aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>1999-03-28 09:26:28 +0000
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>1999-03-28 09:26:28 +0000
commit9fd68c082693e2db323eee226f8f041a1a596cc9 (patch)
tree60bd2c4c9dd96be75e26bf7a55c401eb632b6850
parent9f9d16c921fcede880ddba43b970b29f0f888d8f (diff)
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/egcs_gc_branch@26036 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/.gdbinit10
-rw-r--r--gcc/BUGS8
-rw-r--r--gcc/ChangeLog9665
-rw-r--r--gcc/FSFChangeLog647
-rw-r--r--gcc/FSFChangeLog.106
-rw-r--r--gcc/FSFChangeLog.114
-rw-r--r--gcc/FSFChangeLog.121244
-rw-r--r--gcc/LITERATURE101
-rw-r--r--gcc/Makefile.in873
-rw-r--r--gcc/PROJECTS12
-rw-r--r--gcc/README.C4X8
-rw-r--r--gcc/README.NS32K49
-rw-r--r--gcc/README.RS600022
-rw-r--r--gcc/README.g772
-rw-r--r--gcc/SERVICE861
-rw-r--r--gcc/acconfig.h29
-rw-r--r--gcc/aclocal.m4401
-rw-r--r--gcc/alias.c525
-rw-r--r--gcc/basic-block.h178
-rw-r--r--gcc/bitmap.c6
-rw-r--r--gcc/bitmap.h6
-rw-r--r--gcc/c-aux-info.c243
-rw-r--r--gcc/c-common.c303
-rw-r--r--gcc/c-convert.c2
-rw-r--r--gcc/c-decl.c379
-rw-r--r--gcc/c-iterate.c6
-rw-r--r--gcc/c-lang.c24
-rw-r--r--gcc/c-lex.c400
-rw-r--r--gcc/c-lex.h6
-rw-r--r--gcc/c-parse.gperf4
-rw-r--r--gcc/c-parse.in68
-rw-r--r--gcc/c-parse.y64
-rw-r--r--gcc/c-pragma.c32
-rw-r--r--gcc/c-pragma.h4
-rw-r--r--gcc/c-tree.h96
-rw-r--r--gcc/c-typeck.c535
-rw-r--r--gcc/caller-save.c580
-rw-r--r--gcc/calls.c1986
-rw-r--r--gcc/cccp.c795
-rw-r--r--gcc/cexp.c354
-rw-r--r--gcc/cexp.y260
-rw-r--r--gcc/ch/ChangeLog109
-rw-r--r--gcc/ch/Make-lang.in55
-rw-r--r--gcc/ch/Makefile.in29
-rw-r--r--gcc/ch/actions.c7
-rw-r--r--gcc/ch/actions.h3
-rw-r--r--gcc/ch/ch-tree.def3
-rw-r--r--gcc/ch/ch-tree.h18
-rw-r--r--gcc/ch/config-lang.in3
-rwxr-xr-xgcc/ch/configure3
-rw-r--r--gcc/ch/convert.c5
-rw-r--r--gcc/ch/decl.c23
-rw-r--r--gcc/ch/except.c5
-rw-r--r--gcc/ch/expr.c12
-rw-r--r--gcc/ch/grant.c5
-rw-r--r--gcc/ch/inout.c10
-rw-r--r--gcc/ch/lang-options.h3
-rw-r--r--gcc/ch/lang-specs.h15
-rw-r--r--gcc/ch/lang.c5
-rw-r--r--gcc/ch/lex.c7
-rw-r--r--gcc/ch/lex.h3
-rw-r--r--gcc/ch/loop.c5
-rw-r--r--gcc/ch/nloop.c3
-rw-r--r--gcc/ch/parse.c22
-rw-r--r--gcc/ch/satisfy.c7
-rw-r--r--gcc/ch/tasking.c33
-rw-r--r--gcc/ch/tasking.h3
-rw-r--r--gcc/ch/timing.c5
-rw-r--r--gcc/ch/tree.c5
-rw-r--r--gcc/ch/typeck.c47
-rw-r--r--gcc/ch/xtypeck.c19
-rw-r--r--gcc/collect2.c455
-rw-r--r--gcc/combine.c464
-rw-r--r--gcc/config.in145
-rwxr-xr-xgcc/config.sub979
-rw-r--r--gcc/config/1750a/1750a.c12
-rw-r--r--gcc/config/1750a/1750a.h18
-rw-r--r--gcc/config/a29k/a29k.c11
-rw-r--r--gcc/config/a29k/a29k.h48
-rw-r--r--gcc/config/alpha/alpha.c120
-rw-r--r--gcc/config/alpha/alpha.h149
-rw-r--r--gcc/config/alpha/alpha.md391
-rw-r--r--gcc/config/alpha/elf.h38
-rw-r--r--gcc/config/alpha/linux-ecoff.h3
-rw-r--r--gcc/config/alpha/linux-elf.h3
-rw-r--r--gcc/config/alpha/linux.h3
-rw-r--r--gcc/config/alpha/netbsd-elf.h3
-rw-r--r--gcc/config/alpha/netbsd.h3
-rw-r--r--gcc/config/alpha/vxworks.h6
-rw-r--r--gcc/config/aoutos.h47
-rw-r--r--gcc/config/arc/arc.h4
-rw-r--r--gcc/config/arc/arc.md4
-rw-r--r--gcc/config/arc/initfini.c62
-rw-r--r--gcc/config/arm/README-interworking527
-rw-r--r--gcc/config/arm/aout.h96
-rw-r--r--gcc/config/arm/arm.c1263
-rw-r--r--gcc/config/arm/arm.h550
-rw-r--r--gcc/config/arm/arm.md558
-rw-r--r--gcc/config/arm/coff.h61
-rw-r--r--gcc/config/arm/lib1funcs.asm91
-rw-r--r--gcc/config/arm/lib1thumb.asm96
-rw-r--r--gcc/config/arm/linux-gas.h65
-rw-r--r--gcc/config/arm/linux.h72
-rw-r--r--gcc/config/arm/netbsd.h12
-rw-r--r--gcc/config/arm/riscix.h11
-rw-r--r--gcc/config/arm/riscix1-1.h8
-rw-r--r--gcc/config/arm/t-linux9
-rw-r--r--gcc/config/arm/t-netbsd4
-rw-r--r--gcc/config/arm/t-riscix3
-rw-r--r--gcc/config/arm/t-semi3
-rw-r--r--gcc/config/arm/t-semiaof4
-rw-r--r--gcc/config/arm/thumb.c14
-rw-r--r--gcc/config/arm/thumb.h4
-rw-r--r--gcc/config/arm/xm-arm.h1
-rw-r--r--gcc/config/arm/xm-netbsd.h2
-rw-r--r--gcc/config/c4x/c4x.c2531
-rw-r--r--gcc/config/c4x/c4x.h493
-rw-r--r--gcc/config/c4x/c4x.md1162
-rw-r--r--gcc/config/c4x/libgcc.S12
-rw-r--r--gcc/config/c4x/t-c4x11
-rw-r--r--gcc/config/clipper/clipper.c2
-rw-r--r--gcc/config/clipper/clipper.h10
-rw-r--r--gcc/config/convex/convex.h8
-rw-r--r--gcc/config/dsp16xx/dsp16xx.c8
-rw-r--r--gcc/config/dsp16xx/dsp16xx.h10
-rw-r--r--gcc/config/dsp16xx/dsp16xx.md6
-rw-r--r--gcc/config/elxsi/elxsi.h14
-rw-r--r--gcc/config/float-sh.h2
-rw-r--r--gcc/config/fp-bit.c12
-rw-r--r--gcc/config/fx80/fx80.h28
-rw-r--r--gcc/config/gmicro/gmicro.h9
-rw-r--r--gcc/config/h8300/h8300.c58
-rw-r--r--gcc/config/h8300/h8300.h44
-rw-r--r--gcc/config/h8300/h8300.md51
-rw-r--r--gcc/config/i370/i370.h14
-rw-r--r--gcc/config/i370/i370.md8
-rw-r--r--gcc/config/i386/aix386ng.h6
-rw-r--r--gcc/config/i386/bsd.h4
-rw-r--r--gcc/config/i386/crtdll.h6
-rw-r--r--gcc/config/i386/cygwin32.asm32
-rw-r--r--gcc/config/i386/cygwin32.h479
-rw-r--r--gcc/config/i386/dgux.c4
-rw-r--r--gcc/config/i386/dgux.h5
-rw-r--r--gcc/config/i386/freebsd-elf.h11
-rw-r--r--gcc/config/i386/freebsd.h16
-rw-r--r--gcc/config/i386/gas.h4
-rw-r--r--gcc/config/i386/go32-rtems.h40
-rw-r--r--gcc/config/i386/go32.h99
-rw-r--r--gcc/config/i386/i386.c147
-rw-r--r--gcc/config/i386/i386.h102
-rw-r--r--gcc/config/i386/i386.md684
-rw-r--r--gcc/config/i386/isc.h33
-rw-r--r--gcc/config/i386/isccoff.h4
-rw-r--r--gcc/config/i386/linux.h12
-rw-r--r--gcc/config/i386/mingw32.h13
-rw-r--r--gcc/config/i386/moss.h3
-rw-r--r--gcc/config/i386/netbsd.h8
-rw-r--r--gcc/config/i386/next.h11
-rw-r--r--gcc/config/i386/osfrose.h4
-rw-r--r--gcc/config/i386/sco.h4
-rw-r--r--gcc/config/i386/sco5.h33
-rw-r--r--gcc/config/i386/scodbx.h4
-rw-r--r--gcc/config/i386/sequent.h7
-rw-r--r--gcc/config/i386/sol2.h3
-rw-r--r--gcc/config/i386/sun386.h8
-rw-r--r--gcc/config/i386/t-cygwin3216
-rw-r--r--gcc/config/i386/t-go322
-rw-r--r--gcc/config/i386/t-sco54
-rw-r--r--gcc/config/i386/t-sco5gas4
-rw-r--r--gcc/config/i386/unix.h7
-rw-r--r--gcc/config/i386/win-nt.h4
-rw-r--r--gcc/config/i386/win32.h2
-rw-r--r--gcc/config/i386/winnt.c4
-rw-r--r--gcc/config/i386/x-cygwin324
-rw-r--r--gcc/config/i386/xm-cygwin32.h55
-rw-r--r--gcc/config/i386/xm-go32.h33
-rw-r--r--gcc/config/i860/fx2800.h7
-rw-r--r--gcc/config/i860/i860.c10
-rw-r--r--gcc/config/i860/i860.h16
-rw-r--r--gcc/config/i860/paragon.h12
-rw-r--r--gcc/config/i960/i960.c244
-rw-r--r--gcc/config/i960/i960.h190
-rw-r--r--gcc/config/i960/i960.md28
-rw-r--r--gcc/config/i960/t-960bare4
-rw-r--r--gcc/config/i960/t-vxworks9604
-rw-r--r--gcc/config/i960/vx960-coff.h5
-rw-r--r--gcc/config/m32r/initfini.c74
-rw-r--r--gcc/config/m32r/m32r.c149
-rw-r--r--gcc/config/m32r/m32r.h11
-rw-r--r--gcc/config/m32r/m32r.md19
-rw-r--r--gcc/config/m68k/lb1sf68.asm6
-rw-r--r--gcc/config/m68k/m68k.c26
-rw-r--r--gcc/config/m68k/m68k.h53
-rw-r--r--gcc/config/m68k/m68k.md279
-rw-r--r--gcc/config/m68k/mot3300-crt0.S2
-rw-r--r--gcc/config/m68k/mot3300.h6
-rw-r--r--gcc/config/m68k/mot3300Mcrt0.S2
-rw-r--r--gcc/config/m68k/vxm68k.h11
-rw-r--r--gcc/config/m68k/xm-mot3300.h6
-rw-r--r--gcc/config/m88k/dgux.h2
-rw-r--r--gcc/config/m88k/m88k.c25
-rw-r--r--gcc/config/m88k/m88k.h13
-rw-r--r--gcc/config/m88k/m88k.md87
-rw-r--r--gcc/config/m88k/sysv3.h6
-rw-r--r--gcc/config/m88k/t-luna-gas2
-rw-r--r--gcc/config/m88k/xm-sysv3.h6
-rw-r--r--gcc/config/mips/abi64.h41
-rw-r--r--gcc/config/mips/gnu.h7
-rw-r--r--gcc/config/mips/iris6.h16
-rw-r--r--gcc/config/mips/mips.c255
-rw-r--r--gcc/config/mips/mips.h364
-rw-r--r--gcc/config/mips/mips.md562
-rw-r--r--gcc/config/mips/mips16.S2
-rw-r--r--gcc/config/mips/osfrose.h1
-rw-r--r--gcc/config/mips/sni-svr4.h3
-rw-r--r--gcc/config/mips/t-cross642
-rw-r--r--gcc/config/mn10200/mn10200.h5
-rw-r--r--gcc/config/mn10200/mn10200.md115
-rw-r--r--gcc/config/mn10300/mn10300.h11
-rw-r--r--gcc/config/mn10300/mn10300.md129
-rw-r--r--gcc/config/nextstep.h2
-rw-r--r--gcc/config/ns32k/netbsd.h7
-rw-r--r--gcc/config/ns32k/ns32k.c500
-rw-r--r--gcc/config/ns32k/ns32k.h496
-rw-r--r--gcc/config/ns32k/ns32k.md702
-rw-r--r--gcc/config/pa/pa-gas.h5
-rw-r--r--gcc/config/pa/pa-hpux.h2
-rw-r--r--gcc/config/pa/pa-hpux10.h2
-rw-r--r--gcc/config/pa/pa-hpux9.h2
-rw-r--r--gcc/config/pa/pa-osf.h2
-rw-r--r--gcc/config/pa/pa-pro-end.h3
-rw-r--r--gcc/config/pa/pa-pro.h7
-rw-r--r--gcc/config/pa/pa.c81
-rw-r--r--gcc/config/pa/pa.h200
-rw-r--r--gcc/config/pa/pa.md131
-rw-r--r--gcc/config/pa/pa1.h3
-rw-r--r--gcc/config/pdp11/2bsd.h3
-rw-r--r--gcc/config/pdp11/pdp11.c6
-rw-r--r--gcc/config/pdp11/pdp11.h28
-rw-r--r--gcc/config/pdp11/pdp11.md7
-rw-r--r--gcc/config/ptx4.h7
-rw-r--r--gcc/config/pyr/pyr.h8
-rw-r--r--gcc/config/romp/romp.h10
-rw-r--r--gcc/config/romp/romp.md4
-rw-r--r--gcc/config/rs6000/cygwin32.h67
-rw-r--r--gcc/config/rs6000/eabile.h3
-rw-r--r--gcc/config/rs6000/linux.h11
-rw-r--r--gcc/config/rs6000/netware.h3
-rw-r--r--gcc/config/rs6000/rs6000.c308
-rw-r--r--gcc/config/rs6000/rs6000.h179
-rw-r--r--gcc/config/rs6000/rs6000.md1136
-rw-r--r--gcc/config/rs6000/sol2.h3
-rw-r--r--gcc/config/rs6000/sysv4.h50
-rw-r--r--gcc/config/rs6000/sysv4le.h3
-rw-r--r--gcc/config/rs6000/t-ppcgas9
-rw-r--r--gcc/config/rs6000/win-nt.h6
-rw-r--r--gcc/config/rs6000/x-cygwin324
-rw-r--r--gcc/config/rs6000/xm-cygwin32.h1
-rw-r--r--gcc/config/rs6000/xm-sysv4.h2
-rw-r--r--gcc/config/sh/elf.h2
-rw-r--r--gcc/config/sh/lib1funcs.asm222
-rw-r--r--gcc/config/sh/rtems.h2
-rw-r--r--gcc/config/sh/rtemself.h2
-rw-r--r--gcc/config/sh/sh.c842
-rw-r--r--gcc/config/sh/sh.h436
-rw-r--r--gcc/config/sh/sh.md1481
-rw-r--r--gcc/config/sh/t-sh4
-rw-r--r--gcc/config/sparc/elf.h16
-rw-r--r--gcc/config/sparc/gmon-sol2.c24
-rw-r--r--gcc/config/sparc/linux.h2
-rw-r--r--gcc/config/sparc/linux64.h2
-rw-r--r--gcc/config/sparc/sp64-elf.h4
-rw-r--r--gcc/config/sparc/sparc.c548
-rw-r--r--gcc/config/sparc/sparc.h329
-rw-r--r--gcc/config/sparc/sparc.md123
-rw-r--r--gcc/config/sparc/splet.h28
-rw-r--r--gcc/config/sparc/t-splet5
-rw-r--r--gcc/config/spur/spur.h8
-rw-r--r--gcc/config/svr4.h82
-rw-r--r--gcc/config/t-gnu7
-rw-r--r--gcc/config/t-rtems4
-rw-r--r--gcc/config/v850/lib1funcs.asm5
-rw-r--r--gcc/config/v850/v850.c200
-rw-r--r--gcc/config/v850/v850.h4
-rw-r--r--gcc/config/v850/v850.md168
-rw-r--r--gcc/config/vax/vax.h8
-rw-r--r--gcc/config/vax/xm-vax.h3
-rw-r--r--gcc/config/we32k/we32k.h8
-rwxr-xr-xgcc/configure3200
-rw-r--r--gcc/configure.in748
-rw-r--r--gcc/cp/ChangeLog2569
-rw-r--r--gcc/cp/Make-lang.in63
-rw-r--r--gcc/cp/Makefile.in36
-rw-r--r--gcc/cp/NEWS6
-rw-r--r--gcc/cp/call.c620
-rw-r--r--gcc/cp/class.c997
-rw-r--r--gcc/cp/config-lang.in2
-rw-r--r--gcc/cp/cp-tree.def17
-rw-r--r--gcc/cp/cp-tree.h704
-rw-r--r--gcc/cp/cvt.c156
-rw-r--r--gcc/cp/decl.c2873
-rw-r--r--gcc/cp/decl2.c728
-rw-r--r--gcc/cp/errfn.c132
-rw-r--r--gcc/cp/error.c346
-rw-r--r--gcc/cp/except.c64
-rw-r--r--gcc/cp/exception.cc31
-rw-r--r--gcc/cp/expr.c16
-rw-r--r--gcc/cp/friend.c97
-rw-r--r--gcc/cp/g++spec.c11
-rw-r--r--gcc/cp/gxx.gperf2
-rw-r--r--gcc/cp/gxxint.texi71
-rw-r--r--gcc/cp/hash.h260
-rw-r--r--gcc/cp/inc/exception2
-rw-r--r--gcc/cp/inc/new2
-rw-r--r--gcc/cp/inc/typeinfo17
-rw-r--r--gcc/cp/init.c501
-rw-r--r--gcc/cp/input.c8
-rw-r--r--gcc/cp/lang-options.h10
-rw-r--r--gcc/cp/lang-specs.h12
-rw-r--r--gcc/cp/lex.c637
-rw-r--r--gcc/cp/lex.h3
-rw-r--r--gcc/cp/method.c395
-rw-r--r--gcc/cp/new.cc2
-rw-r--r--gcc/cp/new1.cc2
-rw-r--r--gcc/cp/new2.cc2
-rw-r--r--gcc/cp/parse.c8875
-rw-r--r--gcc/cp/parse.y237
-rw-r--r--gcc/cp/pt.c3416
-rw-r--r--gcc/cp/ptree.c9
-rw-r--r--gcc/cp/repo.c22
-rw-r--r--gcc/cp/rtti.c157
-rw-r--r--gcc/cp/search.c2355
-rw-r--r--gcc/cp/semantics.c143
-rw-r--r--gcc/cp/sig.c103
-rw-r--r--gcc/cp/spew.c7
-rw-r--r--gcc/cp/tinfo.cc11
-rw-r--r--gcc/cp/tinfo.h2
-rw-r--r--gcc/cp/tinfo2.cc30
-rw-r--r--gcc/cp/tree.c310
-rw-r--r--gcc/cp/typeck.c1532
-rw-r--r--gcc/cp/typeck2.c410
-rw-r--r--gcc/cp/xref.c67
-rw-r--r--gcc/cpp.texi2
-rw-r--r--gcc/cppalloc.c45
-rw-r--r--gcc/cpperror.c100
-rw-r--r--gcc/cppexp.c588
-rw-r--r--gcc/cpphash.c1539
-rw-r--r--gcc/cpphash.h46
-rw-r--r--gcc/cpplib.c6960
-rw-r--r--gcc/cpplib.h285
-rw-r--r--gcc/cppmain.c12
-rw-r--r--gcc/cross-make11
-rw-r--r--gcc/crtstuff.c70
-rw-r--r--gcc/cse.c159
-rw-r--r--gcc/dbxout.c20
-rw-r--r--gcc/defaults.h21
-rw-r--r--gcc/demangle.h108
-rw-r--r--gcc/doprint.c22
-rw-r--r--gcc/dwarf2.h31
-rw-r--r--gcc/dwarf2out.c646
-rw-r--r--gcc/dwarfout.c81
-rw-r--r--gcc/dwarfout.h2
-rw-r--r--gcc/dyn-string.c33
-rw-r--r--gcc/dyn-string.h29
-rw-r--r--gcc/eh-common.h25
-rw-r--r--gcc/emit-rtl.c191
-rw-r--r--gcc/except.c291
-rw-r--r--gcc/except.h26
-rw-r--r--gcc/explow.c72
-rw-r--r--gcc/expmed.c186
-rw-r--r--gcc/expr.c592
-rw-r--r--gcc/expr.h23
-rw-r--r--gcc/extend.texi146
-rw-r--r--gcc/f/BUGS116
-rw-r--r--gcc/f/ChangeLog5263
-rw-r--r--gcc/f/INSTALL1289
-rw-r--r--gcc/f/Make-lang.in92
-rw-r--r--gcc/f/Makefile.in2
-rw-r--r--gcc/f/NEWS1447
-rw-r--r--gcc/f/ansify.c2
-rw-r--r--gcc/f/assert.j1
-rw-r--r--gcc/f/bad.c14
-rw-r--r--gcc/f/bad.def6
-rw-r--r--gcc/f/bad.h3
-rw-r--r--gcc/f/bit.c1
-rw-r--r--gcc/f/bit.h1
-rw-r--r--gcc/f/bld-op.def1
-rw-r--r--gcc/f/bld.c4
-rw-r--r--gcc/f/bld.h3
-rw-r--r--gcc/f/bugs.texi160
-rw-r--r--gcc/f/bugs0.texi20
-rw-r--r--gcc/f/com-rt.def6
-rw-r--r--gcc/f/com.c89
-rw-r--r--gcc/f/com.h6
-rw-r--r--gcc/f/config.j1
-rw-r--r--gcc/f/convert.j1
-rw-r--r--gcc/f/data.c4
-rw-r--r--gcc/f/data.h1
-rw-r--r--gcc/f/equiv.c2
-rw-r--r--gcc/f/equiv.h2
-rw-r--r--gcc/f/expr.c98
-rw-r--r--gcc/f/expr.h1
-rw-r--r--gcc/f/fini.c37
-rw-r--r--gcc/f/flags.j1
-rw-r--r--gcc/f/g77.114
-rw-r--r--gcc/f/g77.texi2052
-rw-r--r--gcc/f/g77install.texi175
-rw-r--r--gcc/f/g77spec.c3
-rw-r--r--gcc/f/glimits.j1
-rw-r--r--gcc/f/global.c165
-rw-r--r--gcc/f/global.h6
-rw-r--r--gcc/f/hconfig.j1
-rw-r--r--gcc/f/implic.c5
-rw-r--r--gcc/f/implic.h2
-rw-r--r--gcc/f/info-b.def1
-rw-r--r--gcc/f/info-k.def1
-rw-r--r--gcc/f/info-w.def1
-rw-r--r--gcc/f/info.c11
-rw-r--r--gcc/f/info.h6
-rw-r--r--gcc/f/input.j1
-rw-r--r--gcc/f/install0.texi15
-rw-r--r--gcc/f/intdoc.c13
-rw-r--r--gcc/f/intdoc.in320
-rw-r--r--gcc/f/intdoc.texi409
-rw-r--r--gcc/f/intrin.c84
-rw-r--r--gcc/f/intrin.def14
-rw-r--r--gcc/f/intrin.h17
-rw-r--r--gcc/f/lab.c1
-rw-r--r--gcc/f/lab.h1
-rw-r--r--gcc/f/lang-options.h2
-rw-r--r--gcc/f/lang-specs.h22
-rw-r--r--gcc/f/lex.c26
-rw-r--r--gcc/f/lex.h5
-rw-r--r--gcc/f/malloc.c16
-rw-r--r--gcc/f/malloc.h4
-rw-r--r--gcc/f/name.c3
-rw-r--r--gcc/f/name.h3
-rw-r--r--gcc/f/news.texi589
-rw-r--r--gcc/f/news0.texi20
-rw-r--r--gcc/f/output.j3
-rw-r--r--gcc/f/parse.c2
-rw-r--r--gcc/f/proj.c2
-rw-r--r--gcc/f/proj.h2
-rw-r--r--gcc/f/rtl.j1
-rw-r--r--gcc/f/src.c2
-rw-r--r--gcc/f/src.h2
-rw-r--r--gcc/f/st.c1
-rw-r--r--gcc/f/st.h1
-rw-r--r--gcc/f/sta.c2
-rw-r--r--gcc/f/sta.h2
-rw-r--r--gcc/f/stb.c57
-rw-r--r--gcc/f/stb.h1
-rw-r--r--gcc/f/stc.c2
-rw-r--r--gcc/f/stc.h1
-rw-r--r--gcc/f/std.c2
-rw-r--r--gcc/f/std.h1
-rw-r--r--gcc/f/ste.c2
-rw-r--r--gcc/f/ste.h1
-rw-r--r--gcc/f/storag.c1
-rw-r--r--gcc/f/storag.h1
-rw-r--r--gcc/f/stp.c1
-rw-r--r--gcc/f/stp.h1
-rw-r--r--gcc/f/str-1t.fin1
-rw-r--r--gcc/f/str-2t.fin1
-rw-r--r--gcc/f/str-fo.fin1
-rw-r--r--gcc/f/str-io.fin1
-rw-r--r--gcc/f/str-nq.fin1
-rw-r--r--gcc/f/str-op.fin1
-rw-r--r--gcc/f/str-ot.fin2
-rw-r--r--gcc/f/str.c1
-rw-r--r--gcc/f/str.h1
-rw-r--r--gcc/f/sts.c2
-rw-r--r--gcc/f/sts.h1
-rw-r--r--gcc/f/stt.c2
-rw-r--r--gcc/f/stt.h2
-rw-r--r--gcc/f/stu.c2
-rw-r--r--gcc/f/stu.h1
-rw-r--r--gcc/f/stv.c1
-rw-r--r--gcc/f/stv.h1
-rw-r--r--gcc/f/stw.c1
-rw-r--r--gcc/f/stw.h1
-rw-r--r--gcc/f/symbol.c14
-rw-r--r--gcc/f/symbol.def1
-rw-r--r--gcc/f/symbol.h6
-rw-r--r--gcc/f/system.j2
-rw-r--r--gcc/f/target.c4
-rw-r--r--gcc/f/target.h28
-rw-r--r--gcc/f/tconfig.j1
-rw-r--r--gcc/f/tm.j1
-rw-r--r--gcc/f/top.c9
-rw-r--r--gcc/f/top.h2
-rw-r--r--gcc/f/toplev.j2
-rw-r--r--gcc/f/tree.j1
-rw-r--r--gcc/f/type.c1
-rw-r--r--gcc/f/type.h1
-rw-r--r--gcc/f/version.c2
-rw-r--r--gcc/f/where.c2
-rw-r--r--gcc/f/where.h1
-rw-r--r--gcc/final.c142
-rw-r--r--gcc/fix-header.c119
-rwxr-xr-xgcc/fixinc.irix2
-rwxr-xr-xgcc/fixinc.sco8
-rwxr-xr-xgcc/fixinc.svr436
-rwxr-xr-xgcc/fixinc.wrap29
-rwxr-xr-xgcc/fixincludes140
-rwxr-xr-xgcc/fixproto2
-rw-r--r--gcc/flags.h27
-rw-r--r--gcc/floatlib.c627
-rw-r--r--gcc/flow.c4266
-rw-r--r--gcc/fold-const.c637
-rw-r--r--gcc/frame.c20
-rw-r--r--gcc/frame.h29
-rw-r--r--gcc/function.c1007
-rw-r--r--gcc/function.h20
-rw-r--r--gcc/gansidecl.h82
-rw-r--r--gcc/gcc.12
-rw-r--r--gcc/gcc.c869
-rw-r--r--gcc/gcc.texi174
-rw-r--r--gcc/gcov-io.h12
-rw-r--r--gcc/gcov.c119
-rw-r--r--gcc/gcse.c1591
-rw-r--r--gcc/gen-protos.c15
-rw-r--r--gcc/genattr.c42
-rw-r--r--gcc/genattrtab.c369
-rw-r--r--gcc/gencheck.c10
-rw-r--r--gcc/gencodes.c42
-rw-r--r--gcc/genconfig.c42
-rw-r--r--gcc/genemit.c52
-rw-r--r--gcc/genextract.c98
-rw-r--r--gcc/genflags.c42
-rw-r--r--gcc/gengenrtl.c8
-rw-r--r--gcc/genopinit.c54
-rw-r--r--gcc/genoutput.c247
-rw-r--r--gcc/genpeep.c44
-rw-r--r--gcc/genrecog.c186
-rw-r--r--gcc/getpwd.c9
-rw-r--r--gcc/ginclude/math-3300.h2
-rw-r--r--gcc/ginclude/va-sh.h106
-rw-r--r--gcc/global.c102
-rw-r--r--gcc/gmon.c2
-rw-r--r--gcc/gthr-vxworks.h18
-rw-r--r--gcc/haifa-sched.c423
-rw-r--r--gcc/halfpic.c10
-rw-r--r--gcc/halfpic.h6
-rw-r--r--gcc/hash.c137
-rw-r--r--gcc/hash.h85
-rw-r--r--gcc/input.h2
-rw-r--r--gcc/install.texi177
-rw-r--r--gcc/integrate.c301
-rw-r--r--gcc/integrate.h46
-rw-r--r--gcc/invoke.texi410
-rw-r--r--gcc/java/ChangeLog5677
-rw-r--r--gcc/java/Make-lang.in66
-rw-r--r--gcc/java/Makefile.in114
-rw-r--r--gcc/java/buffer.h3
-rw-r--r--gcc/java/class.c604
-rw-r--r--gcc/java/config-lang.in2
-rw-r--r--gcc/java/constants.c59
-rw-r--r--gcc/java/convert.h4
-rw-r--r--gcc/java/decl.c236
-rw-r--r--gcc/java/except.c72
-rw-r--r--gcc/java/expr.c595
-rw-r--r--gcc/java/gjavah.c1086
-rw-r--r--gcc/java/java-except.h9
-rw-r--r--gcc/java/java-tree.def73
-rw-r--r--gcc/java/java-tree.h269
-rw-r--r--gcc/java/javaop.h19
-rw-r--r--gcc/java/jcf-dump.c297
-rw-r--r--gcc/java/jcf-io.c343
-rw-r--r--gcc/java/jcf-parse.c390
-rw-r--r--gcc/java/jcf-reader.c16
-rw-r--r--gcc/java/jcf-write.c2888
-rw-r--r--gcc/java/jcf.h34
-rw-r--r--gcc/java/jv-scan.c86
-rw-r--r--gcc/java/jvgenmain.c51
-rw-r--r--gcc/java/jvspec.c309
-rw-r--r--gcc/java/lang-options.h10
-rw-r--r--gcc/java/lang-specs.h31
-rw-r--r--gcc/java/lang.c263
-rw-r--r--gcc/java/lex.c362
-rw-r--r--gcc/java/lex.h19
-rw-r--r--gcc/java/mangle.c28
-rw-r--r--gcc/java/parse-scan.y65
-rw-r--r--gcc/java/parse.c10888
-rw-r--r--gcc/java/parse.h433
-rw-r--r--gcc/java/parse.y6840
-rw-r--r--gcc/java/typeck.c130
-rw-r--r--gcc/java/verify.c67
-rw-r--r--gcc/java/zextract.c11
-rw-r--r--gcc/java/zipfile.h9
-rw-r--r--gcc/jump.c928
-rwxr-xr-xgcc/just-fixinc2
-rw-r--r--gcc/libgcc2.c409
-rw-r--r--gcc/local-alloc.c292
-rw-r--r--gcc/longlong.h2
-rw-r--r--gcc/loop.c2039
-rw-r--r--gcc/loop.h102
-rw-r--r--gcc/machmode.h29
-rw-r--r--gcc/mbchar.c6
-rw-r--r--gcc/mbchar.h18
-rw-r--r--gcc/md.texi80
-rw-r--r--gcc/mips-tdump.c112
-rw-r--r--gcc/mips-tfile.c205
-rw-r--r--gcc/mkinstalldirs2
-rw-r--r--gcc/objc/Make-lang.in6
-rw-r--r--gcc/objc/Makefile.in2
-rw-r--r--gcc/objc/objc-act.c32
-rw-r--r--gcc/objc/objc-parse.c3595
-rw-r--r--gcc/objc/objc-parse.y45
-rw-r--r--gcc/objc/objc-tree.def2
-rw-r--r--gcc/optabs.c178
-rw-r--r--gcc/output.h32
-rw-r--r--gcc/prefix.c66
-rw-r--r--gcc/print-rtl.c126
-rw-r--r--gcc/print-tree.c12
-rw-r--r--gcc/profile.c13
-rw-r--r--gcc/protoize.c527
-rw-r--r--gcc/real.c509
-rw-r--r--gcc/real.h18
-rw-r--r--gcc/recog.c718
-rw-r--r--gcc/recog.h102
-rw-r--r--gcc/reg-stack.c577
-rw-r--r--gcc/regclass.c641
-rw-r--r--gcc/regmove.c508
-rw-r--r--gcc/regs.h4
-rw-r--r--gcc/reload.c1170
-rw-r--r--gcc/reload.h27
-rw-r--r--gcc/reload1.c4350
-rw-r--r--gcc/reorg.c1323
-rw-r--r--gcc/rtl.c58
-rw-r--r--gcc/rtl.def28
-rw-r--r--gcc/rtl.h238
-rw-r--r--gcc/rtl.texi75
-rw-r--r--gcc/rtlanal.c202
-rw-r--r--gcc/scan-decls.c11
-rw-r--r--gcc/scan.c2
-rw-r--r--gcc/scan.h12
-rw-r--r--gcc/sched.c238
-rw-r--r--gcc/sdbout.c7
-rw-r--r--gcc/stab.def2
-rw-r--r--gcc/stmt.c952
-rw-r--r--gcc/stor-layout.c70
-rw-r--r--gcc/stupid.c6
-rw-r--r--gcc/system.h168
-rw-r--r--gcc/testsuite/ChangeLog447
-rw-r--r--gcc/testsuite/README.g++66
-rw-r--r--gcc/testsuite/g++.old-deja/g++.benjamin/p12475.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.benjamin/p15561.C194
-rw-r--r--gcc/testsuite/g++.old-deja/g++.benjamin/tem03.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.benjamin/tem06.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.benjamin/typedef01.C7
-rw-r--r--gcc/testsuite/g++.old-deja/g++.benjamin/warn02.C8
-rw-r--r--gcc/testsuite/g++.old-deja/g++.bob/inherit1.C26
-rw-r--r--gcc/testsuite/g++.old-deja/g++.bob/packed1.C17
-rw-r--r--gcc/testsuite/g++.old-deja/g++.bob/protected1.C42
-rw-r--r--gcc/testsuite/g++.old-deja/g++.bob/template3.C49
-rw-r--r--gcc/testsuite/g++.old-deja/g++.bob/template4.C21
-rw-r--r--gcc/testsuite/g++.old-deja/g++.brendan/README41
-rw-r--r--gcc/testsuite/g++.old-deja/g++.brendan/arm1.C11
-rw-r--r--gcc/testsuite/g++.old-deja/g++.brendan/bit-fields2.C16
-rw-r--r--gcc/testsuite/g++.old-deja/g++.brendan/bool1.C12
-rw-r--r--gcc/testsuite/g++.old-deja/g++.brendan/copy1.C22
-rw-r--r--gcc/testsuite/g++.old-deja/g++.brendan/copy2.C80
-rw-r--r--gcc/testsuite/g++.old-deja/g++.brendan/copy3.C58
-rw-r--r--gcc/testsuite/g++.old-deja/g++.brendan/copy5.C85
-rw-r--r--gcc/testsuite/g++.old-deja/g++.brendan/copy7.C30
-rw-r--r--gcc/testsuite/g++.old-deja/g++.brendan/copy9.C41
-rw-r--r--gcc/testsuite/g++.old-deja/g++.brendan/crash11.C26
-rw-r--r--gcc/testsuite/g++.old-deja/g++.brendan/crash13.C36
-rw-r--r--gcc/testsuite/g++.old-deja/g++.brendan/crash14.C24
-rw-r--r--gcc/testsuite/g++.old-deja/g++.brendan/crash15.C22
-rw-r--r--gcc/testsuite/g++.old-deja/g++.brendan/crash19.C8
-rw-r--r--gcc/testsuite/g++.old-deja/g++.brendan/crash29.C19
-rw-r--r--gcc/testsuite/g++.old-deja/g++.brendan/crash30.C1
-rw-r--r--gcc/testsuite/g++.old-deja/g++.brendan/crash33.C7
-rw-r--r--gcc/testsuite/g++.old-deja/g++.brendan/crash38.C43
-rw-r--r--gcc/testsuite/g++.old-deja/g++.brendan/crash44.C27
-rw-r--r--gcc/testsuite/g++.old-deja/g++.brendan/crash47.C94
-rw-r--r--gcc/testsuite/g++.old-deja/g++.brendan/crash48.C22
-rw-r--r--gcc/testsuite/g++.old-deja/g++.brendan/crash5.C107
-rw-r--r--gcc/testsuite/g++.old-deja/g++.brendan/crash50.C30
-rw-r--r--gcc/testsuite/g++.old-deja/g++.brendan/crash54.C10
-rw-r--r--gcc/testsuite/g++.old-deja/g++.brendan/crash57.C14
-rw-r--r--gcc/testsuite/g++.old-deja/g++.brendan/crash7.C47
-rw-r--r--gcc/testsuite/g++.old-deja/g++.brendan/enum1.C15
-rw-r--r--gcc/testsuite/g++.old-deja/g++.brendan/enum2.C20
-rw-r--r--gcc/testsuite/g++.old-deja/g++.brendan/enum5.C11
-rw-r--r--gcc/testsuite/g++.old-deja/g++.brendan/enum6.C18
-rw-r--r--gcc/testsuite/g++.old-deja/g++.brendan/friend1.C20
-rw-r--r--gcc/testsuite/g++.old-deja/g++.brendan/groff1.C1
-rw-r--r--gcc/testsuite/g++.old-deja/g++.brendan/init12.C10
-rw-r--r--gcc/testsuite/g++.old-deja/g++.brendan/init3.C39
-rw-r--r--gcc/testsuite/g++.old-deja/g++.brendan/misc14.C13
-rw-r--r--gcc/testsuite/g++.old-deja/g++.brendan/misc7.C16
-rw-r--r--gcc/testsuite/g++.old-deja/g++.brendan/misc8.C19
-rw-r--r--gcc/testsuite/g++.old-deja/g++.brendan/nest10.C31
-rw-r--r--gcc/testsuite/g++.old-deja/g++.brendan/nest21.C96
-rw-r--r--gcc/testsuite/g++.old-deja/g++.brendan/nest3.C13
-rw-r--r--gcc/testsuite/g++.old-deja/g++.brendan/new-array.C19
-rw-r--r--gcc/testsuite/g++.old-deja/g++.brendan/operators1.C15
-rw-r--r--gcc/testsuite/g++.old-deja/g++.brendan/overload1.C22
-rw-r--r--gcc/testsuite/g++.old-deja/g++.brendan/overload7.C42
-rw-r--r--gcc/testsuite/g++.old-deja/g++.brendan/overload8.C10
-rw-r--r--gcc/testsuite/g++.old-deja/g++.brendan/overload9.C21
-rw-r--r--gcc/testsuite/g++.old-deja/g++.brendan/parse1.C18
-rw-r--r--gcc/testsuite/g++.old-deja/g++.brendan/parse3.C4
-rw-r--r--gcc/testsuite/g++.old-deja/g++.brendan/parse4.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.brendan/parse5.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.brendan/parse6.C4
-rw-r--r--gcc/testsuite/g++.old-deja/g++.brendan/prepost1.C16
-rw-r--r--gcc/testsuite/g++.old-deja/g++.brendan/ptolemy2.C70
-rw-r--r--gcc/testsuite/g++.old-deja/g++.brendan/recurse.C81
-rw-r--r--gcc/testsuite/g++.old-deja/g++.brendan/scope2.C30
-rw-r--r--gcc/testsuite/g++.old-deja/g++.brendan/static2.C20
-rw-r--r--gcc/testsuite/g++.old-deja/g++.brendan/template11.C48
-rw-r--r--gcc/testsuite/g++.old-deja/g++.brendan/template2.C15
-rw-r--r--gcc/testsuite/g++.old-deja/g++.brendan/template20.C22
-rw-r--r--gcc/testsuite/g++.old-deja/g++.brendan/template22.C23
-rw-r--r--gcc/testsuite/g++.old-deja/g++.brendan/template24.C21
-rw-r--r--gcc/testsuite/g++.old-deja/g++.brendan/template28.C14
-rw-r--r--gcc/testsuite/g++.old-deja/g++.brendan/template29.C13
-rw-r--r--gcc/testsuite/g++.old-deja/g++.brendan/template8.C21
-rw-r--r--gcc/testsuite/g++.old-deja/g++.brendan/temporary1.C14
-rw-r--r--gcc/testsuite/g++.old-deja/g++.brendan/visibility1.C17
-rw-r--r--gcc/testsuite/g++.old-deja/g++.brendan/visibility4.C16
-rw-r--r--gcc/testsuite/g++.old-deja/g++.brendan/visibility6.C18
-rw-r--r--gcc/testsuite/g++.old-deja/g++.brendan/visibility8.C16
-rw-r--r--gcc/testsuite/g++.old-deja/g++.bugs/900121_01.C17
-rw-r--r--gcc/testsuite/g++.old-deja/g++.bugs/900213_03.C29
-rw-r--r--gcc/testsuite/g++.old-deja/g++.bugs/900214_01.C23
-rw-r--r--gcc/testsuite/g++.old-deja/g++.bugs/900215_02.C48
-rw-r--r--gcc/testsuite/g++.old-deja/g++.bugs/900321_01.C31
-rw-r--r--gcc/testsuite/g++.old-deja/g++.bugs/900322_01.C71
-rw-r--r--gcc/testsuite/g++.old-deja/g++.bugs/900428_01.C77
-rw-r--r--gcc/testsuite/g++.old-deja/g++.bugs/900511_02.C25
-rw-r--r--gcc/testsuite/g++.old-deja/g++.bugs/900511_03.C22
-rw-r--r--gcc/testsuite/g++.old-deja/g++.bugs/900519_13.C38
-rw-r--r--gcc/testsuite/g++.old-deja/g++.bugs/900520_02.C37
-rw-r--r--gcc/testsuite/g++.old-deja/g++.eh/flow1.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.eh/new1.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.eh/new2.C3
-rw-r--r--gcc/testsuite/g++.old-deja/g++.eh/pdel1.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.eh/pdel2.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.eh/rethrow3.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.eh/spec1.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.eh/spec2.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.eh/spec3.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.eh/spec4.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.ext/default.C27
-rw-r--r--gcc/testsuite/g++.old-deja/g++.ext/implicit1.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.ext/null1.C9
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/2371.C4
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/access16.C21
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/access17.C25
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/access22.C22
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/access23.C90
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/access7.C14
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/aggregate.C14
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/binding.C12
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/bool2.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/bool4.C11
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/bool5.C11
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/bool6.C10
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/byval.C20
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/cleanup2.C16
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/cond.C40
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/cond2.C66
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/const2.C15
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/const3.C11
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/conversion6.C41
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/conversion8.C11
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/crash8.C10
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/ctor1.C28
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/dcast2.C19
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/dcast3.C33
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/default1.C17
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/defctor.C16
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/destruct.C34
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/dot.C21
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/dtor.C14
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/dtor2.C11
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/dtor5.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/enum8.C21
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/friend.C19
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/groff1.C41
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/hmc1.C20
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/init2.C10
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/init3.C43
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/inline.C22
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/jump.C15
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/lex1.C7
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/lineno5.C11
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/lvalue4.C7
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/member1.C4
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/mi.C17
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/mutable1.C12
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/new.C4
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/new5.C6
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/offset2.C24
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/operator.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/overload11.C18
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/overload12.C16
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/overload13.C28
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/overload16.C7
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/overload20.C13
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/overload23.C28
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/overload26.C23
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/overload27.C8
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/overload28.C12
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/parse10.C16
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/parse12.C18
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/parse9.C19
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/pmem2.C44
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/pmem3.C12
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/pmf2.C14
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/pmf7.C28
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/pmf8.C30
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/ref10.C32
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/ref12.C6
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/ref5.C13
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/ref7.C22
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/ref8.C18
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/return3.C20
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/rvalue2.C18
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/rvalue3.C6
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/scoping17.C9
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/scoping4.C31
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/static1.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/synth5.C15
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/synth7.C12
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/tempdest.C21
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/template11.C15
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/template13.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/template14.C17
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/template15.C28
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/template18.C23
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/template19.C10
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/template20.C10
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/template22.C32
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/template24.C22
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/template25.C49
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/template27.C51
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/template3.C15
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/template30.C14
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/template31.C1
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/template34.C25
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/template37.C37
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/template40.C20
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/template42.C19
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/template43.C31
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/temporary2.C17
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/temporary3.C27
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/temporary4.C32
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/temporary5.C17
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/thunk3.C5
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/typeid1.C1
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/typeid2.C31
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/virtual.C42
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/virtual2.C14
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/warning2.C15
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/warning5.C24
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/access2.C21
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/arg1.C30
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/arg11.C24
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/arg3.C23
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/arg7.C34
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/arg9.C40
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/arm13.C1
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/arm14.C25
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/arm9.C34
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/array1.C32
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/bad-error6.C27
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/bad-error7.C25
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/code-gen1.C21
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/code-gen3.C33
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/code-gen4.C31
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/code-gen5.C284
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/copy1.C67
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/ctors11.C22
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/ctors12.C34
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/ctors13.C18
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/ctors16.C50
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/ctors17.C22
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/ctors2.C70
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/ctors8.C25
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/ctors9.C40
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/cvt1.C13
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/cvt10.C61
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/cvt11.C31
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/cvt12.C30
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/cvt13.C20
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/cvt14.C16
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/cvt17.C21
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/cvt19.C28
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/cvt2.C43
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/cvt20.C21
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/cvt21.C37
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/cvt22.C15
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/cvt4.C28
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/cvt5.C29
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/cvt6.C29
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/cvt7.C75
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/cvt8.C36
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/dtors2.C41
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/dtors3.C38
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/dtors4.C23
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/dtors5.C34
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/enum3.C22
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/except6.C28
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/friend4.C20
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/global-init1.C21
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/init11.C25
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/init14.C27
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/init3.C13
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/init9.C36
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/inline4.C21
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/missed-error1.C21
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/missed-error2.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/nest3.C26
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/nest4.C21
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/operators1.C27
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/operators10.C24
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/operators13.C25
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/operators14.C11
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/operators16.C30
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/operators21.C17
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/operators28.C31
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/operators30.C26
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/operators32.C56
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/operators4.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/operators7.C44
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/operators8.C50
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/parsing6.C16
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/parsing8.C32
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/parsing9.C33
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/patches1.C25
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/refs1.C43
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/refs4.C22
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/scope2.C45
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/scope5.C26
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/static-mem4.C14
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/template1.C31
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/temps2.C55
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/temps3.C29
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/temps6.C25
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/typeck1.C19
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/typeck2.C17
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/union1.C31
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/union2.C27
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/unsorted2.C27
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/vbase1.C29
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/virtual3.C48
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/virtual4.C32
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/visibility1.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/visibility11.C45
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/visibility12.C19
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/visibility13.C6
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/visibility16.C38
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/visibility17.C64
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/visibility18.C21
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/visibility19.C41
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/visibility2.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/visibility20.C37
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/visibility23.C26
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/visibility24.C41
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/visibility4.C26
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/visibility7.C72
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/visibility8.C27
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/visibility9.C23
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/vtable1.C29
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/vtable3.C25
-rw-r--r--gcc/testsuite/g++.old-deja/g++.martin/ambig1.C4
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/align1.C57
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/align2.C17
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/ambig1.C33
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/conv1.C11
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/dyncast1.C4
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/dyncast2.C4
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/dyncast3.C21
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/eh19.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/eh20.C7
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/eh33.C4
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/eh34.C4
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/eh4.C7
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/eh49.C17
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/eh6.C21
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/err2.C7
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/leak1.C39
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/misc1.C55
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/misc13.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/misc14.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/misc5.C12
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/misc8.C6
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/net10.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/net17.C59
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/net22.C14
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/net26.C28
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/net34.C37
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/net38.C29
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/net41.C4
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/net43.C12
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/net45.C21
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/net46.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/net47.C9
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/net8.C33
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/net9.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/ns1.C4
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/ns10.C4
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/ns11.C3
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/ns2.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/ns9.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/opr-as1.C12
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/opr-dot1.C23
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/p10148.C34
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/p10769a.C6
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/p10849a.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/p1248.C29
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/p1567.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/p16146.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/p1862.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/p2736.C29
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/p2846.C56
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/p2846a.C35
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/p2846b.C53
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/p2960.C31
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/p3041.C34
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/p3060d.C35
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/p3068.C61
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/p3139.C26
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/p3570.C30
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/p3708.C90
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/p3708a.C90
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/p3708b.C90
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/p4068.C23
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/p4173.C24
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/p4246.C53
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/p4511.C34
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/p4619.C11
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/p4623.C36
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/p4693.C25
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/p4736b.C49
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/p4736c.C63
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/p5469.C22
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/p5469a.C22
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/p5571.C72
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/p5673.C21
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/p5840.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/p6058.C19
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/p6311.C17
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/p658.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/p6927.C17
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/p701.C35
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/p710.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/p7325.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/p755.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/p755a.C15
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/p7626.C44
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/p7651.C26
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/p783.C16
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/p783a.C27
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/p783b.C38
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/p784.C6
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/p786.C36
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/p7865.C29
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/p7868.C23
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/p789.C29
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/p789a.C44
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/p8039.C15
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/p807.C35
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/p8155.C148
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/p8460.C18
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/p8483.C36
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/p8785.C27
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/p8804.C19
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/pmf1.C91
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/pmf2.C55
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/pmf3.C22
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/pmf6.C13
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/rtti2.C6
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/scast1.C8
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/temp.C32
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/virt4.C25
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/virt5.C54
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/warn2.C24
-rw-r--r--gcc/testsuite/g++.old-deja/g++.niklas/t141.C7
-rw-r--r--gcc/testsuite/g++.old-deja/g++.ns/extern1.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.ns/lookup3.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.ns/ns1.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.ns/ns12.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.ns/ns13.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.ns/ns2.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.ns/ns6.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.ns/overload1.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.ns/overload4.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.ns/overload5.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.ns/template6.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.other/ambig1.C12
-rw-r--r--gcc/testsuite/g++.old-deja/g++.other/badopt1.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.other/cleanup1.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.other/decl2.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.other/delete2.C4
-rw-r--r--gcc/testsuite/g++.old-deja/g++.other/friend1.C64
-rw-r--r--gcc/testsuite/g++.old-deja/g++.other/friend4.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.other/init7.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.other/overload1.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.other/rttid4.C117
-rw-r--r--gcc/testsuite/g++.old-deja/g++.other/singleton.C1
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/array1.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/crash10.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/crash21.C1
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/crash5.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/crash8.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/enum5.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/explicit1.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/explicit2.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/explicit22.C6
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/explicit26.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/explicit27.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/explicit28.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/explicit30.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/explicit73.C4
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/friend11.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/friend21.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/friend3.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/friend34.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/friend38.C4
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/m1.C17
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/memclass1.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/memclass2.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/memclass3.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/memclass4.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/memclass5.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/memtemp43.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/memtemp44.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/memtemp45.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/memtemp46.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/memtemp63.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/memtemp67.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/memtemp69.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/overload5.C4
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/spec20.C9
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/spec22.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/static3.C6
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/static_cast.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/t16.C31
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/tiemann2.C35
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/tt2.C23
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/ttp14.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/ttp3.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/typename3.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/typename6.C7
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/typename8.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.robertl/eb125.C6
-rw-r--r--gcc/testsuite/g++.old-deja/g++.robertl/eb131.C5
-rw-r--r--gcc/testsuite/g++.old-deja/g++.robertl/eb26.C3
-rw-r--r--gcc/testsuite/g++.old-deja/g++.robertl/eb27.C1
-rw-r--r--gcc/testsuite/g++.old-deja/g++.robertl/eb36.C6
-rw-r--r--gcc/testsuite/g++.old-deja/g++.robertl/eb4.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.robertl/eb42.C19
-rw-r--r--gcc/testsuite/g++.old-deja/g++.robertl/eb43.C9
-rw-r--r--gcc/testsuite/g++.old-deja/g++.robertl/eb44.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.robertl/eb46.C3
-rw-r--r--gcc/testsuite/g++.old-deja/g++.robertl/eb59.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.robertl/eb66.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.robertl/eb69.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.robertl/eb70.C6
-rw-r--r--gcc/testsuite/g++.old-deja/g++.robertl/eb78.C1
-rw-r--r--gcc/testsuite/g++.old-deja/old-deja.exp1
-rw-r--r--gcc/testsuite/g77.f-torture/execute/u77-test.f9
-rw-r--r--gcc/testsuite/gcc.c-torture/ChangeLog59
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/981001-4.c2
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/920501-4.c30
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/970312-1.c72
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/980526-1.c2
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/980605-1.c4
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/bcp-1.c24
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/bf-sign-2.c68
-rw-r--r--gcc/testsuite/gcc.c-torture/noncompile/noncompile.exp2
-rw-r--r--gcc/testsuite/gcc.c-torture/special/920521-1.c2
-rw-r--r--gcc/testsuite/gcc.c-torture/special/930510-1.c4
-rw-r--r--gcc/testsuite/gcc.dg/980827-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/dll-1.c11
-rw-r--r--gcc/testsuite/gcc.dg/dll-2.c24
-rw-r--r--gcc/testsuite/gcc.dg/dll-3.c16
-rw-r--r--gcc/testsuite/gcc.dg/dll-4.c15
-rw-r--r--gcc/testsuite/gcc.misc-tests/gcov-1.c22
-rw-r--r--gcc/testsuite/gcc.misc-tests/gcov-2.c23
-rw-r--r--gcc/testsuite/lib/c-torture.exp111
-rw-r--r--gcc/testsuite/lib/chill.exp366
-rw-r--r--gcc/testsuite/lib/f-torture.exp2
-rw-r--r--gcc/testsuite/lib/g++.exp7
-rw-r--r--gcc/testsuite/lib/gcc.exp283
-rw-r--r--gcc/testsuite/lib/objc-torture.exp2
-rw-r--r--gcc/testsuite/lib/old-dejagnu.exp39
-rw-r--r--gcc/texinfo.tex4
-rw-r--r--gcc/tlink.c154
-rw-r--r--gcc/tm.texi185
-rw-r--r--gcc/toplev.c1603
-rw-r--r--gcc/toplev.h108
-rw-r--r--gcc/tree.c285
-rw-r--r--gcc/tree.def23
-rw-r--r--gcc/tree.h131
-rw-r--r--gcc/unroll.c1220
-rw-r--r--gcc/varasm.c127
-rw-r--r--gcc/varray.h40
-rw-r--r--gcc/version.c2
-rw-r--r--gcc/xcoffout.c4
-rw-r--r--gcc/xcoffout.h21
1208 files changed, 107729 insertions, 79833 deletions
diff --git a/gcc/.gdbinit b/gcc/.gdbinit
index fe4592baf32..ccc3ad8787f 100644
--- a/gcc/.gdbinit
+++ b/gcc/.gdbinit
@@ -86,10 +86,6 @@ In cc1plus, print the current binding stack, frame by frame, up to and
including the global binding level.
end
-# Don't let abort actually run, as it will make
-# stdio stop working and therefore the `pr' command below as well.
-b abort
-
# Put breakpoints at exit and fancy_abort in case abort is mapped
# to either fprintf/exit or fancy_abort.
b exit
@@ -98,3 +94,9 @@ b fancy_abort
# Make gdb complain about symbol reading errors. This is so that gcc
# developers can see and fix bugs in gcc debug output.
set complaints 20
+
+# Don't let abort actually run, as it will make
+# stdio stop working and therefore the `pr' command above as well.
+# Put this last because gcc does not reference it any more unless
+# USE_SYSTEM_ABORT is defined, so gdb may complain and bail out.
+b abort
diff --git a/gcc/BUGS b/gcc/BUGS
index 33c9386cae1..e628a6467ed 100644
--- a/gcc/BUGS
+++ b/gcc/BUGS
@@ -3,7 +3,7 @@ read the Bugs section of the GCC manual for advice on
(1) how to tell when to report a bug,
(2) where to send your bug report, and
-(2) how to write a useful bug report and what information
+(3) how to write a useful bug report and what information
it needs to have.
There are three ways to read the Bugs section.
@@ -20,4 +20,8 @@ to get to the section on bugs. Or use standalone Info in
a like manner. (Standalone Info is part of the Texinfo distribution.)
(3) By hand. Search for the chapter "Reporting Bugs" in gcc.texi, or
- cat /usr/local/info/gcc* | more "+/^File: emacs, Node: Bugs,"
+ cat /usr/local/info/gcc* | more "+/^File: gcc.info, Node: Bugs,"
+
+You may also want to take a look at the EGCS FAQ, in which there are
+additional instructions for submitting bug reports:
+ http://egcs.cygnus.com/faq.html#bugreport
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index d7d849048b2..a7e32fa1725 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9644 @@
+Sat Mar 27 16:13:50 1999 Jeffrey A Law (law@cygnus.com)
+
+ * flow.c (mark_used_regs): Improve handling of ASMs.
+
+1999-03-26 Zack Weinberg <zack@rabi.columbia.edu>
+
+ * Makefile.in (xcpp, cppspec.o): New targets.
+ (CPP_INSTALL_NAME): New macro.
+ (install-cpp): Install xcpp. Use CPP_INSTALL_NAME.
+ (all.build, start.encap): Build xcpp.
+
+ * cppspec.c: New file, implements argument filtering for a
+ user-visible C preprocessor.
+ * cpp.sh: Removed.
+
+Fri Mar 26 20:41:46 1999 Jim Wilson <wilson@cygnus.com>
+
+ * Makefile.in (stmp-fixinc): Use tooldir instead of gcc_tooldir.
+
+Fri Mar 26 16:02:37 1999 Nick Clifton <nickc@cygnus.com>
+
+ * configure.in (arm-*-vxworks*): Just include arm/vxarm.h
+ * configure: Regenerate.
+ * config/arm/vxarm.h: Define SUBTARGET_CPU_DEFAULT before
+ including arm/coff.h
+
+1999-02-16 Scott Bambrough <scottb@corelcomputer.com>
+
+ * configure.in (arm*-*-linux-gnu*): Set thread_file to 'posix' if
+ --enable-threads[={yes,pthreads,posix}] is passed as a command
+ line parameter to configure.
+
+ * configure: Regenerate.
+
+ * gcc/config/arm/t-linux (TARGET_LIBGCC2_CFLAGS): Include -fPIC.
+
+Fri Mar 26 19:42:19 1999 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * loop.c (combine_givs): Fix index into can_combine when doing
+ benefit adjustment for remaining givs when having combined a giv.
+
+Fri Mar 26 11:38:01 1999 Nick Clifton <nickc@cygnus.com>
+
+ * config/arm/t-arm-elf (EXTRA_MULTILIB_PARTS): Define.
+
+Fri Mar 26 10:48:27 1999 Nick Clifton <nickc@cygnus.com>
+
+ * config/arm/linux-elf.h: Include dbxelf.h
+
+Fri Mar 26 10:43:47 1999 Nick Clifton <nickc@cygnus.com>
+
+ * config/svr4.h: Include new header file dbxelf.h.
+ (DBX_DEBUGGING_INFO): Remove definition.
+ (DBX_USE_BINCL): Remove definition.
+ (DBX_BLOCKS_FUNCTION_RELATIVE): Remove definition.
+ (ASM_IDENTIFY_GCC): Remove definition.
+ (ASM_IDENTIFY_GCC_AFTER_SOURCE): Remove definition.
+ (ASM_OUTPUT_SOURCE_LINE): Remove definition.
+ (DBX_FUNCTION_FIRST): Remove definition.
+ (DBX_OUTPUT_MAIN_SOURCE_FILE_END): Remove definition.
+
+ * config/elfos.h: Include new header file dbxelf.h.
+ (DBX_DEBUGGING_INFO): Remove definition.
+ (DBX_BLOCKS_FUNCTION_RELATIVE): Remove definition.
+ (ASM_IDENTIFY_GCC): Remove definition.
+ (ASM_IDENTIFY_GCC_AFTER_SOURCE): Remove definition.
+ (ASM_OUTPUT_SOURCE_LINE): Remove definition.
+ (DBX_FUNCTION_FIRST): Remove definition.
+
+ * config/dbxelf.h: New header file.
+ (DBX_DEBUGGING_INFO): Define.
+ (DBX_BLOCKS_FUNCTION_RELATIVE): Define.
+ (DBX_FUNCTION_FIRST): Define.
+ (DBX_USE_BINCL): Define.
+ (DBX_CONTIN_LENGTH): Define.
+ (ASM_IDENTIFY_GCC): Define.
+ (ASM_IDENTIFY_GCC_AFTER_SOURCE): Define.
+ (ASM_OUTPUT_SOURCE_LINE): Define.
+ (DBX_OUTPUT_MAIN_SOURCE_FILE_END): Define.
+
+Fri Mar 26 01:59:15 1999 "Charles M. Hannum" <root@ihack.net>
+
+ * fold-const.c (fold_truthop): Optimize bitfield references with
+ different masks as long as their size and bit position are the same.
+
+ * fold-const.c (fold_truthop): Build a type for both the lhs and
+ rhs and use it appropriately.
+
+ * fold-const.c (fold_truthop): Mask the lhs and rhs after merging
+ adjacent bitfield references.
+
+ * fold-const.c (fold_truthop): Verify that the lhs and rhs are
+ in the same bit position when optimizing bitfield references
+ which have the same mask.
+
+Thu Mar 25 22:53:27 1999 Martin von Löwis <loewis@informatik.hu-berlin.de>
+
+ * gcc.texi (Copy Assignment): New node.
+
+1999-03-25 Zack Weinberg <zack@rabi.columbia.edu>
+
+ * gcc.c: Compile unconditionally all code formerly dependent
+ on #ifdef LANG_SPECIFIC_DRIVER.
+ * gccspec.c: New file with stub lang_specific_driver,
+ lang_specific_pre_link.
+ * Makefile.in: Link gccspec.o into xgcc. Add rule to compile
+
+Thu Mar 25 21:08:02 1999 Jason Merrill <jason@yorick.cygnus.com>
+
+ * gcc.texi (Temporaries): Update.
+
+Thu Mar 25 16:53:53 1999 Richard Henderson <rth@cygnus.com>
+
+ * combine.c (distribute_notes): Place REG_LABEL also where
+ REG_EQUAL indicates.
+
+Thu Mar 25 12:46:37 1999 Jim Wilson <wilson@cygnus.com>
+
+ * a29k/a29k.h (TARGET_SWITCHES): Add doc strings.
+ * i960/i960.h (TARGET_SWITCHES): Add doc strings.
+ * invoke.texi (a29k): Add documentation for -mno-multm option.
+
+Thu Mar 25 14:04:54 EST 1999 Andrew MacLeod <amacleod@cygnus.com>
+
+ * rtl.texi (RTX_FRAME_RELATED_P): Add documentation.
+ * rtl.h (struct rtx_def): Update comment for frame_related field.
+ (set_unique_reg_note): Declare prototype.
+ * dwarf2out.c (dwarf2out_frame_debug_expr): Split out from
+ 'dwarf2out_frame_debug' to handle only expressions, and process
+ component parts of a PARALLEL expression.
+ (dwarf2out_frame_debug): Process insns only, and call
+ new function 'dwarf2out_frame_debug_expr' for patterns.
+ * emit-rtl.c (set_unique_reg_note): New function to add a reg note,
+ but if there is an existingone, deletes it first.
+ * expmed.c (expand_mult, expand_divmod): Use set_unique_reg_note.
+ * optabs.c (add_equal_note, expand_binop): Use set_unique_reg_note.
+ (emit_no_conflict_block, emit_libcall_block): Use set_unique_reg_note.
+ (expand_fix): Use set_unique_reg_note.
+
+Thu Mar 25 11:47:49 1999 Art Haas <ahaas@neosoft.com>
+
+ * tlink.c (symbol_hash_newfunc): Remove redundant call to
+ hash_newfunc.
+ (file_hash_newfunc, demangled_hash_newfunc): Likewise.
+
+Thu Mar 25 10:05:56 1999 Richard Henderson <rth@cygnus.com>
+
+ * i386.h (PREFERRED_STACK_BOUNDARY): Set to 128.
+
+1999-03-25 Philip Blundell <pb@nexus.co.uk>
+
+ Based on patch from Jim Studt <jim@federated.com>:
+ * config/arm/linux-elf.h (STARTFILE_SPEC, ENDFILE_SPEC): Copy
+ definitions from config/linux.h.
+ (DBX_BLOCKS_FUNCTION_RELATIVE): Define to 1.
+
+Thu Mar 25 02:12:42 1999 Finn Hakansson <finn@axis.com>
+
+ * loop.c (strength_reduce): Correct a comment.
+
+ * rtl.h (MEM_COPY_ATTRIBUTES): Remove unnecessary ending backslash.
+
+Thu Mar 25 02:02:13 1999 Axel Thimm <Axel.Thimm@physik.fu-berlin.de>
+
+ * Makefile.in (RANLIB_TEST): Improve test.
+
+Thu Mar 25 01:15:33 1999 Donn Terry <donn@interix.com>
+
+ * combine.c (force_to_mode, case PLUS): Use sign extended mask
+ when masking the low bits out of a constant.
+
+Tue Mar 23 15:45:25 1999 Richard Earnshaw (rearnsha@arm.com)
+ Jeff Law <law@cygnus.com>
+
+ * fold-const.c (make_range): If orig_type is unset, set it as soon
+ as we know the type. Remove now unnecessary set of orig_type for
+ conversions.
+
+Wed Mar 24 23:27:25 1999 Mark Elbrecht <snowball3@usa.net>
+ Jeff Law <law@cygnus.com>
+
+ * system.h (STDIN_FILENO): Provide default definition if one is not
+ provided by the system header files.
+ (STDOUT_FILENO, STDERR_FILENO): Likewise.
+
+ * i386/xm-djgpp.h (COLLECT2_HOST_INITIALIZATION): New macro.
+ * collect2.c (main): Use it.
+ (pexecute_pid): New variable. Holds return value from call to pexecute.
+ (collect2_execute): Rework to use pexecute instead of fork.
+ (collect2_wait): Use pwait() instead of wait().
+
+ * i386/djgpp.h: Fix typo.
+
+Wed Mar 24 23:24:30 1999 Jeffrey A Law (law@cygnus.com)
+
+ * fixinc/mkfixinc.sh: Recognize cygwin* instead of only
+ cygwin32.
+
+Wed Mar 24 15:44:12 1999 Nick Clifton <nickc@cygnus.com>
+
+ * config/m32r/m32r.c (init_idents): Accept both NAME and __NAME__
+ versions of attribute names and values.
+ (m32r_valid_machine_decl_attribute): Ditto.
+ (m32r_encode_section_info): Ditto.
+
+Wed Mar 24 21:42:15 1999 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * reload1.c (choose_reload_regs): If output-reloading for a
+ simple move insn, try to inherit an equivalence for the input.
+
+1999-02-24 Mike Stump <mrs@wrs.com>
+
+ * arm/aout.h (DBX_OUTPUT_MAIN_SOURCE_FILENAME): Fix quoting.
+
+1999-03-24 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ * libgcc2.c (__CTOR_LIST__, __DTOR_LIST__): Initialize on all
+ platforms.
+
+Wed Mar 24 01:35:01 1999 Geoff Keating <geoffk@ozemail.com.au>
+
+ * fold-const.c (fold): Recognise a rotate by an unsigned amount.
+
+Tue Mar 23 23:32:14 1999 Jeffrey A Law (law@cygnus.com)
+
+ * pa.md (rotlsi3): New expander. Synthesize a variable rotate
+ left using a variable rotate right. Provide anonymous pattern for
+ rotate left by a constant value.
+
+ * expr.c (expand_assignment): Do not try to optimize a aggregate
+ address which has VOIDmode.
+
+Tue Mar 23 22:51:48 1999 Mumit Khan <khan@xraylith.wisc.edu>
+ Donn Terry <donn@interix.com>
+
+ * protoize.c (abspath): Preserve multiple leading slashes for
+ _WIN32 and Interix.
+
+1999-01-23 Mike Stump <mrs@wrs.com>
+
+ * arm/vxarm.h: Split out vxWorks support into separate headerfile
+ and vxify.
+ * arm/arm.c (cpu_defaults): Allow arm710 as default.
+
+ * configure.in: Split out vxWorks support for Arm.
+ * configure: Rebuilt.
+
+Tue Mar 23 11:20:03 1999 Per Bothner <bothner@cygnus.com>
+
+ * tree.c (first_rtl_op, has_cleanups): Handle GOTO_SUBROUTINE_EXPR.
+
+Tue Mar 23 09:00:39 1999 Nick Clifton <nickc@cygnus.com>
+
+ * config/arm/riscix1.h (SUBTARGET_SWITCHES): Add doc string.
+ * config/arm/riscix1-1.h (SUBTARGET_SWITCHES): Add doc string.
+
+Tue Mar 23 07:50:20 1999 Mark Mitchell <mark@codesourcery.com>
+
+ * function.c: Include hash.h.
+ (insns_for_mem_entry): New struct.
+ (put_reg_into_stack): Take an optional hash-table mapping MEMs to
+ the INSNs that use them.
+ (fixup_var_refs): Likewise.
+ (put_addressof_into_stack): Likewise.
+ (purge_addressof_1): Likewise. Keep the hash-table up to date if
+ we add new instructions.
+ (fixup_var_refs_insns): Use it to avoid searching the entire
+ instruction chain.
+ (insns_for_mem_newfunc): New function.
+ (insns_for_mem_comp): Likewise.
+ (insns_for_mem_walk): Likewise.
+ (compute_insns_for_mem): Likewise.
+ (pop_function_context_from): Pass NULL for the hash-table.
+ (put_var_into_stack): Likewise.
+ (gen_mem_addressof): Likewise.
+ (flush_addressof): Likewise.
+ (purge_addressof): Call compute_insns_for_mem to pre-compute the
+ hash table.
+ * Makefile.in (OBJS): Include hash.o.
+ (function.o): Depend on hash.h.
+
+Tue Mar 23 00:39:14 1999 Jeffrey A Law (law@cygnus.com)
+
+ * i386/openbsd.h (TARGET_DEFAULT): Use symbolic names instead of
+ numbers.
+ * i386/netbsd.h, i386/freebsd.h: Likewise.
+
+ * crtstuff.c: Use ANSI function definitions. Fix minor whitespace
+ problems.
+
+ * i386/openbsd.h (TARGET_DEFAULT): Define.
+ * configure.in: Do not set TARGET_CPU_DEFAULT for x86 OpenBSD
+ configurations.
+ * configure: Rebuilt.
+
+Tue Mar 23 00:39:10 1999 John Wehle (john@feith.com)
+
+ * i386/freebsd.h (TARGET_DEFAULT): Define instead
+ of TARGET_CPU_DEFAULT.
+ * i386/netbsd.h (TARGET_DEFAULT): Likewise.
+
+Mon Mar 22 23:52:01 1999 Mumit Khan <khan@xraylith.wisc.edu>
+ Donn Terry <donn@interix.com>
+
+ * sdbout.c (syms.h): Don't include on Interix.
+ * toplev.c (main): No sbrk on Interix.
+
+ * configure.in: Add i386-pc-interix support.
+ * configure: Regenerate.
+ * fixinc.interix: New file.
+ * config/interix.h: New file.
+ * config/x-interix: New file.
+ * config/xm-interix.h: New file.
+ * i386/interix.h: New file.
+ * i386/interix.c: New file.
+ * i386/t-interix: New file.
+
+Mon Mar 22 23:41:49 1999 Jeffrey A Law (law@cygnus.com)
+
+ * i386.h (PREFERRED_STACK_BOUNDARY): Define.
+
+Mon Mar 22 23:41:31 1999 John Wehle (john@feith.com)
+
+ * i386.c (ix86_compute_frame_size): New function.
+ (ix86_prologue, ix86_epilogue): Use it.
+ * i386.h (INITIAL_ELIMINATION_OFFSET): Likewise.
+ * reload1.c: Provide default for PREFERRED_STACK_BOUNDARY.
+
+Mon Mar 22 18:06:59 1999 Jim Wilson <wilson@cygnus.com>
+
+ * mips/mips.h (TARGET_SWITCHES, TARGET_OPTIONS): Add option doc
+ strings.
+ * mips/abi64.h (SUBTARGET_TARGET_OPTIONS): Likewise.
+
+Mon Mar 22 16:18:27 1999 Nick Clifton <nickc@cygnus.com>
+
+ * config/arm/elf.h (VALID_MACHINE_DECL_ATTRIBUTE): Do not bother
+ passing ATTRIBUTES to arm_valid_machine_decl_attribute.
+
+ * config/arm/coff.h (VALID_MACHINE_DECL_ATTRIBUTE): Do not bother
+ passing ATTRIBUTES to arm_valid_machine_decl_attribute.
+
+ * config/arm/arm.h (DEFAULT_RTX_COSTS): Do not bother passing
+ OUTER_CODE to arm_rtx_costs - it is not used.
+ (arm_compare_fp): Delete declaration.
+ (FINAL_PRESCAN_INSN): Do not bother passing OPVEC or NOPERANDS to
+ arm_final_prescan_insn - they are not used.
+ (const_ok_for_op): Remove prototype.
+ (arm_rtx_costs): Fix prototype.
+ (arm_valid_machine_decl_attribute): Fix prototype.
+ (final_prescan_insn): Fix prototype.
+
+ * config/arm/arm.md: Remove references to arm_compare_fp.
+
+ * config/arm/arm.c (arm_compare_fp): Delete.
+ (const_ok_for_op): Make function static. Add prototype. Remove
+ mode parameter - it is unused.
+ (arm_rtx_costs): Remove outer_code parameter.
+ (reload_memory_operand): Declare mode parameter unused.
+ (power_of_two_operand): Declare mode parameter unused.
+ (equality_operator): Declare mode parameter unused.
+ (load_multiple_operation): Declare mode parameter unused.
+ (store_multiple_operation): Declare mode parameter unused.
+ (multi_register_push): Declare mode parameter unused.
+ (arm_valid_machine_decl_attribute): Remove attributes parameter -
+ it is unused.
+ (select_dominance_cc_mode): Remove op parameter - it is unused.
+ (gen_compare_reg): Remove fp parameter - it is unused.
+ (final_prescan_insn): Remove opvec and noperands parameters - they
+ are unused.
+
+Mon Mar 22 14:35:28 1999 Nick Clifton <nickc@cygnus.com>
+
+ * tm.texi (MD_SCHED_INIT): Add missing closing parenthesis.
+
+Mon Mar 22 22:24:30 1999 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * reload1.c (reload_as_needed): Set reload_is_output_reload /
+ reload_has_output_reload for auto_inc expressions that could be
+ reloaded. Call forget_old_reloads for REG_INC notes.
+
+Mon Mar 22 21:51:57 1999 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * cse.c (cse_insn): Don't change the result register of a libcall.
+
+Mon Mar 22 21:08:59 1999 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * rtl.h (shallow_copy_rtx): Declare.
+ * rtl.c (shallow_copy_rtx): New function.
+ * reload.c (find_reloads_toplev): Use shallow_copy_rtx instead of
+ copy_rtx.
+
+Mon Mar 22 10:44:33 1999 Vladimir Makarov <vmakarov@tofu.to.cygnus.com>
+
+ * config/h8300/h8300.md (adjust_length): New attribute.
+ (modhi3+1, andsi3+1, iorsi3+1, extzv+1, extzv+2): Change insn
+ default value of attribute "adjust_length" onto "no".
+
+ * config/h8300/h8300.c (h8300_adjust_insn_length): Adust
+ length only if the attribute "adjust_length" value is "yes".
+ Use 0 if the shift is negative.
+
+ * final.c (shorten_branches): Check insn length after its
+ adjusting.
+
+Sun Mar 21 17:33:48 1999 Jeffrey A Law (law@cygnus.com)
+
+ * i860.h (TARGET_SWITCHES): Add documentation for default case.
+ * i860/paragon.h (TARGET_SWITCHES): Add documentation for default case.
+ * i370.h (TARGET_SWITCHES): Add documentation for default case.
+ * fx80.h (TARGET_SWITCHES): Add documentation for default case.
+ * elxsi.h (TARGET_SWITCHES): Add documentation for default case.
+ * clipper.h (TARGET_SWITCHES): Add documentation for default case.
+ * 1750a.h (TARGET_SWITCHES): Add documentation for default case.
+ * pa.h (TARGET_SWITCHES): Add documentation for default case.
+ (TARGET_OPTIONS): Likewise for default case.
+ * mn10300.h (TARGET_SWITCHES): Add documentation for default case.
+ * h8300.h (TARGET_SWITCHES): Add documentation for default case.
+
+ * gcse.c (dump_hash_table): Fix whitespace in declaration.
+ (compute_transpout): Renamed from pre_compute_transpout.
+ (compute_pre_*): Deleted
+ (pre_expr_reaches_here_p): New argument, CHECK_PRE_COMP. All
+ callers changed.
+ (insert_insn_end_bb): Renamed from pre_insert_insn.
+ (pre_*): Delete unused variables. Only leave local properties and
+ global redundant/optimal computation points.
+ (alloc_pre_mem, free_pre_mem): Corresponding changes.
+ (compute_pre_data): Simplify and call pre_lcm to run the lazy
+ code motion dataflow analysis.
+ (pre_insert, pre_insert_copies, pre_delete): Revamp to use LCM
+ based redundant and optimal computation points.
+
+ * basic-block.h (pre_lcm, pre_rev_lcm): Declare.
+
+ * toplev.c (main): A debug option without a level defaults to
+ level 2.
+
+Sun Mar 21 12:13:01 1999 Nick Clifton <nickc@cygnus.com>
+
+ * flow.c (can_delete_label_p): Do not allow user specified
+ labels to be deleted.
+ * dwarf2out.c (gen_label_die): Generate addresses for deleted
+ (programmer specified) labels.
+ * dwarfout.c (output_label_die): Generate addresses for deleted
+ (programmer specified) labels.
+
+1999-03-21 Manfred Hollstein <manfred@s-direktnet.de>
+
+ * Makefile.in (xgcc$(exeext)): Add intl.o to list of files to be
+ linked with.
+
+Sun Mar 21 01:15:03 PST 1999 Jeff Law (law@cygnus.com)
+
+ * version.c: Bump for snapshot.
+
+Sat Mar 20 22:26:23 1999 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * sparc.h (TARGET_SWITCHES): Add null description to default case.
+
+Sat Mar 20 21:46:06 1999 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * c-lex.c (yylex): Remove unused variable `bytes'.
+
+ * flow.c (print_rtl_with_bb): Cast the return value of alloca.
+
+ * function.c (assign_parms): Wrap variable `varargs_setup' in
+ macro SETUP_INCOMING_VARARGS.
+ (thread_prologue_and_epilogue_insns): Mark parameter `f' with
+ ATTRIBUTE_UNUSED.
+
+ * local-alloc.c (no_equiv): Likewise for parameter `store'.
+
+ * sched.c (schedule_insns): Remove unused variables `insn' and `next'.
+
+ * tlink.c (symbol_hash_newfunc, symbol_hash_lookup,
+ file_hash_newfunc, file_hash_lookup, demangled_hash_newfunc,
+ demangled_hash_lookup, symbol_push, symbol_pop, file_push,
+ file_pop, tlink_init, tlink_execute, frob_extension,
+ obstack_fgets, tfgets, pfgets, freadsym, read_repo_file,
+ maybe_tweak, recompile_files, read_repo_files,
+ demangle_new_symbols, scan_linker_output): Add static prototype.
+
+ (symbol_hash_newfunc, file_hash_newfunc, demangled_hash_newfunc):
+ Make the third argument a `hash_table_key'.
+
+ * toplev.c (debug_start_source_file): Mark parameter `filename'
+ with ATTRIBUTE_UNUSED.
+
+Sun Mar 21 02:28:21 1999 Andreas Schwab <schwab@issan.cs.uni-dortmund.de>
+
+ * tm.texi (Varargs): Don't split argument of @item across lines.
+
+ * invoke.texi: Fix use of @item vs @itemx.
+
+Sun Mar 21 09:59:54 1999 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
+
+ * config/c4x/c4x.h (TARGET_SWITCHES): Add null description to
+ default case.
+
+Sat Mar 20 23:33:54 1999 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
+
+ * loop.c (check_dbra_loop): Fix debug message.
+
+Sat Mar 20 15:54:35 1999 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
+
+ * config/c4x/c4x.md (decrement_and_branch_on_count): Emit rptb_end
+ pattern instead of decrement_and_branch_until_zero pattern.
+
+Sat Mar 20 11:39:58 1999 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
+
+ * config/c4x/c4x.h (TARGET_SWITCHES): Add documentation.
+ * config/c4x/c4x.h (TARGET_OPTIONS): Add documentation.
+
+Fre Mar 19 23:26:29 1999 Martin von Löwis <loewis@informatik.hu-berlin.de>
+
+ * expr.c (expand_expr): Handle ERROR_MARK much earlier.
+
+Fri Mar 19 15:28:38 1999 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * cccp.c (create_definition): Cast to U_CHAR* when assigning to one.
+
+ * cppfiles.c (read_and_prescan): Likewise.
+ Start a #define in column 0.
+
+ * cpplib.c (cpp_define): Cast to U_CHAR* when assigning to one.
+ (cpp_push_buffer): Likewise for cpp_buffer*.
+ (do_include): Change the type of `fbeg' and `fend' to unsigned char*.
+ (do_endif): Cast to char* when assigning to one.
+ (do_assert): Likewise.
+ (do_unassert): Likewise.
+ (cpp_read_check_assertion): Change the type of `name' to U_CHAR*.
+ Don't do unnecessary cast to char* anymore.
+
+ * genrecog.c (make_insn_sequence): Cast to char** when assigning
+ to one. Cast the first argument of bzero to PTR.
+
+ * loop.c (strength_reduce): Remove unused variable `note'.
+
+ * reload1.c (new_insn_chain): Cast to struct insn_chain* when
+ assigning to one.
+
+ * rtl.c (copy_rtx): Use memcpy instead of bcopy.
+
+Fri Mar 19 11:19:31 1999 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * calls.c (initialize_argument_information): Mark parameters
+ `num_actuals' and `n_named_args' with ATTRIBUTE_UNUSED.
+
+ * dbxout.c (dbxout_start_new_source_file): Likewise for parameter
+ `filename'.
+ (dbxout_finish): Likewise for parameters `file' and `filename'.
+ (dbxout_prepare_symbol): Likewise for parameter `decl'.
+ (dbxout_begin_function): Likewise.
+
+ * explow.c (hard_function_value): Likewise for parameter `func'.
+
+ * function.c (locate_and_pad_parm): Likewise for parameter `fndecl'.
+
+ * expmed.c (expand_divmod): Omit unused argument to `expand_abs'.
+ * expr.c (expand_expr): Likewise.
+ * expr.h (expand_abs): Delete unused argument from prototype.
+ * optabs.c (expand_abs): Remove unused parameter `unsignedp'.
+
+ * sdbout.c (sdbout_init): Mark parameter `syms' with ATTRIBUTE_UNUSED.
+ (sdbout_end_block): Likewise for parameter `n'.
+
+ * toplev.c (debug_define): Likewise for parameters `lineno' and
+ `buffer'.
+ (debug_undef): Likewise.
+
+ * varasm.c (named_section): Likewise for parameter 'reloc'.
+ (assemble_external): Likewise for parameter `decl'.
+ (assemble_alias): Likewise for parameter `target'.
+
+Fri Mar 19 01:54:30 1999 Theodore Papadopoulo <Theodore.Papadopoulo@sophia.inria.fr>
+
+ * toplev.c (read_integral_parameter): Constify. Better control of
+ error messages.
+ (main): Use read_integral_parameter to set optimize, id_clash_len,
+ larger_than_size, and the debugging level.
+ * toplev.h (read_integral_parameter): Update prototype.
+
+Fri Mar 19 01:42:05 1999 Zack Weinberg <zack@rabi.phys.columbia.edu>
+
+ * system.h: Use putc_unlocked, fputc_unlocked, and
+ fputs_unlocked only if putc_unlocked has a prototype already.
+ Prototype fputs_unlocked if necessary.
+ * configure.in: Check for prototypes of putc_unlocked and
+ fputs_unlocked.
+ * acconfig.h: Updated.
+ * config.in, configure: Rebuilt.
+
+Fri Mar 19 02:45:12 1999 Alexandre Oliva <oliva@dcc.unicamp.br>
+
+ * Makefile.in (INTL_TARGETS): new macro
+ ($(INTL_TARGETS)): depend on generated sources; drop dependencies
+ on cp/parse.c and objc/objc-parse.c
+ ($(srcdir)/cp/parse.c): move to cp/Make-lang.in
+ * objc/Make-lang.in ($(INTL_TARGETS)): depend on objc/objc-parse.c
+
+Thu Mar 18 22:28:53 1999 Jeffrey A Law (law@cygnus.com)
+
+ * i860.h (TARGET_SWITCHES): Add documentation.
+ * i860/paragon.h (TARGET_SWITCHES): Add documentation.
+ * i370.h (TARGET_SWITCHES): Add documentation.
+ * fx80.h (TARGET_SWITCHES): Add documentation.
+ * elxsi.h (TARGET_SWITCHES): Add documentation.
+ * clipper.h (TARGET_SWITCHES): Add documentation.
+ * 1750a.h (TARGET_SWITCHES): Add documentation.
+ * pa.h (TARGET_SWITCHES): Add documentation.
+ (TARGET_OPTIONS): Likewise.
+ * mn10300.h (TARGET_SWITCHES): Add documentation.
+ * h8300.h (TARGET_SWITCHES): Add documentation.
+
+Thu Mar 18 15:58:26 1999 Nick Clifton <nickc@cygnus.com>
+
+ * loop.c (strength_reduce): Do not perform pseudo replacements
+ if the loop contains volatile memory references.
+
+Thu Mar 18 19:09:50 1999 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * reload.c (find_reloads_toplev): When processing X recursively,
+ don't alter it destructively except by filling in constants.
+
+Thu Mar 18 10:14:18 1999 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * cccp.c (default_include): Initialize structure memebers.
+ (pass_thru_directive): Change the type of 'keyword_length' to int.
+ (main): Cast `bindtextdomain' and `textdomain' to (void).
+
+ * collect2.c (main): Likewise.
+
+ * cppmain.c (main): Likewise.
+
+ * gcc.c (main): Likewise.
+
+ * gcov.c (main): Likewise.
+
+ * protoize.c (main): Likewise.
+
+ * toplev.c (main): Likewise.
+
+1999-03-18 Gavin Romig-Koch <gavin@cygnus.com>
+
+ * config/mips/mips.c (mips_explicit_type_size_string): Correct
+ its type.
+
+Thu Mar 18 01:24:25 1999 Jeffrey A Law (law@cygnus.com)
+
+ * configure.in: Use "exit 1", not "exit (1)".
+ * configure: Rebuilt.
+
+Wed Mar 17 23:17:42 1999 Mark Kettenis <kettenis@gnu.org>
+
+ * config/t-gnu (SYSTEM_HEADER_DIR): New variable. Set to
+ `/include' in order to find the system's limits.h.
+
+Wed Mar 17 23:00:18 1999 Robert Lipe <robertlipe@usa.net>
+
+ * fixinc/fixincl.c: Include auto-host.h instead of config.h
+ * fixinc/procopen.c: Likewise.
+ * fixinc/regex.c: Likewise.
+ * fixinc/server.c: Likewise.
+
+Wed Mar 17 22:46:13 1999 Mark Elbrecht <snowball3@usa.net.
+
+ * config/i386/go32.h: Delete.
+ * config/i386/djgpp.h: New. Renamed from go32.h.
+ Added -DDJGPP=2 to CPP_PREDEFINES.
+ * config/i386/go32-rtems.h: Delete.
+ * config/i386/djgpp-rtems.h: New. Renamed from go32-rtems.h.
+ Added -DDJGPP=2 to CPP_PREDEFINES.
+ * config/i386/xm-go32.h: Delete.
+ * config/i386/xm-djgpp.h: New. Renamed from xm-go32.h.
+ * config/i386/x-go32: Delete.
+ * config/i386/x-djgpp: New. Renamed from x-go32.
+ * config/i386/t-go32: Delete.
+ * config/i386/t-djgpp: New. Renamed from t-go32.
+ * configure.in(pc-msdosdjgpp): Set xm_file to i386/xm-djgpp.h.
+ Set tm_file to i386/djgpp.h. Set tmake_file to i386/t-djgpp.
+ Set xmake_file to i386/x-djgpp.
+ (*-go32-msdos, *-go32*): Remove entries. Warn that GO32/DJGPP V1.X
+ is now unsupported and *-pc-msdosdjgpp for DJGPP V2.X should be
+ used instead.
+ * configure: Rebuilt.
+
+ * gcc.c (process_command): Dump link_command_spec too.
+
+Wed Mar 17 20:38:08 1999 Jerry Quinn <jquinn@nortelnetworks.com>
+ Jeff Law <law@cygnus.com>
+
+ * pa.md: Add real PA8000 scheduling information.
+
+ * pa.h (processor_type): Add PROCESSOR_8000 symbol.
+ (ISSUE_RATE): Revamp, including PA8000 support.
+ * pa.c (override_options): Add 8000 as -mschedule= option.
+ Do not call strcmp if pa_cpu_string is null.
+ * pa.md (attr cpu): Add 8000.
+ * invoke.texi: Add documentation for PA8000 scheduling.
+
+Wed Mar 17 18:20:24 1999 David S. Miller <davem@redhat.com>
+
+ * config/sparc/sparc.h (TARGET_SWITCHES, TARGET_OPTIONS):
+ Add descriptions.
+ * config/sparc/sp64-elf.h (SUBTARGET_SWITCHES): Likewise.
+ * config/sparc/splet.h (SUBTARGET_SWITCHES): Likewise.
+
+Wed Mar 17 14:51:19 1999 Richard Henderson <rth@cygnus.com>
+
+ * flow.c (compute_immediate_dominators): New function.
+ * basic-block.h (compute_immediate_dominators): Declare it.
+
+ * alpha.h (HARD_REGNO_MODE_OK): Allow only 4 and 8 byte unit modes
+ in FP regs.
+ (MODES_TIEABLE_P): Define asymmetricly wrt modes illegal in FP regs.
+
+Wed Mar 17 14:41:41 1999 Nick Clifton <nickc@cygnus.com>
+
+ * config/arm/aout.h (ASM_GENERATE_INTERNAL_LABEL): Fix compile
+ time warning.
+ * config/arm/arm.md: Fix various compile time warnings.
+ * config/arm/arm.h: Fix various compile time warnings. Add
+ function prototypes.
+ * config/arm/arm.c: Fix various compile time warnings.
+ (arm_override_options): Reorganise to seperate tuning from
+ targetting.
+ (bit_count): New function: Return a count of the number of bits
+ set in a word.
+
+Wed Mar 17 21:29:12 1999 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * reload1.c (eliminate_regs): Don't keep REG_DEAD notes around for
+ things that were eliminated.
+
+Wed Mar 17 12:16:26 1999 Richard Henderson <rth@cygnus.com>
+
+ * function.c (fixup_var_refs_1): First try moving the expression
+ directly into a register. Don't separate cc0 setter and user.
+
+Wed Mar 17 11:20:29 1999 Dave Brolley <brolley@cygnus.com>
+
+ * cppfiles.c (PIPE_BUF): #define PIPE_BUF if not defined already.
+
+Wed Mar 17 09:25:06 1999 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * c-lex.c: Don't include setjmp.h.
+ (parse_float): New static function.
+ (pf_args): New struct.
+ (yylex): Use them in call to `do_float_handler'.
+
+1999-03-16 Andreas Schwab <schwab@issan.cs.uni-dortmund.de>
+
+ * cexp.y (yyerror): Call verror to get a usefull error message.
+ * cexp.c: Rebuilt.
+
+ * .gdbinit: Move command to put breakpoint at abort to end of file
+ so that gdb does not bail out early.
+
+Tue Mar 16 15:30:19 1999 Nick Clifton <nickc@cygnus.com>
+
+ * rtl.h: Rename prototype for free_bb_memory to free_bb_mem.
+
+Tue Mar 16 23:40:09 1999 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * sh.md (movsi_i): Move t/r alternative after r/rI alternative.
+
+Tue Mar 16 13:44:50 1999 Jim Wilson <wilson@cygnus.com>
+
+ * mn10200/mn10200.md (addsi3, subsi3, ashlsi3, lshrsi3, ashrsi3):
+ Delete emit_library_call_value declaration.
+
+1999-03-16 16:06 -0500 Zack Weinberg <zack@rabi.columbia.edu>
+
+ * cppfiles.c (read_and_prescan): Map backslash-newline to '\r'
+ (which cannot otherwise appear in the processed buffer) and
+ move it out of tokens that it appears in the middle of.
+ Improve performance.
+ (find_position): New function.
+
+ * cpplib.c: \r (one character) indicates backslash
+ newline, not \\\n (two characters). It cannot appear in the
+ middle of a token. Call CPP_BUMP_LINE (pfile) whenever
+ parsing moves past \n or \r. Increment pfile->lineno whenever
+ a \n is placed into token_buffer. Only one mark can exist at
+ a time, and CPP_BUMP_LINE must not be used while it is
+ active. It is automatically cleared by cpp_pop_buffer and
+ parse_goto_mark. \r is not in is_hor_space or is_space.
+
+ (NEWLINE_FIX, NEWLINE_FIX1, adjust_position,
+ update_position, count_newlines, parse_move_mark): Removed.
+ (parse_string, copy_comment): New functions.
+ (parse_name): Returns void.
+ (parse_set_mark, parse_clear_mark, parse_goto_mark): Take only
+ one argument, a cpp_reader *. Change for new marking scheme.
+ (skip_comment): Handle CHILL line comments too. Second
+ argument is now first character of comment marker; all callers
+ changed. Issue error for unterminated block comment here.
+ (cpp_skip_hspace): Recognize CHILL comments.
+ (copy_rest_of_line): Likewise. Call skip_comment and
+ parse_string directly, don't go through cpp_get_token. Emit
+ "/**/" for block comments if -traditional (create_definition
+ needs this).
+ (do_define): Don't play with put_out_comments.
+ (cpp_push_buffer): Initialize ->mark to -1.
+ (cpp_buf_line_and_col): Just read out the values in the buffer
+ structure.
+ (output_line_command): Use cpp_buf_line_and_col. Fix
+ formatting. Remove stale code.
+ (cpp_get_token): Break out string parsing code to
+ parse_string. Use skip_comment for CHILL comments too. Use
+ copy_comment for put_out_comments instead of dinking with
+ marks. Remove stale code. Don't call output_line_command
+ unless it's necessary.
+
+ * cpplib.h (parse_marker): Removed.
+ (struct cpp_buffer): line_base is now a unsigned char *; add
+ `mark' [long], remove `marks' [struct parse_marker *].
+ (parse_set_mark, parse_clear_mark, parse_goto_mark): Update
+ prototypes.
+ (CPP_BUMP_LINE, CPP_BUMP_BUFFER_LINE): New macros.
+ * cppinit.c (is_hor_space, is_space): '\r' is not considered
+ whitespace.
+ * cppexp.c (cpp_parse_expression): Use cpp_skip_hspace, not
+ SKIP_WHITE_SPACE.
+ * cpphash.c (macarg): Disable line commands while expanding.
+
+Tue Mar 16 11:30:19 1999 Gavin Romig-Koch <gavin@cygnus.com>
+
+ * c-lex.c (yylex) : Remove warning for integer literals being
+ larger than the largest target int. Add warning for integer
+ literal being larger than than its choosen type.
+
+Tue Mar 16 10:53:17 1999 Gavin Romig-Koch <gavin@cygnus.com>
+
+ * invoke.texi: Add -mlong32 documentation.
+ * config/mips/mips.h (mips_explicit_type_size_string): New.
+ (TARGET_SWITCHES): Add 'long32'.
+ (TARGET_OPTIONS): Add 'explicit-type-size'.
+ (CC1_SPECS): Set -mexplicit-type-size.
+ (LONG_MAX_SPEC): Change a use of 'no-long64' to 'long32'.
+ * config/mips/abi64.h (LONG_MAX_SPEC): Same. Add 'mabi=32'.
+ * config/mips/mips.c (mips_explicit_type_size_string): New.
+ (override_options): Use it.
+ * config/mips/osfrose.h (CC1_SPECS): Set -mexplicit-type-size.
+
+ * config/mips/mips.h (SUBTARGET_CPP_SIZE_SPEC):
+ Pointer size now depends on both size longs and size of GP
+ registers.
+
+Tue Mar 16 10:22:22 1999 Gavin Romig-Koch <gavin@cygnus.com>
+
+ * config/mips/iris.h (CTORS_SECTION_ASM_OP,DTORS_SECTION_ASM_OP,
+ dtors_section): Use Pmode == DImode rather than TARGET_LONG64.
+ * config/mips/mips.c (override_options): Allow -mlong64 and
+ -mint64 with -mips2 or less.
+ * config/mips/mips.h (MASK_LONG64): Fix comment.
+ (POINTER_SIZE): Use Pmode == DImode rather than TARGET_LONG64.
+ (Pmode): Make Pmode the smaller of longs or gp registers.
+ * invoke.texi: Note the new size for pointers.
+
+Mon Mar 15 22:45:25 1999 David Edelsohn <edelsohn@gnu.org>
+
+ * rs6000.h (ASM_OUTPUT_{DOUBLE,FLOAT}): Always generate IEEE 754
+ bit-pattern directly.
+ (ASM_OUTPUT_REG_{PUSH,POP}): Delete.
+ * rs6000.c (first_reg_to_save): If profiling and context needed,
+ allocate a reg to save static chain for all ABIs. For AIX
+ profiling, calculate parameter registers to save based on need.
+ (output_function_profiler): Save and restore static chain around
+ profile call for all ABIs.
+
+1999-03-15 21:39 -0500 Zack Weinberg <zack@rabi.columbia.edu>
+
+ * cppinit.c: Instead of one pending list, keep separate lists
+ for each category of pending option: -D/-U, -A, -include,
+ -imacros. Move the four partial include-path lists into the
+ pending block. Use head and tail pointers so we don't ever
+ have to reverse the lists.
+
+ (cpp_start_read): Break out blocks of code to their own
+ functions: install_predefs and initialize_dependency_output.
+ Use path_include for C_INCLUDE_PATH and friends as well as
+ CPATH. Remove include_defaults gunk. Warn about the
+ combination of -lang-chill and -trigraphs. Optimize string
+ bashing. Walk each pending list once, deallocating as we go.
+
+ (append_include_chain): Brought over from cppfiles.c. Mark
+ dirs as system include dirs if and only if appending to
+ system include path. If opts->verbose, print a notice when a
+ dir is dropped from the include path because it doesn't
+ exist. Fix memory leak: this function is not supposed to copy
+ its DIR argument.
+
+ (nreverse_pending, push_pending): Removed.
+ (APPEND): New macro for adding to pending lists.
+ (path_include): Can now add to any partial include path.
+ (base_name): Bring over from cccp.c.
+ (cpp_options_init): Allocate the pending block.
+ (cpp_handle_option): Add --version. Exit after --help. Fix
+ formatting. Order -ifoo options by frequency of usage.
+ (install_predefs): New function, simplified version of code
+ that was in cpp_start_read.
+ (initialize_dependency_output): Likewise. Understand OBJECT_SUFFIX.
+
+ * cppfiles.c (simplify_pathname): Export.
+ (merge_include_chains): Don't nreverse the lists. If
+ opts->verbose, print a notice when a duplicate dir is detected
+ and dropped from the include path.
+ (finclude): Fix excessive cleverness in setting
+ fp->system_header_p.
+ (actual_directory): Set x->sysp from
+ CPP_BUFFER (pfile)->system_header_p so that one system header
+ may include another with "".
+ (deps_output): Fix double adjustment of deps_size which would
+ cause all dependencies after the first two lines to be lost.
+
+ * cpplib.c (cpp_unassert): New function.
+ * cpplib.h: Lay out struct cpp_pending here. Adjust
+ prototypes. Add include_prefix_len to struct cpp_options.
+
+Mon Mar 15 16:01:52 1999 Jim Wilson <wilson@cygnus.com>
+
+ * config/misp/mips.h (REGISTER_MOVE_COST): Make the cost of moving
+ from HI/LO/HILO/MD into general registers the same as for one
+ of moving general registers to HI/LO/HILO/MD.
+
+Mon Mar 15 12:39:38 1999 Nick Clifton <nickc@cygnus.com>
+
+ * config/m32r/m32r.c (init_idents): New function. Initialise
+ static tree nodes for m32r specific attribute identifiers. Remove
+ leading and trailing double underscores from the attribute names.
+ (m32r_valid_machine_decl_attribute): Call init_idents.
+ (m32r_encode_section_info): Call init_idents.
+
+Mon Mar 15 10:20:20 1999 Mark Mitchell <mark@markmitchell.com>
+
+ * reload.c (find_reloads): Add a REG_LABEL note if we substitute a
+ LABEL_REF for something else.
+
+Mon Mar 15 08:24:17 1999 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * fold-const.c (exact_real_inverse): Move variable `float_error'
+ into the scope where it is used.
+ (const_binop_1): New static function.
+ (cb_args): New struct.
+ (const_binop): Use them in call to `do_float_handler'.
+ (fold_convert_1): New static function.
+ (fc_args): New struct.
+ (fold_convert): Use them in call to `do_float_handler'.
+
+Mon Mar 15 22:50:18 1999 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
+
+ * rtlanal.c (auto_inc_p): New function.
+ * rtl.h (auto_inc_p): Prototype it.
+ * reload1.c (add_auto_inc_notes): New function.
+ (reload): Strip REG_INC notes and call add_auto_inc_notes
+ for each insn to restore them correctly.
+
+1999-03-15 Manfred Hollstein <manfred@s-direktnet.de>
+
+ * fixinc/Makefile.in (procopen.o): List the actual
+ dependencies.
+
+Sun Mar 14 16:22:10 1999 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * cse.c (check_fold_consts): New static function.
+ (cfc_args): New struct.
+ (simplify_relational_operation): Use them in call to
+ `do_float_handler'.
+
+ * toplev.c (do_float_handler): New function to wrap calls to
+ setjmp/set_float_handler.
+
+ * toplev.h (do_float_handler): Add extern prototype.
+
+ * tree.c (build_real_from_int_cst_1): New static function.
+ (brfic_args): New struct.
+ (build_real_from_int_cst): Use them in call to
+ `do_float_handler'.
+
+Sun Mar 14 01:15:06 PST 1999 Jeff Law (law@cygnus.com)
+
+ * version.c: Bump for snapshot.
+
+Sat Mar 13 17:37:18 1999 Richard Henderson <rth@cygnus.com>
+
+ * haifa-sched.c (sched_analyze_1): Only clear reg_last_uses on a SET.
+
+Sat Mar 13 11:36:16 1999 Richard Earnshaw (rearnsha@arm.com)
+
+ * arm.c (arm_split_constant): Don't try to force a constant to
+ memory after arm_reorg has run.
+ (after_arm_reorg): New static variable.
+ (arm_reorg): Set it.
+ (output_func_epilogue): Clear it.
+
+Fri Mar 12 20:26:32 1999 David Edelsohn <edelsohn@gnu.org>
+
+ * configure.in ({rs6000,powerpc}-ibm-aix*): Set float_format to none.
+ * configure: Rebuilt.
+
+Fri Mar 12 20:45:30 1999 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * unroll.c (loop_iterations): Don't return a final value for EQ
+ comparison loops.
+
+Fri Mar 12 12:35:01 1999 Jim Wilson <wilson@cygnus.com>
+
+ * reload1.c (calculate_needs_all_insns): When ignore equivalence
+ setting insn, clear need_elim, need_reload, and need_operand_change.
+
+Fri Mar 12 07:54:43 1999 Bruce Korb <korb@datadesign.com>
+
+ * fixinc/fixinc.*: Some changes from the fixincl-branch
+ were not applied (??!!). Corrected.
+
+ * fixinc/Makefile.in: same thing.
+
+Fri Mar 12 00:51:43 1999 Jeffrey A Law (law@cygnus.com)
+
+ * expr.c (expand_expr): Allow a CALL_EXPR with a mode wider than
+ MAX_INTEGER_COMPUTATION_MODE.
+
+Thu Mar 11 14:00:58 1999 Richard Henderson <rth@cygnus.com>
+
+ * alpha.h (HARD_REGNO_MODE_OK): Disallow QI/HImode in fp regs.
+ (MODES_TIEABLE_P): Update.
+
+ * alpha.md (ev5_e0): Conflict loads and stores.
+
+Thu Mar 11 13:55:52 1999 Richard Henderson <rth@cygnus.com>
+
+ * machmode.h (smallest_mode_for_size): Prototype.
+ * stor-layout.c (smallest_mode_for_size): Remove static.
+
+Thu Mar 11 21:25:59 1999 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * loop.c (strength_reduce): Don't do biv increment -> DEST_REG giv
+ conversion if we don't know the lifetime.
+
+Thu Mar 11 20:37:59 1999 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * reload.1c (delete_address_reloads_1): Check for reloads of
+ CURRENT_INSN even if it sets DST.
+
+Thu Mar 11 10:29:50 1999 Jason Merrill <jason@yorick.cygnus.com>
+
+ * dwarf2out.c (add_AT_lbl_offset): Rename from add_AT_section_offset.
+ (print_die, size_of_die, value_format, output_die): Adjust.
+
+Thu Mar 11 10:27:42 1999 Robert Lipe <robertlipe@usa.net>
+
+ * dwarf2out.c (TEXT_SECTION_LAABEL, DEBUG_LINE_SECTION_LABEL,
+ DEBUG_INFO_SECTION_LABEL, ABBREV_SECTION_LABEL,
+ text_section_laabel, debug_line_section_label,
+ debug_info_section_label, abbrev_section_label): New.
+ (output_compilation_unit_header): Emit label associated
+ with section instead of section name itself.
+ (out_pubnames, output_aranges, output_line_info,
+ dwarf2out_finish): Likewise.
+ (dwarf2out_init): Build internal label names for sections
+ from static labels.
+
+Thu Mar 11 17:28:32 1999 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * sh.md (mulsi3): End mul.l sequence with a no-op move.
+
+Thu Mar 11 08:52:02 1999 Bruce Korb <korb@datadesign.com>
+
+ * Makefile.in: activated fixinc/mkfixinc.sh
+ * configure.in: activated fixinc/mkfixinc.sh
+
+Thu Mar 11 01:38:02 1999 Mumit Khan <khan@xraylith.wisc.edu>
+
+ * cppfiles.c (INO_T_EQ): Handle UWIN.
+
+ * c-common.c (decl_attributes): Flag unrecognized attribute
+ functions as warnings instead of as errors.
+
+ Support for i386-pc-uwin.
+ * i386/uwin.h: New file.
+ * i386/xm-uwin.h: New file.
+ * i386/t-uwin: New file.
+ * i386/uwin.asm: New file.
+ * configure.in (i[3456]86-*-uwin*): Define.
+ Add Workaround for vfork bug when hosted on uwin.
+ * configure: Regenerate.
+
+ * cccp.c (INO_T_EQ): Undefine. UWIN has inodes.
+ (absolute_filename): UWIN uses POSIX pathnames only.
+ * libgcc2.c (getpagesize): Do not define for UWIN.
+ (mprotect): Likewise.
+ * protoize.c (dirent.h): Conditionally include.
+ (fputc): Prototype only if it's not a macro.
+
+Wed Mar 10 02:49:04 1999 Jason Merrill <jason@yorick.cygnus.com>
+
+ * configure.in: Remove init_priority stuff.
+
+1999-03-11 Colin Smith <colin@wrs.com>
+
+ * sdbout.c (plain_type_1): Make boolean types work better with sdb.
+
+Thu Mar 11 00:20:52 1999 Alexandre Oliva <oliva@dcc.unicamp.br>
+
+ * gcc.texi: Update bug reporting instructions to match
+ current ezmlm list reality.
+
+Wed Mar 10 23:11:19 1999 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * gcc.c (print_file_name, print_prog_name, spec_machine,
+ read_specs, set_spec, lookup_compiler, build_search_list,
+ putenv_from_prefixes, find_a_file, record_temp_file,
+ delete_if_ordinary, handle_braces, do_spec, do_spec_1, find_file,
+ is_directory, validate_switches, used_arg, default_arg,
+ pfatal_with_name, perror_with_name, pfatal_pexecute, fatal, error,
+ notice, add_preprocessor_option, add_assembler_option,
+ add_linker_option, process_command, execute,
+ unused_prefix_warnings, clear_args, fatal_error,
+ lang_specific_driver, user_specs, compiler, link_command_spec,
+ option_map, translate_options, make_temp_file, temp_name,
+ programname, path_prefix, machine_suffix, just_machine_suffix,
+ gcc_exec_prefix, standard_exec_prefix, standard_exec_prefix_1,
+ md_exec_prefix, md_startfile_prefix, md_startfile_prefix_1,
+ standard_startfile_prefix, standard_startfile_prefix_1,
+ standard_startfile_prefix_2, tooldir_base_prefix, tooldir_prefix,
+ multilib_dir, temp_filename, temp_file, command, switchstr,
+ infile, outfiles, input_filename, input_basename, input_suffix,
+ check_live_switch, main): Qualify a char* with the `const' keyword.
+
+Wed Mar 10 20:28:29 1999 Jeffrey A Law (law@cygnus.com)
+
+ * lcm.c: New file.
+ * Makefile.in (OBJS): Add lcm.o
+ (lcm.o): Add dependencies.
+
+ * gcse.c (compute_pre_local_properties): Delete.
+ (compute_pre_data): Use compute_local_properties instead of
+ compute_pre_local_properties.
+
+ * gcse.c: More comments, whitespace and similar fixes.
+ (dump_cuid_table, maybe_set_rd_gen, dump_cprop_data): Delete.
+ (dump_pre_data, compute_cprop_local_properties): Likewise.
+ (one_classic_gcse_pass): Lose unused argument. All callers changed.
+ (compute_hash_table, compute_expr_hash_table): Likewise.
+ (compute_set_hash_table, one_pre_gcse_pass, mark_call): Likewise.
+ (cprop_insn, cprop, one_cprop_pass): Add new argument ALTER_JUMPS.
+ All callers changed. Only alter jumps if ALTER_JUMPS is nonzero.
+ Lose unused argument.
+ (gcse_main): Always run a cprop pass after finishing global cse.
+ (compute_local_properties): New function.
+ (hash_scan_pat, hash_scan_insn): No longer call maybe_set_rd_gen.
+ (compute_cprop_data): Use compute_local_properties.
+
+ * gcse.c: Update various comments.
+ (current_function_calls_longjmp): Delete declaration.
+
+ * gcse.c (run_jump_opt_after_gcse): New variable.
+ (gcse_main): Returns an integer.
+ (hash_scan_set): Record initializations from CONST_DOUBLEs too.
+ (try_replace_reg): Update some comments.
+ (cprop_insn): Allow propagation into some JUMP_INSNs too.
+ * rtl.h (gcse_main): Update prototype.
+ * toplev.c (rest_of_compilation): If gcse_main returns nonzero,
+ then run a jump optimization pass.
+ * jump.c (delete_barrier_successors): Delete nop jumps too.
+
+Wed Mar 10 19:04:31 1999 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * sh.c (fp_arith_reg_operand): Actually test if reg is suitable
+ for FP arithmetic. Changed caller.
+ * sh.md (subsf3, subsf_i): Use fp_arith_reg_operand.
+
+Wed Mar 10 18:56:31 1999 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * reload1.c (choose_reload_regs): When inheriting from the frame
+ pointer, don't clobber it.
+
+Wed Mar 10 08:01:52 1999 Bruce Korb <korb@datadesign.com>
+
+ * fixinc/fixinc.*: Resync-ed with the files in this
+ directory.
+
+ * fixinc/mkfixinc.sh: the machine case elements were
+ out-of-order. (the ix86-*-linux-gnu* entry needed to
+ be earlier).
+
+Wed Mar 10 00:01:24 1999 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * reload1.c (reload_combine_note_store): Fix calculation of number
+ of affected registers.
+
+Tue Mar 9 15:48:15 1999 Richard Henderson <rth@cygnus.com>
+
+ * flow.c (tidy_fallthru_edge): Be more careful finding the last
+ BARRIER of a list. Delete the cc0 setter as well as a cond jump.
+
+Tue Mar 9 15:26:02 1999 Hans-Peter Nilsson <hp@bitrange.com>
+
+ * i386.md (ashlsi3 splitter): Fix typo in last change.
+
+Tue Mar 9 11:35:20 1999 Richard Henderson <rth@cygnus.com>
+
+ * reg-stack.c (stack_reg_life_analysis): Use returnjump_p
+ instead of an explicit test for RETURN.
+
+Tue Mar 9 09:33:16 1999 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * Makefile.in (toplev.o): Depend on $(BASIC_BLOCK_H).
+
+ * toplev.c: Include basic-block.h.
+
+Tue Mar 9 02:08:17 1999 Jeffrey A Law (law@cygnus.com)
+
+ * calls.c (load_register_parameters): New function.
+ (expand_call): Use it.
+
+ * calls.c (expand_call): Slightly reorganize code.
+
+ * calls.c (compute_argument_addresses): New function.
+ (rtx_for_function_call): New function.
+ (expand_call): Use them.
+
+ * i386.md (zero_extendhisi2): Split into an expander and anonymous
+ pattern. Add new anonymous pattern for use when optimizing for
+ size or for the PPro.
+ (zero_extendqihi2, zero_extendqisi2): Likewise.
+
+Mon Mar 8 23:43:47 1999 Richard Henderson <rth@cygnus.com>
+
+ * haifa-sched.c (sched_analyze_1): Fix last change -- add clobber
+ dependancies to sets in the non-hard-reg case too.
+
+Mon Mar 8 18:55:21 1999 Marc Espie <espie@cvs.openbsd.org>
+
+ * config/openbsd.h (HANDLE_SYSV_PRAGMA): Define.
+
+Mon Mar 8 16:04:44 1999 Jim Wilson <wilson@cygnus.com>
+
+ * local-alloc.c (combine_regs): Don't combine if we have a hard reg
+ for which CLASS_LIKELY_SPILLED_P is true.
+
+ * unroll.c (loop_iterations): Only call loop_find_equiv_value if we
+ have a REG or SUBREG.
+
+Mon Mar 8 15:27:42 1999 Jeffrey A Law (law@cygnus.com)
+
+ * i386.md (ashlsi3): Revise comments. Provide new anonymous
+ pattern for Pentium and PPro/PII. Reverse constraints in
+ generic ashlsi3 anonymous pattern.
+
+ * calls.c (initialize_argument_info): Accept a pointer to
+ CUMULATIVE_ARGS.
+ (expand_call): Pass the address of CUMULATIVE_ARGS.
+
+ * rs6000/xm-sysv4.h (HOST_BITS_PER_LONGLONG): Remove #if 0.
+
+ * mn10300.h (CASE_DROPS_THROUGH): Delete.
+ * mn10200.h (CASE_DROPS_THROUGH): Delete.
+ * h8300.h (CASE_DROPS_THROUGH): Delete.
+
+ * flow.c (merge_blocks_nomove): For HAVE_cc0 targets, make sure
+ to also delete the cc0 setter when deleting a conditional branch
+ to the next block.
+
+Mon Mar 8 18:47:11 1999 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * regmove.c (copy_src_to_dest): New argument max_old_uid.
+
+Mon Mar 8 08:23:00 1999 Bruce Korb <korb@datadesign.com>
+
+ * ChangeLog: merged entries from fixincl-branch
+
+Sun Mar 7 11:48:56 1999 Richard Henderson <rth@cygnus.com>
+
+ * haifa-sched.c (ENCODE_BLOCKAGE): Don't shift unit too far.
+ (print_exp): Special case addition of a constant.
+ (print_value) [CONST_INT]: Use HOST_WIDE_INT_PRINT_HEX.
+
+Sun Mar 7 11:21:02 1999 Richard Henderson <rth@cygnus.com>
+
+ * haifa-sched.c (reg_last_clobbers): New.
+ (reg_pending_clobbers, bb_reg_last_clobbers): New.
+ (compute_block_backward_dependences): Allocate memory for them.
+ (schedule_region): Likewise.
+ (sched_analyze_1): Clobbers don't interfere with one another.
+ They do interfere with sets ...
+ (sched_analyze_2): ... and uses.
+ (sched_analyze): Likewise.
+ (sched_analyze_insn): Update reg_last_clobbers appropriately.
+
+Sun Mar 7 08:30:37 1999 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * gmon-sol2.c: Include config.h and system.h. Don't redundantly
+ include system header files.
+ (sccsid): Remove.
+ (moncontrol, monstartup, _mcleanup, internal_mcount): Prototype.
+ (_mcleanup): Add the `const' keyword to a char*.
+ (internal_mcount): Declare `etext' as a char[] not a function.
+ Cast `etext' to char* when calling `monstartup'.
+
+ * sparc.c (frame_base_name, save_regs, restore_regs,
+ build_big_number, sparc_cmodel_string, sparc_align_loops_string,
+ sparc_align_jumps_string, sparc_align_funcs_string, code_model,
+ cpu_default, cpu_table, output_function_prologue,
+ output_function_epilogue, output_return,
+ sparc_flat_output_function_prologue, ultra_code_names,
+ sparc_flat_output_function_epilogue): Constify a char*.
+ (hypersparc_adjust_cost): Add a default case in a switch.
+
+ * sparc.h (sparc_cmodel_string, OVERRIDE_OPTIONS,
+ sparc_cpu_select, sparc_align_loops_string,
+ sparc_align_jumps_string, sparc_align_funcs_string,
+ output_return): Constify a char*.
+
+ * sparc.md (movdi): Change the comparison of HOST_BITS_PER_WIDE_INT
+ so that we check "== 32", instead of "!= 64". Cast a value to
+ HOST_WIDE_INT when comparing against one. Hide the declaration
+ for variable `chain'.
+
+Sun Mar 7 08:05:27 1999 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * system.h (const, inline): Move the stage2 handling of these
+ keywords-as-macros from here...
+
+ * gansidecl.h (const, inline): ...to here.
+
+Sun Mar 7 02:44:15 1999 Richard Henderson <rth@cygnus.com>
+
+ * recog.c (push_operand, pop_operand): VOIDmode needn't match modes.
+
+Sun Mar 7 01:58:47 1999 Richard Henderson <rth@cygnus.com>
+
+ * cse.c (canon_hash): Never reject hard regs in CCmode.
+
+Sun Mar 7 01:15:04 PST 1999 Jeff Law (law@cygnus.com)
+
+ * version.c: Bump for snapshot.
+
+Sat Mar 6 17:18:44 1999 Richard Earnshaw (rearnsha@arm.com)
+ Richard Henderson <rth@cygnus.com>
+
+ * flow.c (make_edges): Handle casesi that jump to default branch.
+ If CASE_DROPS_THROUGH, force fallthru to block after casesi.
+
+Sat Mar 6 07:49:23 1999 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * c-aux-info.c (data_type, affix_data_type, gen_decl,
+ gen_formal_list_for_type, gen_formal_list_for_func_def, gen_type):
+ Qualify a char* with the `const' keyword.
+
+ * c-common.c (declare_hidden_char_array, add_attribute, if_elt,
+ declare_function_name, decl_attributes, format_char_info,
+ check_format_info, binary_op_error): Likewise.
+
+ * cexp.y (yyerror, error, pedwarn, warning, token): Likewise.
+
+ * gcse.c (dump_hash_table): Likewise.
+
+ * integrate.c (function_cannot_inline_p): Likewise
+
+ * optabs.c: Include insn-config.h earlier.
+ (init_libfuncs, init_integral_libfuncs, init_floating_libfuncs):
+ Qualify a char* with the `const' keyword.
+
+ * real.c (asctoe24, asctoe53, asctoe64, asctoe113, asctoe,
+ asctoeg, mtherr, ereal_atof): Likewise.
+
+ * real.h (ereal_atof): Likewise.
+
+ * sbitmap.c (dump_sbitmap_vector): Likewise.
+
+ * sbitmap.h (dump_sbitmap_vector): Likewise.
+
+ * stmt.c (nesting, n_occurrences, expand_start_case): Likewise.
+
+ * toplev.c (rest_of_compilation): Likewise.
+
+ * tree.h (function_cannot_inline_p, expand_start_case): Likewise.
+
+Fri Mar 5 23:16:42 1999 David Edelsohn <edelsohn@gnu.org>
+
+ * rs6000.h (ASM_OUTPUT_REG_{PUSH,POP}): Add 64-bit support and do
+ not overwrite AIX link register save area.
+
+Fri Mar 5 23:08:01 1999 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * reload.c (find_reloads_subreg_address): Actually create the USE
+ for the register, not the new memory location.
+
+Fri Mar 5 21:41:07 1999 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * reload1.c (emit_reload_insns): If pseudo that can't be replaced
+ with its equivalent constant, fall back to reload_in.
+
+Fri Mar 5 13:20:39 1999 Richard Henderson <rth@cygnus.com>
+
+ * Makefile.in: Delete .flow2 debugging files.
+
+Fri Mar 5 11:36:11 1999 Nick Clifton <nickc@cygnus.com>
+
+ * config/arm/arm.c (arm_override_options): Change default target
+ cpu selection so that enabling TARGET_APCS_32 does not override
+ default target CPU.
+
+Fri Mar 5 19:26:23 1999 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * sh.h (SLOW_BYTE_ACCESS): Define to 1.
+ (BOOL_TYPE_SIZE): Define.
+
+Fri Mar 5 02:14:54 1999 John Wehle (john@feith.com)
+
+ * function.c (assign_stack_temp_for_type): Abort
+ if mode == Blkmode and align is less than
+ BIGGEST_ALIGNMENT / BITS_PER_UNIT.
+ (assign_stack_temp_for_type): Round the size parameter
+ passed to assign_stack_local instead of size itself.
+
+Thu Mar 4 15:00:35 1999 Richard Henderson <rth@cygnus.com>
+
+ * flow.c (delete_unreachable_blocks): Mark blocks as they
+ are put on to the worklist, not as they are taken off.
+
+Thu Mar 4 00:05:44 1999 Jeffrey A Law (law@cygnus.com)
+
+ * function.c (current_function_has_computed_jump): Remove duplicate
+ definition.
+
+Wed Mar 3 19:09:11 1999 Jim Wilson <wilson@cygnus.com>
+
+ * m68k/m68020-elf.h (INIT_SECTION_ASM_OP, FINI_SECTION_ASM_OP): Undef.
+ (STARTFILE_SPEC, ENDFILE_SPEC): Define to empty string.
+
+ * sparc/elf.h (MULDI3_LIBCALL, DIVDI3_LIBCALL, UDIVDI3_LIBCALL,
+ MODDI3_LIBCALL, UMODDI3_LIBCALL, STDC_0_IN_SYSTEM_HEADERS): Undef.
+ (INIT_SUBTARGET_OPTABS): Define to empty.
+
+Wed Mar 3 00:00:37 1999 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * sh.c (force_into): New function.
+ (expand_block_move): Use it.
+
+Tue Mar 2 10:39:43 1999 Nick Clifton <nickc@cygnus.com>
+
+ * cccp.c (struct default_include): Add 'included' field.
+ (main): Set 'included' field when a default include directory
+ is added to the chain. If -v is specified list all default
+ include directories which do not get appended to the chain.
+
+Tue Mar 2 09:24:10 1999 Nick Clifton <nickc@cygnus.com>
+
+ * configure.in (gxx_include_dir): Rename to
+ gcc_gxx_include_dir in order to prevent it being overridden by
+ a top level Makefile.
+ (gcc_tooldir): If $exec_prefix != $prefix then use the
+ difference between the two as the basis for gcc_tooldir.
+
+ * configure: Rebuild.
+
+ * Makefile.in: Rename gxx_include_dir to gcc_gxx_include_dir.
+
+Tue Mar 2 16:45:31 1999 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * unroll.c (copy_loop_body): Don't make extra copies of
+ NOTE_INSN_LOOP_CONT notes.
+
+Tue Mar 2 07:44:56 1999 Mark Mitchell <mark@markmitchell.com>
+
+ * tree.c (save_tree_status): Don't treat functions with no context
+ as nested.
+
+Tue Mar 2 09:37:05 1999 Robert Lipe <robertlipe@usa.net>
+
+ * Makefile.in (MAKEINFO): Use makeinfo built from sibling
+ tree when available.
+
+Tue Mar 2 10:12:48 1999 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * alpha.c (alpha_cpu_name, alpha_cpu_string, alpha_tp_string,
+ alpha_fprm_string, alpha_fptm_string, alpha_mlat_string,
+ current_function_file): Add the `const' keyword.
+ (normal_memory_operand): Mark parameter `mode' with
+ ATTRIBUTE_UNUSED.
+ (alpha_expand_unaligned_load): Add a default case to a switch.
+
+ * alpha.h (alpha_cpu_string, alpha_fprm_string, alpha_fptm_string,
+ alpha_tp_string, alpha_mlat_string): Add the `const' keyword.
+ (normal_memory_operand): Add prototype.
+
+ * alpha.md: Cast an expression to `unsigned HOST_WIDE_INT' when
+ comparing against one.
+
+Tue Mar 2 10:00:21 1999 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * mips.c (abort_with_insn): Make function static, add a prototype,
+ constify 2nd parameter and mark with ATTRIBUTE_NORETURN.
+ (current_function_file, mips_cpu_string, mips_isa_string,
+ mips_abi_string, mips_no_mips16_string, mips_entry_string,
+ mips_move_1word, mips_move_2words, output_block_move, load_store,
+ override_options, make_temp_file, mips16_fp_args): Qualify a char*
+ with the `const' keyword.
+
+ * mips.h (current_function_file, mips_cpu_string, mips_isa_string,
+ mips_abi_string, mips_entry_string, mips_no_mips16_string,
+ mips_move_1word, mips_move_2words, output_block_move): Likewise.
+ (abort_with_insn): Remove extern prototype.
+
+ * mips.md: Qualify a char* with the `const' keyword.
+ Remove many unused variables named `label'.
+
+Tue Mar 2 01:27:52 1999 H.J. Lu (hjl@gnu.org)
+
+ * Makefile.in (cpp_install_dir, INSTALL_CPP, UNINSTALL_CPP): New
+ variables.
+ (install-cpp, uninstall-cpp): New targets.
+ (install-normal): Depend on $(INSTALL_CPP).
+ (uninstall): Depend on $(UNINSTALL_CPP).
+ * configure.in (cpp_install_dir): New, substitute.
+ (tmake_file): Added t-install-cpp for --enable-cpp.
+ * configure: Rebuilt.
+ * cpp.sh: New cpp script.
+ * config/t-install-cpp: New target fragment.
+
+Tue Mar 2 01:40:01 1999 Franz Sirl <Franz.Sirl-kernel@lauterbach.com>
+ Jeffrey A Law (law@cygnus.com)
+
+ * cse.c (fold_rtx): Update comments for (const (minus (label) (label)))
+ case.
+ (cse_insn): Avoid creating a bogus REG_EQUAL note for
+ (const (minus (label) (label)))
+ (record_jump_cond): Fix mismatched paren in comment.
+
+Tue Mar 2 01:07:12 1999 Dan Nicolaescu <dann@godzilla.ics.uci.edu>
+
+ * final.c (end_final): There are 11 words in the "main header"
+ structure, not 10.
+
+Tue Mar 2 00:09:18 1999 Marc Espie <espie@cvs.openbsd.org>
+
+ * extend.texi: Reference __extension__ in the index.
+
+Mon Mar 1 19:09:32 1999 Jim Wilson <wilson@cygnus.com>
+
+ * Makefile.in (CROSS_FLOAT_H): Delete.
+ (FLOAT_H): Use float_h_file.
+ (rest.cross, stmp-int-hdrs): Delete gfloat.h dependency.
+ (gfloat.h): Delete.
+ (stmp-int-hdrs): Use FLOAT_H instead of gfloat.h.
+ (mostlyclean): Delete gloat.h reference.
+ (install-cross-rest, install-float-h-cross, stmp-headers): Update
+ comments.
+ * configure.in (sparcv9-*-solaris2*): Set float_format to none.
+ (sparc-*-solaris2*): Set float_format to none for 2.5 and higher.
+ (float_h_file): Set from float_format. Substitute into Makefile.in.
+ (float_format): No longer substitute into Makefile.in.
+ * cross-make (FLOAT_H): Delete.
+ * config/mips/t-cross64 (FLOAT_H): Delete.
+ * configure: Rebuilt.
+
+Mon Mar 1 16:36:18 1999 Jeffrey A Law (law@cygnus.com)
+
+ * mips.md (div_trap_normal, div_trap_mips16): Require the dependent
+ insn to be an INSN before looking at its pattern.
+
+Mon Mar 1 15:03:51 1999 Jim Wilson <wilson@cygnus.com>
+
+ * config/m68k/lb1sf68.asm (udivsi3): Change jmi to jcs. Fix comments.
+ * config/m68k/m68k.h (LEGITIMATE_INDEX_REG_P): Reject SIGN_EXTEND of
+ HImode reg when TARGET_5200.
+
+Mon Mar 1 21:44:30 1999 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ From Toshiyasu Morita:
+ * sh.h (CACHE_LOG): SH2 has cache, too.
+
+Mon Mar 1 14:23:36 1999 Catherine Moore <clm@cygnus.com>
+
+ * toplev.c (compile_file): Disable -ffunction-sections and
+ debugging warning if the object format is elf.
+
+Mon Mar 1 11:46:25 1999 Vladimir N. Makarov <vmakarov@cygnus.com>
+
+ * config/h8300/h8300.c (print_operand): Use 16 bit addressing
+ when the data in 8-bit area and can not be addressed by 8-bit.
+
+Sun Feb 28 16:40:00 1999 Richard Henderson <rth@cygnus.com>
+
+ * flow.c (create_basic_block): Disregard integrated bb notes.
+
+Sun Feb 28 15:57:06 1999 Richard Henderson <rth@cygnus.com>
+
+ * sparc.md (blockage, nonlocal_goto_receiver): Set length to 0.
+
+Sun Feb 28 14:47:53 1999 Arturo Montes <mitosys@colomsat.com.co>
+
+ * config/i386/t-sco5gas (crti.o): New target.
+
+Sun Feb 28 15:10:17 1999 David Edelsohn <edelsohn@gnu.org>
+
+ * rs6000.md (elf_high, movsi_got, *movsi_got_internal,
+ *movsi_got_internal_mem, GOT splitter, movdf_hardfloat32,
+ movdf_softfloat32, movdf_hardfloat64, movdf_softfloat64,
+ load_multiple, allocate_stack, call_indirect_aix32,
+ call_indirect_aix64, call_value_indirect_aix32,
+ call_value_indirect_aix64, call_indirect_nt,
+ call_value_indirect_nt): Use gpc_reg_operand instead of
+ register_operand.
+
+Sun Feb 28 15:10:17 1999 Michael Meissner <meissner@cygnus.com>
+
+ * rs6000.md (one_cmplsi2, andsi3, iorsi3, xorsi3, *eqvsi3,
+ *andcsi3, *iorcsi3, *nandsi3, *norsi3): Add alternatives to use CR
+ other than cr0.
+ * rs6000.c (and{,64}_operand): If the user did -ffixed-cr0, don't
+ allow andi. or andis. which always set cr0.
+
+Sun Feb 28 01:15:04 PST 1999 Jeff Law (law@cygnus.com)
+
+ * version.c: Bump for snapshot.
+
+Sun Feb 28 02:00:38 1999 Jeffrey A Law (law@cygnus.com)
+
+ * invoke.texi: Update information for PA scheduling.
+
+Sat Feb 27 23:21:47 1999 Jerry Quinn <jquinn@nortelnetworks.com>
+ Mike Stump <mrs@wrs.com>
+
+ * pa.c (override_options): Change default to 7100LC
+
+ * pa.h (REG_ALLOC_ORDER): Change order to allocate left half of
+ float regs before right half of float regs.
+
+Sat Feb 27 22:48:38 1999 H.J. Lu (hjl@gnu.org)
+ Jeffrey A Law (law@cygnus.com)
+
+ * frame.h: Update some comments.
+ * defaults.h (TARGET_ATTRIBUTE_WEAK): Define.
+ * crtstuff.c (__register_frame_info, __deregister_frame_info): Declare
+ using TARGET_WEAK_ATTRIBUTE.
+ (__do_global_dtors_aux): Check if __deregister_frame_info is
+ zero before calling it.
+ (__do_global_dtors): Likewise.
+ (frame_dummy): Check if __register_frame_info is zero before
+ calling it.
+ (__frame_dummy): Likewise.
+
+Sat Feb 27 19:18:24 1999 Jeffrey A Law (law@cygnus.com)
+
+ * SERVICE: Update from the FSF.
+
+Sat Feb 27 14:31:22 1999 Arturo Montes <mitosys@colomsat.com.co>
+
+ * config/i386/t-sco5 (crti.o): New target.
+ * config/i386/sco5.h (STARTFILE_SPEC): Include crti.o when
+ linking -shared.
+ * configure.in (i[34567]86-*-sco3.2v5*): Add crti.o.
+
+Sat Feb 27 01:12:40 1999 Jeffrey A Law (law@cygnus.com)
+
+ * md.texi (prologue,epilogue): Document named patterns.
+
+Fri Feb 26 19:31:25 1999 Dave Love <fx@gnu.org>
+
+ * md.texi, invoke.texi: Fix unterminated @xrefs.
+
+Fri Feb 26 15:33:45 1999 Richard Henderson <rth@cygnus.com>
+
+ * genattrtab.c (simplify_knowing): Fix uninitialized read
+ in Feb 21 change.
+
+ * genextract.c (main): Clear recog_operands before extracting.
+
+Fri Feb 26 02:24:57 1999 Jeffrey A Law (law@cygnus.com)
+
+ * c-pragma.c (add_weak); Delete. Moved into...
+ * varasm.c (add_weak): New external function.
+ (declare_weak): If HANDLE_PRAGMA_WEAK, then add the function to
+ the list of weak functions.
+ * c-pragma (add_weak): Declare.
+
+Thu Feb 25 23:43:59 1999 Richard Henderson <rth@cygnus.com>
+
+ Flow rewrite to use basic block structures and edge lists:
+
+ * basic-block.h (x_basic_block_head, x_basic_block_end): Kill.
+ (basic_block_computed_jump_target, basic_block_live_at_start): Kill.
+ (struct edge_def): New.
+ (struct basic_block_def): New.
+ (basic_block_info): New.
+ (BLOCK_HEAD, BLOCK_END): Update.
+ (ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR): New.
+ (uid_block_number): Kill.
+ (basic_block_for_insn, BLOCK_FOR_INSN): New.
+ (BLOCK_NUM): Update.
+ * flow.c (XNMALLOC): Kill.
+ (max_uid_for_flow): Kill.
+ (uid_block_number): Kill.
+ (uid_volatile): Turn into a bitmap.
+ (SET_INSN_VOLATILE): New.
+ (basic_block_info): New.
+ (entry_exit_blocks): New.
+ (x_basic_block_head, x_basic_block_end): Kill.
+ (basic_block_computed_jump_target, basic_block_live_at_start): Kill.
+ (flow_int_list_blocks, basic_block_succ, basic_block_pred): Kill.
+ (basic_block_loop_depth): Kill.
+ (basic_block_for_insn): New.
+ (find_basic_blocks): Split out initial block counting into
+ count_basic_blocks. Call functions split out of find_basic_blocks_1.
+ (count_basic_blocks): New.
+ (find_basic_blocks_1): Split out edge recognition, unreachable
+ block deletion.
+ (create_basic_block): New.
+ (compute_bb_for_insn): New.
+ (clear_edges): New.
+ (free_bb_memory): Kill.
+ (add_edge, add_edge_to_label): Kill.
+ (mark_label_ref): Kill.
+ (make_edges): Rewrite to use edge lists.
+ (make_edge, make_label_edge): New.
+ (mark_critical_edges): New.
+ (split_edge, insert_insn_on_edge): New.
+ (commit_one_edge_insertion, commit_edge_insertions): New.
+ (delete_unreachable_blocks): Rewrite to use edge lists.
+ Split out EH region manipulation into delete_eh_regions.
+ Call tidy_fallthru_edge and merge_blocks.
+ (delete_eh_regions): New.
+ (delete_note_p): New.
+ (delete_insn_chain): New.
+ (delete_block): Split out code into delete_insn_chain and
+ tidy_fallthru_edge. Update edge lists.
+ (expunge_block): New.
+ (flow_delete_insn): New?
+ (can_delete_label_p): New?
+ (merge_blocks_nomove, merge_blocks): New.
+ (tidy_fallthru_edge): New.
+ (calculate_loop_depth): New.
+ (life_analysis): Allocate and free uid_volatile.
+ (free_basic_block_vars): Update for new structures.
+ (record_volatile_insns): Use SET_INSN_VOLATILE.
+ (mark_regs_live_at_end): Tidy EXIT_IGNORE_STACK usage.
+ (mark_used_regs): Likewise.
+ (life_analysis_1): Use bb global_live_at_start, global_live_at_end,
+ local_set regsets. Use bb->aux to store new_live_at_end. Begin
+ life propagation from EXIT_BLOCK rather than last block. Clear
+ regs_ever_live after mark_regs_live_at_end.
+ (allocate_for_life_analysis): Update for new structures.
+ (propagate_block): Split out loop depth calculation to
+ calculate_loop_depth.
+ (regno_uninitialized): Use bb->global_live_at_start.
+ (regno_clobbered_at_setjmp): Likewise.
+ (dump_bb_data): Likewise.
+ (find_auto_inc): Use BLOCK_FOR_INSN instead of BLOCK_NUM.
+ (dump_flow_info): Update for new structures.
+ (dump_edge_info): New.
+ (print_rtl_with_bb): Update for new structues.
+ (compute_preds_succs): Do no work -- convert edge lists.
+ (set_block_for_insn): From corpse of old set_block_num.
+ (set_block_num): Call it.
+
+ * rtl.c (note_insn_name): Add NOTE_INSN_BASIC_BLOCK.
+ * rtl.h (rtunion_def): Add bb entry.
+ (NOTE_BASIC_BLOCK): New.
+ (NOTE_INSN_BASIC_BLOCK): New.
+
+ * varray.h (varray_data_tag): Add bb entry.
+ (VARRAY_BB_INIT, VARRAY_BB): New.
+
+ * emit-rtl.c (emit_label_before): New.
+
+ * except.c (expand_rethrow): Delete insns following the call to
+ rethrow. Put the REG_EH_RETHROW on the call.
+
+ * jump.c (returnjump_p, returnjump_p_1): New.
+
+ * expr.h (nonlocal_goto_handler_labels): New declaration.
+ * function.c (nonlocal_goto_handler_labels): Define it.
+ (push_function_context_to): Save it.
+ (pop_function_context_from): Restore it.
+ (init_function_start): Clear it.
+ (nonlocal_label_rtx_list): Kill.
+ * function.h (struct function): Add storage space for it.
+ * stmt.c (expand_nl_handler_label): Return the new label.
+ (expand_nl_goto_receivers): Collect a list of them in
+ nonlocal_goto_handler_labels.
+
+ * Makefile.in (print-rtl.o): Depend on basic-block.h.
+ (flow.o): Depend on insn-flags.h.
+
+ * function.c (thread_prologue_and_epilogue_insns): Do not
+ half-heartedly update bb structures.
+
+ * toplev.c: Add flow2 dump as -dw.
+ (rest_of_compilation): Finish .greg before flow2.
+
+ * graph.c (draw_edge): Handle class 3.
+ (print_rtl_graph_with_bb): Make abnormal edges red class 2,
+ change non-fall-thru but adjacent to green class 3. Update
+ to use new structures.
+
+ * print-rtl.c (print_rtx): Handle NOTE_INSN_BASIC_BLOCK.
+
+ * reg-stack.c (BLOCK_NUM): Convert to function. Abort if
+ block_number is -1.
+ (reg_to_stack): Initialize block_num to -1.
+
+ * combine.c (set_nonzero_bits_and_sign_copies): Update reference
+ to basic_block_live_at_start to bb->global_live_at_start.
+ (try_combine): Likewise.
+ (reg_dead_at_p): Likewise.
+ * global.c (global_conflicts): Likewise.
+ Handle stack regs on all abnormal edges, not just computed jumps.
+ (mark_elimination): Update reference to basic_block_live_at_start.
+ (build_insn_chain): Likewise.
+ * haifa-sched.c (haifa_edge): Rename from edge for conflict.
+ (is_cfg_nonregular): Look at nonlocal_goto_handler_labels instead
+ of nonlocal_label_rtx_list.
+ (check_live_1): Update reference to basic_block_live_at_start.
+ (update_live_1): Likewise.
+ (find_pre_sched_live): Likewise.
+ (find_post_sched_live): Likewise.
+ * local-alloc.c (update_equiv_regs): Likewise.
+ (block_alloc): Likewise.
+ * reload1.c (reload, reload_combine): Likewise.
+ * regmove.c (mark_flags_life_zones): Likewise.
+ * resource.c (mark_target_live_regs): Likewise.
+ * sched.c (schedule_block): Likewise.
+
+ * regclass.c (regset_release_memory): Don't free
+ basic_block_live_at_start.
+
+ * unroll.c (copy_loop_body): Don't duplicate NOTE_INSN_BASIC_BLOCK.
+
+Thu Feb 25 21:32:34 1999 Jason Merrill <jason@yorick.cygnus.com>
+
+ * fixinc.wrap: Also handle struct queue in sys/stream.h.
+ * fixinc.svr4: Likewise.
+
+ * dwarf2out.c (scope_die_for): Set scope_die to comp_unit_die
+ rather than asserting it.
+
+Thu Feb 25 23:33:06 1999 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * cppexp.c (left_shift, right_shift, parse_charconst, COMPARE,
+ cpp_parse_expr): Replace uses of long/HOST_BITS_PER_LONG with
+ HOST_WIDEST_INT/HOST_BITS_PER_WIDEST_INT.
+
+
+ * Makefile.in (cppmain.o, cpplib.o, cpphash.o, cppalloc.o,
+ cpperror.o, cppexp.o, cppfiles.o, cppinit.o, fix-header.o,
+ scan-decls.o): Don't depend on machmode.h.
+
+ * cppexp.c: Don't define CHAR_BIT or HOST_BITS_PER_WIDE_INT anymore.
+ Replace all instances of HOST_WIDE_INT with HOST_WIDEST_INT.
+
+ * cppfiles.c: Likewise.
+
+ * cpplib.c: Likewise.
+
+ * cpplib.h: Likewise. Also don't include machmode.h anymore.
+
+Thu Feb 25 18:46:26 1999 Richard Henderson <rth@cygnus.com>
+
+ * gcc.c (default_compilers): Define __FAST_MATH__ when appropriate.
+ * objc/lang-specs.h: Likewise.
+
+Thu Feb 25 16:19:43 1999 Jeffrey A Law (law@cygnus.com)
+
+ * pa.md (call patterns): Lose unused argument to output_call.
+
+ * print-rtl.c (print_rtl): Print /j and /c for the jump/call flags.
+
+1999-02-25 17:14 -0500 Zack Weinberg <zack@rabi.columbia.edu>
+
+ * cpphash.c (install): Rename to cpp_install, add cpp_reader*
+ first argument. All callers changed.
+ (hashtab): Removed.
+ (cpp_lookup, cpp_install): Change all refs to hashtab to
+ pfile->hashtab.
+ (cpp_hash_cleanup): Removed.
+ * cpphash.h: Adjust prototypes.
+ * cpplib.h (struct cpp_reader): Add hashtab pointer.
+ * cppinit.c (cpp_reader_init): Also allocate space for the
+ hashtab.
+ (cpp_cleanup): Delete all macros and free the hashtab.
+
+Thu Feb 25 21:52:54 1999 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * sh.h (PASS_IN_REG_P): For TARGET_HITACHI, don't pass structures
+ in registers.
+
+ * expr.h (PRETEND_OUTGOING_VARARGS_NAMED): Provide default definition.
+ * function.c (assign_parms): Honour PRETEND_OUTGOING_VARARGS_NAMED.
+ * calls.c (expand_call): Likewise.
+
+ * sh.c (sh_expand_prologue): For TARGET_HITACHI, don't push varargs /
+ stdarg arguments.
+ * sh.h (CPP_SPEC): Add -D__HITACHI__ for -mhitachi.
+ (FUNCTION_ARG): For TARGET_HITACHI, don't pass unnamed
+ arguments in registers.
+ (PRETEND_OUTGOING_VARARGS_NAMED): Define.
+ * va-sh.h (entire file): If __HITACHI__ is defined, use sh[123]
+ flavour varargs.
+
+Thu Feb 25 14:32:40 1999 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * cse.c (dump_class): Revert last change and make the prototype
+ extern.
+
+Thu Feb 25 19:13:42 1999 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * rtl.h (insn_first_p): Don't declare.
+ * rtlanal.c (insn_first_p): Delete.
+ * loop.c (loop_insn_first_p): Faster implementation.
+
+Thu Feb 25 10:44:35 1999 Richard Earnshaw (rearnsha@arm.com)
+
+ * arm.h (TARGET_SWITCHES): Delete deprecated switches -m[236].
+ (TARGET_3, TARGET_6): Delete.
+ (ARM_FLAG_ARM[36]): Delete.
+ (CPP_CPU_ARCH_SPEC): No need to handle -m[236] any more.
+ (CC1_SPEC): Don't expand -m[236] into new equivalents.
+ (CPP_APCS_PC_SPEC): No need to handle -m[236] any more.
+ * arm.c (arm_override_options): Delete warnings about deprecated
+ options -m[236].
+
+ * arm.c (arm_finalize_pic): Build the label into the special pic
+ adjustment insn instead of issuing it separately.
+ * arm.md (pic_add_dot_plus_eight): Rework to contain the label
+ that is needed.
+
+ * arm.md (*zeroextractqi_compare0_scratch): Delete.
+ (*ne_zeroextractsi): New pattern.
+
+Thu Feb 25 18:40:06 1999 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * stmt.c (expand_end_loop): Grok code emitted by
+ expand_exit_loop_if_false.
+
+Thu Feb 25 10:17:32 1999 Nick Clifton <nickc@cygnus.com>
+
+ * config/arm/arm.c (return_in_memory): Float fields in unions
+ force a return in memory.
+ (load_multiple_sequence): Add comment explaining why two LDR
+ instructions can be better than an LDMIA instruction.
+
+ * config/arm/arm.h (TARGET_SHORT_BY_BYTES): Add comment
+ describing the real meaning of this option.
+ (FIXED_REGISTERS): Default r10 to not-fixed.
+ (CALL_USED_REGISTERS): Default r10 to not-call-used.
+ (SUBTARGET_CONDITIONAL_REGISTER_USAGE): If not defined, define
+ as empty.
+ (CONDITIONAL_REGISTER_USAGE): Fix r10 if TARGET_APCS_STACK is
+ true. Invoke SUBTARGET_CONDITIONAL_REGISTER_USAGE after
+ performing other checks.
+
+ * config/arm/arm.md (zero_extendhisi2): Undo previous change.
+ (extendhisi2): Undo previous change.
+ Also add comments describing why TARGET_SHORT_BY_BYTES can be
+ ignored for armv4(t) architectures.
+
+ * config/arm/riscix.h (SUBTARGET_CONDITIONAL_REGISTER_USAGE):
+ Define to fix r10.
+
+ * config/arm/riscix1-1.h
+ (SUBTARGET_CONDITIONAL_REGISTER_USAGE): Define to fix r10.
+
+Thu Feb 25 12:09:04 1999 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * cse.c (dump_class): Make the function definition static to match
+ the prototype.
+
+Wed Feb 24 17:47:28 1999 Jim Wilson <wilson@cygnus.com>
+
+ * dbxout.c (gstab.h): Use if CROSS_COMPILE.
+
+ * dwarf2out.c (add_location_or_const_value_attribute): Add big
+ endian correction for parms passed in regs but living on the stack.
+
+Wed Feb 24 14:03:54 1999 Jeffrey A Law (law@cygnus.com)
+
+ * calls.c (initialize_argument_information): New function extracted
+ from expand_call.
+ (expand_call): Use initialize_argument_information. Remove variables
+ which are no longer used due to cleanups.
+
+ * calls.c (compute_argument_block_size): New function, extracted from
+ expand_calls.
+ (expand_calls): Use compute_argument_block_size. Delete
+ original_args_size, use unadjusted_args_size instead.
+
+ * calls.c (precompute_arguments): New function, extracted from
+ expand_call.
+ (expand_call): Use precompute_arguments.
+
+ * calls.c (finalize_must_preallocate): New function, extracted from
+ expand_call.
+ (expand_call): Use finalize_must_preallocate.
+
+ * calls.c (store_one_arg): Mark "variable_size" as possibly unused.
+
+ * regclass.c (record_reg_classes, case 'p'): Set classes appropriately.
+ An alternative always fails if it needs a pseudo and no suitable
+ register class can be found.
+
+Wed Feb 24 19:47:56 1999 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * loop.h (loop_insn_first_p): Declare.
+ * loop.c (loop_insn_first_p): No longer static.
+ * unroll.c (iteration_info) Fix comparison to
+ reg_iv_type->num_elements.
+ Before accessing reg_biv_class, check index against
+ max_reg_before_loop.
+ Fix and enable code for giv iterators.
+ (loop_iterations): Compare with reg_iv_type->num_elements instead
+ of with max_reg_before_loop.
+
+Wed Feb 24 19:17:11 1999 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * unroll.c (unroll_loop): Avoid out-of-bounds index for local_regno.
+
+Wed Feb 24 11:26:41 1999 Vladimir N. Makarov <vmakarov@cygnus.com>
+
+ * config/sparc/sparc.h (CONDITIONAL_REGISTER_USAGE): Don't use
+ PIC_OFFSET_TABLE_REGNUM for register allocation when -fPIC.
+
+Tue Feb 23 16:24:19 CET 1999 Marc Lehmann <pcg@goof.com>
+
+ * config/i386/i386.md: fix typoe.
+
+Mon Feb 22 19:36:33 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * config/mips/mips.c (mips_debugger_offset): When TARGET_MIPS16 &&
+ frame_pointer_needed adjust frame size.
+ (function_prologue): Don't MIPS16 .mask GPOFFSET. Already adjusted
+ in .frame pseudo-op.
+ Frm Jim Wilson <wilson@cygnus.com>:
+ * mips.c (function_prologue): Adjust frame size in .frame pseudo-op
+ when TARGET_MIPS16 && frame_pointer_needed.
+
+1999-02-22 Nick Clifton <nickc@cygnus.com>
+
+ * config/arm/arm.h: Add TARGET_CPU_strongarm1100.
+ Add -mno-sched command line switch to disable scheduling of
+ instructions into the function's prologue.
+ (enum processor_type): Remove.
+ (TARGET_OPTIONS): Add "fpe=" option to match documentation.
+ (struct arm_cpu_select): Replace 'set_tune_p' and 'set_arch_p'
+ fields with 'processors' field.
+ (CONDITIONAL_REGISTER_USAGE): Allow r10 to be used if stack
+ checking is not enabled.
+ (RETURN_IN_MEMORY): Always call arm_return_in_memory.
+
+ * config/arm/arm.c: (arm_cpu): Remove.
+ (tune_flags): Remove.
+ (arm_is_strong): New variable: true iff the target processor is a
+ StrongARM.
+ (arm_is_6_or_7): New variable: true iff the target processor is an
+ ARM6 or and ARM7.
+ (arm_select): Fields reorganised.
+ (struct processors): processor_type field removed.
+ (all_procs): Remove.
+ (all_cores): New array: Definitions of all known ARM cpu cores.
+ (all_architectures): New array: Definitions of all known ARM
+ architectures.
+ (streq): New macro.
+ (FL_SCHED): New processor flag: processor required load
+ scheduling.
+ (FL_STRONG): New processor flag: processor is a StrongARM.
+ (arm_override_options): Reorganised to make code clearer.
+ (use_return_insn): Test for "not (TARGET_APCS and
+ frame_pointer_needed)".
+ (arm_return_in_memory): Improve handling of structures.
+
+ * config/arm/arm.md: Remove "cpu" attribute. Replace with
+ "is_strongarm" and "is_arm_6_or_7" attributes.
+ (zero_extendhisi2): Check for TARGET_SHORT_BY_BYTES before
+ arm_arch4.
+ (extendhisi2): Check for TARGET_SHORT_BY_BYTES before arm_arch4.
+
+ * invoke.texi (ARM Options): Document -mtune= and -mfp= options.
+
+1999-02-22 Philip Blundell <philb@gnu.org>
+
+ * config/arm/linux-gas.h (INITIALIZE_TRAMPOLINE): Replace default
+ definition with one including cache synchronisation.
+ (CLEAR_INSN_CACHE): Correct syscall number and enable definition.
+ Move definition of inhibit_libc to...
+ * config/arm/xm-linux.h: ... here.
+
+ * config/arm/t-linux: Disable multilib configurations since the
+ only effect for most people is to cause builds to fail.
+
+ * config/arm/elf.h (ASM_FILE_START): Add .file directive.
+ (ASM_SPEC): Translate -mapcs-float to -mfloat for the assembler.
+
+ * config/arm/linux-elf.h (DEFAULT_VTABLE_THUNKS): Define.
+ (HANDLE_SYSV_PRAGMA): Likewise.
+ (LIB_SPEC): Copy definition from generic Linux files.
+ (LIBGCC_SPEC): Include -lfloat if -msoft-float was given.
+ (FP_DEFAULT): Set to SOFT3 on 32-bit targets.
+ (DWARF2_DEBUGGING_INFO): Define.
+ (PREFERRED_DEBUGGING_TYPE): Define as DBX_DEBUG.
+
+Mon Feb 22 16:54:18 EST 1999 Andrew MacLeod <amacleod@cygnus.com>
+
+ * loop.c (libcall_other_regs): Make extern.
+ * rtl.h (find_last_value): Add parameter to prototype.
+ (libcall_other_reg): Add extern declaration.
+ * rtlanal.c (find_last_value): Add another parameter to allow
+ a definition using a hardware register to be found as well.
+
+Mon Feb 22 13:33:47 1999 Mark Mitchell <mark@markmitchell.com>
+
+ * cse.c (dump_class): New function.
+ (invalidate_memory): Fix typo in comment.
+ * function.c (temp_slot): Add an alias set field.
+ (assign_stack_temp): Only reuse slots if they will have the
+ same alias set as before.
+ (combine_temp_slots): Don't combine if -fstrict-aliasing;
+ that's unsafe.
+ * rtl.c (copy_rtx): Copy all the flags (in particular,
+ MEM_SCALAR_P).
+
+Mon Feb 22 14:13:23 1999 Vladimir N. Makarov <vmakarov@cygnus.com>
+
+ * configure.in (i[34567]86-*-linux-gnu*,
+ i[34567]86-*-linux-gnulibc1, i[34567]86-*-linux-gnuaout*,
+ i[34567]86-*-linux-gnuoldld*): Use fixinc.x86-linux-gnu as
+ fixincludes.
+
+ * configure: Rebuilt.
+
+ * fixinc.x86-linux-gnu: New script for fixing asm-statements bug
+ on x86 linux.
+
+ * fixinc/fixinc.x86-linux-gnu: Copy of the previous one.
+
+ * fixinc/mkfixinc.sh (i[34567]86-*-linux-gnu*,
+ i[34567]86-*-linux-gnulibc1, i[34567]86-*-linux-gnuaout*,
+ i[34567]86-*-linux-gnuoldld*): Use fixinc.x86-linux-gnu as
+ fixincludes.
+
+Mon Feb 22 08:55:05 1999 Ovidiu Predescu <ovidiu@cup.hp.com>
+
+ * objc/objc-act.c (encode_type): Temporary revert to the old
+ behavior of encoding types as the new one seems to break the
+ encoding of bitfields.
+
+Mon Feb 22 11:40:44 1999 Craig Burley <craig@jcb-sc.com>
+Sat Feb 20 09:59:36 1999 Craig Burley <craig@jcb-sc.com>
+
+ * Makefile.in (all.internal, all.cross): Depend on `doc'
+ target, to ensure docs get made before installation.
+
+
+ Decrease spurious warnings from -fsyntax-only:
+ * stmt.c (expand_expr_stmt): Expand expr even when -fsyntax-only.
+
+Mon Feb 22 10:55:00 1999 Gavin Romig-Koch <gavin@cygnus.com>
+
+ * c-lex.c (yylex): Replace warning about integer constants being
+ larger than long-longs, with a warning about integer constants
+ being larger than the largest target integer.
+
+Mon Feb 22 08:35:38 1999 Craig Burley <craig@jcb-sc.com>
+
+ Fix -fsyntax-only ICEs:
+ * varasm.c (assemble_zeros, assemble_variable,
+ output_constant_def): Do nothing when -fsyntax-only.
+
+Fri Feb 19 18:18:56 1999 Don Bowman <don@pixstream.com>
+
+ * configure.in (mips*-*-vxworks*): Enable gthreads vxworks support.
+ * configure: Rebuilt.
+
+Sun Feb 21 20:34:44 PST 1999 Jeff Law (law@cygnus.com)
+
+ * version.c: Bump for snapshot.
+
+Sun Feb 21 20:35:10 1999 Jeffrey A Law (law@cygnus.com)
+
+ * config/aoutos.h (ASM_OUTPUT_CONSTRUCTOR): Delete.
+ (ASM_OUTPUT_DESTRUCTOR, ASM_OUTPUT_GC_ENTRY): Likewise.
+ * tm.texi: Update docs for constructors and destructors.
+
+Sun Feb 21 17:11:18 1999 Richard Henderson <rth@cygnus.com>
+
+ * genattrtab.c (check_attr_value): Allow negative const_int if
+ negative_ok. Accept integral arithmetic operators. Accept
+ direct references to other attributes. Accept symbol_ref in
+ non-constant attributes.
+ (max_attr_value): Add new argument `unknownp'. Update all callers.
+ (or_attr_value): Likewise.
+ (simplify_knowing): Don't optimize if max_attr_value unknown.
+ (write_length_unit_log): Likewise with or_attr_value.
+ (find_and_mark_used_attributes): Don't fallthru case.
+ (write_attr_set): Pass thru all non-cond expressions.
+ (write_attr_value): Handle symbol_ref, attr, and arithmetic.
+
+Sun Feb 21 13:16:44 1999 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
+
+ * regmove.c (discover_flags_reg): Use word_mode instead of SImode.
+
+Sun Feb 21 13:15:40 1999 Richard Henderson <rth@cygnus.com>
+
+ * regmove.c (discover_flags_reg): Remove cc0 code.
+ (mark_flags_life_zones) [HAVE_cc0]: Force use of cc0; bail if
+ a potential flags register was identified.
+
+Sat Feb 20 16:16:07 1998 Franz Sirl <Franz.Sirl-kernel@lauterbach.com>
+
+ * rs6000.md (scc plus ltu): Fix typo in last change.
+
+Sat Feb 20 09:08:44 1999 Richard Earnshaw (rearnsha@arm.com)
+
+ * xm-arm.h (HOST_BITS_PER_LONGLONG): Define.
+
+Fri Feb 19 23:02:02 1999 Richard Henderson <rth@cygnus.com>
+
+ * regmove.c (discover_flags_reg): New function.
+ (flags_set_1, mark_flags_life_zones): New functions.
+ (regmove_optimize): Call them.
+ (fixup_match_1): Use insn modes rather than sets_cc0_p.
+
+Fri Feb 19 22:47:01 1999 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * rtlanal.c (insn_first_p): Fix return value for insn == reference.
+
+ * loop.c (strength_reduce, check_final_value, check_dbra_loop):
+ Use loop_insn_first_p.
+
+Fri Feb 19 15:49:26 1999 Michael Meissner <meissner@cygnus.com>
+ David Edelsohn <edelsohn@gnu.org>
+
+ * rs6000.md (scc plus eq): Fix output template.
+ (scc plus ltu): Fix output template and collapse variants
+ correcting early clobbers.
+ (scc plus geu): Fix output template.
+ (scc plus gt): Fix output template.
+ (scc plus gtu): Fix output template and collapse variants.
+
+Fri Feb 19 15:43:59 1999 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * cppinit.c (print_help): Remove unescaped newline in string.
+
+Fri Feb 19 19:55:06 1999 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * loop.c (strength_reduce): Check for intervening jumps when
+ converting biv increment to giv.
+
+Thu Feb 18 16:36:58 1999 Per Bothner <bothner@cygnus.com>
+
+ * tree.def (TRY_FINALLY_EXPR, GOTO_SUBROUTINE_EXPR): New tree nodes,
+ * expr.c (expand_expr): Support new tree nodes.
+
+Fri Feb 19 10:17:56 1999 Andreas Schwab <schwab@issan.cs.uni-dortmund.de>
+
+ * config/m68k/m68k.c (m68k_align_loops_string,
+ m68k_align_jumps_string, m68k_align_funcs_string): Add const.
+ * config/m68k/m68k.h (m68k_align_loops_string,
+ m68k_align_jumps_string, m68k_align_funcs_string): Likewise.
+
+Thu Feb 18 23:28:35 1999 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * bitmap.c (bitmap_print): Qualify a char* with the `const' keyword.
+
+ * bitmap.h (bitmap_print): Likewise.
+
+ * c-decl.c (builtin_function, grokdeclarator, grokfield): Likewise.
+
+ * c-lang.c (build_objc_string): Likewise.
+
+ * c-lex.c (yyerror, extend_token_buffer): Likewise. Don't include
+ limits.h or ctype.h. Remove unused variable `p'.
+
+ * c-lex.h (yyerror): Qualify a char* with the `const' keyword.
+
+ * c-pragma.c (handle_pragma_token): Likewise.
+
+ * c-pragma.h (handle_pragma_token): Likewise.
+
+ * c-tree.h (build_objc_string, builtin_function, grokfield,
+ build_indirect_ref, lvalue_or_else, readonly_warning, error_init,
+ pedwarn_init): Likewise.
+
+ * c-typeck.c (convert_for_assignment, warn_for_assignment,
+ push_string, warning_init, incomplete_type_error,
+ build_indirect_ref, lvalue_or_else, readonly_warning,
+ build_c_cast, spelling, push_member_name, print_spelling,
+ error_init, pedwarn_init, start_init): Likewise.
+
+ * objc/objc-act.c (build_objc_string): Likewise.
+
+ * print-tree.c (print_node_brief, print_node): Likewise.
+
+ * tree.h (lvalue_or_else, print_node, print_node_brief): Likewise.
+
+Thu Feb 18 20:44:21 1999 David Edelsohn <edelsohn@gnu.org>
+
+ * regclass.c (record_reg_classes): Correctly handle 'p' constraint.
+
+Thu Feb 18 19:59:37 1999 Marc Espie <espie@cvs.openbsd.org>
+
+ * configure.in :Handle OpenBSD platforms.
+ * configure: Rebuilt.
+ * config/openbsd.h: New file.
+ * config/xm-openbsd.h: New file.
+ * config/t-openbsd: New file.
+ * config/t-openbsd-thread: New file.
+
+Thu Feb 18 18:47:09 1999 Jeffrey A Law (law@cygnus.com)
+
+ * function.c (assign_stack_temp_for_type): Round SIZE before calling
+ assign_stack_local for BLKmode slots.
+
+Fri Feb 19 01:45:06 1999 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * loop.c (strength_reduce): For derived givs, replace the
+ giv this was derived from with its new_reg.
+ (recombine_givs): Don't set new_reg for derived giv.
+ And don't print it, print SUM instead.
+
+Thu Feb 18 15:52:49 1999 Jim Wilson <wilson@cygnus.com>
+
+ * m68kelf.h (ASM_RETURN_CASE_JUMP): Add 5200 support.
+
+1999-02-18 18:32 -0500 Zack Weinberg <zack@rabi.columbia.edu>
+
+ * cpplib.c: Kill define of STDC_VALUE. Don't include output.h
+ or prefix.h. Change CPP_IS_MACRO_BUFFER to not refer to
+ macro_cleanup.
+ (GET_ENV_PATH_LIST, PATH_SEPARATOR, STANDARD_INCLUDE_DIR,
+ predefs, SIZE_TYPE, PTRDIFF_TYPE, WCHAR_TYPE,
+ CPP_WCHAR_TYPE, USER_LABEL_PREFIX, REGISTER_PREFIX, struct
+ cpp_pending, version_string, struct default_include,
+ include_defaults_array, path_include, cpp_options_init,
+ dump_special_to_buffer, initialize_builtins, cpp_start_read,
+ cpp_reader_init, nreverse_pending, push_pending, print_help,
+ cpp_handle_option, cpp_handle_options, cpp_finish,
+ cpp_cleanup): Move to cppinit.c.
+ (macro_cleanup, struct arglist, collect_expansion,
+ create_definition, compare_defs, comp_def_part, ARG_BASE,
+ struct argdata, macarg, change_newlines, timestamp,
+ monthnames, special_symbol, unsafe_chars, macroexpand,
+ push_macro_expansion): Move to cpphash.c.
+ (quote_string, check_macro_name, cpp_expand_to_buffer,
+ output_line_command, cpp_undef): Export.
+ (null_underflow, null_cleanup, handle_directive): Make static.
+
+ * cpplib.h: Prototype now-exported functions. Adjust decls of
+ syntax tables so we can include cpplib.h in cppinit.c.
+ * cpphash.h: Prototype all functions exported by cpphash.c.
+ * cppinit.c: Make syntax tables initialized data if possible
+ (uses GCC designated-initializer extension).
+ * cppexp.c: Make cpp_lex static.
+ * Makefile.in: Move -D switches for the various include dirs
+ from cpplib.o rule to cppinit.o rule. Adjust dependencies.
+
+Thu Feb 18 13:15:56 1999 Marc Espie <espie@cvs.openbsd.org>
+
+ * alpha/openbsd.h: New file.
+ * alpha/xm-openbsd.h: New file.
+ * sparc/openbsd.h: New file.
+ * sparc/xm-openbsd.h: New file.
+ * m68k/openbsd.h: New file.
+ * m68k/xm-openbsd.h: New file.
+ * i386/openbsd.h: New file, originally from netbsd.
+ * i386/xm-openbsd.h: New file.
+
+1999-02-17 14:49 -0500 Zack Weinberg <zack@rabi.columbia.edu>
+
+ * Makefile.in: Correct dependencies for cpplib object files.
+
+Wed Feb 17 14:04:18 1999 Michael Meissner <meissner@cygnus.com>
+
+ * rs6000.md ({add,sub}si3 `.'): Add alternatives to use CR other
+ than cr0.
+
+Wed Feb 17 16:59:28 1999 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * loop.c (strength_reduce): Don't move giv insn for biv turned giv
+ below scan_start.
+
+Wed Feb 17 10:56:24 1999 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * tree.c (tree_node_kind_names, print_obstack_name,
+ get_identifier, maybe_get_identifier, build_string,
+ build_expr_wfl, is_attribute_p, lookup_attribute,
+ print_obstack_statistics, get_file_function_name_long, tree_check,
+ tree_class_check, expr_check): Qualify a char* with the `const'
+ keyword.
+
+ * tree.h (get_identifier, maybe_get_identifier, build_string,
+ build_expr_wfl, is_attribute_p, lookup_attribute,
+ print_obstack_statistics, print_obstack_name, tree_check,
+ tree_class_check, expr_check): Likewise.
+
+Tue Feb 16 21:29:38 1999 Jeffrey A Law (law@cygnus.com)
+
+ * i386/freebsd-elf.h, i386/gas.h, i386/linux.h: Fix minor spacing
+ errors.
+
+ * calls.c (store_one_arg): Mark any slots used for the argument
+ as in-use immediately after we're done saving any slots which
+ will be overwritten by this argument.
+
+Tue Feb 16 21:02:07 1999 Anton Hartl <toni@devsoft.com>
+
+ * rs6000.md (call_value): Fix typo.
+
+Wed Feb 17 01:29:07 1999 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * loop.c (strength_reduce): Calculate maybe_dead before
+ calling recombine_givs.
+
+Wed Feb 17 00:43:12 1999 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * loop.c (strength_reduce): Dump biv increment -> giv conversions.
+
+Tue Feb 16 15:31:39 1999 Ovidiu Predescu <ovidiu@cup.hp.com>
+
+ * objc/objc-act.c (encode_type): Encode the type instead of
+ encoding the mode of the type (patch from Richard Frith-Macdonald
+ <richard@brainstorm.co.uk>).
+
+Tue Feb 16 10:53:51 1999 Richard Earnshaw (rearnsha@arm.com)
+
+ * config/arm/arm.md (*zeroextractqi_compare0_scratch): Re-add load
+ instruction killed in previous change. Simplify mask generation.
+ (*zeroextractsi_compare0_scratch): Simpify mask generation.
+
+Tue Feb 16 09:52:26 1999 Nick Clifton <nickc@cygnus.com>
+
+ * config/arm/arm.md (zeroextractqi_compare0_scratch): Ensure that
+ bitfield does not overflow a byte boundary.
+
+Tue Feb 16 01:37:33 1999 Charles G Waldman <cgw@alum.mit.edu>
+
+ * c-common.c (shorten_compare): Get the min/max value from the
+ underlying type of an enumeration, not the enumerated type itself.
+
+Mon Feb 15 23:04:48 1999 Jeffrey A Law (law@cygnus.com)
+
+ * jump.c: Include insn-attr.h.
+ (delete_computation): If reload has completed and insn scheduling
+ after reload is enabled, then do not depend on REG_DEAD notes.
+ * Makefile.in (jump.o): Depend on insn-attr.h.
+
+Mon Feb 15 16:57:38 1999 Richard Henderson <rth@cygnus.com>
+
+ * i386.md (addsi3): Allow lea for any constant_p.
+
+1999-02-15 17:11 -0500 Zack Weinberg <zack@rabi.columbia.edu>
+
+ * toplev.c (documented_lang_options): Remove -fident and
+ -fnoident, which are now handled by the language independent
+ option parser.
+
+1999-02-15 16:59 -0500 Zack Weinberg <zack@rabi.columbia.edu>
+
+ * c-common.c (UNGETC [USE_CPPLIB=1]): Do nothing if c is EOF.
+ * c-lex.c: Likewise.
+ * cpplib.c (cpp_push_buffer, cpp_pop_buffer): Use a linked
+ list in malloced memory for the buffer stack.
+ (cpp_get_token): Don't pop the last buffer off the stack.
+ Calls after CPP_EOF has been returned produce CPP_EOF with no
+ state change.
+ (cpp_finish): Pop last buffer here.
+ (do_line): Don't free ip->last_nominal_fname if it is equal to
+ ip->fname.
+ (special_symbol): If a T_CONST is the empty string, push a
+ single `@ ' escape instead.
+ (macroexpand): Special symbol buffers have escapes too.
+ * cpplib.h (struct cpp_buffer): Remove unused fields, add prev
+ buffer pointer.
+ (struct cpp_reader): Remove buffer_stack. Add
+ buffer_stack_depth.
+ (CPP_PREV_BUFFER, CPP_NULL_BUFFER): Buffer stack is now a
+ linked list.
+
+Mon Feb 15 14:44:53 1999 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * cccp.c: Don't define HOST_WIDE_INT. Replace all occurrences of
+ WIDE_INT with WIDEST_INT.
+
+ * cexp.y: Likewise.
+ Don't define unsigned_HOST_WIDE_INT, CHAR_BIT or
+ HOST_BITS_PER_WIDE_INT. Replace occurrences of PRINTF_PROTO_1()
+ style with PVPROTO() ATTRIBUTE_PRINTF_1 style macros. Replace
+ occurrences of "unsigned_HOST" with "unsigned HOST". Provide a
+ definition of variable `c89' when compiling a test binary and set it.
+
+ * system.h: Don't define the PRINTF_PROTO_* macros.
+
+Mon Feb 15 11:33:51 1999 Jeffrey A Law (law@cygnus.com)
+
+ * loop.c (mark_loop_jump): Handle LO_SUM. If we encounter something
+ we do not understand, mark the loop and containing loops as invalid.
+
+Mon Feb 15 00:40:45 1999 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * alias.c (init_alias_analysis): Avoid self-referential value
+ when setting reg_known_value from REG_EQUAL notes.
+
+Sun Feb 14 23:12:10 1999 Richard Henderson <rth@cygnus.com>
+
+ * i386.c (legitimate_address_p): Verify modes of base and index.
+
+Sun Feb 14 23:01:28 1999 Richard Henderson <rth@cygnus.com>
+
+ * i386.c (legitimate_pic_address_disp_p): Remove static.
+ * i386.h (LEGITIMATE_PIC_OPERAND_P): Use it instead of
+ open-coding cases.
+
+Sun Feb 14 21:03:28 1999 Jeffrey A Law (law@cygnus.com)
+
+ * except.c (start_catch_handler): Use emit_cmp_and_jump_insns.
+ * explow.c (probe_stack_range): Likewise.
+ * expmed.c (do_cmp_and_jump): Likewise.
+ * expr.c (store_expr, expand_expr, expand_builtin): Likewise.
+ (do_tablejump): Likewise.
+ * stmt.c (expand_expr_stmt, expand_end_case): Likewise.
+ (do_jump_if_equal, emit_case_nodes): Likewise.
+ * optabs.c (emit_cmp_and_jump_insns): Clarify comments. If UNSIGNEDP,
+ then convert comparison to an unsigned code before emitting the jump.
+ (expand_float, expand_fix): Use emit_cmp_and_jump_insns.
+
+Sun Feb 14 02:24:15 PST 1999 Jeff Law (law@cygnus.com)
+
+ * version.c: Bump for snapshot.
+
+Sun Feb 14 01:15:04 PST 1999 Jeff Law (law@cygnus.com)
+
+ * version.c: Bump for snapshot.
+
+Sun Feb 14 00:45:50 1999 Jeffrey A Law (law@cygnus.com)
+
+ * loop.c: Disable recent loop changes. Temporary as Joern
+ continues to fix problems.
+
+Sat Feb 13 23:29:42 1999 Richard Henderson <rth@cygnus.com>
+
+ * loop.c (combine_givs_used_by_other): Delete.
+ (combine_givs_benefit_from): Delete.
+ (combine_givs): Deny combination of givs only used once. Simplify
+ code with the death of combine_givs_benefit_from.
+
+Sun Feb 14 11:24:05 1999 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
+
+ * loop.c (scan_loop): Call reg_in_basic_block_p before
+ loop_reg_used_before_p.
+
+Sat Feb 13 05:32:00 1999 Richard Earnshaw (rearnsha@arm.com)
+
+ * arm.md: Use gen_rtx_FOO instead of gen_rtx (FOO, ...).
+ * arm.h: Likewise.
+ * arm.c: Likewise.
+
+ * arm.h (TARGET_OPTIONS): Reformat for clarity.
+ (GO_IF_LEGITIMATE_ADDRESS): When generating PIC, references to symbols
+ in the constant pool aren't valid.
+ (LEGITIMATE_PIC_OPERAND_P): Likewise.
+
+ * arm.c: Include "system.h", not stdio.h and string.h.
+
+Fri Feb 12 13:06:28 1999 Jim Wilson <wilson@cygnus.com>
+
+ * stmt.c (expand_return): Return if optimize_tail_recursion succeeded.
+ (optimize_tail_recursion): Change return type from void to int.
+ Add return statements.
+ * tree.h (optimize_tail_recursion): Change prototype to match.
+
+Fri Feb 12 21:09:51 1999 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * reload.c (find_reloads_subreg_address): New function, broken out of
+ find_reloads_toplev.
+ (find_reloads_toplev, find_reloads_address_1): Use it.
+
+Fri Feb 12 13:20:52 1999 Jeffrey A Law (law@cygnus.com)
+
+ * h8300.md (zero_extendhisi2 H8/300 variant): Correctly handle
+ extending a CONST_INT.
+
+ * h8300.md (peephole for combining memrefs): Delete incorrect peephole.
+
+Fri Feb 12 18:29:11 1999 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * loop.c (loop_insn_first_p, biv_elimination_giv_has_0_offset):
+ New functions.
+ (maybe_eliminate_biv_1): Use biv_elimination_giv_has_0_offset.
+
+Fri Feb 12 16:56:10 1999 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * loop.c (load_mems): Don't guess how to do a load / store, use
+ emit_move_insn.
+
+Fri Feb 12 09:24:26 1999 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * system.h: Provide a definition for HOST_WIDEST_INT, etc.
+
+Fri Feb 12 23:37:26 1999 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
+
+ * config/c4x/c4x.c (c4x_address_cost): Revert 9 Feb change.
+
+Fri Feb 12 00:51:26 1999 Jeffrey A Law (law@cygnus.com)
+
+ * reload.c (find_reloads_address_1): Fix handling of an autoincremented
+ pseudo which is homed in the stack.
+
+ * mips.c (save_restore_insns): Fix loop to save/restore FP registers.
+ (compute_frame_size): Change loop over FP regs to be consistent
+ with the loop in save_restore_insns.
+
+Thu Feb 11 17:38:40 1999 Jim Wilson <wilson@cygnus.com>
+
+ * i960/i960.h (OVERRIDE_OPTIONS): Warn if -mlong-double-64 is used.
+ (LONG_DOUBLE_TYPE_SIZE): Undef then unconditionally define to 96.
+
+Thu Feb 11 15:11:35 1999 Jeffrey A Law (law@cygnus.com)
+
+ * mn10200.md (bset); Re-enable.
+
+Thu Feb 11 15:20:49 1999 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * sh.md (is_sfunc): New attribute.
+ * sh.h (INSN_SETS_ARE_DELAYED, INSN_REFERENCES_ARE_DELAYED): Use it.
+
+Thu Feb 11 01:06:49 1999 Nathan Sidwell <nathan@acm.org>
+
+ * fold-const.c (range_binop): Take account of the bounded nature
+ of fixed length arithmetic when comparing unbounded ranges.
+
+Thu Feb 11 00:08:17 1999 John Wehle (john@feith.com)
+
+ * function.c (assign_stack_temp_for_type): Clear best_p
+ when an exact match is found.
+
+ * i386.h (LOCAL_ALIGNMENT): Define.
+ * function.c (assign_stack_local, assign_outer_stack_local): Use it.
+ (assign_stack_temp_for_type): New function based on assign_stack_temp.
+ (assign_stack_temp): Call it.
+ (assign_temp): Use assign_stack_temp_for_type, not assign_stack_temp.
+ * stmt.c: Use assign_temp, not assign_stack_temp.
+ * tm.texi: Document LOCAL_ALIGNMENT.
+
+Wed Feb 10 23:28:28 1999 Jeffrey A Law (law@cygnus.com)
+
+ * reorg.c: Finish deleting half-deleted comment.
+
+Wed Feb 10 17:12:21 1999 Jim Wilson <wilson@cygnus.com>
+
+ * emit-rtl.c (operand_subword): Sign extend REAL_VALUE_TO_TARGET_SINGLE
+ result.
+ * final.c (split_double): Sign extend REAL_VALUE_TO_TARGET_DOUBLE
+ result.
+ * real.c (endian): Delete sign extension code.
+ * config/m32r/m32r.md (movsf_insn+1): REAL_VALUE_TO_TARGET_SINGLE call
+ replaced with operand_subword call.
+
+Wed Feb 10 15:16:39 1999 Richard Henderson <rth@cygnus.com>
+
+ * alpha.md (cmov compound patterns): Delete. Jump can now
+ create the correct constructs in the first place.
+
+Wed Feb 10 11:03:22 1999 Richard Henderson <rth@cygnus.com>
+
+ * configure.in (alphaev6*): Fix typo in target_cpu_default2.
+
+Wed Feb 10 13:59:18 1999 Dave Brolley <brolley@cygnus.com>
+
+ * mbchar.c (local_mb_cur_max): Handle the case where MB_CUR_MAX is 0.
+
+Wed Feb 10 10:35:05 1999 Jim Wilson <wilson@cygnus.com>
+
+ * tmp-emsgids.c: Delete.
+
+Wed Feb 10 09:57:08 1999 Mark Mitchell <mark@markmitchell.com>
+
+ * rtlanal.c (for_each_rtx): Fix declaration to conform to GNU
+ coding standards.
+
+Wed Feb 10 10:09:41 1999 Jeffrey A Law (law@cygnus.com)
+
+ * mn10200.md (bset, bclr): Operand 0 is a read/write operand.
+
+ * reload1.c (reload_combine_note_store): Second argument is no
+ longer unused/ignored. Handle multi-register hard regs.
+ (move2add_note_store): Simplify.
+
+Wed Feb 10 10:05:23 1999 Mumit Khan <khan@xraylith.wisc.edu>
+
+ * collect2.c (collect_execute): Remove cygwin-specific code.
+
+Tue Feb 9 17:27:29 GMT 1999 Nathan Sidwell <nathan@acm.org>
+
+ * system.h (_, N_): Remove dummy i18n macros.
+ * protoize.c: Move inclusion of intl.h to after system.h.
+ * cexp.y: Include intl.h.
+ * cexp.c: Rebuilt.
+
+Tue Feb 9 16:52:22 1999 Mumit Khan <khan@xraylith.wisc.edu>
+
+ * i386/cygwin.h (SUBTARGET_OVERRIDE_OPTIONS): New macro to ignore
+ fpic/fPIC for windows32 targets.
+ * i386/xm-cygwin.h (GET_ENV_PATH_LIST): Replace '\\' in windows32
+ paths with '/'.
+ * i386/mingw32.h (CPP_SPEC): Define.
+ (CPP_PREDEFINES): Add MINGW32 version id.
+ * i386/crtdll.h (CPP_PREDEFINES): Likewise.
+
+ * Makefile.in (collect2$(exeext)): Delete redundant dependency and
+ add missing exeext to target.
+
+ * gcc.c (convert_filename): Handle null filename argument.
+
+Wed Feb 10 15:46:10 1999 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
+
+ * config/c4x/c4x.md (*movhf_noclobber, *movhi_noclobber): Use
+ m constraint instead of QT.
+
+1999-02-09 Brendan Kehoe <brendan@cygnus.com>
+
+ * cpplib.c (special_symbol): Move IP to be declared in function
+ scope, rather than individual case statements.
+
+1999-02-09 16:42 -0500 Zack Weinberg <zack@rabi.columbia.edu>
+
+ * cppfiles.c (finclude): Handle pipes properly under old BSD
+ derivatives.
+
+1999-02-09 16:42 -0500 Melissa O'Neill <oneill@cs.sfu.ca>
+
+ * system.h: Provide fallback definitions for S_ISCHR,
+ S_ISSOCK, S_ISFIFO, O_NONBLOCK, and O_NOCTTY.
+
+1999-02-09 10:30 -0500 Zack Weinberg <zack@rabi.columbia.edu>
+
+ * cpplib.c (do_define): Allow redefining __STDC__ with -D.
+
+1999-02-09 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ * configure.in: For PowerPC configurations, accept "401", "ec603e",
+ "740", and "750" as valid arguments to --with-cpu.
+ * configure: Rebuilt.
+
+Tue Feb 9 00:00:14 1999 Mark Kettenis <kettenis@gnu.org>
+
+ * configure.in (i[34567]86-*gnu*): Set float_format to i386.
+ * configure: Rebuilt.
+
+Mon Feb 8 22:38:24 1999 Jeffrey A Law (law@cygnus.com)
+
+ * rs6000.md: Revert "alternate use of crs if cr0 not available"
+ patches from 01-22-1999, 01-24-1999, 01-26-1999, and 02-08-1999.
+
+Mon Feb 8 21:36:44 1999 Richard Henderson <rth@cygnus.com>
+
+ * output.h (current_function_has_computed_jump): Rename from
+ current_function_addresses_labels.
+ * function.h (struct function): Likewise for addresses_labels member.
+ * rtl.h (FUNCTION_FLAGS_HAS_COMPUTED_JUMP): Likewise.
+ * function.c (current_function_has_computed_jump): Likewise.
+ Update all references.
+ * integrate.c (function_cannot_inline_p):
+ Test current_function_has_computed_jump instead of addresses_labels.
+ (initialize_for_inline): Likewise save.
+ (output_inline_function): Likewise restore.
+
+ * expr.c (expand_expr): Don't reference addresses_labels variables.
+ * stmt.c (expand_computed_goto): Set has_computed_jump.
+
+1999-02-08 Michael Meissner <meissner@cygnus.com>
+
+ This is being installed only to get it into the repository to help
+ with the revert, resubmit & review process for the massive rs6000.md
+ changes.
+ * rs6000.md (andsi3_internal1 splitter): Don't split if using the
+ rlwinm instruction.
+ (anddi3_internal1): Ditto.
+ (andsi3_internal{2,3}): Correct some insn lengths.
+ (anddi3*): Restore missing TARGET_POWERPC64, and don't emit old
+ mnemonics.
+
+Mon Feb 8 21:31:06 1999 Richard Henderson <rth@cygnus.com>
+
+ * loop.c (reg_single_usage): New file-scope variable ...
+ (scan_loop): ... moved out of here. Always initialize.
+ Test loop_has_call instead of reg_single_usage not zero.
+ Free reg_single_usage after strength reduction.
+ (count_loop_regs_set): Assume single_usage non-zero.
+ (combine_givs_used_by_other): Test reg_single_usage.
+ (load_mems_and_recount_loop_regs_set): Remove reg_single_usage
+ as a parameter. Assume non-zero.
+
+1999-02-08 23:25 -0500 Zack Weinberg <zack@midnite.ec.rhno.columbia.edu>
+
+ * cpplib.c (special_symbol): Rewrite. Don't copy things
+ multiple times. Handle __STDC__ specially. T_CONST
+ indicates a constant /string/. Don't handle T_*_TYPE and
+ T_SPEC_DEFINED. Use cpp_buf_line_and_col instead of
+ adjust_position. Determine the file buffer only if needed.
+ (initialize_builtins): Handle __SIZE_TYPE__,
+ __PTRDIFF_TYPE__, __WCHAR_TYPE__, __USER_LABEL_PREFIX__, and
+ __REGISTER_PREFIX__ with T_CONST special hashtab entries.
+ Don't provide __OBJC__; the driver does that. Provide
+ __STDC_VERSION__, using T_CONST. Use T_STDC for
+ __STDC__. Give install the length of all symbols defined.
+ (eval_if_expression): Drop code to insert and remove the
+ "defined" special symbol.
+
+ * cpplib.h: Remove SELF_DIR_DUMMY (no longer used). Remove
+ T_*_TYPE and T_SPEC_DEFINED from enum node_type; add T_STDC.
+
+ * cpphash.c (install): Drop the `ivalue' parameter. Constify
+ the `value' parameter. All callers changed.
+ * cpphash.h (install): Change prototype to match.
+ (union hashval): Remove `ival' member.
+ * cppexp.c (cpp_lex): Handle `defined' here.
+
+Mon Feb 8 17:29:42 1999 Jeffrey A Law (law@cygnus.com)
+
+ * pa.h (EXTRA_CONSTRAINT): Fix comment.
+
+Mon Feb 8 18:57:45 1999 Vladimir N. Makarov <vmakarov@cygnus.com>
+
+ * c-typeck.c (check_init_type_bitfields): Use nonincremental
+ initialization of unions whose first member is a bitfield.
+ Remove unnecessary code for checking the declaration mode
+ after DECL_C_BIT_FIELD.
+
+ * varasm.c (output_constructor): Additional comment about the
+ constructor of bitfield union initialization.
+
+Tue Feb 9 11:55:04 1999 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
+
+ * config/c4x/c4x.md (*movhi_stik): New pattern.
+ (movhi): Allow some immediate constants to be directly
+ stored in memory.
+
+Tue Feb 9 11:34:15 1999 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
+
+ * config/c4x/c4x.md (all call patterns): Add constraints "Ur".
+ (call, call_value): Force address into a register if not valid
+ for a call instruction.
+ (load_immed_address): Emit a USE of the SYMBOL_REF that is
+ forced into memory.
+ * config/c4x/c4x.c (c4x_print_operand): Fix 'C' and 'U' modifiers.
+
+Tue Feb 9 11:08:41 1999 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
+
+ * config/c4x/c4x.c (call_address_operand, symbolic_address_operand):
+ Rename from call_operand and symbolic_operand respectively. All
+ callers changed.
+ * config/c4x/c4x.md (call_address_operand, symbolic_address_operand):
+ Likewise.
+ * config/c4x/c4x.h (call_address_operand, symbolic_address_operand):
+ Likewise.
+ (PREDICATE_CODES): Allow CONST, LABEL_REF for call_address_operand.
+
+Tue Feb 9 10:52:27 1999 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
+
+ * config/c4x/c4x.c (c4x_legitimize_address): Don't generate a
+ LO_SUM address for HImode or HFmode but instead force address into
+ a register so that it is offsettable.
+ (c4x_emit_move_sequence): Handle LO_SUM immediate address.
+
+Tue Feb 9 10:46:42 1999 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
+
+ * config/c4x/c4x.c (c4x_address_cost): Return cost of 1 for
+ REG+REG addressing if strength reduction enabled.
+
+Tue Feb 9 10:10:31 1999 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
+
+ * config/c4x/t-c4x (LIBGCC2_CFLAGS): Delete.
+ (TARGET_LIBGCC2_CFLAGS): Define.
+
+1999-02-08 Nick Clifton <nickc@cygnus.com>
+
+ * config/v850/v850.md: Replace \\n\\t with \\;
+
+ * config/v850/v850.md: Enforce TARGET_LONG_CALLS option.
+ * config/v850/v850.c (construct_restore_jr, construct_save_jarl):
+ Enforce TARGET_LONG_CALLS option.
+
+Mon Feb 8 11:43:07 1999 Donn Terry <donn@interix.com>
+
+ * real.c (PUT_REAL) [XFmode]: Zero the balance of the structure.
+
+Mon Feb 8 11:37:24 1999 Marc Espie (espie@cvs.openbsd.org)
+
+ * m88k/t-luna-gas: Remove bash dependency.
+
+Mon Feb 8 11:34:44 1999 Graham <grahams@rcp.co.uk>
+
+ * collect2.c (xrealloc): Fix typo in last change.
+
+Mon Feb 8 09:13:38 PST 1999 Jeff Law (law@cygnus.com)
+
+ * version.c: Bump for snapshot.
+
+Sun Feb 7 22:18:42 1999 Robert Lipe <robertlipe@usa.net>
+
+ * tree.h (TYPE_CHECK): Make it clear to the preprocessor
+ that we do not want macro replacement within a character constant.
+ (TYPE_CHECK1): Likewise.
+
+Sun Feb 7 15:37:10 1999 Jason Merrill <jason@yorick.cygnus.com>
+
+ * tree.h (DECL_P): New macro.
+
+Sun Feb 7 01:15:04 PST 1999 Jeff Law (law@cygnus.com)
+
+ * version.c: Bump for snapshot.
+
+Sat Feb 6 18:14:46 1999 Jeffrey A Law (law@cygnus.com)
+
+ * mn10300.md (reload_insi): Do not earlyclobber the output operand.
+
+ * README.g77, gcc.c, gcc.texi: Update email addresses.
+ * invoke.texi system.h: Likewise.
+
+Sat Feb 6 11:04:08 1999 Jim Wilson <wilson@cygnus.com>
+
+ * unroll.c (find_splittable_givs): After express_from, call replace_rtx
+ to convert dest_reg to new_reg.
+
+Sat Feb 6 10:31:35 1999 Jeffrey A Law (law@cygnus.com)
+
+ * reload1.c (reload_combine_note_store): Be more careful with
+ STRICT_LOW_PART, ZERO_EXTRACT and SIGN_EXTRACT.
+ (move2add_note_store): Likewise.
+
+Sat Feb 6 10:18:01 1999 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * cppfiles.c (read_and_prescan): Cast the result of `xrealloc' to
+ U_CHAR* when assigning to one. Ensure the values of a ?: operator
+ have the same type.
+
+ * cppinit.c (initialize_char_syntax): Use K&R function definition.
+
+Sat Feb 6 11:17:03 1999 Richard Earnshaw <rearnsha@arm.com>
+
+ Support for ARM9
+ * config/arm/arm.c (all_procs): Add arm9 and arm9tdmi.
+ * config/arm/arm.h ((TARGET_CPU_arm9, TARGET_CPUD_arm9tdmi): Define.
+ (TARGET_CPU_DEFAULT): Rework to support ARM9.
+ (CPP_CPU_ARCH_SPEC): Likewise.
+ (enum processor_type): Likewise.
+ * config/arm/arm.md (attr cpu): Add arm9.
+
+ General scheduling changes
+ * config/arm/arm.c (MAX_INSNS_SKIPPED): Delete.
+ (max_insns_skipped): New variable.
+ (arm_override_options): If generating hard floating point code for
+ the FPA, emit code for version 3.
+ When optimizing for space, don't synthesize constants.
+ Reword several flags based on the requested processor and optimization
+ level.
+ (use_return_insn): New argument iscond, all callers changed. Don't
+ use a return insn if it will be conditional and that would be
+ expensive; eg on StrongARM.
+ (arm_adjust_cost): Anti- and output- dependencies normally have no
+ cost.
+ (load_multiple_sequence): Newer ARMs don't benefit from ldm if
+ the sequence is short.
+ (final_prescan_insn): Use max_insns_skipped instead of
+ MAX_INSNS_SKIPPED. Note whether we will make a return instruction
+ conditional, and aviod this if it would be expensive.
+ * config/arm/arm.md (scheduling attributes and function units):
+ Rewrite to better describe ARM8, 9 and StrongARM.
+
+ * config/arm/arm.md (*movhi_insn_littleend): Make op0 predicate
+ s_register_operand.
+ (*ifcompare_plus_move): Use arm_rhs_operand in place of
+ arm_rhsm_operand. Rework constraints.
+ (*if_plus_move): Likewise.
+ (*ifcompare_move_plus): Likewise.
+ (*if_move_plus): Likewise.
+ (*ifcompre_arith_move): Likewise.
+ (*if_arith_move): Likewise.
+ (*ifcompare_move_arith): Likewise.
+ (*if_move_arith): Likewise.
+
+ * config/arm/xm-netbsd.h: Don't include arm/xm-arm.h.
+
+1999-02-05 Michael Meissner <meissner@cygnus.com>
+
+ * loop.c (check_dbra_loop): A store using an address giv for which
+ we have no life information is not reversible.
+
+Fri Feb 5 17:08:01 1999 Dave Brolley <brolley@cygnus.com>
+
+ * function.c (fixup_var_refs): Scan catch_clauses too.
+
+Fri Feb 5 11:49:49 1999 Benjamin Kosnik <bkoz@loony.cygnus.com>
+
+ * c-common.c (decl_attributes): Fix reserved space for init_priority.
+ * tree.h (MAX_RESERVED_INIT_PRIORITY): New macro.
+
+Fri Feb 5 12:37:05 1999 Jeffrey A Law (law@cygnus.com)
+
+ * loop.c (strength_reduce): Clear not_every_iteration when
+ passing the NOTE_INSN_LOOP_CONT note.
+
+ * haifa-sched.c (add_dependence): Do not add a dependency on a
+ note.
+
+Fri Feb 5 10:55:43 1999 Nick Clifton <nickc@cygnus.com>
+
+ * recog.c (split_block_insns): Only call update_flow_info if
+ instruction scheduling is enabled.
+
+1999-02-05 11:22 -0500 Zack Weinberg <zack@rabi.columbia.edu>
+
+ * Makefile.in (gen-protos): Use libcpp.a like everyone else.
+
+Fri Feb 5 07:09:29 1999 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * loop.c (first_loop_store_insn): New file-scope variable.
+ (prescan_loop): Set it.
+ (check_dbra_loop): Check if a store depends on a register
+ that is set after the store.
+
+Fri Feb 5 06:55:15 1999 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * unroll.c (entire file): Remove tabs / spaces at end of lines.
+ Replace spaces with tabs where appropriate.
+
+Thu Feb 4 15:12:41 1999 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * loop.c (scan_loop): New argument loop_cont. Changed caller.
+ (strength_reduce): New argument loop_cont. Changed caller.
+ Before clearing not_every_iteration after a label, check if
+ we are not already past LOOP_CONT.
+
+1999-02-04 16:04 -0500 Zack Weinberg <zack@rabi.columbia.edu>
+
+ * cpperror.c (cpp_print_containing_files): Fix formatting
+ bug induced by merge.
+
+1999-02-04 14:33 -0500 Zack Weinberg <zack@rabi.phys.columbia.edu>
+
+ * cpplib.c (initialize_char_syntax): Move to cppinit.c.
+ (cpp_define): Remove redundant syntax checks.
+ (make_assertion): Rename cpp_assert, remove redundant syntax
+ checks, export.
+ (cpp_options_init): Don't init things to zero twice.
+ (cpp_expand_to_buffer): Use memcpy, not a char-by-char loop.
+ (do_include): Kill excessively verbose #import warning that
+ snuck back in in the gcc2 merge.
+ (convert_string): Removed.
+ (do_line): Rewrite with simple last-name-used cache instead of
+ private hashtable.
+ (cpp_start_read): Call initialize_char_syntax here, not...
+ (cpp_reader_init): ...here.
+ (cpp_handle_options): Support the -std switch.
+ * cpplib.h (cpp_buffer): Add last_nominal_fname member.
+ (cpp_options): Add c9x flag.
+ Declare all the is_* tables and trigraph table here, as const.
+ Prototype cpp_assert and initialize_char_syntax.
+ * cppinit.c: New file.
+ * cppfiles.c (read_and_prescan): Optimize.
+ * Makefile.in (LIBCPP_OBJS): Add cppinit.o.
+
+Thu Feb 4 10:46:30 1999 Gavin Romig-Koch <gavin@cygnus.com>
+
+ * config/mips/mips.md ([u]divmodsi4,[u]divmoddi4,[u]divsi3,[u]divdi3,
+ [u]modsi3,[u]moddi3) : Don't copy the "zero" argument to a register
+ before calling gen_div_trap.
+
+Wed Feb 3 21:56:27 1999 Jeffrey A Law (law@cygnus.com)
+
+ * configure.in (hppa1.1-*-*, hppa2*-*): Use symbolic value rather
+ than numeric value for target_cpu_default..
+ * configure: Rebuilt.
+
+Wed Feb 3 21:55:56 1999 Marc Espie <Marc.Espie@liafa.jussieu.fr>
+
+ * Makefile.in (xgcc$(exeext)): Remove choose-temp, pexecute and
+ mkstemp. Get them from libiberty.
+ (COLLECT2_OBJS): Similarly for choose-temp, cplus-dem and mkstemp.
+ (PROTO_OBJS): Similarly for choose-temp, getopt, getopt1 and pexecute.
+ (cplus-dem.o, pexecute.o, choose-temp.o): Remove build rules.
+ (mkstemp.o, getopt1.o, getopt.o): Likewise.
+
+ * pa-gas.h (TARGET_DEFAULT): Use symbolic values rather than numeric
+ values.
+ * pa-hpux.h (LINK_SPEC): Likewise.
+ * pa-hpux10.h (LINK_SPEC): Likewise.
+ * pa-hpux9.h (LINK_SPEC): Likewise.
+ * pa-osf.h: (LINK_SPEC): Likewise.
+ * pa-pro.h (TARGET_DEFAULT): Likewise.
+ * pa1.h (TARGET_DEFAULT): Likewise.
+ * pa.h (MASK_*): New defines.
+ (TARGET_*): Use symbolic values rather than numeric values.
+ (TARGET_SWITCHES): Likewise.
+ (TARGET_DEFAULT): likewise.
+ (CPP_SPEC): likewise.
+
+Wed Feb 3 21:07:38 1999 Bernd Schmidt <crux@pool.informatik.rwth-aachen.de>
+
+ * reload1.c (reload_cse_regs_1): Undo Jan 16 patch.
+ * reload.c (find_reusable_reload): New function, broken out of
+ push_reload. Add code to verify that none of the involved
+ outputs are subject to earlyclobbers.
+ (push_reload): Break out new function find_reusable_reload.
+ Delete "register" keyword for IN, OUT args.
+
+Wed Feb 3 15:51:04 1999 Gavin Romig-Koch <gavin@cygnus.com>
+
+ * config/mips/mips.c (true_reg_or_0_operand) : New function.
+ * config/mips/mips.h (PREDICATE_CODES): Add true_reg_or_0_operand.
+ * config/mips/mips.md (div_trap,div_trap_normal,div_trap_mips16):
+ Use true_reg_or_0_operand for div_trap.
+
+Wed Feb 3 20:44:59 1999 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * loop.h (express_from): Declare.
+ (struct induction): Replace derived flag with derived_from pointer.
+ * loop.c (strength_reduce, record_giv, recombine_givs): Likewise.
+ (express_from): No longer static.
+ * unroll.c (find_splittable_givs): Replace derived with derived_from.
+ When processing an address giv with which another giv has been
+ combined that has also been derived from a third giv, handle like
+ having combined with the third giv.
+ Set splittable_regs_updates appropriately for derived givs.
+
+Wed Feb 3 15:26:58 1999 Gavin Romig-Koch <gavin@cygnus.com>
+
+ * config/mips/mips.md (div_trap_mips16): Remove nop's after branches.
+
+Wed Feb 3 11:56:23 1999 Jeffrey A Law (law@cygnus.com)
+
+ * pa.c (insn_sets_and_refs_are_delayed): New function.
+ * pa.h (INSN_SETS_ARE_DELAYED): Use it.
+ (INSN_REFERENCES_ARE_DELAYED): Likewise.
+
+Wed Feb 3 06:24:49 1999 Richard Earnshaw (rearnsha@arm.com)
+
+ * config/arm/t-arm-elf (LIBGCC2_CFLAGS): Delete.
+ * config/arm/t-linux (LIBGCC2_CFLAGS): Delete.
+ (TARGET_LIBGCC2_CFLAGS): Define.
+ (LIBGCC2_DEBUG_CFLAGS): Define.
+ * config/arm/t-netbsd: Likewise.
+ * config/arm/t-semi: Likewise.
+ * config/arm/t-semiaof: Likewise.
+ * config/arm/t-riscix: Likewise.
+
+Wed Feb 3 10:59:07 1999 Andreas Schwab <schwab@issan.cs.uni-dortmund.de>
+
+ * config/m68k/m68k.c (print_operand_address): When printing a
+ SYMBOL_REF that ends in `.<letter>' put parentheses around it.
+
+Tue Feb 2 23:38:35 1999 David O'Brien <obrien@FreeBSD.org>
+
+ * i386/freebsd*.h now allows '$' in label names and does not use the
+ PCC struct return method.
+
+Tue Feb 2 22:38:23 1999 Jim Wilson <wilson@cygnus.com>
+
+ * Makefile.in: Change all uses of AR to AR_FOR_TARGET. Change all uses
+ of HOST_AR to AR. Likewise for AR_FLAGS, RANLIB, and RANLIB_TEST.
+ (RANLIB_TEST): Test to see if ranlib exists. Only test absolute file
+ names if host == target.
+ (HOST_AR, HOST_AR_FLAGS, HOST_RANLIB, HOST_RANLIB_TEST): Delete.
+ (AR_FLAGS_FOR_TARGET): Renamed from AR_FOR_TARGET_FLAGS.
+ (AR, AR_FLAGS, OLDAR, OLDAR_FLAGS, RANLIB, RANLIB_TEST): Delete rules
+ setting them to *_FOR_TARGET.
+ * cross-make (AR, AR_FLAGS, OLDAR, OLDAR_FLAGS, RANLIB, RANLIB_TEST):
+ Delete.
+
+Tue Feb 2 22:38:19 1999 Theodore Papadopoulo <Theodore.Papadopoulo@sophia.inria.fr>
+
+ * toplev.h (read_integral_parameter): Declare.
+ * toplev.c (read_integral_parameter): New function.
+
+Fri Jan 29 21:00:56 1999 Bob Manson <manson@charmed.cygnus.com>
+
+ * resource.c, resource.h: New files.
+ * Makefile.in (OBJS): Add it.
+
+ * haifa-sched.c (regno_use_in): Moved to rtlanal.c.
+ (split_block_insns): Moved to recog.c.
+ (update_flow_info): Make public.
+ * rtl.h: Declare them.
+
+ * reorg.c: Moved the functions dealing with computing resource
+ usage to resource.c.
+
+ * sched.c (regno_use_in): Moved to rtlanal.c.
+ (update_flow_info): Make public.
+ (schedule_insns): Use split_block_insns.
+
+ * recog.c (split_block_insns): New function.
+
+Tue Feb 2 22:03:26 1999 David Edelsohn <edelsohn@gnu.org>
+
+ * rs6000/linux.h (LINK_START_DEFAULT_SPEC): Delete, unused.
+ (LINK_OS_DEFAULT_SPEC): Delete, unused.
+
+Tue Feb 2 20:29:34 1999 Catherine Moore <clm@cygnus.com>
+
+ * configure.in (arm-*-oabi): Support.
+ * configure: Regenerate.
+ * config/arm/unknown-elf-oabi.h: New file.
+
+Tue Feb 2 19:43:59 1999 Jeffrey A Law (law@cygnus.com)
+
+ * i386.md (ashlsi3): Turn into a define_expand an anonymous pattern.
+ Make the anonymous pattern match when ! optimize_size.
+ (ashlsi3 size optimizer): New pattern.
+
+ * intl/Makefile.in (uninstall): Add missing "; \".
+
+Tue Feb 2 18:21:23 1999 Stan Cox <scox@cygnus.com>
+
+ * sparc.h (TARGET_CPU_sparc86x): Added. TARGET_CPU_sparclite86x
+ synonym.
+
+Tue Feb 2 20:24:11 1999 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * loop.c (loop_optimize): Fix value max_uid_for_loop is reset
+ to after find_and_verify_loops call.
+
+Tue Feb 2 19:48:29 1999 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * (recombine_givs): Don't use a giv that's likely to be dead to
+ derive others.
+
+ * loop.c (recombine_givs): Fix test for lifetime overlaps / loop
+ wrap around when deriving givs.
+
+Mon Feb 1 20:00:40 1999 Richard Henderson <rth@cygnus.com>
+
+ * recog.c (check_asm_operands): Treat indeterminate operand ok
+ results as success. Try harder to resolve a matching constraint.
+ * stmt.c (expand_asm_operands): Recognize when an output operand's
+ constraint does not allow memory. Treat indeterminate operand ok
+ results as failure. Try harder to resolve a matching constraint.
+
+Mon Feb 1 15:00:02 1999 Ken Raeburn <raeburn@cygnus.com>
+
+ Use varrays for constant-equivalence data:
+
+ * varray.h (struct const_equiv_data): New type.
+ (union varray_data_tag): New element const_equiv.
+ (VARRAY_CONST_EQUIV_INIT, VARRAY_CONST_EQUIV): New macros.
+ (VARRAY_SIZE): New macro, returns number of elements.
+ * integrate.h: Include varray.h.
+ (struct inline_remap): Replace const_equiv_map, const_age_map and
+ const_equiv_map_size with a const_equiv_varray element.
+ (MAYBE_EXTEND_CONST_EQUIV_VARRAY): New macro; grows varray if
+ needed.
+ (SET_CONST_EQUIV_DATA): New macro; sets rtx and age fields
+ simultaneously, growing the varray if needed.
+
+ * integrate.c (global_const_equiv_map,
+ global_const_equiv_map_size): Deleted, replaced by....
+ (global_const_equiv_varray): New variable.
+ (expand_inline_function): References changed.
+ * integrate.h: Update declarations.
+
+ * integrate.c (process_reg_parm, expand_inline_function,
+ copy_rtx_and_substitute, try_constants, subst_constants,
+ mark_stores): Use varray allocation and accessor macros, new
+ integrate.h macros, and global_const_equiv_varray. Don't
+ conditionalize non-NULL stores on array size; instead, expand the
+ array as needed.
+ * unroll.c (unroll_loop): Likewise.
+
+ * unroll.c (unroll_loop): Initialize const_equiv_varray element to
+ zero. After allocating varray, always exit through bottom of
+ function, where it can be deallocated if needed. Don't explicitly
+ reallocate const_equiv_map storage; instead, just ensure the
+ varray has been initialized, and update the global reference.
+
+Mon Feb 1 09:40:25 1999 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * system.h (inline, const): Handle these for stage2 (and later) gcc.
+
+ * dwarf2out.c (inline): Don't define.
+
+ * dwarfout.c (inline): Likewise.
+
+Sun Jan 31 22:04:37 1999 Richard Henderson <rth@cygnus.com>
+
+ * loop.c (recombine_givs): Dump recombination and derivation data.
+
+Sun Jan 31 20:34:29 1999 Zack Weinberg <zack@rabi.columbia.edu>
+
+ * flags.h: Declare flag_no_ident.
+ * toplev.c: Define flag_no_ident. Process -f(no-)ident here.
+ * c-tree.h: Don't declare flag_no_ident.
+ * c-decl.c: Don't define flag_no_ident. Don't process
+ -f(no-)ident switches here.
+
+ * config/elfos.h (ASM_FILE_END): Output final .ident directive
+ only if !flag_no_ident.
+ * config/ptx4.h: Likewise.
+ * config/svr4.h: Likewise.
+ * config/alpha/elf.h: Likewise.
+ * config/arm/linux-elf.h: Likewise.
+ * config/i386/sco5.h: Likewise.
+ * config/i860/fx2800.h: Likewise.
+ * config/mips/gnu.h: Likewise.
+ * config/i386/osfrose.h: Likewise.
+
+ * gcc.c (C specs): Map -Qn to -fno-ident.
+ * objc/lang-specs.h: Likewise.
+
+Mon Feb 1 10:52:07 1999 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
+
+ * configure.in: Don't remove loop.o and unroll.o when
+ enable-haifa is selected.
+ * configure: Rebuilt.
+
+Sun Jan 31 13:22:02 1999 John Wehle (john@feith.com)
+
+ * i386.md (movsicc, movhicc, movsfcc, movdfcc,
+ movxfcc, movdicc): Delete unconstrained alternatives.
+ * i386.c (output_fp_conditional_move,
+ output_int_conditional_move): Delete unused case.
+
+Sun Jan 31 01:15:04 PST 1999 Jeff Law (law@cygnus.com)
+
+ * version.c: Bump for snapshot.
+
+Sun Jan 31 00:52:37 1999 Richard Henderson <rth@cygnus.com>
+
+ * alpha.md (mov patterns): Emit the assembler aliases mov and fmov
+ instead of bis and cpys. Combine alternatives where possible.
+
+Sat Jan 30 23:14:13 1999 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * gcov.c (fnotice): Add missing FILE* parameter.
+ (function_summary): Fix format specifiers in calls to `fnotice'.
+ (output_data): Likewise.
+
+ * toplev.c (fnotice): Constify char* parameter.
+
+ * toplev.h (fnotice): Add prototype.
+ Wrap prototype with BUFSIZ to protect FILE* usage.
+
+Sun Jan 31 15:33:09 1999 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
+
+ * config/c4x/c4x.h (RTX_COSTS): Explicitly define c4x costs.
+
+Sat Jan 30 08:27:23 1999 Jeffrey A Law (law@cygnus.com)
+
+ * combine.c (distribute_notes): Handle REG_EH_REGION notes.
+
+ * alias.c (fixed_scalar_and_varying_struct_p): Add "static" to
+ function definition.
+ (aliases_everything_p, write_dependence_p):Likewise.
+
+ * install.texi: Fix merge lossages.
+
+ * cccp.c (main): Only call setlocale (LC_MESSAGES, ...) if LC_MESSAGES
+ is defined.
+ * collect2.c (main): Likewise.
+ * cppmain.c (main): Likewise.
+ * gcc.c (main): Likewise.
+ * gcov.c (main): Likewise.
+ * protoize.c (main): Likewise.
+ * toplev.c (main): Likewise.
+
+ * pa.md (parallel shift and shiftadd): Mark output of shift as an
+ earlyclobber.
+
+ * loop.c: Disable recent loop changes. Temporary as Joern
+ continues to fix problems.
+
+Sat Jan 30 03:24:37 1999 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * loop.c (strength_reduce): Size reg_map according to reg_iv_type.
+
+Fri Jan 29 18:26:07 1999 Dave Brolley <brolley@cygnus.com>
+
+ * emit-rtl.c (remove_insn): New function.
+ * rtl.h (remove_insn): Add prototype.
+ * function.c (reposition_prologue_and_epilogue_notes): Call remove_insn.
+
+Fri Jan 29 22:34:41 1999 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * loop.c (recombine_givs): Don't try to derive givs that have combined.
+
+Fri Jan 29 15:00:39 1999 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * toplev.c (notice, fnotice): Check ANSI_PROTOTYPES, not __STDC__,
+ when declaring arguments and calling va_arg() to initialize them.
+
+ * collect2.c (notice): Likewise.
+
+ * loop.c (find_life_end): Use PROTO() macro in the prototype.
+
+Fri Jan 29 14:36:11 1999 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * collect2.c (error): Fix typo in declaration.
+
+ * cpperror.c (cpp_message): Likewise.
+
+ * cpplib.c (cpp_warning): Likewise.
+
+ * cpplib.h (cpp_notice): Use PVPROTO not VPROTO, also add
+ ATTRIBUTE_PRINTF_1.
+
+ * toplev.c (error): Fix typo in declaration.
+
+Fri Jan 29 15:44:13 1999 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * loop.c (strength_reduce): Fix HAVE_cc0 handling when scanning
+ forward from cont dominator.
+
+Fri Jan 29 07:10:27 1999 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * cccp.c (eprint_string): Constify a char*.
+ (notice): Likewise. Use PVPROTO not VPROTO, add ATTRIBUTE_PRINTF_1.
+ (vnotice): Constify a char*.
+ (error): Likewise. Use PVPROTO not VPROTO, add ATTRIBUTE_PRINTF_1.
+ (verror): Constify a char*.
+ (warning): Likewise. Use PVPROTO not VPROTO, add ATTRIBUTE_PRINTF_1.
+ (vwarning): Constify a char*.
+ (error_with_line): Likewise. Use PVPROTO not VPROTO, add
+ ATTRIBUTE_PRINTF_2.
+ (verror_with_line): Constify a char*.
+ (vwarning_with_line): Likewise.
+ (warning_with_line): Likewise. Use PVPROTO not VPROTO, add
+ ATTRIBUTE_PRINTF_2.
+ (pedwarn): Constify a char*. Use PVPROTO not VPROTO, add
+ ATTRIBUTE_PRINTF_1.
+ (pedwarn_with_line): Likewise with ATTRIBUTE_PRINTF_2.
+ (pedwarn_with_file_and_line): Likewise with ATTRIBUTE_PRINTF_4.
+ Also correct typo in parameter name declaration.
+ (make_assertion): Constify a char*.
+ (quote_string_for_make): Likewise.
+ (deps_output): Likewise.
+ (fatal): Likewise. Use PVPROTO not VPROTO, add
+ ATTRIBUTE_PRINTF_1. Use ATTRIBUTE_NORETURN not an explicit
+ "__attribute__ ((noreturn))".
+ (fancy_abort): Likewise for ATTRIBUTE_NORETURN.
+ (pfatal_with_name): Likewise.
+ (pipe_closed): Likewise.
+ (memory_full): Likewise.
+
+Fri Jan 29 00:14:55 1999 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * loop.c (strength_reduce): Grow set_in_loop / n_times_set /
+ may_not_optimize to proper size when converting biv increments
+ into givs.
+ If necessary, reallocate reg_iv_type / reg_iv_info before calling
+ recombine_givs.
+
+Thu Jan 28 23:24:08 1999 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * loop.c (recombine_givs): New parameter unroll_p. If set, don't
+ generate complex adds. Changed caller.
+ Don't generate adds that cost more than the original one.
+ (strength_reduce): Warning fixes.
+
+Thu Jan 28 09:41:11 1999 Jeffrey A Law (law@cygnus.com)
+
+ * configure.in (hppa1.0-hp-hpux10*): Use t-pa.
+ * configure: Rebuilt.
+
+Wed Jan 27 23:39:53 1999 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * rtl.h (insn_first_p, no_jumps_between_p): Declare.
+ * rtlanal.c (insn_first_p, no_jumps_between_p): New function.
+ * loop.h (varray.h): Include.
+ (struct induction): Change combined_with to unsigned.
+ New members derived, ix and last_use.
+ (reg_iv_type, reg_iv_info): Now varray_type. All references changed.
+ (REG_IV_TYPE, REG_IV_INFO): Define.
+ (first_increment_giv, last_increment_giv): Declare.
+ * loop.c (loop_number_loop_cont): New static variable.
+ (loop_number_cont_dominator): Likewise.
+ (reg_iv_type, reg_iv_info): Now varray_type.
+ (first_increment_giv, last_increment_giv): New variables.
+ (compute_luids, verify_dominator, find_life_end): New functions.
+ (cmp_recombine_givs_stats, recombine_givs): Likewise.
+ (loop_optimize): Allocate loop_number_loop_cont and
+ loop_number_cont_dominator. Use compute_luids.
+ (find_and_verify_loops): Initialize loop_number_loop_cont and
+ loop_number_cont_dominator.
+ (strength_reduce): Try to find bivs that can be expressed as givs
+ of another biv, and to convert biv increments into givs.
+ Call recombine_givs. Handle derived givs.
+ (record_biv): New argument location. All callers changed.
+ (record_giv): Initialize derived and last_use fields.
+ (basic_induction_var): New argument location. All callers changed.
+ (combine_givs): Don't combine a DEST_REG giv with a DEST_ADDR giv.
+ Increment combined_with instead of setting to 1.
+ * unroll.c (derived_regs): New static variable.
+ (unroll_loop): Initialize it.
+ Allocate local_regno according to max_reg_num.
+ (copy_loop_body): Cope with derived givs.
+ (find_splittable_givs): Check for Givs made from biv increments.
+ Set derived_regs for givs.
+ * Makefile.in (stmt.o, loop.o, unroll.o): Depend on loop.h .
+
+Wed Jan 27 19:31:36 1999 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * function.c (purge_addressof_1): Handle case when a register
+ has been used in a wider mode.
+
+1999-01-27 Bruce Korb <autogen@linuxbox.com>
+
+ * fixinc/fixincl.c, fixinc/server.[ch]:
+ Removed the last of the capitalized variable and proc names.
+
+ * fixinc/server.c: Removed the process open code
+ * fixinc/procopen.c: New file containing the proc open code
+ * fixinc/inclhack.tpl: Added code to bypass a readability test
+ when a file is not present. A problem on some systems.
+ * fixinc/inclhack.sh, fixinc/fixincl.sh: regenerated
+
+Wed Jan 27 11:58:18 1999 Dave Brolley <brolley@cygnus.com>
+
+ * cpplib.h (cpp_notice): Add prototype.
+
+Wed Jan 27 02:20:48 1999 Jeffrey A Law (law@cygnus.com)
+
+ * Merge gcc2 snapshot 19980929.
+
+ * cccp.c (PRINTF_PROTO): Remove.
+ (PRINTF_PROTO_{1,2,3,4}: Likewise.
+ * cexp.y: Likewise.
+ * system.h: Add PRINTF_PROTO and PRINTF_PROTO_{1,2,3,4}.
+
+ * fix-header.c (cpp_file_lin_for_message): Delete. In libcpp.
+ (cpp_print_containing_files, v_cpp_message, cpp_message): Likewise.
+ (cpp_fatal, cpp-Pfatal_with_name): Likewise.
+
+ * gen-protos.c (hashf): Delete in cpphash.o
+ * gen-protos.c (hashf): Delete in cpphash.o
+
+ * expr.c: Do not merge SAVE_STACKAREA_MODE changes.
+ * expmed.c: Likewise.
+ * rs6000.md: Likewise.
+
+ * rs6000.c, rs6000.md: Do not merge formatting changes yet.
+
+Wed Jan 27 01:13:42 1999 Richard Henderson <rth@cygnus.com>
+
+ * rs6000.c (input_operand): Don't expect CONST around CONSTANT_P_RTX.
+ * rs6000.md (movsi, movdi): Likewise.
+
+Tue Jan 26 13:31:38 1999 Jim Wilson <wilson@cygnus.com>
+
+ * function.c (expand_function_end): Pass arg_pointer_save_area to
+ validize_mem before using it. Emit code into a sequence.
+
+Tue Jan 26 13:41:38 1999 David Edelsohn <edelsohn@gnu.org>
+
+ * rs6000.md (doz + set cr and or + set cr patterns): Add missing
+ '#' to split patterns. Correct indentation of some new patterns.
+
+1999-01-26 12:11 -0500 Zack Weinberg <zack@midnite.ec.rhno.columbia.edu>
+
+ * cppfiles.c (safe_read): Deleted.
+ (read_and_prescan): New function, replaces safe_read, converts
+ and/or warns about trigraphs, silently converts odd line
+ terminators (\r, \n\r, \r\n). Warns about no newline at EOF.
+ (finclude): Use read_and_prescan; turn off nonblocking mode on
+ the input descriptor; remove file-size-examination and
+ no-newline-at-EOF gunk which is longer necessary; be more
+ careful about checking that we've been handed a legitimate
+ file to read (only real files, pipes, and ttys are acceptable).
+ * cpplib.h (cpp_options): Rename no_trigraphs flag to
+ `trigraphs' and invert its sense.
+ (trigraph_table): Declare.
+ (cpp_warning_with_line): Prototype.
+ * cpplib.c: Remove all references to trigraph_pcp. Define
+ trigraph_table; initialize it in initialize_char_syntax. Open
+ files in nonblocking mode. s/no_trigraphs/trigraphs/
+ throughout, and invert sense. Put cpp_warning_with_line back
+ in and export it.
+
+Tue Jan 26 23:21:49 1999 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
+
+ * config/c4x/c4x.h (COUNTER_REGS): New register class.
+ * config/c4x/c4x.md (*rptb_init): Change constraints.
+ (rptb_end): Emit alternate looping instructions if
+ RC register not allocated for loop counter.
+ (decrement_and_branch_on_count): Allow other registers
+ for loop counter.
+
+1999-01-25 14:26 -0500 Zack Weinberg <zack@rabi.columbia.edu>
+
+ * cppexp.c (struct arglist): Removed.
+ (parse_number): Use HOST_WIDE_INT for the accumulator.
+ Allow two `l' suffixes unless C89. Clean up. Make static.
+ (parse_charconst): New function broken out of cpp_lex.
+ Code cleaned up drastically. Don't use a token_buffer.
+ (token_buffer): Removed.
+ (cpp_lex): Don't call parse_number on a constant string.
+ Use parse_charconst.
+ (cpp_parse_expr): Properly handle an ERROR op returned by
+ cpp_lex.
+
+1999-01-25 14:10 -0500 Zack Weinberg <zack@rabi.phys.columbia.edu>
+
+ * cpplib.c: Don't include signal.h, sys/times.h, or
+ sys/resource.h. Don't declare localtime.
+ (macroexpand): Handle special symbols here.
+ (push_macro_expansion): Chop off the trailing '@ ' if possible
+ here.
+ (cpp_get_token): Don't do either of the above two things here.
+ Move `string' label just after case '"' so that wide strings
+ don't crash the preprocessor.
+
+Sun Jan 24 20:13:45 1999 David Edelsohn <edelsohn@gnu.org>
+
+ * rs6000.md (left shift + set cr patterns): Add missing '#' to
+ split patterns.
+ (move register + set cr pattern): Ditto.
+ (movdi, !TARGET_POWERPC64 splitters): Add back in Jan. 15th patch,
+ inadvertently deleted.
+
+Sun Jan 24 08:07:59 1999 Jeffrey A Law (law@cygnus.com)
+
+ * stmt.c (stmt_loop_nest_empty): New function.
+ * tree.h (stmt_loop_nest_empty): Declare it.
+ * rtl.def (CALL_PLACEHOLDER): New rtx code.
+
+Sun Jan 24 21:24:43 1999 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
+
+ * config/c4x/c4x.c (c4x_emit_move_sequence, c4x_encode_section_info):
+ New functions.
+ (c4x_check_legit_addr): Remove USE and PLUS, allow
+ LO_SUM, and disable SYMBOL_REF, LABEL_REF, and CONST cases.
+ (c4x_legitimize_address): Penalise SYMBOL_REF, LABEL_REF, and
+ CONST cases. Add LO_SUM.
+ (c4x_print_operand): Modified 'C' and 'R' cases for calls.
+ Added 'U' case. Remove dependence on SYMBOL_REF_FLAG.
+ (c4x_print_operand_address): Handle LO_SUM.
+ (c4x_scan_for_ldp): Delete. Hooray!
+ (c4x_process_after_reload): Remove call to c4x_scan_for_ldp.
+ Split all insns.
+ (c4x_immed_int_constant): Renamed from c4x_int_constant. All callers
+ changed.
+ (c4x_immed_float_constant): Renamed from c4x_float_constant. All
+ callers changed.
+ (c4x_T_constraint): Allow LO_SUM, disable SYMBOL_REF, LABEL_REF,
+ and CONST.
+ (c4x_U_constraint, symbolic_operand): New functions.
+ (src_operand): Allow 'I' constants in HImode. Allow LO_SUM,
+ disable SYMBOL_REF, LABEL_REF, and CONST.
+ (lsrc_operand, tsrc_operand): Call src_operand instead of
+ general_operand.
+ (c4x_operand_subword): Update comments.
+
+ * config/c4x/c4x.c (TARGET_LOAD_ADDRESS): New macro.
+ (LEGITIMATE_CONSTANT_P): Allow SYMBOL_REF, LABEL_REF, CONST,
+ plus HIGH and LO_SUM for the C40.
+ (ENCODE_SECTION_INFO): Define macro.
+ (symbolic_operand, c4x_U_constraint, c4x_emit_move_sequence): New
+ prototypes.
+ (PREDICATE_CODES): Add symbolic_operand.
+
+ * config/c4x/c4x.md (movqi, movgqf, movhi, movhi): Call
+ c4x_emit_move_sequence.
+ (floatunsqiqf2, fixuns_truncqfqi2): Rework emitted RTL
+ to avoid symbol references.
+ (all patterns with g constraint): Replace 'g' constraint with 'rIm'.
+ (set_high): Renamed from set_high_use.
+ (set_lo_sum): Renamed from set_ior_lo_use.
+ (all call patterns): Make MEM explicit in call address operands.
+ Modified output templates to use 'U' modifier.
+
+Sun Jan 24 01:15:05 PST 1999 Jeff Law (law@cygnus.com)
+
+ * version.c: Bump for snapshot.
+
+Sat Jan 23 22:34:57 1999 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * final.c (bb_str): Qualify a char* with the keyword `const'.
+ (add_bb_string, final_scan_insn, output_asm_insn): Likewise.
+
+ * fix-header.c (read_scan_file): Likewise.
+
+ * genoutput.c (output_epilogue, process_template): Likewise.
+
+ * local-alloc.c (requires_inout, block_alloc): Likewise.
+
+ * output.h (output_asm_insn, assemble_string): Likewise.
+
+ * recog.c (recog_constraints, check_asm_operands,
+ decode_asm_operands, extract_insn, preprocess_constraints,
+ constrain_operands): Likewise.
+
+ * recog.h (operand_alternative, recog_constraints, insn_template,
+ insn_outfun, insn_operand_constraint, insn_name): Likewise.
+
+ * regclass.c (record_reg_classes, scan_one_insn): Likewise.
+
+ * regmove.c (find_matches): Likewise.
+
+ * reload.c (alternative_allows_memconst): Likewise.
+
+ * reload1.c (constraint_accepts_reg_p,
+ reload_cse_simplify_operands): Likewise.
+
+ * rtl.h (decode_asm_operands): Likewise.
+
+ * scan.h (fn_decl): Likewise.
+
+ * varasm.c (assemble_string): Likewise.
+
+Sat Jan 23 01:37:36 1999 Jeffrey A Law (law@cygnus.com)
+
+ * configure.in (gcc_tooldir): Handle case where exec_prefix has
+ not been explicitly set.
+ * configure: Rebuilt.
+
+ * fold-const.c (lshift_double): Mark 'prec' arguments as possibly
+ unused.
+
+ * bitmap.h (bitmap_head_def): Make indx field unsigned.
+
+ * configure.in (gcc_tooldir): When not making a relative gcc_tooldir,
+ use $exec_prefix/$target_alias for gcc_tooldir.
+ * configure: Rebuilt.
+
+Fri Jan 22 11:48:56 1999 Richard Henderson <rth@cygnus.com>
+
+ * cppp.c (xrealloc): Fix typo last change.
+ * cppalloc.c, gcc.c, genattr.c, genattrtab.c, gencodes.c: Likewise.
+ * genconfig.c, genemit.c, genextract.c, genflags.c: Likewise.
+ * genopinit.c, genoutput.c, genpeep.c, genrecog.c: Likewise.
+
+1999-01-22 Michael Meissner <meissner@cygnus.com>
+
+ * rs6000.h (CR0_REGNO_P): New macro to test if cr0.
+ (CR_REGNO_NOT_CR0_P): New macro to test if cr, but not cr0.
+ (PREDICATE_CODES): Add cc_reg_not_cr0_operand.
+ (cc_reg_not_cr0_operand): Add declaration.
+
+ * rs6000.c (cc_reg_not_cr0_operand): Return true if register is a
+ pseudo register, or a control register that is not CR0.
+
+ * rs6000.md (all combiner patterns building . instructions): For
+ all `.' instructions that do something and set cr0, add an
+ alternative that does the operation, and then sets a different
+ flag, in order to avoid using the costly mcrf instruction and also
+ allow cr0 to be clobbered in asm statements. Also fix a few
+ patterns that used the wrong register.
+
+ * rs6000.h (rs6000_cpu_select): Make string, names be const char *.
+ (rs6000_debug_name): Make const char *, not char *.
+
+ * sysv4.h (rs6000_{abi,sdata}_name): Make const char *.
+
+ * rs6000.c (rs6000_{debug,abi,sdata}_name): Make const char *.
+ (rs6000_select): Use const char * in casts.
+
+Fri Jan 22 07:43:01 1999 Jeffrey A Law (law@cygnus.com)
+
+ * Makefile.in (gcc_tooldir): Move before first reference.
+ Let autoconf substitute in a value.
+ * configure.in (gcc_tooldir): Only use a relative path to the
+ tool directory if $exec_prefix == $prefix.
+ * configure: Rebuilt.
+
+ * Makefile.in (tooldir): Replace with gcc_tooldir.
+
+Thu Jan 21 23:21:57 1999 Jeffrey A Law (law@cygnus.com)
+
+ * m68k.md (ashldi_const): Disable for !TARGET_5200. Fix indention.
+ (ashldi3 expander): Similarly. Update comments.
+ (ashrdi_const, lshrdi_const): Fix indention.
+ (ashrdi3, lshrdi3): FIx indention. Update comments.
+
+Thu Jan 21 21:53:36 1999 Richard Henderson <rth@cygnus.com>
+
+ * emit-rtl.c (try_split): Don't try to split non-instructions.
+
+Thu Jan 21 23:47:30 EST 1999 Andrew MacLeod <amacleod@cygnus.com>
+
+ * expr.c (emit_push_insn): Fix dumb typo.
+
+Thu Jan 21 20:24:02 1999 Richard Henderson <rth@cygnus.com>
+
+ * rs6000.h (LEGITIMIZE_RELOAD_ADDRESS): Recognize and accept
+ transformations that we have performed earlier.
+ * alpha.h (LEGITIMIZE_RELOAD_ADDRESS): Likewise.
+
+ * alpha.md (prologue_stack_probe_loop): Don't do our own label
+ handling, call gen_label_rtx instead.
+
+Thu Jan 21 17:45:18 1999 Richard Henderson <rth@cygnus.com>
+
+ * configure.in ({rs6000|powerpc}-ibm-aix4.[12]*): Add missing `then'.
+
+ * cccp.c (xrealloc): Call malloc given a NULL old pointer.
+ * collect2.c, cppalloc.c, gcc.c, genattr.c, genattrtab.c: Likewise.
+ * gencodes.c, genconfig.c, genemit.c, genextract.c: Likewise.
+ * genflags.c, genopinit.c, genoutput.c, genpeep.c: Likewise.
+ * genrecog.c, mips-tfile.c, protoize.c: Likewise.
+
+Thu Jan 21 19:44:55 1999 Michael Meissner <meissner@cygnus.com>
+
+ * configure.in ({rs6000|powerpc}-ibm-aix4.[12]*): If
+ --with-gnu-ld, use x-aix41-gld instead of x-aix41 to suppress
+ adding -Wl,-bbigtoc to BOOT_LDFLAGS.
+ * configure: Regenerate.
+
+ * config/rs6000/x-aix41-gld: New file, don't set BOOT_LDFLAGS.
+
+Thu Jan 21 15:48:03 1999 Dave Brolley <brolley@cygnus.com>
+
+ * cppexp.c (cpp_lex): Allocate token_buffer dynamically.
+
+Thu Jan 21 14:18:04 EST 1999 Andrew MacLeod <amacleod@cygnus.com>
+
+ * expr.c (MOVE_BY_PIECES_P): Define condition for deciding to use
+ move_by_pieces.
+ (MOVE_MAX_PIECES): Define maximum number of bytes to move at once.
+ (USE_LOAD_POST_INCREMENT, USE_LOAD_PRE_DECREMENT): Define defaults.
+ (USE_STORE_POST_INCREMENT, USE_STORE_PRE_DECREMENT): Define defaults.
+ (move_by_pieces): Use new macros.
+ (emit_block_move): Use new macros.
+ (clear_by_pieces): Use new macros.
+ (clear_storage): Use new macros.
+ (emit_push_insn): Use new macros.
+ (expand_expr): Use new macros.
+ * config/sh/sh.h (USE_LOAD_POST_INCREMENT, USE_LOAD_PRE_DECREMENT):
+ Define.
+ (USE_STORE_POST_INCREMENT, USE_STORE_PRE_DECREMENT): Define.
+ (MOVE_BY_PIECES_P): Define based on alignment and TARGET_SMALLCODE.
+ (MOVE_MAX_PIECES): move 8 bytes on SH4.
+ * tm.texi(MOVE_BY_PIECES_P, MOVE_MAX_PIECES, USE_LOAD_POST_INCREMENT,
+ USE_LOAD_PRE_DECREMENT, USE_STORE_POST_INCREMENT,
+ USE_STORE_PRE_DECREMENT): Describe new macros.
+
+Thu Jan 21 14:13:31 1999 Vladimir N. Makarov <vmakarov@cygnus.com>
+
+ * varasm.c (output_constant_pool): Use floor_log2 instead of
+ exact_log2 for ASM_OUTPUT_ALIGN.
+
+ * stor-layout.c (layout_type): Do machine-dependent extra alignment.
+
+ * emit-rtl.c (operand_subword): Handle case when a subword outside
+ the operand.
+
+ * tm.texi (ROUND_TYPE_{SIZE,ALIGN}): More accurate descriptions of
+ the macros.
+
+Thu Jan 21 01:59:30 1999 Richard Henderson <rth@cygnus.com>
+
+ * cse.c (fold_rtx): Revert 29 Dec change.
+ (cse_insn): Revert 12 Jan change.
+ * expr.c (expand_builtin): Don't emit CONST around CONSTANT_P_RTX.
+ * regclass.c (reg_scan_mark_refs): Revert 29 Dec change.
+ * rtl.def: Likewise.
+ * rtl.h (CONSTANT_P): Likewise.
+
+ * expr.c (emit_move_insn): Never try to flush CONSTANT_P_RTX
+ to memory.
+ * recog.c (immediate_operand): Accept CONSTANT_P_RTX.
+ * alpha.c (input_operand): Likewise.
+ * c4x.c (const_operand): Likewise.
+
+ * explow.c (allocate_dynamic_stack_space): Use register_operand
+ instead of arith_operand, which does not exist.
+
+ * 1750a.h: Fix comment closure.
+ * a29k.c (a29k_set_memflags): Fix typo in 19 Jan change.
+ * arc.md (one_cmplsi2_set_cc_insn): Fix set mode mismatch.
+ * arm.h (TARGET_SWITCHES): Fix typo.
+ * i370.md (anon mult and div patterns): Fix set mode mismatch.
+ * i860.c (output_delayed_branch): Fix operands to constrain_operands.
+ (output_delay_insn): Likewise.
+ * m88k.md (anon rotate insns): Fix set mode mismatch.
+ (anon BLKmode moves): Commonize and fix set mode mismatches.
+ * ns32k.md (udivmoddi[shq]i4_internal): Fix mode mismatch.
+ * romp.md (movdf): Fix typo.
+
+Thu Jan 21 00:29:35 1999 Nathan Sidwell <nathan@acm.org>
+
+ * Makefile.in (install-common): Remove extraneous chmod for gcov
+ install.
+
+Wed Jan 20 18:15:08 1999 Dave Brolley <brolley@cygnus.com>
+
+ * function.c (assign_parms): Save and restore setting of
+ TREE_USED (parm).
+
+Wed Jan 20 12:51:42 1999 Mark Mitchell <mark@markmitchell.com>
+
+ * arm.md: Use MEM_COPY_ATTRIBUTES where appropriate throughout.
+ Pass MEM_SCALAR_P to arm_gen_store_multiple where appropriate.
+
+Tue Jan 19 21:20:52 1999 Richard Henderson <rth@cygnus.com>
+
+ * recog.c (pop_operand): New function.
+ * recog.h (pop_operand): Declare it.
+ * genrecog.c (preds): Define it.
+
+ * expr.c (do_jump_for_compare): Handle conditional branch expanders
+ emitting multiple jump instructions.
+ * jump.c (condjump_label): New function.
+ * rtl.h (condjump_label): Declare it.
+
+Tue Jan 19 21:08:20 1999 Richard Henderson <rth@cygnus.com>
+
+ * expr.c (emit_move_insn_1): Revert 17 Dec change. Don't emit
+ clobber during or after reload.
+
+Tue Jan 19 16:56:03 1999 Richard Henderson <rth@cygnus.com>
+
+ * genoutput.c (name_for_index): New function.
+ (scan_operands, validate_insn_alternatives): Use it.
+ * genrecog.c (insn_name_ptr_size): New variable.
+ (make_insn_sequence): Fill in insn_name_ptr.
+ (merge_trees): Use it.
+
+Tue Jan 19 16:37:36 1999 Richard Henderson <rth@cygnus.com>
+
+ * i386/isc.h (TARGET_DEFAULT): Define symbolicly.
+ * i386/isccoff.h, i386/next.h, i386/sco.h, i386/sco5.h: Likewise.
+ * i386/scodbx.h, i386/sequent.h, i386.unix.h: Likewise.
+
+Tue Jan 19 15:00:10 1999 Jeffrey A Law (law@cygnus.com)
+
+ * loop.c (NUM_STORES): Delete.
+ (loop_store_mems): Turn into an EXPR_LIST of MEMs.
+ (prescan_loop): Properly initialize loop_mems_idx.
+ (note_addr_stored): Simplify using list structure instead of
+ fixed sized array.
+ (invariant_p, check_dbra_loop, load_mems): Similarly.
+
+ * flow.c (invalidate_from_autoinc): New function.
+ (mark_set_1, mark_used_regs): Use it.
+
+ * Makefile.in (protoize.o, unprotoize.o): Depend on Makefile.
+
+1999-01-19 Vladimir N. Makarov <vmakarov@cygnus.com>
+
+ * invoke.texi (-mlong-double-64): New option description.
+
+1999-01-19 Jim Wilson <wilson@cygnus.com>
+
+ * libgcc2.c: Change all uses of LONG_DOUBLE_TYPE_SIZE to
+ LIBGCC2_LONG_DOUBLE_TYPE_SIZE.
+ (LIBGCC2_LONG_DOUBLE_TYPE_SIZE): New. Set to LONG_DOUBLE_TYPE_SIZE
+ if not defined.
+ * i960/i960.h (MULTILIB_DEFAULTS): Define to mnumerics.
+ (CPP_SPECS): Add -mlong-double-64 support.
+ (TARGET_FLAG_LONG_DOUBLE_64, TARGET_LONG_DOUBLE_64): New.
+ (TARGET_SWITCHES): Add -mlong-double-64 support.
+ (LONG_DOUBLE_TYPE_SIZE): Likewise.
+ (LIBGCC2_LONG_DOUBLE_TYPE_SIZE): Define.
+ * i960/vx960-coff.h (MULTILIB_DEFAULTS): Define to msoft-float.
+ (CPP_SPECS): Add -mlong-double-64 support.
+ * i960/t-960bare (MULTILIB_OPTIONS): Add mlong-double-64.
+ (MULTILIB_DIRNAMES): Add ld64.
+ * i960/t-vxworks960 (MULTILIB_OPTIONS, MULTILIB_DIRNAMES): Likewise.
+
+Tue Jan 19 11:54:04 1999 Jason Merrill <jason@yorick.cygnus.com>
+
+ * calls.c (expand_call): Strip a TARGET_EXPR if we're passing by
+ invisible reference.
+
+Tue Jan 19 14:51:36 1999 David Edelsohn <edelsohn@gnu.org>
+
+ * rs6000.c (offsettable_addr_operand): Delete.
+ (offsettable_mem_operand): New function.
+ * rs6000.h (PREDICATE_CODES): Reflect function change.
+ (RS6000_SAVE_TOC): Represent address as MEM.
+ * win-nt.h (RS6000_SAVE_TOC): Same.
+ * rs6000.md (indirect calls): Change offsettable address parameter
+ to offsettable memory parameter.
+
+Tue Jan 19 10:24:53 1999 Mark Mitchell <mark@markmitchell.com>
+
+ * rtl.h (rtx_def): Update documentation.
+ (MEM_IN_STRUCT_P): Likewise.
+ (MEM_SCALAR_P): New macro.
+ (MEM_COPY_ATTRIBUTES): Likewise.
+ (MEM_SET_IN_STRUCT_P): Likewise.
+ * rtl.texi (MEM_SCALAR_P): Document.
+ * alias.c (canon_rtx): Use MEM_COPY_ATTRIBUTES.
+ (fixed_scalar_and_varying_struct_p): New function. Use
+ MEM_SCALAR_P rather than !MEM_IN_STRUCT_P.
+ (aliases_everything_p): Likewise.
+ (true_dependence): Use them.
+ (write_dependence_p): New function, containing code common to
+ anti_dependence and output_dependence.
+ (anti_dependence): Use it.
+ (output_dependence): Likewise.
+ * calls.c (save_fixed_argument_area): Don't clear
+ MEM_IN_STRUCT_P.
+ (expand_call): Use MEM_SET_IN_STRUCT_P.
+ (emit_library_call): Don't clear MEM_IN_STRUCT_P.
+ (emit_library_call_value): Likewise.
+ (store_one_arg): Use MEM_SET_IN_STRUCT_P.
+ * combine.c (simplify_rtx): Use MEM_COPY_ATTRIBUTES.
+ (make_extraction): Likewise.
+ (simplify_shift_const): Likewise.
+ (gen_lowpart_for_combine): Likewise.
+ * cse.c (gen_lowpart_if_possible): Use MEM_COPY_ATTRIBUTES.
+ * emit-rtl.c (operand_subword): Likewise.
+ (change_address): Likewise.
+ * explow.c (stabilize): Use MEM_COPY_ATTRIBUTES.
+ * expr.c (protect_from_queue): Use MEM_COPY_ATTRIBUTES.
+ (emit_group_store): Use MEM_SET_IN_STRUCT_P.
+ (copy_blkmode_from_reg): Likewise.
+ (store_field): Likewise.
+ (expand_expr): Remove bogus guesswork setting MEM_IN_STRUCT_P
+ heuristically. Use MEM_SET_IN_STRUCT_P.
+ (get_memory_rtx): Likewise.
+ * final.c (alter_subreg): Use MEM_COPY_ATTRIBUTES.
+ * function.c (assign_stack_temp): Clear MEM_SCALAR_P and
+ MEM_ALIAS_SET on newly returned MEMs.
+ (assign_temp): Use MEM_SET_IN_STRUCT_P.
+ (put_reg_into_stack): Likewise.
+ (fixup_var_refs1): Use MEM_COPY_ATTRIBUTES.
+ (gen_mem_addressof): Use MEM_SET_IN_STRUCT_P.
+ (assign_parms): Likewise.
+ (expand_function): Likewise.
+ * integrate.c (expand_inline_function): Likewise.
+ (copy_rtx_and_substitute): Use MEM_COPY_ATTRIBUTES.
+ * loop.c (note_addr_stored): Remove check on MEM_IN_STRUCT_P.
+ * optabs.c (gen_move_insn): Use MEM_COPY_ATTRIBUTES.
+ * print-rtl.c (print_rtx): Print /f for frame_related.
+ * recog.c (validate_replace_rtx_1): Use MEM_COPY_ATTRIBUTES.
+ * reload1.c (reload): Copy MEM_SCALAR_P as well.
+ * stmt.c (expand_decl): Use MEM_SET_IN_STRUCT_P.
+ (expand_anon_union_decl): Use MEM_COPY_ATTRIBUTES.
+ * varasm.c (make_decl_rtl): Use MEM_SET_IN_STRUCT_P.
+ (output_constant_def): Likewise.
+ * a29k.c (a29k_set_memflags_1): Take scalar_p.
+ Set MEM_SCALAR_P.
+ (a29k_set_memflags): Use it.
+ * alpha.c (get_aligned_mem): Use MEM_COPY_ATTRIBUTES.
+ * c4x.c (c4x_scan_for_ld): Likewise.
+ * h8300.c (fix_bit_operand): Likewise.
+ * m88k.c (legitimize_address): Likewise.
+ (block_move_loop): Likewise.
+ (block_move_no_loop): Likewise.
+ (block_move_sequence): Likewise.
+ (m88k_builtin_saveregs): Use MEM_SET_IN_STRUCT_P.
+ * mips/abi64.h (SETUP_INCOMING_VARARGS): Likewise.
+ * rs6000.c (expand_block_move_insn): Use MEM_COPY_ATTRIBUTES.
+ * sh.c (sh_builtin_saveregs): Use MEM_SET_IN_STRUCT_P.
+ * arm.h (arm_gen_load_multiple): Take scalar_p.
+ (arm_store_load_multiple): Likewise.
+ * arm.c (arm_gen_load_multiple): Likewise.
+ (arm_gen_store_multiple): Likewise.
+ (arm_gen_movstrqi): Treat MEM_SCALAR_P like MEM_IN_STRUCT_P.
+
+Tue Jan 19 12:30:37 EST 1999 Andrew MacLeod <amacleod@cygnus.com>
+
+ * optabs.c (emit_libcall_block): Add a REG_EH_REGION reg note to all
+ calls within a libcall block to indicate no throws are possible.
+ * flow.c (find_basic_blocks, find_basic_blocks_1): Don't look for
+ libcall blocks. Don't add edges to exception handlers if we see
+ a REG_EH_REGION note with a value of 0.
+ (make_edges): Override active_eh_region vector if the call has a note
+ indicating the call does not throw.
+
+1999-01-19 Vladimir N. Makarov <vmakarov@cygnus.com>
+
+ * config/rs6000/sysv4.h (CC1_SPEC): Fix correct numbers of {}.
+
+Tue Jan 19 06:26:30 1999 Jeffrey A Law (law@cygnus.com)
+
+ * Makefile.in (cccp.o, cpplib.o): Depend on Makefile.
+
+Mon Jan 18 09:56:41 1999 Jason Merrill <jason@yorick.cygnus.com>
+
+ * invoke.texi (C++ Dialect Options): Document -fno-rtti.
+
+1999-01-18 Vladimir N. Makarov <vmakarov@cygnus.com>
+
+ * invoke.texi (-mcpu=740, -mcpu=750): New options.
+ (-m(no-)multiple, -m(no-)string): Describe cases for PPC740 &
+ PPC750.
+
+1999-01-18 Michael Meissner <meissner@cygnus.com>
+
+ * rs6000.h ({ASM,CPP}_CPU_SPEC): Add support for all machines
+ supported with -mcpu=xxx.
+ (processor_type): Add PROCESSOR_PPC750.
+ (ADJUST_PRIORITY): Call rs6000_adjust_priority.
+ (RTX_COSTS): Supply costs for 750 multiply/divide operations.
+ (rs6000_adjust_priority): Add declaration.
+
+ * rs6000.c (rs6000_override_options): -mcpu={750,740} now sets the
+ processor type as 750, not 603. Allow -mmultiple and -mstring on
+ little endian 750 systems.
+ (rs6000_adjust_priority): Stub for now.
+ (get_issue_rate): The PowerPC 750 can issue 2 instructions/cycle.
+
+ * rs6000.md (function/cpu attributes): Add initial ppc750 support.
+
+ * sysv4.h (STRICT_ALIGNMENT): Don't force strict alignment if
+ little endian.
+ (CC1_SPEC): Pass -mstrict-align if little endian, and not
+ overridden.
+ (CC1_ENDIAN_{LITTLE,BIG,DEFAULT}_SPEC): Endian specific configs.
+ (SUBTARGET_EXTRA_SPECS): Add cc1 endian specs.
+
+ * {sysv4,eabi}le.h (CC1_ENDIAN_DEFAULT_SPEC): Override, default is
+ little endian.
+
+ * t-ppcgas (MULTILIB_*): Delete obsolete Solaris multilibs.
+
+Mon Jan 18 12:03:08 1999 Gavin Romig-Koch <gavin@cygnus.com>
+
+ * config/mips/mips.md (div_trap): Split div_trap_mips16
+ from div_trap.
+ (div_trap_normal,div_trap_mips16): Correct the length attributes.
+
+Mon Jan 18 11:48:28 1999 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * cpplib.c (special_symbol): Qualify a char* with the `const' keyword.
+ Instead of writing to const char *buf directly, use a non-const
+ variable `wbuf' to allocate and write a string, then set buf = wbuf.
+
+ * cppulp.c (user_label_prefix): Qualify a char* with the `const'
+ keyword.
+
+ * dyn-string.c (dyn_string_append): Likewise.
+
+ * dyn-string.h (dyn_string_append): Likewise.
+
+ * final.c (end_final, output_operand_lossage, asm_fprintf): Likewise.
+
+ * output.h (end_final, output_operand_lossage, asm_fprintf,
+ named_section, decode_reg_name, make_decl_rtl, user_label_prefix):
+ Likewise.
+
+ * profile.c (init_branch_prob): Likewise.
+
+ * toplev.c (set_target_switch, vmessage,
+ v_message_with_file_and_line, v_message_with_decl,
+ v_error_with_file_and_line, v_error_with_decl, v_error_for_asm,
+ verror, vfatal, v_warning_with_file_and_line, v_warning_with_decl,
+ v_warning_for_asm, vwarning, vpedwarn, v_pedwarn_with_decl,
+ v_pedwarn_with_file_and_line, vsorry, v_really_sorry,
+ open_dump_file, dump_rtl, clean_dump_file,
+ print_version, print_single_switch, print_switch_values,
+ dump_base_name, debug_args, lang_independent_options,
+ user_label_prefix, documented_lang_options, target_switches,
+ target_options, print_time, pfatal_with_name, fatal_io_error,
+ fatal_insn, default_print_error_function, print_error_function,
+ report_error_function, error_with_file_and_line, error_with_decl,
+ error_for_asm, error, fatal, warning_with_file_and_line,
+ warning_with_decl, warning_for_asm, warning, pedwarn,
+ pedwarn_with_decl, pedwarn_with_file_and_line, sorry,
+ really_sorry, botch, output_quoted_string, output_file_directive,
+ open_dump_file, rest_of_decl_compilation, display_help, main):
+ Likewise.
+
+ * toplev.h (print_time, fatal, fatal_io_error, pfatal_with_name,
+ fatal_insn, warning, error, pedwarn, pedwarn_with_file_and_line,
+ warning_with_file_and_line, error_with_file_and_line, sorry,
+ really_sorry, default_print_error_function, report_error_function,
+ rest_of_decl_compilation, pedwarn_with_decl, warning_with_decl,
+ error_with_decl, error_for_asm, warning_for_asm, output_quoted_string,
+ output_file_directive, botch): Likewise.
+
+ * tree.h (make_decl_rtl): Likewise.
+
+ * varasm.c (strip_reg_name, named_section, decode_reg_name,
+ make_decl_rtl): Likewise.
+
+Mon Jan 18 11:35:49 1999 Gavin Romig-Koch <gavin@cygnus.com>
+
+ * Makefile.in (TCL_LIBRARY): Use 'cd' to find the library
+ directory logically rather than physically.
+
+Mon Jan 18 09:05:37 1999 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * loop.c (insert_bct): Hide the definition of variables
+ `increment_direction', `compare_direction', `add_iteration' and
+ `loop_var_mode'.
+
+ * recog.c (mode_dependent_address_p): Mark parameter `addr' with
+ ATTRIBUTE_UNUSED. Mark label `win' with ATTRIBUTE_UNUSED_LABEL.
+ (mode_independent_operand): Mark label `lose' with
+ ATTRIBUTE_UNUSED_LABEL.
+
+ * regclass.c (n_occurrences): Remove prototype and definition.
+
+ * reload.c (find_reloads_address_1): Mark variable `tem' with
+ ATTRIBUTE_UNUSED.
+
+ * reload1.c (reload): Cast the first two arguments of `bcopy' to PTR.
+
+ * sbitmap.c (sbitmap_copy): Likewise.
+
+ * scan-decls.c (scan_decls): Hide label `handle_comma'.
+
+ * toplev.c (output_lang_identify): Mark prototype with
+ ATTRIBUTE_UNUSED.
+
+ * tree.c (make_node): Cast the first argument of `bzero' to PTR.
+ (make_tree_vec): Likewise.
+ (build1): Likewise.
+
+ * varasm.c (assemble_static_space): Mark variable `tem' with
+ ATTRIBUTE_UNUSED.
+
+Mon Jan 18 04:28:36 1999 Nathan Sidwell <nathan@acm.org>
+
+ * Makefile.in (GCOV_INSTALL_NAME): New macro.
+ (install-common): Use it.
+ (uninstall): Use it.
+ (uninstall): Use correct names for protoize and unprotoize.
+
+Mon Jan 18 03:52:56 1999 Christian Bruel <Christian.Bruel@st.com>
+ Jeffrey A Law (law@cygnus.com)
+
+ * flow.c (last_mem_set): Delete variable. References removed.
+ (mem_set_list): New variable.
+ (life_analysis): Initialize and finalize alias analysis.
+ (propagate_block); Initialize mem_set_list. Clear for CALL_INSNs.
+ (insn_dead_p): For a store to memory, search the entire mem_set_list
+ for a match.
+ (mark_set_1): Kill entries on the mem_set_list for aliased writes or
+ changes to their addresses. Add new entries to the mem_set_list for
+ memory writes writes.
+ (mark_used_regs): Kill entries on the mem_set_list which may be
+ referenced by a load operation.
+
+Mon Jan 18 01:01:02 1999 Jeffrey A Law (law@cygnus.com)
+
+ * alias.c (base_alias_check): Add missing return for differing
+ symbols case.
+
+Mon Jan 18 00:36:13 1999 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * mips-tdump.c (print_file_desc): Handle unknown filenames and
+ missing local symbols.
+
+Sun Jan 17 21:04:31 1999 Richard Henderson <rth@cygnus.com>
+
+ * jump.c (rtx_renumbered_equal_p): Special case CODE_LABEL.
+
+ * system.h (bcopy): Implement with memmove not memcpy.
+
+Sun Jan 17 19:23:20 1999 Jeffrey A Law (law@cygnus.com)
+
+ * Makefile.in (cppulp.o): Add dependencies.
+
+ * i386.md (integer conditional moves): Add missing earlyclobbers.
+
+ * regmove.c (optimize_reg_copy_1): Undo Aug 18 change. Update
+ REG_N_CALLS_CROSSED and REG_LIVE_LENGH if and only if we change
+ where a register is live.
+
+Sun Jan 17 03:20:47 1999 H.J. Lu (hjl@gnu.org)
+
+ * reg-stack.c (subst_stack_regs_pat): Abort if the destination
+ of a FP conditional move is not on the FP register stack.
+
+Sun Jan 17 01:15:04 PST 1999 Jeff Law (law@cygnus.com)
+
+ * version.c: Bump for snapshot.
+
+Sat Jan 16 23:40:33 1999 Jeffrey A Law (law@cygnus.com)
+
+ * reload1.c (reload_cse_regs_1): Do not call
+ reload_cse_simplify_operands for an insn with asm operands.
+
+ * cccp.c (print_help): Fix typos.
+ * cpplib.c (print_help): Fix typos.
+ * toplev.c (f_optiosn): Fix typos.
+ (documented_lang_options): Fix typos.
+
+Sat Jan 16 21:48:17 1999 Marc Espie (Marc.Espie@openbsd.org)
+
+ * gcc.c: (do_spec_1): Fix obvious typo.
+
+Sat Jan 16 19:31:07 1999 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * c-decl.c (duplicate_decls): If `warn_traditional', warn when
+ a non-static function declaration follows a static one.
+
+ * invoke.texi (-Wtraditional): Document the extra check now done
+ by this flag.
+
+Sat Jan 16 15:13:46 1999 Jeffrey A Law (law@cygnus.com)
+
+ * pa.md (shadd): Create shadd insns, even if the result of the shift is
+ needed without the addition.
+
+Sat Jan 16 10:48:16 1999 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * sh.md (movdf, movsf): Temporary workaround for no_new_pseudos lossage.
+
+Fri Jan 15 23:44:37 1999 Richard Henderson <rth@cygnus.com>
+
+ * sparc.c (sparc_issue): Add hypersparc/sparclite86x entries.
+
+Fri Jan 15 22:30:04 1999 David Edelsohn <edelsohn@gnu.org>
+
+ * rs6000.h (CONST_OK_FOR_LETTER_P): Do not assume 32-bit CONST_INT.
+ * rs6000.c (u_short_cint_operand, add_operand, logical_operand,
+ non_add_cint_operand, non_logical_cint_operand): Likewise.
+ (get_issue_rate): Add CPU_PPC604E case.
+ * rs6000.md (movdi, !TARGET_POWERPC64 splitters): Handle 64-bit hosts.
+
+Fri Jan 15 18:42:12 1999 Richard Henderson <rth@cygnus.com>
+
+ * expr.c (queued_subexp_p): Make public.
+ * expr.h (queued_subexp_p): Declare it.
+ * recog.c (asm_operand_ok): New function.
+ (check_asm_operands): Use it. After reload, use constrain_operands
+ instead.
+ * recog.h (asm_operand_ok): Declare it.
+ * stmt.c (expand_asm_operands): Use it to try harder to make
+ asms initially satisfy their constraints.
+
+Fri Jan 15 17:43:59 1999 Jeffrey A. Law <law@rtl.cygnus.com>
+
+ * sparc.h (LEGITIMIZE_RELOAD_ADDRESS): Do not create
+ (mem (lo_sum (...)) for TFmode unless TARGET_V9.
+
+Sat Jan 16 12:47:15 1999 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
+
+ * config/c4x/c4x.md (not_repeat_reg): Allow ldp instruction
+ in delay slot of RPTBD.
+
+Sat Jan 16 12:26:40 1999 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
+
+ * config/c4x/libgcc.S (___divhi3, ___modhi3): Fix long long
+ divide and modulo sign problem.
+
+Fri Jan 15 11:02:31 1999 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
+
+ * unroll.c (loop_iterations): Return 0 if the last loop insn
+ is not a jump insn or if the loop has multiple back edges.
+
+1999-01-15 Manfred Hollstein <manfred@s-direktnet.de>
+
+ * configure.in (fixinc_defs): Do not define for m[68]8k-motorola-sysv{,3};
+ it's working properly now. Remove comment saying "see m68k-motorola-sysv
+ as an example".
+ * configure: Regenerate using autoconf.
+
+ * fixinc/fixincl.c (main): Do not ignore SIGCHLD.
+
+Thu Jan 14 22:38:41 1999 Jeffrey A Law (law@cygnus.com)
+
+ * unroll.c (find_splittable_givs): For a DEST_ADDR giv, do not share
+ a register with another DEST_ADDR giv if the address is not valid.
+
+ * pa.c (hppa_expand_epilogue): Save and restore the static chain
+ around the call to mcount.
+
+ * h8300.h (ASM_OUTPUT_LABELREF): Use asm_fprintf, not fprintf.
+
+ * stmt.c (expand_end_case): Use emit_cmp_and_jump_insns to avoid
+ generating non-canonical rtl.
+
+1999-01-14 Vladimir N. Makarov <vmakarov@cygnus.com>
+
+ * config/i960/i960.c (i960_output_move_double_zero,
+ i960_output_move_quad_zero): New functions for moving zeros.
+ (i960_output_move_double, i960_output_move_quad): Additional code
+ for situation when moving unaligned register group.
+
+ * config/i960/i960.h (i960_output_move_double_zero,
+ i960_output_move_quad_zero): The function definitions.
+
+ * config/i960/i960.md (movdi+1, movti+1): Usage of the functions.
+
+1999-01-13 Vladimir N. Makarov <vmakarov@cygnus.com>
+
+ * config/i960/i960.c (i960_function_prologue): New code (optimal
+ solution) for saving global registers in local registers.
+ (form_reg_groups, reg_group_compare, split_reg_group): New
+ functions used by the code.
+ (reg_group): New structure definition for the new code.
+
+1999-01-13 Manfred Hollstein <manfred@s-direktnet.de>
+
+ * fixinc/fixincl.c (create_file): Pass file creation mask as
+ third parameter to "open". Use O_TRUNC flag to open instead of
+ explicitly unlink'ing the file.
+ (process): and forget about the "chmod" stuff.
+
+Wed Jan 13 20:12:37 1999 Richard Henderson <rth@cygnus.com>
+
+ * integrate.c (expand_inline_function): Recognize (mem (addressof))
+ and substitute. Copy the return value from there into a new pseudo.
+
+Wed Jan 13 16:47:00 1999 Catherine Moore <clm@cygnus.com>
+
+ * config/arm.c (output_func_epilogue): Check TARGET_ABORT_NORETURN
+ before generating a call to abort for volatile functions.
+ * config/arm.h (ARM_FLAG_ABORT_NORETURN): Define.
+ (TARGET_ABORT_NORETURN): Define.
+ (abort-on-noreturn): New option.
+
+Thu Jan 14 13:52:42 1999 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
+
+ * config/c4x/c4x.md (in_annul_slot_3): Correctly allow unarycc
+ and binarycc operations in 3rd annulled delay slot!
+
+Wed Jan 13 16:16:44 1999 Catherine Moore <clm@cygnus.com>
+
+ * config/arm.c (output_func_epilogue): Check TARGET_ABORT_NORETURN
+ before generating a call to abort for volatile functions.
+ * config/arm.h (ARM_FLAG_ABORT_NORETURN): Define.
+ (TARGET_ABORT_NORETURN): Define.
+ (abort-on-noreturn): New option.
+
+Wed Jan 13 13:30:08 1999 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * cccp.c (xstrdup): Renamed from `savestring'. All callers changed.
+ Remove prototype which we get from libiberty.h.
+
+ * collect2.c (xstrdup): Likewise.
+
+ * genextract.c (xstrdup): Likewise for `copystr'.
+ (mybzero): Remove it and use `memset' instead.
+
+ * genoutput.c (mybcopy, mybzero): Remove these. All callers changed
+ to use `memcpy' and `memset' instead.
+
+ * genrecog.c (xstrdup): Renamed from `copystr'. All callers
+ changed. Remove prototype.
+ (mybcopy, mybzero): Remove these and use memcpy/memset.
+
+Wed Jan 13 00:59:04 1999 Jeffrey A Law (law@cygnus.com)
+
+ * mips.h (LOAD_EXTEND_OP): Correct for SImode and CCmode moves when
+ generating code for TARGET_64BIT.
+
+Tue Jan 12 14:05:37 1999 David Edelsohn <edelsohn@gnu.org>
+
+ * rs6000.c (print_operand, cases 'm' and 'M'): Do not depend on
+ HOST_WIDE_INT word-size.
+ (rs6000_stack_info): Remove redundant alignment of fpmem.
+
+Tue Jan 12 14:05:37 1999 Richard Henderson <rth@cygnus.com>
+
+ * rs6000.c (short_cint_operand): Remove CONSTANT_P_RTX handling.
+ (u_short_cint_operand, reg_or_cint_operand, logical_operand): Likewise.
+ (input_operand): Adjust CONSTANT_P_RTX handling.
+ * rs6000.h (PREDICATE_CODES): Remove CONSTANT_P_RTX references.
+ * rs6000.md (movsi): Adjust CONSTANT_P_RTX handling.
+ (movhi, movqi): Remove CONSANT_P_RTX handling.
+ (movdi): Adjust CONSTANT_P_RTX handling.
+
+1999-01-12 Manfred Hollstein <manfred@s-direktnet.de>
+
+ * configure: Regenerate using autoconf.
+
+ * fixinc/Makefile.in (INCLUDES): Add -I$(srcdir)/../../include.
+ * fixinc/fixincl.c (SIGCHLD): Use SIGCLD on (very) old systems.
+ (process): "fchmod" isn't available on all systems, use "chmod"
+ instead.
+ * fixinc/server.c: Add #include <sys/types.h>.
+ (STDIN_FILENO): Add default definition if no include file defines
+ it already.
+ (STDOUT_FILENO): Likewise.
+
+Tue Jan 12 10:23:24 1999 Stan Cox <scox@cygnus.com>
+
+ * mips.md (call_value_internal3c): New pattern for -mips16 -mlong-calls.
+
+1999-01-12 Manfred Hollstein <manfred@s-direktnet.de>
+
+ * m68k/mot3300.h (ADD_MISSING_POSIX, ADD_MISSING_XOPEN): Define to
+ ensure all prototypes necessary for building libio will be available.
+ * m68k/xm-mot3300.h (ADD_MISSING_POSIX, ADD_MISSING_XOPEN): Remove
+ definitions here as they are not host specific.
+ * m88k/sysv3.h, m88k/xm-sysv3.h: Likewise.
+
+Tue Jan 12 02:53:46 1999 Richard Henderson <rth@cygnus.com>
+
+ * cse.c (cse_insn): Never prefer (const (constant_p_rtx)).
+
+Tue Jan 12 02:36:10 PST 1999 Jeff Law (law@cygnus.com)
+
+ * version.c: Bump for snapshot.
+
+Tue Jan 12 01:30:19 1999 Richard Henderson <rth@cygnus.com>
+
+ * rtl.c (rtx_alloc): Use memset instead of inline loop.
+
+ * recog.h (recog_op_alt): Declare extern.
+
+Tue Jan 12 00:23:31 1999 Richard Henderson <rth@cygnus.com>
+
+ * function.c (purge_addressof_1): If the note accesses a mem+addressof
+ in a wider mode than any replacement, adjust the cached replacement.
+ Cache trivial substitutions as well.
+
+Tue Jan 12 00:06:00 1999 Richard Henderson <rth@cygnus.com>
+
+ * Makefile.in (OBJECTS): Add sbitmap.o.
+ (BASIC_BLOCK_H): Add sbitmap.h.
+ * basic-block.h: Move simple bitmap code to sbitmap.h.
+ * flow.c: Move simple bitmap code to sbitmap.c
+ * sbitmap.h, sbitmap.c: New files.
+
+Mon Jan 11 23:51:50 1999 Richard Henderson <rth@cygnus.com>
+
+ * alpha.h (TARGET_SWITCHES): Document switches.
+ (TARGET_OPTIONS): Likewise.
+
+ * alpha/elf.h (ASM_FINISH_DECLARE_OBJECT): Use HOST_WIDE_INT_PRINT_DEC.
+
+Mon Jan 11 22:54:14 1999 Richard Henderson <rth@cygnus.com>
+
+ * tree.c (new_alias_set): Return zero if !flag_strict_aliasing.
+
+Mon Jan 11 22:36:01 1999 Richard Henderson <rth@cygnus.com>
+
+ * basic-block.h (basic_block_head): Rename to x_basic_block_head.
+ (basic_block_end): Rename to x_basic_block_end.
+ (BLOCK_HEAD, BLOCK_END): Update.
+
+ * caller-save.c: Change basic_block_head/end references to
+ BLOCK_HEAD/END.
+ * combine.c, flow.c, function.c, gcse.c, global.c: Likewise.
+ * graph.c, haifa-sched.c, local-alloc.c, regclass.c: Likewise.
+ * regmove.c, reload1.c, reorg.c, sched.c: Likewise.
+
+Sat Jan 9 23:54:09 1999 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * gcc.c (xstrerror): Renamed from my_strerror. All callers
+ changed. Remove prototype since we get that from libiberty.h.
+
+ * protoize.c (xstrerror): Likewise.
+
+Sat Jan 9 23:22:04 1999 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * gcc.c (read_specs): Ensure format specifiers match their arguments.
+
+Sat Jan 9 20:04:24 1999 Richard Henderson <rth@cygnus.com>
+
+ * tree.c (copy_node): Oops. That would be copy not zero
+ in that last change.
+
+Sun Jan 10 15:35:41 1999 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
+
+ * config/c4x/c4x.c: Include system.h.
+ (c4x_caller_save_map): Disable caller save for RC.
+ (c4x_optimization_options): Disable scheduling before reload.
+ (valid_parallel_load_store) : Define return type as int.
+ Remove unused variable regs.
+ * config/c4x/c4x.h (REGISTER_MOVE_COST): Make independent of register
+ class.
+ * config/c4x/c4x.md (rotlqi3, rotrqi3): Fix up emitted RTL to
+ handle rotations.
+ (*db, decrement_and_branch_until_zero): Fix up constraints
+ to keep reload happy.
+
+Sat Jan 9 18:35:29 1999 Richard Henderson <rth@cygnus.com>
+
+ * tree.c (make_node): Call bzero instead of inline clear.
+ (copy_node, make_tree_vec, build1): Likewise.
+ (get_identifier): Call strlen instead of inline count.
+ (maybe_get_identifier): Likewise.
+
+Sun Jan 10 14:04:51 1999 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
+
+ * config/c4x/c4x.md: (in_annul_slot_3): Allow unarycc and binarycc
+ operations in 3rd annulled delay slot.
+ (*lshrqi3_const_set): Disallow c constraint for operand0.
+ (modhi3+1, modhi3+2): Set attribute type to multi.
+ * config/c4x/c4x.c (c4x_S_constraint): Removed space in middle of
+ != operator.
+
+Sat Jan 9 11:44:55 1999 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * gansidecl.h: Allow attribute unused on labels only when we are
+ version 2.93 or higher. Not all versions of 2.92 have this feature.
+
+ * version.c: Bump minor number to 93.
+
+Fri Jan 8 10:51:13 1999 Andreas Schwab <schwab@issan.cs.uni-dortmund.de>
+
+ * config/m68k/m68k.h: Declare output_function_epilogue.
+ * recog.h: Declare next_insn_tests_no_inequality.
+
+Fri Jan 8 01:43:53 1999 Jeffrey A Law (law@cygnus.com)
+
+ * stmt.c (optimize_tail_recursion): New function, extracted from ...
+ (expand_return): Use optimize_tail_recursion.
+ * tree.h (optimize_tail_recursion): Declare.
+
+ * toplev.c (compile_file): Move call to output_func_start_profiler
+ to after the loop to emit deferred functions.
+
+Thu Jan 7 19:52:53 1999 Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at>
+
+ * system.h (abort): Supply more detailed information on how to
+ report an Internal Compiler Error.
+
+Thu Jan 7 9:25:58 PST 1999 Bruce Korb (korb@datadesign.com)
+
+ * fixinc/fixincl.c (*): more decapitalization of variables
+ plus some explanitory comments
+
+ * fixinc/Makefile.in fixinc/mkfixinc.sh:
+ When the fixincl program does not work for a certain system,
+ we substitute a shell script. Added user commentary when
+ this happens.
+
+Thu Jan 7 11:26:17 1999 Mark Mitchell <mark@markmitchell.com>
+
+ * calls.c (store_unaligned_arguments_into_pseudos): Use xmalloc to
+ allocate memory that will live beyond this function.
+ (expand_call): Free it here.
+
+Thu Jan 7 03:08:17 1999 Richard Henderson <rth@cygnus.com>
+
+ * sparc.h (PREFERRED_RELOAD_CLASS): Select GENERAL_REGS for
+ integer data not destined for fp regs.
+ (LEGITIMIZE_RELOAD_ADDRESS): New.
+
+Thu Jan 7 03:03:42 1999 Stan Cox <scox@cygnus.com>
+ Richard Henderson <rth@cygnus.com>
+
+ Support for Hypersparc and Sparclite86x:
+ * sparc.h (TARGET_CPU_hypersparc, TARGET_CPU_sparclite86x): New.
+ (CPP_CPU32_DEFAULT_SPEC): Fix up for the new targets.
+ (ASM_CPU32_DEFAULT_SPEC): Likewise.
+ (TARGET_CPU_DEFAULT): Likewise.
+ (enum processor_type): Likewise.
+ (CPP_ENDIAN_SPEC): Handle little endian data.
+ (LIBGCC2_WORDS_BIG_ENDIAN): Likewise.
+ (ADJUST_COST): Call sparc_adjust_cost.
+ * sparc.c (sparc_override_options): Fix up for the new targets.
+ (supersparc_adjust_cost): Make static.
+ (hypersparc_adjust_cost): New.
+ (ultrasparc_adjust_cost): Make static.
+ (sparc_adjust_cost): New.
+ * sparc.md (attr cpu): Add hypersparc and sparclite86x.
+ (function_unit): Add hypersparc scheduling rules.
+
+ * configure.in (with_cpu handler): Recognize hypersparc.
+
+Thu Jan 7 23:54:05 1999 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
+
+ * config/c4x/c4x.c: Added space after negation operator.
+ * config/c4x/c4x.h: Likewise.
+ * config/c4x/c4x.md: Likewise.
+
+Thu Jan 7 23:39:27 1999 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
+
+ * config/c4x/c4x.c (c4x_preferred_reload_class): Always return class.
+
+Thu Jan 7 00:29:25 199 Bernd Schmidt <crux@pool.informatik.rwth-aachen.de>
+
+ * combine.c (num_sign_bit_copies): In NEG, MULT, DIV and MOD cases,
+ when a test can't be performed due to limited width of
+ HOST_BITS_PER_WIDE_INT, use the more conservative approximation.
+ Fix UDIV case for cases where the first operand has the highest bit
+ set.
+
+Thu Jan 7 00:01:38 1999 Lutz Vieweg <lkv@mania.robin.de>
+
+ * pa.h (reg_class): Add FPUPPER_REGS.
+ (REG_CLASS_NAMES): Similarly.
+ (REG_CLASS_CONTENTS): Similarly
+ (REGNO_REG_CLASS): Handle FPUPPER_REGS.
+ (FP_REG_CLASS_P): Likewise.
+ (REG_CLASS_FROM_LETTER): Similarly.
+ (CLASS_MAX_NREGS): Similarly.
+
+1999-01-06 Brendan Kehoe <brendan@cygnus.com>
+
+ * fixincludes: For HP/UX 10.20, also look in curses_colr/curses.h
+ for a typedef of bool. Make sure to have a copy of the file is
+ in place before we look to fix it. Fix typo in variable name to
+ FILE.
+
+Wed Jan 6 07:51:05 1999 Richard Henderson <rth@cygnus.com>
+
+ * expr.c (expand_builtin) [case BUILT_IN_CONSTANT_P]: Use
+ value_mode for the return mode.
+
+Wed Jan 6 17:55:19 1999 Robert Lipe <robertlipe@usa.net>
+
+ * configure.in: New flag --with-dwarf2. If set, enables DWARF-2
+ debugging as default.
+
+ * config/tm-dwarf2.h: New file.
+
+Wed Jan 6 16:08:54 1999 Jeffrey A Law (law@cygnus.com)
+
+ * h8300.h (ASM_OUTPUT_LABELREF): Define.
+
+ * pa.h (DONT_RECORD_EQUIVALENCE): Kill.
+ * local-alloc.c (update_equiv_regs): Corresponding changes.
+ * tm.texi (DONT_RECORD_EQUIVALENCE): Kill.
+
+ * calls.c (special_function_p): Push alloca test inside the large
+ conditional which excludes functions not at file scope or not
+ extern.
+
+ * calls.c (special_function_p): New function broken out of
+ expand_call.
+ (precompute_register_parameters): Likewise.
+ (store_one_arg): Likewise.
+ (store_unaligned_argumetns_into_pseudos): Likewise.
+ (save_fixed_argument_area): Likewise.
+ (restore_fixed_argument_area): Likewise.
+ (expand_call): Corresponding changes.
+
+Thu Jan 7 00:12:24 1999 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
+
+ * config/c4x/c4x.md (addqi3): If the destination operand is
+ a hard register other than an extended precision register,
+ emit addqi3_noclobber.
+ (*addqi3_noclobber_reload): New pattern added so that reload
+ will recognise a store of a pseudo, equivalent to the sum
+ of the frame pointer and a constant, as an add insn.
+
+1999-01-06 Manfred Hollstein <manfred@s-direktnet.de>
+
+ * fixinc/fixincl.c: Re-indent according to the GNU standards.
+ fixinc/server.c: Likewise.
+ fixinc/server.h: Likewise.
+
+Wed Jan 6 10:43:29 1999 Andreas Schwab <schwab@issan.cs.uni-dortmund.de>
+
+ * config/m68k/m68k.c (const_uint32_operand): Remove CONSTANT_P_RTX
+ handling.
+ (const_sint32_operand): Likewise.
+
+Wed Jan 6 09:44:51 1999 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * toplev.h: In addition to checking _JBLEN, also check if `setjmp'
+ is a macro when deciding if we can use `jmp_buf' in prototypes.
+
+Wed Jan 6 03:18:53 1999 Mark Elbrecht <snowball3@usa.net>
+
+ * configure.in (pc-msdosdjgpp): Set x_make to x-go32.
+ * configure: Rebuilt.
+ * i386/xm-go32.h: Define LIBSTDCXX.
+ * i386/x-go32: New.
+ * i386/go32.h (MD_EXEC_PREFIX): Define.
+ (FILE_NAME_ABSOLUTE_P): Define.
+ (LINK_COMMAND_SPEC): Define.
+
+Wed Jan 6 02:23:36 1999 "Charles M. Hannum" <root@ihack.net>
+
+ * expr.c (store_expr): If the lhs is a memory location pointed
+ to be a postincremented (or postdecremented) pointer, always
+ force the rhs to be evaluated into a pseudo.
+
+Wed Jan 6 00:54:21 1999 Geoff Keating <geoffk@ozemail.com.au>
+
+ * real.c (mtherr): Print more reasonable warning messages.
+
+Tue Jan 5 21:57:42 1999 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * Makefile.in (gcc.o, prefix.o, cccp.o, cpplib.o): Depend on prefix.h.
+
+ * cccp.c: Include prefix.h, don't prototype prefix.c functions.
+ (new_include_prefix): Constify char* parameters.
+
+ * cppfiles.c (read_name_map): Likewise.
+ (append_include_chain): Likewise. Also, use a writable char* copy
+ of parameter `dir' which we then modify, rather than using the
+ parameter itself to store the new writable string.
+ (remap_filename): Constify some variables. Also, use a writable
+ char* to store an allocated string which we will be modifying.
+
+ * cpplib.c: Include prefix.h, don't prototype prefix.c functions.
+ (cpp_start_read): Constify variable `str'.
+
+ * cpplib.h (append_include_chain): Constify a char* parameter.
+
+ * gcc.c Include prefix.h, don't prototype prefix.c functions.
+ (add_prefix, save_string): Constify char* parameters.
+ (fatal, error): Add ATTRIBUTE_PRINTF_1 to prototypes.
+
+ * prefix.c: Include prefix.h.
+ (get_key_value, translate_name, save_string, update_path,
+ set_std_prefix): Constify various char* parameters and variables.
+ (save_string): Use xmalloc, not malloc.
+ (translate_name): Use a writable temporary variable to create and
+ modify a string before setting it to a const char*.
+
+ * prefix.h: New file to prototype functions exported from prefix.c.
+
+Tue Jan 5 8:52:18 PST 1999 Bruce Korb (korb@datadesign.com)
+
+ * fixinc/fixincl.c (various): added debug code so
+ Manfred can trace the processing.
+
+ * fixinc/inclhack.def (sys/utsname.h): Provide forward declaration of
+ struct utsname on Ultrix V4.[35].
+
+ * fixinc/{fixincl.x|fixincl.sh|inclhack.sh} : regenerated
+
+Mon Jan 4 15:37:30 1999 Zack Weinberg <zack@rabi.phys.columbia.edu>
+
+ * cpplib.c (skip_if_group): Split out the logic that handles
+ directive recognition to its own function. Don't use
+ parse markers; use a bare pointer into the buffer. Use
+ copy/skip_rest_of_line instead of doing it by hand. Remove
+ `return on any directive' mode which was never used, and take
+ only one argument.
+ (consider_directive_while_skipping): New function, subroutine
+ of skip_if_group. Logic streamlined a bit.
+ (conditional_skip, do_elif, do_else): Call skip_if_group with
+ only one argument.
+
+Mon Jan 4 15:27:30 1999 Zack Weinberg <zack@rabi.phys.columbia.edu>
+
+ * cpplib.c (do_undef): EOF immediately after '#undef FOO' is not an
+ error.
+
+Mon Jan 4 11:55:51 1999 Jason Merrill <jason@yorick.cygnus.com>
+
+ * extend.texi (Bound member functions): Document.
+
+Mon Jan 4 11:01:48 1999 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * mips-tdump.c (st_to_string, sc_to_string, glevel_to_string,
+ lang_to_string, type_to_string): Make return type const char*.
+ (print_symbol): Apply `const' keyword to a char*.
+ (print_file_desc): Cast structure member `crfd' to ulong when
+ comparing against one.
+
+ * mips-tfile.c (pfatal_with_name): Apply `const' keyword to char*.
+ (fatal, error): Add ATTRIBUTE_PRINTF_1 to prototypes.
+ (progname, input_name): Apply `const' keyword to a char*.
+ Don't redundantly include sys/stat.h.
+ (alloc_info): Apply `const' keyword to a char*.
+ (st_to_string, sc_to_string): Likewise.
+ (hash_string): Cast variable `hash_string' to a symint_t when
+ comparing against one.
+ (add_string): Cast PAGE_USIZE to Ptrdiff_t when comparing against one.
+ Likewise cast it to long when comparing against one.
+ (add_local_symbol): Apply `const' keyword to a char*.
+ (add_ext_symbol): Likewise.
+ (add_unknown_tag): Likewise.
+ (add_procedure): Cast a printf-style field width to an int.
+ (add_file): Cast PAGE_USIZE to long when comparing against one
+ (parse_begin): Cast a printf-style field width to an int.
+ (parse_bend): Likewise.
+ (parse_def): Likewise.
+ (parse_end): Likewise.
+ (mark_stabs): Mark parameter `start' with ATTRIBUTE_UNUSED.
+ (parse_stabs_common): Fix format specifier.
+ (parse_input): Change type of variable `i' to Size_t.
+ (write_object): Fix arguments to match format specifiers.
+ Cast variable `num_write' to long when comparing against one.
+ (read_seek): Cast variable `sys_read' to symint_t when comparing
+ against one. Fix arguments to match format specifiers. Cast
+ variable `size' to long when comparing against one.
+ (copy_object): Cast result of `sizeof' to int when comparing
+ against one. Fix arguments to match format specifiers. Cast
+ variable `ifd' to long when comparing against a signed value.
+ Likewise, likewise.
+
+Mon Jan 4 10:30:33 1999 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * c-common.c (decl_attributes): Allow applying attribute `unused'
+ on a LABEL_DECL.
+
+ * c-parse.in (label): Parse attributes after a label, and call
+ `decl_attributes' to handle them.
+
+ * gansidecl.h (ATTRIBUTE_UNUSED_LABEL): Define.
+
+ * genrecog.c (OUTPUT_LABEL, write_tree_1, write_tree): When
+ generating labels, mark them with ATTRIBUTE_UNUSED_LABEL.
+
+ * invoke.texi: Note that labels can be marked `unused'.
+
+Sun Jan 3 23:32:18 PST 1999 Jeff Law (law@cygnus.com)
+
+ * version.c: Bump for snapshot.
+
+Sun Jan 3 23:00:42 1999 Jeffrey A Law (law@cygnus.com)
+
+ * optabs.c (emit_cmp_and_jump_insns): Use CONSTANT_P canonicalizing
+ RTL for a compare/jump sequence.
+
+Sun Jan 3 22:58:15 1999 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
+
+ * optabs.c (emit_cmp_insn): Abort if asked to emit non-canonical RTL
+ for a target with HAVE_cc0 defined.
+ (emit_cmp_and_jump_insns): New function.
+ * expr.h (emit_cmp_and_jump_insns): Prototype it.
+ * loop.c (check_dbra_loop): Use it to replace calls
+ to emit_cmp_insn and emit_jump_insn and to canonicalise
+ the comparison if necessary.
+ * unroll.c (unroll_loop): Likewise.
+
+Sun Jan 3 21:01:04 1999 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * fixincludes (sys/utsname.h): Provide forward declaration of
+ struct utsname on Ultrix V4.[35].
+
+ * mips.md (div_trap): Use local labels instead of dot-relative
+ branches.
+
+Sun Jan 3 20:40:34 1999 Jeffrey A Law (law@cygnus.com)
+
+ * pa.md (branch, negated branch): Handle (const_int 0) as first
+ source operand.
+ * pa.c (output_cbranch): Likewise.
+
+Sun Jan 3 03:20:38 1999 David Edelsohn <edelsohn@gnu.org>
+
+ * rs6000.c (rs6000_stack_info): Undo spurious part of last
+ change.
+
+1999-01-01 Manfred Hollstein <manfred@s-direktnet.de>
+
+ * extend.texi (__builtin_constant_p): Add missing @smallexample.
+
+Fri Jan 1 11:48:20 1999 Jeffrey A Law (law@cygnus.com)
+
+ * i386.md (doubleword shifts): Fix dumb mistakes in previous change.
+
+Wed Dec 30 23:38:55 1998 Jeffrey A Law (law@cygnus.com)
+
+ * m68k.md (adddi_dilshr32): Allow all operands to be registers too.
+ (adddi_dishl32): Similarly.
+
+ * cse.c (invalidate_skipped_block): Call invalidate_from_clobbers
+ for each insn in the skipped block.
+
+ * reload1.c (reload_as_needed): Verify that the insn satisfies its
+ constraints after replacing a register address with an autoincrement
+ address for reload inheritance purposes.
+
+ * i386.md (doubleword shifts): Avoid namespace pollution.
+
+Wed Dec 30 23:00:28 1998 David O'Brien <obrien@NUXI.com>
+
+ * configure.in (FreeBSD ELF): Needs special crt files.
+
+Wed Dec 30 22:50:13 1998 Geoffrey Noer <noer@cygnus.com>
+
+ * i386/xm-cygwin.h: change DIR_SEPARATOR to forward slash.
+
+1998-12-30 Andreas Schwab <schwab@issan.cs.uni-dortmund.de>
+
+ * loop.c (check_dbra_loop): While reversing the loop, if the
+ comparison value has a VOID mode use the mode of the other operand
+ to compute the mask.
+
+Wed Dec 30 22:24:00 1998 Michael Meissner <meissner@cygnus.com>
+
+ * rs6000.md ({save,restore}_stack_function): Take 2 operands to
+ avoid warnings in compiling explow.c.
+
+ (patch from Ken Raeburn, raeburn@cygnus.com)
+ * rs6000.c (rs6000_stack_info): Force 8-byte alignment of
+ fpmem_offset. Compute total size after that, and then
+ rs6000_fpmem_offset using both values.
+
+Mon Dec 28 19:26:32 1998 Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at>
+
+ * gcc.texi (Non-bugs): ``Empty'' loops will be optimized away in
+ the future; indeed that already happens in some cases.
+
+Tue Dec 29 11:58:53 1998 Richard Henderson <rth@cygnus.com>
+
+ * sparc.c (input_operand): Recognize (const (constant_p_rtx)).
+ (arith_operand): Remove constant_p_rtx handling.
+ (const64_operand, const64_high_operand): Likewise.
+ (arith11_operand, arith10_operand, arith_double_operand): Likewise.
+ (arith11_double_operand, arith10_double_operand, small_int): Likewise.
+ (small_int_or_double, uns_small_int, zero_operand): Likewise.
+ * sparc.h (PREDICATE_CODES): Likewise.
+
+ * rtl.h (CONSTANT_P): Remove CONSTANT_P_RTX.
+
+Tue Dec 29 11:32:54 1998 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>:
+
+ * rtl.def (CONSTANT_P_RTX): Clarify commentary.
+ * expr.c (expand_builtin, case BUILT_IN_CONSTANT_P): Rework to
+ consider constant CONSTRUCTOR constant and to defer some cases
+ to cse.
+ * cse.c (fold_rtx, case CONST): Add handling for CONSTANT_P_RTX.
+ * regclass.c (reg_scan_mark_refs, case CONST): Likewise.
+
+Tue Dec 29 11:30:10 1998 Richard Henderson <rth@cygnus.com>
+
+ * expr.c (init_expr_once): Kill can_handle_constant_p recognition.
+ * cse.c (fold_rtx, case 'x'): Remove standalone CONSTANT_P_RTX code.
+
+ * alpha.c (reg_or_6bit_operand): Remove CONSTANT_P_RTX handling.
+ (reg_or_8bit_operand, cint8_operand, add_operand): Likewise.
+ (sext_add_operand, and_operand, or_operand): Likewise.
+ (reg_or_cint_operand, some_operand, input_operand): Likewise.
+ * alpha.h (PREDICATE_CODES): Likewise.
+
+Sat Dec 26 23:26:26 PST 1998 Jeff Law (law@cygnus.com)
+
+ * version.c: Bump for snapshot.
+
+Sat Dec 26 09:17:04 1998 Jeffrey A Law (law@cygnus.com)
+
+ * gengenrtl.c (gencode): Always use bzero to clear memory instead
+ of dangerous casts and stores.
+
+ * Makefile.in (compare, gnucompare): Add missing else true clauses.
+
+Fri Dec 25 23:00:56 1998 Jeffrey A Law (law@cygnus.com)
+
+ * alpha.md (builtin_longjmp): Add missing "DONE".
+
+Thu Dec 24 10:39:57 1998 Stan Cox <scox@cygnus.com>
+
+ * gcc.c (execute): Enable -pipe with win32.
+
+Wed Dec 23 10:27:44 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/arm/t-arm-elf: Add multiplib option for leading
+ underscores.
+
+ * config/arm/thumb.h (ASM_OUTPUT_LABELREF): Use variable
+ 'user_label_prefix' rather than macro USER_LABEL_PREFIX.
+
+ (thumb_shiftable_const): Use macro 'BASE_REG_CLASS' rather
+ than variable 'reload_address_base_reg_class'. [Note this
+ change is unrelated to the others in this patch].
+
+ * config/arm/unknown-elf.h (USER_LABEL_PREFIX): Default to no
+ leading underscore.
+
+Wed Dec 23 09:51:32 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * alias.c (record_alias_subset): Remove ignored `&'.
+ (init_alias_once): Likewise.
+
+ * c-lex.c (UNGETC): Cast first argument of comma expression to void.
+
+ * config/mips/mips.c (mips_asm_file_end): Cast the result of
+ fwrite to `int' when comparing against one.
+
+ * config/mips/mips.h (CAN_ELIMINATE): Add parens around && within ||.
+ (INITIAL_ELIMINATION_OFFSET): Add braces to avoid ambiguous `else'.
+
+ * cse.c (rehash_using_reg): Change type of variable `i' to
+ unsigned int.
+
+ * dwarf2out.c (initial_return_save): Cast -1 to unsigned before
+ assigning it to one.
+
+ * except.c (duplicate_eh_handlers): Remove unused variable `tmp'.
+
+ * final.c (final_scan_insn): Likewise for variable `i'.
+ (output_asm_insn): Cast a char to unsigned char when used as an
+ array index.
+
+ * gcse.c (compute_pre_ppinout): Cast -1 to SBITMAP_ELT_TYPE when
+ assigning it to one.
+
+ * loop.c (strength_reduce): Remove unused variables `count' and `temp'.
+
+ * recog.c (preprocess_constraints): Cast a char to unsigned char
+ when used as an array index.
+
+ * regmove.c (find_matches): Likewise.
+
+ * reload1.c (calculate_needs): Add default case in switch.
+ (eliminate_regs_in_insn): Initialize variable `offset'.
+ (set_offsets_for_label): Change type of variable `i' to unsigned.
+ (reload_as_needed): Wrap variable `i' in macro check on
+ AUTO_INC_DEC || INSN_CLOBBERS_REGNO_P.
+
+ * scan-decls.c (scan_decls): Mark parameters `argc' and `argv'
+ with ATTRIBUTE_UNUSED. Cast variable `start_written' to size_t
+ when comparing against one.
+
+ * stor-layout.c (layout_decl): Cast maximum_field_alignment to
+ unsigned when comparing against one. Likewise for
+ GET_MODE_ALIGNMENT().
+ (layout_record): Cast record_align to int when comparing against a
+ signed value.
+ (layout_type): Cast TYPE_ALIGN() to int when comparing against a
+ signed value.
+
+ * tree.c (get_identifier): Cast variable `len' to unsigned when
+ comparing against one.
+ (maybe_get_identifier): Likewise
+
+Wed Dec 23 00:10:01 1998 Jeffrey A Law (law@cygnus.com)
+
+ * toplev.c (rest_of_compilation): Do not set reload_completed.
+ * reload1.c (reload): Set reload_completed before calling
+ cleanup_subreg_operands.
+
+Tue Dec 22 23:58:31 1998 Richard Henderson <rth@cygnus.com>
+
+ * reload1.c (emit_reload_insns): Check `set' not null before use.
+
+Tue Dec 22 15:15:45 1998 Nick Clifton <nickc@cygnus.com>
+
+ * rtlanal.c (multiple_sets): Change type of 'found' from 'rtx' to
+ 'int'.
+
+Tue Dec 22 13:55:44 1998 Theodore Papadopoulo <Theodore.Papadopoulo@sophia.inria.fr>
+
+ * halfpic.c (half_pic_encode): Delete redundant code.
+
+Tue Dec 22 13:02:22 1998 Michael Meissner <meissner@cygnus.com>
+
+ * toplev.c (main): Delete handling of -dM as a preprocessor
+ option.
+
+Mon Dec 21 17:39:38 1998 Michael Meissner <meissner@cygnus.com>
+
+ * toplev.c (main): Don't emit any warnings when using -dD, -dM, or
+ -dI, which are handled by the preprocessor.
+
+Sun Dec 20 16:13:44 1998 John F. Carr <jfc@mit.edu>
+
+ * configure.in: Handle Digital UNIX 5.x the same as 4.x.
+ * i386/sol2.h: Define LOCAL_LABEL_PREFIX as ".".
+
+Sun Dec 20 07:39:52 PST 1998 Jeff Law (law@cygnus.com)
+
+ * version.c: Bump for snapshot.
+
+Sat Dec 19 22:24:22 PST 1998 Jeff Law (law@cygnus.com)
+
+ * version.c: Bump for snapshot.
+
+Sat Dec 19 21:41:32 PST 1998 Jeff Law (law@cygnus.com)
+
+ * version.c: Bump for snapshot.
+
+Sat Dec 19 09:52:27 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * genattr.c (fatal): Qualify a char* with the `const' keyword.
+
+ * genattrtab.c (fatal, attr_printf, attr_string, write_attr_set,
+ write_unit_name, write_eligible_delay, expand_units,
+ make_length_attrs, write_attr_case, find_attr,
+ make_internal_attr): Likewise.
+ * gencheck.c (tree_codes): Likewise.
+ * gencodes.c (fatal): Likewise.
+ * genconfig.c (fatal): Likewise.
+ * genemit.c (fatal): Likewise.
+ * genextract.c (fatal, walk_rtx, copystr): Likewise.
+ * genflags.c (fatal): Likewise.
+ * genopinit.c (fatal, optabs, gen_insn): Likewise.
+ * genoutput.c (fatal, error, predicates): Likewise.
+ * genpeep.c (fatal): Likewise.
+ * genrecog.c (fatal, decision, pred_table, add_to_sequence,
+ write_tree_1, write_tree, change_state, copystr, indents): Likewise.
+
+Thu Dec 17 18:21:49 1998 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * configure.in (with-fast-fixincludes): Fix whitespace.
+ * configure: Rebuilt.
+
+ * fixincludes (c_asm.h): Wrap Digital UNIX V4.0B DEC C specific
+ asm() etc. function declarations in __DECC.
+
+Thu Dec 17 13:57:23 1998 Nick Clifton <nickc@cygnus.com>
+
+ * expr.c (emit_move_insn_1): Only emit a clobber if the target
+ is a pseudo register.
+
+Thu Dec 17 13:50:29 1998 Nick Clifton <nickc@cygnus.com>
+
+ * gcse.c: Include expr.h in order to get the prototype for
+ get_condition() which is used in delete_null_pointer_checks().
+
+Thu Dec 17 15:58:26 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * hwint.h: New file to consolidate HOST_WIDE_INT (etc) macros.
+
+Thu Dec 17 12:31:12 1998 Jim Wilson <wilson@cygnus.com>
+
+ * Makefile.in (INTERNAL_CFLAGS): Add SCHED_CFLAGS.
+ (ALL_CFLAGS): Delete SCHED_CFLAGS.
+
+1998-12-17 Vladimir N. Makarov <vmakarov@cygnus.com>
+
+ * config/i60/i960.md (extendqihi2): Fix typo (usage ',' instead of
+ ';').
+
+1998-12-17 Michael Tiemann <tiemann@axon.cygnus.com>
+
+ * i960.md (extend*, zero_extend*): Don't generate rtl that looks
+ like (subreg:SI (reg:SI N) 0), because it's wrong, and it hides
+ optimizations from the combiner.
+
+Thu Dec 17 08:27:03 1998 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * loop.c (combine_givs_used_by_other): Don't depend on n_times_set.
+
+Wed Dec 16 17:30:35 1998 Nick Clifton <nickc@cygnus.com>
+
+ * toplev.c (main): Disable optimize_size if a specific
+ optimization level is requested. Always set optimization
+ level to 2 if -Os is specified.
+
+Wed Dec 16 16:33:04 1998 Dave Brolley <brolley@cygnus.com>
+
+ * objc/lang-specs.h: Pass -MD, -MMD and -MG to cc1obj if configured with
+ cpplib.
+ * cpplib.c (cpp_start_read): If in_fname is not initialized, try to
+ initialize it using fname.
+
+1998-12-16 Zack Weinberg <zack@rabi.phys.columbia.edu>
+
+ * cpplib.c (do_include): Treat #include_next in the
+ primary source file as #include plus warning. Treat
+ #include_next in a file included by absolute path as an
+ error. fp == CPP_NULL_BUFFER is a fatal inconsistency.
+
+Wed Dec 16 12:28:54 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * cccp.c: Don't define MIN/MAX anymore.
+ * cpplib.c: Likewise.
+ * machmode.h: Likewise.
+ * system.h: Provide definitions for MIN/MAX.
+
+Tue Dec 15 23:47:42 1998 Zack Weinberg <zack@rabi.phys.columbia.edu>
+
+ * fix-header.c: Don't define xstrdup here.
+
+Wed Dec 16 05:11:04 1998 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * loop.c (consec_sets_giv): New argument last_consec_insn.
+ (strength_reduce): Provide / use it.
+
+Wed Dec 16 17:24:07 1998 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
+
+ * loop.h (loop_info): New field 'vtop'.
+ * loop.c (check_dbra_loop): Use loop_info->vtop rather than
+ scanning loop for vtop.
+ * unroll.c (subtract_reg_term, find_common_reg_term): New functions.
+ (loop_iterations): Use them to determine if loop has a constant
+ number of iterations. Set loop_info->vtop. Don't subtract
+ common reg term from initial_value and final_value if have a
+ do-while loop.
+
+Tue Dec 15 13:49:55 1998 Jeffrey A Law (law@cygnus.com)
+
+ * mn10200.md (addsi3 expander): Use "nonmemory_operand" for operand 2.
+
+ * mn10300.md (bset, bclr): Operand 0 is a read/write operand.
+
+ * mn10200.md (abssf2, negsf2): New expanders.
+
+ * mn10300.md (absdf2, abssf2, negdf2, negsf2): New expanders.
+
+Tue Dec 15 11:55:30 1998 Nick Clifton <nickc@cygnus.com>
+
+ * integrate.c (copy_rtx_and_substitute): If a SUBREG is
+ replaced by a CONCAT whoes components do not have the same
+ mode as the original SUBREG, use a new SUBREG to restore the
+ mode.
+
+ * emit-rtl.c (subreg_realpart_p): Cope with subregs containing
+ multiword complex values.
+
+1998-12-15 Zack Weinberg <zack@rabi.phys.columbia.edu>
+
+ * cppalloc.c: Add xstrdup here.
+ * cpplib.h: Remove savestring prototype.
+ * cpplib.c: Remove savestring function. s/savestring/xstrdup/
+ throughout.
+ * cppfiles.c: s/savestring/xstrdup/ throughout.
+
+1998-12-15 Zack Weinberg <zack@rabi.phys.columbia.edu>
+
+ * cpplib.c: Make all directive handlers read their own
+ arguments.
+ (struct directive): Remove last two arguments from FUNC
+ member prototype. Remove `command_reads_line' member
+ entirely.
+ (directive_table): Remove initializations of
+ command_reads_line flag. Pretty-print.
+ (eval_if_expression, do_define, do_line, do_include,
+ do_undef, do_error, do_pragma, do_ident, do_if, do_xifdef,
+ do_else, do_elif, do_sccs, do_assert, do_unassert,
+ do_warning): Take only two args.
+
+ (cpp_define): Call do_define with two args and the text to
+ define stuffed into a buffer.
+ (make_assertion): Call do_assert with two args.
+ (handle_directive): Call do_line with two args. Call
+ kt->func with two args. Remove command_reads_line
+ processing.
+ (do_define, do_undef, do_error, do_warning, do_pragma,
+ do_sccs): Read the rest of the line here.
+ (do_ident): Gobble rest of line, as cccp does.
+ (cpp_undef): New function.
+ (cpp_start_read): Call cpp_undef instead of do_undef.
+
+1998-12-15 Zack Weinberg <zack@rabi.phys.columbia.edu>
+
+ * cpphash.h (union hash_value): Remove `keydef' member, add a
+ `struct hashnode *aschain' member for #assert.
+
+ * cpplib.c (struct tokenlist_list, struct
+ assertion_hashnode): Delete structure definitions.
+ (assertion_install, assertion_lookup, delete_assertion,
+ check_assertion, compare_token_lists, reverse_token_list,
+ read_token_list, free_token_list): Delete functions.
+ (parse_assertion): New function.
+ (cpp_cleanup): Don't destroy the assertion_hashtable.
+
+ (do_assert): Gut and rewrite. #assert foo (bar) places
+ entries for `#foo' and `#foo(bar)' in the macro hash table,
+ type T_ASSERT. The value union's `aschain' member is used
+ to chain all answers for a given predicate together.
+ (do_unassert): Also rewritten. Take an un-asserted
+ answer off the chain from its predicate and call
+ delete_macro on the hashnode, or walk a predicate chain
+ calling delete_macro on all the entries.
+ (cpp_read_check_assertion): Simply call parse_assertion to
+ get the canonical assertion name, and look that up in the
+ hash table.
+
+ * cpplib.h (ASSERTION_HASHNODE,ASSERTION_HASHSIZE,assertion_hashtab):
+ Removed.
+
+ * cpphash.c (install): Use bcopy instead of an explicit loop
+ to copy the macro name.
+
+ * cppexp.c (cpp_lex): Convert the result of
+ cpp_read_check_assertion to a `struct operation' directly;
+ don't go through parse_number.
+
+Tue Dec 15 18:27:39 1998 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * loop.h (struct induction): Delete times_used member.
+ * loop.c (n_times_set): Rename to set_in_loop. Changed all users.
+ (n_times_used): Rename to n_times_set. Changed all users.
+ (scan_loop): Free reg_single_usage before strength reduction.
+ (record_giv, combine_givs): Remove handling of times_used member.
+ (combine_givs_used_once): Rename to:
+ (combine_givs_used_by_other) . Changed all callers.
+
+Tue Dec 15 01:45:26 1998 Jason Merrill <jason@yorick.cygnus.com>
+
+ * dwarf2out.c (gen_struct_or_union_type_die): Check AGGREGATE_TYPE_P
+ instead of TREE_CODE_CLASS == 't'.
+ (gen_type_die): Likewise.
+ (scope_die_for): Ignore FUNCTION_TYPE "scopes".
+
+Mon Dec 14 16:23:27 1998 Jim Wilson <wilson@cygnus.com>
+
+ * real.c (endian): Disable last change unless
+ HOST_BITS_PER_WIDE_INT is greater than 32.
+
+Mon Dec 14 17:13:36 EST 1998 Andrew MacLeod <amacleod@cygnus.com>
+
+ * output.h (force_data_section): New prototype.
+ * varasm.c (force_data_section): New function to force the
+ data section, regardless of what in_section thinks.
+ * dwarf2out.c (output_call_frame_info): Call force_data_section
+ since varasm may not realize we've changes sections.
+
+Mon Dec 14 14:09:34 1998 Nick Clifton <nickc@cygnus.com>
+
+ * reload1.c (reload): Delete REG_RETVAL and REG_LIBCALL notes
+ after completeing reload.
+
+ * rtl.texi: Document that REG_RETVAL and REG_LIBCALL are
+ deleted after reload.
+
+Mon Dec 14 01:39:28 1998 Jeffrey A Law (law@cygnus.com)
+
+ * rtl.h (multiple_sets): Fix prototype.
+ * rtlanal.c (multiple_sets): Fix return type.
+
+Sun Dec 13 12:43:58 PST 1998 Jeff Law (law@cygnus.com)
+
+ * version.c: Bump for snapshot.
+
+Sun Dec 13 01:05:22 PST 1998 Jeff Law (law@cygnus.com)
+
+ * version.c: Bump for snapshot.
+
+1998-12-13 Manfred Hollstein <manfred@s-direktnet.de>
+
+ * protoize.c (fputs): Wrap extern declaration in #ifndef fputs.
+
+Sun Dec 13 00:24:14 1998 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * rtl.h (recompute_reg_usage): Add second argument.
+ * flow.c (recompute_reg_usage): Likewise.
+ * toplev.c (rest_of_compilation): Supply second argument to
+ recompute_reg_usage.
+
+ * reload1.c (compute_use_by_pseudos): Allow reg_renumber[regno] < 0
+ after reload.
+
+Sat Dec 12 23:39:10 1998 Jeffrey A Law (law@cygnus.com)
+
+ * m68k/t-m68kelf (MULTILIB_OPTIONS): Add mcpu32.
+ (MULTILIB_MATCHES): -m68332 now uses mcpu32 libraries, not m68000.
+ (MULTILIB_EXCEPTIONS): Don't build 68881 libraries for m68000,
+ mcpu32 or m5200.
+
+ * i386/next.h (ASM_OUTPUT_ALIGN): Use 0x90 for fill character.
+
+ * rtlanal.c (multiple_sets): New function.
+ * rtl.h (multiple_sets): Declare it.
+ * local-alloc.c (wipe_dead_reg): Use it.
+ * global.c (global_conflicts): Likewise.
+
+Sat Dec 12 22:13:02 1998 Mark Mitchell <mark@markmitchell.com>
+
+ * global.c (record_conflicts): Don't use an array of shorts to
+ store an array of ints.
+ (global_conflicts): Likewise.
+
+Sat Dec 12 16:49:24 1998 Richard Henderson <rth@cygnus.com>
+
+ * alpha.c (alpha_expand_block_move): mode_for_size expects
+ bits, not bytes. Infer extra alignment from addressof.
+
+1998-12-11 Michael Meissner <meissner@cygnus.com>
+
+ * rs6000/sysv4.h (ASM_OUTPUT_ALIGNED_LOCAL): Put small data in the
+ .sbss section, not .sdata.
+
+1998-12-11 Manfred Hollstein <manfred@s-direktnet.de>
+
+ * cccp.c: Do not #include <sys/stat.h> here; this is already done
+ by "system.h".
+ * collect2.c: Likewise.
+ * cpplib.h: Likewise.
+ * gcc.c: Likewise.
+ * gcov.c: Likewise.
+ * getpwd.c: Likewise.
+ * protoize.c: Likewise.
+ * toplev.c: Likewise.
+
+ * cpplib.h (HOST_WIDE_INT): Get definition from "machmode.h"
+ and don't try to define it here.
+ * Makefile.in (cppmain.o): Depend on machmode.h.
+ (cpplib.o): Likewise.
+ (cpperror.o): Likewise.
+ (cppexp.o): Likewise.
+ (cppfiles.o): Likewise.
+ (cpphash.o): Likewise.
+ (cppalloc.o): Likewise.
+ (fix-header.o): Likewise.
+ (scan-decls.o): Likewise.
+
+Fri Dec 11 11:02:49 1998 Stan Cox <scox@cygnus.com>
+
+ * sh.c (print_operand): lookup interrupt_handler attribute instead
+ of relying on static variable.
+ * (calc_live_regs): Likewise.
+ * (sh_pragma_insert_attributes): Create interrupt_handler
+ attribute if a pragma was specified
+ * (sh_valid_machine_decl_attribute): Don't set static flag.
+ * sh.h (PRAGMA_INSERT_ATTRIBUTES): New.
+
+Fri Dec 11 12:56:07 1998 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * reload1.c (reload_combine): Use BASIC_BLOCK_LIVE_AT_START
+ to determine if a register is live at a jump destination.
+ Everything is dead at a BARRIER.
+
+Thu Dec 10 16:02:06 1998 Jim Wilson <wilson@cygnus.com>
+
+ * cse.c (simplify_unary_operation): Sign-extend constants when
+ they have the most significant bit set for the target.
+ * real.c (endian): Sign-extend 32 bit output values on a 64 bit
+ host.
+ * m32r/m32r.c (m32r_expand_prologue): Store pretend_size in
+ HOST_WIDE_INT temporary before negating it.
+ * m32r/m32r.md (movsi_insn+1): Use ~0xffff instead of 0xffff0000.
+
+Thu Dec 10 15:05:59 1998 Dave Brolley <brolley@cygnus.com>
+
+ * objc/objc-act.c (lang_init_options): Enclose cpplib related code in
+ #if USE_CPPLIB.
+
+Thu Dec 10 13:39:46 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * collect2.h: New header file for prototypes.
+
+ * Makefile.in (collect2.o, tlink.o): Depend on collect2.h.
+
+ * collect2.c: Include collect2.h.
+ * tlink.c: Likewise.
+
+Wed Dec 9 23:55:11 1998 Jeffrey A Law (law@cygnus.com)
+
+ * flow.c: Update some comments.
+
+Wed Dec 9 15:29:26 1998 Dave Brolley <brolley@cygnus.com>
+
+ * objc/objc-act.c (cpp_initialized): Removed.
+ (lang_init_options): Initialize cpplib.
+ (lang_decode_option): Move initialization of cpplib to
+ lang_init_options.
+ * c-lang.c: (parse_options,parse_in): Added.
+ (lang_init_options): Initialized cpplib here.
+ * c-decl.c (parse_options,cpp_initialized): Removed.
+ (c_decode_option): Move initialization of cpplib to
+ lang_init_options.
+
+Wed Dec 9 19:36:57 1998 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * reload1.c (reload_combine, reload_combine_note_store):
+ Make STORE_RUID always valid.
+ (reload_combine): Check if BASE is clobbered too early.
+
+Wed Dec 9 09:53:58 1998 Nick Clifton <nickc@cygnus.com>
+
+ * reload.c (find_reloads): Display the insn that cannot be
+ reloaded.
+
+Wed Dec 9 12:15:26 1998 Dave Brolley <brolley@cygnus.com>
+
+ * cccp.c (create_definition): Fix end of bufer logic.
+
+Wed Dec 9 10:15:45 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * except.c (duplicate_eh_handlers, rethrow_symbol_map): Function
+ pointer parameters changed to use the PARAMS() macro.
+
+Wed Dec 9 09:12:40 EST 1998 Andrew MacLeod <amacleod@cygnus.com>
+
+ * except.h (struct handler_info): Add handler_number field.
+ * except.c (gen_exception_label): EH labels no longer need to be
+ on the permanent obstack.
+ (get_new_handler): Set the label number field.
+ (output_exception_table_entry): Regenerate handler label reference
+ from the label number field.
+ (init_eh): Remove a blank line.
+ * integrate.c (get_label_from_map): Labels no longer need to be
+ on the permanent obstack.
+
+Tue Dec 8 22:04:33 1998 Jim Wilson <wilson@cygnus.com>
+
+ * i960/i960.h (CONST_COSTS, case CONST_INT): Accept power2_operand
+ only when OUTER_CODE is SET.
+
+Tue Dec 8 22:47:15 1998 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * loop.c (strength_reduce): If scan_start points to the loop exit
+ test, be wary of subversive use of gotos inside expression statements.
+ Don't set maybe_multiple for a backward jump that does not
+ include the label under consideration into its range.
+ * unroll.c (biv_total_increment): Make use of maybe_multiple field.
+
+Tue Dec 8 22:33:18 1998 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * explow.c (plus_constant_wide): Don't immediately return with
+ result of recursive call.
+
+Tue Dec 8 15:32:56 EST 1998 Andrew MacLeod <amacleod@cygnus.com>
+
+ * eh-common.h (struct eh_context): Add table_index for rethrows.
+
+ * rtl.h (enum reg_note): Add REG_EH_REGION and REG_EH_RETHROW reg notes.
+ (SYMBOL_REF_NEED_ADJUST): New flag indicating symbol needs to be
+ processed when inlined or unrolled (ie duplicated in some way).
+
+ * rtl.c (reg_note_name): Add strings for new reg_note enums.
+
+ * expr.h (rethrow_libfunc): New library decl.
+
+ * optabs.c (rethrow_libfunc): Initialize.
+
+ * except.h (struct eh_entry): Add new field 'rethrow_label'.
+ (new_eh_region_entry): No longer exported from except.c.
+ (duplicate_handlers): Renamed to duplicate_eh_handlers and
+ different prototype.
+ (rethrow_symbol_map, rethrow_used): New exported functions.
+ (eh_region_from_symbol): New exported function.
+
+ * except.c (create_rethrow_ref): New function to create a single
+ SYMBOL_REF for a rethrow region.
+ (push_eh_entry): Initialize a rethrow ref.
+ (func_eh_entry): Add a rethrow_label field.
+ (new_eh_region_entry): Make static, and initialize the rethrow entry.
+ (duplicate_eh_handlers): Create a new region, and remap labels/symbols.
+ (eh_region_from_symbol): Find an EH region based on its rethrow symbol.
+ (rethrow_symbol_map): Given a label map, maps a rethrow symbol for
+ a region into an appropriate new symbol.
+ (rethrow_used): Indicate whether a rethrow symbol has been referenced.
+ (expand_eh_region_end): Don't issue jump around code for new-exceptions.
+ (end_catch_handler): Emit a barrier for new-exceptions since
+ control can never drop through the end of a catch block.
+ (expand_end_all_catch): new-exceptions never fall through a catch
+ block.
+ (expand_rethrow): use __rethrow routine for new exceptions.
+ (output_exception_table_entry): Generate rethrow labels, if needed.
+ (output_exception_table): Generate start and end rethrow labels.
+ (init_eh): Create rethrow symbols for beginning and end of table.
+ (scan_region): Don't eliminate EH regions which are the targets of
+ rethrows.
+
+ * flow.c (make_edges): Add different edges for rethrow calls,
+ identified by having the REG_EH_RETHROW reg label.
+ (delete_unreachable_blocks): Don't delete regions markers which are
+ the target of a rethrow.
+
+ * integrate.c (save_for_inline_eh_labelmap): New callback routine to
+ allow save_for_inline_copying to call duplicate_eh_handlers.
+ (save_for_inline_copying): Call duplicate_eh_handlers instead of
+ exposing internal details of exception regions.
+ (copy_for_inline): Check if SYMBOL_REFs need adjustment.
+ (expand_inline_function_eh_labelmap): New callback routine to
+ allow expand_inline_function to call duplicate_eh_handlers.
+ (expand_inline_function): Call duplicate_eh_handlers instead of
+ exposing internal details of exception regions.
+ (copy_rtx_and_substitute): Adjust SYMBOL_REFS if SYMBOL_REF_NEED_ADJUST
+ flag is set.
+
+ * libgcc2.c (find_exception_handler): Generalize to enable it to
+ pick up processing where it left off last time for a rethrow.
+ (__unwinding_cleanup): New function. debug hook which is called before
+ unwinding when __throw finds there is nothing but cleanups left.
+ (throw_helper): Common parts of __throw extracted out for reuse.
+ (__throw): Common parts moved to throw_helper.
+ (__rethrow): New function for performing rethrows.
+
+Tue Dec 8 13:11:04 1998 Jeffrey A Law (law@cygnus.com)
+
+ * reload1.c (current_function_decl): Tweak declaration.
+
+Tue Dec 8 10:23:52 1998 Richard Henderson <rth@cygnus.com>
+
+ * c-decl.c (flag_isoc9x): Default off.
+ (c_decode_option): Kill -std=gnu, add -std=gnu89 and -std=gnu9x.
+ * cccp.c (print_help, main): Likewise.
+ * gcc.c (default_compilers): Update for -std=gnu*.
+
+Tue Dec 8 01:14:46 1998 Jeffrey A Law (law@cygnus.com)
+
+ * Makefile.in (DEMANGLE_H): Change location to shared demangle.h.
+ * demangle.h: Deleted.
+
+ * reload1.c (current_function_decl): Declare.
+
+Tue Dec 8 11:58:51 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * cpplib.c (convert_string): Use `0x00ff', not `0x00ffU'.
+
+Tue Dec 8 09:28:36 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * dbxout.c: If USG is defined use gstab.h, even if HAVE_STAB_H is set.
+
+1998-12-08 Ulrich Drepper <drepper@cygnus.com>
+
+ * configure.in: Test for availability of putc_unlocked, fputc_unlocked,
+ and fputs_unlocked.
+ * configure: Rebuilt.
+ * system.h: If the *_unlocked functions are available use them
+ instead of the locked counterparts by defining macros.
+ * config.in: Regenerated.
+
+Tue Dec 8 00:34:05 1998 Mike Stump <mrs@wrs.com>
+
+ * i386/bsd.h (ASM_FILE_START): Don't use dump_base_name, it is
+ wrong and should only be used for dump related things, not
+ debugging information, instead main_input_filename should be used.
+ Also, reuse output_file_directive if possible.
+ * i386/aix386ng.h (ASM_FILE_START): Likewise.
+ * i386/isc.h (ASM_FILE_START): Likewise.
+ * i386/win-nt.h (ASM_FILE_START): Likewise.
+ * i386/sun386.h (ASM_FILE_START): Likewise.
+
+Mon Dec 7 23:56:28 1998 Robert Lipe <robertl@dgii.com>
+
+ * configure.in (mips*-*-linux*): Handle big and little endian
+ systems.
+ * configure: Rebuilt.
+
+Mon Dec 7 23:14:51 1998 Mike Stump <mrs@wrs.com>
+
+ * emit-rtl.c: Fix typo.
+
+Mon Dec 7 23:07:38 1998 Nathan Sidwell <nathan@acm.org>
+
+ * reload1.c (eliminate_regs): Don't do anything, if we're not
+ generating code.
+
+Mon Dec 7 15:27:09 1998 DJ Delorie <dj@cygnus.com>
+
+ * mips/mips.h (ENCODE_SECTION_INFO): Handle TARGET_EMBEDDED_DATA.
+ Add comment.
+ * mips/mips.c (mips_select_section): Add comment.
+
+Mon Dec 7 17:55:06 1998 Mike Stump <mrs@wrs.com>
+
+ * cccp.c (ignore_escape_flag): Add support for \ as `natural'
+ characters in file names in #line to be consistent with #include
+ handling. We support escape prcessing in the # 1 "..." version of
+ the command. See also support in cp/lex.c.
+ (handle_directive): Likewise.
+ (do_line): Likewise.
+
+1998-12-07 Zack Weinberg <zack@rabi.phys.columbia.edu>
+
+ * cpplib.c (initialize_char_syntax): Use ISALPHA and ISALNUM
+ so it'll work on non-ASCII platforms. Always consider $ an
+ identifier character. Take no arguments.
+ (cpp_reader_init): Call initialize_char_syntax with no
+ arguments.
+ (cpp_start_read): Don't call initialize_char_syntax again.
+ Clear is_idchar['$'] and is_idstart['$'] if not
+ opts->dollars_in_ident.
+
+ * cpplib.h (struct cpp_reader): Replace void *data element by
+ cpp_options *opts. Rearrange elements to make gdb printout
+ less annoying (put buffer stack at end).
+ (CPP_OPTIONS): Get rid of now-unnecessary cast.
+
+ * cppmain.c: s/data/opts/ when initializing cpp_reader
+ structure.
+ * c-decl.c: Likewise.
+ * objc/objc-act.c: Likewise.
+ * fix-header.c: Likewise.
+
+1998-12-07 Zack Weinberg <zack@rabi.phys.columbia.edu>
+
+ * cpplib.h (struct cpp_buffer): Replace dir and dlen members
+ with a struct file_name_list pointer.
+ (struct cpp_reader): Add pointer to chain of `actual
+ directory' include searchpath entries.
+ (struct file_name_list): Add *alloc pointer for the sake of
+ the actual-directory chain.
+
+ Move definition of HOST_WIDE_INT here.
+ (cpp_parse_escape): Change prototype to match changes in
+ cppexp.c.
+
+ * cppfiles.c (actual_directory): New function.
+ (finclude): Use it to initialize the buffer's actual_dir
+ entry.
+ (find_include_file): We don't need to fix up max_include_len
+ here.
+
+ * cpplib.c (do_include): Don't allocate a file_name_list on
+ the fly for current directory "" includes, use the one that's
+ been preallocated in pfile->buffer->actual_dir. Hoist out
+ duplicate code from the search_start selection logic.
+ (cpp_reader_init): Initialize pfile->actual_dirs.
+
+ Remove definition of HOST_WIDE_INT. Change calls
+ to cpp_parse_escape to match changes in cppexp.c (note
+ hardcoded MASK, which is safe since this is the source
+ character set).
+
+ * cppexp.c: Bring over changes to cpp_parse_escape from cccp.c
+ to handle wide character constants in #if directives. The
+ function now returns a HOST_WIDE_INT, and takes a third
+ argument which is a binary mask for all legal values (0x00ff
+ for 8-bit `char', 0xffff for 16-bit `wchar_t', etc.) Define
+ MAX_CHAR_TYPE_MASK and MAX_WCHAR_TYPE_MASK. Change callers of
+ cpp_parse_escape to match. [Fixes c-torture/execute/widechar-1.c]
+
+Mon Dec 7 15:38:25 1998 Dave Brolley <brolley@cygnus.com>
+
+ * gcc.c (default_compilers): Fix typo in USE_CPPLIB spec for cc1.
+
+Mon Dec 7 15:38:25 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * c-aux-info.c (concat): Wrap function definition in !USE_CPPLIB.
+ * cppalloc.c: Move function `xcalloc' from cpplib.c to here.
+ * cpplib.c: Move function `xcalloc' from here to cppalloc.c.
+
+Mon Dec 7 11:30:49 1998 Nick Clifton <nickc@cygnus.com>
+
+ * final.c (output_asm_name): Use tabs to seperate comments from
+ assembly text.
+
+ Include instruction lengths (if defined) in output.
+
+Mon Dec 7 10:53:38 1998 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
+
+ * loop.c (check_dbra_loop): Fix initial_value and initial_equiv_value
+ in the loop_info structure.
+
+Mon Dec 7 11:04:40 1998 Catherine Moore <clm@cygnus.com>
+
+ * configure.in: (arm*-*-ecos-elf): New target.
+ * configure: Regenerated.
+ * config/arm/elf.h (ASM_WEAKEN_LABEL): Define.
+ * config/arm/ecos-elf.h: New file.
+ * config/arm/unknown-elf.h (TARGET_VERSION): Check
+ for redefinition.
+
+Mon Dec 7 16:15:51 1998 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * sh.c (output_far_jump): Emit braf only for TARGET_SH2.
+
+Sun Dec 6 04:19:45 PST 1998 Jeff Law (law@cygnus.com)
+
+ * version.c: Bump for snapshot.
+
+Sun Dec 6 05:16:16 1998 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
+
+ * loop.c (check_dbra_loop): New argument loop_info. Update fields
+ as needed.
+
+Sun Dec 6 03:40:13 PST 1998 Jeff Law (law@cygnus.com)
+
+ * version.c: Bump for snapshot.
+
+Sun Dec 6 07:49:29 1998 Alexandre Oliva <oliva@dcc.unicamp.br>
+
+ * gcc.texi (Bug Reporting): 40Kb is a soft limit, larger
+ compressed reports are ok and preferred over URLs
+
+Sun Dec 6 07:45:33 1998 Alexandre Oliva <oliva@dcc.unicamp.br>
+
+ * invoke.texi (Warning Options): Soften the tone of -pedantic
+
+Sun Dec 6 00:20:44 1998 H.J. Lu (hjl@gnu.org)
+
+ * print-rtl.c (print_rtx): Add prototype.
+
+ * unroll.c (iteration_info): Make it static.
+
+Sun Dec 6 01:19:46 1998 Richard Henderson <rth@cygnus.com>
+
+ * alias.c (memrefs_conflict_p): A second ANDed address
+ disables the aligned address optimization.
+
+Sat Dec 5 18:48:25 1998 Richard Henderson <rth@cygnus.com>
+
+ * alpha.c (alpha_emit_set_const_1): Fix parenthesis error
+ in -c << n case.
+
+Sat Dec 5 15:14:52 1998 Jason Merrill <jason@yorick.cygnus.com>
+
+ * i960.h (BOOL_TYPE_SIZE): Define.
+
+Sun Dec 6 00:28:16 1998 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
+
+ * config/c4x/c4x.c (valid_parallel_load_store): Flog functionality
+ from old valid_parallel_operands_4.
+ (valid_parallel_operands_4): Check that operands for 4 operand
+ parallel insns are valid, excluding load/store insns.
+ * config/c4x/c4x.h (valid_parallel_load_store): Add prototype.
+ * config/c4x/c4x.md (*movqf_parallel, *movqi_parallel): Use
+ valid_parallel_load_store instead of valid_parallel_operands_4.
+ (*absqf2_movqf_clobber, *floatqiqf2_movqf_clobber,
+ *negqf2_movqf_clobber, *absqi2_movqi_clobber,
+ *fixqfqi2_movqi_clobber, *negqi2_movqi_clobber,
+ *notqi_movqi_clobber): Use valid_parallel_operands_4.
+ (*subqf3_movqf_clobber, *ashlqi3_movqi_clobber,
+ *ashrqi3_movqi_clobber, *lshrqi3_movqi_clobber,
+ *subqi3_movqi_clobber): Use valid_parallel_operands_5.
+
+Sat Dec 5 23:52:01 1998 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
+
+ * config/c4x/c4x.c (iteration_info): Delete extern.
+
+Fri Dec 4 20:15:57 1998 Bernd Schmidt <crux@pool.informatik.rwth-aachen.de>
+
+ * tm.texi (SMALL_REGISTER_CLASSES): Make description match reality.
+
+ * final.c (cleanup_subreg_operands): Delete some unused code.
+
+ * recog.h (MAX_RECOG_ALTERNATIVES): New macro.
+ (struct insn_alternative): New structure definition.
+ (recog_op_alt): Declare variable.
+ (preprocess_constraints): Declare function.
+ * recog.c (recog_op_alt): New variable.
+ (extract_insn): Verify number of alternatives is in range.
+ (preprocess_constraints): New function.
+ * reg-stack.c: Include recog.h.
+ (constrain_asm_operands): Delete.
+ (get_asm_operand_lengths): Delete.
+ (get_asm_operand_n_inputs): New function.
+ (record_asm_reg_life): Delete OPERANDS, CONSTRAINTS, N_INPUTS and
+ N_OUTPUTS args. All callers changed.
+ Compute number of inputs and outputs here by calling
+ get_asm_operand_n_inputs.
+ Instead of constrain_asm_operands, call extract_insn,
+ constrain_operands and preprocess_constaints. Use information
+ computed by these functions throughout.
+ (record_reg_life): Delete code that is unused due to changes in
+ record_asm_reg_life.
+ (subst_asm_stack_regs): Delete OPERANDS, OPERAND_LOC, CONSTRAINTS,
+ N_INPUTS and N_OUTPUTS args. All callers changed.
+ Similar changes as in record_asm_reg_life.
+ (subst_stack_regs): Move n_operands declaration into the if statement
+ where it's used.
+ Delete code that is unused due to changes in subst_asm_stack_regs.
+ * stmt.c (expand_asm_operands): Verify number of alternatives is in
+ range.
+ * Makefile.in (reg-stack.o): Depend on recog.h.
+
+Fri Dec 4 02:23:24 1998 Jeffrey A Law (law@cygnus.com)
+
+ * except.c (set_exception_version_code): Argument is an "int".
+
+Fri Dec 4 01:29:28 1998 Jeffrey A Law (law@cygnus.com)
+
+ * configure.in (hppa2*-*-*): Handle like hppa1.1-*-* for now.
+ * configure: Rebuilt.
+
+Fri Dec 4 01:29:28 1998 Robert Lipe <robertl@dgii.com>
+
+ * configure.in (mipsel-*-linux*): New target.
+ * mips/linux.h: New file, based on other Linux targets.
+
+Thu Dec 3 11:19:50 1998 Mike Stump <mrs@wrs.com>
+
+ * gthr-vxworks.h (__ehdtor): Fix memory leak. The delete hook
+ runs in the context of the deleter, not the deletee, so we must
+ use taskVarGet to find the correct memory to free.
+ (__gthread_key_create): Initialize the task
+ variable subsystem so that the task variable is still active when
+ the delete hook is run.
+
+1998-12-03 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * pdp11.h: Use optimize_size for space optimizations.
+ * pdp11.c: Likewise.
+ * pdp11.md: Likewise.
+
+ * pdp11.h (TARGET_40_PLUS): Fix typo.
+
+Thu Dec 3 11:48:32 1998 Jeffrey A Law (law@cygnus.com)
+
+ * local-alloc.c (block_alloc): Slightly retune heuristic to widen
+ qty lifetimes.
+
+Thu Dec 3 22:30:18 1998 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
+
+ * alias.c (addr_side_effect_eval): New function.
+ (memrefs_conflict_p): Use it.
+ * rtl.h (addr_side_effect_eval): Prototype it.
+
+1998-12-02 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * pdp11.md (extendsfdf2): Fix mode mismatch in SET.
+
+Wed Dec 2 11:23:07 1998 Jim Wilson <wilson@cygnus.com>
+
+ * reload.c (find_reloads): When force const to memory, put result
+ in substed_operand not *recog_operand_loc.
+
+1998-12-02 Ulrich Drepper <drepper@cygnus.com>
+
+ * c-lex.c: Fix indentation from last patch.
+ Remove trailing whitespace.
+ * real.c: Likewise.
+
+Wed Dec 2 10:11:12 1998 Jeffrey A Law (law@cygnus.com)
+
+ * flow.c (delete_block): Call set_last_insn after we have reset
+ NEXT_INSN (kept_tail).
+
+Wed Dec 2 00:47:31 1998 Jeffrey A Law (law@cygnus.com)
+
+ * mips.md (trap_if): Use "$0" for the value zero.
+
+Tue Dec 1 20:49:49 1998 Ulrich Drepper <drepper@cygnus.com>
+ Stephen L Moshier <moshier@world.std.com>
+ Richard Henderson <rth@cygnus.com>
+
+ * c-common.c (declare_function_name): Declare predefinied variable
+ `__func__'.
+
+ * c-decl.c (flag_isoc9x): Set to 1 by default.
+ (c_decode_option): Handle -std= option. Remove -flang-isoc9x.
+ (grokdeclarator): Always emit warning about implicit int for ISO C 9x.
+
+ * c-parse.in: Allow constructors in ISO C 9x.
+ Rewrite designator list handling.
+ Allow [*] parameters.
+ Don't warn about comma at end of enum definition for ISO C 9x.
+
+ * cccp.c (c9x): New variable.
+ (rest_extension): New variable.
+ (print_help): Document new -std= option.
+ (main): Recognize -std= option. Set c9x appropriately.
+ (create_definition): Recognize ISO C 9x vararg macros.
+
+ * gcc.c (default_compilers): Adjust specs for -std options.
+ (option_map): Add --std.
+ (display_help): Document -std.
+
+ * toplev.c (documented_lang_options): Add -std and remove
+ -flang-isoc9x.
+
+ * c-lex.c (yylex): Recognize hex FP constants and call REAL_VALUE_ATOF
+ or REAL_VALUE_HTOF based on base of the constants.
+ * fold-const.c (real_hex_to_f): New function. Replacement function
+ for hex FP conversion if REAL_ARITHMETIC is not defined.
+ * real.c (asctoeg): Add handling of hex FP constants.
+ * real.h: Define REAL_VALUE_HTOF if necessary using ereal_atof or
+ real_hex_to_f.
+
+Tue Dec 1 16:45:49 1998 Stan Cox <scox@cygnus.com>
+
+ * mips.md (divmodsi4*, divmoddi4*, udivmodsi4*, udivmoddi4): Add
+ -mcheck-range-division/-mcheck-zero-division checking. Avoid as macro
+ expansion. Use hi/lo as destination register.
+ (div_trap): New.
+ (divsi3*, divdi3*, modsi3*, moddi3*, udivsi3*, udivdi3*, umodsi3*,
+ umoddi3*): Add -mcheck-range-division/-mcheck-zero-division checking.
+ Avoid as macro expansion. Use hi/lo as destination register.
+
+ * mips.h (MASK_CHECK_RANGE_DIV): New.
+ (MASK_NO_CHECK_ZERO_DIV): New.
+ (ELIMINABLE_REGS): Added GP_REG_FIRST + 31.
+ (CAN_ELIMINATE, INITIAL_ELIMINATION_OFFSET): Allow for getting
+ return address for leaf functions out of r31 to support
+ builtin_return_address.
+
+Tue Dec 1 15:03:30 1998 Herman A.J. ten Brugge <Haj.Ten.Brugge@net.HCC.nl>
+
+ * jump.c (jump_optimize): Call regs_set_between_p with PREV_INSN(x),
+ NEXT_INSN(x) to check insn x.
+
+Tue Dec 1 15:20:44 1998 Jeffrey A Law (law@cygnus.com)
+
+ * flow.c (delete_block): Call set_last_insn if we end up deleting the
+ last insn in the rtl chain.
+
+ * reload1.c (reload): Do not set reload_completed or split insns
+ here. Instead...
+ * toplev.c (rest_of_compilation): Set reload_completed after
+ reload returns. Split insns after reload_cse has run.
+
+Tue Dec 1 11:55:04 1998 Richard Henderson <rth@cygnus.com>
+
+ * final.c (final_scan_insn): Abort if block_depth falls below 0.
+
+Tue Dec 1 10:23:16 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/arm/t-arm-elf (LIBGCC2_CFLAGS): Define inhibit_libc.
+
+Tue Dec 1 10:22:18 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/arm/unknown-elf.h (ASM_OUTPUT_DWARF2_ADDR_CONST): Remove
+ use of user-label_prefix.
+
+Tue Dec 1 17:58:26 1998 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * reload1.c (emit_reload_insns): Clear spill_reg_store
+ when doing a new non-inherited reload from the same pseudo.
+
+ * local-alloc.c (function_invariant_p): New function.
+ (update_equiv_regs): Use function_invariant_p instead of CONSTANT_P
+ to decide if an equivalence should be recorded.
+ * reload1.c (num_eliminable_invariants): New static variable.
+ (reload): Set it. Use function_invariant_p instead of CONSTANT_P
+ to decide if an equivalence should be recorded.
+ Unshare PLUS.
+ (calculate_needs_all_insns): Skip insns that only set an equivalence.
+ Take num_eliminable_invariants into account when deciding
+ if register elimination should be done.
+ (reload_as_needed): Take num_eliminable_invariants into account
+ when deciding if register elimination should be done.
+ (eliminate_regs): Handle non-constant reg_equiv_constant.
+ * rtl.h (function_invariant_p): Declare.
+
+Mon Nov 30 02:00:08 PST 1998 Jeff Law (law@cygnus.com)
+
+ * version.c: Bump for snapshot.
+
+Mon Nov 30 00:42:59 PST 1998 Jeff Law (law@cygnus.com)
+
+ * version.c: Bump for snapshot.
+
+Sun Nov 29 22:59:40 1998 Jason Merrill <jason@yorick.cygnus.com>
+
+ * except.c (add_new_handler): Complain about additional handlers
+ after one that catches everything.
+
+Sat Nov 28 10:56:32 1998 Jeffrey A Law (law@cygnus.com)
+
+ * configure.in (alpha*-*-netbsd): Fix typo.
+ * configure: Rebuilt.
+
+Fri Nov 27 12:28:56 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * system.h: Include libiberty.h.
+
+ * c-aux-info.c: Remove prototypes for concat/concat3. Change
+ function `concat' from fixed parameters to variable parameters,
+ as is done in libiberty. All callers of concat/concat3
+ changed to use the new `concat' with variable args.
+
+ * cccp.c: Remove things made redundant by libiberty.h and/or
+ conform to libiberty standards.
+ * cexp.y: Likewise.
+ * collect2.c: Likewise.
+ * config/1750a/1750a.h: Likewise.
+ * cppalloc.c: Likewise.
+ * cppexp.c: Likewise.
+ * cppfiles.c: Likewise.
+ * cpphash.c: Likewise.
+ * cpplib.c: Likewise.
+ * dyn-string.c: Likewise.
+ * fix-header.c: Likewise.
+ * gcc.c: Likewise.
+ * gcov.c: Likewise.
+ * genattr.c: Likewise.
+ * genattrtab.c: Likewise.
+ * gencheck.c: Likewise.
+ * gencodes.c: Likewise.
+ * genconfig.c: Likewise.
+ * genemit.c: Likewise.
+ * genextract.c: Likewise.
+ * genflags.c: Likewise.
+ * gengenrtl.c: Likewise.
+ * genopinit.c: Likewise.
+ * genoutput.c: Likewise.
+ * genpeep.c: Likewise.
+ * genrecog.c: Likewise.
+ * getpwd.c: Likewise.
+ * halfpic.c: Likewise.
+ * hash.c: Likewise.
+ * mips-tdump.c: Likewise. Wrap malloc/realloc/calloc prototypes
+ in NEED_DECLARATION_* macros.
+
+ * mips-tfile.c: Remove things made redundant by libiberty.h and/or
+ conform to libiberty standards.
+ (fatal): Fix const-ification of variable `format' in
+ !ANSI_PROTOTYPES case.
+
+ * prefix.c: Remove things made redundant by libiberty.h and/or
+ conform to libiberty standards.
+
+ * print-rtl.c: Rename variable `spaces' to `xspaces' to avoid
+ conflicting with function `spaces' from libiberty.
+
+ * profile.c: Remove things made redundant by libiberty.h and/or
+ conform to libiberty standards.
+ * protoize.c: Likewise.
+ * rtl.h: Likewise.
+ * scan.h: Likewise.
+ * tlink.c: Likewise.
+ * toplev.c: Likewise.
+ * toplev.h: Likewise.
+ * tree.h: Likewise.
+
+Thu Nov 26 08:38:06 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * cppfiles.c (simplify_pathname): Un-ANSI-fy function definition.
+
+Thu Nov 26 23:45:37 1998 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
+
+ * README.C4X: Updated URLs.
+ * config/c4x/c4x.c (c4x_address_conflict): Fix typo.
+ (valid_parallel_operands_5): Remove unused variable.
+
+Thu Nov 26 23:40:03 1998 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
+
+ * config/c4x/c4x.h (TARGET_DEFAULT): Fix typo.
+
+1998-11-26 Manfred Hollstein <manfred@s-direktnet.de>
+
+ * Makefile.in (CONFIG_LANGUAGES): New macro taking all languages
+ which can be configured.
+ (LANGUAGES): Use $(CONFIG_LANGUAGES) instead of @all_languages@
+ (Makefile): Pass actual LANGUAGES through the environment when
+ re-configuring.
+ (cstamp-h): Likewise.
+ (config.status): Likewise.
+
+ * configure.in (enable_languages): Add new configuration parameter
+ "--enable-languages=lang1,lang2,...".
+ (${srcdir}/*/config-lang.in): Change handling to configure only
+ those directories, that the user might have enabled; default to
+ "all" existing languages.
+ * configure: Regenerate.
+
+Thu Nov 26 00:19:19 1998 Richard Henderson <rth@cygnus.com>
+
+ * rtlanal.c (regs_set_between_p): New function.
+ * rtl.h (regs_set_between_p): Prototype it.
+ * jump.c (jump_optimize): Use it instead of modified_between_p
+ in the Sep 2 change.
+
+Wed Nov 25 23:32:02 1998 Ian Dall <Ian.Dall@dsto.defence.gov.au>
+ Matthias Pfaller <leo@dachau.marco.de>
+
+ * invoke.texi (Option Summary, NS32K Options): add description
+ of NS32K specific options.
+
+ * ns32k.md (tstdf, cmpdf, movdf, truncdfsf2, fixdfqi2, fixdfhi2,
+ fixdfsi2, fixunsdfqi2, fixunsdfhi2, fixunsdfsi2, fix_truncdfqi2,
+ fix_truncdfhi2, fix_truncdfsi2, adddf3, subdf3, muldf3, divdf3,
+ negdf2, absdf2): Use l instead of f since the double class and
+ float class are no longer the same.
+ (cmpsi, truncsiqi2, truncsihi2, addsi3, subsi3, mulsi3, umulsidi3,
+ divsi3, modsi3, andsi3, iorsi3, xorsi3, negsi2, one_cmplsi2,
+ ashlsi3, ashlhi3, ashlqi3, rotlsi3, rotlhi3, rotlqi3, abssi2,...):
+ use "g" instead of "rmn" since LEGITIMATE_PIC_OPERAND has been
+ fixed.
+ (cmpsi, cmphi, cmpqi): use general_operand instead of
+ non_immediate_operand. Removes erroneous assumption that can't
+ compare constants.
+ (movsf, movsi, movhi, movqi,...): New register numbering scheme.
+ (movsi, addsi3): Use NS32K_DISPLACEMENT_P instead of hard coded
+ constants.
+ (movstrsi, movstrsi1, movstrsi2): completely new block move
+ scheme.
+ (...): Patterns to exploit multiply-add instructions.
+ (udivmodsi4, udivmodsi_internal4, udivmodhi4,
+ udivmoddihi4_internal, udivmodqi4, udivmoddiqi4_internal): new
+ patterns to exploit extended divide insns.
+ (udivsi3, udivhi3, udivqi3): remove since superceded by udivmodsi
+ etc patterns.
+
+ * ns32k.h (FUNCTION_VALUE, LIBCALL_VALUE): Use f0 for complex
+ float return values as well as simple scalar floats.
+ (TARGET_32381, TARGET_MULT_ADD, TARGET_SWITCHES):
+ support new flag to denote 32381 fpu.
+ (OVERRIDE_OPTIONS): 32381 is a strict superset of 32081.
+ (CONDITIONAL_REGISTER_USAGE): disable extra 32381 registers if not
+ compling for 32381.
+ (FIRST_PSEUDO_REGISTER, FIXED_REGISTERS, CALL_USED_REGISTERS,
+ REGISTER_NAMES, ADDITIONAL_REGISTER_NAMES, OUTPUT_REGISTER_NAMES,
+ REG_ALLOC_ORDER, DBX_REGISTER_NUMBER, R0_REGNUM, F0_REGNUM,
+ L1_REGNUM, STACK_POINTER_REGNUM, FRAME_POINTER_REGNUM,
+ LONG_FP_REGS_P, ARG_POINTER_REGNUM, reg_class, REG_CLASS_NAMES,
+ REG_CLASS_CONTENTS, SUBSET_P,REGNO_REG_CLASS,
+ REG_CLASS_FROM_LETTER, FUNCTION_PROLOGUE, FUNCTION_EPILOGUE,
+ REGNO_OK_FOR_INDEX_P, FP_REG_P, REG_OK_FOR_INDEX_P,
+ REG_OK_FOR_BASE_P, MEM_REG): new register scheme to include 32381
+ fpu registers and special register classes for new 32381
+ instructions dotf and polyf.
+ (MODES_TIEABLE_P): Allow all integer modes, notably DI and SI, to
+ be tieable.
+ (INCOMING_RETURN_ADDR_RTX, RETURN_ADDR_RTX,
+ INCOMING_FRAME_SP_OFFSET): New macros in case DWARF support is
+ required.
+ (SMALL_REGISTER_CLASSES): Make dependant on -mmult-add option.
+ (MOVE_RATIO): Set to zero because of smart movstrsi implimentation.
+ (REGISTER_MOVE_COST): move code to register_move_cost function for
+ ease of coding and debugging.
+ (CLASS_LIKELY_SPILLED_P): Under new register scheme class
+ LONG_FLOAT_REGO is likely spilled but not caught by default
+ definition.
+ (CONSTANT_ADDRESS_P, CONSTANT_ADDRESS_NO_LABEL_P): use macro
+ instead of hard coded numbers in range check.
+ (ASM_OUTPUT_LABELREF_AS_INT): delete since unused.
+ (...): Add prototypes for functions in ns32k.c but disable because
+ of problems when ns32k.h is included in machine independant files.
+
+ * ns32k.c: include "system.h", "tree.h", "expr.h", "flags.h".
+ (ns32k_reg_class_contents, regcass_map, ns32k_out_reg_names,
+ hard_regno_mode_ok, secondary_reload_class,
+ print_operand, print_operand_address): new register scheme to
+ include 32381 fpu registers and special register classes for new
+ 32381 instructions dotf and polyf.
+ (gen_indexed_expr): Make static to keep namespace clean.
+ (check_reg): remove since never called.
+ (move_tail, expand_block_move): helper functions for "movstrsi"
+ block move insn.
+ (register_move_cost): Helper function for REGISTER_MOVE_COST macro.
+ Increase cost of moves which go via memory.
+ * netbsd.h (TARGET_DEFAULT): Set (new) 32381 fpu flag.
+ (CPP_PREDEFINES): nolonger predefine "unix".
+
+ * ns32k.md (movsi, movsi, adddi3, subdi3, subsi3, subhi3, subqi3,...):
+ Remove erroneous %$. print_operand() can work out from the rtx is
+ an immediate prefix is required.
+
+ * ns32k.h (RETURN_POPS_ARGS, VALID_MACHINE_DECL_ATTRIBUTE,
+ VALID_MACHINE_TYPE_ATTRIBUTE, COMP_TYPE_ATTRIBUTES,
+ SET_DEFAULT_TYPE_ATTRIBUTES): Support for -mrtd calling
+ convention.
+ (LEGITIMATE_PIC_OPERAND_P, SYMBOLIC_CONST): Correct handling of
+ pic operands.
+
+ * ns32k.c (symbolic_reference_mentioned_p, print_operand):
+ Correct handling of pic operands.
+ (ns32k_valid_decl_attribute_p, ns32k_valid_type_attribute_p,
+ ns32k_comp_type_attributes, ns32k_return_pops_args): Support for
+ -mrtd calling convention.
+
+Wed Nov 25 23:42:20 1998 Tom Tromey <tromey@cygnus.com>
+
+ * gcc.c (option_map): Recognize --output-class-directory.
+
+Thu Nov 26 18:26:21 1998 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
+
+ * loop.h (precondition_loop_p): Added new mode argument.
+ * unroll.c (precondition_loop_p): Likewise.
+ (approx_final_value): Function deleted and subsumed
+ into loop_iterations.
+ (loop_find_equiv_value): New function.
+ (loop_iterations): Use loop_find_equiv_value to find increments
+ too large to be immediate constants. Also use it to find terms
+ common to initial and final iteration values that can be removed.
+
+Thu Nov 26 18:05:04 1998 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
+
+ * loop.h (struct loop_info): Define new structure.
+ (precondition_loop_p): Added prototype.
+ (unroll_loop): Added new argument loop_info to prototype.
+ (final_biv_value, final_giv_value): Added new argument n_iterations
+ to prototype.
+ * loop.c (strength_reduce): Declare new structure loop_iteration_info
+ and new pointer loop_info.
+ (loop_n_iterations): Replace global variable by element in
+ loop_info structure.
+ (check_final_value): New argument n_iterations.
+ (insert_bct): New argument loop_info.
+ (loop_unroll_factor): Replace global array by element in
+ loop_info structure.
+ (loop_optimize): Remove code to allocate and initialise
+ loop_unroll_factor_array.
+ * unroll.c (precondition_loop_p): No longer static since
+ used by branch on count optimization.
+ (precondition_loop_p, unroll_loop): New argument loop_info.
+ (final_biv_value, final_giv_value, find_splittable_regs): New
+ argument n_iterations.
+ (loop_iteration_var, loop_initial_value, loop_increment,
+ loop_final_value, loop_comparison_code, loop_unroll_factor):
+ Replaced global variables by loop_info structure.
+ (loop_unroll_factor): Replace global array by element in
+ loop_info structure.
+
+Thu Nov 26 17:49:29 1998 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
+
+ * loop.c (check_dbra_loop): Update JUMP_LABEL field of jump insn
+ when loop reversed.
+
+ * unroll.c (precondition_loop_p): Return loop_initial_value
+ for initial_value instead of loop_iteration_var.
+
+Thu Nov 26 17:15:38 1998 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
+
+ * config/c4x/c4x.md: Fix minor formatting problems. Update docs.
+ (*b, *b_rev, *b_noov, *b_noov_rev, *db,
+ decrement_and_branch_until_zero, rptb_end): Use c4x_output_cbranch
+ to output the instruction sequences.
+ (rpts): Delete.
+ (rptb_top): Provide alternatives to use any register or memory
+ for loop counter.
+ (rptb_end): Emit use of operands rather than assigning them
+ explicitly to the RS and RE registers.
+
+Thu Nov 26 16:37:59 1998 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
+
+ * config/c4x/c4x.c (c4x_modified_between_p, c4x_mem_set_p,
+ c4x_mem_set_p, c4x_mem_modified_between_p, c4x_insn_moveable_p,
+ c4x_parallel_pack, c4x_parallel_find, c4x_update_info_reg,
+ c4x_update_info_regs, c4x_copy_insn_after, c4x_copy_insns_after,
+ c4x_merge_notes, c4x_parallel_process,
+ c4x_combine_parallel_independent, c4x_combine_parallel_dependent,
+ c4x_combine_parallel): Delete.
+
+Thu Nov 26 15:16:05 1998 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
+
+ * config/c4x/c4x.c: (c4x_override_options): For compatibility
+ with old target options clear flag_branch_on_count_reg if
+ -mno-rptb specified and set flag_argument_alias is -mno-aliases
+ specified.
+ (c4x_output_cbranch): Handle a sequence of insns rather than a
+ single insn.
+ (c4x_rptb_insert): Do not emit a RPTB insn if the RC register
+ has not been allocated as the loop counter.
+ (c4x_address_conflict): Do not allow two volatile memory references.
+ (valid_parallel_operands_4, valid_parallel_operands_5,
+ valid_parallel_operands_6): Reject pattern if the register destination
+ of the first set is used as part of an address in the second set.
+
+Thu Nov 26 14:56:32 1998 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
+
+ * config/c4x/c4x.h (TARGET_DEFAULT): Add PARALEL_MPY_FLAG.
+ (TARGET_SMALL_REG_CLASS): Set to 0 so that SMALL_REGISTER_CLASSES
+ is no longer enabled if PARALLEL_MPY_FLAG set.
+ (HARD_REGNO_CALL_CLOBBERED): Add parentheses to remove ambiguity.
+ (REG_CLASS_CONTENTS): Add braces around initializers.
+ (HAVE_MULTIPLE_PACK): Define.
+ (ASM_OUTPUT_BYTE_FLOAT): Use %lf format specifier with
+ REAL_VALUE_TO_DECIMAL.
+ (ASM_OUTPUT_SHORT_FLOAT): Use %lf format specifier with
+ REAL_VALUE_TO_DECIMAL.
+ (ar0_reg_operand): Add prototype.
+ (ar0_mem_operand): Likewise.
+ (ar1_reg_operand): Likewise.
+ (ar1_mem_operand): Likewise.
+ (ar2_reg_operand): Likewise.
+ (ar2_mem_operand): Likewise.
+ (ar3_reg_operand): Likewise.
+ (ar3_mem_operand): Likewise.
+ (ar4_reg_operand): Likewise.
+ (ar4_mem_operand): Likewise.
+ (ar5_reg_operand): Likewise.
+ (ar5_mem_operand): Likewise.
+ (ar6_reg_operand): Likewise.
+ (ar6_mem_operand): Likewise.
+ (ar7_reg_operand): Likewise.
+ (ar7_mem_operand): Likewise.
+ (ir0_reg_operand): Likewise.
+ (ir0_mem_operand): Likewise.
+ (ir1_reg_operand): Likewise.
+ (ir1_mem_operand): Likewise.
+ (group1_reg_operand): Likewise.
+ (group1_mem_operand): Likewise.
+ (ir1_reg_operand): Likewise.
+ (arx_reg_operand): Likewise.
+ (not_rc_reg): Likewise.
+ (not_modify_reg): Likewise.
+ (c4x_group1_reg_operand): Remove prototype.
+ (c4x_group1_mem_operand): Likewise.
+ (c4x_arx_reg_operand): Likewise.
+
+Wed Nov 25 19:02:55 1998 (Stephen L Moshier) <moshier@world.std.com>
+
+ * emit-rtl.c (gen_lowpart_common): Remove earlier change.
+ * real.c (make_nan): Make SIGN arg actually specify the sign bit.
+
+Thu Nov 26 14:12:05 1998 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
+
+ * config/c4x/c4x.md (addqi3): Emit addqi3_noclobber pattern
+ during reload.
+
+Wed Nov 25 22:05:28 1998 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * config/sh/lib1funcs.asm (___udivsi3_i4): Don't switch to sz == 1
+ unless FMOVD_WORKS is defined.
+
+Wed Nov 25 20:11:04 1998 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * regclass.c (init_reg_sets): Move code that calculates tables
+ dependent on reg_class_contents from here...
+ (init_reg_sets_1): To here.
+
+Wed Nov 25 14:54:46 1998 Zack Weinberg <zack@rabi.phys.columbia.edu>
+
+ * cpplib.h: Delete struct import_file. Add ihash element to
+ struct cpp_buffer. Delete dont_repeat_files and
+ import_hash_table elements from cpp_reader; change
+ all_include_files to a hash table. Delete all foobar_include
+ / last_foobar_include elements from struct cpp_options; put
+ back four such: quote_include, bracket_include,
+ system_include, after_include. Redo struct file_name_list
+ completely. Add new structure type include_hash. Add
+ prototypes for merge_include_chains and include_hash. Change
+ prototypes for finclude, find_include_file, and
+ append_include_chain to match changes below.
+
+ * cppfiles.c (simplify_pathname, include_hash,
+ remap_filename, merge_include_chains): New functions.
+ (add_import, lookup_import, open_include_file): Removed.
+ (INO_T_EQ): Define this (copied from cccp.c).
+ (hack_vms_include_specification): Remove all calls and #if 0
+ out the definition. It was being called incorrectly and at
+ the wrong times. Until a VMSie can look at this, it's better
+ to not pretend to support it.
+ (append_include_chain): Change calling convention; now takes
+ only one directory at a time, and sets up the data structure
+ itself.
+ (redundant_include_p): Rewritten - this is now used for all
+ include redundancy, whether by #ifndef, #import, or #pragma
+ once. Looks up things in the include hash table.
+ (file_cleanup): Decrement pfile->system_include_depth here if
+ it's >0.
+ (find_include_file): Calling convention changed; now passes
+ around a struct include_hash instead of 3 separate parameters.
+ Guts ripped out and replaced with new include_hash mechanism.
+ (finclude): Calling convention changed as for
+ find_include_file. Error exits pulled out-of-line. Reformat.
+ (safe_read): Return a long, not an int.
+ (deps_output): Don't recurse.
+
+ * cpplib.c (is_system_include): Deleted.
+ (path_include): Fix up call to append_include_chain.
+ (do_include): Fix up calls to find_include_file and finclude.
+ Clean up dependency output a bit. Shorten obnoxiously lengthy
+ #import warning message. Don't decrement
+ pfile->system_include_depth here.
+ (do_pragma): Understand the include_hash structure. Reformat.
+ (do_endif): Correct handling of control macros. Understand
+ the include_hash.
+ (cpp_start_read): Fix up calls to finclude. Call
+ merge_include_chains.
+ (cpp_handle_option): Fix up calls to append_include_chain.
+ Understand the four partial include chains.
+ (cpp_finish): Add debugging code (#if 0-ed out) for the
+ include_hash.
+ (cpp_cleanup): Free the include_hash, not the import hash and
+ the all_include and dont_repeat lists which no longer exist.
+
+Wed Nov 25 11:26:19 1998 Jeffrey A Law (law@cygnus.com)
+
+ * toplev.c (no_new_pseudos): Define.
+ (rest_of_compilation): Set no_new_pseudos as needed.
+ * emit-rtl.c (gen_reg_rtx): Abort if we try to create a new pseudo
+ if no_new_pseudos is set.
+ * rtl.h (no_new_pseudos): Declare it.
+ * reload1.c (reload): Update comments.
+ * md.texi: Corresponding changes.
+
+Wed Nov 25 11:26:17 1998 Bernd Schmidt <crux@pool.informatik.rwth-aachen.de>
+
+ * reload1.c (reg_used_in_insn): Renamed from reg_used_by_pseudo.
+ (choose_reload_regs): Rename it here as well. When computing it,
+ also merge in used hardregs.
+
+1998-11-25 07:51 -0500 Zack Weinberg <zack@rabi.phys.columbia.edu>
+
+ * gcc.c: Split out Objective-C specs to...
+ * objc/lang-specs.h: here. (New file.) Make the specs cpplib
+ aware.
+
+ * c-lex.c (init_parse): Always initialize the filename global.
+ * objc/objc-act.c (lang_init): Always call check_newline at
+ beginning of file.
+
+Wed Nov 25 00:48:29 1998 Graham <grahams@rcp.co.uk>
+
+ * reload1.c (reload): Remove unused variable.
+ (reload_reg_free_for_value_p): Add missing parameter definition.
+
+ * jump.c (jump_optimize): Remove unused variable.
+
+Wed Nov 25 00:07:11 1998 Jeffrey A Law (law@cygnus.com)
+
+ * Makefile.in (graph.o): Depend on $(RTL_H), not rtl.h.
+
+ * cse.c (fold_rtx): Make autoincrement addressing mode tests be
+ runtime selectable.
+ * expr.c (move_by_pieces): Similarly.
+ (move_by_pieces_1, clear_by_pieces, clear_by_pieces_1): Similarly.
+ * flow.c (find_auto_inc): Similarly.
+ (try_pre_increment): Similarly.
+ * loop.c (strength_reduce): Similarly.
+ * regclass.c (auto_inc_dec_reg_p): Similarly.
+ * regmove.c (try_auto_increment): Similarly.
+ (fixup_match_1): Similarly.
+ * rtl.h (HAVE_PRE_INCREMENT): Define if not already defined.
+ (HAVE_PRE_DECREMENT): Similarly.
+ (HAVE_POST_INCREMENT, HAVE_POST_DECREMENT): Similarly.
+ * Corresponding changes to all target header files.
+ * tm.texi: Update docs for autoinc addressing modes.
+
+Tue Nov 24 20:24:59 1998 Jim Wilson <wilson@cygnus.com>
+
+ * configure.in (m68020-*-elf*, m68k-*-elf*): New targets.
+ * configure: Rebuild.
+ * config/elfos.h: New file.
+ * config/m68k/m68020-elf.h, config/m68k/m68kelf.h,
+ config/m68k/t-m68kelf: New file.
+
+Tue Nov 24 13:40:06 1998 Jeffrey A Law (law@cygnus.com)
+
+ * Makefile.in (HOST_AR): Define.
+ (HOST_AR_FLAGS, HOST_RANLIB, HOST_RANLIB_TEST): Similarly.
+ (libcpp.a): Use the host tools explicitly.
+ (STAGESTUFF): Add libcpp.a.
+
+Tue Nov 24 09:33:49 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/m32r/m32r.md (movstrsi_internal): Describe changes made
+ to source and destination registers.
+
+Mon Nov 23 20:28:02 1998 Mike Stump <mrs@wrs.com>
+
+ * libgcc2.c (top_elt): Remove top_elt, it isn't thread safe.
+ The strategy we now use is to pre allocate the top_elt along
+ with the EH context so that each thread has its own top_elt.
+ This is necessary as the dynmanic cleanup chain is used on the
+ top element of the stack and each thread MUST have its own.
+ (eh_context_static): Likewise.
+ (new_eh_context): Likewise.
+ (__sjthrow): Likewise.
+
+Mon Nov 23 20:25:03 1998 Jason Merrill <jason@yorick.cygnus.com>
+
+ * i386/linux.h (ASM_OUTPUT_MAX_SKIP_ALIGN): Wrap in do...while.
+ * i386.md (prologue_get_pc): Remove unused variable.
+
+Mon Nov 23 17:05:40 1998 Geoffrey Noer <noer@cygnus.com>
+
+ * i386/xm-cygwin.h: Rename cygwin_ path funcs back to cygwin32_.
+
+Mon Nov 23 16:40:00 1998 Ulrich Drepper <drepper@cygnus.com>
+
+ * Makefile.in (OBJS): Add graph.o
+ (graph.o): New dependency list.
+ * flags.h: Declare dump_for_graph and define graph_dump_types type.
+ * print-rtl.c (dump_for_graph): Define new variable.
+ (print_rtx): Rewrite to allow use in graph dumping functions.
+ * toplev.c: Declare print_rtl_graph_with_bb, clean_graph_dump_file,
+ finish_graph_dump_file.
+ Define graph_dump_format.
+ (compile_file): If graph dumping is enabled also clear these files.
+ Finish graph dump files.
+ (rest_of_compilation): Also dump graph information if enabled.
+ (main): Recognize -dv to enabled VCG based graph dumping.
+ * graph.c: New file. Graph dumping functions.
+
+Mon Nov 23 16:39:04 1998 Richard Henderson <rth@cygnus.com>
+
+ * configure.in: Look for <sys/stat.h>.
+ * system.h: Include it before substitute S_ISREG definitions.
+
+Mon Nov 23 17:40:37 1998 Gavin Romig-Koch <gavin@cygnus.com>
+
+ * config/mips/abi.h: Use ABI_O64, duplicating ABI_32 usage.
+ * config/mips/iris6.h: Same.
+ * config/mips/mips.md: Same.
+ * config/mips/mips.c: Same; also add "-mabi=o64" option.
+ * config/mips/mips.h: Same; also define ABI_O64.
+
+Mon Nov 23 17:02:27 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * configure.in: Use AC_PREREQ(2.12.1).
+
+Mon Nov 23 10:16:38 1998 "Melissa O'Neill" <oneill@cs.sfu.ca>
+
+ * cccp.c (S_ISREG, S_ISDIR): Delete defines.
+ * cpplib.c, gcc.c: Likewise.
+ * system.h (S_ISREG, S_ISDIR): Define if not already defined.
+
+Mon Nov 23 09:53:44 1998 Richard Henderson <rth@cygnus.com>
+
+ * local-alloc.c (local_alloc): Use malloc not alloca for
+ reg_qty, reg_offset, ref_next_in_qty.
+
+Mon Nov 23 16:46:46 1998 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * caller-save.c (insert_one_insn): Initialize the live_before and
+ live_after register sets.
+
+ Add SH4 support:
+
+ * config/sh/lib1funcs.asm (___movstr_i4_even, ___movstr_i4_odd): Define.
+ (___movstrSI12_i4, ___sdivsi3_i4, ___udivsi3_i4): Define.
+ * sh.c (reg_class_from_letter, regno_reg_class): Add DF_REGS.
+ (fp_reg_names, assembler_dialect): New variables.
+ (print_operand_address): Handle SUBREGs.
+ (print_operand): Added 'o' case.
+ Don't use adj_offsettable_operand on PRE_DEC / POST_INC.
+ Name of FP registers depends on mode.
+ (expand_block_move): Emit different code for SH4 hardware.
+ (prepare_scc_operands): Use emit_sf_insn / emit_df_insn as appropriate.
+ (from_compare): Likewise.
+ (add_constant): New argument last_value. Changed all callers.
+ (find_barrier): Don't try HImode load for FPUL_REG.
+ (machine_dependent_reorg): Likewise.
+ (sfunc_uses_reg): A CLOBBER cannot be the address register use.
+ (gen_far_branch): Emit a barrier after the new jump.
+ (barrier_align): Don't trust instruction lengths before
+ fixing up pcloads.
+ (machine_dependent_reorg): Add support for FIRST_XD_REG .. LAST_XD_REG.
+ Use auto-inc addressing for fp registers if doubles need to
+ be loaded in two steps.
+ Set sh_flag_remove_dead_before_cse.
+ (push): Support for TARGET_FMOVD. Use gen_push_fpul for fpul.
+ (pop): Support for TARGET_FMOVD. Use gen_pop_fpul for fpul.
+ (calc_live_regs): Support for TARGET_FMOVD. Don't save FPSCR.
+ Support for FIRST_XD_REG .. LAST_XD_REG.
+ (sh_expand_prologue): Support for FIRST_XD_REG .. LAST_XD_REG.
+ (sh_expand_epilogue): Likewise.
+ (sh_builtin_saveregs): Use DFmode moves for fp regs on SH4.
+ (initial_elimination_offset): Take TARGET_ALIGN_DOUBLE into account.
+ (arith_reg_operand): FPUL_REG is OK for SH4.
+ (fp_arith_reg_operand, fp_extended_operand) New functions.
+ (tertiary_reload_operand, fpscr_operand): Likewise.
+ (commutative_float_operator, noncommutative_float_operator): Likewise.
+ (binary_float_operator, get_fpscr_rtx, emit_sf_insn): Likewise.
+ (emit_df_insn, expand_sf_unop, expand_sf_binop): Likewise.
+ (expand_df_unop, expand_df_binop, expand_fp_branch): Likewise.
+ (emit_fpscr_use, mark_use, remove_dead_before_cse): Likewise.
+ * sh.h (CPP_SPEC): Add support for -m4, m4-single, m4-single-only.
+ (CONDITIONAL_REGISTER_USAGE): Likewise.
+ (HARD_SH4_BIT, FPU_SINGLE_BIT, SH4_BIT, FMOVD_BIT): Define.
+ (TARGET_CACHE32, TARGET_SUPERSCALAR, TARGET_HARWARD): Define.
+ (TARGET_HARD_SH4, TARGET_FPU_SINGLE, TARGET_SH4, TARGET_FMOVD): Define.
+ (target_flag): Add -m4, m4-single, m4-single-only, -mfmovd.
+ (OPTIMIZATION_OPTIONS): If optimizing, set flag_omit_frame_pointer
+ to -1 and sh_flag_remove_dead_before_cse to 1.
+ (ASSEMBLER_DIALECT): Define to assembler_dialect.
+ (assembler_dialect, fp_reg_names): Declare.
+ (OVERRIDE_OPTIONS): Add code for TARGET_SH4.
+ Hide names of registers that are not accessible.
+ (CACHE_LOG): Take TARGET_CACHE32 into account.
+ (LOOP_ALIGN): Take TARGET_HARWARD into account.
+ (FIRST_XD_REG, LAST_XD_REG, FPSCR_REG): Define.
+ (FIRST_PSEUDO_REGISTER: Now 49.
+ (FIXED_REGISTERS, CALL_USED_REGISTERS): Include values for registers.
+ (HARD_REGNO_NREGS): Special treatment of FIRST_XD_REG .. LAST_XD_REG.
+ (HARD_REGNO_MODE_OK): Update.
+ (enum reg_class): Add DF_REGS and FPSCR_REGS.
+ (REG_CLASS_NAMES, REG_CLASS_CONTENTS, REG_ALLOC_ORDER): Likewise.
+ (SECONDARY_OUTPUT_RELOAD_CLASS, SECONDARY_INPUT_RELOAD_CLASS): Update.
+ (CLASS_CANNOT_CHANGE_SIZE, DEBUG_REGISTER_NAMES): Define.
+ (NPARM_REGS): Eight floating point parameter registers on SH4.
+ (BASE_RETURN_VALUE_REG): SH4 also passes double values
+ in floating point registers.
+ (GET_SH_ARG_CLASS) Likewise.
+ Complex float types are also returned in float registers.
+ (BASE_ARG_REG): Complex float types are also passes in float registers.
+ (FUNCTION_VALUE): Change mode like PROMOTE_MODE does.
+ (LIBCALL_VALUE): Remove trailing semicolon.
+ (ROUND_REG): Round when double precision value is passed in floating
+ point register(s).
+ (FUNCTION_ARG_ADVANCE): No change wanted for SH4 when things are
+ passed on the stack.
+ (FUNCTION_ARG): Little endian adjustment for SH4 SFmode.
+ (FUNCTION_ARG_PARTIAL_NREGS): Zero for SH4.
+ (TRAMPOLINE_ALIGNMENT): Take TARGET_HARWARD into account.
+ (INITIALIZE_TRAMPOLINE): Emit ic_invalidate_line for TARGET_HARWARD.
+ (MODE_DISP_OK_8): Not for SH4 DFmode.
+ (GO_IF_LEGITIMATE_ADDRESS): No base reg + index reg for SH4 DFmode.
+ Allow indexed addressing for PSImode after reload.
+ (LEGITIMIZE_ADDRESS): Not for SH4 DFmode.
+ (LEGITIMIZE_RELOAD_ADDRESS): Handle SH3E SFmode.
+ Don't change SH4 DFmode nor PSImode RELOAD_FOR_INPUT_ADDRESS.
+ (DOUBLE_TYPE_SIZE): 64 for SH4.
+ (RTX_COSTS): Add PLUS case.
+ Increae cost of ASHIFT, ASHIFTRT, LSHIFTRT case.
+ (REGISTER_MOVE_COST): Add handling of R0_REGS, FPUL_REGS, T_REGS,
+ MAC_REGS, PR_REGS, DF_REGS.
+ (REGISTER_NAMES): Use fp_reg_names.
+ (enum processor_type): Add PROCESSOR_SH4.
+ (sh_flag_remove_dead_before_cse): Declare.
+ (rtx_equal_function_value_matters, fpscr_rtx, get_fpscr_rtx): Declare.
+ (PREDICATE_CODES): Add binary_float_operator,
+ commutative_float_operator, fp_arith_reg_operand, fp_extended_operand,
+ fpscr_operand, noncommutative_float_operator.
+ (ADJUST_COST): Use different scale for TARGET_SUPERSCALAR.
+ (SH_DYNAMIC_SHIFT_COST): Cheaper for SH4.
+ * sh.md (attribute cpu): Add value sh4.
+ (attrbutes fmovd, issues): Define.
+ (attribute type): Add values dfp_arith, dfp_cmp, dfp_conv, dfdiv.
+ (function units memory, int, mpy, fp): Make dependent on issue rate.
+ (function units issue, single_issue, load_si, load): Define.
+ (function units load_store, fdiv, gp_fpul): Define.
+ (attribute hit_stack): Provide proper default.
+ (use_sfunc_addr+1, udivsi3): Predicated on ! TARGET_SH4.
+ (udivsi3_i4, udivsi3_i4_single, divsi3_i4, divsi3_i4_single): New insns.
+ (udivsi3, divsi3): Emit special patterns for SH4 hardware,
+ (mulsi3_call): Now uses match_operand for function address.
+ (mulsi3): Also emit code for SH1 case. Wrap result in REG_LIBCALL /
+ REG_RETVAL notes.
+ (push, pop, push_e, pop_e): Now define_expands.
+ (push_fpul, push_4, pop_fpul, pop_4, ic_invalidate_line): New expanders.
+ (movsi_ie): Added y/i alternative.
+ (ic_invalidate_line_i, movdf_i4): New insns.
+ (movdf_i4+[123], reload_outdf+[12345], movsi_y+[12]): New splitters.
+ (reload_indf, reload_outdf, reload_outsf, reload_insi): New expanders.
+ (movdf): Add special code for SH4.
+ (movsf_ie, movsf_ie+1, reload_insf, calli): Make use of fpscr visible.
+ (call_valuei, calli, call_value): Likewise.
+ (movsf): Emit no-op move.
+ (mov_nop, movsi_y): New insns.
+ (blt, sge): generalize to handle DFmode.
+ (return predicate): Call emit_fpscr_use and remove_dead_before_cse.
+ (block_move_real, block_lump_real): Predicate on ! TARGET_HARD_SH4.
+ (block_move_real_i4, block_lump_real_i4, fpu_switch): New insns.
+ (fpu_switch0, fpu_switch1, movpsi): New expanders.
+ (fpu_switch+[12], fix_truncsfsi2_i4_2+1): New splitters.
+ (toggle_sz): New insn.
+ (addsf3, subsf3, mulsf3, divsf3): Now define_expands.
+ (addsf3_i, subsf3_i, mulsf3_i4, mulsf3_ie, divsf3_i): New insns.
+ (macsf3): Make use of fpscr visible. Disable for SH4.
+ (floatsisf2): Make use of fpscr visible.
+ (floatsisf2_i4): New insn.
+ (floatsisf2_ie, fixsfsi, cmpgtsf_t, cmpeqsf_t): Disable for SH4.
+ (ieee_ccmpeqsf_t): Likewise.
+ (fix_truncsfsi2): Emit different code for SH4.
+ (fix_truncsfsi2_i4, fix_truncsfsi2_i4_2, cmpgtsf_t_i4): New insns.
+ (cmpeqsf_t_i4, ieee_ccmpeqsf_t_4): New insns.
+ (negsf2, sqrtsf2, abssf2): Now expanders.
+ (adddf3, subdf3i, muldf2, divdf3, floatsidf2): New expanders.
+ (negsf2_i, sqrtsf2_i, abssf2_i, adddf3_i, subdf3_i): New insns.
+ (muldf3_i, divdf3_i, floatsidf2_i, fix_truncdfsi2_i): New insns.
+ (fix_truncdfsi2, cmpdf, negdf2, sqrtdf2, absdf2): New expanders.
+ (fix_truncdfsi2_i4, cmpgtdf_t, cmpeqdf_t, ieee_ccmpeqdf_t): New insns.
+ (fix_truncdfsi2_i4_2+1): New splitters.
+ (negdf2_i, sqrtdf2_i, absdf2_i, extendsfdf2_i4): New insns.
+ (extendsfdf2, truncdfsf2): New expanders.
+ (truncdfsf2_i4): New insn.
+ * t-sh (LIB1ASMFUNCS): Add _movstr_i4, _sdivsi3_i4, _udivsi3_i4.
+ (MULTILIB_OPTIONS): Add m4-single-only/m4-single/m4.
+ * float-sh.h: When testing for __SH3E__, also test for
+ __SH4_SINGLE_ONLY__ .
+ * va-sh.h (__va_freg): Define to float.
+ (__va_greg, __fa_freg, __gnuc_va_list, va_start):
+ Define for __SH4_SINGLE_ONLY__ like for __SH3E__ .
+ (__PASS_AS_FLOAT, __TARGET_SH4_P): Likewise.
+ (__PASS_AS_FLOAT): Use different definition for __SH4__ and
+ __SH4_SINGLE__.
+ (TARGET_SH4_P): Define.
+ (va_arg): Use it.
+
+ * sh.md (movdf_k, movsf_i): Tweak the condition so that
+ init_expr_once is satisfied about the existence of load / store insns.
+
+ * sh.md (movsi_i, movsi_ie, movsi_i_lowpart, movsf_i, movsf_ie):
+ change m constraint in source operand to mr / mf .
+
+ * va-sh.h (__va_arg_sh1): Use __asm instead of asm.
+
+ * (__VA_REEF): Define.
+ (__va_arg_sh1): Use it.
+
+ * va-sh.h (va_start, va_arg, va_copy): Add parenteses.
+
+Sun Nov 22 21:34:02 1998 Jeffrey A Law (law@cygnus.com)
+
+ * i386/dgux.c (struct option): Add new "description field".
+ * m88k/m88k.c (struct option): Likewise.
+
+Sun Nov 22 16:07:57 PST 1998 Jeff Law (law@cygnus.com)
+
+ * version.c: Bump for snapshot.
+
+Sun Nov 22 13:40:02 1998 Bernd Schmidt <crux@pool.informatik.rwth-aachen.de>
+
+ * regmove.c (regmove_profitable_p): Use return value of find_matches
+ properly.
+
+Sun Nov 22 02:47:37 PST 1998 Jeff Law (law@cygnus.com)
+
+ * version.c: Bump for snapshot.
+
+Sat Nov 21 22:12:09 1998 Jeffrey A Law (law@cygnus.com)
+
+ * reload1.c (eliminate_regs): Do not lose if eliminate_regs is called
+ without reload having been called earlier.
+
+ * v850.c (ep_memory_operand): Offsets < 0 are not valid for EP
+ addressing modes.
+ (v850_reorg): Similarly.
+
+ * loop.c (check_dbra_loop): Avoid using gen_add2_insn.
+
+Sat Nov 21 02:18:38 1998 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * loop.c (move_movables): Start of libcall might be new loop start.
+
+Fri Nov 20 12:14:16 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * hash.c (hash_table_init_n): Wrap prototype arguments in PARAMS().
+
+Fri Nov 20 08:34:00 1998 Bernd Schmidt <crux@pool.informatik.rwth-aachen.de>
+
+ * function.c (nonlocal_goto_handler_slots): Renamed from
+ nonlocal_goto_handler_slot; now an EXPR_LIST chain.
+ (push_function_context_to): Adjust for this change.
+ (pop_function_context_from): Likewise.
+ (init_function_start): Likewise.
+ (expand_function_end): Likewise.
+ * function.h (struct function): Likewise.
+ * calls.c (expand_call): Likewise.
+ * explow.c (allocate_dynamic_stack_space): Likewise.
+ * expr.h (nonlocal_goto_handler_slots): Rename its declaration.
+ * stmt.c (declare_nonlocal_label): Make a new handler slot for each
+ label.
+ (expand_goto): When doing a nonlocal goto, find corresponding handler
+ slot for it. Don't put the label address in the static chain register.
+ (expand_end_bindings): Break out nonlocal goto handling code into
+ three new functions.
+ (expand_nl_handler_label, expand_nl_goto_receiver,
+ expand_nl_goto_receivers): New static functions, broken out of
+ expand_end_bindings and adapted to create one handler per nonlocal
+ label.
+ * function.c (delete_handlers): Delete insn if it references any of
+ the nonlocal goto handler slots.
+ * i960.md (nonlocal_goto): Comment out code that modifies
+ static_chain_rtx.
+ * sparc.md (nonlocal_goto): Likewise.
+ (goto_handler_and_restore_v9): Comment out.
+ (goto_handler_and_restore_v9_sp64): Comment out.
+
+Thu Nov 19 23:44:38 1998 Bernd Schmidt <crux@pool.informatik.rwth-aachen.de>
+
+ * expr.c (STACK_BYTES): Delete unused macro.
+ * calls.c: Provide default for PREFERRED_STACK_BOUNDARY.
+ (STACK_BYTES): Use PREFERRED_STACK_BOUNDARY, not STACK_BOUNDARY.
+ (expand_call): Likewise.
+ (emit_library_call): Likewise.
+ (emit_library_call_value): Likewise.
+ * function.c: Provide default for PREFERRED_STACK_BOUNDARY.
+ (STACK_BYTES): Use PREFERRED_STACK_BOUNDARY, not STACK_BOUNDARY.
+ * explow.c: Provide default for PREFERRED_STACK_BOUNDARY.
+ (round_push): Use PREFERRED_STACK_BOUNDARY, not STACK_BOUNDARY.
+ (allocate_dynamic_stack_space): Likewise.
+ * tm.texi (PREFERRED_STACK_BOUNDARY): Document new macro.
+ (STACK_BOUNDARY): Update description to reflect the new situation.
+
+Thu Nov 19 22:20:51 1998 Jeffrey A Law (law@cygnus.com)
+
+ * reorg.c (relax_delay_slots): When optimizing for code size, if a
+ return with a filled delay slot is followed by a return with an
+ unfilled delay slot, delete the first return and reemit the insn
+ that was previously in its delay slot.
+
+ * i860.c (single_insn_src_p): Add missing parens.
+ * ginclude/math-3300.h: Likewise.
+
+Thu Nov 19 20:55:59 1998 H.J. Lu (hjl@gnu.org)
+
+ * regclass.c (init_reg_sets_1): Add prototype.
+ (init_reg_modes): Likewise.
+
+1998-11-19 Zack Weinberg <zack@rabi.phys.columbia.edu>
+
+ * c-common.c: Change warning messages to say `comparison is
+ always true' or `comparison is always false' instead of the
+ confusing `is always 0', `is always 1'.
+
+Thu Nov 19 19:05:49 1998 Per Bothner <bothner@cygnus.com>
+
+ * print-tree.c (print_node): After printing BLOCK or BIND_EXPR,
+ break instead of return (which loses closing '>').
+
+Thu Nov 19 19:34:13 1998 Jeffrey A Law (law@cygnus.com)
+
+ * i386.h (LEGITIMATE_CONSTANT_P): Reject CONST_DOUBLEs that are not
+ standard 387 constants.
+
+ * i386.md (jump): Explicitly set "memory" attribute.
+ (indirect_jump, prologue_set_stack_ptr): Likewise.
+ (prologue_get_pc_and_set_got, pop): Likewise.
+ (allocate_stack_worder, blockage, return_internal): Likewise.
+ (return_pop_internal, nop): Likewise.
+ (epilogue_set_stack_ptr, leave): Likewise.
+
+Thu Nov 19 15:42:54 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/arm/coff.h: Set USER_LABEL_PREFIX to "_".
+
+Thu Nov 19 23:20:59 1998 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * reload1.c (reload_reg_free_for_value_p):
+ Early auto_inc reloads don't conflict with outputs.
+
+Thu Nov 19 12:58:55 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * configure.in: Don't do AC_CHECK_HEADERS(wait.h sys/wait.h).
+ Instead call AC_HEADER_SYS_WAIT.
+
+ * collect2.c: Don't provide defaults for sys/wait.h macros.
+ * gcc.c: Likewise.
+ * protoize.c: Likewise. Also, don't include sys/wait.h.
+
+ * system.h: Include sys/wait.h and provide macro defaults.
+
+1998-11-19 Andreas Schwab <schwab@issan.cs.uni-dortmund.de>
+
+ * Makefile.in (mandir): Set to @mandir@.
+ (man1dir): New variable to hold the former value of $(mandir).
+ Replace all uses of $(mandir) by $(man1dir).
+
+Wed Nov 18 16:31:28 1998 Jim Wilson <wilson@cygnus.com>
+
+ * reload.c (find_reloads_address_part): If have a CONST_INT, create
+ a new one before passing it to force_const_mem.
+
+ * reload.c (find_reloads_toplev): Pass &x instead of NULL_PTR in
+ find_reloads_address call.
+
+Wed Nov 18 22:13:00 1998 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * expr.c (store_expr): Don't generate load-store pair
+ if TEMP is identical (according to ==) with TARGET.
+
+Tue Nov 17 22:25:16 1998 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * reload1.c (reload_reg_free_for_value_p): When considered reload
+ has an output, matching inputs are not sufficient to avoid conflict.
+
+Tue Nov 17 11:51:16 1998 Mark Mitchell <mark@markmitchell.com>
+
+ * hash.h (hash_table_key): New type.
+ (hash_entry): Change `string' field to generic `key'.
+ (hash_table): Add `comp' and `hash' functions.
+ (hash_table_init): Take them as input.
+ (hash_table_init_n): Likewise.
+ (hash_lookup): Modify for generic keys.
+ (hash_newfunc): Likewise.
+ (hash_traverse): Likewise.
+ (string_hash): New function.
+ (string_compare): Likewise.
+ (string_copy): Likewise.
+ * hash.c (hash_table_init_n): Modify for generic keys.
+ (hash_table_init): Likewise.
+ (hash_lookup): Likewise.
+ (hash_newfunc): Likewise.
+ (hash_traverse): Likewise.
+ (string_hash): Split out from hash_lookup.
+ (string_compare): New function.
+ (string_copy): Split out from hash_lookup.
+ * tlink.c (symbol_hash_newfunc): Modify for new interfaces to hash
+ tables.
+ (symbol_hash_lookup): Likewise.
+ (file_hash_newfunc): Likewise.
+ (file_hash_lookup): Likewise.
+ (demangled_hash_newfunc): Likewise.
+ (demangled_hash_lookup): Likewise.
+ (tlink_int): Likewise.
+ (read_repo_file): Likewise.
+ (recompile_files): Likewise.
+ (demangle_new_symbols): Likewise.
+ (scan_linker_output): Likewise.
+
+Tue Nov 17 17:13:53 1998 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * flow.c (insn_dead_p): New argument NOTES. Changed all callers.
+
+Mon Nov 16 17:56:07 1998 David Edelsohn <edelsohn@gnu.org>
+
+ * rs6000.c (output_mi_thunk): Improve test for local branch.
+
+Mon Nov 16 17:56:07 1998 Franz Sirl <Franz.Sirl-kernel@lauterbach.com>
+
+ * rs6000.c (output_mi_thunk): Correct test for aggregate values.
+
+Mon Nov 16 21:02:52 1998 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * reload1.c (reload_reg_free_before_p): Delete.
+ Changed all callers to use reload_reg_free_for_value_p instead.
+ (reload_reg_free_for_value_p): Handle more reload types.
+ A RELOAD_FOR_INPUT doesn't conflict with its
+ RELOAD_FOR_INPUT_ADDRESS / RELOAD_FOR_INPADDR_ADDRESS.
+ Add special case for OUT == const0_rtx.
+ Added ignore_address_reloads argument. Changed all callers.
+
+Mon Nov 16 02:22:29 1998 Jason Merrill <jason@yorick.cygnus.com>
+
+ * toplev.c (compile_file): Don't pedwarn about undefined static
+ functions just because we passed -Wunused.
+
+Mon Nov 16 04:41:41 1998 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * function.c (purge_addressof_1): Unshare rtl created by
+ store_bit_field.
+
+Mon Nov 16 04:23:06 1998 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * regmove.c (regmove_optimize): Don't do anything but
+ optimize_reg_copy[123] when flag_regmove is not set.
+
+Sat Nov 14 15:05:07 1998 Richard Henderson <rth@cygnus.com>
+
+ * alpha.md (addsi3, subsi3): Revise 5 Nov change to store DImode
+ value in paradoxical SImode result, rather than truncating midpoint.
+
+Fri Nov 13 22:19:23 1998 Richard Henderson <rth@cygnus.com>
+
+ * alpha.c (reg_not_elim_operand): New.
+ * alpha.h (PREDICATE_CODES): Add it.
+ * alpha.md (s48addq, s48subq patterns): Use it as the predicate
+ for the multiplicand.
+
+Fri Nov 13 22:50:37 1998 David Edelsohn <edelsohn@gnu.org>
+
+ * rs6000.md (movsf): Remove explicit secondary-reload-like
+ functionality. Only truncate SFmode store if in FPR.
+ (movsf splitters): Combine const_double splitters.
+ (movsf_hardfloat): Add GPR support.
+
+Fri Nov 13 11:02:11 1998 Stan Cox <scox@cygnus.com>
+
+ * splet.h (SUBTARGET_OVERRIDE_OPTIONS): New to
+ deprecate -mlive-g0 and -mbroken-saverestore.
+ * t-splet (MULTILIB_OPTIONS): Likewise.
+
+ * sparc.c (sparc_flat_compute_frame_size): Correctly calc args_size
+ in a leaf function. Clarify total_size/extra_size relationship.
+
+Thu Nov 12 19:20:57 1998 Geoffrey Noer <noer@cygnus.com>
+
+ * i386/cygwin32.asm: Delete.
+ * i386/cygwin.asm: New file, renamed from cygwin32.asm.
+ * i386/cygwin32.h: Delete.
+ * i386/cygwin.h: New file, renamed from cygwin32.h.
+ * i386/t-cygwin32: Delete.
+ * i386/t-cygwin: New file, renamed from t-cygwin32. Include
+ cygwin.asm instead of cygwin32.asm. Remove "32" from comment.
+ * i386/x-cygwin32: Delete.
+ * i386/x-cygwin: New file, renamed from x-cygwin32.
+ * i386/xm-cygwin32: Delete.
+ * i386/xm-cygwin: New file, renamed from xm-cygwin32. Use newly
+ renamed cygwin_ funcs for path translations.
+ * i386/win32.h: Define __CYGWIN__ when -mcygwin given.
+ * i386/winnt.c: Remove "32" from comment about cygwin.
+ * i386/mingw32.h: Fix references to cygwin32.h in light of above.
+ * rs6000/cygwin32.h: Delete.
+ * rs6000/cygwin.h: New file, renamed from cygwin32.h. Add
+ -D__CYGWIN__ to CPP_PREDEFINES.
+ * rs6000/x-cygwin32: Delete.
+ * rs6000/x-cygwin: New file, renamed from x-cygwin32.
+ * rs6000/xm-cygwin32: Delete.
+ * rs6000/xm-cygwin: New file, renamed from xm-cygwin32.
+
+ * configure.in: Check for cygwin* instead of cygwin32. Account
+ for the rename of cygwin-related config files to lose the "32"s.
+ * configure: Regenerate.
+
+ * cccp.c, collect2.c, gcc.c, getpwd.c, libgcc2.c, protoize.c,
+ toplev.c: Change all refs to __CYGWIN32__ to __CYGWIN__.
+
+Wed Nov 11 12:25:19 1998 Tom Tromey <tromey@cygnus.com>
+
+ * Makefile.in (JAVAGC): New macro.
+ * configure: Rebuilt.
+ * configure.in: Recognize --enable-java-gc argument. Subst
+ `JAVAGC' variable.
+
+Thu Nov 12 03:32:16 1998 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ Handle equivalences that have been obscured by gcse:
+
+ * reload1.c (reload): Handle equivalences set up in multiple places.
+ * local-alloc.c (reg_equiv_init_insns): New variable.
+ (no_equiv): New function.
+ (update_equiv_regs): Handle equivalences set up in multiple places.
+ Don't ignore an insn just because its destination is likely to be
+ spilled.
+
+Wed Nov 11 13:46:13 1998 Jim Wilson <wilson@cygnus.com>
+
+ * except.c (expand_eh_return): Readd force_operand call lost in
+ Sept 15 change.
+
+Tue Nov 10 17:04:11 1998 David Edelsohn <edelsohn@gnu.org>
+
+ * rs6000.h (LEGITIMIZE_ADDRESS): Add missing goto on last case.
+
+1998-11-09 Andreas Schwab <schwab@issan.cs.uni-dortmund.de>
+
+ * dbxout.c: Check HAVE_STAB_H instead of HAVE_STABS_H.
+
+Mon Nov 9 20:15:19 1998 Bernd Schmidt <crux@pool.informatik.rwth-aachen.de>
+
+ * regmove.c (regmove_optimize): Fix error in last change.
+
+Mon Nov 9 16:37:52 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mips.c (function_prologue): When TARGET_MIPS16, adjust the register
+ offset in the .mask pseudo to compensate for frame pointer adjustments.
+ (mips16_fp_args, build_mips16_call_stub): For little endian, do not
+ word swap arguments moved to/from FP registers.
+ * mips16.S (DFREVCMP): Reverse arguments to OPCODE.
+
+Mon Nov 9 09:47:06 PST 1998 Jeff Law (law@cygnus.com)
+
+ * version.c: Bump for snapshot.
+
+Mon Nov 9 02:14:14 PST 1998 Jeff Law (law@cygnus.com)
+
+ * version.c: Bump for snapshot.
+
+Mon Nov 9 03:06:24 1998 Jeffrey A Law (law@cygnus.com)
+
+ * reload1.c (delete_output_reload_insn): If a pseudo is set multiple
+ times, then it can not be completely replaced.
+
+Mon Nov 9 00:39:02 1998 Richard Henderson <rth@cygnus.com>
+
+ * alpha.md (call, call_value) [OSF]: Correct alt 3 insn length.
+
+Sun Nov 8 17:50:30 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * gansidecl.h: Prepend a "G" to the macro wrapping this file
+ (to distinguish it from the macro wrapping ansidecl.h.)
+ Include libiberty's ansidecl.h. Remove all redundant definitions.
+ Define the PROTO() style macros in terms of the PARAMS() ones.
+
+
+ * calls.c (emit_library_call): Switch on ANSI_PROTOTYPES, not
+ __STDC__, when deciding whether to use ANSI variable args.
+ (emit_library_call_value): Likewise.
+
+ * cccp.c (error): Likewise.
+ (warning): Likewise.
+ (error_with_line): Likewise.
+ (warning_with_line): Likewise.
+ (pedwarn): Likewise.
+ (pedwarn_with_line): Likewise.
+ (pedwarn_with_file_and_line): Likewise.
+ (fatal): Likewise.
+
+ * cexp.y (error): Likewise.
+ (pedwarn): Likewise.
+ (warning): Likewise.
+
+ * collect2.c (fatal_perror): Likewise.
+ (fatal): Likewise.
+ (error): Likewise.
+
+ * combine.c (gen_rtx_combine): Likewise.
+
+ * cpperror.c (cpp_message): Likewise.
+ (cpp_fatal): Likewise.
+
+ * cpplib.c (cpp_error): Likewise.
+ (cpp_warning): Likewise.
+ (cpp_pedwarn): Likewise.
+ (cpp_error_with_line): Likewise.
+ (cpp_warning_with_line): Likewise.
+ (cpp_pedwarn_with_line): Likewise.
+ (cpp_pedwarn_with_file_and_line): Likewise.
+
+ * cpplib.h: Don't define PARAMS() macro.
+
+ * demangle.h: Likewise.
+
+ * doprint.c (checkit): Switch on ANSI_PROTOTYPES, not __STDC__,
+ when deciding whether to use ANSI variable args.
+
+ * emit-rtl.c (gen_rtx): Likewise.
+ (gen_rtvec): Likewise.
+
+ * final.c (asm_fprintf): Likewise.
+
+ * fix-header.c (cpp_message): Likewise.
+ (fatal): Likewise.
+ (cpp_fatal): Likewise.
+
+ * gcc.c (concat): Likewise.
+ (fatal): Likewise.
+ (error): Likewise.
+
+ * genattr.c (fatal): Likewise.
+
+ * genattrtab.c (attr_rtx): Likewise.
+ (attr_printf): Likewise.
+ (fatal): Likewise.
+
+ * gencodes.c (fatal): Likewise.
+
+ * genconfig.c (fatal): Likewise.
+
+ * genemit.c (fatal): Likewise.
+
+ * genextract.c (fatal): Likewise.
+
+ * genflags.c (fatal): Likewise.
+
+ * genopinit.c (fatal): Likewise.
+
+ * genoutput.c (fatal): Likewise.
+ (error): Likewise.
+
+ * genpeep.c (fatal): Likewise.
+
+ * genrecog.c (fatal): Likewise.
+
+ * halfpic.h: Switch on ANSI_PROTOTYPES, not __STDC__, when
+ deciding whether to declare `tree_node' and `rtx_def'.
+
+ * hash.h: Don't define stuff we get from gansidecl.h.
+
+ * mips-tfile.c: Likewise. Define __proto() in terms of PARAMS().
+ (fatal): Switch on ANSI_PROTOTYPES, not __STDC__, when deciding
+ whether to use ANSI variable args.
+ (error): Likewise.
+
+ * prefix.c (concat): Likewise.
+
+ * scan.h: Likewise.
+
+ * system.h: Likewise.
+
+ * toplev.c (error_with_file_and_line): Likewise.
+ (error_with_decl): Likewise.
+ (error_for_asm): Likewise.
+ (error): Likewise.
+ (fatal): Likewise.
+ (warning_with_file_and_line): Likewise.
+ (warning_with_decl): Likewise.
+ (warning_for_asm): Likewise.
+ (warning): Likewise.
+ (pedwarn): Likewise.
+ (pedwarn_with_decl): Likewise.
+ (pedwarn_with_file_and_line): Likewise.
+ (sorry): Likewise.
+ (really_sorry): Likewise.
+
+ * toplev.h: Switch on ANSI_PROTOTYPES, not __STDC__, when deciding
+ whether to declare `tree_node' and `rtx_def'.
+
+ * tree.c (build): Switch on ANSI_PROTOTYPES, not __STDC__, when
+ deciding whether to use ANSI variable args.
+ (build_nt): Likewise.
+ (build_parse_node): Likewise.
+
+Sun Nov 8 13:10:55 PST 1998 Jeff Law (law@cygnus.com)
+
+ * version.c: Bump for snapshot.
+
+Sat Nov 7 23:34:01 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * Makefile.in (libcpp.a): Check RANLIB_TEST before runing RANLIB.
+
+Sat Nov 7 22:26:19 1998 David Edelsohn <edelsohn@gnu.org>
+
+ * collect2.c (main, case 'b'): Use else if.
+
+Sat Nov 7 15:35:25 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * configure.in (host_xm_file, build_xm_file, xm_file, tm_file):
+ Arrange to include gansidecl.h in {ht}config.h & tm.h just
+ before the config/ directory headers.
+ (tm_file_list, host_xm_file_list, build_xm_file_list): Handle
+ gansidecl.h in the list of dependencies.
+
+ * Makefile.in (RTL_BASE_H): Don't depend on gansidecl.h.
+ (TREE_H, DEMANGLE_H, RECOG_H, REGS_H, libgcc2.a, stmp-multilib,
+ mbchar.o, collect2.o, pexecute.o, vfprintf.o, splay-tree.o, gcc.o,
+ gencheck.o, choose-temp.o, mkstemp.o, mkstemp.o, prefix.o,
+ dyn-string.o, cexp.o, cccp.o, cppmain.o, cpplib.o, cpperror.o,
+ cppexp.o, cppfiles.o, cpphash.o, cppalloc.o, scan-decls.o):
+ Likewise.
+
+ * cccp.c: Don't include gansidecl.h.
+ * cexp.y: Likewise.
+ * collect2.c: Likewise.
+ * config/c4x/c4x.c: Likewise.
+ * config/v850/v850.h: Likewise.
+ * cppalloc.c: Likewise.
+ * cpperror.c: Likewise.
+ * cppexp.c: Likewise.
+ * cppfiles.c: Likewise.
+ * cpphash.c: Likewise.
+ * cpplib.c: Likewise.
+ * cppmain.c: Likewise.
+ * cppulp.c: Likewise.
+ * demangle.h: Likewise.
+ * doprint.c: Likewise.
+ * dyn-string.c: Likewise.
+ * eh-common.h: Likewise.
+ * fix-header.c: Likewise.
+ * frame.c: Likewise.
+ * gcc.c: Likewise.
+ * gcov.c: Likewise.
+ * gen-protos.c: Likewise.
+ * gencheck.c: Likewise.
+ * halfpic.h: Likewise.
+ * hash.c: Likewise.
+ * machmode.h: Likewise.
+ * mbchar.c: Likewise.
+ * prefix.c: Likewise.
+ * protoize.c: Likewise.
+ * recog.h: Likewise.
+ * rtl.h: Likewise.
+ * scan-decls.c: Likewise.
+ * tree.h: Likewise.
+ * varray.h: Likewise.
+
+Sat Nov 7 11:37:53 1998 Richard Henderson <rth@cygnus.com>
+
+ * i386.md (call_value_pop): If we're not popping anything,
+ defer to call_value.
+ (call_pop): Likewise defer to call.
+
+Sat Nov 7 02:49:56 1998 Richard Henderson <rth@cygnus.com>
+
+ * function.c (purge_addressof): Clear purge_addressof_replacements
+ only after processing the whole function.
+
+Sat Nov 7 00:54:55 1998 Jeffrey A Law (law@cygnus.com)
+
+ * reload1.c (reload): If we can not perform a particular elimination
+ when we thought we could earlier, then we must always iterate through
+ the loop at least one more time.
+
+Fri Nov 6 19:37:33 1998 Richard Henderson <rth@cygnus.com>
+
+ * alpha.c (add_operand): Simplify the CONST_INT match.
+ (sext_add_operand): Correct typo in comparison by using
+ CONST_OK_FOR_LETTER_P.
+ * alpha.md (s?addq): Use sext_add_operand to allow the negative
+ constant alternatives to be generated.
+ (mulsi3, muldi3, umuldi3_highpart): Loosen constraints to allow
+ small constants, since the hw instructions do.
+
+Fri Nov 6 20:15:19 1998 Bernd Schmidt <crux@pool.informatik.rwth-aachen.de>
+
+ * reload1.c (emit_reload_insns): When rewriting the SET_DEST of a
+ previous insn to store directly into our reload register, make sure
+ that if the source of the previous insn is a reload register, its
+ spill_reg_store and spill_reg_stored_to values are cleared.
+
+Fri Nov 6 16:35:10 1998 David Edelsohn <edelsohn@gnu.org>
+
+ * rs6000.md (floatunssidf2_internal splitter): Use base register
+ operand, not hard-coded SP.
+
+Fri Nov 6 04:07:53 1998 David S. Miller <davem@pierdol.cobaltmicro.com>
+
+ * jump.c (calculate_can_reach_end): Fix thinko.
+
+Fri Nov 6 00:16:04 1998 Jeffrey A Law (law@cygnus.com)
+
+ * reorg.c (fill_simple_delay_slots): Fix typo.
+
+ * romp.h (LEGITIMIZE_ADDRESS): Fix typo.
+
+Fri Nov 6 00:10:00 1998 Jan Hubicka (hubicka@freesoft.cz)
+
+ * i386.md (extendsidi2): Use # in the output template.
+ (extendsidi splitters): New splitters.
+
+Thu Nov 5 11:13:27 1998 Nick Clifton <nickc@cygnus.com>
+
+ * configure.in: Use unknown-elf.h as tm_file for arm-elf
+ configuarions.
+ * configure: Regenerate.
+
+Thu Nov 5 07:59:05 1998 David S. Miller <davem@pierdol.cobaltmicro.com>
+
+ * jump.c (init_label_info, delete_barrier_successors,
+ mark_all_labels, delete_unreferenced_labels,
+ delete_noop_moves, calculate_can_reach_end): New functions broken
+ out of jump_optimize.
+ (jump_optimize): Use them.
+
+Thu Nov 5 07:57:45 EST 1998 Andrew MacLeod <amacleod@cygnus.com>
+
+ * except.c (expand_fixup_region_end): Make sure outer context labels
+ are not issued in an inner context during cleanups.
+
+Thu Nov 5 04:03:06 1998 Richard Henderson <rth@cygnus.com>
+
+ * alpha.md (addsi3, subsi3): No new temporaries once cse is
+ no longer expected.
+
+Thu Nov 5 03:29:19 1998 Richard Henderson <rth@cygnus.com>
+
+ * alpha.md (addsi3, subsi3): Expand to a DImode temporary so as
+ to expose this midpoint to CSE.
+
+Thu Nov 5 03:42:54 1998 David S. Miller <davem@pierdol.cobaltmicro.com>
+
+ * config/sparc/sparc.md (movdf_const_intreg_sp64): Enable again.
+
+Thu Nov 5 10:53:01 1998 Andreas Schwab <schwab@issan.cs.uni-dortmund.de>
+
+ * configure.in: Bring over gcc2 change of Nov 19 1997.
+
+Wed Nov 4 23:43:08 1998 Graham <grahams@rcp.co.uk>
+
+ * toplev.c (output_lang_identify): Make definition dependent on
+ ASM_IDENTIFY_LANGUAGE.
+
+ * print-rtl.c (spaces): Make static.
+
+Wed Nov 4 22:16:36 1998 Hans-Peter Nilsson <hp@axis.se>
+
+ * extend.texi: Clarify proper uses for register clobbers in asms.
+
+Wed Nov 4 22:16:36 1998 Bernd Schmidt <crux@pool.informatik.rwth-aachen.de>
+
+ * recog.h (enum op_type): Define.
+ (constrain_operands): Adjust prototype.
+ (recog_op_type): Declare new variable.
+ * recog.c (recog_op_type): New variable.
+ (insn_invalid_p): Allow modifying an asm statement after reload.
+ (extract_insn): Set up recog_op_type.
+ (constrain_operands): Lose INSN_CODE_NUM arg. All callers changed.
+ Don't compute operand types, use recog_op_type.
+ Use the information computed by extract_insn instead of the previous
+ method of finding it by insn code number.
+ * caller-save.c (init_caller_save): Use extract_insn, not insn_extract.
+ * reorg.c (fill_slots_from_thread): Likewise.
+ * reload1.c (reload_as_needed): Likewise.
+ (gen_reload): Likewise.
+ (inc_for_reload): Likewise.
+ (reload_cse_simplify_operands): Likewise.
+ Use the information computed by extract_insn instead of the previous
+ method of finding it by insn code number.
+ * genattrtab.c (write_attr_case): Generate call to extract_insn, not
+ insn_extract.
+ * final.c (final_scan_insn): Use extract_insn, not insn_extract.
+ (cleanup_operand_subregs): Use extract_insn, not insn_extract.
+ Use the information computed by extract_insn instead of the previous
+ method of finding it by insn code number.
+ * regmove.c (find_matches): Likewise. Change meaning of the return
+ value to be nonzero if the optimization can be performed, zero if
+ not. All callers changed.
+ Shorten some variable names to fix formatting problems.
+ (regmove_optimize): Shorten some variable names to fix formatting
+ problems.
+ Use the information computed by extract_insn instead of the previous
+ method of finding it by insn code number.
+ * regclass.c (scan_one_insn): Likewise.
+ (record_reg_classes): Don't compute operand types, use recog_op_type.
+ * reload.c (find_reloads): Lose CONSTRAINTS1 variable; use
+ recog_constraints instead.
+
+Wed Nov 4 21:37:46 1998 Jeffrey A Law (law@cygnus.com)
+
+ * rtl.h (flow2_completed): Declare.
+ * flow.c (flow2_completed): Definition.
+ * toplev.c (rest_of_compilation): Set and clear flow2_completed
+ as necessary.
+
+Wed Nov 4 19:15:37 1998 "Melissa O'Neill" <oneill@cs.sfu.ca>
+
+ * Makefile.in (libcpp.a): Ranlib libcpp.a
+
+ * cppulp.c (user_label_prefix): Initialize.
+
+Wed Nov 4 19:07:08 1998 John Wehle (john@feith.com)
+
+ * flow.c (mark_regs_live_at_end): Mark the stack pointer as live
+ at a RETURN if current_function_sp_is_unchanging is set.
+
+Wed Nov 4 18:16:29 1998 Herman A.J. ten Brugge <Haj.Ten.Brugge@net.HCC.nl>
+
+ * emit-rtl.c (try_split): Fixed error in Oct 10 patch.
+
+Wed Nov 4 15:11:15 1998 Geoffrey Noer <noer@cygnus.com>
+
+ * i386/cygwin32.h (MASK_WIN32, MASK_CYGWIN, MASK_WINDOWS, MASK_DLL,
+ TARGET_WIN32, TARGET_CYGWIN, TARGET_WINDOWS, TARGET_DLL): New.
+ (SUBTARGET_SWITCHES): Add -mno-cygwin, -mcygwin, and -mdll options.
+ (CPP_PREDEFINES): Don't define __CYGWIN32__ here.
+ (STARTFILE_SPEC): Handle -mdll, -mno-cygwin options.
+ (CPP_SPEC): Handle -mno-cygwin option. Define __CYWIN__ in addition
+ to __CYGWIN32__.
+ (LIB_SPEC): Handle -mno-cyginw option.
+ (LINK_SPEC): Handle -mdll.
+
+Wed Nov 4 22:56:14 1998 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * reload.c (find_reloads): Fix test for usage by other reload
+ to handle secondary reloads properly.
+
+Wed Nov 4 17:25:10 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * reload1.c (ELIMINABLE_REGS, NUM_ELIMINABLE_REGS): Introduce an
+ intermediate structure which has exactly the members provided by
+ ELIMINABLE_REGS. Define NUM_ELIMINABLE_REGS in terms of the
+ static intermediate structure.
+
+ (init_elim_table): Xmalloc() `reg_eliminate', and initialize it
+ from the intermediate structure. Do the same analogous fix in
+ the case where ELIMINABLE_REGS is not defined.
+
+Tue Nov 3 20:50:03 1998 Jeffrey A Law (law@cygnus.com)
+
+ * pa.h (SELECT_SECTION): Fix thinko.
+
+Tue Nov 3 17:51:36 1998 Jim Wilson <wilson@cygnus.com>
+
+ * dwarf2out.c (output_call_frame_info): Comments on last change.
+
+Tue Nov 3 07:51:43 1998 Richard Earnshaw (rearnsha@arm.com)
+
+ * arm.c (add_constant): When taking the address of an item in the
+ pool, get the mode of the item addressed.
+
+ * arm.c (final_prescan_insn case INSN): If an insn doesn't
+ contain a SET or a PARALLEL, don't consider it for conditional
+ execution.
+
+ Restore ABI compatibility for NetBSD.
+ * arm/netbsd.h (DEFAULT_PCC_STRUCT_RETURN): Override setting in
+ arm.h
+ (RETURN_IN_MEMORY): Likewise.
+
+Mon Nov 2 11:46:17 1998 Doug Evans <devans@canuck.cygnus.com>
+
+ * m32r/m32r.c (m32r_expand_block_move): Fix byte count computations.
+ (m32r_output_block_move): Rewrite bytes < 4 handling.
+
+Mon Nov 2 10:10:35 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * configure.in: Call AC_FUNC_VFORK.
+
+ * collect2.c: Define VFORK_STRING as a printable string for
+ error messages (either "vfork" or "fork".) If HAVE_VFORK_H is
+ defined, include vfork.h. If VMS is defined, define vfork()
+ appropriately. Remove vfork check on USG, we're using autoconf.
+ (collect_execute): Pass VFORK_STRING to fatal_perror instead of
+ checking locally what string to pass.
+ (scan_prog_file): Likewise.
+ (scan_libraries): Likewise.
+
+ * gcc.c: Remove vfork check on USG, we're using autoconf.
+ Besides, no calls to vfork/fork occur in this file.
+
+ * protoize.c: Likewise.
+
+Mon Nov 2 07:52:28 1998 Alexandre Oliva <oliva@dcc.unicamp.br>
+
+ * configure.in (DEFAULT_LINKER): renamed from LD
+ (DEFAULT_ASSEMBLER): renamed from AS; reverted Schwab's patch
+ (gcc_cv_as): try $DEFAULT_ASSEMBLER before $AS
+ * configure: rebuilt
+
+Mon Nov 2 01:48:10 1998 Alexandre Oliva <oliva@dcc.unicamp.br>
+
+ * BUGS: fix the regexp for `more' to find the appropriate node.
+ Reported by Joerg Pietschmann <joerg_pietschmann@zkb.ch>
+
+ * BUGS: added link to the WWW FAQ
+
+Sun Nov 1 18:27:15 PST 1998 Jeff Law (law@cygnus.com)
+
+ * version.c: Bump for snapshot.
+
+Sun Nov 1 11:04:32 1998 Jeffrey A Law (law@cygnus.com)
+
+ * From Christian Gafton:
+ * i386/linux.h (CPP_PREDEFINES): Add -D__i386__.
+ * sparc/linux.h (CPP_PREDEFINES): Add -D__sparc__.
+ * sparc/linux64.h (CPP_PREDEFINES): Add -D__sparc__.
+
+Sat Oct 31 21:42:39 1998 Mark Mitchell <mark@markmitchell.com>
+
+ * c-common.c (c_get_alias_set): Allow all type-punning through
+ unions. Don't get confused about the type of a bit-field, despite
+ the antics of build_modify_expr.
+
+Sat Oct 31 22:35:29 1998 Jean-Pierre Radley <jpr@jpr.com>
+
+ * fixinc.sco: Paramaterize #include_next values.
+ * fixinc/fixinc.sco: Likewise.
+
+Sat Oct 31 20:39:35 1998 Jeffrey A Law (law@cygnus.com)
+
+ * toplev.c (rest_of_compilation): No longer set reload_completed.
+ * reload1.c (reload): Set it here. Perform instruction splitting
+ after reload has completed if we will be running the scheduler
+ again.
+
+Sat Oct 31 12:30:02 1998 Jeffrey A Law (law@cygnus.com)
+
+ * jump.c (jump_optimize): Initialize mappings from INSN_UID to
+ EH region if exceptions are enabled and we're performing cross
+ jump optimizations.
+ (find_cross_jump): Exit loop if the insns are in different EH regions.
+
+Sat Oct 31 10:02:48 1998 Mark Mitchell <mark@markmitchell.com>
+
+ * dwarf2out.c (output_call_frame_info): Use
+ ASM_OUTPUT_DWARF_DELTA4 for the CIE offset to match frame.c.
+
+Sat Oct 31 10:23:14 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ Reinstall Apr 24th fix, lost during May 6th gcc2 merge:
+ * c-common.c (check_format_info): Don't check for the 'x'
+ format character twice, instead check for 'x' and 'X'
+
+Fri Oct 30 14:50:25 1998 Jeffrey A Law (law@cygnus.com)
+
+ * configure.in (assembler features): Also make gas is configured if
+ we find it in the souce tree.
+
+Fri Oct 30 13:23:20 1998 Richard Henderson <rth@cygnus.com>
+
+ * i386.c (i386_comp_type_attributes): Compare whether the
+ attributes are defined, not their tree nodes.
+
+Fri Oct 30 11:39:47 1998 Alexandre Oliva <oliva@dcc.unicamp.br>
+
+ * configure.in (gxx_include_dir): bitten by autoconf quoting
+ characters :-(
+ * configure: rebuilt
+
+Fri Oct 30 10:43:29 1998 Andreas Schwab <schwab@issan.cs.uni-dortmund.de>
+
+ * configure.in: Ignore non-absolute value in $AS.
+
+Fri Oct 30 00:54:25 1998 Peter Jakubek <pjak@snafu.de>
+
+ * m68k.h (INDIRECTABLE_1_ADDRESS_P): Fix thinko.
+
+Fri Oct 30 00:42:34 1998 Mark Elbrecht <snowball3@usa.net>
+
+ * configure.in (msdosdjgpp): Set exeext and target_alias.
+
+Thu Oct 29 23:55:43 1998 Bernd Schmidt <crux@pool.informatik.rwth-aachen.de>
+
+ * flow.c (XNMALLOC): New macro.
+ (flow_int_list_blocks, basic_block_succ, basic_block_pred): New
+ static variables.
+ (add_edge, add_edge_to_label): New static functions.
+ (free_bb_memory): New function.
+ (flow_delete_insn): Delete function.
+ (basic_block_drops_in): Delete variable.
+ (find_basic_blocks): Allocate and initialize basic_block_head,
+ basic_block_succ. Don't allocate basic_block_drops_in.
+ Call free_bb_memory at the beginning.
+ (find_basic_blocks_1): Don't do multiple passes.
+ Delete code to compute basic_block_drops_in.
+ After calling make_edges, mark blocks reached by current block live.
+ Update test for unreachable live blocks.
+ (mark_label_ref): Delete args X, CHECKDUP. Add PRED arg. All callers
+ changed.
+ Simplify to call add_edge_to_label when a LABEL_REF is found.
+ (make_edges): Simplify to call add_edge_to_label instead of
+ mark_label_ref most of the time.
+ Compute here whether control drops into the next block.
+ (delete_unreachable_blocks): Return void. All callers changed.
+ Delete unreachable blocks in reverse order.
+ After deleting all unreachable blocks, renumber the remaining ones
+ and update n_basic_blocks.
+ (delete_block): Speed up deletion a bit.
+ Don't set basic_block_drops_in for deleted blocks.
+ (free_basic_block_vars): Don't free basic_block_drops_in.
+ (life_analysis_1): Update to use new edge representation.
+ (dump_flow_info): Delete code to print basic block info; call
+ dump_bb_data instead.
+ (compute_preds_succs): Delete code to recompute basic_block_drops_in
+ and uid_block_number.
+ Simply copy the previously computed cfg.
+ (dump_bb_data): New arg LIVE_INFO. All callers changed.
+ Print register lifetime information if LIVE_INFO is nonzero.
+ * basic-block.h (dump_bb_data): Adjust prototype.
+ * gcse.c (gcse_main): Update call to dump_bb_data.
+ * rtl.h (free_bb_memory): Declare.
+ * toplev.c (rest_of_compilation): Call free_bb_memory.
+
+ * reload1.c (struct elim_table): Delete MAX_OFFSET member.
+ (update_eliminable_offsets): Don't compute it.
+ (set_initial_elim_offsets): Don't initialize it.
+ Break out some code into set_initial_label_offsets so the rest of
+ this function can be called from reload_as_needed.
+ Assume that INITIAL_FRAME_POINTER_OFFSET is defeined when
+ ELIMINABLE_REGS isn't.
+ (set_initial_label_offsets): New function, broken out of
+ set_initial_elim_offsets.
+ (set_offsets_for_label): New function, broken out of set_label_offsets
+ and reload_as_needed.
+ (reload): Call the two new functions.
+ (reload_as_needed): Call set_initial_elim_offsets instead of
+ duplicating the code. Likewise for set_offsets_for_label.
+
+ * reload1.c (choose_reload_regs): Fix typo in Oct 17 change.
+ (emit_reload_insns): Ensure that when we set reg_reloaded_valid for
+ any hard reg, reg_reloaded_dead contains valid data.
+
+Thu Oct 29 22:30:54 1998 Marcus Meissner <Marcus.Meissner@informatik.uni-erlangen.de>
+
+ * i386.c (i386_comp_type_attributes): Return nonzero for mismatched
+ "stdcall" and "cdecl" attributes.
+
+Thu Oct 29 19:05:17 1998 Jim Wilson <wilson@cygnus.com>
+
+ * sched.c (update_flow_info): Add code to ! found_orig_dest case to
+ handle deleted no-op moves of hard registers.
+ * haifa-sched.c (update_flow_info): Likewise.
+
+Thu Oct 29 18:07:47 1998 Jeffrey A Law (law@cygnus.com)
+
+ * mips.md (reload_{in,out}{si,di}): Emit a USE of HILO at the end
+ of the sequences to reload the HILO register which do not actually
+ reference HILO.
+
+Thu Oct 29 12:39:35 1998 Jim Wilson <wilson@cygnus.com>
+
+ * c-common.c (c_get_alias_set): Handle ARRAY_REF of union field.
+
+Thu Oct 29 14:10:22 EST 1998 Andrew MacLeod <amacleod@cygnus.com>
+
+ * except.c (emit_eh_context): Make the EH context register stay alive
+ at -O0 so stupid.c doesn't get confused.
+
+1998-10-29 Herman A.J. ten Brugge <Haj.Ten.Brugge@net.HCC.nl>
+
+ * emit-rtl.c (try_split): Do not try to split a BARRIER.
+
+Thu Oct 29 01:33:54 1998 Jan Hubicka <hubicka@freesoft.cz>
+ Jeffrey A Law (law@cygnus.com)
+
+ * i386.md: Change ix86_cpu == PROCESSOR_PENTIUM to TARGET_PENTIUM
+ (zero_extendsidi2): Use # in output template and handle completely by
+ splits.
+ (zero_extend splitters): New define_splits.
+ (ashiftrt_32): New pattern.
+
+Wed Oct 28 22:58:35 1998 Jason Merrill <jason@yorick.cygnus.com>
+
+ * tree.c (append_random_chars): New fn.
+ (get_file_function_name_long): Use it.
+
+Wed Oct 28 22:27:05 1998 Richard Henderson <rth@cygnus.com>
+
+ * Makefile.in (cc1): Put C_OBJS, and thence @extra_c_objs@ last.
+ (LIBCPP_OBJS): New. Add cppulp.o.
+ (cppmain, fix-header): Depend on and use libcpp.a.
+ * configure.in (extra_c_objs, extra_cxx_objs): Use libcpp.a instead
+ of the individual object files.
+ * objc/Make-lang.in (cc1obj): Put OBJC_OBJS, and thence @extra_c_objs@,
+ last.
+
+ * cccp.c (user_label_prefix): New.
+ (main): Set it off -f*leading-underscore.
+ (special_symbol): Use it.
+ * cpplib.c (special_symbol): Likewise.
+ (cpp_handle_option): Handle -f*leading-underscore.
+ * cppulp.c: New file.
+
+ * output.h (user_label_prefix): Declare it.
+ * dwarf2out.c (ASM_NAME_TO_STRING): Prepend user_label_prefix.
+ * toplev.c (f_options, main): Handle -f*leading-underscore.
+
+ * defaults.h (ASM_OUTPUT_LABELREF): Use asm_fprintf instead of
+ referencing USER_LABEL_PREFIX directly.
+ * config/nextstep.h (ASM_OUTPUT_LABELREF): Likewise.
+ * m32r/m32r.h (ASM_OUTPUT_LABELREF): Likewise.
+ * final.c (asm_fprintf): Use user_label_prefix instead.
+ * arm/thumb.c (thumb_print_operand): Likewise.
+
+ * gcc.c (default_compilers): Pass -f*leading-underscore on to
+ cpp wherever appropriate.
+
+Wed Oct 28 23:09:25 1998 Robert Lipe <robertl@dgii.com>
+
+ * sco5.h (SUBTARGET_SWITCHES): Add documentation for OpenServer-
+ specific compiler switches.
+
+Wed Oct 28 21:05:53 1998 Jeffrey A Law (law@cygnus.com)
+
+ * Makefile.in (c-common.o): Depend on c-pragma.h. Use $(RTL_H) instead
+ of rtl.h.
+
+Wed Oct 28 20:52:47 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * gcc.c (EXTRA_SPECS, extra_specs): Introduce an intermediate
+ structure which has exactly the members provided by EXTRA_SPECS.
+ Xmalloc() the real `extra_specs', and initialize it from this
+ intermediate structure.
+
+ * alpha.h (EXTRA_SPECS): Revert change for missing initializers.
+
+ * mips.h (EXTRA_SPECS): Likewise.
+
+ * sparc.h (EXTRA_SPECS): Likewise.
+
+Wed Oct 28 16:46:07 1998 Andreas Schwab <schwab@issan.cs.uni-dortmund.de>
+
+ * function.c (purge_addressof_1): Instead of aborting when a
+ bitfield insertion as a replacement for (MEM (ADDRESSOF)) does not
+ work just put the ADDRESSOF on stack. Otherwise remember all such
+ successfull replacements, so that exactly the same replacements
+ can be made on the REG_NOTEs. Remove the special case for CALL
+ insns again.
+ (purge_addressof_replacements): New variable.
+ (purge_addressof): Clear it at end.
+
+1998-10-28 16:10 -0500 Zack Weinberg <zack@rabi.phys.columbia.edu>
+
+ * c-lang.c: Declare extern char *yy_cur if USE_CPPLIB.
+ (lang_init): Call check_newline always.
+ * c-lex.c (init_parse) [USE_CPPLIB=1]: After calling
+ cpp_start_read, set yy_cur and yy_lim to read from
+ parse_in.token_buffer, so that we'll see the first #line
+ directive.
+ * cpplib.c (cpp_start_read): finclude the main input file
+ before processing -include/-imacros. Process -imacros and
+ -include separately, and handle -include by stacking a
+ buffer for the file in question as if it'd been #included.
+ * toplev.c (documented_lang_options) Recognize -H when
+ USE_CPPLIB is on.
+
+1998-10-28 16:09 -0500 Zack Weinberg <zack@rabi.phys.columbia.edu>
+
+ * cpplib.c: Merge do_once into do_pragma. Break file handling
+ code out of do_include.
+ Move append_include_chain, deps_output,
+ file_cleanup, redundant_include_p, import_hash,
+ lookup_import, add_import, read_filename_string, read_name_map,
+ open_include_file, finclude, safe_read to cppfiles.c.
+ Move prototypes for deps_output, append_include_chain,
+ finclude to cpplib.h. Move definition of struct
+ file_name_list there also.
+
+ * cppfiles.c: New file. Contains all the above functions
+ broken out of cpplib.c; also hack_vms_include_specification
+ from cccp.c and find_include_file, a new function broken out of
+ do_include.
+
+ * Makefile.in (cppmain): Depend on cppfiles.o.
+ (fix-header): Likewise.
+ (cppfiles.o): New target.
+ * configure.in (--enable-c-cpplib): Add cppfiles.o to
+ extra_c_objs. Add ../cppfiles.o to extra_cxx_objs.
+
+Wed Oct 28 14:06:49 1998 Jim Wilson <wilson@cygnus.com>
+
+ * dwarfout.c (dwarfout_file_scope_decl): If DECL_CONTEXT, don't abort
+ if pending_types is non-zero.
+ (dwarfout_finish): Verify pending_types is zero before finishing.
+
+Wed Oct 28 10:29:09 1998 Nick Clifton <nickc@cygnus.com>
+
+ * expr.c (convert_move): Use shifts to perform the move if a
+ suitable extend pattern cannot be found. Code written by
+ Richard Henderson <rth@cygnus.com>.
+
+Wed Oct 28 03:59:29 1998 Bernd Schmidt <crux@pool.informatik.rwth-aachen.de>
+
+ * regclass.c (renumber, regno_allocated): New static variables, moved
+ out of allocate_reg_info.
+ (allocate_reg_info): Move these two variables outside the function.
+ Move code to free memory into new function free_reg_info.
+ (free_reg_info): New function, broken out of allocate_reg_info.
+ * toplev.c (compile_file): Call free_reg_info, not allocate_reg_info.
+ * rtl.h (allocate_reg_info): Don't declare.
+ (free_reg_info): Declare.
+
+ * final.c (cleanup_subreg_operands): ASM_INPUTs need no treatment.
+
+Wed Oct 28 02:38:12 1998 Jason Merrill <jason@yorick.cygnus.com>
+
+ * toplev.c (compile_file): Temporarily revert last change.
+
+Wed Oct 28 00:00:35 1998 Jason Merrill <jason@yorick.cygnus.com>
+
+ * c-typeck.c (convert_for_assignment): Parenthesize.
+
+1998-10-28 Andreas Schwab <schwab@issan.cs.uni-dortmund.de>
+
+ * reload1.c (delete_output_reload): Avoid ambigous else.
+
+Wed Oct 28 00:10:35 1998 Jeffrey A Law (law@cygnus.com)
+
+ * toplev.c (compile_file): Call allocate_reg_info to free register
+ table memory.
+ * rtl.h (allocate_reg_info): Declare.
+
+ * PROJECTS: Remove entry for local spilling.
+
+ * final.c (cleanup_subreg_operands): New function.
+ (final_scan_insn): Use it.
+ (alter_subreg): Clear the "used" field when we turn a SUBREG into
+ a REG.
+ * reload1.c (reload): Delete CLOBBER insns and also cleanup SUBREG
+ operands when reload has finished.
+ * reload.h (cleanup_subreg_operands): Declare..
+ * flow.c (life_analysis_1): No longer delete CLOBBER insns after
+ reload. Handled in reload itself.
+
+Tue Oct 27 23:32:34 1998 Bernd Schmidt <crux@pool.informatik.rwth-aachen.de>
+
+ * reload1.c (verify_initial_offsets): New function.
+ (reload): Call it after reload_as_needed. Also verify that the frame
+ size stays constant during reload_as_needed.
+ * i386.h (CONST_DOUBLE_OK_FOR_LETTER_P): Undo Jul 26 change.
+
+ * reload.h (struct insn_chain): Add need_operand_change element.
+ * reload1.c (new_insn_chain): Clear it.
+ (calculate_needs_all_insns): Set it; don't overload need_reload.
+ (reload_as_needed): Use it.
+
+ * reload.c (find_reloads_address): Use BASE_REG_CLASS instead of
+ reload_address_base_reg_class throughout. Similar for INDEX_REG_CLASS
+ and reload_address_index_reg_class.
+ (find_reloads_address_1): Likewise.
+ * reload.h (reload_address_base_reg_class,
+ reload_address_index_reg_class): Don't declare.
+ * reload1.c (reg_old_renumber, pseudo_previous_regs,
+ pseudo_forbidden_regs, bad_spill_regs_global): New static variables.
+ (used_spill_regs): Now static.
+ (reload_address_base_reg_class, reload_address_index_reg_class,
+ regs_explicitly_used, counted_for_groups, counted_for_nongroups,
+ basic_block_needs, max_needs, group_size, group_mode, max_groups,
+ max_nongroups, max_needs_insn, max_groups_insn, max_nongroups_insn,
+ forbidden_regs):
+ Deleted variables.
+ (init_reload): Delete code to compute base/index reg classes.
+ (reload): Delete variable J.
+ Delete code to manage basic_block_needs.
+ Don't compute regs_explicitly_used.
+ Allocate, initialize and free reg_old_renumber, pseudo_forbidden_regs,
+ pseudo_previous_regs.
+ Initialize bad_spill_regs_global.
+ Don't call order_regs_for_reload here.
+ Don't initialize spill_reg_order and n_spills.
+ Don't forbid explicitly used regs to be used for spill regs.
+ Change main loop to infinite loop, with explicit break statements.
+ Make SOMETHING_CHANGED variable local to that loop.
+ Don't initialize max_needs, max_groups, max_nongroups, max_needs_insn,
+ max_groups_insn, max_nongroups_insn, group_size, group_mode.
+ Make sure spilled_speudos is cleared before calling spill_hard_reg or
+ new_spill_reg.
+ Don't call dump_needs.
+ Delete code to reset potential_reload_regs.
+ Delete code to terminate loop conditional on the global needs variables
+ showing no further needs.
+ (calculate_needs_all_insns): Return void. All callers changed.
+ Initialize somehing_needs_elimination here, not in reload.
+ Delete avoid_return_reg kludge.
+ (calculate_needs): Lose AVOID_RETURN_REG and GLOBAL args, return void.
+ All callers changed.
+ Initialize the group_mode and group_size elements of the arg CHAIN.
+ Delete code to manage basic_block_needs.
+ Operate on elements of CHAIN instead of global variables.
+ Delete avoid_return_reg kludge.
+ (find_tworeg_group): Lose GLOBAL arg, take CHAIN arg, return void.
+ All callers changed.
+ Operate on elements of CHAIN instead of global variables.
+ Delete special SMALL_REGISTER_CLASSES code.
+ Delete spill_failure code; now in new_spill_reg.
+ (find_group): Lose GLOBAL arg, take CHAIN arg, return void.
+ All callers changed.
+ Operate on elements of CHAIN instead of global variables.
+ (maybe_mark_pseudo_spilled): New static function.
+ (find_reload_regs): Lose GLOBAL arg, take CHAIN arg, return void.
+ All callers changed.
+ Operate on elements of CHAIN instead of global variables.
+ Call order_regs_for_reload here, not in reload.
+ Initialize spill_reg_order and n_spills.
+ Simplify test whether an asm insn is involved.
+ Delete spill_failure code; now in new_spill_reg.
+ Call maybe_mark_pseudo_spilled for everything marked as live in
+ CHAIN. Merge CHAIN's used_spill_regs into the global variable
+ used_spill_regs.
+ (dump_needs): Take CHAIN arg. No longer static, to prevent the
+ compiler from optimizing this function (now unused) away.
+ Operate on elements of CHAIN instead of global variables.
+ (possible_group_p): Lose MAX_GROUPS arg, take CHAIN arg. All callers
+ changed.
+ Operate on elements of CHAIN instead of global variables.
+ (count_possible_groups): Lose GROUP_SIZE, GROUP_MODE, MAX_GROUPS args,
+ take CHAIN arg. All callers changed.
+ Operate on elements of CHAIN instead of global variables.
+ (new_spill_reg): Lose MAX_NEEDS, MAX_NONGROUPS, GLOBAL args, take
+ CHAIN, NONGROUP args. Return void. All callers changed.
+ Verify caller isn't trying to spill a pseudo.
+ Simplify test for illegal reg, just use bad_spill_regs.
+ Generate better error messages.
+ Operate on elements of CHAIN instead of global variables.
+ Mark spilled register in CHAIN's used_spill_regs element.
+ Don't call spill_hard_reg.
+ (spill_hard_reg): Lose GLOBAL arg, return void. All callers changed.
+ Mark spilled hard regs in bad_spill_regs_global.
+ Mark affected pseudos in spilled_pseudos, but don't spill them.
+ (ior_hard_reg_set): New static function.
+ (finish_spills): Return int. All callers changed.
+ Compute spill_reg_order, n_spills and spill_regs here. Also update
+ regs_ever_live for regs used as spills.
+ For every pseudo in spilled_pseudos, spill it and mark the previous
+ hard reg it had in pseudo_previous_regs. Compute which hard regs
+ arseudo): New static function.
+ (order_regs_for_reload): Take CHAIN arg. All callers changed.
+ Initialize bad_spill_regs from bad_spill_regs_global, then merge any
+ hard registers explicitly used across the current insn into the set.
+ Compute hard_reg_n_uses taking only pseudos live across this insn
+ into account.
+ Tweak sorting of potential_reload_regs.
+ (compare_spill_regs): Delete function.
+ (reload_as_needed): Don't sort the spill_regs array, it's computed
+ in proper order in finish_spills.
+ Delete avoid_return_reg kludge.
+ Delete code to manage basic_block_needs.
+ (allocate_reload_reg): Minor speed/readability tweaks.
+ Operate on elements of CHAIN instead of global variables.
+ (choose_reload_regs): Lose AVOID_RETURN_REG arg. All callers changed.
+ Delete avoid_return_reg kludge.
+ Initialize reload_reg_used from CHAIN's used_spill_regs element.
+ Delete unused label FAIL.
+ (reload_combine): Replce reload_address_index_reg_class with
+ INDEX_REGS.
+ Don't use used_spill_regs to determine information about lifetime of
+ hard regs.
+
+Tue Oct 27 13:15:02 1998 Nick Clifton <nickc@cygnus.com>
+
+ * toplev.c (display_help): Ignore empty target specific
+ options, and if -W is also specified on the command line then
+ display undocumented options.
+
+ * config/arm/arm.c: Updated with changes in devo sources.
+ * config/arm/arm.h: Updated with changes in devo sources.
+ * config/arm/lib1funcs.asm: Updated with changes in devo sources.
+ * config/arm/lib1thumb.asm: Add ELF support.
+
+Tue Oct 27 16:11:43 1998 David Edelsohn <edelsohn@gnu.org>
+
+ * collect2.c (aix64_flag): New variable.
+ (main, case 'b'): Parse it.
+ (GCC_CHECK_HDR): object magic number must match mode.
+ (scan_prog_file): Only check for shared object if valid header.
+ Print debugging if header/mode mismatch.
+
+Tue Oct 27 10:15:02 1998 Nick Clifton <nickc@cygnus.com>
+
+ Added support for arm-elf-linux configuration, submitted by Philip
+ Blundell <pb@nexus.co.uk>, and integrated this with the arm-elf
+ code developed by Catherine Moore <clm@cygnus.com>. The following
+ files are affected:
+
+ * configure.in: Add arm-*-linux-gnu, armv2-*-linux and arm-*-elf
+ targets.
+
+ * configure: Regenerated.
+
+ * config/arm/aout.h: Add default definitions of REGISTER_PREFIX,
+ USER_LABEL_PREFIX and LOCAL_LABEL_PREFIX. Make other macro
+ definitions conditional on their not having been already defined.
+
+ * config/arm/lin1funcs.asm: Add ELF only macros to generate .size
+ and .type directives, and add "(PLT)" qualification to function
+ calls.
+
+ * config/arm/linux.h: Deleted. This file is now superceeded by
+ either linux-elf.h or linux-aout.h.
+
+ * config/arm/linux-gas.h: Define `inhibit_libc' if cross-compiling.
+ (CLEAR_INSN_CACHE): New macro, currently disabled (awaiting kernel
+ support).
+ Move definitions from old linux.h file here.
+
+ * config/arm/elf.h: New file. Generic ARM/ELF support.
+
+ * config/arm/linux-aout.h: New file. Support for Linux with a.out.
+
+ * config/arm/linux-elf.h: New file. Support for Linux with ELF.
+
+ * config/arm/linux-elf26.h: New file. Support for Linux with ELF
+ using the 26bit APCS.
+
+ * config/arm/unknown-elf.h: New file. Support for OS'es other
+ than Linux with ELF.
+
+ * config/arm/t-arm-elf: New file. makefile fragment for arm-elf
+ builds.
+
+ * config/arm/coff.h: Include aout.h for basic assembler macros.
+ Add support for -mstructure_size_boundary=<n> command line option.
+
+ * config/arm/arm.h: Add support for -mstructure_size_boundary=<n>
+ command line option. Make macro definitions conditional on their
+ not having been already defined.
+
+ * config/arm/arm.c: Add support for -mstructure_size_boundary=<n>
+ command line option.
+
+
+Tue Oct 27 08:56:46 1998 Andrew MacLeod <amacleod@cygnus.com>
+
+ * dwarfout.c (ASM_OUTPUT_DWARF_STRING_NEWLINE): ASM_OUTPUT_DWARF_STRING
+ has been changed to not include a newline. Use this macro instead.
+ (output_enumeral_list, const_value_attribute, name_attribute,
+ comp_dir_attribute, prototyped_attribute, producer_attribute,
+ inline_attribute, pure_or_virtual_attribute, output_inheritance_die,
+ dwarfout_file_scope_decl, generate_new_sfname_entry,
+ generate_macinfo_entry, dwarfout_init, dwarfout_finish): Use
+ ASM_OUTPUT_DWARF_STRING_NEWLINE macro.
+
+Mon Oct 26 13:35:02 1998 Richard Henderson <rth@cygnus.com>
+
+ * combine.c (subst): Process the inputs to a parallel asm_operands
+ only once.
+
+Mon Oct 26 13:32:31 1998 Richard Henderson <rth@cygnus.com>
+
+ * stmt.c (expand_asm_operands): Accept `=' or `+' at any position.
+
+Mon Oct 26 12:53:14 1998 Jeffrey A Law (law@cygnus.com)
+
+ * tm.texi (ASM_OUTPUT_MAX_SKIP_ALIGN): Document.
+
+Mon Oct 26 00:36:58 PST 1998 Jeff Law (law@cygnus.com)
+
+ * version.c: Bump for snapshot.
+
+Sun Oct 25 23:36:52 1998 Jason Merrill <jason@yorick.cygnus.com>
+
+ * stmt.c (expand_fixup): Set fixup->before_jump to a
+ NOTE_INSN_DELETED instead of a NOTE_INSN_BLOCK_BEG.
+
+Sun Oct 25 15:49:57 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * Makefile.in (recog.o): Depend on toplev.h.
+ (insn-emit.o): Depend on recog.h.
+ (insn-peep.o): Depend on recog.h and insn-config.h.
+
+ * combine.c (simplify_set): Remove unused variable `scratches'.
+
+ * final.c (final_scan_insn): Wrap declaration of variables `vlen'
+ and `idx' in macro conditional controlling their use.
+
+ * genemit.c (main): Make the generated output file include
+ recog.h. Don't have it declare `insn_operand_constraint', since
+ we get it from recog.h.
+
+ * genpeep.c (main): Make the generated output file include
+ insn-config.h and recog.h.
+
+ * recog.c: Include toplev.h.
+ (extract_insn): Remove unused variable `p'.
+
+ * regclass.c (fix_register): Add missing braces around initializer
+ for `what_option'.
+ (allocate_reg_info): Move variable `i' into the scope where it is
+ used. Change its type to `size_t'.
+
+Sun Oct 25 13:10:15 1998 Bernd Schmidt <crux@pool.informatik.rwth-aachen.de>
+
+ * reload.c (push_reload): When merging reloads, make sure
+ that reload_in_reg and reload_in are from the same reload in
+ all cases.
+
+Sun Oct 25 12:07:00 1998 Mumit Khan <khan@xraylith.wisc.edu>
+
+ * i386/crtdll.h (CPP_PREDEFINES): Fix typo.
+ * i386/mingw32.h (CPP_PREDEFINES): Likewise.
+
+Fri Oct 23 23:42:03 1998 David Edelsohn <edelsohn@gnu.org>
+
+ * loop.c (loop_has_tablejump): New variable.
+ (prescan_loop): Scan for it.
+ (insert_bct): Replace explicit scan with use of it.
+ * regclass.c (regclass): Restore loop variable j.
+ (record_reg_classes): Deterine op_types modifiers and initialize
+ classes[i] before matching constraints. Handle matching
+ constraints 5-9.
+
+Fri Oct 23 13:55:48 1998 Jim Wilson <wilson@cygnus.com>
+
+ * m32r/m32r.c (gen_split_move_double): Call alter_subreg. Delete
+ subreg support.
+
+Fri Oct 23 16:19:24 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * mips.h (EXTRA_SPECS): Add missing initializers.
+
+Fri Oct 23 16:08:39 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * sparc.h (EXTRA_SPECS): Add missing initializers.
+ (sparc_defer_case_vector): Provide a prototype.
+
+ * svr4.h (ASM_OUTPUT_ASCII): Cast STRING_LIMIT to (long) when
+ comparing it to the result of a pointer subtraction.
+
+Fri Oct 23 15:34:14 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * alpha.c (override_options): Use ISDIGIT(), not isdigit(). Cast
+ the argument to (unsigned char).
+
+ * alpha.h (EXTRA_SPECS): Add missing initializers.
+ (ASM_GENERATE_INTERNAL_LABEL): Ensure the argument matches the
+ format specifier.
+
+Fri Oct 23 13:12:35 1998 Jeffrey A Law (law@cygnus.com)
+
+ * flow.c (life_analysis_1): Enable "rescan" code after reload.
+ (propagate_block): Delete dead code after reload.
+
+ * sched.c (update_flow_info): Revert Oct 19, 1998 change. Brings
+ back Oct 15, 1998 change.
+ * haifa-sched.c (update_flow_info): Likewise.
+ * flow.c (life_analysis_1): Delete CLOBBER insns after reload.
+
+ * mn10200.md (truncated shift): Accept constant inputs too.
+
+Fri Oct 23 04:06:57 1998 Richard Earnshaw (rearnsha@arm.com)
+
+ * machmode.h (mode_mask_array): No longer const.
+ * rtl.c (init_rtl): Fully initialize it if EXTRA_CC_MODES defined.
+
+Fri Oct 23 11:19:06 1998 Martin v. Löwis <loewis@informatik.hu-berlin.de>
+
+ * frame.c: Somewhat explain `FDE'.
+ Suggested by Brendan Kehoe
+
+Fri Oct 23 00:56:11 1998 Jason Merrill <jason@yorick.cygnus.com>
+
+ * expr.c (pending_chain): Move up.
+ (save_expr_status): Do save pending_chain.
+ (restore_expr_status): And restore it.
+ * function.h (struct function): Add pending_chain.
+
+1998-10-23 Herman A.J. ten Brugge <Haj.Ten.Brugge@net.HCC.nl>
+
+ * reorg.c (relax_delay_slots): Fixed test for mostly_true_jump. The
+ did not match the code.
+
+Fri Oct 23 00:07:01 1998 Bernd Schmidt <crux@pool.informatik.rwth-aachen.de>
+
+ * regclass.c (regclass): Break out some code into new function
+ scan_one_insn, and into regclass_init.
+ (init_cost): New static variable, moved out of regclass.
+ (regclass_init): Initialize it here, not in .
+ (scan_one_insn): New static function, broken out of regclass.
+ * recog.c (apply_change_group): Break out some code into new
+ function insn_invalid_p.
+ (insn_invalid_p): New static fn, broken out of apply_change_group.
+
+Thu Oct 22 22:34:42 1998 Jim Wilson <wilson@cygnus.com>
+
+ * reload1.c (reload_as_needed): When rewrite POST_INC, verify
+ reg_reloaded_contents matches incremented pseudo.
+
+ * v850/v850.c (v850_reorg): Call alter_subreg. Delete subreg support.
+
+Fri Oct 23 11:11:56 1998 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
+
+ * rtl.def (POST_MODIFY, PRE_MODIFY): New generalized operators for
+ addressing modes with side effects. These are currently
+ placeholders for the C4x target.
+
+Thu Oct 22 16:46:35 1998 Bernd Schmidt <crux@pool.informatik.rwth-aachen.de>
+
+ * loop.c (express_from): Make sure that when generating a PLUS of
+ a PLUS, any constant expression appears on the outermost PLUS.
+
+Thu Oct 22 15:46:23 1998 Per Bothner (bothner@cygnus.com)
+
+ * Makefile.in (distdir-cvs, distdir-start): Clean up so it
+ works if "$(srcdir)" != ".".
+
+Wed Oct 21 19:23:59 1998 Jim Wilson <wilson@cygnus.com>
+
+ * expmed.c (store_bit_field): If need to add a SUBREG, then remove
+ existing SUBREG if we can, otherwise abort.
+
+Wed Oct 21 09:58:51 1998 Mark Mitchell <mark@markmitchell.com>
+
+ * c-common.c (c_apply_type_quals_to_decl): Don't crash when
+ `restrict' is applied to a non-pointer variable.
+
+Wed Oct 21 09:18:58 1998 Mark Mitchell <mark@markmitchell.com>
+
+ * invoke.texi: Document -flang-isoc9x.
+
+ * Makefile.in (OBJS): Add splay-tree.o.
+ (c-common.o): Depend on rtl.h.
+ (splay-tree.o): List dependencies and provide build rule.
+
+ * rtl.h (record_alias_subset): New function.
+ * alias.c: Include splay-tree.h.
+ (alias_set_entry): New type.
+ (CHECK_ALIAS_SETS_FOR_CONSISTENCY): Remove.
+ (DIFFERENT_ALIAS_SETS_P): Use mem_in_disjoint_alias_sets_p.
+ (mems_in_disjoin_alias_sets_p): New function.
+ (alias_set_compare): Likewise.
+ (insert_subset_children): Likewise.
+ (get_alias_set_entry): Likewise.
+
+ * tree.h (TYPE_RESTRICT): New macro.
+ (TYPE_UNQUALIFIED): New manifest constant.
+ (TYPE_QUAL_CONST): Likewise
+ (TYPE_QUAL_VOLATILE): Likewise.
+ (TYPE_QUAL_RESTRICT): Likewise.
+ (tree_type): Add restrict_flag. Reduce count of free bits.
+ (DECL_POINTER_ALIAS_SET): New macro.
+ (DECL_POINTER_ALIAS_SET_KNOWN_P): Likewise.
+ (tree_decl): Add pointer_alias_set.
+ (build_qualified_type): New function.
+ (build_type_variant): Define in terms of build_qualified_type.
+ * tree.c (set_type_quals): New function.
+ (make_node): Initializae DECL_POINTER_ALIAS_SET.
+ (build_type_attribute_variant): Use build_qualified_type and
+ set_type_quals.
+ (build_type_variant): Rename, and modify, to become...
+ (build_qualified_type): New function.
+ (build_complex_type): Use set_type_quals.
+
+ * c-tree.h (C_TYPE_OBJECT_P): New macro.
+ (C_TYPE_FUNCTION_P): Likewise.
+ (C_TYPE_INCOMPLETE_P): Likewise.
+ (C_TYPE_OBJECT_OR_INCOMPLETE_P): Likewise.
+ (c_apply_type_quals_to_decl): New function.
+ (c_build_qualified_type): New function.
+ (c_build_type_variant): Define in terms of c_build_qualified_type.
+ (flag_isoc9x): Declare.
+ * c-typeck.c (qualify_type): Use c_build_qualified_type.
+ (common_type): Change to use TYPE_QUALS.
+ (comptypes): Likewise.
+ (convert_for_assignment): Likewise.
+ * c-aux-info.c (gen_type): Likewise. Deal with `restrict'.
+ * c-decl.c (flag_isoc9x): Define.
+ (c_decode_option): Handle -flang-isoc9x.
+ (grokdeclarator): Update to handle restrict. Use TYPE_QUALS,
+ c_build_qualified_type, etc. Use c_apply_type_quals_to_decl.
+ * c-lex.c (init_lex): Deal with restrict.
+ (init_lex): Don't treat restrict as a reserved word in
+ -traditional mode, or without -flang-isoc9x.
+ * c-lex.h (rid): Add RID_RESTRICT.
+ * c-parse.gperf (restrict, __restrict, __restrict__): Make
+ equivalent to RID_RESTRICT.
+ * c-parse.in (TYPE_QUAL): Update comment.
+ * c-common.c: Include rtl.h.
+ (c_find_base_decl): New function.
+ (c_build_type_variant): Rename, and modify, to become ...
+ (c_build_qualified_type): New function.
+ (c_apply_type_quals_to_decl): Likewise.
+ (c_get_alias_set): For INDIRECT_REFs, check to see if we can find
+ a particular alias set for the reference.
+ * toplev.c (documented_lang_options): Add -flang-isoc9x.
+
+Wed Oct 21 09:15:06 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/arm/arm.h (TARGET_SWITCHES): Document arm specific
+ command line switches.
+
+Tue Oct 20 10:04:51 1998 Graham <grahams@rcp.co.uk>
+
+ * reload.c (loc_mentioned_in_p): Add missing braces to bind
+ else to correct if.
+
+Mon Oct 19 16:34:05 1998 Tom Tromey <tromey@cygnus.com>
+
+ * gcc.c (option_map): Added --classpath and --CLASSPATH.
+
+Tue Oct 20 10:59:02 1998 Gavin Romig-Koch <gavin@cygnus.com>
+
+ * regclass.c (fix_register): Add error message.
+ * invoke.texi (-fcall-used-REG,-fcall-saved-REG): Note the
+ new error message.
+
+Tue Oct 20 10:12:17 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * c-decl.c (warn_missing_noreturn): New global variable.
+ (c_decode_option): Check for new flags -W{no-}missing-noreturn.
+ (finish_function): Implement missing noreturn warning.
+
+ * c-tree.h (warn_missing_noreturn): Declare extern.
+
+ * invoke.texi: Document new flags.
+
+ * toplev.c (documented_lang_options): Add description.
+
+Tue Oct 20 22:16:11 1998 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
+
+ * config/c4x/c4x.c (c4x_parallel_process): Disable until BCT
+ loop optimization stable for the C4x.
+ (c4x_rptb_info_t, c4x_dump, c4x_rptb_in_range, c4x_rptb_unjumped_loop,
+ c4x_rptb_find_comp_and_jump, c4x_rptb_loop_info_get,
+ c4x_rptb_emit_init, c4x_rptb_process): Deleted (superceded by BCT
+ loop optimization).
+ (c4x_address_conflict): Be more paranoid when packing a volatile
+ memref in a parallel load/store.
+
+Tue Oct 20 21:56:05 1998 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
+
+ * config/c4x/c4x.md (repeat_block_top, repeat_block_end,
+ repeat_block_filler): Deleted.
+ (*ashlqi3_set, *ashrqi3_const_set, *ashrqi3_nonconst_clobber):
+ Condition code not set if destination register from 'c' class.
+ (*subbqi3_carry_clobber): Fix typo.
+
+1998-10-18 Herman A.J. ten Brugge <Haj.Ten.Brugge@net.HCC.nl>
+
+ * reorg.c (steal_delay_list_from_target) Check for insns that
+ modify the condition codes and effect the direction of the jump
+ in the sequence.
+
+Sat Oct 17 13:09:09 1998 Graham <grahams@rcp.co.uk>
+
+ * function.c (purge_addressof_1): Replace call to
+ emit_insns_before() with emit_insn_before().
+
+Mon Oct 19 19:34:03 1998 Mike Stump <mrs@wrs.com>
+
+ * libgcc2.c (__pure_virtual): Call __terminate instead of _exit.
+
+Mon Oct 19 13:26:24 1998 Bernd Schmidt <crux@pool.informatik.rwth-aachen.de>
+
+ * jump.c (sets_cc0_p): Compile only if HAVE_cc0.
+
+Mon Oct 19 11:40:56 1998 Jeffrey A Law (law@cygnus.com)
+
+ * gcse.c (compute_hash_table): Correctly identify hard regs which are
+ clobbered across calls.
+
+ * loop.c (scan_loop): Be more selective about what invariants are
+ moved out of a loop.
+
+Mon Oct 19 10:46:58 PDT 1998 Jeff Law (law@cygnus.com)
+
+ * version.c: Bump for snapshot.
+
+Mon Oct 19 11:40:56 1998 Jeffrey A Law (law@cygnus.com)
+
+ * libgcc2.c (eh_context_static): Do not call malloc to allocate the
+ static eh_context structure.
+
+Mon Oct 19 10:45:40 1998 Bernd Schmidt <crux@pool.informatik.rwth-aachen.de>
+
+ * combine.c (recog_for_combine): Lose PADDED_SCRATCHES arg. All
+ callers changed.
+ (try_combine): Don't update max_scratch.
+ * flow.c (max_scratch, num_scratch): Delete variables.
+ (life_analysis_1): Don't initialize max_scratch.
+ (propagate_block): Don't update max_scratch.
+ (mark_set_1): Don't increment num_scratch.
+ * regs.h (max_scratch): Delete declaration.
+
+Mon Oct 19 10:28:15 1998 Jeffrey A Law (law@cygnus.com)
+
+ * reload1.c (reload_reg_free_before_p): Hack. Return 0 if EQUIV
+ is nonzero. This is temporary!
+
+ * sched.c (update_flow_info): Handle death notes made invalid by
+ instruction splitting. Partially reverts Oct 15, 1998 patch.
+ * haifa-sched.c (update_flow_info): Likewise.
+
+Sun Oct 18 17:31:26 1998 Jeffrey A Law (law@cygnus.com)
+
+ * function.c (uninitialized_vars_warning): Do not warn for a VAR_DECL
+ if it has a nonzero DECL_INITIAL.
+
+Sat Oct 17 23:18:08 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * Makefile.in (flow.o): Depend on recog.h.
+
+ * cpplib.h (directive_table): Add missing initializiers.
+ (finclude): Change type of variable `bsize' to size_t.
+
+ * cse.c (rtx_cost): Mark parameter `outer_code' with ATTRIBUTE_UNUSED.
+
+ * dwarfout.h (dwarfout_label): Wrap prototype in macro RTX_CODE.
+
+ * fix-header.c (lookup_std_proto): Cast the result of `strlen' to
+ `int' when comparing against one.
+ (cpp_file_line_for_message): Mark parameter `pfile' with
+ ATTRIBUTE_UNUSED.
+ (cpp_fatal): Mark parameter `pfile' with ATTRIBUTE_UNUSED.
+
+ * flow.c: Include recog.h.
+ (sbitmap_copy): Cast arguments 1 & 2 of `bcopy' to (PTR).
+
+ * function.c (thread_prologue_and_epilogue_insns): Mark parameter
+ `f' with ATTRIBUTE_UNUSED.
+ (reposition_prologue_and_epilogue_notes): Likewise.
+
+ * genopinit.c (gen_insn): Cast argument of ctype functions to
+ `unsigned char'.
+
+ * haifa-sched.c: Include recog.h.
+ (blockage_range): Cast result of UNIT_BLOCKED macro to (int) when
+ comparing against one.
+
+ * libgcc2.a (__throw): Revert ATTRIBUTE_UNUSED change for now.
+
+ * mips-tfile.c (parse_end): Cast the argument of ctype function to
+ `unsigned char'.
+ (parse_ent): Likewise.
+ (parse_input): Likewise.
+
+ * optabs.c (init_libfuncs): Likewise.
+
+ * protoize.c (find_rightmost_formals_list): Likewise.
+
+ * recog.h (const_double_operand): Fix typo in prototype.
+
+ * tlink.c (scan_linker_output): Cast the argument of ctype
+ function to `unsigned char'.
+
+ * toplev.c (check_lang_option): Cast the result of `strlen' to
+ `int' when comparing against one.
+
+Sat Oct 17 13:09:09 1998 Graham <grahams@rcp.co.uk>
+
+ * gcse.c (dump_cuid_table): Correct typo.
+
+Sat Oct 17 11:02:47 1998 Nick Clifton <nickc@cygnus.com>
+
+ * toplev.c (display_help): Prepend '-m' to target specific
+ options.
+ (check_lang_option): Ignore text after end of first word of a
+ language specific option.
+
+Sat Oct 17 02:26:03 1998 Bernd Schmidt <crux@pool.informatik.rwth-aachen.de>
+
+ * reload1.c (reg_used_by_pseudo): New static variable.
+ (choose_reload_regs): Initialize it.
+ Use it instead of testing spill_reg_order to determine whether a
+ pseudo is live in a hard register across the current insn.
+ Fix a typo in a reference to reload_reg_rtx.
+
+ * flow.c (propagate_block): Replace code that computes and uses
+ regs_sometimes_live with simpler code that just walks the set of
+ currently live registers.
+
+ * Makefile.in (insn-extract.o): Fix dependencies.
+ * genextract.c (main): Generate includes for insn-config.h and
+ recog.h.
+ Delete generation of declarations which are now in recog.h.
+ * genrecog.c (main): Delete generation of definitions which are
+ now in recog.c.
+ * local-alloc.c (block_alloc): Use extract_insn and the variables
+ it sets up instead of looking up values by insn_code.
+ * recog.c (recog_operand, recog_operand_loc, recog_dup_loc,
+ recog_dup_num): Define here instead of generating the definition in
+ genrecog.c.
+ (recog_n_operands, recog_n_dups, recog_n_alternatives,
+ recog_operand_mode, recog_constraints, recog_operand_address_p):
+ New variables.
+ (extract_insn): New function.
+ * recog.h (extract_insn): Declare function.
+ (which_alternative, recog_n_operands, recog_n_dups,
+ recog_n_alternatives, recog_operand_mode, recog_constraints,
+ recog_operand_address_p): Declare variables.
+ * regclass.c (n_occurrences): New static function.
+ * reload.c (n_occurrences): Delete function.
+ (find_reloads): Use extract_insn.
+ * reload.h (n_occurrences): Delete declaration.
+
+Sat Oct 17 01:17:51 1998 Jeffrey A Law (law@cygnus.com)
+
+ * reload1.c (reload_as_needed): Fix test for when to call
+ update_eliminable_offsets.
+
+Fri Oct 16 20:40:50 1998 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ Fix consistency problems with reg_equiv_{mem,address};
+ Improve reload inheritance;
+
+ * reload.c (reload_out_reg): New variable.
+ (loc_mentioned_in_p, remove_address_replacements): New functions.
+ (remove_replacements): Deleted.
+ (push_reload): Set reload_out_reg[i].
+ When merging, also set reload_{in,out}_reg[i], and remove
+ duplicate address reloads.
+ (combine_reloads): Copy reload_out_reg[i].
+ (find_reloads): Do make_memloc substitution also when
+ reg_equiv_memory_loc[regno] and num_not_at_initial_offset
+ are both nonzero.
+ Include *recog_operand_loc in commutativity operand changes.
+ Generate optional output reloads.
+ Delete reference to n_memlocs. Don't set *recog_operand_loc before
+ processing operands. Call make_memloc in reg_equiv_address code.
+ Set *recog_operand_loc only after processing operands, and only
+ if replace is true. Return a value.
+ When changing address reload types for operands that didn't get
+ reloaded, use RELOAD_FOR_OPADDR_ADDRESS for
+ RELOAD_FOR_INPADDR_ADDRESS / RELOAD_FOR_OUTADDR_ADDRESS reloads.
+ Don't emit USEs for pseudo SUBREGs when not replacing.
+ (find_reloads_address): Do make_memloc substitution also when
+ reg_equiv_memory_loc[regno] and num_not_at_initial_offset
+ are both nonzero.
+ (find_reloads_toplev): Likewise.
+ Call make_memloc in reg_equiv_address code.
+ (debug_reload_to_stream): Add code to output reload_out_reg.
+ (make_memloc): Delete local variable i, ifdefed out code, and
+ references to memlocs and n_memlocs.
+ (memlocs, n_memlocs): Delete.
+ (push_secondary_reload): Clear reload_out_reg.
+ (find_reloads_address_1): Provide memrefloc argument to all calls
+ to find_reloads_address.
+ In AUTO_INC code, handle non-directly addressable equivalences properly.
+ * reload.h (reload_out_reg, num_not_at_initial_offset): Declare.
+ (find_reloads): Add return type.
+ (remove_address_replacements, deallocate_reload_reg): Declare.
+ * reload1.c (num_not_at_initial_offset): No longer static.
+ (delete_address_reloads, delete_address_reloads_1): Likewise.
+ (deallocate_reload_reg): New function.
+ (spill_reg_stored_to): New array.
+ (eliminate_regs): Don't substitute from reg_equiv_memory_loc.
+ (eliminate_regs_in_insn): Move assignments of previous_offset and
+ max_offset fields, and recalculation of num_not_at_initial_offset
+ into new static function:
+ (update_eliminable_offsets) .
+ (reload_as_needed): Call update_eliminable_offsetss after calling
+ find_reloads.
+ Call forget_old_reloads_1 with contents of reloaded auto_inc
+ expressions if the actual addressing can't be changed to match the
+ auto_inc.
+ (choose_reload_regs): For inheritance, replace
+ reload_reg_free_before_p test with reload_reg_used_at_all test, and
+ remove stand-alone reload_reg_used_at_all test.
+ Use reload_out_reg to determine which reload regs have output reloads.
+ Treat reload_override_in more similar to inherited reloads.
+ Handle (subreg (reg... for inheritance.
+ For flag_expensive_optimizations, add an extra pass to remove
+ unnecessary reloads from known working inheritance.
+ Delete obsolete code for pseudos replaced with MEMs.
+ Handle inheritance from auto_inc expressions.
+ (emit_reload_insns): If reload_in is a MEM, set OLD to
+ reload_in_reg[j].
+ Don't reload directly from oldequiv; if it's a pseudo with a
+ stack slot, use reload_in[j].
+ Check that reload_in_reg[j] is a MEM before replacing reload_in
+ from reg_reloaded_contents.
+ Include non-spill registers in reload inheritance processing.
+ Also try to use reload_out_reg to set spill_reg_store /
+ reg_last_reload_reg.
+ In code to set new_spill_reg_store, use single_set to find out if
+ there is a single set.
+ Add code that allows to delete optional output reloads.
+ Add code to allow deletion of output reloads that use no spill reg.
+ At the end, set reload_override_in to oldequiv.
+ Also call delete_output_reload if reload_out_reg is equal to old
+ in oldequiv code.
+ Add code to call delete_output_reload for stores with no matching load.
+ Set / use spill_reg_stored_to.
+ Handle case where secondary output reload uses a temporary, but
+ actual store isn't found.
+ When looking for a store of a value not loaded in order to call
+ delete_output_reload, count_occurences should return 0 for no
+ loads; but discount inherited input reloadill_reg_stored_to.
+ Do checks for extra uses of REG. Changed all
+ callers.
+ Use delete_address_reloads.
+ (reload): Take return value of find_reloads into account.
+ If a no-op set needs more than one reload, delete it.
+ (reload_reg_free_before_p): RELOAD_FOR_INPUT
+ can ignore RELOAD_FOR_INPUT_ADDRESS / RELOAD_FOR_INPADDR_ADDRESS
+ for the same operand.
+ (clear_reload_reg_in_use): Check for other reloads that keep a
+ register in use.
+ (reload_reg_free_for_value_p): handle RELOAD_FOR_OPERAND_ADDRESS /
+ RELOAD_FOR_OPADDR_ADDR.
+ Take into account when an address address reload is only needed
+ for the address reload we are considering.
+ (count_occurrences): Use rtx_equal_p for MEMs.
+ (inc_for_reload): Return instruction that stores into RELOADREG.
+ New argument two, IN, and rtx. Changed all callers.
+ (calculate_needs_all_insns, reload_as_needed):
+ Don't clear after_call for a CLOBBER.
+ Keep track of how many hard registers need to be copied from
+ after_call, and don't clear after_call before we have seen
+ that much copies, or we see a different instruction.
+
+Fri Oct 16 10:58:23 1998 Jeffrey A Law (law@cygnus.com)
+
+ * flow.c (find_basic_blocks_1): Do not delete unreachable blocks
+ after reload has completed.
+
+Fri Oct 16 17:26:10 1998 Dave Brolley <brolley@cygnus.com>
+
+ * cpplib.c (cpp_get_token): Replace whitespace that occurs between
+ a macro name and the next token with a single blank if that whitespace
+ is in a macro buffer and the next token is not '('.
+
+Fri Oct 16 15:44:02 1998 Dave Brolley <brolley@cygnus.com>
+
+ * cccp.c (rescan): Handle multibyte chartacters ending in backslash.
+ (rescan): Ditto.
+ (skip_if_group): Ditto.
+ (skip_to_end_of_comment): Ditto.
+ (macarg1): Ditto.
+ (discard_comments): Ditto.
+ (change_newlines): Ditto.
+
+Fri Oct 16 15:26:24 1998 Dave Brolley <brolley@cygnus.com>
+
+ * c-lex.c (yylex): Fix unaligned access of wchar_t.
+
+Fri Oct 16 10:47:53 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/arm/arm.h (TARGET_SWITCHES): Add --help documentation.
+ (TARGET_OPTIONS): Add --help documentation.
+
+Fri Oct 16 11:49:01 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * rtl.h (sets_cc0_p): Revert Oct 14 ATTRIBUTE_NORETURN change.
+
+Fri Oct 16 07:08:46 1998 Bruce Korb <korb@datadesign.com>
+
+ * fixinc/* Moved in from ../contrib directory in preparation
+ for integrating it into the normal build process. In particular,
+ fixinc/Makefile.in must be config-ed into the build directory
+ as fixinc/Makefile. Proposed patches to ./Makefile.in and
+ ./configure.in will be "in the mail" momentarily.
+
+Fri Oct 16 08:13:46 1998 David S. Miller <davem@pierdol.cobaltnet.com>
+
+ * cse.c (cse_basic_block): Fixup hash flushing loop so we do not
+ accidently walk into the free list. Comment how that can happen.
+ (invalidate): Fix indentation.
+
+Thu Oct 15 23:53:29 1998 Bernd Schmidt <crux@pool.informatik.rwth-aachen.de>
+ Jeffrey A Law (law@cygnus.com)
+
+ * flow.c (life_analysis_1): Do not clobber regs_ever_live after
+ reload. Never perform rescans of the insn chain after reload.
+ (propagate_block): Do not delete insn or create new autoinc addressing
+ modes after reload.
+
+ * jump.c (jump_optimize): Unconditionally use the code that was
+ previously conditional on PRESERVE_DEATH_INFO_REGNO_P.
+ * reload1.c (reload): When reloading is finished, delete all
+ REG_DEAD and REG_UNUSED notes.
+ (emit_reload_insns): Delete all code that was conditional on
+ PRESERVE_DEATH_INFO_REGNO_P.
+ (no_longer_dead_regs): Delete variable.
+ (reload_cse_delete_death_notes): Delete function.
+ (reload_cse_no_longer_dead): Delete function.
+ (reload_cse_regs_1): Delete all code to handle deletion of death
+ notes.
+ (reload_cse_noop_set_p): Likewise.
+ (reload_cse_simplify_set): Likewise.
+ (reload_cse_simplify_operands): Likewise.
+ (reload_cse_move2add): Likewise.
+ * reorg.c (used_spill_regs): Delete declaration.
+ (max_label_num_after_reload): Delete declaration.
+ (find_dead_or_set_registers): Don't assume that spill regs are
+ dead at a CODE_LABEL.
+ * rtlanal.c (dead_or_set_regno_p): Death notes are always accurate,
+ even after reload.
+ * sched.c (sched_analyze_insn): Likewise.
+ (update_flow_info): Likewise.
+ * haifa-sched.c (sched_analyze_insn): Likewise.
+ (update_flow_info): Likewise.
+ * tm.texi (PRESERVE_DEATH_INFO_REGNO_P): Delete documentation.
+ * toplev.c (max_label_num_after_reload): Delete variable.
+ (rest_of_compilation): Don't set max_label_num_after_reload.
+ Call life_analysis after reload_cse_regs if optimizing.
+ * config/gmicro/gmicro.h: Delete comment referring to
+ PRESERVE_DEATH_INFO_REGNO_P.
+ * config/i386/i386.h: Likewise.
+ * config/m88k/m88k.h: Likewise.
+ * config/m32r/m32r.h (PRESERVE_DEATH_INFO_REGNO_P): Delete definition.
+ * config/sh/sh.h: Likewise.
+
+Thu Oct 15 19:48:41 1998 David Edelsohn <edelsohn@gnu.org>
+
+ * loop.c (strength_reduce): Restore marking bct_p as
+ ATTRIBUTE_UNUSED.
+ * rs6000.c (optimization_options): Change #ifdef HAIFA to
+ HAVE_decrement_and_branch_on_count.
+ (small_data_operand): Remove TARGET_ELF condition for marking
+ parameters ATTRIBUTE_UNUSED.
+
+Thu Oct 15 11:45:51 1998 Robert Lipe <robertl@dgii.com>
+
+ * config/i386/sco5.h (MAX_OFILE_ALIGNMENT): Define.
+ (SELECT_SECTION): Resync with svr4.h.
+
+Thu Oct 15 12:42:13 1998 David Edelsohn <edelsohn@gnu.org>
+
+ * loop.c (strength_reduce): Undo Oct 14 change marking bct_p
+ ATTRIBUTE_UNUSED.
+
+Thu Oct 15 00:57:55 1998 Robert Lipe <robertl@dgii.com>
+
+ * c-pragma.c (handle_pragma_token): Test for null tree before
+ dereferencing TREE_CODE.
+
+Thu Oct 15 17:36:48 1998 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
+
+ * config/c4x/c4x.c: Convert to use GEN_INT.
+ (c4x_parallel_process): Rework to handle new repeat loop structure.
+
+ * config/c4x/c4x.md: Convert to use GEN_INT.
+ (rptb_end): Convert to use GE test. Replace uses with clobbers.
+ (decrement_and_branch_on_count): Likewise.
+
+ * config/c4x/c4x.h (REPEAT_BLOCK_PROCESS): Deleted hook now that
+ loop.c has the desired functionality.
+ (rc_reg_operand): New prototype.
+
+ * config/c4x/t-c4x: Can now build all front ends.
+
+Wed Oct 14 23:27:08 1998 Didier FORT (didier.fort@fedex.com)
+
+ * fixincludes: Fix up rpc/{clnt,svr,xdr}.h for SunOS.
+
+Wed Oct 14 22:13:28 1998 Joel Sherrill (joel@OARcorp.com)
+
+ * Makefile.in (stmp-fixinc): Do not install assert.h if not desired.
+ * config/t-rtems: Do not install assert.h -- use newlib's.
+
+Wed Oct 14 21:57:08 1998 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * combine.c (combine_instructions): When finished, call init_recog.
+ * regmove.c (optimize_reg_copy_3): Reject volatile MEMs.
+
+Wed Oct 14 16:10:22 1998 Per Bothner <bothner@cygnus.com>
+
+ * toplev.c: If flag_syntax_only, don't open or write assembler file.
+
+Wed Oct 14 13:26:05 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * cppalloc.c (memory_full): Mark function prototype with
+ ATTRIBUTE_NORETURN.
+
+ * demangle.h (collect_exit): Likewise.
+
+ * fix-header.c (v_fatal, fatal): Likewise.
+
+ * gcc.c (pfatal_with_name, pfatal_pexecute, fatal, fancy_abort):
+ Likewise.
+
+ * gcov.c (print_usage): Likewise.
+
+ * genattr.c (fatal, fancy_abort): Likewise.
+
+ * genattrtab.c (fatal, fancy_abort): Likewise.
+
+ * gencodes.c (fatal, fancy_abort): Likewise.
+
+ * genconfig.c (fatal, fancy_abort): Likewise.
+
+ * genemit.c (fatal, fancy_abort): Likewise.
+
+ * genextract.c (fatal, fancy_abort): Likewise.
+
+ * genflags.c (fatal, fancy_abort): Likewise.
+
+ * genopinit.c (fatal, fancy_abort): Likewise.
+
+ * genoutput.c (fatal, fancy_abort): Likewise.
+
+ * genpeep.c (fatal, fancy_abort): Likewise.
+
+ * genrecog.c (fatal, fancy_abort): Likewise.
+
+ * libgcc2.c (__eprintf, __default_terminate, __sjthrow,
+ __sjpopnthrow, __throw): Likewise.
+
+ * objc/objc-act.c (objc_fatal): Likewise.
+
+ * protoize.c (usage, aux_info_corrupted,
+ declare_source_confusing): Likewise.
+
+ * rtl.c (dump_and_abort): Likewise.
+
+ * rtl.h (sets_cc0_p): Likewise.
+
+ * toplev.c (float_signal, pipe_closed): Likewise.
+
+1998-10-14 Andreas Schwab <schwab@issan.cs.uni-dortmund.de>
+
+ * dwarf2out.c (expand_builtin_dwarf_reg_size): Look at all ranges
+ when generating the decision tree for the general case.
+
+ * config/m68k/m68k.h (HARD_REGNO_MODE_OK): Don't accept modes
+ wider that 12 bytes in fpu regs or wider than 8 byte in fpa regs.
+
+Wed Oct 14 11:14:02 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * Makefile.in (sched.o): Depend on recog.h.
+
+ * alias.c (REG_BASE_VALUE): Cast the result of REGNO() macro to
+ (unsigned) when comparing against one.
+ (find_base_value): Likewise.
+ (record_base_value): Cast variable `regno' to (unsigned) when
+ comparing against one. Cast the result of REGNO() macro to
+ (unsigned) when comparing against one.
+ (memrefs_conflict_p): Change type of variables `r_x' and `r_y' to
+ unsigned.
+ (init_alias_analysis): Add unsigned variable `ui'. Use it as loop
+ variable where an unsigned index is needed.
+
+ * caller-save.c (init_caller_save): Cast `-1' to (enum insn_code)
+ before comparing against one.
+
+ * collect2.c: Add prototypes for functions `error', `fatal' and
+ `fatal_perror'. Make these functions take variable arguments
+ instead of faking it with a fixed number of args.
+ (write_c_file_stat): Cast the argument of ctype macro to (unsigned
+ char).
+
+ * combine.c (can_combine_p): Mark parameter `pred' with
+ ATTRIBUTE_UNUSED.
+ (find_split_point): Cast variable `src' to (unsigned
+ HOST_WIDE_INT) when comparing against one.
+ (simplify_rtx): Cast 1 to (unsigned HOST_WIDE_INT) in shift.
+ (simplify_logical): Likewise.
+ (force_to_mode): Cast result of INTVAL() macro to (unsigned
+ HOST_WIDE_INT) when comparing against one. Cast 1 to (unsigned
+ HOST_WIDE_INT) in shift.
+ (simplify_and_const_int): Cast result of INTVAL() macro to
+ `unsigned HOST_WIDE_INT' when comparing against one.
+ (merge_outer_ops): Cast variable const0 to `unsigned
+ HOST_WIDE_INT' when comparing against the result of
+ GET_MODE_MASK() macro.
+ (simplify_comparison): Likewise for variable `c0'. Cast variable
+ `const_op' to `unsigned HOST_WIDE_INT' when comparing against
+ one. Cast `1' to `unsigned HOST_WIDE_INT' in shift. Cast the
+ result of `GET_MODE_MASK()/2' to `HOST_WIDE_INT' when comparing
+ against one. Cast `1' to `unsigned HOST_WIDE_INT' in shift. Cast
+ result of INTVAL() macro to `unsigned HOST_WIDE_INT' when
+ comparing against one.
+ (distribute_notes): Wrap variable `cc0_setter' in macro `HAVE_cc0'.
+
+ config/mips/mips.c (gen_int_relational): Cast result of INTVAL()
+ macro to `unsigned HOST_WIDE_INT' when comparing against one.
+ (output_block_move): Cast `sizeof' expression to (int) when
+ comparing against one.
+ (function_arg): Cast BITS_PER_WORD to `unsigned' when comparing
+ against one.
+ (save_restore_insns): Cast `base_offset' to `long' to match format
+ specifier in fprintf.
+
+ * config/mips/mips.h (Pmode): Cast the result of `Pmode' macro
+ to `enum machine_mode'.
+
+ * flow.c (life_analysis_1): Remove unused variable `insn'.
+
+ * gcc.c (translate_options): Move variables `j' and `k' into the
+ scope in which they are used. Change their types to `size_t'.
+ (set_spec): Cast the argument of ctype macro to `unsigned char'.
+ (read_specs): Likewise.
+ (process_command): Cast `sizeof' to (int) when comparing against one.
+ (do_spec_1): Cast the argument of ctype macro to `unsigned char'.
+ (handle_braces): Cast both sides of `==' expression to `long' to
+ ensure sign matching.
+ (main): Cast variable `i' to `int' when comparing against one.
+
+ * gcov-io.h (__fetch_long): Change type of parameter `bytes' from
+ int to size_t. Cast variable `i' to size_t when comparing against
+ one.
+
+ * genattrtab.c (convert_set_attr_alternative): Remove unused
+ parameter `insn_code'. All callers changed.
+ (convert_set_attr): Likewise.
+
+ * genrecog.c (add_to_sequence): Cast result of XVECLEN() macro to
+ size_t when comparing against one. Likewise for variable `len'.
+
+ * global.c (global_alloc): Cast variable `max_regno' to size_t
+ when comparing against one. Likewise for variable `max_allocno'.
+
+ * jump.c (sets_cc0_p): Mark parameter `x' with ATTRIBUTE_UNUSED.
+
+ * local-alloc.c (validate_equiv_mem_from_store): Mark parameter
+ `set' with ATTRIBUTE_UNUSED.
+ (find_free_reg): Cast `sizeof' expression to (int) when comparing
+ against one.
+
+ * loop.c (count_loop_regs_set): Remove unused variable `dest'.
+ (strength_reduce): Mark parameter `bct_p' with ATTRIBUTE_UNUSED.
+ (get_condition): Cast variable `const_val' to `unsigned
+ HOST_WIDE_INT' when comparing against one. Cast unsigned
+ expression to HOST_WIDE_INT when comparing against one.
+ (insert_loop_mem): Mark parameter `data' with ATTRIBUTE_UNUSED.
+ (load_mems_and_recount_loop_regs_set): Cast variable `nregs' to
+ `unsigned' when comparing against one.
+
+ * protoize.c (is_id_char): Change type of parameter `ch' to
+ unsigned char.
+ (munge_compile_params): Cast argument of ctype macro to (const
+ unsigned char).
+ (process_aux_info_file): Cast variable `aux_info_size' to int when
+ comparing against one.
+ (forward_to_next_token_char): Cast argument of ctype macro to
+ `const unsigned char'.
+ (edit_formals_lists): Likewise.
+ (find_rightmost_formals_list): Likewise.
+ (add_local_decl): Likewise.
+ (add_global_decls): Likewise.
+ (edit_fn_definition): Likewise.
+ (do_cleaning): Likewise.
+ (scan_for_missed_items): Likewise.
+ (edit_file): Cast variable `orig_size' to (int) when comparing
+ against one.
+ (main): Cast argument of ctype macro to `const unsigned char'.
+
+ * recog.c (const_int_operand): Mark parameter `mode' with
+ ATTRIBUTE_UNUSED.
+
+ * regclass.c (record_reg_classes): Change type of variable `c' to
+ `unsigned char'. Cast `char' array index to `unsigned char'.
+
+ * reload.c (push_secondary_reload): Cast argument to
+ REG_CLASS_FROM_LETTER() macro to `unsigned char'.
+
+ * reload1.c (calculate_needs): Cast `char' array index to
+ `unsigned char'.
+ (set_label_offsets): Change type of variable `i' to unsigned int.
+ Cast result of XVECLEN() macro to unsigned when comparing against
+ one.
+ (mark_not_eliminable): Change type of variable `i' to unsigned.
+ (order_regs_for_reload): Likewise. Cast `max_regno' to unsigned
+ when comparing against one.
+ (reload_as_needed): Cast macro NUM_ELIMINABLE_REGS to (int) when
+ comparing against one.
+ (choose_reload_regs): Hide unused label `fail'.
+ (reload_cse_simplify_operands): Cast `char' array index to
+ `unsigned char'.
+ (reload_combine_note_store): Mark parameter `set' with
+ ATTRIBUTE_UNUSED. Cast UNITS_PER_WORD to unsigned when comparing
+ against one.
+ (reload_cse_move2add): Remove unused variable `src2'.
+
+ * sched.c: Include recog.h.
+ (sched_note_set): Remove unused parameter `b'. All callers
+ changed.
+ (split_hard_reg_notes): Likewise for parameter `orig_insn'.
+ (blockage_range): Cast result of UNIT_BLOCKED() macro to (int)
+ when comparing against one.
+
+ * stupid.c (stupid_find_reg): Mark parameter `changes_size' with
+ ATTRIBUTE_UNUSED. Cast `sizeof' expression to (int) when
+ comparing against one.
+
+ * unroll.c (precondition_loop_p): Remove unused parameter
+ `loop_end'. All callers changed.
+
+Tue Oct 13 22:12:11 1998 Bernd Schmidt <crux@pool.informatik.rwth-aachen.de>
+
+ * reload1.c (maybe_fix_stack_asms): New static function.
+ (reload): Call it.
+
+ * reload.h (compute_use_by_pseudos): Declare.
+
+ * reload1.c (spilled_pseudos, insns_need_reload): New variables.
+ (something_needs_reloads): Delete variable.
+ (finish_spills): New function.
+ (compute_use_by_pseudos): New function.
+
+ (delete_caller_save_insns): Lose argument FIRST. All callers changed.
+ Use the reload_insn_chain instead of walking the rtl directly.
+
+ (reload): Allocate and free spilled_pseudos.
+ Ensure that all calls of spill_hard_reg are followed by a call to
+ finish_spills.
+ Use the insns_need_reload list instead of something_needs_reloads
+ to find out if reload_as_needed must be called.
+ Clear unused_insn_chains at the end.
+
+ (calculate_needs_all_insns): Lose FIRST parameter. All callers
+ changed.
+ Delete code to keep track of current basic block.
+ Walk reload_insn_chain instead of the rtl structure. Build the
+ insns_need_reload chain.
+ Remember which insns need reloading/elimination by setting the
+ appropriate fields in struct insn_chain, not by putting modes on the
+ insn.
+
+ (calculate_needs): Lose THIS_BLOCK arg. Accept arg CHAIN instead of
+ arg INSN. All callers changed.
+ Delete declaration of struct needs.
+ Don't set something_needs_reloads.
+ Record insn needs in the CHAIN argument.
+
+ (spill_hard_reg): Record the affected pseudos in spilled_pseudos.
+
+ (reload_as_needed): Lose FIRST arg. All callers changed.
+ Walk the reload_insn_chain instead of the rtx structure.
+ Delete code to keep track of current basic block.
+ Rename one of the NEXT variables to OLD_NEXT.
+
+ (allocate_reload_reg): Accept arg CHAIN instead of arg INSN. All
+ callers changed.
+ (choose_reload_regs): Likewise.
+
+ (emit_reload_insns): Replace INSN and BB args with arg CHAIN. All
+ callers changed.
+
+ * caller-save.c (MOVE_MAX_WORDS): New macro. Use it throughout
+ instead of (MOVE_MAX / UNITS_PER_WORD) computation.
+ (hard_regs_live, hard_regs_need_restore): Delete variables.
+ (n_regs_saved): Now static.
+ (referenced_regs, this_insn_sets): New variables.
+
+ (setup_save_areas): Restructure the code a bit.
+
+ (restore_referenced_regs): Delete function.
+ (mark_referenced_regs): New function, similar to the old
+ restore_referenced_regs, but mark registers in referenced_regs.
+
+ (clear_reg_live): Delete function.
+ (mark_set_regs): Renamed from set_reg_live. All callers changed.
+ Only mark registers in this_insn_sets.
+
+ (save_call_clobbered_regs): Rework this function to walk the
+ reload_insn_chain instead of using the list of instructions directly.
+ Delete code to keep track of register lives, compute live regs on the
+ fly from information in the chain.
+ Instead of calling restore_referenced_regs, use mark_referenced_regs,
+ then walk the set it computes and call insert_restore as appropriate.
+
+ (insert_restore): Lose INSN and BLOCK args. Add CHAIN arg. All
+ callers changed.
+ Restructure the code a bit. Test hard_regs_saved instead of
+ hard_regs_need_restore.
+ (insert_save): Lose INSN and BLOCK args. Add CHAIN and TO_SAVE
+ args. All callers changed.
+ Restructure the code a bit. Use TO_SAVE to determine which regs to
+ save instead of more complicated test.
+ (insert_one_arg): Lose INSN and BLOCK args. Add CHAIN arg. All
+ callers changed.
+ Create a new insn_chain structure for the new insn and place it
+ into the chain.
+
+ * rtl.texi: Update documentation to reflect that reload no longer
+ puts modes on the insns.
+
+1998-10-14 Andreas Schwab <schwab@issan.cs.uni-dortmund.de>
+
+ * function.c (purge_addressof_1): Force the first argument of a
+ CALL insn to memory.
+
+Wed Oct 14 00:38:40 1998 Jeffrey A Law (law@cygnus.com)
+
+ * rtl.h: Delete duplicate prototypes. Add some missing
+ prototypes.
+ * rtlanal.c: (for_each_rtx): Formatting tweak.
+
+1998-10-13 Herman A.J. ten Brugge <Haj.Ten.Brugge@net.HCC.nl>
+
+ * real.c (emdnorm and etoasc): Disable round to even for c4x target
+ to be compatible with TI compiler.
+
+ * Makefile.in (USER_H): Add va-c4x.h to definition.
+
+Tue Oct 13 23:03:37 1998 Richard Henderson <rth@cygnus.com>
+
+ * function.c (purge_addressof_1): Fix typo in inequality: do
+ bitfield optimization for equal mode sizes.
+ * expmed.c (store_bit_field): Don't take subregs of subregs in
+ the movstrict case. Tidy a potential problem in the multi-word case.
+ (extract_bit_field): Likewise.
+
+Tue Oct 13 22:12:11 1998 Bernd Schmidt <crux@pool.informatik.rwth-aachen.de>
+
+ * flow.c (find_basic_blocks): Emit NOPs after normal calls in this
+ function.
+ Compute max_uid_for_flow by calling get_max_uid after the scan.
+ (find_basic_blocks_1): Don't emit NOPs here.
+
+Tue Oct 13 22:05:49 1998 Richard Henderson <rth@cygnus.com>
+
+ * alias.c (base_alias_check): Accept new args for the modes of the
+ two references. Use them to determine if an AND can overlap. Update
+ all callers.
+ (memrefs_conflict_p): Assume sizes are aligned, and uses them
+ to determine if an AND can overlap.
+
+Tue Oct 13 17:51:04 1998 Jim Wilson <wilson@cygnus.com>
+
+ * config/m68k/m68k.h (HARD_REGNO_MODE_OK): For FP regs, add REGNO >= 16
+ check. Add comment to document problems with TARGET_SUN_FPA version
+ of this macro.
+ * config/m68k/m68k.md (movxf+1): Support 'r'/'r' moves.
+
+Tue Oct 13 17:46:18 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * Makefile.in (gencheck.o): Depend on gansidecl.h.
+
+ * c-common.c (print_char_table): Add missing initializers.
+ (scan_char_table): Likewise.
+ (time_char_table): Likewise.
+
+ * c-decl.c (c_decode_option): Mark parameter `argc' with
+ ATTRIBUTE_UNUSED.
+ (declare_parm_level): Mark parameter `definition_flag' with
+ ATTRIBUTE_UNUSED.
+
+ * c-lex.c (readescape): Use `(unsigned)1' in shift.
+ (yylex): Likewise. Cast `sizeof' to an (int) when comparing
+ against one.
+
+ * calls.c (store_one_arg): Remove unused parameter `fndecl'. All
+ callers changed.
+ (emit_call_1): Mark parameters `fndecl' and `funtype' with
+ ATTRIBUTE_UNUSED.
+ (expand_call): Cast result of MIN() to (unsigned int) when
+ comparing against an unsigned value.
+
+ * cccp.c (pcfinclude): Remove unused parameter `limit'. All
+ callers changed.
+ (make_definition): Remove unused parameter `op'. All callers
+ changed.
+ (create_definition): Cast REST_EXTENSION_LENGTH to (long) when
+ comparing against the result of pointer arithmetic.
+
+ * config/mips/mips.h (FUNCTION_ARG_BOUNDARY): Cast to (unsigned)
+ when comparing against one.
+
+ * dwarf2out.c (dwarf2out_frame_debug): Cast REGNO() and
+ HARD_FRAME_POINTER_REGNUM to (unsigned) when comparing against
+ one.
+ (output_die): Move variable `i' into the scope in which it is
+ used. Change its type to `unsigned'.
+ (output_die): Cast the result of `strlen' to (int) when passing it
+ to ASM_OUTPUT_ASCII().
+ (output_pubnames): Likewise.
+ (output_line_info): Likewise.
+
+ * emit-rtl.c (global_rtl): Add missing initializers.
+
+ * explow.c (promote_mode): Mark parameter `for_call' with
+ ATTRIBUTE_UNUSED.
+
+ * expmed.c (expand_shift): Cast the result of GET_MODE_BITSIZE to
+ `unsigned HOST_WIDE_INT' when comparing against one.
+ (synth_mult): Change type of variable `cost' to int.
+ (emit_store_flag): Use `(unsigned HOST_WIDE_INT) 1' in shift.
+
+ * expr.c (copy_blkmode_from_reg): Cast BITS_PER_WORD to (unsigned)
+ when comparing against one.
+ (get_inner_reference): Change variable `alignment' to unsigned.
+ (expand_expr): Cast the result of GET_MODE_ALIGNMENT to (unsigned
+ int) when comparing against one.
+ (expand_builtin_setjmp): Change type of variable `i' to size_t.
+
+ * fold-const.c (div_and_round_double): Cast BASE to
+ (HOST_WIDE_INT) when comparing against one.
+
+ * gencheck.c: Include gansidecl.h.
+ (main): Mark parameter `argv' with ATTRIBUTE_UNUSED.
+
+ * optabs.c (gen_cond_trap): Mark parameters `code', `op2' and
+ `tcode' with ATTRIBUTE_UNUSED.
+
+ * real.c (edivm): Cast constant value to (unsigned long) in
+ expression compared against an unsigned value.
+
+ * stmt.c (expand_return): Cast BITS_PER_WORD to (unsigned) when
+ comparing against one.
+ (expand_end_case): Cast CASE_VALUES_THRESHOLD to (unsigned int)
+ when comparing against one.
+
+ * stor-layout.c (mode_for_size): Cast MAX_FIXED_MODE_SIZE to
+ (unsigned int) when comparing against one. Likewise for
+ GET_MODE_BITSIZE.
+ (smallest_mode_for_size): Likewise.
+ (save_storage_status): Mark parameter `p' with ATTRIBUTE_UNUSED.
+ (restore_storage_status): Likewise.
+
+ * toplev.c (debug_args): Add missing initializer.
+ (f_options): Spelling correction. Add missing initializers.
+ (documented_lang_options): Likewise.
+ (debug_end_source_file): Mark parameter `lineno' with
+ ATTRIBUTE_UNUSED.
+
+ * tree.c (valid_machine_attribute): Mark parameters `attr_args',
+ `decl' and `type' with ATTRIBUTE_UNUSED.
+
+ * varasm.c (decode_reg_name): Cast `sizeof' expression to (int)
+ when comparing against one.
+ (assemble_variable): Mark parameter `top_level' with
+ ATTRIBUTE_UNUSED.
+ (assemble_external_libcall): Mark parameter `fun' with
+ ATTRIBUTE_UNUSED.
+ (output_constant_pool): Mark parameters `fnname' and `fndecl' with
+ ATTRIBUTE_UNUSED.
+
+Tue Oct 13 12:51:04 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/v850/lib1funcs.asm (_udivsi3): Add .type declaration.
+ Replace use of r5 with use of r19.
+
+ * config/v850/v850.h (LINK_POINTER_REGNUM): Define.
+
+ * config/v850/v850.c (compute_register_save_size): Allow for the
+ fact that helper functions save all registers, not just those used
+ by the function.
+
+ Replace constant 31 with macro LINK_POINTER_REGNUM.
+
+ * config/v850/v850.md: Use 'indirect_operand' rather than
+ 'memory_operand' for bit test/set/clear patterns.
+
+Tue Oct 13 11:49:14 1998 Jason Merrill <jason@yorick.cygnus.com>
+
+ * mips/iris6.h (ASM_OUTPUT_WEAK_ALIAS): Call ASM_GLOBALIZE_LABEL.
+ * varasm.c (assemble_start_function et al): Don't call
+ ASM_GLOBALIZE_LABEL for weak symbols.
+
+Tue Oct 13 11:37:45 1998 Nick Clifton <nickc@cygnus.com>
+
+ * cse.c (equiv_constant): Check for NULL return from
+ gen_lowpart_if_possible().
+
+Tue Oct 13 11:24:51 1998 Jeffrey A Law (law@cygnus.com)
+
+ * mn10200.md (addsi3, subsi3, negsi2): Only allow register operands.
+
+ * collect2.c (main): Pass -EL/-EB through to the compiler.
+
+1998-10-12 Herman A.J. ten Brugge <Haj.Ten.Brugge@net.HCC.nl>
+
+ * expr.c (push_block): Handle targets where the stack grows
+ to higher addresses, but args grow to lower addresses and
+ ACCUMULATE_OUTGOING_ARGS is not defined.
+
+Tue Oct 13 08:00:52 1998 Catherine Moore <clm@cygnus.com>
+
+ * config/v850/v850.c (print_operand): Extend meaning
+ of 'c' operands to support .vtinherit.
+
+Tue Oct 13 21:38:35 1998 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
+
+ * config/c4x/c4x.c: Convert to gen_rtx_FOO.
+ Added ATTRIBUTE_UNUSED to unused function arguments.
+ (rc_reg_operand): New predicate.
+ (c4x_rptb_insert): New function.
+ (c4x_rptb_nop_p): Recognize modified rptb_top pattern.
+ (c4x_optimization_options): New function.
+
+ * config/c4x/c4x.md: Convert to gen_rtx_FOO.
+ (decrement_and_branch_on_count): New pattern.
+ (rptb_top): Modified pattern to work with BCT optimization.
+
+ * config/c4x/c4x.h (RC_REG): New register class.
+ (rc_reg_operand): Define prototype.
+ (IS_RC_REG): New macro.
+ (IS_RC_OR_PSEUDO_REG): New macro.
+ (IS_RC_OR_PSEUDO_REGNO): New macro.
+ (OPTIMIZATION_OPTIONS): Define.
+
+Mon Oct 12 19:57:34 1998 Jason Merrill <jason@yorick.cygnus.com>
+
+ * collect2.c (extract_init_priority): No priority is 65535.
+
+Mon Oct 12 12:10:37 1998 Alexandre Oliva <oliva@dcc.unicamp.br>
+
+ * Makefile.in (build_tooldir): new variable, same as old
+ $(tooldir), but without depending on $(libdir)/$(unlibsubdir)
+ (GCC_FOR_TARGET): add -B$(build_tooldir)/bin/
+ (bootstrap, bootstrap2, bootstrap3, bootstrap4): ditto
+
+ * configure.in (gxx_include_dir): set default based on unlibsubdir
+ * Makefile.in (tooldir): ditto
+ (cccp.o, cpplib.o): use unlibsubdir implicitly through
+ gxx_include_dir, includedir and tooldir
+ (protoize.o, unprotoize.o): ditto
+
+Mon Oct 12 10:50:44 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/arm/arm.md: Replace (reg 24) with (reg:CC 24).
+
+ * config/arm/thumb.c (thumb_override_options): Add warning about
+ PIC code not being supported just yet.
+
+Sun Oct 11 16:49:15 EDT 1998 John Wehle (john@feith.com)
+
+ * flow.c: Update comment.
+ (notice_stack_pointer_modification): New static function.
+ (record_volatile_insns): Use it.
+ (mark_regs_live_at_end): Mark the stack pointer as alive
+ at the end of the function if current_function_sp_is_unchanging
+ is set.
+ (life_analysis_1): Set current_function_sp_is_unchanging.
+ * function.c: Define it.
+ (init_function_start): Initialize it.
+ * output.h: Declare it.
+ * reorg.c (fill_simple_delay_slots, dbr_schedule): Mark
+ the stack pointer as alive at the end of the function if
+ current_function_sp_is_unchanging is set.
+ * i386.c (ix86_epilogue): Optimize the restoring
+ of the stack pointer.
+
+Mon Oct 12 01:22:53 PDT 1998 Jeff Law (law@cygnus.com)
+
+ * version.c: Bump for snapshot.
+
+Sun Oct 11 23:04:30 1998 Robert Lipe <robertl@dgii.com>
+
+ * c-pragma.c (handle_pragma_token): If passed a token instead
+ of a tree, use that as the pack value.
+
+Sun Oct 11 14:21:14 1998 Mark Mitchell <mark@markmitchell.com>
+
+ * flow.c (find_basic_blocks_1): Fix prototype.
+
+Sun Oct 11 05:03:41 1998 Ken Raeburn <raeburn@cygnus.com>
+
+ * tree.h (DECL_NO_CHECK_MEMORY_USAGE): New macros.
+ (struct tree_decl): New fields no_check_memory_usage.
+ * c-common.c (enum attrs): Add A_NO_CHECK_MEMORY_USAGE.
+ (init_attributes): Register it as a new attribute.
+ (decl_attributes): Set flags on functions given that attribute.
+ * c-decl.c (duplicate_decls): Merge new attribute.
+ * expr.h (current_function_check_memory_usage): Declare new var.
+ * calls.c, expr.c, function.c, stmt.c, alpha.c, clipper.c, m88k.c,
+ pa.c, sparc.c: Replace uses of flag_check_memory_usage with
+ current_function_check_memory_usage.
+ * function.h: Add field to struct function.
+ * function.c (current_function_check_memory_usage): Define it.
+ (push_function_context_to, pop_function_context_from): Save and
+ restore it.
+ (expand_function_start): Set it, based on global flag and function
+ attribute.
+
+ * expr.c (expand_expr, case VAR_DECL): In memory-checking code, do
+ check non-automatic variables, to permit detection of writes to
+ read-only locations in embedded systems without memory management.
+ * calls.c (store_one_arg): Use ARGS_SIZE_RTX to get size of argument
+ when emitting chkr_set_right_libfunc call, even if the argument is
+ BLKmode or variable-sized; don't abort.
+
+ * optabs.c (init_optabs): Create Checker and __cyg_profile_*
+ symbols in Pmode, not VOIDmode.
+
+Sun Oct 11 01:03:05 1998 Zack Weinberg <zack@rabi.phys.columbia.edu>
+
+ * cppexp.c: When forcing unsigned comparisons, cast both sides
+ of the operation.
+
+ * cpphash.h: Move static declaration of hashtab[]...
+ * cpphash.c: ...here.
+
+ * cpplib.c: Cast difference of two pointers to size_t before
+ comparing it to size_t. Cast signed to unsigned
+ before comparing to size_t. (FIXME: struct argdata should use
+ unsigned buffer sizes.)
+ * cpplib.h (struct cpp_reader): Declare token_buffer_size as
+ unsigned int. (CPP_WRITTEN): Cast return value to size_t.
+ (CPP_RESERVE): Parenthesize N for evaluation order, cast to
+ size_t before comparison.
+
+Sun Oct 11 00:15:29 1998 Jeffrey A Law (law@cygnus.com)
+
+ * flow.c (find_basic_blocks): Delete "live_reachable_p" argument.
+ (find_basic_blocks_1): Similarly.
+ * output.h (find_basic_blocks): Fix prototype.
+ * gcse.c, toplev.c: Don't pass "live_reachable_p" argument to
+ find_basic_blocks anymore.
+
+Sat Oct 10 22:00:34 1998 Richard Henderson <rth@cygnus.com>
+
+ * basic-block.h (EXECUTE_IF_SET_IN_SBITMAP): New macro.
+ (sbitmap_free, sbitmap_vector_free): New macros.
+ * output.h (rtl_dump_file): Declare.
+
+Sat Oct 10 17:01:42 1998 Jeffrey A Law (law@cygnus.com)
+
+ * regmove.c (optimize_reg_copy_3): Honor TRULY_NOOP_TRUNCATION.
+
+Fri Oct 9 22:08:05 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * fp-bit.c (SFtype): Don't implicitly use int in declaration.
+ (DFtype): Likewise.
+ (_fpdiv_parts): Remove unused parameter `tmp', all callers changed.
+ (divide): Remove unused variable `tmp'.
+ (si_to_float): Cast numeric constant to (SItype) before comparing
+ it against one.
+
+Fri Oct 9 16:03:19 1998 Graham <grahams@rcp.co.uk>
+
+ * flow.c (print_rtl_with_bb): Changed type of in_bb_p to match use.
+ * gcc.c (add_preprocessor_option): Correct typo when allocating
+ memory, sizeof() argument had one too many `*'.
+ (add_assembler_option): Likewise.
+ (add_linker_option): Likewise.
+ * gcov.c (output_data): Likewise.
+ * local-alloc.c (memref_used_between_p): Likewise.
+ (update_equiv_regs): Likewise.
+ * loop.c (strength_reduce): Likewise.
+ * reg-stack.c (record_asm_reg_life): Likewise.
+ (subst_asm_stack_reg): Likewise.
+ * reorg.c (dbr_schedule): Likewise.
+
+Fri Oct 9 15:57:51 1998 Bernd Schmidt <crux@Pool.Informatik.RWTH-Aachen.DE>
+
+ * flow.c (life_analysis_1): Break out some functions.
+ (find_basic_blocks_1): Likewise. Also move some variables out and
+ make them static.
+ Rename NONLOCAL_LABEL_LIST arg to NONLOCAL_LABELS and initialize
+ new static var nonlocal_label_list with it.
+ (active_eh_region, nested_eh_region, label_value_list,
+ nonlocal_label_list): New static variables.
+ (make_edges, delete_unreachable_blocks, delete_block): New static
+ functions, broken out of find_basic_blocks_1.
+ (record_volatile_insns, mark_regs_live_at_end, set_noop_p,
+ noop_move_p): New static functions, broken out of life_analysis_1.
+
+Fri Oct 9 15:49:29 1998 Richard Henderson <rth@cygnus.com>
+
+ * expmed.c (store_bit_field): Pun non-integral str_rtx modes.
+ Take extra care for op0 now possibly being a subreg.
+ (extract_bit_field): Likewise.
+ * function.c (purge_addressof_1): Revert Oct 4 change. Drop
+ the reg to memory if there is no equal sized integral mode.
+ * stor-layout.c (int_mode_for_mode): New function.
+ * machmode.h: Prototype it.
+
+Fri Oct 9 14:26:44 1998 Jeffrey A Law (law@cygnus.com)
+
+ * global.c (build_insn_chain): Verify no real insns exist past the
+ end of the last basic block, then exit the loop.
+
+Fri Oct 9 11:44:47 1998 David Edelsohn <edelsohn@gnu.org>
+
+ * loop.c (insert_bct): Ensure loop_iteration_var non-zero before use.
+
+Thu Oct 8 21:59:47 1998 Dave Brolley <brolley@cygnus.com>
+
+ * emit-rtl.c (init_emit_once): Call INIT_EXPANDERS.
+
+Thu Oct 8 22:03:45 1998 David Edelsohn <edelsohn@gnu.org>
+
+ * rs6000.h (RTX_COSTS): Add PROCESSOR_PPC604e cases.
+
+Thu Oct 8 17:00:18 1998 Richard Henderson <rth@cygnus.com>
+
+ * flow.c (find_basic_blocks): Correctly determine when a call
+ is within an exception region.
+
+Thu Oct 8 17:15:04 1998 Jeffrey A Law (law@cygnus.com)
+
+ * toplev.c (output_file_directive): Use DIR_SEPARATOR, not '/'.
+
+ * cpplib.h: Protect from multiple inclusions.
+ * cpplib.c: Fix minor formatting problems.
+
+ * i386/xm-cygwin32.h: Only define POSIX if it is not already defined.
+
+ * jump.c (jump_optimize): Revert accidental patch.
+
+ * Makefile.in (cpplib.o): Use unlibsubdir.
+
+Thu Oct 8 12:50:47 1998 Jim Wilson <wilson@cygnus.com>
+
+ * loop.c (get_condition): Allow combine when either compare is
+ VOIDmode.
+
+Thu Oct 8 11:31:01 PDT 1998 Jeff Law (law@cygnus.com)
+
+ * version.c: Bump for snapshot.
+
+Thu Oct 8 12:21:14 1998 Richard Frith-Macdonald <richard@brainstorm.co.uk>
+
+ * c-lex.c (remember_protocol_qualifiers): Handle RID_BYREF.
+ (init_lex): Initialize ridpointers[RID_BYREF].
+ * c-lex.h (enum rid): Add RID_BYREF.
+ * c-parse.gperf: Add RID_BYREF as a type qualifier.
+ * objc/objc-act.c (is_objc_type_qualifiers): Handle RID_BYREF.
+ (encode_type_qualifiers): Similarly
+ * c-gperf.h: Rebuilt.
+
+Thu Oct 8 05:56:00 1998 Jeffrey A Law (law@cygnus.com)
+
+ * c-common.c (type_for_mode): Only return TItype nodes when
+ HOST_BITS_PER_WIDE_INT is >= 64 bits.
+ * c-decl.c (intTI_type_node, unsigned_intTI_type_node): Only declare
+ when HOST_BITS_PER_WIDE_INT is >= 64 bits.
+ (init_decl_processing): Only create TItype nodes when
+ HOST_BITS_PER_WIDE_INT is >= 64 bits.
+ * c-tree.h (intTI_type_node, unsigned_intTI_type_node): Only declare
+ when HOST_BITS_PER_WIDE_INT is >= 64 bits.
+
+Thu Oct 8 05:05:34 1998 Bernd Schmidt <crux@Pool.Informatik.RWTH-Aachen.DE>
+
+ * stmt.c (n_occurrences): New static function.
+ (expand_asm_operands): Verify that all constrains match in the
+ number of alternatives.
+ Verify that '+' or '=' are at the beginning of an output constraint.
+ Don't allow '&' for input operands.
+ Verify that '%' isn't written for the last operand.
+ * reload.c (find_reloads): Abort if an asm is found with invalid
+ constraints; all possible problems ought to be checked for earlier.
+
+Thu Oct 8 04:26:20 1998 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
+
+ * flags.h (flag_branch_on_count_reg): Always declare
+ * toplev.c (flag_branch_on_count_reg): Likewise.
+ * toplev.c: Fix typos.
+
+ * real.c (c4xtoe): Remove unused variables. Add some missing parens.
+ (toc4x): Similarly.
+
Thu Oct 8 01:25:22 1998 Richard Henderson <rth@cygnus.com>
* flow.c (find_basic_blocks): Calc upper bound for extra nops in
@@ -201,7 +9842,7 @@ Mon Oct 5 22:34:30 1998 Alexandre Petit-Bianco <apbianco@cygnus.com>
* expr.c (expand_expr): Expand GOTO_EXPR into a goto or a computed
goto.
-Mon Oct 5 22:43:36 1998 David Edelsohn <edelsohn@mhpcc.edu>
+Mon Oct 5 22:43:36 1998 David Edelsohn <edelsohn@gnu.org>
* unroll.c (loop_iteration_var, loop_initial_value, loop_increment
loop_final_value, loop_comparison_code): No longer static.
@@ -648,7 +10289,7 @@ Mon Sep 28 04:11:35 1998 Jeffrey A Law (law@cygnus.com)
* cpp.texi: Update for Fortran usage from Craig.
-Fri Sep 25 22:09:47 1998 David Edelsohn <edelsohn@mhpcc.edu>
+Fri Sep 25 22:09:47 1998 David Edelsohn <edelsohn@gnu.org>
* rs6000.c (function_arg_boundary): Revert accidental change on
September 18.
@@ -1035,7 +10676,7 @@ Fri Sep 18 22:52:05 1998 Jeffrey A Law (law@cygnus.com)
(MEM (reg_equiv_addr)) in the initializing insn for the
pseudo.
-Fri Sep 18 23:50:56 1998 David Edelsohn <edelsohn@mhpcc.edu>
+Fri Sep 18 23:50:56 1998 David Edelsohn <edelsohn@gnu.org>
* toplev.c (rest_of_compilation): Set bct_p on second call to
loop_optimize.
@@ -1774,7 +11415,7 @@ Thu Sep 3 18:16:16 1998 Michael Meissner <meissner@cygnus.com>
* rs6000.c (rs6000_override_options): Add -mcpu={401,e603e}.
-Thu Sep 3 18:05:16 1998 David Edelsohn <edelsohn@mhpcc.edu>
+Thu Sep 3 18:05:16 1998 David Edelsohn <edelsohn@gnu.org>
* rs6000.md (movsf): Disable explicit secondary-reload-like
functionality if TARGET_POWERPC64.
@@ -2325,7 +11966,7 @@ Tue Aug 25 01:15:27 1998 J"orn Rennecke <amylaar@cygnus.co.uk>
* reload1.c (reload_cse_regs_1): When deleting a no-op move that
loads the function result, substitute with a USE.
-Mon Aug 24 15:20:19 1998 David Edelsohn <edelsohn@mhpcc.edu>
+Mon Aug 24 15:20:19 1998 David Edelsohn <edelsohn@gnu.org>
* rs6000.h (GO_IF_LEGITIMATE_ADDRESS): Use TARGET_POWERPC64
when testing LEGITIMATE_INDEXED_ADDRESS_P DFmode and DImode.
@@ -2446,7 +12087,7 @@ Thu Aug 20 13:56:53 1998 Michael Meissner <meissner@cygnus.com>
sys/param.h pulled in before rtl.h in case the system defines MIN
and MAX.
-Thu Aug 20 13:44:20 1998 David Edelsohn <edelsohn@mhpcc.edu>
+Thu Aug 20 13:44:20 1998 David Edelsohn <edelsohn@gnu.org>
* rs6000.md (movqi, movhi): Add CONSTANT_P_RTX.
@@ -2456,7 +12097,7 @@ Thu Aug 20 13:15:11 1998 Dave Brolley <brolley@cygnus.com>
arrays of bits.
* cpplib.c (cpp_define): Handle macros with parameters.
-Wed Aug 19 21:33:19 1998 David Edelsohn <edelsohn@mhpcc.edu>
+Wed Aug 19 21:33:19 1998 David Edelsohn <edelsohn@gnu.org>
* rs6000.c (rs6000_output_load_toc_table): Use ld for 64-bit.
(output_toc): Use single TOC slot or llong minimal-toc for DFmode
@@ -2717,7 +12358,7 @@ Sun Aug 16 17:37:06 1998 David S. Miller <davem@pierdol.cobaltmicro.com>
(sidi zero/sign extension insns on arch64): Set type to shift.
(sign_extendhidi2_insn): Set type to sload.
-Sun Aug 16 13:52:00 1998 David Edelsohn <edelsohn@mhpcc.edu>
+Sun Aug 16 13:52:00 1998 David Edelsohn <edelsohn@gnu.org>
* rs6000.c (rs6000_stack_info): Use if == 0 for sizes.
(output_epilog): Use if != 0 for offset.
@@ -2733,7 +12374,7 @@ Sun Aug 16 01:53:21 1998 Richard Henderson <rth@cygnus.com>
* reload.c (find_equiv_reg): Reject equivalences separated
by a volatile instruction.
-Sun Aug 16 00:21:44 1998 Franz Sirl <Franz.Sirl-kernel@lauterbach.com>
+Sun Aug 16 00:21:44 1998 Franz Sirl <Franz.Sirl-kernel@lauterbach.com>
* rs6000/linux.h (CPP_OS_DEFAULT_SPEC): Define.
@@ -3359,7 +13000,7 @@ Thu Jul 30 19:15:53 1998 Richard Henderson <rth@cygnus.com>
* alpha.md (fp cmp): Replicate patterns for ALPHA_TP_INSN.
(fcmov): Remove ALPHA_TP_INSN patterns -- fcmov doesn't trap.
-Thu Jul 30 19:50:15 1998 David Edelsohn <edelsohn@mhpcc.edu>
+Thu Jul 30 19:50:15 1998 David Edelsohn <edelsohn@gnu.org>
* rs6000/x-aix43 (AR_FOR_TARGET_FLAGS): Delete.
(AR_FOR_TARGET): Define.
@@ -3429,7 +13070,7 @@ Wed Jul 29 22:39:21 1998 Jeffrey A Law (law@cygnus.com)
or UNROLL_COMPLETELY loop that starts with a jump to its
exit code.
-Wed Jul 29 22:18:14 1998 David Edelsohn <edelsohn@mhpcc.edu>
+Wed Jul 29 22:18:14 1998 David Edelsohn <edelsohn@gnu.org>
* rs6000/rs6000.md (absdi2 define_split): Swap operands of MINUS.
* rs6000/rs6000.c (mask64_operand): Use HOST_BITS_PER_WIDE_INT.
@@ -3629,7 +13270,7 @@ Sun Jul 12 01:27:05 1998 Jason Merrill <jason@yorick.cygnus.com>
constants here.
(fold, case COMPOUND_EXPR): Wrap a constant 0 in a NOP_EXPR.
-Tue Jul 21 15:49:31 1998 David Edelsohn <edelsohn@mhpcc.edu>
+Tue Jul 21 15:49:31 1998 David Edelsohn <edelsohn@gnu.org>
* rs6000.h (PREDICATE_CODES): Add CONSTANT_P_RTX.
* rs6000.md (movsi, movdi): Add CONSTANT_P_RTX.
diff --git a/gcc/FSFChangeLog b/gcc/FSFChangeLog
index 5a9c6cfec75..261934c3d12 100644
--- a/gcc/FSFChangeLog
+++ b/gcc/FSFChangeLog
@@ -1,5 +1,652 @@
+Tue Sep 29 09:57:26 1998 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * expr.c (get_inner_reference): Fix typo in last change.
+
+Mon Sep 27 21:34:00 1998 Paul Eggert <eggert@twinsun.com>
+
+ * po/en_UK.po (Project-Id-Version): Set to cc 2.8.1.19980813 for now.
+ (PO-Revision-Date): Set to the current date.
+
+Sun Sep 27 07:33:18 1998 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * m68k/vxm68k.h (LINK_SPEC): Always use -r.
+ (WIDEST_HARDWARE_FP_SIZE): Define.
+
+ * reload.c (push_reload): If in STRICT_LOW_PART, always reload
+ inside even if SUBREG_WORD is not zero.
+
+ * flow.c (print_rtl_with_bb): Don't say not in basic block if we
+ aren't making basic blocks.8
+
+Sat Sep 26 10:57:09 1998 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * function.c (optimize_bit_field): Don't remove SUBREG from dest
+ if SUBREG_REG is multi-word.
+
+Wed Sep 23 05:43:23 1998 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * reload.c (find_reloads_address): Deal with address which is
+ an AND; clean up return values some more.
+
+Fri Sep 11 13:02:26 1998 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * function.c (purge_addressof_1): Properly copy flags when making MEM.
+
+Mon Sep 7 18:33:06 1998 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * expr.c (get_inner_reference): If not COMPONENT_REF or BITFIELD_REF
+ and mode is BLKmode, set size_tree.
+
+ * expr.c (expand_builtin, case BUILT_IN_LONGJMP): Fix typo in
+ last change.
+
+Wed Sep 2 15:38:01 1998 Paul Eggert <eggert@twinsun.com>
+
+ * libgcc2.c (__floatdisf): Use signed comparison to test
+ whether u is close to zero; unsigned comparison is not what's
+ wanted here.
+
+Mon Aug 17 02:19:30 1998 David Edelsohn <edelsohn@mhpcc.edu>
+
+ * xcoffout.c (UNKNOWN_STAB): Fix typo in previous change; missing
+ backslash before newline.
+
+Mon Aug 17 00:12:42 1998 Paul Eggert <eggert@twinsun.com>
+
+ * reorg.c (check_annul_list_true_false): Fix typo in Jul 17 change.
+
+Sun Aug 2 01:10:15 1998 Paul Eggert <eggert@twinsun.com>
+
+ Add Native Language Support.
+
+ * intl/, ABOUT-NLS, mkinstalldirs, po/Makefile.in.in: New
+ subdirectory and files. They should be kept identical to the
+ corresponding items from the GNU gettext distribution.
+
+ * ABOUT-GCC-NLS, exgettext, intl.c, intl.h, po/POTFILES.in,
+ po/en_UK.po: New files.
+
+ * Makefile.in (AWK, datadir, localedir, top_builddir, USE_NLS,
+ INTLLIBS, POSUB, INTL_SUBDIRS, HOST_INTLLIBS,
+ PREPEND_DOTDOT_TO_RELATIVE_PATHS, SUBDIR_FLAGS_TO_PASS, GCC_OBJS,
+ COLLECT2_OBJS, CCCP_OBJS, CPPMAIN_OBJS, PROTO_OBJS, GCOV_OBJS,
+ INTL_DISTCLEAN, GEN_PROTOS_OBJS): New vars.
+ (LIBDEPS, LIBS): Add $(INTLLIBS).
+ (HOST_LIBDEPS, HOST_LIBS): Add $(HOST_INTLLIBS).
+ (LIBS): Add @LIBS@.
+ (ORDINARY_FLAGS_TO_PASS): New var, containing all the old values
+ from FLAGS_TO_PASS, except for CC.
+ (FLAGS_TO_PASS): Pass datadir, distdir, localedir.
+ (OBJS): Add intl.o.
+ (GEN): Add gencheck.
+ (STAGESTUFF): Add tree-check.h, gencheck$(exeext).
+ (native): Depend on intl.all.
+ (xgcc, collect2, cccp, cppmain, protoize, unprotoize, gcov): Link
+ intl.o.
+ (c-typeck.o, c-lex.o, collect2.o, gcc.o, toplev.o, integrate.o,
+ final.o, cccp.o, cppmain.o, cpplib.o, cpperror.o, s-proto,
+ gcov.o): Depend on intl.h.
+ (gencheck): Depend on $(HOST_LIBDEPS) instead of tree.h and
+ tree.def.
+ (gencheck.o, intl.o, $(top_builddir)/intl/libintl.a,
+ $(srcdir)/cp/parse.c, intl.all, intl.install, intl.uninstall,
+ intl.distdir, intl.mostlyclean, intl.clean, intl.distclean,
+ intl.maintainer-clean, intl.distdir-fixup, distdir-check): New
+ rules.
+ (gen-protos): Link cpperror.o, cppexp.o, cpphash.o, cpplib.o,
+ prefix.o, version.o; needed for `cpp_notice'.
+ (mostlyclean): Depend on intl.mostlyclean.
+ (clean): Depend on intl.clean.
+ (distclean): Depend on intl.disclean, unless the invoker defines
+ INTL_DISTCLEAN to be empty. Remove intl/libintl.h and libintl.h
+ (created by configure).
+ (maintainer-clean): Make intl.maintainer-clean, but define
+ INTL_DISTCLEAN to be empty.
+ (install-normal): Depend on intl.install.
+ (uninstall): Depend on intl.uninstall.
+ (distdir-start): Make sure invoker configured with --enable-nls.
+ Use $(AWK), not awk. Make tmp/intl and tmp/po directories.
+ (distdir-finish): Make distdir-check at the end.
+ (distdir): Depend on intl.distdir, intl.distdir-fixup.
+ (compare, compare3, gnucompare, gnucompare3, stage1-start,
+ stage2-start, stage3-start, stage4-start): Handle intl
+ subdirectory.
+
+ * acconfig.h (ENABLE_NLS, HAVE_CATGETS, HAVE_GETTEXT,
+ HAVE_LC_MESSAGES, HAVE_STPCPY, PACKAGE, VERSION): New macros.
+
+ * aclocal.m4 (AC_ISC_POSIX, AM_WITH_NLS, AM_GNU_GETTEXT,
+ AM_LC_MESSAGES, AM_PATH_PROG_WITH_TEST): New functions; taken from
+ gettext distribution.
+
+ * bi-arity.c, bi-opcode.c, bi-opname.c: Include config file first.
+
+ * c-common.c: Don't include <ctype.h>.
+ (tfaff): Now a function, not a string. All users changed.
+ (check_format_info): Use is_C_digit, not isdigit.
+ Reword messages to ease localization.
+
+ * c-decl.c (redeclaration_error_message): Now returns int, not
+ message.
+ (poplevel, duplicate_decls, pushdecl): Revamp to pass explicit
+ strings to diagnostic generators.
+ (duplicate_decls, parmlist_tags_warning, finish_struct): Reword
+ messages to ease localization.
+
+ * c-iterate.c (prdecl): Reword messages so that they do not require
+ localization.
+
+ * c-lex.c: Include limits.h if available.
+ Include intl.h.
+ Include ctype.h only if MAP_CHARACTER is defined.
+ (UCHAR_MAX): Define if limits.h doesn't.
+ (C_alnum_array): New var.
+ (init_lex): Initialize it.
+ (yyerror): Localize msgid arg.
+ (yylex): Use is_C_alnum and is_C_digit, not isalnum and isdigit.
+
+ * c-lex.h (C_alnum_array): New decl.
+ (is_C_alnum, is_C_digit): New macros.
+
+ * c-typeck.c: Include intl.h.
+ (warning_init): Now takes just one arg.
+ (incomplete_type_error, build_unary_op, lvalue_or_else,
+ readonly_warning, build_modify_expr): Reword messages to ease
+ localization.
+ (build_unary_op, readonly_warning): Revamp to pass explicit
+ strings to diagnostic generators.
+ (build_modify_expr, warn_for_assignment, c_expand_return):
+ Translate strings passed to functions expecting translated
+ strings.
+ (get_spelling): Remove; it was a no-op. All callers changed.
+ (error_init, pedwarn_init): Now takes just one arg. All callers
+ and decls changed. This makes it easier to localize.
+
+ * cccp.c: Include intl.h.
+ (char_name): Remove.
+ (check_macro_name): Now takes int 2nd arg, not char *. All
+ callers changed.
+ (macarg): Now returns int, not char *. All callers changed.
+ (notice, vnotice, pedwarn_strange_white_space): New functions.
+ (verror): Now extern; used by cexp.y.
+ (main): Set message locale, and defer memory allocation until
+ after.
+ (main, do_include, print_containing_files): Invoke `notice' to
+ localize notices.
+ (handle_directive): Invoke pedwarn_strange_white_space instead of
+ using char_name.
+ (do_include, check_macro_name): Reword messages to ease
+ localization.
+ (my_strerror): Reword message so that it does not require
+ localization.
+ (verror, vwarning, verror_with_line, vwarning_with_line,
+ pedwarn_with_file_and_line, fatal): Invoke vnotice to localize
+ msgid.
+ (initialize_char_syntax): No need to initialize char_name.
+
+ * cexp.y (yyerror): Now takes msgid format and args, not just string.
+ (verror): New decl.
+ (parse_number, yylex): Reword messages to ease
+ localization.
+ (verror): New test function.
+ (pedwarn, warning): Translate msgid arg.
+
+ * collect2.c: Include intl.h.
+ (my_strerror, main, collect_execute, scan_prog_file,
+ scan_libraries, read_file, end_file): Reword messages so that they
+ do not require localization.
+ (notice): Nwe function.
+ (fatal, error, main, collect_execute, maybe_unlink,
+ write_c_file_stat, locatelib, scan_libraries, scan_prog_file,
+ add_func_table): Use it to translate msgid strings.
+ (main): Set message locale, and defer memory allocation until
+ after.
+ (collect_wait): Reword messages to ease localization.
+ (bad_header): Revamp to pass explicit strings to diagnostic
+ generators.
+
+ * combine.c (dump_combine_stats, dump_combine_total_stats):
+ Use fnotice to translate diagnostic messages.
+
+ * config/1750a/1750a.c (memop_valid): Don't use `valid' as an
+ identifier; it runs afoul of SunOS 4.1.4 <locale.h>.
+
+ * config/arc/initfini.c (__do_global_dtors): Put backslash before
+ newline in strings, to pacify xgettext.
+
+ * config/dsp16xx/dsp16xx.c, config/dsp16xx/dsp16xx.h
+ (dsp16xx_invalid_register_for_compare): New function.
+ * config/dsp16xx/dsp16xx.md: Use it to report invalid registers.
+
+ * config/i370/i370.h: Include <ctype.h>.
+
+ * config/i386/i386.c: Include config.h first.
+
+ * config/m32r/initfini.c (__do_global_dtors): Put backslash before
+ newline in strings, to pacify xgettext.
+ * config/m88k/dguxbcs.h (CPP_SPEC): Likewise.
+
+ * config/rs6000/rs6000.c: Include config.h first.
+ * config/rs6000/rs6000.c, config/rs6000/rs6000.h
+ (rs6000_fatal_bad_address): New function.
+ * config/rs6000/rs6000.md: Use it to report bad addresses.
+
+ * config/v850/v850.c: Include config.h first.
+
+ * configure.in: When generating config.h and mentioning a file
+ taken from the config directory, surround it with #ifdef IN_GCC,
+ so that programs compiled without IN_GCC -- notably in the intl
+ subdirectory -- don't need to be compiled with -Iconfig.
+ (PACKAGE, VERSION, ALL_LINGUAS): New vars.
+ (AC_ARG_ENABLE): Add --enable-nls.
+ (AM_GNU_GETTEXT): Add. Override XGETTEXT so that we use exgettext
+ instead of xgettext to extract strings.
+ (all_outputs): Add intl/Makefile, po/Makefile.in.
+ Do not use the shell variable 'l'; it runs afoul of gettext's
+ aclocal mechanism!
+ If libintl.h is created, echo '#include "intl/libintl.h"'
+ >libintl.h so that we don't have to futz with our include paths.
+
+ * cp/Make-lang.in (g++.o): Depend on gansidecl.h, intl.h, Makefile;
+ do not depend on config.status.
+ (GXX_OBJS): New var.
+ (g++$(exeext)): Link intl.o.
+
+ * cp/Makefile.in (top_builddir, INTLLIBS): New vars.
+ (LIBS): Add $(INTLLIBS).
+
+ * cppalloc.c (memory_full): Use `cpp_notice' to print diagnostic.
+
+ * cpperror.c: Include intl.h.
+ (cpp_print_containing_files): Use cpp_notice to translate messages.
+ (cpp_message): is_error is -1 for notices. Translate "warning:".
+ (cpp_fatal): Translate msgid arg.
+
+ * cppexp.c (cpp_lex): Revamp to pass explicit strings to
+ diagnostic generators.
+ (cpp_parse_expr): Use cpp_error, not fprintf, to report
+ unimplemented operators.
+
+ * cpplib.c: Include intl.h.
+ (check_macro_name): Now takes int 2nd arg, not char *. All
+ callers changed.
+ (check_macro_name, do_define): Reword messages to ease
+ localization.
+ (do_define): Revamp to pass explicit strings to diagnostic
+ generators.
+ (do_define, cpp_start_read, cpp_handle_options): Use cpp_notice to
+ translate messages.
+ (cpp_error, cpp_warning, cpp_warning_with_line,
+ cpp_pedwarn_with_file_and_line): Translate msgid arg.
+ (cpp_notice): New function.
+ (my_strerror): Reword message so that it does not require
+ localization.
+
+ * cpplib.h (cpp_notice): New decl.
+
+ * cppmain.c: Include intl.h.
+ (main): Set message locale.
+
+ * cse.c (cse_main): Use fnotice to print diagnostic.
+
+ * final.c: Include intl.h; do not include ctype.h.
+ (output_operand_lossage): Translate msgid arg.
+
+ * fold-const.c (optimize_bit_field_compare, fold_truthop): Reword
+ messages to ease localization.
+
+ * gcc.c: Include intl.h.
+ (my_strerror, snapshot_warning): Reword messages so that they do
+ not require localization.
+ (init_spec, set_spec, read_specs, execute, do_spec_1, main,
+ snapshot_warning): Invoke `notice' to localize notices.
+ (struct switchstr): Don't use `valid' as an identifier; it runs
+ afoul of SunOS 4.1.4 <locale.h>. All uses changed.
+ (do_spec_1): Treat %e string as msgid format, which needs
+ translation.
+ (main): Set message locale.
+ (pfatal_with_name): Invoke perror_with_name, not fatal, so that we
+ don't have to translate "%s: %s".
+ (perror_with_name): Invoke printf, not error, so that we don't
+ have to translate "%s: %s".
+ (pfatal_pexecute): Invoke pfatal_with_name, not fatal, so that we
+ don't have to translate "%s: %s".
+ (fatal, error): Translate msgid arg.
+ (notice): New function.
+
+ * gcov.c: Include intl.h; include stdarg.h if __STDC__ is defined.
+ (main): Set message locale.
+ (fnotice): New function.
+ (xmalloc, fancy_abort, print_usage, open_files, read_files,
+ function_summary, output_data): Use it to to print diagnostics.
+
+ * install.texi: Explain new configure options --enable-nls,
+ --with-included-gettext, --with-catgets.
+
+ * integrate.c: Include intl.h.
+ (function_cannot_inline_p): Mark msgids with N_.
+
+ * invoke.texi: Describe environment variables affecting locale.
+
+ * pexecute.c: Include libintl.h if ENABLE_NLS, otherwise define
+ gettext to be a noop.
+ (_, N_): New macros.
+ (install_error_msg): Wrap inside N_.
+ (pexecute): Translate diagnostics.
+
+ * protoize.c: Include intl.h.
+ (__attribute__): New macro.
+ (notice): New function.
+ (my_strerror): Reword message so that it does not require
+ localization.
+ (xmalloc, xrealloc, fancy_abort, safe_write, usage,
+ file_normally_convertible, abspath, find_file, aux_info_corrupted,
+ save_def_or_dec, gen_aux_info_file, process_aux_info_file,
+ rename_c_file, find_extern_def, find_static_definition,
+ declare_source_confusing, edit_fn_declaration, edit_formals_lists,
+ add_local_decl, add_global_decls, edit_fn_definition,
+ scan_for_missed_items, edit_file, main): Use `notice' to print
+ diagnostic.
+ (main): Set message locale.
+
+ * real.c (NMSGS, ermsg): Remove.
+ (mtherr): Revamp to pass explicit strings to diagnostic
+ generators. Abort on invalid operations.
+
+ * regclass.c (fix_register): Reword messages to ease localization.
+
+ * toplev.c: Include intl.h; do not include ctype.h.
+ (v_really_sorry, really_sorry): Remove unused functions.
+ (count_error, fatal_io_error): Translate strings.
+ (default_print_error_function, report_error_function, main,
+ print_version): Reword messages to ease localization. Use
+ `notice' to translate diagnostics.
+ (vnotice, notice, fnotice): New functions.
+ (vmessage): Remove.
+ (v_message_with_file_and_line, vsorry): Translate msgid with
+ vnotice.
+ (v_message_with_file_and_line, v_message_with_decl): Use
+ report_file_and_line. Now takes int warning flag, not prefix;
+ this is easier to localize. All callers changed.
+ (v_message_with_decl): Abort if first format spec is neither %%
+ nor %s. Translate "((anonymous))".
+ (main): Set message locale.
+ (set_target_switch): Don't use `valid' as an identifier; it runs
+ afoul of SunOS 4.1.4 <locale.h>.
+ (__VERSION__): Reword message so that it does not require
+ localization.
+ (print_switch_values): Translate "options passed" and "options
+ enabled".
+
+ * tree.c (valid_machine_attribute): Don't use `valid' as an
+ identifier; it runs afoul of SunOS 4.1.4 <locale.h>.
+
+ * xcoffout.c (xcoff_output_standard_types): Use `error' to
+ output diagnostic, so that it gets translated.
+
+ * patch-apollo-includes: Remove; this is part of README.APOLLO.
+
+Mon Jul 27 18:28:58 1998 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * reload.c (find_reloads): If no_input_reloads, abort if
+ reloads were made for addresses.
+ * m68k.md (sxx): Operand 0 cannot be memory.
+
+Fri Jul 17 07:31:04 1998 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * m68k.c (output_move_simode_const): Use subl to move 0 into addr reg.
+ (output_move_[hq]imode): Likewise.
+
+ * m68k.md (extend[sd]fxf2): Accept constants and general reg as
+ source operand if the destination is a floating point register.
+
+Fri Jul 17 07:23:49 1998 Herman ten Brugge <Haj.Ten.Brugge@net.HCC.nl>
+
+ * reorg.c (check_annul_list_true_false): New function.
+ (steal_delay_list_from_{target,fallthrough}): Call it and also
+ refine tests for when we may annul if already filled a slot.
+ (fill_slots_from_thread): Likewise.
+ (delete_from_delay_slot): Return newly-created thread.
+ (try_merge_delay_isns): Use its new return value.
+
+Sat Jul 4 11:07:33 1998 Eberhard Mattes <mattes@azu.informatik.uni-stuttgart.de>
+
+ * function.c (assign_parms): Handle PARALLEL which include stack.
+
+Sat Jul 4 09:44:29 1998 Paul Edwards <avon@matra.com.au>
+
+ * tree.c, print-tree.c, c-lang.c: Include stdio.h before tree.h.
+ * expr.c (bc_expand_component_address): Correct args to
+ bc_push_offset_and_size.
+ * reload1.c (reload_cse_simplify_operands): Add missing return value.
+
+Fri Jul 3 07:17:19 1998 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * alpha.c (normal_memory_operand): Handle case when REG will be
+ eliminated by reload.
+
+Thu Jul 2 18:43:53 1998 James Carlson <carlson@ironbridgenetworks.com>
+
+ * floatlib.c (HIDDEND_LL, MANTD_LL, PACKD_LL): New macros.
+ (__addsf3): Fixed cases returning wrong type and causing unintended
+ conversions and data corruption.
+ (__mulsf3): Fixed rounding flaws caused wrong scaling.
+ (__float{didf,sisf,disf},__fix{,uns}dfdi): New functions.
+ (__{gt,ge,lt,le,eq,ne}df2): Likewise.
+ (__truncdfsf2): Fixed normalization problems
+ (__fixunsdfsi): Fixed compiler warning
+ (__{add,sub,mul}df3): Rewrite to do real DP math.
+ (__divdf3): Removed previous version by Barrett Richardson.
+
+Thu Jul 2 17:57:20 1998 Douglas B. Rupp <rupp@gnat.com>
+
+ * cpperror.c: Include errno.h.
+
+Thu Jul 2 16:46:36 1998 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * c-decl.c (grokdeclarator): Don't warn about implicit int in
+ `typedef foo = bar'.
+
+Tue Jun 30 18:32:49 1998 Geert Bosch <bosch@gnat.com>
+
+ * alpha/vxworks.h (LINK_SPEC): Add -taso -T 0.
+
+Tue Jun 30 09:39:32 1998 David Edelsohn <edelsohn@mhpcc.edu>
+
+ * expr.c (expand_builtin_{set,long}jmp): If STACK_SAVEAREA_MODE
+ defined, override sa_mode using its value.
+ * explow.c (emit_stack_save): Likewise.
+
+ * rs6000/aix41.h (ASM_CPU_SPEC): Define relative to ASM_DEFAULT_SPEC.
+ (CPP_CPU_SPEC): Define relative to CPU_DEFAULT_SPEC.
+ * rs6000.c (processor_target_table, 620): Don't affect MASK_POWERPC64.
+ (rs6000_override_options): Ignore flag_pic for AIX.
+ (rs6000_immed_double_const): Delete.
+ ({reg_or_u_short,u_short_cint}_operand): Don't assume 32-bit CONST_INT.
+ ({non_logical_cint,logical}_operand): Likewise.
+ (num_insns_constant): mask64_operand is 2 insns.
+ (easy_fp_constant): Any CONST_DOUBLE_HIGH is okay for 64-bit.
+ (mask_constant): HOST_WIDE_INT parameter.
+ (non_and_cint_operand): Delete.
+ ({mask,and}64_operand): New functions.
+ (function_arg{,_advance}): DImode arguments don't need special
+ alignment when 64-bit.
+ (setup_incoming_varargs): Reverse reg_size assignment.
+ (print_operand): HOST_WIDE_INT second parameter.
+ (print_operand, case 'B', 'S'): New cases.
+ (print_operand, case 'M'): Fix typo in lossage string.
+ (rs6000_stack_info): Reverse reg_size assignment. Use total_raw_size
+ to compute AIX push_p. Use reg_size to compute {cr,lr}_save_offset.
+ (rs6000_output_load_toc_table): Reverse init_ptr assignment. Use
+ TARGET_64BIT not TARGET_POWERPC64. Convert fprintf to fputs.
+ Load GOT highpart, don't add it. Add lowpart with {cal|la}.
+ (rs6000_allocate_stack_space): Use {cal|la}.
+ (output_epilog): Use {cal|la}
+ (output_function_profiler): Add call glue to mcount call.
+ Load GOT highpart, don't add it. Add lowpart with {cal|la}.
+ Use asm_fprintf and convert fprintf to fputs.
+
+ * rs6000.h (TARGET_SWITCHES): Add powerpc64.
+ (STACK_BOUNDARY): Depend on TARGET_32BIT.
+ (ADJUST_FIELD_ALIGN): Calculate array alignment using innermost type.
+ (CONST_OK_FOR_LETTER_P): Don't assume 32-bit CONST_INT.
+ (EXTRA_CONSTRAINTS): Remove 'S' and 'T'. Replace 'S' with
+ 64-bit mask operand.
+ (RS6000_SAVE_TOC): Depend on TARGET_32BIT.
+ (STACK_SAVEAREA_MODE): New macro.
+ (LEGITIMATE_CONSTANT_P): DImode okay for 64bit.
+ (RTX_COSTS, AND/IOR/XOR): Reflect current machine description.
+ (ASM_FILE_START): Emit 64-bit ABI directive.
+ (ASM_DECLARE_FUNCTION_NAME): Align CSECT on doubleword in 64-bit mode.
+ (ASM_OUTPUT_SPECIAL_POOL_ENTRY): DImode okay for 64-bit.
+ (PREDICATE_CODES): Add "and64_operand" and "mask64_operand".
+ Delete "non_and_cint_operand". "input_operand" includes CONST_DOUBLE.
+
+ * rs6000.md (iorsi3, xorsi3): Use HOST_WIDE_INT for mask.
+ Restore define_split.
+ (floatsidf2, floatunssidf2): Remove !TARGET_POWERPC64 final constraint.
+ (floatsidf2_internal, floatunssidf2_internal2): Likewise.
+ Do not specify base register operand mode.
+ (floatsidf2_loadaddr): Don't specify base register operand mode.
+ (floatsidf2_store1, floatsidf2_store2): Operand 1 must be base
+ register; do not specify mode. Remove !TARGET_POWERPC64 final
+ constraint.
+ (floatsidf2_load): Don't specify base register operand mode.
+ Remove !TARGET_POWERPC64 final constraint.
+ (fix_truncdfsi2_internal, fix_truncdfsi2_{store,load}): Don't specify
+ base register operand mode.
+ (mulsidi3): Add !TARGET_POWERPC64 constraint.
+ (adddi3): Split large constants early.
+ (absdi3): Shift by 63, not 31.
+ (rotldi3): Add masking combiner patterns.
+ (anddi3): Add rldic{r,l} masking. Remove split of large constants.
+ (iordi3, xordi3): Split large constants early.
+ (movsi matcher): Remove S and T constraints.
+ (movsf const_double): create SImode constant from TARGET_DOUBLE.
+ (movdf_hardfloat32): Add default abort case.
+ (movdf easy_fp_const): create DImode constant from TARGET_DOUBLE.
+ (movdi): Remove 64-bit constant generator. Try to convert
+ CONST_DOUBLE to CONST_INT. Handle TOC memory constants.
+ (movdi_32): Add default abort case.
+ (movdi_64): Add numerous ways to split 64-bit constants.
+ Make catch-all define_split more optimal and never FAIL.
+ (movti_ppc64): Add default abort case.
+ (allocate_stack): Remove operand modes; use Pmode.
+ (restore_stack_block): Remove operand modes. Generate Pmode
+ temporary. Generate MEM and specify mode.
+ (save_stack_nonlocal, restore_stack_nonlocal): Generate Pmode
+ temporary. Save area is double Pmode.
+ (call_indirect_aix64, call_value_indirect_aix64): New patterns.
+ (call, call_value): Do not specify address operand mode. Choose
+ appropriate AIX ABI.
+ (*call_local64, *ret_call_local64): New patterns.
+ (*call_nonlocal_aix64, *ret_call_nonlocal_aix64): New patterns.
+ (*ret_call_nonlocal_aix32): Use call_value_indirect for REG.
+ (compare): Materialize DImode truthvalues.
+
+Tue Jun 30 06:31:40 1998 Richard Henderson <rth@dot.cygnus.com>
+
+ * alpha.h (PRINT_OPERAND_PUNCT_VALID_P): Add '`'.
+ * alpha.c (print_operand): Handle it.
+ * alpha.md (fix_truncdfsi2, fix_truncsfsi2): New patterns and
+ related define_splits.
+
+Tue Jun 30 06:02:07 1998 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * calls.c (emit_library_call{,_value}): Pass null
+ to REG_PARM_STACK_SPACE.
+
+ * alpha.c (normal_memory_operand): New function.
+ * alpha.h (EXTRA_CONSTRAINT, case 'Q'): Call it.
+
+ * fold-const.c (count_cond): New function.
+ (fold): Don't try to build COND_EXPR from binary op when both sides
+ are COND_EXPR unless not nested too deeply.
+
+Thu Jun 25 09:54:55 1998 Nick Clifton <nickc@cygnus.com>
+
+ * arm.h (REG_ALLOC_ORDER): Add ARG_POINTER_REGNUM, noticed by
+ grahams@rcp.co.uk.
+
+Mon Jun 15 17:41:33 1998 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * reload1.c (reload): Issue guidance message on stack frame too large
+ for reliable stack check.
+
+ * fold-const.c (fold_range_test): Prevent falling through with no ret.
+
+Sat Jun 13 15:49:53 1998 Carol LePage <carolo@kemah.hal.com>
+
+ * configure.in (sparc-hal-solaris2*): New target.
+ * sparc/hal.h, sparc/t-halos: New files.
+
+Sat Jun 13 14:30:25 1998 David W. Schuler <schuld@btv.ibm.com>
+
+ * i386/aix386ng.h (CPP_SPEC): Remove bogus quote.
+
+Sat Jun 13 14:16:34 1998 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * regmove.c (try_auto_increment): Fix typo.
+
+ * c-common.c (truthvalue_conversion): Protect side effects in the
+ expression when splitting a complex value.
+ * fold-const.c (fold): Likewise.
+
+ * expr.c (do_jump, case EQ_EXPR, NE_EXPR): When comparing complex
+ prevent operands from being evaluated twice.
+
+Sat Jun 13 12:53:22 1998 Richard Earnshaw (rearnsha@arm.com)
+
+ * unroll.c (verify_addresses): Use validate_replace_rtx to undo
+ changes; abort if undo fails.
+
+Sat Jun 13 11:46:38 1998 Anders Blomdell <anders.blomdell@control.lth.se>
+
+ * flags.h (flag_volatile_static): Declare.
+ * toplev.c (flag_volatile_static): Define.
+ (f_options): Include -fvolatile-static.
+ * varasm.c (make_decl_rtl): Support -fvolatile-static.
+
+Sat Jun 13 08:26:21 1998 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * reload1.c (reload_cse_regno_equal_p): If -ffloat-store, don't
+ consider a MEM in FP mode as equal.
+
+ * varasm.c (assemble_variable): Never put decl with specified section
+ name into bss.
+
+ * output.h (current_function_addresses_labels): Declare.
+ * function.h (struct function): New field `addresses_labels'.
+ * function.c (current_function_addresses_labels): Define.
+ ({push,pop}_function_context): Save/restore it.
+ (init_function_start): Initialize it.
+ * rtl.h (FUNCTION_FLAGS_ADDRESSES_LABELS): New flag.
+ * expr.c (expand_expr, case LABEL_DECL): Show addresses labels.
+ * integrate.c (function_cannot_inline_p): Can't if addresses labels.
+ (initialize_for_inline): Save current_function_addresses_labels.
+ (output_inline_function): Restore it.
+
+ * reload.c (find_reloads, case 'o'): All reloaded addresses
+ are offsettable.
+ (find_reloads_address): If replacing address, don't return 1.
+
+ * profile.c (output_func_start_profiler): Add missing steps in
+ defining function.
+
+Fri Jun 12 17:10:16 1998 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * m68k.md (extendqidi2): Operand 1 must be in data register.
+
Tue Jun 9 07:24:01 1998 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+ * cccp.c (handle_directive): If -dM, also include #undef.
+ * cpplib.c (handle_directive): Likewise.
+
+ * calls.c (expand_call): Allow function pointer to be a REFERENCE_TYPE.
+
+ * function.c (assign_parms): Use proper mode for location of arg
+ on stack when promotions are occurring.
+
* regmove.c ({next,prev}_insn_for_regmove): Properly handle end of
function.
diff --git a/gcc/FSFChangeLog.10 b/gcc/FSFChangeLog.10
index 513ac72c28a..a7d3837d103 100644
--- a/gcc/FSFChangeLog.10
+++ b/gcc/FSFChangeLog.10
@@ -4259,7 +4259,7 @@ Wed Nov 29 14:06:13 1995 Jim Wilson <wilson@cygnus.com>
Wed Nov 29 13:59:58 1995 J"orn Rennecke (amylaar@meolyon.hanse.de)
- * c-decl.c (duplicate_decls): Add new parameter different_binding_level.
+ * c-decl.c (duplicate_decls): Add new paramter different_binding_level.
Lots of changes to use new new parameter.
(pushdecl): Delete variable declared_global. New variable
different_binding_level and code to set it. Move extern/static
@@ -5226,7 +5226,7 @@ Thu Sep 14 14:15:16 1995 Stan Cox (coxs@dg-rtp.dg.com)
* m88k.h (VERSION_INFO1): Removed BCS reference.
* m88k/dgux.h (ASM_SPEC, *_LEGEND):
- Added -mno-legend option. -mstandard no longer implies that
+ Added -mno-legend option. -mstandard no longer implies that legend
legend information not be produced.
(LINK_SPEC): Removed -z text
@@ -5422,7 +5422,7 @@ Thu Aug 31 08:31:40 1995 Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
* va-alpha.h (__gnuc_va_list): Make __offset an int.
* alpha.c (alpha_builtin_saveregs): Properly compute address
- of __offset both OSF and WINNT.
+ of __offset both both OSF and WINNT.
* xm-alpha.h (sbrk): Don't define here.
* gmon.c (sbrk): Define here for __alpha.
diff --git a/gcc/FSFChangeLog.11 b/gcc/FSFChangeLog.11
index 2bc3d590ac9..c244bb65eb5 100644
--- a/gcc/FSFChangeLog.11
+++ b/gcc/FSFChangeLog.11
@@ -6291,7 +6291,7 @@ Sun Apr 20 10:45:35 1997 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
(based_loc_descr): Likewise.
(add_bound_info): Delete default case.
Add cases for CONVERT_EXPR and NON_LVALUE_EXPR; treat like NOP_EXPR.
- Change NOP_EXPR to recursive call.
+ Change NOP_EXPR to to recursive call.
(add_type_attribute): Ignore unnamed subtype of integral or FP.
(gen_subprogram_die): Use reg_loc_descriptor.
(dwarf2out_decl): Ignore nested functions.
@@ -11751,7 +11751,7 @@ Mon Jul 8 18:00:33 1996 Jim Wilson <wilson@cygnus.com>
enclose it in a PARALLEL and set the PARALLEL mode correctly.
* mips.md (call_value): Call gen_call_value_multiple_internal0
only if there are multiple return values. Strip the PARALLEL off
- if there is only one return value.
+ if there there is only one return value.
Mon Jul 8 16:27:33 1996 Jeffrey A. Law <law@cygnus.com>
diff --git a/gcc/FSFChangeLog.12 b/gcc/FSFChangeLog.12
deleted file mode 100644
index ecb29192508..00000000000
--- a/gcc/FSFChangeLog.12
+++ /dev/null
@@ -1,1244 +0,0 @@
-Sat May 2 20:39:22 1998 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
-
- * fold-const.c (fold): When commutting COND_EXPR and binary operation,
- avoid quadratic behavior if have nested COND_EXPRs.
-
-Tue Apr 28 17:30:05 1998 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
-
- * mips.h (HOST_WIDE_INT): Define if not already.
- (compute_frame_size, mips_debugger_offset): Return HOST_WIDE_INT.
- (DEBUGGER_{AUTO,ARG}_OFFSET): Cast second arg to HOST_WIDE_INT.
- * /mips.c (mips_debugger_offset): Now returns HOST_WIDE_INT.
- Likewise for internal variable frame_size.
-
- * final.c (alter_subreg): Make new SUBREG if reload replacement
- scheduled inside it.
-
- * dwarf2out.c (add_bound_info, case SAVE_EXPR): Pass
- SAVE_EXPR_RTL address through fix_lexical_addr.
-
-Mon Apr 27 18:57:18 1998 Jim Wilson <wilson@cygnus.com>
-
- * mips/sni-svr4.h (CPP_PREDEFINES): Add -Dsinix and -DSNI.
-
-Mon Apr 20 14:48:29 1998 Michael Meissner <meissner@cygnus.com>
-
- * rs6000.md (mov{sf,df} define_splits): When splitting move of
- constant to int reg, don't split insns that do simple AND and OR
- operations; just split each word and let normal movsi define split
- handle it further.
-
-Sun Apr 19 20:21:19 1998 Michael P. Hayes <michaelh@ongaonga.chch.cri.nz>
-
- * real.h (C4X_FLOAT_FORMAT): New macro.
- * real.c (c4xtoe, etoc4x, toc4x): New functions.
-
-Sun Apr 19 20:17:32 1998 Niklas Hallqvist <niklas@petra.appli.se>
-
- * m68k.c (notice_update_cc): Use modified_in_p to check for update.
-
-Sun Apr 19 18:48:07 1998 K. Richard Pixley <rich@kyoto.noir.com>
-
- * fixincludes: Discard empty C++ comments.
- Special case more files with C++ comments nested in C comments.
-
-Sun Apr 19 18:30:11 1998 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
-
- * m68k.md ({add,sub}di3): Optimize for constant operand.
-
-Sun Apr 19 18:27:11 1998 Alan Modra <alan@spri.levels.unisa.edu.au>
-
- * i386.c (output_387_binary_op): Swap operands when popping if result
- is st(0).
-
-Sun Apr 19 17:58:01 1998 Peter Jeremy <peter.jeremy@alcatel.com.au>
-
- * expr.c (do_jump_by_parts_equality_rtx): Now public.
- * expmed.c (do_cmp_and_jump): New function.
- (expand_divmod): Use do_cmp_and_jmp instead of emit_cmp_insn and
- emit_jump_insn.
-
-Sun Apr 19 07:48:37 1998 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
-
- * c-typeck.c (build_c_cast): Check underlying type when seeing
- if discarding const or volatile.
-
- * c-decl.c (pushdecl): Avoid duplicate warning about implicit redecl.
-
- * configure.in (stab.h): Check for it.
- (i386-*-vsta): Include xm-i386.h too.
- * dbxout.c (stab.h): Include based on autoconf results.
- * vax/xm-vms.h (NO_STAB_H): Deleted.
- * alpha/xm-vms.h, xm-mips.h, i386/xm-mingw32.h, i386/go32.h: Likewise.
- * i386/xm-cygwin32.h: Likewise.
- * i386/xm-vsta.h (NO_STAB_H): Likewise.
- (i386/xm-i386.h): No longer include.
-
- * mips.c: Cleanups and reformatting throughout.
- ({expand,output}_block_move): Use HOST_WIDE_INT for sizes.
- (mips_debugger_offset, compute_frame_size): Likewise.
- (save_restore_insns, mips_expand_{pro,epi}logue): Likewise.
- (siginfo): Deleted.
- (override_options): Don't set up to call it; don't call setvbuf.
-
-Mon Apr 13 06:40:17 1998 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
-
- * configure.in (sparc-*-vxsim*): Include xm-siglist.h and
- define USG and POSIX.
-
-Sun Apr 12 21:59:27 1998 Jeffrey A. Law <law@cygnus.com>
-
- * calls.c (expand_call): Fix typo in STRICT_ARGUMENT_NAMING.
-
-Sun Apr 12 21:42:23 1998 D. Karthikeyan <karthik@cdotd.ernet.in>
-
- * m68k.h (TARGET_SWITCHES): Add missing comma.
-
-Sun Apr 12 21:33:33 1998 Eric Valette <valette@crf.canon.fr>
-
- * configure.in (i[34567]86-*-rtemself*): New configuration.
- * i386/rtemself.h: New file.
-
-Sun Apr 12 21:08:28 1998 Jim Wilson <wilson@cygnus.com>
-
- * loop.c (loop_optimize): Reset max_uid_for_loop after
- find_and_verify_loops call.
- (strength_reduce): In auto_inc_opt code, verify v->insn has valid
- INSN_LUID.
-
-Sun Apr 12 20:54:59 1998 Richard Earnshaw (rearnsha@arm.com)
-
- * configure.in (sparc-*-solaris2*): Add xm-siglist.h to xm_file.
- Add USG and POSIX to xm_defines.
-
-Sun Apr 12 20:47:37 1998 Pat Rankin <rankin@eql.caltech.edu>
-
- * cccp.c (eprint_string): New function.
- (do_elif, do_else, verror): Use it instead of fwrite(,,,stderr).
- (error_from_errno, vwarning): Likewise.
- ({verror,vwarning,pedwarn}_with_line): Likewise.
- (pedwarn_with_file_and_line, print_containing_files): Likewise.
-
-Sun Apr 12 20:40:44 1998 Richard Henderson <rth@dot.cygnus.com>
-
- * configure.in (alpha*-*-linux-gnu*): Add alpha/t-crtbe.
- Add crt{begin,end}.o in extra_parts and delete crt{begin,end}S.o.o
- * alpha/t-crtbe, alpha/crt{begin,end}.asm: New files.
-
- * alpha.h (PRINT_OPERAND_PUNCT_VALID_P): Accept '(' for s/sv/svi.
- * alpha.c (print_operand): Handle it.
- * alpha.md (fix_trunc[ds]fdi2): Use it. Add earlyclobber pattern
- for ALPHA_TP_INSN.
-
-Sun Apr 12 13:09:46 1998 Scott Christley <scottc@net-community.com>
-
- * objc/encoding.c (objc_sizeof_type, _C_VOID): New case.
-
-Sun Apr 12 13:04:55 1998 Nikolay Yatsenko (nikolay@osf.org)
-
- * configure.in (i[34567]86-*-osf1*): New entry.
- * i386/osf1-c[in].asm: New files for OSF/1.
- * i386/osf1elf{,gdb}.h, i386/[xt]-osf1elf, i386/xm-osf1elf.h: Likewise.
-
-Sun Apr 12 10:03:51 1998 Noel Cragg <noel@red-bean.com>
-
- * fixincludes: Remove specification of parameters when renaming
- functions in Alpha DEC Unix include files.
-
-Sun Apr 12 07:33:46 1998 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
-
- * mips.c (large_int): Use HOST_WIDE_INT, not int.
- (print_operand): Use HOST_WIDE_INT_PRINT_* macros.
-
- * toplev.c (main): Sort order of handling of -d letters.
- Use `F' instead of `D' for addressof_dump.
-
- * libgcc2.c (_eh_compat): Deleted.
- * Makefile.in (LIB2FUNCS): Delete _eh_compat.
-
- * configure.in (alpha*-*-linux-gnu*): Don't include alpha/xm-linux.h.
-
- * c-common.c (check_format_info): Properly test for nested pointers.
-
- * pa.md (casesi0): Add missing mode for operand 0.
-
- * function.c (purge_addressof_1, case MEM): If BLKmode, put ADDRESSOF
- into stack.
-
- * c-parse.in (label): Give warning if pedantic and label not integral.
-
- * c-decl.c (grokdeclarator): Don't warn about return type if in
- system header.
-
- * reload.c (reload_nongroup): New variable.
- (push{_secondary,}_reload): Initialize it.
- (find_reloads): Compute it.
- (debug_reload): Print it.
- * reload.h (reload_nongroup): Declare.
- * reload1.c (reload): Use reload_nongroup instead of local computation.
- Check caller_save_spill_class against any nongroup reloads.
- (reloads_conflict): No longer static.
-
-Sun Apr 12 05:52:18 1998 John David Anglin <dave@hiauly1.hia.nrc.ca>
-
- * vax.md (call patterns): Operand 1 is always a CONST_INT.
-
-Sat Apr 11 16:01:11 1998 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
-
- * convert.c (convert_to_{pointer,integer,real,complex}): Use switch.
- Add missing integer-like types.
- Simplify return of zero in error case.
- (convert_to_pointer): Remove dubious abort.
- (convert_to_integer, case POINTER_TYPE): Make recursive call.
- (convert_to_integer, case COND_EXPR): Always convert arms.
- * tree.c (type_precision): Deleted.
-
- * cccp.c (do_warning): Give pedantic warning if -pedantic and not
- in system file.
- * cpplib.c (do_warning): Likewise.
-
- * function.c (target_temp_slot_level): Define here.
- (push_temp_slots_for_target, {get,set}_target_temp_slot_level): New.
- * stmt.c (target_temp_slot_level): Don't define here.
- * expr.h (temp_slot_level): New declaration.
-
-Fri Apr 10 16:35:48 1998 Paul Eggert <eggert@twinsun.com>
-
- * c-common.c (decl_attributes): Support strftime format checking.
- (record_function_format, {check,init_function}_format_info): Likewise.
- (enum format_type): New type.
- (record_function_format): Now static; takes value of type
- enum format_type instead of int.
- (time_char_table): New constant.
- (struct function_format_info): format_type member renamed from is_scan.
- (check_format_info): Use `warning' rather than sprintf followed by
- `warning', to avoid mishandling `%' in warnings.
- Change a `pedwarn' to `warning'.
- * c-tree.h (record_function_format): Remove decl.
-
-Thu Apr 2 17:34:27 1998 Manfred Hollstein <manfred@s-direktnet.de>
-
- * regclass.c (memory_move_secondary_cost): Protect uses of
- SECONDARY_{INPUT,OUTPUT}_RELOAD_CLASS with #ifdef tests.
-
-Thu Apr 2 07:06:57 1998 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
-
- * m68k.c (standard_68881_constant_p): Don't use fmovecr on 68060.
-
-Thu Apr 2 06:19:25 1998 Ken Raeburn <raeburn@cygnus.com>
-
- * Makefile.in (version.c): Put "cvs log" output in build directory.
-
- * reload.h (MEMORY_MOVE_COST): Define here if not already defined.
- (memory_move_secondary_cost): Declare.
- * regclass.c (MEMORY_MOVE_COST): Don't define default here.
- (memory_move_secondary_cost) [HAVE_SECONDARY_RELOADS]: New function.
- (regclass, record_reg_classes, copy_cost, record_address_regs):
- Pass register class and direction of move to MEMORY_MOVE_COST.
- (top_of_stack) [HAVE_SECONDARY_RELOADS]: New static array.
- (init_regs) [HAVE_SECONDARY_RELOADS]: Initialize it.
- * reload1.c (MEMORY_MOVE_COST): Don't define default here.
- (emit_reload_insns, reload_cse_simplify_set): Pass register class
- and direction of move to MEMORY_MOVE_COST.
- * 1750a.h (MEMORY_MOVE_COST): Add extra ignored arguments.
- * a29k.h, alpha.h, arc.h, arm.h, dsp16xx.h, i386.h, m32r.h: Likewise.
- * m88k.h, rs6000.h: Likewise.
- * mips.h (MEMORY_MOVE_COST): Likewise.
- Add memory_move_secondary_cost result to cpu-specific cost.
-
-Mon Mar 30 13:56:30 1998 Jim Wilson <wilson@cygnus.com>
-
- * mips/ultrix.h (SUBTARGET_CPP_SPEC): Define.
-
-Wed Mar 25 16:09:01 1998 Michael Meissner <meissner@cygnus.com>
-
- * rs6000.h (FUNCTION_ARG_PADDING): Cast result to be enum direction.
- (function_arg_padding): Declare.
-
- * rs6000.c: Include stdlib.h if we have it.
- (function_arg_padding): Change return type to int, cast enum's to int.
-
- (From Kaveh R. Ghazi <ghazi@caip.rutgers.edu>)
- * rs6000.c (rs6000_override_options): Change type of `i', `j' and
- `ptt_size' from int to size_t.
- (rs6000_file_start): Likewise for `i'.
- (rs6000_replace_regno): Add default case in enumeration switch.
- (output_epilog): Remove unused variable `i'.
- (rs6000_longcall_ref): Remove unused variables `len', `p', `reg[12]'.
-
- * rs6000.h (ADDITIONAL_REGISTER_NAMES): Add missing braces around
- initializer.
- (get_issue_rate, non_logical_cint_operand): Add prototype.
- (rs6000_output_load_toc_table): Likewise.
-
- * rs6000.md (udivmodsi4): Add explicit braces to avoid ambiguous
- `else'.
-
-Wed Mar 25 02:39:01 1998 Paul Eggert <eggert@twinsun.com>
-
- * configure.in (i[[34567]]86-*-solaris2*, powerpcle-*-solaris2*,
- sparc-*-solaris2*): Use fixinc.svr4 if Solaris 2.0 through 2.4.
-
-Mon Mar 23 07:27:19 1998 Philippe De Muyter <phdm@macqel.be>
-
- * m68k.md (ashldi_const): Allow shift count in range ]32,63].
- (ashldi3): Allow constant shift count in range ]32,63].
- (ashrdi_const, ashrid3, lshrdi_const, lshrdi3): Likewise.
-
- * m68k.md (zero_extend[qh]idi2, iordi_zext): New patterns.
- (zero_extendsidi2): Avoid useless copy.
- (iorsi_zexthi_ashl16): Avoid "0" constraint for operand 2.
- (iorsi_zext): New name for old unnamed pattern; indentation fixes.
-
-Mon Mar 23 07:12:05 1998 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
-
- * final.c (only_leaf_regs_used): If pic_offset_table_rtx used,
- make sure it is a permitted register.
-
-Sun Mar 22 06:57:04 1998 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
-
- * expmed.c (extract_bit_field): Don't confuse SUBREG_WORD with
- endian adjustment in SUBREG case.
- Don't abort if can't make SUBREG needed for extv/extzv.
-
-Sat Mar 21 08:02:17 1998 Richard Gorton <gorton@amt.tay1.dec.com>
-
- * alpha.md (zero_extendqi[hsd]i2): Use "and", not "zapnot".
-
-Sat Mar 21 07:47:04 1998 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
-
- * unroll.c (verify_addresses): Use validate_replace_rtx.
- (find_splittable_givs): If invalid address, show nothing same_insn.
-
-Fri Mar 20 10:24:12 1998 Philippe De Muyter <phdm@macqel.be>
-
- * fold-const.c (fold, case CONVERT_EXPR): Replace sign-extension of
- a zero-extended value by a single zero-extension.
-
-Thu Mar 19 14:59:32 1998 Andrew Pochinsky <avp@ctp.mit.edu>
-
- * sparc.h (ASM_OUTPUT_LOOP_ALIGN): Fix error in last change.
-
-Thu Mar 19 14:48:35 1998 Michael Meissner <meissner@cygnus.com>
-
- * gcc.c (default_arg): Don't wander off the end of allocated memory.
-
- * rs6000/sysv4.h (RELATIVE_PREFIX_NOT_LINKDIR): Undef for System V
- and EABI.
-
-Thu Mar 19 06:17:59 1998 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
-
- * Makefile.in (toplev.o): Depend on Makefile.
-
-Wed Mar 18 17:40:09 1998 Michael P. Hayes <michaelh@ongaonga.chch.cri.nz>
-
- * expr.c (convert_move): Add [QH]Imode/P[QH]Imode conversions.
- * machmode.def (PQImode, PHImode): New modes.
-
-Wed Mar 18 17:11:18 1998 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
-
- * m68k.md (movsf+1): Optimize moving a CONST_DOUBLE zero.
-
-Wed Mar 18 17:07:54 1998 Ken Raeburn <raeburn@cygnus.com>
-
- * regclass.c (init_reg_sets): Delete init of reg-move cost tables.
- (init_reg_sets_1): Put it here.
-
-Wed Mar 18 16:43:11 1998 Jim Wilson <wilson@cygnus.com>
-
- * i960.md (tablejump): Handle flag_pic.
-
- * profile.c (branch_prob): If see computed goto, call fatal.
-
- * calls.c (expand_call): Fix typos in n_named_args computation.
-
-Wed Mar 18 05:54:25 1998 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
-
- * fold-const.c (operand_equal_for_comparison_p): See if equal
- when nop conversions are removed.
-
- * expr.c (expand_expr, case COND_EXPR): If have conditional move,
- don't use ORIGINAL_TARGET unless REG.
-
- * function.c (fixup_var_refs_insns): Also delete insn storing pseudo
- back into arg list.
-
- * combine.c (gen_binary): Don't make AND that does nothing.
- (simplify_comparison, case AND): Commute AND and SUBREG.
- * i386.h (CONST_CONSTS, case CONST_INT): One-byte integers are cost 0.
-
-Mon Mar 16 15:57:17 1998 Geoffrey Keating <geoffk@ozemail.com.au>
-
- * rs6000.c (small_data_operand): Ensure any address referenced
- relative to small data area is inside SDA.
-
-Sun Mar 15 16:01:19 1998 Andrew Pochinsky <avp@ctp.mit.edu>
-
- * sparc.h (ASM_OUTPUT_LOOP_ALIGN): Write nop's.
-
-Sun Mar 15 15:53:39 1998 Philippe De Muyter <phdm@macqel.be>
-
- * libgcc2.c (exit): Don't call __bb_exit_func if HAVE_ATEXIT.
-
-Sun Mar 15 15:44:41 1998 Paul Eggert <eggert@twinsun.com>
-
- * cccp.c: Fix bugs relating to NUL in input file name,
- e.g. with `#line 2 "x\0y"'.
- (PRINTF_PROTO_4): New macro.
- (struct {file_buf,definition,if_stack}): New member nominal_fname_len.
- (main, expand_to_temp_buffer): Store length of input file names.
- (finclude, create_definition, do_line, conditional_skip): Likewise.
- (skip_if_group, macroexpand): Likewise.
- (make_{definition,undef,assertion}): Likewise.
- (special_symbol, do_include): Use stored length of input file names.
- (do_define, do_elif, do_else, output_line_directive, verror): Likewise.
- (error_from_errno, vwarning, verror_with_line): Likewise.
- (vwarning_with_line, pedwarn_with_file_and_line): Likewise.
- (print_containing_files): Likewise.
- (do_line): Fix off-by-1 problem: 1 too many bytes were being allocated.
- (quote_string, pedwarn_with_file_and_line): New arg specifies length.
- All callers changed.
-
-Sun Mar 15 15:38:16 1998 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
-
- * c-typeck.c: Collect pending initializers in AVL tree instead of list.
- (add_pending_init, pending_init_member): New functions.
- (output_init_element): Use them.
- (output_pending_init_elements): Rewritten to exploit AVL order.
-
-Sun Mar 15 05:10:49 1998 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
-
- * gnu.h (GNU_CPP_PREDEFINES): Deleted; not valid in traditional C.
- * {i386,mips}/gnu.h (CPP_PREDEFINES): Don't call GNU_CPP_PREDEFINES.
-
- * flow.c (insn_dead_p): A CLOBBER of a dead pseudo is dead.
-
- * alpha.h (REG_ALLOC_ORDER): Put $f1 after other nonsaved.
-
- * sparc.c (sparc_type_code): Fix error in previous change.
-
-Sat Mar 14 05:45:21 1998 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
-
- * i386/xm-aix.h, i386/xm-osf.h (i386/xm-i386.h): Don't include.
- (USG): Don't define.
- * i386/xm-isc.h (i386/xm-sysv3.h): Don't include.
- * i386/xm-sco.h (i386/xm-sysv3.h): Likewise.
- (BROKEN_LDEXP, SMALL_ARG_MAX, NO_SYS_SIGLIST): Don't define.
- * m68k/xm-3b1.h (m68k/xm-m68k.h): Don't include.
- (USG): Don't define.
- * m68k/xm-atari.h (m68k/xm-m68kv.h): Don't include.
- (HAVE_VPRINTF, FULL_PROTOTYPES): Don't define.
- * m68k/xm-crds.h (m68k/xm-m68k.h): Don't include.
- (USE_C_ALLOCA, unos, USG): Don't define.
- * m68k/xm-mot3300.h (m68k/xm-m68k.h): Don't include.
- (USE_C_ALLOCA, NO_SYS_SIGLIST): Don't define.
- * m68k/xm-plexus.h (m68k/xm-m68k.h): Don't include.
- (USE_C_ALLOCA, USG): Don't define.
- * m88k/xm-sysv3.h (m88k/xm-m88k.h): Don't include.
- * m68k/xm-next.h (m68k/xm-m68k.h): Don't include.
- * ns32k/xm-pc532-min.h (ns32k/xm-ns32k.h): Don't include.
- (USG): Don't define.
- * rs6000/xm-mach.h: Don't include xm-rs6000.h.
- * rs6000/xm-cygwin32.h (rs6000/xm-rs6000.h): Don't include.
- (NO_STAB_H): Don't define.
- * sparc/xm-linux.h (xm-linux.h): Don't include.
- * sparc/xm-sol2.h (sparc/xm-sysv4.h): Don't include.
- * a29k/xm-unix.h, alpha/xm-linux.h, arm/xm-linux.h: Deleted.
- * arm/xm-netbsd.h, i386/xm-bsd386.h, i386/xm-gnu.h: Deleted.
- * i386/xm-linux.h, i386/xm-sun.h, i386/xm-sysv3.h: Deleted.
- * i386/xm-winnt.h, m68k/xm-altos3068.h, m68k/xm-amix.h: Deleted.
- * m68k/xm-amix.h, m68k/xm-hp320.h, m68k/xm-linux.h: Deleted.
- * m68k/xm-m68kv.h, mips/xm-iris5.h, ns32k/xm-genix.h: Deleted.
- * sparc/xm-pbd.h, vax/xm-vaxv.h, xm-svr3.h, xm-linux.h: Deleted.
- * configure.in: Reflect above changes.
-
- * xm-siglist.h, xm-alloca.h: New files.
- * i386/xm-sysv4.h (i386/xm-i386.h, xm-svr4.h): Don't include.
- (USE_C_ALLOCA, SMALL_ARG_MAX): Don't define.
- * i386/xm-sco5.h (i386/xm-sysv3.h): Don't include.
- (SYS_SIGLIST_DECLARED, USE_C_ALLOCA): Don't define.
- * rs6000/xm-sysv4.h, sparc/xm-sysv4.h: Don't include xm-svr4.h.
- * xm-svr4.h, i386/xm-dgux.h, mips/xm-news.h, mips/xm-sysv4.h: Deleted.
- * configure.in: Reflect above changes.
-
- * configure.in ({,host_,build_}xm_defines): New variables.
- Set to USG instead of including xm-usg.h.
- Write #define lines in config.h files from xm_defines vars.
- * xm-usg.h: Deleted.
-
-Fri Mar 13 07:10:59 1998 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
-
- * calls.c (expand_call): Fix typo in previous change.
-
- * sparc.c (sparc_type_code): Avoid infinite loop when have
- pointer to array of same pointer.
- (sparc_type_code, case REAL_TYPE): Process subtypes here too.
-
- * mips/bsd-4.h, mips/iris3.h, mips/news{4,5}.h: Don't include mips.h.
- * mips/news5.h, mips/osfrose.h, mips/svr{3,4}-4.h: Likewise.
- * mips/ultrix.h: Likewise.
- * mips/cross64.h: Don't include iris6.h.
- * mips/ecoff.h: Don't include mips.h or gofast.h.
- * mips/elforion.h: Don't include elf64.h.
- * mips/iris4.h: Don't include iris3.h.
- * mips/iris4loser.h: Don't include iris4.h.
- * mips/iris5gas.h: Don't include iris5.h.
- * mips/elflorion.h, mips/nws3250v4.h, mips/xm-iris{3,4}.h: Deleted.
- * mips/xm-nws3250v4.h, mips/xm-sysv.h: Deleted.
- * mips/rtems64.h: Don't include elflorion.h.
- * mips/sni-gas.h: Don't include sni-svr4.h.
- * mips/svr4-t.h: Don't include svr4-5.h.
- * mips/dec-osf1.h: Also include mips.h.
- * mips/ecoffl.h, mips/elf.h: Also include mips.h and gofast.h.
- * mips/iris5.h: Also include iris3.h and mips.h.
- * xm-usg.h: New file.
- * mips/xm-iris5.h: Don't include xm-mips.h; don't define USG.
- * mips/xm-news.h, mips/xm-sysv4.h: Don't include xm-sysv.h.
- * configure.in: Reflect above changes.
-
-Thu Mar 12 07:18:48 1998 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
-
- * expr.h (STRICT_ARGUMENT_NAMING): Provide default value of 0.
- * calls.c (expand_call): Use value of STRICT_ARGUMENT_NAMING.
- * function.c (assign_parm): Likewise.
- * mips/abi64.h (STRICT_ARGUMENT_NAMING): Return 0 for ABI_32.
- * sparc.h (STRICT_ARGUMENT_NAMING): Only nonzero for V9.
-
- * calls.c (expand_call, expand_library_call{,_value}, store_one_arg):
- Rework handling of REG_PARM_STACK_SPACE to treat return value of
- zero as if macro not defined; add new arg to emit_push_insn.
- * expr.c (emit_push_insn): New arg, REG_PARM_STACK_SPACE.
- * expr.h (emit_push_insn): Likewise.
- * mips/abi64.h (REG_PARM_STACK_SPACE): Define.
-
-Wed Mar 11 06:58:13 1998 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
-
- * m68k.h (CONST_OK_FOR_LETTER_P, case 'M'): Correct range check.
-
-Wed Mar 11 06:15:52 1998 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
-
- * expr.c (emit_push_insn): Use loop to find movstr patterns
- instead of explicit tests.
-
- * Makefile.in (extraclean): Don't delete install1.texi.
-
-Tue Mar 10 14:27:51 1998 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
-
- * combine.c (make_field_assignment): Don't get confused if OTHER
- has VOIDmode and don't do anything if DEST is wider than a host word.
-
- * vax.c (check_float_value): Cast bcopy args to char *.
-
-Tue Mar 10 13:56:12 1998 Jim Wilson <wilson@cygnus.com>
-
- * mips/abi64.h (LONG_MAX_SPEC): Check MIPS_ABI_DEFAULT and
- TARGET_DEFAULT and define __LONG_MAX__ appropriately.
- Add support for -mabi=X, -mlong64, and -mgp{32,64} options.
- * mips.c (mips_abi): Change type to int.
- * mips.h (enum mips_abi_type): Delete.
- (ABI_32, ABI_N32, ABI_64, ABI_EABI): Define as constants.
- (mips_abi): Change type to int.
-
-Mon Mar 2 08:06:58 1998 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
-
- * Version 2.8.1 released.
-
- * Makefile.in (mostlyclean): Remove duplicate deletion of temp
- files. Delete more stamp files and [df]p-bit.c
- (clean): Don't delete stamp files here.
- (VERSION_DEP): New variable.
- (distdir-finish): Pass a value of null for it.
- (version.c): Use it.
- Avoid broken pipe with cvs log.
-
- * objc/Make-lang.in (objc/runtime-info.h): Rename emptyfile to
- tmp-runtime and delete at end.
-
-Sun Mar 1 05:50:25 1998 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
-
- * tree.c (build_reference_type): Handle obstacks like
- build_pointer_type.
-
- * Makefile.in (tmp-gcc.xtar): Renamed from gcc.xtar.
- (gcc.xtar.gz): Deleted; merged with `dist'.
- (diff): Create gcc-$(oldversion)-$(version).diff.
- (distdir): Depend on distdir-cvs.
- (distdir-cvs): New rule.
- (distdir-start): Depend on version.c and TAGS.
- (TAGS): Use tmp-tags instead of temp.
- (dist): Create gcc-$(version).tar.gz.
-
- * varasm.c (compare_constant_1): Fix typo in previous change.
-
- * objc/Make-lang.in (objc-distdir): Properly rebuild objc-parse.c.
-
-Sat Feb 28 16:58:08 1998 Tristan Gingold <gingold@rossini.enst.fr>
-
- * stmt.c (expand_decl): If -fcheck-memory-usage, put vars in memory.
- * expr.c (get_memory_usage_from_modifier): Convert
- EXPAND_{CONST_ADDRESS, INITIALIZER} to MEMORY_USE_DONT.
-
-Sat Feb 28 08:13:43 1998 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
-
- * i860/fx2800.h (DATA_ALIGNMENT): Use POINTER_TYPE_P.
- * m68k/a-ux.h (FUNCTION_VALUE): Likewise.
- * expr.c (get_pointer_alignment, compare, do_store_flag): Likewise.
- (expand_builtin): Likewise.
- * fold-const.c (force_fit_type, fold_convert, fold): Likewise.
- * function.c (assign_parms): Likewise.
- * integrate.c (expand_inline_function): Likewise.
- * sdbout.c (sdbout_field_types): Likewise.
- * tree.c (integer_pow2p, tree_log2, valid_machine_attribute): Likewise.
- * stmt.c (expand_decl): Likewise.
- ({,bc_}expand_decl_init): Also test for REFERENCE_TYPE.
-
- * configure.in (version_dep): New variable; if srcdir is CVS working
- directory, set to ChangeLog.
- (version): Supply default if no version.c.
- * Makefile.in (version.c): New rule.
-
- * gcc.c (snapshot_warning): New function.
- (main): Call it for snapshots.
-
- * dwarf2out.c (expand_builtin_dwarf_reg_size): If reg_raw_mode
- not valid for reg, use last size. Also refine range assertion.
-
-Sat Feb 28 05:04:47 1998 Michael P. Hayes <michaelh@ongaonga.chch.cri.nz>
-
- * enquire.c (cprop): Don't perform exhaustive search for char_min
- and char_max when bits_per_byte > 16.
-
-Thu Feb 26 15:12:03 1998 Christopher Taylor <cit@ckshq.com>
-
- * fixincludes: Avoid using '0-~' in egrep.
-
-Thu Feb 26 08:04:05 1998 Tristan Gingold <gingold@messiaen.enst.fr>
-
- * function.c (assign_parms): Call 'chkr_set_right' when DECL_RTL
- is stack_parm.
- * expr.c (get_memory_usage_from_modifier): Convert
- EXPAND_{SUM, CONST_ADDRESS, INITIALIZER} to MEMORY_USE_RO.
-
-Thu Feb 26 07:33:53 1998 Paul Eggert <eggert@twinsun.com>
-
- * c-lex.c (yylex): Don't munge errno before using it.
- * cccp.c (error_from_errno, perror_with_name): Likewise.
- * cpplib.c (cpp_error_from_errno): Likewise.
- * gcc.c (pfatal_pexecute): Likewise.
- * protoize.c (safe_write, find_file, process_aux_info_file): Likewise.
- (rename_c_file, edit_file): Likewise.
-
- * c-lex.c (yylex): Remove unused variable exceeds_double.
-
-Thu Feb 26 07:05:14 1998 Michael P. Hayes <michaelh@ongaonga.chch.cri.nz>
-
- * reorg.c (fill_slots_from_thread): Don't steal delay list from target
- if condition code of jump conflicts with opposite_needed.
-
-Thu Feb 26 06:45:23 1998 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
-
- * Makefile.in (distdir-start): Don't copy CVS subdirectory of config.
-
- * varasm.c ({compare,record}_constant_1, case CONSTRUCTOR):
- Handle the case when we have TREE_PURPOSE values.
-
-Thu Feb 26 05:59:01 1998 Philippe De Muyter <phdm@macqel.be>
-
- * fixincludes (sys/limits.h): Fix a nested comment problem with
- HUGE_VAL definition on sysV68 R3V7.1.
-
-Wed Feb 25 21:09:38 1998 Philippe De Muyter <phdm@macqel.be>
-
- * toplev.c (TICKS_PER_SECOND): Renamed from CLOCKS_PER_SECOND.
-
-Wed Feb 25 20:50:08 1998 Michael P. Hayes <michaelh@ongaonga.chch.cri.nz>
-
- * reorg.c (fill_slots_from_thread): Mark resources referenced in
- opposite_needed thread. Return delay_list even when cannot get
- any more delay insns from end of subroutine.
-
-Wed Feb 25 19:50:01 1998 Mikael Pettersson <Mikael.Pettersson@sophia.inria.fr>
-
- * gcc.c (lookup_compiler): Remove redundant test.
-
-Wed Feb 25 07:24:22 1998 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
-
- * vax.md (call insns): Second operand to CALL rtl is SImode.
-
- * configure.in (i[34567]86-*-mingw32): Support msv and crt suffix.
- * i386/crtdll.h: New file.
-
- * sparc.c (pic_setup_code): If -O0, write USE of pic_offset_table_rtx.
-
- * expr.c (safe_from_p): Add new arg, TOP_P; all callers changed.
-
-Sat Feb 21 07:02:39 1998 Jim Wilson <wilson@cygnus.com>
-
- * mips/iris5.h (DWARF2_UNWIND_INFO): Define to 0.
- * mips/iris5gas.h (DWARF2_UNWIND_INFO): Define to 1.
-
-Fri Feb 20 08:27:46 1998 Paul Eggert <eggert@twinsun.com>
-
- * sparc/sol2-sld.h: New file.
- * configure.in (sparc-*-solaris2*): Use it when using system linker.
- * toplev.c (main): Don't default to DWARF2_DEBUG with -ggdb
- if LINKER_DOES_NOT_WORK_WITH_DWARF2 is defined.
-
-Fri Feb 20 08:21:49 1998 H.J. Lu (hjl@gnu.org)
-
- * alpha/elf.h (STARTFILE_SPEC, ENDFILE_SPEC): Support shared library.
- (LIB_SPEC, DEFAULT_VTABLE_THUNKS): Defined #ifndef USE_GNULIBC_1.
- * sparc/linux.h (DEFAULT_VTABLE_THUNKS): Likewise.
- (LIB_SPEC): Add -lc for -shared #ifndef USE_GNULIBC_1.
- * linux.h (LIB_SPEC): Likewise.
- * sparc/linux64.h (LIB_SPEC): Likewise; also updated for glibc 2.
- (LIBGCC_SPEC): Removed.
- (CPP_SUBTARGET_SPEC): Add %{pthread:-D_REENTRANT}.
-
-Fri Feb 20 05:22:12 1998 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
-
- * Makefile.in (distdir-start): Add dependence on bi-parser.[ch].
-
-Thu Feb 19 18:07:11 1998 Jim Wilson <wilson@cygnus.com>
-
- * m68k.h (TARGET_SWITCHES): For 68000, 68302, subtract MASK_68881.
- For 68303, 68332, cpu32, subtract MASK_68040_ONLY.
-
-Wed Feb 18 09:37:29 1998 Paul Eggert <eggert@twinsun.com>
-
- * fixincludes (stdlib.h): Do not double-wrap the size_t typedef.
-
-Wed Feb 18 07:32:11 1998 Jim Wilson <wilson@cygnus.com>
-
- * i960.c (emit_move_sequence): Handle unaligned stores to pseudos.
- * i960.md (store_unaligned_[dt]i_reg): Handle register dest.
- (store_unaligned_ti_reg): Likewise.
-
- * m68k.h (MACHINE_STATE_{SAVE,RESTORE} [MOTOROLA]): Add %# and %/;
- add : to make them into extended asms.
-
-Wed Feb 18 07:08:05 1998 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
-
- * reg-stack.c (compare_for_stack_reg): Only handle FP conditional
- move as next insn specially.
-
- * reload.c (find_reloads): Always convert address reload for
- non-reloaded operand to RELOAD_FOR_OPERAND_ADDRESS.
-
- * emit-rtl.c (hard-reg-set.h): Include.
- (get_lowpart_common): Don't make new REG for hard reg in a
- class that cannot change size.
- * Makefile.in (emit-rtl.o): Depend on hard-reg-set.h.
-
-Sat Feb 14 09:59:00 1998 Richard Earnshaw (rearnsha@arm.com)
-
- * arm.md (movsfcc): Also validate operands[3] for hard float.
- (movdfcc): Only accept fpu_add_operand for operands[3].8
-
-Sat Feb 14 09:32:34 1998 Jim Wilson <wilson@cygnus.com>
-
- * dwarf2out.c (expand_builtin_dwarf_reg_size): New variable mode.
- Convert CCmode to word_mode before calling GET_MODE_SIZE.
-
-Sat Feb 14 09:27:42 1998 David Edelsohn <edelsohn@mhpcc.edu>
-
- * rs6000.h (MY_ISCOFF): Check for U803XTOCMAGIC.
-
-Sat Feb 14 08:29:43 1998 Arvind Sankar <arvind@cse.iitb.ernet.in>
-
- * t-svr4 (TARGET_LIBGCC_CFLAGS): New definition.
-
-Sat Feb 14 07:45:16 1998 Ken Rose (rose@acm.org)
-
- * reorg.c (fill_slots_from_thread): New parameter, delay_list.
- All callers changed.
-
-Sat Feb 14 07:14:02 1998 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
-
- * reload.c (debug_reload): Properly output insn codes.
-
- * pa.c (emit_move_sequence): If in reload, call find_replacement.
-
- * gansidecl.h (bcopy, bzero, {,r}index): Don't define if IN_LIBGCC2.
-
- * combine.c (distribute_notes, case REG_DEAD): When seeing if place
- to put new note sets register, use reg_bitfield_target_p, as in
- original code.
-
- * gcc.c (process_command): If file is for linker, set lang to "*".
- (lookup_compiler): Return 0 for language of "*".
-
- * sched.c (attach_deaths, case SUBREG): Fix error in last change.
-
- * i386.md (mov[sdx]fcc): Disable for now.
- (mov[sd]fcc_1): Add earlyclobber for output on last alternative.
-
-Sat Feb 14 06:42:50 1998 Jason Merrill <jason@yorick.cygnus.com>
-
- * except.c (get_dynamic_handler_chain): Only make call once per func.
- (expand_fixup_region_{start,end}): New functions.
- (expand_eh_region_start_tree): Store cleanup into finalization here.
- * stmt.c (expand_cleanups): Use new functions to protect fixups.
-
- * except.c (get_dynamic_handler_chain): Build up a FUNCTION_DECL.
- * optabs.c (init_optabs): Don't init get_dynamic_handler_chain_libfunc.
- * expr.h (get_dynamic_handler_chain_libfunc): Deleted.
-
-Sat Feb 14 06:34:41 1998 Peter Lawrence <Peter.Lawrence@Eng.Sun.COM>
-
- * optabs.c (emit_conditional_move): Don't reverse condition for FP.
-
-Fri Feb 13 07:22:04 1998 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
-
- * Makefile.in (mostlyclean): Only use s-* convention for stamp
- files in main dir.
-
- * configure.in: Add support for i786 (Pentium II); same as i686.
-
-Thu Feb 12 20:16:35 1998 Michael Meissner <meissner@cygnus.com>
-
- * rs6000.md: Replace gen_rtx (CONST_INT,...) with GEN_INT.
-
-Thu Feb 12 10:08:14 1998 John Hassey <hassey@dg-rtp.dg.com>
-
- * configure.in (i[3456]86-dg-dgux*): Don't need fixincludes.
-
-Thu Feb 12 07:27:39 1998 Mumit Khan <khan@xraylith.wisc.edu>
-
- * i386/cygwin32.h (NO_IMPLICIT_EXTERN_C): Define.
- about system headers.
- (LIB_SPEC): Add -ladvapi32 -lshell32.
-
-Thu Feb 12 07:19:31 1998 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
-
- * expr.c (expand_assignment): Fix typo in checking OFFSET.
-
- * gbl-ctors.h (atexit): Don't define unless needed.
-
- * combine.c (distribute_notes): Completely check for note operand being
- only partially set on potential note target; adjust what notes
- we make in that case.
-
- * i386/xm-go32.h (HAVE_{BCOPY,BZERO,INDEX,RINDEX}): Deleted.
-
-Wed Feb 11 08:53:27 1998 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
-
- * calls.c (emit_call_1): Size args now HOST_WIDE_INT.
- (expand_call): struct_value_size now HOST_WIDE_INT.
-
-Tue Feb 10 09:04:39 1998 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
-
- * integrate.c (initialize_for_inline): Ensure DECL_INCOMING_RTL
- is always copied.
-
-Tue Feb 10 06:10:49 1998 Paul Eggert <eggert@twinsun.com>
-
- * cccp.c (rescan): Fix bug with macro name appearing
- immediately after L'x'.
-
-Mon Feb 9 20:45:32 1998 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
-
- * c-common.c (format_char_info): Add new field zlen.
- (print_char_table): Remove entry for 'Z' as a format character.
- Initialize zlen field as appropriate.
- (scan_char_table): Set zlen field to NULL in each entry.
- (check_format_info): Recognize 'Z' as a length modifier, with a
- warning in pedantic mode.
- Avoid infinite loop when a repeated flag character is detected.
-
-Mon Feb 9 09:24:04 1998 Paul Eggert <eggert@twinsun.com>
-
- * c-parse.in (primary): Minor wording fix in diagnostic.
-
-Mon Feb 9 07:50:19 1998 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
-
- * c-decl.c (grokdeclarator): Remove warning on inline of varargs.
-
- * reload.c (find_reloads): Check for const_to_mem case before
- checking for invalid reload; use force_const_mem if no_input_reloads.
-
- * function.c (push_function_context_to): Call init_emit last.
-
- * protoize.c (my_link): Define as -1 in mingw32.
- (link): Remove declaration.
-
- * rs6000.c (setup_incoming_varargs): Always set rs6000_sysv_varargs_p.
-
- * integrate.c (expand_inline_function): Clear label_map with bzero.
-
- * unroll.c (copy_loop_body, case JUMP_INSN): Correct error in last
- change: call single_set on COPY, not INSN.
-
-Sun Feb 8 08:07:37 1998 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
-
- * msdos/top.sed, winnt/config-nt.sed: Change version number to 2.8.1.
-
- * configure.in (i[3456]86-*-sco3.2v5*): Use cpio for headers.
-
-Sat Feb 7 07:32:46 1998 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
-
- * i386/mingw32.h (LIBGCC_SPEC, STARTFILE_SPEC, MATH_LIBRARY):
- Use msvcrt, not crtdll.
-
-Fri Feb 6 20:32:06 1998 Geert Bosch <bosch@gnat.com>
-
- * i386/xm-os2.h (EMX, USG, BSTRING, HAVE_{PUTENV,VPRINTF,STRERROR}):
- Define ifdef __EMX__.
- (strcasecmp): Define to be stricmp if __EMX__.
- (spawnv{,p}): Don't define if EMX.
- (OBJECT_SUFFIX): Don't define if EMX.
- (MKTEMP_EACH_FILE): Define.
-
-Fri Feb 6 16:37:29 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
-
- * objc/Make-lang.in (objc.stage1): Depend on stage1-start.
- (objc.stage2, objc.stage3, objc.stage4): Likewise for the
- respective stageN-start targets.
- (objc/sendmsg.o): Depend on objc/runtime-info.h.
-
-Fri Feb 6 16:27:09 1998 Bernd Schmidt <crux@Pool.Informatik.RWTH-Aachen.DE>
-
- * stmt.c (expand_asm_operands): Properly treat asm statement
- statements with no operands as volatile.
-
-Fri Feb 6 16:03:25 1998 Greg McGary <gkm@gnu.org>
-
- * c-decl.c (pushdecl): Set DECL_ORIGINAL_TYPE once only.
-
-Fri Feb 6 15:57:36 1998 Mumit Khan <khan@xraylith.wisc.edu>
-
- * i386/cygwin32.h (STRIP_NAME_ENCODING): New macro.
-
-Fri Feb 6 15:50:42 1998 Paul Eggert <eggert@twinsun.com>
-
- * libgcc2.c (__floatdi[xtds]f): Round properly even when rounding
- large negative integer to plus or minus infinity.
-
-Fri Feb 6 15:45:16 1998 Philippe De Muyter <phdm@macqel.be>
-
- * sdbout.c (plain_type_1): Return T_DOUBLE, not T_VOID, for
- long double #ifndef EXTENDED_SDB_BASIC_TYPES.
-
-Fri Feb 6 15:23:49 1998 John David Anglin <dave@hiauly1.hia.nrc.ca>
-
- * vax/ultrix.h (HAVE_ATEXIT): Define.
- * x-vax: File deleted.
-
-Fri Feb 6 14:34:19 1998 Douglas Rupp <rupp@gnat.com>
-
- * gcc.c (process_command, case "-dumpversion"): Print spec_version.
-
-Fri Feb 6 11:01:13 1998 Josh Littlefield <josh@american.com>
-
- * i386/gmon-sol2.c (internal_mcount): Do set-up when program starts
- and install hook to do clean-up when it exits.
- * i386/sol2-c1.asm (_mcount): Make a weak instead of global symbol.
- * i386/sol2dbg.h (ASM_SPEC): Support Solaris bundled assembler's -V
- argument; pass -s argument to assembler.
-
-Fri Feb 6 09:13:21 1998 Jim Wilson (wilson@cygnus.com)
-
- * function.c (assign_parms): New variable named_arg, with value
- depending on STRICT_ARGUMENT_NAMING. Use instead of ! last_named.
-
- * crtstuff.c (__frame_dummy): New function for irix6.
- (__do_global_ctors): Call __frame_dummy for irix6.
- * mips/iris6.h (LINK_SPEC): Hide __frame_dummy too.
-
-Fri Feb 6 09:08:21 1998 Mike Stump <mrs@wrs.com>
-
- * rtlanal.c (dead_or_set_regno_p): Ignore REG_DEAD notes after reload.
- * genattrtab.c (reload_completed): Define.
-
- * configure.in (i960-wrs-vxworks): Same as i960-wrs-vxworks5*.
-
-Fri Feb 6 08:47:38 1998 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
-
- * Makefile.in (diff): Add INSTALL, configure, and config.in;
- remove objc-*.
- * objc/config-lang.in (diff_excludes): Add objc-parse.[cy].
-
- * i386/xm-mingw32.h (link): Delete macro.
-
- * alpha.c (output_prolog): Write out frame sizes as longs and
- print too large sizes as zero.
-
- * function.c (combine_temp_slots): No need to allocate and free rtx.
- Don't do anything if too many slots in the list.
- (put_var_into_stack): Don't use ADDRESSOF if not optimizing.
-
- * function.c (purge_addressof_1): Force into mem if VOLATILE reference.
-
- * calls.c (expand_call): Show VAR_DECL made for structure return
- address is used; remove bogus set of MEM_IN_STRUCT_P.
- * expr.c (expand_expr, case SAVE_EXPR, case TARGET_EXPR): Show used.
- (expand_builtin, case BUILT_IN_LONGJMP): Show __dummy used.
- * function.c (put_reg_into_stack): New arg USED_P; all callers changed.
-
- * expr.c (expand_expr, case SAVE_EXPR): assign_temp with KEEP of 3.
- * function.c (var_temp_slot_level): New variable.
- (push_function_context_to, pop_function_context_from): Save/restore
- it and target_temp_slot_level.
- (assign_stack_temp): Implement KEEP of 3.
- (push_temp_slots_for_block): New function.
- (init_temp_slots): Initialize var_temp_slot_level.
- * function.h (struct function, fields {var,target}_temp_slot_level):
- New fields.
- * stmt.c (expand_start_bindings): Call push_temp_slots_for_block.
-
- * function.c (struct temp_slot): SIZE, BASE_OFF_SET, and FULL_SIZE
- now HOST_WIDE_INT.
- (assign_{,outer_}stack_local, assign_{,stack_}temp): Size arg is
- now HOST_WIDE_INT.
- (assign_stack_temp): Do size computations in HOST_WIDE_INT.
- (fixup_var_refs_1, optimize_bit_field, instantiate_decls): Likewise.
- (instantiate_virtual_regs_1, fix_lexical_address): Likewise.
- * rtl.h (assign_stack_{local,temp}): Size arg is HOST_WIDE_INT.
- (assign_temp): Likewise.
- * expr.h (struct args_size): Field CONSTANT is now HOST_WIDE_INT.
-
- * sched.c (attach_deaths, case REG): Don't check for REG_UNUSED.
- (attach_deaths, case SUBREG, STRICT_LOW_PART, {ZERO,SIGN}_EXTRACT):
- Don't pass set_p of 1 if partial assignment.
-
- * tree.h (size_in_bytes): Returns HOST_WIDE_INT.
- * tree.c (size_in_bytes): Likewise.
- Tighen up logic some to avoid returning a bogus value instead of -1.
-
- * expr.c (get_inner_reference, case ARRAY_EXPR): Make WITH_RECORD_EXPR
- just for index.
- (expand_expr, case PLACEHOLDER_EXPR): Refine search again; look
- at each expression and look for pointer to type.
-
- * expr.c (safe_from_p, case ADDR_EXPR): If TREE_STATIC, no trampoline.
- (expand_expr, case ADDR_EXPR): Likewise.
-
- * expr.c (emit_block_move): Use conservative range for movstr mode.
-
- * configure.in: See if "cp -p" works if "ln -s" doesn't; else "cp".
-
- * combine.c (try_combine.c): Pass elim_i2 and elim_i1 to
- distribute_notes for i3dest_killed REG_DEAD note.
-
- * configure.in (mips-dec-netbsd*): Remove bogus setting of prefix.
-
- * c-decl.c (duplicate_decls): Set DECL_IGNORED_P in newdecl if
- different bindings levels.
-
- * configure.in: Test ln -s by symlinking gcc.c.
-
- * configure.in (i[3456]86-dg-dgux): Add wildcard for version.
-
- * crtstuff.c (__do_global_ctors_aux): Switch back to text section
- in proper place.
-
- * rtlanal.c (rtx_varies_p, case REG): pic_offset_table_rtx is fixed.
- * genattrtab.c (pic_offset_table_rtx): Define (dummy).
- * cse.c (set_nonvarying_address_components): Understand PIC refs.
-
- * loop.c (strength_reduce): When placing increment for auto-inc
- case, do comparison in loop order.
-
- * i860.c (output_delayed_branch): Add missing arg to recog.
- (output_delay_insn): Add missing arg to constrain_operands.
-
- * configure.in: Truncate target after finished comparing it with host.
-
- * i386.h (MAX_FIXED_MODE_SIZE): Delete.
-
- * c-parse.in (expr_no_comma): Clarify undefined error.
-
- * prefix.c (get_key_value): Don't default to PREFIX here.
- (translate_name): Remove bogus addition of "$" if getenv fails;
- clean up application of default value of PREFIX.
-
- * fold-const.c (fold_convert): Call force_fit_type even if input
- already overflows.
-
-Fri Feb 6 07:45:01 1998 Robert Hoehne <robert.hoehne@gmx.net>
-
- * i386/xm-go32.h (HAVE_{BCOPY,BZERO,BCMP,RINDEX,INDEX}): Define.
-
- * gcc.c (main): Treat paths starting with '$' or DOS drives
- as absolute in standard_startfile_prefix.
-
-Thu Feb 5 21:07:12 1998 John David Anglin <dave@hiauly1.hia.nrc.ca>
-
- * cpplib.c (IS_INCLUDE_DIRECTIVE_TYPE): Add casts from enum to int.
- * cccp.c (IS_INCLUDE_DIRECTIVE_TYPE, handle_directive): Likewise.
-
-Thu Feb 5 19:00:44 1998 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
-
- * expr.c (expand_expr, case CONSTRUCTOR): Correct shift count
- when making signed bit field; use EXPAND_NORMAL, not 0.
-
-Thu Feb 5 17:42:43 1998 Manfred Hollstein <manfred@s-direktnet.de>
-
- * libgcc2.c (__clear_insn_cache): On sysV68 enable the memctl
- stuff only if MCT_TEXT is #define'd.
-
-Thu Feb 5 17:32:01 1998 Robert Hoehne <robert.hoehne@gmx.net>
-
- * Makefile.in: Changed most stamp-* to s-*.
-
-Tue Feb 3 19:45:50 1998 James Hawtin <oolon@ankh.org>
-
- * i386/sol2.h (STARTFILE_SPEC, LIB_SPEC): Update -pg files.
- * configure.in (i[3456]86-*-solaris2*): Add gcrt1.o and gmon.o
- to extra_parts.
-
-Tue Feb 3 17:28:48 1998 Christopher C Chimelis <chris@classnet.med.miami.edu>
-
- * configure.in (alpha*-*-linux-gnu*): Add extra_parts for crtstuff.
-
-Tue Feb 3 17:18:19 1998 Richard Earnshaw <rearnsha@arm.com>
-
- * arm.c (find_barrier): Fix one-too-many bug if fail to find barrier.
-
- * arm.c (arm_reload_in_hi): Handle cases where the MEM is too
- complex for a simple offset.
-
-Tue Feb 3 16:14:21 1998 Robert Hoehne <robert.hoehne@gmx.net>
-
- * i386/xm-go32.h (EXECUTABLE_SUFFIX): Define.
-
- * configure.in (i[3456]86-pc-msdosdjgpp*): New entry.
-
-Tue Feb 3 07:33:58 1998 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
-
- * explow.c (probe_stack_range): Properly check for small
- number of probes.
-
- * gcc.c (process_command, case 'V'): Validate arg.
-
- * configure.in (sbrk): Add check for needed declaration.
- * acconfig.h (NEED_DECLARATION_SBRK): New entry.
- * toplev.c (sbrk): Update declaration conditional.
- * mips-tfile.c (sbrk, free): Likewise.
-
- * sparc/sysv4.h (DBX_REGISTER_NUMBER): Remove abort.
-
- * mips.c (mips_expand_prologue): Pass reg 25 to gen_loadgp.
- * mips.md (loadgp): Add second operand for register number to add.
- (builtin_setjmp_receiver): Pass new label and reg 31 to loadgp.
-
- * toplev.c: Include insn-codes.h, insn-config.h, and recog.h.
- (compile_file): Try to emit nop to separate gcc_compiled symbol.
- * Makefile.in (toplev.o): Depends on insn-{codes,config}.h, recog.h.
-
-Tue Feb 3 06:58:46 1998 Mark Mitchell <mmitchell@usa.net>
-
- * integrate.c (get_label_from_map): New function.
- (expand_inline_function): Use it.
- Initialize label_map to NULL_RTX instead of gen_label_rtx.
- (copy_rtx_and_substitute): Use get_label_from_map.
- * integrate.h (get_label_from_map): New function.
- (set_label_from_map): New macro.
- * unroll.c (unroll_loop, copy_loop_body): Use them.
-
-Mon Feb 2 16:33:01 1998 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
-
- * i386.md (mov{si,hi,sf,df,xf}cc{,_1}): Remove cases with branches.
-
- * rs6000/x-aix31 (INSTALL): Deleted.
- * mips/x-dec-osf1, mips/x-osfrose, i386/x-osfrose: Likewise.
- * arm/x-riscix: Likewise.
-
- * c-typeck.c (signed_or_unsigned_type): Properly handle pointer types.
-
-Mon Feb 2 15:33:58 1998 Michael P. Hayes <michaelh@ongaonga.chch.cri.nz>
-
- * unroll.c (copy_loop_body): Use single_set instead of
- PATTERN to detect increment of an iv inside a PARALLEL.
-
-Fri Jan 16 20:29:50 1998 Paul Eggert <eggert@twinsun.com>
-
- * toplev.c (<unistd.h>): New include.
- (get_run_time): Prefer CLK_TCK (if available) to HZ, and
- prefer sysconf (_SC_CLK_TCK) (if available) to CLK_TCK.
- * configure.in (sysconf): Call AC_CHECK_FUNCS.
-
-Wed Jan 14 20:10:51 1998 Paul Eggert <eggert@twinsun.com>
-
- * cccp.c: (rescan): Don't report line 0 as the possible real start
- of an unterminated string constant.
- Don't mishandle backslash-newlines that in are the output of
- a macro expansion. Properly skip // style comments between a function
- macro name and '(', as well as backslash-newlines in comments there.
- (handle_directive): Handle / \ newline * between # and directive name.
- In #include directives, \ does not escape ".
- (do_include): For `#include "file', do not bother expanding into temp
- buffer. When error encountered when expanding, do not try result.
- (skip_if_group): When skipping an include directive, use include
- tokenization, not normal tokenization. Backslash-newline is still
- special when skipping. Handle * \ newline / correctly in comments
- when skipping.
- (skip_quoted_string): After \ newline, set *backslash_newlines_p
- even if count_newlines is 0.
- (macroexpand): Newline space is not a special marker inside a string.
- (macroexpand, macarg): Do not generate \ddd for control characters
- when stringifying; the C Standard does not allow this.
- (macarg1): New arg MACRO. All callers changed.
- Do not treat /*, //, or backslash-newline specially when processing
- the output of a macro.
- (discard_comments): Don't go past limit if looking for end of comment.
- Discard backslash-newline properly when discarding comments.
- (change_newlines): \" does not end a string.
- (make_definition): Do not treat backslash-newline specially, as it
- has already been removed before we get here.
-
- * profile.c (output_func_start_profiler): Don't fflush output
- if -quiet.
- * toplev.c (rest_of_compilation): Likewise.
-
- * i386/x-sco5 (CC): Remove trailing white space.
- * x-convex (CCLIBFLAGS): Likewise.
- * arm/t-semi (LIBGCC2_CFLAGS): Likewise.
-
-Wed Jan 7 18:02:42 1998 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
-
- * Version 2.8.0 released.
-
-Wed Jan 7 17:54:41 1998 J. Kean Johnston <jkj@sco.com>
-
- * i386/sco5.h ({END,START}FILE_SPEC): Link with correct crtbegin.o
- and crtend.o when using -static.
-
-Wed Jan 7 17:49:14 1998 Jan Christiaan van Winkel <Jan.Christiaan.van.Winkel@ATComputing.nl>
-
- * cppexp.c (gansidecl.h): Include.
-
-Wed Jan 7 17:45:07 1998 Tristan Gingold <gingold@puccini.enst.fr>
-
- * expr.c (get_push_address): Use copy_to_reg instead of force_operand.
- (emit_push_insn): Avoid null pointer deference if aggregate has no
- types.
- (expand_expr): Avoid finite but useless recursion.
- (expand_builtin): Fix typo in calling function.
- * function.c (assign_parms): Avoid useless call to chkr_set_right.
-
-Wed Jan 7 17:31:13 1998 Christian Iseli <Christian.Iseli@lslsun.epfl.ch>
-
- * combine.c (force_to_mode): Return if operand is a CLOBBER.
-
-Wed Jan 7 17:23:24 1998 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
-
- * x-rs6000 (INSTALL): Remove.
-
- * jump.c (jump_optimize): Don't use a hard reg as an operand
- of a conditional move if small register classes.
-
-Wed Jan 7 17:09:28 1998 Jim Wilson <wilson@cygnus.com>
-
- * cse.c (max_insn_uid): New variable.
- (cse_around_loop): Use it.
- (cse_main): Set it.
-
-See ChangeLog.11 for earlier changes.
-
-Use a consistent time stamp format in ChangeLog entries.
-Not everyone has Emacs 20 yet, so stick with Emacs 19 format for now.
-
-Local Variables:
-add-log-time-format: current-time-string
-End:
diff --git a/gcc/LITERATURE b/gcc/LITERATURE
deleted file mode 100644
index ac35e3a5a74..00000000000
--- a/gcc/LITERATURE
+++ /dev/null
@@ -1,101 +0,0 @@
-Collected papers/sites on standards, compilers, optimization, etc.
-
-- Massively Scalar Compiler Project
-
- ftp://cs.rice.edu/public/preston/optimizer
-
-- Searchable article archive
-
- http://hypatia.dcs.qmw.ac.uk/SEL-HPC/Articles/CompilersArchive.html
-
-- David M Keaton's site
-
- http://www.dmk.com, ftp://ftp.dmk.com
- c9x stuff is in ftp://ftp.dmk.com/DMK/sc22wg14/c9x
-
-- Some information about optimizing for x86 processors, links to
- x86 manuals and documentation.
-
- http://www.goof.com/pcg/docs.html
-
-
-- AMD site with optimization guide for x86
-
- http://www.amd.com/K6/k6docs/pdf/21828a.pdf
-
-- Links related to many compiler topics
-
- http://www.nullstone.com/htmls/connections.htm
-
-- HPPA information:
-
- http://www.hp.com/computing/framed/technology/micropro
-
-- New compiler book. Online appendix includes some compiler links
-
- http://www.mkp.com/books_catalog/1-55860-320-4.asp
-
-- Various MIPS stuff:
-
- http://www.sgi.com/MIPS/arch/mips4docs/mipsiv_3_2.pdf (*)
- http://www.sgi.com/MIPS/arch/MIPS16/MIPS16.whitepaper.pdf
- http://www.sgi.com/MIPS/arch/MIPS16/mips16.pdf
- http://www.sgi.com/MIPS/arch/ISA5/isa5_tech_brf.pdf
- http://www.sgi.com/MIPS/arch/ISA5/MDMXspec.pdf
- http://www.sgi.com/MIPS/arch/ISA5/MIPSVspec.pdf
-
-
-- IBM Journal of Research and Development
-
- http://www.almaden.ibm.com/journal/
-
-
-- System V PowerPC ABI
-
- http://www.esofta.com/softspecs.html
-
-- C9X draft
-
- http://www.dkuug.dk/JTC1/SC22/WG14/www/docs/n794.htm
-
-- DWARF v2 spec and sample implementation
-
- ftp://sgigate.sgi.com/pub/dwarf/
-
-
-- Various m68k info (including user guides in pdf format)
-
- http://www.mot.com/SPS/HPESD/prod/0X0
-
-
-- Modula 3 Stuff
-
- http://www.cmass.com
- http://www.cl.cam.ac.uk/m3doc/linux/cambridge.html
- ftp://ftp.freebsd.org/pub/FreeBSD/distfiles/LOCAL_PORTS/m3-fbsd-m3cc-3.6.tar.gz
- http://www.m3.org
-
-- Comp.compilers archive
-
- http://www.iecc.com/compilers
-
-- Intel Pentium design info:
-
- http://developer.intel.com/design/litcentr/index.htm
-
-- comp.std.c++ FAQ:
-
- http://reality.sgi.com/employees/austern_mti/std-c++/faq.html
-
-- EG3 maintains a list of compiler Internet resources, including FAQ's,
-papers, hot list pages, potential software/shareware, all known companies, etc.
-
- http://www.eg3.com/ulc/compulc.htm
- http://www.eg3.com/softd/compiler.htm
- http://www.eg3.com/softdv/compiler.htm
-
- These resource pages are published as part of EG3's
- Free Electronic Engineers' Toolbox at:
-
- http://www.eg3.com/ebox.htm
-
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 2328473ede5..e88b62adf2e 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -1,18 +1,18 @@
# Makefile for GNU C compiler.
-# Copyright (C) 1987, 88, 90-97, 1998 Free Software Foundation, Inc.
-
+# Copyright (C) 1987, 88, 90-98, 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,
@@ -39,7 +39,13 @@ SUBDIRS =@subdirs@
# Selection of languages to be made.
# This is overridden by configure.
-LANGUAGES = c proto gcov$(exeext) @all_languages@
+CONFIG_LANGUAGES = @all_languages@
+LANGUAGES = c proto gcov$(exeext) $(CONFIG_LANGUAGES)
+
+# Languages should create dependencies of $(INTL_TARGETS) on generated
+# sources in Make-lang.in. Example:
+# $(INTL_TARGETS): $(srcdir)/cp/parse.c
+INTL_TARGETS = intl.all intl.install intl.distdir
# Selection of languages to be made during stage1 build.
# This is overridden by configure.
@@ -72,6 +78,7 @@ T_CFLAGS =
X_CPPFLAGS =
T_CPPFLAGS =
+AWK = @AWK@
CC = @CC@
# srcdir might be a relative pathname which won't be valid in a subdirectory,
# so we must use objdir/srcdir instead to make it safe. objdir is always
@@ -97,7 +104,9 @@ LN_S=@LN_S@
# These permit overriding just for certain files.
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
-MAKEINFO = makeinfo
+MAKEINFO = `if [ -f $(objdir)/../texinfo/makeinfo/Makefile ] ; \
+ then echo $(objdir)/../texinfo/makeinfo/makeinfo ; \
+ else echo makeinfo ; fi`
MAKEINFOFLAGS =
TEXI2DVI = texi2dvi
# For GNUmake: let us decide what gets passed to recursive makes.
@@ -112,7 +121,9 @@ P =
# How to invoke ranlib.
RANLIB = ranlib
# Test to use to see whether ranlib exists on the system.
-RANLIB_TEST = [ -f /usr/bin/ranlib -o -f /bin/ranlib ]
+RANLIB_TEST = \
+ [ -f $(RANLIB) ] \
+ || [ -f /usr/bin/ranlib -o -f /bin/ranlib ]
# Compiler to use for compiling libgcc1.a.
# OLDCC should not be the GNU C compiler,
@@ -145,7 +156,7 @@ USER_H = $(srcdir)/ginclude/stdarg.h $(srcdir)/ginclude/stddef.h \
$(srcdir)/ginclude/va-m32r.h $(srcdir)/ginclude/va-sh.h \
$(srcdir)/ginclude/va-v850.h $(srcdir)/ginclude/va-arc.h \
$(srcdir)/ginclude/iso646.h $(srcdir)/ginclude/va-ppc.h \
- $(EXTRA_HEADERS) $(LANG_EXTRA_HEADERS) \
+ $(srcdir)/ginclude/va-c4x.h $(EXTRA_HEADERS) $(LANG_EXTRA_HEADERS) \
$(srcdir)/ginclude/proto.h $(srcdir)/ginclude/stdbool.h
# Target to use whe installing assert.h. Some systems may
@@ -155,7 +166,7 @@ INSTALL_ASSERT_H = install-assert-h
# The GCC to use for compiling libgcc2.a, enquire, and libgcc1-test.
# Usually the one we just built.
# Don't use this as a dependency--use $(GCC_PASSES) or $(GCC_PARTS).
-GCC_FOR_TARGET = ./xgcc -B./
+GCC_FOR_TARGET = ./xgcc -B./ -B$(build_tooldir)/bin/
# This is used instead of ALL_CFLAGS when compiling with GCC_FOR_TARGET.
# It omits XCFLAGS, and specifies -B./.
@@ -188,7 +199,7 @@ AR_FOR_TARGET = ` \
t='$(program_transform_name)'; echo ar | sed -e $$t ; \
fi; \
fi`
-AR_FOR_TARGET_FLAGS = rc
+AR_FLAGS_FOR_TARGET = rc
RANLIB_FOR_TARGET = ` \
if [ -f $(objdir)/../binutils/ranlib ] ; then \
echo $(objdir)/../binutils/ranlib ; \
@@ -204,18 +215,6 @@ RANLIB_TEST_FOR_TARGET = \
|| ( [ "$(host_canonical)" = "$(target)" ] \
&& [ -f /usr/bin/ranlib -o -f /bin/ranlib ] )
-# We always act like a cross-compiler, even when we're
-# compiling native. This is because we want to use our own tools if
-# we can. We don't just set RANLIB to a complicated expression,
-# because the top level Makefile.in might override RANLIB_FOR_TARGET.
-# These are from the FSF file "cross-make".
-AR = $(AR_FOR_TARGET)
-AR_FLAGS = $(AR_FOR_TARGET_FLAGS)
-OLDAR = $(AR_FOR_TARGET)
-OLDAR_FLAGS = $(AR_FOR_TARGET_FLAGS)
-RANLIB = $(RANLIB_FOR_TARGET)
-RANLIB_TEST = $(RANLIB_TEST_FOR_TARGET)
-
# Dir to search for system headers. Overridden by cross-make.
SYSTEM_HEADER_DIR = /usr/include
@@ -247,6 +246,7 @@ lang_options_files=@lang_options_files@
lang_tree_files=@lang_tree_files@
GCC_THREAD_FILE=@thread_file@
OBJC_BOEHM_GC=@objc_boehm_gc@
+JAVAGC=@JAVAGC@
GTHREAD_FLAGS=@gthread_flags@
# Be prepared for gcc2 merges.
gcc_version=@gcc_version@
@@ -270,17 +270,28 @@ bindir = @bindir@
libdir = @libdir@
# Directory in which the compiler finds executables, libraries, etc.
libsubdir = $(libdir)/gcc-lib/$(target_alias)/$(version)
-# Used to produce a relative $(tooldir) in gcc.o
+# Used to produce a relative $(gcc_tooldir) in gcc.o
unlibsubdir = ../../..
+# Directory in which to find other cross-compilation tools and headers.
+dollar = @dollar@
+# Used in install-cross.
+gcc_tooldir = @gcc_tooldir@
+# Since tooldir does not exist at build-time, use -B$(build_tooldir)/bin/
+build_tooldir = $(exec_prefix)/$(target_alias)
# Directory in which the compiler finds g++ includes.
-gxx_include_dir= @gxx_include_dir@
+gcc_gxx_include_dir= @gcc_gxx_include_dir@
# Directory to search for site-specific includes.
includedir = $(local_prefix)/include
# assertdir is overridden in cross-make.
# (But this currently agrees with what is in cross-make.)
-assertdir = $(tooldir)/include
+assertdir = $(gcc_tooldir)/include
# where the info files go
infodir = @infodir@
+# Where cpp should go besides $prefix/bin if necessary
+cpp_install_dir = @cpp_install_dir@
+# where the locale files go
+datadir = $(prefix)/@DATADIRNAME@
+localedir = $(datadir)/locale
# Extension (if any) to put in installed man-page filename.
manext = .1
objext = .o
@@ -288,13 +299,24 @@ exeext = @host_exeext@
build_exeext = @build_exeext@
# Directory in which to put man pages.
-mandir = @mandir@/man1
-# Directory in which to find other cross-compilation tools and headers.
-# Used in install-cross.
-tooldir = $(exec_prefix)/$(target_alias)
+mandir = @mandir@
+man1dir = $(mandir)/man1
# Dir for temp files.
tmpdir = /tmp
+# Top build directory, relative to here.
+top_builddir = .
+
+# Whether we were configured with NLS.
+USE_NLS = @USE_NLS@
+
+# Internationalization library.
+INTLLIBS = @INTLLIBS@
+
+# List of internationalization subdirectories.
+POSUB = @POSUB@
+INTL_SUBDIRS = intl $(POSUB)
+
# Additional system libraries to link with.
CLIB=
@@ -390,13 +412,13 @@ LIB1FUNCS_EXTRA =
# Assembler files should have names ending in `.asm'.
LIB2FUNCS_EXTRA =
-# Default float.h source to use for cross-compiler.
-# This is overridden by configure.
-CROSS_FLOAT_H=$(srcdir)/config/float-@float_format@.h
+# Handle cpp installation.
+INSTALL_CPP=
+UNINSTALL_CPP=
# We do not try to build float.h anymore. Let configure select the
# appropriate pre-built float.h file for the target.
-FLOAT_H=$(srcdir)/config/float-@float_format@.h
+FLOAT_H=@float_h_file@
# Program to convert libraries.
LIBCONVERT =
@@ -407,10 +429,6 @@ INSTALL_HEADERS=install-headers
# Options for tar when copying trees. So HPUX can override it.
TAROUTOPTS = xpBf
-# Select which version of fixincludes to use (I.E. regular versus SVR4)
-# This value is overridden directly by configure.
-FIXINCLUDES = @fixincludes@
-
# Additional directories of header files to run fixincludes on.
# These should be directories searched automatically by default
# just as /usr/include is.
@@ -450,6 +468,7 @@ HOST_PREFIX_1=loser-
HOST_CC=$(CC)
HOST_CFLAGS=$(ALL_CFLAGS)
HOST_CLIB=$(CLIB)
+HOST_INTLLIBS=$(INTLLIBS)
HOST_LDFLAGS=$(LDFLAGS)
HOST_CPPFLAGS=$(ALL_CPPFLAGS)
HOST_ALLOCA=$(ALLOCA)
@@ -460,8 +479,10 @@ HOST_DOPRINT=$(DOPRINT)
# Actual name to use when installing a native compiler.
GCC_INSTALL_NAME = `t='$(program_transform_name)'; echo gcc | sed -e $$t`
+CPP_INSTALL_NAME = `t='$(program_transform_name)'; echo cpp | sed -e $$t`
PROTOIZE_INSTALL_NAME = `t='$(program_transform_name)'; echo protoize | sed -e $$t`
UNPROTOIZE_INSTALL_NAME = `t='$(program_transform_name)'; echo unprotoize | sed -e $$t`
+GCOV_INSTALL_NAME = `t='$(program_transform_name)'; echo gcov | sed -e $$t`
# Actual name to use when installing a cross-compiler.
GCC_CROSS_NAME = `t='$(program_transform_cross_name)'; echo gcc | sed -e $$t`
@@ -526,11 +547,13 @@ all: all.indirect
all.indirect: $(ALL)
# IN_GCC tells various files that system.h, toplev.c, etc are available.
-INTERNAL_CFLAGS = $(CROSS) -DIN_GCC @extra_c_flags@
+INTERNAL_CFLAGS = $(CROSS) -DIN_GCC $(SCHED_CFLAGS) @extra_c_flags@
# This is the variable actually used when we compile.
+# If you change this line, you probably also need to change the definition
+# of HOST_CFLAGS in build-make to match.
ALL_CFLAGS = $(INTERNAL_CFLAGS) $(X_CFLAGS) $(T_CFLAGS) $(CFLAGS) $(XCFLAGS) \
- @DEFS@ $(SCHED_CFLAGS)
+ @DEFS@
# Likewise.
ALL_CPPFLAGS = $(CPPFLAGS) $(X_CPPFLAGS) $(T_CPPFLAGS)
@@ -546,22 +569,22 @@ USE_HOST_DOPRINT= ` case "${HOST_DOPRINT}" in ?*) echo ${HOST_PREFIX}${HOST_DOPR
# Dependency on obstack, alloca, malloc or whatever library facilities
# are not installed in the system libraries.
# We don't use USE_ALLOCA because backquote expansion doesn't work in deps.
-LIBDEPS= $(OBSTACK) $(ALLOCA) $(MALLOC) $(VFPRINTF) $(DOPRINT)
+LIBDEPS= $(INTLLIBS) $(OBSTACK) $(ALLOCA) $(MALLOC) $(VFPRINTF) $(DOPRINT)
# Likewise, for use in the tools that must run on this machine
# even if we are cross-building GCC.
# We don't use USE_ALLOCA because backquote expansion doesn't work in deps.
-HOST_LIBDEPS= $(HOST_PREFIX)$(HOST_OBSTACK) $(HOST_PREFIX)$(HOST_ALLOCA) $(HOST_PREFIX)$(HOST_MALLOC) $(HOST_PREFIX)$(HOST_VFPRINTF) $(HOST_PREFIX)$(HOST_DOPRINT)
+HOST_LIBDEPS= $(HOST_PREFIX)$(HOST_INTLLIBS) $(HOST_PREFIX)$(HOST_OBSTACK) $(HOST_PREFIX)$(HOST_ALLOCA) $(HOST_PREFIX)$(HOST_MALLOC) $(HOST_PREFIX)$(HOST_VFPRINTF) $(HOST_PREFIX)$(HOST_DOPRINT)
# How to link with both our special library facilities
# and the system's installed libraries.
-LIBS = $(OBSTACK) $(USE_ALLOCA) $(MALLOC) $(VFPRINTF) $(DOPRINT) $(CLIB) \
- ../libiberty/libiberty.a
+LIBS = $(OBSTACK) $(USE_ALLOCA) $(MALLOC) $(INTLLIBS) @LIBS@ $(VFPRINTF) $(DOPRINT) $(CLIB) ../libiberty/libiberty.a
# Likewise, for use in the tools that must run on this machine
# even if we are cross-building GCC.
-HOST_LIBS = $(USE_HOST_OBSTACK) $(USE_HOST_ALLOCA) $(USE_HOST_MALLOC) \
- $(USE_HOST_VFPRINTF) $(USE_HOST_DOPRINT) $(HOST_CLIB)
+HOST_LIBS = $(USE_HOST_OBSTACK) $(USE_HOST_ALLOCA) $(USE_HOST_MALLOC) \
+ $(HOST_INTLLIBS) $(USE_HOST_VFPRINTF) $(USE_HOST_DOPRINT) \
+ $(HOST_CLIB)
HOST_RTL = $(HOST_PREFIX)rtl.o $(HOST_PREFIX)bitmap.o $(HOST_PREFIX)ggc-none.o
HOST_RTLANAL = $(HOST_PREFIX)rtlanal.o
@@ -597,7 +620,7 @@ LANG_EXTRA_HEADERS = @all_headers@
# subdirectories.
# ??? The choices here will need some experimenting with.
FLAGS_TO_PASS = \
- "AR_FLAGS=$(AR_FOR_TARGET_FLAGS)" \
+ "AR_FLAGS_FOR_TARGET=$(AR_FLAGS_FOR_TARGET)" \
"AR_FOR_TARGET=$(AR_FOR_TARGET)" \
"BISON=$(BISON)" \
"BISONFLAGS=$(BISONFLAGS)" \
@@ -622,10 +645,23 @@ FLAGS_TO_PASS = \
"exec_prefix=$(exec_prefix)" \
"prefix=$(prefix)" \
"local_prefix=$(local_prefix)" \
- "gxx_include_dir=$(gxx_include_dir)" \
+ "gxx_include_dir=$(gcc_gxx_include_dir)" \
"tooldir=$(tooldir)" \
+ "gcc_tooldir=$(gcc_tooldir)" \
"bindir=$(bindir)" \
- "libsubdir=$(libsubdir)"
+ "libsubdir=$(libsubdir)" \
+ "datadir=$(datadir)" \
+ "distdir=../tmp/\$$(subdir)" \
+ "localedir=$(localedir)"
+
+PREPEND_DOTDOT_TO_RELATIVE_PATHS = sed \
+ -e 's|^ *[^ /][^ /]*/|%&|' \
+ -e 's| -B| -B%|g' \
+ -e 's|% *[^- /]|%&|g' \
+ -e 's|%% *|../|g' \
+ -e 's|%||g'
+SUBDIR_FLAGS_TO_PASS = $(ORDINARY_FLAGS_TO_PASS) \
+ "CC=`echo @cc_set_by_configure@ | $(PREPEND_DOTDOT_TO_RELATIVE_PATHS)`"
#
# Lists of files for various purposes.
@@ -642,14 +678,18 @@ SCHED_CFLAGS = @sched_cflags@
# Language-independent object files.
OBJS = toplev.o version.o tree.o print-tree.o stor-layout.o fold-const.o \
function.o stmt.o except.o expr.o calls.o expmed.o explow.o optabs.o \
- varasm.o rtl.o print-rtl.o rtlanal.o emit-rtl.o genrtl.o real.o regmove.o \
- dbxout.o sdbout.o dwarfout.o dwarf2out.o xcoffout.o bitmap.o alias.o \
+ intl.o varasm.o rtl.o print-rtl.o rtlanal.o emit-rtl.o genrtl.o real.o \
+ dbxout.o sdbout.o dwarfout.o dwarf2out.o xcoffout.o bitmap.o alias.o gcse.o \
integrate.o jump.o cse.o loop.o unroll.o flow.o stupid.o combine.o varray.o \
- regclass.o local-alloc.o global.o reload.o reload1.o caller-save.o gcse.o \
+ regclass.o regmove.o local-alloc.o global.o reload.o reload1.o caller-save.o \
insn-peep.o reorg.o $(SCHED_PREFIX)sched.o final.o recog.o reg-stack.o \
insn-opinit.o insn-recog.o insn-extract.o insn-output.o insn-emit.o \
profile.o insn-attrtab.o $(out_object_file) getpwd.o $(EXTRA_OBJS) \
convert.o mbchar.o dyn-string.o $(GGC)
+ insn-opinit.o insn-recog.o insn-extract.o insn-output.o insn-emit.o lcm.o \
+ profile.o insn-attrtab.o $(out_object_file) getpwd.o $(EXTRA_OBJS) convert.o \
+ mbchar.o dyn-string.o splay-tree.o graph.o sbitmap.o resource.o hash.o \
+ $(GGC)
# GEN files are listed separately, so they can be built before doing parallel
# makes for cc1 or cc1plus. Otherwise sequent parallel make attempts to load
@@ -662,7 +702,7 @@ CCCP=@cpp_main@
# Files to be copied away after each stage in building.
STAGESTUFF = *$(objext) insn-flags.h insn-config.h insn-codes.h \
insn-output.c insn-recog.c insn-emit.c insn-extract.c insn-peep.c \
- insn-attr.h insn-attrtab.c insn-opinit.c genrtl.c genrtl.h tree-check.h \
+ insn-attr.h insn-attrtab.c insn-opinit.c tree-check.h \
s-flags s-config s-codes s-mlib s-under\
s-output s-recog s-emit s-extract s-peep s-check \
s-attr s-attrtab s-opinit s-crt s-crtS s-crt0 \
@@ -671,15 +711,15 @@ STAGESTUFF = *$(objext) insn-flags.h insn-config.h insn-codes.h \
genconfig$(build_exeext) genpeep$(build_exeext) genattrtab$(build_exeext) \
genattr$(build_exeext) genopinit$(build_exeext) gengenrtl$(build_exeext) \
gencheck$(build_exeext) \
- xgcc$(exeext) cc1$(exeext) cpp$(exeext) $(EXTRA_PASSES) \
+ xgcc$(exeext) xcpp$(exeext) cc1$(exeext) cpp$(exeext) $(EXTRA_PASSES) \
$(EXTRA_PARTS) $(EXTRA_PROGRAMS) gcc-cross$(exeext) \
$(CCCP)$(exeext) cc1obj$(exeext) enquire$(exeext) \
protoize$(exeext) unprotoize$(exeext) \
specs collect2$(exeext) $(USE_COLLECT2) underscore.c \
gcov$(exeext) *.bp \
*.greg *.lreg *.combine *.flow *.cse *.jump *.rtl *.tree *.loop \
- *.dbr *.jump2 *.sched *.cse2 *.sched2 *.stack *.gcse \
- *.[si] \
+ *.dbr *.jump2 *.sched *.cse2 *.sched2 *.stack *.gcse *.flow2 \
+ *.[si] libcpp.a \
$(LANG_STAGESTUFF)
# Members of libgcc1.a.
@@ -723,14 +763,14 @@ DPBIT_FUNCS = _pack_df _unpack_df _addsub_df _mul_df _div_df \
# ??? Missing ggc.h dependancies.
# CONFIG_H = $(host_xm_file) $(tm_file)
CONFIG_H =
-RTL_BASE_H = rtl.h rtl.def gansidecl.h machmode.h machmode.def
+RTL_BASE_H = rtl.h rtl.def machmode.h machmode.def
RTL_H = $(RTL_BASE_H) genrtl.h
-TREE_H = tree.h real.h tree.def gansidecl.h machmode.h machmode.def tree-check.h
-BASIC_BLOCK_H = basic-block.h bitmap.h
-DEMANGLE_H = demangle.h gansidecl.h
-RECOG_H = recog.h gansidecl.h
+TREE_H = tree.h real.h tree.def machmode.h machmode.def tree-check.h
+BASIC_BLOCK_H = basic-block.h bitmap.h sbitmap.h
+DEMANGLE_H = $(srcdir)/../include/demangle.h
+RECOG_H = recog.h
EXPR_H = expr.h insn-codes.h
-REGS_H = regs.h varray.h machmode.h machmode.def gansidecl.h
+REGS_H = regs.h varray.h machmode.h machmode.def
#
# Language makefile fragments.
@@ -766,7 +806,7 @@ Makefile: $(srcdir)/Makefile.in config.status $(srcdir)/version.c \
$(SHELL) $(srcdir)/configure.frag $(srcdir) "$(SUBDIRS)" \
"$(xmake_file)" "$(tmake_file)"
cp config.status config.run
- $(SHELL) config.run
+ LANGUAGES="$(CONFIG_LANGUAGES)" $(SHELL) config.run
rm -f config.run
$(srcdir)/configure: $(srcdir)/configure.in
@@ -788,7 +828,7 @@ $(srcdir)/cstamp-h.in: $(srcdir)/configure.in $(srcdir)/acconfig.h
echo timestamp > $(srcdir)/cstamp-h.in
auto-host.h: cstamp-h ; @true
cstamp-h: config.in config.status
- CONFIG_HEADERS=auto-host.h:config.in $(SHELL) config.status
+ CONFIG_HEADERS=auto-host.h:config.in LANGUAGES="$(CONFIG_LANGUAGES)" $(SHELL) config.status
# Really, really stupid make features, such as SUN's KEEP_STATE, may force
# a target to build even if it is up-to-date. So we must verify that
@@ -798,24 +838,25 @@ config.status: configure version.c
echo You must configure gcc. Look at the INSTALL file for details.; \
false; \
else \
- $(SHELL) config.status --recheck; \
+ LANGUAGES="$(CONFIG_LANGUAGES)" $(SHELL) config.status --recheck; \
fi
-all.internal: start.encap rest.encap
+all.internal: start.encap rest.encap doc
# This is what to compile if making a cross-compiler.
# Note that we can compile enquire using the cross-compiler just built,
# although we can't run it on this machine.
all.cross: native gcc-cross specs stmp-headers $(STMP_FIXPROTO) $(LIBGCC) \
- $(LIBGCC1_TEST) $(EXTRA_PARTS) lang.all.cross
+ $(LIBGCC1_TEST) $(EXTRA_PARTS) lang.all.cross doc
# This is what to compile if making gcc with a cross-compiler.
-all.build: native xgcc$(exeext) $(EXTRA_PARTS) lang.all.build
+all.build: native xgcc$(exeext) xcpp$(exeext) $(EXTRA_PARTS) lang.all.build
# This is what must be made before installing GCC and converting libraries.
-start.encap: native xgcc$(exeext) specs $(LIBGCC1) xlimits.h lang.start.encap
+start.encap: native xgcc$(exeext) xcpp$(exeext) specs $(LIBGCC1) \
+ xlimits.h lang.start.encap
# These can't be made until after GCC can run.
rest.encap: stmp-headers $(STMP_FIXPROTO) $(LIBGCC) $(EXTRA_PARTS) lang.rest.encap
# This is what is made with the host's compiler
# whether making a cross compiler or not.
-native: config.status auto-host.h cpp$(exeext) $(LANGUAGES) \
+native: config.status auto-host.h cpp$(exeext) intl.all $(LANGUAGES) \
$(EXTRA_PASSES) $(EXTRA_PROGRAMS) $(USE_COLLECT2)
# Define the names for selecting languages in LANGUAGES.
@@ -827,7 +868,7 @@ PROTO: proto
# On the target machine, finish building a cross compiler.
# This does the things that can't be done on the host machine.
-rest.cross: $(LIBGCC) gfloat.h specs
+rest.cross: $(LIBGCC) specs
# Verify that it works to compile and link libgcc1-test.
# If it does, then there are sufficient replacements for libgcc1.a.
@@ -850,10 +891,20 @@ stamp-objlist: $(OBJS)
# We call this executable `xgcc' rather than `gcc'
# to avoid confusion if the current directory is in the path
# and CC is `gcc'. It is renamed to `gcc' when it is installed.
-xgcc$(exeext): gcc.o version.o choose-temp.o pexecute.o prefix.o version.o \
- mkstemp.o $(LIBDEPS) $(EXTRA_GCC_OBJS)
- $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ gcc.o prefix.o version.o \
- choose-temp.o pexecute.o mkstemp.o $(EXTRA_GCC_OBJS) $(LIBS)
+xgcc$(exeext): gcc.o gccspec.o version.o intl.o prefix.o \
+ version.o $(LIBDEPS) $(EXTRA_GCC_OBJS)
+ $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ gcc.o gccspec.o intl.o \
+ prefix.o version.o $(EXTRA_GCC_OBJS) $(LIBS)
+
+# We call this executable `xcpp' rather than `cpp'
+# since the real preprocessor is named `cpp'. It too is renamed
+# when it is installed.
+# The only difference from xgcc is that it's linked with cppspec.o
+# instead of gccspec.o.
+xcpp$(exeext): gcc.o cppspec.o version.o intl.o prefix.o \
+ version.o $(LIBDEPS) $(EXTRA_GCC_OBJS)
+ $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ gcc.o cppspec.o intl.o \
+ prefix.o version.o $(EXTRA_GCC_OBJS) $(LIBS)
# Dump a specs file to make -B./ read these specs over installed ones.
specs: xgcc$(exeext)
@@ -866,13 +917,8 @@ specs: xgcc$(exeext)
gcc-cross: xgcc$(exeext)
cp xgcc$(exeext) gcc-cross$(exeext)
-cc1$(exeext): $(P) $(C_OBJS) $(OBJS) $(LIBDEPS)
- $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ $(C_OBJS) $(OBJS) $(GGC_LIB) $(LIBS)
-
-# Copy float.h from its source.
-gfloat.h: $(FLOAT_H)
- -rm -f gfloat.h
- cp $(FLOAT_H) gfloat.h
+cc1$(exeext): $(P) $(OBJS) $(C_OBJS) $(LIBDEPS)
+ $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ $(OBJS) $(C_OBJS) $(GGC_LIB) $(LIBS)
# Build the version of limits.h that we will install.
xlimits.h: glimits.h limitx.h limity.h
@@ -899,7 +945,7 @@ libgcc1.conv: libgcc1.a
libgcc1.null: $(GCC_PASSES)
echo "void __foo () {}" > dummy.c
$(GCC_FOR_TARGET) $(GCC_CFLAGS) -c dummy.c
- $(OLDAR) $(OLDAR_FLAGS) libgcc1.null dummy$(objext)
+ $(AR_FOR_TARGET) $(AR_FLAGS_FOR_TARGET) libgcc1.null dummy$(objext)
rm -f dummy$(objext) dummy.c
# This is $(LIBGCC1) for a cross-compiler.
@@ -959,7 +1005,9 @@ libgcc1.a: libgcc1.c $(CONFIG_H) $(LIB1FUNCS_EXTRA) config.status
else true; \
fi; \
done
- -if $(RANLIB_TEST) ; then $(RANLIB) tmplibgcc1.a; else true; fi
+ -if $(RANLIB_TEST_FOR_TARGET) ; then \
+ $(RANLIB_FOR_TARGET) tmplibgcc1.a; \
+ else true; fi
mv tmplibgcc1.a libgcc1.a
# Build libgcc1.a from assembler source. LIB1ASMFUNCS is the list of
@@ -982,7 +1030,7 @@ libgcc1-asm.a: libgcc2.ready config.status $(srcdir)/config/$(LIB1ASMSRC)
$(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) $(INCLUDES) -c -DL$${name} libgcc1.S; \
if [ $$? -eq 0 ] ; then true; else exit 1; fi; \
mv libgcc1$(objext) $${name}$(objext); \
- $(AR) $(AR_FLAGS) tmplibgcc1.a $${name}$(objext); \
+ $(AR_FOR_TARGET) $(AR_FLAGS_FOR_TARGET) tmplibgcc1.a $${name}$(objext); \
rm -f $${name}$(objext); \
done
-rm -f libgcc1.S
@@ -1017,7 +1065,7 @@ libgcc2.ready: $(GCC_PASSES) $(LIBGCC2_DEPS) stmp-int-hdrs $(STMP_FIXPROTO)
LIB2ADD = $(srcdir)/frame.c $(LIB2FUNCS_EXTRA) $(LANG_LIB2FUNCS)
libgcc2.a: libgcc2.c libgcc2.ready $(CONFIG_H) $(FPBIT) $(DPBIT) $(LIB2ADD) \
- machmode.h longlong.h frame.h gansidecl.h gbl-ctors.h config.status
+ machmode.h longlong.h frame.h gbl-ctors.h config.status
# Actually build it in tmplibgcc2.a, then rename at end,
# so that libgcc2.a itself remains nonexistent if compilation is aborted.
-rm -f tmplibgcc2.a
@@ -1033,7 +1081,7 @@ libgcc2.a: libgcc2.c libgcc2.ready $(CONFIG_H) $(FPBIT) $(DPBIT) $(LIB2ADD) \
$(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) $(INCLUDES) -c -DL$${name} \
$(srcdir)/libgcc2.c -o $${name}$(objext); \
if [ $$? -eq 0 ] ; then true; else exit 1; fi; \
- $(AR) $(AR_FLAGS) tmplibgcc2.a $${name}$(objext); \
+ $(AR_FOR_TARGET) $(AR_FLAGS_FOR_TARGET) tmplibgcc2.a $${name}$(objext); \
rm -f $${name}$(objext); \
done
for name in $(LIB2FUNCS_EH); \
@@ -1042,7 +1090,7 @@ libgcc2.a: libgcc2.c libgcc2.ready $(CONFIG_H) $(FPBIT) $(DPBIT) $(LIB2ADD) \
$(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) -fexceptions $(INCLUDES) -c \
-DL$${name} $(srcdir)/libgcc2.c -o $${name}$(objext); \
if [ $$? -eq 0 ] ; then true; else exit 1; fi; \
- $(AR) $(AR_FLAGS) tmplibgcc2.a $${name}$(objext); \
+ $(AR_FOR_TARGET) $(AR_FLAGS_FOR_TARGET) tmplibgcc2.a $${name}$(objext); \
rm -f $${name}$(objext); \
done
if [ x$(FPBIT) != x ]; then \
@@ -1052,7 +1100,7 @@ libgcc2.a: libgcc2.c libgcc2.ready $(CONFIG_H) $(FPBIT) $(DPBIT) $(LIB2ADD) \
$(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) $(INCLUDES) -c -DL$${name} \
-DFINE_GRAINED_LIBRARIES $(FPBIT) -o $${name}$(objext); \
if [ $$? -eq 0 ] ; then true; else exit 1; fi; \
- $(AR) $(AR_FLAGS) tmplibgcc2.a $${name}$(objext); \
+ $(AR_FOR_TARGET) $(AR_FLAGS_FOR_TARGET) tmplibgcc2.a $${name}$(objext); \
rm -f $${name}$(objext); \
done; \
else true; fi;
@@ -1063,7 +1111,7 @@ libgcc2.a: libgcc2.c libgcc2.ready $(CONFIG_H) $(FPBIT) $(DPBIT) $(LIB2ADD) \
$(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) $(INCLUDES) -c -DL$${name} \
-DFINE_GRAINED_LIBRARIES $(DPBIT) -o $${name}$(objext); \
if [ $$? -eq 0 ] ; then true; else exit 1; fi; \
- $(AR) $(AR_FLAGS) tmplibgcc2.a $${name}$(objext); \
+ $(AR_FOR_TARGET) $(AR_FLAGS_FOR_TARGET) tmplibgcc2.a $${name}$(objext); \
rm -f $${name}$(objext); \
done; \
else true; fi;
@@ -1079,13 +1127,14 @@ libgcc2.a: libgcc2.c libgcc2.ready $(CONFIG_H) $(FPBIT) $(DPBIT) $(LIB2ADD) \
if [ $${name}.txt = $${file} ]; then \
for f in .. `cat $${file}`; do if [ x$${f} != x.. ]; then \
$(MAKE) GCC_FOR_TARGET="$(GCC_FOR_TARGET)" \
- AR="$(AR)" AR_FLAGS="$(AR_FLAGS)" CC="$(CC)" \
+ AR_FOR_TARGET="$(AR_FOR_TARGET)" \
+ AR_FLAGS_FOR_TARGET="$(AR_FLAGS_FOR_TARGET)" CC="$(CC)" \
CFLAGS="$(CFLAGS)" HOST_PREFIX="$(HOST_PREFIX)" \
HOST_PREFIX_1="$(HOST_PREFIX_1)" \
LANGUAGES="$(LANGUAGES)" \
LIBGCC2_CFLAGS="$(LIBGCC2_CFLAGS)" $${f}; \
if [ $$? -eq 0 ] ; then true; else exit 1; fi; \
- $(AR) $(AR_FLAGS) tmplibgcc2.a $${f}; \
+ $(AR_FOR_TARGET) $(AR_FLAGS_FOR_TARGET) tmplibgcc2.a $${f}; \
rm -f $${f}; \
else true; \
fi; done; \
@@ -1096,7 +1145,7 @@ libgcc2.a: libgcc2.c libgcc2.ready $(CONFIG_H) $(FPBIT) $(DPBIT) $(LIB2ADD) \
else true; fi; \
$(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) $(INCLUDES) -c $${file}; \
if [ $$? -eq 0 ] ; then true; else exit 1; fi; \
- $(AR) $(AR_FLAGS) tmplibgcc2.a $${oname}$(objext); \
+ $(AR_FOR_TARGET) $(AR_FLAGS_FOR_TARGET) tmplibgcc2.a $${oname}$(objext); \
rm -f $${name}.s $${oname}$(objext); \
fi; \
done
@@ -1104,7 +1153,9 @@ libgcc2.a: libgcc2.c libgcc2.ready $(CONFIG_H) $(FPBIT) $(DPBIT) $(LIB2ADD) \
# These lines were deleted from above the mv command
# because ranlibing libgcc.a itself should suffice.
# -if [ x${HPUX_GAS} = x ] ; then \
-# if $(RANLIB_TEST) ; then $(RANLIB) tmplibgcc2.a; else true; fi; \
+# if $(RANLIB_TEST_FOR_TARGET) ; then \
+# $(RANLIB_FOR_TARGET) tmplibgcc2.a;
+# else true; fi; \
# else true; fi
# Combine the various libraries into a single library, libgcc.a.
@@ -1112,7 +1163,7 @@ libgcc.a: $(LIBGCC1) $(LIBGCC2)
-rm -rf tmplibgcc.a libgcc.a tmpcopy
mkdir tmpcopy
-if [ x$(LIBGCC1) != x ]; \
- then (cd tmpcopy; $(AR) x ../$(LIBGCC1)); \
+ then (cd tmpcopy; $(AR_FOR_TARGET) x ../$(LIBGCC1)); \
else true; \
fi
# Some versions of ar (specifically the one in RISC/os 5.x), create an
@@ -1120,10 +1171,12 @@ libgcc.a: $(LIBGCC1) $(LIBGCC2)
# the second ar command tries to overwrite this file. To avoid the error
# message from ar, we make sure all files are writable.
-(cd tmpcopy; chmod +w * > /dev/null 2>&1)
- (cd tmpcopy; $(AR) x ../$(LIBGCC2))
- (cd tmpcopy; $(AR) $(AR_FLAGS) ../tmplibgcc.a *$(objext))
+ (cd tmpcopy; $(AR_FOR_TARGET) x ../$(LIBGCC2))
+ (cd tmpcopy; $(AR_FOR_TARGET) $(AR_FLAGS_FOR_TARGET) ../tmplibgcc.a *$(objext))
rm -rf tmpcopy
- -if $(RANLIB_TEST) ; then $(RANLIB) tmplibgcc.a; else true; fi
+ -if $(RANLIB_TEST_FOR_TARGET) ; then \
+ $(RANLIB_FOR_TARGET) tmplibgcc.a; \
+ else true; fi
# Actually build it in tmplibgcc.a, then rename at end,
# so that libgcc.a itself remains nonexistent if compilation is aborted.
mv tmplibgcc.a libgcc.a
@@ -1144,14 +1197,17 @@ s-mlib: $(srcdir)/genmultilib Makefile
# Build multiple copies of libgcc.a, one for each target switch.
stmp-multilib: $(LIBGCC1) libgcc2.c libgcc2.ready $(CONFIG_H) \
- frame.h gansidecl.h \
+ frame.h \
$(LIB2ADD) machmode.h longlong.h gbl-ctors.h config.status
for i in `$(GCC_FOR_TARGET) --print-multi-lib`; do \
dir=`echo $$i | sed -e 's/;.*$$//'`; \
flags=`echo $$i | sed -e 's/^[^;]*;//' -e 's/@/ -/g'`; \
$(MAKE) GCC_FOR_TARGET="$(GCC_FOR_TARGET)" \
- AR="$(AR)" AR_FLAGS="$(AR_FLAGS)" CC="$(CC)" CFLAGS="$(CFLAGS)" \
- RANLIB="$(RANLIB)" RANLIB_TEST="$(RANLIB_TEST)" \
+ AR_FOR_TARGET="$(AR_FOR_TARGET)" \
+ AR_FLAGS_FOR_TARGET="$(AR_FLAGS_FOR_TARGET)" \
+ CC="$(CC)" CFLAGS="$(CFLAGS)" \
+ RANLIB_FOR_TARGET="$(RANLIB_FOR_TARGET)" \
+ RANLIB_TEST_FOR_TARGET="$(RANLIB_TEST_FOR_TARGET)" \
LANGUAGES="$(LANGUAGES)" \
HOST_PREFIX="$(HOST_PREFIX)" HOST_PREFIX_1="$(HOST_PREFIX_1)" \
LIBGCC2_CFLAGS="$(LIBGCC2_CFLAGS) $${flags}" \
@@ -1171,7 +1227,9 @@ stmp-multilib-sub:
else true; \
fi
$(MAKE) GCC_FOR_TARGET="$(GCC_FOR_TARGET)" \
- AR="$(AR)" AR_FLAGS="$(AR_FLAGS)" CC="$(CC)" CFLAGS="$(CFLAGS)" \
+ AR_FOR_TARGET="$(AR_FOR_TARGET)" \
+ AR_FLAGS_FOR_TARGET="$(AR_FLAGS_FOR_TARGET)" \
+ CC="$(CC)" CFLAGS="$(CFLAGS)" \
HOST_PREFIX="$(HOST_PREFIX)" HOST_PREFIX_1="$(HOST_PREFIX_1)" \
LANGUAGES="$(LANGUAGES)" \
LIBGCC2_CFLAGS="$(LIBGCC2_CFLAGS)" $(LIBGCC2)
@@ -1183,7 +1241,9 @@ stmp-multilib-sub:
then true; \
else \
$(MAKE) GCC_FOR_TARGET="$(GCC_FOR_TARGET)" \
- AR="$(AR)" AR_FLAGS="$(AR_FLAGS)" CC="$(CC)" CFLAGS="$(CFLAGS)" \
+ AR_FOR_TARGET="$(AR_FOR_TARGET)" \
+ AR_FLAGS_FOR_TARGET="$(AR_FLAGS_FOR_TARGET)" \
+ CC="$(CC)" CFLAGS="$(CFLAGS)" \
HOST_PREFIX="$(HOST_PREFIX)" HOST_PREFIX_1="$(HOST_PREFIX_1)" \
LANGUAGES="$(LANGUAGES)" \
LIBGCC2_CFLAGS="$(LIBGCC2_CFLAGS)" $(LIBGCC1); \
@@ -1191,18 +1251,22 @@ stmp-multilib-sub:
rm -rf tmplibgcc.a tmpcopy
mkdir tmpcopy
if [ x$(LIBGCC1) != x ]; \
- then (cd tmpcopy; $(AR) x ../$(LIBGCC1)); \
+ then (cd tmpcopy; $(AR_FOR_TARGET) x ../$(LIBGCC1)); \
else true; \
fi
- (cd tmpcopy; $(AR) x ../$(LIBGCC2))
- (cd tmpcopy; $(AR) $(AR_FLAGS) ../tmplibgcc.a *$(objext))
+ (cd tmpcopy; $(AR_FOR_TARGET) x ../$(LIBGCC2))
+ (cd tmpcopy; $(AR_FOR_TARGET) $(AR_FLAGS_FOR_TARGET) ../tmplibgcc.a *$(objext))
rm -rf libgcc2.a tmpcopy
- if $(RANLIB_TEST) ; then $(RANLIB) tmplibgcc.a; else true; fi
+ if $(RANLIB_TEST_FOR_TARGET) ; then \
+ $(RANLIB_FOR_TARGET) tmplibgcc.a; \
+ else true; fi
if [ -d $(dir) ]; then true; else mkdir $(dir); fi
mv tmplibgcc.a $(dir)/libgcc.a
for f in .. $(EXTRA_MULTILIB_PARTS); do if [ x$${f} != x.. ]; then \
$(MAKE) GCC_FOR_TARGET="$(GCC_FOR_TARGET)" \
- AR="$(AR)" AR_FLAGS="$(AR_FLAGS)" CC="$(CC)" CFLAGS="$(CFLAGS)" \
+ AR_FOR_TARGET="$(AR_FOR_TARGET)" \
+ AR_FLAGS_FOR_TARGET="$(AR_FLAGS_FOR_TARGET)" \
+ CC="$(CC)" CFLAGS="$(CFLAGS)" \
HOST_PREFIX="$(HOST_PREFIX)" HOST_PREFIX_1="$(HOST_PREFIX_1)" \
LANGUAGES="$(LANGUAGES)" \
MULTILIB_CFLAGS="$(MULTILIB_CFLAGS)" T="t" t$${f}; \
@@ -1279,11 +1343,11 @@ $(srcdir)/c-gperf.h: c-parse.gperf
c-decl.o : c-decl.c $(CONFIG_H) system.h $(TREE_H) c-tree.h c-lex.h flags.h \
function.h output.h toplev.h
c-typeck.o : c-typeck.c $(CONFIG_H) system.h $(TREE_H) c-tree.h flags.h \
- output.h $(EXPR_H) $(RTL_H) toplev.h
+ intl.h output.h $(EXPR_H) $(RTL_H) toplev.h
c-lang.o : c-lang.c $(CONFIG_H) system.h $(TREE_H) c-tree.h c-lex.h toplev.h \
function.h output.h
c-lex.o : c-lex.c $(CONFIG_H) system.h $(TREE_H) $(RTL_H) c-lex.h c-tree.h \
- $(srcdir)/c-parse.h input.h flags.h $(srcdir)/c-gperf.h c-pragma.h \
+ $(srcdir)/c-parse.h input.h intl.h flags.h $(srcdir)/c-gperf.h c-pragma.h \
toplev.h output.h mbchar.h
c-aux-info.o : c-aux-info.c $(CONFIG_H) system.h $(TREE_H) c-tree.h flags.h
c-convert.o : c-convert.c $(CONFIG_H) system.h $(TREE_H) flags.h toplev.h
@@ -1291,39 +1355,37 @@ c-pragma.o: c-pragma.c $(CONFIG_H) system.h $(RTL_H) $(TREE_H) function.h \
defaults.h c-pragma.h toplev.h
c-iterate.o: c-iterate.c $(CONFIG_H) system.h $(TREE_H) $(RTL_H) c-tree.h \
flags.h toplev.h $(EXPR_H)
-mbchar.o: mbchar.c $(CONFIG_H) system.h gansidecl.h mbchar.h
+mbchar.o: mbchar.c $(CONFIG_H) system.h mbchar.h
+graph.o: graph.c $(CONFIG_H) system.h toplev.h flags.h output.h $(RTL_H) \
+ hard-reg-set.h $(BASIC_BLOCK_H)
+sbitmap.o: sbitmap.c $(CONFIG_H) system.h $(RTL_H) flags.h $(BASIC_BLOCK_H)
-collect2$(exeext): collect2.o tlink.o hash.o cplus-dem.o underscore.o \
- version.o choose-temp.o mkstemp.o $(LIBDEPS)
+COLLECT2_OBJS = collect2.o tlink.o hash.o intl.o underscore.o version.o
+collect2$(exeext): $(COLLECT2_OBJS) $(LIBDEPS)
# Don't try modifying collect2 (aka ld) in place--it might be linking this.
-rm -f collect2$(exeext)
- $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ collect2.o tlink.o hash.o \
- cplus-dem.o underscore.o version.o choose-temp.o mkstemp.o $(LIBS)
+ $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ $(COLLECT2_OBJS) $(LIBS)
-collect2.o : collect2.c $(CONFIG_H) system.h gansidecl.h gstab.h \
- $(srcdir)/../include/obstack.h $(DEMANGLE_H)
+collect2.o : collect2.c $(CONFIG_H) system.h gstab.h intl.h \
+ $(srcdir)/../include/obstack.h $(DEMANGLE_H) collect2.h
$(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
-DTARGET_MACHINE=\"$(target_alias)\" $(MAYBE_USE_COLLECT2) \
-c `echo $(srcdir)/collect2.c | sed 's,^\./,,'`
-tlink.o: tlink.c $(DEMANGLE_H) hash.h $(CONFIG_H) system.h toplev.h
+tlink.o: tlink.c $(DEMANGLE_H) hash.h $(CONFIG_H) system.h toplev.h collect2.h
hash.o: hash.c hash.h system.h toplev.h
-cplus-dem.o: $(srcdir)/../libiberty/cplus-dem.c $(DEMANGLE_H)
- rm -f cplus-dem.c
- $(LN_S) $(srcdir)/../libiberty/cplus-dem.c cplus-dem.c
- $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) cplus-dem.c
-
-pexecute.o: $(srcdir)/../libiberty/pexecute.c $(CONFIG_H) system.h gansidecl.h
- rm -f pexecute.c
- $(LN_S) $(srcdir)/../libiberty/pexecute.c pexecute.c
- $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) pexecute.c
-
-vfprintf.o: $(srcdir)/../libiberty/vfprintf.c $(CONFIG_H) system.h gansidecl.h
+vfprintf.o: $(srcdir)/../libiberty/vfprintf.c $(CONFIG_H) system.h
rm -f vfprintf.c
$(LN_S) $(srcdir)/../libiberty/vfprintf.c vfprintf.c
$(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) vfprintf.c
+splay-tree.o: $(srcdir)/../libiberty/splay-tree.c \
+ $(srcdir)/../include/splay-tree.h $(srcdir)/../include/libiberty.h
+ rm -f splay-tree.c
+ $(LN_S) $(srcdir)/../libiberty/splay-tree.c splay-tree.c
+ $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) splay-tree.c
+
underscore.c: s-under ; @true
s-under: $(GCC_PASSES)
@@ -1342,7 +1404,7 @@ s-under: $(GCC_PASSES)
# A file used by all variants of C.
c-common.o : c-common.c $(CONFIG_H) system.h $(TREE_H) c-tree.h c-lex.h \
- flags.h toplev.h output.h
+ flags.h toplev.h output.h c-pragma.h $(RTL_H)
# Language-independent files.
@@ -1352,24 +1414,28 @@ DRIVER_DEFINES = \
-DDEFAULT_TARGET_VERSION=\"$(version)\" \
-DDEFAULT_TARGET_MACHINE=\"$(target_alias)\" \
-DTOOLDIR_BASE_PREFIX=\"$(exec_prefix)/\"
-gcc.o: gcc.c $(CONFIG_H) system.h gansidecl.h multilib.h Makefile \
- $(lang_specs_files)
+gcc.o: gcc.c $(CONFIG_H) system.h intl.h multilib.h \
+ Makefile $(lang_specs_files) prefix.h
$(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
$(DRIVER_DEFINES) \
-c `echo $(srcdir)/gcc.c | sed 's,^\./,,'`
+gccspec.o: gccspec.c $(CONFIG_H) system.h
+cppspec.o: cppspec.c $(CONFIG_H) system.h
+
tree-check.h: s-check ; @true
s-check : gencheck $(srcdir)/move-if-change
./gencheck > tmp-check.h
$(srcdir)/move-if-change tmp-check.h tree-check.h
touch s-check
-gencheck : gencheck.o tree.def $(lang_tree_files) $(HOST_LIBDEPS)
+gencheck : gencheck.o $(lang_tree_files) $(HOST_LIBDEPS)
$(HOST_CC) $(HOST_CFLAGS) $(HOST_LDFLAGS) -o $@ \
gencheck.o $(HOST_LIBS)
-gencheck.o : gencheck.c hconfig.h system.h
- $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) $(srcdir)/gencheck.c
+gencheck.o : gencheck.c tree.def $(CONFIG_H) hconfig.h system.h
+ $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) \
+ $(srcdir)/gencheck.c
dumpvers: dumpvers.c
@@ -1381,18 +1447,7 @@ obstack.o: $(srcdir)/../libiberty/obstack.c $(CONFIG_H)
$(LN_S) $(srcdir)/../libiberty/obstack.c obstack.c
$(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) obstack.c
-choose-temp.o: $(srcdir)/../libiberty/choose-temp.c $(CONFIG_H) gansidecl.h \
- system.h
- rm -f choose-temp.c
- $(LN_S) $(srcdir)/../libiberty/choose-temp.c choose-temp.c
- $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) choose-temp.c
-
-mkstemp.o: $(srcdir)/../libiberty/mkstemp.c $(CONFIG_H) gansidecl.h system.h
- rm -f mkstemp.c
- $(LN_S) $(srcdir)/../libiberty/mkstemp.c mkstemp.c
- $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) mkstemp.c
-
-prefix.o: prefix.c $(CONFIG_H) system.h gansidecl.h Makefile
+prefix.o: prefix.c $(CONFIG_H) system.h Makefile prefix.h
$(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
-DPREFIX=\"$(prefix)\" \
-c `echo $(srcdir)/prefix.c | sed 's,^\./,,'`
@@ -1407,8 +1462,8 @@ fold-const.o : fold-const.c $(CONFIG_H) system.h $(TREE_H) flags.h toplev.h \
$(RTL_H)
toplev.o : toplev.c $(CONFIG_H) system.h $(TREE_H) $(RTL_H) function.h \
flags.h input.h insn-attr.h xcoffout.h defaults.h output.h \
- insn-codes.h insn-config.h $(RECOG_H) Makefile toplev.h dwarfout.h \
- dwarf2out.h sdbout.h dbxout.h $(EXPR_H) \
+ insn-codes.h insn-config.h intl.h $(RECOG_H) Makefile toplev.h dwarfout.h \
+ dwarf2out.h sdbout.h dbxout.h $(EXPR_H) $(BASIC_BLOCK_H) \
$(lang_options_files)
$(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $(MAYBE_USE_COLLECT2) \
-DTARGET_NAME=\"$(target_alias)\" \
@@ -1416,7 +1471,7 @@ toplev.o : toplev.c $(CONFIG_H) system.h $(TREE_H) $(RTL_H) function.h \
rtl.o : rtl.c $(CONFIG_H) system.h $(RTL_H) bitmap.h
-print-rtl.o : print-rtl.c $(CONFIG_H) system.h $(RTL_H) bitmap.h
+print-rtl.o : print-rtl.c $(CONFIG_H) system.h $(RTL_H) bitmap.h basic-block.h
rtlanal.o : rtlanal.c $(CONFIG_H) system.h $(RTL_H)
varasm.o : varasm.c $(CONFIG_H) system.h $(TREE_H) $(RTL_H) flags.h \
@@ -1424,10 +1479,10 @@ varasm.o : varasm.c $(CONFIG_H) system.h $(TREE_H) $(RTL_H) flags.h \
xcoffout.h output.h c-pragma.h toplev.h dbxout.h sdbout.h
function.o : function.c $(CONFIG_H) system.h $(RTL_H) $(TREE_H) flags.h \
function.h insn-flags.h insn-codes.h $(EXPR_H) $(REGS_H) hard-reg-set.h \
- insn-config.h $(RECOG_H) output.h toplev.h except.h
+ insn-config.h $(RECOG_H) output.h toplev.h except.h hash.h
stmt.o : stmt.c $(CONFIG_H) system.h $(RTL_H) $(TREE_H) flags.h function.h \
insn-flags.h insn-config.h insn-codes.h hard-reg-set.h $(EXPR_H) except.h \
- loop.h $(RECOG_H) toplev.h output.h
+ loop.h $(RECOG_H) toplev.h output.h varray.h
except.o : except.c $(CONFIG_H) system.h $(RTL_H) $(TREE_H) flags.h \
function.h insn-flags.h $(EXPR_H) $(REGS_H) hard-reg-set.h \
insn-config.h $(RECOG_H) output.h except.h toplev.h
@@ -1466,28 +1521,32 @@ getpwd.o : getpwd.c $(CONFIG_H) system.h
integrate.o : integrate.c $(CONFIG_H) system.h $(RTL_H) $(TREE_H) flags.h \
integrate.h insn-flags.h insn-config.h $(EXPR_H) real.h $(REGS_H) \
- function.h output.h $(RECOG_H) except.h toplev.h
+ intl.h function.h output.h $(RECOG_H) except.h toplev.h
jump.o : jump.c $(CONFIG_H) system.h $(RTL_H) flags.h hard-reg-set.h $(REGS_H) \
insn-config.h insn-flags.h $(RECOG_H) $(EXPR_H) real.h except.h \
- function.h toplev.h
+ toplev.h insn-attr.h
stupid.o : stupid.c $(CONFIG_H) system.h $(RTL_H) $(REGS_H) hard-reg-set.h \
$(BASIC_BLOCK_H) insn-config.h reload.h flags.h toplev.h function.h
cse.o : cse.c $(CONFIG_H) system.h $(RTL_H) $(REGS_H) hard-reg-set.h flags.h \
real.h insn-config.h $(RECOG_H) $(EXPR_H) toplev.h output.h function.h
gcse.o : gcse.c $(CONFIG_H) system.h $(RTL_H) $(REGS_H) hard-reg-set.h flags.h \
- real.h insn-config.h $(RECOG_H) $(EXPR_H) $(BASIC_BLOCK_H) output.h \
- function.h
+ real.h insn-config.h $(RECOG_H) $(EXPR_H) $(BASIC_BLOCK_H) output.h
+resource.o : resource.c $(CONFIG_H) $(RTL_H) hard-reg-set.h system.h \
+ $(BASIC_BLOCK_H) $(REGS_H) flags.h output.h resource.h
+lcm.o : lcm.c $(CONFIG_H) system.h $(RTL_H) $(REGS_H) hard-reg-set.h flags.h \
+ real.h insn-config.h $(RECOG_H) $(EXPR_H) $(BASIC_BLOCK_H)
profile.o : profile.c $(CONFIG_H) system.h $(RTL_H) flags.h insn-flags.h \
gcov-io.h $(TREE_H) output.h $(REGS_H) toplev.h insn-config.h function.h
loop.o : loop.c $(CONFIG_H) system.h $(RTL_H) flags.h loop.h insn-config.h \
insn-flags.h $(REGS_H) hard-reg-set.h $(RECOG_H) $(EXPR_H) real.h \
- function.h toplev.h
-unroll.o : unroll.c $(CONFIG_H) system.h $(RTL_H) insn-config.h function.h \
- integrate.h $(REGS_H) $(RECOG_H) flags.h $(EXPR_H) loop.h toplev.h
+ toplev.h varray.h
+unroll.o : unroll.c $(CONFIG_H) system.h $(RTL_H) insn-config.h \
+ integrate.h $(REGS_H) $(RECOG_H) flags.h $(EXPR_H) loop.h toplev.h varray.h
flow.o : flow.c $(CONFIG_H) system.h $(RTL_H) flags.h insn-config.h \
- $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h output.h toplev.h function.h
+ $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h output.h toplev.h recog.h \
+ insn-flags.h
combine.o : combine.c $(CONFIG_H) system.h $(RTL_H) flags.h \
insn-config.h insn-flags.h insn-codes.h insn-attr.h $(REGS_H) $(EXPR_H) \
$(BASIC_BLOCK_H) $(RECOG_H) real.h hard-reg-set.h toplev.h function.h
@@ -1522,19 +1581,18 @@ regmove.o : regmove.c $(CONFIG_H) system.h $(RTL_H) insn-config.h \
$(RECOG_H) output.h reload.h $(REGS_H) hard-reg-set.h flags.h \
$(EXPR_H) insn-flags.h $(BASIC_BLOCK_H) toplev.h function.h
$(SCHED_PREFIX)sched.o : $(SCHED_PREFIX)sched.c $(CONFIG_H) system.h $(RTL_H) \
- $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h flags.h insn-config.h insn-attr.h \
- function.h toplev.h
-final.o : final.c $(CONFIG_H) system.h $(RTL_H) $(TREE_H) flags.h $(REGS_H) \
- $(RECOG_H) conditions.h insn-config.h insn-attr.h except.h real.h output.h \
- hard-reg-set.h insn-flags.h insn-codes.h gstab.h xcoffout.h defaults.h \
- toplev.h reload.h dwarfout.h dwarf2out.h sdbout.h dbxout.h function.h
+ $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h flags.h insn-config.h \
+ insn-attr.h toplev.h recog.h
+final.o : final.c $(CONFIG_H) system.h $(RTL_H) $(TREE_H) flags.h intl.h \
+ $(REGS_H) $(RECOG_H) conditions.h insn-config.h insn-attr.h except.h real.h \
+ output.h hard-reg-set.h insn-flags.h insn-codes.h gstab.h xcoffout.h \
+ defaults.h toplev.h reload.h dwarfout.h dwarf2out.h sdbout.h dbxout.h
recog.o : recog.c $(CONFIG_H) system.h $(RTL_H) \
$(REGS_H) $(RECOG_H) hard-reg-set.h flags.h insn-config.h insn-attr.h \
- insn-flags.h insn-codes.h real.h
-reg-stack.o : reg-stack.c $(CONFIG_H) system.h $(RTL_H) $(TREE_H) \
- $(REGS_H) hard-reg-set.h flags.h insn-config.h insn-flags.h toplev.h \
- function.h
-dyn-string.o: dyn-string.c dyn-string.h $(CONFIG_H) system.h gansidecl.h
+ insn-flags.h insn-codes.h real.h toplev.h
+reg-stack.o : reg-stack.c $(CONFIG_H) system.h $(RTL_H) $(TREE_H) recog.h \
+ $(REGS_H) hard-reg-set.h flags.h insn-config.h insn-flags.h toplev.h
+dyn-string.o: dyn-string.c dyn-string.h $(CONFIG_H) system.h
$(out_object_file): $(out_file) $(CONFIG_H) $(TREE_H) \
$(RTL_H) $(REGS_H) hard-reg-set.h real.h insn-config.h conditions.h \
@@ -1610,7 +1668,7 @@ s-codes : $(md_file) gencodes $(srcdir)/move-if-change
touch s-codes
insn-emit.o : insn-emit.c $(CONFIG_H) $(RTL_H) $(EXPR_H) real.h output.h \
- insn-config.h insn-flags.h insn-codes.h system.h reload.h function.h
+ insn-config.h insn-flags.h insn-codes.h system.h reload.h recog.h
$(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) -c insn-emit.c
insn-emit.c: s-emit ; @true
@@ -1639,7 +1697,8 @@ s-opinit : $(md_file) genopinit $(srcdir)/move-if-change
$(srcdir)/move-if-change tmp-opinit.c insn-opinit.c
touch s-opinit
-insn-extract.o : insn-extract.c $(CONFIG_H) $(RTL_H) system.h toplev.h
+insn-extract.o : insn-extract.c $(CONFIG_H) $(RTL_H) system.h toplev.h \
+ insn-config.h recog.h
$(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) -c insn-extract.c
insn-extract.c: s-extract ; @true
@@ -1648,7 +1707,8 @@ s-extract : $(md_file) genextract $(srcdir)/move-if-change
$(srcdir)/move-if-change tmp-extract.c insn-extract.c
touch s-extract
-insn-peep.o : insn-peep.c $(CONFIG_H) $(RTL_H) $(REGS_H) output.h real.h system.h
+insn-peep.o : insn-peep.c $(CONFIG_H) $(RTL_H) $(REGS_H) output.h real.h \
+ system.h insn-config.h recog.h
$(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) -c insn-peep.c
insn-peep.c: s-peep ; @true
@@ -1811,7 +1871,8 @@ $(HOST_PREFIX_1)rtl.o: $(srcdir)/rtl.c $(CONFIG_H) system.h $(RTL_H) bitmap.h
sed -e 's/config[.]h/hconfig.h/' $(srcdir)/rtl.c > $(HOST_PREFIX)rtl.c
$(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) $(HOST_PREFIX)rtl.c
-$(HOST_PREFIX_1)print-rtl.o: $(srcdir)/print-rtl.c $(CONFIG_H) $(RTL_H)
+$(HOST_PREFIX_1)print-rtl.o: $(srcdir)/print-rtl.c $(CONFIG_H) $(RTL_H) \
+ bitmap.h basic-block.h
rm -f $(HOST_PREFIX)print-rtl.c
sed -e 's/config[.]h/hconfig.h/' $(srcdir)/print-rtl.c > $(HOST_PREFIX)print-rtl.c
$(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) $(HOST_PREFIX)print-rtl.c
@@ -1857,6 +1918,40 @@ $(HOST_PREFIX_1)malloc.o: malloc.c
$(HOST_PREFIX_1):
touch $(HOST_PREFIX_1)
+
+#
+# Remake internationalization support.
+
+intl.o: intl.c intl.h gansidecl.h Makefile
+ $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
+ -DLOCALEDIR=\"$(localedir)\" \
+ -c `echo $(srcdir)/intl.c | sed 's,^\./,,'`
+
+# This is needed to when doing a partial build after a `make clean'.
+# libintl.a does not depend on intl.all,
+# as that would force a lot of recompiling.
+$(top_builddir)/intl/libintl.a:
+ @echo "$(MAKE) intl.all"
+ @$(MAKE) $(FLAGS_TO_PASS) intl.all
+
+# Make sure all the headers are there for xgettext to scan.
+$(INTL_TARGETS): $(srcdir)/c-gperf.h \
+ $(srcdir)/c-parse.c $(srcdir)/c-parse.h $(srcdir)/cexp.c
+
+intl.all intl.install intl.uninstall intl.distdir \
+ intl.mostlyclean intl.clean intl.distclean intl.maintainer-clean:
+ @for d in $(INTL_SUBDIRS); do \
+ target=`expr $@ : 'intl.\(.*\)'` && \
+ echo "(cd $$d && $(MAKE) $$target)" && \
+ (cd $$d && AWK='$(AWK)' $(MAKE) $(SUBDIR_FLAGS_TO_PASS) $$target); \
+ done
+
+# intl.distdir doesn't copy the intl makefiles (since they aren't distributed),
+# but we need them for the `make extraclean' in distdir-finish.
+intl.distdir-fixup:
+ for d in $(INTL_SUBDIRS); do \
+ ln $$d/Makefile tmp/$$d || cp $$d/Makefile tmp/$$d || exit; \
+ done
#
# Remake cpp and protoize.
@@ -1864,99 +1959,95 @@ $(HOST_PREFIX_1):
cpp$(exeext): $(CCCP)$(exeext)
-rm -f cpp$(exeext)
$(LN) $(CCCP)$(exeext) cpp$(exeext)
-cccp$(exeext): cccp.o cexp.o version.o prefix.o mbchar.o @extra_cpp_objs@ $(LIBDEPS)
- $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ cccp.o cexp.o prefix.o mbchar.o \
- version.o @extra_cpp_objs@ $(LIBS)
-cexp.o: $(srcdir)/cexp.c $(CONFIG_H) system.h gansidecl.h
+CCCP_OBJS = cccp.o cexp.o intl.o prefix.o version.o @extra_cpp_objs@ mbchar.o
+cccp$(exeext): $(CCCP_OBJS) $(LIBDEPS)
+ $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ $(CCCP_OBJS) $(LIBS)
+cexp.o: $(srcdir)/cexp.c $(CONFIG_H) system.h
$(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) -c $(srcdir)/cexp.c
$(srcdir)/cexp.c: $(srcdir)/cexp.y
cd $(srcdir); $(BISON) -o cexp.c cexp.y
# We use $(libsubdir)/$(unlibsubdir) to match the
# -iprefix argument which gcc will pass if GCC_EXEC_PREFIX is used.
-cccp.o: cccp.c $(CONFIG_H) pcp.h version.c config.status system.h gansidecl.h \
- mbchar.h
+cccp.o: cccp.c $(CONFIG_H) intl.h pcp.h version.c config.status system.h \
+ mbchar.h prefix.h Makefile.in
$(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
-DGCC_INCLUDE_DIR=\"$(libsubdir)/include\" \
- -DGPLUSPLUS_INCLUDE_DIR=\"$(libsubdir)/$(unlibsubdir)/..`echo $(exec_prefix) | sed -e 's|^$(prefix)||' -e 's|/[^/]*|/..|g'`/include/g++\" \
- -DLOCAL_INCLUDE_DIR=\"$(libsubdir)/$(unlibsubdir)/..`echo $(exec_prefix) | sed -e 's|^$(prefix)||' -e 's|/[^/]*|/..|g'`/include\" \
- -DCROSS_INCLUDE_DIR=\"$(libsubdir)/$(unlibsubdir)/../$(target_alias)/sys-include\" \
- -DTOOL_INCLUDE_DIR=\"$(libsubdir)/$(unlibsubdir)/../$(target_alias)/include\" \
+ -DGPLUSPLUS_INCLUDE_DIR=\"$(gcc_gxx_include_dir)\" \
+ -DLOCAL_INCLUDE_DIR=\"$(includedir)\" \
+ -DCROSS_INCLUDE_DIR=\"$(gcc_tooldir)/sys-include\" \
+ -DTOOL_INCLUDE_DIR=\"$(gcc_tooldir)/include\" \
-c `echo $(srcdir)/cccp.c | sed 's,^\./,,'`
-cppmain$(exeext): cppmain.o cpplib.o cpphash.o cppalloc.o cpperror.o cppexp.o \
- prefix.o version.o mbchar.o @extra_cpp_objs@ $(LIBDEPS)
- $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ cppmain.o cpplib.o cpphash.o \
- mbchar.o @extra_cpp_objs@ \
- cppalloc.o cpperror.o cppexp.o prefix.o version.o $(LIBS)
-
-cppmain.o: cppmain.c $(CONFIG_H) cpplib.h system.h gansidecl.h
+LIBCPP_OBJS = cpplib.o cpphash.o cppalloc.o cpperror.o cppexp.o cppfiles.o \
+ cppinit.o cppulp.o prefix.o version.o mbchar.o @extra_cpp_objs@
-cpplib.o: cpplib.c $(CONFIG_H) cpplib.h cpphash.h config.status system.h \
- gansidecl.h
+# All the other archives built/used by this makefile are for targets. This
+# one is strictly for the host.
+#
+libcpp.a: $(LIBCPP_OBJS)
+ $(AR) $(AR_FLAGS) libcpp.a $(LIBCPP_OBJS)
+ if $(RANLIB_TEST) ; then $(RANLIB) libcpp.a ; else true ; fi
+
+cppmain$(exeext): cppmain.o libcpp.a $(LIBDEPS)
+ $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o cppmain$(exeext) cppmain.o \
+ libcpp.a $(LIBS)
+
+cppmain.o: cppmain.c $(CONFIG_H) cpplib.h intl.h system.h
+
+cppulp.o: cppulp.c $(CONFIG_H) system.h output.h
+cpplib.o: cpplib.c $(CONFIG_H) cpplib.h intl.h system.h cpphash.h
+cpphash.o: cpphash.c $(CONFIG_H) cpplib.h intl.h system.h cpphash.h
+cppalloc.o: cppalloc.c $(CONFIG_H) cpplib.h intl.h system.h
+cpperror.o: cpperror.c $(CONFIG_H) cpplib.h intl.h system.h
+cppexp.o: cppexp.c $(CONFIG_H) cpplib.h intl.h system.h
+cppfiles.o: cppfiles.c $(CONFIG_H) cpplib.h intl.h system.h
+
+cppinit.o: cppalloc.c $(CONFIG_H) cpplib.h intl.h system.h \
+ cpphash.h prefix.h output.h Makefile
$(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
-DGCC_INCLUDE_DIR=\"$(libsubdir)/include\" \
- -DGPLUSPLUS_INCLUDE_DIR=\"$(gxx_include_dir)\" \
+ -DGPLUSPLUS_INCLUDE_DIR=\"$(gcc_gxx_include_dir)\" \
-DLOCAL_INCLUDE_DIR=\"$(includedir)\" \
- -DCROSS_INCLUDE_DIR=\"$(tooldir)/sys-include\" \
- -DTOOL_INCLUDE_DIR=\"$(tooldir)/include\" \
- -c `echo $(srcdir)/cpplib.c | sed 's,^\./,,'`
-
-cpperror.o: cpperror.c $(CONFIG_H) cpplib.h system.h gansidecl.h
-
-cppexp.o: cppexp.c $(CONFIG_H) cpplib.h system.h gansidecl.h
-
-cpphash.o: cpphash.c cpplib.h cpphash.h $(CONFIG_H) system.h gansidecl.h
-
-cppalloc.o: cppalloc.c $(CONFIG_H) cpplib.h system.h gansidecl.h
+ -DCROSS_INCLUDE_DIR=\"$(gcc_tooldir)/sys-include\" \
+ -DTOOL_INCLUDE_DIR=\"$(gcc_tooldir)/include\" \
+ -c `echo $(srcdir)/cppinit.c | sed 's,^\./,,'`
# Note for the stamp targets, we run the program `true' instead of
# having an empty command (nothing following the semicolon).
proto: config.status protoize$(exeext) unprotoize$(exeext) SYSCALLS.c.X
-protoize$(exeext): protoize.o getopt.o getopt1.o getpwd.o version.o \
- pexecute.o choose-temp.o mkstemp.o $(LIBDEPS)
- $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ \
- protoize.o getopt.o getopt1.o getpwd.o version.o \
- pexecute.o choose-temp.o mkstemp.o $(LIBS)
+PROTO_OBJS = getpwd.o intl.o version.o
+
+protoize$(exeext): protoize.o $(PROTO_OBJS) $(LIBDEPS)
+ $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ protoize.o $(PROTO_OBJS) $(LIBS)
-unprotoize$(exeext): unprotoize.o getopt.o getopt1.o getpwd.o version.o \
- pexecute.o choose-temp.o mkstemp.o $(LIBDEPS)
- $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ \
- unprotoize.o getopt.o getopt1.o getpwd.o version.o \
- pexecute.o choose-temp.o mkstemp.o $(LIBS)
+unprotoize$(exeext): unprotoize.o $(PROTO_OBJS) $(LIBDEPS)
+ $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ unprotoize.o $(PROTO_OBJS) $(LIBS)
-protoize.o: protoize.c $(srcdir)/../include/getopt.h $(CONFIG_H) system.h
+protoize.o: protoize.c $(srcdir)/../include/getopt.h $(CONFIG_H) system.h \
+ Makefile
$(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
-DGCC_INCLUDE_DIR=\"$(libsubdir)/include\" \
- -DGPLUSPLUS_INCLUDE_DIR=\"$(gxx_include_dir)\" \
- -DCROSS_INCLUDE_DIR=\"$(libsubdir)/$(unlibsubdir)/../$(target_alias)/sys-include\" \
- -DTOOL_INCLUDE_DIR=\"$(tooldir)/include\" \
+ -DGPLUSPLUS_INCLUDE_DIR=\"$(gcc_gxx_include_dir)\" \
+ -DCROSS_INCLUDE_DIR=\"$(gcc_tooldir)/sys-include\" \
+ -DTOOL_INCLUDE_DIR=\"$(gcc_tooldir)/include\" \
-DLOCAL_INCLUDE_DIR=\"$(includedir)\" \
-DSTD_PROTO_DIR=\"$(libsubdir)\" \
$(srcdir)/protoize.c
-unprotoize.o: unprotoize.c protoize.c $(srcdir)/../include/getopt.h $(CONFIG_H) system.h
+unprotoize.o: unprotoize.c protoize.c $(srcdir)/../include/getopt.h \
+ $(CONFIG_H) system.h Makefile
$(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
-DGCC_INCLUDE_DIR=\"$(libsubdir)/include\" \
- -DGPLUSPLUS_INCLUDE_DIR=\"$(gxx_include_dir)\" \
- -DCROSS_INCLUDE_DIR=\"$(libsubdir)/$(unlibsubdir)/../$(target_alias)/sys-include\" \
- -DTOOL_INCLUDE_DIR=\"$(tooldir)/include\" \
+ -DGPLUSPLUS_INCLUDE_DIR=\"$(gcc_gxx_include_dir)\" \
+ -DCROSS_INCLUDE_DIR=\"$(gcc_tooldir)/sys-include\" \
+ -DTOOL_INCLUDE_DIR=\"$(gcc_tooldir)/include\" \
-DLOCAL_INCLUDE_DIR=\"$(includedir)\" \
-DSTD_PROTO_DIR=\"$(libsubdir)\" \
$(srcdir)/unprotoize.c
-getopt.o: $(srcdir)/../libiberty/getopt.c $(srcdir)/../include/getopt.h
- rm -f getopt.c
- $(LN_S) $(srcdir)/../libiberty/getopt.c getopt.c
- $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) getopt.c
-
-getopt1.o: $(srcdir)/../libiberty/getopt1.c $(srcdir)/../include/getopt.h
- rm -f getopt1.c
- $(LN_S) $(srcdir)/../libiberty/getopt1.c getopt1.c
- $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) getopt1.c
-
# This info describes the target machine, so compile with GCC just built.
SYSCALLS.c.X: $(srcdir)/sys-types.h $(srcdir)/sys-protos.h $(GCC_PASSES) \
stmp-int-hdrs
@@ -1992,12 +2083,13 @@ test-protoize-simple: ./protoize ./unprotoize $(GCC_PASSES)
diff $(srcdir)/protoize.c tmp-proto.c | cat
-rm -f tmp-proto.[cs] tmp-proto$(objext)
-gcov.o: gcov.c gcov-io.h system.h
+gcov.o: gcov.c gcov-io.h intl.h system.h
# Only one of 'gcov' or 'gcov.exe' is actually built, depending
# upon whether $(exeext) is empty or not.
-gcov$(exeext): gcov.o $(LIBDEPS)
- $(CC) $(ALL_CFLAGS) $(LDFLAGS) gcov.o $(LIBS) -o $@
+GCOV_OBJS = gcov.o intl.o
+gcov$(exeext): $(GCOV_OBJS) $(LIBDEPS)
+ $(CC) $(ALL_CFLAGS) $(LDFLAGS) $(GCOV_OBJS) $(LIBS) -o $@
#
# Build the include directory. The stamp files are stmp-* rather than
# s-* so that mostlyclean does not force the include directory to
@@ -2005,7 +2097,7 @@ gcov$(exeext): gcov.o $(LIBDEPS)
# Build the include directory including float.h (which no longer depends upon
# enquire).
-stmp-int-hdrs: stmp-fixinc $(USER_H) xlimits.h gfloat.h
+stmp-int-hdrs: stmp-fixinc $(USER_H) xlimits.h
# Copy in the headers provided with gcc.
# The sed command gets just the last file name component;
# this is necessary because VPATH could add a dirname.
@@ -2024,8 +2116,8 @@ stmp-int-hdrs: stmp-fixinc $(USER_H) xlimits.h gfloat.h
cp xlimits.h include/limits.h
chmod a+r include/limits.h
rm -f include/float.h
- if [ -s gfloat.h ]; then \
- cp gfloat.h include/float.h && \
+ if [ x$(FLOAT_H) != xMakefile.in ]; then \
+ cp $(srcdir)/config/$(FLOAT_H) include/float.h && \
chmod a+r include/float.h; \
else :; fi
# Install the README
@@ -2034,34 +2126,42 @@ stmp-int-hdrs: stmp-fixinc $(USER_H) xlimits.h gfloat.h
chmod a+r include/README
touch $@
-# Now that gfloat.h no longer depends upon enquire, this is actually a no-op.
+# Now that float.h no longer depends upon enquire, this is actually a no-op.
stmp-headers:
touch $@
-fixinc.sh :
- DEST=`cd $(srcdir) ; pwd`/$@ CC=$(CC) MAKE=$(MAKE) CFLAGS="$(CFLAGS)" \
- export DEST CC MAKE CFLAGS ; \
- echo DEST=$$DEST CC=$$CC MAKE=$$MAKE CFLAGS=$$CFLAGS ; \
- cd ../contrib/fixinc ; \
- $(SHELL) mkfixinc.sh $(target) $$DEST
+fixinc.sh: $(srcdir)/fixinc/mkfixinc.sh
+ MAKE="$(MAKE)"; srcdir=`cd $(srcdir)/fixinc; pwd` ; \
+ export MAKE srcdir ; \
+ cd ./fixinc; $(SHELL) $${srcdir}/mkfixinc.sh $(target)
+
+##stmp-fixinc: $(FIXINCLUDES) gsyslimits.h
+## rm -rf include
+## mkdir include
+## if [ x$(FIXINCLUDES) != xMakefile.in ]; \
+## then \
+## for dir in $(SYSTEM_HEADER_DIR) $(OTHER_FIXINCLUDES_DIRS); do \
+## if [ -d $$dir ]; \
+## then \
+## $(SHELL) $(srcdir)/$(FIXINCLUDES) include $$dir; \
+## else true; fi; \
+## done; \
+## if [ x$(INSTALL_ASSERT_H) != x ] ; \
+## then \
+## rm -f include/assert.h; \
+## cp $(srcdir)/assert.h include/assert.h; \
+## chmod a+r include/assert.h; \
+## fi \
+## else true; \
+## fi
# Build fixed copies of system files.
-stmp-fixinc: $(FIXINCLUDES) gsyslimits.h
- rm -rf include
- mkdir include
- if [ x$(FIXINCLUDES) != xMakefile.in ]; \
- then \
- for dir in $(SYSTEM_HEADER_DIR) $(OTHER_FIXINCLUDES_DIRS); do \
- if [ -d $$dir ]; \
- then \
- $(SHELL) $(srcdir)/$(FIXINCLUDES) include $$dir; \
- else true; fi; \
- done; \
- rm -f include/assert.h; \
- cp $(srcdir)/assert.h include/assert.h; \
- chmod a+r include/assert.h; \
- else true; \
- fi
+stmp-fixinc: fixinc.sh gsyslimits.h
+ rm -rf include; mkdir include
+ TARGET_MACHINE=$(target); srcdir=`cd $(srcdir); pwd`; \
+ INSTALL_ASSERT_H=$(INSTALL_ASSERT_H); \
+ export TARGET_MACHINE srcdir INSTALL_ASSERT_H; \
+ $(SHELL) ./fixinc.sh `pwd`/include $(SYSTEM_HEADER_DIR) $(OTHER_FIXINCLUDES_DIRS)
rm -f include/syslimits.h
if [ -f include/limits.h ]; then \
mv include/limits.h include/syslimits.h; \
@@ -2074,6 +2174,8 @@ stmp-fixinc: $(FIXINCLUDES) gsyslimits.h
# This is because cpp is compiled to find $(tooldir)/include via
# $(libsubdir)/$(unlibsubdir), which will only work if $(libsubdir)
# exists.
+# We deliberately use tooldir instead of gcc_tooldir here. gcc_tooldir
+# won't work because libsubdir doesn't exist yet.
if [ "$(SYSTEM_HEADER_DIR)" = "$(tooldir)/sys-include" ] \
&& [ -d $(tooldir)/sys-include ]; then \
if [ -d $(libdir) ] ; then true ; else mkdir $(libdir) ; fi; \
@@ -2097,9 +2199,10 @@ deduced.h: $(GCC_PASSES) $(srcdir)/scan-types.sh stmp-int-hdrs
touch deduced.h; \
fi
-gen-protos: gen-protos.o scan.o cppalloc.o $(HOST_LIBDEPS)
- ${HOST_CC} $(HOST_CFLAGS) $(HOST_LDFLAGS) -o $@ \
- gen-protos.o scan.o cppalloc.o $(HOST_LIBS)
+GEN_PROTOS_OBJS = gen-protos.o scan.o libcpp.a
+gen-protos: $(GEN_PROTOS_OBJS) $(HOST_LIBDEPS)
+ ${HOST_CC} $(HOST_CFLAGS) $(HOST_LDFLAGS) -o gen-protos \
+ $(GEN_PROTOS_OBJS) $(HOST_LIBS)
gen-protos.o: gen-protos.c scan.h $(build_xm_file) system.h
$(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) $(srcdir)/gen-protos.c
@@ -2117,16 +2220,15 @@ xsys-protos.h: $(GCC_PASSES) $(srcdir)/sys-protos.h deduced.h gen-protos Makefil
rm -rf fixtmp.c
fix-header: fix-header.o scan-decls.o scan.o xsys-protos.h $(HOST_LIBDEPS) \
- cpplib.o cpphash.o cppalloc.o cppexp.o prefix.o version.o
+ libcpp.a
$(HOST_CC) $(HOST_CFLAGS) $(HOST_LDFLAGS) -o $@ fix-header.o \
- scan-decls.o scan.o cpplib.o cpphash.o cppalloc.o prefix.o \
- version.o cppexp.o $(HOST_LIBS)
+ scan-decls.o scan.o libcpp.a $(HOST_LIBS)
fix-header.o: fix-header.c $(srcdir)/../include/obstack.h scan.h \
xsys-protos.h $(build_xm_file) system.h cpplib.h cpphash.h
$(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) $(srcdir)/fix-header.c
-scan-decls.o: scan-decls.c scan.h cpplib.h $(build_xm_file) system.h gansidecl.h
+scan-decls.o: scan-decls.c scan.h cpplib.h $(build_xm_file) system.h
$(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) $(srcdir)/scan-decls.c
# stmp-fixproto depends on this, not on fix-header directly.
@@ -2204,7 +2306,7 @@ INSTALL: $(srcdir)/install1.texi $(srcdir)/install.texi
# (less duplicated code).
-mostlyclean: lang.mostlyclean
+mostlyclean: intl.mostlyclean lang.mostlyclean
-rm -f $(STAGESTUFF)
# Delete the temporary source copies for cross compilation.
-rm -f $(HOST_PREFIX_1)rtl.c $(HOST_PREFIX_1)rtlanal.c
@@ -2221,12 +2323,12 @@ mostlyclean: lang.mostlyclean
# Delete debugging dump files.
-rm -f *.greg *.lreg *.combine *.flow *.cse *.jump *.rtl *.tree *.loop
-rm -f *.dbr *.jump2 *.sched *.cse2 *.sched2 *.stack *.addressof
- -rm -f *.regmove *.mach *.bp *.gcse
+ -rm -f *.regmove *.mach *.bp *.gcse *.flow2
-rm -f */*.greg */*.lreg */*.combine */*.flow */*.cse */*.jump */*.rtl
-rm -f */*.tree */*.loop */*.dbr */*.jump2 */*.sched */*.cse2
- -rm -f */*.sched2 */*.stack */*.regmove */*.gcse
+ -rm -f */*.sched2 */*.stack */*.regmove */*.gcse */*.flow2
# Delete some files made during installation.
- -rm -f specs gfloat.h float.h-* enquire SYSCALLS.c.X SYSCALLS.c
+ -rm -f specs float.h-* enquire SYSCALLS.c.X SYSCALLS.c
-rm -f collect collect2 mips-tfile mips-tdump alloca.s
# Delete files generated for fixproto
-rm -rf fix-header xsys-protos.h deduced.h tmp-deduced.h \
@@ -2242,7 +2344,7 @@ mostlyclean: lang.mostlyclean
# Delete all files made by compilation
# that don't exist in the distribution.
-clean: mostlyclean lang.clean
+clean: mostlyclean intl.clean lang.clean
# It may not be quite desirable to delete unprotoize.c here,
# but the spec for `make clean' requires it.
# Using unprotoize.c is not quite right in the first place,
@@ -2267,7 +2369,8 @@ clean: mostlyclean lang.clean
# Delete all files that users would normally create
# while building and installing GCC.
-distclean: clean lang.distclean
+INTL_DISTCLEAN = intl.distclean
+distclean: clean $(INTL_DISTCLEAN) lang.distclean
-rm -f tm.h config.h auto-host.h auto-build.h tconfig.h hconfig.h
-rm -f md cstamp-h
-rm -f config.status config.run config.cache config.bak
@@ -2280,6 +2383,7 @@ distclean: clean lang.distclean
-rm -f float.h
-rm -f site.exp site.bak testsuite/site.exp testsuite/site.bak
-rm -f testsuite/{gcc,g++}.{log,sum}
+ -rm -f intl/libintl.h libintl.h
# Delete anything likely to be found in the source directory
# that shouldn't be in the distribution.
@@ -2292,6 +2396,7 @@ extraclean: distclean lang.extraclean
-rm -f *.tar *.xtar *diff *.diff.* *.tar.* *.xtar.* *diffs
-rm -f *lose config/*lose config/*/*lose
-rm -f *.s *.s[0-9] *.i config/ChangeLog
+ -rm -f y.tab.c yacc.*
-rm -f */=* */"#"* */*~*
-rm -f */patch* */*.orig */*.rej
-rm -f */*.dvi */*.oaux */*.d */*.[zZ] */*.gz
@@ -2300,10 +2405,13 @@ extraclean: distclean lang.extraclean
# Get rid of every file that's generated from some other file, except for `configure'.
# Most of these files ARE PRESENT in the GCC distribution.
+# We define INTL_DISTCLEAN to be empty in the submake, so that
+# we don't descend into intl after its makefile has been removed.
maintainer-clean:
@echo 'This command is intended for maintainers to use; it'
@echo 'deletes files that may need special tools to rebuild.'
- $(MAKE) distclean lang.maintainer-clean
+ $(MAKE) INTL_DISTCLEAN= distclean \
+ intl.maintainer-clean lang.maintainer-clean
-rm -f c-parse.y c-gperf.h
-rm -f c-parse.c c-parse.h c-parse.output
-rm -f cexp.c cexp.output TAGS
@@ -2322,7 +2430,8 @@ install: $(INSTALL_TARGET) ; @true
# Install the driver last so that the window when things are
# broken is small.
install-normal: install-common $(INSTALL_HEADERS) $(INSTALL_LIBGCC) \
- install-man install-info lang.install-normal install-driver
+ $(INSTALL_CPP) install-man install-info intl.install lang.install-normal \
+ install-driver
# Do nothing while making gcc with a cross-compiler. The person who
# makes gcc for the target machine has to know how to put a complete
@@ -2332,10 +2441,27 @@ install-build: force
# Run this on the target machine
# to finish installation of cross compiler.
+# This is not used anymore now that float.h does not depend on enquire.
install-cross-rest: install-float-h-cross
+# Handle cpp installation.
+install-cpp: xcpp$(exeext)
+ -rm -f $(bindir)/$(CPP_INSTALL_NAME)$(exeext)
+ $(INSTALL_PROGRAM) -m 755 xcpp$(exeext) $(bindir)/$(CPP_INSTALL_NAME)$(exeext)
+ if [ x$(cpp_install_dir) != x ]; then \
+ rm -f $(prefix)/$(cpp_install_dir)/$(CPP_INSTALL_NAME)$(exeext); \
+ $(INSTALL_PROGRAM) -m 755 xcpp$(exeext) $(prefix)/$(cpp_install_dir)/$(CPP_INSTALL_NAME)$(exeext); \
+ else true; fi
+
+uninstall-cpp:
+ -rm -f $(bindir)/cpp
+ -if [ x$(cpp_install_dir) != x ]; then \
+ rm -f $(prefix)/$(cpp_install_dir)/cpp; \
+ else true; fi
+
# Install float.h for cross compiler.
# Run this on the target machine!
+# This is not used anymore now that float.h does not depend on enquire.
install-float-h-cross: installdirs
# if [ -f enquire ] ; then true; else false; fi
# Note: don't use -. We should fail right away if enquire was not made.
@@ -2359,15 +2485,15 @@ installdirs:
done
-if [ -d $(bindir) ] ; then true ; else mkdir $(bindir) ; chmod a+rx $(bindir) ; fi
-if [ -d $(includedir) ] ; then true ; else mkdir $(includedir) ; chmod a+rx $(includedir) ; fi
- -if [ -d $(tooldir) ] ; then true ; else mkdir $(tooldir) ; chmod a+rx $(tooldir) ; fi
+ -if [ -d $(gcc_tooldir) ] ; then true ; else mkdir $(gcc_tooldir) ; chmod a+rx $(gcc_tooldir) ; fi
-if [ -d $(assertdir) ] ; then true ; else mkdir $(assertdir) ; chmod a+rx $(assertdir) ; fi
-if [ -d $(infodir) ] ; then true ; else mkdir $(infodir) ; chmod a+rx $(infodir) ; fi
-# We don't use mkdir -p to create the parents of mandir,
+# We don't use mkdir -p to create the parents of man1dir,
# because some systems don't support it.
-# Instead, we use this technique to create the immediate parent of mandir.
- -parent=`echo $(mandir)|sed -e 's@/[^/]*$$@@'`; \
+# Instead, we use this technique to create the immediate parent of man1dir.
+ -parent=`echo $(man1dir)|sed -e 's@/[^/]*$$@@'`; \
if [ -d $$parent ] ; then true ; else mkdir $$parent ; chmod a+rx $$parent ; fi
- -if [ -d $(mandir) ] ; then true ; else mkdir $(mandir) ; chmod a+rx $(mandir) ; fi
+ -if [ -d $(man1dir) ] ; then true ; else mkdir $(man1dir) ; chmod a+rx $(man1dir) ; fi
# Install the compiler executables built during cross compilation.
install-common: native installdirs $(EXTRA_PARTS) lang.install-common
@@ -2421,19 +2547,18 @@ install-common: native installdirs $(EXTRA_PARTS) lang.install-common
-if [ -f gcov$(exeext) ]; \
then \
rm -f $(bindir)/gcov$(exeext); \
- $(INSTALL_PROGRAM) gcov$(exeext) $(bindir)/gcov$(exeext); \
- chmod a+x $(bindir)/gcov$(exeext); \
+ $(INSTALL_PROGRAM) gcov$(exeext) $(bindir)/$(GCOV_INSTALL_NAME)$(exeext); \
fi
# Install the driver program as $(target_alias)-gcc
-# and also as either gcc (if native) or $(tooldir)/bin/gcc.
+# and also as either gcc (if native) or $(gcc_tooldir)/bin/gcc.
install-driver: xgcc$(exeext)
-if [ -f gcc-cross$(exeext) ] ; then \
rm -f $(bindir)/$(GCC_CROSS_NAME)$(exeext); \
$(INSTALL_PROGRAM) gcc-cross$(exeext) $(bindir)/$(GCC_CROSS_NAME)$(exeext); \
- if [ -d $(tooldir)/bin/. ] ; then \
- rm -f $(tooldir)/bin/gcc$(exeext); \
- $(INSTALL_PROGRAM) gcc-cross$(exeext) $(tooldir)/bin/gcc$(exeext); \
+ if [ -d $(gcc_tooldir)/bin/. ] ; then \
+ rm -f $(gcc_tooldir)/bin/gcc$(exeext); \
+ $(INSTALL_PROGRAM) gcc-cross$(exeext) $(gcc_tooldir)/bin/gcc$(exeext); \
else true; fi; \
else \
rm -f $(bindir)/$(GCC_INSTALL_NAME)$(exeext); \
@@ -2463,25 +2588,25 @@ install-info: doc installdirs lang.install-info
# Install the man pages.
install-man: installdirs $(srcdir)/gcc.1 $(srcdir)/cccp.1 lang.install-man
-if [ -f gcc-cross$(exeext) ] ; then \
- rm -f $(mandir)/$(GCC_CROSS_NAME)$(manext); \
- $(INSTALL_DATA) $(srcdir)/gcc.1 $(mandir)/$(GCC_CROSS_NAME)$(manext); \
- chmod a-x $(mandir)/$(GCC_CROSS_NAME)$(manext); \
+ rm -f $(man1dir)/$(GCC_CROSS_NAME)$(manext); \
+ $(INSTALL_DATA) $(srcdir)/gcc.1 $(man1dir)/$(GCC_CROSS_NAME)$(manext); \
+ chmod a-x $(man1dir)/$(GCC_CROSS_NAME)$(manext); \
else \
- rm -f $(mandir)/$(GCC_INSTALL_NAME)$(manext); \
- $(INSTALL_DATA) $(srcdir)/gcc.1 $(mandir)/$(GCC_INSTALL_NAME)$(manext); \
- chmod a-x $(mandir)/$(GCC_INSTALL_NAME)$(manext); \
+ rm -f $(man1dir)/$(GCC_INSTALL_NAME)$(manext); \
+ $(INSTALL_DATA) $(srcdir)/gcc.1 $(man1dir)/$(GCC_INSTALL_NAME)$(manext); \
+ chmod a-x $(man1dir)/$(GCC_INSTALL_NAME)$(manext); \
fi
- -rm -f $(mandir)/cccp$(manext)
- -$(INSTALL_DATA) $(srcdir)/cccp.1 $(mandir)/cccp$(manext)
- -chmod a-x $(mandir)/cccp$(manext)
+ -rm -f $(man1dir)/cccp$(manext)
+ -$(INSTALL_DATA) $(srcdir)/cccp.1 $(man1dir)/cccp$(manext)
+ -chmod a-x $(man1dir)/cccp$(manext)
# Install the library.
install-libgcc: libgcc.a installdirs
-if [ -f libgcc.a ] ; then \
rm -f $(libsubdir)/libgcc.a; \
$(INSTALL_DATA) libgcc.a $(libsubdir)/libgcc.a; \
- if $(RANLIB_TEST) ; then \
- (cd $(libsubdir); $(RANLIB) libgcc.a); else true; fi; \
+ if $(RANLIB_TEST_FOR_TARGET) ; then \
+ (cd $(libsubdir); $(RANLIB_FOR_TARGET) libgcc.a); else true; fi; \
chmod a-x $(libsubdir)/libgcc.a; \
else true; fi
@@ -2494,8 +2619,9 @@ install-multilib: stmp-multilib installdirs
rm -f $(libsubdir)/$${dir}/$${f}; \
$(INSTALL_DATA) $${dir}/$${f} $(libsubdir)/$${dir}/$${f}; \
done; \
- if $(RANLIB_TEST); then \
- (cd $(libsubdir)/$${dir}; $(RANLIB) libgcc.a); else true; fi; \
+ if $(RANLIB_TEST_FOR_TARGET); then \
+ (cd $(libsubdir)/$${dir}; $(RANLIB_FOR_TARGET) libgcc.a); \
+ else true; fi; \
chmod a-x $(libsubdir)/$${dir}/libgcc.a; \
done
@@ -2564,18 +2690,20 @@ install-collect2: collect2 installdirs
$(INSTALL_PROGRAM) xgcc$(exeext) $(libsubdir)/gcc$(exeext)
# Cancel installation by deleting the installed files.
-uninstall: lang.uninstall
+uninstall: intl.uninstall lang.uninstall $(UNINSTALL_CPP)
-rm -rf $(libsubdir)
-rm -rf $(bindir)/$(GCC_INSTALL_NAME)$(exeext)
-rm -rf $(bindir)/$(GCC_CROSS_NAME)$(exeext)
- -rm -rf $(bindir)/protoize$(exeext)
- -rm -rf $(bindir)/unprotoize$(exeext)
- -rm -rf $(bindir)/gcov$(exeext)
- -rm -rf $(mandir)/$(GCC_INSTALL_NAME)$(manext)
- -rm -rf $(mandir)/$(GCC_CROSS_NAME)$(manext)
- -rm -rf $(mandir)/cccp$(manext)
- -rm -rf $(mandir)/protoize$(manext)
- -rm -rf $(mandir)/unprotoize$(manext)
+ -rm -rf $(bindir)/$(PROTOIZE_INSTALL_NAME)$(exeext)
+ -rm -rf $(bindir)/$(PROTOIZE_CROSS_NAME)$(exeext)
+ -rm -rf $(bindir)/$(UNPROTOIZE_INSTALL_NAME)$(exeext)
+ -rm -rf $(bindir)/$(UNPROTOIZE_CROSS_NAME)$(exeext)
+ -rm -rf $(bindir)/$(GCOV_INSTALL_NAME)$(exeext)
+ -rm -rf $(man1dir)/$(GCC_INSTALL_NAME)$(manext)
+ -rm -rf $(man1dir)/$(GCC_CROSS_NAME)$(manext)
+ -rm -rf $(man1dir)/cccp$(manext)
+ -rm -rf $(man1dir)/protoize$(manext)
+ -rm -rf $(man1dir)/unprotoize$(manext)
-rm -f $(infodir)/cpp.info* $(infodir)/gcc.info*
#
# These targets are for the dejagnu testsuites. The file site.exp
@@ -2649,7 +2777,7 @@ check-g++: testsuite/site.exp
cd testsuite; \
EXPECT=${EXPECT} ; export EXPECT ; \
if [ -f $${rootme}/../expect/expect ] ; then \
- TCL_LIBRARY=$${srcdir}/../tcl/library ; \
+ TCL_LIBRARY=`cd ${srcdir}/../tcl/library ; pwd` ; \
export TCL_LIBRARY ; fi ; \
$(RUNTEST) --tool g++ $(RUNTESTFLAGS)
@@ -2659,7 +2787,7 @@ check-gcc: testsuite/site.exp
cd testsuite; \
EXPECT=${EXPECT} ; export EXPECT ; \
if [ -f $${rootme}/../expect/expect ] ; then \
- TCL_LIBRARY=$${srcdir}/../tcl/library ; \
+ TCL_LIBRARY=`cd ${srcdir}/../tcl/library ; pwd` ; \
export TCL_LIBRARY ; fi ; \
$(RUNTEST) --tool gcc $(RUNTESTFLAGS)
@@ -2669,7 +2797,7 @@ check-g77: testsuite/site.exp
cd testsuite; \
EXPECT=${EXPECT} ; export EXPECT ; \
if [ -f $${rootme}/../expect/expect ] ; then \
- TCL_LIBRARY=$${srcdir}/../tcl/library ; \
+ TCL_LIBRARY=`cd ${srcdir}/../tcl/library ; pwd` ; \
export TCL_LIBRARY ; fi ; \
$(RUNTEST) --tool g77 $(RUNTESTFLAGS)
@@ -2679,7 +2807,7 @@ check-objc: testsuite/site.exp
cd testsuite; \
EXPECT=${EXPECT} ; export EXPECT ; \
if [ -f $${rootme}/../expect/expect ] ; then \
- TCL_LIBRARY=$${srcdir}/../tcl/library ; \
+ TCL_LIBRARY=`cd ${srcdir}/../tcl/library ; pwd` ; \
export TCL_LIBRARY ; fi ; \
$(RUNTEST) --tool objc $(RUNTESTFLAGS)
@@ -2704,22 +2832,27 @@ tmp-gcc.xtar: distdir
tar -chf tmp-gcc.xtar gcc-$(version)
distdir-cvs: force
- if [ -d $(srcdir)/CVS ]; then cvs -r update; fi
+ if [ -d $(srcdir)/CVS ]; then cd $(srcdir) && cvs -r update; fi
# This target exists to do the initial work before the language specific
# stuff gets done.
distdir-start: doc $(srcdir)/INSTALL $(srcdir)/c-parse.y $(srcdir)/c-gperf.h \
$(srcdir)/c-parse.c $(srcdir)/cexp.c $(srcdir)/config.in \
$(srcdir)/version.c TAGS
+ @case '$(USE_NLS)' in \
+ yes) ;; \
+ *) echo "configure with --enable-nls before making a distribution"; \
+ exit 1;; \
+ esac
@if grep -s "for version ${mainversion}" gcc.texi > /dev/null; \
then true; \
else echo "You must update the version number in \`gcc.texi'"; sleep 10;\
fi
# Update the version number in README
- awk '$$1 " " $$2 " " $$3 == "This directory contains" \
+ $(AWK) '$$1 " " $$2 " " $$3 == "This directory contains" \
{ $$6 = version; print $$0 } \
$$1 " " $$2 " " $$3 != "This directory contains"' \
- version=$(version) README > tmp.README
+ version=$(version) $(srcdir)/README > tmp.README
mv tmp.README README
-rm -rf gcc-$(version) tmp
# Put all the files in a temporary subdirectory
@@ -2727,31 +2860,35 @@ distdir-start: doc $(srcdir)/INSTALL $(srcdir)/c-parse.y $(srcdir)/c-gperf.h \
mkdir tmp
mkdir tmp/config
mkdir tmp/ginclude
- for file in *[0-9a-zA-Z+]; do \
- $(LN) $$file tmp; \
+ mkdir tmp/objc
+ mkdir tmp/intl
+ mkdir tmp/po
+ for file in `(cd $(srcdir) && echo *[0-9a-zA-Z+])`; do \
+ test -f $(srcdir)/$$file && $(LN_S) $(srcdir)/$$file tmp; \
done
- cd config; \
- for file in *[0-9a-zA-Z+]; do \
- if test -d $$file && test "$$file" != RCS && test "$$file" != CVS; then \
- mkdir ../tmp/config/$$file; \
- cd $$file; \
- for subfile in *[0-9a-zA-Z+]; do \
- $(LN) $$subfile ../../tmp/config/$$file; \
+ if test "$(srcdir)" != "." ; then \
+ for file in c-parse.c cexp.c ; do \
+ test -f ./$$file && $(LN_S) ../$$file tmp; \
+ done; \
+ fi
+ for file in `(cd $(srcdir)/config && echo *[0-9a-zA-Z+])`; do \
+ if test -d $(srcdir)/config/$$file \
+ && test "$$file" != RCS && test "$$file" != CVS; then \
+ mkdir tmp/config/$$file; \
+ for subfile in `(cd $(srcdir)/config/$$file && echo *[0-9a-zA-Z+])`; do \
+ $(LN_S) $(srcdir)/config/$$file/$$subfile tmp/config/$$file; \
done; \
- cd ..; \
else \
- $(LN) $$file ../tmp/config; \
+ $(LN_S) $(srcdir)/config/$$file tmp/config; \
fi; \
done
- cd ginclude; \
- for file in *[0-9a-zA-Z+]; do \
- $(LN) $$file ../tmp/ginclude; \
+ for file in `(cd $(srcdir)/ginclude && echo *[0-9a-zA-Z+])`; do \
+ $(LN_S) $(srcdir)/ginclude/$$file tmp/ginclude; \
done
- cd objc; \
- for file in *[0-9a-zA-Z+]; do \
- $(LN) $$file ../tmp/objc; \
+ for file in `(cd $(srcdir)/objc && echo *[0-9a-zA-Z+])`; do \
+ $(LN_S) $(srcdir)/objc/$$file tmp/objc; \
done
- $(LN) .gdbinit tmp
+ $(LN_S) .gdbinit tmp
# Finish making `distdir', after the languages have done their thing.
distdir-finish:
@@ -2759,9 +2896,21 @@ distdir-finish:
# Get rid of everything we don't want in the distribution. We'd want
# this to use Makefile.in, but it doesn't have the `lang.foo' targets
# expanded.
- cd gcc-$(version); make extraclean VERSION_DEP=
+ cd gcc-$(version); make extraclean distdir-check VERSION_DEP=
+
+distdir-check:
+ ($(AWK) '/^[^#]/{print} /^#[A-Za-z]/{print substr($$1, 2)}' | sort) \
+ < po/POTFILES.in > tmp.POTFILES
+ ls [A-Za-z]*.[ch] [a-z]*/[A-Za-z]*.[ch] \
+ [a-z]*/[a-z]*/[A-Za-z]*.[ch] | sort > tmp.src
+ diff tmp.POTFILES tmp.src || { \
+ echo "po/POTFILES.in and sources do not match -- please fix"; \
+ exit 1; \
+ }
+ rm -f tmp.*
-distdir: distdir-cvs distdir-start lang.distdir distdir-finish
+distdir: distdir-cvs distdir-start intl.distdir intl.distdir-fixup \
+ lang.distdir distdir-finish
# make diff oldversion=M.N
# creates a diff file between an older distribution and this one.
@@ -2786,22 +2935,22 @@ bootstrap bootstrap-lean: force
# To prevent `make install' from compiling alloca.o and then relinking cc1
# because alloca.o is newer, we permit these recursive makes to compile
# alloca.o. Then cc1 is newer, so it won't have to be relinked.
- $(MAKE) CC="stage1/xgcc$(exeext) -Bstage1/" CFLAGS="$(WARN_CFLAGS) $(BOOT_CFLAGS)" LDFLAGS="$(BOOT_LDFLAGS)" libdir=$(libdir) STAGE_PREFIX=stage1/ LANGUAGES="$(LANGUAGES)"
+ $(MAKE) CC="stage1/xgcc$(exeext) -Bstage1/ -B$(build_tooldir)/bin/" CFLAGS="$(WARN_CFLAGS) $(BOOT_CFLAGS)" LDFLAGS="$(BOOT_LDFLAGS)" libdir=$(libdir) STAGE_PREFIX=stage1/ LANGUAGES="$(LANGUAGES)"
$(MAKE) stage2
-if test $@ = bootstrap-lean; then rm -rf stage1; else true; fi
- $(MAKE) CC="stage2/xgcc$(exeext) -Bstage2/" CFLAGS="$(WARN_CFLAGS) $(BOOT_CFLAGS)" LDFLAGS="$(BOOT_LDFLAGS)" libdir=$(libdir) STAGE_PREFIX=stage2/ LANGUAGES="$(LANGUAGES)"
+ $(MAKE) CC="stage2/xgcc$(exeext) -Bstage2/ -B$(build_tooldir)/bin/" CFLAGS="$(WARN_CFLAGS) $(BOOT_CFLAGS)" LDFLAGS="$(BOOT_LDFLAGS)" libdir=$(libdir) STAGE_PREFIX=stage2/ LANGUAGES="$(LANGUAGES)"
bootstrap2 bootstrap2-lean: force
- $(MAKE) CC="stage1/xgcc$(exeext) -Bstage1/" CFLAGS="$(WARN_CFLAGS) $(BOOT_CFLAGS)" LDFLAGS="$(BOOT_LDFLAGS)" libdir=$(libdir) STAGE_PREFIX=stage1/ LANGUAGES="$(LANGUAGES)"
+ $(MAKE) CC="stage1/xgcc$(exeext) -Bstage1/ -B$(build_tooldir)/bin/" CFLAGS="$(WARN_CFLAGS) $(BOOT_CFLAGS)" LDFLAGS="$(BOOT_LDFLAGS)" libdir=$(libdir) STAGE_PREFIX=stage1/ LANGUAGES="$(LANGUAGES)"
$(MAKE) stage2
-if test $@ = bootstrap2-lean; then rm -rf stage1; else true; fi
- $(MAKE) CC="stage2/xgcc$(exeext) -Bstage2/" CFLAGS="$(WARN_CFLAGS) $(BOOT_CFLAGS)" LDFLAGS="$(BOOT_LDFLAGS)" libdir=$(libdir) STAGE_PREFIX=stage2/ LANGUAGES="$(LANGUAGES)"
+ $(MAKE) CC="stage2/xgcc$(exeext) -Bstage2/ -B$(build_tooldir)/bin/" CFLAGS="$(WARN_CFLAGS) $(BOOT_CFLAGS)" LDFLAGS="$(BOOT_LDFLAGS)" libdir=$(libdir) STAGE_PREFIX=stage2/ LANGUAGES="$(LANGUAGES)"
bootstrap3 bootstrap3-lean: force
- $(MAKE) CC="stage2/xgcc$(exeext) -Bstage2/" CFLAGS="$(WARN_CFLAGS) $(BOOT_CFLAGS)" LDFLAGS="$(BOOT_LDFLAGS)" libdir=$(libdir) STAGE_PREFIX=stage2/ LANGUAGES="$(LANGUAGES)"
+ $(MAKE) CC="stage2/xgcc$(exeext) -Bstage2/ -B$(build_tooldir)/bin/" CFLAGS="$(WARN_CFLAGS) $(BOOT_CFLAGS)" LDFLAGS="$(BOOT_LDFLAGS)" libdir=$(libdir) STAGE_PREFIX=stage2/ LANGUAGES="$(LANGUAGES)"
bootstrap4 bootstrap4-lean: force
- $(MAKE) CC="stage3/xgcc$(exeext) -Bstage3/" CFLAGS="$(WARN_CFLAGS) $(BOOT_CFLAGS)" LDFLAGS="$(BOOT_LDFLAGS)" libdir=$(libdir) STAGE_PREFIX=stage3/ LANGUAGES="$(LANGUAGES)"
+ $(MAKE) CC="stage3/xgcc$(exeext) -Bstage3/ -B$(build_tooldir)/bin/" CFLAGS="$(WARN_CFLAGS) $(BOOT_CFLAGS)" LDFLAGS="$(BOOT_LDFLAGS)" libdir=$(libdir) STAGE_PREFIX=stage3/ LANGUAGES="$(LANGUAGES)"
# Compare the object files in the current directory with those in the
# stage2 directory.
@@ -2816,14 +2965,14 @@ compare compare3 compare4 compare-lean compare3-lean compare4-lean: force
&& (cmp tmp-foo1 tmp-foo2 > /dev/null 2>&1 || echo $$file differs >> .bad_compare) || true; \
done
case "$@" in compare | compare-lean ) stage=2 ;; * ) stage=`echo $@ | sed -e 's,^compare\([0-9][0-9]*\).*,\1,'` ;; esac; \
- for dir in tmp-foo $(SUBDIRS); do \
+ for dir in tmp-foo intl $(SUBDIRS); do \
if [ "`echo $$dir/*$(objext)`" != "$$dir/*$(objext)" ] ; then \
for file in $$dir/*$(objext); do \
tail +16c ./$$file > tmp-foo1; \
tail +16c stage$$stage/$$file > tmp-foo2 \
&& (cmp tmp-foo1 tmp-foo2 > /dev/null 2>&1 || echo $$file differs >> .bad_compare) || true; \
done; \
- fi; \
+ else true; fi; \
done
-rm -f tmp-foo*
case "$@" in compare | compare-lean ) stage=2 ;; * ) stage=`echo $@ | sed -e 's,^compare\([0-9][0-9]*\).*,\1,'` ;; esac; \
@@ -2849,12 +2998,12 @@ gnucompare gnucompare3 gnucompare4 gnucompare-lean gnucompare3-lean gnucompare4-
(cmp --ignore-initial=16 $$file stage$$stage/$$file > /dev/null 2>&1 || echo $$file differs >> .bad_compare) || true; \
done
case "$@" in gnucompare | gnucompare-lean ) stage=2 ;; * ) stage=`echo $@ | sed -e 's,^gnucompare\([0-9][0-9]*\).*,\1,'` ;; esac; \
- for dir in tmp-foo $(SUBDIRS); do \
+ for dir in tmp-foo intl $(SUBDIRS); do \
if [ "`echo $$dir/*$(objext)`" != "$$dir/*$(objext)" ] ; then \
for file in $$dir/*$(objext); do \
(cmp --ignore-initial=16 $$file stage$$stage/$$file > /dev/null 2>&1 || echo $$file differs >> .bad_compare) || true; \
done; \
- fi; \
+ else true; fi; \
done
case "$@" in gnucompare | gnucompare-lean ) stage=2 ;; * ) stage=`echo $@ | sed -e 's,^gnucompare\([0-9][0-9]*\).*,\1,'` ;; esac; \
if [ -f .bad_compare ]; then \
@@ -2870,11 +3019,12 @@ gnucompare gnucompare3 gnucompare4 gnucompare-lean gnucompare3-lean gnucompare4-
# Copy the object files from a particular stage into a subdirectory.
stage1-start:
-if [ -d stage1 ] ; then true ; else mkdir stage1 ; fi
- -for dir in . $(SUBDIRS) ; \
+ -for dir in intl $(SUBDIRS) ; \
do \
if [ -d stage1/$$dir ] ; then true ; else mkdir stage1/$$dir ; fi ; \
done
-mv $(STAGESTUFF) stage1
+ -mv intl/*$(objext) stage1/intl
# Copy as/ld if they exist to stage dir, so that running xgcc from the stage
# dir will work properly.
-if [ -f as$(exeext) ] ; then $(LN_S) ../as$(exeext) stage1 ; else true ; fi
@@ -2882,7 +3032,9 @@ stage1-start:
-if [ -f collect-ld$(exeext) ] ; then $(LN_S) ../collect-ld$(exeext) stage1 ; else true ; fi
-rm -f stage1/libgcc.a
-cp libgcc.a stage1
- -if $(RANLIB_TEST) ; then $(RANLIB) stage1/libgcc.a; else true; fi
+ -if $(RANLIB_TEST_FOR_TARGET) ; then \
+ $(RANLIB_FOR_TARGET) stage1/libgcc.a; \
+ else true; fi
-for f in .. $(EXTRA_MULTILIB_PARTS); do if [ x$${f} != x.. ]; then \
cp stage1/$${f} . ; \
else true; \
@@ -2891,11 +3043,12 @@ stage1: force stage1-start lang.stage1
stage2-start:
-if [ -d stage2 ] ; then true ; else mkdir stage2 ; fi
- -for dir in . $(SUBDIRS) ; \
+ -for dir in intl $(SUBDIRS) ; \
do \
if [ -d stage2/$$dir ] ; then true ; else mkdir stage2/$$dir ; fi ; \
done
-mv $(STAGESTUFF) stage2
+ -mv intl/*$(objext) stage2/intl
# Copy as/ld if they exist to stage dir, so that running xgcc from the stage
# dir will work properly.
-if [ -f as$(exeext) ] ; then $(LN_S) ../as$(exeext) stage2 ; else true ; fi
@@ -2903,7 +3056,9 @@ stage2-start:
-if [ -f collect-ld ] ; then $(LN_S) ../collect-ld$(exeext) stage2 ; else true ; fi
-rm -f stage2/libgcc.a
-cp libgcc.a stage2
- -if $(RANLIB_TEST) ; then $(RANLIB) stage2/libgcc.a; else true; fi
+ -if $(RANLIB_TEST_FOR_TARGET) ; then \
+ $(RANLIB_FOR_TARGET) stage2/libgcc.a; \
+ else true; fi
-for f in .. $(EXTRA_MULTILIB_PARTS); do if [ x$${f} != x.. ]; then \
cp stage2/$${f} . ; \
else true; \
@@ -2912,11 +3067,12 @@ stage2: force stage2-start lang.stage2
stage3-start:
-if [ -d stage3 ] ; then true ; else mkdir stage3 ; fi
- -for dir in . $(SUBDIRS) ; \
+ -for dir in intl $(SUBDIRS) ; \
do \
if [ -d stage3/$$dir ] ; then true ; else mkdir stage3/$$dir ; fi ; \
done
-mv $(STAGESTUFF) stage3
+ -mv intl/*$(objext) stage3/intl
# Copy as/ld if they exist to stage dir, so that running xgcc from the stage
# dir will work properly.
-if [ -f as$(exeext) ] ; then $(LN_S) ../as$(exeext) stage3 ; else true ; fi
@@ -2924,7 +3080,9 @@ stage3-start:
-if [ -f collect-ld$(exeext) ] ; then $(LN_S) ../collect-ld$(exeext) stage3 ; else true ; fi
-rm -f stage3/libgcc.a
-cp libgcc.a stage3
- -if $(RANLIB_TEST) ; then $(RANLIB) stage3/libgcc.a; else true; fi
+ -if $(RANLIB_TEST_FOR_TARGET) ; then \
+ $(RANLIB_FOR_TARGET) stage3/libgcc.a; \
+ else true; fi
-for f in .. $(EXTRA_MULTILIB_PARTS); do if [ x$${f} != x.. ]; then \
cp stage3/$${f} . ; \
else true; \
@@ -2933,11 +3091,12 @@ stage3: force stage3-start lang.stage3
stage4-start:
-if [ -d stage4 ] ; then true ; else mkdir stage4 ; fi
- -for dir in . $(SUBDIRS) ; \
+ -for dir in intl $(SUBDIRS) ; \
do \
if [ -d stage4/$$dir ] ; then true ; else mkdir stage4/$$dir ; fi ; \
done
-mv $(STAGESTUFF) stage4
+ -mv intl/*$(objext) stage4/intl
# Copy as/ld if they exist to stage dir, so that running xgcc from the stage
# dir will work properly.
-if [ -f as$(exeext) ] ; then $(LN_S) ../as$(exeext) stage4 ; else true ; fi
@@ -2945,7 +3104,9 @@ stage4-start:
-if [ -f collect-ld$(exeext) ] ; then $(LN_S) ../collect-ld$(exeext) stage4 ; else true ; fi
-rm -f stage4/libgcc.a
-cp libgcc.a stage4
- -if $(RANLIB_TEST) ; then $(RANLIB) stage4/libgcc.a; else true; fi
+ -if $(RANLIB_TEST_FOR_TARGET) ; then \
+ $(RANLIB_FOR_TARGET) stage4/libgcc.a; \
+ else true; fi
-for f in .. $(EXTRA_MULTILIB_PARTS); do if [ x$${f} != x.. ]; then \
cp stage4/$${f} . ; \
else true; \
diff --git a/gcc/PROJECTS b/gcc/PROJECTS
index d5b53404521..6ff7a0557b0 100644
--- a/gcc/PROJECTS
+++ b/gcc/PROJECTS
@@ -250,18 +250,6 @@ redundant. Constraints might permit a decrement and branch
instruction that checks zeroness to be used when the user has
specified to exit if negative.
-* Smarter reload pass.
-
-The reload pass as currently written can reload values only into registers
-that are reserved for reloading. This means that in order to use a
-register for reloading it must spill everything out of that register.
-
-It would be straightforward, though complicated, for reload1.c to keep
-track, during its scan, of which hard registers were available at each
-point in the function, and use for reloading even registers that were
-free only at the point they were needed. This would avoid much spilling
-and make better code.
-
* Change the type of a variable.
Sometimes a variable is declared as `int', it is assigned only once
diff --git a/gcc/README.C4X b/gcc/README.C4X
index c8c5f22a8d4..994e67d4cc9 100644
--- a/gcc/README.C4X
+++ b/gcc/README.C4X
@@ -23,7 +23,7 @@ not currently included as part of the binutils package, due to the
many hacks required to be compatible with TI's kludged COFF
implementation, and the binutils not being designed for 32-bit bytes.
Patches against binutils-2.7.2 can be obtained from
-ftp://ongaonga.chch.cri.nz/pub/c4x. This site also has patches for
+http://www.elec.canterbury.ac.nz/c4x. This site also has patches for
the GNU debugger (GDB), incoporating a cycle accurate simulator that
can display profiles and histories of code execution, detailing
pipeline conflicts etc.
@@ -35,8 +35,8 @@ configure GCC for both the C3x and C4x. Then use the -m30 option to
generate code for the C30 or -m40 (the default) for the C40.
-Further installation notes and other optimization patches for GCC can
-also be obtained from ftp://ongaonga.chch.cri.nz/pub/c4x.
+Further installation notes and other optimization patches for the C4x
+target can also be obtained from http://www.elec.canterbury.ac.nz/c4x.
A Majordomo mailing list, gcc_c40@atlantek.com.au, exists to discuss
@@ -45,4 +45,4 @@ subscribe send a message with `subscribe gcc_c40' in the body to
majordomo@atlantek.com.au.
-Michael Hayes, 16 Sep 98
+Michael Hayes, 26 Nov 98
diff --git a/gcc/README.NS32K b/gcc/README.NS32K
index 93c5beaef54..8e3610e33b5 100644
--- a/gcc/README.NS32K
+++ b/gcc/README.NS32K
@@ -1,6 +1,55 @@
This file describes the implementation notes of the GNU C Compiler for
the National Semiconductor 32032 chip (and 32000 family).
+Much of this file was obsolete. It described restrictions caused by
+bugs in early versions of of the ns32032 chip and by bugs in sequent
+assemblers and linkers of the time.
+
+Many (all?) of the chip bugs were fixed in later revisions and
+certainly fixed by later chips in the same series (ns32332 and
+ns32532).
+
+Conditional code to support sequent assembler and/or linker restrictions
+has not been removed deliberately, but has probably not been tested in
+a *very* long time.
+
+Support for one sequent assembler bug has *not* been retained.
+It was necessary to say:
+
+ addr _x,rn
+ cmpd _p,rn
+
+rather than:
+
+ cmpd _p,@_x
+
+
+This used to be forced by the use of "rmn" register constraints rather
+than "g". This is bad for other platforms which do not have this
+restraint.
+
+It is likely that there are no Balance 8000's still in operation, but
+if there are and the assembler bug was never fixed then the easiest
+way to run gcc would be to also run gas.
+
+The code required by the sequent assembler is still generated when the
+-fpic flag is in effect and this is forced by the appropriate
+definition of LEGITIMATE_PIC_OPERAND_P. If support for the old sequent
+assembler bug is required, then this could be achieved by adding the
+test from LEGITIMATE_PIC_OPERAND to the GO_IF_LEGITIMATE_ADDRESS
+definition. Of course, this should be conditional on something in the
+sequent.h config file.
+
+The original contents of this file appear below as an historical note.
+SEQUENT_ADDRESS_BUG mentioned below has been replaced by
+INDEX_RATHER_THAN_BASE. Note that merlin.h still defines
+SEQUENT_ADDRESS_BUG even though it is not used anywhere. Since it has
+been like this for a long time, presumably either the
+SEQUENT_ADDRESS_BUG is not required for the merlin, or no one is using
+gcc on the merlin anymore.
+
+HISTORICAL NOTE
+
The 32032 machine description and configuration file for this compiler
is, for NS32000 family machine, primarily machine independent.
However, since this release still depends on vendor-supplied
diff --git a/gcc/README.RS6000 b/gcc/README.RS6000
index fde55b01782..24cc8ba8e72 100644
--- a/gcc/README.RS6000
+++ b/gcc/README.RS6000
@@ -1,4 +1,24 @@
- AIX 4.3 assembler
+ AIX 4.3 archive libraries
+
+AIX 4.3 utilizes a new "large format" archive to support both 32-bit and
+64-bit object modules. The routines provided in AIX 4.3.0 and AIX 4.3.1
+to parse archive libraries did not handle the new format correctly. These
+routines are used by GCC and result in error messages during linking such
+as "not a COFF file". The version of the routines shipped with AIX 4.3.1
+should work for a 32-bit environment. The "-g" option of the archive
+command may be used to create archives of 32-bit objects using the
+original "small format". A correct version of the routines is shipped
+with AIX 4.3.2.
+
+
+ AIX 4.3.2 binder
+
+The AIX 4.3.2.1 linker (bos.rte.bind_cmds Level 4.3.2.1) will dump core
+with a segmentation fault when invoked by any version of GCC. A fix for
+APAR IX87327 will be available from IBM Customer Support.
+
+
+ AIX 4.3.0 assembler
The AIX 4.3.0.0 assembler generates incorrect object files if the ".bs"
pseudo-op references symbols in certain sections. If GCC is invoked with
diff --git a/gcc/README.g77 b/gcc/README.g77
index f22f1799c35..d0f5a4bc27b 100644
--- a/gcc/README.g77
+++ b/gcc/README.g77
@@ -18,7 +18,7 @@ g77, while `[egcs]' denotes egcs-only information.
The email address to which bugs are to be reported is either
-[FSF] <fortran@gnu.org> or [egcs] <egcs-bugs@cygnus.com>.
+[FSF] <fortran@gnu.org> or [egcs] <egcs-bugs@egcs.cygnus.com>.
* *DO NOT* send any email (reporting bugs, asking questions, etc.) to
either of these addresses without *first* reading the g77 documentation.
diff --git a/gcc/SERVICE b/gcc/SERVICE
index 46441675fd0..6404b7c6a13 100644
--- a/gcc/SERVICE
+++ b/gcc/SERVICE
@@ -35,10 +35,28 @@ have nothing to go by. Please put each e-mail address inside "<>".
Please put nothing else inside "<>". Thanks!
For a current copy of this directory, or to have yourself listed, ask:
- gnu@prep.ai.mit.edu
+ gnu@gnu.org
** Please keep the entries in this file alphabetical **

+Alc?ve <infos@alcove.fr>
+12 place Indira Gandhi
+92230 Gennevilliers
+France
+
+http://www.alcove.fr
+T?l.: +33 1 47 33 82 84
+Fax: +33 1 47 33 76 98
+
+Alc?ve offers a comprehensive range of corporate-quality
+Free Software related solutions, with technical support
+via telephone, fax or email and remote system management.
+We also offers consulting and training.
+
+Rates approximately 3000FF per day, depending on the job.
+
+Updated: 1998-09-09
+
Altrasoft <info@altrasoft.com>
4880 Stevens Creek Blvd., Suite 205
San Jose, CA 95129-1034
@@ -98,53 +116,49 @@ Rates approximately 15 USD per hour.
Updated: 1997-05-25

-Joseph Arceneaux <jla@ai.mit.edu>
-PO Box 460633 http://www.samsara.com/~jla
-San Francisco, CA 94146-0633
+Joseph Arceneaux <joe@arceneaux.com>
+307 Chattanooga St. http://www.arceneaux.com
+San Francisco, CA 94114
+1 415 648 9988
-+1 415 285 9088
-
-Recently led the project making Wells Fargo Bank the first to provide
-secure customer account access over the Internet.
-Former FSF staffmember. Performed X11 implementation of Emacs version
-19, designed and implemented WYSIWYG Emacs. Installed and
-administered FSF network. Maintainer of GNU indent. Over 15 years
-experience with Unix and other systems, from writing ROM monitors to
-UI design and system administration.
+I am a former FSF staffmember who made Wells Fargo Bank the first bank
+to provide secure banking over the Internet. I have 20 years
+experience with various computer systems. I performed the X11
+implementation of Emacs version 19, and designed and implemented
+WYSIWYG features of Emacs. I also installed and administered FSF
+network. Maintainer of GNU indent.
I provide installation, porting, debugging and customization or
-development of GNU and other Unix software. I also design and
-implement free software projects and consult on software engineering
-and systems design. Handholding and teaching services are also
-available as well as things like LAN and compute--infrastructure design.
+development of GNU and other software. I also design and implement
+free software projects and consult on software engineering, security,
+and intranet design.
Time and material rates around $150 USD per hour, depending upon the
particular job. I am also very interested in fixed-bid jobs. For
selected non-profit organizations with worthy goals, I work for free.
-Updated: 1995-10-17
+Updated: 1998-06-24

-Gerd Aschemann <Aschemann@Informatik.TH-Darmstadt.de>
+Dipl.-Inform. Gerd Aschemann <Aschemann@Informatik.TU-Darmstadt.de>
Osannstr. 49
D-64285 Darmstadt
Tel.: +49 6151 16 2259
-http://www.informatik.th-darmstadt.de/~ascheman/
+http://www.informatik.tu-darmstadt.de/VS/Mitarbeiter/Aschemann/
-- System Administrator (UNIX) at CS Department, TU Darmstadt, Germany
-- 17 years experience with CS, System administration on different platforms
-- 10 years with UNIX/Networking/FreeWare/GNU/X11
-- 8 years organizer of Operating Systems and Distributed Systems courses
+- System Administrator (UNIX and NT) at CS Department, TU Darmstadt, Germany
+- 18 years working in the CS field, System administration on different platforms
+- 12 years with UNIX/Networking/FreeWare/GNU/X11
+- 9 years courses on Operating Systems and Distributed Systems
- Lectures on System and Network Administration
-- Platforms: Solaris, SunOS, Ultrix, OSF1, HP-UX, Linux, FreeBSD, AIX, SCO
-- Distributed Platforms and Information Systems (CORBA, WWW, Java, FTP)
+- Platforms: Solaris, Linux, SunOS, Ultrix, HP-UX, Digital Unix, AIX, SCO, FreeBSDs
+- Distributed Platforms and Information Systems (CORBA, WWW, Java)
- Experience with parallel environments (Connection Machine, Meiko, Parsytec)
- Consultant
-Rates are at 130,-- DM (~80 US$) per hour minimum, depending on the job.
+Rates are at 150,-- DM (~85 US$) per hour minimum, depending on the job.
I am willing to travel for sufficiently large jobs.
-Updated: 1997-05-07
+Updated: 1998-07-23

Basis Technology Corp.
@@ -181,7 +195,7 @@ GNU Contributions:
Contacts:
Carl Hoffman, Steve Cohen, or Karen Watts
-Updated: 1997-05-07
+Updated: 1998-07-23

Laurent Bernardin
16, rue Dicks
@@ -196,48 +210,68 @@ Expertise: C, C++, Java, Motif, X, Unix administration, network security
Rates: ~60 US$ / hour (Flux 2000.-)
-Updated: 1997-05-07
+Updated: 1998-07-23
+
+Dean Brettle Computer Consulting
+
+<dean@brettle.com>
+http://www.brettle.com/
+
+7485 Rush River Drive
+Suite 710-193
+Sacramento, CA 95831
+916-422-8129
+
+I provide development, technical support, and training for free software
+and open source systems including GNU/Linux, the GNU development suite,
+Tcl/Tk, Emacs, and the GIMP.
+
+I have over 9 years experience building and maintaining systems ranging
+from computed tomography systems to airborne sensor control systems --
+all with free software.
+
+Rates range from $65.00/hr to $72.50/hr USD, depending upon work
+location. I am also willing to work on fixed price contracts.
+
+Updated: 1998-07-07

Philip Brown
<phil@mitre.org>
(703) 893-8967 (prefer email)
-Northern-VA, D.C. Area
-Rates: $40/Hr; less for educational or charitable organizations
+Northern-VA, D.C. Area (world-wide via internet)
+Rates: $45/Hr + extra for site visit; less for educational or charitable organizations
Systems Supported:
- HP9000/7xx running HP/UX 8.07 - 10.X
- IBM RS6000 running AIX 3.2.X
- Also SGI/Indy and Sun/Sparcs
+
+ Sun boxes running Solaris 2.5-up
+ HP9000s running HP/UX 8.07 - 10.X
+ IBM RS6000 running AIX 3.2.X-up
+ Also SGI/Indy
Software Supported:
- Most all FSF (Gnu) software
- esp. GCC, Emacs, Binutils, GS, etc...
+ Most all FSF (Gnu) software
+ esp. GCC, GDB, Emacs, Binutils, GS, et al...
Statement:
I'd be more than happy to assist anyone in my area with acquiring,
installing, and configuring any FSF tools/utilities on any of the
above systems. I'm also willing to work with other UNIX systems not
- listed above. In addition, I'd be happy to share my many years of
+ listed above. In addition, I'm glad to share my many years of
experience with anyone having difficulty using or configuring these
tools. I've been installing and using them for about 5 years now
and I'll swear by their quality and the people/principles that made
them available.
- Phil Brown
+ Phil Brown
-Updated: 1997-05-07
+Updated: 1998-07-23

James Craig Burley
97 Arrowhead Circle
Ashland, MA 01721-1987
-508 881-6087, -4745
-(Please call only between 0900-1700 Eastern time, and only if you
-are prepared to hire me -- ask me to help you for free only
-via email, to which I might or might not respond.)
-Email: <burley@gnu.org> --preferred--
- <burley@cygnus.com>
- <burley@world.std.com>
+(Email and postal mail contacts only, please.)
+Email: <craig@jcb-sc.com>
Expertise:
Compiler Internals (author of GNU Fortran, for example)
@@ -248,63 +282,71 @@ Expertise:
Debugging (often asked to help debug Other People's Code)
Documentation (authored many books and ran a few doc projects)
Extensive experience with a variety of operating systems, hardware,
- languages, and so on
+ languages, and so on
Rate: $100/hour -- willing to consider flat-fee arrangements
-Updated: 1997-05-07
+Updated: 1999-02-01

-Thomas Bushnell, n/BSG <thomas@gnu.org>
+Thomas Bushnell, BSG <thomas@gnu.org>
Becket House
66 Highland Ave. No. 8
Somerville, MA 02143
(617) 623-0654
-
All GNU software: Installation, customization, answering simple or
- complex questions, bug fixing, extension.
+ complex questions, bug fixing, extension.
-Experience: I have done Unix and GNU programming for several years,
- I am the primary author of the Hurd (which provides most
- kernel related facilities for the GNU OS).
+Experience: I have done Unix and GNU programming for many years.
+ I am the primary author of the Hurd (which provides most
+ kernel related facilities for the GNU OS).
I am easily available in the Cambridge/Boston area; work via email.
I am willing to travel for sufficiently large jobs.
Rates: $100/hr, negotiable, less for non-profit organizations.
-Updated: 1997-05-07
+Updated: 1998-07-27

- C2V Michel Delval <mfd@ccv.fr>
- 82 bd Haussmann Jean-Alain Le Borgne <jalb@ccv.fr>
- 75008 Paris
- France
- Tel (33 1) 40.08.07.07
- Fax (33 1) 43.87.35.99
- Compuserve 100413,1012
- http://c2v.com
-
- We offer source or source+binary distribution, installation, training,
- maintenance, technical support, consulting, specific development and
- followup on the GNU software development environment: Emacs, gcc/g++,
- binutils, gas, gdb.
-
- Experience: adapted gcc, gas and binutils to work as cross-development
- tools for the Thomson D950 DSP chip: GCC parser and typing system
- have been augmented to allow the manipulation of variables located in
- separated memory spaces. Porting on new platforms, and professionally
- developing software with the GNU tools in the Unix/X11 environment
- since they were first available.
-
- Rates: from 2000 FF/day to 150 000 FF/year, 40% discount for
- educational institutions, add taxes and expenses. Ask for list.
-
-Updated: 1997-05-09
+C2V Michel Delval <mfd@c2v.com>
+82 bd Haussmann Jean-Alain Le Borgne <jalb@c2v.com>
+75008 Paris
+France
+Tel (33 1) 40.08.07.07
+Fax (33 1) 43.87.35.99
+Compuserve 100413,1012
+http://www.c2v.com/freesoft.htm
+e-mail: <consult@c2v.com>
+
+Services: we offer source or source+binary distribution,
+installation, training, maintenance, technical support,
+consulting, specific development and followup on the GNU software
+development environment: Emacs, gcc/g++, binutils, gas, gdb.
+
+Porting on new platforms, and professionally developing software
+with the GNU tools in the Unix/X11 environment since they were
+first available.
+
+Experience: GNU C Compilation toolchain for the SGS-Thomson D950
+and ST20 DSP chips.
+
+GNU C compilation toolchain (cross-compiler, compiler, linker,
+assembler, debugger) for SparcV7 ERC32 based space systems
+(Sextant Avionique / Alcatel Espace).
+
+Feasability study, analysis and prototyping of a complete
+compilation toolchain based on the GNU programming tools for the
+CSEM RISC microprocessor family.
+
+Rates: from 2000 FF/day to 150 000 FF/year, 40% discount for
+educational institutions, add taxes and expenses. Ask for list.
+
+Updated: 1998-07-23

Bruce Dawson - <jbd@codemeta.com>
CodeMeta, Inc.
-Epping, NH USA
-800-468-8750
+Manchester, NH USA
+800-354-2209
Specializing in GNU tools such as guile, CVS, gnats, bash, gawk, fileutils...
@@ -320,7 +362,7 @@ Rate: $75/hour or per quote.
http://www.codemeta.com
-Updated: 1997-05-09
+Updated: 1998-07-23

Kevin Cosgrove <kevinc@dOink.COM>
@@ -335,52 +377,53 @@ Kevin Cosgrove <kevinc@dOink.COM>
Updated: 1997-05-07

Couvares Consulting
-211 W. Gilman St., Suite 3W
-Madison, WI 53703 USA
-Phone: (608) 256-6201
-EMail: <couvares@family.hampshire.edu>
+1312 Chandler St.
+Madison, WI 53715
+Phone: (608) 256-6901
+Email: <couvares@poboxes.com>
Contact: Peter F. Couvares
-Type of support: We offer phone/email support, installation, ongoing
- administration, training, programming, and specialized consulting for
- free software and other UNIX systems.
+Type of support: We offer phone/email support, installation, systems
+integration, systems programming, training, and specialized consulting
+services for free software in UNIX and NT environments.
-Sample prices: USD75/hour commercial, 40/hour nonprofit, sliding scale
-for individuals.
+Sample prices: USD100/hour commercial, 50/hour non-profit, sliding
+scale for individuals.
-Updated: 1996-12-04
+Updated: 1998-07-23

-Stuart Cracraft <cracraft@ai.mit.edu>
-25682 Cresta Loma
-Laguna Niguel, CA, 92677, USA
-GNUline: 714-308-7900
-Website: http://www.earthlink.net/~cracraft/index.html
-Rate: $90/hour
+Stuart Cracraft <cracraft@ai.mit.edu>
+P.O. Box 6752
+Laguna Niguel, CA, 92607, USA
+Phone: 714-308-7900
+Website: http://home.earthlink.net/~cracraft/index.html
+Rate: $50/hour, and as appropriate for the project.
+
Consultation topics:
Entire GNU suite - porting, compilation, installation,
-user-training, administrator-training
-Method: telephone line support, call-in via modem to your site,
-work over the Internet, or in-person visit.
-
-Experience: supporting GNU since the mid-1980's, coordinator
-of GNU Chess (original author), GNU Shogi, GNU Go. Ported GNU Emacs
-to Solaris (System V Release 4). Expertise in C, Emacs Lisp, Perl,
-Expect, Oracle, Informix, SunOS, Solaris, NIS, NFS.
+user-training, administrator-training.
-Customized programming also available.
+Method: via any combination of telephone, dialup, Internet, in-person, email.
-Updated: 1997-05-07
+Experience: supporting GNU since project inception, original port of
+GNU Emacs to Sun Solaris, original author of GNU Emacs online tutorial.
+Expertise in C, Emacs Lisp, Perl, Expect, Oracle, Informix, SunOS, Solaris,
+NIS, NFS, system-monitoring via paging. Unix System and Database
+administration or development. Coordinator of the GNU mascots: GNU Chess,
+GNU Shogi, GNU Go.
+
+Updated: 1998-07-23

Noel Cragg <noel@cyclic.com>
6244 Aberdeen Av
Goleta CA 93117
-805-899-4695
+805-964-1892
I'll do installation, debugging, and extension of GNU tools on a
contract basis. CVS and configuration management are my current
specialties. Rate: $75/hour or per-project negotiated fee.
-Updated: 1997-05-07
+Updated: 1998-07-22

Cygnus Solutions
<info@cygnus.com>
@@ -414,37 +457,46 @@ Cygnus Solutions contacts:
Updated: 1997-09-02 by rms

Marcus G. Daniels <marcusd@gnu.org>
-31060 S. Kaufman Rd. <marcus@tdb.com>
-Canby, OR 97013-9520 <marcus@sysc.pdx.edu>
-(503) 651-2694
+1399 Hyde Park Road <mgd@santafe.edu>
+Santa Fe, NM 87501 <marcus@tdb.com>
+(505)984-8800 x267
I can customize, extend, port, and repair many types of free software.
-I maintain the CLISP Common Lisp implementation and contribute to
-several GNU packages (e.g. Emacs). Ten years of C and Unix
-experience. Consulting rates start at $40 US/hr.
+I have software maintenance experience (e.g. CLISP, Swarm), and have
+contributed to several GNU packages (e.g. Emacs). Twelve years of C
+and Unix experience. Consulting rates start at $60 US/hr.
-Updated: 1997-05-07
+Updated: 1998-07-22

-Edgar Der-Danieliantz (Danielyan) <edd@acm.org>
-P.O. Box 10 FAX +374 2 28 50 82
-Yerevan 375009
-ARMENIA
+DSS Distributed Systems Software, Inc.
+7500 Abercrombie Dr., Suite 103 <dss@dss.bc.ca>
+Richmond, British Columbia V6Y 3J9 http://www.dss.bc.ca
+CANADA (604) 270-9559
- Support for GCC, X Window System, WWW, Tcl/Tk, logic programming,
- Internet security, TCP/IP.
+GNU-related services:
+ We specialize in support for GCC (mainly C and C++), including porting,
+ retargeting, and customizing.
+ Also, GNU and other free software that falls within our areas of expertise.
- Experience:
- OS's: 4.4BSD, SVR4.2, FreeBSD, SCO, Solaris, UnixWare.
- Languages: C, C++, Objective C, Pascal, Tcl/Tk, Perl, Prolog
- Platforms: Intel, SPARC, Mac, VAX, NeXT.
+Expertise:
+ DSS provides software design, implementation, and consulting services.
- Rates: Depending on type of work, approx. $20/hour. Contact for more
- information.
- Negotiable for individuals and non-profit organizations.
- FREE for individuals who can't pay. Your 'Thanks!' just enough! :-)
- Payment by international wire transfer or check.
+ Distributed systems:
+ o Client/Server architectures, computer networking, communication
+protocols
+ o Directory systems, including X.500 and LDAP
+ o High-performance and special-purpose distributed systems and databases:
+ scalability, reliability, availability, transactions
+ o Computer systems performance analysis
-Updated: 1997-05-07
+ Compilers, translators, and interpreters, including "small" and
+ special-purpose languages
+
+Rates:
+ Consulting rates are $85-$300 (Canadian dollars) per hour, plus
+ applicable taxes. Fixed-cost projects are also possible.
+
+Updated: 1998-06-24

Echo Labs <echo@iinet.net.au>
29 Weld St, http://www.iinet.net.au/~echo/
@@ -459,22 +511,51 @@ based on more traditional technologies. Internet/intranet and data
communications solutions, for all platforms are undertaken. GUI
front-ends done quickly.
-While typically involved in engineering and technical area, any
-GNU/freeware software will be supported.
+While typically involved in engineering and technical areas, any
+GNU/Open Source software will be supported.
For further details see: http://www.iinet.net.au/~echo/
-Experience: 12+ years C/Unix, Sun, SCO, Linux, Win/NT.
+Experience: 13+ years C/Unix, Sun, SCO, Linux, Win/NT.
+ Secure WWW servers (Apache SSL), Ecommerce solutions.
Systems programming, device drivers, hardware interfacing.
- GNU tools/utilities,
- Embedded & realtime systems, software, firmware, hardware.
+ GNU tools/utilities, Embedded & realtime systems.
Communications protocols and implementation.
Degrees: BAppSc (CS), Curtin University, Perth
Rates: AUS $50-75/hr neg.
-Updated: 1997-05-09
+Updated: 1998-07-23
+
+Andrew Ford <A.Ford@ford-mason.co.uk>
+Ford & Mason Ltd. http://www.ford-mason.co.uk/aford/
+South Wing, Compton House Tel: +44 1531 829900
+Compton Green, Redmarley Fax: +44 1531 829901
+Gloucester, United Kingdom
+
+Experience:
+ * 18 years in the computer industry
+ * 14 years Unix/C programming experience
+ * 10 years experience with GNU software
+ * 4 years web experience (author of the first book about setting up a web site)
+
+Services offered:
+ * Installing and customizing GNU and other free software
+ * GNU Emacs customization and emacs lisp coding
+ * Perl module development
+ * TeX and LaTeX macro development
+ * software development (especially in Perl, C, C++)
+ * web site setup (with Apache)
+ * web application development with mod_perl
+ * translation (German -> English)
+ * writing documentation
+
+Rates:
+ around 60 pounds/hour (approx US$80/hour) plus expenses
+ less for charities and non-profit organization
+
+Updated: 1998-06-24

Free Software Association of Germany
Michaela Merz
@@ -498,27 +579,28 @@ response team) : 300 US$ / hour
Entered: 1994-04-14

-Noah Friedman <friedman@prep.ai.mit.edu>
-1111 W. El Camino Real #109-331
-Sunnyvale, CA 94087
+Noah Friedman <friedman@splode.com>
+4463 Moraga Avenue
+Oakland, CA 94611
(permanent)
Author of several Emacs Lisp packages and parts of Emacs, as well as
numerous network and unix system utilities. Co-maintained GNU Texinfo and
-Autoconf for a couple of years. Experienced unix systems administrator.
+Autoconf for a couple of years. Experienced unix systems engineer.
FSF employee Feb 1991--Sep 1994.
I can perform installation, porting, and enhancement of all GNU software
-and any other free software, including the Linux kernel; system design and
-administration for unix-type systems and IP networks; and I am willing to
-provide handholding for shell programming, Emacs Lisp development, and
-version control systems such as RCS and CVS.
-
-Fees negotiable, averaging $75-$100/hour. I can work in the California bay
-area or anywhere accessible on the Internet. For larger jobs I may be
+and any other free software, especially for Linux/GNU systems; design
+high-capacity hardware-redundant servers for production environments;
+provide consulting on the use of version control management with CVS; and I
+am willing to provide handholding for shell programming and Emacs Lisp
+development.
+
+Fees negotiable, averaging $100-$150/hour. I can work in the California
+bay area or anywhere accessible on the Internet. For larger jobs I may be
willing to travel.
-Updated: 1997-05-08
+Updated: 1998-06-24

Ronald F. Guilmette <rfg@monkeys.com>
RG Consulting
@@ -561,7 +643,30 @@ Other qualifications:
Rates: Variable depending upon contract duration. Call for quote.
-Updated: 1997-05-07
+Updated: 1998-07-10
+
+Kevin Harris <gordie@cyberramp.net>
+Dallas, Texas USA
+
+Entire GNU suite - porting, compilation, installation and maintenance
+Platforms: Any unix variant (AIX, *BSD, Digital Unix, HP/UX, GNU/Linux,
+Solaris, SunOS, et al)
+
+Method: Call-in via modem to your site, telnet, or on-site.
+
+Rates: US $0-75/hour depending upon client requirements
+
+Note: If you are an individual installing GNU software on your personal Linux
+system, or are a non-profit organization, my hourly rate for you is simple:
+FREE. You just have to pay for the phone calls and/or travel/lodging, if any is
+required.
+
+Experience: I've used, supported and maintained GNU software on numerous unix
+systems since 1989.
+
+I have extensive experience in C, Emacs Lisp, Perl and general unix systems.
+
+Updated: 1998-06-24

Michael P. Deignan
Ideamation, Inc.
@@ -574,49 +679,30 @@ Rate: Varies depending on complexity of task.
Hourly and fixed-rate contracts are available.
Programs Supported: All
-Updated: 1997-05-07
-
-Interactive Information Limited
-
-Interactive Information Limited is an Edinburgh-based company that
-specialises in WWW services and support for using the Internet for
-marketing.
-
-Our staff have many years experience in using, and developing lisp packages
-within, Emacs, and in using other GNU/Unix tools, particularly under public
-domain UNIXes.
-
-We can provide services throughout the UK, at any level from general
-consultancy through fetching, installing and customising software to
-bespoke programming. Fees would be in the range #300 - #600 per day,
-depending primarily on the size of the job.
-
-You can contact us
- by email: <enquire@interactive.co.uk>
- by phone: 0370 30 40 52 (UK)
- (+44) 370 30 40 52 (International)
- by post: 3, Lauriston Gardens,
- Edinburgh EH3 9HH
- Scotland
-
-Entered: 1997-05-09
+Updated: 1998-07-23

-Scott D. Kalter <sdk@twinsun.com>
-2032 Corral Canyon
-Malibu, CA 90265-9503
-Home: (310) 456-0254
-
-Very familiar with all levels of Elisp programming. Taught Emacs use
-and customization in universities and industry. Extensive
-troubleshooting and user support experience. Co-developed an
-object-oriented extension to Elisp (Eoops) that can be used for
-projects. Extensive Elisp level modification for rapid prototyping of
-designs used in groupware research. This includes the development of
-an infrastructure to support multiple, communicating Emacs processes.
-
-Prefer e-mail communication to telephone calls.
-
-Updated: 1997-05-07
+ Interactive Information Limited is an Edinburgh-based company that
+ specialises in WWW services and in particular support for accessing
+ existing systems and information.
+
+ Our staff have many years experience in using, and developing lisp packages
+ within, Emacs, and in using other GNU/Unix tools, particularly under public
+ domain UNIXes.
+
+ We can provide services throughout the UK, at any level from general
+ consultancy through fetching, installing and customising software to
+ bespoke programming. Fees would be in the range #300 - #600 per day,
+ depending primarily on the size of the job.
+
+ You can contact us
+ by email: <enquire@interactive.co.uk>
+ by phone: 0370 30 40 52 (UK)
+ (+44) 370 30 40 52 (International)
+ by post: 3, Lauriston Gardens,
+ Edinburgh EH3 9HH
+ Scotland
+
+Updated: 1998-07-24

Kaman Sciences Corporation
Griffiss Business & Technology Park
@@ -645,12 +731,12 @@ Updated: 1997-05-07
Joseph R. Kiniry <kiniry@cs.caltech.edu>
Caltech Mailstop 256-80 http://www.cs.caltech.edu/~kiniry/
Pasadena, CA 91125 <jrk@metagenesis.com>
-Phone: 818-395-4840
-Fax: 818-792-4257
+Phone: 626-395-4840
+Fax: 626-792-4257
-Long-term high-level consultant in a variety of domains. See
-http://www.cs.caltech.edu/~kiniry/resume.html for more information on
-professional and academic background.
+Long-term high-level consultant with four advanced degrees in a
+variety of domains. See http://www.cs.caltech.edu/~kiniry/resume.html
+for more information on professional and academic background.
I provide installation, porting, debugging, customization, design, and
development of GNU and other UNIX and non-UNIX software. I am or have
@@ -658,7 +744,7 @@ been a certified developer with Microsoft, SunSoft, NeXT, and Amiga.
I have a great deal of development and management experience and an
extremely broad background which contributes to my excellent system
integration capabilities. I have a special expertise and conduct
-research in distributed object technologies.
+research in distributed systems and component/object technologies.
Time and material rates for local work vary regionally, but are
currently $250 per hour on the west coast. Other rates apply for
@@ -666,20 +752,16 @@ long-term jobs (day rates, travel, etc.) and remote work (usually 1/2
fee). I am interested in fixed-bid jobs and will work for lower rates
for non-profit organizations and educational institutions.
-Updated: 1997-05-07
+Updated: 1998-08-27

Bradley M. Kuhn
-<bkuhn@acm.org>
+<bkuhn@ebb.org>
http://www.ebb.org/bkuhn
-I am available for Unix system administration consulting, including but not
-limited to installation, configuration and integration of GNU tools and other
-copy-lefted software such as GNU/Linux and the various distributions of
-GNU/Linux.
-
-I am particularly skilled at integration of GNU and other copy-lefted software
-into new environments that have not used such tools in the past, and porting
-the GNU software to new Unix-based platforms.
+I am available for Unix system administration and software development
+consulting, including but not limited to installation, configuration and
+integration of GNU tools and other copy-lefted software such as GNU/Linux
+and the various distributions of GNU/Linux.
Please visit my homepage for more information on my background and skills. My
resume is also available there.
@@ -688,20 +770,16 @@ I am available for both 1099 (preferred) and W2 on-site contracting in the
Cincinnati, OH, USA metropolitan area, as well as remote consulting via dialup
or Internet connection anywhere in the USA. I have no interest in permanent
relocation at this time.
-
+
My rate varies greatly between $25-$40/hour, depending on the circumstances.
Rates for non-profit organizations are substantially lower, and possibly free.
-Please note that I have no interest in working with any Micro$oft related
-products! I want the primary focus of my work to be contributing
-to the free software community.
-
-Updated: 1997-12-04
+Updated: 1998-09-12

-Fen Labalme <fen@comedia.com>
-CoMedia Consulting http//www.comedia.com/comedia/
-40 Carl Street #4 WE ARE EVERYWHERE
-San Francisco CA 94117 JUST SAY "KNOW"
+Fen Labalme <fen@comedia.com>
+CoMedia Consulting http://www.comedia.com/
+142 S. Lake Merced Hill WE ARE EVERYWHERE
+San Francisco CA 94132 JUST SAY "KNOW"
Consulting, installation, customization and training for GNU Emacs,
and selected other GNU & network software. Design & implementation
@@ -709,10 +787,10 @@ of free software projects, as well as software engineering & system
design. I have been hacking Emacs since '76 when it was TECO and ^R
macros (don't ask), and am inter/intra-network, UNIX & Web friendly.
-Rates: $75 hour & up, depending; flat rate jobs considered.
- Lower rates, barter or free for selected non-profits.
+Rates: $150 hour & up, depending; flat rate jobs considered.
+ Lower rates, barter or free for selected non-profits.
-Updated: 1997-05-07
+Updated: 1998-06-24

Greg Lehey
LEMIS
@@ -728,17 +806,50 @@ Mail <grog@lemis.com>
Services: Supply, porting, installation, consultation on all GNU
products.
-Experience: 20 years OS and compiler experience, ports of most GNU
+Experience: 25 years OS and compiler experience, ports of most GNU
products. Author of ported software CD-ROM for UNIX System V.4.2,
"Porting UNIX Software" (O'Reilly), "Installing and Running FreeBSD"
and "The Complete FreeBSD" (both Walnut Creek).
-Rates: Choice of AUD 120 per hour or hotline rates AUD 2.50 DM per
-minute. Outside Australia, $US 100 per hour or $US 2 per minute.
-Quick questions may be free. Limited free support available for
+Rates: Choice of AUD 180 per hour or hotline rates AUD 3 per minute.
+Outside Australia, $US 100 per hour or $US 2 per minute. Quick
+questions may be free. Limited free support available for
purchasers of LEMIS CD-ROMs.
-Updated: 1997-05-09
+Updated: 1998-08-26
+
+Alan Lehotsky <qsmgmt@tiac.net>
+Quality Software Management
+634 West St
+Carlisle, MA 01741
+
+Phone: (978)287-0435
+Fax: (978)287-0436
+
+Services:
+ - Support for GNU compilers, including rehost/retarget
+ - General system software work (SW tools, O/S, device drivers)
+ - runtime library (especially floating point)
+ - project management
+ - software process improvement
+
+Experience: 15+ years of design and implementation of optimizing
+ compilers. "Mr. Bliss" at Digital in the 70's and early
+ 80's. Experience with Motorola 68k, PowerPC, SPARC, x86,
+ NS32K, ADI SHARC DSP. Compilers for languages including
+ Ada, BLISS, C, C++, FORTRAN, Pascal, Modula/2, O/S
+ experience includes Unix (OSF/1, SunOS, Solaris, AIX, HP/UX),
+ VAX/VMS, Windows/NT, MacOS.
+
+ 4 years experience with GCC internals, including major
+ changes to support 8 bit bytes on word-address SHARC DSP.
+
+References available
+
+Rates: $100/hr
+ fixed price possible for well-defined deliverables
+
+Updated: 1998-06-24

Rohan Lenard <rjl@wr.com.au>
32 Holtermann St.
@@ -746,7 +857,7 @@ Crows Nest, NSW 2065
AUSTRALIA
+61 411250024
-* The human face behind the bug-g++@prep.ai.mit.edu mailing list - known
+* The human face behind the bug-g++@gnu.org mailing list - known
in the past as <rjl@iassf.easams.com.au> and <rjl@ot.com.au> - now
known as <rjl@wr.com.au>.
@@ -786,7 +897,7 @@ WWW: http://www.netvision.net.il/php/reuven
Consulting rates: $75/hour, less for educational institutions.
-Updated: 1997-05-07
+Updated: 1998-06-24

Richard Levitte (in TeX: Richard Levitte
Levitte Programming Levitte Programming
@@ -825,6 +936,28 @@ Your Rate:
Updated: 1997-05-08

+Sean Levy <attila@StAlphonsos.COM>
+352 Roup Ave http://www.StAlphonsos.COM/~attila/
+Pittsburgh, PA 15232 +1.412.361.7802
+USA
+
+I have been a professional hacker for over 15 years, and have worked on
+everything from PDP-10's and -11's and early microcomputers to modern Unix
+workstations of various kinds, at all levels. I've done every kind of
+hacking, in many different languages (including some I designed and
+implemented). Current efforts are focused on Linux, GNU software, WWW-based
+systems, and security. My resume and PGP key are available via my web
+pages.
+
+Based in Pittsburgh, PA, available anywhere via the Internet. Possibility
+of travel for some jobs. Speak Spanish, have traveled in Europe and
+Scandinavia.
+
+Rates: $100 USD/hour standard, lower for non-profits or other worthy causes,
+ $200 USD/hour for pager access and 24-hour support
+
+Updated: 1998-06-24
+
Lexa Software info@lexa.com
1590 The Alameda, Suite 102
San Jose, CA 95126
@@ -843,32 +976,24 @@ to 2, 5, 25 and larger number of users via phone, email, ftp.
Updated: 1997-05-01

Gord Matzigkeit <gord@gnu.org>
-2220 Capitol Hill Crescent http://www.m-tech.ab.ca/~gord/
-Calgary, Alberta T2M 4B9 Voice: (403) 282-1387
-CANADA FAX: (403) 284-0137
+#15, 2105 Cornwall Street http://www.fig.org/~gord/
+Regina, Saskatchewan S4P 2K8 Voice: (306) 522-7884
+CANADA
-I will help install badly-behaved source code packages, and have experience
-fixing them to conform to GNU standards. I will gladly help novices and
-intermediate computer users to understand, install, and use free software,
-whether or not I have prior experience with that software. I know my
-limitations well, and will freely give other contacts if I do not want to
-solve your problem myself.
+I will gladly help novice and intermediate computer users to install,
+understand, and use free software, whether or not I have prior
+experience with that software. I know my limitations well, and will
+freely give other contacts if I cannot solve your problem myself.
-I have installed and administered free and proprietary systems in home,
-academic, and business environments. I have practical experience in most
-aspects of Unix and network security. I know how to diagnose a complex
-existing computer system and incrementally replace it with a superior free
-system without disrupting service.
+I have over 3 years of experience with several of the major free OSes:
+Linux/GNU (Red Hat, Debian, Slackware), NetBSD, FreeBSD, and GNU/Hurd.
+Some of my specialties are networking, Emacs, Automake, Autoconf, C,
+Perl, and shell script programming.
-I have over 2 years of experience with several of the major free OSes:
-Linux/GNU (Red Hat, Debian, Slackware), NetBSD, FreeBSD, and GNU/Hurd. I am
-the maintainer of GNU Libtool and GNU DLD. Some of my specialties are:
-Emacs, Automake, Autoconf, SANE, C, Perl, and shell script programming.
+My rates are negotiable depending on the task: usually $10-$40
+(Canadian) per hour.
-My rates start at $10 (Canadian dollars) per hour. When I am not starving, I
-do not charge worthy non-profit organizations.
-
-Updated: 1997-05-08
+Updated: 1998-10-19

Andrew McCallum
6623 Dalzell Place
@@ -898,63 +1023,111 @@ Rates: $90-$150 / hour, negotiable, depending on many variables.
Updated: 1997-05-07

-Erik Naggum <erik@naggum.no>
-P.O. Box 1570 Vika http://www.naggum.no
-0118 OSLO phone: +47 8800 8879
-NORWAY NIC handle: EN9
-
-Background: I have extensive experience with programming under Unix, in C
-in particular (since 1983), with standards and specifications for Internet
-protocols (since 1987), International Standards for character sets and
-encoding schemes (since 1988), ISO 8879 SGML (since 1990, national head of
-delegation to ISO/IEC JTC 1/SC 18/WG 8 since 1991), and ANSI X3.226 Common
-Lisp (since early 1994). I have been an Emacs user and programmer from
-1984 to 1987 (TOPS-20) and from 1991 to present (Unix). since early 1994,
-I have worked on GNU Emacs development, in both Lisp and C, and since mid
-1995, I have been tracking the development code.
-
-Services I offer the free software community include supporting Emacs users
-and programmers with expert advice (gratis on USENET or mailing lists where
-others may benefit), customizing and writing Emacs functions and packages,
-delivering courses and seminars from tutorials to writing Emacs Lisp and C
-extensions, and providing general aid with all GNU software.
-
-My standard rate is a flat USD 80 per hour or USD 2 per minute (you decide
-which time unit to apply), but to offset the cost of processing money, the
-minimum credit card charge is USD 100 and the minimum invoiced amount is
-USD 250. Discounts are available to worthy causes -- present your case.
-Time away from home is billed at USD 40 per hour around the clock to
-encourage remote work. (Courses and seminars are negotiated individually.)
-
-Please call only about actual work, I prefer mail for all other questions.
-
-Updated: 1997-07-18
-
-NET-Community <sales@net-community.com>
-522 SW 5th Avenue http://www.net-community.com
-Suite 1105
-Portland, OR 97204 USA
-1-800-919-0060 voice
-1-503-274-4423 voice
-1-503-274-5406 fax
+Mark P. Mitchell <mmitchell@usa.net>
+3421 El Camino Real #35
+Atherton, CA 94027
+(650) 364-5360
+http://home.earthlink.net/~mbmitchell/consulting.html
+
+Experience
+----------
+I am an experienced software engineer, with particular expertise in
+the field of programming tools. I am responsible for the
+implementation of member templates in currently available versions of
+G++ as well as many other G++ bug-fixes, and continue to work actively on
+improving G++.
+
+I am willing to work on any and all projects involving free software.
+
+Please see my resume at the above URL for further information on
+my experience and qualifications.
+
+Rates
+-----
+My standard rate is $125/hr, but I am willing to negotiate flat fees, and
+discounts for deserving organizations.
+
+Updated: 1998-02-13
+
+NET-Community <scottc@net-community.com>
+526 NW 21st, #48 http://www.net-community.com
+Portland, OR 97209 USA
+1-503-279-8845 voice
NET-Community provides support for the complete GNUstep toolset
including the Objective-C runtime within GCC, the GNUstep Base Library,
the Display Ghostscript system, the GNUstep GUI Library, the GNUstep
X/DPS GUI Backend, and the GNUstep Database Library. NET-Community also
provides support for its own MediaBook software including the MediaBook
-Random Library and the MediaBook Speech Synthesis Library.
+Random Library and the MediaBook Speech Synthesis Library.
NET-Community actively supports and develops free software on all
GNUstep platforms; a portion of the proceeds, usually 20%, generated
from CD-ROM sales go towards additional development and enhancement of
GNUstep.
-Updated: 1997-05-12
+Updated: 1998-09-08

- Open Systems Consultants a.s
- St. Olavsgt. 24
- N-0166 OSLO
- NORWAY
+Thi Nguyen <ttn@netcom.com>
+San Jose, CA, USA +1 408 314 3470
+
+Expertise: Hardware Verification Tools and Environment
+ - simulators / transactors / stimulus generators
+ - scripts of all sorts / environment / flows
+ - elisp customizations
+ - speak: C, C++, elisp, Scheme, Perl, Verilog, sh
+
+Please see ftp://ftp.netcom.com/pub/tt/ttn/resume.html for resume.
+
+Rate: $100/hr, possibly less
+
+Updated: 1998-06-24
+
+Peter Olsen
+P.O. Box 410
+Simpsonville, MD 21150
+
+pcolsen@acm.org
+
+What I do: Mathematical modeling and model building using Gnu
+ and other Free Software. Scientific and engineering
+ analysis, modeling, and programming in FORTRAN, C, LISP,
+ Java, and Smalltalk. Statistical analysis.
+ Emacs customization.
+
+Examples of my previous work:
+ 1. I built the model used predict the
+ amount of work required to clean up the Exxon Valdez oil
+ spill. Model was completed in ten days, used to allocate
+ resources for $2 billion summer cleanup, predictions were
+ accurate.
+ 2. I built a model applying commercial capital
+ investment standards to a Federal Agency budget, helped
+ support $250 Million budget increase.
+
+Credo: Engineering is the art of applying a professional
+ knowledge of mathematics and the physical sciences to
+ improve the quality of life.
+
+Rates: $225/hour (+ travel and expenses) on site,
+ $175/hour remote access.
+
+Notes: 1. Visiting Lecturer for Society for Industrial and Applied
+ Mathematics: Will speak without fee about Valdez model
+ (or other work) to Educational and not-for-profit
+ organizations (plus most-economical travel and living
+ expenses or travel or living arrangements in kind).
+
+ 2. I do not accept offers which pose even the appearance
+ of conflict of interest with any present or former client
+ or employer.
+
+Updated: 1998-06-24
+
+ Open Systems Consultants a.s Open Systems Consultants a.s
+ St. Olavsgt. 24 Fabrikkvn 8
+ N-0166 OSLO N-4033 FORUS
+ NORWAY NORWAY
+
Phone: Fax:
+47 22 20 40 50 +47 22 20 02 85
@@ -965,9 +1138,10 @@ Web: E-mail:
Open Systems Consultants a.s can provide programming support for all
GNU software -- extending or adopting it to meet customer needs.
Prices vary with software and project. Hourly fees are in the $80-120
-range. Fixed-priced projects are also available. No phone support.
+range. Fixed-priced projects are also available. Phone support is
+available only for customers with support contracts.
-Updated: 1997-05-08
+Updated: 1998-08-26

Francesco Potorti` <F.Potorti@cnuce.cnr.it>
Via S.Stefano, 8
@@ -991,30 +1165,23 @@ Qualifications: Electronic Engineering degree, Pisa. Full time
researcher in CNUCE-CNR.
Familiar with elisp programming and porting of C programs.
-Updated: 1997-05-08
+Updated: 1998-08-26

-Dipl.-Inform. Klaus Kaempf <kkaempf@progis.de>
-proGIS Software
-Jakobstr. 117
-D-52064 Aachen
+Dipl.-Inform. Klaus K?mpf <kkaempf@rmi.de>
+L?hnerstrasse 14
+D-90491 N?rnberg
Germany
-http://www.progis.de
-Tel +49 241 470670
-Fax +49 241 4706729
- 15 years C/Unix experience
- 6 years VMS experience
- Ported BFD library, Binutils, GNU Assembler, GNU C, GNU C++,
GNU C++ libraries, and GNU Make to openVMS/Alpha.
-We do a lot of cross-platform (Unix-VMS-WindowsNT) development
-mostly with the GNU compiler environment. We are actively
-supporting GNU software on openVMS/Alpha.
-
-Rates start at 160.- DM / hour for support and
-installation. Larger projects are negotiable.
+I do a lot of cross-platform (Unix/Linux-OpenVMS-WindowsNT) development
+mostly with the GNU compiler environment. I am actively supporting GNU
+software on OpenVMS/Alpha and OpenVMS/VAX.
-Updated: 1997-05-08
+Updated: 1998-08-26

Quiotix Corporation
Menlo Park, CA
@@ -1073,20 +1240,19 @@ Entered 1997-07-17
Vin Shelton
EtherSoft, Inc
-617.924.6437
-<acs@acm.org>
+781.488.5135
+<acs@alumni.princeton.edu>
I have been a professional programmer for 20 years, with most of that time
spent doing UNIX/C/C++ hacking. My specialties are (in no particular
order): system/kernel hacking, speech recognition, perl, object-oriented
design and analysis, FSF software (I have built nearly every FSF package on
several different platforms), small language design and implementation, and
-HTML/web programming. Currently I'm a member of the XEmacs beta testing
-team - I'm responsible for maintaining the version 19.15 patches and have
-written a few small packages/lisp hacks. My rates vary from $60 - $100 per
-hour, depending on the size of the project.
+HTML/web programming. Currently I'm a member of the XEmacs and egcs beta
+teams. My rates vary from $60 - $100 per hour, depending on the size of the
+project.
-Updated: 1997-05-09
+Updated: 1998-06-24

Signum Support AB <info@signum.se>
Teknikringen 8
@@ -1285,13 +1451,13 @@ to port (really rewrite) the GUI of a 50K line C++ Netscape plugin from
Win32 to Unix/X/Motif.
Unless otherwise required by a client, all the software I write is covered
-by the GNU Public License. My basic rate is Can$50/hour for work I can do
-remotely over the Internet, more for on-site work, less for selected
+by the GNU General Public License. My basic rate is Can$50/hour for work I
+can do remotely over the Internet, more for on-site work, less for selected
non-profit organizations.
Updated: 1997-05-19

-Leonard H. Tower Jr. <tower@prep.ai.mit.edu>
+Leonard H. Tower Jr. <tower@ai.mit.edu>
36 Porter Street
Somerville, MA 02143
USA
@@ -1300,13 +1466,14 @@ USA
Will work on most GNU software.
Installation, handholding, trouble shooting, extensions, teaching.
-Rates: $ 150.00/hour + travel expenses. Negotiable for non-profits.
+Rates: $ 150.00/hour + travel expenses. Fixed fee quotes available.
+ Negotiable for non-profits.
Experience: Have hacked on over a dozen architectures in many languages. Have
system mothered too many varieties of Unixes. Assisted rms with the front end
of gcc and its back-end support. Resume available on request.
-Updated: 1997-05-24
+Updated: 1998-02-10

noris network GmbH
Matthias Urlichs
@@ -1344,15 +1511,15 @@ Rates:
Updated: 1997-08-04

Paul C.A. van Gool
- <P.vanGool@LR.TUDelft.NL>
+ <vangool@fel.tno.nl>
-Address: Faculty of Aerospace Engineering
- Delft University of Technology
- Kluyverweg 1, 2629 HS Delft
+Address: Netherlands Organization for Applied Scientific Research
+ Physics and Electronics Laboratory
+ PO Box 96864, 2509 JG the Hague
The Netherlands
-Phone: +31-15-2785370
-Fax : +31-15-2786480
+Phone: +31-70-3740260
+Fax : +31-70-3740652
I would like to provide unpaid support for the following things:
@@ -1361,7 +1528,29 @@ I would like to provide unpaid support for the following things:
- f2c
- compilation and installation of most GNU packages
-Updated: 1997-05-12
+Updated: 1998-06-24
+
+Joel N. Weber II
+185 Lowell St #2
+Somerville, MA 02144-2629
+devnull@gnu.org
+
+I can install GNU software, customize it, fix bugs, answer questions,
+and teach.
+
+I am fluent in C, emacs lisp, Bourne shell, and awk. I also have a
+good understanding of automake and autoconf.
+
+I have modified identd, cvs, and ftpd to change their security
+procedures; I have modified the GNU fileutils to understand new flag
+bits that were added to the Hurd. I have been involved in developing
+Hurd translators. Long ago, I worked on developing a web browser;
+that project was eventually killed, but I learned a lot in the
+process.
+
+I am experienced in webmastering and system administration.
+
+Rate: $100/hour, negotiable.

Arne Wichmann
@@ -1415,6 +1604,6 @@ Updated: 1996-12-04

For a current copy of this directory, or to have yourself listed, ask:
- gnu@prep.ai.mit.edu
+ gnu@gnu.org
** Please keep the entries in this file alphabetical **
diff --git a/gcc/acconfig.h b/gcc/acconfig.h
index 04875706983..3aae71e13be 100644
--- a/gcc/acconfig.h
+++ b/gcc/acconfig.h
@@ -7,6 +7,15 @@
/* Define if you want expensive run-time checks. */
#undef ENABLE_CHECKING
+/* Define to 1 if NLS is requested. */
+#undef ENABLE_NLS
+
+/* Define as 1 if you have catgets and don't want to use GNU gettext. */
+#undef HAVE_CATGETS
+
+/* Define as 1 if you have gettext and don't want to use GNU gettext. */
+#undef HAVE_GETTEXT
+
/* Define if your cpp understands the stringify operator. */
#undef HAVE_CPP_STRINGIFY
@@ -27,6 +36,12 @@
/* Define if you have a working <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
+/* Define if your locale.h file contains LC_MESSAGES. */
+#undef HAVE_LC_MESSAGES
+
+/* Define as 1 if you have the stpcpy function. */
+#undef HAVE_STPCPY
+
/* Whether malloc must be declared even if <stdlib.h> is included. */
#undef NEED_DECLARATION_MALLOC
@@ -60,6 +75,9 @@
/* Whether atol must be declared even if <stdlib.h> is included. */
#undef NEED_DECLARATION_ATOL
+/* Whether atof must be declared even if <stdlib.h> is included. */
+#undef NEED_DECLARATION_ATOF
+
/* Whether sbrk must be declared even if <stdlib.h> is included. */
#undef NEED_DECLARATION_SBRK
@@ -84,6 +102,12 @@
/* Whether setrlimit must be declared even if <sys/resource.h> is included. */
#undef NEED_DECLARATION_SETRLIMIT
+/* Whether putc_unlocked must be declared even if <stdio.h> is included. */
+#undef NEED_DECLARATION_PUTC_UNLOCKED
+
+/* Whether fputs_unlocked must be declared even if <stdio.h> is included. */
+#undef NEED_DECLARATION_FPUTS_UNLOCKED
+
/* Define if you want expensive run-time checks. */
#undef ENABLE_CHECKING
@@ -93,4 +117,9 @@
/* Define to enable the use of a default linker. */
#undef DEFAULT_LINKER
+/* Define to the name of the distribution. */
+#undef PACKAGE
+
+/* Define to the version of the distribution. */
+#undef VERSION
@TOP@
diff --git a/gcc/aclocal.m4 b/gcc/aclocal.m4
index ce44ba19eb9..b656d65b4d0 100644
--- a/gcc/aclocal.m4
+++ b/gcc/aclocal.m4
@@ -235,3 +235,404 @@ AC_SUBST(INSTALL_PROGRAM)dnl
test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
AC_SUBST(INSTALL_DATA)dnl
])
+
+#serial 1
+dnl This test replaces the one in autoconf.
+dnl Currently this macro should have the same name as the autoconf macro
+dnl because gettext's gettext.m4 (distributed in the automake package)
+dnl still uses it. Otherwise, the use in gettext.m4 makes autoheader
+dnl give these diagnostics:
+dnl configure.in:556: AC_TRY_COMPILE was called before AC_ISC_POSIX
+dnl configure.in:556: AC_TRY_RUN was called before AC_ISC_POSIX
+
+undefine([AC_ISC_POSIX])
+AC_DEFUN(AC_ISC_POSIX,
+ [
+ dnl This test replaces the obsolescent AC_ISC_POSIX kludge.
+ AC_CHECK_LIB(cposix, strerror, [LIBS="$LIBS -lcposix"])
+ ]
+)
+
+# Macro to add for using GNU gettext.
+# Ulrich Drepper <drepper@cygnus.com>, 1995.
+#
+# This file can be copied and used freely without restrictions. It can
+# be used in projects which are not available under the GNU Public License
+# but which still want to provide support for the GNU gettext functionality.
+# Please note that the actual code is *not* freely available.
+
+# serial 5
+
+AC_DEFUN(AM_WITH_NLS,
+ [AC_MSG_CHECKING([whether NLS is requested])
+ dnl Default is enabled NLS
+ AC_ARG_ENABLE(nls,
+ [ --disable-nls do not use Native Language Support],
+ USE_NLS=$enableval, USE_NLS=yes)
+ AC_MSG_RESULT($USE_NLS)
+ AC_SUBST(USE_NLS)
+
+ USE_INCLUDED_LIBINTL=no
+
+ dnl If we use NLS figure out what method
+ if test "$USE_NLS" = "yes"; then
+ AC_DEFINE(ENABLE_NLS)
+ AC_MSG_CHECKING([whether included gettext is requested])
+ AC_ARG_WITH(included-gettext,
+ [ --with-included-gettext use the GNU gettext library included here],
+ nls_cv_force_use_gnu_gettext=$withval,
+ nls_cv_force_use_gnu_gettext=no)
+ AC_MSG_RESULT($nls_cv_force_use_gnu_gettext)
+
+ nls_cv_use_gnu_gettext="$nls_cv_force_use_gnu_gettext"
+ if test "$nls_cv_force_use_gnu_gettext" != "yes"; then
+ dnl User does not insist on using GNU NLS library. Figure out what
+ dnl to use. If gettext or catgets are available (in this order) we
+ dnl use this. Else we have to fall back to GNU NLS library.
+ dnl catgets is only used if permitted by option --with-catgets.
+ nls_cv_header_intl=
+ nls_cv_header_libgt=
+ CATOBJEXT=NONE
+
+ AC_CHECK_HEADER(libintl.h,
+ [AC_CACHE_CHECK([for gettext in libc], gt_cv_func_gettext_libc,
+ [AC_TRY_LINK([#include <libintl.h>], [return (int) gettext ("")],
+ gt_cv_func_gettext_libc=yes, gt_cv_func_gettext_libc=no)])
+
+ if test "$gt_cv_func_gettext_libc" != "yes"; then
+ AC_CHECK_LIB(intl, bindtextdomain,
+ [AC_CACHE_CHECK([for gettext in libintl],
+ gt_cv_func_gettext_libintl,
+ [AC_CHECK_LIB(intl, gettext,
+ gt_cv_func_gettext_libintl=yes,
+ gt_cv_func_gettext_libintl=no)],
+ gt_cv_func_gettext_libintl=no)])
+ fi
+
+ if test "$gt_cv_func_gettext_libc" = "yes" \
+ || test "$gt_cv_func_gettext_libintl" = "yes"; then
+ AC_DEFINE(HAVE_GETTEXT)
+ AM_PATH_PROG_WITH_TEST(MSGFMT, msgfmt,
+ [test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"], no)dnl
+ if test "$MSGFMT" != "no"; then
+ AC_CHECK_FUNCS(dcgettext)
+ AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT)
+ AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext,
+ [test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"], :)
+ AC_TRY_LINK(, [extern int _nl_msg_cat_cntr;
+ return _nl_msg_cat_cntr],
+ [CATOBJEXT=.gmo
+ DATADIRNAME=share],
+ [CATOBJEXT=.mo
+ DATADIRNAME=lib])
+ INSTOBJEXT=.mo
+ fi
+ fi
+ ])
+
+ if test "$CATOBJEXT" = "NONE"; then
+ AC_MSG_CHECKING([whether catgets can be used])
+ AC_ARG_WITH(catgets,
+ [ --with-catgets use catgets functions if available],
+ nls_cv_use_catgets=$withval, nls_cv_use_catgets=no)
+ AC_MSG_RESULT($nls_cv_use_catgets)
+
+ if test "$nls_cv_use_catgets" = "yes"; then
+ dnl No gettext in C library. Try catgets next.
+ AC_CHECK_LIB(i, main)
+ AC_CHECK_FUNC(catgets,
+ [AC_DEFINE(HAVE_CATGETS)
+ INTLOBJS="\$(CATOBJS)"
+ AC_PATH_PROG(GENCAT, gencat, no)dnl
+ if test "$GENCAT" != "no"; then
+ AC_PATH_PROG(GMSGFMT, gmsgfmt, no)
+ if test "$GMSGFMT" = "no"; then
+ AM_PATH_PROG_WITH_TEST(GMSGFMT, msgfmt,
+ [test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"], no)
+ fi
+ AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext,
+ [test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"], :)
+ USE_INCLUDED_LIBINTL=yes
+ CATOBJEXT=.cat
+ INSTOBJEXT=.cat
+ DATADIRNAME=lib
+ INTLDEPS='$(top_builddir)/intl/libintl.a'
+ INTLLIBS=$INTLDEPS
+ LIBS=`echo $LIBS | sed -e 's/-lintl//'`
+ nls_cv_header_intl=intl/libintl.h
+ nls_cv_header_libgt=intl/libgettext.h
+ fi])
+ fi
+ fi
+
+ if test "$CATOBJEXT" = "NONE"; then
+ dnl Neither gettext nor catgets in included in the C library.
+ dnl Fall back on GNU gettext library.
+ nls_cv_use_gnu_gettext=yes
+ fi
+ fi
+
+ if test "$nls_cv_use_gnu_gettext" = "yes"; then
+ dnl Mark actions used to generate GNU NLS library.
+ INTLOBJS="\$(GETTOBJS)"
+ AM_PATH_PROG_WITH_TEST(MSGFMT, msgfmt,
+ [test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"], msgfmt)
+ AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT)
+ AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext,
+ [test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"], :)
+ AC_SUBST(MSGFMT)
+ USE_INCLUDED_LIBINTL=yes
+ CATOBJEXT=.gmo
+ INSTOBJEXT=.mo
+ DATADIRNAME=share
+ INTLDEPS='$(top_builddir)/intl/libintl.a'
+ INTLLIBS=$INTLDEPS
+ LIBS=`echo $LIBS | sed -e 's/-lintl//'`
+ nls_cv_header_intl=intl/libintl.h
+ nls_cv_header_libgt=intl/libgettext.h
+ fi
+
+ dnl Test whether we really found GNU xgettext.
+ if test "$XGETTEXT" != ":"; then
+ dnl If it is no GNU xgettext we define it as : so that the
+ dnl Makefiles still can work.
+ if $XGETTEXT --omit-header /dev/null 2> /dev/null; then
+ : ;
+ else
+ AC_MSG_RESULT(
+ [found xgettext program is not GNU xgettext; ignore it])
+ XGETTEXT=":"
+ fi
+ fi
+
+ # We need to process the po/ directory.
+ POSUB=po
+ else
+ DATADIRNAME=share
+ nls_cv_header_intl=intl/libintl.h
+ nls_cv_header_libgt=intl/libgettext.h
+ fi
+ AC_LINK_FILES($nls_cv_header_libgt, $nls_cv_header_intl)
+ AC_OUTPUT_COMMANDS(
+ [case "$CONFIG_FILES" in *po/Makefile.in*)
+ sed -e "/POTFILES =/r po/POTFILES" po/Makefile.in > po/Makefile
+ esac])
+
+
+ # If this is used in GNU gettext we have to set USE_NLS to `yes'
+ # because some of the sources are only built for this goal.
+ if test "$PACKAGE" = gettext; then
+ USE_NLS=yes
+ USE_INCLUDED_LIBINTL=yes
+ fi
+
+ dnl These rules are solely for the distribution goal. While doing this
+ dnl we only have to keep exactly one list of the available catalogs
+ dnl in configure.in.
+ for lang in $ALL_LINGUAS; do
+ GMOFILES="$GMOFILES $lang.gmo"
+ POFILES="$POFILES $lang.po"
+ done
+
+ dnl Make all variables we use known to autoconf.
+ AC_SUBST(USE_INCLUDED_LIBINTL)
+ AC_SUBST(CATALOGS)
+ AC_SUBST(CATOBJEXT)
+ AC_SUBST(DATADIRNAME)
+ AC_SUBST(GMOFILES)
+ AC_SUBST(INSTOBJEXT)
+ AC_SUBST(INTLDEPS)
+ AC_SUBST(INTLLIBS)
+ AC_SUBST(INTLOBJS)
+ AC_SUBST(POFILES)
+ AC_SUBST(POSUB)
+ ])
+
+AC_DEFUN(AM_GNU_GETTEXT,
+ [AC_REQUIRE([AC_PROG_MAKE_SET])dnl
+ AC_REQUIRE([AC_PROG_CC])dnl
+ AC_REQUIRE([AC_PROG_RANLIB])dnl
+ AC_REQUIRE([AC_ISC_POSIX])dnl
+ AC_REQUIRE([AC_HEADER_STDC])dnl
+ AC_REQUIRE([AC_C_CONST])dnl
+ AC_REQUIRE([AC_C_INLINE])dnl
+ AC_REQUIRE([AC_TYPE_OFF_T])dnl
+ AC_REQUIRE([AC_TYPE_SIZE_T])dnl
+ AC_REQUIRE([AC_FUNC_ALLOCA])dnl
+ AC_REQUIRE([AC_FUNC_MMAP])dnl
+
+ AC_CHECK_HEADERS([argz.h limits.h locale.h nl_types.h malloc.h string.h \
+unistd.h sys/param.h])
+ AC_CHECK_FUNCS([getcwd munmap putenv setenv setlocale strchr strcasecmp \
+strdup __argz_count __argz_stringify __argz_next])
+
+ if test "${ac_cv_func_stpcpy+set}" != "set"; then
+ AC_CHECK_FUNCS(stpcpy)
+ fi
+ if test "${ac_cv_func_stpcpy}" = "yes"; then
+ AC_DEFINE(HAVE_STPCPY)
+ fi
+
+ AM_LC_MESSAGES
+ AM_WITH_NLS
+
+ if test "x$CATOBJEXT" != "x"; then
+ if test "x$ALL_LINGUAS" = "x"; then
+ LINGUAS=
+ else
+ AC_MSG_CHECKING(for catalogs to be installed)
+ NEW_LINGUAS=
+ for lang in ${LINGUAS=$ALL_LINGUAS}; do
+ case "$ALL_LINGUAS" in
+ *$lang*) NEW_LINGUAS="$NEW_LINGUAS $lang" ;;
+ esac
+ done
+ LINGUAS=$NEW_LINGUAS
+ AC_MSG_RESULT($LINGUAS)
+ fi
+
+ dnl Construct list of names of catalog files to be constructed.
+ if test -n "$LINGUAS"; then
+ for lang in $LINGUAS; do CATALOGS="$CATALOGS $lang$CATOBJEXT"; done
+ fi
+ fi
+
+ dnl The reference to <locale.h> in the installed <libintl.h> file
+ dnl must be resolved because we cannot expect the users of this
+ dnl to define HAVE_LOCALE_H.
+ if test $ac_cv_header_locale_h = yes; then
+ INCLUDE_LOCALE_H="#include <locale.h>"
+ else
+ INCLUDE_LOCALE_H="\
+/* The system does not provide the header <locale.h>. Take care yourself. */"
+ fi
+ AC_SUBST(INCLUDE_LOCALE_H)
+
+ dnl Determine which catalog format we have (if any is needed)
+ dnl For now we know about two different formats:
+ dnl Linux libc-5 and the normal X/Open format
+ test -d intl || mkdir intl
+ if test "$CATOBJEXT" = ".cat"; then
+ AC_CHECK_HEADER(linux/version.h, msgformat=linux, msgformat=xopen)
+
+ dnl Transform the SED scripts while copying because some dumb SEDs
+ dnl cannot handle comments.
+ sed -e '/^#/d' $srcdir/intl/$msgformat-msg.sed > intl/po2msg.sed
+ fi
+ dnl po2tbl.sed is always needed.
+ sed -e '/^#.*[^\\]$/d' -e '/^#$/d' \
+ $srcdir/intl/po2tbl.sed.in > intl/po2tbl.sed
+
+ dnl In the intl/Makefile.in we have a special dependency which makes
+ dnl only sense for gettext. We comment this out for non-gettext
+ dnl packages.
+ if test "$PACKAGE" = "gettext"; then
+ GT_NO="#NO#"
+ GT_YES=
+ else
+ GT_NO=
+ GT_YES="#YES#"
+ fi
+ AC_SUBST(GT_NO)
+ AC_SUBST(GT_YES)
+
+ dnl If the AC_CONFIG_AUX_DIR macro for autoconf is used we possibly
+ dnl find the mkinstalldirs script in another subdir but ($top_srcdir).
+ dnl Try to locate is.
+ MKINSTALLDIRS=
+ if test -n "$ac_aux_dir"; then
+ MKINSTALLDIRS="$ac_aux_dir/mkinstalldirs"
+ fi
+ if test -z "$MKINSTALLDIRS"; then
+ MKINSTALLDIRS="\$(top_srcdir)/mkinstalldirs"
+ fi
+ AC_SUBST(MKINSTALLDIRS)
+
+ dnl *** For now the libtool support in intl/Makefile is not for real.
+ l=
+ AC_SUBST(l)
+
+ dnl Generate list of files to be processed by xgettext which will
+ dnl be included in po/Makefile.
+ test -d po || mkdir po
+ if test "x$srcdir" != "x."; then
+ if test "x`echo $srcdir | sed 's@/.*@@'`" = "x"; then
+ posrcprefix="$srcdir/"
+ else
+ posrcprefix="../$srcdir/"
+ fi
+ else
+ posrcprefix="../"
+ fi
+ rm -f po/POTFILES
+ sed -e "/^#/d" -e "/^\$/d" -e "s,.*, $posrcprefix& \\\\," -e "\$s/\(.*\) \\\\/\1/" \
+ < $srcdir/po/POTFILES.in > po/POTFILES
+ ])
+
+# Check whether LC_MESSAGES is available in <locale.h>.
+# Ulrich Drepper <drepper@cygnus.com>, 1995.
+#
+# This file can be copied and used freely without restrictions. It can
+# be used in projects which are not available under the GNU Public License
+# but which still want to provide support for the GNU gettext functionality.
+# Please note that the actual code is *not* freely available.
+
+# serial 1
+
+AC_DEFUN(AM_LC_MESSAGES,
+ [if test $ac_cv_header_locale_h = yes; then
+ AC_CACHE_CHECK([for LC_MESSAGES], am_cv_val_LC_MESSAGES,
+ [AC_TRY_LINK([#include <locale.h>], [return LC_MESSAGES],
+ am_cv_val_LC_MESSAGES=yes, am_cv_val_LC_MESSAGES=no)])
+ if test $am_cv_val_LC_MESSAGES = yes; then
+ AC_DEFINE(HAVE_LC_MESSAGES)
+ fi
+ fi])
+
+# Search path for a program which passes the given test.
+# Ulrich Drepper <drepper@cygnus.com>, 1996.
+#
+# This file can be copied and used freely without restrictions. It can
+# be used in projects which are not available under the GNU Public License
+# but which still want to provide support for the GNU gettext functionality.
+# Please note that the actual code is *not* freely available.
+
+# serial 1
+
+dnl AM_PATH_PROG_WITH_TEST(VARIABLE, PROG-TO-CHECK-FOR,
+dnl TEST-PERFORMED-ON-FOUND_PROGRAM [, VALUE-IF-NOT-FOUND [, PATH]])
+AC_DEFUN(AM_PATH_PROG_WITH_TEST,
+[# Extract the first word of "$2", so it can be a program name with args.
+set dummy $2; ac_word=[$]2
+AC_MSG_CHECKING([for $ac_word])
+AC_CACHE_VAL(ac_cv_path_$1,
+[case "[$]$1" in
+ /*)
+ ac_cv_path_$1="[$]$1" # Let the user override the test with a path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in ifelse([$5], , $PATH, [$5]); do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if [$3]; then
+ ac_cv_path_$1="$ac_dir/$ac_word"
+ break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+dnl If no 4th arg is given, leave the cache variable unset,
+dnl so AC_PATH_PROGS will keep looking.
+ifelse([$4], , , [ test -z "[$]ac_cv_path_$1" && ac_cv_path_$1="$4"
+])dnl
+ ;;
+esac])dnl
+$1="$ac_cv_path_$1"
+if test -n "[$]$1"; then
+ AC_MSG_RESULT([$]$1)
+else
+ AC_MSG_RESULT(no)
+fi
+AC_SUBST($1)dnl
+])
diff --git a/gcc/alias.c b/gcc/alias.c
index d26bacde8b1..dff441cadd7 100644
--- a/gcc/alias.c
+++ b/gcc/alias.c
@@ -1,5 +1,5 @@
/* Alias analysis for GNU C
- Copyright (C) 1997, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc.
Contributed by John Carr (jfc@mit.edu).
This file is part of GNU CC.
@@ -29,6 +29,49 @@ Boston, MA 02111-1307, USA. */
#include "flags.h"
#include "output.h"
#include "toplev.h"
+#include "splay-tree.h"
+
+/* The alias sets assigned to MEMs assist the back-end in determining
+ which MEMs can alias which other MEMs. In general, two MEMs in
+ different alias sets to not alias each other. There is one
+ exception, however. Consider something like:
+
+ struct S {int i; double d; };
+
+ a store to an `S' can alias something of either type `int' or type
+ `double'. (However, a store to an `int' cannot alias a `double'
+ and vice versa.) We indicate this via a tree structure that looks
+ like:
+ struct S
+ / \
+ / \
+ |/_ _\|
+ int double
+
+ (The arrows are directed and point downwards.) If, when comparing
+ two alias sets, we can hold one set fixed, and trace the other set
+ downwards, and at some point find the first set, the two MEMs can
+ alias one another. In this situation we say the alias set for
+ `struct S' is the `superset' and that those for `int' and `double'
+ are `subsets'.
+
+ Alias set zero is implicitly a superset of all other alias sets.
+ However, this is no actual entry for alias set zero. It is an
+ error to attempt to explicitly construct a subset of zero. */
+
+typedef struct alias_set_entry {
+ /* The alias set number, as stored in MEM_ALIAS_SET. */
+ int alias_set;
+
+ /* The children of the alias set. These are not just the immediate
+ children, but, in fact, all children. So, if we have:
+
+ struct T { struct S s; float f; }
+
+ continuing our example above, the children here will be all of
+ `int', `double', `float', and `struct S'. */
+ splay_tree children;
+}* alias_set_entry;
static rtx canon_rtx PROTO((rtx));
static int rtx_equal_for_memref_p PROTO((rtx, rtx));
@@ -37,37 +80,29 @@ static int memrefs_conflict_p PROTO((int, rtx, int, rtx,
HOST_WIDE_INT));
static void record_set PROTO((rtx, rtx));
static rtx find_base_term PROTO((rtx));
-static int base_alias_check PROTO((rtx, rtx));
+static int base_alias_check PROTO((rtx, rtx, enum machine_mode,
+ enum machine_mode));
static rtx find_base_value PROTO((rtx));
+static int mems_in_disjoint_alias_sets_p PROTO((rtx, rtx));
+static int alias_set_compare PROTO((splay_tree_key,
+ splay_tree_key));
+static int insert_subset_children PROTO((splay_tree_node,
+ void*));
+static alias_set_entry get_alias_set_entry PROTO((int));
+static rtx fixed_scalar_and_varying_struct_p PROTO((rtx, rtx, int (*)(rtx)));
+static int aliases_everything_p PROTO((rtx));
+static int write_dependence_p PROTO((rtx, rtx, int));
/* Set up all info needed to perform alias analysis on memory references. */
#define SIZE_FOR_MODE(X) (GET_MODE_SIZE (GET_MODE (X)))
-/* Perform a basic sanity check. Namely, that there are
- no alias sets if we're not doing strict aliasing. This helps
- to catch bugs whereby someone uses PUT_CODE, but doesn't clear
- MEM_ALIAS_SET, or where a MEM is allocated in some way other
- than by the use of gen_rtx_MEM, and the MEM_ALIAS_SET is not
- cleared. */
-#ifdef ENABLE_CHECKING
-#define CHECK_ALIAS_SETS_FOR_CONSISTENCY(MEM1, MEM2) \
- (!flag_strict_aliasing \
- && (MEM_ALIAS_SET (MEM1) || MEM_ALIAS_SET (MEM2)) \
- ? (abort (), 0) : 0)
-#else
-#define CHECK_ALIAS_SETS_FOR_CONSISTENCY(MEM1, MEM2) ((void)0)
-#endif
-
/* Returns nonzero if MEM1 and MEM2 do not alias because they are in
different alias sets. We ignore alias sets in functions making use
of variable arguments because the va_arg macros on some systems are
not legal ANSI C. */
#define DIFFERENT_ALIAS_SETS_P(MEM1, MEM2) \
- (CHECK_ALIAS_SETS_FOR_CONSISTENCY(MEM1, MEM2), \
- MEM_ALIAS_SET (MEM1) && MEM_ALIAS_SET (MEM2) \
- && MEM_ALIAS_SET (MEM1) != MEM_ALIAS_SET (MEM2) \
- && !current_function_stdarg && !current_function_varargs)
+ mems_in_disjoint_alias_sets_p (MEM1, MEM2)
/* Cap the number of passes we make over the insns propagating alias
information through set chains.
@@ -94,7 +129,7 @@ rtx *reg_base_value;
rtx *new_reg_base_value;
unsigned int reg_base_value_size; /* size of reg_base_value array */
#define REG_BASE_VALUE(X) \
- (REGNO (X) < reg_base_value_size ? reg_base_value[REGNO (X)] : 0)
+ ((unsigned) REGNO (X) < reg_base_value_size ? reg_base_value[REGNO (X)] : 0)
/* Vector of known invariant relationships between registers. Set in
loop unrolling. Indexed by register number, if nonzero the value
@@ -131,6 +166,167 @@ char *reg_known_equiv_p;
static int copying_arguments;
+/* The splay-tree used to store the various alias set entries. */
+
+static splay_tree alias_sets;
+
+/* Returns -1, 0, 1 according to whether SET1 is less than, equal to,
+ or greater than SET2. */
+
+static int
+alias_set_compare (set1, set2)
+ splay_tree_key set1;
+ splay_tree_key set2;
+{
+ int s1 = (int) set1;
+ int s2 = (int) set2;
+
+ if (s1 < s2)
+ return -1;
+ else if (s1 > s2)
+ return 1;
+ else
+ return 0;
+}
+
+/* Returns a pointer to the alias set entry for ALIAS_SET, if there is
+ such an entry, or NULL otherwise. */
+
+static alias_set_entry
+get_alias_set_entry (alias_set)
+ int alias_set;
+{
+ splay_tree_node sn =
+ splay_tree_lookup (alias_sets, (splay_tree_key) alias_set);
+
+ return sn ? ((alias_set_entry) sn->value) : ((alias_set_entry) 0);
+}
+
+/* Returns nonzero value if the alias sets for MEM1 and MEM2 are such
+ that the two MEMs cannot alias each other. */
+
+static int
+mems_in_disjoint_alias_sets_p (mem1, mem2)
+ rtx mem1;
+ rtx mem2;
+{
+ alias_set_entry ase;
+
+#ifdef ENABLE_CHECKING
+/* Perform a basic sanity check. Namely, that there are no alias sets
+ if we're not using strict aliasing. This helps to catch bugs
+ whereby someone uses PUT_CODE, but doesn't clear MEM_ALIAS_SET, or
+ where a MEM is allocated in some way other than by the use of
+ gen_rtx_MEM, and the MEM_ALIAS_SET is not cleared. If we begin to
+ use alias sets to indicate that spilled registers cannot alias each
+ other, we might need to remove this check. */
+ if (!flag_strict_aliasing &&
+ (MEM_ALIAS_SET (mem1) || MEM_ALIAS_SET (mem2)))
+ abort ();
+#endif
+
+ /* The code used in varargs macros are often not conforming ANSI C,
+ which can trick the compiler into making incorrect aliasing
+ assumptions in these functions. So, we don't use alias sets in
+ such a function. FIXME: This should be moved into the front-end;
+ it is a language-dependent notion, and there's no reason not to
+ still use these checks to handle globals. */
+ if (current_function_stdarg || current_function_varargs)
+ return 0;
+
+ if (!MEM_ALIAS_SET (mem1) || !MEM_ALIAS_SET (mem2))
+ /* We have no alias set information for one of the MEMs, so we
+ have to assume it can alias anything. */
+ return 0;
+
+ if (MEM_ALIAS_SET (mem1) == MEM_ALIAS_SET (mem2))
+ /* The two alias sets are the same, so they may alias. */
+ return 0;
+
+ /* Iterate through each of the children of the first alias set,
+ comparing it with the second alias set. */
+ ase = get_alias_set_entry (MEM_ALIAS_SET (mem1));
+ if (ase && splay_tree_lookup (ase->children,
+ (splay_tree_key) MEM_ALIAS_SET (mem2)))
+ return 0;
+
+ /* Now do the same, but with the alias sets reversed. */
+ ase = get_alias_set_entry (MEM_ALIAS_SET (mem2));
+ if (ase && splay_tree_lookup (ase->children,
+ (splay_tree_key) MEM_ALIAS_SET (mem1)))
+ return 0;
+
+ /* The two MEMs are in distinct alias sets, and neither one is the
+ child of the other. Therefore, they cannot alias. */
+ return 1;
+}
+
+/* Insert the NODE into the splay tree given by DATA. Used by
+ record_alias_subset via splay_tree_foreach. */
+
+static int
+insert_subset_children (node, data)
+ splay_tree_node node;
+ void *data;
+{
+ splay_tree_insert ((splay_tree) data,
+ node->key,
+ node->value);
+
+ return 0;
+}
+
+/* Indicate that things in SUBSET can alias things in SUPERSET, but
+ not vice versa. For example, in C, a store to an `int' can alias a
+ structure containing an `int', but not vice versa. Here, the
+ structure would be the SUPERSET and `int' the SUBSET. This
+ function should be called only once per SUPERSET/SUBSET pair. At
+ present any given alias set may only be a subset of one superset.
+
+ It is illegal for SUPERSET to be zero; everything is implicitly a
+ subset of alias set zero. */
+
+void
+record_alias_subset (superset, subset)
+ int superset;
+ int subset;
+{
+ alias_set_entry superset_entry;
+ alias_set_entry subset_entry;
+
+ if (superset == 0)
+ abort ();
+
+ superset_entry = get_alias_set_entry (superset);
+ if (!superset_entry)
+ {
+ /* Create an entry for the SUPERSET, so that we have a place to
+ attach the SUBSET. */
+ superset_entry =
+ (alias_set_entry) xmalloc (sizeof (struct alias_set_entry));
+ superset_entry->alias_set = superset;
+ superset_entry->children
+ = splay_tree_new (alias_set_compare, 0, 0);
+ splay_tree_insert (alias_sets,
+ (splay_tree_key) superset,
+ (splay_tree_value) superset_entry);
+
+ }
+
+ subset_entry = get_alias_set_entry (subset);
+ if (subset_entry)
+ /* There is an entry for the subset. Enter all of its children
+ (if they are not already present) as children of the SUPERSET. */
+ splay_tree_foreach (subset_entry->children,
+ insert_subset_children,
+ superset_entry->children);
+
+ /* Enter the SUBSET itself as a child of the SUPERSET. */
+ splay_tree_insert (superset_entry->children,
+ (splay_tree_key) subset,
+ /*value=*/0);
+}
+
/* Inside SRC, the source of a SET, find a base address. */
static rtx
@@ -158,7 +354,7 @@ find_base_value (src)
The test above is not sufficient because the scheduler may move
a copy out of an arg reg past the NOTE_INSN_FUNCTION_BEGIN. */
if (REGNO (src) >= FIRST_PSEUDO_REGISTER
- && REGNO (src) < reg_base_value_size
+ && (unsigned) REGNO (src) < reg_base_value_size
&& reg_base_value[REGNO (src)])
return reg_base_value[REGNO (src)];
@@ -341,7 +537,7 @@ record_base_value (regno, val, invariant)
rtx val;
int invariant;
{
- if (regno >= reg_base_value_size)
+ if ((unsigned) regno >= reg_base_value_size)
return;
/* If INVARIANT is true then this value also describes an invariant
@@ -352,7 +548,7 @@ record_base_value (regno, val, invariant)
if (GET_CODE (val) == REG)
{
- if (REGNO (val) < reg_base_value_size)
+ if ((unsigned) REGNO (val) < reg_base_value_size)
{
reg_base_value[regno] = reg_base_value[REGNO (val)];
}
@@ -396,9 +592,8 @@ canon_rtx (x)
if (addr != XEXP (x, 0))
{
rtx new = gen_rtx_MEM (GET_MODE (x), addr);
- MEM_VOLATILE_P (new) = MEM_VOLATILE_P (x);
RTX_UNCHANGING_P (new) = RTX_UNCHANGING_P (x);
- MEM_IN_STRUCT_P (new) = MEM_IN_STRUCT_P (x);
+ MEM_COPY_ATTRIBUTES (new, x);
MEM_ALIAS_SET (new) = MEM_ALIAS_SET (x);
x = new;
}
@@ -597,8 +792,9 @@ find_base_term (x)
objects, 1 if they might be pointers to the same object. */
static int
-base_alias_check (x, y)
+base_alias_check (x, y, x_mode, y_mode)
rtx x, y;
+ enum machine_mode x_mode, y_mode;
{
rtx x_base = find_base_term (x);
rtx y_base = find_base_term (y);
@@ -630,17 +826,25 @@ base_alias_check (x, y)
if (rtx_equal_p (x_base, y_base))
return 1;
- /* The base addresses of the read and write are different
- expressions. If they are both symbols and they are not accessed
- via AND, there is no conflict. */
- /* XXX: We can bring knowledge of object alignment and offset into
- play here. For example, on alpha, "char a, b;" can alias one
- another, though "char a; long b;" cannot. Similarly, offsets
- into strutures may be brought into play. Given "char a, b[40];",
- a and b[1] may overlap, but a and b[20] do not. */
+ /* The base addresses of the read and write are different expressions.
+ If they are both symbols and they are not accessed via AND, there is
+ no conflict. We can bring knowledge of object alignment into play
+ here. For example, on alpha, "char a, b;" can alias one another,
+ though "char a; long b;" cannot. */
if (GET_CODE (x_base) != ADDRESS && GET_CODE (y_base) != ADDRESS)
{
- return GET_CODE (x) == AND || GET_CODE (y) == AND;
+ if (GET_CODE (x) == AND && GET_CODE (y) == AND)
+ return 1;
+ if (GET_CODE (x) == AND
+ && (GET_CODE (XEXP (x, 1)) != CONST_INT
+ || GET_MODE_UNIT_SIZE (y_mode) < -INTVAL (XEXP (x, 1))))
+ return 1;
+ if (GET_CODE (y) == AND
+ && (GET_CODE (XEXP (y, 1)) != CONST_INT
+ || GET_MODE_UNIT_SIZE (x_mode) < -INTVAL (XEXP (y, 1))))
+ return 1;
+ /* Differing symbols never alias. */
+ return 0;
}
/* If one address is a stack reference there can be no alias:
@@ -661,6 +865,45 @@ base_alias_check (x, y)
return ! (GET_MODE (x_base) == VOIDmode && GET_MODE (y_base) == VOIDmode);
}
+/* Return the address of the (N_REFS + 1)th memory reference to ADDR
+ where SIZE is the size in bytes of the memory reference. If ADDR
+ is not modified by the memory reference then ADDR is returned. */
+
+rtx
+addr_side_effect_eval (addr, size, n_refs)
+ rtx addr;
+ int size;
+ int n_refs;
+{
+ int offset = 0;
+
+ switch (GET_CODE (addr))
+ {
+ case PRE_INC:
+ offset = (n_refs + 1) * size;
+ break;
+ case PRE_DEC:
+ offset = -(n_refs + 1) * size;
+ break;
+ case POST_INC:
+ offset = n_refs * size;
+ break;
+ case POST_DEC:
+ offset = -n_refs * size;
+ break;
+
+ default:
+ return addr;
+ }
+
+ if (offset)
+ addr = gen_rtx_PLUS (GET_MODE (addr), XEXP (addr, 0), GEN_INT (offset));
+ else
+ addr = XEXP (addr, 0);
+
+ return addr;
+}
+
/* Return nonzero if X and Y (memory addresses) could reference the
same location in memory. C is an offset accumulator. When
C is nonzero, we are testing aliases between X and Y + C.
@@ -690,13 +933,13 @@ memrefs_conflict_p (xsize, x, ysize, y, c)
else if (GET_CODE (x) == LO_SUM)
x = XEXP (x, 1);
else
- x = canon_rtx (x);
+ x = canon_rtx (addr_side_effect_eval (x, xsize, 0));
if (GET_CODE (y) == HIGH)
y = XEXP (y, 0);
else if (GET_CODE (y) == LO_SUM)
y = XEXP (y, 1);
else
- y = canon_rtx (y);
+ y = canon_rtx (addr_side_effect_eval (y, ysize, 0));
if (rtx_equal_for_memref_p (x, y))
{
@@ -792,7 +1035,7 @@ memrefs_conflict_p (xsize, x, ysize, y, c)
/* Are these registers known not to be equal? */
if (alias_invariant)
{
- int r_x = REGNO (x), r_y = REGNO (y);
+ unsigned int r_x = REGNO (x), r_y = REGNO (y);
rtx i_x, i_y; /* invariant relationships of X and Y */
i_x = r_x >= reg_base_value_size ? 0 : alias_invariant[r_x];
@@ -812,18 +1055,24 @@ memrefs_conflict_p (xsize, x, ysize, y, c)
}
/* Treat an access through an AND (e.g. a subword access on an Alpha)
- as an access with indeterminate size.
- ??? Could instead convert an n byte reference at (and x y) to an
- n-y byte reference at (plus x y). */
+ as an access with indeterminate size. Assume that references
+ besides AND are aligned, so if the size of the other reference is
+ at least as large as the alignment, assume no other overlap. */
if (GET_CODE (x) == AND && GET_CODE (XEXP (x, 1)) == CONST_INT)
- return memrefs_conflict_p (-1, XEXP (x, 0), ysize, y, c);
+ {
+ if (GET_CODE (y) == AND || ysize < -INTVAL (XEXP (x, 1)))
+ xsize = -1;
+ return memrefs_conflict_p (xsize, XEXP (x, 0), ysize, y, c);
+ }
if (GET_CODE (y) == AND && GET_CODE (XEXP (y, 1)) == CONST_INT)
{
- /* XXX: If we are indexing far enough into the array/structure, we
+ /* ??? If we are indexing far enough into the array/structure, we
may yet be able to determine that we can not overlap. But we
also need to that we are far enough from the end not to overlap
- a following reference, so we do nothing for now. */
- return memrefs_conflict_p (xsize, x, -1, XEXP (y, 0), c);
+ a following reference, so we do nothing with that for now. */
+ if (GET_CODE (x) == AND || xsize < -INTVAL (XEXP (y, 1)))
+ ysize = -1;
+ return memrefs_conflict_p (xsize, x, ysize, XEXP (y, 0), c);
}
if (CONSTANT_P (x))
@@ -891,6 +1140,56 @@ read_dependence (mem, x)
return MEM_VOLATILE_P (x) && MEM_VOLATILE_P (mem);
}
+/* Returns MEM1 if and only if MEM1 is a scalar at a fixed address and
+ MEM2 is a reference to a structure at a varying address, or returns
+ MEM2 if vice versa. Otherwise, returns NULL_RTX. If a non-NULL
+ value is returned MEM1 and MEM2 can never alias. VARIES_P is used
+ to decide whether or not an address may vary; it should return
+ nozero whenever variation is possible. */
+
+static rtx
+fixed_scalar_and_varying_struct_p (mem1, mem2, varies_p)
+ rtx mem1;
+ rtx mem2;
+ int (*varies_p) PROTO((rtx));
+{
+ rtx mem1_addr = XEXP (mem1, 0);
+ rtx mem2_addr = XEXP (mem2, 0);
+
+ if (MEM_SCALAR_P (mem1) && MEM_IN_STRUCT_P (mem2)
+ && !varies_p (mem1_addr) && varies_p (mem2_addr))
+ /* MEM1 is a scalar at a fixed address; MEM2 is a struct at a
+ varying address. */
+ return mem1;
+
+ if (MEM_IN_STRUCT_P (mem1) && MEM_SCALAR_P (mem2)
+ && varies_p (mem1_addr) && !varies_p (mem2_addr))
+ /* MEM2 is a scalar at a fixed address; MEM1 is a struct at a
+ varying address. */
+ return mem2;
+
+ return NULL_RTX;
+}
+
+/* Returns nonzero if something about the mode or address format MEM1
+ indicates that it might well alias *anything*. */
+
+static int
+aliases_everything_p (mem)
+ rtx mem;
+{
+ if (GET_MODE (mem) == QImode)
+ /* ANSI C says that a `char*' can point to anything. */
+ return 1;
+
+ if (GET_CODE (XEXP (mem, 0)) == AND)
+ /* If the address is an AND, its very hard to know at what it is
+ actually pointing. */
+ return 1;
+
+ return 0;
+}
+
/* True dependence: X is read after store in MEM takes place. */
int
@@ -918,53 +1217,46 @@ true_dependence (mem, mem_mode, x, varies)
if (RTX_UNCHANGING_P (x) && ! RTX_UNCHANGING_P (mem))
return 0;
- if (! base_alias_check (XEXP (x, 0), XEXP (mem, 0)))
+ if (mem_mode == VOIDmode)
+ mem_mode = GET_MODE (mem);
+
+ if (! base_alias_check (XEXP (x, 0), XEXP (mem, 0), GET_MODE (x), mem_mode))
return 0;
x_addr = canon_rtx (XEXP (x, 0));
mem_addr = canon_rtx (XEXP (mem, 0));
- if (mem_mode == VOIDmode)
- mem_mode = GET_MODE (mem);
-
if (! memrefs_conflict_p (GET_MODE_SIZE (mem_mode), mem_addr,
SIZE_FOR_MODE (x), x_addr, 0))
return 0;
- /* If both references are struct references, or both are not, nothing
- is known about aliasing.
-
- If either reference is QImode or BLKmode, ANSI C permits aliasing.
-
- If both addresses are constant, or both are not, nothing is known
- about aliasing. */
- if (MEM_IN_STRUCT_P (x) == MEM_IN_STRUCT_P (mem)
- || mem_mode == QImode || mem_mode == BLKmode
- || GET_MODE (x) == QImode || GET_MODE (x) == BLKmode
- || GET_CODE (x_addr) == AND || GET_CODE (mem_addr) == AND
- || varies (x_addr) == varies (mem_addr))
+ if (aliases_everything_p (x))
return 1;
- /* One memory reference is to a constant address, one is not.
- One is to a structure, the other is not.
+ /* We cannot use aliases_everyting_p to test MEM, since we must look
+ at MEM_MODE, rather than GET_MODE (MEM). */
+ if (mem_mode == QImode || GET_CODE (mem_addr) == AND)
+ return 1;
- If either memory reference is a variable structure the other is a
- fixed scalar and there is no aliasing. */
- if ((MEM_IN_STRUCT_P (mem) && varies (mem_addr))
- || (MEM_IN_STRUCT_P (x) && varies (x_addr)))
- return 0;
+ /* In true_dependence we also allow BLKmode to alias anything. Why
+ don't we do this in anti_dependence and output_dependence? */
+ if (mem_mode == BLKmode || GET_MODE (x) == BLKmode)
+ return 1;
- return 1;
+ return !fixed_scalar_and_varying_struct_p (mem, x, varies);
}
-/* Anti dependence: X is written after read in MEM takes place. */
+/* Returns non-zero if a write to X might alias a previous read from
+ (or, if WRITEP is non-zero, a write to) MEM. */
-int
-anti_dependence (mem, x)
+static int
+write_dependence_p (mem, x, writep)
rtx mem;
rtx x;
+ int writep;
{
rtx x_addr, mem_addr;
+ rtx fixed_scalar;
if (MEM_VOLATILE_P (x) && MEM_VOLATILE_P (mem))
return 1;
@@ -972,10 +1264,11 @@ anti_dependence (mem, x)
/* If MEM is an unchanging read, then it can't possibly conflict with
the store to X, because there is at most one store to MEM, and it must
have occurred somewhere before MEM. */
- if (RTX_UNCHANGING_P (mem))
+ if (!writep && RTX_UNCHANGING_P (mem))
return 0;
- if (! base_alias_check (XEXP (x, 0), XEXP (mem, 0)))
+ if (! base_alias_check (XEXP (x, 0), XEXP (mem, 0), GET_MODE (x),
+ GET_MODE (mem)))
return 0;
x = canon_rtx (x);
@@ -987,16 +1280,25 @@ anti_dependence (mem, x)
x_addr = XEXP (x, 0);
mem_addr = XEXP (mem, 0);
- return (memrefs_conflict_p (SIZE_FOR_MODE (mem), mem_addr,
- SIZE_FOR_MODE (x), x_addr, 0)
- && ! (MEM_IN_STRUCT_P (mem) && rtx_addr_varies_p (mem)
- && GET_MODE (mem) != QImode
- && GET_CODE (mem_addr) != AND
- && ! MEM_IN_STRUCT_P (x) && ! rtx_addr_varies_p (x))
- && ! (MEM_IN_STRUCT_P (x) && rtx_addr_varies_p (x)
- && GET_MODE (x) != QImode
- && GET_CODE (x_addr) != AND
- && ! MEM_IN_STRUCT_P (mem) && ! rtx_addr_varies_p (mem)));
+ if (!memrefs_conflict_p (SIZE_FOR_MODE (mem), mem_addr,
+ SIZE_FOR_MODE (x), x_addr, 0))
+ return 0;
+
+ fixed_scalar
+ = fixed_scalar_and_varying_struct_p (mem, x, rtx_addr_varies_p);
+
+ return (!(fixed_scalar == mem && !aliases_everything_p (x))
+ && !(fixed_scalar == x && !aliases_everything_p (mem)));
+}
+
+/* Anti dependence: X is written after read in MEM takes place. */
+
+int
+anti_dependence (mem, x)
+ rtx mem;
+ rtx x;
+{
+ return write_dependence_p (mem, x, /*writep=*/0);
}
/* Output dependence: X is written after store in MEM takes place. */
@@ -1006,28 +1308,7 @@ output_dependence (mem, x)
register rtx mem;
register rtx x;
{
- if (MEM_VOLATILE_P (x) && MEM_VOLATILE_P (mem))
- return 1;
-
- if (! base_alias_check (XEXP (x, 0), XEXP (mem, 0)))
- return 0;
-
- x = canon_rtx (x);
- mem = canon_rtx (mem);
-
- if (DIFFERENT_ALIAS_SETS_P (x, mem))
- return 0;
-
- return (memrefs_conflict_p (SIZE_FOR_MODE (mem), XEXP (mem, 0),
- SIZE_FOR_MODE (x), XEXP (x, 0), 0)
- && ! (MEM_IN_STRUCT_P (mem) && rtx_addr_varies_p (mem)
- && GET_MODE (mem) != QImode
- && GET_CODE (XEXP (mem, 0)) != AND
- && ! MEM_IN_STRUCT_P (x) && ! rtx_addr_varies_p (x))
- && ! (MEM_IN_STRUCT_P (x) && rtx_addr_varies_p (x)
- && GET_MODE (x) != QImode
- && GET_CODE (XEXP (x, 0)) != AND
- && ! MEM_IN_STRUCT_P (mem) && ! rtx_addr_varies_p (mem)));
+ return write_dependence_p (mem, x, /*writep=*/1);
}
@@ -1048,6 +1329,8 @@ init_alias_once ()
if (FUNCTION_ARG_REGNO_P (OUTGOING_REGNO (i))
&& HARD_REGNO_MODE_OK (i, Pmode))
SET_HARD_REG_BIT (argument_registers, i);
+
+ alias_sets = splay_tree_new (alias_set_compare, 0, 0);
}
void
@@ -1056,6 +1339,7 @@ init_alias_analysis ()
int maxreg = max_reg_num ();
int changed, pass;
register int i;
+ register unsigned int ui;
register rtx insn;
reg_known_value_size = maxreg;
@@ -1182,7 +1466,8 @@ init_alias_analysis ()
&& (((note = find_reg_note (insn, REG_EQUAL, 0)) != 0
&& REG_N_SETS (REGNO (SET_DEST (set))) == 1)
|| (note = find_reg_note (insn, REG_EQUIV, NULL_RTX)) != 0)
- && GET_CODE (XEXP (note, 0)) != EXPR_LIST)
+ && GET_CODE (XEXP (note, 0)) != EXPR_LIST
+ && ! reg_overlap_mentioned_p (SET_DEST (set), XEXP (note, 0)))
{
int regno = REGNO (SET_DEST (set));
reg_known_value[regno] = XEXP (note, 0);
@@ -1195,13 +1480,13 @@ init_alias_analysis ()
}
/* Now propagate values from new_reg_base_value to reg_base_value. */
- for (i = 0; i < reg_base_value_size; i++)
+ for (ui = 0; ui < reg_base_value_size; ui++)
{
- if (new_reg_base_value[i]
- && new_reg_base_value[i] != reg_base_value[i]
- && ! rtx_equal_p (new_reg_base_value[i], reg_base_value[i]))
+ if (new_reg_base_value[ui]
+ && new_reg_base_value[ui] != reg_base_value[ui]
+ && ! rtx_equal_p (new_reg_base_value[ui], reg_base_value[ui]))
{
- reg_base_value[i] = new_reg_base_value[i];
+ reg_base_value[ui] = new_reg_base_value[ui];
changed = 1;
}
}
@@ -1228,16 +1513,16 @@ init_alias_analysis ()
{
changed = 0;
pass++;
- for (i = 0; i < reg_base_value_size; i++)
+ for (ui = 0; ui < reg_base_value_size; ui++)
{
- rtx base = reg_base_value[i];
+ rtx base = reg_base_value[ui];
if (base && GET_CODE (base) == REG)
{
- int base_regno = REGNO (base);
- if (base_regno == i) /* register set from itself */
- reg_base_value[i] = 0;
+ unsigned int base_regno = REGNO (base);
+ if (base_regno == ui) /* register set from itself */
+ reg_base_value[ui] = 0;
else
- reg_base_value[i] = reg_base_value[base_regno];
+ reg_base_value[ui] = reg_base_value[base_regno];
changed = 1;
}
}
diff --git a/gcc/basic-block.h b/gcc/basic-block.h
index 552f74a5d9f..fa3d56f25d6 100644
--- a/gcc/basic-block.h
+++ b/gcc/basic-block.h
@@ -1,5 +1,5 @@
/* Define control and data flow tables, and regsets.
- Copyright (C) 1987, 1997, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1987, 1997, 1998, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -20,6 +20,8 @@ Boston, MA 02111-1307, USA. */
#include "bitmap.h"
+#include "sbitmap.h"
+#include "varray.h"
typedef bitmap regset; /* Head of register set linked list. */
@@ -94,29 +96,65 @@ do { \
/* Grow any tables needed when the number of registers is calculated
or extended. For the linked list allocation, nothing needs to
be done, other than zero the statistics on the first allocation. */
-#define MAX_REGNO_REG_SET(NUM_REGS, NEW_P, RENUMBER_P)
+#define MAX_REGNO_REG_SET(NUM_REGS, NEW_P, RENUMBER_P)
-/* Number of basic blocks in the current function. */
+/* Control flow edge information. */
+typedef struct edge_def {
+ /* Links through the predecessor and successor lists. */
+ struct edge_def *pred_next, *succ_next;
-extern int n_basic_blocks;
+ /* The two blocks at the ends of the edge. */
+ struct basic_block_def *src, *dest;
+
+ /* Instructions queued on the edge. */
+ rtx insns;
+
+ /* Auxiliary info specific to a pass. */
+ void *aux;
+
+ int flags; /* see EDGE_* below */
+ int probability; /* biased by REG_BR_PROB_BASE */
+} *edge;
+
+#define EDGE_FALLTHRU 1
+#define EDGE_CRITICAL 2
+#define EDGE_ABNORMAL 4
+#define EDGE_ABNORMAL_CALL 8
+#define EDGE_EH 16
+#define EDGE_FAKE 32
+
+
+/* Basic block information indexed by block number. */
+typedef struct basic_block_def {
+ /* The first and last insns of the block. */
+ rtx head, end;
+
+ /* The edges into and out of the block. */
+ edge pred, succ;
-/* Index by basic block number, get first insn in the block. */
+ /* Liveness info. */
+ regset local_set;
+ regset global_live_at_start;
+ regset global_live_at_end;
-extern rtx *basic_block_head;
+ /* Auxiliary info specific to a pass. */
+ void *aux;
-/* Index by basic block number, get last insn in the block. */
+ /* The index of this block. */
+ int index;
+ /* The loop depth of this block plus one. */
+ int loop_depth;
+} *basic_block;
-extern rtx *basic_block_end;
+/* Number of basic blocks in the current function. */
-/* Index by basic block number, determine whether the block can be reached
- through a computed jump. */
+extern int n_basic_blocks;
-extern char *basic_block_computed_jump_target;
+/* Index by basic block number, get basic block struct info. */
-/* Index by basic block number, get address of regset
- describing the registers live at the start of that block. */
+extern varray_type basic_block_info;
-extern regset *basic_block_live_at_start;
+#define BASIC_BLOCK(N) (VARRAY_BB (basic_block_info, (N)))
/* What registers are live at the setjmp call. */
@@ -176,91 +214,49 @@ extern void free_int_list PROTO ((int_list_block **));
/* Stuff for recording basic block info. */
-#define BLOCK_HEAD(B) basic_block_head[(B)]
-#define BLOCK_END(B) basic_block_end[(B)]
+#define BLOCK_HEAD(B) (BASIC_BLOCK (B)->head)
+#define BLOCK_END(B) (BASIC_BLOCK (B)->end)
/* Special block numbers [markers] for entry and exit. */
#define ENTRY_BLOCK (-1)
#define EXIT_BLOCK (-2)
+/* Similarly, block pointers for the edge list. */
+extern struct basic_block_def entry_exit_blocks[2];
+#define ENTRY_BLOCK_PTR (&entry_exit_blocks[0])
+#define EXIT_BLOCK_PTR (&entry_exit_blocks[1])
+
/* from flow.c */
-extern void free_regset_vector PROTO ((regset *, int nelts));
-extern int *uid_block_number;
-#define BLOCK_NUM(INSN) uid_block_number[INSN_UID (INSN)]
-
-extern void compute_preds_succs PROTO ((int_list_ptr *, int_list_ptr *,
- int *, int *));
-extern void dump_bb_data PROTO ((FILE *, int_list_ptr *, int_list_ptr *));
-extern void free_bb_mem PROTO ((void));
-extern void free_basic_block_vars PROTO ((int));
+extern void free_regset_vector PROTO ((regset *, int nelts));
-
-/* Simple bitmaps.
- It's not clear yet whether using bitmap.[ch] will be a win.
- It should be straightforward to convert so for now we keep things simple
- while more important issues are dealt with. */
-
-#define SBITMAP_ELT_BITS HOST_BITS_PER_WIDE_INT
-#define SBITMAP_ELT_TYPE unsigned HOST_WIDE_INT
-
-typedef struct simple_bitmap_def {
- /* Number of bits. */
- int n_bits;
- /* Size in elements. */
- int size;
- /* Size in bytes. */
- int bytes;
- /* The elements. */
- SBITMAP_ELT_TYPE elms[1];
-} *sbitmap;
-
-typedef SBITMAP_ELT_TYPE *sbitmap_ptr;
-
-/* Return the set size needed for N elements. */
-#define SBITMAP_SET_SIZE(n) (((n) + SBITMAP_ELT_BITS - 1) / SBITMAP_ELT_BITS)
-
-/* set bit number bitno in the bitmap */
-#define SET_BIT(bitmap, bitno) \
-do { \
- (bitmap)->elms [(bitno) / SBITMAP_ELT_BITS] |= (SBITMAP_ELT_TYPE) 1 << (bitno) % SBITMAP_ELT_BITS; \
-} while (0)
+extern varray_type basic_block_for_insn;
+#define BLOCK_FOR_INSN(INSN) VARRAY_BB (basic_block_for_insn, INSN_UID (INSN))
+#define BLOCK_NUM(INSN) (BLOCK_FOR_INSN (INSN)->index + 0)
-/* test if bit number bitno in the bitmap is set */
-#define TEST_BIT(bitmap, bitno) \
-((bitmap)->elms [(bitno) / SBITMAP_ELT_BITS] & ((SBITMAP_ELT_TYPE) 1 << (bitno) % SBITMAP_ELT_BITS))
+extern void set_block_for_insn PROTO ((rtx, basic_block));
-/* reset bit number bitno in the bitmap */
-#define RESET_BIT(bitmap, bitno) \
-do { \
- (bitmap)->elms [(bitno) / SBITMAP_ELT_BITS] &= ~((SBITMAP_ELT_TYPE) 1 << (bitno) % SBITMAP_ELT_BITS); \
-} while (0)
+extern void dump_bb_data PROTO ((FILE *, int_list_ptr *,
+ int_list_ptr *, int));
+extern void free_bb_mem PROTO ((void));
+extern void free_basic_block_vars PROTO ((int));
+
+extern basic_block split_edge PROTO ((edge));
+extern void insert_insn_on_edge PROTO ((rtx, edge));
+extern void commit_edge_insertions PROTO ((void));
-extern void dump_sbitmap PROTO ((FILE *, sbitmap));
-extern void dump_sbitmap_vector PROTO ((FILE *, char *, char *,
- sbitmap *, int));
-extern sbitmap sbitmap_alloc PROTO ((int));
-extern sbitmap *sbitmap_vector_alloc PROTO ((int, int));
-extern void sbitmap_copy PROTO ((sbitmap, sbitmap));
-extern void sbitmap_zero PROTO ((sbitmap));
-extern void sbitmap_ones PROTO ((sbitmap));
-extern void sbitmap_vector_zero PROTO ((sbitmap *, int));
-extern void sbitmap_vector_ones PROTO ((sbitmap *, int));
-extern int sbitmap_union_of_diff PROTO ((sbitmap, sbitmap, sbitmap, sbitmap));
-extern void sbitmap_difference PROTO ((sbitmap, sbitmap, sbitmap));
-extern void sbitmap_not PROTO ((sbitmap, sbitmap));
-extern int sbitmap_a_or_b_and_c PROTO ((sbitmap, sbitmap, sbitmap, sbitmap));
-extern int sbitmap_a_and_b_or_c PROTO ((sbitmap, sbitmap, sbitmap, sbitmap));
-extern int sbitmap_a_and_b PROTO ((sbitmap, sbitmap, sbitmap));
-extern int sbitmap_a_or_b PROTO ((sbitmap, sbitmap, sbitmap));
-extern void sbitmap_intersect_of_predsucc PROTO ((sbitmap, sbitmap *,
- int, int_list_ptr *));
-extern void sbitmap_intersect_of_predecessors PROTO ((sbitmap, sbitmap *, int,
- int_list_ptr *));
-extern void sbitmap_intersect_of_successors PROTO ((sbitmap, sbitmap *, int,
- int_list_ptr *));
-extern void sbitmap_union_of_predecessors PROTO ((sbitmap, sbitmap *, int,
- int_list_ptr *));
-extern void sbitmap_union_of_successors PROTO ((sbitmap, sbitmap *, int,
+extern void compute_preds_succs PROTO ((int_list_ptr *, int_list_ptr *,
+ int *, int *));
+extern void compute_dominators PROTO ((sbitmap *, sbitmap *,
+ int_list_ptr *,
int_list_ptr *));
-extern void compute_dominators PROTO ((sbitmap *, sbitmap *,
- int_list_ptr *, int_list_ptr *));
+extern void compute_immediate_dominators PROTO ((int *, sbitmap *));
+
+/* In lcm.c */
+extern void pre_lcm PROTO ((int, int, int_list_ptr *,
+ int_list_ptr *,
+ sbitmap *, sbitmap *,
+ sbitmap *, sbitmap *));
+extern void pre_rev_lcm PROTO ((int, int, int_list_ptr *,
+ int_list_ptr *,
+ sbitmap *, sbitmap *,
+ sbitmap *, sbitmap *));
diff --git a/gcc/bitmap.c b/gcc/bitmap.c
index a5aa2e7c02f..b4fc0971601 100644
--- a/gcc/bitmap.c
+++ b/gcc/bitmap.c
@@ -613,10 +613,10 @@ void
bitmap_print (file, head, prefix, suffix)
FILE *file;
bitmap head;
- char *prefix;
- char *suffix;
+ const char *prefix;
+ const char *suffix;
{
- char *comma = "";
+ const char *comma = "";
int i;
fputs (prefix, file);
diff --git a/gcc/bitmap.h b/gcc/bitmap.h
index 2941574e59c..4ff0bf4987e 100644
--- a/gcc/bitmap.h
+++ b/gcc/bitmap.h
@@ -1,5 +1,5 @@
/* Functions to support general ended bitmaps.
- Copyright (C) 1997 Free Software Foundation, Inc.
+ Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -48,7 +48,7 @@ typedef struct bitmap_element_def
typedef struct bitmap_head_def {
bitmap_element *first; /* First element in linked list. */
bitmap_element *current; /* Last element looked at. */
- int indx; /* Index of last element looked at. */
+ unsigned int indx; /* Index of last element looked at. */
} bitmap_head, *bitmap;
/* Enumeration giving the various operations we support. */
@@ -89,7 +89,7 @@ extern void bitmap_debug PROTO((bitmap));
extern void bitmap_debug_file PROTO((FILE *, bitmap));
/* Print a bitmap */
-extern void bitmap_print PROTO((FILE *, bitmap, char *, char *));
+extern void bitmap_print PROTO((FILE *, bitmap, const char *, const char *));
/* Initialize a bitmap header. */
extern bitmap bitmap_initialize PROTO((bitmap));
diff --git a/gcc/c-aux-info.c b/gcc/c-aux-info.c
index 3e2edde0449..f4238dd29e3 100644
--- a/gcc/c-aux-info.c
+++ b/gcc/c-aux-info.c
@@ -1,7 +1,7 @@
/* Generate information regarding function declarations and definitions based
on information stored in GCC's tree structure. This code implements the
-aux-info option.
- Copyright (C) 1989, 91, 94, 95, 97, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1989, 91, 94, 95, 97-98, 1999 Free Software Foundation, Inc.
Contributed by Ron Guilmette (rfg@segfault.us.com).
This file is part of GNU CC.
@@ -35,67 +35,75 @@ enum formals_style_enum {
typedef enum formals_style_enum formals_style;
-static char *data_type;
+static const char *data_type;
-static char *concat PROTO((char *, char *));
-static char *concat3 PROTO((char *, char *, char *));
-static char *affix_data_type PROTO((char *));
-static char *gen_formal_list_for_type PROTO((tree, formals_style));
+static char *affix_data_type PROTO((const char *));
+static const char *gen_formal_list_for_type PROTO((tree, formals_style));
static int deserves_ellipsis PROTO((tree));
-static char *gen_formal_list_for_func_def PROTO((tree, formals_style));
-static char *gen_type PROTO((char *, tree, formals_style));
-static char *gen_decl PROTO((tree, int, formals_style));
+static const char *gen_formal_list_for_func_def PROTO((tree, formals_style));
+static const char *gen_type PROTO((const char *, tree, formals_style));
+static const char *gen_decl PROTO((tree, int, formals_style));
-/* Take two strings and mash them together into a newly allocated area. */
+/* Concatenate a sequence of strings, returning the result.
-static char *
-concat (s1, s2)
- char *s1;
- char *s2;
+ This function is based on the one in libiberty. */
+
+/* This definition will conflict with the one from prefix.c in
+ libcpp.a when linking cc1 and cc1obj. So only provide it if we are
+ not using libcpp.a */
+#ifndef USE_CPPLIB
+char *
+concat VPROTO((const char *first, ...))
{
- int size1, size2;
- char *ret_val;
-
- if (!s1)
- s1 = "";
- if (!s2)
- s2 = "";
-
- size1 = strlen (s1);
- size2 = strlen (s2);
- ret_val = xmalloc (size1 + size2 + 1);
- strcpy (ret_val, s1);
- strcpy (&ret_val[size1], s2);
- return ret_val;
-}
+ register int length;
+ register char *newstr;
+ register char *end;
+ register const char *arg;
+ va_list args;
+#ifndef ANSI_PROTOTYPES
+ const char *first;
+#endif
+
+ /* First compute the size of the result and get sufficient memory. */
+
+ VA_START (args, first);
+#ifndef ANSI_PROTOTYPES
+ first = va_arg (args, const char *);
+#endif
+
+ arg = first;
+ length = 0;
+
+ while (arg != 0)
+ {
+ length += strlen (arg);
+ arg = va_arg (args, const char *);
+ }
-/* Take three strings and mash them together into a newly allocated area. */
+ newstr = (char *) malloc (length + 1);
+ va_end (args);
-static char *
-concat3 (s1, s2, s3)
- char *s1;
- char *s2;
- char *s3;
-{
- int size1, size2, size3;
- char *ret_val;
-
- if (!s1)
- s1 = "";
- if (!s2)
- s2 = "";
- if (!s3)
- s3 = "";
-
- size1 = strlen (s1);
- size2 = strlen (s2);
- size3 = strlen (s3);
- ret_val = xmalloc (size1 + size2 + size3 + 1);
- strcpy (ret_val, s1);
- strcpy (&ret_val[size1], s2);
- strcpy (&ret_val[size1+size2], s3);
- return ret_val;
+ /* Now copy the individual pieces to the result string. */
+
+ VA_START (args, first);
+#ifndef ANSI_PROTOTYPES
+ first = va_arg (args, char *);
+#endif
+
+ end = newstr;
+ arg = first;
+ while (arg != 0)
+ {
+ while (*arg)
+ *end++ = *arg++;
+ arg = va_arg (args, const char *);
+ }
+ *end = '\000';
+ va_end (args);
+
+ return (newstr);
}
+#endif /* ! USE_CPPLIB */
/* Given a string representing an entire type or an entire declaration
which only lacks the actual "data-type" specifier (at its left end),
@@ -112,13 +120,16 @@ concat3 (s1, s2, s3)
that look as expected. */
static char *
-affix_data_type (type_or_decl)
- char *type_or_decl;
+affix_data_type (param)
+ const char *param;
{
+ char *type_or_decl = (char *) alloca (strlen (param) + 1);
char *p = type_or_decl;
char *qualifiers_then_data_type;
char saved;
+ strcpy (type_or_decl, param);
+
/* Skip as many leading const's or volatile's as there are. */
for (;;)
@@ -140,13 +151,13 @@ affix_data_type (type_or_decl)
add a blank after the data-type of course. */
if (p == type_or_decl)
- return concat3 (data_type, " ", type_or_decl);
+ return concat (data_type, " ", type_or_decl, NULL_PTR);
saved = *p;
*p = '\0';
- qualifiers_then_data_type = concat (type_or_decl, data_type);
+ qualifiers_then_data_type = concat (type_or_decl, data_type, NULL_PTR);
*p = saved;
- return concat3 (qualifiers_then_data_type, " ", p);
+ return concat (qualifiers_then_data_type, " ", p, NULL_PTR);
}
/* Given a tree node which represents some "function type", generate the
@@ -156,12 +167,12 @@ affix_data_type (type_or_decl)
we are currently aiming for is non-ansi, then we just return a pair
of empty parens here. */
-static char *
+static const char *
gen_formal_list_for_type (fntype, style)
tree fntype;
formals_style style;
{
- char *formal_list = "";
+ const char *formal_list = "";
tree formal_type;
if (style != ansi)
@@ -170,16 +181,16 @@ gen_formal_list_for_type (fntype, style)
formal_type = TYPE_ARG_TYPES (fntype);
while (formal_type && TREE_VALUE (formal_type) != void_type_node)
{
- char *this_type;
+ const char *this_type;
if (*formal_list)
- formal_list = concat (formal_list, ", ");
+ formal_list = concat (formal_list, ", ", NULL_PTR);
this_type = gen_type ("", TREE_VALUE (formal_type), ansi);
formal_list
= ((strlen (this_type))
- ? concat (formal_list, affix_data_type (this_type))
- : concat (formal_list, data_type));
+ ? concat (formal_list, affix_data_type (this_type), NULL_PTR)
+ : concat (formal_list, data_type, NULL_PTR));
formal_type = TREE_CHAIN (formal_type);
}
@@ -228,10 +239,10 @@ gen_formal_list_for_type (fntype, style)
petered out to a NULL (i.e. without being terminated by a
void_type_node) then we need to tack on an ellipsis. */
if (!formal_type)
- formal_list = concat (formal_list, ", ...");
+ formal_list = concat (formal_list, ", ...", NULL_PTR);
}
- return concat3 (" (", formal_list, ")");
+ return concat (" (", formal_list, ")", NULL_PTR);
}
/* For the generation of an ANSI prototype for a function definition, we have
@@ -276,37 +287,37 @@ deserves_ellipsis (fntype)
This routine returns a string which is the source form for the entire
function formal parameter list. */
-static char *
+static const char *
gen_formal_list_for_func_def (fndecl, style)
tree fndecl;
formals_style style;
{
- char *formal_list = "";
+ const char *formal_list = "";
tree formal_decl;
formal_decl = DECL_ARGUMENTS (fndecl);
while (formal_decl)
{
- char *this_formal;
+ const char *this_formal;
if (*formal_list && ((style == ansi) || (style == k_and_r_names)))
- formal_list = concat (formal_list, ", ");
+ formal_list = concat (formal_list, ", ", NULL_PTR);
this_formal = gen_decl (formal_decl, 0, style);
if (style == k_and_r_decls)
- formal_list = concat3 (formal_list, this_formal, "; ");
+ formal_list = concat (formal_list, this_formal, "; ", NULL_PTR);
else
- formal_list = concat (formal_list, this_formal);
+ formal_list = concat (formal_list, this_formal, NULL_PTR);
formal_decl = TREE_CHAIN (formal_decl);
}
if (style == ansi)
{
if (!DECL_ARGUMENTS (fndecl))
- formal_list = concat (formal_list, "void");
+ formal_list = concat (formal_list, "void", NULL_PTR);
if (deserves_ellipsis (TREE_TYPE (fndecl)))
- formal_list = concat (formal_list, ", ...");
+ formal_list = concat (formal_list, ", ...", NULL_PTR);
}
if ((style == ansi) || (style == k_and_r_names))
- formal_list = concat3 (" (", formal_list, ")");
+ formal_list = concat (" (", formal_list, ")", NULL_PTR);
return formal_list;
}
@@ -351,9 +362,9 @@ gen_formal_list_for_func_def (fndecl, style)
to do at this point is for the initial caller to prepend the "data_type"
string onto the returned "seed". */
-static char *
+static const char *
gen_type (ret_val, t, style)
- char *ret_val;
+ const char *ret_val;
tree t;
formals_style style;
{
@@ -368,14 +379,14 @@ gen_type (ret_val, t, style)
{
case POINTER_TYPE:
if (TYPE_READONLY (t))
- ret_val = concat ("const ", ret_val);
+ ret_val = concat ("const ", ret_val, NULL_PTR);
if (TYPE_VOLATILE (t))
- ret_val = concat ("volatile ", ret_val);
+ ret_val = concat ("volatile ", ret_val, NULL_PTR);
- ret_val = concat ("*", ret_val);
+ ret_val = concat ("*", ret_val, NULL_PTR);
if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE || TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE)
- ret_val = concat3 ("(", ret_val, ")");
+ ret_val = concat ("(", ret_val, ")", NULL_PTR);
ret_val = gen_type (ret_val, TREE_TYPE (t), style);
@@ -383,21 +394,26 @@ gen_type (ret_val, t, style)
case ARRAY_TYPE:
if (TYPE_SIZE (t) == 0 || TREE_CODE (TYPE_SIZE (t)) != INTEGER_CST)
- ret_val = gen_type (concat (ret_val, "[]"), TREE_TYPE (t), style);
+ ret_val = gen_type (concat (ret_val, "[]", NULL_PTR),
+ TREE_TYPE (t), style);
else if (int_size_in_bytes (t) == 0)
- ret_val = gen_type (concat (ret_val, "[0]"), TREE_TYPE (t), style);
+ ret_val = gen_type (concat (ret_val, "[0]", NULL_PTR),
+ TREE_TYPE (t), style);
else
{
int size = (int_size_in_bytes (t) / int_size_in_bytes (TREE_TYPE (t)));
char buff[10];
sprintf (buff, "[%d]", size);
- ret_val = gen_type (concat (ret_val, buff),
+ ret_val = gen_type (concat (ret_val, buff, NULL_PTR),
TREE_TYPE (t), style);
}
break;
case FUNCTION_TYPE:
- ret_val = gen_type (concat (ret_val, gen_formal_list_for_type (t, style)), TREE_TYPE (t), style);
+ ret_val = gen_type (concat (ret_val,
+ gen_formal_list_for_type (t, style),
+ NULL_PTR),
+ TREE_TYPE (t), style);
break;
case IDENTIFIER_NODE:
@@ -424,13 +440,14 @@ gen_type (ret_val, t, style)
chain_p = TYPE_FIELDS (t);
while (chain_p)
{
- data_type = concat (data_type, gen_decl (chain_p, 0, ansi));
+ data_type = concat (data_type, gen_decl (chain_p, 0, ansi),
+ NULL_PTR);
chain_p = TREE_CHAIN (chain_p);
- data_type = concat (data_type, "; ");
+ data_type = concat (data_type, "; ", NULL_PTR);
}
- data_type = concat3 ("{ ", data_type, "}");
+ data_type = concat ("{ ", data_type, "}", NULL_PTR);
}
- data_type = concat ("struct ", data_type);
+ data_type = concat ("struct ", data_type, NULL_PTR);
break;
case UNION_TYPE:
@@ -442,13 +459,14 @@ gen_type (ret_val, t, style)
chain_p = TYPE_FIELDS (t);
while (chain_p)
{
- data_type = concat (data_type, gen_decl (chain_p, 0, ansi));
+ data_type = concat (data_type, gen_decl (chain_p, 0, ansi),
+ NULL_PTR);
chain_p = TREE_CHAIN (chain_p);
- data_type = concat (data_type, "; ");
+ data_type = concat (data_type, "; ", NULL_PTR);
}
- data_type = concat3 ("{ ", data_type, "}");
+ data_type = concat ("{ ", data_type, "}", NULL_PTR);
}
- data_type = concat ("union ", data_type);
+ data_type = concat ("union ", data_type, NULL_PTR);
break;
case ENUMERAL_TYPE:
@@ -461,14 +479,14 @@ gen_type (ret_val, t, style)
while (chain_p)
{
data_type = concat (data_type,
- IDENTIFIER_POINTER (TREE_PURPOSE (chain_p)));
+ IDENTIFIER_POINTER (TREE_PURPOSE (chain_p)), NULL_PTR);
chain_p = TREE_CHAIN (chain_p);
if (chain_p)
- data_type = concat (data_type, ", ");
+ data_type = concat (data_type, ", ", NULL_PTR);
}
- data_type = concat3 ("{ ", data_type, " }");
+ data_type = concat ("{ ", data_type, " }", NULL_PTR);
}
- data_type = concat ("enum ", data_type);
+ data_type = concat ("enum ", data_type, NULL_PTR);
break;
case TYPE_DECL:
@@ -478,9 +496,9 @@ gen_type (ret_val, t, style)
case INTEGER_TYPE:
data_type = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (t)));
/* Normally, `unsigned' is part of the deal. Not so if it comes
- with `const' or `volatile'. */
- if (TREE_UNSIGNED (t) && (TYPE_READONLY (t) || TYPE_VOLATILE (t)))
- data_type = concat ("unsigned ", data_type);
+ with a type qualifier. */
+ if (TREE_UNSIGNED (t) && TYPE_QUALS (t))
+ data_type = concat ("unsigned ", data_type, NULL_PTR);
break;
case REAL_TYPE:
@@ -500,9 +518,11 @@ gen_type (ret_val, t, style)
}
}
if (TYPE_READONLY (t))
- ret_val = concat ("const ", ret_val);
+ ret_val = concat ("const ", ret_val, NULL_PTR);
if (TYPE_VOLATILE (t))
- ret_val = concat ("volatile ", ret_val);
+ ret_val = concat ("volatile ", ret_val, NULL_PTR);
+ if (TYPE_RESTRICT (t))
+ ret_val = concat ("restrict ", ret_val, NULL_PTR);
return ret_val;
}
@@ -516,13 +536,13 @@ gen_type (ret_val, t, style)
associated with a function definition. In this case, we can assume that
an attached list of DECL nodes for function formal arguments is present. */
-static char *
+static const char *
gen_decl (decl, is_func_definition, style)
tree decl;
int is_func_definition;
formals_style style;
{
- char *ret_val;
+ const char *ret_val;
if (DECL_NAME (decl))
ret_val = IDENTIFIER_POINTER (DECL_NAME (decl));
@@ -544,9 +564,9 @@ gen_decl (decl, is_func_definition, style)
generate the qualifiers here. */
if (TREE_THIS_VOLATILE (decl))
- ret_val = concat ("volatile ", ret_val);
+ ret_val = concat ("volatile ", ret_val, NULL_PTR);
if (TREE_READONLY (decl))
- ret_val = concat ("const ", ret_val);
+ ret_val = concat ("const ", ret_val, NULL_PTR);
data_type = "";
@@ -564,7 +584,8 @@ gen_decl (decl, is_func_definition, style)
if (TREE_CODE (decl) == FUNCTION_DECL && is_func_definition)
{
- ret_val = concat (ret_val, gen_formal_list_for_func_def (decl, ansi));
+ ret_val = concat (ret_val, gen_formal_list_for_func_def (decl, ansi),
+ NULL_PTR);
/* Since we have already added in the formals list stuff, here we don't
add the whole "type" of the function we are considering (which
@@ -581,11 +602,11 @@ gen_decl (decl, is_func_definition, style)
ret_val = affix_data_type (ret_val);
if (TREE_CODE (decl) != FUNCTION_DECL && DECL_REGISTER (decl))
- ret_val = concat ("register ", ret_val);
+ ret_val = concat ("register ", ret_val, NULL_PTR);
if (TREE_PUBLIC (decl))
- ret_val = concat ("extern ", ret_val);
+ ret_val = concat ("extern ", ret_val, NULL_PTR);
if (TREE_CODE (decl) == FUNCTION_DECL && !TREE_PUBLIC (decl))
- ret_val = concat ("static ", ret_val);
+ ret_val = concat ("static ", ret_val, NULL_PTR);
return ret_val;
}
diff --git a/gcc/c-common.c b/gcc/c-common.c
index 404c3072ef3..490bc335ba3 100644
--- a/gcc/c-common.c
+++ b/gcc/c-common.c
@@ -1,5 +1,5 @@
/* Subroutines shared by all languages that are variants of C.
- Copyright (C) 1992, 93, 94, 95, 96, 97, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1992, 93-98, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -28,6 +28,7 @@ Boston, MA 02111-1307, USA. */
#include "toplev.h"
#include "output.h"
#include "c-pragma.h"
+#include "rtl.h"
#if USE_CPPLIB
#include "cpplib.h"
@@ -144,7 +145,7 @@ tree c_global_trees[50];
int skip_evaluation;
enum attrs {A_PACKED, A_NOCOMMON, A_COMMON, A_NORETURN, A_CONST, A_T_UNION,
- A_NO_INSTRUMENT_FUNCTION,
+ A_NO_CHECK_MEMORY_USAGE, A_NO_INSTRUMENT_FUNCTION,
A_CONSTRUCTOR, A_DESTRUCTOR, A_MODE, A_SECTION, A_ALIGNED,
A_UNUSED, A_FORMAT, A_FORMAT_ARG, A_WEAK, A_ALIAS,
A_INIT_PRIORITY};
@@ -152,13 +153,14 @@ enum attrs {A_PACKED, A_NOCOMMON, A_COMMON, A_NORETURN, A_CONST, A_T_UNION,
enum format_type { printf_format_type, scanf_format_type,
strftime_format_type };
-static void declare_hidden_char_array PROTO((char *, char *));
-static void add_attribute PROTO((enum attrs, char *,
+static void declare_hidden_char_array PROTO((const char *, const char *));
+static void add_attribute PROTO((enum attrs, const char *,
int, int, int));
static void init_attributes PROTO((void));
static void record_function_format PROTO((tree, tree, enum format_type,
int, int));
static void record_international_format PROTO((tree, tree, int));
+static tree c_find_base_decl PROTO((tree));
/* Keep a stack of if statements. We record the number of compound
statements seen up to the if keyword, as well as the line number
@@ -169,9 +171,10 @@ typedef struct
{
int compstmt_count;
int line;
- char *file;
+ const char *file;
int needs_warning;
} if_elt;
+static void tfaff PROTO((void));
static if_elt *if_stack;
@@ -250,12 +253,12 @@ c_expand_start_else ()
expand_start_else ();
}
-/* Make bindings for __FUNCTION__ and __PRETTY_FUNCTION__. */
+/* Make bindings for __FUNCTION__, __PRETTY_FUNCTION__, and __func__. */
void
declare_function_name ()
{
- char *name, *printable_name;
+ const char *name, *printable_name;
if (current_function_decl == NULL)
{
@@ -274,11 +277,14 @@ declare_function_name ()
declare_hidden_char_array ("__FUNCTION__", name);
declare_hidden_char_array ("__PRETTY_FUNCTION__", printable_name);
+ /* The ISO C people "of course" couldn't use __FUNCTION__ in the
+ ISO C 9x standard; instead a new variable is invented. */
+ declare_hidden_char_array ("__func__", name);
}
static void
declare_hidden_char_array (name, value)
- char *name, *value;
+ const char *name, *value;
{
tree decl, type, init;
int vlen;
@@ -446,7 +452,7 @@ static int attrtab_idx = 0;
static void
add_attribute (id, string, min_len, max_len, decl_req)
enum attrs id;
- char *string;
+ const char *string;
int min_len, max_len;
int decl_req;
{
@@ -491,6 +497,7 @@ init_attributes ()
add_attribute (A_ALIAS, "alias", 1, 1, 1);
add_attribute (A_INIT_PRIORITY, "init_priority", 0, 1, 0);
add_attribute (A_NO_INSTRUMENT_FUNCTION, "no_instrument_function", 0, 0, 1);
+ add_attribute (A_NO_CHECK_MEMORY_USAGE, "no_check_memory_usage", 0, 0, 1);
}
/* Process the attributes listed in ATTRIBUTES and PREFIX_ATTRIBUTES
@@ -612,7 +619,8 @@ decl_attributes (node, attributes, prefix_attributes)
TREE_USED (type) = 1;
else if (TREE_CODE (decl) == PARM_DECL
|| TREE_CODE (decl) == VAR_DECL
- || TREE_CODE (decl) == FUNCTION_DECL)
+ || TREE_CODE (decl) == FUNCTION_DECL
+ || TREE_CODE (decl) == LABEL_DECL)
TREE_USED (decl) = 1;
else
warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
@@ -676,7 +684,7 @@ decl_attributes (node, attributes, prefix_attributes)
else
{
int j;
- char *p = IDENTIFIER_POINTER (TREE_VALUE (args));
+ const char *p = IDENTIFIER_POINTER (TREE_VALUE (args));
int len = strlen (p);
enum machine_mode mode = VOIDmode;
tree typefm;
@@ -808,7 +816,7 @@ decl_attributes (node, attributes, prefix_attributes)
}
else
{
- char *p = IDENTIFIER_POINTER (format_type_id);
+ const char *p = IDENTIFIER_POINTER (format_type_id);
if (!strcmp (p, "printf") || !strcmp (p, "__printf__"))
format_type = printf_format_type;
@@ -819,7 +827,7 @@ decl_attributes (node, attributes, prefix_attributes)
format_type = strftime_format_type;
else
{
- error ("`%s' is an unrecognized format function type", p);
+ warning ("`%s' is an unrecognized format function type", p);
continue;
}
}
@@ -986,6 +994,23 @@ decl_attributes (node, attributes, prefix_attributes)
warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
break;
+ case A_NO_CHECK_MEMORY_USAGE:
+ if (TREE_CODE (decl) != FUNCTION_DECL)
+ {
+ error_with_decl (decl,
+ "`%s' attribute applies only to functions",
+ IDENTIFIER_POINTER (name));
+ }
+ else if (DECL_INITIAL (decl))
+ {
+ error_with_decl (decl,
+ "can't set `%s' attribute after definition",
+ IDENTIFIER_POINTER (name));
+ }
+ else
+ DECL_NO_CHECK_MEMORY_USAGE (decl) = 1;
+ break;
+
case A_INIT_PRIORITY:
{
tree initp_expr = (args ? TREE_VALUE (args): NULL_TREE);
@@ -1017,24 +1042,18 @@ decl_attributes (node, attributes, prefix_attributes)
continue;
}
- /* Check for init_priorities that are reserved for
- implementation. Reserved for language and runtime
- support implementations.*/
- if ((10 <= pri && pri <= 99)
- /* Reserved for standard library implementations. */
- || (500 <= pri && pri <= 999)
- /* Reserved for objects with no attributes. */
- || pri > (MAX_INIT_PRIORITY - 50))
+ if (pri > MAX_INIT_PRIORITY || pri <= 0)
{
- warning
- ("requested init_priority is reserved for internal use");
+ error ("requested init_priority is out of range");
continue;
}
- if (pri > MAX_INIT_PRIORITY || pri <= 0)
+ /* Check for init_priorities that are reserved for
+ language and runtime support implementations.*/
+ if (pri <= MAX_RESERVED_INIT_PRIORITY)
{
- error ("requested init_priority is out of range");
- continue;
+ warning
+ ("requested init_priority is reserved for internal use");
}
static_aggregates_initp
@@ -1177,7 +1196,7 @@ strip_attrs (specs_attrs)
#define T_ST &sizetype
typedef struct {
- char *format_chars;
+ const char *format_chars;
int pointer_count;
/* Type of argument if no length modifier is used. */
tree *nolen;
@@ -1200,7 +1219,7 @@ typedef struct {
If NULL, then this modifier is not allowed. */
tree *zlen;
/* List of other modifier characters allowed with these options. */
- char *flag_chars;
+ const char *flag_chars;
} format_char_info;
static format_char_info print_char_table[] = {
@@ -1216,7 +1235,7 @@ static format_char_info print_char_table[] = {
{ "S", 1, T_W, NULL, NULL, NULL, NULL, NULL, NULL, "-wp" },
{ "p", 1, T_V, NULL, NULL, NULL, NULL, NULL, NULL, "-w" },
{ "n", 1, T_I, NULL, T_S, T_L, T_LL, NULL, NULL, "" },
- { NULL }
+ { NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
};
static format_char_info scan_char_table[] = {
@@ -1230,7 +1249,7 @@ static format_char_info scan_char_table[] = {
{ "S", 1, T_W, NULL, NULL, NULL, NULL, NULL, NULL, "*a" },
{ "p", 2, T_V, NULL, NULL, NULL, NULL, NULL, NULL, "*" },
{ "n", 1, T_I, T_C, T_S, T_L, T_LL, NULL, NULL, "" },
- { NULL }
+ { NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
};
/* Handle format characters recognized by glibc's strftime.c.
@@ -1255,7 +1274,7 @@ static format_char_info time_char_table[] = {
{ "p", 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, "#" },
{ "bh", 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, "^" },
{ "CY", 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, "-_0EOw" },
- { NULL }
+ { NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
};
typedef struct function_format_info
@@ -1400,7 +1419,11 @@ record_international_format (name, assembler_name, format_num)
info->format_num = format_num;
}
-static char tfaff[] = "too few arguments for format";
+static void
+tfaff ()
+{
+ warning ("too few arguments for format");
+}
/* Check the argument list of a call to printf, scanf, etc.
NAME is the function identifier.
@@ -1450,7 +1473,7 @@ check_format_info (info, params)
tree cur_type;
tree wanted_type;
tree first_fillin_param;
- char *format_chars;
+ const char *format_chars;
format_char_info *fci = NULL;
char flag_chars[8];
int has_operand_number = 0;
@@ -1614,7 +1637,7 @@ check_format_info (info, params)
it is an operand number, so set PARAMS to that operand. */
if (*format_chars >= '0' && *format_chars <= '9')
{
- char *p = format_chars;
+ const char *p = format_chars;
while (*p >= '0' && *p++ <= '9')
;
@@ -1667,7 +1690,7 @@ check_format_info (info, params)
++format_chars;
if (params == 0)
{
- warning (tfaff);
+ tfaff ();
return;
}
if (info->first_arg_num != 0)
@@ -1710,7 +1733,7 @@ check_format_info (info, params)
++format_chars;
if (params == 0)
{
- warning (tfaff);
+ tfaff ();
return;
}
cur_param = TREE_VALUE (params);
@@ -1880,7 +1903,7 @@ check_format_info (info, params)
if (precise && index (flag_chars, '0') != 0
&& (format_char == 'd' || format_char == 'i'
|| format_char == 'o' || format_char == 'u'
- || format_char == 'x' || format_char == 'x'))
+ || format_char == 'x' || format_char == 'X'))
warning ("`0' flag ignored with precision specifier and `%c' format",
format_char);
switch (length_char)
@@ -1905,7 +1928,7 @@ check_format_info (info, params)
continue;
if (params == 0)
{
- warning (tfaff);
+ tfaff ();
return;
}
cur_param = TREE_VALUE (params);
@@ -1931,9 +1954,9 @@ check_format_info (info, params)
continue;
}
if (TREE_CODE (cur_type) != ERROR_MARK)
- warning ("format argument is not a %s (arg %d)",
- ((fci->pointer_count + aflag == 1)
- ? "pointer" : "pointer to a pointer"),
+ warning ((fci->pointer_count + aflag == 1
+ ? "format argument is not a pointer (arg %d)"
+ : "format argument is not a pointer to a pointer (arg %d)"),
arg_num);
break;
}
@@ -1973,8 +1996,8 @@ check_format_info (info, params)
&& (TYPE_MAIN_VARIANT (cur_type) == signed_char_type_node
|| TYPE_MAIN_VARIANT (cur_type) == unsigned_char_type_node)))
{
- register char *this;
- register char *that;
+ register const char *this;
+ register const char *that;
this = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (wanted_type)));
that = 0;
@@ -2243,8 +2266,10 @@ type_for_mode (mode, unsignedp)
if (mode == TYPE_MODE (intDI_type_node))
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;
@@ -2302,7 +2327,7 @@ void
binary_op_error (code)
enum tree_code code;
{
- register char *opname;
+ register const char *opname;
switch (code)
{
@@ -2478,6 +2503,12 @@ shorten_compare (op0_ptr, op1_ptr, restype_ptr, rescode_ptr)
type = signed_or_unsigned_type (unsignedp0, TREE_TYPE (primop0));
+ /* If TYPE is an enumeration, then we need to get its min/max
+ values from it's underlying integral type, not the enumerated
+ type itself. */
+ if (TREE_CODE (type) == ENUMERAL_TYPE)
+ type = type_for_size (TYPE_PRECISION (type), unsignedp0);
+
maxval = TYPE_MAX_VALUE (type);
minval = TYPE_MIN_VALUE (type);
@@ -2587,18 +2618,18 @@ shorten_compare (op0_ptr, op1_ptr, restype_ptr, rescode_ptr)
/* This is the case of (char)x >?< 0x80, which people used to use
expecting old C compilers to change the 0x80 into -0x80. */
if (val == boolean_false_node)
- warning ("comparison is always 0 due to limited range of data type");
+ warning ("comparison is always false due to limited range of data type");
if (val == boolean_true_node)
- warning ("comparison is always 1 due to limited range of data type");
+ warning ("comparison is always true due to limited range of data type");
}
if (!min_lt && unsignedp0 && TREE_CODE (primop0) != INTEGER_CST)
{
/* This is the case of (unsigned char)x >?< -1 or < 0. */
if (val == boolean_false_node)
- warning ("comparison is always 0 due to limited range of data type");
+ warning ("comparison is always false due to limited range of data type");
if (val == boolean_true_node)
- warning ("comparison is always 1 due to limited range of data type");
+ warning ("comparison is always true due to limited range of data type");
}
if (val != 0)
@@ -2664,7 +2695,7 @@ shorten_compare (op0_ptr, op1_ptr, restype_ptr, rescode_ptr)
&& ! (TREE_CODE (primop0) == INTEGER_CST
&& ! TREE_OVERFLOW (convert (signed_type (type),
primop0))))
- warning ("unsigned value >= 0 is always 1");
+ warning ("comparison of unsigned expression >= 0 is always true");
value = boolean_true_node;
break;
@@ -2673,7 +2704,7 @@ shorten_compare (op0_ptr, op1_ptr, restype_ptr, rescode_ptr)
&& ! (TREE_CODE (primop0) == INTEGER_CST
&& ! TREE_OVERFLOW (convert (signed_type (type),
primop0))))
- warning ("unsigned value < 0 is always 0");
+ warning ("comparison of unsigned expression < 0 is always false");
value = boolean_false_node;
break;
@@ -2898,7 +2929,7 @@ truthvalue_conversion (expr)
unsigned char *yy_cur, *yy_lim;
#define GETC() (yy_cur < yy_lim ? *yy_cur++ : yy_get_token ())
-#define UNGETC(c) ((c), yy_cur--)
+#define UNGETC(c) ((c) == EOF ? 0 : yy_cur--)
int
yy_get_token ()
@@ -3072,15 +3103,134 @@ get_directive_line (finput)
down to the element type of an array. */
tree
-c_build_type_variant (type, constp, volatilep)
+c_build_qualified_type (type, type_quals)
tree type;
- int constp, volatilep;
+ int type_quals;
{
+ /* A restrict-qualified pointer type must be a pointer to object or
+ incomplete type. Note that the use of POINTER_TYPE_P also allows
+ REFERENCE_TYPEs, which is appropriate for C++. Unfortunately,
+ the C++ front-end also use POINTER_TYPE for pointer-to-member
+ values, so even though it should be illegal to use `restrict'
+ with such an entity we don't flag that here. Thus, special case
+ code for that case is required in the C++ front-end. */
+ if ((type_quals & TYPE_QUAL_RESTRICT)
+ && (!POINTER_TYPE_P (type)
+ || !C_TYPE_OBJECT_OR_INCOMPLETE_P (TREE_TYPE (type))))
+ {
+ error ("invalid use of `restrict'");
+ type_quals &= ~TYPE_QUAL_RESTRICT;
+ }
+
if (TREE_CODE (type) == ARRAY_TYPE)
- return build_array_type (c_build_type_variant (TREE_TYPE (type),
- constp, volatilep),
+ return build_array_type (c_build_qualified_type (TREE_TYPE (type),
+ type_quals),
TYPE_DOMAIN (type));
- return build_type_variant (type, constp, volatilep);
+ return build_qualified_type (type, type_quals);
+}
+
+/* Apply the TYPE_QUALS to the new DECL. */
+
+void
+c_apply_type_quals_to_decl (type_quals, decl)
+ int type_quals;
+ tree decl;
+{
+ if (type_quals & TYPE_QUAL_CONST)
+ TREE_READONLY (decl) = 1;
+ if (type_quals & TYPE_QUAL_VOLATILE)
+ {
+ TREE_SIDE_EFFECTS (decl) = 1;
+ TREE_THIS_VOLATILE (decl) = 1;
+ }
+ if (type_quals & TYPE_QUAL_RESTRICT)
+ {
+ if (!TREE_TYPE (decl)
+ || !POINTER_TYPE_P (TREE_TYPE (decl))
+ || !C_TYPE_OBJECT_OR_INCOMPLETE_P (TREE_TYPE (TREE_TYPE (decl))))
+ error ("invalid use of `restrict'");
+ else if (flag_strict_aliasing)
+ {
+ /* No two restricted pointers can point at the same thing.
+ However, a restricted pointer can point at the same thing
+ as an unrestricted pointer, if that unrestricted pointer
+ is based on the restricted pointer. So, we make the
+ alias set for the restricted pointer a subset of the
+ alias set for the type pointed to by the type of the
+ decl. */
+
+ int pointed_to_alias_set
+ = get_alias_set (TREE_TYPE (TREE_TYPE (decl)));
+
+ if (!pointed_to_alias_set)
+ /* It's not legal to make a subset of alias set zero. */
+ ;
+ else
+ {
+ DECL_POINTER_ALIAS_SET (decl) = new_alias_set ();
+ record_alias_subset (pointed_to_alias_set,
+ DECL_POINTER_ALIAS_SET (decl));
+ }
+ }
+ }
+}
+
+/* T is an expression with pointer type. Find the DECL on which this
+ expression is based. (For example, in `a[i]' this would be `a'.)
+ If there is no such DECL, or a unique decl cannot be determined,
+ NULL_TREE is retured. */
+
+static tree
+c_find_base_decl (t)
+ tree t;
+{
+ int i;
+ tree decl;
+
+ if (t == NULL_TREE || t == error_mark_node)
+ return NULL_TREE;
+
+ if (!POINTER_TYPE_P (TREE_TYPE (t)))
+ return NULL_TREE;
+
+ decl = NULL_TREE;
+
+ if (TREE_CODE (t) == FIELD_DECL
+ || TREE_CODE (t) == PARM_DECL
+ || TREE_CODE (t) == VAR_DECL)
+ /* Aha, we found a pointer-typed declaration. */
+ return t;
+
+ /* It would be nice to deal with COMPONENT_REFs here. If we could
+ tell that `a' and `b' were the same, then `a->f' and `b->f' are
+ also the same. */
+
+ /* Handle general expressions. */
+ switch (TREE_CODE_CLASS (TREE_CODE (t)))
+ {
+ case '1':
+ case '2':
+ case '3':
+ for (i = tree_code_length [(int) TREE_CODE (t)]; --i >= 0;)
+ {
+ tree d = c_find_base_decl (TREE_OPERAND (t, i));
+ if (d)
+ {
+ if (!decl)
+ decl = d;
+ else if (d && d != decl)
+ /* Two different declarations. That's confusing; let's
+ just assume we don't know what's going on. */
+ decl = NULL_TREE;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return decl;
}
/* Return the typed-based alias set for T, which may be an expression
@@ -3091,6 +3241,7 @@ c_get_alias_set (t)
tree t;
{
tree type;
+ tree u;
if (t == error_mark_node)
return 0;
@@ -3111,18 +3262,40 @@ c_get_alias_set (t)
the conservative assumption. */
return 0;
- if (TREE_CODE (t) == COMPONENT_REF
- && TREE_CODE (TREE_TYPE (TREE_OPERAND (t, 0))) == UNION_TYPE)
- /* Permit type-punning when accessing a union, provided the
- access is directly through the union. For example, this code does
- not permit taking the address of a union member and then
- storing through it. Even the type-punning allowed here is a
- GCC extension, albeit a common and useful one; the C standard
- says that such accesses have implementation-defined behavior. */
- return 0;
+ /* Permit type-punning when accessing a union, provided the access
+ is directly through the union. For example, this code does not
+ permit taking the address of a union member and then storing
+ through it. Even the type-punning allowed here is a GCC
+ extension, albeit a common and useful one; the C standard says
+ that such accesses have implementation-defined behavior. */
+ for (u = t;
+ TREE_CODE (u) == COMPONENT_REF || TREE_CODE (u) == ARRAY_REF;
+ u = TREE_OPERAND (u, 0))
+ if (TREE_CODE (u) == COMPONENT_REF
+ && TREE_CODE (TREE_TYPE (TREE_OPERAND (u, 0))) == UNION_TYPE)
+ return 0;
+
+ if (TREE_CODE (t) == INDIRECT_REF)
+ {
+ /* Check for accesses through restrict-qualified pointers. */
+ tree decl = c_find_base_decl (TREE_OPERAND (t, 0));
+
+ if (decl && DECL_POINTER_ALIAS_SET_KNOWN_P (decl))
+ /* We use the alias set indicated in the declaration. */
+ return DECL_POINTER_ALIAS_SET (decl);
+ }
/* From here on, only the type matters. */
+ if (TREE_CODE (t) == COMPONENT_REF
+ && DECL_BIT_FIELD_TYPE (TREE_OPERAND (t, 1)))
+ /* Since build_modify_expr calls get_unwidened for stores to
+ component references, the type of a bit field can be changed
+ from (say) `unsigned int : 16' to `unsigned short' or from
+ `enum E : 16' to `short'. We want the real type of the
+ bit-field in this case, not some the integral equivalent. */
+ type = DECL_BIT_FIELD_TYPE (TREE_OPERAND (t, 1));
+
if (TYPE_ALIAS_SET_KNOWN_P (type))
/* If we've already calculated the value, just return it. */
return TYPE_ALIAS_SET (type);
diff --git a/gcc/c-convert.c b/gcc/c-convert.c
index 6f58e766ae0..9cb941662f2 100644
--- a/gcc/c-convert.c
+++ b/gcc/c-convert.c
@@ -1,5 +1,5 @@
/* Language-level data type conversion for GNU C.
- Copyright (C) 1987, 1988, 1991 Free Software Foundation, Inc.
+ Copyright (C) 1987, 1988, 1991, 1998 Free Software Foundation, Inc.
This file is part of GNU CC.
diff --git a/gcc/c-decl.c b/gcc/c-decl.c
index d42bca8cfd6..7827b34c941 100644
--- a/gcc/c-decl.c
+++ b/gcc/c-decl.c
@@ -1,5 +1,5 @@
/* Process declarations and variables for C compiler.
- Copyright (C) 1988, 92-97, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1988, 92-98, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -39,9 +39,7 @@ Boston, MA 02111-1307, USA. */
#if USE_CPPLIB
#include "cpplib.h"
-extern cpp_reader parse_in;
-extern cpp_options parse_options;
-static int cpp_initialized;
+extern cpp_reader parse_in;
#endif
/* In grokdeclarator, distinguish syntactic contexts of declarators. */
@@ -342,7 +340,7 @@ static struct binding_level * make_binding_level PROTO((void));
static void mark_binding_level PROTO((void *));
static void clear_limbo_values PROTO((tree));
static int duplicate_decls PROTO((tree, tree, int));
-static char *redeclaration_error_message PROTO((tree, tree));
+static int redeclaration_error_message PROTO((tree, tree));
static void storedecls PROTO((tree));
static void storetags PROTO((tree));
static tree lookup_tag PROTO((enum tree_code, tree,
@@ -382,6 +380,10 @@ int flag_no_nonansi_builtin;
int flag_traditional;
+/* Nonzero means use the ISO C9x dialect of C. */
+
+int flag_isoc9x = 0;
+
/* Nonzero means that we have builtin functions, and main is an int */
int flag_hosted = 1;
@@ -395,10 +397,6 @@ int flag_allow_single_precision = 0;
int flag_signed_bitfields = 1;
int explicit_flag_signed_bitfields = 0;
-/* Nonzero means handle `#ident' directives. 0 means ignore them. */
-
-int flag_no_ident = 0;
-
/* Nonzero means warn about use of implicit int. */
int warn_implicit_int;
@@ -429,6 +427,10 @@ int warn_cast_qual;
int warn_bad_function_cast;
+/* Warn about functions which might be candidates for attribute noreturn. */
+
+int warn_missing_noreturn;
+
/* Warn about traditional constructs whose meanings changed in ANSI C. */
int warn_traditional;
@@ -515,19 +517,12 @@ int dollars_in_ident = DOLLARS_IN_IDENTIFIERS;
int
c_decode_option (argc, argv)
- int argc;
+ int argc ATTRIBUTE_UNUSED;
char **argv;
{
int strings_processed;
char *p = argv[0];
#if USE_CPPLIB
- if (! cpp_initialized)
- {
- cpp_reader_init (&parse_in);
- parse_in.data = &parse_options;
- cpp_options_init (&parse_options);
- cpp_initialized = 1;
- }
strings_processed = cpp_handle_option (&parse_in, argc, argv);
#else
strings_processed = 0;
@@ -558,6 +553,63 @@ c_decode_option (argc, argv)
flag_traditional = 0;
flag_writable_strings = 0;
}
+ else if (!strncmp (p, "-std=", 5))
+ {
+ /* Select the appropriate language standard. We currently
+ recognize:
+ -std=iso9899:1990 same as -ansi
+ -std=iso9899:199409 ISO C as modified in amend. 1
+ -std=iso9899:199x ISO C 9x
+ -std=c89 same as -std=iso9899:1990
+ -std=c9x same as -std=iso9899:199x
+ -std=gnu89 default, iso9899:1990 + gnu extensions
+ -std=gnu9x iso9899:199x + gnu extensions
+ */
+ const char *argstart = &p[5];
+
+ if (!strcmp (argstart, "iso9899:1990")
+ || !strcmp (argstart, "c89"))
+ {
+ iso_1990:
+ flag_traditional = 0;
+ flag_writable_strings = 0;
+ flag_no_asm = 1;
+ flag_no_nonansi_builtin = 1;
+ flag_isoc9x = 0;
+ }
+ else if (!strcmp (argstart, "iso9899:199409"))
+ {
+ /* ??? The changes since ISO C 1990 are not supported. */
+ goto iso_1990;
+ }
+ else if (!strcmp (argstart, "iso9899:199x")
+ || !strcmp (argstart, "c9x"))
+ {
+ flag_traditional = 0;
+ flag_writable_strings = 0;
+ flag_no_asm = 1;
+ flag_no_nonansi_builtin = 1;
+ flag_isoc9x = 1;
+ }
+ else if (!strcmp (argstart, "gnu89"))
+ {
+ flag_traditional = 0;
+ flag_writable_strings = 0;
+ flag_no_asm = 0;
+ flag_no_nonansi_builtin = 0;
+ flag_isoc9x = 0;
+ }
+ else if (!strcmp (argstart, "gnu9x"))
+ {
+ flag_traditional = 0;
+ flag_writable_strings = 0;
+ flag_no_asm = 0;
+ flag_no_nonansi_builtin = 0;
+ flag_isoc9x = 1;
+ }
+ else
+ error ("unknown C standard `%s'", argstart);
+ }
else if (!strcmp (p, "-fdollars-in-identifiers"))
dollars_in_ident = 1;
else if (!strcmp (p, "-fno-dollars-in-identifiers"))
@@ -602,12 +654,8 @@ c_decode_option (argc, argv)
flag_no_builtin = 0;
else if (!strcmp (p, "-fno-builtin"))
flag_no_builtin = 1;
- else if (!strcmp (p, "-fno-ident"))
- flag_no_ident = 1;
- else if (!strcmp (p, "-fident"))
- flag_no_ident = 0;
else if (!strcmp (p, "-ansi"))
- flag_no_asm = 1, flag_no_nonansi_builtin = 1;
+ goto iso_1990;
else if (!strcmp (p, "-Werror-implicit-function-declaration"))
mesg_implicit_function_declaration = 2;
else if (!strcmp (p, "-Wimplicit-function-declaration"))
@@ -642,6 +690,10 @@ c_decode_option (argc, argv)
warn_bad_function_cast = 1;
else if (!strcmp (p, "-Wno-bad-function-cast"))
warn_bad_function_cast = 0;
+ else if (!strcmp (p, "-Wmissing-noreturn"))
+ warn_missing_noreturn = 1;
+ else if (!strcmp (p, "-Wno-missing-noreturn"))
+ warn_missing_noreturn = 0;
else if (!strcmp (p, "-Wpointer-arith"))
warn_pointer_arith = 1;
else if (!strcmp (p, "-Wno-pointer-arith"))
@@ -860,7 +912,7 @@ kept_level_p ()
void
declare_parm_level (definition_flag)
- int definition_flag;
+ int definition_flag ATTRIBUTE_UNUSED;
{
current_binding_level->parm_flag = 1;
}
@@ -977,24 +1029,22 @@ poplevel (keep, reverse, functionbody)
if (TYPE_SIZE (TREE_VALUE (link)) == 0)
{
tree type = TREE_VALUE (link);
- char *errmsg;
+ tree type_name = TYPE_NAME (type);
+ char *id = IDENTIFIER_POINTER (TREE_CODE (type_name) == IDENTIFIER_NODE
+ ? type_name
+ : DECL_NAME (type_name));
switch (TREE_CODE (type))
{
case RECORD_TYPE:
- errmsg = "`struct %s' incomplete in scope ending here";
+ error ("`struct %s' incomplete in scope ending here", id);
break;
case UNION_TYPE:
- errmsg = "`union %s' incomplete in scope ending here";
+ error ("`union %s' incomplete in scope ending here", id);
break;
case ENUMERAL_TYPE:
- errmsg = "`enum %s' incomplete in scope ending here";
+ error ("`enum %s' incomplete in scope ending here", id);
break;
}
- if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE)
- error (errmsg, IDENTIFIER_POINTER (TYPE_NAME (type)));
- else
- /* If this type has a typedef-name, the TYPE_NAME is a TYPE_DECL. */
- error (errmsg, IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))));
}
#endif /* 0 */
@@ -1374,7 +1424,7 @@ duplicate_decls (newdecl, olddecl, different_binding_level)
&& DECL_INITIAL (newdecl) != 0);
tree oldtype = TREE_TYPE (olddecl);
tree newtype = TREE_TYPE (newdecl);
- char *errmsg = 0;
+ int errmsg = 0;
if (TREE_CODE_CLASS (TREE_CODE (olddecl)) == 'd')
DECL_MACHINE_ATTRIBUTES (newdecl)
@@ -1601,16 +1651,14 @@ duplicate_decls (newdecl, olddecl, different_binding_level)
if (TREE_CHAIN (t) == 0
&& TYPE_MAIN_VARIANT (type) != void_type_node)
{
- error ("A parameter list with an ellipsis can't match");
- error ("an empty parameter name list declaration.");
+ error ("A parameter list with an ellipsis can't match an empty parameter name list declaration.");
break;
}
if (TYPE_MAIN_VARIANT (type) == float_type_node
|| C_PROMOTING_INTEGER_TYPE_P (type))
{
- error ("An argument type that has a default promotion");
- error ("can't match an empty parameter name list declaration.");
+ error ("An argument type that has a default promotion can't match an empty parameter name list declaration.");
break;
}
}
@@ -1622,7 +1670,21 @@ duplicate_decls (newdecl, olddecl, different_binding_level)
errmsg = redeclaration_error_message (newdecl, olddecl);
if (errmsg)
{
- error_with_decl (newdecl, errmsg);
+ switch (errmsg)
+ {
+ case 1:
+ error_with_decl (newdecl, "redefinition of `%s'");
+ break;
+ case 2:
+ error_with_decl (newdecl, "redeclaration of `%s'");
+ break;
+ case 3:
+ error_with_decl (newdecl, "conflicting declarations of `%s'");
+ break;
+ default:
+ abort ();
+ }
+
error_with_decl (olddecl,
((DECL_INITIAL (olddecl)
&& current_binding_level == global_binding_level)
@@ -1654,14 +1716,22 @@ duplicate_decls (newdecl, olddecl, different_binding_level)
for (parm = TYPE_ACTUAL_ARG_TYPES (oldtype),
type = TYPE_ARG_TYPES (newtype),
nargs = 1;
- (TYPE_MAIN_VARIANT (TREE_VALUE (parm)) != void_type_node
- || TYPE_MAIN_VARIANT (TREE_VALUE (type)) != void_type_node);
+ ;
parm = TREE_CHAIN (parm), type = TREE_CHAIN (type), nargs++)
{
if (TYPE_MAIN_VARIANT (TREE_VALUE (parm)) == void_type_node
+ && TYPE_MAIN_VARIANT (TREE_VALUE (type)) == void_type_node)
+ {
+ warning_with_decl (newdecl, "prototype for `%s' follows");
+ warning_with_decl (olddecl, "non-prototype definition here");
+ break;
+ }
+ if (TYPE_MAIN_VARIANT (TREE_VALUE (parm)) == void_type_node
|| TYPE_MAIN_VARIANT (TREE_VALUE (type)) == void_type_node)
{
- errmsg = "prototype for `%s' follows and number of arguments";
+ error_with_decl (newdecl, "prototype for `%s' follows and number of arguments doesn't match");
+ error_with_decl (olddecl, "non-prototype definition here");
+ errmsg = 1;
break;
}
/* Type for passing arg must be consistent
@@ -1673,21 +1743,14 @@ duplicate_decls (newdecl, olddecl, different_binding_level)
&& TYPE_MAIN_VARIANT (TREE_VALUE (parm)) == integer_type_node
&& TYPE_MAIN_VARIANT (TREE_VALUE (type)) == unsigned_type_node)))
{
- errmsg = "prototype for `%s' follows and argument %d";
+ error_with_decl (newdecl,
+ "prototype for `%s' follows and argument %d doesn't match",
+ nargs);
+ error_with_decl (olddecl, "non-prototype definition here");
+ errmsg = 1;
break;
}
}
- if (errmsg)
- {
- error_with_decl (newdecl, errmsg, nargs);
- error_with_decl (olddecl,
- "doesn't match non-prototype definition here");
- }
- else
- {
- warning_with_decl (newdecl, "prototype for `%s' follows");
- warning_with_decl (olddecl, "non-prototype definition here");
- }
}
/* Warn about mismatches in various flags. */
else
@@ -1712,6 +1775,14 @@ duplicate_decls (newdecl, olddecl, different_binding_level)
&& !TREE_PUBLIC (newdecl))
warning_with_decl (newdecl, "static declaration for `%s' follows non-static");
+ /* If warn_traditional, warn when a non-static function
+ declaration follows a static one. */
+ if (warn_traditional
+ && TREE_CODE (olddecl) == FUNCTION_DECL
+ && !TREE_PUBLIC (olddecl)
+ && TREE_PUBLIC (newdecl))
+ warning_with_decl (newdecl, "non-static declaration for `%s' follows static");
+
/* Warn when const declaration follows a non-const
declaration, but not for functions. */
if (TREE_CODE (olddecl) != FUNCTION_DECL
@@ -1852,6 +1923,8 @@ duplicate_decls (newdecl, olddecl, different_binding_level)
DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (newdecl)
|= DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (olddecl);
+ DECL_NO_CHECK_MEMORY_USAGE (newdecl)
+ |= DECL_NO_CHECK_MEMORY_USAGE (olddecl);
}
pop_obstacks ();
@@ -2372,7 +2445,7 @@ pushdecl (x)
/* No shadow warnings for vars made for inlining. */
&& ! DECL_FROM_INLINE (x))
{
- char *warnstring = 0;
+ char *id = IDENTIFIER_POINTER (name);
if (TREE_CODE (x) == PARM_DECL
&& current_binding_level->level_chain->parm_flag)
@@ -2383,15 +2456,12 @@ pushdecl (x)
but there is no way to tell it's not a definition. */
;
else if (oldlocal != 0 && TREE_CODE (oldlocal) == PARM_DECL)
- warnstring = "declaration of `%s' shadows a parameter";
+ warning ("declaration of `%s' shadows a parameter", id);
else if (oldlocal != 0)
- warnstring = "declaration of `%s' shadows previous local";
+ warning ("declaration of `%s' shadows previous local", id);
else if (IDENTIFIER_GLOBAL_VALUE (name) != 0
&& IDENTIFIER_GLOBAL_VALUE (name) != error_mark_node)
- warnstring = "declaration of `%s' shadows global declaration";
-
- if (warnstring)
- warning (warnstring, IDENTIFIER_POINTER (name));
+ warning ("declaration of `%s' shadows global declaration", id);
}
/* If storing a local value, there may already be one (inherited).
@@ -2502,10 +2572,10 @@ implicitly_declare (functionid)
/* Return zero if the declaration NEWDECL is valid
when the declaration OLDDECL (assumed to be for the same name)
has already been seen.
- Otherwise return an error message format string with a %s
- where the identifier should go. */
+ Otherwise return 1 if NEWDECL is a redefinition, 2 if it is a redeclaration,
+ and 3 if it is a conflicting declaration. */
-static char *
+static int
redeclaration_error_message (newdecl, olddecl)
tree newdecl, olddecl;
{
@@ -2524,7 +2594,7 @@ redeclaration_error_message (newdecl, olddecl)
return 0;
if (DECL_IN_SYSTEM_HEADER (olddecl) || DECL_IN_SYSTEM_HEADER (newdecl))
return 0;
- return "redefinition of `%s'";
+ return 1;
}
else if (TREE_CODE (newdecl) == FUNCTION_DECL)
{
@@ -2537,7 +2607,7 @@ redeclaration_error_message (newdecl, olddecl)
time in another way is ok. */
&& !(DECL_INLINE (olddecl) && DECL_EXTERNAL (olddecl)
&& !(DECL_INLINE (newdecl) && DECL_EXTERNAL (newdecl))))
- return "redefinition of `%s'";
+ return 1;
return 0;
}
else if (current_binding_level == global_binding_level)
@@ -2548,11 +2618,11 @@ redeclaration_error_message (newdecl, olddecl)
return 0;
/* Reject two definitions. */
if (DECL_INITIAL (olddecl) != 0 && DECL_INITIAL (newdecl) != 0)
- return "redefinition of `%s'";
+ return 1;
/* Now we have two tentative defs, or one tentative and one real def. */
/* Insist that the linkage match. */
if (TREE_PUBLIC (olddecl) != TREE_PUBLIC (newdecl))
- return "conflicting declarations of `%s'";
+ return 3;
return 0;
}
else if (current_binding_level->parm_flag
@@ -2566,7 +2636,7 @@ redeclaration_error_message (newdecl, olddecl)
be an extern reference to olddecl. */
if (!(DECL_EXTERNAL (newdecl) && DECL_EXTERNAL (olddecl))
&& DECL_CONTEXT (newdecl) == DECL_CONTEXT (olddecl))
- return "redeclaration of `%s'";
+ return 2;
return 0;
}
}
@@ -2974,8 +3044,10 @@ init_decl_processing ()
intDI_type_node = make_signed_type (GET_MODE_BITSIZE (DImode));
pushdecl (build_decl (TYPE_DECL, NULL_TREE, intDI_type_node));
+#if HOST_BITS_PER_WIDE_INT >= 64
intTI_type_node = make_signed_type (GET_MODE_BITSIZE (TImode));
pushdecl (build_decl (TYPE_DECL, NULL_TREE, intTI_type_node));
+#endif
unsigned_intQI_type_node = make_unsigned_type (GET_MODE_BITSIZE (QImode));
pushdecl (build_decl (TYPE_DECL, NULL_TREE, unsigned_intQI_type_node));
@@ -2989,8 +3061,10 @@ init_decl_processing ()
unsigned_intDI_type_node = make_unsigned_type (GET_MODE_BITSIZE (DImode));
pushdecl (build_decl (TYPE_DECL, NULL_TREE, unsigned_intDI_type_node));
+#if HOST_BITS_PER_WIDE_INT >= 64
unsigned_intTI_type_node = make_unsigned_type (GET_MODE_BITSIZE (TImode));
pushdecl (build_decl (TYPE_DECL, NULL_TREE, unsigned_intTI_type_node));
+#endif
float_type_node = make_node (REAL_TYPE);
TYPE_PRECISION (float_type_node) = FLOAT_TYPE_SIZE;
@@ -3486,10 +3560,10 @@ init_decl_processing ()
tree
builtin_function (name, type, function_code, library_name)
- char *name;
+ const char *name;
tree type;
enum built_in_function function_code;
- char *library_name;
+ const char *library_name;
{
tree decl = build_decl (FUNCTION_DECL, get_identifier (name), type);
DECL_EXTERNAL (decl) = 1;
@@ -4252,13 +4326,15 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
tree type = NULL_TREE;
int longlong = 0;
int constp;
+ int restrictp;
int volatilep;
+ int type_quals = TYPE_UNQUALIFIED;
int inlinep;
int explicit_int = 0;
int explicit_char = 0;
int defaulted_int = 0;
tree typedef_decl = 0;
- char *name;
+ const char *name;
tree typedef_type = 0;
int funcdef_flag = 0;
enum tree_code innermost_code = ERROR_MARK;
@@ -4414,13 +4490,12 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
&& ! (specbits & (1 << (int) RID_TYPEDEF) && initialized)
&& ! (in_system_header && ! allocation_temporary_p ()))
{
- /* C9x will probably require a diagnostic here.
- For now, issue a warning if -Wreturn-type and this is a function,
- or if -Wimplicit; prefer the former warning since it is more
- explicit. */
+ /* Issue a warning if this is an ISO C 9x program or if -Wreturn-type
+ and this is a function, or if -Wimplicit; prefer the former
+ warning since it is more explicit. */
if ((warn_implicit_int || warn_return_type) && funcdef_flag)
warn_about_return_type = 1;
- else if (warn_implicit_int)
+ else if (warn_implicit_int || flag_isoc9x)
warning ("type defaults to `int' in declaration of `%s'", name);
}
@@ -4562,19 +4637,26 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
type = build_complex_type (type);
}
- /* Set CONSTP if this declaration is `const', whether by
- explicit specification or via a typedef.
- Likewise for VOLATILEP. */
-
+ /* Figure out the type qualifiers for the declaration. There are
+ two ways a declaration can become qualified. One is something
+ like `const int i' where the `const' is explicit. Another is
+ something like `typedef const int CI; CI i' where the type of the
+ declaration contains the `const'. */
constp = !! (specbits & 1 << (int) RID_CONST) + TYPE_READONLY (type);
+ restrictp = !! (specbits & 1 << (int) RID_RESTRICT) + TYPE_RESTRICT (type);
volatilep = !! (specbits & 1 << (int) RID_VOLATILE) + TYPE_VOLATILE (type);
inlinep = !! (specbits & (1 << (int) RID_INLINE));
if (constp > 1)
pedwarn ("duplicate `const'");
+ if (restrictp > 1)
+ pedwarn ("duplicate `restrict'");
if (volatilep > 1)
pedwarn ("duplicate `volatile'");
- if (! flag_gen_aux_info && (TYPE_READONLY (type) || TYPE_VOLATILE (type)))
+ if (! flag_gen_aux_info && (TYPE_QUALS (type)))
type = TYPE_MAIN_VARIANT (type);
+ type_quals = ((constp ? TYPE_QUAL_CONST : 0)
+ | (restrictp ? TYPE_QUAL_RESTRICT : 0)
+ | (volatilep ? TYPE_QUAL_VOLATILE : 0));
/* Warn if two storage classes are given. Default to `auto'. */
@@ -4808,13 +4890,12 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
is set correctly. */
type = build_array_type (type, itype);
- if (constp || volatilep)
- type = c_build_type_variant (type, constp, volatilep);
+ if (type_quals)
+ type = c_build_qualified_type (type, type_quals);
#if 0 /* don't clear these; leave them set so that the array type
or the variable is itself const or volatile. */
- constp = 0;
- volatilep = 0;
+ type_quals = TYPE_UNQUALIFIED;
#endif
if (size_varies)
@@ -4879,12 +4960,11 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
flag_traditional
? NULL_TREE : arg_types);
#endif
- /* ANSI seems to say that `const int foo ();'
- does not make the function foo const. */
- if (constp || volatilep)
- type = c_build_type_variant (type, constp, volatilep);
- constp = 0;
- volatilep = 0;
+ /* Type qualifiers before the return type of the function
+ qualify the return type, not the function type. */
+ if (type_quals)
+ type = c_build_qualified_type (type, type_quals);
+ type_quals = TYPE_UNQUALIFIED;
type = build_function_type (type, arg_types);
declarator = TREE_OPERAND (declarator, 0);
@@ -4908,12 +4988,11 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
for the pointer. */
if (pedantic && TREE_CODE (type) == FUNCTION_TYPE
- && (constp || volatilep))
- pedwarn ("ANSI C forbids const or volatile function types");
- if (constp || volatilep)
- type = c_build_type_variant (type, constp, volatilep);
- constp = 0;
- volatilep = 0;
+ && type_quals)
+ pedwarn ("ANSI C forbids qualified function types");
+ if (type_quals)
+ type = c_build_qualified_type (type, type_quals);
+ type_quals = TYPE_UNQUALIFIED;
size_varies = 0;
type = build_pointer_type (type);
@@ -4925,13 +5004,21 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
{
register tree typemodlist;
int erred = 0;
+
+ constp = 0;
+ volatilep = 0;
+ restrictp = 0;
for (typemodlist = TREE_TYPE (declarator); typemodlist;
typemodlist = TREE_CHAIN (typemodlist))
{
- if (TREE_VALUE (typemodlist) == ridpointers[(int) RID_CONST])
+ tree qualifier = TREE_VALUE (typemodlist);
+
+ if (qualifier == ridpointers[(int) RID_CONST])
constp++;
- else if (TREE_VALUE (typemodlist) == ridpointers[(int) RID_VOLATILE])
+ else if (qualifier == ridpointers[(int) RID_VOLATILE])
volatilep++;
+ else if (qualifier == ridpointers[(int) RID_RESTRICT])
+ restrictp++;
else if (!erred)
{
erred = 1;
@@ -4942,6 +5029,12 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
pedwarn ("duplicate `const'");
if (volatilep > 1)
pedwarn ("duplicate `volatile'");
+ if (restrictp > 1)
+ pedwarn ("duplicate `restrict'");
+
+ type_quals = ((constp ? TYPE_QUAL_CONST : 0)
+ | (restrictp ? TYPE_QUAL_RESTRICT : 0)
+ | (volatilep ? TYPE_QUAL_VOLATILE : 0));
}
declarator = TREE_OPERAND (declarator, 0);
@@ -4968,10 +5061,10 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
/* Note that the grammar rejects storage classes
in typenames, fields or parameters */
if (pedantic && TREE_CODE (type) == FUNCTION_TYPE
- && (constp || volatilep))
- pedwarn ("ANSI C forbids const or volatile function types");
- if (constp || volatilep)
- type = c_build_type_variant (type, constp, volatilep);
+ && type_quals)
+ pedwarn ("ANSI C forbids qualified function types");
+ if (type_quals)
+ type = c_build_qualified_type (type, type_quals);
decl = build_decl (TYPE_DECL, declarator, type);
if ((specbits & (1 << (int) RID_SIGNED))
|| (typedef_decl && C_TYPEDEF_EXPLICITLY_SIGNED (typedef_decl)))
@@ -5003,10 +5096,10 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
/* Note that the grammar rejects storage classes
in typenames, fields or parameters */
if (pedantic && TREE_CODE (type) == FUNCTION_TYPE
- && (constp || volatilep))
+ && type_quals)
pedwarn ("ANSI C forbids const or volatile function types");
- if (constp || volatilep)
- type = c_build_type_variant (type, constp, volatilep);
+ if (type_quals)
+ type = c_build_qualified_type (type, type_quals);
pop_obstacks ();
return type;
}
@@ -5046,20 +5139,20 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
{
/* Transfer const-ness of array into that of type pointed to. */
type = TREE_TYPE (type);
- if (constp || volatilep)
- type = c_build_type_variant (type, constp, volatilep);
+ if (type_quals)
+ type = c_build_qualified_type (type, type_quals);
type = build_pointer_type (type);
- volatilep = constp = 0;
+ type_quals = TYPE_UNQUALIFIED;
size_varies = 0;
}
else if (TREE_CODE (type) == FUNCTION_TYPE)
{
- if (pedantic && (constp || volatilep))
- pedwarn ("ANSI C forbids const or volatile function types");
- if (constp || volatilep)
- type = c_build_type_variant (type, constp, volatilep);
+ if (pedantic && type_quals)
+ pedwarn ("ANSI C forbids qualified function types");
+ if (type_quals)
+ type = c_build_qualified_type (type, type_quals);
type = build_pointer_type (type);
- volatilep = constp = 0;
+ type_quals = TYPE_UNQUALIFIED;
}
decl = build_decl (PARM_DECL, declarator, type);
@@ -5107,13 +5200,13 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
type = error_mark_node;
}
/* Move type qualifiers down to element of an array. */
- if (TREE_CODE (type) == ARRAY_TYPE && (constp || volatilep))
+ if (TREE_CODE (type) == ARRAY_TYPE && type_quals)
{
- type = build_array_type (c_build_type_variant (TREE_TYPE (type),
- constp, volatilep),
+ type = build_array_type (c_build_qualified_type (TREE_TYPE (type),
+ type_quals),
TYPE_DOMAIN (type));
#if 0 /* Leave the field const or volatile as well. */
- constp = volatilep = 0;
+ type_quals = TYPE_UNQUALIFIED;
#endif
}
decl = build_decl (FIELD_DECL, declarator, type);
@@ -5152,18 +5245,18 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
decl = build_decl (FUNCTION_DECL, declarator, type);
decl = build_decl_attribute_variant (decl, decl_machine_attr);
- if (pedantic && (constp || volatilep)
- && ! DECL_IN_SYSTEM_HEADER (decl))
- pedwarn ("ANSI C forbids const or volatile functions");
+ if (pedantic && type_quals && ! DECL_IN_SYSTEM_HEADER (decl))
+ pedwarn ("ANSI C forbids qualified function types");
if (pedantic
&& TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (decl))) == void_type_node
- && (TYPE_READONLY (TREE_TYPE (TREE_TYPE (decl)))
- || TYPE_VOLATILE (TREE_TYPE (TREE_TYPE (decl))))
+ && TYPE_QUALS (TREE_TYPE (TREE_TYPE (decl)))
&& ! DECL_IN_SYSTEM_HEADER (decl))
- pedwarn ("ANSI C forbids const or volatile void function return type");
+ pedwarn ("ANSI C forbids qualified void function return type");
- if (volatilep
+ /* GNU C interprets a `volatile void' return type to indicate
+ that the function does not return. */
+ if ((type_quals & TYPE_QUAL_VOLATILE)
&& TREE_TYPE (TREE_TYPE (decl)) != void_type_node)
warning ("`noreturn' function returns non-void value");
@@ -5193,13 +5286,13 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
int extern_ref = !initialized && (specbits & (1 << (int) RID_EXTERN));
/* Move type qualifiers down to element of an array. */
- if (TREE_CODE (type) == ARRAY_TYPE && (constp || volatilep))
+ if (TREE_CODE (type) == ARRAY_TYPE && type_quals)
{
- type = build_array_type (c_build_type_variant (TREE_TYPE (type),
- constp, volatilep),
+ type = build_array_type (c_build_qualified_type (TREE_TYPE (type),
+ type_quals),
TYPE_DOMAIN (type));
#if 0 /* Leave the variable const or volatile as well. */
- constp = volatilep = 0;
+ type_quals = TYPE_UNQUALIFIED;
#endif
}
@@ -5246,14 +5339,8 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
DECL_REGISTER (decl) = 1;
/* Record constancy and volatility. */
+ c_apply_type_quals_to_decl (type_quals, decl);
- if (constp)
- TREE_READONLY (decl) = 1;
- if (volatilep)
- {
- TREE_SIDE_EFFECTS (decl) = 1;
- TREE_THIS_VOLATILE (decl) = 1;
- }
/* If a type has volatile components, it should be stored in memory.
Otherwise, the fact that those components are volatile
will be ignored, and would even crash the compiler. */
@@ -5513,8 +5600,7 @@ parmlist_tags_warning ()
if (! already)
{
- warning ("its scope is only this definition or declaration,");
- warning ("which is probably not what you want.");
+ warning ("its scope is only this definition or declaration, which is probably not what you want.");
already = 1;
}
}
@@ -5628,8 +5714,8 @@ start_struct (code, name)
tree
grokfield (filename, line, declarator, declspecs, width)
- char *filename;
- int line;
+ const char *filename ATTRIBUTE_UNUSED;
+ int line ATTRIBUTE_UNUSED;
tree declarator, declspecs, width;
{
tree value;
@@ -5711,9 +5797,10 @@ finish_struct (t, fieldlist, attributes)
break;
if (x == 0)
- pedwarn ("%s has no %smembers",
- (TREE_CODE (t) == UNION_TYPE ? "union" : "structure"),
- (fieldlist ? "named " : ""));
+ pedwarn ((fieldlist
+ ? "%s has no named members"
+ : "%s has no members"),
+ TREE_CODE (t) == UNION_TYPE ? "union" : "struct");
}
/* Install struct as DECL_CONTEXT of each field decl.
@@ -7130,6 +7217,12 @@ finish_function (nested)
current_function_returns_null |= can_reach_end;
+ if (warn_missing_noreturn
+ && !TREE_THIS_VOLATILE (fndecl)
+ && !current_function_returns_null
+ && !current_function_returns_value)
+ warning ("function might be possible candidate for attribute `noreturn'");
+
if (TREE_THIS_VOLATILE (fndecl) && current_function_returns_null)
warning ("`noreturn' function does return");
else if (warn_return_type && can_reach_end
diff --git a/gcc/c-iterate.c b/gcc/c-iterate.c
index b8f51d090d6..dc0cc8a84af 100644
--- a/gcc/c-iterate.c
+++ b/gcc/c-iterate.c
@@ -1,5 +1,5 @@
/* Build expressions with type checking for C compiler.
- Copyright (C) 1987, 88, 89, 92, 93, 96, 1997 Free Software Foundation, Inc.
+ Copyright (C) 1987, 88, 89, 92, 93, 96, 1997, 1998 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -539,10 +539,10 @@ prdecl (d)
fprintf (stderr, dname);
}
else
- fprintf (stderr, "<<Not a Decl!!!>>");
+ fprintf (stderr, "<<?>>");
}
else
- fprintf (stderr, "<<NULL!!>>");
+ fprintf (stderr, "<<0>>");
}
/* Print Iterator List -- names only */
diff --git a/gcc/c-lang.c b/gcc/c-lang.c
index 622abd4fb51..21f8b191190 100644
--- a/gcc/c-lang.c
+++ b/gcc/c-lang.c
@@ -30,6 +30,13 @@ Boston, MA 02111-1307, USA. */
#include "output.h"
#include "ggc.h"
+#if USE_CPPLIB
+#include "cpplib.h"
+extern char *yy_cur;
+extern cpp_reader parse_in;
+extern cpp_options parse_options;
+#endif
+
/* Each of the functions defined here
is an alternative to a function in objc-actions.c. */
@@ -44,22 +51,29 @@ lang_decode_option (argc, argv)
void
lang_init_options ()
{
+#if USE_CPPLIB
+ cpp_reader_init (&parse_in);
+ parse_in.opts = &parse_options;
+ cpp_options_init (&parse_options);
+#endif
}
void
lang_init ()
{
-#if !USE_CPPLIB
/* the beginning of the file is a new line; check for # */
/* With luck, we discover the real source file's name from that
and put it in input_filename. */
+#if !USE_CPPLIB
ungetc (check_newline (), finput);
-#endif
+#else
+ check_newline ();
+ yy_cur--;
+#endif
+
save_lang_status = &push_c_function_context;
restore_lang_status = &pop_c_function_context;
mark_lang_status = &mark_c_function_context;
-
- c_parse_init ();
}
void
@@ -141,7 +155,7 @@ recognize_objc_keyword ()
tree
build_objc_string (len, str)
int len ATTRIBUTE_UNUSED;
- char *str ATTRIBUTE_UNUSED;
+ const char *str ATTRIBUTE_UNUSED;
{
abort ();
return NULL_TREE;
diff --git a/gcc/c-lex.c b/gcc/c-lex.c
index af627cd5315..27c65f3fa27 100644
--- a/gcc/c-lex.c
+++ b/gcc/c-lex.c
@@ -20,7 +20,6 @@ Boston, MA 02111-1307, USA. */
#include "config.h"
#include "system.h"
-#include <setjmp.h>
#include "rtl.h"
#include "tree.h"
@@ -32,6 +31,14 @@ Boston, MA 02111-1307, USA. */
#include "c-parse.h"
#include "c-pragma.h"
#include "toplev.h"
+#include "intl.h"
+
+/* MULTIBYTE_CHARS support only works for native compilers.
+ ??? Ideally what we want is to model widechar support after
+ the current floating point support. */
+#ifdef CROSS_COMPILE
+#undef MULTIBYTE_CHARS
+#endif
#ifdef MULTIBYTE_CHARS
#include "mbchar.h"
@@ -59,11 +66,11 @@ tree ridpointers[(int) RID_MAX];
#if USE_CPPLIB
extern unsigned char *yy_cur, *yy_lim;
-
+
extern int yy_get_token ();
-
+
#define GETC() (yy_cur < yy_lim ? *yy_cur++ : yy_get_token ())
-#define UNGETC(c) ((c), yy_cur--)
+#define UNGETC(c) ((c) == EOF ? 0 : yy_cur--)
#else
#define GETC() getc (finput)
#define UNGETC(c) ungetc (c, finput)
@@ -116,8 +123,9 @@ static int handle_generic_pragma PROTO((int));
static int whitespace_cr PROTO((int));
static int skip_white_space PROTO((int));
static int skip_white_space_on_line PROTO((void));
-static char *extend_token_buffer PROTO((char *));
+static char *extend_token_buffer PROTO((const char *));
static int readescape PROTO((int *));
+static void parse_float PROTO((PTR));
/* Do not insert generated code into the source, instead, include it.
This allows us to build gcc automatically even for targets that
@@ -164,8 +172,10 @@ remember_protocol_qualifiers ()
wordlist[i].name = "inout";
else if (wordlist[i].rid == RID_BYCOPY)
wordlist[i].name = "bycopy";
+ else if (wordlist[i].rid == RID_BYREF)
+ wordlist[i].name = "byref";
else if (wordlist[i].rid == RID_ONEWAY)
- wordlist[i].name = "oneway";
+ wordlist[i].name = "oneway";
}
char *
@@ -187,19 +197,22 @@ init_parse (filename)
#ifdef IO_BUFFER_SIZE
setvbuf (finput, (char *) xmalloc (IO_BUFFER_SIZE), _IOFBF, IO_BUFFER_SIZE);
#endif
-#endif /* !USE_CPPLIB */
-
- init_lex ();
-
-#if USE_CPPLIB
- yy_cur = "\n";
- yy_lim = yy_cur+1;
-
+#else /* !USE_CPPLIB */
parse_in.show_column = 1;
if (! cpp_start_read (&parse_in, filename))
abort ();
+
+ if (filename == 0 || !strcmp (filename, "-"))
+ filename = "stdin";
+
+ /* cpp_start_read always puts at least one line directive into the
+ token buffer. We must arrange to read it out here. */
+ yy_cur = parse_in.token_buffer;
+ yy_lim = CPP_PWRITTEN (&parse_in);
#endif
+ init_lex ();
+
return filename;
}
@@ -243,6 +256,7 @@ init_lex ()
ridpointers[(int) RID_SIGNED] = get_identifier ("signed");
ridpointers[(int) RID_INLINE] = get_identifier ("inline");
ridpointers[(int) RID_CONST] = get_identifier ("const");
+ ridpointers[(int) RID_RESTRICT] = get_identifier ("restrict");
ridpointers[(int) RID_VOLATILE] = get_identifier ("volatile");
ridpointers[(int) RID_AUTO] = get_identifier ("auto");
ridpointers[(int) RID_STATIC] = get_identifier ("static");
@@ -256,6 +270,7 @@ init_lex ()
ridpointers[(int) RID_OUT] = get_identifier ("out");
ridpointers[(int) RID_INOUT] = get_identifier ("inout");
ridpointers[(int) RID_BYCOPY] = get_identifier ("bycopy");
+ ridpointers[(int) RID_BYREF] = get_identifier ("byref");
ridpointers[(int) RID_ONEWAY] = get_identifier ("oneway");
forget_protocol_qualifiers();
@@ -271,6 +286,7 @@ init_lex ()
if (flag_traditional)
{
UNSET_RESERVED_WORD ("const");
+ UNSET_RESERVED_WORD ("restrict");
UNSET_RESERVED_WORD ("volatile");
UNSET_RESERVED_WORD ("typeof");
UNSET_RESERVED_WORD ("signed");
@@ -278,6 +294,9 @@ init_lex ()
UNSET_RESERVED_WORD ("iterator");
UNSET_RESERVED_WORD ("complex");
}
+ else if (!flag_isoc9x)
+ UNSET_RESERVED_WORD ("restrict");
+
if (flag_no_asm)
{
UNSET_RESERVED_WORD ("asm");
@@ -465,7 +484,7 @@ skip_white_space_on_line ()
static char *
extend_token_buffer (p)
- char *p;
+ const char *p;
{
int offset = p - token_buffer;
@@ -475,7 +494,7 @@ extend_token_buffer (p)
return token_buffer + offset;
}
-#if defined HANDLE_PRAGMA
+#if defined HANDLE_PRAGMA
/* Local versions of these macros, that can be passed as function pointers. */
static int
pragma_getc ()
@@ -549,7 +568,7 @@ check_newline ()
if (token != IDENTIFIER)
goto skipline;
#endif /* HANDLE_PRAGMA || HANDLE_GENERIC_PRAGMAS */
-
+
#ifdef HANDLE_PRAGMA
/* We invoke HANDLE_PRAGMA before HANDLE_GENERIC_PRAGMAS (if
both are defined), in order to give the back end a chance to
@@ -561,7 +580,7 @@ check_newline ()
UNGETC (c);
}
#endif /* !USE_CPPLIB */
-
+
if (TREE_CODE (yylval.ttype) != IDENTIFIER_NODE)
goto skipline;
@@ -569,19 +588,19 @@ check_newline ()
IDENTIFIER_POINTER (yylval.ttype)))
return GETC ();
#endif /* HANDLE_PRAGMA */
-
+
#ifdef HANDLE_GENERIC_PRAGMAS
if (handle_generic_pragma (token))
return GETC ();
#endif /* HANDLE_GENERIC_PRAGMAS */
-
+
/* Issue a warning message if we have been asked to do so.
Ignoring unknown pragmas in system header file unless
an explcit -Wunknown-pragmas has been given. */
if (warn_unknown_pragmas > 1
|| (warn_unknown_pragmas && ! in_system_header))
warning ("ignoring pragma: %s", token_buffer);
-
+
goto skipline;
}
}
@@ -771,7 +790,7 @@ linenum:
struct file_stack *p = input_file_stack;
if (indent_level != p->indent_level)
{
- warning_with_file_and_line
+ warning_with_file_and_line
(p->name, old_lineno,
"This file contains more `%c's than `%c's.",
indent_level > p->indent_level ? '{' : '}',
@@ -878,7 +897,7 @@ handle_generic_pragma (token)
while (c == ' ' || c == '\t')
c = GETC ();
UNGETC (c);
-
+
if (c == '\n' || c == EOF)
return handle_pragma_token (NULL, NULL);
@@ -947,7 +966,7 @@ readescape (ignore_ptr)
;
else if ((count - 1) * 4 >= TYPE_PRECISION (integer_type_node)
|| (count > 1
- && ((1 << (TYPE_PRECISION (integer_type_node) - (count - 1) * 4))
+ && (((unsigned)1 << (TYPE_PRECISION (integer_type_node) - (count - 1) * 4))
<= firstdig)))
pedwarn ("hex escape out of range");
return code;
@@ -1029,30 +1048,25 @@ readescape (ignore_ptr)
}
void
-yyerror (string)
- char *string;
+yyerror (msgid)
+ const char *msgid;
{
- char buf[200];
-
- strcpy (buf, string);
+ const char *string = _(msgid);
/* We can't print string and character constants well
because the token_buffer contains the result of processing escapes. */
if (end_of_file)
- strcat (buf, " at end of input");
+ error ("%s at end of input", string);
else if (token_buffer[0] == 0)
- strcat (buf, " at null character");
+ error ("%s at null character", string);
else if (token_buffer[0] == '"')
- strcat (buf, " before string constant");
+ error ("%s before string constant", string);
else if (token_buffer[0] == '\'')
- strcat (buf, " before character constant");
+ error ("%s before character constant", string);
else if (token_buffer[0] < 040 || (unsigned char) token_buffer[0] >= 0177)
- sprintf (buf + strlen (buf), " before character 0%o",
- (unsigned char) token_buffer[0]);
+ error ("%s before character 0%o", string, (unsigned char) token_buffer[0]);
else
- strcat (buf, " before `%s'");
-
- error (buf, token_buffer);
+ error ("%s before `%s'", string, token_buffer);
}
#if 0
@@ -1065,7 +1079,7 @@ struct try_type
char long_long_flag;
};
-struct try_type type_sequence[] =
+struct try_type type_sequence[] =
{
{ &integer_type_node, 0, 0, 0},
{ &unsigned_type_node, 1, 0, 0},
@@ -1076,6 +1090,120 @@ struct try_type type_sequence[] =
};
#endif /* 0 */
+struct pf_args
+{
+ /* Input */
+ int base;
+ char * p;
+ /* I/O */
+ int c;
+ int imag;
+ tree type;
+ int conversion_errno;
+ /* Output */
+ REAL_VALUE_TYPE value;
+};
+
+static void
+parse_float (data)
+ PTR data;
+{
+ struct pf_args * args = (struct pf_args *) data;
+ int fflag = 0, lflag = 0;
+ /* Copy token_buffer now, while it has just the number
+ and not the suffixes; once we add `f' or `i',
+ REAL_VALUE_ATOF may not work any more. */
+ char *copy = (char *) alloca (args->p - token_buffer + 1);
+ bcopy (token_buffer, copy, args->p - token_buffer + 1);
+
+ while (1)
+ {
+ int lose = 0;
+
+ /* Read the suffixes to choose a data type. */
+ switch (args->c)
+ {
+ case 'f': case 'F':
+ if (fflag)
+ error ("more than one `f' in numeric constant");
+ fflag = 1;
+ break;
+
+ case 'l': case 'L':
+ if (lflag)
+ error ("more than one `l' in numeric constant");
+ lflag = 1;
+ break;
+
+ case 'i': case 'I':
+ if (args->imag)
+ error ("more than one `i' or `j' in numeric constant");
+ else if (pedantic)
+ pedwarn ("ANSI C forbids imaginary numeric constants");
+ args->imag = 1;
+ break;
+
+ default:
+ lose = 1;
+ }
+
+ if (lose)
+ break;
+
+ if (args->p >= token_buffer + maxtoken - 3)
+ args->p = extend_token_buffer (args->p);
+ *(args->p++) = args->c;
+ *(args->p) = 0;
+ args->c = GETC();
+ }
+
+ /* The second argument, machine_mode, of REAL_VALUE_ATOF
+ tells the desired precision of the binary result
+ of decimal-to-binary conversion. */
+
+ if (fflag)
+ {
+ if (lflag)
+ error ("both `f' and `l' in floating constant");
+
+ args->type = float_type_node;
+ errno = 0;
+ if (args->base == 16)
+ args->value = REAL_VALUE_HTOF (copy, TYPE_MODE (args->type));
+ else
+ args->value = REAL_VALUE_ATOF (copy, TYPE_MODE (args->type));
+ args->conversion_errno = errno;
+ /* A diagnostic is required here by some ANSI C testsuites.
+ This is not pedwarn, because some people don't want
+ an error for this. */
+ if (REAL_VALUE_ISINF (args->value) && pedantic)
+ warning ("floating point number exceeds range of `float'");
+ }
+ else if (lflag)
+ {
+ args->type = long_double_type_node;
+ errno = 0;
+ if (args->base == 16)
+ args->value = REAL_VALUE_HTOF (copy, TYPE_MODE (args->type));
+ else
+ args->value = REAL_VALUE_ATOF (copy, TYPE_MODE (args->type));
+ args->conversion_errno = errno;
+ if (REAL_VALUE_ISINF (args->value) && pedantic)
+ warning ("floating point number exceeds range of `long double'");
+ }
+ else
+ {
+ errno = 0;
+ if (args->base == 16)
+ args->value = REAL_VALUE_HTOF (copy, TYPE_MODE (args->type));
+ else
+ args->value = REAL_VALUE_ATOF (copy, TYPE_MODE (args->type));
+ args->conversion_errno = errno;
+ if (REAL_VALUE_ISINF (args->value) && pedantic)
+ warning ("floating point number exceeds range of `double'");
+ }
+}
+
int
yylex ()
{
@@ -1186,8 +1314,6 @@ yylex ()
while (ISALNUM (c) || c == '_' || c == '$' || c == '@')
{
/* Make sure this char really belongs in an identifier. */
- if (c == '@' && ! doing_objc_thang)
- break;
if (c == '$')
{
if (! dollars_in_ident)
@@ -1267,7 +1393,7 @@ yylex ()
&& TREE_CODE (DECL_INITIAL (lastiddecl)) == STRING_CST)
{
tree stringval = DECL_INITIAL (lastiddecl);
-
+
/* Copy the string value so that we won't clobber anything
if we put something in the TREE_CHAIN of this one. */
yylval.ttype = build_string (TREE_STRING_LENGTH (stringval),
@@ -1322,8 +1448,8 @@ yylex ()
int parts[TOTAL_PARTS];
int overflow = 0;
- enum anon1 { NOT_FLOAT, AFTER_POINT, TOO_MANY_POINTS} floatflag
- = NOT_FLOAT;
+ enum anon1 { NOT_FLOAT, AFTER_POINT, TOO_MANY_POINTS, AFTER_EXPON}
+ floatflag = NOT_FLOAT;
for (count = 0; count < TOTAL_PARTS; count++)
parts[count] = 0;
@@ -1359,12 +1485,12 @@ yylex ()
{
if (c == '.')
{
- if (base == 16)
+ if (base == 16 && pedantic)
error ("floating constant may not be in radix 16");
if (floatflag == TOO_MANY_POINTS)
/* We have already emitted an error. Don't need another. */
;
- else if (floatflag == AFTER_POINT)
+ else if (floatflag == AFTER_POINT || floatflag == AFTER_EXPON)
{
error ("malformed floating constant");
floatflag = TOO_MANY_POINTS;
@@ -1375,7 +1501,8 @@ yylex ()
else
floatflag = AFTER_POINT;
- base = 10;
+ if (base == 8)
+ base = 10;
*p++ = c = GETC();
/* Accept '.' as the start of a floating-point number
only when it is followed by a digit.
@@ -1414,12 +1541,17 @@ yylex ()
if (c == 'e' || c == 'E')
{
base = 10;
- floatflag = AFTER_POINT;
+ floatflag = AFTER_EXPON;
break; /* start of exponent */
}
error ("nondigits in number and not hexadecimal");
c = 0;
}
+ else if (base == 16 && (c == 'p' || c == 'P'))
+ {
+ floatflag = AFTER_EXPON;
+ break; /* start of exponent */
+ }
else if (c >= 'a')
{
c = c - 'a' + 10;
@@ -1472,11 +1604,12 @@ yylex ()
int imag = 0;
int conversion_errno = 0;
REAL_VALUE_TYPE value;
- jmp_buf handler;
+ struct pf_args args;
/* Read explicit exponent if any, and put it in tokenbuf. */
- if ((c == 'e') || (c == 'E'))
+ if ((base == 10 && ((c == 'e') || (c == 'E')))
+ || (base == 16 && (c == 'p' || c == 'P')))
{
if (p >= token_buffer + maxtoken - 3)
p = extend_token_buffer (p);
@@ -1487,9 +1620,10 @@ yylex ()
*p++ = c;
c = GETC();
}
+ /* Exponent is decimal, even if string is a hex float. */
if (! ISDIGIT (c))
error ("floating constant exponent has no digits");
- while (ISDIGIT (c))
+ while (ISDIGIT (c))
{
if (p >= token_buffer + maxtoken - 3)
p = extend_token_buffer (p);
@@ -1497,106 +1631,38 @@ yylex ()
c = GETC();
}
}
+ if (base == 16 && floatflag != AFTER_EXPON)
+ error ("hexadecimal floating constant has no exponent");
*p = 0;
+ /* Setup input for parse_float() */
+ args.base = base;
+ args.p = p;
+ args.c = c;
+ args.imag = imag;
+ args.type = type;
+ args.conversion_errno = conversion_errno;
+
/* Convert string to a double, checking for overflow. */
- if (setjmp (handler))
+ if (do_float_handler (parse_float, (PTR) &args))
{
- error ("floating constant out of range");
- value = dconst0;
+ /* Receive output from parse_float() */
+ value = args.value;
}
else
{
- int fflag = 0, lflag = 0;
- /* Copy token_buffer now, while it has just the number
- and not the suffixes; once we add `f' or `i',
- REAL_VALUE_ATOF may not work any more. */
- char *copy = (char *) alloca (p - token_buffer + 1);
- bcopy (token_buffer, copy, p - token_buffer + 1);
-
- set_float_handler (handler);
-
- while (1)
- {
- int lose = 0;
-
- /* Read the suffixes to choose a data type. */
- switch (c)
- {
- case 'f': case 'F':
- if (fflag)
- error ("more than one `f' in numeric constant");
- fflag = 1;
- break;
-
- case 'l': case 'L':
- if (lflag)
- error ("more than one `l' in numeric constant");
- lflag = 1;
- break;
-
- case 'i': case 'I':
- if (imag)
- error ("more than one `i' or `j' in numeric constant");
- else if (pedantic)
- pedwarn ("ANSI C forbids imaginary numeric constants");
- imag = 1;
- break;
-
- default:
- lose = 1;
- }
-
- if (lose)
- break;
-
- if (p >= token_buffer + maxtoken - 3)
- p = extend_token_buffer (p);
- *p++ = c;
- *p = 0;
- c = GETC();
- }
-
- /* The second argument, machine_mode, of REAL_VALUE_ATOF
- tells the desired precision of the binary result
- of decimal-to-binary conversion. */
-
- if (fflag)
- {
- if (lflag)
- error ("both `f' and `l' in floating constant");
-
- type = float_type_node;
- errno = 0;
- value = REAL_VALUE_ATOF (copy, TYPE_MODE (type));
- conversion_errno = errno;
- /* A diagnostic is required here by some ANSI C testsuites.
- This is not pedwarn, become some people don't want
- an error for this. */
- if (REAL_VALUE_ISINF (value) && pedantic)
- warning ("floating point number exceeds range of `float'");
- }
- else if (lflag)
- {
- type = long_double_type_node;
- errno = 0;
- value = REAL_VALUE_ATOF (copy, TYPE_MODE (type));
- conversion_errno = errno;
- if (REAL_VALUE_ISINF (value) && pedantic)
- warning ("floating point number exceeds range of `long double'");
- }
- else
- {
- errno = 0;
- value = REAL_VALUE_ATOF (copy, TYPE_MODE (type));
- conversion_errno = errno;
- if (REAL_VALUE_ISINF (value) && pedantic)
- warning ("floating point number exceeds range of `double'");
- }
+ /* We got an exception from parse_float() */
+ error ("floating constant out of range");
+ value = dconst0;
+ }
- set_float_handler (NULL_PTR);
- }
+ /* Receive output from parse_float() */
+ c = args.c;
+ imag = args.imag;
+ type = args.type;
+ conversion_errno = args.conversion_errno;
+
#ifdef ERANGE
/* ERANGE is also reported for underflow,
so test the value to distinguish overflow from that. */
@@ -1628,7 +1694,7 @@ yylex ()
int spec_long = 0;
int spec_long_long = 0;
int spec_imag = 0;
- int bytes, warn, i;
+ int warn, i;
traditional_type = ansi_type = type = NULL_TREE;
while (1)
@@ -1667,20 +1733,10 @@ yylex ()
c = GETC();
}
- /* If the constant won't fit in an unsigned long long,
- then warn that the constant is out of range. */
-
- /* ??? This assumes that long long and long integer types are
- a multiple of 8 bits. This better than the original code
- though which assumed that long was exactly 32 bits and long
- long was exactly 64 bits. */
-
- bytes = TYPE_PRECISION (long_long_integer_type_node) / 8;
+ /* If it won't fit in the host's representation for integers,
+ then pedwarn. */
warn = overflow;
- for (i = bytes; i < TOTAL_PARTS; i++)
- if (parts[i])
- warn = 1;
if (warn)
pedwarn ("integer constant out of range");
@@ -1696,7 +1752,7 @@ yylex ()
<< (i * HOST_BITS_PER_CHAR));
low |= (HOST_WIDE_INT) parts[i] << (i * HOST_BITS_PER_CHAR);
}
-
+
yylval.ttype = build_int_2 (low, high);
TREE_TYPE (yylval.ttype) = long_long_unsigned_type_node;
@@ -1771,7 +1827,10 @@ yylex ()
if (pedantic && !flag_traditional && !spec_long_long && !warn
&& (TYPE_PRECISION (long_integer_type_node)
< TYPE_PRECISION (type)))
- pedwarn ("integer constant out of range");
+ {
+ warn = 1;
+ pedwarn ("integer constant out of range");
+ }
if (base == 10 && ! spec_unsigned && TREE_UNSIGNED (type))
warning ("decimal constant is so large that it is unsigned");
@@ -1799,6 +1858,15 @@ yylex ()
}
else
TREE_TYPE (yylval.ttype) = type;
+
+
+ /* If it's still an integer (not a complex), and it doesn't
+ fit in the type we choose for it, then pedwarn. */
+
+ if (! warn
+ && TREE_CODE (TREE_TYPE (yylval.ttype)) == INTEGER_TYPE
+ && ! int_fits_type_p (yylval.ttype, TREE_TYPE (yylval.ttype)))
+ pedwarn ("integer constant out of range");
}
UNGETC (c);
@@ -1845,7 +1913,7 @@ yylex ()
if (ignore)
goto tryagain;
if (width < HOST_BITS_PER_INT
- && (unsigned) c >= (1 << width))
+ && (unsigned) c >= ((unsigned)1 << width))
pedwarn ("escape sequence out of range for character");
#ifdef MAP_CHARACTER
if (ISPRINT (c))
@@ -2000,7 +2068,7 @@ yylex ()
if (ignore)
goto skipnewline;
if (width < HOST_BITS_PER_INT
- && (unsigned) c >= (1 << width))
+ && (unsigned) c >= ((unsigned)1 << width))
pedwarn ("escape sequence out of range for character");
}
else if (c == '\n')
@@ -2033,15 +2101,13 @@ yylex ()
/* mbtowc sometimes needs an extra char before accepting */
if (char_len <= i)
UNGETC (c);
- if (wide_flag)
+ if (! wide_flag)
{
- *(wchar_t *)p = wc;
- p += sizeof (wc);
+ p += (i + 1);
+ c = GETC ();
+ continue;
}
- else
- p += (i + 1);
- c = GETC ();
- continue;
+ c = wc;
}
#endif /* MULTIBYTE_CHARS */
}
@@ -2060,7 +2126,7 @@ yylex ()
for (byte = 0; byte < WCHAR_BYTES; ++byte)
{
int value;
- if (byte >= sizeof (c))
+ if (byte >= (int) sizeof (c))
value = 0;
else
value = (c >> (byte * width)) & bytemask;
diff --git a/gcc/c-lex.h b/gcc/c-lex.h
index bd0b9d4b91f..7d73ab5d366 100644
--- a/gcc/c-lex.h
+++ b/gcc/c-lex.h
@@ -1,5 +1,5 @@
/* Define constants for communication with c-parse.y.
- Copyright (C) 1987, 1992 Free Software Foundation, Inc.
+ Copyright (C) 1987, 1992, 1998 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -40,6 +40,7 @@ enum rid
RID_TYPEDEF,
RID_SIGNED,
RID_CONST,
+ RID_RESTRICT,
RID_VOLATILE,
RID_INLINE,
RID_NOALIAS,
@@ -50,6 +51,7 @@ enum rid
RID_OUT,
RID_INOUT,
RID_BYCOPY,
+ RID_BYREF,
RID_ONEWAY,
RID_ID,
@@ -79,7 +81,7 @@ extern void position_after_white_space PROTO((void));
extern int check_newline PROTO((void));
extern int yylex PROTO((void));
-extern void yyerror PROTO((char *));
+extern void yyerror PROTO((const char *));
extern void forget_protocol_qualifiers PROTO((void));
extern void remember_protocol_qualifiers PROTO((void));
diff --git a/gcc/c-parse.gperf b/gcc/c-parse.gperf
index 017dcb5497e..324bd249554 100644
--- a/gcc/c-parse.gperf
+++ b/gcc/c-parse.gperf
@@ -35,6 +35,8 @@ __iterator__, SCSPEC, RID_ITERATOR
__label__, LABEL, NORID
__real, REALPART, NORID
__real__, REALPART, NORID
+__restrict, TYPE_QUAL, RID_RESTRICT
+__restrict__, TYPE_QUAL, RID_RESTRICT
__signed, TYPESPEC, RID_SIGNED
__signed__, TYPESPEC, RID_SIGNED
__typeof, TYPEOF, NORID
@@ -45,6 +47,7 @@ asm, ASM_KEYWORD, NORID
auto, SCSPEC, RID_AUTO
break, BREAK, NORID
bycopy, TYPE_QUAL, RID_BYCOPY
+byref, TYPE_QUAL, RID_BYREF
case, CASE, NORID
char, TYPESPEC, RID_CHAR
const, TYPE_QUAL, RID_CONST
@@ -68,6 +71,7 @@ long, TYPESPEC, RID_LONG
oneway, TYPE_QUAL, RID_ONEWAY
out, TYPE_QUAL, RID_OUT
register, SCSPEC, RID_REGISTER
+restrict, TYPE_QUAL, RID_RESTRICT
return, RETURN, NORID
short, TYPESPEC, RID_SHORT
signed, TYPESPEC, RID_SIGNED
diff --git a/gcc/c-parse.in b/gcc/c-parse.in
index 3db5c1fd1d6..6de29f9eb04 100644
--- a/gcc/c-parse.in
+++ b/gcc/c-parse.in
@@ -1,5 +1,5 @@
/* YACC parser for C syntax and for Objective C. -*-c-*-
- Copyright (C) 1987, 88, 89, 92-97, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1987, 88, 89, 92-98, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -116,7 +116,7 @@ end ifc
yylval contains an IDENTIFIER_NODE which indicates which one. */
%token TYPESPEC
-/* Reserved words that qualify type: "const" or "volatile".
+/* Reserved words that qualify type: "const", "volatile", or "restrict".
yylval contains an IDENTIFIER_NODE which indicates which one. */
%token TYPE_QUAL
@@ -534,7 +534,7 @@ cast_expr:
tree type = $2;
finish_init ();
- if (pedantic)
+ if (pedantic && ! flag_isoc9x)
pedwarn ("ANSI C forbids constructor expressions");
if (TYPE_NAME (type) != 0)
{
@@ -1284,33 +1284,41 @@ initlist1:
/* `initelt' is a single element of an initializer.
It may use braces. */
initelt:
- expr_no_commas
- { process_init_element ($1); }
- | '{'
+ designator_list '=' initval
+ | designator initval
+ | identifier ':'
+ { set_init_label ($1); }
+ initval
+ | initval
+ ;
+
+initval:
+ '{'
{ push_init_level (0); }
initlist_maybe_comma '}'
{ process_init_element (pop_init_level (0)); }
+ | expr_no_commas
+ { process_init_element ($1); }
| error
+ ;
+
+designator_list:
+ designator
+ | designator_list designator
+ ;
+
+designator:
+ '.' identifier
+ { set_init_label ($2); }
/* These are for labeled elements. The syntax for an array element
initializer conflicts with the syntax for an Objective-C message,
so don't include these productions in the Objective-C grammar. */
ifc
- | '[' expr_no_commas ELLIPSIS expr_no_commas ']' '='
+ | '[' expr_no_commas ELLIPSIS expr_no_commas ']'
{ set_init_index ($2, $4); }
- initelt
- | '[' expr_no_commas ']' '='
- { set_init_index ($2, NULL_TREE); }
- initelt
| '[' expr_no_commas ']'
{ set_init_index ($2, NULL_TREE); }
- initelt
end ifc
- | identifier ':'
- { set_init_label ($1); }
- initelt
- | '.' identifier '='
- { set_init_label ($2); }
- initelt
;
nested_function:
@@ -1413,6 +1421,13 @@ parm_declarator:
/* | parm_declarator '(' error ')' %prec '.'
{ $$ = build_nt (CALL_EXPR, $1, NULL_TREE, NULL_TREE);
poplevel (0, 0, 0); } */
+ifc
+ | parm_declarator '[' '*' ']' %prec '.'
+ { $$ = build_nt (ARRAY_REF, $1, NULL_TREE);
+ if (! flag_isoc9x)
+ error ("`[*]' in parameter declaration only allowed in ISO C 9x");
+ }
+end ifc
| parm_declarator '[' expr ']' %prec '.'
{ $$ = build_nt (ARRAY_REF, $1, $3); }
| parm_declarator '[' ']' %prec '.'
@@ -1442,6 +1457,13 @@ notype_declarator:
{ $$ = $2; }
| '*' type_quals notype_declarator %prec UNARY
{ $$ = make_pointer_declarator ($2, $3); }
+ifc
+ | notype_declarator '[' '*' ']' %prec '.'
+ { $$ = build_nt (ARRAY_REF, $1, NULL_TREE);
+ if (! flag_isoc9x)
+ error ("`[*]' in parameter declaration only allowed in ISO C 9x");
+ }
+end ifc
| notype_declarator '[' expr ']' %prec '.'
{ $$ = build_nt (ARRAY_REF, $1, $3); }
| notype_declarator '[' ']' %prec '.'
@@ -1524,7 +1546,8 @@ maybecomma:
maybecomma_warn:
/* empty */
| ','
- { if (pedantic) pedwarn ("comma at end of enumerator list"); }
+ { if (pedantic && ! flag_isoc9x)
+ pedwarn ("comma at end of enumerator list"); }
;
component_decl_list:
@@ -2206,12 +2229,15 @@ label: CASE expr_no_commas ':'
error_with_decl (duplicate, "this is the first default label");
}
position_after_white_space (); }
- | identifier ':'
+ | identifier ':' maybe_attribute
{ tree label = define_label (input_filename, lineno, $1);
stmt_count++;
emit_nop ();
if (label)
- expand_label (label);
+ {
+ expand_label (label);
+ decl_attributes (label, $3, NULL_TREE);
+ }
position_after_white_space (); }
;
diff --git a/gcc/c-parse.y b/gcc/c-parse.y
index 693fd89cddc..0afa87b5ce5 100644
--- a/gcc/c-parse.y
+++ b/gcc/c-parse.y
@@ -1,6 +1,6 @@
/*WARNING: This file is automatically generated!*/
/* YACC parser for C syntax and for Objective C. -*-c-*-
- Copyright (C) 1987, 88, 89, 92-97, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1987, 88, 89, 92-98, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -104,7 +104,7 @@ char *language_string = "GNU C";
yylval contains an IDENTIFIER_NODE which indicates which one. */
%token TYPESPEC
-/* Reserved words that qualify type: "const" or "volatile".
+/* Reserved words that qualify type: "const", "volatile", or "restrict".
yylval contains an IDENTIFIER_NODE which indicates which one. */
%token TYPE_QUAL
@@ -489,7 +489,7 @@ cast_expr:
tree type = $2;
finish_init ();
- if (pedantic)
+ if (pedantic && ! flag_isoc9x)
pedwarn ("ANSI C forbids constructor expressions");
if (TYPE_NAME (type) != 0)
{
@@ -1118,31 +1118,39 @@ initlist1:
/* `initelt' is a single element of an initializer.
It may use braces. */
initelt:
- expr_no_commas
- { process_init_element ($1); }
- | '{'
+ designator_list '=' initval
+ | designator initval
+ | identifier ':'
+ { set_init_label ($1); }
+ initval
+ | initval
+ ;
+
+initval:
+ '{'
{ push_init_level (0); }
initlist_maybe_comma '}'
{ process_init_element (pop_init_level (0)); }
+ | expr_no_commas
+ { process_init_element ($1); }
| error
+ ;
+
+designator_list:
+ designator
+ | designator_list designator
+ ;
+
+designator:
+ '.' identifier
+ { set_init_label ($2); }
/* These are for labeled elements. The syntax for an array element
initializer conflicts with the syntax for an Objective-C message,
so don't include these productions in the Objective-C grammar. */
- | '[' expr_no_commas ELLIPSIS expr_no_commas ']' '='
+ | '[' expr_no_commas ELLIPSIS expr_no_commas ']'
{ set_init_index ($2, $4); }
- initelt
- | '[' expr_no_commas ']' '='
- { set_init_index ($2, NULL_TREE); }
- initelt
| '[' expr_no_commas ']'
{ set_init_index ($2, NULL_TREE); }
- initelt
- | identifier ':'
- { set_init_label ($1); }
- initelt
- | '.' identifier '='
- { set_init_label ($2); }
- initelt
;
nested_function:
@@ -1242,6 +1250,11 @@ parm_declarator:
/* | parm_declarator '(' error ')' %prec '.'
{ $$ = build_nt (CALL_EXPR, $1, NULL_TREE, NULL_TREE);
poplevel (0, 0, 0); } */
+ | parm_declarator '[' '*' ']' %prec '.'
+ { $$ = build_nt (ARRAY_REF, $1, NULL_TREE);
+ if (! flag_isoc9x)
+ error ("`[*]' in parameter declaration only allowed in ISO C 9x");
+ }
| parm_declarator '[' expr ']' %prec '.'
{ $$ = build_nt (ARRAY_REF, $1, $3); }
| parm_declarator '[' ']' %prec '.'
@@ -1271,6 +1284,11 @@ notype_declarator:
{ $$ = $2; }
| '*' type_quals notype_declarator %prec UNARY
{ $$ = make_pointer_declarator ($2, $3); }
+ | notype_declarator '[' '*' ']' %prec '.'
+ { $$ = build_nt (ARRAY_REF, $1, NULL_TREE);
+ if (! flag_isoc9x)
+ error ("`[*]' in parameter declaration only allowed in ISO C 9x");
+ }
| notype_declarator '[' expr ']' %prec '.'
{ $$ = build_nt (ARRAY_REF, $1, $3); }
| notype_declarator '[' ']' %prec '.'
@@ -1353,7 +1371,8 @@ maybecomma:
maybecomma_warn:
/* empty */
| ','
- { if (pedantic) pedwarn ("comma at end of enumerator list"); }
+ { if (pedantic && ! flag_isoc9x)
+ pedwarn ("comma at end of enumerator list"); }
;
component_decl_list:
@@ -2015,12 +2034,15 @@ label: CASE expr_no_commas ':'
error_with_decl (duplicate, "this is the first default label");
}
position_after_white_space (); }
- | identifier ':'
+ | identifier ':' maybe_attribute
{ tree label = define_label (input_filename, lineno, $1);
stmt_count++;
emit_nop ();
if (label)
- expand_label (label);
+ {
+ expand_label (label);
+ decl_attributes (label, $3, NULL_TREE);
+ }
position_after_white_space (); }
;
diff --git a/gcc/c-pragma.c b/gcc/c-pragma.c
index 65ab63d25da..a4d730d3e87 100644
--- a/gcc/c-pragma.c
+++ b/gcc/c-pragma.c
@@ -191,30 +191,6 @@ insert_pack_attributes (node, attributes, prefix)
}
#endif /* HANDLE_PRAGMA_PACK_PUSH_POP */
-#ifdef HANDLE_PRAGMA_WEAK
-static int add_weak PROTO((char *, char *));
-
-static int
-add_weak (name, value)
- char * name;
- char * value;
-{
- struct weak_syms * weak;
-
- weak = (struct weak_syms *) permalloc (sizeof (struct weak_syms));
-
- if (weak == NULL)
- return 0;
-
- weak->next = weak_decls;
- weak->name = name;
- weak->value = value;
- weak_decls = weak;
-
- return 1;
-}
-#endif /* HANDLE_PRAGMA_WEAK */
-
/* Handle one token of a pragma directive. TOKEN is the current token, and
STRING is its printable form. Some front ends do not support generating
tokens, and will only pass in a STRING. Also some front ends will reuse
@@ -230,7 +206,7 @@ add_weak (name, value)
int
handle_pragma_token (string, token)
- char * string;
+ const char * string;
tree token;
{
static enum pragma_state state = ps_start;
@@ -383,7 +359,11 @@ handle_pragma_token (string, token)
break;
case ps_left:
- align = atoi (string);
+
+ if (token && TREE_CODE(token) == INTEGER_CST)
+ align = TREE_INT_CST_LOW(token);
+ else
+ align = atoi (string);
switch (align)
{
case 1:
diff --git a/gcc/c-pragma.h b/gcc/c-pragma.h
index 685f54aeb78..ddc74d1076e 100644
--- a/gcc/c-pragma.h
+++ b/gcc/c-pragma.h
@@ -56,6 +56,8 @@ struct weak_syms
/* Declared in varasm.c */
extern struct weak_syms * weak_decls;
+
+extern int add_weak PROTO((char *, char *));
#endif /* HANDLE_PRAGMA_WEAK */
@@ -94,7 +96,7 @@ enum pragma_state
};
/* Handle a C style pragma */
-extern int handle_pragma_token PROTO((char *, tree));
+extern int handle_pragma_token PROTO((const char *, tree));
#endif /* HANDLE_GENERIC_PRAGMAS */
#endif /* _C_PRAGMA_H */
diff --git a/gcc/c-tree.h b/gcc/c-tree.h
index bfb4ad7d19b..07833d2c83c 100644
--- a/gcc/c-tree.h
+++ b/gcc/c-tree.h
@@ -1,5 +1,5 @@
/* Definitions for C parsing and type checking.
- Copyright (C) 1987, 1993, 1994, 1995, 1997 Free Software Foundation, Inc.
+ Copyright (C) 1987, 93, 94, 95, 97, 98, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -84,6 +84,22 @@ extern int pedantic;
nonzero if the definition of the type has already started. */
#define C_TYPE_BEING_DEFINED(type) TYPE_LANG_FLAG_0 (type)
+/* C types are partitioned into three subsets: object, function, and
+ incomplete types. */
+#define C_TYPE_OBJECT_P(type) \
+ (TREE_CODE (type) != FUNCTION_TYPE && TYPE_SIZE (type))
+
+#define C_TYPE_FUNCTION_P(type) \
+ (TREE_CODE (type) == FUNCTION_TYPE)
+
+#define C_TYPE_INCOMPLETE_P(type) \
+ (TREE_CODE (type) != FUNCTION_TYPE && TYPE_SIZE (type) == 0)
+
+/* For convenience we define a single macro to identify the class of
+ object or incomplete types. */
+#define C_TYPE_OBJECT_OR_INCOMPLETE_P(type) \
+ (!C_TYPE_FUNCTION_P (type))
+
/* In a RECORD_TYPE, a sorted array of the fields of the type. */
struct lang_type
{
@@ -158,23 +174,67 @@ extern int maybe_objc_comptypes PROTO((tree, tree, int));
extern tree maybe_building_objc_message_expr PROTO((void));
extern tree maybe_objc_method_name PROTO((tree));
extern int recognize_objc_keyword PROTO((void));
-extern tree build_objc_string PROTO((int, char *));
+extern tree build_objc_string PROTO((int, const char *));
/* in c-parse.in */
extern void c_parse_init PROTO((void));
/* in c-aux-info.c */
extern void gen_aux_info_record PROTO((tree, int, int, int));
+/* in c-common.c */
+extern void declare_function_name PROTO((void));
+extern void decl_attributes PROTO((tree, tree, tree));
+extern void init_function_format_info PROTO((void));
+extern void check_function_format PROTO((tree, tree, tree));
+extern int c_get_alias_set PROTO((tree));
+extern void c_apply_type_quals_to_decl PROTO((int, tree));
+/* Print an error message for invalid operands to arith operation CODE.
+ NOP_EXPR is used as a special case (see truthvalue_conversion). */
+extern void binary_op_error PROTO((enum tree_code));
+extern void c_expand_expr_stmt PROTO((tree));
+extern void c_expand_start_cond PROTO((tree, int, int));
+extern void c_expand_start_else PROTO((void));
+extern void c_expand_end_cond PROTO((void));
+/* Validate the expression after `case' and apply default promotions. */
+extern tree check_case_value PROTO((tree));
+/* Concatenate a list of STRING_CST nodes into one STRING_CST. */
+extern tree combine_strings PROTO((tree));
+extern void constant_expression_warning PROTO((tree));
+extern tree convert_and_check PROTO((tree, tree));
+extern void overflow_warning PROTO((tree));
+extern void unsigned_conversion_warning PROTO((tree, tree));
+/* Read the rest of the current #-directive line. */
+#if USE_CPPLIB
+extern char *get_directive_line PROTO((void));
+#define GET_DIRECTIVE_LINE() get_directive_line ()
+#else
+extern char *get_directive_line PROTO((FILE *));
+#define GET_DIRECTIVE_LINE() get_directive_line (finput)
+#endif
+
+/* Subroutine of build_binary_op, used for comparison operations.
+ See if the operands have both been converted from subword integer types
+ and, if so, perhaps change them both back to their original type. */
+extern tree shorten_compare PROTO((tree *, tree *, tree *, enum tree_code *));
+/* Prepare expr to be an argument of a TRUTH_NOT_EXPR,
+ or validate its data type for an `if' or `while' statement or ?..: exp. */
+extern tree truthvalue_conversion PROTO((tree));
+extern tree type_for_mode PROTO((enum machine_mode, int));
+extern tree type_for_size PROTO((unsigned, int));
+
/* in c-convert.c */
extern tree convert PROTO((tree, tree));
/* in c-decl.c */
-
extern tree build_enumerator PROTO((tree, tree));
/* Declare a predefined function. Return the declaration. */
-extern tree builtin_function PROTO((char *, tree, enum built_in_function function_, char *));
+extern tree builtin_function PROTO((const char *, tree, enum built_in_function function_, const char *));
/* Add qualifiers to a type, in the fashion for C. */
-extern tree c_build_type_variant PROTO((tree, int, int));
+extern tree c_build_qualified_type PROTO((tree, int));
+#define c_build_type_variant(TYPE, CONST_P, VOLATILE_P) \
+ c_build_qualified_type (TYPE, \
+ ((CONST_P) ? TYPE_QUAL_CONST : 0) | \
+ ((VOLATILE_P) ? TYPE_QUAL_VOLATILE : 0))
extern int c_decode_option PROTO((int, char **));
extern void c_mark_varargs PROTO((void));
extern tree check_identifier PROTO((tree, tree));
@@ -193,7 +253,7 @@ extern tree get_parm_info PROTO((int));
extern tree getdecls PROTO((void));
extern tree gettags PROTO((void));
extern int global_bindings_p PROTO((void));
-extern tree grokfield PROTO((char *, int, tree, tree, tree));
+extern tree grokfield PROTO((const char *, int, tree, tree, tree));
extern tree groktypename PROTO((tree));
extern tree groktypename_in_parm_context PROTO((tree));
extern tree implicitly_declare PROTO((tree));
@@ -252,7 +312,7 @@ extern tree c_alignof PROTO((tree));
extern tree c_alignof_expr PROTO((tree));
extern tree default_conversion PROTO((tree));
extern tree build_component_ref PROTO((tree, tree));
-extern tree build_indirect_ref PROTO((tree, char *));
+extern tree build_indirect_ref PROTO((tree, const char *));
extern tree build_array_ref PROTO((tree, tree));
extern tree build_function_call PROTO((tree, tree));
extern tree parser_build_binary_op PROTO((enum tree_code,
@@ -262,8 +322,8 @@ extern tree build_binary_op PROTO((enum tree_code,
extern tree build_unary_op PROTO((enum tree_code,
tree, int));
extern int lvalue_p PROTO((tree));
-extern int lvalue_or_else PROTO((tree, char *));
-extern void readonly_warning PROTO((tree, char *));
+extern int lvalue_or_else PROTO((tree, const char *));
+extern void readonly_warning PROTO((tree, const char *));
extern int mark_addressable PROTO((tree));
extern tree build_conditional_expr PROTO((tree, tree, tree));
extern tree build_compound_expr PROTO((tree));
@@ -272,10 +332,8 @@ extern tree build_modify_expr PROTO((tree, enum tree_code,
tree));
extern tree initializer_constant_valid_p PROTO((tree, tree));
extern void store_init_value PROTO((tree, tree));
-extern void error_init PROTO((char *, char *,
- char *));
-extern void pedwarn_init PROTO((char *, char *,
- char *));
+extern void error_init PROTO((const char *));
+extern void pedwarn_init PROTO((const char *));
extern void start_init PROTO((tree, tree, int));
extern void finish_init PROTO((void));
extern void really_start_incremental_init PROTO((tree));
@@ -330,10 +388,6 @@ extern int flag_no_asm;
extern int flag_hosted;
-/* Nonzero means ignore `#ident' directives. */
-
-extern int flag_no_ident;
-
/* Nonzero means warn about implicit declarations. */
extern int warn_implicit;
@@ -377,6 +431,10 @@ extern int warn_cast_qual;
extern int warn_bad_function_cast;
+/* Warn about functions which might be candidates for attribute noreturn. */
+
+extern int warn_missing_noreturn;
+
/* Warn about traditional constructs whose meanings changed in ANSI C. */
extern int warn_traditional;
@@ -401,6 +459,10 @@ extern int warn_main;
extern int flag_traditional;
+/* Nonzero means use the ISO C9x dialect of C. */
+
+extern int flag_isoc9x;
+
/* Nonzero means to allow single precision math even if we're generally
being traditional. */
extern int flag_allow_single_precision;
diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c
index d77d9cf6bab..e896c89e17a 100644
--- a/gcc/c-typeck.c
+++ b/gcc/c-typeck.c
@@ -37,6 +37,7 @@ Boston, MA 02111-1307, USA. */
#include "rtl.h"
#include "expr.h"
#include "toplev.h"
+#include "intl.h"
/* Nonzero if we've already printed a "missing braces around initializer"
message within this initializer. */
@@ -55,18 +56,17 @@ static tree pointer_diff PROTO((tree, tree));
static tree unary_complex_lvalue PROTO((enum tree_code, tree));
static void pedantic_lvalue_warning PROTO((enum tree_code));
static tree internal_build_compound_expr PROTO((tree, int));
-static tree convert_for_assignment PROTO((tree, tree, char *, tree,
+static tree convert_for_assignment PROTO((tree, tree, const char *, tree,
+ tree, int));
+static void warn_for_assignment PROTO((const char *, const char *,
tree, int));
-static void warn_for_assignment PROTO((char *, char *, tree, int));
static tree valid_compound_expr_initializer PROTO((tree, tree));
-static void push_string PROTO((char *));
+static void push_string PROTO((const char *));
static void push_member_name PROTO((tree));
static void push_array_bounds PROTO((int));
static int spelling_length PROTO((void));
static char *print_spelling PROTO((char *));
-static char *get_spelling PROTO((char *));
-static void warning_init PROTO((char *, char *,
- char *));
+static void warning_init PROTO((const char *));
static tree digest_init PROTO((tree, tree, int, int));
static void check_init_type_bitfields PROTO((tree));
static void output_init_element PROTO((tree, tree, tree, int));
@@ -101,7 +101,7 @@ incomplete_type_error (value, type)
tree value;
tree type;
{
- char *errmsg;
+ const char *type_code_string;
/* Avoid duplicate error message. */
if (TREE_CODE (type) == ERROR_MARK)
@@ -119,15 +119,15 @@ incomplete_type_error (value, type)
switch (TREE_CODE (type))
{
case RECORD_TYPE:
- errmsg = "invalid use of undefined type `struct %s'";
+ type_code_string = "struct";
break;
case UNION_TYPE:
- errmsg = "invalid use of undefined type `union %s'";
+ type_code_string = "union";
break;
case ENUMERAL_TYPE:
- errmsg = "invalid use of undefined type `enum %s'";
+ type_code_string = "enum";
break;
case VOID_TYPE:
@@ -148,7 +148,8 @@ incomplete_type_error (value, type)
}
if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE)
- error (errmsg, IDENTIFIER_POINTER (TYPE_NAME (type)));
+ error ("invalid use of undefined type `%s %s'",
+ type_code_string, IDENTIFIER_POINTER (TYPE_NAME (type)));
else
/* If this type has a typedef-name, the TYPE_NAME is a TYPE_DECL. */
error ("invalid use of incomplete typedef `%s'",
@@ -163,9 +164,7 @@ static tree
qualify_type (type, like)
tree type, like;
{
- int constflag = TYPE_READONLY (type) || TYPE_READONLY (like);
- int volflag = TYPE_VOLATILE (type) || TYPE_VOLATILE (like);
- return c_build_type_variant (type, constflag, volflag);
+ return c_build_qualified_type (type, TYPE_QUALS (like));
}
/* Return the common type of two types.
@@ -283,14 +282,14 @@ common_type (t1, t2)
But ANSI C specifies doing this with the qualifiers.
So I turned it on again. */
{
- tree target = common_type (TYPE_MAIN_VARIANT (TREE_TYPE (t1)),
- TYPE_MAIN_VARIANT (TREE_TYPE (t2)));
- int constp
- = TYPE_READONLY (TREE_TYPE (t1)) || TYPE_READONLY (TREE_TYPE (t2));
- int volatilep
- = TYPE_VOLATILE (TREE_TYPE (t1)) || TYPE_VOLATILE (TREE_TYPE (t2));
- t1 = build_pointer_type (c_build_type_variant (target, constp,
- volatilep));
+ tree pointed_to_1 = TREE_TYPE (t1);
+ tree pointed_to_2 = TREE_TYPE (t2);
+ tree target = common_type (TYPE_MAIN_VARIANT (pointed_to_1),
+ TYPE_MAIN_VARIANT (pointed_to_2));
+ t1 = build_pointer_type (c_build_qualified_type
+ (target,
+ TYPE_QUALS (pointed_to_1) |
+ TYPE_QUALS (pointed_to_2)));
return build_type_attribute_variant (t1, attributes);
}
#if 0
@@ -447,9 +446,7 @@ comptypes (type1, type2)
/* Qualifiers must match. */
- if (TYPE_READONLY (t1) != TYPE_READONLY (t2))
- return 0;
- if (TYPE_VOLATILE (t1) != TYPE_VOLATILE (t2))
+ if (TYPE_QUALS (t1) != TYPE_QUALS (t2))
return 0;
/* Allow for two different type nodes which have essentially the same
@@ -1084,11 +1081,12 @@ default_conversion (exp)
volatilep = TREE_THIS_VOLATILE (exp);
}
- if (TYPE_READONLY (type) || TYPE_VOLATILE (type)
- || constp || volatilep)
- restype = c_build_type_variant (restype,
- TYPE_READONLY (type) || constp,
- TYPE_VOLATILE (type) || volatilep);
+ if (TYPE_QUALS (type) || constp || volatilep)
+ restype
+ = c_build_qualified_type (restype,
+ TYPE_QUALS (type)
+ | (constp * TYPE_QUAL_CONST)
+ | (volatilep * TYPE_QUAL_VOLATILE));
if (TREE_CODE (exp) == INDIRECT_REF)
return convert (TYPE_POINTER_TO (restype),
@@ -1324,7 +1322,7 @@ build_component_ref (datum, component)
tree
build_indirect_ref (ptr, errorstring)
tree ptr;
- char *errorstring;
+ const char *errorstring;
{
register tree pointer = default_conversion (ptr);
register tree type = TREE_TYPE (pointer);
@@ -2793,7 +2791,6 @@ build_unary_op (code, xarg, noconvert)
register tree arg = xarg;
register tree argtype = 0;
register enum tree_code typecode = TREE_CODE (TREE_TYPE (arg));
- char *errstring = NULL;
tree val;
if (typecode == ERROR_MARK)
@@ -2809,7 +2806,10 @@ build_unary_op (code, xarg, noconvert)
associativity, but won't generate any code. */
if (!(typecode == INTEGER_TYPE || typecode == REAL_TYPE
|| typecode == COMPLEX_TYPE))
- errstring = "wrong type argument to unary plus";
+ {
+ error ("wrong type argument to unary plus");
+ return error_mark_node;
+ }
else if (!noconvert)
arg = default_conversion (arg);
break;
@@ -2817,7 +2817,10 @@ build_unary_op (code, xarg, noconvert)
case NEGATE_EXPR:
if (!(typecode == INTEGER_TYPE || typecode == REAL_TYPE
|| typecode == COMPLEX_TYPE))
- errstring = "wrong type argument to unary minus";
+ {
+ error ("wrong type argument to unary minus");
+ return error_mark_node;
+ }
else if (!noconvert)
arg = default_conversion (arg);
break;
@@ -2830,7 +2833,10 @@ build_unary_op (code, xarg, noconvert)
arg = default_conversion (arg);
}
else if (typecode != INTEGER_TYPE)
- errstring = "wrong type argument to bit-complement";
+ {
+ error ("wrong type argument to bit-complement");
+ return error_mark_node;
+ }
else if (!noconvert)
arg = default_conversion (arg);
break;
@@ -2838,7 +2844,10 @@ build_unary_op (code, xarg, noconvert)
case ABS_EXPR:
if (!(typecode == INTEGER_TYPE || typecode == REAL_TYPE
|| typecode == COMPLEX_TYPE))
- errstring = "wrong type argument to abs";
+ {
+ error ("wrong type argument to abs");
+ return error_mark_node;
+ }
else if (!noconvert)
arg = default_conversion (arg);
break;
@@ -2847,7 +2856,10 @@ build_unary_op (code, xarg, noconvert)
/* Conjugating a real value is a no-op, but allow it anyway. */
if (!(typecode == INTEGER_TYPE || typecode == REAL_TYPE
|| typecode == COMPLEX_TYPE))
- errstring = "wrong type argument to conjugation";
+ {
+ error ("wrong type argument to conjugation");
+ return error_mark_node;
+ }
else if (!noconvert)
arg = default_conversion (arg);
break;
@@ -2859,8 +2871,8 @@ build_unary_op (code, xarg, noconvert)
/* These will convert to a pointer. */
&& typecode != ARRAY_TYPE && typecode != FUNCTION_TYPE)
{
- errstring = "wrong type argument to unary exclamation mark";
- break;
+ error ("wrong type argument to unary exclamation mark");
+ return error_mark_node;
}
arg = truthvalue_conversion (arg);
return invert_truthvalue (arg);
@@ -2913,11 +2925,10 @@ build_unary_op (code, xarg, noconvert)
if (typecode != POINTER_TYPE
&& typecode != INTEGER_TYPE && typecode != REAL_TYPE)
{
- if (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR)
- errstring ="wrong type argument to increment";
- else
- errstring ="wrong type argument to decrement";
- break;
+ error (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR
+ ? "wrong type argument to increment"
+ : "wrong type argument to decrement");
+ return error_mark_node;
}
{
@@ -2934,17 +2945,15 @@ build_unary_op (code, xarg, noconvert)
/* If pointer target is an undefined struct,
we just cannot know how to do the arithmetic. */
if (TYPE_SIZE (TREE_TYPE (result_type)) == 0)
- error ("%s of pointer to unknown structure",
- ((code == PREINCREMENT_EXPR
- || code == POSTINCREMENT_EXPR)
- ? "increment" : "decrement"));
+ error (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR
+ ? "increment of pointer to unknown structure"
+ : "decrement of pointer to unknown structure");
else if ((pedantic || warn_pointer_arith)
&& (TREE_CODE (TREE_TYPE (result_type)) == FUNCTION_TYPE
|| TREE_CODE (TREE_TYPE (result_type)) == VOID_TYPE))
- pedwarn ("wrong type argument to %s",
- ((code == PREINCREMENT_EXPR
- || code == POSTINCREMENT_EXPR)
- ? "increment" : "decrement"));
+ pedwarn (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR
+ ? "wrong type argument to increment"
+ : "wrong type argument to decrement");
inc = c_size_in_bytes (TREE_TYPE (result_type));
}
else
@@ -3001,7 +3010,8 @@ build_unary_op (code, xarg, noconvert)
/* Complain about anything else that is not a true lvalue. */
if (!lvalue_or_else (arg, ((code == PREINCREMENT_EXPR
|| code == POSTINCREMENT_EXPR)
- ? "increment" : "decrement")))
+ ? "invalid lvalue in increment"
+ : "invalid lvalue in decrement")))
return error_mark_node;
/* Report a read-only lvalue. */
@@ -3075,13 +3085,16 @@ build_unary_op (code, xarg, noconvert)
;
/* Anything not already handled and not a true memory reference
is an error. */
- else if (typecode != FUNCTION_TYPE && !lvalue_or_else (arg, "unary `&'"))
+ else if (typecode != FUNCTION_TYPE
+ && !lvalue_or_else (arg, "invalid lvalue in unary `&'"))
return error_mark_node;
/* Ordinary case; arg is a COMPONENT_REF or a decl. */
argtype = TREE_TYPE (arg);
- /* If the lvalue is const or volatile,
- merge that into the type that the address will point to. */
+ /* If the lvalue is const or volatile, merge that into the type
+ to which the address will point. Note that you can't get a
+ restricted pointer by taking the address of something, so we
+ only have to deal with `const' and `volatile' here. */
if (TREE_CODE_CLASS (TREE_CODE (arg)) == 'd'
|| TREE_CODE_CLASS (TREE_CODE (arg)) == 'r')
{
@@ -3141,15 +3154,9 @@ build_unary_op (code, xarg, noconvert)
break;
}
- if (!errstring)
- {
- if (argtype == 0)
- argtype = TREE_TYPE (arg);
- return fold (build1 (code, argtype, arg));
- }
-
- error (errstring);
- return error_mark_node;
+ if (argtype == 0)
+ argtype = TREE_TYPE (arg);
+ return fold (build1 (code, argtype, arg));
}
#if 0
@@ -3223,13 +3230,13 @@ lvalue_p (ref)
otherwise, print an error message and return zero. */
int
-lvalue_or_else (ref, string)
+lvalue_or_else (ref, msgid)
tree ref;
- char *string;
+ const char *msgid;
{
int win = lvalue_p (ref);
if (! win)
- error ("invalid lvalue in %s", string);
+ error (msgid);
return win;
}
@@ -3282,47 +3289,38 @@ pedantic_lvalue_warning (code)
enum tree_code code;
{
if (pedantic)
- pedwarn ("ANSI C forbids use of %s expressions as lvalues",
- code == COND_EXPR ? "conditional"
- : code == COMPOUND_EXPR ? "compound" : "cast");
+ pedwarn (code == COND_EXPR
+ ? "ANSI C forbids use of conditional expressions as lvalues"
+ : code == COMPOUND_EXPR
+ ? "ANSI C forbids use of compound expressions as lvalues"
+ : "ANSI C forbids use of cast expressions as lvalues");
}
/* Warn about storing in something that is `const'. */
void
-readonly_warning (arg, string)
+readonly_warning (arg, msgid)
tree arg;
- char *string;
+ const char *msgid;
{
- char buf[80];
- strcpy (buf, string);
-
/* Forbid assignments to iterators. */
if (TREE_CODE (arg) == VAR_DECL && ITERATOR_P (arg))
- {
- strcat (buf, " of iterator `%s'");
- pedwarn (buf, IDENTIFIER_POINTER (DECL_NAME (arg)));
- }
+ pedwarn ("%s of iterator `%s'", _(msgid),
+ IDENTIFIER_POINTER (DECL_NAME (arg)));
if (TREE_CODE (arg) == COMPONENT_REF)
{
if (TYPE_READONLY (TREE_TYPE (TREE_OPERAND (arg, 0))))
- readonly_warning (TREE_OPERAND (arg, 0), string);
+ readonly_warning (TREE_OPERAND (arg, 0), msgid);
else
- {
- strcat (buf, " of read-only member `%s'");
- pedwarn (buf, IDENTIFIER_POINTER (DECL_NAME (TREE_OPERAND (arg, 1))));
- }
+ pedwarn ("%s of read-only member `%s'", _(msgid),
+ IDENTIFIER_POINTER (DECL_NAME (TREE_OPERAND (arg, 1))));
}
else if (TREE_CODE (arg) == VAR_DECL)
- {
- strcat (buf, " of read-only variable `%s'");
- pedwarn (buf, IDENTIFIER_POINTER (DECL_NAME (arg)));
- }
+ pedwarn ("%s of read-only variable `%s'", _(msgid),
+ IDENTIFIER_POINTER (DECL_NAME (arg)));
else
- {
- pedwarn ("%s of read-only location", buf);
- }
+ pedwarn ("%s of read-only location", _(msgid));
}
/* Mark EXP saying that we need to be able to take the
@@ -3726,7 +3724,7 @@ build_c_cast (type, expr)
if (field)
{
- char *name;
+ const char *name;
tree t;
if (pedantic)
@@ -3779,11 +3777,11 @@ build_c_cast (type, expr)
in_type = TREE_TYPE (in_type);
while (TREE_CODE (in_otype) == POINTER_TYPE)
in_otype = TREE_TYPE (in_otype);
-
- if (TYPE_VOLATILE (in_otype) && ! TYPE_VOLATILE (in_type))
- pedwarn ("cast discards `volatile' from pointer target type");
- if (TYPE_READONLY (in_otype) && ! TYPE_READONLY (in_type))
- pedwarn ("cast discards `const' from pointer target type");
+
+ if (TYPE_QUALS (in_otype) & ~TYPE_QUALS (in_type))
+ /* There are qualifiers present in IN_OTYPE that are not
+ present in IN_TYPE. */
+ pedwarn ("cast discards qualifiers from pointer target type");
}
/* Warn about possible alignment problems. */
@@ -3964,7 +3962,7 @@ build_modify_expr (lhs, modifycode, rhs)
/* Now we have handled acceptable kinds of LHS that are not truly lvalues.
Reject anything strange now. */
- if (!lvalue_or_else (lhs, "assignment"))
+ if (!lvalue_or_else (lhs, "invalid lvalue in assignment"))
return error_mark_node;
/* Warn about storing in something that is `const'. */
@@ -3997,7 +3995,7 @@ build_modify_expr (lhs, modifycode, rhs)
/* Convert new value to destination type. */
- newrhs = convert_for_assignment (lhstype, newrhs, "assignment",
+ newrhs = convert_for_assignment (lhstype, newrhs, _("assignment"),
NULL_TREE, NULL_TREE, 0);
if (TREE_CODE (newrhs) == ERROR_MARK)
return error_mark_node;
@@ -4012,7 +4010,7 @@ build_modify_expr (lhs, modifycode, rhs)
if (olhstype == TREE_TYPE (result))
return result;
- return convert_for_assignment (olhstype, result, "assignment",
+ return convert_for_assignment (olhstype, result, _("assignment"),
NULL_TREE, NULL_TREE, 0);
}
@@ -4023,9 +4021,7 @@ build_modify_expr (lhs, modifycode, rhs)
for assignments that are not allowed in C.
ERRTYPE is a string to use in error messages:
"assignment", "return", etc. If it is null, this is parameter passing
- for a function call (and different error messages are output). Otherwise,
- it may be a name stored in the spelling stack and interpreted by
- get_spelling.
+ for a function call (and different error messages are output).
FUNNAME is the name of the function being called,
as an IDENTIFIER_NODE, or null.
@@ -4034,7 +4030,7 @@ build_modify_expr (lhs, modifycode, rhs)
static tree
convert_for_assignment (type, rhs, errtype, fundecl, funname, parmnum)
tree type, rhs;
- char *errtype;
+ const char *errtype;
tree fundecl, funname;
int parmnum;
{
@@ -4114,12 +4110,13 @@ convert_for_assignment (type, rhs, errtype, fundecl, funname, parmnum)
|| comp_target_types (memb_type, rhstype))
{
/* If this type won't generate any warnings, use it. */
- if ((TREE_CODE (ttr) == FUNCTION_TYPE
- && TREE_CODE (ttl) == FUNCTION_TYPE)
- ? ((! TYPE_READONLY (ttl) | TYPE_READONLY (ttr))
- & (! TYPE_VOLATILE (ttl) | TYPE_VOLATILE (ttr)))
- : ((TYPE_READONLY (ttl) | ! TYPE_READONLY (ttr))
- & (TYPE_VOLATILE (ttl) | ! TYPE_VOLATILE (ttr))))
+ if (TYPE_QUALS (ttl) == TYPE_QUALS (ttr)
+ || ((TREE_CODE (ttr) == FUNCTION_TYPE
+ && TREE_CODE (ttl) == FUNCTION_TYPE)
+ ? ((TYPE_QUALS (ttl) | TYPE_QUALS (ttr))
+ == TYPE_QUALS (ttr))
+ : ((TYPE_QUALS (ttl) | TYPE_QUALS (ttr))
+ == TYPE_QUALS (ttl))))
break;
/* Keep looking for a better type, but remember this one. */
@@ -4157,26 +4154,14 @@ convert_for_assignment (type, rhs, errtype, fundecl, funname, parmnum)
certain things, it is okay to use a const or volatile
function where an ordinary one is wanted, but not
vice-versa. */
- if (TYPE_READONLY (ttl) && ! TYPE_READONLY (ttr))
- warn_for_assignment ("%s makes `const *' function pointer from non-const",
- get_spelling (errtype), funname,
- parmnum);
- if (TYPE_VOLATILE (ttl) && ! TYPE_VOLATILE (ttr))
- warn_for_assignment ("%s makes `volatile *' function pointer from non-volatile",
- get_spelling (errtype), funname,
- parmnum);
- }
- else
- {
- if (! TYPE_READONLY (ttl) && TYPE_READONLY (ttr))
- warn_for_assignment ("%s discards `const' from pointer target type",
- get_spelling (errtype), funname,
- parmnum);
- if (! TYPE_VOLATILE (ttl) && TYPE_VOLATILE (ttr))
- warn_for_assignment ("%s discards `volatile' from pointer target type",
- get_spelling (errtype), funname,
- parmnum);
+ if (TYPE_QUALS (ttl) & ~TYPE_QUALS (ttr))
+ warn_for_assignment ("%s makes qualified function pointer from unqualified",
+ errtype, funname, parmnum);
}
+ else if (TYPE_QUALS (ttr) & ~TYPE_QUALS (ttl))
+ warn_for_assignment ("%s discards qualifiers from pointer target type",
+ errtype, funname,
+ parmnum);
}
if (pedantic && ! DECL_IN_SYSTEM_HEADER (fundecl))
@@ -4211,18 +4196,15 @@ convert_for_assignment (type, rhs, errtype, fundecl, funname, parmnum)
&& (!integer_zerop (rhs) || TREE_CODE (rhs) == NOP_EXPR)
&& TREE_CODE (ttl) == FUNCTION_TYPE)))
warn_for_assignment ("ANSI forbids %s between function pointer and `void *'",
- get_spelling (errtype), funname, parmnum);
+ errtype, funname, parmnum);
/* Const and volatile mean something different for function types,
so the usual warnings are not appropriate. */
else if (TREE_CODE (ttr) != FUNCTION_TYPE
&& TREE_CODE (ttl) != FUNCTION_TYPE)
{
- if (! TYPE_READONLY (ttl) && TYPE_READONLY (ttr))
- warn_for_assignment ("%s discards `const' from pointer target type",
- get_spelling (errtype), funname, parmnum);
- else if (! TYPE_VOLATILE (ttl) && TYPE_VOLATILE (ttr))
- warn_for_assignment ("%s discards `volatile' from pointer target type",
- get_spelling (errtype), funname, parmnum);
+ if (TYPE_QUALS (ttr) & ~TYPE_QUALS (ttl))
+ warn_for_assignment ("%s discards qualifiers from pointer target type",
+ errtype, funname, parmnum);
/* If this is not a case of ignoring a mismatch in signedness,
no warning. */
else if (TYPE_MAIN_VARIANT (ttl) == void_type_node
@@ -4232,7 +4214,7 @@ convert_for_assignment (type, rhs, errtype, fundecl, funname, parmnum)
/* If there is a mismatch, do warn. */
else if (pedantic)
warn_for_assignment ("pointer targets in %s differ in signedness",
- get_spelling (errtype), funname, parmnum);
+ errtype, funname, parmnum);
}
else if (TREE_CODE (ttl) == FUNCTION_TYPE
&& TREE_CODE (ttr) == FUNCTION_TYPE)
@@ -4241,17 +4223,14 @@ convert_for_assignment (type, rhs, errtype, fundecl, funname, parmnum)
that say the function will not do certain things,
it is okay to use a const or volatile function
where an ordinary one is wanted, but not vice-versa. */
- if (TYPE_READONLY (ttl) && ! TYPE_READONLY (ttr))
- warn_for_assignment ("%s makes `const *' function pointer from non-const",
- get_spelling (errtype), funname, parmnum);
- if (TYPE_VOLATILE (ttl) && ! TYPE_VOLATILE (ttr))
- warn_for_assignment ("%s makes `volatile *' function pointer from non-volatile",
- get_spelling (errtype), funname, parmnum);
+ if (TYPE_QUALS (ttl) & ~TYPE_QUALS (ttr))
+ warn_for_assignment ("%s makes qualified function pointer from unqualified",
+ errtype, funname, parmnum);
}
}
else
warn_for_assignment ("%s from incompatible pointer type",
- get_spelling (errtype), funname, parmnum);
+ errtype, funname, parmnum);
return convert (type, rhs);
}
else if (codel == POINTER_TYPE && coder == INTEGER_TYPE)
@@ -4267,7 +4246,7 @@ convert_for_assignment (type, rhs, errtype, fundecl, funname, parmnum)
&& integer_zerop (TREE_OPERAND (rhs, 0))))
{
warn_for_assignment ("%s makes pointer from integer without a cast",
- get_spelling (errtype), funname, parmnum);
+ errtype, funname, parmnum);
return convert (type, rhs);
}
return null_pointer_node;
@@ -4275,7 +4254,7 @@ convert_for_assignment (type, rhs, errtype, fundecl, funname, parmnum)
else if (codel == INTEGER_TYPE && coder == POINTER_TYPE)
{
warn_for_assignment ("%s makes integer from pointer without a cast",
- get_spelling (errtype), funname, parmnum);
+ errtype, funname, parmnum);
return convert (type, rhs);
}
@@ -4297,30 +4276,28 @@ convert_for_assignment (type, rhs, errtype, fundecl, funname, parmnum)
parmnum);
}
else
- error ("incompatible types in %s", get_spelling (errtype));
+ error ("incompatible types in %s", errtype);
return error_mark_node;
}
-/* Print a warning using MSG.
+/* Print a warning using MSGID.
It gets OPNAME as its one parameter.
If OPNAME is null, it is replaced by "passing arg ARGNUM of `FUNCTION'".
FUNCTION and ARGNUM are handled specially if we are building an
Objective-C selector. */
static void
-warn_for_assignment (msg, opname, function, argnum)
- char *msg;
- char *opname;
+warn_for_assignment (msgid, opname, function, argnum)
+ const char *msgid;
+ const char *opname;
tree function;
int argnum;
{
- static char argstring[] = "passing arg %d of `%s'";
- static char argnofun[] = "passing arg %d";
-
if (opname == 0)
{
tree selector = maybe_building_objc_message_expr ();
+ char * new_opname;
if (selector && argnum > 2)
{
@@ -4330,18 +4307,23 @@ warn_for_assignment (msg, opname, function, argnum)
if (function)
{
/* Function name is known; supply it. */
- opname = (char *) alloca (IDENTIFIER_LENGTH (function)
- + sizeof (argstring) + 25 /*%d*/ + 1);
- sprintf (opname, argstring, argnum, IDENTIFIER_POINTER (function));
+ const char *argstring = _("passing arg %d of `%s'");
+ new_opname = (char *) alloca (IDENTIFIER_LENGTH (function)
+ + strlen (argstring) + 1 + 25
+ /*%d*/ + 1);
+ sprintf (new_opname, argstring, argnum,
+ IDENTIFIER_POINTER (function));
}
else
{
- /* Function name unknown (call through ptr); just give arg number. */
- opname = (char *) alloca (sizeof (argnofun) + 25 /*%d*/ + 1);
- sprintf (opname, argnofun, argnum);
+ /* Function name unknown (call through ptr); just give arg number.*/
+ const char *argnofun = _("passing arg %d of pointer to function");
+ new_opname = (char *) alloca (strlen (argnofun) + 1 + 25 /*%d*/ + 1);
+ sprintf (new_opname, argnofun, argnum);
}
+ opname = new_opname;
}
- pedwarn (msg, opname);
+ pedwarn (msgid, opname);
}
/* Return nonzero if VALUE is a valid constant-valued expression
@@ -4580,7 +4562,7 @@ struct spelling
union
{
int i;
- char *s;
+ const char *s;
} u;
};
@@ -4631,7 +4613,7 @@ static int spelling_size; /* Size of the spelling stack. */
static void
push_string (string)
- char *string;
+ const char *string;
{
PUSH_SPELLING (SPELLING_STRING, string, u.s);
}
@@ -4643,7 +4625,7 @@ push_member_name (decl)
tree decl;
{
- char *string
+ const char *string
= DECL_NAME (decl) ? IDENTIFIER_POINTER (DECL_NAME (decl)) : "<anonymous>";
PUSH_SPELLING (SPELLING_MEMBER, string, u.s);
}
@@ -4683,7 +4665,6 @@ print_spelling (buffer)
register char *buffer;
{
register char *d = buffer;
- register char *s;
register struct spelling *p;
for (p = spelling_base; p < spelling; p++)
@@ -4694,6 +4675,7 @@ print_spelling (buffer)
}
else
{
+ register const char *s;
if (p->kind == SPELLING_MEMBER)
*d++ = '.';
for (s = p->u.s; (*d = *s++); d++)
@@ -4703,113 +4685,52 @@ print_spelling (buffer)
return buffer;
}
-/* Provide a means to pass component names derived from the spelling stack. */
-
-char initialization_message;
-
-/* Interpret the spelling of the given ERRTYPE message. */
-
-static char *
-get_spelling (errtype)
- char *errtype;
-{
- static char *buffer;
- static int size;
-
- if (errtype == &initialization_message)
- {
- /* Avoid counting chars */
- static char message[] = "initialization of `%s'";
- register int needed = sizeof (message) + spelling_length () + 1;
- char *temp;
-
- if (needed > size)
- buffer = (char *) xrealloc (buffer, size = needed);
-
- temp = (char *) alloca (needed);
- sprintf (buffer, message, print_spelling (temp));
- return buffer;
- }
-
- return errtype;
-}
-
/* Issue an error message for a bad initializer component.
- FORMAT describes the message. OFWHAT is the name for the component.
- LOCAL is a format string for formatting the insertion of the name
- into the message.
-
- If OFWHAT is null, the component name is stored on the spelling stack.
- If the component name is a null string, then LOCAL is omitted entirely. */
+ MSGID identifies the message.
+ The component name is taken from the spelling stack. */
void
-error_init (format, local, ofwhat)
- char *format, *local, *ofwhat;
+error_init (msgid)
+ const char *msgid;
{
- char *buffer;
-
- if (ofwhat == 0)
- ofwhat = print_spelling ((char *) alloca (spelling_length () + 1));
- buffer = (char *) alloca (strlen (local) + strlen (ofwhat) + 2);
+ char *ofwhat;
+ error (msgid);
+ ofwhat = print_spelling ((char *) alloca (spelling_length () + 1));
if (*ofwhat)
- sprintf (buffer, local, ofwhat);
- else
- buffer[0] = 0;
-
- error (format, buffer);
+ error ("(near initialization for `%s')", ofwhat);
}
/* Issue a pedantic warning for a bad initializer component.
- FORMAT describes the message. OFWHAT is the name for the component.
- LOCAL is a format string for formatting the insertion of the name
- into the message.
-
- If OFWHAT is null, the component name is stored on the spelling stack.
- If the component name is a null string, then LOCAL is omitted entirely. */
+ MSGID identifies the message.
+ The component name is taken from the spelling stack. */
void
-pedwarn_init (format, local, ofwhat)
- char *format, *local, *ofwhat;
+pedwarn_init (msgid)
+ const char *msgid;
{
- char *buffer;
-
- if (ofwhat == 0)
- ofwhat = print_spelling ((char *) alloca (spelling_length () + 1));
- buffer = (char *) alloca (strlen (local) + strlen (ofwhat) + 2);
+ char *ofwhat;
+ pedwarn (msgid);
+ ofwhat = print_spelling ((char *) alloca (spelling_length () + 1));
if (*ofwhat)
- sprintf (buffer, local, ofwhat);
- else
- buffer[0] = 0;
-
- pedwarn (format, buffer);
+ pedwarn ("(near initialization for `%s')", ofwhat);
}
/* Issue a warning for a bad initializer component.
- FORMAT describes the message. OFWHAT is the name for the component.
- LOCAL is a format string for formatting the insertion of the name
- into the message.
-
- If OFWHAT is null, the component name is stored on the spelling stack.
- If the component name is a null string, then LOCAL is omitted entirely. */
+ MSGID identifies the message.
+ The component name is taken from the spelling stack. */
static void
-warning_init (format, local, ofwhat)
- char *format, *local, *ofwhat;
+warning_init (msgid)
+ const char *msgid;
{
- char *buffer;
-
- if (ofwhat == 0)
- ofwhat = print_spelling ((char *) alloca (spelling_length () + 1));
- buffer = (char *) alloca (strlen (local) + strlen (ofwhat) + 2);
+ char *ofwhat;
+ warning (msgid);
+ ofwhat = print_spelling ((char *) alloca (spelling_length () + 1));
if (*ofwhat)
- sprintf (buffer, local, ofwhat);
- else
- buffer[0] = 0;
-
- warning (format, buffer);
+ warning ("(near initialization for `%s')", ofwhat);
}
/* Digest the parser output INIT as an initializer for type TYPE.
@@ -4857,16 +4778,14 @@ digest_init (type, init, require_constant, constructor_constant)
!= char_type_node)
&& TYPE_PRECISION (typ1) == TYPE_PRECISION (char_type_node))
{
- error_init ("char-array%s initialized from wide string",
- " `%s'", NULL);
+ error_init ("char-array initialized from wide string");
return error_mark_node;
}
if ((TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (inside_init)))
== char_type_node)
&& TYPE_PRECISION (typ1) != TYPE_PRECISION (char_type_node))
{
- error_init ("int-array%s initialized from non-wide string",
- " `%s'", NULL);
+ error_init ("int-array initialized from non-wide string");
return error_mark_node;
}
@@ -4883,9 +4802,7 @@ digest_init (type, init, require_constant, constructor_constant)
- (TYPE_PRECISION (typ1) != TYPE_PRECISION (char_type_node)
? TYPE_PRECISION (wchar_type_node) / BITS_PER_UNIT
: 1))
- pedwarn_init (
- "initializer-string for array of chars%s is too long",
- " `%s'", NULL);
+ pedwarn_init ("initializer-string for array of chars is too long");
}
return inside_init;
}
@@ -4912,8 +4829,7 @@ digest_init (type, init, require_constant, constructor_constant)
else if (code == ARRAY_TYPE && TREE_CODE (inside_init) != STRING_CST
&& TREE_CODE (inside_init) != CONSTRUCTOR)
{
- error_init ("array%s initialized from non-constant array expression",
- " `%s'", NULL);
+ error_init ("array initialized from non-constant array expression");
return error_mark_node;
}
@@ -4930,25 +4846,21 @@ digest_init (type, init, require_constant, constructor_constant)
= valid_compound_expr_initializer (inside_init,
TREE_TYPE (inside_init));
if (inside_init == error_mark_node)
- error_init ("initializer element%s is not constant",
- " for `%s'", NULL);
+ error_init ("initializer element is not constant");
else
- pedwarn_init ("initializer element%s is not constant",
- " for `%s'", NULL);
+ pedwarn_init ("initializer element is not constant");
if (flag_pedantic_errors)
inside_init = error_mark_node;
}
else if (require_constant && ! TREE_CONSTANT (inside_init))
{
- error_init ("initializer element%s is not constant",
- " for `%s'", NULL);
+ error_init ("initializer element is not constant");
inside_init = error_mark_node;
}
else if (require_constant
&& initializer_constant_valid_p (inside_init, TREE_TYPE (inside_init)) == 0)
{
- error_init ("initializer element%s is not computable at load time",
- " for `%s'", NULL);
+ error_init ("initializer element is not computable at load time");
inside_init = error_mark_node;
}
@@ -4964,20 +4876,18 @@ digest_init (type, init, require_constant, constructor_constant)
for arrays and functions. We must not call it in the
case where inside_init is a null pointer constant. */
inside_init
- = convert_for_assignment (type, init, "initialization",
+ = convert_for_assignment (type, init, _("initialization"),
NULL_TREE, NULL_TREE, 0);
if (require_constant && ! TREE_CONSTANT (inside_init))
{
- error_init ("initializer element%s is not constant",
- " for `%s'", NULL);
+ error_init ("initializer element is not constant");
inside_init = error_mark_node;
}
else if (require_constant
&& initializer_constant_valid_p (inside_init, TREE_TYPE (inside_init)) == 0)
{
- error_init ("initializer element%s is not computable at load time",
- " for `%s'", NULL);
+ error_init ("initializer element is not computable at load time");
inside_init = error_mark_node;
}
@@ -4988,8 +4898,7 @@ digest_init (type, init, require_constant, constructor_constant)
if (TYPE_SIZE (type) && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
{
- error_init ("variable-sized object%s may not be initialized",
- " `%s'", NULL);
+ error_init ("variable-sized object may not be initialized");
return error_mark_node;
}
@@ -5015,7 +4924,7 @@ digest_init (type, init, require_constant, constructor_constant)
type = TREE_TYPE (TYPE_FIELDS (type));
else
{
- error_init ("invalid initializer%s", " for `%s'", NULL);
+ error_init ("invalid initializer");
return error_mark_node;
}
}
@@ -5031,7 +4940,7 @@ digest_init (type, init, require_constant, constructor_constant)
else
return error_mark_node;
}
- error_init ("invalid initializer%s", " for `%s'", NULL);
+ error_init ("invalid initializer");
return error_mark_node;
}
@@ -5194,7 +5103,7 @@ start_init (decl, asmspec_tree, top_level)
tree asmspec_tree;
int top_level;
{
- char *locus;
+ const char *locus;
struct initializer_stack *p
= (struct initializer_stack *) xmalloc (sizeof (struct initializer_stack));
char *asmspec = 0;
@@ -5508,8 +5417,7 @@ push_init_level (implicit)
if (constructor_type == 0)
{
- error_init ("extra brace group at end of initializer%s",
- " for `%s'", NULL);
+ error_init ("extra brace group at end of initializer");
constructor_fields = 0;
constructor_unfilled_fields = 0;
return;
@@ -5521,7 +5429,7 @@ push_init_level (implicit)
if (implicit && warn_missing_braces && !missing_braces_mentioned)
{
missing_braces_mentioned = 1;
- warning_init ("missing braces around initializer%s", " for `%s'", NULL);
+ warning_init ("missing braces around initializer");
}
if (TREE_CODE (constructor_type) == RECORD_TYPE
@@ -5552,7 +5460,7 @@ push_init_level (implicit)
}
else
{
- warning_init ("braces around scalar initializer%s", " for `%s'", NULL);
+ warning_init ("braces around scalar initializer");
constructor_fields = constructor_type;
constructor_unfilled_fields = constructor_type;
}
@@ -5572,9 +5480,7 @@ check_init_type_bitfields (type)
for (tail = TYPE_FIELDS (type); tail;
tail = TREE_CHAIN (tail))
{
- if (DECL_C_BIT_FIELD (tail)
- /* This catches cases like `int foo : 8;'. */
- || DECL_MODE (tail) != TYPE_MODE (TREE_TYPE (tail)))
+ if (DECL_C_BIT_FIELD (tail))
{
constructor_incremental = 0;
break;
@@ -5584,6 +5490,17 @@ check_init_type_bitfields (type)
}
}
+ else if (TREE_CODE (type) == UNION_TYPE)
+ {
+ tree tail = TYPE_FIELDS (type);
+ if (tail && DECL_C_BIT_FIELD (tail))
+ /* We also use the nonincremental algorithm for initiliazation
+ of unions whose first member is a bitfield, becuase the
+ incremental algorithm has no code for dealing with
+ bitfields. */
+ constructor_incremental = 0;
+ }
+
else if (TREE_CODE (type) == ARRAY_TYPE)
check_init_type_bitfields (TREE_TYPE (type));
}
@@ -5624,7 +5541,7 @@ pop_init_level (implicit)
&& constructor_unfilled_fields)
{
push_member_name (constructor_unfilled_fields);
- warning_init ("missing initializer%s", " for `%s'", NULL);
+ warning_init ("missing initializer");
RESTORE_SPELLING_DEPTH (constructor_depth);
}
@@ -5637,7 +5554,7 @@ pop_init_level (implicit)
&& (TREE_CODE (constructor_type) == ARRAY_TYPE
? integer_zerop (constructor_unfilled_index)
: constructor_unfilled_fields == TYPE_FIELDS (constructor_type)))
- pedwarn_init ("empty braces in initializer%s", " for `%s'", NULL);
+ pedwarn_init ("empty braces in initializer");
#endif
/* Pad out the end of the structure. */
@@ -5701,14 +5618,12 @@ pop_init_level (implicit)
the element, after verifying there is just one. */
if (constructor_elements == 0)
{
- error_init ("empty scalar initializer%s",
- " for `%s'", NULL);
+ error_init ("empty scalar initializer");
constructor = error_mark_node;
}
else if (TREE_CHAIN (constructor_elements) != 0)
{
- error_init ("extra elements in scalar initializer%s",
- " for `%s'", NULL);
+ error_init ("extra elements in scalar initializer");
constructor = TREE_VALUE (constructor_elements);
}
else
@@ -5842,20 +5757,20 @@ set_init_index (first, last)
(last) = TREE_OPERAND (last, 0);
if (TREE_CODE (first) != INTEGER_CST)
- error_init ("nonconstant array index in initializer%s", " for `%s'", NULL);
+ error_init ("nonconstant array index in initializer");
else if (last != 0 && TREE_CODE (last) != INTEGER_CST)
- error_init ("nonconstant array index in initializer%s", " for `%s'", NULL);
+ error_init ("nonconstant array index in initializer");
else if (! constructor_unfilled_index)
- error_init ("array index in non-array initializer%s", " for `%s'", NULL);
+ error_init ("array index in non-array initializer");
else if (tree_int_cst_lt (first, constructor_unfilled_index))
- error_init ("duplicate array index in initializer%s", " for `%s'", NULL);
+ error_init ("duplicate array index in initializer");
else
{
TREE_INT_CST_LOW (constructor_index) = TREE_INT_CST_LOW (first);
TREE_INT_CST_HIGH (constructor_index) = TREE_INT_CST_HIGH (first);
if (last != 0 && tree_int_cst_lt (last, first))
- error_init ("empty index range in initializer%s", " for `%s'", NULL);
+ error_init ("empty index range in initializer");
else
{
if (pedantic)
@@ -6186,15 +6101,13 @@ output_init_element (value, type, field, pending)
if (require_constant_value && ! TREE_CONSTANT (value))
{
- error_init ("initializer element%s is not constant",
- " for `%s'", NULL);
+ error_init ("initializer element is not constant");
value = error_mark_node;
}
else if (require_constant_elements
&& initializer_constant_valid_p (value, TREE_TYPE (value)) == 0)
{
- error_init ("initializer element%s is not computable at load time",
- " for `%s'", NULL);
+ error_init ("initializer element is not computable at load time");
value = error_mark_node;
}
@@ -6210,7 +6123,7 @@ output_init_element (value, type, field, pending)
{
if (pending_init_member (field))
{
- error_init ("duplicate initializer%s", " for `%s'", NULL);
+ error_init ("duplicate initializer");
duplicate = 1;
}
}
@@ -6563,8 +6476,7 @@ process_init_element (value)
if (constructor_stack->replacement_value != 0)
{
- error_init ("excess elements in struct initializer%s",
- " after `%s'", NULL_PTR);
+ error_init ("excess elements in struct initializer");
return;
}
@@ -6599,8 +6511,7 @@ process_init_element (value)
if (constructor_fields == 0)
{
- pedwarn_init ("excess elements in struct initializer%s",
- " after `%s'", NULL_PTR);
+ pedwarn_init ("excess elements in struct initializer");
break;
}
@@ -6664,8 +6575,7 @@ process_init_element (value)
if (constructor_fields == 0)
{
- pedwarn_init ("excess elements in union initializer%s",
- " after `%s'", NULL_PTR);
+ pedwarn_init ("excess elements in union initializer");
break;
}
@@ -6739,8 +6649,7 @@ process_init_element (value)
if (constructor_max_index != 0
&& tree_int_cst_lt (constructor_max_index, constructor_index))
{
- pedwarn_init ("excess elements in array initializer%s",
- " after `%s'", NULL_PTR);
+ pedwarn_init ("excess elements in array initializer");
break;
}
@@ -6751,8 +6660,7 @@ process_init_element (value)
&& tree_int_cst_lt (constructor_max_index,
constructor_range_end))
{
- pedwarn_init ("excess elements in array initializer%s",
- " after `%s'", NULL_PTR);
+ pedwarn_init ("excess elements in array initializer");
TREE_INT_CST_HIGH (constructor_range_end)
= TREE_INT_CST_HIGH (constructor_max_index);
TREE_INT_CST_LOW (constructor_range_end)
@@ -6803,8 +6711,7 @@ process_init_element (value)
for a scalar variable. */
if (constructor_fields == 0)
{
- pedwarn_init ("excess elements in scalar initializer%s",
- " after `%s'", NULL_PTR);
+ pedwarn_init ("excess elements in scalar initializer");
break;
}
@@ -6921,7 +6828,7 @@ c_expand_return (retval)
}
else
{
- tree t = convert_for_assignment (valtype, retval, "return",
+ tree t = convert_for_assignment (valtype, retval, _("return"),
NULL_TREE, NULL_TREE, 0);
tree res = DECL_RESULT (current_function_decl);
tree inner;
diff --git a/gcc/caller-save.c b/gcc/caller-save.c
index 086cdfc0a49..1b7202ce8d0 100644
--- a/gcc/caller-save.c
+++ b/gcc/caller-save.c
@@ -1,5 +1,5 @@
/* Save and restore call-clobbered registers which are live across a call.
- Copyright (C) 1989, 1992, 94-95, 1997, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1989, 1992, 94-95, 97, 98, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -40,6 +40,8 @@ Boston, MA 02111-1307, USA. */
#define MIN_UNITS_PER_WORD UNITS_PER_WORD
#endif
+#define MOVE_MAX_WORDS (MOVE_MAX / UNITS_PER_WORD)
+
/* Modes for each hard register that we can save. The smallest mode is wide
enough to save the entire contents of the register. When saving the
register because it is live we first try to save in multi-register modes.
@@ -65,29 +67,31 @@ static enum insn_code
static enum insn_code
reg_restore_code[FIRST_PSEUDO_REGISTER][MAX_MOVE_MAX / MIN_UNITS_PER_WORD + 1];
-/* Set of hard regs currently live (during scan of all insns). */
-
-static HARD_REG_SET hard_regs_live;
-
/* Set of hard regs currently residing in save area (during insn scan). */
static HARD_REG_SET hard_regs_saved;
-/* Set of hard regs which need to be restored before referenced. */
+/* Number of registers currently in hard_regs_saved. */
-static HARD_REG_SET hard_regs_need_restore;
+static int n_regs_saved;
-/* Number of registers currently in hard_regs_saved. */
+/* Computed by mark_referenced_regs, all regs referenced in a given
+ insn. */
+static HARD_REG_SET referenced_regs;
-int n_regs_saved;
+/* Computed in mark_set_regs, holds all registers set by the current
+ instruction. */
+static HARD_REG_SET this_insn_sets;
-static void set_reg_live PROTO((rtx, rtx));
-static void clear_reg_live PROTO((rtx));
-static void restore_referenced_regs PROTO((rtx, rtx, int));
-static int insert_restore PROTO((rtx, int, int, int, int));
-static int insert_save PROTO((rtx, int, int, int));
-static void insert_one_insn PROTO((rtx, int, enum rtx_code,
- rtx, int));
+
+static void mark_set_regs PROTO((rtx, rtx));
+static void mark_referenced_regs PROTO((rtx));
+static int insert_save PROTO((struct insn_chain *, int, int,
+ HARD_REG_SET *));
+static int insert_restore PROTO((struct insn_chain *, int, int,
+ int));
+static void insert_one_insn PROTO((struct insn_chain *, int,
+ enum insn_code, rtx));
/* Initialize for caller-save.
@@ -116,7 +120,7 @@ init_caller_save ()
{
if (call_used_regs[i] && ! call_fixed_regs[i])
{
- for (j = 1; j <= MOVE_MAX / UNITS_PER_WORD; j++)
+ for (j = 1; j <= MOVE_MAX_WORDS; j++)
{
regno_save_mode[i][j] = HARD_REGNO_CALLER_SAVE_MODE (i, j);
if (regno_save_mode[i][j] == VOIDmode && j == 1)
@@ -173,7 +177,7 @@ init_caller_save ()
start_sequence ();
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
- for (j = 1; j <= MOVE_MAX / UNITS_PER_WORD; j++)
+ for (j = 1; j <= MOVE_MAX_WORDS; j++)
if (regno_save_mode[i][j] != VOIDmode)
{
rtx mem = gen_rtx_MEM (regno_save_mode[i][j], address);
@@ -189,13 +193,14 @@ init_caller_save ()
/* Now extract both insns and see if we can meet their
constraints. */
- ok = (reg_save_code[i][j] != -1 && reg_restore_code[i][j] != -1);
+ ok = (reg_save_code[i][j] != (enum insn_code)-1
+ && reg_restore_code[i][j] != (enum insn_code)-1);
if (ok)
{
- insn_extract (saveinsn);
- ok = constrain_operands (reg_save_code[i][j], 1);
- insn_extract (restinsn);
- ok &= constrain_operands (reg_restore_code[i][j], 1);
+ extract_insn (saveinsn);
+ ok = constrain_operands (1);
+ extract_insn (restinsn);
+ ok &= constrain_operands (1);
}
if (! ok)
@@ -222,7 +227,7 @@ init_save_areas ()
int i, j;
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
- for (j = 1; j <= MOVE_MAX / UNITS_PER_WORD; j++)
+ for (j = 1; j <= MOVE_MAX_WORDS; j++)
regno_save_mem[i][j] = 0;
}
@@ -276,10 +281,9 @@ setup_save_areas ()
in a manner which allows multi-register saves/restores to be done. */
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
- for (j = MOVE_MAX / UNITS_PER_WORD; j > 0; j--)
+ for (j = MOVE_MAX_WORDS; j > 0; j--)
{
- int ok = 1;
- int do_save;
+ int do_save = 1;
/* If no mode exists for this size, try another. Also break out
if we have already saved this hard register. */
@@ -287,7 +291,6 @@ setup_save_areas ()
continue;
/* See if any register in this group has been saved. */
- do_save = 1;
for (k = 0; k < j; k++)
if (regno_save_mem[i + k][1])
{
@@ -298,189 +301,171 @@ setup_save_areas ()
continue;
for (k = 0; k < j; k++)
+ if (! TEST_HARD_REG_BIT (hard_regs_used, i + k))
{
- int regno = i + k;
- ok &= (TEST_HARD_REG_BIT (hard_regs_used, regno) != 0);
+ do_save = 0;
+ break;
}
+ if (! do_save)
+ continue;
/* We have found an acceptable mode to store in. */
- if (ok)
+ regno_save_mem[i][j]
+ = assign_stack_local (regno_save_mode[i][j],
+ GET_MODE_SIZE (regno_save_mode[i][j]), 0);
+
+ /* Setup single word save area just in case... */
+ for (k = 0; k < j; k++)
{
+ /* This should not depend on WORDS_BIG_ENDIAN.
+ The order of words in regs is the same as in memory. */
+ rtx temp = gen_rtx_MEM (regno_save_mode[i+k][1],
+ XEXP (regno_save_mem[i][j], 0));
- regno_save_mem[i][j]
- = assign_stack_local (regno_save_mode[i][j],
- GET_MODE_SIZE (regno_save_mode[i][j]), 0);
-
- /* Setup single word save area just in case... */
- for (k = 0; k < j; k++)
- {
- /* This should not depend on WORDS_BIG_ENDIAN.
- The order of words in regs is the same as in memory. */
- rtx temp = gen_rtx_MEM (regno_save_mode[i+k][1],
- XEXP (regno_save_mem[i][j], 0));
-
- regno_save_mem[i+k][1]
- = adj_offsettable_operand (temp, k * UNITS_PER_WORD);
- }
+ regno_save_mem[i+k][1]
+ = adj_offsettable_operand (temp, k * UNITS_PER_WORD);
}
}
-
- return;
}
/* Find the places where hard regs are live across calls and save them. */
-
void
save_call_clobbered_regs ()
{
- rtx insn;
- int b;
+ struct insn_chain *chain, *next;
+
+ CLEAR_HARD_REG_SET (hard_regs_saved);
+ n_regs_saved = 0;
- for (b = 0; b < n_basic_blocks; b++)
+ for (chain = reload_insn_chain; chain != 0; chain = next)
{
- regset regs_live = basic_block_live_at_start[b];
- int i, j;
- int regno;
-
- /* Compute hard regs live at start of block -- this is the
- real hard regs marked live, plus live pseudo regs that
- have been renumbered to hard regs. No registers have yet been
- saved because we restore all of them before the end of the basic
- block. */
-
- REG_SET_TO_HARD_REG_SET (hard_regs_live, regs_live);
- CLEAR_HARD_REG_SET (hard_regs_saved);
- CLEAR_HARD_REG_SET (hard_regs_need_restore);
- n_regs_saved = 0;
-
- EXECUTE_IF_SET_IN_REG_SET (regs_live, 0, i,
- {
- if ((regno = reg_renumber[i]) >= 0)
- for (j = regno;
- j < regno + HARD_REGNO_NREGS (regno,
- PSEUDO_REGNO_MODE (i));
- j++)
- SET_HARD_REG_BIT (hard_regs_live, j);
- });
-
- /* Now scan the insns in the block, keeping track of what hard
- regs are live as we go. When we see a call, save the live
- call-clobbered hard regs. */
-
- for (insn = basic_block_head[b]; ; insn = NEXT_INSN (insn))
+ rtx insn = chain->insn;
+ enum rtx_code code = GET_CODE (insn);
+
+ next = chain->next;
+
+ if (chain->is_caller_save_insn)
+ abort ();
+
+ if (GET_RTX_CLASS (code) == 'i')
{
- RTX_CODE code = GET_CODE (insn);
+ /* If some registers have been saved, see if INSN references
+ any of them. We must restore them before the insn if so. */
- if (GET_RTX_CLASS (code) == 'i')
+ if (n_regs_saved)
{
- rtx link;
-
- /* If some registers have been saved, see if INSN references
- any of them. We must restore them before the insn if so. */
-
- if (n_regs_saved)
- restore_referenced_regs (PATTERN (insn), insn, b);
-
- /* NB: the normal procedure is to first enliven any
- registers set by insn, then deaden any registers that
- had their last use at insn. This is incorrect now,
- since multiple pseudos may have been mapped to the
- same hard reg, and the death notes are ambiguous. So
- it must be done in the other, safe, order. */
-
- for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
- if (REG_NOTE_KIND (link) == REG_DEAD)
- clear_reg_live (XEXP (link, 0));
-
- /* When we reach a call, we need to save all registers that are
- live, call-used, not fixed, and not already saved. We must
- test at this point because registers that die in a CALL_INSN
- are not live across the call and likewise for registers that
- are born in the CALL_INSN.
-
- If registers are filled with parameters for this function,
- and some of these are also being set by this function, then
- they will not appear to die (no REG_DEAD note for them),
- to check if in fact they do, collect the set registers in
- hard_regs_live first. */
-
- if (code == CALL_INSN)
- {
- HARD_REG_SET this_call_sets;
- {
- HARD_REG_SET old_hard_regs_live;
-
- /* Save the hard_regs_live information. */
- COPY_HARD_REG_SET (old_hard_regs_live, hard_regs_live);
-
- /* Now calculate hard_regs_live for this CALL_INSN
- only. */
- CLEAR_HARD_REG_SET (hard_regs_live);
- note_stores (PATTERN (insn), set_reg_live);
- COPY_HARD_REG_SET (this_call_sets, hard_regs_live);
-
- /* Restore the hard_regs_live information. */
- COPY_HARD_REG_SET (hard_regs_live, old_hard_regs_live);
- }
-
- for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
- if (call_used_regs[regno] && ! call_fixed_regs[regno]
- && TEST_HARD_REG_BIT (hard_regs_live, regno)
- /* It must not be set by this instruction. */
- && ! TEST_HARD_REG_BIT (this_call_sets, regno)
- && ! TEST_HARD_REG_BIT (hard_regs_saved, regno))
- regno += insert_save (insn, 1, regno, b);
-
- /* Put the information for this CALL_INSN on top of what
- we already had. */
- IOR_HARD_REG_SET (hard_regs_live, this_call_sets);
- COPY_HARD_REG_SET (hard_regs_need_restore, hard_regs_saved);
-
- /* Must recompute n_regs_saved. */
- n_regs_saved = 0;
- for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
- if (TEST_HARD_REG_BIT (hard_regs_saved, regno))
- n_regs_saved++;
- }
+ int regno;
+
+ if (code == JUMP_INSN)
+ /* Restore all registers if this is a JUMP_INSN. */
+ COPY_HARD_REG_SET (referenced_regs, hard_regs_saved);
else
{
- note_stores (PATTERN (insn), set_reg_live);
-#ifdef AUTO_INC_DEC
- for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
- if (REG_NOTE_KIND (link) == REG_INC)
- set_reg_live (XEXP (link, 0), NULL_RTX);
-#endif
+ CLEAR_HARD_REG_SET (referenced_regs);
+ mark_referenced_regs (PATTERN (insn));
+ AND_HARD_REG_SET (referenced_regs, hard_regs_saved);
}
- for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
- if (REG_NOTE_KIND (link) == REG_UNUSED)
- clear_reg_live (XEXP (link, 0));
+ for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
+ if (TEST_HARD_REG_BIT (referenced_regs, regno))
+ regno += insert_restore (chain, 1, regno, MOVE_MAX_WORDS);
}
- if (insn == basic_block_end[b])
- break;
- }
+ if (code == CALL_INSN)
+ {
+ rtx x;
+ int regno, nregs;
+ HARD_REG_SET hard_regs_to_save;
+
+ /* Use the register life information in CHAIN to compute which
+ regs are live before the call. */
+ REG_SET_TO_HARD_REG_SET (hard_regs_to_save, chain->live_before);
+ compute_use_by_pseudos (&hard_regs_to_save, chain->live_before);
+
+ /* Record all registers set in this call insn. These don't need
+ to be saved. */
+ CLEAR_HARD_REG_SET (this_insn_sets);
+ note_stores (PATTERN (insn), mark_set_regs);
+
+ /* Compute which hard regs must be saved before this call. */
+ AND_COMPL_HARD_REG_SET (hard_regs_to_save, call_fixed_reg_set);
+ AND_COMPL_HARD_REG_SET (hard_regs_to_save, this_insn_sets);
+ AND_COMPL_HARD_REG_SET (hard_regs_to_save, hard_regs_saved);
+ AND_HARD_REG_SET (hard_regs_to_save, call_used_reg_set);
+
+ /* Registers used for function parameters need not be saved. */
+ for (x = CALL_INSN_FUNCTION_USAGE (insn); x != 0;
+ x = XEXP (x, 1))
+ {
+ rtx y;
+
+ if (GET_CODE (XEXP (x, 0)) != USE)
+ continue;
+ y = XEXP (XEXP (x, 0), 0);
+ if (GET_CODE (y) != REG)
+ abort ();
+ regno = REGNO (y);
+ if (REGNO (y) >= FIRST_PSEUDO_REGISTER)
+ abort ();
+ nregs = HARD_REGNO_NREGS (regno, GET_MODE (y));
+ while (nregs-- > 0)
+ CLEAR_HARD_REG_BIT (hard_regs_to_save, regno + nregs);
+ }
- /* At the end of the basic block, we must restore any registers that
- remain saved. If the last insn in the block is a JUMP_INSN, put
- the restore before the insn, otherwise, put it after the insn. */
+ /* Neither do registers for which we find a death note. */
+ for (x = REG_NOTES (insn); x != 0; x = XEXP (x, 1))
+ {
+ rtx y = XEXP (x, 0);
+
+ if (REG_NOTE_KIND (x) != REG_DEAD)
+ continue;
+ if (GET_CODE (y) != REG)
+ abort ();
+ regno = REGNO (y);
+
+ if (regno >= FIRST_PSEUDO_REGISTER)
+ regno = reg_renumber[regno];
+ if (regno < 0)
+ continue;
+ nregs = HARD_REGNO_NREGS (regno, GET_MODE (y));
+ while (nregs-- > 0)
+ CLEAR_HARD_REG_BIT (hard_regs_to_save, regno + nregs);
+ }
+
+ for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
+ if (TEST_HARD_REG_BIT (hard_regs_to_save, regno))
+ regno += insert_save (chain, 1, regno, &hard_regs_to_save);
+
+ /* Must recompute n_regs_saved. */
+ n_regs_saved = 0;
+ for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
+ if (TEST_HARD_REG_BIT (hard_regs_saved, regno))
+ n_regs_saved++;
+ }
+ }
- if (n_regs_saved)
- for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
- if (TEST_HARD_REG_BIT (hard_regs_need_restore, regno))
- regno += insert_restore (insn, GET_CODE (insn) == JUMP_INSN,
- regno,
- MOVE_MAX / UNITS_PER_WORD, b);
- }
+ if (chain->next == 0 || chain->next->block > chain->block)
+ {
+ int regno;
+ /* At the end of the basic block, we must restore any registers that
+ remain saved. If the last insn in the block is a JUMP_INSN, put
+ the restore before the insn, otherwise, put it after the insn. */
+
+ if (n_regs_saved)
+ for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
+ if (TEST_HARD_REG_BIT (hard_regs_saved, regno))
+ regno += insert_restore (chain, GET_CODE (insn) == JUMP_INSN,
+ regno, MOVE_MAX_WORDS);
+ }
+ }
}
/* Here from note_stores when an insn stores a value in a register.
- Set the proper bit or bits in hard_regs_live. All pseudos that have
+ Set the proper bit or bits in this_insn_sets. All pseudos that have
been assigned hard regs have had their register number changed already,
so we can ignore pseudos. */
-
static void
-set_reg_live (reg, setter)
+mark_set_regs (reg, setter)
rtx reg;
rtx setter ATTRIBUTE_UNUSED;
{
@@ -501,104 +486,71 @@ set_reg_live (reg, setter)
endregno = regno + HARD_REGNO_NREGS (regno, mode);
for (i = regno; i < endregno; i++)
- {
- SET_HARD_REG_BIT (hard_regs_live, i);
- CLEAR_HARD_REG_BIT (hard_regs_saved, i);
- CLEAR_HARD_REG_BIT (hard_regs_need_restore, i);
- }
+ SET_HARD_REG_BIT (this_insn_sets, i);
}
-/* Here when a REG_DEAD note records the last use of a reg. Clear
- the appropriate bit or bits in hard_regs_live. Again we can ignore
- pseudos. */
-
+/* Walk X and record all referenced registers in REFERENCED_REGS. */
static void
-clear_reg_live (reg)
- rtx reg;
-{
- register int regno, endregno, i;
-
- if (GET_CODE (reg) != REG || REGNO (reg) >= FIRST_PSEUDO_REGISTER)
- return;
-
- regno = REGNO (reg);
- endregno= regno + HARD_REGNO_NREGS (regno, GET_MODE (reg));
-
- for (i = regno; i < endregno; i++)
- {
- CLEAR_HARD_REG_BIT (hard_regs_live, i);
- CLEAR_HARD_REG_BIT (hard_regs_need_restore, i);
- CLEAR_HARD_REG_BIT (hard_regs_saved, i);
- }
-}
-
-/* If any register currently residing in the save area is referenced in X,
- which is part of INSN, emit code to restore the register in front of
- INSN. */
-
-static void
-restore_referenced_regs (x, insn, block)
+mark_referenced_regs (x)
rtx x;
- rtx insn;
- int block;
{
enum rtx_code code = GET_CODE (x);
char *fmt;
int i, j;
- if (code == CLOBBER)
- return;
+ if (code == SET)
+ mark_referenced_regs (SET_SRC (x));
+ if (code == SET || code == CLOBBER)
+ {
+ x = SET_DEST (x);
+ code = GET_CODE (x);
+ if (code == REG || code == PC || code == CC0
+ || (code == SUBREG && GET_CODE (SUBREG_REG (x)) == REG))
+ return;
+ }
+ if (code == MEM || code == SUBREG)
+ {
+ x = XEXP (x, 0);
+ code = GET_CODE (x);
+ }
if (code == REG)
{
int regno = REGNO (x);
+ int hardregno = (regno < FIRST_PSEUDO_REGISTER ? regno
+ : reg_renumber[regno]);
- /* If this is a pseudo, scan its memory location, since it might
- involve the use of another register, which might be saved. */
-
- if (regno >= FIRST_PSEUDO_REGISTER
- && reg_equiv_mem[regno] != 0)
- restore_referenced_regs (XEXP (reg_equiv_mem[regno], 0),
- insn, block);
- else if (regno >= FIRST_PSEUDO_REGISTER
- && reg_equiv_address[regno] != 0)
- restore_referenced_regs (reg_equiv_address[regno],
- insn, block);
-
- /* Otherwise if this is a hard register, restore any piece of it that
- is currently saved. */
-
- else if (regno < FIRST_PSEUDO_REGISTER)
+ if (hardregno >= 0)
{
- int numregs = HARD_REGNO_NREGS (regno, GET_MODE (x));
- /* Save at most SAVEREGS at a time. This can not be larger than
- MOVE_MAX, because that causes insert_restore to fail. */
- int saveregs = MIN (numregs, MOVE_MAX / UNITS_PER_WORD);
- int endregno = regno + numregs;
-
- for (i = regno; i < endregno; i++)
- if (TEST_HARD_REG_BIT (hard_regs_need_restore, i))
- i += insert_restore (insn, 1, i, saveregs, block);
+ int nregs = HARD_REGNO_NREGS (hardregno, GET_MODE (x));
+ while (nregs-- > 0)
+ SET_HARD_REG_BIT (referenced_regs, hardregno + nregs);
}
-
+ /* If this is a pseudo that did not get a hard register, scan its
+ memory location, since it might involve the use of another
+ register, which might be saved. */
+ else if (reg_equiv_mem[regno] != 0)
+ mark_referenced_regs (XEXP (reg_equiv_mem[regno], 0));
+ else if (reg_equiv_address[regno] != 0)
+ mark_referenced_regs (reg_equiv_address[regno]);
return;
}
-
+
fmt = GET_RTX_FORMAT (code);
for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
{
if (fmt[i] == 'e')
- restore_referenced_regs (XEXP (x, i), insn, block);
+ mark_referenced_regs (XEXP (x, i));
else if (fmt[i] == 'E')
for (j = XVECLEN (x, i) - 1; j >= 0; j--)
- restore_referenced_regs (XVECEXP (x, i, j), insn, block);
+ mark_referenced_regs (XVECEXP (x, i, j));
}
}
-/* Insert a sequence of insns to restore REGNO. Place these insns in front
- of or after INSN (determined by BEFORE_P). MAXRESTORE is the maximum
- number of registers which should be restored during this call. It should
- never be less than 1 since we only work with entire registers.
+/* Insert a sequence of insns to restore. Place these insns in front of
+ CHAIN if BEFORE_P is nonzero, behind the insn otherwise. MAXRESTORE is
+ the maximum number of registers which should be restored during this call.
+ It should never be less than 1 since we only work with entire registers.
Note that we have verified in init_caller_save that we can do this
with a simple SET, so use it. Set INSN_CODE to what we save there
@@ -609,18 +561,16 @@ restore_referenced_regs (x, insn, block)
Return the extra number of registers saved. */
static int
-insert_restore (insn, before_p, regno, maxrestore, block)
- rtx insn;
+insert_restore (chain, before_p, regno, maxrestore)
+ struct insn_chain *chain;
int before_p;
int regno;
int maxrestore;
- int block;
{
+ int i;
rtx pat = NULL_RTX;
enum insn_code code = CODE_FOR_nothing;
int numregs = 0;
- int i, j, k;
- int ok;
/* A common failure mode if register status is not correct in the RTL
is for this routine to be called with a REGNO we didn't expect to
@@ -632,37 +582,38 @@ insert_restore (insn, before_p, regno, maxrestore, block)
if (regno_save_mem[regno][1] == 0)
abort ();
- /* Get the pattern to emit and update our status. */
+ /* Get the pattern to emit and update our status.
- /* See if we can restore `maxrestore' registers at once. Work
+ See if we can restore `maxrestore' registers at once. Work
backwards to the single register case. */
for (i = maxrestore; i > 0; i--)
{
- ok = 1;
- if (regno_save_mem[regno][i])
- for (j = 0; j < i; j++)
- {
- if (! TEST_HARD_REG_BIT (hard_regs_need_restore, regno + j))
- ok = 0;
- }
- else
+ int j, k;
+ int ok = 1;
+
+ if (regno_save_mem[regno][i] == 0)
continue;
+ for (j = 0; j < i; j++)
+ if (! TEST_HARD_REG_BIT (hard_regs_saved, regno + j))
+ {
+ ok = 0;
+ break;
+ }
/* Must do this one restore at a time */
if (! ok)
continue;
-
+
pat = gen_rtx_SET (VOIDmode,
gen_rtx_REG (GET_MODE (regno_save_mem[regno][i]),
regno),
regno_save_mem[regno][i]);
code = reg_restore_code[regno][i];
-
/* Clear status for all registers we restored. */
for (k = 0; k < i; k++)
{
- CLEAR_HARD_REG_BIT (hard_regs_need_restore, regno + k);
+ CLEAR_HARD_REG_BIT (hard_regs_saved, regno + k);
n_regs_saved--;
}
@@ -670,25 +621,24 @@ insert_restore (insn, before_p, regno, maxrestore, block)
break;
}
- insert_one_insn (insn, before_p, code, pat, block);
+ insert_one_insn (chain, before_p, code, pat);
/* Tell our callers how many extra registers we saved/restored */
return numregs - 1;
}
-/* Like insert_restore, but emit code to save REGNO. */
+/* Like insert_restore above, but save registers instead. */
static int
-insert_save (insn, before_p, regno, block)
- rtx insn;
+insert_save (chain, before_p, regno, to_save)
+ struct insn_chain *chain;
int before_p;
int regno;
- int block;
+ HARD_REG_SET *to_save;
{
+ int i;
rtx pat = NULL_RTX;
enum insn_code code = CODE_FOR_nothing;
int numregs = 0;
- int i, j, k;
- int ok;
/* A common failure mode if register status is not correct in the RTL
is for this routine to be called with a REGNO we didn't expect to
@@ -700,24 +650,23 @@ insert_save (insn, before_p, regno, block)
if (regno_save_mem[regno][1] == 0)
abort ();
- /* Get the pattern to emit and update our status. */
+ /* Get the pattern to emit and update our status.
- /* See if we can save several registers with a single instruction.
+ See if we can save several registers with a single instruction.
Work backwards to the single register case. */
- for (i = MOVE_MAX / UNITS_PER_WORD; i > 0; i--)
+ for (i = MOVE_MAX_WORDS; i > 0; i--)
{
- ok = 1;
- if (regno_save_mem[regno][i] != 0)
- for (j = 0; j < i; j++)
- {
- if (! call_used_regs[regno + j] || call_fixed_regs[regno + j]
- || ! TEST_HARD_REG_BIT (hard_regs_live, regno + j)
- || TEST_HARD_REG_BIT (hard_regs_saved, regno + j))
- ok = 0;
- }
- else
+ int j, k;
+ int ok = 1;
+ if (regno_save_mem[regno][i] == 0)
continue;
+ for (j = 0; j < i; j++)
+ if (! TEST_HARD_REG_BIT (*to_save, regno + j))
+ {
+ ok = 0;
+ break;
+ }
/* Must do this one save at a time */
if (! ok)
continue;
@@ -731,7 +680,6 @@ insert_save (insn, before_p, regno, block)
for (k = 0; k < i; k++)
{
SET_HARD_REG_BIT (hard_regs_saved, regno + k);
- SET_HARD_REG_BIT (hard_regs_need_restore, regno + k);
n_regs_saved++;
}
@@ -739,23 +687,23 @@ insert_save (insn, before_p, regno, block)
break;
}
- insert_one_insn (insn, before_p, code, pat, block);
+ insert_one_insn (chain, before_p, code, pat);
/* Tell our callers how many extra registers we saved/restored */
return numregs - 1;
}
-/* Emit one insn, set the code, and update basic block boundaries. */
+/* Emit a new caller-save insn and set the code. */
static void
-insert_one_insn (insn, before_p, code, pat, block)
- rtx insn;
+insert_one_insn (chain, before_p, code, pat)
+ struct insn_chain *chain;
int before_p;
- enum rtx_code code;
+ enum insn_code code;
rtx pat;
- int block;
{
- rtx insert_point = insn;
- rtx new;
+ rtx insn = chain->insn;
+ struct insn_chain *new;
+
#ifdef HAVE_cc0
/* If INSN references CC0, put our insns in front of the insn that sets
CC0. This is always safe, since the only way we could be passed an
@@ -766,21 +714,45 @@ insert_one_insn (insn, before_p, code, pat, block)
if ((GET_CODE (insn) == INSN || GET_CODE (insn) == JUMP_INSN)
&& before_p
&& reg_referenced_p (cc0_rtx, PATTERN (insn)))
- insert_point = prev_nonnote_insn (insn);
+ chain = chain->prev, insn = chain->insn;
#endif
+ new = new_insn_chain ();
if (before_p)
{
- new = emit_insn_before (pat, insert_point);
- if (insert_point == basic_block_head[block])
- basic_block_head[block] = new;
+ new->prev = chain->prev;
+ if (new->prev != 0)
+ new->prev->next = new;
+ else
+ reload_insn_chain = new;
+
+ chain->prev = new;
+ new->next = chain;
+ new->insn = emit_insn_before (pat, insn);
+ /* ??? It would be nice if we could exclude the already / still saved
+ registers from the live sets. */
+ COPY_REG_SET (new->live_before, chain->live_before);
+ COPY_REG_SET (new->live_after, chain->live_before);
+ if (chain->insn == BLOCK_HEAD (chain->block))
+ BLOCK_HEAD (chain->block) = new->insn;
}
else
{
- new = emit_insn_after (pat, insert_point);
- if (insert_point == basic_block_end[block])
- basic_block_end[block] = new;
+ new->next = chain->next;
+ if (new->next != 0)
+ new->next->prev = new;
+ chain->next = new;
+ new->prev = chain;
+ new->insn = emit_insn_after (pat, insn);
+ /* ??? It would be nice if we could exclude the already / still saved
+ registers from the live sets, and observe REG_UNUSED notes. */
+ COPY_REG_SET (new->live_before, chain->live_after);
+ COPY_REG_SET (new->live_after, chain->live_after);
+ if (chain->insn == BLOCK_END (chain->block))
+ BLOCK_END (chain->block) = new->insn;
}
+ new->block = chain->block;
+ new->is_caller_save_insn = 1;
- INSN_CODE (new) = code;
+ INSN_CODE (new->insn) = code;
}
diff --git a/gcc/calls.c b/gcc/calls.c
index 8377130688e..af96b9b60fb 100644
--- a/gcc/calls.c
+++ b/gcc/calls.c
@@ -1,5 +1,5 @@
/* Convert function calls to rtl insns, for GNU C compiler.
- Copyright (C) 1989, 92-97, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1989, 92-97, 1998, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -22,7 +22,6 @@ Boston, MA 02111-1307, USA. */
#include "system.h"
#include "rtl.h"
#include "tree.h"
-#include "function.h"
#include "flags.h"
#include "expr.h"
#include "regs.h"
@@ -30,6 +29,10 @@ Boston, MA 02111-1307, USA. */
#include "toplev.h"
#include "output.h"
+#if !defined PREFERRED_STACK_BOUNDARY && defined STACK_BOUNDARY
+#define PREFERRED_STACK_BOUNDARY STACK_BOUNDARY
+#endif
+
/* Decide whether a function's arguments should be processed
from first to last or from last to first.
@@ -44,8 +47,8 @@ Boston, MA 02111-1307, USA. */
#endif
-/* Like STACK_BOUNDARY but in units of bytes, not bits. */
-#define STACK_BYTES (STACK_BOUNDARY / BITS_PER_UNIT)
+/* Like PREFERRED_STACK_BOUNDARY but in units of bytes, not bits. */
+#define STACK_BYTES (PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT)
/* Data structure and subroutines used within expand_call. */
@@ -121,13 +124,44 @@ static int highest_outgoing_arg_in_use;
int stack_arg_under_construction;
#endif
-static int calls_function PROTO((tree, int));
-static int calls_function_1 PROTO((tree, int));
-static void emit_call_1 PROTO((rtx, tree, tree, HOST_WIDE_INT,
- HOST_WIDE_INT, rtx, rtx,
- int, rtx, int));
+static int calls_function PROTO ((tree, int));
+static int calls_function_1 PROTO ((tree, int));
+static void emit_call_1 PROTO ((rtx, tree, tree, HOST_WIDE_INT,
+ HOST_WIDE_INT, rtx, rtx,
+ int, rtx, int));
+static void special_function_p PROTO ((char *, tree, int *, int *,
+ int *, int *));
+static void precompute_register_parameters PROTO ((int, struct arg_data *,
+ int *));
static void store_one_arg PROTO ((struct arg_data *, rtx, int, int,
- tree, int));
+ int));
+static void store_unaligned_arguments_into_pseudos PROTO ((struct arg_data *,
+ int));
+static int finalize_must_preallocate PROTO ((int, int,
+ struct arg_data *,
+ struct args_size *));
+static void precompute_arguments PROTO ((int, int, int,
+ struct arg_data *,
+ struct args_size *));
+static int compute_argument_block_size PROTO ((int,
+ struct args_size *));
+static void initialize_argument_information PROTO ((int,
+ struct arg_data *,
+ struct args_size *,
+ int, tree, tree,
+ CUMULATIVE_ARGS *,
+ int, rtx *, int *,
+ int *, int *));
+static void compute_argument_addresses PROTO ((struct arg_data *,
+ rtx, int));
+static rtx rtx_for_function_call PROTO ((tree, tree));
+static void load_register_parameters PROTO ((struct arg_data *,
+ int, rtx *));
+
+#if defined(ACCUMULATE_OUTGOING_ARGS) && defined(REG_PARM_STACK_SPACE)
+static rtx save_fixed_argument_area PROTO ((int, rtx, int *, int *));
+static void restore_fixed_argument_area PROTO ((rtx, rtx, int, int));
+#endif
/* If WHICH is 1, return 1 if EXP contains a call to the built-in function
`alloca'.
@@ -184,7 +218,8 @@ calls_function_1 (exp, which)
if ((DECL_BUILT_IN (fndecl)
&& DECL_FUNCTION_CODE (fndecl) == BUILT_IN_ALLOCA)
|| (DECL_SAVED_INSNS (fndecl)
- && DECL_SAVED_INSNS (fndecl)->calls_alloca))
+ && (FUNCTION_FLAGS (DECL_SAVED_INSNS (fndecl))
+ & FUNCTION_FLAGS_CALLS_ALLOCA)))
return 1;
}
@@ -311,7 +346,7 @@ prepare_call_address (funexp, fndecl, call_fusage, reg_parm_seen)
says that the pointer to this aggregate is to be popped by the callee.
STACK_SIZE is the number of bytes of arguments on the stack,
- rounded up to STACK_BOUNDARY; zero if the size is variable.
+ rounded up to PREFERRED_STACK_BOUNDARY; zero if the size is variable.
This is both to put into the call insn and
to generate explicit popping code if necessary.
@@ -343,8 +378,8 @@ emit_call_1 (funexp, fndecl, funtype, stack_size, struct_value_size,
next_arg_reg, valreg, old_inhibit_defer_pop, call_fusage,
is_const)
rtx funexp;
- tree fndecl;
- tree funtype;
+ tree fndecl ATTRIBUTE_UNUSED;
+ tree funtype ATTRIBUTE_UNUSED;
HOST_WIDE_INT stack_size;
HOST_WIDE_INT struct_value_size;
rtx next_arg_reg;
@@ -471,6 +506,998 @@ emit_call_1 (funexp, fndecl, funtype, stack_size, struct_value_size,
#endif
}
+/* Determine if the function identified by NAME and FNDECL is one with
+ special properties we wish to know about.
+
+ For example, if the function might return more than one time (setjmp), then
+ set RETURNS_TWICE to a nonzero value.
+
+ Similarly set IS_LONGJMP for if the function is in the longjmp family.
+
+ Set IS_MALLOC for any of the standard memory allocation functions which
+ allocate from the heap.
+
+ Set MAY_BE_ALLOCA for any memory allocation function that might allocate
+ space from the stack such as alloca. */
+
+static void
+special_function_p (name, fndecl, returns_twice, is_longjmp,
+ is_malloc, may_be_alloca)
+ char *name;
+ tree fndecl;
+ int *returns_twice;
+ int *is_longjmp;
+ int *is_malloc;
+ int *may_be_alloca;
+{
+ *returns_twice = 0;
+ *is_longjmp = 0;
+ *is_malloc = 0;
+ *may_be_alloca = 0;
+
+ if (name != 0 && IDENTIFIER_LENGTH (DECL_NAME (fndecl)) <= 17
+ /* Exclude functions not at the file scope, or not `extern',
+ since they are not the magic functions we would otherwise
+ think they are. */
+ && DECL_CONTEXT (fndecl) == NULL_TREE && TREE_PUBLIC (fndecl))
+ {
+ char *tname = name;
+
+ /* We assume that alloca will always be called by name. It
+ makes no sense to pass it as a pointer-to-function to
+ anything that does not understand its behavior. */
+ *may_be_alloca
+ = (((IDENTIFIER_LENGTH (DECL_NAME (fndecl)) == 6
+ && name[0] == 'a'
+ && ! strcmp (name, "alloca"))
+ || (IDENTIFIER_LENGTH (DECL_NAME (fndecl)) == 16
+ && name[0] == '_'
+ && ! strcmp (name, "__builtin_alloca"))));
+
+ /* Disregard prefix _, __ or __x. */
+ if (name[0] == '_')
+ {
+ if (name[1] == '_' && name[2] == 'x')
+ tname += 3;
+ else if (name[1] == '_')
+ tname += 2;
+ else
+ tname += 1;
+ }
+
+ if (tname[0] == 's')
+ {
+ *returns_twice
+ = ((tname[1] == 'e'
+ && (! strcmp (tname, "setjmp")
+ || ! strcmp (tname, "setjmp_syscall")))
+ || (tname[1] == 'i'
+ && ! strcmp (tname, "sigsetjmp"))
+ || (tname[1] == 'a'
+ && ! strcmp (tname, "savectx")));
+ if (tname[1] == 'i'
+ && ! strcmp (tname, "siglongjmp"))
+ *is_longjmp = 1;
+ }
+ else if ((tname[0] == 'q' && tname[1] == 's'
+ && ! strcmp (tname, "qsetjmp"))
+ || (tname[0] == 'v' && tname[1] == 'f'
+ && ! strcmp (tname, "vfork")))
+ *returns_twice = 1;
+
+ else if (tname[0] == 'l' && tname[1] == 'o'
+ && ! strcmp (tname, "longjmp"))
+ *is_longjmp = 1;
+ /* XXX should have "malloc" attribute on functions instead
+ of recognizing them by name. */
+ else if (! strcmp (tname, "malloc")
+ || ! strcmp (tname, "calloc")
+ || ! strcmp (tname, "realloc")
+ /* Note use of NAME rather than TNAME here. These functions
+ are only reserved when preceded with __. */
+ || ! strcmp (name, "__vn") /* mangled __builtin_vec_new */
+ || ! strcmp (name, "__nw") /* mangled __builtin_new */
+ || ! strcmp (name, "__builtin_new")
+ || ! strcmp (name, "__builtin_vec_new"))
+ *is_malloc = 1;
+ }
+}
+
+/* Precompute all register parameters as described by ARGS, storing values
+ into fields within the ARGS array.
+
+ NUM_ACTUALS indicates the total number elements in the ARGS array.
+
+ Set REG_PARM_SEEN if we encounter a register parameter. */
+
+static void
+precompute_register_parameters (num_actuals, args, reg_parm_seen)
+ int num_actuals;
+ struct arg_data *args;
+ int *reg_parm_seen;
+{
+ int i;
+
+ *reg_parm_seen = 0;
+
+ for (i = 0; i < num_actuals; i++)
+ if (args[i].reg != 0 && ! args[i].pass_on_stack)
+ {
+ *reg_parm_seen = 1;
+
+ if (args[i].value == 0)
+ {
+ push_temp_slots ();
+ args[i].value = expand_expr (args[i].tree_value, NULL_RTX,
+ VOIDmode, 0);
+ preserve_temp_slots (args[i].value);
+ pop_temp_slots ();
+
+ /* ANSI doesn't require a sequence point here,
+ but PCC has one, so this will avoid some problems. */
+ emit_queue ();
+ }
+
+ /* If we are to promote the function arg to a wider mode,
+ do it now. */
+
+ if (args[i].mode != TYPE_MODE (TREE_TYPE (args[i].tree_value)))
+ args[i].value
+ = convert_modes (args[i].mode,
+ TYPE_MODE (TREE_TYPE (args[i].tree_value)),
+ args[i].value, args[i].unsignedp);
+
+ /* If the value is expensive, and we are inside an appropriately
+ short loop, put the value into a pseudo and then put the pseudo
+ into the hard reg.
+
+ For small register classes, also do this if this call uses
+ register parameters. This is to avoid reload conflicts while
+ loading the parameters registers. */
+
+ if ((! (GET_CODE (args[i].value) == REG
+ || (GET_CODE (args[i].value) == SUBREG
+ && GET_CODE (SUBREG_REG (args[i].value)) == REG)))
+ && args[i].mode != BLKmode
+ && rtx_cost (args[i].value, SET) > 2
+ && ((SMALL_REGISTER_CLASSES && *reg_parm_seen)
+ || preserve_subexpressions_p ()))
+ args[i].value = copy_to_mode_reg (args[i].mode, args[i].value);
+ }
+}
+
+#if defined(ACCUMULATE_OUTGOING_ARGS) && defined(REG_PARM_STACK_SPACE)
+
+ /* The argument list is the property of the called routine and it
+ may clobber it. If the fixed area has been used for previous
+ parameters, we must save and restore it. */
+static rtx
+save_fixed_argument_area (reg_parm_stack_space, argblock,
+ low_to_save, high_to_save)
+ int reg_parm_stack_space;
+ rtx argblock;
+ int *low_to_save;
+ int *high_to_save;
+{
+ int i;
+ rtx save_area = NULL_RTX;
+
+ /* Compute the boundary of the that needs to be saved, if any. */
+#ifdef ARGS_GROW_DOWNWARD
+ for (i = 0; i < reg_parm_stack_space + 1; i++)
+#else
+ for (i = 0; i < reg_parm_stack_space; i++)
+#endif
+ {
+ if (i >= highest_outgoing_arg_in_use
+ || stack_usage_map[i] == 0)
+ continue;
+
+ if (*low_to_save == -1)
+ *low_to_save = i;
+
+ *high_to_save = i;
+ }
+
+ if (*low_to_save >= 0)
+ {
+ int num_to_save = *high_to_save - *low_to_save + 1;
+ enum machine_mode save_mode
+ = mode_for_size (num_to_save * BITS_PER_UNIT, MODE_INT, 1);
+ rtx stack_area;
+
+ /* If we don't have the required alignment, must do this in BLKmode. */
+ if ((*low_to_save & (MIN (GET_MODE_SIZE (save_mode),
+ BIGGEST_ALIGNMENT / UNITS_PER_WORD) - 1)))
+ save_mode = BLKmode;
+
+#ifdef ARGS_GROW_DOWNWARD
+ stack_area = gen_rtx_MEM (save_mode,
+ memory_address (save_mode,
+ plus_constant (argblock,
+ - *high_to_save)));
+#else
+ stack_area = gen_rtx_MEM (save_mode,
+ memory_address (save_mode,
+ plus_constant (argblock,
+ *low_to_save)));
+#endif
+ if (save_mode == BLKmode)
+ {
+ save_area = assign_stack_temp (BLKmode, num_to_save, 0);
+ emit_block_move (validize_mem (save_area), stack_area,
+ GEN_INT (num_to_save),
+ PARM_BOUNDARY / BITS_PER_UNIT);
+ }
+ else
+ {
+ save_area = gen_reg_rtx (save_mode);
+ emit_move_insn (save_area, stack_area);
+ }
+ }
+ return save_area;
+}
+
+static void
+restore_fixed_argument_area (save_area, argblock, high_to_save, low_to_save)
+ rtx save_area;
+ rtx argblock;
+ int high_to_save;
+ int low_to_save;
+{
+ enum machine_mode save_mode = GET_MODE (save_area);
+#ifdef ARGS_GROW_DOWNWARD
+ rtx stack_area
+ = gen_rtx_MEM (save_mode,
+ memory_address (save_mode,
+ plus_constant (argblock,
+ - high_to_save)));
+#else
+ rtx stack_area
+ = gen_rtx_MEM (save_mode,
+ memory_address (save_mode,
+ plus_constant (argblock,
+ low_to_save)));
+#endif
+
+ if (save_mode != BLKmode)
+ emit_move_insn (stack_area, save_area);
+ else
+ emit_block_move (stack_area, validize_mem (save_area),
+ GEN_INT (high_to_save - low_to_save + 1),
+ PARM_BOUNDARY / BITS_PER_UNIT);
+}
+#endif
+
+/* If any elements in ARGS refer to parameters that are to be passed in
+ registers, but not in memory, and whose alignment does not permit a
+ direct copy into registers. Copy the values into a group of pseudos
+ which we will later copy into the appropriate hard registers.
+
+ Pseudos for each unaligned argument will be stored into the array
+ args[argnum].aligned_regs. The caller is responsible for deallocating
+ the aligned_regs array if it is nonzero. */
+
+static void
+store_unaligned_arguments_into_pseudos (args, num_actuals)
+ struct arg_data *args;
+ int num_actuals;
+{
+ int i, j;
+
+ for (i = 0; i < num_actuals; i++)
+ if (args[i].reg != 0 && ! args[i].pass_on_stack
+ && args[i].mode == BLKmode
+ && (TYPE_ALIGN (TREE_TYPE (args[i].tree_value))
+ < (unsigned int) MIN (BIGGEST_ALIGNMENT, BITS_PER_WORD)))
+ {
+ int bytes = int_size_in_bytes (TREE_TYPE (args[i].tree_value));
+ int big_endian_correction = 0;
+
+ args[i].n_aligned_regs
+ = args[i].partial ? args[i].partial
+ : (bytes + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD;
+
+ args[i].aligned_regs = (rtx *) xmalloc (sizeof (rtx)
+ * args[i].n_aligned_regs);
+
+ /* Structures smaller than a word are aligned to the least
+ significant byte (to the right). On a BYTES_BIG_ENDIAN machine,
+ this means we must skip the empty high order bytes when
+ calculating the bit offset. */
+ if (BYTES_BIG_ENDIAN && bytes < UNITS_PER_WORD)
+ big_endian_correction = (BITS_PER_WORD - (bytes * BITS_PER_UNIT));
+
+ for (j = 0; j < args[i].n_aligned_regs; j++)
+ {
+ rtx reg = gen_reg_rtx (word_mode);
+ rtx word = operand_subword_force (args[i].value, j, BLKmode);
+ int bitsize = MIN (bytes * BITS_PER_UNIT, BITS_PER_WORD);
+ int bitalign = TYPE_ALIGN (TREE_TYPE (args[i].tree_value));
+
+ args[i].aligned_regs[j] = reg;
+
+ /* There is no need to restrict this code to loading items
+ in TYPE_ALIGN sized hunks. The bitfield instructions can
+ load up entire word sized registers efficiently.
+
+ ??? This may not be needed anymore.
+ We use to emit a clobber here but that doesn't let later
+ passes optimize the instructions we emit. By storing 0 into
+ the register later passes know the first AND to zero out the
+ bitfield being set in the register is unnecessary. The store
+ of 0 will be deleted as will at least the first AND. */
+
+ emit_move_insn (reg, const0_rtx);
+
+ bytes -= bitsize / BITS_PER_UNIT;
+ store_bit_field (reg, bitsize, big_endian_correction, word_mode,
+ extract_bit_field (word, bitsize, 0, 1,
+ NULL_RTX, word_mode,
+ word_mode,
+ bitalign / BITS_PER_UNIT,
+ BITS_PER_WORD),
+ bitalign / BITS_PER_UNIT, BITS_PER_WORD);
+ }
+ }
+}
+
+/* Fill in ARGS_SIZE and ARGS array based on the parameters found in
+ ACTPARMS.
+
+ NUM_ACTUALS is the total number of parameters.
+
+ N_NAMED_ARGS is the total number of named arguments.
+
+ FNDECL is the tree code for the target of this call (if known)
+
+ ARGS_SO_FAR holds state needed by the target to know where to place
+ the next argument.
+
+ REG_PARM_STACK_SPACE is the number of bytes of stack space reserved
+ for arguments which are passed in registers.
+
+ OLD_STACK_LEVEL is a pointer to an rtx which olds the old stack level
+ and may be modified by this routine.
+
+ OLD_PENDING_ADJ, MUST_PREALLOCATE and IS_CONST are pointers to integer
+ flags which may may be modified by this routine. */
+
+static void
+initialize_argument_information (num_actuals, args, args_size, n_named_args,
+ actparms, fndecl, args_so_far,
+ reg_parm_stack_space, old_stack_level,
+ old_pending_adj, must_preallocate, is_const)
+ int num_actuals ATTRIBUTE_UNUSED;
+ struct arg_data *args;
+ struct args_size *args_size;
+ int n_named_args ATTRIBUTE_UNUSED;
+ tree actparms;
+ tree fndecl;
+ CUMULATIVE_ARGS *args_so_far;
+ int reg_parm_stack_space;
+ rtx *old_stack_level;
+ int *old_pending_adj;
+ int *must_preallocate;
+ int *is_const;
+{
+ /* 1 if scanning parms front to back, -1 if scanning back to front. */
+ int inc;
+
+ /* Count arg position in order args appear. */
+ int argpos;
+
+ int i;
+ tree p;
+
+ args_size->constant = 0;
+ args_size->var = 0;
+
+ /* In this loop, we consider args in the order they are written.
+ We fill up ARGS from the front or from the back if necessary
+ so that in any case the first arg to be pushed ends up at the front. */
+
+#ifdef PUSH_ARGS_REVERSED
+ i = num_actuals - 1, inc = -1;
+ /* In this case, must reverse order of args
+ so that we compute and push the last arg first. */
+#else
+ i = 0, inc = 1;
+#endif
+
+ /* I counts args in order (to be) pushed; ARGPOS counts in order written. */
+ for (p = actparms, argpos = 0; p; p = TREE_CHAIN (p), i += inc, argpos++)
+ {
+ tree type = TREE_TYPE (TREE_VALUE (p));
+ int unsignedp;
+ enum machine_mode mode;
+
+ args[i].tree_value = TREE_VALUE (p);
+
+ /* Replace erroneous argument with constant zero. */
+ if (type == error_mark_node || TYPE_SIZE (type) == 0)
+ args[i].tree_value = integer_zero_node, type = integer_type_node;
+
+ /* If TYPE is a transparent union, pass things the way we would
+ pass the first field of the union. We have already verified that
+ the modes are the same. */
+ if (TYPE_TRANSPARENT_UNION (type))
+ type = TREE_TYPE (TYPE_FIELDS (type));
+
+ /* Decide where to pass this arg.
+
+ args[i].reg is nonzero if all or part is passed in registers.
+
+ args[i].partial is nonzero if part but not all is passed in registers,
+ and the exact value says how many words are passed in registers.
+
+ args[i].pass_on_stack is nonzero if the argument must at least be
+ computed on the stack. It may then be loaded back into registers
+ if args[i].reg is nonzero.
+
+ These decisions are driven by the FUNCTION_... macros and must agree
+ with those made by function.c. */
+
+ /* See if this argument should be passed by invisible reference. */
+ if ((TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST
+ && contains_placeholder_p (TYPE_SIZE (type)))
+ || TREE_ADDRESSABLE (type)
+#ifdef FUNCTION_ARG_PASS_BY_REFERENCE
+ || FUNCTION_ARG_PASS_BY_REFERENCE (*args_so_far, TYPE_MODE (type),
+ type, argpos < n_named_args)
+#endif
+ )
+ {
+ /* If we're compiling a thunk, pass through invisible
+ references instead of making a copy. */
+ if (current_function_is_thunk
+#ifdef FUNCTION_ARG_CALLEE_COPIES
+ || (FUNCTION_ARG_CALLEE_COPIES (*args_so_far, TYPE_MODE (type),
+ type, argpos < n_named_args)
+ /* If it's in a register, we must make a copy of it too. */
+ /* ??? Is this a sufficient test? Is there a better one? */
+ && !(TREE_CODE (args[i].tree_value) == VAR_DECL
+ && REG_P (DECL_RTL (args[i].tree_value)))
+ && ! TREE_ADDRESSABLE (type))
+#endif
+ )
+ {
+ /* C++ uses a TARGET_EXPR to indicate that we want to make a
+ new object from the argument. If we are passing by
+ invisible reference, the callee will do that for us, so we
+ can strip off the TARGET_EXPR. This is not always safe,
+ but it is safe in the only case where this is a useful
+ optimization; namely, when the argument is a plain object.
+ In that case, the frontend is just asking the backend to
+ make a bitwise copy of the argument. */
+
+ if (TREE_CODE (args[i].tree_value) == TARGET_EXPR
+ && (TREE_CODE_CLASS (TREE_CODE (TREE_OPERAND
+ (args[i].tree_value, 1)))
+ == 'd')
+ && ! REG_P (DECL_RTL (TREE_OPERAND (args[i].tree_value, 1))))
+ args[i].tree_value = TREE_OPERAND (args[i].tree_value, 1);
+
+ args[i].tree_value = build1 (ADDR_EXPR,
+ build_pointer_type (type),
+ args[i].tree_value);
+ type = build_pointer_type (type);
+ }
+ else
+ {
+ /* We make a copy of the object and pass the address to the
+ function being called. */
+ rtx copy;
+
+ if (TYPE_SIZE (type) == 0
+ || TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST
+ || (flag_stack_check && ! STACK_CHECK_BUILTIN
+ && (TREE_INT_CST_HIGH (TYPE_SIZE (type)) != 0
+ || (TREE_INT_CST_LOW (TYPE_SIZE (type))
+ > STACK_CHECK_MAX_VAR_SIZE * BITS_PER_UNIT))))
+ {
+ /* This is a variable-sized object. Make space on the stack
+ for it. */
+ rtx size_rtx = expr_size (TREE_VALUE (p));
+
+ if (*old_stack_level == 0)
+ {
+ emit_stack_save (SAVE_BLOCK, old_stack_level, NULL_RTX);
+ *old_pending_adj = pending_stack_adjust;
+ pending_stack_adjust = 0;
+ }
+
+ copy = gen_rtx_MEM (BLKmode,
+ allocate_dynamic_stack_space (size_rtx,
+ NULL_RTX,
+ TYPE_ALIGN (type)));
+ }
+ else
+ {
+ int size = int_size_in_bytes (type);
+ copy = assign_stack_temp (TYPE_MODE (type), size, 0);
+ }
+
+ MEM_SET_IN_STRUCT_P (copy, AGGREGATE_TYPE_P (type));
+
+ store_expr (args[i].tree_value, copy, 0);
+ *is_const = 0;
+
+ args[i].tree_value = build1 (ADDR_EXPR,
+ build_pointer_type (type),
+ make_tree (type, copy));
+ type = build_pointer_type (type);
+ }
+ }
+
+ mode = TYPE_MODE (type);
+ unsignedp = TREE_UNSIGNED (type);
+
+#ifdef PROMOTE_FUNCTION_ARGS
+ mode = promote_mode (type, mode, &unsignedp, 1);
+#endif
+
+ args[i].unsignedp = unsignedp;
+ args[i].mode = mode;
+ args[i].reg = FUNCTION_ARG (*args_so_far, mode, type,
+ argpos < n_named_args);
+#ifdef FUNCTION_ARG_PARTIAL_NREGS
+ if (args[i].reg)
+ args[i].partial
+ = FUNCTION_ARG_PARTIAL_NREGS (*args_so_far, mode, type,
+ argpos < n_named_args);
+#endif
+
+ args[i].pass_on_stack = MUST_PASS_IN_STACK (mode, type);
+
+ /* If FUNCTION_ARG returned a (parallel [(expr_list (nil) ...) ...]),
+ it means that we are to pass this arg in the register(s) designated
+ by the PARALLEL, but also to pass it in the stack. */
+ if (args[i].reg && GET_CODE (args[i].reg) == PARALLEL
+ && XEXP (XVECEXP (args[i].reg, 0, 0), 0) == 0)
+ args[i].pass_on_stack = 1;
+
+ /* If this is an addressable type, we must preallocate the stack
+ since we must evaluate the object into its final location.
+
+ If this is to be passed in both registers and the stack, it is simpler
+ to preallocate. */
+ if (TREE_ADDRESSABLE (type)
+ || (args[i].pass_on_stack && args[i].reg != 0))
+ *must_preallocate = 1;
+
+ /* If this is an addressable type, we cannot pre-evaluate it. Thus,
+ we cannot consider this function call constant. */
+ if (TREE_ADDRESSABLE (type))
+ *is_const = 0;
+
+ /* Compute the stack-size of this argument. */
+ if (args[i].reg == 0 || args[i].partial != 0
+ || reg_parm_stack_space > 0
+ || args[i].pass_on_stack)
+ locate_and_pad_parm (mode, type,
+#ifdef STACK_PARMS_IN_REG_PARM_AREA
+ 1,
+#else
+ args[i].reg != 0,
+#endif
+ fndecl, args_size, &args[i].offset,
+ &args[i].size);
+
+#ifndef ARGS_GROW_DOWNWARD
+ args[i].slot_offset = *args_size;
+#endif
+
+ /* If a part of the arg was put into registers,
+ don't include that part in the amount pushed. */
+ if (reg_parm_stack_space == 0 && ! args[i].pass_on_stack)
+ args[i].size.constant -= ((args[i].partial * UNITS_PER_WORD)
+ / (PARM_BOUNDARY / BITS_PER_UNIT)
+ * (PARM_BOUNDARY / BITS_PER_UNIT));
+
+ /* Update ARGS_SIZE, the total stack space for args so far. */
+
+ args_size->constant += args[i].size.constant;
+ if (args[i].size.var)
+ {
+ ADD_PARM_SIZE (*args_size, args[i].size.var);
+ }
+
+ /* Since the slot offset points to the bottom of the slot,
+ we must record it after incrementing if the args grow down. */
+#ifdef ARGS_GROW_DOWNWARD
+ args[i].slot_offset = *args_size;
+
+ args[i].slot_offset.constant = -args_size->constant;
+ if (args_size->var)
+ {
+ SUB_PARM_SIZE (args[i].slot_offset, args_size->var);
+ }
+#endif
+
+ /* Increment ARGS_SO_FAR, which has info about which arg-registers
+ have been used, etc. */
+
+ FUNCTION_ARG_ADVANCE (*args_so_far, TYPE_MODE (type), type,
+ argpos < n_named_args);
+ }
+}
+
+/* Update ARGS_SIZE to contain the total size for the argument block.
+ Return the original constant component of the argument block's size.
+
+ REG_PARM_STACK_SPACE holds the number of bytes of stack space reserved
+ for arguments passed in registers. */
+
+static int
+compute_argument_block_size (reg_parm_stack_space, args_size)
+ int reg_parm_stack_space;
+ struct args_size *args_size;
+{
+ int unadjusted_args_size = args_size->constant;
+
+ /* Compute the actual size of the argument block required. The variable
+ and constant sizes must be combined, the size may have to be rounded,
+ and there may be a minimum required size. */
+
+ if (args_size->var)
+ {
+ args_size->var = ARGS_SIZE_TREE (*args_size);
+ args_size->constant = 0;
+
+#ifdef PREFERRED_STACK_BOUNDARY
+ if (PREFERRED_STACK_BOUNDARY != BITS_PER_UNIT)
+ args_size->var = round_up (args_size->var, STACK_BYTES);
+#endif
+
+ if (reg_parm_stack_space > 0)
+ {
+ args_size->var
+ = size_binop (MAX_EXPR, args_size->var,
+ size_int (reg_parm_stack_space));
+
+#ifndef OUTGOING_REG_PARM_STACK_SPACE
+ /* The area corresponding to register parameters is not to count in
+ the size of the block we need. So make the adjustment. */
+ args_size->var
+ = size_binop (MINUS_EXPR, args_size->var,
+ size_int (reg_parm_stack_space));
+#endif
+ }
+ }
+ else
+ {
+#ifdef PREFERRED_STACK_BOUNDARY
+ args_size->constant = (((args_size->constant + (STACK_BYTES - 1))
+ / STACK_BYTES) * STACK_BYTES);
+#endif
+
+ args_size->constant = MAX (args_size->constant,
+ reg_parm_stack_space);
+
+#ifdef MAYBE_REG_PARM_STACK_SPACE
+ if (reg_parm_stack_space == 0)
+ args_size->constant = 0;
+#endif
+
+#ifndef OUTGOING_REG_PARM_STACK_SPACE
+ args_size->constant -= reg_parm_stack_space;
+#endif
+ }
+ return unadjusted_args_size;
+}
+
+/* Precompute parameters has needed for a function call.
+
+ IS_CONST indicates the target function is a pure function.
+
+ MUST_PREALLOCATE indicates that we must preallocate stack space for
+ any stack arguments.
+
+ NUM_ACTUALS is the number of arguments.
+
+ ARGS is an array containing information for each argument; this routine
+ fills in the INITIAL_VALUE and VALUE fields for each precomputed argument.
+
+ ARGS_SIZE contains information about the size of the arg list. */
+
+static void
+precompute_arguments (is_const, must_preallocate, num_actuals, args, args_size)
+ int is_const;
+ int must_preallocate;
+ int num_actuals;
+ struct arg_data *args;
+ struct args_size *args_size;
+{
+ int i;
+
+ /* If this function call is cse'able, precompute all the parameters.
+ Note that if the parameter is constructed into a temporary, this will
+ cause an additional copy because the parameter will be constructed
+ into a temporary location and then copied into the outgoing arguments.
+ If a parameter contains a call to alloca and this function uses the
+ stack, precompute the parameter. */
+
+ /* If we preallocated the stack space, and some arguments must be passed
+ on the stack, then we must precompute any parameter which contains a
+ function call which will store arguments on the stack.
+ Otherwise, evaluating the parameter may clobber previous parameters
+ which have already been stored into the stack. */
+
+ for (i = 0; i < num_actuals; i++)
+ if (is_const
+ || ((args_size->var != 0 || args_size->constant != 0)
+ && calls_function (args[i].tree_value, 1))
+ || (must_preallocate
+ && (args_size->var != 0 || args_size->constant != 0)
+ && calls_function (args[i].tree_value, 0)))
+ {
+ /* If this is an addressable type, we cannot pre-evaluate it. */
+ if (TREE_ADDRESSABLE (TREE_TYPE (args[i].tree_value)))
+ abort ();
+
+ push_temp_slots ();
+
+ args[i].initial_value = args[i].value
+ = expand_expr (args[i].tree_value, NULL_RTX, VOIDmode, 0);
+
+ preserve_temp_slots (args[i].value);
+ pop_temp_slots ();
+
+ /* ANSI doesn't require a sequence point here,
+ but PCC has one, so this will avoid some problems. */
+ emit_queue ();
+
+ args[i].initial_value = args[i].value
+ = protect_from_queue (args[i].initial_value, 0);
+
+ if (TYPE_MODE (TREE_TYPE (args[i].tree_value)) != args[i].mode)
+ args[i].value
+ = convert_modes (args[i].mode,
+ TYPE_MODE (TREE_TYPE (args[i].tree_value)),
+ args[i].value, args[i].unsignedp);
+ }
+}
+
+/* Given the current state of MUST_PREALLOCATE and information about
+ arguments to a function call in NUM_ACTUALS, ARGS and ARGS_SIZE,
+ compute and return the final value for MUST_PREALLOCATE. */
+
+static int
+finalize_must_preallocate (must_preallocate, num_actuals, args, args_size)
+ int must_preallocate;
+ int num_actuals;
+ struct arg_data *args;
+ struct args_size *args_size;
+{
+ /* See if we have or want to preallocate stack space.
+
+ If we would have to push a partially-in-regs parm
+ before other stack parms, preallocate stack space instead.
+
+ If the size of some parm is not a multiple of the required stack
+ alignment, we must preallocate.
+
+ If the total size of arguments that would otherwise create a copy in
+ a temporary (such as a CALL) is more than half the total argument list
+ size, preallocation is faster.
+
+ Another reason to preallocate is if we have a machine (like the m88k)
+ where stack alignment is required to be maintained between every
+ pair of insns, not just when the call is made. However, we assume here
+ that such machines either do not have push insns (and hence preallocation
+ would occur anyway) or the problem is taken care of with
+ PUSH_ROUNDING. */
+
+ if (! must_preallocate)
+ {
+ int partial_seen = 0;
+ int copy_to_evaluate_size = 0;
+ int i;
+
+ for (i = 0; i < num_actuals && ! must_preallocate; i++)
+ {
+ if (args[i].partial > 0 && ! args[i].pass_on_stack)
+ partial_seen = 1;
+ else if (partial_seen && args[i].reg == 0)
+ must_preallocate = 1;
+
+ if (TYPE_MODE (TREE_TYPE (args[i].tree_value)) == BLKmode
+ && (TREE_CODE (args[i].tree_value) == CALL_EXPR
+ || TREE_CODE (args[i].tree_value) == TARGET_EXPR
+ || TREE_CODE (args[i].tree_value) == COND_EXPR
+ || TREE_ADDRESSABLE (TREE_TYPE (args[i].tree_value))))
+ copy_to_evaluate_size
+ += int_size_in_bytes (TREE_TYPE (args[i].tree_value));
+ }
+
+ if (copy_to_evaluate_size * 2 >= args_size->constant
+ && args_size->constant > 0)
+ must_preallocate = 1;
+ }
+ return must_preallocate;
+}
+
+/* If we preallocated stack space, compute the address of each argument
+ and store it into the ARGS array.
+
+ We need not ensure it is a valid memory address here; it will be
+ validized when it is used.
+
+ ARGBLOCK is an rtx for the address of the outgoing arguments. */
+
+static void
+compute_argument_addresses (args, argblock, num_actuals)
+ struct arg_data *args;
+ rtx argblock;
+ int num_actuals;
+{
+ if (argblock)
+ {
+ rtx arg_reg = argblock;
+ int i, arg_offset = 0;
+
+ if (GET_CODE (argblock) == PLUS)
+ arg_reg = XEXP (argblock, 0), arg_offset = INTVAL (XEXP (argblock, 1));
+
+ for (i = 0; i < num_actuals; i++)
+ {
+ rtx offset = ARGS_SIZE_RTX (args[i].offset);
+ rtx slot_offset = ARGS_SIZE_RTX (args[i].slot_offset);
+ rtx addr;
+
+ /* Skip this parm if it will not be passed on the stack. */
+ if (! args[i].pass_on_stack && args[i].reg != 0)
+ continue;
+
+ if (GET_CODE (offset) == CONST_INT)
+ addr = plus_constant (arg_reg, INTVAL (offset));
+ else
+ addr = gen_rtx_PLUS (Pmode, arg_reg, offset);
+
+ addr = plus_constant (addr, arg_offset);
+ args[i].stack = gen_rtx_MEM (args[i].mode, addr);
+ MEM_SET_IN_STRUCT_P
+ (args[i].stack,
+ AGGREGATE_TYPE_P (TREE_TYPE (args[i].tree_value)));
+
+ if (GET_CODE (slot_offset) == CONST_INT)
+ addr = plus_constant (arg_reg, INTVAL (slot_offset));
+ else
+ addr = gen_rtx_PLUS (Pmode, arg_reg, slot_offset);
+
+ addr = plus_constant (addr, arg_offset);
+ args[i].stack_slot = gen_rtx_MEM (args[i].mode, addr);
+ }
+ }
+}
+
+/* Given a FNDECL and EXP, return an rtx suitable for use as a target address
+ in a call instruction.
+
+ FNDECL is the tree node for the target function. For an indirect call
+ FNDECL will be NULL_TREE.
+
+ EXP is the CALL_EXPR for this call. */
+
+static rtx
+rtx_for_function_call (fndecl, exp)
+ tree fndecl;
+ tree exp;
+{
+ rtx funexp;
+
+ /* Get the function to call, in the form of RTL. */
+ if (fndecl)
+ {
+ /* If this is the first use of the function, see if we need to
+ make an external definition for it. */
+ if (! TREE_USED (fndecl))
+ {
+ assemble_external (fndecl);
+ TREE_USED (fndecl) = 1;
+ }
+
+ /* Get a SYMBOL_REF rtx for the function address. */
+ funexp = XEXP (DECL_RTL (fndecl), 0);
+ }
+ else
+ /* Generate an rtx (probably a pseudo-register) for the address. */
+ {
+ push_temp_slots ();
+ funexp = expand_expr (TREE_OPERAND (exp, 0), NULL_RTX, VOIDmode, 0);
+ pop_temp_slots (); /* FUNEXP can't be BLKmode */
+
+ /* Check the function is executable. */
+ if (current_function_check_memory_usage)
+ emit_library_call (chkr_check_exec_libfunc, 1,
+ VOIDmode, 1,
+ funexp, ptr_mode);
+ emit_queue ();
+ }
+ return funexp;
+}
+
+/* Do the register loads required for any wholly-register parms or any
+ parms which are passed both on the stack and in a register. Their
+ expressions were already evaluated.
+
+ Mark all register-parms as living through the call, putting these USE
+ insns in the CALL_INSN_FUNCTION_USAGE field. */
+
+static void
+load_register_parameters (args, num_actuals, call_fusage)
+ struct arg_data *args;
+ int num_actuals;
+ rtx *call_fusage;
+{
+ int i, j;
+
+#ifdef LOAD_ARGS_REVERSED
+ for (i = num_actuals - 1; i >= 0; i--)
+#else
+ for (i = 0; i < num_actuals; i++)
+#endif
+ {
+ rtx reg = args[i].reg;
+ int partial = args[i].partial;
+ int nregs;
+
+ if (reg)
+ {
+ /* Set to non-negative if must move a word at a time, even if just
+ one word (e.g, partial == 1 && mode == DFmode). Set to -1 if
+ we just use a normal move insn. This value can be zero if the
+ argument is a zero size structure with no fields. */
+ nregs = (partial ? partial
+ : (TYPE_MODE (TREE_TYPE (args[i].tree_value)) == BLKmode
+ ? ((int_size_in_bytes (TREE_TYPE (args[i].tree_value))
+ + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD)
+ : -1));
+
+ /* Handle calls that pass values in multiple non-contiguous
+ locations. The Irix 6 ABI has examples of this. */
+
+ if (GET_CODE (reg) == PARALLEL)
+ {
+ emit_group_load (reg, args[i].value,
+ int_size_in_bytes (TREE_TYPE (args[i].tree_value)),
+ (TYPE_ALIGN (TREE_TYPE (args[i].tree_value))
+ / BITS_PER_UNIT));
+ }
+
+ /* If simple case, just do move. If normal partial, store_one_arg
+ has already loaded the register for us. In all other cases,
+ load the register(s) from memory. */
+
+ else if (nregs == -1)
+ emit_move_insn (reg, args[i].value);
+
+ /* If we have pre-computed the values to put in the registers in
+ the case of non-aligned structures, copy them in now. */
+
+ else if (args[i].n_aligned_regs != 0)
+ for (j = 0; j < args[i].n_aligned_regs; j++)
+ emit_move_insn (gen_rtx_REG (word_mode, REGNO (reg) + j),
+ args[i].aligned_regs[j]);
+
+ else if (partial == 0 || args[i].pass_on_stack)
+ move_block_to_reg (REGNO (reg),
+ validize_mem (args[i].value), nregs,
+ args[i].mode);
+
+ /* Handle calls that pass values in multiple non-contiguous
+ locations. The Irix 6 ABI has examples of this. */
+ if (GET_CODE (reg) == PARALLEL)
+ use_group_regs (call_fusage, reg);
+ else if (nregs == -1)
+ use_reg (call_fusage, reg);
+ else
+ use_regs (call_fusage, REGNO (reg), nregs == 0 ? 1 : nregs);
+ }
+ }
+}
+
/* Generate all the code for a function call
and return an rtx for its value.
Store the value in TARGET (specified as an rtx) if convenient.
@@ -517,8 +1544,6 @@ expand_call (exp, target, ignore)
/* Number of named args. Args after this are anonymous ones
and they must all go on the stack. */
int n_named_args;
- /* Count arg position in order args appear. */
- int argpos;
/* Vector of information about each argument.
Arguments are numbered in the order they will be pushed,
@@ -528,7 +1553,7 @@ expand_call (exp, target, ignore)
/* Total size in bytes of all the stack-parms scanned so far. */
struct args_size args_size;
/* Size of arguments before any adjustments (such as rounding). */
- struct args_size original_args_size;
+ int unadjusted_args_size;
/* Data on reg parms scanned so far. */
CUMULATIVE_ARGS args_so_far;
/* Nonzero if a reg parm has been scanned. */
@@ -550,8 +1575,6 @@ expand_call (exp, target, ignore)
/* Size of the stack reserved for parameter registers. */
int reg_parm_stack_space = 0;
- /* 1 if scanning parms front to back, -1 if scanning back to front. */
- int inc;
/* Address of space preallocated for stack parms
(on machines that lack push insns), or 0 if space not preallocated. */
rtx argblock = 0;
@@ -589,13 +1612,13 @@ expand_call (exp, target, ignore)
int old_inhibit_defer_pop = inhibit_defer_pop;
rtx call_fusage = 0;
register tree p;
- register int i, j;
+ register int i;
/* The value of the function call can be put in a hard register. But
if -fcheck-memory-usage, code which invokes functions (and thus
damages some hard registers) can be inserted before using the value.
So, target is always a pseudo-register in that case. */
- if (flag_check_memory_usage)
+ if (current_function_check_memory_usage)
target = 0;
/* See if we can find a DECL-node for the actual function.
@@ -613,7 +1636,7 @@ expand_call (exp, target, ignore)
&& fndecl != current_function_decl
&& DECL_INLINE (fndecl)
&& DECL_SAVED_INSNS (fndecl)
- && DECL_SAVED_INSNS (fndecl)->inlinable)
+ && RTX_INTEGRATED_P (DECL_SAVED_INSNS (fndecl)))
is_integrable = 1;
else if (! TREE_ADDRESSABLE (fndecl))
{
@@ -754,7 +1777,7 @@ expand_call (exp, target, ignore)
nonzero then there is a call and it is not necessary
to scan the insns. */
- if (DECL_SAVED_INSNS (fndecl)->outgoing_args_size == 0)
+ if (OUTGOING_ARGS_SIZE (DECL_SAVED_INSNS (fndecl)) == 0)
for (insn = first_insn; insn; insn = NEXT_INSN (insn))
if (GET_CODE (insn) == CALL_INSN)
break;
@@ -778,9 +1801,8 @@ expand_call (exp, target, ignore)
value of reg_parm_stack_space is wrong, but gives
correct results on all supported machines. */
- int adjust =
- (DECL_SAVED_INSNS (fndecl)->outgoing_args_size
- + reg_parm_stack_space);
+ int adjust = (OUTGOING_ARGS_SIZE (DECL_SAVED_INSNS (fndecl))
+ + reg_parm_stack_space);
start_sequence ();
emit_stack_save (SAVE_BLOCK, &old_stack_level, NULL_RTX);
@@ -814,103 +1836,30 @@ expand_call (exp, target, ignore)
mark_addressable (fndecl);
}
- /* When calling a const function, we must pop the stack args right away,
- so that the pop is deleted or moved with the call. */
- if (is_const)
- NO_DEFER_POP;
-
function_call_count++;
if (fndecl && DECL_NAME (fndecl))
name = IDENTIFIER_POINTER (DECL_NAME (fndecl));
-#if 0
- /* Unless it's a call to a specific function that isn't alloca,
- if it has one argument, we must assume it might be alloca. */
-
- may_be_alloca
- = (!(fndecl != 0 && strcmp (name, "alloca"))
- && actparms != 0
- && TREE_CHAIN (actparms) == 0);
-#else
- /* We assume that alloca will always be called by name. It
- makes no sense to pass it as a pointer-to-function to
- anything that does not understand its behavior. */
- may_be_alloca
- = (name && ((IDENTIFIER_LENGTH (DECL_NAME (fndecl)) == 6
- && name[0] == 'a'
- && ! strcmp (name, "alloca"))
- || (IDENTIFIER_LENGTH (DECL_NAME (fndecl)) == 16
- && name[0] == '_'
- && ! strcmp (name, "__builtin_alloca"))));
-#endif
-
/* See if this is a call to a function that can return more than once
- or a call to longjmp. */
-
- returns_twice = 0;
- is_longjmp = 0;
- is_malloc = 0;
-
- if (name != 0 && IDENTIFIER_LENGTH (DECL_NAME (fndecl)) <= 17
- /* Exclude functions not at the file scope, or not `extern',
- since they are not the magic functions we would otherwise
- think they are. */
- && DECL_CONTEXT (fndecl) == NULL_TREE && TREE_PUBLIC (fndecl))
- {
- char *tname = name;
-
- /* Disregard prefix _, __ or __x. */
- if (name[0] == '_')
- {
- if (name[1] == '_' && name[2] == 'x')
- tname += 3;
- else if (name[1] == '_')
- tname += 2;
- else
- tname += 1;
- }
-
- if (tname[0] == 's')
- {
- returns_twice
- = ((tname[1] == 'e'
- && (! strcmp (tname, "setjmp")
- || ! strcmp (tname, "setjmp_syscall")))
- || (tname[1] == 'i'
- && ! strcmp (tname, "sigsetjmp"))
- || (tname[1] == 'a'
- && ! strcmp (tname, "savectx")));
- if (tname[1] == 'i'
- && ! strcmp (tname, "siglongjmp"))
- is_longjmp = 1;
- }
- else if ((tname[0] == 'q' && tname[1] == 's'
- && ! strcmp (tname, "qsetjmp"))
- || (tname[0] == 'v' && tname[1] == 'f'
- && ! strcmp (tname, "vfork")))
- returns_twice = 1;
-
- else if (tname[0] == 'l' && tname[1] == 'o'
- && ! strcmp (tname, "longjmp"))
- is_longjmp = 1;
- /* XXX should have "malloc" attribute on functions instead
- of recognizing them by name. */
- else if (! strcmp (tname, "malloc")
- || ! strcmp (tname, "calloc")
- || ! strcmp (tname, "realloc")
- /* Note use of NAME rather than TNAME here. These functions
- are only reserved when preceded with __. */
- || ! strcmp (name, "__vn") /* mangled __builtin_vec_new */
- || ! strcmp (name, "__nw") /* mangled __builtin_new */
- || ! strcmp (name, "__builtin_new")
- || ! strcmp (name, "__builtin_vec_new"))
- is_malloc = 1;
- }
+ or a call to longjmp or malloc. */
+ special_function_p (name, fndecl, &returns_twice, &is_longjmp,
+ &is_malloc, &may_be_alloca);
if (may_be_alloca)
current_function_calls_alloca = 1;
+ /* Operand 0 is a pointer-to-function; get the type of the function. */
+ funtype = TREE_TYPE (TREE_OPERAND (exp, 0));
+ if (! POINTER_TYPE_P (funtype))
+ abort ();
+ funtype = TREE_TYPE (funtype);
+
+ /* When calling a const function, we must pop the stack args right away,
+ so that the pop is deleted or moved with the call. */
+ if (is_const)
+ NO_DEFER_POP;
+
/* Don't let pending stack adjusts add up to too much.
Also, do all pending adjustments now
if there is any chance this might be a call to alloca. */
@@ -919,12 +1868,6 @@ expand_call (exp, target, ignore)
|| (pending_stack_adjust > 0 && may_be_alloca))
do_pending_stack_adjust ();
- /* Operand 0 is a pointer-to-function; get the type of the function. */
- funtype = TREE_TYPE (TREE_OPERAND (exp, 0));
- if (TREE_CODE (funtype) != POINTER_TYPE)
- abort ();
- funtype = TREE_TYPE (funtype);
-
/* Push the temporary stack slot level so that we can free any temporaries
we make. */
push_temp_slots ();
@@ -972,21 +1915,18 @@ expand_call (exp, target, ignore)
(If no anonymous args follow, the result of list_length is actually
one too large. This is harmless.)
- If SETUP_INCOMING_VARARGS is defined and STRICT_ARGUMENT_NAMING is zero,
- this machine will be able to place unnamed args that were passed in
+ If PRETEND_OUTGOING_VARARGS_NAMED is set and STRICT_ARGUMENT_NAMING is
+ zero, this machine will be able to place unnamed args that were passed in
registers into the stack. So treat all args as named. This allows the
insns emitting for a specific argument list to be independent of the
function declaration.
- If SETUP_INCOMING_VARARGS is not defined, we do not have any reliable
+ If PRETEND_OUTGOING_VARARGS_NAMED is not set, we do not have any reliable
way to pass unnamed args in registers, so we must force them into
memory. */
if ((STRICT_ARGUMENT_NAMING
-#ifndef SETUP_INCOMING_VARARGS
- || 1
-#endif
- )
+ || ! PRETEND_OUTGOING_VARARGS_NAMED)
&& TYPE_ARG_TYPES (funtype) != 0)
n_named_args
= (list_length (TYPE_ARG_TYPES (funtype))
@@ -1002,232 +1942,19 @@ expand_call (exp, target, ignore)
args = (struct arg_data *) alloca (num_actuals * sizeof (struct arg_data));
bzero ((char *) args, num_actuals * sizeof (struct arg_data));
- args_size.constant = 0;
- args_size.var = 0;
-
- /* In this loop, we consider args in the order they are written.
- We fill up ARGS from the front or from the back if necessary
- so that in any case the first arg to be pushed ends up at the front. */
-
-#ifdef PUSH_ARGS_REVERSED
- i = num_actuals - 1, inc = -1;
- /* In this case, must reverse order of args
- so that we compute and push the last arg first. */
-#else
- i = 0, inc = 1;
-#endif
-
- /* I counts args in order (to be) pushed; ARGPOS counts in order written. */
- for (p = actparms, argpos = 0; p; p = TREE_CHAIN (p), i += inc, argpos++)
- {
- tree type = TREE_TYPE (TREE_VALUE (p));
- int unsignedp;
- enum machine_mode mode;
-
- args[i].tree_value = TREE_VALUE (p);
-
- /* Replace erroneous argument with constant zero. */
- if (type == error_mark_node || TYPE_SIZE (type) == 0)
- args[i].tree_value = integer_zero_node, type = integer_type_node;
-
- /* If TYPE is a transparent union, pass things the way we would
- pass the first field of the union. We have already verified that
- the modes are the same. */
- if (TYPE_TRANSPARENT_UNION (type))
- type = TREE_TYPE (TYPE_FIELDS (type));
-
- /* Decide where to pass this arg.
-
- args[i].reg is nonzero if all or part is passed in registers.
-
- args[i].partial is nonzero if part but not all is passed in registers,
- and the exact value says how many words are passed in registers.
-
- args[i].pass_on_stack is nonzero if the argument must at least be
- computed on the stack. It may then be loaded back into registers
- if args[i].reg is nonzero.
-
- These decisions are driven by the FUNCTION_... macros and must agree
- with those made by function.c. */
-
- /* See if this argument should be passed by invisible reference. */
- if ((TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST
- && contains_placeholder_p (TYPE_SIZE (type)))
- || TREE_ADDRESSABLE (type)
-#ifdef FUNCTION_ARG_PASS_BY_REFERENCE
- || FUNCTION_ARG_PASS_BY_REFERENCE (args_so_far, TYPE_MODE (type),
- type, argpos < n_named_args)
-#endif
- )
- {
- /* If we're compiling a thunk, pass through invisible
- references instead of making a copy. */
- if (current_function_is_thunk
-#ifdef FUNCTION_ARG_CALLEE_COPIES
- || (FUNCTION_ARG_CALLEE_COPIES (args_so_far, TYPE_MODE (type),
- type, argpos < n_named_args)
- /* If it's in a register, we must make a copy of it too. */
- /* ??? Is this a sufficient test? Is there a better one? */
- && !(TREE_CODE (args[i].tree_value) == VAR_DECL
- && REG_P (DECL_RTL (args[i].tree_value)))
- && ! TREE_ADDRESSABLE (type))
-#endif
- )
- {
- args[i].tree_value = build1 (ADDR_EXPR,
- build_pointer_type (type),
- args[i].tree_value);
- type = build_pointer_type (type);
- }
- else
- {
- /* We make a copy of the object and pass the address to the
- function being called. */
- rtx copy;
-
- if (TYPE_SIZE (type) == 0
- || TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST
- || (flag_stack_check && ! STACK_CHECK_BUILTIN
- && (TREE_INT_CST_HIGH (TYPE_SIZE (type)) != 0
- || (TREE_INT_CST_LOW (TYPE_SIZE (type))
- > STACK_CHECK_MAX_VAR_SIZE * BITS_PER_UNIT))))
- {
- /* This is a variable-sized object. Make space on the stack
- for it. */
- rtx size_rtx = expr_size (TREE_VALUE (p));
-
- if (old_stack_level == 0)
- {
- emit_stack_save (SAVE_BLOCK, &old_stack_level, NULL_RTX);
- old_pending_adj = pending_stack_adjust;
- pending_stack_adjust = 0;
- }
-
- copy = gen_rtx_MEM (BLKmode,
- allocate_dynamic_stack_space (size_rtx,
- NULL_RTX,
- TYPE_ALIGN (type)));
- }
- else
- {
- int size = int_size_in_bytes (type);
- copy = assign_stack_temp (TYPE_MODE (type), size, 0);
- }
-
- MEM_IN_STRUCT_P (copy) = AGGREGATE_TYPE_P (type);
-
- store_expr (args[i].tree_value, copy, 0);
- is_const = 0;
-
- args[i].tree_value = build1 (ADDR_EXPR,
- build_pointer_type (type),
- make_tree (type, copy));
- type = build_pointer_type (type);
- }
- }
-
- mode = TYPE_MODE (type);
- unsignedp = TREE_UNSIGNED (type);
-
-#ifdef PROMOTE_FUNCTION_ARGS
- mode = promote_mode (type, mode, &unsignedp, 1);
-#endif
-
- args[i].unsignedp = unsignedp;
- args[i].mode = mode;
- args[i].reg = FUNCTION_ARG (args_so_far, mode, type,
- argpos < n_named_args);
-#ifdef FUNCTION_ARG_PARTIAL_NREGS
- if (args[i].reg)
- args[i].partial
- = FUNCTION_ARG_PARTIAL_NREGS (args_so_far, mode, type,
- argpos < n_named_args);
-#endif
-
- args[i].pass_on_stack = MUST_PASS_IN_STACK (mode, type);
-
- /* If FUNCTION_ARG returned a (parallel [(expr_list (nil) ...) ...]),
- it means that we are to pass this arg in the register(s) designated
- by the PARALLEL, but also to pass it in the stack. */
- if (args[i].reg && GET_CODE (args[i].reg) == PARALLEL
- && XEXP (XVECEXP (args[i].reg, 0, 0), 0) == 0)
- args[i].pass_on_stack = 1;
-
- /* If this is an addressable type, we must preallocate the stack
- since we must evaluate the object into its final location.
-
- If this is to be passed in both registers and the stack, it is simpler
- to preallocate. */
- if (TREE_ADDRESSABLE (type)
- || (args[i].pass_on_stack && args[i].reg != 0))
- must_preallocate = 1;
-
- /* If this is an addressable type, we cannot pre-evaluate it. Thus,
- we cannot consider this function call constant. */
- if (TREE_ADDRESSABLE (type))
- is_const = 0;
-
- /* Compute the stack-size of this argument. */
- if (args[i].reg == 0 || args[i].partial != 0
- || reg_parm_stack_space > 0
- || args[i].pass_on_stack)
- locate_and_pad_parm (mode, type,
-#ifdef STACK_PARMS_IN_REG_PARM_AREA
- 1,
-#else
- args[i].reg != 0,
-#endif
- fndecl, &args_size, &args[i].offset,
- &args[i].size);
-
-#ifndef ARGS_GROW_DOWNWARD
- args[i].slot_offset = args_size;
-#endif
-
- /* If a part of the arg was put into registers,
- don't include that part in the amount pushed. */
- if (reg_parm_stack_space == 0 && ! args[i].pass_on_stack)
- args[i].size.constant -= ((args[i].partial * UNITS_PER_WORD)
- / (PARM_BOUNDARY / BITS_PER_UNIT)
- * (PARM_BOUNDARY / BITS_PER_UNIT));
-
- /* Update ARGS_SIZE, the total stack space for args so far. */
-
- args_size.constant += args[i].size.constant;
- if (args[i].size.var)
- {
- ADD_PARM_SIZE (args_size, args[i].size.var);
- }
-
- /* Since the slot offset points to the bottom of the slot,
- we must record it after incrementing if the args grow down. */
-#ifdef ARGS_GROW_DOWNWARD
- args[i].slot_offset = args_size;
-
- args[i].slot_offset.constant = -args_size.constant;
- if (args_size.var)
- {
- SUB_PARM_SIZE (args[i].slot_offset, args_size.var);
- }
-#endif
-
- /* Increment ARGS_SO_FAR, which has info about which arg-registers
- have been used, etc. */
-
- FUNCTION_ARG_ADVANCE (args_so_far, TYPE_MODE (type), type,
- argpos < n_named_args);
- }
+ /* Build up entries inthe ARGS array, compute the size of the arguments
+ into ARGS_SIZE, etc. */
+ initialize_argument_information (num_actuals, args, &args_size, n_named_args,
+ actparms, fndecl, &args_so_far,
+ reg_parm_stack_space, &old_stack_level,
+ &old_pending_adj, &must_preallocate,
+ &is_const);
#ifdef FINAL_REG_PARM_STACK_SPACE
reg_parm_stack_space = FINAL_REG_PARM_STACK_SPACE (args_size.constant,
args_size.var);
#endif
- /* Compute the actual size of the argument block required. The variable
- and constant sizes must be combined, the size may have to be rounded,
- and there may be a minimum required size. */
-
- original_args_size = args_size;
if (args_size.var)
{
/* If this function requires a variable-sized argument list, don't try to
@@ -1237,94 +1964,17 @@ expand_call (exp, target, ignore)
is_const = 0;
must_preallocate = 1;
-
- args_size.var = ARGS_SIZE_TREE (args_size);
- args_size.constant = 0;
-
-#ifdef STACK_BOUNDARY
- if (STACK_BOUNDARY != BITS_PER_UNIT)
- args_size.var = round_up (args_size.var, STACK_BYTES);
-#endif
-
- if (reg_parm_stack_space > 0)
- {
- args_size.var
- = size_binop (MAX_EXPR, args_size.var,
- size_int (reg_parm_stack_space));
-
-#ifndef OUTGOING_REG_PARM_STACK_SPACE
- /* The area corresponding to register parameters is not to count in
- the size of the block we need. So make the adjustment. */
- args_size.var
- = size_binop (MINUS_EXPR, args_size.var,
- size_int (reg_parm_stack_space));
-#endif
- }
- }
- else
- {
-#ifdef STACK_BOUNDARY
- args_size.constant = (((args_size.constant + (STACK_BYTES - 1))
- / STACK_BYTES) * STACK_BYTES);
-#endif
-
- args_size.constant = MAX (args_size.constant,
- reg_parm_stack_space);
-
-#ifdef MAYBE_REG_PARM_STACK_SPACE
- if (reg_parm_stack_space == 0)
- args_size.constant = 0;
-#endif
-
-#ifndef OUTGOING_REG_PARM_STACK_SPACE
- args_size.constant -= reg_parm_stack_space;
-#endif
}
- /* See if we have or want to preallocate stack space.
-
- If we would have to push a partially-in-regs parm
- before other stack parms, preallocate stack space instead.
-
- If the size of some parm is not a multiple of the required stack
- alignment, we must preallocate.
-
- If the total size of arguments that would otherwise create a copy in
- a temporary (such as a CALL) is more than half the total argument list
- size, preallocation is faster.
-
- Another reason to preallocate is if we have a machine (like the m88k)
- where stack alignment is required to be maintained between every
- pair of insns, not just when the call is made. However, we assume here
- that such machines either do not have push insns (and hence preallocation
- would occur anyway) or the problem is taken care of with
- PUSH_ROUNDING. */
-
- if (! must_preallocate)
- {
- int partial_seen = 0;
- int copy_to_evaluate_size = 0;
-
- for (i = 0; i < num_actuals && ! must_preallocate; i++)
- {
- if (args[i].partial > 0 && ! args[i].pass_on_stack)
- partial_seen = 1;
- else if (partial_seen && args[i].reg == 0)
- must_preallocate = 1;
-
- if (TYPE_MODE (TREE_TYPE (args[i].tree_value)) == BLKmode
- && (TREE_CODE (args[i].tree_value) == CALL_EXPR
- || TREE_CODE (args[i].tree_value) == TARGET_EXPR
- || TREE_CODE (args[i].tree_value) == COND_EXPR
- || TREE_ADDRESSABLE (TREE_TYPE (args[i].tree_value))))
- copy_to_evaluate_size
- += int_size_in_bytes (TREE_TYPE (args[i].tree_value));
- }
+ /* Compute the actual size of the argument block required. The variable
+ and constant sizes must be combined, the size may have to be rounded,
+ and there may be a minimum required size. */
+ unadjusted_args_size
+ = compute_argument_block_size (reg_parm_stack_space, &args_size);
- if (copy_to_evaluate_size * 2 >= args_size.constant
- && args_size.constant > 0)
- must_preallocate = 1;
- }
+ /* Now make final decision about preallocating stack space. */
+ must_preallocate = finalize_must_preallocate (must_preallocate,
+ num_actuals, args, &args_size);
/* If the structure value address will reference the stack pointer, we must
stabilize it. We don't need to do this if we know that we are not going
@@ -1340,51 +1990,9 @@ expand_call (exp, target, ignore)
))
structure_value_addr = copy_to_reg (structure_value_addr);
- /* If this function call is cse'able, precompute all the parameters.
- Note that if the parameter is constructed into a temporary, this will
- cause an additional copy because the parameter will be constructed
- into a temporary location and then copied into the outgoing arguments.
- If a parameter contains a call to alloca and this function uses the
- stack, precompute the parameter. */
-
- /* If we preallocated the stack space, and some arguments must be passed
- on the stack, then we must precompute any parameter which contains a
- function call which will store arguments on the stack.
- Otherwise, evaluating the parameter may clobber previous parameters
- which have already been stored into the stack. */
-
- for (i = 0; i < num_actuals; i++)
- if (is_const
- || ((args_size.var != 0 || args_size.constant != 0)
- && calls_function (args[i].tree_value, 1))
- || (must_preallocate && (args_size.var != 0 || args_size.constant != 0)
- && calls_function (args[i].tree_value, 0)))
- {
- /* If this is an addressable type, we cannot pre-evaluate it. */
- if (TREE_ADDRESSABLE (TREE_TYPE (args[i].tree_value)))
- abort ();
-
- push_temp_slots ();
-
- args[i].initial_value = args[i].value
- = expand_expr (args[i].tree_value, NULL_RTX, VOIDmode, 0);
-
- preserve_temp_slots (args[i].value);
- pop_temp_slots ();
-
- /* ANSI doesn't require a sequence point here,
- but PCC has one, so this will avoid some problems. */
- emit_queue ();
-
- args[i].initial_value = args[i].value
- = protect_from_queue (args[i].initial_value, 0);
-
- if (TYPE_MODE (TREE_TYPE (args[i].tree_value)) != args[i].mode)
- args[i].value
- = convert_modes (args[i].mode,
- TYPE_MODE (TREE_TYPE (args[i].tree_value)),
- args[i].value, args[i].unsignedp);
- }
+ /* Precompute any arguments as needed. */
+ precompute_arguments (is_const, must_preallocate, num_actuals,
+ args, &args_size);
/* Now we are about to start emitting insns that can be deleted
if a libcall is deleted. */
@@ -1547,55 +2155,14 @@ expand_call (exp, target, ignore)
}
#endif
+ compute_argument_addresses (args, argblock, num_actuals);
- /* If we preallocated stack space, compute the address of each argument.
- We need not ensure it is a valid memory address here; it will be
- validized when it is used. */
- if (argblock)
- {
- rtx arg_reg = argblock;
- int arg_offset = 0;
-
- if (GET_CODE (argblock) == PLUS)
- arg_reg = XEXP (argblock, 0), arg_offset = INTVAL (XEXP (argblock, 1));
-
- for (i = 0; i < num_actuals; i++)
- {
- rtx offset = ARGS_SIZE_RTX (args[i].offset);
- rtx slot_offset = ARGS_SIZE_RTX (args[i].slot_offset);
- rtx addr;
-
- /* Skip this parm if it will not be passed on the stack. */
- if (! args[i].pass_on_stack && args[i].reg != 0)
- continue;
-
- if (GET_CODE (offset) == CONST_INT)
- addr = plus_constant (arg_reg, INTVAL (offset));
- else
- addr = gen_rtx_PLUS (Pmode, arg_reg, offset);
-
- addr = plus_constant (addr, arg_offset);
- args[i].stack = gen_rtx_MEM (args[i].mode, addr);
- MEM_IN_STRUCT_P (args[i].stack)
- = AGGREGATE_TYPE_P (TREE_TYPE (args[i].tree_value));
-
- if (GET_CODE (slot_offset) == CONST_INT)
- addr = plus_constant (arg_reg, INTVAL (slot_offset));
- else
- addr = gen_rtx_PLUS (Pmode, arg_reg, slot_offset);
-
- addr = plus_constant (addr, arg_offset);
- args[i].stack_slot = gen_rtx_MEM (args[i].mode, addr);
- }
- }
-
#ifdef PUSH_ARGS_REVERSED
-#ifdef STACK_BOUNDARY
+#ifdef PREFERRED_STACK_BOUNDARY
/* If we push args individually in reverse order, perform stack alignment
before the first push (the last arg). */
if (argblock == 0)
- anti_adjust_stack (GEN_INT (args_size.constant
- - original_args_size.constant));
+ anti_adjust_stack (GEN_INT (args_size.constant - unadjusted_args_size));
#endif
#endif
@@ -1604,34 +2171,7 @@ expand_call (exp, target, ignore)
if (argblock)
NO_DEFER_POP;
- /* Get the function to call, in the form of RTL. */
- if (fndecl)
- {
- /* If this is the first use of the function, see if we need to
- make an external definition for it. */
- if (! TREE_USED (fndecl))
- {
- assemble_external (fndecl);
- TREE_USED (fndecl) = 1;
- }
-
- /* Get a SYMBOL_REF rtx for the function address. */
- funexp = XEXP (DECL_RTL (fndecl), 0);
- }
- else
- /* Generate an rtx (probably a pseudo-register) for the address. */
- {
- push_temp_slots ();
- funexp = expand_expr (TREE_OPERAND (exp, 0), NULL_RTX, VOIDmode, 0);
- pop_temp_slots (); /* FUNEXP can't be BLKmode */
-
- /* Check the function is executable. */
- if (flag_check_memory_usage)
- emit_library_call (chkr_check_exec_libfunc, 1,
- VOIDmode, 1,
- funexp, ptr_mode);
- emit_queue ();
- }
+ funexp = rtx_for_function_call (fndecl, exp);
/* Figure out the register where the value, if any, will come back. */
valreg = 0;
@@ -1647,115 +2187,16 @@ expand_call (exp, target, ignore)
/* Precompute all register parameters. It isn't safe to compute anything
once we have started filling any specific hard regs. */
- reg_parm_seen = 0;
- for (i = 0; i < num_actuals; i++)
- if (args[i].reg != 0 && ! args[i].pass_on_stack)
- {
- reg_parm_seen = 1;
-
- if (args[i].value == 0)
- {
- push_temp_slots ();
- args[i].value = expand_expr (args[i].tree_value, NULL_RTX,
- VOIDmode, 0);
- preserve_temp_slots (args[i].value);
- pop_temp_slots ();
-
- /* ANSI doesn't require a sequence point here,
- but PCC has one, so this will avoid some problems. */
- emit_queue ();
- }
-
- /* If we are to promote the function arg to a wider mode,
- do it now. */
-
- if (args[i].mode != TYPE_MODE (TREE_TYPE (args[i].tree_value)))
- args[i].value
- = convert_modes (args[i].mode,
- TYPE_MODE (TREE_TYPE (args[i].tree_value)),
- args[i].value, args[i].unsignedp);
-
- /* If the value is expensive, and we are inside an appropriately
- short loop, put the value into a pseudo and then put the pseudo
- into the hard reg.
-
- For small register classes, also do this if this call uses
- register parameters. This is to avoid reload conflicts while
- loading the parameters registers. */
-
- if ((! (GET_CODE (args[i].value) == REG
- || (GET_CODE (args[i].value) == SUBREG
- && GET_CODE (SUBREG_REG (args[i].value)) == REG)))
- && args[i].mode != BLKmode
- && rtx_cost (args[i].value, SET) > 2
- && ((SMALL_REGISTER_CLASSES && reg_parm_seen)
- || preserve_subexpressions_p ()))
- args[i].value = copy_to_mode_reg (args[i].mode, args[i].value);
- }
+ precompute_register_parameters (num_actuals, args, &reg_parm_seen);
#if defined(ACCUMULATE_OUTGOING_ARGS) && defined(REG_PARM_STACK_SPACE)
- /* The argument list is the property of the called routine and it
- may clobber it. If the fixed area has been used for previous
- parameters, we must save and restore it.
-
- Here we compute the boundary of the that needs to be saved, if any. */
-
-#ifdef ARGS_GROW_DOWNWARD
- for (i = 0; i < reg_parm_stack_space + 1; i++)
-#else
- for (i = 0; i < reg_parm_stack_space; i++)
+ /* Save the fixed argument area if it's part of the caller's frame and
+ is clobbered by argument setup for this call. */
+ save_area = save_fixed_argument_area (reg_parm_stack_space, argblock,
+ &low_to_save, &high_to_save);
#endif
- {
- if (i >= highest_outgoing_arg_in_use
- || stack_usage_map[i] == 0)
- continue;
-
- if (low_to_save == -1)
- low_to_save = i;
-
- high_to_save = i;
- }
-
- if (low_to_save >= 0)
- {
- int num_to_save = high_to_save - low_to_save + 1;
- enum machine_mode save_mode
- = mode_for_size (num_to_save * BITS_PER_UNIT, MODE_INT, 1);
- rtx stack_area;
-
- /* If we don't have the required alignment, must do this in BLKmode. */
- if ((low_to_save & (MIN (GET_MODE_SIZE (save_mode),
- BIGGEST_ALIGNMENT / UNITS_PER_WORD) - 1)))
- save_mode = BLKmode;
-
-#ifdef ARGS_GROW_DOWNWARD
- stack_area = gen_rtx_MEM (save_mode,
- memory_address (save_mode,
- plus_constant (argblock,
- - high_to_save)));
-#else
- stack_area = gen_rtx_MEM (save_mode,
- memory_address (save_mode,
- plus_constant (argblock,
- low_to_save)));
-#endif
- if (save_mode == BLKmode)
- {
- save_area = assign_stack_temp (BLKmode, num_to_save, 0);
- MEM_IN_STRUCT_P (save_area) = 0;
- emit_block_move (validize_mem (save_area), stack_area,
- GEN_INT (num_to_save),
- PARM_BOUNDARY / BITS_PER_UNIT);
- }
- else
- {
- save_area = gen_reg_rtx (save_mode);
- emit_move_insn (save_area, stack_area);
- }
- }
-#endif
-
+
/* Now store (and compute if necessary) all non-register parms.
These come before register parms, since they can require block-moves,
@@ -1766,69 +2207,14 @@ expand_call (exp, target, ignore)
for (i = 0; i < num_actuals; i++)
if (args[i].reg == 0 || args[i].pass_on_stack)
store_one_arg (&args[i], argblock, may_be_alloca,
- args_size.var != 0, fndecl, reg_parm_stack_space);
+ args_size.var != 0, reg_parm_stack_space);
/* If we have a parm that is passed in registers but not in memory
and whose alignment does not permit a direct copy into registers,
make a group of pseudos that correspond to each register that we
will later fill. */
-
if (STRICT_ALIGNMENT)
- for (i = 0; i < num_actuals; i++)
- if (args[i].reg != 0 && ! args[i].pass_on_stack
- && args[i].mode == BLKmode
- && (TYPE_ALIGN (TREE_TYPE (args[i].tree_value))
- < MIN (BIGGEST_ALIGNMENT, BITS_PER_WORD)))
- {
- int bytes = int_size_in_bytes (TREE_TYPE (args[i].tree_value));
- int big_endian_correction = 0;
-
- args[i].n_aligned_regs
- = args[i].partial ? args[i].partial
- : (bytes + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD;
-
- args[i].aligned_regs = (rtx *) alloca (sizeof (rtx)
- * args[i].n_aligned_regs);
-
- /* Structures smaller than a word are aligned to the least
- significant byte (to the right). On a BYTES_BIG_ENDIAN machine,
- this means we must skip the empty high order bytes when
- calculating the bit offset. */
- if (BYTES_BIG_ENDIAN && bytes < UNITS_PER_WORD)
- big_endian_correction = (BITS_PER_WORD - (bytes * BITS_PER_UNIT));
-
- for (j = 0; j < args[i].n_aligned_regs; j++)
- {
- rtx reg = gen_reg_rtx (word_mode);
- rtx word = operand_subword_force (args[i].value, j, BLKmode);
- int bitsize = MIN (bytes * BITS_PER_UNIT, BITS_PER_WORD);
- int bitalign = TYPE_ALIGN (TREE_TYPE (args[i].tree_value));
-
- args[i].aligned_regs[j] = reg;
-
- /* There is no need to restrict this code to loading items
- in TYPE_ALIGN sized hunks. The bitfield instructions can
- load up entire word sized registers efficiently.
-
- ??? This may not be needed anymore.
- We use to emit a clobber here but that doesn't let later
- passes optimize the instructions we emit. By storing 0 into
- the register later passes know the first AND to zero out the
- bitfield being set in the register is unnecessary. The store
- of 0 will be deleted as will at least the first AND. */
-
- emit_move_insn (reg, const0_rtx);
-
- bytes -= bitsize / BITS_PER_UNIT;
- store_bit_field (reg, bitsize, big_endian_correction, word_mode,
- extract_bit_field (word, bitsize, 0, 1,
- NULL_RTX, word_mode,
- word_mode,
- bitalign / BITS_PER_UNIT,
- BITS_PER_WORD),
- bitalign / BITS_PER_UNIT, BITS_PER_WORD);
- }
- }
+ store_unaligned_arguments_into_pseudos (args, num_actuals);
/* Now store any partially-in-registers parm.
This is the last place a block-move can happen. */
@@ -1836,15 +2222,14 @@ expand_call (exp, target, ignore)
for (i = 0; i < num_actuals; i++)
if (args[i].partial != 0 && ! args[i].pass_on_stack)
store_one_arg (&args[i], argblock, may_be_alloca,
- args_size.var != 0, fndecl, reg_parm_stack_space);
+ args_size.var != 0, reg_parm_stack_space);
#ifndef PUSH_ARGS_REVERSED
-#ifdef STACK_BOUNDARY
+#ifdef PREFERRED_STACK_BOUNDARY
/* If we pushed args in forward order, perform stack alignment
after pushing the last arg. */
if (argblock == 0)
- anti_adjust_stack (GEN_INT (args_size.constant
- - original_args_size.constant));
+ anti_adjust_stack (GEN_INT (args_size.constant - unadjusted_args_size));
#endif
#endif
@@ -1865,7 +2250,7 @@ expand_call (exp, target, ignore)
NULL_RTX)));
/* Mark the memory for the aggregate as write-only. */
- if (flag_check_memory_usage)
+ if (current_function_check_memory_usage)
emit_library_call (chkr_set_right_libfunc, 1,
VOIDmode, 3,
structure_value_addr, ptr_mode,
@@ -1879,76 +2264,7 @@ expand_call (exp, target, ignore)
funexp = prepare_call_address (funexp, fndecl, &call_fusage, reg_parm_seen);
- /* Now do the register loads required for any wholly-register parms or any
- parms which are passed both on the stack and in a register. Their
- expressions were already evaluated.
-
- Mark all register-parms as living through the call, putting these USE
- insns in the CALL_INSN_FUNCTION_USAGE field. */
-
-#ifdef LOAD_ARGS_REVERSED
- for (i = num_actuals - 1; i >= 0; i--)
-#else
- for (i = 0; i < num_actuals; i++)
-#endif
- {
- rtx reg = args[i].reg;
- int partial = args[i].partial;
- int nregs;
-
- if (reg)
- {
- /* Set to non-negative if must move a word at a time, even if just
- one word (e.g, partial == 1 && mode == DFmode). Set to -1 if
- we just use a normal move insn. This value can be zero if the
- argument is a zero size structure with no fields. */
- nregs = (partial ? partial
- : (TYPE_MODE (TREE_TYPE (args[i].tree_value)) == BLKmode
- ? ((int_size_in_bytes (TREE_TYPE (args[i].tree_value))
- + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD)
- : -1));
-
- /* Handle calls that pass values in multiple non-contiguous
- locations. The Irix 6 ABI has examples of this. */
-
- if (GET_CODE (reg) == PARALLEL)
- {
- emit_group_load (reg, args[i].value,
- int_size_in_bytes (TREE_TYPE (args[i].tree_value)),
- (TYPE_ALIGN (TREE_TYPE (args[i].tree_value))
- / BITS_PER_UNIT));
- }
-
- /* If simple case, just do move. If normal partial, store_one_arg
- has already loaded the register for us. In all other cases,
- load the register(s) from memory. */
-
- else if (nregs == -1)
- emit_move_insn (reg, args[i].value);
-
- /* If we have pre-computed the values to put in the registers in
- the case of non-aligned structures, copy them in now. */
-
- else if (args[i].n_aligned_regs != 0)
- for (j = 0; j < args[i].n_aligned_regs; j++)
- emit_move_insn (gen_rtx_REG (word_mode, REGNO (reg) + j),
- args[i].aligned_regs[j]);
-
- else if (partial == 0 || args[i].pass_on_stack)
- move_block_to_reg (REGNO (reg),
- validize_mem (args[i].value), nregs,
- args[i].mode);
-
- /* Handle calls that pass values in multiple non-contiguous
- locations. The Irix 6 ABI has examples of this. */
- if (GET_CODE (reg) == PARALLEL)
- use_group_regs (&call_fusage, reg);
- else if (nregs == -1)
- use_reg (&call_fusage, reg);
- else
- use_regs (&call_fusage, REGNO (reg), nregs == 0 ? 1 : nregs);
- }
- }
+ load_register_parameters (args, num_actuals, &call_fusage);
/* Perform postincrements before actually calling the function. */
emit_queue ();
@@ -2068,7 +2384,8 @@ expand_call (exp, target, ignore)
target = gen_rtx_MEM (TYPE_MODE (TREE_TYPE (exp)),
memory_address (TYPE_MODE (TREE_TYPE (exp)),
structure_value_addr));
- MEM_IN_STRUCT_P (target) = AGGREGATE_TYPE_P (TREE_TYPE (exp));
+ MEM_SET_IN_STRUCT_P (target,
+ AGGREGATE_TYPE_P (TREE_TYPE (exp)));
}
}
else if (pcc_struct_value)
@@ -2078,7 +2395,7 @@ expand_call (exp, target, ignore)
never use this value more than once in one expression. */
target = gen_rtx_MEM (TYPE_MODE (TREE_TYPE (exp)),
copy_to_reg (valreg));
- MEM_IN_STRUCT_P (target) = AGGREGATE_TYPE_P (TREE_TYPE (exp));
+ MEM_SET_IN_STRUCT_P (target, AGGREGATE_TYPE_P (TREE_TYPE (exp)));
}
/* Handle calls that return values in multiple non-contiguous locations.
The Irix 6 ABI has examples of this. */
@@ -2089,7 +2406,7 @@ expand_call (exp, target, ignore)
if (target == 0)
{
target = assign_stack_temp (TYPE_MODE (TREE_TYPE (exp)), bytes, 0);
- MEM_IN_STRUCT_P (target) = AGGREGATE_TYPE_P (TREE_TYPE (exp));
+ MEM_SET_IN_STRUCT_P (target, AGGREGATE_TYPE_P (TREE_TYPE (exp)));
preserve_temp_slots (target);
}
@@ -2149,31 +2466,10 @@ expand_call (exp, target, ignore)
{
#ifdef REG_PARM_STACK_SPACE
if (save_area)
- {
- enum machine_mode save_mode = GET_MODE (save_area);
-#ifdef ARGS_GROW_DOWNWARD
- rtx stack_area
- = gen_rtx_MEM (save_mode,
- memory_address (save_mode,
- plus_constant (argblock,
- - high_to_save)));
-#else
- rtx stack_area
- = gen_rtx_MEM (save_mode,
- memory_address (save_mode,
- plus_constant (argblock,
- low_to_save)));
+ restore_fixed_argument_area (save_area, argblock,
+ high_to_save, low_to_save);
#endif
- if (save_mode != BLKmode)
- emit_move_insn (stack_area, save_area);
- else
- emit_block_move (stack_area, validize_mem (save_area),
- GEN_INT (high_to_save - low_to_save + 1),
- PARM_BOUNDARY / BITS_PER_UNIT);
- }
-#endif
-
/* If we saved any argument areas, restore them. */
for (i = 0; i < num_actuals; i++)
if (args[i].save_area)
@@ -2201,11 +2497,16 @@ expand_call (exp, target, ignore)
Check for the handler slots since we might not have a save area
for non-local gotos. */
- if (may_be_alloca && nonlocal_goto_handler_slot != 0)
+ if (may_be_alloca && nonlocal_goto_handler_slots != 0)
emit_stack_save (SAVE_NONLOCAL, &nonlocal_goto_stack_level, NULL_RTX);
pop_temp_slots ();
+ /* Free up storage we no longer need. */
+ for (i = 0; i < num_actuals; ++i)
+ if (args[i].aligned_regs)
+ free (args[i].aligned_regs);
+
return target;
}
@@ -2233,7 +2534,7 @@ void
emit_library_call VPROTO((rtx orgfun, int no_queue, enum machine_mode outmode,
int nargs, ...))
{
-#ifndef __STDC__
+#ifndef ANSI_PROTOTYPES
rtx orgfun;
int no_queue;
enum machine_mode outmode;
@@ -2274,13 +2575,13 @@ emit_library_call VPROTO((rtx orgfun, int no_queue, enum machine_mode outmode,
#ifdef MAYBE_REG_PARM_STACK_SPACE
reg_parm_stack_space = MAYBE_REG_PARM_STACK_SPACE;
#else
- reg_parm_stack_space = REG_PARM_STACK_SPACE (fndecl);
+ reg_parm_stack_space = REG_PARM_STACK_SPACE ((tree) 0);
#endif
#endif
VA_START (p, nargs);
-#ifndef __STDC__
+#ifndef ANSI_PROTOTYPES
orgfun = va_arg (p, rtx);
no_queue = va_arg (p, int);
outmode = va_arg (p, enum machine_mode);
@@ -2387,7 +2688,7 @@ emit_library_call VPROTO((rtx orgfun, int no_queue, enum machine_mode outmode,
assemble_external_libcall (fun);
original_args_size = args_size;
-#ifdef STACK_BOUNDARY
+#ifdef PREFERRED_STACK_BOUNDARY
args_size.constant = (((args_size.constant + (STACK_BYTES - 1))
/ STACK_BYTES) * STACK_BYTES);
#endif
@@ -2455,7 +2756,7 @@ emit_library_call VPROTO((rtx orgfun, int no_queue, enum machine_mode outmode,
#endif
#ifdef PUSH_ARGS_REVERSED
-#ifdef STACK_BOUNDARY
+#ifdef PREFERRED_STACK_BOUNDARY
/* If we push args individually in reverse order, perform stack alignment
before the first push (the last arg). */
if (argblock == 0)
@@ -2521,7 +2822,6 @@ emit_library_call VPROTO((rtx orgfun, int no_queue, enum machine_mode outmode,
if (save_mode == BLKmode)
{
save_area = assign_stack_temp (BLKmode, num_to_save, 0);
- MEM_IN_STRUCT_P (save_area) = 0;
emit_block_move (validize_mem (save_area), stack_area,
GEN_INT (num_to_save),
PARM_BOUNDARY / BITS_PER_UNIT);
@@ -2600,7 +2900,7 @@ emit_library_call VPROTO((rtx orgfun, int no_queue, enum machine_mode outmode,
}
#ifndef PUSH_ARGS_REVERSED
-#ifdef STACK_BOUNDARY
+#ifdef PREFERRED_STACK_BOUNDARY
/* If we pushed args in forward order, perform stack alignment
after pushing the last arg. */
if (argblock == 0)
@@ -2724,7 +3024,7 @@ rtx
emit_library_call_value VPROTO((rtx orgfun, rtx value, int no_queue,
enum machine_mode outmode, int nargs, ...))
{
-#ifndef __STDC__
+#ifndef ANSI_PROTOTYPES
rtx orgfun;
rtx value;
int no_queue;
@@ -2773,13 +3073,13 @@ emit_library_call_value VPROTO((rtx orgfun, rtx value, int no_queue,
#ifdef MAYBE_REG_PARM_STACK_SPACE
reg_parm_stack_space = MAYBE_REG_PARM_STACK_SPACE;
#else
- reg_parm_stack_space = REG_PARM_STACK_SPACE (fndecl);
+ reg_parm_stack_space = REG_PARM_STACK_SPACE ((tree) 0);
#endif
#endif
VA_START (p, nargs);
-#ifndef __STDC__
+#ifndef ANSI_PROTOTYPES
orgfun = va_arg (p, rtx);
value = va_arg (p, rtx);
no_queue = va_arg (p, int);
@@ -2951,7 +3251,7 @@ emit_library_call_value VPROTO((rtx orgfun, rtx value, int no_queue,
assemble_external_libcall (fun);
original_args_size = args_size;
-#ifdef STACK_BOUNDARY
+#ifdef PREFERRED_STACK_BOUNDARY
args_size.constant = (((args_size.constant + (STACK_BYTES - 1))
/ STACK_BYTES) * STACK_BYTES);
#endif
@@ -3019,7 +3319,7 @@ emit_library_call_value VPROTO((rtx orgfun, rtx value, int no_queue,
#endif
#ifdef PUSH_ARGS_REVERSED
-#ifdef STACK_BOUNDARY
+#ifdef PREFERRED_STACK_BOUNDARY
/* If we push args individually in reverse order, perform stack alignment
before the first push (the last arg). */
if (argblock == 0)
@@ -3085,7 +3385,6 @@ emit_library_call_value VPROTO((rtx orgfun, rtx value, int no_queue,
if (save_mode == BLKmode)
{
save_area = assign_stack_temp (BLKmode, num_to_save, 0);
- MEM_IN_STRUCT_P (save_area) = 0;
emit_block_move (validize_mem (save_area), stack_area,
GEN_INT (num_to_save),
PARM_BOUNDARY / BITS_PER_UNIT);
@@ -3165,7 +3464,7 @@ emit_library_call_value VPROTO((rtx orgfun, rtx value, int no_queue,
}
#ifndef PUSH_ARGS_REVERSED
-#ifdef STACK_BOUNDARY
+#ifdef PREFERRED_STACK_BOUNDARY
/* If we pushed args in forward order, perform stack alignment
after pushing the last arg. */
if (argblock == 0)
@@ -3358,13 +3657,12 @@ target_for_arg (type, size, args_addr, offset)
FNDECL is the declaration of the function we are calling. */
static void
-store_one_arg (arg, argblock, may_be_alloca, variable_size, fndecl,
+store_one_arg (arg, argblock, may_be_alloca, variable_size,
reg_parm_stack_space)
struct arg_data *arg;
rtx argblock;
int may_be_alloca;
- int variable_size;
- tree fndecl;
+ int variable_size ATTRIBUTE_UNUSED;
int reg_parm_stack_space;
{
register tree pval = arg->tree_value;
@@ -3426,8 +3724,9 @@ store_one_arg (arg, argblock, may_be_alloca, variable_size, fndecl,
{
arg->save_area = assign_stack_temp (BLKmode,
arg->size.constant, 0);
- MEM_IN_STRUCT_P (arg->save_area)
- = AGGREGATE_TYPE_P (TREE_TYPE (arg->tree_value));
+ MEM_SET_IN_STRUCT_P (arg->save_area,
+ AGGREGATE_TYPE_P (TREE_TYPE
+ (arg->tree_value)));
preserve_temp_slots (arg->save_area);
emit_block_move (validize_mem (arg->save_area), stack_area,
GEN_INT (arg->size.constant),
@@ -3440,6 +3739,14 @@ store_one_arg (arg, argblock, may_be_alloca, variable_size, fndecl,
}
}
}
+
+ /* Now that we have saved any slots that will be overwritten by this
+ store, mark all slots this store will use. We must do this before
+ we actually expand the argument since the expansion itself may
+ trigger library calls which might need to use the same stack slot. */
+ if (argblock && ! variable_size && arg->stack)
+ for (i = lower_bound; i < upper_bound; i++)
+ stack_usage_map[i] = 1;
#endif
/* If this isn't going to be placed on both the stack and in registers,
@@ -3509,15 +3816,13 @@ store_one_arg (arg, argblock, may_be_alloca, variable_size, fndecl,
if (arg->value == arg->stack)
{
- /* If the value is already in the stack slot, we are done. */
- if (flag_check_memory_usage && GET_CODE (arg->stack) == MEM)
+ /* If the value is already in the stack slot, we are done moving
+ data. */
+ if (current_function_check_memory_usage && GET_CODE (arg->stack) == MEM)
{
- if (arg->mode == BLKmode)
- abort ();
-
emit_library_call (chkr_set_right_libfunc, 1, VOIDmode, 3,
XEXP (arg->stack, 0), ptr_mode,
- GEN_INT (GET_MODE_SIZE (arg->mode)),
+ ARGS_SIZE_RTX (arg->size),
TYPE_MODE (sizetype),
GEN_INT (MEMORY_USE_RW),
TYPE_MODE (integer_type_node));
@@ -3617,11 +3922,4 @@ store_one_arg (arg, argblock, may_be_alloca, variable_size, fndecl,
preserve_temp_slots (NULL_RTX);
free_temp_slots ();
pop_temp_slots ();
-
-#ifdef ACCUMULATE_OUTGOING_ARGS
- /* Now mark the segment we just used. */
- if (argblock && ! variable_size && arg->stack)
- for (i = lower_bound; i < upper_bound; i++)
- stack_usage_map[i] = 1;
-#endif
}
diff --git a/gcc/cccp.c b/gcc/cccp.c
index b39675d4c93..a849aabd6b3 100644
--- a/gcc/cccp.c
+++ b/gcc/cccp.c
@@ -1,5 +1,5 @@
/* C Compatible Compiler Preprocessor (CCCP)
- Copyright (C) 1986, 87, 89, 92-97, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1986, 87, 89, 92-98, 1999 Free Software Foundation, Inc.
Written by Paul Rubin, June 1986
Adapted to ANSI C, Richard Stallman, Jan 1987
@@ -20,15 +20,7 @@ Boston, MA 02111-1307, USA. */
#include "config.h"
-#define PRINTF_PROTO(ARGS, m, n) PVPROTO (ARGS) ATTRIBUTE_PRINTF(m, n)
-
-#define PRINTF_PROTO_1(ARGS) PRINTF_PROTO(ARGS, 1, 2)
-#define PRINTF_PROTO_2(ARGS) PRINTF_PROTO(ARGS, 2, 3)
-#define PRINTF_PROTO_3(ARGS) PRINTF_PROTO(ARGS, 3, 4)
-#define PRINTF_PROTO_4(ARGS) PRINTF_PROTO(ARGS, 4, 5)
-
#include "system.h"
-#include <sys/stat.h>
#include <signal.h>
#ifdef HAVE_SYS_RESOURCE_H
@@ -37,8 +29,9 @@ Boston, MA 02111-1307, USA. */
typedef unsigned char U_CHAR;
-#include "gansidecl.h"
#include "pcp.h"
+#include "intl.h"
+#include "prefix.h"
#ifdef MULTIBYTE_CHARS
#include "mbchar.h"
@@ -85,43 +78,11 @@ static int hack_vms_include_specification ();
#endif /* VMS */
/* Windows does not natively support inodes, and neither does MSDOS. */
-#if (defined (_WIN32) && ! defined (CYGWIN32)) || defined (__MSDOS__)
+#if (defined (_WIN32) && ! defined (__CYGWIN__) && ! defined (_UWIN)) \
+ || defined (__MSDOS__)
#define INO_T_EQ(a, b) 0
#endif
-#undef MIN
-#undef MAX
-#define MIN(X,Y) ((X) < (Y) ? (X) : (Y))
-#define MAX(X,Y) ((X) > (Y) ? (X) : (Y))
-
-/* Find the largest host integer type and set its size and type.
- Watch out: on some crazy hosts `long' is shorter than `int'. */
-
-#ifndef HOST_WIDE_INT
-# if HAVE_INTTYPES_H
-# include <inttypes.h>
-# define HOST_WIDE_INT intmax_t
-# else
-# if (HOST_BITS_PER_LONG <= HOST_BITS_PER_INT && HOST_BITS_PER_LONGLONG <= HOST_BITS_PER_INT)
-# define HOST_WIDE_INT int
-# else
-# if (HOST_BITS_PER_LONGLONG <= HOST_BITS_PER_LONG || ! (defined LONG_LONG_MAX || defined LLONG_MAX))
-# define HOST_WIDE_INT long
-# else
-# define HOST_WIDE_INT long long
-# endif
-# endif
-# endif
-#endif
-
-#ifndef S_ISREG
-#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
-#endif
-
-#ifndef S_ISDIR
-#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
-#endif
-
#ifndef INO_T_EQ
#define INO_T_EQ(a, b) ((a) == (b))
#endif
@@ -137,9 +98,8 @@ static int hack_vms_include_specification ();
/* External declarations. */
extern char *version_string;
-extern char *update_path PROTO((char *, char *));
-HOST_WIDE_INT parse_escape PROTO((char **, HOST_WIDE_INT));
-HOST_WIDE_INT parse_c_expression PROTO((char *, int));
+HOST_WIDEST_INT parse_escape PROTO((char **, HOST_WIDEST_INT));
+HOST_WIDEST_INT parse_c_expression PROTO((char *, int));
/* Name under which this program was invoked. */
@@ -294,6 +254,10 @@ int traditional;
int c89;
+/* Nonzero for the 199x C Standard. */
+
+int c9x;
+
/* Nonzero causes output not to be done,
but directives such as #define that have side effects
are still obeyed. */
@@ -414,48 +378,49 @@ static struct default_include {
int cxx_aware; /* Includes in this directory don't need to
be wrapped in extern "C" when compiling
C++. */
+ int included; /* Set if the directory is acceptable. */
} include_defaults_array[]
#ifdef INCLUDE_DEFAULTS
= INCLUDE_DEFAULTS;
#else
= {
/* Pick up GNU C++ specific include files. */
- { GPLUSPLUS_INCLUDE_DIR, "G++", 1, 1 },
+ { GPLUSPLUS_INCLUDE_DIR, "G++", 1, 1, 0 },
#ifdef CROSS_COMPILE
/* This is the dir for fixincludes. Put it just before
the files that we fix. */
- { GCC_INCLUDE_DIR, "GCC", 0, 0 },
+ { GCC_INCLUDE_DIR, "GCC", 0, 0, 0 },
/* For cross-compilation, this dir name is generated
automatically in Makefile.in. */
- { CROSS_INCLUDE_DIR, "GCC", 0, 0 },
+ { CROSS_INCLUDE_DIR, "GCC", 0, 0, 0 },
#ifdef TOOL_INCLUDE_DIR
/* This is another place that the target system's headers might be. */
- { TOOL_INCLUDE_DIR, "BINUTILS", 0, 0 },
+ { TOOL_INCLUDE_DIR, "BINUTILS", 0, 0, 0 },
#endif
#else /* not CROSS_COMPILE */
#ifdef LOCAL_INCLUDE_DIR
/* This should be /usr/local/include and should come before
the fixincludes-fixed header files. */
- { LOCAL_INCLUDE_DIR, 0, 0, 1 },
+ { LOCAL_INCLUDE_DIR, 0, 0, 1, 0 },
#endif
#ifdef TOOL_INCLUDE_DIR
/* This is here ahead of GCC_INCLUDE_DIR because assert.h goes here.
Likewise, behind LOCAL_INCLUDE_DIR, where glibc puts its assert.h. */
- { TOOL_INCLUDE_DIR, "BINUTILS", 0, 0 },
+ { TOOL_INCLUDE_DIR, "BINUTILS", 0, 0, 0 },
#endif
/* This is the dir for fixincludes. Put it just before
the files that we fix. */
- { GCC_INCLUDE_DIR, "GCC", 0, 0 },
+ { GCC_INCLUDE_DIR, "GCC", 0, 0, 0 },
/* Some systems have an extra dir of include files. */
#ifdef SYSTEM_INCLUDE_DIR
- { SYSTEM_INCLUDE_DIR, 0, 0, 0 },
+ { SYSTEM_INCLUDE_DIR, 0, 0, 0, 0 },
#endif
#ifndef STANDARD_INCLUDE_COMPONENT
#define STANDARD_INCLUDE_COMPONENT 0
#endif
- { STANDARD_INCLUDE_DIR, STANDARD_INCLUDE_COMPONENT, 0, 0 },
+ { STANDARD_INCLUDE_DIR, STANDARD_INCLUDE_COMPONENT, 0, 0, 0 },
#endif /* not CROSS_COMPILE */
- { 0, 0, 0, 0 }
+ { 0, 0, 0, 0, 0 }
};
#endif /* no INCLUDE_DEFAULTS */
@@ -613,6 +578,11 @@ union hashval {
static char rest_extension[] = "...";
#define REST_EXTENSION_LENGTH (sizeof (rest_extension) - 1)
+/* This is the implicit parameter name when using variable number of
+ parameters for macros using the ISO C 9x extension. */
+static char va_args_name[] = "__VA_ARGS__";
+#define VA_ARGS_NAME_LENGTH (sizeof (va_args_name) - 1)
+
/* The structure of a node in the hash table. The hash table
has entries for all tokens defined by #define directives (type T_MACRO),
plus some special tokens like __LINE__ (these each have their own
@@ -727,6 +697,8 @@ char * wchar_type = WCHAR_TYPE;
#ifndef USER_LABEL_PREFIX
#define USER_LABEL_PREFIX ""
#endif
+char * user_label_prefix = USER_LABEL_PREFIX;
+#undef USER_LABEL_PREFIX
/* The string value for __REGISTER_PREFIX__ */
@@ -855,8 +827,6 @@ U_CHAR is_idstart[256];
static U_CHAR is_hor_space[256];
/* table to tell if c is horizontal or vertical space. */
U_CHAR is_space[256];
-/* names of some characters */
-static char *char_name[256];
#define SKIP_WHITE_SPACE(p) do { while (is_hor_space[*p]) p++; } while (0)
#define SKIP_ALL_WHITE_SPACE(p) do { while (is_space[*p]) p++; } while (0)
@@ -866,6 +836,10 @@ static int errors = 0; /* Error counter for exit code */
/* Name of output file, for error messages. */
static char *out_fname;
+/* Nonzero to ignore \ in string constants. Use to treat #line 1 "A:\file.h
+ as a non-form feed. If you want it to be a form feed, you must use
+ # 1 "\f". */
+static int ignore_escape_flag = 1;
/* Stack of conditionals currently in progress
(including both successful and failing conditionals). */
@@ -902,7 +876,7 @@ static int ignore_srcdir;
static int safe_read PROTO((int, char *, int));
static void safe_write PROTO((int, char *, int));
-static void eprint_string PROTO((char *, size_t));
+static void eprint_string PROTO((const char *, size_t));
int main PROTO((int, char **));
@@ -942,14 +916,14 @@ static void record_control_macro PROTO((struct include_file *, U_CHAR *));
static char *check_precompiled PROTO((int, struct stat *, char *, char **));
static int check_preconditions PROTO((char *));
-static void pcfinclude PROTO((U_CHAR *, U_CHAR *, U_CHAR *, FILE_BUF *));
+static void pcfinclude PROTO((U_CHAR *, U_CHAR *, FILE_BUF *));
static void pcstring_used PROTO((HASHNODE *));
static void write_output PROTO((void));
static void pass_thru_directive PROTO((U_CHAR *, U_CHAR *, FILE_BUF *, struct directive *));
static MACRODEF create_definition PROTO((U_CHAR *, U_CHAR *, FILE_BUF *));
-static int check_macro_name PROTO((U_CHAR *, char *));
+static int check_macro_name PROTO((U_CHAR *, int));
static int compare_defs PROTO((DEFINITION *, DEFINITION *));
static int comp_def_part PROTO((int, U_CHAR *, int, U_CHAR *, int, int));
@@ -967,7 +941,7 @@ static void delete_assertion PROTO((ASSERTION_HASHNODE *));
static void do_once PROTO((void));
-static HOST_WIDE_INT eval_if_expression PROTO((U_CHAR *, int));
+static HOST_WIDEST_INT eval_if_expression PROTO((U_CHAR *, int));
static void conditional_skip PROTO((FILE_BUF *, int, enum node_type, U_CHAR *, FILE_BUF *));
static void skip_if_group PROTO((FILE_BUF *, int, FILE_BUF *));
static void validate_else PROTO((U_CHAR *, U_CHAR *));
@@ -984,7 +958,7 @@ static void output_line_directive PROTO((FILE_BUF *, FILE_BUF *, int, enum file_
static void macroexpand PROTO((HASHNODE *, FILE_BUF *));
struct argdata;
-static char *macarg PROTO((struct argdata *, int));
+static int macarg PROTO((struct argdata *, int));
static U_CHAR *macarg1 PROTO((U_CHAR *, U_CHAR *, struct hashnode *, int *, int *, int *, int));
@@ -993,18 +967,21 @@ static int discard_comments PROTO((U_CHAR *, int, int));
static int change_newlines PROTO((U_CHAR *, int));
static char *my_strerror PROTO((int));
-void error PRINTF_PROTO_1((char *, ...));
-static void verror PROTO((char *, va_list));
+static void notice PVPROTO((const char *, ...)) ATTRIBUTE_PRINTF_1;
+static void vnotice PROTO((const char *, va_list));
+void error PVPROTO((const char *, ...)) ATTRIBUTE_PRINTF_1;
+void verror PROTO((const char *, va_list));
static void error_from_errno PROTO((char *));
-void warning PRINTF_PROTO_1((char *, ...));
-static void vwarning PROTO((char *, va_list));
-static void error_with_line PRINTF_PROTO_2((int, char *, ...));
-static void verror_with_line PROTO((int, char *, va_list));
-static void vwarning_with_line PROTO((int, char *, va_list));
-static void warning_with_line PRINTF_PROTO_2((int, char *, ...));
-void pedwarn PRINTF_PROTO_1((char *, ...));
-void pedwarn_with_line PRINTF_PROTO_2((int, char *, ...));
-static void pedwarn_with_file_and_line PRINTF_PROTO_4((char *, size_t, int, char *, ...));
+void warning PVPROTO((const char *, ...)) ATTRIBUTE_PRINTF_1;
+static void vwarning PROTO((const char *, va_list));
+static void error_with_line PVPROTO((int, const char *, ...)) ATTRIBUTE_PRINTF_2;
+static void verror_with_line PROTO((int, const char *, va_list));
+static void vwarning_with_line PROTO((int, const char *, va_list));
+static void warning_with_line PVPROTO((int, const char *, ...)) ATTRIBUTE_PRINTF_2;
+void pedwarn PVPROTO((const char *, ...)) ATTRIBUTE_PRINTF_1;
+void pedwarn_with_line PVPROTO((int, const char *, ...)) ATTRIBUTE_PRINTF_2;
+static void pedwarn_with_file_and_line PVPROTO((const char *, size_t, int, const char *, ...)) ATTRIBUTE_PRINTF_4;
+static void pedwarn_strange_white_space PROTO((int));
static void print_containing_files PROTO((void));
@@ -1024,28 +1001,24 @@ static void dump_arg_n PROTO((DEFINITION *, int, FILE *));
static void initialize_char_syntax PROTO((void));
static void initialize_builtins PROTO((FILE_BUF *, FILE_BUF *));
-static void make_definition PROTO((char *, FILE_BUF *));
+static void make_definition PROTO((char *));
static void make_undef PROTO((char *, FILE_BUF *));
-static void make_assertion PROTO((char *, char *));
+static void make_assertion PROTO((const char *, const char *));
-static struct file_name_list *new_include_prefix PROTO((struct file_name_list *, char *, char *, char *));
+static struct file_name_list *new_include_prefix PROTO((struct file_name_list *, const char *, const char *, const char *));
static void append_include_chain PROTO((struct file_name_list *, struct file_name_list *));
-static int quote_string_for_make PROTO((char *, char *));
-static void deps_output PROTO((char *, int));
+static int quote_string_for_make PROTO((char *, const char *));
+static void deps_output PROTO((const char *, int));
-static void fatal PRINTF_PROTO_1((char *, ...)) __attribute__ ((noreturn));
-void fancy_abort PROTO((void)) __attribute__ ((noreturn));
+static void fatal PVPROTO((const char *, ...)) ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN;
+void fancy_abort PROTO((void)) ATTRIBUTE_NORETURN;
static void perror_with_name PROTO((char *));
-static void pfatal_with_name PROTO((char *)) __attribute__ ((noreturn));
-static void pipe_closed PROTO((int)) __attribute__ ((noreturn));
-
-static void memory_full PROTO((void)) __attribute__ ((noreturn));
-GENERIC_PTR xmalloc PROTO((size_t));
-static GENERIC_PTR xrealloc PROTO((GENERIC_PTR, size_t));
-static GENERIC_PTR xcalloc PROTO((size_t, size_t));
-static char *savestring PROTO((char *));
+static void pfatal_with_name PROTO((char *)) ATTRIBUTE_NORETURN;
+static void pipe_closed PROTO((int)) ATTRIBUTE_NORETURN;
+
+static void memory_full PROTO((void)) ATTRIBUTE_NORETURN;
static void print_help PROTO((void));
/* Read LEN bytes at PTR from descriptor DESC, for file FILENAME,
@@ -1127,7 +1100,7 @@ safe_write (desc, ptr, len)
static void
eprint_string (string, length)
- char *string;
+ const char *string;
size_t length;
{
size_t segment_length;
@@ -1166,12 +1139,15 @@ print_help ()
printf (" -traditional Follow K&R pre-processor behaviour\n");
printf (" -trigraphs Support ANSI C trigraphs\n");
printf (" -lang-c Assume that the input sources are in C\n");
- printf (" -lang-c89 Assume that the input sources are in C89\n");
+ printf (" -lang-c89 Assume that the input is C89; depricated\n");
printf (" -lang-c++ Assume that the input sources are in C++\n");
printf (" -lang-objc Assume that the input sources are in ObjectiveC\n");
printf (" -lang-objc++ Assume that the input sources are in ObjectiveC++\n");
printf (" -lang-asm Assume that the input sources are in assembler\n");
printf (" -lang-chill Assume that the input sources are in Chill\n");
+ printf (" -std=<std name> Specify the conformance standard; one of:\n");
+ printf (" gnu89, gnu9x, c89, c9x, iso9899:1990,\n");
+ printf (" iso9899:199409, iso9899:199x\n");
printf (" -+ Allow parsing of C++ style features\n");
printf (" -w Inhibit warning messages\n");
printf (" -Wtrigraphs Warn if trigraphs are encountered\n");
@@ -1179,10 +1155,10 @@ print_help ()
printf (" -Wcomment{s} Warn if one comment starts inside another\n");
printf (" -Wno-comment{s} Do not warn about comments\n");
printf (" -Wtraditional Warn if a macro argument is/would be turned into\n");
- printf (" a string if -tradtional is specified\n");
+ printf (" a string if -traditional is specified\n");
printf (" -Wno-traditional Do not warn about stringification\n");
printf (" -Wundef Warn if an undefined macro is used by #if\n");
- printf (" -Wno-undef Do not warn about testing udefined macros\n");
+ printf (" -Wno-undef Do not warn about testing undefined macros\n");
printf (" -Wimport Warn about the use of the #import directive\n");
printf (" -Wno-import Do not warn about the use of #import\n");
printf (" -Werror Treat all warnings as errors\n");
@@ -1223,16 +1199,17 @@ main (argc, argv)
char *cp;
int f, i;
FILE_BUF *fp;
- char **pend_files = (char **) xmalloc (argc * sizeof (char *));
- char **pend_defs = (char **) xmalloc (argc * sizeof (char *));
- char **pend_undefs = (char **) xmalloc (argc * sizeof (char *));
- char **pend_assertions = (char **) xmalloc (argc * sizeof (char *));
- char **pend_includes = (char **) xmalloc (argc * sizeof (char *));
+
+ char **pend_files;
+ char **pend_defs;
+ char **pend_undefs;
+ char **pend_assertions;
+ char **pend_includes;
/* Record the option used with each element of pend_assertions.
This is preparation for supporting more than one option for making
an assertion. */
- char **pend_assertion_options = (char **) xmalloc (argc * sizeof (char *));
+ char **pend_assertion_options;
int inhibit_predefs = 0;
int no_standard_includes = 0;
int no_standard_cplusplus_includes = 0;
@@ -1270,13 +1247,19 @@ main (argc, argv)
signal (SIGPIPE, pipe_closed);
#endif
+#ifdef HAVE_LC_MESSAGES
+ setlocale (LC_MESSAGES, "");
+#endif
+ (void) bindtextdomain (PACKAGE, localedir);
+ (void) textdomain (PACKAGE);
+
progname = base_name (argv[0]);
#ifdef VMS
{
/* Remove extension from PROGNAME. */
char *p;
- char *s = progname = savestring (progname);
+ char *s = progname = xstrdup (progname);
if ((p = rindex (s, ';')) != 0) *p = '\0'; /* strip version number */
if ((p = rindex (s, '.')) != 0 /* strip type iff ".exe" */
@@ -1288,6 +1271,16 @@ main (argc, argv)
}
#endif
+ /* Do not invoke xmalloc before this point, since locale and
+ progname need to be set first, in case a diagnostic is issued. */
+
+ pend_files = (char **) xmalloc (argc * sizeof (char *));
+ pend_defs = (char **) xmalloc (argc * sizeof (char *));
+ pend_undefs = (char **) xmalloc (argc * sizeof (char *));
+ pend_assertions = (char **) xmalloc (argc * sizeof (char *));
+ pend_includes = (char **) xmalloc (argc * sizeof (char *));
+ pend_assertion_options = (char **) xmalloc (argc * sizeof (char *));
+
in_fname = NULL;
out_fname = NULL;
@@ -1378,7 +1371,7 @@ main (argc, argv)
if (include_prefix != 0)
prefix = include_prefix;
else {
- prefix = savestring (GCC_INCLUDE_DIR);
+ prefix = xstrdup (GCC_INCLUDE_DIR);
/* Remove the `include' from /usr/local/lib/gcc.../include. */
if (!strcmp (prefix + strlen (prefix) - 8, "/include"))
prefix[strlen (prefix) - 7] = 0;
@@ -1403,7 +1396,7 @@ main (argc, argv)
if (include_prefix != 0)
prefix = include_prefix;
else {
- prefix = savestring (GCC_INCLUDE_DIR);
+ prefix = xstrdup (GCC_INCLUDE_DIR);
/* Remove the `include' from /usr/local/lib/gcc.../include. */
if (!strcmp (prefix + strlen (prefix) - 8, "/include"))
prefix[strlen (prefix) - 7] = 0;
@@ -1470,18 +1463,18 @@ main (argc, argv)
case 'l':
if (! strcmp (argv[i], "-lang-c"))
- cplusplus = 0, cplusplus_comments = 1, c89 = 0, objc = 0;
- if (! strcmp (argv[i], "-lang-c89"))
- cplusplus = 0, cplusplus_comments = 0, c89 = 1, objc = 0;
- if (! strcmp (argv[i], "-lang-c++"))
- cplusplus = 1, cplusplus_comments = 1, c89 = 0, objc = 0;
- if (! strcmp (argv[i], "-lang-objc"))
- cplusplus = 0, cplusplus_comments = 1, c89 = 0, objc = 1;
- if (! strcmp (argv[i], "-lang-objc++"))
- cplusplus = 1, cplusplus_comments = 1, c89 = 0, objc = 1;
- if (! strcmp (argv[i], "-lang-asm"))
+ cplusplus = 0, cplusplus_comments = 1, c89 = 0, c9x = 1, objc = 0;
+ else if (! strcmp (argv[i], "-lang-c89"))
+ cplusplus = 0, cplusplus_comments = 0, c89 = 1, c9x = 0, objc = 0;
+ else if (! strcmp (argv[i], "-lang-c++"))
+ cplusplus = 1, cplusplus_comments = 1, c89 = 0, c9x = 0, objc = 0;
+ else if (! strcmp (argv[i], "-lang-objc"))
+ cplusplus = 0, cplusplus_comments = 1, c89 = 0, c9x = 0, objc = 1;
+ else if (! strcmp (argv[i], "-lang-objc++"))
+ cplusplus = 1, cplusplus_comments = 1, c89 = 0, c9x = 0, objc = 1;
+ else if (! strcmp (argv[i], "-lang-asm"))
lang_asm = 1;
- if (! strcmp (argv[i], "-lint"))
+ else if (! strcmp (argv[i], "-lint"))
for_lint = 1;
break;
@@ -1489,6 +1482,18 @@ main (argc, argv)
cplusplus = 1, cplusplus_comments = 1;
break;
+ case 's':
+ if (!strcmp (argv[i], "-std=iso9899:1990")
+ || !strcmp (argv[i], "-std=iso9899:199409")
+ || !strcmp (argv[i], "-std=c89")
+ || !strcmp (argv[i], "-std=gnu89"))
+ cplusplus = 0, cplusplus_comments = 0, c89 = 1, c9x = 0, objc = 0;
+ else if (!strcmp (argv[i], "-std=iso9899:199x")
+ || !strcmp (argv[i], "-std=c9x")
+ || !strcmp (argv[i], "-std=gnu9x"))
+ cplusplus = 0, cplusplus_comments = 1, c89 = 0, c9x = 1, objc = 0;
+ break;
+
case 'w':
inhibit_warnings = 1;
break;
@@ -1529,6 +1534,13 @@ main (argc, argv)
}
break;
+ case 'f':
+ if (!strcmp (argv[i], "-fleading-underscore"))
+ user_label_prefix = "_";
+ else if (!strcmp (argv[i], "-fno-leading-underscore"))
+ user_label_prefix = "";
+ break;
+
case 'M':
/* The style of the choices here is a bit mixed.
The chosen scheme is a hybrid of keeping all options in one string
@@ -1609,7 +1621,7 @@ main (argc, argv)
break;
case 'v':
- fprintf (stderr, "GNU CPP version %s", version_string);
+ notice ("GNU CPP version %s", version_string);
#ifdef TARGET_VERSION
TARGET_VERSION;
#endif
@@ -1828,7 +1840,7 @@ main (argc, argv)
sprintf (versbuf, "__VMS_VER=%08ld", vms_version_value);
if (debug_output)
output_line_directive (fp, &outbuf, 0, same_file);
- make_definition (versbuf, &outbuf);
+ make_definition (versbuf);
}
}
#endif
@@ -1847,7 +1859,7 @@ main (argc, argv)
*p++= 0;
if (debug_output)
output_line_directive (fp, &outbuf, 0, same_file);
- make_definition (q, &outbuf);
+ make_definition (q);
while (*p == ' ' || *p == '\t')
p++;
} else if (p[0] == '-' && p[1] == 'A') {
@@ -1912,7 +1924,7 @@ main (argc, argv)
if (pend_defs[i]) {
if (debug_output)
output_line_directive (fp, &outbuf, 0, same_file);
- make_definition (pend_defs[i], &outbuf);
+ make_definition (pend_defs[i]);
}
if (pend_assertions[i])
make_assertion (pend_assertion_options[i], pend_assertions[i]);
@@ -1958,7 +1970,7 @@ main (argc, argv)
if (c == PATH_SEPARATOR || !c) {
endp[-1] = 0;
include_defaults[num_dirs].fname
- = startp == endp ? "." : savestring (startp);
+ = startp == endp ? "." : xstrdup (startp);
endp[-1] = c;
include_defaults[num_dirs].component = 0;
include_defaults[num_dirs].cplusplus = cplusplus;
@@ -1984,7 +1996,7 @@ main (argc, argv)
if (!no_standard_includes) {
struct default_include *p = include_defaults;
char *specd_prefix = include_prefix;
- char *default_prefix = savestring (GCC_INCLUDE_DIR);
+ char *default_prefix = xstrdup (GCC_INCLUDE_DIR);
int default_len = 0;
/* Remove the `include' from /usr/local/lib/gcc.../include. */
if (!strcmp (default_prefix + strlen (default_prefix) - 8, "/include")) {
@@ -2008,6 +2020,7 @@ main (argc, argv)
append_include_chain (new, new);
if (first_system_include == 0)
first_system_include = new;
+ p->included = 1;
}
}
}
@@ -2023,6 +2036,7 @@ main (argc, argv)
append_include_chain (new, new);
if (first_system_include == 0)
first_system_include = new;
+ p->included = 1;
}
}
}
@@ -2036,10 +2050,10 @@ main (argc, argv)
/* With -v, print the list of dirs to search. */
if (verbose) {
struct file_name_list *p;
- fprintf (stderr, "#include \"...\" search starts here:\n");
+ notice ("#include \"...\" search starts here:\n");
for (p = include; p; p = p->next) {
if (p == first_bracket_include)
- fprintf (stderr, "#include <...> search starts here:\n");
+ notice ("#include <...> search starts here:\n");
if (!p->fname[0])
fprintf (stderr, " .\n");
else if (!strcmp (p->fname, "/") || !strcmp (p->fname, "//"))
@@ -2048,7 +2062,15 @@ main (argc, argv)
/* Omit trailing '/'. */
fprintf (stderr, " %.*s\n", (int) strlen (p->fname) - 1, p->fname);
}
- fprintf (stderr, "End of search list.\n");
+ notice ("End of search list.\n");
+ {
+ struct default_include * d;
+ notice ("The following default directories have been omitted from the search path:\n");
+ for (d = include_defaults; d->fname; d++)
+ if (! d->included)
+ fprintf (stderr, " %s\n", d->fname);
+ notice ("End of omitted list.\n");
+ }
}
/* -MG doesn't select the form of output and must be specified with one of
@@ -2533,7 +2555,7 @@ get_lintcmd (ibp, limit, argstart, arglen, cmdlen)
U_CHAR **argstart; /* point to command arg */
int *arglen, *cmdlen; /* how long they are */
{
- HOST_WIDE_INT linsize;
+ HOST_WIDEST_INT linsize;
register U_CHAR *numptr; /* temp for arg parsing */
*arglen = 0;
@@ -3006,24 +3028,30 @@ do { ip = &instack[indepth]; \
U_CHAR *before_bp = ibp;
while (++ibp < limit) {
- if (*ibp == '\n') {
- if (ibp[-1] != '\\') {
+ if (*ibp == '\n')
+ {
if (put_out_comments) {
bcopy ((char *) before_bp, (char *) obp, ibp - before_bp);
obp += ibp - before_bp;
}
break;
}
- if (warn_comments)
- warning ("multiline `//' comment");
- ++ip->lineno;
- /* Copy the newline into the output buffer, in order to
- avoid the pain of a #line every time a multiline comment
- is seen. */
- if (!put_out_comments)
- *obp++ = '\n';
- ++op->lineno;
- }
+ if (*ibp == '\\')
+ {
+ if (ibp + 1 < limit && ibp[1] == '\n')
+ {
+ if (warn_comments)
+ warning ("multiline `//' comment");
+ ++ip->lineno;
+ /* Copy the newline into the output buffer, in order to
+ avoid the pain of a #line every time a multiline comment
+ is seen. */
+ if (!put_out_comments)
+ *obp++ = '\n';
+ ++op->lineno;
+ ++ibp;
+ }
+ }
else
{
#ifdef MULTIBYTE_CHARS
@@ -3527,9 +3555,11 @@ randomchar:
for (ibp += 2; ; ibp++)
{
if (*ibp == '\n')
+ break;
+ if (*ibp == '\\' && ibp[1] == '\n')
{
- if (ibp[-1] != '\\')
- break;
+ if (put_out_comments)
+ *obp++ = *ibp++;
}
else
{
@@ -3778,11 +3808,13 @@ handle_directive (ip, op)
/* Record where the directive started. do_xifdef needs this. */
directive_start = bp - 1;
+ ignore_escape_flag = 1;
+
/* Skip whitespace and \-newline. */
while (1) {
if (is_hor_space[*bp]) {
if (*bp != ' ' && *bp != '\t' && pedantic)
- pedwarn ("%s in preprocessing directive", char_name[*bp]);
+ pedwarn_strange_white_space (*bp);
bp++;
} else if (*bp == '/') {
if (bp[1] == '\\' && bp[2] == '\n')
@@ -3840,6 +3872,7 @@ handle_directive (ip, op)
pedwarn ("`#' followed by integer");
after_ident = ident;
kt = line_directive_table;
+ ignore_escape_flag = 0;
goto old_linenum;
}
@@ -3984,7 +4017,7 @@ handle_directive (ip, op)
case '\r':
case '\v':
if (pedantic)
- pedwarn ("%s in preprocessing directive", char_name[c]);
+ pedwarn_strange_white_space (c);
break;
case '\n':
@@ -4004,7 +4037,8 @@ handle_directive (ip, op)
/* If a directive should be copied through, and -C was given,
pass it through before removing comments. */
if (!no_output && put_out_comments
- && (kt->type == T_DEFINE ? dump_macros == dump_definitions
+ && ((kt->type == T_DEFINE || kt->type == T_UNDEF)
+ ? dump_macros == dump_definitions
: IS_INCLUDE_DIRECTIVE_TYPE (kt->type) ? dump_includes
: kt->type == T_PRAGMA)) {
int len;
@@ -4274,7 +4308,7 @@ special_symbol (hp, op)
break;
case T_USER_LABEL_PREFIX_TYPE:
- buf = USER_LABEL_PREFIX;
+ buf = user_label_prefix;
break;
case T_REGISTER_PREFIX_TYPE:
@@ -4425,16 +4459,18 @@ do_include (buf, limit, op, keyword)
&& !instack[indepth].system_header_p && !import_warning) {
import_warning = 1;
warning ("using `#import' is not recommended");
- fprintf (stderr, "The fact that a certain header file need not be processed more than once\n");
- fprintf (stderr, "should be indicated in the header file, not where it is used.\n");
- fprintf (stderr, "The best way to do this is with a conditional of this form:\n\n");
- fprintf (stderr, " #ifndef _FOO_H_INCLUDED\n");
- fprintf (stderr, " #define _FOO_H_INCLUDED\n");
- fprintf (stderr, " ... <real contents of file> ...\n");
- fprintf (stderr, " #endif /* Not _FOO_H_INCLUDED */\n\n");
- fprintf (stderr, "Then users can use `#include' any number of times.\n");
- fprintf (stderr, "GNU C automatically avoids processing the file more than once\n");
- fprintf (stderr, "when it is equipped with such a conditional.\n");
+ notice ("The fact that a certain header file need not be processed more than once\n\
+should be indicated in the header file, not where it is used.\n\
+The best way to do this is with a conditional of this form:\n\
+\n\
+ #ifndef _FOO_H_INCLUDED\n\
+ #define _FOO_H_INCLUDED\n\
+ ... <real contents of file> ...\n\
+ #endif /* Not _FOO_H_INCLUDED */\n\
+\n\
+Then users can use `#include' any number of times.\n\
+GNU C automatically avoids processing the file more than once\n\
+when it is equipped with such a conditional.\n");
}
get_filename:
@@ -4806,8 +4842,7 @@ get_filename:
if (pcfbuf) {
pcfname = xmalloc (strlen (pcftry) + 1);
strcpy (pcfname, pcftry);
- pcfinclude ((U_CHAR *) pcfbuf, (U_CHAR *) pcfbuflimit,
- (U_CHAR *) fname, op);
+ pcfinclude ((U_CHAR *) pcfbuf, (U_CHAR *) fname, op);
}
else
finclude (f, inc, op, is_system_include (fname), searchptr);
@@ -4873,10 +4908,11 @@ static int
absolute_filename (filename)
char *filename;
{
-#if defined (__MSDOS__) || (defined (_WIN32) && !defined (__CYGWIN32__))
+#if defined (__MSDOS__) \
+ || (defined (_WIN32) && !defined (__CYGWIN__) && !defined (_UWIN))
if (ISALPHA (filename[0]) && filename[1] == ':') filename += 2;
#endif
-#if defined (__CYGWIN32__)
+#if defined (__CYGWIN__)
/* At present, any path that begins with a drive spec is absolute. */
if (ISALPHA (filename[0]) && filename[1] == ':') return 1;
#endif
@@ -5038,7 +5074,7 @@ read_name_map (dirname)
map_list_ptr = ((struct file_name_map_list *)
xmalloc (sizeof (struct file_name_map_list)));
- map_list_ptr->map_list_name = savestring (dirname);
+ map_list_ptr->map_list_name = xstrdup (dirname);
map_list_ptr->map_list_map = NULL;
dirlen = strlen (dirname);
@@ -5514,8 +5550,8 @@ check_preconditions (prec)
in. OP is the main output buffer. */
static void
-pcfinclude (buf, limit, name, op)
- U_CHAR *buf, *limit, *name;
+pcfinclude (buf, name, op)
+ U_CHAR *buf, *name;
FILE_BUF *op;
{
FILE_BUF tmpbuf;
@@ -5702,7 +5738,7 @@ pass_thru_directive (buf, limit, op, keyword)
FILE_BUF *op;
struct directive *keyword;
{
- register unsigned keyword_length = keyword->length;
+ register int keyword_length = keyword->length;
check_expand (op, 1 + keyword_length + (limit - buf));
*op->bufp++ = '#';
@@ -5766,7 +5802,7 @@ create_definition (buf, limit, op)
bp++;
symname = bp; /* remember where it starts */
- sym_length = check_macro_name (bp, "macro");
+ sym_length = check_macro_name (bp, 0);
bp += sym_length;
/* Lossage will occur if identifiers or control keywords are broken
@@ -5796,13 +5832,24 @@ create_definition (buf, limit, op)
rest_extension);
if (!is_idstart[*bp])
+ {
+ if (c9x && limit - bp > (long) REST_EXTENSION_LENGTH
+ && bcmp (rest_extension, bp, REST_EXTENSION_LENGTH) == 0)
+ {
+ /* This is the ISO C 9x way to write macros with variable
+ number of arguments. */
+ rest_args = 1;
+ temp->rest_args = 1;
+ }
+ else
pedwarn ("invalid character in macro parameter name");
+ }
/* Find the end of the arg name. */
while (is_idchar[*bp]) {
bp++;
/* do we have a "special" rest-args extension here? */
- if (limit - bp > REST_EXTENSION_LENGTH
+ if (limit - bp > (long) REST_EXTENSION_LENGTH
&& bcmp (rest_extension, bp, REST_EXTENSION_LENGTH) == 0) {
if (pedantic && !instack[indepth].system_header_p)
pedwarn ("ANSI C does not allow macro with variable arguments");
@@ -5811,6 +5858,13 @@ create_definition (buf, limit, op)
break;
}
}
+ if (bp == temp->name && rest_args == 1)
+ {
+ /* This is the ISO C 9x style. */
+ temp->name = (U_CHAR *) va_args_name;
+ temp->length = VA_ARGS_NAME_LENGTH;
+ }
+ else
temp->length = bp - temp->name;
if (rest_args == 1)
bp += REST_EXTENSION_LENGTH;
@@ -5824,7 +5878,9 @@ create_definition (buf, limit, op)
bp++;
SKIP_WHITE_SPACE (bp);
/* A comma at this point can only be followed by an identifier. */
- if (!is_idstart[*bp]) {
+ if (!is_idstart[*bp]
+ && !(c9x && limit - bp > (long) REST_EXTENSION_LENGTH
+ && bcmp (rest_extension, bp, REST_EXTENSION_LENGTH) == 0)) {
error ("badly punctuated parameter list in `#define'");
goto nope;
}
@@ -5838,11 +5894,19 @@ create_definition (buf, limit, op)
for (otemp = temp->next; otemp != NULL; otemp = otemp->next)
if (temp->length == otemp->length
- && bcmp (temp->name, otemp->name, temp->length) == 0) {
+ && bcmp (temp->name, otemp->name, temp->length) == 0)
+ {
error ("duplicate argument name `%.*s' in `#define'",
temp->length, temp->name);
goto nope;
}
+ if (rest_args == 0 && temp->length == VA_ARGS_NAME_LENGTH
+ && bcmp (temp->name, va_args_name, VA_ARGS_NAME_LENGTH) == 0)
+ {
+ error ("\
+reserved name `%s' used as argument name in `#define'", va_args_name);
+ goto nope;
+ }
}
}
@@ -5989,12 +6053,12 @@ nope:
}
/* Check a purported macro name SYMNAME, and yield its length.
- USAGE is the kind of name this is intended for. */
+ ASSERTION is nonzero if this is really for an assertion name. */
static int
-check_macro_name (symname, usage)
+check_macro_name (symname, assertion)
U_CHAR *symname;
- char *usage;
+ int assertion;
{
U_CHAR *p;
int sym_length;
@@ -6004,10 +6068,13 @@ check_macro_name (symname, usage)
sym_length = p - symname;
if (sym_length == 0
|| (sym_length == 1 && *symname == 'L' && (*p == '\'' || *p == '"')))
- error ("invalid %s name", usage);
+ error (assertion ? "invalid assertion name" : "invalid macro name");
else if (!is_idstart[*symname]
|| (sym_length == 7 && ! bcmp (symname, "defined", 7)))
- error ("invalid %s name `%.*s'", usage, sym_length, symname);
+ error ((assertion
+ ? "invalid assertion name `%.*s'"
+ : "invalid macro name `%.*s'"),
+ sym_length, symname);
return sym_length;
}
@@ -6433,7 +6500,7 @@ do_assert (buf, limit, op, keyword)
bp++;
symname = bp; /* remember where it starts */
- sym_length = check_macro_name (bp, "assertion");
+ sym_length = check_macro_name (bp, 1);
bp += sym_length;
/* #define doesn't do this, but we should. */
SKIP_WHITE_SPACE (bp);
@@ -6512,7 +6579,7 @@ do_unassert (buf, limit, op, keyword)
bp++;
symname = bp; /* remember where it starts */
- sym_length = check_macro_name (bp, "assertion");
+ sym_length = check_macro_name (bp, 1);
bp += sym_length;
/* #define doesn't do this, but we should. */
SKIP_WHITE_SPACE (bp);
@@ -6885,15 +6952,16 @@ do_line (buf, limit, op, keyword)
return 0;
case '\\':
- {
- char *bpc = (char *) bp;
- HOST_WIDE_INT c = parse_escape (&bpc, (HOST_WIDE_INT) (U_CHAR) (-1));
- bp = (U_CHAR *) bpc;
- if (c < 0)
- p--;
- else
- p[-1] = c;
- }
+ if (! ignore_escape_flag)
+ {
+ char *bpc = (char *) bp;
+ HOST_WIDEST_INT c = parse_escape (&bpc, (HOST_WIDEST_INT) (U_CHAR) (-1));
+ bp = (U_CHAR *) bpc;
+ if (c < 0)
+ p--;
+ else
+ p[-1] = c;
+ }
break;
case '\"':
@@ -6986,7 +7054,7 @@ do_undef (buf, limit, op, keyword)
pass_thru_directive (buf, limit, op, keyword);
SKIP_WHITE_SPACE (buf);
- sym_length = check_macro_name (buf, "macro");
+ sym_length = check_macro_name (buf, 0);
while ((hp = lookup (buf, sym_length, -1)) != NULL) {
/* If we are generating additional info for debugging (with -g) we
@@ -7200,7 +7268,7 @@ do_if (buf, limit, op, keyword)
FILE_BUF *op;
struct directive *keyword ATTRIBUTE_UNUSED;
{
- HOST_WIDE_INT value;
+ HOST_WIDEST_INT value;
FILE_BUF *ip = &instack[indepth];
value = eval_if_expression (buf, limit - buf);
@@ -7217,7 +7285,7 @@ do_elif (buf, limit, op, keyword)
FILE_BUF *op;
struct directive *keyword ATTRIBUTE_UNUSED;
{
- HOST_WIDE_INT value;
+ HOST_WIDEST_INT value;
FILE_BUF *ip = &instack[indepth];
if (if_stack == instack[indepth].if_stack) {
@@ -7255,14 +7323,14 @@ do_elif (buf, limit, op, keyword)
/* Evaluate a #if expression in BUF, of length LENGTH, then parse the
result as a C expression and return the value as an int. */
-static HOST_WIDE_INT
+static HOST_WIDEST_INT
eval_if_expression (buf, length)
U_CHAR *buf;
int length;
{
FILE_BUF temp_obuf;
HASHNODE *save_defined;
- HOST_WIDE_INT value;
+ HOST_WIDEST_INT value;
save_defined = install ((U_CHAR *) "defined", -1, T_SPEC_DEFINED,
NULL_PTR, -1);
@@ -7607,13 +7675,15 @@ skip_if_group (ip, any, op)
bp += 2;
} else if (bp[1] == '/' && cplusplus_comments) {
for (bp += 2; ; bp++) {
- if (*bp == '\n') {
- if (bp[-1] != '\\')
- break;
- if (warn_comments)
- warning ("multiline `//' comment");
- ip->lineno++;
- }
+ if (*bp == '\n')
+ break;
+ if (*bp == '\\' && bp[1] == '\n')
+ {
+ if (warn_comments)
+ warning ("multiline `//' comment");
+ ip->lineno++;
+ bp++;
+ }
else
{
#ifdef MULTIBYTE_CHARS
@@ -7970,16 +8040,21 @@ skip_to_end_of_comment (ip, line_counter, nowarn)
}
if (cplusplus_comments && bp[-1] == '/') {
for (; bp < limit; bp++) {
- if (*bp == '\n') {
- if (bp[-1] != '\\')
- break;
- if (!nowarn && warn_comments)
- warning ("multiline `//' comment");
- if (line_counter)
- ++*line_counter;
- if (op)
- ++op->lineno;
- }
+ if (*bp == '\n')
+ break;
+ if (*bp == '\\' && bp + 1 < limit && bp[1] == '\n')
+ {
+ if (!nowarn && warn_comments)
+ warning ("multiline `//' comment");
+ if (line_counter)
+ ++*line_counter;
+ if (op)
+ {
+ ++op->lineno;
+ *op->bufp++ = *bp;
+ }
+ ++bp;
+ }
else
{
#ifdef MULTIBYTE_CHARS
@@ -8377,7 +8452,7 @@ macroexpand (hp, op)
if (nargs >= 0) {
register int i;
struct argdata *args;
- char *parse_error = 0;
+ int parse_error = 0;
args = (struct argdata *) alloca ((nargs + 1) * sizeof (struct argdata));
@@ -8411,7 +8486,8 @@ macroexpand (hp, op)
else
parse_error = macarg (NULL_PTR, 0);
if (parse_error) {
- error_with_line (line_for_error (start_line), parse_error);
+ error_with_line (line_for_error (start_line),
+ "unterminated macro call");
break;
}
i++;
@@ -8756,7 +8832,7 @@ macroexpand (hp, op)
REST_ARGS is passed to macarg1 to make it absorb the rest of the args.
Return nonzero to indicate a syntax error. */
-static char *
+static int
macarg (argptr, rest_args)
register struct argdata *argptr;
int rest_args;
@@ -8765,7 +8841,7 @@ macarg (argptr, rest_args)
int paren = 0;
int newlines = 0;
int comments = 0;
- char *result = 0;
+ int result = 0;
/* Try to parse as much of the argument as exists at this
input stack level. */
@@ -8798,7 +8874,7 @@ macarg (argptr, rest_args)
while (bp == ip->buf + ip->length) {
if (instack[indepth].macro == 0) {
- result = "unterminated macro call";
+ result = 1;
break;
}
ip->macro->type = T_MACRO;
@@ -8952,11 +9028,15 @@ macarg1 (start, limit, macro, depthptr, newlines, comments, rest_args)
for (bp += 2; bp < limit; bp++) {
if (*bp == '\n') {
++*newlines;
- if (bp[-1] != '\\')
- break;
- if (warn_comments)
- warning ("multiline `//' comment");
+ break;
}
+ if (*bp == '\\' && bp + 1 < limit && bp[1] == '\n')
+ {
+ ++*newlines;
+ if (warn_comments)
+ warning ("multiline `//' comment");
+ ++bp;
+ }
else
{
#ifdef MULTIBYTE_CHARS
@@ -9078,10 +9158,9 @@ discard_comments (start, length, newlines)
while (ibp < limit)
{
if (*ibp == '\n')
- {
- if (ibp[-1] != '\\')
- break;
- }
+ break;
+ if (*ibp == '\\' && ibp + 1 < limit && ibp[1] == '\n')
+ ibp++;
else
{
#ifdef MULTIBYTE_CHARS
@@ -9216,10 +9295,9 @@ change_newlines (start, length)
while (ibp < limit) {
*obp++ = c = *ibp++;
if (c == quotec)
- {
- if (ibp[-2] != '\\')
- break;
- }
+ break;
+ else if (c == '\\' && ibp < limit && *ibp == '\n')
+ *obp++ = *ibp++;
else if (c == '\n')
{
if (quotec == '\'')
@@ -9278,34 +9356,62 @@ my_strerror (errnum)
#endif
if (!result)
- result = "undocumented I/O error";
+ result = "errno = ?";
return result;
}
+/* notice - output message to stderr */
+
+static void
+notice VPROTO ((const char * msgid, ...))
+{
+#ifndef ANSI_PROTOTYPES
+ const char * msgid;
+#endif
+ va_list args;
+
+ VA_START (args, msgid);
+
+#ifndef ANSI_PROTOTYPES
+ msgid = va_arg (args, const char *);
+#endif
+
+ vnotice (msgid, args);
+ va_end (args);
+}
+
+static void
+vnotice (msgid, args)
+ const char *msgid;
+ va_list args;
+{
+ vfprintf (stderr, _(msgid), args);
+}
+
/* error - print error message and increment count of errors. */
void
-error VPROTO ((char * msg, ...))
+error VPROTO ((const char * msgid, ...))
{
-#ifndef __STDC__
- char * msg;
+#ifndef ANSI_PROTOTYPES
+ const char * msgid;
#endif
va_list args;
- VA_START (args, msg);
+ VA_START (args, msgid);
-#ifndef __STDC__
- msg = va_arg (args, char *);
+#ifndef ANSI_PROTOTYPES
+ msgid = va_arg (args, const char *);
#endif
-
- verror (msg, args);
+
+ verror (msgid, args);
va_end (args);
}
-static void
-verror (msg, args)
- char *msg;
+void
+verror (msgid, args)
+ const char *msgid;
va_list args;
{
int i;
@@ -9323,7 +9429,7 @@ verror (msg, args)
eprint_string (ip->nominal_fname, ip->nominal_fname_len);
fprintf (stderr, ":%d: ", ip->lineno);
}
- vfprintf (stderr, msg, args);
+ vnotice (msgid, args);
fprintf (stderr, "\n");
errors++;
}
@@ -9359,26 +9465,26 @@ error_from_errno (name)
/* Print error message but don't count it. */
void
-warning VPROTO ((char * msg, ...))
+warning VPROTO ((const char * msgid, ...))
{
-#ifndef __STDC__
- char * msg;
+#ifndef ANSI_PROTOTYPES
+ const char * msgid;
#endif
va_list args;
- VA_START (args, msg);
+ VA_START (args, msgid);
-#ifndef __STDC__
- msg = va_arg (args, char *);
+#ifndef ANSI_PROTOTYPES
+ msgid = va_arg (args, const char *);
#endif
- vwarning (msg, args);
+ vwarning (msgid, args);
va_end (args);
}
static void
-vwarning (msg, args)
- char *msg;
+vwarning (msgid, args)
+ const char *msgid;
va_list args;
{
int i;
@@ -9402,35 +9508,36 @@ vwarning (msg, args)
eprint_string (ip->nominal_fname, ip->nominal_fname_len);
fprintf (stderr, ":%d: ", ip->lineno);
}
- fprintf (stderr, "warning: ");
- vfprintf (stderr, msg, args);
+ notice ("warning: ");
+ vnotice (msgid, args);
fprintf (stderr, "\n");
}
static void
-error_with_line VPROTO ((int line, char * msg, ...))
+error_with_line VPROTO ((int line, const char * msgid, ...))
{
-#ifndef __STDC__
+#ifndef ANSI_PROTOTYPES
int line;
- char * msg;
+ const char * msgid;
#endif
va_list args;
- VA_START (args, msg);
+ VA_START (args, msgid);
-#ifndef __STDC__
+#ifndef ANSI_PROTOTYPES
line = va_arg (args, int);
- msg = va_arg (args, char *);
+ msgid = va_arg (args, const char *);
#endif
- verror_with_line (line, msg, args);
+ verror_with_line (line, msgid, args);
va_end (args);
}
+
static void
-verror_with_line (line, msg, args)
+verror_with_line (line, msgid, args)
int line;
- char *msg;
+ const char *msgid;
va_list args;
{
int i;
@@ -9448,35 +9555,35 @@ verror_with_line (line, msg, args)
eprint_string (ip->nominal_fname, ip->nominal_fname_len);
fprintf (stderr, ":%d: ", line);
}
- vfprintf (stderr, msg, args);
+ vnotice (msgid, args);
fprintf (stderr, "\n");
errors++;
}
static void
-warning_with_line VPROTO ((int line, char * msg, ...))
+warning_with_line VPROTO ((int line, const char * msgid, ...))
{
-#ifndef __STDC__
+#ifndef ANSI_PROTOTYPES
int line;
- char * msg;
+ const char * msgid;
#endif
va_list args;
- VA_START (args, msg);
+ VA_START (args, msgid);
-#ifndef __STDC__
+#ifndef ANSI_PROTOTYPES
line = va_arg (args, int);
- msg = va_arg (args, char *);
+ msgid = va_arg (args, const char *);
#endif
- vwarning_with_line (line, msg, args);
+ vwarning_with_line (line, msgid, args);
va_end (args);
}
static void
-vwarning_with_line (line, msg, args)
+vwarning_with_line (line, msgid, args)
int line;
- char *msg;
+ const char *msgid;
va_list args;
{
int i;
@@ -9500,54 +9607,54 @@ vwarning_with_line (line, msg, args)
eprint_string (ip->nominal_fname, ip->nominal_fname_len);
fprintf (stderr, line ? ":%d: " : ": ", line);
}
- fprintf (stderr, "warning: ");
- vfprintf (stderr, msg, args);
+ notice ("warning: ");
+ vnotice (msgid, args);
fprintf (stderr, "\n");
}
/* Print an error message and maybe count it. */
void
-pedwarn VPROTO ((char * msg, ...))
+pedwarn VPROTO ((const char * msgid, ...))
{
-#ifndef __STDC__
- char * msg;
+#ifndef ANSI_PROTOTYPES
+ const char * msgid;
#endif
va_list args;
- VA_START (args, msg);
-
-#ifndef __STDC__
- msg = va_arg (args, char *);
+ VA_START (args, msgid);
+
+#ifndef ANSI_PROTOTYPES
+ msgid = va_arg (args, const char *);
#endif
-
+
if (pedantic_errors)
- verror (msg, args);
+ verror (msgid, args);
else
- vwarning (msg, args);
+ vwarning (msgid, args);
va_end (args);
}
void
-pedwarn_with_line VPROTO ((int line, char * msg, ...))
+pedwarn_with_line VPROTO ((int line, const char * msgid, ...))
{
-#ifndef __STDC__
+#ifndef ANSI_PROTOTYPES
int line;
- char * msg;
+ const char * msgid;
#endif
va_list args;
- VA_START (args, msg);
-
-#ifndef __STDC__
+ VA_START (args, msgid);
+
+#ifndef ANSI_PROTOTYPES
line = va_arg (args, int);
- msg = va_arg (args, char *);
+ msgid = va_arg (args, const char *);
#endif
-
+
if (pedantic_errors)
- verror_with_line (line, msg, args);
+ verror_with_line (line, msgid, args);
else
- vwarning_with_line (line, msg, args);
+ vwarning_with_line (line, msgid, args);
va_end (args);
}
@@ -9555,27 +9662,27 @@ pedwarn_with_line VPROTO ((int line, char * msg, ...))
giving specified file name and line number, not current. */
static void
-pedwarn_with_file_and_line VPROTO ((char *file, size_t file_len, int line,
- char * msg, ...))
+pedwarn_with_file_and_line VPROTO ((const char *file, size_t file_len, int line,
+ const char * msgid, ...))
{
-#ifndef __STDC__
- char *file;
+#ifndef ANSI_PROTOTYPES
+ const char *file;
size_t file_len;
int line;
- char * msg;
+ const char * msgid;
#endif
va_list args;
if (!pedantic_errors && inhibit_warnings)
return;
- VA_START (args, msg);
+ VA_START (args, msgid);
-#ifndef __STDC__
- file = va_arg (args, char *);
+#ifndef ANSI_PROTOTYPES
+ file = va_arg (args, const char *);
file_len = va_arg (args, size_t);
line = va_arg (args, int);
- msg = va_arg (args, char *);
+ msgid = va_arg (args, const char *);
#endif
if (file) {
@@ -9585,12 +9692,24 @@ pedwarn_with_file_and_line VPROTO ((char *file, size_t file_len, int line,
if (pedantic_errors)
errors++;
if (!pedantic_errors)
- fprintf (stderr, "warning: ");
-
- vfprintf (stderr, msg, args);
+ notice ("warning: ");
+ vnotice (msgid, args);
va_end (args);
fprintf (stderr, "\n");
}
+
+static void
+pedwarn_strange_white_space (ch)
+ int ch;
+{
+ switch (ch)
+ {
+ case '\f': pedwarn ("formfeed in preprocessing directive"); break;
+ case '\r': pedwarn ("carriage return in preprocessing directive"); break;
+ case '\v': pedwarn ("vertical tab in preprocessing directive"); break;
+ default: abort ();
+ }
+}
/* Print the file names and line numbers of the #include
directives which led to the current file. */
@@ -9623,12 +9742,11 @@ print_containing_files ()
ip = &instack[i];
if (first) {
first = 0;
- fprintf (stderr, "In file included");
+ notice ( "In file included from ");
} else {
- fprintf (stderr, ",\n ");
+ notice (",\n from ");
}
- fprintf (stderr, " from ");
eprint_string (ip->nominal_fname, ip->nominal_fname_len);
fprintf (stderr, ":%d", ip->lineno);
}
@@ -10066,10 +10184,6 @@ initialize_char_syntax ()
is_space['\f'] = 1;
is_space['\n'] = 1;
is_space['\r'] = 1;
-
- char_name['\v'] = "vertical tab";
- char_name['\f'] = "formfeed";
- char_name['\r'] = "carriage return";
}
/* Initialize the built-in macros. */
@@ -10185,9 +10299,8 @@ initialize_builtins (inp, outp)
*/
static void
-make_definition (str, op)
+make_definition (str)
char *str;
- FILE_BUF *op;
{
FILE_BUF *ip;
struct directive *kt;
@@ -10301,8 +10414,8 @@ make_undef (str, op)
static void
make_assertion (option, str)
- char *option;
- char *str;
+ const char *option;
+ const char *str;
{
FILE_BUF *ip;
struct directive *kt;
@@ -10370,9 +10483,9 @@ make_assertion (option, str)
static struct file_name_list *
new_include_prefix (prev_file_name, component, prefix, name)
struct file_name_list *prev_file_name;
- char *component;
- char *prefix;
- char *name;
+ const char *component;
+ const char *prefix;
+ const char *name;
{
if (name == 0)
fatal ("Directory name missing after command line option");
@@ -10497,9 +10610,9 @@ append_include_chain (first, last)
static int
quote_string_for_make (dst, src)
char *dst;
- char *src;
+ const char *src;
{
- char *p = src;
+ const char *p = src;
int i = 0;
for (;;)
{
@@ -10516,7 +10629,7 @@ quote_string_for_make (dst, src)
preceded by 2N backslashes represents N backslashes at
the end of a file name; and backslashes in other
contexts should not be doubled. */
- char *q;
+ const char *q;
for (q = p - 1; src < q && q[-1] == '\\'; q--)
{
if (dst)
@@ -10559,7 +10672,7 @@ quote_string_for_make (dst, src)
static void
deps_output (string, spacer)
- char *string;
+ const char *string;
int spacer;
{
int size = quote_string_for_make ((char *) 0, string);
@@ -10598,21 +10711,20 @@ deps_output (string, spacer)
}
static void
-fatal VPROTO ((char * msg, ...))
+fatal VPROTO ((const char * msgid, ...))
{
-#ifndef __STDC__
- char * msg;
+#ifndef ANSI_PROTOTYPES
+ const char * msgid;
#endif
va_list args;
fprintf (stderr, "%s: ", progname);
- VA_START (args, msg);
-
-#ifndef __STDC__
- msg = va_arg (args, char *);
+ VA_START (args, msgid);
+
+#ifndef ANSI_PROTOTYPES
+ msgid = va_arg (args, const char *);
#endif
-
- vfprintf (stderr, msg, args);
+ vnotice (msgid, args);
va_end (args);
fprintf (stderr, "\n");
exit (FATAL_EXIT_CODE);
@@ -10663,47 +10775,50 @@ memory_full ()
fatal ("Memory exhausted.");
}
-
-GENERIC_PTR
+PTR
xmalloc (size)
- size_t size;
+ size_t size;
{
- register GENERIC_PTR ptr = (GENERIC_PTR) malloc (size);
+ register PTR ptr = (PTR) malloc (size);
if (!ptr)
memory_full ();
return ptr;
}
-static GENERIC_PTR
+PTR
xrealloc (old, size)
- GENERIC_PTR old;
- size_t size;
+ PTR old;
+ size_t size;
{
- register GENERIC_PTR ptr = (GENERIC_PTR) realloc (old, size);
+ register PTR ptr;
+ if (old)
+ ptr = (PTR) realloc (old, size);
+ else
+ ptr = (PTR) malloc (size);
if (!ptr)
memory_full ();
return ptr;
}
-static GENERIC_PTR
+PTR
xcalloc (number, size)
- size_t number, size;
+ size_t number, size;
{
register size_t total = number * size;
- register GENERIC_PTR ptr = (GENERIC_PTR) malloc (total);
+ register PTR ptr = (PTR) malloc (total);
if (!ptr)
memory_full ();
bzero (ptr, total);
return ptr;
}
-static char *
-savestring (input)
- char *input;
+char *
+xstrdup (input)
+ const char *input;
{
- size_t size = strlen (input);
- char *output = xmalloc (size + 1);
- strcpy (output, input);
+ register size_t len = strlen (input) + 1;
+ register char *output = xmalloc (len);
+ memcpy (output, input, len);
return output;
}
diff --git a/gcc/cexp.c b/gcc/cexp.c
index a577b24b2d1..ed318a9e3e4 100644
--- a/gcc/cexp.c
+++ b/gcc/cexp.c
@@ -23,14 +23,10 @@
#include "config.h"
-#define PRINTF_PROTO(ARGS, m, n) PVPROTO (ARGS) ATTRIBUTE_PRINTF(m, n)
-
-#define PRINTF_PROTO_1(ARGS) PRINTF_PROTO(ARGS, 1, 2)
-
#include "system.h"
+#include "intl.h"
#include <setjmp.h>
/* #define YYDEBUG 1 */
-#include "gansidecl.h"
#ifdef MULTIBYTE_CHARS
#include "mbchar.h"
@@ -47,44 +43,12 @@ struct arglist {
int argno;
};
-/* Find the largest host integer type and set its size and type.
- Watch out: on some crazy hosts `long' is shorter than `int'. */
-
-#ifndef HOST_WIDE_INT
-# if HAVE_INTTYPES_H
-# include <inttypes.h>
-# define HOST_WIDE_INT intmax_t
-# define unsigned_HOST_WIDE_INT uintmax_t
-# else
-# if (HOST_BITS_PER_LONG <= HOST_BITS_PER_INT && HOST_BITS_PER_LONGLONG <= HOST_BITS_PER_INT)
-# define HOST_WIDE_INT int
-# else
-# if (HOST_BITS_PER_LONGLONG <= HOST_BITS_PER_LONG || ! (defined LONG_LONG_MAX || defined LLONG_MAX))
-# define HOST_WIDE_INT long
-# else
-# define HOST_WIDE_INT long long
-# endif
-# endif
-# endif
-#endif
-
-#ifndef unsigned_HOST_WIDE_INT
-#define unsigned_HOST_WIDE_INT unsigned HOST_WIDE_INT
-#endif
-
-#ifndef CHAR_BIT
-#define CHAR_BIT 8
-#endif
-
-#ifndef HOST_BITS_PER_WIDE_INT
-#define HOST_BITS_PER_WIDE_INT (CHAR_BIT * sizeof (HOST_WIDE_INT))
-#endif
-
-HOST_WIDE_INT parse_c_expression PROTO((char *, int));
+HOST_WIDEST_INT parse_c_expression PROTO((char *, int));
static int yylex PROTO((void));
-static void yyerror PROTO((char *)) __attribute__ ((noreturn));
-static HOST_WIDE_INT expression_value;
+static void yyerror PVPROTO((const char *, ...))
+ ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN;
+static HOST_WIDEST_INT expression_value;
#ifdef TEST_EXP_READER
static int expression_signedp;
#endif
@@ -145,13 +109,13 @@ extern int c89;
#define MAX_WCHAR_TYPE_SIZE WCHAR_TYPE_SIZE
#endif
-#define MAX_CHAR_TYPE_MASK (MAX_CHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT \
- ? (~ (~ (HOST_WIDE_INT) 0 << MAX_CHAR_TYPE_SIZE)) \
- : ~ (HOST_WIDE_INT) 0)
+#define MAX_CHAR_TYPE_MASK (MAX_CHAR_TYPE_SIZE < HOST_BITS_PER_WIDEST_INT \
+ ? (~ (~ (HOST_WIDEST_INT) 0 << MAX_CHAR_TYPE_SIZE)) \
+ : ~ (HOST_WIDEST_INT) 0)
-#define MAX_WCHAR_TYPE_MASK (MAX_WCHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT \
- ? ~ (~ (HOST_WIDE_INT) 0 << MAX_WCHAR_TYPE_SIZE) \
- : ~ (HOST_WIDE_INT) 0)
+#define MAX_WCHAR_TYPE_MASK (MAX_WCHAR_TYPE_SIZE < HOST_BITS_PER_WIDEST_INT \
+ ? ~ (~ (HOST_WIDEST_INT) 0 << MAX_WCHAR_TYPE_SIZE) \
+ : ~ (HOST_WIDEST_INT) 0)
/* Suppose A1 + B1 = SUM1, using 2's complement arithmetic ignoring overflow.
Suppose A, B and SUM have the same respective signs as A1, B1, and SUM1.
@@ -165,26 +129,26 @@ extern int c89;
struct constant;
-GENERIC_PTR xmalloc PROTO((size_t));
-HOST_WIDE_INT parse_escape PROTO((char **, HOST_WIDE_INT));
+HOST_WIDEST_INT parse_escape PROTO((char **, HOST_WIDEST_INT));
int check_assertion PROTO((U_CHAR *, int, int, struct arglist *));
struct hashnode *lookup PROTO((U_CHAR *, int, int));
-void error PRINTF_PROTO_1((char *, ...));
-void pedwarn PRINTF_PROTO_1((char *, ...));
-void warning PRINTF_PROTO_1((char *, ...));
+void error PVPROTO((const char *, ...)) ATTRIBUTE_PRINTF_1;
+void verror PROTO((const char *, va_list));
+void pedwarn PVPROTO((const char *, ...)) ATTRIBUTE_PRINTF_1;
+void warning PVPROTO((const char *, ...)) ATTRIBUTE_PRINTF_1;
static int parse_number PROTO((int));
-static HOST_WIDE_INT left_shift PROTO((struct constant *, unsigned_HOST_WIDE_INT));
-static HOST_WIDE_INT right_shift PROTO((struct constant *, unsigned_HOST_WIDE_INT));
+static HOST_WIDEST_INT left_shift PROTO((struct constant *, unsigned HOST_WIDEST_INT));
+static HOST_WIDEST_INT right_shift PROTO((struct constant *, unsigned HOST_WIDEST_INT));
static void integer_overflow PROTO((void));
/* `signedp' values */
#define SIGNED (~0)
#define UNSIGNED 0
-#line 195 "cexp.y"
+#line 154 "cexp.y"
typedef union {
- struct constant {HOST_WIDE_INT value; int signedp;} integer;
+ struct constant {HOST_WIDEST_INT value; int signedp;} integer;
struct name {U_CHAR *address; int length;} name;
struct arglist *keywords;
} YYSTYPE;
@@ -263,10 +227,10 @@ static const short yyrhs[] = { 35,
#if YYDEBUG != 0
static const short yyrline[] = { 0,
- 225, 235, 236, 243, 248, 251, 253, 256, 260, 262,
- 267, 272, 285, 302, 315, 321, 327, 333, 339, 342,
- 345, 352, 359, 366, 373, 376, 379, 382, 385, 388,
- 391, 394, 396, 399, 402, 404, 406, 414, 416, 429
+ 184, 194, 195, 202, 207, 210, 212, 215, 219, 221,
+ 226, 231, 244, 261, 274, 280, 286, 292, 298, 301,
+ 304, 311, 318, 325, 332, 335, 338, 341, 344, 347,
+ 350, 353, 355, 358, 361, 363, 365, 373, 375, 388
};
#endif
@@ -372,7 +336,7 @@ static const short yycheck[] = { 4,
26, 27, 23, 24, 25, 26, 27, 0, 9
};
/* -*-C-*- Note some compilers choke on comments on `#line' lines. */
-#line 3 "/usr/cygnus/gnupro-98r1/share/bison.simple"
+#line 3 "/tmp/sky/share/bison.simple"
/* Skeleton output parser for bison,
Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc.
@@ -565,7 +529,7 @@ __yy_memcpy (char *to, char *from, int count)
#endif
#endif
-#line 196 "/usr/cygnus/gnupro-98r1/share/bison.simple"
+#line 196 "/tmp/sky/share/bison.simple"
/* The user can define YYPARSE_PARAM as the name of an argument to be passed
into yyparse. The argument should have type void *.
@@ -870,7 +834,7 @@ yyreduce:
switch (yyn) {
case 1:
-#line 226 "cexp.y"
+#line 185 "cexp.y"
{
expression_value = yyvsp[0].integer.value;
#ifdef TEST_EXP_READER
@@ -879,55 +843,55 @@ case 1:
;
break;}
case 3:
-#line 237 "cexp.y"
+#line 196 "cexp.y"
{ if (pedantic)
pedwarn ("comma operator in operand of `#if'");
yyval.integer = yyvsp[0].integer; ;
break;}
case 4:
-#line 244 "cexp.y"
+#line 203 "cexp.y"
{ yyval.integer.value = - yyvsp[0].integer.value;
yyval.integer.signedp = yyvsp[0].integer.signedp;
if ((yyval.integer.value & yyvsp[0].integer.value & yyval.integer.signedp) < 0)
integer_overflow (); ;
break;}
case 5:
-#line 249 "cexp.y"
+#line 208 "cexp.y"
{ yyval.integer.value = ! yyvsp[0].integer.value;
yyval.integer.signedp = SIGNED; ;
break;}
case 6:
-#line 252 "cexp.y"
+#line 211 "cexp.y"
{ yyval.integer = yyvsp[0].integer; ;
break;}
case 7:
-#line 254 "cexp.y"
+#line 213 "cexp.y"
{ yyval.integer.value = ~ yyvsp[0].integer.value;
yyval.integer.signedp = yyvsp[0].integer.signedp; ;
break;}
case 8:
-#line 257 "cexp.y"
+#line 216 "cexp.y"
{ yyval.integer.value = check_assertion (yyvsp[0].name.address, yyvsp[0].name.length,
0, NULL_PTR);
yyval.integer.signedp = SIGNED; ;
break;}
case 9:
-#line 261 "cexp.y"
+#line 220 "cexp.y"
{ keyword_parsing = 1; ;
break;}
case 10:
-#line 263 "cexp.y"
+#line 222 "cexp.y"
{ yyval.integer.value = check_assertion (yyvsp[-4].name.address, yyvsp[-4].name.length,
1, yyvsp[-1].keywords);
keyword_parsing = 0;
yyval.integer.signedp = SIGNED; ;
break;}
case 11:
-#line 268 "cexp.y"
+#line 227 "cexp.y"
{ yyval.integer = yyvsp[-1].integer; ;
break;}
case 12:
-#line 273 "cexp.y"
+#line 232 "cexp.y"
{ yyval.integer.signedp = yyvsp[-2].integer.signedp & yyvsp[0].integer.signedp;
if (yyval.integer.signedp)
{
@@ -938,11 +902,11 @@ case 12:
integer_overflow ();
}
else
- yyval.integer.value = ((unsigned_HOST_WIDE_INT) yyvsp[-2].integer.value
+ yyval.integer.value = ((unsigned HOST_WIDEST_INT) yyvsp[-2].integer.value
* yyvsp[0].integer.value); ;
break;}
case 13:
-#line 286 "cexp.y"
+#line 245 "cexp.y"
{ if (yyvsp[0].integer.value == 0)
{
if (!skip_evaluation)
@@ -957,11 +921,11 @@ case 13:
integer_overflow ();
}
else
- yyval.integer.value = ((unsigned_HOST_WIDE_INT) yyvsp[-2].integer.value
+ yyval.integer.value = ((unsigned HOST_WIDEST_INT) yyvsp[-2].integer.value
/ yyvsp[0].integer.value); ;
break;}
case 14:
-#line 303 "cexp.y"
+#line 262 "cexp.y"
{ if (yyvsp[0].integer.value == 0)
{
if (!skip_evaluation)
@@ -972,11 +936,11 @@ case 14:
if (yyval.integer.signedp)
yyval.integer.value = yyvsp[-2].integer.value % yyvsp[0].integer.value;
else
- yyval.integer.value = ((unsigned_HOST_WIDE_INT) yyvsp[-2].integer.value
+ yyval.integer.value = ((unsigned HOST_WIDEST_INT) yyvsp[-2].integer.value
% yyvsp[0].integer.value); ;
break;}
case 15:
-#line 316 "cexp.y"
+#line 275 "cexp.y"
{ yyval.integer.value = yyvsp[-2].integer.value + yyvsp[0].integer.value;
yyval.integer.signedp = yyvsp[-2].integer.signedp & yyvsp[0].integer.signedp;
if (overflow_sum_sign (yyvsp[-2].integer.value, yyvsp[0].integer.value,
@@ -984,7 +948,7 @@ case 15:
integer_overflow (); ;
break;}
case 16:
-#line 322 "cexp.y"
+#line 281 "cexp.y"
{ yyval.integer.value = yyvsp[-2].integer.value - yyvsp[0].integer.value;
yyval.integer.signedp = yyvsp[-2].integer.signedp & yyvsp[0].integer.signedp;
if (overflow_sum_sign (yyval.integer.value, yyvsp[0].integer.value,
@@ -992,7 +956,7 @@ case 16:
integer_overflow (); ;
break;}
case 17:
-#line 328 "cexp.y"
+#line 287 "cexp.y"
{ yyval.integer.signedp = yyvsp[-2].integer.signedp;
if ((yyvsp[0].integer.value & yyvsp[0].integer.signedp) < 0)
yyval.integer.value = right_shift (&yyvsp[-2].integer, -yyvsp[0].integer.value);
@@ -1000,7 +964,7 @@ case 17:
yyval.integer.value = left_shift (&yyvsp[-2].integer, yyvsp[0].integer.value); ;
break;}
case 18:
-#line 334 "cexp.y"
+#line 293 "cexp.y"
{ yyval.integer.signedp = yyvsp[-2].integer.signedp;
if ((yyvsp[0].integer.value & yyvsp[0].integer.signedp) < 0)
yyval.integer.value = left_shift (&yyvsp[-2].integer, -yyvsp[0].integer.value);
@@ -1008,110 +972,110 @@ case 18:
yyval.integer.value = right_shift (&yyvsp[-2].integer, yyvsp[0].integer.value); ;
break;}
case 19:
-#line 340 "cexp.y"
+#line 299 "cexp.y"
{ yyval.integer.value = (yyvsp[-2].integer.value == yyvsp[0].integer.value);
yyval.integer.signedp = SIGNED; ;
break;}
case 20:
-#line 343 "cexp.y"
+#line 302 "cexp.y"
{ yyval.integer.value = (yyvsp[-2].integer.value != yyvsp[0].integer.value);
yyval.integer.signedp = SIGNED; ;
break;}
case 21:
-#line 346 "cexp.y"
+#line 305 "cexp.y"
{ yyval.integer.signedp = SIGNED;
if (yyvsp[-2].integer.signedp & yyvsp[0].integer.signedp)
yyval.integer.value = yyvsp[-2].integer.value <= yyvsp[0].integer.value;
else
- yyval.integer.value = ((unsigned_HOST_WIDE_INT) yyvsp[-2].integer.value
+ yyval.integer.value = ((unsigned HOST_WIDEST_INT) yyvsp[-2].integer.value
<= yyvsp[0].integer.value); ;
break;}
case 22:
-#line 353 "cexp.y"
+#line 312 "cexp.y"
{ yyval.integer.signedp = SIGNED;
if (yyvsp[-2].integer.signedp & yyvsp[0].integer.signedp)
yyval.integer.value = yyvsp[-2].integer.value >= yyvsp[0].integer.value;
else
- yyval.integer.value = ((unsigned_HOST_WIDE_INT) yyvsp[-2].integer.value
+ yyval.integer.value = ((unsigned HOST_WIDEST_INT) yyvsp[-2].integer.value
>= yyvsp[0].integer.value); ;
break;}
case 23:
-#line 360 "cexp.y"
+#line 319 "cexp.y"
{ yyval.integer.signedp = SIGNED;
if (yyvsp[-2].integer.signedp & yyvsp[0].integer.signedp)
yyval.integer.value = yyvsp[-2].integer.value < yyvsp[0].integer.value;
else
- yyval.integer.value = ((unsigned_HOST_WIDE_INT) yyvsp[-2].integer.value
+ yyval.integer.value = ((unsigned HOST_WIDEST_INT) yyvsp[-2].integer.value
< yyvsp[0].integer.value); ;
break;}
case 24:
-#line 367 "cexp.y"
+#line 326 "cexp.y"
{ yyval.integer.signedp = SIGNED;
if (yyvsp[-2].integer.signedp & yyvsp[0].integer.signedp)
yyval.integer.value = yyvsp[-2].integer.value > yyvsp[0].integer.value;
else
- yyval.integer.value = ((unsigned_HOST_WIDE_INT) yyvsp[-2].integer.value
+ yyval.integer.value = ((unsigned HOST_WIDEST_INT) yyvsp[-2].integer.value
> yyvsp[0].integer.value); ;
break;}
case 25:
-#line 374 "cexp.y"
+#line 333 "cexp.y"
{ yyval.integer.value = yyvsp[-2].integer.value & yyvsp[0].integer.value;
yyval.integer.signedp = yyvsp[-2].integer.signedp & yyvsp[0].integer.signedp; ;
break;}
case 26:
-#line 377 "cexp.y"
+#line 336 "cexp.y"
{ yyval.integer.value = yyvsp[-2].integer.value ^ yyvsp[0].integer.value;
yyval.integer.signedp = yyvsp[-2].integer.signedp & yyvsp[0].integer.signedp; ;
break;}
case 27:
-#line 380 "cexp.y"
+#line 339 "cexp.y"
{ yyval.integer.value = yyvsp[-2].integer.value | yyvsp[0].integer.value;
yyval.integer.signedp = yyvsp[-2].integer.signedp & yyvsp[0].integer.signedp; ;
break;}
case 28:
-#line 383 "cexp.y"
+#line 342 "cexp.y"
{ skip_evaluation += !yyvsp[-1].integer.value; ;
break;}
case 29:
-#line 385 "cexp.y"
+#line 344 "cexp.y"
{ skip_evaluation -= !yyvsp[-3].integer.value;
yyval.integer.value = (yyvsp[-3].integer.value && yyvsp[0].integer.value);
yyval.integer.signedp = SIGNED; ;
break;}
case 30:
-#line 389 "cexp.y"
+#line 348 "cexp.y"
{ skip_evaluation += !!yyvsp[-1].integer.value; ;
break;}
case 31:
-#line 391 "cexp.y"
+#line 350 "cexp.y"
{ skip_evaluation -= !!yyvsp[-3].integer.value;
yyval.integer.value = (yyvsp[-3].integer.value || yyvsp[0].integer.value);
yyval.integer.signedp = SIGNED; ;
break;}
case 32:
-#line 395 "cexp.y"
+#line 354 "cexp.y"
{ skip_evaluation += !yyvsp[-1].integer.value; ;
break;}
case 33:
-#line 397 "cexp.y"
+#line 356 "cexp.y"
{ skip_evaluation += !!yyvsp[-4].integer.value - !yyvsp[-4].integer.value; ;
break;}
case 34:
-#line 399 "cexp.y"
+#line 358 "cexp.y"
{ skip_evaluation -= !!yyvsp[-6].integer.value;
yyval.integer.value = yyvsp[-6].integer.value ? yyvsp[-3].integer.value : yyvsp[0].integer.value;
yyval.integer.signedp = yyvsp[-3].integer.signedp & yyvsp[0].integer.signedp; ;
break;}
case 35:
-#line 403 "cexp.y"
+#line 362 "cexp.y"
{ yyval.integer = yylval.integer; ;
break;}
case 36:
-#line 405 "cexp.y"
+#line 364 "cexp.y"
{ yyval.integer = yylval.integer; ;
break;}
case 37:
-#line 407 "cexp.y"
+#line 366 "cexp.y"
{ if (warn_undef && !skip_evaluation)
warning ("`%.*s' is not defined",
yyvsp[0].name.length, yyvsp[0].name.address);
@@ -1119,11 +1083,11 @@ case 37:
yyval.integer.signedp = SIGNED; ;
break;}
case 38:
-#line 415 "cexp.y"
+#line 374 "cexp.y"
{ yyval.keywords = 0; ;
break;}
case 39:
-#line 417 "cexp.y"
+#line 376 "cexp.y"
{ struct arglist *temp;
yyval.keywords = (struct arglist *) xmalloc (sizeof (struct arglist));
yyval.keywords->next = yyvsp[-2].keywords;
@@ -1138,7 +1102,7 @@ case 39:
temp->next->length = 1; ;
break;}
case 40:
-#line 430 "cexp.y"
+#line 389 "cexp.y"
{ yyval.keywords = (struct arglist *) xmalloc (sizeof (struct arglist));
yyval.keywords->name = yyvsp[-1].name.address;
yyval.keywords->length = yyvsp[-1].name.length;
@@ -1146,7 +1110,7 @@ case 40:
break;}
}
/* the action file gets copied in in place of this dollarsign */
-#line 498 "/usr/cygnus/gnupro-98r1/share/bison.simple"
+#line 498 "/tmp/sky/share/bison.simple"
yyvsp -= yylen;
yyssp -= yylen;
@@ -1342,7 +1306,7 @@ yyerrhandle:
yystate = yyn;
goto yynewstate;
}
-#line 435 "cexp.y"
+#line 394 "cexp.y"
/* During parsing of a C expression, the pointer to the next character
@@ -1362,7 +1326,7 @@ parse_number (olen)
{
register char *p = lexptr;
register int c;
- register unsigned_HOST_WIDE_INT n = 0, nd, max_over_base;
+ register unsigned HOST_WIDEST_INT n = 0, nd, max_over_base;
register int base = 10;
register int len = olen;
register int overflow = 0;
@@ -1380,7 +1344,7 @@ parse_number (olen)
}
}
- max_over_base = (unsigned_HOST_WIDE_INT) -1 / base;
+ max_over_base = (unsigned HOST_WIDEST_INT) -1 / base;
for (; len > 0; len--) {
c = *p++;
@@ -1409,12 +1373,9 @@ parse_number (olen)
else {
if (c == '.' || c == 'e' || c == 'E' || c == 'p' || c == 'P')
yyerror ("Floating point numbers not allowed in #if expressions");
- else {
- char *buf = (char *) alloca (p - lexptr + 40);
- sprintf (buf, "missing white space after number `%.*s'",
+ else
+ yyerror ("missing white space after number `%.*s'",
(int) (p - lexptr - 1), lexptr);
- yyerror (buf);
- }
}
if (--len == 0)
@@ -1438,7 +1399,7 @@ parse_number (olen)
pedwarn ("integer constant out of range");
/* If too big to be signed, consider it unsigned. */
- if (((HOST_WIDE_INT) n & yylval.integer.signedp) < 0)
+ if (((HOST_WIDEST_INT) n & yylval.integer.signedp) < 0)
{
if (base == 10)
warning ("integer constant is so large that it is unsigned");
@@ -1451,7 +1412,7 @@ parse_number (olen)
}
struct token {
- char *operator;
+ const char *operator;
int token;
};
@@ -1479,7 +1440,7 @@ yylex ()
register unsigned char *tokstart;
register struct token *toktab;
int wide_flag;
- HOST_WIDE_INT mask;
+ HOST_WIDEST_INT mask;
retry:
@@ -1491,11 +1452,7 @@ yylex ()
if (c == *toktab->operator && tokstart[1] == toktab->operator[1]) {
lexptr += 2;
if (toktab->token == ERROR)
- {
- char *buf = (char *) alloca (40);
- sprintf (buf, "`%s' not allowed in operand of `#if'", toktab->operator);
- yyerror (buf);
- }
+ yyerror ("`%s' not allowed in operand of `#if'", toktab->operator);
return toktab->token;
}
@@ -1550,7 +1507,7 @@ yylex ()
handles multicharacter constants and wide characters.
It is mostly copied from c-lex.c. */
{
- register HOST_WIDE_INT result = 0;
+ register HOST_WIDEST_INT result = 0;
register int num_chars = 0;
int chars_seen = 0;
unsigned width = MAX_CHAR_TYPE_SIZE;
@@ -1665,12 +1622,12 @@ yylex ()
sizeof ("__CHAR_UNSIGNED__") - 1, -1)
|| ((result >> (num_bits - 1)) & 1) == 0)
yylval.integer.value
- = result & (~ (unsigned_HOST_WIDE_INT) 0
- >> (HOST_BITS_PER_WIDE_INT - num_bits));
+ = result & (~ (unsigned HOST_WIDEST_INT) 0
+ >> (HOST_BITS_PER_WIDEST_INT - num_bits));
else
yylval.integer.value
- = result | ~(~ (unsigned_HOST_WIDE_INT) 0
- >> (HOST_BITS_PER_WIDE_INT - num_bits));
+ = result | ~(~ (unsigned HOST_WIDEST_INT) 0
+ >> (HOST_BITS_PER_WIDEST_INT - num_bits));
}
else
{
@@ -1796,10 +1753,10 @@ yylex ()
If \ is followed by 000, we return 0 and leave the string pointer
after the zeros. A value of 0 does not mean end of string. */
-HOST_WIDE_INT
+HOST_WIDEST_INT
parse_escape (string_ptr, result_mask)
char **string_ptr;
- HOST_WIDE_INT result_mask;
+ HOST_WIDEST_INT result_mask;
{
register int c = *(*string_ptr)++;
switch (c)
@@ -1838,7 +1795,7 @@ parse_escape (string_ptr, result_mask)
case '6':
case '7':
{
- register HOST_WIDE_INT i = c - '0';
+ register HOST_WIDEST_INT i = c - '0';
register int count = 0;
while (++count < 3)
{
@@ -1860,7 +1817,7 @@ parse_escape (string_ptr, result_mask)
}
case 'x':
{
- register unsigned_HOST_WIDE_INT i = 0, overflow = 0;
+ register unsigned HOST_WIDEST_INT i = 0, overflow = 0;
register int digits_found = 0, digit;
for (;;)
{
@@ -1895,46 +1852,37 @@ parse_escape (string_ptr, result_mask)
}
static void
-yyerror (s)
- char *s;
-{
- error ("%s", s);
- skip_evaluation = 0;
- longjmp (parse_return_error, 1);
-}
-
-static void
integer_overflow ()
{
if (!skip_evaluation && pedantic)
pedwarn ("integer overflow in preprocessor expression");
}
-static HOST_WIDE_INT
+static HOST_WIDEST_INT
left_shift (a, b)
struct constant *a;
- unsigned_HOST_WIDE_INT b;
+ unsigned HOST_WIDEST_INT b;
{
/* It's unclear from the C standard whether shifts can overflow.
The following code ignores overflow; perhaps a C standard
interpretation ruling is needed. */
- if (b >= HOST_BITS_PER_WIDE_INT)
+ if (b >= HOST_BITS_PER_WIDEST_INT)
return 0;
else
- return (unsigned_HOST_WIDE_INT) a->value << b;
+ return (unsigned HOST_WIDEST_INT) a->value << b;
}
-static HOST_WIDE_INT
+static HOST_WIDEST_INT
right_shift (a, b)
struct constant *a;
- unsigned_HOST_WIDE_INT b;
+ unsigned HOST_WIDEST_INT b;
{
- if (b >= HOST_BITS_PER_WIDE_INT)
- return a->signedp ? a->value >> (HOST_BITS_PER_WIDE_INT - 1) : 0;
+ if (b >= HOST_BITS_PER_WIDEST_INT)
+ return a->signedp ? a->value >> (HOST_BITS_PER_WIDEST_INT - 1) : 0;
else if (a->signedp)
return a->value >> b;
else
- return (unsigned_HOST_WIDE_INT) a->value >> b;
+ return (unsigned HOST_WIDEST_INT) a->value >> b;
}
/* This page contains the entry point to this file. */
@@ -1947,7 +1895,7 @@ right_shift (a, b)
We do not support C comments. They should be removed before
this function is called. */
-HOST_WIDE_INT
+HOST_WIDEST_INT
parse_c_expression (string, warn_undefined)
char *string;
int warn_undefined;
@@ -1969,6 +1917,27 @@ parse_c_expression (string, warn_undefined)
return expression_value; /* set by yyparse () */
}
+
+static void
+yyerror VPROTO ((const char * msgid, ...))
+{
+#ifndef ANSI_PROTOTYPES
+ const char * msgid;
+#endif
+ va_list args;
+
+ VA_START (args, msgid);
+
+#ifndef ANSI_PROTOTYPES
+ msgid = va_arg (args, const char *);
+#endif
+
+ verror (msgid, args);
+ va_end (args);
+ skip_evaluation = 0;
+ longjmp (parse_return_error, 1);
+}
+
#ifdef TEST_EXP_READER
@@ -1978,10 +1947,11 @@ extern int yydebug;
int pedantic;
int traditional;
+int c89;
int main PROTO((int, char **));
static void initialize_random_junk PROTO((void));
-static void print_unsigned_host_wide_int PROTO((unsigned_HOST_WIDE_INT));
+static void print_unsigned_host_widest_int PROTO((unsigned HOST_WIDEST_INT));
/* Main program for testing purposes. */
int
@@ -1991,12 +1961,13 @@ main (argc, argv)
{
int n, c;
char buf[1024];
- unsigned_HOST_WIDE_INT u;
+ unsigned HOST_WIDEST_INT u;
pedantic = 1 < argc;
traditional = 2 < argc;
+ c89 = 3 < argc;
#if YYDEBUG
- yydebug = 3 < argc;
+ yydebug = 4 < argc;
#endif
initialize_random_junk ();
@@ -2009,7 +1980,7 @@ main (argc, argv)
break;
parse_c_expression (buf, 1);
printf ("parser returned ");
- u = (unsigned_HOST_WIDE_INT) expression_value;
+ u = (unsigned HOST_WIDEST_INT) expression_value;
if (expression_value < 0 && expression_signedp) {
u = -u;
printf ("-");
@@ -2017,7 +1988,7 @@ main (argc, argv)
if (u == 0)
printf ("0");
else
- print_unsigned_host_wide_int (u);
+ print_unsigned_host_widest_int (u);
if (! expression_signedp)
printf("u");
printf ("\n");
@@ -2027,11 +1998,11 @@ main (argc, argv)
}
static void
-print_unsigned_host_wide_int (u)
- unsigned_HOST_WIDE_INT u;
+print_unsigned_host_widest_int (u)
+ unsigned HOST_WIDEST_INT u;
{
if (u) {
- print_unsigned_host_wide_int (u / 10);
+ print_unsigned_host_widest_int (u / 10);
putchar ('0' + (int) (u % 10));
}
}
@@ -2079,65 +2050,66 @@ initialize_random_junk ()
}
void
-error VPROTO ((char * msg, ...))
+error VPROTO ((char * msgid, ...))
{
-#ifndef __STDC__
- char * msg;
+#ifndef ANSI_PROTOTYPES
+ char * msgid;
#endif
va_list args;
- VA_START (args, msg);
-
-#ifndef __STDC__
- msg = va_arg (args, char *);
+ VA_START (args, msgid);
+
+#ifndef ANSI_PROTOTYPES
+ msgid = va_arg (args, char *);
#endif
-
+
fprintf (stderr, "error: ");
- vfprintf (stderr, msg, args);
+ vfprintf (stderr, _(msgid), args);
fprintf (stderr, "\n");
va_end (args);
}
void
-pedwarn VPROTO ((char * msg, ...))
+pedwarn VPROTO ((char * msgid, ...))
{
-#ifndef __STDC__
- char * msg;
+#ifndef ANSI_PROTOTYPES
+ char * msgid;
#endif
va_list args;
- VA_START (args, msg);
-
-#ifndef __STDC__
- msg = va_arg (args, char *);
+ VA_START (args, msgid);
+
+#ifndef ANSI_PROTOTYPES
+ msgid = va_arg (args, char *);
#endif
-
+
fprintf (stderr, "pedwarn: ");
- vfprintf (stderr, msg, args);
+ vfprintf (stderr, _(msgid), args);
fprintf (stderr, "\n");
va_end (args);
}
void
-warning VPROTO ((char * msg, ...))
+warning VPROTO ((char * msgid, ...))
{
-#ifndef __STDC__
- char * msg;
+#ifndef ANSI_PROTOTYPES
+ char * msgid;
#endif
va_list args;
- VA_START (args, msg);
-
-#ifndef __STDC__
- msg = va_arg (args, char *);
+ VA_START (args, msgid);
+
+#ifndef ANSI_PROTOTYPES
+ msgid = va_arg (args, char *);
#endif
-
+
fprintf (stderr, "warning: ");
- vfprintf (stderr, msg, args);
+ vfprintf (stderr, _(msgid), args);
fprintf (stderr, "\n");
va_end (args);
}
+
int
check_assertion (name, sym_length, tokens_specified, tokens)
U_CHAR *name;
@@ -2157,10 +2129,10 @@ lookup (name, len, hash)
return (DEFAULT_SIGNED_CHAR) ? 0 : ((struct hashnode *) -1);
}
-GENERIC_PTR
+PTR
xmalloc (size)
- size_t size;
+ size_t size;
{
- return (GENERIC_PTR) malloc (size);
+ return (PTR) malloc (size);
}
#endif
diff --git a/gcc/cexp.y b/gcc/cexp.y
index c7d25c19658..9364ac3a8a0 100644
--- a/gcc/cexp.y
+++ b/gcc/cexp.y
@@ -1,5 +1,5 @@
/* Parse C expressions for CCCP.
- Copyright (C) 1987, 1992, 94 - 97, 1998 Free Software Foundation.
+ Copyright (C) 1987, 92, 94-98, 1999 Free Software Foundation.
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
@@ -27,14 +27,10 @@ Boston, MA 02111-1307, USA.
%{
#include "config.h"
-#define PRINTF_PROTO(ARGS, m, n) PVPROTO (ARGS) ATTRIBUTE_PRINTF(m, n)
-
-#define PRINTF_PROTO_1(ARGS) PRINTF_PROTO(ARGS, 1, 2)
-
#include "system.h"
+#include "intl.h"
#include <setjmp.h>
/* #define YYDEBUG 1 */
-#include "gansidecl.h"
#ifdef MULTIBYTE_CHARS
#include "mbchar.h"
@@ -51,44 +47,12 @@ struct arglist {
int argno;
};
-/* Find the largest host integer type and set its size and type.
- Watch out: on some crazy hosts `long' is shorter than `int'. */
-
-#ifndef HOST_WIDE_INT
-# if HAVE_INTTYPES_H
-# include <inttypes.h>
-# define HOST_WIDE_INT intmax_t
-# define unsigned_HOST_WIDE_INT uintmax_t
-# else
-# if (HOST_BITS_PER_LONG <= HOST_BITS_PER_INT && HOST_BITS_PER_LONGLONG <= HOST_BITS_PER_INT)
-# define HOST_WIDE_INT int
-# else
-# if (HOST_BITS_PER_LONGLONG <= HOST_BITS_PER_LONG || ! (defined LONG_LONG_MAX || defined LLONG_MAX))
-# define HOST_WIDE_INT long
-# else
-# define HOST_WIDE_INT long long
-# endif
-# endif
-# endif
-#endif
-
-#ifndef unsigned_HOST_WIDE_INT
-#define unsigned_HOST_WIDE_INT unsigned HOST_WIDE_INT
-#endif
-
-#ifndef CHAR_BIT
-#define CHAR_BIT 8
-#endif
-
-#ifndef HOST_BITS_PER_WIDE_INT
-#define HOST_BITS_PER_WIDE_INT (CHAR_BIT * sizeof (HOST_WIDE_INT))
-#endif
-
-HOST_WIDE_INT parse_c_expression PROTO((char *, int));
+HOST_WIDEST_INT parse_c_expression PROTO((char *, int));
static int yylex PROTO((void));
-static void yyerror PROTO((char *)) __attribute__ ((noreturn));
-static HOST_WIDE_INT expression_value;
+static void yyerror PVPROTO((const char *, ...))
+ ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN;
+static HOST_WIDEST_INT expression_value;
#ifdef TEST_EXP_READER
static int expression_signedp;
#endif
@@ -149,13 +113,13 @@ extern int c89;
#define MAX_WCHAR_TYPE_SIZE WCHAR_TYPE_SIZE
#endif
-#define MAX_CHAR_TYPE_MASK (MAX_CHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT \
- ? (~ (~ (HOST_WIDE_INT) 0 << MAX_CHAR_TYPE_SIZE)) \
- : ~ (HOST_WIDE_INT) 0)
+#define MAX_CHAR_TYPE_MASK (MAX_CHAR_TYPE_SIZE < HOST_BITS_PER_WIDEST_INT \
+ ? (~ (~ (HOST_WIDEST_INT) 0 << MAX_CHAR_TYPE_SIZE)) \
+ : ~ (HOST_WIDEST_INT) 0)
-#define MAX_WCHAR_TYPE_MASK (MAX_WCHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT \
- ? ~ (~ (HOST_WIDE_INT) 0 << MAX_WCHAR_TYPE_SIZE) \
- : ~ (HOST_WIDE_INT) 0)
+#define MAX_WCHAR_TYPE_MASK (MAX_WCHAR_TYPE_SIZE < HOST_BITS_PER_WIDEST_INT \
+ ? ~ (~ (HOST_WIDEST_INT) 0 << MAX_WCHAR_TYPE_SIZE) \
+ : ~ (HOST_WIDEST_INT) 0)
/* Suppose A1 + B1 = SUM1, using 2's complement arithmetic ignoring overflow.
Suppose A, B and SUM have the same respective signs as A1, B1, and SUM1.
@@ -169,17 +133,17 @@ extern int c89;
struct constant;
-GENERIC_PTR xmalloc PROTO((size_t));
-HOST_WIDE_INT parse_escape PROTO((char **, HOST_WIDE_INT));
+HOST_WIDEST_INT parse_escape PROTO((char **, HOST_WIDEST_INT));
int check_assertion PROTO((U_CHAR *, int, int, struct arglist *));
struct hashnode *lookup PROTO((U_CHAR *, int, int));
-void error PRINTF_PROTO_1((char *, ...));
-void pedwarn PRINTF_PROTO_1((char *, ...));
-void warning PRINTF_PROTO_1((char *, ...));
+void error PVPROTO((const char *, ...)) ATTRIBUTE_PRINTF_1;
+void verror PROTO((const char *, va_list));
+void pedwarn PVPROTO((const char *, ...)) ATTRIBUTE_PRINTF_1;
+void warning PVPROTO((const char *, ...)) ATTRIBUTE_PRINTF_1;
static int parse_number PROTO((int));
-static HOST_WIDE_INT left_shift PROTO((struct constant *, unsigned_HOST_WIDE_INT));
-static HOST_WIDE_INT right_shift PROTO((struct constant *, unsigned_HOST_WIDE_INT));
+static HOST_WIDEST_INT left_shift PROTO((struct constant *, unsigned HOST_WIDEST_INT));
+static HOST_WIDEST_INT right_shift PROTO((struct constant *, unsigned HOST_WIDEST_INT));
static void integer_overflow PROTO((void));
/* `signedp' values */
@@ -188,7 +152,7 @@ static void integer_overflow PROTO((void));
%}
%union {
- struct constant {HOST_WIDE_INT value; int signedp;} integer;
+ struct constant {HOST_WIDEST_INT value; int signedp;} integer;
struct name {U_CHAR *address; int length;} name;
struct arglist *keywords;
}
@@ -275,7 +239,7 @@ exp : exp '*' exp
integer_overflow ();
}
else
- $$.value = ((unsigned_HOST_WIDE_INT) $1.value
+ $$.value = ((unsigned HOST_WIDEST_INT) $1.value
* $3.value); }
| exp '/' exp
{ if ($3.value == 0)
@@ -292,7 +256,7 @@ exp : exp '*' exp
integer_overflow ();
}
else
- $$.value = ((unsigned_HOST_WIDE_INT) $1.value
+ $$.value = ((unsigned HOST_WIDEST_INT) $1.value
/ $3.value); }
| exp '%' exp
{ if ($3.value == 0)
@@ -305,7 +269,7 @@ exp : exp '*' exp
if ($$.signedp)
$$.value = $1.value % $3.value;
else
- $$.value = ((unsigned_HOST_WIDE_INT) $1.value
+ $$.value = ((unsigned HOST_WIDEST_INT) $1.value
% $3.value); }
| exp '+' exp
{ $$.value = $1.value + $3.value;
@@ -342,28 +306,28 @@ exp : exp '*' exp
if ($1.signedp & $3.signedp)
$$.value = $1.value <= $3.value;
else
- $$.value = ((unsigned_HOST_WIDE_INT) $1.value
+ $$.value = ((unsigned HOST_WIDEST_INT) $1.value
<= $3.value); }
| exp GEQ exp
{ $$.signedp = SIGNED;
if ($1.signedp & $3.signedp)
$$.value = $1.value >= $3.value;
else
- $$.value = ((unsigned_HOST_WIDE_INT) $1.value
+ $$.value = ((unsigned HOST_WIDEST_INT) $1.value
>= $3.value); }
| exp '<' exp
{ $$.signedp = SIGNED;
if ($1.signedp & $3.signedp)
$$.value = $1.value < $3.value;
else
- $$.value = ((unsigned_HOST_WIDE_INT) $1.value
+ $$.value = ((unsigned HOST_WIDEST_INT) $1.value
< $3.value); }
| exp '>' exp
{ $$.signedp = SIGNED;
if ($1.signedp & $3.signedp)
$$.value = $1.value > $3.value;
else
- $$.value = ((unsigned_HOST_WIDE_INT) $1.value
+ $$.value = ((unsigned HOST_WIDEST_INT) $1.value
> $3.value); }
| exp '&' exp
{ $$.value = $1.value & $3.value;
@@ -446,7 +410,7 @@ parse_number (olen)
{
register char *p = lexptr;
register int c;
- register unsigned_HOST_WIDE_INT n = 0, nd, max_over_base;
+ register unsigned HOST_WIDEST_INT n = 0, nd, max_over_base;
register int base = 10;
register int len = olen;
register int overflow = 0;
@@ -464,7 +428,7 @@ parse_number (olen)
}
}
- max_over_base = (unsigned_HOST_WIDE_INT) -1 / base;
+ max_over_base = (unsigned HOST_WIDEST_INT) -1 / base;
for (; len > 0; len--) {
c = *p++;
@@ -493,12 +457,9 @@ parse_number (olen)
else {
if (c == '.' || c == 'e' || c == 'E' || c == 'p' || c == 'P')
yyerror ("Floating point numbers not allowed in #if expressions");
- else {
- char *buf = (char *) alloca (p - lexptr + 40);
- sprintf (buf, "missing white space after number `%.*s'",
+ else
+ yyerror ("missing white space after number `%.*s'",
(int) (p - lexptr - 1), lexptr);
- yyerror (buf);
- }
}
if (--len == 0)
@@ -522,7 +483,7 @@ parse_number (olen)
pedwarn ("integer constant out of range");
/* If too big to be signed, consider it unsigned. */
- if (((HOST_WIDE_INT) n & yylval.integer.signedp) < 0)
+ if (((HOST_WIDEST_INT) n & yylval.integer.signedp) < 0)
{
if (base == 10)
warning ("integer constant is so large that it is unsigned");
@@ -535,7 +496,7 @@ parse_number (olen)
}
struct token {
- char *operator;
+ const char *operator;
int token;
};
@@ -563,7 +524,7 @@ yylex ()
register unsigned char *tokstart;
register struct token *toktab;
int wide_flag;
- HOST_WIDE_INT mask;
+ HOST_WIDEST_INT mask;
retry:
@@ -575,11 +536,7 @@ yylex ()
if (c == *toktab->operator && tokstart[1] == toktab->operator[1]) {
lexptr += 2;
if (toktab->token == ERROR)
- {
- char *buf = (char *) alloca (40);
- sprintf (buf, "`%s' not allowed in operand of `#if'", toktab->operator);
- yyerror (buf);
- }
+ yyerror ("`%s' not allowed in operand of `#if'", toktab->operator);
return toktab->token;
}
@@ -634,7 +591,7 @@ yylex ()
handles multicharacter constants and wide characters.
It is mostly copied from c-lex.c. */
{
- register HOST_WIDE_INT result = 0;
+ register HOST_WIDEST_INT result = 0;
register int num_chars = 0;
int chars_seen = 0;
unsigned width = MAX_CHAR_TYPE_SIZE;
@@ -749,12 +706,12 @@ yylex ()
sizeof ("__CHAR_UNSIGNED__") - 1, -1)
|| ((result >> (num_bits - 1)) & 1) == 0)
yylval.integer.value
- = result & (~ (unsigned_HOST_WIDE_INT) 0
- >> (HOST_BITS_PER_WIDE_INT - num_bits));
+ = result & (~ (unsigned HOST_WIDEST_INT) 0
+ >> (HOST_BITS_PER_WIDEST_INT - num_bits));
else
yylval.integer.value
- = result | ~(~ (unsigned_HOST_WIDE_INT) 0
- >> (HOST_BITS_PER_WIDE_INT - num_bits));
+ = result | ~(~ (unsigned HOST_WIDEST_INT) 0
+ >> (HOST_BITS_PER_WIDEST_INT - num_bits));
}
else
{
@@ -880,10 +837,10 @@ yylex ()
If \ is followed by 000, we return 0 and leave the string pointer
after the zeros. A value of 0 does not mean end of string. */
-HOST_WIDE_INT
+HOST_WIDEST_INT
parse_escape (string_ptr, result_mask)
char **string_ptr;
- HOST_WIDE_INT result_mask;
+ HOST_WIDEST_INT result_mask;
{
register int c = *(*string_ptr)++;
switch (c)
@@ -922,7 +879,7 @@ parse_escape (string_ptr, result_mask)
case '6':
case '7':
{
- register HOST_WIDE_INT i = c - '0';
+ register HOST_WIDEST_INT i = c - '0';
register int count = 0;
while (++count < 3)
{
@@ -944,7 +901,7 @@ parse_escape (string_ptr, result_mask)
}
case 'x':
{
- register unsigned_HOST_WIDE_INT i = 0, overflow = 0;
+ register unsigned HOST_WIDEST_INT i = 0, overflow = 0;
register int digits_found = 0, digit;
for (;;)
{
@@ -979,46 +936,37 @@ parse_escape (string_ptr, result_mask)
}
static void
-yyerror (s)
- char *s;
-{
- error ("%s", s);
- skip_evaluation = 0;
- longjmp (parse_return_error, 1);
-}
-
-static void
integer_overflow ()
{
if (!skip_evaluation && pedantic)
pedwarn ("integer overflow in preprocessor expression");
}
-static HOST_WIDE_INT
+static HOST_WIDEST_INT
left_shift (a, b)
struct constant *a;
- unsigned_HOST_WIDE_INT b;
+ unsigned HOST_WIDEST_INT b;
{
/* It's unclear from the C standard whether shifts can overflow.
The following code ignores overflow; perhaps a C standard
interpretation ruling is needed. */
- if (b >= HOST_BITS_PER_WIDE_INT)
+ if (b >= HOST_BITS_PER_WIDEST_INT)
return 0;
else
- return (unsigned_HOST_WIDE_INT) a->value << b;
+ return (unsigned HOST_WIDEST_INT) a->value << b;
}
-static HOST_WIDE_INT
+static HOST_WIDEST_INT
right_shift (a, b)
struct constant *a;
- unsigned_HOST_WIDE_INT b;
+ unsigned HOST_WIDEST_INT b;
{
- if (b >= HOST_BITS_PER_WIDE_INT)
- return a->signedp ? a->value >> (HOST_BITS_PER_WIDE_INT - 1) : 0;
+ if (b >= HOST_BITS_PER_WIDEST_INT)
+ return a->signedp ? a->value >> (HOST_BITS_PER_WIDEST_INT - 1) : 0;
else if (a->signedp)
return a->value >> b;
else
- return (unsigned_HOST_WIDE_INT) a->value >> b;
+ return (unsigned HOST_WIDEST_INT) a->value >> b;
}
/* This page contains the entry point to this file. */
@@ -1031,7 +979,7 @@ right_shift (a, b)
We do not support C comments. They should be removed before
this function is called. */
-HOST_WIDE_INT
+HOST_WIDEST_INT
parse_c_expression (string, warn_undefined)
char *string;
int warn_undefined;
@@ -1053,6 +1001,27 @@ parse_c_expression (string, warn_undefined)
return expression_value; /* set by yyparse () */
}
+
+static void
+yyerror VPROTO ((const char * msgid, ...))
+{
+#ifndef ANSI_PROTOTYPES
+ const char * msgid;
+#endif
+ va_list args;
+
+ VA_START (args, msgid);
+
+#ifndef ANSI_PROTOTYPES
+ msgid = va_arg (args, const char *);
+#endif
+
+ verror (msgid, args);
+ va_end (args);
+ skip_evaluation = 0;
+ longjmp (parse_return_error, 1);
+}
+
#ifdef TEST_EXP_READER
@@ -1062,10 +1031,11 @@ extern int yydebug;
int pedantic;
int traditional;
+int c89;
int main PROTO((int, char **));
static void initialize_random_junk PROTO((void));
-static void print_unsigned_host_wide_int PROTO((unsigned_HOST_WIDE_INT));
+static void print_unsigned_host_widest_int PROTO((unsigned HOST_WIDEST_INT));
/* Main program for testing purposes. */
int
@@ -1075,12 +1045,13 @@ main (argc, argv)
{
int n, c;
char buf[1024];
- unsigned_HOST_WIDE_INT u;
+ unsigned HOST_WIDEST_INT u;
pedantic = 1 < argc;
traditional = 2 < argc;
+ c89 = 3 < argc;
#if YYDEBUG
- yydebug = 3 < argc;
+ yydebug = 4 < argc;
#endif
initialize_random_junk ();
@@ -1093,7 +1064,7 @@ main (argc, argv)
break;
parse_c_expression (buf, 1);
printf ("parser returned ");
- u = (unsigned_HOST_WIDE_INT) expression_value;
+ u = (unsigned HOST_WIDEST_INT) expression_value;
if (expression_value < 0 && expression_signedp) {
u = -u;
printf ("-");
@@ -1101,7 +1072,7 @@ main (argc, argv)
if (u == 0)
printf ("0");
else
- print_unsigned_host_wide_int (u);
+ print_unsigned_host_widest_int (u);
if (! expression_signedp)
printf("u");
printf ("\n");
@@ -1111,11 +1082,11 @@ main (argc, argv)
}
static void
-print_unsigned_host_wide_int (u)
- unsigned_HOST_WIDE_INT u;
+print_unsigned_host_widest_int (u)
+ unsigned HOST_WIDEST_INT u;
{
if (u) {
- print_unsigned_host_wide_int (u / 10);
+ print_unsigned_host_widest_int (u / 10);
putchar ('0' + (int) (u % 10));
}
}
@@ -1163,65 +1134,66 @@ initialize_random_junk ()
}
void
-error VPROTO ((char * msg, ...))
+error VPROTO ((char * msgid, ...))
{
-#ifndef __STDC__
- char * msg;
+#ifndef ANSI_PROTOTYPES
+ char * msgid;
#endif
va_list args;
- VA_START (args, msg);
-
-#ifndef __STDC__
- msg = va_arg (args, char *);
+ VA_START (args, msgid);
+
+#ifndef ANSI_PROTOTYPES
+ msgid = va_arg (args, char *);
#endif
-
+
fprintf (stderr, "error: ");
- vfprintf (stderr, msg, args);
+ vfprintf (stderr, _(msgid), args);
fprintf (stderr, "\n");
va_end (args);
}
void
-pedwarn VPROTO ((char * msg, ...))
+pedwarn VPROTO ((char * msgid, ...))
{
-#ifndef __STDC__
- char * msg;
+#ifndef ANSI_PROTOTYPES
+ char * msgid;
#endif
va_list args;
- VA_START (args, msg);
-
-#ifndef __STDC__
- msg = va_arg (args, char *);
+ VA_START (args, msgid);
+
+#ifndef ANSI_PROTOTYPES
+ msgid = va_arg (args, char *);
#endif
-
+
fprintf (stderr, "pedwarn: ");
- vfprintf (stderr, msg, args);
+ vfprintf (stderr, _(msgid), args);
fprintf (stderr, "\n");
va_end (args);
}
void
-warning VPROTO ((char * msg, ...))
+warning VPROTO ((char * msgid, ...))
{
-#ifndef __STDC__
- char * msg;
+#ifndef ANSI_PROTOTYPES
+ char * msgid;
#endif
va_list args;
- VA_START (args, msg);
-
-#ifndef __STDC__
- msg = va_arg (args, char *);
+ VA_START (args, msgid);
+
+#ifndef ANSI_PROTOTYPES
+ msgid = va_arg (args, char *);
#endif
-
+
fprintf (stderr, "warning: ");
- vfprintf (stderr, msg, args);
+ vfprintf (stderr, _(msgid), args);
fprintf (stderr, "\n");
va_end (args);
}
+
int
check_assertion (name, sym_length, tokens_specified, tokens)
U_CHAR *name;
@@ -1241,10 +1213,10 @@ lookup (name, len, hash)
return (DEFAULT_SIGNED_CHAR) ? 0 : ((struct hashnode *) -1);
}
-GENERIC_PTR
+PTR
xmalloc (size)
- size_t size;
+ size_t size;
{
- return (GENERIC_PTR) malloc (size);
+ return (PTR) malloc (size);
}
#endif
diff --git a/gcc/ch/ChangeLog b/gcc/ch/ChangeLog
index 450c956793a..11c859d21c3 100644
--- a/gcc/ch/ChangeLog
+++ b/gcc/ch/ChangeLog
@@ -1,3 +1,112 @@
+1999-02-20 Craig Burley <craig@jcb-sc.com>
+
+ * Make-lang.in (CHILL.info): Depend on intermediate ch/chill.info
+ target instead of the chill.texi file.
+ (ch/chill.info): New target, depends on the chill.texi source file.
+ Its command writes ch/chill.info instead of chill.info.
+ (CHILL.install-info): Install from ch/chill.info instead of
+ chill.info.
+ If any ch/chill.info* files exist, delete *all* chill.info* files
+ in $infodir first, not just the ones corresponding to the
+ files to be installed (just in case the docs get smaller).
+
+Sun Jan 31 20:34:29 1999 Zack Weinberg <zack@rabi.columbia.edu>
+
+ * decl2.c: Don't define flag_no_ident here. Don't process
+ -f(no-)ident here.
+ * ch-tree.h: Don't declare flag_no_ident here.
+ * lang-specs.h: Map -Qn to -fno-ident.
+
+Tue Jan 19 23:24:36 1999 Jeffrey A Law (law@cygnus.com)
+
+ * Makefile.in (typeck.o): Depend on insn-codes.h.
+ * actions.c (chill_handle_multi_case_label): Initialize "expr".
+ * decl.c (poplevel): Initialize "block_previously_created".
+ * expr.c (chill_expand_expr): Initialize "size0" and "size1".
+ (fold_set_expr): Initialize "buffer1".
+ * inout.c (process_io_list): Initialize "to_assign".
+ (check_exprlist): Initialize "result".
+ * parse.c (expand_expr): Declare.
+ (parse_multi_dimension_case_action): Initialize "end_case_label".
+ * tasking.c (build_start_process): Initialize "struct_type_node".
+ * typeck.c (apply_chill_field_layout): Initialize "word".
+ (type_for_mode); Unconditionally cast RHS & LHS to ints to shut up
+ signed/unsigned comparison warning.
+
+Mon Jan 18 11:55:06 1999 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * ch-tree.h: Remove conflicting prototypes for pedwarn,
+ warning_with_decl, and make_dcl_rtl.
+
+Sun Jan 17 21:53:23 1999 Jeffrey A Law (law@cygnus.com)
+
+ * Makefile.in: Do not put ^Ls at the start of a line.
+
+Wed Jan 6 02:53:38 1999 Jeffrey A Law (law@cygnus.com)
+
+ * Makefile.in: Add some missing $(exeext). Remove some obsolete
+ runtime stuff.
+ * Make-lang.in: Similarly.
+
+Tue Nov 24 09:57:34 1998 Jeffrey A Law (law@cygnus.com)
+
+ * Makefile.in (lex.c): Do not depend on hash.h.
+ (lex.o): Depend on hash.h.
+
+Mon Oct 19 12:13:47 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * Makefile.in (lex.o): Depend on dwarfout.h.
+
+ * lang-specs.h: Add missing braces in initializer.
+
+ * lex.c: Include dwarfout.h, if DWARF_DEBUGGING_INFO is defined.
+
+Thu Oct 15 09:25:21 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * expr.c (build_chill_card): Use &&, not &, when comparing truth
+ values.
+
+ * parse.c (parse_spec_module): Remove unused variable
+ `module_name', but preserve function call from initialization.
+ (parse_operand6): Mark variable `location' with ATTRIBUTE_UNUSED.
+
+ * inout.c (init_text_location): Remove unused variable `textlength'.
+
+Wed Oct 14 22:19:48 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * typeck.c (build_chill_cast): Fix typo in assignment statement.
+
+ * tasking.c (build_signal_descriptor): Use IDENTIFIER_POINTER()
+ when printing a `tree'.
+
+Fri Oct 9 13:01:23 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * ch-tree.h (build_delay_case_end): Remove unused parameter.
+ (build_receive_case_end): Likewise.
+ (check_queue_size): Likewise.
+
+ * parse.c: Callers changed.
+
+ * satisfy.c: Likewise.
+
+ * tasking.c (build_receive_buffer_case_end): Remove unused
+ parameter `label_cnt'.
+ (build_receive_signal_case_end): Likewise.
+ (build_receive_case_end): Likewise.
+ (build_delay_case_end): Likewise.
+ (check_queue_size): Likewise for parameter `type'.
+ All callers changed.
+
+Thu Oct 8 05:57:41 1998 Jeffrey A Law (law@cygnus.com)
+
+ * typeck (type_for_mode): Only return TItype nodes when
+ HOST_BITS_PER_WIDE_INT is >= 64 bits.
+ (type_for_size): Similarly.
+ * decl.c (intTI_type_node, unsigned_intTI_type_node): Only declare
+ when HOST_BITS_PER_WIDE_INT is >= 64 bits.
+ (init_decl_processing): Only create TItype nodes when
+ HOST_BITS_PER_WIDE_INT is >= 64 bits.
+
Wed Oct 7 12:19:21 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
* Makefile.in (hash.h): Add -L KR-C -F ', 0, 0, 0' flags to gperf.
diff --git a/gcc/ch/Make-lang.in b/gcc/ch/Make-lang.in
index 2194741a4f0..e0e94626127 100644
--- a/gcc/ch/Make-lang.in
+++ b/gcc/ch/Make-lang.in
@@ -1,5 +1,5 @@
# Top level Makefile fragment for GNU CHILL.
-# Copyright (C) 1994 Free Software Foundation, Inc.
+# Copyright (C) 1994, 1998 Free Software Foundation, Inc.
#This file is part of GNU CC.
@@ -15,7 +15,8 @@
#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, 675 Mass Ave, Cambridge, MA 02139, USA.
+#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:
@@ -64,14 +65,14 @@ CHILL_FLAGS_TO_PASS = \
"GNUCHILL_VERSION=$(GNUCHILL_VERSION)"
#
# Define the names for selecting languages in LANGUAGES.
-CHILL: chill cc1chill chill-runtime
+CHILL: chill cc1chill$(exeext)
# handle startfile in chill script and build script to install
chill: $(srcdir)/ch/chill.in Makefile
thisdir=`pwd` ; \
sed -e "s:startfile=chillrt0:startfile=$${thisdir}/ch/runtime/chillrt0.o:" \
-e "s:libpath=chillrt:libpath=-L$${thisdir}/ch/runtime/:" \
- -e "s:whatgcc=gcc:whatgcc=\"$${thisdir}/xgcc -B$${thisdir}/\":" \
+ -e "s:whatgcc=gcc:whatgcc=\"$${thisdir}/xgcc$(exeext) -B$${thisdir}/\":" \
-e "s:gnuchill_version=unknown:gnuchill_version=$(GNUCHILL_VERSION):" \
-e "s:gnuchill_script_flags=:gnuchill_script_flags=\"$(GNUCHILL_SCRIPT_FLAGS)\":" $(srcdir)/ch/chill.in > chill ; \
chmod a+x chill ; \
@@ -87,24 +88,17 @@ chill: $(srcdir)/ch/chill.in Makefile
-e "s:gnuchill_script_flags=:gnuchill_script_flags=\"$(GNUCHILL_SCRIPT_FLAGS)\":" $(srcdir)/ch/chill.in > chill.install ; \
chmod a+x chill.install
-# Don't depend on cc1chill, because chill-cross is always built for cross,
-# and thus a cc1chill dependence would force cc1chill to always be built.
+# Don't depend on cc1chill$(exeext), because chill-cross is always built for cross,
+# and thus a cc1chill$(exeext) dependence would force cc1chill$(exeext) to always be built.
# Note that gcc-cross and g++-cross do not have cc1 or cc1plus dependencies.
chill-cross: $(srcdir)/ch/chill.in
touch $@
-cc1chill: $(P) $(CHILL_SRCS) $(LIBDEPS) stamp-objlist \
+cc1chill$(exeext): $(P) $(CHILL_SRCS) $(LIBDEPS) stamp-objlist \
insn-config.h insn-flags.h insn-attr.h insn-codes.h \
c-typeck.o c-aux-info.o c-common.o c-iterate.o
- cd ch; $(MAKE) $(FLAGS_TO_PASS) $(CHILL_FLAGS_TO_PASS) ../cc1chill
-
-chill-runtime: stmp-headers $(GCC_PASSES)
- case "$(LANGUAGES)" in \
- *CHILL*) if [ -f ch/runtime/Makefile -a -z "$(CROSS)" ] ; then \
- thisdir1=`pwd`; \
- cd ch/runtime; $(MAKE) $(FLAGS_TO_PASS) $(CHILL_FLAGS_TO_PASS) GCC_FOR_TARGET="$${thisdir1}/xgcc -B$${thisdir1}/" all ; \
- else true; fi ;; \
- esac
+ cd ch; $(MAKE) $(FLAGS_TO_PASS) $(CHILL_FLAGS_TO_PASS) ../cc1chill$(exeext)
+
#
# Build hooks:
@@ -113,8 +107,10 @@ CHILL.all.cross: chill-cross
CHILL.start.encap: chill
CHILL.rest.encap:
-CHILL.info: $(srcdir)/ch/chill.texi
- $(MAKEINFO) -I$(srcdir)/ch $(srcdir)/ch/chill.texi -o chill.info
+CHILL.info: ch/chill.info
+
+ch/chill.info: $(srcdir)/ch/chill.texi
+ $(MAKEINFO) -I$(srcdir)/ch $(srcdir)/ch/chill.texi -o ch/chill.info
chill.dvi: $(srcdir)/ch/chill.texi $(srcdir)/extend.texi $(srcdir)/invoke.texi $(srcdir)/md.texi $(srcdir)/rtl.texi $(srcdir)/tm.texi
cd ch ; \
@@ -127,21 +123,11 @@ chill.dvi: $(srcdir)/ch/chill.texi $(srcdir)/extend.texi $(srcdir)/invoke.texi $
# Install hooks:
# cc1chill is installed elsewhere as part of $(COMPILERS).
-CHILL.install-normal: install-libchill
-
-# Install the CHILL run time library.
-install-libchill: chill-runtime
- if [ -f ch/runtime/libchill.a ] ; then \
- $(INSTALL_DATA) ch/runtime/libchill.a $(libsubdir)/libchill.a; \
- if $(RANLIB_TEST) ; then \
- (cd $(libsubdir); $(RANLIB) libchill.a); else true; fi; \
- chmod a-x $(libsubdir)/libchill.a; \
- $(INSTALL_DATA) ch/runtime/chillrt0.o $(libsubdir)/chillrt0.o; \
- else true; fi
+CHILL.install-normal:
# Install the driver program
CHILL.install-common:
- -if [ -f cc1chill ] ; then \
+ -if [ -f cc1chill$(exeext) ] ; then \
if [ -f chill.install ] ; then \
if [ -f gcc-cross$(exeext) ]; then \
rm -f $(bindir)/$(CHILL_CROSS_NAME); \
@@ -155,10 +141,13 @@ CHILL.install-common:
fi ; \
fi
+# Don't delete $(infodir)/ch.info* unless there's actually new
+# docs to install (in case LANGUAGES didn't contain chill earlier).
CHILL.install-info:
- -for i in chill.info*; do \
- rm -f $(infodir)/$$i; \
- $(INSTALL_DATA) $$i $(infodir)/$$i; \
+ -for i in ch/chill.info*; do \
+ rm -f $(infodir)/chill.info*; \
+ realfile=`echo $$i | sed -e 's|.*/\([^/]*\)$$|\1|'`; \
+ $(INSTALL_DATA) $$i $(infodir)/$$realfile; \
done
CHILL.install-man:
diff --git a/gcc/ch/Makefile.in b/gcc/ch/Makefile.in
index 50b8a66395a..0d9fd777bb6 100644
--- a/gcc/ch/Makefile.in
+++ b/gcc/ch/Makefile.in
@@ -1,5 +1,5 @@
# Makefile for GNU CHILL compiler.
-# Copyright (C) 1987, 88, 90, 91, 92, 93, 1994 Free Software Foundation, Inc.
+# Copyright (C) 1987, 88, 90-94, 1998, 1999 Free Software Foundation, Inc.
#This file is part of GNU CC.
@@ -15,7 +15,8 @@
#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, 675 Mass Ave, Cambridge, MA 02139, USA.
+#the Free Software Foundation, 59 Temple Place - Suite 330,
+#Boston, MA 02111-1307, USA. */
# The makefile built from this file lives in the language subdirectory.
# It's purpose is to provide support for:
@@ -123,10 +124,10 @@ all: all.indirect
####cross overrides
####build overrides
####site overrides
-
+#
# Now figure out from those variables how to compile and link.
-all.indirect: Makefile ../chill ../cc1chill
+all.indirect: Makefile ../chill ../cc1chill$(exeext)
# IN_GCC tells obstack.h that we are using gcc's <stddef.h> file.
INTERNAL_CFLAGS = $(CROSS) -DIN_GCC
@@ -187,7 +188,7 @@ FLAGS_TO_PASS = \
# This tells GNU make version 3 not to export all the variables
# defined in this file into the environment.
.NOEXPORT:
-
+#
# Lists of files for various purposes.
# Language-specific object files for CHILL
@@ -202,7 +203,7 @@ CHILL_OBJS = parse.o actions.o except.o grant.o lang.o \
OBJS = `cat ../stamp-objlist`
OBJDEPS = ../stamp-objlist
-../cc1chill: $(P) $(CHILL_OBJS) $(OBJDEPS) $(LIBDEPS)
+../cc1chill$(exeext): $(P) $(CHILL_OBJS) $(OBJDEPS) $(LIBDEPS)
$(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ $(CHILL_OBJS) \
$(OBJS) $(C_OBJS) $(LIBS)
@@ -215,7 +216,7 @@ utils/printf : $(srcdir)/utils/printf.c
# This is the top-level trigger for a CHILL regression test.
# It also builds those tools needed for CHILL regression testing.
#
-check: ../cc1chill utils/printf
+check: ../cc1chill$(exeext) utils/printf
cd ..; $(MAKE) $(FLAGS_TO_PASS) xgcc gcov cpp cc1 ld
$(srcdir)/regression.sh -d -p
@@ -234,12 +235,12 @@ mostlyclean:
clean: mostlyclean
-
+#
Makefile: $(srcdir)/Makefile.in $(srcdir)/../configure
cd ..; $(SHELL) config.status
-native: config.status ../cc1chill ../chill
-
+native: config.status ../cc1chill$(exeext) ../chill
+#
# Compiling object files from source files.
# Note that dependencies on obstack.h are not written
@@ -291,8 +292,8 @@ lang.o : lang.c $(CONFIG_H) $(CHILL_TREE_H) $(srcdir)/../input.h lex.h \
$(srcdir)/../system.h $(srcdir)/../toplev.h
lex.o : lex.c $(CONFIG_H) $(CHILL_TREE_H) $(RTL_H) $(srcdir)/../flags.h \
$(srcdir)/../input.h $(srcdir)/parse.h $(srcdir)/../system.h \
- $(srcdir)/../toplev.h $(srcdir)/../../include/obstack.h lex.h
-lex.c: hash.h
+ $(srcdir)/../toplev.h $(srcdir)/../../include/obstack.h lex.h \
+ $(srcdir)/../dwarfout.h hash.h
loop.o : loop.c $(CONFIG_H) $(RTL_H) $(CHILL_TREE_H) lex.h \
$(srcdir)/../flags.h $(srcdir)/../input.h \
$(srcdir)/../../include/obstack.h $(srcdir)/../tree.h \
@@ -311,8 +312,8 @@ tasking.o : tasking.c $(CONFIG_H) $(CHILL_TREE_H) $(RTL_H) \
tree.o : tree.c $(CONFIG_H) $(CHILL_TREE_H) $(srcdir)/../system.h \
$(srcdir)/../toplev.h
typeck.o : typeck.c $(CONFIG_H) $(CHILL_TREE_H) ../insn-codes.h \
- $(srcdir)/../expr.h $(srcdir)/../flags.h lex.h $(srcdir)/../system.h \
- $(srcdir)/../toplev.h
+ $(srcdir)/../expr.h ../insn-codes.h $(srcdir)/../flags.h lex.h \
+ $(srcdir)/../system.h $(srcdir)/../toplev.h
ch-version.o : ch-version.c
ch-version.c : Makefile
echo 'char *gnuchill_version = "$(GNUCHILL_VERSION)";' > $@
diff --git a/gcc/ch/actions.c b/gcc/ch/actions.c
index 6d636b7052a..132dbd0b7e8 100644
--- a/gcc/ch/actions.c
+++ b/gcc/ch/actions.c
@@ -1,5 +1,5 @@
/* Implement actions for CHILL.
- Copyright (C) 1992, 93, 1994 Free Software Foundation, Inc.
+ Copyright (C) 1992, 93, 1994, 1998, 1999 Free Software Foundation, Inc.
Authors: Per Bothner, Bill Cox, Michael Tiemann, Michael North
This file is part of GNU CC.
@@ -16,7 +16,8 @@ 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
#include "config.h"
#include "system.h"
@@ -1226,7 +1227,7 @@ static tree
chill_handle_multi_case_label (selector, label)
tree selector, label;
{
- tree expr;
+ tree expr = NULL_TREE;
if (label == NULL_TREE || TREE_CODE (label) == ERROR_MARK)
return NULL_TREE;
diff --git a/gcc/ch/actions.h b/gcc/ch/actions.h
index d1eceb366a6..1059e5fd5f7 100644
--- a/gcc/ch/actions.h
+++ b/gcc/ch/actions.h
@@ -15,7 +15,8 @@ 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
/* used by compile_file */
diff --git a/gcc/ch/ch-tree.def b/gcc/ch/ch-tree.def
index af8edb0c00d..a47e014744c 100644
--- a/gcc/ch/ch-tree.def
+++ b/gcc/ch/ch-tree.def
@@ -17,7 +17,8 @@ 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
/*
diff --git a/gcc/ch/ch-tree.h b/gcc/ch/ch-tree.h
index c555677cee6..29161d23dd4 100644
--- a/gcc/ch/ch-tree.h
+++ b/gcc/ch/ch-tree.h
@@ -1,5 +1,5 @@
/* Definitions for CHILL parsing and type checking.
- Copyright (C) 1992, 93, 1994 Free Software Foundation, Inc.
+ Copyright (C) 1992, 93, 94, 98, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -15,7 +15,8 @@ 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
#ifndef _CH_TREE_H
#define _CH_TREE_H
@@ -391,10 +392,6 @@ extern int flag_cond_mismatch;
extern int flag_no_asm;
-/* Nonzero means ignore `#ident' directives. */
-
-extern int flag_no_ident;
-
/* Nonzero means warn about implicit declarations. */
extern int warn_implicit;
@@ -1038,10 +1035,10 @@ extern tree build_buffer_descriptor PROTO((tree, tree, tree));
extern tree build_buffer_type PROTO((tree, tree));
extern void build_delay_action PROTO((tree, tree));
extern tree build_delay_case_start PROTO((tree, tree));
-extern void build_delay_case_end PROTO((tree, tree));
+extern void build_delay_case_end PROTO((tree));
extern void build_delay_case_label PROTO((tree, int));
extern tree build_event_type PROTO((tree));
-extern void build_receive_case_end PROTO((tree, tree, tree));
+extern void build_receive_case_end PROTO((tree, tree));
extern int build_receive_case_if_generated PROTO((void));
extern tree build_receive_case_label PROTO((tree, tree));
extern tree build_receive_case_start PROTO((tree));
@@ -1062,7 +1059,7 @@ extern tree build_signal_descriptor PROTO((tree, tree));
extern tree build_signal_struct_type PROTO((tree, tree, tree));
extern tree build_tasking_struct PROTO((void));
extern tree chill_taskingcode_type_node;
-extern tree check_queue_size PROTO((tree, tree));
+extern tree check_queue_size PROTO((tree));
extern tree generate_tasking_code_variable PROTO((tree, tree *, int));
extern tree get_signal_type_name PROTO((tree));
extern tree get_struct_type_name PROTO((tree));
@@ -1147,12 +1144,9 @@ extern void remember_end_note PROTO((tree));
/* in toplev.c */
extern void announce_function PROTO((tree));
extern int floor_log2_wide PROTO((unsigned HOST_WIDE_INT));
-extern void pedwarn PROTO((char *, ...));
extern void rest_of_compilation PROTO((tree));
-extern void warning_with_decl PROTO((tree, char*, ...));
/* in varasm.c */
-extern void make_decl_rtl PROTO((tree, char *, int));
extern void make_function_rtl PROTO((tree));
/* in ???? */
diff --git a/gcc/ch/config-lang.in b/gcc/ch/config-lang.in
index 48be2d9488d..ac79f45aff6 100644
--- a/gcc/ch/config-lang.in
+++ b/gcc/ch/config-lang.in
@@ -15,7 +15,8 @@
#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, 675 Mass Ave, Cambridge, MA 02139, USA.
+#the Free Software Foundation, 59 Temple Place - Suite 330,
+#Boston, MA 02111-1307, USA. */
# Configure looks for the existence of this file to auto-config each language.
# We define several parameters used by configure:
diff --git a/gcc/ch/configure b/gcc/ch/configure
index 1179770cd48..8574a9fb763 100755
--- a/gcc/ch/configure
+++ b/gcc/ch/configure
@@ -16,7 +16,8 @@
#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, 675 Mass Ave, Cambridge, MA 02139, USA.
+#the Free Software Foundation, 59 Temple Place - Suite 330,
+#Boston, MA 02111-1307, USA. */
#
# Shell script to create proper links to machine-dependent files in
diff --git a/gcc/ch/convert.c b/gcc/ch/convert.c
index 93d14374be5..1f4345d4424 100644
--- a/gcc/ch/convert.c
+++ b/gcc/ch/convert.c
@@ -1,5 +1,5 @@
/* Language-level data type conversion for GNU CHILL.
- Copyright (C) 1992, 93, 1994 Free Software Foundation, Inc.
+ Copyright (C) 1992, 93, 1994, 1998 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -15,7 +15,8 @@ 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
/* This file contains the functions for converting CHILL expressions
diff --git a/gcc/ch/decl.c b/gcc/ch/decl.c
index 9c4735962f8..f69b88c1598 100644
--- a/gcc/ch/decl.c
+++ b/gcc/ch/decl.c
@@ -1,5 +1,5 @@
/* Process declarations and variables for GNU CHILL compiler.
- Copyright (C) 1992, 93, 1994 Free Software Foundation, Inc.
+ Copyright (C) 1992, 93, 1994, 1998, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -15,7 +15,8 @@
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, 675 Mass Ave, Cambridge, MA 02139, USA. */
+ the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
/* Process declarations and symbol lookup for CHILL front end.
@@ -353,13 +354,17 @@ tree intQI_type_node;
tree intHI_type_node;
tree intSI_type_node;
tree intDI_type_node;
+#if HOST_BITS_PER_WIDE_INT >= 64
tree intTI_type_node;
+#endif
tree unsigned_intQI_type_node;
tree unsigned_intHI_type_node;
tree unsigned_intSI_type_node;
tree unsigned_intDI_type_node;
+#if HOST_BITS_PER_WIDE_INT >= 64
tree unsigned_intTI_type_node;
+#endif
/* a VOID_TYPE node. */
@@ -591,10 +596,6 @@ int flag_allow_single_precision = 0;
int flag_signed_bitfields = 1;
int explicit_flag_signed_bitfields = 0;
-/* Nonzero means handle `#ident' directives. 0 means ignore them. */
-
-int flag_no_ident = 0;
-
/* Nonzero means warn about implicit declarations. */
int warn_implicit;
@@ -793,10 +794,6 @@ c_decode_option (argc, argv)
flag_no_builtin = 0;
else if (!strcmp (p, "-fno-builtin"))
flag_no_builtin = 1;
- else if (!strcmp (p, "-fno-ident"))
- flag_no_ident = 1;
- else if (!strcmp (p, "-fident"))
- flag_no_ident = 0;
else if (!strcmp (p, "-ansi"))
flag_no_asm = 1, flag_no_nonansi_builtin = 1, dollars_in_ident = 0;
else if (!strcmp (p, "-Wimplicit"))
@@ -2935,7 +2932,7 @@ poplevel (keep, reverse, functionbody)
tree subblocks;
tree block = 0;
tree decl;
- int block_previously_created;
+ int block_previously_created = 0;
if (current_scope == NULL)
return error_mark_node;
@@ -3531,12 +3528,16 @@ init_decl_processing ()
intHI_type_node = make_signed_type (GET_MODE_BITSIZE (HImode));
intSI_type_node = make_signed_type (GET_MODE_BITSIZE (SImode));
intDI_type_node = make_signed_type (GET_MODE_BITSIZE (DImode));
+#if HOST_BITS_PER_WIDE_INT >= 64
intTI_type_node = make_signed_type (GET_MODE_BITSIZE (TImode));
+#endif
unsigned_intQI_type_node = make_unsigned_type (GET_MODE_BITSIZE (QImode));
unsigned_intHI_type_node = make_unsigned_type (GET_MODE_BITSIZE (HImode));
unsigned_intSI_type_node = make_unsigned_type (GET_MODE_BITSIZE (SImode));
unsigned_intDI_type_node = make_unsigned_type (GET_MODE_BITSIZE (DImode));
+#if HOST_BITS_PER_WIDE_INT >= 64
unsigned_intTI_type_node = make_unsigned_type (GET_MODE_BITSIZE (TImode));
+#endif
float_type_node = make_node (REAL_TYPE);
TYPE_PRECISION (float_type_node) = FLOAT_TYPE_SIZE;
diff --git a/gcc/ch/except.c b/gcc/ch/except.c
index 0a911bd5e07..8b9c4c38763 100644
--- a/gcc/ch/except.c
+++ b/gcc/ch/except.c
@@ -1,6 +1,6 @@
/* Exception support for GNU CHILL.
WARNING: Only works for native (needs setjmp.h)! FIXME!
- Copyright (C) 1992, 93, 1994 Free Software Foundation, Inc.
+ Copyright (C) 1992, 93, 1994, 1998 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -16,7 +16,8 @@ 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
#include "config.h"
#include "system.h"
diff --git a/gcc/ch/expr.c b/gcc/ch/expr.c
index acc1bc7ec04..5e689a21c29 100644
--- a/gcc/ch/expr.c
+++ b/gcc/ch/expr.c
@@ -1,6 +1,6 @@
/* Convert language-specific tree expression to rtl instructions,
for GNU CHILL compiler.
- Copyright (C) 1992, 93, 1994 Free Software Foundation, Inc.
+ Copyright (C) 1992, 93, 1994, 1998, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -16,7 +16,8 @@ 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
#include "config.h"
@@ -316,7 +317,7 @@ chill_expand_expr (exp, target, tmode, modifier)
{
tree exp0 = TREE_OPERAND (exp, 0);
tree exp1 = TREE_OPERAND (exp, 1);
- rtx size0, size1;
+ rtx size0 = NULL_RTX, size1 = NULL_RTX;
rtx targetx;
if (TREE_CODE (exp1) == UNDEFINED_EXPR)
@@ -1372,7 +1373,8 @@ build_chill_card (powerset)
{ int size;
/* Do constant folding, if possible. */
- if (TREE_CODE (powerset) == CONSTRUCTOR & TREE_CONSTANT (powerset)
+ if (TREE_CODE (powerset) == CONSTRUCTOR
+ && TREE_CONSTANT (powerset)
&& (size = int_size_in_bytes (TREE_TYPE (powerset))) >= 0)
{
int bit_size = size * BITS_PER_UNIT;
@@ -3028,7 +3030,7 @@ fold_set_expr (code, op0, op1)
tree op0, op1;
{
tree temp;
- char *buffer0, *buffer1, *bufferr;
+ char *buffer0, *buffer1 = NULL, *bufferr;
int i, size0, size1, first_unused_bit;
if (! TREE_CONSTANT (op0) || TREE_CODE (op0) != CONSTRUCTOR)
diff --git a/gcc/ch/grant.c b/gcc/ch/grant.c
index ada788c57e7..2809003fdab 100644
--- a/gcc/ch/grant.c
+++ b/gcc/ch/grant.c
@@ -1,5 +1,5 @@
/* Implement grant-file output & seize-file input for CHILL.
- Copyright (C) 1992, 93, 94, 95, 1996 Free Software Foundation, Inc.
+ Copyright (C) 1992, 93, 94, 95, 1996, 1998 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -15,7 +15,8 @@ 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
#include "config.h"
#include "system.h"
diff --git a/gcc/ch/inout.c b/gcc/ch/inout.c
index c9af8160bd6..bac22b41250 100644
--- a/gcc/ch/inout.c
+++ b/gcc/ch/inout.c
@@ -1,5 +1,5 @@
/* Implement I/O-related actions for CHILL.
- Copyright (C) 1992, 93, 1994 Free Software Foundation, Inc.
+ Copyright (C) 1992, 93, 1994, 1998, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -15,7 +15,8 @@
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, 675 Mass Ave, Cambridge, MA 02139, USA. */
+ the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
#include "config.h"
#include "system.h"
@@ -2221,7 +2222,6 @@ void init_text_location (decl, type)
tree type;
{
tree indexmode = text_indexmode (type);
- tree textlength = text_length (type);
unsigned long accessflags = 0;
unsigned long textflags = IO_TEXTLOCATION;
tree lowindex = integer_zero_node;
@@ -3314,7 +3314,7 @@ process_io_list (exprlist, iolist_addr, iolist_length, iolist_rtx, do_read,
}
else if (TREE_CODE (item_type) == BOOLEAN_TYPE)
{
- tree to_assign;
+ tree to_assign = NULL_TREE;
if (do_read && readonly)
{
@@ -3834,7 +3834,7 @@ check_exprlist (code, exprlist, argnum, repetition)
int argnum;
unsigned long repetition;
{
- tree expr, type, result;
+ tree expr, type, result = NULL_TREE;
while (repetition--)
{
diff --git a/gcc/ch/lang-options.h b/gcc/ch/lang-options.h
index 984892bf6de..cf0c44e1014 100644
--- a/gcc/ch/lang-options.h
+++ b/gcc/ch/lang-options.h
@@ -15,7 +15,8 @@ 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
/* This is the contribution to the `lang_options' array in gcc.c for
CHILL. */
diff --git a/gcc/ch/lang-specs.h b/gcc/ch/lang-specs.h
index be02c117e5e..af7b3b3b3f4 100644
--- a/gcc/ch/lang-specs.h
+++ b/gcc/ch/lang-specs.h
@@ -1,5 +1,5 @@
/* Definitions for specs for GNU CHILL.
- Copyright (C) 1995 Free Software Foundation, Inc..
+ Copyright (C) 1995, 1998, 1999 Free Software Foundation, Inc..
This file is part of GNU CC.
@@ -15,15 +15,16 @@ 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
/* This is the contribution to the `default_compilers' array in gcc.c for
CHILL. */
- {".ch", "@chill" },
- {".chi", "@chill" },
+ {".ch", {"@chill"}},
+ {".chi", {"@chill"}},
{"@chill",
- "cpp -lang-chill %{nostdinc*} %{C} %{v} %{A*} %{I*} %{P} %I\
+ {"cpp -lang-chill %{nostdinc*} %{C} %{v} %{A*} %{I*} %{P} %I\
%{C:%{!E:%eGNU CHILL does not support -C without using -E}}\
-undef -D__GNUCHILL__=%v1 -D__GNUC_MINOR__=%v2\
%c %{Os:-D__OPTIMIZE_SIZE__} %{O*:-D__OPTIMIZE__} %{traditional} %{ftraditional:-traditional}\
@@ -34,9 +35,9 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
%{!Q:-quiet} -dumpbase %b.ch %{d*} %{m*} %{a}\
%{g*} %{O*} %{W*} %{w} %{pedantic*} %{itu} \
%{v:-version} %{pg:-p} %{p} %{f*} %{I*} \
- %{aux-info*} %X \
+ %{aux-info*} %{Qn:-fno-ident} %X \
%{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\
%{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%g.s}} |\n\
%{!S:as %a %Y \
%{c:%W{o*}%{!o*:-o %w%b%O}}%{!c:-o %d%w%u%O}\
- %{!pipe:%g.s} %A\n }}"},
+ %{!pipe:%g.s} %A\n }}"}},
diff --git a/gcc/ch/lang.c b/gcc/ch/lang.c
index 86d649009c4..794c5921269 100644
--- a/gcc/ch/lang.c
+++ b/gcc/ch/lang.c
@@ -1,5 +1,5 @@
/* Language-specific hook definitions for CHILL front end.
- Copyright (C) 1992, 93, 1994 Free Software Foundation, Inc.
+ Copyright (C) 1992, 93, 1994, 1998 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -15,7 +15,8 @@ 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
#include "config.h"
diff --git a/gcc/ch/lex.c b/gcc/ch/lex.c
index 38c8fa46276..30096a77c0b 100644
--- a/gcc/ch/lex.c
+++ b/gcc/ch/lex.c
@@ -15,7 +15,8 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
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, 675 Mass Ave, Cambridge, MA 02139, USA. */
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
#include "config.h"
#include "system.h"
@@ -32,6 +33,10 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "obstack.h"
#include "toplev.h"
+#ifdef DWARF_DEBUGGING_INFO
+#include "dwarfout.h"
+#endif
+
#ifdef MULTIBYTE_CHARS
#include <locale.h>
#endif
diff --git a/gcc/ch/lex.h b/gcc/ch/lex.h
index 61c46b79a01..df533425a1c 100644
--- a/gcc/ch/lex.h
+++ b/gcc/ch/lex.h
@@ -15,7 +15,8 @@ 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
diff --git a/gcc/ch/loop.c b/gcc/ch/loop.c
index 88efaac5379..0716ba2cd33 100644
--- a/gcc/ch/loop.c
+++ b/gcc/ch/loop.c
@@ -1,5 +1,5 @@
/* Implement looping actions for CHILL.
- Copyright (C) 1992, 93, 1994 Free Software Foundation, Inc.
+ Copyright (C) 1992, 93, 1994, 1998 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -15,7 +15,8 @@ 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
#include "config.h"
#include "system.h"
diff --git a/gcc/ch/nloop.c b/gcc/ch/nloop.c
index ddd4aad7e42..f011703cd33 100644
--- a/gcc/ch/nloop.c
+++ b/gcc/ch/nloop.c
@@ -15,7 +15,8 @@ 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
#include <stdio.h>
#include <limits.h>
diff --git a/gcc/ch/parse.c b/gcc/ch/parse.c
index fea4581044b..96026a105ba 100644
--- a/gcc/ch/parse.c
+++ b/gcc/ch/parse.c
@@ -1,5 +1,5 @@
/* Parser for GNU CHILL (CCITT High-Level Language) -*- C -*-
- Copyright (C) 1992, 1993 Free Software Foundation, Inc.
+ Copyright (C) 1992, 1993, 1998, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -15,7 +15,8 @@ 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
/*
* This is a two-pass parser. In pass 1, we collect declarations,
@@ -73,6 +74,11 @@ extern struct rtx_def* gen_label_rtx PROTO((void));
extern void emit_jump PROTO((struct rtx_def *));
extern struct rtx_def* emit_label PROTO((struct rtx_def *));
+/* This is a hell of a lot easier than getting expr.h included in
+ by parse.c. */
+extern struct rtx_def *expand_expr PROTO((tree, struct rtx_def *,
+ enum machine_mode, int));
+
static int parse_action PROTO((void));
extern int lineno;
@@ -544,8 +550,9 @@ static void
parse_spec_module (label)
tree label;
{
- tree module_name = push_module (set_module_name (label), 1);
int save_ignoring = ignoring;
+
+ push_module (set_module_name (label), 1);
ignoring = pass == 2;
FORWARD_TOKEN(); /* SKIP SPEC */
expect (MODULE, "expected 'MODULE' here");
@@ -1669,7 +1676,7 @@ static void
parse_multi_dimension_case_action (selector)
tree selector;
{
- struct rtx_def *begin_test_label = 0, *end_case_label, *new_label;
+ struct rtx_def *begin_test_label = 0, *end_case_label = 0, *new_label;
tree action_labels = NULL_TREE;
tree tests = NULL_TREE;
int save_lineno = lineno;
@@ -2205,7 +2212,7 @@ parse_delay_case_action (label)
}
expect (ESAC, "missing 'ESAC' in DELAY CASE'");
if (! ignoring)
- build_delay_case_end (label_cnt, combined_event_list);
+ build_delay_case_end (combined_event_list);
possibly_define_exit_label (label);
poplevel (0, 0, 0);
}
@@ -2436,8 +2443,7 @@ parse_receive_case_action (label)
expect (ESAC, "missing 'ESAC' matching 'RECEIVE CASE'");
if (! ignoring)
{
- build_receive_case_end (instance_location, nreverse (alt_list),
- have_else_actions);
+ build_receive_case_end (nreverse (alt_list), have_else_actions);
}
possibly_define_exit_label (label);
poplevel (0, 0, 0);
@@ -3145,7 +3151,7 @@ parse_operand6 ()
{
if (check_token (RECEIVE))
{
- tree location = parse_primval ();
+ tree location ATTRIBUTE_UNUSED = parse_primval ();
sorry ("RECEIVE expression");
return integer_one_node;
}
diff --git a/gcc/ch/satisfy.c b/gcc/ch/satisfy.c
index 2b8607875b4..61862d16100 100644
--- a/gcc/ch/satisfy.c
+++ b/gcc/ch/satisfy.c
@@ -1,5 +1,5 @@
/* Name-satisfaction for GNU Chill compiler.
- Copyright (C) 1993 Free Software Foundation, Inc.
+ Copyright (C) 1993, 1998 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -15,7 +15,8 @@ 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
#include "config.h"
#include "system.h"
@@ -560,7 +561,7 @@ satisfy (exp, chain)
{
if (CH_IS_BUFFER_MODE (exp) || CH_IS_EVENT_MODE (exp))
DECL_INITIAL (decl)
- = check_queue_size (exp, DECL_INITIAL (decl));
+ = check_queue_size (DECL_INITIAL (decl));
else if (CH_IS_TEXT_MODE (exp) &&
DECL_NAME (decl) == get_identifier ("__textlength"))
DECL_INITIAL (decl)
diff --git a/gcc/ch/tasking.c b/gcc/ch/tasking.c
index c0c1c9ccbd4..8c3fabeffbc 100644
--- a/gcc/ch/tasking.c
+++ b/gcc/ch/tasking.c
@@ -1,5 +1,5 @@
/* Implement tasking-related actions for CHILL.
- Copyright (C) 1992, 93, 1994 Free Software Foundation, Inc.
+ Copyright (C) 1992, 93, 1994, 1998, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -15,7 +15,8 @@ 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
#include "config.h"
#include "system.h"
@@ -514,7 +515,7 @@ build_start_process (process_name, copynum,
exprlist, optset)
tree process_name, copynum, exprlist, optset;
{
- tree process_decl, struct_type_node;
+ tree process_decl = NULL_TREE, struct_type_node = NULL_TREE;
tree result;
tree valtail, typetail;
tree tuple = NULL_TREE, actuallist = NULL_TREE;
@@ -1272,7 +1273,7 @@ build_signal_descriptor (sigdef, exprlist)
|| ! CH_DECL_SIGNAL (sigdef))
{
error ("SEND requires a SIGNAL; %s is not a SIGNAL name",
- signame);
+ IDENTIFIER_POINTER (signame));
return error_mark_node;
}
if (CH_TYPE_NONVALUE_P (TREE_TYPE (sigdef)))
@@ -2085,8 +2086,8 @@ build_receive_case_label (signame, loclist)
* BUFFER location and TREE_PURPOSE defines the defining occurence.
*/
static void
-build_receive_buffer_case_end (label_cnt, buf_list, else_clause)
- tree label_cnt, buf_list, else_clause;
+build_receive_buffer_case_end (buf_list, else_clause)
+ tree buf_list, else_clause;
{
struct rc_state_type *rc_state = current_rc_state;
tree alist;
@@ -2185,8 +2186,8 @@ build_receive_buffer_case_end (label_cnt, buf_list, else_clause)
* case-label counter passed from build_receive_case_start.
*/
static void
-build_receive_signal_case_end (label_cnt, sig_list, else_clause)
- tree label_cnt, sig_list, else_clause;
+build_receive_signal_case_end (sig_list, else_clause)
+ tree sig_list, else_clause;
{
struct rc_state_type *rc_state = current_rc_state;
tree alist, temp1;
@@ -2285,8 +2286,8 @@ build_receive_signal_case_end (label_cnt, sig_list, else_clause)
/* General function for the end of a RECEIVE CASE action */
void
-build_receive_case_end (label_cnt, alist, else_clause)
- tree label_cnt, alist, else_clause;
+build_receive_case_end (alist, else_clause)
+ tree alist, else_clause;
{
rtx rcdone = gen_label_rtx ();
struct rc_state_type *rc_state = current_rc_state;
@@ -2322,9 +2323,9 @@ build_receive_case_end (label_cnt, alist, else_clause)
/* now call the actual end function */
if (rc_state->bufseen)
- build_receive_buffer_case_end (label_cnt, alist, else_clause);
+ build_receive_buffer_case_end (alist, else_clause);
else
- build_receive_signal_case_end (label_cnt, alist, else_clause);
+ build_receive_signal_case_end (alist, else_clause);
/* now jump to the beginning of RECEIVE CASE processing */
gen_rcdoit: ;
@@ -2594,8 +2595,8 @@ build_delay_case_label (eventlist, if_or_elseif)
* passed from build_delay_case_start.
*/
void
-build_delay_case_end (label_cnt, event_list)
- tree label_cnt, event_list;
+build_delay_case_end (event_list)
+ tree event_list;
{
struct dl_state_type *dl_state = current_dl_state;
rtx dldone = gen_label_rtx ();
@@ -3209,8 +3210,8 @@ invalidate_buffer_element_mode (bufmode)
perform various error checks. Return a new queue size. */
tree
-check_queue_size (type, qsize)
- tree type, qsize;
+check_queue_size (qsize)
+ tree qsize;
{
if (qsize == NULL_TREE || TREE_CODE (qsize) == ERROR_MARK)
return qsize;
diff --git a/gcc/ch/tasking.h b/gcc/ch/tasking.h
index 31e0581bc0d..fde719789cb 100644
--- a/gcc/ch/tasking.h
+++ b/gcc/ch/tasking.h
@@ -15,7 +15,8 @@ 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
#ifndef _CH_TASKING_H
#define _CH_TASKING_H
diff --git a/gcc/ch/timing.c b/gcc/ch/timing.c
index aa0c7a6e079..f60cc7aca97 100644
--- a/gcc/ch/timing.c
+++ b/gcc/ch/timing.c
@@ -1,5 +1,5 @@
/* Implement timing-related actions for CHILL.
- Copyright (C) 1992, 93, 1994 Free Software Foundation, Inc.
+ Copyright (C) 1992, 93, 1994, 1998 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -15,7 +15,8 @@ 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
#include "config.h"
#include "system.h"
diff --git a/gcc/ch/tree.c b/gcc/ch/tree.c
index 5b698874319..41ccb0e88d8 100644
--- a/gcc/ch/tree.c
+++ b/gcc/ch/tree.c
@@ -1,5 +1,5 @@
/* Language-dependent node constructors for parse phase of GNU compiler.
- Copyright (C) 1992, 93, 1994 Free Software Foundation, Inc.
+ Copyright (C) 1992, 93, 1994, 1998 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -15,7 +15,8 @@ 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
#include "config.h"
#include "system.h"
diff --git a/gcc/ch/typeck.c b/gcc/ch/typeck.c
index a4795dfddf4..8985476a1e8 100644
--- a/gcc/ch/typeck.c
+++ b/gcc/ch/typeck.c
@@ -1,5 +1,5 @@
/* Build expressions with type checking for CHILL compiler.
- Copyright (C) 1992, 93, 1994 Free Software Foundation, Inc.
+ Copyright (C) 1992, 93, 1994, 1998, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -15,7 +15,8 @@ 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
/* This file is part of the CHILL front end.
@@ -41,13 +42,17 @@ extern tree intQI_type_node;
extern tree intHI_type_node;
extern tree intSI_type_node;
extern tree intDI_type_node;
+#if HOST_BITS_PER_WIDE_INT >= 64
extern tree intTI_type_node;
+#endif
extern tree unsigned_intQI_type_node;
extern tree unsigned_intHI_type_node;
extern tree unsigned_intSI_type_node;
extern tree unsigned_intDI_type_node;
+#if HOST_BITS_PER_WIDE_INT >= 64
extern tree unsigned_intTI_type_node;
+#endif
/* forward declarations */
static int chill_l_equivalent PROTO((tree, tree, struct mode_chain*));
@@ -1207,7 +1212,7 @@ build_chill_cast (type, expr)
build1 (NOP_EXPR, build_pointer_type (type),
build1 (ADDR_EXPR, build_pointer_type (expr_type),
expr)));
- TREE_READONLY (expr) == TYPE_READONLY (type);
+ TREE_READONLY (expr) = TYPE_READONLY (type);
return expr;
}
@@ -3045,7 +3050,7 @@ apply_chill_field_layout (decl, next_struct_offset)
int* next_struct_offset;
{
tree layout, type, temp, what;
- int word, wordsize, start_bit, offset, length, natural_length;
+ int word = 0, wordsize, start_bit, offset, length, natural_length;
int pos_error = 0;
int is_discrete;
@@ -3838,8 +3843,10 @@ type_for_size (bits, unsignedp)
if (bits <= TYPE_PRECISION (intDI_type_node))
return unsignedp ? unsigned_intDI_type_node : intDI_type_node;
+#if HOST_BITS_PER_WIDE_INT >= 64
if (bits <= TYPE_PRECISION (intTI_type_node))
return unsignedp ? unsigned_intTI_type_node : intTI_type_node;
+#endif
return 0;
}
@@ -3853,49 +3860,51 @@ type_for_mode (mode, unsignedp)
enum machine_mode mode;
int unsignedp;
{
- if (mode == TYPE_MODE (integer_type_node))
+ if ((int)mode == (int)TYPE_MODE (integer_type_node))
return unsignedp ? unsigned_type_node : integer_type_node;
- if (mode == TYPE_MODE (signed_char_type_node))
+ if ((int)mode == (int)TYPE_MODE (signed_char_type_node))
return unsignedp ? unsigned_char_type_node : signed_char_type_node;
- if (mode == TYPE_MODE (short_integer_type_node))
+ if ((int)mode == (int)TYPE_MODE (short_integer_type_node))
return unsignedp ? short_unsigned_type_node : short_integer_type_node;
- if (mode == TYPE_MODE (long_integer_type_node))
+ if ((int)mode == (int)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))
+ if ((int)mode == (int)TYPE_MODE (long_long_integer_type_node))
return unsignedp ? long_long_unsigned_type_node : long_long_integer_type_node;
- if (mode == TYPE_MODE (intQI_type_node))
+ if ((int)mode == (int)TYPE_MODE (intQI_type_node))
return unsignedp ? unsigned_intQI_type_node : intQI_type_node;
- if (mode == TYPE_MODE (intHI_type_node))
+ if ((int)mode == (int)TYPE_MODE (intHI_type_node))
return unsignedp ? unsigned_intHI_type_node : intHI_type_node;
- if (mode == TYPE_MODE (intSI_type_node))
+ if ((int)mode == (int)TYPE_MODE (intSI_type_node))
return unsignedp ? unsigned_intSI_type_node : intSI_type_node;
- if (mode == TYPE_MODE (intDI_type_node))
+ if ((int)mode == (int)TYPE_MODE (intDI_type_node))
return unsignedp ? unsigned_intDI_type_node : intDI_type_node;
- if (mode == TYPE_MODE (intTI_type_node))
+#if HOST_BITS_PER_WIDE_INT >= 64
+ if ((int)mode == (int)TYPE_MODE (intTI_type_node))
return unsignedp ? unsigned_intTI_type_node : intTI_type_node;
+#endif
- if (mode == TYPE_MODE (float_type_node))
+ if ((int)mode == (int)TYPE_MODE (float_type_node))
return float_type_node;
- if (mode == TYPE_MODE (double_type_node))
+ if ((int)mode == (int)TYPE_MODE (double_type_node))
return double_type_node;
- if (mode == TYPE_MODE (long_double_type_node))
+ if ((int)mode == (int)TYPE_MODE (long_double_type_node))
return long_double_type_node;
- if (mode == TYPE_MODE (build_pointer_type (char_type_node)))
+ if ((int)mode == (int)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)))
+ if ((int)mode == (int)TYPE_MODE (build_pointer_type (integer_type_node)))
return build_pointer_type (integer_type_node);
return 0;
diff --git a/gcc/ch/xtypeck.c b/gcc/ch/xtypeck.c
index 2946b231029..efe81ff2184 100644
--- a/gcc/ch/xtypeck.c
+++ b/gcc/ch/xtypeck.c
@@ -1,3 +1,22 @@
+/* Copyright (C) 1992, 93, 1994, 1998 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. */
+
#if 0
tree
diff --git a/gcc/collect2.c b/gcc/collect2.c
index bfa91550874..2f31d94138b 100644
--- a/gcc/collect2.c
+++ b/gcc/collect2.c
@@ -1,6 +1,6 @@
/* Collect static initialization info into data structures that can be
traversed by C++ initialization and finalization routines.
- Copyright (C) 1992, 93-97, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1992, 93-98, 1999 Free Software Foundation, Inc.
Contributed by Chris Smith (csmith@convex.com).
Heavily modified by Michael Meissner (meissner@cygnus.com),
Per Bothner (bothner@cygnus.com), and John Gilmore (gnu@cygnus.com).
@@ -28,38 +28,31 @@ Boston, MA 02111-1307, USA. */
#include "config.h"
#include "system.h"
#include <signal.h>
-#include <sys/stat.h>
+
+#ifdef vfork /* Autoconf may define this to fork for us. */
+# define VFORK_STRING "fork"
+#else
+# define VFORK_STRING "vfork"
+#endif
+#ifdef HAVE_VFORK_H
+#include <vfork.h>
+#endif
+#ifdef VMS
+#define vfork() (decc$$alloc_vfork_blocks() >= 0 ? \
+ lib$get_current_invo_context(decc$$get_vfork_jmpbuf()) : -1)
+#endif /* VMS */
#define COLLECT
+#include "collect2.h"
#include "demangle.h"
#include "obstack.h"
-#include "gansidecl.h"
-#ifdef __CYGWIN32__
-#include <process.h>
-#endif
+#include "intl.h"
/* Obstack allocation and deallocation routines. */
#define obstack_chunk_alloc xmalloc
#define obstack_chunk_free free
-#ifdef USG
-#define vfork fork
-#endif
-
-#ifndef WIFSIGNALED
-#define WIFSIGNALED(S) (((S) & 0xff) != 0 && ((S) & 0xff) != 0x7f)
-#endif
-#ifndef WTERMSIG
-#define WTERMSIG(S) ((S) & 0x7f)
-#endif
-#ifndef WIFEXITED
-#define WIFEXITED(S) (((S) & 0xff) == 0)
-#endif
-#ifndef WEXITSTATUS
-#define WEXITSTATUS(S) (((S) & 0xff00) >> 8)
-#endif
-
extern char *make_temp_file PROTO ((char *));
/* On certain systems, we have code that works by scanning the object file
@@ -151,6 +144,9 @@ extern char *make_temp_file PROTO ((char *));
#define SYMBOL__MAIN __main
#endif
+/* This must match tree.h. */
+#define DEFAULT_INIT_PRIORITY 65535
+
#if defined (LDD_SUFFIX) || SUNOS4_SHARED_LIBRARIES
#define SCAN_LIBRARIES
#endif
@@ -193,6 +189,7 @@ static int rflag; /* true if -r */
static int strip_flag; /* true if -s */
#ifdef COLLECT_EXPORT_LIST
static int export_flag; /* true if -bE */
+static int aix64_flag; /* true if -b64 */
#endif
int debug; /* true if -debug */
@@ -228,6 +225,9 @@ struct obstack temporary_obstack;
struct obstack permanent_obstack;
char * temporary_firstobj;
+/* Holds the return value of pexecute. */
+int pexecute_pid;
+
/* Defined in the automatically-generated underscore.c. */
extern int prepends_underscore;
@@ -263,6 +263,11 @@ static struct path_prefix *libpaths[3] = {&cmdline_lib_dirs,
static char *libexts[3] = {"a", "so", NULL}; /* possible library extentions */
#endif
+void error PVPROTO((const char *, ...)) ATTRIBUTE_PRINTF_1;
+void fatal PVPROTO((const char *, ...))
+ ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN;
+void fatal_perror PVPROTO((const char *, ...))
+ ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN;
static char *my_strerror PROTO((int));
static const char *my_strsignal PROTO((int));
static void handler PROTO((int));
@@ -298,10 +303,6 @@ static char *resolve_lib_name PROTO((char *));
static int use_import_list PROTO((char *));
static int ignore_library PROTO((char *));
#endif
-
-char *xcalloc ();
-char *xmalloc ();
-
#ifdef NO_DUP2
int
@@ -335,15 +336,13 @@ my_strerror (e)
#else
- static char buffer[30];
if (!e)
return "";
if (e > 0 && e < sys_nerr)
return sys_errlist[e];
- sprintf (buffer, "Unknown error %d", e);
- return buffer;
+ return "errno = ?";
#endif
}
@@ -403,41 +402,94 @@ collect_exit (status)
}
+/* Notify user of a non-error. */
+void
+notice VPROTO((char *msgid, ...))
+{
+#ifndef ANSI_PROTOTYPES
+ char *msgid;
+#endif
+ va_list ap;
+
+ VA_START (ap, msgid);
+
+#ifndef ANSI_PROTOTYPES
+ msgid = va_arg (ap, char *);
+#endif
+
+ vfprintf (stderr, _(msgid), ap);
+ va_end (ap);
+}
+
/* Die when sys call fails. */
void
-fatal_perror (string, arg1, arg2, arg3)
- char *string, *arg1, *arg2, *arg3;
+fatal_perror VPROTO((const char * msgid, ...))
{
+#ifndef ANSI_PROTOTYPES
+ const char *msgid;
+#endif
int e = errno;
+ va_list ap;
+
+ VA_START (ap, msgid);
+
+#ifndef ANSI_PROTOTYPES
+ msgid = va_arg (ap, const char *);
+#endif
fprintf (stderr, "collect2: ");
- fprintf (stderr, string, arg1, arg2, arg3);
+ vfprintf (stderr, _(msgid), ap);
fprintf (stderr, ": %s\n", my_strerror (e));
+ va_end (ap);
+
collect_exit (FATAL_EXIT_CODE);
}
/* Just die. */
void
-fatal (string, arg1, arg2, arg3)
- char *string, *arg1, *arg2, *arg3;
+fatal VPROTO((const char * msgid, ...))
{
+#ifndef ANSI_PROTOTYPES
+ const char *msgid;
+#endif
+ va_list ap;
+
+ VA_START (ap, msgid);
+
+#ifndef ANSI_PROTOTYPES
+ msgid = va_arg (ap, const char *);
+#endif
+
fprintf (stderr, "collect2: ");
- fprintf (stderr, string, arg1, arg2, arg3);
+ vfprintf (stderr, _(msgid), ap);
fprintf (stderr, "\n");
+ va_end (ap);
+
collect_exit (FATAL_EXIT_CODE);
}
/* Write error message. */
void
-error (string, arg1, arg2, arg3, arg4)
- char *string, *arg1, *arg2, *arg3, *arg4;
+error VPROTO((const char * msgid, ...))
{
+#ifndef ANSI_PROTOTYPES
+ const char * msgid;
+#endif
+ va_list ap;
+
+ VA_START (ap, msgid);
+
+#ifndef ANSI_PROTOTYPES
+ msgid = va_arg (ap, const char *);
+#endif
+
fprintf (stderr, "collect2: ");
- fprintf (stderr, string, arg1, arg2, arg3, arg4);
+ vfprintf (stderr, _(msgid), ap);
fprintf (stderr, "\n");
+ va_end(ap);
}
/* In case obstack is linked in, and abort is defined to fancy_abort,
@@ -448,7 +500,6 @@ fancy_abort ()
{
fatal ("internal error");
}
-
static void
handler (signo)
@@ -476,39 +527,39 @@ handler (signo)
}
-char *
+PTR
xcalloc (size1, size2)
- int size1, size2;
+ size_t size1, size2;
{
- char *ptr = (char *) calloc (size1, size2);
- if (ptr)
- return ptr;
-
- fatal ("out of memory");
- return (char *) 0;
+ PTR ptr = (PTR) calloc (size1, size2);
+ if (!ptr)
+ fatal ("out of memory");
+ return ptr;
}
-char *
+PTR
xmalloc (size)
- unsigned size;
+ size_t size;
{
- char *ptr = (char *) malloc (size);
- if (ptr)
- return ptr;
-
- fatal ("out of memory");
- return (char *) 0;
+ PTR ptr = (PTR) malloc (size);
+ if (!ptr)
+ fatal ("out of memory");
+ return ptr;
}
-char *
-xrealloc (ptr, size)
- char *ptr;
- unsigned size;
+PTR
+xrealloc (old, size)
+ PTR old;
+ size_t size;
{
- register char *value = (char *) realloc (ptr, size);
- if (value == 0)
+ register PTR ptr;
+ if (old)
+ ptr = (PTR) realloc (old, size);
+ else
+ ptr = (PTR) malloc (size);
+ if (ptr == 0)
fatal ("virtual memory exhausted");
- return value;
+ return ptr;
}
int
@@ -521,13 +572,12 @@ file_exists (name)
/* Make a copy of a string INPUT with size SIZE. */
char *
-savestring (input, size)
- char *input;
- int size;
+xstrdup (input)
+ const char *input;
{
- char *output = (char *) xmalloc (size + 1);
- bcopy (input, output, size);
- output[size] = 0;
+ register size_t len = strlen (input) + 1;
+ register char *output = xmalloc (len);
+ memcpy (output, input, len);
return output;
}
@@ -844,7 +894,7 @@ add_prefix (pprefix, prefix)
pprefix->max_len = len;
pl = (struct prefix_list *) xmalloc (sizeof (struct prefix_list));
- pl->prefix = savestring (prefix, len);
+ pl->prefix = xstrdup (prefix);
if (*prev)
pl->next = *prev;
@@ -943,15 +993,33 @@ main (argc, argv)
char *p;
char **c_argv;
char **c_ptr;
- char **ld1_argv = (char **) xcalloc (sizeof (char *), argc+3);
- char **ld1 = ld1_argv;
- char **ld2_argv = (char **) xcalloc (sizeof (char *), argc+6);
- char **ld2 = ld2_argv;
- char **object_lst = (char **) xcalloc (sizeof (char *), argc);
- char **object = object_lst;
+ char **ld1_argv;
+ char **ld1;
+ char **ld2_argv;
+ char **ld2;
+ char **object_lst;
+ char **object;
int first_file;
int num_c_args = argc+9;
+#if defined (COLLECT2_HOST_INITIALZATION)
+ /* Perform system dependant initialization, if neccessary. */
+ COLLECT2_HOST_INITIALZATION;
+#endif
+
+#ifdef HAVE_LC_MESSAGES
+ setlocale (LC_MESSAGES, "");
+#endif
+ (void) bindtextdomain (PACKAGE, localedir);
+ (void) textdomain (PACKAGE);
+
+ /* Do not invoke xcalloc before this point, since locale needs to be
+ set first, in case a diagnostic is issued. */
+
+ ld1 = ld1_argv = (char **) xcalloc (sizeof (char *), argc+3);
+ ld2 = ld2_argv = (char **) xcalloc (sizeof (char *), argc+6);
+ object = object_lst = (char **) xcalloc (sizeof (char *), argc);
+
#ifdef DEBUG
debug = 1;
#endif
@@ -1189,6 +1257,8 @@ main (argc, argv)
char *q = extract_string (&p);
if (*q == '-' && (q[1] == 'm' || q[1] == 'f'))
*c_ptr++ = obstack_copy0 (&permanent_obstack, q, strlen (q));
+ if (strcmp (q, "-EL") == 0 || strcmp (q, "-EB") == 0)
+ *c_ptr++ = obstack_copy0 (&permanent_obstack, q, strlen (q));
if (strncmp (q, "-shared", sizeof ("-shared") - 1) == 0)
shared_obj = 1;
}
@@ -1220,6 +1290,8 @@ main (argc, argv)
case 'b':
if (arg[2] == 'E' || strncmp (&arg[2], "export", 6) == 0)
export_flag = 1;
+ else if (arg[2] == '6' && arg[3] == '4')
+ aix64_flag = 1;
break;
#endif
@@ -1365,16 +1437,16 @@ main (argc, argv)
*ld2++ = buf2;
exportf = fopen (export_file, "w");
if (exportf == (FILE *) 0)
- fatal_perror ("%s", export_file);
+ fatal_perror ("fopen %s", export_file);
write_export_file (exportf);
if (fclose (exportf))
- fatal_perror ("closing %s", export_file);
+ fatal_perror ("fclose %s", export_file);
importf = fopen (import_file, "w");
if (importf == (FILE *) 0)
fatal_perror ("%s", import_file);
write_import_file (importf);
if (fclose (importf))
- fatal_perror ("closing %s", import_file);
+ fatal_perror ("fclose %s", import_file);
}
#endif
@@ -1383,7 +1455,7 @@ main (argc, argv)
if (vflag)
{
- fprintf (stderr, "collect2 version %s", version_string);
+ notice ("collect2 version %s", version_string);
#ifdef TARGET_VERSION
TARGET_VERSION;
#endif
@@ -1472,8 +1544,8 @@ main (argc, argv)
if (debug)
{
- fprintf (stderr, "%d constructor(s) found\n", constructors.number);
- fprintf (stderr, "%d destructor(s) found\n", destructors.number);
+ notice ("%d constructor(s) found\n", constructors.number);
+ notice ("%d destructor(s) found\n", destructors.number);
}
if (constructors.number == 0 && destructors.number == 0
@@ -1516,12 +1588,12 @@ main (argc, argv)
maybe_unlink(output_file);
outf = fopen (c_file, "w");
if (outf == (FILE *) 0)
- fatal_perror ("%s", c_file);
+ fatal_perror ("fopen %s", c_file);
write_c_file (outf, c_file);
if (fclose (outf))
- fatal_perror ("closing %s", c_file);
+ fatal_perror ("fclose %s", c_file);
/* Tell the linker that we have initializer and finalizer functions. */
#ifdef LD_INIT_SWITCH
@@ -1541,10 +1613,10 @@ main (argc, argv)
add_to_list (&exports, "_GLOBAL__DD");
exportf = fopen (export_file, "w");
if (exportf == (FILE *) 0)
- fatal_perror ("%s", export_file);
+ fatal_perror ("fopen %s", export_file);
write_export_file (exportf);
if (fclose (exportf))
- fatal_perror ("closing %s", export_file);
+ fatal_perror ("fclose %s", export_file);
}
#endif
@@ -1597,18 +1669,18 @@ collect_wait (prog)
{
int status;
- wait (&status);
+ pwait (pexecute_pid, &status, 0);
if (status)
{
if (WIFSIGNALED (status))
{
int sig = WTERMSIG (status);
- error ("%s terminated with signal %d [%s]%s",
+ error ((status & 0200
+ ? "%s terminated with signal %d [%s]"
+ : "%s terminated with signal %d [%s], core dumped"),
prog,
sig,
- my_strsignal(sig),
- (status & 0200) ? ", core dumped" : "");
-
+ my_strsignal(sig));
collect_exit (FATAL_EXIT_CODE);
}
@@ -1631,7 +1703,7 @@ do_wait (prog)
}
-/* Fork and execute a program, and wait for the reply. */
+/* Execute a program, and wait for the reply. */
void
collect_execute (prog, argv, redir)
@@ -1639,7 +1711,11 @@ collect_execute (prog, argv, redir)
char **argv;
char *redir;
{
- int pid;
+ char *errmsg_fmt;
+ char *errmsg_arg;
+ int redir_handle = -1;
+ int stdout_save = -1;
+ int stderr_save = -1;
if (vflag || debug)
{
@@ -1649,7 +1725,7 @@ collect_execute (prog, argv, redir)
if (argv[0])
fprintf (stderr, "%s", argv[0]);
else
- fprintf (stderr, "[cannot find %s]", prog);
+ notice ("[cannot find %s]", prog);
for (p_argv = &argv[1]; (str = *p_argv) != (char *) 0; p_argv++)
fprintf (stderr, " %s", str);
@@ -1666,36 +1742,41 @@ collect_execute (prog, argv, redir)
if (argv[0] == 0)
fatal ("cannot find `%s'", prog);
-#ifndef __CYGWIN32__
- pid = vfork ();
- if (pid == -1)
+ if (redir)
{
-#ifdef vfork
- fatal_perror ("fork");
-#else
- fatal_perror ("vfork");
-#endif
+ /* Open response file. */
+ redir_handle = open (redir, O_WRONLY | O_TRUNC | O_CREAT);
+
+ /* Duplicate the stdout and stderr file handles
+ so they can be restored later. */
+ stdout_save = dup (STDOUT_FILENO);
+ if (stdout_save == -1)
+ fatal_perror ("redirecting stdout: %s", redir);
+ stderr_save = dup (STDERR_FILENO);
+ if (stderr_save == -1)
+ fatal_perror ("redirecting stdout: %s", redir);
+
+ /* Redirect stdout & stderr to our response file. */
+ dup2 (redir_handle, STDOUT_FILENO);
+ dup2 (redir_handle, STDERR_FILENO);
}
- if (pid == 0) /* child context */
+ pexecute_pid = pexecute (argv[0], argv, argv[0], NULL,
+ &errmsg_fmt, &errmsg_arg,
+ (PEXECUTE_FIRST | PEXECUTE_LAST | PEXECUTE_SEARCH));
+
+ if (redir)
{
- if (redir)
- {
- unlink (redir);
- if (freopen (redir, "a", stdout) == NULL)
- fatal_perror ("redirecting stdout: %s", redir);
- if (freopen (redir, "a", stderr) == NULL)
- fatal_perror ("redirecting stderr: %s", redir);
- }
+ /* Restore stdout and stderr to their previous settings. */
+ dup2 (stdout_save, STDOUT_FILENO);
+ dup2 (stderr_save, STDERR_FILENO);
- execvp (argv[0], argv);
- fatal_perror ("executing %s", prog);
+ /* Close reponse file. */
+ close (redir_handle);
}
-#else
- pid = _spawnvp (_P_NOWAIT, argv[0], argv);
- if (pid == -1)
- fatal ("spawnvp failed");
-#endif
+
+ if (pexecute_pid == -1)
+ fatal_perror (errmsg_fmt, errmsg_arg);
}
static void
@@ -1716,7 +1797,7 @@ maybe_unlink (file)
if (!debug)
unlink (file);
else
- fprintf (stderr, "[Leaving %s]\n", file);
+ notice ("[Leaving %s]\n", file);
}
@@ -1763,14 +1844,15 @@ static int
extract_init_priority (name)
char *name;
{
- int pos = 0;
+ int pos = 0, pri;
while (name[pos] == '_')
++pos;
pos += 10; /* strlen ("GLOBAL__X_") */
/* Extract init_p number from ctor/dtor name. */
- return atoi (name + pos);
+ pri = atoi (name + pos);
+ return pri ? pri : DEFAULT_INIT_PRIORITY;
}
/* Insertion sort the ids from ctor/dtor list HEAD_PTR in descending order.
@@ -1934,11 +2016,11 @@ write_c_file_stat (stream, name)
strncpy (prefix, p, q - p);
prefix[q - p] = 0;
for (q = prefix; *q; q++)
- if (!ISALNUM (*q))
+ if (!ISALNUM ((unsigned char)*q))
*q = '_';
if (debug)
- fprintf (stderr, "\nwrite_c_file - output name is %s, prefix is %s\n",
- output_file, prefix);
+ notice ("\nwrite_c_file - output name is %s, prefix is %s\n",
+ output_file, prefix);
#define INIT_NAME_FORMAT "_GLOBAL__FI_%s"
initname = xmalloc (strlen (prefix) + sizeof (INIT_NAME_FORMAT) - 2);
@@ -2195,28 +2277,22 @@ scan_prog_file (prog_name, which_pass)
/* Spawn child nm on pipe */
pid = vfork ();
if (pid == -1)
- {
-#ifdef vfork
- fatal_perror ("fork");
-#else
- fatal_perror ("vfork");
-#endif
- }
+ fatal_perror (VFORK_STRING);
if (pid == 0) /* child context */
{
/* setup stdout */
if (dup2 (pipe_fd[1], 1) < 0)
- fatal_perror ("dup2 (%d, 1)", pipe_fd[1]);
+ fatal_perror ("dup2 %d 1", pipe_fd[1]);
if (close (pipe_fd[0]) < 0)
- fatal_perror ("close (%d)", pipe_fd[0]);
+ fatal_perror ("close %d", pipe_fd[0]);
if (close (pipe_fd[1]) < 0)
- fatal_perror ("close (%d)", pipe_fd[1]);
+ fatal_perror ("close %d", pipe_fd[1]);
execv (nm_file_name, nm_argv);
- fatal_perror ("executing %s", nm_file_name);
+ fatal_perror ("execvp %s", nm_file_name);
}
/* Parent context from here on. */
@@ -2226,7 +2302,7 @@ scan_prog_file (prog_name, which_pass)
#endif
if (close (pipe_fd[1]) < 0)
- fatal_perror ("close (%d)", pipe_fd[1]);
+ fatal_perror ("close %d", pipe_fd[1]);
if (debug)
fprintf (stderr, "\nnm output with constructors/destructors.\n");
@@ -2300,7 +2376,7 @@ scan_prog_file (prog_name, which_pass)
fprintf (stderr, "\n");
if (fclose (inf) != 0)
- fatal_perror ("fclose of pipe");
+ fatal_perror ("fclose");
do_wait (nm_file_name);
@@ -2502,7 +2578,7 @@ locatelib (name)
if (*pp == 0)
{
if (debug)
- fprintf (stderr, "not found\n");
+ notice ("not found\n");
else
fatal ("dynamic dependency %s not found", name);
}
@@ -2546,7 +2622,7 @@ scan_libraries (prog_name)
}
if (debug)
- fprintf (stderr, "dynamic dependencies.\n");
+ notice ("dynamic dependencies.\n");
ld_2 = (struct link_dynamic_2 *) ((long) ld->ld_un.ld_2 + (long)base);
for (lo = (struct link_object *) ld_2->ld_need; lo;
@@ -2637,28 +2713,22 @@ scan_libraries (prog_name)
/* Spawn child ldd on pipe */
pid = vfork ();
if (pid == -1)
- {
-#ifdef vfork
- fatal_perror ("fork");
-#else
- fatal_perror ("vfork");
-#endif
- }
+ fatal_perror (VFORK_STRING);
if (pid == 0) /* child context */
{
/* setup stdout */
if (dup2 (pipe_fd[1], 1) < 0)
- fatal_perror ("dup2 (%d, 1)", pipe_fd[1]);
+ fatal_perror ("dup2 %d 1", pipe_fd[1]);
if (close (pipe_fd[0]) < 0)
- fatal_perror ("close (%d)", pipe_fd[0]);
+ fatal_perror ("close %d", pipe_fd[0]);
if (close (pipe_fd[1]) < 0)
- fatal_perror ("close (%d)", pipe_fd[1]);
+ fatal_perror ("close %d", pipe_fd[1]);
execv (ldd_file_name, ldd_argv);
- fatal_perror ("executing %s", ldd_file_name);
+ fatal_perror ("execv %s", ldd_file_name);
}
/* Parent context from here on. */
@@ -2668,10 +2738,10 @@ scan_libraries (prog_name)
#endif
if (close (pipe_fd[1]) < 0)
- fatal_perror ("close (%d)", pipe_fd[1]);
+ fatal_perror ("close %d", pipe_fd[1]);
if (debug)
- fprintf (stderr, "\nldd output with constructors/destructors.\n");
+ notice ("\nldd output with constructors/destructors.\n");
/* Read each line of ldd output. */
while (fgets (buf, sizeof buf, inf) != (char *) 0)
@@ -2707,7 +2777,7 @@ scan_libraries (prog_name)
fprintf (stderr, "\n");
if (fclose (inf) != 0)
- fatal_perror ("fclose of pipe");
+ fatal_perror ("fclose");
do_wait (ldd_file_name);
@@ -2753,7 +2823,9 @@ scan_libraries (prog_name)
(((X).n_sclass == C_EXT) && ((X).n_scnum == N_UNDEF))
# define GCC_SYMINC(X) ((X).n_numaux+1)
# define GCC_SYMZERO(X) 0
-# define GCC_CHECK_HDR(X) (1)
+# define GCC_CHECK_HDR(X) \
+ ((HEADER (X).f_magic == U802TOCMAGIC && ! aix64_flag) \
+ || (HEADER (X).f_magic == 0757 && aix64_flag))
#endif
extern char *ldgetname ();
@@ -2796,18 +2868,19 @@ scan_prog_file (prog_name, which_pass)
#endif
if ((ldptr = ldopen (prog_name, ldptr)) != NULL)
{
-
- if (!MY_ISCOFF (HEADER (ldptr).f_magic))
+ if (! MY_ISCOFF (HEADER (ldptr).f_magic))
fatal ("%s: not a COFF file", prog_name);
-#ifdef COLLECT_EXPORT_LIST
- /* Is current archive member a shared object? */
- is_shared = HEADER (ldptr).f_flags & F_SHROBJ;
-#endif
if (GCC_CHECK_HDR (ldptr))
{
sym_count = GCC_SYMBOLS (ldptr);
sym_index = GCC_SYMZERO (ldptr);
+
+#ifdef COLLECT_EXPORT_LIST
+ /* Is current archive member a shared object? */
+ is_shared = HEADER (ldptr).f_flags & F_SHROBJ;
+#endif
+
while (sym_index < sym_count)
{
GCC_SYMENT symbol;
@@ -2925,6 +2998,16 @@ scan_prog_file (prog_name, which_pass)
#endif
}
}
+#ifdef COLLECT_EXPORT_LIST
+ else
+ {
+ /* If archive contains both 32-bit and 64-bit objects,
+ we want to skip objects in other mode so mismatch normal. */
+ if (debug)
+ fprintf (stderr, "%s : magic=%o aix64=%d mismatch\n",
+ prog_name, HEADER (ldptr).f_magic, aix64_flag);
+ }
+#endif
}
else
{
@@ -3127,7 +3210,7 @@ scan_prog_file (prog_name, which_pass)
prog_fd = open (prog_name, (rw) ? O_RDWR : O_RDONLY);
if (prog_fd < 0)
- fatal_perror ("cannot read %s", prog_name);
+ fatal_perror ("open %s", prog_name);
obj_file = read_file (prog_name, prog_fd, rw);
obj = obj_file->start;
@@ -3223,8 +3306,8 @@ scan_prog_file (prog_name, which_pass)
case SYMC_STABS: kind = "stabs"; break;
}
- fprintf (stderr, "\nProcessing symbol table #%d, offset = 0x%.8lx, kind = %s\n",
- symbol_load_cmds, load_hdr->hdr.ldci_section_off, kind);
+ notice ("\nProcessing symbol table #%d, offset = 0x%.8lx, kind = %s\n",
+ symbol_load_cmds, load_hdr->hdr.ldci_section_off, kind);
}
if (load_hdr->sym.symc_kind != SYMC_DEFINED_SYMBOLS)
@@ -3308,15 +3391,15 @@ scan_prog_file (prog_name, which_pass)
add_func_table (&hdr, load_array, main_sym, FNTC_INITIALIZATION);
if (debug)
- fprintf (stderr, "\nUpdating header and load commands.\n\n");
+ notice ("\nUpdating header and load commands.\n\n");
hdr.moh_n_load_cmds++;
size = sizeof (load_cmd_map_command_t) + (sizeof (mo_offset_t) * (hdr.moh_n_load_cmds - 1));
/* Create new load command map. */
if (debug)
- fprintf (stderr, "load command map, %d cmds, new size %ld.\n",
- (int)hdr.moh_n_load_cmds, (long)size);
+ notice ("load command map, %d cmds, new size %ld.\n",
+ (int) hdr.moh_n_load_cmds, (long) size);
load_map = (load_union_t *) xcalloc (1, size);
load_map->map.ldc_header.ldci_cmd_type = LDC_CMD_MAP;
@@ -3346,7 +3429,7 @@ scan_prog_file (prog_name, which_pass)
bad_header (status);
if (debug)
- fprintf (stderr, "writing load commands.\n\n");
+ notice ("writing load commands.\n\n");
/* Write load commands */
offset = hdr.moh_first_cmd_off;
@@ -3366,7 +3449,7 @@ scan_prog_file (prog_name, which_pass)
end_file (obj_file);
if (close (prog_fd))
- fatal_perror ("closing %s", prog_name);
+ fatal_perror ("close %s", prog_name);
if (debug)
fprintf (stderr, "\n");
@@ -3444,12 +3527,11 @@ add_func_table (hdr_p, load_array, sym, type)
}
if (debug)
- fprintf (stderr,
- "%s function, region %d, offset = %ld (0x%.8lx)\n",
- (type == FNTC_INITIALIZATION) ? "init" : "term",
- (int)ptr->func.fntc_entry_loc[i].adr_lcid,
- (long)ptr->func.fntc_entry_loc[i].adr_sctoff,
- (long)ptr->func.fntc_entry_loc[i].adr_sctoff);
+ notice ("%s function, region %d, offset = %ld (0x%.8lx)\n",
+ type == FNTC_INITIALIZATION ? "init" : "term",
+ (int) ptr->func.fntc_entry_loc[i].adr_lcid,
+ (long) ptr->func.fntc_entry_loc[i].adr_sctoff,
+ (long) ptr->func.fntc_entry_loc[i].adr_sctoff);
}
@@ -3570,22 +3652,17 @@ static void
bad_header (status)
int status;
{
- char *msg = (char *) 0;
-
switch (status)
{
- case MO_ERROR_BAD_MAGIC: msg = "bad magic number"; break;
- case MO_ERROR_BAD_HDR_VERS: msg = "bad header version"; break;
- case MO_ERROR_BAD_RAW_HDR_VERS: msg = "bad raw header version"; break;
- case MO_ERROR_BUF2SML: msg = "raw header buffer too small"; break;
- case MO_ERROR_OLD_RAW_HDR_FILE: msg = "old raw header file"; break;
- case MO_ERROR_UNSUPPORTED_VERS: msg = "unsupported version"; break;
+ case MO_ERROR_BAD_MAGIC: fatal ("bad magic number");
+ case MO_ERROR_BAD_HDR_VERS: fatal ("bad header version");
+ case MO_ERROR_BAD_RAW_HDR_VERS: fatal ("bad raw header version");
+ case MO_ERROR_BUF2SML: fatal ("raw header buffer too small");
+ case MO_ERROR_OLD_RAW_HDR_FILE: fatal ("old raw header file");
+ case MO_ERROR_UNSUPPORTED_VERS: fatal ("unsupported version");
+ default:
+ fatal ("unknown {de,en}code_mach_o_hdr return value %d", status);
}
-
- if (msg == (char *) 0)
- fatal ("unknown {de,en}code_mach_o_hdr return value %d", status);
- else
- fatal ("%s", msg);
}
@@ -3641,7 +3718,7 @@ read_file (name, fd, rw)
p->use_mmap = 0;
p->start = xmalloc (p->size);
if (lseek (fd, 0L, SEEK_SET) < 0)
- fatal_perror ("lseek to 0 on %s", name);
+ fatal_perror ("lseek %s 0", name);
len = read (fd, p->start, p->size);
if (len < 0)
@@ -3689,7 +3766,7 @@ end_file (ptr)
fprintf (stderr, "write %s\n", ptr->name);
if (lseek (ptr->fd, 0L, SEEK_SET) < 0)
- fatal_perror ("lseek to 0 on %s", ptr->name);
+ fatal_perror ("lseek %s 0", ptr->name);
len = write (ptr->fd, ptr->start, ptr->size);
if (len < 0)
diff --git a/gcc/combine.c b/gcc/combine.c
index 8fc0d7640a6..757ffb636d6 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -1,5 +1,5 @@
/* Optimize by combining instructions for GNU compiler.
- Copyright (C) 1987, 88, 92-97, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1987, 88, 92-98, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -427,7 +427,7 @@ static int merge_outer_ops PROTO((enum rtx_code *, HOST_WIDE_INT *,
enum machine_mode, int *));
static rtx simplify_shift_const PROTO((rtx, enum rtx_code, enum machine_mode,
rtx, int));
-static int recog_for_combine PROTO((rtx *, rtx, rtx *, int *));
+static int recog_for_combine PROTO((rtx *, rtx, rtx *));
static rtx gen_lowpart_for_combine PROTO((enum machine_mode, rtx));
static rtx gen_rtx_combine PVPROTO((enum rtx_code code, enum machine_mode mode,
...));
@@ -574,7 +574,7 @@ combine_instructions (f, nregs)
/* If INSN starts a new basic block, update our basic block number. */
if (this_basic_block + 1 < n_basic_blocks
- && basic_block_head[this_basic_block + 1] == insn)
+ && BLOCK_HEAD (this_basic_block + 1) == insn)
this_basic_block++;
if (GET_CODE (insn) == CODE_LABEL)
@@ -675,6 +675,9 @@ combine_instructions (f, nregs)
total_successes += combine_successes;
nonzero_sign_valid = 0;
+
+ /* Make recognizer allow volatile MEMs again. */
+ init_recog ();
}
/* Wipe the reg_last_xxx arrays in preparation for another pass. */
@@ -742,7 +745,7 @@ set_nonzero_bits_and_sign_copies (x, set)
&& REGNO (x) >= FIRST_PSEUDO_REGISTER
/* If this register is undefined at the start of the file, we can't
say what its contents were. */
- && ! REGNO_REG_SET_P (basic_block_live_at_start[0], REGNO (x))
+ && ! REGNO_REG_SET_P (BASIC_BLOCK (0)->global_live_at_start, REGNO (x))
&& GET_MODE_BITSIZE (GET_MODE (x)) <= HOST_BITS_PER_WIDE_INT)
{
if (set == 0 || GET_CODE (set) == CLOBBER)
@@ -817,7 +820,8 @@ static int
can_combine_p (insn, i3, pred, succ, pdest, psrc)
rtx insn;
rtx i3;
- rtx pred, succ;
+ rtx pred ATTRIBUTE_UNUSED;
+ rtx succ;
rtx *pdest, *psrc;
{
int i;
@@ -1353,8 +1357,6 @@ try_combine (i3, i2, i1)
int i3_subst_into_i2 = 0;
/* Notes that I1, I2 or I3 is a MULT operation. */
int have_mult = 0;
- /* Number of clobbers of SCRATCH we had to add. */
- int i3_scratches = 0, i2_scratches = 0, other_scratches = 0;
int maxreg;
rtx temp;
@@ -1831,8 +1833,7 @@ try_combine (i3, i2, i1)
mark_used_regs_combine (newpat);
/* Is the result of combination a valid instruction? */
- insn_code_number
- = recog_for_combine (&newpat, i3, &new_i3_notes, &i3_scratches);
+ insn_code_number = recog_for_combine (&newpat, i3, &new_i3_notes);
/* If the result isn't valid, see if it is a PARALLEL of two SETs where
the second SET's destination is a register that is unused. In that case,
@@ -1853,8 +1854,7 @@ try_combine (i3, i2, i1)
&& asm_noperands (newpat) < 0)
{
newpat = XVECEXP (newpat, 0, 0);
- insn_code_number
- = recog_for_combine (&newpat, i3, &new_i3_notes, &i3_scratches);
+ insn_code_number = recog_for_combine (&newpat, i3, &new_i3_notes);
}
else if (insn_code_number < 0 && GET_CODE (newpat) == PARALLEL
@@ -1867,8 +1867,7 @@ try_combine (i3, i2, i1)
&& asm_noperands (newpat) < 0)
{
newpat = XVECEXP (newpat, 0, 1);
- insn_code_number
- = recog_for_combine (&newpat, i3, &new_i3_notes, &i3_scratches);
+ insn_code_number = recog_for_combine (&newpat, i3, &new_i3_notes);
}
/* If we were combining three insns and the result is a simple SET
@@ -1937,8 +1936,7 @@ try_combine (i3, i2, i1)
if (REGNO (i2dest) >= FIRST_PSEUDO_REGISTER)
SUBST (regno_reg_rtx[REGNO (i2dest)], ni2dest);
- i2_code_number = recog_for_combine (&newi2pat, i2, &new_i2_notes,
- &i2_scratches);
+ i2_code_number = recog_for_combine (&newi2pat, i2, &new_i2_notes);
/* If I2 or I3 has multiple SETs, we won't know how to track
register status, so don't use these insns. If I2's destination
@@ -1947,8 +1945,8 @@ try_combine (i3, i2, i1)
if (i2_code_number >= 0 && i2set && i3set
&& (next_real_insn (i2) == i3
|| ! reg_used_between_p (SET_DEST (i2set), i2, i3)))
- insn_code_number = recog_for_combine (&newi3pat, i3, &new_i3_notes,
- &i3_scratches);
+ insn_code_number = recog_for_combine (&newi3pat, i3,
+ &new_i3_notes);
if (insn_code_number >= 0)
newpat = newi3pat;
@@ -2035,14 +2033,12 @@ try_combine (i3, i2, i1)
newi2pat = gen_rtx_combine (SET, VOIDmode, newdest, *split);
SUBST (*split, newdest);
- i2_code_number
- = recog_for_combine (&newi2pat, i2, &new_i2_notes, &i2_scratches);
+ i2_code_number = recog_for_combine (&newi2pat, i2, &new_i2_notes);
/* If the split point was a MULT and we didn't have one before,
don't use one now. */
if (i2_code_number >= 0 && ! (split_code == MULT && ! have_mult))
- insn_code_number
- = recog_for_combine (&newpat, i3, &new_i3_notes, &i3_scratches);
+ insn_code_number = recog_for_combine (&newpat, i3, &new_i3_notes);
}
}
@@ -2096,12 +2092,10 @@ try_combine (i3, i2, i1)
newpat = XVECEXP (newpat, 0, 1);
SUBST (SET_SRC (newpat),
gen_lowpart_for_combine (GET_MODE (SET_SRC (newpat)), ni2dest));
- i2_code_number
- = recog_for_combine (&newi2pat, i2, &new_i2_notes, &i2_scratches);
+ i2_code_number = recog_for_combine (&newi2pat, i2, &new_i2_notes);
if (i2_code_number >= 0)
- insn_code_number
- = recog_for_combine (&newpat, i3, &new_i3_notes, &i3_scratches);
+ insn_code_number = recog_for_combine (&newpat, i3, &new_i3_notes);
if (insn_code_number >= 0)
{
@@ -2131,7 +2125,7 @@ try_combine (i3, i2, i1)
for (insn = NEXT_INSN (i3);
insn && (this_basic_block == n_basic_blocks - 1
- || insn != basic_block_head[this_basic_block + 1]);
+ || insn != BLOCK_HEAD (this_basic_block + 1));
insn = NEXT_INSN (insn))
{
if (GET_RTX_CLASS (GET_CODE (insn)) == 'i'
@@ -2188,12 +2182,10 @@ try_combine (i3, i2, i1)
newpat = XVECEXP (newpat, 0, 0);
}
- i2_code_number
- = recog_for_combine (&newi2pat, i2, &new_i2_notes, &i2_scratches);
+ i2_code_number = recog_for_combine (&newi2pat, i2, &new_i2_notes);
if (i2_code_number >= 0)
- insn_code_number
- = recog_for_combine (&newpat, i3, &new_i3_notes, &i3_scratches);
+ insn_code_number = recog_for_combine (&newpat, i3, &new_i3_notes);
}
/* If it still isn't recognized, fail and change things back the way they
@@ -2215,9 +2207,8 @@ try_combine (i3, i2, i1)
CLEAR_HARD_REG_SET (newpat_used_regs);
- other_code_number
- = recog_for_combine (&other_pat, undobuf.other_insn,
- &new_other_notes, &other_scratches);
+ other_code_number = recog_for_combine (&other_pat, undobuf.other_insn,
+ &new_other_notes);
if (other_code_number < 0 && ! check_asm_operands (other_pat))
{
@@ -2320,7 +2311,7 @@ try_combine (i3, i2, i1)
SET_DEST (XVECEXP (PATTERN (i2), 0, i))))
for (temp = NEXT_INSN (i2);
temp && (this_basic_block == n_basic_blocks - 1
- || basic_block_head[this_basic_block] != temp);
+ || BLOCK_HEAD (this_basic_block) != temp);
temp = NEXT_INSN (temp))
if (temp != i3 && GET_RTX_CLASS (GET_CODE (temp)) == 'i')
for (link = LOG_LINKS (temp); link; link = XEXP (link, 1))
@@ -2500,7 +2491,8 @@ try_combine (i3, i2, i1)
regno = REGNO (i2dest);
REG_N_SETS (regno)--;
if (REG_N_SETS (regno) == 0
- && ! REGNO_REG_SET_P (basic_block_live_at_start[0], regno))
+ && ! REGNO_REG_SET_P (BASIC_BLOCK (0)->global_live_at_start,
+ regno))
REG_N_REFS (regno) = 0;
}
}
@@ -2522,7 +2514,8 @@ try_combine (i3, i2, i1)
{
REG_N_SETS (regno)--;
if (REG_N_SETS (regno) == 0
- && ! REGNO_REG_SET_P (basic_block_live_at_start[0], regno))
+ && ! REGNO_REG_SET_P (BASIC_BLOCK (0)->global_live_at_start,
+ regno))
REG_N_REFS (regno) = 0;
}
}
@@ -2534,12 +2527,6 @@ try_combine (i3, i2, i1)
if (newi2pat)
note_stores (newi2pat, set_nonzero_bits_and_sign_copies);
- /* If we added any (clobber (scratch)), add them to the max for a
- block. This is a very pessimistic calculation, since we might
- have had them already and this might not be the worst block, but
- it's not worth doing any better. */
- max_scratch += i3_scratches + i2_scratches + other_scratches;
-
/* If I3 is now an unconditional jump, ensure that it has a
BARRIER following it since it may have initially been a
conditional jump. It may also be the last nonnote insn. */
@@ -2751,7 +2738,7 @@ find_split_point (loc, insn)
if (BITS_BIG_ENDIAN)
pos = GET_MODE_BITSIZE (mode) - len - pos;
- if (src == mask)
+ if ((unsigned HOST_WIDE_INT) src == mask)
SUBST (SET_SRC (x),
gen_binary (IOR, mode, dest, GEN_INT (src << pos)));
else
@@ -3064,103 +3051,154 @@ subst (x, from, to, in_dest, unique_copy)
if (COMBINE_RTX_EQUAL_P (x, to))
return to;
- len = GET_RTX_LENGTH (code);
- fmt = GET_RTX_FORMAT (code);
+ /* Parallel asm_operands need special attention because all of the
+ inputs are shared across the arms. Furthermore, unsharing the
+ rtl results in recognition failures. Failure to handle this case
+ specially can result in circular rtl.
- /* We don't need to process a SET_DEST that is a register, CC0, or PC, so
- set up to skip this common case. All other cases where we want to
- suppress replacing something inside a SET_SRC are handled via the
- IN_DEST operand. */
- if (code == SET
- && (GET_CODE (SET_DEST (x)) == REG
- || GET_CODE (SET_DEST (x)) == CC0
- || GET_CODE (SET_DEST (x)) == PC))
- fmt = "ie";
-
- /* Get the mode of operand 0 in case X is now a SIGN_EXTEND of a
- constant. */
- if (fmt[0] == 'e')
- op0_mode = GET_MODE (XEXP (x, 0));
+ Solve this by doing a normal pass across the first entry of the
+ parallel, and only processing the SET_DESTs of the subsequent
+ entries. Ug. */
- for (i = 0; i < len; i++)
+ if (code == PARALLEL
+ && GET_CODE (XVECEXP (x, 0, 0)) == SET
+ && GET_CODE (SET_SRC (XVECEXP (x, 0, 0))) == ASM_OPERANDS)
{
- if (fmt[i] == 'E')
+ new = subst (XVECEXP (x, 0, 0), from, to, 0, unique_copy);
+
+ /* If this substitution failed, this whole thing fails. */
+ if (GET_CODE (new) == CLOBBER
+ && XEXP (new, 0) == const0_rtx)
+ return new;
+
+ SUBST (XVECEXP (x, 0, 0), new);
+
+ for (i = XVECLEN (x, 0) - 1; i >= 1; i--)
{
- register int j;
- for (j = XVECLEN (x, i) - 1; j >= 0; j--)
+ rtx dest = SET_DEST (XVECEXP (x, 0, i));
+
+ if (GET_CODE (dest) != REG
+ && GET_CODE (dest) != CC0
+ && GET_CODE (dest) != PC)
{
- if (COMBINE_RTX_EQUAL_P (XVECEXP (x, i, j), from))
- {
- new = (unique_copy && n_occurrences ? copy_rtx (to) : to);
- n_occurrences++;
- }
- else
- {
- new = subst (XVECEXP (x, i, j), from, to, 0, unique_copy);
+ new = subst (dest, from, to, 0, unique_copy);
- /* If this substitution failed, this whole thing fails. */
- if (GET_CODE (new) == CLOBBER && XEXP (new, 0) == const0_rtx)
- return new;
- }
+ /* If this substitution failed, this whole thing fails. */
+ if (GET_CODE (new) == CLOBBER
+ && XEXP (new, 0) == const0_rtx)
+ return new;
- SUBST (XVECEXP (x, i, j), new);
+ SUBST (SET_DEST (XVECEXP (x, 0, i)), new);
}
}
- else if (fmt[i] == 'e')
+ }
+ else
+ {
+ len = GET_RTX_LENGTH (code);
+ fmt = GET_RTX_FORMAT (code);
+
+ /* We don't need to process a SET_DEST that is a register, CC0,
+ or PC, so set up to skip this common case. All other cases
+ where we want to suppress replacing something inside a
+ SET_SRC are handled via the IN_DEST operand. */
+ if (code == SET
+ && (GET_CODE (SET_DEST (x)) == REG
+ || GET_CODE (SET_DEST (x)) == CC0
+ || GET_CODE (SET_DEST (x)) == PC))
+ fmt = "ie";
+
+ /* Get the mode of operand 0 in case X is now a SIGN_EXTEND of a
+ constant. */
+ if (fmt[0] == 'e')
+ op0_mode = GET_MODE (XEXP (x, 0));
+
+ for (i = 0; i < len; i++)
{
- if (COMBINE_RTX_EQUAL_P (XEXP (x, i), from))
+ if (fmt[i] == 'E')
+ {
+ register int j;
+ for (j = XVECLEN (x, i) - 1; j >= 0; j--)
+ {
+ if (COMBINE_RTX_EQUAL_P (XVECEXP (x, i, j), from))
+ {
+ new = (unique_copy && n_occurrences
+ ? copy_rtx (to) : to);
+ n_occurrences++;
+ }
+ else
+ {
+ new = subst (XVECEXP (x, i, j), from, to, 0,
+ unique_copy);
+
+ /* If this substitution failed, this whole thing
+ fails. */
+ if (GET_CODE (new) == CLOBBER
+ && XEXP (new, 0) == const0_rtx)
+ return new;
+ }
+
+ SUBST (XVECEXP (x, i, j), new);
+ }
+ }
+ else if (fmt[i] == 'e')
{
- /* In general, don't install a subreg involving two modes not
- tieable. It can worsen register allocation, and can even
- make invalid reload insns, since the reg inside may need to
- be copied from in the outside mode, and that may be invalid
- if it is an fp reg copied in integer mode.
-
- We allow two exceptions to this: It is valid if it is inside
- another SUBREG and the mode of that SUBREG and the mode of
- the inside of TO is tieable and it is valid if X is a SET
- that copies FROM to CC0. */
- if (GET_CODE (to) == SUBREG
- && ! MODES_TIEABLE_P (GET_MODE (to),
- GET_MODE (SUBREG_REG (to)))
- && ! (code == SUBREG
- && MODES_TIEABLE_P (GET_MODE (x),
- GET_MODE (SUBREG_REG (to))))
+ if (COMBINE_RTX_EQUAL_P (XEXP (x, i), from))
+ {
+ /* In general, don't install a subreg involving two
+ modes not tieable. It can worsen register
+ allocation, and can even make invalid reload
+ insns, since the reg inside may need to be copied
+ from in the outside mode, and that may be invalid
+ if it is an fp reg copied in integer mode.
+
+ We allow two exceptions to this: It is valid if
+ it is inside another SUBREG and the mode of that
+ SUBREG and the mode of the inside of TO is
+ tieable and it is valid if X is a SET that copies
+ FROM to CC0. */
+
+ if (GET_CODE (to) == SUBREG
+ && ! MODES_TIEABLE_P (GET_MODE (to),
+ GET_MODE (SUBREG_REG (to)))
+ && ! (code == SUBREG
+ && MODES_TIEABLE_P (GET_MODE (x),
+ GET_MODE (SUBREG_REG (to))))
#ifdef HAVE_cc0
- && ! (code == SET && i == 1 && XEXP (x, 0) == cc0_rtx)
+ && ! (code == SET && i == 1 && XEXP (x, 0) == cc0_rtx)
#endif
- )
- return gen_rtx_CLOBBER (VOIDmode, const0_rtx);
+ )
+ return gen_rtx_CLOBBER (VOIDmode, const0_rtx);
- new = (unique_copy && n_occurrences ? copy_rtx (to) : to);
- n_occurrences++;
+ new = (unique_copy && n_occurrences ? copy_rtx (to) : to);
+ n_occurrences++;
+ }
+ else
+ /* If we are in a SET_DEST, suppress most cases unless we
+ have gone inside a MEM, in which case we want to
+ simplify the address. We assume here that things that
+ are actually part of the destination have their inner
+ parts in the first expression. This is true for SUBREG,
+ STRICT_LOW_PART, and ZERO_EXTRACT, which are the only
+ things aside from REG and MEM that should appear in a
+ SET_DEST. */
+ new = subst (XEXP (x, i), from, to,
+ (((in_dest
+ && (code == SUBREG || code == STRICT_LOW_PART
+ || code == ZERO_EXTRACT))
+ || code == SET)
+ && i == 0), unique_copy);
+
+ /* If we found that we will have to reject this combination,
+ indicate that by returning the CLOBBER ourselves, rather than
+ an expression containing it. This will speed things up as
+ well as prevent accidents where two CLOBBERs are considered
+ to be equal, thus producing an incorrect simplification. */
+
+ if (GET_CODE (new) == CLOBBER && XEXP (new, 0) == const0_rtx)
+ return new;
+
+ SUBST (XEXP (x, i), new);
}
- else
- /* If we are in a SET_DEST, suppress most cases unless we
- have gone inside a MEM, in which case we want to
- simplify the address. We assume here that things that
- are actually part of the destination have their inner
- parts in the first expression. This is true for SUBREG,
- STRICT_LOW_PART, and ZERO_EXTRACT, which are the only
- things aside from REG and MEM that should appear in a
- SET_DEST. */
- new = subst (XEXP (x, i), from, to,
- (((in_dest
- && (code == SUBREG || code == STRICT_LOW_PART
- || code == ZERO_EXTRACT))
- || code == SET)
- && i == 0), unique_copy);
-
- /* If we found that we will have to reject this combination,
- indicate that by returning the CLOBBER ourselves, rather than
- an expression containing it. This will speed things up as
- well as prevent accidents where two CLOBBERs are considered
- to be equal, thus producing an incorrect simplification. */
-
- if (GET_CODE (new) == CLOBBER && XEXP (new, 0) == const0_rtx)
- return new;
-
- SUBST (XEXP (x, i), new);
}
}
@@ -3467,9 +3505,8 @@ simplify_rtx (x, op0_mode, last, in_dest)
plus_constant (XEXP (inner, 0),
(SUBREG_WORD (x) * UNITS_PER_WORD
+ endian_offset)));
- MEM_VOLATILE_P (x) = MEM_VOLATILE_P (inner);
RTX_UNCHANGING_P (x) = RTX_UNCHANGING_P (inner);
- MEM_IN_STRUCT_P (x) = MEM_IN_STRUCT_P (inner);
+ MEM_COPY_ATTRIBUTES (x, inner);
return x;
}
@@ -4120,7 +4157,7 @@ simplify_rtx (x, op0_mode, last, in_dest)
if (new_code == NE && GET_MODE_CLASS (mode) == MODE_INT
&& GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
&& ((STORE_FLAG_VALUE & GET_MODE_MASK (mode))
- == (HOST_WIDE_INT) 1 << (GET_MODE_BITSIZE (mode) - 1))
+ == (unsigned HOST_WIDE_INT) 1 << (GET_MODE_BITSIZE(mode)-1))
&& op1 == const0_rtx
&& mode == GET_MODE (op0)
&& (i = exact_log2 (nonzero_bits (op0, mode))) >= 0)
@@ -4648,9 +4685,8 @@ simplify_set (x)
&& exact_log2 (mask = nonzero_bits (op0, GET_MODE (op0))) >= 0)
{
rtx pat = PATTERN (other_insn), note = 0;
- int scratches;
- if ((recog_for_combine (&pat, other_insn, &note, &scratches) < 0
+ if ((recog_for_combine (&pat, other_insn, &note) < 0
&& ! check_asm_operands (pat)))
{
PUT_CODE (*cc_use, old_code);
@@ -5087,7 +5123,7 @@ simplify_logical (x, last)
when STORE_FLAG_VALUE is the sign bit. */
if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
&& ((STORE_FLAG_VALUE & GET_MODE_MASK (mode))
- == (HOST_WIDE_INT) 1 << (GET_MODE_BITSIZE (mode) - 1))
+ == (unsigned HOST_WIDE_INT) 1 << (GET_MODE_BITSIZE (mode) - 1))
&& op1 == const_true_rtx
&& GET_RTX_CLASS (GET_CODE (op0)) == '<'
&& reversible_comparison_p (op0))
@@ -5562,8 +5598,7 @@ make_extraction (mode, inner, pos, pos_rtx, len,
new = gen_rtx_MEM (tmode, plus_constant (XEXP (inner, 0), offset));
RTX_UNCHANGING_P (new) = RTX_UNCHANGING_P (inner);
- MEM_VOLATILE_P (new) = MEM_VOLATILE_P (inner);
- MEM_IN_STRUCT_P (new) = MEM_IN_STRUCT_P (inner);
+ MEM_COPY_ATTRIBUTES (new, inner);
}
else if (GET_CODE (inner) == REG)
{
@@ -5755,8 +5790,7 @@ make_extraction (mode, inner, pos, pos_rtx, len,
rtx newmem = gen_rtx_MEM (wanted_inner_mode,
plus_constant (XEXP (inner, 0), offset));
RTX_UNCHANGING_P (newmem) = RTX_UNCHANGING_P (inner);
- MEM_VOLATILE_P (newmem) = MEM_VOLATILE_P (inner);
- MEM_IN_STRUCT_P (newmem) = MEM_IN_STRUCT_P (inner);
+ MEM_COPY_ATTRIBUTES (newmem, inner);
inner = newmem;
}
}
@@ -6320,7 +6354,7 @@ force_to_mode (x, mode, mask, reg, just_select)
need it. */
if (GET_CODE (x) == AND && GET_CODE (XEXP (x, 1)) == CONST_INT
- && INTVAL (XEXP (x, 1)) == mask)
+ && (unsigned HOST_WIDE_INT) INTVAL (XEXP (x, 1)) == mask)
x = XEXP (x, 0);
/* If it remains an AND, try making another AND with the bits
@@ -6382,20 +6416,21 @@ force_to_mode (x, mode, mask, reg, just_select)
unsigned HOST_WIDE_INT sp_mask = GET_MODE_MASK (mode);
sp_mask &= ~ (sp_alignment - 1);
- if ((sp_mask & ~ mask) == 0
- && ((INTVAL (XEXP (x, 1)) - STACK_BIAS) & ~ mask) != 0)
+ if ((sp_mask & ~ smask) == 0
+ && ((INTVAL (XEXP (x, 1)) - STACK_BIAS) & ~ smask) != 0)
return force_to_mode (plus_constant (XEXP (x, 0),
((INTVAL (XEXP (x, 1)) -
- STACK_BIAS) & mask)
+ STACK_BIAS) & smask)
+ STACK_BIAS),
- mode, mask, reg, next_select);
+ mode, smask, reg, next_select);
}
#endif
- if ((nonzero_bits (XEXP (x, 0), mode) & ~ mask) == 0
- && (INTVAL (XEXP (x, 1)) & ~ mask) != 0)
+ if ((nonzero_bits (XEXP (x, 0), mode) & ~ smask) == 0
+ && (INTVAL (XEXP (x, 1)) & ~ smask) != 0)
return force_to_mode (plus_constant (XEXP (x, 0),
- INTVAL (XEXP (x, 1)) & mask),
- mode, mask, reg, next_select);
+ (INTVAL (XEXP (x, 1))
+ & smask)),
+ mode, smask, reg, next_select);
}
}
@@ -6541,7 +6576,7 @@ force_to_mode (x, mode, mask, reg, just_select)
/* If we are just looking for the sign bit, we don't need this shift at
all, even if it has a variable count. */
if (GET_MODE_BITSIZE (GET_MODE (x)) <= HOST_BITS_PER_WIDE_INT
- && (mask == ((HOST_WIDE_INT) 1
+ && (mask == ((unsigned HOST_WIDE_INT) 1
<< (GET_MODE_BITSIZE (GET_MODE (x)) - 1))))
return force_to_mode (XEXP (x, 0), mode, mask, reg, next_select);
@@ -7368,7 +7403,7 @@ simplify_and_const_int (x, mode, varop, constop)
else
{
if (GET_CODE (XEXP (x, 1)) != CONST_INT
- || INTVAL (XEXP (x, 1)) != constop)
+ || (unsigned HOST_WIDE_INT) INTVAL (XEXP (x, 1)) != constop)
SUBST (XEXP (x, 1), GEN_INT (constop));
SUBST (XEXP (x, 0), varop);
@@ -7986,13 +8021,15 @@ num_sign_bit_copies (x, mode)
is known to be positive, the number of sign bit copies is the
same as that of the input. Finally, if the input has just one bit
that might be nonzero, all the bits are copies of the sign bit. */
+ num0 = num_sign_bit_copies (XEXP (x, 0), mode);
+ if (bitwidth > HOST_BITS_PER_WIDE_INT)
+ return num0 > 1 ? num0 - 1 : 1;
+
nonzero = nonzero_bits (XEXP (x, 0), mode);
if (nonzero == 1)
return bitwidth;
- num0 = num_sign_bit_copies (XEXP (x, 0), mode);
if (num0 > 1
- && bitwidth <= HOST_BITS_PER_WIDE_INT
&& (((HOST_WIDE_INT) 1 << (bitwidth - 1)) & nonzero))
num0--;
@@ -8036,19 +8073,27 @@ num_sign_bit_copies (x, mode)
result = bitwidth - (bitwidth - num0) - (bitwidth - num1);
if (result > 0
- && bitwidth <= HOST_BITS_PER_WIDE_INT
- && ((nonzero_bits (XEXP (x, 0), mode)
- & ((HOST_WIDE_INT) 1 << (bitwidth - 1))) != 0)
- && ((nonzero_bits (XEXP (x, 1), mode)
- & ((HOST_WIDE_INT) 1 << (bitwidth - 1))) != 0))
+ && (bitwidth > HOST_BITS_PER_WIDE_INT
+ || (((nonzero_bits (XEXP (x, 0), mode)
+ & ((HOST_WIDE_INT) 1 << (bitwidth - 1))) != 0)
+ && ((nonzero_bits (XEXP (x, 1), mode)
+ & ((HOST_WIDE_INT) 1 << (bitwidth - 1))) != 0))))
result--;
return MAX (1, result);
case UDIV:
- /* The result must be <= the first operand. */
- return num_sign_bit_copies (XEXP (x, 0), mode);
-
+ /* The result must be <= the first operand. If the first operand
+ has the high bit set, we know nothing about the number of sign
+ bit copies. */
+ if (bitwidth > HOST_BITS_PER_WIDE_INT)
+ return 1;
+ else if ((nonzero_bits (XEXP (x, 0), mode)
+ & ((HOST_WIDE_INT) 1 << (bitwidth - 1))) != 0)
+ return 1;
+ else
+ return num_sign_bit_copies (XEXP (x, 0), mode);
+
case UMOD:
/* The result must be <= the scond operand. */
return num_sign_bit_copies (XEXP (x, 1), mode);
@@ -8059,20 +8104,20 @@ num_sign_bit_copies (x, mode)
to add 1. */
result = num_sign_bit_copies (XEXP (x, 0), mode);
if (result > 1
- && bitwidth <= HOST_BITS_PER_WIDE_INT
- && (nonzero_bits (XEXP (x, 1), mode)
- & ((HOST_WIDE_INT) 1 << (bitwidth - 1))) != 0)
- result --;
+ && (bitwidth > HOST_BITS_PER_WIDE_INT
+ || (nonzero_bits (XEXP (x, 1), mode)
+ & ((HOST_WIDE_INT) 1 << (bitwidth - 1))) != 0))
+ result--;
return result;
case MOD:
result = num_sign_bit_copies (XEXP (x, 1), mode);
if (result > 1
- && bitwidth <= HOST_BITS_PER_WIDE_INT
- && (nonzero_bits (XEXP (x, 1), mode)
- & ((HOST_WIDE_INT) 1 << (bitwidth - 1))) != 0)
- result --;
+ && (bitwidth > HOST_BITS_PER_WIDE_INT
+ || (nonzero_bits (XEXP (x, 1), mode)
+ & ((HOST_WIDE_INT) 1 << (bitwidth - 1))) != 0))
+ result--;
return result;
@@ -8274,7 +8319,8 @@ merge_outer_ops (pop0, pconst0, op1, const1, mode, pcomp_p)
op0 = NIL;
else if (const0 == 0 && op0 == AND)
op0 = SET;
- else if (const0 == GET_MODE_MASK (mode) && op0 == AND)
+ else if ((unsigned HOST_WIDE_INT) const0 == GET_MODE_MASK (mode)
+ && op0 == AND)
op0 = NIL;
/* If this would be an entire word for the target, but is not for
@@ -8457,8 +8503,7 @@ simplify_shift_const (x, code, result_mode, varop, count)
plus_constant (XEXP (varop, 0),
count / BITS_PER_UNIT));
RTX_UNCHANGING_P (new) = RTX_UNCHANGING_P (varop);
- MEM_VOLATILE_P (new) = MEM_VOLATILE_P (varop);
- MEM_IN_STRUCT_P (new) = MEM_IN_STRUCT_P (varop);
+ MEM_COPY_ATTRIBUTES (new, varop);
varop = gen_rtx_combine (code == ASHIFTRT ? SIGN_EXTEND
: ZERO_EXTEND, mode, new);
count = 0;
@@ -9048,18 +9093,14 @@ simplify_shift_const (x, code, result_mode, varop, count)
PNOTES is a pointer to a location where any REG_UNUSED notes added for
the CLOBBERs are placed.
- PADDED_SCRATCHES is set to the number of (clobber (scratch)) patterns
- we had to add.
-
The value is the final insn code from the pattern ultimately matched,
or -1. */
static int
-recog_for_combine (pnewpat, insn, pnotes, padded_scratches)
+recog_for_combine (pnewpat, insn, pnotes)
rtx *pnewpat;
rtx insn;
rtx *pnotes;
- int *padded_scratches;
{
register rtx pat = *pnewpat;
int insn_code_number;
@@ -9067,8 +9108,6 @@ recog_for_combine (pnewpat, insn, pnotes, padded_scratches)
int i;
rtx notes = 0;
- *padded_scratches = 0;
-
/* If PAT is a PARALLEL, check to see if it contains the CLOBBER
we use to indicate that something didn't match. If we find such a
thing, force rejection. */
@@ -9130,8 +9169,6 @@ recog_for_combine (pnewpat, insn, pnotes, padded_scratches)
if (GET_CODE (XEXP (XVECEXP (newpat, 0, i), 0)) == REG
&& ! reg_dead_at_p (XEXP (XVECEXP (newpat, 0, i), 0), insn))
return -1;
- else if (GET_CODE (XEXP (XVECEXP (newpat, 0, i), 0)) == SCRATCH)
- (*padded_scratches)++;
notes = gen_rtx_EXPR_LIST (REG_UNUSED,
XEXP (XVECEXP (newpat, 0, i), 0), notes);
}
@@ -9225,8 +9262,7 @@ gen_lowpart_for_combine (mode, x)
}
new = gen_rtx_MEM (mode, plus_constant (XEXP (x, 0), offset));
RTX_UNCHANGING_P (new) = RTX_UNCHANGING_P (x);
- MEM_VOLATILE_P (new) = MEM_VOLATILE_P (x);
- MEM_IN_STRUCT_P (new) = MEM_IN_STRUCT_P (x);
+ MEM_COPY_ATTRIBUTES (new, x);
return new;
}
@@ -9261,7 +9297,7 @@ gen_lowpart_for_combine (mode, x)
static rtx
gen_rtx_combine VPROTO((enum rtx_code code, enum machine_mode mode, ...))
{
-#ifndef __STDC__
+#ifndef ANSI_PROTOTYPES
enum rtx_code code;
enum machine_mode mode;
#endif
@@ -9275,7 +9311,7 @@ gen_rtx_combine VPROTO((enum rtx_code code, enum machine_mode mode, ...))
VA_START (p, mode);
-#ifndef __STDC__
+#ifndef ANSI_PROTOTYPES
code = va_arg (p, enum rtx_code);
mode = va_arg (p, enum machine_mode);
#endif
@@ -9535,7 +9571,7 @@ simplify_comparison (code, pop0, pop1)
for (tmode = GET_CLASS_NARROWEST_MODE
(GET_MODE_CLASS (GET_MODE (op0)));
tmode != GET_MODE (op0); tmode = GET_MODE_WIDER_MODE (tmode))
- if (c0 == GET_MODE_MASK (tmode))
+ if ((unsigned HOST_WIDE_INT) c0 == GET_MODE_MASK (tmode))
{
op0 = gen_lowpart_for_combine (tmode, inner_op0);
op1 = gen_lowpart_for_combine (tmode, inner_op1);
@@ -9610,7 +9646,7 @@ simplify_comparison (code, pop0, pop1)
|| code == LT || code == LTU)
&& mode_width <= HOST_BITS_PER_WIDE_INT
&& exact_log2 (const_op) >= 0
- && nonzero_bits (op0, mode) == const_op)
+ && nonzero_bits (op0, mode) == (unsigned HOST_WIDE_INT) const_op)
{
code = (code == EQ || code == GE || code == GEU ? NE : EQ);
op1 = const0_rtx, const_op = 0;
@@ -9939,7 +9975,7 @@ simplify_comparison (code, pop0, pop1)
&& (GET_MODE_BITSIZE (GET_MODE (XEXP (op0, 0)))
<= HOST_BITS_PER_WIDE_INT)
&& ((unsigned HOST_WIDE_INT) const_op
- < (((HOST_WIDE_INT) 1
+ < (((unsigned HOST_WIDE_INT) 1
<< (GET_MODE_BITSIZE (GET_MODE (XEXP (op0, 0))) - 1)))))
{
op0 = XEXP (op0, 0);
@@ -9963,7 +9999,7 @@ simplify_comparison (code, pop0, pop1)
&& GET_CODE (XEXP (SUBREG_REG (op0), 1)) == CONST_INT
&& INTVAL (XEXP (SUBREG_REG (op0), 1)) < 0
&& (- INTVAL (XEXP (SUBREG_REG (op0), 1))
- < GET_MODE_MASK (mode) / 2)
+ < (HOST_WIDE_INT)(GET_MODE_MASK (mode) / 2))
&& (unsigned HOST_WIDE_INT) const_op < GET_MODE_MASK (mode) / 2
&& (0 == (nonzero_bits (XEXP (SUBREG_REG (op0), 0),
GET_MODE (SUBREG_REG (op0)))
@@ -10167,7 +10203,7 @@ simplify_comparison (code, pop0, pop1)
&& GET_CODE (XEXP (op0, 1)) == CONST_INT
&& mode_width <= HOST_BITS_PER_WIDE_INT
&& ((INTVAL (XEXP (op0, 1)) & GET_MODE_MASK (mode))
- == (HOST_WIDE_INT) 1 << (mode_width - 1)))
+ == (unsigned HOST_WIDE_INT) 1 << (mode_width - 1)))
{
op0 = XEXP (op0, 0);
code = (code == EQ ? GE : LT);
@@ -10218,8 +10254,8 @@ simplify_comparison (code, pop0, pop1)
&& (INTVAL (XEXP (op0, 1)) & ~ mask) == 0
&& 0 == (~ GET_MODE_MASK (GET_MODE (SUBREG_REG (XEXP (op0, 0))))
& INTVAL (XEXP (op0, 1)))
- && INTVAL (XEXP (op0, 1)) != mask
- && (INTVAL (XEXP (op0, 1))
+ && (unsigned HOST_WIDE_INT) INTVAL (XEXP (op0, 1)) != mask
+ && ((unsigned HOST_WIDE_INT) INTVAL (XEXP (op0, 1))
!= GET_MODE_MASK (GET_MODE (SUBREG_REG (XEXP (op0, 0))))))
{
@@ -10998,7 +11034,7 @@ reg_dead_at_p (reg, insn)
else
{
for (block = 0; block < n_basic_blocks; block++)
- if (insn == basic_block_head[block])
+ if (insn == BLOCK_HEAD (block))
break;
if (block == n_basic_blocks)
@@ -11006,7 +11042,7 @@ reg_dead_at_p (reg, insn)
}
for (i = reg_dead_regno; i < reg_dead_endregno; i++)
- if (REGNO_REG_SET_P (basic_block_live_at_start[block], i))
+ if (REGNO_REG_SET_P (BASIC_BLOCK (block)->global_live_at_start, i))
return 0;
return 1;
@@ -11399,6 +11435,17 @@ distribute_notes (notes, from_insn, i3, i2, elim_i2, elim_i1)
place = i3;
break;
+ case REG_EH_REGION:
+ /* This note must remain with the call. It should not be possible
+ for both I2 and I3 to be a call. */
+ if (GET_CODE (i3) == CALL_INSN)
+ place = i3;
+ else if (i2 && GET_CODE (i2) == CALL_INSN)
+ place = i2;
+ else
+ abort ();
+ break;
+
case REG_UNUSED:
/* Any clobbers for i3 may still exist, and so we must process
REG_UNUSED notes from that insn.
@@ -11462,7 +11509,6 @@ distribute_notes (notes, from_insn, i3, i2, elim_i2, elim_i1)
case REG_INC:
case REG_NO_CONFLICT:
- case REG_LABEL:
/* These notes say something about how a register is used. They must
be present on any use of the register in I2 or I3. */
if (reg_mentioned_p (XEXP (note, 0), PATTERN (i3)))
@@ -11477,6 +11523,30 @@ distribute_notes (notes, from_insn, i3, i2, elim_i2, elim_i1)
}
break;
+ case REG_LABEL:
+ /* This can show up in several ways -- either directly in the
+ pattern, or hidden off in the constant pool with (or without?)
+ a REG_EQUAL note. */
+ /* ??? Ignore the without-reg_equal-note problem for now. */
+ if (reg_mentioned_p (XEXP (note, 0), PATTERN (i3))
+ || ((tem = find_reg_note (i3, REG_EQUAL, NULL_RTX))
+ && GET_CODE (XEXP (tem, 0)) == LABEL_REF
+ && XEXP (XEXP (tem, 0), 0) == XEXP (note, 0)))
+ place = i3;
+
+ if (i2
+ && (reg_mentioned_p (XEXP (note, 0), PATTERN (i2))
+ || ((tem = find_reg_note (i2, REG_EQUAL, NULL_RTX))
+ && GET_CODE (XEXP (tem, 0)) == LABEL_REF
+ && XEXP (XEXP (tem, 0), 0) == XEXP (note, 0))))
+ {
+ if (place)
+ place2 = i2;
+ else
+ place = i2;
+ }
+ break;
+
case REG_WAS_0:
/* It is too much trouble to try to see if this note is still
correct in all situations. It is better to simply delete it. */
@@ -11564,7 +11634,9 @@ distribute_notes (notes, from_insn, i3, i2, elim_i2, elim_i1)
{
rtx set = single_set (tem);
rtx inner_dest = 0;
+#ifdef HAVE_cc0
rtx cc0_setter = NULL_RTX;
+#endif
if (set != 0)
for (inner_dest = SET_DEST (set);
@@ -11687,9 +11759,9 @@ distribute_notes (notes, from_insn, i3, i2, elim_i2, elim_i1)
tem);
/* If this insn was emitted between blocks, then update
- basic_block_head of the current block to include it. */
- if (basic_block_end[this_basic_block - 1] == tem)
- basic_block_head[this_basic_block] = place;
+ BLOCK_HEAD of the current block to include it. */
+ if (BLOCK_END (this_basic_block - 1) == tem)
+ BLOCK_HEAD (this_basic_block) = place;
}
}
@@ -11888,7 +11960,7 @@ distribute_links (links)
for (insn = NEXT_INSN (XEXP (link, 0));
(insn && (this_basic_block == n_basic_blocks - 1
- || basic_block_head[this_basic_block + 1] != insn));
+ || BLOCK_HEAD (this_basic_block + 1) != insn));
insn = NEXT_INSN (insn))
if (GET_RTX_CLASS (GET_CODE (insn)) == 'i'
&& reg_overlap_mentioned_p (reg, PATTERN (insn)))
@@ -11950,7 +12022,7 @@ void
dump_combine_stats (file)
FILE *file;
{
- fprintf
+ fnotice
(file,
";; Combiner statistics: %d attempts, %d substitutions (%d requiring new space),\n;; %d successes.\n\n",
combine_attempts, combine_merges, combine_extras, combine_successes);
@@ -11960,7 +12032,7 @@ void
dump_combine_total_stats (file)
FILE *file;
{
- fprintf
+ fnotice
(file,
"\n;; Combiner totals: %d attempts, %d substitutions (%d requiring new space),\n;; %d successes.\n",
total_attempts, total_merges, total_extras, total_successes);
diff --git a/gcc/config.in b/gcc/config.in
index 05b300231b1..dc6cf2e937e 100644
--- a/gcc/config.in
+++ b/gcc/config.in
@@ -8,6 +8,15 @@
/* Define if you want expensive run-time checks. */
#undef ENABLE_CHECKING
+/* Define to 1 if NLS is requested. */
+#undef ENABLE_NLS
+
+/* Define as 1 if you have catgets and don't want to use GNU gettext. */
+#undef HAVE_CATGETS
+
+/* Define as 1 if you have gettext and don't want to use GNU gettext. */
+#undef HAVE_GETTEXT
+
/* Define if your cpp understands the stringify operator. */
#undef HAVE_CPP_STRINGIFY
@@ -28,6 +37,12 @@
/* Define if you have a working <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
+/* Define if your locale.h file contains LC_MESSAGES. */
+#undef HAVE_LC_MESSAGES
+
+/* Define as 1 if you have the stpcpy function. */
+#undef HAVE_STPCPY
+
/* Whether malloc must be declared even if <stdlib.h> is included. */
#undef NEED_DECLARATION_MALLOC
@@ -61,6 +76,9 @@
/* Whether atol must be declared even if <stdlib.h> is included. */
#undef NEED_DECLARATION_ATOL
+/* Whether atof must be declared even if <stdlib.h> is included. */
+#undef NEED_DECLARATION_ATOF
+
/* Whether sbrk must be declared even if <stdlib.h> is included. */
#undef NEED_DECLARATION_SBRK
@@ -85,6 +103,12 @@
/* Whether setrlimit must be declared even if <sys/resource.h> is included. */
#undef NEED_DECLARATION_SETRLIMIT
+/* Whether putc_unlocked must be declared even if <stdio.h> is included. */
+#undef NEED_DECLARATION_PUTC_UNLOCKED
+
+/* Whether fputs_unlocked must be declared even if <stdio.h> is included. */
+#undef NEED_DECLARATION_FPUTS_UNLOCKED
+
/* Define if you want expensive run-time checks. */
#undef ENABLE_CHECKING
@@ -94,13 +118,64 @@
/* Define to enable the use of a default linker. */
#undef DEFAULT_LINKER
+/* Define to the name of the distribution. */
+#undef PACKAGE
+
+/* Define to the version of the distribution. */
+#undef VERSION
+
+/* Define if using alloca.c. */
+#undef C_ALLOCA
+
+/* Define to empty if the keyword does not work. */
+#undef const
+
+/* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems.
+ This function is required for alloca.c support on those systems. */
+#undef CRAY_STACKSEG_END
+
+/* Define if you have alloca, as a function or macro. */
+#undef HAVE_ALLOCA
+
+/* Define if you have <alloca.h> and it should be used (not on Ultrix). */
+#undef HAVE_ALLOCA_H
/* Define if you don't have vprintf but do have _doprnt. */
#undef HAVE_DOPRNT
+/* Define if you have a working `mmap' system call. */
+#undef HAVE_MMAP
+
+/* Define if you have <sys/wait.h> that is POSIX.1 compatible. */
+#undef HAVE_SYS_WAIT_H
+
+/* Define if you have <vfork.h>. */
+#undef HAVE_VFORK_H
+
/* Define if you have the vprintf function. */
#undef HAVE_VPRINTF
+/* Define as __inline if that's what the C compiler calls it. */
+#undef inline
+
+/* Define to `long' if <sys/types.h> doesn't define. */
+#undef off_t
+
+/* Define to `int' if <sys/types.h> doesn't define. */
+#undef pid_t
+
+/* Define to `unsigned' if <sys/types.h> doesn't define. */
+#undef size_t
+
+/* If using the C implementation of alloca, define if you know the
+ direction of stack growth for your system; otherwise it will be
+ automatically deduced at run-time.
+ STACK_DIRECTION > 0 => grows toward higher addresses
+ STACK_DIRECTION < 0 => grows toward lower addresses
+ STACK_DIRECTION = 0 => direction of growth unknown
+ */
+#undef STACK_DIRECTION
+
/* Define if you have the ANSI C header files. */
#undef STDC_HEADERS
@@ -110,6 +185,18 @@
/* Define if you can safely include both <sys/time.h> and <time.h>. */
#undef TIME_WITH_SYS_TIME
+/* Define vfork as fork if vfork does not work. */
+#undef vfork
+
+/* Define if you have the __argz_count function. */
+#undef HAVE___ARGZ_COUNT
+
+/* Define if you have the __argz_next function. */
+#undef HAVE___ARGZ_NEXT
+
+/* Define if you have the __argz_stringify function. */
+#undef HAVE___ARGZ_STRINGIFY
+
/* Define if you have the atoll function. */
#undef HAVE_ATOLL
@@ -128,6 +215,21 @@
/* Define if you have the bzero function. */
#undef HAVE_BZERO
+/* Define if you have the dcgettext function. */
+#undef HAVE_DCGETTEXT
+
+/* Define if you have the fputc_unlocked function. */
+#undef HAVE_FPUTC_UNLOCKED
+
+/* Define if you have the fputs_unlocked function. */
+#undef HAVE_FPUTS_UNLOCKED
+
+/* Define if you have the getcwd function. */
+#undef HAVE_GETCWD
+
+/* Define if you have the getpagesize function. */
+#undef HAVE_GETPAGESIZE
+
/* Define if you have the getrlimit function. */
#undef HAVE_GETRLIMIT
@@ -143,21 +245,42 @@
/* Define if you have the kill function. */
#undef HAVE_KILL
+/* Define if you have the munmap function. */
+#undef HAVE_MUNMAP
+
/* Define if you have the popen function. */
#undef HAVE_POPEN
+/* Define if you have the putc_unlocked function. */
+#undef HAVE_PUTC_UNLOCKED
+
/* Define if you have the putenv function. */
#undef HAVE_PUTENV
/* Define if you have the rindex function. */
#undef HAVE_RINDEX
+/* Define if you have the setenv function. */
+#undef HAVE_SETENV
+
+/* Define if you have the setlocale function. */
+#undef HAVE_SETLOCALE
+
/* Define if you have the setrlimit function. */
#undef HAVE_SETRLIMIT
+/* Define if you have the stpcpy function. */
+#undef HAVE_STPCPY
+
+/* Define if you have the strcasecmp function. */
+#undef HAVE_STRCASECMP
+
/* Define if you have the strchr function. */
#undef HAVE_STRCHR
+/* Define if you have the strdup function. */
+#undef HAVE_STRDUP
+
/* Define if you have the strerror function. */
#undef HAVE_STRERROR
@@ -173,12 +296,24 @@
/* Define if you have the sysconf function. */
#undef HAVE_SYSCONF
+/* Define if you have the <argz.h> header file. */
+#undef HAVE_ARGZ_H
+
/* Define if you have the <fcntl.h> header file. */
#undef HAVE_FCNTL_H
/* Define if you have the <limits.h> header file. */
#undef HAVE_LIMITS_H
+/* Define if you have the <locale.h> header file. */
+#undef HAVE_LOCALE_H
+
+/* Define if you have the <malloc.h> header file. */
+#undef HAVE_MALLOC_H
+
+/* Define if you have the <nl_types.h> header file. */
+#undef HAVE_NL_TYPES_H
+
/* Define if you have the <stab.h> header file. */
#undef HAVE_STAB_H
@@ -203,20 +338,20 @@
/* Define if you have the <sys/resource.h> header file. */
#undef HAVE_SYS_RESOURCE_H
+/* Define if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
/* Define if you have the <sys/time.h> header file. */
#undef HAVE_SYS_TIME_H
/* Define if you have the <sys/times.h> header file. */
#undef HAVE_SYS_TIMES_H
-/* Define if you have the <sys/wait.h> header file. */
-#undef HAVE_SYS_WAIT_H
-
/* Define if you have the <time.h> header file. */
#undef HAVE_TIME_H
/* Define if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
-/* Define if you have the <wait.h> header file. */
-#undef HAVE_WAIT_H
+/* Define if you have the i library (-li). */
+#undef HAVE_LIBI
diff --git a/gcc/config.sub b/gcc/config.sub
deleted file mode 100755
index f1ee4a1714b..00000000000
--- a/gcc/config.sub
+++ /dev/null
@@ -1,979 +0,0 @@
-#! /bin/sh
-# Configuration validation subroutine script, version 1.1.
-# Copyright (C) 1991, 92-97, 1998 Free Software Foundation, Inc.
-# This file is (in principle) common to ALL GNU software.
-# The presence of a machine in this file suggests that SOME GNU software
-# can handle that machine. It does not imply ALL GNU software can.
-#
-# This file is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330,
-# Boston, MA 02111-1307, USA.
-
-# 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.
-
-# Configuration subroutine to validate and canonicalize a configuration type.
-# Supply the specified configuration type as an argument.
-# If it is invalid, we print an error message on stderr and exit with code 1.
-# Otherwise, we print the canonical config type on stdout and succeed.
-
-# This file is supposed to be the same for all GNU packages
-# and recognize all the CPU types, system types and aliases
-# that are meaningful with *any* GNU software.
-# Each package is responsible for reporting which valid configurations
-# it does not support. The user should be able to distinguish
-# a failure to support a valid configuration from a meaningless
-# configuration.
-
-# The goal of this file is to map all the various variations of a given
-# machine specification into a single specification in the form:
-# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
-# or in some cases, the newer four-part form:
-# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
-# It is wrong to echo any other type of specification.
-
-if [ x$1 = x ]
-then
- echo Configuration name missing. 1>&2
- echo "Usage: $0 CPU-MFR-OPSYS" 1>&2
- echo "or $0 ALIAS" 1>&2
- echo where ALIAS is a recognized configuration type. 1>&2
- exit 1
-fi
-
-# First pass through any local machine types.
-case $1 in
- *local*)
- echo $1
- exit 0
- ;;
- *)
- ;;
-esac
-
-# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
-# Here we must recognize all the valid KERNEL-OS combinations.
-maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
-case $maybe_os in
- linux-gnu*)
- os=-$maybe_os
- basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
- ;;
- *)
- basic_machine=`echo $1 | sed 's/-[^-]*$//'`
- if [ $basic_machine != $1 ]
- then os=`echo $1 | sed 's/.*-/-/'`
- else os=; fi
- ;;
-esac
-
-### Let's recognize common machines as not being operating systems so
-### that things like config.sub decstation-3100 work. We also
-### recognize some manufacturers as not being operating systems, so we
-### can provide default operating systems below.
-case $os in
- -sun*os*)
- # Prevent following clause from handling this invalid input.
- ;;
- -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
- -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
- -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
- -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
- -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
- -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
- -apple)
- os=
- basic_machine=$1
- ;;
- -hiux*)
- os=-hiuxwe2
- ;;
- -sco5)
- os=-sco3.2v5
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -sco4)
- os=-sco3.2v4
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -sco3.2.[4-9]*)
- os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -sco3.2v[4-9]*)
- # Don't forget version if it is 3.2v4 or newer.
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -udk*)
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -sco*)
- os=-sco3.2v2
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -isc)
- os=-isc2.2
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -clix*)
- basic_machine=clipper-intergraph
- ;;
- -isc*)
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -lynx*)
- os=-lynxos
- ;;
- -ptx*)
- basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
- ;;
- -windowsnt*)
- os=`echo $os | sed -e 's/windowsnt/winnt/'`
- ;;
- -psos*)
- os=-psos
- ;;
-esac
-
-# Decode aliases for certain CPU-COMPANY combinations.
-case $basic_machine in
- # Recognize the basic CPU types without company name.
- # Some are omitted here because they have special meanings below.
- tahoe | i860 | m32r | m68k | m68000 | m88k | ns32k | arc | arm \
- | arme[lb] | pyramid | mn10200 | mn10300 \
- | tron | a29k | 580 | i960 | h8300 | hppa | hppa1.0 | hppa1.1 \
- | alpha | alphaev5 | alphaev56 | we32k | ns16k | clipper \
- | i370 | sh | powerpc | powerpcle | 1750a | dsp16xx | pdp11 \
- | mips64 | mipsel | mips64el | mips64orion | mips64orionel \
- | mipstx39 | mipstx39el \
- | sparc | sparclet | sparclite | sparc64 | sparcv9 | v850)
- basic_machine=$basic_machine-unknown
- ;;
- thumb | thumbel)
- basic_machine=$basic_machine-unknown
- ;;
- # We use `pc' rather than `unknown'
- # because (1) that's what they normally are, and
- # (2) the word "unknown" tends to confuse beginning users.
- i[34567]86)
- basic_machine=$basic_machine-pc
- ;;
- # Object if more than one company name word.
- *-*-*)
- echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
- exit 1
- ;;
- # Recognize the basic CPU types with company name.
- vax-* | tahoe-* | i[34567]86-* | i860-* | m32r-* | m68k-* | m68000-* \
- | m88k-* | sparc-* | ns32k-* | fx80-* | arc-* | arm-* | c[123]* \
- | mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* \
- | power-* | none-* | 580-* | cray2-* | h8300-* | i960-* \
- | xmp-* | ymp-* | hppa-* | hppa1.0-* | hppa1.1-* \
- | alpha-* | alphaev5-* | alphaev56-* | we32k-* | cydra-* \
- | ns16k-* | pn-* | np1-* | xps100-* | clipper-* | orion-* \
- | sparclite-* | pdp11-* | sh-* | powerpc-* | powerpcle-* \
- | sparc64-* | sparcv9-* | mips64-* | mipsel-* \
- | mips64el-* | mips64orion-* | mips64orionel-* \
- | mipstx39-* | mipstx39el-* \
- | f301-*)
- ;;
- # Recognize the various machine names and aliases which stand
- # for a CPU type and a company and sometimes even an OS.
- 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
- basic_machine=m68000-att
- ;;
- 3b*)
- basic_machine=we32k-att
- ;;
- alliant | fx80)
- basic_machine=fx80-alliant
- ;;
- altos | altos3068)
- basic_machine=m68k-altos
- ;;
- am29k)
- basic_machine=a29k-none
- os=-bsd
- ;;
- amdahl)
- basic_machine=580-amdahl
- os=-sysv
- ;;
- amiga | amiga-*)
- basic_machine=m68k-cbm
- ;;
- amigaos | amigados)
- basic_machine=m68k-cbm
- os=-amigaos
- ;;
- amigaunix | amix)
- basic_machine=m68k-cbm
- os=-sysv4
- ;;
- apollo68)
- basic_machine=m68k-apollo
- os=-sysv
- ;;
- aux)
- basic_machine=m68k-apple
- os=-aux
- ;;
- balance)
- basic_machine=ns32k-sequent
- os=-dynix
- ;;
- convex-c1)
- basic_machine=c1-convex
- os=-bsd
- ;;
- convex-c2)
- basic_machine=c2-convex
- os=-bsd
- ;;
- convex-c32)
- basic_machine=c32-convex
- os=-bsd
- ;;
- convex-c34)
- basic_machine=c34-convex
- os=-bsd
- ;;
- convex-c38)
- basic_machine=c38-convex
- os=-bsd
- ;;
- cray | ymp)
- basic_machine=ymp-cray
- os=-unicos
- ;;
- cray2)
- basic_machine=cray2-cray
- os=-unicos
- ;;
- [ctj]90-cray)
- basic_machine=c90-cray
- os=-unicos
- ;;
- crds | unos)
- basic_machine=m68k-crds
- ;;
- da30 | da30-*)
- basic_machine=m68k-da30
- ;;
- decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
- basic_machine=mips-dec
- ;;
- delta | 3300 | motorola-3300 | motorola-delta \
- | 3300-motorola | delta-motorola)
- basic_machine=m68k-motorola
- ;;
- delta88)
- basic_machine=m88k-motorola
- os=-sysv3
- ;;
- dpx20 | dpx20-*)
- basic_machine=rs6000-bull
- os=-bosx
- ;;
- dpx2* | dpx2*-bull)
- basic_machine=m68k-bull
- os=-sysv3
- ;;
- ebmon29k)
- basic_machine=a29k-amd
- os=-ebmon
- ;;
- elxsi)
- basic_machine=elxsi-elxsi
- os=-bsd
- ;;
- encore | umax | mmax)
- basic_machine=ns32k-encore
- ;;
- fx2800)
- basic_machine=i860-alliant
- ;;
- genix)
- basic_machine=ns32k-ns
- ;;
- gmicro)
- basic_machine=tron-gmicro
- os=-sysv
- ;;
- h3050r* | hiux*)
- basic_machine=hppa1.1-hitachi
- os=-hiuxwe2
- ;;
- h8300hms)
- basic_machine=h8300-hitachi
- os=-hms
- ;;
- harris)
- basic_machine=m88k-harris
- os=-sysv3
- ;;
- hp300-*)
- basic_machine=m68k-hp
- ;;
- hp300bsd)
- basic_machine=m68k-hp
- os=-bsd
- ;;
- hp300hpux)
- basic_machine=m68k-hp
- os=-hpux
- ;;
- hp9k2[0-9][0-9] | hp9k31[0-9])
- basic_machine=m68000-hp
- ;;
- hp9k3[2-9][0-9])
- basic_machine=m68k-hp
- ;;
- hp9k6[0-9][0-9] | hp6[0-9][0-9] )
- basic_machine=hppa1.0-hp
- ;;
- hp9k7[0-79][0-9] | hp7[0-79][0-9] )
- basic_machine=hppa1.1-hp
- ;;
- hp9k78[0-9] | hp78[0-9] )
- # FIXME: really hppa2.0-hp
- basic_machine=hppa1.1-hp
- ;;
- hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | \
- hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893 )
- # FIXME: really hppa2.0-hp
- basic_machine=hppa1.1-hp
- ;;
- hp9k8[0-9][13679] | hp8[0-9][13679] )
- basic_machine=hppa1.1-hp
- ;;
- hp9k8[0-9][0-9] | hp8[0-9][0-9])
- basic_machine=hppa1.0-hp
- ;;
- hppa-next)
- os=-nextstep3
- ;;
- i370-ibm* | ibm*)
- basic_machine=i370-ibm
- os=-mvs
- ;;
-# I'm not sure what "Sysv32" means. Should this be sysv3.2?
- i[34567]86v32)
- basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
- os=-sysv32
- ;;
- i[34567]86v4*)
- basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
- os=-sysv4
- ;;
- i[34567]86v)
- basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
- os=-sysv
- ;;
- i[34567]86sol2)
- basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
- os=-solaris2
- ;;
- iris | iris4d)
- basic_machine=mips-sgi
- case $os in
- -irix*)
- ;;
- *)
- os=-irix4
- ;;
- esac
- ;;
- isi68 | isi)
- basic_machine=m68k-isi
- os=-sysv
- ;;
- m88k-omron*)
- basic_machine=m88k-omron
- ;;
- magnum | m3230)
- basic_machine=mips-mips
- os=-sysv
- ;;
- merlin)
- basic_machine=ns32k-utek
- os=-sysv
- ;;
- miniframe)
- basic_machine=m68000-convergent
- ;;
- mipsel*-linux*)
- basic_machine=mipsel-unknown
- os=-linux-gnu
- ;;
- mips*-linux*)
- basic_machine=mips-unknown
- os=-linux-gnu
- ;;
- mips3*-*)
- basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
- ;;
- mips3*)
- basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
- ;;
- ncr3000)
- basic_machine=i486-ncr
- os=-sysv4
- ;;
- news | news700 | news800 | news900)
- basic_machine=m68k-sony
- os=-newsos
- ;;
- news1000)
- basic_machine=m68030-sony
- os=-newsos
- ;;
- news-3600 | risc-news)
- basic_machine=mips-sony
- os=-newsos
- ;;
- next | m*-next )
- basic_machine=m68k-next
- case $os in
- -nextstep* )
- ;;
- -ns2*)
- os=-nextstep2
- ;;
- *)
- os=-nextstep3
- ;;
- esac
- ;;
- nh3000)
- basic_machine=m68k-harris
- os=-cxux
- ;;
- nh[45]000)
- basic_machine=m88k-harris
- os=-cxux
- ;;
- nindy960)
- basic_machine=i960-intel
- os=-nindy
- ;;
- np1)
- basic_machine=np1-gould
- ;;
- pa-hitachi)
- basic_machine=hppa1.1-hitachi
- os=-hiuxwe2
- ;;
- paragon)
- basic_machine=i860-intel
- os=-osf
- ;;
- pbd)
- basic_machine=sparc-tti
- ;;
- pbb)
- basic_machine=m68k-tti
- ;;
- pc532 | pc532-*)
- basic_machine=ns32k-pc532
- ;;
- pentium | p5 | k5 | nexen)
- basic_machine=i586-pc
- ;;
- pentiumpro | p6 | k6 | 6x86)
- basic_machine=i686-pc
- ;;
- pentiumii | pentium2)
- basic_machine=i786-pc
- ;;
- pentium-* | p5-* | k5-* | nexen-*)
- basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- pentiumpro-* | p6-* | k6-* | 6x86-*)
- basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- pentiumii-* | pentium2-*)
- basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- pn)
- basic_machine=pn-gould
- ;;
- power) basic_machine=rs6000-ibm
- ;;
- ppc) basic_machine=powerpc-unknown
- ;;
- ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- ppcle | powerpclittle | ppc-le | powerpc-little)
- basic_machine=powerpcle-unknown
- ;;
- ppcle-* | powerpclittle-*)
- basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- ps2)
- basic_machine=i386-ibm
- ;;
- rm[46]00)
- basic_machine=mips-siemens
- ;;
- rtpc | rtpc-*)
- basic_machine=romp-ibm
- ;;
- sequent)
- basic_machine=i386-sequent
- ;;
- sh)
- basic_machine=sh-hitachi
- os=-hms
- ;;
- sps7)
- basic_machine=m68k-bull
- os=-sysv2
- ;;
- spur)
- basic_machine=spur-unknown
- ;;
- sun2)
- basic_machine=m68000-sun
- ;;
- sun2os3)
- basic_machine=m68000-sun
- os=-sunos3
- ;;
- sun2os4)
- basic_machine=m68000-sun
- os=-sunos4
- ;;
- sun3os3)
- basic_machine=m68k-sun
- os=-sunos3
- ;;
- sun3os4)
- basic_machine=m68k-sun
- os=-sunos4
- ;;
- sun4os3)
- basic_machine=sparc-sun
- os=-sunos3
- ;;
- sun4os4)
- basic_machine=sparc-sun
- os=-sunos4
- ;;
- sun4sol2)
- basic_machine=sparc-sun
- os=-solaris2
- ;;
- sun3 | sun3-*)
- basic_machine=m68k-sun
- ;;
- sun4)
- basic_machine=sparc-sun
- ;;
- sun386 | sun386i | roadrunner)
- basic_machine=i386-sun
- ;;
- symmetry)
- basic_machine=i386-sequent
- os=-dynix
- ;;
- tx39)
- basic_machine=mipstx39-unknown
- ;;
- tx39el)
- basic_machine=mipstx39el-unknown
- ;;
- tower | tower-32)
- basic_machine=m68k-ncr
- ;;
- udi29k)
- basic_machine=a29k-amd
- os=-udi
- ;;
- ultra3)
- basic_machine=a29k-nyu
- os=-sym1
- ;;
- vaxv)
- basic_machine=vax-dec
- os=-sysv
- ;;
- vms)
- basic_machine=vax-dec
- os=-vms
- ;;
- vpp*|vx|vx-*)
- basic_machine=f301-fujitsu
- ;;
- vxworks960)
- basic_machine=i960-wrs
- os=-vxworks
- ;;
- vxworks68)
- basic_machine=m68k-wrs
- os=-vxworks
- ;;
- vxworks29k)
- basic_machine=a29k-wrs
- os=-vxworks
- ;;
- xmp)
- basic_machine=xmp-cray
- os=-unicos
- ;;
- xps | xps100)
- basic_machine=xps100-honeywell
- ;;
- none)
- basic_machine=none-none
- os=-none
- ;;
-
-# Here we handle the default manufacturer of certain CPU types. It is in
-# some cases the only manufacturer, in others, it is the most popular.
- mips)
- if [ x$os = x-linux-gnu ]; then
- basic_machine=mips-unknown
- else
- basic_machine=mips-mips
- fi
- ;;
- romp)
- basic_machine=romp-ibm
- ;;
- rs6000)
- basic_machine=rs6000-ibm
- ;;
- vax)
- basic_machine=vax-dec
- ;;
- pdp11)
- basic_machine=pdp11-dec
- ;;
- we32k)
- basic_machine=we32k-att
- ;;
- sparc | sparcv9)
- basic_machine=sparc-sun
- ;;
- cydra)
- basic_machine=cydra-cydrome
- ;;
- orion)
- basic_machine=orion-highlevel
- ;;
- orion105)
- basic_machine=clipper-highlevel
- ;;
- *)
- echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
- exit 1
- ;;
-esac
-
-# Here we canonicalize certain aliases for manufacturers.
-case $basic_machine in
- *-digital*)
- basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
- ;;
- *-commodore*)
- basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
- ;;
- *)
- ;;
-esac
-
-# Decode manufacturer-specific aliases for certain operating systems.
-
-if [ x"$os" != x"" ]
-then
-case $os in
- # First match some system type aliases
- # that might get confused with valid system types.
- # -solaris* is a basic system type, with this one exception.
- -solaris1 | -solaris1.*)
- os=`echo $os | sed -e 's|solaris1|sunos4|'`
- ;;
- -solaris)
- os=-solaris2
- ;;
- -svr4*)
- os=-sysv4
- ;;
- -unixware*)
- os=-sysv4.2uw
- ;;
- -gnu/linux*)
- os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
- ;;
- # First accept the basic system types.
- # The portable systems comes first.
- # Each alternative MUST END IN A *, to match a version number.
- # -sysv* is not here because it comes later, after sysvr4.
- -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
- | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
- | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
- | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
- | -aos* \
- | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
- | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
- | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \
- | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* \
- | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
- | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
- | -cygwin32* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
- | -win32* | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -udk* )
- # Remember, each alternative MUST END IN *, to match a version number.
- ;;
- -linux*)
- os=`echo $os | sed -e 's|linux|linux-gnu|'`
- ;;
- -sunos5*)
- os=`echo $os | sed -e 's|sunos5|solaris2|'`
- ;;
- -sunos6*)
- os=`echo $os | sed -e 's|sunos6|solaris3|'`
- ;;
- -osfrose*)
- os=-osfrose
- ;;
- -osf*)
- os=-osf
- ;;
- -utek*)
- os=-bsd
- ;;
- -dynix*)
- os=-bsd
- ;;
- -acis*)
- os=-aos
- ;;
- -ctix* | -uts*)
- os=-sysv
- ;;
- -ns2 )
- os=-nextstep2
- ;;
- # Preserve the version number of sinix5.
- -sinix5.*)
- os=`echo $os | sed -e 's|sinix|sysv|'`
- ;;
- -sinix*)
- os=-sysv4
- ;;
- -triton*)
- os=-sysv3
- ;;
- -oss*)
- os=-sysv3
- ;;
- -svr4)
- os=-sysv4
- ;;
- -svr3)
- os=-sysv3
- ;;
- -sysvr4)
- os=-sysv4
- ;;
- # This must come after -sysvr4.
- -sysv*)
- ;;
- -xenix)
- os=-xenix
- ;;
- -none)
- ;;
- *)
- # Get rid of the `-' at the beginning of $os.
- os=`echo $os | sed 's/[^-]*-//'`
- echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
- exit 1
- ;;
-esac
-else
-
-# Here we handle the default operating systems that come with various machines.
-# The value should be what the vendor currently ships out the door with their
-# machine or put another way, the most popular os provided with the machine.
-
-# Note that if you're going to try to match "-MANUFACTURER" here (say,
-# "-sun"), then you have to tell the case statement up towards the top
-# that MANUFACTURER isn't an operating system. Otherwise, code above
-# will signal an error saying that MANUFACTURER isn't an operating
-# system, and we'll never get to this point.
-
-case $basic_machine in
- *-acorn)
- os=-riscix1.2
- ;;
- arm*-semi)
- os=-aout
- ;;
- pdp11-*)
- os=-none
- ;;
- *-dec | vax-*)
- os=-ultrix4.2
- ;;
- m68*-apollo)
- os=-domain
- ;;
- i386-sun)
- os=-sunos4.0.2
- ;;
- m68000-sun)
- os=-sunos3
- # This also exists in the configure program, but was not the
- # default.
- # os=-sunos4
- ;;
- *-tti) # must be before sparc entry or we get the wrong os.
- os=-sysv3
- ;;
- sparc-* | *-sun)
- os=-sunos4.1.1
- ;;
- *-ibm)
- os=-aix
- ;;
- *-hp)
- os=-hpux
- ;;
- *-hitachi)
- os=-hiux
- ;;
- i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
- os=-sysv
- ;;
- *-cbm)
- os=-amigaos
- ;;
- *-dg)
- os=-dgux
- ;;
- *-dolphin)
- os=-sysv3
- ;;
- m68k-ccur)
- os=-rtu
- ;;
- m88k-omron*)
- os=-luna
- ;;
- *-next )
- os=-nextstep
- ;;
- *-sequent)
- os=-ptx
- ;;
- *-crds)
- os=-unos
- ;;
- *-ns)
- os=-genix
- ;;
- i370-*)
- os=-mvs
- ;;
- *-next)
- os=-nextstep3
- ;;
- *-gould)
- os=-sysv
- ;;
- *-highlevel)
- os=-bsd
- ;;
- *-encore)
- os=-bsd
- ;;
- *-sgi)
- os=-irix
- ;;
- *-siemens)
- os=-sysv4
- ;;
- *-masscomp)
- os=-rtu
- ;;
- f301-fujitsu)
- os=-uxpv
- ;;
- *-be)
- os=-beos
- ;;
- *)
- os=-none
- ;;
-esac
-fi
-
-# Here we handle the case where we know the os, and the CPU type, but not the
-# manufacturer. We pick the logical manufacturer.
-vendor=unknown
-case $basic_machine in
- *-unknown)
- case $os in
- -riscix*)
- vendor=acorn
- ;;
- -sunos*)
- vendor=sun
- ;;
- -aix*)
- vendor=ibm
- ;;
- -hpux*)
- vendor=hp
- ;;
- -hiux*)
- vendor=hitachi
- ;;
- -unos*)
- vendor=crds
- ;;
- -dgux*)
- vendor=dg
- ;;
- -luna*)
- vendor=omron
- ;;
- -genix*)
- vendor=ns
- ;;
- -mvs*)
- vendor=ibm
- ;;
- -ptx*)
- vendor=sequent
- ;;
- -vxsim* | -vxworks*)
- vendor=wrs
- ;;
- -aux*)
- vendor=apple
- ;;
- -beos*)
- vendor=be
- ;;
- esac
- basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
- ;;
-esac
-
-echo $basic_machine$os
diff --git a/gcc/config/1750a/1750a.c b/gcc/config/1750a/1750a.c
index 134f69de740..ff9ae37e880 100644
--- a/gcc/config/1750a/1750a.c
+++ b/gcc/config/1750a/1750a.c
@@ -1,5 +1,5 @@
/* Subroutines for insn-output.c for MIL-STD-1750.
- Copyright (C) 1994, 1995, 1996, 1997 Free Software Foundation, Inc.
+ Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
Contributed by O.M.Kellogg, DASA (kellogg@space.otn.dasa.de)
This file is part of GNU CC.
@@ -222,7 +222,7 @@ memop_valid (op)
rtx op;
{
static int recurred = 0;
- int valid;
+ int valid_operand;
if (GET_MODE (op) != Pmode && GET_MODE (op) != VOIDmode
&& GET_MODE (op) != QImode)
@@ -238,11 +238,11 @@ memop_valid (op)
return 0;
case PLUS:
recurred = 1;
- valid = memop_valid (XEXP (op, 0));
- if (valid)
- valid = memop_valid (XEXP (op, 1));
+ valid_operand = memop_valid (XEXP (op, 0));
+ if (valid_operand)
+ valid_operand = memop_valid (XEXP (op, 1));
recurred = 0;
- return valid;
+ return valid_operand;
case REG:
if (REGNO (op) > 0)
return 1;
diff --git a/gcc/config/1750a/1750a.h b/gcc/config/1750a/1750a.h
index 0a3aa8e3c98..185dd1e7562 100644
--- a/gcc/config/1750a/1750a.h
+++ b/gcc/config/1750a/1750a.h
@@ -1,5 +1,5 @@
/* Definitions of target machine for GNU compiler.
- Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1994, 95-98, 1999 Free Software Foundation, Inc.
Contributed by O.M.Kellogg, DASA (oliver.kellogg@space.otn.dasa.de)
This file is part of GNU CC.
@@ -35,8 +35,8 @@ Boston, MA 02111-1307, USA. */
/* Run-time compilation parameters selecting different hardware subsets. */
#define TARGET_SWITCHES \
- { {"vaxc-alignment", 2}, \
- { "", TARGET_DEFAULT}}
+ { {"vaxc-alignment", 2, "Use VAX-C alignment"}, \
+ { "", TARGET_DEFAULT, NULL}}
/* Default target_flags if no switches specified. */
@@ -66,7 +66,7 @@ extern struct jumplabel_array jmplbl[];
extern int datalbl_ndx, jmplbl_ndx, label_pending, program_counter;
extern enum section current_section;
extern char *sectname[4];
-extern char *xstrdup(), *float_label();
+extern char *float_label();
extern struct rtx_def *function_arg ();
extern char *movcnt_regno_adjust ();
extern char *mod_regno_adjust ();
@@ -707,10 +707,10 @@ enum reg_class { NO_REGS, R2, R0_1, INDEX_REGS, BASE_REGS, ALL_REGS, LIM_REG_CLA
/* 1750 doesn't have a lot of auto-incr./decr. - just for the stack ptr. */
-/* #define HAVE_POST_INCREMENT just for R15 (stack pointer) */
-/* #define HAVE_POST_DECREMENT */
-/* #define HAVE_PRE_DECREMENT just for R15 (stack pointer) */
-/* #define HAVE_PRE_INCREMENT */
+/* #define HAVE_POST_INCREMENT 0 just for R15 (stack pointer) */
+/* #define HAVE_POST_DECREMENT 0 */
+/* #define HAVE_PRE_DECREMENT 0 just for R15 (stack pointer) */
+/* #define HAVE_PRE_INCREMENT 0 */
/* Macros to check register numbers against specific register classes. */
@@ -732,7 +732,7 @@ enum reg_class { NO_REGS, R2, R0_1, INDEX_REGS, BASE_REGS, ALL_REGS, LIM_REG_CLA
reg_renumber[REGNO] >= 12 && reg_renumber[REGNO] <= 15)
/* Now macros that check whether X is a register and also,
- strictly, whether it is in a specified class.
+ strictly, whether it is in a specified class. */
/* 1 if X is an address register */
diff --git a/gcc/config/a29k/a29k.c b/gcc/config/a29k/a29k.c
index 4b28bba00bd..d4483a43b2d 100644
--- a/gcc/config/a29k/a29k.c
+++ b/gcc/config/a29k/a29k.c
@@ -1,5 +1,6 @@
/* Subroutines used for code generation on AMD Am29000.
- Copyright (C) 1987, 88, 90-94, 1995, 1997 Free Software Foundation, Inc.
+ Copyright (C) 1987, 88, 90-94, 1995, 1997, 1999 Free Software
+ Foundation, Inc.
Contributed by Richard Kenner (kenner@nyu.edu)
This file is part of GNU CC.
@@ -480,9 +481,9 @@ a29k_get_reloaded_address (op)
found in part of X. */
static void
-a29k_set_memflags_1 (x, in_struct_p, volatile_p, unchanging_p)
+a29k_set_memflags_1 (x, in_struct_p, scalar_p, volatile_p, unchanging_p)
rtx x;
- int in_struct_p, volatile_p, unchanging_p;
+ int in_struct_p, scalar_p, volatile_p, unchanging_p;
{
int i;
@@ -508,6 +509,7 @@ a29k_set_memflags_1 (x, in_struct_p, volatile_p, unchanging_p)
case MEM:
MEM_IN_STRUCT_P (x) = in_struct_p;
+ MEM_SCALAR_P (x) = scalar_p;
MEM_VOLATILE_P (x) = volatile_p;
RTX_UNCHANGING_P (x) = unchanging_p;
break;
@@ -528,6 +530,7 @@ a29k_set_memflags (insn, ref)
/* Note that it is always safe to get these flags, though they won't
be what we think if REF is not a MEM. */
int in_struct_p = MEM_IN_STRUCT_P (ref);
+ int scalar_p = MEM_SCALAR_P (ref);
int volatile_p = MEM_VOLATILE_P (ref);
int unchanging_p = RTX_UNCHANGING_P (ref);
@@ -535,7 +538,7 @@ a29k_set_memflags (insn, ref)
|| (! in_struct_p && ! volatile_p && ! unchanging_p))
return;
- a29k_set_memflags_1 (insn, in_struct_p, volatile_p, unchanging_p);
+ a29k_set_memflags_1 (insn, in_struct_p, scalar_p, volatile_p, unchanging_p);
}
/* Return 1 if OP is a comparison operator that we have in floating-point. */
diff --git a/gcc/config/a29k/a29k.h b/gcc/config/a29k/a29k.h
index c3e61747b42..a7f5d8d3ff7 100644
--- a/gcc/config/a29k/a29k.h
+++ b/gcc/config/a29k/a29k.h
@@ -97,26 +97,26 @@ extern int target_flags;
#define TARGET_MULTM ((target_flags & 1024) == 0)
#define TARGET_SWITCHES \
- { {"dw", 1}, \
- {"ndw", -1}, \
- {"bw", 2}, \
- {"nbw", - (1|2)}, \
- {"small", 4}, \
- {"normal", - (4|8)}, \
- {"large", 8}, \
- {"29050", 16+128}, \
- {"29000", -16}, \
- {"kernel-registers", 32}, \
- {"user-registers", -32}, \
- {"stack-check", 64}, \
- {"no-stack-check", - 74}, \
- {"storem-bug", -128}, \
- {"no-storem-bug", 128}, \
- {"reuse-arg-regs", -256}, \
- {"no-reuse-arg-regs", 256}, \
- {"soft-float", 512}, \
- {"no-multm", 1024}, \
- {"", TARGET_DEFAULT}}
+ { {"dw", 1, "Generate code assuming DW bit is set"}, \
+ {"ndw", -1, "Generate code assuming DW bit is not set"}, \
+ {"bw", 2, "Generate code using byte writes"}, \
+ {"nbw", - (1|2), "Do not generate byte writes"}, \
+ {"small", 4, "Use small memory model"}, \
+ {"normal", - (4|8), "Use normal memory model"}, \
+ {"large", 8, "Use large memory model"}, \
+ {"29050", 16+128, "Generate 29050 code"}, \
+ {"29000", -16, "Generate 29000 code"}, \
+ {"kernel-registers", 32, "Use kernel global registers"}, \
+ {"user-registers", -32, "Use user global registers"}, \
+ {"stack-check", 64, "Emit stack checking code"}, \
+ {"no-stack-check", - 74, "Do not emit stack checking code"}, \
+ {"storem-bug", -128, "Work around storem hardware bug"}, \
+ {"no-storem-bug", 128, "Do not work around storem hardware bug"}, \
+ {"reuse-arg-regs", -256, "Store locals in argument registers"}, \
+ {"no-reuse-arg-regs", 256, "Do not store locals in arg registers"}, \
+ {"soft-float", 512, "Use software floating point"}, \
+ {"no-multm", 1024, "Do not generate multm instructions"}, \
+ {"", TARGET_DEFAULT, NULL}}
#define TARGET_DEFAULT 3
@@ -1067,11 +1067,11 @@ extern char *a29k_function_name;
/* Addressing modes, and classification of registers for them. */
-/* #define HAVE_POST_INCREMENT */
-/* #define HAVE_POST_DECREMENT */
+/* #define HAVE_POST_INCREMENT 0 */
+/* #define HAVE_POST_DECREMENT 0 */
-/* #define HAVE_PRE_DECREMENT */
-/* #define HAVE_PRE_INCREMENT */
+/* #define HAVE_PRE_DECREMENT 0 */
+/* #define HAVE_PRE_INCREMENT 0 */
/* Macros to check register numbers against specific register classes. */
diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c
index 15fdf15de25..aa88078adf8 100644
--- a/gcc/config/alpha/alpha.c
+++ b/gcc/config/alpha/alpha.c
@@ -1,5 +1,6 @@
/* Subroutines used for code generation on the DEC Alpha.
- Copyright (C) 1992, 93, 94, 95, 96, 97, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1992, 93, 94, 95, 96, 97, 1998, 1999 Free Software
+ Foundation, Inc.
Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
This file is part of GNU CC.
@@ -48,7 +49,7 @@ extern int rtx_equal_function_value_matters;
/* Specify which cpu to schedule for. */
enum processor_type alpha_cpu;
-static char* const alpha_cpu_name[] =
+static const char * const alpha_cpu_name[] =
{
"ev4", "ev5", "ev6"
};
@@ -67,11 +68,11 @@ enum alpha_fp_trap_mode alpha_fptm;
/* Strings decoded into the above options. */
-char *alpha_cpu_string; /* -mcpu= */
-char *alpha_tp_string; /* -mtrap-precision=[p|s|i] */
-char *alpha_fprm_string; /* -mfp-rounding-mode=[n|m|c|d] */
-char *alpha_fptm_string; /* -mfp-trap-mode=[n|u|su|sui] */
-char *alpha_mlat_string; /* -mmemory-latency= */
+const char *alpha_cpu_string; /* -mcpu= */
+const char *alpha_tp_string; /* -mtrap-precision=[p|s|i] */
+const char *alpha_fprm_string; /* -mfp-rounding-mode=[n|m|c|d] */
+const char *alpha_fptm_string; /* -mfp-trap-mode=[n|u|su|sui] */
+const char *alpha_mlat_string; /* -mmemory-latency= */
/* Save information from a "cmpxx" operation until the branch or scc is
emitted. */
@@ -256,11 +257,11 @@ override_options ()
if (!alpha_mlat_string)
alpha_mlat_string = "L1";
- if (isdigit (alpha_mlat_string[0])
+ if (ISDIGIT ((unsigned char)alpha_mlat_string[0])
&& (lat = strtol (alpha_mlat_string, &end, 10), *end == '\0'))
;
else if ((alpha_mlat_string[0] == 'L' || alpha_mlat_string[0] == 'l')
- && isdigit (alpha_mlat_string[1])
+ && ISDIGIT ((unsigned char)alpha_mlat_string[1])
&& alpha_mlat_string[2] == '\0')
{
static int const cache_latency[][4] =
@@ -340,7 +341,6 @@ reg_or_6bit_operand (op, mode)
{
return ((GET_CODE (op) == CONST_INT
&& (unsigned HOST_WIDE_INT) INTVAL (op) < 64)
- || GET_CODE (op) == CONSTANT_P_RTX
|| register_operand (op, mode));
}
@@ -354,7 +354,6 @@ reg_or_8bit_operand (op, mode)
{
return ((GET_CODE (op) == CONST_INT
&& (unsigned HOST_WIDE_INT) INTVAL (op) < 0x100)
- || GET_CODE (op) == CONSTANT_P_RTX
|| register_operand (op, mode));
}
@@ -366,8 +365,7 @@ cint8_operand (op, mode)
enum machine_mode mode ATTRIBUTE_UNUSED;
{
return ((GET_CODE (op) == CONST_INT
- && (unsigned HOST_WIDE_INT) INTVAL (op) < 0x100)
- || GET_CODE (op) == CONSTANT_P_RTX);
+ && (unsigned HOST_WIDE_INT) INTVAL (op) < 0x100));
}
/* Return 1 if the operand is a valid second operand to an add insn. */
@@ -378,11 +376,9 @@ add_operand (op, mode)
enum machine_mode mode;
{
if (GET_CODE (op) == CONST_INT)
+ /* Constraints I, J, O and P are covered by K. */
return (CONST_OK_FOR_LETTER_P (INTVAL (op), 'K')
- || CONST_OK_FOR_LETTER_P (INTVAL (op), 'L')
- || CONST_OK_FOR_LETTER_P (INTVAL (op), 'O'));
- else if (GET_CODE (op) == CONSTANT_P_RTX)
- return 1;
+ || CONST_OK_FOR_LETTER_P (INTVAL (op), 'L'));
return register_operand (op, mode);
}
@@ -396,10 +392,8 @@ sext_add_operand (op, mode)
enum machine_mode mode;
{
if (GET_CODE (op) == CONST_INT)
- return ((unsigned HOST_WIDE_INT) INTVAL (op) < 255
- || (unsigned HOST_WIDE_INT) (- INTVAL (op)) < 255);
- else if (GET_CODE (op) == CONSTANT_P_RTX)
- return 1;
+ return (CONST_OK_FOR_LETTER_P (INTVAL (op), 'I')
+ || CONST_OK_FOR_LETTER_P (INTVAL (op), 'O'));
return register_operand (op, mode);
}
@@ -430,8 +424,6 @@ and_operand (op, mode)
return ((unsigned HOST_WIDE_INT) INTVAL (op) < 0x100
|| (unsigned HOST_WIDE_INT) ~ INTVAL (op) < 0x100
|| zap_mask (INTVAL (op)));
- else if (GET_CODE (op) == CONSTANT_P_RTX)
- return 1;
return register_operand (op, mode);
}
@@ -446,8 +438,6 @@ or_operand (op, mode)
if (GET_CODE (op) == CONST_INT)
return ((unsigned HOST_WIDE_INT) INTVAL (op) < 0x100
|| (unsigned HOST_WIDE_INT) ~ INTVAL (op) < 0x100);
- else if (GET_CODE (op) == CONSTANT_P_RTX)
- return 1;
return register_operand (op, mode);
}
@@ -547,7 +537,6 @@ reg_or_cint_operand (op, mode)
enum machine_mode mode;
{
return (GET_CODE (op) == CONST_INT
- || GET_CODE (op) == CONSTANT_P_RTX
|| register_operand (op, mode));
}
@@ -565,7 +554,7 @@ some_operand (op, mode)
switch (GET_CODE (op))
{
case REG: case MEM: case CONST_DOUBLE: case CONST_INT: case LABEL_REF:
- case SYMBOL_REF: case CONST: case CONSTANT_P_RTX:
+ case SYMBOL_REF: case CONST:
return 1;
case SUBREG:
@@ -614,9 +603,11 @@ input_operand (op, mode)
return GET_MODE_CLASS (mode) == MODE_FLOAT && op == CONST0_RTX (mode);
case CONST_INT:
- case CONSTANT_P_RTX:
return mode == QImode || mode == HImode || add_operand (op, mode);
+ case CONSTANT_P_RTX:
+ return 1;
+
default:
break;
}
@@ -825,6 +816,54 @@ any_memory_operand (op, mode)
&& REGNO (SUBREG_REG (op)) >= FIRST_PSEUDO_REGISTER));
}
+/* Returns 1 if OP is not an eliminable register.
+
+ This exists to cure a pathological abort in the s8addq (et al) patterns,
+
+ long foo () { long t; bar(); return (long) &t * 26107; }
+
+ which run afoul of a hack in reload to cure a (presumably) similar
+ problem with lea-type instructions on other targets. But there is
+ one of us and many of them, so work around the problem by selectively
+ preventing combine from making the optimization. */
+
+int
+reg_not_elim_operand (op, mode)
+ register rtx op;
+ enum machine_mode mode;
+{
+ rtx inner = op;
+ if (GET_CODE (op) == SUBREG)
+ inner = SUBREG_REG (op);
+ if (inner == frame_pointer_rtx || inner == arg_pointer_rtx)
+ return 0;
+
+ return register_operand (op, mode);
+}
+
+/* Return 1 is OP is a memory location that is not an reference (using
+ an AND) to an unaligned location. Take into account what reload
+ will do. */
+
+int
+normal_memory_operand (op, mode)
+ register rtx op;
+ enum machine_mode mode ATTRIBUTE_UNUSED;
+{
+ if (reload_in_progress && GET_CODE (op) == REG
+ && REGNO (op) >= FIRST_PSEUDO_REGISTER)
+ {
+ op = reg_equiv_mem[REGNO (op)];
+
+ /* This may not have been assigned an equivalent address if it will
+ be eliminated. In that case, it doesn't matter what we do. */
+ if (op == 0)
+ return 1;
+ }
+
+ return GET_CODE (op) == MEM && GET_CODE (XEXP (op, 0)) != AND;
+}
+
/* Return 1 if this function can directly return via $26. */
int
@@ -870,8 +909,7 @@ get_aligned_mem (ref, paligned_mem, pbitnum)
offset += INTVAL (XEXP (base, 1)), base = XEXP (base, 0);
*paligned_mem = gen_rtx_MEM (SImode, plus_constant (base, offset & ~3));
- MEM_IN_STRUCT_P (*paligned_mem) = MEM_IN_STRUCT_P (ref);
- MEM_VOLATILE_P (*paligned_mem) = MEM_VOLATILE_P (ref);
+ MEM_COPY_ATTRIBUTES (*paligned_mem, ref);
RTX_UNCHANGING_P (*paligned_mem) = RTX_UNCHANGING_P (ref);
/* Sadly, we cannot use alias sets here because we may overlap other
@@ -1145,7 +1183,7 @@ alpha_emit_set_const_1 (target, mode, c, n)
for (; bits > 0; bits--)
if ((temp = (alpha_emit_set_const
(subtarget, mode,
- (unsigned HOST_WIDE_INT) c >> bits, i))) != 0
+ (unsigned HOST_WIDE_INT) (c >> bits), i))) != 0
|| ((temp = (alpha_emit_set_const
(subtarget, mode,
((unsigned HOST_WIDE_INT) c) >> bits, i)))
@@ -1530,6 +1568,8 @@ alpha_expand_unaligned_load (tgt, mem, size, ofs, sign)
emit_insn (gen_extqh (exth, memh, addr));
mode = DImode;
break;
+ default:
+ abort();
}
addr = expand_binop (mode, ior_optab, gen_lowpart (mode, extl),
@@ -1803,7 +1843,8 @@ alpha_expand_block_move (operands)
{
rtx bytes_rtx = operands[2];
rtx align_rtx = operands[3];
- HOST_WIDE_INT bytes = INTVAL (bytes_rtx);
+ HOST_WIDE_INT orig_bytes = INTVAL (bytes_rtx);
+ HOST_WIDE_INT bytes = orig_bytes;
HOST_WIDE_INT src_align = INTVAL (align_rtx);
HOST_WIDE_INT dst_align = src_align;
rtx orig_src = operands[1];
@@ -1876,7 +1917,7 @@ alpha_expand_block_move (operands)
enum machine_mode mode;
tmp = XEXP (XEXP (orig_src, 0), 0);
- mode = mode_for_size (bytes, MODE_INT, 1);
+ mode = mode_for_size (bytes * BITS_PER_UNIT, MODE_INT, 1);
if (mode != BLKmode
&& GET_MODE_SIZE (GET_MODE (tmp)) <= bytes)
{
@@ -2006,7 +2047,7 @@ alpha_expand_block_move (operands)
enum machine_mode mode;
tmp = XEXP (XEXP (orig_dst, 0), 0);
- mode = mode_for_size (bytes, MODE_INT, 1);
+ mode = mode_for_size (orig_bytes * BITS_PER_UNIT, MODE_INT, 1);
if (GET_MODE (tmp) == mode && nregs == 1)
{
emit_move_insn (tmp, data_regs[0]);
@@ -2016,9 +2057,12 @@ alpha_expand_block_move (operands)
/* ??? If nregs > 1, consider reconstructing the word in regs. */
/* ??? Optimize mode < dst_mode with strict_low_part. */
- /* No appropriate mode; fall back on memory. */
+
+ /* No appropriate mode; fall back on memory. We can speed things
+ up by recognizing extra alignment information. */
orig_dst = change_address (orig_dst, GET_MODE (orig_dst),
copy_addr_to_reg (XEXP (orig_dst, 0)));
+ dst_align = GET_MODE_SIZE (GET_MODE (tmp));
}
/* Write out the data in whatever chunks reading the source allowed. */
@@ -2954,7 +2998,7 @@ alpha_builtin_saveregs (arglist)
dest = change_address (block, ptr_mode, XEXP (block, 0));
emit_move_insn (dest, addr);
- if (flag_check_memory_usage)
+ if (current_function_check_memory_usage)
emit_library_call (chkr_set_right_libfunc, 1, VOIDmode, 3,
dest, ptr_mode,
GEN_INT (GET_MODE_SIZE (ptr_mode)),
@@ -2968,7 +3012,7 @@ alpha_builtin_saveregs (arglist)
POINTER_SIZE/BITS_PER_UNIT));
emit_move_insn (dest, argsize);
- if (flag_check_memory_usage)
+ if (current_function_check_memory_usage)
emit_library_call (chkr_set_right_libfunc, 1, VOIDmode, 3,
dest, ptr_mode,
GEN_INT (GET_MODE_SIZE
@@ -3898,7 +3942,7 @@ static int num_source_filenames = 0;
/* Name of the file containing the current function. */
-static char *current_function_file = "";
+static const char *current_function_file = "";
/* Offsets to alpha virtual arg/local debugging pointers. */
diff --git a/gcc/config/alpha/alpha.h b/gcc/config/alpha/alpha.h
index 1a435fe7800..2a15b9f200f 100644
--- a/gcc/config/alpha/alpha.h
+++ b/gcc/config/alpha/alpha.h
@@ -1,5 +1,5 @@
/* Definitions of target machine for GNU compiler, for DEC Alpha.
- Copyright (C) 1992, 93, 94, 95, 96, 97, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1992, 93-98, 1999 Free Software Foundation, Inc.
Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
This file is part of GNU CC.
@@ -185,26 +185,30 @@ extern enum alpha_fp_trap_mode alpha_fptm;
where VALUE is the bits to set or minus the bits to clear.
An empty string NAME is used to identify the default VALUE. */
-#define TARGET_SWITCHES \
- { {"no-soft-float", MASK_FP}, \
- {"soft-float", - MASK_FP}, \
- {"fp-regs", MASK_FPREGS}, \
- {"no-fp-regs", - (MASK_FP|MASK_FPREGS)}, \
- {"alpha-as", -MASK_GAS}, \
- {"gas", MASK_GAS}, \
- {"ieee-conformant", MASK_IEEE_CONFORMANT}, \
- {"ieee", MASK_IEEE|MASK_IEEE_CONFORMANT}, \
- {"ieee-with-inexact", MASK_IEEE_WITH_INEXACT|MASK_IEEE_CONFORMANT}, \
- {"build-constants", MASK_BUILD_CONSTANTS}, \
- {"float-vax", MASK_FLOAT_VAX}, \
- {"float-ieee", -MASK_FLOAT_VAX}, \
- {"bwx", MASK_BWX}, \
- {"no-bwx", -MASK_BWX}, \
- {"cix", MASK_CIX}, \
- {"no-cix", -MASK_CIX}, \
- {"max", MASK_MAX}, \
- {"no-max", -MASK_MAX}, \
- {"", TARGET_DEFAULT | TARGET_CPU_DEFAULT} }
+#define TARGET_SWITCHES \
+ { {"no-soft-float", MASK_FP, "Use hardware fp"}, \
+ {"soft-float", - MASK_FP, "Do not use hardware fp"}, \
+ {"fp-regs", MASK_FPREGS, "Use fp registers"}, \
+ {"no-fp-regs", - (MASK_FP|MASK_FPREGS), "Do not use fp registers"}, \
+ {"alpha-as", -MASK_GAS, "Do not assume GAS"}, \
+ {"gas", MASK_GAS, "Assume GAS"}, \
+ {"ieee-conformant", MASK_IEEE_CONFORMANT, \
+ "Request IEEE-conformant math library routines (OSF/1)"}, \
+ {"ieee", MASK_IEEE|MASK_IEEE_CONFORMANT, \
+ "Emit IEEE-conformant code, without inexact exceptions"}, \
+ {"ieee-with-inexact", MASK_IEEE_WITH_INEXACT|MASK_IEEE_CONFORMANT, \
+ "Emit IEEE-conformant code, with inexact exceptions"}, \
+ {"build-constants", MASK_BUILD_CONSTANTS, \
+ "Do not emit complex integer constants to read-only memory"}, \
+ {"float-vax", MASK_FLOAT_VAX, "Use VAX fp"}, \
+ {"float-ieee", -MASK_FLOAT_VAX, "Do not use VAX fp"}, \
+ {"bwx", MASK_BWX, "Emit code for the byte/word ISA extension"}, \
+ {"no-bwx", -MASK_BWX, ""}, \
+ {"cix", MASK_CIX, "Emit code for the counting ISA extension"}, \
+ {"no-cix", -MASK_CIX, ""}, \
+ {"max", MASK_MAX, "Emit code for the motion video ISA extension"}, \
+ {"no-max", -MASK_MAX, ""}, \
+ {"", TARGET_DEFAULT | TARGET_CPU_DEFAULT, ""} }
#define TARGET_DEFAULT MASK_FP|MASK_FPREGS
@@ -229,19 +233,24 @@ extern enum alpha_fp_trap_mode alpha_fptm;
extern char *m88k_short_data;
#define TARGET_OPTIONS { { "short-data-", &m88k_short_data } } */
-extern char *alpha_cpu_string; /* For -mcpu= */
-extern char *alpha_fprm_string; /* For -mfp-rounding-mode=[n|m|c|d] */
-extern char *alpha_fptm_string; /* For -mfp-trap-mode=[n|u|su|sui] */
-extern char *alpha_tp_string; /* For -mtrap-precision=[p|f|i] */
-extern char *alpha_mlat_string; /* For -mmemory-latency= */
-
-#define TARGET_OPTIONS \
-{ \
- {"cpu=", &alpha_cpu_string}, \
- {"fp-rounding-mode=", &alpha_fprm_string}, \
- {"fp-trap-mode=", &alpha_fptm_string}, \
- {"trap-precision=", &alpha_tp_string}, \
- {"memory-latency=", &alpha_mlat_string}, \
+extern const char *alpha_cpu_string; /* For -mcpu= */
+extern const char *alpha_fprm_string; /* For -mfp-rounding-mode=[n|m|c|d] */
+extern const char *alpha_fptm_string; /* For -mfp-trap-mode=[n|u|su|sui] */
+extern const char *alpha_tp_string; /* For -mtrap-precision=[p|f|i] */
+extern const char *alpha_mlat_string; /* For -mmemory-latency= */
+
+#define TARGET_OPTIONS \
+{ \
+ {"cpu=", &alpha_cpu_string, \
+ "Generate code for a given CPU"}, \
+ {"fp-rounding-mode=", &alpha_fprm_string, \
+ "Control the generated fp rounding mode"}, \
+ {"fp-trap-mode=", &alpha_fptm_string, \
+ "Control the IEEE trap mode"}, \
+ {"trap-precision=", &alpha_tp_string, \
+ "Control the precision given to fp exceptions"}, \
+ {"memory-latency=", &alpha_mlat_string, \
+ "Tune expected memory latency"}, \
}
/* Attempt to describe CPU characteristics to the preprocessor. */
@@ -611,18 +620,23 @@ extern void override_options ();
/* Value is 1 if hard register REGNO can hold a value of machine-mode MODE.
On Alpha, the integer registers can hold any mode. The floating-point
registers can hold 32-bit and 64-bit integers as well, but not 16-bit
- or 8-bit values. If we only allowed the larger integers into FP registers,
- we'd have to say that QImode and SImode aren't tiable, which is a
- pain. So say all registers can hold everything and see how that works. */
+ or 8-bit values. */
-#define HARD_REGNO_MODE_OK(REGNO, MODE) 1
+#define HARD_REGNO_MODE_OK(REGNO, MODE) \
+ ((REGNO) >= 32 && (REGNO) <= 62 \
+ ? GET_MODE_UNIT_SIZE (MODE) == 8 || GET_MODE_UNIT_SIZE (MODE) == 4 \
+ : 1)
-/* Value is 1 if it is a good idea to tie two pseudo registers
- when one has mode MODE1 and one has mode MODE2.
- If HARD_REGNO_MODE_OK could produce different values for MODE1 and MODE2,
- for any hard reg, then this must be 0 for correct output. */
+/* A C expression that is nonzero if a value of mode
+ MODE1 is accessible in mode MODE2 without copying.
-#define MODES_TIEABLE_P(MODE1, MODE2) 1
+ This asymmetric test is true when MODE1 could be put
+ in an FP register but MODE2 could not. */
+
+#define MODES_TIEABLE_P(MODE1, MODE2) \
+ (HARD_REGNO_MODE_OK (32, (MODE1)) \
+ ? HARD_REGNO_MODE_OK (32, (MODE2)) \
+ : 1)
/* Specify the registers used for certain standard purposes.
The values of these macros are register numbers. */
@@ -769,11 +783,12 @@ enum reg_class { NO_REGS, GENERAL_REGS, FLOAT_REGS, ALL_REGS,
'S' is a 6-bit constant (valid for a shift insn). */
#define EXTRA_CONSTRAINT(OP, C) \
- ((C) == 'Q' ? GET_CODE (OP) == MEM && GET_CODE (XEXP (OP, 0)) != AND \
+ ((C) == 'Q' ? normal_memory_operand (OP, VOIDmode) \
: (C) == 'R' ? current_file_function_operand (OP, Pmode) \
: (C) == 'S' ? (GET_CODE (OP) == CONST_INT \
&& (unsigned HOST_WIDE_INT) INTVAL (OP) < 64) \
: 0)
+extern int normal_memory_operand ();
/* Given an rtx X being reloaded into a reg required to be
in class CLASS, return the class of reg to actually use.
@@ -1312,11 +1327,11 @@ extern void alpha_init_expanders ();
/* Addressing modes, and classification of registers for them. */
-/* #define HAVE_POST_INCREMENT */
-/* #define HAVE_POST_DECREMENT */
+/* #define HAVE_POST_INCREMENT 0 */
+/* #define HAVE_POST_DECREMENT 0 */
-/* #define HAVE_PRE_DECREMENT */
-/* #define HAVE_PRE_INCREMENT */
+/* #define HAVE_PRE_DECREMENT 0 */
+/* #define HAVE_PRE_INCREMENT 0 */
/* Macros to check register numbers against specific register classes. */
@@ -1504,6 +1519,18 @@ extern void alpha_init_expanders ();
#define LEGITIMIZE_RELOAD_ADDRESS(X,MODE,OPNUM,TYPE,IND_LEVELS,WIN) \
do { \
+ /* We must recognize output that we have already generated ourselves. */ \
+ if (GET_CODE (X) == PLUS \
+ && GET_CODE (XEXP (X, 0)) == PLUS \
+ && GET_CODE (XEXP (XEXP (X, 0), 0)) == REG \
+ && GET_CODE (XEXP (XEXP (X, 0), 1)) == CONST_INT \
+ && GET_CODE (XEXP (X, 1)) == CONST_INT) \
+ { \
+ push_reload (XEXP (X, 0), NULL_RTX, &XEXP (X, 0), NULL_PTR, \
+ BASE_REG_CLASS, GET_MODE (X), VOIDmode, 0, 0, \
+ OPNUM, TYPE); \
+ goto WIN; \
+ } \
if (GET_CODE (X) == PLUS \
&& GET_CODE (XEXP (X, 0)) == REG \
&& REGNO (XEXP (X, 0)) < FIRST_PSEUDO_REGISTER \
@@ -1968,7 +1995,7 @@ literal_section () \
This is suitable for output with `assemble_name'. */
#define ASM_GENERATE_INTERNAL_LABEL(LABEL,PREFIX,NUM) \
- sprintf (LABEL, "*$%s%d", PREFIX, NUM)
+ sprintf ((LABEL), "*$%s%ld", (PREFIX), (long)(NUM))
/* Check a floating-point value for validity for a particular machine mode. */
@@ -2261,15 +2288,15 @@ do { \
#define PREDICATE_CODES \
{"reg_or_0_operand", {SUBREG, REG, CONST_INT}}, \
- {"reg_or_6bit_operand", {SUBREG, REG, CONST_INT, CONSTANT_P_RTX}}, \
- {"reg_or_8bit_operand", {SUBREG, REG, CONST_INT, CONSTANT_P_RTX}}, \
- {"cint8_operand", {CONST_INT, CONSTANT_P_RTX}}, \
- {"reg_or_cint_operand", {SUBREG, REG, CONST_INT, CONSTANT_P_RTX}}, \
- {"add_operand", {SUBREG, REG, CONST_INT, CONSTANT_P_RTX}}, \
- {"sext_add_operand", {SUBREG, REG, CONST_INT, CONSTANT_P_RTX}}, \
+ {"reg_or_6bit_operand", {SUBREG, REG, CONST_INT}}, \
+ {"reg_or_8bit_operand", {SUBREG, REG, CONST_INT}}, \
+ {"cint8_operand", {CONST_INT}}, \
+ {"reg_or_cint_operand", {SUBREG, REG, CONST_INT}}, \
+ {"add_operand", {SUBREG, REG, CONST_INT}}, \
+ {"sext_add_operand", {SUBREG, REG, CONST_INT}}, \
{"const48_operand", {CONST_INT}}, \
- {"and_operand", {SUBREG, REG, CONST_INT, CONSTANT_P_RTX}}, \
- {"or_operand", {SUBREG, REG, CONST_INT, CONSTANT_P_RTX}}, \
+ {"and_operand", {SUBREG, REG, CONST_INT}}, \
+ {"or_operand", {SUBREG, REG, CONST_INT}}, \
{"mode_mask_operand", {CONST_INT}}, \
{"mul8_operand", {CONST_INT}}, \
{"mode_width_operand", {CONST_INT}}, \
@@ -2282,14 +2309,15 @@ do { \
{"current_file_function_operand", {SYMBOL_REF}}, \
{"call_operand", {REG, SYMBOL_REF}}, \
{"input_operand", {SUBREG, REG, MEM, CONST_INT, CONST_DOUBLE, \
- SYMBOL_REF, CONST, LABEL_REF, CONSTANT_P_RTX}}, \
+ SYMBOL_REF, CONST, LABEL_REF}}, \
{"some_operand", {SUBREG, REG, MEM, CONST_INT, CONST_DOUBLE, \
- SYMBOL_REF, CONST, LABEL_REF, CONSTANT_P_RTX}}, \
+ SYMBOL_REF, CONST, LABEL_REF}}, \
{"aligned_memory_operand", {MEM}}, \
{"unaligned_memory_operand", {MEM}}, \
{"reg_or_unaligned_mem_operand", {SUBREG, REG, MEM}}, \
{"any_memory_operand", {MEM}}, \
- {"hard_fp_register_operand", {SUBREG, REG}},
+ {"hard_fp_register_operand", {SUBREG, REG}}, \
+ {"reg_not_elim_operand", {SUBREG, REG}},
/* Tell collect that the object format is ECOFF. */
#define OBJECT_FORMAT_COFF
@@ -2480,6 +2508,7 @@ extern int divmod_operator ();
extern int call_operand ();
extern int reg_or_cint_operand ();
extern int hard_fp_register_operand ();
+extern int reg_not_elim_operand ();
extern void alpha_set_memflags ();
extern int aligned_memory_operand ();
extern void get_aligned_mem ();
diff --git a/gcc/config/alpha/alpha.md b/gcc/config/alpha/alpha.md
index dd69998e1ad..3fb2435f95e 100644
--- a/gcc/config/alpha/alpha.md
+++ b/gcc/config/alpha/alpha.md
@@ -1,5 +1,5 @@
;; Machine description for DEC Alpha for GNU C compiler
-;; Copyright (C) 1992, 93, 94, 95, 96, 97, 1998 Free Software Foundation, Inc.
+;; Copyright (C) 1992, 93-98, 1999 Free Software Foundation, Inc.
;; Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
;; This file is part of GNU CC.
@@ -155,13 +155,18 @@
; Memory takes at least 2 clocks. Return one from here and fix up with
; user-defined latencies in adjust_cost.
-; ??? How to: "An instruction of class LD cannot be issued in the _second_
-; cycle after an instruction of class ST is issued."
(define_function_unit "ev5_ebox" 2 0
(and (eq_attr "cpu" "ev5")
(eq_attr "type" "ild,fld,ldsym"))
1 1)
+; Loads can dual issue with one another, but loads and stores do not mix.
+(define_function_unit "ev5_e0" 1 0
+ (and (eq_attr "cpu" "ev5")
+ (eq_attr "type" "ild,fld,ldsym"))
+ 1 1
+ [(eq_attr "type" "ist,fst")])
+
; Stores, shifts, multiplies can only issue to E0
(define_function_unit "ev5_e0" 1 0
(and (eq_attr "cpu" "ev5")
@@ -426,12 +431,23 @@
(match_operand:SI 2 "add_operand" "")))]
""
"
-{ emit_insn (gen_rtx_SET (VOIDmode, gen_lowpart (DImode, operands[0]),
- gen_rtx_PLUS (DImode,
- gen_lowpart (DImode, operands[1]),
- gen_lowpart (DImode, operands[2]))));
- DONE;
-} ")
+{
+ if (optimize)
+ {
+ rtx op1 = gen_lowpart (DImode, operands[1]);
+ rtx op2 = gen_lowpart (DImode, operands[2]);
+
+ if (! cse_not_expected)
+ {
+ rtx tmp = gen_reg_rtx (DImode);
+ emit_insn (gen_adddi3 (tmp, op1, op2));
+ emit_move_insn (gen_lowpart (DImode, operands[0]), tmp);
+ }
+ else
+ emit_insn (gen_adddi3 (gen_lowpart (DImode, operands[0]), op1, op2));
+ DONE;
+ }
+}")
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
@@ -476,7 +492,7 @@
(sign_extend:DI
(plus:SI (match_operand:SI 1 "register_operand" "")
(match_operand:SI 2 "const_int_operand" ""))))
- (clobber (match_operand:SI 3 "register_operand" ""))]
+ (clobber (match_operand:SI 3 "reg_not_elim_operand" ""))]
"! sext_add_operand (operands[2], SImode) && INTVAL (operands[2]) > 0
&& INTVAL (operands[2]) % 4 == 0"
[(set (match_dup 3) (match_dup 4))
@@ -546,24 +562,24 @@
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r,r")
- (plus:SI (mult:SI (match_operand:SI 1 "reg_or_0_operand" "rJ,rJ")
+ (plus:SI (mult:SI (match_operand:SI 1 "reg_not_elim_operand" "r,r")
(match_operand:SI 2 "const48_operand" "I,I"))
(match_operand:SI 3 "sext_add_operand" "rI,O")))]
""
"@
- s%2addl %r1,%3,%0
- s%2subl %r1,%n3,%0")
+ s%2addl %1,%3,%0
+ s%2subl %1,%n3,%0")
(define_insn ""
[(set (match_operand:DI 0 "register_operand" "=r,r")
(sign_extend:DI
- (plus:SI (mult:SI (match_operand:SI 1 "reg_or_0_operand" "rJ,rJ")
+ (plus:SI (mult:SI (match_operand:SI 1 "reg_not_elim_operand" "r,r")
(match_operand:SI 2 "const48_operand" "I,I"))
(match_operand:SI 3 "sext_add_operand" "rI,O"))))]
""
"@
- s%2addl %r1,%3,%0
- s%2subl %r1,%n3,%0")
+ s%2addl %1,%3,%0
+ s%2subl %1,%n3,%0")
(define_split
[(set (match_operand:DI 0 "register_operand" "")
@@ -573,7 +589,7 @@
(match_operand 3 "" "")])
(match_operand:SI 4 "const48_operand" ""))
(match_operand:SI 5 "add_operand" ""))))
- (clobber (match_operand:DI 6 "register_operand" ""))]
+ (clobber (match_operand:DI 6 "reg_not_elim_operand" ""))]
""
[(set (match_dup 6) (match_dup 7))
(set (match_dup 0)
@@ -588,12 +604,12 @@
(define_insn ""
[(set (match_operand:DI 0 "register_operand" "=r,r")
- (plus:DI (mult:DI (match_operand:DI 1 "reg_or_0_operand" "rJ,rJ")
+ (plus:DI (mult:DI (match_operand:DI 1 "reg_not_elim_operand" "r,r")
(match_operand:DI 2 "const48_operand" "I,I"))
- (match_operand:DI 3 "reg_or_8bit_operand" "rI,O")))]
+ (match_operand:DI 3 "sext_add_operand" "rI,O")))]
""
"@
- s%2addq %r1,%3,%0
+ s%2addq %1,%3,%0
s%2subq %1,%n3,%0")
;; These variants of the above insns can occur if the third operand
@@ -662,9 +678,7 @@
[(set (match_dup 5)
(plus:SI (mult:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
(set (match_dup 0) (sign_extend:DI (plus:SI (match_dup 5) (match_dup 4))))]
- "
-{ operands[5] = gen_lowpart (SImode, operands[0]);
-}")
+ "operands[5] = gen_lowpart (SImode, operands[0]);")
(define_insn ""
[(set (match_operand:DI 0 "some_operand" "=&r")
@@ -712,11 +726,22 @@
(match_operand:SI 2 "reg_or_8bit_operand" "")))]
""
"
-{ emit_insn (gen_rtx_SET (VOIDmode, gen_lowpart (DImode, operands[0]),
- gen_rtx_MINUS (DImode,
- gen_lowpart (DImode, operands[1]),
- gen_lowpart (DImode, operands[2]))));
- DONE;
+{
+ if (optimize)
+ {
+ rtx op1 = gen_lowpart (DImode, operands[1]);
+ rtx op2 = gen_lowpart (DImode, operands[2]);
+
+ if (! cse_not_expected)
+ {
+ rtx tmp = gen_reg_rtx (DImode);
+ emit_insn (gen_subdi3 (tmp, op1, op2));
+ emit_move_insn (gen_lowpart (DImode, operands[0]), tmp);
+ }
+ else
+ emit_insn (gen_subdi3 (gen_lowpart (DImode, operands[0]), op1, op2));
+ DONE;
+ }
} ")
(define_insn ""
@@ -742,64 +767,67 @@
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
- (minus:SI (mult:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
+ (minus:SI (mult:SI (match_operand:SI 1 "reg_not_elim_operand" "r")
(match_operand:SI 2 "const48_operand" "I"))
(match_operand:SI 3 "reg_or_8bit_operand" "rI")))]
""
- "s%2subl %r1,%3,%0")
+ "s%2subl %1,%3,%0")
(define_insn ""
[(set (match_operand:DI 0 "register_operand" "=r")
(sign_extend:DI
- (minus:SI (mult:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
+ (minus:SI (mult:SI (match_operand:SI 1 "reg_not_elim_operand" "r")
(match_operand:SI 2 "const48_operand" "I"))
(match_operand:SI 3 "reg_or_8bit_operand" "rI"))))]
""
- "s%2subl %r1,%3,%0")
+ "s%2subl %1,%3,%0")
(define_insn ""
[(set (match_operand:DI 0 "register_operand" "=r")
- (minus:DI (mult:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
+ (minus:DI (mult:DI (match_operand:DI 1 "reg_not_elim_operand" "r")
(match_operand:DI 2 "const48_operand" "I"))
(match_operand:DI 3 "reg_or_8bit_operand" "rI")))]
""
- "s%2subq %r1,%3,%0")
+ "s%2subq %1,%3,%0")
(define_insn "mulsi3"
[(set (match_operand:SI 0 "register_operand" "=r")
(mult:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
- (match_operand:SI 2 "reg_or_0_operand" "rJ")))]
+ (match_operand:SI 2 "reg_or_8bit_operand" "rI")))]
""
- "mull %r1,%r2,%0"
+ "mull %r1,%2,%0"
[(set_attr "type" "imul")
(set_attr "opsize" "si")])
(define_insn ""
[(set (match_operand:DI 0 "register_operand" "=r")
- (sign_extend:DI (mult:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
- (match_operand:SI 2 "reg_or_0_operand" "rJ"))))]
+ (sign_extend:DI
+ (mult:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
+ (match_operand:SI 2 "reg_or_8bit_operand" "rI"))))]
""
- "mull %r1,%r2,%0"
+ "mull %r1,%2,%0"
[(set_attr "type" "imul")
(set_attr "opsize" "si")])
(define_insn "muldi3"
[(set (match_operand:DI 0 "register_operand" "=r")
(mult:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ")
- (match_operand:DI 2 "reg_or_0_operand" "rJ")))]
+ (match_operand:DI 2 "reg_or_8bit_operand" "rI")))]
""
- "mulq %r1,%r2,%0"
+ "mulq %r1,%2,%0"
[(set_attr "type" "imul")])
(define_insn "umuldi3_highpart"
[(set (match_operand:DI 0 "register_operand" "=r")
(truncate:DI
(lshiftrt:TI
- (mult:TI (zero_extend:TI (match_operand:DI 1 "register_operand" "r"))
- (zero_extend:TI (match_operand:DI 2 "register_operand" "r")))
+ (mult:TI (zero_extend:TI
+ (match_operand:DI 1 "reg_or_0_operand" "%rJ"))
+ (zero_extend:TI
+ (match_operand:DI 2 "reg_or_8bit_operand" "rI")))
(const_int 64))))]
""
- "umulh %1,%2,%0"
+ "umulh %r1,%2,%0"
[(set_attr "type" "imul")
(set_attr "opsize" "udi")])
@@ -1668,22 +1696,22 @@
"HOST_BITS_PER_WIDE_INT == 64
&& GET_CODE (operands[3]) == CONST_INT
&& (((unsigned HOST_WIDE_INT) 0xff << INTVAL (operands[2])
- == INTVAL (operands[3]))
+ == (unsigned HOST_WIDE_INT) INTVAL (operands[3]))
|| ((unsigned HOST_WIDE_INT) 0xffff << INTVAL (operands[2])
- == INTVAL (operands[3]))
+ == (unsigned HOST_WIDE_INT) INTVAL (operands[3]))
|| ((unsigned HOST_WIDE_INT) 0xffffffff << INTVAL (operands[2])
- == INTVAL (operands[3])))"
+ == (unsigned HOST_WIDE_INT) INTVAL (operands[3])))"
"*
{
#if HOST_BITS_PER_WIDE_INT == 64
if ((unsigned HOST_WIDE_INT) 0xff << INTVAL (operands[2])
- == INTVAL (operands[3]))
+ == (unsigned HOST_WIDE_INT) INTVAL (operands[3]))
return \"insbl %1,%s2,%0\";
if ((unsigned HOST_WIDE_INT) 0xffff << INTVAL (operands[2])
- == INTVAL (operands[3]))
+ == (unsigned HOST_WIDE_INT) INTVAL (operands[3]))
return \"inswl %1,%s2,%0\";
if ((unsigned HOST_WIDE_INT) 0xffffffff << INTVAL (operands[2])
- == INTVAL (operands[3]))
+ == (unsigned HOST_WIDE_INT) INTVAL (operands[3]))
return \"insll %1,%s2,%0\";
#endif
abort();
@@ -2018,7 +2046,7 @@
(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "f,m,f")))]
"TARGET_FP && alpha_tp != ALPHA_TP_INSN"
"@
- cpys %1,%1,%0
+ fmov %1,%0
ld%, %0,%1
st%- %1,%0"
[(set_attr "type" "fcpys,fld,fst")
@@ -2350,69 +2378,6 @@
cmovlbc %r2,%3,%0"
[(set_attr "type" "icmov")])
-;; This form is added since combine thinks that an IF_THEN_ELSE with both
-;; arms constant is a single insn, so it won't try to form it if combine
-;; knows they are really two insns. This occurs in divides by powers
-;; of two.
-
-(define_insn ""
- [(set (match_operand:DI 0 "register_operand" "=r")
- (if_then_else:DI
- (match_operator 2 "signed_comparison_operator"
- [(match_operand:DI 3 "reg_or_0_operand" "rJ")
- (const_int 0)])
- (plus:DI (match_dup 0)
- (match_operand:DI 1 "reg_or_8bit_operand" "rI"))
- (match_dup 0)))
- (clobber (match_scratch:DI 4 "=&r"))]
- ""
- "addq %0,%1,%4\;cmov%C2 %r3,%4,%0"
- [(set_attr "type" "icmov")
- (set_attr "length" "8")])
-
-(define_split
- [(set (match_operand:DI 0 "register_operand" "")
- (if_then_else:DI
- (match_operator 2 "signed_comparison_operator"
- [(match_operand:DI 3 "reg_or_0_operand" "")
- (const_int 0)])
- (plus:DI (match_dup 0)
- (match_operand:DI 1 "reg_or_8bit_operand" ""))
- (match_dup 0)))
- (clobber (match_operand:DI 4 "register_operand" ""))]
- ""
- [(set (match_dup 4) (plus:DI (match_dup 0) (match_dup 1)))
- (set (match_dup 0) (if_then_else:DI (match_op_dup 2
- [(match_dup 3)
- (const_int 0)])
- (match_dup 4) (match_dup 0)))]
- "")
-
-(define_split
- [(parallel
- [(set (match_operand:DI 0 "register_operand" "")
- (if_then_else:DI
- (match_operator 1 "comparison_operator"
- [(zero_extract:DI (match_operand:DI 2 "register_operand" "")
- (const_int 1)
- (match_operand:DI 3 "const_int_operand" ""))
- (const_int 0)])
- (match_operand:DI 4 "reg_or_8bit_operand" "")
- (match_operand:DI 5 "reg_or_8bit_operand" "")))
- (clobber (match_operand:DI 6 "register_operand" ""))])]
- "INTVAL (operands[3]) != 0"
- [(set (match_dup 6)
- (lshiftrt:DI (match_dup 2) (match_dup 3)))
- (set (match_dup 0)
- (if_then_else:DI (match_op_dup 1
- [(zero_extract:DI (match_dup 6)
- (const_int 1)
- (const_int 0))
- (const_int 0)])
- (match_dup 4)
- (match_dup 5)))]
- "")
-
;; For ABS, we have two choices, depending on whether the input and output
;; registers are the same or not.
(define_expand "absdi2"
@@ -3703,7 +3668,7 @@
bsr $26,$%0..ng
jsr $26,%0\;ldgp $29,0($26)"
[(set_attr "type" "jsr")
- (set_attr "length" "12,*,12")])
+ (set_attr "length" "12,*,16")])
(define_insn ""
[(call (mem:DI (match_operand:DI 0 "call_operand" "r,R,i"))
@@ -3726,7 +3691,7 @@
(clobber (reg:DI 27))]
"TARGET_OPEN_VMS"
"@
- bis %2,%2,$27\;jsr $26,0\;ldq $27,0($29)
+ mov %2,$27\;jsr $26,0\;ldq $27,0($29)
ldq $27,%2\;jsr $26,%0\;ldq $27,0($29)"
[(set_attr "type" "jsr")
(set_attr "length" "12,16")])
@@ -3743,7 +3708,7 @@
bsr $26,$%1..ng
jsr $26,%1\;ldgp $29,0($26)"
[(set_attr "type" "jsr")
- (set_attr "length" "12,*,12")])
+ (set_attr "length" "12,*,16")])
(define_insn ""
[(set (match_operand 0 "register_operand" "=rf,rf,rf")
@@ -3768,7 +3733,7 @@
(clobber (reg:DI 27))]
"TARGET_OPEN_VMS"
"@
- bis %3,%3,$27\;jsr $26,0\;ldq $27,0($29)
+ mov %3,$27\;jsr $26,0\;ldq $27,0($29)
ldq $27,%3\;jsr $26,%1\;ldq $27,0($29)"
[(set_attr "type" "jsr")
(set_attr "length" "12,16")])
@@ -4009,72 +3974,68 @@
;; they are simpler.
(define_insn ""
- [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m,f,f,f,m")
- (match_operand:SF 1 "input_operand" "rG,m,rG,f,G,m,fG"))]
+ [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m,f,f,m")
+ (match_operand:SF 1 "input_operand" "rG,m,r,fG,m,fG"))]
"! TARGET_CIX
&& (register_operand (operands[0], SFmode)
|| reg_or_fp0_operand (operands[1], SFmode))"
"@
- bis %r1,%r1,%0
+ mov %r1,%0
ldl %0,%1
stl %r1,%0
- cpys %1,%1,%0
- cpys $f31,$f31,%0
+ fmov %R1,%0
ld%, %0,%1
st%, %R1,%0"
- [(set_attr "type" "ilog,ild,ist,fcpys,fcpys,fld,fst")])
+ [(set_attr "type" "ilog,ild,ist,fcpys,fld,fst")])
(define_insn ""
- [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m,f,f,f,m,f,*r")
- (match_operand:SF 1 "input_operand" "rG,m,rG,f,G,m,fG,r,*f"))]
+ [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m,f,f,m,f,*r")
+ (match_operand:SF 1 "input_operand" "rG,m,r,fG,m,fG,r,*f"))]
"TARGET_CIX
&& (register_operand (operands[0], SFmode)
|| reg_or_fp0_operand (operands[1], SFmode))"
"@
- bis %r1,%r1,%0
+ mov %r1,%0
ldl %0,%1
stl %r1,%0
- cpys %1,%1,%0
- cpys $f31,$f31,%0
+ fmov %R1,%0
ld%, %0,%1
st%, %R1,%0
itofs %1,%0
ftois %1,%0"
- [(set_attr "type" "ilog,ild,ist,fcpys,fcpys,fld,fst,itof,ftoi")])
+ [(set_attr "type" "ilog,ild,ist,fcpys,fld,fst,itof,ftoi")])
(define_insn ""
- [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m,f,f,f,m")
- (match_operand:DF 1 "input_operand" "rG,m,rG,f,G,m,fG"))]
+ [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m,f,f,m")
+ (match_operand:DF 1 "input_operand" "rG,m,r,fG,m,fG"))]
"! TARGET_CIX
&& (register_operand (operands[0], DFmode)
|| reg_or_fp0_operand (operands[1], DFmode))"
"@
- bis %r1,%r1,%0
+ mov %r1,%0
ldq %0,%1
stq %r1,%0
- cpys %1,%1,%0
- cpys $f31,$f31,%0
+ fmov %R1,%0
ld%- %0,%1
st%- %R1,%0"
- [(set_attr "type" "ilog,ild,ist,fcpys,fcpys,fld,fst")])
+ [(set_attr "type" "ilog,ild,ist,fcpys,fld,fst")])
(define_insn ""
- [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m,f,f,f,m,f,*r")
- (match_operand:DF 1 "input_operand" "rG,m,rG,f,G,m,fG,r,*f"))]
+ [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m,f,f,m,f,*r")
+ (match_operand:DF 1 "input_operand" "rG,m,r,fG,m,fG,r,*f"))]
"TARGET_CIX
&& (register_operand (operands[0], DFmode)
|| reg_or_fp0_operand (operands[1], DFmode))"
"@
- bis %r1,%r1,%0
+ mov %r1,%0
ldq %0,%1
stq %r1,%0
- cpys %1,%1,%0
- cpys $f31,$f31,%0
+ fmov %R1,%0
ld%- %0,%1
st%- %R1,%0
itoft %1,%0
ftoit %1,%0"
- [(set_attr "type" "ilog,ild,ist,fcpys,fcpys,fld,fst,itof,ftoi")])
+ [(set_attr "type" "ilog,ild,ist,fcpys,fld,fst,itof,ftoi")])
(define_expand "movsf"
[(set (match_operand:SF 0 "nonimmediate_operand" "")
@@ -4099,131 +4060,110 @@
}")
(define_insn ""
- [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,r,r,m,f,f,f,m")
- (match_operand:SI 1 "input_operand" "r,J,I,K,L,m,rJ,f,J,m,fG"))]
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,m,f,f,m")
+ (match_operand:SI 1 "input_operand" "rJ,K,L,m,rJ,fJ,m,f"))]
"! TARGET_WINDOWS_NT && ! TARGET_OPEN_VMS && ! TARGET_CIX
&& (register_operand (operands[0], SImode)
|| reg_or_0_operand (operands[1], SImode))"
"@
- bis %1,%1,%0
- bis $31,$31,%0
- bis $31,%1,%0
+ mov %r1,%0
lda %0,%1
ldah %0,%h1
ldl %0,%1
stl %r1,%0
- cpys %1,%1,%0
- cpys $f31,$f31,%0
+ fmov %R1,%0
ld%, %0,%1
st%, %R1,%0"
- [(set_attr "type" "ilog,ilog,ilog,iadd,iadd,ild,ist,fcpys,fcpys,fld,fst")])
+ [(set_attr "type" "ilog,iadd,iadd,ild,ist,fcpys,fld,fst")])
(define_insn ""
- [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,r,r,m,f,f,f,m,r,*f")
- (match_operand:SI 1 "input_operand" "r,J,I,K,L,m,rJ,f,J,m,fG,f,*r"))]
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,m,f,f,m,r,*f")
+ (match_operand:SI 1 "input_operand" "rJ,K,L,m,rJ,fJ,m,f,f,*r"))]
"! TARGET_WINDOWS_NT && ! TARGET_OPEN_VMS && TARGET_CIX
&& (register_operand (operands[0], SImode)
|| reg_or_0_operand (operands[1], SImode))"
"@
- bis %1,%1,%0
- bis $31,$31,%0
- bis $31,%1,%0
+ mov %r1,%0
lda %0,%1
ldah %0,%h1
ldl %0,%1
stl %r1,%0
- cpys %1,%1,%0
- cpys $f31,$f31,%0
+ fmov %R1,%0
ld%, %0,%1
st%, %R1,%0
ftois %1,%0
itofs %1,%0"
- [(set_attr "type" "ilog,ilog,ilog,iadd,iadd,ild,ist,fcpys,fcpys,fld,fst,ftoi,itof")])
+ [(set_attr "type" "ilog,iadd,iadd,ild,ist,fcpys,fld,fst,ftoi,itof")])
(define_insn ""
- [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,r,r,r,m,f,f,f,m")
- (match_operand:SI 1 "input_operand" "r,J,I,K,L,s,m,rJ,f,J,m,fG"))]
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,r,m,f,f,m")
+ (match_operand:SI 1 "input_operand" "rJ,K,L,s,m,rJ,fJ,m,f"))]
"(TARGET_WINDOWS_NT || TARGET_OPEN_VMS)
&& (register_operand (operands[0], SImode)
|| reg_or_0_operand (operands[1], SImode))"
"@
- bis %1,%1,%0
- bis $31,$31,%0
- bis $31,%1,%0
+ mov %1,%0
lda %0,%1
ldah %0,%h1
lda %0,%1
ldl %0,%1
stl %r1,%0
- cpys %1,%1,%0
- cpys $f31,$f31,%0
+ fmov %R1,%0
ld%, %0,%1
st%, %R1,%0"
- [(set_attr "type" "ilog,ilog,ilog,iadd,iadd,ldsym,ild,ist,fcpys,fcpys,fld,fst")])
+ [(set_attr "type" "ilog,iadd,iadd,ldsym,ild,ist,fcpys,fld,fst")])
(define_insn ""
- [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,r,f,f")
- (match_operand:HI 1 "input_operand" "r,J,I,n,f,J"))]
+ [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,f")
+ (match_operand:HI 1 "input_operand" "rJ,n,fJ"))]
"! TARGET_BWX
&& (register_operand (operands[0], HImode)
|| register_operand (operands[1], HImode))"
"@
- bis %1,%1,%0
- bis $31,$31,%0
- bis $31,%1,%0
+ mov %r1,%0
lda %0,%L1
- cpys %1,%1,%0
- cpys $f31,$f31,%0"
- [(set_attr "type" "ilog,ilog,ilog,iadd,fcpys,fcpys")])
+ fmov %R1,%0"
+ [(set_attr "type" "ilog,iadd,fcpys")])
(define_insn ""
- [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,r,r,m,f,f")
- (match_operand:HI 1 "input_operand" "r,J,I,n,m,rJ,f,J"))]
+ [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m,f")
+ (match_operand:HI 1 "input_operand" "rJ,n,m,rJ,fJ"))]
"TARGET_BWX
&& (register_operand (operands[0], HImode)
|| reg_or_0_operand (operands[1], HImode))"
"@
- bis %1,%1,%0
- bis $31,$31,%0
- bis $31,%1,%0
+ mov %r1,%0
lda %0,%L1
ldwu %0,%1
stw %r1,%0
- cpys %1,%1,%0
- cpys $f31,$f31,%0"
- [(set_attr "type" "ilog,ilog,ilog,iadd,ild,ist,fcpys,fcpys")])
+ fmov %R1,%0"
+ [(set_attr "type" "ilog,iadd,ild,ist,fcpys")])
(define_insn ""
- [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,r,f,f")
- (match_operand:QI 1 "input_operand" "r,J,I,n,f,J"))]
+ [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,f")
+ (match_operand:QI 1 "input_operand" "rJ,n,fJ"))]
"! TARGET_BWX
&& (register_operand (operands[0], QImode)
|| register_operand (operands[1], QImode))"
"@
- bis %1,%1,%0
- bis $31,$31,%0
- bis $31,%1,%0
+ mov %r1,%0
lda %0,%L1
- cpys %1,%1,%0
- cpys $f31,$f31,%0"
- [(set_attr "type" "ilog,ilog,ilog,iadd,fcpys,fcpys")])
+ fmov %R1,%0"
+ [(set_attr "type" "ilog,iadd,fcpys")])
(define_insn ""
- [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,r,r,m,f,f")
- (match_operand:QI 1 "input_operand" "r,J,I,n,m,rJ,f,J"))]
+ [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,m,f")
+ (match_operand:QI 1 "input_operand" "rJ,n,m,rJ,fJ"))]
"TARGET_BWX
&& (register_operand (operands[0], QImode)
|| reg_or_0_operand (operands[1], QImode))"
"@
- bis %1,%1,%0
- bis $31,$31,%0
- bis $31,%1,%0
+ mov %r1,%0
lda %0,%L1
ldbu %0,%1
stb %r1,%0
- cpys %1,%1,%0
- cpys $f31,$f31,%0"
- [(set_attr "type" "ilog,ilog,ilog,iadd,ild,ist,fcpys,fcpys")])
+ fmov %R1,%0"
+ [(set_attr "type" "ilog,iadd,ild,ist,fcpys")])
;; We do two major things here: handle mem->mem and construct long
;; constants.
@@ -4269,48 +4209,42 @@
}")
(define_insn ""
- [(set (match_operand:DI 0 "general_operand" "=r,r,r,r,r,r,r,m,f,f,f,Q")
- (match_operand:DI 1 "input_operand" "r,J,I,K,L,s,m,rJ,f,J,Q,fG"))]
+ [(set (match_operand:DI 0 "general_operand" "=r,r,r,r,r,m,f,f,Q")
+ (match_operand:DI 1 "input_operand" "rJ,K,L,s,m,rJ,fJ,Q,f"))]
"! TARGET_CIX
&& (register_operand (operands[0], DImode)
|| reg_or_0_operand (operands[1], DImode))"
"@
- bis %1,%1,%0
- bis $31,$31,%0
- bis $31,%1,%0
+ mov %r1,%0
lda %0,%1
ldah %0,%h1
lda %0,%1
ldq%A1 %0,%1
stq%A0 %r1,%0
- cpys %1,%1,%0
- cpys $f31,$f31,%0
+ fmov %R1,%0
ldt %0,%1
stt %R1,%0"
- [(set_attr "type" "ilog,ilog,ilog,iadd,iadd,ldsym,ild,ist,fcpys,fcpys,fld,fst")])
+ [(set_attr "type" "ilog,iadd,iadd,ldsym,ild,ist,fcpys,fld,fst")])
(define_insn ""
- [(set (match_operand:DI 0 "general_operand" "=r,r,r,r,r,r,r,m,f,f,f,Q,r,*f")
- (match_operand:DI 1 "input_operand" "r,J,I,K,L,s,m,rJ,f,J,Q,fG,f,*r"))]
+ [(set (match_operand:DI 0 "general_operand" "=r,r,r,r,r,m,f,f,Q,r,*f")
+ (match_operand:DI 1 "input_operand" "rJ,K,L,s,m,rJ,fJ,Q,f,f,*r"))]
"TARGET_CIX
&& (register_operand (operands[0], DImode)
|| reg_or_0_operand (operands[1], DImode))"
"@
- bis %1,%1,%0
- bis $31,$31,%0
- bis $31,%1,%0
+ mov %r1,%0
lda %0,%1
ldah %0,%h1
lda %0,%1
ldq%A1 %0,%1
stq%A0 %r1,%0
- cpys %1,%1,%0
- cpys $f31,$f31,%0
+ fmov %R1,%0
ldt %0,%1
stt %R1,%0
ftoit %1,%0
itoft %1,%0"
- [(set_attr "type" "ilog,ilog,ilog,iadd,iadd,ldsym,ild,ist,fcpys,fcpys,fld,fst,ftoi,itof")])
+ [(set_attr "type" "ilog,iadd,iadd,ldsym,ild,ist,fcpys,fld,fst,ftoi,itof")])
;; We do three major things here: handle mem->mem, put 64-bit constants in
;; memory, and construct long 32-bit constants.
@@ -5109,27 +5043,11 @@
""
"*
{
- static int label_no;
- int count_regno = REGNO (operands[0]);
- int ptr_regno = REGNO (operands[1]);
- char label[64];
-
- /* Ho hum, output the hard way to get the label at the beginning of
- the line. Wish there were a magic char you could get
- asm_output_printf to do that. Then we could use %= as well and
- get rid of the label_no bits here too. */
-
- ASM_GENERATE_INTERNAL_LABEL (label, \"LSC\", label_no);
- ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"LSC\", label_no++);
-
- fprintf (asm_out_file, \"\\tstq $31,-8192($%d)\\n\", ptr_regno);
- fprintf (asm_out_file, \"\\tsubq $%d,1,$%d\\n\", count_regno, count_regno);
- fprintf (asm_out_file, \"\\tlda $%d,-8192($%d)\\n\", ptr_regno, ptr_regno);
- fprintf (asm_out_file, \"\\tbne $%d,\", count_regno);
- assemble_name (asm_out_file, label);
- putc ('\\n', asm_out_file);
-
- return \"\";
+ operands[2] = gen_label_rtx ();
+ ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
+ CODE_LABEL_NUMBER (operands[2]));
+
+ return \"stq $31,-8192(%1)\;subq %0,1,%0\;lda %1,-8192(%1)\;bne %0,%l2\";
}"
[(set_attr "length" "16")
(set_attr "type" "multi")])
@@ -5144,7 +5062,7 @@
(match_operand:DI 1 "register_operand" "r"))
(clobber (mem:BLK (match_operand:DI 2 "register_operand" "r")))]
""
- "bis %1,%1,%0")
+ "mov %1,%0")
(define_expand "epilogue"
[(clobber (const_int 0))]
@@ -5189,6 +5107,7 @@
where to look for it when we get back to setjmp's function for
restoring the gp. */
emit_indirect_jump (pv);
+ DONE;
}")
(define_insn "builtin_setjmp_receiver"
diff --git a/gcc/config/alpha/elf.h b/gcc/config/alpha/elf.h
index 89eda748c06..b90ce9fa914 100644
--- a/gcc/config/alpha/elf.h
+++ b/gcc/config/alpha/elf.h
@@ -1,5 +1,5 @@
/* Definitions of target machine for GNU compiler, for DEC Alpha w/ELF.
- Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
Contributed by Richard Henderson (rth@tamu.edu).
This file is part of GNU CC.
@@ -83,8 +83,9 @@ extern void output_file_directive ();
#else
#define ASM_FILE_END(FILE) \
do { \
- fprintf ((FILE), "\t%s\t\"GCC: (GNU) %s\"\n", \
- IDENT_ASM_OP, version_string); \
+ if (!flag_no_ident) \
+ fprintf ((FILE), "\t%s\t\"GCC: (GNU) %s\"\n", \
+ IDENT_ASM_OP, version_string); \
} while (0)
#endif
@@ -438,20 +439,23 @@ void FN () \
size_directive_output was set
by ASM_DECLARE_OBJECT_NAME when it was run for the same decl. */
-#define ASM_FINISH_DECLARE_OBJECT(FILE, DECL, TOP_LEVEL, AT_END) \
-do { \
- char *name = XSTR (XEXP (DECL_RTL (DECL), 0), 0); \
- if (!flag_inhibit_size_directive && DECL_SIZE (DECL) \
- && ! AT_END && TOP_LEVEL \
- && DECL_INITIAL (DECL) == error_mark_node \
- && !size_directive_output) \
- { \
- size_directive_output = 1; \
- fprintf (FILE, "\t%s\t ", SIZE_ASM_OP); \
- assemble_name (FILE, name); \
- fprintf (FILE, ",%d\n", int_size_in_bytes (TREE_TYPE (DECL))); \
- } \
- } while (0)
+#define ASM_FINISH_DECLARE_OBJECT(FILE, DECL, TOP_LEVEL, AT_END) \
+do { \
+ char *name = XSTR (XEXP (DECL_RTL (DECL), 0), 0); \
+ if (!flag_inhibit_size_directive && DECL_SIZE (DECL) \
+ && ! AT_END && TOP_LEVEL \
+ && DECL_INITIAL (DECL) == error_mark_node \
+ && !size_directive_output) \
+ { \
+ size_directive_output = 1; \
+ fprintf (FILE, "\t%s\t ", SIZE_ASM_OP); \
+ assemble_name (FILE, name); \
+ putc (',', FILE); \
+ fprintf (FILE, HOST_WIDE_INT_PRINT_DEC, \
+ int_size_in_bytes (TREE_TYPE (DECL))); \
+ putc ('\n', FILE); \
+ } \
+} while (0)
/* A table of bytes codes used by the ASM_OUTPUT_ASCII and
ASM_OUTPUT_LIMITED_STRING macros. Each byte in the table
diff --git a/gcc/config/alpha/linux-ecoff.h b/gcc/config/alpha/linux-ecoff.h
index bc271506b5c..824d0280fce 100644
--- a/gcc/config/alpha/linux-ecoff.h
+++ b/gcc/config/alpha/linux-ecoff.h
@@ -17,7 +17,8 @@ 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
#undef TARGET_VERSION
#define TARGET_VERSION fprintf (stderr, " (Alpha GNU/Linux for ECOFF)");
diff --git a/gcc/config/alpha/linux-elf.h b/gcc/config/alpha/linux-elf.h
index 90009f1c5d0..fc07127d757 100644
--- a/gcc/config/alpha/linux-elf.h
+++ b/gcc/config/alpha/linux-elf.h
@@ -17,7 +17,8 @@ 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
#undef TARGET_VERSION
#define TARGET_VERSION fprintf (stderr, " (Alpha GNU/Linux for ELF)");
diff --git a/gcc/config/alpha/linux.h b/gcc/config/alpha/linux.h
index 01b4e9daeea..b8eb9e915e4 100644
--- a/gcc/config/alpha/linux.h
+++ b/gcc/config/alpha/linux.h
@@ -17,7 +17,8 @@ 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
#undef TARGET_DEFAULT
#define TARGET_DEFAULT (MASK_FP | MASK_FPREGS | MASK_GAS)
diff --git a/gcc/config/alpha/netbsd-elf.h b/gcc/config/alpha/netbsd-elf.h
index 17d7bb0e4ae..6e4f4daf62b 100644
--- a/gcc/config/alpha/netbsd-elf.h
+++ b/gcc/config/alpha/netbsd-elf.h
@@ -16,7 +16,8 @@ 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
#undef TARGET_VERSION
#define TARGET_VERSION fprintf (stderr, " (Alpha NetBSD/ELF)");
diff --git a/gcc/config/alpha/netbsd.h b/gcc/config/alpha/netbsd.h
index 054e9e063b4..51890643f88 100644
--- a/gcc/config/alpha/netbsd.h
+++ b/gcc/config/alpha/netbsd.h
@@ -16,7 +16,8 @@ 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
#undef TARGET_DEFAULT
#define TARGET_DEFAULT (MASK_FP | MASK_FPREGS | MASK_GAS)
diff --git a/gcc/config/alpha/vxworks.h b/gcc/config/alpha/vxworks.h
index 6dee4b3e721..7ef1feeb802 100644
--- a/gcc/config/alpha/vxworks.h
+++ b/gcc/config/alpha/vxworks.h
@@ -36,11 +36,11 @@ Boston, MA 02111-1307, USA. */
#undef LIB_SPEC
#define LIB_SPEC ""
-/* VxWorks uses object files, not loadable images. make linker just
- combine objects. */
+/* VxWorks uses object files, not loadable images. Make linker just combine
+ objects. Also show using 32 bit mode and set start of text to 0. */
#undef LINK_SPEC
-#define LINK_SPEC "-r"
+#define LINK_SPEC "-r -taso -T 0"
/* VxWorks provides the functionality of crt0.o and friends itself. */
diff --git a/gcc/config/aoutos.h b/gcc/config/aoutos.h
index e9caa719905..6f4e2623c64 100644
--- a/gcc/config/aoutos.h
+++ b/gcc/config/aoutos.h
@@ -39,50 +39,3 @@ Boston, MA 02111-1307, USA. */
/* Define a symbol indicating that we are using aoutos.h. */
#define USING_AOUTOS_H
-
-/* A C statement (sans semicolon) to output an element in the table of
- global constructors.
- If using GNU LD, tell it that this is part of the static destructor set.
- This code works for any machine provided you use GNU as/ld.
- If not using GNU LD, rely on a "collect" program to look for names defined
- in the particular form we choose as global constructor function names. */
-
-#define ASM_OUTPUT_CONSTRUCTOR(FILE,NAME) \
- do { \
- if (flag_gnu_linker) \
- { \
- /* Output an N_SETT (0x16, 22.) for the name. */ \
- fprintf (FILE, "%s \"___CTOR_LIST__\",22,0,0,", ASM_STABS_OP); \
- assemble_name (FILE, NAME); \
- fputc ('\n', FILE); \
- } \
- } while (0)
-
-
-/* A C statement (sans semicolon) to output an element in the table of
- global destructors. */
-
-#define ASM_OUTPUT_DESTRUCTOR(FILE,NAME) \
- do { \
- if (flag_gnu_linker) \
- { \
- /* Output an N_SETT (0x16, 22.) for the name. */ \
- fprintf (FILE, "%s \"___DTOR_LIST__\",22,0,0,", ASM_STABS_OP); \
- assemble_name (FILE, NAME); \
- fputc ('\n', FILE); \
- } \
- } while (0)
-
-/* Likewise for entries we want to record for garbage collection.
- Garbage collection is still under development. */
-
-#define ASM_OUTPUT_GC_ENTRY(FILE,NAME) \
- do { \
- if (flag_gnu_linker) \
- { \
- /* Output an N_SETT (0x16, 22.) for the name. */ \
- fprintf (FILE, "%s \"___PTR_LIST__\",22,0,0,", ASM_STABS_OP); \
- assemble_name (FILE, NAME); \
- fputc ('\n', FILE); \
- } \
- } while (0)
diff --git a/gcc/config/arc/arc.h b/gcc/config/arc/arc.h
index ab1dc153116..49d9fe2edd2 100644
--- a/gcc/config/arc/arc.h
+++ b/gcc/config/arc/arc.h
@@ -927,8 +927,8 @@ do { \
#define MAX_REGS_PER_ADDRESS 1
/* We have pre inc/dec (load/store with update). */
-#define HAVE_PRE_INCREMENT
-#define HAVE_PRE_DECREMENT
+#define HAVE_PRE_INCREMENT 1
+#define HAVE_PRE_DECREMENT 1
/* Recognize any constant value that is a valid address. */
#define CONSTANT_ADDRESS_P(X) \
diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md
index 328b1ebd991..b4c86ba8b62 100644
--- a/gcc/config/arc/arc.md
+++ b/gcc/config/arc/arc.md
@@ -1,5 +1,5 @@
;; Machine description of the Argonaut ARC cpu for GNU C compiler
-;; Copyright (C) 1994, 1997 Free Software Foundation, Inc.
+;; Copyright (C) 1994, 1997, 1999 Free Software Foundation, Inc.
;; This file is part of GNU CC.
@@ -1039,7 +1039,7 @@
[(set_attr "type" "unary")])
(define_insn "*one_cmplsi2_set_cc_insn"
- [(set (reg:CCZN 61) (compare:CC
+ [(set (reg:CCZN 61) (compare:CCZN
(not:SI (match_operand:SI 1 "register_operand" "r"))
(const_int 0)))
(set (match_operand:SI 0 "register_operand" "=r")
diff --git a/gcc/config/arc/initfini.c b/gcc/config/arc/initfini.c
index 084e2292bf5..6f8e2688188 100644
--- a/gcc/config/arc/initfini.c
+++ b/gcc/config/arc/initfini.c
@@ -1,7 +1,7 @@
/* .init/.fini section handling + C++ global constructor/destructor handling.
This file is based on crtstuff.c, sol2-crti.asm, sol2-crtn.asm.
-Copyright (C) 1995, 1997 Free Software Foundation, Inc.
+Copyright (C) 1995, 1997, 1998 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -77,30 +77,30 @@ __do_global_dtors ()
/* .init section start.
This must appear at the start of the .init section. */
-asm ("
- .section .init\n
- .global init\n
- .word 0\n
-init:\n
- st blink,[sp,4]\n
- st fp,[sp]\n
- mov fp,sp\n
- sub sp,sp,16\n
+asm ("\n\
+ .section .init\n\
+ .global init\n\
+ .word 0\n\
+init:\n\
+ st blink,[sp,4]\n\
+ st fp,[sp]\n\
+ mov fp,sp\n\
+ sub sp,sp,16\n\
");
/* .fini section start.
This must appear at the start of the .init section. */
-asm ("
- .section .fini\n
- .global fini\n
- .word 0\n
-fini:\n
- st blink,[sp,4]\n
- st fp,[sp]\n
- mov fp,sp\n
- sub sp,sp,16\n
- bl.nd __do_global_dtors
+asm ("\n\
+ .section .fini\n\
+ .global fini\n\
+ .word 0\n\
+fini:\n\
+ st blink,[sp,4]\n\
+ st fp,[sp]\n\
+ mov fp,sp\n\
+ sub sp,sp,16\n\
+ bl.nd __do_global_dtors\n\
");
#endif /* CRT_INIT */
@@ -136,22 +136,22 @@ __do_global_ctors ()
/* .init section end.
This must live at the end of the .init section. */
-asm ("
- .section .init\n
- bl.nd __do_global_ctors
- ld blink,[fp,4]\n
- j.d blink\n
- ld.a fp,[sp,16]\n
+asm ("\n\
+ .section .init\n\
+ bl.nd __do_global_ctors\
+ ld blink,[fp,4]\n\
+ j.d blink\n\
+ ld.a fp,[sp,16]\n\
");
/* .fini section end.
This must live at the end of the .fini section. */
-asm ("
- .section .fini\n
- ld blink,[fp,4]\n
- j.d blink\n
- ld.a fp,[sp,16]\n
+asm ("\n\
+ .section .fini\n\
+ ld blink,[fp,4]\n\
+ j.d blink\n\
+ ld.a fp,[sp,16]\n\
");
#endif /* CRT_FINI */
diff --git a/gcc/config/arm/README-interworking b/gcc/config/arm/README-interworking
index a0069a9ea80..46b76c99242 100644
--- a/gcc/config/arm/README-interworking
+++ b/gcc/config/arm/README-interworking
@@ -145,14 +145,14 @@ declspec for individual functions, indicating that that particular
function should support being called by non-interworking aware code.
The function should be defined like this:
- int function __attribute__((interfacearm))
+ int __attribute__((interfacearm)) function
{
... body of function ...
}
or
- int function __declspec(interfacearm)
+ int __declspec(interfacearm) function
{
... body of function ...
}
@@ -162,8 +162,63 @@ or
4. Interworking support in dlltool
==================================
-Currently there is no interworking support in dlltool. This may be a
-future enhancement.
+It is possible to create DLLs containing mixed ARM and Thumb code. It
+is also possible to call Thumb code in a DLL from an ARM program and
+vice versa. It is even possible to call ARM DLLs that have been compiled
+without interworking support (say by an older version of the compiler),
+from Thumb programs and still have things work properly.
+
+ A version of the `dlltool' program which supports the `--interwork'
+command line switch is needed, as well as the following special
+considerations when building programs and DLLs:
+
+*Use `-mthumb-interwork'*
+ When compiling files for a DLL or a program the `-mthumb-interwork'
+ command line switch should be specified if calling between ARM and
+ Thumb code can happen. If a program is being compiled and the
+ mode of the DLLs that it uses is not known, then it should be
+ assumed that interworking might occur and the switch used.
+
+*Use `-m thumb'*
+ If the exported functions from a DLL are all Thumb encoded then the
+ `-m thumb' command line switch should be given to dlltool when
+ building the stubs. This will make dlltool create Thumb encoded
+ stubs, rather than its default of ARM encoded stubs.
+
+ If the DLL consists of both exported Thumb functions and exported
+ ARM functions then the `-m thumb' switch should not be used.
+ Instead the Thumb functions in the DLL should be compiled with the
+ `-mcallee-super-interworking' switch, or with the `interfacearm'
+ attribute specified on their prototypes. In this way they will be
+ given ARM encoded prologues, which will work with the ARM encoded
+ stubs produced by dlltool.
+
+*Use `-mcaller-super-interworking'*
+ If it is possible for Thumb functions in a DLL to call
+ non-interworking aware code via a function pointer, then the Thumb
+ code must be compiled with the `-mcaller-super-interworking'
+ command line switch. This will force the function pointer calls
+ to use the _interwork_call_via_rX stub functions which will
+ correctly restore Thumb mode upon return from the called function.
+
+*Link with `libgcc.a'*
+ When the dll is built it may have to be linked with the GCC
+ library (`libgcc.a') in order to extract the _call_via_rX functions
+ or the _interwork_call_via_rX functions. This represents a partial
+ redundancy since the same functions *may* be present in the
+ application itself, but since they only take up 372 bytes this
+ should not be too much of a consideration.
+
+*Use `--support-old-code'*
+ When linking a program with an old DLL which does not support
+ interworking, the `--support-old-code' command line switch to the
+ linker should be used. This causes the linker to generate special
+ interworking stubs which can cope with old, non-interworking aware
+ ARM code, at the cost of generating bulkier code. The linker will
+ still generate a warning message along the lines of:
+ "Warning: input file XXX does not support interworking, whereas YYY does."
+ but this can now be ignored because the --support-old-code switch
+ has been used.
@@ -363,191 +418,325 @@ be restored upon exit from the function.
8. Some examples
================
-Given this test file:
+ Given these two test files:
+
+ int arm (void) { return 1 + thumb (); }
+
+ int thumb (void) { return 2 + arm (); }
+
+ The following pieces of assembler are produced by the ARM and Thumb
+version of GCC depending upon the command line options used:
+
+ `-O2':
+ .code 32 .code 16
+ .global _arm .global _thumb
+ .thumb_func
+ _arm: _thumb:
+ mov ip, sp
+ stmfd sp!, {fp, ip, lr, pc} push {lr}
+ sub fp, ip, #4
+ bl _thumb bl _arm
+ add r0, r0, #1 add r0, r0, #2
+ ldmea fp, {fp, sp, pc} pop {pc}
+
+ Note how the functions return without using the BX instruction. If
+these files were assembled and linked together they would fail to work
+because they do not change mode when returning to their caller.
+
+ `-O2 -mthumb-interwork':
+
+ .code 32 .code 16
+ .global _arm .global _thumb
+ .thumb_func
+ _arm: _thumb:
+ mov ip, sp
+ stmfd sp!, {fp, ip, lr, pc} push {lr}
+ sub fp, ip, #4
+ bl _thumb bl _arm
+ add r0, r0, #1 add r0, r0, #2
+ ldmea fp, {fp, sp, lr} pop {r1}
+ bx lr bx r1
+
+ Now the functions use BX to return their caller. They have grown by
+4 and 2 bytes respectively, but they can now successfully be linked
+together and be expect to work. The linker will replace the
+destinations of the two BL instructions with the addresses of calling
+stubs which convert to the correct mode before jumping to the called
+function.
+
+ `-O2 -mcallee-super-interworking':
+
+ .code 32 .code 32
+ .global _arm .global _thumb
+ _arm: _thumb:
+ orr r12, pc, #1
+ bx r12
+ mov ip, sp .code 16
+ stmfd sp!, {fp, ip, lr, pc} push {lr}
+ sub fp, ip, #4
+ bl _thumb bl _arm
+ add r0, r0, #1 add r0, r0, #2
+ ldmea fp, {fp, sp, lr} pop {r1}
+ bx lr bx r1
+
+ The thumb function now has an ARM encoded prologue, and it no longer
+has the `.thumb-func' pseudo op attached to it. The linker will not
+generate a calling stub for the call from arm() to thumb(), but it will
+still have to generate a stub for the call from thumb() to arm(). Also
+note how specifying `--mcallee-super-interworking' automatically
+implies `-mthumb-interworking'.
+
+
+9. Some Function Pointer Examples
+=================================
- int func (void) { return 1; }
+ Given this test file:
+
+ int func (void) { return 1; }
+
+ int call (int (* ptr)(void)) { return ptr (); }
+
+ The following varying pieces of assembler are produced by the Thumb
+version of GCC depending upon the command line options used:
+
+ `-O2':
+ .code 16
+ .globl _func
+ .thumb_func
+ _func:
+ mov r0, #1
+ bx lr
+
+ .globl _call
+ .thumb_func
+ _call:
+ push {lr}
+ bl __call_via_r0
+ pop {pc}
+
+ Note how the two functions have different exit sequences. In
+particular call() uses pop {pc} to return, which would not work if the
+caller was in ARM mode. func() however, uses the BX instruction, even
+though `-mthumb-interwork' has not been specified, as this is the most
+efficient way to exit a function when the return address is held in the
+link register.
+
+ `-O2 -mthumb-interwork':
+
+ .code 16
+ .globl _func
+ .thumb_func
+ _func:
+ mov r0, #1
+ bx lr
+
+ .globl _call
+ .thumb_func
+ _call:
+ push {lr}
+ bl __call_via_r0
+ pop {r1}
+ bx r1
+
+ This time both functions return by using the BX instruction. This
+means that call() is now two bytes longer and several cycles slower
+than the previous version.
+
+ `-O2 -mcaller-super-interworking':
+ .code 16
+ .globl _func
+ .thumb_func
+ _func:
+ mov r0, #1
+ bx lr
+
+ .globl _call
+ .thumb_func
+ _call:
+ push {lr}
+ bl __interwork_call_via_r0
+ pop {pc}
+
+ Very similar to the first (non-interworking) version, except that a
+different stub is used to call via the function pointer. This new stub
+will work even if the called function is not interworking aware, and
+tries to return to call() in ARM mode. Note that the assembly code for
+call() is still not interworking aware itself, and so should not be
+called from ARM code.
+
+ `-O2 -mcallee-super-interworking':
+
+ .code 32
+ .globl _func
+ _func:
+ orr r12, pc, #1
+ bx r12
+
+ .code 16
+ .globl .real_start_of_func
+ .thumb_func
+ .real_start_of_func:
+ mov r0, #1
+ bx lr
+
+ .code 32
+ .globl _call
+ _call:
+ orr r12, pc, #1
+ bx r12
+
+ .code 16
+ .globl .real_start_of_call
+ .thumb_func
+ .real_start_of_call:
+ push {lr}
+ bl __call_via_r0
+ pop {r1}
+ bx r1
+
+ Now both functions have an ARM coded prologue, and both functions
+return by using the BX instruction. These functions are interworking
+aware therefore and can safely be called from ARM code. The code for
+the call() function is now 10 bytes longer than the original, non
+interworking aware version, an increase of over 200%.
- int call (int (* ptr)(void)) { return ptr (); }
+ If a prototype for call() is added to the source code, and this
+prototype includes the `interfacearm' attribute:
+
+ int __attribute__((interfacearm)) call (int (* ptr)(void));
+
+ then this code is produced (with only -O2 specified on the command
+line):
+
+ .code 16
+ .globl _func
+ .thumb_func
+ _func:
+ mov r0, #1
+ bx lr
+
+ .globl _call
+ .code 32
+ _call:
+ orr r12, pc, #1
+ bx r12
+
+ .code 16
+ .globl .real_start_of_call
+ .thumb_func
+ .real_start_of_call:
+ push {lr}
+ bl __call_via_r0
+ pop {r1}
+ bx r1
+
+ So now both call() and func() can be safely called via
+non-interworking aware ARM code. If, when such a file is assembled,
+the assembler detects the fact that call() is being called by another
+function in the same file, it will automatically adjust the target of
+the BL instruction to point to .real_start_of_call. In this way there
+is no need for the linker to generate a Thumb-to-ARM calling stub so
+that call can be entered in ARM mode.
+
+
+10. How to use dlltool to build ARM/Thumb DLLs
+==============================================
+ Given a program (`prog.c') like this:
-The following varying pieces of assembler are produced depending upon
-the command line options used:
+ extern int func_in_dll (void);
+
+ int main (void) { return func_in_dll(); }
-no options:
+ And a DLL source file (`dll.c') like this:
- @ Generated by gcc cygnus-2.91.07 980205 (gcc-2.8.0 release) for ARM/pe
- .code 16
- .text
- .globl _func
- .thumb_func
- _func:
- mov r0, #1
- bx lr
+ int func_in_dll (void) { return 1; }
- .globl _call
- .thumb_func
- _call:
- push {lr}
- bl __call_via_r0
- pop {pc}
+ Here is how to build the DLL and the program for a purely ARM based
+environment:
-Note how the two functions have different exit sequences. In
-particular call() uses pop {pc} to return. This would not work if the
-caller was in ARM mode.
+*Step One
+ Build a `.def' file describing the DLL:
-If -mthumb-interwork is specified on the command line:
+ ; example.def
+ ; This file describes the contents of the DLL
+ LIBRARY example
+ HEAPSIZE 0x40000, 0x2000
+ EXPORTS
+ func_in_dll 1
- @ Generated by gcc cygnus-2.91.07 980205 (gcc-2.8.0 release) for ARM/pe
- .code 16
- .text
- .globl _func
- .thumb_func
- _func:
- mov r0, #1
- bx lr
+*Step Two
+ Compile the DLL source code:
- .globl _call
- .thumb_func
- _call:
- push {lr}
- bl __call_via_r0
- pop {r1}
- bx r1
+ arm-pe-gcc -O2 -c dll.c
-This time both functions return by using the BX instruction. This
-means that call() is now two bytes longer and several cycles slower
-than the version that is not interworking enabled.
+*Step Three
+ Use `dlltool' to create an exports file and a library file:
-If -mcaller-super-interworking is specified:
+ dlltool --def example.def --output-exp example.o --output-lib example.a
- @ Generated by gcc cygnus-2.91.07 980205 (gcc-2.8.0 release) for ARM/pe
- .code 16
- .text
- .globl _func
- .thumb_func
- _func:
- mov r0, #1
- bx lr
+*Step Four
+ Link together the complete DLL:
- .globl _call
- .thumb_func
- _call:
- push {lr}
- bl __interwork_call_via_r0
- pop {pc}
-
-Very similar to the first (non-interworking) version, except that a
-different stub is used to call via the function pointer. Note that
-the assembly code for call() is not interworking aware, and so should
-not be called from ARM code.
-
-If -mcallee-super-interworking is specified:
-
- @ Generated by gcc cygnus-2.91.07 980205 (gcc-2.8.0 release) for ARM/pe
- .code 16
- .text
- .globl _func
- .code 32
- _func:
- orr r12, pc, #1
- bx r12
- .code 16
- .globl .real_start_of_func
- .thumb_func
- .real_start_of_func:
- mov r0, #1
- bx lr
+ arm-pe-ld dll.o example.o -o example.dll
- .globl _call
- .code 32
- _call:
- orr r12, pc, #1
- bx r12
- .code 16
- .globl .real_start_of_call
- .thumb_func
- .real_start_of_call:
- push {lr}
- bl __call_via_r0
- pop {r1}
- bx r1
+*Step Five
+ Compile the program's source code:
-Now both functions have an ARM coded prologue, and both functions
-return by using the BX instruction. These functions are interworking
-aware therefore and can safely be called from ARM code. The code for
-the call() function is now 10 bytes longer than the original, non
-interworking aware version, an increase of over 200%.
+ arm-pe-gcc -O2 -c prog.c
-If the source code is slightly altered so that only the call function
-has an (interfacearm) attribute:
+*Step Six
+ Link together the program and the DLL's library file:
- int func (void) { return 1; }
- int call () __attribute__((interfacearm));
- int call (int (* ptr)(void)) { return ptr (); }
- int main (void) { return printf ("result: %d\n", call (func)); }
+ arm-pe-gcc prog.o example.a -o prog
-then this code is produced (with no command line switches):
+ If instead this was a Thumb DLL being called from an ARM program, the
+steps would look like this. (To save space only those steps that are
+different from the previous version are shown):
- @ Generated by gcc cygnus-2.91.07 980205 (gcc-2.8.0 release) for ARM/pe
- .code 16
- .text
- .globl _func
- .thumb_func
- _func:
- mov r0, #1
- bx lr
+*Step Two
+ Compile the DLL source code (using the Thumb compiler):
- .globl _call
- .code 32
- _call:
- orr r12, pc, #1
- bx r12
- .code 16
- .globl .real_start_of_call
- .thumb_func
- .real_start_of_call:
- push {lr}
- bl __call_via_r0
- pop {r1}
- bx r1
+ thumb-pe-gcc -O2 -c dll.c -mthumb-interwork
- .globl _main
- .thumb_func
- _main:
- push {r4, lr}
- bl ___gccmain
- ldr r4, .L4
- ldr r0, .L4+4
- bl _call
- add r1, r0, #0
- add r0, r4, #0
- bl _printf
- pop {r4, pc}
- .L4:
- .word .LC0
- .word _func
-
- .section .rdata
- .LC0:
- .ascii "result: %d\n\000"
-
-So now only call() can be called via non-interworking aware ARM code.
-When this program is assembled, the assembler detects the fact that
-main() is calling call() in Thumb mode, and so automatically adjusts
-the BL instruction to point to the real start of call():
-
- Disassembly of section .text:
-
- 00000028 <_main>:
- 28: b530 b530 push {r4, r5, lr}
- 2a: fffef7ff f7ff bl 2a <_main+0x2>
- 2e: 4d06 4d06 ldr r5, [pc, #24] (48 <.L7>)
- 30: ffe8f7ff f7ff bl 4 <_doit>
- 34: 1c04 1c04 add r4, r0, #0
- 36: 4805 4805 ldr r0, [pc, #20] (4c <.L7+0x4>)
- 38: fff0f7ff f7ff bl 1c <.real_start_of_call>
- 3c: 1824 1824 add r4, r4, r0
- 3e: 1c28 1c28 add r0, r5, #0
- 40: 1c21 1c21 add r1, r4, #0
- 42: fffef7ff f7ff bl 42 <_main+0x1a>
- 46: bd30 bd30 pop {r4, r5, pc}
+*Step Three
+ Build the exports and library files (and support interworking):
+
+ dlltool -d example.def -z example.o -l example.a --interwork -m thumb
+
+*Step Five
+ Compile the program's source code (and support interworking):
+
+ arm-pe-gcc -O2 -c prog.c -mthumb-interwork
+
+ If instead, the DLL was an old, ARM DLL which does not support
+interworking, and which cannot be rebuilt, then these steps would be
+used.
+
+*Step One
+ Skip. If you do not have access to the sources of a DLL, there is
+ no point in building a `.def' file for it.
+
+*Step Two
+ Skip. With no DLL sources there is nothing to compile.
+
+*Step Three
+ Skip. Without a `.def' file you cannot use dlltool to build an
+ exports file or a library file.
+
+*Step Four
+ Skip. Without a set of DLL object files you cannot build the DLL.
+ Besides it has already been built for you by somebody else.
+
+*Step Five
+ Compile the program's source code, this is the same as before:
+
+ arm-pe-gcc -O2 -c prog.c
+
+*Step Six
+ Link together the program and the DLL's library file, passing the
+ `--support-old-code' option to the linker:
+
+ arm-pe-gcc prog.o example.a -Wl,--support-old-code -o prog
+ Ignore the warning message about the input file not supporting
+ interworking as the --support-old-code switch has taken care if this.
diff --git a/gcc/config/arm/aout.h b/gcc/config/arm/aout.h
index 5d3d78959be..faf395aadb2 100644
--- a/gcc/config/arm/aout.h
+++ b/gcc/config/arm/aout.h
@@ -1,5 +1,5 @@
/* Definitions of target machine for GNU compiler, for ARM with a.out
- Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
+ Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
Contributed by Richard Earnshaw (rearnsha@armltd.co.uk).
This file is part of GNU CC.
@@ -24,6 +24,7 @@ Boston, MA 02111-1307, USA. */
#endif
/* The text to go at the start of the assembler file */
+#ifndef ASM_FILE_START
#define ASM_FILE_START(STREAM) \
{ \
fprintf (STREAM,"%srfp\t.req\t%sr9\n", REGISTER_PREFIX, REGISTER_PREFIX); \
@@ -34,22 +35,35 @@ Boston, MA 02111-1307, USA. */
fprintf (STREAM,"%slr\t.req\t%sr14\n", REGISTER_PREFIX, REGISTER_PREFIX); \
fprintf (STREAM,"%spc\t.req\t%sr15\n", REGISTER_PREFIX, REGISTER_PREFIX); \
}
+#endif
-#define ASM_APP_ON ""
-#define ASM_APP_OFF ""
+#define ASM_APP_ON ""
+#define ASM_APP_OFF ""
/* Switch to the text or data segment. */
-#define TEXT_SECTION_ASM_OP ".text"
-#define DATA_SECTION_ASM_OP ".data"
-#define BSS_SECTION_ASM_OP ".bss"
+#define TEXT_SECTION_ASM_OP ".text"
+#define DATA_SECTION_ASM_OP ".data"
+#define BSS_SECTION_ASM_OP ".bss"
+
+/* Note: If USER_LABEL_PREFIX or LOCAL_LABEL_PREFIX are changed,
+ make sure that this change is reflected in the function
+ coff_arm_is_local_label_name() in bfd/coff-arm.c */
+#ifndef REGISTER_PREFIX
+#define REGISTER_PREFIX ""
+#endif
+
+#ifndef USER_LABEL_PREFIX
+#define USER_LABEL_PREFIX "_"
+#endif
+
+#ifndef LOCAL_LABEL_PREFIX
+#define LOCAL_LABEL_PREFIX ""
+#endif
-#define REGISTER_PREFIX ""
-#define USER_LABEL_PREFIX "_"
-#define LOCAL_LABEL_PREFIX ""
/* The assembler's names for the registers. */
#ifndef REGISTER_NAMES
-#define REGISTER_NAMES \
+#define REGISTER_NAMES \
{ \
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", \
"r8", "r9", "sl", "fp", "ip", "sp", "lr", "pc", \
@@ -104,32 +118,40 @@ Boston, MA 02111-1307, USA. */
``desc'' field is set to compiler version number >= 315 (sic). */
#define DBX_OUTPUT_MAIN_SOURCE_FILENAME(STREAM,NAME) \
do { \
- fprintf (STREAM, ".stabs \"%s\",%d,0,315,%s\n", (NAME), N_SO, \
- &ltext_label_name[1]); \
+ fprintf (STREAM, ".stabs "); \
+ output_quoted_string (STREAM, NAME); \
+ fprintf (STREAM, ",%d,0,315,%s\n", N_SO, &ltext_label_name[1]); \
text_section (); \
ASM_OUTPUT_INTERNAL_LABEL (STREAM, "Ltext", 0); \
} while (0)
/* Output a function label definition. */
-#define ASM_DECLARE_FUNCTION_NAME(STREAM,NAME,DECL) \
- ASM_OUTPUT_LABEL(STREAM, NAME)
+#ifndef ASM_DECLARE_FUNCTION_NAME
+#define ASM_DECLARE_FUNCTION_NAME(STREAM,NAME,DECL) ASM_OUTPUT_LABEL (STREAM, NAME)
+#endif
+#ifndef ASM_OUTPUT_LABEL
#define ASM_OUTPUT_LABEL(STREAM,NAME) \
do { \
assemble_name (STREAM,NAME); \
fputs (":\n", STREAM); \
} while (0)
-
+#endif
+
/* Output a globalising directive for a label. */
+#ifndef ASM_GLOBALIZE_LABEL
#define ASM_GLOBALIZE_LABEL(STREAM,NAME) \
(fprintf (STREAM, "\t.global\t"), \
assemble_name (STREAM, NAME), \
- fputc ('\n',STREAM)) \
+ fputc ('\n',STREAM))
+#endif
/* Make an internal label into a string. */
+#ifndef ASM_GENERATE_INTERNAL_LABEL
#define ASM_GENERATE_INTERNAL_LABEL(STRING, PREFIX, NUM) \
- sprintf (STRING, "*%s%s%d", LOCAL_LABEL_PREFIX, PREFIX, NUM)
-
+ sprintf (STRING, "*%s%s%u", LOCAL_LABEL_PREFIX, PREFIX, (unsigned int)(NUM))
+#endif
+
/* Nothing special is done about jump tables */
/* #define ASM_OUTPUT_CASE_LABEL(STREAM,PREFIX,NUM,TABLE) */
/* #define ASM_OUTPUT_CASE_END(STREAM,NUM,TABLE) */
@@ -196,14 +218,14 @@ do { char dstr[30]; \
output_addr_const (STREAM, (EXP)), \
fputc ('\n', STREAM))
-#define ASM_OUTPUT_BYTE(STREAM, VALUE) \
+#define ASM_OUTPUT_BYTE(STREAM, VALUE) \
fprintf (STREAM, "\t.byte\t%d\n", VALUE)
#define ASM_OUTPUT_ASCII(STREAM, PTR, LEN) \
output_ascii_pseudo_op ((STREAM), (unsigned char *)(PTR), (LEN))
/* Output a gap. In fact we fill it with nulls. */
-#define ASM_OUTPUT_SKIP(STREAM, NBYTES) \
+#define ASM_OUTPUT_SKIP(STREAM, NBYTES) \
fprintf (STREAM, "\t.space\t%d\n", NBYTES)
/* Align output to a power of two. Horrible /bin/as. */
@@ -219,13 +241,18 @@ do { char dstr[30]; \
} while (0)
/* Output a common block */
+#ifndef ASM_OUTPUT_COMMON
#define ASM_OUTPUT_COMMON(STREAM, NAME, SIZE, ROUNDED) \
(fprintf (STREAM, "\t.comm\t"), \
assemble_name ((STREAM), (NAME)), \
- fprintf(STREAM, ", %d\t%s %d\n", ROUNDED, ASM_COMMENT_START, SIZE))
-
+ fprintf (STREAM, ", %d\t%s %d\n", ROUNDED, ASM_COMMENT_START, SIZE))
+#endif
+
/* Output a local common block. /bin/as can't do this, so hack a
- `.space' into the bss segment. Note that this is *bad* practice. */
+ `.space' into the bss segment. Note that this is *bad* practice,
+ which is guaranteed NOT to work since it doesn't define STATIC
+ COMMON space but merely STATIC BSS space. */
+#ifndef ASM_OUTPUT_ALIGNED_LOCAL
#define ASM_OUTPUT_ALIGNED_LOCAL(STREAM,NAME,SIZE,ALIGN) \
do { \
bss_section (); \
@@ -233,27 +260,32 @@ do { char dstr[30]; \
ASM_OUTPUT_LABEL (STREAM, NAME); \
fprintf (STREAM, "\t.space\t%d\n", SIZE); \
} while (0)
-
+#endif
+
/* Output a zero-initialized block. */
+#ifndef ASM_OUTPUT_ALIGNED_BSS
#define ASM_OUTPUT_ALIGNED_BSS(STREAM,DECL,NAME,SIZE,ALIGN) \
- asm_output_aligned_bss(STREAM, DECL, NAME, SIZE, ALIGN)
-
+ asm_output_aligned_bss (STREAM, DECL, NAME, SIZE, ALIGN)
+#endif
+
/* Output a source line for the debugger. */
/* #define ASM_OUTPUT_SOURCE_LINE(STREAM,LINE) */
/* Output a #ident directive. */
+#ifndef ASM_OUTPUT_IDENT
#define ASM_OUTPUT_IDENT(STREAM,STRING) \
- fprintf (STREAM,"- - - ident %s\n",STRING)
-
+ fprintf (STREAM, "%s - - - ident %s\n", ASM_COMMENT_START, STRING)
+#endif
+
/* The assembler's parentheses characters. */
-#define ASM_OPEN_PAREN "("
-#define ASM_CLOSE_PAREN ")"
+#define ASM_OPEN_PAREN "("
+#define ASM_CLOSE_PAREN ")"
#ifndef ASM_COMMENT_START
-#define ASM_COMMENT_START "@"
+#define ASM_COMMENT_START "@"
#endif
/* This works for GAS and some other assemblers. */
-#define SET_ASM_OP ".set"
+#define SET_ASM_OP ".set"
#include "arm/arm.h"
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index a4719c61379..0888c24521f 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -1,8 +1,8 @@
-/* Output routines for GCC for ARM/RISCiX.
- Copyright (C) 1991, 93, 94, 95, 96, 97, 1998 Free Software Foundation, Inc.
+/* Output routines for GCC for ARM.
+ Copyright (C) 1991, 93, 94, 95, 96, 97, 98, 1999 Free Software Foundation, Inc.
Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl)
and Martin Simmons (@harleqn.co.uk).
- More major hacks by Richard Earnshaw (rwe11@cl.cam.ac.uk)
+ More major hacks by Richard Earnshaw (rearnsha@arm.com).
This file is part of GNU CC.
@@ -22,8 +22,7 @@ the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include "config.h"
-#include <stdio.h>
-#include <string.h>
+#include "system.h"
#include "rtl.h"
#include "regs.h"
#include "hard-reg-set.h"
@@ -38,45 +37,42 @@ Boston, MA 02111-1307, USA. */
#include "tree.h"
#include "expr.h"
#include "toplev.h"
+#include "recog.h"
/* The maximum number of insns skipped which will be conditionalised if
possible. */
-#define MAX_INSNS_SKIPPED 5
+static int max_insns_skipped = 5;
+extern FILE * asm_out_file;
/* Some function declarations. */
-extern FILE *asm_out_file;
static HOST_WIDE_INT int_log2 PROTO ((HOST_WIDE_INT));
-static char *output_multi_immediate PROTO ((rtx *, char *, char *, int,
+static char * output_multi_immediate PROTO ((rtx *, char *, char *, int,
HOST_WIDE_INT));
static int arm_gen_constant PROTO ((enum rtx_code, enum machine_mode,
HOST_WIDE_INT, rtx, rtx, int, int));
static int arm_naked_function_p PROTO ((tree));
static void init_fpa_table PROTO ((void));
-static enum machine_mode select_dominance_cc_mode PROTO ((enum rtx_code, rtx,
- rtx, HOST_WIDE_INT));
+static enum machine_mode select_dominance_cc_mode PROTO ((rtx, rtx,
+ HOST_WIDE_INT));
static HOST_WIDE_INT add_constant PROTO ((rtx, enum machine_mode, int *));
static void dump_table PROTO ((rtx));
static int fixit PROTO ((rtx, enum machine_mode, int));
static rtx find_barrier PROTO ((rtx, int));
static int broken_move PROTO ((rtx));
-static char *fp_const_from_val PROTO ((REAL_VALUE_TYPE *));
+static char * fp_const_from_val PROTO ((REAL_VALUE_TYPE *));
static int eliminate_lr2ip PROTO ((rtx *));
-static char *shift_op PROTO ((rtx, HOST_WIDE_INT *));
+static char * shift_op PROTO ((rtx, HOST_WIDE_INT *));
static int pattern_really_clobbers_lr PROTO ((rtx));
static int function_really_clobbers_lr PROTO ((rtx));
static void emit_multi_reg_push PROTO ((int));
static void emit_sfm PROTO ((int, int));
static enum arm_cond_code get_arm_condition_code PROTO ((rtx));
+static int const_ok_for_op RTX_CODE_PROTO ((Hint, Rcode));
/* Define the information needed to generate branch insns. This is
stored from the compare operation. */
-
rtx arm_compare_op0, arm_compare_op1;
-int arm_compare_fp;
-
-/* What type of cpu are we compiling for? */
-enum processor_type arm_cpu;
/* What type of floating point are we tuning for? */
enum floating_point_type arm_fpu;
@@ -88,7 +84,32 @@ enum floating_point_type arm_fpu_arch;
enum prog_mode_type arm_prgmode;
/* Set by the -mfp=... option */
-char *target_fp_name = NULL;
+char * target_fp_name = NULL;
+
+/* Used to parse -mstructure_size_boundary command line option. */
+char * structure_size_string = NULL;
+int arm_structure_size_boundary = 32; /* Used to be 8 */
+
+/* Bit values used to identify processor capabilities. */
+#define FL_CO_PROC 0x01 /* Has external co-processor bus */
+#define FL_FAST_MULT 0x02 /* Fast multiply */
+#define FL_MODE26 0x04 /* 26-bit mode support */
+#define FL_MODE32 0x08 /* 32-bit mode support */
+#define FL_ARCH4 0x10 /* Architecture rel 4 */
+#define FL_THUMB 0x20 /* Thumb aware */
+#define FL_LDSCHED 0x40 /* Load scheduling necessary */
+#define FL_STRONG 0x80 /* StrongARM */
+
+/* The bits in this mask specify which instructions we are allowed to generate. */
+static int insn_flags = 0;
+/* The bits in this mask specify which instruction scheduling options should
+ be used. Note - there is an overlap with the FL_FAST_MULT. For some
+ hardware we want to be able to generate the multiply instructions, but to
+ tune as if they were not present in the architecture. */
+static int tune_flags = 0;
+
+/* The following are used in the arm.md file as equivalents to bits
+ in the above two flag variables. */
/* Nonzero if this is an "M" variant of the processor. */
int arm_fast_multiply = 0;
@@ -96,8 +117,14 @@ int arm_fast_multiply = 0;
/* Nonzero if this chip supports the ARM Architecture 4 extensions */
int arm_arch4 = 0;
-/* Set to the features we should tune the code for (multiply speed etc). */
-int tune_flags = 0;
+/* Nonzero if this chip can benefit from load scheduling. */
+int arm_ld_sched = 0;
+
+/* Nonzero if this chip is a StrongARM. */
+int arm_is_strong = 0;
+
+/* Nonzero if this chip is a an ARM6 or an ARM7. */
+int arm_is_6_or_7 = 0;
/* In case of a PRE_INC, POST_INC, PRE_DEC, POST_DEC memory reference, we
must report the mode of the memory reference from PRINT_OPERAND to
@@ -119,9 +146,13 @@ int lr_save_eliminated;
/* Set to 1 when a return insn is output, this means that the epilogue
is not needed. */
-
static int return_used_this_function;
+/* Set to 1 after arm_reorg has started. Reset to start at the start of
+ the next function. */
+static int after_arm_reorg = 0;
+
+/* The maximum number of insns to be used when loading a constant. */
static int arm_constant_limit = 3;
/* For an explanation of these variables, see final_prescan_insn below. */
@@ -131,7 +162,7 @@ rtx arm_target_insn;
int arm_target_label;
/* The condition codes of the ARM, and the inverse function. */
-char *arm_condition_codes[] =
+char * arm_condition_codes[] =
{
"eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
"hi", "ls", "ge", "lt", "gt", "le", "al", "nv"
@@ -139,141 +170,133 @@ char *arm_condition_codes[] =
static enum arm_cond_code get_arm_condition_code ();
+#define streq(string1, string2) (strcmp (string1, string2) == 0)
/* Initialization code */
-struct arm_cpu_select arm_select[4] =
-{
- /* switch name, tune arch */
- { (char *)0, "--with-cpu=", 1, 1 },
- { (char *)0, "-mcpu=", 1, 1 },
- { (char *)0, "-march=", 0, 1 },
- { (char *)0, "-mtune=", 1, 0 },
-};
-
-#define FL_CO_PROC 0x01 /* Has external co-processor bus */
-#define FL_FAST_MULT 0x02 /* Fast multiply */
-#define FL_MODE26 0x04 /* 26-bit mode support */
-#define FL_MODE32 0x08 /* 32-bit mode support */
-#define FL_ARCH4 0x10 /* Architecture rel 4 */
-#define FL_THUMB 0x20 /* Thumb aware */
-
struct processors
{
- char *name;
- enum processor_type type;
+ char * name;
unsigned int flags;
};
/* Not all of these give usefully different compilation alternatives,
but there is no simple way of generalizing them. */
-static struct processors all_procs[] =
+static struct processors all_cores[] =
{
- {"arm2", PROCESSOR_ARM2, FL_CO_PROC | FL_MODE26},
- {"arm250", PROCESSOR_ARM2, FL_CO_PROC | FL_MODE26},
- {"arm3", PROCESSOR_ARM2, FL_CO_PROC | FL_MODE26},
- {"arm6", PROCESSOR_ARM6, FL_CO_PROC | FL_MODE32 | FL_MODE26},
- {"arm600", PROCESSOR_ARM6, FL_CO_PROC | FL_MODE32 | FL_MODE26},
- {"arm610", PROCESSOR_ARM6, FL_MODE32 | FL_MODE26},
- {"arm7", PROCESSOR_ARM7, FL_CO_PROC | FL_MODE32 | FL_MODE26},
- /* arm7m doesn't exist on its own, only in conjunction with D, (and I), but
- those don't alter the code, so it is sometimes known as the arm7m */
- {"arm7m", PROCESSOR_ARM7, (FL_CO_PROC | FL_FAST_MULT | FL_MODE32
- | FL_MODE26)},
- {"arm7dm", PROCESSOR_ARM7, (FL_CO_PROC | FL_FAST_MULT | FL_MODE32
- | FL_MODE26)},
- {"arm7dmi", PROCESSOR_ARM7, (FL_CO_PROC | FL_FAST_MULT | FL_MODE32
- | FL_MODE26)},
- {"arm700", PROCESSOR_ARM7, FL_CO_PROC | FL_MODE32 | FL_MODE26},
- {"arm710", PROCESSOR_ARM7, FL_MODE32 | FL_MODE26},
- {"arm7100", PROCESSOR_ARM7, FL_MODE32 | FL_MODE26},
- {"arm7500", PROCESSOR_ARM7, FL_MODE32 | FL_MODE26},
- /* Doesn't really have an external co-proc, but does have embedded fpu */
- {"arm7500fe", PROCESSOR_ARM7, FL_CO_PROC | FL_MODE32 | FL_MODE26},
- {"arm7tdmi", PROCESSOR_ARM7, (FL_CO_PROC | FL_FAST_MULT | FL_MODE32
- | FL_ARCH4 | FL_THUMB)},
- {"arm8", PROCESSOR_ARM8, (FL_FAST_MULT | FL_MODE32 | FL_MODE26
- | FL_ARCH4)},
- {"arm810", PROCESSOR_ARM8, (FL_FAST_MULT | FL_MODE32 | FL_MODE26
- | FL_ARCH4)},
- {"strongarm", PROCESSOR_STARM, (FL_FAST_MULT | FL_MODE32 | FL_MODE26
- | FL_ARCH4)},
- {"strongarm110", PROCESSOR_STARM, (FL_FAST_MULT | FL_MODE32 | FL_MODE26
- | FL_ARCH4)},
- {"armv2", PROCESSOR_NONE, FL_CO_PROC | FL_MODE26},
- {"armv2a", PROCESSOR_NONE, FL_CO_PROC | FL_MODE26},
- {"armv3", PROCESSOR_NONE, FL_CO_PROC | FL_MODE32 | FL_MODE26},
- {"armv3m", PROCESSOR_NONE, (FL_CO_PROC | FL_FAST_MULT | FL_MODE32
- | FL_MODE26)},
- {"armv4", PROCESSOR_NONE, (FL_CO_PROC | FL_FAST_MULT | FL_MODE32
- | FL_MODE26 | FL_ARCH4)},
+ /* ARM Cores */
+
+ {"arm2", FL_CO_PROC | FL_MODE26 },
+ {"arm250", FL_CO_PROC | FL_MODE26 },
+ {"arm3", FL_CO_PROC | FL_MODE26 },
+ {"arm6", FL_CO_PROC | FL_MODE26 | FL_MODE32 },
+ {"arm60", FL_CO_PROC | FL_MODE26 | FL_MODE32 },
+ {"arm600", FL_CO_PROC | FL_MODE26 | FL_MODE32 },
+ {"arm610", FL_MODE26 | FL_MODE32 },
+ {"arm620", FL_CO_PROC | FL_MODE26 | FL_MODE32 },
+ {"arm7", FL_CO_PROC | FL_MODE26 | FL_MODE32 },
+ {"arm7m", FL_CO_PROC | FL_MODE26 | FL_MODE32 | FL_FAST_MULT }, /* arm7m doesn't exist on its own, */
+ {"arm7d", FL_CO_PROC | FL_MODE26 | FL_MODE32 }, /* but only with D, (and I), */
+ {"arm7dm", FL_CO_PROC | FL_MODE26 | FL_MODE32 | FL_FAST_MULT }, /* but those don't alter the code, */
+ {"arm7di", FL_CO_PROC | FL_MODE26 | FL_MODE32 }, /* so arm7m is sometimes used. */
+ {"arm7dmi", FL_CO_PROC | FL_MODE26 | FL_MODE32 | FL_FAST_MULT },
+ {"arm70", FL_CO_PROC | FL_MODE26 | FL_MODE32 },
+ {"arm700", FL_CO_PROC | FL_MODE26 | FL_MODE32 },
+ {"arm700i", FL_CO_PROC | FL_MODE26 | FL_MODE32 },
+ {"arm710", FL_MODE26 | FL_MODE32 },
+ {"arm710c", FL_MODE26 | FL_MODE32 },
+ {"arm7100", FL_MODE26 | FL_MODE32 },
+ {"arm7500", FL_MODE26 | FL_MODE32 },
+ {"arm7500fe", FL_CO_PROC | FL_MODE26 | FL_MODE32 }, /* Doesn't really have an external co-proc, but does have embedded fpu. */
+ {"arm7tdmi", FL_CO_PROC | FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB },
+ {"arm8", FL_MODE26 | FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_LDSCHED },
+ {"arm810", FL_MODE26 | FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_LDSCHED },
+ {"arm9", FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB | FL_LDSCHED },
+ {"arm9tdmi", FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB | FL_LDSCHED },
+ {"strongarm", FL_MODE26 | FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_LDSCHED | FL_STRONG },
+ {"strongarm110", FL_MODE26 | FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_LDSCHED | FL_STRONG },
+ {"strongarm1100", FL_MODE26 | FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_LDSCHED | FL_STRONG },
+
+ {NULL, 0}
+};
+
+static struct processors all_architectures[] =
+{
+ /* ARM Architectures */
+
+ {"armv2", FL_CO_PROC | FL_MODE26 },
+ {"armv2a", FL_CO_PROC | FL_MODE26 },
+ {"armv3", FL_CO_PROC | FL_MODE26 | FL_MODE32 },
+ {"armv3m", FL_CO_PROC | FL_MODE26 | FL_MODE32 | FL_FAST_MULT },
+ {"armv4", FL_CO_PROC | FL_MODE26 | FL_MODE32 | FL_FAST_MULT | FL_ARCH4 },
/* Strictly, FL_MODE26 is a permitted option for v4t, but there are no
implementations that support it, so we will leave it out for now. */
- {"armv4t", PROCESSOR_NONE, (FL_CO_PROC | FL_FAST_MULT | FL_MODE32
- | FL_ARCH4)},
- {NULL, 0, 0}
+ {"armv4t", FL_CO_PROC | FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB },
+ {NULL, 0}
+};
+
+/* This is a magic stucture. The 'string' field is magically filled in
+ with a pointer to the value specified by the user on the command line
+ assuming that the user has specified such a value. */
+
+struct arm_cpu_select arm_select[] =
+{
+ /* string name processors */
+ { NULL, "-mcpu=", all_cores },
+ { NULL, "-march=", all_architectures },
+ { NULL, "-mtune=", all_cores }
};
+/* Return the number of bits set in value' */
+static unsigned int
+bit_count (value)
+ signed int value;
+{
+ unsigned int count = 0;
+
+ while (value)
+ {
+ value &= ~(value & - value);
+ ++ count;
+ }
+
+ return count;
+}
+
/* Fix up any incompatible options that the user has specified.
This has now turned into a maze. */
void
arm_override_options ()
{
- int arm_thumb_aware = 0;
- int flags = 0;
unsigned i;
- struct arm_cpu_select *ptr;
- static struct cpu_default {
- int cpu;
- char *name;
- } cpu_defaults[] = {
- { TARGET_CPU_arm2, "arm2" },
- { TARGET_CPU_arm6, "arm6" },
- { TARGET_CPU_arm610, "arm610" },
- { TARGET_CPU_arm7dm, "arm7dm" },
- { TARGET_CPU_arm7500fe, "arm7500fe" },
- { TARGET_CPU_arm7tdmi, "arm7tdmi" },
- { TARGET_CPU_arm8, "arm8" },
- { TARGET_CPU_arm810, "arm810" },
- { TARGET_CPU_strongarm, "strongarm" },
- { 0, 0 }
- };
- struct cpu_default *def;
-
- /* Set the default. */
- for (def = &cpu_defaults[0]; def->name; ++def)
- if (def->cpu == TARGET_CPU_DEFAULT)
- break;
- if (! def->name)
- abort ();
-
- arm_select[0].string = def->name;
-
- for (i = 0; i < sizeof (arm_select) / sizeof (arm_select[0]); i++)
+
+ /* Set up the flags based on the cpu/architecture selected by the user. */
+ for (i = sizeof (arm_select) / sizeof (arm_select[0]); i--;)
{
- ptr = &arm_select[i];
- if (ptr->string != (char *)0 && ptr->string[0] != '\0')
+ struct arm_cpu_select * ptr = arm_select + i;
+
+ if (ptr->string != NULL && ptr->string[0] != '\0')
{
- struct processors *sel;
+ struct processors * sel;
- for (sel = all_procs; sel->name != NULL; sel++)
- if (! strcmp (ptr->string, sel->name))
+ for (sel = ptr->processors; sel->name != NULL; sel ++)
+ if (streq (ptr->string, sel->name))
{
- /* -march= is the only flag that can take an architecture
- type, so if we match when the tune bit is set, the
- option was invalid. */
- if (ptr->set_tune_p)
+ if (i == 2)
+ tune_flags = sel->flags;
+ else
{
- if (sel->type == PROCESSOR_NONE)
- continue; /* Its an architecture, not a cpu */
-
- arm_cpu = sel->type;
- tune_flags = sel->flags;
+ /* If we have been given an architecture and a processor
+ make sure that they are compatible. We only generate
+ a warning though, and we prefer the CPU over the
+ architecture. */
+ if (insn_flags != 0 && (insn_flags ^ sel->flags))
+ warning ("switch -mcpu=%s conflicts with -mtune= switch",
+ ptr->string);
+
+ insn_flags = sel->flags;
}
-
- if (ptr->set_arch_p)
- flags = sel->flags;
-
+
break;
}
@@ -281,108 +304,282 @@ arm_override_options ()
error ("bad value (%s) for %s switch", ptr->string, ptr->name);
}
}
+
+ /* If the user did not specify a processor, choose one for them. */
+ if (insn_flags == 0)
+ {
+ struct processors * sel;
+ unsigned int sought;
+ static struct cpu_default
+ {
+ int cpu;
+ char * name;
+ }
+ cpu_defaults[] =
+ {
+ { TARGET_CPU_arm2, "arm2" },
+ { TARGET_CPU_arm6, "arm6" },
+ { TARGET_CPU_arm610, "arm610" },
+ { TARGET_CPU_arm710, "arm710" },
+ { TARGET_CPU_arm7m, "arm7m" },
+ { TARGET_CPU_arm7500fe, "arm7500fe" },
+ { TARGET_CPU_arm7tdmi, "arm7tdmi" },
+ { TARGET_CPU_arm8, "arm8" },
+ { TARGET_CPU_arm810, "arm810" },
+ { TARGET_CPU_arm9, "arm9" },
+ { TARGET_CPU_strongarm, "strongarm" },
+ { TARGET_CPU_generic, "arm" },
+ { 0, 0 }
+ };
+ struct cpu_default * def;
+
+ /* Find the default. */
+ for (def = cpu_defaults; def->name; def ++)
+ if (def->cpu == TARGET_CPU_DEFAULT)
+ break;
- if (write_symbols != NO_DEBUG && flag_omit_frame_pointer)
- warning ("-g with -fomit-frame-pointer may not give sensible debugging");
+ /* Make sure we found the default CPU. */
+ if (def->name == NULL)
+ abort ();
+
+ /* Find the default CPU's flags. */
+ for (sel = all_cores; sel->name != NULL; sel ++)
+ if (streq (def->name, sel->name))
+ break;
+
+ if (sel->name == NULL)
+ abort ();
- if (TARGET_POKE_FUNCTION_NAME)
- target_flags |= ARM_FLAG_APCS_FRAME;
+ insn_flags = sel->flags;
+
+ /* Now check to see if the user has specified some command line
+ switch that require certain abilities from the cpu. */
+ sought = 0;
+
+ if (TARGET_THUMB_INTERWORK)
+ {
+ sought |= (FL_THUMB | FL_MODE32);
+
+ /* Force apcs-32 to be used for interworking. */
+ target_flags |= ARM_FLAG_APCS_32;
+
+ /* There are no ARM processor that supports both APCS-26 and
+ interworking. Therefore we force FL_MODE26 to be removed
+ from insn_flags here (if it was set), so that the search
+ below will always be able to find a compatible processor. */
+ insn_flags &= ~ FL_MODE26;
+ }
+
+ if (! TARGET_APCS_32)
+ sought |= FL_MODE26;
+
+ if (sought != 0 && ((sought & insn_flags) != sought))
+ {
+ /* Try to locate a CPU type that supports all of the abilities
+ of the default CPU, plus the extra abilities requested by
+ the user. */
+ for (sel = all_cores; sel->name != NULL; sel ++)
+ if ((sel->flags & sought) == (sought | insn_flags))
+ break;
+
+ if (sel->name == NULL)
+ {
+ unsigned int current_bit_count = 0;
+ struct processors * best_fit = NULL;
+
+ /* Ideally we would like to issue an error message here
+ saying that it was not possible to find a CPU compatible
+ with the default CPU, but which also supports the command
+ line options specified by the programmer, and so they
+ ought to use the -mcpu=<name> command line option to
+ override the default CPU type.
+
+ Unfortunately this does not work with multilibing. We
+ need to be able to support multilibs for -mapcs-26 and for
+ -mthumb-interwork and there is no CPU that can support both
+ options. Instead if we cannot find a cpu that has both the
+ characteristics of the default cpu and the given command line
+ options we scan the array again looking for a best match. */
+ for (sel = all_cores; sel->name != NULL; sel ++)
+ if ((sel->flags & sought) == sought)
+ {
+ unsigned int count;
- if (TARGET_6)
- warning ("Option '-m6' deprecated. Use: '-mapcs-32' or -mcpu=<proc>");
+ count = bit_count (sel->flags & insn_flags);
+
+ if (count >= current_bit_count)
+ {
+ best_fit = sel;
+ current_bit_count = count;
+ }
+ }
- if (TARGET_3)
- warning ("Option '-m3' deprecated. Use: '-mapcs-26' or -mcpu=<proc>");
+ if (best_fit == NULL)
+ abort ();
+ else
+ sel = best_fit;
+ }
+ insn_flags = sel->flags;
+ }
+ }
+
+ /* If tuning has not been specified, tune for whichever processor or
+ architecture has been selected. */
+ if (tune_flags == 0)
+ tune_flags = insn_flags;
+
+ /* Make sure that the processor choice does not conflict with any of the
+ other command line choices. */
+ if (TARGET_APCS_32 && !(insn_flags & FL_MODE32))
+ {
+ /* If APCS-32 was not the default then it must have been set by the
+ user, so issue a warning message. If the user has specified
+ "-mapcs-32 -mcpu=arm2" then we loose here. */
+ if ((TARGET_DEFAULT & ARM_FLAG_APCS_32) == 0)
+ warning ("target CPU does not support APCS-32" );
+ target_flags &= ~ ARM_FLAG_APCS_32;
+ }
+ else if (! TARGET_APCS_32 && !(insn_flags & FL_MODE26))
+ {
+ warning ("target CPU does not support APCS-26" );
+ target_flags |= ARM_FLAG_APCS_32;
+ }
+
+ if (TARGET_THUMB_INTERWORK && !(insn_flags & FL_THUMB))
+ {
+ warning ("target CPU does not support interworking" );
+ target_flags &= ~ARM_FLAG_THUMB;
+ }
+
+ /* If interworking is enabled then APCS-32 must be selected as well. */
+ if (TARGET_THUMB_INTERWORK)
+ {
+ if (! TARGET_APCS_32)
+ warning ("interworking forces APCS-32 to be used" );
+ target_flags |= ARM_FLAG_APCS_32;
+ }
+
+ if (TARGET_APCS_STACK && ! TARGET_APCS)
+ {
+ warning ("-mapcs-stack-check incompatible with -mno-apcs-frame");
+ target_flags |= ARM_FLAG_APCS_FRAME;
+ }
+
+ if (write_symbols != NO_DEBUG && flag_omit_frame_pointer)
+ warning ("-g with -fomit-frame-pointer may not give sensible debugging");
+
+ if (TARGET_POKE_FUNCTION_NAME)
+ target_flags |= ARM_FLAG_APCS_FRAME;
+
if (TARGET_APCS_REENT && flag_pic)
fatal ("-fpic and -mapcs-reent are incompatible");
-
+
if (TARGET_APCS_REENT)
- warning ("APCS reentrant code not supported.");
-
+ warning ("APCS reentrant code not supported. Ignored");
+
/* If stack checking is disabled, we can use r10 as the PIC register,
which keeps r9 available. */
if (flag_pic && ! TARGET_APCS_STACK)
arm_pic_register = 10;
-
+
/* Well, I'm about to have a go, but pic is NOT going to be compatible
with APCS reentrancy, since that requires too much support in the
assembler and linker, and the ARMASM assembler seems to lack some
required directives. */
if (flag_pic)
warning ("Position independent code not supported");
-
+
if (TARGET_APCS_FLOAT)
warning ("Passing floating point arguments in fp regs not yet supported");
-
- if (TARGET_APCS_STACK && ! TARGET_APCS)
- {
- warning ("-mapcs-stack-check incompatible with -mno-apcs-frame");
- target_flags |= ARM_FLAG_APCS_FRAME;
- }
-
- /* Default is to tune for an FPA */
- arm_fpu = FP_HARD;
-
+
+ /* Initialise boolean versions of the flags, for use in the arm.md file. */
+ arm_fast_multiply = insn_flags & FL_FAST_MULT;
+ arm_arch4 = insn_flags & FL_ARCH4;
+
+ arm_ld_sched = tune_flags & FL_LDSCHED;
+ arm_is_strong = tune_flags & FL_STRONG;
+ arm_is_6_or_7 = ((tune_flags & (FL_MODE26 | FL_MODE32))
+ && !(tune_flags & FL_ARCH4));
+
/* Default value for floating point code... if no co-processor
bus, then schedule for emulated floating point. Otherwise,
assume the user has an FPA.
Note: this does not prevent use of floating point instructions,
-msoft-float does that. */
- if ((tune_flags & FL_CO_PROC) == 0)
- arm_fpu = FP_SOFT3;
-
- arm_fast_multiply = (flags & FL_FAST_MULT) != 0;
- arm_arch4 = (flags & FL_ARCH4) != 0;
- arm_thumb_aware = (flags & FL_THUMB) != 0;
-
+ arm_fpu = (tune_flags & FL_CO_PROC) ? FP_HARD : FP_SOFT3;
+
if (target_fp_name)
{
- if (strcmp (target_fp_name, "2") == 0)
+ if (streq (target_fp_name, "2"))
arm_fpu_arch = FP_SOFT2;
- else if (strcmp (target_fp_name, "3") == 0)
- arm_fpu_arch = FP_HARD;
+ else if (streq (target_fp_name, "3"))
+ arm_fpu_arch = FP_SOFT3;
else
- fatal ("Invalid floating point emulation option: -mfpe=%s",
+ fatal ("Invalid floating point emulation option: -mfpe-%s",
target_fp_name);
}
else
arm_fpu_arch = FP_DEFAULT;
-
- if (TARGET_THUMB_INTERWORK && ! arm_thumb_aware)
- {
- warning ("This processor variant does not support Thumb interworking");
- target_flags &= ~ARM_FLAG_THUMB;
- }
-
+
if (TARGET_FPE && arm_fpu != FP_HARD)
arm_fpu = FP_SOFT2;
-
+
/* For arm2/3 there is no need to do any scheduling if there is only
a floating point emulator, or we are doing software floating-point. */
- if ((TARGET_SOFT_FLOAT || arm_fpu != FP_HARD) && arm_cpu == PROCESSOR_ARM2)
+ if ((TARGET_SOFT_FLOAT || arm_fpu != FP_HARD) && (tune_flags & FL_MODE32) == 0)
flag_schedule_insns = flag_schedule_insns_after_reload = 0;
-
+
arm_prog_mode = TARGET_APCS_32 ? PROG_MODE_PROG32 : PROG_MODE_PROG26;
+
+ if (structure_size_string != NULL)
+ {
+ int size = strtol (structure_size_string, NULL, 0);
+
+ if (size == 8 || size == 32)
+ arm_structure_size_boundary = size;
+ else
+ warning ("Structure size boundary can only be set to 8 or 32");
+ }
+
+ /* If optimizing for space, don't synthesize constants.
+ For processors with load scheduling, it never costs more than 2 cycles
+ to load a constant, and the load scheduler may well reduce that to 1. */
+ if (optimize_size || (tune_flags & FL_LDSCHED))
+ arm_constant_limit = 1;
+
+ /* If optimizing for size, bump the number of instructions that we
+ are prepared to conditionally execute (even on a StrongARM).
+ Otherwise for the StrongARM, which has early execution of branches,
+ a sequence that is worth skipping is shorter. */
+ if (optimize_size)
+ max_insns_skipped = 6;
+ else if (arm_is_strong)
+ max_insns_skipped = 3;
}
-
/* Return 1 if it is possible to return using a single instruction */
int
-use_return_insn ()
+use_return_insn (iscond)
+ int iscond;
{
int regno;
- if (!reload_completed ||current_function_pretend_args_size
+ if (!reload_completed
+ || current_function_pretend_args_size
|| current_function_anonymous_args
|| ((get_frame_size () + current_function_outgoing_args_size != 0)
- && !(TARGET_APCS || frame_pointer_needed)))
+ && !(TARGET_APCS && frame_pointer_needed)))
return 0;
/* Can't be done if interworking with Thumb, and any registers have been
- stacked */
- if (TARGET_THUMB_INTERWORK)
+ stacked. Similarly, on StrongARM, conditional returns are expensive
+ if they aren't taken and registers have been stacked. */
+ if (iscond && arm_is_strong && frame_pointer_needed)
+ return 0;
+ if ((iscond && arm_is_strong)
+ || TARGET_THUMB_INTERWORK)
for (regno = 0; regno < 16; regno++)
if (regs_ever_live[regno] && ! call_used_regs[regno])
return 0;
@@ -433,11 +630,10 @@ const_ok_for_arm (i)
}
/* Return true if I is a valid constant for the operation CODE. */
-int
-const_ok_for_op (i, code, mode)
+static int
+const_ok_for_op (i, code)
HOST_WIDE_INT i;
enum rtx_code code;
- enum machine_mode mode;
{
if (const_ok_for_arm (i))
return 1;
@@ -483,29 +679,39 @@ arm_split_constant (code, mode, val, target, source, subtargets)
|| (GET_CODE (target) == REG && GET_CODE (source) == REG
&& REGNO (target) != REGNO (source)))
{
- if (arm_gen_constant (code, mode, val, target, source, 1, 0)
- > arm_constant_limit + (code != SET))
+ /* After arm_reorg has been called, we can't fix up expensive
+ constants by pushing them into memory so we must synthesise
+ them in-line, regardless of the cost. This is only likely to
+ be more costly on chips that have load delay slots and we are
+ compiling without running the scheduler (so no splitting
+ occurred before the final instruction emission).
+
+ Ref: gcc -O1 -mcpu=strongarm gcc.c-torture/compile/980506-2.c
+ */
+ if (! after_arm_reorg
+ && (arm_gen_constant (code, mode, val, target, source, 1, 0)
+ > arm_constant_limit + (code != SET)))
{
if (code == SET)
{
/* Currently SET is the only monadic value for CODE, all
the rest are diadic. */
- emit_insn (gen_rtx (SET, VOIDmode, target, GEN_INT (val)));
+ emit_insn (gen_rtx_SET (VOIDmode, target, GEN_INT (val)));
return 1;
}
else
{
rtx temp = subtargets ? gen_reg_rtx (mode) : target;
- emit_insn (gen_rtx (SET, VOIDmode, temp, GEN_INT (val)));
+ emit_insn (gen_rtx_SET (VOIDmode, temp, GEN_INT (val)));
/* For MINUS, the value is subtracted from, since we never
have subtraction of a constant. */
if (code == MINUS)
- emit_insn (gen_rtx (SET, VOIDmode, target,
- gen_rtx (code, mode, temp, source)));
+ emit_insn (gen_rtx_SET (VOIDmode, target,
+ gen_rtx (code, mode, temp, source)));
else
- emit_insn (gen_rtx (SET, VOIDmode, target,
- gen_rtx (code, mode, source, temp)));
+ emit_insn (gen_rtx_SET (VOIDmode, target,
+ gen_rtx (code, mode, source, temp)));
return 2;
}
}
@@ -560,8 +766,8 @@ arm_gen_constant (code, mode, val, target, source, subtargets, generate)
if (remainder == 0xffffffff)
{
if (generate)
- emit_insn (gen_rtx (SET, VOIDmode, target,
- GEN_INT (ARM_SIGN_EXTEND (val))));
+ emit_insn (gen_rtx_SET (VOIDmode, target,
+ GEN_INT (ARM_SIGN_EXTEND (val))));
return 1;
}
if (remainder == 0)
@@ -569,7 +775,7 @@ arm_gen_constant (code, mode, val, target, source, subtargets, generate)
if (reload_completed && rtx_equal_p (target, source))
return 0;
if (generate)
- emit_insn (gen_rtx (SET, VOIDmode, target, source));
+ emit_insn (gen_rtx_SET (VOIDmode, target, source));
return 1;
}
break;
@@ -578,7 +784,7 @@ arm_gen_constant (code, mode, val, target, source, subtargets, generate)
if (remainder == 0)
{
if (generate)
- emit_insn (gen_rtx (SET, VOIDmode, target, const0_rtx));
+ emit_insn (gen_rtx_SET (VOIDmode, target, const0_rtx));
return 1;
}
if (remainder == 0xffffffff)
@@ -586,7 +792,7 @@ arm_gen_constant (code, mode, val, target, source, subtargets, generate)
if (reload_completed && rtx_equal_p (target, source))
return 0;
if (generate)
- emit_insn (gen_rtx (SET, VOIDmode, target, source));
+ emit_insn (gen_rtx_SET (VOIDmode, target, source));
return 1;
}
can_invert = 1;
@@ -598,14 +804,14 @@ arm_gen_constant (code, mode, val, target, source, subtargets, generate)
if (reload_completed && rtx_equal_p (target, source))
return 0;
if (generate)
- emit_insn (gen_rtx (SET, VOIDmode, target, source));
+ emit_insn (gen_rtx_SET (VOIDmode, target, source));
return 1;
}
if (remainder == 0xffffffff)
{
if (generate)
- emit_insn (gen_rtx (SET, VOIDmode, target,
- gen_rtx (NOT, mode, source)));
+ emit_insn (gen_rtx_SET (VOIDmode, target,
+ gen_rtx_NOT (mode, source)));
return 1;
}
@@ -618,15 +824,16 @@ arm_gen_constant (code, mode, val, target, source, subtargets, generate)
if (remainder == 0)
{
if (generate)
- emit_insn (gen_rtx (SET, VOIDmode, target,
- gen_rtx (NEG, mode, source)));
+ emit_insn (gen_rtx_SET (VOIDmode, target,
+ gen_rtx_NEG (mode, source)));
return 1;
}
if (const_ok_for_arm (val))
{
if (generate)
- emit_insn (gen_rtx (SET, VOIDmode, target,
- gen_rtx (MINUS, mode, GEN_INT (val), source)));
+ emit_insn (gen_rtx_SET (VOIDmode, target,
+ gen_rtx_MINUS (mode, GEN_INT (val),
+ source)));
return 1;
}
can_negate = 1;
@@ -643,10 +850,10 @@ arm_gen_constant (code, mode, val, target, source, subtargets, generate)
|| (can_invert && const_ok_for_arm (~val)))
{
if (generate)
- emit_insn (gen_rtx (SET, VOIDmode, target,
- (source ? gen_rtx (code, mode, source,
- GEN_INT (val))
- : GEN_INT (val))));
+ emit_insn (gen_rtx_SET (VOIDmode, target,
+ (source ? gen_rtx (code, mode, source,
+ GEN_INT (val))
+ : GEN_INT (val))));
return 1;
}
@@ -701,8 +908,8 @@ arm_gen_constant (code, mode, val, target, source, subtargets, generate)
if (generate)
{
rtx new_src = subtargets ? gen_reg_rtx (mode) : target;
- emit_insn (gen_rtx (SET, VOIDmode, new_src,
- GEN_INT (temp1)));
+ emit_insn (gen_rtx_SET (VOIDmode, new_src,
+ GEN_INT (temp1)));
emit_insn (gen_ashrsi3 (target, new_src,
GEN_INT (set_sign_bit_copies - 1)));
}
@@ -716,8 +923,8 @@ arm_gen_constant (code, mode, val, target, source, subtargets, generate)
if (generate)
{
rtx new_src = subtargets ? gen_reg_rtx (mode) : target;
- emit_insn (gen_rtx (SET, VOIDmode, new_src,
- GEN_INT (temp1)));
+ emit_insn (gen_rtx_SET (VOIDmode, new_src,
+ GEN_INT (temp1)));
emit_insn (gen_ashrsi3 (target, new_src,
GEN_INT (set_sign_bit_copies - 1)));
}
@@ -748,11 +955,12 @@ arm_gen_constant (code, mode, val, target, source, subtargets, generate)
source, subtargets, generate);
source = new_src;
if (generate)
- emit_insn (gen_rtx (SET, VOIDmode, target,
- gen_rtx (IOR, mode,
- gen_rtx (ASHIFT, mode, source,
- GEN_INT (i)),
- source)));
+ emit_insn (gen_rtx_SET
+ (VOIDmode, target,
+ gen_rtx_IOR (mode,
+ gen_rtx_ASHIFT (mode, source,
+ GEN_INT (i)),
+ source)));
return insns + 1;
}
}
@@ -770,11 +978,13 @@ arm_gen_constant (code, mode, val, target, source, subtargets, generate)
source, subtargets, generate);
source = new_src;
if (generate)
- emit_insn (gen_rtx (SET, VOIDmode, target,
- gen_rtx (IOR, mode,
- gen_rtx (LSHIFTRT, mode,
- source, GEN_INT (i)),
- source)));
+ emit_insn
+ (gen_rtx_SET (VOIDmode, target,
+ gen_rtx_IOR
+ (mode,
+ gen_rtx_LSHIFTRT (mode, source,
+ GEN_INT (i)),
+ source)));
return insns + 1;
}
}
@@ -796,9 +1006,9 @@ arm_gen_constant (code, mode, val, target, source, subtargets, generate)
{
rtx sub = subtargets ? gen_reg_rtx (mode) : target;
- emit_insn (gen_rtx (SET, VOIDmode, sub, GEN_INT (val)));
- emit_insn (gen_rtx (SET, VOIDmode, target,
- gen_rtx (code, mode, source, sub)));
+ emit_insn (gen_rtx_SET (VOIDmode, sub, GEN_INT (val)));
+ emit_insn (gen_rtx_SET (VOIDmode, target,
+ gen_rtx (code, mode, source, sub)));
}
return 2;
}
@@ -815,14 +1025,15 @@ arm_gen_constant (code, mode, val, target, source, subtargets, generate)
rtx sub = subtargets ? gen_reg_rtx (mode) : target;
rtx shift = GEN_INT (set_sign_bit_copies);
- emit_insn (gen_rtx (SET, VOIDmode, sub,
- gen_rtx (NOT, mode,
- gen_rtx (ASHIFT, mode, source,
- shift))));
- emit_insn (gen_rtx (SET, VOIDmode, target,
- gen_rtx (NOT, mode,
- gen_rtx (LSHIFTRT, mode, sub,
- shift))));
+ emit_insn (gen_rtx_SET (VOIDmode, sub,
+ gen_rtx_NOT (mode,
+ gen_rtx_ASHIFT (mode,
+ source,
+ shift))));
+ emit_insn (gen_rtx_SET (VOIDmode, target,
+ gen_rtx_NOT (mode,
+ gen_rtx_LSHIFTRT (mode, sub,
+ shift))));
}
return 2;
}
@@ -835,14 +1046,15 @@ arm_gen_constant (code, mode, val, target, source, subtargets, generate)
rtx sub = subtargets ? gen_reg_rtx (mode) : target;
rtx shift = GEN_INT (set_zero_bit_copies);
- emit_insn (gen_rtx (SET, VOIDmode, sub,
- gen_rtx (NOT, mode,
- gen_rtx (LSHIFTRT, mode, source,
- shift))));
- emit_insn (gen_rtx (SET, VOIDmode, target,
- gen_rtx (NOT, mode,
- gen_rtx (ASHIFT, mode, sub,
- shift))));
+ emit_insn (gen_rtx_SET (VOIDmode, sub,
+ gen_rtx_NOT (mode,
+ gen_rtx_LSHIFTRT (mode,
+ source,
+ shift))));
+ emit_insn (gen_rtx_SET (VOIDmode, target,
+ gen_rtx_NOT (mode,
+ gen_rtx_ASHIFT (mode, sub,
+ shift))));
}
return 2;
}
@@ -852,16 +1064,16 @@ arm_gen_constant (code, mode, val, target, source, subtargets, generate)
if (generate)
{
rtx sub = subtargets ? gen_reg_rtx (mode) : target;
- emit_insn (gen_rtx (SET, VOIDmode, sub,
- gen_rtx (NOT, mode, source)));
+ emit_insn (gen_rtx_SET (VOIDmode, sub,
+ gen_rtx_NOT (mode, source)));
source = sub;
if (subtargets)
sub = gen_reg_rtx (mode);
- emit_insn (gen_rtx (SET, VOIDmode, sub,
- gen_rtx (AND, mode, source,
- GEN_INT (temp1))));
- emit_insn (gen_rtx (SET, VOIDmode, target,
- gen_rtx (NOT, mode, sub)));
+ emit_insn (gen_rtx_SET (VOIDmode, sub,
+ gen_rtx_AND (mode, source,
+ GEN_INT (temp1))));
+ emit_insn (gen_rtx_SET (VOIDmode, target,
+ gen_rtx_NOT (mode, sub)));
}
return 3;
}
@@ -1013,30 +1225,31 @@ arm_gen_constant (code, mode, val, target, source, subtargets, generate)
rtx new_src;
if (code == SET)
- emit_insn (gen_rtx (SET, VOIDmode,
- new_src = (subtargets
- ? gen_reg_rtx (mode)
- : target),
- GEN_INT (can_invert ? ~temp1 : temp1)));
+ emit_insn (gen_rtx_SET (VOIDmode,
+ new_src = (subtargets
+ ? gen_reg_rtx (mode)
+ : target),
+ GEN_INT (can_invert
+ ? ~temp1 : temp1)));
else if (code == MINUS)
- emit_insn (gen_rtx (SET, VOIDmode,
- new_src = (subtargets
- ? gen_reg_rtx (mode)
- : target),
- gen_rtx (code, mode, GEN_INT (temp1),
- source)));
+ emit_insn (gen_rtx_SET (VOIDmode,
+ new_src = (subtargets
+ ? gen_reg_rtx (mode)
+ : target),
+ gen_rtx (code, mode, GEN_INT (temp1),
+ source)));
else
- emit_insn (gen_rtx (SET, VOIDmode,
- new_src = (remainder
- ? (subtargets
- ? gen_reg_rtx (mode)
- : target)
- : target),
- gen_rtx (code, mode, source,
- GEN_INT (can_invert ? ~temp1
- : (can_negate
- ? -temp1
- : temp1)))));
+ emit_insn (gen_rtx_SET (VOIDmode,
+ new_src = (remainder
+ ? (subtargets
+ ? gen_reg_rtx (mode)
+ : target)
+ : target),
+ gen_rtx (code, mode, source,
+ GEN_INT (can_invert ? ~temp1
+ : (can_negate
+ ? -temp1
+ : temp1)))));
source = new_src;
}
@@ -1120,24 +1333,55 @@ arm_canonicalize_comparison (code, op1)
return code;
}
-
-/* Handle aggregates that are not laid out in a BLKmode element.
- This is a sub-element of RETURN_IN_MEMORY. */
+/* Decide whether a type should be returned in memory (true)
+ or in a register (false). This is called by the macro
+ RETURN_IN_MEMORY. */
int
arm_return_in_memory (type)
tree type;
{
- if (TREE_CODE (type) == RECORD_TYPE)
+ if (! AGGREGATE_TYPE_P (type))
+ {
+ /* All simple types are returned in registers. */
+ return 0;
+ }
+ else if (int_size_in_bytes (type) > 4)
+ {
+ /* All structures/unions bigger than one word are returned in memory. */
+ return 1;
+ }
+ else if (TREE_CODE (type) == RECORD_TYPE)
{
tree field;
- /* For a struct, we can return in a register if every element was a
- bit-field. */
- for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
- if (TREE_CODE (field) != FIELD_DECL
- || ! DECL_BIT_FIELD_TYPE (field))
- return 1;
+ /* For a struct the APCS says that we must return in a register if
+ every addressable element has an offset of zero. For practical
+ purposes this means that the structure can have at most one non
+ bit-field element and that this element must be the first one in
+ the structure. */
+
+ /* Find the first field, ignoring non FIELD_DECL things which will
+ have been created by C++. */
+ for (field = TYPE_FIELDS (type);
+ field && TREE_CODE (field) != FIELD_DECL;
+ field = TREE_CHAIN (field))
+ continue;
+
+ if (field == NULL)
+ return 0; /* An empty structure. Allowed by an extension to ANSI C. */
+
+ /* Now check the remaining fields, if any. */
+ for (field = TREE_CHAIN (field);
+ field;
+ field = TREE_CHAIN (field))
+ {
+ if (TREE_CODE (field) != FIELD_DECL)
+ continue;
+
+ if (! DECL_BIT_FIELD_TYPE (field))
+ return 1;
+ }
return 0;
}
@@ -1147,16 +1391,23 @@ arm_return_in_memory (type)
/* Unions can be returned in registers if every element is
integral, or can be returned in an integer register. */
- for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
+ for (field = TYPE_FIELDS (type);
+ field;
+ field = TREE_CHAIN (field))
{
- if (TREE_CODE (field) != FIELD_DECL
- || (AGGREGATE_TYPE_P (TREE_TYPE (field))
- && RETURN_IN_MEMORY (TREE_TYPE (field)))
- || FLOAT_TYPE_P (TREE_TYPE (field)))
+ if (TREE_CODE (field) != FIELD_DECL)
+ continue;
+
+ if (FLOAT_TYPE_P (TREE_TYPE (field)))
+ return 1;
+
+ if (RETURN_IN_MEMORY (TREE_TYPE (field)))
return 1;
}
+
return 0;
}
+
/* XXX Not sure what should be done for other aggregates, so put them in
memory. */
return 1;
@@ -1211,16 +1462,17 @@ legitimize_pic_address (orig, mode, reg)
emit_insn (gen_pic_load_addr (address, orig));
- pic_ref = gen_rtx (MEM, Pmode,
- gen_rtx (PLUS, Pmode, pic_offset_table_rtx, address));
+ pic_ref = gen_rtx_MEM (Pmode,
+ gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
+ address));
RTX_UNCHANGING_P (pic_ref) = 1;
insn = emit_move_insn (reg, pic_ref);
#endif
current_function_uses_pic_offset_table = 1;
/* Put a REG_EQUAL note on this insn, so that it can be optimized
by loop. */
- REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_EQUAL, orig,
- REG_NOTES (insn));
+ REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, orig,
+ REG_NOTES (insn));
return reg;
}
else if (GET_CODE (orig) == CONST)
@@ -1272,7 +1524,7 @@ legitimize_pic_address (orig, mode, reg)
return reg;
}
- return gen_rtx (PLUS, Pmode, base, offset);
+ return gen_rtx_PLUS (Pmode, base, offset);
}
else if (GET_CODE (orig) == LABEL_REF)
current_function_uses_pic_offset_table = 1;
@@ -1307,24 +1559,17 @@ arm_finalize_pic ()
start_sequence ();
l1 = gen_label_rtx ();
- global_offset_table = gen_rtx (SYMBOL_REF, Pmode, "_GLOBAL_OFFSET_TABLE_");
- /* The PC contains 'dot'+8, but the label L1 is on the next
- instruction, so the offset is only 'dot'+4. */
- pic_tmp = gen_rtx (CONST, VOIDmode,
- gen_rtx (PLUS, Pmode,
- gen_rtx (LABEL_REF, VOIDmode, l1),
- GEN_INT (4)));
- pic_tmp2 = gen_rtx (CONST, VOIDmode,
- gen_rtx (PLUS, Pmode,
- global_offset_table,
- pc_rtx));
-
- pic_rtx = gen_rtx (CONST, Pmode,
- gen_rtx (MINUS, Pmode, pic_tmp2, pic_tmp));
+ global_offset_table = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
+ /* On the ARM the PC register contains 'dot + 8' at the time of the
+ addition. */
+ pic_tmp = plus_constant (gen_rtx_LABEL_REF (Pmode, l1), 8);
+ pic_tmp2 = gen_rtx_CONST (VOIDmode,
+ gen_rtx_PLUS (Pmode, global_offset_table, pc_rtx));
+ pic_rtx = gen_rtx_CONST (Pmode, gen_rtx_MINUS (Pmode, pic_tmp2, pic_tmp));
+
emit_insn (gen_pic_load_addr (pic_offset_table_rtx, pic_rtx));
- emit_jump_insn (gen_pic_add_dot_plus_eight(l1, pic_offset_table_rtx));
- emit_label (l1);
+ emit_insn (gen_pic_add_dot_plus_eight (pic_offset_table_rtx, l1));
seq = gen_sequence ();
end_sequence ();
@@ -1332,7 +1577,7 @@ arm_finalize_pic ()
/* Need to emit this whether or not we obey regdecls,
since setjmp/longjmp can cause life info to screw up. */
- emit_insn (gen_rtx (USE, VOIDmode, pic_offset_table_rtx));
+ emit_insn (gen_rtx_USE (VOIDmode, pic_offset_table_rtx));
#endif /* AOF_ASSEMBLER */
}
@@ -1348,9 +1593,9 @@ arm_finalize_pic ()
|| (X) == arg_pointer_rtx)
int
-arm_rtx_costs (x, code, outer_code)
+arm_rtx_costs (x, code)
rtx x;
- enum rtx_code code, outer_code;
+ enum rtx_code code;
{
enum machine_mode mode = GET_MODE (x);
enum rtx_code subcode;
@@ -1456,14 +1701,14 @@ arm_rtx_costs (x, code, outer_code)
return (4 + extra_cost + (REG_OR_SUBREG_REG (XEXP (x, 0)) ? 0 : 8)
+ ((REG_OR_SUBREG_REG (XEXP (x, 1))
|| (GET_CODE (XEXP (x, 1)) == CONST_INT
- && const_ok_for_op (INTVAL (XEXP (x, 1)), code, mode)))
+ && const_ok_for_op (INTVAL (XEXP (x, 1)), code)))
? 0 : 8));
if (REG_OR_SUBREG_REG (XEXP (x, 0)))
return (1 + (GET_CODE (XEXP (x, 1)) == CONST_INT ? 0 : extra_cost)
+ ((REG_OR_SUBREG_REG (XEXP (x, 1))
|| (GET_CODE (XEXP (x, 1)) == CONST_INT
- && const_ok_for_op (INTVAL (XEXP (x, 1)), code, mode)))
+ && const_ok_for_op (INTVAL (XEXP (x, 1)), code)))
? 0 : 4));
else if (REG_OR_SUBREG_REG (XEXP (x, 1)))
@@ -1503,7 +1748,7 @@ arm_rtx_costs (x, code, outer_code)
int j;
/* Tune as appropriate */
int booth_unit_size = ((tune_flags & FL_FAST_MULT) ? 8 : 2);
-
+
for (j = 0; i && j < 32; j += booth_unit_size)
{
i >>= booth_unit_size;
@@ -1587,6 +1832,11 @@ arm_adjust_cost (insn, link, dep, cost)
{
rtx i_pat, d_pat;
+ /* XXX This is not strictly true for the FPA. */
+ if (REG_NOTE_KIND(link) == REG_DEP_ANTI
+ || REG_NOTE_KIND(link) == REG_DEP_OUTPUT)
+ return 0;
+
if ((i_pat = single_set (insn)) != NULL
&& GET_CODE (SET_SRC (i_pat)) == MEM
&& (d_pat = single_set (dep)) != NULL
@@ -1745,7 +1995,7 @@ reg_or_int_operand (op, mode)
int
reload_memory_operand (op, mode)
rtx op;
- enum machine_mode mode;
+ enum machine_mode mode ATTRIBUTE_UNUSED;
{
int regno = true_regnum (op);
@@ -1931,7 +2181,7 @@ fpu_add_operand (op, mode)
int
power_of_two_operand (op, mode)
rtx op;
- enum machine_mode mode;
+ enum machine_mode mode ATTRIBUTE_UNUSED;
{
if (GET_CODE (op) == CONST_INT)
{
@@ -2053,7 +2303,7 @@ shift_operator (x, mode)
enum rtx_code code = GET_CODE (x);
if (code == MULT)
- return power_of_two_operand (XEXP (x, 1));
+ return power_of_two_operand (XEXP (x, 1), mode);
return (code == ASHIFT || code == ASHIFTRT || code == LSHIFTRT
|| code == ROTATERT);
@@ -2062,7 +2312,7 @@ shift_operator (x, mode)
int equality_operator (x, mode)
rtx x;
- enum machine_mode mode;
+ enum machine_mode mode ATTRIBUTE_UNUSED;
{
return GET_CODE (x) == EQ || GET_CODE (x) == NE;
}
@@ -2251,7 +2501,7 @@ adjacent_mem_locations (a, b)
int
load_multiple_operation (op, mode)
rtx op;
- enum machine_mode mode;
+ enum machine_mode mode ATTRIBUTE_UNUSED;
{
HOST_WIDE_INT count = XVECLEN (op, 0);
int dest_regno;
@@ -2320,7 +2570,7 @@ load_multiple_operation (op, mode)
int
store_multiple_operation (op, mode)
rtx op;
- enum machine_mode mode;
+ enum machine_mode mode ATTRIBUTE_UNUSED;
{
HOST_WIDE_INT count = XVECLEN (op, 0);
int src_regno;
@@ -2520,6 +2770,36 @@ load_multiple_sequence (operands, nops, regs, base, load_offset)
if (unsorted_offsets[order[nops - 1]] == -4)
return 4; /* ldmdb */
+ /* For ARM8,9 & StrongARM, 2 ldr instructions are faster than an ldm if
+ the offset isn't small enough. The reason 2 ldrs are faster is because
+ these ARMs are able to do more than one cache access in a single cycle.
+ The ARM9 and StrongARM have Harvard caches, whilst the ARM8 has a double
+ bandwidth cache. This means that these cores can do both an instruction
+ fetch and a data fetch in a single cycle, so the trick of calculating the
+ address into a scratch register (one of the result regs) and then doing a
+ load multiple actually becomes slower (and no smaller in code size). That
+ is the transformation
+
+ ldr rd1, [rbase + offset]
+ ldr rd2, [rbase + offset + 4]
+
+ to
+
+ add rd1, rbase, offset
+ ldmia rd1, {rd1, rd2}
+
+ produces worse code -- '3 cycles + any stalls on rd2' instead of '2 cycles
+ + any stalls on rd2'. On ARMs with only one cache access per cycle, the
+ first sequence could never complete in less than 6 cycles, whereas the ldm
+ sequence would only take 5 and would make better use of sequential accesses
+ if not hitting the cache.
+
+ We cheat here and test 'arm_ld_sched' which we currently know to only be
+ true for the ARM8, ARM9 and StrongARM. If this ever changes, then the test
+ below needs to be reworked. */
+ if (nops == 2 && arm_ld_sched)
+ return 0;
+
/* Can't do it without setting up the offset, only do this if it takes
no more than one insn. */
return (const_ok_for_arm (unsorted_offsets[order[0]])
@@ -2772,7 +3052,7 @@ emit_stm_seq (operands, nops)
int
multi_register_push (op, mode)
rtx op;
- enum machine_mode mode;
+ enum machine_mode mode ATTRIBUTE_UNUSED;
{
if (GET_CODE (op) != PARALLEL
|| (GET_CODE (XVECEXP (op, 0, 0)) != SET)
@@ -2796,9 +3076,8 @@ multi_register_push (op, mode)
to do the right thing. */
int
-arm_valid_machine_decl_attribute (decl, attributes, attr, args)
+arm_valid_machine_decl_attribute (decl, attr, args)
tree decl;
- tree attributes;
tree attr;
tree args;
{
@@ -2820,7 +3099,7 @@ arm_naked_function_p (func)
if (TREE_CODE (func) != FUNCTION_DECL)
abort ();
-
+
a = lookup_attribute ("naked", DECL_MACHINE_ATTRIBUTES (func));
return a != NULL_TREE;
}
@@ -2829,7 +3108,7 @@ arm_naked_function_p (func)
rtx
arm_gen_load_multiple (base_regno, count, from, up, write_back, unchanging_p,
- in_struct_p)
+ in_struct_p, scalar_p)
int base_regno;
int count;
rtx from;
@@ -2837,43 +3116,43 @@ arm_gen_load_multiple (base_regno, count, from, up, write_back, unchanging_p,
int write_back;
int unchanging_p;
int in_struct_p;
+ int scalar_p;
{
int i = 0, j;
rtx result;
int sign = up ? 1 : -1;
rtx mem;
- result = gen_rtx (PARALLEL, VOIDmode,
- rtvec_alloc (count + (write_back ? 2 : 0)));
+ result = gen_rtx_PARALLEL (VOIDmode,
+ rtvec_alloc (count + (write_back ? 2 : 0)));
if (write_back)
{
XVECEXP (result, 0, 0)
- = gen_rtx (SET, GET_MODE (from), from,
- plus_constant (from, count * 4 * sign));
+ = gen_rtx_SET (GET_MODE (from), from,
+ plus_constant (from, count * 4 * sign));
i = 1;
count++;
}
for (j = 0; i < count; i++, j++)
{
- mem = gen_rtx (MEM, SImode, plus_constant (from, j * 4 * sign));
+ mem = gen_rtx_MEM (SImode, plus_constant (from, j * 4 * sign));
RTX_UNCHANGING_P (mem) = unchanging_p;
MEM_IN_STRUCT_P (mem) = in_struct_p;
-
- XVECEXP (result, 0, i) = gen_rtx (SET, VOIDmode,
- gen_rtx (REG, SImode, base_regno + j),
- mem);
+ MEM_SCALAR_P (mem) = scalar_p;
+ XVECEXP (result, 0, i)
+ = gen_rtx_SET (VOIDmode, gen_rtx_REG (SImode, base_regno + j), mem);
}
if (write_back)
- XVECEXP (result, 0, i) = gen_rtx (CLOBBER, SImode, from);
+ XVECEXP (result, 0, i) = gen_rtx_CLOBBER (SImode, from);
return result;
}
rtx
arm_gen_store_multiple (base_regno, count, to, up, write_back, unchanging_p,
- in_struct_p)
+ in_struct_p, scalar_p)
int base_regno;
int count;
rtx to;
@@ -2881,35 +3160,37 @@ arm_gen_store_multiple (base_regno, count, to, up, write_back, unchanging_p,
int write_back;
int unchanging_p;
int in_struct_p;
+ int scalar_p;
{
int i = 0, j;
rtx result;
int sign = up ? 1 : -1;
rtx mem;
- result = gen_rtx (PARALLEL, VOIDmode,
- rtvec_alloc (count + (write_back ? 2 : 0)));
+ result = gen_rtx_PARALLEL (VOIDmode,
+ rtvec_alloc (count + (write_back ? 2 : 0)));
if (write_back)
{
XVECEXP (result, 0, 0)
- = gen_rtx (SET, GET_MODE (to), to,
- plus_constant (to, count * 4 * sign));
+ = gen_rtx_SET (GET_MODE (to), to,
+ plus_constant (to, count * 4 * sign));
i = 1;
count++;
}
for (j = 0; i < count; i++, j++)
{
- mem = gen_rtx (MEM, SImode, plus_constant (to, j * 4 * sign));
+ mem = gen_rtx_MEM (SImode, plus_constant (to, j * 4 * sign));
RTX_UNCHANGING_P (mem) = unchanging_p;
MEM_IN_STRUCT_P (mem) = in_struct_p;
+ MEM_SCALAR_P (mem) = scalar_p;
- XVECEXP (result, 0, i) = gen_rtx (SET, VOIDmode, mem,
- gen_rtx (REG, SImode, base_regno + j));
+ XVECEXP (result, 0, i)
+ = gen_rtx_SET (VOIDmode, mem, gen_rtx_REG (SImode, base_regno + j));
}
if (write_back)
- XVECEXP (result, 0, i) = gen_rtx (CLOBBER, SImode, to);
+ XVECEXP (result, 0, i) = gen_rtx_CLOBBER (SImode, to);
return result;
}
@@ -2925,6 +3206,7 @@ arm_gen_movstrqi (operands)
rtx part_bytes_reg = NULL;
rtx mem;
int dst_unchanging_p, dst_in_struct_p, src_unchanging_p, src_in_struct_p;
+ int dst_scalar_p, src_scalar_p;
if (GET_CODE (operands[2]) != CONST_INT
|| GET_CODE (operands[3]) != CONST_INT
@@ -2937,8 +3219,10 @@ arm_gen_movstrqi (operands)
dst_unchanging_p = RTX_UNCHANGING_P (operands[0]);
dst_in_struct_p = MEM_IN_STRUCT_P (operands[0]);
+ dst_scalar_p = MEM_SCALAR_P (operands[0]);
src_unchanging_p = RTX_UNCHANGING_P (operands[1]);
src_in_struct_p = MEM_IN_STRUCT_P (operands[1]);
+ src_scalar_p = MEM_SCALAR_P (operands[1]);
fin_dst = dst = copy_to_mode_reg (SImode, st_dst);
fin_src = src = copy_to_mode_reg (SImode, st_src);
@@ -2948,37 +3232,42 @@ arm_gen_movstrqi (operands)
last_bytes = INTVAL (operands[2]) & 3;
if (out_words_to_go != in_words_to_go && ((in_words_to_go - 1) & 3) != 0)
- part_bytes_reg = gen_rtx (REG, SImode, (in_words_to_go - 1) & 3);
+ part_bytes_reg = gen_rtx_REG (SImode, (in_words_to_go - 1) & 3);
for (i = 0; in_words_to_go >= 2; i+=4)
{
if (in_words_to_go > 4)
emit_insn (arm_gen_load_multiple (0, 4, src, TRUE, TRUE,
- src_unchanging_p, src_in_struct_p));
+ src_unchanging_p,
+ src_in_struct_p,
+ src_scalar_p));
else
emit_insn (arm_gen_load_multiple (0, in_words_to_go, src, TRUE,
FALSE, src_unchanging_p,
- src_in_struct_p));
+ src_in_struct_p, src_scalar_p));
if (out_words_to_go)
{
if (out_words_to_go > 4)
emit_insn (arm_gen_store_multiple (0, 4, dst, TRUE, TRUE,
dst_unchanging_p,
- dst_in_struct_p));
+ dst_in_struct_p,
+ dst_scalar_p));
else if (out_words_to_go != 1)
emit_insn (arm_gen_store_multiple (0, out_words_to_go,
dst, TRUE,
(last_bytes == 0
? FALSE : TRUE),
dst_unchanging_p,
- dst_in_struct_p));
+ dst_in_struct_p,
+ dst_scalar_p));
else
{
- mem = gen_rtx (MEM, SImode, dst);
+ mem = gen_rtx_MEM (SImode, dst);
RTX_UNCHANGING_P (mem) = dst_unchanging_p;
MEM_IN_STRUCT_P (mem) = dst_in_struct_p;
- emit_move_insn (mem, gen_rtx (REG, SImode, 0));
+ MEM_SCALAR_P (mem) = dst_scalar_p;
+ emit_move_insn (mem, gen_rtx_REG (SImode, 0));
if (last_bytes != 0)
emit_insn (gen_addsi3 (dst, dst, GEN_INT (4)));
}
@@ -2993,15 +3282,17 @@ arm_gen_movstrqi (operands)
{
rtx sreg;
- mem = gen_rtx (MEM, SImode, src);
+ mem = gen_rtx_MEM (SImode, src);
RTX_UNCHANGING_P (mem) = src_unchanging_p;
MEM_IN_STRUCT_P (mem) = src_in_struct_p;
+ MEM_SCALAR_P (mem) = src_scalar_p;
emit_move_insn (sreg = gen_reg_rtx (SImode), mem);
emit_move_insn (fin_src = gen_reg_rtx (SImode), plus_constant (src, 4));
- mem = gen_rtx (MEM, SImode, dst);
+ mem = gen_rtx_MEM (SImode, dst);
RTX_UNCHANGING_P (mem) = dst_unchanging_p;
MEM_IN_STRUCT_P (mem) = dst_in_struct_p;
+ MEM_SCALAR_P (mem) = dst_scalar_p;
emit_move_insn (mem, sreg);
emit_move_insn (fin_dst = gen_reg_rtx (SImode), plus_constant (dst, 4));
in_words_to_go--;
@@ -3015,9 +3306,10 @@ arm_gen_movstrqi (operands)
if (in_words_to_go < 0)
abort ();
- mem = gen_rtx (MEM, SImode, src);
+ mem = gen_rtx_MEM (SImode, src);
RTX_UNCHANGING_P (mem) = src_unchanging_p;
MEM_IN_STRUCT_P (mem) = src_in_struct_p;
+ MEM_SCALAR_P (mem) = src_scalar_p;
part_bytes_reg = copy_to_mode_reg (SImode, mem);
}
@@ -3035,10 +3327,11 @@ arm_gen_movstrqi (operands)
while (last_bytes)
{
- mem = gen_rtx (MEM, QImode, plus_constant (dst, last_bytes - 1));
+ mem = gen_rtx_MEM (QImode, plus_constant (dst, last_bytes - 1));
RTX_UNCHANGING_P (mem) = dst_unchanging_p;
MEM_IN_STRUCT_P (mem) = dst_in_struct_p;
- emit_move_insn (mem, gen_rtx (SUBREG, QImode, part_bytes_reg, 0));
+ MEM_SCALAR_P (mem) = dst_scalar_p;
+ emit_move_insn (mem, gen_rtx_SUBREG (QImode, part_bytes_reg, 0));
if (--last_bytes)
{
tmp = gen_reg_rtx (SImode);
@@ -3055,10 +3348,11 @@ arm_gen_movstrqi (operands)
if (part_bytes_reg == NULL)
abort ();
- mem = gen_rtx (MEM, QImode, dst);
+ mem = gen_rtx_MEM (QImode, dst);
RTX_UNCHANGING_P (mem) = dst_unchanging_p;
MEM_IN_STRUCT_P (mem) = dst_in_struct_p;
- emit_move_insn (mem, gen_rtx (SUBREG, QImode, part_bytes_reg, 0));
+ MEM_SCALAR_P (mem) = dst_scalar_p;
+ emit_move_insn (mem, gen_rtx_SUBREG (QImode, part_bytes_reg, 0));
if (--last_bytes)
{
rtx tmp = gen_reg_rtx (SImode);
@@ -3094,17 +3388,16 @@ gen_rotated_half_load (memref)
&& ((BYTES_BIG_ENDIAN ? 1 : 0) ^ ((offset & 2) == 0)))
return NULL;
- base = gen_rtx (MEM, SImode, plus_constant (base, offset & ~2));
+ base = gen_rtx_MEM (SImode, plus_constant (base, offset & ~2));
if ((BYTES_BIG_ENDIAN ? 1 : 0) ^ ((offset & 2) == 2))
return base;
- return gen_rtx (ROTATE, SImode, base, GEN_INT (16));
+ return gen_rtx_ROTATE (SImode, base, GEN_INT (16));
}
static enum machine_mode
-select_dominance_cc_mode (op, x, y, cond_or)
- enum rtx_code op;
+select_dominance_cc_mode (x, y, cond_or)
rtx x;
rtx y;
HOST_WIDE_INT cond_or;
@@ -3274,7 +3567,7 @@ arm_select_cc_mode (op, x, y)
|| XEXP (x, 2) == const1_rtx)
&& GET_RTX_CLASS (GET_CODE (XEXP (x, 0))) == '<'
&& GET_RTX_CLASS (GET_CODE (XEXP (x, 1))) == '<')
- return select_dominance_cc_mode (op, XEXP (x, 0), XEXP (x, 1),
+ return select_dominance_cc_mode (XEXP (x, 0), XEXP (x, 1),
INTVAL (XEXP (x, 2)));
if (GET_MODE (x) == QImode && (op == EQ || op == NE))
@@ -3293,16 +3586,15 @@ arm_select_cc_mode (op, x, y)
floating point compare: I don't think that it is needed on the arm. */
rtx
-gen_compare_reg (code, x, y, fp)
+gen_compare_reg (code, x, y)
enum rtx_code code;
rtx x, y;
- int fp;
{
enum machine_mode mode = SELECT_CC_MODE (code, x, y);
- rtx cc_reg = gen_rtx (REG, mode, 24);
+ rtx cc_reg = gen_rtx_REG (mode, 24);
- emit_insn (gen_rtx (SET, VOIDmode, cc_reg,
- gen_rtx (COMPARE, mode, x, y)));
+ emit_insn (gen_rtx_SET (VOIDmode, cc_reg,
+ gen_rtx_COMPARE (mode, x, y)));
return cc_reg;
}
@@ -3313,37 +3605,35 @@ arm_reload_in_hi (operands)
{
rtx base = find_replacement (&XEXP (operands[1], 0));
- emit_insn (gen_zero_extendqisi2 (operands[2], gen_rtx (MEM, QImode, base)));
+ emit_insn (gen_zero_extendqisi2 (operands[2], gen_rtx_MEM (QImode, base)));
/* Handle the case where the address is too complex to be offset by 1. */
if (GET_CODE (base) == MINUS
|| (GET_CODE (base) == PLUS && GET_CODE (XEXP (base, 1)) != CONST_INT))
{
- rtx base_plus = gen_rtx (REG, SImode, REGNO (operands[0]));
+ rtx base_plus = gen_rtx_REG (SImode, REGNO (operands[0]));
- emit_insn (gen_rtx (SET, VOIDmode, base_plus, base));
+ emit_insn (gen_rtx_SET (VOIDmode, base_plus, base));
base = base_plus;
}
- emit_insn (gen_zero_extendqisi2 (gen_rtx (SUBREG, SImode, operands[0], 0),
- gen_rtx (MEM, QImode,
- plus_constant (base, 1))));
+ emit_insn (gen_zero_extendqisi2 (gen_rtx_SUBREG (SImode, operands[0], 0),
+ gen_rtx_MEM (QImode,
+ plus_constant (base, 1))));
if (BYTES_BIG_ENDIAN)
- emit_insn (gen_rtx (SET, VOIDmode, gen_rtx (SUBREG, SImode,
- operands[0], 0),
- gen_rtx (IOR, SImode,
- gen_rtx (ASHIFT, SImode,
- gen_rtx (SUBREG, SImode,
- operands[0], 0),
- GEN_INT (8)),
- operands[2])));
+ emit_insn (gen_rtx_SET (VOIDmode, gen_rtx_SUBREG (SImode, operands[0], 0),
+ gen_rtx_IOR (SImode,
+ gen_rtx_ASHIFT
+ (SImode,
+ gen_rtx_SUBREG (SImode, operands[0], 0),
+ GEN_INT (8)),
+ operands[2])));
else
- emit_insn (gen_rtx (SET, VOIDmode, gen_rtx (SUBREG, SImode,
- operands[0], 0),
- gen_rtx (IOR, SImode,
- gen_rtx (ASHIFT, SImode,
- operands[2],
- GEN_INT (8)),
- gen_rtx (SUBREG, SImode, operands[0], 0))));
+ emit_insn (gen_rtx_SET (VOIDmode, gen_rtx_SUBREG (SImode, operands[0], 0),
+ gen_rtx_IOR (SImode,
+ gen_rtx_ASHIFT (SImode, operands[2],
+ GEN_INT (8)),
+ gen_rtx_SUBREG (SImode, operands[0],
+ 0))));
}
void
@@ -3354,23 +3644,23 @@ arm_reload_out_hi (operands)
if (BYTES_BIG_ENDIAN)
{
- emit_insn (gen_movqi (gen_rtx (MEM, QImode, plus_constant (base, 1)),
- gen_rtx (SUBREG, QImode, operands[1], 0)));
+ emit_insn (gen_movqi (gen_rtx_MEM (QImode, plus_constant (base, 1)),
+ gen_rtx_SUBREG (QImode, operands[1], 0)));
emit_insn (gen_lshrsi3 (operands[2],
- gen_rtx (SUBREG, SImode, operands[1], 0),
+ gen_rtx_SUBREG (SImode, operands[1], 0),
GEN_INT (8)));
- emit_insn (gen_movqi (gen_rtx (MEM, QImode, base),
- gen_rtx (SUBREG, QImode, operands[2], 0)));
+ emit_insn (gen_movqi (gen_rtx_MEM (QImode, base),
+ gen_rtx_SUBREG (QImode, operands[2], 0)));
}
else
{
- emit_insn (gen_movqi (gen_rtx (MEM, QImode, base),
- gen_rtx (SUBREG, QImode, operands[1], 0)));
+ emit_insn (gen_movqi (gen_rtx_MEM (QImode, base),
+ gen_rtx_SUBREG (QImode, operands[1], 0)));
emit_insn (gen_lshrsi3 (operands[2],
- gen_rtx (SUBREG, SImode, operands[1], 0),
+ gen_rtx_SUBREG (SImode, operands[1], 0),
GEN_INT (8)));
- emit_insn (gen_movqi (gen_rtx (MEM, QImode, plus_constant (base, 1)),
- gen_rtx (SUBREG, QImode, operands[2], 0)));
+ emit_insn (gen_movqi (gen_rtx_MEM (QImode, plus_constant (base, 1)),
+ gen_rtx_SUBREG (QImode, operands[2], 0)));
}
}
@@ -3471,6 +3761,7 @@ add_constant (x, mode, address_only)
else if (GET_CODE (x) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P(x))
{
*address_only = 1;
+ mode = get_pool_mode (x);
x = get_pool_constant (x);
}
#ifndef AOF_ASSEMBLER
@@ -3642,7 +3933,7 @@ find_barrier (from, max_count)
/* Walk back to be just before any jump. */
while (GET_CODE (from) == JUMP_INSN
- || GET_CODE (from) == NOTE
+ || GET_CODE (from) == NOTE
|| GET_CODE (from) == CODE_LABEL)
from = PREV_INSN (from);
@@ -3758,8 +4049,8 @@ arm_reorg (first)
}
offset = add_constant (src, mode, &address_only);
- addr = plus_constant (gen_rtx (LABEL_REF, VOIDmode,
- pool_vector_label),
+ addr = plus_constant (gen_rtx_LABEL_REF (VOIDmode,
+ pool_vector_label),
offset);
/* If we only want the address of the pool entry, or
@@ -3778,7 +4069,7 @@ arm_reorg (first)
if (mode == SImode)
reg = dst;
else
- reg = gen_rtx (REG, SImode, scratch);
+ reg = gen_rtx_REG (SImode, scratch);
newinsn = emit_insn_after (gen_movaddr (reg, addr),
newinsn);
@@ -3787,15 +4078,17 @@ arm_reorg (first)
if (! address_only)
{
- newsrc = gen_rtx (MEM, mode, addr);
+ newsrc = gen_rtx_MEM (mode, addr);
/* XXX Fixme -- I think the following is bogus. */
/* Build a jump insn wrapper around the move instead
of an ordinary insn, because we want to have room for
the target label rtx in fld[7], which an ordinary
insn doesn't have. */
- newinsn = emit_jump_insn_after
- (gen_rtx (SET, VOIDmode, dst, newsrc), newinsn);
+ newinsn
+ = emit_jump_insn_after (gen_rtx_SET (VOIDmode, dst,
+ newsrc),
+ newinsn);
JUMP_LABEL (newinsn) = pool_vector_label;
/* But it's still an ordinary insn */
@@ -3811,6 +4104,8 @@ arm_reorg (first)
insn = scan;
}
}
+
+ after_arm_reorg = 1;
}
@@ -3893,7 +4188,7 @@ output_call (operands)
if (REGNO (operands[0]) == 14)
{
- operands[0] = gen_rtx (REG, SImode, 12);
+ operands[0] = gen_rtx_REG (SImode, 12);
output_asm_insn ("mov%?\t%0, %|lr", operands);
}
output_asm_insn ("mov%?\t%|lr, %|pc", operands);
@@ -3921,7 +4216,7 @@ eliminate_lr2ip (x)
case REG:
if (REGNO (x0) == 14)
{
- *x = gen_rtx (REG, SImode, 12);
+ *x = gen_rtx_REG (SImode, 12);
return 1;
}
return 0;
@@ -3980,9 +4275,9 @@ output_mov_long_double_fpu_from_arm (operands)
if (arm_reg0 == 12)
abort();
- ops[0] = gen_rtx (REG, SImode, arm_reg0);
- ops[1] = gen_rtx (REG, SImode, 1 + arm_reg0);
- ops[2] = gen_rtx (REG, SImode, 2 + arm_reg0);
+ ops[0] = gen_rtx_REG (SImode, arm_reg0);
+ ops[1] = gen_rtx_REG (SImode, 1 + arm_reg0);
+ ops[2] = gen_rtx_REG (SImode, 2 + arm_reg0);
output_asm_insn ("stm%?fd\t%|sp!, {%0, %1, %2}", ops);
output_asm_insn ("ldf%?e\t%0, [%|sp], #12", operands);
@@ -4003,9 +4298,9 @@ output_mov_long_double_arm_from_fpu (operands)
if (arm_reg0 == 12)
abort();
- ops[0] = gen_rtx (REG, SImode, arm_reg0);
- ops[1] = gen_rtx (REG, SImode, 1 + arm_reg0);
- ops[2] = gen_rtx (REG, SImode, 2 + arm_reg0);
+ ops[0] = gen_rtx_REG (SImode, arm_reg0);
+ ops[1] = gen_rtx_REG (SImode, 1 + arm_reg0);
+ ops[2] = gen_rtx_REG (SImode, 2 + arm_reg0);
output_asm_insn ("stf%?e\t%1, [%|sp, #-12]!", operands);
output_asm_insn ("ldm%?fd\t%|sp!, {%0, %1, %2}", ops);
@@ -4029,8 +4324,8 @@ output_mov_long_double_arm_from_arm (operands)
{
for (i = 0; i < 3; i++)
{
- ops[0] = gen_rtx (REG, SImode, dest_start + i);
- ops[1] = gen_rtx (REG, SImode, src_start + i);
+ ops[0] = gen_rtx_REG (SImode, dest_start + i);
+ ops[1] = gen_rtx_REG (SImode, src_start + i);
output_asm_insn ("mov%?\t%0, %1", ops);
}
}
@@ -4038,8 +4333,8 @@ output_mov_long_double_arm_from_arm (operands)
{
for (i = 2; i >= 0; i--)
{
- ops[0] = gen_rtx (REG, SImode, dest_start + i);
- ops[1] = gen_rtx (REG, SImode, src_start + i);
+ ops[0] = gen_rtx_REG (SImode, dest_start + i);
+ ops[1] = gen_rtx_REG (SImode, src_start + i);
output_asm_insn ("mov%?\t%0, %1", ops);
}
}
@@ -4061,8 +4356,8 @@ output_mov_double_fpu_from_arm (operands)
if (arm_reg0 == 12)
abort();
- ops[0] = gen_rtx (REG, SImode, arm_reg0);
- ops[1] = gen_rtx (REG, SImode, 1 + arm_reg0);
+ ops[0] = gen_rtx_REG (SImode, arm_reg0);
+ ops[1] = gen_rtx_REG (SImode, 1 + arm_reg0);
output_asm_insn ("stm%?fd\t%|sp!, {%0, %1}", ops);
output_asm_insn ("ldf%?d\t%0, [%|sp], #8", operands);
return "";
@@ -4082,8 +4377,8 @@ output_mov_double_arm_from_fpu (operands)
if (arm_reg0 == 12)
abort();
- ops[0] = gen_rtx (REG, SImode, arm_reg0);
- ops[1] = gen_rtx (REG, SImode, 1 + arm_reg0);
+ ops[0] = gen_rtx_REG (SImode, arm_reg0);
+ ops[1] = gen_rtx_REG (SImode, 1 + arm_reg0);
output_asm_insn ("stf%?d\t%1, [%|sp, #-8]!", operands);
output_asm_insn ("ldm%?fd\t%|sp!, {%0, %1}", ops);
return "";
@@ -4095,7 +4390,7 @@ output_mov_double_arm_from_fpu (operands)
char *
output_move_double (operands)
- rtx *operands;
+ rtx * operands;
{
enum rtx_code code0 = GET_CODE (operands[0]);
enum rtx_code code1 = GET_CODE (operands[1]);
@@ -4105,7 +4400,8 @@ output_move_double (operands)
{
int reg0 = REGNO (operands[0]);
- otherops[0] = gen_rtx (REG, SImode, 1 + reg0);
+ otherops[0] = gen_rtx_REG (SImode, 1 + reg0);
+
if (code1 == REG)
{
int reg1 = REGNO (operands[1]);
@@ -4208,7 +4504,8 @@ output_move_double (operands)
break;
default:
- if (arm_add_operand (XEXP (XEXP (operands[1], 0), 1)))
+ if (arm_add_operand (XEXP (XEXP (operands[1], 0), 1),
+ GET_MODE (XEXP (XEXP (operands[1], 0), 1))))
{
otherops[0] = operands[0];
otherops[1] = XEXP (XEXP (operands[1], 0), 0);
@@ -4310,7 +4607,7 @@ output_move_double (operands)
default:
otherops[0] = adj_offsettable_operand (operands[0], 4);
- otherops[1] = gen_rtx (REG, SImode, 1 + REGNO (operands[1]));
+ otherops[1] = gen_rtx_REG (SImode, 1 + REGNO (operands[1]));
output_asm_insn ("str%?\t%1, %0", operands);
output_asm_insn ("str%?\t%1, %0", otherops);
}
@@ -4781,7 +5078,7 @@ output_return_instruction (operand, really_return, reverse)
/* Otherwise, trap an attempted return by aborting. */
ops[0] = operand;
- ops[1] = gen_rtx (SYMBOL_REF, Pmode, "abort");
+ ops[1] = gen_rtx_SYMBOL_REF (Pmode, "abort");
assemble_external_libcall (ops[1]);
output_asm_insn (reverse ? "bl%D0\t%a1" : "bl%d0\t%a1", ops);
return "";
@@ -4857,7 +5154,7 @@ output_return_instruction (operand, really_return, reverse)
else if (really_return)
{
if (TARGET_THUMB_INTERWORK)
- sprintf (instr, "bx%%?%%%s\t%%|lr", reverse ? "D" : "d");
+ sprintf (instr, "bx%%?%%%s0\t%%|lr", reverse ? "D" : "d");
else
sprintf (instr, "mov%%?%%%s0%s\t%%|pc, %%|lr",
reverse ? "D" : "d", TARGET_APCS_32 ? "" : "s");
@@ -4975,10 +5272,10 @@ output_func_epilogue (f, frame_size)
int volatile_func = (optimize > 0
&& TREE_THIS_VOLATILE (current_function_decl));
- if (use_return_insn() && return_used_this_function)
+ if (use_return_insn (FALSE) && return_used_this_function)
{
if ((frame_size + current_function_outgoing_args_size) != 0
- && !(frame_pointer_needed || TARGET_APCS))
+ && !(frame_pointer_needed && TARGET_APCS))
abort ();
goto epilogue_done;
}
@@ -4988,9 +5285,9 @@ output_func_epilogue (f, frame_size)
goto epilogue_done;
/* A volatile function should never return. Call abort. */
- if (volatile_func)
+ if (TARGET_ABORT_NORETURN && volatile_func)
{
- rtx op = gen_rtx (SYMBOL_REF, Pmode, "abort");
+ rtx op = gen_rtx_SYMBOL_REF (Pmode, "abort");
assemble_external_libcall (op);
output_asm_insn ("bl\t%a0", &op);
goto epilogue_done;
@@ -5121,8 +5418,10 @@ output_func_epilogue (f, frame_size)
if (TARGET_THUMB_INTERWORK)
{
if (! lr_save_eliminated)
- print_multi_reg(f, "ldmfd\t%ssp!", live_regs_mask | 0x4000,
- FALSE);
+ live_regs_mask |= 0x4000;
+
+ if (live_regs_mask != 0)
+ print_multi_reg (f, "ldmfd\t%ssp!", live_regs_mask, FALSE);
fprintf (f, "\tbx\t%slr\n", REGISTER_PREFIX);
}
@@ -5156,16 +5455,18 @@ output_func_epilogue (f, frame_size)
/* And finally, go home */
if (TARGET_THUMB_INTERWORK)
fprintf (f, "\tbx\t%slr\n", REGISTER_PREFIX);
+ else if (TARGET_APCS_32)
+ fprintf (f, "\tmov\t%spc, %slr\n", REGISTER_PREFIX, REGISTER_PREFIX );
else
- fprintf (f, (TARGET_APCS_32 ? "\tmov\t%spc, %slr\n"
- : "\tmovs\t%spc, %slr\n"),
- REGISTER_PREFIX, REGISTER_PREFIX, f);
+ fprintf (f, "\tmovs\t%spc, %slr\n", REGISTER_PREFIX, REGISTER_PREFIX );
}
}
epilogue_done:
+ /* Reset the ARM-specific per-function variables. */
current_function_anonymous_args = 0;
+ after_arm_reorg = 0;
}
static void
@@ -5183,19 +5484,21 @@ emit_multi_reg_push (mask)
if (num_regs == 0 || num_regs > 16)
abort ();
- par = gen_rtx (PARALLEL, VOIDmode, rtvec_alloc (num_regs));
+ par = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (num_regs));
for (i = 0; i < 16; i++)
{
if (mask & (1 << i))
{
XVECEXP (par, 0, 0)
- = gen_rtx (SET, VOIDmode, gen_rtx (MEM, BLKmode,
- gen_rtx (PRE_DEC, BLKmode,
- stack_pointer_rtx)),
- gen_rtx (UNSPEC, BLKmode,
- gen_rtvec (1, gen_rtx (REG, SImode, i)),
- 2));
+ = gen_rtx_SET (VOIDmode,
+ gen_rtx_MEM (BLKmode,
+ gen_rtx_PRE_DEC (BLKmode,
+ stack_pointer_rtx)),
+ gen_rtx_UNSPEC (BLKmode,
+ gen_rtvec (1,
+ gen_rtx_REG (SImode, i)),
+ 2));
break;
}
}
@@ -5205,7 +5508,7 @@ emit_multi_reg_push (mask)
if (mask & (1 << i))
{
XVECEXP (par, 0, j)
- = gen_rtx (USE, VOIDmode, gen_rtx (REG, SImode, i));
+ = gen_rtx_USE (VOIDmode, gen_rtx_REG (SImode, i));
j++;
}
}
@@ -5221,19 +5524,19 @@ emit_sfm (base_reg, count)
rtx par;
int i;
- par = gen_rtx (PARALLEL, VOIDmode, rtvec_alloc (count));
+ par = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
- XVECEXP (par, 0, 0) = gen_rtx (SET, VOIDmode,
- gen_rtx (MEM, BLKmode,
- gen_rtx (PRE_DEC, BLKmode,
- stack_pointer_rtx)),
- gen_rtx (UNSPEC, BLKmode,
- gen_rtvec (1, gen_rtx (REG, XFmode,
- base_reg++)),
- 2));
+ XVECEXP (par, 0, 0)
+ = gen_rtx_SET (VOIDmode,
+ gen_rtx_MEM (BLKmode,
+ gen_rtx_PRE_DEC (BLKmode, stack_pointer_rtx)),
+ gen_rtx_UNSPEC (BLKmode,
+ gen_rtvec (1, gen_rtx_REG (XFmode,
+ base_reg++)),
+ 2));
for (i = 1; i < count; i++)
- XVECEXP (par, 0, i) = gen_rtx (USE, VOIDmode,
- gen_rtx (REG, XFmode, base_reg++));
+ XVECEXP (par, 0, i) = gen_rtx_USE (VOIDmode,
+ gen_rtx_REG (XFmode, base_reg++));
emit_insn (par);
}
@@ -5267,7 +5570,7 @@ arm_expand_prologue ()
if (frame_pointer_needed)
{
live_regs_mask |= 0xD800;
- emit_insn (gen_movsi (gen_rtx (REG, SImode, 12),
+ emit_insn (gen_movsi (gen_rtx_REG (SImode, 12),
stack_pointer_rtx));
}
@@ -5297,11 +5600,12 @@ arm_expand_prologue ()
{
for (reg = 23; reg > 15; reg--)
if (regs_ever_live[reg] && ! call_used_regs[reg])
- emit_insn (gen_rtx (SET, VOIDmode,
- gen_rtx (MEM, XFmode,
- gen_rtx (PRE_DEC, XFmode,
- stack_pointer_rtx)),
- gen_rtx (REG, XFmode, reg)));
+ emit_insn (gen_rtx_SET
+ (VOIDmode,
+ gen_rtx_MEM (XFmode,
+ gen_rtx_PRE_DEC (XFmode,
+ stack_pointer_rtx)),
+ gen_rtx_REG (XFmode, reg)));
}
else
{
@@ -5331,20 +5635,21 @@ arm_expand_prologue ()
}
if (frame_pointer_needed)
- emit_insn (gen_addsi3 (hard_frame_pointer_rtx, gen_rtx (REG, SImode, 12),
+ emit_insn (gen_addsi3 (hard_frame_pointer_rtx, gen_rtx_REG (SImode, 12),
(GEN_INT
(-(4 + current_function_pretend_args_size)))));
if (amount != const0_rtx)
{
emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, amount));
- emit_insn (gen_rtx (CLOBBER, VOIDmode,
- gen_rtx (MEM, BLKmode, stack_pointer_rtx)));
+ emit_insn (gen_rtx_CLOBBER (VOIDmode,
+ gen_rtx_MEM (BLKmode, stack_pointer_rtx)));
}
/* If we are profiling, make sure no instructions are scheduled before
- the call to mcount. */
- if (profile_flag || profile_block_flag)
+ the call to mcount. Similarly if the user has requested no
+ scheduling in the prolog. */
+ if (profile_flag || profile_block_flag || TARGET_NO_SCHED_PRO)
emit_insn (gen_blockage ());
}
@@ -5654,10 +5959,8 @@ get_arm_condition_code (comparison)
void
-final_prescan_insn (insn, opvec, noperands)
+arm_final_prescan_insn (insn)
rtx insn;
- rtx *opvec;
- int noperands;
{
/* BODY will hold the body of INSN. */
register rtx body = PATTERN (insn);
@@ -5684,10 +5987,10 @@ final_prescan_insn (insn, opvec, noperands)
if (arm_ccfsm_state == 4)
{
if (insn == arm_target_insn)
- {
- arm_target_insn = NULL;
- arm_ccfsm_state = 0;
- }
+ {
+ arm_target_insn = NULL;
+ arm_ccfsm_state = 0;
+ }
return;
}
@@ -5796,7 +6099,7 @@ final_prescan_insn (insn, opvec, noperands)
insns are okay, and the label or unconditional branch to the same
label is not too far away, succeed. */
for (insns_skipped = 0;
- !fail && !succeed && insns_skipped++ < MAX_INSNS_SKIPPED;)
+ !fail && !succeed && insns_skipped++ < max_insns_skipped;)
{
rtx scanbody;
@@ -5858,7 +6161,7 @@ final_prescan_insn (insn, opvec, noperands)
this_insn = next_nonnote_insn (this_insn);
if (this_insn && this_insn == label
- && insns_skipped < MAX_INSNS_SKIPPED)
+ && insns_skipped < max_insns_skipped)
{
if (jump_clobbers)
{
@@ -5893,6 +6196,12 @@ final_prescan_insn (insn, opvec, noperands)
else if (GET_CODE (SET_SRC (scanbody)) == IF_THEN_ELSE)
fail = TRUE;
}
+ /* Fail if a conditional return is undesirable (eg on a
+ StrongARM), but still allow this if optimizing for size. */
+ else if (GET_CODE (scanbody) == RETURN
+ && ! use_return_insn (TRUE)
+ && ! optimize_size)
+ fail = TRUE;
else if (GET_CODE (scanbody) == RETURN
&& seeking_return)
{
@@ -5916,9 +6225,9 @@ final_prescan_insn (insn, opvec, noperands)
/* Instructions using or affecting the condition codes make it
fail. */
scanbody = PATTERN (this_insn);
- if ((GET_CODE (scanbody) == SET
- || GET_CODE (scanbody) == PARALLEL)
- && get_attr_conds (this_insn) != CONDS_NOCOND)
+ if (! (GET_CODE (scanbody) == SET
+ || GET_CODE (scanbody) == PARALLEL)
+ || get_attr_conds (this_insn) != CONDS_NOCOND)
fail = TRUE;
break;
@@ -6006,7 +6315,7 @@ aof_pic_entry (x)
{
/* This needs to persist throughout the compilation. */
end_temporary_allocation ();
- aof_pic_label = gen_rtx (SYMBOL_REF, Pmode, "x$adcons");
+ aof_pic_label = gen_rtx_SYMBOL_REF (Pmode, "x$adcons");
resume_temporary_allocation ();
}
diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h
index ed5e4de9729..6be5c0119b3 100644
--- a/gcc/config/arm/arm.h
+++ b/gcc/config/arm/arm.h
@@ -1,5 +1,5 @@
-/* Definitions of target machine for GNU compiler, for Acorn RISC Machine.
- Copyright (C) 1991, 93, 94, 95, 96, 97, 1998 Free Software Foundation, Inc.
+/* Definitions of target machine for GNU compiler, for ARM.
+ Copyright (C) 1991, 93, 94, 95, 96, 97, 98, 1999 Free Software Foundation, Inc.
Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl)
and Martin Simmons (@harleqn.co.uk).
More major hacks by Richard Earnshaw (rwe11@cl.cam.ac.uk)
@@ -30,6 +30,9 @@ Boston, MA 02111-1307, USA. */
should default to that used by the OS.
*/
+#ifndef __ARM_H__
+#define __ARM_H__
+
#define TARGET_CPU_arm2 0x0000
#define TARGET_CPU_arm250 0x0000
#define TARGET_CPU_arm3 0x0000
@@ -50,6 +53,9 @@ Boston, MA 02111-1307, USA. */
#define TARGET_CPU_arm810 0x0020
#define TARGET_CPU_strongarm 0x0040
#define TARGET_CPU_strongarm110 0x0040
+#define TARGET_CPU_strongarm1100 0x0040
+#define TARGET_CPU_arm9 0x0080
+#define TARGET_CPU_arm9tdmi 0x0080
/* Configure didn't specify */
#define TARGET_CPU_generic 0x8000
@@ -92,7 +98,7 @@ extern int frame_pointer_needed;
#if TARGET_CPU_DEFAULT == TARGET_CPU_arm7m
#define CPP_ARCH_DEFAULT_SPEC "-D__ARM_ARCH_3M__"
#else
-#if TARGET_CPU_DEFAULT == TARGET_CPU_arm7tdmi
+#if TARGET_CPU_DEFAULT == TARGET_CPU_arm7tdmi || TARGET_CPU_DEFAULT == TARGET_CPU_arm9
#define CPP_ARCH_DEFAULT_SPEC "-D__ARM_ARCH_4T__"
#else
#if TARGET_CPU_DEFAULT == TARGET_CPU_arm8 || TARGET_CPU_DEFAULT == TARGET_CPU_arm810 || TARGET_CPU_DEFAULT == TARGET_CPU_strongarm
@@ -116,9 +122,6 @@ Unrecognized value in TARGET_CPU_DEFAULT.
/* Set the architecture define -- if -march= is set, then it overrides
the -mcpu= setting. */
#define CPP_CPU_ARCH_SPEC "\
-%{m2:-D__arm2__ -D__ARM_ARCH_2__} \
-%{m3:-D__arm2__ -D__ARM_ARCH_2__} \
-%{m6:-D__arm6__ -D__ARM_ARCH_3__} \
%{march=arm2:-D__ARM_ARCH_2__} \
%{march=arm250:-D__ARM_ARCH_2__} \
%{march=arm3:-D__ARM_ARCH_2__} \
@@ -137,8 +140,11 @@ Unrecognized value in TARGET_CPU_DEFAULT.
%{march=arm7tdmi:-D__ARM_ARCH_4T__} \
%{march=arm8:-D__ARM_ARCH_4__} \
%{march=arm810:-D__ARM_ARCH_4__} \
+%{march=arm9:-D__ARM_ARCH_4T__} \
+%{march=arm9tdmi:-D__ARM_ARCH_4T__} \
%{march=strongarm:-D__ARM_ARCH_4__} \
%{march=strongarm110:-D__ARM_ARCH_4__} \
+%{march=strongarm1100:-D__ARM_ARCH_4__} \
%{march=armv2:-D__ARM_ARCH_2__} \
%{march=armv2a:-D__ARM_ARCH_2__} \
%{march=armv3:-D__ARM_ARCH_3__} \
@@ -164,23 +170,25 @@ Unrecognized value in TARGET_CPU_DEFAULT.
%{mcpu=arm7tdmi:-D__ARM_ARCH_4T__} \
%{mcpu=arm8:-D__ARM_ARCH_4__} \
%{mcpu=arm810:-D__ARM_ARCH_4__} \
+ %{mcpu=arm9:-D__ARM_ARCH_4T__} \
+ %{mcpu=arm9tdmi:-D__ARM_ARCH_4T__} \
%{mcpu=strongarm:-D__ARM_ARCH_4__} \
%{mcpu=strongarm110:-D__ARM_ARCH_4__} \
- %{!mcpu*:%{!m6:%{!m2:%{!m3:%(cpp_cpu_arch_default)}}}}} \
+ %{mcpu=strongarm1100:-D__ARM_ARCH_4__} \
+ %{!mcpu*:%(cpp_cpu_arch_default)}} \
"
/* Define __APCS_26__ if the PC also contains the PSR */
-/* This also examines deprecated -m[236] if neither of -mapcs-{26,32} is set,
- ??? Delete this for 2.9. */
#define CPP_APCS_PC_SPEC "\
%{mapcs-32:%{mapcs-26:%e-mapcs-26 and -mapcs-32 may not be used together} \
-D__APCS_32__} \
%{mapcs-26:-D__APCS_26__} \
-%{!mapcs-32: %{!mapcs-26:%{m6:-D__APCS_32__} %{m2:-D__APCS_26__} \
- %{m3:-D__APCS_26__} %{!m6:%{!m3:%{!m2:%(cpp_apcs_pc_default)}}}}} \
+%{!mapcs-32: %{!mapcs-26:%(cpp_apcs_pc_default)}} \
"
+#ifndef CPP_APCS_PC_DEFAULT_SPEC
#define CPP_APCS_PC_DEFAULT_SPEC "-D__APCS_26__"
+#endif
#define CPP_FLOAT_SPEC "\
%{msoft-float:\
@@ -203,14 +211,7 @@ Unrecognized value in TARGET_CPU_DEFAULT.
/* Default is little endian, which doesn't define anything. */
#define CPP_ENDIAN_DEFAULT_SPEC ""
-/* Translate (for now) the old -m[236] option into the appropriate -mcpu=...
- and -mapcs-xx equivalents.
- ??? Remove support for this style in 2.9.*/
-#define CC1_SPEC "\
-%{m2:-mcpu=arm2 -mapcs-26} \
-%{m3:-mcpu=arm3 -mapcs-26} \
-%{m6:-mcpu=arm6 -mapcs-32} \
-"
+#define CC1_SPEC ""
/* This macro defines names of additional specifications to put in the specs
that can be used in various specifications like CC1_SPEC. Its definition
@@ -247,7 +248,7 @@ Unrecognized value in TARGET_CPU_DEFAULT.
extern int target_flags;
/* The floating point instruction architecture, can be 2 or 3 */
-extern char *target_fp_name;
+extern char * target_fp_name;
/* Nonzero if the function prologue (and epilogue) should obey
the ARM Procedure Call Standard. */
@@ -264,19 +265,13 @@ extern char *target_fp_name;
case instruction scheduling becomes very uninteresting. */
#define ARM_FLAG_FPE (0x0004)
-/* Nonzero if destined for an ARM6xx. Takes out bits that assume restoration
- of condition flags when returning from a branch & link (ie. a function) */
-/* ********* DEPRECATED ******** */
-#define ARM_FLAG_ARM6 (0x0008)
-
-/* ********* DEPRECATED ******** */
-#define ARM_FLAG_ARM3 (0x0010)
-
/* Nonzero if destined for a processor in 32-bit program mode. Takes out bit
that assume restoration of the condition flags when returning from a
branch and link (ie a function). */
#define ARM_FLAG_APCS_32 (0x0020)
+/* FLAGS 0x0008 and 0x0010 are now spare (used to be arm3/6 selection). */
+
/* Nonzero if stack checking should be performed on entry to each function
which allocates temporary variables on the stack. */
#define ARM_FLAG_APCS_STACK (0x0040)
@@ -301,27 +296,41 @@ extern char *target_fp_name;
#define ARM_FLAG_BIG_END (0x0800)
/* Nonzero if we should compile for Thumb interworking. */
-#define ARM_FLAG_THUMB (0x1000)
+#define ARM_FLAG_THUMB (0x1000)
/* Nonzero if we should have little-endian words even when compiling for
big-endian (for backwards compatibility with older versions of GCC). */
#define ARM_FLAG_LITTLE_WORDS (0x2000)
+/* Nonzero if we need to protect the prolog from scheduling */
+#define ARM_FLAG_NO_SCHED_PRO (0x4000)
+
+/* Nonzero if a call to abort should be generated if a noreturn
+function tries to return. */
+#define ARM_FLAG_ABORT_NORETURN (0x8000)
+
#define TARGET_APCS (target_flags & ARM_FLAG_APCS_FRAME)
#define TARGET_POKE_FUNCTION_NAME (target_flags & ARM_FLAG_POKE)
#define TARGET_FPE (target_flags & ARM_FLAG_FPE)
-#define TARGET_6 (target_flags & ARM_FLAG_ARM6)
-#define TARGET_3 (target_flags & ARM_FLAG_ARM3)
#define TARGET_APCS_32 (target_flags & ARM_FLAG_APCS_32)
#define TARGET_APCS_STACK (target_flags & ARM_FLAG_APCS_STACK)
#define TARGET_APCS_FLOAT (target_flags & ARM_FLAG_APCS_FLOAT)
#define TARGET_APCS_REENT (target_flags & ARM_FLAG_APCS_REENT)
+/* Note: TARGET_SHORT_BY_BYTES is really a misnomer. What it means is
+ that short values sould not be accessed using word load instructions
+ as there is a possibility that they may not be word aligned and this
+ would generate an MMU fault. On processors which do not have a 16 bit
+ load instruction therefore, short values must be loaded by individual
+ byte accesses rather than loading a word and then shifting the desired
+ value into place. */
#define TARGET_SHORT_BY_BYTES (target_flags & ARM_FLAG_SHORT_BYTE)
#define TARGET_SOFT_FLOAT (target_flags & ARM_FLAG_SOFT_FLOAT)
#define TARGET_HARD_FLOAT (! TARGET_SOFT_FLOAT)
#define TARGET_BIG_END (target_flags & ARM_FLAG_BIG_END)
#define TARGET_THUMB_INTERWORK (target_flags & ARM_FLAG_THUMB)
#define TARGET_LITTLE_WORDS (target_flags & ARM_FLAG_LITTLE_WORDS)
+#define TARGET_NO_SCHED_PRO (target_flags & ARM_FLAG_NO_SCHED_PRO)
+#define TARGET_ABORT_NORETURN (target_flags & ARM_FLAG_ABORT_NORETURN)
/* SUBTARGET_SWITCHES is used to add flags on a per-config basis.
Bit 31 is reserved. See riscix.h. */
@@ -331,83 +340,80 @@ extern char *target_fp_name;
#define TARGET_SWITCHES \
{ \
- {"apcs", ARM_FLAG_APCS_FRAME}, \
- {"apcs-frame", ARM_FLAG_APCS_FRAME}, \
- {"no-apcs-frame", -ARM_FLAG_APCS_FRAME}, \
- {"poke-function-name", ARM_FLAG_POKE}, \
- {"fpe", ARM_FLAG_FPE}, \
- {"6", ARM_FLAG_ARM6}, \
- {"2", ARM_FLAG_ARM3}, \
- {"3", ARM_FLAG_ARM3}, \
- {"apcs-32", ARM_FLAG_APCS_32}, \
- {"apcs-26", -ARM_FLAG_APCS_32}, \
- {"apcs-stack-check", ARM_FLAG_APCS_STACK}, \
- {"no-apcs-stack-check", -ARM_FLAG_APCS_STACK}, \
- {"apcs-float", ARM_FLAG_APCS_FLOAT}, \
- {"no-apcs-float", -ARM_FLAG_APCS_FLOAT}, \
- {"apcs-reentrant", ARM_FLAG_APCS_REENT}, \
- {"no-apcs-reentrant", -ARM_FLAG_APCS_REENT}, \
- {"short-load-bytes", ARM_FLAG_SHORT_BYTE}, \
- {"no-short-load-bytes", -ARM_FLAG_SHORT_BYTE}, \
- {"short-load-words", -ARM_FLAG_SHORT_BYTE}, \
- {"no-short-load-words", ARM_FLAG_SHORT_BYTE}, \
- {"soft-float", ARM_FLAG_SOFT_FLOAT}, \
- {"hard-float", -ARM_FLAG_SOFT_FLOAT}, \
- {"big-endian", ARM_FLAG_BIG_END}, \
- {"little-endian", -ARM_FLAG_BIG_END}, \
- {"thumb-interwork", ARM_FLAG_THUMB}, \
- {"no-thumb-interwork", -ARM_FLAG_THUMB}, \
- {"words-little-endian", ARM_FLAG_LITTLE_WORDS}, \
+ {"apcs", ARM_FLAG_APCS_FRAME, "" }, \
+ {"apcs-frame", ARM_FLAG_APCS_FRAME, \
+ "Generate APCS conformant stack frames" }, \
+ {"no-apcs-frame", -ARM_FLAG_APCS_FRAME, "" }, \
+ {"poke-function-name", ARM_FLAG_POKE, \
+ "Store function names in object code" }, \
+ {"fpe", ARM_FLAG_FPE, "" }, \
+ {"apcs-32", ARM_FLAG_APCS_32, \
+ "Use the 32bit version of the APCS" }, \
+ {"apcs-26", -ARM_FLAG_APCS_32, \
+ "Use the 26bit version of the APCS" }, \
+ {"apcs-stack-check", ARM_FLAG_APCS_STACK, "" }, \
+ {"no-apcs-stack-check", -ARM_FLAG_APCS_STACK, "" }, \
+ {"apcs-float", ARM_FLAG_APCS_FLOAT, \
+ "Pass FP arguments in FP registers" }, \
+ {"no-apcs-float", -ARM_FLAG_APCS_FLOAT, "" }, \
+ {"apcs-reentrant", ARM_FLAG_APCS_REENT, \
+ "Generate re-entrant, PIC code" }, \
+ {"no-apcs-reentrant", -ARM_FLAG_APCS_REENT, "" }, \
+ {"short-load-bytes", ARM_FLAG_SHORT_BYTE, \
+ "Load shorts a byte at a time" }, \
+ {"no-short-load-bytes", -ARM_FLAG_SHORT_BYTE, "" }, \
+ {"short-load-words", -ARM_FLAG_SHORT_BYTE, \
+ "Load words a byte at a time" }, \
+ {"no-short-load-words", ARM_FLAG_SHORT_BYTE, "" }, \
+ {"soft-float", ARM_FLAG_SOFT_FLOAT, \
+ "Use library calls to perform FP operations" }, \
+ {"hard-float", -ARM_FLAG_SOFT_FLOAT, \
+ "Use hardware floating point instructions" }, \
+ {"big-endian", ARM_FLAG_BIG_END, \
+ "Assume target CPU is configured as big endian" }, \
+ {"little-endian", -ARM_FLAG_BIG_END, \
+ "Assume target CPU is configured as little endian" }, \
+ {"words-little-endian", ARM_FLAG_LITTLE_WORDS, \
+ "Assume big endian bytes, little endian words" }, \
+ {"thumb-interwork", ARM_FLAG_THUMB, \
+ "Support calls between THUMB and ARM instructions sets" }, \
+ {"no-thumb-interwork", -ARM_FLAG_THUMB, "" }, \
+ {"abort-on-noreturn", ARM_FLAG_ABORT_NORETURN, \
+ "Generate a call to abort if a noreturn function returns"}, \
+ {"no-abort-on-noreturn", -ARM_FLAG_ABORT_NORETURN, ""}, \
+ {"sched-prolog", -ARM_FLAG_NO_SCHED_PRO, \
+ "Do not move instructions into a function's prologue" }, \
+ {"no-sched-prolog", ARM_FLAG_NO_SCHED_PRO, "" }, \
SUBTARGET_SWITCHES \
{"", TARGET_DEFAULT } \
}
-#define TARGET_OPTIONS \
-{ \
- {"cpu=", &arm_select[1].string}, \
- {"arch=", &arm_select[2].string}, \
- {"tune=", &arm_select[3].string}, \
- {"fp=", &target_fp_name} \
+#define TARGET_OPTIONS \
+{ \
+ {"cpu=", & arm_select[0].string, \
+ "Specify the name of the target CPU" }, \
+ {"arch=", & arm_select[1].string, \
+ "Specify the name of the target architecture" }, \
+ {"tune=", & arm_select[2].string, "" }, \
+ {"fpe=", & target_fp_name, "" }, \
+ {"fp=", & target_fp_name, \
+ "Specify the version of the floating point emulator" }, \
+ { "structure-size-boundary=", & structure_size_string, \
+ "Specify the minumum bit alignment of structures" } \
}
-/* arm_select[0] is reserved for the default cpu. */
struct arm_cpu_select
{
- char *string;
- char *name;
- int set_tune_p;
- int set_arch_p;
+ char * string;
+ char * name;
+ struct processors * processors;
};
+/* This is a magic array. If the user specifies a command line switch
+ which matches one of the entries in TARGET_OPTIONS then the corresponding
+ string pointer will be set to the value specified by the user. */
extern struct arm_cpu_select arm_select[];
-#ifndef PROCESSOR_DEFAULT
-#define PROCESSOR_DEFAULT PROCESSOR_ARM2
-#endif
-
-#ifndef TARGET_CPU_DEFAULT
-#define TARGET_CPU_DEFAULT ((char *) 0)
-#endif
-
-/* Which processor we are running on, for instruction scheduling
- purposes. */
-enum processor_type
-{
- PROCESSOR_ARM2,
- PROCESSOR_ARM3,
- PROCESSOR_ARM6,
- PROCESSOR_ARM7,
- PROCESSOR_ARM8,
- PROCESSOR_STARM,
- PROCESSOR_NONE /* NOTE: This must be last, since it doesn't
- appear in the attr_cpu list */
-};
-
-/* Recast the cpu class to be the cpu attribute. */
-#define arm_cpu_attr ((enum attr_cpu)arm_cpu)
-
-extern enum processor_type arm_cpu;
-
enum prog_mode_type
{
prog_mode26,
@@ -448,6 +454,15 @@ extern int arm_fast_multiply;
/* Nonzero if this chip supports the ARM Architecture 4 extensions */
extern int arm_arch4;
+/* Nonzero if this chip can benefit from load scheduling. */
+extern int arm_ld_sched;
+
+/* Nonzero if this chip is a StrongARM. */
+extern int arm_is_strong;
+
+/* Nonzero if this chip is a an ARM6 or an ARM7. */
+extern int arm_is_6_or_7;
+
#ifndef TARGET_DEFAULT
#define TARGET_DEFAULT 0
#endif
@@ -565,7 +580,12 @@ extern int arm_arch4;
/* This is for compatibility with ARMCC. ARM SDT Reference Manual
(ARM DUI 0020D) page 2-20 says "Structures are aligned on word
boundaries". */
+#ifndef STRUCTURE_SIZE_BOUNDARY
#define STRUCTURE_SIZE_BOUNDARY 32
+#endif
+
+/* Used when parsing command line option -mstructure_size_boundary. */
+extern char * structure_size_string;
/* Non-zero if move instructions will actually fail to work
when given unaligned data. */
@@ -584,8 +604,8 @@ extern int arm_arch4;
r4-r8 S register variable
r9 S (rfp) register variable (real frame pointer)
-
- r10 F S (sl) stack limit (not currently used)
+
+ r10 F S (sl) stack limit (used by -mapcs-stack-check)
r11 F S (fp) argument pointer
r12 (ip) temp workspace
r13 F S (sp) lower end of current stack frame
@@ -640,7 +660,7 @@ extern int arm_arch4;
#define FIXED_REGISTERS \
{ \
0,0,0,0,0,0,0,0, \
- 0,0,1,1,0,1,0,1, \
+ 0,0,0,1,0,1,0,1, \
0,0,0,0,0,0,0,0, \
1,1,1 \
}
@@ -656,11 +676,15 @@ extern int arm_arch4;
#define CALL_USED_REGISTERS \
{ \
1,1,1,1,0,0,0,0, \
- 0,0,1,1,1,1,1,1, \
+ 0,0,0,1,1,1,1,1, \
1,1,1,1,0,0,0,0, \
1,1,1 \
}
+#ifndef SUBTARGET_CONDITIONAL_REGISTER_USAGE
+#define SUBTARGET_CONDITIONAL_REGISTER_USAGE
+#endif
+
/* If doing stupid life analysis, avoid a bug causing a return value r0 to be
trampled. This effectively reduces the number of available registers by 1.
XXX It is a hack, I know.
@@ -680,6 +704,12 @@ extern int arm_arch4;
fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \
call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 0; \
} \
+ else if (TARGET_APCS_STACK) \
+ { \
+ fixed_regs[10] = 1; \
+ call_used_regs[10] = 1; \
+ } \
+ SUBTARGET_CONDITIONAL_REGISTER_USAGE \
}
/* Return number of consecutive hard regs needed starting at reg REGNO
@@ -733,7 +763,7 @@ extern int arm_arch4;
via the stack pointer) in functions that seem suitable.
If we have to have a frame pointer we might as well make use of it.
APCS says that the frame pointer does not need to be pushed in leaf
- functions. */
+ functions, or simple tail call functions. */
#define FRAME_POINTER_REQUIRED \
(current_function_has_nonlocal_label || (TARGET_APCS && !leaf_function_p ()))
@@ -793,12 +823,12 @@ enum reg_class
/* Define which registers fit in which classes.
This is an initializer for a vector of HARD_REG_SET
of length N_REG_CLASSES. */
-#define REG_CLASS_CONTENTS \
-{ \
- 0x0000000, /* NO_REGS */ \
- 0x0FF0000, /* FPU_REGS */ \
- 0x200FFFF, /* GENERAL_REGS */ \
- 0x2FFFFFF /* ALL_REGS */ \
+#define REG_CLASS_CONTENTS \
+{ \
+ { 0x0000000 }, /* NO_REGS */ \
+ { 0x0FF0000 }, /* FPU_REGS */ \
+ { 0x200FFFF }, /* GENERAL_REGS */ \
+ { 0x2FFFFFF } /* ALL_REGS */ \
}
/* The same information, inverted:
@@ -994,27 +1024,25 @@ do { \
otherwise, FUNC is 0. */
#define FUNCTION_VALUE(VALTYPE, FUNC) \
(GET_MODE_CLASS (TYPE_MODE (VALTYPE)) == MODE_FLOAT && TARGET_HARD_FLOAT \
- ? gen_rtx (REG, TYPE_MODE (VALTYPE), 16) \
- : gen_rtx (REG, TYPE_MODE (VALTYPE), 0))
+ ? gen_rtx_REG (TYPE_MODE (VALTYPE), 16) \
+ : gen_rtx_REG (TYPE_MODE (VALTYPE), 0))
/* Define how to find the value returned by a library function
assuming the value has mode MODE. */
#define LIBCALL_VALUE(MODE) \
(GET_MODE_CLASS (MODE) == MODE_FLOAT && TARGET_HARD_FLOAT \
- ? gen_rtx (REG, MODE, 16) \
- : gen_rtx (REG, MODE, 0))
+ ? gen_rtx_REG (MODE, 16) \
+ : gen_rtx_REG (MODE, 0))
/* 1 if N is a possible register number for a function value.
On the ARM, only r0 and f0 can return results. */
#define FUNCTION_VALUE_REGNO_P(REGNO) \
- ((REGNO) == 0 || ((REGNO) == 16) && TARGET_HARD_FLOAT)
+ ((REGNO) == 0 || (((REGNO) == 16) && TARGET_HARD_FLOAT))
/* How large values are returned */
/* A C expression which can inhibit the returning of certain function values
in registers, based on the type of value. */
-#define RETURN_IN_MEMORY(TYPE) \
- (TYPE_MODE ((TYPE)) == BLKmode || \
- (AGGREGATE_TYPE_P ((TYPE)) && arm_return_in_memory ((TYPE))))
+#define RETURN_IN_MEMORY(TYPE) arm_return_in_memory (TYPE)
/* Define DEFAULT_PCC_STRUCT_RETURN to 1 if all structure and union return
values must be in memory. On the ARM, they need only do so if larger
@@ -1041,7 +1069,7 @@ do { \
stack if necessary). */
#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \
((NAMED) \
- ? ((CUM) >= 16 ? 0 : gen_rtx (REG, MODE, (CUM) / 4)) \
+ ? ((CUM) >= 16 ? 0 : gen_rtx_REG (MODE, (CUM) / 4)) \
: 0)
/* For an arg passed partly in registers and partly in memory,
@@ -1131,7 +1159,7 @@ do { \
/* Determine if the epilogue should be output as RTL.
You should override this if you define FUNCTION_EXTRA_EPILOGUE. */
-#define USE_RETURN_INSN use_return_insn ()
+#define USE_RETURN_INSN(ISCOND) use_return_insn (ISCOND)
/* Definitions for register eliminations.
@@ -1172,7 +1200,7 @@ do { \
else if ((FROM) == FRAME_POINTER_REGNUM \
&& (TO) == STACK_POINTER_REGNUM) \
(OFFSET) = (current_function_outgoing_args_size \
- + (get_frame_size () + 3 & ~3)); \
+ + ((get_frame_size () + 3) & ~3)); \
else \
{ \
int regno; \
@@ -1198,7 +1226,7 @@ do { \
&& (regs_ever_live[14] || saved_hard_reg)) \
offset += 4; \
offset += current_function_outgoing_args_size; \
- (OFFSET) = (get_frame_size () + 3 & ~3) + offset; \
+ (OFFSET) = ((get_frame_size () + 3) & ~3) + offset; \
} \
} \
}
@@ -1234,9 +1262,9 @@ do { \
CXT is an RTX for the static chain value for the function. */
#define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \
{ \
- emit_move_insn (gen_rtx (MEM, SImode, plus_constant ((TRAMP), 8)), \
+ emit_move_insn (gen_rtx_MEM (SImode, plus_constant ((TRAMP), 8)), \
(CXT)); \
- emit_move_insn (gen_rtx (MEM, SImode, plus_constant ((TRAMP), 12)), \
+ emit_move_insn (gen_rtx_MEM (SImode, plus_constant ((TRAMP), 12)), \
(FNADDR)); \
}
@@ -1474,7 +1502,9 @@ do \
} */ \
else if (GET_MODE_CLASS (MODE) != MODE_FLOAT \
&& GET_CODE (X) == SYMBOL_REF \
- && CONSTANT_POOL_ADDRESS_P (X)) \
+ && CONSTANT_POOL_ADDRESS_P (X) \
+ && ! (flag_pic \
+ && symbol_mentioned_p (get_pool_constant (X)))) \
goto LABEL; \
else if ((GET_CODE (X) == PRE_INC || GET_CODE (X) == POST_DEC) \
&& (GET_MODE_SIZE (MODE) <= 4) \
@@ -1534,14 +1564,14 @@ extern struct rtx_def *legitimize_pic_address ();
n -= low_n; \
} \
base_reg = gen_reg_rtx (SImode); \
- val = force_operand (gen_rtx (PLUS, SImode, xop0, \
- GEN_INT (n)), NULL_RTX); \
+ val = force_operand (gen_rtx_PLUS (SImode, xop0, \
+ GEN_INT (n)), NULL_RTX); \
emit_move_insn (base_reg, val); \
(X) = (low_n == 0 ? base_reg \
- : gen_rtx (PLUS, SImode, base_reg, GEN_INT (low_n))); \
+ : gen_rtx_PLUS (SImode, base_reg, GEN_INT (low_n))); \
} \
else if (xop0 != XEXP (X, 0) || xop1 != XEXP (x, 1)) \
- (X) = gen_rtx (PLUS, SImode, xop0, xop1); \
+ (X) = gen_rtx_PLUS (SImode, xop0, xop1); \
} \
else if (GET_CODE (X) == MINUS) \
{ \
@@ -1553,7 +1583,7 @@ extern struct rtx_def *legitimize_pic_address ();
if (CONSTANT_P (xop1) && ! symbol_mentioned_p (xop1)) \
xop1 = force_reg (SImode, xop1); \
if (xop0 != XEXP (X, 0) || xop1 != XEXP (X, 1)) \
- (X) = gen_rtx (MINUS, SImode, xop0, xop1); \
+ (X) = gen_rtx_MINUS (SImode, xop0, xop1); \
} \
if (flag_pic) \
(X) = legitimize_pic_address (OLDX, MODE, NULL_RTX); \
@@ -1679,7 +1709,7 @@ extern struct rtx_def *legitimize_pic_address ();
|| (X) == arg_pointer_rtx)
#define DEFAULT_RTX_COSTS(X,CODE,OUTER_CODE) \
- return arm_rtx_costs (X, CODE, OUTER_CODE);
+ return arm_rtx_costs (X, CODE);
/* Moves to and from memory are quite expensive */
#define MEMORY_MOVE_COST(MODE,CLASS,IN) 10
@@ -1727,7 +1757,12 @@ extern int arm_pic_register;
#define FINALIZE_PIC arm_finalize_pic ()
-#define LEGITIMATE_PIC_OPERAND_P(X) (! symbol_mentioned_p (X))
+/* We can't directly access anything that contains a symbol,
+ nor can we indirect via the constant pool. */
+#define LEGITIMATE_PIC_OPERAND_P(X) \
+ (! symbol_mentioned_p (X) \
+ && (! CONSTANT_POOL_ADDRESS_P (X) \
+ || ! symbol_mentioned_p (get_pool_constant (X))))
@@ -1749,12 +1784,10 @@ extern int arm_pic_register;
"CC_DNE", "CC_DEQ", "CC_DLE", "CC_DLT", "CC_DGE", "CC_DGT", "CC_DLEU", \
"CC_DLTU", "CC_DGEU", "CC_DGTU", "CC_C"
-enum machine_mode arm_select_cc_mode ();
#define SELECT_CC_MODE(OP,X,Y) arm_select_cc_mode ((OP), (X), (Y))
#define REVERSIBLE_CC_MODE(MODE) ((MODE) != CCFPEmode)
-enum rtx_code arm_canonicalize_comparison ();
#define CANONICALIZE_COMPARISON(CODE,OP0,OP1) \
do \
{ \
@@ -1775,7 +1808,6 @@ do \
since it hasn't been defined! */
extern struct rtx_def *arm_compare_op0, *arm_compare_op1;
-extern int arm_compare_fp;
/* Define the codes that are matched by predicates in arm.c */
#define PREDICATE_CODES \
@@ -1818,10 +1850,11 @@ extern int arm_compare_fp;
goto JUMPTO
/* Output an internal label definition. */
+#ifndef ASM_OUTPUT_INTERNAL_LABEL
#define ASM_OUTPUT_INTERNAL_LABEL(STREAM, PREFIX, NUM) \
do \
{ \
- char *s = (char *) alloca (40 + strlen (PREFIX)); \
+ char * s = (char *) alloca (40 + strlen (PREFIX)); \
extern int arm_target_label, arm_ccfsm_state; \
extern rtx arm_target_insn; \
\
@@ -1834,15 +1867,16 @@ extern int arm_compare_fp;
ASM_GENERATE_INTERNAL_LABEL (s, (PREFIX), (NUM)); \
ASM_OUTPUT_LABEL (STREAM, s); \
} while (0)
+#endif
/* Output a push or a pop instruction (only used when profiling). */
#define ASM_OUTPUT_REG_PUSH(STREAM,REGNO) \
- fprintf(STREAM,"\tstmfd\t%ssp!,{%s%s}\n", \
- REGISTER_PREFIX, REGISTER_PREFIX, reg_names[REGNO])
+ fprintf (STREAM,"\tstmfd\t%ssp!,{%s%s}\n", \
+ REGISTER_PREFIX, REGISTER_PREFIX, reg_names [REGNO])
#define ASM_OUTPUT_REG_POP(STREAM,REGNO) \
- fprintf(STREAM,"\tldmfd\t%ssp!,{%s%s}\n", \
- REGISTER_PREFIX, REGISTER_PREFIX, reg_names[REGNO])
+ fprintf (STREAM,"\tldmfd\t%ssp!,{%s%s}\n", \
+ REGISTER_PREFIX, REGISTER_PREFIX, reg_names [REGNO])
/* Target characters. */
#define TARGET_BELL 007
@@ -1857,7 +1891,7 @@ extern int arm_compare_fp;
we're optimising. Otherwise it's of no use anyway. */
#define FINAL_PRESCAN_INSN(INSN, OPVEC, NOPERANDS) \
if (optimize) \
- final_prescan_insn (INSN, OPVEC, NOPERANDS)
+ arm_final_prescan_insn (INSN)
#define PRINT_OPERAND_PUNCT_VALID_P(CODE) \
((CODE) == '?' || (CODE) == '|' || (CODE) == '@')
@@ -1885,7 +1919,7 @@ extern int arm_compare_fp;
{ \
rtx base = XEXP (X, 0); \
rtx index = XEXP (X, 1); \
- char *base_reg_name; \
+ char * base_reg_name; \
HOST_WIDE_INT offset = 0; \
if (GET_CODE (base) != REG) \
{ \
@@ -1998,7 +2032,7 @@ do { \
#define RETURN_ADDR_RTX(COUNT, FRAME) \
((COUNT == 0) \
- ? gen_rtx (MEM, Pmode, plus_constant (FRAME, -4)) \
+ ? gen_rtx_MEM (Pmode, plus_constant (FRAME, -4)) \
: NULL_RTX)
/* Used to mask out junk bits from the return address, such as
@@ -2010,111 +2044,135 @@ do { \
when running in 32 bit mode. */ \
((!TARGET_APCS_32) ? (GEN_INT (0x03fffffc)) : (GEN_INT (0xffffffff)))
-/* Prototypes for arm.c -- actually, they aren't since the types aren't
- fully defined yet. */
-
-void arm_override_options (/* void */);
-int use_return_insn (/* void */);
-int const_ok_for_arm (/* HOST_WIDE_INT */);
-int const_ok_for_op (/* HOST_WIDE_INT, enum rtx_code,
- enum machine_mode */);
-int arm_split_constant (/* enum rtx_code, enum machine_mode,
- HOST_WIDE_INT, struct rtx_def *,
- struct rtx_def *, int */);
-enum rtx_code arm_canonicalize_comparison (/* enum rtx_code,
- struct rtx_def ** */);
-int arm_return_in_memory (/* union tree_node * */);
-int legitimate_pic_operand_p (/* struct rtx_def * */);
-struct rtx_def *legitimize_pic_address (/* struct rtx_def *,
- enum machine_mode,
- struct rtx_def * */);
-int is_pic (/* struct rtx_def * */);
-void arm_finalize_pic (/* void */);
-int arm_rtx_costs (/* struct rtx_def *, enum rtx_code, enum rtx_code */);
-int arm_adjust_cost (/* struct rtx_def *, struct rtx_def *,
- struct rtx_def *, int */);
-int const_double_rtx_ok_for_fpu (/* struct rtx_def * */);
-int neg_const_double_rtx_ok_for_fpu (/* struct rtx_def * */);
-int s_register_operand (/* struct rtx_def *, enum machine_mode */);
-int f_register_operand (/* struct rtx_def *, enum machine_mode */);
-int reg_or_int_operand (/* struct rtx_def *, enum machine_mode */);
-int reload_memory_operand (/* struct rtx_def *, enum machine_mode */);
-int arm_rhs_operand (/* struct rtx_def *, enum machine_mode */);
-int arm_rhsm_operand (/* struct rtx_def *, enum machine_mode */);
-int arm_add_operand (/* struct rtx_def *, enum machine_mode */);
-int arm_not_operand (/* struct rtx_def *, enum machine_mode */);
-int offsettable_memory_operand (/* struct rtx_def *, enum machine_mode */);
-int alignable_memory_operand (/* struct rtx_def *, enum machine_mode */);
-int bad_signed_byte_operand (/* struct rtx_def *, enum machine_mode */);
-int fpu_rhs_operand (/* struct rtx_def *, enum machine_mode */);
-int fpu_add_operand (/* struct rtx_def *, enum machine_mode */);
-int power_of_two_operand (/* struct rtx_def *, enum machine_mode */);
-int di_operand (/* struct rtx_def *, enum machine_mode */);
-int soft_df_operand (/* struct rtx_def *, enum machine_mode */);
-int index_operand (/* struct rtx_def *, enum machine_mode */);
-int const_shift_operand (/* struct rtx_def *, enum machine_mode */);
-int shiftable_operator (/* struct rtx_def *, enum machine_mode */);
-int shift_operator (/* struct rtx_def *, enum machine_mode */);
-int equality_operator (/* struct rtx_def *, enum machine_mode */);
-int minmax_operator (/* struct rtx_def *, enum machine_mode */);
-int cc_register (/* struct rtx_def *, enum machine_mode */);
-int dominant_cc_register (/* struct rtx_def *, enum machine_mode */);
-int symbol_mentioned_p (/* struct rtx_def * */);
-int label_mentioned_p (/* struct rtx_def * */);
-enum rtx_code minmax_code (/* struct rtx_def * */);
-int adjacent_mem_locations (/* struct rtx_def *, struct rtx_def * */);
-int load_multiple_operation (/* struct rtx_def *, enum machine_mode */);
-int store_multiple_operation (/* struct rtx_def *, enum machine_mode */);
-int load_multiple_sequence (/* struct rtx_def **, int, int *, int *,
- HOST_WIDE_INT * */);
-char *emit_ldm_seq (/* struct rtx_def **, int */);
-int store_multiple_sequence (/* struct rtx_def **, int, int *, int *,
- HOST_WIDE_INT * */);
-char *emit_stm_seq (/* struct rtx_def **, int */);
-int multi_register_push (/* struct rtx_def *, enum machine_mode */);
-int arm_valid_machine_decl_attribute (/* union tree_node *, union tree_node *,
- union tree_node *,
- union tree_node * */);
-struct rtx_def *arm_gen_load_multiple (/* int, int, struct rtx_def *,
- int, int, int, int */);
-struct rtx_def *arm_gen_store_multiple (/* int, int, struct rtx_def *,
- int, int, int, int */);
-int arm_gen_movstrqi (/* struct rtx_def ** */);
-struct rtx_def *gen_rotated_half_load (/* struct rtx_def * */);
-enum machine_mode arm_select_cc_mode (/* enum rtx_code, struct rtx_def *,
- struct rtx_def * */);
-struct rtx_def *gen_compare_reg (/* enum rtx_code, struct rtx_def *,
- struct rtx_def * */);
-void arm_reload_in_hi (/* struct rtx_def ** */);
-void arm_reload_out_hi (/* struct rtx_def ** */);
-void arm_reorg (/* struct rtx_def * */);
-char *fp_immediate_constant (/* struct rtx_def * */);
-void print_multi_reg (/* FILE *, char *, int, int */);
-char *output_call (/* struct rtx_def ** */);
-char *output_call_mem (/* struct rtx_def ** */);
-char *output_mov_long_double_fpu_from_arm (/* struct rtx_def ** */);
-char *output_mov_long_double_arm_from_fpu (/* struct rtx_def ** */);
-char *output_mov_long_double_arm_from_arm (/* struct rtx_def ** */);
-char *output_mov_double_fpu_from_arm (/* struct rtx_def ** */);
-char *output_mov_double_arm_from_fpu (/* struct rtx_def ** */);
-char *output_move_double (/* struct rtx_def ** */);
-char *output_mov_immediate (/* struct rtx_def ** */);
-char *output_add_immediate (/* struct rtx_def ** */);
-char *arithmetic_instr (/* struct rtx_def *, int */);
-void output_ascii_pseudo_op (/* FILE *, unsigned char *, int */);
-char *output_return_instruction (/* struct rtx_def *, int, int */);
-int arm_volatile_func (/* void */);
-void output_func_prologue (/* FILE *, int */);
-void output_func_epilogue (/* FILE *, int */);
-void arm_expand_prologue (/* void */);
-void arm_print_operand (/* FILE *, struct rtx_def *, int */);
-void final_prescan_insn (/* struct rtx_def *, struct rtx_def **, int */);
+/* Prototypes for arm.c */
+
+#ifdef BUFSIZ /* stdio.h has been included, ok to use FILE * */
+#define STDIO_PROTO(ARGS) PROTO (ARGS)
+#else
+#define STDIO_PROTO(ARGS) ()
+#endif
+
+#ifndef TREE_CODE
+union tree_node;
+#define Tree union tree_node *
+#else
+#define Tree tree
+#endif
+
+#ifndef RTX_CODE
+struct rtx_def;
+#define Rtx struct rtx_def *
+#else
+#define Rtx rtx
+#endif
+
+#ifndef HOST_WIDE_INT
+#include "hwint.h"
+#endif
+#define Hint HOST_WIDE_INT
+
+#ifndef HAVE_MACHINE_MODES
+#include "machmode.h"
+#endif
+#define Mmode enum machine_mode
+
+#ifdef RTX_CODE
+#define RTX_CODE_PROTO(ARGS) PROTO (ARGS)
+#else
+#define RTX_CODE_PROTO(ARGS) ()
+#endif
+#define Rcode enum rtx_code
+
+void arm_override_options PROTO ((void));
+int use_return_insn PROTO ((int));
+int const_ok_for_arm PROTO ((Hint));
+int arm_split_constant RTX_CODE_PROTO ((Rcode, Mmode, Hint, Rtx, Rtx, int));
+Rcode arm_canonicalize_comparison RTX_CODE_PROTO ((Rcode, Rtx *));
+int arm_return_in_memory PROTO ((Tree));
+int legitimate_pic_operand_p PROTO ((Rtx));
+Rtx legitimize_pic_address PROTO ((Rtx, Mmode, Rtx));
+int is_pic PROTO ((Rtx));
+void arm_finalize_pic PROTO ((void));
+int arm_rtx_costs RTX_CODE_PROTO ((Rtx, Rcode));
+int arm_adjust_cost PROTO ((Rtx, Rtx, Rtx, int));
+int const_double_rtx_ok_for_fpu PROTO ((Rtx));
+int neg_const_double_rtx_ok_for_fpu PROTO ((Rtx));
+int s_register_operand PROTO ((Rtx, Mmode));
+int f_register_operand PROTO ((Rtx, Mmode));
+int reg_or_int_operand PROTO ((Rtx, Mmode));
+int reload_memory_operand PROTO ((Rtx, Mmode));
+int arm_rhs_operand PROTO ((Rtx, Mmode));
+int arm_rhsm_operand PROTO ((Rtx, Mmode));
+int arm_add_operand PROTO ((Rtx, Mmode));
+int arm_not_operand PROTO ((Rtx, Mmode));
+int offsettable_memory_operand PROTO ((Rtx, Mmode));
+int alignable_memory_operand PROTO ((Rtx, Mmode));
+int bad_signed_byte_operand PROTO ((Rtx, Mmode));
+int fpu_rhs_operand PROTO ((Rtx, Mmode));
+int fpu_add_operand PROTO ((Rtx, Mmode));
+int power_of_two_operand PROTO ((Rtx, Mmode));
+int di_operand PROTO ((Rtx, Mmode));
+int soft_df_operand PROTO ((Rtx, Mmode));
+int index_operand PROTO ((Rtx, Mmode));
+int const_shift_operand PROTO ((Rtx, Mmode));
+int shiftable_operator PROTO ((Rtx, Mmode));
+int shift_operator PROTO ((Rtx, Mmode));
+int equality_operator PROTO ((Rtx, Mmode));
+int minmax_operator PROTO ((Rtx, Mmode));
+int cc_register PROTO ((Rtx, Mmode));
+int dominant_cc_register PROTO ((Rtx, Mmode));
+int symbol_mentioned_p PROTO ((Rtx));
+int label_mentioned_p PROTO ((Rtx));
+Rcode minmax_code PROTO ((Rtx));
+int adjacent_mem_locations PROTO ((Rtx, Rtx));
+int load_multiple_operation PROTO ((Rtx, Mmode));
+int store_multiple_operation PROTO ((Rtx, Mmode));
+int load_multiple_sequence PROTO ((Rtx *, int, int *, int *, Hint *));
+char * emit_ldm_seq PROTO ((Rtx *, int));
+int store_multiple_sequence PROTO ((Rtx *, int, int *, int *, Hint *));
+char * emit_stm_seq PROTO ((Rtx *, int));
+int arm_valid_machine_decl_attribute PROTO ((Tree, Tree, Tree));
+Rtx arm_gen_load_multiple PROTO ((int, int, Rtx, int, int, int, int, int));
+Rtx arm_gen_store_multiple PROTO ((int, int, Rtx, int, int, int, int, int));
+int arm_gen_movstrqi PROTO ((Rtx *));
+Rtx gen_rotated_half_load PROTO ((Rtx));
+Mmode arm_select_cc_mode RTX_CODE_PROTO ((Rcode, Rtx, Rtx));
+Rtx gen_compare_reg RTX_CODE_PROTO ((Rcode, Rtx, Rtx, int));
+void arm_reload_in_hi PROTO ((Rtx *));
+void arm_reload_out_hi PROTO ((Rtx *));
+void arm_reorg PROTO ((Rtx));
+char * fp_immediate_constant PROTO ((Rtx));
+void print_multi_reg STDIO_PROTO ((FILE *, char *, int, int));
+char * output_call PROTO ((Rtx *));
+char * output_call_mem PROTO ((Rtx *));
+char * output_mov_long_double_fpu_from_arm PROTO ((Rtx *));
+char * output_mov_long_double_arm_from_fpu PROTO ((Rtx *));
+char * output_mov_long_double_arm_from_arm PROTO ((Rtx *));
+char * output_mov_double_fpu_from_arm PROTO ((Rtx *));
+char * output_mov_double_arm_from_fpu PROTO ((Rtx *));
+char * output_move_double PROTO ((Rtx *));
+char * output_mov_immediate PROTO ((Rtx *));
+char * output_add_immediate PROTO ((Rtx *));
+char * arithmetic_instr PROTO ((Rtx, int));
+void output_ascii_pseudo_op STDIO_PROTO ((FILE *, unsigned char *, int));
+char * output_return_instruction PROTO ((Rtx, int, int));
+int arm_volatile_func PROTO ((void));
+void output_func_prologue STDIO_PROTO ((FILE *, int));
+void output_func_epilogue STDIO_PROTO ((FILE *, int));
+void arm_expand_prologue PROTO ((void));
+void arm_print_operand STDIO_PROTO ((FILE *, Rtx, int));
+void arm_final_prescan_insn PROTO ((Rtx));
+int short_branch PROTO ((int, int));
+void assemble_align PROTO((int)); /* Used in arm.md, but defined in output.c */
+int multi_register_push PROTO ((Rtx, Mmode));
#ifdef AOF_ASSEMBLER
-struct rtx_def *aof_pic_entry (/* struct rtx_def * */);
-void aof_dump_pic_table (/* FILE * */);
-char *aof_text_section (/* void */);
-char *aof_data_section (/* void */);
-void aof_add_import (/* char * */);
-void aof_delete_import (/* char * */);
-void aof_dump_imports (/* FILE * */);
+Rtx aof_pic_entry PROTO ((Rtx));
+void aof_dump_pic_table STDIO_PROTO ((FILE *));
+char * aof_text_section PROTO ((void));
+char * aof_data_section PROTO ((void));
+void aof_add_import PROTO ((char *));
+void aof_delete_import PROTO ((char *));
+void aof_dump_imports STDIO_PROTO ((FILE *));
#endif
+
+#endif /* __ARM_H__ */
diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
index 20b8d57b40a..71cb167f57e 100644
--- a/gcc/config/arm/arm.md
+++ b/gcc/config/arm/arm.md
@@ -1,8 +1,8 @@
-;;- Machine description for Advanced RISC Machines' ARM for GNU compiler
-;; Copyright (C) 1991, 93-97, 1998 Free Software Foundation, Inc.
+;;- Machine description for ARM for GNU compiler
+;; Copyright (C) 1991, 93-98, 1999 Free Software Foundation, Inc.
;; Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl)
;; and Martin Simmons (@harleqn.co.uk).
-;; More major hacks by Richard Earnshaw (rwe11@cl.cam.ac.uk)
+;; More major hacks by Richard Earnshaw (rearnsha@arm.com).
;; This file is part of GNU CC.
@@ -45,12 +45,7 @@
; by the -mapcs-{32,26} flag, and possibly the -mcpu=... option.
(define_attr "prog_mode" "prog26,prog32" (const (symbol_ref "arm_prog_mode")))
-; CPU attribute is used to determine whether condition codes are clobbered
-; by a call insn: on the arm6 they are if in 32-bit addressing mode; on the
-; arm2 and arm3 the condition codes are restored by the return.
-
-(define_attr "cpu" "arm2,arm3,arm6,arm7,arm8,st_arm"
- (const (symbol_ref "arm_cpu_attr")))
+(define_attr "is_strongarm" "no,yes" (const (symbol_ref "arm_is_strong")))
; Floating Point Unit. If we only have floating point emulation, then there
; is no point in scheduling the floating point insns. (Well, for best
@@ -102,11 +97,9 @@
"normal,mult,block,float,fdivx,fdivd,fdivs,fmul,ffmul,farith,ffarith,float_em,f_load,f_store,f_mem_r,r_mem_f,f_2_r,r_2_f,call,load,store1,store2,store3,store4"
(const_string "normal"))
-; Load scheduling, set from the cpu characteristic
-(define_attr "ldsched" "no,yes"
- (if_then_else (eq_attr "cpu" "arm8,st_arm")
- (const_string "yes")
- (const_string "no")))
+; Load scheduling, set from the arm_ld_sched variable
+; initialised by arm_override_options()
+(define_attr "ldsched" "no,yes" (const (symbol_ref "arm_ld_sched")))
; condition codes: this one is used by final_prescan_insn to speed up
; conditionalizing instructions. It saves having to scan the rtl to see if
@@ -135,6 +128,12 @@
(const_string "clob") (const_string "nocond"))
(const_string "nocond")))
+; Only model the write buffer for ARM6 and ARM7. Earlier processors don't
+; have one. Later ones, such as StrongARM, have write-back caches, so don't
+; suffer blockages enough to warrent modelling this (and it can adversely
+; affect the schedule).
+(define_attr "model_wbuf" "no,yes" (const (symbol_ref "arm_is_6_or_7")))
+
(define_attr "write_conflict" "no,yes"
(if_then_else (eq_attr "type"
"block,float_em,f_load,f_store,f_mem_r,r_mem_f,call,load")
@@ -194,59 +193,87 @@
(define_function_unit "fpa_mem" 1 0 (and (eq_attr "fpu" "fpa")
(eq_attr "type" "f_load")) 3 1)
-(define_function_unit "write_buf" 1 2 (eq_attr "type" "store1") 5 3)
-(define_function_unit "write_buf" 1 2 (eq_attr "type" "store2") 7 4)
-(define_function_unit "write_buf" 1 2 (eq_attr "type" "store3") 9 5)
-(define_function_unit "write_buf" 1 2 (eq_attr "type" "store4") 11 6)
-(define_function_unit "write_buf" 1 2 (eq_attr "type" "r_mem_f") 5 3)
-
-;; The write_blockage unit models (partially), the fact that writes will stall
+;;--------------------------------------------------------------------
+;; Write buffer
+;;--------------------------------------------------------------------
+;; Strictly we should model a 4-deep write buffer for ARM7xx based chips
+(define_function_unit "write_buf" 1 2
+ (and (eq_attr "model_wbuf" "yes")
+ (eq_attr "type" "store1,r_mem_f")) 5 3)
+(define_function_unit "write_buf" 1 2
+ (and (eq_attr "model_wbuf" "yes")
+ (eq_attr "type" "store2")) 7 4)
+(define_function_unit "write_buf" 1 2
+ (and (eq_attr "model_wbuf" "yes")
+ (eq_attr "type" "store3")) 9 5)
+(define_function_unit "write_buf" 1 2
+ (and (eq_attr "model_wbuf" "yes")
+ (eq_attr "type" "store4")) 11 6)
+
+;;--------------------------------------------------------------------
+;; Write blockage unit
+;;--------------------------------------------------------------------
+;; The write_blockage unit models (partially), the fact that reads will stall
;; until the write buffer empties.
-
-(define_function_unit "write_blockage" 1 0 (eq_attr "type" "store1") 5 5
+;; 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_function_unit "write_blockage" 1 0 (and (eq_attr "model_wbuf" "yes")
+ (eq_attr "type" "store1")) 5 5
[(eq_attr "write_conflict" "yes")])
-(define_function_unit "write_blockage" 1 0 (eq_attr "type" "store2") 7 7
+(define_function_unit "write_blockage" 1 0 (and (eq_attr "model_wbuf" "yes")
+ (eq_attr "type" "store2")) 7 7
[(eq_attr "write_conflict" "yes")])
-(define_function_unit "write_blockage" 1 0 (eq_attr "type" "store3") 9 9
+(define_function_unit "write_blockage" 1 0 (and (eq_attr "model_wbuf" "yes")
+ (eq_attr "type" "store3")) 9 9
[(eq_attr "write_conflict" "yes")])
-(define_function_unit "write_blockage" 1 0 (eq_attr "type" "store4") 11 11
+(define_function_unit "write_blockage" 1 0
+ (and (eq_attr "model_wbuf" "yes") (eq_attr "type" "store4")) 11 11
[(eq_attr "write_conflict" "yes")])
-(define_function_unit "write_blockage" 1 0 (eq_attr "type" "r_mem_f") 5 5
- [(eq_attr "write_conflict" "yes")])
-(define_function_unit "write_blockage" 1 0
- (eq_attr "write_conflict" "yes") 1 1)
-
+(define_function_unit "write_blockage" 1 0
+ (and (eq_attr "model_wbuf" "yes")
+ (eq_attr "write_conflict" "yes")) 1 1)
+
+;;--------------------------------------------------------------------
+;; Core unit
+;;--------------------------------------------------------------------
+;; Everything must spend at least one cycle in the core unit
+(define_function_unit "core" 1 0
+ (and (eq_attr "ldsched" "yes") (eq_attr "type" "store1")) 1 1)
+(define_function_unit "core" 1 0
+ (and (eq_attr "ldsched" "yes") (eq_attr "type" "load")) 2 1)
-(define_function_unit "core" 1 1 (eq_attr "core_cycles" "single") 1 1)
+(define_function_unit "core" 1 0
+ (and (eq_attr "ldsched" "!yes") (eq_attr "type" "load,store1")) 2 2)
-(define_function_unit "core" 1 1
- (and (eq_attr "ldsched" "yes") (eq_attr "type" "load")) 1 1)
+(define_function_unit "core" 1 0
+ (and (eq_attr "fpu" "fpa") (eq_attr "type" "f_load")) 3 3)
-(define_function_unit "core" 1 1
- (and (eq_attr "ldsched" "!yes") (eq_attr "type" "load")) 2 2)
+(define_function_unit "core" 1 0
+ (and (eq_attr "fpu" "fpa") (eq_attr "type" "f_store")) 4 4)
-(define_function_unit "core" 1 1 (eq_attr "type" "mult") 16 16)
+(define_function_unit "core" 1 0
+ (and (eq_attr "fpu" "fpa") (eq_attr "type" "r_mem_f")) 6 6)
-(define_function_unit "core" 1 1
- (and (eq_attr "ldsched" "yes") (eq_attr "type" "store1")) 1 1)
+(define_function_unit "core" 1 0
+ (and (eq_attr "fpu" "fpa") (eq_attr "type" "f_mem_r")) 7 7)
-(define_function_unit "core" 1 1
- (and (eq_attr "ldsched" "!yes") (eq_attr "type" "store1")) 2 2)
+(define_function_unit "core" 1 0
+ (and (eq_attr "ldsched" "no") (eq_attr "type" "mult")) 16 16)
-(define_function_unit "core" 1 1 (eq_attr "type" "store2") 3 3)
+(define_function_unit "core" 1 0
+ (and (and (eq_attr "ldsched" "yes") (eq_attr "is_strongarm" "no"))
+ (eq_attr "type" "mult")) 4 4)
-(define_function_unit "core" 1 1 (eq_attr "type" "store3") 4 4)
+(define_function_unit "core" 1 0
+ (and (and (eq_attr "ldsched" "yes") (eq_attr "is_strongarm" "yes"))
+ (eq_attr "type" "mult")) 3 2)
-(define_function_unit "core" 1 1 (eq_attr "type" "store4") 5 5)
+(define_function_unit "core" 1 0 (eq_attr "type" "store2") 3 3)
-(define_function_unit "core" 1 1
- (and (eq_attr "core_cycles" "multi")
- (eq_attr "type" "!mult,load,store2,store3,store4")) 32 32)
-
-(define_function_unit "loader" 1 0
- (and (eq_attr "ldsched" "yes") (eq_attr "type" "load")) 2 1)
+(define_function_unit "core" 1 0 (eq_attr "type" "store3") 4 4)
+(define_function_unit "core" 1 0 (eq_attr "type" "store4") 5 5)
;; Note: For DImode insns, there is normally no reason why operands should
;; not be in the same register, what we don't want is for something being
@@ -1160,43 +1187,31 @@
&& INTVAL (operands[1]) + (INTVAL (operands[2]) & 1) <= 8
&& INTVAL (operands[1]) + INTVAL (operands[2]) <= 32"
"*
-{
- unsigned int mask = 0;
- int cnt = INTVAL (operands[1]);
-
- while (cnt--)
- mask = (mask << 1) | 1;
- operands[1] = GEN_INT (mask << INTVAL (operands[2]));
+ operands[1] = GEN_INT (((1 << INTVAL (operands[1])) - 1)
+ << INTVAL (operands[2]));
output_asm_insn (\"tst%?\\t%0, %1\", operands);
return \"\";
-}
"
[(set_attr "conds" "set")])
-(define_insn "*zeroextractqi_compare0_scratch"
- [(set (reg:CC_NOOV 24)
- (compare:CC_NOOV (zero_extract:SI
- (match_operand:QI 0 "memory_operand" "m")
- (match_operand 1 "const_int_operand" "n")
- (match_operand 2 "const_int_operand" "n"))
- (const_int 0)))
- (clobber (match_scratch:QI 3 "=r"))]
- "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 8
- && INTVAL (operands[1]) > 0 && INTVAL (operands[1]) <= 8"
+(define_insn "*ne_zeroextractsi"
+ [(set (match_operand:SI 0 "s_register_operand" "=r")
+ (ne:SI (zero_extract:SI
+ (match_operand:SI 1 "s_register_operand" "r")
+ (match_operand:SI 2 "const_int_operand" "n")
+ (match_operand:SI 3 "const_int_operand" "n"))
+ (const_int 0)))]
+ "INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
+ && INTVAL (operands[2]) > 0
+ && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
+ && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32"
"*
-{
- unsigned int mask = 0;
- int cnt = INTVAL (operands[1]);
-
- while (cnt--)
- mask = (mask << 1) | 1;
- operands[1] = GEN_INT (mask << INTVAL (operands[2]));
- output_asm_insn (\"ldr%?b\\t%3, %0\", operands);
- output_asm_insn (\"tst%?\\t%3, %1\", operands);
- return \"\";
-}
+ operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
+ << INTVAL (operands[3]));
+ output_asm_insn (\"ands\\t%0, %1, %2\", operands);
+ return \"movne\\t%0, #1\";
"
-[(set_attr "conds" "set")
+[(set_attr "conds" "clob")
(set_attr "length" "8")])
;;; ??? This pattern is bogus. If operand3 has bits outside the range
@@ -1265,8 +1280,8 @@
rtx op1 = gen_reg_rtx (SImode);
emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
- emit_insn (gen_iorsi3 (op1, gen_rtx (LSHIFTRT, SImode, operands[0],
- operands[1]),
+ emit_insn (gen_iorsi3 (op1, gen_rtx_LSHIFTRT (SImode, operands[0],
+ operands[1]),
op0));
emit_insn (gen_rotlsi3 (subtarget, op1, operands[1]));
}
@@ -1282,8 +1297,8 @@
emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
emit_insn (gen_ashlsi3 (op1, operands[0], operands[1]));
emit_insn (gen_iorsi3 (subtarget,
- gen_rtx (LSHIFTRT, SImode, op1,
- operands[1]), op0));
+ gen_rtx_LSHIFTRT (SImode, op1, operands[1]),
+ op0));
}
else
{
@@ -1320,13 +1335,13 @@
}
if (start_bit != 0)
- op0 = gen_rtx (ASHIFT, SImode, op0, operands[2]);
+ op0 = gen_rtx_ASHIFT (SImode, op0, operands[2]);
emit_insn (gen_andsi_notsi_si (op2, operands[0], op0));
}
if (start_bit != 0)
- op1 = gen_rtx (ASHIFT, SImode, op1, operands[2]);
+ op1 = gen_rtx_ASHIFT (SImode, op1, operands[2]);
emit_insn (gen_iorsi3 (subtarget, op1, op2));
}
@@ -1871,7 +1886,7 @@
(define_insn "abssi2"
[(set (match_operand:SI 0 "s_register_operand" "=r,&r")
(abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))
- (clobber (reg 24))]
+ (clobber (reg:CC 24))]
""
"@
cmp\\t%0, #0\;rsblt\\t%0, %0, #0
@@ -1882,7 +1897,7 @@
(define_insn "*neg_abssi2"
[(set (match_operand:SI 0 "s_register_operand" "=r,&r")
(neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))))
- (clobber (reg 24))]
+ (clobber (reg:CC 24))]
""
"@
cmp\\t%0, #0\;rsbgt\\t%0, %0, #0
@@ -2154,8 +2169,12 @@
{
if (arm_arch4 && GET_CODE (operands[1]) == MEM)
{
- emit_insn (gen_rtx (SET, VOIDmode, operands[0],
- gen_rtx (ZERO_EXTEND, SImode, operands[1])));
+ /* Note: We do not have to worry about TARGET_SHORT_BY_BYTES
+ here because the insn below will generate an LDRH instruction
+ rather than an LDR instruction, so we cannot get an unaligned
+ word access. */
+ emit_insn (gen_rtx_SET (VOIDmode, operands[0],
+ gen_rtx_ZERO_EXTEND (SImode, operands[1])));
DONE;
}
if (TARGET_SHORT_BY_BYTES && GET_CODE (operands[1]) == MEM)
@@ -2253,11 +2272,15 @@
(const_int 16)))]
""
"
-{
+{
if (arm_arch4 && GET_CODE (operands[1]) == MEM)
{
- emit_insn (gen_rtx (SET, VOIDmode, operands[0],
- gen_rtx (SIGN_EXTEND, SImode, operands[1])));
+ /* Note: We do not have to worry about TARGET_SHORT_BY_BYTES
+ here because the insn below will generate an LDRH instruction
+ rather than an LDR instruction, so we cannot get an unaligned
+ word access. */
+ emit_insn (gen_rtx_SET (VOIDmode, operands[0],
+ gen_rtx_SIGN_EXTEND (SImode, operands[1])));
DONE;
}
@@ -2285,13 +2308,11 @@
rtx mem1, mem2;
rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
- mem1 = gen_rtx (MEM, QImode, addr);
- MEM_VOLATILE_P (mem1) = MEM_VOLATILE_P (operands[1]);
- MEM_IN_STRUCT_P (mem1) = MEM_IN_STRUCT_P (operands[1]);
+ mem1 = gen_rtx_MEM (QImode, addr);
+ MEM_COPY_ATTRIBUTES (mem1, operands[1]);
RTX_UNCHANGING_P (mem1) = RTX_UNCHANGING_P (operands[1]);
- mem2 = gen_rtx (MEM, QImode, plus_constant (addr, 1));
- MEM_VOLATILE_P (mem2) = MEM_VOLATILE_P (operands[1]);
- MEM_IN_STRUCT_P (mem2) = MEM_IN_STRUCT_P (operands[1]);
+ mem2 = gen_rtx_MEM (QImode, plus_constant (addr, 1));
+ MEM_COPY_ATTRIBUTES (mem2, operands[1]);
RTX_UNCHANGING_P (mem2) = RTX_UNCHANGING_P (operands[1]);
operands[0] = gen_lowpart (SImode, operands[0]);
operands[1] = mem1;
@@ -2362,8 +2383,9 @@
{
if (arm_arch4 && GET_CODE (operands[1]) == MEM)
{
- emit_insn (gen_rtx (SET, VOIDmode, operands[0],
- gen_rtx (SIGN_EXTEND, HImode, operands[1])));
+ emit_insn (gen_rtx_SET (VOIDmode,
+ operands[0],
+ gen_rtx_SIGN_EXTEND (HImode, operands[1])));
DONE;
}
if (! s_register_operand (operands[1], QImode))
@@ -2381,7 +2403,7 @@
"arm_arch4"
"*
/* If the address is invalid, this will split the instruction into two. */
- if (bad_signed_byte_operand(operands[1], QImode))
+ if (bad_signed_byte_operand (operands[1], QImode))
return \"#\";
return \"ldr%?sb\\t%0, %1\";
"
@@ -2398,10 +2420,9 @@
{
HOST_WIDE_INT offset;
- operands[3] = gen_rtx (REG, SImode, REGNO (operands[0]));
- operands[2] = gen_rtx (MEM, QImode, operands[3]);
- MEM_VOLATILE_P (operands[2]) = MEM_VOLATILE_P (operands[1]);
- MEM_IN_STRUCT_P (operands[2]) = MEM_IN_STRUCT_P (operands[1]);
+ operands[3] = gen_rtx_REG (SImode, REGNO (operands[0]));
+ operands[2] = gen_rtx_MEM (QImode, operands[3]);
+ MEM_COPY_ATTRIBUTES (operands[2], operands[1]);
RTX_UNCHANGING_P (operands[2]) = RTX_UNCHANGING_P (operands[1]);
operands[1] = XEXP (operands[1], 0);
if (GET_CODE (operands[1]) == PLUS
@@ -2418,8 +2439,9 @@
else if (GET_CODE (operands[1]) == PLUS
&& GET_CODE (XEXP (operands[1], 1)) != CONST_INT
&& ! s_register_operand (XEXP (operands[1], 1), VOIDmode))
- operands[1] = gen_rtx (PLUS, GET_MODE (operands[1]),
- XEXP (operands[1], 1), XEXP (operands[1], 0));
+ operands[1] = gen_rtx_PLUS (GET_MODE (operands[1]),
+ XEXP (operands[1], 1),
+ XEXP (operands[1], 0));
}
")
@@ -2435,8 +2457,9 @@
{
if (arm_arch4 && GET_CODE (operands[1]) == MEM)
{
- emit_insn (gen_rtx (SET, VOIDmode, operands[0],
- gen_rtx (SIGN_EXTEND, SImode, operands[1])));
+ emit_insn (gen_rtx_SET (VOIDmode,
+ operands[0],
+ gen_rtx_SIGN_EXTEND (SImode, operands[1])));
DONE;
}
if (! s_register_operand (operands[1], QImode))
@@ -2453,7 +2476,7 @@
"arm_arch4"
"*
/* If the address is invalid, this will split the instruction into two. */
- if (bad_signed_byte_operand(operands[1], QImode))
+ if (bad_signed_byte_operand (operands[1], QImode))
return \"#\";
return \"ldr%?sb\\t%0, %1\";
"
@@ -2470,9 +2493,8 @@
{
HOST_WIDE_INT offset;
- operands[2] = gen_rtx (MEM, QImode, operands[0]);
- MEM_VOLATILE_P (operands[2]) = MEM_VOLATILE_P (operands[1]);
- MEM_IN_STRUCT_P (operands[2]) = MEM_IN_STRUCT_P (operands[1]);
+ operands[2] = gen_rtx_MEM (QImode, operands[0]);
+ MEM_COPY_ATTRIBUTES (operands[2], operands[1]);
RTX_UNCHANGING_P (operands[2]) = RTX_UNCHANGING_P (operands[1]);
operands[1] = XEXP (operands[1], 0);
if (GET_CODE (operands[1]) == PLUS
@@ -2489,8 +2511,9 @@
else if (GET_CODE (operands[1]) == PLUS
&& GET_CODE (XEXP (operands[1], 1)) != CONST_INT
&& ! s_register_operand (XEXP (operands[1], 1), VOIDmode))
- operands[1] = gen_rtx (PLUS, GET_MODE (operands[1]),
- XEXP (operands[1], 1), XEXP (operands[1], 0));
+ operands[1] = gen_rtx_PLUS (GET_MODE (operands[1]),
+ XEXP (operands[1], 1),
+ XEXP (operands[1], 0));
}
")
@@ -2615,7 +2638,7 @@
(define_insn "*movsi_insn"
[(set (match_operand:SI 0 "general_operand" "=r,r,r,m")
- (match_operand:SI 1 "general_operand" "rI,K,mi,r"))]
+ (match_operand:SI 1 "general_operand" "rI,K,mi,r"))]
"register_operand (operands[0], SImode)
|| register_operand (operands[1], SImode)"
"@
@@ -2688,11 +2711,15 @@
" [(set_attr "type" "load")])
(define_insn "pic_add_dot_plus_eight"
- [(set (pc) (label_ref (match_operand 0 "" "")))
- (set (match_operand 1 "register_operand" "+r")
- (plus:SI (match_dup 1) (const (plus:SI (pc) (const_int 8)))))]
+ [(set (match_operand 0 "register_operand" "+r")
+ (plus:SI (match_dup 0) (const (plus:SI (pc) (const_int 8)))))
+ (use (label_ref (match_operand 1 "" "")))]
"flag_pic"
- "add%?\\t%1, %|pc, %1")
+ "*
+ ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
+ CODE_LABEL_NUMBER (operands[1]));
+ return \"add%?\\t%0, %|pc, %0\";
+")
;; If copying one reg to another we can set the condition codes according to
;; its value. Such a move is common after a return from subroutine and the
@@ -2825,8 +2852,6 @@
""
"
{
- rtx insn;
-
if (! (reload_in_progress || reload_completed))
{
if (GET_CODE (operands[0]) == MEM)
@@ -2869,10 +2894,14 @@
}
emit_insn (gen_movsi (reg, GEN_INT (val)));
- operands[1] = gen_rtx (SUBREG, HImode, reg, 0);
+ operands[1] = gen_rtx_SUBREG (HImode, reg, 0);
}
else if (! arm_arch4)
{
+ /* Note: We do not have to worry about TARGET_SHORT_BY_BYTES
+ for v4 and up architectures because LDRH instructions will
+ be used to access the HI values, and these cannot generate
+ unaligned word access faults in the MMU. */
if (GET_CODE (operands[1]) == MEM)
{
if (TARGET_SHORT_BY_BYTES)
@@ -2890,10 +2919,9 @@
HOST_WIDE_INT new_offset = INTVAL (offset) & ~2;
rtx new;
- new = gen_rtx (MEM, SImode,
- plus_constant (base, new_offset));
- MEM_VOLATILE_P (new) = MEM_VOLATILE_P (operands[1]);
- MEM_IN_STRUCT_P (new) = MEM_IN_STRUCT_P (operands[1]);
+ new = gen_rtx_MEM (SImode,
+ plus_constant (base, new_offset));
+ MEM_COPY_ATTRIBUTES (new, operands[1]);
RTX_UNCHANGING_P (new) = RTX_UNCHANGING_P (operands[1]);
emit_insn (gen_movsi (reg, new));
if (((INTVAL (offset) & 2) != 0)
@@ -2927,19 +2955,18 @@
if ((INTVAL (offset) & 2) == 2)
{
HOST_WIDE_INT new_offset = INTVAL (offset) ^ 2;
- new = gen_rtx (MEM, SImode,
- plus_constant (base, new_offset));
- MEM_VOLATILE_P (new) = MEM_VOLATILE_P (operands[1]);
- MEM_IN_STRUCT_P (new) = MEM_IN_STRUCT_P (operands[1]);
+ new = gen_rtx_MEM (SImode,
+ plus_constant (base, new_offset));
+ MEM_COPY_ATTRIBUTES (new, operands[1]);
RTX_UNCHANGING_P (new) = RTX_UNCHANGING_P (operands[1]);
emit_insn (gen_movsi (reg, new));
}
else
{
- new = gen_rtx (MEM, SImode, XEXP (operands[1], 0));
- MEM_VOLATILE_P (new) = MEM_VOLATILE_P (operands[1]);
- MEM_IN_STRUCT_P (new) = MEM_IN_STRUCT_P (operands[1]);
- RTX_UNCHANGING_P (new) = RTX_UNCHANGING_P (operands[1]);
+ new = gen_rtx_MEM (SImode, XEXP (operands[1], 0));
+ MEM_COPY_ATTRIBUTES (new, operands[1]);
+ RTX_UNCHANGING_P (new)
+ = RTX_UNCHANGING_P (operands[1]);
emit_insn (gen_rotated_loadsi (reg, new));
}
@@ -2964,7 +2991,7 @@
if (GET_CODE (operands[0]) != REG)
abort ();
- operands[0] = gen_rtx (SUBREG, SImode, operands[0], 0);
+ operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
emit_insn (gen_movsi (operands[0], operands[1]));
DONE;
}
@@ -2981,7 +3008,7 @@
rtx ops[2];
ops[0] = operands[0];
- ops[1] = gen_rtx (MEM, SImode, plus_constant (XEXP (operands[1], 0), 2));
+ ops[1] = gen_rtx_MEM (SImode, plus_constant (XEXP (operands[1], 0), 2));
output_asm_insn (\"ldr%?\\t%0, %1\\t%@ load-rotate\", ops);
return \"\";
}"
@@ -2999,13 +3026,11 @@
rtx mem1, mem2;
rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
- mem1 = gen_rtx (MEM, QImode, addr);
- MEM_VOLATILE_P (mem1) = MEM_VOLATILE_P (operands[1]);
- MEM_IN_STRUCT_P (mem1) = MEM_IN_STRUCT_P (operands[1]);
+ mem1 = gen_rtx_MEM (QImode, addr);
+ MEM_COPY_ATTRIBUTES (mem1, operands[1]);
RTX_UNCHANGING_P (mem1) = RTX_UNCHANGING_P (operands[1]);
- mem2 = gen_rtx (MEM, QImode, plus_constant (addr, 1));
- MEM_VOLATILE_P (mem2) = MEM_VOLATILE_P (operands[1]);
- MEM_IN_STRUCT_P (mem2) = MEM_IN_STRUCT_P (operands[1]);
+ mem2 = gen_rtx_MEM (QImode, plus_constant (addr, 1));
+ MEM_COPY_ATTRIBUTES (mem2, operands[1]);
RTX_UNCHANGING_P (mem2) = RTX_UNCHANGING_P (operands[1]);
operands[0] = gen_lowpart (SImode, operands[0]);
operands[1] = mem1;
@@ -3041,7 +3066,6 @@
")
;; Pattern to recognise insn generated default case above
-
(define_insn "*movhi_insn_arch4"
[(set (match_operand:HI 0 "general_operand" "=r,r,r,m")
(match_operand:HI 1 "general_operand" "rI,K,m,r"))]
@@ -3057,7 +3081,7 @@
[(set_attr "type" "*,*,load,store1")])
(define_insn "*movhi_insn_littleend"
- [(set (match_operand:HI 0 "general_operand" "=r,r,r")
+ [(set (match_operand:HI 0 "s_register_operand" "=r,r,r")
(match_operand:HI 1 "general_operand" "rI,K,m"))]
"! arm_arch4
&& ! BYTES_BIG_ENDIAN
@@ -3139,7 +3163,7 @@
rtx reg = gen_reg_rtx (SImode);
emit_insn (gen_movsi (reg, operands[1]));
- operands[1] = gen_rtx (SUBREG, QImode, reg, 0);
+ operands[1] = gen_rtx_SUBREG (QImode, reg, 0);
}
if (GET_CODE (operands[0]) == MEM)
operands[1] = force_reg (QImode, operands[1]);
@@ -3227,8 +3251,8 @@
operands[2] = XEXP (operands[0], 0);
else if (code == POST_INC || code == PRE_DEC)
{
- operands[0] = gen_rtx (SUBREG, DImode, operands[0], 0);
- operands[1] = gen_rtx (SUBREG, DImode, operands[1], 0);
+ operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
+ operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
emit_insn (gen_movdi (operands[0], operands[1]));
DONE;
}
@@ -3244,8 +3268,8 @@
emit_insn (gen_addsi3 (operands[2], XEXP (XEXP (operands[0], 0), 0),
XEXP (XEXP (operands[0], 0), 1)));
- emit_insn (gen_rtx (SET, VOIDmode, gen_rtx (MEM, DFmode, operands[2]),
- operands[1]));
+ emit_insn (gen_rtx_SET (VOIDmode, gen_rtx_MEM (DFmode, operands[2]),
+ operands[1]));
if (code == POST_DEC)
emit_insn (gen_addsi3 (operands[2], operands[2], GEN_INT (-8)));
@@ -3262,10 +3286,9 @@
|| register_operand (operands[1], DFmode))"
"*
{
- rtx ops[3];
-
switch (which_alternative)
{
+ default:
case 0: return \"ldm%?ia\\t%m1, %M0\\t%@ double\";
case 1: return \"stm%?ia\\t%m0, %M1\\t%@ double\";
case 2: case 3: case 4: return output_move_double (operands);
@@ -3310,6 +3333,7 @@
"*
switch (which_alternative)
{
+ default:
case 0: return \"mvf%?e\\t%0, %1\";
case 1: return \"mnf%?e\\t%0, #%N1\";
case 2: return \"ldf%?e\\t%0, %1\";
@@ -3347,7 +3371,8 @@
= arm_gen_load_multiple (REGNO (operands[0]), INTVAL (operands[2]),
force_reg (SImode, XEXP (operands[1], 0)),
TRUE, FALSE, RTX_UNCHANGING_P(operands[1]),
- MEM_IN_STRUCT_P(operands[1]));
+ MEM_IN_STRUCT_P(operands[1]),
+ MEM_SCALAR_P (operands[1]));
")
;; Load multiple with write-back
@@ -3417,7 +3442,8 @@
= arm_gen_store_multiple (REGNO (operands[1]), INTVAL (operands[2]),
force_reg (SImode, XEXP (operands[0], 0)),
TRUE, FALSE, RTX_UNCHANGING_P (operands[0]),
- MEM_IN_STRUCT_P(operands[0]));
+ MEM_IN_STRUCT_P(operands[0]),
+ MEM_SCALAR_P (operands[0]));
")
;; Store multiple with write-back
@@ -3504,7 +3530,6 @@
{
arm_compare_op0 = operands[0];
arm_compare_op1 = operands[1];
- arm_compare_fp = 0;
DONE;
}
")
@@ -3517,7 +3542,6 @@
{
arm_compare_op0 = operands[0];
arm_compare_op1 = operands[1];
- arm_compare_fp = 1;
DONE;
}
")
@@ -3530,7 +3554,6 @@
{
arm_compare_op0 = operands[0];
arm_compare_op1 = operands[1];
- arm_compare_fp = 1;
DONE;
}
")
@@ -3543,7 +3566,6 @@
{
arm_compare_op0 = operands[0];
arm_compare_op1 = operands[1];
- arm_compare_fp = 1;
DONE;
}
")
@@ -3722,8 +3744,7 @@
""
"
{
- operands[1] = gen_compare_reg (EQ, arm_compare_op0, arm_compare_op1,
- arm_compare_fp);
+ operands[1] = gen_compare_reg (EQ, arm_compare_op0, arm_compare_op1);
}
")
@@ -3735,8 +3756,7 @@
""
"
{
- operands[1] = gen_compare_reg (NE, arm_compare_op0, arm_compare_op1,
- arm_compare_fp);
+ operands[1] = gen_compare_reg (NE, arm_compare_op0, arm_compare_op1);
}
")
@@ -3748,8 +3768,7 @@
""
"
{
- operands[1] = gen_compare_reg (GT, arm_compare_op0, arm_compare_op1,
- arm_compare_fp);
+ operands[1] = gen_compare_reg (GT, arm_compare_op0, arm_compare_op1);
}
")
@@ -3761,8 +3780,7 @@
""
"
{
- operands[1] = gen_compare_reg (LE, arm_compare_op0, arm_compare_op1,
- arm_compare_fp);
+ operands[1] = gen_compare_reg (LE, arm_compare_op0, arm_compare_op1);
}
")
@@ -3774,8 +3792,7 @@
""
"
{
- operands[1] = gen_compare_reg (GE, arm_compare_op0, arm_compare_op1,
- arm_compare_fp);
+ operands[1] = gen_compare_reg (GE, arm_compare_op0, arm_compare_op1);
}
")
@@ -3787,8 +3804,7 @@
""
"
{
- operands[1] = gen_compare_reg (LT, arm_compare_op0, arm_compare_op1,
- arm_compare_fp);
+ operands[1] = gen_compare_reg (LT, arm_compare_op0, arm_compare_op1);
}
")
@@ -3800,8 +3816,7 @@
""
"
{
- operands[1] = gen_compare_reg (GTU, arm_compare_op0, arm_compare_op1,
- arm_compare_fp);
+ operands[1] = gen_compare_reg (GTU, arm_compare_op0, arm_compare_op1);
}
")
@@ -3813,8 +3828,7 @@
""
"
{
- operands[1] = gen_compare_reg (LEU, arm_compare_op0, arm_compare_op1,
- arm_compare_fp);
+ operands[1] = gen_compare_reg (LEU, arm_compare_op0, arm_compare_op1);
}
")
@@ -3826,8 +3840,7 @@
""
"
{
- operands[1] = gen_compare_reg (GEU, arm_compare_op0, arm_compare_op1,
- arm_compare_fp);
+ operands[1] = gen_compare_reg (GEU, arm_compare_op0, arm_compare_op1);
}
")
@@ -3839,8 +3852,7 @@
""
"
{
- operands[1] = gen_compare_reg (LTU, arm_compare_op0, arm_compare_op1,
- arm_compare_fp);
+ operands[1] = gen_compare_reg (LTU, arm_compare_op0, arm_compare_op1);
}
")
@@ -3895,8 +3907,7 @@
""
"
{
- operands[1] = gen_compare_reg (EQ, arm_compare_op0, arm_compare_op1,
- arm_compare_fp);
+ operands[1] = gen_compare_reg (EQ, arm_compare_op0, arm_compare_op1);
}
")
@@ -3906,8 +3917,7 @@
""
"
{
- operands[1] = gen_compare_reg (NE, arm_compare_op0, arm_compare_op1,
- arm_compare_fp);
+ operands[1] = gen_compare_reg (NE, arm_compare_op0, arm_compare_op1);
}
")
@@ -3917,8 +3927,7 @@
""
"
{
- operands[1] = gen_compare_reg (GT, arm_compare_op0, arm_compare_op1,
- arm_compare_fp);
+ operands[1] = gen_compare_reg (GT, arm_compare_op0, arm_compare_op1);
}
")
@@ -3928,8 +3937,7 @@
""
"
{
- operands[1] = gen_compare_reg (LE, arm_compare_op0, arm_compare_op1,
- arm_compare_fp);
+ operands[1] = gen_compare_reg (LE, arm_compare_op0, arm_compare_op1);
}
")
@@ -3939,8 +3947,7 @@
""
"
{
- operands[1] = gen_compare_reg (GE, arm_compare_op0, arm_compare_op1,
- arm_compare_fp);
+ operands[1] = gen_compare_reg (GE, arm_compare_op0, arm_compare_op1);
}
")
@@ -3950,8 +3957,7 @@
""
"
{
- operands[1] = gen_compare_reg (LT, arm_compare_op0, arm_compare_op1,
- arm_compare_fp);
+ operands[1] = gen_compare_reg (LT, arm_compare_op0, arm_compare_op1);
}
")
@@ -3961,8 +3967,7 @@
""
"
{
- operands[1] = gen_compare_reg (GTU, arm_compare_op0, arm_compare_op1,
- arm_compare_fp);
+ operands[1] = gen_compare_reg (GTU, arm_compare_op0, arm_compare_op1);
}
")
@@ -3972,8 +3977,7 @@
""
"
{
- operands[1] = gen_compare_reg (LEU, arm_compare_op0, arm_compare_op1,
- arm_compare_fp);
+ operands[1] = gen_compare_reg (LEU, arm_compare_op0, arm_compare_op1);
}
")
@@ -3983,8 +3987,7 @@
""
"
{
- operands[1] = gen_compare_reg (GEU, arm_compare_op0, arm_compare_op1,
- arm_compare_fp);
+ operands[1] = gen_compare_reg (GEU, arm_compare_op0, arm_compare_op1);
}
")
@@ -3994,8 +3997,7 @@
""
"
{
- operands[1] = gen_compare_reg (LTU, arm_compare_op0, arm_compare_op1,
- arm_compare_fp);
+ operands[1] = gen_compare_reg (LTU, arm_compare_op0, arm_compare_op1);
}
")
@@ -4038,8 +4040,7 @@
"
{
enum rtx_code code = GET_CODE (operands[1]);
- rtx ccreg = gen_compare_reg (code, arm_compare_op0, arm_compare_op1,
- arm_compare_fp);
+ rtx ccreg = gen_compare_reg (code, arm_compare_op0, arm_compare_op1);
operands[1] = gen_rtx (code, VOIDmode, ccreg, const0_rtx);
}")
@@ -4061,8 +4062,7 @@
|| (! fpu_add_operand (operands[3], SFmode)))
operands[3] = force_reg (SFmode, operands[3]);
- ccreg = gen_compare_reg (code, arm_compare_op0, arm_compare_op1,
- arm_compare_fp);
+ ccreg = gen_compare_reg (code, arm_compare_op0, arm_compare_op1);
operands[1] = gen_rtx (code, VOIDmode, ccreg, const0_rtx);
}")
@@ -4076,8 +4076,7 @@
"
{
enum rtx_code code = GET_CODE (operands[1]);
- rtx ccreg = gen_compare_reg (code, arm_compare_op0, arm_compare_op1,
- arm_compare_fp);
+ rtx ccreg = gen_compare_reg (code, arm_compare_op0, arm_compare_op1);
operands[1] = gen_rtx (code, VOIDmode, ccreg, const0_rtx);
}")
@@ -4167,10 +4166,10 @@
extern int arm_ccfsm_state;
if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
- {
- arm_ccfsm_state += 2;
- return \"\";
- }
+ {
+ arm_ccfsm_state += 2;
+ return \"\";
+ }
return \"b%?\\t%l0\";
}")
@@ -4259,7 +4258,7 @@
;; Often the return insn will be the same as loading from memory, so set attr
(define_insn "return"
[(return)]
- "USE_RETURN_INSN"
+ "USE_RETURN_INSN(FALSE)"
"*
{
extern int arm_ccfsm_state;
@@ -4279,7 +4278,7 @@
[(match_operand 1 "cc_register" "") (const_int 0)])
(return)
(pc)))]
- "USE_RETURN_INSN"
+ "USE_RETURN_INSN(TRUE)"
"*
{
extern int arm_ccfsm_state;
@@ -4300,7 +4299,7 @@
[(match_operand 1 "cc_register" "") (const_int 0)])
(pc)
(return)))]
- "USE_RETURN_INSN"
+ "USE_RETURN_INSN(TRUE)"
"*
{
extern int arm_ccfsm_state;
@@ -4650,7 +4649,7 @@
(match_operator 1 "comparison_operator"
[(match_operand:SI 2 "s_register_operand" "r,r")
(match_operand:SI 3 "arm_add_operand" "rI,L")]))
- (clobber (reg 24))]
+ (clobber (reg:CC 24))]
""
"*
if (GET_CODE (operands[1]) == LT && operands[3] == const0_rtx)
@@ -4708,7 +4707,7 @@
[(match_operand:SI 2 "s_register_operand" "r,r")
(match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
(match_operand:SI 1 "s_register_operand" "0,?r")]))
- (clobber (reg 24))]
+ (clobber (reg:CC 24))]
""
"*
if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
@@ -4732,7 +4731,7 @@
(match_operator:SI 4 "comparison_operator"
[(match_operand:SI 2 "s_register_operand" "r,r")
(match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
- (clobber (reg 24))]
+ (clobber (reg:CC 24))]
""
"*
output_asm_insn (\"cmp\\t%2, %3\", operands);
@@ -4813,7 +4812,7 @@
(neg:SI (match_operator 3 "comparison_operator"
[(match_operand:SI 1 "s_register_operand" "r")
(match_operand:SI 2 "arm_rhs_operand" "rI")])))
- (clobber (reg 24))]
+ (clobber (reg:CC 24))]
""
"*
if (GET_CODE (operands[3]) == LT && operands[3] == const0_rtx)
@@ -4840,7 +4839,7 @@
(match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")])
(match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
(match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
- (clobber (reg 24))]
+ (clobber (reg:CC 24))]
""
"*
if (GET_CODE (operands[5]) == LT
@@ -4902,69 +4901,65 @@
(plus:SI
(match_operand:SI 2 "s_register_operand" "r,r")
(match_operand:SI 3 "arm_add_operand" "rIL,rIL"))
- (match_operand:SI 1 "arm_rhsm_operand" "0,?rIm")))
- (clobber (reg 24))]
+ (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
+ (clobber (reg:CC 24))]
""
"#"
[(set_attr "conds" "clob")
(set_attr "length" "8,12")])
(define_insn "*if_plus_move"
- [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r")
+ [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
(if_then_else:SI
(match_operator 4 "comparison_operator"
[(match_operand 5 "cc_register" "") (const_int 0)])
(plus:SI
- (match_operand:SI 2 "s_register_operand" "r,r,r,r,r,r")
- (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L,rI,L"))
- (match_operand:SI 1 "arm_rhsm_operand" "0,0,?rI,?rI,m,m")))]
+ (match_operand:SI 2 "s_register_operand" "r,r,r,r")
+ (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))
+ (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))]
""
"@
add%d4\\t%0, %2, %3
sub%d4\\t%0, %2, #%n3
add%d4\\t%0, %2, %3\;mov%D4\\t%0, %1
- sub%d4\\t%0, %2, #%n3\;mov%D4\\t%0, %1
- add%d4\\t%0, %2, %3\;ldr%D4\\t%0, %1
- sub%d4\\t%0, %2, #%n3\;ldr%D4\\t%0, %1"
+ sub%d4\\t%0, %2, #%n3\;mov%D4\\t%0, %1"
[(set_attr "conds" "use")
- (set_attr "length" "4,4,8,8,8,8")
- (set_attr "type" "*,*,*,*,load,load")])
+ (set_attr "length" "4,4,8,8")
+ (set_attr "type" "*,*,*,*")])
(define_insn "*ifcompare_move_plus"
[(set (match_operand:SI 0 "s_register_operand" "=r,r")
(if_then_else:SI (match_operator 6 "comparison_operator"
[(match_operand:SI 4 "s_register_operand" "r,r")
(match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
- (match_operand:SI 1 "arm_rhsm_operand" "0,?rIm")
+ (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
(plus:SI
(match_operand:SI 2 "s_register_operand" "r,r")
(match_operand:SI 3 "arm_add_operand" "rIL,rIL"))))
- (clobber (reg 24))]
+ (clobber (reg:CC 24))]
""
"#"
[(set_attr "conds" "clob")
(set_attr "length" "8,12")])
(define_insn "*if_move_plus"
- [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r")
+ [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
(if_then_else:SI
(match_operator 4 "comparison_operator"
[(match_operand 5 "cc_register" "") (const_int 0)])
- (match_operand:SI 1 "arm_rhsm_operand" "0,0,?rI,?rI,m,m")
+ (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")
(plus:SI
- (match_operand:SI 2 "s_register_operand" "r,r,r,r,r,r")
- (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L,rI,L"))))]
+ (match_operand:SI 2 "s_register_operand" "r,r,r,r")
+ (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))))]
""
"@
add%D4\\t%0, %2, %3
sub%D4\\t%0, %2, #%n3
add%D4\\t%0, %2, %3\;mov%d4\\t%0, %1
- sub%D4\\t%0, %2, #%n3\;mov%d4\\t%0, %1
- add%D4\\t%0, %2, %3\;ldr%d4\\t%0, %1
- sub%D4\\t%0, %2, #%n3\;ldr%d4\\t%0, %1"
+ sub%D4\\t%0, %2, #%n3\;mov%d4\\t%0, %1"
[(set_attr "conds" "use")
- (set_attr "length" "4,4,8,8,8,8")
- (set_attr "type" "*,*,*,*,load,load")])
+ (set_attr "length" "4,4,8,8")
+ (set_attr "type" "*,*,*,*")])
(define_insn "*ifcompare_arith_arith"
[(set (match_operand:SI 0 "s_register_operand" "=r")
@@ -4977,7 +4972,7 @@
(match_operator:SI 7 "shiftable_operator"
[(match_operand:SI 3 "s_register_operand" "r")
(match_operand:SI 4 "arm_rhs_operand" "rI")])))
- (clobber (reg 24))]
+ (clobber (reg:CC 24))]
""
"#"
[(set_attr "conds" "clob")
@@ -5006,8 +5001,8 @@
(match_operator:SI 7 "shiftable_operator"
[(match_operand:SI 4 "s_register_operand" "r,r")
(match_operand:SI 5 "arm_rhs_operand" "rI,rI")])
- (match_operand:SI 1 "arm_rhsm_operand" "0,?rIm")))
- (clobber (reg 24))]
+ (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
+ (clobber (reg:CC 24))]
""
"*
/* If we have an operation where (op x 0) is the identity operation and
@@ -5032,44 +5027,38 @@
output_asm_insn (\"cmp\\t%2, %3\", operands);
output_asm_insn (\"%I7%d6\\t%0, %4, %5\", operands);
if (which_alternative != 0)
- {
- if (GET_CODE (operands[1]) == MEM)
- return \"ldr%D6\\t%0, %1\";
- else
- return \"mov%D6\\t%0, %1\";
- }
+ return \"mov%D6\\t%0, %1\";
return \"\";
"
[(set_attr "conds" "clob")
(set_attr "length" "8,12")])
(define_insn "*if_arith_move"
- [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
+ [(set (match_operand:SI 0 "s_register_operand" "=r,r")
(if_then_else:SI (match_operator 4 "comparison_operator"
[(match_operand 6 "cc_register" "") (const_int 0)])
(match_operator:SI 5 "shiftable_operator"
- [(match_operand:SI 2 "s_register_operand" "r,r,r")
- (match_operand:SI 3 "arm_rhs_operand" "rI,rI,rI")])
- (match_operand:SI 1 "arm_rhsm_operand" "0,?rI,m")))]
+ [(match_operand:SI 2 "s_register_operand" "r,r")
+ (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
+ (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))]
""
"@
%I5%d4\\t%0, %2, %3
- %I5%d4\\t%0, %2, %3\;mov%D4\\t%0, %1
- %I5%d4\\t%0, %2, %3\;ldr%D4\\t%0, %1"
+ %I5%d4\\t%0, %2, %3\;mov%D4\\t%0, %1"
[(set_attr "conds" "use")
- (set_attr "length" "4,8,8")
- (set_attr "type" "*,*,load")])
+ (set_attr "length" "4,8")
+ (set_attr "type" "*,*")])
(define_insn "*ifcompare_move_arith"
[(set (match_operand:SI 0 "s_register_operand" "=r,r")
(if_then_else:SI (match_operator 6 "comparison_operator"
[(match_operand:SI 4 "s_register_operand" "r,r")
(match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
- (match_operand:SI 1 "arm_rhsm_operand" "0,?rIm")
+ (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
(match_operator:SI 7 "shiftable_operator"
[(match_operand:SI 2 "s_register_operand" "r,r")
(match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
- (clobber (reg 24))]
+ (clobber (reg:CC 24))]
""
"*
/* If we have an operation where (op x 0) is the identity operation and
@@ -5095,34 +5084,28 @@
output_asm_insn (\"cmp\\t%4, %5\", operands);
if (which_alternative != 0)
- {
- if (GET_CODE (operands[1]) == MEM)
- output_asm_insn (\"ldr%d6\\t%0, %1\", operands);
- else
- output_asm_insn (\"mov%d6\\t%0, %1\", operands);
- }
+ output_asm_insn (\"mov%d6\\t%0, %1\", operands);
return \"%I7%D6\\t%0, %2, %3\";
"
[(set_attr "conds" "clob")
(set_attr "length" "8,12")])
(define_insn "*if_move_arith"
- [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
+ [(set (match_operand:SI 0 "s_register_operand" "=r,r")
(if_then_else:SI
(match_operator 4 "comparison_operator"
[(match_operand 6 "cc_register" "") (const_int 0)])
- (match_operand:SI 1 "arm_rhsm_operand" "0,?rI,m")
+ (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
(match_operator:SI 5 "shiftable_operator"
- [(match_operand:SI 2 "s_register_operand" "r,r,r")
- (match_operand:SI 3 "arm_rhs_operand" "rI,rI,rI")])))]
+ [(match_operand:SI 2 "s_register_operand" "r,r")
+ (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))]
""
"@
%I5%D4\\t%0, %2, %3
- %I5%D4\\t%0, %2, %3\;mov%d4\\t%0, %1
- %I5%D4\\t%0, %2, %3\;ldr%d4\\t%0, %1"
+ %I5%D4\\t%0, %2, %3\;mov%d4\\t%0, %1"
[(set_attr "conds" "use")
- (set_attr "length" "4,8,8")
- (set_attr "type" "*,*,load")])
+ (set_attr "length" "4,8")
+ (set_attr "type" "*,*")])
(define_insn "*ifcompare_move_not"
[(set (match_operand:SI 0 "s_register_operand" "=r,r")
@@ -5133,7 +5116,7 @@
(match_operand:SI 1 "arm_not_operand" "0,?rIK")
(not:SI
(match_operand:SI 2 "s_register_operand" "r,r"))))
- (clobber (reg 24))]
+ (clobber (reg:CC 24))]
""
"#"
[(set_attr "conds" "clob")
@@ -5163,7 +5146,7 @@
(not:SI
(match_operand:SI 2 "s_register_operand" "r,r"))
(match_operand:SI 1 "arm_not_operand" "0,?rIK")))
- (clobber (reg 24))]
+ (clobber (reg:CC 24))]
""
"#"
[(set_attr "conds" "clob")
@@ -5194,7 +5177,7 @@
[(match_operand:SI 2 "s_register_operand" "r,r")
(match_operand:SI 3 "arm_rhs_operand" "rM,rM")])
(match_operand:SI 1 "arm_not_operand" "0,?rIK")))
- (clobber (reg 24))]
+ (clobber (reg:CC 24))]
""
"#"
[(set_attr "conds" "clob")
@@ -5227,7 +5210,7 @@
(match_operator:SI 7 "shift_operator"
[(match_operand:SI 2 "s_register_operand" "r,r")
(match_operand:SI 3 "arm_rhs_operand" "rM,rM")])))
- (clobber (reg 24))]
+ (clobber (reg:CC 24))]
""
"#"
[(set_attr "conds" "clob")
@@ -5262,7 +5245,7 @@
(match_operator:SI 9 "shift_operator"
[(match_operand:SI 3 "s_register_operand" "r")
(match_operand:SI 4 "arm_rhs_operand" "rM")])))
- (clobber (reg 24))]
+ (clobber (reg:CC 24))]
""
"#"
[(set_attr "conds" "clob")
@@ -5294,7 +5277,7 @@
(match_operator:SI 7 "shiftable_operator"
[(match_operand:SI 2 "s_register_operand" "r")
(match_operand:SI 3 "arm_rhs_operand" "rI")])))
- (clobber (reg 24))]
+ (clobber (reg:CC 24))]
""
"#"
[(set_attr "conds" "clob")
@@ -5324,7 +5307,7 @@
[(match_operand:SI 2 "s_register_operand" "r")
(match_operand:SI 3 "arm_rhs_operand" "rI")])
(not:SI (match_operand:SI 1 "s_register_operand" "r"))))
- (clobber (reg 24))]
+ (clobber (reg:CC 24))]
""
"#"
[(set_attr "conds" "clob")
@@ -5888,7 +5871,8 @@
"sub%?s\\t%0, %1, #0"
[(set_attr "conds" "set")])
-; Peepholes to spot possible load- and store-multiples.
+; Peepholes to spot possible load- and store-multiples, if the ordering is
+; reversed, check that the memory references aren't volatile.
(define_peephole
[(set (match_operand:SI 0 "s_register_operand" "=r")
@@ -5981,7 +5965,7 @@
(match_operand:SI 1 "general_operand" "g"))
(clobber (reg:SI 14))])
(return)]
- "(GET_CODE (operands[0]) == SYMBOL_REF && USE_RETURN_INSN
+ "(GET_CODE (operands[0]) == SYMBOL_REF && USE_RETURN_INSN(FALSE)
&& !get_frame_size () && !current_function_calls_alloca
&& !frame_pointer_needed && !current_function_args_size)"
"*
@@ -6009,7 +5993,7 @@
(match_operand:SI 2 "general_operand" "g")))
(clobber (reg:SI 14))])
(return)]
- "(GET_CODE (operands[1]) == SYMBOL_REF && USE_RETURN_INSN
+ "(GET_CODE (operands[1]) == SYMBOL_REF && USE_RETURN_INSN(FALSE)
&& !get_frame_size () && !current_function_calls_alloca
&& !frame_pointer_needed && !current_function_args_size)"
"*
@@ -6041,7 +6025,7 @@
(clobber (reg:SI 14))])
(use (match_dup 0))
(return)]
- "(GET_CODE (operands[1]) == SYMBOL_REF && USE_RETURN_INSN
+ "(GET_CODE (operands[1]) == SYMBOL_REF && USE_RETURN_INSN(FALSE)
&& !get_frame_size () && !current_function_calls_alloca
&& !frame_pointer_needed && !current_function_args_size)"
"*
@@ -6117,7 +6101,7 @@
[(match_operand 2 "" "") (match_operand 3 "" "")])
(match_operand 4 "" "")
(match_operand 5 "" "")))
- (clobber (reg 24))]
+ (clobber (reg:CC 24))]
"reload_completed"
[(set (match_dup 6) (match_dup 7))
(set (match_dup 0)
@@ -6129,12 +6113,11 @@
enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]), operands[2],
operands[3]);
- operands[6] = gen_rtx (REG, mode, 24);
- operands[7] = gen_rtx (COMPARE, mode, operands[2], operands[3]);
+ operands[6] = gen_rtx_REG (mode, 24);
+ operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
}
")
-
;; The next two patterns occur when an AND operation is followed by a
;; scc insn sequence
@@ -6210,7 +6193,6 @@
"*
{
char pattern[100];
- int i;
sprintf (pattern, \"sfmfd\\t%%1, %d, [%%m0]!\", XVECLEN (operands[2], 0));
output_asm_insn (pattern, operands);
diff --git a/gcc/config/arm/coff.h b/gcc/config/arm/coff.h
index 4e568cb7941..221c7e00409 100644
--- a/gcc/config/arm/coff.h
+++ b/gcc/config/arm/coff.h
@@ -1,6 +1,6 @@
/* Definitions of target machine for GNU compiler,
for ARM with COFF obj format.
- Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
+ Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
Contributed by Doug Evans (dje@cygnus.com).
This file is part of GNU CC.
@@ -21,34 +21,35 @@ the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include "arm/semi.h"
+#include "arm/aout.h"
+
+#undef USER_LABEL_PREFIX
+#define USER_LABEL_PREFIX "_"
+
/* Run-time Target Specification. */
-#undef TARGET_VERSION
+#undef TARGET_VERSION
#define TARGET_VERSION fputs (" (ARM/coff)", stderr)
-/* ??? Maybe use --with{enable?}-fpu or some such to make hardware floating
- point the default. NOT --nfp! --with{enable?} is supposed to replace it
- (right?), so let's stop using it. */
-#undef TARGET_DEFAULT
+#undef TARGET_DEFAULT
#define TARGET_DEFAULT (ARM_FLAG_SOFT_FLOAT | ARM_FLAG_APCS_32)
-/* ??? Is a big-endian default intended to be supported? */
-#if 0 /*TARGET_CPU_DEFAULT & ARM_FLAG_BIG_END*/
-#define MULTILIB_DEFAULTS { "mbig-endian" }
-#else
-#define MULTILIB_DEFAULTS { "mlittle-endian" }
-#endif
+#define MULTILIB_DEFAULTS { "mlittle-endian", "msoft-float", "mapcs-32" }
-/* ??? Does arm.h really need to set this to 32? */
-#undef STRUCTURE_SIZE_BOUNDARY
-#define STRUCTURE_SIZE_BOUNDARY 8
+/* Setting this to 32 produces more efficient code, but the value set in previous
+ versions of this toolchain was 8, which produces more compact structures. The
+ command line option -mstructure_size_boundary=<n> can be used to change this
+ value. */
+#undef STRUCTURE_SIZE_BOUNDARY
+#define STRUCTURE_SIZE_BOUNDARY arm_structure_size_boundary
+
+extern int arm_structure_size_boundary;
/* A C expression whose value is nonzero if IDENTIFIER with arguments ARGS
is a valid machine specific attribute for DECL.
The attributes in ATTRIBUTES have previously been assigned to DECL. */
-extern int arm_valid_machine_decl_attribute ();
#define VALID_MACHINE_DECL_ATTRIBUTE(DECL, ATTRIBUTES, IDENTIFIER, ARGS) \
-arm_valid_machine_decl_attribute (DECL, ATTRIBUTES, IDENTIFIER, ARGS)
+arm_valid_machine_decl_attribute (DECL, IDENTIFIER, ARGS)
/* This is COFF, but prefer stabs. */
#define SDB_DEBUGGING_INFO
@@ -57,12 +58,6 @@ arm_valid_machine_decl_attribute (DECL, ATTRIBUTES, IDENTIFIER, ARGS)
#include "dbxcoff.h"
-#undef LOCAL_LABEL_PREFIX
-#define LOCAL_LABEL_PREFIX "."
-
-#undef USER_LABEL_PREFIX
-#define USER_LABEL_PREFIX ""
-
/* A C statement to output assembler commands which will identify the
object file as having been compiled with GNU CC (or another GNU
compiler). */
@@ -71,7 +66,8 @@ arm_valid_machine_decl_attribute (DECL, ATTRIBUTES, IDENTIFIER, ARGS)
Also, when using stabs, gcc2_compiled must be a stabs entry, not an
ordinary symbol, or gdb won't see it. The stabs entry must be
before the N_SO in order for gdb to find it. */
-#define ASM_IDENTIFY_GCC(STREAM)
+#define ASM_IDENTIFY_GCC(STREAM) \
+ fprintf (STREAM, "%sgcc2_compiled.:\n", LOCAL_LABEL_PREFIX )
/* This outputs a lot of .req's to define alias for various registers.
Let's try to avoid this. */
@@ -106,14 +102,13 @@ do { \
Otherwise, the readonly data section is used. */
#define JUMP_TABLES_IN_TEXT_SECTION 1
-#undef READONLY_DATA_SECTION
+#undef READONLY_DATA_SECTION
#define READONLY_DATA_SECTION rdata_section
-#undef RDATA_SECTION_ASM_OP
+#undef RDATA_SECTION_ASM_OP
#define RDATA_SECTION_ASM_OP "\t.section .rdata"
-
-#undef CTORS_SECTION_ASM_OP
+#undef CTORS_SECTION_ASM_OP
#define CTORS_SECTION_ASM_OP "\t.section .ctors,\"x\""
-#undef DTORS_SECTION_ASM_OP
+#undef DTORS_SECTION_ASM_OP
#define DTORS_SECTION_ASM_OP "\t.section .dtors,\"x\""
/* A list of other sections which the compiler might be "in" at any
@@ -200,8 +195,12 @@ do { \
#undef DO_GLOBAL_CTORS_BODY
#undef DO_GLOBAL_DTORS_BODY
-/* The ARM development system has atexit and doesn't have _exit,
- so define this for now. */
+/* If you don't define HAVE_ATEXIT, and the object file format/OS/whatever
+ does not support constructors/destructors, then gcc implements destructors
+ by defining its own exit function, which calls the destructors. This gcc
+ exit function overrides the C library's exit function, and this can cause
+ all kinds of havoc if the C library has a non-trivial exit function. You
+ really don't want to use the exit function in libgcc2.c. */
#define HAVE_ATEXIT
/* The ARM development system defines __main. */
diff --git a/gcc/config/arm/lib1funcs.asm b/gcc/config/arm/lib1funcs.asm
index aac0ce1977f..ded20ffe7dd 100644
--- a/gcc/config/arm/lib1funcs.asm
+++ b/gcc/config/arm/lib1funcs.asm
@@ -1,7 +1,7 @@
@ libgcc1 routines for ARM cpu.
@ Division routines, written by Richard Earnshaw, (rearnsha@armltd.co.uk)
-/* Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+/* Copyright (C) 1995, 1996, 1998 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
@@ -44,7 +44,7 @@ Boston, MA 02111-1307, USA. */
#endif
#ifndef __USER_LABEL_PREFIX__
-#define __USER_LABEL_PREFIX__ _
+#error __USER_LABEL_PREFIX__ not defined
#endif
/* ANSI concatenation macros. */
@@ -56,6 +56,16 @@ Boston, MA 02111-1307, USA. */
#define SYM(x) CONCAT1 (__USER_LABEL_PREFIX__, x)
+#ifdef __elf__
+#define __PLT__ (PLT)
+#define TYPE(x) .type SYM(x),function
+#define SIZE(x) .size SYM(x), . - SYM(x)
+#else
+#define __PLT__
+#define TYPE(x)
+#define SIZE(x)
+#endif
+
#ifdef L_udivsi3
dividend .req r0
@@ -66,9 +76,11 @@ ip .req r12
sp .req r13
lr .req r14
pc .req r15
+
.text
- .globl SYM (__udivsi3)
- .align 0
+ .globl SYM (__udivsi3)
+ TYPE (__udivsi3)
+ .align 0
SYM (__udivsi3):
cmp divisor, #0
@@ -124,10 +136,12 @@ Lgot_result:
Ldiv0:
str lr, [sp, #-4]!
- bl SYM (__div0)
+ bl SYM (__div0) __PLT__
mov r0, #0 @ about as wrong as it could be
ldmia sp!, {pc}RETCOND
+ SIZE (__udivsi3)
+
#endif /* L_udivsi3 */
#ifdef L_umodsi3
@@ -140,8 +154,10 @@ ip .req r12
sp .req r13
lr .req r14
pc .req r15
+
.text
- .globl SYM (__umodsi3)
+ .globl SYM (__umodsi3)
+ TYPE (__umodsi3)
.align 0
SYM (__umodsi3):
@@ -210,10 +226,12 @@ Loop3:
Ldiv0:
str lr, [sp, #-4]!
- bl SYM (__div0)
+ bl SYM (__div0) __PLT__
mov r0, #0 @ about as wrong as it could be
ldmia sp!, {pc}RETCOND
+ SIZE (__umodsi3)
+
#endif /* L_umodsi3 */
#ifdef L_divsi3
@@ -226,8 +244,10 @@ ip .req r12
sp .req r13
lr .req r14
pc .req r15
+
.text
- .globl SYM (__divsi3)
+ .globl SYM (__divsi3)
+ TYPE (__divsi3)
.align 0
SYM (__divsi3):
@@ -291,10 +311,12 @@ Lgot_result:
Ldiv0:
str lr, [sp, #-4]!
- bl SYM (__div0)
+ bl SYM (__div0) __PLT__
mov r0, #0 @ about as wrong as it could be
ldmia sp!, {pc}RETCOND
+ SIZE (__divsi3)
+
#endif /* L_divsi3 */
#ifdef L_modsi3
@@ -307,8 +329,10 @@ ip .req r12
sp .req r13
lr .req r14
pc .req r15
+
.text
- .globl SYM (__modsi3)
+ .globl SYM (__modsi3)
+ TYPE (__modsi3)
.align 0
SYM (__modsi3):
@@ -388,38 +412,47 @@ Lgot_result:
Ldiv0:
str lr, [sp, #-4]!
- bl SYM (__div0)
+ bl SYM (__div0) __PLT__
mov r0, #0 @ about as wrong as it could be
ldmia sp!, {pc}RETCOND
+ SIZE (__modsi3)
+
#endif /* L_modsi3 */
#ifdef L_dvmd_tls
- .globl SYM (__div0)
+ .globl SYM (__div0)
+ TYPE (__div0)
.align 0
SYM (__div0):
RET pc, lr
+ SIZE (__div0)
+
#endif /* L_divmodsi_tools */
#ifdef L_dvmd_lnx
@ GNU/Linux division-by zero handler. Used in place of L_dvmd_tls
#include <asm/unistd.h>
+
#define SIGFPE 8 @ cant use <asm/signal.h> as it
@ contains too much C rubbish
- .globl SYM (__div0)
+ .globl SYM (__div0)
+ TYPE (__div0)
.align 0
SYM (__div0):
stmfd sp!, {r1, lr}
swi __NR_getpid
cmn r0, #1000
- ldmgefd sp!, {r1, pc}RETCOND @ not much we can do
+ ldmhsfd sp!, {r1, pc}RETCOND @ not much we can do
mov r1, #SIGFPE
swi __NR_kill
ldmfd sp!, {r1, pc}RETCOND
+ SIZE (__div0)
+
#endif /* L_dvmd_lnx */
/* These next two sections are here despite the fact that they contain Thumb
@@ -439,10 +472,13 @@ SYM (__div0):
.code 16
.macro call_via register
.globl SYM (_call_via_\register)
+ TYPE (_call_via_\register)
.thumb_func
SYM (_call_via_\register):
bx \register
nop
+
+ SIZE (_call_via_\register)
.endm
call_via r0
@@ -480,6 +516,7 @@ SYM (_call_via_\register):
.align 0
.code 32
+ .globl _arm_return
_arm_return:
ldmia r13!, {r12}
bx r12
@@ -488,6 +525,7 @@ _arm_return:
.macro interwork register
.code 16
.globl SYM (_interwork_call_via_\register)
+ TYPE (_interwork_call_via_\register)
.thumb_func
SYM (_interwork_call_via_\register):
bx pc
@@ -500,6 +538,8 @@ SYM (_interwork_call_via_\register):
stmeqdb r13!, {lr}
adreq lr, _arm_return
bx \register
+
+ SIZE (_interwork_call_via_\register)
.endm
interwork r0
@@ -516,6 +556,25 @@ SYM (_interwork_call_via_\register):
interwork fp
interwork ip
interwork sp
- interwork lr
-
+
+ /* The lr case has to be handled a little differently...*/
+ .code 16
+ .globl SYM (_interwork_call_via_lr)
+ TYPE (_interwork_call_via_lr)
+ .thumb_func
+SYM (_interwork_call_via_lr):
+ bx pc
+ nop
+
+ .code 32
+ .globl .Lchange_lr
+.Lchange_lr:
+ tst lr, #1
+ stmeqdb r13!, {lr}
+ mov ip, lr
+ adreq lr, _arm_return
+ bx ip
+
+ SIZE (_interwork_call_via_lr)
+
#endif /* L_interwork_call_via_rX */
diff --git a/gcc/config/arm/lib1thumb.asm b/gcc/config/arm/lib1thumb.asm
index d50d35d15f1..daf8361097b 100644
--- a/gcc/config/arm/lib1thumb.asm
+++ b/gcc/config/arm/lib1thumb.asm
@@ -1,7 +1,7 @@
@ libgcc1 routines for ARM cpu.
@ Division routines, written by Richard Earnshaw, (rearnsha@armltd.co.uk)
-/* Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+/* Copyright (C) 1995, 1996, 1998 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
@@ -36,7 +36,17 @@ Boston, MA 02111-1307, USA. */
.code 16
#ifndef __USER_LABEL_PREFIX__
-#error USER_LABEL_PREFIX not defined
+#error __USER_LABEL_PREFIX__ not defined
+#endif
+
+#ifdef __elf__
+#define __PLT__ (PLT)
+#define TYPE(x) .type SYM(x),function
+#define SIZE(x) .size SYM(x), . - SYM(x)
+#else
+#define __PLT__
+#define TYPE(x)
+#define SIZE(x)
#endif
#define RET mov pc, lr
@@ -64,8 +74,9 @@ lr .req r14
pc .req r15
.text
- .globl SYM (__udivsi3)
- .align 0
+ .globl SYM (__udivsi3)
+ TYPE (__udivsi3)
+ .align 0
.thumb_func
SYM (__udivsi3):
cmp divisor, #0
@@ -151,10 +162,12 @@ Lgot_result:
Ldiv0:
push { lr }
- bl SYM (__div0)
+ bl SYM (__div0) __PLT__
mov r0, #0 @ about as wrong as it could be
pop { pc }
+ SIZE (__udivsi3)
+
#endif /* L_udivsi3 */
#ifdef L_umodsi3
@@ -167,9 +180,11 @@ ip .req r12
sp .req r13
lr .req r14
pc .req r15
+
.text
- .globl SYM (__umodsi3)
- .align 0
+ .globl SYM (__umodsi3)
+ TYPE (__umodsi3)
+ .align 0
.thumb_func
SYM (__umodsi3):
cmp divisor, #0
@@ -302,10 +317,12 @@ Over10:
Ldiv0:
push { lr }
- bl SYM (__div0)
+ bl SYM (__div0) __PLT__
mov r0, #0 @ about as wrong as it could be
pop { pc }
+ SIZE (__umodsi3)
+
#endif /* L_umodsi3 */
#ifdef L_divsi3
@@ -318,9 +335,11 @@ ip .req r12
sp .req r13
lr .req r14
pc .req r15
+
.text
- .globl SYM (__divsi3)
- .align 0
+ .globl SYM (__divsi3)
+ TYPE (__divsi3)
+ .align 0
.thumb_func
SYM (__divsi3):
cmp divisor, #0
@@ -421,10 +440,12 @@ Over7:
Ldiv0:
push { lr }
- bl SYM (__div0)
+ bl SYM (__div0) __PLT__
mov r0, #0 @ about as wrong as it could be
pop { pc }
+ SIZE (__divsi3)
+
#endif /* L_divsi3 */
#ifdef L_modsi3
@@ -437,9 +458,11 @@ ip .req r12
sp .req r13
lr .req r14
pc .req r15
+
.text
- .globl SYM (__modsi3)
- .align 0
+ .globl SYM (__modsi3)
+ TYPE (__modsi3)
+ .align 0
.thumb_func
SYM (__modsi3):
mov curbit, #1
@@ -581,20 +604,25 @@ Over10:
Ldiv0:
push { lr }
- bl SYM (__div0)
+ bl SYM (__div0) __PLT__
mov r0, #0 @ about as wrong as it could be
pop { pc }
+ SIZE (__modsi3)
+
#endif /* L_modsi3 */
#ifdef L_dvmd_tls
- .globl SYM (__div0)
- .align 0
+ .globl SYM (__div0)
+ TYPE (__div0)
+ .align 0
.thumb_func
SYM (__div0):
RET
+ SIZE (__div0)
+
#endif /* L_divmodsi_tools */
@@ -611,10 +639,13 @@ SYM (__div0):
.macro call_via register
.globl SYM (_call_via_\register)
+ TYPE (_call_via_\register)
.thumb_func
SYM (_call_via_\register):
bx \register
nop
+
+ SIZE (_call_via_\register)
.endm
call_via r0
@@ -652,13 +683,16 @@ SYM (_call_via_\register):
.align 0
.code 32
+ .globl _arm_return
_arm_return:
ldmia r13!, {r12}
bx r12
- .code 16
-
+
.macro interwork register
+ .code 16
+
.globl SYM (_interwork_call_via_\register)
+ TYPE (_interwork_call_via_\register)
.thumb_func
SYM (_interwork_call_via_\register):
bx pc
@@ -671,7 +705,8 @@ SYM (_interwork_call_via_\register):
stmeqdb r13!, {lr}
adreq lr, _arm_return
bx \register
- .code 16
+
+ SIZE (_interwork_call_via_\register)
.endm
interwork r0
@@ -688,8 +723,27 @@ SYM (_interwork_call_via_\register):
interwork fp
interwork ip
interwork sp
- interwork lr
-
+
+ /* The lr case has to be handled a little differently...*/
+ .code 16
+ .globl SYM (_interwork_call_via_lr)
+ TYPE (_interwork_call_via_lr)
+ .thumb_func
+SYM (_interwork_call_via_lr):
+ bx pc
+ nop
+
+ .code 32
+ .globl .Lchange_lr
+.Lchange_lr:
+ tst lr, #1
+ stmeqdb r13!, {lr}
+ mov ip, lr
+ adreq lr, _arm_return
+ bx ip
+
+ SIZE (_interwork_call_via_lr)
+
#endif /* L_interwork_call_via_rX */
diff --git a/gcc/config/arm/linux-gas.h b/gcc/config/arm/linux-gas.h
index ea8b4f0a37e..f2b5d42e1e2 100644
--- a/gcc/config/arm/linux-gas.h
+++ b/gcc/config/arm/linux-gas.h
@@ -1,6 +1,6 @@
-/* Definitions of target machine for GNU compiler. ARM Linux-based GNU
- systems version.
- Copyright (C) 1997 Free Software Foundation, Inc.
+/* Definitions of target machine for GNU compiler.
+ ARM Linux-based GNU systems version.
+ Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc.
Contributed by Russell King <rmk92@ecs.soton.ac.uk>.
This file is part of GNU CC.
@@ -20,11 +20,6 @@ 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. */
-/* Limit the length of a stabs entry (for the broken Acorn assembler) */
-#define DBX_CONTIN_LENGTH 80
-
-#include "arm/linux.h"
-
/*
* We are using GAS, so stabs should work.
*/
@@ -32,3 +27,57 @@ Boston, MA 02111-1307, USA. */
#ifndef DBX_DEBUGGING_INFO
#define DBX_DEBUGGING_INFO 1
#endif
+
+/*
+ * This is how we tell the assembler that a symbol is weak. GAS always
+ * supports weak symbols.
+ */
+
+#define ASM_WEAKEN_LABEL(FILE,NAME) \
+ do { fputs ("\t.weak\t", FILE); assemble_name (FILE, NAME); \
+ fputc ('\n', FILE); } while (0)
+
+/* This is used in ASM_FILE_START */
+#undef ARM_OS_NAME
+#define ARM_OS_NAME "Linux"
+
+/* Unsigned chars produces much better code than signed. */
+#define DEFAULT_SIGNED_CHAR 0
+
+#undef SUBTARGET_CPP_SPEC
+#define SUBTARGET_CPP_SPEC "%{posix:-D_POSIX_SOURCE} %{fPIC:-D__PIC__ -D__pic__} %{fpic:-D__PIC__ -D__pic__}"
+
+#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
+
+/* Emit code to set up a trampoline and synchronise the caches. */
+#undef INITIALIZE_TRAMPOLINE
+#define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \
+{ \
+ emit_move_insn (gen_rtx (MEM, SImode, plus_constant ((TRAMP), 8)), \
+ (CXT)); \
+ emit_move_insn (gen_rtx (MEM, SImode, plus_constant ((TRAMP), 12)), \
+ (FNADDR)); \
+ emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__clear_cache"), \
+ 0, VOIDmode, 2, TRAMP, Pmode, \
+ plus_constant (TRAMP, TRAMPOLINE_SIZE), Pmode); \
+}
+
+/* Clear the instruction cache from `beg' to `end'. This makes an
+ inline system call to SYS_cacheflush. */
+#define CLEAR_INSN_CACHE(BEG, END) \
+{ \
+ register unsigned long _beg __asm ("a1") = (unsigned long) (BEG); \
+ register unsigned long _end __asm ("a2") = (unsigned long) (END); \
+ register unsigned long _flg __asm ("a3") = 0; \
+ __asm __volatile ("swi 0x9f0002"); \
+}
diff --git a/gcc/config/arm/linux.h b/gcc/config/arm/linux.h
deleted file mode 100644
index fa8fef10e72..00000000000
--- a/gcc/config/arm/linux.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/* Definitions for ARM running Linux-based GNU systems.
- Copyright (C) 1993, 1994, 1997 Free Software Foundation, Inc.
- Contributed by Russell King <rmk92@ecs.soton.ac.uk>.
-
-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 this program; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
-
-#include <linux-aout.h>
-
-/* these are different... */
-#undef STARTFILE_SPEC
-#define STARTFILE_SPEC \
-"%{pg:gcrt0.o%s} %{!pg:%{p:gcrt0.o%s} %{!p:crt0.o%s}} %{static:-static}"
-
-#undef ASM_APP_ON
-#undef ASM_APP_OFF
-#undef COMMENT_BEGIN
-
-/* We default to ARM3. */
-#define SUBTARGET_CPU_DEFAULT TARGET_CPU_arm3
-
-#undef CPP_PREDEFINES
-#define CPP_PREDEFINES \
-"-Dunix -Darm -Dlinux -Asystem(unix) -Asystem(posix) -Acpu(arm) -Amachine(arm)"
-
-#undef LIB_SPEC
-#define LIB_SPEC \
- "%{mieee-fp:-lieee} %{p:-lgmon} %{pg:-lgmon} %{!ggdb:-lc} %{ggdb:-lg}"
-
-#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
-
-#define HANDLE_SYSV_PRAGMA
-
-/* Run-time Target Specification. */
-#define TARGET_VERSION fputs (" (ARM GNU/Linux with a.out)", stderr);
-
-/* This is used in ASM_FILE_START */
-#define ARM_OS_NAME "Linux"
-
-/* Unsigned chars produces much better code than signed. */
-#define DEFAULT_SIGNED_CHAR 0
-
-/* Maths operation domain error number, EDOM */
-#define TARGET_EDOM 33
-#include "arm/aout.h"
-
-#undef SUBTARGET_CPP_SPEC
-#define SUBTARGET_CPP_SPEC "%{posix:-D_POSIX_SOURCE}"
diff --git a/gcc/config/arm/netbsd.h b/gcc/config/arm/netbsd.h
index 374d5bf65ab..7b03d4a90ff 100644
--- a/gcc/config/arm/netbsd.h
+++ b/gcc/config/arm/netbsd.h
@@ -16,7 +16,8 @@ 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
/* Run-time Target Specification. */
#define TARGET_VERSION fputs (" (ARM/NetBSD)", stderr);
@@ -116,6 +117,15 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#undef TYPE_OPERAND_FMT
#define TYPE_OPERAND_FMT "%%%s"
+/* NetBSD uses the old PCC style aggregate returning conventions. */
+#undef DEFAULT_PCC_STRUCT_RETURN
+#define DEFAULT_PCC_STRUCT_RETURN 1
+
+/* Although not normally relevant (since by default, all aggregates
+ are returned in memory) compiling some parts of libc requires
+ non-APCS style struct returns. */
+#undef RETURN_IN_MEMORY
+
/* VERY BIG NOTE : Change of structure alignment for RiscBSD.
There are consequences you should be aware of...
diff --git a/gcc/config/arm/riscix.h b/gcc/config/arm/riscix.h
index 5ccb2131e6e..07bdb0f7081 100644
--- a/gcc/config/arm/riscix.h
+++ b/gcc/config/arm/riscix.h
@@ -79,8 +79,10 @@ Boston, MA 02111-1307, USA. */
/* None of these is actually used in cc1. If we don't define them in target
switches cc1 complains about them. For the sake of argument lets allocate
bit 31 of target flags for such options. */
-#define SUBTARGET_SWITCHES \
-{"bsd", 0x80000000}, {"xopen", 0x80000000}, {"no-symrename", 0x80000000},
+#define SUBTARGET_SWITCHES \
+{"bsd", 0x80000000, ""}, \
+{"xopen", 0x80000000, ""}, \
+{"no-symrename", 0x80000000, ""},
/* Run-time Target Specification. */
@@ -120,6 +122,11 @@ Boston, MA 02111-1307, USA. */
/* Override the normal default CPU */
#define SUBTARGET_CPU_DEFAULT TARGET_CPU_arm2
+/* r10 is reserved by RISCiX */
+#define SUBTARGET_CONDITIONAL_REGISTER_USAGE \
+ fixed_regs[10] = 1; \
+ call_used_regs[10] = 1;
+
#include "arm/aout.h"
/* The RISCiX assembler does not understand .set */
diff --git a/gcc/config/arm/riscix1-1.h b/gcc/config/arm/riscix1-1.h
index 3718635430d..e896a1eb033 100644
--- a/gcc/config/arm/riscix1-1.h
+++ b/gcc/config/arm/riscix1-1.h
@@ -39,7 +39,7 @@ Boston, MA 02111-1307, USA. */
but everything still compiles. */
/* None of these is actually used in cc1, so they modify bit 31 */
#define SUBTARGET_SWITCHES \
-{"bsd", 0x80000000},
+{"bsd", 0x80000000, ""},
/* Run-time Target Specification. */
@@ -80,6 +80,12 @@ Boston, MA 02111-1307, USA. */
/* Override the normal default CPU */
#define SUBTARGET_CPU_DEFAULT TARGET_CPU_arm2
+/* r10 is reserved by RISCiX */
+#define SUBTARGET_CONDITIONAL_REGISTER_USAGE \
+ fixed_regs[10] = 1; \
+ call_used_regs[10] = 1;
+
+
#include "arm/aout.h"
#undef CPP_SPEC
diff --git a/gcc/config/arm/t-linux b/gcc/config/arm/t-linux
index f45e3147e98..9b7c3e38f4e 100644
--- a/gcc/config/arm/t-linux
+++ b/gcc/config/arm/t-linux
@@ -1,6 +1,7 @@
# Just for these, we omit the frame pointer since it makes such a big
# difference. It is then pointless adding debugging.
-LIBGCC2_CFLAGS=-O2 -fomit-frame-pointer $(LIBGCC2_INCLUDES) $(GCC_CFLAGS) -g0
+TARGET_LIBGCC2_CFLAGS = -fomit-frame-pointer -fPIC
+LIBGCC2_DEBUG_CFLAGS = -g0
# Don't build enquire
ENQUIRE=
@@ -12,8 +13,10 @@ LIBGCC1 = libgcc1-asm.a
LIB1ASMSRC = arm/lib1funcs.asm
LIB1ASMFUNCS = _udivsi3 _divsi3 _umodsi3 _modsi3 _dvmd_lnx
-MULTILIB_OPTIONS = mapcs-32
-MULTILIB_DIRNAMES = apcs-32
+# If you want to build both APCS variants as multilib options this is how
+# to do it.
+#MULTILIB_OPTIONS = mapcs-32/apcs-26
+#MULTILIB_DIRNAMES = apcs-32 apcs-26
LIBGCC = stmp-multilib
INSTALL_LIBGCC = install-multilib
diff --git a/gcc/config/arm/t-netbsd b/gcc/config/arm/t-netbsd
index cc2f6583679..6a61e9c40fa 100644
--- a/gcc/config/arm/t-netbsd
+++ b/gcc/config/arm/t-netbsd
@@ -1,7 +1,7 @@
# Just for these, we omit the frame pointer since it makes such a big
# difference. It is then pointless adding debugging.
-LIBGCC2_CFLAGS=-O2 -fomit-frame-pointer $(LIBGCC2_INCLUDES) $(GCC_CFLAGS) -g0
-# -Dinhibit_libc
+TARGET_LIBGCC2_CFLAGS = -fomit-frame-pointer
+LIBGCC2_DEBUG_CFLAGS = -g0
# Don't build enquire
ENQUIRE=
diff --git a/gcc/config/arm/t-riscix b/gcc/config/arm/t-riscix
index e5a2213b83c..9e59d8eb807 100644
--- a/gcc/config/arm/t-riscix
+++ b/gcc/config/arm/t-riscix
@@ -1,3 +1,4 @@
# Just for these, we omit the frame pointer since it makes such a big
# difference. It is then pointless adding debugging.
-LIBGCC2_CFLAGS=-O2 -fomit-frame-pointer $(LIBGCC2_INCLUDES) $(GCC_CFLAGS) -g0
+TARGET_LIBGCC2_CFLAGS = -fomit-frame-pointer
+LIBGCC2_DEBUG_CFLAGS = -g0
diff --git a/gcc/config/arm/t-semi b/gcc/config/arm/t-semi
index 61c1c37c529..ade87003cab 100644
--- a/gcc/config/arm/t-semi
+++ b/gcc/config/arm/t-semi
@@ -1,6 +1,7 @@
# Just for these, we omit the frame pointer since it makes such a big
# difference. It is then pointless adding debugging.
-LIBGCC2_CFLAGS=-O2 -fomit-frame-pointer $(LIBGCC2_INCLUDES) $(GCC_CFLAGS) -g0
+TARGET_LIBGCC2_CFLAGS = -fomit-frame-pointer
+LIBGCC2_DEBUG_CFLAGS = -g0
# Don't build enquire
ENQUIRE=
diff --git a/gcc/config/arm/t-semiaof b/gcc/config/arm/t-semiaof
index 101754375ea..eeb03fdf2fd 100644
--- a/gcc/config/arm/t-semiaof
+++ b/gcc/config/arm/t-semiaof
@@ -4,7 +4,9 @@ ENQUIRE=
CROSS_LIBGCC1 = libgcc1-aof.a
LIBGCC2 = libgcc2-aof.a
LIBGCC = libgcc-aof.a
-LIBGCC2_CFLAGS = -O2 -fomit-frame-pointer
+TARGET_LIBGCC2_CFLAGS = -fomit-frame-pointer
+LIBGCC2_DEBUG_CFLAGS = -g0
+
LIBGCC1_TEST = #libgcc1-atest
EXTRA_PARTS = crtbegin.o crtend.o
STMP_FIXPROTO =
diff --git a/gcc/config/arm/thumb.c b/gcc/config/arm/thumb.c
index c7cc7a28e45..43082bb2d72 100644
--- a/gcc/config/arm/thumb.c
+++ b/gcc/config/arm/thumb.c
@@ -1465,7 +1465,8 @@ thumb_unexpanded_epilogue ()
if ((live_regs_mask & (1 << PROGRAM_COUNTER)) == 0)
thumb_exit (asm_out_file,
(had_to_push_lr
- && is_called_in_ARM_mode (current_function_decl)) ? -1 : LINK_REGISTER);
+ && is_called_in_ARM_mode (current_function_decl)) ?
+ -1 : LINK_REGISTER);
}
else
{
@@ -1731,7 +1732,7 @@ thumb_print_operand (f, x, code)
return;
case '_':
- fputs (USER_LABEL_PREFIX, f);
+ fputs (user_label_prefix, f);
return;
case 'D':
@@ -1971,7 +1972,8 @@ thumb_return_in_memory (type)
return 1;
}
-void thumb_override_options()
+void
+thumb_override_options ()
{
if (structure_size_string != NULL)
{
@@ -1982,4 +1984,10 @@ void thumb_override_options()
else
warning ("Structure size boundary can only be set to 8 or 32");
}
+
+ if (flag_pic)
+ {
+ warning ("Position independent code not supported. Ignored");
+ flag_pic = 0;
+ }
}
diff --git a/gcc/config/arm/thumb.h b/gcc/config/arm/thumb.h
index 0f6c60c6390..be2a0e4d5a9 100644
--- a/gcc/config/arm/thumb.h
+++ b/gcc/config/arm/thumb.h
@@ -161,7 +161,7 @@ extern int target_flags;
/* Output a reference to a label. */
#define ASM_OUTPUT_LABELREF(STREAM,NAME) \
- fprintf ((STREAM), "%s%s", USER_LABEL_PREFIX, (NAME))
+ fprintf ((STREAM), "%s%s", user_label_prefix, (NAME))
/* This is how to output an assembler line for a numeric constant byte. */
#define ASM_OUTPUT_BYTE(STREAM,VALUE) \
@@ -977,7 +977,7 @@ int thumb_shiftable_const ();
rtx orig_X = X; \
X = copy_rtx (X); \
push_reload (orig_X, NULL_RTX, &X, NULL_PTR, \
- reload_address_base_reg_class, \
+ BASE_REG_CLASS, \
Pmode, VOIDmode, 0, 0, OPNUM, TYPE); \
goto WIN; \
} \
diff --git a/gcc/config/arm/xm-arm.h b/gcc/config/arm/xm-arm.h
index a6143fa9abf..0899e9f74e5 100644
--- a/gcc/config/arm/xm-arm.h
+++ b/gcc/config/arm/xm-arm.h
@@ -30,6 +30,7 @@ Boston, MA 02111-1307, USA. */
#define HOST_BITS_PER_SHORT 16
#define HOST_BITS_PER_INT 32
#define HOST_BITS_PER_LONG 32
+#define HOST_BITS_PER_LONGLONG 64
/* A code distinguishing the floating point format of the host
machine. There are three defined values: IEEE_FLOAT_FORMAT,
diff --git a/gcc/config/arm/xm-netbsd.h b/gcc/config/arm/xm-netbsd.h
index ea9a64ea4bf..622709c1006 100644
--- a/gcc/config/arm/xm-netbsd.h
+++ b/gcc/config/arm/xm-netbsd.h
@@ -1,7 +1,5 @@
/* Configuration for GCC for ARM running NetBSD as host. */
-#include <arm/xm-arm.h>
-
#ifndef SYS_SIGLIST_DECLARED
#define SYS_SIGLIST_DECLARED
#endif
diff --git a/gcc/config/c4x/c4x.c b/gcc/config/c4x/c4x.c
index f6b75c13ec4..c1309f15ea9 100644
--- a/gcc/config/c4x/c4x.c
+++ b/gcc/config/c4x/c4x.c
@@ -1,5 +1,5 @@
/* Subroutines for assembler code output on the TMS320C[34]x
- Copyright (C) 1994, 1995, 1996, 1997 Free Software Foundation, Inc.
+ Copyright (C) 1994-98, 1999 Free Software Foundation, Inc.
Contributed by Michael Hayes (m.hayes@elec.canterbury.ac.nz)
and Herman Ten Brugge (Haj.Ten.Brugge@net.HCC.nl).
@@ -22,11 +22,8 @@
Boston, MA 02111-1307, USA. */
/* Some output-actions in c4x.md need these. */
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdarg.h>
#include "config.h"
-#include "gansidecl.h"
+#include "system.h"
#include "toplev.h"
#include "rtl.h"
#include "regs.h"
@@ -46,8 +43,6 @@
#include "recog.h"
#include "c-tree.h"
-extern void iteration_info (); /* in unroll.c */
-
static int c4x_leaf_function;
static char *float_reg_names[] = FLOAT_REGISTER_NAMES;
@@ -87,7 +82,7 @@ enum reg_class c4x_regclass_map[FIRST_PSEUDO_REGISTER] =
NO_REGS, /* IIF/IOF No */
INT_REGS, /* RS QI No */
INT_REGS, /* RE QI No */
- INT_REGS, /* RC QI No */
+ RC_REG, /* RC QI No */
EXT_REGS, /* R8 QI, QF, HF QI */
EXT_REGS, /* R9 QI, QF, HF No */
EXT_REGS, /* R10 QI, QF, HF No */
@@ -124,7 +119,7 @@ enum machine_mode c4x_caller_save_map[FIRST_PSEUDO_REGISTER] =
VOIDmode, /* IIF/IOF No */
QImode, /* RS QI No */
QImode, /* RE QI No */
- QImode, /* RC QI No */
+ VOIDmode, /* RC QI No */
QFmode, /* R8 QI, QF, HF QI */
HFmode, /* R9 QI, QF, HF No */
HFmode, /* R10 QI, QF, HF No */
@@ -132,22 +127,6 @@ enum machine_mode c4x_caller_save_map[FIRST_PSEUDO_REGISTER] =
};
-/* rptb_info has enough information to compute rtx for loop counter. */
-typedef struct
-{
- int loop_count; /* Positive if loop count is constant */
- /* The rest of fields are meaningless if loop_count is set */
- rtx start_value; /* Starting value for biv */
- rtx end_value; /* Limit for biv */
- int swap_p; /* 1 for count down */
- int incr; /* Increment for biv -- must be constant */
- int shift; /* log2(incr) */
- int off_by_one; /* 1 for "<", 0 for "<=" */
- int unsigned_p; /* True if unsigned comparison at loop end */
- rtx loop_start;
-}
-c4x_rptb_info_t;
-
/* Test and compare insns in c4x.md store the information needed to
generate branch and scc insns here. */
@@ -167,29 +146,6 @@ tree pure_tree = NULL_TREE;
tree noreturn_tree = NULL_TREE;
tree interrupt_tree = NULL_TREE;
-static void
-c4x_dump (file, s)
- FILE * file;
- const char *s;
- ...
-{
-#ifndef __STDC__
- char *s;
-#endif
- va_list ap;
-
- if (!file)
- return;
-
- VA_START (ap, s);
-
-#ifndef __STDC__
- s = va_arg (ap, char *);
-#endif
-
- vfprintf (file, s, ap);
- va_end (ap);
-}
/* Override command line options.
Called once after all options have been parsed.
@@ -199,9 +155,6 @@ c4x_dump (file, s)
void
c4x_override_options ()
{
- /* Convert foo / 8.0 into foo * 0.125, etc. */
- flag_fast_math = 1;
-
if (c4x_rpts_cycles_string)
c4x_rpts_cycles = atoi (c4x_rpts_cycles_string);
else
@@ -244,8 +197,31 @@ c4x_override_options ()
else
target_flags &= ~C3X_FLAG;
+ /* Convert foo / 8.0 into foo * 0.125, etc. */
+ flag_fast_math = 1;
+
+ /* We should phase out the following at some stage.
+ This provides compatibility with the old -mno-aliases option. */
+ if (! TARGET_ALIASES && ! flag_argument_noalias)
+ flag_argument_noalias = 1;
}
+/* This is called before c4x_override_options. */
+void
+c4x_optimization_options (level, size)
+ int level;
+ int size ATTRIBUTE_UNUSED;
+{
+ /* Scheduling before register allocation can screw up global
+ register allocation, especially for functions that use MPY||ADD
+ instructions. The benefit we gain we get by scheduling before
+ register allocation is probably marginal anyhow. */
+ flag_schedule_insns = 0;
+
+ /* When optimizing, enable use of RPTB instruction. */
+ if (level >= 1)
+ flag_branch_on_count_reg = 1;
+}
/* Write an ASCII string. */
@@ -305,7 +281,7 @@ c4x_output_ascii (stream, ptr, len)
}
if (s)
{
- if (!first)
+ if (! first)
fputc (',', stream);
sbuf[s] = 0;
@@ -441,12 +417,12 @@ c4x_init_cumulative_args (cum, fntype, libname)
/* If the last arg doesn't have void type then we have
variable arguments. */
- if (!next_param)
+ if (! next_param)
cum->var = 1;
if ((mode = TYPE_MODE (type)))
{
- if (!MUST_PASS_IN_STACK (mode, type))
+ if (! MUST_PASS_IN_STACK (mode, type))
{
/* Look for float, double, or long double argument. */
if (mode == QFmode || mode == HFmode)
@@ -483,10 +459,10 @@ c4x_function_arg_advance (cum, mode, type, named)
if (TARGET_DEBUG)
fprintf (stderr, "c4x_function_adv(mode=%s, named=%d)\n\n",
GET_MODE_NAME (mode), named);
- if (!TARGET_MEMPARM
+ if (! TARGET_MEMPARM
&& named
&& type
- && !MUST_PASS_IN_STACK (mode, type))
+ && ! MUST_PASS_IN_STACK (mode, type))
{
/* Look for float, double, or long double argument. */
if (mode == QFmode || mode == HFmode)
@@ -495,7 +471,7 @@ c4x_function_arg_advance (cum, mode, type, named)
else if (mode == QImode || mode == Pmode)
cum->ints++;
}
- else if (!TARGET_MEMPARM && !type)
+ else if (! TARGET_MEMPARM && ! type)
{
/* Handle libcall arguments. */
if (mode == QFmode || mode == HFmode)
@@ -529,7 +505,7 @@ c4x_function_arg (cum, mode, type, named)
{
int reg = 0; /* default to passing argument on stack */
- if (!cum->init)
+ if (! cum->init)
{
/* We can handle at most 2 floats in R2, R3 */
cum->maxfloats = (cum->floats > 2) ? 2 : cum->floats;
@@ -540,17 +516,17 @@ c4x_function_arg (cum, mode, type, named)
6 - cum->maxfloats : cum->ints;
/* If there is no prototype, assume all the arguments are integers. */
- if (!cum->prototype)
+ if (! cum->prototype)
cum->maxints = 6;
cum->ints = cum->floats = 0;
cum->init = 1;
}
- if (!TARGET_MEMPARM
+ if (! TARGET_MEMPARM
&& named
&& type
- && !MUST_PASS_IN_STACK (mode, type))
+ && ! MUST_PASS_IN_STACK (mode, type))
{
/* Look for float, double, or long double argument. */
if (mode == QFmode || mode == HFmode)
@@ -565,7 +541,7 @@ c4x_function_arg (cum, mode, type, named)
reg = c4x_int_reglist[cum->maxfloats][cum->ints];
}
}
- else if (!TARGET_MEMPARM && !type)
+ else if (! TARGET_MEMPARM && ! type)
{
/* We could use a different argument calling model for libcalls,
since we're only calling functions in libgcc. Thus we could
@@ -591,7 +567,7 @@ c4x_function_arg (cum, mode, type, named)
fprintf (stderr, ")\n");
}
if (reg)
- return gen_rtx (REG, mode, reg);
+ return gen_rtx_REG (mode, reg);
else
return NULL_RTX;
}
@@ -610,7 +586,7 @@ c4x_isr_reg_used_p (regno)
We'll only save if for the big memory model or if
we're paranoid. ;-) */
if (IS_DP_REG (regno))
- return !TARGET_SMALL || TARGET_PARANOID;
+ return ! TARGET_SMALL || TARGET_PARANOID;
/* Only save/restore regs in leaf function that are used. */
if (c4x_leaf_function)
@@ -797,7 +773,7 @@ c4x_function_prologue (file, size)
for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
{
- if (regs_ever_live[regno] && !call_used_regs[regno])
+ if (regs_ever_live[regno] && ! call_used_regs[regno])
{
if ((regno == R6_REGNO) || (regno == R7_REGNO))
{
@@ -806,7 +782,7 @@ c4x_function_prologue (file, size)
fprintf (file, "\tpush\t%s\n", reg_names[regno]);
fprintf (file, "\tpushf\t%s\n", float_reg_names[regno]);
}
- else if ((!dont_push_ar3) || (regno != AR3_REGNO))
+ else if ((! dont_push_ar3) || (regno != AR3_REGNO))
{
fprintf (file, "\tpush\t%s\n", reg_names[regno]);
}
@@ -855,7 +831,7 @@ c4x_function_epilogue (file, size)
{
for (regno = FIRST_PSEUDO_REGISTER - 1; regno >= 0; --regno)
{
- if (!c4x_isr_reg_used_p (regno))
+ if (! c4x_isr_reg_used_p (regno))
continue;
if (IS_EXT_REG (regno))
fprintf (file, "\tpopf\t%s\n", float_reg_names[regno]);
@@ -910,8 +886,8 @@ c4x_function_epilogue (file, size)
registers. */
for (regno = FIRST_PSEUDO_REGISTER - 1; regno >= 0; regno--)
{
- if ((regs_ever_live[regno] && !call_used_regs[regno])
- && ((!dont_pop_ar3) || (regno != AR3_REGNO)))
+ if ((regs_ever_live[regno] && ! call_used_regs[regno])
+ && ((! dont_pop_ar3) || (regno != AR3_REGNO)))
{
restore_count++;
if (TARGET_PRESERVE_FLOAT
@@ -944,7 +920,7 @@ c4x_function_epilogue (file, size)
where required. */
for (regno = FIRST_PSEUDO_REGISTER - 1; regno >= 0; regno--)
{
- if (regs_ever_live[regno] && !call_used_regs[regno])
+ if (regs_ever_live[regno] && ! call_used_regs[regno])
{
if (regno == AR3_REGNO && dont_pop_ar3)
continue;
@@ -1011,7 +987,7 @@ c4x_function_epilogue (file, size)
fprintf (file, "\tsubi\t%d,sp\n", size);
}
- if (!delayed_jump)
+ if (! delayed_jump)
fprintf (file, "\trets\n");
}
}
@@ -1022,16 +998,16 @@ c4x_null_epilogue_p ()
int regno;
if (reload_completed
- && !c4x_assembler_function_p ()
- && !c4x_interrupt_function_p ()
- && !current_function_calls_alloca
- && !current_function_args_size
- && !(profile_block_flag == 2)
- && !(optimize < 2)
- && !get_frame_size ())
+ && ! c4x_assembler_function_p ()
+ && ! c4x_interrupt_function_p ()
+ && ! current_function_calls_alloca
+ && ! current_function_args_size
+ && ! (profile_block_flag == 2)
+ && ! (optimize < 2)
+ && ! get_frame_size ())
{
for (regno = FIRST_PSEUDO_REGISTER - 1; regno >= 0; regno--)
- if (regs_ever_live[regno] && !call_used_regs[regno]
+ if (regs_ever_live[regno] && ! call_used_regs[regno]
&& (regno != AR3_REGNO))
return 0;
return 1;
@@ -1039,10 +1015,95 @@ c4x_null_epilogue_p ()
return 0;
}
+int
+c4x_emit_move_sequence (operands, mode)
+ rtx *operands;
+ enum machine_mode mode;
+{
+ rtx op0 = operands[0];
+ rtx op1 = operands[1];
+
+ if (! reload_in_progress
+ && ! REG_P (op0)
+ && ! REG_P (op1)
+ && ! (stik_const_operand (op1, mode) && ! push_operand (op0, mode)))
+ op1 = force_reg (mode, op1);
+
+ if (GET_CODE (op1) == LO_SUM
+ && GET_MODE (op1) == Pmode
+ && dp_reg_operand (XEXP (op1, 0), mode))
+ {
+ /* expand_increment will sometimes create a LO_SUM immediate
+ address. */
+ op1 = XEXP (op1, 1);
+ }
+ else if (symbolic_address_operand (op1, mode))
+ {
+ if (TARGET_LOAD_ADDRESS)
+ {
+ /* Alias analysis seems to do a better job if we force
+ constant addresses to memory after reload. */
+ emit_insn (gen_load_immed_address (op0, op1));
+ return 1;
+ }
+ else
+ {
+ /* Stick symbol or label address into the constant pool. */
+ op1 = force_const_mem (Pmode, op1);
+ }
+ }
+ else if (mode == HFmode && CONSTANT_P (op1) && ! LEGITIMATE_CONSTANT_P (op1))
+ {
+ /* We could be a lot smarter about loading some of these
+ constants... */
+ op1 = force_const_mem (mode, op1);
+ }
+ else if (mode == HImode && CONSTANT_P (op1) && ! LEGITIMATE_CONSTANT_P (op1))
+ {
+ /* We could load all sorts of constants in two goes by pulling all
+ sorts of tricks... The tricky thing is that we cannot clobber CC
+ so that stifles most of the obvious methods. */
+ op1 = force_const_mem (mode, op1);
+ }
+
+ /* Convert (MEM (SYMREF)) to a (MEM (LO_SUM (REG) (SYMREF)))
+ and emit associated (HIGH (SYMREF)) if large memory model.
+ c4x_legitimize_address could be used to do this,
+ perhaps by calling validize_address. */
+ if (! (reload_in_progress || reload_completed)
+ && GET_CODE (op1) == MEM
+ && symbolic_address_operand (XEXP (op1, 0), Pmode))
+ {
+ rtx dp_reg = gen_rtx_REG (Pmode, DP_REGNO);
+ if (! TARGET_SMALL)
+ emit_insn (gen_set_ldp (dp_reg, XEXP (op1, 0)));
+ op1 = change_address (op1, mode,
+ gen_rtx_LO_SUM (Pmode, dp_reg, XEXP (op1, 0)));
+ }
+
+ if (! (reload_in_progress || reload_completed)
+ && GET_CODE (op0) == MEM
+ && symbolic_address_operand (XEXP (op0, 0), Pmode))
+ {
+ rtx dp_reg = gen_rtx_REG (Pmode, DP_REGNO);
+ if (! TARGET_SMALL)
+ emit_insn (gen_set_ldp (dp_reg, XEXP (op0, 0)));
+ op0 = change_address (op0, mode,
+ gen_rtx_LO_SUM (Pmode, dp_reg, XEXP (op0, 0)));
+ }
+
+ /* Adjust operands in case we have modified them. */
+ operands[0] = op0;
+ operands[1] = op1;
+
+ /* Emit normal pattern. */
+ return 0;
+}
+
void
c4x_emit_libcall (name, code, dmode, smode, noperands, operands)
- const char *name;
+ char *name;
enum rtx_code code;
enum machine_mode dmode;
enum machine_mode smode;
@@ -1055,7 +1116,7 @@ c4x_emit_libcall (name, code, dmode, smode, noperands, operands)
rtx equiv;
start_sequence ();
- libcall = gen_rtx (SYMBOL_REF, Pmode, name);
+ libcall = gen_rtx_SYMBOL_REF (Pmode, name);
switch (noperands)
{
case 2:
@@ -1090,9 +1151,10 @@ c4x_emit_libcall3 (name, code, mode, operands)
return c4x_emit_libcall (name, code, mode, mode, 3, operands);
}
+
void
c4x_emit_libcall_mulhi (name, code, mode, operands)
- const char *name;
+ char *name;
enum rtx_code code;
enum machine_mode mode;
rtx *operands;
@@ -1103,15 +1165,15 @@ c4x_emit_libcall_mulhi (name, code, mode, operands)
rtx equiv;
start_sequence ();
- libcall = gen_rtx (SYMBOL_REF, Pmode, name);
+ libcall = gen_rtx_SYMBOL_REF (Pmode, name);
ret = emit_library_call_value (libcall, NULL_RTX, 1, mode, 2,
operands[1], mode, operands[2], mode);
- equiv = gen_rtx (TRUNCATE, mode,
- gen_rtx (LSHIFTRT, HImode,
- gen_rtx (MULT, HImode,
+ equiv = gen_rtx_TRUNCATE (mode,
+ gen_rtx_LSHIFTRT (HImode,
+ gen_rtx_MULT (HImode,
gen_rtx (code, HImode, operands[1]),
gen_rtx (code, HImode, operands[2])),
- gen_rtx (CONST_INT, VOIDmode, 32)));
+ GEN_INT (32)));
insns = get_insns ();
end_sequence ();
emit_libcall_block (insns, operands[0], ret, equiv);
@@ -1120,31 +1182,16 @@ c4x_emit_libcall_mulhi (name, code, mode, operands)
enum reg_class
c4x_preferred_reload_class (x, class)
- rtx x;
+ rtx x ATTRIBUTE_UNUSED;
enum reg_class class;
{
- if (GET_CODE (x) == MEM && class > ADDR_REGS && class != INDEX_REGS)
- {
- x = XEXP (x, 0);
- if (GET_CODE (x) == PLUS)
- {
- rtx op0 = XEXP (x, 0);
- rtx op1 = XEXP (x, 1);
-
- if (REG_P (op0)
- && IS_ADDR_REGNO (op0)
- && GET_CODE (op1) == CONST_INT
- && !IS_DISP8_CONST (INTVAL (op1)))
- class = ADDR_REGS;
- }
- }
return class;
}
enum reg_class
c4x_limit_reload_class (mode, class)
- enum machine_mode mode;
+ enum machine_mode mode ATTRIBUTE_UNUSED;
enum reg_class class;
{
return class;
@@ -1153,14 +1200,30 @@ c4x_limit_reload_class (mode, class)
enum reg_class
c4x_secondary_memory_needed (class1, class2, mode)
- enum reg_class class1;
- enum reg_class class2;
- enum machine_mode mode;
+ enum reg_class class1 ATTRIBUTE_UNUSED;
+ enum reg_class class2 ATTRIBUTE_UNUSED;
+ enum machine_mode mode ATTRIBUTE_UNUSED;
{
return 0;
}
+/* Set the SYMBOL_REF_FLAG for a function decl. However, wo do not
+ yet use this info. */
+void
+c4x_encode_section_info (decl)
+ tree decl;
+{
+#if 0
+ if (TREE_CODE (TREE_TYPE (decl)) == FUNCTION_TYPE)
+ SYMBOL_REF_FLAG (XEXP (DECL_RTL (decl), 0)) = 1;
+#else
+ if (TREE_CODE (decl) == FUNCTION_DECL)
+ SYMBOL_REF_FLAG (XEXP (DECL_RTL (decl), 0)) = 1;
+#endif
+}
+
+
int
c4x_check_legit_addr (mode, addr, strict)
enum machine_mode mode;
@@ -1186,7 +1249,7 @@ c4x_check_legit_addr (mode, addr, strict)
case PRE_INC:
case POST_INC:
base = XEXP (addr, 0);
- if (!REG_P (base))
+ if (! REG_P (base))
return 0;
break;
@@ -1199,7 +1262,7 @@ c4x_check_legit_addr (mode, addr, strict)
if (mode != QImode && mode != QFmode)
return 0;
- if (!REG_P (op0)
+ if (! REG_P (op0)
|| (GET_CODE (op1) != PLUS && GET_CODE (op1) != MINUS))
return 0;
base = XEXP (op1, 0);
@@ -1226,19 +1289,6 @@ c4x_check_legit_addr (mode, addr, strict)
switch (code0)
{
- case USE:
- /* The uses are put in to avoid problems
- with referenced things disappearing. */
- return c4x_check_legit_addr (mode, op1, strict);
-
- case PLUS:
- /* This is another reference to keep things
- from disappearing, but it contains a plus
- of a use and DP. */
- if (GET_CODE (XEXP (op0, 0)) == USE)
- return c4x_check_legit_addr (mode, op1, strict);
- return 0;
-
case REG:
if (REG_P (op1))
{
@@ -1263,18 +1313,47 @@ c4x_check_legit_addr (mode, addr, strict)
}
break;
+ /* Direct addressing with DP register. */
+ case LO_SUM:
+ {
+ rtx op0 = XEXP (addr, 0);
+ rtx op1 = XEXP (addr, 1);
+
+ /* HImode and HFmode direct memory references aren't truly
+ offsettable (consider case at end of data page). We
+ probably get better code by loading a pointer and using an
+ indirect memory reference. */
+ if (mode == HImode || mode == HFmode)
+ return 0;
+
+ if (!REG_P (op0) || REGNO (op0) != DP_REGNO)
+ return 0;
+
+ if ((GET_CODE (op1) == SYMBOL_REF || GET_CODE (op1) == LABEL_REF))
+ return 1;
+
+ if (GET_CODE (op1) == CONST)
+ {
+ addr = XEXP (op1, 0);
+
+ if (GET_CODE (addr) == PLUS
+ && (GET_CODE (XEXP (addr, 0)) == SYMBOL_REF
+ || GET_CODE (XEXP (addr, 0)) == LABEL_REF)
+ && GET_CODE (XEXP (addr, 1)) == CONST_INT)
+ return 1;
+ }
+ return 0;
+ }
+ break;
+
/* Direct addressing with some work for the assembler... */
case CONST:
- if (GET_CODE (XEXP (addr, 0)) == PLUS
- && (GET_CODE (XEXP (XEXP (addr, 0), 0)) == SYMBOL_REF
- || GET_CODE (XEXP (XEXP (addr, 0), 0)) == LABEL_REF)
- && GET_CODE (XEXP (XEXP (addr, 0), 1)) == CONST_INT)
- return 1;
-
/* Direct addressing. */
- case SYMBOL_REF:
case LABEL_REF:
- return 1;
+ case SYMBOL_REF:
+ /* These need to be converted to a LO_SUM (...).
+ c4x_legitimize_address will fix them up. */
+ return 0;
/* Do not allow direct memory access to absolute addresses.
This is more pain than its worth, especially for the
@@ -1306,9 +1385,9 @@ c4x_check_legit_addr (mode, addr, strict)
/* Handle DP based stuff. */
if (REGNO (base) == DP_REGNO)
return 1;
- if (strict && !REGNO_OK_FOR_BASE_P (REGNO (base)))
+ if (strict && ! REGNO_OK_FOR_BASE_P (REGNO (base)))
return 0;
- else if (!strict && !IS_ADDR_OR_PSEUDO_REGNO (base))
+ else if (! strict && ! IS_ADDR_OR_PSEUDO_REGNO (base))
return 0;
}
@@ -1317,9 +1396,9 @@ c4x_check_legit_addr (mode, addr, strict)
{
if (GET_CODE (indx) != REG)
return 0;
- if (strict && !REGNO_OK_FOR_INDEX_P (REGNO (indx)))
+ if (strict && ! REGNO_OK_FOR_INDEX_P (REGNO (indx)))
return 0;
- else if (!strict && !IS_INDEX_OR_PSEUDO_REGNO (indx))
+ else if (! strict && ! IS_INDEX_OR_PSEUDO_REGNO (indx))
return 0;
}
@@ -1331,12 +1410,12 @@ c4x_check_legit_addr (mode, addr, strict)
if (mode == HImode || mode == HFmode)
{
/* The offset displacement must be legitimate. */
- if (!IS_DISP8_OFF_CONST (INTVAL (disp)))
+ if (! IS_DISP8_OFF_CONST (INTVAL (disp)))
return 0;
}
else
{
- if (!IS_DISP8_CONST (INTVAL (disp)))
+ if (! IS_DISP8_CONST (INTVAL (disp)))
return 0;
}
/* Can't add an index with a disp. */
@@ -1349,9 +1428,30 @@ c4x_check_legit_addr (mode, addr, strict)
rtx
c4x_legitimize_address (orig, mode)
- rtx orig;
- enum machine_mode mode;
+ rtx orig ATTRIBUTE_UNUSED;
+ enum machine_mode mode ATTRIBUTE_UNUSED;
{
+ if (GET_CODE (orig) == SYMBOL_REF)
+ {
+ if (mode == HImode || mode == HFmode)
+ {
+ /* We need to force the address into
+ a register so that it is offsettable. */
+ rtx addr_reg = gen_reg_rtx (Pmode);
+ emit_move_insn (addr_reg, orig);
+ return addr_reg;
+ }
+ else
+ {
+ rtx dp_reg = gen_rtx_REG (Pmode, DP_REGNO);
+
+ if (! TARGET_SMALL)
+ emit_insn (gen_set_ldp (dp_reg, orig));
+
+ return gen_rtx_LO_SUM (Pmode, dp_reg, orig);
+ }
+ }
+
return NULL_RTX;
}
@@ -1371,32 +1471,46 @@ rtx addr;
case REG:
return 1;
- case CONST:
- {
- rtx offset = const0_rtx;
- addr = eliminate_constant_term (addr, &offset);
-
- if (GET_CODE (addr) == LABEL_REF)
- return 3;
-
- if (GET_CODE (addr) != SYMBOL_REF)
- return 4;
-
- if (INTVAL (offset) == 0)
- return 3;
- }
-
- /* fall through */
-
case POST_INC:
case POST_DEC:
case PRE_INC:
case PRE_DEC:
return 1;
+ /* These shouldn't be directly generated. */
case SYMBOL_REF:
case LABEL_REF:
- return TARGET_SMALL ? 3 : 4;
+ case CONST:
+ return 10;
+
+ case LO_SUM:
+ {
+ rtx op1 = XEXP (addr, 1);
+
+ if (GET_CODE (op1) == LABEL_REF || GET_CODE (op1) == SYMBOL_REF)
+ return TARGET_SMALL ? 3 : 4;
+
+ if (GET_CODE (op1) == CONST)
+ {
+ rtx offset = const0_rtx;
+
+ op1 = eliminate_constant_term (op1, &offset);
+
+ /* ??? These costs need rethinking... */
+ if (GET_CODE (op1) == LABEL_REF)
+ return 3;
+
+ if (GET_CODE (op1) != SYMBOL_REF)
+ return 4;
+
+ if (INTVAL (offset) == 0)
+ return 3;
+
+ return 4;
+ }
+ fatal_insn ("c4x_address_cost: Invalid addressing mode", addr);
+ }
+ break;
case PLUS:
{
@@ -1412,13 +1526,15 @@ rtx addr;
break;
case REG:
+ /* This cost for REG+REG must be greater than the cost
+ for REG if we want autoincrement addressing modes. */
return 2;
case CONST_INT:
if (IS_DISP1_CONST (INTVAL (op1)))
return 1;
- if (!TARGET_C3X && IS_UINT5_CONST (INTVAL (op1)))
+ if (! TARGET_C3X && IS_UINT5_CONST (INTVAL (op1)))
return 2;
return 3;
@@ -1443,37 +1559,33 @@ c4x_gen_compare_reg (code, x, y)
&& (code == LE || code == GE || code == LT || code == GT))
return NULL_RTX;
- cc_reg = gen_rtx (REG, mode, ST_REGNO);
- emit_insn (gen_rtx (SET, VOIDmode, cc_reg,
- gen_rtx (COMPARE, mode, x, y)));
+ cc_reg = gen_rtx_REG (mode, ST_REGNO);
+ emit_insn (gen_rtx_SET (VOIDmode, cc_reg,
+ gen_rtx_COMPARE (mode, x, y)));
return cc_reg;
}
char *
-c4x_output_cbranch (reversed, insn)
- int reversed;
- rtx insn;
+c4x_output_cbranch (form, seq)
+ char *form;
+ rtx seq;
{
int delayed = 0;
int annultrue = 0;
int annulfalse = 0;
rtx delay;
char *cp;
- static char str[20];
+ static char str[100];
if (final_sequence)
{
delay = XVECEXP (final_sequence, 0, 1);
- delayed = !INSN_ANNULLED_BRANCH_P (insn);
- annultrue = INSN_ANNULLED_BRANCH_P (insn) && !INSN_FROM_TARGET_P (delay);
- annulfalse = INSN_ANNULLED_BRANCH_P (insn) && INSN_FROM_TARGET_P (delay);
+ delayed = ! INSN_ANNULLED_BRANCH_P (seq);
+ annultrue = INSN_ANNULLED_BRANCH_P (seq) && ! INSN_FROM_TARGET_P (delay);
+ annulfalse = INSN_ANNULLED_BRANCH_P (seq) && INSN_FROM_TARGET_P (delay);
}
- cp = str;
- *cp++ = 'b';
- *cp++ = '%';
- if (reversed)
- *cp++ = 'I';
- *cp++ = '0';
+ strcpy (str, form);
+ cp = &str [strlen (str)];
if (delayed)
{
*cp++ = '%';
@@ -1497,7 +1609,6 @@ c4x_output_cbranch (reversed, insn)
return str;
}
-
void
c4x_print_operand (file, op, letter)
FILE *file; /* file to write to */
@@ -1523,18 +1634,9 @@ c4x_print_operand (file, op, letter)
asm_fprintf (file, "@");
break;
- case 'C': /* call */
- if (code != MEM)
- fatal_insn ("c4x_print_operand: %%C inconsistency", op);
- op1 = XEXP (op, 0);
- SYMBOL_REF_FLAG (op1) = 1;
- output_addr_const (file, op1);
- return;
-
case 'H': /* sethi */
- if (code == SYMBOL_REF)
- SYMBOL_REF_FLAG (op) = 1;
- break;
+ output_addr_const (file, op);
+ return;
case 'I': /* reversed condition */
code = reverse_condition (code);
@@ -1553,11 +1655,11 @@ c4x_print_operand (file, op, letter)
return;
case 'K': /* generate ldp(k) if direct address */
- if (!TARGET_SMALL
+ if (! TARGET_SMALL
&& code == MEM
- && GET_CODE (XEXP (op, 0)) == PLUS
- && GET_CODE(XEXP (XEXP (op, 0), 0)) == REG
- && REGNO(XEXP (XEXP (op, 0), 0)) == DP_REGNO)
+ && GET_CODE (XEXP (op, 0)) == LO_SUM
+ && GET_CODE (XEXP (XEXP (op, 0), 0)) == REG
+ && REGNO (XEXP (XEXP (op, 0), 0)) == DP_REGNO)
{
op1 = XEXP (XEXP (op, 0), 1);
if (GET_CODE(op1) == CONST_INT || GET_CODE(op1) == SYMBOL_REF)
@@ -1570,7 +1672,7 @@ c4x_print_operand (file, op, letter)
return;
case 'M': /* generate ldp(k) if direct address */
- if (!TARGET_SMALL /* only used in asm statements */
+ if (! TARGET_SMALL /* only used in asm statements */
&& code == MEM
&& (GET_CODE (XEXP (op, 0)) == CONST
|| GET_CODE (XEXP (op, 0)) == SYMBOL_REF))
@@ -1592,12 +1694,12 @@ c4x_print_operand (file, op, letter)
fatal_insn ("c4x_print_operand: %%O inconsistency", op);
return;
- case 'R': /* call register */
- op1 = XEXP (op, 0);
- if (code != MEM || GET_CODE (op1) != REG)
- fatal_insn ("c4x_print_operand: %%R inconsistency", op);
- else
- fprintf (file, "%s", reg_names[REGNO (op1)]);
+ case 'C': /* call */
+ break;
+
+ case 'U': /* call/callu */
+ if (code != SYMBOL_REF)
+ asm_fprintf (file, "u");
return;
default:
@@ -1765,20 +1867,10 @@ c4x_print_operand_address (file, addr)
{
rtx op0 = XEXP (addr, 0);
rtx op1 = XEXP (addr, 1);
- enum rtx_code code0 = GET_CODE (op0);
- if (code0 == USE || code0 == PLUS)
- {
- asm_fprintf (file, "@");
- output_addr_const (file, op1);
- }
- else if (REG_P (op0))
+ if (REG_P (op0))
{
- if (REGNO (op0) == DP_REGNO)
- {
- c4x_print_operand_address (file, op1);
- }
- else if (REG_P (op1))
+ if (REG_P (op1))
{
if (IS_INDEX_REGNO (op0))
{
@@ -1806,16 +1898,28 @@ c4x_print_operand_address (file, addr)
INTVAL (op1)); /* base + displacement */
}
}
+ else
+ fatal_insn ("c4x_print_operand_address: Bad operand case", addr);
+ }
+ break;
+
+ case LO_SUM:
+ {
+ rtx op0 = XEXP (addr, 0);
+ rtx op1 = XEXP (addr, 1);
+
+ if (REG_P (op0) && REGNO (op0) == DP_REGNO)
+ c4x_print_operand_address (file, op1);
+ else
+ fatal_insn ("c4x_print_operand_address: Bad operand case", addr);
}
break;
case CONST:
case SYMBOL_REF:
case LABEL_REF:
- if (!SYMBOL_REF_FLAG (addr))
- fprintf (file, "@");
+ fprintf (file, "@");
output_addr_const (file, addr);
- SYMBOL_REF_FLAG (addr) = 0;
break;
/* We shouldn't access CONST_INT addresses. */
@@ -1827,17 +1931,18 @@ c4x_print_operand_address (file, addr)
}
}
-
+/* Return nonzero if the floating point operand will fit
+ in the immediate field. */
static int
-c4x_immed_float_p (operand)
- rtx operand;
+c4x_immed_float_p (op)
+ rtx op;
{
long convval[2];
int exponent;
REAL_VALUE_TYPE r;
- REAL_VALUE_FROM_CONST_DOUBLE (r, operand);
- if (GET_MODE (operand) == HFmode)
+ REAL_VALUE_FROM_CONST_DOUBLE (r, op);
+ if (GET_MODE (op) == HFmode)
REAL_VALUE_TO_TARGET_DOUBLE (r, convval);
else
{
@@ -1855,157 +1960,6 @@ c4x_immed_float_p (operand)
&& (exponent >= -7); /* Negative exp */
}
-
-/* This function checks for an insn operand that requires direct
- addressing and inserts a load of the DP register prior to the
- insn if the big memory model is being compiled for. Immediate
- operands that do not fit within the opcode field get changed
- into memory references using direct addressing. At this point
- all pseudos have been converted to hard registers. */
-
-int
-c4x_scan_for_ldp (newop, insn, operand0)
- rtx *newop;
- rtx insn;
- rtx operand0;
-{
- int i;
- char *format_ptr;
- rtx op0, op1, op2, addr;
- rtx operand = *newop;
-
- switch (GET_CODE (operand))
- {
- case MEM:
- op0 = XEXP (operand, 0);
-
- /* We have something we need to emit a load dp insn for.
- The first operand should hold the rtx for the instruction
- required. */
-
- switch (GET_CODE (op0))
- {
- case CONST_INT:
- fatal_insn ("c4x_scan_for_ldp: Direct memory access to const_int",
- op0);
- break;
-
- case CONST:
- case SYMBOL_REF:
- if (!TARGET_C3X && !TARGET_SMALL
- && recog_memoized (insn) == CODE_FOR_movqi_noclobber
- && ((addr = find_reg_note (insn, REG_EQUAL, NULL_RTX))
- || (addr = find_reg_note (insn, REG_EQUIV, NULL_RTX)))
- && (IS_STD_OR_PSEUDO_REGNO (operand0)))
- {
- addr = XEXP (addr, 0);
- if (GET_CODE (addr) == CONST_INT)
- {
- op1 = gen_rtx (CONST_INT, VOIDmode, INTVAL (addr) & ~0xffff);
- emit_insn_before (gen_movqi (operand0, op1), insn);
- op1 = gen_rtx (CONST_INT, VOIDmode, INTVAL (addr) & 0xffff);
- emit_insn_before (gen_iorqi3_noclobber (operand0,
- operand0, op1), insn);
- delete_insn (insn);
- return 1;
- }
- else if (GET_CODE (addr) == SYMBOL_REF)
- {
- emit_insn_before (gen_set_high_use (operand0, addr, addr),
- insn);
- emit_insn_before (gen_set_ior_lo_use (operand0, addr, addr),
- insn);
- delete_insn (insn);
- return 1;
- }
- else if (GET_CODE (addr) == CONST
- && GET_CODE (op1 = XEXP (addr, 0)) == PLUS
- && GET_CODE (op2 = XEXP (op1, 0)) == SYMBOL_REF
- && GET_CODE (XEXP (op1, 1)) == CONST_INT)
- {
- emit_insn_before (gen_set_high_use (operand0, addr, op2),
- insn);
- emit_insn_before (gen_set_ior_lo_use (operand0, addr, op2),
- insn);
- delete_insn (insn);
- return 1;
- }
- }
- if (!TARGET_SMALL)
- emit_insn_before (gen_set_ldp (gen_rtx (REG, Pmode, DP_REGNO),
- operand), insn);
-
- /* Replace old memory reference with direct reference. */
- *newop = gen_rtx (MEM, GET_MODE (operand),
- gen_rtx (PLUS, Pmode,
- gen_rtx (REG, Pmode, DP_REGNO), op0));
-
- /* Use change_address? */
- MEM_VOLATILE_P (*newop) = MEM_VOLATILE_P (operand);
- RTX_UNCHANGING_P (*newop) = RTX_UNCHANGING_P (operand);
- MEM_IN_STRUCT_P (*newop) = MEM_IN_STRUCT_P (operand);
- break;
-
- default:
- break;
- }
-
- return 0;
-
- case CONST_INT:
- if (SMALL_CONST (INTVAL (operand), insn))
- break;
- fatal_insn ("Immediate integer too large", insn);
-
- case CONST_DOUBLE:
- if (c4x_immed_float_p (operand))
- break;
-
- /* We'll come here if a CONST_DOUBLE integer has slipped
- though the net... */
- fatal_insn ("Immediate CONST_DOUBLE integer too large", insn);
-
- case CONST:
- fatal_insn ("Immediate integer not known", insn);
-
- /* Symbol and label immediate addresses cannot be stored
- within a C[34]x instruction, so we store them in memory
- and use direct addressing instead. */
- case LABEL_REF:
- case SYMBOL_REF:
- if (GET_CODE (operand0) != REG)
- break;
-
- op0 = XEXP (force_const_mem (Pmode, operand), 0);
- *newop = gen_rtx (MEM, GET_MODE (operand),
- gen_rtx (PLUS, Pmode,
- gen_rtx (PLUS, Pmode,
- gen_rtx (USE, VOIDmode, operand),
- gen_rtx (REG, Pmode, DP_REGNO)),
- op0));
-
- if (!TARGET_SMALL)
- emit_insn_before (gen_set_ldp_use (gen_rtx (REG, Pmode, DP_REGNO),
- *newop, operand), insn);
- return 0;
-
- default:
- break;
- }
-
- format_ptr = GET_RTX_FORMAT (GET_CODE (operand));
-
- /* Recursively hunt for required loads of DP. */
- for (i = 0; i < GET_RTX_LENGTH (GET_CODE (operand)); i++)
- {
- if (*format_ptr++ == 'e') /* rtx expression */
- if (c4x_scan_for_ldp (&XEXP (operand, i), insn, operand0))
- break;
- }
- return 0;
-}
-
-
/* The last instruction in a repeat block cannot be a Bcond, DBcound,
CALL, CALLCond, TRAPcond, RETIcond, RETScond, IDLE, RPTB or RPTS.
@@ -2021,17 +1975,27 @@ c4x_scan_for_ldp (newop, insn, operand0)
Note that we cannot have a call insn, since we don't generate
repeat loops with calls in them (although I suppose we could, but
- there's no benefit.) */
+ there's no benefit.)
+
+ !!! FIXME. The rptb_top insn may be sucked into a SEQUENCE. */
int
c4x_rptb_nop_p (insn)
rtx insn;
{
+ rtx start_label;
int i;
+ /* Extract the start label from the jump pattern (rptb_end). */
+ start_label = XEXP (XEXP (SET_SRC (XVECEXP (PATTERN (insn), 0, 0)), 1), 0);
+
/* If there is a label at the end of the loop we must insert
a NOP. */
- insn = prev_nonnote_insn (insn);
+ do {
+ insn = previous_insn (insn);
+ } while (GET_CODE (insn) == NOTE
+ || GET_CODE (insn) == USE
+ || GET_CODE (insn) == CLOBBER);
if (GET_CODE (insn) == CODE_LABEL)
return 1;
@@ -2040,43 +2004,73 @@ c4x_rptb_nop_p (insn)
/* Search back for prev non-note and non-label insn. */
while (GET_CODE (insn) == NOTE || GET_CODE (insn) == CODE_LABEL
|| GET_CODE (insn) == USE || GET_CODE (insn) == CLOBBER)
- insn = PREV_INSN (insn);
+ {
+ if (insn == start_label)
+ return i == 0;
+
+ insn = previous_insn (insn);
+ };
- /* I we have a jump instruction we should insert a NOP. If we
+ /* If we have a jump instruction we should insert a NOP. If we
hit repeat block top we should only insert a NOP if the loop
is empty. */
if (GET_CODE (insn) == JUMP_INSN)
return 1;
- else if (recog_memoized (insn) == CODE_FOR_rptb_top)
- return i == 0;
- insn = PREV_INSN (insn);
+ insn = previous_insn (insn);
}
return 0;
}
-/* This function is a C4x special. It scans through all the insn
- operands looking for places where the DP register needs to be
- reloaded and for large immediate operands that need to be converted
- to memory references. The latter should be avoidable with proper
- definition of patterns in machine description. We come here right
- near the end of things, immediately before delayed branch
- scheduling. */
+void
+c4x_rptb_insert (insn)
+ rtx insn;
+{
+ rtx end_label;
+ rtx start_label;
+ rtx count_reg;
+
+ /* If the count register has not been allocated to RC, say if
+ there is a movstr pattern in the loop, then do not insert a
+ RPTB instruction. Instead we emit a decrement and branch
+ at the end of the loop. */
+ count_reg = XEXP (XEXP (SET_SRC (XVECEXP (PATTERN (insn), 0, 0)), 0), 0);
+ if (REGNO (count_reg) != RC_REGNO)
+ return;
+
+ /* Extract the start label from the jump pattern (rptb_end). */
+ start_label = XEXP (XEXP (SET_SRC (XVECEXP (PATTERN (insn), 0, 0)), 1), 0);
+
+ /* We'll have to update the basic blocks. */
+ end_label = gen_label_rtx ();
+ emit_label_after (end_label, insn);
+
+ for (; insn; insn = PREV_INSN (insn))
+ if (insn == start_label)
+ break;
+ if (! insn)
+ fatal_insn ("c4x_rptb_insert: Cannot find start label", start_label);
+
+ /* We'll have to update the basic blocks. */
+ emit_insn_before (gen_rptb_top (start_label, end_label), insn);
+}
+
+
+/* This function is a C4x special called immediately before delayed
+ branch scheduling. We fix up RTPB style loops that didn't get RC
+ allocated as the loop counter. */
void
c4x_process_after_reload (first)
rtx first;
{
- rtx operand0;
rtx insn;
- int i;
for (insn = first; insn; insn = NEXT_INSN (insn))
{
/* Look for insn. */
if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
{
- int noperands;
int insn_code_number;
insn_code_number = recog_memoized (insn);
@@ -2084,14 +2078,17 @@ c4x_process_after_reload (first)
if (insn_code_number < 0)
continue;
+ /* Insert the RTX for RPTB at the top of the loop
+ and a label at the end of the loop. */
+ if (insn_code_number == CODE_FOR_rptb_end)
+ c4x_rptb_insert(insn);
+
/* We split all insns here if they have a # for the output
- template if we are using the big memory model since there
- is a chance that we might be accessing memory across a
- page boundary. */
+ template. */
- if (!TARGET_SMALL)
+ if (1)
{
- char *template;
+ const char *template;
template = insn_template[insn_code_number];
if (template && template[0] == '#' && template[1] == '\0')
@@ -2105,37 +2102,9 @@ c4x_process_after_reload (first)
PUT_CODE (insn, NOTE);
NOTE_SOURCE_FILE (insn) = 0;
NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
-
- /* Do we have to update the basic block info here?
- Maybe reorg wants it sorted out... */
-
- /* Continue with the first of the new insns gnerated
- by the split. */
insn = new;
-
- insn_code_number = recog_memoized (insn);
-
- if (insn_code_number < 0)
- continue;
}
}
-
- /* Ignore jumps and calls. */
- if (GET_CODE (insn) == CALL_INSN
- || GET_CODE (insn) == JUMP_INSN)
- {
- continue; /* Hopefully we are not hosed here. */
- }
-
- noperands = insn_n_operands[insn_code_number];
-
- insn_extract (insn);
-
- operand0 = recog_operand[0];
-
- for (i = 0; i < noperands; i++)
- if (c4x_scan_for_ldp (recog_operand_loc[i], insn, operand0))
- break;
}
}
}
@@ -2158,11 +2127,12 @@ c4x_x_register (op)
static int
-c4x_int_constant (op)
+c4x_immed_int_constant (op)
rtx op;
{
if (GET_CODE (op) != CONST_INT)
return 0;
+
return GET_MODE (op) == VOIDmode
|| GET_MODE_CLASS (op) == MODE_INT
|| GET_MODE_CLASS (op) == MODE_PARTIAL_INT;
@@ -2170,11 +2140,15 @@ c4x_int_constant (op)
static int
-c4x_float_constant (op)
+c4x_immed_float_constant (op)
rtx op;
{
if (GET_CODE (op) != CONST_DOUBLE)
return 0;
+
+ if (GET_CODE (XEXP (op, 0)) == MEM)
+ return 0;
+
return GET_MODE (op) == QFmode || GET_MODE (op) == HFmode;
}
@@ -2183,7 +2157,7 @@ int
c4x_H_constant (op)
rtx op;
{
- return c4x_float_constant (op) && c4x_immed_float_p (op);
+ return c4x_immed_float_constant (op) && c4x_immed_float_p (op);
}
@@ -2191,7 +2165,7 @@ int
c4x_I_constant (op)
rtx op;
{
- return c4x_int_constant (op) && IS_INT16_CONST (INTVAL (op));
+ return c4x_immed_int_constant (op) && IS_INT16_CONST (INTVAL (op));
}
@@ -2201,7 +2175,7 @@ c4x_J_constant (op)
{
if (TARGET_C3X)
return 0;
- return c4x_int_constant (op) && IS_INT8_CONST (INTVAL (op));
+ return c4x_immed_int_constant (op) && IS_INT8_CONST (INTVAL (op));
}
@@ -2211,7 +2185,7 @@ c4x_K_constant (op)
{
if (TARGET_C3X)
return 0;
- return c4x_int_constant (op) && IS_INT5_CONST (INTVAL (op));
+ return c4x_immed_int_constant (op) && IS_INT5_CONST (INTVAL (op));
}
@@ -2219,7 +2193,7 @@ int
c4x_L_constant (op)
rtx op;
{
- return c4x_int_constant (op) && IS_UINT16_CONST (INTVAL (op));
+ return c4x_immed_int_constant (op) && IS_UINT16_CONST (INTVAL (op));
}
@@ -2227,7 +2201,7 @@ static int
c4x_N_constant (op)
rtx op;
{
- return c4x_int_constant (op) && IS_NOT_UINT16_CONST (INTVAL (op));
+ return c4x_immed_int_constant (op) && IS_NOT_UINT16_CONST (INTVAL (op));
}
@@ -2235,7 +2209,7 @@ static int
c4x_O_constant (op)
rtx op;
{
- return c4x_int_constant (op) && IS_HIGH_CONST (INTVAL (op));
+ return c4x_immed_int_constant (op) && IS_HIGH_CONST (INTVAL (op));
}
@@ -2267,7 +2241,7 @@ c4x_Q_constraint (op)
rtx op0 = XEXP (op, 0);
rtx op1 = XEXP (op, 1);
- if (!REG_P (op0))
+ if (! REG_P (op0))
return 0;
if (REG_P (op1))
@@ -2283,6 +2257,7 @@ c4x_Q_constraint (op)
return IS_DISP8_CONST (INTVAL (op1));
}
break;
+
default:
break;
}
@@ -2314,7 +2289,7 @@ c4x_R_constraint (op)
rtx op0 = XEXP (op, 0);
rtx op1 = XEXP (op, 1);
- if (!REG_P (op0))
+ if (! REG_P (op0))
return 0;
if (GET_CODE (op1) != CONST_INT)
@@ -2514,7 +2489,7 @@ c4x_S_indirect (op)
}
-/* Symbol ref. */
+/* Direct memory operand. */
int
c4x_T_constraint (op)
@@ -2524,27 +2499,37 @@ c4x_T_constraint (op)
return 0;
op = XEXP (op, 0);
- if ((GET_CODE (op) == PLUS)
- && (GET_CODE (XEXP (op, 0)) == REG)
- && (REGNO (XEXP (op, 0)) == DP_REGNO))
+ if (GET_CODE (op) != LO_SUM)
{
- op = XEXP (op, 1);
- }
- else if ((GET_CODE (op) == PLUS)
- && (GET_CODE (XEXP (op, 0)) == PLUS)
- && (GET_CODE (XEXP (XEXP (op, 0), 0)) == USE))
- {
- op = XEXP (op, 1);
- }
- else if ((GET_CODE (op) == PLUS) && (GET_CODE (XEXP (op, 0)) == USE))
- {
- op = XEXP (op, 1);
+ /* Allow call operands. */
+ return GET_CODE (op) == SYMBOL_REF
+ && GET_MODE (op) == Pmode
+ && SYMBOL_REF_FLAG (op);
}
+ /* HImode and HFmode are not offsettable. */
+ if (GET_MODE (op) == HImode || GET_CODE (op) == HFmode)
+ return 0;
+
+ if ((GET_CODE (XEXP (op, 0)) == REG)
+ && (REGNO (XEXP (op, 0)) == DP_REGNO))
+ return c4x_U_constraint (XEXP (op, 1));
+
+ return 0;
+}
+
+
+/* Symbolic operand. */
+
+int
+c4x_U_constraint (op)
+ rtx op;
+{
/* Don't allow direct addressing to an arbitrary constant. */
if (GET_CODE (op) == CONST
&& GET_CODE (XEXP (op, 0)) == PLUS
- && GET_CODE (XEXP (XEXP (op, 0), 0)) == SYMBOL_REF
+ && (GET_CODE (XEXP (XEXP (op, 0), 0)) == SYMBOL_REF
+ || GET_CODE (XEXP (XEXP (op, 0), 0)) == LABEL_REF)
&& GET_CODE (XEXP (XEXP (op, 0), 1)) == CONST_INT)
return 1;
@@ -2555,7 +2540,7 @@ c4x_T_constraint (op)
int
c4x_autoinc_operand (op, mode)
rtx op;
- enum machine_mode mode;
+ enum machine_mode mode ATTRIBUTE_UNUSED;
{
if (GET_CODE (op) == MEM)
{
@@ -2578,8 +2563,8 @@ c4x_autoinc_operand (op, mode)
int
any_operand (op, mode)
- register rtx op;
- enum machine_mode mode;
+ register rtx op ATTRIBUTE_UNUSED;
+ enum machine_mode mode ATTRIBUTE_UNUSED;
{
return 1;
}
@@ -2618,6 +2603,9 @@ const_operand (op, mode)
case Pmode:
#endif
case QImode:
+ if (GET_CODE (op) == CONSTANT_P_RTX)
+ return 1;
+
if (GET_CODE (op) != CONST_INT
|| (GET_MODE (op) != VOIDmode && GET_MODE (op) != mode)
|| GET_MODE_CLASS (mode) != MODE_INT)
@@ -2637,7 +2625,7 @@ const_operand (op, mode)
int
stik_const_operand (op, mode)
rtx op;
- enum machine_mode mode;
+ enum machine_mode mode ATTRIBUTE_UNUSED;
{
return c4x_K_constant (op);
}
@@ -2646,7 +2634,7 @@ stik_const_operand (op, mode)
int
not_const_operand (op, mode)
rtx op;
- enum machine_mode mode;
+ enum machine_mode mode ATTRIBUTE_UNUSED;
{
return c4x_N_constant (op);
}
@@ -2660,20 +2648,22 @@ reg_operand (op, mode)
return register_operand (op, mode);
}
+
int
reg_imm_operand (op, mode)
rtx op;
- enum machine_mode mode;
+ enum machine_mode mode ATTRIBUTE_UNUSED;
{
if (REG_P (op) || CONSTANT_P (op))
return 1;
return 0;
}
+
int
not_modify_reg (op, mode)
rtx op;
- enum machine_mode mode;
+ enum machine_mode mode ATTRIBUTE_UNUSED;
{
if (REG_P (op) || CONSTANT_P (op))
return 1;
@@ -2690,12 +2680,22 @@ not_modify_reg (op, mode)
rtx op0 = XEXP (op, 0);
rtx op1 = XEXP (op, 1);
- if (!REG_P (op0))
+ if (! REG_P (op0))
return 0;
if (REG_P (op1) || GET_CODE (op1) == CONST_INT)
return 1;
}
+
+ case LO_SUM:
+ {
+ rtx op0 = XEXP (op, 0);
+
+ if (REG_P (op0) && REGNO (op0) == DP_REGNO)
+ return 1;
+ }
+ break;
+
case CONST:
case SYMBOL_REF:
case LABEL_REF:
@@ -2706,16 +2706,18 @@ not_modify_reg (op, mode)
return 0;
}
+
int
not_rc_reg (op, mode)
rtx op;
- enum machine_mode mode;
+ enum machine_mode mode ATTRIBUTE_UNUSED;
{
if (REG_P (op) && REGNO (op) == RC_REGNO)
return 0;
return 1;
}
+
/* Extended precision register R0-R1. */
int
@@ -2723,7 +2725,7 @@ r0r1_reg_operand (op, mode)
rtx op;
enum machine_mode mode;
{
- if (!register_operand (op, mode))
+ if (! register_operand (op, mode))
return 0;
if (GET_CODE (op) == SUBREG)
op = SUBREG_REG (op);
@@ -2738,7 +2740,7 @@ r2r3_reg_operand (op, mode)
rtx op;
enum machine_mode mode;
{
- if (!register_operand (op, mode))
+ if (! register_operand (op, mode))
return 0;
if (GET_CODE (op) == SUBREG)
op = SUBREG_REG (op);
@@ -2753,7 +2755,7 @@ ext_low_reg_operand (op, mode)
rtx op;
enum machine_mode mode;
{
- if (!register_operand (op, mode))
+ if (! register_operand (op, mode))
return 0;
if (GET_CODE (op) == SUBREG)
op = SUBREG_REG (op);
@@ -2768,11 +2770,11 @@ ext_reg_operand (op, mode)
rtx op;
enum machine_mode mode;
{
- if (!register_operand (op, mode))
+ if (! register_operand (op, mode))
return 0;
if (GET_CODE (op) == SUBREG)
op = SUBREG_REG (op);
- if (!REG_P (op))
+ if (! REG_P (op))
return 0;
return IS_EXT_OR_PSEUDO_REGNO (op);
}
@@ -2785,7 +2787,7 @@ std_reg_operand (op, mode)
rtx op;
enum machine_mode mode;
{
- if (!register_operand (op, mode))
+ if (! register_operand (op, mode))
return 0;
if (GET_CODE (op) == SUBREG)
op = SUBREG_REG (op);
@@ -2800,7 +2802,7 @@ addr_reg_operand (op, mode)
rtx op;
enum machine_mode mode;
{
- if (!register_operand (op, mode))
+ if (! register_operand (op, mode))
return 0;
return c4x_a_register (op);
}
@@ -2813,7 +2815,7 @@ index_reg_operand (op, mode)
rtx op;
enum machine_mode mode;
{
- if (!register_operand (op, mode))
+ if (! register_operand (op, mode))
return 0;
if (GET_CODE (op) == SUBREG)
op = SUBREG_REG (op);
@@ -2826,7 +2828,7 @@ index_reg_operand (op, mode)
int
dp_reg_operand (op, mode)
rtx op;
- enum machine_mode mode;
+ enum machine_mode mode ATTRIBUTE_UNUSED;
{
return REG_P (op) && IS_DP_OR_PSEUDO_REGNO (op);
}
@@ -2837,7 +2839,7 @@ dp_reg_operand (op, mode)
int
sp_reg_operand (op, mode)
rtx op;
- enum machine_mode mode;
+ enum machine_mode mode ATTRIBUTE_UNUSED;
{
return REG_P (op) && IS_SP_OR_PSEUDO_REGNO (op);
}
@@ -2848,28 +2850,52 @@ sp_reg_operand (op, mode)
int
st_reg_operand (op, mode)
register rtx op;
- enum machine_mode mode;
+ enum machine_mode mode ATTRIBUTE_UNUSED;
{
return REG_P (op) && IS_ST_OR_PSEUDO_REGNO (op);
}
+/* RC register. */
+
+int
+rc_reg_operand (op, mode)
+ register rtx op;
+ enum machine_mode mode ATTRIBUTE_UNUSED;
+{
+ return REG_P (op) && IS_RC_OR_PSEUDO_REGNO (op);
+}
+
+
int
-call_operand (op, mode)
+call_address_operand (op, mode)
rtx op;
- enum machine_mode mode;
+ enum machine_mode mode ATTRIBUTE_UNUSED;
+{
+ return (REG_P (op) || symbolic_address_operand (op, mode));
+}
+
+
+/* Symbolic operand. */
+
+int
+symbolic_address_operand (op, mode)
+ register rtx op;
+ enum machine_mode mode ATTRIBUTE_UNUSED;
{
- if (GET_CODE (op) != MEM)
- return 0;
- op = XEXP (op, 0);
switch (GET_CODE (op))
{
case SYMBOL_REF:
- case REG:
+ case LABEL_REF:
return 1;
+ case CONST:
+ op = XEXP (op, 0);
+ return ((GET_CODE (XEXP (op, 0)) == SYMBOL_REF
+ || GET_CODE (XEXP (op, 0)) == LABEL_REF)
+ && GET_CODE (XEXP (op, 1)) == CONST_INT);
default:
+ return 0;
}
- return 0;
}
@@ -2886,14 +2912,29 @@ src_operand (op, mode)
if (mode == VOIDmode)
mode = GET_MODE (op);
- /* We could allow certain CONST_INT values for HImode... */
if (GET_CODE (op) == CONST_INT)
- return (mode == QImode || mode == Pmode) && c4x_I_constant (op);
+ return (mode == QImode || mode == Pmode || mode == HImode)
+ && c4x_I_constant (op);
/* We don't like CONST_DOUBLE integers. */
if (GET_CODE (op) == CONST_DOUBLE)
return c4x_H_constant (op);
+ /* Disallow symbolic addresses. */
+ if (GET_CODE (op) == SYMBOL_REF
+ || GET_CODE (op) == LABEL_REF
+ || GET_CODE (op) == CONST)
+ return 0;
+
+ /* Disallow direct memory access symbolic addresses.
+ These are usually caught by the movqi expander and
+ converted to a LO_SUM. */
+ if (GET_CODE (op) == MEM
+ && ((GET_CODE (XEXP (op, 0)) == SYMBOL_REF
+ || GET_CODE (XEXP (op, 0)) == LABEL_REF
+ || GET_CODE (XEXP (op, 0)) == CONST)))
+ return 0;
+
return general_operand (op, mode);
}
@@ -2922,13 +2963,10 @@ lsrc_operand (op, mode)
if (mode != QImode && mode != Pmode)
fatal_insn ("Mode not QImode", op);
- if (REG_P (op))
- return reg_operand (op, mode);
-
if (GET_CODE (op) == CONST_INT)
return c4x_L_constant (op) || c4x_J_constant (op);
- return general_operand (op, mode);
+ return src_operand (op, mode);
}
@@ -2945,13 +2983,10 @@ tsrc_operand (op, mode)
if (mode != QImode && mode != Pmode)
fatal_insn ("Mode not QImode", op);
- if (REG_P (op))
- return reg_operand (op, mode);
-
if (GET_CODE (op) == CONST_INT)
return c4x_L_constant (op) || c4x_N_constant (op) || c4x_J_constant (op);
- return general_operand (op, mode);
+ return src_operand (op, mode);
}
@@ -3113,6 +3148,9 @@ c4x_address_conflict (op0, op1, store0, store1)
int disp0;
int disp1;
+ if (MEM_VOLATILE_P (op0) && MEM_VOLATILE_P (op1))
+ return 1;
+
c4x_S_address_parse (op0, &base0, &incdec0, &index0, &disp0);
c4x_S_address_parse (op1, &base1, &incdec1, &index1, &disp1);
@@ -3127,12 +3165,7 @@ c4x_address_conflict (op0, op1, store0, store1)
have an aliased address if both locations are not marked
volatile, it is probably safer to flag a potential conflict
if either location is volatile. */
- if (!TARGET_ALIASES)
- {
- if (MEM_VOLATILE_P (op0) && MEM_VOLATILE_P (op1))
- return 1;
- }
- else
+ if (! flag_argument_noalias)
{
if (MEM_VOLATILE_P (op0) || MEM_VOLATILE_P (op1))
return 1;
@@ -3151,17 +3184,12 @@ c4x_address_conflict (op0, op1, store0, store1)
/* It might be too confusing for GCC if we have use a base register
with a side effect and a memory reference using the same register
in parallel. */
- if (!TARGET_DEVEL && base0 == base1 && (incdec0 || incdec1))
+ if (! TARGET_DEVEL && base0 == base1 && (incdec0 || incdec1))
return 1;
- /* It is not worthwhile having parallel loads from the same address
- unless we could be sure that both locations were in internal
- memory. We allow this for peepholes (after reload has completed
- since we are going to be executing two insns to the same address
- anyhow) but steer the combiner away from doing this since it seems
- to get the wrong idea. */
- if (!store0 && !store1 && base0 == base1 && disp0 == disp1
- && !reload_completed)
+ /* We can not optimize the case where op1 and op2 refer to the same
+ address. */
+ if (base0 == base1 && disp0 == disp1 && index0 == index1)
return 1;
/* No conflict. */
@@ -3195,9 +3223,9 @@ c4x_label_conflict (insn, jump, db)
/* Validate combination of operands for parallel load/store instructions. */
int
-valid_parallel_operands_4 (operands, mode)
+valid_parallel_load_store (operands, mode)
rtx *operands;
- enum machine_mode mode;
+ enum machine_mode mode ATTRIBUTE_UNUSED;
{
rtx op0 = operands[0];
rtx op1 = operands[1];
@@ -3217,105 +3245,153 @@ valid_parallel_operands_4 (operands, mode)
par_ind_operand() operands. Thus of the 4 operands, only 2
should be REGs and the other 2 should be MEMs. */
+ /* This test prevents the multipack pass from using this pattern if
+ op0 is used as an index or base register in op2 or op3, since
+ this combination will require reloading. */
+ if (GET_CODE (op0) == REG
+ && ((GET_CODE (op2) == MEM && reg_mentioned_p (op0, XEXP (op2, 0)))
+ || (GET_CODE (op3) == MEM && reg_mentioned_p (op0, XEXP (op3, 0)))))
+ return 0;
+
/* LDI||LDI */
if (GET_CODE (op0) == REG && GET_CODE (op2) == REG)
return (REGNO (op0) != REGNO (op2))
&& GET_CODE (op1) == MEM && GET_CODE (op3) == MEM
- && !c4x_address_conflict (op1, op3, 0, 0);
+ && ! c4x_address_conflict (op1, op3, 0, 0);
/* STI||STI */
if (GET_CODE (op1) == REG && GET_CODE (op3) == REG)
return GET_CODE (op0) == MEM && GET_CODE (op2) == MEM
- && !c4x_address_conflict (op0, op2, 1, 1);
+ && ! c4x_address_conflict (op0, op2, 1, 1);
/* LDI||STI */
if (GET_CODE (op0) == REG && GET_CODE (op3) == REG)
return GET_CODE (op1) == MEM && GET_CODE (op2) == MEM
- && !c4x_address_conflict (op1, op2, 0, 1);
+ && ! c4x_address_conflict (op1, op2, 0, 1);
/* STI||LDI */
if (GET_CODE (op1) == REG && GET_CODE (op2) == REG)
return GET_CODE (op0) == MEM && GET_CODE (op3) == MEM
- && !c4x_address_conflict (op0, op3, 1, 0);
+ && ! c4x_address_conflict (op0, op3, 1, 0);
return 0;
}
-/* We only use this to check operands 1 and 2 since these may be
- commutative. It will need extending for the C32 opcodes. */
+
+int
+valid_parallel_operands_4 (operands, mode)
+ rtx *operands;
+ enum machine_mode mode ATTRIBUTE_UNUSED;
+{
+ rtx op0 = operands[0];
+ rtx op2 = operands[2];
+
+ if (GET_CODE (op0) == SUBREG)
+ op0 = SUBREG_REG (op0);
+ if (GET_CODE (op2) == SUBREG)
+ op2 = SUBREG_REG (op2);
+
+ /* This test prevents the multipack pass from using this pattern if
+ op0 is used as an index or base register in op2, since this combination
+ will require reloading. */
+ if (GET_CODE (op0) == REG
+ && GET_CODE (op2) == MEM
+ && reg_mentioned_p (op0, XEXP (op2, 0)))
+ return 0;
+
+ return 1;
+}
+
+
int
valid_parallel_operands_5 (operands, mode)
rtx *operands;
- enum machine_mode mode;
+ enum machine_mode mode ATTRIBUTE_UNUSED;
{
int regs = 0;
- rtx op0 = operands[1];
- rtx op1 = operands[2];
+ rtx op0 = operands[0];
+ rtx op1 = operands[1];
+ rtx op2 = operands[2];
+ rtx op3 = operands[3];
if (GET_CODE (op0) == SUBREG)
op0 = SUBREG_REG (op0);
if (GET_CODE (op1) == SUBREG)
op1 = SUBREG_REG (op1);
+ if (GET_CODE (op2) == SUBREG)
+ op2 = SUBREG_REG (op2);
/* The patterns should only allow ext_low_reg_operand() or
- par_ind_operand() operands. */
-
- if (GET_CODE (op0) == REG)
- regs++;
+ par_ind_operand() operands. Operands 1 and 2 may be commutative
+ but only one of them can be a register. */
if (GET_CODE (op1) == REG)
regs++;
+ if (GET_CODE (op2) == REG)
+ regs++;
+
+ if (regs != 1)
+ return 0;
- return regs == 1;
+ /* This test prevents the multipack pass from using this pattern if
+ op0 is used as an index or base register in op3, since this combination
+ will require reloading. */
+ if (GET_CODE (op0) == REG
+ && GET_CODE (op3) == MEM
+ && reg_mentioned_p (op0, XEXP (op3, 0)))
+ return 0;
+
+ return 1;
}
int
valid_parallel_operands_6 (operands, mode)
rtx *operands;
- enum machine_mode mode;
+ enum machine_mode mode ATTRIBUTE_UNUSED;
{
int regs = 0;
- rtx op0 = operands[1];
- rtx op1 = operands[2];
- rtx op2 = operands[4];
- rtx op3 = operands[5];
+ rtx op0 = operands[0];
+ rtx op1 = operands[1];
+ rtx op2 = operands[2];
+ rtx op4 = operands[4];
+ rtx op5 = operands[5];
- if (GET_CODE (op0) == SUBREG)
- op0 = SUBREG_REG (op0);
if (GET_CODE (op1) == SUBREG)
op1 = SUBREG_REG (op1);
if (GET_CODE (op2) == SUBREG)
op2 = SUBREG_REG (op2);
- if (GET_CODE (op3) == SUBREG)
- op3 = SUBREG_REG (op3);
+ if (GET_CODE (op4) == SUBREG)
+ op4 = SUBREG_REG (op4);
+ if (GET_CODE (op5) == SUBREG)
+ op5 = SUBREG_REG (op5);
/* The patterns should only allow ext_low_reg_operand() or
par_ind_operand() operands. Thus of the 4 input operands, only 2
should be REGs and the other 2 should be MEMs. */
- if (GET_CODE (op0) == REG)
- regs++;
if (GET_CODE (op1) == REG)
regs++;
if (GET_CODE (op2) == REG)
regs++;
- if (GET_CODE (op3) == REG)
+ if (GET_CODE (op4) == REG)
+ regs++;
+ if (GET_CODE (op5) == REG)
regs++;
/* The new C30/C40 silicon dies allow 3 regs of the 4 input operands.
Perhaps we should count the MEMs as well? */
- return regs == 2;
-}
+ if (regs != 2)
+ return 0;
+ /* This test prevents the multipack pass from using this pattern if
+ op0 is used as an index or base register in op4 or op5, since
+ this combination will require reloading. */
+ if (GET_CODE (op0) == REG
+ && ((GET_CODE (op4) == MEM && reg_mentioned_p (op0, XEXP (op4, 0)))
+ || (GET_CODE (op5) == MEM && reg_mentioned_p (op0, XEXP (op5, 0)))))
+ return 0;
-int
-legitimize_parallel_operands_6 (operands, mode)
- rtx *operands;
- enum machine_mode mode;
-{
- /* It's gonna be hard to legitimize operands for a parallel
- instruction... TODO... */
- return valid_parallel_operands_6 (operands, mode);
+ return 1;
}
@@ -3378,7 +3454,7 @@ c4x_valid_operands (code, operands, mode, force)
break;
case CONST_DOUBLE:
- if (!c4x_H_constant (op2))
+ if (! c4x_H_constant (op2))
return 0;
break;
@@ -3392,13 +3468,13 @@ c4x_valid_operands (code, operands, mode, force)
break;
default:
- fatal ("c4x_valid_operands: Internal error");
+ fatal_insn ("c4x_valid_operands: Internal error", op2);
break;
}
/* Check that we have a valid destination register for a two operand
instruction. */
- return !force || code == COMPARE || REGNO (op1) == REGNO (operands[0]);
+ return ! force || code == COMPARE || REGNO (op1) == REGNO (operands[0]);
}
/* We assume MINUS is commutative since the subtract patterns
@@ -3418,7 +3494,7 @@ c4x_valid_operands (code, operands, mode, force)
break;
case CONST_DOUBLE:
- if (!c4x_H_constant (op1))
+ if (! c4x_H_constant (op1))
return 0;
break;
@@ -3438,7 +3514,7 @@ c4x_valid_operands (code, operands, mode, force)
/* Check that we have a valid destination register for a two operand
instruction. */
- return !force || REGNO (op1) == REGNO (operands[0]);
+ return ! force || REGNO (op1) == REGNO (operands[0]);
}
@@ -3456,7 +3532,7 @@ int valid_operands (code, operands, mode)
operands for an insn when not optimizing. The problem only rarely
occurs, for example with the C-torture program DFcmp.c */
- return !optimize || c4x_valid_operands (code, operands, mode, 0);
+ return ! optimize || c4x_valid_operands (code, operands, mode, 0);
}
@@ -3483,17 +3559,17 @@ legitimize_operands (code, operands, mode)
the cost mechanism doesn't allow us to look at the other
operand to decide whether the constant is expensive. */
- if (!reload_in_progress
+ if (! reload_in_progress
&& TARGET_HOIST
&& optimize > 0
&& ((GET_CODE (operands[1]) == CONST_INT
- && !c4x_J_constant (operands[1])
+ && ! c4x_J_constant (operands[1])
&& INTVAL (operands[1]) != 0)
|| GET_CODE (operands[1]) == CONST_DOUBLE))
operands[1] = force_reg (mode, operands[1]);
- if (!reload_in_progress
- && !c4x_valid_operands (code, operands, mode, 0))
+ if (! reload_in_progress
+ && ! c4x_valid_operands (code, operands, mode, 0))
operands[0] = force_reg (mode, operands[0]);
return 1;
}
@@ -3501,11 +3577,11 @@ legitimize_operands (code, operands, mode)
/* We cannot do this for ADDI/SUBI insns since we will
defeat the flow pass from finding autoincrement addressing
opportunities. */
- if (!reload_in_progress
- && !((code == PLUS || code == MINUS) && mode == Pmode)
+ if (! reload_in_progress
+ && ! ((code == PLUS || code == MINUS) && mode == Pmode)
&& (TARGET_HOIST && optimize > 1
&& ((GET_CODE (operands[2]) == CONST_INT
- && !c4x_J_constant (operands[2])
+ && ! c4x_J_constant (operands[2])
&& INTVAL (operands[2]) != 0)
|| GET_CODE (operands[2]) == CONST_DOUBLE)))
operands[2] = force_reg (mode, operands[2]);
@@ -3520,8 +3596,8 @@ legitimize_operands (code, operands, mode)
Note that expand_binops will not try to load an expensive constant
into a register if it is used within a loop for a shift insn. */
- if (!reload_in_progress
- && !c4x_valid_operands (code, operands, mode, TARGET_FORCE))
+ if (! reload_in_progress
+ && ! c4x_valid_operands (code, operands, mode, TARGET_FORCE))
{
/* If the operand combination is invalid, we force operand1 into a
register, preventing reload from having doing to do this at a
@@ -3535,7 +3611,7 @@ legitimize_operands (code, operands, mode)
else
{
/* Just in case... */
- if (!c4x_valid_operands (code, operands, mode, 0))
+ if (! c4x_valid_operands (code, operands, mode, 0))
operands[2] = force_reg (mode, operands[2]);
}
}
@@ -3544,7 +3620,7 @@ legitimize_operands (code, operands, mode)
a positive count, so we emit a NEG. */
if ((code == ASHIFTRT || code == LSHIFTRT)
&& (GET_CODE (operands[2]) != CONST_INT))
- operands[2] = gen_rtx (NEG, mode, negate_rtx (mode, operands[2]));
+ operands[2] = gen_rtx_NEG (mode, negate_rtx (mode, operands[2]));
return 1;
}
@@ -3873,16 +3949,19 @@ c4x_operand_subword (op, i, validate_address, mode)
{
enum rtx_code code = GET_CODE (XEXP (op, 0));
enum machine_mode mode = GET_MODE (XEXP (op, 0));
+ enum machine_mode submode;
+
+ submode = mode;
+ if (mode == HImode)
+ submode = QImode;
+ else if (mode == HFmode)
+ submode = QFmode;
switch (code)
{
case POST_INC:
case PRE_INC:
- if (mode == HImode)
- mode = QImode;
- else if (mode == HFmode)
- mode = QFmode;
- return gen_rtx (MEM, mode, XEXP (op, 0));
+ return gen_rtx_MEM (submode, XEXP (op, 0));
case POST_DEC:
case PRE_DEC:
@@ -3892,6 +3971,23 @@ c4x_operand_subword (op, i, validate_address, mode)
e.g., *p-- => *(p-=2); *(p+1). */
fatal_insn ("c4x_operand_subword: invalid autoincrement", op);
+ case SYMBOL_REF:
+ case LABEL_REF:
+ case CONST:
+ case CONST_INT:
+ fatal_insn ("c4x_operand_subword: invalid address", op);
+
+ /* Even though offsettable_address_p considers (MEM
+ (LO_SUM)) to be offsettable, it is not safe if the
+ address is at the end of the data page since we also have
+ to fix up the associated high PART. In this case where
+ we are trying to split a HImode or HFmode memory
+ reference, we would have to emit another insn to reload a
+ new HIGH value. It's easier to disable LO_SUM memory references
+ in HImode or HFmode and we probably get better code. */
+ case LO_SUM:
+ fatal_insn ("c4x_operand_subword: address not offsettable", op);
+
default:
break;
}
@@ -3921,7 +4017,7 @@ c4x_operand_subword (op, i, validate_address, mode)
int
c4x_handle_pragma (p_getc, p_ungetc, pname)
int (* p_getc) PROTO ((void));
- void (* p_ungetc) PROTO ((int));
+ void (* p_ungetc) PROTO ((int)) ATTRIBUTE_UNUSED;
char *pname;
{
int i;
@@ -3939,7 +4035,7 @@ c4x_handle_pragma (p_getc, p_ungetc, pname)
c = p_getc ();
while (c == ' ' || c == '\t') c = p_getc ();
- if (!(isalpha(c) || c == '_' || c == '$' || c == '@'))
+ if (! (isalpha(c) || c == '_' || c == '$' || c == '@'))
return 0;
i = 0;
@@ -3987,7 +4083,6 @@ c4x_handle_pragma (p_getc, p_ungetc, pname)
}
name[i] = 0;
sect = build_string (i, name);
- TREE_TYPE (sect) = char_array_type_node;
free (name);
sect = build_tree_list (NULL_TREE, sect);
@@ -4043,8 +4138,8 @@ c4x_check_attribute(attrib, list, decl, attributes)
tree list, decl, *attributes;
{
while (list != NULL_TREE
- && IDENTIFIER_POINTER (TREE_PURPOSE (list)) !=
- IDENTIFIER_POINTER (DECL_NAME (decl)))
+ && IDENTIFIER_POINTER (TREE_PURPOSE (list))
+ != IDENTIFIER_POINTER (DECL_NAME (decl)))
list = TREE_CHAIN(list);
if (list)
*attributes = chainon (*attributes,
@@ -4083,9 +4178,9 @@ c4x_set_default_attributes(decl, attributes)
int
c4x_valid_type_attribute_p (type, attributes, identifier, args)
tree type;
- tree attributes;
+ tree attributes ATTRIBUTE_UNUSED;
tree identifier;
- tree args;
+ tree args ATTRIBUTE_UNUSED;
{
if (TREE_CODE (type) != FUNCTION_TYPE)
return 0;
@@ -4103,1266 +4198,7 @@ c4x_valid_type_attribute_p (type, attributes, identifier, args)
}
-/* This is a modified version of modified_between_p that doesn't give
- up if a changing MEM is found. It checks all insns between START
- and END to see if any registers mentioned in X are set. */
-static int
-c4x_modified_between_p (x, start, end)
- rtx x;
- rtx start, end;
-{
- enum rtx_code code = GET_CODE (x);
- char *fmt;
- int i, j;
-
- switch (code)
- {
- case CONST_INT:
- case CONST_DOUBLE:
- case CONST:
- case SYMBOL_REF:
- case LABEL_REF:
- return 0;
-
- case PC:
- case CC0:
- return 1;
-
- case MEM:
- break;
-
- case REG:
- return reg_set_between_p (x, start, end);
-
- default:
- break;
- }
-
- fmt = GET_RTX_FORMAT (code);
- for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
- {
- if (fmt[i] == 'e' && c4x_modified_between_p (XEXP (x, i), start, end))
- return 1;
-
- if (fmt[i] == 'E')
- for (j = XVECLEN (x, i) - 1; j >= 0; j--)
- if (c4x_modified_between_p (XVECEXP (x, i, j), start, end))
- return 1;
- }
-
- return 0;
-}
-
-/* Return 1 if rtx X references memory that is changing. */
-static int
-c4x_mem_ref_p (x)
- rtx x;
-{
- enum rtx_code code = GET_CODE (x);
- char *fmt;
- int i, j;
-
- if (code == MEM && !RTX_UNCHANGING_P (x))
- return 1;
-
- fmt = GET_RTX_FORMAT (code);
- for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
- {
- if (fmt[i] == 'e' && c4x_mem_ref_p (XEXP (x, i)))
- return 1;
-
- if (fmt[i] == 'E')
- for (j = XVECLEN (x, i) - 1; j >= 0; j--)
- if (c4x_mem_ref_p (XVECEXP (x, i, j)))
- return 1;
- }
-
- return 0;
-}
-
-/* Return 1 if rtx X sets or clobbers memory. */
-static int
-c4x_mem_set_p (x)
- rtx x;
-{
- enum rtx_code code = GET_CODE (x);
- char *fmt;
- int i, j;
-
- if ((code == SET || code == CLOBBER)
- && (GET_CODE (SET_DEST (x)) == MEM))
- return 1;
-
- fmt = GET_RTX_FORMAT (code);
- for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
- {
- if (fmt[i] == 'e' && c4x_mem_set_p (XEXP (x, i)))
- return 1;
-
- if (fmt[i] == 'E')
- for (j = XVECLEN (x, i) - 1; j >= 0; j--)
- if (c4x_mem_set_p (XVECEXP (x, i, j)))
- return 1;
- }
-
- return 0;
-}
-
-
-/* Return 1 if any insns between START and END (exclusive) sets
- or clobbers memory. */
-static int
-c4x_mem_modified_between_p (start, end)
- rtx start, end;
-{
- rtx insn;
-
- if (start == end)
- return 0;
-
- for (insn = NEXT_INSN (start); insn != end; insn = NEXT_INSN (insn))
- if (GET_RTX_CLASS (GET_CODE (insn)) == 'i'
- && c4x_mem_set_p (PATTERN (insn)))
- return 1;
- return 0;
-}
-
-
-/* Returns 1 if INSN can be moved past all the insns between START and
- END exclusive. If TARGET_ALIASES is not set and a memory store is
- detected, then 0 is returned. */
-static int
-c4x_insn_moveable_p (insn, start, end)
- rtx insn;
- rtx start, end;
-{
- if (start == end)
- return 1;
-
- /* We can't use modified_between_p since this will
- return 1 if set1 contains a MEM. */
- if (c4x_modified_between_p (insn, start, end))
- return 0;
-
- return 1;
-}
-
-
-/* See if the insns INSN1 and INSN2 can be packed into a PARALLEL.
- Return 0 if the insns cannot be packed or the rtx of the packed
- insn (with clobbers added as necessary). If DEPEND is non zero,
- then the destination register of INSN1 must be used by INSN2. */
-static rtx
-c4x_parallel_pack (insn1, insn2, depend)
- rtx insn1;
- rtx insn2;
- int depend;
-{
- rtx set1;
- rtx set2;
- rtx pack;
- enum machine_mode mode1;
- enum machine_mode mode2;
- int num_clobbers;
- int insn_code_number;
-
- /* We could generalise things to not just rely on single sets. */
- if (!(set1 = single_set (insn1))
- || !(set2 = single_set (insn2)))
- return 0;
-
- mode1 = GET_MODE (SET_DEST (set1));
- mode2 = GET_MODE (SET_DEST (set2));
- if (mode1 != mode2)
- return 0;
-
- if (depend)
- {
- rtx dst1;
-
- /* Require insn2 to be dependent upon the result of insn1. */
- dst1 = SET_DEST (set1);
-
- if (!REG_P (dst1))
- return 0;
-
- if (!reg_mentioned_p (dst1, set2))
- return 0;
-
- /* The dependent register must die in insn2 since a parallel
- insn will generate a new value. */
- if (!find_regno_note (insn2, REG_DEAD, REGNO (dst1)))
- return 0;
- }
-
- pack = gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2, set1, set2));
- num_clobbers = 0;
- if ((insn_code_number = recog (pack, pack, &num_clobbers)) < 0)
- return 0;
-
- if (num_clobbers != 0)
- {
- rtx newpack;
- int i;
-
- newpack = gen_rtx (PARALLEL, VOIDmode,
- gen_rtvec (GET_CODE (pack) == PARALLEL
- ? XVECLEN (pack, 0) + num_clobbers
- : num_clobbers + 1));
-
- if (GET_CODE (pack) == PARALLEL)
- for (i = 0; i < XVECLEN (pack, 0); i++)
- XVECEXP (newpack, 0, i) = XVECEXP (pack, 0, i);
- else
- XVECEXP (newpack, 0, 0) = pack;
-
- add_clobbers (newpack, insn_code_number);
- pack = newpack;
- }
-
- return pack;
-}
-
-
-static rtx
-c4x_parallel_find (insn1, loop_end, depend, insn2)
- rtx insn1;
- rtx loop_end;
- int depend;
- rtx *insn2;
-{
- rtx insn;
- rtx pack;
-
- /* We could use the logical links if depend is non zero? */
-
- for (insn = NEXT_INSN (insn1); insn != loop_end; insn = NEXT_INSN(insn))
- {
- switch (GET_CODE (insn))
- {
- default:
- case JUMP_INSN:
- case CALL_INSN:
- case NOTE:
- break;
-
- case INSN:
- if (!(pack = c4x_parallel_pack (insn1, insn, depend)))
- break;
-
- /* What if insn1 or insn2 sets cc and is required by another
- insn? */
-
-#if 0
- /* Check that nothing between insn1 and insn will spoil the
- show. */
- if (NEXT_INSN (insn1) != insn
- && c4x_modified_between_p (insn, NEXT_INSN (insn1), insn))
- return 0;
-#else
- /* This will do in the interim. If the insns between
- insn1 and insn are harmless, we can move things around
- if we're careful. */
- if (next_nonnote_insn (insn1) != insn)
- return 0;
-#endif
-
- /* Do some checks here... */
- *insn2 = insn;
- return pack;
- }
- }
- return 0;
-}
-
-
-/* Update the register info for reg REG found in the basic block BB,
- where SET is 1 if the register is being set. */
-static void
-c4x_update_info_reg (reg, set, bb)
- rtx reg;
- int set;
- int bb;
-{
- int regno;
-
- if (!REG_P (reg))
- fatal_insn ("Expecting register rtx", reg);
-
- regno = REGNO (reg);
-
- /* REGNO_FIRST_UID and REGNO_LAST_UID don't need setting. */
-
- SET_REGNO_REG_SET (basic_block_live_at_start[bb], regno);
- REG_BASIC_BLOCK (regno) = REG_BLOCK_GLOBAL;
- if (set)
- REG_N_SETS (regno)++;
- else
- REG_N_REFS (regno)++;
-}
-
-
-/* Update the register info for all the regs in X found in the basic
- block BB. */
-static void
-c4x_update_info_regs(x, bb)
- rtx x;
- int bb;
-{
- enum rtx_code code;
- char *fmt;
- int i, j;
-
- if (!x)
- return;
-
- code = GET_CODE (x);
- switch (code)
- {
- case CLOBBER:
-#if 0
- if (REG_P (SET_DEST (x)))
- return;
- break;
-#endif
-
- case SET:
- if (REG_P (SET_DEST (x)))
- c4x_update_info_reg (SET_DEST (x), 1, bb);
- else
- c4x_update_info_regs (SET_DEST (x), bb);
-
- if (code == SET)
- c4x_update_info_regs (SET_SRC (x), bb);
- return;
-
- case REG:
- c4x_update_info_reg (x, 0, bb);
- return;
-
- default:
- break;
- }
-
- fmt = GET_RTX_FORMAT (code);
- for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
- {
- if (fmt[i] == 'e')
- c4x_update_info_regs (XEXP (x, i), bb);
- else if (fmt[i] == 'E')
- for (j = XVECLEN (x, i) - 1; j >= 0; j--)
- c4x_update_info_regs (XVECEXP (x, i, j), bb);
- }
-}
-
-
-static void
-c4x_copy_insn_after(insn, prev, bb)
- rtx insn;
- rtx prev;
- int bb;
-{
- rtx note;
- rtx new;
-
- emit_insn_after (copy_rtx (PATTERN (insn)), prev);
-
- new = NEXT_INSN (prev);
-
- /* Copy the REG_NOTES from insn to the new insn. */
- for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
- REG_NOTES (new) = gen_rtx (GET_CODE (note),
- REG_NOTE_KIND (note),
- XEXP (note, 0),
- REG_NOTES (new));
-
- /* Handle all the registers within insn and update the reg info. */
- c4x_update_info_regs (PATTERN (insn), bb);
-}
-
-
-static void
-c4x_copy_insns_after(start, end, pprev, bb)
- rtx start;
- rtx end;
- rtx *pprev;
- int bb;
-{
- rtx insn;
-
- for (insn = start; insn != NEXT_INSN (end); insn = NEXT_INSN(insn))
- {
- switch (GET_CODE (insn))
- {
- case CALL_INSN:
- /* We could allow a libcall with no side effects??? */
- fatal_insn("Repeat block loop contains a call", insn);
- break;
-
- case INSN:
- c4x_copy_insn_after(insn, *pprev, bb - 1);
- *pprev = NEXT_INSN (*pprev);
- break;
-
- default:
- break;
- }
- }
-}
-
-
-/* Merge the notes of insn2 with the notes of insn. */
-static void
-c4x_merge_notes(insn, insn2)
- rtx insn;
- rtx insn2;
-{
- rtx note;
-
- for (note = REG_NOTES (insn2); note; note = XEXP (note, 1))
- {
- rtx link;
-
- for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
- if (REG_NOTE_KIND (note) == REG_NOTE_KIND (link)
- && XEXP (note, 0) == XEXP (link, 0))
- remove_note (insn, note);
- }
- for (note = REG_NOTES (insn2); note; note = XEXP (note, 1))
- REG_NOTES (insn) = gen_rtx (GET_CODE (note),
- REG_NOTE_KIND (note),
- XEXP (note, 0),
- REG_NOTES (insn));
-}
-
-
-/* This pass must update information that subsequent passes expect to be
- correct. Namely: reg_n_refs, reg_n_sets, reg_n_deaths,
- reg_n_calls_crossed, and reg_live_length. Also, basic_block_head,
- basic_block_end. */
-
-static int
-c4x_parallel_process (loop_start, loop_end)
- rtx loop_start;
- rtx loop_end;
-{
- rtx insn;
- rtx insn2;
- rtx pack;
- rtx hoist;
- rtx sink;
- rtx loop_count;
- rtx loop_count_set;
- rtx end_label;
- int num_packs;
- int bb;
-
- /* The loop must have a calculable number of iterations
- since we need to reduce the loop count by one.
-
- For now, only process repeat block loops, since we can tell that
- these have a calculable number of iterations.
-
- The loop count must be at least 2? */
-
- loop_count = NEXT_INSN (loop_start);
-
- /* Skip past CLOBBER and USE and deleted insn. This is from flow. */
- for (;;)
- {
- if (GET_CODE (loop_count) == INSN)
- {
- rtx x = PATTERN (loop_count);
- if (GET_CODE (x) != USE && GET_CODE (x) != CLOBBER)
- break;
- }
- else if (GET_CODE (loop_count) == NOTE)
- {
- if (! INSN_DELETED_P (loop_count))
- break;
- }
- else
- break;
- loop_count = NEXT_INSN (loop_count);
- }
-
- if (!(loop_count_set = single_set (loop_count)))
- return 0;
-
- if (!REG_P (SET_DEST (loop_count_set))
- || REGNO (SET_DEST (loop_count_set)) != RC_REGNO)
- return 0;
-
- /* Determine places to hoist and sink insns out of the loop. We
- won't have to update basic_block_head if we move things after
- loop_count. */
-
- hoist = loop_count;
- end_label = PREV_INSN (loop_end);
-
- /* Skip past filler insn if present. */
- if (GET_CODE (end_label) != CODE_LABEL)
- end_label = PREV_INSN (end_label);
-
- /* Skip past CLOBBER, USE, and deleted insns inserted by the flow pass. */
- for (;;)
- {
- if (GET_CODE (end_label) == INSN)
- {
- rtx x = PATTERN (end_label);
- if (GET_CODE (x) != USE && GET_CODE (x) != CLOBBER)
- break;
- }
- else if (GET_CODE (end_label) == NOTE)
- {
- if (! INSN_DELETED_P (end_label))
- break;
- }
- else
- break;
- end_label = PREV_INSN (end_label);
- }
-
- if (GET_CODE (end_label) != CODE_LABEL)
- return 0;
-
- sink = end_label;
-
- /* There must be an easier way to work out which basic block we are
- in. */
- for (bb = 0; bb < n_basic_blocks; bb++)
- if (basic_block_head[bb] == sink)
- break;
-
- if (bb >= n_basic_blocks)
- fatal_insn("Cannot find basic block for insn", sink);
-
- /* Skip to label at top of loop. */
- for (; GET_CODE (loop_start) != CODE_LABEL;
- loop_start = NEXT_INSN(loop_start));
-
- num_packs = 0;
- for (insn = loop_start; insn != loop_end; insn = NEXT_INSN(insn))
- {
- switch (GET_CODE (insn))
- {
- default:
- case JUMP_INSN:
- case CALL_INSN:
- case NOTE:
- break;
-
- case INSN:
-
- /* Look for potential insns to combine where the second one
- is dependent upon the first. We could have another pass
- that tries combining independent insns but that is not so
- important. We could do this afterwards as a more generic
- peepholer. */
-
- if ((pack = c4x_parallel_find(insn, loop_end, 1, &insn2)))
- {
- rtx set1;
- rtx set2;
- rtx note;
- rtx seq_start;
-
- set1 = single_set (insn);
- set2 = single_set (insn2);
-
- /* We need to hoist a copy of insn1 out of the loop and
- to sink a copy insn2 out of the loop. We can avoid
- the latter if the destination of insn2 is used
- by a following insn within the loop.
-
- We cannot hoist insn1 out of the loop if any of the
- preceeding insns within the loop modifies the destination
- of insn1 or modifies any of the operands of insn1. */
-
- /* If the user has flagged that there are potential aliases,
- then we can't move the insn if it references memory
- past any insns that modify memory. */
- if (TARGET_ALIASES
- && c4x_mem_ref_p (PATTERN (insn))
- && c4x_mem_modified_between_p (loop_start, loop_end))
- break;
-
- /* None of the registers used in insn can be modified by
- any of the insns from the start of the loop until insn. */
- if (!c4x_insn_moveable_p (set1, loop_start, insn))
- break;
-
- /* None of the registers used in insn can be modified by
- any of the insns after insn2 until the end of the
- loop, especially the result which needs to be saved
- for the next iteration. */
- if (!c4x_insn_moveable_p (set1, insn2, loop_end))
- break;
-
- /* We need to hoist all the insns from the loop top
- to and including insn. */
- c4x_copy_insns_after(NEXT_INSN (loop_start), insn, &hoist, bb);
-
- /* We need to sink all the insns after insn to
- loop_end. */
- c4x_copy_insns_after (NEXT_INSN (insn), PREV_INSN(end_label),
- &sink, bb + 1);
-
- /* Change insn to the new parallel insn, retaining the notes
- of the old insn. */
- if (!validate_change (insn, &PATTERN (insn), pack, 0))
- fatal_insn("Cannot replace insn with parallel insn", pack);
-
- /* Copy the REG_NOTES from insn2 to the new insn
- avoiding duplicates. */
- c4x_merge_notes (insn, insn2);
-
- delete_insn (insn2);
-
- /* The destination register of insn1 no longer dies in
- this composite insn. Don't use remove_death since that
- alters REG_N_DEATHS. The REG_DEAD note has just been
- moved. */
- note = find_regno_note (insn, REG_DEAD, REGNO (SET_DEST (set1)));
- if (note)
- remove_note (insn, note);
-
- /* Do we have to modify the LOG_LINKS? */
-
- /* We need to decrement the loop count. We probably
- should test if RC is negative and branch to end label
- if so. */
- if (GET_CODE (SET_SRC (loop_count_set)) == CONST_INT)
- {
- /* The loop count must be more than 1 surely? */
- SET_SRC (loop_count_set)
- = gen_rtx (CONST_INT, VOIDmode,
- INTVAL (SET_SRC (loop_count_set)) -1);
- }
- else if (GET_CODE (SET_SRC (loop_count_set)) == PLUS
- && GET_CODE (XEXP (SET_SRC (loop_count_set), 1))
- == CONST_INT)
- {
- XEXP (SET_SRC (loop_count_set), 1)
- = gen_rtx (CONST_INT, VOIDmode,
- INTVAL (XEXP (SET_SRC (loop_count_set), 1))
- - 1);
- }
- else
- {
- start_sequence ();
- expand_binop (QImode, sub_optab,
- gen_rtx (REG, QImode, RC_REGNO),
- gen_rtx (CONST_INT, VOIDmode, 1),
- gen_rtx (REG, QImode, RC_REGNO),
- 1, OPTAB_DIRECT);
- seq_start = get_insns ();
- end_sequence ();
- emit_insns_after (seq_start, loop_count);
-
- /* Check this. What if we emit more than one insn?
- Can we emit more than one insn? */
- REG_NOTES (seq_start)
- = gen_rtx (EXPR_LIST, REG_UNUSED,
- gen_rtx (REG, QImode, RC_REGNO),
- REG_NOTES (seq_start));
- }
-
- start_sequence ();
- emit_cmp_insn (gen_rtx (REG, QImode, RC_REGNO),
- const0_rtx, LT, NULL_RTX, QImode, 0, 0);
- emit_jump_insn (gen_blt (end_label));
- seq_start = get_insns ();
- end_sequence ();
- emit_insns_after (seq_start, hoist);
-
- /* This is a bit of a hack... */
- REG_NOTES (NEXT_INSN (seq_start))
- = gen_rtx (EXPR_LIST, REG_DEAD,
- gen_rtx (REG, QImode, RC_REGNO),
- REG_NOTES (NEXT_INSN (seq_start)));
-
- if (TARGET_DEVEL)
- debug_rtx(insn);
-
- num_packs ++;
-
-#if 1
- /* If we want to pack more than one parallel insn
- we will have to tag which insns have been
- hoisted/sunk/paired. We might need a recursive approach. */
-
- return num_packs;
-#endif
- }
- break;
- }
- }
- return num_packs;
-}
-
-
-static void
-c4x_combine_parallel_independent (insns)
- rtx insns;
-{
- /* Combine independent insns like
- (set (mem (reg 0)) (reg 1))
- (set (reg 2) (mem (reg 3)))
- where (reg 1) != (reg 2) unless there is a REG_DEAD note
- on the first insn. */
-
-}
-
-static void
-c4x_combine_parallel_dependent (insns)
- rtx insns;
-{
- rtx insn;
- rtx loop_start;
- rtx loop_end;
- int num_jumps;
- int num_insns;
-
- /* Find the innermost loop and check that it is unjumped. */
- loop_start = NULL_RTX;
- num_jumps = 0;
- for (insn = insns; insn; insn = NEXT_INSN(insn))
- {
- switch (GET_CODE (insn))
- {
- case INSN:
- num_insns++;
- break;
-
- case CALL_INSN:
- /* We could allow a libcall with no side effects??? */
- case JUMP_INSN:
- num_jumps++;
- break;
-
- case NOTE:
- switch (NOTE_LINE_NUMBER (insn))
- {
- case NOTE_INSN_LOOP_BEG:
- loop_start = insn;
- num_jumps = 0;
- num_insns = 0;
- break;
-
- case NOTE_INSN_LOOP_CONT:
- if (!loop_start)
- break;
- /* We can't handle a loop with jumps or calls.
- If there are too many insns, we are unlikely
- to be able to find a suitable case for optimisation.
- The maximum number of insns may require tweaking. */
- if (!num_jumps && num_insns < 20)
- {
- /* Skip to end of loop. */
- loop_end = NULL_RTX;
- for (; insn; insn = NEXT_INSN(insn))
- if (GET_CODE (insn) == NOTE
- && NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_END)
- break;
- loop_end = insn;
- if (!loop_end)
- fatal_insn("Could not find note at end of loop",
- loop_start);
- c4x_parallel_process(loop_start, loop_end);
- }
- loop_start = NULL_RTX;
- break;
-
- default:
- break;
- }
- default:
- break;
- }
- }
-}
-
-
-void
-c4x_combine_parallel (insns)
- rtx insns;
-{
- /* Only let people who know how to shoot themselves in the foot do so! */
- if (!TARGET_PARALLEL_PACK)
- return;
-
- c4x_combine_parallel_dependent (insns);
-
- c4x_combine_parallel_independent (insns);
-}
-
-
-/* True if INSN is between START and END. If END precedes START
- something has gone awry. */
-
-static int
-c4x_rptb_in_range (insn, start, end)
- rtx insn, start, end;
-{
- rtx this;
-
- for (this = start; ; this = NEXT_INSN (this))
- {
- if (this == insn)
- return 1;
- if (this == end)
- return 0;
- if (this == NULL_RTX)
- fatal_insn ("c4x_rptb_in_range: Repeat block error", start);
- }
-}
-
-
-/* Returns true if there are no jumps crossing the loop boundary and
- no calls anywhere. */
-
-int
-c4x_rptb_unjumped_loop_p (loop_start, loop_end)
- rtx loop_start, loop_end;
-{
- rtx insn;
- rtx continue_label = NULL_RTX;
- rtx continue_note = NULL_RTX; /* Loop continue note if there is one. */
-
- /* Scan loop backwards. */
- for (insn = PREV_INSN (loop_end); insn && insn != loop_start;
- insn = PREV_INSN (insn))
- {
- switch (GET_CODE (insn))
- {
- case JUMP_INSN:
- {
- rtx jump_label = JUMP_LABEL (insn);
-
- /* We don't like jumps out of the loop. We also look
- for jumps to the end of loop, say from a continue
- statement. */
- if (continue_note
- && jump_label == next_nonnote_insn (continue_note))
- continue_label = jump_label;
- else if (!c4x_rptb_in_range (jump_label, loop_start,
- continue_note ? continue_note :
- loop_end))
- return 0;
- }
- /* Fall through */
-
- case INSN:
- if (0 && volatile_refs_p (PATTERN (insn)))
- {
- c4x_dump (loop_dump_stream,
- "Repeat block: Volatile memory ref within loop\n");
- return 0;
- }
-
- /* The C4x movstrqi_large pattern clobbers RC, RE, RS.
- This should be generalised to check for insns that use
- these registers within the loop. */
- if (recog_memoized (insn) == CODE_FOR_movstrqi_large)
- {
- c4x_dump (loop_dump_stream,
- "Repeat block: Memory copy within loop\n");
- return 0;
- }
- break;
-
- /* It is not worthwhile preserving the zero overhead loop
- context across calls. */
- case CALL_INSN:
- /* We could allow a libcall with no side effects??? */
- c4x_dump (loop_dump_stream, "Repeat block: Call within loop\n");
- return 0;
-
- case NOTE:
- switch (NOTE_LINE_NUMBER (insn))
- {
- case NOTE_INSN_LOOP_CONT:
- if (continue_note == NULL_RTX)
- continue_note = insn;
-
- /* Check for empty loop which would throw c4x_rptb_nop_p.
- GCC doesn't optimise empty loops away since user
- may be trying to implement a simple but crude delay. */
- if (GET_CODE (PREV_INSN (insn)) == NOTE
- && NOTE_LINE_NUMBER (PREV_INSN (insn)) == NOTE_INSN_LOOP_BEG)
- {
- c4x_dump (loop_dump_stream, "Repeat block: Empty loop\n");
- return 0;
- }
- break;
-
- /* If we find a LOOP_END note, then we are not in the
- innermost loop. */
- case NOTE_INSN_LOOP_END:
- return 0;
-
- default:
- continue;
- }
- default:
- continue;
- }
- }
- if (insn == NULL_RTX)
- fatal("Repeat block: Inconsistent loop");
-
- c4x_dump (loop_dump_stream, "Repeat block: Unjumped loop\n");
- if (continue_label)
- c4x_dump (loop_dump_stream, "Repeat block: Continue_label %d\n",
- INSN_UID (continue_label));
- return 1;
-}
-
-
-/* Find and record in PCOMP and PJUMP the final comparison and jump
- insns of the loop specified by LOOP_END. Return 1 if both have been
- found, otherwise return 0. */
-
-static int
-c4x_rptb_find_comp_and_jump (loop_end, pcomp, pjump)
- rtx loop_end;
- rtx *pcomp, *pjump;
-{
- rtx final_comp, comp_pat;
- rtx final_jump = prev_nonnote_insn (loop_end);
-
- if (!final_jump)
- return 0;
-
- final_comp = PREV_INSN (final_jump);
- if (!final_comp)
- return 0;
-
- if ((GET_CODE (final_comp) != INSN))
- return 0;
-
- comp_pat = PATTERN (final_comp);
-
- if ((GET_CODE (comp_pat) != SET)
- || GET_CODE (XEXP (comp_pat, 0)) != REG
- || REGNO (XEXP (comp_pat, 0)) != ST_REGNO)
- return 0;
-
- *pcomp = final_comp;
- *pjump = final_jump;
- return 1;
-}
-
-
-/* Determine if the loop count is computable for a repeat loop. */
-
-static int
-c4x_rptb_loop_info_get (loop_start, loop_end, loop_info)
- rtx loop_start, loop_end;
- c4x_rptb_info_t *loop_info;
-{
- rtx iteration_var, initial_value, increment, comparison;
- enum rtx_code cc; /* Comparison code */
- rtx comparison_value;
-
- loop_info->loop_start = loop_start;
- loop_info->loop_count = loop_iterations (loop_start, loop_end);
-
- /* If the number of loop cycles does not need calculating at
- run-time then things are easy... Note that the repeat count
- value must be a positive integer for the RPTB instruction. If
- loop_count is zero then we don't have a constant count. */
- if (loop_info->loop_count > 0)
- return 1;
- if (loop_info->loop_count < 0)
- {
- c4x_dump (loop_dump_stream, "Repeat block: Negative loop count %d\n",
- loop_info->loop_count);
- return 0;
- }
-
- comparison = get_condition_for_loop (prev_nonnote_insn (loop_end));
- if (comparison == NULL_RTX)
- {
- c4x_dump (loop_dump_stream, "Repeat block: Cannot find comparison\n");
- return 0;
- }
- cc = GET_CODE (comparison);
-
- /* Only allow a register as the iteration value. */
- iteration_var = XEXP (comparison, 0);
- if (GET_CODE (iteration_var) != REG)
- {
- c4x_dump (loop_dump_stream, "Repeat block: Non reg. iteration value\n");
- return 0;
- }
-
- c4x_dump (loop_dump_stream, "Repeat block: Iteration value regno = %d\n",
- REGNO (iteration_var));
-
- /* The comparison value must not change on the fly. */
- comparison_value = XEXP (comparison, 1);
- if (!invariant_p (comparison_value))
- {
- c4x_dump (loop_dump_stream, "Repeat block: Comparison value variant\n");
- return 0;
- }
-
- /* This routine in unroll.c does the hard work of finding the
- initial value and increment for us. Currently it won't find the
- intitial value or increment for do {} while; or while() {} do;
- loops. This is because the iteration_var we find in the
- comparison insn is a GIV rather than a BIV and iteration_info does
- not like GIVs. We could scan all the BIVs like check_dbra_loop()
- does... */
-
- iteration_info (iteration_var, &initial_value, &increment,
- loop_start, loop_end);
- if (initial_value == NULL_RTX || increment == NULL_RTX)
- {
- c4x_dump (loop_dump_stream, "Repeat block: Cannot determine initial"
- " value or increment\n");
- return 0;
- }
-
- /* Only allow constant integer increment, not a variable. */
- if (GET_CODE (increment) != CONST_INT)
- {
- c4x_dump (loop_dump_stream, "Repeat block: Increment not constant\n");
- return 0;
- }
-
- loop_info->incr = INTVAL (increment);
-
- /* If the increment is not a power of 2, (i.e, 1, 2, 4, etc.) then
- we will need to emit a divide instruction rather than a right
- shift to calculate the loop count. */
- if ((loop_info->shift = exact_log2 (abs (loop_info->incr))) < 0)
- {
- c4x_dump (loop_dump_stream, "Repeat block: Increment not power of 2\n");
- return 0;
- }
-
- /* The front end changes GT to NE for unsigned numbers, so we
- "undo" this here for clarity. */
- loop_info->unsigned_p = 0;
- if (GET_CODE (increment) == CONST_INT
- && INTVAL (increment) == -1 && cc == NE)
- {
- loop_info->unsigned_p = 1;
- cc = GT;
- }
-
- if (!(cc == LT || cc == LE || cc == LTU || cc == LEU
- || cc == GT || cc == GE || cc == GTU || cc == GEU))
- {
- c4x_dump (loop_dump_stream, "Repeat block: Invalid comparison\n");
- return 0;
- }
-
- loop_info->swap_p = (cc == GT || cc == GE || cc == GTU || cc == GEU);
- if (loop_info->swap_p)
- {
- loop_info->start_value = comparison_value;
- loop_info->end_value = initial_value;
- loop_info->incr = -loop_info->incr;
- }
- else
- {
- loop_info->start_value = initial_value;
- loop_info->end_value = comparison_value;
- }
-
- /* Check if loop won't terminate? */
- if (loop_info->incr <= 0)
- {
- c4x_dump (loop_dump_stream, "Repeat block: Increment negative\n");
- return 0;
- }
-
- loop_info->off_by_one = (cc == LT || cc == LTU || cc == GT || cc == GTU);
- loop_info->unsigned_p |= (cc == LTU || cc == LEU || cc == GTU || cc == GEU);
-
- /* We have a switch to allow an unsigned loop counter.
- We'll normally disallow this case since the the repeat
- count for the RPTB instruction must be less than 0x80000000. */
- if (loop_info->unsigned_p && !TARGET_LOOP_UNSIGNED)
- {
- c4x_dump (loop_dump_stream, "Repeat block: Unsigned comparison\n");
- return 0;
- }
-
- return 1;
-}
-
-
-/* Emit insn(s) to compute loop iteration count. */
-
-static rtx
-c4x_rptb_emit_init (loop_info)
- c4x_rptb_info_t *loop_info;
-{
- rtx result;
- int adjust;
- rtx seq_start;
-
- /* If have a known constant loop count, things are easy... */
- if (loop_info->loop_count > 0)
- return gen_rtx (CONST_INT, VOIDmode, loop_info->loop_count - 1);
-
- if (loop_info->shift < 0)
- abort ();
-
- start_sequence ();
-
- result = loop_info->end_value;
- if (loop_info->start_value != const0_rtx)
- {
- /* end_value - start_value */
- result = expand_binop (QImode, sub_optab,
- result, loop_info->start_value,
- 0, loop_info->unsigned_p, OPTAB_DIRECT);
- }
-
- adjust = loop_info->incr - loop_info->off_by_one;
- if (adjust > 0)
- {
- /* end_value - start_value + adjust */
- result = expand_binop (QImode, add_optab,
- result, GEN_INT (adjust),
- 0, loop_info->unsigned_p, OPTAB_DIRECT);
- }
-
- if (loop_info->shift > 0)
- {
- /* (end_value - start_value + adjust) >> shift */
- result = expand_binop (QImode, loop_info->unsigned_p ?
- lshr_optab : ashr_optab, result,
- gen_rtx (CONST_INT, VOIDmode,
- loop_info->shift),
- 0, loop_info->unsigned_p, OPTAB_DIRECT);
- }
-
- /* ((end_value - start_value + adjust) >> shift) - 1 */
- result = expand_binop (QImode, sub_optab,
- result, gen_rtx (CONST_INT, VOIDmode, 1),
- 0, loop_info->unsigned_p, OPTAB_DIRECT);
-
- seq_start = get_insns ();
- end_sequence ();
-
- emit_insns_before (seq_start, loop_info->loop_start);
- return result;
-}
-
-
-/* This routine checks for suitable loops that can use zero overhead
- looping and emits insns marking the start and end of the loop
- as well as an insn for initialising the loop counter. */
-
-void
-c4x_rptb_process (loop_start, loop_end)
- rtx loop_start, loop_end;
-{
- rtx iteration_count;
- rtx start_label;
- rtx end_label;
- rtx comp_insn;
- rtx jump_insn;
- c4x_rptb_info_t info;
-
- if (!TARGET_RPTB)
- return;
-
- /* Check that there are no jumps crossing loop boundary or calls. */
- if (!c4x_rptb_unjumped_loop_p (loop_start, loop_end))
- return;
-
- start_label = next_nonnote_insn (loop_start);
- if (GET_CODE (start_label) != CODE_LABEL)
- return;
-
- /* Find comparison and jump insns. */
- if (!c4x_rptb_find_comp_and_jump (loop_end, &comp_insn, &jump_insn))
- return;
-
- /* If we don't jump back to start label, then the loop is no good. */
- if (start_label != JUMP_LABEL (jump_insn))
- return;
-
- /* Check that number of loops is computable. */
- if (!c4x_rptb_loop_info_get (loop_start, loop_end, &info))
- return;
-
- c4x_dump (loop_dump_stream, "Repeat block: Loop start at %d, end at %d\n",
- INSN_UID (loop_start), INSN_UID (loop_end));
-
- if (info.loop_count > 0)
- c4x_dump (loop_dump_stream, "Repeat block: Loop count = %d\n",
- info.loop_count);
- else
- c4x_dump (loop_dump_stream,
- "Repeat block: incr %d, shift %d, swap_p %d,"
- " off_by_one %d, unsigned_p %d\n",
- info.incr, info.shift, info.swap_p,
- info.off_by_one, info.unsigned_p);
-
- /* Emit insns to compute loop iteration count. */
- iteration_count = c4x_rptb_emit_init (&info);
- if (iteration_count == NULL_RTX)
- abort ();
-
- /* Add label at end of loop, immediately after jump insn. */
- end_label = gen_label_rtx ();
- emit_label_after (end_label, jump_insn);
-
- /* Add label to forced label list to prevent jump optimisation
- coalescing end_label with bypass_label since we need these destinct if
- we are to sink insns out of the loop. */
- if (GET_CODE (NEXT_INSN (loop_end)) == CODE_LABEL)
- {
- rtx bypass_label;
-
- bypass_label = NEXT_INSN (loop_end);
-#if 0
- forced_labels = gen_rtx (EXPR_LIST, VOIDmode,
- end_label, forced_labels);
- forced_labels = gen_rtx (EXPR_LIST, VOIDmode,
- bypass_label, forced_labels);
-#endif
- emit_insn_after (gen_repeat_block_filler (), end_label);
-
- c4x_dump (loop_dump_stream,
- "Repeat block: Start label at %d, end label at %d,"
- " bypass label at %d\n",
- INSN_UID (start_label), INSN_UID (end_label),
- INSN_UID (bypass_label));
- }
- else
- {
- emit_insn_after (gen_repeat_block_filler (), end_label);
- c4x_dump (loop_dump_stream,
- "Repeat block: Start label at %d, end label at %d\n",
- INSN_UID (start_label), INSN_UID (end_label));
- }
-
- /* Create pattern for repeat_block_top and insert at top of loop. */
- emit_insn_before (gen_repeat_block_top (const0_rtx, iteration_count,
- start_label, end_label),
- start_label);
-
- /* Replace the jump instruction with repeat_block_end insn. */
- PATTERN (jump_insn) = gen_repeat_block_end (const0_rtx, start_label);
-
- /* The insn is unrecognizable after the surgery. */
- INSN_CODE (jump_insn) = -1;
-
- /* Delete the comparison insn. */
- delete_insn (comp_insn);
-}
-
-
+/* !!! FIXME to emit RPTS correctly. */
int
c4x_rptb_rpts_p (insn, op)
rtx insn, op;
@@ -5396,7 +4232,7 @@ c4x_rptb_rpts_p (insn, op)
if (GET_RTX_CLASS (GET_CODE (insn)) != 'i')
return 0;
- if (recog_memoized (insn) != CODE_FOR_repeat_block_end)
+ if (recog_memoized (insn) != CODE_FOR_rptb_end)
return 0;
if (TARGET_RPTS)
@@ -5405,48 +4241,6 @@ c4x_rptb_rpts_p (insn, op)
return (GET_CODE (op) == CONST_INT) && TARGET_RPTS_CYCLES (INTVAL (op));
}
-/*
- Loop structure of `for' loops:
-
- Check if iterations required
- If not, jump to BYPASS_LABEL
-
- NOTE_INSN_LOOP_BEG
- <<<Repeat block top goes here>>
- START_LABEL:
- {NOTE_BLOCK_BEGIN}
-
- Body of loop
-
- {NOTE_BLOCK_END}
- {NOTE_INSN_LOOP_CONT}
-
- Increment loop counters here
-
- {NOTE_INSN_LOOP_VTOP}
- <<<Repeat block nop goes here if nec.>>>
- Exit test here <<<This gets deleted>>>
- If not exiting jump to START_LABEL <<<Repeat block end goes here>>>
- <<<END_LABEL goes here>>
-
- NOTE_INSN_LOOP_END
-
- BYPASS_LABEL:
-
- Note that NOTE_INSN_LOOP_VTOP is only required for loops such as
- for loops, where it necessary to duplicate the exit test. This
- position becomes another virtual start of the loop when considering
- invariants.
-
- Note that if there is nothing in the loop body we get:
-
- NOTE_INSN_LOOP_BEG
- NOTE_INSN_LOOP_CONT
- START_LABEL:
- NOTE_INSN_LOOP_VTOP
- ...
- */
-
/* Adjust the cost of a scheduling dependency. Return the new cost of
a dependency LINK or INSN on DEP_INSN. COST is the current cost.
@@ -5466,7 +4260,7 @@ c4x_adjust_cost (insn, link, dep_insn, cost)
{
/* Don't worry about this until we know what registers have been
assigned. */
- if (!reload_completed)
+ if (! reload_completed)
return 0;
/* How do we handle dependencies where a read followed by another
@@ -5486,7 +4280,6 @@ c4x_adjust_cost (insn, link, dep_insn, cost)
/* Data dependency; DEP_INSN writes a register that INSN reads some
cycles later. */
-
if (TARGET_C3X)
{
if (get_attr_setgroup1 (dep_insn) && get_attr_usegroup1 (insn))
@@ -5501,7 +4294,6 @@ c4x_adjust_cost (insn, link, dep_insn, cost)
insn uses ar0-ar7. We then test if the same register
is used. The tricky bit is that some operands will
use several registers... */
-
if (get_attr_setar0 (dep_insn) && get_attr_usear0 (insn))
max = SET_USE_COST > max ? SET_USE_COST : max;
if (get_attr_setlda_ar0 (dep_insn) && get_attr_usear0 (insn))
@@ -5595,3 +4387,4 @@ c4x_adjust_cost (insn, link, dep_insn, cost)
else
abort ();
}
+
diff --git a/gcc/config/c4x/c4x.h b/gcc/config/c4x/c4x.h
index cc92b2a12f9..a72d6dbc307 100644
--- a/gcc/config/c4x/c4x.h
+++ b/gcc/config/c4x/c4x.h
@@ -1,5 +1,5 @@
/* Definitions of target machine for GNU compiler. TMS320C[34]x
- Copyright (C) 1994, 1995, 1996, 1997 Free Software Foundation, Inc.
+ Copyright (C) 1994-98, 1999 Free Software Foundation, Inc.
Contributed by Michael Hayes (m.hayes@elec.canterbury.ac.nz)
and Herman Ten Brugge (Haj.Ten.Brugge@net.HCC.nl).
@@ -156,66 +156,109 @@
/* 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 }
+ 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. */
#define TARGET_SWITCHES \
-{ { "small", SMALL_MEMORY_FLAG }, \
- { "big", -SMALL_MEMORY_FLAG }, \
- { "mpyi", MPYI_FLAG}, \
- { "no-mpyi", -MPYI_FLAG}, \
- { "fast-fix", FAST_FIX_FLAG}, \
- { "no-fast-fix", -FAST_FIX_FLAG}, \
- { "rpts", RPTS_FLAG}, \
- { "no-rpts", -RPTS_FLAG}, \
- { "rptb", RPTB_FLAG}, \
- { "no-rptb", -RPTB_FLAG}, \
- { "30", C30_FLAG}, \
- { "31", C31_FLAG}, \
- { "32", C32_FLAG}, \
- { "40", C40_FLAG}, \
- { "44", C44_FLAG}, \
- { "ti", TI_FLAG}, \
- { "no-ti", -TI_FLAG}, \
- { "paranoid", PARANOID_FLAG}, \
- { "no-paranoid", -PARANOID_FLAG}, \
- { "isr-dp-reload", PARANOID_FLAG}, \
- { "no-isr-dp-reload", -PARANOID_FLAG}, \
- { "memparm", MEMPARM_FLAG}, \
- { "regparm", -MEMPARM_FLAG}, \
- { "devel", DEVEL_FLAG}, \
- { "no-devel", -DEVEL_FLAG}, \
- { "bk", BK_FLAG}, \
- { "no-bk", -BK_FLAG}, \
- { "db", DB_FLAG}, \
- { "no-db", -DB_FLAG}, \
- { "debug", DEBUG_FLAG}, \
- { "no-debug", -DEBUG_FLAG}, \
- { "hoist", HOIST_FLAG}, \
- { "no-hoist", -HOIST_FLAG}, \
- { "no-force", -FORCE_FLAG}, \
- { "force", FORCE_FLAG}, \
- { "loop-unsigned", LOOP_UNSIGNED_FLAG}, \
- { "no-loop-unsigned", -LOOP_UNSIGNED_FLAG}, \
- { "preserve-float", PRESERVE_FLOAT_FLAG}, \
- { "no-preserve-float", -PRESERVE_FLOAT_FLAG}, \
- { "parallel-insns", PARALLEL_PACK_FLAG}, \
- { "no-parallel-mpy", -PARALLEL_MPY_FLAG}, \
- { "parallel-mpy", PARALLEL_MPY_FLAG}, \
- { "no-parallel-insns", -PARALLEL_PACK_FLAG}, \
- { "aliases", ALIASES_FLAG}, \
- { "no-aliases", -ALIASES_FLAG}, \
- { "", TARGET_DEFAULT} }
+{ { "small", SMALL_MEMORY_FLAG, \
+ "Small memory model" }, \
+ { "big", -SMALL_MEMORY_FLAG, \
+ "Big memory model" }, \
+ { "mpyi", MPYI_FLAG, \
+ "Use MPYI instruction for C3x" }, \
+ { "no-mpyi", -MPYI_FLAG, \
+ "Do not use MPYI instruction for C3x" }, \
+ { "fast-fix", FAST_FIX_FLAG, \
+ "Use fast but approximate float to integer conversion" }, \
+ { "no-fast-fix", -FAST_FIX_FLAG, \
+ "Use slow but accurate float to integer conversion" }, \
+ { "rpts", RPTS_FLAG, \
+ "Enable use of RTPS instruction" }, \
+ { "no-rpts", -RPTS_FLAG, \
+ "Disable use of RTPS instruction" }, \
+ { "rptb", RPTB_FLAG, \
+ "Enable use of RTPB instruction" }, \
+ { "no-rptb", -RPTB_FLAG, \
+ "Disable use of RTPB instruction" }, \
+ { "30", C30_FLAG, \
+ "Generate code for C30 CPU"}, \
+ { "31", C31_FLAG, \
+ "Generate code for C31 CPU"}, \
+ { "32", C32_FLAG, \
+ "Generate code for C32 CPU"}, \
+ { "40", C40_FLAG, \
+ "Generate code for C40 CPU"}, \
+ { "44", C44_FLAG, \
+ "Generate code for C44 CPU"}, \
+ { "ti", TI_FLAG, \
+ "Emit code compatible with TI tools"}, \
+ { "no-ti", -TI_FLAG, \
+ "Emit code to use GAS extensions"}, \
+ { "paranoid", PARANOID_FLAG, \
+ "Save DP across ISR in small memory model" }, \
+ { "no-paranoid", -PARANOID_FLAG, \
+ "Don't save DP across ISR in small memory model" }, \
+ { "isr-dp-reload", PARANOID_FLAG, \
+ "Save DP across ISR in small memory model" }, \
+ { "no-isr-dp-reload", -PARANOID_FLAG, \
+ "Don't save DP across ISR in small memory model" }, \
+ { "memparm", MEMPARM_FLAG, \
+ "Pass arguments on the stack" }, \
+ { "regparm", -MEMPARM_FLAG, \
+ "Pass arguments in registers" }, \
+ { "devel", DEVEL_FLAG, \
+ "Enable new features under development" }, \
+ { "no-devel", -DEVEL_FLAG, \
+ "Disable new features under development" }, \
+ { "bk", BK_FLAG, \
+ "Use the BK register as a general purpose register" }, \
+ { "no-bk", -BK_FLAG, \
+ "Do not allocate BK register" }, \
+ { "db", DB_FLAG, \
+ "Enable use of DB instruction" }, \
+ { "no-db", -DB_FLAG, \
+ "Disable use of DB instruction" }, \
+ { "debug", DEBUG_FLAG, \
+ "Enable debugging" }, \
+ { "no-debug", -DEBUG_FLAG, \
+ "Disable debugging" }, \
+ { "hoist", HOIST_FLAG, \
+ "Force constants into registers to improve hoisting" }, \
+ { "no-hoist", -HOIST_FLAG, \
+ "Don't force constants into registers" }, \
+ { "force", FORCE_FLAG, \
+ "Force RTL generation to emit valid 3 operand insns" }, \
+ { "no-force", -FORCE_FLAG, \
+ "Allow RTL generation to emit invalid 3 operand insns" }, \
+ { "loop-unsigned", LOOP_UNSIGNED_FLAG, \
+ "Allow unsigned interation counts for RPTB/DB" }, \
+ { "no-loop-unsigned", -LOOP_UNSIGNED_FLAG, \
+ "Disallow unsigned iteration counts for RPTB/DB" }, \
+ { "preserve-float", PRESERVE_FLOAT_FLAG, \
+ "Preserve all 40 bits of FP reg across call" }, \
+ { "no-preserve-float", -PRESERVE_FLOAT_FLAG, \
+ "Only preserve 32 bits of FP reg across call" }, \
+ { "parallel-insns", PARALLEL_PACK_FLAG, \
+ "Enable parallel instructions" }, \
+ { "no-parallel-mpy", -PARALLEL_MPY_FLAG, \
+ "Disable parallel instructions" }, \
+ { "parallel-mpy", PARALLEL_MPY_FLAG, \
+ "Enable MPY||ADD and MPY||SUB instructions" }, \
+ { "no-parallel-insns", -PARALLEL_PACK_FLAG, \
+ "Disable MPY||ADD and MPY||SUB instructions" }, \
+ { "aliases", ALIASES_FLAG, \
+ "Assume that pointers may be aliased" }, \
+ { "no-aliases", -ALIASES_FLAG, \
+ "Assume that pointers not aliased" }, \
+ { "", TARGET_DEFAULT, ""} }
/* Default target switches */
-/* Play safe, not the fastest code. Note that setting PARALLEL_MPY
-flag will set SMALL_REGISTER_CLASSES which can be a price to pay,
-especially when MPY||ADD instructions are only generated very
-infrequenctly. */
-#define TARGET_DEFAULT ALIASES_FLAG | RPTB_FLAG | PARALLEL_PACK_FLAG
+/* Play safe, not the fastest code. */
+#define TARGET_DEFAULT ALIASES_FLAG | PARALLEL_PACK_FLAG \
+ | PARALLEL_MPY_FLAG | RPTB_FLAG
/* Caveats:
Max iteration count for RPTB/RPTS is 2^31 + 1.
@@ -227,7 +270,7 @@ extern int target_flags;
#define TARGET_INLINE 1 /* Inline MPYI */
#define TARGET_PARALLEL 1 /* Enable parallel insns in MD */
-#define TARGET_SMALL_REG_CLASS 1
+#define TARGET_SMALL_REG_CLASS 0
#define TARGET_SMALL (target_flags & SMALL_MEMORY_FLAG)
#define TARGET_MPYI (!TARGET_C3X || (target_flags & MPYI_FLAG))
@@ -240,7 +283,7 @@ extern int target_flags;
#define TARGET_RPTB (target_flags & RPTB_FLAG \
&& optimize >= 2)
#define TARGET_BK (target_flags & BK_FLAG)
-#define TARGET_DB (!TARGET_C3X || (target_flags & DB_FLAG))
+#define TARGET_DB (! TARGET_C3X || (target_flags & DB_FLAG))
#define TARGET_DEBUG (target_flags & DEBUG_FLAG)
#define TARGET_HOIST (target_flags & HOIST_FLAG)
#define TARGET_LOOP_UNSIGNED (target_flags & LOOP_UNSIGNED_FLAG)
@@ -260,12 +303,16 @@ extern int target_flags;
#define TARGET_C40 (target_flags & C40_FLAG)
#define TARGET_C44 (target_flags & C44_FLAG)
+#define TARGET_LOAD_ADDRESS (1 || (! TARGET_C3X && ! TARGET_SMALL))
+
/* -mrpts allows the use of the RPTS instruction irregardless.
-mrpts=max-cycles will use RPTS if the number of cycles is constant
and less than max-cycles. */
#define TARGET_RPTS_CYCLES(CYCLES) (TARGET_RPTS || (CYCLES) < c4x_rpts_cycles)
+#define BCT_CHECK_LOOP_ITERATIONS !(TARGET_LOOP_UNSIGNED)
+
/* -mcpu=XX with XX = target DSP version number */
/* This macro is similar to `TARGET_SWITCHES' but defines names of
@@ -288,8 +335,10 @@ extern int target_flags;
extern char *c4x_rpts_cycles_string, *c4x_cpu_version_string;
#define TARGET_OPTIONS \
-{ {"rpts=", &c4x_rpts_cycles_string},\
- {"cpu=", &c4x_cpu_version_string} }
+{ {"rpts=", &c4x_rpts_cycles_string, \
+ "Specify maximum number of iterations for RPTS" }, \
+ {"cpu=", &c4x_cpu_version_string, \
+ "Select CPU to generate code for" } }
/* Sometimes certain combinations of command options do not make sense
on a particular target machine. You can define a macro
@@ -300,6 +349,9 @@ extern char *c4x_rpts_cycles_string, *c4x_cpu_version_string;
extern void c4x_override_options ();
#define OVERRIDE_OPTIONS c4x_override_options ()
+/* Define this to change the optimizations performed by default. */
+extern void c4x_optimization_options ();
+#define OPTIMIZATION_OPTIONS(LEVEL,SIZE) c4x_optimization_options(LEVEL,SIZE)
/* Run Time Target Specification */
@@ -335,6 +387,11 @@ extern void c4x_override_options ();
#define TARGET_FLOAT_FORMAT C4X_FLOAT_FORMAT
#define MAX_FIXED_MODE_SIZE 64 /* HImode */
+/* Number of bits in the high and low parts of a two stage
+ load of an immediate constant. */
+#define BITS_PER_HIGH 16
+#define BITS_PER_LO_SUM 16
+
/* Use the internal floating point stuff in the compiler and not the
host floating point stuff. */
@@ -417,7 +474,7 @@ extern void c4x_override_options ();
/* Extended precision registers (high set) */
-#define IS_EXT_HIGH_REG(r) (!TARGET_C3X \
+#define IS_EXT_HIGH_REG(r) (! TARGET_C3X \
&& ((r) >= R8_REGNO) && ((r) <= R11_REGNO))
/* Address registers */
@@ -431,6 +488,7 @@ extern void c4x_override_options ();
/* Misc registers */
#define IS_ST_REG(r) ((r) == ST_REGNO)
+#define IS_RC_REG(r) ((r) == RC_REGNO)
#define IS_REPEAT_REG(r) (((r) >= RS_REGNO) && ((r) <= RC_REGNO))
/* Composite register sets */
@@ -455,6 +513,7 @@ extern void c4x_override_options ();
#define IS_DP_OR_PSEUDO_REG(r) (IS_DP_REG(r) || IS_PSEUDO_REG(r))
#define IS_SP_OR_PSEUDO_REG(r) (IS_SP_REG(r) || IS_PSEUDO_REG(r))
#define IS_ST_OR_PSEUDO_REG(r) (IS_ST_REG(r) || IS_PSEUDO_REG(r))
+#define IS_RC_OR_PSEUDO_REG(r) (IS_RC_REG(r) || IS_PSEUDO_REG(r))
#define IS_PSEUDO_REGNO(op) (IS_PSEUDO_REG(REGNO(op)))
#define IS_ADDR_REGNO(op) (IS_ADDR_REG(REGNO(op)))
@@ -473,6 +532,7 @@ extern void c4x_override_options ();
#define IS_DP_OR_PSEUDO_REGNO(op) (IS_DP_OR_PSEUDO_REG(REGNO(op)))
#define IS_SP_OR_PSEUDO_REGNO(op) (IS_SP_OR_PSEUDO_REG(REGNO(op)))
#define IS_ST_OR_PSEUDO_REGNO(op) (IS_ST_OR_PSEUDO_REG(REGNO(op)))
+#define IS_RC_OR_PSEUDO_REGNO(op) (IS_RC_OR_PSEUDO_REG(REGNO(op)))
/* 1 for registers that have pervasive standard uses
and are not available for the register allocator. */
@@ -508,7 +568,7 @@ extern void c4x_override_options ();
#define CONDITIONAL_REGISTER_USAGE \
{ \
- if (!TARGET_BK) \
+ if (! TARGET_BK) \
{ \
fixed_regs[BK_REGNO] = 1; \
call_used_regs[BK_REGNO] = 1; \
@@ -528,6 +588,11 @@ extern void c4x_override_options ();
c4x_regclass_map[i] = NO_REGS; \
} \
} \
+ if (TARGET_PRESERVE_FLOAT) \
+ { \
+ c4x_caller_save_map[R6_REGNO] = HFmode; \
+ c4x_caller_save_map[R7_REGNO] = HFmode; \
+ } \
}
/* Order of Allocation of Registers */
@@ -573,11 +638,10 @@ extern void c4x_override_options ();
across a call in mode MODE. This does not have to include the call used
registers. */
-#define HARD_REGNO_CALL_PART_CLOBBERED(REGNO, MODE) \
- (((REGNO) == R6_REGNO || (REGNO) == R7_REGNO) \
- && (MODE) != QFmode \
- || ((REGNO) == R4_REGNO || (REGNO) == R5_REGNO || (REGNO == R8_REGNO) \
- && ((MODE) != QImode || (MODE) != HImode || (MODE) != Pmode)))
+#define HARD_REGNO_CALL_PART_CLOBBERED(REGNO, MODE) \
+ ((((REGNO) == R6_REGNO || (REGNO) == R7_REGNO) && ! ((MODE) == QFmode)) \
+ || (((REGNO) == R4_REGNO || (REGNO) == R5_REGNO || (REGNO == R8_REGNO)) \
+ && ! ((MODE) == QImode || (MODE) == HImode || (MODE) == Pmode)))
/* Specify the modes required to caller save a given hard regno. */
@@ -628,8 +692,10 @@ enum reg_class
EXT_REGS, /* 'f' */
ADDR_REGS, /* 'a' */
INDEX_REGS, /* 'x' */
- SP_REG, /* 'b' */
BK_REG, /* 'k' */
+ SP_REG, /* 'b' */
+ RC_REG, /* 'v' */
+ COUNTER_REGS, /* */
INT_REGS, /* 'c' */
GENERAL_REGS, /* 'r' */
DP_REG, /* 'z' */
@@ -649,36 +715,41 @@ enum reg_class
"EXT_REGS", \
"ADDR_REGS", \
"INDEX_REGS", \
- "SP_REG", \
"BK_REG", \
+ "SP_REG", \
+ "RC_REG", \
+ "COUNTER_REGS", \
"INT_REGS", \
"GENERAL_REGS", \
"DP_REG", \
"ST_REG", \
"ALL_REGS" \
-};
+}
/* Define which registers fit in which classes.
This is an initializer for a vector of HARD_REG_SET
- of length N_REG_CLASSES. */
-
+ of length N_REG_CLASSES. RC is not included in GENERAL_REGS
+ since the register allocator will often choose a general register
+ in preference to RC for the decrement_and_branch_on_count pattern. */
#define REG_CLASS_CONTENTS \
{ \
- 0x00000000, /* No registers */ \
- 0x00000003, /* 't' R0-R1 */ \
- 0x0000000c, /* 'u' R2-R3 */ \
- 0x000000ff, /* 'q' R0-R7 */ \
- 0xf00000ff, /* 'f' R0-R11 */ \
- 0x0000ff00, /* 'a' AR0-AR7 */ \
- 0x00060000, /* 'x' IR0-IR1 */ \
- 0x00100000, /* 'b' SP */ \
- 0x00080000, /* 'k' BK */ \
- 0x0e1eff00, /* 'c' AR0-AR7, IR0-IR1, RC, RS, RE, BK, SP */ \
- 0xfe1effff, /* 'r' R0-R11, AR0-AR7, IR0-IR1, RC, RS, RE, BK, SP */\
- 0x00010000, /* 'z' DP */ \
- 0x00200000, /* 'y' ST */ \
- 0xffffffff, /* All registers */ \
+ {0x00000000}, /* No registers */ \
+ {0x00000003}, /* 't' R0-R1 */ \
+ {0x0000000c}, /* 'u' R2-R3 */ \
+ {0x000000ff}, /* 'q' R0-R7 */ \
+ {0xf00000ff}, /* 'f' R0-R11 */ \
+ {0x0000ff00}, /* 'a' AR0-AR7 */ \
+ {0x00060000}, /* 'x' IR0-IR1 */ \
+ {0x00080000}, /* 'k' BK */ \
+ {0x00100000}, /* 'b' SP */ \
+ {0x08000000}, /* 'v' RC */ \
+ {0x0800ff00}, /* RC,AR0-AR7 */ \
+ {0x0e1eff00}, /* 'c' AR0-AR7, IR0-IR1, BK, SP, RS, RE, RC */ \
+ {0xfe1effff}, /* 'r' R0-R11, AR0-AR7, IR0-IR1, BK, SP, RS, RE, RC */\
+ {0x00010000}, /* 'z' DP */ \
+ {0x00200000}, /* 'y' ST */ \
+ {0xffffffff}, /* All registers */ \
}
/* The same information, inverted:
@@ -688,22 +759,18 @@ enum reg_class
#define REGNO_REG_CLASS(REGNO) (c4x_regclass_map[REGNO])
-/* When SMALL_REGISTER_CLASSES is defined, the compiler allows
-registers explicitly used in the rtl to be used as spill registers but
-prevents the compiler from extending the lifetime of these registers.
-Problems can occur if reload has to spill a register used explicitly
-in the RTL if it has a long lifetime. This is only likely to be a problem
-with a function having many variables and thus lots of spilling.
-
-We only need to define SMALL_REGISTER_CLASSES if TARGET_PARALLEL_MPY
-is defined since the MPY|ADD insns require the classes R0R1_REGS and
-R2R3_REGS which are used by the function return registers (R0,R1) and
-the register arguments (R2,R3), respectively. I'm reluctant to define
-this macro since it stomps on many potential optimisations. Ideally
-it should have a register class argument so that not all the register
-classes gets penalised for the sake of a naughty few... For long
-double arithmetic we need two additional registers that we can use as
-spill registers. */
+/* When SMALL_REGISTER_CLASSES is defined, the lifetime of registers
+ explicitly used in the rtl is kept as short as possible.
+
+ We only need to define SMALL_REGISTER_CLASSES if TARGET_PARALLEL_MPY
+ is defined since the MPY|ADD insns require the classes R0R1_REGS and
+ R2R3_REGS which are used by the function return registers (R0,R1) and
+ the register arguments (R2,R3), respectively. I'm reluctant to define
+ this macro since it stomps on many potential optimisations. Ideally
+ it should have a register class argument so that not all the register
+ classes gets penalised for the sake of a naughty few... For long
+ double arithmetic we need two additional registers that we can use as
+ spill registers. */
#define SMALL_REGISTER_CLASSES (TARGET_SMALL_REG_CLASS && TARGET_PARALLEL_MPY)
@@ -711,7 +778,7 @@ spill registers. */
#define INDEX_REG_CLASS INDEX_REGS
/*
- Constraints for the C4x
+ Register constraints for the C4x
a - address reg (ar0-ar7)
b - stack reg (sp)
@@ -723,10 +790,13 @@ spill registers. */
q - r0-r7
t - r0-r1
u - r2-r3
+ v - repeat count (rc)
x - index register (ir0-ir1)
y - status register (st)
z - dp reg (dp)
+ Memory/constant constraints for the C4x
+
G - short float 16-bit
I - signed 16-bit constant (sign extended)
J - signed 8-bit constant (sign extended) (C4x only)
@@ -756,6 +826,7 @@ spill registers. */
: ((CC) == 'q') ? EXT_LOW_REGS \
: ((CC) == 't') ? R0R1_REGS \
: ((CC) == 'u') ? R2R3_REGS \
+ : ((CC) == 'v') ? RC_REG \
: ((CC) == 'x') ? INDEX_REGS \
: ((CC) == 'y') ? ST_REG \
: ((CC) == 'z') ? DP_REG \
@@ -801,7 +872,7 @@ c4x_secondary_memory_needed(CLASS1, CLASS2, MODE)
#define IS_NOT_UINT16_CONST(VAL) IS_UINT16_CONST(~(VAL)) /* 'N' */
-#define IS_HIGH_CONST(VAL) (!TARGET_C3X && (((VAL) & 0xffff) == 0)) /* 'O' */
+#define IS_HIGH_CONST(VAL) (! TARGET_C3X && (((VAL) & 0xffff) == 0)) /* 'O' */
#define IS_DISP1_CONST(VAL) (((VAL) <= 1) && ((VAL) >= -1)) /* 'S' */
@@ -816,24 +887,25 @@ c4x_secondary_memory_needed(CLASS1, CLASS2, MODE)
#define CONST_OK_FOR_LETTER_P(VAL, C) \
( ((C) == 'I') ? (IS_INT16_CONST (VAL)) \
- : ((C) == 'J') ? (!TARGET_C3X && IS_INT8_CONST (VAL)) \
- : ((C) == 'K') ? (!TARGET_C3X && IS_INT5_CONST (VAL)) \
+ : ((C) == 'J') ? (! TARGET_C3X && IS_INT8_CONST (VAL)) \
+ : ((C) == 'K') ? (! TARGET_C3X && IS_INT5_CONST (VAL)) \
: ((C) == 'L') ? (IS_UINT16_CONST (VAL)) \
- : ((C) == 'M') ? (!TARGET_C3X && IS_UINT8_CONST (VAL)) \
+ : ((C) == 'M') ? (! TARGET_C3X && IS_UINT8_CONST (VAL)) \
: ((C) == 'N') ? (IS_NOT_UINT16_CONST (VAL)) \
: ((C) == 'O') ? (IS_HIGH_CONST (VAL)) \
: 0 )
-#define CONST_DOUBLE_OK_FOR_LETTER_P(VAL, C) \
- ( ((C) == 'G') ? (fp_zero_operand (VAL)) \
- : ((C) == 'H') ? (c4x_H_constant (VAL)) \
+#define CONST_DOUBLE_OK_FOR_LETTER_P(OP, C) \
+ ( ((C) == 'G') ? (fp_zero_operand (OP)) \
+ : ((C) == 'H') ? (c4x_H_constant (OP)) \
: 0 )
-#define EXTRA_CONSTRAINT(VAL, C) \
- ( ((C) == 'Q') ? (c4x_Q_constraint (VAL)) \
- : ((C) == 'R') ? (c4x_R_constraint (VAL)) \
- : ((C) == 'S') ? (c4x_S_constraint (VAL)) \
- : ((C) == 'T') ? (c4x_T_constraint (VAL)) \
+#define EXTRA_CONSTRAINT(OP, C) \
+ ( ((C) == 'Q') ? (c4x_Q_constraint (OP)) \
+ : ((C) == 'R') ? (c4x_R_constraint (OP)) \
+ : ((C) == 'S') ? (c4x_S_constraint (OP)) \
+ : ((C) == 'T') ? (c4x_T_constraint (OP)) \
+ : ((C) == 'U') ? (c4x_U_constraint (OP)) \
: 0 )
#define SMALL_CONST(VAL, insn) \
@@ -978,7 +1050,7 @@ c4x_secondary_memory_needed(CLASS1, CLASS2, MODE)
int regno; \
int offset = 0; \
for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) \
- if (regs_ever_live[regno] && !call_used_regs[regno]) \
+ if (regs_ever_live[regno] && ! call_used_regs[regno]) \
offset += TARGET_PRESERVE_FLOAT \
&& ((regno == R6_REGNO) || (regno == R7_REGNO)) \
? 2 : 1; \
@@ -990,7 +1062,7 @@ c4x_secondary_memory_needed(CLASS1, CLASS2, MODE)
{{ FRAME_POINTER_REGNUM, FRAME_POINTER_REGNUM }}
#define CAN_ELIMINATE(FROM, TO) \
- (!(((FROM) == FRAME_POINTER_REGNUM && (TO) == STACK_POINTER_REGNUM) \
+ (! (((FROM) == FRAME_POINTER_REGNUM && (TO) == STACK_POINTER_REGNUM) \
|| ((FROM) == FRAME_POINTER_REGNUM && (TO) == FRAME_POINTER_REGNUM)))
#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
@@ -998,7 +1070,7 @@ c4x_secondary_memory_needed(CLASS1, CLASS2, MODE)
int regno; \
int offset = 0; \
for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) \
- if (regs_ever_live[regno] && !call_used_regs[regno]) \
+ if (regs_ever_live[regno] && ! call_used_regs[regno]) \
offset += TARGET_PRESERVE_FLOAT \
&& ((regno == R6_REGNO) || (regno == R7_REGNO)) \
? 2 : 1; \
@@ -1096,7 +1168,7 @@ extern struct rtx_def *c4x_function_arg();
MSBs of the address. This is not supported by the TI assembler. */
#define FUNCTION_PROFILER(FILE, LABELNO) \
- if (!TARGET_C3X) \
+ if (! TARGET_C3X) \
{ \
fprintf (FILE, "\tpush\tar2\n"); \
fprintf (FILE, "\tldhi\t^LP%d,ar2\n", (LABELNO)); \
@@ -1146,7 +1218,7 @@ extern struct rtx_def *c4x_function_arg();
#define FUNCTION_BLOCK_PROFILER(FILE, BLOCKNO) \
if (profile_block_flag == 2) \
{ \
- if (!TARGET_C3X) \
+ if (! TARGET_C3X) \
{ \
fprintf (FILE, "\tpush\tst\n"); \
fprintf (FILE, "\tpush\tar2\n"); \
@@ -1193,7 +1265,7 @@ extern struct rtx_def *c4x_function_arg();
} \
else \
{ \
- if (!TARGET_C3X) \
+ if (! TARGET_C3X) \
{ \
fprintf (FILE, "\tpush\tst\n"); \
fprintf (FILE, "\tpush\tar2\n"); \
@@ -1225,7 +1297,7 @@ extern struct rtx_def *c4x_function_arg();
#define BLOCK_PROFILER(FILE, BLOCKNO) \
if (profile_block_flag == 2) \
{ \
- if (!TARGET_C3X) \
+ if (! TARGET_C3X) \
{ \
fprintf (FILE, "\tpush\tst\n"); \
fprintf (FILE, "\tpush\tar2\n"); \
@@ -1281,7 +1353,7 @@ extern struct rtx_def *c4x_function_arg();
} \
else \
{ \
- if (!TARGET_C3X) \
+ if (! TARGET_C3X) \
{ \
fprintf (FILE, "\tpush\tar2\n"); \
fprintf (FILE, "\tpush\tar0\n"); \
@@ -1508,14 +1580,16 @@ extern struct rtx_def *c4x_gen_compare_reg ();
/* Addressing Modes */
-#define HAVE_POST_INCREMENT
-#define HAVE_PRE_INCREMENT
-#define HAVE_POST_DECREMENT
-#define HAVE_PRE_DECREMENT
-#define HAVE_PRE_MODIFY_REG
-#define HAVE_POST_MODIFY_REG
-#define HAVE_PRE_MODIFY_DISP
-#define HAVE_POST_MODIFY_DISP
+#define HAVE_POST_INCREMENT 1
+#define HAVE_PRE_INCREMENT 1
+#define HAVE_POST_DECREMENT 1
+#define HAVE_PRE_DECREMENT 1
+#define HAVE_PRE_MODIFY_REG 1
+#define HAVE_POST_MODIFY_REG 1
+#define HAVE_PRE_MODIFY_DISP 1
+#define HAVE_POST_MODIFY_DISP 1
+
+#define HAVE_MULTIPLE_PACK 2
/* What about LABEL_REF? */
#define CONSTANT_ADDRESS_P(X) (GET_CODE (X) == SYMBOL_REF)
@@ -1599,17 +1673,44 @@ extern struct rtx_def *c4x_legitimize_address ();
/* Nonzero if the constant value X is a legitimate general operand.
It is given that X satisfies CONSTANT_P or is a CONST_DOUBLE.
- The C4x can only load 16-bit immediate values, so we only allow
- a restricted subset of CONST_INT and CONST_DOUBLE and reject
- LABEL_REF, SYMBOL_REF, CONST, and HIGH codes. */
+ The C4x can only load 16-bit immediate values, so we only allow a
+ restricted subset of CONST_INT and CONST_DOUBLE. Disallow
+ LABEL_REF and SYMBOL_REF (except on the C40 with the big memory
+ model) so that the symbols will be forced into the constant pool.
+ On second thoughts, lets do this with the move expanders.
+*/
#define LEGITIMATE_CONSTANT_P(X) \
- (GET_CODE (X) == CONST_DOUBLE && c4x_H_constant (X) \
- || GET_CODE (X) == CONST_INT && c4x_I_constant (X))
-
+ ((GET_CODE (X) == CONST_DOUBLE && c4x_H_constant (X)) \
+ || (GET_CODE (X) == CONST_INT && c4x_I_constant (X)) \
+ || (GET_CODE (X) == SYMBOL_REF) \
+ || (GET_CODE (X) == LABEL_REF) \
+ || (GET_CODE (X) == CONST) \
+ || (GET_CODE (X) == HIGH && ! TARGET_C3X) \
+ || (GET_CODE (X) == LO_SUM && ! TARGET_C3X))
#define LEGITIMATE_DISPLACEMENT_P(X) IS_DISP8_CONST (INTVAL (X))
+/* Define this macro if references to a symbol must be treated
+ differently depending on something about the variable or
+ function named by the symbol (such as what section it is in).
+
+ The macro definition, if any, is executed immediately after the
+ rtl for DECL or other node is created.
+ The value of the rtl will be a `mem' whose address is a
+ `symbol_ref'.
+
+ The usual thing for this macro to do is to a flag in the
+ `symbol_ref' (such as `SYMBOL_REF_FLAG') or to store a modified
+ name string in the `symbol_ref' (if one bit is not enough
+ information).
+
+ On the C4x we use this to indicate if a symbol is in text or
+ data space. */
+
+extern void c4x_encode_section_info ();
+#define ENCODE_SECTION_INFO(DECL) c4x_encode_section_info (DECL);
+
/* Descripting Relative Cost of Operations */
/* Provide the costs of a rtl expression. This is in the body of a
@@ -1625,10 +1726,22 @@ extern struct rtx_def *c4x_legitimize_address ();
#define RTX_COSTS(RTX, CODE, OUTER_CODE) \
+ case PLUS: \
+ case MINUS: \
+ case AND: \
+ case IOR: \
+ case XOR: \
+ case ASHIFT: \
+ case ASHIFTRT: \
+ case LSHIFTRT: \
+ return COSTS_N_INSNS (1); \
case MULT: \
return COSTS_N_INSNS (GET_MODE_CLASS (GET_MODE (RTX)) == MODE_FLOAT \
|| TARGET_MPYI ? 1 : 14); \
- case DIV: case UDIV: case MOD: case UMOD: \
+ case DIV: \
+ case UDIV: \
+ case MOD: \
+ case UMOD: \
return COSTS_N_INSNS (GET_MODE_CLASS (GET_MODE (RTX)) == MODE_FLOAT \
? 15 : 50);
@@ -1699,11 +1812,10 @@ if (REG_P (OP1) && ! REG_P (OP0)) \
#define EXPENSIVE_CLASS_P(CLASS) (ADDR_CLASS_P(CLASS) \
|| INDEX_CLASS_P(CLASS) || (CLASS) == SP_REG)
-/* Make the Rx register a little easier to use so they are used for
- calculations and the ARx registers are used for addressing. */
+/* Compute extra cost of moving data between one register class
+ and another. */
-#define REGISTER_MOVE_COST(FROM, TO) \
-(EXPENSIVE_CLASS_P(TO) ? 5 : EXPENSIVE_CLASS_P(FROM) ? 4 : 3)
+#define REGISTER_MOVE_COST(FROM, TO) 2
/* Memory move cost is same as fast register move. Maybe this should
be bumped up? */
@@ -1774,7 +1886,7 @@ do { \
} while (0)
/* The TI tooling uses atexit. */
-#define ON_EXIT(FUNC,ARG) atexit (FUNC)
+#define HAVE_ATEXIT
#undef EXTRA_SECTIONS
#define EXTRA_SECTIONS in_const, in_init, in_fini, in_ctors, in_dtors
@@ -1816,7 +1928,7 @@ void \
const_section () \
{ \
extern void text_section(); \
- if (!USE_CONST_SECTION) \
+ if (! USE_CONST_SECTION) \
text_section(); \
else if (in_section != in_const) \
{ \
@@ -1896,10 +2008,10 @@ dtors_section () \
else if (TREE_CODE (DECL) == VAR_DECL) \
{ \
if ((0 && RELOC) /* should be (flag_pic && RELOC) */ \
- || !TREE_READONLY (DECL) || TREE_SIDE_EFFECTS (DECL) \
- || !DECL_INITIAL (DECL) \
+ || ! TREE_READONLY (DECL) || TREE_SIDE_EFFECTS (DECL) \
+ || ! DECL_INITIAL (DECL) \
|| (DECL_INITIAL (DECL) != error_mark_node \
- && !TREE_CONSTANT (DECL_INITIAL (DECL)))) \
+ && ! TREE_CONSTANT (DECL_INITIAL (DECL)))) \
data_section (); \
else \
const_section (); \
@@ -1951,7 +2063,7 @@ dtors_section () \
may have quietly changed this register on the sly. */
#define ASM_IDENTIFY_GCC(FILE) \
- if (!TARGET_TI) fputs ("gcc2_compiled.:\n", FILE); \
+ if (! TARGET_TI) fputs ("gcc2_compiled.:\n", FILE); \
fputs ("\t.data\ndata_sec:\n", FILE);
#define ASM_COMMENT_START ";"
@@ -1965,7 +2077,7 @@ dtors_section () \
{ long l; \
char str[30]; \
REAL_VALUE_TO_TARGET_SINGLE (VALUE, l); \
- REAL_VALUE_TO_DECIMAL (VALUE, "%20f", str); \
+ REAL_VALUE_TO_DECIMAL (VALUE, "%20lf", str); \
if (sizeof (int) == sizeof (long)) \
fprintf (FILE, "\t.word\t0%08xh\t; %s\n", l, str);\
else \
@@ -1984,7 +2096,7 @@ dtors_section () \
{ long l[2]; \
char str[30]; \
REAL_VALUE_TO_TARGET_DOUBLE (VALUE, l); \
- REAL_VALUE_TO_DECIMAL (VALUE, "%20f", str); \
+ REAL_VALUE_TO_DECIMAL (VALUE, "%20lf", str); \
l[1] = (l[0] << 8) | ((l[1] >> 24) & 0xff); \
if (sizeof (int) == sizeof (long)) \
fprintf (FILE, "\t.word\t0%08xh\t; %s\n\t.word\t0%08xh\n", \
@@ -2427,8 +2539,6 @@ do { fprintf (asm_out_file, "\t.sdef\t"); \
#define MACHINE_DEPENDENT_REORG(INSNS) c4x_process_after_reload(INSNS)
-#define MACHINE_DEPENDENT_COMBINE(INSNS) c4x_combine_parallel(INSNS)
-
#define DBR_OUTPUT_SEQEND(FILE) \
if (final_sequence != NULL_RTX) \
{ \
@@ -2447,11 +2557,6 @@ if (final_sequence != NULL_RTX) \
#define NO_FUNCTION_CSE
-/* Repeat block stuff (hook into strength_reduce() in loop.c). */
-
-extern void c4x_rptb_process ();
-#define REPEAT_BLOCK_PROCESS(START, END) c4x_rptb_process(START, END)
-
/* We don't want a leading tab. */
#define ASM_OUTPUT_ASM(FILE, STRING) fprintf (FILE, "%s\n", STRING)
@@ -2475,7 +2580,8 @@ extern void c4x_rptb_process ();
{"dp_reg_operand", {REG}}, \
{"sp_reg_operand", {REG}}, \
{"st_reg_operand", {REG}}, \
- {"call_operand", {REG, SYMBOL_REF}}, \
+ {"rc_reg_operand", {REG}}, \
+ {"call_address_operand", {REG, SYMBOL_REF, LABEL_REF, CONST}}, \
{"src_operand", {SUBREG, REG, MEM, CONST_INT, CONST_DOUBLE}}, \
{"src_hi_operand", {SUBREG, REG, MEM, CONST_DOUBLE}}, \
{"lsrc_operand", {SUBREG, REG, MEM, CONST_INT, CONST_DOUBLE}}, \
@@ -2483,7 +2589,8 @@ extern void c4x_rptb_process ();
{"any_operand", {SUBREG, REG, MEM, CONST_INT, CONST_DOUBLE}}, \
{"par_ind_operand", {MEM}}, \
{"parallel_operand", {SUBREG, REG, MEM}}, \
- {"mem_operand", {MEM}}, \
+ {"symbolic_address_operand", {SYMBOL_REF, LABEL_REF, CONST}}, \
+ {"mem_operand", {MEM}},
/* Variables in c4x.c */
@@ -2535,6 +2642,10 @@ extern int stik_const_operand ();
extern int not_const_operand ();
+extern int parallel_operand ();
+
+extern int reg_or_const_operand ();
+
extern int reg_operand ();
extern int reg_imm_operand ();
@@ -2551,6 +2662,8 @@ extern int std_reg_operand ();
extern int src_operand ();
+extern int src_hi_operand ();
+
extern int lsrc_operand ();
extern int tsrc_operand ();
@@ -2563,12 +2676,66 @@ extern int dp_reg_operand ();
extern int sp_reg_operand ();
+extern int rc_reg_operand ();
+
extern int st_reg_operand ();
-extern int call_operand ();
+extern int symbolic_address_operand ();
+
+extern int ar0_reg_operand ();
+
+extern int ar0_mem_operand ();
+
+extern int ar1_reg_operand ();
+
+extern int ar1_mem_operand ();
+
+extern int ar2_reg_operand ();
+
+extern int ar2_mem_operand ();
+
+extern int ar3_reg_operand ();
+
+extern int ar3_mem_operand ();
+
+extern int ar4_reg_operand ();
+
+extern int ar4_mem_operand ();
+
+extern int ar5_reg_operand ();
+
+extern int ar5_mem_operand ();
+
+extern int ar6_reg_operand ();
+
+extern int ar6_mem_operand ();
+
+extern int ar7_reg_operand ();
+
+extern int ar7_mem_operand ();
+
+extern int ir0_reg_operand ();
+
+extern int ir0_mem_operand ();
+
+extern int ir1_reg_operand ();
+
+extern int ir1_mem_operand ();
+
+extern int group1_reg_operand ();
+
+extern int group1_mem_operand ();
+
+extern int arx_reg_operand ();
+
+extern int call_address_operand ();
extern int par_ind_operand ();
+extern int not_rc_reg ();
+
+extern int not_modify_reg ();
+
extern int c4x_H_constant ();
extern int c4x_I_constant ();
@@ -2585,22 +2752,22 @@ extern int c4x_S_constraint ();
extern int c4x_T_constraint ();
+extern int c4x_U_constraint ();
+
extern void c4x_emit_libcall ();
extern void c4x_emit_libcall3 ();
extern void c4x_emit_libcall_mulhi ();
-extern int c4x_group1_reg_operand ();
-
-extern int c4x_group1_mem_operand ();
-
-extern int c4x_arx_reg_operand ();
+extern int c4x_emit_move_sequence ();
extern int legitimize_operands ();
extern int valid_operands ();
+extern int valid_parallel_load_store ();
+
extern int valid_parallel_operands_4 ();
extern int valid_parallel_operands_5 ();
diff --git a/gcc/config/c4x/c4x.md b/gcc/config/c4x/c4x.md
index 21e62eacc7d..51cb0245408 100644
--- a/gcc/config/c4x/c4x.md
+++ b/gcc/config/c4x/c4x.md
@@ -1,7 +1,7 @@
;; Machine description for the TMS320C[34]x for GNU C compiler
-;; Copyright (C) 1994, 1995, 1996, 1997 Free Software Foundation, Inc.
+;; Copyright (C) 1994-98, 1999 Free Software Foundation, Inc.
-;; Contributed by Michael Hayes (m.hayes@elec.canterbury.cri.nz)
+;; Contributed by Michael Hayes (m.hayes@elec.canterbury.ac.nz)
;; and Herman Ten Brugge (Haj.Ten.Brugge@net.HCC.nl)
;; This file is part of GNU CC.
@@ -23,7 +23,6 @@
;
; TODO :
-; Set up addressing macros to handle direct memory references properly
; Try using PQImode again for addresses since C30 only uses
; 24-bit addresses. Ideally GCC would emit different insns
; for QImode and Pmode, whether Pmode was QImode or PQImode.
@@ -66,7 +65,7 @@
; st_reg_operand ST [y]
; dp_reg_operand DP [z]
; stik_const_operand 5-bit const [K]
-; src_operand general operand [rfmHI]
+; src_operand general operand [rfHmI]
; par_ind_operand indirect S mode (ARx + 0, 1, IRx) [S<>]
; parallel_operand par_ind_operand or ext_low_reg_operand
@@ -90,16 +89,25 @@
; b stack pointer SP
; c other int reg AR0-AR7, IR0-IR1, RC, RS, RE
; d fp reg R0-R11 (sets CC when dst)
+; e
; f fp reg R0-R11 (sets CC when dst)
; g general reg, memory, constant
-; h fp reg R0-R11 (sets CC when dst)
+; h fp reg (HFmode) R0-R11 (sets CC when dst)
; i immediate int constant
+; j
+; k block count BK
+; l
; m memory
+; n immediate int constant with known numeric value
+; o offsettable memory
+; p memory address
; q low fp reg R0-R7 (sets CC when dst)
; r general reg R0-R11, AR0-AR7, IR0-IR1, RC, RS, RE
-; s immediate int (value not explicit)
+; s immediate int constant (value not explicit)
; t R0-R1
; u R2-R3
+; v repeat count reg RC
+; w
; x index reg IR0-IR1
; y status (CC) reg ST
; z data pointer DP
@@ -116,14 +124,20 @@
; Q ARx + 9-bit signed disp
; R ARx + 5-bit unsigned disp (C4x only)
; S ARx + 0, 1, IRx disp
-; T symbol ref (direct)
+; T direct memory operand
+; V non offsettable memory
+; X any operand
; < memory operand with autodecrement addressing
; > memory operand with autoincrement addressing
; { memory operand with pre-modify addressing
; } memory operand with post-modify addressing
-; Note that the d, f, and h constraints are equivalent.
-; The m constraint is equivalent to QT<>{}
+; Note that the 'd', 'f', and 'h' constraints are equivalent.
+; The m constraint is equivalent to 'QT<>{}'
+
+; Note we cannot use the 'g' constraint with Pmode (i.e, QImode)
+; operations since LEGITIMATE_CONSTANT_P accepts SYMBOL_REF.
+; So instead we use 'rIm' for signed operands or 'rLm' for unsigned operands.
; Note that the constraints are used to select the operands
; for a chosen pattern. The constraint that requires the fewest
@@ -331,7 +345,7 @@
(const_string "false")))
(define_attr "not_repeat_reg" "false,true"
- (cond [(eq_attr "type" "unary,unarycc,compare,lda,store")
+ (cond [(eq_attr "type" "unary,unarycc,compare,lda,ldp,store")
(if_then_else (and (match_operand 0 "not_rc_reg" "")
(match_operand 1 "not_rc_reg" ""))
(const_string "true") (const_string "false"))
@@ -342,6 +356,9 @@
(const_string "true") (const_string "false"))]
(const_string "false")))
+/* Disable compare because the c4x contains a bug. The cmpi insn sets the CC
+ in the read phase of the pipeline instead of the execution phase when
+ two registers are compared. */
(define_attr "in_annul_slot_1" "false,true"
(if_then_else (and (and (eq_attr "cpu" "c4x")
(eq_attr "type" "!jump,call,rets,jmpc,compare,db,dbc,repeat,repeat_top,laj,push,pop,lda,ldp,multi"))
@@ -358,7 +375,7 @@
(define_attr "in_annul_slot_3" "false,true"
(if_then_else (and (eq_attr "cpu" "c4x")
- (eq_attr "type" "!jump,call,rets,jmpc,unarycc,binarycc,compare,db,dbc,repeat,repeat_top,laj,push,pop,multi"))
+ (eq_attr "type" "!jump,call,rets,jmpc,db,dbc,repeat,repeat_top,laj,push,pop,multi"))
(const_string "true")
(const_string "false")))
@@ -1063,6 +1080,14 @@
(const_int 1) (const_int 0))]
(const_int 0)))
+
+;
+; C4x INSN PATTERNS:
+;
+; Note that the movMM and addP patterns can be called during reload
+; so we need to take special care with theses patterns since
+; we cannot blindly clobber CC or generate new pseudo registers.
+
;
; TWO OPERAND INTEGER INSTRUCTIONS
;
@@ -1073,43 +1098,87 @@
(define_insn "set_ldp"
[(set (match_operand:QI 0 "dp_reg_operand" "=z")
(high:QI (match_operand:QI 1 "" "")))]
- "!TARGET_SMALL"
+ "! TARGET_SMALL"
"* return (TARGET_C3X) ? \"ldp\\t%A1\" : \"ldpk\\t%A1\";"
[(set_attr "type" "ldp")])
-
-; Used when moving a constant label reference to an external
-; location, this will make sure the original label is still
-; used so the optimizer will not optimize it away.
-;
-(define_insn "set_ldp_use"
- [(parallel [(set (match_operand:QI 0 "dp_reg_operand" "=z")
- (high:QI (match_operand:QI 1 "" "")))
- (use (match_operand 2 "" ""))])]
- "!TARGET_SMALL"
- "* return (TARGET_C3X) ? \"ldp\\t%A1\" : \"ldpk\\t%A1\";"
- [(set_attr "type" "ldp")])
-
-(define_insn "set_high_use"
- [(parallel [(set (match_operand:QI 0 "std_reg_operand" "=c")
- (high:QI (match_operand:QI 1 "" "")))
- (use (match_operand 2 "" ""))])]
- "!TARGET_C3X && !TARGET_SMALL"
+(define_insn "set_high"
+ [(set (match_operand:QI 0 "std_reg_operand" "=c")
+ (high:QI (match_operand:QI 1 "symbolic_address_operand" "")))]
+ "! TARGET_C3X "
"ldhi\\t^%H1,%0"
[(set_attr "type" "unary")])
-(define_insn "set_ior_lo_use"
- [(parallel [(set (match_operand:QI 0 "std_reg_operand" "=c")
- (ior:QI (match_dup 0)
- (and:QI (match_operand:QI 1 "" "")
- (const_int 65535))))
- (use (match_operand 2 "" ""))])]
- "!TARGET_C3X && !TARGET_SMALL"
+(define_insn "set_lo_sum"
+ [(set (match_operand:QI 0 "std_reg_operand" "=c")
+ (lo_sum:QI (match_dup 0)
+ (match_operand:QI 1 "symbolic_address_operand" "")))]
+ ""
"or\\t#%H1,%0"
[(set_attr "type" "unary")])
+(define_split
+ [(set (match_operand:QI 0 "std_reg_operand" "")
+ (match_operand:QI 1 "symbolic_address_operand" ""))]
+ "! TARGET_C3X"
+ [(set (match_dup 0) (high:QI (match_dup 1)))
+ (set (match_dup 0) (lo_sum:QI (match_dup 0) (match_dup 1)))]
+ "")
+
+; This pattern is required to handle the case where a register that clobbers
+; CC has been selected to load a symbolic address. We force the address
+; into memory and then generate LDP and LDIU insns.
+; This is also required for the C30 if we pretend that we can
+; easily load symbolic addresses into a register.
+(define_split
+ [(set (match_operand:QI 0 "reg_operand" "")
+ (match_operand:QI 1 "symbolic_address_operand" ""))]
+ "! TARGET_SMALL
+ && (TARGET_C3X || (reload_completed
+ && ! std_reg_operand (operands[0], QImode)))"
+ [(set (match_dup 2) (high:QI (match_dup 3)))
+ (set (match_dup 0) (match_dup 4))
+ (use (match_dup 1))]
+ "
+{
+ rtx dp_reg = gen_rtx_REG (Pmode, DP_REGNO);
+ operands[2] = dp_reg;
+ operands[3] = force_const_mem (Pmode, operands[1]);
+ operands[4] = change_address (operands[3], QImode,
+ gen_rtx_LO_SUM (Pmode, dp_reg,
+ XEXP (operands[3], 0)));
+ operands[3] = XEXP (operands[3], 0);
+}")
+
+; This pattern is similar to the above but does not emit a LDP
+; for the small memory model.
+(define_split
+ [(set (match_operand:QI 0 "reg_operand" "")
+ (match_operand:QI 1 "symbolic_address_operand" ""))]
+ "TARGET_SMALL
+ && (TARGET_C3X || (reload_completed
+ && ! std_reg_operand (operands[0], QImode)))"
+ [(set (match_dup 0) (match_dup 2))
+ (use (match_dup 1))]
+ "
+{
+ rtx dp_reg = gen_rtx_REG (Pmode, DP_REGNO);
+ operands[2] = force_const_mem (Pmode, operands[1]);
+ operands[2] = change_address (operands[2], QImode,
+ gen_rtx_LO_SUM (Pmode, dp_reg,
+ XEXP (operands[2], 0)));
+}")
+
+(define_insn "load_immed_address"
+ [(set (match_operand:QI 0 "reg_operand" "=a?x?c*r")
+ (match_operand:QI 1 "symbolic_address_operand" ""))]
+ "TARGET_LOAD_ADDRESS"
+ "#"
+ [(set_attr "type" "multi")])
+
;
; LDIU/LDA/STI/STIK
+;
; The following moves will not set the condition codes register.
;
@@ -1117,7 +1186,7 @@
(define_insn "*movqi_stik"
[(set (match_operand:QI 0 "memory_operand" "=m")
(match_operand:QI 1 "stik_const_operand" "K"))]
- "!TARGET_C3X"
+ "! TARGET_C3X"
"stik\\t%1,%0"
[(set_attr "type" "store")])
@@ -1125,23 +1194,24 @@
; spill a register.
(define_insn "movqi_noclobber"
[(set (match_operand:QI 0 "src_operand" "=d,*c,m,r")
- (match_operand:QI 1 "src_hi_operand" "rmI,rmI,r,O"))]
- "reg_operand (operands[0], QImode)
- || reg_operand (operands[1], QImode)"
+ (match_operand:QI 1 "src_hi_operand" "rIm,rIm,r,O"))]
+ "(REG_P (operands[0]) || REG_P (operands[1])
+ || GET_CODE (operands[0]) == SUBREG
+ || GET_CODE (operands[1]) == SUBREG)
+ && ! symbolic_address_operand (operands[1], QImode)"
"*
if (which_alternative == 2)
return \"sti\\t%1,%0\";
- if (!TARGET_C3X && which_alternative == 3)
+ if (! TARGET_C3X && which_alternative == 3)
{
- operands[1] = gen_rtx (CONST_INT, VOIDmode,
- (INTVAL (operands[1]) >> 16) & 0xffff);
+ operands[1] = GEN_INT ((INTVAL (operands[1]) >> 16) & 0xffff);
return \"ldhi\\t%1,%0\";
}
/* The lda instruction cannot use the same register as source
and destination. */
- if (!TARGET_C3X && which_alternative == 1
+ if (! TARGET_C3X && which_alternative == 1
&& ( IS_ADDR_REG (REGNO (operands[0]))
|| IS_INDEX_REG (REGNO (operands[0]))
|| IS_SP_REG (REGNO (operands[0])))
@@ -1159,7 +1229,7 @@
; We shouldn't need these peepholes, but the combiner seems to miss them...
(define_peephole
[(set (match_operand:QI 0 "ext_reg_operand" "=d")
- (match_operand:QI 1 "src_operand" "g"))
+ (match_operand:QI 1 "src_operand" "rIm"))
(set (reg:CC 21)
(compare:CC (match_dup 0) (const_int 0)))]
""
@@ -1170,7 +1240,7 @@
(define_insn "*movqi_set"
[(set (reg:CC 21)
- (compare:CC (match_operand:QI 1 "src_operand" "g")
+ (compare:CC (match_operand:QI 1 "src_operand" "rIm")
(const_int 0)))
(set (match_operand:QI 0 "ext_reg_operand" "=d")
(match_dup 1))]
@@ -1184,7 +1254,7 @@
; when a simple compare with zero will suffice.
;(define_insn "*movqi_test"
; [(set (reg:CC 21)
-; (compare:CC (match_operand:QI 1 "src_operand" "g")
+; (compare:CC (match_operand:QI 1 "src_operand" "rIm")
; (const_int 0)))
; (clobber (match_scratch:QI 0 "=d"))]
; ""
@@ -1204,28 +1274,14 @@
; the compiler, have memoized the insn number already.
(define_expand "movqi"
- [(set (match_operand:QI 0 "src_operand" "")
- (match_operand:QI 1 "src_operand" ""))]
+ [(set (match_operand:QI 0 "general_operand" "")
+ (match_operand:QI 1 "general_operand" ""))]
""
"
- /* We shouldn't have to do this, since reload is supposed to
- be able to do this if we have a memory constraint. */
- if (CONSTANT_P (operands[1])
- && !const_operand (operands[1], QImode))
- {
- operands[1] = force_const_mem (QImode, operands[1]);
- if (!memory_address_p (QImode, XEXP (operands[1], 0))
- && !reload_in_progress)
- operands[1] = change_address (operands[1], QImode,
- XEXP (operands[1], 0));
- }
-
- if (!reload_in_progress
- && !reg_operand (operands[0], QImode)
- && !reg_operand (operands[1], QImode)
- && !(stik_const_operand (operands[1], QImode)
- && !push_operand (operands[0], QImode)))
- operands[1] = force_reg (QImode, operands[1]);")
+{
+ if (c4x_emit_move_sequence (operands, QImode))
+ DONE;
+}")
(define_insn "*movqi_update"
[(set (match_operand:QI 0 "reg_operand" "=r")
@@ -1243,7 +1299,7 @@
(match_operand:QI 1 "parallel_operand" "S<>,q,S<>,q"))
(set (match_operand:QI 2 "parallel_operand" "=q,S<>,S<>,q")
(match_operand:QI 3 "parallel_operand" "S<>,q,q,S<>"))]
- "valid_parallel_operands_4 (operands, QImode)"
+ "valid_parallel_load_store (operands, QImode)"
"@
ldi1\\t%1,%0\\n||\\tldi2\\t%3,%2
sti1\\t%1,%0\\n||\\tsti2\\t%3,%2
@@ -1281,7 +1337,7 @@
(define_insn "*absqi2_clobber"
[(set (match_operand:QI 0 "reg_operand" "=d,c")
- (abs:QI (match_operand:QI 1 "src_operand" "g,g")))
+ (abs:QI (match_operand:QI 1 "src_operand" "rIm,rIm")))
(clobber (reg:CC_NOOV 21))]
""
"absi\\t%1,%0"
@@ -1290,7 +1346,7 @@
(define_insn "*absqi2_test"
[(set (reg:CC_NOOV 21)
- (compare:CC_NOOV (abs:QI (match_operand:QI 1 "src_operand" "g"))
+ (compare:CC_NOOV (abs:QI (match_operand:QI 1 "src_operand" "rIm"))
(const_int 0)))
(clobber (match_scratch:QI 0 "=d"))]
""
@@ -1300,7 +1356,7 @@
(define_insn "*absqi2_set"
[(set (reg:CC_NOOV 21)
- (compare:CC_NOOV (abs:QI (match_operand:QI 1 "src_operand" "g"))
+ (compare:CC_NOOV (abs:QI (match_operand:QI 1 "src_operand" "rIm"))
(const_int 0)))
(set (match_operand:QI 0 "ext_reg_operand" "=d")
(abs:QI (match_dup 1)))]
@@ -1321,7 +1377,7 @@
(define_insn "*negqi2_clobber"
[(set (match_operand:QI 0 "reg_operand" "=d,c")
- (neg:QI (match_operand:QI 1 "src_operand" "g,g")))
+ (neg:QI (match_operand:QI 1 "src_operand" "rIm,rIm")))
(clobber (reg:CC_NOOV 21))]
""
"negi\\t%1,%0"
@@ -1330,7 +1386,7 @@
(define_insn "*negqi2_test"
[(set (reg:CC_NOOV 21)
- (compare:CC_NOOV (neg:QI (match_operand:QI 1 "src_operand" "g"))
+ (compare:CC_NOOV (neg:QI (match_operand:QI 1 "src_operand" "rIm"))
(const_int 0)))
(clobber (match_scratch:QI 0 "=d"))]
""
@@ -1340,7 +1396,7 @@
(define_insn "*negqi2_set"
[(set (reg:CC_NOOV 21)
- (compare:CC_NOOV (neg:QI (match_operand:QI 1 "src_operand" "g"))
+ (compare:CC_NOOV (neg:QI (match_operand:QI 1 "src_operand" "rIm"))
(const_int 0)))
(set (match_operand:QI 0 "ext_reg_operand" "=d")
(neg:QI (match_dup 1)))]
@@ -1351,7 +1407,7 @@
(define_insn "*negbqi2_clobber"
[(set (match_operand:QI 0 "ext_reg_operand" "=d")
- (neg:QI (match_operand:QI 1 "src_operand" "g")))
+ (neg:QI (match_operand:QI 1 "src_operand" "rIm")))
(use (reg:CC_NOOV 21))
(clobber (reg:CC_NOOV 21))]
""
@@ -1371,7 +1427,7 @@
(define_insn "*one_cmplqi2_clobber"
[(set (match_operand:QI 0 "reg_operand" "=d,c")
- (not:QI (match_operand:QI 1 "lsrc_operand" "g,g")))
+ (not:QI (match_operand:QI 1 "lsrc_operand" "rLm,rLm")))
(clobber (reg:CC 21))]
""
"not\\t%1,%0"
@@ -1380,7 +1436,7 @@
(define_insn "*one_cmplqi2_test"
[(set (reg:CC 21)
- (compare:CC (not:QI (match_operand:QI 1 "lsrc_operand" "g"))
+ (compare:CC (not:QI (match_operand:QI 1 "lsrc_operand" "rLm"))
(const_int 0)))
(clobber (match_scratch:QI 0 "=d"))]
""
@@ -1390,7 +1446,7 @@
(define_insn "*one_cmplqi2_set"
[(set (reg:CC 21)
- (compare:CC (not:QI (match_operand:QI 1 "lsrc_operand" "g"))
+ (compare:CC (not:QI (match_operand:QI 1 "lsrc_operand" "rLm"))
(const_int 0)))
(set (match_operand:QI 0 "ext_reg_operand" "=d")
(not:QI (match_dup 1)))]
@@ -1439,19 +1495,26 @@
(match_operand:QI 2 "const_int_operand" "")))
(clobber (reg:CC 21))])]
""
- "if (INTVAL (operands[2]) >= 4)
+ "if (INTVAL (operands[2]) > 4)
FAIL; /* Open code as two shifts and an or */
if (INTVAL (operands[2]) > 1)
{
int i;
+ rtx tmp;
/* If we have 4 or fewer shifts, then it is probably faster
to emit separate ROL instructions. A C3x requires
at least 4 instructions (a C4x requires at least 3), to
perform a rotation by shifts. */
- for (i = 0; i < INTVAL (operands[2]); i++)
- emit_insn (gen_rotl_1_clobber (operands[0], operands[1]));
+ tmp = operands[1];
+ for (i = 0; i < INTVAL (operands[2]) - 1; i++)
+ {
+ tmp = gen_reg_rtx (QImode);
+ emit_insn (gen_rotl_1_clobber (tmp, operands[1]));
+ operands[1] = tmp;
+ }
+ emit_insn (gen_rotl_1_clobber (operands[0], tmp));
DONE;
}")
@@ -1474,19 +1537,26 @@
(match_operand:QI 2 "const_int_operand" "")))
(clobber (reg:CC 21))])]
""
- "if (INTVAL (operands[2]) >= 4)
+ "if (INTVAL (operands[2]) > 4)
FAIL; /* Open code as two shifts and an or */
if (INTVAL (operands[2]) > 1)
{
int i;
+ rtx tmp;
/* If we have 4 or fewer shifts, then it is probably faster
to emit separate ROL instructions. A C3x requires
at least 4 instructions (a C4x requires at least 3), to
perform a rotation by shifts. */
- for (i = 0; i < INTVAL (operands[2]); i++)
- emit_insn (gen_rotr_1_clobber (operands[0], operands[1]));
+ tmp = operands[1];
+ for (i = 0; i < INTVAL (operands[2]) - 1; i++)
+ {
+ tmp = gen_reg_rtx (QImode);
+ emit_insn (gen_rotr_1_clobber (tmp, operands[1]));
+ operands[1] = tmp;
+ }
+ emit_insn (gen_rotr_1_clobber (operands[0], tmp));
DONE;
}")
@@ -1508,18 +1578,28 @@
;
; ADDI
;
+; This is used by reload when it calls gen_add2_insn for address arithmetic
+; so we must emit the pattern that doesn't clobber CC.
+;
(define_expand "addqi3"
[(parallel [(set (match_operand:QI 0 "reg_operand" "")
(plus:QI (match_operand:QI 1 "src_operand" "")
(match_operand:QI 2 "src_operand" "")))
(clobber (reg:CC_NOOV 21))])]
""
- "legitimize_operands (PLUS, operands, QImode);")
+ "legitimize_operands (PLUS, operands, QImode);
+ if (reload_in_progress
+ || (! IS_PSEUDO_REGNO (operands[0])
+ && ! IS_EXT_REG (REGNO (operands[0]))))
+ {
+ emit_insn (gen_addqi3_noclobber (operands[0], operands[1], operands[2]));
+ DONE;
+ }")
(define_insn "*addqi3_clobber"
[(set (match_operand:QI 0 "reg_operand" "=d,?d,d,c,?c,c")
(plus:QI (match_operand:QI 1 "src_operand" "%rR,rS<>,0,rR,rS<>,0")
- (match_operand:QI 2 "src_operand" "JR,rS<>,g,JR,rS<>,g")))
+ (match_operand:QI 2 "src_operand" "JR,rS<>,rIm,JR,rS<>,rIm")))
(clobber (reg:CC_NOOV 21))]
"valid_operands (PLUS, operands, QImode)"
"@
@@ -1535,7 +1615,7 @@
(define_insn "*addqi3_test"
[(set (reg:CC_NOOV 21)
(compare:CC_NOOV (plus:QI (match_operand:QI 1 "src_operand" "%rR,rS<>,0")
- (match_operand:QI 2 "src_operand" "JR,rS<>,g"))
+ (match_operand:QI 2 "src_operand" "JR,rS<>,rIm"))
(const_int 0)))
(clobber (match_scratch:QI 0 "=d,?d,d"))]
"valid_operands (PLUS, operands, QImode)"
@@ -1576,7 +1656,7 @@
(define_insn "*addqi3_set"
[(set (reg:CC_NOOV 21)
(compare:CC_NOOV (plus:QI (match_operand:QI 1 "src_operand" "%rR,rS<>,0")
- (match_operand:QI 2 "src_operand" "JR,rS<>,g"))
+ (match_operand:QI 2 "src_operand" "JR,rS<>,rIm"))
(const_int 0)))
(set (match_operand:QI 0 "ext_reg_operand" "=d,?d,d")
(plus:QI (match_dup 1) (match_dup 2)))]
@@ -1589,11 +1669,12 @@
; Default to int16 data attr.
; This pattern is required primarily for manipulating the stack pointer
-; where GCC doesn't expect CC to be clobbered.
+; where GCC doesn't expect CC to be clobbered or for calculating
+; addresses during reload.
(define_insn "addqi3_noclobber"
[(set (match_operand:QI 0 "std_reg_operand" "=c,?c,c")
(plus:QI (match_operand:QI 1 "src_operand" "%rR,rS<>,0")
- (match_operand:QI 2 "src_operand" "JR,rS<>,g")))]
+ (match_operand:QI 2 "src_operand" "JR,rS<>,rIm")))]
"valid_operands (PLUS, operands, QImode)"
"@
addi3\\t%2,%1,%0
@@ -1603,10 +1684,39 @@
; Default to int16 data attr.
+; This pattern is required during reload when eliminate_regs_in_insn
+; effectively converts a move insn into an add insn when the src
+; operand is the frame pointer plus a constant. Without this
+; pattern, gen_addqi3 can be called with a register for operand0
+; that can clobber CC.
+; For example, we may have (set (mem (reg ar0)) (reg 99))
+; with (set (reg 99) (plus (reg ar3) (const_int 8)))
+; Now since ar3, the frame pointer, is unchanging within the function,
+; (plus (reg ar3) (const_int 8)) is considered a constant.
+; eliminate_regs_in_insn substitutes this constant to give
+; (set (mem (reg ar0)) (plus (reg ar3) (const_int 8))).
+; This is an invalid C4x insn but if we don't provide a pattern
+; for it, it will be considered to be a move insn for reloading.
+; The nasty bit is that a GENERAL_REGS class register, say r0,
+; may be allocated to reload the PLUS and thus gen_reload will
+; emit an add insn that may clobber CC.
+(define_insn "*addqi3_noclobber_reload"
+ [(set (match_operand:QI 0 "general_operand" "=c,?c,c")
+ (plus:QI (match_operand:QI 1 "src_operand" "%rR,rS<>,0")
+ (match_operand:QI 2 "src_operand" "JR,rS<>,rIm")))]
+ "reload_in_progress"
+ "@
+ addi3\\t%2,%1,%0
+ addi3\\t%2,%1,%0
+ addi\\t%2,%0"
+ [(set_attr "type" "binary,binary,binary")])
+; Default to int16 data attr.
+
+
(define_insn "*addqi3_carry_clobber"
[(set (match_operand:QI 0 "reg_operand" "=d,?d,d,c,?c,c")
(plus:QI (match_operand:QI 1 "src_operand" "%rR,rS<>,0,rR,rS<>,0")
- (match_operand:QI 2 "src_operand" "JR,rS<>,g,JR,rS<>,g")))
+ (match_operand:QI 2 "src_operand" "JR,rS<>,rIm,JR,rS<>,rIm")))
(use (reg:CC_NOOV 21))
(clobber (reg:CC_NOOV 21))]
"valid_operands (PLUS, operands, QImode)"
@@ -1634,8 +1744,8 @@
(define_insn "*subqi3_clobber"
[(set (match_operand:QI 0 "reg_operand" "=d,?d,d,d,c,?c,c,c")
- (minus:QI (match_operand:QI 1 "src_operand" "rR,rS<>,0,g,rR,rS<>,0,g")
- (match_operand:QI 2 "src_operand" "JR,rS<>,g,0,JR,rS<>,g,0")))
+ (minus:QI (match_operand:QI 1 "src_operand" "rR,rS<>,0,rIm,rR,rS<>,0,rIm")
+ (match_operand:QI 2 "src_operand" "JR,rS<>,rIm,0,JR,rS<>,rIm,0")))
(clobber (reg:CC_NOOV 21))]
"valid_operands (MINUS, operands, QImode)"
"@
@@ -1652,8 +1762,8 @@
(define_insn "*subqi3_test"
[(set (reg:CC_NOOV 21)
- (compare:CC_NOOV (minus:QI (match_operand:QI 1 "src_operand" "rR,rS<>,0,g")
- (match_operand:QI 2 "src_operand" "JR,rS<>,g,0"))
+ (compare:CC_NOOV (minus:QI (match_operand:QI 1 "src_operand" "rR,rS<>,0,rIm")
+ (match_operand:QI 2 "src_operand" "JR,rS<>,rIm,0"))
(const_int 0)))
(clobber (match_scratch:QI 0 "=d,?d,d,d"))]
"valid_operands (MINUS, operands, QImode)"
@@ -1667,8 +1777,8 @@
(define_peephole
[(parallel [(set (match_operand:QI 0 "ext_reg_operand" "=d,?d,d,d")
- (minus:QI (match_operand:QI 1 "src_operand" "rR,rS<>,0,g")
- (match_operand:QI 2 "src_operand" "JR,rS<>,g,0")))
+ (minus:QI (match_operand:QI 1 "src_operand" "rR,rS<>,0,rIm")
+ (match_operand:QI 2 "src_operand" "JR,rS<>,rIm,0")))
(clobber (reg:CC_NOOV 21))])
(set (reg:CC_NOOV 21)
(compare:CC_NOOV (match_dup 0) (const_int 0)))]
@@ -1682,8 +1792,8 @@
(define_insn "*subqi3_set"
[(set (reg:CC_NOOV 21)
- (compare:CC_NOOV (minus:QI (match_operand:QI 1 "src_operand" "rR,rS<>,0,g")
- (match_operand:QI 2 "src_operand" "JR,rS<>,g,0"))
+ (compare:CC_NOOV (minus:QI (match_operand:QI 1 "src_operand" "rR,rS<>,0,rIm")
+ (match_operand:QI 2 "src_operand" "JR,rS<>,rIm,0"))
(const_int 0)))
(set (match_operand:QI 0 "ext_reg_operand" "=d,?d,d,d")
(minus:QI (match_dup 1)
@@ -1699,8 +1809,8 @@
(define_insn "*subqi3_carry_clobber"
[(set (match_operand:QI 0 "reg_operand" "=d,?d,d,d,c,?c,c,c")
- (minus:QI (match_operand:QI 1 "src_operand" "rR,rS<>,0,g,rR,rS<>,0,g")
- (match_operand:QI 2 "src_operand" "JR,rS<>,0,g,JR,rS<>,g,0")))
+ (minus:QI (match_operand:QI 1 "src_operand" "rR,rS<>,0,rIm,rR,rS<>,0,rIm")
+ (match_operand:QI 2 "src_operand" "JR,rS<>,rIm,0,JR,rS<>,rIm,0")))
(use (reg:CC_NOOV 21))
(clobber (reg:CC_NOOV 21))]
"valid_operands (MINUS, operands, QImode)"
@@ -1718,8 +1828,8 @@
(define_insn "*subqi3_carry_set"
[(set (reg:CC_NOOV 21)
- (compare:CC_NOOV (minus:QI (match_operand:QI 1 "src_operand" "rR,rS<>,0,g")
- (match_operand:QI 2 "src_operand" "JR,rS<>,g,0"))
+ (compare:CC_NOOV (minus:QI (match_operand:QI 1 "src_operand" "rR,rS<>,0,rIm")
+ (match_operand:QI 2 "src_operand" "JR,rS<>,rIm,0"))
(const_int 0)))
(set (match_operand:QI 0 "ext_reg_operand" "=d,?d,d,d")
(minus:QI (match_dup 1)
@@ -1758,13 +1868,13 @@
if (operands[1] == operands[2])
{
/* Do the squaring operation in-line. */
- emit_insn (gen_sqrqi2_inline(operands[0], operands[1]));
+ emit_insn (gen_sqrqi2_inline (operands[0], operands[1]));
DONE;
}
if (TARGET_INLINE)
{
- emit_insn (gen_mulqi3_inline(operands[0], operands[1],
- operands[2]));
+ emit_insn (gen_mulqi3_inline (operands[0], operands[1],
+ operands[2]));
DONE;
}
c4x_emit_libcall3 (MULQI3_LIBCALL, MULT, QImode, operands);
@@ -1775,7 +1885,7 @@
(define_insn "*mulqi3_clobber"
[(set (match_operand:QI 0 "reg_operand" "=d,?d,d,c,?c,c")
(mult:QI (match_operand:QI 1 "src_operand" "%rR,rS<>,0,rR,rS<>,0")
- (match_operand:QI 2 "src_operand" "JR,rS<>,g,JR,rS<>,g")))
+ (match_operand:QI 2 "src_operand" "JR,rS<>,rIm,JR,rS<>,rIm")))
(clobber (reg:CC_NOOV 21))]
"valid_operands (MULT, operands, QImode)"
"*
@@ -1796,7 +1906,7 @@
(define_insn "*mulqi3_test"
[(set (reg:CC_NOOV 21)
(compare:CC_NOOV (mult:QI (match_operand:QI 1 "src_operand" "%rR,rS<>,0")
- (match_operand:QI 2 "src_operand" "JR,rS<>,g"))
+ (match_operand:QI 2 "src_operand" "JR,rS<>,rIm"))
(const_int 0)))
(clobber (match_scratch:QI 0 "=d,?d,d"))]
"valid_operands (MULT, operands, QImode)"
@@ -1818,7 +1928,7 @@
(define_insn "*mulqi3_set"
[(set (reg:CC_NOOV 21)
(compare:CC_NOOV (mult:QI (match_operand:QI 1 "src_operand" "%rR,rS<>,0")
- (match_operand:QI 2 "src_operand" "JR,rS<>,g"))
+ (match_operand:QI 2 "src_operand" "JR,rS<>,rIm"))
(const_int 0)))
(set (match_operand:QI 0 "ext_reg_operand" "=d,?d,d")
(mult:QI (match_dup 1)
@@ -1848,7 +1958,7 @@
(and:QI (match_operand:QI 1 "src_operand" "%rR,rS<>,0,rR,rS<>,0")
(const_int 16777215)))
(sign_extend:QI
- (and:QI (match_operand:QI 2 "src_operand" "JR,rS<>,g,JR,rS<>,g")
+ (and:QI (match_operand:QI 2 "src_operand" "JR,rS<>,rIm,JR,rS<>,rIm")
(const_int 16777215)))))
(clobber (reg:CC_NOOV 21))]
"TARGET_C3X && valid_operands (MULT, operands, QImode)"
@@ -1989,10 +2099,10 @@
(lshiftrt:HI
(mult:HI
(sign_extend:HI (match_operand:QI 1 "src_operand" "%rR,rS<>,0,rR,rS<>,0"))
- (sign_extend:HI (match_operand:QI 2 "src_operand" "JR,rS<>,g,JR,rS<>,g")))
+ (sign_extend:HI (match_operand:QI 2 "src_operand" "JR,rS<>,rIm,JR,rS<>,rIm")))
(const_int 32))))
(clobber (reg:CC_NOOV 21))]
- "!TARGET_C3X && valid_operands (MULT, operands, QImode)"
+ "! TARGET_C3X && valid_operands (MULT, operands, QImode)"
"@
mpyshi3\\t%2,%1,%0
mpyshi3\\t%2,%1,%0
@@ -2030,10 +2140,10 @@
(lshiftrt:HI
(mult:HI
(zero_extend:HI (match_operand:QI 1 "src_operand" "%rR,rS<>,0,rR,rS<>,0"))
- (zero_extend:HI (match_operand:QI 2 "lsrc_operand" "JR,rS<>,g,JR,rS<>,g")))
+ (zero_extend:HI (match_operand:QI 2 "lsrc_operand" "JR,rS<>,rLm,JR,rS<>,rLm")))
(const_int 32))))
(clobber (reg:CC_NOOV 21))]
- "!TARGET_C3X && valid_operands (MULT, operands, QImode)"
+ "! TARGET_C3X && valid_operands (MULT, operands, QImode)"
"@
mpyuhi3\\t%2,%1,%0
mpyuhi3\\t%2,%1,%0
@@ -2338,7 +2448,7 @@
(define_insn "*ashlqi3_clobber"
[(set (match_operand:QI 0 "reg_operand" "=d,?d,d,c,?c,c")
(ashift:QI (match_operand:QI 1 "src_operand" "rR,rS<>,0,rR,rS<>,0")
- (match_operand:QI 2 "src_operand" "JR,rS<>,g,JR,rS<>,g")))
+ (match_operand:QI 2 "src_operand" "JR,rS<>,rIm,JR,rS<>,rIm")))
(clobber (reg:CC 21))]
"valid_operands (ASHIFT, operands, QImode)"
"@
@@ -2354,21 +2464,18 @@
(define_insn "*ashlqi3_set"
[(set (reg:CC 21)
(compare:CC
- (ashift:QI (match_operand:QI 1 "src_operand" "rR,rS<>,0,rR,rS<>,0")
- (match_operand:QI 2 "src_operand" "JR,rS<>,g,JR,rS<>,g"))
+ (ashift:QI (match_operand:QI 1 "src_operand" "rR,rS<>,0")
+ (match_operand:QI 2 "src_operand" "JR,rS<>,rIm"))
(const_int 0)))
- (set (match_operand:QI 0 "reg_operand" "=d,?d,d,c,?c,c")
+ (set (match_operand:QI 0 "reg_operand" "=d,?d,d")
(ashift:QI (match_dup 1)
(match_dup 2)))]
"valid_operands (ASHIFT, operands, QImode)"
"@
ash3\\t%2,%1,%0
ash3\\t%2,%1,%0
- ash\\t%2,%0
- ash3\\t%2,%1,%0
- ash3\\t%2,%1,%0
ash\\t%2,%0"
- [(set_attr "type" "binarycc,binarycc,binarycc,binary,binary,binary")])
+ [(set_attr "type" "binarycc,binarycc,binarycc")])
; Default to int16 data attr.
; This is only used by lshrhi3_reg where we need a LSH insn that will
@@ -2376,7 +2483,7 @@
(define_insn "*lshlqi3_clobber"
[(set (match_operand:QI 0 "reg_operand" "=d,?d,d,c,?c,c")
(ashift:QI (match_operand:QI 1 "src_operand" "rR,rS<>,0,rR,rS<>,0")
- (unspec [(match_operand:QI 2 "src_operand" "JR,rS<>,g,JR,rS<>,g")] 3)))
+ (unspec [(match_operand:QI 2 "src_operand" "JR,rS<>,rIm,JR,rS<>,rIm")] 3)))
(clobber (reg:CC 21))]
"valid_operands (ASHIFT, operands, QImode)"
"@
@@ -2424,19 +2531,17 @@
(define_insn "*lshrqi3_const_set"
[(set (reg:CC 21)
(compare:CC
- (lshiftrt:QI (match_operand:QI 1 "src_operand" "0,0,r,r")
- (match_operand:QI 2 "const_int_operand" "n,n,J,J"))
+ (lshiftrt:QI (match_operand:QI 1 "src_operand" "0,r")
+ (match_operand:QI 2 "const_int_operand" "n,J"))
(const_int 0)))
- (set (match_operand:QI 0 "reg_operand" "=?d,?c,d,c")
+ (set (match_operand:QI 0 "reg_operand" "=?d,d")
(lshiftrt:QI (match_dup 1)
(match_dup 2)))]
"valid_operands (LSHIFTRT, operands, QImode)"
"@
lsh\\t%n2,%0
- lsh\\t%n2,%0
- lsh3\\t%n2,%1,%0
lsh3\\t%n2,%1,%0"
- [(set_attr "type" "binarycc,binarycc,binarycc,binarycc")])
+ [(set_attr "type" "binarycc,binarycc")])
(define_insn "*lshrqi3_nonconst_clobber"
[(set (match_operand:QI 0 "reg_operand" "=d,?d,d,c,?c,c")
@@ -2489,19 +2594,17 @@
(define_insn "*ashrqi3_const_set"
[(set (reg:CC 21)
(compare:CC
- (ashiftrt:QI (match_operand:QI 1 "src_operand" "0,0,r,r")
- (match_operand:QI 2 "const_int_operand" "n,n,J,J"))
+ (ashiftrt:QI (match_operand:QI 1 "src_operand" "0,r")
+ (match_operand:QI 2 "const_int_operand" "n,J"))
(const_int 0)))
- (set (match_operand:QI 0 "reg_operand" "=?d,?c,d,c")
+ (set (match_operand:QI 0 "reg_operand" "=?d,d")
(ashiftrt:QI (match_dup 1)
(match_dup 2)))]
"valid_operands (ASHIFTRT, operands, QImode)"
"@
ash\\t%n2,%0
- ash\\t%n2,%0
- ash3\\t%n2,%1,%0
ash3\\t%n2,%1,%0"
- [(set_attr "type" "binarycc,binarycc,binarycc,binarycc")])
+ [(set_attr "type" "binarycc,binarycc")])
(define_insn "*ashrqi3_nonconst_clobber"
[(set (match_operand:QI 0 "reg_operand" "=d,?d,d,c,?c,c")
@@ -2545,7 +2648,7 @@
(define_insn "*cmpqi_test"
[(set (reg:CC 21)
(compare:CC (match_operand:QI 0 "src_operand" "rR,?rS<>,r")
- (match_operand:QI 1 "src_operand" "JR,rS<>,g")))]
+ (match_operand:QI 1 "src_operand" "JR,rS<>,rIm")))]
"valid_operands (COMPARE, operands, QImode)"
"@
cmpi3\\t%1,%0
@@ -2556,7 +2659,7 @@
(define_insn "*cmpqi_test_noov"
[(set (reg:CC_NOOV 21)
(compare:CC_NOOV (match_operand:QI 0 "src_operand" "rR,?rS<>,r")
- (match_operand:QI 1 "src_operand" "JR,rS<>,g")))]
+ (match_operand:QI 1 "src_operand" "JR,rS<>,rIm")))]
"valid_operands (COMPARE, operands, QImode)"
"@
cmpi3\\t%1,%0
@@ -2621,7 +2724,7 @@
(match_operand:QI 2 "const_int_operand" "")
(match_operand:QI 3 "const_int_operand" "")))
(clobber (reg:CC 21))])]
- "!TARGET_C3X"
+ "! TARGET_C3X"
"if ((INTVAL (operands[2]) != 8 && INTVAL (operands[2]) != 16)
|| (INTVAL (operands[3]) % INTVAL (operands[2]) != 0))
FAIL;
@@ -2629,20 +2732,20 @@
(define_insn "*extv_clobber"
[(set (match_operand:QI 0 "reg_operand" "=d,c")
- (sign_extract:QI (match_operand:QI 1 "src_operand" "g,g")
+ (sign_extract:QI (match_operand:QI 1 "src_operand" "rLm,rLm")
(match_operand:QI 2 "const_int_operand" "n,n")
(match_operand:QI 3 "const_int_operand" "n,n")))
(clobber (reg:CC 21))]
- "!TARGET_C3X
+ "! TARGET_C3X
&& (INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16)
&& (INTVAL (operands[3]) % INTVAL (operands[2]) == 0)"
"*
if (INTVAL (operands[2]) == 8)
{
- operands[3] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[3]) / 8);
+ operands[3] = GEN_INT (INTVAL (operands[3]) / 8);
return \"lb%3\\t%1,%0\";
}
- operands[3] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[3]) / 16);
+ operands[3] = GEN_INT (INTVAL (operands[3]) / 16);
return \"lh%3\\t%1,%0\";
"
[(set_attr "type" "binarycc,binary")
@@ -2650,21 +2753,21 @@
(define_insn "*extv_clobber_test"
[(set (reg:CC 21)
- (compare:CC (sign_extract:QI (match_operand:QI 1 "src_operand" "g")
+ (compare:CC (sign_extract:QI (match_operand:QI 1 "src_operand" "rLm")
(match_operand:QI 2 "const_int_operand" "n")
(match_operand:QI 3 "const_int_operand" "n"))
(const_int 0)))
(clobber (match_scratch:QI 0 "=d"))]
- "!TARGET_C3X
+ "! TARGET_C3X
&& (INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16)
&& (INTVAL (operands[3]) % INTVAL (operands[2]) == 0)"
"*
if (INTVAL (operands[2]) == 8)
{
- operands[3] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[3]) / 8);
+ operands[3] = GEN_INT (INTVAL (operands[3]) / 8);
return \"lb%3\\t%1,%0\";
}
- operands[3] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[3]) / 16);
+ operands[3] = GEN_INT (INTVAL (operands[3]) / 16);
return \"lh%3\\t%1,%0\";
"
[(set_attr "type" "binarycc")
@@ -2672,7 +2775,7 @@
(define_insn "*extv_clobber_set"
[(set (reg:CC 21)
- (compare:CC (sign_extract:QI (match_operand:QI 1 "src_operand" "g")
+ (compare:CC (sign_extract:QI (match_operand:QI 1 "src_operand" "rLm")
(match_operand:QI 2 "const_int_operand" "n")
(match_operand:QI 3 "const_int_operand" "n"))
(const_int 0)))
@@ -2680,16 +2783,16 @@
(sign_extract:QI (match_dup 1)
(match_dup 2)
(match_dup 3)))]
- "!TARGET_C3X
+ "! TARGET_C3X
&& (INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16)
&& (INTVAL (operands[3]) % INTVAL (operands[2]) == 0)"
"*
if (INTVAL (operands[2]) == 8)
{
- operands[3] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[3]) / 8);
+ operands[3] = GEN_INT (INTVAL (operands[3]) / 8);
return \"lb%3\\t%1,%0\";
}
- operands[3] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[3]) / 16);
+ operands[3] = GEN_INT (INTVAL (operands[3]) / 16);
return \"lh%3\\t%1,%0\";
"
[(set_attr "type" "binarycc")
@@ -2704,7 +2807,7 @@
(match_operand:QI 2 "const_int_operand" "")
(match_operand:QI 3 "const_int_operand" "")))
(clobber (reg:CC 21))])]
- "!TARGET_C3X"
+ "! TARGET_C3X"
"if ((INTVAL (operands[2]) != 8 && INTVAL (operands[2]) != 16)
|| (INTVAL (operands[3]) % INTVAL (operands[2]) != 0))
FAIL;
@@ -2712,20 +2815,20 @@
(define_insn "*extzv_clobber"
[(set (match_operand:QI 0 "reg_operand" "=d,c")
- (zero_extract:QI (match_operand:QI 1 "src_operand" "g,g")
+ (zero_extract:QI (match_operand:QI 1 "src_operand" "rLm,rLm")
(match_operand:QI 2 "const_int_operand" "n,n")
(match_operand:QI 3 "const_int_operand" "n,n")))
(clobber (reg:CC 21))]
- "!TARGET_C3X
+ "! TARGET_C3X
&& (INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16)
&& (INTVAL (operands[3]) % INTVAL (operands[2]) == 0)"
"*
if (INTVAL (operands[2]) == 8)
{
- operands[3] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[3]) / 8);
+ operands[3] = GEN_INT (INTVAL (operands[3]) / 8);
return \"lbu%3\\t%1,%0\";
}
- operands[3] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[3]) / 16);
+ operands[3] = GEN_INT (INTVAL (operands[3]) / 16);
return \"lhu%3\\t%1,%0\";
"
[(set_attr "type" "binarycc,binary")
@@ -2733,21 +2836,21 @@
(define_insn "*extzv_test"
[(set (reg:CC 21)
- (compare:CC (zero_extract:QI (match_operand:QI 1 "src_operand" "g")
+ (compare:CC (zero_extract:QI (match_operand:QI 1 "src_operand" "rLm")
(match_operand:QI 2 "const_int_operand" "n")
(match_operand:QI 3 "const_int_operand" "n"))
(const_int 0)))
(clobber (match_scratch:QI 0 "=d"))]
- "!TARGET_C3X
+ "! TARGET_C3X
&& (INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16)
&& (INTVAL (operands[3]) % INTVAL (operands[2]) == 0)"
"*
if (INTVAL (operands[2]) == 8)
{
- operands[3] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[3]) / 8);
+ operands[3] = GEN_INT (INTVAL (operands[3]) / 8);
return \"lbu%3\\t%1,%0\";
}
- operands[3] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[3]) / 16);
+ operands[3] = GEN_INT (INTVAL (operands[3]) / 16);
return \"lhu%3\\t%1,%0\";
"
[(set_attr "type" "binarycc")
@@ -2755,24 +2858,24 @@
(define_insn "*extzv_set"
[(set (reg:CC 21)
- (compare:CC (zero_extract:QI (match_operand:QI 1 "src_operand" "g")
+ (compare:CC (zero_extract:QI (match_operand:QI 1 "src_operand" "rLm")
(match_operand:QI 2 "const_int_operand" "n")
(match_operand:QI 3 "const_int_operand" "n"))
(const_int 0)))
- (set (match_operand:QI 0 "reg_operand" "=d")
+ (set (match_operand:QI 0 "ext_reg_operand" "=d")
(zero_extract:QI (match_dup 1)
(match_dup 2)
(match_dup 3)))]
- "!TARGET_C3X
+ "! TARGET_C3X
&& (INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16)
&& (INTVAL (operands[3]) % INTVAL (operands[2]) == 0)"
"*
if (INTVAL (operands[2]) == 8)
{
- operands[3] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[3]) / 8);
+ operands[3] = GEN_INT (INTVAL (operands[3]) / 8);
return \"lbu%3\\t%1,%0\";
}
- operands[3] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[3]) / 16);
+ operands[3] = GEN_INT (INTVAL (operands[3]) / 16);
return \"lhu%3\\t%1,%0\";
"
[(set_attr "type" "binarycc")
@@ -2787,8 +2890,8 @@
(match_operand:QI 2 "const_int_operand" ""))
(match_operand:QI 3 "src_operand" ""))
(clobber (reg:CC 21))])]
- "!TARGET_C3X"
- "if (!(((INTVAL (operands[1]) == 8 || INTVAL (operands[1]) == 16)
+ "! TARGET_C3X"
+ "if (! (((INTVAL (operands[1]) == 8 || INTVAL (operands[1]) == 16)
&& (INTVAL (operands[2]) % INTVAL (operands[1]) == 0))
|| (INTVAL (operands[1]) == 24 && INTVAL (operands[2]) == 8)))
FAIL;
@@ -2798,21 +2901,21 @@
[(set (zero_extract:QI (match_operand:QI 0 "reg_operand" "=d,c")
(match_operand:QI 1 "const_int_operand" "n,n")
(match_operand:QI 2 "const_int_operand" "n,n"))
- (match_operand:QI 3 "src_operand" "g,g"))
+ (match_operand:QI 3 "src_operand" "rLm,rLm"))
(clobber (reg:CC 21))]
- "!TARGET_C3X
+ "! TARGET_C3X
&& (((INTVAL (operands[1]) == 8 || INTVAL (operands[1]) == 16)
&& (INTVAL (operands[2]) % INTVAL (operands[1]) == 0))
|| (INTVAL (operands[1]) == 24 && INTVAL (operands[2]) == 8))"
"*
if (INTVAL (operands[1]) == 8)
{
- operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) / 8);
+ operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
return \"mb%2\\t%3,%0\";
}
else if (INTVAL (operands[1]) == 16)
{
- operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) / 16);
+ operands[2] = GEN_INT (INTVAL (operands[2]) / 16);
return \"mh%2\\t%3,%0\";
}
return \"lwl1\\t%3,%0\";
@@ -2821,23 +2924,23 @@
(set_attr "data" "uint16,uint16")])
(define_peephole
- [(parallel [(set (zero_extract:QI (match_operand:QI 0 "reg_operand" "=d")
+ [(parallel [(set (zero_extract:QI (match_operand:QI 0 "ext_reg_operand" "=d")
(match_operand:QI 1 "const_int_operand" "n")
(match_operand:QI 2 "const_int_operand" "n"))
- (match_operand:QI 3 "src_operand" "g"))
+ (match_operand:QI 3 "src_operand" "rLm"))
(clobber (reg:CC 21))])
(set (reg:CC 21)
(compare:CC (match_dup 0) (const_int 0)))]
- "!TARGET_C3X
+ "! TARGET_C3X
&& (INTVAL (operands[1]) == 8 || INTVAL (operands[1]) == 16)
&& (INTVAL (operands[2]) % INTVAL (operands[1]) == 0)"
"*
if (INTVAL (operands[1]) == 8)
{
- operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) / 8);
+ operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
return \"mb%2\\t%3,%0\";
}
- operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) / 16);
+ operands[2] = GEN_INT (INTVAL (operands[2]) / 16);
return \"mh%2\\t%3,%0\";
"
[(set_attr "type" "binarycc")
@@ -2860,28 +2963,17 @@
(match_operand:QF 1 "src_operand" ""))]
""
"
- if (CONSTANT_P (operands[1]) && !const_operand (operands[1], QFmode))
- {
- operands[1] = force_const_mem (QFmode, operands[1]);
- if (!memory_address_p (QFmode, XEXP (operands[1], 0))
- && !reload_in_progress)
- operands[1] = change_address (operands[1], QFmode,
- XEXP (operands[1], 0));
- }
-
- if (!reload_in_progress
- && !reg_operand (operands[0], QFmode)
- && !reg_operand (operands[1], QFmode))
- operands[1] = force_reg (QFmode, operands[1]);
- ")
+{
+ if (c4x_emit_move_sequence (operands, QFmode))
+ DONE;
+}")
; We must provide an alternative to store to memory in case we have to
; spill a register.
-(define_insn "*movqf_noclobber"
+(define_insn "movqf_noclobber"
[(set (match_operand:QF 0 "src_operand" "=f,m")
- (match_operand:QF 1 "src_operand" "fmH,f"))]
- "reg_operand (operands[0], QFmode)
- || reg_operand (operands[1], QFmode)"
+ (match_operand:QF 1 "src_operand" "fHm,f"))]
+ "REG_P (operands[0]) || REG_P (operands[1])"
"@
ldfu\\t%1,%0
stf\\t%1,%0"
@@ -2889,7 +2981,7 @@
;(define_insn "*movqf_clobber"
; [(set (match_operand:QF 0 "reg_operand" "=f")
-; (match_operand:QF 1 "src_operand" "fmH"))
+; (match_operand:QF 1 "src_operand" "fHm"))
; (clobber (reg:CC 21))]
; "0"
; "ldf\\t%1,%0"
@@ -2897,7 +2989,7 @@
(define_insn "*movqf_test"
[(set (reg:CC 21)
- (compare:CC (match_operand:QF 1 "src_operand" "fmH")
+ (compare:CC (match_operand:QF 1 "src_operand" "fHm")
(const_int 0)))
(clobber (match_scratch:QF 0 "=f"))]
""
@@ -2906,7 +2998,7 @@
(define_insn "*movqf_set"
[(set (reg:CC 21)
- (compare:CC (match_operand:QF 1 "src_operand" "fmH")
+ (compare:CC (match_operand:QF 1 "src_operand" "fHm")
(match_operand:QF 2 "fp_zero_operand" "G")))
(set (match_operand:QF 0 "reg_operand" "=f")
(match_dup 1))]
@@ -2929,7 +3021,7 @@
(match_operand:QF 1 "parallel_operand" "S<>,q,S<>,q"))
(set (match_operand:QF 2 "parallel_operand" "=q,S<>,S<>,q")
(match_operand:QF 3 "parallel_operand" "S<>,q,q,S<>"))]
- "valid_parallel_operands_4 (operands, QFmode)"
+ "valid_parallel_load_store (operands, QFmode)"
"@
ldf1\\t%1,%0\\n||\\tldf2\\t%3,%2
stf1\\t%1,%0\\n||\\tstf2\\t%3,%2
@@ -2969,7 +3061,7 @@
(define_insn "*absqf2_clobber"
[(set (match_operand:QF 0 "reg_operand" "=f")
- (abs:QF (match_operand:QF 1 "src_operand" "fmH")))
+ (abs:QF (match_operand:QF 1 "src_operand" "fHm")))
(clobber (reg:CC_NOOV 21))]
""
"absf\\t%1,%0"
@@ -2977,7 +3069,7 @@
(define_insn "*absqf2_test"
[(set (reg:CC_NOOV 21)
- (compare:CC_NOOV (abs:QF (match_operand:QF 1 "src_operand" "fmH"))
+ (compare:CC_NOOV (abs:QF (match_operand:QF 1 "src_operand" "fHm"))
(match_operand:QF 2 "fp_zero_operand" "G")))
(clobber (match_scratch:QF 0 "=f"))]
""
@@ -2986,7 +3078,7 @@
(define_insn "*absqf2_set"
[(set (reg:CC_NOOV 21)
- (compare:CC_NOOV (abs:QF (match_operand:QF 1 "src_operand" "fmH"))
+ (compare:CC_NOOV (abs:QF (match_operand:QF 1 "src_operand" "fHm"))
(match_operand:QF 2 "fp_zero_operand" "G")))
(set (match_operand:QF 0 "reg_operand" "=f")
(abs:QF (match_dup 1)))]
@@ -3007,7 +3099,7 @@
(define_insn "*negqf2_clobber"
[(set (match_operand:QF 0 "reg_operand" "=f")
- (neg:QF (match_operand:QF 1 "src_operand" "fmH")))
+ (neg:QF (match_operand:QF 1 "src_operand" "fHm")))
(clobber (reg:CC_NOOV 21))]
""
"negf\\t%1,%0"
@@ -3015,7 +3107,7 @@
(define_insn "*negqf2_test"
[(set (reg:CC_NOOV 21)
- (compare:CC_NOOV (neg:QF (match_operand:QF 1 "src_operand" "fmH"))
+ (compare:CC_NOOV (neg:QF (match_operand:QF 1 "src_operand" "fHm"))
(match_operand:QF 2 "fp_zero_operand" "G")))
(clobber (match_scratch:QF 0 "=f"))]
""
@@ -3024,7 +3116,7 @@
(define_insn "*negqf2_set"
[(set (reg:CC_NOOV 21)
- (compare:CC_NOOV (neg:QF (match_operand:QF 1 "src_operand" "fmH"))
+ (compare:CC_NOOV (neg:QF (match_operand:QF 1 "src_operand" "fHm"))
(match_operand:QF 2 "fp_zero_operand" "G")))
(set (match_operand:QF 0 "reg_operand" "=f")
(neg:QF (match_dup 1)))]
@@ -3037,7 +3129,7 @@
;
(define_insn "floatqiqf2"
[(set (match_operand:QF 0 "reg_operand" "=f")
- (float:QF (match_operand:QI 1 "src_operand" "g")))
+ (float:QF (match_operand:QI 1 "src_operand" "rIm")))
(clobber (reg:CC 21))]
""
"float\\t%1,%0"
@@ -3045,17 +3137,17 @@
(define_insn "*floatqiqf2_set"
[(set (reg:CC 21)
- (compare:CC (float:QF (match_operand:QI 1 "src_operand" "g"))
+ (compare:CC (float:QF (match_operand:QI 1 "src_operand" "rIm"))
(match_operand:QF 2 "fp_zero_operand" "G")))
(set (match_operand:QF 0 "reg_operand" "=f")
(float:QF (match_dup 1)))]
-
""
"float\\t%1,%0"
[(set_attr "type" "unarycc")])
; Unsigned conversions are a little tricky because we need to
; add the value for the high bit if necessary.
+;
;
(define_expand "floatunsqiqf2"
[(set (match_dup 2) (match_dup 3))
@@ -3064,22 +3156,25 @@
(match_dup 3)))
(set (match_dup 4)
(float:QF (match_dup 1)))])
- (set (match_dup 2)
+ (set (match_dup 6)
(if_then_else:QF (lt (reg:CC 21) (const_int 0))
- (mem:QF (symbol_ref:QF "*___unsfltconst"))
+ (match_dup 5)
(match_dup 2)))
(parallel [(set (match_operand:QF 0 "reg_operand" "")
- (plus:QF (match_dup 2) (match_dup 4)))
+ (plus:QF (match_dup 6) (match_dup 4)))
(clobber (reg:CC_NOOV 21))])]
""
"operands[2] = gen_reg_rtx (QFmode);
operands[3] = CONST0_RTX (QFmode);
operands[4] = gen_reg_rtx (QFmode);
- ")
+ operands[5] = gen_reg_rtx (QFmode);
+ operands[6] = gen_reg_rtx (QFmode);
+ emit_move_insn (operands[5],
+ immed_real_const_1 (REAL_VALUE_ATOF (\"4294967296.0\", QFmode), QFmode));")
(define_insn "floatqihf2"
[(set (match_operand:HF 0 "reg_operand" "=h")
- (float:HF (match_operand:QI 1 "src_operand" "g")))
+ (float:HF (match_operand:QI 1 "src_operand" "rIm")))
(clobber (reg:CC 21))]
""
"float\\t%1,%0"
@@ -3090,7 +3185,7 @@
;
(define_insn "fixqfqi_clobber"
[(set (match_operand:QI 0 "reg_operand" "=d,c")
- (fix:QI (match_operand:QF 1 "src_operand" "fmH,fmH")))
+ (fix:QI (match_operand:QF 1 "src_operand" "fHm,fHm")))
(clobber (reg:CC 21))]
""
"fix\\t%1,%0"
@@ -3098,9 +3193,9 @@
(define_insn "*fixqfqi_set"
[(set (reg:CC 21)
- (compare:CC (fix:QI (match_operand:QF 1 "src_operand" "fmH"))
+ (compare:CC (fix:QI (match_operand:QF 1 "src_operand" "fHm"))
(const_int 0)))
- (set (match_operand:QI 0 "reg_operand" "=d")
+ (set (match_operand:QI 0 "ext_reg_operand" "=d")
(fix:QI (match_dup 1)))]
""
"fix\\t%1,%0"
@@ -3146,26 +3241,20 @@
"c4x_emit_libcall (FIX_TRUNCQFHI2_LIBCALL, FIX, HImode, QFmode, 2, operands);
DONE;")
+; Is this allowed to be implementation dependent? If so, we can
+; omit the conditional load. Otherwise we should emit a split.
(define_expand "fixuns_truncqfqi2"
- [(set (match_dup 2) (match_dup 4))
- (set (reg:CC 21)
- (compare:CC (match_operand:QF 1 "reg_operand" "")
- (mem:QF (symbol_ref "*___unsfltcompare"))))
- (set (match_dup 2)
- (if_then_else:QF (ge (reg:CC 21) (const_int 0))
- (mem:QF (symbol_ref "*___unsfltconst"))
- (match_dup 2)))
- (parallel [(set (match_dup 3)
- (minus:QF (match_dup 1) (match_dup 2)))
- (clobber (reg:CC_NOOV 21))])
- (parallel [(set (match_operand:QI 0 "reg_operand" "")
- (fix:QI (match_dup 3)))
- (clobber (reg:CC 21))])]
+ [(parallel [(set (reg:CC 21)
+ (compare:CC (fix:QI (match_operand:QF 1 "src_operand" "fHm"))
+ (const_int 0)))
+ (set (match_dup 2)
+ (fix:QI (match_dup 1)))])
+ (set (match_operand:QI 0 "reg_operand" "=r")
+ (if_then_else:QI (lt (reg:CC 21) (const_int 0))
+ (const_int 0)
+ (match_dup 2)))]
""
- "operands[2] = gen_reg_rtx (QFmode);
- operands[3] = gen_reg_rtx (QFmode);
- operands[4] = CONST0_RTX (QFmode);
- ")
+ "operands[2] = gen_reg_rtx (QImode);")
(define_expand "fixuns_truncqfhi2"
[(parallel [(set (match_operand:HI 0 "reg_operand" "")
@@ -3181,9 +3270,9 @@
;
(define_insn "*rcpfqf_clobber"
[(set (match_operand:QF 0 "reg_operand" "=f")
- (unspec [(match_operand:QF 1 "src_operand" "fmH")] 5))
+ (unspec [(match_operand:QF 1 "src_operand" "fHm")] 5))
(clobber (reg:CC_NOOV 21))]
- "!TARGET_C3X"
+ "! TARGET_C3X"
"rcpf\\t%1,%0"
[(set_attr "type" "unarycc")])
@@ -3192,9 +3281,9 @@
;
(define_insn "*rsqrfqf_clobber"
[(set (match_operand:QF 0 "reg_operand" "=f")
- (unspec [(match_operand:QF 1 "src_operand" "fmH")] 10))
+ (unspec [(match_operand:QF 1 "src_operand" "fHm")] 10))
(clobber (reg:CC_NOOV 21))]
- "!TARGET_C3X"
+ "! TARGET_C3X"
"rsqrf\\t%1,%0"
[(set_attr "type" "unarycc")])
@@ -3203,9 +3292,9 @@
;
(define_insn "*rndqf_clobber"
[(set (match_operand:QF 0 "reg_operand" "=f")
- (unspec [(match_operand:QF 1 "src_operand" "fmH")] 6))
+ (unspec [(match_operand:QF 1 "src_operand" "fHm")] 6))
(clobber (reg:CC_NOOV 21))]
- "!TARGET_C3X"
+ "! TARGET_C3X"
"rnd\\t%1,%0"
[(set_attr "type" "unarycc")])
@@ -3238,9 +3327,9 @@
(parallel [(set (match_operand:QF 0 "reg_operand" "")
(unspec [(match_dup 4)] 6))
(clobber (reg:CC_NOOV 21))])]
- "!TARGET_C3X"
- "if (!reload_in_progress
- && !reg_operand (operands[1], QFmode))
+ "! TARGET_C3X"
+ "if (! reload_in_progress
+ && ! reg_operand (operands[1], QFmode))
operands[1] = force_reg (QFmode, operands[1]);
operands[2] = gen_reg_rtx (QFmode);
operands[3] = gen_reg_rtx (QFmode);
@@ -3255,11 +3344,11 @@
(sqrt:QF (match_operand:QF 1 "src_operand" "")))
(clobber (reg:CC 21))])]
""
- "if (TARGET_C3X || !TARGET_INLINE)
+ "if (TARGET_C3X || ! TARGET_INLINE)
FAIL;
else
{
- emit_insn (gen_sqrtqf2_inline( operands[0], operands[1]));
+ emit_insn (gen_sqrtqf2_inline (operands[0], operands[1]));
DONE;
}
")
@@ -3282,7 +3371,7 @@
(define_insn "*addqf3_clobber"
[(set (match_operand:QF 0 "reg_operand" "=f,?f,f")
(plus:QF (match_operand:QF 1 "src_operand" "%fR,fS<>,0")
- (match_operand:QF 2 "src_operand" "R,fS<>,fmH")))
+ (match_operand:QF 2 "src_operand" "R,fS<>,fHm")))
(clobber (reg:CC_NOOV 21))]
"valid_operands (PLUS, operands, QFmode)"
"@
@@ -3294,7 +3383,7 @@
(define_insn "*addqf3_test"
[(set (reg:CC_NOOV 21)
(compare:CC_NOOV (plus:QF (match_operand:QF 1 "src_operand" "%fR,fS<>,0")
- (match_operand:QF 2 "src_operand" "R,fS<>,fmH"))
+ (match_operand:QF 2 "src_operand" "R,fS<>,fHm"))
(match_operand:QF 3 "fp_zero_operand" "G,G,G")))
(clobber (match_scratch:QF 0 "=f,?f,f"))]
"valid_operands (PLUS, operands, QFmode)"
@@ -3307,7 +3396,7 @@
(define_insn "*addqf3_set"
[(set (reg:CC_NOOV 21)
(compare:CC_NOOV (plus:QF (match_operand:QF 1 "src_operand" "%fR,fS<>,0")
- (match_operand:QF 2 "src_operand" "R,fS<>,fmH"))
+ (match_operand:QF 2 "src_operand" "R,fS<>,fHm"))
(match_operand:QF 3 "fp_zero_operand" "G,G,G")))
(set (match_operand:QF 0 "reg_operand" "=f,?f,f")
(plus:QF (match_dup 1)
@@ -3332,8 +3421,8 @@
(define_insn "*subqf3_clobber"
[(set (match_operand:QF 0 "reg_operand" "=f,?f,f,f")
- (minus:QF (match_operand:QF 1 "src_operand" "fR,fS<>,0,fmH")
- (match_operand:QF 2 "src_operand" "R,fS<>,fmH,0")))
+ (minus:QF (match_operand:QF 1 "src_operand" "fR,fS<>,0,fHm")
+ (match_operand:QF 2 "src_operand" "R,fS<>,fHm,0")))
(clobber (reg:CC_NOOV 21))]
"valid_operands (MINUS, operands, QFmode)"
"@
@@ -3345,8 +3434,8 @@
(define_insn "*subqf3_test"
[(set (reg:CC_NOOV 21)
- (compare:CC_NOOV (minus:QF (match_operand:QF 1 "src_operand" "fR,fS<>,0,fmH")
- (match_operand:QF 2 "src_operand" "R,fS<>,fmH,0"))
+ (compare:CC_NOOV (minus:QF (match_operand:QF 1 "src_operand" "fR,fS<>,0,fHm")
+ (match_operand:QF 2 "src_operand" "R,fS<>,fHm,0"))
(match_operand:QF 3 "fp_zero_operand" "G,G,G,G")))
(clobber (match_scratch:QF 0 "=f,?f,f,f"))]
"valid_operands (MINUS, operands, QFmode)"
@@ -3359,8 +3448,8 @@
(define_insn "*subqf3_set"
[(set (reg:CC_NOOV 21)
- (compare:CC_NOOV (minus:QF (match_operand:QF 1 "src_operand" "fR,fS<>,0,fmH")
- (match_operand:QF 2 "src_operand" "R,fS<>,fmH,0"))
+ (compare:CC_NOOV (minus:QF (match_operand:QF 1 "src_operand" "fR,fS<>,0,fHm")
+ (match_operand:QF 2 "src_operand" "R,fS<>,fHm,0"))
(match_operand:QF 3 "fp_zero_operand" "G,G,G,G")))
(set (match_operand:QF 0 "reg_operand" "=f,?f,f,f")
(minus:QF (match_dup 1)
@@ -3387,7 +3476,7 @@
(define_insn "*mulqf3_clobber"
[(set (match_operand:QF 0 "reg_operand" "=f,?f,f")
(mult:QF (match_operand:QF 1 "src_operand" "%fR,fS<>,0")
- (match_operand:QF 2 "src_operand" "R,fS<>,fmH")))
+ (match_operand:QF 2 "src_operand" "R,fS<>,fHm")))
(clobber (reg:CC_NOOV 21))]
"valid_operands (MULT, operands, QFmode)"
"@
@@ -3399,7 +3488,7 @@
(define_insn "*mulqf3_test"
[(set (reg:CC_NOOV 21)
(compare:CC_NOOV (mult:QF (match_operand:QF 1 "src_operand" "%fR,fS<>,0")
- (match_operand:QF 2 "src_operand" "R,fS<>,fmH"))
+ (match_operand:QF 2 "src_operand" "R,fS<>,fHm"))
(match_operand:QF 3 "fp_zero_operand" "G,G,G")))
(clobber (match_scratch:QF 0 "=f,?f,f"))]
"valid_operands (MULT, operands, QFmode)"
@@ -3412,7 +3501,7 @@
(define_insn "*mulqf3_set"
[(set (reg:CC_NOOV 21)
(compare:CC_NOOV (mult:QF (match_operand:QF 1 "src_operand" "%fR,fS<>,0")
- (match_operand:QF 2 "src_operand" "R,fS<>,fmH"))
+ (match_operand:QF 2 "src_operand" "R,fS<>,fHm"))
(match_operand:QF 3 "fp_zero_operand" "G,G,G")))
(set (match_operand:QF 0 "reg_operand" "=f,?f,f")
(mult:QF (match_dup 1)
@@ -3440,7 +3529,7 @@
(define_insn "*cmpqf"
[(set (reg:CC 21)
(compare:CC (match_operand:QF 0 "src_operand" "fR,?fS<>,f")
- (match_operand:QF 1 "src_operand" "R,fS<>,fmH")))]
+ (match_operand:QF 1 "src_operand" "R,fS<>,fHm")))]
"valid_operands (COMPARE, operands, QFmode)"
"@
cmpf3\\t%1,%0
@@ -3451,7 +3540,7 @@
(define_insn "*cmpqf_noov"
[(set (reg:CC_NOOV 21)
(compare:CC_NOOV (match_operand:QF 0 "src_operand" "fR,?fS<>,f")
- (match_operand:QF 1 "src_operand" "R,fS<>,fmH")))]
+ (match_operand:QF 1 "src_operand" "R,fS<>,fHm")))]
"valid_operands (COMPARE, operands, QFmode)"
"@
cmpf3\\t%1,%0
@@ -3483,9 +3572,9 @@
(parallel [(set (match_operand:QF 0 "reg_operand" "")
(unspec [(match_dup 3)] 6))
(clobber (reg:CC_NOOV 21))])]
- "!TARGET_C3X"
- "if (!reload_in_progress
- && !reg_operand (operands[2], QFmode))
+ "! TARGET_C3X"
+ "if (! reload_in_progress
+ && ! reg_operand (operands[2], QFmode))
operands[2] = force_reg (QFmode, operands[2]);
operands[3] = gen_reg_rtx (QFmode);
operands[4] = gen_reg_rtx (QFmode);
@@ -3497,14 +3586,14 @@
(match_operand:QF 2 "src_operand" "")))
(clobber (reg:CC 21))])]
""
- "if (TARGET_C3X || !TARGET_INLINE)
+ "if (TARGET_C3X || ! TARGET_INLINE)
{
c4x_emit_libcall3 (DIVQF3_LIBCALL, DIV, QFmode, operands);
DONE;
}
else
{
- emit_insn (gen_divqf3_inline( operands[0], operands[1], operands[2]));
+ emit_insn (gen_divqf3_inline (operands[0], operands[1], operands[2]));
DONE;
}
")
@@ -3517,8 +3606,8 @@
[(set (match_operand:QI 0 "reg_operand" "=r,r")
(if_then_else:QI (match_operator 1 "comparison_operator"
[(reg:CC 21) (const_int 0)])
- (match_operand:QI 2 "src_operand" "g,0")
- (match_operand:QI 3 "src_operand" "0,g")))]
+ (match_operand:QI 2 "src_operand" "rIm,0")
+ (match_operand:QI 3 "src_operand" "0,rIm")))]
""
"@
ldi%1\\t%2,%0
@@ -3529,12 +3618,12 @@
[(set (match_operand:QI 0 "reg_operand" "=r,r")
(if_then_else:QI (match_operator 1 "comparison_operator"
[(reg:CC_NOOV 21) (const_int 0)])
- (match_operand:QI 2 "src_operand" "g,0")
- (match_operand:QI 3 "src_operand" "0,g")))]
- "GET_CODE(operands[1]) != LE
- && GET_CODE(operands[1]) != GE
- && GET_CODE(operands[1]) != LT
- && GET_CODE(operands[1]) != GT"
+ (match_operand:QI 2 "src_operand" "rIm,0")
+ (match_operand:QI 3 "src_operand" "0,rIm")))]
+ "GET_CODE (operands[1]) != LE
+ && GET_CODE (operands[1]) != GE
+ && GET_CODE (operands[1]) != LT
+ && GET_CODE (operands[1]) != GT"
"@
ldi%1\\t%2,%0
ldi%I1\\t%3,%0"
@@ -3555,8 +3644,8 @@
enum rtx_code code = GET_CODE (operands[1]);
rtx ccreg = c4x_gen_compare_reg (code, c4x_compare_op0, c4x_compare_op1);
if (ccreg == NULL_RTX) FAIL;
- emit_insn (gen_rtx (SET, QImode, operands[0],
- gen_rtx (IF_THEN_ELSE, QImode,
+ emit_insn (gen_rtx_SET (QImode, operands[0],
+ gen_rtx_IF_THEN_ELSE (QImode,
gen_rtx (code, VOIDmode, ccreg, const0_rtx),
operands[2], operands[3])));
DONE;}")
@@ -3565,8 +3654,8 @@
[(set (match_operand:QF 0 "reg_operand" "=f,f")
(if_then_else:QF (match_operator 1 "comparison_operator"
[(reg:CC 21) (const_int 0)])
- (match_operand:QF 2 "src_operand" "fmH,0")
- (match_operand:QF 3 "src_operand" "0,fmH")))]
+ (match_operand:QF 2 "src_operand" "fHm,0")
+ (match_operand:QF 3 "src_operand" "0,fHm")))]
""
"@
ldf%1\\t%2,%0
@@ -3577,12 +3666,12 @@
[(set (match_operand:QF 0 "reg_operand" "=f,f")
(if_then_else:QF (match_operator 1 "comparison_operator"
[(reg:CC_NOOV 21) (const_int 0)])
- (match_operand:QF 2 "src_operand" "fmH,0")
- (match_operand:QF 3 "src_operand" "0,fmH")))]
- "GET_CODE(operands[1]) != LE
- && GET_CODE(operands[1]) != GE
- && GET_CODE(operands[1]) != LT
- && GET_CODE(operands[1]) != GT"
+ (match_operand:QF 2 "src_operand" "fHm,0")
+ (match_operand:QF 3 "src_operand" "0,fHm")))]
+ "GET_CODE (operands[1]) != LE
+ && GET_CODE (operands[1]) != GE
+ && GET_CODE (operands[1]) != LT
+ && GET_CODE (operands[1]) != GT"
"@
ldf%1\\t%2,%0
ldf%I1\\t%3,%0"
@@ -3598,8 +3687,8 @@
enum rtx_code code = GET_CODE (operands[1]);
rtx ccreg = c4x_gen_compare_reg (code, c4x_compare_op0, c4x_compare_op1);
if (ccreg == NULL_RTX) FAIL;
- emit_insn (gen_rtx (SET, QFmode, operands[0],
- gen_rtx (IF_THEN_ELSE, QFmode,
+ emit_insn (gen_rtx_SET (QFmode, operands[0],
+ gen_rtx_IF_THEN_ELSE (QFmode,
gen_rtx (code, VOIDmode, ccreg, const0_rtx),
operands[2], operands[3])));
DONE;}")
@@ -3777,7 +3866,7 @@
(set (match_operand:QF 2 "par_ind_operand" "=S<>")
(match_operand:QF 3 "ext_low_reg_operand" "q"))
(clobber (reg:CC_NOOV 21))]
- "TARGET_PARALLEL"
+ "TARGET_PARALLEL && valid_parallel_operands_4 (operands, QFmode)"
"absf\\t%1,%0\\n||\\tstf\\t%3,%2"
[(set_attr "type" "binarycc")])
@@ -3800,13 +3889,13 @@
; FLOAT/STF
;
-(define_insn "*floatqiqf_movqf_clobber"
+(define_insn "*floatqiqf2_movqf_clobber"
[(set (match_operand:QF 0 "ext_low_reg_operand" "=q")
(float:QF (match_operand:QI 1 "par_ind_operand" "S<>")))
(set (match_operand:QF 2 "par_ind_operand" "=S<>")
(match_operand:QF 3 "ext_low_reg_operand" "q"))
(clobber (reg:CC 21))]
- "TARGET_PARALLEL"
+ "TARGET_PARALLEL && valid_parallel_operands_4 (operands, QFmode)"
"float\\t%1,%0\\n||\\tstf\\t%3,%2"
[(set_attr "type" "binarycc")])
@@ -3816,10 +3905,10 @@
(define_insn "*mulqf3_addqf3_clobber"
[(set (match_operand:QF 0 "r0r1_reg_operand" "=t")
- (mult:QF (match_operand:QF 1 "parallel_operand" "S<>q")
+ (mult:QF (match_operand:QF 1 "parallel_operand" "%S<>q")
(match_operand:QF 2 "parallel_operand" "S<>q")))
(set (match_operand:QF 3 "r2r3_reg_operand" "=u")
- (plus:QF (match_operand:QF 4 "parallel_operand" "S<>q")
+ (plus:QF (match_operand:QF 4 "parallel_operand" "%S<>q")
(match_operand:QF 5 "parallel_operand" "S<>q")))
(clobber (reg:CC 21))]
"TARGET_PARALLEL_MPY && valid_parallel_operands_6 (operands, QFmode)"
@@ -3868,7 +3957,7 @@
(set (match_operand:QF 2 "par_ind_operand" "=S<>")
(match_operand:QF 3 "ext_low_reg_operand" "q"))
(clobber (reg:CC 21))]
- "TARGET_PARALLEL"
+ "TARGET_PARALLEL && valid_parallel_operands_4 (operands, QFmode)"
"negf\\t%1,%0\\n||\\tstf\\t%3,%2"
[(set_attr "type" "binarycc")])
@@ -3879,11 +3968,11 @@
(define_insn "*subqf3_movqf_clobber"
[(set (match_operand:QF 0 "ext_low_reg_operand" "=q")
(minus:QF (match_operand:QF 1 "ext_low_reg_operand" "q")
- (match_operand:QF 2 "par_ind_operand" "S<>")))
+ (match_operand:QF 2 "par_ind_operand" "S<>")))
(set (match_operand:QF 3 "par_ind_operand" "=S<>")
(match_operand:QF 4 "ext_low_reg_operand" "q"))
(clobber (reg:CC 21))]
- "TARGET_PARALLEL"
+ "TARGET_PARALLEL && valid_parallel_operands_5 (operands, QFmode)"
"subf3\\t%2,%1,%0\\n||\\tstf\\t%4,%3"
[(set_attr "type" "binarycc")])
@@ -3902,7 +3991,7 @@
(set (match_operand:QI 2 "par_ind_operand" "=S<>")
(match_operand:QI 3 "ext_low_reg_operand" "q"))
(clobber (reg:CC_NOOV 21))]
- "TARGET_PARALLEL"
+ "TARGET_PARALLEL && valid_parallel_operands_4 (operands, QImode)"
"absi\\t%1,%0\\n||\\tsti\\t%3,%2"
[(set_attr "type" "binarycc")])
@@ -3947,7 +4036,7 @@
(set (match_operand:QI 3 "par_ind_operand" "=S<>")
(match_operand:QI 4 "ext_low_reg_operand" "q"))
(clobber (reg:CC 21))]
- "TARGET_PARALLEL"
+ "TARGET_PARALLEL && valid_parallel_operands_5 (operands, QImode)"
"ash3\\t%2,%1,%0\\n||\\tsti\\t%4,%3"
[(set_attr "type" "binarycc")])
@@ -3955,14 +4044,14 @@
; ASH(right)/STI
;
-(define_insn "*ashlqi3_movqi_clobber"
+(define_insn "*ashrqi3_movqi_clobber"
[(set (match_operand:QI 0 "ext_low_reg_operand" "=q")
(ashiftrt:QI (match_operand:QI 1 "par_ind_operand" "S<>")
(neg:QI (match_operand:QI 2 "ext_low_reg_operand" "q"))))
(set (match_operand:QI 3 "par_ind_operand" "=S<>")
(match_operand:QI 4 "ext_low_reg_operand" "q"))
(clobber (reg:CC 21))]
- "TARGET_PARALLEL"
+ "TARGET_PARALLEL && valid_parallel_operands_5 (operands, QImode)"
"ash3\\t%2,%1,%0\\n||\\tsti\\t%4,%3"
[(set_attr "type" "binarycc")])
@@ -3976,7 +4065,7 @@
(set (match_operand:QI 2 "par_ind_operand" "=S<>")
(match_operand:QI 3 "ext_low_reg_operand" "q"))
(clobber (reg:CC 21))]
- "TARGET_PARALLEL"
+ "TARGET_PARALLEL && valid_parallel_operands_4 (operands, QImode)"
"fix\\t%1,%0\\n||\\tsti\\t%3,%2"
[(set_attr "type" "binarycc")])
@@ -3991,7 +4080,7 @@
(set (match_operand:QI 3 "par_ind_operand" "=S<>")
(match_operand:QI 4 "ext_low_reg_operand" "q"))
(clobber (reg:CC 21))]
- "TARGET_PARALLEL"
+ "TARGET_PARALLEL && valid_parallel_operands_5 (operands, QImode)"
"lsh3\\t%2,%1,%0\\n||\\tsti\\t%4,%3"
[(set_attr "type" "binarycc")])
@@ -4055,7 +4144,7 @@
(set (match_operand:QI 2 "par_ind_operand" "=S<>")
(match_operand:QI 3 "ext_low_reg_operand" "q"))
(clobber (reg:CC 21))]
- "TARGET_PARALLEL"
+ "TARGET_PARALLEL && valid_parallel_operands_4 (operands, QImode)"
"negi\\t%1,%0\\n||\\tsti\\t%3,%2"
[(set_attr "type" "binarycc")])
@@ -4069,7 +4158,7 @@
(set (match_operand:QI 2 "par_ind_operand" "=S<>")
(match_operand:QI 3 "ext_low_reg_operand" "q"))
(clobber (reg:CC 21))]
- "TARGET_PARALLEL"
+ "TARGET_PARALLEL && valid_parallel_operands_4 (operands, QImode)"
"not\\t%1,%0\\n||\\tsti\\t%3,%2"
[(set_attr "type" "binarycc")])
@@ -4099,7 +4188,7 @@
(set (match_operand:QI 3 "par_ind_operand" "=S<>")
(match_operand:QI 4 "ext_low_reg_operand" "q"))
(clobber (reg:CC 21))]
- "TARGET_PARALLEL"
+ "TARGET_PARALLEL && valid_parallel_operands_5 (operands, QImode)"
"subi3\\t%2,%1,%0\\n||\\tsti\\t%4,%3"
[(set_attr "type" "binarycc")])
@@ -4132,7 +4221,7 @@
(pc)))]
""
"*
- return c4x_output_cbranch (0, insn);"
+ return c4x_output_cbranch (\"b%0\", insn);"
[(set_attr "type" "jmpc")])
(define_insn "*b_rev"
@@ -4142,7 +4231,7 @@
(label_ref (match_operand 1 "" ""))))]
""
"*
- return c4x_output_cbranch (1, insn);"
+ return c4x_output_cbranch (\"b%I0\", insn);"
[(set_attr "type" "jmpc")])
(define_insn "*b_noov"
@@ -4150,12 +4239,12 @@
[(reg:CC_NOOV 21) (const_int 0)])
(label_ref (match_operand 1 "" ""))
(pc)))]
- "GET_CODE(operands[0]) != LE
- && GET_CODE(operands[0]) != GE
- && GET_CODE(operands[0]) != LT
- && GET_CODE(operands[0]) != GT"
+ "GET_CODE (operands[0]) != LE
+ && GET_CODE (operands[0]) != GE
+ && GET_CODE (operands[0]) != LT
+ && GET_CODE (operands[0]) != GT"
"*
- return c4x_output_cbranch (0, insn);"
+ return c4x_output_cbranch (\"b%0\", insn);"
[(set_attr "type" "jmpc")])
(define_insn "*b_noov_rev"
@@ -4163,12 +4252,12 @@
[(reg:CC_NOOV 21) (const_int 0)])
(pc)
(label_ref (match_operand 1 "" ""))))]
- "GET_CODE(operands[0]) != LE
- && GET_CODE(operands[0]) != GE
- && GET_CODE(operands[0]) != LT
- && GET_CODE(operands[0]) != GT"
+ "GET_CODE (operands[0]) != LE
+ && GET_CODE (operands[0]) != GE
+ && GET_CODE (operands[0]) != LT
+ && GET_CODE (operands[0]) != GT"
"*
- return c4x_output_cbranch (1, insn);"
+ return c4x_output_cbranch (\"b%I0\", insn);"
[(set_attr "type" "jmpc")])
(define_expand "beq"
@@ -4267,96 +4356,84 @@
; CALL
;
(define_insn "*call_c3x"
- [(call (match_operand:QI 0 "call_operand" "T,!o")
+ [(call (mem:QI (match_operand:QI 0 "call_address_operand" "Ur"))
(match_operand:QI 1 "general_operand" ""))
(clobber (reg:QI 31))]
;; Operand 1 not really used on the C4x. The C30 doesn't have reg 31.
"TARGET_C3X"
- "@
- call\\t%C0
- callu\\t%R0"
- [(set_attr "type" "call,call")])
+ "call%U0\\t%C0"
+ [(set_attr "type" "call")])
; LAJ requires R11 (31) for the return address
(define_insn "*laj"
- [(call (match_operand:QI 0 "call_operand" "T,!o")
+ [(call (mem:QI (match_operand:QI 0 "call_address_operand" "Ur"))
(match_operand:QI 1 "general_operand" ""))
(clobber (reg:QI 31))]
;; Operand 1 not really used on the C4x.
- "!TARGET_C3X"
+ "! TARGET_C3X"
"*
- if (which_alternative == 0)
- {
- if (final_sequence)
- return \"laj\\t%C0\";
- else
- return \"call\\t%C0\";
- }
- if (which_alternative == 1)
- {
- if (final_sequence)
- return \"laju\\t%R0\";
- else
- return \"callu\\t%R0\";
- }"
- [(set_attr "type" "laj,laj")])
+ if (final_sequence)
+ return \"laj%U0\\t%C0\";
+ else
+ return \"call%U0\\t%C0\";"
+ [(set_attr "type" "laj")])
(define_expand "call"
- [(parallel [(call (match_operand:QI 0 "call_operand" "")
+ [(parallel [(call (match_operand:QI 0 "" "")
(match_operand:QI 1 "general_operand" ""))
(clobber (reg:QI 31))])]
""
- "")
+ "
+{
+ if (GET_CODE (operands[0]) == MEM
+ && ! call_address_operand (XEXP (operands[0], 0), Pmode))
+ operands[0] = gen_rtx_MEM (GET_MODE (operands[0]),
+ force_reg (Pmode, XEXP (operands[0], 0)));
+}")
(define_insn "*callv_c3x"
- [(set (match_operand 0 "" "=r,r")
- (call (match_operand:QI 1 "call_operand" "T,!o")
+ [(set (match_operand 0 "" "=r")
+ (call (mem:QI (match_operand:QI 1 "call_address_operand" "Ur"))
(match_operand:QI 2 "general_operand" "")))
(clobber (reg:QI 31))]
;; Operand 0 and 2 not really used for the C4x.
;; The C30 doesn't have reg 31.
"TARGET_C3X"
- "@
- call\\t%C1
- callu\\t%R1"
- [(set_attr "type" "call,call")])
+ "call%U1\\t%C1"
+ [(set_attr "type" "call")])
; LAJ requires R11 (31) for the return address
(define_insn "*lajv"
- [(set (match_operand 0 "" "=r,r")
- (call (match_operand:QI 1 "call_operand" "T,!o")
+ [(set (match_operand 0 "" "=r")
+ (call (mem:QI (match_operand:QI 1 "call_address_operand" "Ur"))
(match_operand:QI 2 "general_operand" "")))
(clobber (reg:QI 31))]
;; Operand 0 and 2 not really used in the C30 instruction.
- "!TARGET_C3X"
+ "! TARGET_C3X"
"*
- if (which_alternative == 0)
- {
- if (final_sequence)
- return \"laj\\t%C1\";
- else
- return \"call\\t%C1\";
- }
- if (which_alternative == 1)
- {
- if (final_sequence)
- return \"laju\\t%R1\";
- else
- return \"callu\\t%R1\";
- }"
- [(set_attr "type" "laj,laj")])
+ if (final_sequence)
+ return \"laj%U1\\t%C1\";
+ else
+ return \"call%U1\\t%C1\";"
+ [(set_attr "type" "laj")])
(define_expand "call_value"
[(parallel [(set (match_operand 0 "" "")
- (call (match_operand:QI 1 "call_operand" "")
+ (call (match_operand:QI 1 "" "")
(match_operand:QI 2 "general_operand" "")))
(clobber (reg:QI 31))])]
""
- "")
+ "
+{
+ if (GET_CODE (operands[0]) == MEM
+ && ! call_address_operand (XEXP (operands[1], 0), Pmode))
+ operands[0] = gen_rtx_MEM (GET_MODE (operands[1]),
+ force_reg (Pmode, XEXP (operands[1], 0)));
+}")
(define_insn "return"
[(return)]
@@ -4380,10 +4457,10 @@
[(reg:CC_NOOV 21) (const_int 0)])
(return)
(pc)))]
- "GET_CODE(operands[0]) != LE
- && GET_CODE(operands[0]) != GE
- && GET_CODE(operands[0]) != LT
- && GET_CODE(operands[0]) != GT
+ "GET_CODE (operands[0]) != LE
+ && GET_CODE (operands[0]) != GE
+ && GET_CODE (operands[0]) != LT
+ && GET_CODE (operands[0]) != GT
&& c4x_null_epilogue_p ()"
"rets%0"
[(set_attr "type" "rets")])
@@ -4404,10 +4481,10 @@
[(reg:CC_NOOV 21) (const_int 0)])
(pc)
(return)))]
- "GET_CODE(operands[0]) != LE
- && GET_CODE(operands[0]) != GE
- && GET_CODE(operands[0]) != LT
- && GET_CODE(operands[0]) != GT
+ "GET_CODE (operands[0]) != LE
+ && GET_CODE (operands[0]) != GE
+ && GET_CODE (operands[0]) != LT
+ && GET_CODE (operands[0]) != GT
&& c4x_null_epilogue_p ()"
"rets%I0"
[(set_attr "type" "rets")])
@@ -4432,55 +4509,62 @@
; have an option to disable this instruction.
(define_insn "*db"
[(set (pc)
- (if_then_else (ne (match_operand:QI 0 "addr_reg_operand" "+a,!d,!m")
+ (if_then_else (ne (match_operand:QI 0 "addr_reg_operand" "+a,?*d,??*r,!m")
(const_int 0))
(label_ref (match_operand 1 "" ""))
(pc)))
(set (match_dup 0)
(plus:QI (match_dup 0)
- (const_int -1)))]
+ (const_int -1)))
+ (clobber (reg:CC_NOOV 21))]
"TARGET_DB && TARGET_LOOP_UNSIGNED"
"*
- if (IS_ADDR_REG (REGNO (operands[0])))
- {
- return \"dbu%#\\t%0,%l1\";
- }
- else if (IS_EXT_REG (REGNO (operands[0])))
- {
- return \"subi\\t1,%0\\n\\tbge%#\\t%l1\";
- }
+ if (which_alternative == 0)
+ return \"dbu%#\\t%0,%l1\";
+ else if (which_alternative == 1)
+ return c4x_output_cbranch (\"subi\\t1,%0\\n\\tbge\", insn);
+ else if (which_alternative == 2)
+ return c4x_output_cbranch (\"subi\\t1,%0\\n\\tcmpi\\t0,%0\\n\\tbge\", insn);
else
- {
- return \"push\\tr0\\n\\tldi\\t%0,r0\\n\\tsubi\\t1,r0\\n\\tsti\\tr0,%0\\n\\tpop\\tr0\\n\\tbhs%#\\t%l1\";
- }
+ return c4x_output_cbranch (\"push\\tr0\\n\\tldi\\t%0,r0\\n\\tsubi\\t1,r0\\n\\tsti\\tr0,%0\\n\\tpop\\tr0\\n\\tbhs\", insn);
"
- [(set_attr "type" "db")])
+ [(set_attr "type" "db,jmpc,jmpc,jmpc")])
+
+; This insn is used for some loop tests, typically loops reversed when
+; strength reduction is used. It is actually created when the instruction
+; combination phase combines the special loop test. Since this insn
+; is both a jump insn and has an output, it must deal with its own
+; reloads, hence the `m' constraints.
+
+; The C4x does the decrement and then compares the result against zero.
+; It branches if the result was greater than or equal to zero.
+; In the RTL the comparison and decrement are assumed to happen
+; at the same time so we bias the iteration counter with by -1
+; when we make the test.
(define_insn "decrement_and_branch_until_zero"
[(set (pc)
- (if_then_else (ge (plus:QI (match_operand:QI 0 "addr_reg_operand" "+a,!d,!m")
- (const_int -1)) (const_int 0))
+ (if_then_else (ge (plus:QI (match_operand:QI 0 "addr_reg_operand" "+a,?*d,??*r,!m")
+ (const_int -1))
+ (const_int 0))
(label_ref (match_operand 1 "" ""))
(pc)))
(set (match_dup 0)
(plus:QI (match_dup 0)
- (const_int -1)))]
+ (const_int -1)))
+ (clobber (reg:CC_NOOV 21))]
"TARGET_DB && find_reg_note (insn, REG_NONNEG, 0)"
"*
- if (IS_ADDR_REG (REGNO (operands[0])))
- {
- return \"dbu%#\\t%0,%l1\";
- }
- else if (IS_EXT_REG (REGNO (operands[0])))
- {
- return \"subi\\t1,%0\\n\\tbge%#\\t%l1\";
- }
+ if (which_alternative == 0)
+ return \"dbu%#\\t%0,%l1\";
+ else if (which_alternative == 1)
+ return c4x_output_cbranch (\"subi\\t1,%0\\n\\tbge\", insn);
+ else if (which_alternative == 2)
+ return c4x_output_cbranch (\"subi\\t1,%0\\n\\tcmpi\\t0,%0\\n\\tbge\", insn);
else
- {
- return \"push\\tr0\\n\\tldi\\t%0,r0\\n\\tsubi\\t1,r0\\n\\tsti\\tr0,%0\\n\\t\\tpop\\tr0\\n\\tbhs%#\\t%l1\";
- }
+ return c4x_output_cbranch (\"push\\tr0\\n\\tldi\\t%0,r0\\n\\tsubi\\t1,r0\\n\\tsti\\tr0,%0\\n\\tpop\\tr0\\n\\tbhs\", insn);
"
- [(set_attr "type" "db")])
+ [(set_attr "type" "db,jmpc,jmpc,jmpc")])
;
; MISC INSTRUCTIONS
@@ -4495,70 +4579,83 @@
"nop")
; Default to misc type attr.
-;
-; RPTS
-;
-; Should we disallow RPTS if we get a silly number of shifts?
-(define_insn "rpts"
- [(set (reg:QI 27)
- (unspec [(match_operand:QI 0 "src_operand" "g")] 2))
- (clobber (reg:QI 25))
- (clobber (reg:QI 26))]
- ""
- "rpts\\t%0"
- [(set_attr "type" "repeat")])
;
; RPTB
;
(define_insn "rptb_top"
- [(set (reg:QI 25) (label_ref (match_operand 0 "" "")))
- (set (reg:QI 26) (label_ref (match_operand 1 "" "")))]
+ [(use (label_ref (match_operand 0 "" "")))
+ (use (label_ref (match_operand 1 "" "")))]
""
"*
- return !final_sequence && c4x_rptb_rpts_p (insn, operands[0])
+ return ! final_sequence && c4x_rptb_rpts_p (insn, operands[0])
? \"rpts\\trc\" : \"rptb%#\\t%l1-1\";
"
[(set_attr "type" "repeat_top")])
-; operand 0 is the loop depth
-; operand 1 is the loop count
-(define_expand "repeat_block_top"
- [(set (reg:QI 27) (match_operand:QI 1 "src_operand" ""))
- (use (match_operand:QI 0 "immediate_operand" ""))
- (parallel[(set (reg:QI 25) (label_ref (match_operand 2 "" "")))
- (set (reg:QI 26) (label_ref (match_operand 3 "" "")))])]
- ""
- "if (CONSTANT_P (operands[1])
- && !const_operand (operands[1], QImode))
- operands[1] = force_const_mem (QImode, operands[1]);"
- )
-
-; operand 0 is the loop depth
-(define_insn "repeat_block_end"
+; This pattern needs to be emitted at the start of the loop to
+; say that RS and RE are loaded.
+(define_insn "*rptb_init"
+ [(unspec[(match_operand:QI 0 "register_operand" "va")] 22)
+ (clobber (reg:QI 25))
+ (clobber (reg:QI 26))]
+ ""
+ ""
+ [(set_attr "type" "repeat")])
+
+
+; The RS (25) and RE (26) registers must be unviolate from the top of the loop
+; to here.
+(define_insn "rptb_end"
[(set (pc)
- (if_then_else (ne (reg:QI 27) (const_int 0))
+ (if_then_else (ge (match_operand:QI 0 "register_operand" "+v,?a,!*d,!*x*k,!m")
+ (const_int 0))
(label_ref (match_operand 1 "" ""))
(pc)))
- (use (match_operand:QI 0 "immediate_operand" ""))
+ (set (match_dup 0)
+ (plus:QI (match_dup 0)
+ (const_int -1)))
(use (reg:QI 25))
(use (reg:QI 26))
- (set (reg:QI 27)
- (plus:QI (reg:QI 27)
- (const_int -1)))]
+ (clobber (reg:CC_NOOV 21))]
""
"*
- return c4x_rptb_nop_p(insn) ? \"nop\" : \"\";"
- [(set_attr "type" "repeat")])
-
-; to prevent labels being coalesced and to leave a space to sink insns
-; out of a repeat block loop.
-(define_insn "repeat_block_filler"
- [(unspec [(const_int 0)] 7)]
- ""
+ if (which_alternative == 0)
+ return c4x_rptb_nop_p (insn) ? \"nop\" : \"\";
+ else if (which_alternative == 1 && TARGET_DB)
+ return \"dbu%#\\t%0,%l1\";
+ else if (which_alternative == 2)
+ return c4x_output_cbranch (\"subi\\t1,%0\\n\\tbge\", insn);
+ else if (which_alternative == 3 || (which_alternative == 1 && ! TARGET_DB))
+ return c4x_output_cbranch (\"subi\\t1,%0\\n\\tcmpi\\t0,%0\\n\\tbge\", insn);
+ else
+ return c4x_output_cbranch (\"push\\tr0\\n\\tldi\\t%0,r0\\n\\tsubi\\t1,r0\\n\\tsti\\tr0,%0\\n\\tpop\\tr0\\n\\tbhs\", insn);
+ "
+ [(set_attr "type" "repeat,db,jmpc,jmpc,jmpc")])
+
+
+(define_expand "decrement_and_branch_on_count"
+ [(parallel [(set (pc)
+ (if_then_else (ge (match_operand:QI 0 "register_operand" "")
+ (const_int 0))
+ (label_ref (match_operand 1 "" ""))
+ (pc)))
+ (set (match_dup 0)
+ (plus:QI (match_dup 0)
+ (const_int -1)))
+ (use (reg:QI 25))
+ (use (reg:QI 26))
+ (clobber (reg:CC_NOOV 21))])]
""
- [(set_attr "type" "repeat")])
-
+ "if (0)
+ {
+ /* The C30 maximum iteration count for DB is 2^24. */
+ if (!TARGET_DB)
+ FAIL;
+ emit_insn (gen_decrement_and_branch_until_zero (operands[0],
+ operands[1]));
+ DONE;
+ }")
(define_expand "movstrqi_small2"
[(parallel [(set (mem:BLK (match_operand:BLK 0 "src_operand" ""))
@@ -4579,8 +4676,8 @@
len = INTVAL (operands[2]);
tmp = operands[4];
- src_mem = gen_rtx (MEM, QImode, src);
- dst_mem = gen_rtx (MEM, QImode, dst);
+ src_mem = gen_rtx_MEM (QImode, src);
+ dst_mem = gen_rtx_MEM (QImode, dst);
emit_insn (gen_movqi (tmp, src_mem));
emit_insn (gen_addqi3_noclobber (src, src, const1_rtx));
@@ -4653,7 +4750,7 @@
int len = INTVAL (operands[2]);
output_asm_insn (\"ldiu\\t*%1++,%4\", operands);
- if (TARGET_RPTS_CYCLES(len))
+ if (TARGET_RPTS_CYCLES (len))
{
output_asm_insn (\"rpts\\t%2-2\", operands);
output_asm_insn (\"sti\\t%4,*%0++\", operands);
@@ -4671,7 +4768,7 @@
}
}
"
- [(set_attr "type" "repeat")])
+ [(set_attr "type" "multi")])
; Operand 2 is the count, operand 3 is the alignment.
(define_expand "movstrqi"
@@ -4690,8 +4787,8 @@
FAIL; /* Try to call _memcpy */
}
- operands[0] = copy_to_mode_reg (Pmode, XEXP(operands[0], 0));
- operands[1] = copy_to_mode_reg (Pmode, XEXP(operands[1], 0));
+ operands[0] = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
+ operands[1] = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
tmp = gen_reg_rtx (QImode);
if (INTVAL (operands[2]) < 8)
emit_insn (gen_movstrqi_small (operands[0], operands[1], operands[2],
@@ -4706,7 +4803,7 @@
(define_insn "*cmpstrqi"
- [(set (match_operand:QI 0 "reg_operand" "=d")
+ [(set (match_operand:QI 0 "ext_reg_operand" "=d")
(compare:QI (mem:BLK (match_operand:QI 1 "addr_reg_operand" "a"))
(mem:BLK (match_operand:QI 2 "addr_reg_operand" "a"))))
(use (match_operand:QI 3 "immediate_operand" "i"))
@@ -4719,6 +4816,7 @@
output_asm_insn (\"ldi\\t%3-1,%5\", operands);
output_asm_insn (\"$1:\tsubi3\\t*%1++,*%2++,%0\", operands);
output_asm_insn (\"dbeq\\t%5,$1\", operands);
+ return \"\";
}")
(define_expand "cmpstrqi"
@@ -4738,8 +4836,8 @@
{
FAIL;
}
- operands[1] = copy_to_mode_reg (Pmode, XEXP(operands[1], 0));
- operands[2] = copy_to_mode_reg (Pmode, XEXP(operands[2], 0));
+ operands[1] = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
+ operands[2] = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
operands[5] = gen_reg_rtx (QImode);
}")
@@ -4751,32 +4849,19 @@
[(set (match_operand:HF 0 "src_operand" "")
(match_operand:HF 1 "src_operand" ""))]
""
- "if (CONSTANT_P (operands[1]))
- {
- operands[1] = force_const_mem (HFmode, operands[1]);
- if (!memory_address_p (HFmode, XEXP (operands[1], 0))
- && !reload_in_progress)
- operands[1] = change_address (operands[1], HFmode,
- XEXP (operands[1], 0));
- }
-
- /* Memory to memory copies must go through a register. */
- if (GET_CODE (operands[1]) == MEM && GET_CODE (operands[0]) == MEM
- && !reload_in_progress)
- operands[1] = force_reg (HFmode, operands[1]);
-")
+ "if (c4x_emit_move_sequence (operands, HFmode))
+ DONE;")
(define_insn "*movhf_noclobber_reg"
[(set (match_operand:HF 0 "reg_operand" "=h")
- (match_operand:HF 1 "reg_operand" "h"))]
- ""
+ (match_operand:HF 1 "src_operand" "Hh"))]
+ "GET_CODE (operands[1]) != MEM"
"ldfu\\t%1,%0"
[(set_attr "type" "unary")])
-; The predicates could be tightened to disallow constants
(define_insn "*movhf_noclobber"
[(set (match_operand:HF 0 "src_operand" "=h,m")
- (match_operand:HF 1 "src_operand" "m,h"))]
+ (match_operand:HF 1 "src_operand" "Hm,h"))]
"reg_operand (operands[0], HFmode) ^ reg_operand (operands[1], HFmode)"
"#"
[(set_attr "type" "multi,multi")])
@@ -4835,7 +4920,7 @@
(define_insn "*loadhf_float"
[(set (match_operand:HF 0 "reg_operand" "=h")
- (float_extend:HF (match_operand:QF 1 "src_operand" "fmH")))]
+ (float_extend:HF (match_operand:QF 1 "src_operand" "fHm")))]
""
"@
ldfu\\t%1,%0"
@@ -4844,7 +4929,7 @@
(define_insn "*loadhf_int"
[(set (match_operand:HF 0 "reg_operand" "=h")
(unspec[(subreg:QI (match_dup 0) 0)
- (match_operand:QI 1 "src_operand" "g")] 8))]
+ (match_operand:QI 1 "src_operand" "rIm")] 8))]
""
"@
ldiu\\t%1,%0"
@@ -5049,7 +5134,7 @@
[(set (match_operand:HF 0 "reg_operand" "=h")
(unspec [(match_operand:HF 1 "reg_or_const_operand" "hH")] 5))
(clobber (reg:CC_NOOV 21))]
- "!TARGET_C3X"
+ "! TARGET_C3X"
"rcpf\\t%1,%0"
[(set_attr "type" "unarycc")])
@@ -5060,7 +5145,7 @@
[(set (match_operand:HF 0 "reg_operand" "=h")
(unspec [(match_operand:HF 1 "reg_or_const_operand" "hH")] 10))
(clobber (reg:CC_NOOV 21))]
- "!TARGET_C3X"
+ "! TARGET_C3X"
"rsqrf\\t%1,%0"
[(set_attr "type" "unarycc")])
@@ -5071,7 +5156,7 @@
[(set (match_operand:HF 0 "reg_operand" "=h")
(unspec [(match_operand:HF 1 "reg_or_const_operand" "hH")] 6))
(clobber (reg:CC_NOOV 21))]
- "!TARGET_C3X"
+ "! TARGET_C3X"
"rnd\\t%1,%0"
[(set_attr "type" "unarycc")])
@@ -5102,7 +5187,7 @@
(parallel [(set (match_operand:HF 0 "reg_operand" "")
(mult:HF (match_dup 2) (match_dup 1)))
(clobber (reg:CC_NOOV 21))])]
- "!TARGET_C3X"
+ "! TARGET_C3X"
"
operands[2] = gen_reg_rtx (HFmode);
operands[3] = gen_reg_rtx (HFmode);
@@ -5117,11 +5202,11 @@
(sqrt:HF (match_operand:HF 1 "reg_operand" "")))
(clobber (reg:CC 21))])]
""
- "if (TARGET_C3X || !TARGET_INLINE)
+ "if (TARGET_C3X || ! TARGET_INLINE)
FAIL;
else
{
- emit_insn (gen_sqrthf2_inline( operands[0], operands[1]));
+ emit_insn (gen_sqrthf2_inline (operands[0], operands[1]));
DONE;
}
")
@@ -5254,7 +5339,7 @@
(mult:HF (match_operand:HF 1 "reg_operand" "")
(match_dup 3)))
(clobber (reg:CC_NOOV 21))])]
- "!TARGET_C3X"
+ "! TARGET_C3X"
"
operands[3] = gen_reg_rtx (HFmode);
operands[4] = gen_reg_rtx (HFmode);
@@ -5267,14 +5352,14 @@
(match_operand:HF 2 "reg_operand" "")))
(clobber (reg:CC 21))])]
""
- "if (TARGET_C3X || !TARGET_INLINE)
+ "if (TARGET_C3X || ! TARGET_INLINE)
{
c4x_emit_libcall3 (DIVHF3_LIBCALL, DIV, HFmode, operands);
DONE;
}
else
{
- emit_insn (gen_divhf3_inline( operands[0], operands[1], operands[2]));
+ emit_insn (gen_divhf3_inline (operands[0], operands[1], operands[2]));
DONE;
}
")
@@ -5284,28 +5369,21 @@
; TWO OPERAND LONG LONG INSTRUCTIONS
;
+(define_insn "*movhi_stik"
+ [(set (match_operand:HI 0 "memory_operand" "=m")
+ (match_operand:HI 1 "stik_const_operand" "K"))]
+ "! TARGET_C3X"
+ "#"
+ [(set_attr "type" "multi")])
+
; We could load some constants using define_splits for the C30
; in the large memory model---these would emit shift and or insns.
(define_expand "movhi"
[(set (match_operand:HI 0 "src_operand" "")
(match_operand:HI 1 "src_operand" ""))]
""
- "if (CONSTANT_P (operands[1]))
- {
- /* We don't need to force all constants into memory.
- This could be improved.... */
- operands[1] = force_const_mem (HImode, operands[1]);
- if (!memory_address_p (HImode, XEXP (operands[1], 0))
- && !reload_in_progress)
- operands[1] = change_address (operands[1], HImode,
- XEXP (operands[1], 0));
- }
-
- /* Memory to memory copies must go through a register. */
- if (GET_CODE (operands[1]) == MEM && GET_CODE (operands[0]) == MEM
- && !reload_in_progress)
- operands[1] = force_reg (HImode, operands[1]);
-")
+ "if (c4x_emit_move_sequence (operands, HImode))
+ DONE;")
; The constraints for movhi must include 'r' if we don't
; restrict HImode regnos to start on an even number, since
@@ -5313,7 +5391,7 @@
; votes for FP_REGS so we use dr as the constraints.
(define_insn "*movhi_noclobber"
[(set (match_operand:HI 0 "src_operand" "=dr,m")
- (match_operand:HI 1 "src_operand" "drm,r"))]
+ (match_operand:HI 1 "src_operand" "drIm,r"))]
"reg_operand (operands[0], HImode)
|| reg_operand (operands[1], HImode)"
"#"
@@ -5323,7 +5401,9 @@
[(set (match_operand:HI 0 "src_operand" "")
(match_operand:HI 1 "src_operand" ""))]
"reload_completed
- && (reg_operand (operands[0], HImode) || reg_operand (operands[1], HImode))"
+ && (reg_operand (operands[0], HImode)
+ || reg_operand (operands[1], HImode)
+ || stik_const_operand (operands[1], HImode))"
[(set (match_dup 2) (match_dup 3))
(set (match_dup 4) (match_dup 5))]
"operands[2] = c4x_operand_subword (operands[0], 0, 1, HImode);
@@ -5334,7 +5414,7 @@
(define_insn "extendqihi2"
[(set (match_operand:HI 0 "reg_operand" "=dc")
- (sign_extend:HI (match_operand:QI 1 "src_operand" "g")))
+ (sign_extend:HI (match_operand:QI 1 "src_operand" "rIm")))
(clobber (reg:CC 21))]
""
"#"
@@ -5342,7 +5422,7 @@
(define_split
[(set (match_operand:HI 0 "reg_operand" "=?dc")
- (sign_extend:HI (match_operand:QI 1 "src_operand" "g")))
+ (sign_extend:HI (match_operand:QI 1 "src_operand" "rIm")))
(clobber (reg:CC 21))]
"reload_completed && TARGET_C3X"
[(set (match_dup 2) (match_dup 1))
@@ -5354,9 +5434,9 @@
(define_split
[(set (match_operand:HI 0 "reg_operand" "=?dc")
- (sign_extend:HI (match_operand:QI 1 "src_operand" "g")))
+ (sign_extend:HI (match_operand:QI 1 "src_operand" "rIm")))
(clobber (reg:CC 21))]
- "reload_completed && !TARGET_C3X"
+ "reload_completed && ! TARGET_C3X"
[(set (match_dup 2) (match_dup 1))
(parallel [(set (match_dup 3) (ashiftrt:QI (match_dup 2) (const_int 31)))
(clobber (reg:CC 21))])]
@@ -5365,7 +5445,7 @@
(define_insn "zero_extendqihi2"
[(set (match_operand:HI 0 "reg_operand" "=?dc")
- (zero_extend:HI (match_operand:QI 1 "src_operand" "g")))
+ (zero_extend:HI (match_operand:QI 1 "src_operand" "rIm")))
(clobber (reg:CC 21))]
""
"#"
@@ -5375,7 +5455,7 @@
; the first set.
(define_split
[(set (match_operand:HI 0 "reg_operand" "=?dc")
- (zero_extend:HI (match_operand:QI 1 "src_operand" "g")))
+ (zero_extend:HI (match_operand:QI 1 "src_operand" "rIm")))
(clobber (reg:CC 21))]
"reload_completed"
[(set (match_dup 2) (match_dup 1))
@@ -5698,8 +5778,7 @@
rtx op0hi = operand_subword (operands[0], 1, 0, HImode);
rtx op0lo = operand_subword (operands[0], 0, 0, HImode);
rtx op1lo = operand_subword (operands[1], 0, 0, HImode);
- rtx count = gen_rtx (CONST_INT, VOIDmode,
- (INTVAL (operands[2]) - 32));
+ rtx count = GEN_INT ((INTVAL (operands[2]) - 32));
if (INTVAL (count))
emit_insn (gen_ashlqi3 (op0hi, op1lo, count));
@@ -5761,8 +5840,7 @@
rtx op0hi = operand_subword (operands[0], 1, 0, HImode);
rtx op0lo = operand_subword (operands[0], 0, 0, HImode);
rtx op1hi = operand_subword (operands[1], 1, 0, HImode);
- rtx count = gen_rtx (CONST_INT, VOIDmode,
- (INTVAL (operands[2]) - 32));
+ rtx count = GEN_INT ((INTVAL (operands[2]) - 32));
if (INTVAL (count))
emit_insn (gen_lshrqi3 (op0lo, op1hi, count));
@@ -5830,15 +5908,13 @@
rtx op0hi = operand_subword (operands[0], 1, 0, HImode);
rtx op0lo = operand_subword (operands[0], 0, 0, HImode);
rtx op1hi = operand_subword (operands[1], 1, 0, HImode);
- rtx count = gen_rtx (CONST_INT, VOIDmode,
- (INTVAL (operands[2]) - 32));
+ rtx count = GEN_INT ((INTVAL (operands[2]) - 32));
if (INTVAL (count))
emit_insn (gen_ashrqi3 (op0lo, op1hi, count));
else
emit_insn (gen_movqi (op0lo, op1hi));
- emit_insn (gen_ashrqi3 (op0hi, op1hi, gen_rtx (CONST_INT,
- VOIDmode, 31)));
+ emit_insn (gen_ashrqi3 (op0hi, op1hi, GEN_INT (31)));
DONE;
}
emit_insn (gen_ashrhi3_reg (operands[0], operands[1], operands[2]));
@@ -5904,7 +5980,7 @@
[(set (reg:CC 21)
(compare:CC (match_operand:HI 0 "src_operand" "")
(match_operand:HI 1 "src_operand" "")))]
- "!reload_completed"
+ "! reload_completed"
[(parallel [(set (reg:CC 21)
(unspec [(compare:CC (match_dup 0)
(match_dup 1))] 4))
@@ -5916,7 +5992,7 @@
[(set (reg:CC_NOOV 21)
(compare:CC_NOOV (match_operand:HI 0 "src_operand" "")
(match_operand:HI 1 "src_operand" "")))]
- "!reload_completed"
+ "! reload_completed"
[(parallel [(set (reg:CC_NOOV 21)
(unspec [(compare:CC_NOOV (match_dup 0)
(match_dup 1))] 4))
@@ -6138,9 +6214,11 @@
(pc)))
(set (match_dup 0)
(plus:QI (match_dup 0)
- (const_int -1)))])]
- "!c4x_label_conflict (insn, operands[2], operands[1])"
- "db%I3\\t%0,%l1\\n\\tb%3\\t%l2")
+ (const_int -1)))
+ (clobber (reg:CC_NOOV 21))])]
+ "! c4x_label_conflict (insn, operands[2], operands[1])"
+ "db%I3\\t%0,%l1\\n\\tb%3\\t%l2"
+ [(set_attr "type" "multi")])
(define_peephole
[(set (pc) (if_then_else (match_operator 3 "comparison_operator"
@@ -6156,35 +6234,41 @@
(pc)))
(set (match_dup 0)
(plus:QI (match_dup 0)
- (const_int -1)))])]
- "!c4x_label_conflict (insn, operands[2], operands[1])"
- "db%I3\\t%0,%l1\\n\\tb%3\\t%l2")
+ (const_int -1)))
+ (clobber (reg:CC_NOOV 21))])]
+ "! c4x_label_conflict (insn, operands[2], operands[1])"
+ "db%I3\\t%0,%l1\\n\\tb%3\\t%l2"
+ [(set_attr "type" "multi")])
;
; Peepholes to convert 'call label; rets' into jump label
;
(define_peephole
- [(parallel [(call (match_operand:QI 0 "call_operand" "T,!o")
+ [(parallel [(call (mem:QI (match_operand:QI 0 "call_address_operand" ""))
(match_operand:QI 1 "general_operand" ""))
(clobber (reg:QI 31))])
(return)]
"c4x_null_epilogue_p ()"
- "@
- br%#\\t%C0
- bu%#\\t%R0"
- [(set_attr "type" "jump,jump")])
+ "*
+ if (REG_P (operands[0]))
+ return \"bu%#\\t%C0\";
+ else
+ return \"br%#\\t%C0\";"
+ [(set_attr "type" "jump")])
(define_peephole
[(parallel [(set (match_operand 0 "" "")
- (call (match_operand:QI 1 "call_operand" "T,!o")
+ (call (mem:QI (match_operand:QI 1 "call_address_operand" ""))
(match_operand:QI 2 "general_operand" "")))
(clobber (reg:QI 31))])
(return)]
"c4x_null_epilogue_p ()"
- "@
- br%#\\t%C1
- bu%#\\t%R1"
- [(set_attr "type" "jump,jump")])
+ "*
+ if (REG_P (operands[1]))
+ return \"bu%#\\t%C1\";
+ else
+ return \"br%#\\t%C1\";"
+ [(set_attr "type" "jump")])
;
; Peepholes for parallel instructions
@@ -6195,7 +6279,7 @@
(set (match_operand:QI 2 "ext_low_reg_operand" "")
(match_operand:QI 3 "par_ind_operand" ""))]
"(REGNO (operands[0]) != REGNO (operands[2]))
- && !c4x_address_conflict (operands[1], operands[3], 0, 0)"
+ && ! c4x_address_conflict (operands[1], operands[3], 0, 0)"
"ldi1\\t%1,%0\\n||\\tldi2\\t%3,%2")
; load occurs before store if 1 and 2 point to same address
@@ -6205,7 +6289,7 @@
(set (match_operand:QI 2 "par_ind_operand" "")
(match_operand:QI 3 "ext_low_reg_operand" ""))]
"(REGNO (operands[0]) != REGNO (operands[3]))
- && !c4x_address_conflict (operands[1], operands[2], 0, 1)"
+ && ! c4x_address_conflict (operands[1], operands[2], 0, 1)"
"ldi\\t%1,%0\\n||\\tsti\\t%3,%2")
; load occurs before store if 0 and 3 point to same address
@@ -6215,7 +6299,7 @@
(set (match_operand:QI 2 "ext_low_reg_operand" "")
(match_operand:QI 3 "par_ind_operand" ""))]
"(REGNO (operands[1]) != REGNO (operands[2]))
- && !c4x_address_conflict (operands[0], operands[3], 1, 0)"
+ && ! c4x_address_conflict (operands[0], operands[3], 1, 0)"
"ldi\\t%3,%2\\n||\\tsti\\t%1,%0")
(define_peephole
@@ -6223,7 +6307,7 @@
(match_operand:QI 1 "ext_low_reg_operand" ""))
(set (match_operand:QI 2 "par_ind_operand" "")
(match_operand:QI 3 "ext_low_reg_operand" ""))]
- "!c4x_address_conflict (operands[0], operands[2], 1, 1)"
+ "! c4x_address_conflict (operands[0], operands[2], 1, 1)"
"sti\\t%1,%0\\n||\\tsti\\t%3,%2")
; This peephole should be unnecessary with my patches to flow.c
@@ -6244,7 +6328,7 @@
(set (match_operand:QF 2 "ext_low_reg_operand" "")
(match_operand:QF 3 "par_ind_operand" ""))]
"(REGNO (operands[0]) != REGNO (operands[2]))
- && !c4x_address_conflict (operands[1], operands[3], 0, 1)"
+ && ! c4x_address_conflict (operands[1], operands[3], 0, 1)"
"ldf1\\t%1,%0\\n||\\tldf2\\t%3,%2")
; This peephole should be unnecessary with my patches to flow.c
@@ -6272,7 +6356,7 @@
(match_operand:QF 1 "ext_low_reg_operand" ""))
(set (match_operand:QF 2 "ext_low_reg_operand" "")
(match_operand:QF 3 "par_ind_operand" ""))]
- "!c4x_address_conflict (operands[0], operands[3], 1, 1)"
+ "! c4x_address_conflict (operands[0], operands[3], 1, 1)"
"ldf\\t%3,%2\\n||\\tstf\\t%1,%0")
(define_peephole
@@ -6280,7 +6364,7 @@
(match_operand:QF 1 "ext_low_reg_operand" ""))
(set (match_operand:QF 2 "par_ind_operand" "")
(match_operand:QF 3 "ext_low_reg_operand" ""))]
- "!c4x_address_conflict (operands[0], operands[2], 1, 1)"
+ "! c4x_address_conflict (operands[0], operands[2], 1, 1)"
"stf1\\t%1,%0\\n||\\tstf2\\t%3,%2")
(define_peephole
diff --git a/gcc/config/c4x/libgcc.S b/gcc/config/c4x/libgcc.S
index fb79cf80a9e..0ce115a1ef6 100644
--- a/gcc/config/c4x/libgcc.S
+++ b/gcc/config/c4x/libgcc.S
@@ -1,7 +1,7 @@
/* libgcc1 routines for the Texas Instruments TMS320C[34]x
- Copyright (C) 1997,98 Free Software Foundation, Inc.
+ Copyright (C) 1997,98, 1999 Free Software Foundation, Inc.
- Contributed by Michael Hayes (m.hayes@elec.canterbury.cri.nz)
+ Contributed by Michael Hayes (m.hayes@elec.canterbury.ac.nz)
and Herman Ten Brugge (Haj.Ten.Brugge@net.HCC.nl).
@@ -958,7 +958,7 @@ ___divhi3:
ldi *-ar2(4),r0
ldi *-ar2(3),r1
bge div1
- negi ir0
+ not ir0
negi r0
negb r1
div1:
@@ -967,7 +967,7 @@ div1:
ldi *-ar2(2),r0
ldi *-ar2(1),r1
bge div2
- negi ir0
+ not ir0
negi r0
negb r1
div2:
@@ -995,7 +995,7 @@ ___modhi3:
ldi *-ar2(4),r0
ldi *-ar2(3),r1
bge mod1
- negi ir0
+ not ir0
negi r0
negb r1
mod1:
@@ -1004,7 +1004,7 @@ mod1:
ldi *-ar2(2),r0
ldi *-ar2(1),r1
bge mod2
- negi ir0
+ not ir0
negi r0
negb r1
mod2:
diff --git a/gcc/config/c4x/t-c4x b/gcc/config/c4x/t-c4x
index e6964740c8d..3b3dbd6ea06 100644
--- a/gcc/config/c4x/t-c4x
+++ b/gcc/config/c4x/t-c4x
@@ -6,9 +6,7 @@ LIB1ASMFUNCS = _divqf3 _divqi3 _udivqi3 _umodqi3 _modqi3 _mulqi3 \
_fix_truncqfhi2 _ufix_truncqfhi2 _floathiqf2 _ufloathiqf2 \
_floathihf2 _ufloathihf2 _fix_trunchfhi2 _ufix_trunchfhi2 _ffs
-# We do not have DF or DI types (or SF and SI for that matter),
-# so fake out the libgcc2 compilation.
-LIBGCC2_CFLAGS = -O2 -Dexit=unused_exit $(GCC_CFLAGS) $(LIBGCC2_INCLUDES) -DDF=HF -DDI=HI -DSF=QF -DSI=QI
+TARGET_LIBGCC2_CFLAGS = -Dexit=unused_exit -DDF=HF -DDI=HI -DSF=QF -DSI=QI -Dinhibit_libc
MULTILIB_OPTIONS = m30 msmall mmemparm
MULTILIB_DIRNAMES = c3x small mem
@@ -20,10 +18,3 @@ INSTALL_LIBGCC = install-multilib
# Don't make libgcc1-test since require crt0.o
LIBGCC1_TEST =
-
-# Don't make objective C because we can't compile the libraries.
-LANGUAGES = c proto c++
-
-# C[34]x has its own float and limits.h
-TARGET_FLOAT_H=config/c4x/c4x-float.h
-TARGET_LIMITS_H=config/c4x/c4x-limits.h
diff --git a/gcc/config/clipper/clipper.c b/gcc/config/clipper/clipper.c
index 4bee0e6aaa7..d59d3f1671e 100644
--- a/gcc/config/clipper/clipper.c
+++ b/gcc/config/clipper/clipper.c
@@ -438,7 +438,7 @@ clipper_builtin_saveregs (arglist)
scratch);
- if (flag_check_memory_usage)
+ if (current_function_check_memory_usage)
{
emit_library_call (chkr_set_right_libfunc, 1, VOIDmode, 3,
addr, ptr_mode,
diff --git a/gcc/config/clipper/clipper.h b/gcc/config/clipper/clipper.h
index 8ce8c473f59..bd2e5a66fc4 100644
--- a/gcc/config/clipper/clipper.h
+++ b/gcc/config/clipper/clipper.h
@@ -39,9 +39,9 @@ extern int target_flags;
An empty string NAME is used to identify the default VALUE. */
#define TARGET_SWITCHES \
- { { "c400", 1 }, \
- { "c300", -1 }, \
- { "", TARGET_DEFAULT} }
+ { { "c400", 1, "Generate code for the C400" }, \
+ { "c300", -1, "Generate code for the C300" }, \
+ { "", TARGET_DEFAULT, NULL} }
#define TARGET_C400 1
#define TARGET_C300 0
@@ -639,9 +639,9 @@ do \
/* Addressing modes, and classification of registers for them. */
-/* #define HAVE_POST_DECREMENT */
+/* #define HAVE_POST_DECREMENT 0 */
-/* #define HAVE_PRE_INCREMENT */
+/* #define HAVE_PRE_INCREMENT 0 */
/* Macros to check register numbers against specific register classes. */
diff --git a/gcc/config/convex/convex.h b/gcc/config/convex/convex.h
index 893d83aee28..f455f961c4a 100644
--- a/gcc/config/convex/convex.h
+++ b/gcc/config/convex/convex.h
@@ -892,11 +892,11 @@ enum reg_class {
/* Addressing modes, and classification of registers for them. */
-/* #define HAVE_POST_INCREMENT */
-/* #define HAVE_POST_DECREMENT */
+/* #define HAVE_POST_INCREMENT 0 */
+/* #define HAVE_POST_DECREMENT 0 */
-/* #define HAVE_PRE_DECREMENT */
-/* #define HAVE_PRE_INCREMENT */
+/* #define HAVE_PRE_DECREMENT 0 */
+/* #define HAVE_PRE_INCREMENT 0 */
/* Macros to check register numbers against specific register classes. */
diff --git a/gcc/config/dsp16xx/dsp16xx.c b/gcc/config/dsp16xx/dsp16xx.c
index e7bcdced235..69f40c7fe5f 100644
--- a/gcc/config/dsp16xx/dsp16xx.c
+++ b/gcc/config/dsp16xx/dsp16xx.c
@@ -1,5 +1,5 @@
/* Subroutines for assembler code output on the DSP1610.
- Copyright (C) 1994, 1995, 1997 Free Software Foundation, Inc.
+ Copyright (C) 1994, 1995, 1997, 1998 Free Software Foundation, Inc.
Contributed by Michael Collison (collison@world.std.com).
This file is part of GNU CC.
@@ -2239,3 +2239,9 @@ output_block_move (operands)
fprintf (asm_out_file, "\t}\n");
return "";
}
+
+void
+dsp16xx_invalid_register_for_compare ()
+{
+ fatal ("Invalid register for compare");
+}
diff --git a/gcc/config/dsp16xx/dsp16xx.h b/gcc/config/dsp16xx/dsp16xx.h
index d63cc800337..f48de0968ca 100644
--- a/gcc/config/dsp16xx/dsp16xx.h
+++ b/gcc/config/dsp16xx/dsp16xx.h
@@ -1299,11 +1299,11 @@ extern struct dsp16xx_frame_info current_frame_info;
/* ADDRESSING MODES */
/* The 1610 has post-increment and decrement, but no pre-modify */
-#define HAVE_POST_INCREMENT
-#define HAVE_POST_DECREMENT
+#define HAVE_POST_INCREMENT 1
+#define HAVE_POST_DECREMENT 1
-/* #define HAVE_PRE_DECREMENT */
-/* #define HAVE_PRE_INCREMENT */
+/* #define HAVE_PRE_DECREMENT 0 */
+/* #define HAVE_PRE_INCREMENT 0 */
/* Recognize any constant value that is a valid address. */
#define CONSTANT_ADDRESS_P(X) CONSTANT_P (X)
@@ -1970,3 +1970,5 @@ const_section () \
/* Define this so gcc does not output a call to __main, since we
are not currently supporting c++. */
#define INIT_SECTION_ASM_OP 1
+
+void dsp16xx_invalid_register_for_compare ();
diff --git a/gcc/config/dsp16xx/dsp16xx.md b/gcc/config/dsp16xx/dsp16xx.md
index 9923178d90c..6029489628b 100644
--- a/gcc/config/dsp16xx/dsp16xx.md
+++ b/gcc/config/dsp16xx/dsp16xx.md
@@ -1,5 +1,5 @@
;;- Machine description for the AT&T DSP1600 for GNU C compiler
-;; Copyright (C) 1994, 1995, 1997 Free Software Foundation, Inc.
+;; Copyright (C) 1994, 1995, 1997, 1998 Free Software Foundation, Inc.
;; Contributed by Michael Collison (collison@world.std.com).
;; This file is part of GNU CC.
@@ -178,7 +178,7 @@
output_asm_insn (\"a0=%u0\;a0l=%w0\", operands);
}
else
- fatal (\"Invalid register for compare\");
+ dsp16xx_invalid_register_for_compare ();
}
else if (GET_CODE(operands[0]) == CONST_INT)
{
@@ -205,7 +205,7 @@
output_asm_insn (\"a1=%u1\;a1l=%w1\", operands);
}
else
- fatal (\"Invalid register for compare\");
+ dsp16xx_invalid_register_for_compare ();
}
else if (GET_CODE (operands[1]) == MEM)
{
diff --git a/gcc/config/elxsi/elxsi.h b/gcc/config/elxsi/elxsi.h
index 5d35acef74f..4bacabdaba4 100644
--- a/gcc/config/elxsi/elxsi.h
+++ b/gcc/config/elxsi/elxsi.h
@@ -47,9 +47,9 @@ extern int target_flags;
An empty string NAME is used to identify the default VALUE. */
#define TARGET_SWITCHES \
- { {"unix", 1}, \
- {"embos", -1}, \
- { "", TARGET_DEFAULT}}
+ { {"unix", 1, "Generate code the unix assembler can handle"}, \
+ {"embos", -1, "Generate code an embedded assembler can handle"}, \
+ { "", TARGET_DEFAULT, NULL}}
/* Default target_flags if no switches specified. */
@@ -499,11 +499,11 @@ enum reg_class { NO_REGS, GENERAL_REGS, ALL_REGS, LIM_REG_CLASSES };
/* Addressing modes, and classification of registers for them. */
-/* #define HAVE_POST_INCREMENT */
-/* #define HAVE_POST_DECREMENT */
+/* #define HAVE_POST_INCREMENT 0 */
+/* #define HAVE_POST_DECREMENT 0 */
-/* #define HAVE_PRE_DECREMENT */
-/* #define HAVE_PRE_INCREMENT */
+/* #define HAVE_PRE_DECREMENT 0 */
+/* #define HAVE_PRE_INCREMENT 0 */
/* Macros to check register numbers against specific register classes. */
diff --git a/gcc/config/float-sh.h b/gcc/config/float-sh.h
index 9a942987920..446692428c2 100644
--- a/gcc/config/float-sh.h
+++ b/gcc/config/float-sh.h
@@ -37,7 +37,7 @@
#undef FLT_MAX_10_EXP
#define FLT_MAX_10_EXP 38
-#ifdef __SH3E__
+#if defined (__SH3E__) || defined (__SH4_SINGLE_ONLY__)
/* Number of base-FLT_RADIX digits in the significand of a double */
#undef DBL_MANT_DIG
diff --git a/gcc/config/fp-bit.c b/gcc/config/fp-bit.c
index 2acc3852dd7..6b8bd703f7e 100644
--- a/gcc/config/fp-bit.c
+++ b/gcc/config/fp-bit.c
@@ -156,8 +156,8 @@ __floatsixf (){ abort(); }
#else /* !EXTENDED_FLOAT_STUBS, rest of file */
-typedef SFtype __attribute__ ((mode (SF)));
-typedef DFtype __attribute__ ((mode (DF)));
+typedef float SFtype __attribute__ ((mode (SF)));
+typedef float DFtype __attribute__ ((mode (DF)));
typedef int HItype __attribute__ ((mode (HI)));
typedef int SItype __attribute__ ((mode (SI)));
@@ -999,8 +999,7 @@ multiply (FLO_type arg_a, FLO_type arg_b)
#if defined(L_div_sf) || defined(L_div_df)
static INLINE fp_number_type *
_fpdiv_parts (fp_number_type * a,
- fp_number_type * b,
- fp_number_type * tmp)
+ fp_number_type * b)
{
fractype bit;
fractype numerator;
@@ -1092,13 +1091,12 @@ divide (FLO_type arg_a, FLO_type arg_b)
{
fp_number_type a;
fp_number_type b;
- fp_number_type tmp;
fp_number_type *res;
unpack_d ((FLO_union_type *) & arg_a, &a);
unpack_d ((FLO_union_type *) & arg_b, &b);
- res = _fpdiv_parts (&a, &b, &tmp);
+ res = _fpdiv_parts (&a, &b);
return pack_d (res);
}
@@ -1331,7 +1329,7 @@ si_to_float (SItype arg_a)
{
/* Special case for minint, since there is no +ve integer
representation for it */
- if (arg_a == 0x80000000)
+ if (arg_a == (SItype) 0x80000000)
{
return -2147483648.0;
}
diff --git a/gcc/config/fx80/fx80.h b/gcc/config/fx80/fx80.h
index 0826236b644..3b5d5807ee6 100644
--- a/gcc/config/fx80/fx80.h
+++ b/gcc/config/fx80/fx80.h
@@ -109,16 +109,16 @@ extern int target_flags;
An empty string NAME is used to identify the default VALUE. */
#define TARGET_SWITCHES \
- { { "68020", 5}, \
- { "c68020", 5}, \
- { "bitfield", 4}, \
- { "68000", -7}, \
- { "c68000", -7}, \
- { "soft-float", -2}, \
- { "nobitfield", -4}, \
- { "short", 040}, \
- { "noshort", -040}, \
- { "", TARGET_DEFAULT}}
+ { { "68020", 5, "Generate code for a mc68020"}, \
+ { "c68020", 5, "Generate code for a mc68020"}, \
+ { "bitfield", 4, "Use bitfield instructions"}, \
+ { "68000", -7, "Generate code for a mc68000"}, \
+ { "c68000", -7, "Generate code for a mc68000"}, \
+ { "soft-float", -2, "Generate software FP code"}, \
+ { "nobitfield", -4, "Do not generate bitfield insns"}, \
+ { "short", 040, "Use 16bit integers"}, \
+ { "noshort", -040, "Use 32bit integers"}, \
+ { "", TARGET_DEFAULT, NULL}}
/* target machine storage layout */
@@ -607,11 +607,11 @@ extern enum reg_class regno_reg_class[];
/* Addressing modes, and classification of registers for them. */
-#define HAVE_POST_INCREMENT
-/* #define HAVE_POST_DECREMENT */
+#define HAVE_POST_INCREMENT 1
+/* #define HAVE_POST_DECREMENT 0 */
-#define HAVE_PRE_DECREMENT
-/* #define HAVE_PRE_INCREMENT */
+#define HAVE_PRE_DECREMENT 1
+/* #define HAVE_PRE_INCREMENT 0 */
/* Macros to check register numbers against specific register classes. */
diff --git a/gcc/config/gmicro/gmicro.h b/gcc/config/gmicro/gmicro.h
index 2c44dd03aff..789ca843982 100644
--- a/gcc/config/gmicro/gmicro.h
+++ b/gcc/config/gmicro/gmicro.h
@@ -241,7 +241,6 @@ extern int target_flags;
/* #define OVERLAPPING_REGNO_P(REGNO) */
/* #define INSN_CLOBBERS_REGNO_P(INSN,REGNO) */
-/* #define PRESERVE_DEATH_INFO_REGNO_P(REGNO) */
/* Return number of consecutive hard regs needed starting at reg REGNO
to hold something of mode MODE.
@@ -864,11 +863,11 @@ extern enum reg_class regno_reg_class[];
/* Addressing modes, and classification of registers for them. */
-/* #define HAVE_POST_INCREMENT */
-/* #define HAVE_POST_DECREMENT */
+/* #define HAVE_POST_INCREMENT 0 */
+/* #define HAVE_POST_DECREMENT 0 */
-/* #define HAVE_PRE_DECREMENT */
-/* #define HAVE_PRE_INCREMENT */
+/* #define HAVE_PRE_DECREMENT 0 */
+/* #define HAVE_PRE_INCREMENT 0 */
/* Macros to check register numbers against specific register classes. */
diff --git a/gcc/config/h8300/h8300.c b/gcc/config/h8300/h8300.c
index 603b3e0f64e..eb5d418aece 100644
--- a/gcc/config/h8300/h8300.c
+++ b/gcc/config/h8300/h8300.c
@@ -1,5 +1,6 @@
/* Subroutines for insn-output.c for Hitachi H8/300.
- Copyright (C) 1992, 93, 94, 95, 96, 97, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1992, 93, 94, 95, 96, 97, 1998, 1999 Free Software
+ Foundation, Inc.
Contributed by Steve Chamberlain (sac@cygnus.com),
Jim Wilson (wilson@cygnus.com), and Doug Evans (dje@cygnus.com).
@@ -1413,13 +1414,14 @@ print_operand (file, x, code)
fprintf (file, "@");
output_address (XEXP (x, 0));
- /* If this is an 'R' operand (reference into the 8-bit area),
- then specify a symbolic address as "foo:8". */
- if (code == 'R'
- && GET_CODE (XEXP (x, 0)) == SYMBOL_REF
+ /* If this is an 'R' operand (reference into the 8-bit
+ area), then specify a symbolic address as "foo:8",
+ otherwise if operand is still in eight bit section, use
+ "foo:16". */
+ if (GET_CODE (XEXP (x, 0)) == SYMBOL_REF
&& SYMBOL_REF_FLAG (XEXP (x, 0)))
- fprintf (file, ":8");
- if (GET_CODE (XEXP (x, 0)) == SYMBOL_REF
+ fprintf (file, (code == 'R' ? ":8" : ":16"));
+ else if (GET_CODE (XEXP (x, 0)) == SYMBOL_REF
&& TINY_DATA_NAME_P (XSTR (XEXP (x, 0), 0)))
fprintf (file, ":16");
break;
@@ -2792,8 +2794,7 @@ fix_bit_operand (operands, what, type)
mem = gen_rtx (MEM, GET_MODE (operands[0]),
copy_to_mode_reg (Pmode, XEXP (operands[0], 0)));
RTX_UNCHANGING_P (mem) = RTX_UNCHANGING_P (operands[0]);
- MEM_IN_STRUCT_P (mem) = MEM_IN_STRUCT_P (operands[0]);
- MEM_VOLATILE_P (mem) = MEM_VOLATILE_P (operands[0]);
+ MEM_COPY_ATTRIBUTES (mem, operands[0]);
operands[0] = mem;
}
@@ -2803,8 +2804,7 @@ fix_bit_operand (operands, what, type)
mem = gen_rtx (MEM, GET_MODE (operands[1]),
copy_to_mode_reg (Pmode, XEXP (operands[1], 0)));
RTX_UNCHANGING_P (mem) = RTX_UNCHANGING_P (operands[1]);
- MEM_IN_STRUCT_P (mem) = MEM_IN_STRUCT_P (operands[1]);
- MEM_VOLATILE_P (mem) = MEM_VOLATILE_P (operands[1]);
+ MEM_COPY_ATTRIBUTES (mem, operands[0]);
operands[1] = mem;
}
return 0;
@@ -3031,7 +3031,12 @@ h8300_adjust_insn_length (insn, length)
rtx insn;
int length;
{
- rtx pat = PATTERN (insn);
+ rtx pat;
+
+ if (get_attr_adjust_length (insn) == ADJUST_LENGTH_NO)
+ return 0;
+
+ pat = PATTERN (insn);
/* Adjust length for reg->mem and mem->reg copies. */
if (GET_CODE (pat) == SET
@@ -3109,34 +3114,37 @@ h8300_adjust_insn_length (insn, length)
{
rtx src = SET_SRC (XVECEXP (pat, 0, 0));
enum machine_mode mode = GET_MODE (src);
+ int shift;
if (GET_CODE (XEXP (src, 1)) != CONST_INT)
return 0;
+ shift = INTVAL (XEXP (src, 1));
+ /* According to ANSI, negative shift is undefined. It is
+ considered to be zero in this case (see function
+ emit_a_shift above). */
+ if (shift < 0)
+ shift = 0;
+
/* QImode shifts by small constants take one insn
per shift. So the adjustment is 20 (md length) -
# shifts * 2. */
- if (mode == QImode && INTVAL (XEXP (src, 1)) <= 4)
- return -(20 - INTVAL (XEXP (src, 1)) * 2);
+ if (mode == QImode && shift <= 4)
+ return -(20 - shift * 2);
/* Similarly for HImode and SImode shifts by
small constants on the H8/300H and H8/300S. */
if ((TARGET_H8300H || TARGET_H8300S)
- && (mode == HImode || mode == SImode)
- && INTVAL (XEXP (src, 1)) <= 4)
- return -(20 - INTVAL (XEXP (src, 1)) * 2);
+ && (mode == HImode || mode == SImode) && shift <= 4)
+ return -(20 - shift * 2);
/* HImode shifts by small constants for the H8/300. */
- if (mode == HImode
- && INTVAL (XEXP (src, 1)) <= 4)
- return -(20 - (INTVAL (XEXP (src, 1))
- * (GET_CODE (src) == ASHIFT ? 2 : 4)));
+ if (mode == HImode && shift <= 4)
+ return -(20 - (shift * (GET_CODE (src) == ASHIFT ? 2 : 4)));
/* SImode shifts by small constants for the H8/300. */
- if (mode == SImode
- && INTVAL (XEXP (src, 1)) <= 2)
- return -(20 - (INTVAL (XEXP (src, 1))
- * (GET_CODE (src) == ASHIFT ? 6 : 8)));
+ if (mode == SImode && shift <= 2)
+ return -(20 - (shift * (GET_CODE (src) == ASHIFT ? 6 : 8)));
/* XXX ??? Could check for more shift/rotate cases here. */
}
diff --git a/gcc/config/h8300/h8300.h b/gcc/config/h8300/h8300.h
index f159174980d..4ee440ac58d 100644
--- a/gcc/config/h8300/h8300.h
+++ b/gcc/config/h8300/h8300.h
@@ -1,6 +1,6 @@
/* Definitions of target machine for GNU compiler.
Hitachi H8/300 version generating coff
- Copyright (C) 1992, 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
+ Copyright (C) 1992, 93-98, 1999 Free SoftwareFoundation, Inc.
Contributed by Steve Chamberlain (sac@cygnus.com),
Jim Wilson (wilson@cygnus.com), and Doug Evans (dje@cygnus.com).
@@ -98,19 +98,19 @@ extern int target_flags;
An empty string NAME is used to identify the default VALUE. */
#define TARGET_SWITCHES \
- { {"s",1 }, \
- {"no-s",-1}, \
- {"int32",8}, \
- {"addresses",64 }, \
- {"quickcall",128}, \
- {"no-quickcall",-128}, \
- {"slowbyte",256}, \
- {"relax",1024}, \
- {"rtl-dump",2048}, \
- {"h",4096}, \
- {"no-h",-4096}, \
- {"align-300",8192}, \
- { "", TARGET_DEFAULT}}
+ { {"s", 1, "Generate H8/S code"}, \
+ {"no-s", -1, "Do not generate H8/S code"}, \
+ {"int32", 8, "Make integers 32 bits wide"}, \
+ {"addresses", 64, NULL}, \
+ {"quickcall", 128, "Use registers for argument passing"}, \
+ {"no-quickcall", -128, "Do not use registers for argument passing"},\
+ {"slowbyte", 256, "Consider access to byte sized memory slow"},\
+ {"relax", 1024, "Enable linker relaxing"}, \
+ {"rtl-dump", 2048, NULL}, \
+ {"h", 4096, "Generate H8/300H code"}, \
+ {"no-h", -4096, "Do not generate H8/300H code"}, \
+ {"align-300", 8192, "Use H8/300 alignment rules"}, \
+ { "", TARGET_DEFAULT, NULL}}
/* Do things that must be done once at start up. */
@@ -721,11 +721,11 @@ struct rtx_def *function_arg();
/* Addressing modes, and classification of registers for them. */
-#define HAVE_POST_INCREMENT
-/*#define HAVE_POST_DECREMENT */
+#define HAVE_POST_INCREMENT 1
+/*#define HAVE_POST_DECREMENT 0 */
-#define HAVE_PRE_DECREMENT
-/*#define HAVE_PRE_INCREMENT */
+#define HAVE_PRE_DECREMENT 1
+/*#define HAVE_PRE_INCREMENT 0 */
/* Macros to check register numbers against specific register classes. */
@@ -879,11 +879,6 @@ struct rtx_def *function_arg();
Do not define this if the table should contain absolute addresses. */
/*#define CASE_VECTOR_PC_RELATIVE 1 */
-/* Define this if the case instruction drops through after the table
- when the index is out of range. Don't define it if the case insn
- jumps to the default label instead. */
-#define CASE_DROPS_THROUGH
-
/* Specify the tree operation to be used to convert reals to integers. */
#define IMPLICIT_FIX_EXPR FIX_ROUND_EXPR
@@ -1186,6 +1181,9 @@ readonly_data() \
#define ASM_OUTPUT_LABEL(FILE, NAME) \
do { assemble_name (FILE, NAME); fputs (":\n", FILE); } while (0)
+#define ASM_OUTPUT_LABELREF(FILE,NAME) \
+ asm_fprintf ((FILE), "%U%s", (NAME) + (TINY_DATA_NAME_P (NAME) ? 1 : 0))
+
#define ASM_OUTPUT_EXTERNAL(FILE, DECL, NAME)
/* This is how to output a command to make the user-level label named NAME
diff --git a/gcc/config/h8300/h8300.md b/gcc/config/h8300/h8300.md
index a94a5ad55b2..7e49af5ef75 100644
--- a/gcc/config/h8300/h8300.md
+++ b/gcc/config/h8300/h8300.md
@@ -81,6 +81,12 @@
(const_int 6)))]
(const_int 200)))
+;; The necessity of instruction length adjustment.
+
+(define_attr "adjust_length" "yes,no"
+ (cond [(eq_attr "type" "branch") (const_string "no")]
+ (const_string "yes")))
+
;; Condition code settings.
;; none - insn does not affect cc
;; none_0hit - insn does not affect cc but it does modify operand 0
@@ -983,6 +989,7 @@
and %X2,%X0
bclr %W2,%R0"
[(set_attr "length" "2,4")
+ (set_attr "adjust_length" "no")
(set_attr "cc" "set_znv,none_0hit")])
(define_expand "andqi3"
@@ -1087,6 +1094,7 @@
or %X2,%X0
bset %V2,%R0"
[(set_attr "length" "2,4")
+ (set_attr "adjust_length" "no")
(set_attr "cc" "set_znv,none_0hit")])
(define_expand "iorqi3"
@@ -1173,6 +1181,7 @@
xor %X2,%X0
bnot %V2,%R0"
[(set_attr "length" "2,4")
+ (set_attr "adjust_length" "no")
(set_attr "cc" "set_znv,none_0hit")])
(define_expand "xorqi3"
@@ -1687,15 +1696,17 @@
"TARGET_H8300"
"")
+;; %e prints the high part of a CONST_INT, not the low part. Arggh.
(define_insn ""
- [(set (match_operand:SI 0 "register_operand" "=r,r")
- (zero_extend:SI (match_operand:HI 1 "general_operand_src" "0,g>")))]
+ [(set (match_operand:SI 0 "register_operand" "=r,r,r")
+ (zero_extend:SI (match_operand:HI 1 "general_operand_src" "0,i,g>")))]
"TARGET_H8300"
"@
sub.w %e0,%e0
+ mov.w %f1,%f0\;sub.w %e0,%e0
mov.w %e1,%f0\;sub.w %e0,%e0"
- [(set_attr "length" "2,4")
- (set_attr "cc" "clobber,clobber")])
+ [(set_attr "length" "2,4,4")
+ (set_attr "cc" "clobber,clobber,clobber")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r,r")
@@ -2224,7 +2235,8 @@
""
"bld %Z2,%Y1\;%b4 #0,%R0\;bst #0,%R0; bl1"
[(set_attr "cc" "clobber")
- (set_attr "length" "6")])
+ (set_attr "length" "6")
+ (set_attr "adjust_length" "no")])
(define_insn ""
[(set (match_operand:HI 0 "bit_operand" "=Ur")
@@ -2238,39 +2250,14 @@
""
"bld %Z2,%Y1\;%b5 %Z4,%Y3\;bst #0,%R0; bl3"
[(set_attr "cc" "clobber")
- (set_attr "length" "6")])
+ (set_attr "length" "6")
+ (set_attr "adjust_length" "no")])
;; ----------------------------------------------
;; Peepholes go at the end.
;; ----------------------------------------------
-;; Notice when two byte moves in a row could be a word move.
-
-(define_peephole
- [(set (match_operand:QI 0 "register_operand" "=r")
- (mem:QI (plus:HI (match_operand:HI 1 "register_operand" "r")
- (match_operand:HI 2 "immediate_operand" "n"))))
- (set (match_operand:QI 3 "register_operand" "=r")
- (mem:QI (plus:HI (match_dup 1)
- (match_operand:HI 4 "immediate_operand" "n"))))]
- "(INTVAL(operands[2]) == INTVAL(operands[4])+1) && REGNO(operands[0]) +1 == REGNO(operands[3])"
- "mov.w @(%u4,%T1),%T0"
- [(set_attr "length" "6")
- (set_attr "cc" "set_znv")])
-
-(define_peephole
- [(set (mem:QI (plus:HI (match_operand:HI 1 "register_operand" "r")
- (match_operand:HI 2 "immediate_operand" "n")))
- (match_operand:QI 0 "register_operand" "r"))
- (set (mem:QI (plus:HI (match_dup 1)
- (match_operand:HI 4 "immediate_operand" "n")))
- (match_operand:QI 3 "register_operand" "r"))]
- "(INTVAL(operands[2]) == INTVAL(operands[4])+1) && REGNO(operands[0]) +1 == REGNO(operands[3])"
- "mov.w %T0,@(%u4,%T1)"
- [(set_attr "length" "6")
- (set_attr "cc" "set_znv")])
-
;; Notice a move which could be post incremented.
(define_peephole
diff --git a/gcc/config/i370/i370.h b/gcc/config/i370/i370.h
index 1bb4e069e0a..3c54acfd56e 100644
--- a/gcc/config/i370/i370.h
+++ b/gcc/config/i370/i370.h
@@ -74,9 +74,9 @@ extern int current_function_outgoing_args_size;
An empty string NAME is used to identify the default VALUE. */
#define TARGET_SWITCHES \
-{ { "char-instructions", 1}, \
- { "no-char-instructions", -1}, \
- { "", TARGET_DEFAULT} }
+{ { "char-instructions", 1, "Generate char instructions"}, \
+ { "no-char-instructions", -1, "Do not generate char instructions"}, \
+ { "", TARGET_DEFAULT, NULL} }
/* To use IBM supplied macro function prologue and epilogue, define the
following to 1. Should only be needed if IBM changes the definition
@@ -612,11 +612,11 @@ enum reg_class
/* Addressing modes, and classification of registers for them. */
-/* #define HAVE_POST_INCREMENT */
-/* #define HAVE_POST_DECREMENT */
+/* #define HAVE_POST_INCREMENT 0 */
+/* #define HAVE_POST_DECREMENT 0 */
-/* #define HAVE_PRE_DECREMENT */
-/* #define HAVE_PRE_INCREMENT */
+/* #define HAVE_PRE_DECREMENT 0 */
+/* #define HAVE_PRE_INCREMENT 0 */
/* These assume that REGNO is a hard or pseudo reg number. They give
nonzero only if REGNO is a hard reg of the suitable class or a pseudo
diff --git a/gcc/config/i370/i370.md b/gcc/config/i370/i370.md
index 6d893d64388..16e2c95dc76 100644
--- a/gcc/config/i370/i370.md
+++ b/gcc/config/i370/i370.md
@@ -1,5 +1,5 @@
;;- Machine description for GNU compiler -- System/370 version.
-;; Copyright (C) 1989, 93, 94, 95, 1997 Free Software Foundation, Inc.
+;; Copyright (C) 1989, 93, 94, 95, 97, 1999 Free Software Foundation, Inc.
;; Contributed by Jan Stein (jan@cd.chalmers.se).
;; Modified for MVS C/370 by Dave Pitts (dpitts@nyx.cs.du.edu)
@@ -2125,7 +2125,7 @@ check_label_emit ();
(define_insn ""
[(set (match_operand:DI 0 "register_operand" "=d")
- (mult:SI (match_operand:DI 1 "general_operand" "%0")
+ (mult:DI (match_operand:DI 1 "general_operand" "%0")
(match_operand:SI 2 "general_operand" "g")))]
""
"*
@@ -2281,7 +2281,7 @@ check_label_emit ();
(define_insn ""
[(set (match_operand:DI 0 "register_operand" "=d")
- (div:SI (match_operand:DI 1 "register_operand" "0")
+ (div:DI (match_operand:DI 1 "register_operand" "0")
(match_operand:SI 2 "general_operand" "")))]
""
"*
@@ -2441,7 +2441,7 @@ check_label_emit ();
(define_insn ""
[(set (match_operand:DI 0 "register_operand" "=d")
- (mod:SI (match_operand:DI 1 "register_operand" "0")
+ (mod:DI (match_operand:DI 1 "register_operand" "0")
(match_operand:SI 2 "general_operand" "")))]
""
"*
diff --git a/gcc/config/i386/aix386ng.h b/gcc/config/i386/aix386ng.h
index a177b69250f..9a8dae632c3 100644
--- a/gcc/config/i386/aix386ng.h
+++ b/gcc/config/i386/aix386ng.h
@@ -1,5 +1,5 @@
/* Definitions for IBM PS2 running AIX/386.
- Copyright (C) 1988, 1996 Free Software Foundation, Inc.
+ Copyright (C) 1988, 1996, 1998 Free Software Foundation, Inc.
Contributed by Minh Tran-Le <TRANLE@intellicorp.com>.
This file is part of GNU CC.
@@ -58,9 +58,7 @@ Boston, MA 02111-1307, USA. */
#undef ASM_FILE_START
#define ASM_FILE_START(FILE) \
- do { fprintf (FILE, "\t.file\t"); \
- output_quoted_string (FILE, dump_base_name); \
- fprintf (FILE, "\n"); \
+ do { output_file_directive (FILE, main_input_filename); \
if (optimize) \
ASM_FILE_START_1 (FILE); \
else \
diff --git a/gcc/config/i386/bsd.h b/gcc/config/i386/bsd.h
index d50be3664c1..34db79a79d5 100644
--- a/gcc/config/i386/bsd.h
+++ b/gcc/config/i386/bsd.h
@@ -49,9 +49,7 @@ Boston, MA 02111-1307, USA. */
??? I am skeptical of this -- RMS. */
#define ASM_FILE_START(FILE) \
- do { fprintf (FILE, "\t.file\t"); \
- output_quoted_string (FILE, dump_base_name); \
- fprintf (FILE, "\n"); \
+ do { output_file_directive (FILE, main_input_filename); \
} while (0)
/* This was suggested, but it shouldn't be right for DBX output. -- RMS
diff --git a/gcc/config/i386/crtdll.h b/gcc/config/i386/crtdll.h
index 9a6d9a176a9..4334da0bd91 100644
--- a/gcc/config/i386/crtdll.h
+++ b/gcc/config/i386/crtdll.h
@@ -3,7 +3,7 @@
as distinct from winnt.h, which is used to build GCC for use with a
windows style library and tool set and uses the Microsoft tools.
This variant uses CRTDLL.DLL insted of MSVCRTDLL.DLL.
- Copyright (C) 1998 Free Software Foundation, Inc.
+ Copyright (C) 1998, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -24,9 +24,9 @@ Boston, MA 02111-1307, USA. */
#undef CPP_PREDEFINES
#define CPP_PREDEFINES "-Di386 -D_WIN32 -DWIN32 -D__WIN32__ \
- -D__MINGW32__ -DWINNT -D_X86_=1 -D__STDC__=1\
+ -D__MINGW32__=0.2 -DWINNT -D_X86_=1 -D__STDC__=1\
-D__stdcall=__attribute__((__stdcall__)) \
- _D_stdcall=__attribute__((__stdcall__)) \
+ -D_stdcall=__attribute__((__stdcall__)) \
-D__cdecl=__attribute__((__cdecl__)) \
-D__declspec(x)=__attribute__((x)) \
-Asystem(winnt) -Acpu(i386) -Amachine(i386)"
diff --git a/gcc/config/i386/cygwin32.asm b/gcc/config/i386/cygwin32.asm
deleted file mode 100644
index 4ac4c91a3b1..00000000000
--- a/gcc/config/i386/cygwin32.asm
+++ /dev/null
@@ -1,32 +0,0 @@
-/* stuff needed for libgcc1 on win32. */
-
-#ifdef L_chkstk
-
- .global ___chkstk
- .global __alloca
-___chkstk:
-__alloca:
- pushl %ecx /* save temp */
- movl %esp,%ecx /* get sp */
- addl $0x8,%ecx /* and point to return addr */
-
-probe: cmpl $0x1000,%eax /* > 4k ?*/
- jb done
-
- subl $0x1000,%ecx /* yes, move pointer down 4k*/
- orl $0x0,(%ecx) /* probe there */
- subl $0x1000,%eax /* decrement count */
- jmp probe /* and do it again */
-
-done: subl %eax,%ecx
- orl $0x0,(%ecx) /* less that 4k, just peek here */
-
- movl %esp,%eax
- movl %ecx,%esp /* decrement stack */
-
- movl (%eax),%ecx /* recover saved temp */
- movl 4(%eax),%eax /* get return address */
- jmp *%eax
-
-
-#endif
diff --git a/gcc/config/i386/cygwin32.h b/gcc/config/i386/cygwin32.h
deleted file mode 100644
index e52c7100591..00000000000
--- a/gcc/config/i386/cygwin32.h
+++ /dev/null
@@ -1,479 +0,0 @@
-/* Operating system specific defines to be used when targeting GCC for
- hosting on Windows NT 3.x, using a Unix style C library and tools,
- as distinct from winnt.h, which is used to build GCC for use with a
- windows style library and tool set and uses the Microsoft tools.
- Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
-
-This file is part of GNU CC.
-
-GNU CC is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
-
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
-
-#define YES_UNDERSCORES
-
-#define DBX_DEBUGGING_INFO
-#define SDB_DEBUGGING_INFO
-#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG
-
-#include "i386/gas.h"
-#include "dbxcoff.h"
-
-/* Support the __declspec keyword by turning them into attributes.
- We currently only support: dllimport and dllexport.
- Note that the current way we do this may result in a collision with
- predefined attributes later on. This can be solved by using one attribute,
- say __declspec__, and passing args to it. The problem with that approach
- is that args are not accumulated: each new appearance would clobber any
- existing args. */
-
-#ifdef CPP_PREDEFINES
-#undef CPP_PREDEFINES
-#endif
-
-#define CPP_PREDEFINES "-Di386 -D_WIN32 \
- -D__CYGWIN32__ -DWINNT -D_X86_=1 -D__STDC__=1\
- -D__stdcall=__attribute__((__stdcall__)) \
- -D__cdecl=__attribute__((__cdecl__)) \
- -D__declspec(x)=__attribute__((x)) \
- -Asystem(winnt) -Acpu(i386) -Amachine(i386)"
-
-#undef CPP_SPEC
-#define CPP_SPEC "-remap %(cpp_cpu) %{posix:-D_POSIX_SOURCE}"
-
-/* We have to dynamic link to get to the system DLLs. All of libc, libm and
- the Unix stuff is in cygwin.dll. The import library is called
- 'libcygwin.a'. For Windows applications, include more libraries, but
- always include kernel32. We'd like to specific subsystem windows to
- ld, but that doesn't work just yet. */
-
-#undef LIB_SPEC
-#define LIB_SPEC "%{pg:-lgmon} -lcygwin %{mwindows:-luser32 -lgdi32 -lcomdlg32}\
- -lkernel32 -ladvapi32 -lshell32"
-
-#define LINK_SPEC "%{mwindows:--subsystem windows}"
-
-/* Normally, -lgcc is not needed since everything in it is in the DLL, but we
- want to allow things to be added to it when installing new versions of
- GCC without making a new CYGWIN.DLL, so we leave it. Profiling is handled
- by calling the init function from the prologue. */
-
-#undef STARTFILE_SPEC
-#define STARTFILE_SPEC "%{pg:gcrt0%O%s} crt0%O%s"
-
-#define SIZE_TYPE "unsigned int"
-#define PTRDIFF_TYPE "int"
-#define WCHAR_UNSIGNED 1
-#define WCHAR_TYPE_SIZE 16
-#define WCHAR_TYPE "short unsigned int"
-#define HAVE_ATEXIT 1
-
-
-/* Ignore dllimport for functions. */
-#define TARGET_NOP_FUN_DLLIMPORT (target_flags & 0x20000)
-
-#undef SUBTARGET_SWITCHES
-#define SUBTARGET_SWITCHES \
- { "nop-fun-dllimport", 0x20000 }, \
- { "no-nop-fun-dllimport", -0x20000 }, \
- { "windows", 0x0 },
-
-/* Enable parsing of #pragma pack(push,<n>) and #pragma pack(pop). */
-#define HANDLE_PRAGMA_PACK_PUSH_POP 1
-
-/* A C expression whose value is nonzero if IDENTIFIER with arguments ARGS
- is a valid machine specific attribute for DECL.
- The attributes in ATTRIBUTES have previously been assigned to DECL. */
-extern int i386_pe_valid_decl_attribute_p ();
-
-#undef VALID_MACHINE_DECL_ATTRIBUTE
-#define VALID_MACHINE_DECL_ATTRIBUTE(DECL, ATTRIBUTES, IDENTIFIER, ARGS) \
- i386_pe_valid_decl_attribute_p (DECL, ATTRIBUTES, IDENTIFIER, ARGS)
-
-/* A C expression whose value is nonzero if IDENTIFIER with arguments ARGS
- is a valid machine specific attribute for TYPE.
- The attributes in ATTRIBUTES have previously been assigned to TYPE. */
-
-#undef VALID_MACHINE_TYPE_ATTRIBUTE
-#define VALID_MACHINE_TYPE_ATTRIBUTE(TYPE, ATTRIBUTES, IDENTIFIER, ARGS) \
- i386_pe_valid_type_attribute_p (TYPE, ATTRIBUTES, IDENTIFIER, ARGS)
-extern int i386_pe_valid_type_attribute_p ();
-
-extern union tree_node *i386_pe_merge_decl_attributes ();
-#define MERGE_MACHINE_DECL_ATTRIBUTES(OLD, NEW) \
- i386_pe_merge_decl_attributes ((OLD), (NEW))
-
-/* Used to implement dllexport overriding dllimport semantics. It's also used
- to handle vtables - the first pass won't do anything because
- DECL_CONTEXT (DECL) will be 0 so i386_pe_dll{ex,im}port_p will return 0.
- It's also used to handle dllimport override semantics. */
-#if 0
-#define REDO_SECTION_INFO_P(DECL) \
- ((DECL_MACHINE_ATTRIBUTES (DECL) != NULL_TREE) \
- || (TREE_CODE (DECL) == VAR_DECL && DECL_VIRTUAL_P (DECL)))
-#else
-#define REDO_SECTION_INFO_P(DECL) 1
-#endif
-
-
-#undef EXTRA_SECTIONS
-#define EXTRA_SECTIONS in_ctor, in_dtor, in_drectve
-
-#undef EXTRA_SECTION_FUNCTIONS
-#define EXTRA_SECTION_FUNCTIONS \
- CTOR_SECTION_FUNCTION \
- DTOR_SECTION_FUNCTION \
- DRECTVE_SECTION_FUNCTION \
- SWITCH_TO_SECTION_FUNCTION
-
-#define CTOR_SECTION_FUNCTION \
-void \
-ctor_section () \
-{ \
- if (in_section != in_ctor) \
- { \
- fprintf (asm_out_file, "\t.section .ctor\n"); \
- in_section = in_ctor; \
- } \
-}
-
-#define DTOR_SECTION_FUNCTION \
-void \
-dtor_section () \
-{ \
- if (in_section != in_dtor) \
- { \
- fprintf (asm_out_file, "\t.section .dtor\n"); \
- in_section = in_dtor; \
- } \
-}
-
-#define DRECTVE_SECTION_FUNCTION \
-void \
-drectve_section () \
-{ \
- if (in_section != in_drectve) \
- { \
- fprintf (asm_out_file, "%s\n", "\t.section .drectve\n"); \
- in_section = in_drectve; \
- } \
-}
-
-/* Switch to SECTION (an `enum in_section').
-
- ??? This facility should be provided by GCC proper.
- The problem is that we want to temporarily switch sections in
- ASM_DECLARE_OBJECT_NAME and then switch back to the original section
- afterwards. */
-#define SWITCH_TO_SECTION_FUNCTION \
-void \
-switch_to_section (section, decl) \
- enum in_section section; \
- tree decl; \
-{ \
- switch (section) \
- { \
- case in_text: text_section (); break; \
- case in_data: data_section (); break; \
- case in_named: named_section (decl, NULL, 0); break; \
- case in_ctor: ctor_section (); break; \
- case in_dtor: dtor_section (); break; \
- case in_drectve: drectve_section (); break; \
- default: abort (); break; \
- } \
-}
-
-#define ASM_OUTPUT_CONSTRUCTOR(FILE,NAME) \
- do { \
- ctor_section (); \
- fprintf (FILE, "%s\t", ASM_LONG); \
- assemble_name (FILE, NAME); \
- fprintf (FILE, "\n"); \
- } while (0)
-
-#define ASM_OUTPUT_DESTRUCTOR(FILE,NAME) \
- do { \
- dtor_section (); \
- fprintf (FILE, "%s\t", ASM_LONG); \
- assemble_name (FILE, NAME); \
- fprintf (FILE, "\n"); \
- } while (0)
-
-/* Define this macro if references to a symbol must be treated
- differently depending on something about the variable or
- function named by the symbol (such as what section it is in).
-
- On i386 running Windows NT, modify the assembler name with a suffix
- consisting of an atsign (@) followed by string of digits that represents
- the number of bytes of arguments passed to the function, if it has the
- attribute STDCALL.
-
- In addition, we must mark dll symbols specially. Definitions of
- dllexport'd objects install some info in the .drectve section.
- References to dllimport'd objects are fetched indirectly via
- _imp__. If both are declared, dllexport overrides. This is also
- needed to implement one-only vtables: they go into their own
- section and we need to set DECL_SECTION_NAME so we do that here.
- Note that we can be called twice on the same decl. */
-
-extern void i386_pe_encode_section_info ();
-
-#ifdef ENCODE_SECTION_INFO
-#undef ENCODE_SECTION_INFO
-#endif
-#define ENCODE_SECTION_INFO(DECL) i386_pe_encode_section_info (DECL)
-
-/* Utility used only in this file. */
-#define I386_PE_STRIP_ENCODING(SYM_NAME) \
- ((SYM_NAME) + ((SYM_NAME)[0] == '@' ? 3 : 0))
-
-/* This macro gets just the user-specified name
- out of the string in a SYMBOL_REF. Discard
- trailing @[NUM] encoded by ENCODE_SECTION_INFO. */
-#undef STRIP_NAME_ENCODING
-#define STRIP_NAME_ENCODING(VAR,SYMBOL_NAME) \
-do { \
- char *_p; \
- char *_name = I386_PE_STRIP_ENCODING (SYMBOL_NAME); \
- for (_p = _name; *_p && *_p != '@'; ++_p) \
- ; \
- if (*_p == '@') \
- { \
- int _len = _p - _name; \
- (VAR) = (char *) alloca (_len + 1); \
- strncpy ((VAR), _name, _len); \
- (VAR)[_len] = '\0'; \
- } \
- else \
- (VAR) = _name; \
-} while (0)
-
-
-/* Output a reference to a label. */
-#undef ASM_OUTPUT_LABELREF
-#define ASM_OUTPUT_LABELREF(STREAM, NAME) \
- fprintf (STREAM, "%s%s", USER_LABEL_PREFIX, \
- I386_PE_STRIP_ENCODING (NAME)) \
-
-/* Output a common block. */
-#undef ASM_OUTPUT_COMMON
-#define ASM_OUTPUT_COMMON(STREAM, NAME, SIZE, ROUNDED) \
-do { \
- if (i386_pe_dllexport_name_p (NAME)) \
- { \
- drectve_section (); \
- fprintf ((STREAM), "\t.ascii \" -export:%s\"\n", \
- I386_PE_STRIP_ENCODING (NAME)); \
- } \
- if (! i386_pe_dllimport_name_p (NAME)) \
- { \
- fprintf ((STREAM), "\t.comm\t"); \
- assemble_name ((STREAM), (NAME)); \
- fprintf ((STREAM), ", %d\t%s %d\n", \
- (ROUNDED), ASM_COMMENT_START, (SIZE)); \
- } \
-} while (0)
-
-/* Output the label for an initialized variable. */
-#undef ASM_DECLARE_OBJECT_NAME
-#define ASM_DECLARE_OBJECT_NAME(STREAM, NAME, DECL) \
-do { \
- if (i386_pe_dllexport_name_p (NAME)) \
- { \
- enum in_section save_section = in_section; \
- drectve_section (); \
- fprintf ((STREAM), "\t.ascii \" -export:%s\"\n", \
- I386_PE_STRIP_ENCODING (NAME)); \
- switch_to_section (save_section, (DECL)); \
- } \
- ASM_OUTPUT_LABEL ((STREAM), (NAME)); \
-} while (0)
-
-
-/* Emit code to check the stack when allocating more that 4000
- bytes in one go. */
-
-#define CHECK_STACK_LIMIT 4000
-
-/* By default, target has a 80387, uses IEEE compatible arithmetic,
- and returns float values in the 387 and needs stack probes */
-#undef TARGET_DEFAULT
-
-#define TARGET_DEFAULT \
- (MASK_80387 | MASK_IEEE_FP | MASK_FLOAT_RETURNS | MASK_STACK_PROBE)
-
-/* This is how to output an assembler line
- that says to advance the location counter
- to a multiple of 2**LOG bytes. */
-
-#undef ASM_OUTPUT_ALIGN
-#define ASM_OUTPUT_ALIGN(FILE,LOG) \
- if ((LOG)!=0) fprintf ((FILE), "\t.align %d\n", 1<<(LOG))
-
-/* Define this macro if in some cases global symbols from one translation
- unit may not be bound to undefined symbols in another translation unit
- without user intervention. For instance, under Microsoft Windows
- symbols must be explicitly imported from shared libraries (DLLs). */
-#define MULTIPLE_SYMBOL_SPACES
-
-#define UNIQUE_SECTION_P(DECL) DECL_ONE_ONLY (DECL)
-extern void i386_pe_unique_section ();
-#define UNIQUE_SECTION(DECL,RELOC) i386_pe_unique_section (DECL, RELOC)
-
-#define SUPPORTS_ONE_ONLY 1
-
-/* A C statement to output something to the assembler file to switch to section
- NAME for object DECL which is either a FUNCTION_DECL, a VAR_DECL or
- NULL_TREE. Some target formats do not support arbitrary sections. Do not
- define this macro in such cases. */
-#undef ASM_OUTPUT_SECTION_NAME
-#define ASM_OUTPUT_SECTION_NAME(STREAM, DECL, NAME, RELOC) \
-do { \
- static struct section_info \
- { \
- struct section_info *next; \
- char *name; \
- enum sect_enum {SECT_RW, SECT_RO, SECT_EXEC} type; \
- } *sections; \
- struct section_info *s; \
- char *mode; \
- enum sect_enum type; \
- \
- for (s = sections; s; s = s->next) \
- if (!strcmp (NAME, s->name)) \
- break; \
- \
- if (DECL && TREE_CODE (DECL) == FUNCTION_DECL) \
- type = SECT_EXEC, mode = "x"; \
- else if (DECL && DECL_READONLY_SECTION (DECL, RELOC)) \
- type = SECT_RO, mode = ""; \
- else \
- type = SECT_RW, mode = "w"; \
- \
- if (s == 0) \
- { \
- s = (struct section_info *) xmalloc (sizeof (struct section_info)); \
- s->name = xmalloc ((strlen (NAME) + 1) * sizeof (*NAME)); \
- strcpy (s->name, NAME); \
- s->type = type; \
- s->next = sections; \
- sections = s; \
- fprintf (STREAM, ".section\t%s,\"%s\"\n", NAME, mode); \
- /* Functions may have been compiled at various levels of \
- optimization so we can't use `same_size' here. Instead, \
- have the linker pick one. */ \
- if ((DECL) && DECL_ONE_ONLY (DECL)) \
- fprintf (STREAM, "\t.linkonce %s\n", \
- TREE_CODE (DECL) == FUNCTION_DECL \
- ? "discard" : "same_size"); \
- } \
- else \
- { \
- fprintf (STREAM, ".section\t%s,\"%s\"\n", NAME, mode); \
- } \
-} while (0)
-
-/* Write the extra assembler code needed to declare a function
- properly. If we are generating SDB debugging information, this
- will happen automatically, so we only need to handle other cases. */
-#undef ASM_DECLARE_FUNCTION_NAME
-#define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \
- do \
- { \
- if (i386_pe_dllexport_name_p (NAME)) \
- { \
- drectve_section (); \
- fprintf ((FILE), "\t.ascii \" -export:%s\"\n", \
- I386_PE_STRIP_ENCODING (NAME)); \
- function_section (DECL); \
- } \
- if (write_symbols != SDB_DEBUG) \
- i386_pe_declare_function_type (FILE, NAME, TREE_PUBLIC (DECL)); \
- ASM_OUTPUT_LABEL (FILE, NAME); \
- } \
- while (0)
-
-/* Add an external function to the list of functions to be declared at
- the end of the file. */
-#define ASM_OUTPUT_EXTERNAL(FILE, DECL, NAME) \
- do \
- { \
- if (TREE_CODE (DECL) == FUNCTION_DECL) \
- i386_pe_record_external_function (NAME); \
- } \
- while (0)
-
-/* Declare the type properly for any external libcall. */
-#define ASM_OUTPUT_EXTERNAL_LIBCALL(FILE, FUN) \
- i386_pe_declare_function_type (FILE, XSTR (FUN, 0), 1)
-
-/* Output function declarations at the end of the file. */
-#define ASM_FILE_END(FILE) \
- i386_pe_asm_file_end (FILE)
-
-#undef ASM_COMMENT_START
-#define ASM_COMMENT_START " #"
-
-/* DWARF2 Unwinding doesn't work with exception handling yet. */
-#define DWARF2_UNWIND_INFO 0
-
-/* Don't assume anything about the header files. */
-#define NO_IMPLICIT_EXTERN_C
-
-#define SUBTARGET_PROLOGUE \
- if (profile_flag \
- && strcmp (IDENTIFIER_POINTER (DECL_NAME (current_function_decl)),\
- "main") == 0) \
- { \
- rtx xops[1]; \
- xops[0] = gen_rtx_MEM (FUNCTION_MODE, \
- gen_rtx (SYMBOL_REF, Pmode, "_monstartup")); \
- if (do_rtl) \
- emit_call_insn (gen_rtx (CALL, VOIDmode, xops[0], const0_rtx)); \
- else \
- output_asm_insn (AS1 (call,%P1), xops); \
- }
-
-/* External function declarations. */
-
-#ifndef PROTO
-#if defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__)
-#define PROTO(ARGS) ARGS
-#else
-#define PROTO(ARGS) ()
-#endif
-#endif
-
-#ifdef BUFSIZ /* stdio.h has been included, ok to use FILE * */
-#define STDIO_PROTO(ARGS) PROTO(ARGS)
-#else
-#define STDIO_PROTO(ARGS) ()
-#endif
-
-extern void i386_pe_record_external_function PROTO((char *));
-extern void i386_pe_declare_function_type STDIO_PROTO((FILE *, char *, int));
-extern void i386_pe_asm_file_end STDIO_PROTO((FILE *));
-
-/* For Win32 ABI compatibility */
-#undef DEFAULT_PCC_STRUCT_RETURN
-#define DEFAULT_PCC_STRUCT_RETURN 0
-
-/* No data type wants to be aligned rounder than this. */
-#undef BIGGEST_ALIGNMENT
-#define BIGGEST_ALIGNMENT 128
-
-/* A bitfield declared as `int' forces `int' alignment for the struct. */
-#undef PCC_BITFIELDS_TYPE_MATTERS
-#define PCC_BITFIELDS_TYPE_MATTERS 0
-
diff --git a/gcc/config/i386/dgux.c b/gcc/config/i386/dgux.c
index ff36135380c..638d1e0f60e 100644
--- a/gcc/config/i386/dgux.c
+++ b/gcc/config/i386/dgux.c
@@ -16,7 +16,8 @@ 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
#include <time.h>
#include "i386/i386.c"
@@ -29,6 +30,7 @@ struct option
char *string;
int *variable;
int on_value;
+ char *description;
};
static int
diff --git a/gcc/config/i386/dgux.h b/gcc/config/i386/dgux.h
index 692fb7dbc6b..75eacb4bfe0 100644
--- a/gcc/config/i386/dgux.h
+++ b/gcc/config/i386/dgux.h
@@ -16,7 +16,8 @@ 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
/* for now, we are just like the sysv4 version with a
few hacks
@@ -25,7 +26,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "i386/sysv4.h"
#ifndef VERSION_INFO2
-#define VERSION_INFO2 "$Revision: 1.6 $"
+#define VERSION_INFO2 "$Revision: 1.4 $"
#endif
#ifndef VERSION_STRING
diff --git a/gcc/config/i386/freebsd-elf.h b/gcc/config/i386/freebsd-elf.h
index 3c1934b4cda..1c4f1dc6389 100644
--- a/gcc/config/i386/freebsd-elf.h
+++ b/gcc/config/i386/freebsd-elf.h
@@ -26,8 +26,13 @@ Boston, MA 02111-1307, USA. */
/* The svr4 ABI for the i386 says that records and unions are returned
in memory. */
+/* On FreeBSD, we do not. */
#undef DEFAULT_PCC_STRUCT_RETURN
-#define DEFAULT_PCC_STRUCT_RETURN 1
+#define DEFAULT_PCC_STRUCT_RETURN 0
+
+/* This gets defined in tm.h->linux.h->svr4.h, and keeps us from using
+ libraries compiled with the native cc, so undef it. */
+#undef NO_DOLLAR_IN_LABEL
/* This is how to output an element of a case-vector that is relative.
This is only used for PIC code. See comments by the `casesi' insn in
@@ -194,7 +199,7 @@ Boston, MA 02111-1307, USA. */
#ifdef HAVE_GAS_MAX_SKIP_P2ALIGN
#define ASM_OUTPUT_MAX_SKIP_ALIGN(FILE,LOG,MAX_SKIP) \
- if ((LOG)!=0) \
- if ((MAX_SKIP)==0) fprintf ((FILE), "\t.p2align %d\n", (LOG)); \
+ if ((LOG) != 0) \
+ if ((MAX_SKIP) == 0) fprintf ((FILE), "\t.p2align %d\n", (LOG)); \
else fprintf ((FILE), "\t.p2align %d,,%d\n", (LOG), (MAX_SKIP))
#endif
diff --git a/gcc/config/i386/freebsd.h b/gcc/config/i386/freebsd.h
index df653ae3bd9..52302222ae3 100644
--- a/gcc/config/i386/freebsd.h
+++ b/gcc/config/i386/freebsd.h
@@ -20,9 +20,6 @@ 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 goes away when the math-emulator is fixed */
-#define TARGET_CPU_DEFAULT 0400 /* TARGET_NO_FANCY_MATH_387 */
-
/* This is tested by i386gas.h. */
#define YES_UNDERSCORES
@@ -34,6 +31,11 @@ Boston, MA 02111-1307, USA. */
/* Get perform_* macros to build libgcc.a. */
#include "i386/perform.h"
+/* This goes away when the math-emulator is fixed */
+#undef TARGET_DEFAULT
+#define TARGET_DEFAULT \
+ (MASK_80387 | MASK_IEEE_FP | MASK_FLOAT_RETURNS | MASK_NO_FANCY_MATH_387)
+
#undef CPP_PREDEFINES
#define CPP_PREDEFINES "-Dunix -Di386 -D__FreeBSD__ -Asystem(unix) -Asystem(FreeBSD) -Acpu(i386) -Amachine(i386)"
@@ -86,9 +88,13 @@ Boston, MA 02111-1307, USA. */
#define JUMP_TABLES_IN_TEXT_SECTION 1
-/* Don't default to pcc-struct-return, because gcc is the only compiler, and
- we want to retain compatibility with older gcc versions. */
+/* Don't default to pcc-struct-return, because in FreeBSD we prefer the
+ superior nature of the older gcc way. */
#define DEFAULT_PCC_STRUCT_RETURN 0
+
+/* Ensure we the configuration knows our system correctly so we can link with
+ libraries compiled with the native cc. */
+#undef NO_DOLLAR_IN_LABEL
/* i386 freebsd still uses old binutils that don't insert nops by default
when the .align directive demands to insert extra space in the text
diff --git a/gcc/config/i386/gas.h b/gcc/config/i386/gas.h
index 173bf1920ff..3350afef7bc 100644
--- a/gcc/config/i386/gas.h
+++ b/gcc/config/i386/gas.h
@@ -94,8 +94,8 @@ Boston, MA 02111-1307, USA. */
#ifdef HAVE_GAS_MAX_SKIP_P2ALIGN
# define ASM_OUTPUT_MAX_SKIP_ALIGN(FILE,LOG,MAX_SKIP) \
- if ((LOG)!=0) \
- if ((MAX_SKIP)==0) fprintf ((FILE), "\t.p2align %d\n", (LOG)); \
+ if ((LOG) != 0) \
+ if ((MAX_SKIP) == 0) fprintf ((FILE), "\t.p2align %d\n", (LOG)); \
else fprintf ((FILE), "\t.p2align %d,,%d\n", (LOG), (MAX_SKIP))
#endif
diff --git a/gcc/config/i386/go32-rtems.h b/gcc/config/i386/go32-rtems.h
deleted file mode 100644
index 9ae1998db51..00000000000
--- a/gcc/config/i386/go32-rtems.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/* Configuration for an i386 running RTEMS on top of MS-DOS with
- djgpp/go32 v1.x.
-
- Copyright (C) 1996 Free Software Foundation, Inc.
- Contributed by Joel Sherrill (joel@OARcorp.com).
-
-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/go32.h"
-
-/* Specify predefined symbols in preprocessor. */
-
-#ifdef CPP_PREDEFINES
-#undef CPP_PREDEFINES
-#endif
-#define CPP_PREDEFINES "-Dunix -Di386 -DGO32 -DMSDOS -Drtems -D__rtems__ \
- -Asystem(unix) -Asystem(msdos) -Acpu(i386) -Amachine(i386) -Asystem(rtems)"
-
-/* Generate calls to memcpy, memcmp and memset. */
-#ifndef TARGET_MEM_FUNCTIONS
-#define TARGET_MEM_FUNCTIONS
-#endif
-
-/* end of i386/go32-rtems.h */
-
diff --git a/gcc/config/i386/go32.h b/gcc/config/i386/go32.h
deleted file mode 100644
index c190f7fed15..00000000000
--- a/gcc/config/i386/go32.h
+++ /dev/null
@@ -1,99 +0,0 @@
-/* Configuration for an i386 running MS-DOS with djgpp/go32. */
-
-#include "dbxcoff.h"
-
-/* Don't assume anything about the header files. */
-#define NO_IMPLICIT_EXTERN_C
-
-#define HANDLE_SYSV_PRAGMA
-
-/* Enable parsing of #pragma pack(push,<n>) and #pragma pack(pop). */
-#define HANDLE_PRAGMA_PACK_PUSH_POP 1
-
-#define YES_UNDERSCORES
-
-#include "i386/gas.h"
-
-#ifdef CPP_PREDEFINES
-#undef CPP_PREDEFINES
-#endif
-#define CPP_PREDEFINES "-Dunix -Di386 -DGO32 -DMSDOS \
- -Asystem(unix) -Asystem(msdos) -Acpu(i386) -Amachine(i386)"
-
-#undef EXTRA_SECTIONS
-#define EXTRA_SECTIONS in_ctor, in_dtor
-
-#undef EXTRA_SECTION_FUNCTIONS
-#define EXTRA_SECTION_FUNCTIONS \
- CTOR_SECTION_FUNCTION \
- DTOR_SECTION_FUNCTION
-
-#define CTOR_SECTION_FUNCTION \
-void \
-ctor_section () \
-{ \
- if (in_section != in_ctor) \
- { \
- fprintf (asm_out_file, "\t.section .ctor\n"); \
- in_section = in_ctor; \
- } \
-}
-
-#define DTOR_SECTION_FUNCTION \
-void \
-dtor_section () \
-{ \
- if (in_section != in_dtor) \
- { \
- fprintf (asm_out_file, "\t.section .dtor\n"); \
- in_section = in_dtor; \
- } \
-}
-
-#define ASM_OUTPUT_CONSTRUCTOR(FILE,NAME) \
- do { \
- ctor_section (); \
- fprintf (FILE, "%s\t", ASM_LONG); \
- assemble_name (FILE, NAME); \
- fprintf (FILE, "\n"); \
- } while (0)
-
-/* Allow (eg) __attribute__((section "locked")) to work */
-#define ASM_OUTPUT_SECTION_NAME(FILE, DECL, NAME, RELOC)\
- do { \
- fprintf (FILE, "\t.section %s\n", NAME); \
- } while (0)
-
-#define ASM_OUTPUT_DESTRUCTOR(FILE,NAME) \
- do { \
- dtor_section (); \
- fprintf (FILE, "%s\t", ASM_LONG); \
- assemble_name (FILE, NAME); \
- fprintf (FILE, "\n"); \
- } while (0)
-
-/* Output at beginning of assembler file. */
-/* The .file command should always begin the output. */
-/* Use the main_input_filename instead of dump_base_name */
-
-#undef ASM_FILE_START
-#define ASM_FILE_START(FILE) \
- do { \
- output_file_directive (FILE, main_input_filename); \
- } while (0)
-
-/* This is how to output an assembler line
- that says to advance the location counter
- to a multiple of 2**LOG bytes. */
-
-#undef ASM_OUTPUT_ALIGN
-#define ASM_OUTPUT_ALIGN(FILE,LOG) \
- if ((LOG) != 0) fprintf ((FILE), "\t.p2align %d\n", LOG)
-
-/* djgpp has atexit (). */
-#undef HAVE_ATEXIT
-#define HAVE_ATEXIT
-
-/* djgpp automatically calls its own version of __main, so don't define one
- in libgcc, nor call one in main(). */
-#define HAS_INIT_SECTION
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 1d370657622..dad8c90e8e6 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -1,5 +1,5 @@
/* Subroutines for insn-output.c for Intel X86.
- Copyright (C) 1988, 92, 94, 95, 96, 97, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1988, 92, 94-98, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -622,9 +622,19 @@ i386_valid_type_attribute_p (type, attributes, identifier, args)
int
i386_comp_type_attributes (type1, type2)
- tree type1 ATTRIBUTE_UNUSED;
- tree type2 ATTRIBUTE_UNUSED;
+ tree type1;
+ tree type2;
{
+ /* Check for mismatch of non-default calling convention. */
+ char *rtdstr = TARGET_RTD ? "cdecl" : "stdcall";
+
+ if (TREE_CODE (type1) != FUNCTION_TYPE)
+ return 1;
+
+ /* Check for mismatched return types (cdecl vs stdcall). */
+ if (!lookup_attribute (rtdstr, TYPE_ATTRIBUTES (type1))
+ != !lookup_attribute (rtdstr, TYPE_ATTRIBUTES (type2)))
+ return 0;
return 1;
}
@@ -2079,6 +2089,62 @@ load_pic_register (do_rtl)
emit_insn (gen_blockage ());
}
+/* Compute the size of local storage taking into consideration the
+ desired stack alignment which is to be maintained. Also determine
+ the number of registers saved below the local storage. */
+
+HOST_WIDE_INT
+ix86_compute_frame_size (size, nregs_on_stack)
+ HOST_WIDE_INT size;
+ int *nregs_on_stack;
+{
+ int limit;
+ int nregs;
+ int regno;
+ int padding;
+ int pic_reg_used = flag_pic && (current_function_uses_pic_offset_table
+ || current_function_uses_const_pool);
+ HOST_WIDE_INT total_size;
+
+ limit = frame_pointer_needed
+ ? FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM;
+
+ nregs = 0;
+
+ for (regno = limit - 1; regno >= 0; regno--)
+ if ((regs_ever_live[regno] && ! call_used_regs[regno])
+ || (regno == PIC_OFFSET_TABLE_REGNUM && pic_reg_used))
+ nregs++;
+
+ padding = 0;
+ total_size = size + (nregs * UNITS_PER_WORD);
+
+#ifdef PREFERRED_STACK_BOUNDARY
+ {
+ int offset;
+ int preferred_alignment = PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT;
+
+ offset = 4;
+ if (frame_pointer_needed)
+ offset += UNITS_PER_WORD;
+
+ total_size += offset;
+
+ padding = ((total_size + preferred_alignment - 1)
+ & -preferred_alignment) - total_size;
+
+ if (padding < (((offset + preferred_alignment - 1)
+ & -preferred_alignment) - offset))
+ padding += preferred_alignment;
+ }
+#endif
+
+ if (nregs_on_stack)
+ *nregs_on_stack = nregs;
+
+ return size + padding;
+}
+
static void
ix86_prologue (do_rtl)
int do_rtl;
@@ -2088,7 +2154,7 @@ ix86_prologue (do_rtl)
rtx xops[4];
int pic_reg_used = flag_pic && (current_function_uses_pic_offset_table
|| current_function_uses_const_pool);
- long tsize = get_frame_size ();
+ HOST_WIDE_INT tsize = ix86_compute_frame_size (get_frame_size (), (int *)0);
rtx insn;
int cfa_offset = INCOMING_FRAME_SP_OFFSET, cfa_store_offset = cfa_offset;
@@ -2301,32 +2367,18 @@ ix86_epilogue (do_rtl)
int do_rtl;
{
register int regno;
- register int nregs, limit;
- int offset;
+ register int limit;
+ int nregs;
rtx xops[3];
int pic_reg_used = flag_pic && (current_function_uses_pic_offset_table
|| current_function_uses_const_pool);
- long tsize = get_frame_size ();
-
- /* Compute the number of registers to pop */
-
- limit = (frame_pointer_needed ? FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM);
+ int sp_valid = !frame_pointer_needed || current_function_sp_is_unchanging;
+ HOST_WIDE_INT offset;
+ HOST_WIDE_INT tsize = ix86_compute_frame_size (get_frame_size (), &nregs);
- nregs = 0;
-
- for (regno = limit - 1; regno >= 0; regno--)
- if ((regs_ever_live[regno] && ! call_used_regs[regno])
- || (regno == PIC_OFFSET_TABLE_REGNUM && pic_reg_used))
- nregs++;
-
- /* sp is often unreliable so we must go off the frame pointer.
-
- In reality, we may not care if sp is unreliable, because we can restore
- the register relative to the frame pointer. In theory, since each move
- is the same speed as a pop, and we don't need the leal, this is faster.
- For now restore multiple registers the old way. */
+ /* sp is often unreliable so we may have to go off the frame pointer. */
- offset = - tsize - (nregs * UNITS_PER_WORD);
+ offset = -(tsize + nregs * UNITS_PER_WORD);
xops[2] = stack_pointer_rtx;
@@ -2341,9 +2393,17 @@ ix86_epilogue (do_rtl)
if (flag_pic || profile_flag || profile_block_flag)
emit_insn (gen_blockage ());
- if (nregs > 1 || ! frame_pointer_needed)
+ /* If we're only restoring one register and sp is not valid then
+ using a move instruction to restore the register since it's
+ less work than reloading sp and popping the register. Otherwise,
+ restore sp (if necessary) and pop the registers. */
+
+ limit = frame_pointer_needed
+ ? FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM;
+
+ if (nregs > 1 || sp_valid)
{
- if (frame_pointer_needed)
+ if ( !sp_valid )
{
xops[0] = adj_offsettable_operand (AT_BP (QImode), offset);
if (do_rtl)
@@ -2550,7 +2610,7 @@ do { \
} \
} while (0)
-static int
+int
legitimate_pic_address_disp_p (disp)
register rtx disp;
{
@@ -2602,7 +2662,7 @@ legitimate_address_p (mode, addr, strict)
}
if (GET_CODE (addr) == REG || GET_CODE (addr) == SUBREG)
- base = addr;
+ base = addr;
else if (GET_CODE (addr) == PLUS)
{
@@ -2692,6 +2752,12 @@ legitimate_address_p (mode, addr, strict)
return FALSE;
}
+ if (GET_MODE (base) != Pmode)
+ {
+ ADDR_INVALID ("Base is not in Pmode.\n", base);
+ return FALSE;
+ }
+
if ((strict && ! REG_OK_FOR_BASE_STRICT_P (base))
|| (! strict && ! REG_OK_FOR_BASE_NONSTRICT_P (base)))
{
@@ -2713,6 +2779,12 @@ legitimate_address_p (mode, addr, strict)
return FALSE;
}
+ if (GET_MODE (indx) != Pmode)
+ {
+ ADDR_INVALID ("Index is not in Pmode.\n", indx);
+ return FALSE;
+ }
+
if ((strict && ! REG_OK_FOR_INDEX_STRICT_P (indx))
|| (! strict && ! REG_OK_FOR_INDEX_NONSTRICT_P (indx)))
{
@@ -5423,12 +5495,6 @@ output_fp_conditional_move (which_alternative, operands)
output_asm_insn (AS2 (fcmov%f1,%3,%0), operands);
break;
- case 2:
- /* r <- cond ? r : arg */
- output_asm_insn (AS2 (fcmov%F1,%2,%0), operands);
- output_asm_insn (AS2 (fcmov%f1,%3,%0), operands);
- break;
-
default:
abort ();
}
@@ -5488,17 +5554,6 @@ output_int_conditional_move (which_alternative, operands)
output_asm_insn (AS2 (cmov%c1,%3,%0), xops);
break;
- case 2:
- /* rm <- cond ? arg1 : arg2 */
- output_asm_insn (AS2 (cmov%C1,%2,%0), operands);
- output_asm_insn (AS2 (cmov%c1,%3,%0), operands);
- if (mode == DImode)
- {
- output_asm_insn (AS2 (cmov%C1,%2,%0), xops);
- output_asm_insn (AS2 (cmov%c1,%3,%0), xops);
- }
- break;
-
default:
abort ();
}
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index 8c3a877c645..d3dbc18b088 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -410,6 +410,11 @@ extern int ix86_arch;
/* Boundary (in *bits*) on which stack pointer should be aligned. */
#define STACK_BOUNDARY 32
+/* We want to keep the stack aligned to 128 bits when possible, for the
+ benefit of doubles and SSE __m128. But the compiler can not rely on
+ the stack having this alignment.*/
+#define PREFERRED_STACK_BOUNDARY 128
+
/* Allocation boundary (in *bits*) for the code of a function.
For i486, we get better performance by aligning to a cache
line (i.e. 16 byte) boundary. */
@@ -502,6 +507,46 @@ extern int ix86_arch;
: (ALIGN)) \
: (ALIGN))
+/* If defined, a C expression to compute the alignment for a local
+ variable. TYPE is the data type, and ALIGN is the alignment that
+ the object would ordinarily have. The value of this macro is used
+ instead of that alignment to align the object.
+
+ If this macro is not defined, then ALIGN is used.
+
+ One use of this macro is to increase alignment of medium-size
+ data to make it all fit in fewer cache lines. */
+
+#define LOCAL_ALIGNMENT(TYPE, ALIGN) \
+ (TREE_CODE (TYPE) == ARRAY_TYPE \
+ ? ((TYPE_MODE (TREE_TYPE (TYPE)) == DFmode && (ALIGN) < 64) \
+ ? 64 \
+ : (TYPE_MODE (TREE_TYPE (TYPE)) == XFmode && (ALIGN) < 128) \
+ ? 128 \
+ : (ALIGN)) \
+ : TREE_CODE (TYPE) == COMPLEX_TYPE \
+ ? ((TYPE_MODE (TYPE) == DCmode && (ALIGN) < 64) \
+ ? 64 \
+ : (TYPE_MODE (TYPE) == XCmode && (ALIGN) < 128) \
+ ? 128 \
+ : (ALIGN)) \
+ : ((TREE_CODE (TYPE) == RECORD_TYPE \
+ || TREE_CODE (TYPE) == UNION_TYPE \
+ || TREE_CODE (TYPE) == QUAL_UNION_TYPE) \
+ && TYPE_FIELDS (TYPE)) \
+ ? ((DECL_MODE (TYPE_FIELDS (TYPE)) == DFmode && (ALIGN) < 64) \
+ ? 64 \
+ : (DECL_MODE (TYPE_FIELDS (TYPE)) == XFmode && (ALIGN) < 128) \
+ ? 128 \
+ : (ALIGN)) \
+ : TREE_CODE (TYPE) == REAL_TYPE \
+ ? ((TYPE_MODE (TYPE) == DFmode && (ALIGN) < 64) \
+ ? 64 \
+ : (TYPE_MODE (TYPE) == XFmode && (ALIGN) < 128) \
+ ? 128 \
+ : (ALIGN)) \
+ : (ALIGN))
+
/* Set this non-zero if move instructions will actually fail to work
when given unaligned data. */
#define STRICT_ALIGNMENT 0
@@ -834,11 +879,6 @@ enum reg_class
#define STACK_TOP_P(xop) (REG_P (xop) && REGNO (xop) == FIRST_STACK_REG)
-/* Try to maintain the accuracy of the death notes for regs satisfying the
- following. Important for stack like regs, to know when to pop. */
-
-/* #define PRESERVE_DEATH_INFO_REGNO_P(x) FP_REGNO_P(x) */
-
/* 1 if register REGNO can magically overlap other regs.
Note that nonzero values work only in very special circumstances. */
@@ -896,19 +936,10 @@ enum reg_class
/* Similar, but for floating constants, and defining letters G and H.
Here VALUE is the CONST_DOUBLE rtx itself. We allow constants even if
TARGET_387 isn't set, because the stack register converter may need to
- load 0.0 into the function value register.
-
- We disallow these constants when -fomit-frame-pointer and compiling
- PIC code since reload might need to force the constant to memory.
- Forcing the constant to memory changes the elimination offsets after
- the point where they must stay constant.
-
- However, we must allow them after reload as completed as reg-stack.c
- will create insns which use these constants. */
+ load 0.0 into the function value register. */
#define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C) \
- (((reload_completed || !flag_pic || !flag_omit_frame_pointer) && (C) == 'G') \
- ? standard_80387_constant_p (VALUE) : 0)
+ ((C) == 'G' ? standard_80387_constant_p (VALUE) : 0)
/* Place additional restrictions on the register class to use when it
is necessary to be able to hold a value of mode MODE in a reload
@@ -1601,30 +1632,33 @@ do { \
(OFFSET) = 8; /* Skip saved PC and previous frame pointer */ \
else \
{ \
- int regno; \
- int offset = 0; \
+ int nregs; \
+ int offset; \
+ int preferred_alignment = PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT; \
+ HOST_WIDE_INT tsize = ix86_compute_frame_size (get_frame_size (), \
+ &nregs); \
\
- for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) \
- if ((regs_ever_live[regno] && ! call_used_regs[regno]) \
- || ((current_function_uses_pic_offset_table \
- || current_function_uses_const_pool) \
- && flag_pic && regno == PIC_OFFSET_TABLE_REGNUM)) \
- offset += 4; \
+ (OFFSET) = (tsize + nregs * UNITS_PER_WORD); \
\
- (OFFSET) = offset + get_frame_size (); \
+ offset = 4; \
+ if (frame_pointer_needed) \
+ offset += UNITS_PER_WORD; \
\
- if ((FROM) == ARG_POINTER_REGNUM && (TO) == STACK_POINTER_REGNUM) \
- (OFFSET) += 4; /* Skip saved PC */ \
+ if ((FROM) == ARG_POINTER_REGNUM) \
+ (OFFSET) += offset; \
+ else \
+ (OFFSET) -= ((offset + preferred_alignment - 1) \
+ & -preferred_alignment) - offset; \
} \
}
/* Addressing modes, and classification of registers for them. */
-/* #define HAVE_POST_INCREMENT */
-/* #define HAVE_POST_DECREMENT */
+/* #define HAVE_POST_INCREMENT 0 */
+/* #define HAVE_POST_DECREMENT 0 */
-/* #define HAVE_PRE_DECREMENT */
-/* #define HAVE_PRE_INCREMENT */
+/* #define HAVE_PRE_DECREMENT 0 */
+/* #define HAVE_PRE_INCREMENT 0 */
/* Macros to check register numbers against specific register classes. */
@@ -1710,7 +1744,8 @@ do { \
/* Nonzero if the constant value X is a legitimate general operand.
It is given that X satisfies CONSTANT_P or is a CONST_DOUBLE. */
-#define LEGITIMATE_CONSTANT_P(X) 1
+#define LEGITIMATE_CONSTANT_P(X) \
+ (GET_CODE (X) == CONST_DOUBLE ? standard_80387_constant_p (X) : 1)
#ifdef REG_OK_STRICT
#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
@@ -1763,8 +1798,7 @@ do { \
that X satisfies CONSTANT_P or is a CONST_DOUBLE. */
#define LEGITIMATE_PIC_OPERAND_P(X) \
- (! SYMBOLIC_CONST (X) \
- || (GET_CODE (X) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (X)))
+ (! SYMBOLIC_CONST (X) || legitimate_pic_address_disp_p (X))
#define SYMBOLIC_CONST(X) \
(GET_CODE (X) == SYMBOL_REF \
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index eea2b34c2e1..be4f0da2338 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -1,5 +1,5 @@
; GCC machine description for Intel X86.
-;; Copyright (C) 1988, 94, 95, 96, 97, 1998 Free Software Foundation, Inc.
+;; Copyright (C) 1988, 94, 95, 96, 97, 98, 1999 Free Software Foundation, Inc.
;; Mostly by William Schelter.
;; This file is part of GNU CC.
@@ -1252,7 +1252,7 @@
It is at least as fast as xor on any processor except a Pentium. */
if (operands[1] == const1_rtx
- && ix86_cpu == PROCESSOR_PENTIUM
+ && TARGET_PENTIUM
&& (link = find_reg_note (insn, REG_WAS_0, 0))
/* Make sure the insn that stored the 0 is still present. */
&& ! INSN_DELETED_P (XEXP (link, 0))
@@ -1313,7 +1313,7 @@
/* movb $0,reg8 is 2 bytes, the same as xorl reg8,reg8. */
if (operands[1] == const1_rtx
- && ix86_cpu == PROCESSOR_PENTIUM
+ && TARGET_PENTIUM
&& ! NON_QI_REG_P (operands[0])
&& (link = find_reg_note (insn, REG_WAS_0, 0))
/* Make sure the insn that stored the 0 is still present. */
@@ -1789,10 +1789,25 @@
;;- zero extension instructions
;; See comments by `andsi' for when andl is faster than movzx.
-(define_insn "zero_extendhisi2"
+(define_expand "zero_extendhisi2"
+ [(set (match_operand:SI 0 "register_operand" "")
+ (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
+ ""
+ "")
+
+;; When optimizing for the PPro/PII or code size, always use movzwl.
+;; We want to use a different pattern so we can use different constraints
+;; than the generic pattern.
+(define_insn ""
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
+ "(optimize_size || (int)ix86_cpu == (int)PROCESSOR_PENTIUMPRO)"
+ "* return AS2 (movz%W0%L0,%1,%0);")
+
+(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r,&r,?r")
(zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0,rm,rm")))]
- ""
+ "! (optimize_size || (int)ix86_cpu == (int)PROCESSOR_PENTIUMPRO)"
"*
{
rtx xops[2];
@@ -1853,10 +1868,23 @@
(const_int 65535)))]
"operands[2] = gen_rtx_REG (HImode, true_regnum (operands[0]));")
-(define_insn "zero_extendqihi2"
+(define_expand "zero_extendqihi2"
+ [(set (match_operand:HI 0 "register_operand" "")
+ (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]
+ ""
+ "")
+
+(define_insn ""
+ [(set (match_operand:HI 0 "register_operand" "=r")
+ (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
+ "optimize_size || (int)ix86_cpu == (int)PROCESSOR_PENTIUMPRO"
+
+ "* return AS2 (movz%B0%W0,%1,%0);")
+
+(define_insn ""
[(set (match_operand:HI 0 "register_operand" "=q,&q,?r")
(zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm,qm")))]
- ""
+ "! (optimize_size || (int)ix86_cpu == (int)PROCESSOR_PENTIUMPRO)"
"*
{
rtx xops[2];
@@ -1934,10 +1962,22 @@
FAIL;
operands[2] = gen_rtx_REG (HImode, REGNO (operands[1]));")
-(define_insn "zero_extendqisi2"
+(define_expand "zero_extendqisi2"
+ [(set (match_operand:SI 0 "register_operand" "")
+ (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
+ ""
+ "")
+
+(define_insn ""
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
+ "optimize_size || (int)ix86_cpu == (int)PROCESSOR_PENTIUMPRO"
+ "* return AS2 (movz%B0%L0,%1,%0);")
+
+(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=q,&q,?r")
(zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm,qm")))]
- ""
+ "! (optimize_size || (int)ix86_cpu == (int)PROCESSOR_PENTIUMPRO)"
"*
{
rtx xops[2];
@@ -2022,58 +2062,105 @@
"operands[2] = gen_rtx_REG (SImode, true_regnum (operands[1]));")
(define_insn "zero_extendsidi2"
- [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?m")
- (zero_extend:DI (match_operand:SI 1 "register_operand" "0,rm,r")))]
+ [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o")
+ (zero_extend:DI (match_operand:SI 1 "general_operand" "0,rm,r")))]
""
- "*
- {
- rtx high[2], low[2], xops[4];
-
- if (REG_P (operands[0]) && REG_P (operands[1])
- && REGNO (operands[0]) == REGNO (operands[1]))
- {
- operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
- return AS2 (xor%L0,%0,%0);
- }
-
- split_di (operands, 1, low, high);
- xops[0] = low[0];
- xops[1] = operands[1];
- xops[2] = high[0];
- xops[3] = const0_rtx;
-
- output_asm_insn (AS2 (mov%L0,%1,%0), xops);
- if (GET_CODE (low[0]) == MEM)
- output_asm_insn (AS2 (mov%L2,%3,%2), xops);
- else
- output_asm_insn (AS2 (xor%L2,%2,%2), xops);
+ "#")
- RET;
-}")
+(define_split
+ [(set (match_operand:DI 0 "register_operand" "")
+ (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
+ "reload_completed && true_regnum (operands[0]) == true_regnum (operands[1])"
+ [(set (match_dup 4) (const_int 0))]
+ "split_di (&operands[0], 1, &operands[3], &operands[4]);")
+
+(define_split
+ [(set (match_operand:DI 0 "nonimmediate_operand" "")
+ (zero_extend:DI (match_operand:SI 1 "general_operand" "")))]
+ "reload_completed"
+ [(set (match_dup 3) (match_dup 1))
+ (set (match_dup 4) (const_int 0))]
+ "split_di (&operands[0], 1, &operands[3], &operands[4]);")
;;- sign extension instructions
(define_insn "extendsidi2"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (sign_extend:DI (match_operand:SI 1 "register_operand" "0")))]
+ [(set (match_operand:DI 0 "nonimmediate_operand" "=A,?r,?Ar,*o")
+ (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,*r")))
+ (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
""
- "*
+ "#")
+
+;; Extend to memory case when source register does die.
+(define_split
+ [(set (match_operand:DI 0 "memory_operand" "")
+ (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
+ (clobber (match_operand:SI 2 "register_operand" ""))]
+ "(flow2_completed
+ && dead_or_set_p (insn, operands[1])
+ && !reg_mentioned_p (operands[1], operands[0]))"
+ [(set (match_dup 3) (match_dup 1))
+ (set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
+ (set (match_dup 4) (match_dup 1))]
+ "split_di (&operands[0], 1, &operands[3], &operands[4]);")
+
+;; Extend to memory case when source register does not die.
+(define_split
+ [(set (match_operand:DI 0 "memory_operand" "")
+ (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
+ (clobber (match_operand:SI 2 "register_operand" ""))]
+ "flow2_completed"
+ [(const_int 0)]
+ "
{
- if (REGNO (operands[0]) == 0)
+ split_di (&operands[0], 1, &operands[3], &operands[4]);
+
+ emit_move_insn (operands[3], operands[1]);
+
+ /* Generate a cltd if possible and doing so it profitable. */
+ if (true_regnum (operands[1]) == 0
+ && true_regnum (operands[2]) == 1
+ && (optimize_size || !TARGET_PENTIUM))
{
- /* This used to be cwtl, but that extends HI to SI somehow. */
-#ifdef INTEL_SYNTAX
- return \"cdq\";
-#else
- return \"cltd\";
-#endif
+ emit_insn (gen_ashrsi3_31 (operands[2], operands[1]));
+ }
+ else
+ {
+ emit_move_insn (operands[2], operands[1]);
+ emit_insn (gen_ashrsi3_31 (operands[2], operands[2]));
+ }
+ emit_move_insn (operands[4], operands[2]);
+ DONE;
+}")
+
+;; Extend to register case. Optimize case where source and destination
+;; registers match and cases where we can use cltd.
+(define_split
+ [(set (match_operand:DI 0 "register_operand" "")
+ (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
+ (clobber (match_scratch:SI 2 ""))]
+ "reload_completed"
+ [(const_int 0)]
+ "
+{
+ split_di (&operands[0], 1, &operands[3], &operands[4]);
+
+ if (true_regnum (operands[3]) != true_regnum (operands[1]))
+ emit_move_insn (operands[3], operands[1]);
+
+ /* Generate a cltd if possible and doing so it profitable. */
+ if (true_regnum (operands[3]) == 0
+ && (optimize_size || !TARGET_PENTIUM))
+ {
+ emit_insn (gen_ashrsi3_31 (operands[4], operands[3]));
+ DONE;
}
- operands[1] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
- output_asm_insn (AS2 (mov%L0,%0,%1), operands);
+ if (true_regnum (operands[4]) != true_regnum (operands[1]))
+ emit_move_insn (operands[4], operands[1]);
- operands[0] = GEN_INT (31);
- return AS2 (sar%L1,%0,%1);
+ emit_insn (gen_ashrsi3_31 (operands[4], operands[4]));
+ DONE;
}")
;; Note that the i386 programmers' manual says that the opcodes
@@ -3008,7 +3095,7 @@
"*
{
if (REG_P (operands[0]) && REG_P (operands[1])
- && (REG_P (operands[2]) || GET_CODE (operands[2]) == CONST_INT)
+ && (REG_P (operands[2]) || CONSTANT_P (operands[2]))
&& REGNO (operands[0]) != REGNO (operands[1]))
{
if (REG_P (operands[2]) && REGNO (operands[0]) == REGNO (operands[2]))
@@ -4640,8 +4727,7 @@ byte_xor_operation:
""
"*
{
- rtx xops[4], low[1], high[1];
- static int ashldi_label_number;
+ rtx xops[5], low[1], high[1];
CC_STATUS_INIT;
@@ -4650,27 +4736,193 @@ byte_xor_operation:
xops[1] = GEN_INT (32);
xops[2] = low[0];
xops[3] = high[0];
+ xops[4] = gen_label_rtx ();
output_asm_insn (AS3_SHIFT_DOUBLE (shld%L3,%0,%2,%3), xops);
output_asm_insn (AS2 (sal%L2,%0,%2), xops);
output_asm_insn (AS2 (test%B0,%1,%b0), xops);
- asm_fprintf (asm_out_file, \"\\tje %LLASHLDI%d\\n\", ashldi_label_number);
+ output_asm_insn (AS1 (je,%X4), xops);
output_asm_insn (AS2 (mov%L3,%2,%3), xops); /* Fast shift by 32 */
output_asm_insn (AS2 (xor%L2,%2,%2), xops);
- asm_fprintf (asm_out_file, \"%LLASHLDI%d:\\n\", ashldi_label_number++);
-
+ ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
+ CODE_LABEL_NUMBER (xops[4]));
RET;
}")
+(define_expand "ashlsi3"
+ [(set (match_operand:SI 0 "nonimmediate_operand" "")
+ (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
+ (match_operand:SI 2 "nonmemory_operand" "")))]
+ ""
+ "")
+
+;; Optimizing for code size:
+;; For regsiter destinations:
+;; add == 2 bytes, move == 2 bytes, shift == 3 bytes, lea == 7 bytes
+;;
+;; lea loses when optimizing for size
+;;
+;; Do the math. If the count is 1, using add, else using sal will
+;; produce the smallest possible code, even when the source and
+;; dest do not match. For a memory destination, sal is the only
+;; choice.
+;;
+;; Do not try to handle case where src and dest do not match. Let regmove
+;; and reload handle them. A mov followed by this insn will generate the
+;; desired size optimized results.
+(define_insn ""
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
+ (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
+ (match_operand:SI 2 "nonmemory_operand" "cI")))]
+ "optimize_size"
+ "*
+{
+ if (REG_P (operands[0]) && operands[2] == const1_rtx)
+ return AS2 (add%L0,%0,%0);
+
+ if (REG_P (operands[2]))
+ return AS2 (sal%L0,%b2,%0);
+ return AS2 (sal%L0,%2,%0);
+}")
+
+;; For Pentium/Pentium MMX:
+;;
+;; We want to optimize for pairability, but avoid generating AGI stalls.
+;;
+;; If this insn is expected to issue in the U pipe, then prefer sal,
+;; else prefer lea for small shifts when srcreg == dstreg.
+;;
+;; For PPro/PII
+;;
+;; There's more than one approach to optimizing for this family; it is
+;; unclear which approach is best. For now, we will try to minimize
+;; uops. Note that sal and lea have the same characteristics, so we
+;; prefer sal as it takes less space.
+;;
+;; We can actually share code for these two cases since the basic techniques
+;; for generating good code on these chips is the same, even if the final
+;; code sequences are different.
+;;
+;; I do not know what is most appropriate for the AMD or Cyrix chips.
+;;
+;; srcreg == dstreg, constant shift count:
+;;
+;; For a shift count of one, use "add".
+;; For a shift count of two or three, use "sal"/"lea" for Pentium and
+;; Pentium MMX depending on which pipe the insn will execute.
+;; All others use "sar".
+;;
+;; srcreg != dstreg, constant shift count:
+;;
+;; For shift counts of one to three, use "lea".
+;; All others use "lea" for the first shift into the destination reg,
+;; then fall back on the srcreg == dstreg for the residual shifts.
+;;
+;; memory destinations or nonconstant shift count:
+;;
+;; Use "sal".
+;;
+(define_insn ""
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
+ (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,r")
+ (match_operand:SI 2 "nonmemory_operand" "cI,I")))]
+ "! optimize_size
+ && ((int)ix86_cpu == (int)PROCESSOR_PENTIUM
+ || (int)ix86_cpu == (int)PROCESSOR_PENTIUMPRO)"
+ "*
+{
+ /* This should be extremely rare (impossible?). We can not encode a shift
+ of the stack pointer using an lea instruction. So copy the stack pointer
+ into the destination register and fall into the srcreg == dstreg shifting
+ support. */
+ if (operands[1] == stack_pointer_rtx)
+ {
+ output_asm_insn (AS2 (mov%L0,%1,%0), operands);
+ operands[1] = operands[0];
+ }
+
+ /* Handle case where srcreg != dstreg. */
+ if (REG_P (operands[0]) && REGNO (operands[0]) != REGNO (operands[1]))
+ {
+ /* For counts > 3, it is easiest to split into component insns. */
+ if (INTVAL (operands[2]) > 3)
+ return \"#\";
+
+ /* For shifts up to and including 3 bits, use lea. */
+ operands[1] = gen_rtx_MULT (SImode, operands[1],
+ GEN_INT (1 << INTVAL (operands[2])));
+ return AS2 (lea%L0,%a1,%0);
+ }
+
+ /* Source and destination match. */
+
+ /* Handle variable shift. */
+ if (REG_P (operands[2]))
+ return AS2 (sal%L0,%b2,%0);
+
+ /* Always perform shift by 1 using an add instruction. */
+ if (REG_P (operands[0]) && operands[2] == const1_rtx)
+ return AS2 (add%L0,%0,%0);
+
+#if 0
+ /* ??? Currently disabled. reg-stack currently stomps on the mode of
+ each insn. Thus, we can not easily detect when we should use lea to
+ improve issue characteristics. Until reg-stack is fixed, fall back to
+ sal instruction for Pentiums to avoid AGI stall. */
+ /* Shift reg by 2 or 3 use an lea instruction for Pentium if this is
+ insn is expected to issue into the V pipe (the insn's mode will be
+ TImode for a U pipe, and !TImode for a V pipe instruction). */
+ if (REG_P (operands[0])
+ && GET_CODE (operands[2]) == CONST_INT
+ && INTVAL (operands[2]) <= 3
+ && (int)ix86_cpu == (int)PROCESSOR_PENTIUM
+ && GET_MODE (insn) != TImode)
+ {
+ operands[1] = gen_rtx_MULT (SImode, operands[1],
+ GEN_INT (1 << INTVAL (operands[2])));
+ return AS2 (lea%L0,%a1,%0);
+ }
+#endif
+
+ /* Otherwise use a shift instruction. */
+ return AS2 (sal%L0,%2,%0);
+}")
+
+;; Pentium/PPro/PII Splitter used when srcreg != destreg and shift
+;; count is > 3. In each case we use lea to perform the first three
+;; shifts into the destination register, then we fall back to the
+;; normal shifting code for the residual shifts.
+(define_split
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (ashift:SI (match_operand:SI 1 "register_operand" "r")
+ (match_operand:SI 2 "immediate_operand" "I")))]
+ "reload_completed
+ && ! optimize_size
+ && ((int)ix86_cpu == (int)PROCESSOR_PENTIUM
+ || (int)ix86_cpu == (int)PROCESSOR_PENTIUMPRO)
+ && GET_CODE (operands[2]) == CONST_INT
+ && INTVAL (operands[2]) > 3
+ && true_regnum (operands[0]) != true_regnum (operands[1])"
+ [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))
+ (set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 3)))]
+ "
+{
+ operands[3] = GEN_INT (INTVAL (operands[2]) - 3);
+ operands[2] = GEN_INT (3);
+}")
+
+
;; On i386 and i486, "addl reg,reg" is faster than "sall $1,reg"
;; On i486, movl/sall appears slightly faster than leal, but the leal
;; is smaller - use leal for now unless the shift count is 1.
-
-(define_insn "ashlsi3"
- [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
- (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "r,0")
- (match_operand:SI 2 "nonmemory_operand" "M,cI")))]
- ""
+;;
+(define_insn ""
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
+ (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,r")
+ (match_operand:SI 2 "nonmemory_operand" "cI,M")))]
+ "! optimize_size
+ && ! ((int)ix86_cpu == (int)PROCESSOR_PENTIUM
+ || (int)ix86_cpu == (int)PROCESSOR_PENTIUMPRO)"
"*
{
if (REG_P (operands[0]) && REGNO (operands[0]) != REGNO (operands[1]))
@@ -4828,8 +5080,7 @@ byte_xor_operation:
""
"*
{
- rtx xops[4], low[1], high[1];
- static int ashrdi_label_number;
+ rtx xops[5], low[1], high[1];
CC_STATUS_INIT;
@@ -4838,19 +5089,29 @@ byte_xor_operation:
xops[1] = GEN_INT (32);
xops[2] = low[0];
xops[3] = high[0];
+ xops[4] = gen_label_rtx ();
output_asm_insn (AS3_SHIFT_DOUBLE (shrd%L2,%0,%3,%2), xops);
output_asm_insn (AS2 (sar%L3,%0,%3), xops);
output_asm_insn (AS2 (test%B0,%1,%b0), xops);
- asm_fprintf (asm_out_file, \"\\tje %LLASHRDI%d\\n\", ashrdi_label_number);
+ output_asm_insn (AS1 (je,%X4), xops);
xops[1] = GEN_INT (31);
output_asm_insn (AS2 (mov%L2,%3,%2), xops);
output_asm_insn (AS2 (sar%L3,%1,%3), xops); /* shift by 32 */
- asm_fprintf (asm_out_file, \"%LLASHRDI%d:\\n\", ashrdi_label_number++);
-
+ ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
+ CODE_LABEL_NUMBER (xops[4]));
RET;
}")
+(define_insn "ashrsi3_31"
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,d")
+ (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,a")
+ (const_int 31)))]
+ "!TARGET_PENTIUM || optimize_size"
+ "@
+ sar%L0 $31,%0
+ cltd")
+
(define_insn "ashrsi3"
[(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
(ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
@@ -4983,8 +5244,7 @@ byte_xor_operation:
""
"*
{
- rtx xops[4], low[1], high[1];
- static int lshrdi_label_number;
+ rtx xops[5], low[1], high[1];
CC_STATUS_INIT;
@@ -4993,15 +5253,16 @@ byte_xor_operation:
xops[1] = GEN_INT (32);
xops[2] = low[0];
xops[3] = high[0];
+ xops[4] = gen_label_rtx ();
output_asm_insn (AS3_SHIFT_DOUBLE (shrd%L2,%0,%3,%2), xops);
output_asm_insn (AS2 (shr%L3,%0,%3), xops);
output_asm_insn (AS2 (test%B0,%1,%b0), xops);
- asm_fprintf (asm_out_file, \"\\tje %LLLSHRDI%d\\n\", lshrdi_label_number);
+ output_asm_insn (AS1 (je,%X4), xops);
output_asm_insn (AS2 (mov%L2,%3,%2), xops); /* Fast shift by 32 */
output_asm_insn (AS2 (xor%L3,%3,%3), xops);
- asm_fprintf (asm_out_file, \"%LLLSHRDI%d:\\n\", lshrdi_label_number++);
-
+ ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
+ CODE_LABEL_NUMBER (xops[4]));
RET;
}")
@@ -5733,7 +5994,8 @@ byte_xor_operation:
[(set (pc)
(label_ref (match_operand 0 "" "")))]
""
- "jmp %l0")
+ "jmp %l0"
+ [(set_attr "memory" "none")])
(define_insn "indirect_jump"
[(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
@@ -5743,7 +6005,8 @@ byte_xor_operation:
CC_STATUS_INIT;
return AS1 (jmp,%*%0);
-}")
+}"
+ [(set_attr "memory" "none")])
;; ??? could transform while(--i > 0) S; to if (--i > 0) do S; while(--i);
;; if S does not change i
@@ -6045,6 +6308,12 @@ byte_xor_operation:
{
rtx addr;
+ if (operands[3] == const0_rtx)
+ {
+ emit_insn (gen_call (operands[0], operands[1]));
+ DONE;
+ }
+
if (flag_pic)
current_function_uses_pic_offset_table = 1;
@@ -6147,6 +6416,12 @@ byte_xor_operation:
{
rtx addr;
+ if (operands[4] == const0_rtx)
+ {
+ emit_insn (gen_call_value (operands[0], operands[1], operands[2]));
+ DONE;
+ }
+
if (flag_pic)
current_function_uses_pic_offset_table = 1;
@@ -6286,7 +6561,8 @@ byte_xor_operation:
(define_insn "blockage"
[(unspec_volatile [(const_int 0)] 0)]
""
- "")
+ ""
+ [(set_attr "memory" "none")])
;; Insn emitted into the body of a function to return from a function.
;; This is only done if the function's epilogue is known to be simple.
@@ -6300,18 +6576,21 @@ byte_xor_operation:
(define_insn "return_internal"
[(return)]
"reload_completed"
- "ret")
+ "ret"
+ [(set_attr "memory" "none")])
(define_insn "return_pop_internal"
[(return)
(use (match_operand:SI 0 "const_int_operand" ""))]
"reload_completed"
- "ret %0")
+ "ret %0"
+ [(set_attr "memory" "none")])
(define_insn "nop"
[(const_int 0)]
""
- "nop")
+ "nop"
+ [(set_attr "memory" "none")])
(define_expand "prologue"
[(const_int 1)]
@@ -6338,7 +6617,8 @@ byte_xor_operation:
xops[1] = stack_pointer_rtx;
output_asm_insn (AS2 (sub%L1,%0,%1), xops);
RET;
-}")
+}"
+ [(set_attr "memory" "none")])
(define_insn "prologue_set_got"
[(set (match_operand:SI 0 "" "")
@@ -6370,15 +6650,14 @@ byte_xor_operation:
""
"*
{
- char buffer[64];
-
output_asm_insn (AS1 (call,%X1), operands);
if (! TARGET_DEEP_BRANCH_PREDICTION)
{
ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", CODE_LABEL_NUMBER (operands[1]));
}
RET;
-}")
+}"
+ [(set_attr "memory" "none")])
(define_insn "prologue_get_pc_and_set_got"
[(unspec_volatile [(match_operand:SI 0 "" "")] 3)]
@@ -6392,7 +6671,8 @@ byte_xor_operation:
output_asm_insn (AS1 (pop%L0,%0), operands);
output_asm_insn (\"addl $_GLOBAL_OFFSET_TABLE_+[.-%X1],%0\", operands);
RET;
-}")
+}"
+ [(set_attr "memory" "none")])
(define_expand "epilogue"
[(const_int 1)]
@@ -6415,14 +6695,16 @@ byte_xor_operation:
xops[1] = stack_pointer_rtx;
output_asm_insn (AS2 (mov%L0,%0,%1), xops);
RET;
-}")
+}"
+ [(set_attr "memory" "none")])
(define_insn "leave"
[(const_int 2)
(clobber (reg:SI 6))
(clobber (reg:SI 7))]
""
- "leave")
+ "leave"
+ [(set_attr "memory" "none")])
(define_insn "pop"
[(set (match_operand:SI 0 "register_operand" "r")
@@ -6433,7 +6715,8 @@ byte_xor_operation:
{
output_asm_insn (AS1 (pop%L0,%P0), operands);
RET;
-}")
+}"
+ [(set_attr "memory" "load")])
(define_expand "movstrsi"
[(parallel [(set (match_operand:BLK 0 "memory_operand" "")
@@ -7073,32 +7356,32 @@ byte_xor_operation:
}")
(define_insn ""
- [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r")
+ [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
(if_then_else:SI (match_operator 1 "comparison_operator"
- [(match_operand:QI 2 "nonimmediate_operand" "q,m,q,m,q,m")
- (match_operand:QI 3 "general_operand" "qmn,qn,qmn,qn,qmn,qn")])
- (match_operand:SI 4 "nonimmediate_operand" "rm,rm,0,0,rm,rm")
- (match_operand:SI 5 "nonimmediate_operand" "0,0,rm,rm,rm,rm")))]
+ [(match_operand:QI 2 "nonimmediate_operand" "q,m,q,m")
+ (match_operand:QI 3 "general_operand" "qmn,qn,qmn,qn")])
+ (match_operand:SI 4 "nonimmediate_operand" "rm,rm,0,0")
+ (match_operand:SI 5 "nonimmediate_operand" "0,0,rm,rm")))]
"TARGET_CMOVE"
"#")
(define_insn ""
- [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r")
+ [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
(if_then_else:SI (match_operator 1 "comparison_operator"
- [(match_operand 2 "nonimmediate_operand" "r,m,r,m,r,m")
- (match_operand 3 "general_operand" "rmi,ri,rmi,ri,rmi,ri")])
- (match_operand:SI 4 "nonimmediate_operand" "rm,rm,0,0,rm,rm")
- (match_operand:SI 5 "nonimmediate_operand" "0,0,rm,rm,rm,rm")))]
+ [(match_operand 2 "nonimmediate_operand" "r,m,r,m")
+ (match_operand 3 "general_operand" "rmi,ri,rmi,ri")])
+ (match_operand:SI 4 "nonimmediate_operand" "rm,rm,0,0")
+ (match_operand:SI 5 "nonimmediate_operand" "0,0,rm,rm")))]
"TARGET_CMOVE && GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT"
"#")
(define_split
- [(set (match_operand:SI 0 "register_operand" "=r,r,r")
+ [(set (match_operand:SI 0 "register_operand" "=r,r")
(if_then_else:SI (match_operator 1 "comparison_operator"
[(match_operand 2 "nonimmediate_operand" "")
(const_int 0)])
- (match_operand:SI 3 "nonimmediate_operand" "rm,0,rm")
- (match_operand:SI 4 "nonimmediate_operand" "0,rm,rm")))]
+ (match_operand:SI 3 "nonimmediate_operand" "rm,0")
+ (match_operand:SI 4 "nonimmediate_operand" "0,rm")))]
"TARGET_CMOVE && reload_completed"
[(set (cc0)
(match_dup 2))
@@ -7108,12 +7391,12 @@ byte_xor_operation:
"")
(define_split
- [(set (match_operand:SI 0 "register_operand" "=r,r,r")
+ [(set (match_operand:SI 0 "register_operand" "=r,r")
(if_then_else:SI (match_operator 1 "comparison_operator"
[(match_operand 2 "nonimmediate_operand" "")
(match_operand 3 "general_operand" "")])
- (match_operand:SI 4 "nonimmediate_operand" "rm,0,rm")
- (match_operand:SI 5 "nonimmediate_operand" "0,rm,rm")))]
+ (match_operand:SI 4 "nonimmediate_operand" "rm,0")
+ (match_operand:SI 5 "nonimmediate_operand" "0,rm")))]
"TARGET_CMOVE && reload_completed"
[(set (cc0) (compare (match_dup 2) (match_dup 3)))
(set (match_dup 0)
@@ -7122,11 +7405,11 @@ byte_xor_operation:
"")
(define_insn ""
- [(set (match_operand:SI 0 "register_operand" "=r,r,r")
+ [(set (match_operand:SI 0 "register_operand" "=r,r")
(if_then_else:SI (match_operator 1 "comparison_operator"
[(cc0) (const_int 0)])
- (match_operand:SI 2 "nonimmediate_operand" "rm,0,rm")
- (match_operand:SI 3 "nonimmediate_operand" "0,rm,rm")))]
+ (match_operand:SI 2 "nonimmediate_operand" "rm,0")
+ (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
"TARGET_CMOVE && reload_completed"
"* return output_int_conditional_move (which_alternative, operands);")
@@ -7147,32 +7430,32 @@ byte_xor_operation:
}")
(define_insn ""
- [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r,r")
+ [(set (match_operand:HI 0 "register_operand" "=r,r,r,r")
(if_then_else:HI (match_operator 1 "comparison_operator"
- [(match_operand:QI 2 "nonimmediate_operand" "q,m,q,m,q,m")
- (match_operand:QI 3 "general_operand" "qmn,qn,qmn,qn,qmn,qn")])
- (match_operand:HI 4 "nonimmediate_operand" "rm,rm,0,0,rm,rm")
- (match_operand:HI 5 "nonimmediate_operand" "0,0,rm,rm,rm,rm")))]
+ [(match_operand:QI 2 "nonimmediate_operand" "q,m,q,m")
+ (match_operand:QI 3 "general_operand" "qmn,qn,qmn,qn")])
+ (match_operand:HI 4 "nonimmediate_operand" "rm,rm,0,0")
+ (match_operand:HI 5 "nonimmediate_operand" "0,0,rm,rm")))]
"TARGET_CMOVE"
"#")
(define_insn ""
- [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r,r")
+ [(set (match_operand:HI 0 "register_operand" "=r,r,r,r")
(if_then_else:HI (match_operator 1 "comparison_operator"
- [(match_operand 2 "nonimmediate_operand" "r,m,r,m,r,m")
- (match_operand 3 "general_operand" "rmi,ri,rmi,ri,rmi,ri")])
- (match_operand:HI 4 "nonimmediate_operand" "rm,rm,0,0,rm,rm")
- (match_operand:HI 5 "nonimmediate_operand" "0,0,rm,rm,rm,rm")))]
+ [(match_operand 2 "nonimmediate_operand" "r,m,r,m")
+ (match_operand 3 "general_operand" "rmi,ri,rmi,ri")])
+ (match_operand:HI 4 "nonimmediate_operand" "rm,rm,0,0")
+ (match_operand:HI 5 "nonimmediate_operand" "0,0,rm,rm")))]
"TARGET_CMOVE && GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT"
"#")
(define_split
- [(set (match_operand:HI 0 "register_operand" "=r,r,r")
+ [(set (match_operand:HI 0 "register_operand" "=r,r")
(if_then_else:HI (match_operator 1 "comparison_operator"
[(match_operand 2 "nonimmediate_operand" "")
(const_int 0)])
- (match_operand:HI 3 "nonimmediate_operand" "rm,0,rm")
- (match_operand:HI 4 "nonimmediate_operand" "0,rm,rm")))]
+ (match_operand:HI 3 "nonimmediate_operand" "rm,0")
+ (match_operand:HI 4 "nonimmediate_operand" "0,rm")))]
"TARGET_CMOVE && reload_completed"
[(set (cc0)
(match_dup 2))
@@ -7182,12 +7465,12 @@ byte_xor_operation:
"")
(define_split
- [(set (match_operand:HI 0 "register_operand" "=r,r,r")
+ [(set (match_operand:HI 0 "register_operand" "=r,r")
(if_then_else:HI (match_operator 1 "comparison_operator"
[(match_operand 2 "nonimmediate_operand" "")
(match_operand 3 "general_operand" "")])
- (match_operand:HI 4 "nonimmediate_operand" "rm,0,rm")
- (match_operand:HI 5 "nonimmediate_operand" "0,rm,rm")))]
+ (match_operand:HI 4 "nonimmediate_operand" "rm,0")
+ (match_operand:HI 5 "nonimmediate_operand" "0,rm")))]
"TARGET_CMOVE && reload_completed"
[(set (cc0)
(compare (match_dup 2) (match_dup 3)))
@@ -7197,11 +7480,11 @@ byte_xor_operation:
"")
(define_insn ""
- [(set (match_operand:HI 0 "register_operand" "=r,r,r")
+ [(set (match_operand:HI 0 "register_operand" "=r,r")
(if_then_else:HI (match_operator 1 "comparison_operator"
[(cc0) (const_int 0)])
- (match_operand:HI 2 "nonimmediate_operand" "rm,0,rm")
- (match_operand:HI 3 "nonimmediate_operand" "0,rm,rm")))]
+ (match_operand:HI 2 "nonimmediate_operand" "rm,0")
+ (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
"TARGET_CMOVE && reload_completed"
"* return output_int_conditional_move (which_alternative, operands);")
@@ -7246,36 +7529,36 @@ byte_xor_operation:
}")
(define_insn ""
- [(set (match_operand:SF 0 "register_operand" "=f,f,f,f,f,f")
+ [(set (match_operand:SF 0 "register_operand" "=f,f,f,f")
(if_then_else:SF (match_operator 1 "comparison_operator"
- [(match_operand:QI 2 "nonimmediate_operand" "q,m,q,m,q,m")
- (match_operand:QI 3 "general_operand" "qmn,qn,qmn,qn,qmn,qn")])
- (match_operand:SF 4 "register_operand" "f,f,0,0,f,f")
- (match_operand:SF 5 "register_operand" "0,0,f,f,f,f")))]
+ [(match_operand:QI 2 "nonimmediate_operand" "q,m,q,m")
+ (match_operand:QI 3 "general_operand" "qmn,qn,qmn,qn")])
+ (match_operand:SF 4 "register_operand" "f,f,0,0")
+ (match_operand:SF 5 "register_operand" "0,0,f,f")))]
"TARGET_CMOVE
&& GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != LE
&& GET_CODE (operands[1]) != GE && GET_CODE (operands[1]) != GT"
"#")
(define_insn ""
- [(set (match_operand:SF 0 "register_operand" "=f,f,f,f,f,f")
+ [(set (match_operand:SF 0 "register_operand" "=f,f,f,f")
(if_then_else:SF (match_operator 1 "comparison_operator"
- [(match_operand 2 "nonimmediate_operand" "r,m,r,m,r,m")
- (match_operand 3 "general_operand" "rmi,ri,rmi,ri,rmi,ri")])
- (match_operand:SF 4 "register_operand" "f,f,0,0,f,f")
- (match_operand:SF 5 "register_operand" "0,0,f,f,f,f")))]
+ [(match_operand 2 "nonimmediate_operand" "r,m,r,m")
+ (match_operand 3 "general_operand" "rmi,ri,rmi,ri")])
+ (match_operand:SF 4 "register_operand" "f,f,0,0")
+ (match_operand:SF 5 "register_operand" "0,0,f,f")))]
"TARGET_CMOVE && GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT
&& GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != LE
&& GET_CODE (operands[1]) != GE && GET_CODE (operands[1]) != GT"
"#")
(define_split
- [(set (match_operand:SF 0 "register_operand" "=f,f,f")
+ [(set (match_operand:SF 0 "register_operand" "=f,f")
(if_then_else:SF (match_operator 1 "comparison_operator"
[(match_operand 2 "nonimmediate_operand" "")
(const_int 0)])
- (match_operand:SF 3 "register_operand" "f,0,f")
- (match_operand:SF 4 "register_operand" "0,f,f")))]
+ (match_operand:SF 3 "register_operand" "f,0")
+ (match_operand:SF 4 "register_operand" "0,f")))]
"TARGET_CMOVE && reload_completed"
[(set (cc0)
(match_dup 2))
@@ -7285,12 +7568,12 @@ byte_xor_operation:
"")
(define_split
- [(set (match_operand:SF 0 "register_operand" "=f,f,f")
+ [(set (match_operand:SF 0 "register_operand" "=f,f")
(if_then_else:SF (match_operator 1 "comparison_operator"
[(match_operand 2 "nonimmediate_operand" "")
(match_operand 3 "general_operand" "")])
- (match_operand:SF 4 "register_operand" "f,0,f")
- (match_operand:SF 5 "register_operand" "0,f,f")))]
+ (match_operand:SF 4 "register_operand" "f,0")
+ (match_operand:SF 5 "register_operand" "0,f")))]
"TARGET_CMOVE && reload_completed"
[(set (cc0) (compare (match_dup 2) (match_dup 3)))
(set (match_dup 0)
@@ -7299,11 +7582,11 @@ byte_xor_operation:
"")
(define_insn ""
- [(set (match_operand:SF 0 "register_operand" "=f,f,f")
+ [(set (match_operand:SF 0 "register_operand" "=f,f")
(if_then_else:SF (match_operator 1 "comparison_operator"
[(cc0) (const_int 0)])
- (match_operand:SF 2 "register_operand" "f,0,f")
- (match_operand:SF 3 "register_operand" "0,f,f")))]
+ (match_operand:SF 2 "register_operand" "f,0")
+ (match_operand:SF 3 "register_operand" "0,f")))]
"TARGET_CMOVE && reload_completed"
"* return output_fp_conditional_move (which_alternative, operands);")
@@ -7348,36 +7631,36 @@ byte_xor_operation:
}")
(define_insn ""
- [(set (match_operand:DF 0 "register_operand" "=f,f,f,f,f,f")
+ [(set (match_operand:DF 0 "register_operand" "=f,f,f,f")
(if_then_else:DF (match_operator 1 "comparison_operator"
- [(match_operand:QI 2 "nonimmediate_operand" "q,m,q,m,q,m")
- (match_operand:QI 3 "general_operand" "qmn,qn,qmn,qn,qmn,qn")])
- (match_operand:DF 4 "register_operand" "f,f,0,0,f,f")
- (match_operand:DF 5 "register_operand" "0,0,f,f,f,f")))]
+ [(match_operand:QI 2 "nonimmediate_operand" "q,m,q,m")
+ (match_operand:QI 3 "general_operand" "qmn,qn,qmn,qn")])
+ (match_operand:DF 4 "register_operand" "f,f,0,0")
+ (match_operand:DF 5 "register_operand" "0,0,f,f")))]
"TARGET_CMOVE
&& GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != LE
&& GET_CODE (operands[1]) != GE && GET_CODE (operands[1]) != GT"
"#")
(define_insn ""
- [(set (match_operand:DF 0 "register_operand" "=f,f,f,f,f,f")
+ [(set (match_operand:DF 0 "register_operand" "=f,f,f,f")
(if_then_else:DF (match_operator 1 "comparison_operator"
- [(match_operand 2 "nonimmediate_operand" "r,m,r,m,r,m")
- (match_operand 3 "general_operand" "rmi,ri,rmi,ri,rmi,ri")])
- (match_operand:DF 4 "register_operand" "f,f,0,0,f,f")
- (match_operand:DF 5 "register_operand" "0,0,f,f,f,f")))]
+ [(match_operand 2 "nonimmediate_operand" "r,m,r,m")
+ (match_operand 3 "general_operand" "rmi,ri,rmi,ri")])
+ (match_operand:DF 4 "register_operand" "f,f,0,0")
+ (match_operand:DF 5 "register_operand" "0,0,f,f")))]
"TARGET_CMOVE && GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT
&& GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != LE
&& GET_CODE (operands[1]) != GE && GET_CODE (operands[1]) != GT"
"#")
(define_split
- [(set (match_operand:DF 0 "register_operand" "=f,f,f")
+ [(set (match_operand:DF 0 "register_operand" "=f,f")
(if_then_else:DF (match_operator 1 "comparison_operator"
[(match_operand 2 "nonimmediate_operand" "")
(const_int 0)])
- (match_operand:DF 3 "register_operand" "f,0,f")
- (match_operand:DF 4 "register_operand" "0,f,f")))]
+ (match_operand:DF 3 "register_operand" "f,0")
+ (match_operand:DF 4 "register_operand" "0,f")))]
"TARGET_CMOVE && reload_completed"
[(set (cc0)
(match_dup 2))
@@ -7387,12 +7670,12 @@ byte_xor_operation:
"")
(define_split
- [(set (match_operand:DF 0 "register_operand" "=f,f,f")
+ [(set (match_operand:DF 0 "register_operand" "=f,f")
(if_then_else:DF (match_operator 1 "comparison_operator"
[(match_operand 2 "nonimmediate_operand" "")
(match_operand 3 "general_operand" "")])
- (match_operand:DF 4 "register_operand" "f,0,f")
- (match_operand:DF 5 "register_operand" "0,f,f")))]
+ (match_operand:DF 4 "register_operand" "f,0")
+ (match_operand:DF 5 "register_operand" "0,f")))]
"TARGET_CMOVE && reload_completed"
[(set (cc0) (compare (match_dup 2) (match_dup 3)))
(set (match_dup 0)
@@ -7401,11 +7684,11 @@ byte_xor_operation:
"")
(define_insn ""
- [(set (match_operand:DF 0 "register_operand" "=f,f,f")
+ [(set (match_operand:DF 0 "register_operand" "=f,f")
(if_then_else:DF (match_operator 1 "comparison_operator"
[(cc0) (const_int 0)])
- (match_operand:DF 2 "register_operand" "f,0,f")
- (match_operand:DF 3 "register_operand" "0,f,f")))]
+ (match_operand:DF 2 "register_operand" "f,0")
+ (match_operand:DF 3 "register_operand" "0,f")))]
"TARGET_CMOVE && reload_completed"
"* return output_fp_conditional_move (which_alternative, operands);")
@@ -7450,36 +7733,36 @@ byte_xor_operation:
}")
(define_insn ""
- [(set (match_operand:XF 0 "register_operand" "=f,f,f,f,f,f")
+ [(set (match_operand:XF 0 "register_operand" "=f,f,f,f")
(if_then_else:XF (match_operator 1 "comparison_operator"
- [(match_operand:QI 2 "nonimmediate_operand" "q,m,q,m,q,m")
- (match_operand:QI 3 "general_operand" "qmn,qn,qmn,qn,qmn,qn")])
- (match_operand:XF 4 "register_operand" "f,f,0,0,f,f")
- (match_operand:XF 5 "register_operand" "0,0,f,f,f,f")))]
+ [(match_operand:QI 2 "nonimmediate_operand" "q,m,q,m")
+ (match_operand:QI 3 "general_operand" "qmn,qn,qmn,qn")])
+ (match_operand:XF 4 "register_operand" "f,f,0,0")
+ (match_operand:XF 5 "register_operand" "0,0,f,f")))]
"TARGET_CMOVE
&& GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != LE
&& GET_CODE (operands[1]) != GE && GET_CODE (operands[1]) != GT"
"#")
(define_insn ""
- [(set (match_operand:XF 0 "register_operand" "=f,f,f,f,f,f")
+ [(set (match_operand:XF 0 "register_operand" "=f,f,f,f")
(if_then_else:XF (match_operator 1 "comparison_operator"
- [(match_operand 2 "nonimmediate_operand" "r,m,r,m,r,m")
- (match_operand 3 "general_operand" "rmi,ri,rmi,ri,rmi,ri")])
- (match_operand:XF 4 "register_operand" "f,f,0,0,f,f")
- (match_operand:XF 5 "register_operand" "0,0,f,f,f,f")))]
+ [(match_operand 2 "nonimmediate_operand" "r,m,r,m")
+ (match_operand 3 "general_operand" "rmi,ri,rmi,ri")])
+ (match_operand:XF 4 "register_operand" "f,f,0,0")
+ (match_operand:XF 5 "register_operand" "0,0,f,f")))]
"TARGET_CMOVE && GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT
&& GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != LE
&& GET_CODE (operands[1]) != GE && GET_CODE (operands[1]) != GT"
"#")
(define_split
- [(set (match_operand:XF 0 "register_operand" "=f,f,f")
+ [(set (match_operand:XF 0 "register_operand" "=f,f")
(if_then_else:XF (match_operator 1 "comparison_operator"
[(match_operand 2 "nonimmediate_operand" "")
(const_int 0)])
- (match_operand:XF 3 "register_operand" "f,0,f")
- (match_operand:XF 4 "register_operand" "0,f,f")))]
+ (match_operand:XF 3 "register_operand" "f,0")
+ (match_operand:XF 4 "register_operand" "0,f")))]
"TARGET_CMOVE && reload_completed"
[(set (cc0)
(match_dup 2))
@@ -7489,12 +7772,12 @@ byte_xor_operation:
"")
(define_split
- [(set (match_operand:XF 0 "register_operand" "=f,f,f")
+ [(set (match_operand:XF 0 "register_operand" "=f,f")
(if_then_else:XF (match_operator 1 "comparison_operator"
[(match_operand 2 "nonimmediate_operand" "")
(match_operand 3 "general_operand" "")])
- (match_operand:XF 4 "register_operand" "f,0,f")
- (match_operand:XF 5 "register_operand" "0,f,f")))]
+ (match_operand:XF 4 "register_operand" "f,0")
+ (match_operand:XF 5 "register_operand" "0,f")))]
"TARGET_CMOVE && reload_completed"
[(set (cc0) (compare (match_dup 2) (match_dup 3)))
(set (match_dup 0)
@@ -7503,11 +7786,11 @@ byte_xor_operation:
"")
(define_insn ""
- [(set (match_operand:XF 0 "register_operand" "=f,f,f")
+ [(set (match_operand:XF 0 "register_operand" "=f,f")
(if_then_else:XF (match_operator 1 "comparison_operator"
[(cc0) (const_int 0)])
- (match_operand:XF 2 "register_operand" "f,0,f")
- (match_operand:XF 3 "register_operand" "0,f,f")))]
+ (match_operand:XF 2 "register_operand" "f,0")
+ (match_operand:XF 3 "register_operand" "0,f")))]
"TARGET_CMOVE && reload_completed"
"* return output_fp_conditional_move (which_alternative, operands);")
@@ -7528,32 +7811,32 @@ byte_xor_operation:
}")
(define_insn ""
- [(set (match_operand:DI 0 "register_operand" "=&r,&r,&r,&r,&r,&r")
+ [(set (match_operand:DI 0 "register_operand" "=&r,&r,&r,&r")
(if_then_else:DI (match_operator 1 "comparison_operator"
- [(match_operand:QI 2 "nonimmediate_operand" "q,m,q,m,q,m")
- (match_operand:QI 3 "general_operand" "qmn,qn,qmn,qn,qmn,qn")])
- (match_operand:DI 4 "nonimmediate_operand" "ro,ro,0,0,ro,ro")
- (match_operand:DI 5 "nonimmediate_operand" "0,0,ro,ro,ro,ro")))]
+ [(match_operand:QI 2 "nonimmediate_operand" "q,m,q,m")
+ (match_operand:QI 3 "general_operand" "qmn,qn,qmn,qn")])
+ (match_operand:DI 4 "nonimmediate_operand" "ro,ro,0,0")
+ (match_operand:DI 5 "nonimmediate_operand" "0,0,ro,ro")))]
"TARGET_CMOVE"
"#")
(define_insn ""
- [(set (match_operand:DI 0 "register_operand" "=&r,&r,&r,&r,&r,&r")
+ [(set (match_operand:DI 0 "register_operand" "=&r,&r,&r,&r")
(if_then_else:DI (match_operator 1 "comparison_operator"
- [(match_operand 2 "nonimmediate_operand" "r,m,r,m,r,m")
- (match_operand 3 "general_operand" "rmi,ri,rmi,ri,rmi,ri")])
- (match_operand:DI 4 "nonimmediate_operand" "ro,ro,0,0,ro,ro")
- (match_operand:DI 5 "nonimmediate_operand" "0,0,ro,ro,ro,ro")))]
+ [(match_operand 2 "nonimmediate_operand" "r,m,r,m")
+ (match_operand 3 "general_operand" "rmi,ri,rmi,ri")])
+ (match_operand:DI 4 "nonimmediate_operand" "ro,ro,0,0")
+ (match_operand:DI 5 "nonimmediate_operand" "0,0,ro,ro")))]
"TARGET_CMOVE && GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT"
"#")
(define_split
- [(set (match_operand:DI 0 "register_operand" "=&r,&r,&r")
+ [(set (match_operand:DI 0 "register_operand" "=&r,&r")
(if_then_else:DI (match_operator 1 "comparison_operator"
[(match_operand 2 "nonimmediate_operand" "")
(const_int 0)])
- (match_operand:DI 3 "nonimmediate_operand" "ro,0,ro")
- (match_operand:DI 4 "nonimmediate_operand" "0,ro,ro")))]
+ (match_operand:DI 3 "nonimmediate_operand" "ro,0")
+ (match_operand:DI 4 "nonimmediate_operand" "0,ro")))]
"TARGET_CMOVE && reload_completed"
[(set (cc0)
(match_dup 2))
@@ -7563,12 +7846,12 @@ byte_xor_operation:
"")
(define_split
- [(set (match_operand:DI 0 "register_operand" "=&r,&r,&r")
+ [(set (match_operand:DI 0 "register_operand" "=&r,&r")
(if_then_else:DI (match_operator 1 "comparison_operator"
[(match_operand 2 "nonimmediate_operand" "")
(match_operand 3 "general_operand" "")])
- (match_operand:DI 4 "nonimmediate_operand" "ro,0,ro")
- (match_operand:DI 5 "nonimmediate_operand" "0,ro,ro")))]
+ (match_operand:DI 4 "nonimmediate_operand" "ro,0")
+ (match_operand:DI 5 "nonimmediate_operand" "0,ro")))]
"TARGET_CMOVE && reload_completed"
[(set (cc0) (compare (match_dup 2) (match_dup 3)))
(set (match_dup 0)
@@ -7577,11 +7860,11 @@ byte_xor_operation:
"")
(define_insn ""
- [(set (match_operand:DI 0 "register_operand" "=&r,&r,&r")
+ [(set (match_operand:DI 0 "register_operand" "=&r,&r")
(if_then_else:DI (match_operator 1 "comparison_operator"
[(cc0) (const_int 0)])
- (match_operand:DI 2 "nonimmediate_operand" "ro,0,ro")
- (match_operand:DI 3 "nonimmediate_operand" "0,ro,ro")))]
+ (match_operand:DI 2 "nonimmediate_operand" "ro,0")
+ (match_operand:DI 3 "nonimmediate_operand" "0,ro")))]
"TARGET_CMOVE && reload_completed"
"* return output_int_conditional_move (which_alternative, operands);")
@@ -7620,7 +7903,8 @@ byte_xor_operation:
(set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 0)))
(clobber (match_dup 0))]
"TARGET_STACK_PROBE"
- "* return AS1(call,__alloca);")
+ "* return AS1(call,__alloca);"
+ [(set_attr "memory" "none")])
(define_expand "allocate_stack"
[(set (match_operand:SI 0 "register_operand" "=r")
diff --git a/gcc/config/i386/isc.h b/gcc/config/i386/isc.h
index 5c39896df01..6c1c4c72718 100644
--- a/gcc/config/i386/isc.h
+++ b/gcc/config/i386/isc.h
@@ -59,7 +59,7 @@
So don't make TARGET_IEEE_FP default for ISC. */
#undef TARGET_DEFAULT
-#define TARGET_DEFAULT 0201
+#define TARGET_DEFAULT (MASK_80387 | MASK_FLOAT_RETURNS)
/* The ISC 2.0.2 software FPU emulator apparently can't handle
80-bit XFmode insns, so don't generate them. */
@@ -72,20 +72,23 @@
message. */
#undef ASM_FILE_START
-#define ASM_FILE_START(FILE) \
- do { \
- char c; \
- int max = 0; \
- char *string = dump_base_name; \
- \
- fputs ("\t.file\t\"", FILE); \
- \
- while ((c = *string++) != 0 && max++ < 14) { \
- if (c == '\"' || c == '\\') \
- putc ('\\', FILE); \
- putc (c, FILE); \
- } \
- fputs ("\"\n", FILE); \
+#define ASM_FILE_START(FILE) \
+ do { \
+ int len = strlen (main_input_filename); \
+ char *na = main_input_filename + len; \
+ char shorter[15]; \
+ /* NA gets MAIN_INPUT_FILENAME sans directory names. */\
+ while (na > main_input_filename) \
+ { \
+ if (na[-1] == '/') \
+ break; \
+ na--; \
+ } \
+ strncpy (shorter, na, 14); \
+ shorter[14] = 0; \
+ fprintf (FILE, "\t.file\t"); \
+ output_quoted_string (FILE, shorter); \
+ fprintf (FILE, "\n"); \
} while (0)
/* Work around assembler forward label references generated in exception
diff --git a/gcc/config/i386/isccoff.h b/gcc/config/i386/isccoff.h
index 383b981328b..595c7d98fe3 100644
--- a/gcc/config/i386/isccoff.h
+++ b/gcc/config/i386/isccoff.h
@@ -1,8 +1,8 @@
/* Definitions for Intel 386 running Interactive Unix System V.
Specifically, this is for recent versions that support POSIX;
for version 2.0.2, use configuration option i386-sysv instead.
- (But set TARGET_DEFAULT to 0201 if you do that,
- if you don't have a real 80387.) */
+ (But set TARGET_DEFAULT to (MASK_80307 | MASK_FLOAT_RETURNS)
+ if you do that, if you don't have a real 80387.) */
/* Mostly it's like AT&T Unix System V. */
diff --git a/gcc/config/i386/linux.h b/gcc/config/i386/linux.h
index 373c80444cf..91d3830673d 100644
--- a/gcc/config/i386/linux.h
+++ b/gcc/config/i386/linux.h
@@ -151,7 +151,7 @@ Boston, MA 02111-1307, USA. */
#define WCHAR_TYPE_SIZE BITS_PER_WORD
#undef CPP_PREDEFINES
-#define CPP_PREDEFINES "-D__ELF__ -Dunix -Dlinux -Asystem(posix)"
+#define CPP_PREDEFINES "-D__ELF__ -Dunix -D__i386__ -Dlinux -Asystem(posix)"
#undef CPP_SPEC
#ifdef USE_GNULIBC_1
@@ -226,8 +226,10 @@ Boston, MA 02111-1307, USA. */
This is used to align code labels according to Intel recommendations. */
#ifdef HAVE_GAS_MAX_SKIP_P2ALIGN
-#define ASM_OUTPUT_MAX_SKIP_ALIGN(FILE,LOG,MAX_SKIP) \
- if ((LOG)!=0) \
- if ((MAX_SKIP)==0) fprintf ((FILE), "\t.p2align %d\n", (LOG)); \
- else fprintf ((FILE), "\t.p2align %d,,%d\n", (LOG), (MAX_SKIP))
+#define ASM_OUTPUT_MAX_SKIP_ALIGN(FILE,LOG,MAX_SKIP) \
+ do { \
+ if ((LOG) != 0) \
+ if ((MAX_SKIP) == 0) fprintf ((FILE), "\t.p2align %d\n", (LOG)); \
+ else fprintf ((FILE), "\t.p2align %d,,%d\n", (LOG), (MAX_SKIP)); \
+ } while (0)
#endif
diff --git a/gcc/config/i386/mingw32.h b/gcc/config/i386/mingw32.h
index a320a61f780..f8da4894ad0 100644
--- a/gcc/config/i386/mingw32.h
+++ b/gcc/config/i386/mingw32.h
@@ -2,7 +2,7 @@
hosting on Windows32, using GNU tools and the Windows32 API Library,
as distinct from winnt.h, which is used to build GCC for use with a
windows style library and tool set and uses the Microsoft tools.
- Copyright (C) 1997, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -21,19 +21,19 @@ 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. */
-/* Most of this is the same as for Cygwin32, except for changing some
+/* Most of this is the same as for cygwin, except for changing some
specs. */
-#include "i386/cygwin32.h"
+#include "i386/cygwin.h"
/* Please keep changes to CPP_PREDEFINES in sync with i386/crtdll. The
only difference between the two should be __MSVCRT__ needed to
distinguish MSVC from CRTDLL runtime in mingw headers. */
#undef CPP_PREDEFINES
#define CPP_PREDEFINES "-Di386 -D_WIN32 -DWIN32 -D__WIN32__ \
- -D__MINGW32__ -D__MSVCRT__ -DWINNT -D_X86_=1 -D__STDC__=1\
+ -D__MINGW32__=0.2 -D__MSVCRT__ -DWINNT -D_X86_=1 -D__STDC__=1\
-D__stdcall=__attribute__((__stdcall__)) \
- _D_stdcall=__attribute__((__stdcall__)) \
+ -D_stdcall=__attribute__((__stdcall__)) \
-D__cdecl=__attribute__((__cdecl__)) \
-D__declspec(x)=__attribute__((x)) \
-Asystem(winnt) -Acpu(i386) -Amachine(i386)"
@@ -44,6 +44,9 @@ Boston, MA 02111-1307, USA. */
#define STANDARD_INCLUDE_COMPONENT "MINGW32"
+#undef CPP_SPEC
+#define CPP_SPEC "-remap %(cpp_cpu) %{posix:-D_POSIX_SOURCE}"
+
/* For Windows applications, include more libraries, but always include
kernel32. */
#undef LIB_SPEC
diff --git a/gcc/config/i386/moss.h b/gcc/config/i386/moss.h
index dadf3d86af2..d2548e3a5b9 100644
--- a/gcc/config/i386/moss.h
+++ b/gcc/config/i386/moss.h
@@ -16,7 +16,8 @@ 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
/* I believe in reuse... */
#include "i386/linux.h"
diff --git a/gcc/config/i386/netbsd.h b/gcc/config/i386/netbsd.h
index 5978aec5c4b..d9f06469e62 100644
--- a/gcc/config/i386/netbsd.h
+++ b/gcc/config/i386/netbsd.h
@@ -1,6 +1,3 @@
-/* This goes away when the math-emulator is fixed */
-#define TARGET_CPU_DEFAULT 0400 /* TARGET_NO_FANCY_MATH_387 */
-
/* This is tested by i386gas.h. */
#define YES_UNDERSCORES
@@ -12,6 +9,11 @@
/* Get generic NetBSD definitions. */
#include <netbsd.h>
+/* This goes away when the math-emulator is fixed */
+#undef TARGET_DEFAULT
+#define TARGET_DEFAULT \
+ (MASK_80387 | MASK_IEEE_FP | MASK_FLOAT_RETURNS | MASK_NO_FANCY_MATH_387)
+
#undef CPP_PREDEFINES
#define CPP_PREDEFINES "-Dunix -Di386 -D__NetBSD__ -Asystem(unix) -Asystem(NetBSD) -Acpu(i386) -Amachine(i386)"
diff --git a/gcc/config/i386/next.h b/gcc/config/i386/next.h
index 8dd46f5cd41..bbc0e6b3061 100644
--- a/gcc/config/i386/next.h
+++ b/gcc/config/i386/next.h
@@ -1,5 +1,5 @@
/* Target definitions for GNU compiler for Intel x86 CPU running NeXTSTEP
- Copyright (C) 1993, 1995, 1996 Free Software Foundation, Inc.
+ Copyright (C) 1993, 1995, 1996, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -24,7 +24,7 @@ Boston, MA 02111-1307, USA. */
/* By default, target has a 80387, with IEEE FP. */
#undef TARGET_DEFAULT
-#define TARGET_DEFAULT (1|0100)
+#define TARGET_DEFAULT (MASK_80387 | MASK_IEEE_FP)
/* Implicit library calls should use memcpy, not bcopy, etc. */
@@ -224,3 +224,10 @@ Boston, MA 02111-1307, USA. */
== void_type_node))) ? (SIZE) : 0)
/* END Calling Convention CHANGES */
+
+/* NeXT still uses old binutils that don't insert nops by default
+ when the .align directive demands to insert extra space in the text
+ segment. */
+#undef ASM_OUTPUT_ALIGN
+#define ASM_OUTPUT_ALIGN(FILE,LOG) \
+ if ((LOG)!=0) fprintf ((FILE), "\t.align %d,0x90\n", (LOG))
diff --git a/gcc/config/i386/osfrose.h b/gcc/config/i386/osfrose.h
index 9cfe187ea09..4d0161c32a8 100644
--- a/gcc/config/i386/osfrose.h
+++ b/gcc/config/i386/osfrose.h
@@ -1,6 +1,6 @@
/* Definitions of target machine for GNU compiler.
Intel 386 (OSF/1 with OSF/rose) version.
- Copyright (C) 1991, 1992, 1993, 1996 Free Software Foundation, Inc.
+ Copyright (C) 1991, 1992, 1993, 1996, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -752,7 +752,7 @@ do \
if (HALF_PIC_P ()) \
HALF_PIC_FINISH (STREAM); \
\
- if (TARGET_IDENT) \
+ if (TARGET_IDENT && !flag_no_ident) \
{ \
char *fstart = main_input_filename; \
char *fname; \
diff --git a/gcc/config/i386/sco.h b/gcc/config/i386/sco.h
index 016e0a00ce0..55af64128a1 100644
--- a/gcc/config/i386/sco.h
+++ b/gcc/config/i386/sco.h
@@ -1,5 +1,5 @@
/* Definitions for Intel 386 running SCO Unix System V.
- Copyright (C) 1988, 1992, 1994, 1995 Free, 1996 Software Foundation, Inc.
+ Copyright (C) 1988, 92, 94, 95, 96, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -31,7 +31,7 @@ Boston, MA 02111-1307, USA. */
So don't make TARGET_IEEE_FP default for SCO. */
#undef TARGET_DEFAULT
-#define TARGET_DEFAULT 0201
+#define TARGET_DEFAULT (MASK_80387 | MASK_FLOAT_RETURNS)
/* Let's guess that the SCO software FPU emulator can't handle
80-bit XFmode insns, so don't generate them. */
diff --git a/gcc/config/i386/sco5.h b/gcc/config/i386/sco5.h
index b97fffc73ff..ac4e7e1e094 100644
--- a/gcc/config/i386/sco5.h
+++ b/gcc/config/i386/sco5.h
@@ -1,5 +1,5 @@
/* Definitions for Intel 386 running SCO Unix System V 3.2 Version 5.
- Copyright (C) 1992, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1992, 95-98, 1999 Free Software Foundation, Inc.
Contributed by Kean Johnston (hug@netcom.com)
This file is part of GNU CC.
@@ -211,8 +211,9 @@ do { \
#undef ASM_FILE_END
#define ASM_FILE_END(FILE) \
do { \
- fprintf ((FILE), "%s\t\"GCC: (GNU) %s\"\n", \
- IDENT_ASM_OP, version_string); \
+ if (!flag_no_ident) \
+ fprintf ((FILE), "%s\t\"GCC: (GNU) %s\"\n", \
+ IDENT_ASM_OP, version_string); \
} while (0)
#undef ASM_FINISH_DECLARE_OBJECT
@@ -689,7 +690,9 @@ dtors_section () \
#undef SELECT_SECTION
#define SELECT_SECTION(DECL,RELOC) \
{ \
- if (TREE_CODE (DECL) == STRING_CST) \
+ if (TARGET_ELF && flag_pic && RELOC) \
+ data_section (); \
+ else if (TREE_CODE (DECL) == STRING_CST) \
{ \
if (! flag_writable_strings) \
const_section (); \
@@ -698,11 +701,7 @@ dtors_section () \
} \
else if (TREE_CODE (DECL) == VAR_DECL) \
{ \
- if ((TARGET_ELF && flag_pic && RELOC) \
- || !TREE_READONLY (DECL) || TREE_SIDE_EFFECTS (DECL) \
- || !DECL_INITIAL (DECL) \
- || (DECL_INITIAL (DECL) != error_mark_node \
- && !TREE_CONSTANT (DECL_INITIAL (DECL)))) \
+ if (! DECL_READONLY_SECTION (DECL, RELOC)) \
data_section (); \
else \
const_section (); \
@@ -726,7 +725,7 @@ dtors_section () \
&& strcmp (STR, "Tbss"))
#undef TARGET_DEFAULT
-#define TARGET_DEFAULT 0301
+#define TARGET_DEFAULT (MASK_80387 | MASK_IEEE_FP | MASK_FLOAT_RETURNS)
#undef HANDLE_SYSV_PRAGMA
#define HANDLE_SYSV_PRAGMA 1
@@ -813,7 +812,8 @@ dtors_section () \
#undef STARTFILE_SPEC
#define STARTFILE_SPEC \
- "%{!shared:\
+ "%{shared: %{!mcoff: crti.o%s}} \
+ %{!shared:\
%{!symbolic: \
%{pg:gcrt.o%s}%{!pg:%{p:mcrt1.o%s}%{!p:crt1.o%s}}}} \
%{ansi:values-Xc.o%s} \
@@ -911,8 +911,8 @@ dtors_section () \
#undef SUBTARGET_SWITCHES
#define SUBTARGET_SWITCHES \
- { "coff", MASK_COFF }, \
- { "elf", -MASK_COFF },
+ { "coff", MASK_COFF, "Generate COFF output" }, \
+ { "elf", -MASK_COFF, "Generate ELF output" },
#define NO_DOLLAR_IN_LABEL
@@ -921,6 +921,13 @@ dtors_section () \
#define TARGET_MEM_FUNCTIONS
+/* Biggest alignment supported by the object file format of this
+ machine. Use this macro to limit the alignment which can be
+ specified using the `__attribute__ ((aligned (N)))' construct. If
+ not defined, the default value is `BIGGEST_ALIGNMENT'. */
+
+#define MAX_OFILE_ALIGNMENT (32768*8)
+
/*
Here comes some major hackery to get the crt stuff to compile properly.
Since we can (and do) compile for both COFF and ELF environments, we
diff --git a/gcc/config/i386/scodbx.h b/gcc/config/i386/scodbx.h
index a2581d4257f..d7d03f86326 100644
--- a/gcc/config/i386/scodbx.h
+++ b/gcc/config/i386/scodbx.h
@@ -1,6 +1,6 @@
/* Definitions for Intel 386 running SCO Unix System V,
using dbx-in-coff encapsulation.
- Copyright (C) 1992, 1995, 1996 Free Software Foundation, Inc.
+ Copyright (C) 1992, 1995, 1996, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -32,7 +32,7 @@ Boston, MA 02111-1307, USA. */
So don't make TARGET_IEEE_FP default for SCO. */
#undef TARGET_DEFAULT
-#define TARGET_DEFAULT 0201
+#define TARGET_DEFAULT (MASK_80387 | MASK_FLOAT_RETURNS)
/* Use crt1.o as a startup file and crtn.o as a closing file. */
diff --git a/gcc/config/i386/sequent.h b/gcc/config/i386/sequent.h
index 4d76c389b6a..8613ad79e2d 100644
--- a/gcc/config/i386/sequent.h
+++ b/gcc/config/i386/sequent.h
@@ -1,5 +1,5 @@
/* Definitions for Sequent Intel 386.
- Copyright (C) 1988, 1994 Free Software Foundation, Inc.
+ Copyright (C) 1988, 1994, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -26,11 +26,10 @@ Boston, MA 02111-1307, USA. */
/* By default, don't use IEEE compatible arithmetic comparisons
because the assembler can't handle the fucom insn.
- Return float values in the 387.
- (TARGET_80387 | TARGET_FLOAT_RETURNS_IN_80387) */
+ Return float values in the 387. */
#undef TARGET_DEFAULT
-#define TARGET_DEFAULT 0201
+#define TARGET_DEFAULT (MASK_80387 | MASK_FLOAT_RETURNS)
/* Specify predefined symbols in preprocessor. */
diff --git a/gcc/config/i386/sol2.h b/gcc/config/i386/sol2.h
index 8fc3e6140e7..cc5a089229f 100644
--- a/gcc/config/i386/sol2.h
+++ b/gcc/config/i386/sol2.h
@@ -93,3 +93,6 @@ Boston, MA 02111-1307, USA. */
|| (CHAR) == 'z')
#define STDC_0_IN_SYSTEM_HEADERS
+
+#undef LOCAL_LABEL_PREFIX
+#define LOCAL_LABEL_PREFIX "."
diff --git a/gcc/config/i386/sun386.h b/gcc/config/i386/sun386.h
index 4d4d66c181a..4302ec40841 100644
--- a/gcc/config/i386/sun386.h
+++ b/gcc/config/i386/sun386.h
@@ -59,11 +59,11 @@ do \
do { \
extern char *version_string, *language_string; \
{ \
- int len = strlen (dump_base_name); \
- char *na = dump_base_name + len; \
+ int len = strlen (main_input_filename); \
+ char *na = main_input_filename + len; \
char shorter[15]; \
- /* NA gets DUMP_BASE_NAME sans directory names. */\
- while (na > dump_base_name) \
+ /* NA gets MAIN_INPUT_FILENAME sans directory names. */\
+ while (na > main_input_filename) \
{ \
if (na[-1] == '/') \
break; \
diff --git a/gcc/config/i386/t-cygwin32 b/gcc/config/i386/t-cygwin32
deleted file mode 100644
index 20bc9803b1e..00000000000
--- a/gcc/config/i386/t-cygwin32
+++ /dev/null
@@ -1,16 +0,0 @@
-LIBGCC1 = libgcc1-asm.a
-CROSS_LIBGCC1 = libgcc1-asm.a
-LIB1ASMSRC = i386/cygwin32.asm
-LIB1ASMFUNCS = _chkstk
-
-# cygwin32 always has a limits.h, but, depending upon how we are doing
-# the build, it may not be installed yet.
-LIMITS_H_TEST = true
-
-# If we are building next to winsup, this will let us find the real
-# limits.h when building libgcc2. Otherwise, winsup must be installed
-# first.
-LIBGCC2_INCLUDES = -I$(srcdir)/../winsup/include
-
-winnt.o: $(srcdir)/config/i386/winnt.c
- $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $(srcdir)/config/i386/winnt.c
diff --git a/gcc/config/i386/t-go32 b/gcc/config/i386/t-go32
deleted file mode 100644
index 6160b7ec945..00000000000
--- a/gcc/config/i386/t-go32
+++ /dev/null
@@ -1,2 +0,0 @@
-LIBGCC1 = libgcc1.null
-CROSS_LIBGCC1 = libgcc1.null
diff --git a/gcc/config/i386/t-sco5 b/gcc/config/i386/t-sco5
index fd3d6c63b8e..f602066e995 100644
--- a/gcc/config/i386/t-sco5
+++ b/gcc/config/i386/t-sco5
@@ -14,3 +14,7 @@ MULTILIB_EXTRA_OPTS =
LIBGCC=stmp-multilib
INSTALL_LIBGCC=install-multilib
+
+crti.o: $(srcdir)/config/i386/sol2-ci.asm $(GCC_PASSES)
+ sed -e '/^!/d' <$(srcdir)/config/i386/sol2-ci.asm >crti.s
+ $(GCC_FOR_TARGET) -c -o crti.o crti.s
diff --git a/gcc/config/i386/t-sco5gas b/gcc/config/i386/t-sco5gas
index 6aa15d2a213..2bca87be7a8 100644
--- a/gcc/config/i386/t-sco5gas
+++ b/gcc/config/i386/t-sco5gas
@@ -14,3 +14,7 @@ MULTILIB_EXTRA_OPTS =
LIBGCC=stmp-multilib
INSTALL_LIBGCC=install-multilib
+
+crti.o: $(srcdir)/config/i386/sol2-ci.asm $(GCC_PASSES)
+ sed -e '/^!/d' <$(srcdir)/config/i386/sol2-ci.asm >crti.s
+ $(GCC_FOR_TARGET) -c -o crti.o crti.s
diff --git a/gcc/config/i386/unix.h b/gcc/config/i386/unix.h
index 47440ddd943..3ff2075cfaf 100644
--- a/gcc/config/i386/unix.h
+++ b/gcc/config/i386/unix.h
@@ -1,5 +1,5 @@
/* Definitions for Unix assembler syntax for the Intel 80386.
- Copyright (C) 1988, 1994 Free Software Foundation, Inc.
+ Copyright (C) 1988, 1994, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -131,10 +131,9 @@ Boston, MA 02111-1307, USA. */
(fputs (".globl ", FILE), assemble_name (FILE, NAME), fputs ("\n", FILE))
/* By default, target has a 80387, uses IEEE compatible arithmetic,
- and returns float values in the 387, ie,
- (TARGET_80387 | TARGET_IEEE_FP | TARGET_FLOAT_RETURNS_IN_80387) */
+ and returns float values in the 387. */
-#define TARGET_DEFAULT 0301
+#define TARGET_DEFAULT (MASK_80387 | MASK_IEEE_FP | MASK_FLOAT_RETURNS)
/* Floating-point return values come in the FP register. */
diff --git a/gcc/config/i386/win-nt.h b/gcc/config/i386/win-nt.h
index 60c0bb6a1f6..97f10c39d00 100644
--- a/gcc/config/i386/win-nt.h
+++ b/gcc/config/i386/win-nt.h
@@ -131,9 +131,7 @@ while (0)
#undef ASM_FILE_START
#endif
#define ASM_FILE_START(FILE) \
- do { fprintf (FILE, "\t.file\t"); \
- output_quoted_string (FILE, dump_base_name); \
- fprintf (FILE, "\n"); \
+ do { output_file_directive (FILE, main_input_filename); \
fprintf (FILE, ".global\t__fltused\n"); \
} while (0)
diff --git a/gcc/config/i386/win32.h b/gcc/config/i386/win32.h
index a8b6904cdb0..f6cc4516648 100644
--- a/gcc/config/i386/win32.h
+++ b/gcc/config/i386/win32.h
@@ -71,7 +71,7 @@ Boston, MA 02111-1307, USA. */
#undef CPP_SPEC
#define CPP_SPEC "%(cpp_cpu) %{posix:-D_POSIX_SOURCE} \
%{!mcygwin:-iwithprefixbefore include/mingw32 -D__MINGW32__} \
- %{mcygwin:-D__CYGWIN32__}"
+ %{mcygwin:-D__CYGWIN32__ -D__CYGWIN__}"
/* We have to dynamic link to get to the system DLLs. All of libc, libm and
the Unix stuff is in cygwin.dll. The import library is called
diff --git a/gcc/config/i386/winnt.c b/gcc/config/i386/winnt.c
index 0058eb76499..f1a2d4b83be 100644
--- a/gcc/config/i386/winnt.c
+++ b/gcc/config/i386/winnt.c
@@ -1,6 +1,6 @@
/* Subroutines for insn-output.c for Windows NT.
Contributed by Douglas Rupp (drupp@cs.washington.edu)
- Copyright (C) 1995, 1997 Free Software Foundation, Inc.
+ Copyright (C) 1995, 1997, 1998 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -493,7 +493,7 @@ i386_pe_unique_section (decl, reloc)
}
/* The Microsoft linker requires that every function be marked as
- DT_FCN. When using gas on cygwin32, we must emit appropriate .type
+ DT_FCN. When using gas on cygwin, we must emit appropriate .type
directives. */
#include "gsyms.h"
diff --git a/gcc/config/i386/x-cygwin32 b/gcc/config/i386/x-cygwin32
deleted file mode 100644
index f251835bd33..00000000000
--- a/gcc/config/i386/x-cygwin32
+++ /dev/null
@@ -1,4 +0,0 @@
-# Don't run fixproto
-STMP_FIXPROTO =
-# prefix.c wants to poke around the Registry
-CLIB = -ladvapi32
diff --git a/gcc/config/i386/xm-cygwin32.h b/gcc/config/i386/xm-cygwin32.h
deleted file mode 100644
index fd9c6db5923..00000000000
--- a/gcc/config/i386/xm-cygwin32.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/* Configuration for GNU C-compiler for hosting on Windows NT.
- using a unix style C library.
- Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
-
-This file is part of GNU CC.
-
-GNU CC is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
-
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
-
-#define EXECUTABLE_SUFFIX ".exe"
-#define NO_SYS_SIGLIST 1
-#define HAVE_BCOPY 1
-#define HAVE_BZERO 1
-#define HAVE_BCMP 1
-#define HAVE_RINDEX 1
-#define HAVE_INDEX 1
-
-/* Even though we support "/", allow "\" since everybody tests both. */
-#define DIR_SEPARATOR '\\'
-
-/* If we allow both '/' and '\' as dir separators, then
- allow both unix and win32 PATH syntax */
-#undef GET_ENV_PATH_LIST
-#define GET_ENV_PATH_LIST(VAR,NAME) \
-do { \
- char *_epath; \
- char *_win32epath; \
- _epath = _win32epath = getenv (NAME); \
- /* if we have a posix path list, convert to win32 path list */ \
- if (_epath != NULL && *_epath != 0 \
- && cygwin32_posix_path_list_p (_epath)) \
- { \
- _win32epath = (char *) xmalloc \
- (cygwin32_posix_to_win32_path_list_buf_size (_epath)); \
- cygwin32_posix_to_win32_path_list (_epath, _win32epath); \
- } \
- (VAR) = _win32epath; \
-} while (0)
-
-#define PATH_SEPARATOR ';'
-
-/* This is needed so that protoize will compile. */
-#define POSIX
diff --git a/gcc/config/i386/xm-go32.h b/gcc/config/i386/xm-go32.h
deleted file mode 100644
index c44e73ea421..00000000000
--- a/gcc/config/i386/xm-go32.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/* Configuration for GNU C-compiler for Intel 80386 running GO32.
- Copyright (C) 1988, 1996, 1998 Free Software Foundation, Inc.
-
-This file is part of GNU CC.
-
-GNU CC is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
-
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
-
-#define __MSDOS__ 1
-
-#include "i386/xm-i386.h"
-
-/* Use semicolons to separate elements of a path. */
-#define PATH_SEPARATOR ';'
-
-#define EXECUTABLE_SUFFIX ".exe"
-
-/* Even though we support "/", allow "\" since everybody tests both. */
-#define DIR_SEPARATOR '\\'
-
-#define NO_SYS_SIGLIST 1
diff --git a/gcc/config/i860/fx2800.h b/gcc/config/i860/fx2800.h
index 26c7c253755..50014eac71d 100644
--- a/gcc/config/i860/fx2800.h
+++ b/gcc/config/i860/fx2800.h
@@ -1,6 +1,6 @@
/* Target definitions for GNU compiler for Alliant FX/2800
running Concentrix 2.2
- Copyright (C) 1991, 1996, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1991, 1996, 1998, 1999 Free Software Foundation, Inc.
Contributed by Howard Chu (hyc@hanauma.jpl.nasa.gov).
This file is part of GNU CC.
@@ -351,6 +351,7 @@ do { \
text_section(); \
fputs("__ETEXT:\n", (FILE)); \
} \
- fprintf ((FILE), "\t.ident\t\"GCC: (GNU) %s\"\n", \
- version_string); \
+ if (!flag_no_ident) \
+ fprintf ((FILE), "\t.ident\t\"GCC: (GNU) %s\"\n", \
+ version_string); \
} while (0)
diff --git a/gcc/config/i860/i860.c b/gcc/config/i860/i860.c
index 31dd07e07a4..4b3498da7c9 100644
--- a/gcc/config/i860/i860.c
+++ b/gcc/config/i860/i860.c
@@ -1,5 +1,5 @@
/* Subroutines for insn-output.c for Intel 860
- Copyright (C) 1989, 1991, 1997, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1989, 91, 97, 98, 1999 Free Software Foundation, Inc.
Derived from sparc.c.
Written by Richard Stallman (rms@ai.mit.edu).
@@ -312,7 +312,7 @@ single_insn_src_p (op, mode)
if (CONSTANT_P (arg)
&& !(GET_CODE (arg) == CONST_INT
&& (SMALL_INT (arg)
- || INTVAL (arg) & 0xffff == 0)))
+ || (INTVAL (arg) & 0xffff) == 0)))
return 0;
}
case IOR:
@@ -322,7 +322,7 @@ single_insn_src_p (op, mode)
if (CONSTANT_P (XEXP (op, 1))
&& !(GET_CODE (XEXP (op, 1)) == CONST_INT
&& (SMALL_INT (XEXP (op, 1))
- || INTVAL (XEXP (op, 1)) & 0xffff == 0)))
+ || (INTVAL (XEXP (op, 1)) & 0xffff) == 0)))
return 0;
case ASHIFT:
@@ -1447,7 +1447,7 @@ output_delayed_branch (template, operands, insn)
}
insn_extract (delay_insn);
- if (! constrain_operands (insn_code_number, 1))
+ if (! constrain_operands (1))
fatal_insn_not_found (delay_insn);
template = insn_template[insn_code_number];
@@ -1490,7 +1490,7 @@ output_delay_insn (delay_insn)
}
#ifdef REGISTER_CONSTRAINTS
- if (! constrain_operands (insn_code_number, 1))
+ if (! constrain_operands (1))
abort ();
#endif
diff --git a/gcc/config/i860/i860.h b/gcc/config/i860/i860.h
index 316ba65a7d0..0b0d3659e25 100644
--- a/gcc/config/i860/i860.h
+++ b/gcc/config/i860/i860.h
@@ -52,10 +52,10 @@ extern int target_flags;
An empty string NAME is used to identify the default VALUE. */
#define TARGET_SWITCHES \
- { {"xp", 1}, \
- {"noxp", -1}, \
- {"xr", -1}, \
- { "", TARGET_DEFAULT}}
+ { {"xp", 1, "Generate code which uses the FPU"}, \
+ {"noxp", -1, "Do not generate code which uses the FPU"}, \
+ {"xr", -1, "Do not generate code which uses the FPU"}, \
+ { "", TARGET_DEFAULT, NULL}}
#define TARGET_DEFAULT 0
@@ -656,11 +656,11 @@ struct cumulative_args { int ints, floats; };
/* Addressing modes, and classification of registers for them. */
-/* #define HAVE_POST_INCREMENT */
-/* #define HAVE_POST_DECREMENT */
+/* #define HAVE_POST_INCREMENT 0 */
+/* #define HAVE_POST_DECREMENT 0 */
-/* #define HAVE_PRE_DECREMENT */
-/* #define HAVE_PRE_INCREMENT */
+/* #define HAVE_PRE_DECREMENT 0 */
+/* #define HAVE_PRE_INCREMENT 0 */
/* Macros to check register numbers against specific register classes. */
diff --git a/gcc/config/i860/paragon.h b/gcc/config/i860/paragon.h
index c6bfbba09e9..493b5abce76 100644
--- a/gcc/config/i860/paragon.h
+++ b/gcc/config/i860/paragon.h
@@ -28,12 +28,12 @@ Boston, MA 02111-1307, USA. */
#undef TARGET_SWITCHES
#define TARGET_SWITCHES \
- { {"xp", 1}, \
- {"noxp", -1}, \
- {"xr", -1}, \
- {"noieee", -1}, \
- {"nx", 2}, \
- { "", TARGET_DEFAULT}}
+ { {"xp", 1, "Generate code which uses the FPU"}, \
+ {"noxp", -1, "Do not generate code which uses the FPU"}, \
+ {"xr", -1, "Do not generate code which uses the FPU"}, \
+ {"noieee", -1, "Do not generate code which uses the FPU"}, \
+ {"nx", 2, NULL}, \
+ { "", TARGET_DEFAULT, NULL}}
#undef TARGET_DEFAULT
#define TARGET_DEFAULT 1
diff --git a/gcc/config/i960/i960.c b/gcc/config/i960/i960.c
index 9fa8889c301..3b79d644bdc 100644
--- a/gcc/config/i960/i960.c
+++ b/gcc/config/i960/i960.c
@@ -575,7 +575,7 @@ i960_address_cost (x)
Return 1 if we have written out everything that needs to be done to
do the move. Otherwise, return 0 and the caller will emit the move
- normally. */
+ normally. */
int
emit_move_sequence (operands, mode)
@@ -583,8 +583,12 @@ emit_move_sequence (operands, mode)
enum machine_mode mode;
{
/* We can only store registers to memory. */
-
- if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) != REG)
+
+ if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) != REG
+ && (operands[1] != const0_rtx || current_function_args_size
+ || current_function_varargs || current_function_stdarg
+ || rtx_equal_function_value_matters))
+ /* Here we use the same test as movsi+1 pattern -- see i960.md. */
operands[1] = force_reg (mode, operands[1]);
/* Storing multi-word values in unaligned hard registers to memory may
@@ -673,8 +677,13 @@ i960_output_move_double (dst, src)
{
if (REGNO (src) & 1)
{
- /* This is handled by emit_move_sequence so we shouldn't get here. */
- abort ();
+ operands[0] = dst;
+ operands[1] = adj_offsettable_operand (dst, UNITS_PER_WORD);
+ if (! memory_address_p (word_mode, XEXP (operands[1], 0)))
+ abort ();
+ operands[2] = src;
+ output_asm_insn ("st %2,%0\n\tst %D2,%1", operands);
+ return "";
}
return "stl %1,%0";
}
@@ -682,6 +691,22 @@ i960_output_move_double (dst, src)
abort ();
}
+/* Output assembler to move a double word zero. */
+
+char *
+i960_output_move_double_zero (dst)
+ rtx dst;
+{
+ rtx operands[2];
+
+ operands[0] = dst;
+ {
+ operands[1] = adj_offsettable_operand (dst, 4);
+ output_asm_insn ("st g14,%0\n\tst g14,%1", operands);
+ }
+ return "";
+}
+
/* Output assembler to move a quad word value. */
char *
@@ -744,14 +769,40 @@ i960_output_move_quad (dst, src)
{
if (REGNO (src) & 3)
{
- /* This is handled by emit_move_sequence so we shouldn't get here. */
- abort ();
+ operands[0] = dst;
+ operands[1] = adj_offsettable_operand (dst, UNITS_PER_WORD);
+ operands[2] = adj_offsettable_operand (dst, 2*UNITS_PER_WORD);
+ operands[3] = adj_offsettable_operand (dst, 3*UNITS_PER_WORD);
+ if (! memory_address_p (word_mode, XEXP (operands[3], 0)))
+ abort ();
+ operands[4] = src;
+ output_asm_insn ("st %4,%0\n\tst %D4,%1\n\tst %E4,%2\n\tst %F4,%3", operands);
+ return "";
}
return "stq %1,%0";
}
else
abort ();
}
+
+/* Output assembler to move a quad word zero. */
+
+char *
+i960_output_move_quad_zero (dst)
+ rtx dst;
+{
+ rtx operands[4];
+
+ operands[0] = dst;
+ {
+ operands[1] = adj_offsettable_operand (dst, 4);
+ operands[2] = adj_offsettable_operand (dst, 8);
+ operands[3] = adj_offsettable_operand (dst, 12);
+ output_asm_insn ("st g14,%0\n\tst g14,%1\n\tst g14,%2\n\tst g14,%3", operands);
+ }
+ return "";
+}
+
/* Emit insns to load a constant to non-floating point registers.
Uses several strategies to try to use as few insns as possible. */
@@ -1184,6 +1235,95 @@ compute_frame_size (size)
return actual_fsize;
}
+/* Here register group is range of registers which can be moved by
+ one i960 instruction. */
+
+struct reg_group
+{
+ char start_reg;
+ char length;
+};
+
+/* The following functions forms the biggest as possible register
+ groups with registers in STATE. REGS contain states of the
+ registers in range [start, finish_reg). The function returns the
+ number of groups formed. */
+static int
+i960_form_reg_groups (start_reg, finish_reg, regs, state, reg_groups)
+ int start_reg;
+ int finish_reg;
+ int *regs;
+ int state;
+ struct reg_group *reg_groups;
+{
+ int i;
+ int nw = 0;
+
+ for (i = start_reg; i < finish_reg; )
+ {
+ if (regs [i] != state)
+ {
+ i++;
+ continue;
+ }
+ else if (i % 2 != 0 || regs [i + 1] != state)
+ reg_groups [nw].length = 1;
+ else if (i % 4 != 0 || regs [i + 2] != state)
+ reg_groups [nw].length = 2;
+ else if (regs [i + 3] != state)
+ reg_groups [nw].length = 3;
+ else
+ reg_groups [nw].length = 4;
+ reg_groups [nw].start_reg = i;
+ i += reg_groups [nw].length;
+ nw++;
+ }
+ return nw;
+}
+
+/* We sort register winodws in descending order by length. */
+static int
+i960_reg_group_compare (group1, group2)
+ void *group1;
+ void *group2;
+{
+ struct reg_group *w1 = group1;
+ struct reg_group *w2 = group2;
+
+ if (w1->length > w2->length)
+ return -1;
+ else if (w1->length < w2->length)
+ return 1;
+ else
+ return 0;
+}
+
+/* Split the first register group in REG_GROUPS on subgroups one of
+ which will contain SUBGROUP_LENGTH registers. The function
+ returns new number of winodws. */
+static int
+i960_split_reg_group (reg_groups, nw, subgroup_length)
+ struct reg_group *reg_groups;
+ int nw;
+ int subgroup_length;
+{
+ if (subgroup_length < reg_groups->length - subgroup_length)
+ /* This guarantees correct alignments of the two subgroups for
+ i960 (see spliting for the group length 2, 3, 4). More
+ generalized algorithm would require splitting the group more
+ two subgroups. */
+ subgroup_length = reg_groups->length - subgroup_length;
+ /* More generalized algorithm would require to try merging
+ subgroups here. But in case i960 it always results in failure
+ because of register group alignment. */
+ reg_groups[nw].length = reg_groups->length - subgroup_length;
+ reg_groups[nw].start_reg = reg_groups->start_reg + subgroup_length;
+ nw++;
+ reg_groups->length = subgroup_length;
+ qsort (reg_groups, nw, sizeof (struct reg_group), i960_reg_group_compare);
+ return nw;
+}
+
/* Output code for the function prologue. */
void
@@ -1195,10 +1335,17 @@ i960_function_prologue (file, size)
int n_iregs = 0;
int rsize = 0;
int actual_fsize, offset;
+ int gnw, lnw;
+ struct reg_group *g, *l;
char tmpstr[1000];
/* -1 if reg must be saved on proc entry, 0 if available, 1 if saved
somewhere. */
int regs[FIRST_PSEUDO_REGISTER];
+ /* All global registers (which must be saved) divided by groups. */
+ struct reg_group global_reg_groups [16];
+ /* All local registers (which are available) divided by groups. */
+ struct reg_group local_reg_groups [16];
+
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
if (regs_ever_live[i]
@@ -1226,62 +1373,43 @@ i960_function_prologue (file, size)
regs[i] = -1;
}
- /* First look for local registers to save globals in. */
- for (i = 0; i < 16; i++)
+ gnw = i960_form_reg_groups (0, 16, regs, -1, global_reg_groups);
+ lnw = i960_form_reg_groups (19, 32, regs, 0, local_reg_groups);
+ qsort (global_reg_groups, gnw, sizeof (struct reg_group),
+ i960_reg_group_compare);
+ qsort (local_reg_groups, lnw, sizeof (struct reg_group),
+ i960_reg_group_compare);
+ for (g = global_reg_groups, l = local_reg_groups; lnw != 0 && gnw != 0;)
{
- if (regs[i] == 0)
- continue;
-
- /* Start at r4, not r3. */
- for (j = 20; j < 32; j++)
+ if (g->length == l->length)
{
- if (regs[j] != 0)
- continue;
-
- regs[i] = 1;
- regs[j] = -1;
- regs_ever_live[j] = 1;
- nr = 1;
- if (i <= 14 && i % 2 == 0 && j <= 30 && j % 2 == 0
- && regs[i+1] != 0 && regs[j+1] == 0)
- {
- nr = 2;
- regs[i+1] = 1;
- regs[j+1] = -1;
- regs_ever_live[j+1] = 1;
- }
- if (nr == 2 && i <= 12 && i % 4 == 0 && j <= 28 && j % 4 == 0
- && regs[i+2] != 0 && regs[j+2] == 0)
- {
- nr = 3;
- regs[i+2] = 1;
- regs[j+2] = -1;
- regs_ever_live[j+2] = 1;
- }
- if (nr == 3 && regs[i+3] != 0 && regs[j+3] == 0)
- {
- nr = 4;
- regs[i+3] = 1;
- regs[j+3] = -1;
- regs_ever_live[j+3] = 1;
- }
-
fprintf (file, "\tmov%s %s,%s\n",
- ((nr == 4) ? "q" :
- (nr == 3) ? "t" :
- (nr == 2) ? "l" : ""),
- reg_names[i], reg_names[j]);
+ ((g->length == 4) ? "q" :
+ (g->length == 3) ? "t" :
+ (g->length == 2) ? "l" : ""),
+ reg_names[g->start_reg], reg_names[l->start_reg]);
sprintf (tmpstr, "\tmov%s %s,%s\n",
- ((nr == 4) ? "q" :
- (nr == 3) ? "t" :
- (nr == 2) ? "l" : ""),
- reg_names[j], reg_names[i]);
+ ((g->length == 4) ? "q" :
+ (g->length == 3) ? "t" :
+ (g->length == 2) ? "l" : ""),
+ reg_names[l->start_reg], reg_names[g->start_reg]);
strcat (epilogue_string, tmpstr);
-
- n_iregs -= nr;
- i += nr-1;
- break;
+ n_iregs -= g->length;
+ for (i = 0; i < g->length; i++)
+ {
+ regs [i + g->start_reg] = 1;
+ regs [i + l->start_reg] = -1;
+ regs_ever_live [i + l->start_reg] = 1;
+ }
+ g++;
+ l++;
+ gnw--;
+ lnw--;
}
+ else if (g->length > l->length)
+ gnw = i960_split_reg_group (g, gnw, l->length);
+ else
+ lnw = i960_split_reg_group (l, lnw, g->length);
}
/* N_iregs is now the number of global registers that haven't been saved
@@ -1314,6 +1442,8 @@ i960_function_prologue (file, size)
into account, but store them before the argument block area. */
offset = 64 + actual_fsize - compute_frame_size (0) - rsize;
/* Save registers on stack if needed. */
+ /* ??? Is it worth to use the same algorithm as one for saving
+ global registers in local registers? */
for (i = 0, j = n_iregs; j > 0 && i < 16; i++)
{
if (regs[i] != -1)
diff --git a/gcc/config/i960/i960.h b/gcc/config/i960/i960.h
index fac037bb348..36aa6d9757b 100644
--- a/gcc/config/i960/i960.h
+++ b/gcc/config/i960/i960.h
@@ -24,6 +24,8 @@ Boston, MA 02111-1307, USA. */
/* Note that some other tm.h files may include this one and then override
many of the definitions that relate to assembler syntax. */
+#define MULTILIB_DEFAULTS { "mnumerics" }
+
/* Names to predefine in the preprocessor for this target machine. */
#define CPP_PREDEFINES "-Di960 -Di80960 -DI960 -DI80960 -Acpu(i960) -Amachine(i960)"
@@ -45,7 +47,8 @@ Boston, MA 02111-1307, USA. */
%{mcc:-D__i960CC__ -D__i960_CC__}\
%{mcf:-D__i960CF__ -D__i960_CF__}\
%{!mka:%{!mkb:%{!msa:%{!msb:%{!mmc:%{!mca:\
- %{!mcc:%{!mcf:-D__i960_KB -D__i960KB__ %{mic*:-D__i960KB}}}}}}}}}"
+ %{!mcc:%{!mcf:-D__i960_KB -D__i960KB__ %{mic*:-D__i960KB}}}}}}}}}\
+ %{mlong-double-64:-D__LONG_DOUBLE_64__}"
/* -mic* options make characters signed by default. */
/* Use #if rather than ?: because MIPS C compiler rejects ?: in
@@ -209,6 +212,11 @@ extern int process_pragma ();
#define TARGET_FLAG_OLD_ALIGN 0x8000
#define TARGET_OLD_ALIGN (target_flags & TARGET_FLAG_OLD_ALIGN)
+/* Nonzero if long doubles are to be 64 bits. Useful for soft-float targets
+ if 80 bit long double support is missing. */
+#define TARGET_FLAG_LONG_DOUBLE_64 0x10000
+#define TARGET_LONG_DOUBLE_64 (target_flags & TARGET_FLAG_LONG_DOUBLE_64)
+
extern int target_flags;
/* Macro to define tables used to set the flags.
@@ -221,57 +229,98 @@ extern int target_flags;
am not sure which are real and which aren't. */
#define TARGET_SWITCHES \
- { {"sa", (TARGET_FLAG_K_SERIES|TARGET_FLAG_COMPLEX_ADDR)},\
- {"sb", (TARGET_FLAG_NUMERICS|TARGET_FLAG_K_SERIES| \
- TARGET_FLAG_COMPLEX_ADDR)},\
-/* {"sc", (TARGET_FLAG_NUMERICS|TARGET_FLAG_PROTECTED|\
- TARGET_FLAG_MC|TARGET_FLAG_COMPLEX_ADDR)},*/ \
- {"ka", (TARGET_FLAG_K_SERIES|TARGET_FLAG_COMPLEX_ADDR)},\
- {"kb", (TARGET_FLAG_NUMERICS|TARGET_FLAG_K_SERIES| \
- TARGET_FLAG_COMPLEX_ADDR)},\
-/* {"kc", (TARGET_FLAG_NUMERICS|TARGET_FLAG_PROTECTED|\
- TARGET_FLAG_MC|TARGET_FLAG_COMPLEX_ADDR)},*/ \
- {"ja", (TARGET_FLAG_K_SERIES|TARGET_FLAG_COMPLEX_ADDR)},\
- {"jd", (TARGET_FLAG_K_SERIES|TARGET_FLAG_COMPLEX_ADDR)},\
- {"jf", (TARGET_FLAG_NUMERICS|TARGET_FLAG_K_SERIES| \
- TARGET_FLAG_COMPLEX_ADDR)},\
- {"rp", (TARGET_FLAG_K_SERIES|TARGET_FLAG_COMPLEX_ADDR)},\
- {"mc", (TARGET_FLAG_NUMERICS|TARGET_FLAG_PROTECTED|\
- TARGET_FLAG_MC|TARGET_FLAG_COMPLEX_ADDR)},\
- {"ca", (TARGET_FLAG_C_SERIES|TARGET_FLAG_BRANCH_PREDICT|\
- TARGET_FLAG_CODE_ALIGN|TARGET_FLAG_COMPLEX_ADDR)},\
-/* {"cb", (TARGET_FLAG_NUMERICS|TARGET_FLAG_C_SERIES|\
- TARGET_FLAG_BRANCH_PREDICT|TARGET_FLAG_CODE_ALIGN)},\
- {"cc", (TARGET_FLAG_NUMERICS|TARGET_FLAG_PROTECTED|\
+ { {"sa", (TARGET_FLAG_K_SERIES|TARGET_FLAG_COMPLEX_ADDR), \
+ "Generate SA code"}, \
+ {"sb", (TARGET_FLAG_NUMERICS|TARGET_FLAG_K_SERIES| \
+ TARGET_FLAG_COMPLEX_ADDR), \
+ "Generate SB code"}, \
+/* {"sc", (TARGET_FLAG_NUMERICS|TARGET_FLAG_PROTECTED| \
+ TARGET_FLAG_MC|TARGET_FLAG_COMPLEX_ADDR), \
+ "Generate SC code"}, */ \
+ {"ka", (TARGET_FLAG_K_SERIES|TARGET_FLAG_COMPLEX_ADDR), \
+ "Generate KA code"}, \
+ {"kb", (TARGET_FLAG_NUMERICS|TARGET_FLAG_K_SERIES| \
+ TARGET_FLAG_COMPLEX_ADDR), \
+ "Generate KB code"}, \
+/* {"kc", (TARGET_FLAG_NUMERICS|TARGET_FLAG_PROTECTED| \
+ TARGET_FLAG_MC|TARGET_FLAG_COMPLEX_ADDR), \
+ "Generate KC code"}, */ \
+ {"ja", (TARGET_FLAG_K_SERIES|TARGET_FLAG_COMPLEX_ADDR), \
+ "Generate JA code"}, \
+ {"jd", (TARGET_FLAG_K_SERIES|TARGET_FLAG_COMPLEX_ADDR), \
+ "Generate JD code"}, \
+ {"jf", (TARGET_FLAG_NUMERICS|TARGET_FLAG_K_SERIES| \
+ TARGET_FLAG_COMPLEX_ADDR), \
+ "Generate JF code"}, \
+ {"rp", (TARGET_FLAG_K_SERIES|TARGET_FLAG_COMPLEX_ADDR), \
+ "generate RP code"}, \
+ {"mc", (TARGET_FLAG_NUMERICS|TARGET_FLAG_PROTECTED| \
+ TARGET_FLAG_MC|TARGET_FLAG_COMPLEX_ADDR), \
+ "Generate MC code"}, \
+ {"ca", (TARGET_FLAG_C_SERIES|TARGET_FLAG_BRANCH_PREDICT| \
+ TARGET_FLAG_CODE_ALIGN|TARGET_FLAG_COMPLEX_ADDR),\
+ "Generate CA code"}, \
+/* {"cb", (TARGET_FLAG_NUMERICS|TARGET_FLAG_C_SERIES| \
+ TARGET_FLAG_BRANCH_PREDICT|TARGET_FLAG_CODE_ALIGN),\
+ "Generate CB code"}, \
+ {"cc", (TARGET_FLAG_NUMERICS|TARGET_FLAG_PROTECTED| \
TARGET_FLAG_C_SERIES|TARGET_FLAG_BRANCH_PREDICT|\
- TARGET_FLAG_CODE_ALIGN)}, */ \
- {"cf", (TARGET_FLAG_C_SERIES|TARGET_FLAG_BRANCH_PREDICT|\
- TARGET_FLAG_CODE_ALIGN|TARGET_FLAG_COMPLEX_ADDR)},\
- {"numerics", (TARGET_FLAG_NUMERICS)}, \
- {"soft-float", -(TARGET_FLAG_NUMERICS)}, \
- {"leaf-procedures", TARGET_FLAG_LEAFPROC}, \
- {"no-leaf-procedures",-(TARGET_FLAG_LEAFPROC)}, \
- {"tail-call",TARGET_FLAG_TAILCALL}, \
- {"no-tail-call",-(TARGET_FLAG_TAILCALL)}, \
- {"complex-addr",TARGET_FLAG_COMPLEX_ADDR}, \
- {"no-complex-addr",-(TARGET_FLAG_COMPLEX_ADDR)}, \
- {"code-align",TARGET_FLAG_CODE_ALIGN}, \
- {"no-code-align",-(TARGET_FLAG_CODE_ALIGN)}, \
- {"clean-linkage", (TARGET_FLAG_CLEAN_LINKAGE)}, \
- {"no-clean-linkage", -(TARGET_FLAG_CLEAN_LINKAGE)}, \
- {"ic-compat", TARGET_FLAG_IC_COMPAT2_0}, \
- {"ic2.0-compat", TARGET_FLAG_IC_COMPAT2_0}, \
- {"ic3.0-compat", TARGET_FLAG_IC_COMPAT3_0}, \
- {"asm-compat",TARGET_FLAG_ASM_COMPAT}, \
- {"intel-asm",TARGET_FLAG_ASM_COMPAT}, \
- {"strict-align", TARGET_FLAG_STRICT_ALIGN}, \
- {"no-strict-align", -(TARGET_FLAG_STRICT_ALIGN)}, \
- {"old-align", (TARGET_FLAG_OLD_ALIGN|TARGET_FLAG_STRICT_ALIGN)}, \
- {"no-old-align", -(TARGET_FLAG_OLD_ALIGN|TARGET_FLAG_STRICT_ALIGN)}, \
- {"link-relax", 0}, \
- {"no-link-relax", 0}, \
+ TARGET_FLAG_CODE_ALIGN), \
+ "Generate CC code"}, */ \
+ {"cf", (TARGET_FLAG_C_SERIES|TARGET_FLAG_BRANCH_PREDICT| \
+ TARGET_FLAG_CODE_ALIGN|TARGET_FLAG_COMPLEX_ADDR),\
+ "Generate CF code"}, \
+ {"numerics", (TARGET_FLAG_NUMERICS), \
+ "Use hardware floating point instructions"}, \
+ {"soft-float", -(TARGET_FLAG_NUMERICS), \
+ "Use software floating point"}, \
+ {"leaf-procedures", TARGET_FLAG_LEAFPROC, \
+ "Use alternate leaf function entries"}, \
+ {"no-leaf-procedures", -(TARGET_FLAG_LEAFPROC), \
+ "Do not use alternate leaf function entries"}, \
+ {"tail-call", TARGET_FLAG_TAILCALL, \
+ "Perform tail call optimization"}, \
+ {"no-tail-call", -(TARGET_FLAG_TAILCALL), \
+ "Do not perform tail call optimization"}, \
+ {"complex-addr", TARGET_FLAG_COMPLEX_ADDR, \
+ "Use complex addressing modes"}, \
+ {"no-complex-addr", -(TARGET_FLAG_COMPLEX_ADDR), \
+ "Do not use complex addressing modes"}, \
+ {"code-align", TARGET_FLAG_CODE_ALIGN, \
+ "Align code to 8 byte boundary"}, \
+ {"no-code-align", -(TARGET_FLAG_CODE_ALIGN), \
+ "Do not align code to 8 byte boundary"}, \
+/* {"clean-linkage", (TARGET_FLAG_CLEAN_LINKAGE), \
+ "Force use of prototypes"}, \
+ {"no-clean-linkage", -(TARGET_FLAG_CLEAN_LINKAGE), \
+ "Do not force use of prototypes"}, */ \
+ {"ic-compat", TARGET_FLAG_IC_COMPAT2_0, \
+ "Enable compatibility with iC960 v2.0"}, \
+ {"ic2.0-compat", TARGET_FLAG_IC_COMPAT2_0, \
+ "Enable compatibility with iC960 v2.0"}, \
+ {"ic3.0-compat", TARGET_FLAG_IC_COMPAT3_0, \
+ "Enable compatibility with iC960 v3.0"}, \
+ {"asm-compat", TARGET_FLAG_ASM_COMPAT, \
+ "Enable compatibility with ic960 assembler"}, \
+ {"intel-asm", TARGET_FLAG_ASM_COMPAT, \
+ "Enable compatibility with ic960 assembler"}, \
+ {"strict-align", TARGET_FLAG_STRICT_ALIGN, \
+ "Do not permit unaligned accesses"}, \
+ {"no-strict-align", -(TARGET_FLAG_STRICT_ALIGN), \
+ "Permit unaligned accesses"}, \
+ {"old-align", (TARGET_FLAG_OLD_ALIGN|TARGET_FLAG_STRICT_ALIGN), \
+ "Layout types like Intel's v1.3 gcc"}, \
+ {"no-old-align", -(TARGET_FLAG_OLD_ALIGN|TARGET_FLAG_STRICT_ALIGN), \
+ "Do not layout types like Intel's v1.3 gcc"}, \
+ {"long-double-64", TARGET_FLAG_LONG_DOUBLE_64, \
+ "Use 64 bit long doubles"}, \
+ {"link-relax", 0, \
+ "Enable linker relaxation"}, \
+ {"no-link-relax", 0, \
+ "Do not enable linker relaxation"}, \
SUBTARGET_SWITCHES \
- { "", TARGET_DEFAULT}}
+ { "", TARGET_DEFAULT, \
+ NULL}}
/* This are meant to be redefined in the host dependent files */
#define SUBTARGET_SWITCHES
@@ -312,6 +361,9 @@ extern int target_flags;
flag_signed_char = 1; \
target_flags |= TARGET_FLAG_CLEAN_LINKAGE; \
} \
+ /* ??? See the LONG_DOUBLE_TYPE_SIZE definition below. */ \
+ if (TARGET_LONG_DOUBLE_64) \
+ warning ("The -mlong-double-64 option does not work yet.", 0);\
i960_initialize (); \
}
@@ -356,8 +408,21 @@ extern int target_flags;
/* Width in bits of a pointer. See also the macro `Pmode' defined below. */
#define POINTER_SIZE 32
-/* Width in bits of a long double. Identical to double for now. */
-#define LONG_DOUBLE_TYPE_SIZE 64
+/* Width in bits of a long double. Define to 96, and let
+ ROUND_TYPE_ALIGN adjust the alignment for speed. */
+#define LONG_DOUBLE_TYPE_SIZE (TARGET_LONG_DOUBLE_64 ? 64 : 96)
+
+/* ??? This must be a constant, because real.c and real.h test it with #if. */
+#undef LONG_DOUBLE_TYPE_SIZE
+#define LONG_DOUBLE_TYPE_SIZE 96
+
+/* Define this to set long double type size to use in libgcc2.c, which can
+ not depend on target_flags. */
+#if defined(__LONG_DOUBLE_64__)
+#define LIBGCC2_LONG_DOUBLE_TYPE_SIZE 64
+#else
+#define LIBGCC2_LONG_DOUBLE_TYPE_SIZE 96
+#endif
/* Allocation boundary (in *bits*) for storing pointers in memory. */
#define POINTER_BOUNDARY 32
@@ -924,11 +989,11 @@ extern struct rtx_def *i960_function_arg ();
/* Addressing modes, and classification of registers for them. */
-/* #define HAVE_POST_INCREMENT */
-/* #define HAVE_POST_DECREMENT */
+/* #define HAVE_POST_INCREMENT 0 */
+/* #define HAVE_POST_DECREMENT 0 */
-/* #define HAVE_PRE_DECREMENT */
-/* #define HAVE_PRE_INCREMENT */
+/* #define HAVE_PRE_DECREMENT 0 */
+/* #define HAVE_PRE_INCREMENT 0 */
/* Macros to check register numbers against specific register classes. */
@@ -1114,6 +1179,11 @@ extern struct rtx_def *legitimize_address ();
#define SLOW_BYTE_ACCESS 1
+/* Force sizeof(bool) == 1 to maintain binary compatibility; otherwise, the
+ change in SLOW_BYTE_ACCESS would have changed it to 4. */
+
+#define BOOL_TYPE_SIZE CHAR_TYPE_SIZE
+
/* We assume that the store-condition-codes instructions store 0 for false
and some other value for true. This is the value stored for true. */
@@ -1185,10 +1255,14 @@ extern struct rtx_def *gen_compare_reg ();
that can be non-ldconst operands in rare cases are cost 1. Other constants
have higher costs. */
+/* Must check for OUTER_CODE of SET for power2_operand, because
+ reload_cse_move2add calls us with OUTER_CODE of PLUS to decide when
+ to replace set with add. */
+
#define CONST_COSTS(RTX, CODE, OUTER_CODE) \
case CONST_INT: \
if ((INTVAL (RTX) >= 0 && INTVAL (RTX) < 32) \
- || power2_operand (RTX, VOIDmode)) \
+ || (OUTER_CODE == SET && power2_operand (RTX, VOIDmode))) \
return 0; \
else if (INTVAL (RTX) >= -31 && INTVAL (RTX) < 0) \
return 1; \
@@ -1555,7 +1629,9 @@ extern char *i960_output_ldconst ();
extern char *i960_output_call_insn ();
extern char *i960_output_ret_insn ();
extern char *i960_output_move_double ();
+extern char *i960_output_move_double_zero ();
extern char *i960_output_move_quad ();
+extern char *i960_output_move_quad_zero ();
/* Defined in reload.c, and used in insn-recog.c. */
diff --git a/gcc/config/i960/i960.md b/gcc/config/i960/i960.md
index c99c6c1fdc9..53157e09c2f 100644
--- a/gcc/config/i960/i960.md
+++ b/gcc/config/i960/i960.md
@@ -835,8 +835,7 @@
case 2:
return i960_output_ldconst (operands[0], operands[1]);
case 5:
- operands[1] = adj_offsettable_operand (operands[0], 4);
- return \"st g14,%0\;st g14,%1\";
+ return i960_output_move_double_zero (operands[0]);
}
}"
[(set_attr "type" "move,move,load,load,store,store")])
@@ -915,10 +914,7 @@
case 2:
return i960_output_ldconst (operands[0], operands[1]);
case 5:
- operands[1] = adj_offsettable_operand (operands[0], 4);
- operands[2] = adj_offsettable_operand (operands[0], 8);
- operands[3] = adj_offsettable_operand (operands[0], 12);
- return \"st g14,%0\;st g14,%1\;st g14,%2\;st g14,%3\";
+ return i960_output_move_quad_zero (operands[0]);
}
}"
[(set_attr "type" "move,move,load,load,store,store")])
@@ -1193,7 +1189,8 @@
op1_subreg_word = SUBREG_WORD (operand1);
operand1 = SUBREG_REG (operand1);
}
- operand1 = gen_rtx (SUBREG, SImode, operand1, op1_subreg_word);
+ if (GET_MODE (operand1) != SImode)
+ operand1 = gen_rtx (SUBREG, SImode, operand1, op1_subreg_word);
emit_insn (gen_ashlsi3 (temp, operand1, shift_16));
emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
@@ -1227,7 +1224,8 @@
op1_subreg_word = SUBREG_WORD (operand1);
operand1 = SUBREG_REG (operand1);
}
- operand1 = gen_rtx (SUBREG, SImode, operand1, op1_subreg_word),
+ if (GET_MODE (operand1) != SImode)
+ operand1 = gen_rtx (SUBREG, SImode, operand1, op1_subreg_word);
emit_insn (gen_ashlsi3 (temp, operand1, shift_24));
emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
@@ -1263,7 +1261,8 @@
op1_subreg_word = SUBREG_WORD (operand1);
operand1 = SUBREG_REG (operand1);
}
- operand1 = gen_rtx (SUBREG, SImode, operand1, op1_subreg_word);
+ if (GET_MODE (operand1) != SImode)
+ operand1 = gen_rtx (SUBREG, SImode, operand1, op1_subreg_word);
if (GET_CODE (operand0) == SUBREG)
{
@@ -1306,7 +1305,8 @@
op1_subreg_word = SUBREG_WORD (operand1);
operand1 = SUBREG_REG (operand1);
}
- operand1 = gen_rtx (SUBREG, SImode, operand1, op1_subreg_word);
+ if (GET_MODE (operand1) != SImode)
+ operand1 = gen_rtx (SUBREG, SImode, operand1, op1_subreg_word);
emit_insn (gen_ashlsi3 (temp, operand1, shift_16));
emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
@@ -1345,7 +1345,8 @@
op1_subreg_word = SUBREG_WORD (operand1);
operand1 = SUBREG_REG (operand1);
}
- operand1 = gen_rtx (SUBREG, SImode, operand1, op1_subreg_word);
+ if (GET_MODE (operand1) != SImode)
+ operand1 = gen_rtx (SUBREG, SImode, operand1, op1_subreg_word);
emit_insn (gen_ashlsi3 (temp, operand1, shift_24));
emit_insn (gen_lshrsi3 (operand0, temp, shift_24));
@@ -1381,7 +1382,8 @@
op1_subreg_word = SUBREG_WORD (operand1);
operand1 = SUBREG_REG (operand1);
}
- operand1 = gen_rtx (SUBREG, SImode, operand1, op1_subreg_word);
+ if (GET_MODE (operand1) != SImode)
+ operand1 = gen_rtx (SUBREG, SImode, operand1, op1_subreg_word);
if (GET_CODE (operand0) == SUBREG)
{
@@ -2343,6 +2345,7 @@
plus_constant (fp, 8)),
new_pc);
+#if 0
/* Next, we put the value into the static chain register's save
area on the stack. After the ret below, this will be loaded into
r3 (the static chain). */
@@ -2350,6 +2353,7 @@
emit_move_insn (gen_rtx (MEM, SImode,
plus_constant (fp, 12)),
val);
+#endif
/* We now load pfp (the previous frame pointer) with the value that
we want fp to be. */
diff --git a/gcc/config/i960/t-960bare b/gcc/config/i960/t-960bare
index c6be2a04f3e..37929bb07f8 100644
--- a/gcc/config/i960/t-960bare
+++ b/gcc/config/i960/t-960bare
@@ -16,8 +16,8 @@ xp-bit.c: $(srcdir)/config/fp-bit.c
echo '#define EXTENDED_FLOAT_STUBS' > xp-bit.c
cat $(srcdir)/config/fp-bit.c >> xp-bit.c
-MULTILIB_OPTIONS=mnumerics/msoft-float
-MULTILIB_DIRNAMES=float soft-float
+MULTILIB_OPTIONS=mnumerics/msoft-float mlong-double-64
+MULTILIB_DIRNAMES=float soft-float ld64
MULTILIB_MATCHES=mnumerics=msb mnumerics=msc mnumerics=mkb mnumerics=mkc mnumerics=mmc mnumerics=mcb mnumerics=mcc mnumerics=mjf msoft-float=msa msoft-float=mka msoft-float=mca msoft-float=mcf
LIBGCC = stmp-multilib
diff --git a/gcc/config/i960/t-vxworks960 b/gcc/config/i960/t-vxworks960
index c2dd5eb2060..851e7bd1fec 100644
--- a/gcc/config/i960/t-vxworks960
+++ b/gcc/config/i960/t-vxworks960
@@ -19,8 +19,8 @@ xp-bit.c: $(srcdir)/config/fp-bit.c
echo '#define EXTENDED_FLOAT_STUBS' > xp-bit.c
cat $(srcdir)/config/fp-bit.c >> xp-bit.c
-MULTILIB_OPTIONS=mnumerics/msoft-float
-MULTILIB_DIRNAMES=float soft-float
+MULTILIB_OPTIONS=mnumerics/msoft-float mlong-double-64
+MULTILIB_DIRNAMES=float soft-float ld64
MULTILIB_MATCHES=mnumerics=msb mnumerics=msc mnumerics=mkb mnumerics=mkc mnumerics=mmc mnumerics=mcb mnumerics=mcc msoft-float=msa msoft-float=mka msoft-float=mca msoft-float=mcf
LIBGCC = stmp-multilib
diff --git a/gcc/config/i960/vx960-coff.h b/gcc/config/i960/vx960-coff.h
index b2e93fb9976..91879ddec39 100644
--- a/gcc/config/i960/vx960-coff.h
+++ b/gcc/config/i960/vx960-coff.h
@@ -21,6 +21,8 @@ Boston, MA 02111-1307, USA. */
/* This file just exists to give specs for the 960 running on VxWorks.
VxWorks does all the library stuff itself. */
+#define MULTILIB_DEFAULTS { "msoft-float" }
+
#undef LIB_SPEC
#define LIB_SPEC ""
@@ -57,7 +59,8 @@ Boston, MA 02111-1307, USA. */
%{mcf:-D__i960CF__ -D__i960_CF__}\
%{!mka:%{!mkb:%{!msa:%{!msb:%{!mmc:%{!mca:\
%{!mcc:%{!mcf:-D__i960_CA -D__i960CA__ -DCPU=I960CA\
- %{mic*:-D__i960CA}}}}}}}}}"
+ %{mic*:-D__i960CA}}}}}}}}}\
+ %{mlong-double-64:-D__LONG_DOUBLE_64__}"
/* Default to -mca. */
diff --git a/gcc/config/m32r/initfini.c b/gcc/config/m32r/initfini.c
index 34ef5da962f..51444279e52 100644
--- a/gcc/config/m32r/initfini.c
+++ b/gcc/config/m32r/initfini.c
@@ -1,7 +1,7 @@
/* .init/.fini section handling + C++ global constructor/destructor handling.
This file is based on crtstuff.c, sol2-crti.asm, sol2-crtn.asm.
-Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -80,32 +80,32 @@ __do_global_dtors ()
/* .init section start.
This must appear at the start of the .init section. */
-asm ("
- .section .init,\"ax\",@progbits
- .balign 4
- .global __init
-__init:
- push fp
- push lr
- mv fp,sp
- ld24 r0,#__fini
- bl atexit
- .fillinsn
+asm ("\n\
+ .section .init,\"ax\",@progbits\n\
+ .balign 4\n\
+ .global __init\n\
+__init:\n\
+ push fp\n\
+ push lr\n\
+ mv fp,sp\n\
+ ld24 r0,#__fini\n\
+ bl atexit\n\
+ .fillinsn\n\
");
/* .fini section start.
This must appear at the start of the .init section. */
-asm ("
- .section .fini,\"ax\",@progbits
- .balign 4
- .global __fini
-__fini:
- push fp
- push lr
- mv fp,sp
- bl __do_global_dtors
- .fillinsn
+asm ("\n\
+ .section .fini,\"ax\",@progbits\n\
+ .balign 4\n\
+ .global __fini\n\
+__fini:\n\
+ push fp\n\
+ push lr\n\
+ mv fp,sp\n\
+ bl __do_global_dtors\n\
+ .fillinsn\n\
");
#endif /* CRT_INIT */
@@ -144,26 +144,26 @@ __do_global_ctors ()
/* .init section end.
This must live at the end of the .init section. */
-asm ("
- .section .init,\"ax\",@progbits
- bl __do_global_ctors
- mv sp,fp
- pop lr
- pop fp
- jmp lr
- .fillinsn
+asm ("\n\
+ .section .init,\"ax\",@progbits\n\
+ bl __do_global_ctors\n\
+ mv sp,fp\n\
+ pop lr\n\
+ pop fp\n\
+ jmp lr\n\
+ .fillinsn\n\
");
/* .fini section end.
This must live at the end of the .fini section. */
-asm ("
- .section .fini,\"ax\",@progbits
- mv sp,fp
- pop lr
- pop fp
- jmp lr
- .fillinsn
+asm ("\n\
+ .section .fini,\"ax\",@progbits\n\
+ mv sp,fp\n\
+ pop lr\n\
+ pop fp\n\
+ jmp lr\n\
+ .fillinsn\n\
");
#endif /* CRT_FINI */
diff --git a/gcc/config/m32r/m32r.c b/gcc/config/m32r/m32r.c
index 41f7ce330ce..ddc052b365b 100644
--- a/gcc/config/m32r/m32r.c
+++ b/gcc/config/m32r/m32r.c
@@ -203,6 +203,35 @@ init_reg_tables ()
Grep for MODEL in m32r.h for more info.
*/
+static tree interrupt_ident1;
+static tree interrupt_ident2;
+static tree model_ident1;
+static tree model_ident2;
+static tree small_ident1;
+static tree small_ident2;
+static tree medium_ident1;
+static tree medium_ident2;
+static tree large_ident1;
+static tree large_ident2;
+
+static void
+init_idents PROTO ((void))
+{
+ if (interrupt_ident1 == 0)
+ {
+ interrupt_ident1 = get_identifier ("interrupt");
+ interrupt_ident2 = get_identifier ("__interrupt__");
+ model_ident1 = get_identifier ("model");
+ model_ident2 = get_identifier ("__model__");
+ small_ident1 = get_identifier ("small");
+ small_ident2 = get_identifier ("__small__");
+ medium_ident1 = get_identifier ("medium");
+ medium_ident2 = get_identifier ("__medium__");
+ large_ident1 = get_identifier ("large");
+ large_ident2 = get_identifier ("__large__");
+ }
+}
+
/* Return nonzero if IDENTIFIER is a valid decl attribute. */
int
@@ -212,27 +241,22 @@ m32r_valid_machine_decl_attribute (type, attributes, identifier, args)
tree identifier;
tree args;
{
- static tree interrupt_ident, model_ident;
- static tree small_ident, medium_ident, large_ident;
+ init_idents ();
- if (interrupt_ident == 0)
- {
- interrupt_ident = get_identifier ("__interrupt__");
- model_ident = get_identifier ("__model__");
- small_ident = get_identifier ("__small__");
- medium_ident = get_identifier ("__medium__");
- large_ident = get_identifier ("__large__");
- }
-
- if (identifier == interrupt_ident
+ if ((identifier == interrupt_ident1
+ || identifier == interrupt_ident2)
&& list_length (args) == 0)
return 1;
- if (identifier == model_ident
+ if ((identifier == model_ident1
+ || identifier == model_ident2)
&& list_length (args) == 1
- && (TREE_VALUE (args) == small_ident
- || TREE_VALUE (args) == medium_ident
- || TREE_VALUE (args) == large_ident))
+ && (TREE_VALUE (args) == small_ident1
+ || TREE_VALUE (args) == small_ident2
+ || TREE_VALUE (args) == medium_ident1
+ || TREE_VALUE (args) == medium_ident2
+ || TREE_VALUE (args) == large_ident1
+ || TREE_VALUE (args) == large_ident2))
return 1;
return 0;
@@ -371,11 +395,17 @@ m32r_encode_section_info (decl)
{
if (model)
{
- if (TREE_VALUE (TREE_VALUE (model)) == get_identifier ("__small__"))
+ tree id;
+
+ init_idents ();
+
+ id = TREE_VALUE (TREE_VALUE (model));
+
+ if (id == small_ident1 || id == small_ident2)
; /* don't mark the symbol specially */
- else if (TREE_VALUE (TREE_VALUE (model)) == get_identifier ("__medium__"))
+ else if (id == medium_ident1 || id == medium_ident2)
prefix = MEDIUM_FLAG_CHAR;
- else if (TREE_VALUE (TREE_VALUE (model)) == get_identifier ("__large__"))
+ else if (id == large_ident1 || id == large_ident2)
prefix = LARGE_FLAG_CHAR;
else
abort (); /* shouldn't happen */
@@ -1123,16 +1153,29 @@ gen_split_move_double (operands)
rtx src = operands[1];
rtx val;
+ /* We might have (SUBREG (MEM)) here, so just get rid of the
+ subregs to make this code simpler. It is safe to call
+ alter_subreg any time after reload. */
+ if (GET_CODE (dest) == SUBREG)
+ dest = alter_subreg (dest);
+ if (GET_CODE (src) == SUBREG)
+ src = alter_subreg (src);
+
start_sequence ();
- if (GET_CODE (dest) == REG || GET_CODE (dest) == SUBREG)
+ if (GET_CODE (dest) == REG)
{
+ int dregno = REGNO (dest);
+
/* reg = reg */
- if (GET_CODE (src) == REG || GET_CODE (src) == SUBREG)
+ if (GET_CODE (src) == REG)
{
+ int sregno = REGNO (src);
+
+ int reverse = (dregno == sregno + 1);
+
/* We normally copy the low-numbered register first. However, if
the first register operand 0 is the same as the second register of
operand 1, we must copy in the opposite order. */
- int reverse = (REGNO (operands[0]) == REGNO (operands[1]) + 1);
emit_insn (gen_rtx_SET (VOIDmode,
operand_subword (dest, reverse, TRUE, mode),
operand_subword (src, reverse, TRUE, mode)));
@@ -1162,8 +1205,7 @@ gen_split_move_double (operands)
/* If the high-address word is used in the address, we must load it
last. Otherwise, load it first. */
rtx addr = XEXP (src, 0);
- int reverse = (refers_to_regno_p (REGNO (dest), REGNO (dest)+1,
- addr, 0) != 0);
+ int reverse = (refers_to_regno_p (dregno, dregno+1, addr, 0) != 0);
/* We used to optimize loads from single registers as
@@ -1205,8 +1247,7 @@ gen_split_move_double (operands)
st r1,r3; st r2,+r3; addi r3,-4
which saves 2 bytes and doesn't force longword alignment. */
- else if (GET_CODE (dest) == MEM
- && (GET_CODE (src) == REG || GET_CODE (src) == SUBREG))
+ else if (GET_CODE (dest) == MEM && GET_CODE (src) == REG)
{
rtx addr = XEXP (dest, 0);
@@ -1540,9 +1581,14 @@ m32r_expand_prologue ()
/* Allocate space for register arguments if this is a variadic function. */
if (current_frame_info.pretend_size != 0)
- emit_insn (gen_addsi3 (stack_pointer_rtx,
- stack_pointer_rtx,
- GEN_INT (-current_frame_info.pretend_size)));
+ {
+ /* Use a HOST_WIDE_INT temporary, since negating an unsigned int gives
+ the wrong result on a 64-bit host. */
+ HOST_WIDE_INT pretend_size = current_frame_info.pretend_size;
+ emit_insn (gen_addsi3 (stack_pointer_rtx,
+ stack_pointer_rtx,
+ GEN_INT (-pretend_size)));
+ }
/* Save any registers we need to and set up fp. */
@@ -2311,8 +2357,8 @@ m32r_expand_block_move (operands)
{
rtx label;
rtx final_src;
-
- bytes_rtx = GEN_INT (MAX_MOVE_BYTES);
+ rtx at_a_time = GEN_INT (MAX_MOVE_BYTES);
+ rtx rounded_total = GEN_INT (bytes);
/* If we are going to have to perform this loop more than
once, then generate a label and compute the address the
@@ -2323,10 +2369,10 @@ m32r_expand_block_move (operands)
final_src = gen_reg_rtx (Pmode);
if (INT16_P(bytes))
- emit_insn (gen_addsi3 (final_src, src_reg, bytes_rtx));
+ emit_insn (gen_addsi3 (final_src, src_reg, rounded_total));
else
{
- emit_insn (gen_movsi (final_src, bytes_rtx));
+ emit_insn (gen_movsi (final_src, rounded_total));
emit_insn (gen_addsi3 (final_src, final_src, src_reg));
}
@@ -2338,7 +2384,7 @@ m32r_expand_block_move (operands)
to the word after the end of the source block, and dst_reg to point
to the last word of the destination block, provided that the block
is MAX_MOVE_BYTES long. */
- emit_insn (gen_movstrsi_internal (dst_reg, src_reg, bytes_rtx));
+ emit_insn (gen_movstrsi_internal (dst_reg, src_reg, at_a_time));
emit_insn (gen_addsi3 (dst_reg, dst_reg, GEN_INT (4)));
if (bytes > MAX_MOVE_BYTES)
@@ -2424,7 +2470,13 @@ m32r_output_block_move (insn, operands)
/* Get the entire next word, even though we do not want all of it.
The saves us from doing several smaller loads, and we assume that
we cannot cause a page fault when at least part of the word is in
- valid memory. If got_extra is true then we have already loaded
+ valid memory [since we don't get called if things aren't properly
+ aligned]. */
+ int dst_offset = first_time ? 0 : 4;
+ int last_shift;
+ rtx my_operands[3];
+
+ /* If got_extra is true then we have already loaded
the next word as part of loading and storing the previous word. */
if (! got_extra)
output_asm_insn ("ld\t%4, @%1", operands);
@@ -2433,21 +2485,36 @@ m32r_output_block_move (insn, operands)
{
bytes -= 2;
- output_asm_insn ("sth\t%4, @%0", operands);
+ output_asm_insn ("sra3\t%3, %4, #16", operands);
+ my_operands[0] = operands[3];
+ my_operands[1] = GEN_INT (dst_offset);
+ my_operands[2] = operands[0];
+ output_asm_insn ("sth\t%0, @(%1,%2)", my_operands);
/* If there is a byte left to store then increment the
destination address and shift the contents of the source
- register down by 16 bits. We could not do the address
+ register down by 8 bits. We could not do the address
increment in the store half word instruction, because it does
not have an auto increment mode. */
if (bytes > 0) /* assert (bytes == 1) */
{
- output_asm_insn ("srai\t%4, #16", operands);
- output_asm_insn ("addi\t%0, #2", operands);
+ dst_offset += 2;
+ last_shift = 8;
}
}
-
- output_asm_insn ("stb\t%4, @%0", operands);
+ else
+ last_shift = 24;
+
+ if (bytes > 0)
+ {
+ my_operands[0] = operands[4];
+ my_operands[1] = GEN_INT (last_shift);
+ output_asm_insn ("srai\t%0, #%1", my_operands);
+ my_operands[0] = operands[4];
+ my_operands[1] = GEN_INT (dst_offset);
+ my_operands[2] = operands[0];
+ output_asm_insn ("stb\t%0, @(%1,%2)", my_operands);
+ }
bytes = 0;
}
diff --git a/gcc/config/m32r/m32r.h b/gcc/config/m32r/m32r.h
index 382f66ef978..425b83cb20b 100644
--- a/gcc/config/m32r/m32r.h
+++ b/gcc/config/m32r/m32r.h
@@ -1126,9 +1126,9 @@ do { \
/* We have post-inc load and pre-dec,pre-inc store,
but only for 4 byte vals. */
#if 0
-#define HAVE_PRE_DECREMENT
-#define HAVE_PRE_INCREMENT
-#define HAVE_POST_INCREMENT
+#define HAVE_PRE_DECREMENT 1
+#define HAVE_PRE_INCREMENT 1
+#define HAVE_POST_INCREMENT 1
#endif
/* Recognize any constant value that is a valid address. */
@@ -1660,7 +1660,7 @@ do { \
do { \
char * real_name; \
STRIP_NAME_ENCODING (real_name, (NAME)); \
- fprintf (FILE, "%s%s", USER_LABEL_PREFIX, real_name); \
+ asm_fprintf (FILE, "%U%s", real_name); \
} while (0)
/* If -Os, don't force line number labels to begin at the beginning of
@@ -2077,9 +2077,6 @@ extern int conditional_move_operand PROTO((Rtx, int));
extern int carry_compare_operand PROTO((Rtx, int));
extern char *emit_cond_move PROTO((Rtx *, Rtx));
-/* Needed by a peephole optimisation. */
-#define PRESERVE_DEATH_INFO_REGNO_P(regno) (regno < FIRST_PSEUDO_REGISTER)
-
extern char * m32r_output_block_move PROTO((Rtx, Rtx *));
extern int m32r_block_immediate_operand PROTO((Rtx, int));
extern void m32r_expand_block_move PROTO((Rtx *));
diff --git a/gcc/config/m32r/m32r.md b/gcc/config/m32r/m32r.md
index e1638903ad6..3f1e6e51f71 100644
--- a/gcc/config/m32r/m32r.md
+++ b/gcc/config/m32r/m32r.md
@@ -434,8 +434,9 @@
}
}
- /* Can't use any two byte insn, fall back to seth/or3. */
- operands[2] = GEN_INT ((val) & 0xffff0000);
+ /* Can't use any two byte insn, fall back to seth/or3. Use ~0xffff instead
+ of 0xffff0000, since the later fails on a 64-bit host. */
+ operands[2] = GEN_INT ((val) & ~0xffff);
operands[3] = GEN_INT ((val) & 0xffff);
}")
@@ -588,14 +589,8 @@
[(set (match_dup 2) (match_dup 3))]
"
{
- long l;
- REAL_VALUE_TYPE rv;
-
- REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
- REAL_VALUE_TO_TARGET_SINGLE (rv, l);
-
operands[2] = operand_subword (operands[0], 0, 0, SFmode);
- operands[3] = GEN_INT (l);
+ operands[3] = operand_subword (operands[1], 0, 0, SFmode);
}")
(define_expand "movdf"
@@ -1787,10 +1782,10 @@
[(set (mem:BLK (match_operand:SI 0 "register_operand" "r")) ;; destination
(mem:BLK (match_operand:SI 1 "register_operand" "r"))) ;; source
(use (match_operand:SI 2 "m32r_block_immediate_operand" "J"));; # bytes to move
+ (set (match_dup 0) (plus:SI (match_dup 0) (minus:SI (match_dup 2) (const_int 4))))
+ (set (match_dup 1) (plus:SI (match_dup 1) (match_dup 2)))
(clobber (match_scratch:SI 3 "=&r")) ;; temp 1
- (clobber (match_scratch:SI 4 "=&r")) ;; temp 2
- (clobber (match_dup 0))
- (clobber (match_dup 1))]
+ (clobber (match_scratch:SI 4 "=&r"))] ;; temp 2
""
"* return m32r_output_block_move (insn, operands);"
[(set_attr "type" "store8")
diff --git a/gcc/config/m68k/lb1sf68.asm b/gcc/config/m68k/lb1sf68.asm
index 9e33ccb4b2f..ef40a340763 100644
--- a/gcc/config/m68k/lb1sf68.asm
+++ b/gcc/config/m68k/lb1sf68.asm
@@ -382,9 +382,9 @@ L1: addl d0,d0 | shift reg pair (p,a) one bit left
addxl d2,d2
movl d2,d3 | subtract b from p, store in tmp.
subl d1,d3
- jmi L2 | if the result is not is negative, set the
- bset IMM (0),d0 | low order bit of a to 1 and store tmp in p.
- movl d3,d2
+ jcs L2 | if no carry,
+ bset IMM (0),d0 | set the low order bit of a to 1,
+ movl d3,d2 | and store tmp in p.
L2: subql IMM (1),d4
jcc L1
moveml sp@,d2-d4 | restore data registers
diff --git a/gcc/config/m68k/m68k.c b/gcc/config/m68k/m68k.c
index 9303c6f2b76..344f9b659cb 100644
--- a/gcc/config/m68k/m68k.c
+++ b/gcc/config/m68k/m68k.c
@@ -1,5 +1,5 @@
/* Subroutines for insn-output.c for Motorola 68000 family.
- Copyright (C) 1987, 93, 94, 95, 96, 97, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1987, 93-98, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -58,11 +58,11 @@ rtx legitimize_pic_address ();
/* Alignment to use for loops and jumps */
/* Specify power of two alignment used for loops. */
-char *m68k_align_loops_string;
+const char *m68k_align_loops_string;
/* Specify power of two alignment used for non-loop jumps. */
-char *m68k_align_jumps_string;
+const char *m68k_align_jumps_string;
/* Specify power of two alignment used for functions. */
-char *m68k_align_funcs_string;
+const char *m68k_align_funcs_string;
/* Specify power of two alignment used for loops. */
int m68k_align_loops;
@@ -3176,7 +3176,19 @@ print_operand_address (file, addr)
}
else
{
- output_addr_const (file, addr);
+ /* Special case for SYMBOL_REF if the symbol name ends in
+ `.<letter>', this can be mistaken as a size suffix. Put
+ the name in parentheses. */
+ if (GET_CODE (addr) == SYMBOL_REF
+ && strlen (XSTR (addr, 0)) > 2
+ && XSTR (addr, 0)[strlen (XSTR (addr, 0)) - 2] == '.')
+ {
+ putc ('(', file);
+ output_addr_const (file, addr);
+ putc (')', file);
+ }
+ else
+ output_addr_const (file, addr);
}
break;
}
@@ -3250,8 +3262,6 @@ const_uint32_operand (op, mode)
rtx op;
enum machine_mode mode ATTRIBUTE_UNUSED;
{
- if (GET_CODE (op) == CONSTANT_P_RTX)
- return 1;
#if HOST_BITS_PER_WIDE_INT > 32
/* All allowed constants will fit a CONST_INT. */
return (GET_CODE (op) == CONST_INT
@@ -3271,8 +3281,6 @@ const_sint32_operand (op, mode)
rtx op;
enum machine_mode mode ATTRIBUTE_UNUSED;
{
- if (GET_CODE (op) == CONSTANT_P_RTX)
- return 1;
/* All allowed constants will fit a CONST_INT. */
return (GET_CODE (op) == CONST_INT
&& (INTVAL (op) >= (-0x7fffffff - 1) && INTVAL (op) <= 0x7fffffff));
diff --git a/gcc/config/m68k/m68k.h b/gcc/config/m68k/m68k.h
index a4bfef9a638..268b639d8b7 100644
--- a/gcc/config/m68k/m68k.h
+++ b/gcc/config/m68k/m68k.h
@@ -1,5 +1,5 @@
/* Definitions of target machine for GNU compiler. Sun 68000/68020 version.
- Copyright (C) 1987, 88, 93-97, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1987, 88, 93-98, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -471,11 +471,12 @@ extern int target_flags;
#define HARD_REGNO_MODE_OK(REGNO, MODE) \
(((REGNO) < 16 \
- && !((REGNO) < 8 && (REGNO) + GET_MODE_SIZE ((MODE)) / 4 > 8)) \
- || ((REGNO) < 24 \
+ && !((REGNO) < 8 && (REGNO) + GET_MODE_SIZE (MODE) / 4 > 8)) \
+ || ((REGNO) >= 16 && (REGNO) < 24 \
&& TARGET_68881 \
&& (GET_MODE_CLASS (MODE) == MODE_FLOAT \
- || GET_MODE_CLASS (MODE) == MODE_COMPLEX_FLOAT)))
+ || GET_MODE_CLASS (MODE) == MODE_COMPLEX_FLOAT) \
+ && GET_MODE_UNIT_SIZE (MODE) <= 12))
#else /* defined SUPPORT_SUN_FPA */
@@ -486,6 +487,11 @@ extern int target_flags;
(apparently) hold whatever you feel like putting in them.
If using the fpa, don't put a double in d7/a0. */
+/* ??? This is confused. The check to prohibit d7/a0 overlaps should always
+ be enabled regardless of whether TARGET_FPA is specified. It isn't clear
+ what the other d/a register checks are for. Every check using REGNO
+ actually needs to use a range, e.g. 24>=X<56 not <56. There is probably
+ no one using this code anymore. */
#define HARD_REGNO_MODE_OK(REGNO, MODE) \
(((REGNO) < 16 \
&& !(TARGET_FPA \
@@ -494,9 +500,11 @@ extern int target_flags;
&& (REGNO) < 8 && (REGNO) + GET_MODE_SIZE ((MODE)) / 4 > 8 \
&& (REGNO) % (GET_MODE_UNIT_SIZE ((MODE)) / 4) != 0)) \
|| ((REGNO) < 24 \
- ? TARGET_68881 && (GET_MODE_CLASS (MODE) == MODE_FLOAT \
- || GET_MODE_CLASS (MODE) == MODE_COMPLEX_FLOAT) \
- : ((REGNO) < 56 ? TARGET_FPA : 0)))
+ ? (TARGET_68881 \
+ && (GET_MODE_CLASS (MODE) == MODE_FLOAT \
+ || GET_MODE_CLASS (MODE) == MODE_COMPLEX_FLOAT) \
+ && GET_MODE_UNIT_SIZE (MODE) <= 12) \
+ : ((REGNO) < 56 ? TARGET_FPA && GET_MODE_UNIT_SIZE (MODE) <= 8 : 0)))
#endif /* defined SUPPORT_SUN_FPA */
@@ -1273,11 +1281,11 @@ __transfer_from_trampoline () \
/* Addressing modes, and classification of registers for them. */
-#define HAVE_POST_INCREMENT
-/* #define HAVE_POST_DECREMENT */
+#define HAVE_POST_INCREMENT 1
+/* #define HAVE_POST_DECREMENT 0 */
-#define HAVE_PRE_DECREMENT
-/* #define HAVE_PRE_INCREMENT */
+#define HAVE_PRE_DECREMENT 1
+/* #define HAVE_PRE_INCREMENT 0 */
/* Macros to check register numbers against specific register classes. */
@@ -1418,21 +1426,13 @@ __transfer_from_trampoline () \
|| (GET_CODE (X) == PLUS \
&& LEGITIMATE_BASE_REG_P (XEXP (X, 0)) \
&& GET_CODE (XEXP (X, 1)) == CONST_INT \
- && (TARGET_68020 || (unsigned) INTVAL (XEXP (X, 1)) + 0x8000) < 0x10000) \
+ && (TARGET_68020 \
+ || ((unsigned) INTVAL (XEXP (X, 1)) + 0x8000) < 0x10000)) \
|| (GET_CODE (X) == PLUS && XEXP (X, 0) == pic_offset_table_rtx \
&& flag_pic && GET_CODE (XEXP (X, 1)) == SYMBOL_REF) \
|| (GET_CODE (X) == PLUS && XEXP (X, 0) == pic_offset_table_rtx \
&& flag_pic && GET_CODE (XEXP (X, 1)) == LABEL_REF)) \
-#if 0
-/* This should replace the last two (non-pic) lines
- except that Sun's assembler does not seem to handle such operands. */
- && (TARGET_68020 ? CONSTANT_ADDRESS_P (XEXP (X, 1)) \
- : (GET_CODE (XEXP (X, 1)) == CONST_INT \
- && ((unsigned) INTVAL (XEXP (X, 1)) + 0x8000) < 0x10000))))
-#endif
-
-
#define GO_IF_NONINDEXED_ADDRESS(X, ADDR) \
{ if (INDIRECTABLE_1_ADDRESS_P (X)) goto ADDR; }
@@ -1463,9 +1463,11 @@ __transfer_from_trampoline () \
&& (TARGET_68020 || (unsigned) INTVAL (XEXP (X, 0)) + 0x80 < 0x100)) \
{ rtx go_temp = XEXP (X, 1); GO_IF_INDEXING (go_temp, ADDR); } } }
+/* coldfire/5200 does not allow HImode index registers. */
#define LEGITIMATE_INDEX_REG_P(X) \
((GET_CODE (X) == REG && REG_OK_FOR_INDEX_P (X)) \
- || (GET_CODE (X) == SIGN_EXTEND \
+ || (! TARGET_5200 \
+ && GET_CODE (X) == SIGN_EXTEND \
&& GET_CODE (XEXP (X, 0)) == REG \
&& GET_MODE (XEXP (X, 0)) == HImode \
&& REG_OK_FOR_INDEX_P (XEXP (X, 0))) \
@@ -2107,9 +2109,9 @@ extern int flags_in_68881 ();
extern int strict_low_part_peephole_ok ();
/* Variables in m68k.c */
-extern char *m68k_align_loops_string;
-extern char *m68k_align_jumps_string;
-extern char *m68k_align_funcs_string;
+extern const char *m68k_align_loops_string;
+extern const char *m68k_align_jumps_string;
+extern const char *m68k_align_funcs_string;
extern int m68k_align_loops;
extern int m68k_align_jumps;
extern int m68k_align_funcs;
@@ -2121,6 +2123,7 @@ extern int const_int_cost ();
extern int standard_68881_constant_p ();
extern int standard_sun_fpa_constant_p ();
extern void output_function_prologue ();
+extern void output_function_epilogue ();
extern int use_return_insn ();
extern void print_operand_address ();
extern void print_operand ();
diff --git a/gcc/config/m68k/m68k.md b/gcc/config/m68k/m68k.md
index dfe0cbc313e..236bd9a0062 100644
--- a/gcc/config/m68k/m68k.md
+++ b/gcc/config/m68k/m68k.md
@@ -1,5 +1,5 @@
;;- Machine description for GNU compiler, Motorola 68000 Version
-;; Copyright (C) 1987, 88, 93-97, 1998 Free Software Foundation, Inc.
+;; Copyright (C) 1987, 88, 93-98, 1999 Free Software Foundation, Inc.
;; This file is part of GNU CC.
@@ -1224,8 +1224,8 @@
}")
(define_insn ""
- [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,!r,!f")
- (match_operand:XF 1 "nonimmediate_operand" "m,f,f,f,r"))]
+ [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,!r,!f,!r")
+ (match_operand:XF 1 "nonimmediate_operand" "m,f,f,f,r,!r"))]
"TARGET_68881"
"*
{
@@ -1247,15 +1247,20 @@
return \"fmove%.x %1,%0\";
return \"fmove%.x %f1,%0\";
}
- if (REG_P (operands[0]))
+ if (FP_REG_P (operands[1]))
{
- output_asm_insn (\"fmove%.x %f1,%-\;move%.l %+,%0\", operands);
- operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
- output_asm_insn (\"move%.l %+,%0\", operands);
- operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
- return \"move%.l %+,%0\";
+ if (REG_P (operands[0]))
+ {
+ output_asm_insn (\"fmove%.x %f1,%-\;move%.l %+,%0\", operands);
+ operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
+ output_asm_insn (\"move%.l %+,%0\", operands);
+ operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
+ return \"move%.l %+,%0\";
+ }
+ /* Must be memory destination. */
+ return \"fmove%.x %f1,%0\";
}
- return \"fmove%.x %f1,%0\";
+ return output_move_double (operands);
}
")
@@ -1670,8 +1675,7 @@
(define_insn "extendqidi2"
[(set (match_operand:DI 0 "general_operand" "=d")
- (sign_extend:DI
- (match_operand:QI 1 "general_operand" "rm")))]
+ (sign_extend:DI (match_operand:QI 1 "general_operand" "dm")))]
""
"*
{
@@ -2099,7 +2103,7 @@
;; (plus:DI (match_operand:DI 2 "general_operand" "%0")
;; (lshiftrt:DI (match_operand:DI 1 "general_operand" "ro")
;; (const_int 32))))]
- (plus:DI (lshiftrt:DI (match_operand:DI 1 "general_operand" "o,r")
+ (plus:DI (lshiftrt:DI (match_operand:DI 1 "general_operand" "ro,r")
(const_int 32))
(match_operand:DI 2 "general_operand" "0,0")))]
""
@@ -2118,7 +2122,7 @@
;; (plus:DI (match_operand:DI 2 "general_operand" "%0")
;; (ashift:DI (match_operand:DI 1 "general_operand" "ro")
;; (const_int 32))))]
- (plus:DI (ashift:DI (match_operand:DI 1 "general_operand" "o,r")
+ (plus:DI (ashift:DI (match_operand:DI 1 "general_operand" "ro,r")
(const_int 32))
(match_operand:DI 2 "general_operand" "0,0")))]
""
@@ -4558,9 +4562,10 @@
[(set (match_operand:DI 0 "general_operand" "=d")
(ashift:DI (match_operand:DI 1 "general_operand" "0")
(match_operand 2 "const_int_operand" "n")))]
- "((INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 3)
- || INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16
- || (INTVAL (operands[2]) > 32 && INTVAL (operands[2]) <= 63))"
+ "(!TARGET_5200
+ && ((INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 3)
+ || INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16
+ || (INTVAL (operands[2]) > 32 && INTVAL (operands[2]) <= 63)))"
"*
{
operands[1] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
@@ -4589,13 +4594,15 @@
[(set (match_operand:DI 0 "general_operand" "")
(ashift:DI (match_operand:DI 1 "general_operand" "")
(match_operand 2 "const_int_operand" "")))]
- ""
+ "!TARGET_5200"
"
{
+ /* ??? This is a named pattern like this is not allowed to FAIL based
+ on its operands. */
if (GET_CODE (operands[2]) != CONST_INT
- || ((INTVAL (operands[2]) < 1 || INTVAL (operands[2]) > 3)
- && INTVAL (operands[2]) != 8 && INTVAL (operands[2]) != 16
- && (INTVAL (operands[2]) < 32 || INTVAL (operands[2]) > 63)))
+ || ((INTVAL (operands[2]) < 1 || INTVAL (operands[2]) > 3)
+ && INTVAL (operands[2]) != 8 && INTVAL (operands[2]) != 16
+ && (INTVAL (operands[2]) < 32 || INTVAL (operands[2]) > 63)))
FAIL;
} ")
@@ -4758,11 +4765,11 @@
[(set (match_operand:DI 0 "general_operand" "=d")
(ashiftrt:DI (match_operand:DI 1 "general_operand" "0")
(match_operand 2 "const_int_operand" "n")))]
- "!TARGET_5200
+ "(!TARGET_5200
&& ((INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 3)
- || INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16
- || INTVAL (operands[2]) == 31
- || (INTVAL (operands[2]) > 32 && INTVAL (operands[2]) <= 63))"
+ || INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16
+ || INTVAL (operands[2]) == 31
+ || (INTVAL (operands[2]) > 32 && INTVAL (operands[2]) <= 63)))"
"*
{
operands[1] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
@@ -4801,10 +4808,12 @@
"!TARGET_5200"
"
{
+ /* ??? This is a named pattern like this is not allowed to FAIL based
+ on its operands. */
if (GET_CODE (operands[2]) != CONST_INT
- || ((INTVAL (operands[2]) < 1 || INTVAL (operands[2]) > 3)
- && INTVAL (operands[2]) != 8 && INTVAL (operands[2]) != 16
- && (INTVAL (operands[2]) < 31 || INTVAL (operands[2]) > 63)))
+ || ((INTVAL (operands[2]) < 1 || INTVAL (operands[2]) > 3)
+ && INTVAL (operands[2]) != 8 && INTVAL (operands[2]) != 16
+ && (INTVAL (operands[2]) < 31 || INTVAL (operands[2]) > 63)))
FAIL;
} ")
@@ -4929,10 +4938,10 @@
[(set (match_operand:DI 0 "general_operand" "=d")
(lshiftrt:DI (match_operand:DI 1 "general_operand" "0")
(match_operand 2 "const_int_operand" "n")))]
- "!TARGET_5200
+ "(!TARGET_5200
&& ((INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 3)
- || INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16
- || (INTVAL (operands[2]) > 32 && INTVAL (operands[2]) <= 63))"
+ || INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16
+ || (INTVAL (operands[2]) > 32 && INTVAL (operands[2]) <= 63)))"
"*
{
operands[1] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
@@ -4967,10 +4976,12 @@
"!TARGET_5200"
"
{
+ /* ??? This is a named pattern like this is not allowed to FAIL based
+ on its operands. */
if (GET_CODE (operands[2]) != CONST_INT
- || ((INTVAL (operands[2]) < 1 || INTVAL (operands[2]) > 3)
- && INTVAL (operands[2]) != 8 && INTVAL (operands[2]) != 16
- && (INTVAL (operands[2]) < 32 || INTVAL (operands[2]) > 63)))
+ || ((INTVAL (operands[2]) < 1 || INTVAL (operands[2]) > 3)
+ && INTVAL (operands[2]) != 8 && INTVAL (operands[2]) != 16
+ && (INTVAL (operands[2]) < 32 || INTVAL (operands[2]) > 63)))
FAIL;
} ")
@@ -5663,8 +5674,12 @@
return output_scc_di (operands[1], operands[2], operands[3], operands[0]);
} ")
+;; Note that operand 0 of an SCC insn is supported in the hardware as
+;; memory, but we cannot allow it to be in memory in case the address
+;; needs to be reloaded.
+
(define_expand "seq"
- [(set (match_operand:QI 0 "general_operand" "")
+ [(set (match_operand:QI 0 "register_operand" "")
(eq:QI (cc0) (const_int 0)))]
""
"
@@ -5677,25 +5692,16 @@
}")
(define_insn ""
- [(set (match_operand:QI 0 "general_operand" "=dm")
- (eq:QI (cc0) (const_int 0)))]
- "! TARGET_5200"
- "*
- cc_status = cc_prev_status;
- OUTPUT_JUMP (\"seq %0\", \"fseq %0\", \"seq %0\");
-")
-
-(define_insn ""
- [(set (match_operand:QI 0 "general_operand" "=d")
+ [(set (match_operand:QI 0 "register_operand" "=d")
(eq:QI (cc0) (const_int 0)))]
- "TARGET_5200"
+ ""
"*
cc_status = cc_prev_status;
OUTPUT_JUMP (\"seq %0\", \"fseq %0\", \"seq %0\");
")
(define_expand "sne"
- [(set (match_operand:QI 0 "general_operand" "")
+ [(set (match_operand:QI 0 "register_operand" "")
(ne:QI (cc0) (const_int 0)))]
""
"
@@ -5708,25 +5714,16 @@
}")
(define_insn ""
- [(set (match_operand:QI 0 "general_operand" "=dm")
- (ne:QI (cc0) (const_int 0)))]
- "! TARGET_5200"
- "*
- cc_status = cc_prev_status;
- OUTPUT_JUMP (\"sne %0\", \"fsne %0\", \"sne %0\");
-")
-
-(define_insn ""
- [(set (match_operand:QI 0 "general_operand" "=d")
+ [(set (match_operand:QI 0 "register_operand" "=d")
(ne:QI (cc0) (const_int 0)))]
- "TARGET_5200"
+ ""
"*
cc_status = cc_prev_status;
OUTPUT_JUMP (\"sne %0\", \"fsne %0\", \"sne %0\");
")
(define_expand "sgt"
- [(set (match_operand:QI 0 "general_operand" "")
+ [(set (match_operand:QI 0 "register_operand" "")
(gt:QI (cc0) (const_int 0)))]
""
"
@@ -5739,45 +5736,30 @@
}")
(define_insn ""
- [(set (match_operand:QI 0 "general_operand" "=dm")
- (gt:QI (cc0) (const_int 0)))]
- "! TARGET_5200"
- "*
- cc_status = cc_prev_status;
- OUTPUT_JUMP (\"sgt %0\", \"fsgt %0\", 0);
-")
-
-(define_insn ""
- [(set (match_operand:QI 0 "general_operand" "=d")
+ [(set (match_operand:QI 0 "register_operand" "=d")
(gt:QI (cc0) (const_int 0)))]
- "TARGET_5200"
+ ""
"*
cc_status = cc_prev_status;
OUTPUT_JUMP (\"sgt %0\", \"fsgt %0\", 0);
")
(define_expand "sgtu"
- [(set (match_operand:QI 0 "general_operand" "")
+ [(set (match_operand:QI 0 "register_operand" "")
(gtu:QI (cc0) (const_int 0)))]
""
"")
(define_insn ""
- [(set (match_operand:QI 0 "general_operand" "=dm")
- (gtu:QI (cc0) (const_int 0)))]
- "! TARGET_5200"
- "* cc_status = cc_prev_status;
- return \"shi %0\"; ")
-
-(define_insn ""
- [(set (match_operand:QI 0 "general_operand" "=d")
+ [(set (match_operand:QI 0 "register_operand" "=d")
(gtu:QI (cc0) (const_int 0)))]
- "TARGET_5200"
- "* cc_status = cc_prev_status;
- return \"shi %0\"; ")
+ ""
+ "*
+ cc_status = cc_prev_status;
+ return \"shi %0\"; ")
(define_expand "slt"
- [(set (match_operand:QI 0 "general_operand" "")
+ [(set (match_operand:QI 0 "register_operand" "")
(lt:QI (cc0) (const_int 0)))]
""
"
@@ -5790,41 +5772,29 @@
}")
(define_insn ""
- [(set (match_operand:QI 0 "general_operand" "=dm")
- (lt:QI (cc0) (const_int 0)))]
- "! TARGET_5200"
- "* cc_status = cc_prev_status;
- OUTPUT_JUMP (\"slt %0\", \"fslt %0\", \"smi %0\"); ")
-
-(define_insn ""
- [(set (match_operand:QI 0 "general_operand" "=d")
+ [(set (match_operand:QI 0 "register_operand" "=d")
(lt:QI (cc0) (const_int 0)))]
- "TARGET_5200"
- "* cc_status = cc_prev_status;
- OUTPUT_JUMP (\"slt %0\", \"fslt %0\", \"smi %0\"); ")
+ ""
+ "*
+ cc_status = cc_prev_status;
+ OUTPUT_JUMP (\"slt %0\", \"fslt %0\", \"smi %0\"); ")
(define_expand "sltu"
- [(set (match_operand:QI 0 "general_operand" "")
+ [(set (match_operand:QI 0 "register_operand" "")
(ltu:QI (cc0) (const_int 0)))]
""
"")
(define_insn ""
- [(set (match_operand:QI 0 "general_operand" "=dm")
- (ltu:QI (cc0) (const_int 0)))]
- "! TARGET_5200"
- "* cc_status = cc_prev_status;
- return \"scs %0\"; ")
-
-(define_insn ""
- [(set (match_operand:QI 0 "general_operand" "=d")
+ [(set (match_operand:QI 0 "register_operand" "=d")
(ltu:QI (cc0) (const_int 0)))]
- "TARGET_5200"
- "* cc_status = cc_prev_status;
- return \"scs %0\"; ")
+ ""
+ "*
+ cc_status = cc_prev_status;
+ return \"scs %0\"; ")
(define_expand "sge"
- [(set (match_operand:QI 0 "general_operand" "")
+ [(set (match_operand:QI 0 "register_operand" "")
(ge:QI (cc0) (const_int 0)))]
""
"
@@ -5837,41 +5807,29 @@
}")
(define_insn ""
- [(set (match_operand:QI 0 "general_operand" "=dm")
- (ge:QI (cc0) (const_int 0)))]
- "! TARGET_5200"
- "* cc_status = cc_prev_status;
- OUTPUT_JUMP (\"sge %0\", \"fsge %0\", \"spl %0\"); ")
-
-(define_insn ""
- [(set (match_operand:QI 0 "general_operand" "=d")
+ [(set (match_operand:QI 0 "register_operand" "=d")
(ge:QI (cc0) (const_int 0)))]
- "TARGET_5200"
- "* cc_status = cc_prev_status;
- OUTPUT_JUMP (\"sge %0\", \"fsge %0\", \"spl %0\"); ")
+ ""
+ "*
+ cc_status = cc_prev_status;
+ OUTPUT_JUMP (\"sge %0\", \"fsge %0\", \"spl %0\"); ")
(define_expand "sgeu"
- [(set (match_operand:QI 0 "general_operand" "")
+ [(set (match_operand:QI 0 "register_operand" "")
(geu:QI (cc0) (const_int 0)))]
""
"")
(define_insn ""
- [(set (match_operand:QI 0 "general_operand" "=dm")
- (geu:QI (cc0) (const_int 0)))]
- "! TARGET_5200"
- "* cc_status = cc_prev_status;
- return \"scc %0\"; ")
-
-(define_insn ""
- [(set (match_operand:QI 0 "general_operand" "=d")
+ [(set (match_operand:QI 0 "register_operand" "=d")
(geu:QI (cc0) (const_int 0)))]
- "TARGET_5200"
- "* cc_status = cc_prev_status;
- return \"scc %0\"; ")
+ ""
+ "*
+ cc_status = cc_prev_status;
+ return \"scc %0\"; ")
(define_expand "sle"
- [(set (match_operand:QI 0 "general_operand" "")
+ [(set (match_operand:QI 0 "register_operand" "")
(le:QI (cc0) (const_int 0)))]
""
"
@@ -5884,42 +5842,27 @@
}")
(define_insn ""
- [(set (match_operand:QI 0 "general_operand" "=dm")
- (le:QI (cc0) (const_int 0)))]
- "! TARGET_5200"
- "*
- cc_status = cc_prev_status;
- OUTPUT_JUMP (\"sle %0\", \"fsle %0\", 0);
-")
-
-(define_insn ""
- [(set (match_operand:QI 0 "general_operand" "=d")
+ [(set (match_operand:QI 0 "register_operand" "=d")
(le:QI (cc0) (const_int 0)))]
- "TARGET_5200"
+ ""
"*
cc_status = cc_prev_status;
OUTPUT_JUMP (\"sle %0\", \"fsle %0\", 0);
")
(define_expand "sleu"
- [(set (match_operand:QI 0 "general_operand" "")
+ [(set (match_operand:QI 0 "register_operand" "")
(leu:QI (cc0) (const_int 0)))]
""
"")
(define_insn ""
- [(set (match_operand:QI 0 "general_operand" "=dm")
- (leu:QI (cc0) (const_int 0)))]
- "! TARGET_5200"
- "* cc_status = cc_prev_status;
- return \"sls %0\"; ")
-
-(define_insn ""
- [(set (match_operand:QI 0 "general_operand" "=d")
+ [(set (match_operand:QI 0 "register_operand" "=d")
(leu:QI (cc0) (const_int 0)))]
- "TARGET_5200"
- "* cc_status = cc_prev_status;
- return \"sls %0\"; ")
+ ""
+ "*
+ cc_status = cc_prev_status;
+ return \"sls %0\"; ")
;; Basic conditional jump instructions.
@@ -7492,7 +7435,7 @@
(define_insn "extendsfxf2"
[(set (match_operand:XF 0 "general_operand" "=fm,f")
- (float_extend:XF (match_operand:SF 1 "general_operand" "f,m")))]
+ (float_extend:XF (match_operand:SF 1 "general_operand" "f,rmF")))]
"TARGET_68881"
"*
{
@@ -7509,7 +7452,15 @@
return \"f%$move%.x %1,%0\";
}
if (FP_REG_P (operands[0]))
- return \"f%$move%.s %f1,%0\";
+ {
+ if (FP_REG_P (operands[1]))
+ return \"f%$move%.x %1,%0\";
+ else if (ADDRESS_REG_P (operands[1]))
+ return \"move%.l %1,%-\;f%$move%.s %+,%0\";
+ else if (GET_CODE (operands[1]) == CONST_DOUBLE)
+ return output_move_const_single (operands);
+ return \"f%$move%.s %f1,%0\";
+ }
return \"fmove%.x %f1,%0\";
}")
@@ -7517,7 +7468,7 @@
(define_insn "extenddfxf2"
[(set (match_operand:XF 0 "general_operand" "=fm,f")
(float_extend:XF
- (match_operand:DF 1 "general_operand" "f,m")))]
+ (match_operand:DF 1 "general_operand" "f,rmE")))]
"TARGET_68881"
"*
{
@@ -7534,7 +7485,19 @@
return \"fmove%.x %1,%0\";
}
if (FP_REG_P (operands[0]))
- return \"f%&move%.d %f1,%0\";
+ {
+ if (REG_P (operands[1]))
+ {
+ rtx xoperands[2];
+ xoperands[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
+ output_asm_insn (\"move%.l %1,%-\", xoperands);
+ output_asm_insn (\"move%.l %1,%-\", operands);
+ return \"f%&move%.d %+,%0\";
+ }
+ if (GET_CODE (operands[1]) == CONST_DOUBLE)
+ return output_move_const_double (operands);
+ return \"f%&move%.d %f1,%0\";
+ }
return \"fmove%.x %f1,%0\";
}")
diff --git a/gcc/config/m68k/mot3300-crt0.S b/gcc/config/m68k/mot3300-crt0.S
index 3c1648fe053..4221aede169 100644
--- a/gcc/config/m68k/mot3300-crt0.S
+++ b/gcc/config/m68k/mot3300-crt0.S
@@ -93,6 +93,6 @@ __stop_monitor:
COMM splimit%,4
COMM environ,4
- IDENT ("$Id: mot3300-crt0.S,v 1.2 1997/12/22 23:41:12 kenner Exp $")
+ IDENT ("$Id: mot3300-crt0.S,v 1.2 1998/12/16 21:07:03 law Exp $")
IDENT ("Contributed by Manfred Hollstein (manfred@lts.sel.alcatel.de)")
IDENT ("Corrections by Philippe De Muyter (phdm@macqel.be)")
diff --git a/gcc/config/m68k/mot3300.h b/gcc/config/m68k/mot3300.h
index e1b40600808..e6eadd1216a 100644
--- a/gcc/config/m68k/mot3300.h
+++ b/gcc/config/m68k/mot3300.h
@@ -1,6 +1,6 @@
/* Definitions of target machine for GNU compiler,
SysV68 Motorola 3300 Delta Series.
- Copyright (C) 1987, 93, 94, 95, 96, 1997 Free Software Foundation, Inc.
+ Copyright (C) 1987, 93, 94, 95, 96, 1997, 1998, 1999 Free Software Foundation, Inc.
Contributed by Abramo and Roberto Bagnara (bagnara@dipisa.di.unipi.it)
based on Alex Crain's 3B1 definitions.
Maintained by Philippe De Muyter (phdm@info.ucl.ac.be).
@@ -97,6 +97,10 @@ Boston, MA 02111-1307, USA. */
#define SIZE_TYPE "unsigned int"
+/* We need POSIX/XOPEN symbols; otherwise building libio will fail. */
+#define ADD_MISSING_POSIX 1
+#define ADD_MISSING_XOPEN 1
+
/* Every structure or union's size must be a multiple of 2 bytes. */
#define STRUCTURE_SIZE_BOUNDARY 16
diff --git a/gcc/config/m68k/mot3300Mcrt0.S b/gcc/config/m68k/mot3300Mcrt0.S
index 3ef6611630c..0faf9e5ab9e 100644
--- a/gcc/config/m68k/mot3300Mcrt0.S
+++ b/gcc/config/m68k/mot3300Mcrt0.S
@@ -137,6 +137,6 @@ LOCAL_LABEL(endofstart):
COMM environ,4
COMM _countbase,4
- IDENT ("$Id: mot3300Mcrt0.S,v 1.2 1997/12/22 23:39:48 kenner Exp $")
+ IDENT ("$Id: mot3300Mcrt0.S,v 1.2 1998/12/16 21:07:05 law Exp $")
IDENT ("Contributed by Manfred Hollstein (manfred@lts.sel.alcatel.de)")
IDENT ("Corrections by Philippe De Muyter (phdm@macqel.be)")
diff --git a/gcc/config/m68k/vxm68k.h b/gcc/config/m68k/vxm68k.h
index 063ded86a63..86884db9719 100644
--- a/gcc/config/m68k/vxm68k.h
+++ b/gcc/config/m68k/vxm68k.h
@@ -1,5 +1,5 @@
/* Definitions of target machine for GNU compiler. Vxworks m68k version.
- Copyright (C) 1994, 1996, 1997 Free Software Foundation, Inc.
+ Copyright (C) 1994, 1996, 1997, 1998 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -82,9 +82,9 @@ Unrecognized value in TARGET_CPU_DEFAULT.
#define LIB_SPEC ""
-/* Provide required defaults for linker -e. */
+/* Provide required defaults for linker. */
-#define LINK_SPEC "%{!nostdlib:%{!r*:%{!e*:-e start}}}"
+#define LINK_SPEC "-r"
/* VxWorks provides the functionality of crt0.o and friends itself. */
@@ -99,3 +99,8 @@ Unrecognized value in TARGET_CPU_DEFAULT.
/* GCC is the primary compiler for VxWorks, so we don't need this. */
#undef PCC_STATIC_STRUCT_RETURN
+
+/* Restrict use of 128 bit floating-point by default since VxWorks doesn't
+ have the proper accuracy routines for that size; this is not done because
+ the hardware doesn't support it, despite the name. */
+#define WIDEST_HARDWARE_FP_SIZE 64
diff --git a/gcc/config/m68k/xm-mot3300.h b/gcc/config/m68k/xm-mot3300.h
index ea3b5589dbe..4a949052cef 100644
--- a/gcc/config/m68k/xm-mot3300.h
+++ b/gcc/config/m68k/xm-mot3300.h
@@ -1,6 +1,6 @@
/* Configuration for GNU C-compiler for Motorola 68000 family.
SysV68 Motorola 3300 Delta Series
- Copyright (C) 1994, 1995, 1996, 1997 Free Software Foundation, Inc.
+ Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -35,7 +35,3 @@ extern char *alloca ();
#define __PTR_TO_INT(P) ((int)(P))
#define __INT_TO_PTR(P) ((char *)(P))
-
-/* We need POSIX/XOPEN symbols; otherwise make check will fail. */
-#define ADD_MISSING_POSIX 1
-#define ADD_MISSING_XOPEN 1
diff --git a/gcc/config/m88k/dgux.h b/gcc/config/m88k/dgux.h
index 3e4c66ea90c..f93672c99c9 100644
--- a/gcc/config/m88k/dgux.h
+++ b/gcc/config/m88k/dgux.h
@@ -30,7 +30,7 @@ Boston, MA 02111-1307, USA. */
(TARGET_SVR4 ? DWARF_DEBUG : SDB_DEBUG)
#ifndef VERSION_INFO2
-#define VERSION_INFO2 "$Revision: 1.3 $"
+#define VERSION_INFO2 "$Revision: 1.4 $"
#endif
#ifndef NO_BUGS
#define AS_BUG_IMMEDIATE_LABEL
diff --git a/gcc/config/m88k/m88k.c b/gcc/config/m88k/m88k.c
index b1250e5e61b..2814ccbbc64 100644
--- a/gcc/config/m88k/m88k.c
+++ b/gcc/config/m88k/m88k.c
@@ -1,5 +1,6 @@
/* Subroutines for insn-output.c for Motorola 88000.
- Copyright (C) 1988, 92, 93, 94, 95, 16, 1997 Free Software Foundation, Inc.
+ Copyright (C) 1988, 92, 93, 94, 95, 16, 1997, 1999 Free Software
+ Foundation, Inc.
Contributed by Michael Tiemann (tiemann@mcc.com)
Currently maintained by (gcc@dg-rtp.dg.com)
@@ -406,8 +407,7 @@ legitimize_address (pic, orig, reg, scratch)
{
new = gen_rtx (MEM, GET_MODE (orig), new);
RTX_UNCHANGING_P (new) = RTX_UNCHANGING_P (orig);
- MEM_VOLATILE_P (new) = MEM_VOLATILE_P (orig);
- MEM_IN_STRUCT_P (new) = MEM_IN_STRUCT_P (orig);
+ MEM_COPY_ATTRIBUTES (new, orig);
}
return new;
}
@@ -603,8 +603,7 @@ block_move_loop (dest, dest_mem, src, src_mem, size, align)
gen_rtx (REG, Pmode, 3),
offset_rtx));
RTX_UNCHANGING_P (value_rtx) = RTX_UNCHANGING_P (src_mem);
- MEM_VOLATILE_P (value_rtx) = MEM_VOLATILE_P (src_mem);
- MEM_IN_STRUCT_P (value_rtx) = MEM_IN_STRUCT_P (src_mem);
+ MEM_COPY_ATTRIBUTES (value_rtx, src_mem);
emit_insn (gen_call_movstrsi_loop
(gen_rtx (SYMBOL_REF, Pmode, IDENTIFIER_POINTER (entry_name)),
@@ -660,8 +659,7 @@ block_move_no_loop (dest, dest_mem, src, src_mem, size, align)
gen_rtx (REG, Pmode, 3),
offset_rtx));
RTX_UNCHANGING_P (value_rtx) = RTX_UNCHANGING_P (src_mem);
- MEM_VOLATILE_P (value_rtx) = MEM_VOLATILE_P (src_mem);
- MEM_IN_STRUCT_P (value_rtx) = MEM_IN_STRUCT_P (src_mem);
+ MEM_COPY_ATTRIBUTES (value_rtx, src_mem);
value_reg = ((((most - (size - remainder)) / align) & 1) == 0
? (align == 8 ? 6 : 5) : 4);
@@ -733,8 +731,7 @@ block_move_sequence (dest, dest_mem, src, src_mem, size, align, offset)
gen_rtx (PLUS, Pmode, src,
GEN_INT (offset_ld)));
RTX_UNCHANGING_P (srcp) = RTX_UNCHANGING_P (src_mem);
- MEM_VOLATILE_P (srcp) = MEM_VOLATILE_P (src_mem);
- MEM_IN_STRUCT_P (srcp) = MEM_IN_STRUCT_P (src_mem);
+ MEM_COPY_ATTRIBUTES (srcp, src_mem);
emit_insn (gen_rtx (SET, VOIDmode, temp[next], srcp));
offset_ld += amount[next];
active[next] = TRUE;
@@ -748,8 +745,7 @@ block_move_sequence (dest, dest_mem, src, src_mem, size, align, offset)
gen_rtx (PLUS, Pmode, dest,
GEN_INT (offset_st)));
RTX_UNCHANGING_P (dstp) = RTX_UNCHANGING_P (dest_mem);
- MEM_VOLATILE_P (dstp) = MEM_VOLATILE_P (dest_mem);
- MEM_IN_STRUCT_P (dstp) = MEM_IN_STRUCT_P (dest_mem);
+ MEM_COPY_ATTRIBUTES (dstp, dest_mem);
emit_insn (gen_rtx (SET, VOIDmode, dstp, temp[phase]));
offset_st += amount[phase];
}
@@ -1484,6 +1480,7 @@ struct options
char *string;
int *variable;
int on_value;
+ char *description;
};
static int
@@ -2610,7 +2607,7 @@ m88k_builtin_saveregs (arglist)
/* Allocate the va_list constructor */
block = assign_stack_local (BLKmode, 3 * UNITS_PER_WORD, BITS_PER_WORD);
- MEM_IN_STRUCT_P (block) = 1;
+ MEM_SET_IN_STRUCT_P (block, 1);
RTX_UNCHANGING_P (block) = 1;
RTX_UNCHANGING_P (XEXP (block, 0)) = 1;
@@ -2626,7 +2623,7 @@ m88k_builtin_saveregs (arglist)
/* Allocate the register space, and store it as the __va_reg member. */
addr = assign_stack_local (BLKmode, 8 * UNITS_PER_WORD, -1);
- MEM_IN_STRUCT_P (addr) = 1;
+ MEM_SET_IN_STRUCT_P (addr, 1);
RTX_UNCHANGING_P (addr) = 1;
RTX_UNCHANGING_P (XEXP (addr, 0)) = 1;
emit_move_insn (change_address (block, Pmode,
@@ -2644,7 +2641,7 @@ m88k_builtin_saveregs (arglist)
UNITS_PER_WORD * (8 - fixed));
}
- if (flag_check_memory_usage)
+ if (current_function_check_memory_usage)
{
emit_library_call (chkr_set_right_libfunc, 1, VOIDmode, 3,
block, ptr_mode,
diff --git a/gcc/config/m88k/m88k.h b/gcc/config/m88k/m88k.h
index 40230029e5b..5f3a4f58c55 100644
--- a/gcc/config/m88k/m88k.h
+++ b/gcc/config/m88k/m88k.h
@@ -198,13 +198,13 @@ extern char * reg_names[];
Redefined in sysv4.h, and luna.h. */
#define VERSION_INFO1 "m88k, "
#ifndef VERSION_INFO2
-#define VERSION_INFO2 "$Revision: 1.9 $"
+#define VERSION_INFO2 "$Revision: 1.12 $"
#endif
#ifndef VERSION_STRING
#define VERSION_STRING version_string
#ifdef __STDC__
-#define TM_RCS_ID "@(#)" __FILE__ " $Revision: 1.9 $ " __DATE__
+#define TM_RCS_ID "@(#)" __FILE__ " $Revision: 1.12 $ " __DATE__
#else
#define TM_RCS_ID "$What: <@(#) m88k.h,v 1.1.1.2.2.2> $"
#endif /* __STDC__ */
@@ -648,7 +648,6 @@ extern char * reg_names[];
/* These interfaces that don't apply to the m88000. */
/* OVERLAPPING_REGNO_P(REGNO) 0 */
/* INSN_CLOBBERS_REGNO_P(INSN, REGNO) 0 */
-/* PRESERVE_DEATH_INFO_REGNO_P(REGNO) 0 */
/* True if register is an extended register. */
#define XRF_REGNO_P(N) ((N) < FIRST_PSEUDO_REGISTER && (N) >= FIRST_EXTENDED_REGISTER)
@@ -1260,11 +1259,11 @@ enum reg_class { NO_REGS, AP_REG, XRF_REGS, GENERAL_REGS, AGRF_REGS,
#define SELECT_CC_MODE(OP,X,Y) CCmode
-/* #define HAVE_POST_INCREMENT */
-/* #define HAVE_POST_DECREMENT */
+/* #define HAVE_POST_INCREMENT 0 */
+/* #define HAVE_POST_DECREMENT 0 */
-/* #define HAVE_PRE_DECREMENT */
-/* #define HAVE_PRE_INCREMENT */
+/* #define HAVE_PRE_DECREMENT 0 */
+/* #define HAVE_PRE_INCREMENT 0 */
/* Recognize any constant value that is a valid address.
When PIC, we do not accept an address that would require a scratch reg
diff --git a/gcc/config/m88k/m88k.md b/gcc/config/m88k/m88k.md
index 118ebe366da..edab3f706ae 100644
--- a/gcc/config/m88k/m88k.md
+++ b/gcc/config/m88k/m88k.md
@@ -1,5 +1,5 @@
;;- Machine description for the Motorola 88000 for GNU C compiler
-;;; Copyright (C) 1988, 92, 93, 94, 95, 1996 Free Software Foundation, Inc.
+;;; Copyright (C) 1988, 92-96, 1999 Free Software Foundation, Inc.
;; Contributed by Michael Tiemann (tiemann@mcc.com)
;; Currently maintained by (gcc@dg-rtp.dg.com)
@@ -759,7 +759,7 @@
(define_insn ""
[(set (match_operand:CCEVEN 0 "register_operand" "=r")
- (rotate:CC (match_operand 1 "partial_ccmode_register_operand" "r")
+ (rotate:CCEVEN (match_operand 1 "partial_ccmode_register_operand" "r")
(match_operand:CC 2 "int5_operand" "")))]
""
"rot %0,%1,%2"
@@ -782,7 +782,7 @@
(define_insn ""
[(set (match_operand:CCEVEN 0 "register_operand" "=r")
- (ior:CC (rotate:CC (match_operand 1 "partial_ccmode_register_operand" "r")
+ (ior:CCEVEN (rotate:CC (match_operand 1 "partial_ccmode_register_operand" "r")
(match_operand:CC 2 "int5_operand" ""))
(match_operand 3 "partial_ccmode_register_operand" "r")))
(clobber (match_scratch:CCEVEN 4 "=r"))]
@@ -2129,60 +2129,49 @@
DONE;
}")
+;; ??? We shouldn't be allowing such mode mismatches
(define_insn ""
- [(set (match_operand:QI 0 "register_operand" "=r")
- (match_operand:BLK 1 "memory_operand" "m"))]
- ""
- "%V1ld.bu\\t %0,%1"
- [(set_attr "type" "load")])
-
-(define_insn ""
- [(set (match_operand:HI 0 "register_operand" "=r")
+ [(set (match_operand 0 "register_operand" "=r")
(match_operand:BLK 1 "memory_operand" "m"))]
""
- "%V1ld.hu\\t %0,%1"
- [(set_attr "type" "load")])
-
-(define_insn ""
- [(set (match_operand:SI 0 "register_operand" "=r")
- (match_operand:BLK 1 "memory_operand" "m"))]
- ""
- "%V1ld\\t %0,%1"
+ "*
+{
+ switch (GET_MODE (operands[0]))
+ {
+ case QImode:
+ return \"%V1ld.bu\\t %0,%1\";
+ case HImode:
+ return \"%V1ld.hu\\t %0,%1\";
+ case SImode:
+ return \"%V1ld\\t %0,%1\";
+ case DImode:
+ return \"%V1ld.d\\t %0,%1\";
+ default:
+ abort ();
+ }
+}"
[(set_attr "type" "load")])
(define_insn ""
- [(set (match_operand:DI 0 "register_operand" "=r")
- (match_operand:BLK 1 "memory_operand" "m"))]
- ""
- "%V1ld.d\\t %0,%1"
- [(set_attr "type" "loadd")])
-
-(define_insn ""
- [(set (match_operand:BLK 0 "memory_operand" "=m")
- (match_operand:QI 1 "register_operand" "r"))]
- ""
- "%v0st.b\\t %1,%0"
- [(set_attr "type" "store")])
-
-(define_insn ""
[(set (match_operand:BLK 0 "memory_operand" "=m")
- (match_operand:HI 1 "register_operand" "r"))]
+ (match_operand 1 "register_operand" "r"))]
""
- "%v0st.h\\t %1,%0"
- [(set_attr "type" "store")])
-
-(define_insn ""
- [(set (match_operand:BLK 0 "memory_operand" "=m")
- (match_operand:SI 1 "register_operand" "r"))]
- ""
- "%v0st\\t %1,%0"
- [(set_attr "type" "store")])
-
-(define_insn ""
- [(set (match_operand:BLK 0 "memory_operand" "=m")
- (match_operand:DI 1 "register_operand" "r"))]
- ""
- "%v0st.d\\t %1,%0"
+ "*
+{
+ switch (GET_MODE (operands[1]))
+ {
+ case QImode:
+ return \"%v0st.b\\t %1,%0\";
+ case HImode:
+ return \"%v0st.h\\t %1,%0\";
+ case SImode:
+ return \"%v0st\\t %1,%0\";
+ case DImode:
+ return \"%v0st.d\\t %1,%0\";
+ default:
+ abort ();
+ }
+}"
[(set_attr "type" "store")])
;; Call a non-looping block move library function (e.g. __movstrSI96x64).
diff --git a/gcc/config/m88k/sysv3.h b/gcc/config/m88k/sysv3.h
index ef351897398..546b6dfc1a6 100644
--- a/gcc/config/m88k/sysv3.h
+++ b/gcc/config/m88k/sysv3.h
@@ -1,6 +1,6 @@
/* Definitions of target machine for GNU compiler.
Motorola m88100 running the AT&T/Unisoft/Motorola V.3 reference port.
- Copyright (C) 1990, 1991, 1997 Free Software Foundation, Inc.
+ Copyright (C) 1990, 1991, 1997, 1999 Free Software Foundation, Inc.
Contributed by Ray Essick (ressick@mot.com)
Enhanced by Tom Wood (Tom_Wood@NeXT.com)
@@ -44,6 +44,10 @@ Boston, MA 02111-1307, USA. */
#undef LIB_SPEC
#define LIB_SPEC "%{p:-L/lib/libp}%{pg:%{!p:-L/lib/libp}} -lg -lc crtend.o%s"
+/* We need POSIX/XOPEN symbols; otherwise building libio will fail. */
+#define ADD_MISSING_POSIX 1
+#define ADD_MISSING_XOPEN 1
+
/* Hot version of the profiler that uses r10 to pass the address of
the counter. the _gcc_mcount routine knows not to screw with
the parameter registers.
diff --git a/gcc/config/m88k/t-luna-gas b/gcc/config/m88k/t-luna-gas
index 1d6692ab4a0..780e75cec9f 100644
--- a/gcc/config/m88k/t-luna-gas
+++ b/gcc/config/m88k/t-luna-gas
@@ -5,7 +5,7 @@ MOVE_ASM = moveHI15x.asm moveQI16x.asm moveSI46x.asm moveSI64n.asm \
moveDI96x.asm
$(MOVE_ASM): $(srcdir)/config/m88k/m88k-move.sh
- bash $(srcdir)/config/m88k/m88k-move.sh -no-tdesc
+ $(SHELL) $(srcdir)/config/m88k/m88k-move.sh -no-tdesc
LIB2FUNCS_EXTRA = $(MOVE_ASM)
LIBGCC1 = libgcc1.null
diff --git a/gcc/config/m88k/xm-sysv3.h b/gcc/config/m88k/xm-sysv3.h
index 84110d7474d..a15fbbaaa54 100644
--- a/gcc/config/m88k/xm-sysv3.h
+++ b/gcc/config/m88k/xm-sysv3.h
@@ -1,6 +1,6 @@
/* Configuration for GNU C-compiler.
Motorola m88100 running the AT&T/Unisoft/Motorola V.3 reference port.
- Copyright (C) 1990, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1990, 1998, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -26,7 +26,3 @@ Boston, MA 02111-1307, USA. */
/* for the emacs version of alloca */
#define STACK_DIRECTION -1
-
-/* We need POSIX/XOPEN symbols; otherwise make check will fail. */
-#define ADD_MISSING_POSIX 1
-#define ADD_MISSING_XOPEN 1
diff --git a/gcc/config/mips/abi64.h b/gcc/config/mips/abi64.h
index ea3f28c7381..ce1e5fe3831 100644
--- a/gcc/config/mips/abi64.h
+++ b/gcc/config/mips/abi64.h
@@ -1,5 +1,5 @@
/* Definitions of target machine for GNU compiler. 64 bit ABI support.
- Copyright (C) 1994, 1995, 1996, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1994, 1995, 1996, 1998, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -22,23 +22,27 @@ Boston, MA 02111-1307, USA. */
after mips.h. */
#undef SUBTARGET_TARGET_OPTIONS
-#define SUBTARGET_TARGET_OPTIONS\
- { "abi=", &mips_abi_string },
+#define SUBTARGET_TARGET_OPTIONS \
+ { "abi=", &mips_abi_string, \
+ "Speciy ABI to use"},
#undef STACK_BOUNDARY
#define STACK_BOUNDARY \
- ((mips_abi == ABI_32 || mips_abi == ABI_EABI) ? 64 : 128)
+ ((mips_abi == ABI_32 || mips_abi == ABI_O64 || mips_abi == ABI_EABI) \
+ ? 64 : 128)
#undef MIPS_STACK_ALIGN
-#define MIPS_STACK_ALIGN(LOC) \
- ((mips_abi == ABI_32 || mips_abi == ABI_EABI) \
- ? ((LOC) + 7) & ~7 \
+#define MIPS_STACK_ALIGN(LOC) \
+ ((mips_abi == ABI_32 || mips_abi == ABI_O64 || mips_abi == ABI_EABI) \
+ ? ((LOC) + 7) & ~7 \
: ((LOC) + 15) & ~15)
#undef GP_ARG_LAST
-#define GP_ARG_LAST (mips_abi == ABI_32 ? GP_REG_FIRST + 7 : GP_REG_FIRST + 11)
+#define GP_ARG_LAST ((mips_abi == ABI_32 || mips_abi == ABI_O64) \
+ ? GP_REG_FIRST + 7 : GP_REG_FIRST + 11)
#undef FP_ARG_LAST
-#define FP_ARG_LAST (mips_abi == ABI_32 ? FP_REG_FIRST + 15 : FP_REG_FIRST + 19)
+#define FP_ARG_LAST ((mips_abi == ABI_32 || mips_abi == ABI_O64) \
+ ? FP_REG_FIRST + 15 : FP_REG_FIRST + 19)
#undef SUBTARGET_CONDITIONAL_REGISTER_USAGE
#define SUBTARGET_CONDITIONAL_REGISTER_USAGE \
@@ -60,11 +64,12 @@ Boston, MA 02111-1307, USA. */
}
#undef MAX_ARGS_IN_REGISTERS
-#define MAX_ARGS_IN_REGISTERS (mips_abi == ABI_32 ? 4 : 8)
+#define MAX_ARGS_IN_REGISTERS ((mips_abi == ABI_32 || mips_abi == ABI_O64) \
+ ? 4 : 8)
#undef REG_PARM_STACK_SPACE
#define REG_PARM_STACK_SPACE(FNDECL) \
- (mips_abi == ABI_32 \
+ ((mips_abi == ABI_32 || mips_abi == ABI_O64) \
? (MAX_ARGS_IN_REGISTERS*UNITS_PER_WORD) - FIRST_PARM_OFFSET (FNDECL) \
: 0)
@@ -75,13 +80,15 @@ Boston, MA 02111-1307, USA. */
? ((TYPE) && TREE_CODE (TYPE_SIZE (TYPE)) == INTEGER_CST \
&& int_size_in_bytes (TYPE) < (PARM_BOUNDARY / BITS_PER_UNIT))\
: (GET_MODE_BITSIZE (MODE) < PARM_BOUNDARY \
- && (mips_abi == ABI_32 || mips_abi == ABI_EABI \
+ && (mips_abi == ABI_32 \
+ || mips_abi == ABI_O64 \
+ || mips_abi == ABI_EABI \
|| GET_MODE_CLASS (MODE) == MODE_INT))) \
? downward : upward))
#undef RETURN_IN_MEMORY
#define RETURN_IN_MEMORY(TYPE) \
- (mips_abi == ABI_32 \
+ ((mips_abi == ABI_32 || mips_abi == ABI_O64) \
? TYPE_MODE (TYPE) == BLKmode \
: (int_size_in_bytes (TYPE) \
> (mips_abi == ABI_EABI ? 2 * UNITS_PER_WORD : 16)))
@@ -97,7 +104,7 @@ extern struct rtx_def *mips_function_value ();
#define SETUP_INCOMING_VARARGS(CUM,MODE,TYPE,PRETEND_SIZE,NO_RTL) \
{ int mips_off = (! current_function_varargs) && (! (CUM).last_arg_fp); \
int mips_fp_off = (! current_function_varargs) && ((CUM).last_arg_fp); \
- if ((mips_abi != ABI_32 \
+ if (((mips_abi != ABI_32 && mips_abi != ABI_O64) \
&& (CUM).arg_words < MAX_ARGS_IN_REGISTERS - mips_off) \
|| (mips_abi == ABI_EABI \
&& ! TARGET_SOFT_FLOAT \
@@ -133,7 +140,7 @@ extern struct rtx_def *mips_function_value ();
so that the insn scheduler won't assume that these \
stores can't possibly overlap with the va_arg loads. */ \
if (mips_abi != ABI_EABI && BYTES_BIG_ENDIAN) \
- MEM_IN_STRUCT_P (mem) = 1; \
+ MEM_SET_IN_STRUCT_P (mem, 1); \
move_block_from_reg \
((CUM).arg_words + GP_ARG_FIRST + mips_off, \
mem, \
@@ -178,7 +185,7 @@ extern struct rtx_def *mips_function_value ();
} \
}
-#define STRICT_ARGUMENT_NAMING (mips_abi != ABI_32)
+#define STRICT_ARGUMENT_NAMING (mips_abi != ABI_32 && mips_abi != ABI_O64)
/* A C expression that indicates when an argument must be passed by
reference. If nonzero for an argument, a copy of that argument is
@@ -217,7 +224,7 @@ extern struct rtx_def *mips_function_value ();
#undef LONG_MAX_SPEC
#if ((MIPS_ABI_DEFAULT == ABI_64) || ((MIPS_ABI_DEFAULT == ABI_EABI) && ((TARGET_DEFAULT | TARGET_CPU_DEFAULT) & MASK_64BIT)))
#define LONG_MAX_SPEC \
- "%{!mabi=n32:%{!mno-long64:%{!mgp32:%{!mips1:%{!mips2:-D__LONG_MAX__=9223372036854775807L}}}}}"
+ "%{!mabi=32:%{!mabi=n32:%{!mlong32:%{!mgp32:%{!mips1:%{!mips2:-D__LONG_MAX__=9223372036854775807L}}}}}}"
#else
#define LONG_MAX_SPEC \
"%{mabi=64:-D__LONG_MAX__=9223372036854775807L} \
diff --git a/gcc/config/mips/gnu.h b/gcc/config/mips/gnu.h
index bf48bc4dbca..734548b5211 100644
--- a/gcc/config/mips/gnu.h
+++ b/gcc/config/mips/gnu.h
@@ -1,5 +1,5 @@
/* Definitions of target machine for GNU compiler. MIPS GNU Hurd version.
- Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+ Copyright (C) 1995, 1996, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -52,8 +52,9 @@ Boston, MA 02111-1307, USA. */
#define ASM_FILE_END(FILE) \
do { \
mips_asm_file_end(FILE); \
- fprintf ((FILE), "\t%s\t\"GCC: (GNU) %s\"\n", \
- IDENT_ASM_OP, version_string); \
+ if (!flag_no_ident) \
+ fprintf ((FILE), "\t%s\t\"GCC: (GNU) %s\"\n", \
+ IDENT_ASM_OP, version_string); \
} while (0)
#undef ASM_OUTPUT_SOURCE_LINE
diff --git a/gcc/config/mips/iris6.h b/gcc/config/mips/iris6.h
index 30e1860267f..9df7732e8b0 100644
--- a/gcc/config/mips/iris6.h
+++ b/gcc/config/mips/iris6.h
@@ -187,6 +187,7 @@ Boston, MA 02111-1307, USA. */
#define ASM_OUTPUT_WEAK_ALIAS(FILE,NAME,VALUE) \
do { \
+ ASM_GLOBALIZE_LABEL (FILE, NAME); \
fputs ("\t.weakext\t", FILE); \
assemble_name (FILE, NAME); \
if (VALUE) \
@@ -262,9 +263,9 @@ Boston, MA 02111-1307, USA. */
/* If we are included from varasm.c, these need to depend on -mabi. */
#define CTORS_SECTION_ASM_OP \
- (TARGET_LONG64 ? ".section\t.ctors,1,2,0,8" : ".section\t.ctors,1,2,0,4")
+ (Pmode == DImode ? ".section\t.ctors,1,2,0,8" : ".section\t.ctors,1,2,0,4")
#define DTORS_SECTION_ASM_OP \
- (TARGET_LONG64 ? ".section\t.dtors,1,2,0,8" : ".section\t.dtors,1,2,0,4")
+ (Pmode == DImode ? ".section\t.dtors,1,2,0,8" : ".section\t.dtors,1,2,0,4")
#endif /* defined (CRT_BEGIN) || defined (CRT_END) */
/* dwarf2out will handle padding this data properly. We definitely don't
@@ -302,7 +303,7 @@ rdata_section () \
{ \
if (in_section != in_rdata) \
{ \
- if (mips_abi != ABI_32) \
+ if (mips_abi != ABI_32 && mips_abi != ABI_O64) \
fprintf (asm_out_file, "%s\n", CONST_SECTION_ASM_OP_64); \
else \
fprintf (asm_out_file, "%s\n", CONST_SECTION_ASM_OP_32); \
@@ -340,7 +341,7 @@ dtors_section () \
do { \
ctors_section (); \
fprintf (FILE, "\t%s\t ", \
- TARGET_LONG64 ? ".dword" : ".word"); \
+ (Pmode == DImode) ? ".dword" : ".word"); \
assemble_name (FILE, NAME); \
fprintf (FILE, "\n"); \
} while (0)
@@ -351,7 +352,7 @@ dtors_section () \
do { \
dtors_section (); \
fprintf (FILE, "\t%s\t ", \
- TARGET_LONG64 ? ".dword" : ".word"); \
+ (Pmode == DImode) ? ".dword" : ".word"); \
assemble_name (FILE, NAME); \
fprintf (FILE, "\n"); \
} while (0)
@@ -393,7 +394,7 @@ while (0)
#define ASM_OUTPUT_ALIGNED_LOCAL(STREAM, NAME, SIZE, ALIGN) \
do \
{ \
- if (mips_abi != ABI_32) \
+ if (mips_abi != ABI_32 && mips_abi != ABI_O64) \
{ \
fprintf (STREAM, "%s\n", BSS_SECTION_ASM_OP); \
mips_declare_object (STREAM, NAME, "", ":\n", 0); \
@@ -454,7 +455,8 @@ do { \
} while (0)
#undef LOCAL_LABEL_PREFIX
-#define LOCAL_LABEL_PREFIX (mips_abi == ABI_32 ? "$" : ".")
+#define LOCAL_LABEL_PREFIX ((mips_abi == ABI_32 || mips_abi == ABI_O64) \
+ ? "$" : ".")
/* Profiling is supported via libprof1.a not -lc_p as in Irix 3. */
/* ??? If no mabi=X option give, but a mipsX option is, then should depend
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index 98c634dc34a..a4b38e197a3 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -1,5 +1,5 @@
/* Subroutines for insn-output.c for MIPS
- Copyright (C) 1989, 90, 91, 93-97, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1989, 90, 91, 93-98, 1999 Free Software Foundation, Inc.
Contributed by A. Lichnewsky, lich@inria.inria.fr.
Changes by Michael Meissner, meissner@osf.org.
64 bit r4000 support by Ian Lance Taylor, ian@cygnus.com, and
@@ -106,6 +106,8 @@ static rtx add_constant PROTO ((struct constant **,
static void dump_constants PROTO ((struct constant *,
rtx));
static rtx mips_find_symbol PROTO ((rtx));
+static void abort_with_insn PROTO ((rtx, const char *))
+ ATTRIBUTE_NORETURN;
/* Global variables for machine-dependent things. */
@@ -148,7 +150,7 @@ struct extern_list
} *extern_head = 0;
/* Name of the file containing the current function. */
-char *current_function_file = "";
+const char *current_function_file = "";
/* Warning given that Mips ECOFF can't support changing files
within a function. */
@@ -206,9 +208,9 @@ int mips_abi;
#endif
/* Strings to hold which cpu and instruction set architecture to use. */
-char *mips_cpu_string; /* for -mcpu=<xxx> */
-char *mips_isa_string; /* for -mips{1,2,3,4} */
-char *mips_abi_string; /* for -mabi={32,n32,64,eabi} */
+const char *mips_cpu_string; /* for -mcpu=<xxx> */
+const char *mips_isa_string; /* for -mips{1,2,3,4} */
+const char *mips_abi_string; /* for -mabi={32,n32,64,eabi} */
/* Whether we are generating mips16 code. This is a synonym for
TARGET_MIPS16, and exists for use as an attribute. */
@@ -217,7 +219,12 @@ int mips16;
/* This variable is set by -mno-mips16. We only care whether
-mno-mips16 appears or not, and using a string in this fashion is
just a way to avoid using up another bit in target_flags. */
-char *mips_no_mips16_string;
+const char *mips_no_mips16_string;
+
+/* This is only used to determine if an type size setting option was
+ explicitly specified (-mlong64, -mint64, -mlong32). The specs
+ set this option if such an option is used. */
+const char *mips_explicit_type_size_string;
/* Whether we are generating mips16 hard float code. In mips16 mode
we always set TARGET_SOFT_FLOAT; this variable is nonzero if
@@ -228,7 +235,7 @@ int mips16_hard_float;
/* This variable is set by -mentry. We only care whether -mentry
appears or not, and using a string in this fashion is just a way to
avoid using up another bit in target_flags. */
-char *mips_entry_string;
+const char *mips_entry_string;
/* Whether we should entry and exit pseudo-ops in mips16 mode. */
int mips_entry;
@@ -543,6 +550,33 @@ reg_or_0_operand (op, mode)
return 0;
}
+/* Return truth value of whether OP is a register or the constant 0,
+ even in mips16 mode. */
+
+int
+true_reg_or_0_operand (op, mode)
+ rtx op;
+ enum machine_mode mode;
+{
+ switch (GET_CODE (op))
+ {
+ case CONST_INT:
+ return INTVAL (op) == 0;
+
+ case CONST_DOUBLE:
+ return op == CONST0_RTX (mode);
+
+ case REG:
+ case SUBREG:
+ return register_operand (op, mode);
+
+ default:
+ break;
+ }
+
+ return 0;
+}
+
/* Return truth value if a CONST_DOUBLE is ok to be a legitimate constant. */
int
@@ -565,7 +599,7 @@ mips_const_double_ok (op, mode)
return 1;
/* ??? li.s does not work right with SGI's Irix 6 assembler. */
- if (mips_abi != ABI_32 && mips_abi != ABI_EABI)
+ if (mips_abi != ABI_32 && mips_abi != ABI_O64 && mips_abi != ABI_EABI)
return 0;
REAL_VALUE_FROM_CONST_DOUBLE (d, op);
@@ -1622,13 +1656,13 @@ embedded_pic_offset (x)
/* Return the appropriate instructions to move one operand to another. */
-char *
+const char *
mips_move_1word (operands, insn, unsignedp)
rtx operands[];
rtx insn;
int unsignedp;
{
- char *ret = 0;
+ const char *ret = 0;
rtx op0 = operands[0];
rtx op1 = operands[1];
enum rtx_code code0 = GET_CODE (op0);
@@ -2016,12 +2050,12 @@ mips_move_1word (operands, insn, unsignedp)
/* Return the appropriate instructions to move 2 words */
-char *
+const char *
mips_move_2words (operands, insn)
rtx operands[];
rtx insn;
{
- char *ret = 0;
+ const char *ret = 0;
rtx op0 = operands[0];
rtx op1 = operands[1];
enum rtx_code code0 = GET_CODE (operands[0]);
@@ -2682,7 +2716,7 @@ gen_int_relational (test_code, result, cmp0, cmp1, p_invert)
&& p_info->const_add != 0
&& ((p_info->unsignedp
? ((unsigned HOST_WIDE_INT) (value + p_info->const_add)
- > INTVAL (cmp1))
+ > (unsigned HOST_WIDE_INT) INTVAL (cmp1))
: (value + p_info->const_add) > INTVAL (cmp1))
!= (p_info->const_add > 0))))
cmp1 = force_reg (mode, cmp1);
@@ -2710,7 +2744,8 @@ gen_int_relational (test_code, result, cmp0, cmp1, p_invert)
we would get the wrong answer if we follow the usual path;
thus, x > 0xffffffffU would turn into x > 0U. */
if ((p_info->unsignedp
- ? (unsigned HOST_WIDE_INT) new > INTVAL (cmp1)
+ ? (unsigned HOST_WIDE_INT) new >
+ (unsigned HOST_WIDE_INT) INTVAL (cmp1)
: new > INTVAL (cmp1))
!= (p_info->const_add > 0))
{
@@ -3196,7 +3231,7 @@ expand_block_move (operands)
BLOCK_MOVE_NOT_LAST Do all but the last store.
BLOCK_MOVE_LAST Do just the last store. */
-char *
+const char *
output_block_move (insn, operands, num_regs, move_type)
rtx insn;
rtx operands[];
@@ -3216,11 +3251,11 @@ output_block_move (insn, operands, num_regs, move_type)
rtx xoperands[10];
struct {
- char *load; /* load insn without nop */
- char *load_nop; /* load insn with trailing nop */
- char *store; /* store insn */
- char *final; /* if last_store used: NULL or swr */
- char *last_store; /* last store instruction */
+ const char *load; /* load insn without nop */
+ const char *load_nop; /* load insn with trailing nop */
+ const char *store; /* store insn */
+ const char *final; /* if last_store used: NULL or swr */
+ const char *last_store; /* last store instruction */
int offset; /* current offset */
enum machine_mode mode; /* mode to use on (MEM) */
} load_store[4];
@@ -3230,7 +3265,7 @@ output_block_move (insn, operands, num_regs, move_type)
the number of registers available. */
for (i = 4;
i < last_operand
- && safe_regs < (sizeof(xoperands) / sizeof(xoperands[0]));
+ && safe_regs < (int)(sizeof(xoperands) / sizeof(xoperands[0]));
i++)
if (! reg_mentioned_p (operands[i], operands[0])
&& ! reg_mentioned_p (operands[i], operands[1]))
@@ -3326,7 +3361,7 @@ output_block_move (insn, operands, num_regs, move_type)
}
}
- if (num_regs > sizeof (load_store) / sizeof (load_store[0]))
+ if (num_regs > (int)(sizeof (load_store) / sizeof (load_store[0])))
num_regs = sizeof (load_store) / sizeof (load_store[0]);
else if (num_regs < 1)
@@ -3689,7 +3724,7 @@ function_arg (cum, mode, type, named)
switch (mode)
{
case SFmode:
- if (mips_abi == ABI_32)
+ if (mips_abi == ABI_32 || mips_abi == ABI_O64)
{
if (cum->gp_reg_found || cum->arg_number >= 2 || TARGET_SOFT_FLOAT)
regbase = GP_ARG_FIRST;
@@ -3725,7 +3760,7 @@ function_arg (cum, mode, type, named)
cum->arg_words += cum->arg_words & 1;
}
- if (mips_abi == ABI_32)
+ if (mips_abi == ABI_32 || mips_abi == ABI_O64)
regbase = ((cum->gp_reg_found
|| TARGET_SOFT_FLOAT || TARGET_SINGLE_FLOAT
|| cum->arg_number >= 2)
@@ -3749,7 +3784,7 @@ function_arg (cum, mode, type, named)
/* Drops through. */
case BLKmode:
- if (type != (tree)0 && TYPE_ALIGN (type) > BITS_PER_WORD
+ if (type != (tree)0 && TYPE_ALIGN (type) > (unsigned) BITS_PER_WORD
&& ! TARGET_64BIT && mips_abi != ABI_EABI)
cum->arg_words += (cum->arg_words & 1);
regbase = GP_ARG_FIRST;
@@ -3781,7 +3816,7 @@ function_arg (cum, mode, type, named)
abort ();
if (! type || TREE_CODE (type) != RECORD_TYPE || mips_abi == ABI_32
- || mips_abi == ABI_EABI || ! named)
+ || mips_abi == ABI_EABI || mips_abi == ABI_O64 || ! named)
ret = gen_rtx (REG, mode, regbase + *arg_words + bias);
else
{
@@ -3954,10 +3989,10 @@ function_arg_partial_nregs (cum, mode, type, named)
/* Abort after printing out a specific insn. */
-void
+static void
abort_with_insn (insn, reason)
rtx insn;
- char *reason;
+ const char *reason;
{
error (reason);
debug_rtx (insn);
@@ -4041,11 +4076,13 @@ override_options ()
}
#ifdef MIPS_ABI_DEFAULT
- /* Get the ABI to use. Currently this code is only used for Irix 6. */
+ /* Get the ABI to use. */
if (mips_abi_string == (char *) 0)
mips_abi = MIPS_ABI_DEFAULT;
else if (! strcmp (mips_abi_string, "32"))
mips_abi = ABI_32;
+ else if (! strcmp (mips_abi_string, "o64"))
+ mips_abi = ABI_O64;
else if (! strcmp (mips_abi_string, "n32"))
mips_abi = ABI_N32;
else if (! strcmp (mips_abi_string, "64"))
@@ -4056,7 +4093,8 @@ override_options ()
error ("bad value (%s) for -mabi= switch", mips_abi_string);
/* A specified ISA defaults the ABI if it was not specified. */
- if (mips_abi_string == 0 && mips_isa_string && mips_abi != ABI_EABI)
+ if (mips_abi_string == 0 && mips_isa_string
+ && mips_abi != ABI_EABI && mips_abi != ABI_O64)
{
if (mips_isa <= 2)
mips_abi = ABI_32;
@@ -4065,7 +4103,8 @@ override_options ()
}
/* A specified ABI defaults the ISA if it was not specified. */
- else if (mips_isa_string == 0 && mips_abi_string && mips_abi != ABI_EABI)
+ else if (mips_isa_string == 0 && mips_abi_string
+ && mips_abi != ABI_EABI && mips_abi != ABI_O64)
{
if (mips_abi == ABI_32)
mips_isa = 1;
@@ -4078,7 +4117,8 @@ override_options ()
/* If both ABI and ISA were specified, check for conflicts. */
else if (mips_isa_string && mips_abi_string)
{
- if ((mips_isa <= 2 && (mips_abi == ABI_N32 || mips_abi == ABI_64))
+ if ((mips_isa <= 2 && (mips_abi == ABI_N32 || mips_abi == ABI_64
+ || mips_abi == ABI_O64))
|| (mips_isa >= 3 && mips_abi == ABI_32))
error ("-mabi=%s does not support -mips%d", mips_abi_string, mips_isa);
}
@@ -4087,10 +4127,12 @@ override_options ()
if (mips_abi == ABI_32)
target_flags &= ~ (MASK_FLOAT64|MASK_64BIT);
- /* In the EABI in 64 bit mode, longs and pointers are 64 bits. Likewise
- for the SGI Irix6 N64 ABI. */
- if ((mips_abi == ABI_EABI && TARGET_64BIT)
- || mips_abi == ABI_64)
+ /* If no type size setting options (-mlong64,-mint64,-mlong32) were used
+ then set the type sizes. In the EABI in 64 bit mode, longs and
+ pointers are 64 bits. Likewise for the SGI Irix6 N64 ABI. */
+ if (mips_explicit_type_size_string == NULL
+ && ((mips_abi == ABI_EABI && TARGET_64BIT)
+ || mips_abi == ABI_64))
target_flags |= MASK_LONG64;
/* ??? This doesn't work yet, so don't let people try to use it. */
@@ -4139,7 +4181,7 @@ override_options ()
else
{
- char *p = mips_cpu_string;
+ const char *p = mips_cpu_string;
int seen_v = 0;
/* We need to cope with the various "vr" prefixes for the NEC 4300
@@ -4156,13 +4198,6 @@ override_options ()
mips_cpu = PROCESSOR_DEFAULT;
switch (*p)
{
- /* start-sanitize-tx19 */
- case '1':
- if (!strcmp (p, "1900"))
- mips_cpu = PROCESSOR_R3900;
- break;
- /* end-sanitize-tx19 */
-
case '2':
if (!strcmp (p, "2000") || !strcmp (p, "2k") || !strcmp (p, "2K"))
mips_cpu = PROCESSOR_R3000;
@@ -4246,20 +4281,14 @@ override_options ()
/* make sure sizes of ints/longs/etc. are ok */
if (mips_isa < 3)
{
- if (TARGET_INT64)
- fatal ("Only MIPS-III or MIPS-IV CPUs can support 64 bit ints");
-
- else if (TARGET_LONG64)
- fatal ("Only MIPS-III or MIPS-IV CPUs can support 64 bit longs");
-
- else if (TARGET_FLOAT64)
+ if (TARGET_FLOAT64)
fatal ("Only MIPS-III or MIPS-IV CPUs can support 64 bit fp registers");
else if (TARGET_64BIT)
fatal ("Only MIPS-III or MIPS-IV CPUs can support 64 bit gp registers");
}
- if (mips_abi != ABI_32)
+ if (mips_abi != ABI_32 && mips_abi != ABI_O64)
flag_pcc_struct_return = 0;
/* Tell halfpic.c that we have half-pic code if we do. */
@@ -4519,6 +4548,10 @@ mips_debugger_offset (addr, offset)
? compute_frame_size (get_frame_size ())
: current_frame_info.total_size;
+ /* MIPS16 frame is smaller */
+ if (frame_pointer_needed && TARGET_MIPS16)
+ frame_size -= current_function_outgoing_args_size;
+
offset = offset - frame_size;
}
@@ -5046,7 +5079,7 @@ static FILE *
make_temp_file ()
{
FILE *stream;
- char *base = getenv ("TMPDIR");
+ const char *base = getenv ("TMPDIR");
int len;
if (base == 0)
@@ -5253,7 +5286,7 @@ mips_asm_file_start (stream)
/* Start a section, so that the first .popsection directive is guaranteed
to have a previously defined section to pop back to. */
- if (mips_abi != ABI_32 && mips_abi != ABI_EABI)
+ if (mips_abi != ABI_32 && mips_abi != ABI_O64 && mips_abi != ABI_EABI)
fprintf (stream, "\t.section\t.text\n");
/* This code exists so that we can put all externs before all symbol
@@ -5327,7 +5360,7 @@ mips_asm_file_end (file)
fatal_io_error (temp_filename);
while ((len = fread (buffer, 1, sizeof (buffer), asm_out_text_file)) > 0)
- if (fwrite (buffer, 1, len, file) != len)
+ if ((int) fwrite (buffer, 1, len, file) != len)
pfatal_with_name (asm_file_name);
if (len < 0)
@@ -5540,7 +5573,11 @@ compute_frame_size (size)
fp_bits = 3;
}
- for (regno = FP_REG_FIRST; regno <= FP_REG_LAST; regno += fp_inc)
+ /* This loop must iterate over the same space as its companion in
+ save_restore_regs. */
+ for (regno = (FP_REG_LAST - fp_inc + 1);
+ regno >= FP_REG_FIRST;
+ regno -= fp_inc)
{
if (regs_ever_live[regno] && !call_used_regs[regno])
{
@@ -5557,7 +5594,8 @@ compute_frame_size (size)
The gp reg is callee saved in the 64 bit ABI, so all routines must
save the gp reg. This is not a leaf routine if -p, because of the
call to mcount. */
- if (total_size == extra_size && (mips_abi == ABI_32 || mips_abi == ABI_EABI)
+ if (total_size == extra_size
+ && (mips_abi == ABI_32 || mips_abi == ABI_O64 || mips_abi == ABI_EABI)
&& ! profile_flag)
total_size = extra_size = 0;
else if (TARGET_ABICALLS)
@@ -5572,7 +5610,7 @@ compute_frame_size (size)
/* Add in space reserved on the stack by the callee for storing arguments
passed in registers. */
- if (mips_abi != ABI_32)
+ if (mips_abi != ABI_32 && mips_abi != ABI_O64)
total_size += MIPS_STACK_ALIGN (current_function_pretend_args_size);
/* The entry pseudo instruction will allocate 32 bytes on the stack. */
@@ -5764,7 +5802,7 @@ save_restore_insns (store_p, large_reg, large_offset, file)
else
{
fprintf (file, "\tli\t%s,0x%.08lx\t# ",
- reg_names[MIPS_TEMP2_REGNUM], base_offset);
+ reg_names[MIPS_TEMP2_REGNUM], (long) base_offset);
fprintf (file, HOST_WIDE_INT_PRINT_DEC, base_offset);
fprintf (file, "\n\t%s\t%s,%s,%s\n",
Pmode == DImode ? "daddu" : "addu",
@@ -5827,7 +5865,8 @@ save_restore_insns (store_p, large_reg, large_offset, file)
insn = emit_move_insn (mem_rtx, reg_rtx);
RTX_FRAME_RELATED_P (insn) = 1;
}
- else if (!TARGET_ABICALLS || mips_abi != ABI_32
+ else if (!TARGET_ABICALLS
+ || (mips_abi != ABI_32 && mips_abi != ABI_O64)
|| regno != (PIC_OFFSET_TABLE_REGNUM - GP_REG_FIRST))
{
emit_move_insn (reg_rtx, mem_rtx);
@@ -5840,7 +5879,8 @@ save_restore_insns (store_p, large_reg, large_offset, file)
}
else
{
- if (store_p || !TARGET_ABICALLS || mips_abi != ABI_32
+ if (store_p || !TARGET_ABICALLS
+ || (mips_abi != ABI_32 && mips_abi != ABI_O64)
|| regno != (PIC_OFFSET_TABLE_REGNUM - GP_REG_FIRST))
{
int r = regno;
@@ -5981,7 +6021,7 @@ save_restore_insns (store_p, large_reg, large_offset, file)
else
{
fprintf (file, "\tli\t%s,0x%.08lx\t# ",
- reg_names[MIPS_TEMP2_REGNUM], base_offset);
+ reg_names[MIPS_TEMP2_REGNUM], (long) base_offset);
fprintf (file, HOST_WIDE_INT_PRINT_DEC, base_offset);
fprintf (file, "\n\t%s\t%s,%s,%s\n",
Pmode == DImode ? "daddu" : "addu",
@@ -5991,7 +6031,11 @@ save_restore_insns (store_p, large_reg, large_offset, file)
}
}
- for (regno = FP_REG_LAST-1; regno >= FP_REG_FIRST; regno -= fp_inc)
+ /* This loop must iterate over the same space as its companion in
+ compute_frame_size. */
+ for (regno = (FP_REG_LAST - fp_inc + 1);
+ regno >= FP_REG_FIRST;
+ regno -= fp_inc)
if (BITSET_P (fmask, regno - FP_REG_FIRST))
{
if (file == 0)
@@ -6078,22 +6122,31 @@ function_prologue (file, size)
if (!flag_inhibit_size_directive)
{
+ /* .frame FRAMEREG, FRAMESIZE, RETREG */
fprintf (file,
"\t.frame\t%s,%ld,%s\t\t# vars= %ld, regs= %d/%d, args= %d, extra= %ld\n",
(reg_names[(frame_pointer_needed)
? HARD_FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM]),
- tsize, reg_names[31 + GP_REG_FIRST],
+ ((frame_pointer_needed && TARGET_MIPS16)
+ ? (tsize - current_function_outgoing_args_size)
+ : tsize),
+ reg_names[31 + GP_REG_FIRST],
current_frame_info.var_size,
current_frame_info.num_gp,
current_frame_info.num_fp,
current_function_outgoing_args_size,
current_frame_info.extra_size);
+ /* .mask MASK, GPOFFSET; .fmask FPOFFSET */
fprintf (file, "\t.mask\t0x%08lx,%ld\n\t.fmask\t0x%08lx,%ld\n",
current_frame_info.mask,
current_frame_info.gp_save_offset,
current_frame_info.fmask,
current_frame_info.fp_save_offset);
+
+ /* Require:
+ OLD_SP == *FRAMEREG + FRAMESIZE => can find old_sp from nominated FP reg.
+ HIGHEST_GP_SAVED == *FRAMEREG + FRAMESIZE + GPOFFSET => can find saved regs. */
}
if (mips_entry && ! mips_can_use_return_insn ())
@@ -6211,7 +6264,7 @@ function_prologue (file, size)
fprintf (file, "\n");
}
- if (TARGET_ABICALLS && mips_abi == ABI_32)
+ if (TARGET_ABICALLS && (mips_abi == ABI_32 || mips_abi == ABI_O64))
{
char *sp_str = reg_names[STACK_POINTER_REGNUM];
@@ -6339,7 +6392,7 @@ mips_expand_prologue ()
/* If this function is a varargs function, store any registers that
would normally hold arguments ($4 - $7) on the stack. */
- if (mips_abi == ABI_32
+ if ((mips_abi == ABI_32 || mips_abi == ABI_O64)
&& (! mips_entry || mips_can_use_return_insn ())
&& ((TYPE_ARG_TYPES (fntype) != 0
&& (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
@@ -6452,7 +6505,7 @@ mips_expand_prologue ()
/* If we are doing svr4-abi, sp move is done by
function_prologue. In mips16 mode with a large frame, we
save the registers before adjusting the stack. */
- if ((!TARGET_ABICALLS || mips_abi != ABI_32)
+ if ((!TARGET_ABICALLS || (mips_abi != ABI_32 && mips_abi != ABI_O64))
&& (!TARGET_MIPS16 || tsize <= 32767))
{
rtx insn;
@@ -6499,7 +6552,7 @@ mips_expand_prologue ()
else if (reg_18_save != NULL_RTX)
emit_insn (reg_18_save);
- if ((!TARGET_ABICALLS || mips_abi != ABI_32)
+ if ((!TARGET_ABICALLS || (mips_abi != ABI_32 && mips_abi != ABI_O64))
&& TARGET_MIPS16
&& tsize > 32767)
{
@@ -6530,7 +6583,7 @@ mips_expand_prologue ()
instructions when using the frame pointer by pointing the
frame pointer ahead of the argument space allocated on
the stack. */
- if ((! TARGET_ABICALLS || mips_abi != ABI_32)
+ if ((! TARGET_ABICALLS || (mips_abi != ABI_32 && mips_abi != ABI_O64))
&& TARGET_MIPS16
&& tsize > 32767)
{
@@ -6573,7 +6626,7 @@ mips_expand_prologue ()
RTX_FRAME_RELATED_P (insn) = 1;
}
- if (TARGET_ABICALLS && mips_abi != ABI_32)
+ if (TARGET_ABICALLS && (mips_abi != ABI_32 && mips_abi != ABI_O64))
emit_insn (gen_loadgp (XEXP (DECL_RTL (current_function_decl), 0),
gen_rtx (REG, DImode, 25)));
}
@@ -6757,7 +6810,7 @@ mips_expand_epilogue ()
/* The GP/PIC register is implicitly used by all SYMBOL_REFs, so if we
are going to restore it, then we must emit a blockage insn to
prevent the scheduler from moving the restore out of the epilogue. */
- else if (TARGET_ABICALLS && mips_abi != ABI_32
+ else if (TARGET_ABICALLS && mips_abi != ABI_32 && mips_abi != ABI_O64
&& (current_frame_info.mask
& (1L << (PIC_OFFSET_TABLE_REGNUM - GP_REG_FIRST))))
emit_insn (gen_blockage ());
@@ -6856,7 +6909,16 @@ mips_select_rtx_section (mode, x)
}
/* Choose the section to use for DECL. RELOC is true if its value contains
- any relocatable expression. */
+ any relocatable expression.
+
+ Some of the logic used here needs to be replicated in
+ ENCODE_SECTION_INFO in mips.h so that references to these symbols
+ are done correctly. Specifically, at least all symbols assigned
+ here to rom (.text and/or .rodata) must not be referenced via
+ ENCODE_SECTION_INFO with %gprel, as the rom might be too far away.
+
+ If you need to make a change here, you probably should check
+ ENCODE_SECTION_INFO to see if it needs a similar change. */
void
mips_select_section (decl, reloc)
@@ -6950,7 +7012,9 @@ mips_function_value (valtype, func)
}
else if (TREE_CODE (valtype) == RECORD_TYPE
- && mips_abi != ABI_32 && mips_abi != ABI_EABI)
+ && mips_abi != ABI_32
+ && mips_abi != ABI_O64
+ && mips_abi != ABI_EABI)
{
/* A struct with only one or two floating point fields is returned in
the floating point registers. */
@@ -7408,12 +7472,12 @@ mips16_fp_args (file, fp_code, from_fp_p)
int fp_code;
int from_fp_p;
{
- char *s;
+ const char *s;
int gparg, fparg;
unsigned int f;
- /* This code only works for the original 32 bit ABI. */
- if (mips_abi != ABI_32)
+ /* This code only works for the original 32 bit ABI and the O64 ABI. */
+ if (mips_abi != ABI_32 && mips_abi != ABI_O64)
abort ();
if (from_fp_p)
@@ -7440,9 +7504,14 @@ mips16_fp_args (file, fp_code, from_fp_p)
{
if ((fparg & 1) != 0)
++fparg;
- fprintf (file, "\t%s\t%s,%s\n\t%s\t%s,%s\n", s,
- reg_names[gparg], reg_names[fparg + 1], s,
- reg_names[gparg + 1], reg_names[fparg]);
+ if (TARGET_BIG_ENDIAN)
+ fprintf (file, "\t%s\t%s,%s\n\t%s\t%s,%s\n", s,
+ reg_names[gparg], reg_names[fparg + 1], s,
+ reg_names[gparg + 1], reg_names[fparg]);
+ else
+ fprintf (file, "\t%s\t%s,%s\n\t%s\t%s,%s\n", s,
+ reg_names[gparg], reg_names[fparg], s,
+ reg_names[gparg + 1], reg_names[fparg + 1]);
++gparg;
++fparg;
}
@@ -7610,9 +7679,9 @@ build_mips16_call_stub (retval, fnmem, arg_size, fp_code)
&& strncmp (XSTR (fn, 0), "__mips16_", 9) == 0)
return 0;
- /* This code will only work for the standard ABI. The other ABI's
+ /* This code will only work for o32 and o64 abis. The other ABI's
require more sophisticated support. */
- if (mips_abi != ABI_32)
+ if (mips_abi != ABI_32 && mips_abi != ABI_O64)
abort ();
/* We can only handle SFmode and DFmode floating point return
@@ -7783,12 +7852,24 @@ build_mips16_call_stub (retval, fnmem, arg_size, fp_code)
reg_names[GP_REG_FIRST + 2], reg_names[FP_REG_FIRST + 0]);
else
{
- fprintf (asm_out_file, "\tmfc1\t%s,%s\n",
- reg_names[GP_REG_FIRST + 2],
- reg_names[FP_REG_FIRST + 1]);
- fprintf (asm_out_file, "\tmfc1\t%s,%s\n",
- reg_names[GP_REG_FIRST + 3],
- reg_names[FP_REG_FIRST + 0]);
+ if (TARGET_BIG_ENDIAN)
+ {
+ fprintf (asm_out_file, "\tmfc1\t%s,%s\n",
+ reg_names[GP_REG_FIRST + 2],
+ reg_names[FP_REG_FIRST + 1]);
+ fprintf (asm_out_file, "\tmfc1\t%s,%s\n",
+ reg_names[GP_REG_FIRST + 3],
+ reg_names[FP_REG_FIRST + 0]);
+ }
+ else
+ {
+ fprintf (asm_out_file, "\tmfc1\t%s,%s\n",
+ reg_names[GP_REG_FIRST + 2],
+ reg_names[FP_REG_FIRST + 0]);
+ fprintf (asm_out_file, "\tmfc1\t%s,%s\n",
+ reg_names[GP_REG_FIRST + 3],
+ reg_names[FP_REG_FIRST + 1]);
+ }
}
fprintf (asm_out_file, "\tj\t%s\n", reg_names[GP_REG_FIRST + 18]);
/* As above, we can't fill the delay slot. */
diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h
index 72e77b01398..4358a703283 100644
--- a/gcc/config/mips/mips.h
+++ b/gcc/config/mips/mips.h
@@ -1,5 +1,5 @@
/* Definitions of target machine for GNU compiler. MIPS version.
- Copyright (C) 1989, 90-97, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1989, 90-98, 1999 Free Software Foundation, Inc.
Contributed by A. Lichnewsky (lich@inria.inria.fr).
Changed by Michael Meissner (meissner@osf.org).
64 bit r4000 support by Ian Lance Taylor (ian@cygnus.com) and
@@ -76,12 +76,16 @@ enum processor_type {
#define mips_cpu_attr ((enum attr_cpu)mips_cpu)
/* Which ABI to use. These are constants because abi64.h must check their
- value at preprocessing time. */
+ value at preprocessing time.
+
+ ABI_32 (original 32, or o32), ABI_N32 (n32), ABI_64 (n64) are all
+ defined by SGI. ABI_O64 is o32 extended to work on a 64 bit machine. */
#define ABI_32 0
#define ABI_N32 1
#define ABI_64 2
#define ABI_EABI 3
+#define ABI_O64 4
#ifndef MIPS_ABI_DEFAULT
/* We define this away so that there is no extra runtime cost if the target
@@ -112,7 +116,7 @@ enum block_move_type {
extern char mips_reg_names[][8]; /* register names (a0 vs. $4). */
extern char mips_print_operand_punct[]; /* print_operand punctuation chars */
-extern char *current_function_file; /* filename current function is in */
+extern const char *current_function_file; /* filename current function is in */
extern int num_source_filenames; /* current .file # */
extern int inside_function; /* != 0 if inside of a function */
extern int ignore_line_number; /* != 0 if we are to ignore next .loc */
@@ -137,11 +141,12 @@ extern int mips_isa; /* architectural level */
extern int mips16; /* whether generating mips16 code */
extern int mips16_hard_float; /* mips16 without -msoft-float */
extern int mips_entry; /* generate entry/exit for mips16 */
-extern char *mips_cpu_string; /* for -mcpu=<xxx> */
-extern char *mips_isa_string; /* for -mips{1,2,3,4} */
-extern char *mips_abi_string; /* for -mabi={32,n32,64} */
-extern char *mips_entry_string; /* for -mentry */
-extern char *mips_no_mips16_string; /* for -mno-mips16 */
+extern const char *mips_cpu_string; /* for -mcpu=<xxx> */
+extern const char *mips_isa_string; /* for -mips{1,2,3,4} */
+extern const char *mips_abi_string; /* for -mabi={32,n32,64} */
+extern const char *mips_entry_string; /* for -mentry */
+extern const char *mips_no_mips16_string;/* for -mno-mips16 */
+extern const char *mips_explicit_type_size_string;/* for -mexplicit-type-size */
extern int mips_split_addresses; /* perform high/lo_sum support */
extern int dslots_load_total; /* total # load related delay slots */
extern int dslots_load_filled; /* # filled load delay slots */
@@ -174,7 +179,6 @@ extern struct rtx_def *mips16_gp_pseudo_rtx; /* psuedo reg holding $gp */
#endif
-extern void abort_with_insn ();
extern int arith32_operand ();
extern int arith_operand ();
extern int cmp_op ();
@@ -208,20 +212,21 @@ extern void mips_expand_epilogue ();
extern void mips_expand_prologue ();
extern int mips_check_split ();
extern char *mips_fill_delay_slot ();
-extern char *mips_move_1word ();
-extern char *mips_move_2words ();
+extern const char *mips_move_1word ();
+extern const char *mips_move_2words ();
extern void mips_output_double ();
extern int mips_output_external ();
extern void mips_output_float ();
extern void mips_output_filename ();
extern void mips_output_lineno ();
-extern char *output_block_move ();
+extern const char *output_block_move ();
extern void override_options ();
extern int pc_or_label_operand ();
extern void print_operand_address ();
extern void print_operand ();
extern void print_options ();
extern int reg_or_0_operand ();
+extern int true_reg_or_0_operand ();
extern int simple_epilogue_p ();
extern int simple_memory_operand ();
extern int double_memory_operand ();
@@ -311,7 +316,7 @@ extern void mips_select_section ();
/* Bits for real switches */
#define MASK_INT64 0x00000001 /* ints are 64 bits */
-#define MASK_LONG64 0x00000002 /* longs and pointers are 64 bits */
+#define MASK_LONG64 0x00000002 /* longs are 64 bits */
#define MASK_SPLIT_ADDR 0x00000004 /* Address splitting is enabled. */
#define MASK_GPOPT 0x00000008 /* Optimize for global pointer */
#define MASK_GAS 0x00000010 /* Gas used instead of MIPS as */
@@ -332,16 +337,18 @@ extern void mips_select_section ();
#define MASK_4300_MUL_FIX 0x00080000 /* Work-around early Vr4300 CPU bug */
#define MASK_MIPS3900 0x00100000 /* like -mips1 only 3900 */
#define MASK_MIPS16 0x01000000 /* Generate mips16 code */
+#define MASK_NO_CHECK_ZERO_DIV 0x04000000 /* divide by zero checking */
+#define MASK_CHECK_RANGE_DIV 0x08000000 /* divide result range checking */
/* Dummy switches used only in spec's*/
#define MASK_MIPS_TFILE 0x00000000 /* flag for mips-tfile usage */
/* Debug switches, not documented */
-#define MASK_DEBUG 0x40000000 /* Eliminate version # in .s file */
-#define MASK_DEBUG_A 0x20000000 /* don't allow <label>($reg) addrs */
-#define MASK_DEBUG_B 0x10000000 /* GO_IF_LEGITIMATE_ADDRESS debug */
-#define MASK_DEBUG_C 0x08000000 /* don't expand seq, etc. */
-#define MASK_DEBUG_D 0x04000000 /* don't do define_split's */
+#define MASK_DEBUG 0 /* Eliminate version # in .s file */
+#define MASK_DEBUG_A 0x40000000 /* don't allow <label>($reg) addrs */
+#define MASK_DEBUG_B 0x20000000 /* GO_IF_LEGITIMATE_ADDRESS debug */
+#define MASK_DEBUG_C 0x10000000 /* don't expand seq, etc. */
+#define MASK_DEBUG_D 0 /* don't do define_split's */
#define MASK_DEBUG_E 0 /* function_arg debug */
#define MASK_DEBUG_F 0
#define MASK_DEBUG_G 0 /* don't support 64 bit arithmetic */
@@ -421,6 +428,9 @@ extern void mips_select_section ();
#define TARGET_4300_MUL_FIX (target_flags & MASK_4300_MUL_FIX)
+#define TARGET_NO_CHECK_ZERO_DIV (target_flags & MASK_NO_CHECK_ZERO_DIV)
+#define TARGET_CHECK_RANGE_DIV (target_flags & MASK_CHECK_RANGE_DIV)
+
/* This is true if we must enable the assembly language file switching
code. */
@@ -442,64 +452,129 @@ extern void mips_select_section ();
#define TARGET_SWITCHES \
{ \
- {"int64", MASK_INT64 | MASK_LONG64}, \
- {"long64", MASK_LONG64}, \
- {"split-addresses", MASK_SPLIT_ADDR}, \
- {"no-split-addresses", -MASK_SPLIT_ADDR}, \
- {"mips-as", -MASK_GAS}, \
- {"gas", MASK_GAS}, \
- {"rnames", MASK_NAME_REGS}, \
- {"no-rnames", -MASK_NAME_REGS}, \
- {"gpOPT", MASK_GPOPT}, \
- {"gpopt", MASK_GPOPT}, \
- {"no-gpOPT", -MASK_GPOPT}, \
- {"no-gpopt", -MASK_GPOPT}, \
- {"stats", MASK_STATS}, \
- {"no-stats", -MASK_STATS}, \
- {"memcpy", MASK_MEMCPY}, \
- {"no-memcpy", -MASK_MEMCPY}, \
- {"mips-tfile", MASK_MIPS_TFILE}, \
- {"no-mips-tfile", -MASK_MIPS_TFILE}, \
- {"soft-float", MASK_SOFT_FLOAT}, \
- {"hard-float", -MASK_SOFT_FLOAT}, \
- {"fp64", MASK_FLOAT64}, \
- {"fp32", -MASK_FLOAT64}, \
- {"gp64", MASK_64BIT}, \
- {"gp32", -MASK_64BIT}, \
- {"abicalls", MASK_ABICALLS}, \
- {"no-abicalls", -MASK_ABICALLS}, \
- {"half-pic", MASK_HALF_PIC}, \
- {"no-half-pic", -MASK_HALF_PIC}, \
- {"long-calls", MASK_LONG_CALLS}, \
- {"no-long-calls", -MASK_LONG_CALLS}, \
- {"embedded-pic", MASK_EMBEDDED_PIC}, \
- {"no-embedded-pic", -MASK_EMBEDDED_PIC}, \
- {"embedded-data", MASK_EMBEDDED_DATA}, \
- {"no-embedded-data", -MASK_EMBEDDED_DATA}, \
- {"eb", MASK_BIG_ENDIAN}, \
- {"el", -MASK_BIG_ENDIAN}, \
- {"single-float", MASK_SINGLE_FLOAT}, \
- {"double-float", -MASK_SINGLE_FLOAT}, \
- {"mad", MASK_MAD}, \
- {"no-mad", -MASK_MAD}, \
- {"fix4300", MASK_4300_MUL_FIX}, \
- {"no-fix4300", -MASK_4300_MUL_FIX}, \
- {"4650", MASK_MAD | MASK_SINGLE_FLOAT}, \
- {"3900", MASK_MIPS3900}, \
- {"debug", MASK_DEBUG}, \
- {"debuga", MASK_DEBUG_A}, \
- {"debugb", MASK_DEBUG_B}, \
- {"debugc", MASK_DEBUG_C}, \
- {"debugd", MASK_DEBUG_D}, \
- {"debuge", MASK_DEBUG_E}, \
- {"debugf", MASK_DEBUG_F}, \
- {"debugg", MASK_DEBUG_G}, \
- {"debugh", MASK_DEBUG_H}, \
- {"debugi", MASK_DEBUG_I}, \
+ {"int64", MASK_INT64 | MASK_LONG64, \
+ "Use 64-bit int type"}, \
+ {"long64", MASK_LONG64, \
+ "Use 64-bit long type"}, \
+ {"long32", -(MASK_LONG64 | MASK_INT64), \
+ "Use 32-bit long type"}, \
+ {"split-addresses", MASK_SPLIT_ADDR, \
+ "Optimize lui/addiu address loads"}, \
+ {"no-split-addresses", -MASK_SPLIT_ADDR, \
+ "Don't optimize lui/addiu address loads"}, \
+ {"mips-as", -MASK_GAS, \
+ "Use MIPS as"}, \
+ {"gas", MASK_GAS, \
+ "Use GNU as"}, \
+ {"rnames", MASK_NAME_REGS, \
+ "Use symbolic register names"}, \
+ {"no-rnames", -MASK_NAME_REGS, \
+ "Don't use symbolic register names"}, \
+ {"gpOPT", MASK_GPOPT, \
+ "Use GP relative sdata/sbss sections"}, \
+ {"gpopt", MASK_GPOPT, \
+ "Use GP relative sdata/sbss sections"}, \
+ {"no-gpOPT", -MASK_GPOPT, \
+ "Don't use GP relative sdata/sbss sections"}, \
+ {"no-gpopt", -MASK_GPOPT, \
+ "Don't use GP relative sdata/sbss sections"}, \
+ {"stats", MASK_STATS, \
+ "Output compiler statistics"}, \
+ {"no-stats", -MASK_STATS, \
+ "Don't output compiler statistics"}, \
+ {"memcpy", MASK_MEMCPY, \
+ "Don't optimize block moves"}, \
+ {"no-memcpy", -MASK_MEMCPY, \
+ "Optimize block moves"}, \
+ {"mips-tfile", MASK_MIPS_TFILE, \
+ "Use mips-tfile asm postpass"}, \
+ {"no-mips-tfile", -MASK_MIPS_TFILE, \
+ "Don't use mips-tfile asm postpass"}, \
+ {"soft-float", MASK_SOFT_FLOAT, \
+ "Use software floating point"}, \
+ {"hard-float", -MASK_SOFT_FLOAT, \
+ "Use hardware floating point"}, \
+ {"fp64", MASK_FLOAT64, \
+ "Use 64-bit FP registers"}, \
+ {"fp32", -MASK_FLOAT64, \
+ "Use 32-bit FP registers"}, \
+ {"gp64", MASK_64BIT, \
+ "Use 64-bit general registers"}, \
+ {"gp32", -MASK_64BIT, \
+ "Use 32-bit general registers"}, \
+ {"abicalls", MASK_ABICALLS, \
+ "Use Irix PIC"}, \
+ {"no-abicalls", -MASK_ABICALLS, \
+ "Don't use Irix PIC"}, \
+ {"half-pic", MASK_HALF_PIC, \
+ "Use OSF PIC"}, \
+ {"no-half-pic", -MASK_HALF_PIC, \
+ "Don't use OSF PIC"}, \
+ {"long-calls", MASK_LONG_CALLS, \
+ "Use indirect calls"}, \
+ {"no-long-calls", -MASK_LONG_CALLS, \
+ "Don't use indirect calls"}, \
+ {"embedded-pic", MASK_EMBEDDED_PIC, \
+ "Use embedded PIC"}, \
+ {"no-embedded-pic", -MASK_EMBEDDED_PIC, \
+ "Don't use embedded PIC"}, \
+ {"embedded-data", MASK_EMBEDDED_DATA, \
+ "Use ROM instead of RAM"}, \
+ {"no-embedded-data", -MASK_EMBEDDED_DATA, \
+ "Don't use ROM instead of RAM"}, \
+ {"eb", MASK_BIG_ENDIAN, \
+ "Use big-endian byte order"}, \
+ {"el", -MASK_BIG_ENDIAN, \
+ "Use little-endian byte order"}, \
+ {"single-float", MASK_SINGLE_FLOAT, \
+ "Use single (32-bit) FP only"}, \
+ {"double-float", -MASK_SINGLE_FLOAT, \
+ "Don't use single (32-bit) FP only"}, \
+ {"mad", MASK_MAD, \
+ "Use multiply accumulate"}, \
+ {"no-mad", -MASK_MAD, \
+ "Don't use multiply accumulate"}, \
+ {"fix4300", MASK_4300_MUL_FIX, \
+ "Work around early 4300 hardware bug"}, \
+ {"no-fix4300", -MASK_4300_MUL_FIX, \
+ "Don't work around early 4300 hardware bug"}, \
+ {"4650", MASK_MAD | MASK_SINGLE_FLOAT, \
+ "Optimize for 4650"}, \
+ {"3900", MASK_MIPS3900, \
+ "Optimize for 3900"}, \
+ {"check-zero-division",-MASK_NO_CHECK_ZERO_DIV, \
+ "Trap on integer divide by zero"}, \
+ {"no-check-zero-division", MASK_NO_CHECK_ZERO_DIV, \
+ "Don't trap on integer divide by zero"}, \
+ {"check-range-division",MASK_CHECK_RANGE_DIV, \
+ "Trap on integer divide overflow"}, \
+ {"no-check-range-division",-MASK_CHECK_RANGE_DIV, \
+ "Don't trap on integer divide overflow"}, \
+ {"debug", MASK_DEBUG, \
+ NULL}, \
+ {"debuga", MASK_DEBUG_A, \
+ NULL}, \
+ {"debugb", MASK_DEBUG_B, \
+ NULL}, \
+ {"debugc", MASK_DEBUG_C, \
+ NULL}, \
+ {"debugd", MASK_DEBUG_D, \
+ NULL}, \
+ {"debuge", MASK_DEBUG_E, \
+ NULL}, \
+ {"debugf", MASK_DEBUG_F, \
+ NULL}, \
+ {"debugg", MASK_DEBUG_G, \
+ NULL}, \
+ {"debugh", MASK_DEBUG_H, \
+ NULL}, \
+ {"debugi", MASK_DEBUG_I, \
+ NULL}, \
{"", (TARGET_DEFAULT \
| TARGET_CPU_DEFAULT \
- | TARGET_ENDIAN_DEFAULT)} \
-}
+ | TARGET_ENDIAN_DEFAULT), \
+ NULL}, \
+}
/* Default target_flags if no switches are specified */
@@ -560,10 +635,16 @@ extern void mips_select_section ();
#define TARGET_OPTIONS \
{ \
SUBTARGET_TARGET_OPTIONS \
- { "cpu=", &mips_cpu_string }, \
- { "ips", &mips_isa_string }, \
- { "entry", &mips_entry_string }, \
- { "no-mips16", &mips_no_mips16_string } \
+ { "cpu=", &mips_cpu_string, \
+ "Specify CPU for scheduling purposes"}, \
+ { "ips", &mips_isa_string, \
+ "Specify MIPS ISA"}, \
+ { "entry", &mips_entry_string, \
+ "Use mips16 entry/exit psuedo ops"}, \
+ { "no-mips16", &mips_no_mips16_string, \
+ "Don't use MIPS16 instructions"}, \
+ { "explicit-type-size", &mips_explicit_type_size_string, \
+ NULL}, \
}
/* This is meant to be redefined in the host dependent files. */
@@ -875,6 +956,7 @@ while (0)
%{mips4:%{!msingle-float:%{!m4650:-mfp64}} -mgp64} \
%{mfp64:%{msingle-float:%emay not use both -mfp64 and -msingle-float}} \
%{mfp64:%{m4650:%emay not use both -mfp64 and -m4650}} \
+%{mint64|mlong64|mlong32:-mexplicit-type-size }\
%{m4650:-mcpu=r4650} \
%{m3900:-mips1 -mcpu=r3900 -mfp32 -mgp32} \
%{G*} %{EB:-meb} %{EL:-mel} %{EB:%{EL:%emay not use both -EB and -EL}} \
@@ -893,7 +975,7 @@ while (0)
#ifndef SUBTARGET_CPP_SIZE_SPEC
#define SUBTARGET_CPP_SIZE_SPEC "\
-%{mlong64:-D__SIZE_TYPE__=long\\ unsigned\\ int -D__PTRDIFF_TYPE__=long\\ int} \
+%{mlong64:%{!mips1:%{!mips2:-D__SIZE_TYPE__=long\\ unsigned\\ int -D__PTRDIFF_TYPE__=long\\ int}}} \
%{!mlong64:-D__SIZE_TYPE__=unsigned\\ int -D__PTRDIFF_TYPE__=int}"
#endif
@@ -907,7 +989,7 @@ while (0)
correctly. Similarly for 64bit ints and __INT_MAX__. */
#ifndef LONG_MAX_SPEC
#if ((TARGET_DEFAULT | TARGET_CPU_DEFAULT) & MASK_LONG64)
-#define LONG_MAX_SPEC "%{!mno-long64:-D__LONG_MAX__=9223372036854775807L}"
+#define LONG_MAX_SPEC "%{!mlong32:-D__LONG_MAX__=9223372036854775807L}"
#else
#define LONG_MAX_SPEC "%{mlong64:-D__LONG_MAX__=9223372036854775807L}"
#endif
@@ -957,7 +1039,7 @@ while (0)
{ "mips_as_asm_spec", MIPS_AS_ASM_SPEC }, \
{ "gas_asm_spec", GAS_ASM_SPEC }, \
{ "target_asm_spec", TARGET_ASM_SPEC }, \
- { "subtarget_mips_as_asm_spec", SUBTARGET_MIPS_AS_ASM_SPEC }, \
+ { "subtarget_mips_as_asm_spec", SUBTARGET_MIPS_AS_ASM_SPEC }, \
{ "subtarget_asm_optimizing_spec", SUBTARGET_ASM_OPTIMIZING_SPEC }, \
{ "subtarget_asm_debugging_spec", SUBTARGET_ASM_DEBUGGING_SPEC }, \
{ "subtarget_asm_spec", SUBTARGET_ASM_SPEC }, \
@@ -1331,7 +1413,7 @@ do { \
/* Width in bits of a pointer.
See also the macro `Pmode' defined below. */
#ifndef POINTER_SIZE
-#define POINTER_SIZE (TARGET_LONG64 ? 64 : 32)
+#define POINTER_SIZE (Pmode == DImode ? 64 : 32)
#endif
/* Allocation boundary (in *bits*) for storing pointers in memory. */
@@ -1430,8 +1512,13 @@ do { \
/* Define if loading in MODE, an integral mode narrower than BITS_PER_WORD
will either zero-extend or sign-extend. The value of this macro should
be the code that says which one of the two operations is implicitly
- done, NIL if none. */
-#define LOAD_EXTEND_OP(MODE) ZERO_EXTEND
+ done, NIL if none.
+
+ When in 64 bit mode, mips_move_1word will sign extend SImode and CCmode
+ moves. All other referces are zero extended. */
+#define LOAD_EXTEND_OP(MODE) \
+ (TARGET_64BIT && ((MODE) == SImode || (MODE) == CCmode) \
+ ? SIGN_EXTEND : ZERO_EXTEND)
/* Define this macro if it is advisable to hold scalars in registers
in a wider mode than that declared by the program. In such cases,
@@ -2140,6 +2227,7 @@ extern struct mips_frame_info current_frame_info;
{ RETURN_ADDRESS_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
{ RETURN_ADDRESS_POINTER_REGNUM, GP_REG_FIRST + 30}, \
{ RETURN_ADDRESS_POINTER_REGNUM, GP_REG_FIRST + 17}, \
+ { RETURN_ADDRESS_POINTER_REGNUM, GP_REG_FIRST + 31}, \
{ FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
{ FRAME_POINTER_REGNUM, GP_REG_FIRST + 30}, \
{ FRAME_POINTER_REGNUM, GP_REG_FIRST + 17}}
@@ -2165,11 +2253,14 @@ extern struct mips_frame_info current_frame_info;
*/
#define CAN_ELIMINATE(FROM, TO) \
- ((TO) == HARD_FRAME_POINTER_REGNUM \
+ (((FROM) == RETURN_ADDRESS_POINTER_REGNUM && (! leaf_function_p () \
+ || (TO == GP_REG_FIRST + 31 && leaf_function_p))) \
+ || ((FROM) != RETURN_ADDRESS_POINTER_REGNUM \
+ && ((TO) == HARD_FRAME_POINTER_REGNUM \
|| ((TO) == STACK_POINTER_REGNUM && ! frame_pointer_needed \
&& ! (TARGET_MIPS16 && TARGET_64BIT) \
&& (! TARGET_MIPS16 \
- || compute_frame_size (get_frame_size ()) < 32768)))
+ || compute_frame_size (get_frame_size ()) < 32768)))))
/* This macro is similar to `INITIAL_FRAME_POINTER_OFFSET'. It
specifies the initial difference between the specified pair of
@@ -2187,20 +2278,28 @@ extern struct mips_frame_info current_frame_info;
&& (TO) == HARD_FRAME_POINTER_REGNUM) \
(OFFSET) = (current_frame_info.total_size \
- current_function_outgoing_args_size \
- - ((mips_abi != ABI_32 && mips_abi != ABI_EABI) \
+ - ((mips_abi != ABI_32 \
+ && mips_abi != ABI_O64 \
+ && mips_abi != ABI_EABI) \
? current_function_pretend_args_size \
: 0)); \
else if ((FROM) == ARG_POINTER_REGNUM) \
(OFFSET) = (current_frame_info.total_size \
- - ((mips_abi != ABI_32 && mips_abi != ABI_EABI) \
+ - ((mips_abi != ABI_32 \
+ && mips_abi != ABI_O64 \
+ && mips_abi != ABI_EABI) \
? current_function_pretend_args_size \
: 0)); \
/* Some ABIs store 64 bits to the stack, but Pmode is 32 bits, \
so we must add 4 bytes to the offset to get the right value. */ \
else if ((FROM) == RETURN_ADDRESS_POINTER_REGNUM) \
- (OFFSET) = current_frame_info.gp_sp_offset \
+ { \
+ if (leaf_function_p ()) \
+ (OFFSET) = 0; \
+ else (OFFSET) = current_frame_info.gp_sp_offset \
+ ((UNITS_PER_WORD - (POINTER_SIZE / BITS_PER_UNIT)) \
* (BYTES_BIG_ENDIAN != 0)); \
+ } \
}
/* If we generate an insn to push BYTES bytes,
@@ -2470,7 +2569,7 @@ typedef struct mips_args {
#define FUNCTION_ARG_BOUNDARY(MODE, TYPE) \
(((TYPE) != 0) \
- ? ((TYPE_ALIGN(TYPE) <= PARM_BOUNDARY) \
+ ? ((TYPE_ALIGN(TYPE) <= (unsigned)PARM_BOUNDARY) \
? PARM_BOUNDARY \
: TYPE_ALIGN(TYPE)) \
: ((GET_MODE_ALIGNMENT(MODE) <= PARM_BOUNDARY) \
@@ -2626,11 +2725,11 @@ typedef struct mips_args {
/* Addressing modes, and classification of registers for them. */
-/* #define HAVE_POST_INCREMENT */
-/* #define HAVE_POST_DECREMENT */
+/* #define HAVE_POST_INCREMENT 0 */
+/* #define HAVE_POST_DECREMENT 0 */
-/* #define HAVE_PRE_DECREMENT */
-/* #define HAVE_PRE_INCREMENT */
+/* #define HAVE_PRE_DECREMENT 0 */
+/* #define HAVE_PRE_INCREMENT 0 */
/* These assume that REGNO is a hard or pseudo reg number.
They give nonzero only if REGNO is a hard reg of the suitable class
@@ -2825,7 +2924,9 @@ typedef struct mips_args {
/* ??? Reject combining an address with a register for the MIPS \
64 bit ABI, because the SGI assembler can not handle this. */ \
if (!TARGET_DEBUG_A_MODE \
- && (mips_abi == ABI_32 || mips_abi == ABI_EABI) \
+ && (mips_abi == ABI_32 \
+ || mips_abi == ABI_O64 \
+ || mips_abi == ABI_EABI) \
&& CONSTANT_ADDRESS_P (xplus1) \
&& ! mips_split_addresses \
&& (!TARGET_EMBEDDED_PIC \
@@ -2856,7 +2957,9 @@ typedef struct mips_args {
|| GET_CODE (X) == CONST_INT || GET_CODE (X) == HIGH \
|| (GET_CODE (X) == CONST \
&& ! (flag_pic && pic_address_needs_scratch (X)) \
- && (mips_abi == ABI_32 || mips_abi == ABI_EABI))) \
+ && (mips_abi == ABI_32 \
+ || mips_abi == ABI_O64 \
+ || mips_abi == ABI_EABI))) \
&& (!HALF_PIC_P () || !HALF_PIC_ADDRESS_P (X)))
/* Define this, so that when PIC, reload won't try to reload invalid
@@ -2876,7 +2979,9 @@ typedef struct mips_args {
((GET_CODE (X) != CONST_DOUBLE \
|| mips_const_double_ok (X, GET_MODE (X))) \
&& ! (GET_CODE (X) == CONST \
- && mips_abi != ABI_32 && mips_abi != ABI_EABI) \
+ && mips_abi != ABI_32 \
+ && mips_abi != ABI_O64 \
+ && mips_abi != ABI_EABI) \
&& (! TARGET_MIPS16 || mips16_constant (X, GET_MODE (X), 0, 0)))
/* A C compound statement that attempts to replace X with a valid
@@ -2939,7 +3044,9 @@ typedef struct mips_args {
if (GET_CODE (xinsn) == CONST \
&& ((flag_pic && pic_address_needs_scratch (xinsn)) \
/* ??? SGI's Irix 6 assembler can't handle CONST. */ \
- || (mips_abi != ABI_32 && mips_abi != ABI_EABI))) \
+ || (mips_abi != ABI_32 \
+ && mips_abi != ABI_O64 \
+ && mips_abi != ABI_EABI))) \
{ \
rtx ptr_reg = gen_reg_rtx (Pmode); \
rtx constant = XEXP (XEXP (xinsn, 0), 1); \
@@ -3049,7 +3156,19 @@ typedef struct mips_args {
gp addresable section, SYMBOL_REF_FLAG is set prevent gcc from
splitting the reference so that gas can generate a gp relative
reference.
- */
+
+ When TARGET_EMBEDDED_DATA is set, we assume that all const
+ variables will be stored in ROM, which is too far from %gp to use
+ %gprel addressing. Note that (1) we include "extern const"
+ variables in this, which mips_select_section doesn't, and (2) we
+ can't always tell if they're really const (they might be const C++
+ objects with non-const constructors), so we err on the side of
+ caution and won't use %gprel anyway (otherwise we'd have to defer
+ this decision to the linker/loader). The handling of extern consts
+ is why the DECL_INITIAL macros differ from mips_select_section.
+
+ If you are changing this macro, you should look at
+ mips_select_section and see if it needs a similar change. */
#define ENCODE_SECTION_INFO(DECL) \
do \
@@ -3063,7 +3182,17 @@ do \
mips_string_length += TREE_STRING_LENGTH (DECL); \
} \
} \
- if (TARGET_EMBEDDED_PIC) \
+ \
+ if (TARGET_EMBEDDED_DATA \
+ && (TREE_CODE (DECL) == VAR_DECL \
+ && TREE_READONLY (DECL) && !TREE_SIDE_EFFECTS (DECL)) \
+ && (!DECL_INITIAL (DECL) \
+ || TREE_CONSTANT (DECL_INITIAL (DECL)))) \
+ { \
+ SYMBOL_REF_FLAG (XEXP (DECL_RTL (DECL), 0)) = 0; \
+ } \
+ \
+ else if (TARGET_EMBEDDED_PIC) \
{ \
if (TREE_CODE (DECL) == VAR_DECL) \
SYMBOL_REF_FLAG (XEXP (DECL_RTL (DECL), 0)) = 1; \
@@ -3180,10 +3309,12 @@ while (0)
/* Specify the machine mode that pointers have.
After generation of rtl, the compiler makes no further distinction
- between pointers and any other objects of this machine mode. */
+ between pointers and any other objects of this machine mode.
+
+ For MIPS we make pointers are the smaller of longs and gp-registers. */
#ifndef Pmode
-#define Pmode (TARGET_LONG64 ? DImode : SImode)
+#define Pmode ((enum machine_mode)((TARGET_LONG64 && TARGET_64BIT) ? DImode : SImode))
#endif
/* A function address in a call instruction
@@ -3557,7 +3688,21 @@ while (0)
that the constraints of the insn are met. Setting a cost of
other than 2 will allow reload to verify that the constraints are
met. You should do this if the `movM' pattern's constraints do
- not allow such copying. */
+ not allow such copying.
+
+ ??? We make make the cost of moving from HI/LO/HILO/MD into general
+ registers the same as for one of moving general registers to
+ HI/LO/HILO/MD for TARGET_MIPS16 in order to prevent allocating a
+ pseudo to HI/LO/HILO/MD. This might hurt optimizations though, it
+ isn't clear if it is wise. And it might not work in all cases. We
+ could solve the DImode LO reg problem by using a multiply, just like
+ reload_{in,out}si. We could solve the SImode/HImode HI reg problem
+ by using divide instructions. divu puts the remainder in the HI
+ reg, so doing a divide by -1 will move the value in the HI reg for
+ all values except -1. We could handle that case by using a signed
+ divide, e.g. -1 / 2 (or maybe 1 / -2?). We'd have to emit a
+ compare/branch to test the input value to see which instruction we
+ need to use. This gets pretty messy, but it is feasible. */
#define REGISTER_MOVE_COST(FROM, TO) \
((FROM) == M16_REGS && GR_REG_CLASS_P (TO) ? 2 \
@@ -3573,7 +3718,7 @@ while (0)
&& ((TO) == M16_REGS || (TO) == M16_NA_REGS)) ? 6 \
: (((FROM) == HI_REG || (FROM) == LO_REG \
|| (FROM) == MD_REGS || (FROM) == HILO_REG) \
- && GR_REG_CLASS_P (TO)) ? (TARGET_MIPS16 ? 8 : 6) \
+ && GR_REG_CLASS_P (TO)) ? (TARGET_MIPS16 ? 12 : 6) \
: (((TO) == HI_REG || (TO) == LO_REG \
|| (TO) == MD_REGS || (TO) == HILO_REG) \
&& GR_REG_CLASS_P (FROM)) ? (TARGET_MIPS16 ? 12 : 6) \
@@ -3637,7 +3782,8 @@ while (0)
{"uns_arith_operand", { REG, CONST_INT, SUBREG }}, \
{"arith_operand", { REG, CONST_INT, SUBREG }}, \
{"arith32_operand", { REG, CONST_INT, SUBREG }}, \
- {"reg_or_0_operand", { REG, CONST_INT, SUBREG }}, \
+ {"reg_or_0_operand", { REG, CONST_INT, CONST_DOUBLE, SUBREG }}, \
+ {"true_reg_or_0_operand", { REG, CONST_INT, CONST_DOUBLE, SUBREG }}, \
{"small_int", { CONST_INT }}, \
{"large_int", { CONST_INT }}, \
{"mips_const_double_ok", { CONST_DOUBLE }}, \
@@ -3655,7 +3801,7 @@ while (0)
SYMBOL_REF, LABEL_REF, SUBREG, REG, \
MEM, SIGN_EXTEND }}, \
{"se_register_operand", { SUBREG, REG, SIGN_EXTEND }}, \
- {"se_reg_or_0_operand", { REG, CONST_INT, SUBREG, \
+ {"se_reg_or_0_operand", { REG, CONST_INT, CONST_DOUBLE, SUBREG, \
SIGN_EXTEND }}, \
{"se_uns_arith_operand", { REG, CONST_INT, SUBREG, \
SIGN_EXTEND }}, \
@@ -4222,7 +4368,7 @@ do { \
fprintf (STREAM, "\t%s\t%sL%d-%sLS%d\n", \
Pmode == DImode ? ".dword" : ".word", \
LOCAL_LABEL_PREFIX, VALUE, LOCAL_LABEL_PREFIX, REL); \
- else if (mips_abi == ABI_32) \
+ else if (mips_abi == ABI_32 || mips_abi == ABI_O64) \
fprintf (STREAM, "\t%s\t%sL%d\n", \
Pmode == DImode ? ".gpdword" : ".gpword", \
LOCAL_LABEL_PREFIX, VALUE); \
@@ -4479,7 +4625,9 @@ while (0)
/* See mips_expand_prologue's use of loadgp for when this should be
true. */
-#define DONT_ACCESS_GBLS_AFTER_EPILOGUE (TARGET_ABICALLS && mips_abi != ABI_32)
+#define DONT_ACCESS_GBLS_AFTER_EPILOGUE (TARGET_ABICALLS \
+ && mips_abi != ABI_32 \
+ && mips_abi != ABI_O64)
/* In mips16 mode, we need to look through the function to check for
PC relative loads that are out of range. */
diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md
index 18d4a76c303..6dde18bf372 100644
--- a/gcc/config/mips/mips.md
+++ b/gcc/config/mips/mips.md
@@ -3,7 +3,7 @@
;; Changes by Michael Meissner, meissner@osf.org
;; 64 bit r4000 support by Ian Lance Taylor, ian@cygnus.com, and
;; Brendan Eich, brendan@microunity.com.
-;; Copyright (C) 1989, 90-97, 1998 Free Software Foundation, Inc.
+;; Copyright (C) 1989, 90-98, 1999 Free Software Foundation, Inc.
;; This file is part of GNU CC.
@@ -1735,7 +1735,7 @@
&& !TARGET_MIPS16"
"*
{
- static char *const madd[] = { \"madd\\t%1,%2\", \"madd\\t%0,%1,%2\" };
+ static const char *const madd[] = { \"madd\\t%1,%2\", \"madd\\t%0,%1,%2\" };
if (which_alternative == 2)
return \"#\";
return madd[which_alternative];
@@ -2228,7 +2228,7 @@
;; a divide by power of 2 with a shift, and then the remainder is no longer
;; available.
-(define_insn "divmodsi4"
+(define_expand "divmodsi4"
[(set (match_operand:SI 0 "register_operand" "=d")
(div:SI (match_operand:SI 1 "register_operand" "d")
(match_operand:SI 2 "register_operand" "d")))
@@ -2239,21 +2239,44 @@
(clobber (match_scratch:SI 5 "=h"))
(clobber (match_scratch:SI 6 "=a"))]
"optimize"
- "*
+ "
{
- if (find_reg_note (insn, REG_UNUSED, operands[3]))
- return \"div\\t%0,%1,%2\";
-
- if (find_reg_note (insn, REG_UNUSED, operands[0]))
- return \"rem\\t%3,%1,%2\";
+ emit_insn (gen_divmodsi4_internal (operands[0], operands[1], operands[2],
+ operands[3]));
+ if (!TARGET_NO_CHECK_ZERO_DIV)
+ {
+ emit_insn (gen_div_trap (operands[2],
+ GEN_INT (0),
+ GEN_INT (0x7)));
+ }
+ if (TARGET_CHECK_RANGE_DIV)
+ {
+ emit_insn (gen_div_trap (operands[2],
+ copy_to_mode_reg (SImode, GEN_INT (-1)),
+ GEN_INT (0x6)));
+ emit_insn (gen_div_trap (operands[2],
+ copy_to_mode_reg (SImode, GEN_INT (0x80000000)),
+ GEN_INT (0x6)));
+ }
+
+ DONE;
+}")
- return \"div\\t%0,%1,%2\;mfhi\\t%3\";
-}"
+(define_insn "divmodsi4_internal"
+ [(set (match_operand:SI 0 "register_operand" "=l")
+ (div:SI (match_operand:SI 1 "register_operand" "d")
+ (match_operand:SI 2 "register_operand" "d")))
+ (set (match_operand:SI 3 "register_operand" "=h")
+ (mod:SI (match_dup 1)
+ (match_dup 2)))
+ (clobber (match_scratch:SI 6 "=a"))]
+ "optimize"
+ "div\\t$0,%1,%2"
[(set_attr "type" "idiv")
(set_attr "mode" "SI")
- (set_attr "length" "14")]) ;; various tests for dividing by 0 and such
+ (set_attr "length" "1")])
-(define_insn "divmoddi4"
+(define_expand "divmoddi4"
[(set (match_operand:DI 0 "register_operand" "=d")
(div:DI (match_operand:DI 1 "se_register_operand" "d")
(match_operand:DI 2 "se_register_operand" "d")))
@@ -2264,21 +2287,44 @@
(clobber (match_scratch:DI 5 "=h"))
(clobber (match_scratch:DI 6 "=a"))]
"TARGET_64BIT && optimize"
- "*
+ "
{
- if (find_reg_note (insn, REG_UNUSED, operands[3]))
- return \"ddiv\\t%0,%1,%2\";
-
- if (find_reg_note (insn, REG_UNUSED, operands[0]))
- return \"drem\\t%3,%1,%2\";
+ emit_insn (gen_divmoddi4_internal (operands[0], operands[1], operands[2],
+ operands[3]));
+ if (!TARGET_NO_CHECK_ZERO_DIV)
+ {
+ emit_insn (gen_div_trap (operands[2],
+ GEN_INT (0),
+ GEN_INT (0x7)));
+ }
+ if (TARGET_CHECK_RANGE_DIV)
+ {
+ emit_insn (gen_div_trap (operands[2],
+ copy_to_mode_reg (DImode, GEN_INT (-1)),
+ GEN_INT (0x6)));
+ emit_insn (gen_div_trap (operands[2],
+ copy_to_mode_reg (DImode, GEN_INT (0x80000000)),
+ GEN_INT (0x6)));
+ }
+
+ DONE;
+}")
- return \"ddiv\\t%0,%1,%2\;mfhi\\t%3\";
-}"
+(define_insn "divmoddi4_internal"
+ [(set (match_operand:DI 0 "register_operand" "=l")
+ (div:DI (match_operand:DI 1 "se_register_operand" "d")
+ (match_operand:DI 2 "se_register_operand" "d")))
+ (set (match_operand:DI 3 "register_operand" "=h")
+ (mod:DI (match_dup 1)
+ (match_dup 2)))
+ (clobber (match_scratch:DI 6 "=a"))]
+ "TARGET_64BIT && optimize"
+ "ddiv\\t$0,%1,%2"
[(set_attr "type" "idiv")
- (set_attr "mode" "DI")
- (set_attr "length" "15")]) ;; various tests for dividing by 0 and such
+ (set_attr "mode" "SI")
+ (set_attr "length" "1")])
-(define_insn "udivmodsi4"
+(define_expand "udivmodsi4"
[(set (match_operand:SI 0 "register_operand" "=d")
(udiv:SI (match_operand:SI 1 "register_operand" "d")
(match_operand:SI 2 "register_operand" "d")))
@@ -2289,21 +2335,35 @@
(clobber (match_scratch:SI 5 "=h"))
(clobber (match_scratch:SI 6 "=a"))]
"optimize"
- "*
+ "
{
- if (find_reg_note (insn, REG_UNUSED, operands[3]))
- return \"divu\\t%0,%1,%2\";
-
- if (find_reg_note (insn, REG_UNUSED, operands[0]))
- return \"remu\\t%3,%1,%2\";
+ emit_insn (gen_udivmodsi4_internal (operands[0], operands[1], operands[2],
+ operands[3]));
+ if (!TARGET_NO_CHECK_ZERO_DIV)
+ {
+ emit_insn (gen_div_trap (operands[2],
+ GEN_INT (0),
+ GEN_INT (0x7)));
+ }
+
+ DONE;
+}")
- return \"divu\\t%0,%1,%2\;mfhi\\t%3\";
-}"
+(define_insn "udivmodsi4_internal"
+ [(set (match_operand:SI 0 "register_operand" "=l")
+ (udiv:SI (match_operand:SI 1 "register_operand" "d")
+ (match_operand:SI 2 "register_operand" "d")))
+ (set (match_operand:SI 3 "register_operand" "=h")
+ (umod:SI (match_dup 1)
+ (match_dup 2)))
+ (clobber (match_scratch:SI 6 "=a"))]
+ "optimize"
+ "divu\\t$0,%1,%2"
[(set_attr "type" "idiv")
(set_attr "mode" "SI")
- (set_attr "length" "8")]) ;; various tests for dividing by 0 and such
+ (set_attr "length" "1")])
-(define_insn "udivmoddi4"
+(define_expand "udivmoddi4"
[(set (match_operand:DI 0 "register_operand" "=d")
(udiv:DI (match_operand:DI 1 "se_register_operand" "d")
(match_operand:DI 2 "se_register_operand" "d")))
@@ -2314,220 +2374,418 @@
(clobber (match_scratch:DI 5 "=h"))
(clobber (match_scratch:DI 6 "=a"))]
"TARGET_64BIT && optimize"
+ "
+{
+ emit_insn (gen_udivmoddi4_internal (operands[0], operands[1], operands[2],
+ operands[3]));
+ if (!TARGET_NO_CHECK_ZERO_DIV)
+ {
+ emit_insn (gen_div_trap (operands[2],
+ GEN_INT (0),
+ GEN_INT (0x7)));
+ }
+
+ DONE;
+}")
+
+(define_insn "udivmoddi4_internal"
+ [(set (match_operand:DI 0 "register_operand" "=l")
+ (udiv:DI (match_operand:DI 1 "se_register_operand" "d")
+ (match_operand:DI 2 "se_register_operand" "d")))
+ (set (match_operand:DI 3 "register_operand" "=h")
+ (umod:DI (match_dup 1)
+ (match_dup 2)))
+ (clobber (match_scratch:DI 6 "=a"))]
+ "TARGET_64BIT && optimize"
+ "ddivu\\t$0,%1,%2"
+ [(set_attr "type" "idiv")
+ (set_attr "mode" "SI")
+ (set_attr "length" "1")])
+
+;; Division trap
+
+(define_expand "div_trap"
+ [(trap_if (eq (match_operand 0 "register_operand" "d")
+ (match_operand 1 "true_reg_or_0_operand" "dJ"))
+ (match_operand 2 "immediate_operand" ""))]
+ ""
+ "
+{
+ if (TARGET_MIPS16)
+ emit_insn (gen_div_trap_mips16 (operands[0],operands[1],operands[2]));
+ else
+ emit_insn (gen_div_trap_normal (operands[0],operands[1],operands[2]));
+ DONE;
+}")
+
+(define_insn "div_trap_normal"
+ [(trap_if (eq (match_operand 0 "register_operand" "d")
+ (match_operand 1 "true_reg_or_0_operand" "dJ"))
+ (match_operand 2 "immediate_operand" ""))]
+ "!TARGET_MIPS16"
"*
{
- if (find_reg_note (insn, REG_UNUSED, operands[3]))
- return \"ddivu\\t%0,%1,%2\";
+ rtx link;
+ int have_dep_anti = 0;
- if (find_reg_note (insn, REG_UNUSED, operands[0]))
- return \"dremu\\t%3,%1,%2\";
+ /* For divmod if one division is not needed then we don't need an extra
+ divide by zero trap, which is anti dependent on previous trap */
+ for (link = LOG_LINKS (insn); link; link = XEXP (link, 1))
- return \"ddivu\\t%0,%1,%2\;mfhi\\t%3\";
+ if ((int) REG_DEP_ANTI == (int) REG_NOTE_KIND (link)
+ && GET_CODE (XEXP (link, 0)) == INSN
+ && GET_CODE (PATTERN (XEXP (link, 0))) == TRAP_IF
+ && REGNO (operands[1]) == 0)
+ have_dep_anti = 1;
+ if (! have_dep_anti)
+ {
+ if (GENERATE_BRANCHLIKELY)
+ {
+ if (GET_CODE (operands[1]) == CONST_INT)
+ return \"%(beql\\t%0,$0,1f\\n\\tbreak\\t%2\\n1:%)\";
+ else
+ return \"%(beql\\t%0,%1,1f\\n\\tbreak\\t%2\\n1:%)\";
+ }
+ else
+ {
+ if (GET_CODE (operands[1]) == CONST_INT)
+ return \"%(bne\\t%0,$0,1f\\n\\tnop\\n\\tbreak\\t%2\\n1:%)\";
+ else
+ return \"%(bne\\t%0,%1,1f\\n\\tnop\\n\\tbreak\\t%2\\n1:%)\";
+ }
+ }
+ return \"\";
}"
- [(set_attr "type" "idiv")
- (set_attr "mode" "DI")
- (set_attr "length" "8")]) ;; various tests for dividing by 0 and such
+ [(set_attr "type" "unknown")
+ (set_attr "length" "3")])
+
+
+;; The mips16 bne insns is a macro which uses reg 24 as an intermediate.
+
+(define_insn "div_trap_mips16"
+ [(trap_if (eq (match_operand 0 "register_operand" "d")
+ (match_operand 1 "true_reg_or_0_operand" "dJ"))
+ (match_operand 2 "immediate_operand" ""))
+ (clobber (reg:SI 24))]
+ "TARGET_MIPS16"
+ "*
+{
+ rtx link;
+ int have_dep_anti = 0;
+
+ /* For divmod if one division is not needed then we don't need an extra
+ divide by zero trap, which is anti dependent on previous trap */
+ for (link = LOG_LINKS (insn); link; link = XEXP (link, 1))
+
+ if ((int) REG_DEP_ANTI == (int) REG_NOTE_KIND (link)
+ && GET_CODE (XEXP (link, 0)) == INSN
+ && GET_CODE (PATTERN (XEXP (link, 0))) == TRAP_IF
+ && REGNO (operands[1]) == 0)
+ have_dep_anti = 1;
+ if (! have_dep_anti)
+ {
+ /* No branch delay slots on mips16. */
+ if (GET_CODE (operands[1]) == CONST_INT)
+ return \"%(bnez\\t%0,1f\\n\\tbreak\\t%2\\n1:%)\";
+ else
+ return \"%(bne\\t%0,%1,1f\\n\\tbreak\\t%2\\n1:%)\";
+ }
+ return \"\";
+}"
+ [(set_attr "type" "unknown")
+ (set_attr "length" "3")])
(define_expand "divsi3"
- [(set (match_operand:SI 0 "register_operand" "=d")
+ [(set (match_operand:SI 0 "register_operand" "=l")
(div:SI (match_operand:SI 1 "register_operand" "d")
- (match_operand:SI 2 "nonmemory_operand" "di")))
- (clobber (match_scratch:SI 3 "=l"))
- (clobber (match_scratch:SI 4 "=h"))
- (clobber (match_scratch:SI 6 "=a"))]
+ (match_operand:SI 2 "register_operand" "d")))
+ (clobber (match_scratch:SI 3 "=h"))
+ (clobber (match_scratch:SI 4 "=a"))]
"!optimize"
"
{
- /* MIPS16 needs div/rem ops in registers. */
- if (TARGET_MIPS16)
- operands[2] = force_reg (SImode, operands[2]);
+ emit_insn (gen_divsi3_internal (operands[0], operands[1], operands[2]));
+ if (!TARGET_NO_CHECK_ZERO_DIV)
+ {
+ emit_insn (gen_div_trap (operands[2],
+ GEN_INT (0),
+ GEN_INT (0x7)));
+ }
+ if (TARGET_CHECK_RANGE_DIV)
+ {
+ emit_insn (gen_div_trap (operands[2],
+ copy_to_mode_reg (SImode, GEN_INT (-1)),
+ GEN_INT (0x6)));
+ emit_insn (gen_div_trap (operands[2],
+ copy_to_mode_reg (SImode, GEN_INT (0x80000000)),
+ GEN_INT (0x6)));
+ }
+
+ DONE;
}")
(define_insn "divsi3_internal"
- [(set (match_operand:SI 0 "register_operand" "=d")
+ [(set (match_operand:SI 0 "register_operand" "=l")
(div:SI (match_operand:SI 1 "register_operand" "d")
- (match_operand:SI 2 "nonmemory_operand" "di")))]
+ (match_operand:SI 2 "nonmemory_operand" "di")))
+ (clobber (match_scratch:SI 3 "=h"))
+ (clobber (match_scratch:SI 4 "=a"))]
"!optimize"
- "div\\t%0,%1,%2"
+ "div\\t$0,%1,%2"
[(set_attr "type" "idiv")
(set_attr "mode" "SI")
- (set_attr "length" "13")]) ;; various tests for dividing by 0 and such
+ (set_attr "length" "1")])
(define_expand "divdi3"
- [(set (match_operand:DI 0 "register_operand" "=d")
+ [(set (match_operand:DI 0 "register_operand" "=l")
(div:DI (match_operand:DI 1 "se_register_operand" "d")
- (match_operand:DI 2 "se_nonmemory_operand" "di")))
- (clobber (match_scratch:DI 3 "=l"))
- (clobber (match_scratch:DI 4 "=h"))
- (clobber (match_scratch:DI 6 "=a"))]
+ (match_operand:DI 2 "se_register_operand" "d")))
+ (clobber (match_scratch:DI 3 "=h"))
+ (clobber (match_scratch:DI 4 "=a"))]
"TARGET_64BIT && !optimize"
"
{
- /* MIPS16 needs div/rem ops in registers. */
- if (TARGET_MIPS16)
- operands[2] = force_reg (DImode, operands[2]);
+ emit_insn (gen_divdi3_internal (operands[0], operands[1], operands[2]));
+ if (!TARGET_NO_CHECK_ZERO_DIV)
+ {
+ emit_insn (gen_div_trap (operands[2],
+ GEN_INT (0),
+ GEN_INT (0x7)));
+ }
+ if (TARGET_CHECK_RANGE_DIV)
+ {
+ emit_insn (gen_div_trap (operands[2],
+ copy_to_mode_reg (DImode, GEN_INT (-1)),
+ GEN_INT (0x6)));
+ emit_insn (gen_div_trap (operands[2],
+ copy_to_mode_reg (DImode, GEN_INT (0x80000000)),
+ GEN_INT (0x6)));
+ }
+
+ DONE;
}")
(define_insn "divdi3_internal"
- [(set (match_operand:DI 0 "register_operand" "=d")
+ [(set (match_operand:DI 0 "register_operand" "=l")
(div:DI (match_operand:DI 1 "se_register_operand" "d")
- (match_operand:DI 2 "se_nonmemory_operand" "di")))]
+ (match_operand:DI 2 "se_nonmemory_operand" "di")))
+ (clobber (match_scratch:SI 3 "=h"))
+ (clobber (match_scratch:SI 4 "=a"))]
"TARGET_64BIT && !optimize"
- "ddiv\\t%0,%1,%2"
+ "ddiv\\t$0,%1,%2"
[(set_attr "type" "idiv")
(set_attr "mode" "DI")
- (set_attr "length" "14")]) ;; various tests for dividing by 0 and such
+ (set_attr "length" "1")])
(define_expand "modsi3"
- [(set (match_operand:SI 0 "register_operand" "=d")
+ [(set (match_operand:SI 0 "register_operand" "=h")
(mod:SI (match_operand:SI 1 "register_operand" "d")
- (match_operand:SI 2 "nonmemory_operand" "di")))
+ (match_operand:SI 2 "register_operand" "d")))
(clobber (match_scratch:SI 3 "=l"))
- (clobber (match_scratch:SI 4 "=h"))
- (clobber (match_scratch:SI 6 "=a"))]
+ (clobber (match_scratch:SI 4 "=a"))]
"!optimize"
"
{
- /* MIPS16 needs div/rem ops in registers. */
- if (TARGET_MIPS16)
- operands[2] = force_reg (SImode, operands[2]);
+ emit_insn (gen_modsi3_internal (operands[0], operands[1], operands[2]));
+ if (!TARGET_NO_CHECK_ZERO_DIV)
+ {
+ emit_insn (gen_div_trap (operands[2],
+ GEN_INT (0),
+ GEN_INT (0x7)));
+ }
+ if (TARGET_CHECK_RANGE_DIV)
+ {
+ emit_insn (gen_div_trap (operands[2],
+ copy_to_mode_reg (SImode, GEN_INT (-1)),
+ GEN_INT (0x6)));
+ emit_insn (gen_div_trap (operands[2],
+ copy_to_mode_reg (SImode, GEN_INT (0x80000000)),
+ GEN_INT (0x6)));
+ }
+
+ DONE;
}")
(define_insn "modsi3_internal"
- [(set (match_operand:SI 0 "register_operand" "=d")
+ [(set (match_operand:SI 0 "register_operand" "=h")
(mod:SI (match_operand:SI 1 "register_operand" "d")
- (match_operand:SI 2 "nonmemory_operand" "di")))]
+ (match_operand:SI 2 "nonmemory_operand" "di")))
+ (clobber (match_scratch:SI 3 "=l"))
+ (clobber (match_scratch:SI 4 "=a"))]
"!optimize"
- "rem\\t%0,%1,%2"
+ "div\\t$0,%1,%2"
[(set_attr "type" "idiv")
(set_attr "mode" "SI")
- (set_attr "length" "13")]) ;; various tests for dividing by 0 and such
+ (set_attr "length" "1")])
(define_expand "moddi3"
- [(set (match_operand:DI 0 "register_operand" "=d")
+ [(set (match_operand:DI 0 "register_operand" "=h")
(mod:DI (match_operand:DI 1 "se_register_operand" "d")
- (match_operand:DI 2 "se_nonmemory_operand" "di")))
+ (match_operand:DI 2 "se_register_operand" "d")))
(clobber (match_scratch:DI 3 "=l"))
- (clobber (match_scratch:DI 4 "=h"))
- (clobber (match_scratch:DI 6 "=a"))]
+ (clobber (match_scratch:DI 4 "=a"))]
"TARGET_64BIT && !optimize"
"
{
- /* MIPS16 needs div/rem ops in registers. */
- if (TARGET_MIPS16)
- operands[2] = force_reg (DImode, operands[2]);
+ emit_insn (gen_moddi3_internal (operands[0], operands[1], operands[2]));
+ if (!TARGET_NO_CHECK_ZERO_DIV)
+ {
+ emit_insn (gen_div_trap (operands[2],
+ GEN_INT (0),
+ GEN_INT (0x7)));
+ }
+ if (TARGET_CHECK_RANGE_DIV)
+ {
+ emit_insn (gen_div_trap (operands[2],
+ copy_to_mode_reg (DImode, GEN_INT (-1)),
+ GEN_INT (0x6)));
+ emit_insn (gen_div_trap (operands[2],
+ copy_to_mode_reg (DImode, GEN_INT (0x80000000)),
+ GEN_INT (0x6)));
+ }
+
+ DONE;
}")
(define_insn "moddi3_internal"
- [(set (match_operand:DI 0 "register_operand" "=d")
+ [(set (match_operand:DI 0 "register_operand" "=h")
(mod:DI (match_operand:DI 1 "se_register_operand" "d")
- (match_operand:DI 2 "se_nonmemory_operand" "di")))]
+ (match_operand:DI 2 "se_nonmemory_operand" "di")))
+ (clobber (match_scratch:SI 3 "=l"))
+ (clobber (match_scratch:SI 4 "=a"))]
"TARGET_64BIT && !optimize"
- "drem\\t%0,%1,%2"
+ "ddiv\\t$0,%1,%2"
[(set_attr "type" "idiv")
(set_attr "mode" "DI")
- (set_attr "length" "14")]) ;; various tests for dividing by 0 and such
+ (set_attr "length" "1")])
(define_expand "udivsi3"
- [(set (match_operand:SI 0 "register_operand" "=d")
+ [(set (match_operand:SI 0 "register_operand" "=l")
(udiv:SI (match_operand:SI 1 "register_operand" "d")
- (match_operand:SI 2 "nonmemory_operand" "di")))
- (clobber (match_scratch:SI 3 "=l"))
- (clobber (match_scratch:SI 4 "=h"))
- (clobber (match_scratch:SI 6 "=a"))]
+ (match_operand:SI 2 "register_operand" "d")))
+ (clobber (match_scratch:SI 3 "=h"))
+ (clobber (match_scratch:SI 4 "=a"))]
"!optimize"
"
{
- /* MIPS16 needs div/rem ops in registers. */
- if (TARGET_MIPS16)
- operands[2] = force_reg (SImode, operands[2]);
+ emit_insn (gen_udivsi3_internal (operands[0], operands[1], operands[2]));
+ if (!TARGET_NO_CHECK_ZERO_DIV)
+ {
+ emit_insn (gen_div_trap (operands[2],
+ GEN_INT (0),
+ GEN_INT (0x7)));
+ }
+
+ DONE;
}")
(define_insn "udivsi3_internal"
- [(set (match_operand:SI 0 "register_operand" "=d")
+ [(set (match_operand:SI 0 "register_operand" "=l")
(udiv:SI (match_operand:SI 1 "register_operand" "d")
- (match_operand:SI 2 "nonmemory_operand" "di")))]
+ (match_operand:SI 2 "nonmemory_operand" "di")))
+ (clobber (match_scratch:SI 3 "=h"))
+ (clobber (match_scratch:SI 4 "=a"))]
"!optimize"
- "divu\\t%0,%1,%2"
+ "divu\\t$0,%1,%2"
[(set_attr "type" "idiv")
(set_attr "mode" "SI")
- (set_attr "length" "7")]) ;; various tests for dividing by 0 and such
+ (set_attr "length" "1")])
(define_expand "udivdi3"
- [(set (match_operand:DI 0 "register_operand" "=d")
+ [(set (match_operand:DI 0 "register_operand" "=l")
(udiv:DI (match_operand:DI 1 "se_register_operand" "d")
- (match_operand:DI 2 "se_nonmemory_operand" "di")))
- (clobber (match_scratch:DI 3 "=l"))
- (clobber (match_scratch:DI 4 "=h"))
- (clobber (match_scratch:DI 6 "=a"))]
+ (match_operand:DI 2 "se_register_operand" "di")))
+ (clobber (match_scratch:DI 3 "=h"))
+ (clobber (match_scratch:DI 4 "=a"))]
"TARGET_64BIT && !optimize"
"
{
- /* MIPS16 needs div/rem ops in registers. */
- if (TARGET_MIPS16)
- operands[2] = force_reg (DImode, operands[2]);
+ emit_insn (gen_udivdi3_internal (operands[0], operands[1], operands[2]));
+ if (!TARGET_NO_CHECK_ZERO_DIV)
+ {
+ emit_insn (gen_div_trap (operands[2],
+ GEN_INT (0),
+ GEN_INT (0x7)));
+ }
+
+ DONE;
}")
(define_insn "udivdi3_internal"
- [(set (match_operand:DI 0 "register_operand" "=d")
+ [(set (match_operand:DI 0 "register_operand" "=l")
(udiv:DI (match_operand:DI 1 "se_register_operand" "d")
- (match_operand:DI 2 "se_nonmemory_operand" "di")))]
+ (match_operand:DI 2 "se_nonmemory_operand" "di")))
+ (clobber (match_scratch:SI 3 "=h"))
+ (clobber (match_scratch:SI 4 "=a"))]
"TARGET_64BIT && !optimize"
- "ddivu\\t%0,%1,%2"
+ "ddivu\\t$0,%1,%2"
[(set_attr "type" "idiv")
(set_attr "mode" "DI")
- (set_attr "length" "7")]) ;; various tests for dividing by 0 and such
+ (set_attr "length" "1")])
(define_expand "umodsi3"
- [(set (match_operand:SI 0 "register_operand" "=d")
+ [(set (match_operand:SI 0 "register_operand" "=h")
(umod:SI (match_operand:SI 1 "register_operand" "d")
- (match_operand:SI 2 "nonmemory_operand" "di")))
+ (match_operand:SI 2 "register_operand" "d")))
(clobber (match_scratch:SI 3 "=l"))
- (clobber (match_scratch:SI 4 "=h"))
- (clobber (match_scratch:SI 6 "=a"))]
+ (clobber (match_scratch:SI 4 "=a"))]
"!optimize"
"
{
- /* MIPS16 needs div/rem ops in registers. */
- if (TARGET_MIPS16)
- operands[2] = force_reg (SImode, operands[2]);
+ emit_insn (gen_umodsi3_internal (operands[0], operands[1], operands[2]));
+ if (!TARGET_NO_CHECK_ZERO_DIV)
+ {
+ emit_insn (gen_div_trap (operands[2],
+ GEN_INT (0),
+ GEN_INT (0x7)));
+ }
+
+ DONE;
}")
(define_insn "umodsi3_internal"
- [(set (match_operand:SI 0 "register_operand" "=d")
+ [(set (match_operand:SI 0 "register_operand" "=h")
(umod:SI (match_operand:SI 1 "register_operand" "d")
- (match_operand:SI 2 "nonmemory_operand" "di")))]
+ (match_operand:SI 2 "nonmemory_operand" "di")))
+ (clobber (match_scratch:SI 3 "=l"))
+ (clobber (match_scratch:SI 4 "=a"))]
"!optimize"
- "remu\\t%0,%1,%2"
+ "divu\\t$0,%1,%2"
[(set_attr "type" "idiv")
(set_attr "mode" "SI")
- (set_attr "length" "7")]) ;; various tests for dividing by 0 and such
+ (set_attr "length" "1")])
(define_expand "umoddi3"
- [(set (match_operand:DI 0 "register_operand" "=d")
+ [(set (match_operand:DI 0 "register_operand" "=h")
(umod:DI (match_operand:DI 1 "se_register_operand" "d")
- (match_operand:DI 2 "se_nonmemory_operand" "di")))
+ (match_operand:DI 2 "se_register_operand" "di")))
(clobber (match_scratch:DI 3 "=l"))
- (clobber (match_scratch:DI 4 "=h"))
- (clobber (match_scratch:DI 6 "=a"))]
+ (clobber (match_scratch:DI 4 "=a"))]
"TARGET_64BIT && !optimize"
"
{
- /* MIPS16 needs div/rem ops in registers. */
- if (TARGET_MIPS16)
- operands[2] = force_reg (DImode, operands[2]);
+ emit_insn (gen_umoddi3_internal (operands[0], operands[1], operands[2]));
+ if (!TARGET_NO_CHECK_ZERO_DIV)
+ {
+ emit_insn (gen_div_trap (operands[2],
+ GEN_INT (0),
+ GEN_INT (0x7)));
+ }
+
+ DONE;
}")
(define_insn "umoddi3_internal"
- [(set (match_operand:DI 0 "register_operand" "=d")
+ [(set (match_operand:DI 0 "register_operand" "=h")
(umod:DI (match_operand:DI 1 "se_register_operand" "d")
- (match_operand:DI 2 "se_nonmemory_operand" "di")))]
+ (match_operand:DI 2 "se_nonmemory_operand" "di")))
+ (clobber (match_scratch:SI 3 "=l"))
+ (clobber (match_scratch:SI 4 "=a"))]
"TARGET_64BIT && !optimize"
- "dremu\\t%0,%1,%2"
+ "ddivu\\t$0,%1,%2"
[(set_attr "type" "idiv")
(set_attr "mode" "DI")
- (set_attr "length" "7")]) ;; various tests for dividing by 0 and such
-
+ (set_attr "length" "1")])
;;
;; ....................
@@ -4382,7 +4640,7 @@ move\\t%0,%z4\\n\\
rtx offset = const0_rtx;
rtx addr = XEXP (operands[1], 0);
rtx mem_addr = eliminate_constant_term (addr, &offset);
- char *ret;
+ const char *ret;
if (TARGET_STATS)
mips_count_memory_refs (operands[1], 2);
@@ -4441,7 +4699,7 @@ move\\t%0,%z4\\n\\
rtx offset = const0_rtx;
rtx addr = XEXP (operands[1], 0);
rtx mem_addr = eliminate_constant_term (addr, &offset);
- char *ret;
+ const char *ret;
if (TARGET_STATS)
mips_count_memory_refs (operands[1], 2);
@@ -4803,6 +5061,7 @@ move\\t%0,%z4\\n\\
emit_move_insn (gen_rtx (REG, SImode, 64), scratch);
emit_move_insn (scratch, loword);
emit_move_insn (gen_rtx (REG, SImode, 65), scratch);
+ emit_insn (gen_rtx_USE (VOIDmode, operands[0]));
}
else
{
@@ -4811,6 +5070,7 @@ move\\t%0,%z4\\n\\
emit_insn (gen_ashldi3 (scratch, operands[1], GEN_INT (32)));
emit_insn (gen_ashrdi3 (scratch, scratch, GEN_INT (32)));
emit_insn (gen_movdi (gen_rtx (REG, DImode, 65), scratch));
+ emit_insn (gen_rtx_USE (VOIDmode, operands[0]));
}
DONE;
}
@@ -4822,6 +5082,7 @@ move\\t%0,%z4\\n\\
emit_insn (gen_movdi (operands[0], gen_rtx (REG, DImode, 64)));
emit_insn (gen_ashldi3 (operands[0], operands[0], GEN_INT (32)));
emit_insn (gen_iordi3 (operands[0], operands[0], scratch));
+ emit_insn (gen_rtx_USE (VOIDmode, operands[1]));
DONE;
}
/* This handles moves between a float register and HI/LO. */
@@ -4851,6 +5112,7 @@ move\\t%0,%z4\\n\\
emit_insn (gen_ashldi3 (scratch, operands[1], GEN_INT (32)));
emit_insn (gen_ashrdi3 (scratch, scratch, GEN_INT (32)));
emit_insn (gen_movdi (gen_rtx (REG, DImode, 65), scratch));
+ emit_insn (gen_rtx_USE (VOIDmode, operands[0]));
DONE;
}
if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == HILO_REGNUM)
@@ -4879,6 +5141,7 @@ move\\t%0,%z4\\n\\
emit_move_insn (hiword, scratch);
emit_move_insn (scratch, gen_rtx (REG, SImode, 65));
emit_move_insn (loword, scratch);
+ emit_insn (gen_rtx_USE (VOIDmode, operands[1]));
}
else if (TARGET_MIPS16 && ! M16_REG_P (REGNO (operands[0])))
{
@@ -4893,6 +5156,7 @@ move\\t%0,%z4\\n\\
emit_insn (gen_ashldi3 (scratch2, scratch2, GEN_INT (32)));
emit_insn (gen_iordi3 (scratch, scratch, scratch2));
emit_insn (gen_movdi (operands[0], scratch));
+ emit_insn (gen_rtx_USE (VOIDmode, operands[1]));
}
else
{
@@ -4902,6 +5166,7 @@ move\\t%0,%z4\\n\\
emit_insn (gen_movdi (operands[0], gen_rtx (REG, DImode, 64)));
emit_insn (gen_ashldi3 (operands[0], operands[0], GEN_INT (32)));
emit_insn (gen_iordi3 (operands[0], operands[0], scratch));
+ emit_insn (gen_rtx_USE (VOIDmode, operands[1]));
}
DONE;
}
@@ -5225,6 +5490,7 @@ move\\t%0,%z4\\n\\
emit_insn (gen_movsi (gen_rtx (REG, SImode, 65), operands[1]));
emit_insn (gen_ashrsi3 (operands[2], operands[1], GEN_INT (31)));
emit_insn (gen_movsi (gen_rtx (REG, SImode, 64), operands[2]));
+ emit_insn (gen_rtx_USE (VOIDmode, operands[0]));
DONE;
}
/* Use a mult to reload LO on mips16. ??? This is hideous. */
@@ -8761,7 +9027,7 @@ move\\t%0,%z4\\n\\
/* ??? I don't know why this is necessary. This works around an
assembler problem that appears when a label is defined, then referenced
in a switch table, then used in a `j' instruction. */
- else if (mips_abi != ABI_32)
+ else if (mips_abi != ABI_32 && mips_abi != ABI_O64)
return \"%*b\\t%l0\";
else
return \"%*j\\t%l0\";
@@ -8952,7 +9218,7 @@ move\\t%0,%z4\\n\\
"*
{
/* .cpadd expands to add REG,REG,$gp when pic, and nothing when not pic. */
- if (mips_abi == ABI_32)
+ if (mips_abi == ABI_32 || mips_abi == ABI_O64)
output_asm_insn (\".cpadd\\t%0\", operands);
return \"%*j\\t%0\";
}"
@@ -9537,7 +9803,8 @@ move\\t%0,%z4\\n\\
(call (mem:SI (match_operand:SI 1 "register_operand" "r"))
(match_operand 2 "" "i")))
(clobber (match_operand:SI 3 "register_operand" "=d"))]
- "!(Pmode == DImode) && !TARGET_ABICALLS && TARGET_LONG_CALLS"
+ "!TARGET_MIPS16
+ && !(Pmode == DImode) && !TARGET_ABICALLS && TARGET_LONG_CALLS"
"%*jal\\t%3,%1"
[(set_attr "type" "call")
(set_attr "mode" "none")
@@ -9548,7 +9815,20 @@ move\\t%0,%z4\\n\\
(call (mem:DI (match_operand:DI 1 "se_register_operand" "r"))
(match_operand 2 "" "i")))
(clobber (match_operand:SI 3 "register_operand" "=d"))]
- "Pmode == DImode && !TARGET_ABICALLS && TARGET_LONG_CALLS"
+ "!TARGET_MIPS16
+ && Pmode == DImode && !TARGET_ABICALLS && TARGET_LONG_CALLS"
+ "%*jal\\t%3,%1"
+ [(set_attr "type" "call")
+ (set_attr "mode" "none")
+ (set_attr "length" "1")])
+
+(define_insn "call_value_internal3c"
+ [(set (match_operand 0 "register_operand" "=df")
+ (call (mem:SI (match_operand:SI 1 "register_operand" "e"))
+ (match_operand 2 "" "i")))
+ (clobber (match_operand:SI 3 "register_operand" "=y"))]
+ "TARGET_MIPS16 && !(Pmode == DImode) && !TARGET_ABICALLS && TARGET_LONG_CALLS
+ && GET_CODE (operands[3]) == REG && REGNO (operands[3]) == 31"
"%*jal\\t%3,%1"
[(set_attr "type" "call")
(set_attr "mode" "none")
diff --git a/gcc/config/mips/mips16.S b/gcc/config/mips/mips16.S
index f5af9e7c476..f21f10f2118 100644
--- a/gcc/config/mips/mips16.S
+++ b/gcc/config/mips/mips16.S
@@ -330,7 +330,7 @@ STARTFN (NAME); \
STARTFN (NAME); \
LDDBL1; \
LDDBL2; \
- OPCODE $f12,$f14; \
+ OPCODE $f14,$f12; \
li $2,TRUE; \
bc1t 1f; \
li $2,FALSE; \
diff --git a/gcc/config/mips/osfrose.h b/gcc/config/mips/osfrose.h
index ee76053d9c4..3d92619c3e5 100644
--- a/gcc/config/mips/osfrose.h
+++ b/gcc/config/mips/osfrose.h
@@ -76,6 +76,7 @@ Boston, MA 02111-1307, USA. */
#define CC1_SPEC "\
%{gline:%{!g:%{!g0:%{!g1:%{!g2: -g1}}}}} \
%{mips1:-mfp32 -mgp32} %{mips2:-mfp32 -mgp32} %{mips3:-mfp64 -mgp64} \
+%{mint64|mlong64|mlong32:-mexplicit-type-size }\
%{G*} \
%{pic-none: -mno-half-pic} \
%{pic-lib: -mhalf-pic} \
diff --git a/gcc/config/mips/sni-svr4.h b/gcc/config/mips/sni-svr4.h
index 24d035b5dcd..cf6edbccad6 100644
--- a/gcc/config/mips/sni-svr4.h
+++ b/gcc/config/mips/sni-svr4.h
@@ -16,7 +16,8 @@ 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
#define MIPS_SVR4
diff --git a/gcc/config/mips/t-cross64 b/gcc/config/mips/t-cross64
index 9482412a844..bfca95072f7 100644
--- a/gcc/config/mips/t-cross64
+++ b/gcc/config/mips/t-cross64
@@ -2,8 +2,6 @@ SYSTEM_HEADER_DIR = /usr/cross64/usr/include
AR = /usr/cross64/usr/bin/ar
-FLOAT_H = $(CROSS_FLOAT_H)
-
# The rest of the file is identical to t-iris6.
# Suppress building libgcc1.a, since the MIPS compiler port is complete
diff --git a/gcc/config/mn10200/mn10200.h b/gcc/config/mn10200/mn10200.h
index d2b474d5d70..fcf1058e0a4 100644
--- a/gcc/config/mn10200/mn10200.h
+++ b/gcc/config/mn10200/mn10200.h
@@ -991,11 +991,6 @@ do { char dstr[30]; \
for the index in the tablejump instruction. */
#define CASE_VECTOR_MODE Pmode
-/* Define this if the case instruction drops through after the table
- when the index is out of range. Don't define it if the case insn
- jumps to the default label instead. */
-#define CASE_DROPS_THROUGH
-
/* Dispatch tables on the mn10200 are extremely expensive in terms of code
and readonly data size. So we crank up the case threshold value to
encourage a series of if/else comparisons to implement many small switch
diff --git a/gcc/config/mn10200/mn10200.md b/gcc/config/mn10200/mn10200.md
index 7659ce763cc..30ff23dd7c4 100644
--- a/gcc/config/mn10200/mn10200.md
+++ b/gcc/config/mn10200/mn10200.md
@@ -371,10 +371,13 @@
;;
;; So we call out to a library routine to perform 32bit add or
;; subtract operations.
+;;
+;; operand2 must be nonmemory_operand so that we will accept CONST_INTs
+;; during initial code generation.
(define_expand "addsi3"
- [(set (match_operand:SI 0 "general_operand" "")
- (plus:SI (match_operand:SI 1 "general_operand" "")
- (match_operand:SI 2 "general_operand" "")))]
+ [(set (match_operand:SI 0 "register_operand" "")
+ (plus:SI (match_operand:SI 1 "register_operand" "")
+ (match_operand:SI 2 "nonmemory_operand" "")))]
""
"
{
@@ -396,7 +399,6 @@
else if (rtx_equal_function_value_matters)
{
rtx ret, insns;
- extern rtx emit_library_call_value ();
start_sequence ();
ret = emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"__addsi3\"),
@@ -413,8 +415,8 @@
}")
(define_insn "addsi3_const"
- [(set (match_operand:SI 0 "general_operand" "=d")
- (plus:SI (match_operand:SI 1 "general_operand" "0")
+ [(set (match_operand:SI 0 "register_operand" "=d")
+ (plus:SI (match_operand:SI 1 "register_operand" "0")
(match_operand:SI 2 "const_int_operand" "i")))
(clobber (match_scratch:SI 3 "=&d"))]
""
@@ -459,9 +461,9 @@
[(set_attr "cc" "set_zn")])
(define_expand "subsi3"
- [(set (match_operand:SI 0 "general_operand" "")
- (minus:SI (match_operand:SI 1 "general_operand" "")
- (match_operand:SI 2 "general_operand" "")))]
+ [(set (match_operand:SI 0 "register_operand" "")
+ (minus:SI (match_operand:SI 1 "register_operand" "")
+ (match_operand:SI 2 "register_operand" "")))]
""
"
{
@@ -474,7 +476,6 @@
if (rtx_equal_function_value_matters)
{
rtx ret, insns;
- extern rtx emit_library_call_value ();
start_sequence ();
ret = emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"__subsi3\"),
@@ -523,8 +524,8 @@
;; data register pair has proven to be the most efficient
;; and most compact way to represent negsi2.
(define_insn "negsi2"
- [(set (match_operand:SI 0 "general_operand" "=d")
- (neg:SI (match_operand:SI 1 "general_operand" "0")))]
+ [(set (match_operand:SI 0 "register_operand" "=d")
+ (neg:SI (match_operand:SI 1 "register_operand" "0")))]
""
"jsr ___negsi2_%0"
[(set_attr "cc" "clobber")])
@@ -653,7 +654,7 @@
;; These clears a constant set of bits in memory or in a register.
;; We must support register destinations to make reload happy.
(define_insn ""
- [(set (match_operand:QI 0 "general_operand" "R,d")
+ [(set (match_operand:QI 0 "general_operand" "+R,d")
(subreg:QI
(and:HI (subreg:HI (match_dup 0) 0)
(match_operand 1 "const_int_operand" "")) 0))
@@ -666,7 +667,7 @@
;; This clears a variable set of bits in memory or in a register.
(define_insn ""
- [(set (match_operand:QI 0 "general_operand" "R,d")
+ [(set (match_operand:QI 0 "general_operand" "+R,d")
(subreg:QI
(and:HI (subreg:HI (match_dup 0) 0)
(not:HI (match_operand:HI 1 "general_operand" "d,d"))) 0))
@@ -678,7 +679,7 @@
[(set_attr "cc" "clobber")])
(define_insn ""
- [(set (match_operand:QI 0 "general_operand" "R,d")
+ [(set (match_operand:QI 0 "general_operand" "+R,d")
(subreg:QI
(and:HI (not:HI (match_operand:HI 1 "general_operand" "d,d"))
(subreg:HI (match_dup 0) 0)) 0))
@@ -691,7 +692,7 @@
;; These set bits in memory.
(define_insn ""
- [(set (match_operand:QI 0 "general_operand" "R,d")
+ [(set (match_operand:QI 0 "general_operand" "+R,d")
(subreg:QI
(ior:HI (subreg:HI (match_dup 0) 0)
(match_operand:HI 1 "general_operand" "d,d")) 0))]
@@ -702,7 +703,7 @@
[(set_attr "cc" "clobber")])
(define_insn ""
- [(set (match_operand:QI 0 "general_operand" "R,d")
+ [(set (match_operand:QI 0 "general_operand" "+R,d")
(subreg:QI
(ior:HI (match_operand:HI 1 "general_operand" "d,d")
(subreg:HI (match_dup 0) 0)) 0))]
@@ -1495,7 +1496,6 @@
|| INTVAL (operands[2]) <= 15))
{
rtx ret, insns;
- extern rtx emit_library_call_value ();
start_sequence ();
ret = emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"__ashlsi3\"),
@@ -1554,7 +1554,6 @@
|| INTVAL (operands[2]) <= 15))
{
rtx ret, insns;
- extern rtx emit_library_call_value ();
start_sequence ();
ret = emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"__lshrsi3\"),
@@ -1613,7 +1612,6 @@
|| INTVAL (operands[2]) <= 15))
{
rtx ret, insns;
- extern rtx emit_library_call_value ();
start_sequence ();
ret = emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"__ashrsi3\"),
@@ -1639,6 +1637,77 @@
[(set_attr "cc" "clobber")])
;; ----------------------------------------------------------------------
+;; FP INSTRUCTIONS
+;; ----------------------------------------------------------------------
+;;
+;; The mn102 series does not have floating point instructions, but since
+;; FP values are held in integer regs, we can clear the high bit easily
+;; which gives us an efficient inline floating point absolute value.
+;;
+;; Similarly for negation of a FP value.
+;;
+
+(define_expand "abssf2"
+ [(set (match_operand:SF 0 "register_operand" "")
+ (abs:SF (match_operand:SF 1 "register_operand" "")))]
+ ""
+ "
+{
+ rtx target, result, insns;
+
+ start_sequence ();
+ target = operand_subword (operands[0], 1, 1, SFmode);
+ result = expand_binop (HImode, and_optab,
+ operand_subword_force (operands[1], 1, SFmode),
+ GEN_INT(0x7fff), target, 0, OPTAB_WIDEN);
+
+ if (result == 0)
+ abort ();
+
+ if (result != target)
+ emit_move_insn (result, target);
+
+ emit_move_insn (operand_subword (operands[0], 0, 1, SFmode),
+ operand_subword_force (operands[1], 0, SFmode));
+
+ insns = get_insns ();
+ end_sequence ();
+
+ emit_no_conflict_block (insns, operands[0], operands[1], 0, 0);
+ DONE;
+}")
+
+(define_expand "negsf2"
+ [(set (match_operand:SF 0 "register_operand" "")
+ (neg:SF (match_operand:SF 1 "register_operand" "")))]
+ ""
+ "
+{
+ rtx target, result, insns;
+
+ start_sequence ();
+ target = operand_subword (operands[0], 1, 1, SFmode);
+ result = expand_binop (HImode, xor_optab,
+ operand_subword_force (operands[1], 1, SFmode),
+ GEN_INT(0x8000), target, 0, OPTAB_WIDEN);
+
+ if (result == 0)
+ abort ();
+
+ if (result != target)
+ emit_move_insn (result, target);
+
+ emit_move_insn (operand_subword (operands[0], 0, 1, SFmode),
+ operand_subword_force (operands[1], 0, SFmode));
+
+ insns = get_insns ();
+ end_sequence ();
+
+ emit_no_conflict_block (insns, operands[0], operands[1], 0, 0);
+ DONE;
+}")
+
+;; ----------------------------------------------------------------------
;; PROLOGUE/EPILOGUE
;; ----------------------------------------------------------------------
(define_expand "prologue"
@@ -1713,10 +1782,10 @@
;; opportunity to match patterns which allow us to remove the initial
;; extension completely, which is a big win.
(define_insn ""
- [(set (match_operand:PSI 0 "general_operand" "=d,d,a")
+ [(set (match_operand:PSI 0 "general_operand" "=d,d,a,da")
(truncate:PSI
- (ashift:SI (match_operand:SI 1 "general_operand" "d,m,m")
- (match_operand:HI 2 "const_int_operand" "i,i,i"))))]
+ (ashift:SI (match_operand:SI 1 "general_operand" "d,m,m,i")
+ (match_operand:HI 2 "const_int_operand" "i,i,i,i"))))]
""
"*
{
diff --git a/gcc/config/mn10300/mn10300.h b/gcc/config/mn10300/mn10300.h
index e54b77a718b..3c2a6a7c37a 100644
--- a/gcc/config/mn10300/mn10300.h
+++ b/gcc/config/mn10300/mn10300.h
@@ -47,9 +47,9 @@ extern int target_flags;
/* Generate code to work around mul/mulq bugs on the mn10300. */
#define TARGET_MULT_BUG (target_flags & 0x1)
#define TARGET_SWITCHES \
- {{ "mult-bug", 0x1}, \
- { "no-mult-bug", -0x1}, \
- { "", TARGET_DEFAULT}}
+ {{ "mult-bug", 0x1, "Work around hardware multiply bug"}, \
+ { "no-mult-bug", -0x1, "Do not work around hardware multiply bug"},\
+ { "", TARGET_DEFAULT, NULL}}
#ifndef TARGET_DEFAULT
#define TARGET_DEFAULT 0x1
@@ -987,11 +987,6 @@ do { char dstr[30]; \
for the index in the tablejump instruction. */
#define CASE_VECTOR_MODE Pmode
-/* Define this if the case instruction drops through after the table
- when the index is out of range. Don't define it if the case insn
- jumps to the default label instead. */
-#define CASE_DROPS_THROUGH
-
/* Define if operations between registers always perform the operation
on the full register even if a narrower mode is specified. */
#define WORD_REGISTER_OPERATIONS
diff --git a/gcc/config/mn10300/mn10300.md b/gcc/config/mn10300/mn10300.md
index d3061ad54b8..8e090a3395d 100644
--- a/gcc/config/mn10300/mn10300.md
+++ b/gcc/config/mn10300/mn10300.md
@@ -155,7 +155,6 @@
{
if (XEXP (operands[1], 0) == stack_pointer_rtx)
{
- emit_move_insn (operands[0], XEXP (operands[1], 0));
if (GET_CODE (XEXP (operands[1], 1)) == SUBREG
&& (GET_MODE_SIZE (GET_MODE (XEXP (operands[1], 1)))
> GET_MODE_SIZE (GET_MODE (SUBREG_REG (XEXP (operands[1], 1))))))
@@ -164,10 +163,10 @@
SUBREG_REG (XEXP (operands[1], 1))));
else
emit_move_insn (operands[2], XEXP (operands[1], 1));
+ emit_move_insn (operands[0], XEXP (operands[1], 0));
}
else
{
- emit_move_insn (operands[0], XEXP (operands[1], 1));
if (GET_CODE (XEXP (operands[1], 0)) == SUBREG
&& (GET_MODE_SIZE (GET_MODE (XEXP (operands[1], 0)))
> GET_MODE_SIZE (GET_MODE (SUBREG_REG (XEXP (operands[1], 0))))))
@@ -176,6 +175,7 @@
SUBREG_REG (XEXP (operands[1], 0))));
else
emit_move_insn (operands[2], XEXP (operands[1], 0));
+ emit_move_insn (operands[0], XEXP (operands[1], 1));
}
emit_insn (gen_addsi3 (operands[0], operands[0], operands[2]));
DONE;
@@ -849,7 +849,7 @@
[(set_attr "cc" "clobber,none_0hit")])
(define_insn ""
- [(set (match_operand:QI 0 "general_operand" "=R,d")
+ [(set (match_operand:QI 0 "general_operand" "+R,d")
(subreg:QI
(and:SI (subreg:SI (match_dup 0) 0)
(match_operand:SI 1 "const_int_operand" "i,i")) 0))]
@@ -860,7 +860,7 @@
[(set_attr "cc" "clobber,set_znv")])
(define_insn ""
- [(set (match_operand:QI 0 "general_operand" "=R,d")
+ [(set (match_operand:QI 0 "general_operand" "+R,d")
(subreg:QI
(ior:SI (subreg:SI (match_dup 0) 0)
(match_operand:SI 1 "const_int_operand" "i,i")) 0))]
@@ -1339,6 +1339,127 @@
[(set_attr "cc" "set_zn")])
;; ----------------------------------------------------------------------
+;; FP INSTRUCTIONS
+;; ----------------------------------------------------------------------
+;;
+;; The mn103 series does not have floating point instructions, but since
+;; FP values are held in integer regs, we can clear the high bit easily
+;; which gives us an efficient inline floating point absolute value.
+;;
+;; Similarly for negation of a FP value.
+;;
+
+(define_expand "absdf2"
+ [(set (match_operand:DF 0 "register_operand" "")
+ (abs:DF (match_operand:DF 1 "register_operand" "")))]
+ ""
+ "
+{
+ rtx target, result, insns;
+
+ start_sequence ();
+ target = operand_subword (operands[0], 1, 1, DFmode);
+ result = expand_binop (SImode, and_optab,
+ operand_subword_force (operands[1], 1, DFmode),
+ GEN_INT(0x7fffffff), target, 0, OPTAB_WIDEN);
+
+ if (result == 0)
+ abort ();
+
+ if (result != target)
+ emit_move_insn (result, target);
+
+ emit_move_insn (operand_subword (operands[0], 0, 1, DFmode),
+ operand_subword_force (operands[1], 0, DFmode));
+
+ insns = get_insns ();
+ end_sequence ();
+
+ emit_no_conflict_block (insns, operands[0], operands[1], 0, 0);
+ DONE;
+}")
+
+(define_expand "abssf2"
+ [(set (match_operand:SF 0 "register_operand" "")
+ (abs:SF (match_operand:SF 1 "register_operand" "")))]
+ ""
+ "
+{
+ rtx result;
+ rtx target;
+
+ target = operand_subword_force (operands[0], 0, SFmode);
+ result = expand_binop (SImode, and_optab,
+ operand_subword_force (operands[1], 0, SFmode),
+ GEN_INT(0x7fffffff), target, 0, OPTAB_WIDEN);
+ if (result == 0)
+ abort ();
+
+ if (result != target)
+ emit_move_insn (result, target);
+
+ /* Make a place for REG_EQUAL. */
+ emit_move_insn (operands[0], operands[0]);
+ DONE;
+}")
+
+
+(define_expand "negdf2"
+ [(set (match_operand:DF 0 "register_operand" "")
+ (neg:DF (match_operand:DF 1 "register_operand" "")))]
+ ""
+ "
+{
+ rtx target, result, insns;
+
+ start_sequence ();
+ target = operand_subword (operands[0], 1, 1, DFmode);
+ result = expand_binop (SImode, xor_optab,
+ operand_subword_force (operands[1], 1, DFmode),
+ GEN_INT(0x80000000), target, 0, OPTAB_WIDEN);
+
+ if (result == 0)
+ abort ();
+
+ if (result != target)
+ emit_move_insn (result, target);
+
+ emit_move_insn (operand_subword (operands[0], 0, 1, DFmode),
+ operand_subword_force (operands[1], 0, DFmode));
+
+ insns = get_insns ();
+ end_sequence ();
+
+ emit_no_conflict_block (insns, operands[0], operands[1], 0, 0);
+ DONE;
+}")
+
+(define_expand "negsf2"
+ [(set (match_operand:SF 0 "register_operand" "")
+ (neg:SF (match_operand:SF 1 "register_operand" "")))]
+ ""
+ "
+{
+ rtx result;
+ rtx target;
+
+ target = operand_subword_force (operands[0], 0, SFmode);
+ result = expand_binop (SImode, xor_optab,
+ operand_subword_force (operands[1], 0, SFmode),
+ GEN_INT(0x80000000), target, 0, OPTAB_WIDEN);
+ if (result == 0)
+ abort ();
+
+ if (result != target)
+ emit_move_insn (result, target);
+
+ /* Make a place for REG_EQUAL. */
+ emit_move_insn (operands[0], operands[0]);
+ DONE;
+}")
+
+
+;; ----------------------------------------------------------------------
;; PROLOGUE/EPILOGUE
;; ----------------------------------------------------------------------
(define_expand "prologue"
diff --git a/gcc/config/nextstep.h b/gcc/config/nextstep.h
index a3919f7f023..59050a18a9e 100644
--- a/gcc/config/nextstep.h
+++ b/gcc/config/nextstep.h
@@ -291,7 +291,7 @@ extern int handle_pragma ();
else if (!strncmp (NAME, "_OBJC_", 6)) fprintf (FILE, "L%s", NAME); \
else if (!strncmp (NAME, ".objc_class_name_", 17)) \
fprintf (FILE, "%s", NAME); \
- else fprintf (FILE, "%s%s", USER_LABEL_PREFIX, NAME); } while (0)
+ else asm_fprintf (FILE, "%U%s", NAME); } while (0)
#undef ALIGN_ASM_OP
#define ALIGN_ASM_OP ".align"
diff --git a/gcc/config/ns32k/netbsd.h b/gcc/config/ns32k/netbsd.h
index cef68d82c2e..bc86e31ccb6 100644
--- a/gcc/config/ns32k/netbsd.h
+++ b/gcc/config/ns32k/netbsd.h
@@ -24,9 +24,10 @@ Boston, MA 02111-1307, USA.
/* Compile for the floating point unit & 32532 by default;
Don't assume SB is zero;
- Don't use bitfield instructions; */
+ Don't use bitfield instructions;
+ FPU is 32381; */
-#define TARGET_DEFAULT (1 + 24 + 32 + 64)
+#define TARGET_DEFAULT (1 + 24 + 32 + 64 + 256)
/* 32-bit alignment for efficiency */
@@ -68,7 +69,7 @@ Boston, MA 02111-1307, USA.
/* Names to predefine in the preprocessor for this target machine. */
#undef CPP_PREDEFINES
-#define CPP_PREDEFINES "-Dunix -Dns32k -Dns32000 -Dns32532 -D__NetBSD__ -Dpc532 -D__ns32k__ -Asystem(unix) -Asystem(NetBSD) -Acpu(ns32k) -Amachine(ns32k)"
+#define CPP_PREDEFINES "-Dns32k -Dns32000 -Dns32532 -D__NetBSD__ -Dpc532 -D__ns32k__ -D__KPRINTF_ATTRIBUTE__ -Asystem(unix) -Asystem(NetBSD) -Acpu(ns32k) -Amachine(ns32k)"
/* Make gcc agree with <machine/ansi.h> */
diff --git a/gcc/config/ns32k/ns32k.c b/gcc/config/ns32k/ns32k.c
index 8c2fb1f784b..af89e5999e0 100644
--- a/gcc/config/ns32k/ns32k.c
+++ b/gcc/config/ns32k/ns32k.c
@@ -20,7 +20,7 @@ Boston, MA 02111-1307, USA. */
/* Some output-actions in ns32k.md need these. */
#include "config.h"
-#include <stdio.h>
+#include "system.h"
#include "rtl.h"
#include "regs.h"
#include "hard-reg-set.h"
@@ -30,11 +30,33 @@ Boston, MA 02111-1307, USA. */
#include "insn-flags.h"
#include "output.h"
#include "insn-attr.h"
+#include "tree.h"
+#include "expr.h"
+#include "flags.h"
#ifdef OSF_OS
int ns32k_num_files = 0;
#endif
+/* This duplicates reg_class_contens in reg_class.c, but maybe that isn't
+ initialized in time. Also this is more convenient as an array of ints.
+ We know that HARD_REG_SET fits in an unsigned int */
+
+unsigned int ns32k_reg_class_contents[N_REG_CLASSES] = REG_CLASS_CONTENTS;
+
+enum reg_class regclass_map[FIRST_PSEUDO_REGISTER] =
+{
+ GENERAL_REGS, GENERAL_REGS, GENERAL_REGS, GENERAL_REGS,
+ GENERAL_REGS, GENERAL_REGS, GENERAL_REGS, GENERAL_REGS,
+ FLOAT_REG0, LONG_FLOAT_REG0, FLOAT_REGS, FLOAT_REGS,
+ FLOAT_REGS, FLOAT_REGS, FLOAT_REGS, FLOAT_REGS,
+ FP_REGS, FP_REGS, FP_REGS, FP_REGS,
+ FP_REGS, FP_REGS, FP_REGS, FP_REGS,
+ FRAME_POINTER_REG, STACK_POINTER_REG
+};
+
+char *ns32k_out_reg_names[] = OUTPUT_REGISTER_NAMES;
+
void
trace (s, s1, s2)
char *s, *s1, *s2;
@@ -42,78 +64,67 @@ trace (s, s1, s2)
fprintf (stderr, s, s1, s2);
}
-/* Value is 1 if hard register REGNO can hold a value of machine-mode MODE. */
+/* Value is 1 if hard register REGNO can hold a value of machine-mode MODE. */
int
hard_regno_mode_ok (regno, mode)
int regno;
enum machine_mode mode;
{
- switch (mode)
+ int size = GET_MODE_UNIT_SIZE(mode);
+
+ if (FLOAT_MODE_P(mode))
{
- case QImode:
- case HImode:
- case PSImode:
- case SImode:
- case PDImode:
- case VOIDmode:
- case BLKmode:
- if (regno < 8 || regno == 16 || regno == 17)
+ if (size == UNITS_PER_WORD && regno < L1_REGNUM)
return 1;
- else
- return 0;
-
- case DImode:
- if (regno < 8 && (regno & 1) == 0)
+ if (size == UNITS_PER_WORD * 2
+ && (((regno & 1) == 0 && regno < FRAME_POINTER_REGNUM)))
return 1;
- else
- return 0;
-
- case SFmode:
- case SCmode:
- if (TARGET_32081)
- {
- if (regno < 16)
- return 1;
- else
- return 0;
- }
- else
- {
- if (regno < 8)
- return 1;
- else
- return 0;
- }
-
- case DFmode:
- case DCmode:
- if ((regno & 1) == 0)
- {
- if (TARGET_32081)
- {
- if (regno < 16)
- return 1;
- else
- return 0;
- }
- else
- {
- if (regno < 8)
- return 1;
- else
- return 0;
- }
- }
- else
- return 0;
+ return 0;
}
-
- /* Used to abort here, but simply saying "no" handles TImode
- much better. */
+ if (size == UNITS_PER_WORD * 2
+ && (regno & 1) == 0 && regno < F0_REGNUM)
+ return 1;
+ if (size <= UNITS_PER_WORD
+ && (regno < F0_REGNUM || regno == FRAME_POINTER_REGNUM
+ || regno == STACK_POINTER_REGNUM))
+ return 1;
return 0;
}
+int register_move_cost(CLASS1, CLASS2)
+ enum reg_class CLASS1;
+ enum reg_class CLASS2;
+{
+ if (CLASS1 == NO_REGS || CLASS2 == NO_REGS)
+ return 2;
+ if((SUBSET_P(CLASS1, FP_REGS) && !SUBSET_P(CLASS2, FP_REGS))
+ || (!SUBSET_P(CLASS1, FP_REGS) && SUBSET_P(CLASS2, FP_REGS)))
+ return 8;
+ if (((CLASS1) == STACK_POINTER_REG && !SUBSET_P(CLASS2,GENERAL_REGS))
+ || ((CLASS2) == STACK_POINTER_REG && !SUBSET_P(CLASS1,GENERAL_REGS)))
+ return 6;
+ if (((CLASS1) == FRAME_POINTER_REG && !SUBSET_P(CLASS2,GENERAL_REGS))
+ || ((CLASS2) == FRAME_POINTER_REG && !SUBSET_P(CLASS1,GENERAL_REGS)))
+ return 6;
+ return 2;
+}
+
+#if 0
+/* We made the insn definitions copy from floating point to general
+ registers via the stack. */
+int secondary_memory_needed(CLASS1, CLASS2, M)
+ enum reg_class CLASS1;
+ enum reg_class CLASS2;
+ enum machine_mode M;
+{
+ int ret = ((SUBSET_P(CLASS1, FP_REGS) && !SUBSET_P(CLASS2, FP_REGS))
+ || (!SUBSET_P(CLASS1, FP_REGS) && SUBSET_P(CLASS2, FP_REGS)));
+ return ret;
+}
+#endif
+
+
/* ADDRESS_COST calls this. This function is not optimal
for the 32032 & 32332, but it probably is better than
the default. */
@@ -146,8 +157,10 @@ calc_address_cost (operand)
case POST_DEC:
case PRE_DEC:
break;
- case MULT:
case MEM:
+ cost += calc_address_cost (XEXP (operand, 0));
+ break;
+ case MULT:
case PLUS:
for (i = 0; i < GET_RTX_LENGTH (GET_CODE (operand)); i++)
{
@@ -174,30 +187,18 @@ secondary_reload_class (class, mode, in)
if (regno >= FIRST_PSEUDO_REGISTER)
regno = -1;
- /* We can place anything into GENERAL_REGS and can put GENERAL_REGS
- into anything. */
- if (class == GENERAL_REGS || (regno >= 0 && regno < 8))
- return NO_REGS;
-
- /* Constants, memory, and FP registers can go into FP registers. */
- if ((regno == -1 || (regno >= 8 && regno < 16)) && (class == FLOAT_REGS))
- return NO_REGS;
-
-#if 0 /* This isn't strictly true (can't move fp to sp or vice versa),
- so it's cleaner to use PREFERRED_RELOAD_CLASS
- to make the right things happen. */
- if (regno >= 16 && class == GEN_AND_MEM_REGS)
+ if ((class == FRAME_POINTER_REG && regno == STACK_POINTER_REGNUM)
+ || ( class == STACK_POINTER_REG && regno == FRAME_POINTER_REGNUM))
+ return GENERAL_REGS;
+ else
return NO_REGS;
-#endif
-
- /* Otherwise, we need GENERAL_REGS. */
- return GENERAL_REGS;
}
+
/* Generate the rtx that comes from an address expression in the md file */
/* The expression to be build is BASE[INDEX:SCALE]. To recognize this,
scale must be converted from an exponent (from ASHIFT) to a
multiplier (for MULT). */
-rtx
+static rtx
gen_indexed_expr (base, index, scale)
rtx base, index, scale;
{
@@ -226,6 +227,7 @@ reg_or_mem_operand (op, mode)
|| GET_CODE (op) == SUBREG
|| GET_CODE (op) == MEM));
}
+
/* Split one or more DImode RTL references into pairs of SImode
references. The RTL can be REG, offsettable MEM, integer constant, or
@@ -404,27 +406,163 @@ output_move_double (operands)
return singlemove_string (operands);
}
-int
-check_reg (oper, reg)
- rtx oper;
- int reg;
+
+#define MAX_UNALIGNED_COPY (32)
+/* Expand string/block move operations.
+
+ operands[0] is the pointer to the destination.
+ operands[1] is the pointer to the source.
+ operands[2] is the number of bytes to move.
+ operands[3] is the alignment. */
+
+static void
+move_tail(operands, bytes, offset)
+ rtx operands[];
+ int bytes;
+ int offset;
{
- register int i;
+ if (bytes & 2)
+ {
+ rtx src, dest;
+ dest = change_address(operands[0], HImode,
+ plus_constant(XEXP(operands[0], 0), offset));
+ src = change_address(operands[1], HImode,
+ plus_constant(XEXP(operands[1], 0), offset));
+ emit_move_insn(dest, src);
+ offset += 2;
+ }
+ if (bytes & 1)
+ {
+ rtx src, dest;
+ dest = change_address(operands[0], QImode,
+ plus_constant(XEXP(operands[0], 0), offset));
+ src = change_address(operands[1], QImode,
+ plus_constant(XEXP(operands[1], 0), offset));
+ emit_move_insn(dest, src);
+ }
+}
- if (oper == 0)
- return 0;
- switch (GET_CODE(oper))
+void
+expand_block_move (operands)
+ rtx operands[];
+{
+ rtx bytes_rtx = operands[2];
+ rtx align_rtx = operands[3];
+ int constp = (GET_CODE (bytes_rtx) == CONST_INT);
+ int bytes = (constp ? INTVAL (bytes_rtx) : 0);
+ int align = INTVAL (align_rtx);
+ rtx src_reg = gen_rtx(REG, Pmode, 1);
+ rtx dest_reg = gen_rtx(REG, Pmode, 2);
+ rtx count_reg = gen_rtx(REG, SImode, 0);
+ rtx insn;
+
+ if (constp && bytes <= 0)
+ return;
+
+ if (constp && bytes < 20)
{
- case REG:
- return (REGNO(oper) == reg) ? 1 : 0;
- case MEM:
- return check_reg(XEXP(oper, 0), reg);
- case PLUS:
- case MULT:
- return check_reg(XEXP(oper, 0), reg) || check_reg(XEXP(oper, 1), reg);
+ int words = bytes >> 2;
+ if (words)
+ if (words < 3 || flag_unroll_loops)
+ {
+ int offset = 0;
+ for (; words; words--, offset += 4)
+ {
+ rtx src, dest;
+ dest = change_address(operands[0], SImode,
+ plus_constant(XEXP(operands[0], 0), offset));
+ src = change_address(operands[1], SImode,
+ plus_constant(XEXP(operands[1], 0), offset));
+ emit_move_insn(dest, src);
+ }
+ }
+ else
+ {
+ /* Use movmd. It is slower than multiple movd's but more
+ compact. It is also slower than movsd for large copies
+ but causes less registers reloading so is better than movsd
+ for small copies. */
+ rtx src, dest;
+ dest = copy_addr_to_reg (XEXP(operands[0], 0));
+ src = copy_addr_to_reg (XEXP(operands[1], 0));
+
+ emit_insn(gen_movstrsi2(dest, src, GEN_INT(words)));
+ }
+ move_tail(operands, bytes & 3, bytes & ~3);
+ return;
+ }
+
+ if (align > UNITS_PER_WORD)
+ align = UNITS_PER_WORD;
+
+ /* Move the address into scratch registers. */
+ emit_insn(gen_rtx(CLOBBER, VOIDmode, dest_reg));
+ emit_move_insn(dest_reg, XEXP (operands[0], 0));
+ emit_insn(gen_rtx(CLOBBER, VOIDmode, src_reg));
+ emit_move_insn(src_reg, XEXP (operands[1], 0));
+ emit_insn(gen_rtx(CLOBBER, VOIDmode, count_reg));
+
+ if (constp && (align == UNITS_PER_WORD || bytes < MAX_UNALIGNED_COPY))
+ {
+ rtx bytes_reg;
+
+ /* constant no of bytes and aligned or small enough copy to not bother
+ * aligning. Emit insns to copy by words.
+ */
+ if (bytes >> 2)
+ {
+ emit_move_insn(count_reg, GEN_INT(bytes >> 2));
+ emit_insn(gen_movstrsi1 (GEN_INT(4)));
+ }
+ /* insns to copy rest */
+ move_tail(operands, bytes & 3, bytes & ~3);
+ }
+ else if (align == UNITS_PER_WORD)
+ {
+ /* insns to copy by words */
+ emit_insn(gen_lshrsi3 (count_reg, bytes_rtx, GEN_INT(2)));
+ emit_insn(gen_movstrsi1 (GEN_INT(4)));
+ /* insns to copy rest */
+ emit_insn(gen_andsi3 (count_reg, bytes_rtx, GEN_INT(3)));
+ emit_insn(gen_movstrsi1 (const1_rtx));
+ }
+ else
+ {
+ /* Not aligned and we may have a lot to copy so it is worth
+ * aligning.
+ */
+ rtx aligned_label = gen_label_rtx ();
+ rtx bytes_reg;
+
+ bytes_reg = copy_to_mode_reg(SImode, bytes_rtx);
+ if (!constp)
+ {
+ /* Emit insns to test and skip over the alignment if it is
+ * not worth it. This doubles as a test to ensure that the alignment
+ * operation can't copy too many bytes
+ */
+ emit_insn(gen_cmpsi (bytes_reg, GEN_INT(MAX_UNALIGNED_COPY)));
+ emit_jump_insn (gen_blt (aligned_label));
+ }
+
+ /* Emit insns to do alignment at run time */
+ emit_insn(gen_negsi2 (count_reg, src_reg));
+ emit_insn(gen_andsi3 (count_reg, count_reg, GEN_INT(3)));
+ emit_insn(gen_subsi3 (bytes_reg, bytes_reg, count_reg));
+ emit_insn(gen_movstrsi1 (const1_rtx));
+ if (!constp)
+ emit_label (aligned_label);
+
+ /* insns to copy by words */
+ emit_insn (gen_lshrsi3 (count_reg, bytes_reg, GEN_INT(2)));
+ emit_insn(gen_movstrsi1 (GEN_INT(4)));
+
+ /* insns to copy rest */
+ emit_insn (gen_andsi3 (count_reg, bytes_reg, GEN_INT(3)));
+ emit_insn(gen_movstrsi1 (const1_rtx));
}
- return 0;
}
+
/* Returns 1 if OP contains a global symbol reference */
@@ -466,10 +604,142 @@ global_symbolic_reference_mentioned_p (op, f)
}
+/* Returns 1 if OP contains a symbol reference */
+
+int
+symbolic_reference_mentioned_p (op)
+ rtx op;
+{
+ register char *fmt;
+ register int i;
+
+ if (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF)
+ return 1;
+
+ fmt = GET_RTX_FORMAT (GET_CODE (op));
+ for (i = GET_RTX_LENGTH (GET_CODE (op)) - 1; i >= 0; i--)
+ {
+ if (fmt[i] == 'E')
+ {
+ register int j;
+
+ for (j = XVECLEN (op, i) - 1; j >= 0; j--)
+ if (symbolic_reference_mentioned_p (XVECEXP (op, i, j)))
+ return 1;
+ }
+ else if (fmt[i] == 'e' && symbolic_reference_mentioned_p (XEXP (op, i)))
+ return 1;
+ }
+
+ return 0;
+}
+
+/* Return nonzero if IDENTIFIER with arguments ARGS is a valid machine specific
+ attribute for DECL. The attributes in ATTRIBUTES have previously been
+ assigned to DECL. */
+
+int
+ns32k_valid_decl_attribute_p (decl, attributes, identifier, args)
+ tree decl;
+ tree attributes;
+ tree identifier;
+ tree args;
+{
+ return 0;
+}
+
+/* Return nonzero if IDENTIFIER with arguments ARGS is a valid machine specific
+ attribute for TYPE. The attributes in ATTRIBUTES have previously been
+ assigned to TYPE. */
+
+int
+ns32k_valid_type_attribute_p (type, attributes, identifier, args)
+ tree type;
+ tree attributes;
+ tree identifier;
+ tree args;
+{
+ if (TREE_CODE (type) != FUNCTION_TYPE
+ && TREE_CODE (type) != FIELD_DECL
+ && TREE_CODE (type) != TYPE_DECL)
+ return 0;
+
+ /* Stdcall attribute says callee is responsible for popping arguments
+ if they are not variable. */
+ if (is_attribute_p ("stdcall", identifier))
+ return (args == NULL_TREE);
+
+ /* Cdecl attribute says the callee is a normal C declaration */
+ if (is_attribute_p ("cdecl", identifier))
+ return (args == NULL_TREE);
+
+ return 0;
+}
+
+/* Return 0 if the attributes for two types are incompatible, 1 if they
+ are compatible, and 2 if they are nearly compatible (which causes a
+ warning to be generated). */
+
+int
+ns32k_comp_type_attributes (type1, type2)
+ tree type1;
+ tree type2;
+{
+ return 1;
+}
+
+
+/* Value is the number of bytes of arguments automatically
+ popped when returning from a subroutine call.
+ FUNDECL is the declaration node of the function (as a tree),
+ FUNTYPE is the data type of the function (as a tree),
+ or for a library call it is an identifier node for the subroutine name.
+ SIZE is the number of bytes of arguments passed on the stack.
+
+ On the ns32k, the RET insn may be used to pop them if the number
+ of args is fixed, but if the number is variable then the caller
+ must pop them all. RET can't be used for library calls now
+ because the library is compiled with the Unix compiler.
+ Use of RET is a selectable option, since it is incompatible with
+ standard Unix calling sequences. If the option is not selected,
+ the caller must always pop the args.
+
+ The attribute stdcall is equivalent to RET on a per module basis. */
+
+int
+ns32k_return_pops_args (fundecl, funtype, size)
+ tree fundecl;
+ tree funtype;
+ int size;
+{
+ int rtd = TARGET_RTD;
+
+ if (TREE_CODE (funtype) == IDENTIFIER_NODE)
+ return rtd ? size : 0;
+
+ /* Cdecl functions override -mrtd, and never pop the stack */
+ if (lookup_attribute ("cdecl", TYPE_ATTRIBUTES (funtype)))
+ return 0;
+
+ /* Stdcall functions will pop the stack if not variable args */
+ if (lookup_attribute ("stdcall", TYPE_ATTRIBUTES (funtype)))
+ rtd = 1;
+
+ if (rtd)
+ {
+ if (TYPE_ARG_TYPES (funtype) == NULL_TREE
+ || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (funtype))) == void_type_node))
+ return size;
+ }
+
+ return 0;
+}
+
/* PRINT_OPERAND is defined to call this function,
which is easier to debug than putting all the code in
a macro definition in ns32k.h. */
+/* XXX time 12% of cpu time is in fprintf for non optimizing */
void
print_operand (file, x, code)
FILE *file;
@@ -481,7 +751,7 @@ print_operand (file, x, code)
else if (code == '?')
PUT_EXTERNAL_PREFIX (file);
else if (GET_CODE (x) == REG)
- fprintf (file, "%s", reg_names[REGNO (x)]);
+ fprintf (file, "%s", ns32k_out_reg_names[REGNO (x)]);
else if (GET_CODE (x) == MEM)
{
rtx tmp = XEXP (x, 0);
@@ -528,11 +798,30 @@ print_operand (file, x, code)
}
else
{
+ if (flag_pic
+ && GET_CODE (x) == CONST
+ && symbolic_reference_mentioned_p (x))
+ {
+ fprintf(stderr, "illegal constant for pic-mode: \n");
+ print_rtl(stderr, x);
+ fprintf(stderr, "\nGET_CODE (x) == %d, CONST == %d, symbolic_reference_mentioned_p (x) == %d\n",
+ GET_CODE (x), CONST, symbolic_reference_mentioned_p(x));
+ abort ();
+ }
+ else if (flag_pic
+ && (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == LABEL_REF))
+ {
+ output_addr_const (file, x);
+ fprintf (file, "(sb)");
+ }
+ else
+ {
#ifdef NO_IMMEDIATE_PREFIX_IF_SYMBOLIC
- if (GET_CODE (x) == CONST_INT)
+ if (GET_CODE (x) == CONST_INT)
#endif
- PUT_IMMEDIATE_PREFIX (file);
- output_addr_const (file, x);
+ PUT_IMMEDIATE_PREFIX (file);
+ output_addr_const (file, x);
+ }
}
}
@@ -545,6 +834,7 @@ print_operand (file, x, code)
figure out how it worked.
90-11-25 Tatu Yl|nen <ylo@cs.hut.fi> */
+void
print_operand_address (file, addr)
register FILE *file;
register rtx addr;
@@ -597,7 +887,7 @@ print_operand_address (file, addr)
base = tmp;
break;
case REG:
- if (REGNO (tmp) < 8)
+ if (REGNO (tmp) < F0_REGNUM)
if (base)
{
indexexp = tmp;
@@ -728,7 +1018,7 @@ print_operand_address (file, addr)
(disp(sb)) (MEM ...)
*/
case REG:
- fprintf (file, "(%s)", reg_names[REGNO (base)]);
+ fprintf (file, "(%s)", ns32k_out_reg_names[REGNO (base)]);
break;
case SYMBOL_REF:
if (! flag_pic)
@@ -785,7 +1075,7 @@ print_operand_address (file, addr)
fprintf (file, "(");
output_addr_const (file, offset);
if (base)
- fprintf (file, "(%s)", reg_names[REGNO (base)]);
+ fprintf (file, "(%s)", ns32k_out_reg_names[REGNO (base)]);
else if (TARGET_SB)
fprintf (file, "(sb)");
else
@@ -816,16 +1106,16 @@ print_operand_address (file, addr)
}
else
scale = 0;
- if (GET_CODE (indexexp) != REG || REGNO (indexexp) >= 8)
+ if (GET_CODE (indexexp) != REG || REGNO (indexexp) >= F0_REGNUM)
abort ();
#ifdef UTEK_ASM
fprintf (file, "[%c`%s]",
scales[scale],
- reg_names[REGNO (indexexp)]);
+ ns32k_out_reg_names[REGNO (indexexp)]);
#else
fprintf (file, "[%s:%c]",
- reg_names[REGNO (indexexp)],
+ ns32k_out_reg_names[REGNO (indexexp)],
scales[scale]);
#endif
}
diff --git a/gcc/config/ns32k/ns32k.h b/gcc/config/ns32k/ns32k.h
index 7c138a4d18b..d409ac26408 100644
--- a/gcc/config/ns32k/ns32k.h
+++ b/gcc/config/ns32k/ns32k.h
@@ -23,8 +23,6 @@ Boston, MA 02111-1307, USA. */
/* Note that some other tm.h files include this one and then override
many of the definitions that relate to assembler syntax. */
-extern enum reg_class secondary_reload_class();
-
/* Names to predefine in the preprocessor for this target machine. */
#define CPP_PREDEFINES "-Dns32000 -Dunix -Asystem(unix) -Acpu(ns32k) -Amachine(ns32k)"
@@ -66,6 +64,18 @@ extern int target_flags;
/* Compile 32081 insns for floating point (not library calls). */
#define TARGET_32081 (target_flags & 1)
+#define TARGET_32381 (target_flags & 256)
+
+/* The use of multiply-add instructions is optional because it can
+ * cause an abort due to being unable to find a spill register. The
+ * main problem is that the multiply-add instructions require f0 and
+ * f0 is not available for spilling because it is "explicitly
+ * mentioned" in the rtl for function return values. This can be fixed
+ * by defining SMALL_REGISTER_CLASSES, but that causes worse code for
+ * the (more common) integer case. We really need better reload code.
+ */
+
+#define TARGET_MULT_ADD (target_flags & 512)
/* Compile using rtd insn calling sequence.
This will not work unless you use prototypes at least
@@ -93,9 +103,9 @@ extern int target_flags;
where VALUE is the bits to set or minus the bits to clear.
An empty string NAME is used to identify the default VALUE. */
-#define TARGET_SWITCHES \
+#define TARGET_SWITCHES \
{ { "32081", 1}, \
- { "soft-float", -1}, \
+ { "soft-float", -257}, \
{ "rtd", 2}, \
{ "nortd", -2}, \
{ "regparm", 4}, \
@@ -110,17 +120,66 @@ extern int target_flags;
{ "nobitfield", 64}, \
{ "himem", 128}, \
{ "nohimem", -128}, \
+ { "32381", 256}, \
+ { "mult-add", 512}, \
+ { "nomult-add", -512}, \
{ "", TARGET_DEFAULT}}
+
/* TARGET_DEFAULT is defined in encore.h, pc532.h, etc. */
/* When we are generating PIC, the sb is used as a pointer
- to the GOT. */
+ to the GOT. 32381 is a superset of 32081 */
-#define OVERRIDE_OPTIONS \
-{ \
+#define OVERRIDE_OPTIONS \
+{ \
if (flag_pic || TARGET_HIMEM) target_flags |= 32; \
+ if (TARGET_32381) target_flags |= 1; \
+ else target_flags &= ~512; \
}
+/* Zero or more C statements that may conditionally modify two
+ variables `fixed_regs' and `call_used_regs' (both of type `char
+ []') after they have been initialized from the two preceding
+ macros.
+
+ This is necessary in case the fixed or call-clobbered registers
+ depend on target flags.
+
+ You need not define this macro if it has no work to do.
+
+ If the usage of an entire class of registers depends on the target
+ flags, you may indicate this to GCC by using this macro to modify
+ `fixed_regs' and `call_used_regs' to 1 for each of the registers in
+ the classes which should not be used by GCC. Also define the macro
+ `REG_CLASS_FROM_LETTER' to return `NO_REGS' if it is called with a
+ letter for a class that shouldn't be used.
+
+ (However, if this class is not included in `GENERAL_REGS' and all
+ of the insn patterns whose constraints permit this class are
+ controlled by target switches, then GCC will automatically avoid
+ using these registers when the target switches are opposed to
+ them.) */
+
+#define CONDITIONAL_REGISTER_USAGE \
+do \
+ { \
+ if (!TARGET_32081) \
+ { \
+ int regno; \
+ \
+ for (regno = F0_REGNUM; regno <= F0_REGNUM + 8; regno++) \
+ fixed_regs[regno] = call_used_regs[regno] = 1; \
+ } \
+ if (!TARGET_32381) \
+ { \
+ int regno; \
+ \
+ for (regno = L1_REGNUM; regno <= L1_REGNUM + 8; regno++) \
+ fixed_regs[regno] = call_used_regs[regno] = 1; \
+ } \
+ } \
+while (0)
+
/* target machine storage layout */
@@ -190,13 +249,14 @@ extern int target_flags;
from 0 to just below FIRST_PSEUDO_REGISTER.
All registers that the compiler knows about must be given numbers,
even those that are not normally considered general registers. */
-#define FIRST_PSEUDO_REGISTER 18
+#define FIRST_PSEUDO_REGISTER 26
/* 1 for registers that have pervasive standard uses
and are not available for the register allocator.
On the ns32k, these are the FP, SP, (SB and PC are not included here). */
#define FIXED_REGISTERS {0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, \
+ 0, 0, 0, 0, 0, 0, 0, 0, \
1, 1}
/* 1 for registers not available across function calls.
@@ -207,13 +267,70 @@ extern int target_flags;
Aside from that, you can include as many other registers as you like. */
#define CALL_USED_REGISTERS {1, 1, 1, 0, 0, 0, 0, 0, \
1, 1, 1, 1, 0, 0, 0, 0, \
+ 1, 1, 0, 0, 0, 0, 0, 0, \
1, 1}
+/* How to refer to registers in assembler output.
+ This sequence is indexed by compiler's hard-register-number (see above). */
+
+#define REGISTER_NAMES \
+{"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", \
+ "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", \
+ "l1", "l1h","l3", "l3h","l5", "l5h","l7", "l7h", \
+ "fp", "sp"}
+
+
+#define ADDITIONAL_REGISTER_NAMES \
+{{"l0", 8}, {"l2", 10}, {"l4", 12}, {"l6", 14}}
+
+/* l0-7 are not recognized by the assembler. These are the names to use,
+ * but we don't want ambiguous names in REGISTER_NAMES
+ */
+#define OUTPUT_REGISTER_NAMES \
+{"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", \
+ "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", \
+ "f1", "l1h","f3", "l3h","f5", "l5h","f7", "f7h", \
+ "fp", "sp"}
+
+#define REG_ALLOC_ORDER \
+{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 16, 10, 11, 18, 12, 13, 20, 14, 15, 22, 24, 25, 17, 19, 23}
+
+/* How to renumber registers for dbx and gdb.
+ NS32000 may need more change in the numeration. XXX */
+
+#define DBX_REGISTER_NUMBER(REGNO) \
+ ((REGNO) < L1_REGNUM? (REGNO) \
+ : (REGNO) < FRAME_POINTER_REGNUM? (REGNO) - L1_REGNUM + 22 \
+ : (REGNO) == FRAME_POINTER_REGNUM? 17 \
+ : 16)
+
+
+
+
+#define R0_REGNUM 0
+#define F0_REGNUM 8
+#define L1_REGNUM 16
+
+/* Specify the registers used for certain standard purposes.
+ The values of these macros are register numbers. */
+
+/* NS32000 pc is not overloaded on a register. */
+/* #define PC_REGNUM */
+
+/* Register to use for pushing function arguments. */
+#define STACK_POINTER_REGNUM 25
+
+/* Base register for access to local variables of the function. */
+#define FRAME_POINTER_REGNUM 24
+
+
/* Return number of consecutive hard regs needed starting at reg REGNO
to hold something of mode MODE.
This is ordinarily the length in words of a value of mode MODE
but can be less for certain modes in special long registers.
- On the ns32k, all registers are 32 bits long. */
+ On the ns32k, all registers are 32 bits long except for the 32381 "long"
+ registers but we treat those as pairs */
+#define LONG_FP_REGS_P(REGNO) ((REGNO) >= L1_REGNUM && (REGNO) < L1_REGNUM + 8)
#define HARD_REGNO_NREGS(REGNO, MODE) \
((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
@@ -223,22 +340,19 @@ extern int target_flags;
/* Value is 1 if it is a good idea to tie two pseudo registers
when one has mode MODE1 and one has mode MODE2.
If HARD_REGNO_MODE_OK could produce different values for MODE1 and MODE2,
- for any hard reg, then this must be 0 for correct output. */
-#define MODES_TIEABLE_P(MODE1, MODE2) \
- (((MODE1) == DFmode || (MODE1) == DCmode || (MODE1) == DImode) == \
- ((MODE2) == DFmode || (MODE2) == DCmode || (MODE2) == DImode))
+ for any hard reg, then this must be 0 for correct output.
-/* Specify the registers used for certain standard purposes.
- The values of these macros are register numbers. */
-
-/* NS32000 pc is not overloaded on a register. */
-/* #define PC_REGNUM */
+ Early documentation says SI and DI are not tieable if some reg can
+ be OK for SI but not for DI. However other ports (mips, i860, mvs
+ and tahoe) don't meet the above criterion. Evidently the real
+ requirement is somewhat laxer. Documentation was changed for gcc
+ 2.8 but was not picked up by egcs (at least egcs 1.0). Having all
+ integer modes tieable definitely generates faster code. */
-/* Register to use for pushing function arguments. */
-#define STACK_POINTER_REGNUM 17
-
-/* Base register for access to local variables of the function. */
-#define FRAME_POINTER_REGNUM 16
+#define MODES_TIEABLE_P(MODE1, MODE2) \
+ ((FLOAT_MODE_P(MODE1) && FLOAT_MODE_P(MODE2) \
+ && (GET_MODE_UNIT_SIZE(MODE1) == GET_MODE_UNIT_SIZE(MODE2))) \
+ || (!FLOAT_MODE_P(MODE1) && !FLOAT_MODE_P(MODE2)))
/* Value should be nonzero if functions must have frame pointers.
Zero means the frame pointer need not be set up (and parms
@@ -247,7 +361,7 @@ extern int target_flags;
#define FRAME_POINTER_REQUIRED 0
/* Base register for access to arguments of the function. */
-#define ARG_POINTER_REGNUM 16
+#define ARG_POINTER_REGNUM 24
/* Register in which static-chain is passed to a function. */
#define STATIC_CHAIN_REGNUM 1
@@ -275,37 +389,39 @@ extern int target_flags;
For any two classes, it is very desirable that there be another
class that represents their union. */
-
-enum reg_class { NO_REGS, GENERAL_REGS, FLOAT_REGS, GEN_AND_FP_REGS,
- FRAME_POINTER_REG, STACK_POINTER_REG,
- GEN_AND_MEM_REGS, ALL_REGS, LIM_REG_CLASSES };
+
+enum reg_class
+{ NO_REGS, GENERAL_REGS, FLOAT_REG0, LONG_FLOAT_REG0, FLOAT_REGS,
+ FP_REGS, GEN_AND_FP_REGS, FRAME_POINTER_REG, STACK_POINTER_REG,
+ GEN_AND_MEM_REGS, ALL_REGS, LIM_REG_CLASSES };
#define N_REG_CLASSES (int) LIM_REG_CLASSES
/* Give names of register classes as strings for dump file. */
#define REG_CLASS_NAMES \
- {"NO_REGS", "GENERAL_REGS", "FLOAT_REGS", "GEN_AND_FP_REGS", \
- "FRAME_POINTER_REG", "STACK_POINTER_REG", "GEN_AND_MEM_REGS", "ALL_REGS" }
+ {"NO_REGS", "GENERAL_REGS", "FLOAT_REG0", "LONG_FLOAT_REG0", "FLOAT_REGS", \
+ "FP_REGS", "GEN_AND_FP_REGS", "FRAME_POINTER_REG", "STACK_POINTER_REG", \
+ "GEN_AND_MEM_REGS", "ALL_REGS" }
/* Define which registers fit in which classes.
This is an initializer for a vector of HARD_REG_SET
of length N_REG_CLASSES. */
-#define REG_CLASS_CONTENTS {0, 0x00ff, 0xff00, 0xffff, \
- 0x10000, 0x20000, 0x300ff, 0x3ffff }
+#define REG_CLASS_CONTENTS {0, 0x00ff, 0x100, 0x300, 0xff00, \
+ 0xffff00, 0xffffff, 0x1000000, 0x2000000, \
+ 0x30000ff, 0x3ffffff }
+
+#define SUBSET_P(CLASS1, CLASS2) \
+ ((ns32k_reg_class_contents[CLASS1] & ~ns32k_reg_class_contents[CLASS2]) \
+ == 0)
/* The same information, inverted:
Return the class number of the smallest class containing
reg number REGNO. This could be a conditional expression
or could index an array. */
-#define REGNO_REG_CLASS(REGNO) \
- ((REGNO) < 8 ? GENERAL_REGS \
- : (REGNO) < 16 ? FLOAT_REGS \
- : (REGNO) == 16 ? FRAME_POINTER_REG \
- : (REGNO) == 17 ? STACK_POINTER_REG \
- : NO_REGS)
+#define REGNO_REG_CLASS(REGNO) (regclass_map[REGNO])
/* The class value for index registers, and the one for base regs. */
@@ -314,10 +430,13 @@ enum reg_class { NO_REGS, GENERAL_REGS, FLOAT_REGS, GEN_AND_FP_REGS,
/* Get reg_class from a letter such as appears in the machine description. */
-#define REG_CLASS_FROM_LETTER(C) \
- ((C) == 'f' ? FLOAT_REGS \
- : (C) == 'x' ? FRAME_POINTER_REG \
- : (C) == 'y' ? STACK_POINTER_REG \
+#define REG_CLASS_FROM_LETTER(C) \
+ ((C) == 'u' ? FLOAT_REG0 \
+ : (C) == 'v' ? LONG_FLOAT_REG0 \
+ : (C) == 'f' ? FLOAT_REGS \
+ : (C) == 'l' ? FP_REGS \
+ : (C) == 'x' ? FRAME_POINTER_REG \
+ : (C) == 'y' ? STACK_POINTER_REG \
: NO_REGS)
/* The letters I, J, K, L and M in a register constraint string
@@ -353,13 +472,15 @@ enum reg_class { NO_REGS, GENERAL_REGS, FLOAT_REGS, GEN_AND_FP_REGS,
/* We return GENERAL_REGS instead of GEN_AND_MEM_REGS.
The latter offers no real additional possibilities
- and can cause spurious secondary reloading. */
+ and can cause spurious secondary reloading. */
+
#define PREFERRED_RELOAD_CLASS(X,CLASS) \
((CLASS) == GEN_AND_MEM_REGS ? GENERAL_REGS : (CLASS))
/* Return the maximum number of consecutive registers
needed to represent mode MODE in a register of class CLASS. */
/* On the 32000, this is the size of MODE in words */
+
#define CLASS_MAX_NREGS(CLASS, MODE) \
((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
@@ -381,6 +502,46 @@ enum reg_class { NO_REGS, GENERAL_REGS, FLOAT_REGS, GEN_AND_FP_REGS,
of the first local allocated. */
#define STARTING_FRAME_OFFSET 0
+/* A C expression whose value is RTL representing the location of the
+ incoming return address at the beginning of any function, before
+ the prologue. This RTL is either a `REG', indicating that the
+ return value is saved in `REG', or a `MEM' representing a location
+ in the stack.
+
+ You only need to define this macro if you want to support call
+ frame debugging information like that provided by DWARF 2.
+
+ Before the prologue, RA is at 0(sp). */
+
+#define INCOMING_RETURN_ADDR_RTX \
+ gen_rtx (MEM, VOIDmode, gen_rtx (REG, VOIDmode, STACK_POINTER_REGNUM))
+
+/* A C expression whose value is RTL representing the value of the
+ return address for the frame COUNT steps up from the current frame,
+ after the prologue. FRAMEADDR is the frame pointer of the COUNT
+ frame, or the frame pointer of the COUNT - 1 frame if
+ `RETURN_ADDR_IN_PREVIOUS_FRAME' is defined.
+
+ After the prologue, RA is at 4(fp) in the current frame. */
+
+#define RETURN_ADDR_RTX(COUNT, FRAME) \
+ (gen_rtx (MEM, Pmode, gen_rtx (PLUS, Pmode, (FRAME), GEN_INT(4))))
+
+/* A C expression whose value is an integer giving the offset, in
+ bytes, from the value of the stack pointer register to the top of
+ the stack frame at the beginning of any function, before the
+ prologue. The top of the frame is defined to be the value of the
+ stack pointer in the previous frame, just before the call
+ instruction.
+
+ You only need to define this macro if you want to support call
+ frame debugging information like that provided by DWARF 2. */
+
+#define INCOMING_FRAME_SP_OFFSET 4
+
+/* Offset of the CFA from the argument pointer register value. */
+#define ARG_POINTER_CFA_OFFSET 8
+
/* If we generate an insn to push BYTES bytes,
this says how many the stack pointer really advances by.
On the 32000, sp@- in a byte insn really pushes a BYTE. */
@@ -402,14 +563,12 @@ enum reg_class { NO_REGS, GENERAL_REGS, FLOAT_REGS, GEN_AND_FP_REGS,
because the library is compiled with the Unix compiler.
Use of RET is a selectable option, since it is incompatible with
standard Unix calling sequences. If the option is not selected,
- the caller must always pop the args. */
+ the caller must always pop the args.
+
+ The attribute stdcall is equivalent to RTD on a per module basis. */
-#define RETURN_POPS_ARGS(FUNDECL,FUNTYPE,SIZE) \
- ((TARGET_RTD && (!(FUNDECL) || TREE_CODE (FUNDECL) != IDENTIFIER_NODE) \
- && (TYPE_ARG_TYPES (FUNTYPE) == 0 \
- || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (FUNTYPE))) \
- == void_type_node))) \
- ? (SIZE) : 0)
+#define RETURN_POPS_ARGS(FUNDECL,FUNTYPE,SIZE) \
+ (ns32k_return_pops_args (FUNDECL, FUNTYPE, SIZE))
/* Define how to find the value returned by a function.
VALTYPE is the data type of the value (as a tree).
@@ -417,23 +576,19 @@ enum reg_class { NO_REGS, GENERAL_REGS, FLOAT_REGS, GEN_AND_FP_REGS,
otherwise, FUNC is 0. */
/* On the 32000 the return value is in R0,
- or perhaps in F0 is there is fp support. */
+ or perhaps in F0 if there is fp support. */
-#define FUNCTION_VALUE(VALTYPE, FUNC) \
- (TREE_CODE (VALTYPE) == REAL_TYPE && TARGET_32081 \
- ? gen_rtx (REG, TYPE_MODE (VALTYPE), 8) \
- : gen_rtx (REG, TYPE_MODE (VALTYPE), 0))
+#define FUNCTION_VALUE(VALTYPE, FUNC) LIBCALL_VALUE(TYPE_MODE (VALTYPE))
/* Define how to find the value returned by a library function
assuming the value has mode MODE. */
/* On the 32000 the return value is in R0,
- or perhaps F0 is there is fp support. */
+ or perhaps F0 is there is fp support. */
#define LIBCALL_VALUE(MODE) \
- (((MODE) == DFmode || (MODE) == SFmode) && TARGET_32081 \
- ? gen_rtx (REG, MODE, 8) \
- : gen_rtx (REG, MODE, 0))
+ gen_rtx (REG, MODE, \
+ FLOAT_MODE_P(MODE) && TARGET_32081 ? F0_REGNUM: R0_REGNUM)
/* Define this if PCC uses the nonreentrant convention for returning
structure and union values. */
@@ -554,18 +709,18 @@ enum reg_class { NO_REGS, GENERAL_REGS, FLOAT_REGS, GEN_AND_FP_REGS,
#define FUNCTION_PROLOGUE(FILE, SIZE) \
{ register int regno, g_regs_used = 0; \
int used_regs_buf[8], *bufp = used_regs_buf; \
- int used_fregs_buf[8], *fbufp = used_fregs_buf; \
+ int used_fregs_buf[17], *fbufp = used_fregs_buf; \
extern char call_used_regs[]; \
extern int current_function_uses_pic_offset_table, flag_pic; \
MAIN_FUNCTION_PROLOGUE; \
- for (regno = 0; regno < 8; regno++) \
+ for (regno = R0_REGNUM; regno < F0_REGNUM; regno++) \
if (regs_ever_live[regno] \
&& ! call_used_regs[regno]) \
{ \
*bufp++ = regno; g_regs_used++; \
} \
*bufp = -1; \
- for (; regno < 16; regno++) \
+ for (; regno < FRAME_POINTER_REGNUM; regno++) \
if (regs_ever_live[regno] && !call_used_regs[regno]) \
{ \
*fbufp++ = regno; \
@@ -600,11 +755,12 @@ enum reg_class { NO_REGS, GENERAL_REGS, FLOAT_REGS, GEN_AND_FP_REGS,
fbufp = used_fregs_buf; \
while (*fbufp >= 0) \
{ \
- if ((*fbufp & 1) || (fbufp[0] != fbufp[1] - 1)) \
- fprintf (FILE, "\tmovf f%d,tos\n", *fbufp++ - 8); \
+ if ((*fbufp & 1) || (fbufp[0] != fbufp[1] - 1)) \
+ fprintf (FILE, "\tmovf %s,tos\n", ns32k_out_reg_names[*fbufp++]); \
else \
{ \
- fprintf (FILE, "\tmovl f%d,tos\n", fbufp[0] - 8); \
+ fprintf (FILE, "\tmovl %s,tos\n", \
+ ns32k_out_reg_names[fbufp[0]]); \
fbufp += 2; \
} \
} \
@@ -678,19 +834,19 @@ enum reg_class { NO_REGS, GENERAL_REGS, FLOAT_REGS, GEN_AND_FP_REGS,
#define FUNCTION_EPILOGUE(FILE, SIZE) \
{ register int regno, g_regs_used = 0, f_regs_used = 0; \
int used_regs_buf[8], *bufp = used_regs_buf; \
- int used_fregs_buf[8], *fbufp = used_fregs_buf; \
+ int used_fregs_buf[17], *fbufp = used_fregs_buf; \
extern char call_used_regs[]; \
extern int current_function_uses_pic_offset_table, flag_pic; \
if (flag_pic && current_function_uses_pic_offset_table) \
fprintf (FILE, "\tlprd sb,tos\n"); \
*fbufp++ = -2; \
- for (regno = 8; regno < 16; regno++) \
+ for (regno = F0_REGNUM; regno < FRAME_POINTER_REGNUM; regno++) \
if (regs_ever_live[regno] && !call_used_regs[regno]) \
{ \
*fbufp++ = regno; f_regs_used++; \
} \
fbufp--; \
- for (regno = 0; regno < 8; regno++) \
+ for (regno = 0; regno < F0_REGNUM; regno++) \
if (regs_ever_live[regno] \
&& ! call_used_regs[regno]) \
{ \
@@ -698,12 +854,13 @@ enum reg_class { NO_REGS, GENERAL_REGS, FLOAT_REGS, GEN_AND_FP_REGS,
} \
while (fbufp > used_fregs_buf) \
{ \
- if ((*fbufp & 1) && fbufp[0] == fbufp[-1] + 1) \
+ if ((*fbufp & 1) && fbufp[0] == fbufp[-1] + 1) \
{ \
- fprintf (FILE, "\tmovl tos,f%d\n", fbufp[-1] - 8); \
+ fprintf (FILE, "\tmovl tos,%s\n", \
+ ns32k_out_reg_names[fbufp[-1]]); \
fbufp -= 2; \
} \
- else fprintf (FILE, "\tmovf tos,f%d\n", *fbufp-- - 8); \
+ else fprintf (FILE, "\tmovf tos,%s\n", ns32k_out_reg_names[*fbufp--]); \
} \
if (frame_pointer_needed) \
fprintf (FILE, "\texit ["); \
@@ -742,9 +899,12 @@ enum reg_class { NO_REGS, GENERAL_REGS, FLOAT_REGS, GEN_AND_FP_REGS,
int regno; \
int offset = -4; \
extern int current_function_uses_pic_offset_table, flag_pic; \
- for (regno = 0; regno < 16; regno++) \
+ for (regno = 0; regno < L1_REGNUM; regno++) \
if (regs_ever_live[regno] && ! call_used_regs[regno]) \
offset += 4; \
+ for (; regno < FRAME_POINTER_REGNUM; regno++) \
+ if (regs_ever_live[regno] && ! call_used_regs[regno]) \
+ offset += 8; \
if (flag_pic && current_function_uses_pic_offset_table) \
offset += 4; \
(DEPTH) = (offset + get_frame_size () \
@@ -808,11 +968,11 @@ __transfer_from_trampoline () \
/* Addressing modes, and classification of registers for them. */
-/* #define HAVE_POST_INCREMENT */
-/* #define HAVE_POST_DECREMENT */
+/* #define HAVE_POST_INCREMENT 0 */
+/* #define HAVE_POST_DECREMENT 0 */
-/* #define HAVE_PRE_DECREMENT */
-/* #define HAVE_PRE_INCREMENT */
+/* #define HAVE_PRE_DECREMENT 0 */
+/* #define HAVE_PRE_INCREMENT 0 */
/* Macros to check register numbers against specific register classes. */
@@ -824,12 +984,13 @@ __transfer_from_trampoline () \
/* note that FP and SP cannot be used as an index. What about PC? */
#define REGNO_OK_FOR_INDEX_P(REGNO) \
-((REGNO) < 8 || (unsigned)reg_renumber[REGNO] < 8)
+((REGNO) < F0_REGNUM || (unsigned)reg_renumber[REGNO] < F0_REGNUM)
#define REGNO_OK_FOR_BASE_P(REGNO) \
-((REGNO) < 8 || (unsigned)reg_renumber[REGNO] < 8 \
+((REGNO) < F0_REGNUM || (unsigned)reg_renumber[REGNO] < F0_REGNUM \
|| (REGNO) == FRAME_POINTER_REGNUM || (REGNO) == STACK_POINTER_REGNUM)
-#define FP_REG_P(X) (GET_CODE (X) == REG && REGNO (X) > 7 && REGNO (X) < 16)
+#define FP_REG_P(X) \
+ (GET_CODE (X) == REG && REGNO (X) >= F0_REGNUM && REGNO (X) < FRAME_POINTER_REGNUM)
/* Maximum number of registers that can appear in a valid memory address. */
@@ -838,19 +999,18 @@ __transfer_from_trampoline () \
/* Recognize any constant value that is a valid address.
This might not work on future ns32k processors as negative
displacements are not officially allowed but a mode reserved
- to National. This works on processors up to 32532, though. */
+ to National. This works on processors up to 32532, though,
+ and we don't expect any new ones in the series ;-( */
#define CONSTANT_ADDRESS_P(X) \
(GET_CODE (X) == LABEL_REF || GET_CODE (X) == SYMBOL_REF \
|| GET_CODE (X) == CONST \
|| (GET_CODE (X) == CONST_INT \
- && ((unsigned)INTVAL (X) >= 0xe0000000 \
- || (unsigned)INTVAL (X) < 0x20000000)))
+ && NS32K_DISPLACEMENT_P (INTVAL (X))))
#define CONSTANT_ADDRESS_NO_LABEL_P(X) \
(GET_CODE (X) == CONST_INT \
- && ((unsigned)INTVAL (X) >= 0xe0000000 \
- || (unsigned)INTVAL (X) < 0x20000000))
+ && NS32K_DISPLACEMENT_P (INTVAL (X)))
/* Return the register class of a scratch register needed to copy IN into
or out of a register in CLASS in MODE. If it can be done directly,
@@ -859,6 +1019,42 @@ __transfer_from_trampoline () \
#define SECONDARY_RELOAD_CLASS(CLASS,MODE,IN) \
secondary_reload_class (CLASS, MODE, IN)
+/* Certain machines have the property that some registers cannot be
+ copied to some other registers without using memory. Define this
+ macro on those machines to be a C expression that is non-zero if
+ objects of mode M in registers of CLASS1 can only be copied to
+ registers of class CLASS2 by storing a register of CLASS1 into
+ memory and loading that memory location into a register of CLASS2.
+
+ On the ns32k, floating point regs can only be loaded through memory
+
+ The movdf and movsf insns in ns32k.md copy between general and
+ floating registers using the stack. In principle, we could get
+ better code not allowing that case in the constraints and defining
+ SECONDARY_MEMORY_NEEDED in practice, though the stack slots used
+ are not available for optimization. */
+
+#if 0
+#define SECONDARY_MEMORY_NEEDED(CLASS1, CLASS2, M) \
+ secondary_memory_needed(CLASS1, CLASS2, M)
+#endif
+
+/* SMALL_REGISTER_CLASSES is true only if we have said we are using the
+ * multiply-add instructions.
+ */
+#define SMALL_REGISTER_CLASSES (target_flags & 512)
+
+/* A C expression whose value is nonzero if pseudos that have been
+ assigned to registers of class CLASS would likely be spilled
+ because registers of CLASS are needed for spill registers.
+
+ The default definition won't do because class LONG_FLOAT_REG0 has two
+ registers which are always acessed as a pair */
+
+#define CLASS_LIKELY_SPILLED_P(CLASS) \
+ (reg_class_size[(int) (CLASS)] == 1 || (CLASS) == LONG_FLOAT_REG0)
+
+
/* Nonzero if the constant value X is a legitimate general operand.
It is given that X satisfies CONSTANT_P or is a CONST_DOUBLE. */
@@ -882,10 +1078,10 @@ __transfer_from_trampoline () \
/* Nonzero if X is a hard reg that can be used as an index
or if it is a pseudo reg. */
#define REG_OK_FOR_INDEX_P(X) \
- (REGNO (X) < 8 || REGNO (X) >= FIRST_PSEUDO_REGISTER)
+ (REGNO (X) < F0_REGNUM || REGNO (X) >= FIRST_PSEUDO_REGISTER)
/* Nonzero if X is a hard reg that can be used as a base reg
of if it is a pseudo reg. */
-#define REG_OK_FOR_BASE_P(X) (REGNO (X) < 8 || REGNO (X) >= FRAME_POINTER_REGNUM)
+#define REG_OK_FOR_BASE_P(X) (REGNO (X) < F0_REGNUM || REGNO (X) >= FRAME_POINTER_REGNUM)
/* Nonzero if X is a floating point reg or a pseudo reg. */
#else
@@ -936,7 +1132,8 @@ __transfer_from_trampoline () \
/* Check for frame pointer or stack pointer. */
#define MEM_REG(X) \
- (GET_CODE (X) == REG && (REGNO (X) ^ 16) < 2)
+ (GET_CODE (X) == REG && (REGNO (X) == FRAME_POINTER_REGNUM \
+ || REGNO(X) == STACK_POINTER_REGNUM))
/* A memory ref whose address is the FP or SP, with optional integer offset,
or (on certain machines) a constant address. */
@@ -1040,15 +1237,21 @@ __transfer_from_trampoline () \
#define LEGITIMIZE_ADDRESS(X,OLDX,MODE,WIN) {}
/* Nonzero if the constant value X is a legitimate general operand
- when generating PIC code. It is given that flag_pic is on and
+ when generating PIC code. It is given that flag_pic is on and
that X satisfies CONSTANT_P or is a CONST_DOUBLE. */
extern int current_function_uses_pic_offset_table, flag_pic;
#define LEGITIMATE_PIC_OPERAND_P(X) \
(((! current_function_uses_pic_offset_table \
- && global_symbolic_reference_mentioned_p (X, 1))? \
+ && symbolic_reference_mentioned_p (X))? \
(current_function_uses_pic_offset_table = 1):0 \
- ), 1)
+ ), (! SYMBOLIC_CONST (X) \
+ || GET_CODE (X) == SYMBOL_REF || GET_CODE (X) == LABEL_REF))
+
+#define SYMBOLIC_CONST(X) \
+(GET_CODE (X) == SYMBOL_REF \
+ || GET_CODE (X) == LABEL_REF \
+ || (GET_CODE (X) == CONST && symbolic_reference_mentioned_p (X)))
/* Define this macro if references to a symbol must be treated
differently depending on something about the variable or
@@ -1082,6 +1285,33 @@ while (0)
{ if (GET_CODE (ADDR) == POST_INC || GET_CODE (ADDR) == PRE_DEC) \
goto LABEL;}
+/* If defined, a C expression whose value is nonzero if IDENTIFIER
+ with arguments ARGS is a valid machine specific attribute for DECL.
+ The attributes in ATTRIBUTES have previously been assigned to DECL. */
+
+#define VALID_MACHINE_DECL_ATTRIBUTE(DECL, ATTRIBUTES, NAME, ARGS) \
+ (ns32k_valid_decl_attribute_p (DECL, ATTRIBUTES, NAME, ARGS))
+
+/* If defined, a C expression whose value is nonzero if IDENTIFIER
+ with arguments ARGS is a valid machine specific attribute for TYPE.
+ The attributes in ATTRIBUTES have previously been assigned to TYPE. */
+
+#define VALID_MACHINE_TYPE_ATTRIBUTE(TYPE, ATTRIBUTES, NAME, ARGS) \
+ (ns32k_valid_type_attribute_p (TYPE, ATTRIBUTES, NAME, ARGS))
+
+/* If defined, a C expression whose value is zero if the attributes on
+ TYPE1 and TYPE2 are incompatible, one if they are compatible, and
+ two if they are nearly compatible (which causes a warning to be
+ generated). */
+
+#define COMP_TYPE_ATTRIBUTES(TYPE1, TYPE2) \
+ (ns32k_comp_type_attributes (TYPE1, TYPE2))
+
+/* If defined, a C statement that assigns default attributes to newly
+ defined TYPE. */
+
+/* #define SET_DEFAULT_TYPE_ATTRIBUTES (TYPE) */
+
/* Specify the machine mode that this machine uses
for the index in the tablejump instruction.
HI mode is more efficient but the range is not wide enough for
@@ -1107,6 +1337,12 @@ while (0)
in one reasonably fast instruction. */
#define MOVE_MAX 4
+/* The number of scalar move insns which should be generated instead
+ of a string move insn or a library call.
+
+ We have a smart movstrsi insn */
+#define MOVE_RATIO 0
+
/* Define this if zero-extension is slow (more than one real instruction). */
/* #define SLOW_ZERO_EXTEND */
@@ -1226,16 +1462,13 @@ while (0)
/* Describe the costs of the following register moves which are discouraged:
1.) Moves between the Floating point registers and the frame pointer and stack pointer
2.) Moves between the stack pointer and the frame pointer
- 3.) Moves between the floating point and general registers */
+ 3.) Moves between the floating point and general registers
+
+ These all involve two memory references. This is worse than a memory
+ to memory move (default cost 4)
+ */
-#define REGISTER_MOVE_COST(CLASS1, CLASS2) \
- ((((CLASS1) == FLOAT_REGS && ((CLASS2) == STACK_POINTER_REG || (CLASS2) == FRAME_POINTER_REG)) \
- || ((CLASS2) == FLOAT_REGS && ((CLASS1) == STACK_POINTER_REG || (CLASS1) == FRAME_POINTER_REG)) \
- || ((CLASS1) == STACK_POINTER_REG && (CLASS2) == FRAME_POINTER_REG) \
- || ((CLASS2) == STACK_POINTER_REG && (CLASS1) == FRAME_POINTER_REG) \
- || ((CLASS1) == FLOAT_REGS && (CLASS2) == GENERAL_REGS) \
- || ((CLASS1) == GENERAL_REGS && (CLASS2) == FLOAT_REGS)) \
- ? 4 : 2)
+#define REGISTER_MOVE_COST(CLASS1, CLASS2) register_move_cost(CLASS1, CLASS2)
#define OUTPUT_JUMP(NORMAL, NO_OV) \
{ if (cc_status.flags & CC_NO_OVERFLOW) \
@@ -1307,12 +1540,8 @@ while (0)
/* This is how to output an assembler line defining an external/static
address which is not in tree format (for collect.c). */
-#define ASM_OUTPUT_LABELREF_AS_INT(STREAM, NAME) \
-do { \
- fprintf (STREAM, "\t.long\t"); \
- ASM_OUTPUT_LABELREF (STREAM, NAME); \
- fprintf (STREAM, "\n"); \
-} while (0)
+/* The prefix to add to user-visible assembler symbols. */
+#define USER_LABEL_PREFIX "_"
/* This is how to output an insn to push a register on the stack.
It need not be very fast code. */
@@ -1326,19 +1555,6 @@ do { \
#define ASM_OUTPUT_REG_POP(FILE,REGNO) \
fprintf (FILE, "\tmovd tos,%s\n", reg_names[REGNO])
-/* How to refer to registers in assembler output.
- This sequence is indexed by compiler's hard-register-number (see above). */
-
-#define REGISTER_NAMES \
-{"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", \
- "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", \
- "fp", "sp"}
-
-/* How to renumber registers for dbx and gdb.
- NS32000 may need more change in the numeration. */
-
-#define DBX_REGISTER_NUMBER(REGNO) ((REGNO < 8) ? (REGNO)+4 : (REGNO))
-
/* This is how to output the definition of a user-level label named NAME,
such as the label on a static function or variable NAME. */
@@ -1365,9 +1581,11 @@ do { \
} while (0)
#endif
-/* The prefix to add to user-visible assembler symbols. */
+/* This is how to output a reference to a user-level label named NAME.
+ `assemble_name' uses this. */
-#define USER_LABEL_PREFIX "_"
+#define ASM_OUTPUT_LABELREF(FILE,NAME) \
+ fprintf (FILE, "_%s", NAME)
/* This is how to output an internal numbered label where
PREFIX is the class of label and NUM is the number within the class. */
@@ -1463,11 +1681,39 @@ do { \
#define PRINT_OPERAND_ADDRESS(FILE, ADDR) print_operand_address(FILE, ADDR)
-/* Define functions in ns32k.c and used in insn-output.c. */
-
-extern char *output_move_double ();
-extern char *output_shift_insn ();
-extern char *output_move_dconst ();
+/* Prototypes for functions in ns32k.c */
+
+/* Prototypes would be nice, but for now it causes too many problems.
+ This file gets included in places where the types (such as "rtx"
+ and enum machine_mode) are not defined. */
+#define NS32K_PROTO(ARGS) ()
+
+int hard_regno_mode_ok NS32K_PROTO((int regno, enum machine_mode mode));
+int register_move_cost NS32K_PROTO((enum reg_class CLASS1, enum reg_class CLASS2));
+int calc_address_cost NS32K_PROTO((rtx operand));
+enum reg_class secondary_reload_class NS32K_PROTO((enum reg_class class,
+ enum machine_mode mode, rtx in));
+int reg_or_mem_operand NS32K_PROTO((register rtx op, enum machine_mode mode));
+
+void split_di NS32K_PROTO((rtx operands[], int num, rtx lo_half[], hi_half[]));
+
+void expand_block_move NS32K_PROTO((rtx operands[]));
+int global_symbolic_reference_mentioned_p NS32K_PROTO((rtx op, int f));
+int ns32k_comp_type_attributes NS32K_PROTO((tree type1, tree type2));
+int ns32k_return_pops_args NS32K_PROTO((tree fundecl, tree funtype, int size));
+int ns32k_valid_decl_attribute_p NS32K_PROTO((tree decl, tree attributes,
+ tree identifier, tree args));
+int ns32k_valid_type_attribute_p NS32K_PROTO((tree decl, tree attributes,
+ tree identifier, tree args));
+void print_operand NS32K_PROTO((FILE *file, rtx x, char code));
+void print_operand_address NS32K_PROTO((register FILE *file, register rtx addr));
+char *output_move_dconst NS32K_PROTO((int n, char *s));
+char *output_move_double NS32K_PROTO((rtx *operands));
+char *output_shift_insn NS32K_PROTO((rtx *operands));
+
+extern unsigned int ns32k_reg_class_contents[N_REG_CLASSES];
+extern char *ns32k_out_reg_names[];
+extern enum reg_class regclass_map[]; /* smalled class containing REGNO */
/*
Local variables:
diff --git a/gcc/config/ns32k/ns32k.md b/gcc/config/ns32k/ns32k.md
index e44ccccbe06..69ba564638b 100644
--- a/gcc/config/ns32k/ns32k.md
+++ b/gcc/config/ns32k/ns32k.md
@@ -1,5 +1,5 @@
;;- Machine description for GNU compiler, ns32000 Version
-;; Copyright (C) 1988, 1994, 1996 Free Software Foundation, Inc.
+;; Copyright (C) 1988, 1994, 1996, 1999 Free Software Foundation, Inc.
;; Contributed by Michael Tiemann (tiemann@cygnus.com)
;; This file is part of GNU CC.
@@ -39,7 +39,20 @@
;; We don't want to allow a constant operand for test insns because
;; (set (cc0) (const_int foo)) has no mode information. Such insns will
;; be folded while optimizing anyway.
-
+;;
+;; In order for pic mode to work we cannot generate, for example
+;;
+;; addd _x+5,r1
+;;
+;; instead we must force gcc to generate something like
+;;
+;; addr 5(_x(sb)),r0
+;; addd r0,r1
+;;
+;; This was done through operand constraints (using "rmn" in place of "g"),
+;; but with the proper definition of LEGITIMATE_PIC_OPERAND (ns32k.h)
+;; this is unnecessary.
+;;
(define_insn "tstsi"
[(set (cc0)
(match_operand:SI 0 "nonimmediate_operand" "rm"))]
@@ -69,7 +82,7 @@
(define_insn "tstdf"
[(set (cc0)
- (match_operand:DF 0 "general_operand" "fmF"))]
+ (match_operand:DF 0 "general_operand" "lmF"))]
"TARGET_32081"
"*
{ cc_status.flags |= CC_REVERSED;
@@ -85,10 +98,11 @@
operands[1] = CONST0_RTX (SFmode);
return \"cmpf %1,%0\"; }")
+;; See note 1
(define_insn "cmpsi"
[(set (cc0)
- (compare (match_operand:SI 0 "nonimmediate_operand" "rmn")
- (match_operand:SI 1 "general_operand" "rmn")))]
+ (compare (match_operand:SI 0 "general_operand" "g")
+ (match_operand:SI 1 "general_operand" "g")))]
""
"*
{
@@ -113,7 +127,7 @@
(define_insn "cmphi"
[(set (cc0)
- (compare (match_operand:HI 0 "nonimmediate_operand" "g")
+ (compare (match_operand:HI 0 "general_operand" "g")
(match_operand:HI 1 "general_operand" "g")))]
""
"*
@@ -145,7 +159,7 @@
(define_insn "cmpqi"
[(set (cc0)
- (compare (match_operand:QI 0 "nonimmediate_operand" "g")
+ (compare (match_operand:QI 0 "general_operand" "g")
(match_operand:QI 1 "general_operand" "g")))]
""
"*
@@ -177,8 +191,8 @@
(define_insn "cmpdf"
[(set (cc0)
- (compare (match_operand:DF 0 "general_operand" "fmF")
- (match_operand:DF 1 "general_operand" "fmF")))]
+ (compare (match_operand:DF 0 "general_operand" "lmF")
+ (match_operand:DF 1 "general_operand" "lmF")))]
"TARGET_32081"
"cmpl %0,%1")
@@ -189,9 +203,14 @@
"TARGET_32081"
"cmpf %0,%1")
+;; movdf and movsf copy between general and floating registers using
+;; the stack. In principle, we could get better code not allowing
+;; that case in the constraints and defining SECONDARY_MEMORY_NEEDED
+;; in practice, though the stack slots used are not available for
+;; optimization.
(define_insn "movdf"
- [(set (match_operand:DF 0 "general_operand" "=fg<")
- (match_operand:DF 1 "general_operand" "fFg"))]
+ [(set (match_operand:DF 0 "general_operand" "=lg<")
+ (match_operand:DF 1 "general_operand" "lFg"))]
""
"*
{
@@ -231,7 +250,7 @@
{
if (FP_REG_P (operands[0]))
{
- if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) < 8)
+ if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) < F0_REGNUM)
return \"movd %1,tos\;movf tos,%0\";
else
return \"movf %1,%0\";
@@ -308,8 +327,8 @@
;; This special case must precede movsi.
(define_insn ""
- [(set (reg:SI 17)
- (match_operand:SI 0 "general_operand" "rmn"))]
+ [(set (reg:SI 25)
+ (match_operand:SI 0 "general_operand" "g"))]
""
"lprd sp,%0")
@@ -323,7 +342,7 @@
if (FP_REG_P (operands[0]))
{
- if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) < 8)
+ if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) < F0_REGNUM)
return \"movd %1,tos\;movf tos,%0\";
else
return \"movf %1,%0\";
@@ -347,16 +366,16 @@
{
if (i <= 7 && i >= -8)
return \"movqd %1,%0\";
- if (i <= 0x1fffffff && i >= -0x20000000)
+ if (NS32K_DISPLACEMENT_P (i))
#if defined (GNX_V3) || defined (UTEK_ASM)
return \"addr %c1,%0\";
#else
return \"addr @%c1,%0\";
#endif
- return \"movd %$%1,%0\";
+ return \"movd %1,%0\";
}
else
- return output_move_dconst(i, \"%$%1,%0\");
+ return output_move_dconst(i, \"%1,%0\");
}
else if (GET_CODE (operands[1]) == CONST && ! flag_pic)
{
@@ -364,11 +383,11 @@
* that case addr might lead to overflow. For PIC symbolic
* address loads always have to be done with addr.
*/
- return \"movd %$%1,%0\";
+ return \"movd %1,%0\";
}
else if (GET_CODE (operands[1]) == REG)
{
- if (REGNO (operands[1]) < 16)
+ if (REGNO (operands[1]) < F0_REGNUM)
return \"movd %1,%0\";
else if (REGNO (operands[1]) == FRAME_POINTER_REGNUM)
{
@@ -426,7 +445,7 @@
}
else if (FP_REG_P (operands[0]))
{
- if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) < 8)
+ if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) < F0_REGNUM)
return \"movwf %1,tos\;movf tos,%0\";
else
return \"movwf %1,%0\";
@@ -472,7 +491,7 @@
}
else if (FP_REG_P (operands[0]))
{
- if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) < 8)
+ if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) < F0_REGNUM)
return \"movbf %1,tos\;movf tos,%0\";
else
return \"movbf %1,%0\";
@@ -499,75 +518,63 @@
return \"movb %1,%0\";
}")
-;; This is here to accept 4 arguments and pass the first 3 along
-;; to the movstrsi1 pattern that really does the work.
+;; Block moves
+;; Argument 0 is the destination
+;; Argument 1 is the source
+;; Argument 2 is the length
+;; Argument 3 is the alignment
+;;
+;; Strategy: Use define_expand to
+;; either emit insns directly if it can be done simply or
+;; emit rtl to match movstrsi1 which has extra scratch registers
+;; which can be used to generate more complex code.
+
(define_expand "movstrsi"
- [(set (match_operand:BLK 0 "general_operand" "=g")
- (match_operand:BLK 1 "general_operand" "g"))
- (use (match_operand:SI 2 "general_operand" "rmn"))
- (match_operand 3 "" "")]
+ [(parallel [(set (match_operand:BLK 0 "general_operand" "")
+ (match_operand:BLK 1 "general_operand" ""))
+ (use (match_operand:SI 2 "general_operand" ""))
+ (use (match_operand:SI 3 "const_int_operand" ""))])]
""
"
- emit_insn (gen_movstrsi1 (operands[0], operands[1], operands[2]));
- DONE;
-")
+{
+ if (operands[0]) /* avoid unused code messages */
+ {
+ expand_block_move (operands);
+ DONE;
+ }
+}")
+
+;; Special Registers:
+;; r0 count
+;; r1 from
+;; r2 to
+;; r3 match
+
-;; The definition of this insn does not really explain what it does,
-;; but it should suffice
-;; that anything generated as this insn will be recognized as one
-;; and that it won't successfully combine with anything.
(define_insn "movstrsi1"
- [(set (match_operand:BLK 0 "general_operand" "=g")
- (match_operand:BLK 1 "general_operand" "g"))
- (use (match_operand:SI 2 "general_operand" "rmn"))
- (clobber (reg:SI 0))
- (clobber (reg:SI 1))
- (clobber (reg:SI 2))]
+ [(set (mem:BLK (reg:SI 2))
+ (mem:BLK (reg:SI 1)))
+ (use (reg:SI 0))
+ (set (reg:SI 2) (plus:SI (reg:SI 2) (mult:SI (reg:SI 0) (match_operand:SI 0 "const_int_operand" ""))))
+ (set (reg:SI 1) (plus:SI (reg:SI 1) (mult:SI (reg:SI 0) (match_dup 0))))
+ (set (reg:SI 0) (const_int 0))]
""
"*
-{
- if (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
- abort ();
- operands[0] = XEXP (operands[0], 0);
- operands[1] = XEXP (operands[1], 0);
- if (GET_CODE (operands[0]) == MEM)
- if (GET_CODE (operands[1]) == MEM)
- output_asm_insn (\"movd %0,r2\;movd %1,r1\", operands);
- else
- output_asm_insn (\"movd %0,r2\;addr %a1,r1\", operands);
- else if (GET_CODE (operands[1]) == MEM)
- output_asm_insn (\"addr %a0,r2\;movd %1,r1\", operands);
- else
- output_asm_insn (\"addr %a0,r2\;addr %a1,r1\", operands);
+ {
+ int align = INTVAL(operands[0]);
+ if (align == 4)
+ return \"movsd\";
+ else
+ return \"movsb\";
+ }")
+
+(define_insn "movstrsi2"
+ [(set (mem:BLK (match_operand:SI 0 "address_operand" "g"))
+ (mem:BLK (match_operand:SI 1 "address_operand" "g")))
+ (use (match_operand 2 "immediate_operand" "i"))]
+ ""
+ "movmd %a1,%a0,%2")
-#ifdef UTEK_ASM
- if (GET_CODE (operands[2]) == CONST_INT && (INTVAL (operands[2]) & 0x3) == 0)
- {
- operands[2] = GEN_INT (INTVAL (operands[2]) >> 2);
- if ((unsigned) INTVAL (operands[2]) <= 7)
- return \"movqd %2,r0\;movsd $0\";
- else
- return \"movd %2,r0\;movsd $0\";
- }
- else
- {
- return \"movd %2,r0\;movsb $0\";
- }
-#else
- if (GET_CODE (operands[2]) == CONST_INT && (INTVAL (operands[2]) & 0x3) == 0)
- {
- operands[2] = GEN_INT (INTVAL (operands[2]) >> 2);
- if ((unsigned) INTVAL (operands[2]) <= 7)
- return \"movqd %2,r0\;movsd\";
- else
- return \"movd %2,r0\;movsd\";
- }
- else
- {
- return \"movd %2,r0\;movsb\";
- }
-#endif
-}")
;; Extension and truncation insns.
;; Those for integer source operand
@@ -575,13 +582,13 @@
(define_insn "truncsiqi2"
[(set (match_operand:QI 0 "general_operand" "=g<")
- (truncate:QI (match_operand:SI 1 "nonimmediate_operand" "rmn")))]
+ (truncate:QI (match_operand:SI 1 "nonimmediate_operand" "g")))]
""
"movb %1,%0")
(define_insn "truncsihi2"
[(set (match_operand:HI 0 "general_operand" "=g<")
- (truncate:HI (match_operand:SI 1 "nonimmediate_operand" "rmn")))]
+ (truncate:HI (match_operand:SI 1 "nonimmediate_operand" "g")))]
""
"movw %1,%0")
@@ -610,14 +617,14 @@
"movxbd %1,%0")
(define_insn "extendsfdf2"
- [(set (match_operand:DF 0 "general_operand" "=fm<")
+ [(set (match_operand:DF 0 "general_operand" "=lm<")
(float_extend:DF (match_operand:SF 1 "general_operand" "fmF")))]
"TARGET_32081"
"movfl %1,%0")
(define_insn "truncdfsf2"
[(set (match_operand:SF 0 "general_operand" "=fm<")
- (float_truncate:SF (match_operand:DF 1 "general_operand" "fmF")))]
+ (float_truncate:SF (match_operand:DF 1 "general_operand" "lmF")))]
"TARGET_32081"
"movlf %1,%0")
@@ -657,7 +664,7 @@
"movdf %1,%0")
(define_insn "floatsidf2"
- [(set (match_operand:DF 0 "general_operand" "=fm<")
+ [(set (match_operand:DF 0 "general_operand" "=lm<")
(float:DF (match_operand:SI 1 "general_operand" "rm")))]
"TARGET_32081"
"movdl %1,%0")
@@ -669,7 +676,7 @@
"movwf %1,%0")
(define_insn "floathidf2"
- [(set (match_operand:DF 0 "general_operand" "=fm<")
+ [(set (match_operand:DF 0 "general_operand" "=lm<")
(float:DF (match_operand:HI 1 "general_operand" "rm")))]
"TARGET_32081"
"movwl %1,%0")
@@ -683,7 +690,7 @@
; Some assemblers warn that this insn doesn't work.
; Maybe they know something we don't.
;(define_insn "floatqidf2"
-; [(set (match_operand:DF 0 "general_operand" "=fm<")
+; [(set (match_operand:DF 0 "general_operand" "=lm<")
; (float:DF (match_operand:QI 1 "general_operand" "rm")))]
; "TARGET_32081"
; "movbl %1,%0")
@@ -711,19 +718,19 @@
(define_insn "fixdfqi2"
[(set (match_operand:QI 0 "general_operand" "=g<")
- (fix:QI (fix:DF (match_operand:DF 1 "general_operand" "fm"))))]
+ (fix:QI (fix:DF (match_operand:DF 1 "general_operand" "lm"))))]
"TARGET_32081"
"trunclb %1,%0")
(define_insn "fixdfhi2"
[(set (match_operand:HI 0 "general_operand" "=g<")
- (fix:HI (fix:DF (match_operand:DF 1 "general_operand" "fm"))))]
+ (fix:HI (fix:DF (match_operand:DF 1 "general_operand" "lm"))))]
"TARGET_32081"
"trunclw %1,%0")
(define_insn "fixdfsi2"
[(set (match_operand:SI 0 "general_operand" "=g<")
- (fix:SI (fix:DF (match_operand:DF 1 "general_operand" "fm"))))]
+ (fix:SI (fix:DF (match_operand:DF 1 "general_operand" "lm"))))]
"TARGET_32081"
"truncld %1,%0")
@@ -749,19 +756,19 @@
(define_insn "fixunsdfqi2"
[(set (match_operand:QI 0 "general_operand" "=g<")
- (unsigned_fix:QI (fix:DF (match_operand:DF 1 "general_operand" "fm"))))]
+ (unsigned_fix:QI (fix:DF (match_operand:DF 1 "general_operand" "lm"))))]
"TARGET_32081"
"trunclb %1,%0")
(define_insn "fixunsdfhi2"
[(set (match_operand:HI 0 "general_operand" "=g<")
- (unsigned_fix:HI (fix:DF (match_operand:DF 1 "general_operand" "fm"))))]
+ (unsigned_fix:HI (fix:DF (match_operand:DF 1 "general_operand" "lm"))))]
"TARGET_32081"
"trunclw %1,%0")
(define_insn "fixunsdfsi2"
[(set (match_operand:SI 0 "general_operand" "=g<")
- (unsigned_fix:SI (fix:DF (match_operand:DF 1 "general_operand" "fm"))))]
+ (unsigned_fix:SI (fix:DF (match_operand:DF 1 "general_operand" "lm"))))]
"TARGET_32081"
"truncld %1,%0")
@@ -786,28 +793,69 @@
(define_insn "fix_truncdfqi2"
[(set (match_operand:QI 0 "general_operand" "=g<")
- (fix:QI (match_operand:DF 1 "general_operand" "fm")))]
+ (fix:QI (match_operand:DF 1 "general_operand" "lm")))]
"TARGET_32081"
"trunclb %1,%0")
(define_insn "fix_truncdfhi2"
[(set (match_operand:HI 0 "general_operand" "=g<")
- (fix:HI (match_operand:DF 1 "general_operand" "fm")))]
+ (fix:HI (match_operand:DF 1 "general_operand" "lm")))]
"TARGET_32081"
"trunclw %1,%0")
(define_insn "fix_truncdfsi2"
[(set (match_operand:SI 0 "general_operand" "=g<")
- (fix:SI (match_operand:DF 1 "general_operand" "fm")))]
+ (fix:SI (match_operand:DF 1 "general_operand" "lm")))]
"TARGET_32081"
"truncld %1,%0")
+;; Multiply-add instructions
+(define_insn ""
+ [(set (match_operand:DF 0 "general_operand" "=v,v")
+ (plus:DF (mult:DF (match_operand:DF 1 "general_operand" "%lmF,0")
+ (match_operand:DF 2 "general_operand" "lmF,lmF"))
+ (match_operand:DF 3 "general_operand" "0,lmF")))]
+ "TARGET_MULT_ADD"
+ "@
+ dotl %1,%2
+ polyl %2,%3")
+
+(define_insn ""
+ [(set (match_operand:SF 0 "general_operand" "=u,u")
+ (plus:SF (mult:SF (match_operand:SF 1 "general_operand" "%fmF,0")
+ (match_operand:SF 2 "general_operand" "fmF,fmF"))
+ (match_operand:SF 3 "general_operand" "0,fmF")))]
+ "TARGET_MULT_ADD"
+ "@
+ dotf %1,%2
+ polyf %2,%3")
+
+
+;; Multiply-sub instructions
+(define_insn ""
+ [(set (match_operand:DF 0 "general_operand" "=v")
+ (minus:DF (mult:DF (match_operand:DF 1 "general_operand" "%lmF")
+ (match_operand:DF 2 "general_operand" "lmF"))
+ (match_operand:DF 3 "general_operand" "0")))]
+ "TARGET_MULT_ADD"
+ "@
+ negl %0,%0\;dotl %1,%2")
+
+(define_insn ""
+ [(set (match_operand:SF 0 "general_operand" "=u")
+ (minus:SF (mult:SF (match_operand:SF 1 "general_operand" "%fmF")
+ (match_operand:SF 2 "general_operand" "fmF"))
+ (match_operand:SF 3 "general_operand" "0")))]
+ "TARGET_MULT_ADD"
+ "@
+ negf %0,%0\;dotf %1,%2")
+
;;- All kinds of add instructions.
(define_insn "adddf3"
- [(set (match_operand:DF 0 "general_operand" "=fm")
+ [(set (match_operand:DF 0 "general_operand" "=lm")
(plus:DF (match_operand:DF 1 "general_operand" "%0")
- (match_operand:DF 2 "general_operand" "fmF")))]
+ (match_operand:DF 2 "general_operand" "lmF")))]
"TARGET_32081"
"addl %2,%0")
@@ -820,8 +868,8 @@
"addf %2,%0")
(define_insn ""
- [(set (reg:SI 17)
- (plus:SI (reg:SI 17)
+ [(set (reg:SI 25)
+ (plus:SI (reg:SI 25)
(match_operand:SI 0 "immediate_operand" "i")))]
"GET_CODE (operands[0]) == CONST_INT"
"*
@@ -837,23 +885,23 @@
if (! TARGET_32532)
{
if (INTVAL (operands[0]) < 64 && INTVAL (operands[0]) > -64)
- return \"adjspb %$%n0\";
+ return \"adjspb %n0\";
else if (INTVAL (operands[0]) < 8192 && INTVAL (operands[0]) >= -8192)
- return \"adjspw %$%n0\";
+ return \"adjspw %n0\";
}
- return \"adjspd %$%n0\";
+ return \"adjspd %n0\";
}")
(define_insn ""
[(set (match_operand:SI 0 "general_operand" "=g<")
- (plus:SI (reg:SI 16)
+ (plus:SI (reg:SI 24)
(match_operand:SI 1 "immediate_operand" "i")))]
"GET_CODE (operands[1]) == CONST_INT"
"addr %c1(fp),%0")
(define_insn ""
[(set (match_operand:SI 0 "general_operand" "=g<")
- (plus:SI (reg:SI 17)
+ (plus:SI (reg:SI 25)
(match_operand:SI 1 "immediate_operand" "i")))]
"GET_CODE (operands[1]) == CONST_INT"
"addr %c1(sp),%0")
@@ -882,14 +930,14 @@
{
i = INTVAL (xops[3]);
if (i <= 7 && i >= -8)
- output_asm_insn (\"addqd %$%3,%1\", xops);
+ output_asm_insn (\"addqd %3,%1\", xops);
else
- output_asm_insn (\"addd %$%3,%1\", xops);
+ output_asm_insn (\"addd %3,%1\", xops);
}
else
{
- output_asm_insn (\"addqd %$%2,%0\", xops);
- output_asm_insn (\"addcd %$%3,%1\", xops);
+ output_asm_insn (\"addqd %2,%0\", xops);
+ output_asm_insn (\"addcd %3,%1\", xops);
}
return \"\";
}
@@ -899,29 +947,40 @@
return \"\";
}")
+;; See Note 1
(define_insn "addsi3"
[(set (match_operand:SI 0 "general_operand" "=g,=g&<")
(plus:SI (match_operand:SI 1 "general_operand" "%0,r")
- (match_operand:SI 2 "general_operand" "rmn,n")))]
+ (match_operand:SI 2 "general_operand" "g,i")))]
""
"*
{
if (which_alternative == 1)
{
- int i = INTVAL (operands[2]);
- if (NS32K_DISPLACEMENT_P (i))
- return \"addr %c2(%1),%0\";
+ if (GET_CODE (operands[2]) == CONST_INT)
+ {
+ int i = INTVAL (operands[2]);
+ if (NS32K_DISPLACEMENT_P (i))
+ return \"addr %c2(%1),%0\";
+ else
+ return \"movd %1,%0\;addd %2,%0\";
+ }
else
- return \"movd %1,%0\;addd %2,%0\";
+ {
+ if (flag_pic)
+ return \"addr %a2[%1:b],%0\";
+ else
+ return \"addr %c2(%1),%0\";
+ }
}
- if (GET_CODE (operands[2]) == CONST_INT)
+ else if (GET_CODE (operands[2]) == CONST_INT)
{
int i = INTVAL (operands[2]);
if (i <= 7 && i >= -8)
return \"addqd %2,%0\";
else if (! TARGET_32532 && GET_CODE (operands[0]) == REG
- && i <= 0x1fffffff && i >= -0x20000000)
+ && NS32K_DISPLACEMENT_P (i))
return \"addr %c2(%0),%0\";
}
return \"addd %2,%0\";
@@ -986,9 +1045,9 @@
;;- All kinds of subtract instructions.
(define_insn "subdf3"
- [(set (match_operand:DF 0 "general_operand" "=fm")
+ [(set (match_operand:DF 0 "general_operand" "=lm")
(minus:DF (match_operand:DF 1 "general_operand" "0")
- (match_operand:DF 2 "general_operand" "fmF")))]
+ (match_operand:DF 2 "general_operand" "lmF")))]
"TARGET_32081"
"subl %2,%0")
@@ -1000,16 +1059,16 @@
"subf %2,%0")
(define_insn ""
- [(set (reg:SI 17)
- (minus:SI (reg:SI 17)
+ [(set (reg:SI 25)
+ (minus:SI (reg:SI 25)
(match_operand:SI 0 "immediate_operand" "i")))]
"GET_CODE (operands[0]) == CONST_INT"
"*
{
if (! TARGET_32532 && GET_CODE(operands[0]) == CONST_INT
&& INTVAL(operands[0]) < 64 && INTVAL(operands[0]) > -64)
- return \"adjspb %$%0\";
- return \"adjspd %$%0\";
+ return \"adjspb %0\";
+ return \"adjspd %0\";
}")
(define_insn "subdi3"
@@ -1036,14 +1095,14 @@
{
i = INTVAL (xops[3]);
if (i <= 8 && i >= -7)
- output_asm_insn (\"addqd %$%n3,%1\", xops);
+ output_asm_insn (\"addqd %n3,%1\", xops);
else
- output_asm_insn (\"subd %$%3,%1\", xops);
+ output_asm_insn (\"subd %3,%1\", xops);
}
else
{
- output_asm_insn (\"addqd %$%n2,%0\", xops);
- output_asm_insn (\"subcd %$%3,%1\", xops);
+ output_asm_insn (\"addqd %n2,%0\", xops);
+ output_asm_insn (\"subcd %3,%1\", xops);
}
return \"\";
}
@@ -1056,7 +1115,7 @@
(define_insn "subsi3"
[(set (match_operand:SI 0 "general_operand" "=g")
(minus:SI (match_operand:SI 1 "general_operand" "0")
- (match_operand:SI 2 "general_operand" "rmn")))]
+ (match_operand:SI 2 "general_operand" "g")))]
""
"*
{ if (GET_CODE (operands[2]) == CONST_INT)
@@ -1064,7 +1123,7 @@
int i = INTVAL (operands[2]);
if (i <= 8 && i >= -7)
- return \"addqd %$%n2,%0\";
+ return \"addqd %n2,%0\";
}
return \"subd %2,%0\";
}")
@@ -1080,7 +1139,7 @@
int i = INTVAL (operands[2]);
if (i <= 8 && i >= -7)
- return \"addqw %$%n2,%0\";
+ return \"addqw %n2,%0\";
}
return \"subw %2,%0\";
}")
@@ -1094,7 +1153,7 @@
{
if (GET_CODE (operands[1]) == CONST_INT
&& INTVAL (operands[1]) >-8 && INTVAL(operands[1]) < 9)
- return \"addqw %$%n2,%0\";
+ return \"addqw %n2,%0\";
return \"subw %2,%0\";
}")
@@ -1109,7 +1168,7 @@
int i = INTVAL (operands[2]);
if (i <= 8 && i >= -7)
- return \"addqb %$%n2,%0\";
+ return \"addqb %n2,%0\";
}
return \"subb %2,%0\";
}")
@@ -1123,16 +1182,16 @@
{
if (GET_CODE (operands[1]) == CONST_INT
&& INTVAL (operands[1]) >-8 && INTVAL(operands[1]) < 9)
- return \"addqb %$%n2,%0\";
+ return \"addqb %n2,%0\";
return \"subb %2,%0\";
}")
;;- Multiply instructions.
(define_insn "muldf3"
- [(set (match_operand:DF 0 "general_operand" "=fm")
+ [(set (match_operand:DF 0 "general_operand" "=lm")
(mult:DF (match_operand:DF 1 "general_operand" "%0")
- (match_operand:DF 2 "general_operand" "fmF")))]
+ (match_operand:DF 2 "general_operand" "lmF")))]
"TARGET_32081"
"mull %2,%0")
@@ -1143,10 +1202,11 @@
"TARGET_32081"
"mulf %2,%0")
+;; See note 1
(define_insn "mulsi3"
[(set (match_operand:SI 0 "general_operand" "=g")
(mult:SI (match_operand:SI 1 "general_operand" "%0")
- (match_operand:SI 2 "general_operand" "rmn")))]
+ (match_operand:SI 2 "general_operand" "g")))]
""
"muld %2,%0")
@@ -1169,16 +1229,195 @@
(mult:DI (zero_extend:DI
(match_operand:SI 1 "nonimmediate_operand" "0"))
(zero_extend:DI
- (match_operand:SI 2 "nonimmediate_operand" "rmn"))))]
+ (match_operand:SI 2 "nonimmediate_operand" "g"))))]
""
"meid %2,%0")
+;; divmod insns: We can only do the unsigned case.
+(define_expand "udivmodsi4"
+ [(parallel
+ [(set (match_operand:SI 0 "reg_or_mem_operand" "")
+ (udiv:SI (match_operand:SI 1 "general_operand" "")
+ (match_operand:SI 2 "general_operand" "")))
+ (set (match_operand:SI 3 "reg_or_mem_operand" "")
+ (umod:SI (match_dup 1) (match_dup 2)))])]
+ ""
+ "
+{
+ rtx temp = gen_reg_rtx(DImode);
+ rtx insn, first, last;
+ first = emit_move_insn(gen_lowpart(SImode, temp), operands[1]);
+ emit_move_insn(gen_highpart(SImode, temp), const0_rtx);
+ emit_insn(gen_udivmoddisi4_internal(temp, temp, operands[2]));
+ last = emit_move_insn(temp, temp);
+ {
+ rtx divdi, moddi, divsi, modsi;
+ divsi = gen_rtx (UDIV, SImode, operands[1], operands[2]);
+ modsi = gen_rtx (UMOD, SImode, operands[1], operands[2]);
+ divdi = gen_rtx (ZERO_EXTEND, DImode, divsi);
+ moddi = gen_rtx (ZERO_EXTEND, DImode, modsi);
+ REG_NOTES (first) = gen_rtx (INSN_LIST, REG_LIBCALL, last,
+ REG_NOTES (first));
+ REG_NOTES (last) = gen_rtx (INSN_LIST, REG_RETVAL, first,
+ gen_rtx (EXPR_LIST, REG_EQUAL,
+ gen_rtx (IOR, DImode, moddi,
+ gen_rtx (ASHIFT, DImode, divdi, GEN_INT(32))),
+ REG_NOTES (last)));
+ }
+
+ insn = emit_move_insn(operands[0], gen_highpart(SImode, temp));
+ insn = emit_move_insn(operands[3], gen_lowpart(SImode, temp));
+ DONE;
+}")
+
+;; If we try and describe what this does, we have to zero-expand an
+;; operand, which prevents it being a constant (VOIDmode) (see udivmoddisi4
+;; below. This udivmoddisi4_internal never matches anything and is only
+;; ever used when explicitly emitted by a define_expand.
+(define_insn "udivmoddisi4_internal"
+ [(set (match_operand:DI 0 "reg_or_mem_operand" "=rm")
+ (unspec:DI [(match_operand:DI 1 "reg_or_mem_operand" "0")
+ (match_operand:SI 2 "general_operand" "g")] 0))]
+ ""
+ "deid %2,%0")
+
+;; Retain this insn which *does* have a pattern indicating what it does,
+;; just in case the compiler is smart enough to recognize a substitution.
+(define_insn "udivmoddisi4"
+ [(set (subreg:SI (match_operand:DI 0 "register_operand" "=rm") 1)
+ (truncate:SI (udiv:DI (match_operand:DI 1 "reg_or_mem_operand" "0")
+ (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "g")))))
+ (set (subreg:SI (match_operand:DI 3 "register_operand" "=0") 0)
+ (truncate:SI (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))]
+ ""
+ "deid %2,%0")
+
+;; Part word variants. These seem to never be used at the moment (gcc
+;; 2.7.2.2). The code generation prefers to zero extend hi's and qi's
+;; and use signed div and mod. Keep these insns incase that changes.
+;; divmod should have an advantage when both div and mod are needed. However,
+;; divmod uses two registers, so maybe the compiler knows best.
+
+(define_expand "udivmodhi4"
+ [(parallel
+ [(set (match_operand:HI 0 "reg_or_mem_operand" "")
+ (udiv:HI (match_operand:HI 1 "general_operand" "")
+ (match_operand:HI 2 "general_operand" "")))
+ (set (match_operand:HI 3 "reg_or_mem_operand" "")
+ (umod:HI (match_dup 1) (match_dup 2)))])]
+ ""
+ "
+{
+ rtx temp = gen_reg_rtx(DImode);
+ rtx insn, first, last;
+ first = emit_move_insn(gen_lowpart(HImode, temp), operands[1]);
+ emit_move_insn(gen_highpart (HImode, temp), const0_rtx);
+ operands[2] = force_reg(HImode, operands[2]);
+ emit_insn(gen_udivmoddihi4_internal(temp, temp, operands[2]));
+ last = emit_move_insn(temp, temp);
+ {
+ rtx divdi, moddi, divhi, modhi;
+ divhi = gen_rtx (UDIV, HImode, operands[1], operands[2]);
+ modhi = gen_rtx (UMOD, HImode, operands[1], operands[2]);
+ divdi = gen_rtx (ZERO_EXTEND, DImode, divhi);
+ moddi = gen_rtx (ZERO_EXTEND, DImode, modhi);
+ REG_NOTES (first) = gen_rtx (INSN_LIST, REG_LIBCALL, last,
+ REG_NOTES (first));
+ REG_NOTES (last) = gen_rtx (INSN_LIST, REG_RETVAL, first,
+ gen_rtx (EXPR_LIST, REG_EQUAL,
+ gen_rtx(IOR, DImode, moddi,
+ gen_rtx(ASHIFT, DImode, divdi, GEN_INT(32))),
+ REG_NOTES (last)));
+ }
+
+ insn = emit_move_insn(operands[0], gen_highpart(HImode, temp));
+ insn = emit_move_insn(operands[3], gen_lowpart(HImode, temp));
+ DONE;
+}")
+
+;; deiw wants two hi's in seperate registers or else they can be adjacent
+;; in memory. DI mode will ensure two registers are available, but if we
+;; want to allow memory as an operand we would need SI mode. There is no
+;; way to do this, so just restrict operand 0 and 1 to be in registers.
+(define_insn "udivmoddihi4_internal"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "register_operand" "0")
+ (match_operand:HI 2 "general_operand" "g")] 0))]
+ ""
+ "deiw %2,%0")
+
+(define_insn "udivmoddihi4"
+ [(set (subreg:HI (match_operand:DI 0 "register_operand" "=r") 1)
+ (truncate:HI (udiv:DI (match_operand:DI 1 "reg_or_mem_operand" "0")
+ (zero_extend:DI (match_operand:HI 2 "nonimmediate_operand" "g")))))
+ (set (subreg:HI (match_operand:DI 3 "register_operand" "=0") 0)
+ (truncate:HI (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))]
+ ""
+ "deiw %2,%0")
+
+(define_expand "udivmodqi4"
+ [(parallel
+ [(set (match_operand:QI 0 "reg_or_mem_operand" "")
+ (udiv:QI (match_operand:QI 1 "general_operand" "")
+ (match_operand:QI 2 "general_operand" "")))
+ (set (match_operand:QI 3 "reg_or_mem_operand" "")
+ (umod:QI (match_dup 1) (match_dup 2)))])]
+ ""
+ "
+{
+ rtx temp = gen_reg_rtx(DImode);
+ rtx insn, first, last;
+ first = emit_move_insn(gen_lowpart(QImode, temp), operands[1]);
+ emit_move_insn(gen_highpart(QImode, temp), const0_rtx);
+ operands[2] = force_reg(QImode, operands[2]);
+ emit_insn(gen_udivmoddiqi4_internal(temp, temp, operands[2]));
+ last = emit_move_insn(temp, temp);
+ {
+ rtx divdi, moddi, divqi, modqi;
+ divqi = gen_rtx (UDIV, QImode, operands[1], operands[2]);
+ modqi = gen_rtx (UMOD, QImode, operands[1], operands[2]);
+ divdi = gen_rtx (ZERO_EXTEND, DImode, divqi);
+ moddi = gen_rtx (ZERO_EXTEND, DImode, modqi);
+ REG_NOTES (first) = gen_rtx (INSN_LIST, REG_LIBCALL, last,
+ REG_NOTES (first));
+ REG_NOTES (last) = gen_rtx (INSN_LIST, REG_RETVAL, first,
+ gen_rtx (EXPR_LIST, REG_EQUAL,
+ gen_rtx(IOR, DImode, moddi,
+ gen_rtx(ASHIFT, DImode, divdi, GEN_INT(32))),
+ REG_NOTES (last)));
+ }
+
+ insn = emit_move_insn(operands[0], gen_highpart(QImode, temp));
+ insn = emit_move_insn(operands[3], gen_lowpart(QImode, temp));
+ DONE;
+}")
+
+;; deib wants two qi's in seperate registers or else they can be adjacent
+;; in memory. DI mode will ensure two registers are available, but if we
+;; want to allow memory as an operand we would need HI mode. There is no
+;; way to do this, so just restrict operand 0 and 1 to be in registers.
+(define_insn "udivmoddiqi4_internal"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "reg_or_mem_operand" "0")
+ (match_operand:QI 2 "general_operand" "g")] 0))]
+ ""
+ "deib %2,%0")
+
+(define_insn "udivmoddiqi4"
+ [(set (subreg:QI (match_operand:DI 0 "register_operand" "=r") 1)
+ (truncate:QI (udiv:DI (match_operand:DI 1 "reg_or_mem_operand" "0")
+ (zero_extend:DI (match_operand:QI 2 "nonimmediate_operand" "g")))))
+ (set (subreg:QI (match_operand:DI 3 "register_operand" "=0") 0)
+ (truncate:QI (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))]
+ ""
+ "deib %2,%0")
+
;;- Divide instructions.
(define_insn "divdf3"
- [(set (match_operand:DF 0 "general_operand" "=fm")
+ [(set (match_operand:DF 0 "general_operand" "=lm")
(div:DF (match_operand:DF 1 "general_operand" "0")
- (match_operand:DF 2 "general_operand" "fmF")))]
+ (match_operand:DF 2 "general_operand" "lmF")))]
"TARGET_32081"
"divl %2,%0")
@@ -1189,10 +1428,11 @@
"TARGET_32081"
"divf %2,%0")
+;; See note 1
(define_insn "divsi3"
[(set (match_operand:SI 0 "general_operand" "=g")
(div:SI (match_operand:SI 1 "general_operand" "0")
- (match_operand:SI 2 "general_operand" "rmn")))]
+ (match_operand:SI 2 "general_operand" "g")))]
""
"quod %2,%0")
@@ -1209,46 +1449,14 @@
(match_operand:QI 2 "general_operand" "g")))]
""
"quob %2,%0")
-
-(define_insn "udivsi3"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (udiv:SI (subreg:SI (match_operand:DI 1 "reg_or_mem_operand" "0") 0)
- (match_operand:SI 2 "general_operand" "rmn")))]
- ""
- "*
-{
- operands[1] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
- return \"deid %2,%0\;movd %1,%0\";
-}")
-
-(define_insn "udivhi3"
- [(set (match_operand:HI 0 "register_operand" "=r")
- (udiv:HI (subreg:HI (match_operand:DI 1 "reg_or_mem_operand" "0") 0)
- (match_operand:HI 2 "general_operand" "g")))]
- ""
- "*
-{
- operands[1] = gen_rtx (REG, HImode, REGNO (operands[0]) + 1);
- return \"deiw %2,%0\;movw %1,%0\";
-}")
-
-(define_insn "udivqi3"
- [(set (match_operand:QI 0 "register_operand" "=r")
- (udiv:QI (subreg:QI (match_operand:DI 1 "reg_or_mem_operand" "0") 0)
- (match_operand:QI 2 "general_operand" "g")))]
- ""
- "*
-{
- operands[1] = gen_rtx (REG, QImode, REGNO (operands[0]) + 1);
- return \"deib %2,%0\;movb %1,%0\";
-}")
-
+
;; Remainder instructions.
+;; See note 1
(define_insn "modsi3"
[(set (match_operand:SI 0 "general_operand" "=g")
(mod:SI (match_operand:SI 1 "general_operand" "0")
- (match_operand:SI 2 "general_operand" "rmn")))]
+ (match_operand:SI 2 "general_operand" "g")))]
""
"remd %2,%0")
@@ -1266,43 +1474,14 @@
""
"remb %2,%0")
-(define_insn "umodsi3"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (umod:SI (subreg:SI (match_operand:DI 1 "reg_or_mem_operand" "0") 0)
- (match_operand:SI 2 "general_operand" "rmn")))]
- ""
- "deid %2,%0")
-
-(define_insn "umodhi3"
- [(set (match_operand:HI 0 "register_operand" "=r")
- (umod:HI (subreg:HI (match_operand:DI 1 "reg_or_mem_operand" "0") 0)
- (match_operand:HI 2 "general_operand" "g")))]
- ""
- "deiw %2,%0")
-
-(define_insn "umodqi3"
- [(set (match_operand:QI 0 "register_operand" "=r")
- (umod:QI (subreg:QI (match_operand:DI 1 "reg_or_mem_operand" "0") 0)
- (match_operand:QI 2 "general_operand" "g")))]
- ""
- "deib %2,%0")
-
-; This isn't be usable in its current form.
-;(define_insn "udivmoddisi4"
-; [(set (subreg:SI (match_operand:DI 0 "general_operand" "=r") 1)
-; (udiv:SI (match_operand:DI 1 "general_operand" "0")
-; (match_operand:SI 2 "general_operand" "rmn")))
-; (set (subreg:SI (match_dup 0) 0)
-; (umod:SI (match_dup 1) (match_dup 2)))]
-; ""
-; "deid %2,%0")
;;- Logical Instructions: AND
+;; See note 1
(define_insn "andsi3"
[(set (match_operand:SI 0 "general_operand" "=g")
(and:SI (match_operand:SI 1 "general_operand" "%0")
- (match_operand:SI 2 "general_operand" "rmn")))]
+ (match_operand:SI 2 "general_operand" "g")))]
""
"*
{
@@ -1360,9 +1539,10 @@
""
"andb %2,%0")
+;; See note 1
(define_insn ""
[(set (match_operand:SI 0 "general_operand" "=g")
- (and:SI (not:SI (match_operand:SI 1 "general_operand" "rmn"))
+ (and:SI (not:SI (match_operand:SI 1 "general_operand" "g"))
(match_operand:SI 2 "general_operand" "0")))]
""
"bicd %1,%0")
@@ -1383,10 +1563,11 @@
;;- Bit set instructions.
+;; See note 1
(define_insn "iorsi3"
[(set (match_operand:SI 0 "general_operand" "=g")
(ior:SI (match_operand:SI 1 "general_operand" "%0")
- (match_operand:SI 2 "general_operand" "rmn")))]
+ (match_operand:SI 2 "general_operand" "g")))]
""
"*
{
@@ -1421,10 +1602,11 @@
;;- xor instructions.
+;; See note 1
(define_insn "xorsi3"
[(set (match_operand:SI 0 "general_operand" "=g")
(xor:SI (match_operand:SI 1 "general_operand" "%0")
- (match_operand:SI 2 "general_operand" "rmn")))]
+ (match_operand:SI 2 "general_operand" "g")))]
""
"*
{
@@ -1458,8 +1640,8 @@
"xorb %2,%0")
(define_insn "negdf2"
- [(set (match_operand:DF 0 "general_operand" "=fm<")
- (neg:DF (match_operand:DF 1 "general_operand" "fmF")))]
+ [(set (match_operand:DF 0 "general_operand" "=lm<")
+ (neg:DF (match_operand:DF 1 "general_operand" "lmF")))]
"TARGET_32081"
"negl %1,%0")
@@ -1497,9 +1679,10 @@
return \"\";
}")
+;; See note 1
(define_insn "negsi2"
[(set (match_operand:SI 0 "general_operand" "=g<")
- (neg:SI (match_operand:SI 1 "general_operand" "rmn")))]
+ (neg:SI (match_operand:SI 1 "general_operand" "g")))]
""
"negd %1,%0")
@@ -1515,9 +1698,10 @@
""
"negb %1,%0")
+;; See note 1
(define_insn "one_cmplsi2"
[(set (match_operand:SI 0 "general_operand" "=g<")
- (not:SI (match_operand:SI 1 "general_operand" "rmn")))]
+ (not:SI (match_operand:SI 1 "general_operand" "g")))]
""
"comd %1,%0")
@@ -1540,10 +1724,11 @@
;; than elsewhere.
;; alternative 0 never matches on the 32532
+;; See note 1
(define_insn "ashlsi3"
[(set (match_operand:SI 0 "general_operand" "=g,g")
(ashift:SI (match_operand:SI 1 "general_operand" "r,0")
- (match_operand:SI 2 "general_operand" "I,rmn")))]
+ (match_operand:SI 2 "general_operand" "I,g")))]
""
"*
{ if (TARGET_32532)
@@ -1555,7 +1740,7 @@
(define_insn "ashlhi3"
[(set (match_operand:HI 0 "general_operand" "=g")
(ashift:HI (match_operand:HI 1 "general_operand" "0")
- (match_operand:SI 2 "general_operand" "rmn")))]
+ (match_operand:SI 2 "general_operand" "g")))]
""
"*
{ if (GET_CODE (operands[2]) == CONST_INT)
@@ -1574,7 +1759,7 @@
(define_insn "ashlqi3"
[(set (match_operand:QI 0 "general_operand" "=g")
(ashift:QI (match_operand:QI 1 "general_operand" "0")
- (match_operand:SI 2 "general_operand" "rmn")))]
+ (match_operand:SI 2 "general_operand" "g")))]
""
"*
{ if (GET_CODE (operands[2]) == CONST_INT)
@@ -1607,7 +1792,7 @@
(ashiftrt:SI (match_operand:SI 1 "general_operand" "0")
(match_operand:SI 2 "immediate_operand" "i")))]
""
- "ashd %$%n2,%0")
+ "ashd %n2,%0")
(define_insn ""
[(set (match_operand:SI 0 "general_operand" "=g")
@@ -1632,7 +1817,7 @@
(ashiftrt:HI (match_operand:HI 1 "general_operand" "0")
(match_operand:SI 2 "immediate_operand" "i")))]
""
- "ashw %$%n2,%0")
+ "ashw %n2,%0")
(define_insn ""
[(set (match_operand:HI 0 "general_operand" "=g")
@@ -1657,7 +1842,7 @@
(ashiftrt:QI (match_operand:QI 1 "general_operand" "0")
(match_operand:SI 2 "immediate_operand" "i")))]
""
- "ashb %$%n2,%0")
+ "ashb %n2,%0")
(define_insn ""
[(set (match_operand:QI 0 "general_operand" "=g")
@@ -1685,7 +1870,7 @@
(lshiftrt:SI (match_operand:SI 1 "general_operand" "0")
(match_operand:SI 2 "immediate_operand" "i")))]
""
- "lshd %$%n2,%0")
+ "lshd %n2,%0")
(define_insn ""
[(set (match_operand:SI 0 "general_operand" "=g")
@@ -1710,7 +1895,7 @@
(lshiftrt:HI (match_operand:HI 1 "general_operand" "0")
(match_operand:SI 2 "immediate_operand" "i")))]
""
- "lshw %$%n2,%0")
+ "lshw %n2,%0")
(define_insn ""
[(set (match_operand:HI 0 "general_operand" "=g")
@@ -1735,7 +1920,7 @@
(lshiftrt:QI (match_operand:QI 1 "general_operand" "0")
(match_operand:SI 2 "immediate_operand" "i")))]
""
- "lshb %$%n2,%0")
+ "lshb %n2,%0")
(define_insn ""
[(set (match_operand:QI 0 "general_operand" "=g")
@@ -1746,24 +1931,25 @@
;; Rotate instructions
+;; See note 1
(define_insn "rotlsi3"
[(set (match_operand:SI 0 "general_operand" "=g")
(rotate:SI (match_operand:SI 1 "general_operand" "0")
- (match_operand:SI 2 "general_operand" "rmn")))]
+ (match_operand:SI 2 "general_operand" "g")))]
""
"rotd %2,%0")
(define_insn "rotlhi3"
[(set (match_operand:HI 0 "general_operand" "=g")
(rotate:HI (match_operand:HI 1 "general_operand" "0")
- (match_operand:SI 2 "general_operand" "rmn")))]
+ (match_operand:SI 2 "general_operand" "g")))]
""
"rotw %2,%0")
(define_insn "rotlqi3"
[(set (match_operand:QI 0 "general_operand" "=g")
(rotate:QI (match_operand:QI 1 "general_operand" "0")
- (match_operand:SI 2 "general_operand" "rmn")))]
+ (match_operand:SI 2 "general_operand" "g")))]
""
"rotb %2,%0")
@@ -1784,7 +1970,7 @@
(rotatert:SI (match_operand:SI 1 "general_operand" "0")
(match_operand:SI 2 "immediate_operand" "i")))]
""
- "rotd %$%n2,%0")
+ "rotd %n2,%0")
(define_insn ""
[(set (match_operand:SI 0 "general_operand" "=g")
@@ -1809,7 +1995,7 @@
(rotatert:HI (match_operand:HI 1 "general_operand" "0")
(match_operand:SI 2 "immediate_operand" "i")))]
""
- "rotw %$%n2,%0")
+ "rotw %n2,%0")
(define_insn ""
[(set (match_operand:HI 0 "general_operand" "=g")
@@ -1834,7 +2020,7 @@
(rotatert:QI (match_operand:QI 1 "general_operand" "0")
(match_operand:SI 2 "immediate_operand" "i")))]
""
- "rotb %$%n2,%0")
+ "rotb %n2,%0")
(define_insn ""
[(set (match_operand:QI 0 "general_operand" "=g")
@@ -1871,53 +2057,58 @@
;;; Index insns. These are about the same speed as multiply-add counterparts.
;;; but slower then using power-of-2 shifts if we can use them
;
+;;; See note 1
;(define_insn ""
; [(set (match_operand:SI 0 "register_operand" "=r")
-; (plus:SI (match_operand:SI 1 "general_operand" "rmn")
+; (plus:SI (match_operand:SI 1 "general_operand" "g")
; (mult:SI (match_operand:SI 2 "register_operand" "0")
-; (plus:SI (match_operand:SI 3 "general_operand" "rmn") (const_int 1)))))]
+; (plus:SI (match_operand:SI 3 "general_operand" "g") (const_int 1)))))]
; "GET_CODE (operands[3]) != CONST_INT || INTVAL (operands[3]) > 8"
; "indexd %0,%3,%1")
;
;(define_insn ""
; [(set (match_operand:SI 0 "register_operand" "=r")
; (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "0")
-; (plus:SI (match_operand:SI 2 "general_operand" "rmn") (const_int 1)))
-; (match_operand:SI 3 "general_operand" "rmn")))]
+; (plus:SI (match_operand:SI 2 "general_operand" "g") (const_int 1)))
+; (match_operand:SI 3 "general_operand" "g")))]
; "GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) > 8"
; "indexd %0,%2,%3")
;; Set, Clear, and Invert bit
+;; See note 1
(define_insn ""
[(set (zero_extract:SI (match_operand:SI 0 "general_operand" "+g")
(const_int 1)
- (match_operand:SI 1 "general_operand" "rmn"))
+ (match_operand:SI 1 "general_operand" "g"))
(const_int 1))]
""
"sbitd %1,%0")
+;; See note 1
(define_insn ""
[(set (zero_extract:SI (match_operand:SI 0 "general_operand" "+g")
(const_int 1)
- (match_operand:SI 1 "general_operand" "rmn"))
+ (match_operand:SI 1 "general_operand" "g"))
(const_int 0))]
""
"cbitd %1,%0")
+;; See note 1
(define_insn ""
[(set (match_operand:SI 0 "general_operand" "+g")
(xor:SI (ashift:SI (const_int 1)
- (match_operand:SI 1 "general_operand" "rmn"))
+ (match_operand:SI 1 "general_operand" "g"))
(match_dup 0)))]
""
"ibitd %1,%0")
+;; See note 1
(define_insn ""
[(set (match_operand:QI 0 "general_operand" "=g")
(xor:QI (subreg:QI
(ashift:SI (const_int 1)
- (match_operand:QI 1 "general_operand" "rmn")) 0)
+ (match_operand:QI 1 "general_operand" "g")) 0)
(match_dup 0)))]
""
"ibitb %1,%0")
@@ -2308,7 +2499,7 @@
(minus:SI (match_dup 0)
(match_dup 1)))]
"INTVAL (operands[1]) > -8 && INTVAL (operands[1]) <= 8"
- "acbd %$%n1,%0,%l2")
+ "acbd %n1,%0,%l2")
(define_insn ""
[(set (pc)
@@ -2450,14 +2641,15 @@
"absf %1,%0")
(define_insn "absdf2"
- [(set (match_operand:DF 0 "general_operand" "=fm<")
- (abs:DF (match_operand:DF 1 "general_operand" "fmF")))]
+ [(set (match_operand:DF 0 "general_operand" "=lm<")
+ (abs:DF (match_operand:DF 1 "general_operand" "lmF")))]
"TARGET_32081"
"absl %1,%0")
+;; See note 1
(define_insn "abssi2"
[(set (match_operand:SI 0 "general_operand" "=g<")
- (abs:SI (match_operand:SI 1 "general_operand" "rmn")))]
+ (abs:SI (match_operand:SI 1 "general_operand" "g")))]
""
"absd %1,%0")
@@ -2745,14 +2937,14 @@
;; Speed up stack adjust followed by a HI fixedpoint push.
(define_peephole
- [(set (reg:SI 17) (plus:SI (reg:SI 17) (const_int -2)))
+ [(set (reg:SI 25) (plus:SI (reg:SI 25) (const_int -2)))
(set (match_operand:HI 0 "push_operand" "=m")
(match_operand:HI 1 "general_operand" "g"))]
"! reg_mentioned_p (stack_pointer_rtx, operands[1])"
"*
{
if (GET_CODE (operands[1]) == CONST_INT)
- output_asm_insn (output_move_dconst (INTVAL (operands[1]), \"%$%1,tos\"),
+ output_asm_insn (output_move_dconst (INTVAL (operands[1]), \"%1,tos\"),
operands);
else
output_asm_insn (\"movzwd %1,tos\", operands);
@@ -2762,14 +2954,14 @@
;; Speed up stack adjust followed by a zero_extend:HI(QI) fixedpoint push.
(define_peephole
- [(set (reg:SI 17) (plus:SI (reg:SI 17) (const_int -2)))
+ [(set (reg:SI 25) (plus:SI (reg:SI 25) (const_int -2)))
(set (match_operand:HI 0 "push_operand" "=m")
(zero_extend:HI (match_operand:QI 1 "general_operand" "g")))]
"! reg_mentioned_p (stack_pointer_rtx, operands[1])"
"*
{
if (GET_CODE (operands[1]) == CONST_INT)
- output_asm_insn (output_move_dconst (INTVAL (operands[1]), \"%$%1,tos\"),
+ output_asm_insn (output_move_dconst (INTVAL (operands[1]), \"%1,tos\"),
operands);
else
output_asm_insn (\"movzbd %1,tos\", operands);
@@ -2779,14 +2971,14 @@
;; Speed up stack adjust followed by a sign_extend:HI(QI) fixedpoint push.
(define_peephole
- [(set (reg:SI 17) (plus:SI (reg:SI 17) (const_int -2)))
+ [(set (reg:SI 25) (plus:SI (reg:SI 25) (const_int -2)))
(set (match_operand:HI 0 "push_operand" "=m")
(sign_extend:HI (match_operand:QI 1 "general_operand" "g")))]
"! reg_mentioned_p (stack_pointer_rtx, operands[1])"
"*
{
if (GET_CODE (operands[1]) == CONST_INT)
- output_asm_insn (output_move_dconst (INTVAL (operands[1]), \"%$%1,tos\"),
+ output_asm_insn (output_move_dconst (INTVAL (operands[1]), \"%1,tos\"),
operands);
else
output_asm_insn (\"movxbd %1,tos\", operands);
@@ -2796,14 +2988,14 @@
;; Speed up stack adjust followed by a QI fixedpoint push.
(define_peephole
- [(set (reg:SI 17) (plus:SI (reg:SI 17) (const_int -3)))
+ [(set (reg:SI 25) (plus:SI (reg:SI 25) (const_int -3)))
(set (match_operand:QI 0 "push_operand" "=m")
(match_operand:QI 1 "general_operand" "g"))]
"! reg_mentioned_p (stack_pointer_rtx, operands[1])"
"*
{
if (GET_CODE (operands[1]) == CONST_INT)
- output_asm_insn (output_move_dconst (INTVAL (operands[1]), \"%$%1,tos\"),
+ output_asm_insn (output_move_dconst (INTVAL (operands[1]), \"%1,tos\"),
operands);
else
output_asm_insn (\"movzbd %1,tos\", operands);
@@ -2813,14 +3005,14 @@
;; Speed up stack adjust followed by a SI fixedpoint push.
(define_peephole
- [(set (reg:SI 17) (plus:SI (reg:SI 17) (const_int 4)))
+ [(set (reg:SI 25) (plus:SI (reg:SI 25) (const_int 4)))
(set (match_operand:SI 0 "push_operand" "=m")
(match_operand:SI 1 "general_operand" "g"))]
"! reg_mentioned_p (stack_pointer_rtx, operands[1])"
"*
{
if (GET_CODE (operands[1]) == CONST_INT)
- output_asm_insn (output_move_dconst (INTVAL (operands[1]), \"%$%1,0(sp)\"),
+ output_asm_insn (output_move_dconst (INTVAL (operands[1]), \"%1,0(sp)\"),
operands);
else if (GET_CODE (operands[1]) != REG
&& GET_CODE (operands[1]) != MEM
@@ -2834,7 +3026,7 @@
;; Speed up stack adjust followed by two fullword fixedpoint pushes.
(define_peephole
- [(set (reg:SI 17) (plus:SI (reg:SI 17) (const_int 8)))
+ [(set (reg:SI 25) (plus:SI (reg:SI 25) (const_int 8)))
(set (match_operand:SI 0 "push_operand" "=m")
(match_operand:SI 1 "general_operand" "g"))
(set (match_operand:SI 2 "push_operand" "=m")
@@ -2844,7 +3036,7 @@
"*
{
if (GET_CODE (operands[1]) == CONST_INT)
- output_asm_insn (output_move_dconst (INTVAL (operands[1]), \"%$%1,4(sp)\"),
+ output_asm_insn (output_move_dconst (INTVAL (operands[1]), \"%1,4(sp)\"),
operands);
else if (GET_CODE (operands[1]) != REG
&& GET_CODE (operands[1]) != MEM
@@ -2854,7 +3046,7 @@
output_asm_insn (\"movd %1,4(sp)\", operands);
if (GET_CODE (operands[3]) == CONST_INT)
- output_asm_insn (output_move_dconst (INTVAL (operands[3]), \"%$%3,0(sp)\"),
+ output_asm_insn (output_move_dconst (INTVAL (operands[3]), \"%3,0(sp)\"),
operands);
else if (GET_CODE (operands[3]) != REG
&& GET_CODE (operands[3]) != MEM
diff --git a/gcc/config/pa/pa-gas.h b/gcc/config/pa/pa-gas.h
index d7da9e733b1..cd2ddaeac12 100644
--- a/gcc/config/pa/pa-gas.h
+++ b/gcc/config/pa/pa-gas.h
@@ -15,7 +15,8 @@ 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
#undef TARGET_DEFAULT
-#define TARGET_DEFAULT 0x88 /* TARGET_GAS + TARGET_JUMP_IN_DELAY */
+#define TARGET_DEFAULT (MASK_GAS | MASK_JUMP_IN_DELAY)
diff --git a/gcc/config/pa/pa-hpux.h b/gcc/config/pa/pa-hpux.h
index e001ebe438c..1838442e948 100644
--- a/gcc/config/pa/pa-hpux.h
+++ b/gcc/config/pa/pa-hpux.h
@@ -36,7 +36,7 @@ Boston, MA 02111-1307, USA. */
#define CPP_PREDEFINES "-Dhppa -Dhp9000s800 -D__hp9000s800 -Dhp9k8 -DPWB -Dhpux -Dunix -Asystem(unix) -Asystem(hpux) -Acpu(hppa) -Amachine(hppa)"
#undef LINK_SPEC
-#if ((TARGET_DEFAULT | TARGET_CPU_DEFAULT) & 1)
+#if ((TARGET_DEFAULT | TARGET_CPU_DEFAULT) & MASK_SNAKE)
#define LINK_SPEC \
"%{!mpa-risc-1-0:%{!shared:-L/lib/pa1.1 -L/usr/lib/pa1.1 }}%{mlinker-opt:-O} %{!shared:-u main} %{static:-a archive} %{g*:-a archive} %{shared:-b}"
#else
diff --git a/gcc/config/pa/pa-hpux10.h b/gcc/config/pa/pa-hpux10.h
index 0cd59127f68..5050f24f4c8 100644
--- a/gcc/config/pa/pa-hpux10.h
+++ b/gcc/config/pa/pa-hpux10.h
@@ -22,7 +22,7 @@ Boston, MA 02111-1307, USA. */
/* We can debug dynamically linked executables on hpux9; we also want
dereferencing of a NULL pointer to cause a SEGV. */
#undef LINK_SPEC
-#if ((TARGET_DEFAULT | TARGET_CPU_DEFAULT) & 1)
+#if ((TARGET_DEFAULT | TARGET_CPU_DEFAULT) & MASK_SNAKE)
#define LINK_SPEC \
"%{!mpa-risc-1-0:%{!shared:-L/lib/pa1.1 -L/usr/lib/pa1.1 }} -z %{mlinker-opt:-O} %{!shared:-u main} %{static:-a archive} %{shared:-b}"
#else
diff --git a/gcc/config/pa/pa-hpux9.h b/gcc/config/pa/pa-hpux9.h
index 8d039d2637e..c0ba9c16381 100644
--- a/gcc/config/pa/pa-hpux9.h
+++ b/gcc/config/pa/pa-hpux9.h
@@ -22,7 +22,7 @@ Boston, MA 02111-1307, USA. */
/* We can debug dynamically linked executables on hpux9; we also want
dereferencing of a NULL pointer to cause a SEGV. */
#undef LINK_SPEC
-#if ((TARGET_DEFAULT | TARGET_CPU_DEFAULT) & 1)
+#if ((TARGET_DEFAULT | TARGET_CPU_DEFAULT) & MASK_SNAKE)
#define LINK_SPEC \
"%{!mpa-risc-1-0:%{!shared:-L/lib/pa1.1 -L/usr/lib/pa1.1 }} -z %{mlinker-opt:-O} %{!shared:-u main} %{static:-a archive} %{shared:-b}"
#else
diff --git a/gcc/config/pa/pa-osf.h b/gcc/config/pa/pa-osf.h
index 047d20e34ff..1d7d3bad34c 100644
--- a/gcc/config/pa/pa-osf.h
+++ b/gcc/config/pa/pa-osf.h
@@ -20,7 +20,7 @@ the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#undef CPP_PREDEFINES
-#if ((TARGET_DEFAULT | TARGET_CPU_DEFAULT) & 1)
+#if ((TARGET_DEFAULT | TARGET_CPU_DEFAULT) & MASK_SNAKE)
#define CPP_PREDEFINES "-Dhppa -Dunix -Dhp9000 -Dspectrum -DREVARGV -Dhp700 -DHP700 -Dparisc -D__pa_risc -DPARISC -DBYTE_MSF -DBIT_MSF -Asystem(unix) -Asystem(mach) -Acpu(hppa) -Amachine(hppa)"
#else
#define CPP_PREDEFINES "-Dhppa -Dhp9000s800 -D__hp9000s800 -Dhp9k8 -Dunix -Dhp9000 -Dhp800 -Dspectrum -DREVARGV -Dparisc -D__pa_risc -DPARISC -DBYTE_MSF -DBIT_MSF -Asystem(unix) -Asystem(mach) -Acpu(hppa) -Amachine(hppa)"
diff --git a/gcc/config/pa/pa-pro-end.h b/gcc/config/pa/pa-pro-end.h
index 8b1de1c5e5f..de88036e0ba 100644
--- a/gcc/config/pa/pa-pro-end.h
+++ b/gcc/config/pa/pa-pro-end.h
@@ -15,7 +15,8 @@ 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
/* Make GCC agree with types.h. */
#undef SIZE_TYPE
diff --git a/gcc/config/pa/pa-pro.h b/gcc/config/pa/pa-pro.h
index f64ac2dc54c..8a4c2bcabd3 100644
--- a/gcc/config/pa/pa-pro.h
+++ b/gcc/config/pa/pa-pro.h
@@ -15,7 +15,8 @@ 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
/* Global constructor and destructor support. */
/* Define the pseudo-ops used to switch to the .ctors and .dtors sections.
@@ -74,5 +75,5 @@ dtors_section () \
fputs ("\n", FILE); \
} while (0)
-/* JUMP_IN_DELAY + PORTABLE_RUNTIME + GAS + NO_SPACE_REGS + SOFT_FLOAT */
-#define TARGET_DEFAULT (4 + 8 + 64 + 128 + 256)
+#define TARGET_DEFAULT (MASK_JUMP_IN_DELAY | MASK_PORTABLE_RUNTIME | \
+MASK_GAS | MASK_NO_SPACE_REGS | MASK_SOFT_FLOAT )
diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c
index 41642041e32..6eb4ea7b789 100644
--- a/gcc/config/pa/pa.c
+++ b/gcc/config/pa/pa.c
@@ -1,5 +1,5 @@
/* Subroutines for insn-output.c for HPPA.
- Copyright (C) 1992, 93, 94, 95, 96, 97, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1992, 93-98, 1999 Free Software Foundation, Inc.
Contributed by Tim Moore (moore@cs.utah.edu), based on sparc.c
This file is part of GNU CC.
@@ -96,33 +96,36 @@ static int max_unscaled_index_insn_codes_uid;
void
override_options ()
{
- /* Default to 7100 scheduling. If the 7100LC scheduling ever
- gets reasonably tuned, it should be the default since that
- what most PAs sold now are. */
- if (pa_cpu_string == NULL
- || ! strcmp (pa_cpu_string, "7100"))
+ /* Default to 7100LC scheduling. */
+ if (pa_cpu_string && ! strcmp (pa_cpu_string, "7100"))
{
pa_cpu_string = "7100";
pa_cpu = PROCESSOR_7100;
}
- else if (! strcmp (pa_cpu_string, "700"))
+ else if (pa_cpu_string && ! strcmp (pa_cpu_string, "700"))
{
pa_cpu_string = "700";
pa_cpu = PROCESSOR_700;
}
- else if (! strcmp (pa_cpu_string, "7100LC"))
+ else if (pa_cpu_string == NULL
+ || ! strcmp (pa_cpu_string, "7100LC"))
{
pa_cpu_string = "7100LC";
pa_cpu = PROCESSOR_7100LC;
}
- else if (! strcmp (pa_cpu_string, "7200"))
+ else if (pa_cpu_string && ! strcmp (pa_cpu_string, "7200"))
{
pa_cpu_string = "7200";
pa_cpu = PROCESSOR_7200;
}
+ else if (pa_cpu_string && ! strcmp (pa_cpu_string, "8000"))
+ {
+ pa_cpu_string = "8000";
+ pa_cpu = PROCESSOR_8000;
+ }
else
{
- warning ("Unknown -mschedule= option (%s).\nValid options are 700, 7100 and 7100LC and 7200\n", pa_cpu_string);
+ warning ("Unknown -mschedule= option (%s).\nValid options are 700, 7100, 7100LC, 7200, and 8000\n", pa_cpu_string);
}
if (flag_pic && TARGET_PORTABLE_RUNTIME)
@@ -2834,6 +2837,8 @@ hppa_expand_prologue()
hp_profile_label_rtx = gen_rtx_SYMBOL_REF (SImode, hp_profile_label_name);
if (current_function_returns_struct)
store_reg (STRUCT_VALUE_REGNUM, - 12 - offsetadj, basereg);
+ if (current_function_needs_context)
+ store_reg (STATIC_CHAIN_REGNUM, - 16 - offsetadj, basereg);
for (i = 26, arg_offset = -36 - offsetadj; i >= 23; i--, arg_offset -= 4)
if (regs_ever_live [i])
@@ -2858,6 +2863,8 @@ hppa_expand_prologue()
if (current_function_returns_struct)
load_reg (STRUCT_VALUE_REGNUM, -12 - offsetadj, basereg);
+ if (current_function_needs_context)
+ load_reg (STATIC_CHAIN_REGNUM, -16 - offsetadj, basereg);
}
/* Normal register save.
@@ -4391,7 +4398,7 @@ hppa_builtin_saveregs (arglist)
last argument register store. So we emit a blockage insn here. */
emit_insn (gen_blockage ());
- if (flag_check_memory_usage)
+ if (current_function_check_memory_usage)
emit_library_call (chkr_set_right_libfunc, 1, VOIDmode, 3,
dest, ptr_mode,
GEN_INT (4 * UNITS_PER_WORD), TYPE_MODE (sizetype),
@@ -4461,11 +4468,11 @@ output_cbranch (operands, nullify, length, negated, insn)
else
strcat (buf, "%S3");
if (useskip)
- strcat (buf, " %2,%1,0");
+ strcat (buf, " %2,%r1,0");
else if (nullify)
- strcat (buf, ",n %2,%1,%0");
+ strcat (buf, ",n %2,%r1,%0");
else
- strcat (buf, " %2,%1,%0");
+ strcat (buf, " %2,%r1,%0");
break;
/* All long conditionals. Note an short backward branch with an
@@ -4483,7 +4490,7 @@ output_cbranch (operands, nullify, length, negated, insn)
strcat (buf, "%S3");
else
strcat (buf, "%B3");
- strcat (buf, ",n %2,%1,.+12\n\tbl %0,0");
+ strcat (buf, ",n %2,%r1,.+12\n\tbl %0,0");
}
/* Handle short backwards branch with an unfilled delay slot.
Using a comb;nop rather than comiclr;bl saves 1 cycle for both
@@ -4496,9 +4503,9 @@ output_cbranch (operands, nullify, length, negated, insn)
{
strcpy (buf, "com%I2b,");
if (negated)
- strcat (buf, "%B3 %2,%1,%0%#");
+ strcat (buf, "%B3 %2,%r1,%0%#");
else
- strcat (buf, "%S3 %2,%1,%0%#");
+ strcat (buf, "%S3 %2,%r1,%0%#");
}
else
{
@@ -4508,9 +4515,9 @@ output_cbranch (operands, nullify, length, negated, insn)
else
strcat (buf, "%B3");
if (nullify)
- strcat (buf, " %2,%1,0\n\tbl,n %0,0");
+ strcat (buf, " %2,%r1,0\n\tbl,n %0,0");
else
- strcat (buf, " %2,%1,0\n\tbl %0,0");
+ strcat (buf, " %2,%r1,0\n\tbl %0,0");
}
break;
@@ -4523,9 +4530,9 @@ output_cbranch (operands, nullify, length, negated, insn)
/* Create a reversed conditional branch which branches around
the following insns. */
if (negated)
- strcpy (buf, "com%I2b,%S3,n %2,%1,.+20");
+ strcpy (buf, "com%I2b,%S3,n %2,%r1,.+20");
else
- strcpy (buf, "com%I2b,%B3,n %2,%1,.+20");
+ strcpy (buf, "com%I2b,%B3,n %2,%r1,.+20");
output_asm_insn (buf, operands);
/* Output an insn to save %r1. */
@@ -4548,9 +4555,9 @@ output_cbranch (operands, nullify, length, negated, insn)
/* Create a reversed conditional branch which branches around
the following insns. */
if (negated)
- strcpy (buf, "com%I2b,%S3,n %2,%1,.+28");
+ strcpy (buf, "com%I2b,%S3,n %2,%r1,.+28");
else
- strcpy (buf, "com%I2b,%B3,n %2,%1,.+28");
+ strcpy (buf, "com%I2b,%B3,n %2,%r1,.+28");
output_asm_insn (buf, operands);
/* Output an insn to save %r1. */
@@ -6432,3 +6439,31 @@ pa_can_combine_p (new, anchor, floater, reversed, dest, src1, src2)
/* If we get here, then everything is good. */
return 1;
}
+
+/* Return nonzero if sets and references for INSN are delayed.
+
+ Millicode insns are actually function calls with some special
+ constraints on arguments and register usage.
+
+ Millicode calls always expect their arguments in the integer argument
+ registers, and always return their result in %r29 (ret1). They
+ are expected to clobber their arguments, %r1, %r29, and %r31 and
+ nothing else.
+
+ By considering this effects delayed reorg reorg can put insns
+ which set the argument registers into the delay slot of the millicode
+ call -- thus they act more like traditional CALL_INSNs.
+
+ get_attr_type will try to recognize the given insn, so make sure to
+ filter out things it will not accept -- SEQUENCE, USE and CLOBBER insns
+ in particular. */
+int
+insn_sets_and_refs_are_delayed (insn)
+ rtx insn;
+{
+ return ((GET_CODE (insn) == INSN
+ && GET_CODE (PATTERN (insn)) != SEQUENCE
+ && GET_CODE (PATTERN (insn)) != USE
+ && GET_CODE (PATTERN (insn)) != CLOBBER
+ && get_attr_type (insn) == TYPE_MILLI));
+}
diff --git a/gcc/config/pa/pa.h b/gcc/config/pa/pa.h
index 1c92f211cba..2a72fb50ac4 100644
--- a/gcc/config/pa/pa.h
+++ b/gcc/config/pa/pa.h
@@ -1,5 +1,5 @@
/* Definitions of target machine for GNU compiler, for the HP Spectrum.
- Copyright (C) 1992, 93, 94, 95, 96, 97, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1992, 93-98, 1999 Free Software Foundation, Inc.
Contributed by Michael Tiemann (tiemann@cygnus.com) of Cygnus Support
and Tim Moore (moore@defmacro.cs.utah.edu) of the Center for
Software Science at the University of Utah.
@@ -39,7 +39,8 @@ enum processor_type
PROCESSOR_700,
PROCESSOR_7100,
PROCESSOR_7100LC,
- PROCESSOR_7200
+ PROCESSOR_7200,
+ PROCESSOR_8000
};
/* For -mschedule= option. */
@@ -49,8 +50,15 @@ extern enum processor_type pa_cpu;
#define pa_cpu_attr ((enum attr_cpu)pa_cpu)
/* The 700 can only issue a single insn at a time.
- The 7XXX processors can issue two insns at a time. */
-#define ISSUE_RATE (pa_cpu == PROCESSOR_700 ? 1 : 2)
+ The 7XXX processors can issue two insns at a time.
+ The 8000 can issue 4 insns at a time. */
+#define ISSUE_RATE \
+ (pa_cpu == PROCESSOR_700 ? 1 \
+ : pa_cpu == PROCESSOR_7100 ? 2 \
+ : pa_cpu == PROCESSOR_7100LC ? 2 \
+ : pa_cpu == PROCESSOR_7200 ? 2 \
+ : pa_cpu == PROCESSOR_8000 ? 4 \
+ : 2)
/* Print subsidiary information on the compiler version in use. */
@@ -62,14 +70,16 @@ extern int target_flags;
/* compile code for HP-PA 1.1 ("Snake") */
-#define TARGET_SNAKE (target_flags & 1)
+#define MASK_SNAKE 1
+#define TARGET_SNAKE (target_flags & MASK_SNAKE)
/* Disable all FP registers (they all become fixed). This may be necessary
for compiling kernels which perform lazy context switching of FP regs.
Note if you use this option and try to perform floating point operations
the compiler will abort! */
-#define TARGET_DISABLE_FPREGS (target_flags & 2)
+#define MASK_DISABLE_FPREGS 2
+#define TARGET_DISABLE_FPREGS (target_flags & MASK_DISABLE_FPREGS)
/* Generate code which assumes that calls through function pointers will
never cross a space boundary. Such assumptions are generally safe for
@@ -78,18 +88,21 @@ extern int target_flags;
or uses nested functions!
This is also used to trigger aggressive unscaled index addressing. */
-#define TARGET_NO_SPACE_REGS (target_flags & 4)
+#define MASK_NO_SPACE_REGS 4
+#define TARGET_NO_SPACE_REGS (target_flags & MASK_NO_SPACE_REGS)
/* Allow unconditional jumps in the delay slots of call instructions. */
-#define TARGET_JUMP_IN_DELAY (target_flags & 8)
+#define MASK_JUMP_IN_DELAY 8
+#define TARGET_JUMP_IN_DELAY (target_flags & MASK_JUMP_IN_DELAY)
/* Optimize for space. Currently this only turns on out of line
prologues and epilogues. */
-#define TARGET_SPACE (target_flags & 16)
+#define MASK_SPACE 16
+#define TARGET_SPACE (target_flags & MASK_SPACE)
/* Disable indexed addressing modes. */
-
-#define TARGET_DISABLE_INDEXING (target_flags & 32)
+#define MASK_DISABLE_INDEXING 32
+#define TARGET_DISABLE_INDEXING (target_flags & MASK_DISABLE_INDEXING)
/* Emit code which follows the new portable runtime calling conventions
HP wants everyone to use for ELF objects. If at all possible you want
@@ -97,29 +110,32 @@ extern int target_flags;
Note TARGET_PORTABLE_RUNTIME also forces all calls to use inline
long-call stubs which is quite expensive. */
-
-#define TARGET_PORTABLE_RUNTIME (target_flags & 64)
+#define MASK_PORTABLE_RUNTIME 64
+#define TARGET_PORTABLE_RUNTIME (target_flags & MASK_PORTABLE_RUNTIME)
/* Emit directives only understood by GAS. This allows parameter
relocations to work for static functions. There is no way
to make them work the HP assembler at this time. */
-
-#define TARGET_GAS (target_flags & 128)
+#define MASK_GAS 128
+#define TARGET_GAS (target_flags & MASK_GAS)
/* Emit code for processors which do not have an FPU. */
-
-#define TARGET_SOFT_FLOAT (target_flags & 256)
+#define MASK_SOFT_FLOAT 256
+#define TARGET_SOFT_FLOAT (target_flags & MASK_SOFT_FLOAT)
/* Use 3-insn load/store sequences for access to large data segments
in shared libraries on hpux10. */
-#define TARGET_LONG_LOAD_STORE (target_flags & 512)
+#define MASK_LONG_LOAD_STORE 512
+#define TARGET_LONG_LOAD_STORE (target_flags & MASK_LONG_LOAD_STORE)
/* Use a faster sequence for indirect calls. */
-#define TARGET_FAST_INDIRECT_CALLS (target_flags & 1024)
+#define MASK_FAST_INDIRECT_CALLS 1024
+#define TARGET_FAST_INDIRECT_CALLS (target_flags & MASK_FAST_INDIRECT_CALLS)
/* Generate code with big switch statements to avoid out of range branches
occurring within the switch table. */
-#define TARGET_BIG_SWITCH (target_flags & 2048)
+#define MASK_BIG_SWITCH 2048
+#define TARGET_BIG_SWITCH (target_flags & MASK_BIG_SWITCH)
/* Macro to define tables used to set the flags.
This is a list in braces of pairs in braces,
@@ -128,37 +144,37 @@ extern int target_flags;
An empty string NAME is used to identify the default VALUE. */
#define TARGET_SWITCHES \
- {{"snake", 1}, \
- {"nosnake", -1}, \
- {"pa-risc-1-0", -1}, \
- {"pa-risc-1-1", 1}, \
- {"disable-fpregs", 2}, \
- {"no-disable-fpregs", -2}, \
- {"no-space-regs", 4}, \
- {"space-regs", -4}, \
- {"jump-in-delay", 8}, \
- {"no-jump-in-delay", -8}, \
- {"space", 16}, \
- {"no-space", -16}, \
- {"disable-indexing", 32}, \
- {"no-disable-indexing", -32},\
- {"portable-runtime", 64}, \
- {"no-portable-runtime", -64},\
- {"gas", 128}, \
- {"no-gas", -128}, \
- {"soft-float", 256}, \
- {"no-soft-float", -256}, \
- {"long-load-store", 512}, \
- {"no-long-load-store", -512},\
- {"fast-indirect-calls", 1024},\
- {"no-fast-indirect-calls", -1024},\
- {"big-switch", 2048}, \
- {"no-big-switch", -2048}, \
- {"linker-opt", 0}, \
- { "", TARGET_DEFAULT | TARGET_CPU_DEFAULT}}
+ {{"snake", MASK_SNAKE, "Generate PA1.1 code"}, \
+ {"nosnake", -MASK_SNAKE, "Do not generate PA1.1 code"}, \
+ {"pa-risc-1-0", -MASK_SNAKE, "Do not generate PA1.1 code"}, \
+ {"pa-risc-1-1", MASK_SNAKE, "Generate PA1.1 code"}, \
+ {"disable-fpregs", MASK_DISABLE_FPREGS, "Disable FP regs"}, \
+ {"no-disable-fpregs", -MASK_DISABLE_FPREGS, "Do not disable FP regs"},\
+ {"no-space-regs", MASK_NO_SPACE_REGS, "Disable space regs"}, \
+ {"space-regs", -MASK_NO_SPACE_REGS, "Do not disable space regs"}, \
+ {"jump-in-delay", MASK_JUMP_IN_DELAY, "Put jumps in call delay slots"},\
+ {"no-jump-in-delay", -MASK_JUMP_IN_DELAY, "Do not put jumps in call delay slots"}, \
+ {"space", MASK_SPACE, "Optimize for code space"}, \
+ {"no-space", -MASK_SPACE, "Do not optimize for code space"}, \
+ {"disable-indexing", MASK_DISABLE_INDEXING, "Disable indexed addressing"},\
+ {"no-disable-indexing", -MASK_DISABLE_INDEXING, "Do not disable indexed addressing"},\
+ {"portable-runtime", MASK_PORTABLE_RUNTIME, "Use portable calling conventions"}, \
+ {"no-portable-runtime", -MASK_PORTABLE_RUNTIME, "Do not use portable calling conventions"},\
+ {"gas", MASK_GAS, "Assume code will be assembled by GAS"}, \
+ {"no-gas", -MASK_GAS, "Do not assume code will be assembled by GAS"}, \
+ {"soft-float", MASK_SOFT_FLOAT, "Use software floating point"}, \
+ {"no-soft-float", -MASK_SOFT_FLOAT, "Do not use software floating point"}, \
+ {"long-load-store", MASK_LONG_LOAD_STORE, "Emit long load/store sequences"}, \
+ {"no-long-load-store", -MASK_LONG_LOAD_STORE, "Do not emit long load/store sequences"},\
+ {"fast-indirect-calls", MASK_FAST_INDIRECT_CALLS, "Generate fast indirect calls"},\
+ {"no-fast-indirect-calls", -MASK_FAST_INDIRECT_CALLS, "Do not generate fast indirect calls"},\
+ {"big-switch", MASK_BIG_SWITCH, "Generate code for huge switch statements"}, \
+ {"no-big-switch", -MASK_BIG_SWITCH, "Do not generate code for huge switch statements"}, \
+ {"linker-opt", 0, "Enable linker optimizations"}, \
+ { "", TARGET_DEFAULT | TARGET_CPU_DEFAULT, NULL}}
#ifndef TARGET_DEFAULT
-#define TARGET_DEFAULT 0x88 /* TARGET_GAS + TARGET_JUMP_IN_DELAY */
+#define TARGET_DEFAULT (MASK_GAS | MASK_JUMP_IN_DELAY)
#endif
#ifndef TARGET_CPU_DEFAULT
@@ -167,7 +183,7 @@ extern int target_flags;
#define TARGET_OPTIONS \
{ \
- { "schedule=", &pa_cpu_string }\
+ { "schedule=", &pa_cpu_string, "Specify CPU for scheduling purposes" }\
}
#define OVERRIDE_OPTIONS override_options ()
@@ -238,7 +254,7 @@ extern int target_flags;
fprintf (FILE, \
"\t.stabs \"\",%d,0,0,L$text_end0000\nL$text_end0000:\n", N_SO)
-#if ((TARGET_DEFAULT | TARGET_CPU_DEFAULT) & 1) == 0
+#if ((TARGET_DEFAULT | TARGET_CPU_DEFAULT) & MASK_SNAKE) == 0
#define CPP_SPEC "%{msnake:-D__hp9000s700 -D_PA_RISC1_1}\
%{mpa-risc-1-1:-D__hp9000s700 -D_PA_RISC1_1}\
%{!ansi: -D_HPUX_SOURCE -D_HIUX_SOURCE}\
@@ -555,23 +571,30 @@ do { \
registers will generally not be allocated across a call).
Experimentation has shown slightly better results by allocating
- FP registers first. */
+ FP registers first.
+
+ FP registers are ordered so that all L registers are selected before
+ R registers. This works around a false dependency interlock on the
+ PA8000 when accessing the high and low parts of an FP register
+ independently. */
#define REG_ALLOC_ORDER \
{ \
/* caller-saved fp regs. */ \
- 68, 69, 70, 71, 72, 73, 74, 75, \
- 76, 77, 78, 79, 80, 81, 82, 83, \
- 84, 85, 86, 87, \
- 40, 41, 42, 43, 44, 45, 46, 47, \
- 32, 33, 34, 35, 36, 37, 38, 39, \
+ 68, 70, 72, 74, 76, 78, 80, 82, \
+ 84, 86, 40, 42, 44, 46, 32, 34, \
+ 36, 38, \
+ 69, 71, 73, 75, 77, 79, 81, 83, \
+ 85, 87, 41, 43, 45, 47, 33, 35, \
+ 37, 39, \
/* caller-saved general regs. */ \
19, 20, 21, 22, 23, 24, 25, 26, \
27, 28, 29, 31, 2, \
/* callee-saved fp regs. */ \
- 48, 49, 50, 51, 52, 53, 54, 55, \
- 56, 57, 58, 59, 60, 61, 62, 63, \
- 64, 65, 66, 67, \
+ 48, 50, 52, 54, 56, 58, 60, 62, \
+ 64, 66, \
+ 49, 51, 53, 55, 57, 59, 61, 63, \
+ 65, 67, \
/* callee-saved general regs. */ \
3, 4, 5, 6, 7, 8, 9, 10, \
11, 12, 13, 14, 15, 16, 17, 18, \
@@ -687,7 +710,7 @@ do { \
1.1 fp regs, and the high 1.1 fp regs, to which the operands of
fmpyadd and fmpysub are restricted. */
-enum reg_class { NO_REGS, R1_REGS, GENERAL_REGS, FP_REGS, GENERAL_OR_FP_REGS,
+enum reg_class { NO_REGS, R1_REGS, GENERAL_REGS, FPUPPER_REGS, FP_REGS, GENERAL_OR_FP_REGS,
SHIFT_REGS, ALL_REGS, LIM_REG_CLASSES};
#define N_REG_CLASSES (int) LIM_REG_CLASSES
@@ -695,7 +718,7 @@ enum reg_class { NO_REGS, R1_REGS, GENERAL_REGS, FP_REGS, GENERAL_OR_FP_REGS,
/* Give names of register classes as strings for dump file. */
#define REG_CLASS_NAMES \
- {"NO_REGS", "R1_REGS", "GENERAL_REGS", "FP_REGS", \
+ {"NO_REGS", "R1_REGS", "GENERAL_REGS", "FPUPPER_REGS", "FP_REGS", \
"GENERAL_OR_FP_REGS", "SHIFT_REGS", "ALL_REGS"}
/* Define which registers fit in which classes.
@@ -707,6 +730,7 @@ enum reg_class { NO_REGS, R1_REGS, GENERAL_REGS, FP_REGS, GENERAL_OR_FP_REGS,
{{0x00000000, 0x00000000, 0x00000000}, /* NO_REGS */ \
{0x00000002, 0x00000000, 0x00000000}, /* R1_REGS */ \
{0xfffffffe, 0x00000000, 0x00000000}, /* GENERAL_REGS */ \
+ {0x00000000, 0xff000000, 0x00ffffff}, /* FPUPPER_REGS */ \
{0x00000000, 0xffffffff, 0x00ffffff}, /* FP_REGS */ \
{0xfffffffe, 0xffffffff, 0x00ffffff}, /* GENERAL_OR_FP_REGS */ \
{0x00000000, 0x00000000, 0x01000000}, /* SHIFT_REGS */ \
@@ -721,7 +745,8 @@ enum reg_class { NO_REGS, R1_REGS, GENERAL_REGS, FP_REGS, GENERAL_OR_FP_REGS,
((REGNO) == 0 ? NO_REGS \
: (REGNO) == 1 ? R1_REGS \
: (REGNO) < 32 ? GENERAL_REGS \
- : (REGNO) < 88 ? FP_REGS \
+ : (REGNO) < 56 ? FP_REGS \
+ : (REGNO) < 88 ? FPUPPER_REGS \
: SHIFT_REGS)
/* The class value for index registers, and the one for base regs. */
@@ -729,12 +754,13 @@ enum reg_class { NO_REGS, R1_REGS, GENERAL_REGS, FP_REGS, GENERAL_OR_FP_REGS,
#define BASE_REG_CLASS GENERAL_REGS
#define FP_REG_CLASS_P(CLASS) \
- ((CLASS) == FP_REGS)
+ ((CLASS) == FP_REGS || (CLASS) == FPUPPER_REGS)
/* Get reg_class from a letter such as appears in the machine description. */
/* Keep 'x' for backward compatibility with user asm. */
#define REG_CLASS_FROM_LETTER(C) \
((C) == 'f' ? FP_REGS : \
+ (C) == 'y' ? FPUPPER_REGS : \
(C) == 'x' ? FP_REGS : \
(C) == 'q' ? SHIFT_REGS : \
(C) == 'a' ? R1_REGS : \
@@ -808,22 +834,8 @@ int zdepi_cint_p ();
/* Return the maximum number of consecutive registers
needed to represent mode MODE in a register of class CLASS. */
#define CLASS_MAX_NREGS(CLASS, MODE) \
- (!TARGET_SNAKE && (CLASS) == FP_REGS ? 1 : \
+ (!TARGET_SNAKE && ((CLASS) == FP_REGS || (CLASS) == FPUPPER_REGS) ? 1 : \
((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
-
-/* We do not want to record equivalences for expressions which are
- likely to cause a spill of %r1 if they are used by reload.
-
- Nor do we want to record an equivalence of a constant expression
- that the target can not handle appearing in an insn, but which
- also must be accepted by LEGITIMATE_CONSTANT_P.
-
- On the PA, these two goals are the same -- don't record any equivalences
- for symbolic operands that are not read_only_operands. */
-#define DONT_RECORD_EQUIVALENCE(NOTE) \
- (symbolic_operand (XEXP (NOTE, 0), VOIDmode) \
- && !read_only_operand (XEXP (NOTE, 0), VOIDmode))
-
/* Stack layout; function entry, exit and calling. */
@@ -1368,11 +1380,11 @@ extern struct rtx_def *hppa_builtin_saveregs ();
/* Addressing modes, and classification of registers for them. */
-#define HAVE_POST_INCREMENT
-#define HAVE_POST_DECREMENT
+#define HAVE_POST_INCREMENT 1
+#define HAVE_POST_DECREMENT 1
-#define HAVE_PRE_DECREMENT
-#define HAVE_PRE_INCREMENT
+#define HAVE_PRE_DECREMENT 1
+#define HAVE_PRE_INCREMENT 1
/* Macros to check register numbers against specific register classes. */
@@ -1451,7 +1463,7 @@ extern struct rtx_def *hppa_builtin_saveregs ();
these things in insns and then not re-recognize the insns, causing
constrain_operands to fail.
- `R' is unused.
+ `R' is used for scaled indexed addresses.
`S' is unused.
@@ -1774,11 +1786,11 @@ while (0)
&& DECL_INITIAL (EXP) \
&& (DECL_INITIAL (EXP) == error_mark_node \
|| TREE_CONSTANT (DECL_INITIAL (EXP))) \
- && !reloc) \
+ && !RELOC) \
readonly_data_section (); \
else if (TREE_CODE_CLASS (TREE_CODE (EXP)) == 'c' \
&& !(TREE_CODE (EXP) == STRING_CST && flag_writable_strings) \
- && !reloc) \
+ && !RELOC) \
readonly_data_section (); \
else \
data_section ();
@@ -2013,19 +2025,8 @@ while (0)
get_attr_type will try to recognize the given insn, so make sure to
filter out things it will not accept -- SEQUENCE, USE and CLOBBER insns
in particular. */
-#define INSN_SETS_ARE_DELAYED(X) \
- ((GET_CODE (X) == INSN \
- && GET_CODE (PATTERN (X)) != SEQUENCE \
- && GET_CODE (PATTERN (X)) != USE \
- && GET_CODE (PATTERN (X)) != CLOBBER \
- && get_attr_type (X) == TYPE_MILLI))
-
-#define INSN_REFERENCES_ARE_DELAYED(X) \
- ((GET_CODE (X) == INSN \
- && GET_CODE (PATTERN (X)) != SEQUENCE \
- && GET_CODE (PATTERN (X)) != USE \
- && GET_CODE (PATTERN (X)) != CLOBBER \
- && get_attr_type (X) == TYPE_MILLI))
+#define INSN_SETS_ARE_DELAYED(X) (insn_sets_and_refs_are_delayed (X))
+#define INSN_REFERENCES_ARE_DELAYED(X) (insn_sets_and_refs_are_delayed (X))
/* Control the assembler format that we output. */
@@ -2537,6 +2538,7 @@ extern int hppa_can_use_return_insn_p ();
extern int is_function_label_plus_const ();
extern int jump_in_call_delay ();
extern enum reg_class secondary_reload_class ();
+extern int insn_sets_and_refs_are_delayed ();
/* Declare functions defined in pa.c and used in templates. */
diff --git a/gcc/config/pa/pa.md b/gcc/config/pa/pa.md
index 2f3848c28b3..078a04efd68 100644
--- a/gcc/config/pa/pa.md
+++ b/gcc/config/pa/pa.md
@@ -1,5 +1,5 @@
;;- Machine description for HP PA-RISC architecture for GNU C compiler
-;; Copyright (C) 1992, 93-97, 1998 Free Software Foundation, Inc.
+;; Copyright (C) 1992, 93-98, 1999 Free Software Foundation, Inc.
;; Contributed by the Center for Software Science at the University
;; of Utah.
@@ -43,7 +43,7 @@
;;
;; FIXME: Add 800 scheduling for completeness?
-(define_attr "cpu" "700,7100,7100LC,7200" (const (symbol_ref "pa_cpu_attr")))
+(define_attr "cpu" "700,7100,7100LC,7200,8000" (const (symbol_ref "pa_cpu_attr")))
;; Length (in # of insns).
(define_attr "length" ""
@@ -350,6 +350,56 @@
;; treat it just like the 7100LC pipeline.
;; Similarly for the multi-issue fake units.
+;;
+;; Scheduling for the PA8000 is somewhat different than scheduling for a
+;; traditional architecture.
+;;
+;; The PA8000 has a large (56) entry reorder buffer that is split between
+;; memory and non-memory operations.
+;;
+;; The PA800 can issue two memory and two non-memory operations per cycle to
+;; the function units. Similarly, the PA8000 can retire two memory and two
+;; non-memory operations per cycle.
+;;
+;; Given the large reorder buffer, the processor can hide most latencies.
+;; According to HP, they've got the best results by scheduling for retirement
+;; bandwidth with limited latency scheduling for floating point operations.
+;; Latency for integer operations and memory references is ignored.
+;;
+;; We claim floating point operations have a 2 cycle latency and are
+;; fully pipelined, except for div and sqrt which are not pipelined.
+;;
+;; It is not necessary to define the shifter and integer alu units.
+;;
+;; These first two define_unit_unit descriptions model retirement from
+;; the reorder buffer.
+(define_function_unit "pa8000lsu" 2 1
+ (and
+ (eq_attr "type" "load,fpload,store,fpstore")
+ (eq_attr "cpu" "8000")) 1 1)
+
+(define_function_unit "pa8000alu" 2 1
+ (and
+ (eq_attr "type" "!load,fpload,store,fpstore")
+ (eq_attr "cpu" "8000")) 1 1)
+
+;; Claim floating point ops have a 2 cycle latency, excluding div and
+;; sqrt, which are not pipelined and issue to different units.
+(define_function_unit "pa8000fmac" 2 0
+ (and
+ (eq_attr "type" "fpcc,fpalu,fpmulsgl,fpmuldbl")
+ (eq_attr "cpu" "8000")) 2 1)
+
+(define_function_unit "pa8000fdiv" 2 1
+ (and
+ (eq_attr "type" "fpdivsgl,fpsqrtsgl")
+ (eq_attr "cpu" "8000")) 17 17)
+
+(define_function_unit "pa8000fdiv" 2 1
+ (and
+ (eq_attr "type" "fpdivdbl,fpsqrtdbl")
+ (eq_attr "cpu" "8000")) 31 31)
+
;; Compare instructions.
;; This controls RTL generation and register allocation.
@@ -1031,7 +1081,7 @@
[(set (pc)
(if_then_else
(match_operator 3 "comparison_operator"
- [(match_operand:SI 1 "register_operand" "r")
+ [(match_operand:SI 1 "reg_or_0_operand" "rM")
(match_operand:SI 2 "arith5_operand" "rL")])
(label_ref (match_operand 0 "" ""))
(pc)))]
@@ -1059,7 +1109,7 @@
[(set (pc)
(if_then_else
(match_operator 3 "comparison_operator"
- [(match_operand:SI 1 "register_operand" "r")
+ [(match_operand:SI 1 "reg_or_0_operand" "rM")
(match_operand:SI 2 "arith5_operand" "rL")])
(pc)
(label_ref (match_operand 0 "" ""))))]
@@ -3649,6 +3699,45 @@
[(set_attr "type" "multi")
(set_attr "length" "8")])
+;; This anonymous pattern and splitter wins because it reduces the latency
+;; of the shadd sequence without increasing the latency of the shift.
+;;
+;; We want to make sure and split up the operations for the scheduler since
+;; these instructions can (and should) schedule independently.
+;;
+;; It would be clearer if combine used the same operator for both expressions,
+;; it's somewhat confusing to have a mult in ine operation and an ashift
+;; in the other.
+;;
+;; If this pattern is not split before register allocation, then we must expose
+;; the fact that operand 4 is set before operands 1, 2 and 3 have been read.
+(define_insn ""
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (plus:SI (mult:SI (match_operand:SI 2 "register_operand" "r")
+ (match_operand:SI 3 "shadd_operand" ""))
+ (match_operand:SI 1 "register_operand" "r")))
+ (set (match_operand:SI 4 "register_operand" "=&r")
+ (ashift:SI (match_dup 2)
+ (match_operand:SI 5 "const_int_operand" "i")))]
+ "INTVAL (operands[5]) == exact_log2 (INTVAL (operands[3]))"
+ "#"
+ [(set_attr "type" "binary")
+ (set_attr "length" "8")])
+
+(define_split
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (plus:SI (mult:SI (match_operand:SI 2 "register_operand" "r")
+ (match_operand:SI 3 "shadd_operand" ""))
+ (match_operand:SI 1 "register_operand" "r")))
+ (set (match_operand:SI 4 "register_operand" "=&r")
+ (ashift:SI (match_dup 2)
+ (match_operand:SI 5 "const_int_operand" "i")))]
+ "INTVAL (operands[5]) == exact_log2 (INTVAL (operands[3]))"
+ [(set (match_dup 4) (ashift:SI (match_dup 2) (match_dup 5)))
+ (set (match_dup 0) (plus:SI (mult:SI (match_dup 2) (match_dup 3))
+ (match_dup 1)))]
+ "")
+
(define_expand "ashlsi3"
[(set (match_operand:SI 0 "register_operand" "")
(ashift:SI (match_operand:SI 1 "lhs_lshift_operand" "")
@@ -3812,6 +3901,36 @@
[(set_attr "type" "shift")
(set_attr "length" "4")])
+(define_expand "rotlsi3"
+ [(set (match_operand:SI 0 "register_operand" "")
+ (rotate:SI (match_operand:SI 1 "register_operand" "")
+ (match_operand:SI 2 "arith32_operand" "")))]
+ ""
+ "
+{
+ if (GET_CODE (operands[2]) != CONST_INT)
+ {
+ rtx temp = gen_reg_rtx (SImode);
+ emit_insn (gen_subsi3 (temp, GEN_INT (32), operands[2]));
+ emit_insn (gen_rotrsi3 (operands[0], operands[1], temp));
+ DONE;
+ }
+ /* Else expand normally. */
+}")
+
+(define_insn ""
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (rotate:SI (match_operand:SI 1 "register_operand" "r")
+ (match_operand:SI 2 "const_int_operand" "n")))]
+ ""
+ "*
+{
+ operands[2] = GEN_INT ((32 - INTVAL (operands[2])) & 31);
+ return \"shd %1,%1,%2,%0\";
+}"
+ [(set_attr "type" "shift")
+ (set_attr "length" "4")])
+
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
(match_operator:SI 5 "plus_xor_ior_operator"
@@ -4111,7 +4230,7 @@
"*
{
output_arg_descriptor (insn);
- return output_call (insn, operands[0], gen_rtx_REG (SImode, 2));
+ return output_call (insn, operands[0]);
}"
[(set_attr "type" "call")
(set (attr "length")
@@ -4270,7 +4389,7 @@
"*
{
output_arg_descriptor (insn);
- return output_call (insn, operands[1], gen_rtx_REG (SImode, 2));
+ return output_call (insn, operands[1]);
}"
[(set_attr "type" "call")
(set (attr "length")
diff --git a/gcc/config/pa/pa1.h b/gcc/config/pa/pa1.h
index 418de750c02..5d89aa5aa01 100644
--- a/gcc/config/pa/pa1.h
+++ b/gcc/config/pa/pa1.h
@@ -19,8 +19,7 @@ along with GNU CC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-#define TARGET_DEFAULT 0x89 /* TARGET_SNAKE + TARGET_GAS
- + TARGET_JUMP_IN_DELAY */
+#define TARGET_DEFAULT (MASK_GAS | MASK_SNAKE | MASK_JUMP_IN_DELAY)
/* This is the same as pa.h, except that we generate snake code by
default. */
diff --git a/gcc/config/pdp11/2bsd.h b/gcc/config/pdp11/2bsd.h
index 3cc97dbace3..401df171900 100644
--- a/gcc/config/pdp11/2bsd.h
+++ b/gcc/config/pdp11/2bsd.h
@@ -16,7 +16,8 @@ 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
/* This macro generates the assembly code for function entry. */
#undef FUNCTION_PROLOGUE
diff --git a/gcc/config/pdp11/pdp11.c b/gcc/config/pdp11/pdp11.c
index c040c457222..9bf69dd00b5 100644
--- a/gcc/config/pdp11/pdp11.c
+++ b/gcc/config/pdp11/pdp11.c
@@ -1115,7 +1115,7 @@ output_block_move(operands)
char buf[200];
if (GET_CODE(operands[2]) == CONST_INT
- && TARGET_TIME)
+ && ! optimize_size)
{
if (INTVAL(operands[2]) < 16
&& INTVAL(operands[3]) == 1)
@@ -1257,7 +1257,7 @@ output_block_move(operands)
bgt x
*/
- if (TARGET_SPACE)
+ if (optimize_size)
goto generate_compact_code;
output_asm_insn("asr %4", operands);
@@ -1308,7 +1308,7 @@ output_block_move(operands)
*/
- if (TARGET_SPACE)
+ if (optimize_size)
goto generate_compact_code;
output_asm_insn("asr %4", operands);
diff --git a/gcc/config/pdp11/pdp11.h b/gcc/config/pdp11/pdp11.h
index 55f9993e812..7912beaa151 100644
--- a/gcc/config/pdp11/pdp11.h
+++ b/gcc/config/pdp11/pdp11.h
@@ -89,9 +89,6 @@ extern int target_flags;
/* this is just to play around and check what code gcc generates */ \
{ "branch-expensive", 256}, \
{ "branch-cheap", -256}, \
-/* optimize for space instead of time - just in a couple of places */ \
- { "space", 512 }, \
- { "time", -512 }, \
/* split instruction and data memory? */ \
{ "split", 1024 }, \
{ "no-split", -1024 }, \
@@ -108,7 +105,7 @@ extern int target_flags;
#define TARGET_NO_AC0 (! TARGET_AC0)
#define TARGET_45 (target_flags & 8)
-#define TARGET_40_PLUS ((target_flags & 4) || (target_flags))
+#define TARGET_40_PLUS ((target_flags & 4) || (target_flags & 8))
#define TARGET_10 (! TARGET_40_PLUS)
#define TARGET_BCOPY_BUILTIN (! (target_flags & 16))
@@ -124,9 +121,6 @@ extern int target_flags;
#define TARGET_BRANCH_EXPENSIVE (target_flags & 256)
#define TARGET_BRANCH_CHEAP (!TARGET_BRANCH_EXPENSIVE)
-#define TARGET_SPACE (target_flags & 512)
-#define TARGET_TIME (! TARGET_SPACE)
-
#define TARGET_SPLIT (target_flags & 1024)
#define TARGET_NOSPLIT (! TARGET_SPLIT)
@@ -687,11 +681,11 @@ extern int current_function_pretend_args_size;
/* Addressing modes, and classification of registers for them. */
-#define HAVE_POST_INCREMENT
-/* #define HAVE_POST_DECREMENT */
+#define HAVE_POST_INCREMENT 1
+/* #define HAVE_POST_DECREMENT 0 */
-#define HAVE_PRE_DECREMENT
-/* #define HAVE_PRE_INCREMENT */
+#define HAVE_PRE_DECREMENT 1
+/* #define HAVE_PRE_INCREMENT 0 */
/* Macros to check register numbers against specific register classes. */
@@ -1315,31 +1309,31 @@ JMP FUNCTION 0x0058 0x0000 <- FUNCTION
there is something wrong in MULT because MULT is not
as cheap as total = 2 even if we can shift!
- if TARGET_SPACE make mult etc cheap, but not 1, so when
+ if optimizing for size make mult etc cheap, but not 1, so when
in doubt the faster insn is chosen.
*/
#define RTX_COSTS(X,CODE,OUTER_CODE) \
case MULT: \
- if (TARGET_SPACE) \
+ if (optimize_size) \
total = COSTS_N_INSNS(2); \
else \
total = COSTS_N_INSNS (11); \
break; \
case DIV: \
- if (TARGET_SPACE) \
+ if (optimize_size) \
total = COSTS_N_INSNS(2); \
else \
total = COSTS_N_INSNS (25); \
break; \
case MOD: \
- if (TARGET_SPACE) \
+ if (optimize_size) \
total = COSTS_N_INSNS(2); \
else \
total = COSTS_N_INSNS (26); \
break; \
case ABS: \
- /* equivalent to length, so same for TARGET_SPACE */ \
+ /* equivalent to length, so same for optimize_size */ \
total = COSTS_N_INSNS (3); \
break; \
case ZERO_EXTEND: \
@@ -1358,7 +1352,7 @@ JMP FUNCTION 0x0058 0x0000 <- FUNCTION
case ASHIFT: \
case LSHIFTRT: \
case ASHIFTRT: \
- if (TARGET_SPACE) \
+ if (optimize_size) \
total = COSTS_N_INSNS(1); \
else if (GET_MODE(X) == QImode) \
{ \
diff --git a/gcc/config/pdp11/pdp11.md b/gcc/config/pdp11/pdp11.md
index f93d1ce0aed..621b8743e89 100644
--- a/gcc/config/pdp11/pdp11.md
+++ b/gcc/config/pdp11/pdp11.md
@@ -16,7 +16,8 @@
;; 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, 675 Mass Ave, Cambridge, MA 02139, USA.
+;; the Free Software Foundation, 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
;; HI is 16 bit
@@ -778,7 +779,7 @@
(define_insn "extendsfdf2"
[(set (match_operand:DF 0 "register_operand" "=a,a,a")
- (float_extend:SF (match_operand:SF 1 "general_operand" "r,R,Q")))]
+ (float_extend:DF (match_operand:SF 1 "general_operand" "r,R,Q")))]
"TARGET_FPU"
"@
mov %1, -(sp)\;ldcfd (sp)+,%0
@@ -1432,7 +1433,7 @@
[(set (match_operand:HI 0 "general_operand" "=r")
(ashift:HI (match_operand:HI 1 "general_operand" "0")
(match_operand:HI 2 "expand_shift_operand" "O")))]
- "TARGET_TIME"
+ "! optimize_size"
"*
{
register int i;
diff --git a/gcc/config/ptx4.h b/gcc/config/ptx4.h
index aa31924032f..b1eaabeb4cc 100644
--- a/gcc/config/ptx4.h
+++ b/gcc/config/ptx4.h
@@ -1,6 +1,6 @@
/* Operating system specific defines to be used when targeting GCC for some
generic System V Release 4 system.
- Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
Contributed by Ron Guilmette (rfg@monkeys.com).
Renamed and changed to suit Dynix/ptx v4 and later.
Modified by Tim Wright (timw@sequent.com).
@@ -183,8 +183,9 @@ Boston, MA 02111-1307, USA.
#define ASM_FILE_END(FILE) \
do { \
- fprintf ((FILE), "\t%s\t\"GCC: (GNU) %s\"\n", \
- IDENT_ASM_OP, version_string); \
+ if (!flag_no_ident) \
+ fprintf ((FILE), "\t%s\t\"GCC: (GNU) %s\"\n", \
+ IDENT_ASM_OP, version_string); \
} while (0)
/* Allow #sccs in preprocessor. */
diff --git a/gcc/config/pyr/pyr.h b/gcc/config/pyr/pyr.h
index 42d55c0b84b..e5ffcb8361d 100644
--- a/gcc/config/pyr/pyr.h
+++ b/gcc/config/pyr/pyr.h
@@ -803,11 +803,11 @@ extern int current_function_calls_alloca;
/*** Addressing modes, and classification of registers for them. ***/
-/* #define HAVE_POST_INCREMENT */ /* pyramid has none of these */
-/* #define HAVE_POST_DECREMENT */
+/* #define HAVE_POST_INCREMENT 0 */ /* pyramid has none of these */
+/* #define HAVE_POST_DECREMENT 0 */
-/* #define HAVE_PRE_DECREMENT */
-/* #define HAVE_PRE_INCREMENT */
+/* #define HAVE_PRE_DECREMENT 0 */
+/* #define HAVE_PRE_INCREMENT 0 */
/* Macros to check register numbers against specific register classes. */
diff --git a/gcc/config/romp/romp.h b/gcc/config/romp/romp.h
index 0add9ee2467..82a0186a66c 100644
--- a/gcc/config/romp/romp.h
+++ b/gcc/config/romp/romp.h
@@ -905,11 +905,11 @@ struct rt_cargs {int gregs, fregs; };
/* Addressing modes, and classification of registers for them. */
-/* #define HAVE_POST_INCREMENT */
-/* #define HAVE_POST_DECREMENT */
+/* #define HAVE_POST_INCREMENT 0 */
+/* #define HAVE_POST_DECREMENT 0 */
-/* #define HAVE_PRE_DECREMENT */
-/* #define HAVE_PRE_INCREMENT */
+/* #define HAVE_PRE_DECREMENT 0 */
+/* #define HAVE_PRE_INCREMENT 0 */
/* Macros to check register numbers against specific register classes. */
@@ -1078,7 +1078,7 @@ struct rt_cargs {int gregs, fregs; };
force_operand \
(gen_rtx (PLUS, SImode, XEXP (X, 0), \
GEN_INT (high_int << 16)), 0),\
- GEN_INT (, low_int)); \
+ GEN_INT (low_int)); \
} \
}
diff --git a/gcc/config/romp/romp.md b/gcc/config/romp/romp.md
index 3abd56b7dab..5f0631521e3 100644
--- a/gcc/config/romp/romp.md
+++ b/gcc/config/romp/romp.md
@@ -1,5 +1,5 @@
;;- Machine description for ROMP chip for GNU C compiler
-;; Copyright (C) 1988, 1991, 1993, 1994, 1995 Free Software Foundation, Inc.
+;; Copyright (C) 1988, 91, 93, 94, 95, 1999 Free Software Foundation, Inc.
;; Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
;; This file is part of GNU CC.
@@ -651,7 +651,7 @@
start_sequence ();
if (GET_CODE (operands[0]) != REG
|| ! refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
- operands[1]), 0)
+ operands[1], 0))
{
emit_move_insn (operand_subword (op0, 0, 1, DFmode),
operand_subword_force (op1, 0, DFmode));
diff --git a/gcc/config/rs6000/cygwin32.h b/gcc/config/rs6000/cygwin32.h
deleted file mode 100644
index f527736a020..00000000000
--- a/gcc/config/rs6000/cygwin32.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/* Operating system specific defines to be used when targeting GCC for
- hosting on Windows NT 3.x, using the Cygnus API
-
- This is different to the winnt.h file, since that is used
- to build GCC for use with a windows style library and tool
- set, winnt.h uses the Microsoft tools to do that.
-
- Copyright (C) 1996, 1997 Free Software Foundation, Inc.
-
-This file is part of GNU CC.
-
-GNU CC is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
-
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
-
-
-/* Ugly hack */
-#include "rs6000/win-nt.h"
-
-
-#ifdef CPP_PREDEFINES
-#undef CPP_PREDEFINES
-#endif
-
-#define CPP_PREDEFINES "-D_WIN32 -DWINNT -D__CYGWIN32__ -DPOSIX \
- -D_POWER -D_ARCH_PPC -D__PPC__ -Asystem(winnt) -Acpu(powerpc) -Amachine(powerpc)"
-
-#undef CPP_SPEC
-#define CPP_SPEC "-remap %{posix: -D_POSIX_SOURCE} %(cpp_cpu)"
-
-/* We have to dynamic link to get to the system DLLs. All of libc, libm and
- the Unix stuff is in cygwin.dll. The import library is called
- 'libcygwin.a'. For Windows applications, include more libraries, but
- always include kernel32. We'd like to specific subsystem windows to
- ld, but that doesn't work just yet. */
-
-#undef LIB_SPEC
-#define LIB_SPEC "-lcygwin %{mwindows:-luser32 -lgdi32 -lcomdlg32} -lkernel32"
-
-#undef LINK_SPEC
-#define LINK_SPEC "%{v:-V}"
-
-#undef STARTFILE_SPEC
-#define STARTFILE_SPEC "crti%O%s crt0%O%s"
-
-#undef ENDFILE_SPEC
-#define ENDFILE_SPEC "crtn%O%s"
-
-#define PTRDIFF_TYPE "int"
-#define WCHAR_UNSIGNED 1
-#define WCHAR_TYPE_SIZE 16
-#define WCHAR_TYPE "short unsigned int"
-
-#define DBX_DEBUGGING_INFO
-#undef SDB_DEBUGGING_INFO
-#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG
diff --git a/gcc/config/rs6000/eabile.h b/gcc/config/rs6000/eabile.h
index 78dc7bc89c4..97e2b7c6e85 100644
--- a/gcc/config/rs6000/eabile.h
+++ b/gcc/config/rs6000/eabile.h
@@ -28,6 +28,9 @@ Boston, MA 02111-1307, USA. */
#undef CPP_ENDIAN_DEFAULT_SPEC
#define CPP_ENDIAN_DEFAULT_SPEC "%(cpp_endian_little)"
+#undef CC1_ENDIAN_DEFAULT_SPEC
+#define CC1_ENDIAN_DEFAULT_SPEC "%(cc1_endian_little)"
+
#undef LINK_TARGET_SPEC
#define LINK_TARGET_SPEC "\
%{mbig: -oformat elf32-powerpc } %{mbig-endian: -oformat elf32-powerpc } \
diff --git a/gcc/config/rs6000/linux.h b/gcc/config/rs6000/linux.h
index 19f939f7a69..7b3571f7561 100644
--- a/gcc/config/rs6000/linux.h
+++ b/gcc/config/rs6000/linux.h
@@ -1,6 +1,6 @@
/* Definitions of target machine for GNU compiler,
for IBM RS/6000 running AIX version 3.1.
- Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
Contributed by Michael Meissner (meissner@cygnus.com).
This file is part of GNU CC.
@@ -17,7 +17,8 @@ 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
#include "rs6000/sysv4.h"
@@ -45,12 +46,6 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#undef ENDFILE_DEFAULT_SPEC
#define ENDFILE_DEFAULT_SPEC "%(endfile_linux)"
-#undef LINK_START_DEFAULT_SPEC
-#define LINK_START_DEFAULT_SPEC "%(link_start_linux)"
-
-#undef LINK_OS_DEFAULT_SPEC
-#define LINK_OS_DEFAULT_SPEC "%(link_os_linux)"
-
#undef TARGET_VERSION
#define TARGET_VERSION fprintf (stderr, " (PowerPC GNU/Linux)");
diff --git a/gcc/config/rs6000/netware.h b/gcc/config/rs6000/netware.h
index a465c63fe3b..61133b9b1ee 100644
--- a/gcc/config/rs6000/netware.h
+++ b/gcc/config/rs6000/netware.h
@@ -17,7 +17,8 @@ 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
#define TARGET_AIX 0
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index b1b36fe423e..a59425dae73 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -1,5 +1,5 @@
/* Subroutines used for code generation on IBM RS/6000.
- Copyright (C) 1991, 93-7, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1991, 93-8, 1999 Free Software Foundation, Inc.
Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
This file is part of GNU CC.
@@ -54,10 +54,10 @@ extern int profile_block_flag;
enum processor_type rs6000_cpu;
struct rs6000_cpu_select rs6000_select[3] =
{
- /* switch name, tune arch */
- { (char *)0, "--with-cpu=", 1, 1 },
- { (char *)0, "-mcpu=", 1, 1 },
- { (char *)0, "-mtune=", 1, 0 },
+ /* switch name, tune arch */
+ { (const char *)0, "--with-cpu=", 1, 1 },
+ { (const char *)0, "-mcpu=", 1, 1 },
+ { (const char *)0, "-mtune=", 1, 0 },
};
/* Set to non-zero by "fix" operation to indicate that itrunc and
@@ -84,13 +84,13 @@ int rs6000_pic_labelno;
int rs6000_pic_func_labelno;
/* Which abi to adhere to */
-char *rs6000_abi_name = RS6000_ABI_NAME;
+const char *rs6000_abi_name = RS6000_ABI_NAME;
/* Semantics of the small data area */
enum rs6000_sdata_type rs6000_sdata = SDATA_DATA;
/* Which small data model to use */
-char *rs6000_sdata_name = (char *)0;
+const char *rs6000_sdata_name = (char *)0;
#endif
/* Whether a System V.4 varargs area was created. */
@@ -105,7 +105,7 @@ int rs6000_fpmem_offset;
int rs6000_fpmem_size;
/* Debug flags */
-char *rs6000_debug_name;
+const char *rs6000_debug_name;
int rs6000_debug_stack; /* debug stack applications */
int rs6000_debug_arg; /* debug argument handling */
@@ -234,6 +234,12 @@ rs6000_override_options (default_cpu)
{"620", PROCESSOR_PPC620,
MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
POWER_MASKS | MASK_PPC_GPOPT},
+ {"740", PROCESSOR_PPC750,
+ MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
+ POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
+ {"750", PROCESSOR_PPC750,
+ MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
+ POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
{"801", PROCESSOR_MPCCORE,
MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS,
POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
@@ -297,9 +303,12 @@ rs6000_override_options (default_cpu)
if (TARGET_STRING_SET)
target_flags = (target_flags & ~MASK_STRING) | string;
- /* Don't allow -mmultiple or -mstring on little endian systems, because the
- hardware doesn't support the instructions used in little endian mode */
- if (!BYTES_BIG_ENDIAN)
+ /* Don't allow -mmultiple or -mstring on little endian systems unless the cpu
+ is a 750, because the hardware doesn't support the instructions used in
+ little endian mode, and causes an alignment trap. The 750 does not cause
+ an alignment trap (except when the target is unaligned). */
+
+ if (!BYTES_BIG_ENDIAN && rs6000_cpu != PROCESSOR_PPC750)
{
if (TARGET_MULTIPLE)
{
@@ -353,7 +362,7 @@ optimization_options (level, size)
int level;
int size ATTRIBUTE_UNUSED;
{
-#ifdef HAIFA
+#ifdef HAVE_decrement_and_branch_on_count
/* When optimizing, enable use of BCT instruction. */
if (level >= 1)
flag_branch_on_count_reg = 1;
@@ -497,8 +506,7 @@ short_cint_operand (op, mode)
enum machine_mode mode ATTRIBUTE_UNUSED;
{
return ((GET_CODE (op) == CONST_INT
- && (unsigned HOST_WIDE_INT) (INTVAL (op) + 0x8000) < 0x10000)
- || GET_CODE (op) == CONSTANT_P_RTX);
+ && (unsigned HOST_WIDE_INT) (INTVAL (op) + 0x8000) < 0x10000));
}
/* Similar for a unsigned D field. */
@@ -508,9 +516,8 @@ u_short_cint_operand (op, mode)
register rtx op;
enum machine_mode mode ATTRIBUTE_UNUSED;
{
- return ((GET_CODE (op) == CONST_INT
- && (INTVAL (op) & (~ (HOST_WIDE_INT) 0xffff)) == 0)
- || GET_CODE (op) == CONSTANT_P_RTX);
+ return (GET_CODE (op) == CONST_INT
+ && (INTVAL (op) & (~ (HOST_WIDE_INT) 0xffff)) == 0);
}
/* Return 1 if OP is a CONST_INT that cannot fit in a signed D field. */
@@ -552,6 +559,20 @@ cc_reg_operand (op, mode)
|| CR_REGNO_P (REGNO (op))));
}
+/* Returns 1 if OP is either a pseudo-register or a register denoting a
+ CR field that isn't CR0. */
+
+int
+cc_reg_not_cr0_operand (op, mode)
+ register rtx op;
+ enum machine_mode mode;
+{
+ return (register_operand (op, mode)
+ && (GET_CODE (op) != REG
+ || REGNO (op) >= FIRST_PSEUDO_REGISTER
+ || CR_REGNO_NOT_CR0_P (REGNO (op))));
+}
+
/* Returns 1 if OP is either a constant integer valid for a D-field or a
non-special register. If a register, it must be in the proper mode unless
MODE is VOIDmode. */
@@ -598,7 +619,6 @@ reg_or_cint_operand (op, mode)
enum machine_mode mode;
{
return (GET_CODE (op) == CONST_INT
- || GET_CODE (op) == CONSTANT_P_RTX
|| gpc_reg_operand (op, mode));
}
@@ -826,15 +846,16 @@ volatile_mem_operand (op, mode)
return memory_address_p (mode, XEXP (op, 0));
}
-/* Return 1 if the operand is an offsettable memory address. */
+/* Return 1 if the operand is an offsettable memory operand. */
int
-offsettable_addr_operand (op, mode)
+offsettable_mem_operand (op, mode)
register rtx op;
enum machine_mode mode;
{
- return offsettable_address_p (reload_completed | reload_in_progress,
- mode, op);
+ return ((GET_CODE (op) == MEM)
+ && offsettable_address_p (reload_completed | reload_in_progress,
+ mode, XEXP (op, 0)));
}
/* Return 1 if the operand is either an easy FP constant (see above) or
@@ -857,7 +878,8 @@ add_operand (op, mode)
enum machine_mode mode;
{
return (reg_or_short_operand (op, mode)
- || (GET_CODE (op) == CONST_INT && (INTVAL (op) & 0xffff) == 0));
+ || (GET_CODE (op) == CONST_INT
+ && (INTVAL (op) & (~ (HOST_WIDE_INT) 0xffff0000)) == 0));
}
/* Return 1 if OP is a constant but not a valid add_operand. */
@@ -869,7 +891,7 @@ non_add_cint_operand (op, mode)
{
return (GET_CODE (op) == CONST_INT
&& (unsigned HOST_WIDE_INT) (INTVAL (op) + 0x8000) >= 0x10000
- && (INTVAL (op) & 0xffff) != 0);
+ && (INTVAL (op) & (~ (HOST_WIDE_INT) 0xffff0000)) != 0);
}
/* Return 1 if the operand is a non-special register or a constant that
@@ -883,8 +905,7 @@ logical_operand (op, mode)
return (gpc_reg_operand (op, mode)
|| (GET_CODE (op) == CONST_INT
&& ((INTVAL (op) & (~ (HOST_WIDE_INT) 0xffff)) == 0
- || (INTVAL (op) & 0xffff) == 0))
- || GET_CODE (op) == CONSTANT_P_RTX);
+ || (INTVAL (op) & (~ (HOST_WIDE_INT) 0xffff0000)) == 0)));
}
/* Return 1 if C is a constant that is not a logical operand (as
@@ -897,7 +918,7 @@ non_logical_cint_operand (op, mode)
{
return (GET_CODE (op) == CONST_INT
&& (INTVAL (op) & (~ (HOST_WIDE_INT) 0xffff)) != 0
- && (INTVAL (op) & 0xffff) != 0);
+ && (INTVAL (op) & (~ (HOST_WIDE_INT) 0xffff0000)) != 0);
}
/* Return 1 if C is a constant that can be encoded in a mask on the
@@ -1020,8 +1041,10 @@ and64_operand (op, mode)
register rtx op;
enum machine_mode mode;
{
- return (logical_operand (op, mode)
- || mask64_operand (op, mode));
+ if (fixed_regs[68]) /* CR0 not available, don't do andi./andis. */
+ return (gpc_reg_operand (op, mode) || mask64_operand (op, mode));
+
+ return (logical_operand (op, mode) || mask64_operand (op, mode));
}
/* Return 1 if the operand is either a non-special register or a
@@ -1032,8 +1055,10 @@ and_operand (op, mode)
register rtx op;
enum machine_mode mode;
{
- return (logical_operand (op, mode)
- || mask_operand (op, mode));
+ if (fixed_regs[68]) /* CR0 not available, don't do andi./andis. */
+ return (gpc_reg_operand (op, mode) || mask_operand (op, mode));
+
+ return (logical_operand (op, mode) || mask_operand (op, mode));
}
/* Return 1 if the operand is a general register or memory operand. */
@@ -1110,6 +1135,10 @@ input_operand (op, mode)
if (memory_operand (op, mode))
return 1;
+ /* Only a tiny bit of handling for CONSTANT_P_RTX is necessary. */
+ if (GET_CODE (op) == CONSTANT_P_RTX)
+ return 1;
+
/* For floating-point, easy constants are valid. */
if (GET_MODE_CLASS (mode) == MODE_FLOAT
&& CONSTANT_P (op)
@@ -1119,7 +1148,6 @@ input_operand (op, mode)
/* Allow any integer constant. */
if (GET_MODE_CLASS (mode) == MODE_INT
&& (GET_CODE (op) == CONST_INT
- || GET_CODE (op) == CONSTANT_P_RTX
|| GET_CODE (op) == CONST_DOUBLE))
return 1;
@@ -1159,13 +1187,8 @@ input_operand (op, mode)
int
small_data_operand (op, mode)
-#if TARGET_ELF
- rtx op;
- enum machine_mode mode;
-#else
rtx op ATTRIBUTE_UNUSED;
enum machine_mode mode ATTRIBUTE_UNUSED;
-#endif
{
#if TARGET_ELF
rtx sym_ref, const_part;
@@ -1702,8 +1725,7 @@ expand_block_move_mem (mode, addr, orig_mem)
rtx mem = gen_rtx_MEM (mode, addr);
RTX_UNCHANGING_P (mem) = RTX_UNCHANGING_P (orig_mem);
- MEM_VOLATILE_P (mem) = MEM_VOLATILE_P (orig_mem);
- MEM_IN_STRUCT_P (mem) = MEM_IN_STRUCT_P (orig_mem);
+ MEM_COPY_ATTRIBUTES (mem, orig_mem);
#ifdef MEM_UNALIGNED_P
MEM_UNALIGNED_P (mem) = MEM_UNALIGNED_P (orig_mem);
#endif
@@ -2752,15 +2774,15 @@ print_operand (file, x, code)
/* If the high bit is set and the low bit is not, the value is zero.
If the high bit is zero, the value is the first 1 bit we find from
the left. */
- if (val < 0 && (val & 1) == 0)
+ if ((val & 0x80000000) && ((val & 1) == 0))
{
putc ('0', file);
return;
}
- else if (val >= 0)
+ else if ((val & 0x80000000) == 0)
{
for (i = 1; i < 32; i++)
- if ((val <<= 1) < 0)
+ if ((val <<= 1) & 0x80000000)
break;
fprintf (file, "%d", i);
return;
@@ -2787,7 +2809,7 @@ print_operand (file, x, code)
/* If the low bit is set and the high bit is not, the value is 31.
If the low bit is zero, the value is the first 1 bit we find from
the right. */
- if ((val & 1) && val >= 0)
+ if ((val & 1) && ((val & 0x80000000) == 0))
{
fputs ("31", file);
return;
@@ -2807,7 +2829,7 @@ print_operand (file, x, code)
/* Otherwise, look for the first 0 bit from the left. The result is its
number minus 1. We know the high-order bit is one. */
for (i = 0; i < 32; i++)
- if ((val <<= 1) >= 0)
+ if (((val <<= 1) & 0x80000000) == 0)
break;
fprintf (file, "%d", i);
@@ -3207,14 +3229,46 @@ first_reg_to_save ()
if (regs_ever_live[first_reg])
break;
- /* If profiling, then we must save/restore every register that contains
- a parameter before/after the .__mcount call. Use registers from 30 down
- to 23 to do this. Don't use the frame pointer in reg 31.
+ if (profile_flag)
+ {
+ /* AIX must save/restore every register that contains a parameter
+ before/after the .__mcount call plus an additional register
+ for the static chain, if needed; use registers from 30 down to 22
+ to do this. */
+ if (DEFAULT_ABI == ABI_AIX)
+ {
+ int last_parm_reg, profile_first_reg;
+
+ /* Figure out last used parameter register. The proper thing
+ to do is to walk incoming args of the function. A function
+ might have live parameter registers even if it has no
+ incoming args. */
+ for (last_parm_reg = 10;
+ last_parm_reg > 2 && ! regs_ever_live [last_parm_reg];
+ last_parm_reg--)
+ ;
+
+ /* Calculate first reg for saving parameter registers
+ and static chain.
+ Skip reg 31 which may contain the frame pointer. */
+ profile_first_reg = (33 - last_parm_reg
+ - (current_function_needs_context ? 1 : 0));
+ /* Do not save frame pointer if no parameters needs to be saved. */
+ if (profile_first_reg == 31)
+ profile_first_reg = 32;
+
+ if (first_reg > profile_first_reg)
+ first_reg = profile_first_reg;
+ }
- For now, save enough room for all of the parameter registers. */
- if (DEFAULT_ABI == ABI_AIX && profile_flag)
- if (first_reg > 23)
- first_reg = 23;
+ /* SVR4 may need one register to preserve the static chain. */
+ else if (current_function_needs_context)
+ {
+ /* Skip reg 31 which may contain the frame pointer. */
+ if (first_reg > 30)
+ first_reg = 30;
+ }
+ }
return first_reg;
}
@@ -3453,7 +3507,6 @@ rs6000_stack_info ()
}
}
-
/* Determine if we need to save the link register */
if (regs_ever_live[65]
|| (DEFAULT_ABI == ABI_AIX && profile_flag)
@@ -3480,13 +3533,6 @@ rs6000_stack_info ()
info_ptr->cr_size = reg_size;
}
- /* Ensure that fp_save_offset will be aligned to an 8-byte boundary. */
- if (info_ptr->fpmem_p)
- {
- info_ptr->gp_size = RS6000_ALIGN (info_ptr->gp_size, 8);
- info_ptr->main_size = RS6000_ALIGN (info_ptr->main_size, 8);
- }
-
/* Determine various sizes */
info_ptr->reg_size = reg_size;
info_ptr->fixed_size = RS6000_SAVE_AREA;
@@ -3501,40 +3547,6 @@ rs6000_stack_info ()
+ info_ptr->toc_size
+ info_ptr->main_size, 8);
- total_raw_size = (info_ptr->vars_size
- + info_ptr->parm_size
- + info_ptr->fpmem_size
- + info_ptr->save_size
- + info_ptr->varargs_size
- + info_ptr->fixed_size);
-
- info_ptr->total_size = RS6000_ALIGN (total_raw_size, ABI_STACK_BOUNDARY / BITS_PER_UNIT);
-
- /* Determine if we need to allocate any stack frame:
-
- For AIX we need to push the stack if a frame pointer is needed (because
- the stack might be dynamically adjusted), if we are debugging, if we
- make calls, or if the sum of fp_save, gp_save, fpmem, and local variables
- are more than the space needed to save all non-volatile registers:
- 32-bit: 18*8 + 19*4 = 220 or 64-bit: 18*8 + 19*8 = 296
-
- For V.4 we don't have the stack cushion that AIX uses, but assume that
- the debugger can handle stackless frames. */
-
- if (info_ptr->calls_p)
- info_ptr->push_p = 1;
-
- else if (abi == ABI_V4 || abi == ABI_NT || abi == ABI_SOLARIS)
- info_ptr->push_p = (total_raw_size > info_ptr->fixed_size
- || (abi == ABI_NT ? info_ptr->lr_save_p
- : info_ptr->calls_p));
-
- else
- info_ptr->push_p = (frame_pointer_needed
- || write_symbols != NO_DEBUG
- || ((total_raw_size - info_ptr->fixed_size)
- > (TARGET_32BIT ? 220 : 296)));
-
/* Calculate the offsets */
switch (abi)
{
@@ -3574,6 +3586,45 @@ rs6000_stack_info ()
break;
}
+ /* Ensure that fpmem_offset will be aligned to an 8-byte boundary. */
+ if (info_ptr->fpmem_p
+ && (info_ptr->main_save_offset - info_ptr->fpmem_size) % 8)
+ info_ptr->fpmem_size += reg_size;
+
+ total_raw_size = (info_ptr->vars_size
+ + info_ptr->parm_size
+ + info_ptr->fpmem_size
+ + info_ptr->save_size
+ + info_ptr->varargs_size
+ + info_ptr->fixed_size);
+
+ info_ptr->total_size = RS6000_ALIGN (total_raw_size, ABI_STACK_BOUNDARY / BITS_PER_UNIT);
+
+ /* Determine if we need to allocate any stack frame:
+
+ For AIX we need to push the stack if a frame pointer is needed (because
+ the stack might be dynamically adjusted), if we are debugging, if we
+ make calls, or if the sum of fp_save, gp_save, fpmem, and local variables
+ are more than the space needed to save all non-volatile registers:
+ 32-bit: 18*8 + 19*4 = 220 or 64-bit: 18*8 + 19*8 = 296
+
+ For V.4 we don't have the stack cushion that AIX uses, but assume that
+ the debugger can handle stackless frames. */
+
+ if (info_ptr->calls_p)
+ info_ptr->push_p = 1;
+
+ else if (abi == ABI_V4 || abi == ABI_NT || abi == ABI_SOLARIS)
+ info_ptr->push_p = (total_raw_size > info_ptr->fixed_size
+ || (abi == ABI_NT ? info_ptr->lr_save_p
+ : info_ptr->calls_p));
+
+ else
+ info_ptr->push_p = (frame_pointer_needed
+ || write_symbols != NO_DEBUG
+ || ((total_raw_size - info_ptr->fixed_size)
+ > (TARGET_32BIT ? 220 : 296)));
+
if (info_ptr->fpmem_p)
{
info_ptr->fpmem_offset = info_ptr->main_save_offset - info_ptr->fpmem_size;
@@ -4479,7 +4530,7 @@ output_mi_thunk (file, thunk_fndecl, delta, function)
int delta;
tree function;
{
- char *this_reg = reg_names[ aggregate_value_p (TREE_TYPE (function)) ? 3 : 4 ];
+ char *this_reg = reg_names[ aggregate_value_p (TREE_TYPE (TREE_TYPE (function))) ? 4 : 3 ];
char *r0 = reg_names[0];
char *sp = reg_names[1];
char *toc = reg_names[2];
@@ -4564,7 +4615,7 @@ output_mi_thunk (file, thunk_fndecl, delta, function)
fprintf (file, "\n");
#else
- if (TREE_ASM_WRITTEN (function)
+ if (current_file_function_operand (XEXP (DECL_RTL (function), 0))
&& !lookup_attribute ("longcall", TYPE_ATTRIBUTES (TREE_TYPE (function))))
{
fprintf (file, "\tb %s", prefix);
@@ -5032,13 +5083,20 @@ output_function_profiler (file, labelno)
asm_fprintf (file, "\t{liu|lis} %s,", reg_names[12]);
assemble_name (file, buf);
fputs ("@ha\n", file);
- asm_fprintf (file, "\t{st|stw} %s,4(%s)\n", reg_names[0], reg_names[1]);
+ asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
+ reg_names[0], reg_names[1]);
asm_fprintf (file, "\t{cal|la} %s,", reg_names[0]);
assemble_name (file, buf);
asm_fprintf (file, "@l(%s)\n", reg_names[12]);
}
+ if (current_function_needs_context)
+ asm_fprintf (file, "\tmr %s,%s\n",
+ reg_names[30], reg_names[STATIC_CHAIN_REGNUM]);
fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
+ if (current_function_needs_context)
+ asm_fprintf (file, "\tmr %s,%s\n",
+ reg_names[STATIC_CHAIN_REGNUM], reg_names[30]);
break;
case ABI_AIX:
@@ -5070,11 +5128,13 @@ output_function_profiler (file, labelno)
last_parm_reg--)
;
- /* Save parameter registers in regs 23-30. Don't overwrite reg 31, since
- it might be set up as the frame pointer. */
+ /* Save parameter registers in regs 23-30 and static chain in r22.
+ Don't overwrite reg 31, since it might be set up as the frame pointer. */
for (i = 3, j = 30; i <= last_parm_reg; i++, j--)
asm_fprintf (file, "\tmr %d,%d\n", j, i);
+ if (current_function_needs_context)
+ asm_fprintf (file, "\tmr %d,%d\n", j, STATIC_CHAIN_REGNUM);
/* Load location address into r3, and call mcount. */
@@ -5085,10 +5145,13 @@ output_function_profiler (file, labelno)
asm_fprintf (file, "(%s)\n\tbl %s\n\t%s\n",
reg_names[2], RS6000_MCOUNT, RS6000_CALL_GLUE);
- /* Restore parameter registers. */
+ /* Restore parameter registers and static chain. */
for (i = 3, j = 30; i <= last_parm_reg; i++, j--)
asm_fprintf (file, "\tmr %d,%d\n", i, j);
+ if (current_function_needs_context)
+ asm_fprintf (file, "\tmr %d,%d\n", STATIC_CHAIN_REGNUM, j);
+
break;
}
}
@@ -5127,6 +5190,48 @@ rs6000_adjust_cost (insn, link, dep_insn, cost)
return cost;
}
+/* A C statement (sans semicolon) to update the integer scheduling priority
+ INSN_PRIORITY (INSN). Reduce the priority to execute the INSN earlier,
+ increase the priority to execute INSN later. Do not define this macro if
+ you do not need to adjust the scheduling priorities of insns. */
+
+int
+rs6000_adjust_priority (insn, priority)
+ rtx insn;
+ int priority;
+{
+ /* On machines (like the 750) which have asymetric integer units, where one
+ integer unit can do multiply and divides and the other can't, reduce the
+ priority of multiply/divide so it is scheduled before other integer
+ operationss. */
+
+#if 0
+ if (GET_RTX_CLASS (GET_CODE (insn)) != 'i')
+ return priority;
+
+ if (GET_CODE (PATTERN (insn)) == USE)
+ return priority;
+
+ switch (rs6000_cpu_attr) {
+ case CPU_PPC750:
+ switch (get_attr_type (insn))
+ {
+ default:
+ break;
+
+ case TYPE_IMUL:
+ case TYPE_IDIV:
+ fprintf (stderr, "priority was %#x (%d) before adjustment\n", priority, priority);
+ if (priority >= 0 && priority < 0x01000000)
+ priority >>= 3;
+ break;
+ }
+ }
+#endif
+
+ return priority;
+}
+
/* Return how many instructions the machine can issue per cycle */
int get_issue_rate()
{
@@ -5139,8 +5244,12 @@ int get_issue_rate()
return 3; /* ? */
case CPU_PPC603:
return 2;
+ case CPU_PPC750:
+ return 2;
case CPU_PPC604:
return 4;
+ case CPU_PPC604E:
+ return 4;
case CPU_PPC620:
return 4;
default:
@@ -5148,7 +5257,6 @@ int get_issue_rate()
}
}
-
/* Output assembler code for a block containing the constant parts
of a trampoline, leaving space for the variable parts.
diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h
index bbdcebb73b7..ad69576fd64 100644
--- a/gcc/config/rs6000/rs6000.h
+++ b/gcc/config/rs6000/rs6000.h
@@ -1,5 +1,5 @@
/* Definitions of target machine for GNU compiler, for IBM RS/6000.
- Copyright (C) 1992, 93-7, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1992, 93-8, 1999 Free Software Foundation, Inc.
Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
This file is part of GNU CC.
@@ -81,6 +81,9 @@ Boston, MA 02111-1307, USA. */
%{mcpu=604: -D_ARCH_PPC} \
%{mcpu=604e: -D_ARCH_PPC} \
%{mcpu=620: -D_ARCH_PPC} \
+%{mcpu=740: -D_ARCH_PPC} \
+%{mcpu=750: -D_ARCH_PPC} \
+%{mcpu=801: -D_ARCH_PPC} \
%{mcpu=821: -D_ARCH_PPC} \
%{mcpu=823: -D_ARCH_PPC} \
%{mcpu=860: -D_ARCH_PPC}"
@@ -134,6 +137,9 @@ Boston, MA 02111-1307, USA. */
%{mcpu=604: -mppc} \
%{mcpu=604e: -mppc} \
%{mcpu=620: -mppc} \
+%{mcpu=740: -mppc} \
+%{mcpu=750: -mppc} \
+%{mcpu=801: -mppc} \
%{mcpu=821: -mppc} \
%{mcpu=823: -mppc} \
%{mcpu=860: -mppc}"
@@ -391,15 +397,18 @@ extern int target_flags;
/* Processor type. Order must match cpu attribute in MD file. */
enum processor_type
- {PROCESSOR_RIOS1,
- PROCESSOR_RIOS2,
- PROCESSOR_MPCCORE,
- PROCESSOR_PPC403,
- PROCESSOR_PPC601,
- PROCESSOR_PPC603,
- PROCESSOR_PPC604,
- PROCESSOR_PPC604e,
- PROCESSOR_PPC620};
+ {
+ PROCESSOR_RIOS1,
+ PROCESSOR_RIOS2,
+ PROCESSOR_MPCCORE,
+ PROCESSOR_PPC403,
+ PROCESSOR_PPC601,
+ PROCESSOR_PPC603,
+ PROCESSOR_PPC604,
+ PROCESSOR_PPC604e,
+ PROCESSOR_PPC620,
+ PROCESSOR_PPC750
+};
extern enum processor_type rs6000_cpu;
@@ -452,8 +461,8 @@ extern enum processor_type rs6000_cpu;
/* rs6000_select[0] is reserved for the default cpu defined via --with-cpu */
struct rs6000_cpu_select
{
- char *string;
- char *name;
+ const char *string;
+ const char *name;
int set_tune_p;
int set_arch_p;
};
@@ -461,7 +470,7 @@ struct rs6000_cpu_select
extern struct rs6000_cpu_select rs6000_select[];
/* Debug support */
-extern char *rs6000_debug_name; /* Name for -mdebug-xxxx option */
+extern const char *rs6000_debug_name; /* Name for -mdebug-xxxx option */
extern int rs6000_debug_stack; /* debug stack applications */
extern int rs6000_debug_arg; /* debug argument handling */
@@ -756,6 +765,12 @@ extern int rs6000_debug_arg; /* debug argument handling */
/* True if register is a condition register. */
#define CR_REGNO_P(N) ((N) >= 68 && (N) <= 75)
+/* True if register is condition register 0. */
+#define CR0_REGNO_P(N) ((N) == 68)
+
+/* True if register is a condition register, but not cr0. */
+#define CR_REGNO_NOT_CR0_P(N) ((N) >= 69 && (N) <= 75)
+
/* True if register is an integer register. */
#define INT_REGNO_P(N) ((N) <= 31 || (N) == 67)
@@ -855,6 +870,14 @@ extern int rs6000_debug_arg; /* debug argument handling */
#define ADJUST_COST(INSN,LINK,DEP_INSN,COST) \
(COST) = rs6000_adjust_cost (INSN,LINK,DEP_INSN,COST)
+/* A C statement (sans semicolon) to update the integer scheduling priority
+ INSN_PRIORITY (INSN). Reduce the priority to execute the INSN earlier,
+ increase the priority to execute INSN later. Do not define this macro if
+ you do not need to adjust the scheduling priorities of insns. */
+
+#define ADJUST_PRIORITY(INSN) \
+ INSN_PRIORITY (INSN) = rs6000_adjust_priority (INSN, INSN_PRIORITY (INSN))
+
/* Define this macro to change register usage conditional on target flags.
Set MQ register fixed (already call_used) if not POWER architecture
(RIOS1, RIOS2, RSC, and PPC601) so that it will not be allocated.
@@ -1075,7 +1098,7 @@ enum reg_class
#define CONST_OK_FOR_LETTER_P(VALUE, C) \
( (C) == 'I' ? (unsigned HOST_WIDE_INT) ((VALUE) + 0x8000) < 0x10000 \
- : (C) == 'J' ? ((VALUE) & 0xffff) == 0 \
+ : (C) == 'J' ? ((VALUE) & (~ (HOST_WIDE_INT) 0xffff0000)) == 0 \
: (C) == 'K' ? ((VALUE) & (~ (HOST_WIDE_INT) 0xffff)) == 0 \
: (C) == 'L' ? mask_constant (VALUE) \
: (C) == 'M' ? (VALUE) > 31 \
@@ -1232,8 +1255,10 @@ typedef struct rs6000_stack {
/* Size of the fixed area on the stack */
#define RS6000_SAVE_AREA (TARGET_32BIT ? 24 : 48)
-/* Address to save the TOC register */
-#define RS6000_SAVE_TOC plus_constant (stack_pointer_rtx, (TARGET_32BIT ? 20 : 40))
+/* MEM representing address to save the TOC register */
+#define RS6000_SAVE_TOC gen_rtx_MEM (Pmode, \
+ plus_constant (stack_pointer_rtx, \
+ (TARGET_32BIT ? 20 : 40)))
/* Offset & size for fpmem stack locations used for converting between
float and integral types. */
@@ -1755,11 +1780,11 @@ typedef struct rs6000_args
/* Addressing modes, and classification of registers for them. */
-/* #define HAVE_POST_INCREMENT */
-/* #define HAVE_POST_DECREMENT */
+/* #define HAVE_POST_INCREMENT 0 */
+/* #define HAVE_POST_DECREMENT 0 */
-#define HAVE_PRE_DECREMENT
-#define HAVE_PRE_INCREMENT
+#define HAVE_PRE_DECREMENT 1
+#define HAVE_PRE_INCREMENT 1
/* Macros to check register numbers against specific register classes. */
@@ -1997,6 +2022,7 @@ typedef struct rs6000_args
rtx reg = gen_reg_rtx (Pmode); \
emit_insn (gen_elf_high (reg, (X))); \
(X) = gen_rtx_LO_SUM (Pmode, reg, (X)); \
+ goto WIN; \
} \
}
@@ -2010,6 +2036,18 @@ typedef struct rs6000_args
#define LEGITIMIZE_RELOAD_ADDRESS(X,MODE,OPNUM,TYPE,IND_LEVELS,WIN) \
do { \
+ /* We must recognize output that we have already generated ourselves. */ \
+ if (GET_CODE (X) == PLUS \
+ && GET_CODE (XEXP (X, 0)) == PLUS \
+ && GET_CODE (XEXP (XEXP (X, 0), 0)) == REG \
+ && GET_CODE (XEXP (XEXP (X, 0), 1)) == CONST_INT \
+ && GET_CODE (XEXP (X, 1)) == CONST_INT) \
+ { \
+ push_reload (XEXP (X, 0), NULL_RTX, &XEXP (X, 0), NULL_PTR, \
+ BASE_REG_CLASS, GET_MODE (X), VOIDmode, 0, 0, \
+ OPNUM, TYPE); \
+ goto WIN; \
+ } \
if (GET_CODE (X) == PLUS \
&& GET_CODE (XEXP (X, 0)) == REG \
&& REGNO (XEXP (X, 0)) < FIRST_PSEUDO_REGISTER \
@@ -2274,10 +2312,12 @@ do { \
? COSTS_N_INSNS (3) : COSTS_N_INSNS (4)); \
case PROCESSOR_RIOS2: \
case PROCESSOR_MPCCORE: \
+ case PROCESSOR_PPC604e: \
return COSTS_N_INSNS (2); \
case PROCESSOR_PPC601: \
return COSTS_N_INSNS (5); \
case PROCESSOR_PPC603: \
+ case PROCESSOR_PPC750: \
return (GET_CODE (XEXP (X, 1)) != CONST_INT \
? COSTS_N_INSNS (5) \
: INTVAL (XEXP (X, 1)) >= -256 && INTVAL (XEXP (X, 1)) <= 255 \
@@ -2310,8 +2350,11 @@ do { \
case PROCESSOR_PPC603: \
return COSTS_N_INSNS (37); \
case PROCESSOR_PPC604: \
+ case PROCESSOR_PPC604e: \
case PROCESSOR_PPC620: \
return COSTS_N_INSNS (20); \
+ case PROCESSOR_PPC750: \
+ return COSTS_N_INSNS (19); \
} \
case FFS: \
return COSTS_N_INSNS (4); \
@@ -2957,43 +3000,21 @@ extern char rs6000_reg_names[][8]; /* register names (0 vs. %r0). */
/* This is how to output an assembler line defining a `double' constant. */
-#define ASM_OUTPUT_DOUBLE(FILE, VALUE) \
- { \
- if (REAL_VALUE_ISINF (VALUE) \
- || REAL_VALUE_ISNAN (VALUE) \
- || REAL_VALUE_MINUS_ZERO (VALUE)) \
- { \
- long t[2]; \
- REAL_VALUE_TO_TARGET_DOUBLE ((VALUE), t); \
- fprintf (FILE, "\t.long 0x%lx\n\t.long 0x%lx\n", \
- t[0] & 0xffffffff, t[1] & 0xffffffff); \
- } \
- else \
- { \
- char str[30]; \
- REAL_VALUE_TO_DECIMAL (VALUE, "%.20e", str); \
- fprintf (FILE, "\t.double 0d%s\n", str); \
- } \
+#define ASM_OUTPUT_DOUBLE(FILE, VALUE) \
+ { \
+ long t[2]; \
+ REAL_VALUE_TO_TARGET_DOUBLE ((VALUE), t); \
+ fprintf (FILE, "\t.long 0x%lx\n\t.long 0x%lx\n", \
+ t[0] & 0xffffffff, t[1] & 0xffffffff); \
}
/* This is how to output an assembler line defining a `float' constant. */
-#define ASM_OUTPUT_FLOAT(FILE, VALUE) \
- { \
- if (REAL_VALUE_ISINF (VALUE) \
- || REAL_VALUE_ISNAN (VALUE) \
- || REAL_VALUE_MINUS_ZERO (VALUE)) \
- { \
- long t; \
- REAL_VALUE_TO_TARGET_SINGLE ((VALUE), t); \
- fprintf (FILE, "\t.long 0x%lx\n", t & 0xffffffff); \
- } \
- else \
- { \
- char str[30]; \
- REAL_VALUE_TO_DECIMAL ((VALUE), "%.20e", str); \
- fprintf (FILE, "\t.float 0d%s\n", str); \
- } \
+#define ASM_OUTPUT_FLOAT(FILE, VALUE) \
+ { \
+ long t; \
+ REAL_VALUE_TO_TARGET_SINGLE ((VALUE), t); \
+ fprintf (FILE, "\t.long 0x%lx\n", t & 0xffffffff); \
}
/* This is how to output an assembler line defining an `int' constant. */
@@ -3042,32 +3063,6 @@ do { \
#define ASM_OUTPUT_ASCII(FILE, P, N) output_ascii ((FILE), (P), (N))
-/* This is how to output code to push a register on the stack.
- It need not be very fast code.
-
- On the rs6000, we must keep the backchain up to date. In order
- to simplify things, always allocate 16 bytes for a push (System V
- wants to keep stack aligned to a 16 byte boundary). */
-
-#define ASM_OUTPUT_REG_PUSH(FILE,REGNO) \
-do { \
- extern char *reg_names[]; \
- asm_fprintf (FILE, "\t{stu|stwu} %s,-16(%s)\n\t{st|stw} %s,8(%s)\n", \
- reg_names[1], reg_names[1], reg_names[REGNO], \
- reg_names[1]); \
-} while (0)
-
-/* This is how to output an insn to pop a register from the stack.
- It need not be very fast code. */
-
-#define ASM_OUTPUT_REG_POP(FILE,REGNO) \
-do { \
- extern char *reg_names[]; \
- asm_fprintf (FILE, "\t{l|lwz} %s,8(%s)\n\t{ai|addic} %s,%s,16\n", \
- reg_names[REGNO], reg_names[1], reg_names[1], \
- reg_names[1]); \
-} while (0)
-
/* This is how to output an element of a case-vector that is absolute.
(RS/6000 does not use such vectors, but we must define this macro
anyway.) */
@@ -3166,29 +3161,29 @@ do { \
/* Define the codes that are matched by predicates in rs6000.c. */
#define PREDICATE_CODES \
- {"short_cint_operand", {CONST_INT, CONSTANT_P_RTX}}, \
- {"u_short_cint_operand", {CONST_INT, CONSTANT_P_RTX}}, \
+ {"short_cint_operand", {CONST_INT}}, \
+ {"u_short_cint_operand", {CONST_INT}}, \
{"non_short_cint_operand", {CONST_INT}}, \
{"gpc_reg_operand", {SUBREG, REG}}, \
{"cc_reg_operand", {SUBREG, REG}}, \
- {"reg_or_short_operand", {SUBREG, REG, CONST_INT, CONSTANT_P_RTX}}, \
+ {"cc_reg_not_cr0_operand", {SUBREG, REG}}, \
+ {"reg_or_short_operand", {SUBREG, REG, CONST_INT}}, \
{"reg_or_neg_short_operand", {SUBREG, REG, CONST_INT}}, \
- {"reg_or_u_short_operand", {SUBREG, REG, CONST_INT, CONSTANT_P_RTX}}, \
- {"reg_or_cint_operand", {SUBREG, REG, CONST_INT, CONSTANT_P_RTX}}, \
+ {"reg_or_u_short_operand", {SUBREG, REG, CONST_INT}}, \
+ {"reg_or_cint_operand", {SUBREG, REG, CONST_INT}}, \
{"got_operand", {SYMBOL_REF, CONST, LABEL_REF}}, \
{"got_no_const_operand", {SYMBOL_REF, LABEL_REF}}, \
{"easy_fp_constant", {CONST_DOUBLE}}, \
{"reg_or_mem_operand", {SUBREG, MEM, REG}}, \
{"lwa_operand", {SUBREG, MEM, REG}}, \
{"volatile_mem_operand", {MEM}}, \
- {"offsettable_addr_operand", {REG, SUBREG, PLUS}}, \
+ {"offsettable_mem_operand", {MEM}}, \
{"mem_or_easy_const_operand", {SUBREG, MEM, CONST_DOUBLE}}, \
- {"add_operand", {SUBREG, REG, CONST_INT, CONSTANT_P_RTX}}, \
+ {"add_operand", {SUBREG, REG, CONST_INT}}, \
{"non_add_cint_operand", {CONST_INT}}, \
- {"and_operand", {SUBREG, REG, CONST_INT, CONSTANT_P_RTX}}, \
- {"and64_operand", {SUBREG, REG, CONST_INT, CONSTANT_P_RTX, \
- CONST_DOUBLE}}, \
- {"logical_operand", {SUBREG, REG, CONST_INT, CONSTANT_P_RTX}}, \
+ {"and_operand", {SUBREG, REG, CONST_INT}}, \
+ {"and64_operand", {SUBREG, REG, CONST_INT, CONST_DOUBLE}}, \
+ {"logical_operand", {SUBREG, REG, CONST_INT}}, \
{"non_logical_cint_operand", {CONST_INT}}, \
{"mask_operand", {CONST_INT}}, \
{"mask64_operand", {CONST_INT, CONST_DOUBLE}}, \
@@ -3196,7 +3191,7 @@ do { \
{"fpmem_operand", {REG}}, \
{"call_operand", {SYMBOL_REF, REG}}, \
{"current_file_function_operand", {SYMBOL_REF}}, \
- {"input_operand", {SUBREG, MEM, REG, CONST_INT, CONSTANT_P_RTX, \
+ {"input_operand", {SUBREG, MEM, REG, CONST_INT, \
CONST_DOUBLE, SYMBOL_REF}}, \
{"load_multiple_operation", {PARALLEL}}, \
{"store_multiple_operation", {PARALLEL}}, \
@@ -3236,6 +3231,7 @@ extern int u_short_cint_operand ();
extern int non_short_cint_operand ();
extern int gpc_reg_operand ();
extern int cc_reg_operand ();
+extern int cc_reg_not_cr0_operand ();
extern int reg_or_short_operand ();
extern int reg_or_neg_short_operand ();
extern int reg_or_u_short_operand ();
@@ -3304,6 +3300,7 @@ extern void output_ascii ();
extern void rs6000_gen_section_name ();
extern void output_function_profiler ();
extern int rs6000_adjust_cost ();
+extern int rs6000_adjust_priority ();
extern void rs6000_trampoline_template ();
extern int rs6000_trampoline_size ();
extern void rs6000_initialize_trampoline ();
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 7b7f989fddf..cbfafd9606c 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -1,5 +1,5 @@
;; Machine description for IBM RISC System 6000 (POWER) for GNU C compiler
-;; Copyright (C) 1990, 91-97, 1998 Free Software Foundation, Inc.
+;; Copyright (C) 1990, 91-98, 1999 Free Software Foundation, Inc.
;; Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
;; This file is part of GNU CC.
@@ -40,7 +40,7 @@
;; Processor type -- this attribute must exactly match the processor_type
;; enumeration in rs6000.h.
-(define_attr "cpu" "rios1,rios2,mpccore,ppc403,ppc601,ppc603,ppc604,ppc604e,ppc620"
+(define_attr "cpu" "rios1,rios2,mpccore,ppc403,ppc601,ppc603,ppc604,ppc604e,ppc620,ppc750"
(const (symbol_ref "rs6000_cpu_attr")))
; (define_function_unit NAME MULTIPLICITY SIMULTANEITY
@@ -50,17 +50,17 @@
; (POWER and 601 use Integer Unit)
(define_function_unit "lsu" 1 0
(and (eq_attr "type" "load")
- (eq_attr "cpu" "mpccore,ppc603,ppc604,ppc604e,ppc620"))
+ (eq_attr "cpu" "mpccore,ppc603,ppc604,ppc604e,ppc620,ppc750"))
2 1)
(define_function_unit "lsu" 1 0
(and (eq_attr "type" "store,fpstore")
- (eq_attr "cpu" "mpccore,ppc603,ppc604,ppc604e,ppc620"))
+ (eq_attr "cpu" "mpccore,ppc603,ppc604,ppc604e,ppc620,ppc750"))
1 1)
(define_function_unit "lsu" 1 0
(and (eq_attr "type" "fpload")
- (eq_attr "cpu" "mpccore,ppc603"))
+ (eq_attr "cpu" "mpccore,ppc603,ppc750"))
2 1)
(define_function_unit "lsu" 1 0
@@ -204,6 +204,31 @@
(eq_attr "cpu" "ppc604,ppc604e,ppc620"))
20 19)
+; PPC750 has two integer units: a primary one which can perform all
+; operations and a secondary one which is fed in lock step with the first
+; and can perform "simple" integer operations.
+; To catch this we define a 'dummy' imuldiv-unit that is also needed
+; for the complex insns.
+(define_function_unit "iu2" 2 0
+ (and (eq_attr "type" "integer")
+ (eq_attr "cpu" "ppc750"))
+ 1 1)
+
+(define_function_unit "iu2" 2 0
+ (and (eq_attr "type" "imul")
+ (eq_attr "cpu" "ppc750"))
+ 4 2)
+
+(define_function_unit "imuldiv" 1 0
+ (and (eq_attr "type" "imul")
+ (eq_attr "cpu" "ppc750"))
+ 4 2)
+
+(define_function_unit "imuldiv" 1 0
+ (and (eq_attr "type" "idiv")
+ (eq_attr "cpu" "ppc750"))
+ 19 19)
+
; compare is done on integer unit, but feeds insns which
; execute on the branch unit.
(define_function_unit "iu" 1 0
@@ -218,7 +243,7 @@
(define_function_unit "iu" 1 0
(and (eq_attr "type" "compare,delayed_compare")
- (eq_attr "cpu" "mpccore,ppc403,ppc601,ppc603,ppc604,ppc604e,ppc620"))
+ (eq_attr "cpu" "mpccore,ppc403,ppc601,ppc603,ppc604,ppc604e,ppc620,ppc750"))
3 1)
(define_function_unit "iu2" 2 0
@@ -228,7 +253,7 @@
(define_function_unit "iu2" 2 0
(and (eq_attr "type" "compare,delayed_compare")
- (eq_attr "cpu" "ppc604,ppc604e,ppc620"))
+ (eq_attr "cpu" "ppc604,ppc604e,ppc620,ppc750"))
1 1)
; fp compare uses fp unit
@@ -255,7 +280,7 @@
; fp compare uses fp unit
(define_function_unit "fpu" 1 0
(and (eq_attr "type" "fpcompare")
- (eq_attr "cpu" "ppc601,ppc603,ppc604,ppc604e,ppc620"))
+ (eq_attr "cpu" "ppc601,ppc603,ppc604,ppc604e,ppc620,ppc750"))
5 1)
(define_function_unit "fpu" 1 0
@@ -270,7 +295,7 @@
(define_function_unit "bpu" 1 0
(and (eq_attr "type" "mtjmpr")
- (eq_attr "cpu" "mpccore,ppc403,ppc601,ppc603,ppc604,ppc604e,ppc620"))
+ (eq_attr "cpu" "mpccore,ppc403,ppc601,ppc603,ppc604,ppc604e,ppc620,ppc750"))
4 1)
; all jumps/branches are executing on the bpu, in 1 cycle, for all machines.
@@ -300,7 +325,7 @@
(define_function_unit "fpu" 1 0
(and (eq_attr "type" "fp")
- (eq_attr "cpu" "ppc603,ppc604,ppc604e,ppc620"))
+ (eq_attr "cpu" "ppc603,ppc604,ppc604e,ppc620,ppc750"))
3 1)
(define_function_unit "fpu" 1 0
@@ -316,7 +341,7 @@
; is this true?
(define_function_unit "fpu" 1 0
(and (eq_attr "type" "dmul")
- (eq_attr "cpu" "ppc603"))
+ (eq_attr "cpu" "ppc603,ppc750"))
4 2)
(define_function_unit "fpu" 1 0
@@ -351,7 +376,7 @@
(define_function_unit "fpu" 1 0
(and (eq_attr "type" "ddiv")
- (eq_attr "cpu" "ppc601,ppc604,ppc604e,ppc620"))
+ (eq_attr "cpu" "ppc601,ppc604,ppc604e,ppc620,ppc750"))
31 31)
(define_function_unit "fpu" 1 0
@@ -901,29 +926,67 @@
[(set_attr "length" "4,4,4,4")])
(define_insn "*addsi3_internal2"
- [(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
- (compare:CC (plus:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r")
- (match_operand:SI 2 "reg_or_short_operand" "r,I"))
+ [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y")
+ (compare:CC (plus:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r")
+ (match_operand:SI 2 "reg_or_short_operand" "r,I,r,I"))
(const_int 0)))
- (clobber (match_scratch:SI 3 "=r,r"))]
+ (clobber (match_scratch:SI 3 "=r,r,r,r"))]
""
"@
{cax.|add.} %3,%1,%2
- {ai.|addic.} %3,%1,%2"
- [(set_attr "type" "compare")])
+ {ai.|addic.} %3,%1,%2
+ #
+ #"
+ [(set_attr "type" "compare")
+ (set_attr "length" "4,4,8,8")])
+
+(define_split
+ [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+ (compare:CC (plus:SI (match_operand:SI 1 "gpc_reg_operand" "")
+ (match_operand:SI 2 "reg_or_short_operand" ""))
+ (const_int 0)))
+ (clobber (match_scratch:SI 3 ""))]
+ "reload_completed"
+ [(set (match_dup 3)
+ (plus:SI (match_dup 1)
+ (match_dup 2)))
+ (set (match_dup 0)
+ (compare:CC (match_dup 3)
+ (const_int 0)))]
+ "")
(define_insn "*addsi3_internal3"
- [(set (match_operand:CC 3 "cc_reg_operand" "=x,x")
- (compare:CC (plus:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r")
- (match_operand:SI 2 "reg_or_short_operand" "r,I"))
+ [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y")
+ (compare:CC (plus:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r")
+ (match_operand:SI 2 "reg_or_short_operand" "r,I,r,I"))
(const_int 0)))
- (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
- (plus:SI (match_dup 1) (match_dup 2)))]
+ (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r")
+ (plus:SI (match_dup 1)
+ (match_dup 2)))]
""
"@
{cax.|add.} %0,%1,%2
- {ai.|addic.} %0,%1,%2"
- [(set_attr "type" "compare")])
+ {ai.|addic.} %0,%1,%2
+ #
+ #"
+ [(set_attr "type" "compare")
+ (set_attr "length" "4,4,8,8")])
+
+(define_split
+ [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
+ (compare:CC (plus:SI (match_operand:SI 1 "gpc_reg_operand" "")
+ (match_operand:SI 2 "reg_or_short_operand" ""))
+ (const_int 0)))
+ (set (match_operand:SI 0 "gpc_reg_operand" "")
+ (plus:SI (match_dup 1) (match_dup 2)))]
+ "reload_completed"
+ [(set (match_dup 0)
+ (plus:SI (match_dup 1)
+ (match_dup 2)))
+ (set (match_dup 3)
+ (compare:CC (match_dup 0)
+ (const_int 0)))]
+ "")
;; Split an add that we can't do in one insn into two insns, each of which
;; does one 16-bit part. This is used by combine. Note that the low-order
@@ -955,23 +1018,56 @@
"nor %0,%1,%1")
(define_insn ""
- [(set (match_operand:CC 0 "cc_reg_operand" "=x")
- (compare:CC (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
+ [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
+ (compare:CC (not:SI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
(const_int 0)))
- (clobber (match_scratch:SI 2 "=r"))]
+ (clobber (match_scratch:SI 2 "=r,r"))]
""
- "nor. %2,%1,%1"
- [(set_attr "type" "compare")])
+ "@
+ nor. %2,%1,%1
+ #"
+ [(set_attr "type" "compare")
+ (set_attr "length" "4,8")])
+
+(define_split
+ [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+ (compare:CC (not:SI (match_operand:SI 1 "gpc_reg_operand" ""))
+ (const_int 0)))
+ (clobber (match_scratch:SI 2 ""))]
+ "reload_completed"
+ [(set (match_dup 2)
+ (not:SI (match_dup 1)))
+ (set (match_dup 0)
+ (compare:CC (match_dup 2)
+ (const_int 0)))]
+ "")
(define_insn ""
- [(set (match_operand:CC 2 "cc_reg_operand" "=x")
- (compare:CC (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
+ [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
+ (compare:CC (not:SI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
(const_int 0)))
- (set (match_operand:SI 0 "gpc_reg_operand" "=r")
+ (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
(not:SI (match_dup 1)))]
""
- "nor. %0,%1,%1"
- [(set_attr "type" "compare")])
+ "@
+ nor. %0,%1,%1
+ #"
+ [(set_attr "type" "compare")
+ (set_attr "length" "4,8")])
+
+(define_split
+ [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "")
+ (compare:CC (not:SI (match_operand:SI 1 "gpc_reg_operand" ""))
+ (const_int 0)))
+ (set (match_operand:SI 0 "gpc_reg_operand" "=r")
+ (not:SI (match_dup 1)))]
+ "reload_completed"
+ [(set (match_dup 0)
+ (not:SI (match_dup 1)))
+ (set (match_dup 2)
+ (compare:CC (match_dup 0)
+ (const_int 0)))]
+ "")
(define_insn ""
[(set (match_operand:SI 0 "gpc_reg_operand" "=r")
@@ -990,46 +1086,91 @@
subfic %0,%2,%1")
(define_insn ""
- [(set (match_operand:CC 0 "cc_reg_operand" "=x")
- (compare:CC (minus:SI (match_operand:SI 1 "gpc_reg_operand" "r")
- (match_operand:SI 2 "gpc_reg_operand" "r"))
+ [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
+ (compare:CC (minus:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
+ (match_operand:SI 2 "gpc_reg_operand" "r,r"))
(const_int 0)))
- (clobber (match_scratch:SI 3 "=r"))]
+ (clobber (match_scratch:SI 3 "=r,r"))]
"! TARGET_POWERPC"
- "{sf.|subfc.} %3,%2,%1"
- [(set_attr "type" "compare")])
+ "@
+ {sf.|subfc.} %3,%2,%1
+ #"
+ [(set_attr "type" "compare")
+ (set_attr "length" "4,8")])
(define_insn ""
- [(set (match_operand:CC 0 "cc_reg_operand" "=x")
- (compare:CC (minus:SI (match_operand:SI 1 "gpc_reg_operand" "r")
- (match_operand:SI 2 "gpc_reg_operand" "r"))
+ [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
+ (compare:CC (minus:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
+ (match_operand:SI 2 "gpc_reg_operand" "r,r"))
(const_int 0)))
- (clobber (match_scratch:SI 3 "=r"))]
+ (clobber (match_scratch:SI 3 "=r,r"))]
"TARGET_POWERPC"
- "subf. %3,%2,%1"
- [(set_attr "type" "compare")])
+ "@
+ subf. %3,%2,%1
+ #"
+ [(set_attr "type" "compare")
+ (set_attr "length" "4,8")])
+
+(define_split
+ [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+ (compare:CC (minus:SI (match_operand:SI 1 "gpc_reg_operand" "")
+ (match_operand:SI 2 "gpc_reg_operand" ""))
+ (const_int 0)))
+ (clobber (match_scratch:SI 3 ""))]
+ "reload_completed"
+ [(set (match_dup 3)
+ (minus:SI (match_dup 1)
+ (match_dup 2)))
+ (set (match_dup 0)
+ (compare:CC (match_dup 3)
+ (const_int 0)))]
+ "")
(define_insn ""
- [(set (match_operand:CC 3 "cc_reg_operand" "=x")
- (compare:CC (minus:SI (match_operand:SI 1 "gpc_reg_operand" "r")
- (match_operand:SI 2 "gpc_reg_operand" "r"))
+ [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
+ (compare:CC (minus:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
+ (match_operand:SI 2 "gpc_reg_operand" "r,r"))
(const_int 0)))
- (set (match_operand:SI 0 "gpc_reg_operand" "=r")
+ (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
(minus:SI (match_dup 1) (match_dup 2)))]
"! TARGET_POWERPC"
- "{sf.|subfc.} %0,%2,%1"
- [(set_attr "type" "compare")])
+ "@
+ {sf.|subfc.} %0,%2,%1
+ #"
+ [(set_attr "type" "compare")
+ (set_attr "length" "4,8")])
(define_insn ""
- [(set (match_operand:CC 3 "cc_reg_operand" "=x")
- (compare:CC (minus:SI (match_operand:SI 1 "gpc_reg_operand" "r")
- (match_operand:SI 2 "gpc_reg_operand" "r"))
+ [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
+ (compare:CC (minus:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
+ (match_operand:SI 2 "gpc_reg_operand" "r,r"))
(const_int 0)))
- (set (match_operand:SI 0 "gpc_reg_operand" "=r")
- (minus:SI (match_dup 1) (match_dup 2)))]
+ (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
+ (minus:SI (match_dup 1)
+ (match_dup 2)))]
"TARGET_POWERPC"
- "subf. %0,%2,%1"
- [(set_attr "type" "compare")])
+ "@
+ subf. %0,%2,%1
+ #"
+ [(set_attr "type" "compare")
+ (set_attr "length" "4,8")])
+
+(define_split
+ [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
+ (compare:CC (minus:SI (match_operand:SI 1 "gpc_reg_operand" "")
+ (match_operand:SI 2 "gpc_reg_operand" ""))
+ (const_int 0)))
+ (set (match_operand:SI 0 "gpc_reg_operand" "")
+ (minus:SI (match_dup 1)
+ (match_dup 2)))]
+ "reload_completed"
+ [(set (match_dup 0)
+ (minus:SI (match_dup 1)
+ (match_dup 2)))
+ (set (match_dup 3)
+ (compare:CC (match_dup 0)
+ (const_int 0)))]
+ "")
(define_expand "subsi3"
[(set (match_operand:SI 0 "gpc_reg_operand" "")
@@ -1720,36 +1861,89 @@
{rlinm|rlwinm} %0,%1,0,%m2,%M2
{andil.|andi.} %0,%1,%b2
{andiu.|andis.} %0,%1,%u2"
- [(set_attr "length" "4,4,4,4")])
+ [(set_attr "length" "4")])
+
+;; Note to set cr's other than cr0 we do the and immediate and then
+;; the test again -- this avoids a mcrf which on the higher end
+;; machines causes an execution serialization
(define_insn "*andsi3_internal2"
- [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,x,x")
- (compare:CC (and:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r")
- (match_operand:SI 2 "and_operand" "r,K,J,L"))
+ [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,x,x,?y,??y,??y,?y")
+ (compare:CC (and:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r,r,r,r")
+ (match_operand:SI 2 "and_operand" "r,K,J,L,r,K,J,L"))
(const_int 0)))
- (clobber (match_scratch:SI 3 "=r,r,r,r"))]
+ (clobber (match_scratch:SI 3 "=r,r,r,r,r,r,r,r"))
+ (clobber (match_scratch:CC 4 "=X,X,X,X,X,x,x,X"))]
""
"@
and. %3,%1,%2
{andil.|andi.} %3,%1,%b2
{andiu.|andis.} %3,%1,%u2
- {rlinm.|rlwinm.} %3,%1,0,%m2,%M2"
- [(set_attr "type" "compare,compare,compare,delayed_compare")])
+ {rlinm.|rlwinm.} %3,%1,0,%m2,%M2
+ #
+ #
+ #
+ #"
+ [(set_attr "type" "compare,compare,compare,delayed_compare,compare,compare,compare,compare")
+ (set_attr "length" "4,4,4,4,8,8,8,8")])
+
+(define_split
+ [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+ (compare:CC (and:SI (match_operand:SI 1 "gpc_reg_operand" "")
+ (match_operand:SI 2 "and_operand" ""))
+ (const_int 0)))
+ (clobber (match_scratch:SI 3 ""))
+ (clobber (match_scratch:CC 4 ""))]
+ "reload_completed"
+ [(parallel [(set (match_dup 3)
+ (and:SI (match_dup 1)
+ (match_dup 2)))
+ (clobber (match_dup 4))])
+ (set (match_dup 0)
+ (compare:CC (match_dup 3)
+ (const_int 0)))]
+ "")
(define_insn "*andsi3_internal3"
- [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,x,x")
- (compare:CC (and:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r")
- (match_operand:SI 2 "and_operand" "r,K,J,L"))
+ [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,x,x,?y,??y,??y,?y")
+ (compare:CC (and:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r,r,r,r")
+ (match_operand:SI 2 "and_operand" "r,K,J,L,r,K,J,L"))
(const_int 0)))
- (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r")
- (and:SI (match_dup 1) (match_dup 2)))]
+ (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r,r,r,r")
+ (and:SI (match_dup 1)
+ (match_dup 2)))
+ (clobber (match_scratch:CC 4 "=X,X,X,X,X,x,x,X"))]
""
"@
and. %0,%1,%2
{andil.|andi.} %0,%1,%b2
{andiu.|andis.} %0,%1,%u2
- {rlinm.|rlwinm.} %0,%1,0,%m2,%M2"
- [(set_attr "type" "compare,compare,compare,delayed_compare")])
+ {rlinm.|rlwinm.} %0,%1,0,%m2,%M2
+ #
+ #
+ #
+ #"
+ [(set_attr "type" "compare,compare,compare,delayed_compare,compare,compare,compare,compare")
+ (set_attr "length" "4,4,4,4,8,8,8,8")])
+
+(define_split
+ [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
+ (compare:CC (and:SI (match_operand:SI 1 "gpc_reg_operand" "")
+ (match_operand:SI 2 "and_operand" ""))
+ (const_int 0)))
+ (set (match_operand:SI 0 "gpc_reg_operand" "")
+ (and:SI (match_dup 1)
+ (match_dup 2)))
+ (clobber (match_scratch:CC 4 ""))]
+ "reload_completed"
+ [(parallel [(set (match_dup 0)
+ (and:SI (match_dup 1)
+ (match_dup 2)))
+ (clobber (match_dup 4))])
+ (set (match_dup 3)
+ (compare:CC (match_dup 0)
+ (const_int 0)))]
+ "")
(define_expand "iorsi3"
[(set (match_operand:SI 0 "gpc_reg_operand" "")
@@ -1785,25 +1979,63 @@
[(set_attr "length" "4,4,4")])
(define_insn "*iorsi3_internal2"
- [(set (match_operand:CC 0 "cc_reg_operand" "=x")
- (compare:CC (ior:SI (match_operand:SI 1 "gpc_reg_operand" "%r")
- (match_operand:SI 2 "gpc_reg_operand" "r"))
+ [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
+ (compare:CC (ior:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r")
+ (match_operand:SI 2 "gpc_reg_operand" "r,r"))
(const_int 0)))
- (clobber (match_scratch:SI 3 "=r"))]
+ (clobber (match_scratch:SI 3 "=r,r"))]
""
- "or. %3,%1,%2"
- [(set_attr "type" "compare")])
+ "@
+ or. %3,%1,%2
+ #"
+ [(set_attr "type" "compare")
+ (set_attr "length" "4,8")])
+
+(define_split
+ [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+ (compare:CC (ior:SI (match_operand:SI 1 "gpc_reg_operand" "")
+ (match_operand:SI 2 "gpc_reg_operand" ""))
+ (const_int 0)))
+ (clobber (match_scratch:SI 3 ""))]
+ "reload_completed"
+ [(set (match_dup 3)
+ (ior:SI (match_dup 1)
+ (match_dup 2)))
+ (set (match_dup 0)
+ (compare:CC (match_dup 3)
+ (const_int 0)))]
+ "")
(define_insn "*iorsi3_internal3"
- [(set (match_operand:CC 3 "cc_reg_operand" "=x")
- (compare:CC (ior:SI (match_operand:SI 1 "gpc_reg_operand" "%r")
- (match_operand:SI 2 "gpc_reg_operand" "r"))
+ [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
+ (compare:CC (ior:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r")
+ (match_operand:SI 2 "gpc_reg_operand" "r,r"))
(const_int 0)))
- (set (match_operand:SI 0 "gpc_reg_operand" "=r")
- (ior:SI (match_dup 1) (match_dup 2)))]
+ (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
+ (ior:SI (match_dup 1)
+ (match_dup 2)))]
""
- "or. %0,%1,%2"
- [(set_attr "type" "compare")])
+ "@
+ or. %0,%1,%2
+ #"
+ [(set_attr "type" "compare")
+ (set_attr "length" "4,8")])
+
+(define_split
+ [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
+ (compare:CC (ior:SI (match_operand:SI 1 "gpc_reg_operand" "")
+ (match_operand:SI 2 "gpc_reg_operand" ""))
+ (const_int 0)))
+ (set (match_operand:SI 0 "gpc_reg_operand" "")
+ (ior:SI (match_dup 1) (match_dup 2)))]
+ "reload_completed"
+ [(set (match_dup 0)
+ (ior:SI (match_dup 1)
+ (match_dup 2)))
+ (set (match_dup 3)
+ (compare:CC (match_dup 0)
+ (const_int 0)))]
+ "")
;; Split an IOR that we can't do in one insn into two insns, each of which
;; does one 16-bit part. This is used by combine.
@@ -1855,25 +2087,63 @@
[(set_attr "length" "4,4,4")])
(define_insn "*xorsi3_internal2"
- [(set (match_operand:CC 0 "cc_reg_operand" "=x")
- (compare:CC (xor:SI (match_operand:SI 1 "gpc_reg_operand" "%r")
- (match_operand:SI 2 "gpc_reg_operand" "r"))
+ [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
+ (compare:CC (xor:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r")
+ (match_operand:SI 2 "gpc_reg_operand" "r,r"))
(const_int 0)))
- (clobber (match_scratch:SI 3 "=r"))]
+ (clobber (match_scratch:SI 3 "=r,r"))]
""
- "xor. %3,%1,%2"
- [(set_attr "type" "compare")])
+ "@
+ xor. %3,%1,%2
+ #"
+ [(set_attr "type" "compare")
+ (set_attr "length" "4,8")])
+
+(define_split
+ [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+ (compare:CC (xor:SI (match_operand:SI 1 "gpc_reg_operand" "")
+ (match_operand:SI 2 "gpc_reg_operand" ""))
+ (const_int 0)))
+ (clobber (match_scratch:SI 3 ""))]
+ "reload_completed"
+ [(set (match_dup 3)
+ (xor:SI (match_dup 1)
+ (match_dup 2)))
+ (set (match_dup 0)
+ (compare:CC (match_dup 3)
+ (const_int 0)))]
+ "")
(define_insn "*xorsi3_internal3"
- [(set (match_operand:CC 3 "cc_reg_operand" "=x")
- (compare:CC (xor:SI (match_operand:SI 1 "gpc_reg_operand" "%r")
- (match_operand:SI 2 "gpc_reg_operand" "r"))
+ [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
+ (compare:CC (xor:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r")
+ (match_operand:SI 2 "gpc_reg_operand" "r,r"))
(const_int 0)))
- (set (match_operand:SI 0 "gpc_reg_operand" "=r")
- (xor:SI (match_dup 1) (match_dup 2)))]
+ (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
+ (xor:SI (match_dup 1)
+ (match_dup 2)))]
""
- "xor. %0,%1,%2"
- [(set_attr "type" "compare")])
+ "@
+ xor. %0,%1,%2
+ #"
+ [(set_attr "type" "compare")
+ (set_attr "length" "4,8")])
+
+(define_split
+ [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
+ (compare:CC (xor:SI (match_operand:SI 1 "gpc_reg_operand" "")
+ (match_operand:SI 2 "gpc_reg_operand" ""))
+ (const_int 0)))
+ (set (match_operand:SI 0 "gpc_reg_operand" "")
+ (xor:SI (match_dup 1) (match_dup 2)))]
+ "reload_completed"
+ [(set (match_dup 0)
+ (xor:SI (match_dup 1)
+ (match_dup 2)))
+ (set (match_dup 3)
+ (compare:CC (match_dup 0)
+ (const_int 0)))]
+ "")
;; Split an XOR that we can't do in one insn into two insns, each of which
;; does one 16-bit part. This is used by combine.
@@ -1899,25 +2169,63 @@
"eqv %0,%1,%2")
(define_insn "*eqvsi3_internal2"
- [(set (match_operand:CC 0 "cc_reg_operand" "=x")
- (compare:CC (not:SI (xor:SI (match_operand:SI 1 "gpc_reg_operand" "%r")
- (match_operand:SI 2 "gpc_reg_operand" "r")))
+ [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
+ (compare:CC (not:SI (xor:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r")
+ (match_operand:SI 2 "gpc_reg_operand" "r,r")))
(const_int 0)))
- (clobber (match_scratch:SI 3 "=r"))]
+ (clobber (match_scratch:SI 3 "=r,r"))]
""
- "eqv. %3,%1,%2"
- [(set_attr "type" "compare")])
+ "@
+ eqv. %3,%1,%2
+ #"
+ [(set_attr "type" "compare")
+ (set_attr "length" "4,8")])
+
+(define_split
+ [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+ (compare:CC (not:SI (xor:SI (match_operand:SI 1 "gpc_reg_operand" "")
+ (match_operand:SI 2 "gpc_reg_operand" "")))
+ (const_int 0)))
+ (clobber (match_scratch:SI 3 ""))]
+ "reload_completed"
+ [(set (match_dup 3)
+ (not:SI (xor:SI (match_dup 1)
+ (match_dup 2))))
+ (set (match_dup 0)
+ (compare:CC (match_dup 3)
+ (const_int 0)))]
+ "")
(define_insn "*eqvsi3_internal3"
- [(set (match_operand:CC 3 "cc_reg_operand" "=x")
- (compare:CC (not:SI (xor:SI (match_operand:SI 1 "gpc_reg_operand" "%r")
- (match_operand:SI 2 "gpc_reg_operand" "r")))
+ [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
+ (compare:CC (not:SI (xor:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r")
+ (match_operand:SI 2 "gpc_reg_operand" "r,r")))
(const_int 0)))
- (set (match_operand:SI 0 "gpc_reg_operand" "=r")
+ (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
(not:SI (xor:SI (match_dup 1) (match_dup 2))))]
""
- "eqv. %0,%1,%2"
- [(set_attr "type" "compare")])
+ "@
+ eqv. %0,%1,%2
+ #"
+ [(set_attr "type" "compare")
+ (set_attr "length" "4,8")])
+
+(define_split
+ [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
+ (compare:CC (not:SI (xor:SI (match_operand:SI 1 "gpc_reg_operand" "")
+ (match_operand:SI 2 "reg_or_short_operand" "")))
+ (const_int 0)))
+ (set (match_operand:SI 0 "gpc_reg_operand" "")
+ (not:SI (xor:SI (match_dup 1)
+ (match_dup 2))))]
+ "reload_completed"
+ [(set (match_dup 0)
+ (not:SI (xor:SI (match_dup 1)
+ (match_dup 2))))
+ (set (match_dup 3)
+ (compare:CC (match_dup 0)
+ (const_int 0)))]
+ "")
(define_insn "*andcsi3_internal1"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r")
@@ -1927,25 +2235,64 @@
"andc %0,%2,%1")
(define_insn "*andcsi3_internal2"
- [(set (match_operand:CC 0 "cc_reg_operand" "=x")
- (compare:CC (and:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
- (match_operand:SI 2 "gpc_reg_operand" "r"))
+ [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
+ (compare:CC (and:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
+ (match_operand:SI 2 "gpc_reg_operand" "r,r"))
(const_int 0)))
- (clobber (match_scratch:SI 3 "=r"))]
+ (clobber (match_scratch:SI 3 "=r,r"))]
""
- "andc. %3,%2,%1"
- [(set_attr "type" "compare")])
+ "@
+ andc. %3,%2,%1
+ #"
+ [(set_attr "type" "compare")
+ (set_attr "length" "4,8")])
+
+(define_split
+ [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+ (compare:CC (and:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" ""))
+ (match_operand:SI 2 "gpc_reg_operand" ""))
+ (const_int 0)))
+ (clobber (match_scratch:SI 3 ""))]
+ "reload_completed"
+ [(set (match_dup 3)
+ (and:SI (not:SI (match_dup 1))
+ (match_dup 2)))
+ (set (match_dup 0)
+ (compare:CC (match_dup 3)
+ (const_int 0)))]
+ "")
(define_insn "*andcsi3_internal3"
- [(set (match_operand:CC 3 "cc_reg_operand" "=x")
- (compare:CC (and:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
- (match_operand:SI 2 "gpc_reg_operand" "r"))
+ [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
+ (compare:CC (and:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
+ (match_operand:SI 2 "gpc_reg_operand" "r,r"))
(const_int 0)))
- (set (match_operand:SI 0 "gpc_reg_operand" "=r")
- (and:SI (not:SI (match_dup 1)) (match_dup 2)))]
+ (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
+ (and:SI (not:SI (match_dup 1))
+ (match_dup 2)))]
""
- "andc. %0,%2,%1"
- [(set_attr "type" "compare")])
+ "@
+ andc. %0,%2,%1
+ #"
+ [(set_attr "type" "compare")
+ (set_attr "length" "4,8")])
+
+(define_split
+ [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
+ (compare:CC (and:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" ""))
+ (match_operand:SI 2 "gpc_reg_operand" ""))
+ (const_int 0)))
+ (set (match_operand:SI 0 "gpc_reg_operand" "")
+ (and:SI (not:SI (match_dup 1))
+ (match_dup 2)))]
+ "reload_completed"
+ [(set (match_dup 0)
+ (and:SI (not:SI (match_dup 1))
+ (match_dup 2)))
+ (set (match_dup 3)
+ (compare:CC (match_dup 0)
+ (const_int 0)))]
+ "")
(define_insn "*iorcsi3_internal1"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r")
@@ -1955,26 +2302,63 @@
"orc %0,%2,%1")
(define_insn "*iorcsi3_internal2"
- [(set (match_operand:CC 0 "cc_reg_operand" "=x")
- (compare:CC (ior:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
- (match_operand:SI 2 "gpc_reg_operand" "r"))
+ [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
+ (compare:CC (ior:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
+ (match_operand:SI 2 "gpc_reg_operand" "r,r"))
(const_int 0)))
- (clobber (match_scratch:SI 3 "=r"))]
+ (clobber (match_scratch:SI 3 "=r,r"))]
""
- "orc. %3,%2,%1"
- [(set_attr "type" "compare")])
+ "@
+ orc. %3,%2,%1
+ #"
+ [(set_attr "type" "compare")
+ (set_attr "length" "4,8")])
+
+(define_split
+ [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+ (compare:CC (ior:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" ""))
+ (match_operand:SI 2 "gpc_reg_operand" ""))
+ (const_int 0)))
+ (clobber (match_scratch:SI 3 ""))]
+ "reload_completed"
+ [(set (match_dup 3)
+ (ior:SI (not:SI (match_dup 1))
+ (match_dup 2)))
+ (set (match_dup 0)
+ (compare:CC (match_dup 3)
+ (const_int 0)))]
+ "")
(define_insn "*iorcsi3_internal3"
- [(set (match_operand:CC 3 "cc_reg_operand" "=x")
- (compare:CC (ior:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
- (match_operand:SI 2 "gpc_reg_operand" "r"))
+ [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
+ (compare:CC (ior:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
+ (match_operand:SI 2 "gpc_reg_operand" "r,r"))
(const_int 0)))
- (set (match_operand:SI 0 "gpc_reg_operand" "=r")
+ (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
(ior:SI (not:SI (match_dup 1)) (match_dup 2)))]
""
- "orc. %0,%2,%1"
+ "@
+ orc. %0,%2,%1
+ #"
[(set_attr "type" "compare")])
+(define_split
+ [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
+ (compare:CC (ior:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" ""))
+ (match_operand:SI 2 "gpc_reg_operand" ""))
+ (const_int 0)))
+ (set (match_operand:SI 0 "gpc_reg_operand" "")
+ (ior:SI (not:SI (match_dup 1))
+ (match_dup 2)))]
+ "reload_completed"
+ [(set (match_dup 0)
+ (ior:SI (not:SI (match_dup 1))
+ (match_dup 2)))
+ (set (match_dup 3)
+ (compare:CC (match_dup 0)
+ (const_int 0)))]
+ "")
+
(define_insn "*nandsi3_internal1"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(ior:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "%r"))
@@ -1983,25 +2367,64 @@
"nand %0,%1,%2")
(define_insn "*nandsi3_internal2"
- [(set (match_operand:CC 0 "cc_reg_operand" "=x")
- (compare:CC (ior:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "%r"))
- (not:SI (match_operand:SI 2 "gpc_reg_operand" "r")))
+ [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
+ (compare:CC (ior:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r"))
+ (not:SI (match_operand:SI 2 "gpc_reg_operand" "r,r")))
(const_int 0)))
- (clobber (match_scratch:SI 3 "=r"))]
+ (clobber (match_scratch:SI 3 "=r,r"))]
""
- "nand. %3,%1,%2"
- [(set_attr "type" "compare")])
+ "@
+ nand. %3,%1,%2
+ #"
+ [(set_attr "type" "compare")
+ (set_attr "length" "4,8")])
+
+(define_split
+ [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+ (compare:CC (ior:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" ""))
+ (not:SI (match_operand:SI 2 "gpc_reg_operand" "")))
+ (const_int 0)))
+ (clobber (match_scratch:SI 3 ""))]
+ "reload_completed"
+ [(set (match_dup 3)
+ (ior:SI (not:SI (match_dup 1))
+ (not:SI (match_dup 2))))
+ (set (match_dup 0)
+ (compare:CC (match_dup 3)
+ (const_int 0)))]
+ "")
(define_insn "*nandsi3_internal3"
- [(set (match_operand:CC 3 "cc_reg_operand" "=x")
- (compare:CC (ior:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "%r"))
- (not:SI (match_operand:SI 2 "gpc_reg_operand" "r")))
+ [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
+ (compare:CC (ior:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r"))
+ (not:SI (match_operand:SI 2 "gpc_reg_operand" "r,r")))
(const_int 0)))
- (set (match_operand:SI 0 "gpc_reg_operand" "=r")
- (ior:SI (not:SI (match_dup 1)) (not:SI (match_dup 2))))]
+ (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
+ (ior:SI (not:SI (match_dup 1))
+ (not:SI (match_dup 2))))]
""
- "nand. %0,%1,%2"
- [(set_attr "type" "compare")])
+ "@
+ nand. %0,%1,%2
+ #"
+ [(set_attr "type" "compare")
+ (set_attr "length" "4,8")])
+
+(define_split
+ [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
+ (compare:CC (ior:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" ""))
+ (not:SI (match_operand:SI 2 "gpc_reg_operand" "")))
+ (const_int 0)))
+ (set (match_operand:SI 0 "gpc_reg_operand" "")
+ (ior:SI (not:SI (match_dup 1))
+ (not:SI (match_dup 2))))]
+ "reload_completed"
+ [(set (match_dup 0)
+ (ior:SI (not:SI (match_dup 1))
+ (not:SI (match_dup 2))))
+ (set (match_dup 3)
+ (compare:CC (match_dup 0)
+ (const_int 0)))]
+ "")
(define_insn "*norsi3_internal1"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r")
@@ -2011,25 +2434,64 @@
"nor %0,%1,%2")
(define_insn "*norsi3_internal2"
- [(set (match_operand:CC 0 "cc_reg_operand" "=x")
- (compare:CC (and:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "%r"))
- (not:SI (match_operand:SI 2 "gpc_reg_operand" "r")))
+ [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
+ (compare:CC (and:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r"))
+ (not:SI (match_operand:SI 2 "gpc_reg_operand" "r,r")))
(const_int 0)))
- (clobber (match_scratch:SI 3 "=r"))]
+ (clobber (match_scratch:SI 3 "=r,r"))]
""
- "nor. %3,%1,%2"
- [(set_attr "type" "compare")])
+ "@
+ nor. %3,%1,%2
+ #"
+ [(set_attr "type" "compare")
+ (set_attr "length" "4,8")])
+
+(define_split
+ [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+ (compare:CC (and:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" ""))
+ (not:SI (match_operand:SI 2 "gpc_reg_operand" "")))
+ (const_int 0)))
+ (clobber (match_scratch:SI 3 ""))]
+ "reload_completed"
+ [(set (match_dup 3)
+ (and:SI (not:SI (match_dup 1))
+ (not:SI (match_dup 2))))
+ (set (match_dup 0)
+ (compare:CC (match_dup 3)
+ (const_int 0)))]
+ "")
(define_insn "*norsi3_internal3"
- [(set (match_operand:CC 3 "cc_reg_operand" "=x")
- (compare:CC (and:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "%r"))
- (not:SI (match_operand:SI 2 "gpc_reg_operand" "r")))
+ [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
+ (compare:CC (and:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r"))
+ (not:SI (match_operand:SI 2 "gpc_reg_operand" "r,r")))
(const_int 0)))
- (set (match_operand:SI 0 "gpc_reg_operand" "=r")
- (and:SI (not:SI (match_dup 1)) (not:SI (match_dup 2))))]
+ (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
+ (and:SI (not:SI (match_dup 1))
+ (not:SI (match_dup 2))))]
""
- "nor. %0,%1,%2"
- [(set_attr "type" "compare")])
+ "@
+ nor. %0,%1,%2
+ #"
+ [(set_attr "type" "compare")
+ (set_attr "length" "4,8")])
+
+(define_split
+ [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
+ (compare:CC (and:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" ""))
+ (not:SI (match_operand:SI 2 "gpc_reg_operand" "")))
+ (const_int 0)))
+ (set (match_operand:SI 0 "gpc_reg_operand" "")
+ (and:SI (not:SI (match_dup 1))
+ (not:SI (match_dup 2))))]
+ "reload_completed"
+ [(set (match_dup 0)
+ (and:SI (not:SI (match_dup 1))
+ (not:SI (match_dup 2))))
+ (set (match_dup 3)
+ (compare:CC (match_dup 0)
+ (const_int 0)))]
+ "")
;; maskir insn. We need four forms because things might be in arbitrary
;; orders. Don't define forms that only set CR fields because these
@@ -3704,7 +4166,7 @@
(unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "")))
(use (match_operand:SI 2 "gpc_reg_operand" ""))
(use (match_operand:DF 3 "gpc_reg_operand" ""))
- (clobber (match_operand 4 "gpc_reg_operand" "=b"))
+ (clobber (match_operand 4 "gpc_reg_operand" ""))
(clobber (reg:DF 76))]
"TARGET_HARD_FLOAT"
[(set (match_dup 4)
@@ -3718,7 +4180,7 @@
(match_dup 5)] 13)) ;; high word
(set (match_dup 0)
(unspec [(match_dup 5)
- (reg:SI 1)] 14))
+ (match_dup 4)] 14))
(set (match_dup 0)
(minus:DF (match_dup 0)
(match_dup 3)))]
@@ -5304,14 +5766,14 @@
;; registers, since almost all uses of this will need it
;; in a base register shortly.
(define_insn "elf_high"
- [(set (match_operand:SI 0 "register_operand" "=b")
+ [(set (match_operand:SI 0 "gpc_reg_operand" "=b")
(high:SI (match_operand 1 "" "")))]
"TARGET_ELF && !TARGET_64BIT"
"{liu|lis} %0,%1@ha")
(define_insn "elf_low"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (lo_sum:SI (match_operand:SI 1 "register_operand" "b")
+ [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
+ (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
(match_operand 2 "" "")))]
"TARGET_ELF && !TARGET_64BIT"
"{cal|la} %0,%2@l(%1)")
@@ -5319,7 +5781,7 @@
;; Set up a register with a value from the GOT table
(define_expand "movsi_got"
- [(set (match_operand:SI 0 "register_operand" "")
+ [(set (match_operand:SI 0 "gpc_reg_operand" "")
(unspec [(match_operand:SI 1 "got_operand" "")
(match_dup 2)] 8))]
"(DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS) && flag_pic == 1"
@@ -5347,9 +5809,9 @@
}")
(define_insn "*movsi_got_internal"
- [(set (match_operand:SI 0 "register_operand" "=r")
+ [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(unspec [(match_operand:SI 1 "got_no_const_operand" "")
- (match_operand:SI 2 "register_operand" "b")] 8))]
+ (match_operand:SI 2 "gpc_reg_operand" "b")] 8))]
"(DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS) && flag_pic == 1"
"{l|lwz} %0,%a1@got(%2)"
[(set_attr "type" "load")])
@@ -5359,7 +5821,7 @@
;; Force final to split this insn (if it hasn't been split already) to
;; avoid having to create a suitable output template.
(define_insn "*movsi_got_internal_mem"
- [(set (match_operand:SI 0 "register_operand" "=r")
+ [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(unspec [(match_operand:SI 1 "got_no_const_operand" "")
(match_operand:SI 2 "memory_operand" "m")] 8))]
"(DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)
@@ -5372,7 +5834,7 @@
;; Used by sched, shorten_branches and final when the GOT pseudo reg
;; didn't get allocated to a hard register.
(define_split
- [(set (match_operand:SI 0 "register_operand" "=r")
+ [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(unspec [(match_operand:SI 1 "got_no_const_operand" "")
(match_operand:SI 2 "memory_operand" "m")] 8))]
"(DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)
@@ -5399,6 +5861,13 @@
if (GET_CODE (operands[1]) == CONST_DOUBLE)
operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
+ /* Only a tiny bit of handling for CONSTANT_P_RTX is necessary. */
+ if (GET_CODE (operands[1]) == CONSTANT_P_RTX)
+ {
+ emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
+ DONE;
+ }
+
/* Use default pattern for address of ELF small data */
if (TARGET_ELF
&& (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)
@@ -5420,8 +5889,7 @@
&& !flag_pic
&& CONSTANT_P (operands[1])
&& GET_CODE (operands[1]) != HIGH
- && GET_CODE (operands[1]) != CONST_INT
- && GET_CODE (operands[1]) != CONSTANT_P_RTX)
+ && GET_CODE (operands[1]) != CONST_INT)
{
rtx target = (reload_completed || reload_in_progress)
? operands[0] : gen_reg_rtx (SImode);
@@ -5475,7 +5943,6 @@
if ((!TARGET_WINDOWS_NT || DEFAULT_ABI != ABI_NT)
&& CONSTANT_P (operands[1])
&& GET_CODE (operands[1]) != CONST_INT
- && GET_CODE (operands[1]) != CONSTANT_P_RTX
&& GET_CODE (operands[1]) != HIGH
&& ! LEGITIMATE_CONSTANT_POOL_ADDRESS_P (operands[1]))
{
@@ -5574,8 +6041,7 @@
operands[1] = force_reg (HImode, operands[1]);
if (CONSTANT_P (operands[1])
- && GET_CODE (operands[1]) != CONST_INT
- && GET_CODE (operands[1]) != CONSTANT_P_RTX)
+ && GET_CODE (operands[1]) != CONST_INT)
{
operands[1] = force_const_mem (HImode, operands[1]);
if (! memory_address_p (HImode, XEXP (operands[1], 0))
@@ -5611,8 +6077,7 @@
operands[1] = force_reg (QImode, operands[1]);
if (CONSTANT_P (operands[1])
- && GET_CODE (operands[1]) != CONST_INT
- && GET_CODE (operands[1]) != CONSTANT_P_RTX)
+ && GET_CODE (operands[1]) != CONST_INT)
{
operands[1] = force_const_mem (QImode, operands[1]);
if (! memory_address_p (QImode, XEXP (operands[1], 0))
@@ -5686,80 +6151,23 @@
&& REGNO (SUBREG_REG (operands[1])) < FIRST_PSEUDO_REGISTER)
operands[1] = alter_subreg (operands[1]);
- if (TARGET_SOFT_FLOAT && GET_CODE (operands[0]) == MEM)
- operands[1] = force_reg (SFmode, operands[1]);
-
- else if (TARGET_HARD_FLOAT)
+ if (GET_CODE (operands[0]) == MEM)
{
- if (! TARGET_POWERPC64
- && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < 32)
- {
- /* If this is a store to memory or another integer register do the
- move directly. Otherwise store to a temporary stack slot and
- load from there into a floating point register. */
-
- if (GET_CODE (operands[0]) == MEM
- || (GET_CODE (operands[0]) == REG
- && (REGNO (operands[0]) < 32
- || (reload_in_progress
- && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER))))
- {
- emit_move_insn (operand_subword (operands[0], 0, 0, SFmode),
- operand_subword (operands[1], 0, 0, SFmode));
- DONE;
- }
- else
- {
- rtx stack_slot = assign_stack_temp (SFmode, 4, 0);
-
- emit_move_insn (stack_slot, operands[1]);
- emit_move_insn (operands[0], stack_slot);
- DONE;
- }
- }
-
- if (GET_CODE (operands[0]) == MEM)
+ /* If operands[1] is a register, it may have double-precision data
+ in it, so truncate it to single precision. We need not do
+ this for POWERPC. */
+ if (! TARGET_POWERPC && TARGET_HARD_FLOAT
+ && GET_CODE (operands[1]) == REG
+ && (FP_REGNO_P (REGNO (operands[1]))
+ || REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER))
{
- /* If operands[1] is a register, it may have double-precision data
- in it, so truncate it to single precision. We need not do
- this for POWERPC. */
- if (! TARGET_POWERPC && TARGET_HARD_FLOAT
- && GET_CODE (operands[1]) == REG)
- {
- rtx newreg
- = reload_in_progress ? operands[1] : gen_reg_rtx (SFmode);
- emit_insn (gen_aux_truncdfsf2 (newreg, operands[1]));
- operands[1] = newreg;
- }
-
- operands[1] = force_reg (SFmode, operands[1]);
+ rtx newreg
+ = reload_in_progress ? operands[1] : gen_reg_rtx (SFmode);
+ emit_insn (gen_aux_truncdfsf2 (newreg, operands[1]));
+ operands[1] = newreg;
}
- if (! TARGET_POWERPC64
- && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < 32)
- {
- if (GET_CODE (operands[1]) == MEM
-#if HOST_FLOAT_FORMAT == TARGET_FLOAT_FORMAT && ! defined(REAL_IS_NOT_DOUBLE)
- || GET_CODE (operands[1]) == CONST_DOUBLE
-#endif
- || (GET_CODE (operands[1]) == REG
- && (REGNO (operands[1]) < 32
- || (reload_in_progress
- && REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER))))
- {
- emit_move_insn (operand_subword (operands[0], 0, 0, SFmode),
- operand_subword (operands[1], 0, 0, SFmode));
- DONE;
- }
- else
- {
- rtx stack_slot = assign_stack_temp (SFmode, 4, 0);
-
- emit_move_insn (stack_slot, operands[1]);
- emit_move_insn (operands[0], stack_slot);
- DONE;
- }
- }
+ operands[1] = force_reg (SFmode, operands[1]);
}
if (CONSTANT_P (operands[1]) && TARGET_HARD_FLOAT)
@@ -5775,7 +6183,7 @@
(define_split
[(set (match_operand:SF 0 "gpc_reg_operand" "")
(match_operand:SF 1 "const_double_operand" ""))]
- "! TARGET_POWERPC64 && reload_completed
+ "reload_completed
&& ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
|| (GET_CODE (operands[0]) == SUBREG
&& GET_CODE (SUBREG_REG (operands[0])) == REG
@@ -5789,44 +6197,30 @@
REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
REAL_VALUE_TO_TARGET_SINGLE (rv, l);
- operands[2] = operand_subword (operands[0], 0, 0, SFmode);
- operands[3] = GEN_INT(l);
-}")
-
-(define_split
- [(set (match_operand:SF 0 "gpc_reg_operand" "")
- (match_operand:SF 1 "const_double_operand" ""))]
- "TARGET_POWERPC64 && reload_completed
- && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
- || (GET_CODE (operands[0]) == SUBREG
- && GET_CODE (SUBREG_REG (operands[0])) == REG
- && REGNO (SUBREG_REG (operands[0])) <= 31))"
- [(set (match_dup 2) (match_dup 3))]
- "
-{
- long l;
- REAL_VALUE_TYPE rv;
-
- REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
- REAL_VALUE_TO_TARGET_SINGLE (rv, l);
+ if (! TARGET_POWERPC64)
+ operands[2] = operand_subword (operands[0], 0, 0, SFmode);
+ else
+ operands[2] = gen_lowpart (SImode, operands[0]);
- operands[2] = gen_lowpart (SImode, operands[0]);
operands[3] = GEN_INT(l);
}")
(define_insn "*movsf_hardfloat"
- [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,m,!r,!r")
- (match_operand:SF 1 "input_operand" "f,m,f,G,Fn"))]
+ [(set (match_operand:SF 0 "nonimmediate_operand" "=!r,!r,m,f,f,m,!r,!r")
+ (match_operand:SF 1 "input_operand" "r,m,r,f,m,f,G,Fn"))]
"(gpc_reg_operand (operands[0], SFmode)
|| gpc_reg_operand (operands[1], SFmode)) && TARGET_HARD_FLOAT"
"@
+ mr %0,%1
+ {l%U1%X1|lwz%U1%X1} %0,%1
+ {st%U0%X0|stw%U0%X0} %1,%0
fmr %0,%1
lfs%U1%X1 %0,%1
stfs%U0%X0 %1,%0
#
#"
- [(set_attr "type" "fp,fpload,fpstore,*,*")
- (set_attr "length" "4,4,4,4,8")])
+ [(set_attr "type" "*,load,store,fp,fpload,fpstore,*,*")
+ (set_attr "length" "4,4,4,4,4,4,4,8")])
(define_insn "*movsf_softfloat"
[(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m,r,r,r,r,r")
@@ -5941,8 +6335,8 @@
[(set (match_operand:DF 0 "nonimmediate_operand" "=!r,??r,o,!r,!r,!r,f,f,m")
(match_operand:DF 1 "input_operand" "r,o,r,G,H,F,f,m,f"))]
"! TARGET_POWERPC64 && TARGET_HARD_FLOAT
- && (register_operand (operands[0], DFmode)
- || register_operand (operands[1], DFmode))"
+ && (gpc_reg_operand (operands[0], DFmode)
+ || gpc_reg_operand (operands[1], DFmode))"
"*
{
switch (which_alternative)
@@ -5988,8 +6382,8 @@
[(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m,r,r,r")
(match_operand:DF 1 "input_operand" "r,m,r,G,H,F"))]
"! TARGET_POWERPC64 && TARGET_SOFT_FLOAT
- && (register_operand (operands[0], DFmode)
- || register_operand (operands[1], DFmode))"
+ && (gpc_reg_operand (operands[0], DFmode)
+ || gpc_reg_operand (operands[1], DFmode))"
"*
{
switch (which_alternative)
@@ -6029,8 +6423,8 @@
[(set (match_operand:DF 0 "nonimmediate_operand" "=!r,??r,m,!r,!r,!r,f,f,m")
(match_operand:DF 1 "input_operand" "r,m,r,G,H,F,f,m,f"))]
"TARGET_POWERPC64 && TARGET_HARD_FLOAT
- && (register_operand (operands[0], DFmode)
- || register_operand (operands[1], DFmode))"
+ && (gpc_reg_operand (operands[0], DFmode)
+ || gpc_reg_operand (operands[1], DFmode))"
"@
mr %0,%1
ld%U1%X1 %0,%1
@@ -6048,8 +6442,8 @@
[(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m,r,r,r")
(match_operand:DF 1 "input_operand" "r,m,r,G,H,F"))]
"TARGET_POWERPC64 && TARGET_SOFT_FLOAT
- && (register_operand (operands[0], DFmode)
- || register_operand (operands[1], DFmode))"
+ && (gpc_reg_operand (operands[0], DFmode)
+ || gpc_reg_operand (operands[1], DFmode))"
"@
mr %0,%1
ld%U1%X1 %0,%1
@@ -6083,11 +6477,17 @@
)
operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
+ /* Only a tiny bit of handling for CONSTANT_P_RTX is necessary. */
+ if (GET_CODE (operands[1]) == CONSTANT_P_RTX)
+ {
+ emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
+ DONE;
+ }
+
if (TARGET_64BIT
&& CONSTANT_P (operands[1])
#if HOST_BITS_PER_WIDE_INT == 32
&& GET_CODE (operands[1]) != CONST_INT
- && GET_CODE (operands[1]) != CONSTANT_P_RTX
#endif
&& ! easy_fp_constant (operands[1], DImode)
&& ! LEGITIMATE_CONSTANT_POOL_ADDRESS_P (operands[1]))
@@ -6187,13 +6587,18 @@
{
operands[2] = gen_rtx_SUBREG (SImode, operands[0], WORDS_BIG_ENDIAN == 0);
operands[3] = gen_rtx_SUBREG (SImode, operands[0], WORDS_BIG_ENDIAN != 0);
+#if HOST_BITS_PER_WIDE_INT == 32
operands[4] = (INTVAL (operands[1]) & 0x80000000) ? constm1_rtx : const0_rtx;
+#else
+ operands[4] = (HOST_WIDE_INT) INTVAL (operands[1]) >> 32;
+ operands[1] = INTVAL (operands[1]) & 0xffffffff;
+#endif
}")
(define_split
[(set (match_operand:DI 0 "gpc_reg_operand" "")
(match_operand:DI 1 "const_double_operand" ""))]
- "! TARGET_POWERPC64 && reload_completed"
+ "HOST_BITS_PER_WIDE_INT == 32 && ! TARGET_POWERPC64 && reload_completed"
[(set (match_dup 2) (match_dup 4))
(set (match_dup 3) (match_dup 5))]
"
@@ -6573,7 +6978,7 @@
(define_insn ""
[(match_parallel 0 "load_multiple_operation"
[(set (match_operand:SI 1 "gpc_reg_operand" "=r")
- (mem:SI (match_operand:SI 2 "register_operand" "b")))])]
+ (mem:SI (match_operand:SI 2 "gpc_reg_operand" "b")))])]
"TARGET_STRING"
"*
{
@@ -6684,7 +7089,7 @@
(define_insn ""
[(match_parallel 0 "store_multiple_operation"
- [(set (mem:SI (match_operand:SI 1 "register_operand" "b"))
+ [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
(match_operand:SI 2 "gpc_reg_operand" "r"))
(clobber (match_scratch:SI 3 "X"))])]
"TARGET_STRING && !TARGET_POWER"
@@ -6732,11 +7137,11 @@
"")
(define_insn ""
- [(set (mem:BLK (match_operand:SI 0 "register_operand" "b"))
- (mem:BLK (match_operand:SI 1 "register_operand" "b")))
+ [(set (mem:BLK (match_operand:SI 0 "gpc_reg_operand" "b"))
+ (mem:BLK (match_operand:SI 1 "gpc_reg_operand" "b")))
(use (match_operand:SI 2 "immediate_operand" "i"))
(use (match_operand:SI 3 "immediate_operand" "i"))
- (clobber (match_operand:SI 4 "register_operand" "=r"))
+ (clobber (match_operand:SI 4 "gpc_reg_operand" "=r"))
(clobber (reg:SI 6))
(clobber (reg:SI 7))
(clobber (reg:SI 8))
@@ -6755,11 +7160,11 @@
(set_attr "length" "8")])
(define_insn ""
- [(set (mem:BLK (match_operand:SI 0 "register_operand" "b"))
- (mem:BLK (match_operand:SI 1 "register_operand" "b")))
+ [(set (mem:BLK (match_operand:SI 0 "gpc_reg_operand" "b"))
+ (mem:BLK (match_operand:SI 1 "gpc_reg_operand" "b")))
(use (match_operand:SI 2 "immediate_operand" "i"))
(use (match_operand:SI 3 "immediate_operand" "i"))
- (clobber (match_operand:SI 4 "register_operand" "=r"))
+ (clobber (match_operand:SI 4 "gpc_reg_operand" "=r"))
(clobber (reg:SI 6))
(clobber (reg:SI 7))
(clobber (reg:SI 8))
@@ -6795,11 +7200,11 @@
"")
(define_insn ""
- [(set (mem:BLK (match_operand:SI 0 "register_operand" "b"))
- (mem:BLK (match_operand:SI 1 "register_operand" "b")))
+ [(set (mem:BLK (match_operand:SI 0 "gpc_reg_operand" "b"))
+ (mem:BLK (match_operand:SI 1 "gpc_reg_operand" "b")))
(use (match_operand:SI 2 "immediate_operand" "i"))
(use (match_operand:SI 3 "immediate_operand" "i"))
- (clobber (match_operand:SI 4 "register_operand" "=r"))
+ (clobber (match_operand:SI 4 "gpc_reg_operand" "=r"))
(clobber (reg:SI 8))
(clobber (reg:SI 9))
(clobber (reg:SI 10))
@@ -6816,11 +7221,11 @@
(set_attr "length" "8")])
(define_insn ""
- [(set (mem:BLK (match_operand:SI 0 "register_operand" "b"))
- (mem:BLK (match_operand:SI 1 "register_operand" "b")))
+ [(set (mem:BLK (match_operand:SI 0 "gpc_reg_operand" "b"))
+ (mem:BLK (match_operand:SI 1 "gpc_reg_operand" "b")))
(use (match_operand:SI 2 "immediate_operand" "i"))
(use (match_operand:SI 3 "immediate_operand" "i"))
- (clobber (match_operand:SI 4 "register_operand" "=r"))
+ (clobber (match_operand:SI 4 "gpc_reg_operand" "=r"))
(clobber (reg:SI 8))
(clobber (reg:SI 9))
(clobber (reg:SI 10))
@@ -6852,11 +7257,11 @@
"")
(define_insn ""
- [(set (mem:BLK (match_operand:SI 0 "register_operand" "b"))
- (mem:BLK (match_operand:SI 1 "register_operand" "b")))
+ [(set (mem:BLK (match_operand:SI 0 "gpc_reg_operand" "b"))
+ (mem:BLK (match_operand:SI 1 "gpc_reg_operand" "b")))
(use (match_operand:SI 2 "immediate_operand" "i"))
(use (match_operand:SI 3 "immediate_operand" "i"))
- (clobber (match_operand:SI 4 "register_operand" "=r"))
+ (clobber (match_operand:SI 4 "gpc_reg_operand" "=r"))
(clobber (reg:SI 10))
(clobber (reg:SI 11))
(clobber (reg:SI 12))
@@ -6871,11 +7276,11 @@
(set_attr "length" "8")])
(define_insn ""
- [(set (mem:BLK (match_operand:SI 0 "register_operand" "b"))
- (mem:BLK (match_operand:SI 1 "register_operand" "b")))
+ [(set (mem:BLK (match_operand:SI 0 "gpc_reg_operand" "b"))
+ (mem:BLK (match_operand:SI 1 "gpc_reg_operand" "b")))
(use (match_operand:SI 2 "immediate_operand" "i"))
(use (match_operand:SI 3 "immediate_operand" "i"))
- (clobber (match_operand:SI 4 "register_operand" "=r"))
+ (clobber (match_operand:SI 4 "gpc_reg_operand" "=r"))
(clobber (reg:SI 10))
(clobber (reg:SI 11))
(clobber (reg:SI 12))
@@ -6901,8 +7306,8 @@
"")
(define_insn ""
- [(set (mem:BLK (match_operand:SI 0 "register_operand" "b"))
- (mem:BLK (match_operand:SI 1 "register_operand" "b")))
+ [(set (mem:BLK (match_operand:SI 0 "gpc_reg_operand" "b"))
+ (mem:BLK (match_operand:SI 1 "gpc_reg_operand" "b")))
(use (match_operand:SI 2 "immediate_operand" "i"))
(use (match_operand:SI 3 "immediate_operand" "i"))
(clobber (match_scratch:DI 4 "=&r"))
@@ -6914,8 +7319,8 @@
(set_attr "length" "8")])
(define_insn ""
- [(set (mem:BLK (match_operand:SI 0 "register_operand" "b"))
- (mem:BLK (match_operand:SI 1 "register_operand" "b")))
+ [(set (mem:BLK (match_operand:SI 0 "gpc_reg_operand" "b"))
+ (mem:BLK (match_operand:SI 1 "gpc_reg_operand" "b")))
(use (match_operand:SI 2 "immediate_operand" "i"))
(use (match_operand:SI 3 "immediate_operand" "i"))
(clobber (match_scratch:DI 4 "=&r"))
@@ -6938,8 +7343,8 @@
"")
(define_insn ""
- [(set (mem:BLK (match_operand:SI 0 "register_operand" "b"))
- (mem:BLK (match_operand:SI 1 "register_operand" "b")))
+ [(set (mem:BLK (match_operand:SI 0 "gpc_reg_operand" "b"))
+ (mem:BLK (match_operand:SI 1 "gpc_reg_operand" "b")))
(use (match_operand:SI 2 "immediate_operand" "i"))
(use (match_operand:SI 3 "immediate_operand" "i"))
(clobber (match_scratch:SI 4 "=&r"))
@@ -6951,8 +7356,8 @@
(set_attr "length" "8")])
(define_insn ""
- [(set (mem:BLK (match_operand:SI 0 "register_operand" "b"))
- (mem:BLK (match_operand:SI 1 "register_operand" "b")))
+ [(set (mem:BLK (match_operand:SI 0 "gpc_reg_operand" "b"))
+ (mem:BLK (match_operand:SI 1 "gpc_reg_operand" "b")))
(use (match_operand:SI 2 "immediate_operand" "i"))
(use (match_operand:SI 3 "immediate_operand" "i"))
(clobber (match_scratch:SI 4 "=&r"))
@@ -7223,7 +7628,7 @@
;; We move the back-chain and decrement the stack pointer.
(define_expand "allocate_stack"
- [(set (match_operand 0 "register_operand" "=r")
+ [(set (match_operand 0 "gpc_reg_operand" "=r")
(minus (reg 1) (match_operand 1 "reg_or_short_operand" "")))
(set (reg 1)
(minus (reg 1) (match_dup 1)))]
@@ -7297,14 +7702,16 @@
;; save area is a memory location.
(define_expand "save_stack_function"
- [(use (const_int 0))]
+ [(match_operand 0 "any_operand" "")
+ (match_operand 1 "any_operand" "")]
""
- "")
+ "DONE;")
(define_expand "restore_stack_function"
- [(use (const_int 0))]
+ [(match_operand 0 "any_operand" "")
+ (match_operand 1 "any_operand" "")]
""
- "")
+ "DONE;")
(define_expand "restore_stack_block"
[(use (match_operand 0 "register_operand" ""))
@@ -7381,64 +7788,64 @@
;; to move the load of the new TOC before any loads from the TOC.
(define_insn "call_indirect_aix32"
- [(call (mem:SI (match_operand:SI 0 "register_operand" "b"))
+ [(call (mem:SI (match_operand:SI 0 "gpc_reg_operand" "b"))
(match_operand 1 "const_int_operand" "n"))
(use (match_operand 2 "const_int_operand" "n"))
- (use (match_operand 3 "offsettable_addr_operand" "p"))
- (use (match_operand 4 "register_operand" "r"))
- (clobber (match_operand 5 "register_operand" "=r"))
+ (use (match_operand 3 "offsettable_mem_operand" "o"))
+ (use (match_operand 4 "gpc_reg_operand" "r"))
+ (clobber (match_operand 5 "gpc_reg_operand" "=r"))
(clobber (match_scratch:SI 6 "=&r"))
(clobber (match_scratch:SI 7 "=l"))]
"DEFAULT_ABI == ABI_AIX
&& (INTVAL (operands[2]) == CALL_NORMAL || (INTVAL (operands[2]) & CALL_LONG) != 0)"
- "{st|stw} %4,%a3\;{l|lwz} %6,0(%0)\;{l|lwz} %4,4(%0)\;mt%7 %6\;{l|lwz} %5,8(%0)\;{brl|blrl}\;{l|lwz} %4,%a3"
+ "{st|stw} %4,%3\;{l|lwz} %6,0(%0)\;{l|lwz} %4,4(%0)\;mt%7 %6\;{l|lwz} %5,8(%0)\;{brl|blrl}\;{l|lwz} %4,%3"
[(set_attr "type" "load")
(set_attr "length" "28")])
(define_insn "call_indirect_aix64"
- [(call (mem:SI (match_operand:DI 0 "register_operand" "b"))
+ [(call (mem:SI (match_operand:DI 0 "gpc_reg_operand" "b"))
(match_operand 1 "const_int_operand" "n"))
(use (match_operand 2 "const_int_operand" "n"))
- (use (match_operand 3 "offsettable_addr_operand" "p"))
- (use (match_operand 4 "register_operand" "r"))
- (clobber (match_operand 5 "register_operand" "=r"))
+ (use (match_operand 3 "offsettable_mem_operand" "o"))
+ (use (match_operand 4 "gpc_reg_operand" "r"))
+ (clobber (match_operand 5 "gpc_reg_operand" "=r"))
(clobber (match_scratch:SI 6 "=&r"))
(clobber (match_scratch:SI 7 "=l"))]
"TARGET_64BIT && DEFAULT_ABI == ABI_AIX
&& (INTVAL (operands[2]) == CALL_NORMAL || (INTVAL (operands[2]) & CALL_LONG) != 0)"
- "std %4,%a3\;ld %6,0(%0)\;ld %4,8(%0)\;mt%7 %6\;ld %5,16(%0)\;blrl\;ld %4,%a3"
+ "std %4,%3\;ld %6,0(%0)\;ld %4,8(%0)\;mt%7 %6\;ld %5,16(%0)\;blrl\;ld %4,%3"
[(set_attr "type" "load")
(set_attr "length" "28")])
(define_insn "call_value_indirect_aix32"
[(set (match_operand 0 "register_operand" "fg")
- (call (mem:SI (match_operand:SI 1 "register_operand" "b"))
+ (call (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
(match_operand 2 "const_int_operand" "n")))
(use (match_operand 3 "const_int_operand" "n"))
- (use (match_operand 4 "offsettable_addr_operand" "p"))
- (use (match_operand 5 "register_operand" "r"))
- (clobber (match_operand 6 "register_operand" "=r"))
+ (use (match_operand 4 "offsettable_mem_operand" "o"))
+ (use (match_operand 5 "gpc_reg_operand" "r"))
+ (clobber (match_operand 6 "gpc_reg_operand" "=r"))
(clobber (match_scratch:SI 7 "=&r"))
(clobber (match_scratch:SI 8 "=l"))]
"DEFAULT_ABI == ABI_AIX
&& (INTVAL (operands[3]) == CALL_NORMAL || (INTVAL (operands[3]) & CALL_LONG) != 0)"
- "{st|stw} %5,%a4\;{l|lwz} %7,0(%1)\;{l|lwz} %5,4(%1)\;mt%8 %7\;{l|lwz} %6,8(%1)\;{brl|blrl}\;{l|lwz} %5,%a4"
+ "{st|stw} %5,%4\;{l|lwz} %7,0(%1)\;{l|lwz} %5,4(%1)\;mt%8 %7\;{l|lwz} %6,8(%1)\;{brl|blrl}\;{l|lwz} %5,%4"
[(set_attr "type" "load")
(set_attr "length" "28")])
(define_insn "call_value_indirect_aix64"
[(set (match_operand 0 "register_operand" "fg")
- (call (mem:SI (match_operand:DI 1 "register_operand" "b"))
+ (call (mem:SI (match_operand:DI 1 "gpc_reg_operand" "b"))
(match_operand 2 "const_int_operand" "n")))
(use (match_operand 3 "const_int_operand" "n"))
- (use (match_operand 4 "offsettable_addr_operand" "p"))
- (use (match_operand 5 "register_operand" "r"))
- (clobber (match_operand 6 "register_operand" "=r"))
+ (use (match_operand 4 "offsettable_mem_operand" "o"))
+ (use (match_operand 5 "gpc_reg_operand" "r"))
+ (clobber (match_operand 6 "gpc_reg_operand" "=r"))
(clobber (match_scratch:SI 7 "=&r"))
(clobber (match_scratch:SI 8 "=l"))]
"TARGET_64BIT && DEFAULT_ABI == ABI_AIX
&& (INTVAL (operands[3]) == CALL_NORMAL || (INTVAL (operands[3]) & CALL_LONG) != 0)"
- "std %5,%a4\;ld %7,0(%1)\;ld %5,8(%1)\;mt%8 %7\;ld %6,16(%1)\;blrl\;ld %5,%a4"
+ "std %5,%4\;ld %7,0(%1)\;ld %5,8(%1)\;mt%8 %7\;ld %6,16(%1)\;blrl\;ld %5,%4"
[(set_attr "type" "load")
(set_attr "length" "28")])
@@ -7457,11 +7864,11 @@
;; to move the load of the new TOC before any loads from the TOC.
(define_insn "call_indirect_nt"
- [(call (mem:SI (match_operand:SI 0 "register_operand" "b"))
+ [(call (mem:SI (match_operand:SI 0 "gpc_reg_operand" "b"))
(match_operand 1 "const_int_operand" "n"))
(use (match_operand 2 "const_int_operand" "n"))
- (use (match_operand 3 "offsettable_addr_operand" "p"))
- (use (match_operand 4 "register_operand" "r"))
+ (use (match_operand 3 "offsettable_mem_operand" "o"))
+ (use (match_operand 4 "gpc_reg_operand" "r"))
(clobber (match_scratch:SI 5 "=&r"))
(clobber (match_scratch:SI 6 "=l"))]
"DEFAULT_ABI == ABI_NT
@@ -7472,11 +7879,11 @@
(define_insn "call_value_indirect_nt"
[(set (match_operand 0 "register_operand" "fg")
- (call (mem:SI (match_operand:SI 1 "register_operand" "b"))
+ (call (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
(match_operand 2 "const_int_operand" "n")))
(use (match_operand 3 "const_int_operand" "n"))
- (use (match_operand 4 "offsettable_addr_operand" "p"))
- (use (match_operand 5 "register_operand" "r"))
+ (use (match_operand 4 "offsettable_mem_operand" "o"))
+ (use (match_operand 5 "gpc_reg_operand" "r"))
(clobber (match_scratch:SI 6 "=&r"))
(clobber (match_scratch:SI 7 "=l"))]
"DEFAULT_ABI == ABI_NT
@@ -7616,7 +8023,7 @@
if (GET_CODE (operands[1]) != SYMBOL_REF
|| (INTVAL (operands[3]) & CALL_LONG) != 0)
{
- if (INTVAL (operands[2]) & CALL_LONG)
+ if (INTVAL (operands[3]) & CALL_LONG)
operands[1] = rs6000_longcall_ref (operands[1]);
if (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_AIX_NODESC || DEFAULT_ABI == ABI_SOLARIS)
@@ -8671,7 +9078,7 @@
""
"@
xor %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3
- {sfi|subfic} %4,%1,0\;{aze.|addze.} %0,%3
+ {sfi|subfic} %4,%1,0\;{aze.|addze.} %4,%3
{xoril|xori} %4,%1,%b2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3
{xoriu|xoris} %4,%1,%u2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3
{sfi|subfic} %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3"
@@ -8692,7 +9099,7 @@
""
"@
xor %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %0,%3
- {sfi|subfic} %4,%1,0\;{aze.|addze.} %4,%3
+ {sfi|subfic} %4,%1,0\;{aze.|addze.} %0,%3
{xoril|xori} %4,%1,%b2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %0,%3
{xoriu|xoris} %4,%1,%u2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %0,%3
{sfi|subfic} %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %0,%3"
@@ -9099,16 +9506,14 @@
(set_attr "length" "12")])
(define_insn ""
- [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r")
- (plus:SI (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
- (match_operand:SI 2 "reg_or_neg_short_operand" "r,r,P,P"))
- (match_operand:SI 3 "reg_or_short_operand" "r,I,r,I")))
- (clobber (match_scratch:SI 4 "=&r,r,&r,r"))]
+ [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
+ (plus:SI (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
+ (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))
+ (match_operand:SI 3 "reg_or_short_operand" "rI,rI")))
+ (clobber (match_scratch:SI 4 "=&r,&r"))]
""
"@
{sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;{sf%I3|subf%I3c} %0,%4,%3
- {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;{sf%I3|subf%I3c} %0,%4,%3
- {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;{sf%I3|subf%I3c} %0,%4,%3
{ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;{sf%I3|subf%I3c} %0,%4,%3"
[(set_attr "length" "12")])
@@ -9335,7 +9740,7 @@
""
"@
{sf|subfc} %4,%2,%1\;{aze.|addze.} %0,%3
- {ai|addic} %4,%1,%n2\;{aze.|addze.} %4,%3"
+ {ai|addic} %4,%1,%n2\;{aze.|addze.} %0,%3"
[(set_attr "type" "compare")
(set_attr "length" "8")])
@@ -9457,7 +9862,7 @@
(const_int 0)))
(clobber (match_scratch:SI 3 "=&r"))]
""
- "{a|addc} %3,%1,%1\;{sfe|subfe} %3,%1,%3\;{aze.|addze.} %0,%2"
+ "{a|addc} %3,%1,%1\;{sfe|subfe} %3,%1,%3\;{aze.|addze.} %3,%2"
[(set_attr "type" "compare")
(set_attr "length" "12")])
@@ -9472,7 +9877,7 @@
(plus:SI (gt:SI (match_dup 1) (const_int 0)) (match_dup 2)))
(clobber (match_scratch:SI 3 "=&r"))]
""
- "{a|addc} %3,%1,%1\;{sfe|subfe} %3,%1,%3\;{aze.|addze.} %3,%2"
+ "{a|addc} %3,%1,%1\;{sfe|subfe} %3,%1,%3\;{aze.|addze.} %0,%2"
[(set_attr "type" "compare")
(set_attr "length" "12")])
@@ -9552,17 +9957,16 @@
(set_attr "length" "12")])
(define_insn ""
- [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r")
- (plus:SI (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r")
- (match_operand:SI 2 "reg_or_short_operand" "I,r,rI"))
- (match_operand:SI 3 "reg_or_short_operand" "r,r,I")))
- (clobber (match_scratch:SI 4 "=&r,&r,&r"))]
+ [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
+ (plus:SI (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
+ (match_operand:SI 2 "reg_or_short_operand" "I,rI"))
+ (match_operand:SI 3 "reg_or_short_operand" "r,rI")))
+ (clobber (match_scratch:SI 4 "=&r,&r"))]
""
"@
{ai|addic} %4,%1,%k2\;{aze|addze} %0,%3
- {sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;{sf%I3|subf%I3c} %0,%4,%3
{sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;{sf%I3|subf%I3c} %0,%4,%3"
- [(set_attr "length" "8,12,12")])
+ [(set_attr "length" "8,12")])
(define_insn ""
[(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
@@ -9574,8 +9978,8 @@
(clobber (match_scratch:SI 4 "=&r,&r"))]
""
"@
- {ai|addic} %4,%1,%k2\;{aze.|addze.} %0,%3
- {sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %0,%4,%3"
+ {ai|addic} %4,%1,%k2\;{aze.|addze.} %4,%3
+ {sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %4,%4,%3"
[(set_attr "type" "compare")
(set_attr "length" "8,12")])
diff --git a/gcc/config/rs6000/sol2.h b/gcc/config/rs6000/sol2.h
index 0a73c4d26d5..0f1b13b313b 100644
--- a/gcc/config/rs6000/sol2.h
+++ b/gcc/config/rs6000/sol2.h
@@ -17,7 +17,8 @@ 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
#include "rs6000/sysv4le.h"
diff --git a/gcc/config/rs6000/sysv4.h b/gcc/config/rs6000/sysv4.h
index 2b7e1ed4b48..e945e80d197 100644
--- a/gcc/config/rs6000/sysv4.h
+++ b/gcc/config/rs6000/sysv4.h
@@ -1,5 +1,5 @@
/* Target definitions for GNU compiler for PowerPC running System V.4
- Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1995, 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
Contributed by Cygnus Support.
This file is part of GNU CC.
@@ -107,8 +107,8 @@ extern enum rs6000_sdata_type rs6000_sdata;
#define RS6000_ABI_NAME "sysv"
/* Strings provided by SUBTARGET_OPTIONS */
-extern char *rs6000_abi_name;
-extern char *rs6000_sdata_name;
+extern const char *rs6000_abi_name;
+extern const char *rs6000_sdata_name;
#define SUBTARGET_OPTIONS \
{ "call-", &rs6000_abi_name}, \
@@ -393,12 +393,9 @@ do { \
/* Define this macro to be the value 1 if instructions will fail to
work if given data not on the nominal alignment. If instructions
- will merely go slower in that case, define this macro as 0.
-
- Note, little endian systems trap on unaligned addresses, so never
- turn off strict alignment in that case. */
+ will merely go slower in that case, define this macro as 0. */
#undef STRICT_ALIGNMENT
-#define STRICT_ALIGNMENT (TARGET_STRICT_ALIGN || TARGET_LITTLE_ENDIAN)
+#define STRICT_ALIGNMENT (TARGET_STRICT_ALIGN)
/* Alignment in bits of the stack boundary. Note, in order to allow building
one set of libraries with -mno-eabi instead of eabi libraries and non-eabi
@@ -710,7 +707,7 @@ do { \
if (rs6000_sdata != SDATA_NONE && (SIZE) > 0 \
&& (SIZE) <= g_switch_value) \
{ \
- sdata_section (); \
+ sbss_section (); \
ASM_OUTPUT_ALIGN (FILE, exact_log2 (ALIGN / BITS_PER_UNIT)); \
ASM_OUTPUT_LABEL (FILE, NAME); \
ASM_OUTPUT_SKIP (FILE, SIZE); \
@@ -975,16 +972,36 @@ do { \
%{memb} %{!memb: %{msdata: -memb} %{msdata=eabi: -memb}} \
%{mlittle} %{mlittle-endian} %{mbig} %{mbig-endian} \
%{!mlittle: %{!mlittle-endian: %{!mbig: %{!mbig-endian: \
- %{mcall-solaris: -mlittle -msolaris} %{mcall-linux: -mbig} }}}}"
+ %{mcall-solaris: -mlittle -msolaris} \
+ %{mcall-linux: -mbig} }}}}"
+
+#ifndef CC1_ENDIAN_BIG_SPEC
+#define CC1_ENDIAN_BIG_SPEC ""
+#endif
+
+#ifndef CC1_ENDIAN_LITTLE_SPEC
+#define CC1_ENDIAN_LITTLE_SPEC "\
+%{!mstrict-align: %{!mno-strict-align: \
+ -mstrict-align \
+}}"
+#endif
+
+#ifndef CC1_ENDIAN_DEFAULT_SPEC
+#define CC1_ENDIAN_DEFAULT_SPEC "%(cc1_endian_big_spec)"
+#endif
#undef CC1_SPEC
/* Pass -G xxx to the compiler and set correct endian mode */
#define CC1_SPEC "%{G*} \
-%{!mlittle: %{!mlittle-endian: %{!mbig: %{!mbig-endian: \
- %{mcall-nt: -mlittle } \
- %{mcall-aixdesc: -mbig } \
- %{mcall-solaris: -mlittle } \
- %{mcall-linux: -mbig} }}}} \
+%{mlittle: %(cc1_endian_little)} %{!mlittle: %{mlittle-endian: %(cc1_endian_little)}} \
+%{mbig: %(cc1_endian_big)} %{!mbig: %{mbig-endian: %(cc1_endian_big)}} \
+ %{mcall-nt: -mlittle %{cc1_endian_little} } \
+ %{mcall-aixdesc: -mbig %{cc1_endian_big} } \
+ %{mcall-solaris: -mlittle %{cc1_endian_little} } \
+ %{mcall-linux: -mbig %{cc1_endian_big} } \
+ %{!mcall-nt: %{!mcall-aixdesc: %{!mcall-solaris: %{!mcall-linux: \
+ %(cc1_endian_default) \
+ }}}} \
%{mcall-solaris: -mregnames } \
%{mno-sdata: -msdata=none } \
%{meabi: %{!mcall-*: -mcall-sysv }} \
@@ -1419,6 +1436,9 @@ do { \
{ "link_os_linux", LINK_OS_LINUX_SPEC }, \
{ "link_os_solaris", LINK_OS_SOLARIS_SPEC }, \
{ "link_os_default", LINK_OS_DEFAULT_SPEC }, \
+ { "cc1_endian_big", CC1_ENDIAN_BIG_SPEC }, \
+ { "cc1_endian_little", CC1_ENDIAN_LITTLE_SPEC }, \
+ { "cc1_endian_default", CC1_ENDIAN_DEFAULT_SPEC }, \
{ "cpp_endian_big", CPP_ENDIAN_BIG_SPEC }, \
{ "cpp_endian_little", CPP_ENDIAN_LITTLE_SPEC }, \
{ "cpp_endian_solaris", CPP_ENDIAN_SOLARIS_SPEC }, \
diff --git a/gcc/config/rs6000/sysv4le.h b/gcc/config/rs6000/sysv4le.h
index 0cf2ec49019..1e21acd7b86 100644
--- a/gcc/config/rs6000/sysv4le.h
+++ b/gcc/config/rs6000/sysv4le.h
@@ -28,6 +28,9 @@ Boston, MA 02111-1307, USA. */
#undef CPP_ENDIAN_DEFAULT_SPEC
#define CPP_ENDIAN_DEFAULT_SPEC "%(cpp_endian_little)"
+#undef CC1_ENDIAN_DEFAULT_SPEC
+#define CC1_ENDIAN_DEFAULT_SPEC "%(cc1_endian_little)"
+
#undef LINK_TARGET_SPEC
#define LINK_TARGET_SPEC "\
%{mbig: -oformat elf32-powerpc } %{mbig-endian: -oformat elf32-powerpc } \
diff --git a/gcc/config/rs6000/t-ppcgas b/gcc/config/rs6000/t-ppcgas
index 9fb5e4ec328..8ea37beebd5 100644
--- a/gcc/config/rs6000/t-ppcgas
+++ b/gcc/config/rs6000/t-ppcgas
@@ -3,17 +3,14 @@
MULTILIB_OPTIONS = msoft-float \
mlittle/mbig \
- mcall-sysv/mcall-aix/mcall-solaris/mcall-linux
+ mcall-sysv/mcall-aix/mcall-linux
MULTILIB_DIRNAMES = nof \
le be \
- cs ca sol lin
+ cs ca lin
MULTILIB_EXTRA_OPTS = mrelocatable-lib mno-eabi mstrict-align
-MULTILIB_EXCEPTIONS = *mbig/*mcall-solaris* \
- *mlittle/*mcall-solaris* \
- *msoft-float/*mcall-solaris* \
- *mbig/*mcall-linux* \
+MULTILIB_EXCEPTIONS = *mbig/*mcall-linux* \
*mlittle/*mcall-linux* \
*msoft-float/*mcall-linux*
diff --git a/gcc/config/rs6000/win-nt.h b/gcc/config/rs6000/win-nt.h
index 742a5e8c5fc..796e487b0de 100644
--- a/gcc/config/rs6000/win-nt.h
+++ b/gcc/config/rs6000/win-nt.h
@@ -119,9 +119,11 @@ Boston, MA 02111-1307, USA. */
#undef TARGET_DEFAULT
#define TARGET_DEFAULT (MASK_POWERPC | MASK_NEW_MNEMONICS | MASK_NO_FP_IN_TOC | MASK_NO_SUM_IN_TOC)
-/* Address to save the TOC register */
+/* MEM representing address to save the TOC register */
#undef RS6000_SAVE_TOC
-#define RS6000_SAVE_TOC plus_constant (virtual_incoming_args_rtx, -RS6000_SAVE_AREA - 8)
+#define RS6000_SAVE_TOC gen_rtx_MEM (Pmode, \
+ plus_constant (virtual_incoming_args_rtx,
+ -RS6000_SAVE_AREA - 8))
/* Windows NT specifies that r13 is reserved to the OS, so it is not available
to the normal user. */
diff --git a/gcc/config/rs6000/x-cygwin32 b/gcc/config/rs6000/x-cygwin32
deleted file mode 100644
index 5e796a0e916..00000000000
--- a/gcc/config/rs6000/x-cygwin32
+++ /dev/null
@@ -1,4 +0,0 @@
-# Don't run fixproto
-STMP_FIXPROTO =
-# Don't need collect2
-USE_COLLECT2 =
diff --git a/gcc/config/rs6000/xm-cygwin32.h b/gcc/config/rs6000/xm-cygwin32.h
deleted file mode 100644
index ca548319c10..00000000000
--- a/gcc/config/rs6000/xm-cygwin32.h
+++ /dev/null
@@ -1 +0,0 @@
-#define EXECUTABLE_SUFFIX ".exe"
diff --git a/gcc/config/rs6000/xm-sysv4.h b/gcc/config/rs6000/xm-sysv4.h
index cf56eb4ad33..181f8b7d818 100644
--- a/gcc/config/rs6000/xm-sysv4.h
+++ b/gcc/config/rs6000/xm-sysv4.h
@@ -30,9 +30,7 @@ Boston, MA 02111-1307, USA. */
#define HOST_BITS_PER_SHORT 16
#define HOST_BITS_PER_INT 32
#define HOST_BITS_PER_LONG 32
-#if 0
#define HOST_BITS_PER_LONGLONG 64
-#endif
/* Doubles are stored in memory with the high order word first. This
matters when cross-compiling. */
diff --git a/gcc/config/sh/elf.h b/gcc/config/sh/elf.h
index 40d4c77b204..68cc6916bdc 100644
--- a/gcc/config/sh/elf.h
+++ b/gcc/config/sh/elf.h
@@ -1,5 +1,5 @@
/* Definitions of target machine for gcc for Hitachi Super-H using ELF.
- Copyright (C) 1996 Free Software Foundation, Inc.
+ Copyright (C) 1996, 1997 Free Software Foundation, Inc.
Contributed by Ian Lance Taylor <ian@cygnus.com>.
This file is part of GNU CC.
diff --git a/gcc/config/sh/lib1funcs.asm b/gcc/config/sh/lib1funcs.asm
index 5084e9830ef..bf9ea9a3efa 100644
--- a/gcc/config/sh/lib1funcs.asm
+++ b/gcc/config/sh/lib1funcs.asm
@@ -1,4 +1,4 @@
-/* Copyright (C) 1994, 1995, 1997 Free Software Foundation, Inc.
+/* Copyright (C) 1994, 1995, 1997, 1998 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
@@ -770,6 +770,64 @@ ___movstr:
add #64,r4
#endif
+#ifdef L_movstr_i4
+#if defined(__SH4__) || defined(__SH4_SINGLE__) || defined(__SH4_SINGLE_ONLY__)
+ .text
+ .global ___movstr_i4_even
+ .global ___movstr_i4_odd
+ .global ___movstrSI12_i4
+
+ .p2align 5
+L_movstr_2mod4_end:
+ mov.l r0,@(16,r4)
+ rts
+ mov.l r1,@(20,r4)
+
+ .p2align 2
+
+___movstr_i4_odd:
+ mov.l @r5+,r1
+ add #-4,r4
+ mov.l @r5+,r2
+ mov.l @r5+,r3
+ mov.l r1,@(4,r4)
+ mov.l r2,@(8,r4)
+
+L_movstr_loop:
+ mov.l r3,@(12,r4)
+ dt r6
+ mov.l @r5+,r0
+ bt/s L_movstr_2mod4_end
+ mov.l @r5+,r1
+ add #16,r4
+L_movstr_start_even:
+ mov.l @r5+,r2
+ mov.l @r5+,r3
+ mov.l r0,@r4
+ dt r6
+ mov.l r1,@(4,r4)
+ bf/s L_movstr_loop
+ mov.l r2,@(8,r4)
+ rts
+ mov.l r3,@(12,r4)
+
+___movstr_i4_even:
+ mov.l @r5+,r0
+ bra L_movstr_start_even
+ mov.l @r5+,r1
+
+ .p2align 4
+___movstrSI12_i4:
+ mov.l @r5,r0
+ mov.l @(4,r5),r1
+ mov.l @(8,r5),r2
+ mov.l r0,@r4
+ mov.l r1,@(4,r4)
+ rts
+ mov.l r2,@(8,r4)
+#endif /* ! __SH4__ */
+#endif
+
#ifdef L_mulsi3
@@ -808,9 +866,47 @@ hiset: sts macl,r0 ! r0 = bb*dd
#endif
-#ifdef L_sdivsi3
+#ifdef L_sdivsi3_i4
.title "SH DIVIDE"
!! 4 byte integer Divide code for the Hitachi SH
+#ifdef __SH4__
+!! args in r4 and r5, result in fpul, clobber dr0, dr2
+
+ .global ___sdivsi3_i4
+___sdivsi3_i4:
+ lds r4,fpul
+ float fpul,dr0
+ lds r5,fpul
+ float fpul,dr2
+ fdiv dr2,dr0
+ rts
+ ftrc dr0,fpul
+
+#elif defined(__SH4_SINGLE__) || defined(__SH4_SINGLE_ONLY__)
+!! args in r4 and r5, result in fpul, clobber r2, dr0, dr2
+
+ .global ___sdivsi3_i4
+___sdivsi3_i4:
+ sts.l fpscr,@-r15
+ mov #8,r2
+ swap.w r2,r2
+ lds r2,fpscr
+ lds r4,fpul
+ float fpul,dr0
+ lds r5,fpul
+ float fpul,dr2
+ fdiv dr2,dr0
+ ftrc dr0,fpul
+ rts
+ lds.l @r15+,fpscr
+
+#endif /* ! __SH4__ */
+#endif
+
+#ifdef L_sdivsi3
+/* __SH4_SINGLE_ONLY__ keeps this part for link compatibility with
+ sh3e code. */
+#if ! defined(__SH4__) && ! defined (__SH4_SINGLE__)
!!
!! Steve Chamberlain
!! sac@cygnus.com
@@ -904,11 +1000,109 @@ ___sdivsi3:
div0: rts
mov #0,r0
+#endif /* ! __SH4__ */
#endif
-#ifdef L_udivsi3
+#ifdef L_udivsi3_i4
.title "SH DIVIDE"
!! 4 byte integer Divide code for the Hitachi SH
+#ifdef __SH4__
+!! args in r4 and r5, result in fpul, clobber r0, r1, r4, r5, dr0, dr2, dr4
+
+ .global ___udivsi3_i4
+___udivsi3_i4:
+ mov #1,r1
+ cmp/hi r1,r5
+ bf trivial
+ rotr r1
+ xor r1,r4
+ lds r4,fpul
+ mova L1,r0
+#ifdef FMOVD_WORKS
+ fmov.d @r0+,dr4
+#else
+#ifdef __LITTLE_ENDIAN__
+ fmov.s @r0+,fr5
+ fmov.s @r0,fr4
+#else
+ fmov.s @r0+,fr4
+ fmov.s @r0,fr5
+#endif
+#endif
+ float fpul,dr0
+ xor r1,r5
+ lds r5,fpul
+ float fpul,dr2
+ fadd dr4,dr0
+ fadd dr4,dr2
+ fdiv dr2,dr0
+ rts
+ ftrc dr0,fpul
+
+trivial:
+ rts
+ lds r4,fpul
+
+ .align 2
+L1:
+ .double 2147483648
+
+#elif defined(__SH4_SINGLE__) || defined(__SH4_SINGLE_ONLY__)
+!! args in r4 and r5, result in fpul, clobber r0, r1, r4, r5, dr0, dr2, dr4
+
+ .global ___udivsi3_i4
+___udivsi3_i4:
+ mov #1,r1
+ cmp/hi r1,r5
+ bf trivial
+ sts.l fpscr,@-r15
+ mova L1,r0
+ lds.l @r0+,fpscr
+ rotr r1
+ xor r1,r4
+ lds r4,fpul
+#ifdef FMOVD_WORKS
+ fmov.d @r0+,dr4
+#else
+#ifdef __LITTLE_ENDIAN__
+ fmov.s @r0+,fr5
+ fmov.s @r0,fr4
+#else
+ fmov.s @r0+,fr4
+ fmov.s @r0,fr5
+#endif
+#endif
+ float fpul,dr0
+ xor r1,r5
+ lds r5,fpul
+ float fpul,dr2
+ fadd dr4,dr0
+ fadd dr4,dr2
+ fdiv dr2,dr0
+ ftrc dr0,fpul
+ rts
+ lds.l @r15+,fpscr
+
+trivial:
+ rts
+ lds r4,fpul
+
+ .align 2
+L1:
+#if defined (__LITTLE_ENDIAN__) || ! defined (FMOVD_WORKS)
+ .long 0x80000
+#else
+ .long 0x180000
+#endif
+ .double 2147483648
+
+#endif /* ! __SH4__ */
+#endif
+
+#ifdef L_udivsi3
+/* __SH4_SINGLE_ONLY__ keeps this part for link compatibility with
+ sh3e code. */
+#if ! defined(__SH4__) && ! defined (__SH4_SINGLE__)
!!
!! Steve Chamberlain
!! sac@cygnus.com
@@ -966,22 +1160,40 @@ vshortway:
ret: rts
mov r4,r0
+#endif /* __SH4__ */
#endif
#ifdef L_set_fpscr
-#if defined (__SH3E__)
+#if defined (__SH3E__) || defined(__SH4_SINGLE__) || defined(__SH4__) || defined(__SH4_SINGLE_ONLY__)
.global ___set_fpscr
___set_fpscr:
lds r4,fpscr
mov.l ___set_fpscr_L1,r1
swap.w r4,r0
or #24,r0
+#ifndef FMOVD_WORKS
xor #16,r0
+#endif
+#if defined(__SH4__)
+ swap.w r0,r3
+ mov.l r3,@(4,r1)
+#else /* defined(__SH3E__) || defined(__SH4_SINGLE*__) */
swap.w r0,r2
mov.l r2,@r1
+#endif
+#ifndef FMOVD_WORKS
xor #8,r0
+#else
+ xor #24,r0
+#endif
+#if defined(__SH4__)
+ swap.w r0,r2
+ rts
+ mov.l r2,@r1
+#else /* defined(__SH3E__) || defined(__SH4_SINGLE*__) */
swap.w r0,r3
rts
mov.l r3,@(4,r1)
+#endif
.align 2
___set_fpscr_L1:
.long ___fpscr_values
@@ -990,5 +1202,5 @@ ___set_fpscr_L1:
#else
.comm ___fpscr_values,8
#endif /* ELF */
-#endif /* SH3E */
+#endif /* SH3E / SH4 */
#endif /* L_set_fpscr */
diff --git a/gcc/config/sh/rtems.h b/gcc/config/sh/rtems.h
index 3e3fc7b8ca2..b58075e11fe 100644
--- a/gcc/config/sh/rtems.h
+++ b/gcc/config/sh/rtems.h
@@ -1,5 +1,5 @@
/* Definitions for rtems targeting a SH using COFF.
- Copyright (C) 1997 Free Software Foundation, Inc.
+ Copyright (C) 1997, 1998 Free Software Foundation, Inc.
Contributed by Joel Sherrill (joel@OARcorp.com).
This file is part of GNU CC.
diff --git a/gcc/config/sh/rtemself.h b/gcc/config/sh/rtemself.h
index 8000a3ae769..fb1c8cac246 100644
--- a/gcc/config/sh/rtemself.h
+++ b/gcc/config/sh/rtemself.h
@@ -1,5 +1,5 @@
/* Definitions for rtems targeting a SH using elf.
- Copyright (C) 1997 Free Software Foundation, Inc.
+ Copyright (C) 1997, 1998 Free Software Foundation, Inc.
Contributed by Joel Sherrill (joel@OARcorp.com).
This file is part of GNU CC.
diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c
index 12f1b74c317..41c5ac5ecac 100644
--- a/gcc/config/sh/sh.c
+++ b/gcc/config/sh/sh.c
@@ -1,5 +1,5 @@
/* Output routines for GCC for Hitachi Super-H.
- Copyright (C) 1993, 1994, 1995, 1996, 1997 Free Software Foundation, Inc.
+ Copyright (C) 1993-1998 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -103,6 +103,17 @@ int regno_reg_class[FIRST_PSEUDO_REGISTER] =
FP_REGS, FP_REGS, FP_REGS, FP_REGS,
FP_REGS, FP_REGS, FP_REGS, FP_REGS,
FP_REGS, FP_REGS, FP_REGS, FP_REGS,
+ DF_REGS, DF_REGS, DF_REGS, DF_REGS,
+ DF_REGS, DF_REGS, DF_REGS, DF_REGS,
+ FPSCR_REGS,
+};
+
+char fp_reg_names[][5] =
+{
+ "fr0", "fr1", "fr2", "fr3", "fr4", "fr5", "fr6", "fr7",
+ "fr8", "fr9", "fr10", "fr11", "fr12", "fr13", "fr14", "fr15",
+ "fpul",
+ "xd0","xd2","xd4", "xd6", "xd8", "xd10", "xd12", "xd14",
};
/* Provide reg_class from a letter such as appears in the machine
@@ -110,7 +121,7 @@ int regno_reg_class[FIRST_PSEUDO_REGISTER] =
enum reg_class reg_class_from_letter[] =
{
- /* a */ NO_REGS, /* b */ NO_REGS, /* c */ NO_REGS, /* d */ NO_REGS,
+ /* a */ ALL_REGS, /* b */ NO_REGS, /* c */ FPSCR_REGS, /* d */ DF_REGS,
/* e */ NO_REGS, /* f */ FP_REGS, /* g */ NO_REGS, /* h */ NO_REGS,
/* i */ NO_REGS, /* j */ NO_REGS, /* k */ NO_REGS, /* l */ PR_REGS,
/* m */ NO_REGS, /* n */ NO_REGS, /* o */ NO_REGS, /* p */ NO_REGS,
@@ -119,6 +130,12 @@ enum reg_class reg_class_from_letter[] =
/* y */ FPUL_REGS, /* z */ R0_REGS
};
+int assembler_dialect;
+
+rtx get_fpscr_rtx ();
+void emit_sf_insn ();
+void emit_df_insn ();
+
static void split_branches PROTO ((rtx));
/* Print the operand address in x to the stream. */
@@ -131,7 +148,8 @@ print_operand_address (stream, x)
switch (GET_CODE (x))
{
case REG:
- fprintf (stream, "@%s", reg_names[REGNO (x)]);
+ case SUBREG:
+ fprintf (stream, "@%s", reg_names[true_regnum (x)]);
break;
case PLUS:
@@ -143,13 +161,19 @@ print_operand_address (stream, x)
{
case CONST_INT:
fprintf (stream, "@(%d,%s)", INTVAL (index),
- reg_names[REGNO (base)]);
+ reg_names[true_regnum (base)]);
break;
case REG:
- fprintf (stream, "@(r0,%s)",
- reg_names[MAX (REGNO (base), REGNO (index))]);
- break;
+ case SUBREG:
+ {
+ int base_num = true_regnum (base);
+ int index_num = true_regnum (index);
+
+ fprintf (stream, "@(r0,%s)",
+ reg_names[MAX (base_num, index_num)]);
+ break;
+ }
default:
debug_rtx (x);
@@ -159,11 +183,11 @@ print_operand_address (stream, x)
break;
case PRE_DEC:
- fprintf (stream, "@-%s", reg_names[REGNO (XEXP (x, 0))]);
+ fprintf (stream, "@-%s", reg_names[true_regnum (XEXP (x, 0))]);
break;
case POST_INC:
- fprintf (stream, "@%s+", reg_names[REGNO (XEXP (x, 0))]);
+ fprintf (stream, "@%s+", reg_names[true_regnum (XEXP (x, 0))]);
break;
default:
@@ -182,7 +206,8 @@ print_operand_address (stream, x)
'O' print a constant without the #
'R' print the LSW of a dp value - changes if in little endian
'S' print the MSW of a dp value - changes if in little endian
- 'T' print the next word of a dp value - same as 'R' in big endian mode. */
+ 'T' print the next word of a dp value - same as 'R' in big endian mode.
+ 'o' output an operator. */
void
print_operand (stream, x, code)
@@ -201,13 +226,25 @@ print_operand (stream, x, code)
fprintf (stream, "%s", LOCAL_LABEL_PREFIX);
break;
case '@':
+ {
+ int interrupt_handler;
+
+ if ((lookup_attribute
+ ("interrupt_handler",
+ DECL_MACHINE_ATTRIBUTES (current_function_decl)))
+ != NULL_TREE)
+ interrupt_handler = 1;
+ else
+ interrupt_handler = 0;
+
if (trap_exit)
fprintf (stream, "trapa #%d", trap_exit);
- else if (pragma_interrupt)
+ else if (interrupt_handler)
fprintf (stream, "rte");
else
fprintf (stream, "rts");
break;
+ }
case '#':
/* Output a nop if there's nothing in the delay slot. */
if (dbr_sequence_length () == 0)
@@ -230,16 +267,31 @@ print_operand (stream, x, code)
fputs (reg_names[REGNO (x) + 1], (stream));
break;
case MEM:
- print_operand_address (stream,
- XEXP (adj_offsettable_operand (x, 4), 0));
+ if (GET_CODE (XEXP (x, 0)) != PRE_DEC
+ && GET_CODE (XEXP (x, 0)) != POST_INC)
+ x = adj_offsettable_operand (x, 4);
+ print_operand_address (stream, XEXP (x, 0));
break;
}
break;
+ case 'o':
+ switch (GET_CODE (x))
+ {
+ case PLUS: fputs ("add", stream); break;
+ case MINUS: fputs ("sub", stream); break;
+ case MULT: fputs ("mul", stream); break;
+ case DIV: fputs ("div", stream); break;
+ }
+ break;
default:
switch (GET_CODE (x))
{
case REG:
- fputs (reg_names[REGNO (x)], (stream));
+ if (REGNO (x) >= FIRST_FP_REG && REGNO (x) <= LAST_FP_REG
+ && GET_MODE_SIZE (GET_MODE (x)) > 4)
+ fprintf ((stream), "d%s", reg_names[REGNO (x)]+1);
+ else
+ fputs (reg_names[REGNO (x)], (stream));
break;
case MEM:
output_address (XEXP (x, 0));
@@ -253,6 +305,18 @@ print_operand (stream, x, code)
}
}
+static void force_into PROTO ((rtx, rtx));
+
+/* Like force_operand, but guarantees that VALUE ends up in TARGET. */
+static void
+force_into (value, target)
+ rtx value, target;
+{
+ value = force_operand (value, target);
+ if (! rtx_equal_p (value, target))
+ emit_insn (gen_move_insn (target, value));
+}
+
/* Emit code to perform a block move. Choose the best method.
OPERANDS[0] is the destination.
@@ -273,6 +337,55 @@ expand_block_move (operands)
if (! constp || align < 4 || (bytes % 4 != 0))
return 0;
+ if (TARGET_HARD_SH4)
+ {
+ if (bytes < 12)
+ return 0;
+ else if (bytes == 12)
+ {
+ tree entry_name;
+ rtx func_addr_rtx;
+ rtx r4 = gen_rtx (REG, SImode, 4);
+ rtx r5 = gen_rtx (REG, SImode, 5);
+
+ entry_name = get_identifier ("__movstrSI12_i4");
+
+ func_addr_rtx
+ = copy_to_mode_reg (Pmode,
+ gen_rtx_SYMBOL_REF (Pmode,
+ IDENTIFIER_POINTER (entry_name)));
+ force_into (XEXP (operands[0], 0), r4);
+ force_into (XEXP (operands[1], 0), r5);
+ emit_insn (gen_block_move_real_i4 (func_addr_rtx));
+ return 1;
+ }
+ else if (! TARGET_SMALLCODE)
+ {
+ tree entry_name;
+ rtx func_addr_rtx;
+ int dwords;
+ rtx r4 = gen_rtx (REG, SImode, 4);
+ rtx r5 = gen_rtx (REG, SImode, 5);
+ rtx r6 = gen_rtx (REG, SImode, 6);
+
+ entry_name = get_identifier (bytes & 4
+ ? "__movstr_i4_odd"
+ : "__movstr_i4_even");
+ func_addr_rtx
+ = copy_to_mode_reg (Pmode,
+ gen_rtx_SYMBOL_REF (Pmode,
+ IDENTIFIER_POINTER (entry_name)));
+ force_into (XEXP (operands[0], 0), r4);
+ force_into (XEXP (operands[1], 0), r5);
+
+ dwords = bytes >> 3;
+ emit_insn (gen_move_insn (r6, GEN_INT (dwords - 1)));
+ emit_insn (gen_block_lump_real_i4 (func_addr_rtx));
+ return 1;
+ }
+ else
+ return 0;
+ }
if (bytes < 64)
{
char entry[30];
@@ -288,8 +401,8 @@ expand_block_move (operands)
= copy_to_mode_reg (Pmode,
gen_rtx (SYMBOL_REF, Pmode,
IDENTIFIER_POINTER (entry_name)));
- emit_insn (gen_move_insn (r4, XEXP (operands[0], 0)));
- emit_insn (gen_move_insn (r5, XEXP (operands[1], 0)));
+ force_into (XEXP (operands[0], 0), r4);
+ force_into (XEXP (operands[1], 0), r5);
emit_insn (gen_block_move_real (func_addr_rtx));
return 1;
}
@@ -310,8 +423,8 @@ expand_block_move (operands)
= copy_to_mode_reg (Pmode,
gen_rtx (SYMBOL_REF, Pmode,
IDENTIFIER_POINTER (entry_name)));
- emit_insn (gen_move_insn (r4, XEXP (operands[0], 0)));
- emit_insn (gen_move_insn (r5, XEXP (operands[1], 0)));
+ force_into (XEXP (operands[0], 0), r4);
+ force_into (XEXP (operands[1], 0), r5);
/* r6 controls the size of the move. 16 is decremented from it
for each 64 bytes moved. Then the negative bit left over is used
@@ -405,9 +518,17 @@ prepare_scc_operands (code)
|| TARGET_SH3E && GET_MODE_CLASS (mode) == MODE_FLOAT)
sh_compare_op1 = force_reg (mode, sh_compare_op1);
- emit_insn (gen_rtx (SET, VOIDmode, t_reg,
- gen_rtx (code, SImode, sh_compare_op0,
- sh_compare_op1)));
+ if (TARGET_SH4 && GET_MODE_CLASS (mode) == MODE_FLOAT)
+ (mode == SFmode ? emit_sf_insn : emit_df_insn)
+ (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2,
+ gen_rtx (SET, VOIDmode, t_reg,
+ gen_rtx (code, SImode,
+ sh_compare_op0, sh_compare_op1)),
+ gen_rtx (USE, VOIDmode, get_fpscr_rtx ()))));
+ else
+ emit_insn (gen_rtx (SET, VOIDmode, t_reg,
+ gen_rtx (code, SImode, sh_compare_op0,
+ sh_compare_op1)));
return t_reg;
}
@@ -443,7 +564,15 @@ from_compare (operands, code)
insn = gen_rtx (SET, VOIDmode,
gen_rtx (REG, SImode, 18),
gen_rtx (code, SImode, sh_compare_op0, sh_compare_op1));
- emit_insn (insn);
+ if (TARGET_SH4 && GET_MODE_CLASS (mode) == MODE_FLOAT)
+ {
+ insn = gen_rtx (PARALLEL, VOIDmode,
+ gen_rtvec (2, insn,
+ gen_rtx (USE, VOIDmode, get_fpscr_rtx ())));
+ (mode == SFmode ? emit_sf_insn : emit_df_insn) (insn);
+ }
+ else
+ emit_insn (insn);
}
/* Functions to output assembly code. */
@@ -552,7 +681,9 @@ output_far_jump (insn, op)
this.lab = gen_label_rtx ();
- if (offset >= -32764 && offset - get_attr_length (insn) <= 32766)
+ if (TARGET_SH2
+ && offset >= -32764
+ && offset - get_attr_length (insn) <= 32766)
{
far = 0;
jump = "mov.w %O0,%1;braf %1";
@@ -1722,7 +1853,8 @@ static int pool_size;
/* Add a constant to the pool and return its label. */
static rtx
-add_constant (x, mode)
+add_constant (x, mode, last_value)
+ rtx last_value;
rtx x;
enum machine_mode mode;
{
@@ -1741,13 +1873,27 @@ add_constant (x, mode)
continue;
}
if (rtx_equal_p (x, pool_vector[i].value))
- return pool_vector[i].label;
+ {
+ lab = 0;
+ if (! last_value
+ || ! i
+ || ! rtx_equal_p (last_value, pool_vector[i-1].value))
+ {
+ lab = pool_vector[i].label;
+ if (! lab)
+ pool_vector[i].label = lab = gen_label_rtx ();
+ }
+ return lab;
+ }
}
}
/* Need a new one. */
pool_vector[pool_size].value = x;
- lab = gen_label_rtx ();
+ if (last_value && rtx_equal_p (last_value, pool_vector[pool_size - 1].value))
+ lab = 0;
+ else
+ lab = gen_label_rtx ();
pool_vector[pool_size].mode = mode;
pool_vector[pool_size].label = lab;
pool_size++;
@@ -1965,7 +2111,8 @@ find_barrier (num_mova, mova, from)
/* We must explicitly check the mode, because sometimes the
front end will generate code to load unsigned constants into
HImode targets without properly sign extending them. */
- if (mode == HImode || (mode == SImode && hi_const (src)))
+ if (mode == HImode
+ || (mode == SImode && hi_const (src) && REGNO (dst) != FPUL_REG))
{
found_hi += 2;
/* We put the short constants before the long constants, so
@@ -2130,7 +2277,7 @@ sfunc_uses_reg (insn)
for (i = XVECLEN (pattern, 0) - 1; i >= 0; i--)
{
part = XVECEXP (pattern, 0, i);
- if (part == reg_part)
+ if (part == reg_part || GET_CODE (part) == CLOBBER)
continue;
if (reg_mentioned_p (reg, ((GET_CODE (part) == SET
&& GET_CODE (SET_DEST (part)) == REG)
@@ -2470,6 +2617,13 @@ gen_far_branch (bp)
}
else
jump = emit_jump_insn_after (gen_return (), insn);
+ /* Emit a barrier so that reorg knows that any following instructions
+ are not reachable via a fall-through path.
+ But don't do this when not optimizing, since we wouldn't supress the
+ alignment for the barrier then, and could end up with out-of-range
+ pc-relative loads. */
+ if (optimize)
+ emit_barrier_after (jump);
emit_label_after (bp->near_label, insn);
JUMP_LABEL (jump) = bp->far_label;
if (! invert_jump (insn, label))
@@ -2556,36 +2710,42 @@ barrier_align (barrier_or_label)
if (! TARGET_SH3 || ! optimize)
return CACHE_LOG;
- /* Check if there is an immediately preceding branch to the insn beyond
- the barrier. We must weight the cost of discarding useful information
- from the current cache line when executing this branch and there is
- an alignment, against that of fetching unneeded insn in front of the
- branch target when there is no alignment. */
-
- /* PREV is presumed to be the JUMP_INSN for the barrier under
- investigation. Skip to the insn before it. */
- prev = prev_real_insn (prev);
-
- for (slot = 2, credit = 1 << (CACHE_LOG - 2) + 2;
- credit >= 0 && prev && GET_CODE (prev) == INSN;
- prev = prev_real_insn (prev))
+ /* When fixing up pcloads, a constant table might be inserted just before
+ the basic block that ends with the barrier. Thus, we can't trust the
+ instruction lengths before that. */
+ if (mdep_reorg_phase > SH_FIXUP_PCLOAD)
{
- if (GET_CODE (PATTERN (prev)) == USE
- || GET_CODE (PATTERN (prev)) == CLOBBER)
- continue;
- if (GET_CODE (PATTERN (prev)) == SEQUENCE)
- prev = XVECEXP (PATTERN (prev), 0, 1);
- if (slot &&
- get_attr_in_delay_slot (prev) == IN_DELAY_SLOT_YES)
- slot = 0;
- credit -= get_attr_length (prev);
+ /* Check if there is an immediately preceding branch to the insn beyond
+ the barrier. We must weight the cost of discarding useful information
+ from the current cache line when executing this branch and there is
+ an alignment, against that of fetching unneeded insn in front of the
+ branch target when there is no alignment. */
+
+ /* PREV is presumed to be the JUMP_INSN for the barrier under
+ investigation. Skip to the insn before it. */
+ prev = prev_real_insn (prev);
+
+ for (slot = 2, credit = 1 << (CACHE_LOG - 2) + 2;
+ credit >= 0 && prev && GET_CODE (prev) == INSN;
+ prev = prev_real_insn (prev))
+ {
+ if (GET_CODE (PATTERN (prev)) == USE
+ || GET_CODE (PATTERN (prev)) == CLOBBER)
+ continue;
+ if (GET_CODE (PATTERN (prev)) == SEQUENCE)
+ prev = XVECEXP (PATTERN (prev), 0, 1);
+ if (slot &&
+ get_attr_in_delay_slot (prev) == IN_DELAY_SLOT_YES)
+ slot = 0;
+ credit -= get_attr_length (prev);
+ }
+ if (prev
+ && GET_CODE (prev) == JUMP_INSN
+ && JUMP_LABEL (prev)
+ && next_real_insn (JUMP_LABEL (prev)) == next_real_insn (barrier_or_label)
+ && (credit - slot >= (GET_CODE (SET_SRC (PATTERN (prev))) == PC ? 2 : 0)))
+ return 0;
}
- if (prev
- && GET_CODE (prev) == JUMP_INSN
- && JUMP_LABEL (prev)
- && next_real_insn (JUMP_LABEL (prev)) == next_real_insn (barrier_or_label)
- && (credit - slot >= (GET_CODE (SET_SRC (PATTERN (prev))) == PC ? 2 : 0)))
- return 0;
return CACHE_LOG;
}
@@ -2914,7 +3074,8 @@ machine_dependent_reorg (first)
dst = SET_DEST (pat);
mode = GET_MODE (dst);
- if (mode == SImode && hi_const (src))
+ if (mode == SImode && hi_const (src)
+ && REGNO (dst) != FPUL_REG)
{
int offset = 0;
@@ -2929,7 +3090,7 @@ machine_dependent_reorg (first)
if (GET_CODE (dst) == REG
&& ((REGNO (dst) >= FIRST_FP_REG
- && REGNO (dst) <= LAST_FP_REG)
+ && REGNO (dst) <= LAST_XD_REG)
|| REGNO (dst) == FPUL_REG))
{
if (last_float
@@ -2943,7 +3104,8 @@ machine_dependent_reorg (first)
last_float_move = scan;
last_float = src;
newsrc = gen_rtx (MEM, mode,
- (REGNO (dst) == FPUL_REG
+ ((TARGET_SH4 && ! TARGET_FMOVD
+ || REGNO (dst) == FPUL_REG)
? r0_inc_rtx
: r0_rtx));
last_float_addr = &XEXP (newsrc, 0);
@@ -2983,6 +3145,16 @@ machine_dependent_reorg (first)
emit_insn_before (gen_use_sfunc_addr (reg), insn);
}
}
+#if 0
+ /* fpscr is not actually a user variable, but we pretend it is for the
+ sake of the previous optimization passes, since we want it handled like
+ one. However, we don't have eny debugging information for it, so turn
+ it into a non-user variable now. */
+ if (TARGET_SH4)
+ REG_USERVAR_P (get_fpscr_rtx ()) = 0;
+#endif
+ if (optimize)
+ sh_flag_remove_dead_before_cse = 1;
mdep_reorg_phase = SH_AFTER_MDEP_REORG;
}
@@ -3386,8 +3558,16 @@ push (rn)
int rn;
{
rtx x;
- if ((rn >= FIRST_FP_REG && rn <= LAST_FP_REG)
- || rn == FPUL_REG)
+ if (rn == FPUL_REG)
+ x = gen_push_fpul ();
+ else if (TARGET_SH4 && TARGET_FMOVD && ! TARGET_FPU_SINGLE
+ && rn >= FIRST_FP_REG && rn <= LAST_XD_REG)
+ {
+ if ((rn - FIRST_FP_REG) & 1 && rn <= LAST_FP_REG)
+ return;
+ x = gen_push_4 (gen_rtx (REG, DFmode, rn));
+ }
+ else if (TARGET_SH3E && rn >= FIRST_FP_REG && rn <= LAST_FP_REG)
x = gen_push_e (gen_rtx (REG, SFmode, rn));
else
x = gen_push (gen_rtx (REG, SImode, rn));
@@ -3404,8 +3584,16 @@ pop (rn)
int rn;
{
rtx x;
- if ((rn >= FIRST_FP_REG && rn <= LAST_FP_REG)
- || rn == FPUL_REG)
+ if (rn == FPUL_REG)
+ x = gen_pop_fpul ();
+ else if (TARGET_SH4 && TARGET_FMOVD && ! TARGET_FPU_SINGLE
+ && rn >= FIRST_FP_REG && rn <= LAST_XD_REG)
+ {
+ if ((rn - FIRST_FP_REG) & 1 && rn <= LAST_FP_REG)
+ return;
+ x = gen_pop_4 (gen_rtx (REG, DFmode, rn));
+ }
+ else if (TARGET_SH3E && rn >= FIRST_FP_REG && rn <= LAST_FP_REG)
x = gen_pop_e (gen_rtx (REG, SFmode, rn));
else
x = gen_pop (gen_rtx (REG, SImode, rn));
@@ -3451,11 +3639,30 @@ calc_live_regs (count_ptr, live_regs_mask2)
int reg;
int live_regs_mask = 0;
int count;
+ int interrupt_handler;
+
+ if ((lookup_attribute
+ ("interrupt_handler",
+ DECL_MACHINE_ATTRIBUTES (current_function_decl)))
+ != NULL_TREE)
+ interrupt_handler = 1;
+ else
+ interrupt_handler = 0;
*live_regs_mask2 = 0;
+ /* If we can save a lot of saves by switching to double mode, do that. */
+ if (TARGET_SH4 && TARGET_FMOVD && TARGET_FPU_SINGLE)
+ for (count = 0, reg = FIRST_FP_REG; reg <= LAST_FP_REG; reg += 2)
+ if (regs_ever_live[reg] && regs_ever_live[reg+1]
+ && (! call_used_regs[reg] || (interrupt_handler && ! pragma_trapa))
+ && ++count > 2)
+ {
+ target_flags &= ~FPU_SINGLE_BIT;
+ break;
+ }
for (count = 0, reg = FIRST_PSEUDO_REGISTER - 1; reg >= 0; reg--)
{
- if ((pragma_interrupt && ! pragma_trapa)
+ if ((interrupt_handler && ! pragma_trapa)
? (/* Need to save all the regs ever live. */
(regs_ever_live[reg]
|| (call_used_regs[reg]
@@ -3463,7 +3670,7 @@ calc_live_regs (count_ptr, live_regs_mask2)
&& regs_ever_live[PR_REG]))
&& reg != STACK_POINTER_REGNUM && reg != ARG_POINTER_REGNUM
&& reg != RETURN_ADDRESS_POINTER_REGNUM
- && reg != T_REG && reg != GBR_REG)
+ && reg != T_REG && reg != GBR_REG && reg != FPSCR_REG)
: (/* Only push those regs which are used and need to be saved. */
regs_ever_live[reg] && ! call_used_regs[reg]))
{
@@ -3472,6 +3679,24 @@ calc_live_regs (count_ptr, live_regs_mask2)
else
live_regs_mask |= 1 << reg;
count++;
+ if (TARGET_SH4 && TARGET_FMOVD && reg >= FIRST_FP_REG)
+ if (reg <= LAST_FP_REG)
+ {
+ if (! TARGET_FPU_SINGLE && ! regs_ever_live[reg ^ 1])
+ {
+ if (reg >= 32)
+ *live_regs_mask2 |= 1 << ((reg ^ 1) - 32);
+ else
+ live_regs_mask |= 1 << (reg ^ 1);
+ count++;
+ }
+ }
+ else if (reg <= LAST_XD_REG)
+ {
+ /* Must switch to double mode to access these registers. */
+ target_flags &= ~FPU_SINGLE_BIT;
+ count++;
+ }
}
}
@@ -3487,6 +3712,7 @@ sh_expand_prologue ()
int live_regs_mask;
int d, i;
int live_regs_mask2;
+ int save_flags = target_flags;
int double_align = 0;
/* We have pretend args if we had an object sent partially in registers
@@ -3503,7 +3729,7 @@ sh_expand_prologue ()
current_function_anonymous_args = 0;
/* This is not used by the SH3E calling convention */
- if (!TARGET_SH3E)
+ if (! TARGET_SH3E && ! TARGET_HITACHI)
{
/* Push arg regs as if they'd been provided by caller in stack. */
for (i = 0; i < NPARM_REGS(SImode); i++)
@@ -3524,11 +3750,19 @@ sh_expand_prologue ()
emit_insn (gen_sp_switch_1 ());
live_regs_mask = calc_live_regs (&d, &live_regs_mask2);
+ /* ??? Maybe we could save some switching if we can move a mode switch
+ that already happens to be at the function start into the prologue. */
+ if (target_flags != save_flags)
+ emit_insn (gen_toggle_sz ());
push_regs (live_regs_mask, live_regs_mask2);
+ if (target_flags != save_flags)
+ emit_insn (gen_toggle_sz ());
if (TARGET_ALIGN_DOUBLE && d & 1)
double_align = 4;
+ target_flags = save_flags;
+
output_stack_adjust (-get_frame_size () - double_align,
stack_pointer_rtx, 3);
@@ -3543,6 +3777,7 @@ sh_expand_epilogue ()
int d, i;
int live_regs_mask2;
+ int save_flags = target_flags;
int frame_size = get_frame_size ();
live_regs_mask = calc_live_regs (&d, &live_regs_mask2);
@@ -3573,7 +3808,8 @@ sh_expand_epilogue ()
/* Pop all the registers. */
- live_regs_mask = calc_live_regs (&d, &live_regs_mask2);
+ if (target_flags != save_flags)
+ emit_insn (gen_toggle_sz ());
if (live_regs_mask & (1 << PR_REG))
pop (PR_REG);
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
@@ -3584,6 +3820,9 @@ sh_expand_epilogue ()
else if (j >= 32 && (live_regs_mask2 & (1 << (j - 32))))
pop (j);
}
+ if (target_flags != save_flags)
+ emit_insn (gen_toggle_sz ());
+ target_flags = save_flags;
output_stack_adjust (extra_push + current_function_pretend_args_size,
stack_pointer_rtx, 7);
@@ -3627,7 +3866,7 @@ sh_builtin_saveregs (arglist)
bufsize = (n_intregs * UNITS_PER_WORD) + (n_floatregs * UNITS_PER_WORD);
regbuf = assign_stack_local (BLKmode, bufsize, 0);
- MEM_IN_STRUCT_P (regbuf) = 1;
+ MEM_SET_IN_STRUCT_P (regbuf, 1);
/* Save int args.
This is optimized to only save the regs that are necessary. Explicitly
@@ -3651,6 +3890,25 @@ sh_builtin_saveregs (arglist)
emit_move_insn (fpregs, XEXP (regbuf, 0));
emit_insn (gen_addsi3 (fpregs, fpregs,
GEN_INT (n_floatregs * UNITS_PER_WORD)));
+ if (TARGET_SH4)
+ {
+ for (regno = NPARM_REGS (DFmode) - 2; regno >= first_floatreg; regno -= 2)
+ {
+ emit_insn (gen_addsi3 (fpregs, fpregs,
+ GEN_INT (-2 * UNITS_PER_WORD)));
+ emit_move_insn (gen_rtx (MEM, DFmode, fpregs),
+ gen_rtx (REG, DFmode, BASE_ARG_REG (DFmode) + regno));
+ }
+ regno = first_floatreg;
+ if (regno & 1)
+ {
+ emit_insn (gen_addsi3 (fpregs, fpregs, GEN_INT (- UNITS_PER_WORD)));
+ emit_move_insn (gen_rtx (MEM, SFmode, fpregs),
+ gen_rtx (REG, SFmode, BASE_ARG_REG (SFmode) + regno
+ - (TARGET_LITTLE_ENDIAN != 0)));
+ }
+ }
+ else
for (regno = NPARM_REGS (SFmode) - 1; regno >= first_floatreg; regno--)
{
emit_insn (gen_addsi3 (fpregs, fpregs, GEN_INT (- UNITS_PER_WORD)));
@@ -3677,6 +3935,8 @@ initial_elimination_offset (from, to)
int live_regs_mask, live_regs_mask2;
live_regs_mask = calc_live_regs (&regs_saved, &live_regs_mask2);
+ if (TARGET_ALIGN_DOUBLE && regs_saved & 1)
+ total_auto_space += 4;
target_flags = save_flags;
total_saved_regs_space = (regs_saved) * 4;
@@ -3724,6 +3984,31 @@ sh_handle_pragma (p_getc, p_ungetc, pname)
return retval;
}
+
+/* Generate 'handle_interrupt' attribute for decls */
+
+void
+sh_pragma_insert_attributes (node, attributes, prefix)
+ tree node;
+ tree * attributes;
+ tree * prefix;
+{
+ tree a;
+
+ if (! pragma_interrupt
+ || TREE_CODE (node) != FUNCTION_DECL)
+ return;
+
+ /* We are only interested in fields. */
+ if (TREE_CODE_CLASS (TREE_CODE (node)) != 'd')
+ return;
+
+ /* Add a 'handle_interrupt' attribute. */
+ * attributes = tree_cons (get_identifier ("interrupt_handler"), NULL, * attributes);
+
+ return;
+}
+
/* Return nonzero if ATTR is a valid attribute for DECL.
ATTRIBUTES are any existing attributes and ARGS are the arguments
supplied with ATTR.
@@ -3752,7 +4037,6 @@ sh_valid_machine_decl_attribute (decl, attributes, attr, args)
if (is_attribute_p ("interrupt_handler", attr))
{
- pragma_interrupt = 1;
return 1;
}
@@ -3885,7 +4169,57 @@ arith_reg_operand (op, mode)
else
return 1;
- return (regno != T_REG && regno != PR_REG && regno != FPUL_REG
+ return (regno != T_REG && regno != PR_REG
+ && (regno != FPUL_REG || TARGET_SH4)
+ && regno != MACH_REG && regno != MACL_REG);
+ }
+ return 0;
+}
+
+int
+fp_arith_reg_operand (op, mode)
+ rtx op;
+ enum machine_mode mode;
+{
+ if (register_operand (op, mode))
+ {
+ int regno;
+
+ if (GET_CODE (op) == REG)
+ regno = REGNO (op);
+ else if (GET_CODE (op) == SUBREG && GET_CODE (SUBREG_REG (op)) == REG)
+ regno = REGNO (SUBREG_REG (op));
+ else
+ return 1;
+
+ return (regno >= FIRST_PSEUDO_REGISTER
+ || (regno >= FIRST_FP_REG && regno <= LAST_FP_REG));
+ }
+ return 0;
+}
+
+int
+fp_extended_operand (op, mode)
+ rtx op;
+ enum machine_mode mode;
+{
+ if (GET_CODE (op) == FLOAT_EXTEND && GET_MODE (op) == mode)
+ {
+ op = XEXP (op, 0);
+ mode = GET_MODE (op);
+ }
+ if (register_operand (op, mode))
+ {
+ int regno;
+
+ if (GET_CODE (op) == REG)
+ regno = REGNO (op);
+ else if (GET_CODE (op) == SUBREG && GET_CODE (SUBREG_REG (op)) == REG)
+ regno = REGNO (SUBREG_REG (op));
+ else
+ return 1;
+
+ return (regno != T_REG && regno != PR_REG && regno > 15
&& regno != MACH_REG && regno != MACL_REG);
}
return 0;
@@ -3991,6 +4325,73 @@ braf_label_ref_operand(op, mode)
if (GET_CODE (prev) != PLUS || XEXP (prev, 1) != op)
return 0;
}
+
+int
+tertiary_reload_operand (op, mode)
+ rtx op;
+ enum machine_mode mode;
+{
+ enum rtx_code code = GET_CODE (op);
+ return code == MEM || (TARGET_SH4 && code == CONST_DOUBLE);
+}
+
+int
+fpscr_operand (op)
+ rtx op;
+{
+ return (GET_CODE (op) == REG && REGNO (op) == FPSCR_REG
+ && GET_MODE (op) == PSImode);
+}
+
+int
+commutative_float_operator (op, mode)
+ rtx op;
+ enum machine_mode mode;
+{
+ if (GET_MODE (op) != mode)
+ return 0;
+ switch (GET_CODE (op))
+ {
+ case PLUS:
+ case MULT:
+ return 1;
+ }
+ return 0;
+}
+
+int
+noncommutative_float_operator (op, mode)
+ rtx op;
+ enum machine_mode mode;
+{
+ if (GET_MODE (op) != mode)
+ return 0;
+ switch (GET_CODE (op))
+ {
+ case MINUS:
+ case DIV:
+ return 1;
+ }
+ return 0;
+}
+
+int
+binary_float_operator (op, mode)
+ rtx op;
+ enum machine_mode mode;
+{
+ if (GET_MODE (op) != mode)
+ return 0;
+ switch (GET_CODE (op))
+ {
+ case PLUS:
+ case MINUS:
+ case MULT:
+ case DIV:
+ return 1;
+ }
+ return 0;
+}
/* Return the destination address of a branch. */
@@ -4102,3 +4503,304 @@ reg_unused_after (reg, insn)
}
return 1;
}
+
+extern struct obstack permanent_obstack;
+
+rtx
+get_fpscr_rtx ()
+{
+ static rtx fpscr_rtx;
+
+ if (! fpscr_rtx)
+ {
+ push_obstacks (&permanent_obstack, &permanent_obstack);
+ fpscr_rtx = gen_rtx (REG, PSImode, 48);
+ REG_USERVAR_P (fpscr_rtx) = 1;
+ pop_obstacks ();
+ mark_user_reg (fpscr_rtx);
+ }
+ if (! reload_completed || mdep_reorg_phase != SH_AFTER_MDEP_REORG)
+ mark_user_reg (fpscr_rtx);
+ return fpscr_rtx;
+}
+
+void
+emit_sf_insn (pat)
+ rtx pat;
+{
+ rtx addr;
+ /* When generating reload insns, we must not create new registers. FPSCR
+ should already have the correct value, so do nothing to change it. */
+ if (! TARGET_FPU_SINGLE && ! reload_in_progress)
+ {
+ addr = gen_reg_rtx (SImode);
+ emit_insn (gen_fpu_switch0 (addr));
+ }
+ emit_insn (pat);
+ if (! TARGET_FPU_SINGLE && ! reload_in_progress)
+ {
+ addr = gen_reg_rtx (SImode);
+ emit_insn (gen_fpu_switch1 (addr));
+ }
+}
+
+void
+emit_df_insn (pat)
+ rtx pat;
+{
+ rtx addr;
+ if (TARGET_FPU_SINGLE && ! reload_in_progress)
+ {
+ addr = gen_reg_rtx (SImode);
+ emit_insn (gen_fpu_switch0 (addr));
+ }
+ emit_insn (pat);
+ if (TARGET_FPU_SINGLE && ! reload_in_progress)
+ {
+ addr = gen_reg_rtx (SImode);
+ emit_insn (gen_fpu_switch1 (addr));
+ }
+}
+
+void
+expand_sf_unop (fun, operands)
+ rtx (*fun)();
+ rtx *operands;
+{
+ emit_sf_insn ((*fun) (operands[0], operands[1], get_fpscr_rtx ()));
+}
+
+void
+expand_sf_binop (fun, operands)
+ rtx (*fun)();
+ rtx *operands;
+{
+ emit_sf_insn ((*fun) (operands[0], operands[1], operands[2],
+ get_fpscr_rtx ()));
+}
+
+void
+expand_df_unop (fun, operands)
+ rtx (*fun)();
+ rtx *operands;
+{
+ emit_df_insn ((*fun) (operands[0], operands[1], get_fpscr_rtx ()));
+}
+
+void
+expand_df_binop (fun, operands)
+ rtx (*fun)();
+ rtx *operands;
+{
+ emit_df_insn ((*fun) (operands[0], operands[1], operands[2],
+ get_fpscr_rtx ()));
+}
+
+void
+expand_fp_branch (compare, branch)
+ rtx (*compare) (), (*branch) ();
+{
+ (GET_MODE (sh_compare_op0) == SFmode ? emit_sf_insn : emit_df_insn)
+ ((*compare) ());
+ emit_jump_insn ((*branch) ());
+}
+
+/* We don't want to make fpscr call-saved, because that would prevent
+ channging it, and it would also cost an exstra instruction to save it.
+ We don't want it to be known as a global register either, because
+ that disables all flow analysis. But it has to be live at the function
+ return. Thus, we need to insert a USE at the end of the function. */
+/* This should best be called at about the time FINALIZE_PIC is called,
+ but not dependent on flag_pic. Alas, there is no suitable hook there,
+ so this gets called from HAVE_RETURN. */
+int
+emit_fpscr_use ()
+{
+ static int fpscr_uses = 0;
+
+ if (rtx_equal_function_value_matters)
+ {
+ emit_insn (gen_rtx (USE, VOIDmode, get_fpscr_rtx ()));
+ fpscr_uses++;
+ }
+ else
+ {
+ if (fpscr_uses > 1)
+ {
+ /* Due to he crude way we emit the USEs, we might end up with
+ some extra ones. Delete all but the last one. */
+ rtx insn;
+
+ for (insn = get_last_insn(); insn; insn = PREV_INSN (insn))
+ if (GET_CODE (insn) == INSN
+ && GET_CODE (PATTERN (insn)) == USE
+ && GET_CODE (XEXP (PATTERN (insn), 0)) == REG
+ && REGNO (XEXP (PATTERN (insn), 0)) == FPSCR_REG)
+ {
+ insn = PREV_INSN (insn);
+ break;
+ }
+ for (; insn; insn = PREV_INSN (insn))
+ if (GET_CODE (insn) == INSN
+ && GET_CODE (PATTERN (insn)) == USE
+ && GET_CODE (XEXP (PATTERN (insn), 0)) == REG
+ && REGNO (XEXP (PATTERN (insn), 0)) == FPSCR_REG)
+ {
+ PUT_CODE (insn, NOTE);
+ NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
+ NOTE_SOURCE_FILE (insn) = 0;
+ }
+ }
+ fpscr_uses = 0;
+ }
+}
+
+/* ??? gcc does flow analysis strictly after common subexpression
+ elimination. As a result, common subespression elimination fails
+ when there are some intervening statements setting the same register.
+ If we did nothing about this, this would hurt the precision switching
+ for SH4 badly. There is some cse after reload, but it is unable to
+ undo the extra register pressure from the unused instructions, and
+ it cannot remove auto-increment loads.
+
+ A C code example that shows this flow/cse weakness for (at least) SH
+ and sparc (as of gcc ss-970706) is this:
+
+double
+f(double a)
+{
+ double d;
+ d = 0.1;
+ a += d;
+ d = 1.1;
+ d = 0.1;
+ a *= d;
+ return a;
+}
+
+ So we add another pass before common subexpression elimination, to
+ remove assignments that are dead due to a following assignment in the
+ same basic block. */
+
+int sh_flag_remove_dead_before_cse;
+
+static void
+mark_use (x, reg_set_block)
+ rtx x, *reg_set_block;
+{
+ enum rtx_code code;
+
+ if (! x)
+ return;
+ code = GET_CODE (x);
+ switch (code)
+ {
+ case REG:
+ {
+ int regno = REGNO (x);
+ int nregs = (regno < FIRST_PSEUDO_REGISTER
+ ? HARD_REGNO_NREGS (regno, GET_MODE (x))
+ : 1);
+ do
+ {
+ reg_set_block[regno + nregs - 1] = 0;
+ }
+ while (--nregs);
+ break;
+ }
+ case SET:
+ {
+ rtx dest = SET_DEST (x);
+
+ if (GET_CODE (dest) == SUBREG)
+ dest = SUBREG_REG (dest);
+ if (GET_CODE (dest) != REG)
+ mark_use (dest, reg_set_block);
+ mark_use (SET_SRC (x), reg_set_block);
+ break;
+ }
+ case CLOBBER:
+ break;
+ default:
+ {
+ char *fmt = GET_RTX_FORMAT (code);
+ int i, j;
+ for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
+ {
+ if (fmt[i] == 'e')
+ mark_use (XEXP (x, i), reg_set_block);
+ else if (fmt[i] == 'E')
+ for (j = XVECLEN (x, i) - 1; j >= 0; j--)
+ mark_use (XVECEXP (x, i, j), reg_set_block);
+ }
+ break;
+ }
+ }
+}
+
+int
+remove_dead_before_cse ()
+{
+ rtx *reg_set_block, last, last_call, insn, set;
+ int in_libcall = 0;
+
+ /* This pass should run just once, after rtl generation. */
+
+ if (! sh_flag_remove_dead_before_cse
+ || rtx_equal_function_value_matters
+ || reload_completed)
+ return;
+
+ sh_flag_remove_dead_before_cse = 0;
+
+ reg_set_block = (rtx *)alloca (max_reg_num () * sizeof (rtx));
+ bzero ((char *)reg_set_block, max_reg_num () * sizeof (rtx));
+ last_call = last = get_last_insn ();
+ for (insn = last; insn; insn = PREV_INSN (insn))
+ {
+ if (GET_RTX_CLASS (GET_CODE (insn)) != 'i')
+ continue;
+ if (GET_CODE (insn) == JUMP_INSN)
+ {
+ last_call = last = insn;
+ continue;
+ }
+ set = single_set (insn);
+
+ /* Don't delete parts of libcalls, since that would confuse cse, loop
+ and flow. */
+ if (find_reg_note (insn, REG_RETVAL, NULL_RTX))
+ in_libcall = 1;
+ else if (in_libcall)
+ {
+ if (find_reg_note (insn, REG_LIBCALL, NULL_RTX))
+ in_libcall = 0;
+ }
+ else if (set && GET_CODE (SET_DEST (set)) == REG)
+ {
+ int regno = REGNO (SET_DEST (set));
+ rtx ref_insn = (regno < FIRST_PSEUDO_REGISTER && call_used_regs[regno]
+ ? last_call
+ : last);
+ if (reg_set_block[regno] == ref_insn
+ && (regno >= FIRST_PSEUDO_REGISTER
+ || HARD_REGNO_NREGS (regno, GET_MODE (SET_DEST (set))) == 1)
+ && (GET_CODE (insn) != CALL_INSN || CONST_CALL_P (insn)))
+ {
+ PUT_CODE (insn, NOTE);
+ NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
+ NOTE_SOURCE_FILE (insn) = 0;
+ continue;
+ }
+ else
+ reg_set_block[REGNO (SET_DEST (set))] = ref_insn;
+ }
+ if (GET_CODE (insn) == CALL_INSN)
+ {
+ last_call = insn;
+ mark_use (CALL_INSN_FUNCTION_USAGE (insn), reg_set_block);
+ }
+ mark_use (PATTERN (insn), reg_set_block);
+ }
+ return 0;
+}
diff --git a/gcc/config/sh/sh.h b/gcc/config/sh/sh.h
index ebffc4dd628..2f2a000b89d 100644
--- a/gcc/config/sh/sh.h
+++ b/gcc/config/sh/sh.h
@@ -1,5 +1,5 @@
/* Definitions of target machine for GNU compiler for Hitachi Super-H.
- Copyright (C) 1993, 1994, 1995, 1996, 1997 Free Software Foundation, Inc.
+ Copyright (C) 1993-1998 Free Software Foundation, Inc.
Contributed by Steve Chamberlain (sac@cygnus.com).
Improved by Jim Wilson (wilson@cygnus.com).
@@ -43,7 +43,11 @@ extern int code_for_indirect_jump_scratch;
%{m2:-D__sh2__} \
%{m3:-D__sh3__} \
%{m3e:-D__SH3E__} \
-%{!m1:%{!m2:%{!m3:%{!m3e:-D__sh1__}}}}"
+%{m4-single-only:-D__SH4_SINGLE_ONLY__} \
+%{m4-single:-D__SH4_SINGLE__} \
+%{m4:-D__SH4__} \
+%{!m1:%{!m2:%{!m3:%{!m3e:%{!m4:%{!m4-single:%{!m4-single-only:-D__sh1__}}}}}}} \
+%{mhitachi:-D__HITACHI__}"
#define CPP_PREDEFINES "-D__sh__ -Acpu(sh) -Amachine(sh)"
@@ -54,19 +58,28 @@ extern int code_for_indirect_jump_scratch;
/* We can not debug without a frame pointer. */
/* #define CAN_DEBUG_WITHOUT_FP */
-#define CONDITIONAL_REGISTER_USAGE \
- if (! TARGET_SH3E) \
- { \
- int regno; \
- for (regno = FIRST_FP_REG; regno <= LAST_FP_REG; regno++) \
- fixed_regs[regno] = call_used_regs[regno] = 1; \
- fixed_regs[FPUL_REG] = call_used_regs[FPUL_REG] = 1; \
- } \
- /* Hitachi saves and restores mac registers on call. */ \
- if (TARGET_HITACHI) \
- { \
- call_used_regs[MACH_REG] = 0; \
- call_used_regs[MACL_REG] = 0; \
+#define CONDITIONAL_REGISTER_USAGE \
+ if (! TARGET_SH4 || ! TARGET_FMOVD) \
+ { \
+ int regno; \
+ for (regno = FIRST_XD_REG; regno <= LAST_XD_REG; regno++) \
+ fixed_regs[regno] = call_used_regs[regno] = 1; \
+ if (! TARGET_SH4) \
+ { \
+ if (! TARGET_SH3E) \
+ { \
+ int regno; \
+ for (regno = FIRST_FP_REG; regno <= LAST_FP_REG; regno++) \
+ fixed_regs[regno] = call_used_regs[regno] = 1; \
+ fixed_regs[FPUL_REG] = call_used_regs[FPUL_REG] = 1; \
+ } \
+ } \
+ } \
+ /* Hitachi saves and restores mac registers on call. */ \
+ if (TARGET_HITACHI) \
+ { \
+ call_used_regs[MACH_REG] = 0; \
+ call_used_regs[MACL_REG] = 0; \
}
/* ??? Need to write documentation for all SH options and add it to the
@@ -81,6 +94,10 @@ extern int target_flags;
#define SH2_BIT (1<<9)
#define SH3_BIT (1<<10)
#define SH3E_BIT (1<<11)
+#define HARD_SH4_BIT (1<<5)
+#define FPU_SINGLE_BIT (1<<7)
+#define SH4_BIT (1<<12)
+#define FMOVD_BIT (1<<4)
#define SPACE_BIT (1<<13)
#define BIGTABLE_BIT (1<<14)
#define RELAX_BIT (1<<15)
@@ -107,6 +124,27 @@ extern int target_flags;
/* Nonzero if we should generate code using type 3E insns. */
#define TARGET_SH3E (target_flags & SH3E_BIT)
+/* Nonzero if the cache line size is 32. */
+#define TARGET_CACHE32 (target_flags & HARD_SH4_BIT)
+
+/* Nonzero if we schedule for a superscalar implementation. */
+#define TARGET_SUPERSCALAR (target_flags & HARD_SH4_BIT)
+
+/* Nonzero if the target has separate instruction and data caches. */
+#define TARGET_HARWARD (target_flags & HARD_SH4_BIT)
+
+/* Nonzero if compiling for SH4 hardware (to be used for insn costs etc.) */
+#define TARGET_HARD_SH4 (target_flags & HARD_SH4_BIT)
+
+/* Nonzero if the default precision of th FPU is single */
+#define TARGET_FPU_SINGLE (target_flags & FPU_SINGLE_BIT)
+
+/* Nonzero if we should generate code using type 4 insns. */
+#define TARGET_SH4 (target_flags & SH4_BIT)
+
+/* Nonzero if we should generate fmovd. */
+#define TARGET_FMOVD (target_flags & FMOVD_BIT)
+
/* Nonzero if we respect NANs. */
#define TARGET_IEEE (target_flags & IEEE_BIT)
@@ -137,10 +175,14 @@ extern int target_flags;
{ {"1", SH1_BIT}, \
{"2", SH2_BIT}, \
{"3", SH3_BIT|SH2_BIT}, \
- {"3e", SH3E_BIT|SH3_BIT|SH2_BIT}, \
+ {"3e", SH3E_BIT|SH3_BIT|SH2_BIT|FPU_SINGLE_BIT}, \
+ {"4-single-only", SH3E_BIT|SH3_BIT|SH2_BIT|SH3E_BIT|HARD_SH4_BIT|FPU_SINGLE_BIT}, \
+ {"4-single", SH4_BIT|SH3E_BIT|SH3_BIT|SH2_BIT|HARD_SH4_BIT|FPU_SINGLE_BIT},\
+ {"4", SH4_BIT|SH3E_BIT|SH3_BIT|SH2_BIT|HARD_SH4_BIT}, \
{"b", -LITTLE_ENDIAN_BIT}, \
{"bigtable", BIGTABLE_BIT}, \
{"dalign", DALIGN_BIT}, \
+ {"fmovd", FMOVD_BIT}, \
{"hitachi", HITACHI_BIT}, \
{"ieee", IEEE_BIT}, \
{"isize", ISIZE_BIT}, \
@@ -158,30 +200,60 @@ extern int target_flags;
#define TARGET_DEFAULT (0)
-#define PRESERVE_DEATH_INFO_REGNO_P(regno) (TARGET_RELAX || optimize)
-
#define OPTIMIZATION_OPTIONS(LEVEL,SIZE) \
do { \
+ if (LEVEL) \
+ flag_omit_frame_pointer = -1; \
+ if (LEVEL) \
+ sh_flag_remove_dead_before_cse = 1; \
if (SIZE) \
target_flags |= SPACE_BIT; \
} while (0)
-#define ASSEMBLER_DIALECT 0 /* will allow to distinguish b[tf].s and b[tf]/s . */
-#define OVERRIDE_OPTIONS \
-do { \
- sh_cpu = CPU_SH1; \
- if (TARGET_SH2) \
- sh_cpu = CPU_SH2; \
- if (TARGET_SH3) \
- sh_cpu = CPU_SH3; \
- if (TARGET_SH3E) \
- sh_cpu = CPU_SH3E; \
- \
- /* Never run scheduling before reload, since that can \
- break global alloc, and generates slower code anyway due \
- to the pressure on R0. */ \
- flag_schedule_insns = 0; \
- sh_addr_diff_vec_mode = TARGET_BIGTABLE ? SImode : HImode; \
+#define ASSEMBLER_DIALECT assembler_dialect
+
+extern int assembler_dialect;
+
+#define OVERRIDE_OPTIONS \
+do { \
+ sh_cpu = CPU_SH1; \
+ assembler_dialect = 0; \
+ if (TARGET_SH2) \
+ sh_cpu = CPU_SH2; \
+ if (TARGET_SH3) \
+ sh_cpu = CPU_SH3; \
+ if (TARGET_SH3E) \
+ sh_cpu = CPU_SH3E; \
+ if (TARGET_SH4) \
+ { \
+ assembler_dialect = 1; \
+ sh_cpu = CPU_SH4; \
+ } \
+ if (! TARGET_SH4 || ! TARGET_FMOVD) \
+ { \
+ /* Prevent usage of explicit register names for variables \
+ for registers not present / not addressable in the \
+ target architecture. */ \
+ int regno; \
+ for (regno = (TARGET_SH3E) ? 17 : 0; \
+ regno <= 24; regno++) \
+ fp_reg_names[regno][0] = 0; \
+ } \
+ if (flag_omit_frame_pointer < 0) \
+ /* The debugging information is sufficient, \
+ but gdb doesn't implement this yet */ \
+ if (0) \
+ flag_omit_frame_pointer \
+ = (PREFERRED_DEBUGGING_TYPE == DWARF_DEBUG \
+ || PREFERRED_DEBUGGING_TYPE == DWARF2_DEBUG); \
+ else \
+ flag_omit_frame_pointer = 0; \
+ \
+ /* Never run scheduling before reload, since that can \
+ break global alloc, and generates slower code anyway due \
+ to the pressure on R0. */ \
+ flag_schedule_insns = 0; \
+ sh_addr_diff_vec_mode = TARGET_BIGTABLE ? SImode : HImode; \
} while (0)
/* Target machine storage layout. */
@@ -234,8 +306,9 @@ do { \
#define STACK_BOUNDARY BIGGEST_ALIGNMENT
/* The log (base 2) of the cache line size, in bytes. Processors prior to
- SH3 have no actual cache, but they fetch code in chunks of 4 bytes. */
-#define CACHE_LOG (TARGET_SH3 ? 4 : 2)
+ SH2 have no actual cache, but they fetch code in chunks of 4 bytes.
+ The SH2/3 have 16 byte cache lines, and the SH4 has a 32 byte cache line */
+#define CACHE_LOG (TARGET_CACHE32 ? 5 : TARGET_SH2 ? 4 : 2)
/* Allocation boundary (in *bits*) for the code of a function.
32 bit alignment is faster, because instructions are always fetched as a
@@ -281,7 +354,7 @@ do { \
barrier_align (LABEL_AFTER_BARRIER)
#define LOOP_ALIGN(A_LABEL) \
- ((! optimize || TARGET_SMALLCODE) ? 0 : 2)
+ ((! optimize || TARGET_HARWARD || TARGET_SMALLCODE) ? 0 : 2)
#define LABEL_ALIGN(A_LABEL) \
( \
@@ -343,8 +416,11 @@ do { \
#define RAP_REG 23
#define FIRST_FP_REG 24
#define LAST_FP_REG 39
+#define FIRST_XD_REG 40
+#define LAST_XD_REG 47
+#define FPSCR_REG 48
-#define FIRST_PSEUDO_REGISTER 40
+#define FIRST_PSEUDO_REGISTER 49
/* 1 for registers that have pervasive standard uses
and are not available for the register allocator.
@@ -363,6 +439,9 @@ do { \
0, 0, 0, 0, \
0, 0, 0, 0, \
0, 0, 0, 0, \
+ 0, 0, 0, 0, \
+ 0, 0, 0, 0, \
+ 1, \
}
/* 1 for registers not available across function calls.
@@ -383,6 +462,9 @@ do { \
1, 1, 1, 1, \
1, 1, 1, 1, \
0, 0, 0, 0, \
+ 1, 1, 1, 1, \
+ 1, 1, 0, 0, \
+ 1, \
}
/* Return number of consecutive hard regs needed starting at reg REGNO
@@ -390,20 +472,39 @@ do { \
This is ordinarily the length in words of a value of mode MODE
but can be less for certain modes in special long registers.
- On the SH regs are UNITS_PER_WORD bits wide. */
+ On the SH all but the XD regs are UNITS_PER_WORD bits wide. */
#define HARD_REGNO_NREGS(REGNO, MODE) \
- (((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
+ ((REGNO) >= FIRST_XD_REG && (REGNO) <= LAST_XD_REG \
+ ? (GET_MODE_SIZE (MODE) / (2 * UNITS_PER_WORD)) \
+ : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)) \
/* Value is 1 if hard register REGNO can hold a value of machine-mode MODE.
We can allow any mode in any general register. The special registers
only allow SImode. Don't allow any mode in the PR. */
+/* We cannot hold DCmode values in the XD registers because alter_reg
+ handles subregs of them incorrectly. We could work around this by
+ spacing the XD registers like the DR registers, but this would require
+ additional memory in every compilation to hold larger register vectors.
+ We could hold SFmode / SCmode values in XD registers, but that
+ would require a tertiary reload when reloading from / to memory,
+ and a secondary reload to reload from / to general regs; that
+ seems to be a loosing proposition. */
#define HARD_REGNO_MODE_OK(REGNO, MODE) \
(SPECIAL_REG (REGNO) ? (MODE) == SImode \
: (REGNO) == FPUL_REG ? (MODE) == SImode || (MODE) == SFmode \
- : (REGNO) >= FIRST_FP_REG && (REGNO) <= LAST_FP_REG ? (MODE) == SFmode \
+ : (REGNO) >= FIRST_FP_REG && (REGNO) <= LAST_FP_REG && (MODE) == SFmode \
+ ? 1 \
+ : (REGNO) >= FIRST_FP_REG && (REGNO) <= LAST_FP_REG \
+ ? ((MODE) == SFmode \
+ || (TARGET_SH3E && (MODE) == SCmode) \
+ || (((TARGET_SH4 && (MODE) == DFmode) || (MODE) == DCmode) \
+ && (((REGNO) - FIRST_FP_REG) & 1) == 0)) \
+ : (REGNO) >= FIRST_XD_REG && (REGNO) <= LAST_XD_REG \
+ ? (MODE) == DFmode \
: (REGNO) == PR_REG ? 0 \
+ : (REGNO) == FPSCR_REG ? (MODE) == PSImode \
: 1)
/* Value is 1 if it is a good idea to tie two pseudo registers
@@ -543,6 +644,8 @@ enum reg_class
GENERAL_REGS,
FP0_REGS,
FP_REGS,
+ DF_REGS,
+ FPSCR_REGS,
GENERAL_FP_REGS,
ALL_REGS,
LIM_REG_CLASSES
@@ -562,6 +665,8 @@ enum reg_class
"GENERAL_REGS", \
"FP0_REGS", \
"FP_REGS", \
+ "DF_REGS", \
+ "FPSCR_REGS", \
"GENERAL_FP_REGS", \
"ALL_REGS", \
}
@@ -581,8 +686,10 @@ enum reg_class
{ 0x0081FFFF, 0x00000000 }, /* GENERAL_REGS */ \
{ 0x01000000, 0x00000000 }, /* FP0_REGS */ \
{ 0xFF000000, 0x000000FF }, /* FP_REGS */ \
- { 0xFF81FFFF, 0x000000FF }, /* GENERAL_FP_REGS */ \
- { 0xFFFFFFFF, 0x000000FF }, /* ALL_REGS */ \
+ { 0xFF000000, 0x0000FFFF }, /* DF_REGS */ \
+ { 0x00000000, 0x00010000 }, /* FPSCR_REGS */ \
+ { 0xFF81FFFF, 0x0000FFFF }, /* GENERAL_FP_REGS */ \
+ { 0xFFFFFFFF, 0x0001FFFF }, /* ALL_REGS */ \
}
/* The same information, inverted:
@@ -605,6 +712,7 @@ extern int regno_reg_class[];
spilled or used otherwise, we better have the FP_REGS allocated first. */
#define REG_ALLOC_ORDER \
{ 25,26,27,28,29,30,31,24,32,33,34,35,36,37,38,39, \
+ 40,41,42,43,44,45,46,47,48, \
1,2,3,7,6,5,4,0,8,9,10,11,12,13,14, \
22,15,16,17,18,19,20,21,23 }
@@ -659,7 +767,8 @@ extern enum reg_class reg_class_from_letter[];
#define PREFERRED_RELOAD_CLASS(X, CLASS) (CLASS)
#define SECONDARY_OUTPUT_RELOAD_CLASS(CLASS,MODE,X) \
- ((((((CLASS) == FP_REGS || (CLASS) == FP0_REGS) \
+ ((((((CLASS) == FP_REGS || (CLASS) == FP0_REGS \
+ || (CLASS) == DF_REGS) \
&& (GET_CODE (X) == REG && REGNO (X) <= AP_REG)) \
|| (((CLASS) == GENERAL_REGS || (CLASS) == R0_REGS) \
&& GET_CODE (X) == REG \
@@ -668,7 +777,7 @@ extern enum reg_class reg_class_from_letter[];
? FPUL_REGS \
: ((CLASS) == FPUL_REGS \
&& (GET_CODE (X) == MEM \
- || GET_CODE (X) == REG && REGNO (X) >= FIRST_PSEUDO_REGISTER))\
+ || (GET_CODE (X) == REG && REGNO (X) >= FIRST_PSEUDO_REGISTER)))\
? GENERAL_REGS \
: (((CLASS) == MAC_REGS || (CLASS) == PR_REGS) \
&& GET_CODE (X) == REG && REGNO (X) > 15 \
@@ -676,10 +785,19 @@ extern enum reg_class reg_class_from_letter[];
? GENERAL_REGS : NO_REGS)
#define SECONDARY_INPUT_RELOAD_CLASS(CLASS,MODE,X) \
- ((((CLASS) == FP_REGS || (CLASS) == FP0_REGS) \
+ ((((CLASS) == FP_REGS || (CLASS) == FP0_REGS || (CLASS) == DF_REGS) \
&& immediate_operand ((X), (MODE)) \
- && ! (fp_zero_operand (X) || fp_one_operand (X))) \
- ? R0_REGS : SECONDARY_OUTPUT_RELOAD_CLASS((CLASS),(MODE),(X)))
+ && ! ((fp_zero_operand (X) || fp_one_operand (X)) && (MODE) == SFmode))\
+ ? R0_REGS \
+ : CLASS == FPUL_REGS && immediate_operand ((X), (MODE)) \
+ ? (GET_CODE (X) == CONST_INT && CONST_OK_FOR_I (INTVAL (X)) \
+ ? GENERAL_REGS \
+ : R0_REGS) \
+ : (CLASS == FPSCR_REGS \
+ && ((GET_CODE (X) == REG && REGNO (X) >= FIRST_PSEUDO_REGISTER) \
+ || GET_CODE (X) == MEM && GET_CODE (XEXP ((X), 0)) == PLUS)) \
+ ? GENERAL_REGS \
+ : SECONDARY_OUTPUT_RELOAD_CLASS((CLASS),(MODE),(X)))
/* Return the maximum number of consecutive registers
needed to represent mode MODE in a register of class CLASS.
@@ -687,6 +805,11 @@ extern enum reg_class reg_class_from_letter[];
On SH this is the size of MODE in words. */
#define CLASS_MAX_NREGS(CLASS, MODE) \
((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
+
+/* If defined, gives a class of registers that cannot be used as the
+ operand of a SUBREG that changes the size of the object. */
+
+#define CLASS_CANNOT_CHANGE_SIZE DF_REGS
/* Stack layout; function entry, exit and calling. */
@@ -696,6 +819,9 @@ extern enum reg_class reg_class_from_letter[];
#define NPARM_REGS(MODE) \
(TARGET_SH3E && (MODE) == SFmode \
? 8 \
+ : TARGET_SH4 && (GET_MODE_CLASS (MODE) == MODE_FLOAT \
+ || GET_MODE_CLASS (MODE) == MODE_COMPLEX_FLOAT) \
+ ? 8 \
: 4)
#define FIRST_PARM_REG 4
@@ -754,25 +880,48 @@ extern enum reg_class reg_class_from_letter[];
#define BASE_RETURN_VALUE_REG(MODE) \
((TARGET_SH3E && ((MODE) == SFmode)) \
? FIRST_FP_RET_REG \
+ : TARGET_SH3E && (MODE) == SCmode \
+ ? FIRST_FP_RET_REG \
+ : (TARGET_SH4 \
+ && ((MODE) == DFmode || (MODE) == SFmode \
+ || (MODE) == DCmode || (MODE) == SCmode )) \
+ ? FIRST_FP_RET_REG \
: FIRST_RET_REG)
#define BASE_ARG_REG(MODE) \
((TARGET_SH3E && ((MODE) == SFmode)) \
? FIRST_FP_PARM_REG \
+ : TARGET_SH4 && (GET_MODE_CLASS (MODE) == MODE_FLOAT \
+ || GET_MODE_CLASS (MODE) == MODE_COMPLEX_FLOAT)\
+ ? FIRST_FP_PARM_REG \
: FIRST_PARM_REG)
/* Define how to find the value returned by a function.
VALTYPE is the data type of the value (as a tree).
If the precise function being called is known, FUNC is its FUNCTION_DECL;
- otherwise, FUNC is 0. */
-
-#define FUNCTION_VALUE(VALTYPE, FUNC) \
- LIBCALL_VALUE (TYPE_MODE (VALTYPE))
+ otherwise, FUNC is 0.
+ For the SH, this is like LIBCALL_VALUE, except that we must change the
+ mode like PROMOTE_MODE does.
+ ??? PROMOTE_MODE is ignored for non-scalar types. The set of types
+ tested here has to be kept in sync with the one in explow.c:promote_mode. */
+
+#define FUNCTION_VALUE(VALTYPE, FUNC) \
+ gen_rtx (REG, \
+ ((GET_MODE_CLASS (TYPE_MODE (VALTYPE)) == MODE_INT \
+ && GET_MODE_SIZE (TYPE_MODE (VALTYPE)) < UNITS_PER_WORD \
+ && (TREE_CODE (VALTYPE) == INTEGER_TYPE \
+ || TREE_CODE (VALTYPE) == ENUMERAL_TYPE \
+ || TREE_CODE (VALTYPE) == BOOLEAN_TYPE \
+ || TREE_CODE (VALTYPE) == CHAR_TYPE \
+ || TREE_CODE (VALTYPE) == REAL_TYPE \
+ || TREE_CODE (VALTYPE) == OFFSET_TYPE)) \
+ ? SImode : TYPE_MODE (VALTYPE)), \
+ BASE_RETURN_VALUE_REG (TYPE_MODE (VALTYPE)))
/* Define how to find the value returned by a library function
assuming the value has mode MODE. */
#define LIBCALL_VALUE(MODE) \
- gen_rtx (REG, (MODE), BASE_RETURN_VALUE_REG (MODE));
+ gen_rtx (REG, (MODE), BASE_RETURN_VALUE_REG (MODE))
/* 1 if N is a possible register number for a function value. */
#define FUNCTION_VALUE_REGNO_P(REGNO) \
@@ -803,7 +952,11 @@ struct sh_args {
#define CUMULATIVE_ARGS struct sh_args
#define GET_SH_ARG_CLASS(MODE) \
- ((TARGET_SH3E && ((MODE) == SFmode)) ? SH_ARG_FLOAT : SH_ARG_INT)
+ ((TARGET_SH3E && (MODE) == SFmode) \
+ ? SH_ARG_FLOAT \
+ : TARGET_SH4 && (GET_MODE_CLASS (MODE) == MODE_FLOAT \
+ || GET_MODE_CLASS (MODE) == MODE_COMPLEX_FLOAT) \
+ ? SH_ARG_FLOAT : SH_ARG_INT)
#define ROUND_ADVANCE(SIZE) \
(((SIZE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
@@ -815,7 +968,9 @@ struct sh_args {
round doubles to even regs when asked to explicitly. */
#define ROUND_REG(CUM, MODE) \
- ((TARGET_ALIGN_DOUBLE \
+ (((TARGET_ALIGN_DOUBLE \
+ || (TARGET_SH4 && ((MODE) == DFmode || (MODE) == DCmode) \
+ && (CUM).arg_count[(int) SH_ARG_FLOAT] < NPARM_REGS (MODE)))\
&& GET_MODE_UNIT_SIZE ((MODE)) > UNITS_PER_WORD) \
? ((CUM).arg_count[(int) GET_SH_ARG_CLASS (MODE)] \
+ ((CUM).arg_count[(int) GET_SH_ARG_CLASS (MODE)] & 1)) \
@@ -840,17 +995,20 @@ struct sh_args {
available.) */
#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \
- ((CUM).arg_count[(int) GET_SH_ARG_CLASS (MODE)] = \
- (ROUND_REG ((CUM), (MODE)) \
- + ((MODE) != BLKmode \
- ? ROUND_ADVANCE (GET_MODE_SIZE (MODE)) \
- : ROUND_ADVANCE (int_size_in_bytes (TYPE)))))
+ if (! TARGET_SH4 || PASS_IN_REG_P ((CUM), (MODE), (TYPE))) \
+ ((CUM).arg_count[(int) GET_SH_ARG_CLASS (MODE)] \
+ = (ROUND_REG ((CUM), (MODE)) \
+ + ((MODE) == BLKmode \
+ ? ROUND_ADVANCE (int_size_in_bytes (TYPE)) \
+ : ROUND_ADVANCE (GET_MODE_SIZE (MODE)))))
/* Return boolean indicating arg of mode MODE will be passed in a reg.
This macro is only used in this file. */
#define PASS_IN_REG_P(CUM, MODE, TYPE) \
- (((TYPE) == 0 || ! TREE_ADDRESSABLE ((tree)(TYPE))) \
+ (((TYPE) == 0 \
+ || (! TREE_ADDRESSABLE ((tree)(TYPE))) \
+ && (! TARGET_HITACHI || ! AGGREGATE_TYPE_P (TYPE))) \
&& (TARGET_SH3E \
? ((MODE) == BLKmode \
? (((CUM).arg_count[(int) SH_ARG_INT] * UNITS_PER_WORD \
@@ -883,11 +1041,16 @@ extern int current_function_varargs;
#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \
((PASS_IN_REG_P ((CUM), (MODE), (TYPE)) \
- && ((NAMED) || TARGET_SH3E || ! current_function_varargs)) \
+ && ((NAMED) \
+ || (! TARGET_HITACHI && (TARGET_SH3E || ! current_function_varargs)))) \
? gen_rtx (REG, (MODE), \
- (BASE_ARG_REG (MODE) + ROUND_REG ((CUM), (MODE)))) \
+ ((BASE_ARG_REG (MODE) + ROUND_REG ((CUM), (MODE))) \
+ ^ ((MODE) == SFmode && TARGET_SH4 \
+ && TARGET_LITTLE_ENDIAN != 0))) \
: 0)
+#define PRETEND_OUTGOING_VARARGS_NAMED (! TARGET_HITACHI)
+
/* For an arg passed partly in registers and partly in memory,
this is the number of registers used.
For args passed entirely in registers or entirely in memory, zero.
@@ -896,8 +1059,9 @@ extern int current_function_varargs;
#define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) \
((PASS_IN_REG_P ((CUM), (MODE), (TYPE)) \
+ && ! TARGET_SH4 \
&& (ROUND_REG ((CUM), (MODE)) \
- + (MODE != BLKmode \
+ + ((MODE) != BLKmode \
? ROUND_ADVANCE (GET_MODE_SIZE (MODE)) \
: ROUND_ADVANCE (int_size_in_bytes (TYPE))) \
- NPARM_REGS (MODE) > 0)) \
@@ -957,7 +1121,7 @@ extern int current_function_anonymous_args;
/* Alignment required for a trampoline in bits . */
#define TRAMPOLINE_ALIGNMENT \
- ((CACHE_LOG < 3 || TARGET_SMALLCODE) ? 32 : 64) \
+ ((CACHE_LOG < 3 || TARGET_SMALLCODE && ! TARGET_HARWARD) ? 32 : 64)
/* Emit RTL insns to initialize the variable parts of a trampoline.
FNADDR is an RTX for the address of the function's pure code.
@@ -973,6 +1137,8 @@ extern int current_function_anonymous_args;
(CXT)); \
emit_move_insn (gen_rtx (MEM, SImode, plus_constant ((TRAMP), 12)), \
(FNADDR)); \
+ if (TARGET_HARWARD) \
+ emit_insn (gen_ic_invalidate_line (TRAMP)); \
}
/* A C expression whose value is RTL representing the value of the return
@@ -996,6 +1162,17 @@ extern struct rtx_def *sh_builtin_saveregs ();
/*#define HAVE_POST_DECREMENT 1*/
#define HAVE_PRE_DECREMENT 1
+#define USE_LOAD_POST_INCREMENT(mode) ((mode == SImode || mode == DImode) \
+ ? 0 : 1)
+#define USE_LOAD_PRE_DECREMENT(mode) 0
+#define USE_STORE_POST_INCREMENT(mode) 0
+#define USE_STORE_PRE_DECREMENT(mode) ((mode == SImode || mode == DImode) \
+ ? 0 : 1)
+
+#define MOVE_BY_PIECES_P(SIZE, ALIGN) (move_by_pieces_ninsns (SIZE, ALIGN) \
+ < (TARGET_SMALLCODE ? 2 : \
+ ((ALIGN >= 4) ? 16 : 2)))
+
/* Macros to check register numbers against specific register classes. */
/* These assume that REGNO is a hard or pseudo reg number.
@@ -1088,7 +1265,10 @@ extern struct rtx_def *sh_builtin_saveregs ();
#define MODE_DISP_OK_4(X,MODE) \
(GET_MODE_SIZE (MODE) == 4 && (unsigned) INTVAL (X) < 64 \
&& ! (INTVAL (X) & 3) && ! (TARGET_SH3E && (MODE) == SFmode))
-#define MODE_DISP_OK_8(X,MODE) ((GET_MODE_SIZE(MODE)==8) && ((unsigned)INTVAL(X)<60) && (!(INTVAL(X) &3)))
+
+#define MODE_DISP_OK_8(X,MODE) \
+((GET_MODE_SIZE(MODE)==8) && ((unsigned)INTVAL(X)<60) \
+ && ! (INTVAL(X) & 3) && ! (TARGET_SH4 && (MODE) == DFmode))
#define BASE_REGISTER_RTX_P(X) \
((GET_CODE (X) == REG && REG_OK_FOR_BASE_P (X)) \
@@ -1143,13 +1323,15 @@ extern struct rtx_def *sh_builtin_saveregs ();
else if ((GET_CODE (X) == POST_INC || GET_CODE (X) == PRE_DEC) \
&& BASE_REGISTER_RTX_P (XEXP ((X), 0))) \
goto LABEL; \
- else if (GET_CODE (X) == PLUS && MODE != PSImode) \
+ else if (GET_CODE (X) == PLUS \
+ && ((MODE) != PSImode || reload_completed)) \
{ \
rtx xop0 = XEXP ((X), 0); \
rtx xop1 = XEXP ((X), 1); \
if (GET_MODE_SIZE (MODE) <= 8 && BASE_REGISTER_RTX_P (xop0)) \
GO_IF_LEGITIMATE_INDEX ((MODE), xop1, LABEL); \
- if (GET_MODE_SIZE (MODE) <= 4) \
+ if (GET_MODE_SIZE (MODE) <= 4 \
+ || TARGET_SH4 && TARGET_FMOVD && MODE == DFmode) \
{ \
if (BASE_REGISTER_RTX_P (xop1) && INDEX_REGISTER_RTX_P (xop0))\
goto LABEL; \
@@ -1183,6 +1365,7 @@ extern struct rtx_def *sh_builtin_saveregs ();
|| GET_MODE_SIZE (MODE) == 8) \
&& GET_CODE (XEXP ((X), 1)) == CONST_INT \
&& BASE_REGISTER_RTX_P (XEXP ((X), 0)) \
+ && ! (TARGET_SH4 && (MODE) == DFmode) \
&& ! (TARGET_SH3E && (MODE) == SFmode)) \
{ \
rtx index_rtx = XEXP ((X), 1); \
@@ -1230,12 +1413,21 @@ extern struct rtx_def *sh_builtin_saveregs ();
&& (GET_MODE_SIZE (MODE) == 4 || GET_MODE_SIZE (MODE) == 8) \
&& GET_CODE (XEXP (X, 1)) == CONST_INT \
&& BASE_REGISTER_RTX_P (XEXP (X, 0)) \
- && ! (TARGET_SH3E && MODE == SFmode)) \
+ && ! (TARGET_SH4 && (MODE) == DFmode) \
+ && ! ((MODE) == PSImode && (TYPE) == RELOAD_FOR_INPUT_ADDRESS)) \
{ \
rtx index_rtx = XEXP (X, 1); \
HOST_WIDE_INT offset = INTVAL (index_rtx), offset_base; \
rtx sum; \
\
+ if (TARGET_SH3E && MODE == SFmode) \
+ { \
+ X = copy_rtx (X); \
+ push_reload (index_rtx, NULL_RTX, &XEXP (X, 1), NULL_PTR, \
+ INDEX_REG_CLASS, Pmode, VOIDmode, 0, 0, (OPNUM), \
+ (TYPE)); \
+ goto WIN; \
+ } \
/* Instead of offset_base 128..131 use 124..127, so that \
simple add suffices. */ \
if (offset > 127) \
@@ -1317,7 +1509,7 @@ extern struct rtx_def *sh_builtin_saveregs ();
/* Since the SH3e has only `float' support, it is desirable to make all
floating point types equivalent to `float'. */
-#define DOUBLE_TYPE_SIZE (TARGET_SH3E ? 32 : 64)
+#define DOUBLE_TYPE_SIZE ((TARGET_SH3E && ! TARGET_SH4) ? 32 : 64)
/* 'char' is signed by default. */
#define DEFAULT_SIGNED_CHAR 1
@@ -1335,6 +1527,10 @@ extern struct rtx_def *sh_builtin_saveregs ();
in one reasonably fast instruction. */
#define MOVE_MAX 4
+/* Max number of bytes we want move_by_pieces to be able to copy
+ efficiently. */
+#define MOVE_MAX_PIECES (TARGET_SH4 ? 8 : 4)
+
/* Define if operations between registers always perform the operation
on the full register even if a narrower mode is specified. */
#define WORD_REGISTER_OPERATIONS
@@ -1352,8 +1548,13 @@ extern struct rtx_def *sh_builtin_saveregs ();
On the SH, it's only one instruction. */
/* #define SLOW_ZERO_EXTEND */
-/* Nonzero if access to memory by bytes is slow and undesirable. */
-#define SLOW_BYTE_ACCESS 0
+/* Nonzero if access to memory by bytes is no faster than for words. */
+#define SLOW_BYTE_ACCESS 1
+
+/* Force sizeof(bool) == 1 to maintain binary compatibility; otherwise, the
+ change in SLOW_BYTE_ACCESS would have changed it to 4. */
+
+#define BOOL_TYPE_SIZE (flag_new_abi ? INT_TYPE_SIZE : CHAR_TYPE_SIZE)
/* We assume that the store-condition-codes instructions store 0 for false
and some other value for true. This is the value stored for true. */
@@ -1409,6 +1610,11 @@ extern struct rtx_def *sh_builtin_saveregs ();
return 10;
#define RTX_COSTS(X, CODE, OUTER_CODE) \
+ case PLUS: \
+ return (COSTS_N_INSNS (1) \
+ + rtx_cost (XEXP ((X), 0), PLUS) \
+ + (rtx_equal_p (XEXP ((X), 0), XEXP ((X), 1))\
+ ? 0 : rtx_cost (XEXP ((X), 1), PLUS)));\
case AND: \
return COSTS_N_INSNS (andcosts (X)); \
case MULT: \
@@ -1416,7 +1622,13 @@ extern struct rtx_def *sh_builtin_saveregs ();
case ASHIFT: \
case ASHIFTRT: \
case LSHIFTRT: \
- return COSTS_N_INSNS (shiftcosts (X)) ; \
+ /* Add one extra unit for the matching constraint. \
+ Otherwise loop strength reduction would think that\
+ a shift with different sourc and destination is \
+ as cheap as adding a constant to a register. */ \
+ return (COSTS_N_INSNS (shiftcosts (X)) \
+ + rtx_cost (XEXP ((X), 0), (CODE)) \
+ + 1); \
case DIV: \
case UDIV: \
case MOD: \
@@ -1436,7 +1648,7 @@ extern struct rtx_def *sh_builtin_saveregs ();
which set the argument registers into the delay slot of the millicode
call -- thus they act more like traditional CALL_INSNs.
- get_attr_type will try to recognize the given insn, so make sure to
+ get_attr_is_sfunc will try to recognize the given insn, so make sure to
filter out things it will not accept -- SEQUENCE, USE and CLOBBER insns
in particular. */
@@ -1445,14 +1657,14 @@ extern struct rtx_def *sh_builtin_saveregs ();
&& GET_CODE (PATTERN (X)) != SEQUENCE \
&& GET_CODE (PATTERN (X)) != USE \
&& GET_CODE (PATTERN (X)) != CLOBBER \
- && get_attr_type (X) == TYPE_SFUNC))
+ && get_attr_is_sfunc (X)))
#define INSN_REFERENCES_ARE_DELAYED(X) \
((GET_CODE (X) == INSN \
&& GET_CODE (PATTERN (X)) != SEQUENCE \
&& GET_CODE (PATTERN (X)) != USE \
&& GET_CODE (PATTERN (X)) != CLOBBER \
- && get_attr_type (X) == TYPE_SFUNC))
+ && get_attr_is_sfunc (X)))
/* Compute the cost of an address. For the SH, all valid addresses are
the same cost. */
@@ -1464,11 +1676,29 @@ extern struct rtx_def *sh_builtin_saveregs ();
/* Compute extra cost of moving data between one register class
and another. */
+/* Regclass always uses 2 for moves in the same register class;
+ If SECONDARY*_RELOAD_CLASS says something about the src/dst pair,
+ it uses this information. Hence, the general register <-> floating point
+ register information here is not used for SFmode. */
#define REGISTER_MOVE_COST(SRCCLASS, DSTCLASS) \
- ((DSTCLASS) == PR_REG ? 10 \
- : (((DSTCLASS) == FP_REGS && (SRCCLASS) == GENERAL_REGS) \
- || ((DSTCLASS) == GENERAL_REGS && (SRCCLASS) == FP_REGS)) ? 4 \
- : 1)
+ ((((DSTCLASS) == T_REGS) || ((DSTCLASS) == PR_REG)) ? 10 \
+ : ((((DSTCLASS) == FP0_REGS || (DSTCLASS) == FP_REGS || (DSTCLASS) == DF_REGS) \
+ && ((SRCCLASS) == GENERAL_REGS || (SRCCLASS) == R0_REGS)) \
+ || (((DSTCLASS) == GENERAL_REGS || (DSTCLASS) == R0_REGS) \
+ && ((SRCCLASS) == FP0_REGS || (SRCCLASS) == FP_REGS \
+ || (SRCCLASS) == DF_REGS))) \
+ ? TARGET_FMOVD ? 8 : 12 \
+ : (((DSTCLASS) == FPUL_REGS \
+ && ((SRCCLASS) == GENERAL_REGS || (SRCCLASS) == R0_REGS)) \
+ || (SRCCLASS == FPUL_REGS \
+ && ((DSTCLASS) == GENERAL_REGS || (DSTCLASS) == R0_REGS))) \
+ ? 5 \
+ : (((DSTCLASS) == FPUL_REGS \
+ && ((SRCCLASS) == PR_REGS || (SRCCLASS) == MAC_REGS)) \
+ || ((SRCCLASS) == FPUL_REGS \
+ && ((DSTCLASS) == PR_REGS || (DSTCLASS) == MAC_REGS))) \
+ ? 7 \
+ : 2)
/* ??? Perhaps make MEMORY_MOVE_COST depend on compiler option? This
would be so that people would slow memory systems could generate
@@ -1575,13 +1805,32 @@ dtors_section() \
the Real framepointer; it can also be used as a normal general register.
Note that the name `fp' is horribly misleading since `fp' is in fact only
the argument-and-return-context pointer. */
+
+extern char fp_reg_names[][5];
+
#define REGISTER_NAMES \
{ \
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", \
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", \
+ "ap", "pr", "t", "gbr", "mach","macl", fp_reg_names[16], "rap", \
+ fp_reg_names[0], fp_reg_names[1] , fp_reg_names[2], fp_reg_names[3], \
+ fp_reg_names[4], fp_reg_names[5], fp_reg_names[6], fp_reg_names[7], \
+ fp_reg_names[8], fp_reg_names[9], fp_reg_names[10], fp_reg_names[11], \
+ fp_reg_names[12], fp_reg_names[13], fp_reg_names[14], fp_reg_names[15], \
+ fp_reg_names[17], fp_reg_names[18], fp_reg_names[19], fp_reg_names[20], \
+ fp_reg_names[21], fp_reg_names[22], fp_reg_names[23], fp_reg_names[24], \
+ "fpscr", \
+}
+
+#define DEBUG_REGISTER_NAMES \
+{ \
+ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", \
+ "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", \
"ap", "pr", "t", "gbr", "mach","macl", "fpul","rap", \
"fr0","fr1","fr2", "fr3", "fr4", "fr5", "fr6", "fr7", \
"fr8","fr9","fr10","fr11","fr12","fr13","fr14","fr15",\
+ "xd0","xd2","xd4", "xd6", "xd8", "xd10","xd12","xd14", \
+ "fpscr", \
}
/* DBX register number for a given compiler register number. */
@@ -1775,7 +2024,8 @@ enum processor_type {
PROCESSOR_SH1,
PROCESSOR_SH2,
PROCESSOR_SH3,
- PROCESSOR_SH3E
+ PROCESSOR_SH3E,
+ PROCESSOR_SH4
};
#define sh_cpu_attr ((enum attr_cpu)sh_cpu)
@@ -1839,8 +2089,15 @@ extern int sh_valid_machine_decl_attribute ();
#define VALID_MACHINE_DECL_ATTRIBUTE(DECL, ATTRIBUTES, IDENTIFIER, ARGS) \
sh_valid_machine_decl_attribute (DECL, ATTRIBUTES, IDENTIFIER, ARGS)
+extern void sh_pragma_insert_attributes ();
+#define PRAGMA_INSERT_ATTRIBUTES(node, pattr, prefix_attr) \
+ sh_pragma_insert_attributes (node, pattr, prefix_attr)
+
+extern int sh_flag_remove_dead_before_cse;
+extern int rtx_equal_function_value_matters;
+extern struct rtx_def *fpscr_rtx;
+extern struct rtx_def *get_fpscr_rtx ();
-#define MOVE_RATIO (TARGET_SMALLCODE ? 2 : 16)
/* Instructions with unfilled delay slots take up an extra two bytes for
the nop in the delay slot. */
@@ -1862,10 +2119,16 @@ sh_valid_machine_decl_attribute (DECL, ATTRIBUTES, IDENTIFIER, ARGS)
{"arith_operand", {SUBREG, REG, CONST_INT}}, \
{"arith_reg_operand", {SUBREG, REG}}, \
{"arith_reg_or_0_operand", {SUBREG, REG, CONST_INT}}, \
+ {"binary_float_operator", {PLUS, MULT}}, \
{"braf_label_ref_operand", {LABEL_REF}}, \
+ {"commutative_float_operator", {PLUS, MULT}}, \
+ {"fp_arith_reg_operand", {SUBREG, REG}}, \
+ {"fp_extended_operand", {SUBREG, REG, FLOAT_EXTEND}}, \
+ {"fpscr_operand", {REG}}, \
{"general_movsrc_operand", {SUBREG, REG, CONST_INT, MEM}}, \
{"general_movdst_operand", {SUBREG, REG, CONST_INT, MEM}}, \
{"logical_operand", {SUBREG, REG, CONST_INT}}, \
+ {"noncommutative_float_operator", {MINUS, DIV}}, \
{"register_operand", {SUBREG, REG}},
/* Define this macro if it is advisable to hold scalars in registers
@@ -1931,7 +2194,7 @@ do { \
using their arguments pretty quickly. \
Assume a four cycle delay before they are needed. */ \
if (! reg_set_p (reg, dep_insn)) \
- cost -= 4; \
+ cost -= TARGET_SUPERSCALAR ? 40 : 4; \
} \
/* Adjust load_si / pcload_si type insns latency. Use the known \
nominal latency and form of the insn to speed up the check. */ \
@@ -1941,9 +2204,14 @@ do { \
it's actually a move insn. */ \
&& general_movsrc_operand (SET_SRC (PATTERN (dep_insn)), SImode))\
cost = 2; \
+ else if (cost == 30 \
+ && GET_CODE (PATTERN (dep_insn)) == SET \
+ && GET_MODE (SET_SRC (PATTERN (dep_insn))) == SImode) \
+ cost = 20; \
} while (0) \
/* For the sake of libgcc2.c, indicate target supports atexit. */
#define HAVE_ATEXIT
-#define SH_DYNAMIC_SHIFT_COST (TARGET_SH3 ? (TARGET_SMALLCODE ? 1 : 2) : 20)
+#define SH_DYNAMIC_SHIFT_COST \
+ (TARGET_HARD_SH4 ? 1 : TARGET_SH3 ? (TARGET_SMALLCODE ? 1 : 2) : 20)
diff --git a/gcc/config/sh/sh.md b/gcc/config/sh/sh.md
index 3ca60b5d9ba..f572d6f343d 100644
--- a/gcc/config/sh/sh.md
+++ b/gcc/config/sh/sh.md
@@ -1,5 +1,5 @@
;;- Machine description for the Hitachi SH.
-;; Copyright (C) 1993, 1994, 1995, 1996, 1997 Free Software Foundation, Inc.
+;; Copyright (C) 1993 - 1999 Free Software Foundation, Inc.
;; Contributed by Steve Chamberlain (sac@cygnus.com).
;; Improved by Jim Wilson (wilson@cygnus.com).
@@ -70,13 +70,20 @@
;; Target CPU.
(define_attr "cpu"
- "sh1,sh2,sh3,sh3e"
+ "sh1,sh2,sh3,sh3e,sh4"
(const (symbol_ref "sh_cpu_attr")))
(define_attr "endian" "big,little"
(const (if_then_else (symbol_ref "TARGET_LITTLE_ENDIAN")
(const_string "little") (const_string "big"))))
+(define_attr "fmovd" "yes,no"
+ (const (if_then_else (symbol_ref "TARGET_FMOVD")
+ (const_string "yes") (const_string "no"))))
+;; issues/clock
+(define_attr "issues" "1,2"
+ (const (if_then_else (symbol_ref "TARGET_SUPERSCALAR") (const_string "2") (const_string "1"))))
+
;; cbranch conditional branch instructions
;; jump unconditional jumps
;; arith ordinary arithmetic
@@ -101,10 +108,12 @@
;; fp floating point
;; fdiv floating point divide (or square root)
;; gp_fpul move between general purpose register and fpul
+;; dfp_arith, dfp_cmp,dfp_conv
+;; dfdiv double precision floating point divide (or square root)
;; nil no-op move, will be deleted.
(define_attr "type"
- "cbranch,jump,jump_ind,arith,arith3,arith3b,dyn_shift,other,load,load_si,store,move,fmove,smpy,dmpy,return,pload,pstore,pcload,pcload_si,rte,sfunc,call,fp,fdiv,gp_fpul,nil"
+ "cbranch,jump,jump_ind,arith,arith3,arith3b,dyn_shift,other,load,load_si,store,move,fmove,smpy,dmpy,return,pload,pstore,pcload,pcload_si,rte,sfunc,call,fp,fdiv,dfp_arith,dfp_cmp,dfp_conv,dfdiv,gp_fpul,nil"
(const_string "other"))
; If a conditional branch destination is within -252..258 bytes away
@@ -252,34 +261,216 @@
;; We only do this for SImode loads of general registers, to make the work
;; for ADJUST_COST easier.
(define_function_unit "memory" 1 0
- (eq_attr "type" "load_si,pcload_si")
+ (and (eq_attr "issues" "1")
+ (eq_attr "type" "load_si,pcload_si"))
3 2)
(define_function_unit "memory" 1 0
- (eq_attr "type" "load,pcload,pload,store,pstore")
+ (and (eq_attr "issues" "1")
+ (eq_attr "type" "load,pcload,pload,store,pstore"))
2 2)
(define_function_unit "int" 1 0
- (eq_attr "type" "arith3,arith3b") 3 3)
+ (and (eq_attr "issues" "1") (eq_attr "type" "arith3,arith3b")) 3 3)
(define_function_unit "int" 1 0
- (eq_attr "type" "dyn_shift") 2 2)
+ (and (eq_attr "issues" "1") (eq_attr "type" "dyn_shift")) 2 2)
(define_function_unit "int" 1 0
- (eq_attr "type" "arith,arith3b,dyn_shift") 2 2)
+ (and (eq_attr "issues" "1") (eq_attr "type" "!arith3,arith3b,dyn_shift")) 1 1)
;; ??? These are approximations.
-(define_function_unit "mpy" 1 0 (eq_attr "type" "smpy") 2 2)
-(define_function_unit "mpy" 1 0 (eq_attr "type" "dmpy") 3 3)
+(define_function_unit "mpy" 1 0
+ (and (eq_attr "issues" "1") (eq_attr "type" "smpy")) 2 2)
+(define_function_unit "mpy" 1 0
+ (and (eq_attr "issues" "1") (eq_attr "type" "dmpy")) 3 3)
+
+(define_function_unit "fp" 1 0
+ (and (eq_attr "issues" "1") (eq_attr "type" "fp,fmove")) 2 1)
+(define_function_unit "fp" 1 0
+ (and (eq_attr "issues" "1") (eq_attr "type" "fdiv")) 13 12)
+
+
+;; SH4 scheduling
+;; The SH4 is a dual-issue implementation, thus we have to multiply all
+;; costs by at least two.
+;; There will be single increments of the modeled that don't correspond
+;; to the actual target ;; whenever two insns to be issued depend one a
+;; single resource, and the scheduler picks to be the first one.
+;; If we multiplied the costs just by two, just two of these single
+;; increments would amount to an actual cycle. By picking a larger
+;; factor, we can ameliorate the effect; However, we then have to make sure
+;; that only two insns are modeled as issued per actual cycle.
+;; Moreover, we need a way to specify the latency of insns that don't
+;; use an actual function unit.
+;; We use an 'issue' function unit to do that, and a cost factor of 10.
+
+(define_function_unit "issue" 2 0
+ (and (eq_attr "issues" "2") (eq_attr "type" "!nil,arith3"))
+ 10 10)
+
+(define_function_unit "issue" 2 0
+ (and (eq_attr "issues" "2") (eq_attr "type" "arith3"))
+ 30 30)
+
+;; There is no point in providing exact scheduling information about branches,
+;; because they are at the starts / ends of basic blocks anyways.
+
+;; Some insns cannot be issued before/after another insn in the same cycle,
+;; irrespective of the type of the other insn.
+
+;; default is dual-issue, but can't be paired with an insn that
+;; uses multiple function units.
+(define_function_unit "single_issue" 1 0
+ (and (eq_attr "issues" "2")
+ (eq_attr "type" "!smpy,dmpy,pload,pstore,dfp_cmp,gp_fpul,call,sfunc,arith3,arith3b"))
+ 1 10
+ [(eq_attr "type" "smpy,dmpy,pload,pstore,dfp_cmp,gp_fpul")])
+
+(define_function_unit "single_issue" 1 0
+ (and (eq_attr "issues" "2")
+ (eq_attr "type" "smpy,dmpy,pload,pstore,dfp_cmp,gp_fpul"))
+ 10 10
+ [(const_int 1)])
+
+;; arith3 insns are always pairable at the start, but not inecessarily at
+;; the end; however, there doesn;t seem to be a way to express that.
+(define_function_unit "single_issue" 1 0
+ (and (eq_attr "issues" "2")
+ (eq_attr "type" "arith3"))
+ 30 20
+ [(const_int 1)])
+
+;; arith3b insn are pairable at the end and have latency that prevents pairing
+;; with the following branch, but we don't want this latency be respected;
+;; When the following branch is immediately adjacent, we can redirect the
+;; internal branch, which is likly to be a larger win.
+(define_function_unit "single_issue" 1 0
+ (and (eq_attr "issues" "2")
+ (eq_attr "type" "arith3b"))
+ 20 20
+ [(const_int 1)])
+
+;; calls introduce a longisch delay that is likely to flush the pipelines.
+(define_function_unit "single_issue" 1 0
+ (and (eq_attr "issues" "2")
+ (eq_attr "type" "call,sfunc"))
+ 160 160
+ [(eq_attr "type" "!call") (eq_attr "type" "call")])
+
+;; Load and store instructions have no alignment peculiarities for the SH4,
+;; but they use the load-store unit, which they share with the fmove type
+;; insns (fldi[01]; fmov frn,frm; flds; fsts; fabs; fneg) .
+;; Loads have a latency of two.
+;; However, call insns can only paired with a preceding insn, and have
+;; a delay slot, so that we want two more insns to be scheduled between the
+;; load of the function address and the call. This is equivalent to a
+;; latency of three.
+;; We cannot use a conflict list for this, because we need to distinguish
+;; between the actual call address and the function arguments.
+;; ADJUST_COST can only properly handle reductions of the cost, so we
+;; use a latency of three here, which gets multiplied by 10 to yield 30.
+;; We only do this for SImode loads of general registers, to make the work
+;; for ADJUST_COST easier.
-(define_function_unit "fp" 1 0 (eq_attr "type" "fp,fmove") 2 1)
-(define_function_unit "fp" 1 0 (eq_attr "type" "fdiv") 13 12)
+;; When specifying different latencies for different insns using the
+;; the same function unit, genattrtab.c assumes a 'FIFO constraint'
+;; so that the blockage is at least READY-COST (E) + 1 - READY-COST (C)
+;; for an executing insn E and a candidate insn C.
+;; Therefore, we define three different function units for load_store:
+;; load_store, load and load_si.
+
+(define_function_unit "load_si" 1 0
+ (and (eq_attr "issues" "2")
+ (eq_attr "type" "load_si,pcload_si")) 30 10)
+(define_function_unit "load" 1 0
+ (and (eq_attr "issues" "2")
+ (eq_attr "type" "load,pcload,pload")) 20 10)
+(define_function_unit "load_store" 1 0
+ (and (eq_attr "issues" "2")
+ (eq_attr "type" "load_si,pcload_si,load,pcload,pload,store,pstore,fmove"))
+ 10 10)
+(define_function_unit "int" 1 0
+ (and (eq_attr "issues" "2") (eq_attr "type" "arith,dyn_shift")) 10 10)
+
+;; Again, we have to pretend a lower latency for the "int" unit to avoid a
+;; spurious FIFO constraint; the multiply instructions use the "int"
+;; unit actually only for two cycles.
+(define_function_unit "int" 1 0
+ (and (eq_attr "issues" "2") (eq_attr "type" "smpy,dmpy")) 20 20)
+
+;; We use a fictous "mpy" unit to express the actual latency.
+(define_function_unit "mpy" 1 0
+ (and (eq_attr "issues" "2") (eq_attr "type" "smpy,dmpy")) 40 20)
+
+;; Again, we have to pretend a lower latency for the "int" unit to avoid a
+;; spurious FIFO constraint.
+(define_function_unit "int" 1 0
+ (and (eq_attr "issues" "2") (eq_attr "type" "gp_fpul")) 10 10)
+
+;; We use a fictous "gp_fpul" unit to express the actual latency.
+(define_function_unit "gp_fpul" 1 0
+ (and (eq_attr "issues" "2") (eq_attr "type" "gp_fpul")) 20 10)
+
+;; ??? multiply uses the floating point unit, but with a two cycle delay.
+;; Thus, a simple single-precision fp operation could finish if issued in
+;; the very next cycle, but stalls when issued two or three cycles later.
+;; Similarily, a divide / sqrt can work without stalls if issued in
+;; the very next cycle, while it would have to block if issued two or
+;; three cycles later.
+;; There is no way to model this with gcc's function units. This problem is
+;; actually mentioned in md.texi. Tackling this problem requires first that
+;; it is possible to speak about the target in an open discussion.
+;;
+;; However, simple double-precision operations always conflict.
+
+(define_function_unit "fp" 1 0
+ (and (eq_attr "issues" "2") (eq_attr "type" "smpy,dmpy")) 40 40
+ [(eq_attr "type" "dfp_cmp,dfp_conv,dfp_arith")])
+
+;; The "fp" unit is for pipeline stages F1 and F2.
+
+(define_function_unit "fp" 1 0
+ (and (eq_attr "issues" "2") (eq_attr "type" "fp")) 30 10)
+
+;; Again, we have to pretend a lower latency for the "fp" unit to avoid a
+;; spurious FIFO constraint; the bulk of the fdiv type insns executes in
+;; the F3 stage.
+(define_function_unit "fp" 1 0
+ (and (eq_attr "issues" "2") (eq_attr "type" "fdiv")) 30 10)
+
+;; The "fdiv" function unit models the aggregate effect of the F1, F2 and F3
+;; pipeline stages on the pipelining of fdiv/fsqrt insns.
+;; We also use it to give the actual latency here.
+;; fsqrt is actually one cycle faster than fdiv (and the value used here),
+;; but that will hardly matter in practice for scheduling.
+(define_function_unit "fdiv" 1 0
+ (and (eq_attr "issues" "2") (eq_attr "type" "fdiv")) 120 100)
+
+;; There is again a late use of the "fp" unit by [d]fdiv type insns
+;; that we can't express.
+
+(define_function_unit "fp" 1 0
+ (and (eq_attr "issues" "2") (eq_attr "type" "dfp_cmp,dfp_conv")) 40 20)
+
+(define_function_unit "fp" 1 0
+ (and (eq_attr "issues" "2") (eq_attr "type" "dfp_arith")) 80 60)
+
+(define_function_unit "fp" 1 0
+ (and (eq_attr "issues" "2") (eq_attr "type" "dfdiv")) 230 10)
+
+(define_function_unit "fdiv" 1 0
+ (and (eq_attr "issues" "2") (eq_attr "type" "dfdiv")) 230 210)
; Definitions for filling branch delay slots.
(define_attr "needs_delay_slot" "yes,no" (const_string "no"))
-(define_attr "hit_stack" "yes,no" (const_string "no"))
+;; ??? This should be (nil) instead of (const_int 0)
+(define_attr "hit_stack" "yes,no"
+ (cond [(eq (symbol_ref "find_regno_note (insn, REG_INC, 15)") (const_int 0))
+ (const_string "no")]
+ (const_string "yes")))
(define_attr "interrupt_function" "no,yes"
(const (symbol_ref "pragma_interrupt")))
@@ -291,6 +482,9 @@
(eq_attr "length" "2") (const_string "yes")
] (const_string "no")))
+(define_attr "is_sfunc" ""
+ (if_then_else (eq_attr "type" "sfunc") (const_int 1) (const_int 0)))
+
(define_delay
(eq_attr "needs_delay_slot" "yes")
[(eq_attr "in_delay_slot" "yes") (nil) (nil)])
@@ -668,7 +862,42 @@
(clobber (reg:SI 17))
(clobber (reg:SI 4))
(use (match_operand:SI 1 "arith_reg_operand" "r"))]
- ""
+ "! TARGET_SH4"
+ "jsr @%1%#"
+ [(set_attr "type" "sfunc")
+ (set_attr "needs_delay_slot" "yes")])
+
+(define_insn "udivsi3_i4"
+ [(set (match_operand:SI 0 "register_operand" "=y")
+ (udiv:SI (reg:SI 4) (reg:SI 5)))
+ (clobber (reg:SI 17))
+ (clobber (reg:DF 24))
+ (clobber (reg:DF 26))
+ (clobber (reg:DF 28))
+ (clobber (reg:SI 0))
+ (clobber (reg:SI 1))
+ (clobber (reg:SI 4))
+ (clobber (reg:SI 5))
+ (use (reg:PSI 48))
+ (use (match_operand:SI 1 "arith_reg_operand" "r"))]
+ "TARGET_SH4 && ! TARGET_FPU_SINGLE"
+ "jsr @%1%#"
+ [(set_attr "type" "sfunc")
+ (set_attr "needs_delay_slot" "yes")])
+
+(define_insn "udivsi3_i4_single"
+ [(set (match_operand:SI 0 "register_operand" "=y")
+ (udiv:SI (reg:SI 4) (reg:SI 5)))
+ (clobber (reg:SI 17))
+ (clobber (reg:DF 24))
+ (clobber (reg:DF 26))
+ (clobber (reg:DF 28))
+ (clobber (reg:SI 0))
+ (clobber (reg:SI 1))
+ (clobber (reg:SI 4))
+ (clobber (reg:SI 5))
+ (use (match_operand:SI 1 "arith_reg_operand" "r"))]
+ "TARGET_HARD_SH4 && TARGET_FPU_SINGLE"
"jsr @%1%#"
[(set_attr "type" "sfunc")
(set_attr "needs_delay_slot" "yes")])
@@ -685,7 +914,22 @@
(clobber (reg:SI 4))
(use (match_dup 3))])]
""
- "operands[3] = gen_reg_rtx(SImode);")
+ "
+{
+ operands[3] = gen_reg_rtx(SImode);
+ if (TARGET_HARD_SH4)
+ {
+ emit_move_insn (gen_rtx (REG, SImode, 4), operands[1]);
+ emit_move_insn (gen_rtx (REG, SImode, 5), operands[2]);
+ emit_move_insn (operands[3],
+ gen_rtx_SYMBOL_REF (SImode, \"__udivsi3_i4\"));
+ if (TARGET_FPU_SINGLE)
+ emit_insn (gen_udivsi3_i4_single (operands[0], operands[3]));
+ else
+ emit_insn (gen_udivsi3_i4 (operands[0], operands[3]));
+ DONE;
+ }
+}")
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=z")
@@ -696,7 +940,33 @@
(clobber (reg:SI 2))
(clobber (reg:SI 3))
(use (match_operand:SI 1 "arith_reg_operand" "r"))]
- ""
+ "! TARGET_SH4"
+ "jsr @%1%#"
+ [(set_attr "type" "sfunc")
+ (set_attr "needs_delay_slot" "yes")])
+
+(define_insn "divsi3_i4"
+ [(set (match_operand:SI 0 "register_operand" "=y")
+ (div:SI (reg:SI 4) (reg:SI 5)))
+ (clobber (reg:SI 17))
+ (clobber (reg:DF 24))
+ (clobber (reg:DF 26))
+ (use (reg:PSI 48))
+ (use (match_operand:SI 1 "arith_reg_operand" "r"))]
+ "TARGET_SH4 && ! TARGET_FPU_SINGLE"
+ "jsr @%1%#"
+ [(set_attr "type" "sfunc")
+ (set_attr "needs_delay_slot" "yes")])
+
+(define_insn "divsi3_i4_single"
+ [(set (match_operand:SI 0 "register_operand" "=y")
+ (div:SI (reg:SI 4) (reg:SI 5)))
+ (clobber (reg:SI 17))
+ (clobber (reg:DF 24))
+ (clobber (reg:DF 26))
+ (clobber (reg:SI 2))
+ (use (match_operand:SI 1 "arith_reg_operand" "r"))]
+ "TARGET_HARD_SH4 && TARGET_FPU_SINGLE"
"jsr @%1%#"
[(set_attr "type" "sfunc")
(set_attr "needs_delay_slot" "yes")])
@@ -715,7 +985,22 @@
(clobber (reg:SI 3))
(use (match_dup 3))])]
""
- "operands[3] = gen_reg_rtx(SImode);")
+ "
+{
+ operands[3] = gen_reg_rtx(SImode);
+ if (TARGET_HARD_SH4)
+ {
+ emit_move_insn (gen_rtx (REG, SImode, 4), operands[1]);
+ emit_move_insn (gen_rtx (REG, SImode, 5), operands[2]);
+ emit_move_insn (operands[3],
+ gen_rtx_SYMBOL_REF (SImode, \"__sdivsi3_i4\"));
+ if (TARGET_FPU_SINGLE)
+ emit_insn (gen_divsi3_i4_single (operands[0], operands[3]));
+ else
+ emit_insn (gen_divsi3_i4 (operands[0], operands[3]));
+ DONE;
+ }
+}")
;; -------------------------------------------------------------------------
;; Multiplication instructions
@@ -782,7 +1067,6 @@
(define_expand "mulsi3_call"
[(set (reg:SI 4) (match_operand:SI 1 "general_operand" ""))
(set (reg:SI 5) (match_operand:SI 2 "general_operand" ""))
- (set (match_dup 3) (symbol_ref:SI "__mulsi3"))
(parallel[(set (match_operand:SI 0 "register_operand" "")
(mult:SI (reg:SI 4)
(reg:SI 5)))
@@ -792,9 +1076,9 @@
(clobber (reg:SI 3))
(clobber (reg:SI 2))
(clobber (reg:SI 1))
- (use (match_dup 3))])]
+ (use (match_operand:SI 3 "register_operand" ""))])]
""
- "operands[3] = gen_reg_rtx(SImode);")
+ "")
(define_insn "mul_l"
[(set (reg:SI 21)
@@ -813,13 +1097,32 @@
""
"
{
+ rtx first, last;
+
if (!TARGET_SH2)
{
- FAIL;
- /* ??? Does this give worse or better code? */
- emit_insn (gen_mulsi3_call (operands[0], operands[1], operands[2]));
- DONE;
+ /* The address must be set outside the libcall,
+ since it goes into a pseudo. */
+ rtx addr = force_reg (SImode, gen_rtx_SYMBOL_REF (SImode, \"__mulsi3\"));
+ rtx insns = gen_mulsi3_call (operands[0], operands[1], operands[2], addr);
+ first = XVECEXP (insns, 0, 0);
+ last = XVECEXP (insns, 0, XVECLEN (insns, 0) - 1);
+ emit_insn (insns);
+ }
+ else
+ {
+ rtx macl = gen_rtx_REG (SImode, MACL_REG);
+ first = emit_insn (gen_mul_l (operands[1], operands[2]));
+ emit_insn (gen_movsi_i ((operands[0]), macl));
+ /* The sequence must end in a no-op move, lest cse puts macl in its
+ tables and does invalid substitutions. */
+ last = emit_insn (gen_movsi_i ((operands[0]), operands[0]));
}
+ /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
+ invariant code motion can move it. */
+ REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
+ REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
+ DONE;
}")
(define_insn "mulsidi3_i"
@@ -1767,50 +2070,65 @@
;; define push and pop so it is easy for sh.c
-(define_insn "push"
+(define_expand "push"
[(set (mem:SI (pre_dec:SI (reg:SI 15)))
(match_operand:SI 0 "register_operand" "r,l,x"))]
""
- "@
- mov.l %0,@-r15
- sts.l %0,@-r15
- sts.l %0,@-r15"
- [(set_attr "type" "store,pstore,store")
- (set_attr "hit_stack" "yes")])
+ "")
-(define_insn "pop"
+(define_expand "pop"
[(set (match_operand:SI 0 "register_operand" "=r,l,x")
(mem:SI (post_inc:SI (reg:SI 15))))]
""
- "@
- mov.l @r15+,%0
- lds.l @r15+,%0
- lds.l @r15+,%0"
- [(set_attr "type" "load,pload,load")
- (set_attr "hit_stack" "yes")])
+ "")
+
+(define_expand "push_e"
+ [(parallel [(set (mem:SF (pre_dec:SI (reg:SI 15)))
+ (match_operand:SF 0 "" ""))
+ (use (reg:PSI 48))
+ (clobber (scratch:SI))])]
+ ""
+ "")
-(define_insn "push_e"
- [(set (mem:SF (pre_dec:SI (reg:SI 15)))
- (match_operand:SF 0 "register_operand" "r,f,y"))]
+(define_insn "push_fpul"
+ [(set (mem:SF (pre_dec:SI (reg:SI 15))) (reg:SF 22))]
"TARGET_SH3E"
- "@
- mov.l %0,@-r15
- fmov.s %0,@-r15
- sts.l %0,@-r15"
+ "sts.l fpul,@-r15"
[(set_attr "type" "store")
(set_attr "hit_stack" "yes")])
-(define_insn "pop_e"
- [(set (match_operand:SF 0 "register_operand" "=r,f,y")
- (mem:SF (post_inc:SI (reg:SI 15))))]
+;; DFmode pushes for sh4 require a lot of what is defined for movdf_i4,
+;; so use that.
+(define_expand "push_4"
+ [(parallel [(set (mem:DF (pre_dec:SI (reg:SI 15))) (match_operand:DF 0 "" ""))
+ (use (reg:PSI 48))
+ (clobber (scratch:SI))])]
+ ""
+ "")
+
+(define_expand "pop_e"
+ [(parallel [(set (match_operand:SF 0 "" "")
+ (mem:SF (post_inc:SI (reg:SI 15))))
+ (use (reg:PSI 48))
+ (clobber (scratch:SI))])]
+ ""
+ "")
+
+(define_insn "pop_fpul"
+ [(set (reg:SF 22) (mem:SF (post_inc:SI (reg:SI 15))))]
"TARGET_SH3E"
- "@
- mov.l @r15+,%0
- fmov.s @r15+,%0
- lds.l @r15+,%0"
+ "lds.l @r15+,fpul"
[(set_attr "type" "load")
(set_attr "hit_stack" "yes")])
+(define_expand "pop_4"
+ [(parallel [(set (match_operand:DF 0 "" "")
+ (mem:DF (post_inc:SI (reg:SI 15))))
+ (use (reg:PSI 48))
+ (clobber (scratch:SI))])]
+ ""
+ "")
+
;; These two patterns can happen as the result of optimization, when
;; comparisons get simplified to a move of zero or 1 into the T reg.
;; They don't disappear completely, because the T reg is a fixed hard reg.
@@ -1825,19 +2143,20 @@
""
"sett")
-;; t/r is first, so that it will be preferred over r/r when reloading a move
-;; of a pseudo-reg into the T reg
+;; t/r must come after r/r, lest reload will try to reload stuff like
+;; (set (subreg:SI (mem:QI (plus:SI (reg:SI 15 r15) (const_int 12)) 0) 0)
+;; (made from (set (subreg:SI (reg:QI 73) 0) ) into T.
(define_insn "movsi_i"
- [(set (match_operand:SI 0 "general_movdst_operand" "=t,r,r,r,r,r,m,<,<,xl,x,l,r")
- (match_operand:SI 1 "general_movsrc_operand" "r,Q,rI,m,xl,t,r,x,l,r,>,>,i"))]
+ [(set (match_operand:SI 0 "general_movdst_operand" "=r,r,t,r,r,r,m,<,<,xl,x,l,r")
+ (match_operand:SI 1 "general_movsrc_operand" "Q,rI,r,mr,xl,t,r,x,l,r,>,>,i"))]
"
! TARGET_SH3E
&& (register_operand (operands[0], SImode)
|| register_operand (operands[1], SImode))"
"@
- cmp/pl %1
mov.l %1,%0
mov %1,%0
+ cmp/pl %1
mov.l %1,%0
sts %1,%0
movt %0
@@ -1848,7 +2167,7 @@
lds.l %1,%0
lds.l %1,%0
fake %1,%0"
- [(set_attr "type" "*,pcload_si,move,load_si,move,move,store,store,pstore,move,load,pload,pcload_si")
+ [(set_attr "type" "pcload_si,move,*,load_si,move,move,store,store,pstore,move,load,pload,pcload_si")
(set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*")])
;; t/r must come after r/r, lest reload will try to reload stuff like
@@ -1856,8 +2175,8 @@
;; ??? This allows moves from macl to fpul to be recognized, but these moves
;; will require a reload.
(define_insn "movsi_ie"
- [(set (match_operand:SI 0 "general_movdst_operand" "=r,r,t,r,r,r,m,<,<,xl,x,l,r,y,r,y")
- (match_operand:SI 1 "general_movsrc_operand" "Q,rI,r,m,xl,t,r,x,l,r,>,>,i,r,y,y"))]
+ [(set (match_operand:SI 0 "general_movdst_operand" "=r,r,t,r,r,r,m,<,<,xl,x,l,y,r,y,r,y")
+ (match_operand:SI 1 "general_movsrc_operand" "Q,rI,r,mr,xl,t,r,x,l,r,>,>,>,i,r,y,y"))]
"TARGET_SH3E
&& (register_operand (operands[0], SImode)
|| register_operand (operands[1], SImode))"
@@ -1874,16 +2193,17 @@
lds %1,%0
lds.l %1,%0
lds.l %1,%0
+ lds.l %1,%0
fake %1,%0
lds %1,%0
sts %1,%0
! move optimized away"
- [(set_attr "type" "pcload_si,move,*,load_si,move,move,store,store,pstore,move,load,pload,pcload_si,gp_fpul,gp_fpul,nil")
- (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,0")])
+ [(set_attr "type" "pcload_si,move,*,load_si,move,move,store,store,pstore,move,load,pload,load,pcload_si,gp_fpul,gp_fpul,nil")
+ (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,0")])
(define_insn "movsi_i_lowpart"
[(set (strict_low_part (match_operand:SI 0 "general_movdst_operand" "=r,r,r,r,r,m,r"))
- (match_operand:SI 1 "general_movsrc_operand" "Q,rI,m,xl,t,r,i"))]
+ (match_operand:SI 1 "general_movsrc_operand" "Q,rI,mr,xl,t,r,i"))]
"register_operand (operands[0], SImode)
|| register_operand (operands[1], SImode)"
"@
@@ -1901,6 +2221,30 @@
""
"{ if (prepare_move_operands (operands, SImode)) DONE; }")
+(define_expand "ic_invalidate_line"
+ [(parallel [(unspec_volatile [(match_operand:SI 0 "register_operand" "+r")
+ (match_dup 1)] 12)
+ (clobber (scratch:SI))])]
+ "TARGET_HARD_SH4"
+ "
+{
+ operands[0] = force_reg (Pmode, operands[0]);
+ operands[1] = force_reg (Pmode, GEN_INT (0xf0000008));
+}")
+
+;; The address %0 is assumed to be 4-aligned at least. Thus, by ORing
+;; 0xf0000008, we get the low-oder bits *1*00 (binary), ;; which fits
+;; the requirement *0*00 for associative address writes. The alignment of
+;; %0 implies that its least significant bit is cleared,
+;; thus we clear the V bit of a matching entry if there is one.
+(define_insn "ic_invalidate_line_i"
+ [(unspec_volatile [(match_operand:SI 0 "register_operand" "r,r")
+ (match_operand:SI 1 "register_operand" "r,r")] 12)
+ (clobber (match_scratch:SI 2 "=&r,1"))]
+ "TARGET_HARD_SH4"
+ "ocbwb\\t@%0\;extu.w\\t%0,%2\;or\\t%r1,%r2\;mov.l\\t%0,@%2"
+ [(set_attr "length" "8")])
+
(define_insn "movqi_i"
[(set (match_operand:QI 0 "general_movdst_operand" "=r,r,m,r,r,l")
(match_operand:QI 1 "general_movsrc_operand" "ri,m,r,t,l,r"))]
@@ -2014,12 +2358,330 @@
(define_insn "movdf_k"
[(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
(match_operand:DF 1 "general_movsrc_operand" "r,FQ,m,r"))]
- "arith_reg_operand (operands[0], DFmode)
- || arith_reg_operand (operands[1], DFmode)"
+ "(! TARGET_SH4 || reload_completed
+ /* ??? We provide some insn so that direct_{load,store}[DFmode] get set */
+ || GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3
+ || GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3)
+ && (arith_reg_operand (operands[0], DFmode)
+ || arith_reg_operand (operands[1], DFmode))"
"* return output_movedouble (insn, operands, DFmode);"
[(set_attr "length" "4")
(set_attr "type" "move,pcload,load,store")])
+;; All alternatives of movdf_i4 are split for ! TARGET_FMOVD.
+;; However, the d/F/c/z alternative cannot be split directly; it is converted
+;; with special code in machine_dependent_reorg into a load of the R0_REG and
+;; the d/m/c/X alternative, which is split later into single-precision
+;; instructions. And when not optimizing, no splits are done before fixing
+;; up pcloads, so we need usable length information for that.
+(define_insn "movdf_i4"
+ [(set (match_operand:DF 0 "general_movdst_operand" "=d,r,d,d,m,r,r,m,!??r,!???d")
+ (match_operand:DF 1 "general_movsrc_operand" "d,r,F,m,d,FQ,m,r,d,r"))
+ (use (match_operand:PSI 2 "fpscr_operand" "c,c,c,c,c,c,c,c,c,c"))
+ (clobber (match_scratch:SI 3 "=X,X,&z,X,X,X,X,X,X,X"))]
+ "TARGET_SH4
+ && (arith_reg_operand (operands[0], DFmode)
+ || arith_reg_operand (operands[1], DFmode))"
+ "@
+ fmov %1,%0
+ #
+ #
+ fmov.d %1,%0
+ fmov.d %1,%0
+ #
+ #
+ #
+ #
+ #"
+ [(set_attr_alternative "length"
+ [(if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 4))
+ (const_int 4)
+ (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
+ (if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 6))
+ (if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 6))
+ (const_int 4)
+ (const_int 8) (const_int 8) ;; these need only 8 bytes for @(r0,rn)
+ (const_int 8) (const_int 8)])
+ (set_attr "type" "fmove,move,pcload,load,store,pcload,load,store,load,load")])
+
+;; Moving DFmode between fp/general registers through memory
+;; (the top of the stack) is faster than moving through fpul even for
+;; little endian. Because the type of an instruction is important for its
+;; scheduling, it is beneficial to split these operations, rather than
+;; emitting them in one single chunk, even if this will expose a stack
+;; use that will prevent scheduling of other stack accesses beyond this
+;; instruction.
+(define_split
+ [(set (match_operand:DF 0 "register_operand" "")
+ (match_operand:DF 1 "register_operand" ""))
+ (use (match_operand:PSI 2 "fpscr_operand" "c"))
+ (clobber (match_scratch:SI 3 "=X"))]
+ "TARGET_SH4 && reload_completed
+ && (true_regnum (operands[0]) < 16) != (true_regnum (operands[1]) < 16)"
+ [(const_int 0)]
+ "
+{
+ rtx insn, tos;
+
+ tos = gen_rtx (MEM, DFmode, gen_rtx (PRE_DEC, Pmode, stack_pointer_rtx));
+ insn = emit_insn (gen_movdf_i4 (tos, operands[1], operands[2]));
+ REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, stack_pointer_rtx, NULL_RTX);
+ tos = gen_rtx (MEM, DFmode, gen_rtx (POST_INC, Pmode, stack_pointer_rtx));
+ insn = emit_insn (gen_movdf_i4 (operands[0], tos, operands[2]));
+ REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, stack_pointer_rtx, NULL_RTX);
+ DONE;
+}")
+
+;; local-alloc sometimes allocates scratch registers even when not required,
+;; so we must be prepared to handle these.
+
+;; Remove the use and clobber from a movdf_i4 so that we can use movdf_k.
+(define_split
+ [(set (match_operand:DF 0 "general_movdst_operand" "")
+ (match_operand:DF 1 "general_movsrc_operand" ""))
+ (use (match_operand:PSI 2 "fpscr_operand" "c"))
+ (clobber (match_scratch:SI 3 "X"))]
+ "TARGET_SH4
+ && reload_completed
+ && true_regnum (operands[0]) < 16
+ && true_regnum (operands[1]) < 16"
+ [(set (match_dup 0) (match_dup 1))]
+ "
+{
+ /* If this was a reg <-> mem operation with base + index reg addressing,
+ we have to handle this in a special way. */
+ rtx mem = operands[0];
+ int store_p = 1;
+ if (! memory_operand (mem, DFmode))
+ {
+ mem = operands[1];
+ store_p = 0;
+ }
+ if (GET_CODE (mem) == SUBREG && SUBREG_WORD (mem) == 0)
+ mem = SUBREG_REG (mem);
+ if (GET_CODE (mem) == MEM)
+ {
+ rtx addr = XEXP (mem, 0);
+ if (GET_CODE (addr) == PLUS
+ && GET_CODE (XEXP (addr, 0)) == REG
+ && GET_CODE (XEXP (addr, 1)) == REG)
+ {
+ int offset;
+ rtx reg0 = gen_rtx (REG, Pmode, 0);
+ rtx regop = operands[store_p], word0 ,word1;
+
+ if (GET_CODE (regop) == SUBREG)
+ regop = alter_subreg (regop);
+ if (REGNO (XEXP (addr, 0)) == REGNO (XEXP (addr, 1)))
+ offset = 2;
+ else
+ offset = 4;
+ mem = copy_rtx (mem);
+ PUT_MODE (mem, SImode);
+ word0 = gen_rtx(SUBREG, SImode, regop, 0);
+ emit_insn (store_p
+ ? gen_movsi_ie (mem, word0) : gen_movsi_ie (word0, mem));
+ emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
+ mem = copy_rtx (mem);
+ word1 = gen_rtx(SUBREG, SImode, regop, 1);
+ emit_insn (store_p
+ ? gen_movsi_ie (mem, word1) : gen_movsi_ie (word1, mem));
+ emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
+ DONE;
+ }
+ }
+}")
+
+;; Split away the clobber of r0 after machine_dependent_reorg has fixed pcloads.
+(define_split
+ [(set (match_operand:DF 0 "register_operand" "")
+ (match_operand:DF 1 "memory_operand" ""))
+ (use (match_operand:PSI 2 "fpscr_operand" "c"))
+ (clobber (reg:SI 0))]
+ "TARGET_SH4 && reload_completed"
+ [(parallel [(set (match_dup 0) (match_dup 1))
+ (use (match_dup 2))
+ (clobber (scratch:SI))])]
+ "")
+
+(define_expand "reload_indf"
+ [(parallel [(set (match_operand:DF 0 "register_operand" "=f")
+ (match_operand:DF 1 "immediate_operand" "FQ"))
+ (use (reg:PSI 48))
+ (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
+ ""
+ "")
+
+(define_expand "reload_outdf"
+ [(parallel [(set (match_operand:DF 0 "register_operand" "=r,f")
+ (match_operand:DF 1 "register_operand" "af,r"))
+ (clobber (match_operand:SI 2 "register_operand" "=&y,y"))])]
+ ""
+ "")
+
+;; Simplify no-op moves.
+(define_split
+ [(set (match_operand:SF 0 "register_operand" "")
+ (match_operand:SF 1 "register_operand" ""))
+ (use (match_operand:PSI 2 "fpscr_operand" ""))
+ (clobber (match_scratch:SI 3 "X"))]
+ "TARGET_SH3E && reload_completed
+ && true_regnum (operands[0]) == true_regnum (operands[1])"
+ [(set (match_dup 0) (match_dup 0))]
+ "")
+
+;; fmovd substitute post-reload splits
+(define_split
+ [(set (match_operand:DF 0 "register_operand" "")
+ (match_operand:DF 1 "register_operand" ""))
+ (use (match_operand:PSI 2 "fpscr_operand" "c"))
+ (clobber (match_scratch:SI 3 "X"))]
+ "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
+ && true_regnum (operands[0]) >= FIRST_FP_REG
+ && true_regnum (operands[1]) >= FIRST_FP_REG"
+ [(const_int 0)]
+ "
+{
+ int dst = true_regnum (operands[0]), src = true_regnum (operands[1]);
+ emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode, dst),
+ gen_rtx (REG, SFmode, src), operands[2]));
+ emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode, dst + 1),
+ gen_rtx (REG, SFmode, src + 1), operands[2]));
+ DONE;
+}")
+
+(define_split
+ [(set (match_operand:DF 0 "register_operand" "")
+ (mem:DF (match_operand:SI 1 "register_operand" "")))
+ (use (match_operand:PSI 2 "fpscr_operand" "c"))
+ (clobber (match_scratch:SI 3 "X"))]
+ "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
+ && true_regnum (operands[0]) >= FIRST_FP_REG
+ && find_regno_note (insn, REG_DEAD, true_regnum (operands[1]))"
+ [(const_int 0)]
+ "
+{
+ int regno = true_regnum (operands[0]);
+ rtx insn;
+ rtx mem2 = gen_rtx (MEM, SFmode, gen_rtx (POST_INC, Pmode, operands[1]));
+
+ insn = emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode,
+ regno + !! TARGET_LITTLE_ENDIAN),
+ mem2, operands[2]));
+ REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, operands[1], NULL_RTX);
+ insn = emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode,
+ regno + ! TARGET_LITTLE_ENDIAN),
+ gen_rtx (MEM, SFmode, operands[1]),
+ operands[2]));
+ DONE;
+}")
+
+(define_split
+ [(set (match_operand:DF 0 "register_operand" "")
+ (match_operand:DF 1 "memory_operand" ""))
+ (use (match_operand:PSI 2 "fpscr_operand" "c"))
+ (clobber (match_scratch:SI 3 "X"))]
+ "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
+ && true_regnum (operands[0]) >= FIRST_FP_REG"
+ [(const_int 0)]
+ "
+{
+ int regno = true_regnum (operands[0]);
+ rtx addr, insn, adjust = NULL_RTX;
+ rtx mem2 = copy_rtx (operands[1]);
+ rtx reg0 = gen_rtx_REG (SFmode, regno + !! TARGET_LITTLE_ENDIAN);
+ rtx reg1 = gen_rtx_REG (SFmode, regno + ! TARGET_LITTLE_ENDIAN);
+
+ PUT_MODE (mem2, SFmode);
+ operands[1] = copy_rtx (mem2);
+ addr = XEXP (mem2, 0);
+ if (GET_CODE (addr) != POST_INC)
+ {
+ /* If we have to modify the stack pointer, the value that we have
+ read with post-increment might be modified by an interrupt,
+ so write it back. */
+ if (REGNO (addr) == STACK_POINTER_REGNUM)
+ adjust = gen_push_e (reg0);
+ else
+ adjust = gen_addsi3 (addr, addr, GEN_INT (-4));
+ XEXP (mem2, 0) = addr = gen_rtx_POST_INC (SImode, addr);
+ }
+ addr = XEXP (addr, 0);
+ insn = emit_insn (gen_movsf_ie (reg0, mem2, operands[2]));
+ REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
+ insn = emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
+ if (adjust)
+ emit_insn (adjust);
+ else
+ REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
+ DONE;
+}")
+
+(define_split
+ [(set (match_operand:DF 0 "memory_operand" "")
+ (match_operand:DF 1 "register_operand" ""))
+ (use (match_operand:PSI 2 "fpscr_operand" "c"))
+ (clobber (match_scratch:SI 3 "X"))]
+ "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
+ && true_regnum (operands[1]) >= FIRST_FP_REG"
+ [(const_int 0)]
+ "
+{
+ int regno = true_regnum (operands[1]);
+ rtx insn, addr, adjust = NULL_RTX;
+
+ operands[0] = copy_rtx (operands[0]);
+ PUT_MODE (operands[0], SFmode);
+ insn = emit_insn (gen_movsf_ie (operands[0],
+ gen_rtx (REG, SFmode,
+ regno + ! TARGET_LITTLE_ENDIAN),
+ operands[2]));
+ operands[0] = copy_rtx (operands[0]);
+ addr = XEXP (operands[0], 0);
+ if (GET_CODE (addr) != PRE_DEC)
+ {
+ adjust = gen_addsi3 (addr, addr, GEN_INT (4));
+ emit_insn_before (adjust, insn);
+ XEXP (operands[0], 0) = addr = gen_rtx (PRE_DEC, SImode, addr);
+ }
+ addr = XEXP (addr, 0);
+ if (! adjust)
+ REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, addr, NULL_RTX);
+ insn = emit_insn (gen_movsf_ie (operands[0],
+ gen_rtx (REG, SFmode,
+ regno + !! TARGET_LITTLE_ENDIAN),
+ operands[2]));
+ REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, addr, NULL_RTX);
+ DONE;
+}")
+
+;; The '&' for operand 2 is not really true, but push_secondary_reload
+;; insists on it.
+;; Operand 1 must accept FPUL_REGS in case fpul is reloaded to memory,
+;; to avoid a bogus tertiary reload.
+;; We need a tertiary reload when a floating point register is reloaded
+;; to memory, so the predicate for operand 0 must accept this, while the
+;; constraint of operand 1 must reject the secondary reload register.
+;; Thus, the secondary reload register for this case has to be GENERAL_REGS,
+;; too.
+;; By having the predicate for operand 0 reject any register, we make
+;; sure that the ordinary moves that just need an intermediate register
+;; won't get a bogus tertiary reload.
+;; We use tertiary_reload_operand instead of memory_operand here because
+;; memory_operand rejects operands that are not directly addressible, e.g.:
+;; (mem:SF (plus:SI (reg:SI 14 r14)
+;; (const_int 132)))
+
+(define_expand "reload_outsf"
+ [(parallel [(set (match_operand:SF 2 "register_operand" "=&r")
+ (match_operand:SF 1 "register_operand" "y"))
+ (clobber (scratch:SI))])
+ (parallel [(set (match_operand:SF 0 "tertiary_reload_operand" "=m")
+ (match_dup 2))
+ (clobber (scratch:SI))])]
+ ""
+ "")
+
;; If the output is a register and the input is memory or a register, we have
;; to be careful and see which word needs to be loaded first.
@@ -2129,14 +2791,33 @@
"
{
if (prepare_move_operands (operands, DFmode)) DONE;
+ if (TARGET_SH4)
+ {
+ if (no_new_pseudos)
+ {
+ /* ??? FIXME: This is only a stopgap fix. There is no guarantee
+ that fpscr is in the right state. */
+ emit_insn (gen_movdf_i4 (operands[0], operands[1], get_fpscr_rtx ()));
+ DONE;
+ }
+ emit_df_insn (gen_movdf_i4 (operands[0], operands[1], get_fpscr_rtx ()));
+ /* We need something to tag possible REG_LIBCALL notes on to. */
+ if (TARGET_FPU_SINGLE && rtx_equal_function_value_matters
+ && GET_CODE (operands[0]) == REG)
+ emit_insn (gen_mov_nop (operands[0]));
+ DONE;
+ }
}")
(define_insn "movsf_i"
[(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,r,m,l,r")
- (match_operand:SF 1 "general_movsrc_operand" "r,I,FQ,m,r,r,l"))]
+ (match_operand:SF 1 "general_movsrc_operand" "r,I,FQ,mr,r,r,l"))]
"
- ! TARGET_SH3E
+ (! TARGET_SH3E
+ /* ??? We provide some insn so that direct_{load,store}[SFmode] get set */
+ || GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3
+ || GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3)
&& (arith_reg_operand (operands[0], SFmode)
|| arith_reg_operand (operands[1], SFmode))"
"@
@@ -2156,8 +2837,9 @@
[(set (match_operand:SF 0 "general_movdst_operand"
"=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,y")
(match_operand:SF 1 "general_movsrc_operand"
- "f,r,G,H,FQ,m,f,FQ,m,r,y,f,>,fr,y,r,y"))
- (clobber (match_scratch:SI 2 "=X,X,X,X,&z,X,X,X,X,X,X,X,X,y,X,X,X"))]
+ "f,r,G,H,FQ,mf,f,FQ,mr,r,y,f,>,fr,y,r,y"))
+ (use (match_operand:PSI 2 "fpscr_operand" "c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c"))
+ (clobber (match_scratch:SI 3 "=X,X,X,X,&z,X,X,X,X,X,X,X,X,y,X,X,X"))]
"TARGET_SH3E
&& (arith_reg_operand (operands[0], SFmode)
@@ -2181,16 +2863,19 @@
lds %1,%0
! move optimized away"
[(set_attr "type" "fmove,move,fmove,fmove,pcload,load,store,pcload,load,store,fmove,fmove,load,*,gp_fpul,gp_fpul,nil")
- (set_attr "length" "*,*,*,*,4,*,*,*,*,*,2,2,2,*,2,2,0")])
+ (set_attr "length" "*,*,*,*,4,*,*,*,*,*,2,2,2,4,2,2,0")])
(define_split
[(set (match_operand:SF 0 "register_operand" "")
(match_operand:SF 1 "register_operand" ""))
+ (use (match_operand:PSI 2 "fpscr_operand" "c"))
(clobber (reg:SI 22))]
""
[(parallel [(set (reg:SF 22) (match_dup 1))
+ (use (match_dup 2))
(clobber (scratch:SI))])
(parallel [(set (match_dup 0) (reg:SF 22))
+ (use (match_dup 2))
(clobber (scratch:SI))])]
"")
@@ -2204,17 +2889,70 @@
DONE;
if (TARGET_SH3E)
{
- emit_insn (gen_movsf_ie (operands[0], operands[1]));
+ if (no_new_pseudos)
+ {
+ /* ??? FIXME: This is only a stopgap fix. There is no guarantee
+ that fpscr is in the right state. */
+ emit_insn (gen_movsf_ie (operands[0], operands[1], get_fpscr_rtx ()));
+ DONE;
+ }
+ emit_sf_insn (gen_movsf_ie (operands[0], operands[1], get_fpscr_rtx ()));
+ /* We need something to tag possible REG_LIBCALL notes on to. */
+ if (! TARGET_FPU_SINGLE && rtx_equal_function_value_matters
+ && GET_CODE (operands[0]) == REG)
+ emit_insn (gen_mov_nop (operands[0]));
DONE;
}
}")
+(define_insn "mov_nop"
+ [(set (match_operand 0 "register_operand" "") (match_dup 0))]
+ "TARGET_SH3E"
+ ""
+ [(set_attr "length" "0")
+ (set_attr "type" "nil")])
+
(define_expand "reload_insf"
[(parallel [(set (match_operand:SF 0 "register_operand" "=f")
(match_operand:SF 1 "immediate_operand" "FQ"))
+ (use (reg:PSI 48))
+ (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
+ ""
+ "")
+
+(define_expand "reload_insi"
+ [(parallel [(set (match_operand:SF 0 "register_operand" "=y")
+ (match_operand:SF 1 "immediate_operand" "FQ"))
(clobber (match_operand:SI 2 "register_operand" "=&z"))])]
""
"")
+
+(define_insn "*movsi_y"
+ [(set (match_operand:SI 0 "register_operand" "=y,y")
+ (match_operand:SI 1 "immediate_operand" "Qi,I"))
+ (clobber (match_scratch:SI 3 "=&z,r"))]
+ "TARGET_SH3E
+ && (reload_in_progress || reload_completed)"
+ "#"
+ [(set_attr "length" "4")
+ (set_attr "type" "pcload,move")])
+
+(define_split
+ [(set (match_operand:SI 0 "register_operand" "y")
+ (match_operand:SI 1 "immediate_operand" "I"))
+ (clobber (match_operand:SI 2 "register_operand" "r"))]
+ ""
+ [(set (match_dup 2) (match_dup 1))
+ (set (match_dup 0) (match_dup 2))]
+ "")
+
+(define_split
+ [(set (match_operand:SI 0 "register_operand" "y")
+ (match_operand:SI 1 "memory_operand" ">"))
+ (clobber (reg:SI 0))]
+ ""
+ [(set (match_dup 0) (match_dup 1))]
+ "")
;; ------------------------------------------------------------------------
;; Define the real conditional branch instructions.
@@ -2289,7 +3027,7 @@
""
"
{
- if (GET_MODE (sh_compare_op0) == SFmode)
+ if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
{
rtx tmp = sh_compare_op0;
sh_compare_op0 = sh_compare_op1;
@@ -2396,6 +3134,7 @@
(define_insn "calli"
[(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
(match_operand 1 "" ""))
+ (use (reg:SI 48))
(clobber (reg:SI 17))]
""
"jsr @%0%#"
@@ -2406,6 +3145,7 @@
[(set (match_operand 0 "" "=rf")
(call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
(match_operand 2 "" "")))
+ (use (reg:SI 48))
(clobber (reg:SI 17))]
""
"jsr @%1%#"
@@ -2415,6 +3155,7 @@
(define_expand "call"
[(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
(match_operand 1 "" ""))
+ (use (reg:SI 48))
(clobber (reg:SI 17))])]
""
"operands[0] = force_reg (SImode, XEXP (operands[0], 0));")
@@ -2423,6 +3164,7 @@
[(parallel [(set (match_operand 0 "arith_reg_operand" "")
(call (mem:SI (match_operand 1 "arith_reg_operand" ""))
(match_operand 2 "" "")))
+ (use (reg:SI 48))
(clobber (reg:SI 17))])]
""
"operands[1] = force_reg (SImode, XEXP (operands[1], 0));")
@@ -2656,9 +3398,16 @@
}"
[(set_attr "length" "4")])
+;; ??? This is not the proper place to invoke another compiler pass;
+;; Alas, there is no proper place to put it.
+;; ??? This is also an odd place for the call to emit_fpscr_use. It
+;; would be all right if it were for an define_expand for return, but
+;; that doesn't mix with emitting a prologue.
(define_insn "return"
[(return)]
- "reload_completed"
+ "emit_fpscr_use (),
+ remove_dead_before_cse (),
+ reload_completed"
"%@ %#"
[(set_attr "type" "return")
(set_attr "needs_delay_slot" "yes")])
@@ -2726,19 +3475,15 @@
""
"
{
- if (GET_MODE (sh_compare_op0) == SFmode)
+ if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
{
if (TARGET_IEEE)
{
rtx t_reg = gen_rtx (REG, SImode, T_REG);
rtx lab = gen_label_rtx ();
- emit_insn (gen_rtx (SET, VOIDmode, t_reg,
- gen_rtx (EQ, SImode, sh_compare_op0,
- sh_compare_op1)));
+ prepare_scc_operands (EQ);
emit_jump_insn (gen_branch_true (lab));
- emit_insn (gen_rtx (SET, VOIDmode, t_reg,
- gen_rtx (GT, SImode, sh_compare_op0,
- sh_compare_op1)));
+ prepare_scc_operands (GT);
emit_label (lab);
emit_insn (gen_movt (operands[0]));
}
@@ -2963,7 +3708,7 @@
(use (match_operand:SI 0 "arith_reg_operand" "r"))
(clobber (reg:SI 17))
(clobber (reg:SI 0))])]
- ""
+ "! TARGET_HARD_SH4"
"jsr @%0%#"
[(set_attr "type" "sfunc")
(set_attr "needs_delay_slot" "yes")])
@@ -2978,7 +3723,38 @@
(clobber (reg:SI 5))
(clobber (reg:SI 6))
(clobber (reg:SI 0))])]
- ""
+ "! TARGET_HARD_SH4"
+ "jsr @%0%#"
+ [(set_attr "type" "sfunc")
+ (set_attr "needs_delay_slot" "yes")])
+
+(define_insn "block_move_real_i4"
+ [(parallel [(set (mem:BLK (reg:SI 4))
+ (mem:BLK (reg:SI 5)))
+ (use (match_operand:SI 0 "arith_reg_operand" "r"))
+ (clobber (reg:SI 17))
+ (clobber (reg:SI 0))
+ (clobber (reg:SI 1))
+ (clobber (reg:SI 2))])]
+ "TARGET_HARD_SH4"
+ "jsr @%0%#"
+ [(set_attr "type" "sfunc")
+ (set_attr "needs_delay_slot" "yes")])
+
+(define_insn "block_lump_real_i4"
+ [(parallel [(set (mem:BLK (reg:SI 4))
+ (mem:BLK (reg:SI 5)))
+ (use (match_operand:SI 0 "arith_reg_operand" "r"))
+ (use (reg:SI 6))
+ (clobber (reg:SI 17))
+ (clobber (reg:SI 4))
+ (clobber (reg:SI 5))
+ (clobber (reg:SI 6))
+ (clobber (reg:SI 0))
+ (clobber (reg:SI 1))
+ (clobber (reg:SI 2))
+ (clobber (reg:SI 3))])]
+ "TARGET_HARD_SH4"
"jsr @%0%#"
[(set_attr "type" "sfunc")
(set_attr "needs_delay_slot" "yes")])
@@ -2989,43 +3765,188 @@
;; ??? All patterns should have a type attribute.
-(define_insn "addsf3"
+(define_expand "fpu_switch0"
+ [(set (match_operand:SI 0 "" "") (symbol_ref "__fpscr_values"))
+ (set (match_dup 2) (match_dup 1))]
+ ""
+ "
+{
+ operands[1] = gen_rtx (MEM, PSImode, operands[0]);
+ RTX_UNCHANGING_P (operands[1]) = 1;
+ operands[2] = get_fpscr_rtx ();
+}")
+
+(define_expand "fpu_switch1"
+ [(set (match_operand:SI 0 "" "") (symbol_ref "__fpscr_values"))
+ (set (match_dup 1) (plus:SI (match_dup 0) (const_int 4)))
+ (set (match_dup 3) (match_dup 2))]
+ ""
+ "
+{
+ operands[1] = gen_reg_rtx (SImode);
+ operands[2] = gen_rtx (MEM, PSImode, operands[1]);
+ RTX_UNCHANGING_P (operands[2]) = 1;
+ operands[3] = get_fpscr_rtx ();
+}")
+
+(define_expand "movpsi"
+ [(set (match_operand:PSI 0 "register_operand" "")
+ (match_operand:PSI 1 "general_movsrc_operand" ""))]
+ ""
+ "")
+
+;; The c / m alternative is a fake to guide reload to load directly into
+;; fpscr, since reload doesn't know how to use post-increment.
+;; GO_IF_LEGITIMATE_ADDRESS guards about bogus addresses before reload,
+;; SECONDARY_INPUT_RELOAD_CLASS does this during reload, and the insn's
+;; predicate after reload.
+;; The gp_fpul type for r/!c might look a bit odd, but it actually schedules
+;; like a gpr <-> fpul move.
+(define_insn "fpu_switch"
+ [(set (match_operand:PSI 0 "register_operand" "c,c,r,c,c,r,m,r")
+ (match_operand:PSI 1 "general_movsrc_operand" "c,>,m,m,r,r,r,!c"))]
+ "! reload_completed
+ || true_regnum (operands[0]) != FPSCR_REG || GET_CODE (operands[1]) != MEM
+ || GET_CODE (XEXP (operands[1], 0)) != PLUS"
+ "@
+ ! precision stays the same
+ lds.l %1,fpscr
+ mov.l %1,%0
+ #
+ lds %1,fpscr
+ mov %1,%0
+ mov.l %1,%0
+ sts fpscr,%0"
+ [(set_attr "length" "0,2,2,4,2,2,2,2")
+ (set_attr "type" "dfp_conv,dfp_conv,load,dfp_conv,dfp_conv,move,store,gp_fpul")])
+
+(define_split
+ [(set (reg:PSI 48) (mem:PSI (match_operand:SI 0 "register_operand" "r")))]
+ "find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
+ [(set (match_dup 0) (match_dup 0))]
+ "
+{
+ rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
+ gen_rtx (MEM, PSImode,
+ gen_rtx (POST_INC, Pmode,
+ operands[0]))));
+ REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, operands[0], NULL_RTX);
+}")
+
+(define_split
+ [(set (reg:PSI 48) (mem:PSI (match_operand:SI 0 "register_operand" "r")))]
+ ""
+ [(set (match_dup 0) (plus:SI (match_dup 0) (const_int -4)))]
+ "
+{
+ rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
+ gen_rtx (MEM, PSImode,
+ gen_rtx (POST_INC, Pmode,
+ operands[0]))));
+ REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, operands[0], NULL_RTX);
+}")
+
+;; ??? This uses the fp unit, but has no type indicating that.
+;; If we did that, this would either give a bogus latency or introduce
+;; a bogus FIFO constraint.
+;; Since this insn is currently only used for prologues/epilogues,
+;; it is probably best to claim no function unit, which matches the
+;; current setting.
+(define_insn "toggle_sz"
+ [(set (reg:PSI 48) (xor:PSI (reg:PSI 48) (const_int 1048576)))]
+ "TARGET_SH4"
+ "fschg")
+
+(define_expand "addsf3"
+ [(match_operand:SF 0 "arith_reg_operand" "")
+ (match_operand:SF 1 "arith_reg_operand" "")
+ (match_operand:SF 2 "arith_reg_operand" "")]
+ "TARGET_SH3E"
+ "{ expand_sf_binop (&gen_addsf3_i, operands); DONE; }")
+
+(define_insn "addsf3_i"
[(set (match_operand:SF 0 "arith_reg_operand" "=f")
(plus:SF (match_operand:SF 1 "arith_reg_operand" "%0")
- (match_operand:SF 2 "arith_reg_operand" "f")))]
+ (match_operand:SF 2 "arith_reg_operand" "f")))
+ (use (match_operand:PSI 3 "fpscr_operand" "c"))]
"TARGET_SH3E"
"fadd %2,%0"
[(set_attr "type" "fp")])
-(define_insn "subsf3"
- [(set (match_operand:SF 0 "arith_reg_operand" "=f")
- (minus:SF (match_operand:SF 1 "arith_reg_operand" "0")
- (match_operand:SF 2 "arith_reg_operand" "f")))]
+(define_expand "subsf3"
+ [(match_operand:SF 0 "fp_arith_reg_operand" "")
+ (match_operand:SF 1 "fp_arith_reg_operand" "")
+ (match_operand:SF 2 "fp_arith_reg_operand" "")]
+ "TARGET_SH3E"
+ "{ expand_sf_binop (&gen_subsf3_i, operands); DONE; }")
+
+(define_insn "subsf3_i"
+ [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
+ (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")
+ (match_operand:SF 2 "fp_arith_reg_operand" "f")))
+ (use (match_operand:PSI 3 "fpscr_operand" "c"))]
"TARGET_SH3E"
"fsub %2,%0"
[(set_attr "type" "fp")])
-(define_insn "mulsf3"
+;; Unfortunately, the combiner is unable to cope with the USE of the FPSCR
+;; register in feeding fp instructions. Thus, we cannot generate fmac for
+;; mixed-precision SH4 targets. To allow it to be still generated for the
+;; SH3E, we use a separate insn for SH3E mulsf3.
+
+(define_expand "mulsf3"
+ [(match_operand:SF 0 "arith_reg_operand" "")
+ (match_operand:SF 1 "arith_reg_operand" "")
+ (match_operand:SF 2 "arith_reg_operand" "")]
+ "TARGET_SH3E"
+ "
+{
+ if (TARGET_SH4)
+ expand_sf_binop (&gen_mulsf3_i4, operands);
+ else
+ emit_insn (gen_mulsf3_ie (operands[0], operands[1], operands[2]));
+ DONE;
+}")
+
+(define_insn "mulsf3_i4"
[(set (match_operand:SF 0 "arith_reg_operand" "=f")
(mult:SF (match_operand:SF 1 "arith_reg_operand" "%0")
- (match_operand:SF 2 "arith_reg_operand" "f")))]
+ (match_operand:SF 2 "arith_reg_operand" "f")))
+ (use (match_operand:PSI 3 "fpscr_operand" "c"))]
"TARGET_SH3E"
"fmul %2,%0"
[(set_attr "type" "fp")])
+(define_insn "mulsf3_ie"
+ [(set (match_operand:SF 0 "arith_reg_operand" "=f")
+ (mult:SF (match_operand:SF 1 "arith_reg_operand" "%0")
+ (match_operand:SF 2 "arith_reg_operand" "f")))]
+ "TARGET_SH3E && ! TARGET_SH4"
+ "fmul %2,%0"
+ [(set_attr "type" "fp")])
+
(define_insn "*macsf3"
[(set (match_operand:SF 0 "arith_reg_operand" "=f")
(plus:SF (mult:SF (match_operand:SF 1 "arith_reg_operand" "%w")
(match_operand:SF 2 "arith_reg_operand" "f"))
- (match_operand:SF 3 "arith_reg_operand" "0")))]
- "TARGET_SH3E"
+ (match_operand:SF 3 "arith_reg_operand" "0")))
+ (use (match_operand:PSI 4 "fpscr_operand" "c"))]
+ "TARGET_SH3E && ! TARGET_SH4"
"fmac fr0,%2,%0"
[(set_attr "type" "fp")])
-(define_insn "divsf3"
+(define_expand "divsf3"
+ [(match_operand:SF 0 "arith_reg_operand" "")
+ (match_operand:SF 1 "arith_reg_operand" "")
+ (match_operand:SF 2 "arith_reg_operand" "")]
+ "TARGET_SH3E"
+ "{ expand_sf_binop (&gen_divsf3_i, operands); DONE; }")
+
+(define_insn "divsf3_i"
[(set (match_operand:SF 0 "arith_reg_operand" "=f")
(div:SF (match_operand:SF 1 "arith_reg_operand" "0")
- (match_operand:SF 2 "arith_reg_operand" "f")))]
+ (match_operand:SF 2 "arith_reg_operand" "f")))
+ (use (match_operand:PSI 3 "fpscr_operand" "c"))]
"TARGET_SH3E"
"fdiv %2,%0"
[(set_attr "type" "fdiv")])
@@ -3033,15 +3954,34 @@
(define_expand "floatsisf2"
[(set (reg:SI 22)
(match_operand:SI 1 "arith_reg_operand" ""))
- (set (match_operand:SF 0 "arith_reg_operand" "")
- (float:SF (reg:SI 22)))]
+ (parallel [(set (match_operand:SF 0 "arith_reg_operand" "")
+ (float:SF (reg:SI 22)))
+ (use (match_dup 2))])]
"TARGET_SH3E"
- "")
+ "
+{
+ if (TARGET_SH4)
+ {
+ emit_insn (gen_rtx (SET, VOIDmode, gen_rtx (REG, SImode, 22),
+ operands[1]));
+ emit_sf_insn (gen_floatsisf2_i4 (operands[0], get_fpscr_rtx ()));
+ DONE;
+ }
+ operands[2] = get_fpscr_rtx ();
+}")
+
+(define_insn "floatsisf2_i4"
+ [(set (match_operand:SF 0 "arith_reg_operand" "=f")
+ (float:SF (reg:SI 22)))
+ (use (match_operand:PSI 1 "fpscr_operand" "c"))]
+ "TARGET_SH3E"
+ "float fpul,%0"
+ [(set_attr "type" "fp")])
(define_insn "*floatsisf2_ie"
[(set (match_operand:SF 0 "arith_reg_operand" "=f")
(float:SF (reg:SI 22)))]
- "TARGET_SH3E"
+ "TARGET_SH3E && ! TARGET_SH4"
"float fpul,%0"
[(set_attr "type" "fp")])
@@ -3051,26 +3991,62 @@
(set (match_operand:SI 0 "arith_reg_operand" "=r")
(reg:SI 22))]
"TARGET_SH3E"
- "")
+ "
+{
+ if (TARGET_SH4)
+ {
+ emit_sf_insn (gen_fix_truncsfsi2_i4 (operands[1], get_fpscr_rtx ()));
+ emit_insn (gen_rtx (SET, VOIDmode, operands[0],
+ gen_rtx (REG, SImode, 22)));
+ DONE;
+ }
+}")
+
+(define_insn "fix_truncsfsi2_i4"
+ [(set (reg:SI 22)
+ (fix:SI (match_operand:SF 0 "arith_reg_operand" "f")))
+ (use (match_operand:PSI 1 "fpscr_operand" "c"))]
+ "TARGET_SH4"
+ "ftrc %0,fpul"
+ [(set_attr "type" "fp")])
+
+(define_insn "fix_truncsfsi2_i4_2"
+ [(set (match_operand:SI 0 "arith_reg_operand" "=r")
+ (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
+ (use (reg:SI 48))
+ (clobber (reg:SI 22))]
+ "TARGET_SH4"
+ "#"
+ [(set_attr "length" "4")])
+
+(define_split
+ [(set (match_operand:SI 0 "arith_reg_operand" "=r")
+ (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
+ (use (match_operand:PSI 2 "fpscr_operand" "c"))
+ (clobber (reg:SI 22))]
+ "TARGET_SH4"
+ [(parallel [(set (reg:SI 22) (fix:SI (match_dup 1)))
+ (use (match_dup 2))])
+ (set (match_dup 0) (reg:SI 22))])
(define_insn "*fixsfsi"
[(set (reg:SI 22)
(fix:SI (match_operand:SF 0 "arith_reg_operand" "f")))]
- "TARGET_SH3E"
+ "TARGET_SH3E && ! TARGET_SH4"
"ftrc %0,fpul"
[(set_attr "type" "fp")])
(define_insn "cmpgtsf_t"
[(set (reg:SI 18) (gt:SI (match_operand:SF 0 "arith_reg_operand" "f")
(match_operand:SF 1 "arith_reg_operand" "f")))]
- "TARGET_SH3E"
+ "TARGET_SH3E && ! TARGET_SH4"
"fcmp/gt %1,%0"
[(set_attr "type" "fp")])
(define_insn "cmpeqsf_t"
[(set (reg:SI 18) (eq:SI (match_operand:SF 0 "arith_reg_operand" "f")
(match_operand:SF 1 "arith_reg_operand" "f")))]
- "TARGET_SH3E"
+ "TARGET_SH3E && ! TARGET_SH4"
"fcmp/eq %1,%0"
[(set_attr "type" "fp")])
@@ -3078,11 +4054,36 @@
[(set (reg:SI 18) (ior:SI (reg:SI 18)
(eq:SI (match_operand:SF 0 "arith_reg_operand" "f")
(match_operand:SF 1 "arith_reg_operand" "f"))))]
- "TARGET_SH3E && TARGET_IEEE"
+ "TARGET_SH3E && TARGET_IEEE && ! TARGET_SH4"
"* return output_ieee_ccmpeq (insn, operands);"
[(set_attr "length" "4")])
+(define_insn "cmpgtsf_t_i4"
+ [(set (reg:SI 18) (gt:SI (match_operand:SF 0 "arith_reg_operand" "f")
+ (match_operand:SF 1 "arith_reg_operand" "f")))
+ (use (match_operand:PSI 2 "fpscr_operand" "c"))]
+ "TARGET_SH4"
+ "fcmp/gt %1,%0"
+ [(set_attr "type" "fp")])
+
+(define_insn "cmpeqsf_t_i4"
+ [(set (reg:SI 18) (eq:SI (match_operand:SF 0 "arith_reg_operand" "f")
+ (match_operand:SF 1 "arith_reg_operand" "f")))
+ (use (match_operand:PSI 2 "fpscr_operand" "c"))]
+ "TARGET_SH4"
+ "fcmp/eq %1,%0"
+ [(set_attr "type" "fp")])
+
+(define_insn "*ieee_ccmpeqsf_t_4"
+ [(set (reg:SI 18) (ior:SI (reg:SI 18)
+ (eq:SI (match_operand:SF 0 "arith_reg_operand" "f")
+ (match_operand:SF 1 "arith_reg_operand" "f"))))
+ (use (match_operand:PSI 2 "fpscr_operand" "c"))]
+ "TARGET_IEEE && TARGET_SH4"
+ "* return output_ieee_ccmpeq (insn, operands);"
+ [(set_attr "length" "4")])
+
(define_expand "cmpsf"
[(set (reg:SI 18) (compare (match_operand:SF 0 "arith_operand" "")
(match_operand:SF 1 "arith_operand" "")))]
@@ -3094,25 +4095,285 @@
DONE;
}")
-(define_insn "negsf2"
+(define_expand "negsf2"
+ [(match_operand:SF 0 "arith_reg_operand" "")
+ (match_operand:SF 1 "arith_reg_operand" "")]
+ "TARGET_SH3E"
+ "{ expand_sf_unop (&gen_negsf2_i, operands); DONE; }")
+
+(define_insn "negsf2_i"
[(set (match_operand:SF 0 "arith_reg_operand" "=f")
- (neg:SF (match_operand:SF 1 "arith_reg_operand" "0")))]
+ (neg:SF (match_operand:SF 1 "arith_reg_operand" "0")))
+ (use (match_operand:PSI 2 "fpscr_operand" "c"))]
"TARGET_SH3E"
"fneg %0"
- [(set_attr "type" "fp")])
+ [(set_attr "type" "fmove")])
-(define_insn "sqrtsf2"
+(define_expand "sqrtsf2"
+ [(match_operand:SF 0 "arith_reg_operand" "")
+ (match_operand:SF 1 "arith_reg_operand" "")]
+ "TARGET_SH3E"
+ "{ expand_sf_unop (&gen_sqrtsf2_i, operands); DONE; }")
+
+(define_insn "sqrtsf2_i"
[(set (match_operand:SF 0 "arith_reg_operand" "=f")
- (sqrt:SF (match_operand:SF 1 "arith_reg_operand" "0")))]
+ (sqrt:SF (match_operand:SF 1 "arith_reg_operand" "0")))
+ (use (match_operand:PSI 2 "fpscr_operand" "c"))]
"TARGET_SH3E"
"fsqrt %0"
[(set_attr "type" "fdiv")])
-(define_insn "abssf2"
+(define_expand "abssf2"
+ [(match_operand:SF 0 "arith_reg_operand" "")
+ (match_operand:SF 1 "arith_reg_operand" "")]
+ "TARGET_SH3E"
+ "{ expand_sf_unop (&gen_abssf2_i, operands); DONE; }")
+
+(define_insn "abssf2_i"
[(set (match_operand:SF 0 "arith_reg_operand" "=f")
- (abs:SF (match_operand:SF 1 "arith_reg_operand" "0")))]
+ (abs:SF (match_operand:SF 1 "arith_reg_operand" "0")))
+ (use (match_operand:PSI 2 "fpscr_operand" "c"))]
"TARGET_SH3E"
"fabs %0"
+ [(set_attr "type" "fmove")])
+
+(define_expand "adddf3"
+ [(match_operand:DF 0 "arith_reg_operand" "")
+ (match_operand:DF 1 "arith_reg_operand" "")
+ (match_operand:DF 2 "arith_reg_operand" "")]
+ "TARGET_SH4"
+ "{ expand_df_binop (&gen_adddf3_i, operands); DONE; }")
+
+(define_insn "adddf3_i"
+ [(set (match_operand:DF 0 "arith_reg_operand" "=f")
+ (plus:DF (match_operand:DF 1 "arith_reg_operand" "%0")
+ (match_operand:DF 2 "arith_reg_operand" "f")))
+ (use (match_operand:PSI 3 "fpscr_operand" "c"))]
+ "TARGET_SH4"
+ "fadd %2,%0"
+ [(set_attr "type" "dfp_arith")])
+
+(define_expand "subdf3"
+ [(match_operand:DF 0 "arith_reg_operand" "")
+ (match_operand:DF 1 "arith_reg_operand" "")
+ (match_operand:DF 2 "arith_reg_operand" "")]
+ "TARGET_SH4"
+ "{ expand_df_binop (&gen_subdf3_i, operands); DONE; }")
+
+(define_insn "subdf3_i"
+ [(set (match_operand:DF 0 "arith_reg_operand" "=f")
+ (minus:DF (match_operand:DF 1 "arith_reg_operand" "0")
+ (match_operand:DF 2 "arith_reg_operand" "f")))
+ (use (match_operand:PSI 3 "fpscr_operand" "c"))]
+ "TARGET_SH4"
+ "fsub %2,%0"
+ [(set_attr "type" "dfp_arith")])
+
+(define_expand "muldf3"
+ [(match_operand:DF 0 "arith_reg_operand" "")
+ (match_operand:DF 1 "arith_reg_operand" "")
+ (match_operand:DF 2 "arith_reg_operand" "")]
+ "TARGET_SH4"
+ "{ expand_df_binop (&gen_muldf3_i, operands); DONE; }")
+
+(define_insn "muldf3_i"
+ [(set (match_operand:DF 0 "arith_reg_operand" "=f")
+ (mult:DF (match_operand:DF 1 "arith_reg_operand" "%0")
+ (match_operand:DF 2 "arith_reg_operand" "f")))
+ (use (match_operand:PSI 3 "fpscr_operand" "c"))]
+ "TARGET_SH4"
+ "fmul %2,%0"
+ [(set_attr "type" "dfp_arith")])
+
+(define_expand "divdf3"
+ [(match_operand:DF 0 "arith_reg_operand" "")
+ (match_operand:DF 1 "arith_reg_operand" "")
+ (match_operand:DF 2 "arith_reg_operand" "")]
+ "TARGET_SH4"
+ "{ expand_df_binop (&gen_divdf3_i, operands); DONE; }")
+
+(define_insn "divdf3_i"
+ [(set (match_operand:DF 0 "arith_reg_operand" "=f")
+ (div:DF (match_operand:DF 1 "arith_reg_operand" "0")
+ (match_operand:DF 2 "arith_reg_operand" "f")))
+ (use (match_operand:PSI 3 "fpscr_operand" "c"))]
+ "TARGET_SH4"
+ "fdiv %2,%0"
+ [(set_attr "type" "dfdiv")])
+
+(define_expand "floatsidf2"
+ [(match_operand:DF 0 "arith_reg_operand" "")
+ (match_operand:SI 1 "arith_reg_operand" "")]
+ "TARGET_SH4"
+ "
+{
+ emit_insn (gen_rtx (SET, VOIDmode, gen_rtx (REG, SImode, 22), operands[1]));
+ emit_df_insn (gen_floatsidf2_i (operands[0], get_fpscr_rtx ()));
+ DONE;
+}")
+
+(define_insn "floatsidf2_i"
+ [(set (match_operand:DF 0 "arith_reg_operand" "=f")
+ (float:DF (reg:SI 22)))
+ (use (match_operand:PSI 1 "fpscr_operand" "c"))]
+ "TARGET_SH4"
+ "float fpul,%0"
+ [(set_attr "type" "dfp_conv")])
+
+(define_expand "fix_truncdfsi2"
+ [(match_operand:SI 0 "arith_reg_operand" "=r")
+ (match_operand:DF 1 "arith_reg_operand" "f")]
+ "TARGET_SH4"
+ "
+{
+ emit_df_insn (gen_fix_truncdfsi2_i (operands[1], get_fpscr_rtx ()));
+ emit_insn (gen_rtx (SET, VOIDmode, operands[0], gen_rtx (REG, SImode, 22)));
+ DONE;
+}")
+
+(define_insn "fix_truncdfsi2_i"
+ [(set (reg:SI 22)
+ (fix:SI (match_operand:DF 0 "arith_reg_operand" "f")))
+ (use (match_operand:PSI 1 "fpscr_operand" "c"))]
+ "TARGET_SH4"
+ "ftrc %0,fpul"
+ [(set_attr "type" "dfp_conv")])
+
+(define_insn "fix_truncdfsi2_i4"
+ [(set (match_operand:SI 0 "arith_reg_operand" "=r")
+ (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
+ (use (match_operand:PSI 2 "fpscr_operand" "c"))
+ (clobber (reg:SI 22))]
+ "TARGET_SH4"
+ "#"
+ [(set_attr "length" "4")])
+
+(define_split
+ [(set (match_operand:SI 0 "arith_reg_operand" "=r")
+ (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
+ (use (match_operand:PSI 2 "fpscr_operand" "c"))
+ (clobber (reg:SI 22))]
+ "TARGET_SH4"
+ [(parallel [(set (reg:SI 22) (fix:SI (match_dup 1)))
+ (use (match_dup 2))])
+ (set (match_dup 0) (reg:SI 22))])
+
+(define_insn "cmpgtdf_t"
+ [(set (reg:SI 18) (gt:SI (match_operand:DF 0 "arith_reg_operand" "f")
+ (match_operand:DF 1 "arith_reg_operand" "f")))
+ (use (match_operand:PSI 2 "fpscr_operand" "c"))]
+ "TARGET_SH4"
+ "fcmp/gt %1,%0"
+ [(set_attr "type" "dfp_cmp")])
+
+(define_insn "cmpeqdf_t"
+ [(set (reg:SI 18) (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
+ (match_operand:DF 1 "arith_reg_operand" "f")))
+ (use (match_operand:PSI 2 "fpscr_operand" "c"))]
+ "TARGET_SH4"
+ "fcmp/eq %1,%0"
+ [(set_attr "type" "dfp_cmp")])
+
+(define_insn "*ieee_ccmpeqdf_t"
+ [(set (reg:SI 18) (ior:SI (reg:SI 18)
+ (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
+ (match_operand:DF 1 "arith_reg_operand" "f"))))
+ (use (match_operand:PSI 2 "fpscr_operand" "c"))]
+ "TARGET_IEEE && TARGET_SH4"
+ "* return output_ieee_ccmpeq (insn, operands);"
+ [(set_attr "length" "4")])
+
+(define_expand "cmpdf"
+ [(set (reg:SI 18) (compare (match_operand:DF 0 "arith_operand" "")
+ (match_operand:DF 1 "arith_operand" "")))]
+ "TARGET_SH4"
+ "
+{
+ sh_compare_op0 = operands[0];
+ sh_compare_op1 = operands[1];
+ DONE;
+}")
+
+(define_expand "negdf2"
+ [(match_operand:DF 0 "arith_reg_operand" "")
+ (match_operand:DF 1 "arith_reg_operand" "")]
+ "TARGET_SH4"
+ "{ expand_df_unop (&gen_negdf2_i, operands); DONE; }")
+
+(define_insn "negdf2_i"
+ [(set (match_operand:DF 0 "arith_reg_operand" "=f")
+ (neg:DF (match_operand:DF 1 "arith_reg_operand" "0")))
+ (use (match_operand:PSI 2 "fpscr_operand" "c"))]
+ "TARGET_SH4"
+ "fneg %0"
+ [(set_attr "type" "fmove")])
+
+(define_expand "sqrtdf2"
+ [(match_operand:DF 0 "arith_reg_operand" "")
+ (match_operand:DF 1 "arith_reg_operand" "")]
+ "TARGET_SH4"
+ "{ expand_df_unop (&gen_sqrtdf2_i, operands); DONE; }")
+
+(define_insn "sqrtdf2_i"
+ [(set (match_operand:DF 0 "arith_reg_operand" "=f")
+ (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "0")))
+ (use (match_operand:PSI 2 "fpscr_operand" "c"))]
+ "TARGET_SH4"
+ "fsqrt %0"
+ [(set_attr "type" "dfdiv")])
+
+(define_expand "absdf2"
+ [(match_operand:DF 0 "arith_reg_operand" "")
+ (match_operand:DF 1 "arith_reg_operand" "")]
+ "TARGET_SH4"
+ "{ expand_df_unop (&gen_absdf2_i, operands); DONE; }")
+
+(define_insn "absdf2_i"
+ [(set (match_operand:DF 0 "arith_reg_operand" "=f")
+ (abs:DF (match_operand:DF 1 "arith_reg_operand" "0")))
+ (use (match_operand:PSI 2 "fpscr_operand" "c"))]
+ "TARGET_SH4"
+ "fabs %0"
+ [(set_attr "type" "fmove")])
+
+(define_expand "extendsfdf2"
+ [(match_operand:DF 0 "arith_reg_operand" "")
+ (match_operand:SF 1 "arith_reg_operand" "")]
+ "TARGET_SH4"
+ "
+{
+ emit_sf_insn (gen_movsf_ie (gen_rtx (REG, SFmode, 22), operands[1],
+ get_fpscr_rtx ()));
+ emit_df_insn (gen_extendsfdf2_i4 (operands[0], get_fpscr_rtx ()));
+ DONE;
+}")
+
+(define_insn "extendsfdf2_i4"
+ [(set (match_operand:DF 0 "arith_reg_operand" "=f")
+ (float_extend:DF (reg:SF 22)))
+ (use (match_operand:PSI 1 "fpscr_operand" "c"))]
+ "TARGET_SH4"
+ "fcnvsd fpul,%0"
+ [(set_attr "type" "fp")])
+
+(define_expand "truncdfsf2"
+ [(match_operand:SF 0 "arith_reg_operand" "")
+ (match_operand:DF 1 "arith_reg_operand" "")]
+ "TARGET_SH4"
+ "
+{
+ emit_df_insn (gen_truncdfsf2_i4 (operands[1], get_fpscr_rtx ()));
+ emit_sf_insn (gen_movsf_ie (operands[0], gen_rtx (REG, SFmode, 22),
+ get_fpscr_rtx ()));
+ DONE;
+}")
+
+(define_insn "truncdfsf2_i4"
+ [(set (reg:SF 22)
+ (float_truncate:SF (match_operand:DF 0 "arith_reg_operand" "f")))
+ (use (match_operand:PSI 1 "fpscr_operand" "c"))]
+ "TARGET_SH4"
+ "fcnvds %0,fpul"
[(set_attr "type" "fp")])
;; Bit field extract patterns. These give better code for packed bitfields,
diff --git a/gcc/config/sh/t-sh b/gcc/config/sh/t-sh
index c6af7c1839b..bfbf45ea6a0 100644
--- a/gcc/config/sh/t-sh
+++ b/gcc/config/sh/t-sh
@@ -1,7 +1,7 @@
CROSS_LIBGCC1 = libgcc1-asm.a
LIB1ASMSRC = sh/lib1funcs.asm
LIB1ASMFUNCS = _ashiftrt _ashiftrt_n _ashiftlt _lshiftrt _movstr \
- _mulsi3 _sdivsi3 _udivsi3 _set_fpscr
+ _movstr_i4 _mulsi3 _sdivsi3 _sdivsi3_i4 _udivsi3 _udivsi3_i4 _set_fpscr
# These are really part of libgcc1, but this will cause them to be
# built correctly, so...
@@ -21,7 +21,7 @@ fp-bit.c: $(srcdir)/config/fp-bit.c
echo '#endif' >> fp-bit.c
cat $(srcdir)/config/fp-bit.c >> fp-bit.c
-MULTILIB_OPTIONS= ml m2/m3e
+MULTILIB_OPTIONS= ml m2/m3e/m4-single-only/m4-single/m4
MULTILIB_DIRNAMES=
MULTILIB_MATCHES = m2=m3
diff --git a/gcc/config/sparc/elf.h b/gcc/config/sparc/elf.h
index 70cb26a93be..635238f5b1f 100644
--- a/gcc/config/sparc/elf.h
+++ b/gcc/config/sparc/elf.h
@@ -40,3 +40,19 @@ Boston, MA 02111-1307, USA. */
/* FIXME: until fixed */
#undef LONG_DOUBLE_TYPE_SIZE
#define LONG_DOUBLE_TYPE_SIZE 64
+
+/* This solaris2 define does not apply. */
+#undef STDC_0_IN_SYSTEM_HEADERS
+
+/* We don't want to use the Solaris2 specific long long int conversion
+ routines. */
+#undef INIT_SUBTARGET_OPTABS
+#define INIT_SUBTARGET_OPTABS
+
+/* ??? We haven't added Solaris2 equivalent 64 bit library routines to
+ lb1sp*.asm, so we need to avoid using them. */
+#undef MULDI3_LIBCALL
+#undef DIVDI3_LIBCALL
+#undef UDIVDI3_LIBCALL
+#undef MODDI3_LIBCALL
+#undef UMODDI3_LIBCALL
diff --git a/gcc/config/sparc/gmon-sol2.c b/gcc/config/sparc/gmon-sol2.c
index 2a5b898353d..a6abcabcc51 100644
--- a/gcc/config/sparc/gmon-sol2.c
+++ b/gcc/config/sparc/gmon-sol2.c
@@ -35,16 +35,8 @@
* for Cygnus Support, July 1992.
*/
-#ifndef lint
-static char sccsid[] = "@(#)gmon.c 5.3 (Berkeley) 5/22/91";
-#endif /* not lint */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <limits.h>
-#include <unistd.h>
-#include <fcntl.h>
+#include "config.h"
+#include "system.h"
#if 0
#include "sparc/gmon.h"
@@ -96,7 +88,9 @@ static int s_scale;
#define MSG "No space for profiling buffer(s)\n"
-static void moncontrol();
+static void moncontrol PROTO ((int));
+extern void monstartup PROTO ((char *, char *));
+extern void _mcleanup PROTO ((void));
void monstartup(lowpc, highpc)
char *lowpc;
@@ -185,7 +179,7 @@ _mcleanup()
int toindex;
struct rawarc rawarc;
char *profdir;
- char *proffile;
+ const char *proffile;
char *progname;
char buf[PATH_MAX];
extern char **___Argv;
@@ -275,6 +269,8 @@ _mcleanup()
* -- [eichin:19920702.1107EST]
*/
+static void internal_mcount PROTO((char *, unsigned short *)) ATTRIBUTE_UNUSED;
+
/* i7 == last ret, -> frompcindex */
/* o7 == current ret, -> selfpc */
/* Solaris 2 libraries use _mcount. */
@@ -297,9 +293,9 @@ static void internal_mcount(selfpc, frompcindex)
*/
if(!already_setup) {
- extern etext();
+ extern char etext[];
already_setup = 1;
- monstartup(0, etext);
+ monstartup(0, (char *)etext);
#ifdef USE_ONEXIT
on_exit(_mcleanup, 0);
#else
diff --git a/gcc/config/sparc/linux.h b/gcc/config/sparc/linux.h
index fe6bf6a9934..d967b01ebe3 100644
--- a/gcc/config/sparc/linux.h
+++ b/gcc/config/sparc/linux.h
@@ -103,7 +103,7 @@ Boston, MA 02111-1307, USA. */
#define WCHAR_TYPE_SIZE BITS_PER_WORD
#undef CPP_PREDEFINES
-#define CPP_PREDEFINES "-D__ELF__ -Dunix -Dsparc -Dlinux -Asystem(unix) -Asystem(posix)"
+#define CPP_PREDEFINES "-D__ELF__ -Dunix -D__sparc__ -Dlinux -Asystem(unix) -Asystem(posix)"
#undef CPP_SUBTARGET_SPEC
#ifdef USE_GNULIBC_1
diff --git a/gcc/config/sparc/linux64.h b/gcc/config/sparc/linux64.h
index ed8c3ec3d55..705b5ca33a0 100644
--- a/gcc/config/sparc/linux64.h
+++ b/gcc/config/sparc/linux64.h
@@ -144,7 +144,7 @@ Boston, MA 02111-1307, USA. */
#define LONG_DOUBLE_TYPE_SIZE 128
#undef CPP_PREDEFINES
-#define CPP_PREDEFINES "-D__ELF__ -Dunix -Dsparc -Dlinux -Asystem(unix) -Asystem(posix)"
+#define CPP_PREDEFINES "-D__ELF__ -Dunix -D_LONGLONG -D__sparc__ -Dlinux -Asystem(unix) -Asystem(posix)"
#undef CPP_SUBTARGET_SPEC
#define CPP_SUBTARGET_SPEC "\
diff --git a/gcc/config/sparc/sp64-elf.h b/gcc/config/sparc/sp64-elf.h
index a1e4ef0c252..4fd81c55c47 100644
--- a/gcc/config/sparc/sp64-elf.h
+++ b/gcc/config/sparc/sp64-elf.h
@@ -80,8 +80,8 @@ crtbegin.o%s \
/* V9 chips can handle either endianness. */
#undef SUBTARGET_SWITCHES
#define SUBTARGET_SWITCHES \
-{"big-endian", -MASK_LITTLE_ENDIAN}, \
-{"little-endian", MASK_LITTLE_ENDIAN},
+{"big-endian", -MASK_LITTLE_ENDIAN, "Generate code for big endian" }, \
+{"little-endian", MASK_LITTLE_ENDIAN, "Generate code for little endian" },
#undef BYTES_BIG_ENDIAN
#define BYTES_BIG_ENDIAN (! TARGET_LITTLE_ENDIAN)
diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index ae207027b0f..05affdd5289 100644
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -1,5 +1,5 @@
/* Subroutines for insn-output.c for Sun SPARC.
- Copyright (C) 1987, 88, 89, 92-97, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1987, 88, 89, 92-98, 1999 Free Software Foundation, Inc.
Contributed by Michael Tiemann (tiemann@cygnus.com)
64 bit SPARC V9 support by Michael Tiemann, Jim Wilson, and Doug Evans,
at Cygnus Support.
@@ -98,18 +98,23 @@ char leaf_reg_remap[] =
this is "%sp+something". We record "something" separately as it may be
too big for reg+constant addressing. */
-static char *frame_base_name;
+static const char *frame_base_name;
static int frame_base_offset;
static rtx pic_setup_code PROTO((void));
static void sparc_init_modes PROTO((void));
-static int save_regs PROTO((FILE *, int, int, char *,
+static int save_regs PROTO((FILE *, int, int, const char *,
int, int, int));
-static int restore_regs PROTO((FILE *, int, int, char *, int, int));
-static void build_big_number PROTO((FILE *, int, char *));
+static int restore_regs PROTO((FILE *, int, int, const char *, int, int));
+static void build_big_number PROTO((FILE *, int, const char *));
static int function_arg_slotno PROTO((const CUMULATIVE_ARGS *,
enum machine_mode, tree, int, int,
int *, int *));
+
+static int supersparc_adjust_cost PROTO((rtx, rtx, rtx, int));
+static int hypersparc_adjust_cost PROTO((rtx, rtx, rtx, int));
+static int ultrasparc_adjust_cost PROTO((rtx, rtx, rtx, int));
+
static void sparc_output_addr_vec PROTO((rtx));
static void sparc_output_addr_diff_vec PROTO((rtx));
static void sparc_output_deferred_case_vectors PROTO((void));
@@ -122,14 +127,14 @@ extern char *dwarf2out_cfi_label ();
/* Option handling. */
/* Code model option as passed by user. */
-char *sparc_cmodel_string;
+const char *sparc_cmodel_string;
/* Parsed value. */
enum cmodel sparc_cmodel;
/* Record alignment options as passed by user. */
-char *sparc_align_loops_string;
-char *sparc_align_jumps_string;
-char *sparc_align_funcs_string;
+const char *sparc_align_loops_string;
+const char *sparc_align_jumps_string;
+const char *sparc_align_funcs_string;
/* Parsed values, as a power of two. */
int sparc_align_loops;
@@ -155,7 +160,7 @@ void
sparc_override_options ()
{
static struct code_model {
- char *name;
+ const char *name;
int value;
} cmodels[] = {
{ "32", CM_32 },
@@ -169,13 +174,15 @@ sparc_override_options ()
/* Map TARGET_CPU_DEFAULT to value for -m{arch,tune}=. */
static struct cpu_default {
int cpu;
- char *name;
+ const char *name;
} cpu_default[] = {
/* There must be one entry here for each TARGET_CPU value. */
{ TARGET_CPU_sparc, "cypress" },
{ TARGET_CPU_sparclet, "tsc701" },
{ TARGET_CPU_sparclite, "f930" },
{ TARGET_CPU_v8, "v8" },
+ { TARGET_CPU_hypersparc, "hypersparc" },
+ { TARGET_CPU_sparclite86x, "sparclite86x" },
{ TARGET_CPU_supersparc, "supersparc" },
{ TARGET_CPU_v9, "v9" },
{ TARGET_CPU_ultrasparc, "ultrasparc" },
@@ -184,7 +191,7 @@ sparc_override_options ()
struct cpu_default *def;
/* Table of values for -m{cpu,tune}=. */
static struct cpu_table {
- char *name;
+ const char *name;
enum processor_type processor;
int disable;
int enable;
@@ -199,6 +206,8 @@ sparc_override_options ()
The Fujitsu MB86934 is the recent sparclite chip, with an fpu. */
{ "f930", PROCESSOR_F930, MASK_ISA|MASK_FPU, MASK_SPARCLITE },
{ "f934", PROCESSOR_F934, MASK_ISA, MASK_SPARCLITE|MASK_FPU },
+ { "hypersparc", PROCESSOR_HYPERSPARC, MASK_ISA, MASK_V8|MASK_FPU },
+ { "sparclite86x", PROCESSOR_SPARCLITE86X, MASK_ISA|MASK_FPU, MASK_V8 },
{ "sparclet", PROCESSOR_SPARCLET, MASK_ISA, MASK_SPARCLET },
/* TEMIC sparclet */
{ "tsc701", PROCESSOR_TSC701, MASK_ISA, MASK_SPARCLET },
@@ -792,8 +801,7 @@ arith_operand (op, mode)
enum machine_mode mode;
{
int val;
- if (register_operand (op, mode)
- || GET_CODE (op) == CONSTANT_P_RTX)
+ if (register_operand (op, mode))
return 1;
if (GET_CODE (op) != CONST_INT)
return 0;
@@ -842,7 +850,7 @@ const64_operand (op, mode)
((CONST_DOUBLE_LOW (op) & 0x80000000) != 0 ?
(HOST_WIDE_INT)0xffffffff : 0)))
#endif
- || GET_CODE (op) == CONSTANT_P_RTX);
+ );
}
/* The same, but only for sethi instructions. */
@@ -864,8 +872,7 @@ const64_high_operand (op, mode)
|| (GET_CODE (op) == CONST_DOUBLE
&& CONST_DOUBLE_HIGH (op) == 0
&& (CONST_DOUBLE_LOW (op) & 0xfffffc00) != 0
- && SPARC_SETHI_P (CONST_DOUBLE_LOW (op)))
- || GET_CODE (op) == CONSTANT_P_RTX);
+ && SPARC_SETHI_P (CONST_DOUBLE_LOW (op))));
}
/* Return true if OP is a register, or is a CONST_INT that can fit in a
@@ -878,7 +885,6 @@ arith11_operand (op, mode)
enum machine_mode mode;
{
return (register_operand (op, mode)
- || GET_CODE (op) == CONSTANT_P_RTX
|| (GET_CODE (op) == CONST_INT && SPARC_SIMM11_P (INTVAL (op))));
}
@@ -892,7 +898,6 @@ arith10_operand (op, mode)
enum machine_mode mode;
{
return (register_operand (op, mode)
- || GET_CODE (op) == CONSTANT_P_RTX
|| (GET_CODE (op) == CONST_INT && SPARC_SIMM10_P (INTVAL (op))));
}
@@ -909,7 +914,6 @@ arith_double_operand (op, mode)
enum machine_mode mode;
{
return (register_operand (op, mode)
- || GET_CODE (op) == CONSTANT_P_RTX
|| (GET_CODE (op) == CONST_INT && SMALL_INT (op))
|| (! TARGET_ARCH64
&& GET_CODE (op) == CONST_DOUBLE
@@ -959,7 +963,6 @@ arith11_double_operand (op, mode)
enum machine_mode mode;
{
return (register_operand (op, mode)
- || GET_CODE (op) == CONSTANT_P_RTX
|| (GET_CODE (op) == CONST_DOUBLE
&& (GET_MODE (op) == mode || GET_MODE (op) == VOIDmode)
&& (unsigned HOST_WIDE_INT) (CONST_DOUBLE_LOW (op) + 0x400) < 0x800
@@ -983,7 +986,6 @@ arith10_double_operand (op, mode)
enum machine_mode mode;
{
return (register_operand (op, mode)
- || GET_CODE (op) == CONSTANT_P_RTX
|| (GET_CODE (op) == CONST_DOUBLE
&& (GET_MODE (op) == mode || GET_MODE (op) == VOIDmode)
&& (unsigned) (CONST_DOUBLE_LOW (op) + 0x200) < 0x400
@@ -1005,8 +1007,7 @@ small_int (op, mode)
rtx op;
enum machine_mode mode ATTRIBUTE_UNUSED;
{
- return ((GET_CODE (op) == CONST_INT && SMALL_INT (op))
- || GET_CODE (op) == CONSTANT_P_RTX);
+ return (GET_CODE (op) == CONST_INT && SMALL_INT (op));
}
int
@@ -1017,8 +1018,7 @@ small_int_or_double (op, mode)
return ((GET_CODE (op) == CONST_INT && SMALL_INT (op))
|| (GET_CODE (op) == CONST_DOUBLE
&& CONST_DOUBLE_HIGH (op) == 0
- && SPARC_SIMM13_P (CONST_DOUBLE_LOW (op)))
- || GET_CODE (op) == CONSTANT_P_RTX);
+ && SPARC_SIMM13_P (CONST_DOUBLE_LOW (op))));
}
/* Recognize operand values for the umul instruction. That instruction sign
@@ -1032,17 +1032,15 @@ uns_small_int (op, mode)
{
#if HOST_BITS_PER_WIDE_INT > 32
/* All allowed constants will fit a CONST_INT. */
- return ((GET_CODE (op) == CONST_INT
- && ((INTVAL (op) >= 0 && INTVAL (op) < 0x1000)
- || (INTVAL (op) >= 0xFFFFF000
- && INTVAL (op) < 0x100000000)))
- || GET_CODE (op) == CONSTANT_P_RTX);
+ return (GET_CODE (op) == CONST_INT
+ && ((INTVAL (op) >= 0 && INTVAL (op) < 0x1000)
+ || (INTVAL (op) >= 0xFFFFF000
+ && INTVAL (op) < 0x100000000)));
#else
- return (((GET_CODE (op) == CONST_INT && (unsigned) INTVAL (op) < 0x1000)
- || (GET_CODE (op) == CONST_DOUBLE
- && CONST_DOUBLE_HIGH (op) == 0
- && (unsigned) CONST_DOUBLE_LOW (op) - 0xFFFFF000 < 0x1000))
- || GET_CODE (op) == CONSTANT_P_RTX);
+ return ((GET_CODE (op) == CONST_INT && (unsigned) INTVAL (op) < 0x1000)
+ || (GET_CODE (op) == CONST_DOUBLE
+ && CONST_DOUBLE_HIGH (op) == 0
+ && (unsigned) CONST_DOUBLE_LOW (op) - 0xFFFFF000 < 0x1000));
#endif
}
@@ -1070,7 +1068,7 @@ zero_operand (op, mode)
rtx op;
enum machine_mode mode ATTRIBUTE_UNUSED;
{
- return (op == const0_rtx || GET_CODE (op) == CONSTANT_P_RTX);
+ return op == const0_rtx;
}
/* Return 1 if OP is a valid operand for the source of a move insn. */
@@ -1084,6 +1082,10 @@ input_operand (op, mode)
if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op))
return 0;
+ /* Only a tiny bit of handling for CONSTANT_P_RTX is necessary. */
+ if (GET_CODE (op) == CONST && GET_CODE (XEXP (op, 0)) == CONSTANT_P_RTX)
+ return 1;
+
/* Allow any one instruction integer constant, and all CONST_INT
variants when we are working in DImode and !arch64. */
if (GET_MODE_CLASS (mode) == MODE_INT
@@ -1112,10 +1114,6 @@ input_operand (op, mode)
))))
return 1;
- /* Always match this. */
- if (GET_CODE (op) == CONSTANT_P_RTX)
- return 1;
-
/* If !arch64 and this is a DImode const, allow it so that
the splits can be generated. */
if (! TARGET_ARCH64
@@ -2888,7 +2886,7 @@ static int
save_regs (file, low, high, base, offset, n_regs, real_offset)
FILE *file;
int low, high;
- char *base;
+ const char *base;
int offset;
int n_regs;
int real_offset;
@@ -2961,7 +2959,7 @@ static int
restore_regs (file, low, high, base, offset, n_regs)
FILE *file;
int low, high;
- char *base;
+ const char *base;
int offset;
int n_regs;
{
@@ -3076,7 +3074,7 @@ static void
build_big_number (file, num, reg)
FILE *file;
int num;
- char *reg;
+ const char *reg;
{
if (num >= 0 || ! TARGET_ARCH64)
{
@@ -3208,7 +3206,7 @@ output_function_prologue (file, size, leaf_function)
if (num_gfregs)
{
int offset, real_offset, n_regs;
- char *base;
+ const char *base;
real_offset = -apparent_fsize;
offset = -apparent_fsize + frame_base_offset;
@@ -3259,7 +3257,7 @@ output_function_epilogue (file, size, leaf_function)
int size ATTRIBUTE_UNUSED;
int leaf_function;
{
- char *ret;
+ const char *ret;
if (leaf_label)
{
@@ -3289,7 +3287,7 @@ output_function_epilogue (file, size, leaf_function)
if (num_gfregs)
{
int offset, n_regs;
- char *base;
+ const char *base;
offset = -apparent_fsize + frame_base_offset;
if (offset < -4096 || offset + num_gfregs * 4 > 4096 - 8 /*double*/)
@@ -4279,7 +4277,7 @@ sparc_builtin_saveregs (arglist)
GEN_INT (STACK_POINTER_OFFSET
+ UNITS_PER_WORD * first_reg));
- if (flag_check_memory_usage
+ if (current_function_check_memory_usage
&& first_reg < NPARM_REGS (word_mode))
emit_library_call (chkr_set_right_libfunc, 1, VOIDmode, 3,
address, ptr_mode,
@@ -4677,7 +4675,7 @@ epilogue_renumber (where)
/* Output assembler code to return from a function. */
-char *
+const char *
output_return (operands)
rtx *operands;
{
@@ -5630,18 +5628,23 @@ sparc_flat_compute_frame_size (size)
/* This is the size of the 16 word reg save area, 1 word struct addr
area, and 4 word fp/alu register copy area. */
- extra_size = -STARTING_FRAME_OFFSET + FIRST_PARM_OFFSET(0);
- var_size = size;
- /* Also include the size needed for the 6 parameter registers. */
- args_size = current_function_outgoing_args_size + 24;
- total_size = var_size + args_size + extra_size;
- gp_reg_size = 0;
- fp_reg_size = 0;
- gmask = 0;
- fmask = 0;
- reg_offset = 0;
+ extra_size = -STARTING_FRAME_OFFSET + FIRST_PARM_OFFSET(0);
+ var_size = size;
+ gp_reg_size = 0;
+ fp_reg_size = 0;
+ gmask = 0;
+ fmask = 0;
+ reg_offset = 0;
need_aligned_p = 0;
+ args_size = 0;
+ if (!leaf_function_p ())
+ {
+ /* Also include the size needed for the 6 parameter registers. */
+ args_size = current_function_outgoing_args_size + 24;
+ }
+ total_size = var_size + args_size;
+
/* Calculate space needed for gp registers. */
for (regno = 1; regno <= 31; regno++)
{
@@ -5690,9 +5693,13 @@ sparc_flat_compute_frame_size (size)
total_size += gp_reg_size + fp_reg_size;
}
- /* ??? This looks a little suspicious. Clarify. */
- if (total_size == extra_size)
- total_size = extra_size = 0;
+ /* If we must allocate a stack frame at all, we must also allocate
+ room for register window spillage, so as to be binary compatible
+ with libraries and operating systems that do not use -mflat. */
+ if (total_size > 0)
+ total_size += extra_size;
+ else
+ extra_size = 0;
total_size = SPARC_STACK_ALIGN (total_size);
@@ -5869,7 +5876,7 @@ sparc_flat_output_function_prologue (file, size)
{
unsigned int reg_offset = current_frame_info.reg_offset;
char *fp_str = reg_names[FRAME_POINTER_REGNUM];
- char *t1_str = "%g1";
+ const char *t1_str = "%g1";
/* Things get a little tricky if local variables take up more than ~4096
bytes and outgoing arguments take up more than ~4096 bytes. When that
@@ -6048,7 +6055,7 @@ sparc_flat_output_function_epilogue (file, size)
unsigned int size1;
char *sp_str = reg_names[STACK_POINTER_REGNUM];
char *fp_str = reg_names[FRAME_POINTER_REGNUM];
- char *t1_str = "%g1";
+ const char *t1_str = "%g1";
/* In the reload sequence, we don't need to fill the load delay
slots for most of the loads, also see if we can fill the final
@@ -6196,7 +6203,7 @@ sparc_flat_eligible_for_epilogue_delay (trial, slot)
/* Adjust the cost of a scheduling dependency. Return the new cost of
a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
-int
+static int
supersparc_adjust_cost (insn, link, dep_insn, cost)
rtx insn;
rtx link;
@@ -6261,6 +6268,263 @@ supersparc_adjust_cost (insn, link, dep_insn, cost)
return cost;
}
+static int
+hypersparc_adjust_cost (insn, link, dep_insn, cost)
+ rtx insn;
+ rtx link;
+ rtx dep_insn;
+ int cost;
+{
+ enum attr_type insn_type, dep_type;
+ rtx pat = PATTERN(insn);
+ rtx dep_pat = PATTERN (dep_insn);
+
+ if (recog_memoized (insn) < 0 || recog_memoized (dep_insn) < 0)
+ return cost;
+
+ insn_type = get_attr_type (insn);
+ dep_type = get_attr_type (dep_insn);
+
+ switch (REG_NOTE_KIND (link))
+ {
+ case 0:
+ /* Data dependency; DEP_INSN writes a register that INSN reads some
+ cycles later. */
+
+ switch (insn_type)
+ {
+ case TYPE_STORE:
+ case TYPE_FPSTORE:
+ /* Get the delay iff the address of the store is the dependence. */
+ if (GET_CODE (pat) != SET || GET_CODE (dep_pat) != SET)
+ return cost;
+
+ if (rtx_equal_p (SET_DEST (dep_pat), SET_SRC (pat)))
+ return cost;
+ return cost + 3;
+
+ case TYPE_LOAD:
+ case TYPE_SLOAD:
+ case TYPE_FPLOAD:
+ /* If a load, then the dependence must be on the memory address. If
+ the addresses aren't equal, then it might be a false dependency */
+ if (dep_type == TYPE_STORE || dep_type == TYPE_FPSTORE)
+ {
+ if (GET_CODE (pat) != SET || GET_CODE (dep_pat) != SET
+ || GET_CODE (SET_DEST (dep_pat)) != MEM
+ || GET_CODE (SET_SRC (pat)) != MEM
+ || ! rtx_equal_p (XEXP (SET_DEST (dep_pat), 0),
+ XEXP (SET_SRC (pat), 0)))
+ return cost + 2;
+
+ return cost + 8;
+ }
+ break;
+
+ case TYPE_BRANCH:
+ /* Compare to branch latency is 0. There is no benefit from
+ separating compare and branch. */
+ if (dep_type == TYPE_COMPARE)
+ return 0;
+ /* Floating point compare to branch latency is less than
+ compare to conditional move. */
+ if (dep_type == TYPE_FPCMP)
+ return cost - 1;
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case REG_DEP_ANTI:
+ /* Anti-dependencies only penalize the fpu unit. */
+ if (insn_type == TYPE_IALU || insn_type == TYPE_SHIFT)
+ return 0;
+ break;
+
+ default:
+ break;
+ }
+
+ return cost;
+}
+
+static int
+ultrasparc_adjust_cost (insn, link, dep_insn, cost)
+ rtx insn;
+ rtx link;
+ rtx dep_insn;
+ int cost;
+{
+ enum attr_type insn_type, dep_type;
+ rtx pat = PATTERN(insn);
+ rtx dep_pat = PATTERN (dep_insn);
+
+ if (recog_memoized (insn) < 0 || recog_memoized (dep_insn) < 0)
+ return cost;
+
+ insn_type = get_attr_type (insn);
+ dep_type = get_attr_type (dep_insn);
+
+ /* Nothing issues in parallel with integer multiplies, so
+ mark as zero cost since the scheduler can not do anything
+ about it. */
+ if (insn_type == TYPE_IMUL)
+ return 0;
+
+#define SLOW_FP(dep_type) \
+(dep_type == TYPE_FPSQRT || dep_type == TYPE_FPDIVS || dep_type == TYPE_FPDIVD)
+
+ switch (REG_NOTE_KIND (link))
+ {
+ case 0:
+ /* Data dependency; DEP_INSN writes a register that INSN reads some
+ cycles later. */
+
+ if (dep_type == TYPE_CMOVE)
+ {
+ /* Instructions that read the result of conditional moves cannot
+ be in the same group or the following group. */
+ return cost + 1;
+ }
+
+ switch (insn_type)
+ {
+ /* UltraSPARC can dual issue a store and an instruction setting
+ the value stored, except for divide and square root. */
+ case TYPE_FPSTORE:
+ if (! SLOW_FP (dep_type))
+ return 0;
+ return cost;
+
+ case TYPE_STORE:
+ if (GET_CODE (pat) != SET || GET_CODE (dep_pat) != SET)
+ return cost;
+
+ if (rtx_equal_p (SET_DEST (dep_pat), SET_SRC (pat)))
+ /* The dependency between the two instructions is on the data
+ that is being stored. Assume that the address of the store
+ is not also dependent. */
+ return 0;
+ return cost;
+
+ case TYPE_LOAD:
+ case TYPE_SLOAD:
+ case TYPE_FPLOAD:
+ /* A load does not return data until at least 11 cycles after
+ a store to the same location. 3 cycles are accounted for
+ in the load latency; add the other 8 here. */
+ if (dep_type == TYPE_STORE || dep_type == TYPE_FPSTORE)
+ {
+ /* If the addresses are not equal this may be a false
+ dependency because pointer aliasing could not be
+ determined. Add only 2 cycles in that case. 2 is
+ an arbitrary compromise between 8, which would cause
+ the scheduler to generate worse code elsewhere to
+ compensate for a dependency which might not really
+ exist, and 0. */
+ if (GET_CODE (pat) != SET || GET_CODE (dep_pat) != SET
+ || GET_CODE (SET_SRC (pat)) != MEM
+ || GET_CODE (SET_DEST (dep_pat)) != MEM
+ || ! rtx_equal_p (XEXP (SET_SRC (pat), 0),
+ XEXP (SET_DEST (dep_pat), 0)))
+ return cost + 2;
+
+ return cost + 8;
+ }
+ return cost;
+
+ case TYPE_BRANCH:
+ /* Compare to branch latency is 0. There is no benefit from
+ separating compare and branch. */
+ if (dep_type == TYPE_COMPARE)
+ return 0;
+ /* Floating point compare to branch latency is less than
+ compare to conditional move. */
+ if (dep_type == TYPE_FPCMP)
+ return cost - 1;
+ return cost;
+
+ case TYPE_FPCMOVE:
+ /* FMOVR class instructions can not issue in the same cycle
+ or the cycle after an instruction which writes any
+ integer register. Model this as cost 2 for dependent
+ instructions. */
+ if ((dep_type == TYPE_IALU || dep_type == TYPE_UNARY
+ || dep_type == TYPE_BINARY)
+ && cost < 2)
+ return 2;
+ /* Otherwise check as for integer conditional moves. */
+
+ case TYPE_CMOVE:
+ /* Conditional moves involving integer registers wait until
+ 3 cycles after loads return data. The interlock applies
+ to all loads, not just dependent loads, but that is hard
+ to model. */
+ if (dep_type == TYPE_LOAD || dep_type == TYPE_SLOAD)
+ return cost + 3;
+ return cost;
+
+ default:
+ break;
+ }
+ break;
+
+ case REG_DEP_ANTI:
+ /* Divide and square root lock destination registers for full latency. */
+ if (! SLOW_FP (dep_type))
+ return 0;
+ break;
+
+ case REG_DEP_OUTPUT:
+ /* IEU and FPU instruction that have the same destination
+ register cannot be grouped together. */
+ return cost + 1;
+
+ default:
+ break;
+ }
+
+ /* Other costs not accounted for:
+ - Single precision floating point loads lock the other half of
+ the even/odd register pair.
+ - Several hazards associated with ldd/std are ignored because these
+ instructions are rarely generated for V9.
+ - The floating point pipeline can not have both a single and double
+ precision operation active at the same time. Format conversions
+ and graphics instructions are given honorary double precision status.
+ - call and jmpl are always the first instruction in a group. */
+
+ return cost;
+
+#undef SLOW_FP
+}
+
+int
+sparc_adjust_cost(insn, link, dep, cost)
+ rtx insn;
+ rtx link;
+ rtx dep;
+ int cost;
+{
+ switch (sparc_cpu)
+ {
+ case PROCESSOR_SUPERSPARC:
+ cost = supersparc_adjust_cost (insn, link, dep, cost);
+ break;
+ case PROCESSOR_HYPERSPARC:
+ case PROCESSOR_SPARCLITE86X:
+ cost = hypersparc_adjust_cost (insn, link, dep, cost);
+ break;
+ case PROCESSOR_ULTRASPARC:
+ cost = ultrasparc_adjust_cost (insn, link, dep, cost);
+ break;
+ default:
+ break;
+ }
+ return cost;
+}
+
/* This describes the state of the UltraSPARC pipeline during
instruction scheduling. */
@@ -6278,7 +6542,7 @@ enum ultra_code { NONE=0, /* no insn at all */
SINGLE, /* single issue instructions */
NUM_ULTRA_CODES };
-static char *ultra_code_names[NUM_ULTRA_CODES] = {
+static const char *ultra_code_names[NUM_ULTRA_CODES] = {
"NONE", "IEU0", "IEU1", "IEUN", "LSU", "CTI",
"FPM", "FPA", "SINGLE" };
@@ -6992,155 +7256,6 @@ ultrasparc_sched_reorder (dump, sched_verbose, ready, n_ready)
}
}
-int
-ultrasparc_adjust_cost (insn, link, dep_insn, cost)
- rtx insn;
- rtx link;
- rtx dep_insn;
- int cost;
-{
- enum attr_type insn_type, dep_type;
- rtx pat = PATTERN(insn);
- rtx dep_pat = PATTERN (dep_insn);
-
- if (recog_memoized (insn) < 0 || recog_memoized (dep_insn) < 0)
- return cost;
-
- insn_type = get_attr_type (insn);
- dep_type = get_attr_type (dep_insn);
-
- /* Nothing issues in parallel with integer multiplies, so
- mark as zero cost since the scheduler can not do anything
- about it. */
- if (insn_type == TYPE_IMUL)
- return 0;
-
-#define SLOW_FP(dep_type) \
-(dep_type == TYPE_FPSQRT || dep_type == TYPE_FPDIVS || dep_type == TYPE_FPDIVD)
-
- switch (REG_NOTE_KIND (link))
- {
- case 0:
- /* Data dependency; DEP_INSN writes a register that INSN reads some
- cycles later. */
-
- if (dep_type == TYPE_CMOVE)
- {
- /* Instructions that read the result of conditional moves cannot
- be in the same group or the following group. */
- return cost + 1;
- }
-
- switch (insn_type)
- {
- /* UltraSPARC can dual issue a store and an instruction setting
- the value stored, except for divide and square root. */
- case TYPE_FPSTORE:
- if (! SLOW_FP (dep_type))
- return 0;
- return cost;
-
- case TYPE_STORE:
- if (GET_CODE (pat) != SET || GET_CODE (dep_pat) != SET)
- return cost;
-
- if (rtx_equal_p (SET_DEST (dep_pat), SET_SRC (pat)))
- /* The dependency between the two instructions is on the data
- that is being stored. Assume that the address of the store
- is not also dependent. */
- return 0;
- return cost;
-
- case TYPE_LOAD:
- case TYPE_SLOAD:
- case TYPE_FPLOAD:
- /* A load does not return data until at least 11 cycles after
- a store to the same location. 3 cycles are accounted for
- in the load latency; add the other 8 here. */
- if (dep_type == TYPE_STORE || dep_type == TYPE_FPSTORE)
- {
- /* If the addresses are not equal this may be a false
- dependency because pointer aliasing could not be
- determined. Add only 2 cycles in that case. 2 is
- an arbitrary compromise between 8, which would cause
- the scheduler to generate worse code elsewhere to
- compensate for a dependency which might not really
- exist, and 0. */
- if (GET_CODE (pat) != SET || GET_CODE (dep_pat) != SET
- || GET_CODE (SET_SRC (pat)) != MEM
- || GET_CODE (SET_DEST (dep_pat)) != MEM
- || ! rtx_equal_p (XEXP (SET_SRC (pat), 0),
- XEXP (SET_DEST (dep_pat), 0)))
- return cost + 2;
-
- return cost + 8;
- }
- return cost;
-
- case TYPE_BRANCH:
- /* Compare to branch latency is 0. There is no benefit from
- separating compare and branch. */
- if (dep_type == TYPE_COMPARE)
- return 0;
- /* Floating point compare to branch latency is less than
- compare to conditional move. */
- if (dep_type == TYPE_FPCMP)
- return cost - 1;
- return cost;
-
- case TYPE_FPCMOVE:
- /* FMOVR class instructions can not issue in the same cycle
- or the cycle after an instruction which writes any
- integer register. Model this as cost 2 for dependent
- instructions. */
- if ((dep_type == TYPE_IALU || dep_type == TYPE_UNARY
- || dep_type == TYPE_BINARY)
- && cost < 2)
- return 2;
- /* Otherwise check as for integer conditional moves. */
-
- case TYPE_CMOVE:
- /* Conditional moves involving integer registers wait until
- 3 cycles after loads return data. The interlock applies
- to all loads, not just dependent loads, but that is hard
- to model. */
- if (dep_type == TYPE_LOAD || dep_type == TYPE_SLOAD)
- return cost + 3;
- return cost;
-
- default:
- break;
- }
- break;
-
- case REG_DEP_ANTI:
- /* Divide and square root lock destination registers for full latency. */
- if (! SLOW_FP (dep_type))
- return 0;
- break;
-
- case REG_DEP_OUTPUT:
- /* IEU and FPU instruction that have the same destination
- register cannot be grouped together. */
- return cost + 1;
-
- default:
- break;
- }
-
- /* Other costs not accounted for:
- - Single precision floating point loads lock the other half of
- the even/odd register pair.
- - Several hazards associated with ldd/std are ignored because these
- instructions are rarely generated for V9.
- - The floating point pipeline can not have both a single and double
- precision operation active at the same time. Format conversions
- and graphics instructions are given honorary double precision status.
- - call and jmpl are always the first instruction in a group. */
-
- return cost;
-}
-
int
sparc_issue_rate ()
{
@@ -7153,6 +7268,9 @@ sparc_issue_rate ()
return 2;
case PROCESSOR_SUPERSPARC:
return 3;
+ case PROCESSOR_HYPERSPARC:
+ case PROCESSOR_SPARCLITE86X:
+ return 2;
case PROCESSOR_ULTRASPARC:
return 4;
}
diff --git a/gcc/config/sparc/sparc.h b/gcc/config/sparc/sparc.h
index 177c3327adb..b37b5e9eef5 100644
--- a/gcc/config/sparc/sparc.h
+++ b/gcc/config/sparc/sparc.h
@@ -1,5 +1,5 @@
/* Definitions of target machine for GNU compiler, for Sun SPARC.
- Copyright (C) 1987, 88, 89, 92, 94-97, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1987, 88, 89, 92, 94-98, 1999 Free Software Foundation, Inc.
Contributed by Michael Tiemann (tiemann@cygnus.com).
64 bit SPARC V9 support by Michael Tiemann, Jim Wilson, and Doug Evans,
at Cygnus Support.
@@ -87,7 +87,7 @@ enum cmodel {
};
/* Value of -mcmodel specified by user. */
-extern char *sparc_cmodel_string;
+extern const char *sparc_cmodel_string;
/* One of CM_FOO. */
extern enum cmodel sparc_cmodel;
@@ -106,18 +106,24 @@ extern enum cmodel sparc_cmodel;
/* Values of TARGET_CPU_DEFAULT, set via -D in the Makefile,
and specified by the user via --with-cpu=foo.
This specifies the cpu implementation, not the architecture size. */
+/* Note that TARGET_CPU_v9 is assumed to start the list of 64-bit
+ capable cpu's. */
#define TARGET_CPU_sparc 0
#define TARGET_CPU_v7 0 /* alias for previous */
#define TARGET_CPU_sparclet 1
#define TARGET_CPU_sparclite 2
#define TARGET_CPU_v8 3 /* generic v8 implementation */
#define TARGET_CPU_supersparc 4
-#define TARGET_CPU_v9 5 /* generic v9 implementation */
-#define TARGET_CPU_sparcv9 5 /* alias */
-#define TARGET_CPU_sparc64 5 /* alias */
-#define TARGET_CPU_ultrasparc 6
+#define TARGET_CPU_hypersparc 5
+#define TARGET_CPU_sparc86x 6
+#define TARGET_CPU_sparclite86x 6
+#define TARGET_CPU_v9 7 /* generic v9 implementation */
+#define TARGET_CPU_sparcv9 7 /* alias */
+#define TARGET_CPU_sparc64 7 /* alias */
+#define TARGET_CPU_ultrasparc 8
-#if TARGET_CPU_DEFAULT == TARGET_CPU_v9 || TARGET_CPU_DEFAULT == TARGET_CPU_ultrasparc
+#if TARGET_CPU_DEFAULT == TARGET_CPU_v9 \
+ || TARGET_CPU_DEFAULT == TARGET_CPU_ultrasparc
#define CPP_CPU32_DEFAULT_SPEC ""
#define ASM_CPU32_DEFAULT_SPEC ""
@@ -140,19 +146,37 @@ extern enum cmodel sparc_cmodel;
#define CPP_CPU64_DEFAULT_SPEC ""
#define ASM_CPU64_DEFAULT_SPEC ""
-#if TARGET_CPU_DEFAULT == TARGET_CPU_sparc || TARGET_CPU_DEFAULT == TARGET_CPU_v8 || TARGET_CPU_DEFAULT == TARGET_CPU_supersparc
+#if TARGET_CPU_DEFAULT == TARGET_CPU_sparc \
+ || TARGET_CPU_DEFAULT == TARGET_CPU_v8
#define CPP_CPU32_DEFAULT_SPEC ""
#define ASM_CPU32_DEFAULT_SPEC ""
#endif
+
#if TARGET_CPU_DEFAULT == TARGET_CPU_sparclet
#define CPP_CPU32_DEFAULT_SPEC "-D__sparclet__"
#define ASM_CPU32_DEFAULT_SPEC "-Asparclet"
#endif
+
#if TARGET_CPU_DEFAULT == TARGET_CPU_sparclite
#define CPP_CPU32_DEFAULT_SPEC "-D__sparclite__"
#define ASM_CPU32_DEFAULT_SPEC "-Asparclite"
#endif
+#if TARGET_CPU_DEFAULT == TARGET_CPU_supersparc
+#define CPP_CPU32_DEFAULT_SPEC "-D__supersparc__ -D__sparc_v8__"
+#define ASM_CPU32_DEFAULT_SPEC ""
+#endif
+
+#if TARGET_CPU_DEFAULT == TARGET_CPU_hypersparc
+#define CPP_CPU32_DEFAULT_SPEC "-D__hypersparc__ -D__sparc_v8__"
+#define ASM_CPU32_DEFAULT_SPEC ""
+#endif
+
+#if TARGET_CPU_DEFAULT == TARGET_CPU_sparclite86x
+#define CPP_CPU32_DEFAULT_SPEC "-D__sparclite86x__ -D__sparc_v8__"
+#define ASM_CPU32_DEFAULT_SPEC "-Av8"
+#endif
+
#endif
#if !defined(CPP_CPU32_DEFAULT_SPEC) || !defined(CPP_CPU64_DEFAULT_SPEC)
@@ -208,6 +232,8 @@ Unrecognized value in TARGET_CPU_DEFAULT.
%{mcpu=f930:-D__sparclite__} %{mcpu=f934:-D__sparclite__} \
%{mcpu=v8:-D__sparc_v8__} \
%{mcpu=supersparc:-D__supersparc__ -D__sparc_v8__} \
+%{mcpu=hypersparc:-D__hypersparc__ -D__sparc_v8__} \
+%{mcpu=sparclite86x:-D__sparclite86x__ -D__sparc_v8__} \
%{mcpu=v9:-D__sparc_v9__} \
%{mcpu=ultrasparc:-D__sparc_v9__} \
%{!mcpu*:%{!mcypress:%{!msparclite:%{!mf930:%{!mf934:%{!mv8:%{!msupersparc:%(cpp_cpu_default)}}}}}}} \
@@ -243,7 +269,9 @@ Unrecognized value in TARGET_CPU_DEFAULT.
"
/* Macros to distinguish endianness. */
-#define CPP_ENDIAN_SPEC "%{mlittle-endian:-D__LITTLE_ENDIAN__}"
+#define CPP_ENDIAN_SPEC "\
+%{mlittle-endian:-D__LITTLE_ENDIAN__} \
+%{mlittle-endian-data:-D__LITTLE_ENDIAN_DATA__}"
/* Macros to distinguish the particular subtarget. */
#define CPP_SUBTARGET_SPEC ""
@@ -316,20 +344,20 @@ Unrecognized value in TARGET_CPU_DEFAULT.
Do not define this macro if it does not need to do anything. */
#define EXTRA_SPECS \
- { "cpp_cpu", CPP_CPU_SPEC }, \
- { "cpp_cpu_default", CPP_CPU_DEFAULT_SPEC }, \
- { "cpp_arch32", CPP_ARCH32_SPEC }, \
- { "cpp_arch64", CPP_ARCH64_SPEC }, \
- { "cpp_arch_default", CPP_ARCH_DEFAULT_SPEC }, \
- { "cpp_arch", CPP_ARCH_SPEC }, \
- { "cpp_endian", CPP_ENDIAN_SPEC }, \
- { "cpp_subtarget", CPP_SUBTARGET_SPEC }, \
- { "asm_cpu", ASM_CPU_SPEC }, \
- { "asm_cpu_default", ASM_CPU_DEFAULT_SPEC }, \
- { "asm_arch32", ASM_ARCH32_SPEC }, \
- { "asm_arch64", ASM_ARCH64_SPEC }, \
- { "asm_arch_default", ASM_ARCH_DEFAULT_SPEC }, \
- { "asm_arch", ASM_ARCH_SPEC }, \
+ { "cpp_cpu", CPP_CPU_SPEC }, \
+ { "cpp_cpu_default", CPP_CPU_DEFAULT_SPEC }, \
+ { "cpp_arch32", CPP_ARCH32_SPEC }, \
+ { "cpp_arch64", CPP_ARCH64_SPEC }, \
+ { "cpp_arch_default", CPP_ARCH_DEFAULT_SPEC },\
+ { "cpp_arch", CPP_ARCH_SPEC }, \
+ { "cpp_endian", CPP_ENDIAN_SPEC }, \
+ { "cpp_subtarget", CPP_SUBTARGET_SPEC }, \
+ { "asm_cpu", ASM_CPU_SPEC }, \
+ { "asm_cpu_default", ASM_CPU_DEFAULT_SPEC }, \
+ { "asm_arch32", ASM_ARCH32_SPEC }, \
+ { "asm_arch64", ASM_ARCH64_SPEC }, \
+ { "asm_arch_default", ASM_ARCH_DEFAULT_SPEC },\
+ { "asm_arch", ASM_ARCH_SPEC }, \
SUBTARGET_EXTRA_SPECS
#define SUBTARGET_EXTRA_SPECS
@@ -361,7 +389,7 @@ void sparc_override_options ();
{ \
if (flag_pic) \
{ \
- char *pic_string = (flag_pic == 1) ? "-fpic" : "-fPIC"; \
+ const char *pic_string = (flag_pic == 1) ? "-fpic" : "-fPIC";\
warning ("%s and profiling conflict: disabling %s", \
pic_string, pic_string); \
flag_pic = 0; \
@@ -541,44 +569,44 @@ extern int target_flags;
An empty string NAME is used to identify the default VALUE. */
#define TARGET_SWITCHES \
- { {"fpu", MASK_FPU | MASK_FPU_SET}, \
- {"no-fpu", -MASK_FPU}, \
- {"no-fpu", MASK_FPU_SET}, \
- {"hard-float", MASK_FPU | MASK_FPU_SET}, \
- {"soft-float", -MASK_FPU}, \
- {"soft-float", MASK_FPU_SET}, \
- {"epilogue", MASK_EPILOGUE}, \
- {"no-epilogue", -MASK_EPILOGUE}, \
- {"unaligned-doubles", MASK_UNALIGNED_DOUBLES}, \
- {"no-unaligned-doubles", -MASK_UNALIGNED_DOUBLES}, \
- {"impure-text", MASK_IMPURE_TEXT}, \
- {"no-impure-text", -MASK_IMPURE_TEXT}, \
- {"flat", MASK_FLAT}, \
- {"no-flat", -MASK_FLAT}, \
- {"app-regs", MASK_APP_REGS}, \
- {"no-app-regs", -MASK_APP_REGS}, \
- {"hard-quad-float", MASK_HARD_QUAD}, \
- {"soft-quad-float", -MASK_HARD_QUAD}, \
- {"v8plus", MASK_V8PLUS}, \
- {"no-v8plus", -MASK_V8PLUS}, \
- {"vis", MASK_VIS}, \
- {"no-vis", -MASK_VIS}, \
+ { {"fpu", MASK_FPU | MASK_FPU_SET, "Use hardware fp" }, \
+ {"no-fpu", -MASK_FPU, "Do not use hardware fp" }, \
+ {"no-fpu", MASK_FPU_SET, "Do not use hardware fp" }, \
+ {"hard-float", MASK_FPU | MASK_FPU_SET, "Use hardware fp" }, \
+ {"soft-float", -MASK_FPU, "Do not use hardware fp" }, \
+ {"soft-float", MASK_FPU_SET, "Do not use hardware fp" }, \
+ {"epilogue", MASK_EPILOGUE, "Use FUNCTION_EPILOGUE" }, \
+ {"no-epilogue", -MASK_EPILOGUE, "Do not use FUNCTION_EPILOGUE" }, \
+ {"unaligned-doubles", MASK_UNALIGNED_DOUBLES, "Assume possible double misalignment" },\
+ {"no-unaligned-doubles", -MASK_UNALIGNED_DOUBLES, "Assume all doubles are aligned" }, \
+ {"impure-text", MASK_IMPURE_TEXT, "Pass -assert pure-text to linker" }, \
+ {"no-impure-text", -MASK_IMPURE_TEXT, "Do not pass -assert pure-text to linker" }, \
+ {"flat", MASK_FLAT, "Use flat register window model" }, \
+ {"no-flat", -MASK_FLAT, "Do not use flat register window model" }, \
+ {"app-regs", MASK_APP_REGS, "Use ABI reserved registers" }, \
+ {"no-app-regs", -MASK_APP_REGS, "Do not use ABI reserved registers" }, \
+ {"hard-quad-float", MASK_HARD_QUAD, "Use hardware quad fp instructions" }, \
+ {"soft-quad-float", -MASK_HARD_QUAD, "Do not use hardware quad fp instructions" }, \
+ {"v8plus", MASK_V8PLUS, "Compile for v8plus ABI" }, \
+ {"no-v8plus", -MASK_V8PLUS, "Do not compile for v8plus ABI" }, \
+ {"vis", MASK_VIS, "Utilize Visual Instruction Set" }, \
+ {"no-vis", -MASK_VIS, "Do not utilize Visual Instruction Set" }, \
/* ??? These are deprecated, coerced to -mcpu=. Delete in 2.9. */ \
- {"cypress", 0}, \
- {"sparclite", 0}, \
- {"f930", 0}, \
- {"f934", 0}, \
- {"v8", 0}, \
- {"supersparc", 0}, \
+ {"cypress", 0, "Optimize for Cypress processors" }, \
+ {"sparclite", 0, "Optimize for SparcLite processors" }, \
+ {"f930", 0, "Optimize for F930 processors" }, \
+ {"f934", 0, "Optimize for F934 processors" }, \
+ {"v8", 0, "Use V8 Sparc ISA" }, \
+ {"supersparc", 0, "Optimize for SuperSparc processors" }, \
/* End of deprecated options. */ \
- {"ptr64", MASK_PTR64}, \
- {"ptr32", -MASK_PTR64}, \
- {"32", -MASK_64BIT}, \
- {"64", MASK_64BIT}, \
- {"stack-bias", MASK_STACK_BIAS}, \
- {"no-stack-bias", -MASK_STACK_BIAS}, \
+ {"ptr64", MASK_PTR64, "Pointers are 64-bit" }, \
+ {"ptr32", -MASK_PTR64, "Pointers are 32-bit" }, \
+ {"32", -MASK_64BIT, "Use 32-bit ABI" }, \
+ {"64", MASK_64BIT, "Use 64-bit ABI" }, \
+ {"stack-bias", MASK_STACK_BIAS, "Use stack bias" }, \
+ {"no-stack-bias", -MASK_STACK_BIAS, "Do not use stack bias" }, \
SUBTARGET_SWITCHES \
- { "", TARGET_DEFAULT}}
+ { "", TARGET_DEFAULT, ""}}
/* MASK_APP_REGS must always be the default because that's what
FIXED_REGISTERS is set to and -ffixed- is processed before
@@ -598,6 +626,8 @@ enum processor_type {
PROCESSOR_SPARCLITE,
PROCESSOR_F930,
PROCESSOR_F934,
+ PROCESSOR_HYPERSPARC,
+ PROCESSOR_SPARCLITE86X,
PROCESSOR_SPARCLET,
PROCESSOR_TSC701,
PROCESSOR_V9,
@@ -630,12 +660,12 @@ extern enum processor_type sparc_cpu;
#define TARGET_OPTIONS \
{ \
- { "cpu=", &sparc_select[1].string }, \
- { "tune=", &sparc_select[2].string }, \
- { "cmodel=", &sparc_cmodel_string }, \
- { "align-loops=", &sparc_align_loops_string }, \
- { "align-jumps=", &sparc_align_jumps_string }, \
- { "align-functions=", &sparc_align_funcs_string }, \
+ { "cpu=", &sparc_select[1].string, "Use features of and schedule code for given CPU" }, \
+ { "tune=", &sparc_select[2].string, "Schedule code for given CPU" }, \
+ { "cmodel=", &sparc_cmodel_string, "Use given Sparc code model" }, \
+ { "align-loops=", &sparc_align_loops_string, "Loop code aligned to this power of 2" }, \
+ { "align-jumps=", &sparc_align_jumps_string, "Jump targets are aligned to this power of 2" }, \
+ { "align-functions=", &sparc_align_funcs_string, "Function starts are aligned to this power of 2" }, \
SUBTARGET_OPTIONS \
}
@@ -645,8 +675,8 @@ extern enum processor_type sparc_cpu;
/* sparc_select[0] is reserved for the default cpu. */
struct sparc_cpu_select
{
- char *string;
- char *name;
+ const char *string;
+ const char *name;
int set_tune_p;
int set_arch_p;
};
@@ -654,9 +684,9 @@ struct sparc_cpu_select
extern struct sparc_cpu_select sparc_select[];
/* Variables to record values the user passes. */
-extern char *sparc_align_loops_string;
-extern char *sparc_align_jumps_string;
-extern char *sparc_align_funcs_string;
+extern const char *sparc_align_loops_string;
+extern const char *sparc_align_jumps_string;
+extern const char *sparc_align_funcs_string;
/* Parsed values as a power of two. */
extern int sparc_align_loops;
extern int sparc_align_jumps;
@@ -684,7 +714,7 @@ extern int sparc_align_funcs;
/* Define this to set the endianness to use in libgcc2.c, which can
not depend on target_flags. */
-#if defined (__LITTLE_ENDIAN__)
+#if defined (__LITTLE_ENDIAN__) || defined(__LITTLE_ENDIAN_DATA__)
#define LIBGCC2_WORDS_BIG_ENDIAN 0
#else
#define LIBGCC2_WORDS_BIG_ENDIAN 1
@@ -973,6 +1003,11 @@ if (TARGET_ARCH64 \
#define CONDITIONAL_REGISTER_USAGE \
do \
{ \
+ if (flag_pic) \
+ { \
+ fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \
+ call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \
+ } \
if (TARGET_ARCH32) \
{ \
fixed_regs[5] = 1; \
@@ -1410,15 +1445,23 @@ extern char leaf_reg_remap[];
in class CLASS, return the class of reg to actually use.
In general this is just CLASS; but on some machines
in some cases it is preferable to use a more restrictive class. */
-/* We can't load constants into FP registers. We can't load any FP constant
- if an 'E' constraint fails to match it. */
+/* - We can't load constants into FP registers. We can't load any FP
+ constant if an 'E' constraint fails to match it.
+ - Try and reload integer constants (symbolic or otherwise) back into
+ registers directly, rather than having them dumped to memory. */
+
#define PREFERRED_RELOAD_CLASS(X,CLASS) \
(CONSTANT_P (X) \
- && (FP_REG_CLASS_P (CLASS) \
+ ? ((FP_REG_CLASS_P (CLASS) \
|| (GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT \
&& (HOST_FLOAT_FORMAT != IEEE_FLOAT_FORMAT \
|| HOST_BITS_PER_INT != BITS_PER_WORD))) \
- ? NO_REGS : (CLASS))
+ ? NO_REGS \
+ : (!FP_REG_CLASS_P (CLASS) \
+ && GET_MODE_CLASS (GET_MODE (X)) == MODE_INT) \
+ ? GENERAL_REGS \
+ : (CLASS)) \
+ : (CLASS))
/* Return the register class of a scratch register needed to load IN into
a register of class CLASS in MODE.
@@ -2271,11 +2314,11 @@ extern struct rtx_def *sparc_builtin_saveregs ();
/* Addressing modes, and classification of registers for them. */
-/* #define HAVE_POST_INCREMENT */
-/* #define HAVE_POST_DECREMENT */
+/* #define HAVE_POST_INCREMENT 0 */
+/* #define HAVE_POST_DECREMENT 0 */
-/* #define HAVE_PRE_DECREMENT */
-/* #define HAVE_PRE_INCREMENT */
+/* #define HAVE_PRE_DECREMENT 0 */
+/* #define HAVE_PRE_INCREMENT 0 */
/* Macros to check register numbers against specific register classes. */
@@ -2515,6 +2558,33 @@ extern struct rtx_def *legitimize_pic_address ();
if (memory_address_p (MODE, X)) \
goto WIN; }
+/* Try a machine-dependent way of reloading an illegitimate address
+ operand. If we find one, push the reload and jump to WIN. This
+ macro is used in only one place: `find_reloads_address' in reload.c.
+
+ For Sparc 32, we wish to handle addresses by splitting them into
+ HIGH+LO_SUM pairs, retaining the LO_SUM in the memory reference.
+ This cuts the number of extra insns by one. */
+
+#define LEGITIMIZE_RELOAD_ADDRESS(X,MODE,OPNUM,TYPE,IND_LEVELS,WIN) \
+do { \
+ /* Decompose SImode constants into hi+lo_sum. We do have to \
+ rerecognize what we produce, so be careful. */ \
+ if (CONSTANT_P (X) \
+ && (MODE != TFmode || TARGET_V9) \
+ && GET_MODE (X) == SImode \
+ && GET_CODE (X) != LO_SUM && GET_CODE (X) != HIGH) \
+ { \
+ X = gen_rtx_LO_SUM (GET_MODE (X), \
+ gen_rtx_HIGH (GET_MODE (X), X), X); \
+ push_reload (XEXP (X, 0), NULL_RTX, &XEXP (X, 0), NULL_PTR, \
+ BASE_REG_CLASS, GET_MODE (X), VOIDmode, 0, 0, \
+ OPNUM, TYPE); \
+ goto WIN; \
+ } \
+ /* ??? 64-bit reloads. */ \
+} while (0)
+
/* Go to LABEL if ADDR (a legitimate address expression)
has an effect that depends on the machine mode it is used for.
On the SPARC this is never true. */
@@ -2803,12 +2873,8 @@ extern struct rtx_def *legitimize_pic_address ();
#define ISSUE_RATE sparc_issue_rate()
/* Adjust the cost of dependencies. */
-#define ADJUST_COST(INSN,LINK,DEP,COST) \
- if (sparc_cpu == PROCESSOR_SUPERSPARC) \
- (COST) = supersparc_adjust_cost (INSN, LINK, DEP, COST); \
- else if (sparc_cpu == PROCESSOR_ULTRASPARC) \
- (COST) = ultrasparc_adjust_cost (INSN, LINK, DEP, COST); \
- else
+#define ADJUST_COST(INSN,LINK,DEP,COST) \
+ sparc_adjust_cost(INSN, LINK, DEP, COST)
extern void ultrasparc_sched_reorder ();
extern void ultrasparc_sched_init ();
@@ -3029,6 +3095,7 @@ extern int ultrasparc_variable_issue ();
/* This is how we hook in and defer the case-vector until the end of
the function. */
+extern void sparc_defer_case_vector ();
#define ASM_OUTPUT_ADDR_VEC(LAB,VEC) \
sparc_defer_case_vector ((LAB),(VEC), 0)
@@ -3275,50 +3342,49 @@ do { \
/* Define the codes that are matched by predicates in sparc.c. */
-#define PREDICATE_CODES \
-{"reg_or_0_operand", {SUBREG, REG, CONST_INT, CONST_DOUBLE}}, \
-{"fp_zero_operand", {CONST_DOUBLE}}, \
-{"intreg_operand", {SUBREG, REG}}, \
-{"fcc_reg_operand", {REG}}, \
-{"icc_or_fcc_reg_operand", {REG}}, \
-{"restore_operand", {REG}}, \
-{"call_operand", {MEM}}, \
-{"call_operand_address", {SYMBOL_REF, LABEL_REF, CONST, CONST_DOUBLE, ADDRESSOF, \
- SUBREG, REG, PLUS, LO_SUM, CONST_INT}}, \
-{"symbolic_operand", {SYMBOL_REF, LABEL_REF, CONST, CONST_DOUBLE}}, \
-{"symbolic_memory_operand", {SUBREG, MEM}}, \
-{"label_ref_operand", {LABEL_REF}}, \
-{"sp64_medium_pic_operand", {CONST}}, \
-{"data_segment_operand", {SYMBOL_REF, PLUS, CONST}}, \
-{"text_segment_operand", {LABEL_REF, SYMBOL_REF, PLUS, CONST}}, \
-{"reg_or_nonsymb_mem_operand", {SUBREG, REG, MEM}}, \
-{"splittable_symbolic_memory_operand", {MEM}}, \
-{"splittable_immediate_memory_operand", {MEM}}, \
-{"eq_or_neq", {EQ, NE}}, \
-{"normal_comp_operator", {GE, GT, LE, LT, GTU, LEU}}, \
-{"noov_compare_op", {NE, EQ, GE, GT, LE, LT, GEU, GTU, LEU, LTU}}, \
-{"v9_regcmp_op", {EQ, NE, GE, LT, LE, GT}}, \
-{"extend_op", {SIGN_EXTEND, ZERO_EXTEND}}, \
-{"cc_arithop", {AND, IOR, XOR}}, \
-{"cc_arithopn", {AND, IOR}}, \
-{"arith_operand", {SUBREG, REG, CONSTANT_P_RTX, CONST_INT}}, \
-{"arith_add_operand", {SUBREG, REG, CONSTANT_P_RTX, CONST_INT}}, \
-{"arith11_operand", {SUBREG, REG, CONSTANT_P_RTX, CONST_INT}}, \
-{"arith10_operand", {SUBREG, REG, CONSTANT_P_RTX, CONST_INT}}, \
-{"arith_double_operand", {SUBREG, REG, CONSTANT_P_RTX, CONST_INT, CONST_DOUBLE}}, \
-{"arith_double_add_operand", {SUBREG, REG, CONSTANT_P_RTX, CONST_INT, CONST_DOUBLE}},\
-{"arith11_double_operand", {SUBREG, REG, CONSTANT_P_RTX, CONST_INT, CONST_DOUBLE}}, \
-{"arith10_double_operand", {SUBREG, REG, CONSTANT_P_RTX, CONST_INT, CONST_DOUBLE}}, \
-{"small_int", {CONST_INT, CONSTANT_P_RTX}}, \
-{"small_int_or_double", {CONST_INT, CONST_DOUBLE, CONSTANT_P_RTX}}, \
-{"uns_small_int", {CONST_INT, CONSTANT_P_RTX}}, \
-{"uns_arith_operand", {SUBREG, REG, CONST_INT, CONSTANT_P_RTX}}, \
-{"clobbered_register", {REG}}, \
-{"input_operand", {SUBREG, REG, CONSTANT_P_RTX, CONST_INT, MEM}}, \
-{"zero_operand", {CONST_INT, CONSTANT_P_RTX}}, \
-{"const64_operand", {CONST_INT, CONST_DOUBLE, CONSTANT_P_RTX}}, \
-{"const64_high_operand", {CONST_INT, CONST_DOUBLE, CONSTANT_P_RTX}},
-
+#define PREDICATE_CODES \
+{"reg_or_0_operand", {SUBREG, REG, CONST_INT, CONST_DOUBLE}}, \
+{"fp_zero_operand", {CONST_DOUBLE}}, \
+{"intreg_operand", {SUBREG, REG}}, \
+{"fcc_reg_operand", {REG}}, \
+{"icc_or_fcc_reg_operand", {REG}}, \
+{"restore_operand", {REG}}, \
+{"call_operand", {MEM}}, \
+{"call_operand_address", {SYMBOL_REF, LABEL_REF, CONST, CONST_DOUBLE, \
+ ADDRESSOF, SUBREG, REG, PLUS, LO_SUM, CONST_INT}}, \
+{"symbolic_operand", {SYMBOL_REF, LABEL_REF, CONST, CONST_DOUBLE}}, \
+{"symbolic_memory_operand", {SUBREG, MEM}}, \
+{"label_ref_operand", {LABEL_REF}}, \
+{"sp64_medium_pic_operand", {CONST}}, \
+{"data_segment_operand", {SYMBOL_REF, PLUS, CONST}}, \
+{"text_segment_operand", {LABEL_REF, SYMBOL_REF, PLUS, CONST}}, \
+{"reg_or_nonsymb_mem_operand", {SUBREG, REG, MEM}}, \
+{"splittable_symbolic_memory_operand", {MEM}}, \
+{"splittable_immediate_memory_operand", {MEM}}, \
+{"eq_or_neq", {EQ, NE}}, \
+{"normal_comp_operator", {GE, GT, LE, LT, GTU, LEU}}, \
+{"noov_compare_op", {NE, EQ, GE, GT, LE, LT, GEU, GTU, LEU, LTU}}, \
+{"v9_regcmp_op", {EQ, NE, GE, LT, LE, GT}}, \
+{"extend_op", {SIGN_EXTEND, ZERO_EXTEND}}, \
+{"cc_arithop", {AND, IOR, XOR}}, \
+{"cc_arithopn", {AND, IOR}}, \
+{"arith_operand", {SUBREG, REG, CONST_INT}}, \
+{"arith_add_operand", {SUBREG, REG, CONST_INT}}, \
+{"arith11_operand", {SUBREG, REG, CONST_INT}}, \
+{"arith10_operand", {SUBREG, REG, CONST_INT}}, \
+{"arith_double_operand", {SUBREG, REG, CONST_INT, CONST_DOUBLE}}, \
+{"arith_double_add_operand", {SUBREG, REG, CONST_INT, CONST_DOUBLE}}, \
+{"arith11_double_operand", {SUBREG, REG, CONST_INT, CONST_DOUBLE}}, \
+{"arith10_double_operand", {SUBREG, REG, CONST_INT, CONST_DOUBLE}}, \
+{"small_int", {CONST_INT}}, \
+{"small_int_or_double", {CONST_INT, CONST_DOUBLE}}, \
+{"uns_small_int", {CONST_INT}}, \
+{"uns_arith_operand", {SUBREG, REG, CONST_INT}}, \
+{"clobbered_register", {REG}}, \
+{"input_operand", {SUBREG, REG, CONST_INT, MEM, CONST}}, \
+{"zero_operand", {CONST_INT}}, \
+{"const64_operand", {CONST_INT, CONST_DOUBLE}}, \
+{"const64_high_operand", {CONST_INT, CONST_DOUBLE}},
/* The number of Pmode words for the setjmp buffer. */
#define JMP_BUF_SIZE 12
@@ -3334,7 +3400,7 @@ extern int sparc_splitdi_legitimate ();
extern int sparc_absnegfloat_split_legitimate ();
extern char *output_cbranch ();
-extern char *output_return ();
+extern const char *output_return ();
extern char *output_v9branch ();
extern void emit_v9_brxx_insn ();
@@ -3394,11 +3460,10 @@ extern int sparc_flat_epilogue_delay_slots ();
extern int sparc_issue_rate ();
extern int splittable_immediate_memory_operand ();
extern int splittable_symbolic_memory_operand ();
-extern int supersparc_adjust_cost ();
+extern int sparc_adjust_cost ();
extern int symbolic_memory_operand ();
extern int symbolic_operand ();
extern int text_segment_operand ();
-extern int ultrasparc_adjust_cost ();
extern int uns_small_int ();
extern int v9_regcmp_op ();
extern int v9_regcmp_p ();
diff --git a/gcc/config/sparc/sparc.md b/gcc/config/sparc/sparc.md
index e7538a1ae65..c1adf93bbda 100644
--- a/gcc/config/sparc/sparc.md
+++ b/gcc/config/sparc/sparc.md
@@ -1,5 +1,5 @@
;;- Machine description for SPARC chip for GNU C compiler
-;; Copyright (C) 1987, 88, 89, 92-96, 1997 Free Software Foundation, Inc.
+;; Copyright (C) 1987, 88, 89, 92-98, 1999 Free Software Foundation, Inc.
;; Contributed by Michael Tiemann (tiemann@cygnus.com)
;; 64 bit SPARC V9 support by Michael Tiemann, Jim Wilson, and Doug Evans,
;; at Cygnus Support.
@@ -65,7 +65,7 @@
;; Attribute for cpu type.
;; These must match the values for enum processor_type in sparc.h.
-(define_attr "cpu" "v7,cypress,v8,supersparc,sparclite,f930,f934,sparclet,tsc701,v9,ultrasparc"
+(define_attr "cpu" "v7,cypress,v8,supersparc,sparclite,f930,f934,hypersparc,sparclite86x,sparclet,tsc701,v9,ultrasparc"
(const (symbol_ref "sparc_cpu_attr")))
;; Attribute for the instruction set.
@@ -345,6 +345,53 @@
(eq_attr "type" "imul"))
4 4)
+;; ----- hypersparc/sparclite86x scheduling
+;; The Hypersparc can issue 1 - 2 insns per cycle. The dual issue cases are:
+;; L-Ld/St I-Int F-Float B-Branch LI/LF/LB/II/IF/IB/FF/FB
+;; II/FF case is only when loading a 32 bit hi/lo constant
+;; Single issue insns include call, jmpl, u/smul, u/sdiv, lda, sta, fcmp
+;; Memory delivers its result in one cycle to IU
+
+(define_function_unit "memory" 1 0
+ (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
+ (eq_attr "type" "load,sload,fpload"))
+ 1 1)
+
+(define_function_unit "memory" 1 0
+ (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
+ (eq_attr "type" "store,fpstore"))
+ 2 1)
+
+(define_function_unit "fp_alu" 1 0
+ (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
+ (eq_attr "type" "fp,fpmove,fpcmp"))
+ 1 1)
+
+(define_function_unit "fp_mds" 1 0
+ (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
+ (eq_attr "type" "fpmul"))
+ 1 1)
+
+(define_function_unit "fp_mds" 1 0
+ (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
+ (eq_attr "type" "fpdivs"))
+ 8 6)
+
+(define_function_unit "fp_mds" 1 0
+ (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
+ (eq_attr "type" "fpdivd"))
+ 12 10)
+
+(define_function_unit "fp_mds" 1 0
+ (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
+ (eq_attr "type" "fpsqrt"))
+ 17 15)
+
+(define_function_unit "fp_mds" 1 0
+ (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
+ (eq_attr "type" "imul"))
+ 17 15)
+
;; ----- sparclet tsc701 scheduling
;; The tsc701 issues 1 insn per cycle.
;; Results may be written back out of order.
@@ -2238,10 +2285,10 @@
{
/* Where possible, convert CONST_DOUBLE into a CONST_INT. */
if (GET_CODE (operands[1]) == CONST_DOUBLE
-#if HOST_BITS_PER_WIDE_INT != 64
+#if HOST_BITS_PER_WIDE_INT == 32
&& ((CONST_DOUBLE_HIGH (operands[1]) == 0
&& (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) == 0)
- || (CONST_DOUBLE_HIGH (operands[1]) == 0xffffffff
+ || (CONST_DOUBLE_HIGH (operands[1]) == (HOST_WIDE_INT) 0xffffffff
&& (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) != 0))
#endif
)
@@ -2949,15 +2996,13 @@
[(set_attr "type" "move")
(set_attr "length" "1,2,2")])
-;; ?? This and split disabled on sparc64... When I change the destination
-;; ?? reg to be DImode to emit the constant formation code, the instruction
-;; ?? scheduler does not want to believe that it is the same as the DFmode
-;; ?? subreg we started with... See the SFmode version of this above to
-;; ?? see how it can be handled.
+;; Now that we redo life analysis with a clean slate after
+;; instruction splitting for sched2 this can work.
(define_insn "*movdf_const_intreg_sp64"
[(set (match_operand:DF 0 "general_operand" "=e,e,r")
(match_operand:DF 1 "" "m,o,F"))]
- "0 && TARGET_FPU && TARGET_ARCH64
+ "TARGET_FPU
+ && TARGET_ARCH64
&& GET_CODE (operands[1]) == CONST_DOUBLE
&& GET_CODE (operands[0]) == REG"
"*
@@ -2973,8 +3018,7 @@
(define_split
[(set (match_operand:DF 0 "register_operand" "")
(match_operand:DF 1 "const_double_operand" ""))]
- "! TARGET_ARCH64
- && TARGET_FPU
+ "TARGET_FPU
&& GET_CODE (operands[1]) == CONST_DOUBLE
&& (GET_CODE (operands[0]) == REG
&& REGNO (operands[0]) < 32)
@@ -7557,7 +7601,8 @@
(define_insn "blockage"
[(unspec_volatile [(const_int 0)] 0)]
""
- "")
+ ""
+ [(set_attr "length" "0")])
;; Prepare to return any type including a structure value.
@@ -7659,7 +7704,9 @@
""
"
{
+#if 0
rtx chain = operands[0];
+#endif
rtx fp = operands[1];
rtx stack = operands[2];
rtx lab = operands[3];
@@ -7689,6 +7736,8 @@
really needed. */
/*emit_insn (gen_rtx_USE (VOIDmode, frame_pointer_rtx));*/
emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
+
+#if 0
/* Return, restoring reg window and jumping to goto handler. */
if (TARGET_V9 && GET_CODE (chain) == CONST_INT
&& ! (INTVAL (chain) & ~(HOST_WIDE_INT)0xffffffff))
@@ -7700,6 +7749,8 @@
}
/* Put in the static chain register the nonlocal label address. */
emit_move_insn (static_chain_rtx, chain);
+#endif
+
emit_insn (gen_rtx_USE (VOIDmode, static_chain_rtx));
emit_insn (gen_goto_handler_and_restore (labreg));
emit_barrier ();
@@ -7721,27 +7772,27 @@
[(set_attr "type" "misc")
(set_attr "length" "2")])
-(define_insn "goto_handler_and_restore_v9"
- [(unspec_volatile [(match_operand:SI 0 "register_operand" "=r,r")
- (match_operand:SI 1 "register_operand" "=r,r")
- (match_operand:SI 2 "const_int_operand" "I,n")] 3)]
- "TARGET_V9 && ! TARGET_ARCH64"
- "@
- return\\t%0+0\\n\\tmov\\t%2, %Y1
- sethi\\t%%hi(%2), %1\\n\\treturn\\t%0+0\\n\\tor\\t%Y1, %%lo(%2), %Y1"
- [(set_attr "type" "misc")
- (set_attr "length" "2,3")])
-
-(define_insn "*goto_handler_and_restore_v9_sp64"
- [(unspec_volatile [(match_operand:DI 0 "register_operand" "=r,r")
- (match_operand:DI 1 "register_operand" "=r,r")
- (match_operand:SI 2 "const_int_operand" "I,n")] 3)]
- "TARGET_V9 && TARGET_ARCH64"
- "@
- return\\t%0+0\\n\\tmov\\t%2, %Y1
- sethi\\t%%hi(%2), %1\\n\\treturn\\t%0+0\\n\\tor\\t%Y1, %%lo(%2), %Y1"
- [(set_attr "type" "misc")
- (set_attr "length" "2,3")])
+;;(define_insn "goto_handler_and_restore_v9"
+;; [(unspec_volatile [(match_operand:SI 0 "register_operand" "=r,r")
+;; (match_operand:SI 1 "register_operand" "=r,r")
+;; (match_operand:SI 2 "const_int_operand" "I,n")] 3)]
+;; "TARGET_V9 && ! TARGET_ARCH64"
+;; "@
+;; return\\t%0+0\\n\\tmov\\t%2, %Y1
+;; sethi\\t%%hi(%2), %1\\n\\treturn\\t%0+0\\n\\tor\\t%Y1, %%lo(%2), %Y1"
+;; [(set_attr "type" "misc")
+;; (set_attr "length" "2,3")])
+;;
+;;(define_insn "*goto_handler_and_restore_v9_sp64"
+;; [(unspec_volatile [(match_operand:DI 0 "register_operand" "=r,r")
+;; (match_operand:DI 1 "register_operand" "=r,r")
+;; (match_operand:SI 2 "const_int_operand" "I,n")] 3)]
+;; "TARGET_V9 && TARGET_ARCH64"
+;; "@
+;; return\\t%0+0\\n\\tmov\\t%2, %Y1
+;; sethi\\t%%hi(%2), %1\\n\\treturn\\t%0+0\\n\\tor\\t%Y1, %%lo(%2), %Y1"
+;; [(set_attr "type" "misc")
+;; (set_attr "length" "2,3")])
;; Pattern for use after a setjmp to store FP and the return register
;; into the stack area.
@@ -8139,7 +8190,8 @@
(define_insn "nonlocal_goto_receiver"
[(unspec_volatile [(const_int 0)] 5)]
"flag_pic"
- "")
+ ""
+ [(set_attr "length" "0")])
(define_insn "trap"
[(trap_if (const_int 1) (const_int 5))]
@@ -8172,4 +8224,3 @@
"t%C0\\t%%xcc, %1"
[(set_attr "type" "misc")
(set_attr "length" "1")])
-
diff --git a/gcc/config/sparc/splet.h b/gcc/config/sparc/splet.h
index 23c6414417a..d924e708996 100644
--- a/gcc/config/sparc/splet.h
+++ b/gcc/config/sparc/splet.h
@@ -29,12 +29,12 @@ Boston, MA 02111-1307, USA. */
/* -mlive-g0 is only supported on the sparclet. */
#undef SUBTARGET_SWITCHES
#define SUBTARGET_SWITCHES \
-{"big-endian", -MASK_LITTLE_ENDIAN}, \
-{"little-endian", MASK_LITTLE_ENDIAN}, \
-{"live-g0", MASK_LIVE_G0}, \
-{"no-live-g0", -MASK_LIVE_G0}, \
-{"broken-saverestore", MASK_BROKEN_SAVERESTORE}, \
-{"no-broken-saverestore", -MASK_BROKEN_SAVERESTORE},
+{"big-endian", -MASK_LITTLE_ENDIAN, "Generate code for big endian" }, \
+{"little-endian", MASK_LITTLE_ENDIAN, "Generate code for little endian" }, \
+{"live-g0", MASK_LIVE_G0, "Use g0 as a normal register" }, \
+{"no-live-g0", -MASK_LIVE_G0, "Register g0 is fixed with a zero value" }, \
+{"broken-saverestore", MASK_BROKEN_SAVERESTORE, "Enable save/restore bug workarounds" }, \
+{"no-broken-saverestore", -MASK_BROKEN_SAVERESTORE, "Disable save/restore bug workarouns" },
#undef ASM_SPEC
#define ASM_SPEC "%{mlittle-endian:-EL} %(asm_cpu)"
@@ -51,3 +51,19 @@ Boston, MA 02111-1307, USA. */
#define BYTES_BIG_ENDIAN (! TARGET_LITTLE_ENDIAN)
#undef WORDS_BIG_ENDIAN
#define WORDS_BIG_ENDIAN (! TARGET_LITTLE_ENDIAN)
+
+#undef SUBTARGET_OVERRIDE_OPTIONS
+#define SUBTARGET_OVERRIDE_OPTIONS \
+ do { \
+ if (TARGET_LIVE_G0) \
+ { \
+ warning ("Option '-mlive-g0' deprecated."); \
+ target_flags &= ~MASK_LIVE_G0; \
+ } \
+ else if (TARGET_BROKEN_SAVERESTORE) \
+ { \
+ warning ("Option '-mbroken-saverestore' deprecated."); \
+ target_flags &= ~MASK_BROKEN_SAVERESTORE; \
+ } \
+ } while (0)
+
diff --git a/gcc/config/sparc/t-splet b/gcc/config/sparc/t-splet
index 3409f5dfe88..3329e0bef07 100644
--- a/gcc/config/sparc/t-splet
+++ b/gcc/config/sparc/t-splet
@@ -16,8 +16,7 @@ fp-bit.c: $(srcdir)/config/fp-bit.c
echo '#define FLOAT' > fp-bit.c
cat $(srcdir)/config/fp-bit.c >> fp-bit.c
-MULTILIB_OPTIONS = mlittle-endian mlive-g0 mbroken-saverestore
-MULTILIB_DIRNAMES = little live-g0 brknsave
-
+MULTILIB_OPTIONS = mlittle-endian mflat
+MULTILIB_DIRNAMES = little flat
LIBGCC = stmp-multilib
INSTALL_LIBGCC = install-multilib
diff --git a/gcc/config/spur/spur.h b/gcc/config/spur/spur.h
index c75caf6f5f1..e6d058a4491 100644
--- a/gcc/config/spur/spur.h
+++ b/gcc/config/spur/spur.h
@@ -586,11 +586,11 @@ extern int current_function_pretend_args_size;
/* Addressing modes, and classification of registers for them. */
-/* #define HAVE_POST_INCREMENT */
-/* #define HAVE_POST_DECREMENT */
+/* #define HAVE_POST_INCREMENT 0 */
+/* #define HAVE_POST_DECREMENT 0 */
-/* #define HAVE_PRE_DECREMENT */
-/* #define HAVE_PRE_INCREMENT */
+/* #define HAVE_PRE_DECREMENT 0 */
+/* #define HAVE_PRE_INCREMENT 0 */
/* Macros to check register numbers against specific register classes. */
diff --git a/gcc/config/svr4.h b/gcc/config/svr4.h
index ef7a1d9df84..1c8482fd11d 100644
--- a/gcc/config/svr4.h
+++ b/gcc/config/svr4.h
@@ -1,6 +1,6 @@
/* Operating system specific defines to be used when targeting GCC for some
generic System V Release 4 system.
- Copyright (C) 1991, 94-97, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1991, 94-98, 1999 Free Software Foundation, Inc.
Contributed by Ron Guilmette (rfg@monkeys.com).
This file is part of GNU CC.
@@ -212,8 +212,9 @@ Boston, MA 02111-1307, USA.
#define ASM_FILE_END(FILE) \
do { \
- fprintf ((FILE), "\t%s\t\"GCC: (GNU) %s\"\n", \
- IDENT_ASM_OP, version_string); \
+ if (!flag_no_ident) \
+ fprintf ((FILE), "\t%s\t\"GCC: (GNU) %s\"\n", \
+ IDENT_ASM_OP, version_string); \
} while (0)
/* Allow #sccs in preprocessor. */
@@ -260,83 +261,14 @@ do { \
#undef DBX_REGISTER_NUMBER
-/* gas on SVR4 supports the use of .stabs. Permit -gstabs to be used
- in general, although it will only work when using gas. */
-
-#define DBX_DEBUGGING_INFO
-
-/* When generating stabs debugging, use N_BINCL entries. */
-
-#define DBX_USE_BINCL
-
/* Use DWARF debugging info by default. */
#ifndef PREFERRED_DEBUGGING_TYPE
#define PREFERRED_DEBUGGING_TYPE DWARF_DEBUG
#endif
-/* Make LBRAC and RBRAC addresses relative to the start of the
- function. The native Solaris stabs debugging format works this
- way, gdb expects it, and it reduces the number of relocation
- entries. */
-
-#define DBX_BLOCKS_FUNCTION_RELATIVE 1
-
-/* When using stabs, gcc2_compiled must be a stabs entry, not an
- ordinary symbol, or gdb won't see it. Furthermore, since gdb reads
- the input piecemeal, starting with each N_SO, it's a lot easier if
- the gcc2 flag symbol is *after* the N_SO rather than before it. So
- we emit an N_OPT stab there. */
-
-#define ASM_IDENTIFY_GCC(FILE) \
-do \
- { \
- if (write_symbols != DBX_DEBUG) \
- fputs ("gcc2_compiled.:\n", FILE); \
- } \
-while (0)
-
-#define ASM_IDENTIFY_GCC_AFTER_SOURCE(FILE) \
-do \
- { \
- if (write_symbols == DBX_DEBUG) \
- fputs ("\t.stabs\t\"gcc2_compiled.\", 0x3c, 0, 0, 0\n", FILE); \
- } \
-while (0)
-
-/* Like block addresses, stabs line numbers are relative to the
- current function. */
-
-#define ASM_OUTPUT_SOURCE_LINE(file, line) \
-do \
- { \
- static int sym_lineno = 1; \
- fprintf (file, ".stabn 68,0,%d,.LM%d-", \
- line, sym_lineno); \
- assemble_name (file, \
- XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0));\
- fprintf (file, "\n.LM%d:\n", sym_lineno); \
- sym_lineno += 1; \
- } \
-while (0)
-
-/* In order for relative line numbers to work, we must output the
- stabs entry for the function name first. */
-
-#define DBX_FUNCTION_FIRST
-
-/* Generate a blank trailing N_SO to mark the end of the .o file, since
- we can't depend upon the linker to mark .o file boundaries with
- embedded stabs. */
-
-#define DBX_OUTPUT_MAIN_SOURCE_FILE_END(FILE, FILENAME) \
-do \
- { \
- text_section (); \
- fprintf (FILE, \
- "\t.stabs \"\",%d,0,0,.Letext\n.Letext:\n", N_SO); \
- } \
-while (0)
+/* But allow STABS to be supoorted as well. */
+#include "dbxelf.h"
/* Define the actual types of some ANSI-mandated types. (These
definitions should work for most SVR4 systems). */
@@ -950,7 +882,7 @@ do { \
} \
for (p = _ascii_bytes; p < limit && *p != '\0'; p++) \
continue; \
- if (p < limit && (p - _ascii_bytes) <= STRING_LIMIT) \
+ if (p < limit && (p - _ascii_bytes) <= (long)STRING_LIMIT) \
{ \
if (bytes_in_chunk > 0) \
{ \
diff --git a/gcc/config/t-gnu b/gcc/config/t-gnu
index 58969f21e20..575f729768c 100644
--- a/gcc/config/t-gnu
+++ b/gcc/config/t-gnu
@@ -1,5 +1,8 @@
-LIBGCC1=libgcc1.null
-CROSS_LIBGCC1=libgcc1.null
+# In GNU, "/usr" is a four-letter word.
+SYSTEM_HEADER_DIR = /include
+
+LIBGCC1 = libgcc1.null
+CROSS_LIBGCC1 = libgcc1.null
# The pushl in CTOR initialization interferes with frame pointer elimination.
diff --git a/gcc/config/t-rtems b/gcc/config/t-rtems
index 25dd398dd52..aa0ca66d98b 100644
--- a/gcc/config/t-rtems
+++ b/gcc/config/t-rtems
@@ -1,2 +1,6 @@
# RTEMS uses newlib which does not require prototype fixing
STMP_FIXPROTO =
+
+# Don't install "assert.h" in gcc. RTEMS uses the one in newlib.
+INSTALL_ASSERT_H =
+
diff --git a/gcc/config/v850/lib1funcs.asm b/gcc/config/v850/lib1funcs.asm
index 2787e97519a..cb1f039fa04 100644
--- a/gcc/config/v850/lib1funcs.asm
+++ b/gcc/config/v850/lib1funcs.asm
@@ -95,6 +95,7 @@ ___mulsi3:
#ifdef L_udivsi3
.text
.global ___udivsi3
+ .type ___udivsi3,@function
___udivsi3:
mov 1,r12
mov 0,r10
@@ -110,8 +111,8 @@ ___udivsi3:
bnl .L12
cmp r0,r12
be .L8
- mov r7,r5
- and r13,r5
+ mov r7,r19
+ and r13,r19
be .L4
br .L12
.L9:
diff --git a/gcc/config/v850/v850.c b/gcc/config/v850/v850.c
index 8d9981c810c..15867ac4892 100644
--- a/gcc/config/v850/v850.c
+++ b/gcc/config/v850/v850.c
@@ -1,5 +1,5 @@
/* Subroutines for insn-output.c for NEC V850 series
- Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
Contributed by Jeff Law (law@cygnus.com).
This file is part of GNU CC.
@@ -19,9 +19,9 @@ 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 "config.h"
#include <stdio.h>
#include <ctype.h>
-#include "config.h"
#include "tree.h"
#include "rtl.h"
#include "regs.h"
@@ -365,9 +365,16 @@ print_operand (file, x, code)
switch (code)
{
+ case 'c':
+ /* We use 'c' operands with symbols for .vtinherit */
+ if (GET_CODE (x) == SYMBOL_REF)
+ {
+ output_addr_const(file, x);
+ break;
+ }
+ /* fall through */
case 'b':
case 'B':
- case 'c':
case 'C':
switch ((code == 'B' || code == 'C')
? reverse_condition (GET_CODE (x)) : GET_CODE (x))
@@ -937,6 +944,7 @@ ep_memory_operand (op, mode, unsigned_load)
op1 = XEXP (addr, 1);
if (GET_CODE (op1) == CONST_INT
&& INTVAL (op1) < max_offset
+ && INTVAL (op1) >= 0
&& (INTVAL (op1) & mask) == 0)
{
if (GET_CODE (op0) == REG && REGNO (op0) == EP_REGNUM)
@@ -1142,7 +1150,8 @@ Saved %d bytes (%d uses of register %s) in function %s, starting as insn %d, end
&& GET_CODE (XEXP (addr, 1)) == CONST_INT
&& ((INTVAL (XEXP (addr, 1)))
< ep_memory_offset (GET_MODE (*p_mem),
- unsignedp)))
+ unsignedp))
+ && ((INTVAL (XEXP (addr, 1))) >= 0))
*p_mem = change_address (*p_mem, VOIDmode,
gen_rtx (PLUS, Pmode,
*p_ep, XEXP (addr, 1)));
@@ -1253,6 +1262,14 @@ void v850_reorg (start_insn)
/* Memory operands are signed by default. */
int unsignedp = FALSE;
+ /* We might have (SUBREG (MEM)) here, so just get rid of the
+ subregs to make this code simpler. It is safe to call
+ alter_subreg any time after reload. */
+ if (GET_CODE (dest) == SUBREG)
+ dest = alter_subreg (dest);
+ if (GET_CODE (src) == SUBREG)
+ src = alter_subreg (src);
+
if (GET_CODE (dest) == MEM && GET_CODE (src) == MEM)
mem = NULL_RTX;
@@ -1285,7 +1302,8 @@ void v850_reorg (start_insn)
&& GET_CODE (XEXP (addr, 0)) == REG
&& GET_CODE (XEXP (addr, 1)) == CONST_INT
&& ((INTVAL (XEXP (addr, 1)))
- < ep_memory_offset (GET_MODE (mem), unsignedp)))
+ < ep_memory_offset (GET_MODE (mem), unsignedp))
+ && ((INTVAL (XEXP (addr, 1))) >= 0))
{
short_p = TRUE;
regno = REGNO (XEXP (addr, 0));
@@ -1305,20 +1323,13 @@ void v850_reorg (start_insn)
/* Loading up a register in the basic block zaps any savings
for the register */
- if (GET_CODE (dest) == REG || GET_CODE (dest) == SUBREG)
+ if (GET_CODE (dest) == REG)
{
enum machine_mode mode = GET_MODE (dest);
- int word = 0;
int regno;
int endregno;
- while (GET_CODE (dest) == SUBREG)
- {
- word = SUBREG_WORD (dest);
- dest = SUBREG_REG (dest);
- }
-
- regno = REGNO (dest) + word;
+ regno = REGNO (dest);
endregno = regno + HARD_REGNO_NREGS (regno, mode);
if (!use_ep)
@@ -1391,12 +1402,12 @@ compute_register_save_size (p_reg_saved)
int size = 0;
int i;
int interrupt_handler = v850_interrupt_function_p (current_function_decl);
- int call_p = regs_ever_live[31];
+ int call_p = regs_ever_live [LINK_POINTER_REGNUM];
long reg_saved = 0;
/* Count the return pointer if we need to save it. */
if (profile_flag && !call_p)
- regs_ever_live[31] = call_p = 1;
+ regs_ever_live [LINK_POINTER_REGNUM] = call_p = 1;
/* Count space for the register saves. */
if (interrupt_handler)
@@ -1429,15 +1440,63 @@ compute_register_save_size (p_reg_saved)
break;
}
}
-
else
- for (i = 0; i <= 31; i++)
- if (regs_ever_live[i] && ((! call_used_regs[i]) || i == 31))
+ {
+ /* Find the first register that needs to be saved. */
+ for (i = 0; i <= 31; i++)
+ if (regs_ever_live[i] && ((! call_used_regs[i])
+ || i == LINK_POINTER_REGNUM))
+ break;
+
+ /* If it is possible that an out-of-line helper function might be
+ used to generate the prologue for the current function, then we
+ need to cover the possibility that such a helper function will
+ be used, despite the fact that there might be gaps in the list of
+ registers that need to be saved. To detect this we note that the
+ helper functions always push at least register r29 if the link
+ register is not used, and at least registers r27 - r31 if the
+ link register is used (and provided that the function is not an
+ interrupt handler). */
+
+ if (TARGET_PROLOG_FUNCTION
+ && (i == 2 || i >= 20)
+ && regs_ever_live[LINK_POINTER_REGNUM] ? (i < 28) : (i < 30))
{
- size += 4;
- reg_saved |= 1L << i;
- }
+ if (i == 2)
+ {
+ size += 4;
+ reg_saved |= 1L << i;
+ i = 20;
+ }
+
+ /* Helper functions save all registers between the starting
+ register and the last register, regardless of whether they
+ are actually used by the function or not. */
+ for (; i <= 29; i++)
+ {
+ size += 4;
+ reg_saved |= 1L << i;
+ }
+
+ if (regs_ever_live [LINK_POINTER_REGNUM])
+ {
+ size += 4;
+ reg_saved |= 1L << LINK_POINTER_REGNUM;
+ }
+ }
+ else
+ {
+ for (; i <= 31; i++)
+ if (regs_ever_live[i] && ((! call_used_regs[i])
+ || i == LINK_POINTER_REGNUM))
+ {
+ size += 4;
+ reg_saved |= 1L << i;
+ }
+ }
+ }
+
if (p_reg_saved)
*p_reg_saved = reg_saved;
@@ -1479,8 +1538,10 @@ expand_prologue ()
if (interrupt_handler)
{
emit_insn (gen_save_interrupt ());
+
actual_fsize -= INTERRUPT_FIXED_SAVE_SIZE;
- if (((1L << 31) & reg_saved) != 0)
+
+ if (((1L << LINK_POINTER_REGNUM) & reg_saved) != 0)
actual_fsize -= INTERRUPT_ALL_SAVE_SIZE;
}
@@ -1488,7 +1549,9 @@ expand_prologue ()
else if (current_function_anonymous_args)
{
if (TARGET_PROLOG_FUNCTION)
- emit_insn (gen_save_r6_r9 ());
+ {
+ emit_insn (gen_save_r6_r9 ());
+ }
else
{
offset = 0;
@@ -1514,9 +1577,9 @@ expand_prologue ()
/* If the return pointer is saved, the helper functions also allocate
16 bytes of stack for arguments to be saved in. */
- if (((1L << 31) & reg_saved) != 0)
+ if (((1L << LINK_POINTER_REGNUM) & reg_saved) != 0)
{
- save_regs[num_save++] = gen_rtx (REG, Pmode, 31);
+ save_regs[num_save++] = gen_rtx (REG, Pmode, LINK_POINTER_REGNUM);
default_stack = 16;
}
@@ -1556,14 +1619,14 @@ expand_prologue ()
if (TARGET_V850)
{
- XVECEXP (save_all, 0, num_save+1)
+ XVECEXP (save_all, 0, num_save + 1)
= gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, Pmode, 10));
}
offset = - default_stack;
for (i = 0; i < num_save; i++)
{
- XVECEXP (save_all, 0, i+1)
+ XVECEXP (save_all, 0, i + 1)
= gen_rtx (SET, VOIDmode,
gen_rtx (MEM, Pmode,
plus_constant (stack_pointer_rtx, offset)),
@@ -1577,7 +1640,7 @@ expand_prologue ()
rtx insn = emit_insn (save_all);
INSN_CODE (insn) = code;
actual_fsize -= alloc_stack;
-
+
if (TARGET_DEBUG)
fprintf (stderr, "\
Saved %d bytes via prologue function (%d vs. %d) for function %s\n",
@@ -1595,9 +1658,10 @@ Saved %d bytes via prologue function (%d vs. %d) for function %s\n",
if (!save_all)
{
/* Special case interrupt functions that save all registers for a call. */
- if (interrupt_handler && ((1L << 31) & reg_saved) != 0)
- emit_insn (gen_save_all_interrupt ());
-
+ if (interrupt_handler && ((1L << LINK_POINTER_REGNUM) & reg_saved) != 0)
+ {
+ emit_insn (gen_save_all_interrupt ());
+ }
else
{
/* If the stack is too big, allocate it in chunks so we can do the
@@ -1617,7 +1681,7 @@ Saved %d bytes via prologue function (%d vs. %d) for function %s\n",
GEN_INT (-init_stack_alloc)));
/* Save the return pointer first. */
- if (num_save > 0 && REGNO (save_regs[num_save-1]) == 31)
+ if (num_save > 0 && REGNO (save_regs[num_save-1]) == LINK_POINTER_REGNUM)
{
emit_move_insn (gen_rtx (MEM, SImode,
plus_constant (stack_pointer_rtx,
@@ -1681,7 +1745,7 @@ expand_epilogue ()
if (interrupt_handler)
{
actual_fsize -= INTERRUPT_FIXED_SAVE_SIZE;
- if (((1L << 31) & reg_saved) != 0)
+ if (((1L << LINK_POINTER_REGNUM) & reg_saved) != 0)
actual_fsize -= INTERRUPT_ALL_SAVE_SIZE;
}
@@ -1700,9 +1764,9 @@ expand_epilogue ()
/* If the return pointer is saved, the helper functions also allocate
16 bytes of stack for arguments to be saved in. */
- if (((1L << 31) & reg_saved) != 0)
+ if (((1L << LINK_POINTER_REGNUM) & reg_saved) != 0)
{
- restore_regs[num_restore++] = gen_rtx (REG, Pmode, 31);
+ restore_regs[num_restore++] = gen_rtx (REG, Pmode, LINK_POINTER_REGNUM);
default_stack = 16;
}
@@ -1825,15 +1889,18 @@ Saved %d bytes via epilogue function (%d vs. %d) in function %s\n",
/* Special case interrupt functions that save all registers
for a call. */
- if (interrupt_handler && ((1L << 31) & reg_saved) != 0)
- emit_insn (gen_restore_all_interrupt ());
+ if (interrupt_handler && ((1L << LINK_POINTER_REGNUM) & reg_saved) != 0)
+ {
+ emit_insn (gen_restore_all_interrupt ());
+ }
else
{
/* Restore registers from the beginning of the stack frame */
offset = init_stack_free - 4;
/* Restore the return pointer first. */
- if (num_restore > 0 && REGNO (restore_regs[num_restore-1]) == 31)
+ if (num_restore > 0
+ && REGNO (restore_regs [num_restore - 1]) == LINK_POINTER_REGNUM)
{
emit_move_insn (restore_regs[--num_restore],
gen_rtx (MEM, SImode,
@@ -2260,17 +2327,18 @@ construct_restore_jr (op)
abort ();
/* Discover the last register to pop. */
- if (mask & (1 << 31))
+ if (mask & (1 << LINK_POINTER_REGNUM))
{
if (stack_bytes != 16)
abort ();
- last = 31;
+ last = LINK_POINTER_REGNUM;
}
else
{
if (stack_bytes != 0)
abort ();
+
if ((mask & (1 << 29)) == 0)
abort ();
@@ -2282,11 +2350,26 @@ construct_restore_jr (op)
be popping more registers than is strictly necessary, but
it does save code space. */
- if (first == last)
- sprintf (buff, "jr __return_%s", reg_names [first]);
+ if (TARGET_LONG_CALLS)
+ {
+ char name[40];
+
+ if (first == last)
+ sprintf (name, "__return_%s", reg_names [first]);
+ else
+ sprintf (name, "__return_%s_%s", reg_names [first], reg_names [last]);
+
+ sprintf (buff, "movhi hi(%s), r0, r6\n\tmovea lo(%s), r6, r6\n\tjmp r6",
+ name, name);
+ }
else
- sprintf (buff, "jr __return_%s_%s", reg_names [first], reg_names [last]);
-
+ {
+ if (first == last)
+ sprintf (buff, "jr __return_%s", reg_names [first]);
+ else
+ sprintf (buff, "jr __return_%s_%s", reg_names [first], reg_names [last]);
+ }
+
return buff;
}
@@ -2446,12 +2529,12 @@ construct_save_jarl (op)
abort ();
/* Discover the last register to push. */
- if (mask & (1 << 31))
+ if (mask & (1 << LINK_POINTER_REGNUM))
{
if (stack_bytes != -16)
abort ();
- last = 31;
+ last = LINK_POINTER_REGNUM;
}
else
{
@@ -2468,11 +2551,26 @@ construct_save_jarl (op)
be pushing more registers than is strictly necessary, but
it does save code space. */
- if (first == last)
- sprintf (buff, "jarl __save_%s, r10", reg_names [first]);
+ if (TARGET_LONG_CALLS)
+ {
+ char name[40];
+
+ if (first == last)
+ sprintf (name, "__save_%s", reg_names [first]);
+ else
+ sprintf (name, "__save_%s_%s", reg_names [first], reg_names [last]);
+
+ sprintf (buff, "movhi hi(%s), r0, r11\n\tmovea lo(%s), r11, r11\n\tjarl .+4, r10\n\tadd 4, r10\n\tjmp r11",
+ name, name);
+ }
else
- sprintf (buff, "jarl __save_%s_%s, r10", reg_names [first],
- reg_names [last]);
+ {
+ if (first == last)
+ sprintf (buff, "jarl __save_%s, r10", reg_names [first]);
+ else
+ sprintf (buff, "jarl __save_%s_%s, r10", reg_names [first],
+ reg_names [last]);
+ }
return buff;
}
diff --git a/gcc/config/v850/v850.h b/gcc/config/v850/v850.h
index 8a417f079fc..fe3f7ae535c 100644
--- a/gcc/config/v850/v850.h
+++ b/gcc/config/v850/v850.h
@@ -20,7 +20,6 @@ the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include "svr4.h" /* Automatically does #undef CPP_PREDEFINES */
-#include "gansidecl.h" /* For the PROTO macro */
#undef ASM_SPEC
#define ASM_SPEC "%{mv*:-mv%*}"
@@ -573,6 +572,9 @@ enum reg_class
/* Base register for access to local variables of the function. */
#define FRAME_POINTER_REGNUM 32
+/* Register containing return address from latest function call. */
+#define LINK_POINTER_REGNUM 31
+
/* On some machines the offset between the frame pointer and starting
offset of the automatic variables is not known until after register
allocation has been done (for example, because the saved registers
diff --git a/gcc/config/v850/v850.md b/gcc/config/v850/v850.md
index 0ba10ca0cc0..7eef0c639ae 100644
--- a/gcc/config/v850/v850.md
+++ b/gcc/config/v850/v850.md
@@ -1,5 +1,5 @@
;; GCC machine description for NEC V850
-;; Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+;; Copyright (C) 1996, 1997, 1999 Free Software Foundation, Inc.
;; Contributed by Jeff Law (law@cygnus.com).
@@ -36,6 +36,11 @@
(define_attr "length" ""
(const_int 200))
+(define_attr "long_calls" "yes,no"
+ (const (if_then_else (symbol_ref "TARGET_LONG_CALLS")
+ (const_string "yes")
+ (const_string "no"))))
+
;; Types of instructions (for scheduling purposes).
(define_attr "type" "load,mult,other"
@@ -397,7 +402,7 @@
(set_attr "cc" "clobber")])
(define_insn "*v850_clr1_2"
- [(set (match_operand:HI 0 "memory_operand" "=m")
+ [(set (match_operand:HI 0 "indirect_operand" "=m")
(subreg:HI
(and:SI (subreg:SI (match_dup 0) 0)
(match_operand:HI 1 "not_power_of_two_operand" "")) 0))]
@@ -417,7 +422,7 @@
(set_attr "cc" "clobber")])
(define_insn "*v850_clr1_3"
- [(set (match_operand:SI 0 "memory_operand" "=m")
+ [(set (match_operand:SI 0 "indirect_operand" "=m")
(and:SI (match_dup 0)
(match_operand:SI 1 "not_power_of_two_operand" "")))]
""
@@ -461,7 +466,7 @@
(set_attr "cc" "clobber")])
(define_insn "*v850_set1_2"
- [(set (match_operand:HI 0 "memory_operand" "=m")
+ [(set (match_operand:HI 0 "indirect_operand" "=m")
(subreg:HI (ior:SI (subreg:SI (match_dup 0) 0)
(match_operand 1 "power_of_two_operand" "")) 0))]
""
@@ -485,7 +490,7 @@
(set_attr "cc" "clobber")])
(define_insn "*v850_set1_3"
- [(set (match_operand:SI 0 "memory_operand" "=m")
+ [(set (match_operand:SI 0 "indirect_operand" "=m")
(ior:SI (match_dup 0)
(match_operand 1 "power_of_two_operand" "")))]
""
@@ -534,7 +539,7 @@
(set_attr "cc" "clobber")])
(define_insn "*v850_not1_2"
- [(set (match_operand:HI 0 "memory_operand" "=m")
+ [(set (match_operand:HI 0 "indirect_operand" "=m")
(subreg:HI (xor:SI (subreg:SI (match_dup 0) 0)
(match_operand 1 "power_of_two_operand" "")) 0))]
""
@@ -558,7 +563,7 @@
(set_attr "cc" "clobber")])
(define_insn "*v850_not1_3"
- [(set (match_operand:SI 0 "memory_operand" "=m")
+ [(set (match_operand:SI 0 "indirect_operand" "=m")
(xor:SI (match_dup 0)
(match_operand 1 "power_of_two_operand" "")))]
""
@@ -969,19 +974,44 @@
if (! call_address_operand (XEXP (operands[0], 0))
|| TARGET_LONG_CALLS)
XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
- emit_call_insn (gen_call_internal (XEXP (operands[0], 0), operands[1]));
+ if (TARGET_LONG_CALLS)
+ emit_call_insn (gen_call_internal_long (XEXP (operands[0], 0), operands[1]));
+ else
+ emit_call_insn (gen_call_internal_short (XEXP (operands[0], 0), operands[1]));
+
DONE;
}")
-(define_insn "call_internal"
+(define_insn "call_internal_short"
[(call (mem:QI (match_operand:SI 0 "call_address_operand" "S,r"))
(match_operand:SI 1 "general_operand" "g,g"))
(clobber (reg:SI 31))]
- ""
+ "! TARGET_LONG_CALLS"
"@
jarl %0,r31
- jarl .+4,r31\\n\\tadd 4,r31\\n\\tjmp %0"
- [(set_attr "length" "4,8")])
+ jarl .+4,r31\\;add 4,r31\\;jmp %0"
+ [(set_attr "length" "4,8")]
+)
+
+(define_insn "call_internal_long"
+ [(call (mem:QI (match_operand:SI 0 "call_address_operand" "S,r"))
+ (match_operand:SI 1 "general_operand" "g,g"))
+ (clobber (reg:SI 31))]
+ "TARGET_LONG_CALLS"
+ "*
+ {
+ if (which_alternative == 0)
+ {
+ if (GET_CODE (operands[0]) == REG)
+ return \"jarl %0,r31\";
+ else
+ return \"movhi hi(%0), r0, r11\\;movea lo(%0), r11, r11\\;jarl .+4,r31\\;add 4, r31\\;jmp r11\";
+ }
+ else
+ return \"jarl .+4,r31\\;add 4,r31\\;jmp %0\";
+ }"
+ [(set_attr "length" "16,8")]
+)
;; Call subroutine, returning value in operand 0
;; (which must be a hard register).
@@ -996,22 +1026,50 @@
if (! call_address_operand (XEXP (operands[1], 0))
|| TARGET_LONG_CALLS)
XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
- emit_call_insn (gen_call_value_internal (operands[0],
- XEXP (operands[1], 0),
- operands[2]));
+ if (TARGET_LONG_CALLS)
+ emit_call_insn (gen_call_value_internal_long (operands[0],
+ XEXP (operands[1], 0),
+ operands[2]));
+ else
+ emit_call_insn (gen_call_value_internal_short (operands[0],
+ XEXP (operands[1], 0),
+ operands[2]));
DONE;
}")
-(define_insn "call_value_internal"
+(define_insn "call_value_internal_short"
[(set (match_operand 0 "" "=r,r")
(call (mem:QI (match_operand:SI 1 "call_address_operand" "S,r"))
(match_operand:SI 2 "general_operand" "g,g")))
(clobber (reg:SI 31))]
- ""
+ "! TARGET_LONG_CALLS"
"@
jarl %1,r31
- jarl .+4,r31\\n\\tadd 4,r31\\n\\tjmp %1"
- [(set_attr "length" "4,8")])
+ jarl .+4,r31\\;add 4,r31\\;jmp %1"
+ [(set_attr "length" "4,8")]
+)
+
+(define_insn "call_value_internal_long"
+ [(set (match_operand 0 "" "=r,r")
+ (call (mem:QI (match_operand:SI 1 "call_address_operand" "S,r"))
+ (match_operand:SI 2 "general_operand" "g,g")))
+ (clobber (reg:SI 31))]
+ "TARGET_LONG_CALLS"
+ "*
+ {
+ if (which_alternative == 0)
+ {
+ if (GET_CODE (operands[1]) == REG)
+ return \"jarl %1, r31\";
+ else
+ /* Reload can generate this pattern... */
+ return \"movhi hi(%1), r0, r11\\;movea lo(%1), r11, r11\\;jarl .+4, r31\\;add 4, r31\\;jmp r11\";
+ }
+ else
+ return \"jarl .+4, r31\\;add 4, r31\\;jmp %1\";
+ }"
+ [(set_attr "length" "16,8")]
+)
(define_insn "nop"
[(const_int 0)]
@@ -1180,45 +1238,15 @@
"TARGET_PROLOG_FUNCTION"
"* return construct_save_jarl (operands[0]);
"
- [(set_attr "length" "4")
+ [(set (attr "length") (if_then_else (eq_attr "long_calls" "yes")
+ (const_string "16")
+ (const_string "4")))
(set_attr "cc" "clobber")])
-
-;; Initialize an interrupt function. Do not depend on TARGET_PROLOG_FUNCTION.
-(define_insn "save_interrupt"
- [(set (reg:SI 3) (plus:SI (reg:SI 3) (const_int -16)))
- (set (mem:SI (reg:SI 3)) (reg:SI 30))
- (set (mem:SI (plus:SI (reg:SI 3) (const_int -4))) (reg:SI 10))
- (set (mem:SI (plus:SI (reg:SI 3) (const_int -8))) (reg:SI 4))
- (set (mem:SI (plus:SI (reg:SI 3) (const_int -12))) (reg:SI 1))]
- ""
- "add -16,sp\;st.w r10,12[sp]\;jarl __save_interrupt,r10"
- [(set_attr "length" "12")
- (set_attr "cc" "clobber")])
-
-
-;; Save all registers except for the registers saved in save_interrupt when
-;; an interrupt function makes a call.
-;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
-;; all of memory. This blocks insns from being moved across this point.
-;; This is needed because the rest of the compiler is not ready to handle
-;; insns this complicated.
-
-(define_insn "save_all_interrupt"
- [(unspec_volatile [(const_int 0)] 0)]
- ""
- "jarl __save_all_interrupt,r10"
- [(set_attr "length" "4")
- (set_attr "cc" "clobber")])
-
-
-
-
;; This pattern will match a return RTX followed by any number of pop RTXs
;; and possible a stack adjustment as well. These RTXs will be turned into
;; a suitable call to a worker function.
-
(define_insn ""
[(match_parallel 0 "pattern_is_ok_for_epilogue"
[(return)
@@ -1230,9 +1258,23 @@
"TARGET_PROLOG_FUNCTION && TARGET_V850"
"* return construct_restore_jr (operands[0]);
"
- [(set_attr "length" "4")
+ [(set (attr "length") (if_then_else (eq_attr "long_calls" "yes")
+ (const_string "12")
+ (const_string "4")))
(set_attr "cc" "clobber")])
+;; Initialize an interrupt function. Do not depend on TARGET_PROLOG_FUNCTION.
+(define_insn "save_interrupt"
+ [(set (reg:SI 3) (plus:SI (reg:SI 3) (const_int -16)))
+ (set (mem:SI (reg:SI 3)) (reg:SI 30))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -4))) (reg:SI 10))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -8))) (reg:SI 4))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -12))) (reg:SI 1))]
+ "TARGET_V850 && ! TARGET_LONG_CALLS"
+ "add -16,sp\;st.w r10,12[sp]\;jarl __save_interrupt,r10"
+ [(set_attr "length" "12")
+ (set_attr "cc" "clobber")])
+
;; Restore r1, r4, r10, and return from the interrupt
(define_insn "restore_interrupt"
[(return)
@@ -1246,6 +1288,22 @@
[(set_attr "length" "4")
(set_attr "cc" "clobber")])
+
+;; Save all registers except for the registers saved in save_interrupt when
+;; an interrupt function makes a call.
+;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
+;; all of memory. This blocks insns from being moved across this point.
+;; This is needed because the rest of the compiler is not ready to handle
+;; insns this complicated.
+
+(define_insn "save_all_interrupt"
+ [(unspec_volatile [(const_int 0)] 0)]
+ "TARGET_V850 && ! TARGET_LONG_CALLS"
+ "jarl __save_all_interrupt,r10"
+ [(set_attr "length" "4")
+ (set_attr "cc" "clobber")])
+
+
;; Restore all registers saved when an interrupt function makes a call.
;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
;; all of memory. This blocks insns from being moved across this point.
@@ -1254,7 +1312,7 @@
(define_insn "restore_all_interrupt"
[(unspec_volatile [(const_int 0)] 1)]
- ""
+ "TARGET_V850 && ! TARGET_LONG_CALLS"
"jarl __restore_all_interrupt,r10"
[(set_attr "length" "4")
(set_attr "cc" "clobber")])
@@ -1266,7 +1324,7 @@
(set (mem:SI (plus:SI (reg:SI 3) (const_int 8))) (reg:SI 8))
(set (mem:SI (plus:SI (reg:SI 3) (const_int 12))) (reg:SI 9))
(clobber (reg:SI 10))]
- "TARGET_PROLOG_FUNCTION"
+ "TARGET_PROLOG_FUNCTION && ! TARGET_LONG_CALLS"
"jarl __save_r6_r9,r10"
[(set_attr "length" "4")
(set_attr "cc" "clobber")])
diff --git a/gcc/config/vax/vax.h b/gcc/config/vax/vax.h
index 3b4c54999cc..ad8fb7cc476 100644
--- a/gcc/config/vax/vax.h
+++ b/gcc/config/vax/vax.h
@@ -579,11 +579,11 @@ gen_rtx (PLUS, Pmode, frame, GEN_INT (12))
/* Addressing modes, and classification of registers for them. */
-#define HAVE_POST_INCREMENT
-/* #define HAVE_POST_DECREMENT */
+#define HAVE_POST_INCREMENT 1
+/* #define HAVE_POST_DECREMENT 0 */
-#define HAVE_PRE_DECREMENT
-/* #define HAVE_PRE_INCREMENT */
+#define HAVE_PRE_DECREMENT 1
+/* #define HAVE_PRE_INCREMENT 0 */
/* Macros to check register numbers against specific register classes. */
diff --git a/gcc/config/vax/xm-vax.h b/gcc/config/vax/xm-vax.h
index 219ef2310fa..d7ef168f3cd 100644
--- a/gcc/config/vax/xm-vax.h
+++ b/gcc/config/vax/xm-vax.h
@@ -15,7 +15,8 @@ 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
/* #defines that need visibility everywhere. */
#define FALSE 0
diff --git a/gcc/config/we32k/we32k.h b/gcc/config/we32k/we32k.h
index 07f00107d59..0859ec1cdda 100644
--- a/gcc/config/we32k/we32k.h
+++ b/gcc/config/we32k/we32k.h
@@ -509,11 +509,11 @@ enum reg_class { NO_REGS, GENERAL_REGS,
/* Addressing modes, and classification of registers for them. */
-/* #define HAVE_POST_INCREMENT */
-/* #define HAVE_POST_DECREMENT */
+/* #define HAVE_POST_INCREMENT 0 */
+/* #define HAVE_POST_DECREMENT 0 */
-/* #define HAVE_PRE_DECREMENT */
-/* #define HAVE_PRE_INCREMENT */
+/* #define HAVE_PRE_DECREMENT 0 */
+/* #define HAVE_PRE_INCREMENT 0 */
/* Macros to check register numbers against specific register classes. */
diff --git a/gcc/configure b/gcc/configure
index 806e46f14a1..70e96223dd9 100755
--- a/gcc/configure
+++ b/gcc/configure
@@ -1,7 +1,7 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated automatically using autoconf version 2.12.2
+# Generated automatically using autoconf version 2.13
# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
#
# This configure script is free software; the Free Software Foundation
@@ -42,18 +42,23 @@ ac_help="$ac_help
--disable-haifa don't use the experimental scheduler for the
targets which normally enable it."
ac_help="$ac_help
- --with-fast-fixincludes use a faster fixinclude program (experimental)"
-ac_help="$ac_help
- --enable-init-priority use attributes to assign initialization order
- for static objects.
- --disable-init-priority conform to ISO C++ rules for ordering static objects
- (i.e. initialized in order of declaration). "
-ac_help="$ac_help
--enable-threads enable thread usage for target GCC.
--enable-threads=LIB use LIB thread package for target GCC."
ac_help="$ac_help
--enable-objc-gc enable the use of Boehm's garbage collector with
the GNU Objective-C runtime."
+ac_help="$ac_help
+ --enable-java-gc=TYPE choose garbage collector [boehm]"
+ac_help="$ac_help
+ --enable-dwarf2 enable DWARF2 debugging as default."
+ac_help="$ac_help
+ --enable-nls use Native Language Support (disabled by default)"
+ac_help="$ac_help
+ --disable-nls do not use Native Language Support"
+ac_help="$ac_help
+ --with-included-gettext use the GNU gettext library included here"
+ac_help="$ac_help
+ --with-catgets use catgets functions if available"
# Initialize some variables set by options.
# The variables have the same names as the options, with
@@ -376,7 +381,7 @@ EOF
verbose=yes ;;
-version | --version | --versio | --versi | --vers)
- echo "configure generated by autoconf version 2.12.2"
+ echo "configure generated by autoconf version 2.13"
exit 0 ;;
-with-* | --with-*)
@@ -580,7 +585,7 @@ copy=cp
# - two terminals occur directly after each other
# - the path contains an element with a dot in it
echo $ac_n "checking LIBRARY_PATH variable""... $ac_c" 1>&6
-echo "configure:584: checking LIBRARY_PATH variable" >&5
+echo "configure:589: checking LIBRARY_PATH variable" >&5
case ${LIBRARY_PATH} in
[:\;]* | *[:\;] | *[:\;][:\;]* | *[:\;]. | .[:\;]*| . | *[:\;].[:\;]* )
library_path_setting="contains current directory"
@@ -605,7 +610,7 @@ fi
# - two terminals occur directly after each other
# - the path contains an element with a dot in it
echo $ac_n "checking GCC_EXEC_PREFIX variable""... $ac_c" 1>&6
-echo "configure:609: checking GCC_EXEC_PREFIX variable" >&5
+echo "configure:614: checking GCC_EXEC_PREFIX variable" >&5
case ${GCC_EXEC_PREFIX} in
[:\;]* | *[:\;] | *[:\;][:\;]* | *[:\;]. | .[:\;]*| . | *[:\;].[:\;]* )
gcc_exec_prefix_setting="contains current directory"
@@ -638,17 +643,17 @@ fi
# Check whether --with-ld or --without-ld was given.
if test "${with_ld+set}" = set; then
withval="$with_ld"
- LD="$with_ld"
+ DEFAULT_LINKER="$with_ld"
fi
-if test x"${LD+set}" = x"set"; then
- if test ! -x "$LD"; then
- echo "configure: warning: cannot execute: $LD: check --with-ld or env. var. LD" 1>&2
- elif test "GNU" = `$LD -v </dev/null 2>&1 | sed '1s/^GNU.*/GNU/;q'`; then
+if test x"${DEFAULT_LINKER+set}" = x"set"; then
+ if test ! -x "$DEFAULT_LINKER"; then
+ echo "configure: warning: cannot execute: $DEFAULT_LINKER: check --with-ld or env. var. DEFAULT_LINKER" 1>&2
+ elif test "GNU" = `$DEFAULT_LINKER -v </dev/null 2>&1 | sed '1s/^GNU.*/GNU/;q'`; then
gnu_ld_flag=yes
fi
cat >> confdefs.h <<EOF
-#define DEFAULT_LINKER "$LD"
+#define DEFAULT_LINKER "$DEFAULT_LINKER"
EOF
fi
@@ -666,17 +671,17 @@ fi
# Check whether --with-as or --without-as was given.
if test "${with_as+set}" = set; then
withval="$with_as"
- AS="$with_as"
+ DEFAULT_ASSEMBLER="$with_as"
fi
-if test x"${AS+set}" = x"set"; then
- if test ! -x "$AS"; then
- echo "configure: warning: cannot execute: $AS: check --with-as or env. var. AS" 1>&2
- elif test "GNU" = `$AS -v </dev/null 2>&1 | sed '1s/^GNU.*/GNU/;q'`; then
+if test x"${DEFAULT_ASSEMBLER+set}" = x"set"; then
+ if test ! -x "$DEFAULT_ASSEMBLER"; then
+ echo "configure: warning: cannot execute: $DEFAULT_ASSEMBLER: check --with-as or env. var. DEFAULT_ASSEMBLER" 1>&2
+ elif test "GNU" = `$DEFAULT_ASSEMBLER -v </dev/null 2>&1 | sed '1s/^GNU.*/GNU/;q'`; then
gas_flag=yes
fi
cat >> confdefs.h <<EOF
-#define DEFAULT_ASSEMBLER "$AS"
+#define DEFAULT_ASSEMBLER "$DEFAULT_ASSEMBLER"
EOF
fi
@@ -719,7 +724,10 @@ if test x$local_prefix = x; then
local_prefix=/usr/local
fi
-gxx_include_dir=
+# 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
# Check whether --with-gxx-include-dir or --without-gxx-include-dir was given.
if test "${with_gxx_include_dir+set}" = set; then
@@ -727,17 +735,17 @@ if test "${with_gxx_include_dir+set}" = set; then
case "${withval}" in
yes) { echo "configure: error: bad value ${withval} given for g++ include directory" 1>&2; exit 1; } ;;
no) ;;
-*) gxx_include_dir=$with_gxx_include_dir ;;
+*) gcc_gxx_include_dir=$with_gxx_include_dir ;;
esac
fi
-if test x${gxx_include_dir} = x; then
+if test x${gcc_gxx_include_dir} = x; then
if test x${enable_version_specific_runtime_libs} = xyes; then
- gxx_include_dir='${libsubdir}/include/g++'
+ gcc_gxx_include_dir='${libsubdir}/include/g++'
else
topsrcdir=${srcdir}/.. . ${srcdir}/../config.if
- gxx_include_dir='${prefix}/include/g++'-${libstdcxx_interface}
+ gcc_gxx_include_dir="\$(libsubdir)/\$(unlibsubdir)/..\`echo \$(exec_prefix) | sed -e 's|^\$(prefix)||' -e 's|/[^/]*|/..|g'\`/include/g++"-${libstdcxx_interface}
fi
fi
@@ -772,10 +780,9 @@ fi
if test "${enable_c_cpplib+set}" = set; then
enableval="$enable_c_cpplib"
if test x$enable_c_cpplib != xno; then
- extra_c_objs="${extra_c_objs} cpplib.o cppexp.o cpphash.o cpperror.o"
- extra_c_objs="${extra_c_objs} prefix.o"
- extra_cxx_objs="${extra_cxx_objs} ../cpplib.o ../cppexp.o ../cpphash.o ../cpperror.o ../prefix.o"
- extra_c_flags=-DUSE_CPPLIB=1
+ extra_c_objs="${extra_c_objs} libcpp.a"
+ extra_cxx_objs="${extra_cxx_objs} ../libcpp.a"
+ extra_c_flags="${extra_c_flags} -DUSE_CPPLIB=1"
cpp_main=cppmain
fi
fi
@@ -798,27 +805,6 @@ if test "${enable_haifa+set}" = set; then
:
fi
-# Fast fixincludes
-#
-# This is a work in progress...
-# Check whether --with-fast-fixincludes or --without-fast-fixincludes was given.
-if test "${with_fast_fixincludes+set}" = set; then
- withval="$with_fast_fixincludes"
- fast_fixinc="$with_fast_fixincludes"
-else
- fast_fixinc=no
-fi
-
-
-# Enable init_priority.
-# Check whether --enable-init-priority or --disable-init-priority was given.
-if test "${enable_init_priority+set}" = set; then
- enableval="$enable_init_priority"
- if test x$enable_init_priority != xno; then
- extra_c_flags=-DUSE_INIT_PRIORITY
-fi
-fi
-
# Enable threads
# Pass with no value to take the default
@@ -868,6 +854,25 @@ else
fi
+# Check whether --enable-java-gc or --disable-java-gc was given.
+if test "${enable_java_gc+set}" = set; then
+ enableval="$enable_java_gc"
+
+ JAVAGC=$enableval
+else
+ JAVAGC=boehm
+fi
+
+
+# Check whether --with-dwarf2 or --without-dwarf2 was given.
+if test "${with_dwarf2+set}" = set; then
+ withval="$with_dwarf2"
+ dwarf2="$with_dwarf2"
+else
+ dwarf2=no
+fi
+
+
# Determine the host, build, and target systems
ac_aux_dir=
for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
@@ -916,7 +921,7 @@ else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
fi
echo $ac_n "checking host system type""... $ac_c" 1>&6
-echo "configure:920: checking host system type" >&5
+echo "configure:925: checking host system type" >&5
host_alias=$host
case "$host_alias" in
@@ -937,7 +942,7 @@ host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
echo "$ac_t""$host" 1>&6
echo $ac_n "checking target system type""... $ac_c" 1>&6
-echo "configure:941: checking target system type" >&5
+echo "configure:946: checking target system type" >&5
target_alias=$target
case "$target_alias" in
@@ -955,7 +960,7 @@ target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
echo "$ac_t""$target" 1>&6
echo $ac_n "checking build system type""... $ac_c" 1>&6
-echo "configure:959: checking build system type" >&5
+echo "configure:964: checking build system type" >&5
build_alias=$build
case "$build_alias" in
@@ -982,7 +987,7 @@ test "$host_alias" != "$target_alias" &&
# Extract the first word of "gcc", so it can be a program name with args.
set dummy gcc; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:986: checking for $ac_word" >&5
+echo "configure:991: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -990,7 +995,8 @@ else
ac_cv_prog_CC="$CC" # Let the user override the test.
else
IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
- for ac_dir in $PATH; do
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
test -z "$ac_dir" && ac_dir=.
if test -f $ac_dir/$ac_word; then
ac_cv_prog_CC="gcc"
@@ -1011,7 +1017,7 @@ if test -z "$CC"; then
# Extract the first word of "cc", so it can be a program name with args.
set dummy cc; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1015: checking for $ac_word" >&5
+echo "configure:1021: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -1020,7 +1026,8 @@ else
else
IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
ac_prog_rejected=no
- for ac_dir in $PATH; do
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
test -z "$ac_dir" && ac_dir=.
if test -f $ac_dir/$ac_word; then
if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
@@ -1061,7 +1068,7 @@ fi
# Extract the first word of "cl", so it can be a program name with args.
set dummy cl; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1065: checking for $ac_word" >&5
+echo "configure:1072: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -1069,7 +1076,8 @@ else
ac_cv_prog_CC="$CC" # Let the user override the test.
else
IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
- for ac_dir in $PATH; do
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
test -z "$ac_dir" && ac_dir=.
if test -f $ac_dir/$ac_word; then
ac_cv_prog_CC="cl"
@@ -1092,7 +1100,7 @@ fi
fi
echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
-echo "configure:1096: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+echo "configure:1104: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
ac_ext=c
# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
@@ -1101,12 +1109,14 @@ ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
cross_compiling=$ac_cv_prog_cc_cross
-cat > conftest.$ac_ext <<EOF
-#line 1106 "configure"
+cat > conftest.$ac_ext << EOF
+
+#line 1115 "configure"
#include "confdefs.h"
+
main(){return(0);}
EOF
-if { (eval echo configure:1110: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1120: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
ac_cv_prog_cc_works=yes
# If we can't run a trivial program, we are probably using a cross compiler.
if (./conftest; exit) 2>/dev/null; then
@@ -1120,18 +1130,24 @@ else
ac_cv_prog_cc_works=no
fi
rm -fr conftest*
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
echo "$ac_t""$ac_cv_prog_cc_works" 1>&6
if test $ac_cv_prog_cc_works = no; then
{ echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
fi
echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
-echo "configure:1130: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "configure:1146: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
cross_compiling=$ac_cv_prog_cc_cross
echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
-echo "configure:1135: checking whether we are using GNU C" >&5
+echo "configure:1151: checking whether we are using GNU C" >&5
if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -1140,7 +1156,7 @@ else
yes;
#endif
EOF
-if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1144: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1160: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
ac_cv_prog_gcc=yes
else
ac_cv_prog_gcc=no
@@ -1159,7 +1175,7 @@ ac_test_CFLAGS="${CFLAGS+set}"
ac_save_CFLAGS="$CFLAGS"
CFLAGS=
echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
-echo "configure:1163: checking whether ${CC-cc} accepts -g" >&5
+echo "configure:1179: checking whether ${CC-cc} accepts -g" >&5
if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -1202,7 +1218,7 @@ fi
echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
-echo "configure:1206: checking whether ${MAKE-make} sets \${MAKE}" >&5
+echo "configure:1222: checking whether ${MAKE-make} sets \${MAKE}" >&5
set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@@ -1230,24 +1246,24 @@ fi
echo $ac_n "checking whether a default assembler was specified""... $ac_c" 1>&6
-echo "configure:1234: checking whether a default assembler was specified" >&5
-if test x"${AS+set}" = x"set"; then
+echo "configure:1250: checking whether a default assembler was specified" >&5
+if test x"${DEFAULT_ASSEMBLER+set}" = x"set"; then
if test x"$with_gas" = x"no"; then
- echo "$ac_t""yes ($AS)" 1>&6
+ echo "$ac_t""yes ($DEFAULT_ASSEMBLER)" 1>&6
else
- echo "$ac_t""yes ($AS - GNU as)" 1>&6
+ echo "$ac_t""yes ($DEFAULT_ASSEMBLER - GNU as)" 1>&6
fi
else
echo "$ac_t""no" 1>&6
fi
echo $ac_n "checking whether a default linker was specified""... $ac_c" 1>&6
-echo "configure:1246: checking whether a default linker was specified" >&5
-if test x"${LD+set}" = x"set"; then
+echo "configure:1262: checking whether a default linker was specified" >&5
+if test x"${DEFAULT_LINKER+set}" = x"set"; then
if test x"$with_gnu_ld" = x"no"; then
- echo "$ac_t""yes ($LD)" 1>&6
+ echo "$ac_t""yes ($DEFAULT_LINKER)" 1>&6
else
- echo "$ac_t""yes ($LD - GNU ld)" 1>&6
+ echo "$ac_t""yes ($DEFAULT_LINKER - GNU ld)" 1>&6
fi
else
echo "$ac_t""no" 1>&6
@@ -1259,7 +1275,7 @@ do
# Extract the first word of "$ac_prog", so it can be a program name with args.
set dummy $ac_prog; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1263: checking for $ac_word" >&5
+echo "configure:1279: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_AWK'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -1267,7 +1283,8 @@ else
ac_cv_prog_AWK="$AWK" # Let the user override the test.
else
IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
- for ac_dir in $PATH; do
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
test -z "$ac_dir" && ac_dir=.
if test -f $ac_dir/$ac_word; then
ac_cv_prog_AWK="$ac_prog"
@@ -1290,7 +1307,7 @@ done
# Extract the first word of "flex", so it can be a program name with args.
set dummy flex; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1294: checking for $ac_word" >&5
+echo "configure:1311: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_LEX'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -1298,7 +1315,8 @@ else
ac_cv_prog_LEX="$LEX" # Let the user override the test.
else
IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
- for ac_dir in $PATH; do
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
test -z "$ac_dir" && ac_dir=.
if test -f $ac_dir/$ac_word; then
ac_cv_prog_LEX="flex"
@@ -1323,7 +1341,7 @@ then
*) ac_lib=l ;;
esac
echo $ac_n "checking for yywrap in -l$ac_lib""... $ac_c" 1>&6
-echo "configure:1327: checking for yywrap in -l$ac_lib" >&5
+echo "configure:1345: checking for yywrap in -l$ac_lib" >&5
ac_lib_var=`echo $ac_lib'_'yywrap | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@@ -1331,7 +1349,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-l$ac_lib $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 1335 "configure"
+#line 1353 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@@ -1342,7 +1360,7 @@ int main() {
yywrap()
; return 0; }
EOF
-if { (eval echo configure:1346: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1364: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
@@ -1365,7 +1383,7 @@ fi
fi
echo $ac_n "checking whether ln works""... $ac_c" 1>&6
-echo "configure:1369: checking whether ln works" >&5
+echo "configure:1387: checking whether ln works" >&5
if eval "test \"`echo '$''{'gcc_cv_prog_LN'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -1397,7 +1415,7 @@ else
fi
echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6
-echo "configure:1401: checking whether ln -s works" >&5
+echo "configure:1419: checking whether ln -s works" >&5
if eval "test \"`echo '$''{'gcc_cv_prog_LN_S'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -1429,19 +1447,19 @@ else
fi
echo $ac_n "checking for volatile""... $ac_c" 1>&6
-echo "configure:1433: checking for volatile" >&5
+echo "configure:1451: checking for volatile" >&5
if eval "test \"`echo '$''{'gcc_cv_c_volatile'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1438 "configure"
+#line 1456 "configure"
#include "confdefs.h"
int main() {
volatile int foo;
; return 0; }
EOF
-if { (eval echo configure:1445: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1463: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
gcc_cv_c_volatile=yes
else
@@ -1464,7 +1482,7 @@ fi
# Extract the first word of "ranlib", so it can be a program name with args.
set dummy ranlib; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1468: checking for $ac_word" >&5
+echo "configure:1486: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -1472,7 +1490,8 @@ else
ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
else
IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
- for ac_dir in $PATH; do
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
test -z "$ac_dir" && ac_dir=.
if test -f $ac_dir/$ac_word; then
ac_cv_prog_RANLIB="ranlib"
@@ -1495,7 +1514,7 @@ do
# Extract the first word of "$ac_prog", so it can be a program name with args.
set dummy $ac_prog; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1499: checking for $ac_word" >&5
+echo "configure:1518: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_YACC'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -1503,7 +1522,8 @@ else
ac_cv_prog_YACC="$YACC" # Let the user override the test.
else
IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
- for ac_dir in $PATH; do
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
test -z "$ac_dir" && ac_dir=.
if test -f $ac_dir/$ac_word; then
ac_cv_prog_YACC="$ac_prog"
@@ -1535,7 +1555,7 @@ test -n "$YACC" || YACC="yacc"
# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
# ./install, which can be erroneously created by make from ./install.sh.
echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
-echo "configure:1539: checking for a BSD compatible install" >&5
+echo "configure:1559: checking for a BSD compatible install" >&5
if test -z "$INSTALL"; then
if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@@ -1586,7 +1606,7 @@ test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
-echo "configure:1590: checking how to run the C preprocessor" >&5
+echo "configure:1610: checking how to run the C preprocessor" >&5
# On Suns, sometimes $CPP names a directory.
if test -n "$CPP" && test -d "$CPP"; then
CPP=
@@ -1601,13 +1621,13 @@ else
# On the NeXT, cc -E runs the code through the compiler's parser,
# not just through cpp.
cat > conftest.$ac_ext <<EOF
-#line 1605 "configure"
+#line 1625 "configure"
#include "confdefs.h"
#include <assert.h>
Syntax Error
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1611: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1631: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
:
@@ -1618,13 +1638,13 @@ else
rm -rf conftest*
CPP="${CC-cc} -E -traditional-cpp"
cat > conftest.$ac_ext <<EOF
-#line 1622 "configure"
+#line 1642 "configure"
#include "confdefs.h"
#include <assert.h>
Syntax Error
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1628: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1648: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
:
@@ -1635,13 +1655,13 @@ else
rm -rf conftest*
CPP="${CC-cc} -nologo -E"
cat > conftest.$ac_ext <<EOF
-#line 1639 "configure"
+#line 1659 "configure"
#include "confdefs.h"
#include <assert.h>
Syntax Error
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1645: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1665: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
:
@@ -1666,12 +1686,12 @@ fi
echo "$ac_t""$CPP" 1>&6
echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
-echo "configure:1670: checking for ANSI C header files" >&5
+echo "configure:1690: checking for ANSI C header files" >&5
if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1675 "configure"
+#line 1695 "configure"
#include "confdefs.h"
#include <stdlib.h>
#include <stdarg.h>
@@ -1679,7 +1699,7 @@ else
#include <float.h>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1683: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1703: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
@@ -1696,7 +1716,7 @@ rm -f conftest*
if test $ac_cv_header_stdc = yes; then
# SunOS 4.x string.h does not declare mem*, contrary to ANSI.
cat > conftest.$ac_ext <<EOF
-#line 1700 "configure"
+#line 1720 "configure"
#include "confdefs.h"
#include <string.h>
EOF
@@ -1714,7 +1734,7 @@ fi
if test $ac_cv_header_stdc = yes; then
# ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
cat > conftest.$ac_ext <<EOF
-#line 1718 "configure"
+#line 1738 "configure"
#include "confdefs.h"
#include <stdlib.h>
EOF
@@ -1735,7 +1755,7 @@ if test "$cross_compiling" = yes; then
:
else
cat > conftest.$ac_ext <<EOF
-#line 1739 "configure"
+#line 1759 "configure"
#include "confdefs.h"
#include <ctype.h>
#define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
@@ -1746,7 +1766,7 @@ if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2);
exit (0); }
EOF
-if { (eval echo configure:1750: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:1770: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
:
else
@@ -1770,12 +1790,12 @@ EOF
fi
echo $ac_n "checking whether time.h and sys/time.h may both be included""... $ac_c" 1>&6
-echo "configure:1774: checking whether time.h and sys/time.h may both be included" >&5
+echo "configure:1794: checking whether time.h and sys/time.h may both be included" >&5
if eval "test \"`echo '$''{'ac_cv_header_time'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1779 "configure"
+#line 1799 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <sys/time.h>
@@ -1784,7 +1804,7 @@ int main() {
struct tm *tp;
; return 0; }
EOF
-if { (eval echo configure:1788: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1808: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_header_time=yes
else
@@ -1805,12 +1825,12 @@ EOF
fi
echo $ac_n "checking whether string.h and strings.h may both be included""... $ac_c" 1>&6
-echo "configure:1809: checking whether string.h and strings.h may both be included" >&5
+echo "configure:1829: checking whether string.h and strings.h may both be included" >&5
if eval "test \"`echo '$''{'gcc_cv_header_string'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1814 "configure"
+#line 1834 "configure"
#include "confdefs.h"
#include <string.h>
#include <strings.h>
@@ -1818,7 +1838,7 @@ int main() {
; return 0; }
EOF
-if { (eval echo configure:1822: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1842: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
gcc_cv_header_string=yes
else
@@ -1838,21 +1858,63 @@ EOF
fi
-for ac_hdr in limits.h stddef.h string.h strings.h stdlib.h time.h fcntl.h unistd.h stab.h sys/file.h sys/time.h sys/resource.h sys/param.h sys/times.h wait.h sys/wait.h
+echo $ac_n "checking for sys/wait.h that is POSIX.1 compatible""... $ac_c" 1>&6
+echo "configure:1863: checking for sys/wait.h that is POSIX.1 compatible" >&5
+if eval "test \"`echo '$''{'ac_cv_header_sys_wait_h'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1868 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <sys/wait.h>
+#ifndef WEXITSTATUS
+#define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8)
+#endif
+#ifndef WIFEXITED
+#define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
+#endif
+int main() {
+int s;
+wait (&s);
+s = WIFEXITED (s) ? WEXITSTATUS (s) : 1;
+; return 0; }
+EOF
+if { (eval echo configure:1884: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_header_sys_wait_h=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_header_sys_wait_h=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_header_sys_wait_h" 1>&6
+if test $ac_cv_header_sys_wait_h = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_SYS_WAIT_H 1
+EOF
+
+fi
+
+for ac_hdr in limits.h stddef.h string.h strings.h stdlib.h time.h fcntl.h unistd.h stab.h sys/file.h sys/time.h sys/resource.h sys/param.h sys/times.h sys/stat.h
do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:1846: checking for $ac_hdr" >&5
+echo "configure:1908: checking for $ac_hdr" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1851 "configure"
+#line 1913 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1856: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1918: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
@@ -1882,17 +1944,17 @@ done
# Check for thread headers.
ac_safe=`echo "thread.h" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for thread.h""... $ac_c" 1>&6
-echo "configure:1886: checking for thread.h" >&5
+echo "configure:1948: checking for thread.h" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1891 "configure"
+#line 1953 "configure"
#include "confdefs.h"
#include <thread.h>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1896: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1958: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
@@ -1916,17 +1978,17 @@ fi
ac_safe=`echo "pthread.h" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for pthread.h""... $ac_c" 1>&6
-echo "configure:1920: checking for pthread.h" >&5
+echo "configure:1982: checking for pthread.h" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1925 "configure"
+#line 1987 "configure"
#include "confdefs.h"
#include <pthread.h>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1930: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1992: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
@@ -1953,7 +2015,7 @@ fi
# Extract the first word of "gnatbind", so it can be a program name with args.
set dummy gnatbind; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1957: checking for $ac_word" >&5
+echo "configure:2019: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_gnat'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -1961,7 +2023,8 @@ else
ac_cv_prog_gnat="$gnat" # Let the user override the test.
else
IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
- for ac_dir in $PATH; do
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
test -z "$ac_dir" && ac_dir=.
if test -f $ac_dir/$ac_word; then
ac_cv_prog_gnat="yes"
@@ -1983,12 +2046,12 @@ fi
# See if the system preprocessor understands the ANSI C preprocessor
# stringification operator.
echo $ac_n "checking whether cpp understands the stringify operator""... $ac_c" 1>&6
-echo "configure:1987: checking whether cpp understands the stringify operator" >&5
+echo "configure:2050: checking whether cpp understands the stringify operator" >&5
if eval "test \"`echo '$''{'gcc_cv_c_have_stringify'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1992 "configure"
+#line 2055 "configure"
#include "confdefs.h"
int main() {
@@ -1996,7 +2059,7 @@ int main() {
char *test = S(foo);
; return 0; }
EOF
-if { (eval echo configure:2000: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:2063: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
gcc_cv_c_have_stringify=yes
else
@@ -2019,12 +2082,12 @@ fi
# Use <inttypes.h> only if it exists,
# doesn't clash with <sys/types.h>, and declares intmax_t.
echo $ac_n "checking for inttypes.h""... $ac_c" 1>&6
-echo "configure:2023: checking for inttypes.h" >&5
+echo "configure:2086: checking for inttypes.h" >&5
if eval "test \"`echo '$''{'gcc_cv_header_inttypes_h'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 2028 "configure"
+#line 2091 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <inttypes.h>
@@ -2032,13 +2095,9 @@ int main() {
intmax_t i = -1;
; return 0; }
EOF
-if { (eval echo configure:2036: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:2099: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
- cat >> confdefs.h <<EOF
-#define HAVE_INTTYPES_H 1
-EOF
-
- gcc_cv_header_inttypes_h=yes
+ gcc_cv_header_inttypes_h=yes
else
echo "configure: failed program was:" >&5
cat conftest.$ac_ext >&5
@@ -2049,18 +2108,25 @@ rm -f conftest*
fi
echo "$ac_t""$gcc_cv_header_inttypes_h" 1>&6
+if test $gcc_cv_header_inttypes_h = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_INTTYPES_H 1
+EOF
+
+fi
for ac_func in strtoul bsearch strerror putenv popen bcopy bzero bcmp \
index rindex strchr strrchr kill getrlimit setrlimit atoll atoq \
- sysconf isascii gettimeofday strsignal
+ sysconf isascii gettimeofday strsignal putc_unlocked fputc_unlocked \
+ fputs_unlocked
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:2059: checking for $ac_func" >&5
+echo "configure:2125: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 2064 "configure"
+#line 2130 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -2083,7 +2149,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:2087: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2153: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
@@ -2112,12 +2178,12 @@ done
#AC_CHECK_TYPE(wchar_t, unsigned int)
echo $ac_n "checking for vprintf""... $ac_c" 1>&6
-echo "configure:2116: checking for vprintf" >&5
+echo "configure:2182: checking for vprintf" >&5
if eval "test \"`echo '$''{'ac_cv_func_vprintf'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 2121 "configure"
+#line 2187 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char vprintf(); below. */
@@ -2140,7 +2206,7 @@ vprintf();
; return 0; }
EOF
-if { (eval echo configure:2144: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2210: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_vprintf=yes"
else
@@ -2164,12 +2230,12 @@ fi
if test "$ac_cv_func_vprintf" != yes; then
echo $ac_n "checking for _doprnt""... $ac_c" 1>&6
-echo "configure:2168: checking for _doprnt" >&5
+echo "configure:2234: checking for _doprnt" >&5
if eval "test \"`echo '$''{'ac_cv_func__doprnt'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 2173 "configure"
+#line 2239 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char _doprnt(); below. */
@@ -2192,7 +2258,7 @@ _doprnt();
; return 0; }
EOF
-if { (eval echo configure:2196: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2262: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func__doprnt=yes"
else
@@ -2228,7 +2294,7 @@ fi
echo $ac_n "checking whether the printf functions support %p""... $ac_c" 1>&6
-echo "configure:2232: checking whether the printf functions support %p" >&5
+echo "configure:2298: checking whether the printf functions support %p" >&5
if eval "test \"`echo '$''{'gcc_cv_func_printf_ptr'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -2236,7 +2302,7 @@ else
gcc_cv_func_printf_ptr=no
else
cat > conftest.$ac_ext <<EOF
-#line 2240 "configure"
+#line 2306 "configure"
#include "confdefs.h"
#include <stdio.h>
@@ -2249,7 +2315,7 @@ main()
exit (p != q);
}
EOF
-if { (eval echo configure:2253: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:2319: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
gcc_cv_func_printf_ptr=yes
else
@@ -2273,17 +2339,269 @@ EOF
fi
+case "${host}" in
+*-*-uwin*)
+ # Under some versions of uwin, vfork is notoriously buggy and the test
+ # can hang configure; on other versions, vfork exists just as a stub.
+ # FIXME: This should be removed once vfork in uwin's runtime is fixed.
+ ac_cv_func_vfork_works=no
+ ;;
+esac
+echo $ac_n "checking for pid_t""... $ac_c" 1>&6
+echo "configure:2352: checking for pid_t" >&5
+if eval "test \"`echo '$''{'ac_cv_type_pid_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2357 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "(^|[^a-zA-Z_0-9])pid_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_type_pid_t=yes
+else
+ rm -rf conftest*
+ ac_cv_type_pid_t=no
+fi
+rm -f conftest*
+
+fi
+echo "$ac_t""$ac_cv_type_pid_t" 1>&6
+if test $ac_cv_type_pid_t = no; then
+ cat >> confdefs.h <<\EOF
+#define pid_t int
+EOF
+
+fi
+
+ac_safe=`echo "vfork.h" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for vfork.h""... $ac_c" 1>&6
+echo "configure:2386: checking for vfork.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2391 "configure"
+#include "confdefs.h"
+#include <vfork.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2396: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define HAVE_VFORK_H 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+echo $ac_n "checking for working vfork""... $ac_c" 1>&6
+echo "configure:2421: checking for working vfork" >&5
+if eval "test \"`echo '$''{'ac_cv_func_vfork_works'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ echo $ac_n "checking for vfork""... $ac_c" 1>&6
+echo "configure:2427: checking for vfork" >&5
+if eval "test \"`echo '$''{'ac_cv_func_vfork'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2432 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char vfork(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char vfork();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_vfork) || defined (__stub___vfork)
+choke me
+#else
+vfork();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:2455: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_vfork=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_vfork=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'vfork`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ :
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ac_cv_func_vfork_works=$ac_cv_func_vfork
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2477 "configure"
+#include "confdefs.h"
+/* Thanks to Paul Eggert for this test. */
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_VFORK_H
+#include <vfork.h>
+#endif
+/* On some sparc systems, changes by the child to local and incoming
+ argument registers are propagated back to the parent.
+ The compiler is told about this with #include <vfork.h>,
+ but some compilers (e.g. gcc -O) don't grok <vfork.h>.
+ Test for this by using a static variable whose address
+ is put into a register that is clobbered by the vfork. */
+static
+#ifdef __cplusplus
+sparc_address_test (int arg)
+#else
+sparc_address_test (arg) int arg;
+#endif
+{
+ static pid_t child;
+ if (!child) {
+ child = vfork ();
+ if (child < 0) {
+ perror ("vfork");
+ _exit(2);
+ }
+ if (!child) {
+ arg = getpid();
+ write(-1, "", 0);
+ _exit (arg);
+ }
+ }
+}
+main() {
+ pid_t parent = getpid ();
+ pid_t child;
+
+ sparc_address_test ();
+
+ child = vfork ();
+
+ if (child == 0) {
+ /* Here is another test for sparc vfork register problems.
+ This test uses lots of local variables, at least
+ as many local variables as main has allocated so far
+ including compiler temporaries. 4 locals are enough for
+ gcc 1.40.3 on a Solaris 4.1.3 sparc, but we use 8 to be safe.
+ A buggy compiler should reuse the register of parent
+ for one of the local variables, since it will think that
+ parent can't possibly be used any more in this routine.
+ Assigning to the local variable will thus munge parent
+ in the parent process. */
+ pid_t
+ p = getpid(), p1 = getpid(), p2 = getpid(), p3 = getpid(),
+ p4 = getpid(), p5 = getpid(), p6 = getpid(), p7 = getpid();
+ /* Convince the compiler that p..p7 are live; otherwise, it might
+ use the same hardware register for all 8 local variables. */
+ if (p != p1 || p != p2 || p != p3 || p != p4
+ || p != p5 || p != p6 || p != p7)
+ _exit(1);
+
+ /* On some systems (e.g. IRIX 3.3),
+ vfork doesn't separate parent from child file descriptors.
+ If the child closes a descriptor before it execs or exits,
+ this munges the parent's descriptor as well.
+ Test for this by closing stdout in the child. */
+ _exit(close(fileno(stdout)) != 0);
+ } else {
+ int status;
+ struct stat st;
+
+ while (wait(&status) != child)
+ ;
+ exit(
+ /* Was there some problem with vforking? */
+ child < 0
+
+ /* Did the child fail? (This shouldn't happen.) */
+ || status
+
+ /* Did the vfork/compiler bug occur? */
+ || parent != getpid()
+
+ /* Did the file descriptor bug occur? */
+ || fstat(fileno(stdout), &st) != 0
+ );
+ }
+}
+EOF
+if { (eval echo configure:2572: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ ac_cv_func_vfork_works=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_func_vfork_works=no
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$ac_cv_func_vfork_works" 1>&6
+if test $ac_cv_func_vfork_works = no; then
+ cat >> confdefs.h <<\EOF
+#define vfork fork
+EOF
+
+fi
+
+
for ac_func in malloc realloc calloc free bcopy bzero bcmp \
index rindex getenv atol sbrk abort atof strerror getcwd getwd \
- strsignal
+ strsignal putc_unlocked fputs_unlocked
do
echo $ac_n "checking whether $ac_func must be declared""... $ac_c" 1>&6
-echo "configure:2282: checking whether $ac_func must be declared" >&5
+echo "configure:2600: checking whether $ac_func must be declared" >&5
if eval "test \"`echo '$''{'gcc_cv_decl_needed_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 2287 "configure"
+#line 2605 "configure"
#include "confdefs.h"
#include <stdio.h>
@@ -2316,7 +2634,7 @@ int main() {
char *(*pfn) = (char *(*)) $ac_func
; return 0; }
EOF
-if { (eval echo configure:2320: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:2638: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
eval "gcc_cv_decl_needed_$ac_func=no"
else
@@ -2345,12 +2663,12 @@ done
for ac_func in getrlimit setrlimit
do
echo $ac_n "checking whether $ac_func must be declared""... $ac_c" 1>&6
-echo "configure:2349: checking whether $ac_func must be declared" >&5
+echo "configure:2667: checking whether $ac_func must be declared" >&5
if eval "test \"`echo '$''{'gcc_cv_decl_needed_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 2354 "configure"
+#line 2672 "configure"
#include "confdefs.h"
#include <stdio.h>
@@ -2387,7 +2705,7 @@ int main() {
char *(*pfn) = (char *(*)) $ac_func
; return 0; }
EOF
-if { (eval echo configure:2391: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:2709: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
eval "gcc_cv_decl_needed_$ac_func=no"
else
@@ -2414,12 +2732,12 @@ done
echo $ac_n "checking for sys_siglist declaration in signal.h or unistd.h""... $ac_c" 1>&6
-echo "configure:2418: checking for sys_siglist declaration in signal.h or unistd.h" >&5
+echo "configure:2736: checking for sys_siglist declaration in signal.h or unistd.h" >&5
if eval "test \"`echo '$''{'ac_cv_decl_sys_siglist'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 2423 "configure"
+#line 2741 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <signal.h>
@@ -2431,7 +2749,7 @@ int main() {
char *msg = *(sys_siglist + 1);
; return 0; }
EOF
-if { (eval echo configure:2435: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:2753: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_decl_sys_siglist=yes
else
@@ -2468,6 +2786,9 @@ host_xmake_file=
host_truncate_target=
host_exeext=
+# It is relative to $prefix.
+cpp_install_dir=
+
# Decode the host machine, then the target machine.
# For the host machine, we save the xm_file variable as host_xm_file;
# then we decode the target machine and forget everything else
@@ -2490,10 +2811,6 @@ for machine in $build $host $target; do
use_collect2=
# Set this to override the default target model.
target_cpu_default=
- # Set this to control which fixincludes program to use.
- if test x$fast_fixinc != xyes; then
- fixincludes=fixincludes
- else fixincludes=fixinc.sh ; fi
# Set this to control how the header file directory is installed.
install_headers_dir=install-headers-tar
# Set this to a non-empty list of args to pass to cpp if the target
@@ -2553,11 +2870,23 @@ for machine in $build $host $target; do
tm_file=${cpu_type}/${cpu_type}.h
xm_file=${cpu_type}/xm-${cpu_type}.h
- # Set the default macros to define for GNU/Linux systems.
+ # Common parts for linux-gnu and openbsd systems
case $machine in
*-*-linux-gnu*)
xm_defines="HAVE_ATEXIT POSIX BSTRING"
;;
+ *-*-openbsd*)
+ tm_file=${cpu_type}/openbsd.h
+ # On OpenBSD systems, the headers are okay
+ fixincludes=Makefile.in
+ tmake_file="t-libc-ok t-openbsd"
+ # avoid surprises, always provide an xm-openbsd file
+ xm_file=${cpu_type}/xm-openbsd.h
+ if test x$enable_threads = xyes; then
+ thread_file='posix'
+ tmake_file="${tmake_file} t-openbsd-thread"
+ fi
+ ;;
esac
case $machine in
@@ -2609,7 +2938,6 @@ for machine in $build $host $target; do
target_cpu_default="MASK_GAS"
tmake_file="t-linux t-linux-gnulibc1 alpha/t-linux alpha/t-crtbe"
extra_parts="crtbegin.o crtend.o"
- fixincludes=fixinc.wrap
xmake_file=none
gas=yes gnu_ld=yes
if test x$enable_threads = xyes; then
@@ -2622,21 +2950,25 @@ for machine in $build $host $target; do
tmake_file="t-linux alpha/t-linux alpha/t-crtbe"
extra_parts="crtbegin.o crtend.o"
xmake_file=none
- fixincludes=Makefile.in
gas=yes gnu_ld=yes
if test x$enable_threads = xyes; then
thread_file='posix'
fi
;;
alpha*-*-netbsd*)
- tm_file="${tm_file} alpha/elf.h alpha/netbsd.h alpha/netbsdl-elf.h"
+ tm_file="${tm_file} alpha/elf.h alpha/netbsd.h alpha/netbsd-elf.h"
target_cpu_default="MASK_GAS"
tmake_file="alpha/t-crtbe"
extra_parts="crtbegin.o crtend.o"
xmake_file=none
- fixincludes=fixinc.wrap
gas=yes gnu_ld=yes
;;
+
+ alpha*-*-openbsd*)
+ # default x-alpha is only appropriate for dec-osf.
+ target_cpu_default="MASK_GAS"
+ xmake_file=none
+ ;;
alpha*-dec-osf*)
if test x$stabs = xyes
@@ -2683,7 +3015,6 @@ for machine in $build $host $target; do
xmake_file=winnt/x-winnt
extra_host_objs=oldnames.o
extra_gcc_objs="spawnv.o oldnames.o"
- fixincludes=fixinc.winnt
if test x$gnu_ld != xyes
then
extra_programs=ld.exe
@@ -2696,7 +3027,6 @@ for machine in $build $host $target; do
tm_file=alpha/vms.h
xm_file="${xm_file} alpha/xm-vms.h"
tmake_file=alpha/t-vms
- fixincludes=Makefile.in
;;
arc-*-elf*)
extra_parts="crtinit.o crtfini.o"
@@ -2705,6 +3035,10 @@ for machine in $build $host $target; do
tm_file=arm/coff.h
tmake_file=arm/t-bare
;;
+ arm-*-vxworks*)
+ tm_file=arm/vxarm.h
+ tmake_file=arm/t-bare
+ ;;
arm-*-riscix1.[01]*) # Acorn RISC machine (early versions)
tm_file=arm/riscix1-1.h
use_collect2=yes
@@ -2723,56 +3057,78 @@ for machine in $build $host $target; do
arm-semi-aout | armel-semi-aout)
tm_file=arm/semi.h
tmake_file=arm/t-semi
- fixincludes=Makefile.in # There is nothing to fix
;;
arm-semi-aof | armel-semi-aof)
tm_file=arm/semiaof.h
tmake_file=arm/t-semiaof
- fixincludes=Makefile.in # There is nothing to fix
;;
arm*-*-netbsd*)
tm_file=arm/netbsd.h
xm_file="arm/xm-netbsd.h ${xm_file}"
tmake_file="t-netbsd arm/t-netbsd"
- # On NetBSD, the headers are already okay, except for math.h.
- fixincludes=fixinc.wrap
;;
- arm-*-linux-gnuaout*) # ARM GNU/Linux
+ arm*-*-linux-gnuaout*) # ARM GNU/Linux with a.out
cpu_type=arm
xmake_file=x-linux
- tm_file=arm/linux-gas.h
+ tm_file=arm/linux-aout.h
tmake_file=arm/t-linux
- fixincludes=Makefile.in
gnu_ld=yes
;;
- arm-*-aout)
+ arm*-*-linux-gnu*) # ARM GNU/Linux with ELF
+ xm_file=arm/xm-linux.h
+ xmake_file=x-linux
+ case $machine in
+ armv2*-*-*)
+ tm_file=arm/linux-elf26.h
+ ;;
+ *)
+ tm_file=arm/linux-elf.h
+ ;;
+ esac
+ tmake_file="t-linux arm/t-linux"
+ extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o"
+ gnu_ld=yes
+ case x${enable_threads} in
+ x | xyes | xpthreads | xposix)
+ thread_file='posix'
+ ;;
+ esac
+ ;;
+ arm*-*-aout)
tm_file=arm/aout.h
tmake_file=arm/t-bare
;;
+ arm*-*-ecos-elf)
+ tm_file=arm/ecos-elf.h
+ tmake_file=arm/t-elf
+ ;;
+ arm*-*-elf)
+ tm_file=arm/unknown-elf.h
+ tmake_file=arm/t-arm-elf
+ ;;
+ arm*-*-oabi)
+ tm_file=arm/unknown-elf-oabi.h
+ tmake_file=arm/t-arm-elf
+ ;;
c1-convex-*) # Convex C1
target_cpu_default=1
use_collect2=yes
- fixincludes=Makefile.in
;;
c2-convex-*) # Convex C2
target_cpu_default=2
use_collect2=yes
- fixincludes=Makefile.in
;;
c32-convex-*)
target_cpu_default=4
use_collect2=yes
- fixincludes=Makefile.in
;;
c34-convex-*)
target_cpu_default=8
use_collect2=yes
- fixincludes=Makefile.in
;;
c38-convex-*)
target_cpu_default=16
use_collect2=yes
- fixincludes=Makefile.in
;;
c4x-*)
cpu_type=c4x
@@ -2797,16 +3153,19 @@ for machine in $build $host $target; do
h8300-*-*)
float_format=i32
;;
+ hppa*-*-openbsd*)
+ target_cpu_default="MASK_SNAKE"
+ tmake_file=pa/t-openbsd
+ ;;
hppa1.1-*-pro*)
tm_file="pa/pa-pro.h ${tm_file} pa/pa-pro-end.h libgloss.h"
xm_file=pa/xm-papro.h
tmake_file=pa/t-pro
;;
hppa1.1-*-osf*)
- target_cpu_default=1
+ target_cpu_default="MASK_SNAKE"
tm_file="${tm_file} pa/pa-osf.h"
use_collect2=yes
- fixincludes=Makefile.in
;;
hppa1.1-*-rtems*)
tm_file="pa/pa-pro.h ${tm_file} pa/pa-pro-end.h libgloss.h pa/rtems.h"
@@ -2816,16 +3175,13 @@ for machine in $build $host $target; do
hppa1.0-*-osf*)
tm_file="${tm_file} pa/pa-osf.h"
use_collect2=yes
- fixincludes=Makefile.in
;;
hppa1.1-*-bsd*)
- target_cpu_default=1
+ target_cpu_default="MASK_SNAKE"
use_collect2=yes
- fixincludes=Makefile.in
;;
hppa1.0-*-bsd*)
use_collect2=yes
- fixincludes=Makefile.in
;;
hppa1.0-*-hpux7*)
tm_file="pa/pa-oldas.h ${tm_file} pa/pa-hpux7.h"
@@ -2852,7 +3208,7 @@ for machine in $build $host $target; do
use_collect2=yes
;;
hppa1.1-*-hpux8.0[0-2]*)
- target_cpu_default=1
+ target_cpu_default="MASK_SNAKE"
tm_file="${tm_file} pa/pa-hpux.h"
xm_file=pa/xm-pahpux.h
xmake_file=pa/x-pa-hpux
@@ -2866,7 +3222,7 @@ for machine in $build $host $target; do
use_collect2=yes
;;
hppa1.1-*-hpux8*)
- target_cpu_default=1
+ target_cpu_default="MASK_SNAKE"
tm_file="${tm_file} pa/pa-hpux.h"
xm_file=pa/xm-pahpux.h
xmake_file=pa/x-pa-hpux
@@ -2888,8 +3244,8 @@ for machine in $build $host $target; do
install_headers_dir=install-headers-cpio
use_collect2=yes
;;
- hppa1.1-*-hpux10*)
- target_cpu_default=1
+ hppa1.1-*-hpux10* | hppa2*-*-hpux10*)
+ target_cpu_default="MASK_SNAKE"
tm_file="${tm_file} pa/pa-hpux.h pa/pa-hpux10.h"
xm_file=pa/xm-pahpux.h
xmake_file=pa/x-pa-hpux
@@ -2912,6 +3268,7 @@ for machine in $build $host $target; do
tm_file="${tm_file} pa/pa-hpux.h pa/pa-hpux10.h"
xm_file=pa/xm-pahpux.h
xmake_file=pa/x-pa-hpux
+ tmake_file=pa/t-pa
if test x$gas = xyes
then
tm_file="${tm_file} pa/pa-gas.h"
@@ -2926,8 +3283,8 @@ for machine in $build $host $target; do
install_headers_dir=install-headers-cpio
use_collect2=yes
;;
- hppa1.1-*-hpux*)
- target_cpu_default=1
+ hppa1.1-*-hpux* | hppa2*-*-hpux*)
+ target_cpu_default="MASK_SNAKE"
tm_file="${tm_file} pa/pa-hpux.h pa/pa-hpux9.h"
xm_file=pa/xm-pahpux.h
xmake_file=pa/x-pa-hpux
@@ -2949,8 +3306,8 @@ for machine in $build $host $target; do
install_headers_dir=install-headers-cpio
use_collect2=yes
;;
- hppa1.1-*-hiux*)
- target_cpu_default=1
+ hppa1.1-*-hiux* | hppa2*-*-hiux*)
+ target_cpu_default="MASK_SNAKE"
tm_file="${tm_file} pa/pa-hpux.h pa/pa-hiux.h"
xm_file=pa/xm-pahpux.h
xmake_file=pa/x-pa-hpux
@@ -2973,9 +3330,8 @@ for machine in $build $host $target; do
use_collect2=yes
;;
hppa*-*-lites*)
- target_cpu_default=1
+ target_cpu_default="MASK_SNAKE"
use_collect2=yes
- fixincludes=Makefile.in
;;
i370-*-mvs*)
;;
@@ -3031,7 +3387,6 @@ for machine in $build $host $target; do
xmake_file=i386/x-sysv3
tm_file=i386/seq-sysv3.h
tmake_file=i386/t-crtstuff
- fixincludes=fixinc.ptx
extra_parts="crtbegin.o crtend.o"
install_headers_dir=install-headers-cpio
;;
@@ -3041,7 +3396,6 @@ for machine in $build $host $target; do
tm_file=i386/seq2-sysv3.h
tmake_file=i386/t-crtstuff
extra_parts="crtbegin.o crtend.o"
- fixincludes=fixinc.ptx
install_headers_dir=install-headers-cpio
;;
i[34567]86-sequent-ptx4* | i[34567]86-sequent-sysv4*)
@@ -3051,7 +3405,6 @@ for machine in $build $host $target; do
tm_file=i386/ptx4-i.h
tmake_file=t-svr4
extra_parts="crtbegin.o crtend.o"
- fixincludes=fixinc.ptx
install_headers_dir=install-headers-cpio
;;
i386-sun-sunos*) # Sun i386 roadrunner
@@ -3081,6 +3434,7 @@ for machine in $build $host $target; do
tm_file="i386/i386.h i386/att.h linux.h i386/freebsd-elf.h i386/perform.h"
# On FreeBSD, the headers are already ok, except for math.h.
fixincludes=fixinc.wrap
+ extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o"
tmake_file=i386/t-freebsd
gas=yes
gnu_ld=yes
@@ -3088,18 +3442,17 @@ for machine in $build $host $target; do
;;
i[34567]86-*-freebsd*)
tm_file=i386/freebsd.h
- # On FreeBSD, the headers are already ok, except for math.h.
- fixincludes=fixinc.wrap
tmake_file=i386/t-freebsd
;;
- # We are hoping OpenBSD is still close enough to NetBSD that we can
- # share the configurations.
- i[34567]86-*-netbsd* | i[34567]86-*-openbsd*)
+ i[34567]86-*-netbsd*)
tm_file=i386/netbsd.h
- # On NetBSD, the headers are already okay, except for math.h.
- fixincludes=fixinc.wrap
tmake_file=t-netbsd
;;
+ i[34567]86-*-openbsd*)
+ # Remove when the math emulator is fixed
+ # we need collect2 until our bug is fixed...
+ use_collect2=yes
+ ;;
i[34567]86-*-coff*)
tm_file=i386/i386-coff.h
tmake_file=i386/t-i386bare
@@ -3132,7 +3485,6 @@ for machine in $build $host $target; do
xmake_file=x-linux-aout
tmake_file="t-linux-aout i386/t-crtstuff"
tm_file=i386/linux-oldld.h
- fixincludes=Makefile.in #On Linux, the headers are ok already.
gnu_ld=yes
float_format=i386
;;
@@ -3140,7 +3492,6 @@ for machine in $build $host $target; do
xmake_file=x-linux-aout
tmake_file="t-linux-aout i386/t-crtstuff"
tm_file=i386/linux-aout.h
- fixincludes=Makefile.in #On Linux, the headers are ok already.
gnu_ld=yes
float_format=i386
;;
@@ -3150,7 +3501,6 @@ for machine in $build $host $target; do
tm_file=i386/linux.h
tmake_file="t-linux t-linux-gnulibc1 i386/t-crtstuff"
extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o"
- fixincludes=Makefile.in #On Linux, the headers are ok already.
gnu_ld=yes
float_format=i386
if test x$enable_threads = xyes; then
@@ -3163,7 +3513,6 @@ for machine in $build $host $target; do
tm_file=i386/linux.h
tmake_file="t-linux i386/t-crtstuff"
extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o"
- fixincludes=Makefile.in #On Linux, the headers are ok already.
gnu_ld=yes
float_format=i386
if test x$enable_threads = xyes; then
@@ -3173,23 +3522,28 @@ for machine in $build $host $target; do
i[34567]86-*-gnu*)
;;
i[34567]86-*-gnu*)
+ float_format=i386
;;
i[34567]86-go32-msdos | i[34567]86-*-go32*)
- xm_file=i386/xm-go32.h
- tm_file=i386/go32.h
- tmake_file=i386/t-go32
+ echo "GO32/DJGPP V1.X is no longer supported. Use *-pc-msdosdjgpp for DJGPP V2.X instead."
+ exit 1
;;
i[34567]86-pc-msdosdjgpp*)
- xm_file=i386/xm-go32.h
- tm_file=i386/go32.h
- tmake_file=i386/t-go32
+ xm_file=i386/xm-djgpp.h
+ tm_file=i386/djgpp.h
+ tmake_file=i386/t-djgpp
+ xmake_file=i386/x-djgpp
gnu_ld=yes
gas=yes
+ exeext=.exe
+ case $host in *pc-msdosdjgpp*)
+ target_alias=djgpp
+ ;;
+ esac
;;
i[34567]86-moss-msdos* | i[34567]86-*-moss*)
tm_file=i386/moss.h
tmake_file=t-libc-ok
- fixincludes=Makefile.in
gnu_ld=yes
gas=yes
;;
@@ -3243,7 +3597,6 @@ for machine in $build $host $target; do
xm_file="xm-siglist.h xm-alloca.h ${xm_file} i386/xm-sco5.h"
xm_defines="USG SVR3"
xmake_file=i386/x-sco5
- fixincludes=fixinc.sco
install_headers_dir=install-headers-cpio
tm_file=i386/sco5.h
if test x$gas = xyes
@@ -3253,13 +3606,12 @@ for machine in $build $host $target; do
else
tmake_file=i386/t-sco5
fi
- extra_parts="crtbegin.o crtend.o crtbeginS.o crtendS.o"
+ extra_parts="crti.o crtbegin.o crtend.o crtbeginS.o crtendS.o"
;;
i[34567]86-*-sco3.2v4*) # 80386 running SCO 3.2v4 system
xm_file="${xm_file} i386/xm-sco.h"
xm_defines="USG SVR3 BROKEN_LDEXP SMALL_ARG_MAX NO_SYS_SIGLIST"
xmake_file=i386/x-sco4
- fixincludes=fixinc.sco
install_headers_dir=install-headers-cpio
if test x$stabs = xyes
then
@@ -3301,12 +3653,6 @@ for machine in $build $host $target; do
tmake_file=i386/t-sol2
extra_parts="crt1.o crti.o crtn.o gcrt1.o gmon.o crtbegin.o crtend.o"
xmake_file=x-svr4
- case $machine in
- *-*-solaris2.[0-4])
- fixincludes=fixinc.svr4;;
- *)
- fixincludes=fixinc.wrap;;
- esac
if test x$enable_threads = xyes; then
thread_file='solaris'
fi
@@ -3322,7 +3668,6 @@ for machine in $build $host $target; do
tmake_file=i386/t-crtpic
xmake_file=x-svr4
extra_parts="crtbegin.o crtend.o"
- fixincludes=fixinc.svr4
;;
i[34567]86-*-sysv4*) # Intel 80386's running system V.4
xm_file="xm-siglist.h xm-alloca.h ${xm_file}"
@@ -3343,13 +3688,11 @@ for machine in $build $host $target; do
tmake_file="i386/t-crtpic i386/t-udk"
xmake_file=x-svr4
extra_parts="crtbegin.o crtend.o"
- fixincludes="fixinc.svr4"
;;
i[34567]86-*-osf1*) # Intel 80386's running OSF/1 1.3+
cpu_type=i386
xm_file="${xm_file} xm-svr4.h i386/xm-sysv4.h i386/xm-osf1elf.h"
xm_defines="USE_C_ALLOCA SMALL_ARG_MAX"
- fixincludes=Makefile.in #Don't do it on OSF/1
if test x$stabs = xyes
then
tm_file=i386/osf1elfgdb.h
@@ -3388,24 +3731,22 @@ for machine in $build $host $target; do
xmake_file=i386/x-vsta
;;
i[34567]86-*-win32)
- xm_file="${xm_file} i386/xm-cygwin32.h"
- tmake_file=i386/t-cygwin32
+ xm_file="${xm_file} i386/xm-cygwin.h"
+ tmake_file=i386/t-cygwin
tm_file=i386/win32.h
- xmake_file=i386/x-cygwin32
+ xmake_file=i386/x-cygwin
extra_objs=winnt.o
- fixincludes=Makefile.in
if test x$enable_threads = xyes; then
thread_file='win32'
fi
exeext=.exe
;;
- i[34567]86-*-pe | i[34567]86-*-cygwin32)
- xm_file="${xm_file} i386/xm-cygwin32.h"
- tmake_file=i386/t-cygwin32
- tm_file=i386/cygwin32.h
- xmake_file=i386/x-cygwin32
+ i[34567]86-*-pe | i[34567]86-*-cygwin*)
+ xm_file="${xm_file} i386/xm-cygwin.h"
+ tmake_file=i386/t-cygwin
+ tm_file=i386/cygwin.h
+ xmake_file=i386/x-cygwin
extra_objs=winnt.o
- fixincludes=Makefile.in
if test x$enable_threads = xyes; then
thread_file='win32'
fi
@@ -3414,10 +3755,9 @@ for machine in $build $host $target; do
i[34567]86-*-mingw32*)
tm_file=i386/mingw32.h
xm_file="${xm_file} i386/xm-mingw32.h"
- tmake_file="i386/t-cygwin32 i386/t-mingw32"
+ tmake_file="i386/t-cygwin i386/t-mingw32"
extra_objs=winnt.o
- xmake_file=i386/x-cygwin32
- fixincludes=Makefile.in
+ xmake_file=i386/x-cygwin
if test x$enable_threads = xyes; then
thread_file='win32'
fi
@@ -3430,6 +3770,34 @@ for machine in $build $host $target; do
;;
esac
;;
+ i[34567]86-*-uwin*)
+ tm_file=i386/uwin.h
+ xm_file="${xm_file} i386/xm-uwin.h"
+ xm_defines="USG NO_STAB_H NO_SYS_SIGLIST"
+ tmake_file="i386/t-cygwin i386/t-uwin"
+ extra_objs=winnt.o
+ xmake_file=i386/x-cygwin
+ fixincludes=Makefile.in
+ if test x$enable_threads = xyes; then
+ thread_file='win32'
+ fi
+ exeext=.exe
+ ;;
+ i[34567]86-*-interix*)
+ tm_file=i386/interix.h
+ xm_file="${xm_file} xm-interix.h"
+ xm_defines="USG NO_SYS_SIGLIST"
+ tmake_file="i386/t-interix"
+ extra_objs=interix.o
+ xmake_file=x-interix
+ fixincludes=fixinc.interix
+ if [ x$enable_threads = xyes ]; then
+ thread_file='posix'
+ fi
+ if [ x$stabs = xyes ]; then
+ tm_file="${tm_file} dbxcoff.h"
+ fi
+ ;;
i[34567]86-*-winnt3*)
tm_file=i386/win-nt.h
out_file=i386/i386.c
@@ -3438,7 +3806,6 @@ for machine in $build $host $target; do
tmake_file=i386/t-winnt
extra_host_objs="winnt.o oldnames.o"
extra_gcc_objs="spawnv.o oldnames.o"
- fixincludes=fixinc.winnt
if test x$gnu_ld != xyes
then
extra_programs=ld.exe
@@ -3454,7 +3821,6 @@ for machine in $build $host $target; do
tm_file=i386/dgux.h
tmake_file=i386/t-dgux
xmake_file=i386/x-dgux
- fixincludes=fixinc.dgux
install_headers_dir=install-headers-cpio
;;
i860-alliant-*) # Alliant FX/2800
@@ -3867,6 +4233,12 @@ for machine in $build $host $target; do
extra_headers=math-68881.h
float_format=m68k
;;
+ m68020-*-elf* | m68k-*-elf*)
+ tm_file="m68k/m68020-elf.h libgloss.h"
+ xm_file=m68k/xm-m68kv.h
+ tmake_file=m68k/t-m68kelf
+ header_files=math-68881.h
+ ;;
m68k-*-lynxos*)
if test x$gas = xyes
then
@@ -3882,11 +4254,14 @@ for machine in $build $host $target; do
;;
m68k*-*-netbsd*)
tm_file=m68k/netbsd.h
- # On NetBSD, the headers are already okay, except for math.h.
- fixincludes=fixinc.wrap
tmake_file=t-netbsd
float_format=m68k
;;
+ m68k*-*-openbsd*)
+ float_format=m68k
+ # we need collect2 until our bug is fixed...
+ use_collect2=yes
+ ;;
m68k-*-sysv3*) # Motorola m68k's running system V.3
xm_file="xm-alloca.h ${xm_file}"
xm_defines=USG
@@ -3909,7 +4284,6 @@ for machine in $build $host $target; do
xmake_file=x-linux
tm_file=m68k/linux-aout.h
tmake_file="t-linux-aout m68k/t-linux-aout"
- fixincludes=Makefile.in # The headers are ok already.
extra_headers=math-68881.h
float_format=m68k
gnu_ld=yes
@@ -3921,7 +4295,6 @@ for machine in $build $host $target; do
tm_file=m68k/linux.h
tmake_file="t-linux t-linux-gnulibc1 m68k/t-linux"
extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o"
- fixincludes=Makefile.in # The headers are ok already.
extra_headers=math-68881.h
float_format=m68k
gnu_ld=yes
@@ -3933,7 +4306,6 @@ for machine in $build $host $target; do
tm_file=m68k/linux.h
tmake_file="t-linux m68k/t-linux"
extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o"
- fixincludes=Makefile.in # The headers are ok already.
extra_headers=math-68881.h
float_format=m68k
gnu_ld=yes
@@ -3971,7 +4343,6 @@ for machine in $build $host $target; do
then
tmake_file=m88k/t-dgux-gas
fi
- fixincludes=fixinc.dgux
;;
m88k-dolphin-sysv3*)
tm_file=m88k/dolph.h
@@ -4010,6 +4381,9 @@ for machine in $build $host $target; do
tmake_file=m88k/t-luna
fi
;;
+ m88k-*-openbsd*)
+ tmake_file="${tmake_file} m88k/t-luna-gas"
+ ;;
m88k-*-sysv3*)
tm_file=m88k/sysv3.h
extra_parts="crtbegin.o crtend.o"
@@ -4029,7 +4403,6 @@ for machine in $build $host $target; do
mips-sgi-irix6*) # SGI System V.4., IRIX 6
tm_file=mips/iris6.h
xm_file=mips/xm-iris6.h
- fixincludes=fixinc.irix
xmake_file=mips/x-iris6
tmake_file=mips/t-iris6
# if test x$enable_threads = xyes; then
@@ -4042,13 +4415,12 @@ for machine in $build $host $target; do
gas=yes
gnu_ld=yes
extra_parts="crtbegin.o crtend.o"
-# thread_file='vxworks'
+ thread_file='vxworks'
;;
mips-sgi-irix5cross64) # Irix5 host, Irix 6 target, cross64
tm_file="mips/iris6.h mips/cross64.h"
xm_defines=USG
xm_file="mips/xm-iris5.h"
- fixincludes=Makefile.in
xmake_file=mips/x-iris
tmake_file=mips/t-cross64
# See comment in mips/iris[56].h files.
@@ -4090,7 +4462,6 @@ for machine in $build $host $target; do
fi
xm_defines=USG
xm_file="mips/xm-iris5.h"
- fixincludes=fixinc.irix
xmake_file=mips/x-iris
# mips-tfile doesn't work yet
tmake_file=mips/t-mips-gas
@@ -4190,7 +4561,6 @@ for machine in $build $host $target; do
;;
mips-dec-bsd*) # Decstation running 4.4 BSD
tm_file=mips/dec-bsd.h
- fixincludes=
if test x$gas = xyes
then
tmake_file=mips/t-mips-gas
@@ -4206,9 +4576,30 @@ for machine in $build $host $target; do
mipsel-*-netbsd* | mips-dec-netbsd*) # Decstation running NetBSD
tm_file=mips/netbsd.h
# On NetBSD, the headers are already okay, except for math.h.
- fixincludes=fixinc.wrap
tmake_file=t-netbsd
;;
+ mips*-*-linux*) # Linux MIPS, either endian.
+ xmake_file=x-linux
+ xm_file="xm-siglist.h ${xm_file}"
+ case $machine in
+ mipsel-*) tm_file="mips/elfl.h mips/linux.h" ;;
+ *) tm_file="mips/elf.h mips/linux.h" ;;
+ esac
+ extra_parts="crtbegin.o crtend.o"
+ gnu_ld=yes
+ gas=yes
+ fixincludes=Makefile.in
+ ;;
+ mips*el-*-openbsd*) # mips little endian
+ target_cpu_default="MASK_GAS|MASK_ABICALLS"
+ tm_file=mips/openbsd.h
+ xmake_file=none
+ ;;
+ mips*-*-openbsd*) # mips big endian
+ target_cpu_default="MASK_GAS|MASK_ABICALLS"
+ tm_file=mips/openbsd-be.h
+ xmake_file=none
+ ;;
mips-sony-bsd* | mips-sony-newsos*) # Sony NEWS 3600 or risc/news.
tm_file="mips/news4.h ${tm_file}"
if test x$stabs = xyes; then
@@ -4539,7 +4930,6 @@ for machine in $build $host $target; do
tm_file=ns32k/netbsd.h
xm_file="ns32k/xm-netbsd.h ${xm_file}"
# On NetBSD, the headers are already okay, except for math.h.
- fixincludes=fixinc.wrap
tmake_file=t-netbsd
;;
pdp11-*-bsd)
@@ -4547,6 +4937,9 @@ for machine in $build $host $target; do
;;
pdp11-*-*)
;;
+ ns32k-*-openbsd*)
+ # Nothing special
+ ;;
pyramid-*-*)
cpu_type=pyr
xmake_file=pyr/x-pyr
@@ -4559,6 +4952,13 @@ for machine in $build $host $target; do
xmake_file=romp/x-mach
use_collect2=yes
;;
+ romp-*-openbsd*)
+ # Nothing special
+ ;;
+ powerpc-*-openbsd*)
+ tmake_file="${tmake_file} rs6000/t-rs6000 rs6000/t-openbsd"
+ xmake_file=none
+ ;;
powerpc-*-beos*)
cpu_type=rs6000
tm_file=rs6000/beos.h
@@ -4582,13 +4982,11 @@ for machine in $build $host $target; do
powerpc-*-eabiaix*)
tm_file=rs6000/eabiaix.h
tmake_file="rs6000/t-ppcgas rs6000/t-ppccomm"
- fixincludes=Makefile.in
extra_headers=ppc-asm.h
;;
powerpc-*-eabisim*)
tm_file=rs6000/eabisim.h
tmake_file="rs6000/t-ppcgas rs6000/t-ppccomm"
- fixincludes=Makefile.in
extra_headers=ppc-asm.h
;;
powerpc-*-eabi*)
@@ -4599,7 +4997,6 @@ for machine in $build $host $target; do
else
tmake_file="rs6000/t-ppc rs6000/t-ppccomm"
fi
- fixincludes=Makefile.in
extra_headers=ppc-asm.h
;;
powerpc-*-rtems*)
@@ -4610,7 +5007,6 @@ for machine in $build $host $target; do
else
tmake_file="rs6000/t-ppc t-rtems rs6000/t-ppccomm"
fi
- fixincludes=Makefile.in
extra_headers=ppc-asm.h
;;
powerpc-*-linux-gnulibc1)
@@ -4624,7 +5020,6 @@ for machine in $build $host $target; do
tmake_file="rs6000/t-ppc t-linux t-linux-gnulibc1 rs6000/t-ppccomm"
fi
xmake_file=x-linux
- fixincludes=Makefile.in
extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o"
extra_headers=ppc-asm.h
if test x$enable_threads = xyes; then
@@ -4643,7 +5038,6 @@ for machine in $build $host $target; do
tmake_file="rs6000/t-ppc t-linux rs6000/t-ppccomm"
fi
xmake_file=x-linux
- fixincludes=Makefile.in
extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o"
extra_headers=ppc-asm.h
if test x$enable_threads = xyes; then
@@ -4675,7 +5069,6 @@ for machine in $build $host $target; do
powerpcle-*-eabisim*)
tm_file=rs6000/eabilesim.h
tmake_file="rs6000/t-ppcgas rs6000/t-ppccomm"
- fixincludes=Makefile.in
extra_headers=ppc-asm.h
;;
powerpcle-*-eabi*)
@@ -4686,26 +5079,23 @@ for machine in $build $host $target; do
else
tmake_file="rs6000/t-ppc rs6000/t-ppccomm"
fi
- fixincludes=Makefile.in
extra_headers=ppc-asm.h
;;
powerpcle-*-winnt* )
tm_file=rs6000/win-nt.h
tmake_file=rs6000/t-winnt
# extra_objs=pe.o
- fixincludes=Makefile.in
if test x$enable_threads = xyes; then
thread_file='win32'
fi
extra_headers=ppc-asm.h
;;
- powerpcle-*-pe | powerpcle-*-cygwin32)
- tm_file=rs6000/cygwin32.h
- xm_file="rs6000/xm-cygwin32.h ${xm_file}"
+ powerpcle-*-pe | powerpcle-*-cygwin*)
+ tm_file=rs6000/cygwin.h
+ xm_file="rs6000/xm-cygwin.h ${xm_file}"
tmake_file=rs6000/t-winnt
- xmake_file=rs6000/x-cygwin32
+ xmake_file=rs6000/x-cygwin
# extra_objs=pe.o
- fixincludes=Makefile.in
if test x$enable_threads = xyes; then
thread_file='win32'
fi
@@ -4723,17 +5113,12 @@ for machine in $build $host $target; do
tmake_file="rs6000/t-ppc rs6000/t-ppccomm"
fi
xmake_file=rs6000/x-sysv4
- case $machine in
- *-*-solaris2.[0-4])
- fixincludes=fixinc.svr4;;
- *)
- fixincludes=fixinc.wrap;;
- esac
extra_headers=ppc-asm.h
;;
rs6000-ibm-aix3.[01]*)
tm_file=rs6000/aix31.h
xmake_file=rs6000/x-aix31
+ float_format=none
use_collect2=yes
;;
rs6000-ibm-aix3.2.[456789]* | powerpc-ibm-aix3.2.[456789]*)
@@ -4744,10 +5129,16 @@ for machine in $build $host $target; do
else
tmake_file=rs6000/t-newas
fi
+ float_format=none
use_collect2=yes
;;
rs6000-ibm-aix4.[12]* | powerpc-ibm-aix4.[12]*)
- tm_file=rs6000/aix41.h
+ if test "$gnu_ld" = yes
+ then
+ tm_file=rs6000/aix41-gld.h
+ else
+ tm_file=rs6000/aix41.h
+ fi
if test x$host != x$target
then
tmake_file=rs6000/t-xnewas
@@ -4755,6 +5146,7 @@ for machine in $build $host $target; do
tmake_file=rs6000/t-newas
fi
xmake_file=rs6000/x-aix41
+ float_format=none
use_collect2=yes
;;
rs6000-ibm-aix4.[3456789].* | powerpc-ibm-aix4.[3456789].*)
@@ -4766,6 +5158,7 @@ for machine in $build $host $target; do
tmake_file=rs6000/t-aix43
fi
xmake_file=rs6000/x-aix43
+ float_format=none
use_collect2=yes
;;
rs6000-ibm-aix[56789].* | powerpc-ibm-aix[56789].*)
@@ -4777,12 +5170,15 @@ for machine in $build $host $target; do
tmake_file=rs6000/t-aix43
fi
xmake_file=rs6000/x-aix43
+ float_format=none
use_collect2=yes
;;
rs6000-ibm-aix*)
+ float_format=none
use_collect2=yes
;;
rs6000-bull-bosx)
+ float_format=none
use_collect2=yes
;;
rs6000-*-mach*)
@@ -4832,10 +5228,12 @@ for machine in $build $host $target; do
;;
sparc-*-netbsd*)
tm_file=sparc/netbsd.h
- # On NetBSD, the headers are already okay, except for math.h.
- fixincludes=fixinc.wrap
tmake_file=t-netbsd
;;
+ sparc-*-openbsd*)
+ # we need collect2 until our bug is fixed...
+ use_collect2=yes
+ ;;
sparc-*-bsd*)
tm_file=sparc/bsd.h
;;
@@ -4850,7 +5248,6 @@ for machine in $build $host $target; do
xm_file="${xm_file} sparc/xm-linux.h"
tm_file=sparc/linux-aout.h
xmake_file=x-linux
- fixincludes=Makefile.in #On Linux, the headers are ok already.
gnu_ld=yes
;;
sparc-*-linux-gnulibc1*) # Sparc's running GNU/Linux, libc5
@@ -4859,7 +5256,6 @@ for machine in $build $host $target; do
tm_file=sparc/linux.h
tmake_file="t-linux t-linux-gnulibc1"
extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o"
- fixincludes=Makefile.in #On Linux, the headers are ok already.
gnu_ld=yes
;;
sparc-*-linux-gnu*) # Sparc's running GNU/Linux, libc6
@@ -4868,7 +5264,6 @@ for machine in $build $host $target; do
tm_file=sparc/linux.h
tmake_file="t-linux"
extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o"
- fixincludes=Makefile.in #On Linux, the headers are ok already.
gnu_ld=yes
if test x$enable_threads = xyes; then
thread_file='posix'
@@ -4896,8 +5291,7 @@ for machine in $build $host $target; do
tmake_file="sparc/t-sol2 sparc/t-sol2-64"
xmake_file=sparc/x-sysv4
extra_parts="crt1.o crti.o crtn.o gcrt1.o crtbegin.o crtend.o"
- fixincludes=fixinc.wrap
- float_format=i128
+ float_format=none
if test x${enable_threads} = x ; then
enable_threads=$have_pthread_h
if test x${enable_threads} = x ; then
@@ -4912,6 +5306,15 @@ for machine in $build $host $target; do
fi
fi
;;
+ sparc-hal-solaris2*)
+ xm_file=sparc/xm-sol2.h
+ tm_file="sparc/sol2.h sparc/hal.h"
+ tmake_file="sparc/t-halos sparc/t-sol2"
+ xmake_file=sparc/x-sysv4
+ extra_parts="crt1.o crti.o crtn.o gmon.o crtbegin.o crtend.o"
+ fixincludes=fixinc.svr4
+ broken_install=yes
+ ;;
sparc-*-solaris2*)
if test x$gnu_ld = xyes
then
@@ -4926,11 +5329,12 @@ for machine in $build $host $target; do
extra_parts="crt1.o crti.o crtn.o gcrt1.o gmon.o crtbegin.o crtend.o"
case $machine in
*-*-solaris2.[0-4])
- fixincludes=fixinc.svr4;;
+ float_format=i128
+ ;;
*)
- fixincludes=fixinc.wrap;;
+ float_format=none
+ ;;
esac
- float_format=i128
if test x${enable_threads} = x; then
enable_threads=$have_pthread_h
if test x${enable_threads} = x; then
@@ -5003,7 +5407,6 @@ for machine in $build $host $target; do
xm_file="sparc/xm-sp64.h sparc/xm-linux.h"
tm_file=sparc/linux64.h
xmake_file=x-linux
- fixincludes=Makefile.in # The headers are ok already.
extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o"
gnu_ld=yes
;;
@@ -5019,7 +5422,6 @@ for machine in $build $host $target; do
xm_file=arm/xm-thumb.h
md_file=arm/thumb.md
tmake_file=arm/t-thumb
- fixincludes=Makefile.in # There is nothing to fix
;;
# This hasn't been upgraded to GCC 2.
# tron-*-*)
@@ -5048,11 +5450,12 @@ for machine in $build $host $target; do
;;
vax-*-netbsd*)
tm_file="${tm_file} netbsd.h vax/netbsd.h"
- # On NetBSD, the headers are already okay, except for math.h.
- fixincludes=fixinc.wrap
tmake_file=t-netbsd
float_format=vax
;;
+ vax-*-openbsd*)
+ tmake_file="${tm_file} vax/t-openbsd"
+ ;;
vax-*-ultrix*) # vaxen running ultrix
tm_file="${tm_file} vax/ultrix.h"
use_collect2=yes
@@ -5091,13 +5494,10 @@ for machine in $build $host $target; do
# GNU tools are the only tools.
gnu_ld=yes
gas=yes
- # On GNU, the headers are already okay.
- fixincludes=Makefile.in
xmake_file=x-linux # These details are the same as Linux.
tmake_file=t-gnu # These are not.
;;
*-*-sysv4*)
- fixincludes=fixinc.svr4
xmake_try_sysv=x-sysv
install_headers_dir=install-headers-cpio
;;
@@ -5123,7 +5523,7 @@ for machine in $build $host $target; do
alpha*-*-*)
case $machine in
alphaev6*)
- target_cpu_default2="MASK_CPU_EV6|MASK_BXW|MASK_CIX|MASK_MAX"
+ target_cpu_default2="MASK_CPU_EV6|MASK_BWX|MASK_CIX|MASK_MAX"
;;
alphapca56*)
target_cpu_default2="MASK_CPU_EV5|MASK_BWX|MASK_MAX"
@@ -5158,7 +5558,7 @@ for machine in $build $host $target; do
xarm23678 | xarm250 | xarm67010 \
| xarm7m | xarm7dm | xarm7dmi | xarm7tdmi \
| xarm7100 | xarm7500 | xarm7500fe | xarm810 \
- | xstrongarm | xstrongarm110)
+ | xstrongarm | xstrongarm110 | xstrongarm1100)
target_cpu_default2="TARGET_CPU_$with_cpu"
;;
@@ -5202,6 +5602,7 @@ for machine in $build $host $target; do
xcommon | xpower | xpower2 | xpowerpc | xrios \
| xrios1 | xrios2 | xrsc | xrsc1 \
| x601 | x602 | x603 | x603e | x604 | x604e | x620 \
+ | xec603e | x740 | x750 | x401 \
| x403 | x505 | x801 | x821 | x823 | x860)
target_cpu_default2="\"$with_cpu\""
;;
@@ -5225,7 +5626,7 @@ for machine in $build $host $target; do
.)
target_cpu_default2=TARGET_CPU_"`echo $machine | sed 's/-.*$//'`"
;;
- .supersparc | .ultrasparc | .v7 | .v8 | .v9)
+ .supersparc | .hypersparc | .ultrasparc | .v7 | .v8 | .v9)
target_cpu_default2="TARGET_CPU_$with_cpu"
;;
*)
@@ -5313,18 +5714,33 @@ if test x"$tmake_file" = x
then tmake_file=$cpu_type/t-$cpu_type
fi
+if test x"$dwarf2" = xyes
+then tm_file="tm-dwarf2.h $tm_file"
+fi
+
if test x$float_format = x
then float_format=i64
fi
+if test $float_format = none
+then float_h_file=Makefile.in
+else float_h_file=float-$float_format.h
+fi
+
if test x$enable_haifa = x
then
case $target in
- alpha*-* | hppa1.?-* | powerpc*-* | rs6000-* | *sparc*-* | m32r*-*)
+ alpha*-* | hppa*-* | powerpc*-* | rs6000-* | *sparc*-* | m32r*-*)
enable_haifa=yes;;
esac
fi
+# Handle cpp installation.
+if [ x$enable_cpp != x ]
+then
+ tmake_file="$tmake_file t-install-cpp"
+fi
+
# Say what files are being used for the output code and MD file.
echo "Using \`$srcdir/config/$out_file' to output insns."
echo "Using \`$srcdir/config/$md_file' as machine description file."
@@ -5384,14 +5800,14 @@ fi
# auto-host.h is the file containing items generated by autoconf and is
# the first file included by config.h.
null_defines=
-host_xm_file="auto-host.h ${host_xm_file}"
+host_xm_file="auto-host.h gansidecl.h ${host_xm_file}"
# If host=build, it is correct to have hconfig 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_xm_file="auto-host.h ${build_xm_file}"
+ build_xm_file="auto-host.h gansidecl.h ${build_xm_file}"
else
# We create a subdir, then run autoconf in the subdir.
# To prevent recursion we set host and build for the new
@@ -5413,9 +5829,12 @@ else
mv auto-host.h ../auto-build.h
cd ..
rm -rf $tempdir
- build_xm_file="auto-build.h ${build_xm_file}"
+ build_xm_file="auto-build.h gansidecl.h ${build_xm_file}"
fi
+xm_file="gansidecl.h ${xm_file}"
+tm_file="gansidecl.h ${tm_file}"
+
vars="host_xm_file tm_file xm_file build_xm_file"
links="config.h tm.h tconfig.h hconfig.h"
defines="host_xm_defines null_defines xm_defines build_xm_defines"
@@ -5440,7 +5859,21 @@ do
fi
for file in `eval echo '$'$var`; do
+ case $file in
+ auto-config.h)
+ ;;
+ *)
+ echo '#ifdef IN_GCC' >>$link
+ ;;
+ esac
echo "#include \"$file\"" >>$link
+ case $file in
+ auto-config.h)
+ ;;
+ *)
+ echo '#endif' >>$link
+ ;;
+ esac
done
for def in `eval echo '$'$define`; do
@@ -5463,6 +5896,1873 @@ else
fi
gcc_version=`sed -e 's/.*\"\([^ \"]*\)[ \"].*/\1/' < ${gcc_version_trigger}`
+# Internationalization
+PACKAGE=gcc
+VERSION="$gcc_version"
+cat >> confdefs.h <<EOF
+#define PACKAGE "$PACKAGE"
+EOF
+
+cat >> confdefs.h <<EOF
+#define VERSION "$VERSION"
+EOF
+
+
+
+
+ALL_LINGUAS="en_UK"
+
+# NLS support is still experimental, so disable it by default for now.
+# Check whether --enable-nls or --disable-nls was given.
+if test "${enable_nls+set}" = set; then
+ enableval="$enable_nls"
+ :
+else
+ enable_nls=no
+fi
+
+
+
+ echo $ac_n "checking for strerror in -lcposix""... $ac_c" 1>&6
+echo "configure:5928: checking for strerror in -lcposix" >&5
+ac_lib_var=`echo cposix'_'strerror | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lcposix $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 5936 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char strerror();
+
+int main() {
+strerror()
+; return 0; }
+EOF
+if { (eval echo configure:5947: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ LIBS="$LIBS -lcposix"
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+
+echo $ac_n "checking for working const""... $ac_c" 1>&6
+echo "configure:5970: checking for working const" >&5
+if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 5975 "configure"
+#include "confdefs.h"
+
+int main() {
+
+/* Ultrix mips cc rejects this. */
+typedef int charset[2]; const charset x;
+/* SunOS 4.1.1 cc rejects this. */
+char const *const *ccp;
+char **p;
+/* NEC SVR4.0.2 mips cc rejects this. */
+struct point {int x, y;};
+static struct point const zero = {0,0};
+/* AIX XL C 1.02.0.0 rejects this.
+ It does not let you subtract one const X* pointer from another in an arm
+ of an if-expression whose if-part is not a constant expression */
+const char *g = "string";
+ccp = &g + (g ? g-g : 0);
+/* HPUX 7.0 cc rejects these. */
+++ccp;
+p = (char**) ccp;
+ccp = (char const *const *) p;
+{ /* SCO 3.2v4 cc rejects this. */
+ char *t;
+ char const *s = 0 ? (char *) 0 : (char const *) 0;
+
+ *t++ = 0;
+}
+{ /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */
+ int x[] = {25, 17};
+ const int *foo = &x[0];
+ ++foo;
+}
+{ /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */
+ typedef const int *iptr;
+ iptr p = 0;
+ ++p;
+}
+{ /* AIX XL C 1.02.0.0 rejects this saying
+ "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
+ struct s { int j; const int *ap[3]; };
+ struct s *b; b->j = 5;
+}
+{ /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
+ const int foo = 10;
+}
+
+; return 0; }
+EOF
+if { (eval echo configure:6024: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_c_const=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_c_const=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_c_const" 1>&6
+if test $ac_cv_c_const = no; then
+ cat >> confdefs.h <<\EOF
+#define const
+EOF
+
+fi
+
+echo $ac_n "checking for inline""... $ac_c" 1>&6
+echo "configure:6045: checking for inline" >&5
+if eval "test \"`echo '$''{'ac_cv_c_inline'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_cv_c_inline=no
+for ac_kw in inline __inline__ __inline; do
+ cat > conftest.$ac_ext <<EOF
+#line 6052 "configure"
+#include "confdefs.h"
+
+int main() {
+} $ac_kw foo() {
+; return 0; }
+EOF
+if { (eval echo configure:6059: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_c_inline=$ac_kw; break
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+done
+
+fi
+
+echo "$ac_t""$ac_cv_c_inline" 1>&6
+case "$ac_cv_c_inline" in
+ inline | yes) ;;
+ no) cat >> confdefs.h <<\EOF
+#define inline
+EOF
+ ;;
+ *) cat >> confdefs.h <<EOF
+#define inline $ac_cv_c_inline
+EOF
+ ;;
+esac
+
+echo $ac_n "checking for off_t""... $ac_c" 1>&6
+echo "configure:6085: checking for off_t" >&5
+if eval "test \"`echo '$''{'ac_cv_type_off_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 6090 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "(^|[^a-zA-Z_0-9])off_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_type_off_t=yes
+else
+ rm -rf conftest*
+ ac_cv_type_off_t=no
+fi
+rm -f conftest*
+
+fi
+echo "$ac_t""$ac_cv_type_off_t" 1>&6
+if test $ac_cv_type_off_t = no; then
+ cat >> confdefs.h <<\EOF
+#define off_t long
+EOF
+
+fi
+
+echo $ac_n "checking for size_t""... $ac_c" 1>&6
+echo "configure:6118: checking for size_t" >&5
+if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 6123 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "(^|[^a-zA-Z_0-9])size_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_type_size_t=yes
+else
+ rm -rf conftest*
+ ac_cv_type_size_t=no
+fi
+rm -f conftest*
+
+fi
+echo "$ac_t""$ac_cv_type_size_t" 1>&6
+if test $ac_cv_type_size_t = no; then
+ cat >> confdefs.h <<\EOF
+#define size_t unsigned
+EOF
+
+fi
+
+# The Ultrix 4.2 mips builtin alloca declared by alloca.h only works
+# for constant arguments. Useless!
+echo $ac_n "checking for working alloca.h""... $ac_c" 1>&6
+echo "configure:6153: checking for working alloca.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_alloca_h'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 6158 "configure"
+#include "confdefs.h"
+#include <alloca.h>
+int main() {
+char *p = alloca(2 * sizeof(int));
+; return 0; }
+EOF
+if { (eval echo configure:6165: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ ac_cv_header_alloca_h=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_header_alloca_h=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_header_alloca_h" 1>&6
+if test $ac_cv_header_alloca_h = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_ALLOCA_H 1
+EOF
+
+fi
+
+echo $ac_n "checking for alloca""... $ac_c" 1>&6
+echo "configure:6186: checking for alloca" >&5
+if eval "test \"`echo '$''{'ac_cv_func_alloca_works'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 6191 "configure"
+#include "confdefs.h"
+
+#ifdef __GNUC__
+# define alloca __builtin_alloca
+#else
+# ifdef _MSC_VER
+# include <malloc.h>
+# define alloca _alloca
+# else
+# if HAVE_ALLOCA_H
+# include <alloca.h>
+# else
+# ifdef _AIX
+ #pragma alloca
+# else
+# ifndef alloca /* predefined by HP cc +Olibcalls */
+char *alloca ();
+# endif
+# endif
+# endif
+# endif
+#endif
+
+int main() {
+char *p = (char *) alloca(1);
+; return 0; }
+EOF
+if { (eval echo configure:6219: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ ac_cv_func_alloca_works=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_func_alloca_works=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_func_alloca_works" 1>&6
+if test $ac_cv_func_alloca_works = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_ALLOCA 1
+EOF
+
+fi
+
+if test $ac_cv_func_alloca_works = no; then
+ # The SVR3 libPW and SVR4 libucb both contain incompatible functions
+ # that cause trouble. Some versions do not even contain alloca or
+ # contain a buggy version. If you still want to use their alloca,
+ # use ar to extract alloca.o from them instead of compiling alloca.c.
+ ALLOCA=alloca.${ac_objext}
+ cat >> confdefs.h <<\EOF
+#define C_ALLOCA 1
+EOF
+
+
+echo $ac_n "checking whether alloca needs Cray hooks""... $ac_c" 1>&6
+echo "configure:6251: checking whether alloca needs Cray hooks" >&5
+if eval "test \"`echo '$''{'ac_cv_os_cray'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 6256 "configure"
+#include "confdefs.h"
+#if defined(CRAY) && ! defined(CRAY2)
+webecray
+#else
+wenotbecray
+#endif
+
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "webecray" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_os_cray=yes
+else
+ rm -rf conftest*
+ ac_cv_os_cray=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_os_cray" 1>&6
+if test $ac_cv_os_cray = yes; then
+for ac_func in _getb67 GETB67 getb67; do
+ echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:6281: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 6286 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:6309: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<EOF
+#define CRAY_STACKSEG_END $ac_func
+EOF
+
+ break
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+done
+fi
+
+echo $ac_n "checking stack direction for C alloca""... $ac_c" 1>&6
+echo "configure:6336: checking stack direction for C alloca" >&5
+if eval "test \"`echo '$''{'ac_cv_c_stack_direction'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ ac_cv_c_stack_direction=0
+else
+ cat > conftest.$ac_ext <<EOF
+#line 6344 "configure"
+#include "confdefs.h"
+find_stack_direction ()
+{
+ static char *addr = 0;
+ auto char dummy;
+ if (addr == 0)
+ {
+ addr = &dummy;
+ return find_stack_direction ();
+ }
+ else
+ return (&dummy > addr) ? 1 : -1;
+}
+main ()
+{
+ exit (find_stack_direction() < 0);
+}
+EOF
+if { (eval echo configure:6363: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ ac_cv_c_stack_direction=1
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_c_stack_direction=-1
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$ac_cv_c_stack_direction" 1>&6
+cat >> confdefs.h <<EOF
+#define STACK_DIRECTION $ac_cv_c_stack_direction
+EOF
+
+fi
+
+for ac_hdr in unistd.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:6388: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 6393 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:6398: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+for ac_func in getpagesize
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:6427: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 6432 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:6455: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+echo $ac_n "checking for working mmap""... $ac_c" 1>&6
+echo "configure:6480: checking for working mmap" >&5
+if eval "test \"`echo '$''{'ac_cv_func_mmap_fixed_mapped'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ ac_cv_func_mmap_fixed_mapped=no
+else
+ cat > conftest.$ac_ext <<EOF
+#line 6488 "configure"
+#include "confdefs.h"
+
+/* Thanks to Mike Haertel and Jim Avera for this test.
+ Here is a matrix of mmap possibilities:
+ mmap private not fixed
+ mmap private fixed at somewhere currently unmapped
+ mmap private fixed at somewhere already mapped
+ mmap shared not fixed
+ mmap shared fixed at somewhere currently unmapped
+ mmap shared fixed at somewhere already mapped
+ For private mappings, we should verify that changes cannot be read()
+ back from the file, nor mmap's back from the file at a different
+ address. (There have been systems where private was not correctly
+ implemented like the infamous i386 svr4.0, and systems where the
+ VM page cache was not coherent with the filesystem buffer cache
+ like early versions of FreeBSD and possibly contemporary NetBSD.)
+ For shared mappings, we should conversely verify that changes get
+ propogated back to all the places they're supposed to be.
+
+ Grep wants private fixed already mapped.
+ The main things grep needs to know about mmap are:
+ * does it exist and is it safe to write into the mmap'd area
+ * how to use it (BSD variants) */
+#include <sys/types.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+
+/* This mess was copied from the GNU getpagesize.h. */
+#ifndef HAVE_GETPAGESIZE
+# ifdef HAVE_UNISTD_H
+# include <unistd.h>
+# endif
+
+/* Assume that all systems that can run configure have sys/param.h. */
+# ifndef HAVE_SYS_PARAM_H
+# define HAVE_SYS_PARAM_H 1
+# endif
+
+# ifdef _SC_PAGESIZE
+# define getpagesize() sysconf(_SC_PAGESIZE)
+# else /* no _SC_PAGESIZE */
+# ifdef HAVE_SYS_PARAM_H
+# include <sys/param.h>
+# ifdef EXEC_PAGESIZE
+# define getpagesize() EXEC_PAGESIZE
+# else /* no EXEC_PAGESIZE */
+# ifdef NBPG
+# define getpagesize() NBPG * CLSIZE
+# ifndef CLSIZE
+# define CLSIZE 1
+# endif /* no CLSIZE */
+# else /* no NBPG */
+# ifdef NBPC
+# define getpagesize() NBPC
+# else /* no NBPC */
+# ifdef PAGESIZE
+# define getpagesize() PAGESIZE
+# endif /* PAGESIZE */
+# endif /* no NBPC */
+# endif /* no NBPG */
+# endif /* no EXEC_PAGESIZE */
+# else /* no HAVE_SYS_PARAM_H */
+# define getpagesize() 8192 /* punt totally */
+# endif /* no HAVE_SYS_PARAM_H */
+# endif /* no _SC_PAGESIZE */
+
+#endif /* no HAVE_GETPAGESIZE */
+
+#ifdef __cplusplus
+extern "C" { void *malloc(unsigned); }
+#else
+char *malloc();
+#endif
+
+int
+main()
+{
+ char *data, *data2, *data3;
+ int i, pagesize;
+ int fd;
+
+ pagesize = getpagesize();
+
+ /*
+ * First, make a file with some known garbage in it.
+ */
+ data = malloc(pagesize);
+ if (!data)
+ exit(1);
+ for (i = 0; i < pagesize; ++i)
+ *(data + i) = rand();
+ umask(0);
+ fd = creat("conftestmmap", 0600);
+ if (fd < 0)
+ exit(1);
+ if (write(fd, data, pagesize) != pagesize)
+ exit(1);
+ close(fd);
+
+ /*
+ * Next, try to mmap the file at a fixed address which
+ * already has something else allocated at it. If we can,
+ * also make sure that we see the same garbage.
+ */
+ fd = open("conftestmmap", O_RDWR);
+ if (fd < 0)
+ exit(1);
+ data2 = malloc(2 * pagesize);
+ if (!data2)
+ exit(1);
+ data2 += (pagesize - ((int) data2 & (pagesize - 1))) & (pagesize - 1);
+ if (data2 != mmap(data2, pagesize, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_FIXED, fd, 0L))
+ exit(1);
+ for (i = 0; i < pagesize; ++i)
+ if (*(data + i) != *(data2 + i))
+ exit(1);
+
+ /*
+ * Finally, make sure that changes to the mapped area
+ * do not percolate back to the file as seen by read().
+ * (This is a bug on some variants of i386 svr4.0.)
+ */
+ for (i = 0; i < pagesize; ++i)
+ *(data2 + i) = *(data2 + i) + 1;
+ data3 = malloc(pagesize);
+ if (!data3)
+ exit(1);
+ if (read(fd, data3, pagesize) != pagesize)
+ exit(1);
+ for (i = 0; i < pagesize; ++i)
+ if (*(data + i) != *(data3 + i))
+ exit(1);
+ close(fd);
+ unlink("conftestmmap");
+ exit(0);
+}
+
+EOF
+if { (eval echo configure:6628: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ ac_cv_func_mmap_fixed_mapped=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_func_mmap_fixed_mapped=no
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$ac_cv_func_mmap_fixed_mapped" 1>&6
+if test $ac_cv_func_mmap_fixed_mapped = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_MMAP 1
+EOF
+
+fi
+
+
+ for ac_hdr in argz.h limits.h locale.h nl_types.h malloc.h string.h \
+unistd.h sys/param.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:6656: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 6661 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:6666: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+ for ac_func in getcwd munmap putenv setenv setlocale strchr strcasecmp \
+strdup __argz_count __argz_stringify __argz_next
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:6696: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 6701 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:6724: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+
+ if test "${ac_cv_func_stpcpy+set}" != "set"; then
+ for ac_func in stpcpy
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:6753: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 6758 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:6781: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+ fi
+ if test "${ac_cv_func_stpcpy}" = "yes"; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_STPCPY 1
+EOF
+
+ fi
+
+ if test $ac_cv_header_locale_h = yes; then
+ echo $ac_n "checking for LC_MESSAGES""... $ac_c" 1>&6
+echo "configure:6815: checking for LC_MESSAGES" >&5
+if eval "test \"`echo '$''{'am_cv_val_LC_MESSAGES'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 6820 "configure"
+#include "confdefs.h"
+#include <locale.h>
+int main() {
+return LC_MESSAGES
+; return 0; }
+EOF
+if { (eval echo configure:6827: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ am_cv_val_LC_MESSAGES=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ am_cv_val_LC_MESSAGES=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$am_cv_val_LC_MESSAGES" 1>&6
+ if test $am_cv_val_LC_MESSAGES = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_LC_MESSAGES 1
+EOF
+
+ fi
+ fi
+ echo $ac_n "checking whether NLS is requested""... $ac_c" 1>&6
+echo "configure:6848: checking whether NLS is requested" >&5
+ # Check whether --enable-nls or --disable-nls was given.
+if test "${enable_nls+set}" = set; then
+ enableval="$enable_nls"
+ USE_NLS=$enableval
+else
+ USE_NLS=yes
+fi
+
+ echo "$ac_t""$USE_NLS" 1>&6
+
+
+ USE_INCLUDED_LIBINTL=no
+
+ if test "$USE_NLS" = "yes"; then
+ cat >> confdefs.h <<\EOF
+#define ENABLE_NLS 1
+EOF
+
+ echo $ac_n "checking whether included gettext is requested""... $ac_c" 1>&6
+echo "configure:6868: checking whether included gettext is requested" >&5
+ # Check whether --with-included-gettext or --without-included-gettext was given.
+if test "${with_included_gettext+set}" = set; then
+ withval="$with_included_gettext"
+ nls_cv_force_use_gnu_gettext=$withval
+else
+ nls_cv_force_use_gnu_gettext=no
+fi
+
+ echo "$ac_t""$nls_cv_force_use_gnu_gettext" 1>&6
+
+ nls_cv_use_gnu_gettext="$nls_cv_force_use_gnu_gettext"
+ if test "$nls_cv_force_use_gnu_gettext" != "yes"; then
+ nls_cv_header_intl=
+ nls_cv_header_libgt=
+ CATOBJEXT=NONE
+
+ ac_safe=`echo "libintl.h" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for libintl.h""... $ac_c" 1>&6
+echo "configure:6887: checking for libintl.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 6892 "configure"
+#include "confdefs.h"
+#include <libintl.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:6897: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ echo $ac_n "checking for gettext in libc""... $ac_c" 1>&6
+echo "configure:6914: checking for gettext in libc" >&5
+if eval "test \"`echo '$''{'gt_cv_func_gettext_libc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 6919 "configure"
+#include "confdefs.h"
+#include <libintl.h>
+int main() {
+return (int) gettext ("")
+; return 0; }
+EOF
+if { (eval echo configure:6926: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ gt_cv_func_gettext_libc=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ gt_cv_func_gettext_libc=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$gt_cv_func_gettext_libc" 1>&6
+
+ if test "$gt_cv_func_gettext_libc" != "yes"; then
+ echo $ac_n "checking for bindtextdomain in -lintl""... $ac_c" 1>&6
+echo "configure:6942: checking for bindtextdomain in -lintl" >&5
+ac_lib_var=`echo intl'_'bindtextdomain | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lintl $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 6950 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char bindtextdomain();
+
+int main() {
+bindtextdomain()
+; return 0; }
+EOF
+if { (eval echo configure:6961: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ echo $ac_n "checking for gettext in libintl""... $ac_c" 1>&6
+echo "configure:6977: checking for gettext in libintl" >&5
+if eval "test \"`echo '$''{'gt_cv_func_gettext_libintl'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ echo $ac_n "checking for gettext in -lintl""... $ac_c" 1>&6
+echo "configure:6982: checking for gettext in -lintl" >&5
+ac_lib_var=`echo intl'_'gettext | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lintl $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 6990 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char gettext();
+
+int main() {
+gettext()
+; return 0; }
+EOF
+if { (eval echo configure:7001: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ gt_cv_func_gettext_libintl=yes
+else
+ echo "$ac_t""no" 1>&6
+gt_cv_func_gettext_libintl=no
+fi
+
+fi
+
+echo "$ac_t""$gt_cv_func_gettext_libintl" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ fi
+
+ if test "$gt_cv_func_gettext_libc" = "yes" \
+ || test "$gt_cv_func_gettext_libintl" = "yes"; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_GETTEXT 1
+EOF
+
+ # Extract the first word of "msgfmt", so it can be a program name with args.
+set dummy msgfmt; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:7040: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_MSGFMT'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$MSGFMT" in
+ /*)
+ ac_cv_path_MSGFMT="$MSGFMT" # Let the user override the test with a path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"; then
+ ac_cv_path_MSGFMT="$ac_dir/$ac_word"
+ break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_MSGFMT" && ac_cv_path_MSGFMT="no"
+ ;;
+esac
+fi
+MSGFMT="$ac_cv_path_MSGFMT"
+if test -n "$MSGFMT"; then
+ echo "$ac_t""$MSGFMT" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+ if test "$MSGFMT" != "no"; then
+ for ac_func in dcgettext
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:7074: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 7079 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:7102: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+ # Extract the first word of "gmsgfmt", so it can be a program name with args.
+set dummy gmsgfmt; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:7129: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_GMSGFMT'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$GMSGFMT" in
+ /*)
+ ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a path.
+ ;;
+ ?:/*)
+ ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a dos path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_path_GMSGFMT="$ac_dir/$ac_word"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_GMSGFMT" && ac_cv_path_GMSGFMT="$MSGFMT"
+ ;;
+esac
+fi
+GMSGFMT="$ac_cv_path_GMSGFMT"
+if test -n "$GMSGFMT"; then
+ echo "$ac_t""$GMSGFMT" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ # Extract the first word of "xgettext", so it can be a program name with args.
+set dummy xgettext; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:7165: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_XGETTEXT'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$XGETTEXT" in
+ /*)
+ ac_cv_path_XGETTEXT="$XGETTEXT" # Let the user override the test with a path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"; then
+ ac_cv_path_XGETTEXT="$ac_dir/$ac_word"
+ break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_XGETTEXT" && ac_cv_path_XGETTEXT=":"
+ ;;
+esac
+fi
+XGETTEXT="$ac_cv_path_XGETTEXT"
+if test -n "$XGETTEXT"; then
+ echo "$ac_t""$XGETTEXT" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ cat > conftest.$ac_ext <<EOF
+#line 7197 "configure"
+#include "confdefs.h"
+
+int main() {
+extern int _nl_msg_cat_cntr;
+ return _nl_msg_cat_cntr
+; return 0; }
+EOF
+if { (eval echo configure:7205: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ CATOBJEXT=.gmo
+ DATADIRNAME=share
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CATOBJEXT=.mo
+ DATADIRNAME=lib
+fi
+rm -f conftest*
+ INSTOBJEXT=.mo
+ fi
+ fi
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+ if test "$CATOBJEXT" = "NONE"; then
+ echo $ac_n "checking whether catgets can be used""... $ac_c" 1>&6
+echo "configure:7228: checking whether catgets can be used" >&5
+ # Check whether --with-catgets or --without-catgets was given.
+if test "${with_catgets+set}" = set; then
+ withval="$with_catgets"
+ nls_cv_use_catgets=$withval
+else
+ nls_cv_use_catgets=no
+fi
+
+ echo "$ac_t""$nls_cv_use_catgets" 1>&6
+
+ if test "$nls_cv_use_catgets" = "yes"; then
+ echo $ac_n "checking for main in -li""... $ac_c" 1>&6
+echo "configure:7241: checking for main in -li" >&5
+ac_lib_var=`echo i'_'main | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-li $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 7249 "configure"
+#include "confdefs.h"
+
+int main() {
+main()
+; return 0; }
+EOF
+if { (eval echo configure:7256: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_lib=HAVE_LIB`echo i | sed -e 's/[^a-zA-Z0-9_]/_/g' \
+ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_lib 1
+EOF
+
+ LIBS="-li $LIBS"
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ echo $ac_n "checking for catgets""... $ac_c" 1>&6
+echo "configure:7284: checking for catgets" >&5
+if eval "test \"`echo '$''{'ac_cv_func_catgets'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 7289 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char catgets(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char catgets();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_catgets) || defined (__stub___catgets)
+choke me
+#else
+catgets();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:7312: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_catgets=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_catgets=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'catgets`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define HAVE_CATGETS 1
+EOF
+
+ INTLOBJS="\$(CATOBJS)"
+ # Extract the first word of "gencat", so it can be a program name with args.
+set dummy gencat; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:7334: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_GENCAT'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$GENCAT" in
+ /*)
+ ac_cv_path_GENCAT="$GENCAT" # Let the user override the test with a path.
+ ;;
+ ?:/*)
+ ac_cv_path_GENCAT="$GENCAT" # Let the user override the test with a dos path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_path_GENCAT="$ac_dir/$ac_word"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_GENCAT" && ac_cv_path_GENCAT="no"
+ ;;
+esac
+fi
+GENCAT="$ac_cv_path_GENCAT"
+if test -n "$GENCAT"; then
+ echo "$ac_t""$GENCAT" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+ if test "$GENCAT" != "no"; then
+ # Extract the first word of "gmsgfmt", so it can be a program name with args.
+set dummy gmsgfmt; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:7370: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_GMSGFMT'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$GMSGFMT" in
+ /*)
+ ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a path.
+ ;;
+ ?:/*)
+ ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a dos path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_path_GMSGFMT="$ac_dir/$ac_word"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_GMSGFMT" && ac_cv_path_GMSGFMT="no"
+ ;;
+esac
+fi
+GMSGFMT="$ac_cv_path_GMSGFMT"
+if test -n "$GMSGFMT"; then
+ echo "$ac_t""$GMSGFMT" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ if test "$GMSGFMT" = "no"; then
+ # Extract the first word of "msgfmt", so it can be a program name with args.
+set dummy msgfmt; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:7407: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_GMSGFMT'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$GMSGFMT" in
+ /*)
+ ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"; then
+ ac_cv_path_GMSGFMT="$ac_dir/$ac_word"
+ break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_GMSGFMT" && ac_cv_path_GMSGFMT="no"
+ ;;
+esac
+fi
+GMSGFMT="$ac_cv_path_GMSGFMT"
+if test -n "$GMSGFMT"; then
+ echo "$ac_t""$GMSGFMT" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ fi
+ # Extract the first word of "xgettext", so it can be a program name with args.
+set dummy xgettext; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:7442: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_XGETTEXT'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$XGETTEXT" in
+ /*)
+ ac_cv_path_XGETTEXT="$XGETTEXT" # Let the user override the test with a path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"; then
+ ac_cv_path_XGETTEXT="$ac_dir/$ac_word"
+ break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_XGETTEXT" && ac_cv_path_XGETTEXT=":"
+ ;;
+esac
+fi
+XGETTEXT="$ac_cv_path_XGETTEXT"
+if test -n "$XGETTEXT"; then
+ echo "$ac_t""$XGETTEXT" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ USE_INCLUDED_LIBINTL=yes
+ CATOBJEXT=.cat
+ INSTOBJEXT=.cat
+ DATADIRNAME=lib
+ INTLDEPS='$(top_builddir)/intl/libintl.a'
+ INTLLIBS=$INTLDEPS
+ LIBS=`echo $LIBS | sed -e 's/-lintl//'`
+ nls_cv_header_intl=intl/libintl.h
+ nls_cv_header_libgt=intl/libgettext.h
+ fi
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ fi
+ fi
+
+ if test "$CATOBJEXT" = "NONE"; then
+ nls_cv_use_gnu_gettext=yes
+ fi
+ fi
+
+ if test "$nls_cv_use_gnu_gettext" = "yes"; then
+ INTLOBJS="\$(GETTOBJS)"
+ # Extract the first word of "msgfmt", so it can be a program name with args.
+set dummy msgfmt; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:7500: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_MSGFMT'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$MSGFMT" in
+ /*)
+ ac_cv_path_MSGFMT="$MSGFMT" # Let the user override the test with a path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"; then
+ ac_cv_path_MSGFMT="$ac_dir/$ac_word"
+ break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_MSGFMT" && ac_cv_path_MSGFMT="msgfmt"
+ ;;
+esac
+fi
+MSGFMT="$ac_cv_path_MSGFMT"
+if test -n "$MSGFMT"; then
+ echo "$ac_t""$MSGFMT" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ # Extract the first word of "gmsgfmt", so it can be a program name with args.
+set dummy gmsgfmt; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:7534: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_GMSGFMT'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$GMSGFMT" in
+ /*)
+ ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a path.
+ ;;
+ ?:/*)
+ ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a dos path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_path_GMSGFMT="$ac_dir/$ac_word"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_GMSGFMT" && ac_cv_path_GMSGFMT="$MSGFMT"
+ ;;
+esac
+fi
+GMSGFMT="$ac_cv_path_GMSGFMT"
+if test -n "$GMSGFMT"; then
+ echo "$ac_t""$GMSGFMT" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ # Extract the first word of "xgettext", so it can be a program name with args.
+set dummy xgettext; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:7570: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_XGETTEXT'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$XGETTEXT" in
+ /*)
+ ac_cv_path_XGETTEXT="$XGETTEXT" # Let the user override the test with a path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"; then
+ ac_cv_path_XGETTEXT="$ac_dir/$ac_word"
+ break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_XGETTEXT" && ac_cv_path_XGETTEXT=":"
+ ;;
+esac
+fi
+XGETTEXT="$ac_cv_path_XGETTEXT"
+if test -n "$XGETTEXT"; then
+ echo "$ac_t""$XGETTEXT" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+ USE_INCLUDED_LIBINTL=yes
+ CATOBJEXT=.gmo
+ INSTOBJEXT=.mo
+ DATADIRNAME=share
+ INTLDEPS='$(top_builddir)/intl/libintl.a'
+ INTLLIBS=$INTLDEPS
+ LIBS=`echo $LIBS | sed -e 's/-lintl//'`
+ nls_cv_header_intl=intl/libintl.h
+ nls_cv_header_libgt=intl/libgettext.h
+ fi
+
+ if test "$XGETTEXT" != ":"; then
+ if $XGETTEXT --omit-header /dev/null 2> /dev/null; then
+ : ;
+ else
+ echo "$ac_t""found xgettext program is not GNU xgettext; ignore it" 1>&6
+ XGETTEXT=":"
+ fi
+ fi
+
+ # We need to process the po/ directory.
+ POSUB=po
+ else
+ DATADIRNAME=share
+ nls_cv_header_intl=intl/libintl.h
+ nls_cv_header_libgt=intl/libgettext.h
+ fi
+
+
+
+
+ # If this is used in GNU gettext we have to set USE_NLS to `yes'
+ # because some of the sources are only built for this goal.
+ if test "$PACKAGE" = gettext; then
+ USE_NLS=yes
+ USE_INCLUDED_LIBINTL=yes
+ fi
+
+ for lang in $ALL_LINGUAS; do
+ GMOFILES="$GMOFILES $lang.gmo"
+ POFILES="$POFILES $lang.po"
+ done
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ if test "x$CATOBJEXT" != "x"; then
+ if test "x$ALL_LINGUAS" = "x"; then
+ LINGUAS=
+ else
+ echo $ac_n "checking for catalogs to be installed""... $ac_c" 1>&6
+echo "configure:7663: checking for catalogs to be installed" >&5
+ NEW_LINGUAS=
+ for lang in ${LINGUAS=$ALL_LINGUAS}; do
+ case "$ALL_LINGUAS" in
+ *$lang*) NEW_LINGUAS="$NEW_LINGUAS $lang" ;;
+ esac
+ done
+ LINGUAS=$NEW_LINGUAS
+ echo "$ac_t""$LINGUAS" 1>&6
+ fi
+
+ if test -n "$LINGUAS"; then
+ for lang in $LINGUAS; do CATALOGS="$CATALOGS $lang$CATOBJEXT"; done
+ fi
+ fi
+
+ if test $ac_cv_header_locale_h = yes; then
+ INCLUDE_LOCALE_H="#include <locale.h>"
+ else
+ INCLUDE_LOCALE_H="\
+/* The system does not provide the header <locale.h>. Take care yourself. */"
+ fi
+
+
+ test -d intl || mkdir intl
+ if test "$CATOBJEXT" = ".cat"; then
+ ac_safe=`echo "linux/version.h" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for linux/version.h""... $ac_c" 1>&6
+echo "configure:7691: checking for linux/version.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 7696 "configure"
+#include "confdefs.h"
+#include <linux/version.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:7701: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ msgformat=linux
+else
+ echo "$ac_t""no" 1>&6
+msgformat=xopen
+fi
+
+
+ sed -e '/^#/d' $srcdir/intl/$msgformat-msg.sed > intl/po2msg.sed
+ fi
+ sed -e '/^#.*[^\\]$/d' -e '/^#$/d' \
+ $srcdir/intl/po2tbl.sed.in > intl/po2tbl.sed
+
+ if test "$PACKAGE" = "gettext"; then
+ GT_NO="#NO#"
+ GT_YES=
+ else
+ GT_NO=
+ GT_YES="#YES#"
+ fi
+
+
+
+ MKINSTALLDIRS=
+ if test -n "$ac_aux_dir"; then
+ MKINSTALLDIRS="$ac_aux_dir/mkinstalldirs"
+ fi
+ if test -z "$MKINSTALLDIRS"; then
+ MKINSTALLDIRS="\$(top_srcdir)/mkinstalldirs"
+ fi
+
+
+ l=
+
+
+ test -d po || mkdir po
+ if test "x$srcdir" != "x."; then
+ if test "x`echo $srcdir | sed 's@/.*@@'`" = "x"; then
+ posrcprefix="$srcdir/"
+ else
+ posrcprefix="../$srcdir/"
+ fi
+ else
+ posrcprefix="../"
+ fi
+ rm -f po/POTFILES
+ sed -e "/^#/d" -e "/^\$/d" -e "s,.*, $posrcprefix& \\\\," -e "\$s/\(.*\) \\\\/\1/" \
+ < $srcdir/po/POTFILES.in > po/POTFILES
+
+XGETTEXT="AWK='$AWK' \$(SHELL) \$(top_srcdir)/exgettext $XGETTEXT"
+
# Get an absolute path to the GCC top-level source directory
holddir=`pwd`
cd $srcdir
@@ -5520,28 +7820,28 @@ out_object_file=`basename $out_file .c`.o
tm_file_list=
for f in $tm_file; do
- tm_file_list="${tm_file_list} \$(srcdir)/config/$f"
+ if test $f != "gansidecl.h" ; then
+ tm_file_list="${tm_file_list} \$(srcdir)/config/$f"
+ else
+ tm_file_list="${tm_file_list} $f"
+ fi
done
host_xm_file_list=
for f in $host_xm_file; do
- if test $f != "auto-host.h"; then
+ if test $f != "auto-host.h" -a $f != "gansidecl.h" ; then
host_xm_file_list="${host_xm_file_list} \$(srcdir)/config/$f"
else
- host_xm_file_list="${host_xm_file_list} auto-host.h"
+ host_xm_file_list="${host_xm_file_list} $f"
fi
done
build_xm_file_list=
for f in $build_xm_file; do
- if test $f != "auto-build.h"; then
- if test $f != "auto-host.h"; then
- build_xm_file_list="${build_xm_file_list} \$(srcdir)/config/$f"
- else
- build_xm_file_list="${build_xm_file_list} auto-host.h"
- fi
+ if test $f != "auto-build.h" -a $f != "auto-host.h" -a $f != "gansidecl.h" ; then
+ build_xm_file_list="${build_xm_file_list} \$(srcdir)/config/$f"
else
- build_xm_file_list="${build_xm_file_list} auto-build.h"
+ build_xm_file_list="${build_xm_file_list} $f"
fi
done
@@ -5629,16 +7929,18 @@ fi
# Figure out what assembler alignment features are present.
echo $ac_n "checking assembler alignment features""... $ac_c" 1>&6
-echo "configure:5633: checking assembler alignment features" >&5
+echo "configure:7933: checking assembler alignment features" >&5
gcc_cv_as=
gcc_cv_as_alignment_features=
gcc_cv_as_gas_srcdir=`echo $srcdir | sed -e 's,/gcc$,,'`/gas
-if test -x "$AS"; then
- gcc_cv_as=$AS
+if test -x "$DEFAULT_ASSEMBLER"; then
+ gcc_cv_as="$DEFAULT_ASSEMBLER"
+elif test -x "$AS"; then
+ gcc_cv_as="$AS"
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; then
+elif test -f $gcc_cv_as_gas_srcdir/configure.in -a -f ../gas/Makefile; then
# Single tree build which includes gas.
for f in $gcc_cv_as_gas_srcdir/configure $gcc_cv_as_gas_srcdir/configure.in $gcc_cv_as_gas_srcdir/Makefile.in
do
@@ -5700,7 +8002,7 @@ fi
echo "$ac_t""$gcc_cv_as_alignment_features" 1>&6
echo $ac_n "checking assembler subsection support""... $ac_c" 1>&6
-echo "configure:5704: checking assembler subsection support" >&5
+echo "configure:8006: checking assembler subsection support" >&5
gcc_cv_as_subsections=
if test x$gcc_cv_as != x; then
# Check if we have .subsection
@@ -5740,6 +8042,16 @@ fi
echo "$ac_t""$gcc_cv_as_subsections" 1>&6
# Figure out what language subdirectories are present.
+# Look if the user specified --enable-languages="..."; if not, use
+# the environment variable $LANGUAGES if defined. $LANGUAGES might
+# go away some day.
+if test x"${enable_languages+set}" != xset; then
+ if test x"${LANGUAGES+set}" = xset; then
+ enable_languages="`echo ${LANGUAGES} | tr ' ' ','`"
+ else
+ enable_languages=all
+ fi
+fi
subdirs=
for lang in ${srcdir}/*/config-lang.in ..
do
@@ -5747,13 +8059,39 @@ do
..) ;;
# The odd quoting in the next line works around
# an apparent bug in bash 1.12 on linux.
- ${srcdir}/ada/config-lang.in)
- if test x$gnat = xyes ; then
- subdirs="$subdirs `echo $lang | sed -e 's,^.*/\([^/]*\)/config-lang.in$,\1,'`"
- fi
- ;;
${srcdir}/[*]/config-lang.in) ;;
- *) subdirs="$subdirs `echo $lang | sed -e 's,^.*/\([^/]*\)/config-lang.in$,\1,'`" ;;
+ *)
+ 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
+ if test x"${enable_languages}" = xall; then
+ add_this_lang=yes
+ else
+ case "${enable_languages}" in
+ ${lang_alias} | "${lang_alias},"* | *",${lang_alias},"* | *",${lang_alias}" )
+ add_this_lang=yes
+ ;;
+ * )
+ add_this_lang=no
+ ;;
+ esac
+ fi
+ if test x"${add_this_lang}" = xyes; then
+ case $lang in
+ ${srcdir}/ada/config-lang.in)
+ if test x$gnat = xyes ; then
+ subdirs="$subdirs `echo $lang | sed -e 's,^.*/\([^/]*\)/config-lang.in$,\1,'`"
+ fi
+ ;;
+ *)
+ subdirs="$subdirs `echo $lang | sed -e 's,^.*/\([^/]*\)/config-lang.in$,\1,'`"
+ ;;
+ esac
+ fi
+ ;;
esac
done
@@ -5797,7 +8135,7 @@ all_boot_languages=
all_compilers=
all_stagestuff=
all_diff_excludes=
-all_outputs=Makefile
+all_outputs='Makefile intl/Makefile po/Makefile.in fixinc/Makefile'
# List of language makefile fragments.
all_lang_makefiles=
all_headers=
@@ -5865,10 +8203,10 @@ target_list="all.build all.cross start.encap rest.encap \
for t in $target_list
do
x=
- for l in .. $all_languages
+ for lang in .. $all_languages
do
- if test $l != ".."; then
- x="$x $l.$t"
+ if test $lang != ".."; then
+ x="$x $lang.$t"
fi
done
echo "lang.$t: $x" >> Make-hooks
@@ -5926,7 +8264,7 @@ fi
if test x$enable_haifa != x; then
# Explicitly remove files that need to be recompiled for the Haifa scheduler.
- for x in genattrtab.o toplev.o loop.o unroll.o *sched.o; do
+ for x in genattrtab.o toplev.o *sched.o; do
if test -f $x; then
echo "Removing $x"
rm -f $x
@@ -5934,13 +8272,42 @@ if test x$enable_haifa != x; then
done
fi
-# Warn if using init_priority.
-echo $ac_n "checking whether to enable init_priority by default""... $ac_c" 1>&6
-echo "configure:5940: checking whether to enable init_priority by default" >&5
-if test x$enable_init_priority != xyes; then
- enable_init_priority=no
+# 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_alias)'
+else
+# 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 occurance 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_alias)"
fi
-echo "$ac_t""$enable_init_priority" 1>&6
+
+
# Nothing to do for FLOAT_H, float_format already handled.
objdir=`pwd`
@@ -6007,6 +8374,9 @@ ${CONFIG_SHELL-/bin/sh} $srcdir/configure.frag $srcdir "$subdirs" "$dep_host_xma
+
+
+
# Echo that links are built
if test x$host = x$target
then
@@ -6066,7 +8436,7 @@ EOF
# Ultrix sh set writes to stderr and can't be redirected directly,
# and sets the high bit in the cache file unless we assign to the vars.
(set) 2>&1 |
- case `(ac_space=' '; set) 2>&1 | grep ac_space` in
+ case `(ac_space=' '; set | grep ac_space) 2>&1` in
*ac_space=\ *)
# `set' does not quote correctly, so add quotes (double-quote substitution
# turns \\\\ into \\, and sed turns \\ into \).
@@ -6133,7 +8503,7 @@ do
echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
-version | --version | --versio | --versi | --vers | --ver | --ve | --v)
- echo "$CONFIG_STATUS generated by autoconf version 2.12.2"
+ echo "$CONFIG_STATUS generated by autoconf version 2.13"
exit 0 ;;
-help | --help | --hel | --he | --h)
echo "\$ac_cs_usage"; exit 0 ;;
@@ -6156,6 +8526,7 @@ s%@SHELL@%$SHELL%g
s%@CFLAGS@%$CFLAGS%g
s%@CPPFLAGS@%$CPPFLAGS%g
s%@CXXFLAGS@%$CXXFLAGS%g
+s%@FFLAGS@%$FFLAGS%g
s%@DEFS@%$DEFS%g
s%@LDFLAGS@%$LDFLAGS%g
s%@LIBS@%$LIBS%g
@@ -6208,6 +8579,30 @@ s%@vfprintf@%$vfprintf%g
s%@doprint@%$doprint%g
s%@manext@%$manext%g
s%@objext@%$objext%g
+s%@PACKAGE@%$PACKAGE%g
+s%@VERSION@%$VERSION%g
+s%@ALLOCA@%$ALLOCA%g
+s%@USE_NLS@%$USE_NLS%g
+s%@MSGFMT@%$MSGFMT%g
+s%@GMSGFMT@%$GMSGFMT%g
+s%@XGETTEXT@%$XGETTEXT%g
+s%@GENCAT@%$GENCAT%g
+s%@USE_INCLUDED_LIBINTL@%$USE_INCLUDED_LIBINTL%g
+s%@CATALOGS@%$CATALOGS%g
+s%@CATOBJEXT@%$CATOBJEXT%g
+s%@DATADIRNAME@%$DATADIRNAME%g
+s%@GMOFILES@%$GMOFILES%g
+s%@INSTOBJEXT@%$INSTOBJEXT%g
+s%@INTLDEPS@%$INTLDEPS%g
+s%@INTLLIBS@%$INTLLIBS%g
+s%@INTLOBJS@%$INTLOBJS%g
+s%@POFILES@%$POFILES%g
+s%@POSUB@%$POSUB%g
+s%@INCLUDE_LOCALE_H@%$INCLUDE_LOCALE_H%g
+s%@GT_NO@%$GT_NO%g
+s%@GT_YES@%$GT_YES%g
+s%@MKINSTALLDIRS@%$MKINSTALLDIRS%g
+s%@l@%$l%g
s%@gthread_flags@%$gthread_flags%g
s%@build_canonical@%$build_canonical%g
s%@host_canonical@%$host_canonical%g
@@ -6215,55 +8610,59 @@ s%@target_subdir@%$target_subdir%g
s%@inhibit_libc@%$inhibit_libc%g
s%@sched_prefix@%$sched_prefix%g
s%@sched_cflags@%$sched_cflags%g
+s%@gcc_tooldir@%$gcc_tooldir%g
+s%@dollar@%$dollar%g
s%@objdir@%$objdir%g
s%@subdirs@%$subdirs%g
-s%@all_languages@%$all_languages%g
s%@all_boot_languages@%$all_boot_languages%g
s%@all_compilers@%$all_compilers%g
-s%@all_lang_makefiles@%$all_lang_makefiles%g
-s%@all_stagestuff@%$all_stagestuff%g
s%@all_diff_excludes@%$all_diff_excludes%g
-s%@all_lib2funcs@%$all_lib2funcs%g
s%@all_headers@%$all_headers%g
+s%@all_lang_makefiles@%$all_lang_makefiles%g
+s%@all_languages@%$all_languages%g
+s%@all_lib2funcs@%$all_lib2funcs%g
+s%@all_stagestuff@%$all_stagestuff%g
+s%@build_exeext@%$build_exeext%g
+s%@build_install_headers_dir@%$build_install_headers_dir%g
+s%@build_xm_file_list@%$build_xm_file_list%g
+s%@cc_set_by_configure@%$cc_set_by_configure%g
+s%@cpp_install_dir@%$cpp_install_dir%g
s%@cpp_main@%$cpp_main%g
-s%@extra_passes@%$extra_passes%g
-s%@extra_programs@%$extra_programs%g
-s%@extra_parts@%$extra_parts%g
+s%@dep_host_xmake_file@%$dep_host_xmake_file%g
+s%@dep_tmake_file@%$dep_tmake_file%g
+s%@extra_c_flags@%$extra_c_flags%g
s%@extra_c_objs@%$extra_c_objs%g
-s%@extra_cxx_objs@%$extra_cxx_objs%g
s%@extra_cpp_objs@%$extra_cpp_objs%g
-s%@extra_c_flags@%$extra_c_flags%g
+s%@extra_cxx_objs@%$extra_cxx_objs%g
+s%@extra_headers_list@%$extra_headers_list%g
s%@extra_objs@%$extra_objs%g
+s%@extra_parts@%$extra_parts%g
+s%@extra_passes@%$extra_passes%g
+s%@extra_programs@%$extra_programs%g
+s%@fixinc_defs@%$fixinc_defs%g
+s%@float_h_file@%$float_h_file%g
+s%@gcc_gxx_include_dir@%$gcc_gxx_include_dir%g
+s%@gcc_version@%$gcc_version%g
+s%@gcc_version_trigger@%$gcc_version_trigger%g
+s%@host_exeext@%$host_exeext%g
s%@host_extra_gcc_objs@%$host_extra_gcc_objs%g
-s%@extra_headers_list@%$extra_headers_list%g
-s%@dep_host_xmake_file@%$dep_host_xmake_file%g
-s%@dep_tmake_file@%$dep_tmake_file%g
-s%@out_file@%$out_file%g
-s%@out_object_file@%$out_object_file%g
-s%@md_file@%$md_file%g
-s%@tm_file_list@%$tm_file_list%g
-s%@build_xm_file_list@%$build_xm_file_list%g
s%@host_xm_file_list@%$host_xm_file_list%g
-s%@lang_specs_files@%$lang_specs_files%g
+s%@install@%$install%g
+s%@JAVAGC@%$JAVAGC%g
s%@lang_options_files@%$lang_options_files%g
+s%@lang_specs_files@%$lang_specs_files%g
s%@lang_tree_files@%$lang_tree_files%g
-s%@thread_file@%$thread_file%g
-s%@objc_boehm_gc@%$objc_boehm_gc%g
-s%@gcc_version@%$gcc_version%g
-s%@gcc_version_trigger@%$gcc_version_trigger%g
s%@local_prefix@%$local_prefix%g
-s%@gxx_include_dir@%$gxx_include_dir%g
-s%@fixincludes@%$fixincludes%g
-s%@build_install_headers_dir@%$build_install_headers_dir%g
-s%@build_exeext@%$build_exeext%g
-s%@host_exeext@%$host_exeext%g
-s%@float_format@%$float_format%g
-s%@will_use_collect2@%$will_use_collect2%g
s%@maybe_use_collect2@%$maybe_use_collect2%g
-s%@cc_set_by_configure@%$cc_set_by_configure%g
+s%@md_file@%$md_file%g
+s%@objc_boehm_gc@%$objc_boehm_gc%g
+s%@out_file@%$out_file%g
+s%@out_object_file@%$out_object_file%g
s%@stage_prefix_set_by_configure@%$stage_prefix_set_by_configure%g
-s%@install@%$install%g
s%@symbolic_link@%$symbolic_link%g
+s%@thread_file@%$thread_file%g
+s%@tm_file_list@%$tm_file_list%g
+s%@will_use_collect2@%$will_use_collect2%g
/@target_overrides@/r $target_overrides
s%@target_overrides@%%g
/@host_overrides@/r $host_overrides
@@ -6480,7 +8879,53 @@ cat >> $CONFIG_STATUS <<\EOF
fi; done
EOF
+
cat >> $CONFIG_STATUS <<EOF
+ac_sources="$nls_cv_header_libgt"
+ac_dests="$nls_cv_header_intl"
+EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+srcdir=$ac_given_srcdir
+while test -n "$ac_sources"; do
+ set $ac_dests; ac_dest=$1; shift; ac_dests=$*
+ set $ac_sources; ac_source=$1; shift; ac_sources=$*
+
+ echo "linking $srcdir/$ac_source to $ac_dest"
+
+ if test ! -r $srcdir/$ac_source; then
+ { echo "configure: error: $srcdir/$ac_source: File not found" 1>&2; exit 1; }
+ fi
+ rm -f $ac_dest
+
+ # Make relative symlinks.
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dest_dir=`echo $ac_dest|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dest_dir" != "$ac_dest" && test "$ac_dest_dir" != .; then
+ # The dest file is in a subdirectory.
+ test ! -d "$ac_dest_dir" && mkdir "$ac_dest_dir"
+ ac_dest_dir_suffix="/`echo $ac_dest_dir|sed 's%^\./%%'`"
+ # A "../" for each directory in $ac_dest_dir_suffix.
+ ac_dots=`echo $ac_dest_dir_suffix|sed 's%/[^/]*%../%g'`
+ else
+ ac_dest_dir_suffix= ac_dots=
+ fi
+
+ case "$srcdir" in
+ [/$]*) ac_rel_source="$srcdir/$ac_source" ;;
+ *) ac_rel_source="$ac_dots$srcdir/$ac_source" ;;
+ esac
+
+ # Make a symlink if possible; otherwise try a hard link.
+ if ln -s $ac_rel_source $ac_dest 2>/dev/null ||
+ ln $srcdir/$ac_source $ac_dest; then :
+ else
+ { echo "configure: error: can not link $ac_dest to $srcdir/$ac_source" 1>&2; exit 1; }
+ fi
+done
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
host='${host}'
build='${build}'
@@ -6512,9 +8957,13 @@ host_overrides='${host_overrides}'
cross_defines='${cross_defines}'
cross_overrides='${cross_overrides}'
build_overrides='${build_overrides}'
+cpp_install_dir='${cpp_install_dir}'
EOF
cat >> $CONFIG_STATUS <<\EOF
+case "$CONFIG_FILES" in *po/Makefile.in*)
+ sed -e "/POTFILES =/r po/POTFILES" po/Makefile.in > po/Makefile
+ esac
. $srcdir/configure.lang
case x$CONFIG_HEADERS in
@@ -6541,6 +8990,11 @@ if test "$symbolic_link" = "ln -s"; then
fi
done
else true ; fi
+# Avoid having to add intl to our include paths.
+if test -f intl/libintl.h; then
+ echo creating libintl.h
+ echo '#include "intl/libintl.h"' >libintl.h
+fi
exit 0
EOF
diff --git a/gcc/configure.in b/gcc/configure.in
index ceab2a8e7d9..18a66807e34 100644
--- a/gcc/configure.in
+++ b/gcc/configure.in
@@ -1,7 +1,7 @@
# configure.in for GNU CC
# Process this file with autoconf to generate a configuration script.
-# Copyright (C) 1997, 1998 Free Software Foundation, Inc.
+# Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc.
#This file is part of GNU CC.
@@ -21,6 +21,7 @@
#Boston, MA 02111-1307, USA.
# Initialization and defaults
+AC_PREREQ(2.12.1)
AC_INIT(tree.c)
AC_CONFIG_HEADER(auto-host.h:config.in)
@@ -93,14 +94,14 @@ gnu_ld_flag=no)
# With pre-defined ld
AC_ARG_WITH(ld,
[ --with-ld arrange to use the specified ld (full pathname).],
-LD="$with_ld")
-if test x"${LD+set}" = x"set"; then
- if test ! -x "$LD"; then
- AC_MSG_WARN([cannot execute: $LD: check --with-ld or env. var. LD])
- elif test "GNU" = `$LD -v </dev/null 2>&1 | sed '1s/^GNU.*/GNU/;q'`; then
+DEFAULT_LINKER="$with_ld")
+if test x"${DEFAULT_LINKER+set}" = x"set"; then
+ if test ! -x "$DEFAULT_LINKER"; then
+ AC_MSG_WARN([cannot execute: $DEFAULT_LINKER: check --with-ld or env. var. DEFAULT_LINKER])
+ elif test "GNU" = `$DEFAULT_LINKER -v </dev/null 2>&1 | sed '1s/^GNU.*/GNU/;q'`; then
gnu_ld_flag=yes
fi
- AC_DEFINE_UNQUOTED(DEFAULT_LINKER,"$LD")
+ AC_DEFINE_UNQUOTED(DEFAULT_LINKER,"$DEFAULT_LINKER")
fi
# With GNU as
@@ -111,14 +112,14 @@ gas_flag=no)
AC_ARG_WITH(as,
[ --with-as arrange to use the specified as (full pathname).],
-AS="$with_as")
-if test x"${AS+set}" = x"set"; then
- if test ! -x "$AS"; then
- AC_MSG_WARN([cannot execute: $AS: check --with-as or env. var. AS])
- elif test "GNU" = `$AS -v </dev/null 2>&1 | sed '1s/^GNU.*/GNU/;q'`; then
+DEFAULT_ASSEMBLER="$with_as")
+if test x"${DEFAULT_ASSEMBLER+set}" = x"set"; then
+ if test ! -x "$DEFAULT_ASSEMBLER"; then
+ AC_MSG_WARN([cannot execute: $DEFAULT_ASSEMBLER: check --with-as or env. var. DEFAULT_ASSEMBLER])
+ elif test "GNU" = `$DEFAULT_ASSEMBLER -v </dev/null 2>&1 | sed '1s/^GNU.*/GNU/;q'`; then
gas_flag=yes
fi
- AC_DEFINE_UNQUOTED(DEFAULT_ASSEMBLER,"$AS")
+ AC_DEFINE_UNQUOTED(DEFAULT_ASSEMBLER,"$DEFAULT_ASSEMBLER")
fi
# With stabs
@@ -148,7 +149,10 @@ if test x$local_prefix = x; then
local_prefix=/usr/local
fi
-gxx_include_dir=
+# 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
@@ -156,15 +160,17 @@ AC_ARG_WITH(gxx-include-dir,
[case "${withval}" in
yes) AC_MSG_ERROR(bad value ${withval} given for g++ include directory) ;;
no) ;;
-*) gxx_include_dir=$with_gxx_include_dir ;;
+*) gcc_gxx_include_dir=$with_gxx_include_dir ;;
esac])
-if test x${gxx_include_dir} = x; then
+if test x${gcc_gxx_include_dir} = x; then
if test x${enable_version_specific_runtime_libs} = xyes; then
- gxx_include_dir='${libsubdir}/include/g++'
+ gcc_gxx_include_dir='${libsubdir}/include/g++'
else
topsrcdir=${srcdir}/.. . ${srcdir}/../config.if
- gxx_include_dir='${prefix}/include/g++'-${libstdcxx_interface}
+changequote(<<, >>)dnl
+ gcc_gxx_include_dir="\$(libsubdir)/\$(unlibsubdir)/..\`echo \$(exec_prefix) | sed -e 's|^\$(prefix)||' -e 's|/[^/]*|/..|g'\`/include/g++"-${libstdcxx_interface}
+changequote([, ])dnl
fi
fi
@@ -190,10 +196,9 @@ AC_ARG_ENABLE(c-cpplib,
[ --enable-c-cpplib link cpplib directly into C and C++ compilers
(implies --enable-cpplib).],
if test x$enable_c_cpplib != xno; then
- extra_c_objs="${extra_c_objs} cpplib.o cppexp.o cpphash.o cpperror.o"
- extra_c_objs="${extra_c_objs} prefix.o"
- extra_cxx_objs="${extra_cxx_objs} ../cpplib.o ../cppexp.o ../cpphash.o ../cpperror.o ../prefix.o"
- extra_c_flags=-DUSE_CPPLIB=1
+ extra_c_objs="${extra_c_objs} libcpp.a"
+ extra_cxx_objs="${extra_cxx_objs} ../libcpp.a"
+ extra_c_flags="${extra_c_flags} -DUSE_CPPLIB=1"
cpp_main=cppmain
fi)
@@ -209,23 +214,6 @@ AC_ARG_ENABLE(haifa,
[ --enable-haifa use the experimental scheduler.
--disable-haifa don't use the experimental scheduler for the
targets which normally enable it.])
-# Fast fixincludes
-#
-# This is a work in progress...
-AC_ARG_WITH(fast-fixincludes,
-[ --with-fast-fixincludes use a faster fixinclude program (experimental)],
-fast_fixinc="$with_fast_fixincludes",
-fast_fixinc=no)
-
-# Enable init_priority.
-AC_ARG_ENABLE(init-priority,
-[ --enable-init-priority use attributes to assign initialization order
- for static objects.
- --disable-init-priority conform to ISO C++ rules for ordering static objects
- (i.e. initialized in order of declaration). ],
-if test x$enable_init_priority != xno; then
- extra_c_flags=-DUSE_INIT_PRIORITY
-fi)
# Enable threads
# Pass with no value to take the default
@@ -269,6 +257,18 @@ else
fi,
objc_boehm_gc='')
+AC_ARG_ENABLE(java-gc,
+changequote(<<,>>)dnl
+<< --enable-java-gc=TYPE choose garbage collector [boehm]>>,
+changequote([,])
+ JAVAGC=$enableval,
+ JAVAGC=boehm)
+
+AC_ARG_WITH(dwarf2,
+[ --enable-dwarf2 enable DWARF2 debugging as default.],
+dwarf2="$with_dwarf2",
+dwarf2=no)
+
# Determine the host, build, and target systems
AC_CANONICAL_SYSTEM
@@ -288,22 +288,22 @@ AC_SUBST(stage1_warn_cflags)
AC_PROG_MAKE_SET
AC_MSG_CHECKING([whether a default assembler was specified])
-if test x"${AS+set}" = x"set"; then
+if test x"${DEFAULT_ASSEMBLER+set}" = x"set"; then
if test x"$with_gas" = x"no"; then
- AC_MSG_RESULT([yes ($AS)])
+ AC_MSG_RESULT([yes ($DEFAULT_ASSEMBLER)])
else
- AC_MSG_RESULT([yes ($AS - GNU as)])
+ AC_MSG_RESULT([yes ($DEFAULT_ASSEMBLER - GNU as)])
fi
else
AC_MSG_RESULT(no)
fi
AC_MSG_CHECKING([whether a default linker was specified])
-if test x"${LD+set}" = x"set"; then
+if test x"${DEFAULT_LINKER+set}" = x"set"; then
if test x"$with_gnu_ld" = x"no"; then
- AC_MSG_RESULT([yes ($LD)])
+ AC_MSG_RESULT([yes ($DEFAULT_LINKER)])
else
- AC_MSG_RESULT([yes ($LD - GNU ld)])
+ AC_MSG_RESULT([yes ($DEFAULT_LINKER - GNU ld)])
fi
else
AC_MSG_RESULT(no)
@@ -322,7 +322,8 @@ EGCS_PROG_INSTALL
AC_HEADER_STDC
AC_HEADER_TIME
GCC_HEADER_STRING
-AC_CHECK_HEADERS(limits.h stddef.h string.h strings.h stdlib.h time.h fcntl.h unistd.h stab.h sys/file.h sys/time.h sys/resource.h sys/param.h sys/times.h wait.h sys/wait.h)
+AC_HEADER_SYS_WAIT
+AC_CHECK_HEADERS(limits.h stddef.h string.h strings.h stdlib.h time.h fcntl.h unistd.h stab.h sys/file.h sys/time.h sys/resource.h sys/param.h sys/times.h sys/stat.h)
# Check for thread headers.
AC_CHECK_HEADER(thread.h, [have_thread_h=yes], [have_thread_h=])
@@ -352,14 +353,17 @@ AC_CACHE_VAL(gcc_cv_header_inttypes_h,
[#include <sys/types.h>
#include <inttypes.h>],
[intmax_t i = -1;],
- [AC_DEFINE_UNQUOTED(HAVE_INTTYPES_H)
- gcc_cv_header_inttypes_h=yes],
+ [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)
+fi
AC_CHECK_FUNCS(strtoul bsearch strerror putenv popen bcopy bzero bcmp \
index rindex strchr strrchr kill getrlimit setrlimit atoll atoq \
- sysconf isascii gettimeofday strsignal)
+ sysconf isascii gettimeofday strsignal putc_unlocked fputc_unlocked \
+ fputs_unlocked)
# Make sure wchar_t is available
#AC_CHECK_TYPE(wchar_t, unsigned int)
@@ -367,9 +371,19 @@ AC_CHECK_FUNCS(strtoul bsearch strerror putenv popen bcopy bzero bcmp \
GCC_FUNC_VFPRINTF_DOPRNT
GCC_FUNC_PRINTF_PTR
+case "${host}" in
+*-*-uwin*)
+ # Under some versions of uwin, vfork is notoriously buggy and the test
+ # can hang configure; on other versions, vfork exists just as a stub.
+ # FIXME: This should be removed once vfork in uwin's runtime is fixed.
+ ac_cv_func_vfork_works=no
+ ;;
+esac
+AC_FUNC_VFORK
+
GCC_NEED_DECLARATIONS(malloc realloc calloc free bcopy bzero bcmp \
index rindex getenv atol sbrk abort atof strerror getcwd getwd \
- strsignal)
+ strsignal putc_unlocked fputs_unlocked)
GCC_NEED_DECLARATIONS(getrlimit setrlimit, [
#include <sys/types.h>
@@ -396,6 +410,9 @@ host_xmake_file=
host_truncate_target=
host_exeext=
+# It is relative to $prefix.
+cpp_install_dir=
+
# Decode the host machine, then the target machine.
# For the host machine, we save the xm_file variable as host_xm_file;
# then we decode the target machine and forget everything else
@@ -418,10 +435,6 @@ for machine in $build $host $target; do
use_collect2=
# Set this to override the default target model.
target_cpu_default=
- # Set this to control which fixincludes program to use.
- if test x$fast_fixinc != xyes; then
- fixincludes=fixincludes
- else fixincludes=fixinc.sh ; fi
# Set this to control how the header file directory is installed.
install_headers_dir=install-headers-tar
# Set this to a non-empty list of args to pass to cpp if the target
@@ -483,11 +496,23 @@ changequote([,])dnl
tm_file=${cpu_type}/${cpu_type}.h
xm_file=${cpu_type}/xm-${cpu_type}.h
- # Set the default macros to define for GNU/Linux systems.
+ # Common parts for linux-gnu and openbsd systems
case $machine in
*-*-linux-gnu*)
xm_defines="HAVE_ATEXIT POSIX BSTRING"
;;
+ *-*-openbsd*)
+ tm_file=${cpu_type}/openbsd.h
+ # On OpenBSD systems, the headers are okay
+ fixincludes=Makefile.in
+ tmake_file="t-libc-ok t-openbsd"
+ # avoid surprises, always provide an xm-openbsd file
+ xm_file=${cpu_type}/xm-openbsd.h
+ if test x$enable_threads = xyes; then
+ thread_file='posix'
+ tmake_file="${tmake_file} t-openbsd-thread"
+ fi
+ ;;
esac
case $machine in
@@ -539,7 +564,6 @@ changequote([,])dnl
target_cpu_default="MASK_GAS"
tmake_file="t-linux t-linux-gnulibc1 alpha/t-linux alpha/t-crtbe"
extra_parts="crtbegin.o crtend.o"
- fixincludes=fixinc.wrap
xmake_file=none
gas=yes gnu_ld=yes
if test x$enable_threads = xyes; then
@@ -552,21 +576,25 @@ changequote([,])dnl
tmake_file="t-linux alpha/t-linux alpha/t-crtbe"
extra_parts="crtbegin.o crtend.o"
xmake_file=none
- fixincludes=Makefile.in
gas=yes gnu_ld=yes
if test x$enable_threads = xyes; then
thread_file='posix'
fi
;;
alpha*-*-netbsd*)
- tm_file="${tm_file} alpha/elf.h alpha/netbsd.h alpha/netbsdl-elf.h"
+ tm_file="${tm_file} alpha/elf.h alpha/netbsd.h alpha/netbsd-elf.h"
target_cpu_default="MASK_GAS"
tmake_file="alpha/t-crtbe"
extra_parts="crtbegin.o crtend.o"
xmake_file=none
- fixincludes=fixinc.wrap
gas=yes gnu_ld=yes
;;
+
+ alpha*-*-openbsd*)
+ # default x-alpha is only appropriate for dec-osf.
+ target_cpu_default="MASK_GAS"
+ xmake_file=none
+ ;;
alpha*-dec-osf*)
if test x$stabs = xyes
@@ -617,7 +645,6 @@ changequote([,])dnl
xmake_file=winnt/x-winnt
extra_host_objs=oldnames.o
extra_gcc_objs="spawnv.o oldnames.o"
- fixincludes=fixinc.winnt
if test x$gnu_ld != xyes
then
extra_programs=ld.exe
@@ -630,7 +657,6 @@ changequote([,])dnl
tm_file=alpha/vms.h
xm_file="${xm_file} alpha/xm-vms.h"
tmake_file=alpha/t-vms
- fixincludes=Makefile.in
;;
arc-*-elf*)
extra_parts="crtinit.o crtfini.o"
@@ -639,6 +665,10 @@ changequote([,])dnl
tm_file=arm/coff.h
tmake_file=arm/t-bare
;;
+ arm-*-vxworks*)
+ tm_file=arm/vxarm.h
+ tmake_file=arm/t-bare
+ ;;
changequote(,)dnl
arm-*-riscix1.[01]*) # Acorn RISC machine (early versions)
changequote([,])dnl
@@ -659,56 +689,78 @@ changequote([,])dnl
arm-semi-aout | armel-semi-aout)
tm_file=arm/semi.h
tmake_file=arm/t-semi
- fixincludes=Makefile.in # There is nothing to fix
;;
arm-semi-aof | armel-semi-aof)
tm_file=arm/semiaof.h
tmake_file=arm/t-semiaof
- fixincludes=Makefile.in # There is nothing to fix
;;
arm*-*-netbsd*)
tm_file=arm/netbsd.h
xm_file="arm/xm-netbsd.h ${xm_file}"
tmake_file="t-netbsd arm/t-netbsd"
- # On NetBSD, the headers are already okay, except for math.h.
- fixincludes=fixinc.wrap
;;
- arm-*-linux-gnuaout*) # ARM GNU/Linux
+ arm*-*-linux-gnuaout*) # ARM GNU/Linux with a.out
cpu_type=arm
xmake_file=x-linux
- tm_file=arm/linux-gas.h
+ tm_file=arm/linux-aout.h
tmake_file=arm/t-linux
- fixincludes=Makefile.in
gnu_ld=yes
;;
- arm-*-aout)
+ arm*-*-linux-gnu*) # ARM GNU/Linux with ELF
+ xm_file=arm/xm-linux.h
+ xmake_file=x-linux
+ case $machine in
+ armv2*-*-*)
+ tm_file=arm/linux-elf26.h
+ ;;
+ *)
+ tm_file=arm/linux-elf.h
+ ;;
+ esac
+ tmake_file="t-linux arm/t-linux"
+ extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o"
+ gnu_ld=yes
+ case x${enable_threads} in
+ x | xyes | xpthreads | xposix)
+ thread_file='posix'
+ ;;
+ esac
+ ;;
+ arm*-*-aout)
tm_file=arm/aout.h
tmake_file=arm/t-bare
;;
+ arm*-*-ecos-elf)
+ tm_file=arm/ecos-elf.h
+ tmake_file=arm/t-elf
+ ;;
+ arm*-*-elf)
+ tm_file=arm/unknown-elf.h
+ tmake_file=arm/t-arm-elf
+ ;;
+ arm*-*-oabi)
+ tm_file=arm/unknown-elf-oabi.h
+ tmake_file=arm/t-arm-elf
+ ;;
c1-convex-*) # Convex C1
target_cpu_default=1
use_collect2=yes
- fixincludes=Makefile.in
;;
c2-convex-*) # Convex C2
target_cpu_default=2
use_collect2=yes
- fixincludes=Makefile.in
;;
c32-convex-*)
target_cpu_default=4
use_collect2=yes
- fixincludes=Makefile.in
;;
c34-convex-*)
target_cpu_default=8
use_collect2=yes
- fixincludes=Makefile.in
;;
c38-convex-*)
target_cpu_default=16
use_collect2=yes
- fixincludes=Makefile.in
;;
c4x-*)
cpu_type=c4x
@@ -733,16 +785,19 @@ changequote([,])dnl
h8300-*-*)
float_format=i32
;;
+ hppa*-*-openbsd*)
+ target_cpu_default="MASK_SNAKE"
+ tmake_file=pa/t-openbsd
+ ;;
hppa1.1-*-pro*)
tm_file="pa/pa-pro.h ${tm_file} pa/pa-pro-end.h libgloss.h"
xm_file=pa/xm-papro.h
tmake_file=pa/t-pro
;;
hppa1.1-*-osf*)
- target_cpu_default=1
+ target_cpu_default="MASK_SNAKE"
tm_file="${tm_file} pa/pa-osf.h"
use_collect2=yes
- fixincludes=Makefile.in
;;
hppa1.1-*-rtems*)
tm_file="pa/pa-pro.h ${tm_file} pa/pa-pro-end.h libgloss.h pa/rtems.h"
@@ -752,16 +807,13 @@ changequote([,])dnl
hppa1.0-*-osf*)
tm_file="${tm_file} pa/pa-osf.h"
use_collect2=yes
- fixincludes=Makefile.in
;;
hppa1.1-*-bsd*)
- target_cpu_default=1
+ target_cpu_default="MASK_SNAKE"
use_collect2=yes
- fixincludes=Makefile.in
;;
hppa1.0-*-bsd*)
use_collect2=yes
- fixincludes=Makefile.in
;;
hppa1.0-*-hpux7*)
tm_file="pa/pa-oldas.h ${tm_file} pa/pa-hpux7.h"
@@ -792,7 +844,7 @@ changequote([,])dnl
changequote(,)dnl
hppa1.1-*-hpux8.0[0-2]*)
changequote([,])dnl
- target_cpu_default=1
+ target_cpu_default="MASK_SNAKE"
tm_file="${tm_file} pa/pa-hpux.h"
xm_file=pa/xm-pahpux.h
xmake_file=pa/x-pa-hpux
@@ -806,7 +858,7 @@ changequote([,])dnl
use_collect2=yes
;;
hppa1.1-*-hpux8*)
- target_cpu_default=1
+ target_cpu_default="MASK_SNAKE"
tm_file="${tm_file} pa/pa-hpux.h"
xm_file=pa/xm-pahpux.h
xmake_file=pa/x-pa-hpux
@@ -828,8 +880,8 @@ changequote([,])dnl
install_headers_dir=install-headers-cpio
use_collect2=yes
;;
- hppa1.1-*-hpux10*)
- target_cpu_default=1
+ hppa1.1-*-hpux10* | hppa2*-*-hpux10*)
+ target_cpu_default="MASK_SNAKE"
tm_file="${tm_file} pa/pa-hpux.h pa/pa-hpux10.h"
xm_file=pa/xm-pahpux.h
xmake_file=pa/x-pa-hpux
@@ -852,6 +904,7 @@ changequote([,])dnl
tm_file="${tm_file} pa/pa-hpux.h pa/pa-hpux10.h"
xm_file=pa/xm-pahpux.h
xmake_file=pa/x-pa-hpux
+ tmake_file=pa/t-pa
if test x$gas = xyes
then
tm_file="${tm_file} pa/pa-gas.h"
@@ -866,8 +919,8 @@ changequote([,])dnl
install_headers_dir=install-headers-cpio
use_collect2=yes
;;
- hppa1.1-*-hpux*)
- target_cpu_default=1
+ hppa1.1-*-hpux* | hppa2*-*-hpux*)
+ target_cpu_default="MASK_SNAKE"
tm_file="${tm_file} pa/pa-hpux.h pa/pa-hpux9.h"
xm_file=pa/xm-pahpux.h
xmake_file=pa/x-pa-hpux
@@ -889,8 +942,8 @@ changequote([,])dnl
install_headers_dir=install-headers-cpio
use_collect2=yes
;;
- hppa1.1-*-hiux*)
- target_cpu_default=1
+ hppa1.1-*-hiux* | hppa2*-*-hiux*)
+ target_cpu_default="MASK_SNAKE"
tm_file="${tm_file} pa/pa-hpux.h pa/pa-hiux.h"
xm_file=pa/xm-pahpux.h
xmake_file=pa/x-pa-hpux
@@ -913,9 +966,8 @@ changequote([,])dnl
use_collect2=yes
;;
hppa*-*-lites*)
- target_cpu_default=1
+ target_cpu_default="MASK_SNAKE"
use_collect2=yes
- fixincludes=Makefile.in
;;
i370-*-mvs*)
;;
@@ -981,7 +1033,6 @@ changequote([,])dnl
xmake_file=i386/x-sysv3
tm_file=i386/seq-sysv3.h
tmake_file=i386/t-crtstuff
- fixincludes=fixinc.ptx
extra_parts="crtbegin.o crtend.o"
install_headers_dir=install-headers-cpio
;;
@@ -993,7 +1044,6 @@ changequote([,])dnl
tm_file=i386/seq2-sysv3.h
tmake_file=i386/t-crtstuff
extra_parts="crtbegin.o crtend.o"
- fixincludes=fixinc.ptx
install_headers_dir=install-headers-cpio
;;
changequote(,)dnl
@@ -1005,7 +1055,6 @@ changequote([,])dnl
tm_file=i386/ptx4-i.h
tmake_file=t-svr4
extra_parts="crtbegin.o crtend.o"
- fixincludes=fixinc.ptx
install_headers_dir=install-headers-cpio
;;
i386-sun-sunos*) # Sun i386 roadrunner
@@ -1045,6 +1094,7 @@ changequote([,])dnl
tm_file="i386/i386.h i386/att.h linux.h i386/freebsd-elf.h i386/perform.h"
# On FreeBSD, the headers are already ok, except for math.h.
fixincludes=fixinc.wrap
+ extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o"
tmake_file=i386/t-freebsd
gas=yes
gnu_ld=yes
@@ -1054,21 +1104,22 @@ changequote(,)dnl
i[34567]86-*-freebsd*)
changequote([,])dnl
tm_file=i386/freebsd.h
- # On FreeBSD, the headers are already ok, except for math.h.
- fixincludes=fixinc.wrap
tmake_file=i386/t-freebsd
;;
- # We are hoping OpenBSD is still close enough to NetBSD that we can
- # share the configurations.
changequote(,)dnl
- i[34567]86-*-netbsd* | i[34567]86-*-openbsd*)
+ i[34567]86-*-netbsd*)
changequote([,])dnl
tm_file=i386/netbsd.h
- # On NetBSD, the headers are already okay, except for math.h.
- fixincludes=fixinc.wrap
tmake_file=t-netbsd
;;
changequote(,)dnl
+ i[34567]86-*-openbsd*)
+changequote([,])dnl
+ # Remove when the math emulator is fixed
+ # we need collect2 until our bug is fixed...
+ use_collect2=yes
+ ;;
+changequote(,)dnl
i[34567]86-*-coff*)
changequote([,])dnl
tm_file=i386/i386-coff.h
@@ -1108,7 +1159,6 @@ changequote([,])dnl # with a.out format using
xmake_file=x-linux-aout
tmake_file="t-linux-aout i386/t-crtstuff"
tm_file=i386/linux-oldld.h
- fixincludes=Makefile.in #On Linux, the headers are ok already.
gnu_ld=yes
float_format=i386
;;
@@ -1118,7 +1168,6 @@ changequote([,])dnl # with a.out format
xmake_file=x-linux-aout
tmake_file="t-linux-aout i386/t-crtstuff"
tm_file=i386/linux-aout.h
- fixincludes=Makefile.in #On Linux, the headers are ok already.
gnu_ld=yes
float_format=i386
;;
@@ -1130,7 +1179,6 @@ changequote([,])dnl # with ELF format using the
tm_file=i386/linux.h
tmake_file="t-linux t-linux-gnulibc1 i386/t-crtstuff"
extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o"
- fixincludes=Makefile.in #On Linux, the headers are ok already.
gnu_ld=yes
float_format=i386
if test x$enable_threads = xyes; then
@@ -1145,7 +1193,6 @@ changequote([,])dnl # with ELF format using glibc 2
tm_file=i386/linux.h
tmake_file="t-linux i386/t-crtstuff"
extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o"
- fixincludes=Makefile.in #On Linux, the headers are ok already.
gnu_ld=yes
float_format=i386
if test x$enable_threads = xyes; then
@@ -1156,30 +1203,35 @@ changequote([,])dnl # with ELF format using glibc 2
;;
changequote(,)dnl
i[34567]86-*-gnu*)
+ float_format=i386
changequote([,])dnl
;;
changequote(,)dnl
i[34567]86-go32-msdos | i[34567]86-*-go32*)
changequote([,])dnl
- xm_file=i386/xm-go32.h
- tm_file=i386/go32.h
- tmake_file=i386/t-go32
+ echo "GO32/DJGPP V1.X is no longer supported. Use *-pc-msdosdjgpp for DJGPP V2.X instead."
+ exit 1
;;
changequote(,)dnl
i[34567]86-pc-msdosdjgpp*)
changequote([,])dnl
- xm_file=i386/xm-go32.h
- tm_file=i386/go32.h
- tmake_file=i386/t-go32
+ xm_file=i386/xm-djgpp.h
+ tm_file=i386/djgpp.h
+ tmake_file=i386/t-djgpp
+ xmake_file=i386/x-djgpp
gnu_ld=yes
gas=yes
+ exeext=.exe
+ case $host in *pc-msdosdjgpp*)
+ target_alias=djgpp
+ ;;
+ esac
;;
changequote(,)dnl
i[34567]86-moss-msdos* | i[34567]86-*-moss*)
changequote([,])dnl
tm_file=i386/moss.h
tmake_file=t-libc-ok
- fixincludes=Makefile.in
gnu_ld=yes
gas=yes
;;
@@ -1247,7 +1299,6 @@ changequote([,])dnl
xm_file="xm-siglist.h xm-alloca.h ${xm_file} i386/xm-sco5.h"
xm_defines="USG SVR3"
xmake_file=i386/x-sco5
- fixincludes=fixinc.sco
install_headers_dir=install-headers-cpio
tm_file=i386/sco5.h
if test x$gas = xyes
@@ -1257,7 +1308,7 @@ changequote([,])dnl
else
tmake_file=i386/t-sco5
fi
- extra_parts="crtbegin.o crtend.o crtbeginS.o crtendS.o"
+ extra_parts="crti.o crtbegin.o crtend.o crtbeginS.o crtendS.o"
;;
changequote(,)dnl
i[34567]86-*-sco3.2v4*) # 80386 running SCO 3.2v4 system
@@ -1265,7 +1316,6 @@ changequote([,])dnl
xm_file="${xm_file} i386/xm-sco.h"
xm_defines="USG SVR3 BROKEN_LDEXP SMALL_ARG_MAX NO_SYS_SIGLIST"
xmake_file=i386/x-sco4
- fixincludes=fixinc.sco
install_headers_dir=install-headers-cpio
if test x$stabs = xyes
then
@@ -1311,14 +1361,6 @@ changequote([,])dnl
tmake_file=i386/t-sol2
extra_parts="crt1.o crti.o crtn.o gcrt1.o gmon.o crtbegin.o crtend.o"
xmake_file=x-svr4
- case $machine in
-changequote(,)dnl
- *-*-solaris2.[0-4])
-changequote([,])dnl
- fixincludes=fixinc.svr4;;
- *)
- fixincludes=fixinc.wrap;;
- esac
if test x$enable_threads = xyes; then
thread_file='solaris'
fi
@@ -1336,7 +1378,6 @@ changequote([,])dnl
tmake_file=i386/t-crtpic
xmake_file=x-svr4
extra_parts="crtbegin.o crtend.o"
- fixincludes=fixinc.svr4
;;
changequote(,)dnl
i[34567]86-*-sysv4*) # Intel 80386's running system V.4
@@ -1361,7 +1402,6 @@ changequote([,])dnl
tmake_file="i386/t-crtpic i386/t-udk"
xmake_file=x-svr4
extra_parts="crtbegin.o crtend.o"
- fixincludes="fixinc.svr4"
;;
changequote(,)dnl
i[34567]86-*-osf1*) # Intel 80386's running OSF/1 1.3+
@@ -1369,7 +1409,6 @@ changequote([,])dnl
cpu_type=i386
xm_file="${xm_file} xm-svr4.h i386/xm-sysv4.h i386/xm-osf1elf.h"
xm_defines="USE_C_ALLOCA SMALL_ARG_MAX"
- fixincludes=Makefile.in #Don't do it on OSF/1
if test x$stabs = xyes
then
tm_file=i386/osf1elfgdb.h
@@ -1412,26 +1451,24 @@ changequote([,])dnl
changequote(,)dnl
i[34567]86-*-win32)
changequote([,])dnl
- xm_file="${xm_file} i386/xm-cygwin32.h"
- tmake_file=i386/t-cygwin32
+ xm_file="${xm_file} i386/xm-cygwin.h"
+ tmake_file=i386/t-cygwin
tm_file=i386/win32.h
- xmake_file=i386/x-cygwin32
+ xmake_file=i386/x-cygwin
extra_objs=winnt.o
- fixincludes=Makefile.in
if test x$enable_threads = xyes; then
thread_file='win32'
fi
exeext=.exe
;;
changequote(,)dnl
- i[34567]86-*-pe | i[34567]86-*-cygwin32)
+ i[34567]86-*-pe | i[34567]86-*-cygwin*)
changequote([,])dnl
- xm_file="${xm_file} i386/xm-cygwin32.h"
- tmake_file=i386/t-cygwin32
- tm_file=i386/cygwin32.h
- xmake_file=i386/x-cygwin32
+ xm_file="${xm_file} i386/xm-cygwin.h"
+ tmake_file=i386/t-cygwin
+ tm_file=i386/cygwin.h
+ xmake_file=i386/x-cygwin
extra_objs=winnt.o
- fixincludes=Makefile.in
if test x$enable_threads = xyes; then
thread_file='win32'
fi
@@ -1442,10 +1479,9 @@ changequote(,)dnl
changequote([,])dnl
tm_file=i386/mingw32.h
xm_file="${xm_file} i386/xm-mingw32.h"
- tmake_file="i386/t-cygwin32 i386/t-mingw32"
+ tmake_file="i386/t-cygwin i386/t-mingw32"
extra_objs=winnt.o
- xmake_file=i386/x-cygwin32
- fixincludes=Makefile.in
+ xmake_file=i386/x-cygwin
if test x$enable_threads = xyes; then
thread_file='win32'
fi
@@ -1459,6 +1495,38 @@ changequote([,])dnl
esac
;;
changequote(,)dnl
+ i[34567]86-*-uwin*)
+changequote([,])dnl
+ tm_file=i386/uwin.h
+ xm_file="${xm_file} i386/xm-uwin.h"
+ xm_defines="USG NO_STAB_H NO_SYS_SIGLIST"
+ tmake_file="i386/t-cygwin i386/t-uwin"
+ extra_objs=winnt.o
+ xmake_file=i386/x-cygwin
+ fixincludes=Makefile.in
+ if test x$enable_threads = xyes; then
+ thread_file='win32'
+ fi
+ exeext=.exe
+ ;;
+changequote(,)dnl
+ i[34567]86-*-interix*)
+changequote([,])dnl
+ tm_file=i386/interix.h
+ xm_file="${xm_file} xm-interix.h"
+ xm_defines="USG NO_SYS_SIGLIST"
+ tmake_file="i386/t-interix"
+ extra_objs=interix.o
+ xmake_file=x-interix
+ fixincludes=fixinc.interix
+ if [[ x$enable_threads = xyes ]]; then
+ thread_file='posix'
+ fi
+ if [[ x$stabs = xyes ]]; then
+ tm_file="${tm_file} dbxcoff.h"
+ fi
+ ;;
+changequote(,)dnl
i[34567]86-*-winnt3*)
changequote([,])dnl
tm_file=i386/win-nt.h
@@ -1468,7 +1536,6 @@ changequote([,])dnl
tmake_file=i386/t-winnt
extra_host_objs="winnt.o oldnames.o"
extra_gcc_objs="spawnv.o oldnames.o"
- fixincludes=fixinc.winnt
if test x$gnu_ld != xyes
then
extra_programs=ld.exe
@@ -1486,7 +1553,6 @@ changequote([,])dnl
tm_file=i386/dgux.h
tmake_file=i386/t-dgux
xmake_file=i386/x-dgux
- fixincludes=fixinc.dgux
install_headers_dir=install-headers-cpio
;;
i860-alliant-*) # Alliant FX/2800
@@ -1899,6 +1965,12 @@ changequote([,])dnl
extra_headers=math-68881.h
float_format=m68k
;;
+ m68020-*-elf* | m68k-*-elf*)
+ tm_file="m68k/m68020-elf.h libgloss.h"
+ xm_file=m68k/xm-m68kv.h
+ tmake_file=m68k/t-m68kelf
+ header_files=math-68881.h
+ ;;
m68k-*-lynxos*)
if test x$gas = xyes
then
@@ -1914,11 +1986,14 @@ changequote([,])dnl
;;
m68k*-*-netbsd*)
tm_file=m68k/netbsd.h
- # On NetBSD, the headers are already okay, except for math.h.
- fixincludes=fixinc.wrap
tmake_file=t-netbsd
float_format=m68k
;;
+ m68k*-*-openbsd*)
+ float_format=m68k
+ # we need collect2 until our bug is fixed...
+ use_collect2=yes
+ ;;
m68k-*-sysv3*) # Motorola m68k's running system V.3
xm_file="xm-alloca.h ${xm_file}"
xm_defines=USG
@@ -1941,7 +2016,6 @@ changequote([,])dnl
xmake_file=x-linux
tm_file=m68k/linux-aout.h
tmake_file="t-linux-aout m68k/t-linux-aout"
- fixincludes=Makefile.in # The headers are ok already.
extra_headers=math-68881.h
float_format=m68k
gnu_ld=yes
@@ -1953,7 +2027,6 @@ changequote([,])dnl
tm_file=m68k/linux.h
tmake_file="t-linux t-linux-gnulibc1 m68k/t-linux"
extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o"
- fixincludes=Makefile.in # The headers are ok already.
extra_headers=math-68881.h
float_format=m68k
gnu_ld=yes
@@ -1965,7 +2038,6 @@ changequote([,])dnl
tm_file=m68k/linux.h
tmake_file="t-linux m68k/t-linux"
extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o"
- fixincludes=Makefile.in # The headers are ok already.
extra_headers=math-68881.h
float_format=m68k
gnu_ld=yes
@@ -2003,7 +2075,6 @@ changequote([,])dnl
then
tmake_file=m88k/t-dgux-gas
fi
- fixincludes=fixinc.dgux
;;
m88k-dolphin-sysv3*)
tm_file=m88k/dolph.h
@@ -2042,6 +2113,9 @@ changequote([,])dnl
tmake_file=m88k/t-luna
fi
;;
+ m88k-*-openbsd*)
+ tmake_file="${tmake_file} m88k/t-luna-gas"
+ ;;
m88k-*-sysv3*)
tm_file=m88k/sysv3.h
extra_parts="crtbegin.o crtend.o"
@@ -2061,7 +2135,6 @@ changequote([,])dnl
mips-sgi-irix6*) # SGI System V.4., IRIX 6
tm_file=mips/iris6.h
xm_file=mips/xm-iris6.h
- fixincludes=fixinc.irix
xmake_file=mips/x-iris6
tmake_file=mips/t-iris6
# if test x$enable_threads = xyes; then
@@ -2074,13 +2147,12 @@ changequote([,])dnl
gas=yes
gnu_ld=yes
extra_parts="crtbegin.o crtend.o"
-# thread_file='vxworks'
+ thread_file='vxworks'
;;
mips-sgi-irix5cross64) # Irix5 host, Irix 6 target, cross64
tm_file="mips/iris6.h mips/cross64.h"
xm_defines=USG
xm_file="mips/xm-iris5.h"
- fixincludes=Makefile.in
xmake_file=mips/x-iris
tmake_file=mips/t-cross64
# See comment in mips/iris[56].h files.
@@ -2122,7 +2194,6 @@ changequote([,])dnl
fi
xm_defines=USG
xm_file="mips/xm-iris5.h"
- fixincludes=fixinc.irix
xmake_file=mips/x-iris
# mips-tfile doesn't work yet
tmake_file=mips/t-mips-gas
@@ -2222,7 +2293,6 @@ changequote([,])dnl
;;
mips-dec-bsd*) # Decstation running 4.4 BSD
tm_file=mips/dec-bsd.h
- fixincludes=
if test x$gas = xyes
then
tmake_file=mips/t-mips-gas
@@ -2238,9 +2308,30 @@ changequote([,])dnl
mipsel-*-netbsd* | mips-dec-netbsd*) # Decstation running NetBSD
tm_file=mips/netbsd.h
# On NetBSD, the headers are already okay, except for math.h.
- fixincludes=fixinc.wrap
tmake_file=t-netbsd
;;
+ mips*-*-linux*) # Linux MIPS, either endian.
+ xmake_file=x-linux
+ xm_file="xm-siglist.h ${xm_file}"
+ case $machine in
+ mipsel-*) tm_file="mips/elfl.h mips/linux.h" ;;
+ *) tm_file="mips/elf.h mips/linux.h" ;;
+ esac
+ extra_parts="crtbegin.o crtend.o"
+ gnu_ld=yes
+ gas=yes
+ fixincludes=Makefile.in
+ ;;
+ mips*el-*-openbsd*) # mips little endian
+ target_cpu_default="MASK_GAS|MASK_ABICALLS"
+ tm_file=mips/openbsd.h
+ xmake_file=none
+ ;;
+ mips*-*-openbsd*) # mips big endian
+ target_cpu_default="MASK_GAS|MASK_ABICALLS"
+ tm_file=mips/openbsd-be.h
+ xmake_file=none
+ ;;
mips-sony-bsd* | mips-sony-newsos*) # Sony NEWS 3600 or risc/news.
tm_file="mips/news4.h ${tm_file}"
if test x$stabs = xyes; then
@@ -2583,7 +2674,6 @@ changequote([,])dnl
tm_file=ns32k/netbsd.h
xm_file="ns32k/xm-netbsd.h ${xm_file}"
# On NetBSD, the headers are already okay, except for math.h.
- fixincludes=fixinc.wrap
tmake_file=t-netbsd
;;
pdp11-*-bsd)
@@ -2591,6 +2681,9 @@ changequote([,])dnl
;;
pdp11-*-*)
;;
+ ns32k-*-openbsd*)
+ # Nothing special
+ ;;
pyramid-*-*)
cpu_type=pyr
xmake_file=pyr/x-pyr
@@ -2603,6 +2696,13 @@ changequote([,])dnl
xmake_file=romp/x-mach
use_collect2=yes
;;
+ romp-*-openbsd*)
+ # Nothing special
+ ;;
+ powerpc-*-openbsd*)
+ tmake_file="${tmake_file} rs6000/t-rs6000 rs6000/t-openbsd"
+ xmake_file=none
+ ;;
powerpc-*-beos*)
cpu_type=rs6000
tm_file=rs6000/beos.h
@@ -2626,13 +2726,11 @@ changequote([,])dnl
powerpc-*-eabiaix*)
tm_file=rs6000/eabiaix.h
tmake_file="rs6000/t-ppcgas rs6000/t-ppccomm"
- fixincludes=Makefile.in
extra_headers=ppc-asm.h
;;
powerpc-*-eabisim*)
tm_file=rs6000/eabisim.h
tmake_file="rs6000/t-ppcgas rs6000/t-ppccomm"
- fixincludes=Makefile.in
extra_headers=ppc-asm.h
;;
powerpc-*-eabi*)
@@ -2643,7 +2741,6 @@ changequote([,])dnl
else
tmake_file="rs6000/t-ppc rs6000/t-ppccomm"
fi
- fixincludes=Makefile.in
extra_headers=ppc-asm.h
;;
powerpc-*-rtems*)
@@ -2654,7 +2751,6 @@ changequote([,])dnl
else
tmake_file="rs6000/t-ppc t-rtems rs6000/t-ppccomm"
fi
- fixincludes=Makefile.in
extra_headers=ppc-asm.h
;;
powerpc-*-linux-gnulibc1)
@@ -2668,7 +2764,6 @@ changequote([,])dnl
tmake_file="rs6000/t-ppc t-linux t-linux-gnulibc1 rs6000/t-ppccomm"
fi
xmake_file=x-linux
- fixincludes=Makefile.in
extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o"
extra_headers=ppc-asm.h
if test x$enable_threads = xyes; then
@@ -2687,7 +2782,6 @@ changequote([,])dnl
tmake_file="rs6000/t-ppc t-linux rs6000/t-ppccomm"
fi
xmake_file=x-linux
- fixincludes=Makefile.in
extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o"
extra_headers=ppc-asm.h
if test x$enable_threads = xyes; then
@@ -2719,7 +2813,6 @@ changequote([,])dnl
powerpcle-*-eabisim*)
tm_file=rs6000/eabilesim.h
tmake_file="rs6000/t-ppcgas rs6000/t-ppccomm"
- fixincludes=Makefile.in
extra_headers=ppc-asm.h
;;
powerpcle-*-eabi*)
@@ -2730,26 +2823,23 @@ changequote([,])dnl
else
tmake_file="rs6000/t-ppc rs6000/t-ppccomm"
fi
- fixincludes=Makefile.in
extra_headers=ppc-asm.h
;;
powerpcle-*-winnt* )
tm_file=rs6000/win-nt.h
tmake_file=rs6000/t-winnt
# extra_objs=pe.o
- fixincludes=Makefile.in
if test x$enable_threads = xyes; then
thread_file='win32'
fi
extra_headers=ppc-asm.h
;;
- powerpcle-*-pe | powerpcle-*-cygwin32)
- tm_file=rs6000/cygwin32.h
- xm_file="rs6000/xm-cygwin32.h ${xm_file}"
+ powerpcle-*-pe | powerpcle-*-cygwin*)
+ tm_file=rs6000/cygwin.h
+ xm_file="rs6000/xm-cygwin.h ${xm_file}"
tmake_file=rs6000/t-winnt
- xmake_file=rs6000/x-cygwin32
+ xmake_file=rs6000/x-cygwin
# extra_objs=pe.o
- fixincludes=Makefile.in
if test x$enable_threads = xyes; then
thread_file='win32'
fi
@@ -2767,14 +2857,6 @@ changequote([,])dnl
tmake_file="rs6000/t-ppc rs6000/t-ppccomm"
fi
xmake_file=rs6000/x-sysv4
- case $machine in
-changequote(,)dnl
- *-*-solaris2.[0-4])
-changequote([,])dnl
- fixincludes=fixinc.svr4;;
- *)
- fixincludes=fixinc.wrap;;
- esac
extra_headers=ppc-asm.h
;;
changequote(,)dnl
@@ -2782,6 +2864,7 @@ changequote(,)dnl
changequote([,])dnl
tm_file=rs6000/aix31.h
xmake_file=rs6000/x-aix31
+ float_format=none
use_collect2=yes
;;
changequote(,)dnl
@@ -2794,12 +2877,18 @@ changequote([,])dnl
else
tmake_file=rs6000/t-newas
fi
+ float_format=none
use_collect2=yes
;;
changequote(,)dnl
rs6000-ibm-aix4.[12]* | powerpc-ibm-aix4.[12]*)
changequote([,])dnl
- tm_file=rs6000/aix41.h
+ if test "$gnu_ld" = yes
+ then
+ tm_file=rs6000/aix41-gld.h
+ else
+ tm_file=rs6000/aix41.h
+ fi
if test x$host != x$target
then
tmake_file=rs6000/t-xnewas
@@ -2807,6 +2896,7 @@ changequote([,])dnl
tmake_file=rs6000/t-newas
fi
xmake_file=rs6000/x-aix41
+ float_format=none
use_collect2=yes
;;
changequote(,)dnl
@@ -2820,6 +2910,7 @@ changequote([,])dnl
tmake_file=rs6000/t-aix43
fi
xmake_file=rs6000/x-aix43
+ float_format=none
use_collect2=yes
;;
changequote(,)dnl
@@ -2833,12 +2924,15 @@ changequote([,])dnl
tmake_file=rs6000/t-aix43
fi
xmake_file=rs6000/x-aix43
+ float_format=none
use_collect2=yes
;;
rs6000-ibm-aix*)
+ float_format=none
use_collect2=yes
;;
rs6000-bull-bosx)
+ float_format=none
use_collect2=yes
;;
rs6000-*-mach*)
@@ -2888,10 +2982,12 @@ changequote([,])dnl
;;
sparc-*-netbsd*)
tm_file=sparc/netbsd.h
- # On NetBSD, the headers are already okay, except for math.h.
- fixincludes=fixinc.wrap
tmake_file=t-netbsd
;;
+ sparc-*-openbsd*)
+ # we need collect2 until our bug is fixed...
+ use_collect2=yes
+ ;;
sparc-*-bsd*)
tm_file=sparc/bsd.h
;;
@@ -2906,7 +3002,6 @@ changequote([,])dnl
xm_file="${xm_file} sparc/xm-linux.h"
tm_file=sparc/linux-aout.h
xmake_file=x-linux
- fixincludes=Makefile.in #On Linux, the headers are ok already.
gnu_ld=yes
;;
sparc-*-linux-gnulibc1*) # Sparc's running GNU/Linux, libc5
@@ -2915,7 +3010,6 @@ changequote([,])dnl
tm_file=sparc/linux.h
tmake_file="t-linux t-linux-gnulibc1"
extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o"
- fixincludes=Makefile.in #On Linux, the headers are ok already.
gnu_ld=yes
;;
sparc-*-linux-gnu*) # Sparc's running GNU/Linux, libc6
@@ -2924,7 +3018,6 @@ changequote([,])dnl
tm_file=sparc/linux.h
tmake_file="t-linux"
extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o"
- fixincludes=Makefile.in #On Linux, the headers are ok already.
gnu_ld=yes
if test x$enable_threads = xyes; then
thread_file='posix'
@@ -2952,8 +3045,7 @@ changequote([,])dnl
tmake_file="sparc/t-sol2 sparc/t-sol2-64"
xmake_file=sparc/x-sysv4
extra_parts="crt1.o crti.o crtn.o gcrt1.o crtbegin.o crtend.o"
- fixincludes=fixinc.wrap
- float_format=i128
+ float_format=none
if test x${enable_threads} = x ; then
enable_threads=$have_pthread_h
if test x${enable_threads} = x ; then
@@ -2968,6 +3060,15 @@ changequote([,])dnl
fi
fi
;;
+ sparc-hal-solaris2*)
+ xm_file=sparc/xm-sol2.h
+ tm_file="sparc/sol2.h sparc/hal.h"
+ tmake_file="sparc/t-halos sparc/t-sol2"
+ xmake_file=sparc/x-sysv4
+ extra_parts="crt1.o crti.o crtn.o gmon.o crtbegin.o crtend.o"
+ fixincludes=fixinc.svr4
+ broken_install=yes
+ ;;
sparc-*-solaris2*)
if test x$gnu_ld = xyes
then
@@ -2984,11 +3085,12 @@ changequote([,])dnl
changequote(,)dnl
*-*-solaris2.[0-4])
changequote([,])dnl
- fixincludes=fixinc.svr4;;
+ float_format=i128
+ ;;
*)
- fixincludes=fixinc.wrap;;
+ float_format=none
+ ;;
esac
- float_format=i128
if test x${enable_threads} = x; then
enable_threads=$have_pthread_h
if test x${enable_threads} = x; then
@@ -3061,7 +3163,6 @@ changequote([,])dnl
xm_file="sparc/xm-sp64.h sparc/xm-linux.h"
tm_file=sparc/linux64.h
xmake_file=x-linux
- fixincludes=Makefile.in # The headers are ok already.
extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o"
gnu_ld=yes
;;
@@ -3077,7 +3178,6 @@ changequote([,])dnl
xm_file=arm/xm-thumb.h
md_file=arm/thumb.md
tmake_file=arm/t-thumb
- fixincludes=Makefile.in # There is nothing to fix
;;
# This hasn't been upgraded to GCC 2.
# tron-*-*)
@@ -3106,11 +3206,12 @@ changequote([,])dnl
;;
vax-*-netbsd*)
tm_file="${tm_file} netbsd.h vax/netbsd.h"
- # On NetBSD, the headers are already okay, except for math.h.
- fixincludes=fixinc.wrap
tmake_file=t-netbsd
float_format=vax
;;
+ vax-*-openbsd*)
+ tmake_file="${tm_file} vax/t-openbsd"
+ ;;
vax-*-ultrix*) # vaxen running ultrix
tm_file="${tm_file} vax/ultrix.h"
use_collect2=yes
@@ -3149,13 +3250,10 @@ changequote([,])dnl
# GNU tools are the only tools.
gnu_ld=yes
gas=yes
- # On GNU, the headers are already okay.
- fixincludes=Makefile.in
xmake_file=x-linux # These details are the same as Linux.
tmake_file=t-gnu # These are not.
;;
*-*-sysv4*)
- fixincludes=fixinc.svr4
xmake_try_sysv=x-sysv
install_headers_dir=install-headers-cpio
;;
@@ -3181,7 +3279,7 @@ changequote([,])dnl
alpha*-*-*)
case $machine in
alphaev6*)
- target_cpu_default2="MASK_CPU_EV6|MASK_BXW|MASK_CIX|MASK_MAX"
+ target_cpu_default2="MASK_CPU_EV6|MASK_BWX|MASK_CIX|MASK_MAX"
;;
alphapca56*)
target_cpu_default2="MASK_CPU_EV5|MASK_BWX|MASK_MAX"
@@ -3216,7 +3314,7 @@ changequote([,])dnl
xarm[23678] | xarm250 | xarm[67][01]0 \
| xarm7m | xarm7dm | xarm7dmi | xarm7tdmi \
| xarm7100 | xarm7500 | xarm7500fe | xarm810 \
- | xstrongarm | xstrongarm110)
+ | xstrongarm | xstrongarm110 | xstrongarm1100)
target_cpu_default2="TARGET_CPU_$with_cpu"
;;
@@ -3260,6 +3358,7 @@ changequote([,])dnl
xcommon | xpower | xpower2 | xpowerpc | xrios \
| xrios1 | xrios2 | xrsc | xrsc1 \
| x601 | x602 | x603 | x603e | x604 | x604e | x620 \
+ | xec603e | x740 | x750 | x401 \
| x403 | x505 | x801 | x821 | x823 | x860)
target_cpu_default2="\"$with_cpu\""
;;
@@ -3283,7 +3382,7 @@ changequote([,])dnl
.)
target_cpu_default2=TARGET_CPU_"`echo $machine | sed 's/-.*$//'`"
;;
- .supersparc | .ultrasparc | .v7 | .v8 | .v9)
+ .supersparc | .hypersparc | .ultrasparc | .v7 | .v8 | .v9)
target_cpu_default2="TARGET_CPU_$with_cpu"
;;
*)
@@ -3371,18 +3470,33 @@ if test x"$tmake_file" = x
then tmake_file=$cpu_type/t-$cpu_type
fi
+if test x"$dwarf2" = xyes
+then tm_file="tm-dwarf2.h $tm_file"
+fi
+
if test x$float_format = x
then float_format=i64
fi
+if test $float_format = none
+then float_h_file=Makefile.in
+else float_h_file=float-$float_format.h
+fi
+
if test x$enable_haifa = x
then
case $target in
- alpha*-* | hppa1.?-* | powerpc*-* | rs6000-* | *sparc*-* | m32r*-*)
+ alpha*-* | hppa*-* | powerpc*-* | rs6000-* | *sparc*-* | m32r*-*)
enable_haifa=yes;;
esac
fi
+# Handle cpp installation.
+if [[ x$enable_cpp != x ]]
+then
+ tmake_file="$tmake_file t-install-cpp"
+fi
+
# Say what files are being used for the output code and MD file.
echo "Using \`$srcdir/config/$out_file' to output insns."
echo "Using \`$srcdir/config/$md_file' as machine description file."
@@ -3442,14 +3556,14 @@ fi
# auto-host.h is the file containing items generated by autoconf and is
# the first file included by config.h.
null_defines=
-host_xm_file="auto-host.h ${host_xm_file}"
+host_xm_file="auto-host.h gansidecl.h ${host_xm_file}"
# If host=build, it is correct to have hconfig 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_xm_file="auto-host.h ${build_xm_file}"
+ build_xm_file="auto-host.h gansidecl.h ${build_xm_file}"
else
# We create a subdir, then run autoconf in the subdir.
# To prevent recursion we set host and build for the new
@@ -3471,9 +3585,12 @@ else
mv auto-host.h ../auto-build.h
cd ..
rm -rf $tempdir
- build_xm_file="auto-build.h ${build_xm_file}"
+ build_xm_file="auto-build.h gansidecl.h ${build_xm_file}"
fi
+xm_file="gansidecl.h ${xm_file}"
+tm_file="gansidecl.h ${tm_file}"
+
vars="host_xm_file tm_file xm_file build_xm_file"
links="config.h tm.h tconfig.h hconfig.h"
defines="host_xm_defines null_defines xm_defines build_xm_defines"
@@ -3498,7 +3615,21 @@ do
fi
for file in `eval echo '$'$var`; do
+ case $file in
+ auto-config.h)
+ ;;
+ *)
+ echo '#ifdef IN_GCC' >>$link
+ ;;
+ esac
echo "#include \"$file\"" >>$link
+ case $file in
+ auto-config.h)
+ ;;
+ *)
+ echo '#endif' >>$link
+ ;;
+ esac
done
for def in `eval echo '$'$define`; do
@@ -3523,6 +3654,24 @@ changequote(,)dnl
gcc_version=`sed -e 's/.*\"\([^ \"]*\)[ \"].*/\1/' < ${gcc_version_trigger}`
changequote([,])dnl
+# Internationalization
+PACKAGE=gcc
+VERSION="$gcc_version"
+AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE")
+AC_DEFINE_UNQUOTED(VERSION, "$VERSION")
+AC_SUBST(PACKAGE)
+AC_SUBST(VERSION)
+
+ALL_LINGUAS="en_UK"
+
+# NLS support is still experimental, so disable it by default for now.
+AC_ARG_ENABLE(nls,
+ [ --enable-nls use Native Language Support (disabled by default)],
+ , enable_nls=no)
+
+AM_GNU_GETTEXT
+XGETTEXT="AWK='$AWK' \$(SHELL) \$(top_srcdir)/exgettext $XGETTEXT"
+
# Get an absolute path to the GCC top-level source directory
holddir=`pwd`
cd $srcdir
@@ -3580,28 +3729,28 @@ out_object_file=`basename $out_file .c`.o
tm_file_list=
for f in $tm_file; do
- tm_file_list="${tm_file_list} \$(srcdir)/config/$f"
+ if test $f != "gansidecl.h" ; then
+ tm_file_list="${tm_file_list} \$(srcdir)/config/$f"
+ else
+ tm_file_list="${tm_file_list} $f"
+ fi
done
host_xm_file_list=
for f in $host_xm_file; do
- if test $f != "auto-host.h"; then
+ if test $f != "auto-host.h" -a $f != "gansidecl.h" ; then
host_xm_file_list="${host_xm_file_list} \$(srcdir)/config/$f"
else
- host_xm_file_list="${host_xm_file_list} auto-host.h"
+ host_xm_file_list="${host_xm_file_list} $f"
fi
done
build_xm_file_list=
for f in $build_xm_file; do
- if test $f != "auto-build.h"; then
- if test $f != "auto-host.h"; then
- build_xm_file_list="${build_xm_file_list} \$(srcdir)/config/$f"
- else
- build_xm_file_list="${build_xm_file_list} auto-host.h"
- fi
+ if test $f != "auto-build.h" -a $f != "auto-host.h" -a $f != "gansidecl.h" ; then
+ build_xm_file_list="${build_xm_file_list} \$(srcdir)/config/$f"
else
- build_xm_file_list="${build_xm_file_list} auto-build.h"
+ build_xm_file_list="${build_xm_file_list} $f"
fi
done
@@ -3692,12 +3841,14 @@ AC_MSG_CHECKING(assembler alignment features)
gcc_cv_as=
gcc_cv_as_alignment_features=
gcc_cv_as_gas_srcdir=`echo $srcdir | sed -e 's,/gcc$,,'`/gas
-if test -x "$AS"; then
- gcc_cv_as=$AS
+if test -x "$DEFAULT_ASSEMBLER"; then
+ gcc_cv_as="$DEFAULT_ASSEMBLER"
+elif test -x "$AS"; then
+ gcc_cv_as="$AS"
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; then
+elif test -f $gcc_cv_as_gas_srcdir/configure.in -a -f ../gas/Makefile; then
# Single tree build which includes gas.
for f in $gcc_cv_as_gas_srcdir/configure $gcc_cv_as_gas_srcdir/configure.in $gcc_cv_as_gas_srcdir/Makefile.in
do
@@ -3787,6 +3938,16 @@ fi
AC_MSG_RESULT($gcc_cv_as_subsections)
# Figure out what language subdirectories are present.
+# Look if the user specified --enable-languages="..."; if not, use
+# the environment variable $LANGUAGES if defined. $LANGUAGES might
+# go away some day.
+if test x"${enable_languages+set}" != xset; then
+ if test x"${LANGUAGES+set}" = xset; then
+ enable_languages="`echo ${LANGUAGES} | tr ' ' ','`"
+ else
+ enable_languages=all
+ fi
+fi
subdirs=
for lang in ${srcdir}/*/config-lang.in ..
do
@@ -3795,13 +3956,39 @@ do
# The odd quoting in the next line works around
# an apparent bug in bash 1.12 on linux.
changequote(,)dnl
- ${srcdir}/ada/config-lang.in)
- if test x$gnat = xyes ; then
- subdirs="$subdirs `echo $lang | sed -e 's,^.*/\([^/]*\)/config-lang.in$,\1,'`"
- fi
- ;;
${srcdir}/[*]/config-lang.in) ;;
- *) subdirs="$subdirs `echo $lang | sed -e 's,^.*/\([^/]*\)/config-lang.in$,\1,'`" ;;
+ *)
+ 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
+ if test x"${enable_languages}" = xall; then
+ add_this_lang=yes
+ else
+ case "${enable_languages}" in
+ ${lang_alias} | "${lang_alias},"* | *",${lang_alias},"* | *",${lang_alias}" )
+ add_this_lang=yes
+ ;;
+ * )
+ add_this_lang=no
+ ;;
+ esac
+ fi
+ if test x"${add_this_lang}" = xyes; then
+ case $lang in
+ ${srcdir}/ada/config-lang.in)
+ if test x$gnat = xyes ; then
+ subdirs="$subdirs `echo $lang | sed -e 's,^.*/\([^/]*\)/config-lang.in$,\1,'`"
+ fi
+ ;;
+ *)
+ subdirs="$subdirs `echo $lang | sed -e 's,^.*/\([^/]*\)/config-lang.in$,\1,'`"
+ ;;
+ esac
+ fi
+ ;;
changequote([,])dnl
esac
done
@@ -3846,7 +4033,7 @@ all_boot_languages=
all_compilers=
all_stagestuff=
all_diff_excludes=
-all_outputs=Makefile
+all_outputs='Makefile intl/Makefile po/Makefile.in fixinc/Makefile'
# List of language makefile fragments.
all_lang_makefiles=
all_headers=
@@ -3914,10 +4101,10 @@ target_list="all.build all.cross start.encap rest.encap \
for t in $target_list
do
x=
- for l in .. $all_languages
+ for lang in .. $all_languages
do
- if test $l != ".."; then
- x="$x $l.$t"
+ if test $lang != ".."; then
+ x="$x $lang.$t"
fi
done
echo "lang.$t: $x" >> Make-hooks
@@ -3975,7 +4162,7 @@ AC_SUBST(sched_prefix)
AC_SUBST(sched_cflags)
if test x$enable_haifa != x; then
# Explicitly remove files that need to be recompiled for the Haifa scheduler.
- for x in genattrtab.o toplev.o loop.o unroll.o *sched.o; do
+ for x in genattrtab.o toplev.o *sched.o; do
if test -f $x; then
echo "Removing $x"
rm -f $x
@@ -3983,12 +4170,44 @@ if test x$enable_haifa != x; then
done
fi
-# Warn if using init_priority.
-AC_MSG_CHECKING(whether to enable init_priority by default)
-if test x$enable_init_priority != xyes; then
- enable_init_priority=no
+# 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_alias)'
+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 occurance 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_alias)"
+changequote([, ])dnl
fi
-AC_MSG_RESULT($enable_init_priority)
+AC_SUBST(gcc_tooldir)
+AC_SUBST(dollar)
# Nothing to do for FLOAT_H, float_format already handled.
objdir=`pwd`
@@ -3999,53 +4218,56 @@ ${CONFIG_SHELL-/bin/sh} $srcdir/configure.frag $srcdir "$subdirs" "$dep_host_xma
# Substitute configuration variables
AC_SUBST(subdirs)
-AC_SUBST(all_languages)
AC_SUBST(all_boot_languages)
AC_SUBST(all_compilers)
-AC_SUBST(all_lang_makefiles)
-AC_SUBST(all_stagestuff)
AC_SUBST(all_diff_excludes)
-AC_SUBST(all_lib2funcs)
AC_SUBST(all_headers)
+AC_SUBST(all_lang_makefiles)
+AC_SUBST(all_languages)
+AC_SUBST(all_lib2funcs)
+AC_SUBST(all_stagestuff)
+AC_SUBST(build_exeext)
+AC_SUBST(build_install_headers_dir)
+AC_SUBST(build_xm_file_list)
+AC_SUBST(cc_set_by_configure)
+AC_SUBST(cpp_install_dir)
AC_SUBST(cpp_main)
-AC_SUBST(extra_passes)
-AC_SUBST(extra_programs)
-AC_SUBST(extra_parts)
+AC_SUBST(dep_host_xmake_file)
+AC_SUBST(dep_tmake_file)
+AC_SUBST(extra_c_flags)
AC_SUBST(extra_c_objs)
-AC_SUBST(extra_cxx_objs)
AC_SUBST(extra_cpp_objs)
-AC_SUBST(extra_c_flags)
+AC_SUBST(extra_cxx_objs)
+AC_SUBST(extra_headers_list)
AC_SUBST(extra_objs)
+AC_SUBST(extra_parts)
+AC_SUBST(extra_passes)
+AC_SUBST(extra_programs)
+AC_SUBST(fixinc_defs)
+AC_SUBST(float_h_file)
+AC_SUBST(gcc_gxx_include_dir)
+AC_SUBST(gcc_version)
+AC_SUBST(gcc_version_trigger)
+AC_SUBST(host_exeext)
AC_SUBST(host_extra_gcc_objs)
-AC_SUBST(extra_headers_list)
-AC_SUBST(dep_host_xmake_file)
-AC_SUBST(dep_tmake_file)
-AC_SUBST(out_file)
-AC_SUBST(out_object_file)
-AC_SUBST(md_file)
-AC_SUBST(tm_file_list)
-AC_SUBST(build_xm_file_list)
AC_SUBST(host_xm_file_list)
-AC_SUBST(lang_specs_files)
+AC_SUBST(install)
+AC_SUBST(JAVAGC)
AC_SUBST(lang_options_files)
+AC_SUBST(lang_specs_files)
AC_SUBST(lang_tree_files)
-AC_SUBST(thread_file)
-AC_SUBST(objc_boehm_gc)
-AC_SUBST(gcc_version)
-AC_SUBST(gcc_version_trigger)
AC_SUBST(local_prefix)
-AC_SUBST(gxx_include_dir)
-AC_SUBST(fixincludes)
-AC_SUBST(build_install_headers_dir)
-AC_SUBST(build_exeext)
-AC_SUBST(host_exeext)
-AC_SUBST(float_format)
-AC_SUBST(will_use_collect2)
AC_SUBST(maybe_use_collect2)
-AC_SUBST(cc_set_by_configure)
+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(install)
AC_SUBST(symbolic_link)
+AC_SUBST(thread_file)
+AC_SUBST(tm_file_list)
+AC_SUBST(will_use_collect2)
+
AC_SUBST_FILE(target_overrides)
AC_SUBST_FILE(host_overrides)
@@ -4118,6 +4340,11 @@ if test "$symbolic_link" = "ln -s"; then
fi
done
else true ; fi
+# Avoid having to add intl to our include paths.
+if test -f intl/libintl.h; then
+ echo creating libintl.h
+ echo '#include "intl/libintl.h"' >libintl.h
+fi
],
[
host='${host}'
@@ -4150,4 +4377,5 @@ host_overrides='${host_overrides}'
cross_defines='${cross_defines}'
cross_overrides='${cross_overrides}'
build_overrides='${build_overrides}'
+cpp_install_dir='${cpp_install_dir}'
])
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index c7b1ed806dd..0138c8461b4 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,2571 @@
+1999-03-27 Jason Merrill <jason@yorick.cygnus.com>
+
+ * call.c (build_field_call): Unify 'this' and non-'this' cases.
+
+ * typeck.c (build_indirect_ref): Check for 'this' sooner.
+
+Fri Mar 26 10:20:34 1999 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * call.c (op_error): Const-ify a char*.
+ (add_candidate, source_type, add_warning): Add static prototype.
+ (print_z_candidates): Const-ify a char*.
+
+ * class.c (resolve_address_of_overloaded_function,
+ fixed_type_or_null, build_vtable_entry_ref): Add static prototype.
+ (get_vtable_name, finish_struct_1): Const-ify a char*.
+
+ * cvt.c (convert_to_reference): Likewise.
+
+ * decl.c (redeclaration_error_message, record_builtin_type,
+ record_unknown_type, member_function_or_else, bad_specifiers):
+ Likewise.
+ (find_binding, select_decl, unqualified_namespace_lookup,
+ lookup_flags, qualify_lookup, record_builtin_java_type, tag_name):
+ Add static prototype.
+ (warn_extern_redeclared_static, duplicate_decls, pushdecl,
+ implicitly_declare, record_builtin_java_type, define_function,
+ grok_op_properties, tag_name): Const-ify a char*.
+
+ * cp-tree.h (FORMAT_VBASE_NAME): Allow parameter `BUF' to be const.
+ (define_function, finish_builtin_type): Const-ify a char*.
+ (cp_error, cp_error_at, cp_warning, cp_warning_at, cp_pedwarn,
+ cp_pedwarn_at, cp_compiler_error, cp_sprintf): Add prototype args.
+ (file_name_nondirectory): Const-ify a char*.
+ (init_filename_times): Don't prototype.
+ (compiler_error): Prototype.
+ (yyerror, init_repo): Const-ify a char*.
+ (build_srcloc): Don't prototype.
+ (build_x_indirect_ref, build_indirect_ref, build_component_addr):
+ Const-ify a char*.
+ (warn_for_assignment): Don't prototype.
+ (convert_for_initialization, readonly_error, check_for_new_type,
+ GNU_xref_begin, GNU_xref_file, GNU_xref_ref, GNU_xref_call):
+ Const-ify a char*.
+
+ * decl2.c (acceptable_java_type, output_vtable_inherit,
+ setup_initp, start_objects, finish_objects, do_dtors, do_ctors,
+ merge_functions, decl_namespace, validate_nonmember_using_decl,
+ do_nonmember_using_decl): Add static prototype.
+ (lang_f_options): Const-ify a char*.
+ (finish_builtin_type): Likewise.
+ (add_function, arg_assoc_namespace, arg_assoc_class): Add static
+ prototype.
+
+ * errfn.c: Include cp-tree.h.
+ (cp_thing): Add static prototype.
+ (compiler_error): Don't protoptype.
+ (cp_compiler_error): Cast `compiler_error' to `errorfn' before
+ passing it to `cp_thing'.
+
+ * error.c (interesting_scope_p): Add static prototype.
+
+ * except.c (build_eh_type_type, build_eh_type_type_ref): Const-ify
+ a char*.
+
+ * init.c (compiler_error): Don't prototype.
+ (member_init_ok_or_else): Const-ify a char*.
+ (build_java_class_ref): Add static prototype.
+
+ * lex.c (compiler_error): Don't prototype.
+ (get_time_identifier, interface_strcmp, extend_token_buffer,
+ handle_cp_pragma): Const-ify a char*.
+ (is_global, init_filename_times): Add static prototype.
+ (file_name_nondirectory, cplus_tree_code_name): Const-ify a char*.
+ (compiler_error): Change from fixed args to variable args.
+ (yyerror): Const-ify a char*.
+
+ * parse.y (cond_stmt_keyword): Const-ify a char*.
+ (parse_decl): Add static prototype.
+
+ * pt.c (template_args_equal, print_template_context): Likewise.
+ (print_candidates, check_default_tmpl_args): Const-ify a char*.
+ (instantiate_class_template): Likewise.
+
+ * repo.c (get_base_filename, open_repo_file, init_repo): Likewise.
+
+ * rtti.c (call_void_fn, expand_generic_desc, expand_si_desc,
+ expand_class_desc, expand_ptr_desc, expand_attr_desc): Likewise.
+
+ * search.c (lookup_field_info, lookup_member): Likewise.
+ (lookup_member): Cast the first argument of `bzero' to a PTR.
+
+ * sig.c (compiler_error): Don't prototype.
+ (build_signature_pointer_or_reference_nam): Const-ify a char*.
+ (get_sigtable_name, build_member_function_pointer): Likewise.
+
+ * tree.c (compiler_error): Don't prototype.
+ (no_linkage_helper, build_srcloc): Add static prototype.
+ (build_vbase_pointer_fields): Const-ify a char*.
+ (__eprintf): Don't unnecessarily handle `const' when !__STDC__.
+
+ * typeck.c (compiler_error): Don't prototype.
+ (convert_for_assignment): Const-ify a char*.
+ (comp_cv_target_types): Add static prototype.
+ (build_x_indirect_ref, build_indirect_ref, convert_arguments,
+ build_component_addr, build_unary_op, convert_for_initialization):
+ Const-ify a char*.
+
+ * typeck2.c (ack): Add static prototype and change from fixed args
+ to variable args.
+ (readonly_error, check_for_new_type): Const-ify a char*.
+
+ * xref.c (_XREF_FILE, find_file, filename, fctname, declname,
+ fixname, open_xref_file, classname, GNU_xref_begin): Likewise.
+ (GNU_xref_file): Likewise. Also use `xmalloc' instead of `malloc'.
+ (GNU_xref_end_scope, GNU_xref_ref, GNU_xref_decl, GNU_xref_call,
+ gen_assign, GNU_xref_member): Const-ify a char*.
+
+1999-03-25 Martin von Löwis <loewis@informatik.hu-berlin.de>
+
+ * gxxint.texi: Remove old discussion on copying virtual bases.
+
+1999-03-25 Zack Weinberg <zack@rabi.columbia.edu>
+
+ * Make-lang.in: Remove all references to g++.o/g++.c.
+ Link g++ from gcc.o.
+
+1999-03-25 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl2.c (comdat_linkage): Treat vtables like functions.
+
+1999-03-25 Mark Mitchell <mark@codesourcery.com>
+
+ * pt.c (tsubst_decl): Tsubst into DECL_BEFRIENDING_CLASSES.
+
+1999-03-25 Nathan Sidwell <nathan@acm.org>
+
+ * decl.c (init_decl_processing): Add `signed' type as a synonym
+ for `int'.
+
+1999-03-25 Jason Merrill <jason@yorick.cygnus.com>
+
+ * typeck.c (common_type): Handle cv-qual unification for pointers
+ to members.
+
+ * decl.c (unqualified_namespace_lookup): Return error_mark_node
+ on error.
+ (lookup_name_real): Set LOOKUP_COMPLAIN when *not* parsing.
+ * lex.c (do_identifier): If we got error_mark_node, call
+ lookup_name again.
+
+1999-03-24 Martin von Löwis <loewis@informatik.hu-berlin.de>
+
+ * class.c (finish_struct_1): Always reset TYPE_FIELDS for empty
+ classes.
+
+1999-03-24 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (lookup_name_real): Do nested field lookup regardless of
+ TYPE_BEING_DEFINED.
+
+1999-03-24 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (lang_type): Remove has_assignment and
+ has_real_assignment. Add befriending_classes.
+ (TYPE_HAS_ASSIGNMENT): Remove.
+ (TYPE_HAS_REAL_ASSIGNMENT): Likewise.
+ (CLASSTYPE_BEFRIENDING_CLASSES): New macro.
+ (lang_decl): Document.
+ (DECL_BEFRIENDING_CLASSES): New macro.
+ (FRIEND_NAME): Move declaration to more obvious location.
+ (FRIEND_DECLS): Likewise.
+ * class.c (finish_struct_1): Don't use TYPE_HAS_REAL_ASSIGNMENT.
+ * decl.c (duplicate_decls): Copy DECL_BEFRIENDING_CLASSES.
+ (fixup_anonymous_union): Don't use TYPE_HAS_ASSIGNMENT.
+ (grok_op_properties): Likewise.
+ * friend.c (is_friend): Use FRIEND_NAME and FRIEND_DECLS.
+ (add_friend): Likewise. Don't do weird things with assignment
+ operators. Update DECL_BEFRIENDING_CLASSES.
+ (add_friends): Don't do weird things with assignment operators.
+ (make_friend_class): Likewise. Update
+ CLASSTYPE_BEFRIENDING_CLASSES.
+ * pt.c (instantiate_class_template): Don't set
+ TYPE_HAS_ASSIGNMENT.
+ (tsubst_copy): Substitute the TREE_TYPE for more unary
+ expressions.
+ * ptree.c (print_lang_type): Don't look at TYPE_HAS_ASSIGNMENT.
+ * search.c (protected_accessible_p): New function.
+ (friend_accessible_p): Likewise.
+ (accessible_p): Use them.
+
+1999-03-23 Mark Mitchell <mark@codesourcery.com>
+
+ * pt.c (convert_nontype_argument): Don't create things that aren't
+ PTRMEM_CSTs when applying a qualification conversion to a
+ PTRMEM_CST.
+
+1999-03-23 Mark Mitchell <mark@codesourcery.com>
+
+ * Makefile.in (OBJS): Don't mention hash.o.
+ (OBJDEPS): Likewise.
+
+1999-03-23 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl2.c (finish_file): Set at_eof to 2 after expanding ctors.
+ * decl.c (expand_static_init): Make sure we don't add any after
+ then.
+
+ * decl.c (cp_finish_decl): Move intelligence about handling
+ DECL_COMDAT for variables from here...
+ * decl2.c (comdat_linkage): ...to here.
+ (maybe_make_one_only): Tweak.
+ (import_export_decl): Call comdat_linkage for variables, too.
+ (finish_file): Handle template statics properly.
+
+1999-03-22 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (TYPE_PTRMEMFUNC_P): Use TYPE_PTRMEMFUNC_FLAG.
+ Document internals of pointer-to-member-functions.
+ (DELTA2_FROM_PTRMEMFUNC): Make it call delta2_from_ptrmemfunc.
+ (PFN_FROM_PTRMEMFUNC): Similarly.
+ (build_type_conversion): Remove unused parameter.
+ (build_ptrmemfunc1): Declare.
+ (expand_ptrmemfunc_cst): New function.
+ (delta2_from_ptrmemfunc): Likewise.
+ (pfn_from_ptrmemfunc): Likewise.
+ * cvt.c (cp_convert_to_pointer): Remove unused parameter to
+ build_type_conversion. Use TYPE_PTRMEM_P for readability.
+ (convert_to_reference): Remove unused parameter to
+ build_type_conversion.
+ (ocp_convert): Likewise.
+ (build_user_type_conversion): Likewise.
+ * error.c (dump_expr): Handle NULL pointer-to-member functions.
+ * expr.c (cplus_expand_expr): Handle PTRMEM_CSTs for functions.
+ * method.c (build_overload_value): Don't go splitting CONSTRUCTORs
+ open when handling pointer-to-member functions.
+ * pt.c (convert_nontype_argument): Clean up error messages. Be
+ more stringent with pointers-to-members.
+ * typeck.c (build_ptrmemfunc1): Don't declare. Make it global.
+ (build_unary_op): Tidy ever-so-slightly.
+ (build_conditional_expr): Remove extra parameter to
+ build_type_conversion.
+ (build_ptrmemfunc): Build PTRMEM_CSTs if we know what function
+ we're using.
+ (expand_ptrmemfunc_cst): Define.
+ (delta2_from_ptrmemfunc): Likewise.
+ (pfn_from_ptrmemfunc): Likewise.
+
+1999-03-19 Mark Mitchell <mark@codesourcery.com>
+
+ * init.c (build_member_call): Handle template-id expressions
+ correctly.
+ * typeck.c (build_x_function_call): Likewise.
+
+1999-03-19 Chip Salzenberg <chip@perlsupport.com>
+
+ * friend.c (make_friend_class): Avoid core dump when
+ not-yet-defined friend type lacks TYPE_LANG_SPECIFIC().
+
+1999-03-18 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (start_function): Suppress normal linkage heuristics
+ for #pragma interface under MULTIPLE_SYMBOL_SPACES.
+
+1999-03-19 Alexandre Oliva <oliva@dcc.unicamp.br>
+
+ * Make-lang.in: ($(INTL_TARGETS)): depend on cp/parse.c
+ ($(srcdir)/cp/parse.c): moved from ../Makefile.in
+
+1999-03-17 Martin von Löwis <loewis@informatik.hu-berlin.de>
+
+ * parse.y (named_complex_class_head_sans_basetype):
+ Do not push a scope for error_mark_node.
+ (maybe_base_class_list): Likewise.
+
+ * decl.c (start_decl): Check for error_mark_node as a type.
+ Detected by g++.brendan/array-refs.C.
+ (start_decl_1): Likewise. Detected by g++.bugs/900322_01.C.
+ (maybe_build_cleanup_1): Likewise. Detected by
+ g++.jason/incomplete1.C.
+
+ * tree.c (build_dummy_object): Use void_zero_node instead of the
+ error_mark_node
+ (is_dummy_object): Check for such a node.
+ Detected by g++.bob/inherit1.C
+
+1999-03-16 Jason Merrill <jason@yorick.cygnus.com>
+
+ * method.c (old_backref_index): Split out...
+ (flush_repeats): From here. Rename back from try_old_backref.
+ (build_mangled_name): Put back some old-style repeat handling.
+
+Mon Mar 15 21:57:16 1999 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * lex.c: Don't include setjmp.h.
+ (parse_float): New static function.
+ (pf_args): New struct.
+ (real_yylex): Use them in call to `do_float_handler'.
+
+1999-03-15 Mark Mitchell <mark@markmitchell.com>
+
+ * decl.c (xref_basetypes): Set CLASSTYPE_VBASECLASSES here.
+ * tree.c (layout_basetypes): Not here.
+ * search.c (dfs_search): Remove; no longer used.
+
+1999-03-12 Mark Mitchell <mark@markmitchell.com>
+
+ * decl2.c (validate_nonmember_using_decl): Issue sensible
+ error-messages on bogus qualifiers.
+
+1999-03-14 Jason Merrill <jason@yorick.cygnus.com>
+
+ * call.c (add_function_candidate): Fix uninitialized variable.
+
+ * Makefile.in (search.o): Add dependency on varray.h.
+
+1999-03-13 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (duplicate_decls): Use same_type_p.
+ * method.c (try_old_backref): Renamed from flush_repeats. Use
+ same_type_p. Don't try to handle repeats. Return success.
+ (is_back_referenceable_type): Return 0 if TYPE_FOR_JAVA. Support
+ calls from old-style code, too.
+ (check_ktype): Use same_type_p.
+ (check_btype): Use same_type_p. Don't pull out TYPE_MAIN_VARIANT.
+ (build_qualified_name): Simplify logic.
+ (process_overload_item): Strip typedefs and quals at the top.
+ (build_mangled_name_for_type_with_Gcode): Remove call to
+ type_canonical_variant.
+ (build_mangled_name): Likewise. Remove support for old-style
+ repeats, which have been disabled since 2.7.2. Don't mess with
+ TREE_USED.
+ (build_decl_overload_real): Don't mess with TREE_USED.
+
+1999-03-13 Nathan Sidwell <nathan@acm.org>
+
+ * error.c (cp_printers): Add 'F' escape character.
+ (dump_type_real): Remove TREE_LIST (fnargs) printing.
+ Functionality moved to dump_parameters.
+ (dump_type_suffix): Use dump_parameters and dump_exception_spec.
+ (dump_function_decl): Extend meaning of V parameter. Use
+ dump_parameters and dump_exception_spec.
+ (dump_parameters): New static function.
+ (dump_exception_spec): New static function.
+ (fndecl_as_string): Change argument semantics. Use
+ dump_function_decl directly.
+
+ * sig.c (build_signature_table_constructor): Use cp_error.
+
+1999-03-13 Martin von Löwis <loewis@informatik.hu-berlin.de>
+
+ * semantics.c (finish_switch_cond): Handle error cases gracefully.
+ Detected by g++.law/enum5.C
+
+ * typeck.c (build_modify_expr): Check for errors after resolving
+ offsets. Detected by g++.brendan/static1.C
+
+ * decl.c (complete_array_type): Ignore initial_value if it is an
+ error. Detected by g++.benjamin/17930.C
+
+ * typeck2.c (process_init_constructor): Return error if one argument
+ is in error. Detected by g++.benjamin/13478.C
+
+1999-03-12 Martin von Löwis <loewis@informatik.hu-berlin.de>
+
+ * decl.c (select_decl): Allow class templates when we need types.
+ * decl2.c (ambiguous_decl): Likewise.
+
+1999-03-12 Mark Mitchell <mark@markmitchell.com>
+
+ * lex.c (do_identifier): Correct call to enforce_access.
+ * search.c (accessible_p): Tweak comment.
+
+1999-03-10 Mark Mitchell <mark@markmitchell.com>
+
+ * semantics.c (begin_class_definition): Call build_self_reference.
+ (finish_member_declaration): Set DECL_CONTEXT for TYPE_DECLs.
+
+ * search.c (assert_canonical_unmarked): Fix typo in prototype.
+
+ * search.c (dfs_canonical_queue): New function.
+ (dfs_assert_unmarked_p): Likewise.
+ (assert_canonical_unmarked): Likewise.
+ (access_in_type): Use it.
+ (accessible_p): Likewise. Walk the whole tree when umarking.
+
+ * sig.c (build_signature_table_constructor): Use accessible_p
+ instead of compute_access.
+
+1999-03-09 Jason Merrill <jason@yorick.cygnus.com>
+
+ * call.c (add_builtin_candidates): Handle overloaded conversion ops.
+
+1999-03-09 Mark Mitchell <mark@markmitchell.com>
+
+ * cp-tree.h (flag_access_control): Declare.
+ (TREE_VIA_PPUBLIC): Document.
+ (DECL_NONSTATIC_MEMBER_P): New macro.
+ (enforce_access): Return an indication of whether or not access
+ was permitted.
+ (build_self_reference): Change prototype.
+ (compute_access): Replace with ...
+ (accessible_p): New function.
+ (dfs_walk): Change prototype.
+ (dfs_unmark): Likewise.
+ (markedp): Likewise.
+ * call.c (enforce_access): Use accessible_p.
+ * class.c (build_self_reference): Insert the declaration into the
+ list of members for this type, and make it public.
+ * decl.c (xref_basetypes): Avoid ill-timed recursion.
+ * init.c (build_offset_ref): Use lookup_member, not three separate
+ name-lookups. Call enforce_access rather than checking for
+ illegal accesses here.
+ (resolve_offset_ref): Likewise.
+ * lex.c (do_identifier): Likewise.
+ * method.c (hack_identifier): Likewise.
+ * parse.y (self_reference): Remove.
+ (opt_component_decl_list): Don't use it.
+ * parse.c: Regenerated.
+ * pt.c (print_candidates): Generalize to handle lists of
+ overloaded functions.
+ (instantiate_class_template): Don't rely on TREE_VIA_PRIVATE; it's
+ not set.
+ (get_template_base): Use new calling convention for dfs_walk.
+ * search.c: Include varray.h. Add prototypes.
+ (dfs_walk): Accept a data pointer to pass to the work functions.
+ All callers changed. All work functions changed.
+ (breadth_first_search): Rename to bfs_walk, and make consistent
+ with dfs_walk.
+ (dfs_walk_real): New function.
+ (canonical_binfo): New function.
+ (context_for_name_lookup): Likewise.
+ (shared_marked_p): Likewise.
+ (shared_unmarked_p): Likewise.
+ (lokup_field_queue_p): Likewise.
+ (lookup_field_r): Generalize to handle both functions and fields.
+ (lookup_field): Just call lookup_member.
+ (lookup_fnfields): Likewise.
+ (lookup_member): Move body of lookup_field here and generalize.
+ (dfs_accessible_queue_p): Likewise.
+ (dfs_accessible_p): Likewise.
+ (dfs_access_in_type): Likewise.
+ (access_in_type): Likewise.
+ (compute_access): Remove, and replace with ...
+ (accessible_p): New function.
+ (vbase_types): Remove.
+ (vbase_decl_ptr_intermediate): Likewise.
+ (vbase_decl_ptr): Likewise.
+ (vbase_init_result): Likewise.
+ (closed_envelopes): Likewise.
+ (bvtable): Likewise.
+
+1999-03-09 Jason Merrill <jason@yorick.cygnus.com>
+
+ * call.c (add_function_candidate): Check for proper number of args
+ before checking the validity of those args.
+
+1999-03-06 Jason Merrill <jason@yorick.cygnus.com>
+
+ * cp-tree.h (struct lang_type): Add anon_union field.
+ (ANON_UNION_TYPE_P): Use it instead of examining type.
+ (SET_ANON_UNION_TYPE_P): New macro.
+ * decl.c (check_tag_decl): Use it.
+
+ * search.c (compute_access): Handle non-type contexts earlier, and
+ handle NULL_TREE.
+
+ * tree.c (build_exception_variant): Use copy_to_permanent.
+
+ * decl2.c (setup_initp): Give statics with no priority the default
+ priority here.
+ (do_dtors, do_ctors, finish_file): Remove special handling of
+ non-prioritized statics.
+
+1999-03-05 Mark Mitchell <mark@markmitchell.com>
+
+ * cp-tree.h (ANON_UNION_TYPE_P): Robustify.
+ * decl.c (make_typename_type): Don't issue an error if an
+ immediate lookup fails; it migt be resolved later.
+ * friend.c (is_friend): Add comment.
+ * search.c (breadth_first_search): Add POSTFN and DATA
+ parameters. Tidy. All callers changed.
+ (lookup_field_queue_p): New function.
+ (lookup_field_r): Likewise.
+ (lookup_field_post): Likewise.
+ (lookup_field): Use them, via breadth_first_search, instead of
+ duplicating logic.
+ (compute_access): Robustify.
+ (lookup_fnfield_info): New structure.
+
+1999-03-05 Jason Merrill <jason@yorick.cygnus.com>
+
+ * pt.c (tsubst, case ARRAY_REF): Use tsubst_expr again.
+
+1999-03-03 Jason Merrill <jason@yorick.cygnus.com>
+
+ * class.c, decl2.c, method.c, pt.c: Add 'static' to make SunOS 4
+ cc happy.
+
+ * decl2.c (import_export_class): Also return if
+ CLASSTYPE_INTERFACE_ONLY is set.
+
+1999-03-03 Martin von Löwis <loewis@informatik.hu-berlin.de>
+
+ * decl.c (push_overloaded_decl): Only overwrite the old binding if
+ there was one.
+ * decl2.c (do_local_using_decl): Fix loop termination.
+
+1999-03-02 Mark Mitchell <mark@markmitchell.com>
+
+ * cp-tree.h (determine_specialization): Don't declare.
+ * pt.c (determine_specialization): Make it static. Eliminate
+ complain parameter. Note that decl is always non-NULL now, and
+ simplify accordingly.
+
+ * decl.c (maybe_push_to_top_level): Always call
+ push_cp_function_context.
+ (pop_from_top_level): Always call pop_cp_function_context.
+
+1999-02-26 Nathan Sidwell <nathan@acm.org>
+
+ * typeck.c (complete_type_or_else): Add VALUE arg, for helpful
+ diagnostics.
+ cp-tree.h (complete_type_or_else): Added VALUE parameter.
+ * init.c (build_new_1): Extra arg to complete_type_or_else.
+ (build_delete): Likewise.
+ * typeck.c (require_complete_type): Likewise.
+ (pointer_int_sum): Likewise.
+ (pointer_diff): Likewise.
+ (build_component_ref): Likewise.
+
+ * typeck2.c (incomplete_type_error): Always use cp_error.
+ Show declaration of undefined type, if appropriate.
+ Deal with UNKNOWN_TYPE nodes.
+
+ * typeck.c (require_complete_type): Use TYPE_SIZE as
+ size_zero_node to mean incomplete type.
+ (require_complete_type_in_void): New function.
+ (build_compound_expr): Call complete_type_in_void for LHS.
+ (build_c_cast): Call complete_type_in_void for void cast.
+ * cvt.c (ocp_convert): Call complete_type_in_void for void cast.
+ * decl.c (cplus_expand_expr_stmt): Void expression checks moved to
+ require_complete_type_in_void. Call it.
+ * cp-tree.h (require_complete_type_in_void): Prototype new function.
+
+ * typeck.c (convert_arguments): Use alternative format for function
+ decls. Don't require_complete_type here. Simplify diagnostic printing.
+ (convert_for_initialization): Don't require_complete_type on RHS yet.
+ * call.c (convert_arg_to_ellipsis): Call require_complete_type.
+
+ * call.c (build_over_call): Cope with qualified void return type.
+ * semantics.c (finish_call_expr): Likewise
+ * typeck.c (build_function_call_real): Likewise
+ (c_expand_return): Likewise
+ * decl2.c (reparse_absdcl_as_expr): Cope with qualified void type.
+
+ * call.c (print_z_candidates): Use alternate print format, to be
+ consistant with (pt.c) print_candidates.
+ method.c (hack_identifier): List candidate members.
+ search.c (lookup_field): Build ambiguous list, and show it, if
+ ambiguous.
+
+1999-02-26 Mark Mitchell <mark@markmitchell.com>
+
+ * typeck.c (decay_conversion): Don't confuse constant array
+ variables with their intiailizers.
+
+ * decl.c (duplicate_decls): Copy DECL_TEMPLATE_INSTANTIATED when
+ merging decls.
+ * pt.c (regenerate_decl_from_template): Tweak for clarity.
+ (instantiate_decl): Mark a decl instantiated before regenerating
+ it to avoid recursion.
+ * tree.c (mapcar): Don't call decl_constant_value unless we know
+ something is TREE_READONLY_DECL_P.
+
+ * class.c (check_for_override): Don't stop checking when we find
+ the first overridden function. Delete #if 0'd code.
+ * search.c (get_matching_virtual): Likewise.
+
+1999-02-25 Richard Henderson <rth@cygnus.com>
+
+ * lang-specs.h: Define __FAST_MATH__ when appropriate.
+
+1999-02-24 Mike Stump <mrs@wrs.com>
+
+ * typeck.c (convert_for_assignment): Allow boolean integral constant
+ expressions to convert to null pointer.
+
+1999-02-24 Martin von Loewis <loewis@informatik.hu-berlin.de>
+
+ * decl.c (lookup_namespace_name): Resolve namespace aliases.
+
+ * class.c (push_nested_class): Allow namespaces.
+
+ * decl2.c (set_decl_namespace): Add friendp parameter.
+ * decl.c (grokfndecl): Pass it.
+ (grokvardecl): Likewise.
+ * cp-tree.h: Change declaration.
+
+1999-02-24 Jason Merrill <jason@yorick.cygnus.com>
+
+ * pt.c (tsubst): Allow an array of explicit size zero.
+
+1999-02-23 Jason Merrill <jason@yorick.cygnus.com>
+
+ * errfn.c: Change varargs code to look like toplev.c.
+
+ * method.c (process_modifiers): Don't prepend 'U' for char or
+ wchar_t.
+
+1999-02-20 Craig Burley <craig@jcb-sc.com>
+
+ * Make-lang.in (cplib2.ready): Don't consider updating
+ cplib2 stuff if the current directory isn't writable, as
+ it won't work (such as during a `make install').
+
+Sun Feb 21 20:38:00 1999 H.J. Lu (hjl@gnu.org)
+
+ * decl2.c (start_objects): Make file scope constructors and
+ destructors local to the file if ASM_OUTPUT_CONSTRUCTOR and
+ ASM_OUTPUT_DESTRUCTOR are defined.
+
+1999-02-19 Mark Mitchell <mark@markmitchell.com>
+
+ * cp-tree.h (CLASSTYPE_METHOD_VEC): Adjust comment.
+ (fn_type_unification): Adjust prototype.
+ (lookup_fnfields_1): Declare.
+ * call.c (add_template_candidate_real): Adjust call to
+ fn_type_unification.
+ * class.c (add_method): Don't allow duplicate declarations of
+ constructors or destructors.
+ (resolve_address_of_overloaded_function): Remove unused variable.
+ Adjust call to fn_type_unification.
+ * decl.c (grokfndecl): Be more robust in the face of illegal
+ specializations.
+ * decl2.c (check_classfn): Remove hokey handling of member
+ templates.
+ * pt.c (determine_specialization): Improve comments. Adjust to
+ handle template argument deduction as per the standard.
+ (check_explicit_specialization): Fix comment spacing. Handle
+ type-conversion operators correctly. Improve error-recovery.
+ (fn_type_unification): Remove EXTRA_FN_ARG parameter.
+ (get_bindings_real): Simplify handling of static members.
+ * search.c (lookup_fnfields_1): Make it have external linkage.
+ * typeck.c (compparms): Fix comment.
+ (build_unary_op): Don't try to figure out which template
+ specialization is being referred to when when the address-of
+ operator is used with a template function.
+
+Thu Feb 18 23:40:01 1999 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * cp-tree.h (lvalue_or_else): Qualify a char* with the `const'
+ keyword to match an analogous change at the top level.
+
+ * tree.c (lvalue_or_else): Likewise.
+
+1999-02-17 Mark Mitchell <mark@markmitchell.com>
+
+ * decl.c (xref_basetypes): Comment.
+ * pt.c (instantiate_class_template): Use xref_basetypes.
+
+1999-02-16 Mark Mitchell <mark@markmitchell.com>
+
+ * cp-tree.h (tsubst): Change prototype.
+ (tsubst_expr): Likewise.
+ (tsubst_copy): Likewise.
+ (type_unification): Remove prototype.
+ * call.c (convert_default_arg): Adjust call to tsubst_expr.
+ * class.c (resolve_address_of_overloaded_function): Just use
+ fn_type_unification.
+ * decl.c (grokdeclarator): Adjust call to tsubst.
+ * method.c (build_template_parm_names): Likewise.
+ * pt.c (GTB_VIA_VIRTUAL): New macro.
+ (GTB_IGNORE_TYPE): Likewise.
+ (resolve_overloaded_unification): Add `complain' parameter.
+ (try_one_overload): Likewise.
+ (tsubst_template_arg_vector): Likewise.
+ (tsubst_template_parms): Likewise.
+ (tsubst_aggr_type): Likewise.
+ (tsubst_arg_types): Likewise.
+ (tsubst_call_declarator_parms): Likewise.
+ (unify): Remove explicit_mask.
+ (type_unification_real): Likewise.
+ (get_template_base_recursive): Likewise.
+ (coerce_template_template_parms): Provide prototype.
+ (tsubst_function_type): Likewise.
+ (try_class_unification): New function.
+ All callers changed to use new complain parameter.
+ (get_template_base): Use try_class_unification.
+ (unify): Adjust handling of classes derived from template types.
+ (fn_type_unification): Substitute explicit arguments before
+ unification.
+
+1999-02-16 Kriang Lerdsuwanakij <lerdsuwa@scf-fs.usc.edu>
+
+ * decl.c (pushdecl): Remove dead code.
+
+1999-02-16 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl2.c (finish_objects): Fix code I missed in previous change.
+
+1999-02-13 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (grokfndecl): Return NULL_TREE instead of error_mark_node.
+ (grokdeclarator): Don't expect error_mark_node from grokfndecl.
+
+ * pt.c (maybe_process_partial_specialization): Complain about
+ 'template <>' on non-specialization.
+
+1999-02-10 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (grokdeclarator): Catch wierd declarators.
+ * decl2.c (finish_file): Don't abort because of namespace parsing
+ failure.
+ (check_decl_namespace): Remove.
+
+1999-02-09 Mark Mitchell <mark@markmitchell.com>
+
+ * cp-tree.h (get_template_base): Don't declare.
+ (dfs_walk): Declare.
+ (dfs_unmark): Likewise.
+ (markedp): Likewise.
+ * pt.c (unify): Remove duplicate declaration. Pass tparms and
+ targs to get_template_base.
+ (get_template_base_recursive): Move here from search.c. Check to
+ see that the base found can be instantiated to form the desired
+ type.
+ (get_template_base): Likewise.
+ (get_class_bindings): Simplify.
+ * search.c (get_template_base_recursive): Move to pt.c.
+ (get_template_base): Likewise.
+ (markedp): Make it global.
+ (dfs_walk): Likewise.
+ (dfs_unmark): Likewise.
+
+1999-02-07 Jason Merrill <jason@yorick.cygnus.com>
+
+ * pt.c (maybe_process_partial_specialization): Complain about
+ specialization in wrong namespace.
+ * tree.c (decl_namespace_context): New fn.
+
+1999-02-06 Kriang Lerdsuwanakij <lerdsuwa@scf-fs.usc.edu>
+
+ * decl2.c (arg_assoc_type): Handle TEMPLATE_TEMPLATE_PARM.
+ * pt.c (coerce_template_template_parms): Handle nested
+ template template parameters.
+
+Sat Feb 6 18:08:40 1999 Jeffrey A Law (law@cygnus.com)
+
+ * typeck2.c: Update email addrsses.
+
+1999-02-04 Kriang Lerdsuwanakij <lerdsuwa@scf-fs.usc.edu>
+
+ * pt.c (unify): Call coerce_template_parms with the COMPLAIN flag
+ turned off.
+
+1999-02-04 Jason Merrill <jason@yorick.cygnus.com>
+
+ * lex.c (retrofit_lang_decl): Split out...
+ (build_lang_decl): From here.
+ * decl.c (pushdecl): Call it for functions generated by the middle
+ end that don't have DECL_LANG_SPECIFIC.
+ * cp-tree.h: Declare it.
+
+ * decl2.c: Remove flag_init_priority. Always enable initp stuff.
+ (start_objects, finish_objects): Only use special
+ init_priority code if the user specified a priority.
+ (do_ctors, do_dtors): Use DEFAULT_INIT_PRIORITY for the non-initp
+ objects.
+
+Wed Feb 3 22:50:17 1999 Marc Espie <Marc.Espie@liafa.jussieu.fr>
+
+ * Make-lang.in (GXX_OBJS): Remove choose-temp.o, pexecute.o and
+ mkstemp.o. Get them from libiberty now.
+ (DEMANGLER_PROG): Simlarly, remove getopt.o getopt1.o.
+
+Tue Feb 2 22:38:48 1999 Theodore Papadopoulo <Theodore.Papadopoulo@sophia.inria.fr>
+
+ * decl2.c (lang_decode_option): Use read_integral_parameter.
+
+1999-02-01 Mark Mitchell <mark@markmitchell.com>
+
+ * pt.c (tsubst, case TYPENAME_TYPE): Check TYPE_BEING_DEFINED
+ before calling complete_type_or_else.
+
+Mon Feb 1 09:49:52 1999 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * input.c (inline): Don't define, its handled by system.h.
+
+Sun Jan 31 20:34:29 1999 Zack Weinberg <zack@rabi.columbia.edu>
+
+ * decl2.c: Don't define flag_no_ident here. Don't process
+ -f(no-)ident here.
+ * cp-tree.h: Don't declare flag_no_ident here.
+ * lang-specs.h: Map -Qn to -fno-ident.
+
+1999-01-28 Jason Merrill <jason@yorick.cygnus.com>
+
+ * cp-tree.h (struct tree_binding): Replace scope field with a union.
+ (BINDING_SCOPE): Adjust.
+ * decl.c (BINDING_LEVEL): Adjust.
+
+1999-01-26 Jason Merrill <jason@yorick.cygnus.com>
+
+ * pt.c (instantiate_class_template): Set up the DECL_INITIAL of
+ member constants.
+
+ * init.c (expand_member_init): Pull out TYPE_MAIN_VARIANT in
+ a ctor initializer.
+
+ * tree.c (equal_functions): Fix name in prototype.
+
+ * decl.c (push_local_binding): Add FLAGS argument.
+ (pushdecl, push_overloaded_decl): Pass it.
+ * decl2.c (do_local_using_decl): Likewise.
+ * cp-tree.h: Adjust prototype.
+ * decl.c (poplevel): Fix logic.
+
+ * decl.c (push_local_binding): Also wrap used decls in a TREE_LIST.
+ (poplevel): Handle that. Fix logic for removing TREE_LISTs.
+ (cat_namespace_levels): Don't loop forever.
+
+1999-01-25 Richard Henderson <rth@cygnus.com>
+
+ * typeck.c (build_reinterpret_cast): Fix typo in duplicated test.
+
+1999-01-25 Jason Merrill <jason@yorick.cygnus.com>
+
+ * class.c (resolve_address_of_overloaded_function): Mark the
+ chosen function used.
+
+ * call.c (build_call): Make sure that a function coming in has
+ been marked used already.
+ * decl.c (expand_static_init): Call mark_used instead of
+ assemble_external.
+ * except.c (call_eh_info, do_pop_exception, expand_end_eh_spec,
+ alloc_eh_object, expand_throw): Likewise.
+ * init.c (build_builtin_delete_call): Likewise.
+ * rtti.c (call_void_fn, get_tinfo_fn, build_dynamic_cast_1,
+ expand_si_desc, expand_class_desc, expand_ptr_desc, expand_attr_desc,
+ expand_generic_desc): Likewise.
+
+1999-01-25 Martin von Löwis <loewis@informatik.hu-berlin.de>
+
+ * tree.c (equal_functions): New function.
+ (ovl_member): Call it.
+
+1999-01-24 Jason Merrill <jason@yorick.cygnus.com>
+
+ * cvt.c (cp_convert_to_pointer): Fix conversion of 0 to pmf.
+
+1999-01-25 Martin von Loewis <loewis@informatik.hu-berlin.de>
+
+ * decl.c (decls_match): Return 1 if old and new are identical.
+ (push_overloaded_decl): Set OVL_USED when PUSH_USING.
+
+1999-01-24 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (start_function): Make member functions one_only on windows.
+ * decl2.c (import_export_decl): Likewise.
+
+ * decl.c (grokdeclarator): Don't complain about implicit int in
+ a system header. Change same-name field check to not complain in
+ a system header instead of within extern "C".
+
+1999-01-21 Mark Mitchell <mark@markmitchell.com>
+
+ * cp-tree.h (PUSH_GLOBAL): New macro.
+ (PUSH_LOCAL): Likewise.
+ (PUSH_USING): Likewise.
+ (namespace_bindings_p): Declare.
+ (push_overloaded_decl): Likewise.
+ * decl.c (push_overloaded_decl): Don't make it static. Check for
+ illegal declarations after using declarations here.
+ (namespace_bindings_p): Likewise.
+ (duplicate_decls): Don't consider declarations from different
+ namespaces to be the same.
+ (pushdecl): Use symbolic PUSH_ constants in calls to
+ push_overloaded_decl.
+ (push_overloaded_decl_1): Likewise.
+ * decl2.c (validate_nonmember_using_decl): Tweak `std' handling.
+ (do_nonmember_using_decl): Check for illegal using declarations
+ after ordinary declarations here.
+ (do_local_using_decl): Call pushdecl to insert declarations.
+
+1999-01-21 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (grokdeclarator): Fix lang_c -> lang_name_c typo.
+
+1999-01-21 Mark Mitchell <mark@markmitchell.com>
+
+ * tree.c (build_cplus_array_type_1): Don't call build_array_type
+ for types involving template parameters.
+
+ * cp-tree.h (PARM_DECL_EXPR): Delete.
+ (convert_default_arg): Change prototype.
+ (check_default_argument): Declare.
+ (search_tree): Likewise.
+ * call.c (convert_default_arg): Take the function to which the
+ default argument belongs as a parameter, and do any necessary
+ instantiation here, instead of ...
+ (build_over_call): Here.
+ * decl.c (local_variable_p): New function.
+ (check_default_argument): Likewise, split out and tidied from ...
+ (grokparms): Here.
+ * error.c (dump_expr): Don't set PARM_DECL_EXPR.
+ * pt.c (tsubst_call_declarator_parms): New function.
+ (for_each_template_parm): Handle ARRAY_REFs. Do the obvious thing
+ with CALL_EXPRs, rather than trying to be clever.
+ (tsubst): Use tsubst_call_declarator_parms.
+ * tree.c (search_tree): Don't make it static.
+ * typeck.c (convert_arguments): Use new interface to
+ convert_default_arg.
+
+1999-01-20 Mark Mitchell <mark@markmitchell.com>
+
+ * error.c (dump_function_decl): Don't print the argument types for
+ a function when the verbosity level is negative.
+
+ * call.c (build_over_call): Check format attributes at call-time.
+
+ * pt.c (tsubst_copy): Fix comment.
+ (unify): Don't allow unification with variable-sized arrays.
+
+ * semantics.c (finish_stmt_expr): When processing a template make
+ the BIND_EXPR long-lived.
+
+1999-01-19 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl2.c (finish_vtable_vardecl): Make vtables comdat here.
+ (import_export_vtable): Not here.
+
+1999-01-18 Jason Merrill <jason@yorick.cygnus.com>
+
+ * typeck.c (build_component_ref): Wrap an OVERLOAD around a unique
+ non-static member function.
+
+1999-01-18 Nathan Sidwell <nathan@acm.org>
+
+ * class.c (instantiate_type): Only diagnose illegal address of member
+ function if complaining.
+
+ * decl.c (lookup_name_real): Remove duplicate code.
+
+1999-01-18 Jason Merrill <jason@yorick.cygnus.com>
+
+ * tree.c (copy_template_template_parm): Use permanent_obstack.
+
+1999-01-18 Kriang Lerdsuwanakij <lerdsuwa@scf-fs.usc.edu>
+
+ * pt.c (unify): Remove restrictions on deduction of argument
+ of template template parameters.
+
+1999-01-18 Nathan Sidwell <nathan@acm.org>
+
+ * rtti.c (build_dynamic_cast_1): Resolve OFFSET_REF exprs.
+
+ * class.c (resolve_address_of_overloaded_function): Show list of
+ all candidates, when none of them match.
+
+1999-01-18 Chip Salzenberg <chip@perlsupport.com>
+
+ * typeck.c (comp_ptr_ttypes_reinterpret): Per ANSI, tighten up
+ definition of 'casting away const' in reinterpret_cast<>.
+
+1999-01-18 Graham <grahams@rcp.co.uk>
+
+ * cvt.c: Add include for decl.h, remove extern for
+ static_aggregates which is now provided by decl.h.
+
+ * Makefile.in (cvt.o): Add dependency for decl.h and missing
+ dependencies for convert.h and flags.h.
+
+1999-01-18 Nathan Sidwell <nathan@acm.org>
+
+ * decl2.c (do_dtors): Set current location to that of the
+ decl, for sensible diagnostics and debugging.
+ (check_classfn): Issue `incomplete type' error, if
+ class is not defined.
+
+1999-01-16 Jason Merrill <jason@yorick.cygnus.com>
+
+ * cp-tree.h: Add prototype for bound_pmf_p.
+
+1999-01-16 Jason Merrill <jason@yorick.cygnus.com>
+ Manfred Hollstein <manfred@s-direktnet.de>
+
+ * decl.c (grokdeclarator): Don't make 'main(){}' an error with only
+ -Wreturn-type.
+
+1999-01-16 Nathan Sidwell <nathan@acm.org>
+
+ * cp-tree.h (struct lang_type): Added has_mutable flag.
+ (CLASSTYPE_HAS_MUTABLE): New macro to access it.
+ (TYPE_HAS_MUTABLE_P): New macro to read it.
+ (cp_has_mutable_p): Prototype for new function.
+ * class.c (finish_struct_1): Set has_mutable from members.
+ * decl.c (cp_finish_decl): Clear decl's TREE_READONLY flag, if
+ it contains a mutable.
+ * typeck.c (cp_has_mutable_p): New function.
+
+1999-01-15 Mark Mitchell <mark@markmitchell.com>
+
+ * pt.c (process_template_parm): Ignore top-level qualifiers on
+ non-type parameters.
+
+ * decl.c (start_function): Use current_function_parms in the call
+ to require_complete_type_for_parms, not the probably empty
+ DECL_ARGUMENTS.
+
+1999-01-14 Jason Merrill <jason@yorick.cygnus.com>
+
+ * semantics.c (finish_asm_stmt): Don't warn about redundant volatile.
+
+ * decl2.c (import_export_class): MULTIPLE_SYMBOL_SPACES only means
+ that we don't suppress the other copies.
+ * lex.c (handle_cp_pragma): Likewise.
+
+1999-01-13 Mark Mitchell <mark@markmitchell.com>
+
+ * decl.c (grokdeclarator): Undo 1998-12-14 change.
+ * tree.c (build_cplus_array_type_1): Likewise.
+ * pt.c (instantiate_class_template): Remove misleading comment.
+ (tsubst_aggr_type): Substitute if there are template parameters,
+ regardless of whether or not they use template arguments.
+ (unify): Likewise, but for unification.
+
+1999-01-12 Richard Henderson <rth@cygnus.com>
+
+ * cp-tree.h (flag_permissive): Declare extern.
+
+1999-01-06 Mark Mitchell <mark@markmitchell.com>
+
+ * cp-tree.h (IDENTIFIER_TYPENAME_P): Use OPERATOR_TYPENAME_FORMAT
+ here.
+ (lang_type): Add is_partial_instantiation. Decrease width of
+ dummy.
+ (PARTIAL_INSTANTIATION_P): New macro.
+ (OPERATOR_TYPENAME_P): Remove.
+ * decl.c (unary_op_p): Use IDENTIFIER_TYPENAME_P, not
+ OPERATOR_TYPENAME_P.
+ (grok_op_properties): Likewise.
+ * friend.c (do_friend): Handle friends that are member functions
+ correctly.
+ * lex.c (init_parse): Use OPERATOR_TYPENAME_FORMAT.
+ * pt.c (instantiate_class_template): Rework for clarity. Avoid
+ leaving TYPE_BEING_DEFINED set in obscure cases. Don't do
+ any more partial instantiation than is absolutely necessary for
+ implicit typename. Set PARTIAL_INSTANTIATION_P.
+ (tsubst_decl): Use IDENTIFIER_TYPENAME_P.
+ * semantics.c (begin_class_definition): Handle partial
+ specializations of a type that was previously partially
+ instantiated.
+
+Wed Jan 6 03:18:53 1999 Mark Elbrecht <snowball3@usa.net.
+
+ * g++spec.c (LIBSTDCXX): Provide default definition.
+ (lang_specific_driver): Use LIBSTDCXX instead of "-lstdc++".
+
+Tue Jan 5 22:11:25 1999 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * Make-lang.in (g++.o): Depend on prefix.h.
+
+1999-01-04 Jason Merrill <jason@yorick.cygnus.com>
+
+ * tree.c (bound_pmf_p): New fn.
+ * typeck.c (build_c_cast): Use it.
+
+ * decl.c (grok_op_properties): Use same_type_p.
+
+Tue Dec 22 15:09:25 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * Makefile.in (cvt.o): Depend on toplev.h.
+
+ * cp-tree.h (check_template_shadow, pod_type_p): Add prototypes.
+
+ * cvt.c: Include toplev.h.
+
+ * except.c (get_eh_caught, get_eh_handlers): Hide prototypes and
+ definitions.
+
+ * init.c (expand_vec_init): Initialize variable `itype'.
+
+ * lex.c (yyerror): Cast the argument passed to a ctype function to
+ an unsigned char.
+
+ * method.c (build_mangled_C9x_name): Wrap prototype and definition
+ in "HOST_BITS_PER_WIDE_INT >= 64".
+
+ * typeck.c (build_binary_op): Mark parameter `convert_p' with
+ ATTRIBUTE_UNUSED.
+
+1998-12-22 Mark Mitchell <mark@markmitchell.com>
+
+ * cp-tree.h (TYPE_RAISES_EXCEPTIONS): Improve documentation.
+ * tree.c (build_exception_variant): Don't crash on empty throw
+ specs.
+
+1998-12-18 DJ Delorie <dj@cygnus.com>
+
+ * cvt.c (convert_to_reference): Check for both error_mark_node
+ and NULL_NODE after call to convert_for_initialization.
+
+1998-12-17 Jason Merrill <jason@yorick.cygnus.com>
+
+ * error.c (interesting_scope_p): New fn.
+ (dump_simple_decl): Use it.
+ (dump_expr, case CONSTRUCTOR): Force a & for a PMF.
+ (dump_expr, case OFFSET_REF): Print ->* if appropriate.
+
+1998-12-16 Mark Mitchell <mark@markmitchell.com>
+
+ * class.c (resolve_address_of_overloaded_function): Do conversion
+ to correct type here, rather than ...
+ (instantiate_type): Here.
+
+ * cp-tree.h (DECL_TEMPLATE_PARM_P): New macro.
+ (DECL_TEMPLATE_TEMPLATE_PARM_P): Use it.
+ (decl_template_parm_p): Remove.
+ * decl.c (pushdecl): Don't set DECL_CONTEXT for a template
+ paramter.
+ * lex.c (do_identifier): Use DECL_TEMPLATE_PARM_P.
+ * pt.c (push_inline_template_parms_recursive): Set it.
+ (decl_template_parm_p): Remove.
+ (check_template_shadow): Use DECL_TEMPLATE_PARM_P.
+ (process_template_parm): Set it.
+
+Wed Dec 16 16:33:58 1998 Dave Brolley <brolley@cygnus.com>
+
+ * lang-specs.h (default_compilers): Pass -MD, -MMD and -MG to cc1plus
+ if configured with cpplib.
+
+1998-12-15 Mark Mitchell <mark@markmitchell.com>
+
+ * decl.c (poplevel): Make sure ns_binding is initialized.
+
+ * decl.c (finish_function): Undo inadvertant change in previous
+ patch.
+
+1998-12-14 Mark Mitchell <mark@markmitchell.com>
+
+ * class.c (pushclass): Tweak handling of class-level bindings.
+ (resolve_address_of_overloaded_function): Update pointer-to-member
+ handling.
+ (instantiate_type): Likewise.
+ * cvt.c (cp_convert_to_pointer): Likewise.
+ * decl.c (pop_binding): Take the DECL to pop, not just the name.
+ Deal with `struct stat' hack.
+ (binding_level): Add to documentation.
+ (push_binding): Clear BINDING_TYPE.
+ (add_binding): New function.
+ (push_local_binding): Use it.
+ (push_class_binding): Likewise.
+ (poplevel): Adjust calls to pop_binding.
+ (poplevel_class): Likewise.
+ (pushdecl): Adjust handling of TYPE_DECLs; add bindings for hidden
+ declarations to current binding level.
+ (push_class_level_binding): Likewise.
+ (push_overloaded_decl): Adjust handling of OVERLOADs in local
+ bindings.
+ (lookup_namespace_name): Don't crash when confronted with a
+ TEMPLATE_DECL.
+ (lookup_name_real): Do `struct stat' hack in local binding
+ contexts.
+ (build_ptrmemfunc_type): Adjust documentation.
+ (grokdeclarator): Don't avoid building real array types when
+ processing templates unless really necessary.
+ (finish_method): Adjust calls to pop_binding.
+ * decl2.c (reparse_absdcl_as_expr): Recursively call ourselves,
+ not reparse_decl_as_expr.
+ (build_expr_from_tree): Deal with a template-id as the function to
+ call in a METHOD_CALL_EXPR.
+ * pt.c (convert_nontype_argument): Tweak pointer-to-member handling.
+ (maybe_adjust_types_For_deduction): Don't do peculiar things with
+ METHOD_TYPEs here.
+ (resolve_overloaded_unification): Handle COMPONENT_REFs. Build
+ pointer-to-member types where necessary.
+ * tree.c (build_cplus_array_type_1): Don't avoid building real
+ array types when processing templates unless really necessary.
+ (build_exception_variant): Compare the exception lists correctly.
+
+1998-12-13 Mark Mitchell <mark@markmitchell.com>
+
+ * cp-tree.def (CPLUS_BINDING): Update documentation.
+ * cp-tree.h (LOCAL_BINDING_P): New macro.
+ (lang_identifier): Rename local_value to bindings.
+ (tree_binding): Make `scope' of type `void*', not `tree'.
+ (BINDING_SCOPE): Update documentation.
+ (IDENTIFIER_LOCAL_VALUE): Remove.
+ (IDENTIFIER_CLASS_VALUE): Document.
+ (IDENTIFIER_BINDING): New macro.
+ (IDENTIFIER_VALUE): Likewise.
+ (TIME_IDENTIFIER_TIME): Likewise.
+ (TIME_IDENTIFIER_FILEINFO): Likewise.
+ (IMPLICIT_TYPENAME_P): Likewise.
+ (set_identifier_local_value): Remove.
+ (push_local_binding): New function.
+ (push_class_binding): Likewise.
+ * class.c (pushclass): Update comments; use push_class_binding.
+ * decl.c (set_identifier_local_value_with_scope): Remove.
+ (set_identifier_local_value): Likewise.
+ (push_binding): New function.
+ (pop_binding): Likewise.
+ (binding_level): Update documentation. Remove shadowed.
+ (BINDING_LEVEL): New macro.
+ (free_binding_nodes): New variable.
+ (poplevel): Adjust for new name-lookup scheme. Don't mess up
+ BLOCK_VARs when doing for-scope extension. Remove effectively
+ dead code.
+ (pushlevel_class): Tweak formatting.
+ (poplevel_class): Adjust for new name-lookup scheme.
+ (print_binding_level): Likewise.
+ (store_bindings): Likewise.
+ (pushdecl): Likewise.
+ (pushdecl_class_level): Likewise.
+ (push_class_level_binding): Likewise.
+ (push_overloaded_decl): Update comments. Adjust for new
+ name-lookup scheme.
+ (lookup_name_real): Likewise.
+ (lookup_name_current_level): Likewise.
+ (cp_finish_decl): Likewise.
+ (require_complete_types_for_parms): Likewise. Remove misleading
+ #if 0'd code.
+ (grok_parms): Likewise. Don't call
+ require_complete_types_for_parms here.
+ (grok_ctor_properties): Don't treat templates as copy
+ constructors.
+ (grop_op_properties): Or as assignment operators.
+ (start_function): Document. Adjust for new name-lookup scheme.
+ (finish_function): Likewise.
+ * decl2.c (do_local_using_decl): Use push_local_binding.
+ * lex.c (begin_definition_of_inclass_inline): New function, split
+ out from ...
+ (do_pending_inlines): Here, and ...
+ (process_next_inline): Here.
+ (get_time_identifier): Use TIME_IDENTIFIER_* macros.
+ (init_filename_times): Likewise.
+ (extract_interface_info): Likewise.
+ (ste_typedecl_interface_info): Likewise.
+ (check_newline): Likewise.
+ (dump_time_statistics): Likewise.
+ (handle_cp_pragma): Likewise.
+ (do_identifier): Adjust for new name-lookup scheme.
+ * parse.y (function_try_block): Return ctor_initializer_opt value.
+ (fndef): Use it.
+ (fn.defpen): Pass appropriate values to start_function.
+ (pending_inline): Use functor_try_block value, and pass
+ appropriate values to finish_function.
+ * pt.c (is_member_template): Update documentation; remove handling
+ of FUNCTION_DECLs. As per name, this function should deal only in
+ TEMPLATE_DECLs.
+ (decl_template_parm_p): Change name of olddecl parameter to decl.
+ (check_template_shadow): Adjust for new name-lookup scheme.
+ (lookup_template_class): Likewise.
+ (tsubst_decl): Tweak so as not to confuse member templates with
+ copy constructors and assignment operators.
+ (unify): Handle UNION_TYPEs.
+ * ptree.c (print_lang_identifier): Adjust for new name-lookup scheme.
+ (lang_print_xnode): Adjust for new name-lookup scheme.
+ * typeck.c (mark_addressable): Likewise.
+ (c_expand_return): Likewise.
+
+1998-12-08 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (grokdeclarator): Allow field with same name as class
+ in extern "C".
+
+ * decl.c (lookup_name_real): Don't limit field lookup to types.
+ * class.c (check_member_decl_is_same_in_complete_scope): No error
+ if icv and x are the same.
+ * lex.c (do_identifier): Tweak error message.
+
+1998-12-10 Mark Mitchell <mark@markmitchell.com>
+
+ * decl.c (start_enum): Use push_obstacks, not
+ end_temporary_allocation.
+ (finish_enum): Call pop_obstacks.
+
+1998-12-10 Mark Mitchell <mark@markmitchell.com>
+
+ * class.c (instantiate_type): Return error_mark_node rather than
+ junk.
+
+1998-12-09 Mark Mitchell <mark@markmitchell.com>
+
+ * cp-tree.h (most_specialized_instantiation): New function.
+ (print_candidates): Likewise.
+ * class.c (validate_lhs): Remove.
+ (resolve_address_of_overloaded_function): New function, split out
+ and then substantially reworked, from ...
+ (instantiate_type): Use it. Simplify.
+ * cvt.c (convert_to_reference): Complain when caller has indicated
+ that's the right thing to do. Don't crash if instantiate_type
+ fails.
+ * pt.c: Substitute `parameters' for `paramters' throughout.
+ (print_candidates): Don't make it static.
+ (most_specialized_instantiation): Split out from ...
+ (most_specialized): Here.
+
+Wed Dec 9 15:33:01 1998 Dave Brolley <brolley@cygnus.com>
+
+ * lex.c (lang_init_options): Initialize cpplib.
+ * decl2.c (parse_options,cpp_initialized): Removed.
+ (lang_decode_option): Move initialization of cpplib to
+ lang_init_options.
+
+1998-12-09 Mark Mitchell <mark@markmitchell.com>
+
+ * decl.c (grokdeclarator): Update the name of the TEMPLATE_DECL, as
+ well as the TYPE_DECL, when a typedef name is assigned to a
+ previously anonymous type.
+
+1998-12-08 Andrew MacLeod <amacleod@cygnus.com>
+
+ * cp/except.c (call_eh_info): use __start_cp_handler instead of
+ __cp_eh_info for getting the eh info pointer. Add table_index to
+ field list.
+ (push_eh_cleanup): Don't increment 'handlers' data field.
+ (process_start_catch_block): Don't set the 'caught' field.
+
+ * cp/exception.cc (CP_EH_INFO): New macro for getting the
+ exception info pointer within library routines.
+ (__cp_eh_info): Use CP_EH_INFO.
+ (__start_cp_handler): Get exception info pointer, set caught field,
+ and increment the handlers field. Avoids this being done by handlers.
+ (__uncatch_exception, __check_eh_spec): Use CP_EH_INFO macro.
+ (uncaught_exception): Use CP_EH_INFO macro.
+
+Tue Dec 8 10:48:21 1998 Jeffrey A Law (law@cygnus.com)
+
+ * Make-lang.in (cxxmain.o): Depend on $(DEMANGLE_H), not demangle.h
+
+Mon Dec 7 17:56:06 1998 Mike Stump <mrs@wrs.com>
+
+ * lex.c (check_newline): Add support for \ as `natural'
+ characters in file names in #line to be consistent with #include
+ handling. We support escape prcessing in the # 1 "..." version of
+ the command. See also support in cp/lex.c.
+
+1998-12-07 Zack Weinberg <zack@rabi.phys.columbia.edu>
+
+ * cp/decl2.c: s/data/opts/ when initializing cpp_reader
+ structure.
+
+1998-12-07 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (build_typename_type): Set DECL_ARTIFICIAL.
+
+ * error.c (dump_simple_decl): Also print namespace context.
+ (dump_function_decl): Likewise.
+
+ * decl2.c (ambiguous_decl): Don't print old value if it's
+ error_mark_node.
+
+ * decl.c (lookup_name_real): Fix handling of local types shadowed
+ by a non-type decl. Remove obsolete code.
+ * cp-tree.h (DECL_FUNCTION_SCOPE_P): New macro.
+
+ * lang-options.h: Add -fpermissive.
+ * decl2.c: Likewise.
+ * cp-tree.h: Add flag_permissive.
+ * decl.c (init_decl_processing): If neither -fpermissive or -pedantic
+ were specified, set flag_pedantic_errors.
+ * call.c (build_over_call): Turn dropped qualifier messages
+ back into pedwarns.
+ * cvt.c (convert_to_reference): Likewise.
+ * typeck.c (convert_for_assignment): Likewise.
+
+1998-12-05 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl2.c (coerce_new_type): Use same_type_p.
+ (coerce_delete_type): Likewise.
+
+ * call.c (check_dtor_name): Return 1, not error_mark_node.
+
+1998-12-04 Jason Merrill <jason@yorick.cygnus.com>
+
+ * lex.c (handle_cp_pragma): Disable #pragma interface/implementation
+ if MULTIPLE_SYMBOL_SPACES.
+
+ * pt.c (check_template_shadow): New fn.
+ * decl2.c (grokfield): Use it.
+ * decl.c (pushdecl): Likewise.
+ (pushdecl_class_level): Likewise.
+ (start_method): Likewise.
+ (xref_tag): Don't try to use 't' if we're defining.
+
+ * call.c (check_dtor_name): Just return an error_mark_node.
+ * pt.c (lookup_template_class): Complain about using non-template here.
+ * parse.y (apparent_template_type): Not here.
+
+ * pt.c (check_explicit_specialization): Complain about specialization
+ with C linkage.
+
+ * lang-options.h: Add -f{no-,}implicit-inline-templates.
+
+ * pt.c (convert_nontype_argument): Don't assume that any integer
+ argument is intended to be a constant-expression.
+
+1998-12-03 Mark Mitchell <mark@markmitchell.com>
+
+ * class.c (handle_using_decl): Fix comment. Don't lookup
+ constructors in base classes.
+ (validate_lhs): Fix typo in comment.
+ * search.c (lookup_field_1): Don't return a USING_DECL.
+
+ * cp-tree.h (DECL_ACCESS): Improve documentation.
+
+ * decl.c (expand_static_init): Don't set the initialization-done
+ flag until the initialization is done.
+
+1998-12-02 Mark Mitchell <mark@markmitchell.com>
+
+ * decl2.c (validate_nonmember_using_decl): Complain about using
+ declarations for class members.
+
+1998-11-29 Jason Merrill <jason@yorick.cygnus.com>
+
+ * typeck2.c (process_init_constructor): Use same_type_p.
+
+ * decl.c (check_tag_decl): Don't warn about null decl inside a
+ class.
+
+ * pt.c (unify, case OFFSET_TYPE): Pass down 'strict' rather than
+ UNIFY_ALLOW_NONE.
+ (convert_nontype_argument): Use TYPE_PTRMEMFUNC_FN_TYPE.
+ (resolve_overloaded_unification): Strip baselinks.
+
+Fri Nov 27 13:07:23 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * g++spec.c: Don't prototype xmalloc.
+
+1998-11-25 Jason Merrill <jason@yorick.cygnus.com>
+
+ * except.c (expand_throw): Use TYPE_PTR_P to check for pointers.
+
+ * decl.c (check_tag_decl): Do complain about null friend decl at
+ file scope.
+
+1998-11-25 Andreas Schwab <schwab@issan.cs.uni-dortmund.de>
+
+ * lex.c (make_lang_type): Clear the whole struct lang_type, not
+ only the first multiple of sizeof (int).
+
+1998-11-24 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (start_decl): An explicit specialization of a static data
+ member is only a definition if it has an initializer.
+
+ * except.c (expand_throw): Use cp_finish_decl for the throw temp.
+ * cvt.c (build_up_reference): Pass DIRECT_BIND down into
+ cp_finish_decl.
+ * init.c (expand_default_init): Check for DIRECT_BIND instead of
+ DECL_ARTIFICIAL.
+
+ * call.c (build_over_call): Use build_decl.
+
+ * except.c (expand_throw): Just use convert, not
+ build_reinterpret_cast.
+
+ * lex.c (handle_generic_pragma): Use token_buffer.
+
+ * decl.c (check_tag_decl): Don't complain about null friend decl.
+
+1998-11-24 Dave Pitts <dpitts@cozx.com>
+
+ * Make-lang.in (DEMANGLER_PROG): Move the output argumnts to the
+ first position.
+ * lex.c (check_newline): Use ISALPHA.
+ (readescape): Use ISGRAPH.
+ (yyerror): Use ISGRAPH.
+
+1998-11-24 Nathan Sidwell <nathan@acm.org>
+
+ * search.c (get_abstract_virtuals): Do not use initial
+ CLASSTYPE_ABSTRACT_VIRTUALS.
+ * typeck2.c (abstract_virtuals_error): Show location of abstract
+ declaration.
+ * call.c (build_new_method_call): Use
+ CLASSTYPE_ABSTRACT_VIRTUAL, rather than recalculate.
+ * class.c (finish_struct_bits): Don't bother working out whether
+ get_abstract_virtuals will do anything, just do it.
+
+1998-11-24 Graham <grahams@rcp.co.uk>
+
+ * typeck.c (build_component_ref): Remove unused statement.
+
+1998-11-24 Jason Merrill <jason@yorick.cygnus.com>
+
+ * class.c (add_method): Catch invalid overloads.
+
+ * class.c (add_method): Build up OVERLOADs properly for conversion ops.
+ * search.c (lookup_conversions): Handle getting real OVERLOADs.
+ (add_conversions): Likewise. Revert last change.
+ * call.c (add_conv_candidate): Pass totype to add_candidate instead
+ of fn. Don't add a new candidate if the last one was for the same
+ type.
+ (print_z_candidates): Handle getting a type as a function.
+ (joust): If we got two conversion candidates to the same type,
+ just pick one.
+ (build_object_call): Lose 'templates'.
+ (build_user_type_conversion_1): Handle getting real OVERLOADs.
+
+1998-11-23 Jason Merrill <jason@yorick.cygnus.com>
+
+ * typeck2.c (process_init_constructor): If there are elements
+ that don't have initializers and they need to have constructors
+ run, supply them with initializers.
+
+ * class.c (finish_struct_1): A class with a 0-width bitfield is
+ still empty.
+
+1998-11-23 Mark Mitchell <mark@markmitchell.com>
+
+ * pt.c (instantiate_class_template): Don't try to figure out what
+ specialization to use for a partial instantiation. Correct
+ typos in a couple of comments. Avoid calling uses_template_parms
+ multiple times.
+
+1998-11-23 Benjamin Kosnik <bkoz@cygnus.com>
+
+ * method.c (process_overload_item): Add call to
+ build_mangled_C9x_name for intTI_type_nodes.
+ (build_mangled_C9x_name): Add prototype, define.
+ * decl.c (init_decl_processing): Add names for
+ TImode_type_node.
+
+1998-11-23 Jason Merrill <jason@yorick.cygnus.com>
+
+ * parse.y (named_class_head): Update CLASSTYPE_DECLARED_CLASS.
+
+ * class.c (finish_struct_1): Set things up for 0-width bitfields
+ like we do for others.
+
+ * decl.c (check_tag_decl): New fn.
+ (shadow_tag): Split out from here.
+ * decl2.c (grok_x_components): Call it.
+
+1998-11-22 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c: Lose warn_about_return_type.
+ (grokdeclarator): Always complain about implicit int, except for
+ `main () { ... }'.
+
+ * decl.c (tag_name): New fn.
+ (xref_tag): Complain about using typedef-name after class-key.
+
+ * init.c (expand_vec_init): Also keep going if from_array.
+
+ * tree.c (is_overloaded_fn): Also handle the output of
+ build_offset_ref.
+
+ * decl.c (grokdeclarator): Use constructor_name when comparing
+ field name against enclosing class.
+ * class.c (finish_struct_anon): Likewise.
+
+1998-11-22 Mark Mitchell <mark@markmitchell.com>
+
+ * decl.c (poplevel): Remove code to handle KEEP == 2.
+ (finish_function): Don't confuse BLOCK-order when
+ processing a destructor.
+
+1998-11-21 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (require_complete_types_for_parms): Call layout_decl
+ after we've completed the type.
+
+1998-11-21 Martin von Löwis <loewis@informatik.hu-berlin.de>
+
+ * decl2.c (validate_nonmember_using_decl): Allow using templates
+ from the global namespace.
+
+1998-11-21 Jason Merrill <jason@yorick.cygnus.com>
+
+ Handle specifying template args to member function templates.
+ * tree.c (build_overload): Always create an OVERLOAD for a template.
+ * search.c (add_conversions): Handle finding an OVERLOAD.
+ * decl2.c (check_classfn): Likewise.
+ * lex.c (identifier_type): See through a baselink.
+ * parse.y (do_id): Don't call do_identifier if we got a baselink.
+ * class.c (instantiate_type, case TREE_LIST): Recurse.
+
+ * decl.c (grokdeclarator): Allow a boolean constant for array
+ bounds, odd as that sounds.
+
+ * pt.c (unify): Be more strict about non-type parms, except for
+ array bounds.
+ (UNIFY_ALLOW_INTEGER): New macro.
+
+1998-11-19 Manfred Hollstein <manfred@s-direktnet.de>
+
+ * Make-lang.in (mandir): Replace all uses of $(mandir) by $(man1dir).
+
+1998-11-19 Jason Merrill <jason@yorick.cygnus.com>
+
+ * semantics.c (begin_class_definition): Call
+ maybe_process_partial_specialization before push_template_decl.
+ Don't call push_template_decl for a specialization.
+ * search.c (lookup_field): Do return a member template class.
+ * decl2.c (handle_class_head): Handle member template classes.
+
+ * decl.c (grokdeclarator): A parm type need not be complete.
+
+ * pt.c (convert_nontype_argument): Fix thinko.
+
+1998-11-18 Mark Mitchell <mark@markmitchell.com>
+
+ * cp-tree.h (PTRMEM_CST_CLASS): Fix typo.
+ (global_delete_fndecl): New variable.
+ * decl.c (global_delete_fndecl): Define it.
+ (init_decl_processing): Set it.
+ * init.c (build_builtin_delete_call): Use it.
+ * tree.c (mapcar): Recursively call mapcar for the type of EXPR
+ nodes.
+
+1998-11-18 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (cplus_expand_expr_stmt): Always complain about unresolved
+ type.
+
+ * tree.c (lvalue_p_1): An INDIRECT_REF to a function is an lvalue.
+ * call.c (build_object_call): Also support references to functions.
+ * typeck.c (convert_for_initialization): Don't decay a function
+ if the target is a reference to function.
+
+ * search.c (add_conversions): Get all the overloads from a class.
+
+ * decl.c (grok_ctor_properties): Complain about any constructor
+ that will take a single arg of the class type by value.
+
+ * typeck2.c (build_functional_cast): Can't create objects of
+ abstract classes this way.
+ * cvt.c (ocp_convert): Likewise.
+
+ * decl.c (grokfndecl): Member functions of local classes are not
+ public.
+
+1998-11-18 Mark Mitchell <mark@markmitchell.com>
+
+ * Make-lang.in (cc1plus): Add dependency on hash.o.
+
+1998-11-18 Jason Merrill <jason@yorick.cygnus.com>
+
+ * search.c (get_abstract_virtuals): Complain about virtuals with
+ no final overrider.
+ * typeck2.c (abstract_virtuals_error): Remove handling for virtuals
+ with no final overrider.
+ * class.c (override_one_vtable): Don't set DECL_ABSTRACT_VIRTUAL_P
+ on virtuals with no final overrider.
+
+ * lex.c (reinit_parse_for_block): Add a space after the initial ':'.
+
+ * class.c (finish_struct_1): Don't remove zero-width bit-fields until
+ after layout_type.
+
+ * friend.c (do_friend): Don't set_mangled_name_for_decl.
+
+ * class.c (finish_struct_anon): Complain about non-fields.
+ * decl2.c (build_anon_union_vars): Likewise.
+
+ * decl.c (grokdeclarator): Normal data members can't have the same
+ name as the class, either.
+ * class.c (finish_struct_anon): Neither can members of an
+ anonymous union.
+
+1998-11-17 Mark Mitchell <mark@markmitchell.com>
+
+ * cp-tree.h (TYPE_ALIAS_SET): Document language-dependent uses.
+ (TYPE_BINFO): Likewise.
+ (IS_AGGR_TYPE): Tweak.
+ (SET_IS_AGGR_TYPE): New macro.
+ (CLASS_TYPE_P): Tweak.
+ (lang_type): Group mark bitfields together. Remove linenum.
+ (CLASSTYPE_SOURCE_LINE): Remove macro.
+ (CLASSTYPE_MARKED_N): New macro.
+ (SET_CLASSTYPE_MARKED_N): Likewise.
+ (CLEAR_CLASSTYPE_MARKED_N): Likewise.
+ (CLASS_TYPE_MARKED_*): Use them.
+ (SET_CLASSTYPE_MARKED_*): Likewise.
+ (CLEAR_CLASSTYPE_MARKED_*): Likewise.
+ (TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO): Likewise.
+ (TYPE_TEMPLATE_INFO): Handle TEMPLATE_TEMPLATE_PARMs as well.
+ (TYPENAME_TYPE_FULLNAME): Use TYPE_BINFO rather than CLASSTYPE_SIZE.
+ * class.c (class_cache_obstack): New variable.
+ (class_cache_firstobj): Likewise.
+ (finish_struct): Don't set CLASSTYPE_SOURCE_LINE.
+ (pushclass): Free the cache, when appropriate.
+ (popclass): Tidy.
+ (maybe_push_cache_obstack): Use class_cache_obstack.
+ * decl.c (include hash.h).
+ (typename_hash): New function.
+ (typename_compare): Likewise.
+ (build_typename_type): Check the hash table to avoid creating
+ duplicates.
+ (build_ptrmemfunc_type): Use SET_IS_AGGR_TYPE.
+ (grokdeclarator): Use CLASS_TYPE_P.
+ (xref_basetypes): Likewise.
+ (start_function): Likewise. Don't put current_class_ref on the
+ permanent obstack.
+ * error.c (dump_type_real): Use TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO
+ and TYPE_TI_ARGS.
+ * lex.c (note_got_semicolon): Use CLASS_TYPE_P.
+ (make_lang_type): Don't create TYPE_LANG_SPECIFIC and associated
+ fields for types other than class types. Do clear TYPE_ALIAS_SET
+ for types other than class types, though.
+ * method.c (build_overload_identifier): Use CLASS_TYPE_P and
+ TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO.
+ * pt.c (process_template_parm): Don't set
+ CLASSTYPE_GOT_SEMICOLON.
+ (lookup_template_class) Use TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO.
+ Coerce arguments on the momentary obstack.
+ (for_each_template_parm): Use TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO.
+ (instantiate_class_template): Calculate template arguments on the
+ momentary obstack. Tidy.
+ (tsubst_template_arg_vector): Use make_temp_vec.
+ (tsubst_aggr_type): Put template arguments on the momentary
+ obstack.
+ (tsubst_decl): Likewise.
+ (tsubst): Copy the array bounds index to the permanent obstack
+ before building index types. Use new macros.
+ (unify): Use new macros.
+ (do_type_instantiation): Likewise.
+ * search.c (lookup_fnfields_1): Use new macros.
+ (dfs_pushdecls): Build envelopes on the cache obstack.
+ (dfs_compress_decls): Use new macros.
+ (push_class_decls): Build on the cache obstack.
+ * semantics.c (finish_typeof): Don't set CLASSTYPE_GOT_SEMICOLON.
+ * sign.c (build_signature_pointer_or_reference_type): Use
+ SET_IS_AGGR_TYPE.
+ * tree.c (make_binfo): Check CLASS_TYPE_P.
+ (copy_template_template_parm): Adjust.
+ (make_temp_vec): Use push_expresion_obstack.
+ * typeck.c (complete_type): Use new macros.
+ (comptypes): Likewise.
+
+1998-11-17 Jason Merrill <jason@yorick.cygnus.com>
+
+ * pt.c (tsubst): Add diagnostics for invalid array, reference
+ and pointer to member types.
+
+1998-11-16 Jason Merrill <jason@yorick.cygnus.com>
+
+ * typeck2.c (my_friendly_abort): Don't fatal twice in a row.
+
+ * typeck.c (c_expand_start_case): Use build_expr_type_conversion.
+ Simplify.
+
+ * parse.y (structsp): Fix cut-and-paste error.
+
+ * init.c (build_new): Complain about non-integral size.
+
+ * parse.y (unary_expr): Complain about defining types in sizeof.
+
+ * typeck.c (expr_sizeof): Complain about sizeof an overloaded fn.
+
+ * rtti.c (build_x_typeid): Complain about typeid without
+ including <typeinfo>.
+ (get_typeid): Likewise. Complain about typeid of incomplete type.
+ (get_tinfo_fn_dynamic): Likewise.
+ (get_typeid_1): Not static anymore.
+ * except.c (build_eh_type_type): Use get_typeid_1.
+
+ * rtti.c (build_dynamic_cast_1): Give errors for dynamic_cast to
+ ambiguous or private bases. Fix warning for reference cast.
+
+1998-11-16 Mark Mitchell <mark@markmitchell.com>
+
+ * cp-tree.h (DECL_TEMPLATE_INSTANTIATED): New macro.
+ * decl.c (duplicate_decls): Remove special-case code to deal with
+ template friends, and just do the obvious thing.
+ * pt.c (register_specialization): Tweak for clarity, and also to
+ clear DECL_INITIAL for an instantiation before it is merged with a
+ specialization.
+ (check_explicit_specialization): Fix indentation.
+ (tsubst_friend_function): Handle both definitions in friend
+ declaration and outside friend declarations.
+ (tsubst_decl): Don't clear DECL_INITIAL for an instantiation.
+ (regenerate_decl_from_template): Tweak accordingly.
+ (instantiate_decl): Likewise.
+
+1998-11-16 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (cplus_expand_expr_stmt): Promote warning about naked
+ member function reference to error.
+ * cvt.c (ocp_convert): Complain about converting an overloaded
+ function to void.
+
+ * init.c (build_offset_ref): Just return a lone static member
+ function.
+
+ * decl.c (cp_finish_decl): Only complain about real CONSTRUCTORs,
+ not internal ones.
+
+ * typeck.c (build_binary_op_nodefault): Improve error handling.
+
+ * decl.c (grokfndecl): Complain about making 'main' a template.
+
+ * typeck.c (string_conv_p): Don't convert from wchar_t[] to char*.
+
+ * call.c (build_method_call): Handle a BIT_NOT_EXPR around a
+ TYPE_DECL in a template.
+
+1998-11-15 Jason Merrill <jason@yorick.cygnus.com>
+
+ * typeck2.c (my_friendly_abort): Add URL in the other case, too.
+
+ * decl.c (struct cp_function): Add named_label_uses.
+ (push_cp_function_context): Save it.
+ (pop_cp_function_context): Restore it.
+ (define_label): Also complain about jumping into the scope of
+ non-POD objects that don't have constructors.
+ * tree.c (pod_type_p): New fn.
+
+ * pt.c (instantiate_class_template): Clear TYPE_BEING_DEFINED sooner.
+ * rtti.c (synthesize_tinfo_fn): Call import_export_decl here.
+ (get_tinfo_fn): Not here.
+ * repo.c (repo_get_id): Abort if we get called for an incomplete
+ type.
+
+1998-11-13 Mark Mitchell <mark@markmitchell.com>
+
+ * except.c (expand_throw): Make sure first argument to
+ __cp_push_exception is of type `void*' to avoid spurious error
+ messages.
+
+1998-11-11 Jason Merrill <jason@yorick.cygnus.com>
+
+ * pt.c (try_one_overload): Take orig_targs again. Only check for
+ mismatches against them; we don't care what a previous call found.
+ (resolve_overloaded_unification): Adjust.
+
+ * search.c (lookup_field): Don't return anything for a non-type
+ field from a dependent type.
+ * decl.c (grokdeclarator): Resolve SCOPE_REFs of the current class
+ in an array declarator.
+ (start_decl): Push into the class before looking for the field.
+
+1998-11-08 Mark Mitchell <mark@markmitchell.com>
+
+ * method.c (build_overload_value): Handle REFERENCE_TYPE.
+
+1998-11-08 Martin von Löwis <loewis@informatik.hu-berlin.de>
+
+ * decl.c (grokdeclarator): Allow namespace-scoped members if they
+ are friends.
+
+1998-11-08 Jason Merrill <jason@yorick.cygnus.com>
+
+ * pt.c (tsubst_decl): Don't mess with the global value of an
+ un-mangled DECL_ASSEMBLER_NAME.
+
+1998-11-03 Christopher Faylor <cgf@cygnus.com>
+
+ * decl.c (init_decl_processing): Remove CYGWIN conditional
+ since CYGWIN is now able to deal with trapping signals.
+
+Sat Nov 7 15:48:02 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * cp-tree.h: Don't include gansidecl.h.
+ * exception.cc: Include gansidecl.h (since we don't include config.h)
+ * g++spec.c: Don't include gansidecl.h.
+
+1998-11-06 Mark Mitchell <mark@markmitchell.com>
+
+ * cp-tree.h (lang_decl_flags): Add defined_in_class. Decrease
+ size of dummy.
+ (DECL_DEFINED_IN_CLASS_P): New macro.
+ (TEMPLATE_PARMS_FOR_INLINE): Document.
+ (check_static_variable_definition): New function.
+ * decl.c (cp_finish_decl): Set DECL_DEFINED_IN_CLASS_P, if
+ appropriate.
+ (check_static_variable_definition): Split out from ...
+ (grokdeclarator): Here.
+ * pt.c (check_default_tmpl_args): New function, split out from ...
+ (push_template_decl_real): Here.
+ (instantiate_template): Fix comment.
+
+1998-11-04 Mark Mitchell <mark@markmitchell.com>
+
+ * cp-tree.h (CP_TYPE_CONST_P): Make {0,1}-valued.
+ (CP_TYPE_VOLATILE_P): Likewise.
+ (CP_TYPE_RESTRICT_P): Likewise.
+
+1998-11-03 Mark Mitchell <mark@markmitchell.com>
+
+ * pt.c (tsubst): Use build_index_type, not build_index_2_type.
+
+1998-11-02 Jason Merrill <jason@yorick.cygnus.com>
+
+ * class.c (instantiate_type): Be more helpful.
+
+ * decl2.c (import_export_decl): Call import_export_class.
+
+ * cp-tree.h (EMPTY_CONSTRUCTOR_P): Check !TREE_HAS_CONSTRUCTOR.
+ * decl2.c (build_expr_from_tree): Propagate TREE_HAS_CONSTRUCTOR.
+ * pt.c (tsubst_copy): Likewise.
+
+1998-11-02 Mark Mitchell <mark@markmitchell.com>
+
+ * init.c (expand_vec_init): Fix off-by-one error.
+
+1998-11-02 Alexandre Oliva <oliva@dcc.unicamp.br>
+
+ * parse.y (apparent_template_type): new type
+ (named_complex_class_head_sans_basetype): use it
+ * Makefile.in (CONFLICTS): one new conflict
+ * parse.c: Regenerated
+
+1998-11-01 Mark Mitchell <mark@markmitchell.com>
+
+ * cp-tree.h (COMPARE_STRICT): New macro.
+ (COMPARE_BASE): Likewise.
+ (COMPARE_RELAXED): Likewise.
+ (COMPARE_REDECLARATION): Likewise.
+ (same_type_p): Likewise.
+ (same_or_base_type_p): Likewise.
+ * call.c (standard_conversion): Use them, in place of comptypes
+ with numeric arguments.
+ (reference_binding): Likewise.
+ (convert_like): Likewise.
+ (build_over_call): Likewise.
+ (is_subseq): Likewise.
+ (is_properly_derived_from): Likewise.
+ (compare_ics): Likewise.
+ (joust): Likewise.
+ * class.c (delete_duplicate_fields_1): Likewise.
+ (resolves_to_fixed_type_p): Likewise.
+ (instantiate_type): Likewise. Remove #if 0'd code.
+ * decl.c (decls_match): Likewise. Use COMPARE_REDECLARATION here.
+ (pushdecl): Likewise.
+ (lookup_name_real): Likewise.
+ (grokdeclarator): Likewise. Check for illegal array declarations.
+ (grokparms): Likewise.
+ (grok_op_properties): Likewise.
+ * decl2.c (check_classfn): Likewise.
+ * friend.c (is_friend): Likewise.
+ (make_friend_class): Likewise.
+ * init.c (expand_aggr_init): Likewise.
+ (expand_vec_init): Likewise.
+ * pt.c (is_member_template_class): Remove declaration.
+ (is_specialization_of): Use COMPARE_* and new macros.
+ (comp_template_parms): Likewise.
+ (convert_nontype_argument): Likewise.
+ (coerce_template_template_parms): Likewise.
+ (template_args_equal): Likewise.
+ (lookup_template_class): Likewise.
+ (type_unification_real): Likewise.
+ (unify): Likewise.
+ (get_bindings_real): Likewise.
+ * search.c (covariant_return_p): Likewise.
+ (get_matching_virtual): Likewise.
+ * sig.c (match_method_types): Likewise.
+ * tree.c (vec_binfo_member): Likewise.
+ (cp_tree_equal): Likewise.
+ * typeck.c (common_type): Likewise.
+ (comp_array_types): Likewise. Get issues involving unknown array
+ bounds right.
+ (comptypes): Update comments. Use new flags.
+ (comp_target_types): Use new macros.
+ (compparms): Likewise.
+ (comp_target_parms): Likewise.
+ (string_conv_p): Likewise.
+ (build_component_ref): Likewise.
+ (build_indirect_ref): Likewise.
+ (build_conditional_expr): Likewise.
+ (build_static_cast): Likewise.
+ (build_reinterpret_cast): Likewise.
+ (build_const_cast): Likewise.
+ (build_modify_expr): Likewise.
+ (convert_for_assignment): Likewise.
+ (comp_ptr_ttypes_real): Likewise.
+ (ptr_reasonably_similar): Likewise.
+ (comp_ptr_ttypes_const): Likewise.
+
+1998-10-31 Jason Merrill <jason@yorick.cygnus.com>
+
+ * rtti.c (build_dynamic_cast_1): Fix cut-and-paste error.
+
+1998-10-30 Mark Mitchell <mark@markmitchell.com>
+
+ * decl2.c (delete_sanity): Pass integer_zero_node, not
+ integer_two_node, to build_vec_delete.
+ * init.c (build_array_eh_cleanup): Remove.
+ (expand_vec_init_try_block): New function.
+ (expand_vec_init_catch_clause): Likewise.
+ (build_vec_delete_1): Don't deal with case that auto_delete_vec
+ might be integer_two_node anymore.
+ (expand_vec_init): Rework for initialization-correctness and
+ exception-correctness.
+ * typeck2.c (process_init_constructor): Make mutual exclusivity
+ of cases more obvious.
+
+1998-10-29 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (lookup_name_real): OK, only warn if not lexing.
+ Simplify suggested fix.
+
+ * cp-tree.h (IDENTIFIER_MARKED): New macro.
+ * search.c (lookup_conversions): Use breadth_first_search.
+ (add_conversions): Avoid adding two conversions to the same type.
+ (breadth_first_search): Work with base binfos, rather
+ than binfos and base indices.
+ (get_virtual_destructor): Adjust.
+ (tree_has_any_destructor_p): Adjust.
+ (get_matching_virtual): Adjust.
+
+ * pt.c (push_template_decl_real): Generalize check for incorrect
+ number of template parms.
+ (is_member_template_class): #if 0.
+
+1998-10-29 Richard Henderson <rth@cygnus.com>
+
+ * Makefile.in (cc1plus): Put CXX_OBJS, and thence @extra_cxx_objs@,
+ last.
+
+1998-10-28 Zack Weinberg <zack@rabi.phys.columbia.edu>
+
+ * lex.c: Call check_newline from lang_init always. After
+ calling cpp_start_read, set yy_cur and yy_lim to read from the
+ cpplib token buffer.
+
+1998-10-28 Jason Merrill <jason@yorick.cygnus.com>
+
+ * class.c (instantiate_type): Don't consider templates for a normal
+ match.
+
+ * class.c (finish_struct_1): Don't complain about non-copy
+ assignment ops in union members.
+
+ * class.c (build_vtable): Don't pass at_eof to import_export_vtable.
+ (prepare_fresh_vtable): Likewise.
+ (finish_struct_1): Don't call import_export_class.
+ * decl2.c (finish_vtable_vardecl): Do import/export stuff.
+ (finish_prevtable_vardecl): Lose.
+ (finish_file): Don't call it.
+ * pt.c (instantiate_class_template): Likewise.
+ * cp-tree.h: Remove it.
+
+ * init.c (build_delete): Reset TYPE_HAS_DESTRUCTOR here.
+ * decl.c (finish_function): Not here.
+ (start_function): Do set DECL_INITIAL.
+
+ * pt.c (push_template_decl_real): Complain about default template
+ args for enclosing classes.
+
+ * call.c (add_function_candidate): Treat conversion functions
+ as coming from the argument's class.
+ * cp-tree.h (DECL_CONV_FN_P): New fn.
+ (DECL_DESTRUCTOR_P): Also check DECL_LANGUAGE.
+ * class.c (add_method): Use DECL_CONV_FN_P.
+ * decl2.c (check_classfn): Likewise.
+ * error.c (dump_function_name): Likewise.
+ (dump_function_decl): Likewise.
+ * pt.c (fn_type_unification): Likewise.
+ * search.c (add_conversions): Likewise.
+
+1998-10-27 Jason Merrill <jason@yorick.cygnus.com>
+
+ * lex.c (do_identifier): Also generate LOOKUP_EXPR for RESULT_DECL.
+ * method.c (hack_identifier): Also check for using RESULT_DECL
+ from outer context.
+
+1998-10-27 Mark Mitchell <mark@markmitchell.com>
+
+ * decl.c (grokdeclarator): Use type_quals, rather than constp,
+ consistently.
+
+1998-10-27 Jason Merrill <jason@yorick.cygnus.com>
+
+ * call.c (standard_conversion): instantiate_type here.
+ (reference_binding): And here.
+ (implicit_conversion): Not here.
+ (build_op_delete_call): No need to cons up an OVERLOAD.
+ * cvt.c (cp_convert_to_pointer): instantiate_type here.
+ (convert_to_reference): And here.
+ * decl.c (grok_reference_init): Not here.
+ (grokparms): Or here.
+ * typeck2.c (digest_init): Or here.
+ * typeck.c (decay_conversion): Take the address of overloaded
+ functions, too.
+ (require_instantiated_type): Lose.
+ (convert_arguments): Don't handle unknown types here.
+ (build_c_cast): Likewise.
+ (build_binary_op): Gut.
+ (build_conditional_expr): Don't require_instantiated_type.
+ (build_modify_expr): Likewise.
+ (build_static_cast): Don't instantiate_type.
+ (build_reinterpret_cast): Likewise.
+ (build_const_cast): Likewise.
+ (convert_for_initialization): Likewise.
+ (build_ptrmemfunc): Use type_unknown_p.
+ (convert_for_assignment): Also do default_conversion on overloaded
+ functions. Hand them off to ocp_convert.
+
+1998-10-26 Mark Mitchell <mark@markmitchell.com>
+
+ * error.c (dump_decl): Deal with TEMPLATE_DECLs that are
+ VAR_DECLs. Handle vtables whose DECL_CONTEXT is not a type.
+
+ * class.c (finish_struct_1): Use build_cplus_array_type to build
+ array types.
+ * decl.c (init_decl_processing): Likewise.
+ * except.c (expand_end_eh_spec): Likewise.
+ * search.c (expand_upcast_fixups): Simplify very slightly.
+
+1998-10-26 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (grokdeclarator): Complain about a variable using
+ constructor syntax coming back null from start_decl.
+
+ * friend.c (make_friend_class): Complain about trying to make
+ a non-class type a friend.
+
+ * decl.c (grokfndecl): Set DECL_INITIAL for a defn here.
+ (start_function): Not here.
+
+1998-10-26 Brendan Kehoe <brendan@cygnus.com>
+
+ * decl.c (grokdeclarator): Disallow `explicit' in a friend declaration.
+
+1998-10-26 Jason Merrill <jason@yorick.cygnus.com>
+
+ * typeck2.c (process_init_constructor): Only skip anonymous fields
+ if they are bitfields.
+
+ * cp-tree.def (TYPEOF_TYPE): New code.
+ * error.c (dump_type_real): Handle it.
+ * pt.c (tsubst): Likewise.
+ * tree.c (search_tree): Likewise.
+ * semantics.c (finish_typeof): New fn.
+ * parse.y (typespec): Use it.
+ * cp-tree.h: Declare it.
+
+1998-10-26 Manfred Hollstein <manfred@s-direktnet.de>
+
+ * cp-tree.h (FORMAT_VBASE_NAME): Make definition unconditional.
+
+1998-10-26 Jason Merrill <jason@yorick.cygnus.com>
+
+ * typeck.c (convert_arguments): Don't handle pmf references
+ specially.
+
+ * init.c (build_member_call): Don't try to convert to the base type
+ if it's ambiguous or pedantic.
+
+ * typeck2.c (check_for_new_type): Only depend on pedantic for
+ C-style casts.
+
+1998-10-25 Mark Mitchell <mark@markmitchell.com>
+
+ * decl.c (grokdeclarator): Set DECL_NONCONVERTING_P for all
+ non-converting constructors.
+
+1998-10-24 Martin von Löwis <loewis@informatik.hu-berlin.de>
+
+ * gxxint.texi: Correct documentation for n, N, Q, and B.
+
+1998-10-23 Martin von Löwis <loewis@informatik.hu-berlin.de>
+
+ * parse.y (condition): Convert VAR_DECL from reference to indirect
+ reference.
+
+1998-10-23 Andrew MacLeod <amacleod@cygnus.com>
+
+ * exception.cc (__cp_pop_exception): Free the original exception
+ value, not the potentially coerced one.
+
+1998-10-23 Mark Mitchell <mark@markmitchell.com>
+
+ * Makefile.in (hash.h): Run gperf when necessary.
+
+ * cp-tree.h (CP_TYPE_READONLY): Remove.
+ (CP_TYPE_VOLATILE): Likewise.
+ (CP_TYPE_QUALS): New macro.
+ (CP_TYPE_CONST_P): Likewise.
+ (CP_TYPE_VOLATILE_P): Likewise.
+ (CP_TYPE_RESTRICT_P): Likewise.
+ (CP_TYPE_CONST_NON_VOLATILE_P): Likewise.
+ (cp_build_type_variant): Rename to ...
+ (cp_build_qualified_type): New function.
+ (c_apply_type_quals_to_decl): Declare.
+ (SIGNATURE_POINTER_NAME_FORMAT): Modify to allow `restrict'.
+ (SIGNATURE_REFERENCE_NAME_FORMAT): Likewise.
+ (cp_type_qual_from_rid): New function.
+ (compparms): Remove unused parameter. All callers changed.
+ (cp_type_quals): New function.
+ (at_least_as_qualified_p): Likewise.
+ (more_qualified_p): Likewise.
+
+ * call.c (standard_conversion): Replace calls to
+ cp_build_type_variant with cp_build_qualified_type. Use
+ CP_TYPE_QUALS to get qualifiers and at_least_as_qualified_p to
+ compare them. Use CP_TYPE_* macros to check qualifiers.
+ (reference_binding): Likewise.
+ (implicit_conversion): Likewise.
+ (add_builtin_candidates): Likewise.
+ (build_over_call): Likewise.
+ * class.c (overrides): Compare all qualifiers, not just `const',
+ on method declarations.
+ * cvt.c (convert_to_reference): More CP_TYPE_QUALS conversion, etc.
+ (convert_pointer_to_real): Likewise.
+ (type_promotes_to): Likewise.
+ * decl.c (check_for_uninitialized_const_var): New function.
+ (init_decl_processing): More CP_TYPE_QUALS conversion, etc.
+ (cp_finish_decl): Use check_for_uninitialized_const_var.
+ (grokdeclarator): More CP_TYPE_QUALS conversion, etc. Update to
+ handle `restrict'.
+ (grok_ctor_properties): Likewise.
+ (grok_op_properties): Likewise.
+ (start_function): Likewise.
+ (rever_static_member_fn): Likewise.
+ * decl2.c (grok_method_quals): Likewise.
+ (grokfield): Likewise.
+ * error.c (dump_readonly_or_volatile): Rename to ...
+ (dump_qualifiers): New function. Handle `restrict'.
+ (dump_type_real): Use it.
+ (dump_aggr_type): Likewise.
+ (dump_type_prefix): Likewise.
+ (dump_type_suffix): Likewise.
+ (dump_function_decl): Likewise.
+ (cv_as_string): Likewise.
+ * gxx.gperf: Add __restrict and __restrict__.
+ * gxxint.texi: Document `u' as used for `__restrict', and a few
+ other previously undocumented codes.
+ * hash.h: Regenerated.
+ * init.c (expand_aggr_init): More CP_TYPE_QUALS conversion, etc.
+ (build_member_call): Likewise.
+ (build_new_1): Likewise.
+ * lex.c (init_parse): Add entry for RID_RESTRICT.
+ (cons_up_default_function): More CP_TYPE_QUALS conversion, etc.
+ (cp_type_qual_from_rid): Define.
+ * lex.h (enum rid): Add RID_RESTRICT.
+ * method.c (process_modifiers): Deal with `restrict'.
+ * parse.y (primary): More CP_TYPE_QUALS conversion, etc.
+ * parse.c: Regenerated.
+ * pt.c (convert_nontype_argument): More CP_TYPE_QUALS conversion, etc.
+ (tsubst_aggr_type): Likewise.
+ (tsubst): Likewise.
+ (check_cv_quals_for_unify): Likewise.
+ (unify): Likewise.
+ * rtti.c (init_rtti_processing): Likewise.
+ (build_headof): Likewise.
+ (get_tinfo_var): Likewise.
+ (buidl_dynamic_cast_1): Likewise. Fix `volatile' handling.
+ (expand_class_desc): Likewise.
+ (expand_attr_desc): Likewise.
+ (synthesize_tinfo_fn): Likewise.
+ * search.c (covariant_return_p): Likewise. Fix `volatile' handling.
+ (get_matching_virtual): Likewise.
+ (expand_upcast_fixups): Likewise.
+ * sig.c (build_signature_pointer_or_reference_name): Take
+ type_quals, not constp and volatilep.
+ (build_signature_pointer_or_reference_type): Likewise.
+ (match_method_types): More CP_TYPE_QUALS conversion, etc.
+ (build_signature_pointer_constructor): Likewise.
+ (build_signature_method_call): Likewise.
+ * tree.c (build_cplus_array_type): Likewise.
+ (cp_build_type_variant): Rename to ...
+ (cp_build_qualified_type): New function. Deal with `__restrict'.
+ (canonical_type_variant): More CP_TYPE_QUALS conversion, etc.
+ (build_exception_variant): Likewise.
+ (mapcar): Likewise.
+ * typeck.c (qualif_type): Likewise.
+ (common_type): Likewise.
+ (comptypes): Likewise.
+ (comp_cv_target_types): Likewise.
+ (at_least_as_qualified_p): Define.
+ (more_qualified_p): Likewise.
+ (comp_cv_qualification): More CP_TYPE_QUALS conversion, etc.
+ (compparms): Likewise.
+ (inline_conversion): Likewise.
+ (string_conv_p): Likewise.
+ (build_component_ref): Likewise.
+ (build_indirect_ref): Likewise.
+ (build_array_ref): Likewise.
+ (build_unary_op): Likewise.
+ (build_conditional_expr): Likewise.
+ (build_static_cast): Likewise.
+ (build_c_cast): Likewise.
+ (build_modify_expr): Likewise.
+ (convert_For_assignment): Likewise.
+ (comp_ptr_ttypes_real): Likewise.
+ (cp_type_quals): New function.
+
+1998-10-23 Jason Merrill <jason@yorick.cygnus.com>
+
+ * cp-tree.h (CP_TYPE_READONLY): New macro to handle arrays.
+ (CP_TYPE_VOLATILE): Likewise.
+ * decl.c (grokdeclarator): Use them.
+ * tree.c (canonical_type_variant): Likewise.
+
+1998-10-22 Martin von Löwis <loewis@informatik.hu-berlin.de>
+
+ * parse.y (named_class_head): Push into class while parsing the
+ base class list.
+ * decl2.c (push_scope, pop_scope): New functions.
+ * cp-tree.h: Declare them.
+ * init.c (build_new_1): Delay cleanup until end of full expression.
+
+1998-10-21 Jason Merrill <jason@yorick.cygnus.com>
+
+ * typeck.c (build_component_ref): Use of a type here is an error.
+
+1998-10-19 Jason Merrill <jason@yorick.cygnus.com>
+
+ Revamp references to member functions.
+ * method.c (hack_identifier): Call build_component_ref for a
+ reference to a member function.
+ * typeck.c (build_component_ref): Only return a single function
+ if it's static. Otherwise, return a COMPONENT_REF.
+ (build_x_function_call): Handle a COMPONENT_REF.
+ (build_unary_op): Handle all unknown-type things.
+ * decl2.c (arg_assoc): Handle COMPONENT_REF.
+ * class.c (instantiate_type): Complain if the function we get is a
+ nonstatic member function. Remove code for finding "compatible"
+ functions.
+ * pt.c (tsubst_copy): Handle NOP_EXPR.
+ * tree.c (build_dummy_object): New fn.
+ (maybe_dummy_object): New fn.
+ (is_dummy_object): New fn.
+ * cp-tree.h: Declare them.
+ * cvt.c (cp_convert_to_pointer): Use maybe_dummy_object.
+ * error.c (dump_expr, case OFFSET_REF): Use is_dummy_object.
+ * init.c (build_member_call): Use maybe_dummy_object and
+ is_dummy_object.
+ (build_offset_ref): Use maybe_dummy_object.
+ (resolve_offset_ref): Use is_dummy_object.
+ * typeck.c (build_x_function_call): Call build_dummy_object.
+ (unary_complex_lvalue): Call is_dummy_object.
+
+ * typeck.c (build_component_addr): Make sure field is a field.
+
+ * call.c (build_new_op): Delete obsolete code.
+
+ * pt.c (tsubst, TEMPLATE*PARM*): Abort if we don't have any args.
+
+1998-10-18 Martin von Löwis <loewis@informatik.hu-berlin.de>
+
+ * decl2.c (validate_nonmember_using_decl): Fix using-directives of
+ std if std is ignored.
+
+1998-10-18 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (grokvardecl): Fix thinko.
+
+ * decl.c (grokdeclarator): Embedded attrs bind to the right,
+ not the left.
+
+ * parse.y (fn.def2): Fix 'attrs' format.
+
+1998-10-18 Alastair J. Houghton <ajh8@doc.ic.ac.uk>
+
+ * Makefile.in (CONFLICTS): Update.
+ * parse.y (expr_or_declarator_intern): New rule.
+ (expr_or_declarator, direct_notype_declarator, primary,
+ functional_cast): Use it.
+ (notype_declarator_intern): New rule.
+ (notype_declarator, complex_notype_declarator): Use it.
+
+1998-10-17 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (grokfndecl): Set DECL_CONTEXT to namespace if appropriate.
+ (grokvardecl): Likewise.
+
+Sat Oct 17 23:27:20 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * class.c (make_method_vec): Cast 1st argument of `bzero' to (PTR).
+ (add_method): Likewise for arguments 1 & 2 of `bcopy'.
+
+ * decl.c (signal_catch): Mark with ATTRIBUTE_NORETURN.
+
+ * pt.c (process_partial_specialization): Cast 1st argument of
+ `bzero' to (PTR).
+
+ * tree.c (build_base_fields): Cast `base_align' to (int) when
+ comparing against one.
+
+1998-10-16 Mark Mitchell <mark@markmitchell.com>
+
+ * decl.c (lookup_name_real): Handle template parameters for member
+ templates where said parameters have the same name as the
+ surrounding class.
+
+ * decl.c (expand_static_init): Build cleanups before entering the
+ anonymous function used to do them to avoid access-checking
+ confusion.
+
+ * decl.c (grokfndecl): Add back call to cplus_decl_attributes
+ accidentally removed by previous change, and make DECL_RTL here.
+ * class.c (add_method): Don't make DECL_RTL here.
+
+ * pt.c (for_each_template_parm): Don't examine uninstantiated
+ default arguments.
+
+1998-10-16 Dave Brolley <brolley@cygnus.com>
+
+ * lex.c (real_yylex): Fix unaligned access of wchar_t.
+
+1998-10-16 Mark Mitchell <mark@markmitchell.com>
+
+ * class.c (add_method): Fix documentation to reflect previous
+ changes. Check for duplicate method declarations here.
+ * decl.c (decls_match): Handle FUNCTION_DECL vs TEMPLATE_DECL
+ correctly; such things never match.
+ (grokfndecl): Don't look for duplicate methods here.
+ * decl2.c (check_classfn): Don't assume names are mangled.
+ Don't add bogus member function declarations to a class before the
+ class type is complete.
+ (grokfield): Reformat error message.
+ * method.c (set_mangled_name_for_decl): Don't mangle names while
+ procesing_template_decl.
+
+1998-10-16 Jason Merrill <jason@yorick.cygnus.com>
+
+ * typeck.c (build_indirect_ref): Complain about a pointer to data
+ member, too.
+ * typeck2.c (build_m_component_ref): Don't indirect a pointer to
+ data member.
+ * init.c (resolve_offset_ref): Don't undo the above.
+
+ * cp-tree.h (DECL_C_BIT_FIELD, SET_DECL_C_BIT_FIELD): New macros.
+ (struct lang_decl_flags): Add `bitfield'.
+ * class.c (finish_struct_1): Use DECL_C_BIT_FIELD instead of
+ DECL_BIT_FIELD.
+ * decl2.c (grokbitfield, grok_alignof): Likewise.
+ * init.c (build_offset_ref): Likewise.
+ * typeck.c (build_component_addr, expr_sizeof): Likewise.
+ * cvt.c (build_up_reference): Don't crash if taking the address
+ returns error_mark_node.
+
+ * decl.c (grokfndecl): Also check ctype when checking for ::main().
+
+1998-10-15 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (grokfndecl): ::main and __builtin_* get C linkage.
+ Do mangling here.
+ (grokdeclarator): Instead of here.
+ * friend.c (do_friend): Lose special handling of ::main and
+ __builtin_*.
+ * cp-tree.h (DECL_MAIN_P): Check for C linkage.
+
+ * spew.c (yylex): Clear looking_for_typename if we got
+ 'enum { ... };'.
+
+1998-10-15 Mark Mitchell <mark@markmitchell.com>
+
+ * class.c (maybe_warn_about_overly_private_class): Improve error
+ messages for class with only private constructors.
+
+ * cp-tree.def (TYPENAME_TYPE): Add to documentation.
+ * cp-tree.h (TYPENAME_TYPE_FULLNAME): Document.
+ (build_typename_type): New function.
+ * decl.c (build_typename_type): Broken out from ...
+ (make_typename_type): Use it.
+ * search.c (lookup_field): Likewise.
+
+1998-10-14 Benjamin Kosnik <bkoz@rhino.cygnus.com>
+
+ * pt.c (convert_nontype_argument): Check against type_referred_to.
+ * decl.c (grokvardecl): Check for declarator name before building
+ DECL_ASSEMBLER_NAME.
+
+1998-10-14 Mark Mitchell <mark@markmitchell.com>
+
+ * pt.c (lookup_template_class): Add comment.
+ (instantiate_class_template): Don't mark the _TYPE node for
+ member class templates as an instantiation.
+
+1998-10-14 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (grokfndecl): Fix my thinko.
+
+1998-10-13 Jason Merrill <jason@yorick.cygnus.com>
+
+ * tinfo2.cc (fast_compare): Remove.
+ (before): Just use strcmp.
+ * tinfo.cc (operator==): Just use strcmp.
+
+1998-10-13 Klaus-Georg Adams <Klaus-Georg.Adams@chemie.uni-karlsruhe.de>
+
+ * decl.c (grokfndecl): Don't check for linkage in `extern "C"'
+ declarations.
+
+1998-10-13 Mark Mitchell <mark@markmitchell.com>
+
+ * cp-tree.h (specializations_of_same_template_p): Remove.
+ * search.c (get_template_base): Don't use it.
+ (get_template_base_recursive): Likewise.
+ * pt.c (specializations_of_same_template_p): Remove.
+ (unify): Don't use it.
+ (lookup_template_class): Find the correct parent when setting
+ CLASSTYPE_TI_TEMPLATE.
+
+1998-10-12 Jason Merrill <jason@yorick.cygnus.com>
+
+ * tinfo.cc (operator==): Always compare names.
+
+1998-10-12 Herman ten Brugge <Haj.Ten.Brugge@net.HCC.nl>
+
+ * decl.c (start_function): Fix cut-and-paste error.
+
+1998-10-12 Jason Merrill <jason@yorick.cygnus.com>
+
+ * inc/typeinfo: Add #pragma interface.
+ (operator!=): Just call operator==.
+ * tinfo.cc: Add #pragma implementation.
+ (operator==): Move from inc/typeinfo and tinfo2.cc.
+ Check __COMMON_UNRELIABLE instead of _WIN32.
+
+ * typeck2.c (my_friendly_abort): Add URL.
+
+1998-10-12 Alastair J. Houghton <ajh8@doc.ic.ac.uk>
+
+ * decl.c (start_method): Added extra parameter for attributes.
+ * cp-tree.h (start_method): Update prototype.
+ * parse.y (fn.def2): Update start_method parameter list.
+
+1998-10-11 Mark Mitchell <mark@markmitchell.com>
+
+ * cp-tree.h (specializations_of_same_template_p): Declare.
+ * pt.c (specializations_of_same_template_p): New function.
+ (unify): Use it.
+ * search.c (get_template_base): Use it.
+ (get_template_base_recursive): Likewise.
+
+1998-10-10 Manfred Hollstein <manfred@s-direktnet.de>
+
+ * decl2.c (start_objects): Add new variable `joiner' and
+ initialize it properly.
+
+1998-10-09 Mark Mitchell <mark@markmitchell.com>
+
+ * search.c (expand_upcast_fixups): Tweak to match 1998-10-07
+ change to vtable types.
+
+ * cvt.c (ocp_convert): Avoid infinite recursion caused by
+ 1998-10-03 change.
+
+1998-10-08 Jason Merrill <jason@yorick.cygnus.com>
+
+ * pt.c (resolve_overloaded_unification): New fn.
+ (try_one_overload): Likewise.
+ (unify): Don't fail on unknown type.
+ (type_unification_real): Likewise. Use resolve_overloaded_unification
+ to handle an overloaded argument.
+ (template_args_equal): Split out...
+ (comp_template_args): From here.
+ (determine_specialization): Also allow a template with more
+ parms than were explicitly specified.
+ * cp-tree.h: Add template_args_equal.
+ * call.c (resolve_args): Remove TEMPLATE_ID_EXPR code.
+
+Thu Oct 8 15:58:30 1998 Anthony Green <green@cygnus.com>
+
+ * semantics.c (finish_asm_stmt): Revert my 1998-09-28
+ change.
+
+Thu Oct 8 06:00:19 1998 Jeffrey A Law (law@cygnus.com)
+
+ * typeck.c (unsigned_type): Only return TItype nodes when
+ HOST_BITS_PER_WIDE_INT is >= 64 bits.
+ (signed_type): Similarly.
+ * decl.c (intTI_type_node, unsigned_intTI_type_node): Only declare
+ when HOST_BITS_PER_WIDE_INT is >= 64 bits.
+ (init_decl_processing): Only create TItype nodes when
+ HOST_BITS_PER_WIDE_INT is >= 64 bits.
+ * cp-tree.h (intTI_type_node, unsigned_intTI_type_node): Only declare
+ when HOST_BITS_PER_WIDE_INT is >= 64 bits.
+
Wed Oct 7 12:32:44 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
* Makefile.in (hash.h): Add -L KR-C -F ', 0, 0' flags to gperf.
@@ -246,7 +2814,6 @@ Tue Oct 6 07:57:26 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
* decl2.c (merge_functions): Remove duplicates.
* decl2.c: Add -f{no-,}implicit-inline-templates.
- (lang_decode_option): Unset it if -frepo.
(import_export_decl): Check it.
* decl.c (lookup_name_real): Template parms also take precedence
diff --git a/gcc/cp/Make-lang.in b/gcc/cp/Make-lang.in
index 320ffc3e7f2..c877417de47 100644
--- a/gcc/cp/Make-lang.in
+++ b/gcc/cp/Make-lang.in
@@ -1,5 +1,5 @@
# Top level makefile fragment for GNU C++.
-# Copyright (C) 1994, 1995, 1997 Free Software Foundation, Inc.
+# Copyright (C) 1994, 1995, 1997, 1998, 1999 Free Software Foundation, Inc.
#This file is part of GNU CC.
@@ -75,43 +75,38 @@ C++ c++: cc1plus$(exeext)
# Tell GNU make to ignore these if they exist.
.PHONY: C++ c++
-g++.c: $(srcdir)/gcc.c
- -rm -f $@
- $(LN_S) $(srcdir)/gcc.c $@
-
g++spec.o: $(srcdir)/cp/g++spec.c
$(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $(srcdir)/cp/g++spec.c
-# N.B.: This is a copy of the gcc.o rule, with -DLANG_SPECIFIC_DRIVER added.
-# It'd be nice if we could find an easier way to do this---rather than have
-# to track changes to the toplevel gcc Makefile as well.
-# We depend on g++.c last, to make it obvious where it came from.
-g++.o: $(CONFIG_H) multilib.h config.status $(lang_specs_files) g++.c \
- system.h
- $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
- $(DRIVER_DEFINES) \
- -DLANG_SPECIFIC_DRIVER \
- -c g++.c
+$(INTL_TARGETS): $(srcdir)/cp/parse.c
+$(srcdir)/cp/parse.c: $(srcdir)/cp/parse.y
+ @cp_srcdir=`sed -n 's/^srcdir[ ]*=[ ]*//p' cp/Makefile` && \
+ echo "cd cp && $(MAKE) $$cp_srcdir/parse.c" && \
+ cd cp && \
+ $(MAKE) $(SUBDIR_FLAGS_TO_PASS) $(CXX_FLAGS_TO_PASS) \
+ $$cp_srcdir/parse.c
# Create the compiler driver for g++.
-g++$(exeext): g++.o g++spec.o version.o choose-temp.o pexecute.o prefix.o mkstemp.o $(LIBDEPS) $(EXTRA_GCC_OBJS)
- $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ g++.o g++spec.o prefix.o \
- version.o choose-temp.o pexecute.o mkstemp.o $(EXTRA_GCC_OBJS) $(LIBS)
+GXX_OBJS = gcc.o g++spec.o intl.o prefix.o version.o
+g++$(exeext): $(GXX_OBJS) $(EXTRA_GCC_OBJS) $(LIBDEPS)
+ $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ \
+ $(GXX_OBJS) $(EXTRA_GCC_OBJS) $(LIBS)
# Create a version of the g++ driver which calls the cross-compiler.
g++-cross$(exeext): g++$(exeext)
-rm -f g++-cross$(exeext)
cp g++$(exeext) g++-cross$(exeext)
-cxxmain.o: $(srcdir)/../libiberty/cplus-dem.c demangle.h
+cxxmain.o: $(srcdir)/../libiberty/cplus-dem.c $(DEMANGLE_H)
rm -f cxxmain.c
$(LN_S) $(srcdir)/../libiberty/cplus-dem.c cxxmain.c
$(CC) -c -DMAIN $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
-DVERSION=\"$(version)\" cxxmain.c
-$(DEMANGLER_PROG): cxxmain.o underscore.o getopt.o getopt1.o $(LIBDEPS)
- $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ \
- cxxmain.o underscore.o getopt.o getopt1.o $(LIBS)
+# Apparently OpenVM needs the -o to be at the beginning of the link line.
+$(DEMANGLER_PROG): cxxmain.o underscore.o $(LIBDEPS)
+ $(CC) -o $@ $(ALL_CFLAGS) $(LDFLAGS) \
+ cxxmain.o underscore.o $(LIBS)
CXX_SRCS = $(srcdir)/cp/call.c $(srcdir)/cp/decl2.c \
$(srcdir)/cp/except.c $(srcdir)/cp/input.c $(srcdir)/cp/pt.c \
@@ -125,7 +120,7 @@ CXX_SRCS = $(srcdir)/cp/call.c $(srcdir)/cp/decl2.c \
$(srcdir)/cp/repo.c $(srcdir)/cp/semantics.c
cc1plus$(exeext): $(P) $(CXX_SRCS) $(LIBDEPS) stamp-objlist c-common.o c-pragma.o \
- $(srcdir)/cp/cp-tree.h $(srcdir)/cp/cp-tree.def
+ $(srcdir)/cp/cp-tree.h $(srcdir)/cp/cp-tree.def hash.o
cd cp; $(MAKE) $(FLAGS_TO_PASS) $(CXX_FLAGS_TO_PASS) ../cc1plus$(exeext)
#
# Build hooks:
@@ -187,8 +182,11 @@ cplib2.txt: $(CXX_LIB2SRCS) $(CXX_EXTRA_HEADERS) cplib2.ready
mv -f cplib2.new cplib2.txt
# Or if it would be different.
+# Don't try to do write if `.' is not writable;
+# in that case, we're installing from someone else's directory.
+# But go ahead and fail if that directory hasn't been properly built.
cplib2.ready: $(GCC_PASSES) $(LANGUAGES) $(LIBGCC2_DEPS) stmp-int-hdrs
- @if [ -r cplib2.txt ]; then \
+ @if [ -r cplib2.txt -a -w . ]; then \
case " $(LANGUAGES) " in \
*" "[cC]"++ "*) \
echo $(CXX_LIB2FUNCS) > cplib2.new;; \
@@ -246,13 +244,13 @@ c++.install-info:
c++.install-man: $(srcdir)/cp/g++.1
-if [ -f cc1plus$(exeext) ] ; then \
if [ -f g++-cross$(exeext) ] ; then \
- rm -f $(mandir)/$(GXX_CROSS_NAME)$(manext); \
- $(INSTALL_DATA) $(srcdir)/cp/g++.1 $(mandir)/$(GXX_CROSS_NAME)$(manext); \
- chmod a-x $(mandir)/$(GXX_CROSS_NAME)$(manext); \
+ rm -f $(man1dir)/$(GXX_CROSS_NAME)$(manext); \
+ $(INSTALL_DATA) $(srcdir)/cp/g++.1 $(man1dir)/$(GXX_CROSS_NAME)$(manext); \
+ chmod a-x $(man1dir)/$(GXX_CROSS_NAME)$(manext); \
else \
- rm -f $(mandir)/$(GXX_INSTALL_NAME)$(manext); \
- $(INSTALL_DATA) $(srcdir)/cp/g++.1 $(mandir)/$(GXX_INSTALL_NAME)$(manext); \
- chmod a-x $(mandir)/$(GXX_INSTALL_NAME)$(manext); \
+ rm -f $(man1dir)/$(GXX_INSTALL_NAME)$(manext); \
+ $(INSTALL_DATA) $(srcdir)/cp/g++.1 $(man1dir)/$(GXX_INSTALL_NAME)$(manext); \
+ chmod a-x $(man1dir)/$(GXX_INSTALL_NAME)$(manext); \
fi; \
else true; fi
@@ -263,8 +261,8 @@ c++.uninstall:
-rm -rf $(bindir)/$(GXX_CROSS_NAME)$(exeext)
-rm -rf $(bindir)/$(DEMANGLER_INSTALL_NAME)$(exeext)
-rm -rf $(bindir)/$(DEMANGLER_CROSS_NAME)$(exeext)
- -rm -rf $(mandir)/$(GXX_INSTALL_NAME)$(manext)
- -rm -rf $(mandir)/$(GXX_CROSS_NAME)$(manext)
+ -rm -rf $(man1dir)/$(GXX_INSTALL_NAME)$(manext)
+ -rm -rf $(man1dir)/$(GXX_CROSS_NAME)$(manext)
#
# Clean hooks:
# A lot of the ancillary files are deleted by the main makefile.
@@ -277,7 +275,6 @@ c++.clean:
c++.distclean:
-rm -f cp/config.status cp/Makefile
-rm -f cp/parse.output
- -rm -f g++.c
c++.extraclean:
c++.maintainer-clean:
-rm -f cp/parse.c cp/parse.h
diff --git a/gcc/cp/Makefile.in b/gcc/cp/Makefile.in
index d9e32402d39..ef81437d2ae 100644
--- a/gcc/cp/Makefile.in
+++ b/gcc/cp/Makefile.in
@@ -1,5 +1,5 @@
# Makefile for GNU C++ compiler.
-# Copyright (C) 1987, 88, 90-5, 1998 Free Software Foundation, Inc.
+# Copyright (C) 1987, 88, 90-5, 1998, 1999 Free Software Foundation, Inc.
#This file is part of GNU CC.
@@ -105,6 +105,12 @@ VPATH = @srcdir@
# Additional system libraries to link with.
CLIB=
+
+# Top build directory, relative to here.
+top_builddir = ..
+
+# Internationalization library.
+INTLLIBS = @INTLLIBS@
# Change this to a null string if obstacks are installed in the
# system library.
@@ -154,7 +160,8 @@ SUBDIR_MALLOC = `if [ x$(MALLOC) != x ]; then echo ../$(MALLOC); else true; fi`
# How to link with both our special library facilities
# and the system's installed libraries.
-LIBS = $(SUBDIR_OBSTACK) $(SUBDIR_USE_ALLOCA) $(SUBDIR_MALLOC) $(CLIB)
+LIBS = $(SUBDIR_OBSTACK) $(SUBDIR_USE_ALLOCA) $(SUBDIR_MALLOC) \
+ $(INTLLIBS) $(CLIB)
# Specify the directories to be searched for header files.
# Both . and srcdir are used, in that order,
@@ -188,9 +195,8 @@ OBJS = `cat ../stamp-objlist` ../c-common.o ../c-pragma.o
OBJDEPS = ../stamp-objlist ../c-common.o ../c-pragma.o
compiler: ../cc1plus$(exeext)
-../cc1plus$(exeext): $(P) $(CXX_OBJS) $(OBJDEPS) $(LIBDEPS)
- $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ \
- $(CXX_OBJS) $(OBJS) $(LIBS)
+../cc1plus$(exeext): $(P) $(OBJDEPS) $(CXX_OBJS) $(LIBDEPS)
+ $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ $(OBJS) $(CXX_OBJS) $(LIBS)
Makefile: $(srcdir)/Makefile.in $(srcdir)/../configure
cd ..; $(SHELL) config.status
@@ -219,7 +225,7 @@ parse.o : $(PARSE_C) $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h lex.h \
$(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $(BIG_SWITCHFLAG) \
`echo $(PARSE_C) | sed 's,^\./,,'`
-CONFLICTS = expect 25 shift/reduce conflicts and 42 reduce/reduce conflicts.
+CONFLICTS = expect 36 shift/reduce conflicts and 42 reduce/reduce conflicts.
$(PARSE_H) : $(PARSE_C)
$(PARSE_C) : $(srcdir)/parse.y
@echo $(CONFLICTS)
@@ -235,11 +241,10 @@ $(PARSE_C) : $(srcdir)/parse.y
# cp $(PARSE_C) y.tab.c
# touch stamp-parse
-# hash.h really depends on $(srcdir)/gxx.gperf.
-# But this would screw things for people that don't have gperf,
-# if gxx.gpref got touched, say.
-# Thus you have to remove hash.h to force it to be re-made.
-$(srcdir)/hash.h:
+# We used to try to protect people from having to rerun gperf. But,
+# the C front-end already requires this if c-parse.gperf is changed,
+# so we should be consistent.
+$(srcdir)/hash.h: $(srcdir)/gxx.gperf
gperf -L KR-C -F ', 0, 0' -p -j1 -g -o -t -N is_reserved_word \
'-k1,4,7,$$' $(srcdir)/gxx.gperf >$(srcdir)/hash.h
@@ -251,7 +256,8 @@ lex.o : lex.c $(CONFIG_H) $(CXX_TREE_H) \
$(srcdir)/../output.h $(srcdir)/../mbchar.h
decl.o : decl.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h \
lex.h decl.h $(srcdir)/../stack.h $(srcdir)/../output.h \
- $(srcdir)/../except.h $(srcdir)/../system.h $(srcdir)/../toplev.h
+ $(srcdir)/../except.h $(srcdir)/../system.h $(srcdir)/../toplev.h \
+ $(srcdir)/../hash.h
decl2.o : decl2.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h \
lex.h decl.h $(EXPR_H) $(srcdir)/../except.h \
$(srcdir)/../output.h $(srcdir)/../except.h $(srcdir)/../system.h \
@@ -270,9 +276,11 @@ init.o : init.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h $(RTL_H) \
$(EXPR_H) $(srcdir)/../system.h $(srcdir)/../toplev.h
method.o : method.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../system.h \
$(srcdir)/../toplev.h
-cvt.o : cvt.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../system.h
+cvt.o : cvt.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../system.h decl.h \
+ $(srcdir)/../flags.h $(srcdir)/../toplev.h $(srcdir)/../convert.h
search.o : search.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../stack.h \
- $(srcdir)/../flags.h $(srcdir)/../system.h $(srcdir)/../toplev.h
+ $(srcdir)/../flags.h $(srcdir)/../system.h $(srcdir)/../toplev.h \
+ $(srcdir)/../varray.h
tree.o : tree.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h \
$(srcdir)/../system.h $(srcdir)/../toplev.h
ptree.o : ptree.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../system.h
diff --git a/gcc/cp/NEWS b/gcc/cp/NEWS
index 9cb7d5b2c26..0cdcc229a4e 100644
--- a/gcc/cp/NEWS
+++ b/gcc/cp/NEWS
@@ -1,3 +1,9 @@
+*** Changes since EGCS 1.1:
+
+* Messages about non-conformant code that we can still handle ("pedwarns")
+ are now errors by default, rather than warnings. This can be reverted
+ with -fpermissive, and is overridden by -pedantic or -pedantic-errors.
+
*** Changes in EGCS 1.1:
* Namespaces are fully supported. The library has not yet been converted
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index f01aacb09c0..9bc349e7999 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -1,5 +1,5 @@
/* Functions related to invoking methods and overloaded functions.
- Copyright (C) 1987, 92-97, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1987, 92-97, 1998, 1999 Free Software Foundation, Inc.
Contributed by Michael Tiemann (tiemann@cygnus.com) and
modified by Brendan Kehoe (brendan@cygnus.com).
@@ -49,7 +49,7 @@ static int compare_ics PROTO((tree, tree));
static tree build_over_call PROTO((struct z_candidate *, tree, int));
static tree convert_like PROTO((tree, tree));
static void op_error PROTO((enum tree_code, enum tree_code, tree, tree,
- tree, char *));
+ tree, const char *));
static tree build_object_call PROTO((tree, tree));
static tree resolve_args PROTO((tree));
static struct z_candidate * build_user_type_conversion_1
@@ -90,6 +90,10 @@ static int is_subseq PROTO((tree, tree));
static int is_properly_derived_from PROTO((tree, tree));
static int maybe_handle_ref_bind PROTO((tree*, tree*));
static void maybe_handle_implicit_object PROTO((tree*));
+static struct z_candidate * add_candidate PROTO((struct z_candidate *,
+ tree, tree, int));
+static tree source_type PROTO((tree));
+static void add_warning PROTO((struct z_candidate *, struct z_candidate *));
tree
build_vfield_ref (datum, type)
@@ -124,92 +128,40 @@ build_field_call (basetype_path, instance_ptr, name, parms)
if (name == ctor_identifier || name == dtor_identifier)
return NULL_TREE;
- if (instance_ptr == current_class_ptr)
- {
- /* Check to see if we really have a reference to an instance variable
- with `operator()()' overloaded. */
- field = IDENTIFIER_CLASS_VALUE (name);
-
- if (field == NULL_TREE)
- {
- cp_error ("`this' has no member named `%D'", name);
- return error_mark_node;
- }
-
- if (TREE_CODE (field) == FIELD_DECL || TREE_CODE (field) == VAR_DECL)
- {
- /* If it's a field, try overloading operator (),
- or calling if the field is a pointer-to-function. */
- instance = build_component_ref_1 (current_class_ref, field, 0);
- if (instance == error_mark_node)
- return error_mark_node;
-
- if (TYPE_LANG_SPECIFIC (TREE_TYPE (instance)))
- return build_opfncall (CALL_EXPR, LOOKUP_NORMAL, instance, parms, NULL_TREE);
-
- if (TREE_CODE (TREE_TYPE (instance)) == POINTER_TYPE)
- {
- if (TREE_CODE (TREE_TYPE (TREE_TYPE (instance))) == FUNCTION_TYPE)
- return build_function_call (instance, parms);
- else if (TREE_CODE (TREE_TYPE (TREE_TYPE (instance))) == METHOD_TYPE)
- return build_function_call (instance, expr_tree_cons (NULL_TREE, current_class_ptr, parms));
- }
- }
- return NULL_TREE;
- }
+ /* Speed up the common case. */
+ if (instance_ptr == current_class_ptr
+ && IDENTIFIER_CLASS_VALUE (name) == NULL_TREE)
+ return NULL_TREE;
- /* Check to see if this is not really a reference to an instance variable
- with `operator()()' overloaded. */
field = lookup_field (basetype_path, name, 1, 0);
- /* This can happen if the reference was ambiguous or for access
- violations. */
- if (field == error_mark_node)
- return error_mark_node;
+ if (field == error_mark_node || field == NULL_TREE)
+ return field;
- if (field && (TREE_CODE (field) == FIELD_DECL ||
- TREE_CODE (field) == VAR_DECL))
+ if (TREE_CODE (field) == FIELD_DECL || TREE_CODE (field) == VAR_DECL)
{
- tree basetype;
- tree ftype = TREE_TYPE (field);
+ /* If it's a field, try overloading operator (),
+ or calling if the field is a pointer-to-function. */
+ instance = build_indirect_ref (instance_ptr, NULL_PTR);
+ instance = build_component_ref_1 (instance, field, 0);
- if (TREE_CODE (ftype) == REFERENCE_TYPE)
- ftype = TREE_TYPE (ftype);
+ if (instance == error_mark_node)
+ return error_mark_node;
- if (TYPE_LANG_SPECIFIC (ftype))
- {
- /* Make the next search for this field very short. */
- basetype = DECL_FIELD_CONTEXT (field);
- instance_ptr = convert_pointer_to (basetype, instance_ptr);
-
- instance = build_indirect_ref (instance_ptr, NULL_PTR);
- return build_opfncall (CALL_EXPR, LOOKUP_NORMAL,
- build_component_ref_1 (instance, field, 0),
- parms, NULL_TREE);
- }
- if (TREE_CODE (ftype) == POINTER_TYPE)
- {
- if (TREE_CODE (TREE_TYPE (ftype)) == FUNCTION_TYPE
- || TREE_CODE (TREE_TYPE (ftype)) == METHOD_TYPE)
- {
- /* This is a member which is a pointer to function. */
- tree ref
- = build_component_ref_1 (build_indirect_ref (instance_ptr,
- NULL_PTR),
- field, LOOKUP_COMPLAIN);
- if (ref == error_mark_node)
- return error_mark_node;
- return build_function_call (ref, parms);
- }
- }
- else if (TREE_CODE (ftype) == METHOD_TYPE)
+ if (IS_AGGR_TYPE (TREE_TYPE (instance)))
+ return build_opfncall (CALL_EXPR, LOOKUP_NORMAL,
+ instance, parms, NULL_TREE);
+ else if (TREE_CODE (TREE_TYPE (instance)) == POINTER_TYPE)
{
- error ("invalid call via pointer-to-member function");
- return error_mark_node;
+ if (TREE_CODE (TREE_TYPE (TREE_TYPE (instance))) == FUNCTION_TYPE)
+ return build_function_call (instance, parms);
+ else if (TREE_CODE (TREE_TYPE (TREE_TYPE (instance)))
+ == METHOD_TYPE)
+ return build_function_call
+ (instance, expr_tree_cons (NULL_TREE, instance_ptr, parms));
}
- else
- return NULL_TREE;
}
+
return NULL_TREE;
}
@@ -347,6 +299,10 @@ check_dtor_name (basetype, name)
{
name = TREE_OPERAND (name, 0);
+ /* Just accept something we've already complained about. */
+ if (name == error_mark_node)
+ return 1;
+
if (TREE_CODE (name) == TYPE_DECL)
name = TREE_TYPE (name);
else if (TREE_CODE_CLASS (TREE_CODE (name)) == 't')
@@ -548,6 +504,9 @@ build_call (function, result_type, parms)
if (decl && DECL_CONSTRUCTOR_P (decl))
is_constructor = 1;
+ if (decl)
+ my_friendly_assert (TREE_USED (decl), 990125);
+
/* Don't pass empty class objects by value. This is useful
for tags in STL, which are used to control overload resolution.
We don't need to handle other cases of copying empty classes. */
@@ -625,10 +584,15 @@ build_method_call (instance, name, parms, basetype_path, flags)
{
/* We need to process template parm names here so that tsubst catches
them properly. Other type names can wait. */
- if (TREE_CODE (name) == BIT_NOT_EXPR
- && TREE_CODE (TREE_OPERAND (name, 0)) == IDENTIFIER_NODE)
+ if (TREE_CODE (name) == BIT_NOT_EXPR)
{
- tree type = get_aggr_from_typedef (TREE_OPERAND (name, 0), 0);
+ tree type = NULL_TREE;
+
+ if (TREE_CODE (TREE_OPERAND (name, 0)) == IDENTIFIER_NODE)
+ type = get_aggr_from_typedef (TREE_OPERAND (name, 0), 0);
+ else if (TREE_CODE (TREE_OPERAND (name, 0)) == TYPE_DECL)
+ type = TREE_TYPE (TREE_OPERAND (name, 0));
+
if (type && TREE_CODE (type) == TEMPLATE_TYPE_PARM)
name = build_min_nt (BIT_NOT_EXPR, type);
}
@@ -803,6 +767,15 @@ standard_conversion (to, from, expr)
to = strip_top_quals (to);
from = strip_top_quals (from);
+ if ((TYPE_PTRFN_P (to) || TYPE_PTRMEMFUNC_P (to))
+ && expr && type_unknown_p (expr))
+ {
+ expr = instantiate_type (to, expr, 0);
+ if (expr == error_mark_node)
+ return NULL_TREE;
+ from = TREE_TYPE (expr);
+ }
+
fcode = TREE_CODE (from);
tcode = TREE_CODE (to);
@@ -836,16 +809,15 @@ standard_conversion (to, from, expr)
enum tree_code ufcode = TREE_CODE (TREE_TYPE (from));
enum tree_code utcode = TREE_CODE (TREE_TYPE (to));
- if (comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (from)),
- TYPE_MAIN_VARIANT (TREE_TYPE (to)), 1))
+ if (same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (from)),
+ TYPE_MAIN_VARIANT (TREE_TYPE (to))))
;
else if (utcode == VOID_TYPE && ufcode != OFFSET_TYPE
&& ufcode != FUNCTION_TYPE)
{
from = build_pointer_type
- (cp_build_type_variant (void_type_node,
- TYPE_READONLY (TREE_TYPE (from)),
- TYPE_VOLATILE (TREE_TYPE (from))));
+ (cp_build_qualified_type (void_type_node,
+ CP_TYPE_QUALS (TREE_TYPE (from))));
conv = build_conv (PTR_CONV, from, conv);
}
else if (ufcode == OFFSET_TYPE && utcode == OFFSET_TYPE)
@@ -854,9 +826,9 @@ standard_conversion (to, from, expr)
tree tbase = TYPE_OFFSET_BASETYPE (TREE_TYPE (to));
if (DERIVED_FROM_P (fbase, tbase)
- && (comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (from))),
- TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (to))),
- 1)))
+ && (same_type_p
+ (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (from))),
+ TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (to))))))
{
from = build_offset_type (tbase, TREE_TYPE (TREE_TYPE (from)));
from = build_pointer_type (from);
@@ -868,15 +840,15 @@ standard_conversion (to, from, expr)
{
if (DERIVED_FROM_P (TREE_TYPE (to), TREE_TYPE (from)))
{
- from = cp_build_type_variant (TREE_TYPE (to),
- TYPE_READONLY (TREE_TYPE (from)),
- TYPE_VOLATILE (TREE_TYPE (from)));
+ from =
+ cp_build_qualified_type (TREE_TYPE (to),
+ CP_TYPE_QUALS (TREE_TYPE (from)));
from = build_pointer_type (from);
conv = build_conv (PTR_CONV, from, conv);
}
}
- if (comptypes (from, to, 1))
+ if (same_type_p (from, to))
/* OK */;
else if (comp_ptr_ttypes (TREE_TYPE (to), TREE_TYPE (from)))
conv = build_conv (QUAL_CONV, to, conv);
@@ -901,15 +873,13 @@ standard_conversion (to, from, expr)
tree tbase = TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (tofn)));
if (! DERIVED_FROM_P (fbase, tbase)
- || ! comptypes (TREE_TYPE (fromfn), TREE_TYPE (tofn), 1)
+ || ! same_type_p (TREE_TYPE (fromfn), TREE_TYPE (tofn))
|| ! compparms (TREE_CHAIN (TYPE_ARG_TYPES (fromfn)),
- TREE_CHAIN (TYPE_ARG_TYPES (tofn)), 1)
- || TYPE_READONLY (fbase) != TYPE_READONLY (tbase)
- || TYPE_VOLATILE (fbase) != TYPE_VOLATILE (tbase))
+ TREE_CHAIN (TYPE_ARG_TYPES (tofn)))
+ || CP_TYPE_QUALS (fbase) != CP_TYPE_QUALS (tbase))
return 0;
- from = cp_build_type_variant (tbase, TYPE_READONLY (fbase),
- TYPE_VOLATILE (fbase));
+ from = cp_build_qualified_type (tbase, CP_TYPE_QUALS (fbase));
from = build_cplus_method_type (from, TREE_TYPE (fromfn),
TREE_CHAIN (TYPE_ARG_TYPES (fromfn)));
from = build_ptrmemfunc_type (build_pointer_type (from));
@@ -971,24 +941,30 @@ reference_binding (rto, rfrom, expr, flags)
tree from = rfrom;
int related;
+ if (TREE_CODE (to) == FUNCTION_TYPE && expr && type_unknown_p (expr))
+ {
+ expr = instantiate_type (to, expr, 0);
+ if (expr == error_mark_node)
+ return NULL_TREE;
+ from = TREE_TYPE (expr);
+ }
+
if (TREE_CODE (from) == REFERENCE_TYPE)
from = TREE_TYPE (from);
else if (! expr || ! real_lvalue_p (expr))
lvalue = 0;
- related = (comptypes (TYPE_MAIN_VARIANT (to),
- TYPE_MAIN_VARIANT (from), 1)
+ related = (same_type_p (TYPE_MAIN_VARIANT (to),
+ TYPE_MAIN_VARIANT (from))
|| (IS_AGGR_TYPE (to) && IS_AGGR_TYPE (from)
&& DERIVED_FROM_P (to, from)));
- if (lvalue && related
- && TYPE_READONLY (to) >= TYPE_READONLY (from)
- && TYPE_VOLATILE (to) >= TYPE_VOLATILE (from))
+ if (lvalue && related && at_least_as_qualified_p (to, from))
{
conv = build1 (IDENTITY_CONV, from, expr);
- if (comptypes (TYPE_MAIN_VARIANT (to),
- TYPE_MAIN_VARIANT (from), 1))
+ if (same_type_p (TYPE_MAIN_VARIANT (to),
+ TYPE_MAIN_VARIANT (from)))
conv = build_conv (REF_BIND, rto, conv);
else
{
@@ -1012,14 +988,12 @@ reference_binding (rto, rfrom, expr, flags)
TREE_OPERAND (conv, 0) = TREE_OPERAND (TREE_OPERAND (conv, 0), 0);
}
if (conv
- && ((! (TYPE_READONLY (to) && ! TYPE_VOLATILE (to)
+ && ((! (CP_TYPE_CONST_NON_VOLATILE_P (to)
&& (flags & LOOKUP_NO_TEMP_BIND) == 0))
/* If T1 is reference-related to T2, cv1 must be the same
cv-qualification as, or greater cv-qualification than,
cv2; otherwise, the program is ill-formed. */
- || (related
- && (TYPE_READONLY (to) < TYPE_READONLY (from)
- || TYPE_VOLATILE (to) < TYPE_VOLATILE (from)))))
+ || (related && !at_least_as_qualified_p (to, from))))
ICS_BAD_FLAG (conv) = 1;
}
@@ -1039,14 +1013,6 @@ implicit_conversion (to, from, expr, flags)
tree conv;
struct z_candidate *cand;
- if (expr && type_unknown_p (expr))
- {
- expr = instantiate_type (to, expr, 0);
- if (expr == error_mark_node)
- return 0;
- from = TREE_TYPE (expr);
- }
-
if (TREE_CODE (to) == REFERENCE_TYPE)
conv = reference_binding (to, from, expr, flags);
else
@@ -1056,7 +1022,7 @@ implicit_conversion (to, from, expr, flags)
;
else if (expr != NULL_TREE
&& (IS_AGGR_TYPE (non_reference (from))
- || IS_AGGR_TYPE (non_reference (to)))
+ || IS_AGGR_TYPE (non_reference (to)))
&& (flags & LOOKUP_NO_CONVERSION) == 0)
{
cand = build_user_type_conversion_1
@@ -1071,8 +1037,7 @@ implicit_conversion (to, from, expr, flags)
(TYPE_MAIN_VARIANT (TREE_TYPE (to)), expr, LOOKUP_ONLYCONVERTING);
if (cand)
{
- if (! TYPE_READONLY (TREE_TYPE (to))
- || TYPE_VOLATILE (TREE_TYPE (to)))
+ if (!CP_TYPE_CONST_NON_VOLATILE_P (TREE_TYPE (to)))
ICS_BAD_FLAG (cand->second_conv) = 1;
if (!conv || (ICS_BAD_FLAG (conv)
> ICS_BAD_FLAG (cand->second_conv)))
@@ -1121,26 +1086,62 @@ add_function_candidate (candidates, fn, arglist, flags)
tree parmlist = TYPE_ARG_TYPES (TREE_TYPE (fn));
int i, len;
tree convs;
- tree parmnode = parmlist;
- tree argnode = arglist;
+ tree parmnode, argnode;
int viable = 1;
/* The `this' and `in_chrg' arguments to constructors are not considered
in overload resolution. */
if (DECL_CONSTRUCTOR_P (fn))
{
- parmnode = TREE_CHAIN (parmnode);
- argnode = TREE_CHAIN (argnode);
+ parmlist = TREE_CHAIN (parmlist);
+ arglist = TREE_CHAIN (arglist);
if (TYPE_USES_VIRTUAL_BASECLASSES (DECL_CONTEXT (fn)))
{
- parmnode = TREE_CHAIN (parmnode);
- argnode = TREE_CHAIN (argnode);
+ parmlist = TREE_CHAIN (parmlist);
+ arglist = TREE_CHAIN (arglist);
}
}
- len = list_length (argnode);
+ len = list_length (arglist);
convs = make_scratch_vec (len);
+ /* 13.3.2 - Viable functions [over.match.viable]
+ First, to be a viable function, a candidate function shall have enough
+ parameters to agree in number with the arguments in the list.
+
+ We need to check this first; otherwise, checking the ICSes might cause
+ us to produce an ill-formed template instantiation. */
+
+ parmnode = parmlist;
+ for (i = 0; i < len; ++i)
+ {
+ if (parmnode == NULL_TREE || parmnode == void_list_node)
+ break;
+ parmnode = TREE_CHAIN (parmnode);
+ }
+
+ if (i < len && parmnode)
+ viable = 0;
+
+ /* Make sure there are default args for the rest of the parms. */
+ else for (; parmnode && parmnode != void_list_node;
+ parmnode = TREE_CHAIN (parmnode))
+ if (! TREE_PURPOSE (parmnode))
+ {
+ viable = 0;
+ break;
+ }
+
+ if (! viable)
+ goto out;
+
+ /* Second, for F to be a viable function, there shall exist for each
+ argument an implicit conversion sequence that converts that argument
+ to the corresponding parameter of F. */
+
+ parmnode = parmlist;
+ argnode = arglist;
+
for (i = 0; i < len; ++i)
{
tree arg = TREE_VALUE (argnode);
@@ -1149,8 +1150,28 @@ add_function_candidate (candidates, fn, arglist, flags)
if (parmnode == void_list_node)
break;
- else if (parmnode)
- t = implicit_conversion (TREE_VALUE (parmnode), argtype, arg, flags);
+
+ if (parmnode)
+ {
+ tree parmtype = TREE_VALUE (parmnode);
+
+ /* [over.match.funcs] For conversion functions, the function is
+ considered to be a member of the class of the implicit object
+ argument for the purpose of defining the type of the implicit
+ object parameter.
+
+ Since build_over_call ignores the ICS for the `this' parameter,
+ we can just change the parm type. */
+ if (DECL_CONV_FN_P (fn) && i == 0)
+ {
+ parmtype
+ = build_qualified_type (TREE_TYPE (argtype),
+ TYPE_QUALS (TREE_TYPE (parmtype)));
+ parmtype = build_pointer_type (parmtype);
+ }
+
+ t = implicit_conversion (parmtype, argtype, arg, flags);
+ }
else
{
t = build1 (IDENTITY_CONV, argtype, arg);
@@ -1163,7 +1184,10 @@ add_function_candidate (candidates, fn, arglist, flags)
TREE_VEC_ELT (convs, i) = t;
if (! t)
- break;
+ {
+ viable = 0;
+ break;
+ }
if (ICS_BAD_FLAG (t))
viable = -1;
@@ -1173,25 +1197,20 @@ add_function_candidate (candidates, fn, arglist, flags)
argnode = TREE_CHAIN (argnode);
}
- if (i < len)
- viable = 0;
-
- /* Make sure there are default args for the rest of the parms. */
- for (; parmnode && parmnode != void_list_node;
- parmnode = TREE_CHAIN (parmnode))
- if (! TREE_PURPOSE (parmnode))
- {
- viable = 0;
- break;
- }
-
+ out:
return add_candidate (candidates, fn, convs, viable);
}
/* Create an overload candidate for the conversion function FN which will
be invoked for expression OBJ, producing a pointer-to-function which
will in turn be called with the argument list ARGLIST, and add it to
- CANDIDATES. FLAGS is passed on to implicit_conversion. */
+ CANDIDATES. FLAGS is passed on to implicit_conversion.
+
+ Actually, we don't really care about FN; we care about the type it
+ converts to. There may be multiple conversion functions that will
+ convert to that type, and we rely on build_user_type_conversion_1 to
+ choose the best one; so when we create our candidate, we record the type
+ instead of the function. */
static struct z_candidate *
add_conv_candidate (candidates, fn, obj, arglist)
@@ -1207,6 +1226,10 @@ add_conv_candidate (candidates, fn, obj, arglist)
int viable = 1;
int flags = LOOKUP_NORMAL;
+ /* Don't bother looking up the same type twice. */
+ if (candidates && candidates->fn == totype)
+ return candidates;
+
for (i = 0; i < len; ++i)
{
tree arg = i == 0 ? obj : TREE_VALUE (argnode);
@@ -1251,7 +1274,7 @@ add_conv_candidate (candidates, fn, obj, arglist)
break;
}
- return add_candidate (candidates, fn, convs, viable);
+ return add_candidate (candidates, totype, convs, viable);
}
static struct z_candidate *
@@ -1797,7 +1820,7 @@ add_builtin_candidates (candidates, code, code2, fnname, args, flags)
;
else if (IS_AGGR_TYPE (argtypes[i]))
{
- tree convs = lookup_conversions (argtypes[i]);
+ tree convs;
if (i == 0 && code == MODIFY_EXPR && code2 == NOP_EXPR)
return candidates;
@@ -1819,11 +1842,11 @@ add_builtin_candidates (candidates, code, code2, fnname, args, flags)
for (; convs; convs = TREE_CHAIN (convs))
{
- type = TREE_TYPE (TREE_TYPE (TREE_VALUE (convs)));
+ type = TREE_TYPE (TREE_TYPE (OVL_CURRENT (TREE_VALUE (convs))));
if (i == 0 && ref1
&& (TREE_CODE (type) != REFERENCE_TYPE
- || TYPE_READONLY (TREE_TYPE (type))))
+ || CP_TYPE_CONST_P (TREE_TYPE (type))))
continue;
if (code == COND_EXPR && TREE_CODE (type) == REFERENCE_TYPE)
@@ -1905,7 +1928,7 @@ add_template_candidate_real (candidates, tmpl, explicit_targs,
tree fn;
i = fn_type_unification (tmpl, explicit_targs, targs, arglist,
- return_type, strict, NULL_TREE);
+ return_type, strict);
if (i != 0)
return candidates;
@@ -2014,7 +2037,7 @@ static void
print_z_candidates (candidates)
struct z_candidate *candidates;
{
- char *str = "candidates are:";
+ const char *str = "candidates are:";
for (; candidates; candidates = candidates->next)
{
if (TREE_CODE (candidates->fn) == IDENTIFIER_NODE)
@@ -2032,8 +2055,10 @@ print_z_candidates (candidates)
cp_error ("%s %D(%T) <builtin>", str, candidates->fn,
TREE_TYPE (TREE_VEC_ELT (candidates->convs, 0)));
}
+ else if (TYPE_P (candidates->fn))
+ cp_error ("%s %T <conversion>", str, candidates->fn);
else
- cp_error_at ("%s %+D%s", str, candidates->fn,
+ cp_error_at ("%s %+#D%s", str, candidates->fn,
candidates->viable == -1 ? " <near match>" : "");
str = " ";
}
@@ -2117,7 +2142,7 @@ build_user_type_conversion_1 (totype, expr, flags)
if (TREE_CODE (totype) == REFERENCE_TYPE)
convflags |= LOOKUP_NO_TEMP_BIND;
- if (TREE_CODE (fns) != TEMPLATE_DECL)
+ if (TREE_CODE (OVL_CURRENT (fns)) != TEMPLATE_DECL)
ics = implicit_conversion
(totype, TREE_TYPE (TREE_TYPE (OVL_CURRENT (fns))), 0, convflags);
else
@@ -2255,26 +2280,6 @@ resolve_args (args)
}
else if (TREE_CODE (TREE_VALUE (t)) == OFFSET_REF)
TREE_VALUE (t) = resolve_offset_ref (TREE_VALUE (t));
- else if (TREE_CODE (TREE_VALUE (t)) == TEMPLATE_ID_EXPR)
- {
- tree targs;
- tree r;
-
- r = determine_specialization (TREE_VALUE (t), NULL_TREE,
- &targs,
- /*need_member_template=*/0,
- /*complain=*/0);
-
- /* If we figured out what was being specialized, use it.
- Otherwise, the function being called may resolve the
- choice of specialization, so we don't issue any error
- messages here. */
- if (r)
- {
- r = instantiate_template (r, targs);
- TREE_VALUE (t) = r;
- }
- }
}
return args;
}
@@ -2363,7 +2368,6 @@ build_object_call (obj, args)
struct z_candidate *candidates = 0, *cand;
tree fns, convs, mem_args = NULL_TREE;
tree type = TREE_TYPE (obj);
- tree templates = NULL_TREE;
if (TYPE_PTRMEMFUNC_P (type))
{
@@ -2393,7 +2397,6 @@ build_object_call (obj, args)
tree fn = OVL_CURRENT (fns);
if (TREE_CODE (fn) == TEMPLATE_DECL)
{
- templates = scratch_tree_cons (NULL_TREE, fn, templates);
candidates
= add_template_candidate (candidates, fn, NULL_TREE,
mem_args, NULL_TREE,
@@ -2415,14 +2418,14 @@ build_object_call (obj, args)
tree fns = TREE_VALUE (convs);
tree totype = TREE_TYPE (TREE_TYPE (OVL_CURRENT (fns)));
- if (TREE_CODE (totype) == POINTER_TYPE
+ if ((TREE_CODE (totype) == POINTER_TYPE
+ || TREE_CODE (totype) == REFERENCE_TYPE)
&& TREE_CODE (TREE_TYPE (totype)) == FUNCTION_TYPE)
for (; fns; fns = OVL_NEXT (fns))
{
tree fn = OVL_CURRENT (fns);
if (TREE_CODE (fn) == TEMPLATE_DECL)
{
- templates = scratch_tree_cons (NULL_TREE, fn, templates);
candidates = add_template_conv_candidate (candidates,
fn,
obj,
@@ -2467,9 +2470,9 @@ static void
op_error (code, code2, arg1, arg2, arg3, problem)
enum tree_code code, code2;
tree arg1, arg2, arg3;
- char *problem;
+ const char *problem;
{
- char * opname
+ const char * opname
= (code == MODIFY_EXPR ? assignop_tab [code2] : opname_tab [code]);
switch (code)
@@ -2533,73 +2536,10 @@ build_new_op (code, flags, arg1, arg2, arg3)
{
case NEW_EXPR:
case VEC_NEW_EXPR:
- {
- tree rval;
-
- arglist = scratch_tree_cons (NULL_TREE, arg2, arg3);
- if (flags & LOOKUP_GLOBAL)
- return build_new_function_call
- (lookup_function_nonclass (fnname, arglist), arglist);
-
- /* FIXME */
- rval = build_method_call
- (build_indirect_ref (build1 (NOP_EXPR, arg1, error_mark_node),
- "new"),
- fnname, arglist, NULL_TREE, flags);
- if (rval == error_mark_node)
- /* User might declare fancy operator new, but invoke it
- like standard one. */
- return rval;
-
- TREE_TYPE (rval) = arg1;
- return rval;
- }
-
case VEC_DELETE_EXPR:
case DELETE_EXPR:
- {
- tree rval;
-
- if (flags & LOOKUP_GLOBAL)
- {
- arglist = build_scratch_list (NULL_TREE, arg1);
- return build_new_function_call
- (lookup_function_nonclass (fnname, arglist), arglist);
- }
-
- arglist = scratch_tree_cons (NULL_TREE, arg1, build_scratch_list (NULL_TREE, arg2));
-
- arg1 = TREE_TYPE (arg1);
-
- /* This handles the case where we're trying to delete
- X (*a)[10];
- a=new X[5][10];
- delete[] a; */
-
- if (TREE_CODE (TREE_TYPE (arg1)) == ARRAY_TYPE)
- {
- /* Strip off the pointer and the array. */
- arg1 = TREE_TYPE (TREE_TYPE (arg1));
-
- while (TREE_CODE (arg1) == ARRAY_TYPE)
- arg1 = (TREE_TYPE (arg1));
-
- arg1 = build_pointer_type (arg1);
- }
-
- /* FIXME */
- rval = build_method_call
- (build_indirect_ref (build1 (NOP_EXPR, arg1,
- error_mark_node),
- NULL_PTR),
- fnname, arglist, NULL_TREE, flags);
-#if 0
- /* This can happen when operator delete is protected. */
- my_friendly_assert (rval != error_mark_node, 250);
- TREE_TYPE (rval) = void_type_node;
-#endif
- return rval;
- }
+ /* Use build_op_new_call and build_op_delete_call instead. */
+ my_friendly_abort (981018);
case CALL_EXPR:
return build_object_call (arg1, arg2);
@@ -2918,10 +2858,8 @@ build_op_new_call (code, type, args, flags)
if (IS_AGGR_TYPE (type) && ! (flags & LOOKUP_GLOBAL)
&& (TYPE_GETS_NEW (type) & (1 << (code == VEC_NEW_EXPR))))
{
- tree dummy = build1 (NOP_EXPR, build_pointer_type (type),
- error_mark_node);
- dummy = build_indirect_ref (dummy, "new");
- return build_method_call (dummy, fnname, args, NULL_TREE, flags);
+ return build_method_call (build_dummy_object (type),
+ fnname, args, NULL_TREE, flags);
}
else
return build_new_function_call
@@ -3000,11 +2938,6 @@ build_op_delete_call (code, addr, size, flags, placement)
if (type != TYPE_MAIN_VARIANT (type))
addr = cp_convert (build_pointer_type (TYPE_MAIN_VARIANT (type)), addr);
- /* instantiate_type will always return a plain function; pretend it's
- overloaded. */
- if (TREE_CODE (fns) == FUNCTION_DECL)
- fns = scratch_ovl_cons (fns, NULL_TREE);
-
fn = instantiate_type (fntype, fns, 0);
if (fn != error_mark_node)
@@ -3048,28 +2981,30 @@ build_op_delete_call (code, addr, size, flags, placement)
}
/* If the current scope isn't allowed to access DECL along
- BASETYPE_PATH, give an error. */
+ BASETYPE_PATH, give an error. The most derived class in
+ BASETYPE_PATH is the one used to qualify DECL. */
-void
+int
enforce_access (basetype_path, decl)
- tree basetype_path, decl;
+ tree basetype_path;
+ tree decl;
{
- tree access = compute_access (basetype_path, decl);
+ int accessible;
- if (access == access_private_node)
- {
- cp_error_at ("`%+#D' is %s", decl,
- TREE_PRIVATE (decl) ? "private"
- : "from private base class");
- error ("within this context");
- }
- else if (access == access_protected_node)
+ accessible = accessible_p (basetype_path, decl);
+ if (!accessible)
{
- cp_error_at ("`%+#D' %s", decl,
- TREE_PROTECTED (decl) ? "is protected"
- : "has protected accessibility");
- error ("within this context");
+ if (TREE_PRIVATE (decl))
+ cp_error_at ("`%+#D' is private", decl);
+ else if (TREE_PROTECTED (decl))
+ cp_error_at ("`%+#D' is protected", decl);
+ else
+ cp_error_at ("`%+#D' is inaccessible", decl);
+ cp_error ("within this context");
+ return 0;
}
+
+ return 1;
}
/* Perform the conversions in CONVS on the expression EXPR. */
@@ -3168,7 +3103,7 @@ convert_like (convs, expr)
destination type takes a pointer argument. */
if (TYPE_SIZE (TREE_TYPE (expr)) == 0)
{
- if (comptypes (TREE_TYPE (expr), TREE_TYPE (convs), 1))
+ if (same_type_p (TREE_TYPE (expr), TREE_TYPE (convs)))
incomplete_type_error (expr, TREE_TYPE (expr));
else
cp_error ("could not convert `%E' (with incomplete type `%T') to `%T'",
@@ -3222,17 +3157,47 @@ convert_arg_to_ellipsis (arg)
/* Convert `short' and `char' to full-size `int'. */
arg = default_conversion (arg);
+ arg = require_complete_type (arg);
+
return arg;
}
/* ARG is a default argument expression being passed to a parameter of
- the indicated TYPE. Do any required conversions. Return the
- converted value. */
+ the indicated TYPE, which is a parameter to FN. Do any required
+ conversions. Return the converted value. */
tree
-convert_default_arg (type, arg)
- tree type, arg;
+convert_default_arg (type, arg, fn)
+ tree type;
+ tree arg;
+ tree fn;
{
+ if (fn && DECL_TEMPLATE_INFO (fn))
+ {
+ /* This default argument came from a template. Instantiate the
+ default argument here, not in tsubst. In the case of
+ something like:
+
+ template <class T>
+ struct S {
+ static T t();
+ void f(T = t());
+ };
+
+ we must be careful to do name lookup in the scope of S<T>,
+ rather than in the current class. */
+ if (DECL_CLASS_SCOPE_P (fn))
+ pushclass (DECL_REAL_CONTEXT (fn), 2);
+
+ arg = tsubst_expr (arg, DECL_TI_ARGS (fn), /*complain=*/1, NULL_TREE);
+
+ if (DECL_CLASS_SCOPE_P (fn))
+ popclass (1);
+
+ /* Make sure the default argument is reasonable. */
+ arg = check_default_argument (type, arg);
+ }
+
arg = break_out_target_exprs (arg);
if (TREE_CODE (arg) == CONSTRUCTOR)
@@ -3308,17 +3273,9 @@ build_over_call (cand, args, flags)
tree argtype = TREE_TYPE (TREE_VALUE (arg));
tree t;
if (ICS_BAD_FLAG (TREE_VEC_ELT (convs, i)))
- {
- int dv = (TYPE_VOLATILE (TREE_TYPE (parmtype))
- < TYPE_VOLATILE (TREE_TYPE (argtype)));
- int dc = (TYPE_READONLY (TREE_TYPE (parmtype))
- < TYPE_READONLY (TREE_TYPE (argtype)));
- char *p = (dv && dc ? "const and volatile"
- : dc ? "const" : dv ? "volatile" : "");
-
- cp_error ("passing `%T' as `this' argument of `%#D' discards %s",
- TREE_TYPE (argtype), fn, p);
- }
+ cp_pedwarn ("passing `%T' as `this' argument of `%#D' discards qualifiers",
+ TREE_TYPE (argtype), fn);
+
/* [class.mfct.nonstatic]: If a nonstatic member function of a class
X is called for an object that is not of type X, or of a type
derived from X, the behavior is undefined.
@@ -3384,34 +3341,12 @@ build_over_call (cand, args, flags)
/* Default arguments */
for (; parm && parm != void_list_node; parm = TREE_CHAIN (parm))
- {
- tree arg = TREE_PURPOSE (parm);
-
- if (DECL_TEMPLATE_INFO (fn))
- {
- /* This came from a template. Instantiate the default arg here,
- not in tsubst. In the case of something like:
-
- template <class T>
- struct S {
- static T t();
- void f(T = t());
- };
-
- we must be careful to do name lookup in the scope of
- S<T>, rather than in the current class. */
- if (DECL_CLASS_SCOPE_P (fn))
- pushclass (DECL_REAL_CONTEXT (fn), 2);
-
- arg = tsubst_expr (arg, DECL_TI_ARGS (fn), NULL_TREE);
-
- if (DECL_CLASS_SCOPE_P (fn))
- popclass (1);
- }
- converted_args = expr_tree_cons
- (NULL_TREE, convert_default_arg (TREE_VALUE (parm), arg),
- converted_args);
- }
+ converted_args
+ = expr_tree_cons (NULL_TREE,
+ convert_default_arg (TREE_VALUE (parm),
+ TREE_PURPOSE (parm),
+ fn),
+ converted_args);
/* Ellipsis */
for (; arg; arg = TREE_CHAIN (arg))
@@ -3422,6 +3357,10 @@ build_over_call (cand, args, flags)
converted_args = nreverse (converted_args);
+ if (warn_format && (DECL_NAME (fn) || DECL_ASSEMBLER_NAME (fn)))
+ check_function_format (DECL_NAME (fn), DECL_ASSEMBLER_NAME (fn),
+ converted_args);
+
/* Avoid actually calling copy constructors and copy assignment operators,
if possible. */
@@ -3446,8 +3385,8 @@ build_over_call (cand, args, flags)
if (TREE_CODE (targ) == ADDR_EXPR)
{
targ = TREE_OPERAND (targ, 0);
- if (! comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (arg))),
- TYPE_MAIN_VARIANT (TREE_TYPE (targ)), 1))
+ if (!same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (arg))),
+ TYPE_MAIN_VARIANT (TREE_TYPE (targ))))
targ = NULL_TREE;
}
else
@@ -3474,8 +3413,7 @@ build_over_call (cand, args, flags)
return arg;
else if (TYPE_HAS_TRIVIAL_INIT_REF (DECL_CONTEXT (fn)))
{
- val = build (VAR_DECL, DECL_CONTEXT (fn));
- layout_decl (val, 0);
+ val = build_decl (VAR_DECL, NULL_TREE, DECL_CONTEXT (fn));
val = build (TARGET_EXPR, DECL_CONTEXT (fn), val, arg, 0, 0);
TREE_SIDE_EFFECTS (val) = 1;
return val;
@@ -3561,7 +3499,7 @@ build_over_call (cand, args, flags)
}
fn = build_call (fn, TREE_TYPE (TREE_TYPE (TREE_TYPE (fn))), converted_args);
- if (TREE_TYPE (fn) == void_type_node)
+ if (TREE_CODE (TREE_TYPE (fn)) == VOID_TYPE)
return fn;
fn = require_complete_type (fn);
if (IS_AGGR_TYPE (TREE_TYPE (fn)))
@@ -3733,11 +3671,10 @@ build_new_method_call (instance, name, args, basetype_path, flags)
&& instance == current_class_ref
&& DECL_CONSTRUCTOR_P (current_function_decl)
&& ! (flags & LOOKUP_NONVIRTUAL)
- && value_member (cand->fn, get_abstract_virtuals (basetype)))
+ && value_member (cand->fn, CLASSTYPE_ABSTRACT_VIRTUALS (basetype)))
cp_error ("abstract virtual `%#D' called from constructor", cand->fn);
if (TREE_CODE (TREE_TYPE (cand->fn)) == METHOD_TYPE
- && TREE_CODE (instance_ptr) == NOP_EXPR
- && TREE_OPERAND (instance_ptr, 0) == error_mark_node)
+ && is_dummy_object (instance_ptr))
cp_error ("cannot call member function `%D' without object", cand->fn);
if (DECL_VINDEX (cand->fn) && ! (flags & LOOKUP_NONVIRTUAL)
@@ -3791,9 +3728,9 @@ is_subseq (ics1, ics2)
ics2 = TREE_OPERAND (ics2, 0);
if (TREE_CODE (ics2) == TREE_CODE (ics1)
- && comptypes (TREE_TYPE (ics2), TREE_TYPE (ics1), 1)
- && comptypes (TREE_TYPE (TREE_OPERAND (ics2, 0)),
- TREE_TYPE (TREE_OPERAND (ics1, 0)), 1))
+ && same_type_p (TREE_TYPE (ics2), TREE_TYPE (ics1))
+ && same_type_p (TREE_TYPE (TREE_OPERAND (ics2, 0)),
+ TREE_TYPE (TREE_OPERAND (ics1, 0))))
return 1;
}
}
@@ -3812,8 +3749,8 @@ is_properly_derived_from (derived, base)
/* We only allow proper derivation here. The DERIVED_FROM_P macro
considers every class derived from itself. */
- return (!comptypes (TYPE_MAIN_VARIANT (derived),
- TYPE_MAIN_VARIANT (base), 1)
+ return (!same_type_p (TYPE_MAIN_VARIANT (derived),
+ TYPE_MAIN_VARIANT (base))
&& DERIVED_FROM_P (base, derived));
}
@@ -4026,7 +3963,7 @@ compare_ics (ics1, ics2)
from_type2 = TREE_TYPE (from_type2);
}
- if (comptypes (from_type1, from_type2, 1))
+ if (same_type_p (from_type1, from_type2))
{
if (is_subseq (ics1, ics2))
return 1;
@@ -4126,7 +4063,7 @@ compare_ics (ics1, ics2)
else if (TREE_CODE (deref_to_type1) == VOID_TYPE
|| TREE_CODE (deref_to_type2) == VOID_TYPE)
{
- if (comptypes (deref_from_type1, deref_from_type2, 1))
+ if (same_type_p (deref_from_type1, deref_from_type2))
{
if (TREE_CODE (deref_to_type2) == VOID_TYPE)
{
@@ -4153,7 +4090,7 @@ compare_ics (ics1, ics2)
--conversion of B* to A* is better than conversion of C* to
A* */
- if (comptypes (deref_from_type1, deref_from_type2, 1))
+ if (same_type_p (deref_from_type1, deref_from_type2))
{
if (is_properly_derived_from (deref_to_type1,
deref_to_type2))
@@ -4162,7 +4099,7 @@ compare_ics (ics1, ics2)
deref_to_type1))
return -1;
}
- else if (comptypes (deref_to_type1, deref_to_type2, 1))
+ else if (same_type_p (deref_to_type1, deref_to_type2))
{
if (is_properly_derived_from (deref_from_type2,
deref_from_type1))
@@ -4174,7 +4111,7 @@ compare_ics (ics1, ics2)
}
}
else if (IS_AGGR_TYPE_CODE (TREE_CODE (from_type1))
- && comptypes (from_type1, from_type2, 1))
+ && same_type_p (from_type1, from_type2))
{
/* [over.ics.rank]
@@ -4193,7 +4130,7 @@ compare_ics (ics1, ics2)
}
}
else if (IS_AGGR_TYPE_CODE (TREE_CODE (to_type1))
- && comptypes (to_type1, to_type2, 1))
+ && same_type_p (to_type1, to_type2))
{
/* [over.ics.rank]
@@ -4220,7 +4157,7 @@ compare_ics (ics1, ics2)
qualification signature of type T2 */
if (TREE_CODE (ics1) == QUAL_CONV
&& TREE_CODE (ics2) == QUAL_CONV
- && comptypes (from_type1, from_type2, 1))
+ && same_type_p (from_type1, from_type2))
return comp_cv_qual_signature (to_type1, to_type2);
/* [over.ics.rank]
@@ -4232,8 +4169,8 @@ compare_ics (ics1, ics2)
which the reference initialized by S1 refers */
if (ref_binding1 && ref_binding2
- && comptypes (TYPE_MAIN_VARIANT (to_type1),
- TYPE_MAIN_VARIANT (to_type2), 1))
+ && same_type_p (TYPE_MAIN_VARIANT (to_type1),
+ TYPE_MAIN_VARIANT (to_type2)))
return comp_cv_qualification (target_type2, target_type1);
/* Neither conversion sequence is better than the other. */
@@ -4291,6 +4228,11 @@ joust (cand1, cand2, warn)
if (cand1->viable < cand2->viable)
return -1;
+ /* If we have two pseudo-candidates for conversions to the same type,
+ arbitrarily pick one. */
+ if (TYPE_P (cand1->fn) && cand1->fn == cand2->fn)
+ return 1;
+
/* a viable function F1
is defined to be a better function than another viable function F2 if
for all arguments i, ICSi(F1) is not a worse conversion sequence than
@@ -4376,8 +4318,8 @@ joust (cand1, cand2, warn)
!= DECL_CONSTRUCTOR_P (cand2->fn))
/* Don't warn if the two conv ops convert to the same type... */
|| (! DECL_CONSTRUCTOR_P (cand1->fn)
- && ! comptypes (TREE_TYPE (cand1->second_conv),
- TREE_TYPE (cand2->second_conv), 1))))
+ && ! same_type_p (TREE_TYPE (cand1->second_conv),
+ TREE_TYPE (cand2->second_conv)))))
{
int comp = compare_ics (cand1->second_conv, cand2->second_conv);
if (comp != winner)
@@ -4433,8 +4375,8 @@ joust (cand1, cand2, warn)
&& TREE_CODE (cand1->fn) == IDENTIFIER_NODE)
{
for (i = 0; i < len; ++i)
- if (! comptypes (TREE_TYPE (TREE_VEC_ELT (cand1->convs, i)),
- TREE_TYPE (TREE_VEC_ELT (cand2->convs, i)), 1))
+ if (!same_type_p (TREE_TYPE (TREE_VEC_ELT (cand1->convs, i)),
+ TREE_TYPE (TREE_VEC_ELT (cand2->convs, i))))
break;
if (i == TREE_VEC_LENGTH (cand1->convs))
return 1;
@@ -4449,7 +4391,7 @@ joust (cand1, cand2, warn)
tree t1 = strip_top_quals (non_reference (TREE_TYPE (c1)));
tree t2 = strip_top_quals (non_reference (TREE_TYPE (c2)));
- if (comptypes (t1, t2, 1))
+ if (same_type_p (t1, t2))
{
if (TREE_CODE (c1) == REF_BIND && TREE_CODE (c2) != REF_BIND)
return 1;
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index cd16b59c97e..a4daed214be 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -1,5 +1,5 @@
/* Functions related to building classes and their related objects.
- Copyright (C) 1987, 92, 93, 94, 95, 96, 1997 Free Software Foundation, Inc.
+ Copyright (C) 1987, 92-97, 1998, 1999 Free Software Foundation, Inc.
Contributed by Michael Tiemann (tiemann@cygnus.com)
This file is part of GNU CC.
@@ -82,6 +82,12 @@ tree previous_class_type; /* _TYPE: the previous type that was a class */
tree previous_class_values; /* TREE_LIST: copy of the class_shadowed list
when leaving an outermost class scope. */
+/* The obstack on which the cached class declarations are kept. */
+static struct obstack class_cache_obstack;
+/* The first object allocated on that obstack. We can use
+ obstack_free with tis value to free the entire obstack. */
+static char *class_cache_firstobj;
+
struct base_info;
static tree get_vfield_name PROTO((tree));
@@ -128,6 +134,10 @@ static void check_member_decl_is_same_in_complete_scope PROTO((tree, tree));
static tree make_method_vec PROTO((int));
static void free_method_vec PROTO((tree));
static tree add_implicitly_declared_members PROTO((tree, int, int, int));
+static tree fixed_type_or_null PROTO((tree, int *));
+static tree resolve_address_of_overloaded_function PROTO((tree, tree, int,
+ int, tree));
+static void build_vtable_entry_ref PROTO((tree, tree, tree));
/* Way of stacking language names. */
tree *current_lang_base, *current_lang_stack;
@@ -598,7 +608,7 @@ get_vtable_name (type)
tree type_id = build_typename_overload (type);
char *buf = (char *) alloca (strlen (VTABLE_NAME_FORMAT)
+ IDENTIFIER_LENGTH (type_id) + 2);
- char *ptr = IDENTIFIER_POINTER (type_id);
+ const char *ptr = IDENTIFIER_POINTER (type_id);
int i;
for (i = 0; ptr[i] == OPERATOR_TYPENAME_FORMAT[i]; i++) ;
#if 0
@@ -717,7 +727,7 @@ build_vtable (binfo, type)
#endif
/* Set TREE_PUBLIC and TREE_EXTERN as appropriate. */
- import_export_vtable (decl, type, at_eof);
+ import_export_vtable (decl, type, 0);
decl = pushdecl_top_level (decl);
SET_IDENTIFIER_GLOBAL_VALUE (name, decl);
@@ -901,7 +911,7 @@ prepare_fresh_vtable (binfo, for_type)
#endif
/* Set TREE_PUBLIC and TREE_EXTERN as appropriate. */
- import_export_vtable (new_decl, for_type, at_eof);
+ import_export_vtable (new_decl, for_type, 0);
if (TREE_VIA_VIRTUAL (binfo))
my_friendly_assert (binfo == binfo_member (BINFO_TYPE (binfo),
@@ -1091,7 +1101,7 @@ make_method_vec (n)
new_vec = *t;
*t = TREE_CHAIN (new_vec);
TREE_CHAIN (new_vec) = NULL_TREE;
- bzero (&TREE_VEC_ELT (new_vec, 0), n * sizeof (tree));
+ bzero ((PTR) &TREE_VEC_ELT (new_vec, 0), n * sizeof (tree));
return new_vec;
}
@@ -1109,12 +1119,10 @@ free_method_vec (vec)
free_method_vecs = vec;
}
-/* Add method METHOD to class TYPE. This is used when a method
- has been defined which did not initially appear in the class definition,
- and helps cut down on spurious error messages.
+/* Add method METHOD to class TYPE.
- FIELDS is the entry in the METHOD_VEC vector entry of the class type where
- the method should be added. */
+ If non-NULL, FIELDS is the entry in the METHOD_VEC vector entry of
+ the class type where the method should be added. */
void
add_method (type, fields, method)
@@ -1132,6 +1140,7 @@ add_method (type, fields, method)
else
{
int len;
+ int slot;
tree method_vec;
if (!CLASSTYPE_METHOD_VEC (type))
@@ -1153,39 +1162,32 @@ add_method (type, fields, method)
len = TREE_VEC_LENGTH (method_vec);
if (DECL_NAME (method) == constructor_name (type))
- {
- /* A new constructor or destructor. Constructors go in
- slot 0; destructors go in slot 1. */
- int slot
- = DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (method)) ? 1 : 0;
-
- TREE_VEC_ELT (method_vec, slot)
- = build_overload (method, TREE_VEC_ELT (method_vec, slot));
- }
+ /* A new constructor or destructor. Constructors go in
+ slot 0; destructors go in slot 1. */
+ slot = DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (method)) ? 1 : 0;
else
{
- int i;
-
/* See if we already have an entry with this name. */
- for (i = 2; i < len; ++i)
- if (!TREE_VEC_ELT (method_vec, i)
- || (DECL_NAME (OVL_CURRENT (TREE_VEC_ELT (method_vec, i)))
+ for (slot = 2; slot < len; ++slot)
+ if (!TREE_VEC_ELT (method_vec, slot)
+ || (DECL_NAME (OVL_CURRENT (TREE_VEC_ELT (method_vec,
+ slot)))
== DECL_NAME (method)))
break;
- if (i == len)
+ if (slot == len)
{
/* We need a bigger method vector. */
tree new_vec = make_method_vec (2 * len);
- bcopy (&TREE_VEC_ELT (method_vec, 0),
- &TREE_VEC_ELT (new_vec, 0),
+ bcopy ((PTR) &TREE_VEC_ELT (method_vec, 0),
+ (PTR) &TREE_VEC_ELT (new_vec, 0),
len * sizeof (tree));
free_method_vec (method_vec);
len = 2 * len;
method_vec = CLASSTYPE_METHOD_VEC (type) = new_vec;
}
- if (IDENTIFIER_TYPENAME_P (DECL_NAME (method)))
+ if (DECL_CONV_FN_P (method) && !TREE_VEC_ELT (method_vec, slot))
{
/* Type conversion operators have to come before
ordinary methods; add_conversions depends on this to
@@ -1193,44 +1195,107 @@ add_method (type, fields, method)
necessary, we slide some of the vector elements up.
In theory, this makes this algorithm O(N^2) but we
don't expect many conversion operators. */
- for (i = 2; i < len; ++i)
+ for (slot = 2; slot < len; ++slot)
{
- tree fn = TREE_VEC_ELT (method_vec, i);
- tree name;
-
+ tree fn = TREE_VEC_ELT (method_vec, slot);
+
if (!fn)
/* There are no more entries in the vector, so we
can insert the new conversion operator here. */
break;
-
- name = DECL_NAME (OVL_CURRENT (fn));
- if (!IDENTIFIER_TYPENAME_P (name))
- /* We can insert the new function right at the Ith
- position. */
+
+ if (!DECL_CONV_FN_P (OVL_CURRENT (fn)))
+ /* We can insert the new function right at the
+ SLOTth position. */
break;
}
-
- if (!TREE_VEC_ELT (method_vec, i))
+
+ if (!TREE_VEC_ELT (method_vec, slot))
/* There is nothing in the Ith slot, so we can avoid
moving anything. */
;
else
{
/* We know the last slot in the vector is empty
- because we know that at this point there's room for
- a new function. */
- bcopy (&TREE_VEC_ELT (method_vec, i),
- &TREE_VEC_ELT (method_vec, i + 1),
- (len - i - 1) * sizeof (tree));
- TREE_VEC_ELT (method_vec, i) = NULL_TREE;
+ because we know that at this point there's room
+ for a new function. */
+ bcopy ((PTR) &TREE_VEC_ELT (method_vec, slot),
+ (PTR) &TREE_VEC_ELT (method_vec, slot + 1),
+ (len - slot - 1) * sizeof (tree));
+ TREE_VEC_ELT (method_vec, slot) = NULL_TREE;
}
}
-
- /* Actually insert the new method. */
- TREE_VEC_ELT (method_vec, i)
- = build_overload (method, TREE_VEC_ELT (method_vec, i));
}
+ if (template_class_depth (type))
+ /* TYPE is a template class. Don't issue any errors now; wait
+ until instantiation time to complain. */
+ ;
+ else
+ {
+ tree fns;
+
+ /* Check to see if we've already got this method. */
+ for (fns = TREE_VEC_ELT (method_vec, slot);
+ fns;
+ fns = OVL_NEXT (fns))
+ {
+ tree fn = OVL_CURRENT (fns);
+
+ if (TREE_CODE (fn) != TREE_CODE (method))
+ continue;
+
+ if (TREE_CODE (method) != TEMPLATE_DECL)
+ {
+ /* [over.load] Member function declarations with the
+ same name and the same parameter types cannot be
+ overloaded if any of them is a static member
+ function declaration. */
+ if (DECL_STATIC_FUNCTION_P (fn)
+ != DECL_STATIC_FUNCTION_P (method))
+ {
+ tree parms1 = TYPE_ARG_TYPES (TREE_TYPE (fn));
+ tree parms2 = TYPE_ARG_TYPES (TREE_TYPE (method));
+
+ if (! DECL_STATIC_FUNCTION_P (fn))
+ parms1 = TREE_CHAIN (parms1);
+ else
+ parms2 = TREE_CHAIN (parms2);
+
+ if (compparms (parms1, parms2))
+ cp_error ("`%#D' and `%#D' cannot be overloaded",
+ fn, method);
+ }
+
+ /* Since this is an ordinary function in a
+ non-template class, it's mangled name can be used
+ as a unique identifier. This technique is only
+ an optimization; we would get the same results if
+ we just used decls_match here. */
+ if (DECL_ASSEMBLER_NAME (fn)
+ != DECL_ASSEMBLER_NAME (method))
+ continue;
+ }
+ else if (!decls_match (fn, method))
+ continue;
+
+ /* There has already been a declaration of this method
+ or member template. */
+ cp_error_at ("`%D' has already been declared in `%T'",
+ method, type);
+
+ /* We don't call duplicate_decls here to merge the
+ declarations because that will confuse things if the
+ methods have inline definitions In particular, we
+ will crash while processing the definitions. */
+ return;
+ }
+ }
+
+ /* Actually insert the new method. */
+ TREE_VEC_ELT (method_vec, slot)
+ = build_overload (method, TREE_VEC_ELT (method_vec, slot));
+
if (TYPE_BINFO_BASETYPES (type) && CLASSTYPE_BASELINK_VEC (type))
{
/* ??? May be better to know whether these can be extended? */
@@ -1309,7 +1374,7 @@ delete_duplicate_fields_1 (field, fields)
else if (DECL_DECLARES_TYPE_P (field)
&& DECL_DECLARES_TYPE_P (x))
{
- if (comptypes (TREE_TYPE (field), TREE_TYPE (x), 1))
+ if (same_type_p (TREE_TYPE (field), TREE_TYPE (x)))
continue;
cp_error_at ("duplicate nested type `%D'", x);
}
@@ -1379,7 +1444,6 @@ alter_access (t, binfo, fdecl, access)
else
{
enforce_access (binfo, fdecl);
-
DECL_ACCESS (fdecl) = tree_cons (t, access, DECL_ACCESS (fdecl));
return 1;
}
@@ -1387,10 +1451,9 @@ alter_access (t, binfo, fdecl, access)
}
/* Process the USING_DECL, which is a member of T. The METHOD_VEC, if
- non-NULL, is the methods of T. The FIELDS are the fields of T.
- Returns 1 if the USING_DECL was valid, 0 otherwise. */
+ non-NULL, is the methods of T. The FIELDS are the fields of T. */
-void
+static void
handle_using_decl (using_decl, t, method_vec, fields)
tree using_decl;
tree t;
@@ -1415,8 +1478,11 @@ handle_using_decl (using_decl, t, method_vec, fields)
if (name == constructor_name (ctype)
|| name == constructor_name_full (ctype))
- cp_error_at ("using-declaration for constructor", using_decl);
-
+ {
+ cp_error_at ("using-declaration for constructor", using_decl);
+ return;
+ }
+
fdecl = lookup_member (binfo, name, 0, 0);
if (!fdecl)
@@ -1894,24 +1960,15 @@ finish_struct_bits (t, max_has_virtual)
if (n_baseclasses && max_has_virtual)
{
- /* Done by `finish_struct' for classes without baseclasses. */
- int might_have_abstract_virtuals = CLASSTYPE_ABSTRACT_VIRTUALS (t) != 0;
- tree binfos = TYPE_BINFO_BASETYPES (t);
- for (i = n_baseclasses-1; i >= 0; i--)
- {
- might_have_abstract_virtuals
- |= (CLASSTYPE_ABSTRACT_VIRTUALS (BINFO_TYPE (TREE_VEC_ELT (binfos, i))) != 0);
- if (might_have_abstract_virtuals)
- break;
- }
- if (might_have_abstract_virtuals)
- {
- /* We use error_mark_node from override_one_vtable to signal
- an artificial abstract. */
- if (CLASSTYPE_ABSTRACT_VIRTUALS (t) == error_mark_node)
- CLASSTYPE_ABSTRACT_VIRTUALS (t) = NULL_TREE;
- CLASSTYPE_ABSTRACT_VIRTUALS (t) = get_abstract_virtuals (t);
- }
+ /* for a class w/o baseclasses, `finish_struct' has set
+ * CLASS_TYPE_ABSTRACT_VIRTUALS correctly (by definition). Similarly
+ * for a class who's base classes do not have vtables. When neither of
+ * these is true, we might have removed abstract virtuals (by
+ * providing a definition), added some (by declaring new ones), or
+ * redeclared ones from a base class. We need to recalculate what's
+ * really an abstract virtual at this point (by looking in the vtables).
+ */
+ CLASSTYPE_ABSTRACT_VIRTUALS (t) = get_abstract_virtuals (t);
}
if (n_baseclasses)
@@ -2013,12 +2070,18 @@ maybe_warn_about_overly_private_class (t)
has_nonprivate_method = 1;
break;
}
- else
+ else if (!DECL_CONSTRUCTOR_P (fn) && !DECL_DESTRUCTOR_P (fn))
has_member_fn = 1;
}
if (!has_nonprivate_method && has_member_fn)
{
+ /* There are no non-private methods, and there's at least one
+ private member function that isn't a constructor or
+ destructor. (If all the private members are
+ constructors/destructors we want to use the code below that
+ issues error messages specifically referring to
+ constructors/destructors.) */
int i;
tree binfos = BINFO_BASETYPES (TYPE_BINFO (t));
for (i = 0; i < CLASSTYPE_N_BASECLASSES (t); i++)
@@ -2337,9 +2400,9 @@ overrides (fndecl, base_fndecl)
#endif
types = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
base_types = TYPE_ARG_TYPES (TREE_TYPE (base_fndecl));
- if ((TYPE_READONLY (TREE_TYPE (TREE_VALUE (base_types)))
- == TYPE_READONLY (TREE_TYPE (TREE_VALUE (types))))
- && compparms (TREE_CHAIN (base_types), TREE_CHAIN (types), 3))
+ if ((TYPE_QUALS (TREE_TYPE (TREE_VALUE (base_types)))
+ == TYPE_QUALS (TREE_TYPE (TREE_VALUE (types))))
+ && compparms (TREE_CHAIN (base_types), TREE_CHAIN (types)))
return 1;
}
return 0;
@@ -2804,13 +2867,11 @@ override_one_vtable (binfo, old, t)
}
{
/* This MUST be overridden, or the class is ill-formed. */
- /* For now, we just make it abstract. */
tree fndecl = TREE_OPERAND (FNADDR_FROM_VTABLE_ENTRY (TREE_VALUE (virtuals)), 0);
tree vfn;
fndecl = copy_node (fndecl);
copy_lang_decl (fndecl);
- DECL_ABSTRACT_VIRTUAL_P (fndecl) = 1;
DECL_NEEDS_FINAL_OVERRIDER_P (fndecl) = 1;
/* Make sure we search for it later. */
if (! CLASSTYPE_ABSTRACT_VIRTUALS (t))
@@ -2933,6 +2994,7 @@ check_for_override (decl, ctype)
tree binfos = BINFO_BASETYPES (TYPE_BINFO (ctype));
int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;
int virtualp = DECL_VIRTUAL_P (decl);
+ int found_overriden_fn = 0;
for (i = 0; i < n_baselinks; i++)
{
@@ -2942,7 +3004,8 @@ check_for_override (decl, ctype)
tree tmp = get_matching_virtual
(base_binfo, decl,
DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (decl)));
- if (tmp)
+
+ if (tmp && !found_overriden_fn)
{
/* If this function overrides some virtual in some base
class, then the function itself is also necessarily
@@ -2963,26 +3026,15 @@ check_for_override (decl, ctype)
}
virtualp = 1;
-#if 0 /* The signature of an overriding function is not changed. */
- {
- /* The argument types may have changed... */
- tree type = TREE_TYPE (decl);
- tree argtypes = TYPE_ARG_TYPES (type);
- tree base_variant = TREE_TYPE (TREE_VALUE (argtypes));
- tree raises = TYPE_RAISES_EXCEPTIONS (type);
-
- argtypes = commonparms (TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (tmp))),
- TREE_CHAIN (argtypes));
- /* But the return type has not. */
- type = build_cplus_method_type (base_variant, TREE_TYPE (type), argtypes);
- if (raises)
- type = build_exception_variant (type, raises);
- TREE_TYPE (decl) = type;
- }
-#endif
DECL_VINDEX (decl)
= tree_cons (NULL_TREE, tmp, DECL_VINDEX (decl));
- break;
+
+ /* We now know that DECL overrides something,
+ which is all that is important. But, we must
+ continue to iterate through all the base-classes
+ in order to allow get_matching_virtual to check for
+ various illegal overrides. */
+ found_overriden_fn = 1;
}
}
}
@@ -3088,9 +3140,20 @@ finish_struct_anon (t)
tree* uelt = &TYPE_FIELDS (TREE_TYPE (field));
for (; *uelt; uelt = &TREE_CHAIN (*uelt))
{
- if (TREE_CODE (*uelt) != FIELD_DECL)
+ if (DECL_ARTIFICIAL (*uelt))
continue;
+ if (DECL_NAME (*uelt) == constructor_name (t))
+ cp_pedwarn_at ("ANSI C++ forbids member `%D' with same name as enclosing class",
+ *uelt);
+
+ if (TREE_CODE (*uelt) != FIELD_DECL)
+ {
+ cp_pedwarn_at ("`%#D' invalid; an anonymous union can only have non-static data members",
+ *uelt);
+ continue;
+ }
+
if (TREE_PRIVATE (*uelt))
cp_pedwarn_at ("private member `%#D' in anonymous union",
*uelt);
@@ -3238,6 +3301,7 @@ finish_struct_1 (t, warn_anon)
int cant_have_default_ctor;
int cant_have_const_ctor;
int no_const_asn_ref;
+ int has_mutable = 0;
/* The index of the first base class which has virtual
functions. Only applied to non-virtual baseclasses. */
@@ -3390,7 +3454,11 @@ finish_struct_1 (t, warn_anon)
if (TREE_CODE (x) == FIELD_DECL)
{
DECL_PACKED (x) |= TYPE_PACKED (t);
- empty = 0;
+
+ if (DECL_C_BIT_FIELD (x) && integer_zerop (DECL_INITIAL (x)))
+ /* A zero-width bitfield doesn't do the trick. */;
+ else
+ empty = 0;
}
if (TREE_CODE (x) == USING_DECL)
@@ -3496,6 +3564,9 @@ finish_struct_1 (t, warn_anon)
if (TREE_CODE (TREE_TYPE (x)) == POINTER_TYPE)
has_pointers = 1;
+ if (DECL_MUTABLE_P (x) || TYPE_HAS_MUTABLE_P (TREE_TYPE (x)))
+ has_mutable = 1;
+
/* If any field is const, the structure type is pseudo-const. */
if (TREE_READONLY (x))
{
@@ -3535,12 +3606,10 @@ finish_struct_1 (t, warn_anon)
}
}
- /* We set DECL_BIT_FIELD tentatively in grokbitfield.
- If the type and width are valid, we'll keep it set.
- Otherwise, the flag is cleared. */
- if (DECL_BIT_FIELD (x))
+ /* We set DECL_C_BIT_FIELD in grokbitfield.
+ If the type and width are valid, we'll also set DECL_BIT_FIELD. */
+ if (DECL_C_BIT_FIELD (x))
{
- DECL_BIT_FIELD (x) = 0;
/* Invalid bit-field size done by grokfield. */
/* Detect invalid bit-field type. */
if (DECL_INITIAL (x)
@@ -3608,23 +3677,24 @@ finish_struct_1 (t, warn_anon)
x, TREE_TYPE (x));
}
- if (DECL_INITIAL (x) == NULL_TREE)
- ;
- else if (width == 0)
+ if (DECL_INITIAL (x))
{
+ DECL_INITIAL (x) = NULL_TREE;
+ DECL_FIELD_SIZE (x) = width;
+ DECL_BIT_FIELD (x) = 1;
+
+ if (width == 0)
+ {
#ifdef EMPTY_FIELD_BOUNDARY
- DECL_ALIGN (x) = MAX (DECL_ALIGN (x), EMPTY_FIELD_BOUNDARY);
+ DECL_ALIGN (x) = MAX (DECL_ALIGN (x),
+ EMPTY_FIELD_BOUNDARY);
#endif
#ifdef PCC_BITFIELD_TYPE_MATTERS
- DECL_ALIGN (x) = MAX (DECL_ALIGN (x),
- TYPE_ALIGN (TREE_TYPE (x)));
+ if (PCC_BITFIELD_TYPE_MATTERS)
+ DECL_ALIGN (x) = MAX (DECL_ALIGN (x),
+ TYPE_ALIGN (TREE_TYPE (x)));
#endif
- }
- else
- {
- DECL_INITIAL (x) = NULL_TREE;
- DECL_FIELD_SIZE (x) = width;
- DECL_BIT_FIELD (x) = 1;
+ }
}
}
else
@@ -3652,13 +3722,13 @@ finish_struct_1 (t, warn_anon)
if (code == UNION_TYPE)
{
- char *fie = NULL;
+ const char *fie = NULL;
if (TYPE_NEEDS_CONSTRUCTING (type))
fie = "constructor";
else if (TYPE_NEEDS_DESTRUCTOR (type))
fie = "destructor";
- else if (TYPE_HAS_REAL_ASSIGNMENT (type))
- fie = "assignment operator";
+ else if (TYPE_HAS_COMPLEX_ASSIGN_REF (type))
+ fie = "copy assignment operator";
if (fie)
cp_error_at ("member `%#D' with %s not allowed in union", x,
fie);
@@ -3713,6 +3783,7 @@ finish_struct_1 (t, warn_anon)
CLASSTYPE_READONLY_FIELDS_NEED_INIT (t) = const_sans_init;
CLASSTYPE_REF_FIELDS_NEED_INIT (t) = ref_sans_init;
CLASSTYPE_ABSTRACT_VIRTUALS (t) = abstract_virtuals;
+ CLASSTYPE_HAS_MUTABLE (t) = has_mutable;
/* Effective C++ rule 11. */
if (has_pointers && warn_ecpp && TYPE_HAS_CONSTRUCTOR (t)
@@ -3741,7 +3812,6 @@ finish_struct_1 (t, warn_anon)
if (! IS_SIGNATURE (t))
CLASSTYPE_NON_AGGREGATE (t)
= ! aggregate || has_virtual || TYPE_HAS_CONSTRUCTOR (t);
- TYPE_HAS_REAL_ASSIGNMENT (t) |= TYPE_HAS_ASSIGNMENT (t);
TYPE_HAS_REAL_ASSIGN_REF (t) |= TYPE_HAS_ASSIGN_REF (t);
TYPE_HAS_COMPLEX_ASSIGN_REF (t)
|= TYPE_HAS_ASSIGN_REF (t) || TYPE_USES_VIRTUAL_BASECLASSES (t);
@@ -3833,23 +3903,9 @@ finish_struct_1 (t, warn_anon)
}
/* Now DECL_INITIAL is null on all members except for zero-width bit-fields.
- And they have already done their work.
C++: maybe we will support default field initialization some day... */
- /* Delete all zero-width bit-fields from the front of the fieldlist */
- while (fields && DECL_BIT_FIELD (fields)
- && DECL_INITIAL (fields))
- fields = TREE_CHAIN (fields);
- /* Delete all such fields from the rest of the fields. */
- for (x = fields; x;)
- {
- if (TREE_CHAIN (x) && DECL_BIT_FIELD (TREE_CHAIN (x))
- && DECL_INITIAL (TREE_CHAIN (x)))
- TREE_CHAIN (x) = TREE_CHAIN (TREE_CHAIN (x));
- else
- x = TREE_CHAIN (x);
- }
/* Delete all duplicate fields from the fields */
delete_duplicate_fields (fields);
@@ -3879,7 +3935,7 @@ finish_struct_1 (t, warn_anon)
}
}
- /* Now we have the final fieldlist for the data fields. Record it,
+ /* Now we have the nearly final fieldlist for the data fields. Record it,
then lay out the structure or union (including the fields). */
TYPE_FIELDS (t) = fields;
@@ -3933,9 +3989,26 @@ finish_struct_1 (t, warn_anon)
if (n_baseclasses)
/* layout_basetypes will remove the base subobject fields. */
max_has_virtual = layout_basetypes (t, max_has_virtual);
- else if (empty)
+ if (empty)
TYPE_FIELDS (t) = fields;
+ my_friendly_assert (TYPE_FIELDS (t) == fields, 981117);
+
+ /* Delete all zero-width bit-fields from the front of the fieldlist */
+ while (fields && DECL_C_BIT_FIELD (fields)
+ && DECL_INITIAL (fields))
+ fields = TREE_CHAIN (fields);
+ /* Delete all such fields from the rest of the fields. */
+ for (x = fields; x;)
+ {
+ if (TREE_CHAIN (x) && DECL_C_BIT_FIELD (TREE_CHAIN (x))
+ && DECL_INITIAL (TREE_CHAIN (x)))
+ TREE_CHAIN (x) = TREE_CHAIN (TREE_CHAIN (x));
+ else
+ x = TREE_CHAIN (x);
+ }
+ TYPE_FIELDS (t) = fields;
+
if (TYPE_USES_VIRTUAL_BASECLASSES (t))
{
tree vbases;
@@ -3997,11 +4070,6 @@ finish_struct_1 (t, warn_anon)
if (max_has_virtual > 0)
TYPE_VIRTUAL_P (t) = 1;
- /* Do this here before we start messing with vtables so that we are ready
- for import_export_vtable. */
- if (at_eof)
- import_export_class (t);
-
if (flag_rtti && TYPE_VIRTUAL_P (t) && !pending_hard_virtuals)
modify_all_vtables (t, NULL_TREE, NULL_TREE);
@@ -4107,7 +4175,7 @@ finish_struct_1 (t, warn_anon)
{
/* Use size_int so values are memoized in common cases. */
tree itype = build_index_type (size_int (has_virtual));
- tree atype = build_array_type (vtable_entry_type, itype);
+ tree atype = build_cplus_array_type (vtable_entry_type, itype);
layout_type (atype);
@@ -4292,7 +4360,9 @@ check_member_decl_is_same_in_complete_scope (t, x)
else
icv = NULL_TREE;
- if (icv
+ /* This should match pushdecl_class_level. */
+ if (icv && icv != x
+ && flag_optional_diags
/* Don't complain about constructors. */
&& name != constructor_name (current_class_type)
/* Or inherited names. */
@@ -4363,7 +4433,6 @@ finish_struct (t, attributes, warn_anon)
will fill in the right line number. (mrs) */
if (DECL_SOURCE_LINE (name))
DECL_SOURCE_LINE (name) = lineno;
- CLASSTYPE_SOURCE_LINE (t) = lineno;
name = DECL_NAME (name);
}
@@ -4431,7 +4500,7 @@ finish_struct (t, attributes, warn_anon)
*NONNULL is set iff INSTANCE can be known to be nonnull, regardless
of our knowledge of its type. */
-tree
+static tree
fixed_type_or_null (instance, nonnull)
tree instance;
int *nonnull;
@@ -4551,7 +4620,7 @@ resolves_to_fixed_type_p (instance, nonnull)
return 0;
if (POINTER_TYPE_P (t))
t = TREE_TYPE (t);
- return comptypes (TYPE_MAIN_VARIANT (t), TYPE_MAIN_VARIANT (fixed), 1);
+ return same_type_p (TYPE_MAIN_VARIANT (t), TYPE_MAIN_VARIANT (fixed));
}
@@ -4660,6 +4729,11 @@ pushclass (type, modify)
/* Forcibly remove any old class remnants. */
popclass (-1);
previous_class_type = NULL_TREE;
+
+ /* Now, free the obstack on which we cached all the values. */
+ obstack_free (&class_cache_obstack, class_cache_firstobj);
+ class_cache_firstobj
+ = (char*) obstack_finish (&class_cache_obstack);
}
pushlevel_class ();
@@ -4695,15 +4769,18 @@ pushclass (type, modify)
{
tree item;
- /* Hooray, we successfully cached; let's just install the
- cached class_shadowed list, and walk through it to get the
- IDENTIFIER_TYPE_VALUEs correct. */
+ /* We are re-entering the same class we just left, so we
+ don't have to search the whole inheritance matrix to find
+ all the decls to bind again. Instead, we install the
+ cached class_shadowed list, and walk through it binding
+ names and setting up IDENTIFIER_TYPE_VALUEs. */
set_class_shadows (previous_class_values);
for (item = previous_class_values; item; item = TREE_CHAIN (item))
{
tree id = TREE_PURPOSE (item);
- tree decl = IDENTIFIER_CLASS_VALUE (id);
+ tree decl = TREE_TYPE (item);
+ push_class_binding (id, decl);
if (TREE_CODE (decl) == TYPE_DECL)
set_identifier_type_value (id, TREE_TYPE (decl));
}
@@ -4720,8 +4797,6 @@ pushclass (type, modify)
if (! (IS_AGGR_TYPE_CODE (TREE_CODE (tag_type))
&& CLASSTYPE_IS_TEMPLATE (tag_type)))
pushtag (TREE_PURPOSE (tags), tag_type, 0);
- else
- pushdecl_class_level (CLASSTYPE_TI_TEMPLATE (tag_type));
}
current_function_decl = this_fndecl;
@@ -4753,7 +4828,8 @@ popclass (modify)
TREE_NONLOCAL_FLAG (TREE_VALUE (tags)) = 0;
tags = TREE_CHAIN (tags);
}
- goto ret;
+
+ return;
}
if (modify)
@@ -4783,9 +4859,6 @@ popclass (modify)
current_class_name = current_class_stack[current_class_depth].name;
current_class_type = current_class_stack[current_class_depth].type;
current_access_specifier = current_class_stack[current_class_depth].access;
-
- ret:
- ;
}
/* Returns 1 if current_class_type is either T or a nested type of T. */
@@ -4817,9 +4890,9 @@ push_nested_class (type, modify)
{
tree context;
- my_friendly_assert (!type || TREE_CODE (type) != NAMESPACE_DECL, 980711);
-
+ /* A namespace might be passed in error cases, like A::B:C. */
if (type == NULL_TREE || type == error_mark_node || ! IS_AGGR_TYPE (type)
+ || TREE_CODE (type) == NAMESPACE_DECL
|| TREE_CODE (type) == TEMPLATE_TYPE_PARM
|| TREE_CODE (type) == TEMPLATE_TEMPLATE_PARM)
return;
@@ -4890,47 +4963,269 @@ pop_lang_context ()
/* Type instantiation routines. */
+/* Given an OVERLOAD and a TARGET_TYPE, return the function that
+ matches the TARGET_TYPE. If there is no satisfactory match, return
+ error_mark_node, and issue an error message if COMPLAIN is
+ non-zero. If TEMPLATE_ONLY, the name of the overloaded function
+ was a template-id, and EXPLICIT_TARGS are the explicitly provided
+ template arguments. */
+
static tree
-validate_lhs (lhstype, complain)
- tree lhstype;
+resolve_address_of_overloaded_function (target_type,
+ overload,
+ complain,
+ template_only,
+ explicit_targs)
+ tree target_type;
+ tree overload;
int complain;
+ int template_only;
+ tree explicit_targs;
{
- if (TYPE_PTRMEMFUNC_P (lhstype))
- lhstype = TYPE_PTRMEMFUNC_FN_TYPE (lhstype);
+ /* Here's what the standard says:
+
+ [over.over]
+
+ If the name is a function template, template argument deduction
+ is done, and if the argument deduction succeeds, the deduced
+ arguments are used to generate a single template function, which
+ is added to the set of overloaded functions considered.
+
+ Non-member functions and static member functions match targets of
+ type "pointer-to-function" or "reference-to-function." Nonstatic
+ member functions match targets of type "pointer-to-member
+ function;" the function type of the pointer to member is used to
+ select the member function from the set of overloaded member
+ functions. If a nonstatic member function is selected, the
+ reference to the overloaded function name is required to have the
+ form of a pointer to member as described in 5.3.1.
+
+ If more than one function is selected, any template functions in
+ the set are eliminated if the set also contains a non-template
+ function, and any given template function is eliminated if the
+ set contains a second template function that is more specialized
+ than the first according to the partial ordering rules 14.5.5.2.
+ After such eliminations, if any, there shall remain exactly one
+ selected function. */
+
+ int is_ptrmem = 0;
+ int is_reference = 0;
+ /* We store the matches in a TREE_LIST rooted here. The functions
+ are the TREE_PURPOSE, not the TREE_VALUE, in this list, for easy
+ interoperability with most_specialized_instantiation. */
+ tree matches = NULL_TREE;
+ tree fn;
- if (TREE_CODE (lhstype) == POINTER_TYPE)
+ /* By the time we get here, we should be seeing only real
+ pointer-to-member types, not the internal POINTER_TYPE to
+ METHOD_TYPE representation. */
+ my_friendly_assert (!(TREE_CODE (target_type) == POINTER_TYPE
+ && (TREE_CODE (TREE_TYPE (target_type))
+ == METHOD_TYPE)), 0);
+
+ /* Check that the TARGET_TYPE is reasonable. */
+ if (TYPE_PTRFN_P (target_type))
+ /* This is OK. */
+ ;
+ else if (TYPE_PTRMEMFUNC_P (target_type))
+ /* This is OK, too. */
+ is_ptrmem = 1;
+ else if (TREE_CODE (target_type) == FUNCTION_TYPE)
+ {
+ /* This is OK, too. This comes from a conversion to reference
+ type. */
+ target_type = build_reference_type (target_type);
+ is_reference = 1;
+ }
+ else
{
- if (TREE_CODE (TREE_TYPE (lhstype)) == FUNCTION_TYPE
- || TREE_CODE (TREE_TYPE (lhstype)) == METHOD_TYPE)
- lhstype = TREE_TYPE (lhstype);
+ if (complain)
+ cp_error("cannot resolve overloaded function `%D' based on conversion to type `%T'",
+ DECL_NAME (OVL_FUNCTION (overload)), target_type);
+ return error_mark_node;
+ }
+
+ /* If we can find a non-template function that matches, we can just
+ use it. There's no point in generating template instantiations
+ if we're just going to throw them out anyhow. But, of course, we
+ can only do this when we don't *need* a template function. */
+ if (!template_only)
+ {
+ tree fns;
+
+ for (fns = overload; fns; fns = OVL_CHAIN (fns))
+ {
+ tree fn = OVL_FUNCTION (fns);
+ tree fntype;
+
+ if (TREE_CODE (fn) == TEMPLATE_DECL)
+ /* We're not looking for templates just yet. */
+ continue;
+
+ if ((TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE)
+ != is_ptrmem)
+ /* We're looking for a non-static member, and this isn't
+ one, or vice versa. */
+ continue;
+
+ /* See if there's a match. */
+ fntype = TREE_TYPE (fn);
+ if (is_ptrmem)
+ fntype = build_ptrmemfunc_type (build_pointer_type (fntype));
+ else if (!is_reference)
+ fntype = build_pointer_type (fntype);
+
+ if (can_convert_arg (target_type, fntype, fn))
+ matches = scratch_tree_cons (fn, NULL_TREE, matches);
+ }
+ }
+
+ /* Now, if we've already got a match (or matches), there's no need
+ to proceed to the template functions. But, if we don't have a
+ match we need to look at them, too. */
+ if (!matches)
+ {
+ tree target_fn_type;
+ tree target_arg_types;
+ tree fns;
+
+ if (is_ptrmem)
+ target_fn_type
+ = TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (target_type));
else
+ target_fn_type = TREE_TYPE (target_type);
+ target_arg_types = TYPE_ARG_TYPES (target_fn_type);
+
+ for (fns = overload; fns; fns = OVL_CHAIN (fns))
{
- if (complain)
- error ("invalid type combination for overload");
- return error_mark_node;
+ tree fn = OVL_FUNCTION (fns);
+ tree instantiation;
+ tree instantiation_type;
+ tree targs;
+
+ if (TREE_CODE (fn) != TEMPLATE_DECL)
+ /* We're only looking for templates. */
+ continue;
+
+ if ((TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE)
+ != is_ptrmem)
+ /* We're not looking for a non-static member, and this is
+ one, or vice versa. */
+ continue;
+
+ /* Try to do argument deduction. */
+ targs = make_scratch_vec (DECL_NTPARMS (fn));
+ if (fn_type_unification (fn, explicit_targs, targs,
+ target_arg_types, NULL_TREE,
+ DEDUCE_EXACT) != 0)
+ /* Argument deduction failed. */
+ continue;
+
+ /* Instantiate the template. */
+ instantiation = instantiate_template (fn, targs);
+ if (instantiation == error_mark_node)
+ /* Instantiation failed. */
+ continue;
+
+ /* See if there's a match. */
+ instantiation_type = TREE_TYPE (instantiation);
+ if (is_ptrmem)
+ instantiation_type =
+ build_ptrmemfunc_type (build_pointer_type (instantiation_type));
+ else if (!is_reference)
+ instantiation_type = build_pointer_type (instantiation_type);
+ if (can_convert_arg (target_type, instantiation_type, instantiation))
+ matches = scratch_tree_cons (instantiation, fn, matches);
+ }
+
+ /* Now, remove all but the most specialized of the matches. */
+ if (matches)
+ {
+ tree match = most_specialized_instantiation (matches,
+ explicit_targs);
+
+ if (match != error_mark_node)
+ matches = scratch_tree_cons (match, NULL_TREE, NULL_TREE);
+ }
+ }
+
+ /* Now we should have exactly one function in MATCHES. */
+ if (matches == NULL_TREE)
+ {
+ /* There were *no* matches. */
+ if (complain)
+ {
+ cp_error ("no matches converting function `%D' to type `%#T'",
+ DECL_NAME (OVL_FUNCTION (overload)),
+ target_type);
+
+ /* print_candidates expects a chain with the functions in
+ TREE_VALUE slots, so we cons one up here (we're losing anyway,
+ so why be clever?). */
+ for (; overload; overload = OVL_NEXT (overload))
+ matches = scratch_tree_cons (NULL_TREE, OVL_CURRENT (overload),
+ matches);
+
+ print_candidates (matches);
}
+ return error_mark_node;
+ }
+ else if (TREE_CHAIN (matches))
+ {
+ /* There were too many matches. */
+
+ if (complain)
+ {
+ tree match;
+
+ cp_error ("converting overloaded function `%D' to type `%#T' is ambiguous",
+ DECL_NAME (OVL_FUNCTION (overload)),
+ target_type);
+
+ /* Since print_candidates expects the functions in the
+ TREE_VALUE slot, we flip them here. */
+ for (match = matches; match; match = TREE_CHAIN (match))
+ TREE_VALUE (match) = TREE_PURPOSE (match);
+
+ print_candidates (matches);
+ }
+
+ return error_mark_node;
+ }
+
+ /* Good, exactly one match. Now, convert it to the correct type. */
+ fn = TREE_PURPOSE (matches);
+
+ mark_used (fn);
+
+ if (TYPE_PTRFN_P (target_type) || TYPE_PTRMEMFUNC_P (target_type))
+ return build_unary_op (ADDR_EXPR, fn, 0);
+ else
+ {
+ /* The target must be a REFERENCE_TYPE. Above, build_unary_op
+ will mark the function as addressed, but here we must do it
+ explicitly. */
+ mark_addressable (fn);
+
+ return fn;
}
- return lhstype;
}
/* This function will instantiate the type of the expression given in
RHS to match the type of LHSTYPE. If errors exist, then return
- error_mark_node. If only complain is COMPLAIN is set. If we are
+ error_mark_node. We only complain is COMPLAIN is set. If we are
not complaining, never modify rhs, as overload resolution wants to
try many possible instantiations, in hopes that at least one will
work.
- This function is used in build_modify_expr, convert_arguments,
- build_c_cast, and compute_conversion_costs. */
+ For non-recursive calls, LHSTYPE should be a function, pointer to
+ function, or a pointer to member function. */
tree
instantiate_type (lhstype, rhs, complain)
tree lhstype, rhs;
int complain;
{
- tree explicit_targs = NULL_TREE;
- int template_only = 0;
-
if (TREE_CODE (lhstype) == UNKNOWN_TYPE)
{
if (complain)
@@ -4940,7 +5235,7 @@ instantiate_type (lhstype, rhs, complain)
if (TREE_TYPE (rhs) != NULL_TREE && ! (type_unknown_p (rhs)))
{
- if (comptypes (lhstype, TREE_TYPE (rhs), 1))
+ if (same_type_p (lhstype, TREE_TYPE (rhs)))
return rhs;
if (complain)
cp_error ("argument of type `%T' does not match `%T'",
@@ -4991,72 +5286,34 @@ instantiate_type (lhstype, rhs, complain)
case COMPONENT_REF:
{
tree field = TREE_OPERAND (rhs, 1);
- if (TREE_CODE (field) == TREE_LIST)
- {
- tree function = instantiate_type (lhstype, field, complain);
- if (function == error_mark_node)
- return error_mark_node;
- my_friendly_assert (TREE_CODE (function) == FUNCTION_DECL, 185);
- if (DECL_VINDEX (function))
- {
- tree base = TREE_OPERAND (rhs, 0);
- tree base_ptr = build_unary_op (ADDR_EXPR, base, 0);
- if (base_ptr == error_mark_node)
- return error_mark_node;
- base_ptr = convert_pointer_to (DECL_CONTEXT (function), base_ptr);
- if (base_ptr == error_mark_node)
- return error_mark_node;
- return build_vfn_ref (&base_ptr, base, DECL_VINDEX (function));
- }
- mark_used (function);
- return function;
- }
+ tree r;
- /* I could not trigger this code. MvL */
- my_friendly_abort (980326);
-#if 0
- my_friendly_assert (TREE_CODE (field) == FIELD_DECL, 178);
- my_friendly_assert (!(TREE_CODE (TREE_TYPE (field)) == FUNCTION_TYPE
- || TREE_CODE (TREE_TYPE (field)) == METHOD_TYPE),
- 179);
-
- TREE_TYPE (rhs) = lhstype;
- /* First look for an exact match */
+ my_friendly_assert (TREE_CODE (field) == TREE_LIST, 0);
- while (field && TREE_TYPE (field) != lhstype)
- field = DECL_CHAIN (field);
- if (field)
- {
- TREE_OPERAND (rhs, 1) = field;
- mark_used (field);
- return rhs;
- }
+ r = instantiate_type (lhstype, field, complain);
- /* No exact match found, look for a compatible function. */
- field = TREE_OPERAND (rhs, 1);
- while (field && ! comptypes (lhstype, TREE_TYPE (field), 0))
- field = DECL_CHAIN (field);
- if (field)
+ if (r != error_mark_node && TYPE_PTRMEMFUNC_P (lhstype))
{
- TREE_OPERAND (rhs, 1) = field;
- field = DECL_CHAIN (field);
- while (field && ! comptypes (lhstype, TREE_TYPE (field), 0))
- field = DECL_CHAIN (field);
- if (field)
+ if (complain)
{
- if (complain)
- error ("ambiguous overload for COMPONENT_REF requested");
- return error_mark_node;
+ tree t = TYPE_PTRMEMFUNC_OBJECT_TYPE (lhstype);
+ tree fn = TREE_VALUE (field);
+ if (TREE_CODE (fn) == OVERLOAD)
+ fn = OVL_FUNCTION (fn);
+ if (TREE_CODE (fn) == FUNCTION_DECL)
+ {
+ cp_error ("object-dependent reference `%E' can only be used in a call",
+ DECL_NAME (fn));
+ cp_error (" to form a pointer to member function, say `&%T::%E'",
+ t, DECL_NAME (fn));
+ }
+ else
+ cp_error ("object-dependent reference can only be used in a call");
}
- }
- else
- {
- if (complain)
- error ("no appropriate overload exists for COMPONENT_REF");
return error_mark_node;
}
-#endif
- return rhs;
+
+ return r;
}
case OFFSET_REF:
@@ -5068,143 +5325,23 @@ instantiate_type (lhstype, rhs, complain)
/* Fall through. */
case TEMPLATE_ID_EXPR:
- {
- explicit_targs = TREE_OPERAND (rhs, 1);
- template_only = 1;
- rhs = TREE_OPERAND (rhs, 0);
- }
- /* fall through */
- my_friendly_assert (TREE_CODE (rhs) == OVERLOAD, 980401);
+ return
+ resolve_address_of_overloaded_function (lhstype,
+ TREE_OPERAND (rhs, 0),
+ complain,
+ /*template_only=*/1,
+ TREE_OPERAND (rhs, 1));
case OVERLOAD:
- {
- tree elem, elems;
-
- /* Check that the LHSTYPE and the RHS are reasonable. */
- lhstype = validate_lhs (lhstype, complain);
- if (lhstype == error_mark_node)
- return lhstype;
-
- if (TREE_CODE (lhstype) != FUNCTION_TYPE
- && TREE_CODE (lhstype) != METHOD_TYPE)
- {
- if (complain)
- cp_error("cannot resolve overloaded function `%D' "
- "based on non-function type",
- DECL_NAME (OVL_FUNCTION (rhs)));
- return error_mark_node;
- }
-
- /* Look for an exact match, by searching through the
- overloaded functions. */
- if (template_only)
- /* If we're processing a template-id, only a template
- function can match, so we don't look through the
- overloaded functions. */
- ;
- else for (elems = rhs; elems; elems = OVL_CHAIN (elems))
- {
- elem = OVL_FUNCTION (elems);
- if (comptypes (lhstype, TREE_TYPE (elem), 1))
- {
- mark_used (elem);
- return elem;
- }
- }
-
- /* No overloaded function was an exact match. See if we can
- instantiate some template to match. */
- {
- tree save_elem = 0;
- elems = rhs;
- if (TREE_CODE (elems) == TREE_LIST)
- elems = TREE_VALUE (rhs);
- for (; elems; elems = OVL_NEXT (elems))
- if (TREE_CODE (elem = OVL_CURRENT (elems)) == TEMPLATE_DECL)
- {
- int n = DECL_NTPARMS (elem);
- tree t = make_scratch_vec (n);
- int i;
- i = type_unification
- (DECL_INNERMOST_TEMPLATE_PARMS (elem), t,
- TYPE_ARG_TYPES (TREE_TYPE (elem)),
- TYPE_ARG_TYPES (lhstype), explicit_targs, DEDUCE_EXACT, 1);
- if (i == 0)
- {
- if (save_elem)
- {
- cp_error ("ambiguous template instantiation converting to `%#T'", lhstype);
- return error_mark_node;
- }
- save_elem = instantiate_template (elem, t);
- /* Check the return type. */
- if (! comptypes (TREE_TYPE (lhstype),
- TREE_TYPE (TREE_TYPE (save_elem)), 1))
- save_elem = 0;
- }
- }
- if (save_elem)
- {
- mark_used (save_elem);
- return save_elem;
- }
- }
-
- /* There's no exact match, and no templates can be
- instantiated to match. The last thing we try is to see if
- some ordinary overloaded function is close enough. If
- we're only looking for template functions, we don't do
- this. */
- if (!template_only)
- {
- for (elems = rhs; elems; elems = OVL_NEXT (elems))
- {
- elem = OVL_CURRENT (elems);
- if (comp_target_types (lhstype, TREE_TYPE (elem), 1) > 0)
- break;
- }
- if (elems)
- {
- tree save_elem = elem;
- for (elems = OVL_CHAIN (elems); elems;
- elems = OVL_CHAIN (elems))
- {
- elem = OVL_FUNCTION (elems);
- if (comp_target_types (lhstype, TREE_TYPE (elem), 0) > 0)
- break;
- }
- if (elems)
- {
- if (complain)
- {
- cp_error
- ("cannot resolve overload to target type `%#T'",
- lhstype);
- cp_error_at (" ambiguity between `%#D'", save_elem);
- cp_error_at (" and `%#D', at least", elem);
- }
- return error_mark_node;
- }
- mark_used (save_elem);
- return save_elem;
- }
- }
-
- /* We failed to find a match. */
- if (complain)
- {
- cp_error ("cannot resolve overload to target type `%#T'", lhstype);
- cp_error
- (" because no suitable overload of function `%D' exists",
- DECL_NAME (OVL_FUNCTION (rhs)));
- }
- return error_mark_node;
- }
+ return
+ resolve_address_of_overloaded_function (lhstype,
+ rhs,
+ complain,
+ /*template_only=*/0,
+ /*explicit_targs=*/NULL_TREE);
case TREE_LIST:
{
- tree elem, baselink, name = NULL_TREE;
-
if (TREE_PURPOSE (rhs) == error_mark_node)
{
/* Make sure we don't drop the non-local flag, as the old code
@@ -5218,79 +5355,12 @@ instantiate_type (lhstype, rhs, complain)
/* Now we should have a baselink. */
my_friendly_assert (TREE_CODE (TREE_PURPOSE (rhs)) == TREE_VEC,
980331);
- /* First look for an exact match. Search member functions.
- May have to undo what `default_conversion' might do to
- lhstype. */
-
- lhstype = validate_lhs (lhstype, complain);
- if (lhstype == error_mark_node)
- return lhstype;
-
my_friendly_assert (TREE_CHAIN (rhs) == NULL_TREE, 181);
my_friendly_assert (TREE_CODE (TREE_VALUE (rhs)) == FUNCTION_DECL
|| TREE_CODE (TREE_VALUE (rhs)) == OVERLOAD,
182);
- for (baselink = rhs; baselink;
- baselink = next_baselink (baselink))
- {
- elem = TREE_VALUE (baselink);
- while (elem)
- if (comptypes (lhstype, TREE_TYPE (OVL_CURRENT (elem)), 1))
- {
- mark_used (OVL_CURRENT (elem));
- return OVL_CURRENT (elem);
- }
- else
- elem = OVL_NEXT (elem);
- }
-
- /* No exact match found, look for a compatible method. */
- for (baselink = rhs; baselink;
- baselink = next_baselink (baselink))
- {
- elem = TREE_VALUE (baselink);
- for (; elem; elem = OVL_NEXT (elem))
- if (comp_target_types (lhstype,
- TREE_TYPE (OVL_CURRENT (elem)), 1) > 0)
- break;
- if (elem)
- {
- tree save_elem = OVL_CURRENT (elem);
- for (elem = OVL_NEXT (elem); elem; elem = OVL_NEXT (elem))
- if (comp_target_types (lhstype,
- TREE_TYPE (OVL_CURRENT (elem)), 0) > 0)
- break;
- if (elem)
- {
- if (complain)
- error ("ambiguous overload for overloaded method requested");
- return error_mark_node;
- }
- mark_used (save_elem);
- return save_elem;
- }
- name = rhs;
- while (TREE_CODE (name) == TREE_LIST)
- name = TREE_VALUE (name);
- name = DECL_NAME (OVL_CURRENT (name));
-#if 0
- if (TREE_CODE (lhstype) == FUNCTION_TYPE && globals < 0)
- {
- /* Try to instantiate from non-member functions. */
- rhs = lookup_name_nonclass (name);
- if (rhs && TREE_CODE (rhs) == TREE_LIST)
- {
- /* This code seems to be missing a `return'. */
- my_friendly_abort (4);
- instantiate_type (lhstype, rhs, complain);
- }
- }
-#endif
- }
- if (complain)
- cp_error ("no compatible member functions named `%D'", name);
- return error_mark_node;
+ return instantiate_type (lhstype, TREE_VALUE (rhs), complain);
}
case CALL_EXPR:
@@ -5395,30 +5465,7 @@ instantiate_type (lhstype, rhs, complain)
return rhs;
case ADDR_EXPR:
- if (TYPE_PTRMEMFUNC_P (lhstype))
- lhstype = TYPE_PTRMEMFUNC_FN_TYPE (lhstype);
- else if (TREE_CODE (lhstype) != POINTER_TYPE)
- {
- if (complain)
- error ("type for resolving address of overloaded function must be pointer type");
- return error_mark_node;
- }
- {
- tree fn = instantiate_type (TREE_TYPE (lhstype), TREE_OPERAND (rhs, 0), complain);
- if (fn == error_mark_node)
- return error_mark_node;
- mark_addressable (fn);
- TREE_TYPE (rhs) = lhstype;
- TREE_OPERAND (rhs, 0) = fn;
- TREE_CONSTANT (rhs) = staticp (fn);
- if (TREE_CODE (lhstype) == POINTER_TYPE
- && TREE_CODE (TREE_TYPE (lhstype)) == METHOD_TYPE)
- {
- build_ptrmemfunc_type (lhstype);
- rhs = build_ptrmemfunc (lhstype, rhs, 0);
- }
- }
- return rhs;
+ return instantiate_type (lhstype, TREE_OPERAND (rhs, 0), complain);
case ENTRY_VALUE_EXPR:
my_friendly_abort (184);
@@ -5477,16 +5524,24 @@ print_class_statistics ()
}
/* Push an obstack which is sufficiently long-lived to hold such class
- decls that may be cached in the previous_class_values list. For now, let's
- use the permanent obstack, later we may create a dedicated obstack just
- for this purpose. The effect is undone by pop_obstacks. */
+ decls that may be cached in the previous_class_values list. The
+ effect is undone by pop_obstacks. */
void
maybe_push_cache_obstack ()
{
+ static int cache_obstack_initialized;
+
+ if (!cache_obstack_initialized)
+ {
+ gcc_obstack_init (&class_cache_obstack);
+ class_cache_firstobj
+ = (char*) obstack_finish (&class_cache_obstack);
+ cache_obstack_initialized = 1;
+ }
+
push_obstacks_nochange ();
- if (current_class_depth == 1)
- current_obstack = &permanent_obstack;
+ current_obstack = &class_cache_obstack;
}
/* Build a dummy reference to ourselves so Derived::Base (and A::A) works,
@@ -5495,18 +5550,24 @@ maybe_push_cache_obstack ()
into the scope of the class itself. For purposes of access checking,
the inserted class name is treated as if it were a public member name. */
-tree
+void
build_self_reference ()
{
tree name = constructor_name (current_class_type);
tree value = build_lang_decl (TYPE_DECL, name, current_class_type);
+ tree saved_cas;
+
DECL_NONLOCAL (value) = 1;
DECL_CONTEXT (value) = current_class_type;
DECL_CLASS_CONTEXT (value) = current_class_type;
DECL_ARTIFICIAL (value) = 1;
pushdecl_class_level (value);
- return value;
+
+ saved_cas = current_access_specifier;
+ current_access_specifier = access_public_node;
+ finish_member_declaration (value);
+ current_access_specifier = saved_cas;
}
/* Returns 1 if TYPE contains only padding bytes. */
diff --git a/gcc/cp/config-lang.in b/gcc/cp/config-lang.in
index 9b39d51ed87..dd31af4f986 100644
--- a/gcc/cp/config-lang.in
+++ b/gcc/cp/config-lang.in
@@ -1,5 +1,5 @@
# Top level configure fragment for GNU C++.
-# Copyright (C) 1994, 1995 Free Software Foundation, Inc.
+# Copyright (C) 1994, 1995, 1997, 1998 Free Software Foundation, Inc.
#This file is part of GNU CC.
diff --git a/gcc/cp/cp-tree.def b/gcc/cp/cp-tree.def
index 20a0117c160..2fdacfd3965 100644
--- a/gcc/cp/cp-tree.def
+++ b/gcc/cp/cp-tree.def
@@ -1,7 +1,7 @@
/* This file contains the definitions and documentation for the
additional tree codes used in the GNU C++ compiler (see tree.def
for the standard codes).
- Copyright (C) 1987, 1988, 1990, 1993 Free Software Foundation, Inc.
+ Copyright (C) 1987, 1988, 1990, 1993, 1997, 1998 Free Software Foundation, Inc.
Hacked by Michael Tiemann (tiemann@cygnus.com)
This file is part of GNU CC.
@@ -143,9 +143,16 @@ DEFTREECODE (TEMPLATE_TYPE_PARM, "template_type_parm", 't', 0)
The TYPE_FIELDS value will be a TEMPLATE_PARM_INDEX. */
DEFTREECODE (TEMPLATE_TEMPLATE_PARM, "template_template_parm", 't', 0)
-/* A type designated by 'typename T::t'. */
+/* A type designated by `typename T::t'. TYPE_CONTEXT is `T',
+ TYPE_NAME is a TYPE_DECL for `t'. If TREE_TYPE is present, this
+ type was generated by the implicit typename extension, and the
+ TREE_TYPE is a _TYPE from a baseclass of `T'. */
DEFTREECODE (TYPENAME_TYPE, "typename_type", 't', 0)
+/* A type designated by `__typeof (expr)'. TYPE_FIELDS is the
+ expression in question. */
+DEFTREECODE (TYPEOF_TYPE, "typeof_type", 't', 0)
+
/* A thunk is a stub function.
Thunks are used to implement multiple inheritance:
@@ -171,9 +178,9 @@ DEFTREECODE (DEFAULT_ARG, "default_arg", 'c', 2)
the template may be an IDENTIFIER_NODE. */
DEFTREECODE (TEMPLATE_ID_EXPR, "template_id_expr", 'e', 2)
-/* An association between namespace and entity. Parameters are the
- scope and the (non-type) value.
- TREE_TYPE indicates the type bound to the name. */
+/* An association between name and entity. Parameters are the scope
+ and the (non-type) value. TREE_TYPE indicates the type bound to
+ the name. */
DEFTREECODE (CPLUS_BINDING, "binding", 'x', 2)
/* A list-like node for chaining overloading candidates. TREE_TYPE is
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 44587abc2de..14306231f9c 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -1,5 +1,5 @@
/* Definitions for C++ parsing and type checking.
- Copyright (C) 1987, 93, 94, 95, 1996 Free Software Foundation, Inc.
+ Copyright (C) 1987, 92-97, 1998, 1999 Free Software Foundation, Inc.
Hacked by Michael Tiemann (tiemann@cygnus.com)
This file is part of GNU CC.
@@ -22,10 +22,6 @@ Boston, MA 02111-1307, USA. */
#ifndef _CP_TREE_H
#define _CP_TREE_H
-#include "gansidecl.h"
-
-#include "c-common.h"
-
/* Usage of TREE_LANG_FLAG_?:
0: TREE_NONLOCAL_FLAG (in TREE_LIST or _TYPE).
BINFO_MARKED (BINFO nodes).
@@ -34,7 +30,9 @@ Boston, MA 02111-1307, USA. */
DELETE_EXPR_USE_GLOBAL (in DELETE_EXPR).
LOOKUP_EXPR_GLOBAL (in LOOKUP_EXPR).
TREE_NEGATED_INT (in INTEGER_CST).
- (TREE_MANGLED) (in IDENTIFIER_NODE) (commented-out).
+ TREE_INDIRECT_USING (in NAMESPACE_DECL).
+ IDENTIFIER_MARKED (used by search routines).
+ LOCAL_BINDING_P (in CPLUS_BINDING)
1: IDENTIFIER_VIRTUAL_P.
TI_PENDING_TEMPLATE_FLAG.
TEMPLATE_PARMS_FOR_INLINE.
@@ -46,7 +44,6 @@ Boston, MA 02111-1307, USA. */
BINFO_VBASE_MARKED.
BINFO_FIELDS_MARKED.
TYPE_VIRTUAL_P.
- PARM_DECL_EXPR (in SAVE_EXPR).
3: TYPE_USES_VIRTUAL_BASECLASSES (in a class TYPE).
BINFO_VTABLE_PATH_MARKED.
BINFO_PUSHDECLS_MARKED.
@@ -68,23 +65,37 @@ Boston, MA 02111-1307, USA. */
Usage of DECL_LANG_FLAG_?:
0: DECL_ERROR_REPORTED (in VAR_DECL).
+ DECL_TEMPLATE_PARM_P (in CONST_DECL, TYPE_DECL, or TEMPLATE_DECL)
1: C_TYPEDEF_EXPLICITLY_SIGNED (in TYPE_DECL).
+ DECL_TEMPLATE_INSTANTIATED (in a VAR_DECL or a FUNCTION_DECL)
2: DECL_THIS_EXTERN (in VAR_DECL or FUNCTION_DECL).
3: DECL_IN_AGGR_P.
4: DECL_MAYBE_TEMPLATE.
5: DECL_INTERFACE_KNOWN.
6: DECL_THIS_STATIC (in VAR_DECL or FUNCTION_DECL).
7: DECL_DEAD_FOR_LOCAL (in VAR_DECL).
-*/
-struct function;
+ Usage of language-independent fields in a language-dependent manner:
+
+ TYPE_ALIAS_SET
+ This field is used by TYPENAME_TYPEs, TEMPLATE_TYPE_PARMs, and so
+ forth as a substitute for the mark bits provided in `lang_type'.
+ At present, only the six low-order bits are used.
+
+ TYPE_BINFO
+ For an ENUMERAL_TYPE, this is ENUM_TEMPLATE_INFO.
+ For a TYPENAME_TYPE, this is TYPENAME_TYPE_FULLNAME.
+ For a TEMPLATE_TEMPLATE_PARM, this is
+ TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO.
+*/
/* Language-dependent contents of an identifier. */
struct lang_identifier
{
struct tree_identifier ignore;
- tree namespace_bindings, local_value;
+ tree namespace_bindings;
+ tree bindings;
tree class_value;
tree class_template_info;
struct lang_id2 *x;
@@ -119,15 +130,24 @@ typedef struct ptrmem_cst
tree member;
}* ptrmem_cst_t;
-/* For a binding between a name and an entity, defines the scope
- where the binding is declared. Currently always points to a
- namespace declaration. */
-#define BINDING_SCOPE(NODE) (((struct tree_binding*)NODE)->scope)
+/* Nonzero if this binding is for a local scope, as opposed to a class
+ or namespace scope. */
+#define LOCAL_BINDING_P(NODE) TREE_LANG_FLAG_0(NODE)
+
+/* For a binding between a name and an entity at a non-local scope,
+ defines the scope where the binding is declared. (Either a class
+ _TYPE node, or a NAMESPACE_DECL.) This macro should be used only
+ for namespace-level bindings; on the IDENTIFIER_BINDING list
+ BINDING_LEVEL is used instead. */
+#define BINDING_SCOPE(NODE) (((struct tree_binding*)NODE)->scope.scope)
+
/* This is the declaration bound to the name. Possible values:
variable, overloaded function, namespace, template, enumerator. */
#define BINDING_VALUE(NODE) (((struct tree_binding*)NODE)->value)
+
/* If name is bound to a type, this is the type (struct, union, enum). */
#define BINDING_TYPE(NODE) TREE_TYPE(NODE)
+
#define IDENTIFIER_GLOBAL_VALUE(NODE) \
namespace_binding (NODE, global_namespace)
#define SET_IDENTIFIER_GLOBAL_VALUE(NODE, VAL) \
@@ -140,7 +160,10 @@ typedef struct ptrmem_cst
struct tree_binding
{
char common[sizeof (struct tree_common)];
- tree scope;
+ union {
+ tree scope;
+ struct binding_level *level;
+ } scope;
tree value;
};
@@ -192,13 +215,43 @@ struct tree_srcloc
#define IDENTIFIER_NAMESPACE_BINDINGS(NODE) \
(((struct lang_identifier *)(NODE))->namespace_bindings)
-#define IDENTIFIER_CLASS_VALUE(NODE) \
- (((struct lang_identifier *)(NODE))->class_value)
-#define IDENTIFIER_LOCAL_VALUE(NODE) \
- (((struct lang_identifier *)(NODE))->local_value)
#define IDENTIFIER_TEMPLATE(NODE) \
(((struct lang_identifier *)(NODE))->class_template_info)
+/* The IDENTIFIER_BINDING is the innermost CPLUS_BINDING for the
+ identifier. It's TREE_CHAIN is the next outermost binding. Each
+ BINDING_VALUE is a DECL for the associated declaration. Thus,
+ name lookup consists simply of pulling off the node at the front
+ of the list (modulo oddities for looking up the names of types,
+ and such.) You can use BINDING_SCOPE or BINDING_LEVEL to
+ determine the scope that bound the name. */
+#define IDENTIFIER_BINDING(NODE) \
+ (((struct lang_identifier*) (NODE))->bindings)
+
+/* The IDENTIFIER_VALUE is the value of the IDENTIFIER_BINDING, or
+ NULL_TREE if there is no binding. */
+#define IDENTIFIER_VALUE(NODE) \
+ (IDENTIFIER_BINDING (NODE) \
+ ? BINDING_VALUE (IDENTIFIER_BINDING (NODE)) \
+ : NULL_TREE)
+
+/* If we are currently in class scope, then IDENTIFIER_CLASS_VALUE
+ indicates the class-scoped binding of NODE. This is just a pointer
+ to the BINDING_VALUE of one of the bindings in the
+ IDENTIFIER_BINDINGs list, so any time that this is set so is
+ IDENTIFIER_BINDING. */
+#define IDENTIFIER_CLASS_VALUE(NODE) \
+ (((struct lang_identifier *) (NODE))->class_value)
+
+/* The amount of time used by the file whose special "time identifier"
+ is NODE, represented as an INTEGER_CST. See get_time_identifier. */
+#define TIME_IDENTIFIER_TIME(NODE) IDENTIFIER_BINDING(NODE)
+
+/* For a "time identifier" this is a INTEGER_CST. The
+ TREE_INT_CST_LOW is 1 if the corresponding file is "interface only".
+ The TRE_INT_CST_HIGH is 1 if it is "interface unknown". */
+#define TIME_IDENTIFIER_FILEINFO(NODE) IDENTIFIER_CLASS_VALUE (NODE)
+
/* TREE_TYPE only indicates on local and class scope the current
type. For namespace scope, the presence of a type in any namespace
is indicated with global_type_node, and the real type behind must
@@ -243,10 +296,12 @@ struct tree_srcloc
/* Nonzero if this identifier is the prefix for a mangled C++ operator name. */
#define IDENTIFIER_OPNAME_P(NODE) TREE_LANG_FLAG_2(NODE)
-#define IDENTIFIER_TYPENAME_P(NODE) \
- (! strncmp (IDENTIFIER_POINTER (NODE), \
- IDENTIFIER_POINTER (ansi_opname[(int) TYPE_EXPR]), \
- IDENTIFIER_LENGTH (ansi_opname[(int) TYPE_EXPR])))
+/* Nonzero if this identifier is the name of a type-conversion
+ operator. */
+#define IDENTIFIER_TYPENAME_P(NODE) \
+ (! strncmp (IDENTIFIER_POINTER (NODE), \
+ OPERATOR_TYPENAME_FORMAT, \
+ strlen (OPERATOR_TYPENAME_FORMAT)))
/* Nonzero means reject anything that ANSI standard C forbids. */
extern int pedantic;
@@ -341,10 +396,6 @@ extern int flag_gnu_xref;
extern int flag_gnu_binutils;
-/* Nonzero means ignore `#ident' directives. */
-
-extern int flag_no_ident;
-
/* Nonzero means warn about implicit declarations. */
extern int warn_implicit;
@@ -499,11 +550,19 @@ extern int flag_optional_diags;
/* Nonzero means do not consider empty argument prototype to mean function
takes no arguments. */
-
extern int flag_strict_prototype;
/* Nonzero means output .vtable_{entry,inherit} for use in doing vtable gc. */
extern int flag_vtable_gc;
+
+/* Nonzero means make the default pedwarns warnings instead of errors.
+ The value of this flag is ignored if -pedantic is specified. */
+extern int flag_permissive;
+
+/* Nonzero if we want to obey access control semantics. */
+
+extern int flag_access_control;
+
/* C++ language-specific tree codes. */
#define DEFTREECODE(SYM, NAME, TYPE, LENGTH) SYM,
@@ -531,12 +590,21 @@ enum languages { lang_c, lang_cplusplus, lang_java };
for template type parameters and typename types. Despite its name,
this macro has nothing to do with the definition of aggregate given
in the standard. Think of this macro as MAYBE_CLASS_TYPE_P. */
-#define IS_AGGR_TYPE(t) (TYPE_LANG_FLAG_5 (t))
+#define IS_AGGR_TYPE(t) \
+ (TREE_CODE (t) == TEMPLATE_TYPE_PARM \
+ || TREE_CODE (t) == TYPENAME_TYPE \
+ || TREE_CODE (t) == TYPEOF_TYPE \
+ || TYPE_LANG_FLAG_5 (t))
+
+/* Set IS_AGGR_TYPE for T to VAL. T must be a class, struct, or
+ union type. */
+#define SET_IS_AGGR_TYPE(T, VAL) \
+ (TYPE_LANG_FLAG_5 (T) = (VAL))
/* Nonzero if T is a class type. Zero for template type parameters,
typename types, and so forth. */
#define CLASS_TYPE_P(t) \
- (IS_AGGR_TYPE (t) && IS_AGGR_TYPE_CODE (TREE_CODE (t)))
+ (IS_AGGR_TYPE_CODE (TREE_CODE (t)) && IS_AGGR_TYPE (t))
#define IS_AGGR_TYPE_CODE(t) (t == RECORD_TYPE || t == UNION_TYPE)
#define IS_AGGR_TYPE_2(TYPE1,TYPE2) \
@@ -551,6 +619,32 @@ enum languages { lang_c, lang_cplusplus, lang_java };
/* True if this a "Java" type, defined in 'extern "Java"'. */
#define TYPE_FOR_JAVA(NODE) TYPE_LANG_FLAG_3(NODE)
+/* The type qualifiers for this type, including the qualifiers on the
+ elements for an array type. */
+#define CP_TYPE_QUALS(NODE) \
+ ((TREE_CODE (NODE) != ARRAY_TYPE) \
+ ? TYPE_QUALS (NODE) : cp_type_quals (NODE))
+
+/* Nonzero if this type is const-qualified. */
+#define CP_TYPE_CONST_P(NODE) \
+ ((CP_TYPE_QUALS (NODE) & TYPE_QUAL_CONST) != 0)
+
+/* Nonzero if this type is volatile-qualified. */
+#define CP_TYPE_VOLATILE_P(NODE) \
+ ((CP_TYPE_QUALS (NODE) & TYPE_QUAL_VOLATILE) != 0)
+
+/* Nonzero if this type is restrict-qualified. */
+#define CP_TYPE_RESTRICT_P(NODE) \
+ ((CP_TYPE_QUALS (NODE) & TYPE_QUAL_RESTRICT) != 0)
+
+/* Nonzero if this type is const-qualified, but not
+ volatile-qualified. Other qualifiers are ignored. This macro is
+ used to test whether or not it is OK to bind an rvalue to a
+ reference. */
+#define CP_TYPE_CONST_NON_VOLATILE_P(NODE) \
+ ((CP_TYPE_QUALS (NODE) & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE)) \
+ == TYPE_QUAL_CONST)
+
#define DELTA_FROM_VTABLE_ENTRY(ENTRY) \
(!flag_vtable_thunks ? \
TREE_VALUE (CONSTRUCTOR_ELTS (ENTRY)) \
@@ -579,23 +673,31 @@ enum languages { lang_c, lang_cplusplus, lang_java };
#define ACCESSIBLY_UNIQUELY_DERIVED_P(PARENT, TYPE) (get_base_distance (PARENT, TYPE, 1, (tree *)0) >= 0)
#define DERIVED_FROM_P(PARENT, TYPE) (get_base_distance (PARENT, TYPE, 0, (tree *)0) != -1)
-/* Statistics show that while the GNU C++ compiler may generate
- thousands of different types during a compilation run, it
- generates relatively few (tens) of classtypes. Because of this,
- it is not costly to store a generous amount of information
- in classtype nodes. This struct must fill out to a multiple of 4 bytes. */
+/* This structure provides additional information above and beyond
+ what is provide in the ordinary tree_type. In the past, we used it
+ for the types of class types, template parameters types, typename
+ types, and so forth. However, there can be many (tens to hundreds
+ of thousands) of template parameter types in a compilation, and
+ there's no need for this additional information in that case.
+ Therefore, we now use this data structure only for class types.
+
+ In the past, it was thought that there would be relatively few
+ class types. However, in the presence of heavy use of templates,
+ many (i.e., thousands) of classes can easily be generated.
+ Therefore, we should endeavor to keep the size of this structure to
+ a minimum. */
struct lang_type
{
struct
{
unsigned has_type_conversion : 1;
unsigned has_init_ref : 1;
- unsigned has_assignment : 1;
unsigned has_default_ctor : 1;
unsigned uses_multiple_inheritance : 1;
unsigned const_needs_init : 1;
unsigned ref_needs_init : 1;
unsigned has_const_assign_ref : 1;
+ unsigned anon_union : 1;
unsigned has_nonpublic_ctor : 2;
unsigned has_nonpublic_assign_ref : 2;
@@ -609,43 +711,39 @@ struct lang_type
unsigned has_arrow_overloaded : 1;
unsigned interface_only : 1;
unsigned interface_unknown : 1;
-
unsigned needs_virtual_reinit : 1;
+
+ unsigned marks: 6;
unsigned vec_delete_takes_size : 1;
unsigned declared_class : 1;
+
unsigned being_defined : 1;
unsigned redefined : 1;
- unsigned marked : 1;
- unsigned marked2 : 1;
- unsigned marked3 : 1;
-
- unsigned marked4 : 1;
- unsigned marked5 : 1;
- unsigned marked6 : 1;
unsigned debug_requested : 1;
unsigned use_template : 2;
unsigned got_semicolon : 1;
unsigned ptrmemfunc_flag : 1;
-
unsigned is_signature : 1;
+
unsigned is_signature_pointer : 1;
unsigned is_signature_reference : 1;
unsigned has_opaque_typedecls : 1;
unsigned sigtable_has_been_generated : 1;
unsigned was_anonymous : 1;
- unsigned has_real_assignment : 1;
unsigned has_real_assign_ref : 1;
-
unsigned has_const_init_ref : 1;
unsigned has_complex_init_ref : 1;
+
unsigned has_complex_assign_ref : 1;
unsigned has_abstract_assign_ref : 1;
unsigned non_aggregate : 1;
+ unsigned is_partial_instantiation : 1;
+ unsigned has_mutable : 1;
/* The MIPS compiler gets it wrong if this struct also
does not fill out to a multiple of 4 bytes. Add a
member `dummy' with new bits if you go over the edge. */
- unsigned dummy : 12;
+ unsigned dummy : 11;
} type_flags;
int n_ancestors;
@@ -681,14 +779,10 @@ struct lang_type
union tree_node *signature;
union tree_node *signature_pointer_to;
union tree_node *signature_reference_to;
-
union tree_node *template_info;
-
- int linenum;
+ tree befriending_classes;
};
-#define CLASSTYPE_SOURCE_LINE(NODE) (TYPE_LANG_SPECIFIC(NODE)->linenum)
-
/* Indicates whether or not (and how) a template was expanded for this class.
0=no information yet/non-template class
1=implicit template instantiation
@@ -702,13 +796,6 @@ struct lang_type
/* List of friends which were defined inline in this class definition. */
#define CLASSTYPE_INLINE_FRIENDS(NODE) (TYPE_NONCOPIED_PARTS (NODE))
-/* Nonzero for _CLASSTYPE means that the _CLASSTYPE either has
- a special meaning for the assignment operator ("operator="),
- or one of its fields (or base members) has a special meaning
- defined. */
-#define TYPE_HAS_ASSIGNMENT(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.has_assignment)
-#define TYPE_HAS_REAL_ASSIGNMENT(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.has_real_assignment)
-
/* Nonzero for _CLASSTYPE means that operator new and delete are defined,
respectively. */
#define TYPE_GETS_NEW(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.gets_new)
@@ -807,11 +894,11 @@ struct lang_type
#define TYPE_USES_VIRTUAL_BASECLASSES(NODE) (TREE_LANG_FLAG_3(NODE))
/* Vector member functions defined in this class. Each element is
- either a FUNCTION_DECL, a TEMPLATE_DECL, or an OVERLOAD. The first
+ either a FUNCTION_DECL, a TEMPLATE_DECL, or an OVERLOAD. All
+ functions with the same name end up in the same slot. The first
two elements are for constructors, and destructors, respectively.
- Any user-defined conversion operators follow these. These are
- followed by ordinary member functions. There may be empty entries
- at the end of the vector. */
+ These are followed by ordinary member functions. There may be
+ empty entries at the end of the vector. */
#define CLASSTYPE_METHOD_VEC(NODE) (TYPE_LANG_SPECIFIC(NODE)->methods)
/* The first type conversion operator in the class (the others can be
@@ -827,25 +914,45 @@ struct lang_type
#define CLASSTYPE_BASELINK_VEC(NODE) (TYPE_LANG_SPECIFIC(NODE)->baselink_vec)
/* Mark bits for depth-first and breath-first searches. */
-#define CLASSTYPE_MARKED(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.marked)
-#define CLASSTYPE_MARKED2(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.marked2)
-#define CLASSTYPE_MARKED3(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.marked3)
-#define CLASSTYPE_MARKED4(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.marked4)
-#define CLASSTYPE_MARKED5(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.marked5)
-#define CLASSTYPE_MARKED6(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.marked6)
+
+/* Get the value of the Nth mark bit. */
+#define CLASSTYPE_MARKED_N(NODE, N) \
+ (((CLASS_TYPE_P (NODE) ? TYPE_LANG_SPECIFIC (NODE)->type_flags.marks \
+ : TYPE_ALIAS_SET (NODE)) & (1 << N)) != 0)
+
+/* Set the Nth mark bit. */
+#define SET_CLASSTYPE_MARKED_N(NODE, N) \
+ (CLASS_TYPE_P (NODE) \
+ ? (TYPE_LANG_SPECIFIC (NODE)->type_flags.marks |= (1 << (N))) \
+ : (TYPE_ALIAS_SET (NODE) |= (1 << (N))))
+
+/* Clear the Nth mark bit. */
+#define CLEAR_CLASSTYPE_MARKED_N(NODE, N) \
+ (CLASS_TYPE_P (NODE) \
+ ? (TYPE_LANG_SPECIFIC (NODE)->type_flags.marks &= ~(1 << (N))) \
+ : (TYPE_ALIAS_SET (NODE) &= ~(1 << (N))))
+
+/* Get the value of the mark bits. */
+#define CLASSTYPE_MARKED(NODE) CLASSTYPE_MARKED_N(NODE, 0)
+#define CLASSTYPE_MARKED2(NODE) CLASSTYPE_MARKED_N(NODE, 1)
+#define CLASSTYPE_MARKED3(NODE) CLASSTYPE_MARKED_N(NODE, 2)
+#define CLASSTYPE_MARKED4(NODE) CLASSTYPE_MARKED_N(NODE, 3)
+#define CLASSTYPE_MARKED5(NODE) CLASSTYPE_MARKED_N(NODE, 4)
+#define CLASSTYPE_MARKED6(NODE) CLASSTYPE_MARKED_N(NODE, 5)
+
/* Macros to modify the above flags */
-#define SET_CLASSTYPE_MARKED(NODE) (CLASSTYPE_MARKED(NODE) = 1)
-#define CLEAR_CLASSTYPE_MARKED(NODE) (CLASSTYPE_MARKED(NODE) = 0)
-#define SET_CLASSTYPE_MARKED2(NODE) (CLASSTYPE_MARKED2(NODE) = 1)
-#define CLEAR_CLASSTYPE_MARKED2(NODE) (CLASSTYPE_MARKED2(NODE) = 0)
-#define SET_CLASSTYPE_MARKED3(NODE) (CLASSTYPE_MARKED3(NODE) = 1)
-#define CLEAR_CLASSTYPE_MARKED3(NODE) (CLASSTYPE_MARKED3(NODE) = 0)
-#define SET_CLASSTYPE_MARKED4(NODE) (CLASSTYPE_MARKED4(NODE) = 1)
-#define CLEAR_CLASSTYPE_MARKED4(NODE) (CLASSTYPE_MARKED4(NODE) = 0)
-#define SET_CLASSTYPE_MARKED5(NODE) (CLASSTYPE_MARKED5(NODE) = 1)
-#define CLEAR_CLASSTYPE_MARKED5(NODE) (CLASSTYPE_MARKED5(NODE) = 0)
-#define SET_CLASSTYPE_MARKED6(NODE) (CLASSTYPE_MARKED6(NODE) = 1)
-#define CLEAR_CLASSTYPE_MARKED6(NODE) (CLASSTYPE_MARKED6(NODE) = 0)
+#define SET_CLASSTYPE_MARKED(NODE) SET_CLASSTYPE_MARKED_N(NODE, 0)
+#define CLEAR_CLASSTYPE_MARKED(NODE) CLEAR_CLASSTYPE_MARKED_N(NODE, 0)
+#define SET_CLASSTYPE_MARKED2(NODE) SET_CLASSTYPE_MARKED_N(NODE, 1)
+#define CLEAR_CLASSTYPE_MARKED2(NODE) CLEAR_CLASSTYPE_MARKED_N(NODE, 1)
+#define SET_CLASSTYPE_MARKED3(NODE) SET_CLASSTYPE_MARKED_N(NODE, 2)
+#define CLEAR_CLASSTYPE_MARKED3(NODE) CLEAR_CLASSTYPE_MARKED_N(NODE, 2)
+#define SET_CLASSTYPE_MARKED4(NODE) SET_CLASSTYPE_MARKED_N(NODE, 3)
+#define CLEAR_CLASSTYPE_MARKED4(NODE) CLEAR_CLASSTYPE_MARKED_N(NODE, 3)
+#define SET_CLASSTYPE_MARKED5(NODE) SET_CLASSTYPE_MARKED_N(NODE, 4)
+#define CLEAR_CLASSTYPE_MARKED5(NODE) CLEAR_CLASSTYPE_MARKED_N(NODE, 4)
+#define SET_CLASSTYPE_MARKED6(NODE) SET_CLASSTYPE_MARKED_N(NODE, 5)
+#define CLEAR_CLASSTYPE_MARKED6(NODE) CLEAR_CLASSTYPE_MARKED_N(NODE, 5)
/* A list of the nested tag-types (class, struct, union, or enum)
found within this class. The TREE_PURPOSE of each node is the name
@@ -936,6 +1043,10 @@ struct lang_type
/* Ditto, for operator=. */
#define TYPE_HAS_NONPUBLIC_ASSIGN_REF(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.has_nonpublic_assign_ref)
+/* Nonzero means that this type contains a mutable member */
+#define CLASSTYPE_HAS_MUTABLE(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.has_mutable)
+#define TYPE_HAS_MUTABLE_P(NODE) (cp_has_mutable_p (NODE))
+
/* Many routines need to cons up a list of basetypes for access
checking. This field contains a TREE_LIST node whose TREE_VALUE
is the main variant of the type, and whose TREE_VIA_PUBLIC
@@ -946,11 +1057,15 @@ struct lang_type
/* Same, but cache a list whose value is the binfo of this type. */
#define CLASSTYPE_BINFO_AS_LIST(NODE) (TYPE_LANG_SPECIFIC(NODE)->binfo_as_list)
-/* A list of class types with which this type is a friend. The
+/* A list of class types of which this type is a friend. The
TREE_VALUE is normally a TYPE, but will be a TEMPLATE_DECL in the
case of a template friend. */
#define CLASSTYPE_FRIEND_CLASSES(NODE) (TYPE_LANG_SPECIFIC(NODE)->friend_classes)
+/* A list of the classes which grant friendship to this class. */
+#define CLASSTYPE_BEFRIENDING_CLASSES(NODE) \
+ (TYPE_LANG_SPECIFIC (NODE)->befriending_classes)
+
/* Say whether this node was declared as a "class" or a "struct". */
#define CLASSTYPE_DECLARED_CLASS(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.declared_class)
@@ -980,11 +1095,16 @@ struct lang_type
gcc/tree.h. In particular if D is derived from B then the BINFO
for B (in D) will have a BINFO_INHERITANCE_CHAIN pointing to
D. In tree.h, this pointer is described as pointing in other
- direction.
+ direction. There is a different BINFO for each path to a virtual
+ base; BINFOs for virtual bases are not shared. In addition, shared
+ versions of each of the virtual class BINFOs are stored in
+ CLASSTYPE_VBASECLASSES.
+
+ We use TREE_VIA_PROTECTED and TREE_VIA_PUBLIC, but private
+ inheritance is indicated by the absence of the other two flags, not
+ by TREE_VIAR_PRIVATE, which is unused.
- After a call to get_vbase_types, the vbases are chained together in
- depth-first order via TREE_CHAIN. Other than that, TREE_CHAIN is
- unused. */
+ The TREE_CHAIN is for scratch space in search.c. */
/* Nonzero means marked by DFS or BFS search, including searches
by `get_binfo' and `get_base_distance'. */
@@ -1022,6 +1142,9 @@ struct lang_type
#define BINFO_PUSHDECLS_MARKED(NODE) BINFO_VTABLE_PATH_MARKED (NODE)
#define SET_BINFO_PUSHDECLS_MARKED(NODE) SET_BINFO_VTABLE_PATH_MARKED (NODE)
#define CLEAR_BINFO_PUSHDECLS_MARKED(NODE) CLEAR_BINFO_VTABLE_PATH_MARKED (NODE)
+
+/* Used by various search routines. */
+#define IDENTIFIER_MARKED(NODE) TREE_LANG_FLAG_0 (NODE)
/* Accessor macros for the vfield slots in structures. */
@@ -1042,12 +1165,23 @@ struct lang_type
#define TREE_PARMLIST(NODE) ((NODE)->common.unsigned_flag) /* overloaded! */
/* For FUNCTION_TYPE or METHOD_TYPE, a list of the exceptions that
- this type can raise. */
+ this type can raise. Each TREE_VALUE is a _TYPE. The TREE_VALUE
+ will be NULL_TREE to indicate a throw specification of `(...)', or,
+ equivalently, no throw specification. */
#define TYPE_RAISES_EXCEPTIONS(NODE) TYPE_NONCOPIED_PARTS (NODE)
/* The binding level associated with the namespace. */
#define NAMESPACE_LEVEL(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.level)
+
+/* If a DECL has DECL_LANG_SPECIFIC, it is either a lang_decl_flags or
+ a lang_decl (which has lang_decl_flags as its initial prefix). A
+ FUNCTION_DECL, NAMESPACE_DECL, TYPE_DECL, or USING_DECL may have a
+ full lang_decl. A FIELD_DECL, or a static data member VAR_DECL,
+ will have only lang_decl_flags. Thus, one should only access the
+ members of lang_decl that are not in lang_decl_flags for DECLs that
+ are not FIELD_DECLs or VAR_DECLs. */
+
struct lang_decl_flags
{
#ifdef ONLY_INT_FIELDS
@@ -1078,7 +1212,9 @@ struct lang_decl_flags
unsigned not_really_extern : 1;
unsigned comdat : 1;
unsigned needs_final_overrider : 1;
- unsigned dummy : 3;
+ unsigned bitfield : 1;
+ unsigned defined_in_class : 1;
+ unsigned dummy : 1;
tree access;
tree context;
@@ -1092,6 +1228,7 @@ struct lang_decl
struct lang_decl_flags decl_flags;
tree main_decl_variant;
+ tree befriending_classes;
struct pending_inline *pending_inline_info;
};
@@ -1113,7 +1250,15 @@ struct lang_decl
/* For FUNCTION_DECLs: nonzero means that this function is a constructor. */
#define DECL_CONSTRUCTOR_P(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.constructor_attr)
-#define DECL_DESTRUCTOR_P(NODE) (DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME(NODE)))
+
+/* There ought to be a better way to find out whether or not something is
+ a destructor. */
+#define DECL_DESTRUCTOR_P(NODE) \
+ (DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (NODE)) \
+ && DECL_LANGUAGE (NODE) == lang_cplusplus)
+
+#define DECL_CONV_FN_P(NODE) \
+ (IDENTIFIER_TYPENAME_P (DECL_NAME (NODE)) && TREE_TYPE (DECL_NAME (NODE)))
/* For FUNCTION_DECLs: nonzero means that this function is a constructor
for an object with virtual baseclasses. */
@@ -1140,11 +1285,20 @@ struct lang_decl
should be allocated. */
#define DECL_IN_AGGR_P(NODE) (DECL_LANG_FLAG_3(NODE))
+/* Nonzero if the DECL was defined in the class definition itself,
+ rather than outside the class. */
+#define DECL_DEFINED_IN_CLASS_P(DECL) \
+ (DECL_LANG_SPECIFIC (DECL)->decl_flags.defined_in_class)
+
/* Nonzero for FUNCTION_DECL means that this decl is just a
friend declaration, and should not be added to the list of
member functions for this class. */
#define DECL_FRIEND_P(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.friend_attr)
+/* A TREE_LIST of the types which have befriended this FUNCTION_DECL. */
+#define DECL_BEFRIENDING_CLASSES(NODE) \
+ (DECL_LANG_SPECIFIC(NODE)->befriending_classes)
+
/* Nonzero for FUNCTION_DECL means that this decl is a static
member function. */
#define DECL_STATIC_FUNCTION_P(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.static_function)
@@ -1173,6 +1327,12 @@ struct lang_decl
has `this' as volatile X *const. */
#define DECL_VOLATILE_MEMFUNC_P(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.volatile_memfunc)
+/* Nonzero for a DECL means that this member is a non-static member. */
+#define DECL_NONSTATIC_MEMBER_P(NODE) \
+ ((TREE_CODE (NODE) == FUNCTION_DECL \
+ && DECL_NONSTATIC_MEMBER_FUNCTION_P (NODE)) \
+ || TREE_CODE (NODE) == FIELD_DECL)
+
/* Nonzero for _DECL means that this member object type
is mutable. */
#define DECL_MUTABLE_P(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.mutable_flag)
@@ -1215,6 +1375,11 @@ struct lang_decl
(DECL_CONTEXT (NODE) \
&& TREE_CODE_CLASS (TREE_CODE (DECL_CONTEXT (NODE))) == 't')
+/* 1 iff NODE is function-local. */
+#define DECL_FUNCTION_SCOPE_P(NODE) \
+ (DECL_CONTEXT (NODE) \
+ && TREE_CODE (DECL_CONTEXT (NODE)) == FUNCTION_DECL)
+
/* For a NAMESPACE_DECL: the list of using namespace directives
The PURPOSE is the used namespace, the value is the namespace
that is the common ancestor. */
@@ -1271,10 +1436,16 @@ struct lang_decl
non-type template parameters. */
#define ENUM_TEMPLATE_INFO(NODE) (TYPE_BINFO (NODE))
+/* Template information for a template template parameter. */
+#define TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO(NODE) (TYPE_BINFO (NODE))
+
/* Template information for an ENUMERAL_, RECORD_, or UNION_TYPE. */
-#define TYPE_TEMPLATE_INFO(NODE) \
- (TREE_CODE (NODE) == ENUMERAL_TYPE \
- ? ENUM_TEMPLATE_INFO (NODE) : CLASSTYPE_TEMPLATE_INFO (NODE))
+#define TYPE_TEMPLATE_INFO(NODE) \
+ (TREE_CODE (NODE) == ENUMERAL_TYPE \
+ ? ENUM_TEMPLATE_INFO (NODE) : \
+ (TREE_CODE (NODE) == TEMPLATE_TEMPLATE_PARM \
+ ? TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (NODE) \
+ : CLASSTYPE_TEMPLATE_INFO (NODE)))
/* Set the template information for an ENUMERAL_, RECORD_, or
UNION_TYPE to VAL. */
@@ -1332,6 +1503,9 @@ struct lang_decl
#define INNERMOST_TEMPLATE_PARMS(NODE) TREE_VALUE(NODE)
+/* Nonzero if the NODE corresponds to the template parameters for a
+ member template, whose inline definition is being processed after
+ the class definition is complete. */
#define TEMPLATE_PARMS_FOR_INLINE(NODE) TREE_LANG_FLAG_1 (NODE)
#define DECL_SAVED_TREE(NODE) DECL_MEMFUNC_POINTER_TO (NODE)
@@ -1350,7 +1524,15 @@ struct lang_decl
&& !CLASSTYPE_USE_TEMPLATE (NODE) \
&& PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (NODE)))
-#define TYPENAME_TYPE_FULLNAME(NODE) CLASSTYPE_SIZE (NODE)
+/* The name used by the user to name the typename type. Typically,
+ this is an IDENTIFIER_NODE, and the same as the DECL_NAME on the
+ corresponding TYPE_DECL. However, this may also be a
+ TEMPLATE_ID_EXPR if we had something like `typename X::Y<T>'. */
+#define TYPENAME_TYPE_FULLNAME(NODE) TYPE_BINFO (NODE)
+
+/* Nonzero if NODE is an implicit typename. */
+#define IMPLICIT_TYPENAME_P(NODE) \
+ (TREE_CODE (NODE) == TYPENAME_TYPE && TREE_TYPE (NODE))
/* Nonzero in INTEGER_CST means that this int is negative by dint of
using a twos-complement negated operand. */
@@ -1371,7 +1553,7 @@ struct lang_decl
/* Nonzero in IDENTIFIER_NODE means that this name is not the name the user
gave; it's a DECL_NESTED_TYPENAME. Someone may want to set this on
mangled function names, too, but it isn't currently. */
-#define TREE_MANGLED(NODE) (TREE_LANG_FLAG_0 (NODE))
+#define TREE_MANGLED(NODE) (FOO)
#endif
#if 0 /* UNUSED */
@@ -1407,6 +1589,12 @@ extern int flag_new_for_scope;
/* Record whether a typedef for type `int' was actually `signed int'. */
#define C_TYPEDEF_EXPLICITLY_SIGNED(exp) DECL_LANG_FLAG_1 ((exp))
+/* In a FIELD_DECL, nonzero if the decl was originally a bitfield. */
+#define DECL_C_BIT_FIELD(NODE) \
+ (DECL_LANG_SPECIFIC (NODE) && DECL_LANG_SPECIFIC (NODE)->decl_flags.bitfield)
+#define SET_DECL_C_BIT_FIELD(NODE) \
+ (DECL_LANG_SPECIFIC (NODE)->decl_flags.bitfield = 1)
+
/* Nonzero if the type T promotes to itself.
ANSI C states explicitly the list of types that promote;
in particular, short promotes to int even if they have the same width. */
@@ -1446,8 +1634,9 @@ extern int flag_new_for_scope;
has been duly initialized in its constructor. */
#define TREE_HAS_CONSTRUCTOR(NODE) (TREE_LANG_FLAG_4(NODE))
-#define EMPTY_CONSTRUCTOR_P(NODE) (TREE_CODE (NODE) == CONSTRUCTOR \
- && CONSTRUCTOR_ELTS (NODE) == NULL_TREE)
+#define EMPTY_CONSTRUCTOR_P(NODE) (TREE_CODE (NODE) == CONSTRUCTOR \
+ && CONSTRUCTOR_ELTS (NODE) == NULL_TREE \
+ && ! TREE_HAS_CONSTRUCTOR (NODE))
#if 0
/* Indicates that a NON_LVALUE_EXPR came from a C++ reference.
@@ -1511,8 +1700,63 @@ extern int flag_new_for_scope;
/* Nonzero for _TYPE node means that this type is a pointer to member
function type. */
-#define TYPE_PTRMEMFUNC_P(NODE) (TREE_CODE(NODE) == RECORD_TYPE && TYPE_LANG_SPECIFIC(NODE)->type_flags.ptrmemfunc_flag)
-#define TYPE_PTRMEMFUNC_FLAG(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.ptrmemfunc_flag)
+#define TYPE_PTRMEMFUNC_P(NODE) \
+ (TREE_CODE(NODE) == RECORD_TYPE && TYPE_PTRMEMFUNC_FLAG (NODE))
+#define TYPE_PTRMEMFUNC_FLAG(NODE) \
+ (TYPE_LANG_SPECIFIC(NODE)->type_flags.ptrmemfunc_flag)
+
+/* A pointer-to-function member type looks like:
+
+ struct {
+ short __delta;
+ short __index;
+ union {
+ P __pfn;
+ short __delta2;
+ } __pfn_or_delta2;
+ };
+
+ where P is a POINTER_TYPE to a METHOD_TYPE appropriate for the
+ pointer to member. The fields are used as follows:
+
+ If __INDEX is -1, then the function to call is non-virtual, and
+ is located at the address given by __PFN.
+
+ If __INDEX is zero, then this a NULL pointer-to-member.
+
+ Otherwise, the function to call is virtual. Then, __DELTA2 gives
+ the offset from an instance of the object to the virtual function
+ table, and __INDEX - 1 is the index into the vtable to use to
+ find the function.
+
+ The value to use for the THIS parameter is the address of the
+ object plus __DELTA.
+
+ For example, given:
+
+ struct B1 {
+ int i;
+ };
+
+ struct B2 {
+ double d;
+ void f();
+ };
+
+ struct S : public B1, B2 {};
+
+ the pointer-to-member for `&S::f' looks like:
+
+ { 4, -1, { &f__2B2 } };
+
+ The `4' means that given an `S*' you have to add 4 bytes to get to
+ the address of the `B2*'. Then, the -1 indicates that this is a
+ non-virtual function. Of course, `&f__2B2' is the name of that
+ function.
+
+ (Of course, the exactl values may differ depending on the mangling
+ scheme, sizes of types, and such.). */
+
/* Get the POINTER_TYPE to the METHOD_TYPE associated with this
pointer to member function. TYPE_PTRMEMFUNC_P _must_ be true,
before using this macro. */
@@ -1527,14 +1771,14 @@ extern int flag_new_for_scope;
#define TYPE_GET_PTRMEMFUNC_TYPE(NODE) ((tree)TYPE_LANG_SPECIFIC(NODE))
#define TYPE_SET_PTRMEMFUNC_TYPE(NODE, VALUE) (TYPE_LANG_SPECIFIC(NODE) = ((struct lang_type *)(void*)(VALUE)))
/* These are to get the delta2 and pfn fields from a TYPE_PTRMEMFUNC_P. */
-#define DELTA2_FROM_PTRMEMFUNC(NODE) (build_component_ref (build_component_ref ((NODE), pfn_or_delta2_identifier, NULL_TREE, 0), delta2_identifier, NULL_TREE, 0))
-#define PFN_FROM_PTRMEMFUNC(NODE) (build_component_ref (build_component_ref ((NODE), pfn_or_delta2_identifier, NULL_TREE, 0), pfn_identifier, NULL_TREE, 0))
+#define DELTA2_FROM_PTRMEMFUNC(NODE) delta2_from_ptrmemfunc ((NODE))
+#define PFN_FROM_PTRMEMFUNC(NODE) pfn_from_ptrmemfunc ((NODE))
/* For a pointer-to-member constant `X::Y' this is the RECORD_TYPE for
`X'. */
-#define PTRMEM_CST_CLASS(NODE) \
- (TYPE_PTRMEM_P (TREE_TYPE (NODE)) \
- ? TYPE_OFFSET_BASETYPE (TREE_TYPE (NODE)) \
+#define PTRMEM_CST_CLASS(NODE) \
+ (TYPE_PTRMEM_P (TREE_TYPE (NODE)) \
+ ? TYPE_OFFSET_BASETYPE (TREE_TYPE (TREE_TYPE (NODE))) \
: TYPE_PTRMEMFUNC_OBJECT_TYPE (TREE_TYPE (NODE)))
/* For a pointer-to-member constant `X::Y' this is the _DECL for
@@ -1549,19 +1793,20 @@ extern int flag_new_for_scope;
specified in its declaration. */
#define DECL_THIS_STATIC(NODE) (DECL_LANG_FLAG_6(NODE))
-/* Nonzero for SAVE_EXPR if used to initialize a PARM_DECL. */
-#define PARM_DECL_EXPR(NODE) (TREE_LANG_FLAG_2(NODE))
-
/* Nonzero in FUNCTION_DECL means it is really an operator.
Just used to communicate formatting information to dbxout.c. */
#define DECL_OPERATOR(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.operator_attr)
#define ANON_UNION_P(NODE) (DECL_NAME (NODE) == 0)
-/* Nonzero if TYPE is an anonymous union type. */
-#define ANON_UNION_TYPE_P(TYPE) \
- (TREE_CODE (TYPE) == UNION_TYPE \
- && ANON_AGGRNAME_P (TYPE_IDENTIFIER (TYPE)))
+/* Nonzero if TYPE is an anonymous union type. We have to use a flag for
+ this because "A union for which objects or pointers are declared is not
+ an anonymous union" [class.union]. */
+#define ANON_UNION_TYPE_P(NODE) \
+ (TYPE_LANG_SPECIFIC (NODE) \
+ && TYPE_LANG_SPECIFIC (NODE)->type_flags.anon_union)
+#define SET_ANON_UNION_TYPE_P(NODE) \
+ (TYPE_LANG_SPECIFIC (NODE)->type_flags.anon_union = 1)
#define UNKNOWN_TYPE LANG_TYPE
@@ -1595,9 +1840,15 @@ extern int flag_new_for_scope;
the TREE_PUROSE will be the class type, and the TREE_VALUE will be
NULL_TREE. */
#define DECL_FRIENDLIST(NODE) (DECL_INITIAL (NODE))
+#define FRIEND_NAME(LIST) (TREE_PURPOSE (LIST))
+#define FRIEND_DECLS(LIST) (TREE_VALUE (LIST))
-/* The DECL_ACCESS is used to record under which context
- special access rules apply. */
+/* The DECL_ACCESS, if non-NULL, is a TREE_LIST. The TREE_PURPOSE of
+ each node is a type; the TREE_VALUE is the access granted for this
+ DECL in that type. The DECL_ACCESS is set by access declarations.
+ For example, if a member that would normally be public in a
+ derived class is made protected, then the derived class and the
+ protected_access_node will appear in the DECL_ACCESS for the node. */
#define DECL_ACCESS(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.access)
/* C++: all of these are overloaded!
@@ -1684,11 +1935,12 @@ extern int flag_new_for_scope;
#define DECL_TEMPLATE_SPECIALIZATIONS(NODE) DECL_SIZE(NODE)
#define DECL_TEMPLATE_INJECT(NODE) DECL_INITIAL(NODE)
-/* Nonzero for TEMPLATE_DECL nodes that represents template template
- parameters */
+/* Nonzero for a DECL which is actually a template parameter. */
+#define DECL_TEMPLATE_PARM_P(NODE) \
+ DECL_LANG_FLAG_0 (NODE)
+
#define DECL_TEMPLATE_TEMPLATE_PARM_P(NODE) \
- (TREE_CODE (NODE) == TEMPLATE_DECL && TREE_TYPE (NODE) \
- && TREE_CODE (TREE_TYPE (NODE)) == TEMPLATE_TEMPLATE_PARM)
+ (TREE_CODE (NODE) == TEMPLATE_DECL && DECL_TEMPLATE_PARM_P (NODE))
#define DECL_FUNCTION_TEMPLATE_P(NODE) \
(TREE_CODE (NODE) == TEMPLATE_DECL \
@@ -1761,6 +2013,12 @@ extern int flag_new_for_scope;
#define DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION(DECL) \
(DECL_TEMPLATE_INFO (DECL) && !DECL_USE_TEMPLATE (DECL))
+/* Non-zero if TYPE is a partial instantiation of a template class,
+ i.e., an instantiation whose instantiation arguments involve
+ template types. */
+#define PARTIAL_INSTANTIATION_P(TYPE) \
+ (TYPE_LANG_SPECIFIC (TYPE)->type_flags.is_partial_instantiation)
+
/* Non-zero iff we are currently processing a declaration for an
entity with its own template parameter list, and which is not a
full specialization. */
@@ -1769,6 +2027,12 @@ extern int flag_new_for_scope;
/* This function may be a guiding decl for a template. */
#define DECL_MAYBE_TEMPLATE(NODE) DECL_LANG_FLAG_4 (NODE)
+
+/* Nonzero if this VAR_DECL or FUNCTION_DECL has already been
+ instantiated, i.e. its definition has been generated from the
+ pattern given in the the template. */
+#define DECL_TEMPLATE_INSTANTIATED(NODE) DECL_LANG_FLAG_1(NODE)
+
/* We know what we're doing with this decl now. */
#define DECL_INTERFACE_KNOWN(NODE) DECL_LANG_FLAG_5 (NODE)
@@ -1875,7 +2139,7 @@ extern void check_function_format PROTO((tree, tree, tree));
/* Print an error message for invalid operands to arith operation CODE.
NOP_EXPR is used as a special case (see truthvalue_conversion). */
extern void binary_op_error PROTO((enum tree_code));
-extern tree cp_build_type_variant PROTO((tree, int, int));
+extern tree cp_build_qualified_type PROTO((tree, int));
extern tree canonical_type_variant PROTO((tree));
extern void c_expand_expr_stmt PROTO((tree));
/* Validate the expression after `case' and apply default promotions. */
@@ -1886,6 +2150,7 @@ extern void constant_expression_warning PROTO((tree));
extern tree convert_and_check PROTO((tree, tree));
extern void overflow_warning PROTO((tree));
extern void unsigned_conversion_warning PROTO((tree, tree));
+extern void c_apply_type_quals_to_decl PROTO((int, tree));
/* Read the rest of the current #-directive line. */
#if USE_CPPLIB
@@ -1933,6 +2198,10 @@ extern tree null_node;
extern tree anonymous_namespace_name;
+/* The FUNCTION_DECL for the default `::operator delete'. */
+
+extern tree global_delete_fndecl;
+
/* in pt.c */
/* These values are used for the `STRICT' parameter to type_unfication and
@@ -1997,12 +2266,6 @@ extern int current_function_parms_stored;
#define OPERATOR_ASSIGN_FORMAT "__a%s"
#define OPERATOR_FORMAT "__%s"
#define OPERATOR_TYPENAME_FORMAT "__op"
-#define OPERATOR_TYPENAME_P(ID_NODE) \
- (IDENTIFIER_POINTER (ID_NODE)[0] == '_' \
- && IDENTIFIER_POINTER (ID_NODE)[1] == '_' \
- && IDENTIFIER_POINTER (ID_NODE)[2] == 'o' \
- && IDENTIFIER_POINTER (ID_NODE)[3] == 'p')
-
/* Cannot use '$' up front, because this confuses gdb
(names beginning with '$' are gdb-local identifiers).
@@ -2125,9 +2388,9 @@ extern int current_function_parms_stored;
#define SIGNATURE_OPTR_NAME "__optr"
#define SIGNATURE_SPTR_NAME "__sptr"
#define SIGNATURE_POINTER_NAME "__sp_"
-#define SIGNATURE_POINTER_NAME_FORMAT "__%s%ssp_%s"
+#define SIGNATURE_POINTER_NAME_FORMAT "__%s%s%ssp_%s"
#define SIGNATURE_REFERENCE_NAME "__sr_"
-#define SIGNATURE_REFERENCE_NAME_FORMAT "__%s%ssr_%s"
+#define SIGNATURE_REFERENCE_NAME_FORMAT "__%s%s%ssr_%s"
#define SIGTABLE_PTR_TYPE "__sigtbl_ptr_type"
#define SIGTABLE_NAME_FORMAT "__st_%s_%s"
@@ -2154,13 +2417,6 @@ extern int current_function_parms_stored;
&& IDENTIFIER_POINTER (ID_NODE)[2] == 'b' \
&& IDENTIFIER_POINTER (ID_NODE)[3] == JOINER)
-/* Store the vbase pointer field name for type TYPE into pointer BUF. */
-#define FORMAT_VBASE_NAME(BUF,TYPE) do { \
- BUF = (char *) alloca (TYPE_ASSEMBLER_NAME_LENGTH (TYPE) \
- + sizeof (VBASE_NAME) + 1); \
- sprintf (BUF, VBASE_NAME_FORMAT, TYPE_ASSEMBLER_NAME_STRING (TYPE)); \
-} while (0)
-
#define TEMP_NAME_P(ID_NODE) (!strncmp (IDENTIFIER_POINTER (ID_NODE), AUTO_TEMP_NAME, sizeof (AUTO_TEMP_NAME)-1))
#define VFIELD_NAME_P(ID_NODE) (!strncmp (IDENTIFIER_POINTER (ID_NODE), VFIELD_NAME, sizeof(VFIELD_NAME)-1))
@@ -2174,6 +2430,14 @@ extern int current_function_parms_stored;
&& IDENTIFIER_POINTER (ID_NODE)[1] <= '9')
#endif /* !defined(NO_DOLLAR_IN_LABEL) || !defined(NO_DOT_IN_LABEL) */
+/* Store the vbase pointer field name for type TYPE into pointer BUF. */
+#define FORMAT_VBASE_NAME(BUF,TYPE) do { \
+ char *wbuf = (char *) alloca (TYPE_ASSEMBLER_NAME_LENGTH (TYPE) \
+ + sizeof (VBASE_NAME) + 1); \
+ sprintf (wbuf, VBASE_NAME_FORMAT, TYPE_ASSEMBLER_NAME_STRING (TYPE)); \
+ (BUF) = wbuf; \
+} while (0)
+
/* Returns non-zero iff ID_NODE is an IDENTIFIER_NODE whose name is
`main'. */
#define MAIN_NAME_P(ID_NODE) \
@@ -2183,7 +2447,7 @@ extern int current_function_parms_stored;
`main'. */
#define DECL_MAIN_P(NODE) \
(TREE_CODE (NODE) == FUNCTION_DECL \
- && DECL_CONTEXT (NODE) == NULL_TREE \
+ && DECL_LANGUAGE (NODE) == lang_c \
&& DECL_NAME (NODE) != NULL_TREE \
&& MAIN_NAME_P (DECL_NAME (NODE)))
@@ -2365,11 +2629,45 @@ extern tree current_class_name; /* IDENTIFIER_NODE: name of current class */
#define WANT_ENUM 4 /* enumerated types */
#define WANT_POINTER 8 /* pointer types */
#define WANT_NULL 16 /* null pointer constant */
-
#define WANT_ARITH (WANT_INT | WANT_FLOAT)
-#define FRIEND_NAME(LIST) (TREE_PURPOSE (LIST))
-#define FRIEND_DECLS(LIST) (TREE_VALUE (LIST))
+/* Used with comptypes, and related functions, to guide type
+ comparison. */
+
+#define COMPARE_STRICT 0 /* Just check if the types are the
+ same. */
+#define COMPARE_BASE 1 /* Check to see if the second type is
+ derived from the first, or if both
+ are pointers (or references) and
+ the types pointed to by the second
+ type is derived from the pointed to
+ by the first. */
+#define COMPARE_RELAXED 2 /* Like COMPARE_DERIVED, but in
+ reverse. Also treat enmeration
+ types as the same as integer types
+ of the same width. */
+#define COMPARE_REDECLARATION 4 /* The comparsion is being done when
+ another declaration of an existing
+ entity is seen. */
+
+/* Used with push_overloaded_decl. */
+#define PUSH_GLOBAL 0 /* Push the DECL into namespace scope,
+ regardless of the current scope. */
+#define PUSH_LOCAL 1 /* Push the DECL into the current
+ scope. */
+#define PUSH_USING 2 /* We are pushing this DECL as the
+ result of a using declaration. */
+
+/* Returns nonzero iff TYPE1 and TYPE2 are the same type, in the usual
+ sense of `same'. */
+#define same_type_p(type1, type2) \
+ comptypes ((type1), (type2), COMPARE_STRICT)
+
+/* Returns nonzero iff TYPE1 and TYPE2 are the same type, or if TYPE2
+ is derived from TYPE1, or if TYPE2 is a pointer (reference) to a
+ class derived from the type pointed to (referred to) by TYPE1. */
+#define same_or_base_type_p(type1, type2) \
+ comptypes ((type1), (type2), COMPARE_BASE)
/* These macros are used to access a TEMPLATE_PARM_INDEX. */
#define TEMPLATE_PARM_IDX(NODE) (((template_parm_index*) NODE)->index)
@@ -2415,8 +2713,8 @@ extern tree build_op_new_call PROTO((enum tree_code, tree, tree, int));
extern tree build_op_delete_call PROTO((enum tree_code, tree, tree, int, tree));
extern int can_convert PROTO((tree, tree));
extern int can_convert_arg PROTO((tree, tree, tree));
-extern void enforce_access PROTO((tree, tree));
-extern tree convert_default_arg PROTO((tree, tree));
+extern int enforce_access PROTO((tree, tree));
+extern tree convert_default_arg PROTO((tree, tree, tree));
extern tree convert_arg_to_ellipsis PROTO((tree));
/* in class.c */
@@ -2442,7 +2740,7 @@ extern tree instantiate_type PROTO((tree, tree, int));
extern void print_class_statistics PROTO((void));
extern void maybe_push_cache_obstack PROTO((void));
extern unsigned HOST_WIDE_INT skip_rtti_stuff PROTO((tree *));
-extern tree build_self_reference PROTO((void));
+extern void build_self_reference PROTO((void));
extern void warn_hidden PROTO((tree));
extern tree get_enclosing_class PROTO((tree));
int is_base_of_enclosing_class PROTO((tree, tree));
@@ -2457,7 +2755,7 @@ extern tree ocp_convert PROTO((tree, tree, int, int));
extern tree cp_convert PROTO((tree, tree));
extern tree convert PROTO((tree, tree));
extern tree convert_force PROTO((tree, tree, int));
-extern tree build_type_conversion PROTO((enum tree_code, tree, tree, int));
+extern tree build_type_conversion PROTO((tree, tree, int));
extern tree build_expr_type_conversion PROTO((int, tree, int));
extern tree type_promotes_to PROTO((tree));
extern tree perform_qualification_conversions PROTO((tree, tree));
@@ -2467,6 +2765,7 @@ extern tree perform_qualification_conversions PROTO((tree, tree));
extern void set_identifier_local_value PROTO((tree, tree));
extern int global_bindings_p PROTO((void));
extern int toplevel_bindings_p PROTO((void));
+extern int namespace_bindings_p PROTO((void));
extern void keep_next_level PROTO((void));
extern int kept_level_p PROTO((void));
extern void declare_parm_level PROTO((void));
@@ -2493,7 +2792,6 @@ extern void push_to_top_level PROTO((void));
extern void pop_from_top_level PROTO((void));
extern tree identifier_type_value PROTO((tree));
extern void set_identifier_type_value PROTO((tree, tree));
-extern void set_identifier_local_value PROTO((tree, tree));
extern void pop_everything PROTO((void));
extern void pushtag PROTO((tree, tree, int));
extern tree make_anon_name PROTO((void));
@@ -2527,6 +2825,7 @@ extern tree binding_for_name PROTO((tree, tree));
extern tree namespace_binding PROTO((tree, tree));
extern void set_namespace_binding PROTO((tree, tree, tree));
extern tree lookup_namespace_name PROTO((tree, tree));
+extern tree build_typename_type PROTO((tree, tree, tree, tree));
extern tree make_typename_type PROTO((tree, tree));
extern tree lookup_name_nonclass PROTO((tree));
extern tree lookup_function_nonclass PROTO((tree, tree));
@@ -2543,8 +2842,9 @@ extern tree auto_function PROTO((tree, tree, enum built_in_function));
extern void init_decl_processing PROTO((void));
extern int init_type_desc PROTO((void));
extern tree define_function
- PROTO((char *, tree, enum built_in_function,
- void (*) (tree), char *));
+ PROTO((const char *, tree, enum built_in_function,
+ void (*) (tree), const char *));
+extern tree check_tag_decl PROTO((tree));
extern void shadow_tag PROTO((tree));
extern tree groktypename PROTO((tree));
extern tree start_decl PROTO((tree, tree, int, tree, tree));
@@ -2570,7 +2870,7 @@ extern void expand_start_early_try_stmts PROTO((void));
extern void store_parm_decls PROTO((void));
extern void store_return_init PROTO((tree, tree));
extern void finish_function PROTO((int, int, int));
-extern tree start_method PROTO((tree, tree));
+extern tree start_method PROTO((tree, tree, tree));
extern tree finish_method PROTO((tree));
extern void hack_incomplete_structures PROTO((tree));
extern tree maybe_build_cleanup_and_delete PROTO((tree));
@@ -2587,6 +2887,11 @@ extern void print_other_binding_stack PROTO((struct binding_level *));
extern void revert_static_member_fn PROTO((tree*, tree*, tree*));
extern void cat_namespace_levels PROTO((void));
extern void fixup_anonymous_union PROTO((tree));
+extern int check_static_variable_definition PROTO((tree, tree));
+extern void push_local_binding PROTO((tree, tree, int));
+extern void push_class_binding PROTO((tree, tree));
+extern tree check_default_argument PROTO((tree, tree));
+extern tree push_overloaded_decl PROTO((tree, int));
/* in decl2.c */
extern void init_decl2 PROTO((void));
@@ -2618,13 +2923,13 @@ extern tree get_temp_name PROTO((tree, int));
extern tree get_temp_regvar PROTO((tree, tree));
extern void finish_anon_union PROTO((tree));
extern tree finish_table PROTO((tree, tree, tree, int));
-extern void finish_builtin_type PROTO((tree, char *, tree *, int, tree));
+extern void finish_builtin_type PROTO((tree, const char *,
+ tree *, int, tree));
extern tree coerce_new_type PROTO((tree));
extern tree coerce_delete_type PROTO((tree));
extern void comdat_linkage PROTO((tree));
extern void import_export_class PROTO((tree));
extern void import_export_vtable PROTO((tree, tree, int));
-extern int finish_prevtable_vardecl PROTO((tree, tree));
extern int walk_vtables PROTO((void (*)(tree, tree),
int (*)(tree, tree)));
extern void walk_sigtables PROTO((void (*)(tree, tree),
@@ -2638,10 +2943,12 @@ extern tree build_expr_from_tree PROTO((tree));
extern tree reparse_decl_as_expr PROTO((tree, tree));
extern tree finish_decl_parsing PROTO((tree));
extern tree check_cp_case_value PROTO((tree));
-extern void set_decl_namespace PROTO((tree, tree));
+extern void set_decl_namespace PROTO((tree, tree, int));
extern tree current_decl_namespace PROTO((void));
extern void push_decl_namespace PROTO((tree));
extern void pop_decl_namespace PROTO((void));
+extern void push_scope PROTO((tree));
+extern void pop_scope PROTO((tree));
extern void do_namespace_alias PROTO((tree, tree));
extern void do_toplevel_using_decl PROTO((tree));
extern void do_local_using_decl PROTO((tree));
@@ -2656,14 +2963,15 @@ extern tree lookup_arg_dependent PROTO((tree, tree, tree));
extern void cp_parse_init PROTO((void));
/* in errfn.c */
-extern void cp_error ();
-extern void cp_error_at ();
-extern void cp_warning ();
-extern void cp_warning_at ();
-extern void cp_pedwarn ();
-extern void cp_pedwarn_at ();
-extern void cp_compiler_error ();
-extern void cp_sprintf ();
+/* The cp_* functions aren't suitable for ATTRIBUTE_PRINTF. */
+extern void cp_error PVPROTO((const char *, ...));
+extern void cp_error_at PVPROTO((const char *, ...));
+extern void cp_warning PVPROTO((const char *, ...));
+extern void cp_warning_at PVPROTO((const char *, ...));
+extern void cp_pedwarn PVPROTO((const char *, ...));
+extern void cp_pedwarn_at PVPROTO((const char *, ...));
+extern void cp_compiler_error PVPROTO((const char *, ...));
+extern void cp_sprintf PVPROTO((const char *, ...));
/* in error.c */
extern void init_error PROTO((void));
@@ -2733,7 +3041,7 @@ extern tree build_vec_delete PROTO((tree, tree, tree, tree, int));
/* in input.c */
/* in lex.c */
-extern char *file_name_nondirectory PROTO((char *));
+extern char *file_name_nondirectory PROTO((const char *));
extern tree make_pointer_declarator PROTO((tree, tree));
extern tree make_reference_declarator PROTO((tree, tree));
extern tree make_call_declarator PROTO((tree, tree, tree, tree));
@@ -2741,7 +3049,6 @@ extern void set_quals_and_spec PROTO((tree, tree, tree));
extern char *operator_name_string PROTO((tree));
extern void lang_init PROTO((void));
extern void lang_finish PROTO((void));
-extern void init_filename_times PROTO((void));
#if 0
extern void reinit_lang_specific PROTO((void));
#endif
@@ -2768,12 +3075,14 @@ extern tree identifier_typedecl_value PROTO((tree));
extern int real_yylex PROTO((void));
extern int is_rid PROTO((tree));
extern tree build_lang_decl PROTO((enum tree_code, tree, tree));
+extern void retrofit_lang_decl PROTO((tree));
extern tree build_lang_field_decl PROTO((enum tree_code, tree, tree));
extern void copy_lang_decl PROTO((tree));
extern tree make_lang_type PROTO((enum tree_code));
extern void dump_time_statistics PROTO((void));
-/* extern void compiler_error PROTO((char *, HOST_WIDE_INT, HOST_WIDE_INT)); */
-extern void yyerror PROTO((char *));
+extern void compiler_error PVPROTO((const char *, ...))
+ ATTRIBUTE_PRINTF_1;
+extern void yyerror PROTO((const char *));
extern void clear_inline_text_obstack PROTO((void));
extern void maybe_snarf_defarg PROTO((void));
extern tree snarf_defarg PROTO((void));
@@ -2781,6 +3090,7 @@ extern void add_defarg_fn PROTO((tree));
extern void do_pending_defargs PROTO((void));
extern int identifier_type PROTO((tree));
extern void yyhook PROTO((int));
+extern int cp_type_qual_from_rid PROTO((tree));
/* in method.c */
extern void init_method PROTO((void));
@@ -2802,10 +3112,11 @@ extern void synthesize_method PROTO((tree));
extern tree get_id_2 PROTO((char *, tree));
/* in pt.c */
+extern void check_template_shadow PROTO ((tree));
extern tree innermost_args PROTO ((tree));
-extern tree tsubst PROTO ((tree, tree, tree));
-extern tree tsubst_expr PROTO ((tree, tree, tree));
-extern tree tsubst_copy PROTO ((tree, tree, tree));
+extern tree tsubst PROTO ((tree, tree, int, tree));
+extern tree tsubst_expr PROTO ((tree, tree, int, tree));
+extern tree tsubst_copy PROTO ((tree, tree, int, tree));
extern void maybe_begin_member_template_processing PROTO((tree));
extern void maybe_end_member_template_processing PROTO((void));
extern tree finish_member_template_decl PROTO((tree));
@@ -2815,7 +3126,6 @@ extern void reset_specialization PROTO((void));
extern void end_specialization PROTO((void));
extern void begin_explicit_instantiation PROTO((void));
extern void end_explicit_instantiation PROTO((void));
-extern tree determine_specialization PROTO((tree, tree, tree *, int, int));
extern tree check_explicit_specialization PROTO((tree, tree, int, int));
extern tree process_template_parm PROTO((tree, tree));
extern tree end_template_parm_list PROTO((tree));
@@ -2830,8 +3140,7 @@ extern int uses_template_parms PROTO((tree));
extern tree instantiate_class_template PROTO((tree));
extern tree instantiate_template PROTO((tree, tree));
extern void overload_template_name PROTO((tree));
-extern int fn_type_unification PROTO((tree, tree, tree, tree, tree, unification_kind_t, tree));
-extern int type_unification PROTO((tree, tree, tree, tree, tree, unification_kind_t, int));
+extern int fn_type_unification PROTO((tree, tree, tree, tree, tree, unification_kind_t));
struct tinst_level *tinst_for_decl PROTO((void));
extern void mark_decl_instantiated PROTO((tree, int));
extern int more_specialized PROTO((tree, tree, tree));
@@ -2850,13 +3159,15 @@ extern void pop_tinst_level PROTO((void));
extern int more_specialized_class PROTO((tree, tree));
extern void do_pushlevel PROTO((void));
extern int is_member_template PROTO((tree));
+extern int template_parms_equal PROTO((tree, tree));
extern int comp_template_parms PROTO((tree, tree));
-extern int decl_template_parm_p PROTO((tree));
extern int template_class_depth PROTO((tree));
extern int is_specialization_of PROTO((tree, tree));
extern int comp_template_args PROTO((tree, tree));
extern void maybe_process_partial_specialization PROTO((tree));
extern void maybe_check_template_type PROTO((tree));
+extern tree most_specialized_instantiation PROTO((tree, tree));
+extern void print_candidates PROTO((tree));
extern int processing_specialization;
extern int processing_explicit_instantiation;
@@ -2865,7 +3176,7 @@ extern int processing_template_parmlist;
/* in repo.c */
extern void repo_template_used PROTO((tree));
extern void repo_template_instantiated PROTO((tree, int));
-extern void init_repo PROTO((char*));
+extern void init_repo PROTO((const char *));
extern void finish_repo PROTO((void));
/* in rtti.c */
@@ -2875,6 +3186,7 @@ extern tree build_typeid PROTO((tree));
extern tree build_x_typeid PROTO((tree));
extern tree get_tinfo_fn PROTO((tree));
extern tree get_typeid PROTO((tree));
+extern tree get_typeid_1 PROTO((tree));
extern tree build_dynamic_cast PROTO((tree, tree));
extern void synthesize_tinfo_fn PROTO((tree));
@@ -2883,9 +3195,10 @@ extern int types_overlap_p PROTO((tree, tree));
extern tree get_vbase PROTO((tree, tree));
extern tree get_binfo PROTO((tree, tree, int));
extern int get_base_distance PROTO((tree, tree, int, tree *));
-extern tree compute_access PROTO((tree, tree));
+extern int accessible_p PROTO((tree, tree));
extern tree lookup_field PROTO((tree, tree, int, int));
extern tree lookup_nested_field PROTO((tree, int));
+extern int lookup_fnfields_1 PROTO((tree, tree));
extern tree lookup_fnfields PROTO((tree, tree, int));
extern tree lookup_member PROTO((tree, tree, int, int));
extern tree lookup_nested_tag PROTO((tree, tree));
@@ -2906,8 +3219,13 @@ extern void init_search_processing PROTO((void));
extern void reinit_search_statistics PROTO((void));
extern tree current_scope PROTO((void));
extern tree lookup_conversions PROTO((tree));
-extern tree get_template_base PROTO((tree, tree));
extern tree binfo_for_vtable PROTO((tree));
+extern tree dfs_walk PROTO((tree,
+ tree (*)(tree, void *),
+ tree (*) (tree, void *),
+ void *));
+extern tree dfs_unmark PROTO((tree, void *));
+extern tree markedp PROTO((tree, void *));
/* in semantics.c */
extern void finish_expr_stmt PROTO((tree));
@@ -2978,6 +3296,7 @@ extern void enter_scope_of PROTO((tree));
extern tree finish_base_specifier PROTO((tree, tree, int));
extern void finish_member_declaration PROTO((tree));
extern void check_multiple_declarators PROTO((void));
+extern tree finish_typeof PROTO((tree));
/* in sig.c */
extern tree build_signature_pointer_type PROTO((tree));
@@ -2994,6 +3313,7 @@ extern int yylex PROTO((void));
extern tree arbitrate_lookup PROTO((tree, tree, tree));
/* in tree.c */
+extern int pod_type_p PROTO((tree));
extern void unshare_base_binfos PROTO((tree));
extern int member_p PROTO((tree));
extern int real_lvalue_p PROTO((tree));
@@ -3001,7 +3321,7 @@ extern tree build_min PVPROTO((enum tree_code, tree, ...));
extern tree build_min_nt PVPROTO((enum tree_code, ...));
extern tree min_tree_cons PROTO((tree, tree, tree));
extern int lvalue_p PROTO((tree));
-extern int lvalue_or_else PROTO((tree, char *));
+extern int lvalue_or_else PROTO((tree, const char *));
extern tree build_cplus_new PROTO((tree, tree));
extern tree get_target_expr PROTO((tree));
extern tree break_out_cleanups PROTO((tree));
@@ -3023,6 +3343,7 @@ extern int count_functions PROTO((tree));
extern int is_overloaded_fn PROTO((tree));
extern tree get_first_fn PROTO((tree));
extern tree binding_init PROTO((struct tree_binding*));
+extern int bound_pmf_p PROTO((tree));
extern tree ovl_cons PROTO((tree, tree));
extern tree scratch_ovl_cons PROTO((tree, tree));
extern int ovl_member PROTO((tree, tree));
@@ -3044,13 +3365,13 @@ extern tree break_out_target_exprs PROTO((tree));
extern tree get_type_decl PROTO((tree));
extern tree vec_binfo_member PROTO((tree, tree));
extern tree hack_decl_function_context PROTO((tree));
+extern tree decl_namespace_context PROTO((tree));
extern tree lvalue_type PROTO((tree));
extern tree error_type PROTO((tree));
extern tree make_temp_vec PROTO((int));
extern tree build_ptr_wrapper PROTO((void *));
extern tree build_expr_ptr_wrapper PROTO((void *));
extern tree build_int_wrapper PROTO((int));
-extern tree build_srcloc PROTO((char *, int));
extern tree build_srcloc_here PROTO((void));
extern int varargs_function_p PROTO((tree));
extern int really_overloaded_fn PROTO((tree));
@@ -3060,6 +3381,10 @@ extern tree mapcar PROTO((tree, tree (*) (tree)));
extern tree no_linkage_check PROTO((tree));
extern void debug_binfo PROTO((tree));
extern void push_expression_obstack PROTO((void));
+extern tree build_dummy_object PROTO((tree));
+extern tree maybe_dummy_object PROTO((tree, tree *));
+extern int is_dummy_object PROTO((tree));
+extern tree search_tree PROTO((tree, tree (*)(tree)));
#define scratchalloc expralloc
#define scratch_tree_cons expr_tree_cons
#define build_scratch_list build_expr_list
@@ -3073,18 +3398,18 @@ extern int string_conv_p PROTO((tree, tree, int));
extern tree condition_conversion PROTO((tree));
extern tree target_type PROTO((tree));
extern tree require_complete_type PROTO((tree));
+extern tree require_complete_type_in_void PROTO((tree));
extern tree complete_type PROTO((tree));
-extern tree complete_type_or_else PROTO((tree));
+extern tree complete_type_or_else PROTO((tree, tree));
extern int type_unknown_p PROTO((tree));
extern int fntype_p PROTO((tree));
-extern tree require_instantiated_type PROTO((tree, tree, tree));
extern tree commonparms PROTO((tree, tree));
extern tree original_type PROTO((tree));
extern tree common_type PROTO((tree, tree));
extern int compexcepttypes PROTO((tree, tree));
extern int comptypes PROTO((tree, tree, int));
extern int comp_target_types PROTO((tree, tree, int));
-extern int compparms PROTO((tree, tree, int));
+extern int compparms PROTO((tree, tree));
extern int comp_target_types PROTO((tree, tree, int));
extern int comp_cv_qualification PROTO((tree, tree));
extern int comp_cv_qual_signature PROTO((tree, tree));
@@ -3103,8 +3428,8 @@ extern tree build_object_ref PROTO((tree, tree, tree));
extern tree build_component_ref_1 PROTO((tree, tree, int));
extern tree build_component_ref PROTO((tree, tree, tree, int));
extern tree build_x_component_ref PROTO((tree, tree, tree, int));
-extern tree build_x_indirect_ref PROTO((tree, char *));
-extern tree build_indirect_ref PROTO((tree, char *));
+extern tree build_x_indirect_ref PROTO((tree, const char *));
+extern tree build_indirect_ref PROTO((tree, const char *));
extern tree build_array_ref PROTO((tree, tree));
extern tree build_x_function_call PROTO((tree, tree, tree));
extern tree get_member_function_from_ptrfunc PROTO((tree *, tree));
@@ -3115,7 +3440,7 @@ extern tree convert_arguments PROTO((tree, tree, tree, int));
extern tree build_x_binary_op PROTO((enum tree_code, tree, tree));
extern tree build_binary_op PROTO((enum tree_code, tree, tree, int));
extern tree build_binary_op_nodefault PROTO((enum tree_code, tree, tree, enum tree_code));
-extern tree build_component_addr PROTO((tree, tree, char *));
+extern tree build_component_addr PROTO((tree, tree, const char *));
extern tree build_x_unary_op PROTO((enum tree_code, tree));
extern tree build_unary_op PROTO((enum tree_code, tree, int));
extern tree unary_complex_lvalue PROTO((enum tree_code, tree));
@@ -3130,19 +3455,26 @@ extern tree build_const_cast PROTO((tree, tree));
extern tree build_c_cast PROTO((tree, tree));
extern tree build_x_modify_expr PROTO((tree, enum tree_code, tree));
extern tree build_modify_expr PROTO((tree, enum tree_code, tree));
-extern void warn_for_assignment PROTO((char *, char *, char *, tree, int, int));
-extern tree convert_for_initialization PROTO((tree, tree, tree, int, char *, tree, int));
+extern tree convert_for_initialization PROTO((tree, tree, tree, int, const char *, tree, int));
extern void c_expand_asm_operands PROTO((tree, tree, tree, tree, int, char *, int));
extern void c_expand_return PROTO((tree));
extern tree c_expand_start_case PROTO((tree));
extern int comp_ptr_ttypes PROTO((tree, tree));
extern int ptr_reasonably_similar PROTO((tree, tree));
extern tree build_ptrmemfunc PROTO((tree, tree, int));
+extern int cp_type_quals PROTO((tree));
+extern int cp_has_mutable_p PROTO((tree));
+extern int at_least_as_qualified_p PROTO((tree, tree));
+extern int more_qualified_p PROTO((tree, tree));
+extern tree build_ptrmemfunc1 PROTO((tree, tree, tree, tree, tree));
+extern void expand_ptrmemfunc_cst PROTO((tree, tree *, tree *, tree *, tree *));
+extern tree delta2_from_ptrmemfunc PROTO((tree));
+extern tree pfn_from_ptrmemfunc PROTO((tree));
/* in typeck2.c */
extern tree error_not_base_type PROTO((tree, tree));
extern tree binfo_or_else PROTO((tree, tree));
-extern void readonly_error PROTO((tree, char *, int));
+extern void readonly_error PROTO((tree, const char *, int));
extern void abstract_virtuals_error PROTO((tree, tree));
extern void signature_error PROTO((tree, tree));
extern void incomplete_type_error PROTO((tree, tree));
@@ -3157,18 +3489,18 @@ extern tree build_m_component_ref PROTO((tree, tree));
extern tree build_functional_cast PROTO((tree, tree));
extern char *enum_name_string PROTO((tree, tree));
extern void report_case_error PROTO((int, tree, tree, tree));
-extern void check_for_new_type PROTO((char *,flagged_type_tree));
+extern void check_for_new_type PROTO((const char *, flagged_type_tree));
extern tree initializer_constant_valid_p PROTO((tree, tree));
/* in xref.c */
-extern void GNU_xref_begin PROTO((char *));
+extern void GNU_xref_begin PROTO((const char *));
extern void GNU_xref_end PROTO((int));
-extern void GNU_xref_file PROTO((char *));
+extern void GNU_xref_file PROTO((const char *));
extern void GNU_xref_start_scope PROTO((HOST_WIDE_INT));
extern void GNU_xref_end_scope PROTO((HOST_WIDE_INT, HOST_WIDE_INT, int, int));
-extern void GNU_xref_ref PROTO((tree, char *));
+extern void GNU_xref_ref PROTO((tree, const char *));
extern void GNU_xref_decl PROTO((tree, tree));
-extern void GNU_xref_call PROTO((tree, char *));
+extern void GNU_xref_call PROTO((tree, const char *));
extern void GNU_xref_function PROTO((tree, tree));
extern void GNU_xref_assign PROTO((tree));
extern void GNU_xref_hier PROTO((tree, tree, int, int, int));
diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c
index f2b41d80b14..d03cff5df65 100644
--- a/gcc/cp/cvt.c
+++ b/gcc/cp/cvt.c
@@ -1,5 +1,5 @@
/* Language-level data type conversion for GNU C++.
- Copyright (C) 1987, 88, 92-96, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1987, 88, 92-97, 1998 Free Software Foundation, Inc.
Hacked by Michael Tiemann (tiemann@cygnus.com)
This file is part of GNU CC.
@@ -31,8 +31,8 @@ Boston, MA 02111-1307, USA. */
#include "flags.h"
#include "cp-tree.h"
#include "convert.h"
-
-extern tree static_aggregates;
+#include "toplev.h"
+#include "decl.h"
static tree cp_convert_to_pointer PROTO((tree, tree));
static tree convert_to_pointer_force PROTO((tree, tree));
@@ -85,7 +85,7 @@ cp_convert_to_pointer (type, expr)
return error_mark_node;
}
- rval = build_type_conversion (CONVERT_EXPR, type, expr, 1);
+ rval = build_type_conversion (type, expr, 1);
if (rval)
{
if (rval == error_mark_node)
@@ -95,9 +95,6 @@ cp_convert_to_pointer (type, expr)
}
}
- if (TYPE_PTRMEMFUNC_P (type))
- type = TYPE_PTRMEMFUNC_FN_TYPE (type);
-
/* Handle anachronistic conversions from (::*)() to cv void* or (*)(). */
if (TREE_CODE (type) == POINTER_TYPE
&& (TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE
@@ -107,21 +104,8 @@ cp_convert_to_pointer (type, expr)
functions. */
if (TYPE_PTRMEMFUNC_P (intype))
{
- tree decl, basebinfo;
tree fntype = TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (intype));
- tree t = TYPE_METHOD_BASETYPE (fntype);
-
- if (current_class_type == 0
- || get_base_distance (t, current_class_type, 0, &basebinfo)
- == -1)
- {
- decl = build1 (NOP_EXPR, t, error_mark_node);
- }
- else if (current_class_ptr == 0)
- decl = build1 (NOP_EXPR, t, error_mark_node);
- else
- decl = current_class_ref;
-
+ tree decl = maybe_dummy_object (TYPE_METHOD_BASETYPE (fntype), 0);
expr = build (OFFSET_REF, fntype, decl, expr);
}
@@ -141,16 +125,14 @@ cp_convert_to_pointer (type, expr)
intype = TREE_TYPE (expr);
}
- if (TYPE_PTRMEMFUNC_P (intype))
- intype = TYPE_PTRMEMFUNC_FN_TYPE (intype);
-
form = TREE_CODE (intype);
- if (form == POINTER_TYPE || form == REFERENCE_TYPE)
+ if (POINTER_TYPE_P (intype))
{
intype = TYPE_MAIN_VARIANT (intype);
if (TYPE_MAIN_VARIANT (type) != intype
+ && TREE_CODE (type) == POINTER_TYPE
&& TREE_CODE (TREE_TYPE (type)) == RECORD_TYPE
&& IS_AGGR_TYPE (TREE_TYPE (type))
&& IS_AGGR_TYPE (TREE_TYPE (intype))
@@ -194,13 +176,8 @@ cp_convert_to_pointer (type, expr)
}
}
}
- if (TREE_CODE (TREE_TYPE (intype)) == METHOD_TYPE
- && TREE_CODE (type) == POINTER_TYPE
- && TREE_CODE (TREE_TYPE (type)) == METHOD_TYPE)
- return build_ptrmemfunc (type, expr, 1);
- if (TREE_CODE (TREE_TYPE (type)) == OFFSET_TYPE
- && TREE_CODE (TREE_TYPE (intype)) == OFFSET_TYPE)
+ if (TYPE_PTRMEM_P (type) && TYPE_PTRMEM_P (intype))
{
tree b1 = TYPE_OFFSET_BASETYPE (TREE_TYPE (type));
tree b2 = TYPE_OFFSET_BASETYPE (TREE_TYPE (intype));
@@ -218,10 +195,7 @@ cp_convert_to_pointer (type, expr)
if (binfo && ! TREE_VIA_VIRTUAL (binfo))
expr = size_binop (code, expr, BINFO_OFFSET (binfo));
}
-
- if (TREE_CODE (TREE_TYPE (intype)) == METHOD_TYPE
- || (TREE_CODE (type) == POINTER_TYPE
- && TREE_CODE (TREE_TYPE (type)) == METHOD_TYPE))
+ else if (TYPE_PTRMEMFUNC_P (type))
{
cp_error ("cannot convert `%E' from type `%T' to type `%T'",
expr, intype, type);
@@ -232,6 +206,14 @@ cp_convert_to_pointer (type, expr)
TREE_CONSTANT (rval) = TREE_CONSTANT (expr);
return rval;
}
+ else if (TYPE_PTRMEMFUNC_P (type) && TYPE_PTRMEMFUNC_P (intype))
+ return build_ptrmemfunc (TYPE_PTRMEMFUNC_FN_TYPE (type), expr, 1);
+ else if (TYPE_PTRMEMFUNC_P (intype))
+ {
+ cp_error ("cannot convert `%E' from type `%T' to type `%T'",
+ expr, intype, type);
+ return error_mark_node;
+ }
my_friendly_assert (form != OFFSET_TYPE, 186);
@@ -241,8 +223,8 @@ cp_convert_to_pointer (type, expr)
if (integer_zerop (expr))
{
- if (TREE_CODE (TREE_TYPE (type)) == METHOD_TYPE)
- return build_ptrmemfunc (type, expr, 0);
+ if (TYPE_PTRMEMFUNC_P (type))
+ return build_ptrmemfunc (TYPE_PTRMEMFUNC_FN_TYPE (type), expr, 0);
expr = build_int_2 (0, 0);
TREE_TYPE (expr) = type;
return expr;
@@ -262,6 +244,9 @@ cp_convert_to_pointer (type, expr)
return convert_to_pointer (type, expr);
}
+ if (type_unknown_p (expr))
+ return instantiate_type (type, expr, 1);
+
cp_error ("cannot convert `%E' from type `%T' to type `%T'",
expr, intype, type);
return error_mark_node;
@@ -364,11 +349,13 @@ build_up_reference (type, arg, flags)
DECL_ARTIFICIAL (arg) = 1;
}
DECL_INITIAL (arg) = targ;
- cp_finish_decl (arg, targ, NULL_TREE, 0, LOOKUP_ONLYCONVERTING);
+ cp_finish_decl (arg, targ, NULL_TREE, 0,
+ LOOKUP_ONLYCONVERTING|DIRECT_BIND);
}
else if (!(flags & DIRECT_BIND) && ! lvalue_p (arg))
{
tree slot = build_decl (VAR_DECL, NULL_TREE, argtype);
+ DECL_ARTIFICIAL (slot) = 1;
arg = build (TARGET_EXPR, argtype, slot, arg, NULL_TREE, NULL_TREE);
TREE_SIDE_EFFECTS (arg) = 1;
}
@@ -377,6 +364,9 @@ build_up_reference (type, arg, flags)
address, transform all occurrences of the register, into a memory
reference we could win better. */
rval = build_unary_op (ADDR_EXPR, arg, 1);
+ if (rval == error_mark_node)
+ return error_mark_node;
+
if ((flags & LOOKUP_PROTECT)
&& TYPE_MAIN_VARIANT (argtype) != TYPE_MAIN_VARIANT (target_type)
&& IS_AGGR_TYPE (argtype)
@@ -417,6 +407,16 @@ convert_to_reference (reftype, expr, convtype, flags, decl)
tree rval_as_conversion = NULL_TREE;
int i;
+ if (TREE_CODE (type) == FUNCTION_TYPE && intype == unknown_type_node)
+ {
+ expr = instantiate_type (type, expr,
+ (flags & LOOKUP_COMPLAIN) != 0);
+ if (expr == error_mark_node)
+ return error_mark_node;
+
+ intype = TREE_TYPE (expr);
+ }
+
if (TREE_CODE (intype) == REFERENCE_TYPE)
my_friendly_abort (364);
@@ -430,7 +430,7 @@ convert_to_reference (reftype, expr, convtype, flags, decl)
/* Look for a user-defined conversion to lvalue that we can use. */
rval_as_conversion
- = build_type_conversion (CONVERT_EXPR, reftype, expr, 1);
+ = build_type_conversion (reftype, expr, 1);
if (rval_as_conversion && rval_as_conversion != error_mark_node
&& real_lvalue_p (rval_as_conversion))
@@ -454,31 +454,26 @@ convert_to_reference (reftype, expr, convtype, flags, decl)
initialize a reference, then the reference must be to a
non-volatile const type. */
if (! real_lvalue_p (expr)
- && (!TYPE_READONLY (ttl) || TYPE_VOLATILE (ttl)))
+ && !CP_TYPE_CONST_NON_VOLATILE_P (ttl))
{
- char* msg;
+ const char *msg;
- if (TYPE_VOLATILE (ttl) && decl)
+ if (CP_TYPE_VOLATILE_P (ttl) && decl)
msg = "initialization of volatile reference type `%#T'";
- else if (TYPE_VOLATILE (ttl))
+ else if (CP_TYPE_VOLATILE_P (ttl))
msg = "conversion to volatile reference type `%#T'";
else if (decl)
msg = "initialization of non-const reference type `%#T'";
else
msg = "conversion to non-const reference type `%#T'";
- cp_error (msg, reftype);
- cp_error ("from rvalue of type `%T'", intype);
- }
- else if (! (convtype & CONV_CONST))
- {
- if (! TYPE_READONLY (ttl) && TYPE_READONLY (ttr))
- cp_error ("conversion from `%T' to `%T' discards const",
- ttr, reftype);
- else if (! TYPE_VOLATILE (ttl) && TYPE_VOLATILE (ttr))
- cp_error ("conversion from `%T' to `%T' discards volatile",
- ttr, reftype);
+ cp_pedwarn (msg, reftype);
+ cp_pedwarn ("from rvalue of type `%T'", intype);
}
+ else if (! (convtype & CONV_CONST)
+ && !at_least_as_qualified_p (ttl, ttr))
+ cp_pedwarn ("conversion from `%T' to `%T' discards qualifiers",
+ ttr, reftype);
}
return build_up_reference (reftype, expr, flags);
@@ -493,7 +488,8 @@ convert_to_reference (reftype, expr, convtype, flags, decl)
/* B* bp; A& ar = (A&)bp; is valid, but it's probably not what they
meant. */
if (TREE_CODE (intype) == POINTER_TYPE
- && (comptypes (TREE_TYPE (intype), type, -1)))
+ && (comptypes (TREE_TYPE (intype), type,
+ COMPARE_BASE | COMPARE_RELAXED )))
cp_warning ("casting `%T' to `%T' does not dereference pointer",
intype, reftype);
@@ -508,11 +504,11 @@ convert_to_reference (reftype, expr, convtype, flags, decl)
{
rval = convert_for_initialization (NULL_TREE, type, expr, flags,
"converting", 0, 0);
- if (rval == error_mark_node)
- return error_mark_node;
+ if (rval == NULL_TREE || rval == error_mark_node)
+ return rval;
rval = build_up_reference (reftype, rval, flags);
- if (rval && ! TYPE_READONLY (TREE_TYPE (reftype)))
+ if (rval && ! CP_TYPE_CONST_P (TREE_TYPE (reftype)))
cp_pedwarn ("initializing non-const `%T' with `%T' will use a temporary",
reftype, intype);
}
@@ -580,8 +576,8 @@ convert_pointer_to_real (binfo, expr)
binfo = NULL_TREE;
}
- ptr_type = cp_build_type_variant (type, TYPE_READONLY (TREE_TYPE (intype)),
- TYPE_VOLATILE (TREE_TYPE (intype)));
+ ptr_type = cp_build_qualified_type (type,
+ CP_TYPE_QUALS (TREE_TYPE (intype)));
ptr_type = build_pointer_type (ptr_type);
if (ptr_type == TYPE_MAIN_VARIANT (intype))
return expr;
@@ -675,20 +671,26 @@ ocp_convert (type, expr, convtype, flags)
/* We need a new temporary; don't take this shortcut. */;
else if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (e)))
{
- if (comptypes (type, TREE_TYPE (e), 1))
+ if (same_type_p (type, TREE_TYPE (e)))
/* The call to fold will not always remove the NOP_EXPR as
might be expected, since if one of the types is a typedef;
the comparsion in fold is just equality of pointers, not a
- call to comptypes. */
- ;
+ call to comptypes. We don't call fold in this case because
+ that can result in infinite recursion; fold will call
+ convert, which will call ocp_convert, etc. */
+ return e;
else
- e = build1 (NOP_EXPR, type, e);
-
- return fold (e);
+ return fold (build1 (NOP_EXPR, type, e));
}
if (code == VOID_TYPE && (convtype & CONV_STATIC))
- return build1 (CONVERT_EXPR, type, e);
+ {
+ e = require_complete_type_in_void (e);
+ if (e != error_mark_node)
+ e = build1 (CONVERT_EXPR, void_type_node, e);
+
+ return e;
+ }
#if 0
/* This is incorrect. A truncation can't be stripped this way.
@@ -731,7 +733,7 @@ ocp_convert (type, expr, convtype, flags)
if (IS_AGGR_TYPE (intype))
{
tree rval;
- rval = build_type_conversion (CONVERT_EXPR, type, e, 1);
+ rval = build_type_conversion (type, e, 1);
if (rval)
return rval;
if (flags & LOOKUP_COMPLAIN)
@@ -758,7 +760,7 @@ ocp_convert (type, expr, convtype, flags)
if (IS_AGGR_TYPE (TREE_TYPE (e)))
{
tree rval;
- rval = build_type_conversion (CONVERT_EXPR, type, e, 1);
+ rval = build_type_conversion (type, e, 1);
if (rval)
return rval;
else
@@ -814,6 +816,12 @@ ocp_convert (type, expr, convtype, flags)
ctor = e;
+ if (IS_AGGR_TYPE (type) && CLASSTYPE_ABSTRACT_VIRTUALS (type))
+ {
+ abstract_virtuals_error (NULL_TREE, type);
+ return error_mark_node;
+ }
+
if ((flags & LOOKUP_ONLYCONVERTING)
&& ! (IS_AGGR_TYPE (dtype) && DERIVED_FROM_P (type, dtype)))
/* For copy-initialization, first we create a temp of the proper type
@@ -938,8 +946,7 @@ convert_force (type, expr, convtype)
(jason 8/9/95) */
tree
-build_type_conversion (code, xtype, expr, for_sure)
- enum tree_code code ATTRIBUTE_UNUSED;
+build_type_conversion (xtype, expr, for_sure)
tree xtype, expr;
int for_sure;
{
@@ -1069,13 +1076,12 @@ tree
type_promotes_to (type)
tree type;
{
- int constp, volatilep;
+ int type_quals;
if (type == error_mark_node)
return error_mark_node;
- constp = TYPE_READONLY (type);
- volatilep = TYPE_VOLATILE (type);
+ type_quals = CP_TYPE_QUALS (type);
type = TYPE_MAIN_VARIANT (type);
/* bool always promotes to int (not unsigned), even if it's the same
@@ -1109,7 +1115,7 @@ type_promotes_to (type)
else if (type == float_type_node)
type = double_type_node;
- return cp_build_type_variant (type, constp, volatilep);
+ return cp_build_qualified_type (type, type_quals);
}
/* The routines below this point are carefully written to conform to
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 9ecb9846cf8..d8fdfe3b537 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -1,5 +1,5 @@
/* Process declarations and variables for C compiler.
- Copyright (C) 1988, 92-97, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1988, 92-98, 1999 Free Software Foundation, Inc.
Contributed by Michael Tiemann (tiemann@cygnus.com)
This file is part of GNU CC.
@@ -42,6 +42,7 @@ Boston, MA 02111-1307, USA. */
#include "output.h"
#include "except.h"
#include "toplev.h"
+#include "../hash.h"
#include "ggc.h"
#define obstack_chunk_alloc xmalloc
@@ -135,8 +136,7 @@ static struct stack_level *decl_stack;
static tree grokparms PROTO((tree, int));
static tree lookup_nested_type PROTO((tree, tree));
-static char *redeclaration_error_message PROTO((tree, tree));
-static tree push_overloaded_decl PROTO((tree, int));
+static const char *redeclaration_error_message PROTO((tree, tree));
static struct stack_level *push_decl_level PROTO((struct stack_level *,
struct obstack *));
@@ -146,10 +146,8 @@ static void pop_binding_level PROTO((void));
static void suspend_binding_level PROTO((void));
static void resume_binding_level PROTO((struct binding_level *));
static struct binding_level *make_binding_level PROTO((void));
-static int namespace_bindings_p PROTO((void));
-static void mark_binding_level PROTO((void *));
static void declare_namespace_level PROTO((void));
-static void signal_catch PROTO((int));
+static void signal_catch PROTO((int)) ATTRIBUTE_NORETURN;
static void storedecls PROTO((tree));
static void storetags PROTO((tree));
static void require_complete_types_for_parms PROTO((tree));
@@ -171,15 +169,27 @@ static tree lookup_tag PROTO((enum tree_code, tree,
struct binding_level *, int));
static void set_identifier_type_value_with_scope
PROTO((tree, tree, struct binding_level *));
-static void set_identifier_local_value_with_scope
- PROTO((tree, tree, struct binding_level *));
-static void record_builtin_type PROTO((enum rid, char *, tree));
-static void record_unknown_type PROTO((tree, char *));
-static int member_function_or_else PROTO((tree, tree, char *));
-static void bad_specifiers PROTO((tree, char *, int, int, int, int,
+static void record_builtin_type PROTO((enum rid, const char *, tree));
+static void record_unknown_type PROTO((tree, const char *));
+static int member_function_or_else PROTO((tree, tree, const char *));
+static void bad_specifiers PROTO((tree, const char *, int, int, int, int,
int));
static void lang_print_error_function PROTO((char *));
static tree maybe_process_template_type_declaration PROTO((tree, int, struct binding_level*));
+static void check_for_uninitialized_const_var PROTO((tree));
+static unsigned long typename_hash PROTO((hash_table_key));
+static boolean typename_compare PROTO((hash_table_key, hash_table_key));
+static void push_binding PROTO((tree, tree, struct binding_level*));
+static void add_binding PROTO((tree, tree));
+static void pop_binding PROTO((tree, tree));
+static tree local_variable_p PROTO((tree));
+static tree find_binding PROTO((tree, tree));
+static tree select_decl PROTO((tree, int));
+static tree unqualified_namespace_lookup PROTO((tree, int));
+static int lookup_flags PROTO((int, int));
+static tree qualify_lookup PROTO((tree, int));
+static tree record_builtin_java_type PROTO((const char *, int));
+static const char *tag_name PROTO((enum tag_types code));
#if defined (DEBUG_CP_BINDING_LEVELS)
static void indent PROTO((void));
@@ -519,11 +529,6 @@ int current_function_returns_null;
tree current_function_return_value;
-/* Set to nonzero by `grokdeclarator' for a function
- whose return type is defaulted, if warnings for this are desired. */
-
-static int warn_about_return_type;
-
/* Nonzero means give `double' the same size as `float'. */
extern int flag_short_double;
@@ -617,7 +622,10 @@ push_decl_level (stack, obstack)
to catch class-local declarations. It is otherwise nonexistent.
Also there may be binding levels that catch cleanups that must be
- run when exceptions occur. */
+ run when exceptions occur. Thus, to see whether a name is bound in
+ the current scope, it is not enough to look in the
+ CURRENT_BINDING_LEVEL. You should use lookup_name_current_level
+ instead. */
/* Note that the information in the `names' component of the global contour
is duplicated in the IDENTIFIER_GLOBAL_VALUEs of all identifiers. */
@@ -626,7 +634,8 @@ struct binding_level
{
/* A chain of _DECL nodes for all variables, constants, functions,
and typedef types. These are in the reverse of the order
- supplied. */
+ supplied. There may be OVERLOADs on this list, too, but they
+ are wrapped in TREE_LISTs; the TREE_VALUE is the OVERLOAD. */
tree names;
/* A list of structure, union and enum definitions, for looking up
@@ -646,16 +655,17 @@ struct binding_level
VALUE the common ancestor with this binding_level's namespace. */
tree using_directives;
- /* For each level, a list of shadowed outer-level local definitions
- to be restored when this level is popped.
- Each link is a TREE_LIST whose TREE_PURPOSE is an identifier and
- whose TREE_VALUE is its old definition (a kind of ..._DECL node). */
- tree shadowed;
-
- /* Same, for IDENTIFIER_CLASS_VALUE. */
+ /* If this binding level is the binding level for a class, then
+ class_shadowed is a TREE_LIST. The TREE_PURPOSE of each node
+ is the name of an entity bound in the class; the TREE_VALUE is
+ the IDENTIFIER_CLASS_VALUE before we entered the class. Thus,
+ when leaving class scope, we can restore the
+ IDENTIFIER_CLASS_VALUE by walking this list. The TREE_TYPE is
+ the DECL bound by this name in the class. */
tree class_shadowed;
- /* Same, for IDENTIFIER_TYPE_VALUE. */
+ /* Similar to class_shadowed, but for IDENTIFIER_TYPE_VALUE, and
+ is used for all binding levels. */
tree type_shadowed;
/* For each level (except not the global one),
@@ -676,7 +686,8 @@ struct binding_level
/* List of VAR_DECLS saved from a previous for statement.
These would be dead in ANSI-conforming code, but might
- be referenced in ARM-era code. */
+ be referenced in ARM-era code. These are stored in a
+ TREE_LIST; the TREE_VALUE is the actual declaration. */
tree dead_vars_from_for;
/* 1 for the level that holds the parameters of a function.
@@ -929,7 +940,7 @@ toplevel_bindings_p ()
/* Nonzero if this is a namespace scope. */
-static int
+int
namespace_bindings_p ()
{
return current_binding_level->namespace_p;
@@ -1045,6 +1056,184 @@ pushlevel_temporary (tag_transparent)
expand_start_bindings (0);
}
+/* For a binding between a name and an entity at a block scope,
+ this is the `struct binding_level' for the block. */
+#define BINDING_LEVEL(NODE) \
+ (((struct tree_binding*)NODE)->scope.level)
+
+/* These are currently unused, but permanent, CPLUS_BINDING nodes.
+ They are kept here because they are allocated from the permanent
+ obstack and cannot be easily freed. */
+static tree free_binding_nodes;
+
+/* Make DECL the innermost binding for ID. The LEVEL is the binding
+ level at which this declaration is being bound. */
+
+static void
+push_binding (id, decl, level)
+ tree id;
+ tree decl;
+ struct binding_level* level;
+{
+ tree binding;
+
+ if (!free_binding_nodes)
+ {
+ /* There are no free nodes, so we must build one here. */
+ push_obstacks_nochange ();
+ end_temporary_allocation ();
+ binding = make_node (CPLUS_BINDING);
+ pop_obstacks ();
+ }
+ else
+ {
+ /* There are nodes on the free list. Grab the first one. */
+ binding = free_binding_nodes;
+
+ /* And update the free list. */
+ free_binding_nodes = TREE_CHAIN (free_binding_nodes);
+ }
+
+ /* Now, fill in the binding information. */
+ BINDING_VALUE (binding) = decl;
+ BINDING_TYPE (binding) = NULL_TREE;
+ BINDING_LEVEL (binding) = level;
+ LOCAL_BINDING_P (binding) = (level != class_binding_level);
+
+ /* And put it on the front of the ilst of bindings for ID. */
+ TREE_CHAIN (binding) = IDENTIFIER_BINDING (id);
+ IDENTIFIER_BINDING (id) = binding;
+}
+
+/* ID is already bound in the current scope. But, DECL is an
+ additional binding for ID in the same scope. This is the `struct
+ stat' hack whereby a non-typedef class-name or enum-name can be
+ bound at the same level as some other kind of entity. It's the
+ responsibility of the caller to check that inserting this name is
+ legal here. */
+static void
+add_binding (id, decl)
+ tree id;
+ tree decl;
+{
+ tree binding = IDENTIFIER_BINDING (id);
+
+ if (TREE_CODE (decl) == TYPE_DECL && DECL_ARTIFICIAL (decl))
+ /* The new name is the type name. */
+ BINDING_TYPE (binding) = decl;
+ else
+ {
+ /* The old name must be the type name. It was placed in
+ IDENTIFIER_VALUE because it was thought, at the point it
+ was declared, to be the only entity with such a name. */
+ my_friendly_assert (TREE_CODE (BINDING_VALUE (binding)) == TYPE_DECL
+ && DECL_ARTIFICIAL (BINDING_VALUE (binding)),
+ 0);
+
+ /* Move the type name into the type slot; it is now hidden by
+ the new binding. */
+ BINDING_TYPE (binding) = BINDING_VALUE (binding);
+ BINDING_VALUE (binding) = decl;
+ }
+}
+
+/* Bind DECL to ID in the current_binding_level.
+ If PUSH_USING is set in FLAGS, we know that DECL doesn't really belong
+ to this binding level, that it got here through a using-declaration. */
+
+void
+push_local_binding (id, decl, flags)
+ tree id;
+ tree decl;
+ int flags;
+{
+ tree d = decl;
+
+ if (lookup_name_current_level (id))
+ /* Supplement the existing binding. */
+ add_binding (id, d);
+ else
+ /* Create a new binding. */
+ push_binding (id, d, current_binding_level);
+
+ if (TREE_CODE (decl) == OVERLOAD || (flags & PUSH_USING))
+ /* We must put the OVERLOAD into a TREE_LIST since the
+ TREE_CHAIN of an OVERLOAD is already used. Similarly for
+ decls that got here through a using-declaration. */
+ decl = build_tree_list (NULL_TREE, decl);
+
+ /* And put DECL on the list of things declared by the current
+ binding level. */
+ TREE_CHAIN (decl) = current_binding_level->names;
+ current_binding_level->names = decl;
+}
+
+/* Bind DECL to ID in the class_binding_level. */
+
+void
+push_class_binding (id, decl)
+ tree id;
+ tree decl;
+{
+ if (IDENTIFIER_BINDING (id)
+ && BINDING_LEVEL (IDENTIFIER_BINDING (id)) == class_binding_level)
+ /* Supplement the existing binding. */
+ add_binding (id, decl);
+ else
+ /* Create a new binding. */
+ push_binding (id, decl, class_binding_level);
+
+ /* Update the IDENTIFIER_CLASS_VALUE for this ID to be the
+ class-level declaration. Note that we do not use DECL here
+ because of the possibility of the `struct stat' hack; if DECL is
+ a class-name or enum-name we might prefer a field-name, or some
+ such. */
+ IDENTIFIER_CLASS_VALUE (id) = BINDING_VALUE (IDENTIFIER_BINDING (id));
+}
+
+/* Remove the binding for DECL which should be the innermost binding
+ for ID. */
+
+static void
+pop_binding (id, decl)
+ tree id;
+ tree decl;
+{
+ tree binding;
+
+ if (id == NULL_TREE)
+ /* It's easiest to write the loops that call this function without
+ checking whether or not the entities involved have names. We
+ get here for such an entity. */
+ return;
+
+ /* Get the innermost binding for ID. */
+ binding = IDENTIFIER_BINDING (id);
+
+ /* The name should be bound. */
+ my_friendly_assert (binding != NULL_TREE, 0);
+
+ /* The DECL will be either the ordinary binding or the type
+ binding for this identifier. Remove that binding. */
+ if (BINDING_VALUE (binding) == decl)
+ BINDING_VALUE (binding) = NULL_TREE;
+ else if (BINDING_TYPE (binding) == decl)
+ BINDING_TYPE (binding) = NULL_TREE;
+ else
+ my_friendly_abort (0);
+
+ if (!BINDING_VALUE (binding) && !BINDING_TYPE (binding))
+ {
+ /* We're completely done with the innermost binding for this
+ identifier. Unhook it from the list of bindings. */
+ IDENTIFIER_BINDING (id) = TREE_CHAIN (binding);
+
+ /* And place it on the free list. */
+ TREE_CHAIN (binding) = free_binding_nodes;
+ free_binding_nodes = binding;
+ }
+}
+
/* 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.
@@ -1053,12 +1242,6 @@ pushlevel_temporary (tag_transparent)
and create a "block" (a BLOCK node) for the level
to record its declarations and subblocks for symbol table output.
- If KEEP == 2, this level's subblocks go to the front,
- not the back of the current binding level. This happens,
- for instance, when code for constructors and destructors
- need to generate code at the end of a function which must
- be moved up to the front of the function.
-
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.
@@ -1084,6 +1267,18 @@ poplevel (keep, reverse, functionbody)
tree block = NULL_TREE;
tree decl;
int block_previously_created;
+ int leaving_for_scope;
+
+ if (current_binding_level->parm_flag == 2
+ || current_binding_level->class_shadowed)
+ /* We should not be using poplevel to pop a class binding level.
+ Use poplevel_class instead. */
+ my_friendly_abort (0);
+
+ /* We used to use KEEP == 2 to indicate that the new block should go
+ at the beginning of the list of blocks at this binding level,
+ rather than the end. This hack is no longer used. */
+ my_friendly_assert (keep == 0 || keep == 1, 0);
GNU_xref_end_scope ((HOST_WIDE_INT) current_binding_level,
(HOST_WIDE_INT) current_binding_level->level_chain,
@@ -1143,9 +1338,8 @@ poplevel (keep, reverse, functionbody)
if (decls || tags || subblocks)
{
if (BLOCK_VARS (block) || BLOCK_TYPE_TAGS (block))
- {
- warning ("internal compiler error: debugging info corrupted");
- }
+ warning ("internal compiler error: debugging info corrupted");
+
BLOCK_VARS (block) = decls;
BLOCK_TYPE_TAGS (block) = tags;
@@ -1164,7 +1358,8 @@ poplevel (keep, reverse, functionbody)
BLOCK_VARS (block) = decls;
BLOCK_TYPE_TAGS (block) = tags;
BLOCK_SUBBLOCKS (block) = subblocks;
- /* Otherwise, for a new block, install a new BLOCK_END_NOTE value. */
+ /* Otherwise, for a new block, install a new BLOCK_END_NOTE
+ value. */
remember_end_note (block);
}
}
@@ -1175,92 +1370,123 @@ poplevel (keep, reverse, functionbody)
for (link = subblocks; link; link = TREE_CHAIN (link))
BLOCK_SUPERCONTEXT (link) = block;
- /* Clear out the meanings of the local variables of this level. */
+ /* We still support the old for-scope rules, whereby the variables
+ in a for-init statement were in scope after the for-statement
+ ended. We only use the new rules in flag_new_for_scope is
+ nonzero. */
+ leaving_for_scope
+ = current_binding_level->is_for_scope && flag_new_for_scope == 1;
- if (current_binding_level->is_for_scope && flag_new_for_scope == 1)
+ /* Remove declarations for all the DECLs in this level. */
+ for (link = decls; link; link = TREE_CHAIN (link))
{
- struct binding_level *outer = current_binding_level->level_chain;
- for (link = decls; link; link = TREE_CHAIN (link))
+ if (leaving_for_scope && TREE_CODE (link) == VAR_DECL)
{
- if (TREE_CODE (link) == VAR_DECL)
- DECL_DEAD_FOR_LOCAL (link) = 1;
- else
- IDENTIFIER_LOCAL_VALUE (DECL_NAME (link)) = NULL_TREE;
- }
+ tree outer_binding
+ = TREE_CHAIN (IDENTIFIER_BINDING (DECL_NAME (link)));
+ tree ns_binding;
- /* Save declarations made in a 'for' statement so we can support pre-ANSI
- 'for' scoping semantics. */
-
- for (link = current_binding_level->shadowed; link; link = TREE_CHAIN (link))
- {
- tree id = TREE_PURPOSE (link);
- tree decl = IDENTIFIER_LOCAL_VALUE (id);
+ if (!outer_binding)
+ ns_binding = IDENTIFIER_NAMESPACE_VALUE (DECL_NAME (link));
+ else
+ ns_binding = NULL_TREE;
- if (decl && DECL_DEAD_FOR_LOCAL (decl))
+ if (outer_binding
+ && (BINDING_LEVEL (outer_binding)
+ == current_binding_level->level_chain))
+ /* We have something like:
+
+ int i;
+ for (int i; ;);
+
+ and we are leaving the `for' scope. There's no reason to
+ keep the binding of the inner `i' in this case. */
+ pop_binding (DECL_NAME (link), link);
+ else if ((outer_binding
+ && (TREE_CODE (BINDING_VALUE (outer_binding))
+ == TYPE_DECL))
+ || (ns_binding
+ && TREE_CODE (ns_binding) == TYPE_DECL))
+ /* Here, we have something like:
+
+ typedef int I;
+
+ void f () {
+ for (int I; ;);
+ }
+
+ We must pop the for-scope binding so we know what's a
+ type and what isn't. */
+ pop_binding (DECL_NAME (link), link);
+ else
{
- /* In this case keep the dead for-decl visible,
- but remember what (if anything) it shadowed. */
- DECL_SHADOWED_FOR_VAR (decl) = TREE_VALUE (link);
- TREE_CHAIN (decl) = outer->dead_vars_from_for;
- outer->dead_vars_from_for = decl;
+ /* Mark this VAR_DECL as dead so that we can tell we left it
+ there only for backward compatibility. */
+ DECL_DEAD_FOR_LOCAL (link) = 1;
+
+ /* Keep track of what should of have happenned when we
+ popped the binding. */
+ if (outer_binding && BINDING_VALUE (outer_binding))
+ DECL_SHADOWED_FOR_VAR (link)
+ = BINDING_VALUE (outer_binding);
+
+ /* Add it to the list of dead variables in the next
+ outermost binding to that we can remove these when we
+ leave that binding. */
+ current_binding_level->level_chain->dead_vars_from_for
+ = tree_cons (NULL_TREE, link,
+ current_binding_level->level_chain->
+ dead_vars_from_for);
+
+ /* Although we don't pop the CPLUS_BINDING, we do clear
+ its BINDING_LEVEL since the level is going away now. */
+ BINDING_LEVEL (IDENTIFIER_BINDING (DECL_NAME (link)))
+ = 0;
}
- else
- IDENTIFIER_LOCAL_VALUE (id) = TREE_VALUE (link);
}
- }
- else /* Not special for scope. */
- {
- for (link = decls; link; link = TREE_CHAIN (link))
+ else
{
- if (DECL_NAME (link) != NULL_TREE)
- {
- /* If the ident. was used or addressed via a local extern decl,
- don't forget that fact. */
- if (DECL_EXTERNAL (link))
- {
- if (TREE_USED (link))
- TREE_USED (DECL_ASSEMBLER_NAME (link)) = 1;
- if (TREE_ADDRESSABLE (link))
- TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (link)) = 1;
- }
- IDENTIFIER_LOCAL_VALUE (DECL_NAME (link)) = NULL_TREE;
- }
+ /* Remove the binding. */
+ decl = link;
+ if (TREE_CODE (decl) == TREE_LIST)
+ decl = TREE_VALUE (decl);
+ if (TREE_CODE_CLASS (TREE_CODE (decl)) == 'd')
+ pop_binding (DECL_NAME (decl), decl);
+ else if (TREE_CODE (decl) == OVERLOAD)
+ pop_binding (DECL_NAME (OVL_FUNCTION (decl)), decl);
+ else
+ my_friendly_abort (0);
}
+ }
- /* Restore all name-meanings of the outer levels
- that were shadowed by this level. */
-
- for (link = current_binding_level->shadowed;
- link; link = TREE_CHAIN (link))
- IDENTIFIER_LOCAL_VALUE (TREE_PURPOSE (link)) = TREE_VALUE (link);
-
- /* We first restore the regular decls and *then* the dead_vars_from_for
- to handle this case:
-
- int i; // i#1
- {
- for (int i; ; ) { ...} // i#2
- int i; // i#3
- } // we are here
+ /* Remove declarations for any `for' variables from inner scopes
+ that we kept around. */
+ for (link = current_binding_level->dead_vars_from_for;
+ link; link = TREE_CHAIN (link))
+ pop_binding (DECL_NAME (TREE_VALUE (link)), TREE_VALUE (link));
- In this case, we want remove the binding for i#3, restoring
- that of i#2. Then we want to remove the binding for i#2,
- and restore that of i#1. */
+ /* Restore the IDENTIFIER_TYPE_VALUEs. */
+ for (link = current_binding_level->type_shadowed;
+ link; link = TREE_CHAIN (link))
+ SET_IDENTIFIER_TYPE_VALUE (TREE_PURPOSE (link), TREE_VALUE (link));
+
+ /* There may be OVERLOADs (wrapped in TREE_LISTs) on the BLOCK_VARs
+ list if a `using' declaration put them there. The debugging
+ back-ends won't understand OVERLOAD, so we remove them here.
+ Because the BLOCK_VARS are (temporarily) shared with
+ CURRENT_BINDING_LEVEL->NAMES we must do this fixup after we have
+ popped all the bindings. */
+ if (block)
+ {
+ tree* d;
- link = current_binding_level->dead_vars_from_for;
- for (; link != NULL_TREE; link = TREE_CHAIN (link))
+ for (d = &BLOCK_VARS (block); *d; )
{
- tree id = DECL_NAME (link);
- if (IDENTIFIER_LOCAL_VALUE (id) == link)
- IDENTIFIER_LOCAL_VALUE (id) = DECL_SHADOWED_FOR_VAR (link);
+ if (TREE_CODE (*d) == TREE_LIST)
+ *d = TREE_CHAIN (*d);
+ else
+ d = &TREE_CHAIN (*d);
}
-
- for (link = current_binding_level->class_shadowed;
- link; link = TREE_CHAIN (link))
- IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (link)) = TREE_VALUE (link);
- for (link = current_binding_level->type_shadowed;
- link; link = TREE_CHAIN (link))
- SET_IDENTIFIER_TYPE_VALUE (TREE_PURPOSE (link), TREE_VALUE (link));
}
/* If the level being exited is the top level of a function,
@@ -1335,14 +1561,8 @@ poplevel (keep, reverse, functionbody)
must be carried forward so they will later become subblocks
of something else. */
else if (subblocks)
- {
- if (keep == 2)
- current_binding_level->blocks
- = chainon (subblocks, current_binding_level->blocks);
- else
- current_binding_level->blocks
- = chainon (current_binding_level->blocks, subblocks);
- }
+ current_binding_level->blocks
+ = chainon (current_binding_level->blocks, subblocks);
/* Take care of compiler's internal binding structures. */
if (tmp == 2)
@@ -1429,9 +1649,7 @@ pushlevel_class ()
free_binding_level = free_binding_level->level_chain;
}
else
- {
- newlevel = make_binding_level ();
- }
+ newlevel = make_binding_level ();
#if defined(DEBUG_CP_BINDING_LEVELS)
is_class_level = 1;
@@ -1466,8 +1684,6 @@ poplevel_class (force)
my_friendly_assert (level != 0, 354);
decl_stack = pop_stack_level (decl_stack);
- for (shadowed = level->shadowed; shadowed; shadowed = TREE_CHAIN (shadowed))
- IDENTIFIER_LOCAL_VALUE (TREE_PURPOSE (shadowed)) = TREE_VALUE (shadowed);
/* If we're leaving a toplevel class, don't bother to do the setting
of IDENTIFIER_CLASS_VALUE to NULL_TREE, since first of all this slot
shouldn't even be used when current_class_type isn't set, and second,
@@ -1490,6 +1706,12 @@ poplevel_class (force)
shadowed = TREE_CHAIN (shadowed))
SET_IDENTIFIER_TYPE_VALUE (TREE_PURPOSE (shadowed), TREE_VALUE (shadowed));
+ /* Remove the bindings for all of the class-level declarations. */
+ for (shadowed = level->class_shadowed;
+ shadowed;
+ shadowed = TREE_CHAIN (shadowed))
+ pop_binding (TREE_PURPOSE (shadowed), TREE_TYPE (shadowed));
+
GNU_xref_end_scope ((HOST_WIDE_INT) class_binding_level,
(HOST_WIDE_INT) class_binding_level->level_chain,
class_binding_level->parm_flag,
@@ -1620,15 +1842,6 @@ print_binding_level (lvl)
if (i)
fprintf (stderr, "\n");
}
- if (lvl->shadowed)
- {
- fprintf (stderr, " shadowed:");
- for (t = lvl->shadowed; t; t = TREE_CHAIN (t))
- {
- fprintf (stderr, " %s ", IDENTIFIER_POINTER (TREE_PURPOSE (t)));
- }
- fprintf (stderr, "\n");
- }
if (lvl->class_shadowed)
{
fprintf (stderr, " class-shadowed:");
@@ -1917,6 +2130,10 @@ cat_namespace_levels()
/* The nested namespaces appear in the names list of their ancestors. */
for (current = last; current; current = TREE_CHAIN (current))
{
+ /* Catch simple infinite loops. */
+ if (TREE_CHAIN (current) == current)
+ my_friendly_abort (990126);
+
if (TREE_CODE (current) != NAMESPACE_DECL
|| DECL_NAMESPACE_ALIAS (current))
continue;
@@ -2001,9 +2218,11 @@ store_bindings (names, old_bindings)
else
id = DECL_NAME (t);
- if (!id
- || (!IDENTIFIER_LOCAL_VALUE (id)
- && !IDENTIFIER_CLASS_VALUE (id)))
+ if (!id
+ /* Note that we may have an IDENTIFIER_CLASS_VALUE even when
+ we have no IDENTIFIER_BINDING if we have left the class
+ scope, but cached the class-level declarations. */
+ || !(IDENTIFIER_BINDING (id) || IDENTIFIER_CLASS_VALUE (id)))
continue;
for (t1 = old_bindings; t1; t1 = TREE_CHAIN (t1))
@@ -2017,9 +2236,9 @@ store_bindings (names, old_bindings)
my_friendly_assert (TREE_CODE (id) == IDENTIFIER_NODE, 135);
TREE_VEC_ELT (binding, 0) = id;
TREE_VEC_ELT (binding, 1) = REAL_IDENTIFIER_TYPE_VALUE (id);
- TREE_VEC_ELT (binding, 2) = IDENTIFIER_LOCAL_VALUE (id);
+ TREE_VEC_ELT (binding, 2) = IDENTIFIER_BINDING (id);
TREE_VEC_ELT (binding, 3) = IDENTIFIER_CLASS_VALUE (id);
- IDENTIFIER_LOCAL_VALUE (id) = NULL_TREE;
+ IDENTIFIER_BINDING (id) = NULL_TREE;
IDENTIFIER_CLASS_VALUE (id) = NULL_TREE;
}
TREE_CHAIN (binding) = old_bindings;
@@ -2143,16 +2362,16 @@ pop_from_top_level ()
current_saved_scope = s->prev;
for (t = s->old_bindings; t; )
{
+ tree save = t;
tree id = TREE_VEC_ELT (t, 0);
if (id)
{
SET_IDENTIFIER_TYPE_VALUE (id, TREE_VEC_ELT (t, 1));
- IDENTIFIER_LOCAL_VALUE (id) = TREE_VEC_ELT (t, 2);
+ IDENTIFIER_BINDING (id) = TREE_VEC_ELT (t, 2);
IDENTIFIER_CLASS_VALUE (id) = TREE_VEC_ELT (t, 3);
}
t = TREE_CHAIN (t);
}
- s->old_bindings = NULL_TREE;
current_namespace = s->old_namespace;
current_class_name = s->class_name;
current_class_type = s->class_type;
@@ -2230,26 +2449,6 @@ set_identifier_type_value (id, type)
set_identifier_type_value_with_scope (id, type, inner_binding_level);
}
-static void
-set_identifier_local_value_with_scope (id, val, b)
- tree id, val;
- struct binding_level *b;
-{
- tree oldlocal;
- my_friendly_assert (! b->namespace_p, 980716);
-
- oldlocal = IDENTIFIER_LOCAL_VALUE (id);
- b->shadowed = tree_cons (id, oldlocal, b->shadowed);
- IDENTIFIER_LOCAL_VALUE (id) = val;
-}
-
-void
-set_identifier_local_value (id, val)
- tree id, val;
-{
- set_identifier_local_value_with_scope (id, val, current_binding_level);
-}
-
/* Return the type associated with id. */
tree
@@ -2301,7 +2500,7 @@ pop_everything ()
Returns the TYPE_DECL for TYPE, which may have been altered by this
processing. */
-static tree
+static tree
maybe_process_template_type_declaration (type, globalize, b)
tree type;
int globalize;
@@ -2568,8 +2767,15 @@ decls_match (newdecl, olddecl)
{
int types_match;
- if (TREE_CODE (newdecl) == FUNCTION_DECL
- && TREE_CODE (olddecl) == FUNCTION_DECL)
+ if (newdecl == olddecl)
+ return 1;
+
+ if (TREE_CODE (newdecl) != TREE_CODE (olddecl))
+ /* If the two DECLs are not even the same kind of thing, we're not
+ interested in their types. */
+ return 0;
+
+ if (TREE_CODE (newdecl) == FUNCTION_DECL)
{
tree f1 = TREE_TYPE (newdecl);
tree f2 = TREE_TYPE (olddecl);
@@ -2604,7 +2810,7 @@ decls_match (newdecl, olddecl)
return 0;
}
- if (comptypes (TREE_TYPE (f1), TREE_TYPE (f2), 1))
+ if (same_type_p (TREE_TYPE (f1), TREE_TYPE (f2)))
{
if (! strict_prototypes_lang_c && DECL_LANGUAGE (olddecl) == lang_c
&& p2 == NULL_TREE)
@@ -2620,13 +2826,12 @@ decls_match (newdecl, olddecl)
TREE_TYPE (newdecl) = TREE_TYPE (olddecl);
}
else
- types_match = compparms (p1, p2, 3);
+ types_match = compparms (p1, p2);
}
else
types_match = 0;
}
- else if (TREE_CODE (newdecl) == TEMPLATE_DECL
- && TREE_CODE (olddecl) == TEMPLATE_DECL)
+ else if (TREE_CODE (newdecl) == TEMPLATE_DECL)
{
if (!comp_template_parms (DECL_TEMPLATE_PARMS (newdecl),
DECL_TEMPLATE_PARMS (olddecl)))
@@ -2648,7 +2853,8 @@ decls_match (newdecl, olddecl)
types_match = 0;
else
types_match = comptypes (TREE_TYPE (newdecl),
- TREE_TYPE (olddecl), 1);
+ TREE_TYPE (olddecl),
+ COMPARE_REDECLARATION);
}
return types_match;
@@ -2670,9 +2876,9 @@ warn_extern_redeclared_static (newdecl, olddecl)
{
tree name;
- static char *explicit_extern_static_warning
+ static const char *explicit_extern_static_warning
= "`%D' was declared `extern' and later `static'";
- static char *implicit_extern_static_warning
+ static const char *implicit_extern_static_warning
= "`%D' was declared implicitly `extern' and later `static'";
if (TREE_CODE (newdecl) == TYPE_DECL)
@@ -2808,6 +3014,11 @@ duplicate_decls (newdecl, olddecl)
}
else if (!types_match)
{
+ if (DECL_REAL_CONTEXT (newdecl) != DECL_REAL_CONTEXT (olddecl))
+ /* These are certainly not duplicate declarations; they're
+ from different scopes. */
+ return 0;
+
if (TREE_CODE (newdecl) == TEMPLATE_DECL)
{
/* The name of a class template may not be declared to refer to
@@ -2823,7 +3034,7 @@ duplicate_decls (newdecl, olddecl)
else if (TREE_CODE (DECL_TEMPLATE_RESULT (olddecl)) == FUNCTION_DECL
&& TREE_CODE (DECL_TEMPLATE_RESULT (newdecl)) == FUNCTION_DECL
&& compparms (TYPE_ARG_TYPES (TREE_TYPE (DECL_TEMPLATE_RESULT (olddecl))),
- TYPE_ARG_TYPES (TREE_TYPE (DECL_TEMPLATE_RESULT (newdecl))), 3)
+ TYPE_ARG_TYPES (TREE_TYPE (DECL_TEMPLATE_RESULT (newdecl))))
&& comp_template_parms (DECL_TEMPLATE_PARMS (newdecl),
DECL_TEMPLATE_PARMS (olddecl)))
{
@@ -2842,7 +3053,7 @@ duplicate_decls (newdecl, olddecl)
cp_error_at ("previous declaration `%#D' here", olddecl);
}
else if (compparms (TYPE_ARG_TYPES (TREE_TYPE (newdecl)),
- TYPE_ARG_TYPES (TREE_TYPE (olddecl)), 3))
+ TYPE_ARG_TYPES (TREE_TYPE (olddecl))))
{
cp_error ("new declaration `%#D'", newdecl);
cp_error_at ("ambiguates old declaration `%#D'", olddecl);
@@ -2892,7 +3103,7 @@ duplicate_decls (newdecl, olddecl)
return 1;
else
{
- char *errmsg = redeclaration_error_message (newdecl, olddecl);
+ const char *errmsg = redeclaration_error_message (newdecl, olddecl);
if (errmsg)
{
cp_error (errmsg, newdecl);
@@ -3041,9 +3252,6 @@ duplicate_decls (newdecl, olddecl)
DECL_TEMPLATE_RESULT (olddecl)))
cp_error ("invalid redeclaration of %D", newdecl);
TREE_TYPE (olddecl) = TREE_TYPE (DECL_TEMPLATE_RESULT (olddecl));
- DECL_TEMPLATE_PARMS (olddecl) = DECL_TEMPLATE_PARMS (newdecl);
- if (DECL_TEMPLATE_INFO (newdecl))
- DECL_TEMPLATE_INFO (olddecl) = DECL_TEMPLATE_INFO (newdecl);
DECL_TEMPLATE_SPECIALIZATIONS (olddecl)
= chainon (DECL_TEMPLATE_SPECIALIZATIONS (olddecl),
DECL_TEMPLATE_SPECIALIZATIONS (newdecl));
@@ -3095,7 +3303,7 @@ duplicate_decls (newdecl, olddecl)
TREE_TYPE (newdecl) = TREE_TYPE (olddecl) = newtype;
/* Lay the type out, unless already done. */
- if (newtype != canonical_type_variant (oldtype)
+ if (! same_type_p (newtype, oldtype)
&& TREE_TYPE (newdecl) != error_mark_node
&& !(processing_template_decl && uses_template_parms (newdecl)))
layout_type (TREE_TYPE (newdecl));
@@ -3170,17 +3378,22 @@ duplicate_decls (newdecl, olddecl)
DECL_INTERFACE_KNOWN (newdecl) |= DECL_INTERFACE_KNOWN (olddecl);
DECL_NOT_REALLY_EXTERN (newdecl) |= DECL_NOT_REALLY_EXTERN (olddecl);
DECL_COMDAT (newdecl) |= DECL_COMDAT (olddecl);
+ DECL_TEMPLATE_INSTANTIATED (newdecl)
+ |= DECL_TEMPLATE_INSTANTIATED (olddecl);
/* Don't really know how much of the language-specific
values we should copy from old to new. */
DECL_IN_AGGR_P (newdecl) = DECL_IN_AGGR_P (olddecl);
DECL_ACCESS (newdecl) = DECL_ACCESS (olddecl);
DECL_NONCONVERTING_P (newdecl) = DECL_NONCONVERTING_P (olddecl);
- if (DECL_TEMPLATE_INFO (newdecl) == NULL_TREE)
- {
- DECL_TEMPLATE_INFO (newdecl) = DECL_TEMPLATE_INFO (olddecl);
- DECL_USE_TEMPLATE (newdecl) = DECL_USE_TEMPLATE (olddecl);
- }
+ DECL_TEMPLATE_INFO (newdecl) = DECL_TEMPLATE_INFO (olddecl);
olddecl_friend = DECL_FRIEND_P (olddecl);
+
+ /* Only functions have DECL_BEFRIENDING_CLASSES. */
+ if (TREE_CODE (newdecl) == FUNCTION_DECL
+ || DECL_FUNCTION_TEMPLATE_P (newdecl))
+ DECL_BEFRIENDING_CLASSES (newdecl)
+ = chainon (DECL_BEFRIENDING_CLASSES (newdecl),
+ DECL_BEFRIENDING_CLASSES (olddecl));
}
if (TREE_CODE (newdecl) == FUNCTION_DECL)
@@ -3244,6 +3457,8 @@ duplicate_decls (newdecl, olddecl)
regardless of declaration matches. */
DECL_RTL (newdecl) = DECL_RTL (olddecl);
}
+ else
+ DECL_FRAME_SIZE (newdecl) = DECL_FRAME_SIZE (olddecl);
DECL_RESULT (newdecl) = DECL_RESULT (olddecl);
if ((DECL_SAVED_INSNS (newdecl) = DECL_SAVED_INSNS (olddecl)))
@@ -3384,23 +3599,30 @@ pushdecl (x)
{
register tree t;
register tree name = DECL_ASSEMBLER_NAME (x);
- register struct binding_level *b = current_binding_level;
-
- if (current_function_decl && x != current_function_decl
- /* A local declaration for a function doesn't constitute nesting. */
- && (TREE_CODE (x) != FUNCTION_DECL || DECL_INITIAL (x))
- /* Don't change DECL_CONTEXT of virtual methods. */
- && (TREE_CODE (x) != FUNCTION_DECL || !DECL_VIRTUAL_P (x))
- && ! DECL_CONTEXT (x))
- DECL_CONTEXT (x) = current_function_decl;
- if (!DECL_CONTEXT (x))
- DECL_CONTEXT (x) = FROB_CONTEXT (current_namespace);
+ int need_new_binding = 1;
+
+ if (DECL_TEMPLATE_PARM_P (x))
+ /* Template parameters have no context; they are not X::T even
+ when declared within a class or namespace. */
+ ;
+ else
+ {
+ if (current_function_decl && x != current_function_decl
+ /* A local declaration for a function doesn't constitute
+ nesting. */
+ && (TREE_CODE (x) != FUNCTION_DECL || DECL_INITIAL (x))
+ /* Don't change DECL_CONTEXT of virtual methods. */
+ && (TREE_CODE (x) != FUNCTION_DECL || !DECL_VIRTUAL_P (x))
+ && !DECL_CONTEXT (x))
+ DECL_CONTEXT (x) = current_function_decl;
+ if (!DECL_CONTEXT (x))
+ DECL_CONTEXT (x) = FROB_CONTEXT (current_namespace);
+ }
/* Type are looked up using the DECL_NAME, as that is what the rest of the
compiler wants to use. */
if (TREE_CODE (x) == TYPE_DECL || TREE_CODE (x) == VAR_DECL
- || TREE_CODE (x) == NAMESPACE_DECL || TREE_CODE (x) == TEMPLATE_TYPE_PARM
- || TREE_CODE (x) == TEMPLATE_TEMPLATE_PARM)
+ || TREE_CODE (x) == NAMESPACE_DECL)
name = DECL_NAME (x);
if (name)
@@ -3514,14 +3736,30 @@ pushdecl (x)
}
}
+ check_template_shadow (x);
+
+ /* If this is a function conjured up by the backend, massage it
+ so it looks friendly. */
+ if (TREE_CODE (x) == FUNCTION_DECL
+ && ! DECL_LANG_SPECIFIC (x))
+ {
+ retrofit_lang_decl (x);
+ DECL_LANGUAGE (x) = lang_c;
+ }
+
if (TREE_CODE (x) == FUNCTION_DECL && ! DECL_FUNCTION_MEMBER_P (x))
{
- t = push_overloaded_decl (x, 1);
+ t = push_overloaded_decl (x, PUSH_LOCAL);
if (t != x || DECL_LANGUAGE (x) == lang_c)
return t;
+ if (!namespace_bindings_p ())
+ /* We do not need to create a binding for this name;
+ push_overloaded_decl will have already done so if
+ necessary. */
+ need_new_binding = 0;
}
else if (DECL_FUNCTION_TEMPLATE_P (x) && DECL_NAMESPACE_SCOPE_P (x))
- return push_overloaded_decl (x, 0);
+ return push_overloaded_decl (x, PUSH_GLOBAL);
/* If declaring a type as a typedef, copy the type (unless we're
at line 0), and install this TYPE_DECL as the new type's typedef
@@ -3555,7 +3793,9 @@ pushdecl (x)
if (type != error_mark_node
&& TYPE_NAME (type)
&& TYPE_IDENTIFIER (type))
- set_identifier_type_value_with_scope (DECL_NAME (x), type, b);
+ set_identifier_type_value_with_scope (DECL_NAME (x), type,
+ current_binding_level);
+
}
/* Multiple external decls of the same identifier ought to match.
@@ -3578,7 +3818,7 @@ pushdecl (x)
if (decl
/* If different sort of thing, we already gave an error. */
&& TREE_CODE (decl) == TREE_CODE (x)
- && ! comptypes (TREE_TYPE (x), TREE_TYPE (decl), 1))
+ && !same_type_p (TREE_TYPE (x), TREE_TYPE (decl)))
{
cp_pedwarn ("type mismatch with previous external decl", x);
cp_pedwarn_at ("previous external decl of `%#D'", decl);
@@ -3596,11 +3836,8 @@ pushdecl (x)
if (IDENTIFIER_GLOBAL_VALUE (name) == NULL_TREE && TREE_PUBLIC (x))
TREE_PUBLIC (name) = 1;
- /* Don't install an artificial TYPE_DECL if we already have
- another _DECL with that name. */
- if (TREE_CODE (x) != TYPE_DECL
- || t == NULL_TREE
- || ! DECL_ARTIFICIAL (x))
+ if (!(TREE_CODE (x) == TYPE_DECL && DECL_ARTIFICIAL (x)
+ && t != NULL_TREE))
{
if (TREE_CODE (x) == FUNCTION_DECL)
my_friendly_assert
@@ -3635,25 +3872,29 @@ pushdecl (x)
else
{
/* Here to install a non-global value. */
- tree oldlocal = IDENTIFIER_LOCAL_VALUE (name);
+ tree oldlocal = IDENTIFIER_VALUE (name);
tree oldglobal = IDENTIFIER_NAMESPACE_VALUE (name);
- /* Don't install an artificial TYPE_DECL if we already have
- another _DECL with that name. */
- if (TREE_CODE (x) != TYPE_DECL
- || t == NULL_TREE
- || ! DECL_ARTIFICIAL (x))
- set_identifier_local_value_with_scope (name, x, b);
+ if (need_new_binding)
+ {
+ push_local_binding (name, x, 0);
+ /* Because push_local_binding will hook X on to the
+ current_binding_level's name list, we don't want to
+ do that again below. */
+ need_new_binding = 0;
+ }
/* If this is a TYPE_DECL, push it into the type value slot. */
if (TREE_CODE (x) == TYPE_DECL)
- set_identifier_type_value_with_scope (name, TREE_TYPE (x), b);
+ set_identifier_type_value_with_scope (name, TREE_TYPE (x),
+ current_binding_level);
/* Clear out any TYPE_DECL shadowed by a namespace so that
we won't think this is a type. The C struct hack doesn't
go through namespaces. */
if (TREE_CODE (x) == NAMESPACE_DECL)
- set_identifier_type_value_with_scope (name, NULL_TREE, b);
+ set_identifier_type_value_with_scope (name, NULL_TREE,
+ current_binding_level);
/* If this is an extern function declaration, see if we
have a global definition or declaration for the function. */
@@ -3679,9 +3920,7 @@ pushdecl (x)
&& oldglobal == NULL_TREE
&& DECL_EXTERNAL (x)
&& TREE_PUBLIC (x))
- {
- TREE_PUBLIC (name) = 1;
- }
+ TREE_PUBLIC (name) = 1;
if (DECL_FROM_INLINE (x))
/* Inline decls shadow nothing. */;
@@ -3702,7 +3941,8 @@ pushdecl (x)
if (b->parm_flag == 1)
cp_error ("declaration of `%#D' shadows a parameter", name);
}
- else if (warn_shadow && oldlocal != NULL_TREE && b->is_for_scope
+ else if (warn_shadow && oldlocal != NULL_TREE
+ && current_binding_level->is_for_scope
&& !DECL_DEAD_FOR_LOCAL (oldlocal))
{
warning ("variable `%s' shadows local",
@@ -3716,7 +3956,7 @@ pushdecl (x)
/* No shadow warnings for vars made for inlining. */
&& ! DECL_FROM_INLINE (x))
{
- char *warnstring = NULL;
+ const char *warnstring = NULL;
if (oldlocal != NULL_TREE && TREE_CODE (oldlocal) == PARM_DECL)
warnstring = "declaration of `%s' shadows a parameter";
@@ -3733,16 +3973,6 @@ pushdecl (x)
if (warnstring)
warning (warnstring, IDENTIFIER_POINTER (name));
}
- /* Check to see if decl redeclares a template parameter. */
- if (oldlocal && (current_class_type || current_function_decl)
- && current_template_parms)
- {
- if (decl_template_parm_p (oldlocal))
- {
- cp_error ("re-using name of template parameter `%T' in this scope", name);
- cp_error_at (" previously declared here `%#D'", oldlocal);
- }
- }
}
if (TREE_CODE (x) == FUNCTION_DECL)
@@ -3756,15 +3986,20 @@ pushdecl (x)
/* RTTI TD entries are created while defining the type_info. */
|| (TYPE_LANG_SPECIFIC (TREE_TYPE (x))
&& TYPE_BEING_DEFINED (TREE_TYPE (x)))))
- b->incomplete = tree_cons (NULL_TREE, x, b->incomplete);
+ current_binding_level->incomplete
+ = tree_cons (NULL_TREE, x, current_binding_level->incomplete);
}
- /* Put decls on list in reverse order.
- We will reverse them later if necessary. */
- TREE_CHAIN (x) = b->names;
- b->names = x;
- if (! (b != global_binding_level || TREE_PERMANENT (x)))
- my_friendly_abort (124);
+ if (need_new_binding)
+ {
+ /* Put decls on list in reverse order.
+ We will reverse them later if necessary. */
+ TREE_CHAIN (x) = current_binding_level->names;
+ current_binding_level->names = x;
+ if (! (current_binding_level != global_binding_level
+ || TREE_PERMANENT (x)))
+ my_friendly_abort (124);
+ }
return x;
}
@@ -3878,8 +4113,8 @@ pushdecl_class_level (x)
Types, enums, and static vars are checked here; other
members are checked in finish_struct. */
tree icv = IDENTIFIER_CLASS_VALUE (name);
- tree ilv = IDENTIFIER_LOCAL_VALUE (name);
+ /* This should match check_member_decl_is_same_in_complete_scope. */
if (icv && icv != x
&& flag_optional_diags
/* Don't complain about inherited names. */
@@ -3893,24 +4128,12 @@ pushdecl_class_level (x)
icv);
}
- /* Check to see if decl redeclares a template parameter. */
- if (ilv && ! decls_match (ilv, x)
- && (current_class_type || current_function_decl)
- && current_template_parms)
- {
- if (decl_template_parm_p (ilv))
- {
- cp_error ("re-using name of template parameter `%T' in this scope", name);
- cp_error_at (" previously declared here `%#D'", ilv);
- }
- }
+ check_template_shadow (x);
}
push_class_level_binding (name, x);
if (TREE_CODE (x) == TYPE_DECL)
- {
- set_identifier_type_value (name, TREE_TYPE (x));
- }
+ set_identifier_type_value (name, TREE_TYPE (x));
}
}
@@ -3950,16 +4173,21 @@ push_class_level_binding (name, x)
if (!class_binding_level)
return;
- if (TREE_CODE (x) == TYPE_DECL && DECL_ARTIFICIAL (x)
- && purpose_member (name, class_binding_level->class_shadowed))
- return;
-
+ /* If this declaration shadows a declaration from an enclosing
+ class, then we will need to restore IDENTIFIER_CLASS_VALUE when
+ we leave this class. Record the shadowed declaration here. */
maybe_push_cache_obstack ();
class_binding_level->class_shadowed
- = tree_cons (name, IDENTIFIER_CLASS_VALUE (name),
- class_binding_level->class_shadowed);
+ = tree_cons (name, IDENTIFIER_CLASS_VALUE (name),
+ class_binding_level->class_shadowed);
+ TREE_TYPE (class_binding_level->class_shadowed)
+ = x;
pop_obstacks ();
- IDENTIFIER_CLASS_VALUE (name) = x;
+
+ /* Put the binding on the stack of bindings for the identifier, and
+ update IDENTIFIER_CLASS_VALUE. */
+ push_class_binding (name, x);
+
obstack_ptr_grow (&decl_obstack, x);
}
@@ -4014,31 +4242,38 @@ push_using_directive (used)
return ud;
}
-/* DECL is a FUNCTION_DECL which may have other definitions already in
- place. We get around this by making the value of the identifier point
- to a list of all the things that want to be referenced by that name. It
- is then up to the users of that name to decide what to do with that
- list.
+/* DECL is a FUNCTION_DECL for a non-member function, which may have
+ other definitions already in place. We get around this by making
+ the value of the identifier point to a list of all the things that
+ want to be referenced by that name. It is then up to the users of
+ that name to decide what to do with that list.
DECL may also be a TEMPLATE_DECL, with a FUNCTION_DECL in its DECL_RESULT
slot. It is dealt with the same way.
+ FLAGS is a bitwise-or of the following values:
+ PUSH_LOCAL: Bind DECL in the current scope, rather than at
+ namespace scope.
+ PUSH_USING: DECL is being pushed as the result of a using
+ declaration.
+
The value returned may be a previous declaration if we guessed wrong
about what language DECL should belong to (C or C++). Otherwise,
it's always DECL (and never something that's not a _DECL). */
-static tree
-push_overloaded_decl (decl, forgettable)
+tree
+push_overloaded_decl (decl, flags)
tree decl;
- int forgettable;
+ int flags;
{
- tree orig_name = DECL_NAME (decl);
+ tree name = DECL_NAME (decl);
tree old;
- int doing_global = (namespace_bindings_p () || ! forgettable);
+ tree new_binding;
+ int doing_global = (namespace_bindings_p () || !(flags & PUSH_LOCAL));
if (doing_global)
{
- old = namespace_binding (orig_name, DECL_CONTEXT (decl));
+ old = namespace_binding (name, DECL_CONTEXT (decl));
if (old && TREE_CODE (old) == FUNCTION_DECL
&& DECL_ARTIFICIAL (old)
&& (DECL_BUILT_IN (old) || DECL_BUILT_IN_NONANSI (old)))
@@ -4049,16 +4284,7 @@ push_overloaded_decl (decl, forgettable)
}
}
else
- {
- old = IDENTIFIER_LOCAL_VALUE (orig_name);
-
- if (! purpose_member (orig_name, current_binding_level->shadowed))
- {
- current_binding_level->shadowed
- = tree_cons (orig_name, old, current_binding_level->shadowed);
- old = NULL_TREE;
- }
- }
+ old = lookup_name_current_level (name);
if (old)
{
@@ -4076,9 +4302,19 @@ push_overloaded_decl (decl, forgettable)
tree tmp;
for (tmp = old; tmp; tmp = OVL_NEXT (tmp))
- if (decl == OVL_CURRENT (tmp)
- || duplicate_decls (decl, OVL_CURRENT (tmp)))
- return OVL_CURRENT (tmp);
+ {
+ tree fn = OVL_CURRENT (tmp);
+
+ if (TREE_CODE (tmp) == OVERLOAD && OVL_USED (tmp)
+ && !(flags & PUSH_USING)
+ && compparms (TYPE_ARG_TYPES (TREE_TYPE (fn)),
+ TYPE_ARG_TYPES (TREE_TYPE (decl))))
+ cp_error ("`%#D' conflicts with previous using declaration `%#D'",
+ decl, fn);
+
+ if (duplicate_decls (decl, fn))
+ return fn;
+ }
}
else
{
@@ -4091,17 +4327,57 @@ push_overloaded_decl (decl, forgettable)
if (old || TREE_CODE (decl) == TEMPLATE_DECL)
{
if (old && TREE_CODE (old) != OVERLOAD)
- old = ovl_cons (old, NULL_TREE);
- old = ovl_cons (decl, old);
+ new_binding = ovl_cons (decl, ovl_cons (old, NULL_TREE));
+ else
+ new_binding = ovl_cons (decl, old);
+ if (flags & PUSH_USING)
+ OVL_USED (new_binding) = 1;
}
else
- /* orig_name is not ambiguous. */
- old = decl;
+ /* NAME is not ambiguous. */
+ new_binding = decl;
if (doing_global)
- set_namespace_binding (orig_name, current_namespace, old);
+ set_namespace_binding (name, current_namespace, new_binding);
else
- IDENTIFIER_LOCAL_VALUE (orig_name) = old;
+ {
+ /* We only create an OVERLOAD if there was a previous binding at
+ this level, or if decl is a template. In the former case, we
+ need to remove the old binding and replace it with the new
+ binding. We must also run through the NAMES on the binding
+ level where the name was bound to update the chain. */
+
+ if (TREE_CODE (new_binding) == OVERLOAD && old)
+ {
+ tree *d;
+
+ for (d = &BINDING_LEVEL (IDENTIFIER_BINDING (name))->names;
+ *d;
+ d = &TREE_CHAIN (*d))
+ if (*d == old
+ || (TREE_CODE (*d) == TREE_LIST
+ && TREE_VALUE (*d) == old))
+ {
+ if (TREE_CODE (*d) == TREE_LIST)
+ /* Just replace the old binding with the new. */
+ TREE_VALUE (*d) = new_binding;
+ else
+ /* Build a TREE_LIST to wrap the OVERLOAD. */
+ *d = build_tree_list (NULL_TREE, new_binding);
+
+ /* And update the CPLUS_BINDING node. */
+ BINDING_VALUE (IDENTIFIER_BINDING (name))
+ = new_binding;
+ return decl;
+ }
+
+ /* We should always find a previous binding in this case. */
+ my_friendly_abort (0);
+ }
+
+ /* Install the new binding. */
+ push_local_binding (name, new_binding, flags);
+ }
return decl;
}
@@ -4157,7 +4433,7 @@ implicitly_declare (functionid)
Otherwise return an error message format string with a %s
where the identifier should go. */
-static char *
+static const char *
redeclaration_error_message (newdecl, olddecl)
tree newdecl, olddecl;
{
@@ -4166,7 +4442,7 @@ redeclaration_error_message (newdecl, olddecl)
/* Because C++ can put things into name space for free,
constructs like "typedef struct foo { ... } foo"
would look like an erroneous redeclaration. */
- if (comptypes (TREE_TYPE (newdecl), TREE_TYPE (olddecl), 0))
+ if (same_type_p (TREE_TYPE (newdecl), TREE_TYPE (olddecl)))
return 0;
else
return "redefinition of `%#D'";
@@ -4396,9 +4672,8 @@ define_label (filename, line, name)
and they should be cleaned up
by the time we get to the label. */
&& ! DECL_ARTIFICIAL (new_decls)
- && ((DECL_INITIAL (new_decls) != NULL_TREE
- && DECL_INITIAL (new_decls) != error_mark_node)
- || TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (new_decls))))
+ && !(DECL_INITIAL (new_decls) == NULL_TREE
+ && pod_type_p (TREE_TYPE (new_decls))))
{
if (! identified)
{
@@ -4408,8 +4683,13 @@ define_label (filename, line, name)
" from here");
identified = 1;
}
- cp_error_at (" crosses initialization of `%#D'",
- new_decls);
+ if (DECL_INITIAL (new_decls)
+ || TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (new_decls)))
+ cp_error_at (" crosses initialization of `%#D'",
+ new_decls);
+ else
+ cp_error_at (" enters scope of non-POD `%#D'",
+ new_decls);
}
new_decls = TREE_CHAIN (new_decls);
}
@@ -4807,9 +5087,18 @@ lookup_namespace_name (namespace, name)
my_friendly_assert (TREE_CODE (namespace) == NAMESPACE_DECL, 370);
- /* This happens for A::B<int> when B is a namespace. */
if (TREE_CODE (name) == NAMESPACE_DECL)
+ /* This happens for A::B<int> when B is a namespace. */
return name;
+ else if (TREE_CODE (name) == TEMPLATE_DECL)
+ {
+ /* This happens for A::B where B is a template, and there are no
+ template arguments. */
+ cp_error ("invalid use of `%D'", name);
+ return error_mark_node;
+ }
+
+ namespace = ORIGINAL_NAMESPACE (namespace);
my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 373);
@@ -4831,11 +5120,111 @@ lookup_namespace_name (namespace, name)
return error_mark_node;
}
+/* Hash a TYPENAME_TYPE. K is really of type `tree'. */
+
+static unsigned long
+typename_hash (k)
+ hash_table_key k;
+{
+ unsigned long hash;
+ tree t;
+
+ t = (tree) k;
+ hash = (((unsigned long) TYPE_CONTEXT (t))
+ ^ ((unsigned long) DECL_NAME (TYPE_NAME (t))));
+
+ return hash;
+}
+
+/* Compare two TYPENAME_TYPEs. K1 and K2 are really of type `tree'. */
+
+static boolean
+typename_compare (k1, k2)
+ hash_table_key k1;
+ hash_table_key k2;
+{
+ tree t1;
+ tree t2;
+ tree d1;
+ tree d2;
+
+ t1 = (tree) k1;
+ t2 = (tree) k2;
+ d1 = TYPE_NAME (t1);
+ d2 = TYPE_NAME (t2);
+
+ return (DECL_NAME (d1) == DECL_NAME (d2)
+ && same_type_p (TYPE_CONTEXT (t1), TYPE_CONTEXT (t2))
+ && ((TREE_TYPE (t1) != NULL_TREE)
+ == (TREE_TYPE (t2) != NULL_TREE))
+ && same_type_p (TREE_TYPE (t1), TREE_TYPE (t2))
+ && TYPENAME_TYPE_FULLNAME (t1) == TYPENAME_TYPE_FULLNAME (t2));
+}
+
+/* Build a TYPENAME_TYPE. If the type is `typename T::t', CONTEXT is
+ the type of `T', NAME is the IDENTIFIER_NODE for `t'. If BASE_TYPE
+ is non-NULL, this type is being created by the implicit typename
+ extension, and BASE_TYPE is a type named `t' in some base class of
+ `T' which depends on template parameters.
+
+ Returns the new TYPENAME_TYPE. */
+
+tree
+build_typename_type (context, name, fullname, base_type)
+ tree context;
+ tree name;
+ tree fullname;
+ tree base_type;
+{
+ tree t;
+ tree d;
+ struct hash_entry* e;
+
+ static struct hash_table ht;
+
+ push_obstacks (&permanent_obstack, &permanent_obstack);
+
+ if (!ht.table
+ && !hash_table_init (&ht, &hash_newfunc, &typename_hash,
+ &typename_compare))
+ fatal ("virtual memory exhausted");
+
+ /* Build the TYPENAME_TYPE. */
+ t = make_lang_type (TYPENAME_TYPE);
+ TYPE_CONTEXT (t) = FROB_CONTEXT (context);
+ TYPENAME_TYPE_FULLNAME (t) = fullname;
+ TREE_TYPE (t) = base_type;
+
+ /* Build the corresponding TYPE_DECL. */
+ d = build_decl (TYPE_DECL, name, t);
+ TYPE_NAME (TREE_TYPE (d)) = d;
+ TYPE_STUB_DECL (TREE_TYPE (d)) = d;
+ DECL_CONTEXT (d) = FROB_CONTEXT (context);
+ DECL_ARTIFICIAL (d) = 1;
+
+ /* See if we already have this type. */
+ e = hash_lookup (&ht, t, /*create=*/false, /*copy=*/0);
+ if (e)
+ {
+ /* This will free not only TREE_TYPE, but the lang-specific data
+ and the TYPE_DECL as well. */
+ obstack_free (&permanent_obstack, t);
+ t = (tree) e->key;
+ }
+ else
+ /* Insert the type into the table. */
+ hash_lookup (&ht, t, /*create=*/true, /*copy=*/0);
+
+ pop_obstacks ();
+
+ return t;
+}
+
tree
make_typename_type (context, name)
tree context, name;
{
- tree t, d;
+ tree t;
tree fullname;
if (TREE_CODE_CLASS (TREE_CODE (name)) == 't')
@@ -4871,52 +5260,33 @@ make_typename_type (context, name)
if (IS_AGGR_TYPE (context))
t = lookup_field (context, name, 0, 0);
else
- t = NULL_TREE;
-
- if (t == NULL_TREE || TREE_CODE (t) != TEMPLATE_DECL
- || TREE_CODE (DECL_RESULT (t)) != TYPE_DECL)
{
cp_error ("no class template named `%#T' in `%#T'",
name, context);
return error_mark_node;
}
- return lookup_template_class (t, TREE_OPERAND (fullname, 1),
- NULL_TREE, context,
- /*entering_scope=*/0);
+ if (t && DECL_CLASS_TEMPLATE_P (t))
+ return lookup_template_class (t, TREE_OPERAND (fullname, 1),
+ NULL_TREE, context,
+ /*entering_scope=*/0);
}
else
{
if (IS_AGGR_TYPE (context))
t = lookup_field (context, name, 0, 1);
else
- t = NULL_TREE;
-
- if (t == NULL_TREE)
{
cp_error ("no type named `%#T' in `%#T'", name, context);
return error_mark_node;
}
- return TREE_TYPE (t);
+ if (t)
+ return TREE_TYPE (t);
}
}
-
- if (processing_template_decl)
- push_obstacks (&permanent_obstack, &permanent_obstack);
- t = make_lang_type (TYPENAME_TYPE);
- TYPENAME_TYPE_FULLNAME (t) = fullname;
- d = build_decl (TYPE_DECL, name, t);
- if (processing_template_decl)
- pop_obstacks ();
-
- TYPE_CONTEXT (t) = FROB_CONTEXT (context);
- TYPE_NAME (TREE_TYPE (d)) = d;
- TYPE_STUB_DECL (TREE_TYPE (d)) = d;
- DECL_CONTEXT (d) = FROB_CONTEXT (context);
- CLASSTYPE_GOT_SEMICOLON (t) = 1;
-
- return t;
+
+ return build_typename_type (context, name, fullname, NULL_TREE);
}
/* Select the right _DECL from multiple choices. */
@@ -4944,7 +5314,8 @@ select_decl (binding, flags)
val = TYPE_STUB_DECL (BINDING_TYPE (binding));
/* Don't return non-types if we really prefer types. */
else if (val && LOOKUP_TYPES_ONLY (flags) && TREE_CODE (val) != TYPE_DECL
- && (!looking_for_template || TREE_CODE (val) != TEMPLATE_DECL))
+ && (TREE_CODE (val) != TEMPLATE_DECL
+ || !DECL_CLASS_TEMPLATE_P (val)))
val = NULL_TREE;
return val;
@@ -4981,7 +5352,7 @@ unqualified_namespace_lookup (name, flags)
if (!lookup_using_namespace (name, b, level->using_directives,
scope, flags))
/* Give up because of error. */
- return NULL_TREE;
+ return error_mark_node;
/* Add all _DECLs seen through global using-directives. */
/* XXX local and global using lists should work equally. */
@@ -4991,7 +5362,7 @@ unqualified_namespace_lookup (name, flags)
if (!lookup_using_namespace (name, b, DECL_NAMESPACE_USING (siter),
scope, flags))
/* Give up because of error. */
- return NULL_TREE;
+ return error_mark_node;
if (siter == scope) break;
siter = CP_DECL_CONTEXT (siter);
}
@@ -5063,7 +5434,6 @@ lookup_name_real (name, prefer_type, nonclass, namespaces_only)
register tree val;
int yylex = 0;
tree from_obj = NULL_TREE;
- tree locval, classval;
int flags;
/* Hack: copy flag set by parser, if set. */
@@ -5079,8 +5449,6 @@ lookup_name_real (name, prefer_type, nonclass, namespaces_only)
prefer_type = looking_for_typename;
flags = lookup_flags (prefer_type, namespaces_only);
- /* During parsing, we need to complain. */
- flags |= LOOKUP_COMPLAIN;
/* If the next thing is '<', class templates are types. */
if (looking_for_template)
flags |= LOOKUP_TEMPLATES_EXPECTED;
@@ -5154,112 +5522,98 @@ lookup_name_real (name, prefer_type, nonclass, namespaces_only)
from_obj = val;
}
else
- flags = lookup_flags (prefer_type, namespaces_only);
-
- locval = classval = NULL_TREE;
-
- if (! namespace_bindings_p ())
- locval = qualify_lookup (IDENTIFIER_LOCAL_VALUE (name), flags);
-
- /* In C++ class fields are between local and global scope,
- just before the global scope. */
- if (current_class_type && ! nonclass)
{
- classval = IDENTIFIER_CLASS_VALUE (name);
- if (classval == NULL_TREE && TYPE_BEING_DEFINED (current_class_type))
- /* Try to find values from base classes if we are presently
- defining a type. We are presently only interested in
- TYPE_DECLs. */
- classval = lookup_field (current_class_type, name, 0, 1);
-
- /* Add implicit 'typename' to types from template bases. lookup_field
- will do this for us. If classval is actually from an enclosing
- scope, lookup_nested_field will get it for us. */
- else if (processing_template_decl
- && classval && TREE_CODE (classval) == TYPE_DECL
- && ! currently_open_class (DECL_CONTEXT (classval))
- && uses_template_parms (current_class_type))
- classval = lookup_field (current_class_type, name, 0, 1);
-
- /* yylex() calls this with -2, since we should never start digging for
- the nested name at the point where we haven't even, for example,
- created the COMPONENT_REF or anything like that. */
- if (classval == NULL_TREE)
- classval = lookup_nested_field (name, ! yylex);
-
- classval = qualify_lookup (classval, flags);
+ flags = lookup_flags (prefer_type, namespaces_only);
+ /* If we're not parsing, we need to complain. */
+ flags |= LOOKUP_COMPLAIN;
}
- if (locval && classval)
+ /* First, look in non-namespace scopes. */
+ for (val = IDENTIFIER_BINDING (name); val; val = TREE_CHAIN (val))
{
- if (current_scope () == current_function_decl
- && ! hack_decl_function_context (current_function_decl))
- /* Not in a nested function. */
- val = locval;
- else
+ if (!LOCAL_BINDING_P (val) && nonclass)
+ /* We're not looking for class-scoped bindings, so keep going. */
+ continue;
+
+ /* If this is the kind of thing we're looking for, we're done. */
+ if (qualify_lookup (BINDING_VALUE (val), flags))
{
- /* This is incredibly horrible. The whole concept of
- IDENTIFIER_LOCAL_VALUE / IDENTIFIER_CLASS_VALUE /
- IDENTIFIER_GLOBAL_VALUE needs to be scrapped for local
- classes. */
- tree lctx = hack_decl_function_context (locval);
- tree cctx = hack_decl_function_context (classval);
-
- if (lctx == current_scope ())
- val = locval;
- else if (lctx == cctx)
- val = classval;
- else
- /* I don't know which is right; let's just guess for now. */
- val = locval;
+ val = BINDING_VALUE (val);
+ break;
+ }
+ else if ((flags & LOOKUP_PREFER_TYPES)
+ && qualify_lookup (BINDING_TYPE (val), flags))
+ {
+ val = BINDING_TYPE (val);
+ break;
}
}
- else if (locval)
- val = locval;
- else if (classval)
- val = classval;
- else
- val = unqualified_namespace_lookup (name, flags);
- /* Any other name takes precedence over an implicit typename. Warn the
- user about this potentially confusing lookup. */
- if (classval && TREE_CODE (val) == TYPE_DECL
- && TREE_CODE (TREE_TYPE (val)) == TYPENAME_TYPE
- && TREE_TYPE (TREE_TYPE (val)))
+ /* If VAL is a type from a dependent base, we're not really supposed
+ to be able to see it; the fact that we can is the "implicit
+ typename" extension. We call lookup_field here to turn VAL into
+ a TYPE_DECL for a TYPENAME_TYPE. */
+ if (processing_template_decl && val
+ && val == IDENTIFIER_CLASS_VALUE (name)
+ && TREE_CODE (val) == TYPE_DECL
+ && !currently_open_class (DECL_CONTEXT (val))
+ && uses_template_parms (current_class_type))
+ val = lookup_field (current_class_type, name, 0, 1);
+
+ /* We don't put names from baseclasses onto the IDENTIFIER_BINDING
+ list when we're defining a type. It would probably be simpler to
+ do this, but we don't. So, we must lookup names from base
+ classes explicitly. */
+ if (!val && !nonclass
+ && current_class_type && TYPE_BEING_DEFINED (current_class_type))
+ val = qualify_lookup (lookup_field (current_class_type, name, 0, 0),
+ flags);
+
+ /* The name might be from an enclosing class of the current scope. */
+ if (!val && !nonclass && current_class_type)
+ val = qualify_lookup (lookup_nested_field (name, !yylex), flags);
+
+ /* If we found a type from a dependent base class (using the
+ implicit typename extension) make sure that there's not some
+ global name which should be chosen instead. */
+ if (val && TREE_CODE (val) == TYPE_DECL
+ && IMPLICIT_TYPENAME_P (TREE_TYPE (val)))
{
- if (locval == NULL_TREE)
- locval = unqualified_namespace_lookup (name, flags);
+ tree global_val;
+
+ /* Any other name takes precedence over an implicit typename. Warn the
+ user about this potentially confusing lookup. */
+ global_val = unqualified_namespace_lookup (name, flags);
- if (locval && val != locval)
+ if (global_val)
{
tree subtype;
- val = locval;
-
- /* To avoid redundant warnings, only warn when lexing, and the
- decls are significantly different. */
- subtype = TREE_TYPE (TREE_TYPE (classval));
- if (yylex
- && ! (TREE_CODE (locval) == TEMPLATE_DECL
+ /* Only warn when not lexing; we don't want to warn if they
+ use this name as a declarator. */
+ subtype = TREE_TYPE (TREE_TYPE (val));
+ if (! yylex
+ && ! (TREE_CODE (global_val) == TEMPLATE_DECL
&& CLASSTYPE_TEMPLATE_INFO (subtype)
- && CLASSTYPE_TI_TEMPLATE (subtype) == locval)
- && ! (TREE_CODE (locval) == TYPE_DECL
- && comptypes (TREE_TYPE (locval), subtype, 1)))
+ && CLASSTYPE_TI_TEMPLATE (subtype) == global_val)
+ && ! (TREE_CODE (global_val) == TYPE_DECL
+ && same_type_p (TREE_TYPE (global_val), subtype)))
{
- static int explained;
-
- cp_warning ("lookup of `%D' finds `%#D'", name, locval);
- cp_warning
- (" instead of `%D' from dependent base class", classval);
- if (! explained)
- {
- explained = 1;
- cp_warning (" (use `typename %D' if that's what you meant)",
- classval);
- }
+ cp_warning ("lookup of `%D' finds `%#D'", name, global_val);
+ cp_warning (" instead of `%D' from dependent base class",
+ val);
+ cp_warning (" (use `typename %T::%D' if that's what you meant)",
+ constructor_name (current_class_type), name);
}
+
+ /* Use the global value instead of the implicit typename. */
+ val = global_val;
}
}
+ else if (!val)
+ /* No local, or class-scoped binding. Look for a namespace-scope
+ declaration. */
+ val = unqualified_namespace_lookup (name, flags);
done:
if (val)
@@ -5284,17 +5638,6 @@ lookup_name_real (name, prefer_type, nonclass, namespaces_only)
val = from_obj;
}
- if ((TREE_CODE (val) == TEMPLATE_DECL && looking_for_template)
- || TREE_CODE (val) == TYPE_DECL || prefer_type <= 0)
- ;
- /* Caller wants a class-or-namespace-name. */
- else if (prefer_type == 1 && TREE_CODE (val) == NAMESPACE_DECL)
- ;
- else if (IDENTIFIER_HAS_TYPE_VALUE (name))
- val = TYPE_MAIN_DECL (IDENTIFIER_TYPE_VALUE (name));
- else if (TREE_TYPE (val) == error_mark_node)
- val = error_mark_node;
-
/* If we have a single function from a using decl, pull it out. */
if (TREE_CODE (val) == OVERLOAD && ! really_overloaded_fn (val))
val = OVL_FUNCTION (val);
@@ -5352,13 +5695,16 @@ lookup_name_current_level (name)
if (t != NULL_TREE && TREE_CODE (t) == TREE_LIST)
t = TREE_VALUE (t);
}
- else if (IDENTIFIER_LOCAL_VALUE (name) != NULL_TREE)
+ else if (IDENTIFIER_BINDING (name)
+ && LOCAL_BINDING_P (IDENTIFIER_BINDING (name)))
{
struct binding_level *b = current_binding_level;
+
while (1)
{
- if (purpose_member (name, b->shadowed))
- return IDENTIFIER_LOCAL_VALUE (name);
+ if (BINDING_LEVEL (IDENTIFIER_BINDING (name)) == b)
+ return IDENTIFIER_VALUE (name);
+
if (b->keep == 2)
b = b->level_chain;
else
@@ -5452,7 +5798,7 @@ static int builtin_type_tdescs_len, builtin_type_tdescs_max;
static void
record_builtin_type (rid_index, name, type)
enum rid rid_index;
- char *name;
+ const char *name;
tree type;
{
tree rname = NULL_TREE, tname = NULL_TREE;
@@ -5495,7 +5841,7 @@ record_builtin_type (rid_index, name, type)
static tree
record_builtin_java_type (name, size)
- char *name;
+ const char *name;
int size;
{
tree type, decl;
@@ -5524,7 +5870,7 @@ record_builtin_java_type (name, size)
static void
record_unknown_type (type, name)
tree type;
- char *name;
+ const char *name;
{
tree decl = pushdecl (build_decl (TYPE_DECL, get_identifier (name), type));
/* Make sure the "unknown type" typedecl gets ignored for debug info. */
@@ -5542,7 +5888,7 @@ static void
push_overloaded_decl_1 (x)
tree x;
{
- push_overloaded_decl (x, 0);
+ push_overloaded_decl (x, PUSH_GLOBAL);
}
#ifdef __GNUC__
@@ -5575,6 +5921,8 @@ init_decl_processing ()
tree temp;
tree array_domain_type;
tree vb_off_identifier = NULL_TREE;
+ /* Function type `char *(char *, char *)' and similar ones */
+ tree string_ftype_ptr_ptr, int_ftype_string_string;
tree sizetype_endlink;
tree ptr_ftype, ptr_ftype_unsigned, ptr_ftype_sizetype;
tree void_ftype, void_ftype_int, void_ftype_ptr;
@@ -5594,6 +5942,8 @@ init_decl_processing ()
if (flag_strict_prototype == 2)
flag_strict_prototype = pedantic;
+ if (! flag_permissive && ! pedantic)
+ flag_pedantic_errors = 1;
strict_prototypes_lang_c = flag_strict_prototype;
@@ -5606,7 +5956,6 @@ init_decl_processing ()
current_binding_level = NULL_BINDING_LEVEL;
free_binding_level = NULL_BINDING_LEVEL;
-#ifndef __CYGWIN32__
/* Because most segmentation signals can be traced back into user
code, catch them and at least give the user a chance of working
around compiler bugs. */
@@ -5628,13 +5977,6 @@ init_decl_processing ()
#ifdef SIGBUS
signal (SIGBUS, signal_catch);
#endif
-#else /* ndef __CYGWIN32__ */
- /* Cygwin32 cannot handle catching signals other than
- SIGABRT yet. We hope this will cease to be the case soon. */
-#ifdef SIGABRT
- signal (SIGABRT, signal_catch);
-#endif
-#endif /* ndef __CYGWIN32__ */
gcc_obstack_init (&decl_obstack);
@@ -5682,6 +6024,9 @@ init_decl_processing ()
: make_unsigned_type (CHAR_TYPE_SIZE));
record_builtin_type (RID_CHAR, "char", char_type_node);
+ /* `signed' is the same as `int' */
+ record_builtin_type (RID_SIGNED, NULL_PTR, integer_type_node);
+
long_integer_type_node = make_signed_type (LONG_TYPE_SIZE);
record_builtin_type (RID_LONG, "long int", long_integer_type_node);
@@ -5731,8 +6076,10 @@ init_decl_processing ()
pushdecl (build_decl (TYPE_DECL, NULL_TREE, intSI_type_node));
intDI_type_node = make_signed_type (GET_MODE_BITSIZE (DImode));
pushdecl (build_decl (TYPE_DECL, NULL_TREE, intDI_type_node));
+#if HOST_BITS_PER_WIDE_INT >= 64
intTI_type_node = make_signed_type (GET_MODE_BITSIZE (TImode));
- pushdecl (build_decl (TYPE_DECL, NULL_TREE, intTI_type_node));
+ pushdecl (build_decl (TYPE_DECL, get_identifier ("__int128_t"), intTI_type_node));
+#endif
unsigned_intQI_type_node = make_unsigned_type (GET_MODE_BITSIZE (QImode));
pushdecl (build_decl (TYPE_DECL, NULL_TREE, unsigned_intQI_type_node));
unsigned_intHI_type_node = make_unsigned_type (GET_MODE_BITSIZE (HImode));
@@ -5741,8 +6088,10 @@ init_decl_processing ()
pushdecl (build_decl (TYPE_DECL, NULL_TREE, unsigned_intSI_type_node));
unsigned_intDI_type_node = make_unsigned_type (GET_MODE_BITSIZE (DImode));
pushdecl (build_decl (TYPE_DECL, NULL_TREE, unsigned_intDI_type_node));
+#if HOST_BITS_PER_WIDE_INT >= 64
unsigned_intTI_type_node = make_unsigned_type (GET_MODE_BITSIZE (TImode));
- pushdecl (build_decl (TYPE_DECL, NULL_TREE, unsigned_intTI_type_node));
+ pushdecl (build_decl (TYPE_DECL, get_identifier ("__uint128_t"), unsigned_intTI_type_node));
+#endif
float_type_node = make_node (REAL_TYPE);
TYPE_PRECISION (float_type_node) = FLOAT_TYPE_SIZE;
@@ -5838,7 +6187,8 @@ init_decl_processing ()
string_type_node = build_pointer_type (char_type_node);
const_string_type_node
- = build_pointer_type (build_type_variant (char_type_node, 1, 0));
+ = build_pointer_type (build_qualified_type (char_type_node,
+ TYPE_QUAL_CONST));
#if 0
record_builtin_type (RID_MAX, NULL_PTR, string_type_node);
#endif
@@ -5868,7 +6218,8 @@ init_decl_processing ()
ptr_type_node = build_pointer_type (void_type_node);
const_ptr_type_node
- = build_pointer_type (build_type_variant (void_type_node, 1, 0));
+ = build_pointer_type (build_qualified_type (void_type_node,
+ TYPE_QUAL_CONST));
#if 0
record_builtin_type (RID_MAX, NULL_PTR, ptr_type_node);
#endif
@@ -6197,14 +6548,15 @@ init_decl_processing ()
DECL_SIZE (fields[3]) = TYPE_SIZE (delta_type_node);
TREE_UNSIGNED (fields[3]) = 0;
TREE_CHAIN (fields[2]) = fields[3];
- vtable_entry_type = build_type_variant (vtable_entry_type, 1, 0);
+ vtable_entry_type = build_qualified_type (vtable_entry_type,
+ TYPE_QUAL_CONST);
}
record_builtin_type (RID_MAX, VTBL_PTR_TYPE, vtable_entry_type);
vtbl_type_node
- = build_array_type (vtable_entry_type, NULL_TREE);
+ = build_cplus_array_type (vtable_entry_type, NULL_TREE);
layout_type (vtbl_type_node);
- vtbl_type_node = cp_build_type_variant (vtbl_type_node, 1, 0);
+ vtbl_type_node = build_qualified_type (vtbl_type_node, TYPE_QUAL_CONST);
record_builtin_type (RID_MAX, NULL_PTR, vtbl_type_node);
vtbl_ptr_type_node = build_pointer_type (vtable_entry_type);
layout_type (vtbl_ptr_type_node);
@@ -6243,7 +6595,8 @@ init_decl_processing ()
TREE_UNSIGNED (fields[5]) = 0;
TREE_CHAIN (fields[4]) = fields[5];
- sigtable_entry_type = build_type_variant (sigtable_entry_type, 1, 0);
+ sigtable_entry_type = build_qualified_type (sigtable_entry_type,
+ TYPE_QUAL_CONST);
record_builtin_type (RID_MAX, SIGTABLE_PTR_TYPE, sigtable_entry_type);
}
@@ -6272,7 +6625,8 @@ init_decl_processing ()
(void_ftype_ptr, build_tree_list (NULL_TREE, NULL_TREE));
auto_function (ansi_opname[(int) NEW_EXPR], newtype, NOT_BUILT_IN);
auto_function (ansi_opname[(int) VEC_NEW_EXPR], newtype, NOT_BUILT_IN);
- auto_function (ansi_opname[(int) DELETE_EXPR], deltype, NOT_BUILT_IN);
+ global_delete_fndecl
+ = auto_function (ansi_opname[(int) DELETE_EXPR], deltype, NOT_BUILT_IN);
auto_function (ansi_opname[(int) VEC_DELETE_EXPR], deltype, NOT_BUILT_IN);
}
@@ -6375,11 +6729,11 @@ lang_print_error_function (file)
tree
define_function (name, type, function_code, pfn, library_name)
- char *name;
+ const char *name;
tree type;
enum built_in_function function_code;
void (*pfn) PROTO((tree));
- char *library_name;
+ const char *library_name;
{
tree decl = build_lang_decl (FUNCTION_DECL, get_identifier (name), type);
DECL_EXTERNAL (decl) = 1;
@@ -6426,7 +6780,6 @@ fixup_anonymous_union (t)
TYPE_HAS_INIT_REF (t) = 0;
TYPE_HAS_CONST_INIT_REF (t) = 0;
TYPE_HAS_ASSIGN_REF (t) = 0;
- TYPE_HAS_ASSIGNMENT (t) = 0;
TYPE_HAS_CONST_ASSIGN_REF (t) = 0;
/* Splice the implicitly generated functions out of the TYPE_METHODS
@@ -6446,41 +6799,39 @@ fixup_anonymous_union (t)
error ("an anonymous union cannot have function members");
}
-/* Called when a declaration is seen that contains no names to declare.
- If its type is a reference to a structure, union or enum inherited
- from a containing scope, shadow that tag name for the current scope
- with a forward reference.
- If its type defines a new named structure or union
- or defines an enum, it is valid but we need not do anything here.
- Otherwise, it is an error.
+/* Make sure that a declaration with no declarator is well-formed, i.e.
+ just defines a tagged type or anonymous union.
- C++: may have to grok the declspecs to learn about static,
- complain for anonymous unions. */
+ Returns the type defined, if any. */
-void
-shadow_tag (declspecs)
+tree
+check_tag_decl (declspecs)
tree declspecs;
{
- int found_tag = 0;
+ int found_type = 0;
tree ob_modifier = NULL_TREE;
register tree link;
- register enum tree_code code, ok_code = ERROR_MARK;
register tree t = NULL_TREE;
for (link = declspecs; link; link = TREE_CHAIN (link))
{
register tree value = TREE_VALUE (link);
- code = TREE_CODE (value);
- if (IS_AGGR_TYPE_CODE (code) || code == ENUMERAL_TYPE)
+ if (TYPE_P (value))
{
- my_friendly_assert (TYPE_MAIN_DECL (value) != NULL_TREE, 261);
+ ++found_type;
- maybe_process_partial_specialization (value);
-
- t = value;
- ok_code = code;
- found_tag++;
+ if (IS_AGGR_TYPE (value) || TREE_CODE (value) == ENUMERAL_TYPE)
+ {
+ my_friendly_assert (TYPE_MAIN_DECL (value) != NULL_TREE, 261);
+ t = value;
+ }
+ }
+ else if (value == ridpointers[(int) RID_FRIEND])
+ {
+ if (current_class_type == NULL_TREE
+ || current_scope () != current_class_type)
+ ob_modifier = value;
}
else if (value == ridpointers[(int) RID_STATIC]
|| value == ridpointers[(int) RID_EXTERN]
@@ -6488,21 +6839,75 @@ shadow_tag (declspecs)
|| value == ridpointers[(int) RID_REGISTER]
|| value == ridpointers[(int) RID_INLINE]
|| value == ridpointers[(int) RID_VIRTUAL]
+ || value == ridpointers[(int) RID_CONST]
+ || value == ridpointers[(int) RID_VOLATILE]
|| value == ridpointers[(int) RID_EXPLICIT])
ob_modifier = value;
}
+ if (found_type > 1)
+ error ("multiple types in one declaration");
+
+ /* Inside a class, we might be in a friend or access declaration.
+ Until we have a good way of detecting the latter, don't warn. */
+ if (t == NULL_TREE && ! current_class_type)
+ pedwarn ("declaration does not declare anything");
+
+ /* Check for an anonymous union. We're careful
+ accessing TYPE_IDENTIFIER because some built-in types, like
+ pointer-to-member types, do not have TYPE_NAME. */
+ else if (t && TREE_CODE (t) == UNION_TYPE
+ && TYPE_NAME (t)
+ && ANON_AGGRNAME_P (TYPE_IDENTIFIER (t)))
+ {
+ /* Anonymous unions are objects, so they can have specifiers. */;
+ SET_ANON_UNION_TYPE_P (t);
+ }
+
+ else if (ob_modifier)
+ {
+ if (ob_modifier == ridpointers[(int) RID_INLINE]
+ || ob_modifier == ridpointers[(int) RID_VIRTUAL])
+ cp_error ("`%D' can only be specified for functions", ob_modifier);
+ else if (ob_modifier == ridpointers[(int) RID_FRIEND])
+ cp_error ("`%D' can only be specified inside a class", ob_modifier);
+ else if (ob_modifier == ridpointers[(int) RID_EXPLICIT])
+ cp_error ("`%D' can only be specified for constructors",
+ ob_modifier);
+ else
+ cp_error ("`%D' can only be specified for objects and functions",
+ ob_modifier);
+ }
+
+ return t;
+}
+
+/* Called when a declaration is seen that contains no names to declare.
+ If its type is a reference to a structure, union or enum inherited
+ from a containing scope, shadow that tag name for the current scope
+ with a forward reference.
+ If its type defines a new named structure or union
+ or defines an enum, it is valid but we need not do anything here.
+ Otherwise, it is an error.
+
+ C++: may have to grok the declspecs to learn about static,
+ complain for anonymous unions. */
+
+void
+shadow_tag (declspecs)
+ tree declspecs;
+{
+ tree t = check_tag_decl (declspecs);
+
+ if (t)
+ maybe_process_partial_specialization (t);
+
/* This is where the variables in an anonymous union are
declared. An anonymous union declaration looks like:
union { ... } ;
because there is no declarator after the union, the parser
sends that declaration here. */
- if (ok_code == UNION_TYPE
- && t != NULL_TREE
- && ((TREE_CODE (TYPE_NAME (t)) == IDENTIFIER_NODE
- && ANON_AGGRNAME_P (TYPE_NAME (t)))
- || (TREE_CODE (TYPE_NAME (t)) == TYPE_DECL
- && ANON_AGGRNAME_P (TYPE_IDENTIFIER (t)))))
+ if (t && ANON_UNION_TYPE_P (t))
{
fixup_anonymous_union (t);
@@ -6513,29 +6918,6 @@ shadow_tag (declspecs)
finish_anon_union (decl);
}
}
- else
- {
- /* Anonymous unions are objects, that's why we only check for
- inappropriate specifiers in this branch. */
-
- if (ob_modifier)
- {
- if (ob_modifier == ridpointers[(int) RID_INLINE]
- || ob_modifier == ridpointers[(int) RID_VIRTUAL])
- cp_error ("`%D' can only be specified for functions", ob_modifier);
- else if (ob_modifier == ridpointers[(int) RID_EXPLICIT])
- cp_error ("`%D' can only be specified for constructors",
- ob_modifier);
- else
- cp_error ("`%D' can only be specified for objects and functions",
- ob_modifier);
- }
-
- if (found_tag == 0)
- cp_error ("abstract declarator used as declaration");
- else if (found_tag > 1)
- pedwarn ("multiple types in one declaration");
- }
}
/* Decode a "typename", such as "int **", returning a ..._TYPE node. */
@@ -6602,6 +6984,9 @@ start_decl (declarator, declspecs, initialized, attributes, prefix_attributes)
type = TREE_TYPE (decl);
+ if (type == error_mark_node)
+ return NULL_TREE;
+
/* Don't lose if destructors must be executed at file-level. */
if (! processing_template_decl && TREE_STATIC (decl)
&& TYPE_NEEDS_DESTRUCTOR (complete_type (type))
@@ -6704,6 +7089,8 @@ start_decl (declarator, declspecs, initialized, attributes, prefix_attributes)
if (context && TYPE_SIZE (complete_type (context)) != NULL_TREE)
{
+ pushclass (context, 2);
+
if (TREE_CODE (decl) == VAR_DECL)
{
tree field = lookup_field (context, DECL_NAME (decl), 0, 0);
@@ -6740,13 +7127,21 @@ start_decl (declarator, declspecs, initialized, attributes, prefix_attributes)
DECL_IN_AGGR_P (decl) = 0;
if ((DECL_LANG_SPECIFIC (decl) && DECL_USE_TEMPLATE (decl))
|| CLASSTYPE_USE_TEMPLATE (context))
- SET_DECL_TEMPLATE_SPECIALIZATION (decl);
+ {
+ SET_DECL_TEMPLATE_SPECIALIZATION (decl);
+ /* [temp.expl.spec] An explicit specialization of a static data
+ member of a template is a definition if the declaration
+ includes an initializer; otherwise, it is a declaration.
+
+ We check for processing_specialization so this only applies
+ to the new specialization syntax. */
+ if (DECL_INITIAL (decl) == NULL_TREE && processing_specialization)
+ DECL_EXTERNAL (decl) = 1;
+ }
if (DECL_EXTERNAL (decl) && ! DECL_TEMPLATE_SPECIALIZATION (decl))
cp_pedwarn ("declaration of `%#D' outside of class is not definition",
decl);
-
- pushclass (context, 2);
}
#ifdef SET_DEFAULT_DECL_ATTRIBUTES
@@ -6838,6 +7233,9 @@ start_decl_1 (decl)
tree type = TREE_TYPE (decl);
int initialized = (DECL_INITIAL (decl) != NULL_TREE);
+ if (type == error_mark_node)
+ return;
+
/* If this type of object needs a cleanup, and control may
jump past it, make a new binding level so that it is cleaned
up only when it is initialized first. */
@@ -6852,9 +7250,7 @@ start_decl_1 (decl)
{
/* Don't allow initializations for incomplete types except for
arrays which might be completed by the initialization. */
- if (type == error_mark_node)
- ; /* Don't complain again. */
- else if (TYPE_SIZE (complete_type (type)) != NULL_TREE)
+ if (TYPE_SIZE (complete_type (type)) != NULL_TREE)
; /* A complete type is ok. */
else if (TREE_CODE (type) != ARRAY_TYPE)
{
@@ -6954,10 +7350,6 @@ grok_reference_init (decl, type, init)
return;
}
- if (TREE_TYPE (init) && TREE_CODE (TREE_TYPE (init)) == UNKNOWN_TYPE)
- /* decay_conversion is probably wrong for references to functions. */
- init = decay_conversion (instantiate_type (TREE_TYPE (type), init, 1));
-
if (TREE_CODE (init) == TREE_LIST)
init = build_compound_expr (init);
@@ -7038,6 +7430,25 @@ obscure_complex_init (decl, init)
return init;
}
+/* Issue an error message if DECL is an uninitialized const variable. */
+
+static void
+check_for_uninitialized_const_var (decl)
+ tree decl;
+{
+ tree type = TREE_TYPE (decl);
+
+ /* ``Unless explicitly declared extern, a const object does not have
+ external linkage and must be initialized. ($8.4; $12.1)'' ARM
+ 7.1.6 */
+ if (TREE_CODE (decl) == VAR_DECL
+ && TREE_CODE (type) != REFERENCE_TYPE
+ && CP_TYPE_CONST_P (type)
+ && !TYPE_NEEDS_CONSTRUCTING (type)
+ && !DECL_INITIAL (decl))
+ cp_error ("uninitialized const `%D'", decl);
+}
+
/* Finish processing of a declaration;
install its line number and initial value.
If the length of an array type is not known before,
@@ -7094,6 +7505,12 @@ cp_finish_decl (decl, init, asmspec_tree, need_pop, flags)
init = NULL_TREE;
}
+ if (current_class_type
+ && DECL_REAL_CONTEXT (decl) == current_class_type
+ && TYPE_BEING_DEFINED (current_class_type)
+ && (DECL_INITIAL (decl) || init))
+ DECL_DEFINED_IN_CLASS_P (decl) = 1;
+
if (TREE_CODE (decl) == VAR_DECL
&& DECL_CONTEXT (decl)
&& TREE_CODE (DECL_CONTEXT (decl)) == NAMESPACE_DECL
@@ -7120,6 +7537,9 @@ cp_finish_decl (decl, init, asmspec_tree, need_pop, flags)
return;
}
+ if (TYPE_HAS_MUTABLE_P (type))
+ TREE_READONLY (decl) = 0;
+
if (processing_template_decl)
{
if (init && DECL_INITIAL (decl))
@@ -7238,7 +7658,8 @@ cp_finish_decl (decl, init, asmspec_tree, need_pop, flags)
{
if (TREE_CODE (type) == ARRAY_TYPE)
init = digest_init (type, init, (tree *) 0);
- else if (TREE_CODE (init) == CONSTRUCTOR)
+ else if (TREE_CODE (init) == CONSTRUCTOR
+ && TREE_HAS_CONSTRUCTOR (init))
{
if (TYPE_NON_AGGREGATE_CLASS (type))
{
@@ -7279,32 +7700,16 @@ cp_finish_decl (decl, init, asmspec_tree, need_pop, flags)
decl);
}
- if (TREE_CODE (decl) == VAR_DECL
- && !DECL_INITIAL (decl)
- && !TYPE_NEEDS_CONSTRUCTING (type)
- && (TYPE_READONLY (type) || TREE_READONLY (decl)))
- cp_error ("uninitialized const `%D'", decl);
+ check_for_uninitialized_const_var (decl);
if (TYPE_SIZE (type) != NULL_TREE
&& TYPE_NEEDS_CONSTRUCTING (type))
init = obscure_complex_init (decl, NULL_TREE);
- }
- else if (TREE_CODE (decl) == VAR_DECL
- && TREE_CODE (type) != REFERENCE_TYPE
- && (TYPE_READONLY (type) || TREE_READONLY (decl)))
- {
- /* ``Unless explicitly declared extern, a const object does not have
- external linkage and must be initialized. ($8.4; $12.1)'' ARM 7.1.6
- However, if it's `const int foo = 1; const int foo;', don't complain
- about the second decl, since it does have an initializer before.
- We deliberately don't complain about arrays, because they're
- supposed to be initialized by a constructor. */
- if (! DECL_INITIAL (decl)
- && TREE_CODE (type) != ARRAY_TYPE
- && (!pedantic || !current_class_type))
- cp_error ("uninitialized const `%#D'", decl);
- }
+ }
+ else
+ check_for_uninitialized_const_var (decl);
+
/* For top-level declaration, the initial value was read in
the temporary obstack. MAXINDEX, rtl, etc. to be made below
must go in the permanent obstack; but don't discard the
@@ -7480,31 +7885,9 @@ cp_finish_decl (decl, init, asmspec_tree, need_pop, flags)
else if (TREE_CODE (decl) == VAR_DECL
&& DECL_LANG_SPECIFIC (decl)
&& DECL_COMDAT (decl))
- {
- /* Dynamically initialized vars go into common. */
- if (DECL_INITIAL (decl) == NULL_TREE
- || DECL_INITIAL (decl) == error_mark_node)
- DECL_COMMON (decl) = 1;
- else if (EMPTY_CONSTRUCTOR_P (DECL_INITIAL (decl)))
- {
- DECL_COMMON (decl) = 1;
- DECL_INITIAL (decl) = error_mark_node;
- }
- else
- {
- /* Statically initialized vars are weak or comdat, if
- supported. */
- if (flag_weak)
- make_decl_one_only (decl);
- else
- {
- /* We can't do anything useful; leave vars for explicit
- instantiation. */
- DECL_EXTERNAL (decl) = 1;
- DECL_NOT_REALLY_EXTERN (decl) = 0;
- }
- }
- }
+ /* Set it up again; we might have set DECL_INITIAL since the
+ last time. */
+ comdat_linkage (decl);
if (TREE_CODE (decl) == VAR_DECL && DECL_VIRTUAL_P (decl))
make_decl_rtl (decl, NULL_PTR, toplev);
@@ -7652,7 +8035,8 @@ cp_finish_decl (decl, init, asmspec_tree, need_pop, flags)
if (current_binding_level->is_for_scope)
{
- struct binding_level *outer = current_binding_level->level_chain;
+ struct binding_level *outer
+ = current_binding_level->level_chain;
/* Check to see if the same name is already bound at
the outer level, either because it was directly declared,
@@ -7664,36 +8048,20 @@ cp_finish_decl (decl, init, asmspec_tree, need_pop, flags)
Otherwise, we need to preserve the temp slot for decl
to last into the outer binding level. */
- int handling_dead_for_vars = 0;
- tree link = outer->names;
- for (; ; link = TREE_CHAIN (link))
+ tree outer_binding
+ = TREE_CHAIN (IDENTIFIER_BINDING (DECL_NAME (decl)));
+
+ if (outer_binding && BINDING_LEVEL (outer_binding) == outer
+ && (TREE_CODE (BINDING_VALUE (outer_binding))
+ == VAR_DECL)
+ && DECL_DEAD_FOR_LOCAL (BINDING_VALUE (outer_binding)))
{
- if (link == NULL && handling_dead_for_vars == 0)
- {
- link = outer->dead_vars_from_for;
- handling_dead_for_vars = 1;
- }
- if (link == NULL)
- {
- if (DECL_IN_MEMORY_P (decl))
- preserve_temp_slots (DECL_RTL (decl));
- break;
- }
- if (DECL_NAME (link) == DECL_NAME (decl))
- {
- if (handling_dead_for_vars)
- {
- tree shadowing
- = purpose_member (DECL_NAME (decl),
- current_binding_level->shadowed);
- if (shadowing && TREE_VALUE (shadowing) == link)
- TREE_VALUE (shadowing)
- = DECL_SHADOWED_FOR_VAR (link);
- }
- current_binding_level->is_for_scope = 0;
- break;
- }
+ BINDING_VALUE (outer_binding)
+ = DECL_SHADOWED_FOR_VAR (BINDING_VALUE (outer_binding));
+ current_binding_level->is_for_scope = 0;
}
+ else if (DECL_IN_MEMORY_P (decl))
+ preserve_temp_slots (DECL_RTL (decl));
}
expand_start_target_temps ();
@@ -7815,6 +8183,9 @@ expand_static_init (decl, init)
{
tree oldstatic = value_member (decl, static_aggregates);
+ /* If at_eof is 2, we're too late. */
+ my_friendly_assert (at_eof <= 1, 990323);
+
if (oldstatic)
{
if (TREE_PURPOSE (oldstatic) && init != NULL_TREE)
@@ -7828,14 +8199,39 @@ expand_static_init (decl, init)
/* Remember this information until end of file. */
push_obstacks (&permanent_obstack, &permanent_obstack);
- /* Emit code to perform this initialization but once. */
+ /* Emit code to perform this initialization but once. This code
+ looks like:
+
+ static int temp = 0;
+ if (!temp) {
+ // Do initialization.
+ temp = 1;
+ // Register variable for destruction at end of program.
+ }
+
+ Note that the `temp' variable is only set to 1 *after* the
+ initialization is complete. This ensures that an exception,
+ thrown during the construction, will cause the variable to
+ reinitialized when we pass through this code again, as per:
+
+ [stmt.dcl]
+
+ If the initialization exits by throwing an exception, the
+ initialization is not complete, so it will be tried again
+ the next time control enters the declaration.
+
+ In theory, this process should be thread-safe, too; multiple
+ threads should not be able to initialize the variable more
+ than once. We don't yet attempt to ensure thread-safety. */
temp = get_temp_name (integer_type_node, 1);
rest_of_decl_compilation (temp, NULL_PTR, 0, 0);
+
+ /* Begin the conditional initialization. */
expand_start_cond (build_binary_op (EQ_EXPR, temp,
integer_zero_node, 1), 0);
expand_start_target_temps ();
- expand_assignment (temp, integer_one_node, 0, 0);
+ /* Do the initialization itself. */
if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl))
|| (init && TREE_CODE (init) == TREE_LIST))
{
@@ -7845,9 +8241,17 @@ expand_static_init (decl, init)
else if (init)
expand_assignment (decl, init, 0, 0);
- /* Cleanup any temporaries needed for the initial value. */
+ /* Set TEMP to 1. */
+ expand_assignment (temp, integer_one_node, 0, 0);
+
+ /* Cleanup any temporaries needed for the initial value. If
+ destroying one of the temporaries causes an exception to be
+ thrown, then the object itself has still been fully
+ constructed. */
expand_end_target_temps ();
+ /* Use atexit to register a function for destroying this static
+ variable. */
if (TYPE_NEEDS_DESTRUCTOR (TREE_TYPE (decl)))
{
tree cleanup, fcall;
@@ -7871,14 +8275,19 @@ expand_static_init (decl, init)
build_function_type (void_type_node,
pfvlist),
NOT_BUILT_IN, NULL_PTR);
- assemble_external (atexit_fndecl);
+ mark_used (atexit_fndecl);
Atexit = default_conversion (atexit_fndecl);
pop_lang_context ();
pop_obstacks ();
}
+ /* Call build_cleanup before we enter the anonymous function
+ so that any access checks will be done relative to the
+ current scope, rather than the scope of the anonymous
+ function. */
+ fcall = build_cleanup (decl);
cleanup = start_anon_func ();
- expand_expr_stmt (build_cleanup (decl));
+ expand_expr_stmt (fcall);
end_anon_func ();
mark_addressable (cleanup);
cleanup = build_unary_op (ADDR_EXPR, cleanup, 0);
@@ -7949,6 +8358,8 @@ complete_array_type (type, initial_value, do_default)
/* Make an error message unless that happened already. */
if (initial_value != error_mark_node)
value = 1;
+ else
+ initial_value = NULL_TREE;
/* Prevent further error messages. */
maxindex = build_int_2 (0, 0);
@@ -7996,7 +8407,7 @@ complete_array_type (type, initial_value, do_default)
static int
member_function_or_else (ctype, cur_type, string)
tree ctype, cur_type;
- char *string;
+ const char *string;
{
if (ctype && ctype != cur_type)
{
@@ -8014,7 +8425,7 @@ member_function_or_else (ctype, cur_type, string)
static void
bad_specifiers (object, type, virtualp, quals, inlinep, friendp, raises)
tree object;
- char *type;
+ const char *type;
int virtualp, quals, friendp, raises, inlinep;
{
if (virtualp)
@@ -8042,7 +8453,7 @@ bad_specifiers (object, type, virtualp, quals, inlinep, friendp, raises)
CHECK is 1 if we must find this method in CTYPE, 0 if we should
not look, and -1 if we should not call `grokclassfn' at all.
- Returns `error_mark_node' if something goes wrong, after issuing
+ Returns `NULL_TREE' if something goes wrong, after issuing
applicable error messages. */
static tree
@@ -8078,9 +8489,23 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals,
if (TYPE_VOLATILE (type))
TREE_THIS_VOLATILE (decl) = 1;
- /* This decl is not from the current namespace. */
+ /* If this decl has namespace scope, set that up. */
if (in_namespace)
- set_decl_namespace (decl, in_namespace);
+ set_decl_namespace (decl, in_namespace, friendp);
+ else if (publicp && ! ctype)
+ DECL_CONTEXT (decl) = FROB_CONTEXT (current_namespace);
+
+ /* `main' and builtins have implicit 'C' linkage. */
+ if ((MAIN_NAME_P (declarator)
+ || (IDENTIFIER_LENGTH (declarator) > 10
+ && IDENTIFIER_POINTER (declarator)[0] == '_'
+ && IDENTIFIER_POINTER (declarator)[1] == '_'
+ && strncmp (IDENTIFIER_POINTER (declarator)+2, "builtin_", 8) == 0))
+ && current_lang_name == lang_name_cplusplus
+ && ctype == NULL_TREE
+ /* NULL_TREE means global namespace. */
+ && DECL_CONTEXT (decl) == NULL_TREE)
+ DECL_LANGUAGE (decl) = lang_c;
/* Should probably propagate const out from type to decl I bet (mrs). */
if (staticp)
@@ -8092,8 +8517,10 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals,
if (ctype)
DECL_CLASS_CONTEXT (decl) = ctype;
- if (ctype == NULL_TREE && MAIN_NAME_P (declarator))
+ if (ctype == NULL_TREE && DECL_MAIN_P (decl))
{
+ if (processing_template_decl)
+ error ("cannot declare `main' to be a template");
if (inlinep)
error ("cannot declare `main' to be inline");
else if (! publicp)
@@ -8102,8 +8529,10 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals,
publicp = 1;
}
- /* Members of anonymous types have no linkage; make them internal. */
- if (ctype && ANON_AGGRNAME_P (TYPE_IDENTIFIER (ctype)))
+ /* Members of anonymous types and local classes have no linkage; make
+ them internal. */
+ if (ctype && (ANON_AGGRNAME_P (TYPE_IDENTIFIER (ctype))
+ || hack_decl_function_context (TYPE_MAIN_DECL (ctype))))
publicp = 0;
if (publicp)
@@ -8117,7 +8546,13 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals,
if (t)
{
if (ANON_AGGRNAME_P (TYPE_IDENTIFIER (t)))
- cp_pedwarn ("non-local function `%#D' uses anonymous type", decl);
+ {
+ if (DECL_LANGUAGE (decl) == lang_c)
+ /* Allow this; it's pretty common in C. */;
+ else
+ cp_pedwarn ("non-local function `%#D' uses anonymous type",
+ decl);
+ }
else
cp_pedwarn ("non-local function `%#D' uses local type `%T'",
decl, t);
@@ -8170,7 +8605,7 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals,
/* Something like `template <class T> friend void f<T>()'. */
cp_error ("template-id `%D' in declaration of primary template",
orig_declarator);
- return error_mark_node;
+ return NULL_TREE;
}
/* A friend declaration of the form friend void f<>(). Record
@@ -8183,6 +8618,17 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals,
}
}
+ /* Plain overloading: will not be grok'd by grokclassfn. */
+ if (! ctype && ! processing_template_decl
+ && DECL_LANGUAGE (decl) != lang_c
+ && (! DECL_USE_TEMPLATE (decl) || name_mangling_version < 1))
+ set_mangled_name_for_decl (decl);
+
+ if (funcdef_flag)
+ /* Make the init_value nonzero so pushdecl knows this is not
+ tentative. error_mark_node is replaced later with the BLOCK. */
+ DECL_INITIAL (decl) = error_mark_node;
+
/* Caller will do the rest of this. */
if (check < 0)
return decl;
@@ -8207,7 +8653,7 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals,
2 * (funcdef_flag != 0) +
4 * (friendp != 0));
if (decl == error_mark_node)
- return error_mark_node;
+ return NULL_TREE;
if ((! TYPE_FOR_JAVA (ctype) || check_java_method (decl))
&& check)
@@ -8223,23 +8669,7 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals,
return tmp;
}
if (! grok_ctor_properties (ctype, decl))
- return error_mark_node;
-
- if (check == 0 && ! current_function_decl)
- {
- /* Assembler names live in the global namespace. */
- tmp = IDENTIFIER_GLOBAL_VALUE (DECL_ASSEMBLER_NAME (decl));
- if (tmp == NULL_TREE)
- SET_IDENTIFIER_GLOBAL_VALUE (DECL_ASSEMBLER_NAME (decl), decl);
- else if (TREE_CODE (tmp) != TREE_CODE (decl))
- cp_error ("inconsistent declarations for `%D'", decl);
- else
- {
- duplicate_decls (decl, tmp);
- decl = tmp;
- }
- make_decl_rtl (decl, NULL_PTR, 1);
- }
+ return NULL_TREE;
}
else
{
@@ -8256,7 +8686,7 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals,
2 * (funcdef_flag != 0) +
4 * (friendp != 0));
if (decl == error_mark_node)
- return error_mark_node;
+ return NULL_TREE;
if (ctype != NULL_TREE
&& (! TYPE_FOR_JAVA (ctype) || check_java_method (decl))
@@ -8279,8 +8709,11 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals,
cp_error ("definition of implicitly-declared `%D'", tmp);
if (tmp)
{
+ /* Attempt to merge the declarations. This can fail, in
+ the case of some illegal specialization declarations. */
if (!duplicate_decls (decl, tmp))
- my_friendly_abort (892);
+ cp_error ("no `%#D' member function declared in class `%T'",
+ decl, ctype);
return tmp;
}
}
@@ -8288,37 +8721,11 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals,
if (ctype == NULL_TREE || check)
return decl;
- /* Now install the declaration of this function so that others may
- find it (esp. its DECL_FRIENDLIST). Don't do this for local class
- methods, though. */
- if (! current_function_decl)
- {
- if (!DECL_TEMPLATE_SPECIALIZATION (decl))
- {
- /* We don't do this for specializations since the
- equivalent checks will be done later. Also, at this
- point the DECL_ASSEMBLER_NAME is not yet fully
- accurate. */
-
- /* FIXME: this should only need to look at
- IDENTIFIER_GLOBAL_VALUE. */
- tmp = lookup_name (DECL_ASSEMBLER_NAME (decl), 0);
- if (tmp == NULL_TREE)
- SET_IDENTIFIER_GLOBAL_VALUE (DECL_ASSEMBLER_NAME (decl), decl);
- else if (TREE_CODE (tmp) != TREE_CODE (decl))
- cp_error ("inconsistent declarations for `%D'", decl);
- else
- {
- duplicate_decls (decl, tmp);
- decl = tmp;
- }
- }
+ if (attrlist)
+ cplus_decl_attributes (decl, TREE_PURPOSE (attrlist),
+ TREE_VALUE (attrlist));
+ make_decl_rtl (decl, NULL_PTR, 1);
- if (attrlist)
- cplus_decl_attributes (decl, TREE_PURPOSE (attrlist),
- TREE_VALUE (attrlist));
- make_decl_rtl (decl, NULL_PTR, 1);
- }
if (virtualp)
{
DECL_VIRTUAL_P (decl) = 1;
@@ -8357,16 +8764,27 @@ grokvardecl (type, declarator, specbits_in, initialized, constp, in_namespace)
}
else
{
- tree context = in_namespace ? in_namespace : current_namespace;
+ tree context;
+
+ if (in_namespace)
+ context = in_namespace;
+ else if (namespace_bindings_p () || RIDBIT_SETP (RID_EXTERN, specbits))
+ context = current_namespace;
+ else
+ context = NULL_TREE;
+
decl = build_decl (VAR_DECL, declarator, complete_type (type));
- if (context != global_namespace && namespace_bindings_p ()
- && current_lang_name != lang_name_c)
- DECL_ASSEMBLER_NAME (decl) = build_static_name (context,
- declarator);
+
+ if (context)
+ set_decl_namespace (decl, context, 0);
+
+ context = DECL_CONTEXT (decl);
+ if (declarator && context && current_lang_name != lang_name_c)
+ DECL_ASSEMBLER_NAME (decl) = build_static_name (context, declarator);
}
if (in_namespace)
- set_decl_namespace (decl, in_namespace);
+ set_decl_namespace (decl, in_namespace, 0);
if (RIDBIT_SETP (RID_EXTERN, specbits))
{
@@ -8418,7 +8836,8 @@ grokvardecl (type, declarator, specbits_in, initialized, constp, in_namespace)
return decl;
}
-/* Create a canonical pointer to member function type. */
+/* Create and return a canonical pointer to member function type, for
+ TYPE, which is a POINTER_TYPE to a METHOD_TYPE. */
tree
build_ptrmemfunc_type (type)
@@ -8438,7 +8857,7 @@ build_ptrmemfunc_type (type)
push_obstacks (TYPE_OBSTACK (type), TYPE_OBSTACK (type));
u = make_lang_type (UNION_TYPE);
- IS_AGGR_TYPE (u) = 0;
+ SET_IS_AGGR_TYPE (u, 0);
fields[0] = build_lang_field_decl (FIELD_DECL, pfn_identifier, type);
fields[1] = build_lang_field_decl (FIELD_DECL, delta2_identifier,
delta_type_node);
@@ -8450,7 +8869,7 @@ build_ptrmemfunc_type (type)
/* Let the front-end know this is a pointer to member function... */
TYPE_PTRMEMFUNC_FLAG (t) = 1;
/* ... and not really an aggregate. */
- IS_AGGR_TYPE (t) = 0;
+ SET_IS_AGGR_TYPE (t, 0);
fields[0] = build_lang_field_decl (FIELD_DECL, delta_identifier,
delta_type_node);
@@ -8530,6 +8949,41 @@ build_ptrmemfunc_type (type)
enum return_types { return_normal, return_ctor, return_dtor, return_conversion };
+/* DECL is a VAR_DECL defined in-class, whose TYPE is also given.
+ Check to see that the definition is valid. Issue appropriate error
+ messages. Return 1 if the definition is particularly bad, or 0
+ otherwise. */
+
+int
+check_static_variable_definition (decl, type)
+ tree decl;
+ tree type;
+{
+ /* Motion 10 at San Diego: If a static const integral data member is
+ initialized with an integral constant expression, the initializer
+ may appear either in the declaration (within the class), or in
+ the definition, but not both. If it appears in the class, the
+ member is a member constant. The file-scope definition is always
+ required. */
+ if (CLASS_TYPE_P (type) || TREE_CODE (type) == REFERENCE_TYPE)
+ {
+ cp_error ("in-class initialization of static data member of non-integral type `%T'",
+ type);
+ /* If we just return the declaration, crashes will sometimes
+ occur. We therefore return void_type_node, as if this was a
+ friend declaration, to cause callers to completely ignore
+ this declaration. */
+ return 1;
+ }
+ else if (!CP_TYPE_CONST_P (type))
+ cp_error ("ANSI C++ forbids in-class initialization of non-const static member `%D'",
+ decl);
+ else if (pedantic && !INTEGRAL_TYPE_P (type))
+ cp_pedwarn ("ANSI C++ forbids initialization of member constant `%D' of non-integral type `%T'", decl, type);
+
+ return 0;
+}
+
tree
grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
tree declspecs;
@@ -8544,7 +8998,9 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
tree type = NULL_TREE;
int longlong = 0;
int constp;
+ int restrictp;
int volatilep;
+ int type_quals;
int virtualp, explicitp, friendp, inlinep, staticp;
int explicit_int = 0;
int explicit_char = 0;
@@ -8577,6 +9033,8 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
tree raises = NULL_TREE;
int template_count = 0;
tree in_namespace = NULL_TREE;
+ tree inner_attrs;
+ int ignore_attrs;
RIDBIT_RESET_ALL (specbits);
if (decl_context == FUNCDEF)
@@ -8598,6 +9056,11 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
decl = *next;
switch (TREE_CODE (decl))
{
+ case TREE_LIST:
+ /* For attributes. */
+ next = &TREE_VALUE (decl);
+ break;
+
case COND_EXPR:
ctype = NULL_TREE;
next = &TREE_OPERAND (decl, 0);
@@ -8665,10 +9128,15 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
init = TREE_OPERAND (decl, 1);
decl = start_decl (declarator, declspecs, 1, NULL_TREE, NULL_TREE);
- /* Look for __unused__ attribute */
- if (TREE_USED (TREE_TYPE (decl)))
- TREE_USED (decl) = 1;
- finish_decl (decl, init, NULL_TREE);
+ if (decl)
+ {
+ /* Look for __unused__ attribute */
+ if (TREE_USED (TREE_TYPE (decl)))
+ TREE_USED (decl) = 1;
+ finish_decl (decl, init, NULL_TREE);
+ }
+ else
+ cp_error ("invalid declarator");
return 0;
}
innermost_code = TREE_CODE (decl);
@@ -9045,24 +9513,24 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
}
else
{
- if (funcdef_flag)
- {
- if (warn_return_type
- && return_type == return_normal)
- /* Save warning until we know what is really going on. */
- warn_about_return_type = 1;
- }
- else if (RIDBIT_SETP (RID_TYPEDEF, specbits))
- pedwarn ("ANSI C++ forbids typedef which does not specify a type");
- else if (innermost_code != CALL_EXPR || pedantic
- || (warn_return_type && return_type == return_normal))
- {
- if (innermost_code == CALL_EXPR)
- cp_pedwarn ("return-type of `%D' defaults to `int'", dname);
- else
- cp_pedwarn ("ANSI C++ forbids declaration `%D' with no type",
- dname);
- }
+ /* We handle `main' specially here, because 'main () { }' is so
+ common. With no options, it is allowed. With -Wreturn-type,
+ it is a warning. It is only an error with -pedantic-errors. */
+ int is_main = (funcdef_flag
+ && MAIN_NAME_P (dname)
+ && ctype == NULL_TREE
+ && in_namespace == NULL_TREE
+ && current_namespace == global_namespace);
+
+ if (in_system_header)
+ /* Allow it, sigh. */;
+ else if (pedantic || ! is_main)
+ cp_pedwarn ("ANSI C++ forbids declaration `%D' with no type",
+ dname);
+ else if (warn_return_type)
+ cp_warning ("ANSI C++ forbids declaration `%D' with no type",
+ dname);
+
type = integer_type_node;
}
}
@@ -9078,7 +9546,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
}
else if (return_type == return_conversion)
{
- if (comptypes (type, ctor_return_type, 1) == 0)
+ if (!same_type_p (type, ctor_return_type))
cp_error ("operator `%T' declared to return `%T'",
ctor_return_type, type);
else
@@ -9099,8 +9567,8 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
&& TYPE_MAIN_VARIANT (type) == double_type_node)
{
RIDBIT_RESET (RID_LONG, specbits);
- type = build_type_variant (long_double_type_node, TYPE_READONLY (type),
- TYPE_VOLATILE (type));
+ type = build_qualified_type (long_double_type_node,
+ CP_TYPE_QUALS (type));
}
/* Check all other uses of type modifiers. */
@@ -9222,17 +9690,24 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
if (return_type == return_conversion
&& (RIDBIT_SETP (RID_CONST, specbits)
- || RIDBIT_SETP (RID_VOLATILE, specbits)))
- cp_error ("`operator %T' cannot be cv-qualified",
+ || RIDBIT_SETP (RID_VOLATILE, specbits)
+ || RIDBIT_SETP (RID_RESTRICT, specbits)))
+ cp_error ("qualifiers are not allowed on declaration of `operator %T'",
ctor_return_type);
/* Set CONSTP if this declaration is `const', whether by
explicit specification or via a typedef.
Likewise for VOLATILEP. */
- constp = !! RIDBIT_SETP (RID_CONST, specbits) + TYPE_READONLY (type);
- volatilep = !! RIDBIT_SETP (RID_VOLATILE, specbits) + TYPE_VOLATILE (type);
- type = cp_build_type_variant (type, constp, volatilep);
+ constp = !! RIDBIT_SETP (RID_CONST, specbits) + CP_TYPE_CONST_P (type);
+ restrictp =
+ !! RIDBIT_SETP (RID_RESTRICT, specbits) + CP_TYPE_RESTRICT_P (type);
+ volatilep =
+ !! RIDBIT_SETP (RID_VOLATILE, specbits) + CP_TYPE_VOLATILE_P (type);
+ type_quals = ((constp ? TYPE_QUAL_CONST : 0)
+ | (restrictp ? TYPE_QUAL_RESTRICT : 0)
+ | (volatilep ? TYPE_QUAL_VOLATILE : 0));
+ type = cp_build_qualified_type (type, type_quals);
staticp = 0;
inlinep = !! RIDBIT_SETP (RID_INLINE, specbits);
virtualp = RIDBIT_SETP (RID_VIRTUAL, specbits);
@@ -9252,6 +9727,10 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
friendp = RIDBIT_SETP (RID_FRIEND, specbits);
RIDBIT_RESET (RID_FRIEND, specbits);
+ /* $7.1.2, Function specifiers */
+ if (friendp && explicitp)
+ error ("only declarations of constructors can be `explicit'");
+
if (RIDBIT_SETP (RID_MUTABLE, specbits))
{
if (decl_context == PARM)
@@ -9309,16 +9788,10 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
&& IS_SIGNATURE (current_class_type)
&& RIDBIT_NOTSETP (RID_TYPEDEF, specbits))
{
- if (constp)
- {
- error ("`const' specified for signature member function `%s'", name);
- constp = 0;
- }
- if (volatilep)
+ if (type_quals != TYPE_UNQUALIFIED)
{
- error ("`volatile' specified for signature member function `%s'",
- name);
- volatilep = 0;
+ error ("type qualifiers specified for signature member function `%s'", name);
+ type_quals = TYPE_UNQUALIFIED;
}
if (inlinep)
{
@@ -9405,7 +9878,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
{
/* It's common practice (and completely valid) to have a const
be initialized and declared extern. */
- if (! constp)
+ if (!(type_quals & TYPE_QUAL_CONST))
warning ("`%s' initialized and declared `extern'", name);
}
else
@@ -9427,6 +9900,9 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
Descend through it, creating more complex types, until we reach
the declared identifier (or NULL_TREE, in an absolute declarator). */
+ inner_attrs = NULL_TREE;
+ ignore_attrs = 0;
+
while (declarator && TREE_CODE (declarator) != IDENTIFIER_NODE
&& TREE_CODE (declarator) != TEMPLATE_ID_EXPR)
{
@@ -9473,8 +9949,32 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
quals = NULL_TREE;
}
}
+
+ /* See the comment for the TREE_LIST case, below. */
+ if (ignore_attrs)
+ ignore_attrs = 0;
+ else if (inner_attrs)
+ {
+ decl_attributes (type, inner_attrs, NULL_TREE);
+ inner_attrs = NULL_TREE;
+ }
+
switch (TREE_CODE (declarator))
{
+ case TREE_LIST:
+ {
+ /* We encode a declarator with embedded attributes using
+ a TREE_LIST. The attributes apply to the declarator
+ directly inside them, so we have to skip an iteration
+ before applying them to the type. If the declarator just
+ inside is the declarator-id, we apply the attrs to the
+ decl itself. */
+ inner_attrs = TREE_PURPOSE (declarator);
+ ignore_attrs = 1;
+ declarator = TREE_VALUE (declarator);
+ }
+ break;
+
case ARRAY_REF:
{
register tree itype = NULL_TREE;
@@ -9528,6 +10028,18 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
if (size == error_mark_node)
type = error_mark_node;
+ else if (TREE_CODE (type) == ARRAY_TYPE && !TYPE_DOMAIN (type))
+ {
+ /* [dcl.array]
+
+ the constant expressions that specify the bounds of
+ the arrays can be omitted only for the first member
+ of the sequence. */
+ cp_error ("declaration of `%D' as multidimensional array",
+ dname);
+ cp_error ("must have bounds for all dimensions except the first");
+ type = error_mark_node;
+ }
if (type == error_mark_node)
continue;
@@ -9546,10 +10058,25 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
&& TREE_TYPE (size) == TREE_TYPE (TREE_OPERAND (size, 0)))
size = TREE_OPERAND (size, 0);
- /* If this involves a template parameter, it'll be
- constant, but we don't know what the value is yet. */
+ /* If this involves a template parameter, it will be a
+ constant at instantiation time, but we don't know
+ what the value is yet. Even if no template
+ parameters are involved, we may an expression that
+ is not a constant; we don't even simplify `1 + 2'
+ when processing a template. */
if (processing_template_decl)
{
+ /* Resolve a qualified reference to an enumerator or
+ static const data member of ours. */
+ if (TREE_CODE (size) == SCOPE_REF
+ && TREE_OPERAND (size, 0) == current_class_type)
+ {
+ tree t = lookup_field (current_class_type,
+ TREE_OPERAND (size, 1), 0, 0);
+ if (t)
+ size = t;
+ }
+
itype = make_node (INTEGER_TYPE);
TYPE_MIN_VALUE (itype) = size_zero_node;
TYPE_MAX_VALUE (itype) = build_min
@@ -9558,7 +10085,8 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
}
if (TREE_CODE (TREE_TYPE (size)) != INTEGER_TYPE
- && TREE_CODE (TREE_TYPE (size)) != ENUMERAL_TYPE)
+ && TREE_CODE (TREE_TYPE (size)) != ENUMERAL_TYPE
+ && TREE_CODE (TREE_TYPE (size)) != BOOLEAN_TYPE)
{
cp_error ("size of array `%D' has non-integer type",
dname);
@@ -9641,9 +10169,9 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
/* Declaring a function type.
Make sure we have a valid type for the function to return. */
- /* We now know that constp and volatilep don't apply to the
+ /* We now know that the TYPE_QUALS don't apply to the
decl, but to its return type. */
- constp = volatilep = 0;
+ type_quals = TYPE_UNQUALIFIED;
/* Warn about some types functions can't return. */
@@ -9851,9 +10379,9 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
/* Merge any constancy or volatility into the target type
for the pointer. */
- /* We now know that constp and volatilep don't apply to the
- decl, but to the target of the pointer. */
- constp = volatilep = 0;
+ /* We now know that the TYPE_QUALS don't apply to the decl,
+ but to the target of the pointer. */
+ type_quals = TYPE_UNQUALIFIED;
if (IS_SIGNATURE (type))
{
@@ -9878,8 +10406,6 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
type);
type = build_signature_pointer_type (type);
}
- constp = 0;
- volatilep = 0;
}
else if (TREE_CODE (declarator) == ADDR_EXPR)
{
@@ -9889,9 +10415,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
type = build_reference_type (type);
}
else if (TREE_CODE (type) == METHOD_TYPE)
- {
- type = build_ptrmemfunc_type (build_pointer_type (type));
- }
+ type = build_ptrmemfunc_type (build_pointer_type (type));
else
type = build_pointer_type (type);
@@ -9902,25 +10426,37 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
{
register tree typemodlist;
int erred = 0;
+
+ constp = 0;
+ volatilep = 0;
+ restrictp = 0;
for (typemodlist = TREE_TYPE (declarator); typemodlist;
typemodlist = TREE_CHAIN (typemodlist))
{
- if (TREE_VALUE (typemodlist) == ridpointers[(int) RID_CONST])
+ tree qualifier = TREE_VALUE (typemodlist);
+
+ if (qualifier == ridpointers[(int) RID_CONST])
constp++;
- else if (TREE_VALUE (typemodlist) == ridpointers[(int) RID_VOLATILE])
+ else if (qualifier == ridpointers[(int) RID_VOLATILE])
volatilep++;
+ else if (qualifier == ridpointers[(int) RID_RESTRICT])
+ restrictp++;
else if (!erred)
{
erred = 1;
- error ("invalid type modifier within %s declarator",
- TREE_CODE (declarator) == ADDR_EXPR
- ? "reference" : "pointer");
+ error ("invalid type modifier within pointer declarator");
}
}
if (constp > 1)
pedwarn ("duplicate `const'");
if (volatilep > 1)
pedwarn ("duplicate `volatile'");
+ if (restrictp > 1)
+ pedwarn ("duplicate `restrict'");
+
+ type_quals = ((constp ? TYPE_QUAL_CONST : 0)
+ | (restrictp ? TYPE_QUAL_RESTRICT : 0)
+ | (volatilep ? TYPE_QUAL_VOLATILE : 0));
if (TREE_CODE (declarator) == ADDR_EXPR
&& (constp || volatilep))
{
@@ -9928,9 +10464,9 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
pedwarn ("discarding `const' applied to a reference");
if (volatilep)
pedwarn ("discarding `volatile' applied to a reference");
- constp = volatilep = 0;
+ type_quals &= ~(TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE);
}
- type = cp_build_type_variant (type, constp, volatilep);
+ type = cp_build_qualified_type (type, type_quals);
}
declarator = TREE_OPERAND (declarator, 0);
ctype = NULL_TREE;
@@ -9974,7 +10510,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
&& uses_template_parms (current_class_type))
{
tree args = current_template_args ();
- type = tsubst (type, args, NULL_TREE);
+ type = tsubst (type, args, /*complain=*/1, NULL_TREE);
}
/* This pop_nested_class corresponds to the
@@ -9999,7 +10535,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
ctype = TREE_OPERAND (declarator, 0);
t = ctype;
- while (t != NULL_TREE)
+ while (t != NULL_TREE && CLASS_TYPE_P (t))
{
if (CLASSTYPE_TEMPLATE_INFO (t) &&
!CLASSTYPE_TEMPLATE_SPECIALIZATION (t))
@@ -10115,6 +10651,17 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
}
}
+ /* See the comment for the TREE_LIST case, above. */
+ if (inner_attrs)
+ {
+ if (! ignore_attrs)
+ decl_attributes (type, inner_attrs, NULL_TREE);
+ else if (attrlist)
+ TREE_VALUE (attrlist) = chainon (inner_attrs, TREE_VALUE (attrlist));
+ else
+ attrlist = build_decl_list (NULL_TREE, inner_attrs);
+ }
+
if (explicitp == 1)
{
error ("only constructors can be declared `explicit'");
@@ -10127,7 +10674,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
if (RIDBIT_SETP (RID_MUTABLE, specbits))
{
- if (constp)
+ if (type_quals & TYPE_QUAL_CONST)
{
error ("const `%s' cannot be declared `mutable'", name);
RIDBIT_RESET (RID_MUTABLE, specbits);
@@ -10139,6 +10686,20 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
}
}
+ if (declarator == NULL_TREE
+ || TREE_CODE (declarator) == IDENTIFIER_NODE
+ || (TREE_CODE (declarator) == TEMPLATE_ID_EXPR
+ && (TREE_CODE (type) == FUNCTION_TYPE
+ || TREE_CODE (type) == METHOD_TYPE)))
+ /* OK */;
+ else if (TREE_CODE (declarator) == TEMPLATE_ID_EXPR)
+ {
+ cp_error ("template-id `%D' used as a declarator", declarator);
+ declarator = dname;
+ }
+ else
+ my_friendly_abort (990210);
+
if (RIDBIT_SETP (RID_TYPEDEF, specbits) && decl_context != TYPENAME)
{
tree decl;
@@ -10150,7 +10711,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
if (decl_context == FIELD)
{
- if (declarator == current_class_name)
+ if (declarator == constructor_name (current_class_type))
cp_pedwarn ("ANSI C++ forbids nested type `%D' with same name as enclosing class",
declarator);
decl = build_lang_decl (TYPE_DECL, declarator, type);
@@ -10193,6 +10754,13 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
if (TYPE_LANG_SPECIFIC (type))
TYPE_WAS_ANONYMOUS (type) = 1;
+ /* If this is a typedef within a template class, the nested
+ type is a (non-primary) template. The name for the
+ template needs updating as well. */
+ if (TYPE_LANG_SPECIFIC (type) && CLASSTYPE_TEMPLATE_INFO (type))
+ DECL_NAME (CLASSTYPE_TI_TEMPLATE (type))
+ = TYPE_IDENTIFIER (type);
+
/* XXX Temporarily set the scope.
When returning, start_decl expects it as NULL_TREE,
and will then then set it using pushdecl. */
@@ -10264,19 +10832,20 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
{
/* Note that the grammar rejects storage classes
in typenames, fields or parameters. */
- if (constp || volatilep)
+ if (type_quals != TYPE_UNQUALIFIED)
{
if (IS_SIGNATURE (type))
- error ("`const' or `volatile' specified with signature type");
+ error ("type qualifiers specified for signature type");
+ type_quals = TYPE_UNQUALIFIED;
}
/* Special case: "friend class foo" looks like a TYPENAME context. */
if (friendp)
{
- if (volatilep)
+ if (type_quals != TYPE_UNQUALIFIED)
{
- cp_error ("`volatile' specified for friend class declaration");
- volatilep = 0;
+ cp_error ("type qualifiers specified for friend class declaration");
+ type_quals = TYPE_UNQUALIFIED;
}
if (inlinep)
{
@@ -10356,7 +10925,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
{
/* Transfer const-ness of array into that of type pointed to. */
type = build_pointer_type (TREE_TYPE (type));
- volatilep = constp = 0;
+ type_quals = TYPE_UNQUALIFIED;
}
else if (TREE_CODE (type) == FUNCTION_TYPE)
type = build_pointer_type (type);
@@ -10374,7 +10943,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
if (decl_context == PARM)
{
- decl = build_decl (PARM_DECL, declarator, complete_type (type));
+ decl = build_decl (PARM_DECL, declarator, type);
bad_specifiers (decl, "parameter", virtualp, quals != NULL_TREE,
inlinep, friendp, raises != NULL_TREE);
@@ -10404,7 +10973,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
are error_mark_node, for example. */
decl = NULL_TREE;
}
- else if (in_namespace)
+ else if (in_namespace && !friendp)
{
/* Something like struct S { int N::j; }; */
cp_error ("invalid use of `::'");
@@ -10474,7 +11043,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
virtualp, flags, quals, raises, attrlist,
friendp ? -1 : 0, friendp, publicp, inlinep,
funcdef_flag, template_count, in_namespace);
- if (decl == NULL_TREE || decl == error_mark_node)
+ if (decl == NULL_TREE)
return decl;
#if 0
/* This clobbers the attrs stored in `decl' from `attrlist'. */
@@ -10482,8 +11051,37 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
decl = build_decl_attribute_variant (decl, decl_machine_attr);
#endif
+ /* [class.conv.ctor]
+
+ A constructor declared without the function-specifier
+ explicit that can be called with a single parameter
+ specifies a conversion from the type of its first
+ parameter to the type of its class. Such a constructor
+ is called a converting constructor. */
if (explicitp == 2)
DECL_NONCONVERTING_P (decl) = 1;
+ else if (DECL_CONSTRUCTOR_P (decl))
+ {
+ /* The constructor can be called with exactly one
+ parameter if there is at least one parameter, and
+ any subsequent parameters have default arguments.
+ We don't look at the first parameter, which is
+ really just the `this' parameter for the new
+ object. */
+ tree arg_types =
+ TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (decl)));
+
+ /* Skip the `in_chrg' argument too, if present. */
+ if (TYPE_USES_VIRTUAL_BASECLASSES (DECL_CONTEXT (decl)))
+ arg_types = TREE_CHAIN (arg_types);
+
+ if (arg_types == void_list_node
+ || (arg_types
+ && TREE_CHAIN (arg_types)
+ && TREE_CHAIN (arg_types) != void_list_node
+ && !TREE_PURPOSE (TREE_CHAIN (arg_types))))
+ DECL_NONCONVERTING_P (decl) = 1;
+ }
}
else if (TREE_CODE (type) == METHOD_TYPE)
{
@@ -10582,47 +11180,36 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
the rest of the compiler does not correctly
handle the initialization unless the member is
static so we make it static below. */
- cp_pedwarn ("ANSI C++ forbids initialization of %s `%D'",
- constp ? "const member" : "member",
+ cp_pedwarn ("ANSI C++ forbids initialization of member `%D'",
declarator);
cp_pedwarn ("making `%D' static", declarator);
staticp = 1;
}
- /* Motion 10 at San Diego: If a static const integral data
- member is initialized with an integral constant
- expression, the initializer may appear either in the
- declaration (within the class), or in the definition,
- but not both. If it appears in the class, the member is
- a member constant. The file-scope definition is always
- required. */
- if (CLASS_TYPE_P (type)
- || TREE_CODE (type) == REFERENCE_TYPE)
- {
- cp_error ("in-class initialization of static data member of non-integral type `%T'",
- type);
- /* If we just return the declaration, crashes will
- sometimes occur. We therefore return
- void_type_node, as if this was a friend
- declaration, to cause callers to completely
- ignore this declaration. */
- return void_type_node;
- }
- else if (!constp)
- cp_error ("ANSI C++ forbids in-class initialization of non-const static member `%D'",
- declarator);
- else if (pedantic && ! INTEGRAL_TYPE_P (type)
- && !uses_template_parms (type))
- cp_pedwarn ("ANSI C++ forbids initialization of member constant `%D' of non-integral type `%T'", declarator, type);
+ if (uses_template_parms (type))
+ /* We'll check at instantiation time. */
+ ;
+ else if (check_static_variable_definition (declarator,
+ type))
+ /* If we just return the declaration, crashes
+ will sometimes occur. We therefore return
+ void_type_node, as if this was a friend
+ declaration, to cause callers to completely
+ ignore this declaration. */
+ return void_type_node;
}
+ /* 9.2p13 [class.mem] */
+ if (declarator == constructor_name (current_class_type)
+ /* Divergence from the standard: In extern "C", we
+ allow non-static data members here, because C does
+ and /usr/include/netinet/in.h uses that. */
+ && (staticp || ! in_system_header))
+ cp_pedwarn ("ANSI C++ forbids data member `%D' with same name as enclosing class",
+ declarator);
+
if (staticp)
{
- /* ANSI C++ Apr '95 wp 9.2 */
- if (declarator == current_class_name)
- cp_pedwarn ("ANSI C++ forbids static member `%D' with same name as enclosing class",
- declarator);
-
/* C++ allows static class members.
All other work for this is done by grokfield.
This VAR_DCL is built by build_lang_field_decl.
@@ -10685,18 +11272,6 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
error ("virtual non-class function `%s'", name);
virtualp = 0;
}
-
- if (current_lang_name == lang_name_cplusplus
- && ! processing_template_decl
- && ! MAIN_NAME_P (original_name)
- && ! (IDENTIFIER_LENGTH (original_name) > 10
- && IDENTIFIER_POINTER (original_name)[0] == '_'
- && IDENTIFIER_POINTER (original_name)[1] == '_'
- && strncmp (IDENTIFIER_POINTER (original_name)+2, "builtin_", 8) == 0))
- /* Plain overloading: will not be grok'd by grokclassfn. */
- if (name_mangling_version < 1
- || TREE_CODE (declarator) != TEMPLATE_ID_EXPR)
- declarator = build_decl_overload (dname, TYPE_ARG_TYPES (type), 0);
}
else if (TREE_CODE (type) == FUNCTION_TYPE && staticp < 2)
type = build_cplus_method_type (ctype, TREE_TYPE (type),
@@ -10715,16 +11290,6 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
if (decl == NULL_TREE)
return NULL_TREE;
- /* Among other times, could occur from check_explicit_specialization
- returning an error_mark_node. */
- if (decl == error_mark_node)
- return error_mark_node;
-
- if (ctype == NULL_TREE && DECL_LANGUAGE (decl) != lang_c
- && (! DECL_USE_TEMPLATE (decl) ||
- name_mangling_version < 1))
- DECL_ASSEMBLER_NAME (decl) = declarator;
-
if (staticp == 1)
{
int illegal_static = 0;
@@ -10756,7 +11321,9 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
/* An uninitialized decl with `extern' is a reference. */
decl = grokvardecl (type, declarator, &specbits,
- initialized, constp, in_namespace);
+ initialized,
+ (type_quals & TYPE_QUAL_CONST) != 0,
+ in_namespace);
bad_specifiers (decl, "variable", virtualp, quals != NULL_TREE,
inlinep, friendp, raises != NULL_TREE);
@@ -10801,14 +11368,8 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
DECL_THIS_STATIC (decl) = 1;
/* Record constancy and volatility. */
-
- if (constp)
- TREE_READONLY (decl) = TREE_CODE (type) != REFERENCE_TYPE;
- if (volatilep)
- {
- TREE_SIDE_EFFECTS (decl) = 1;
- TREE_THIS_VOLATILE (decl) = 1;
- }
+ /* FIXME: Disallow `restrict' pointer-to-member declarations. */
+ c_apply_type_quals_to_decl (type_quals, decl);
return decl;
}
@@ -10841,18 +11402,14 @@ parmlist_is_exprlist (exprs)
return 1;
}
-/* Subroutine of `grokparms'. In a fcn definition, arg types must
- be complete.
-
- C++: also subroutine of `start_function'. */
+/* Subroutine of start_function. Ensure that each of the parameter
+ types (as listed in PARMS) is complete, as is required for a
+ function definition. */
static void
require_complete_types_for_parms (parms)
tree parms;
{
- if (processing_template_decl)
- return;
-
while (parms)
{
tree type = TREE_TYPE (parms);
@@ -10865,35 +11422,110 @@ require_complete_types_for_parms (parms)
error ("parameter has incomplete type");
TREE_TYPE (parms) = error_mark_node;
}
-#if 0
- /* If the arg types are incomplete in a declaration,
- they must include undefined tags.
- These tags can never be defined in the scope of the declaration,
- so the types can never be completed,
- and no call can be compiled successfully. */
- /* This is not the right behavior for C++, but not having
- it is also probably wrong. */
else
- {
- /* Now warn if is a pointer to an incomplete type. */
- while (TREE_CODE (type) == POINTER_TYPE
- || TREE_CODE (type) == REFERENCE_TYPE)
- type = TREE_TYPE (type);
- type = TYPE_MAIN_VARIANT (type);
- if (TYPE_SIZE (type) == NULL_TREE)
- {
- if (DECL_NAME (parm) != NULL_TREE)
- warning ("parameter `%s' points to incomplete type",
- IDENTIFIER_POINTER (DECL_NAME (parm)));
- else
- warning ("parameter points to incomplete type");
- }
- }
-#endif
+ layout_decl (parms, 0);
+
parms = TREE_CHAIN (parms);
}
}
+/* Returns DECL if DECL is a local variable (or parameter). Returns
+ NULL_TREE otherwise. */
+
+static tree
+local_variable_p (t)
+ tree t;
+{
+ if ((TREE_CODE (t) == VAR_DECL
+ /* A VAR_DECL with a context that is a _TYPE is a static data
+ member. */
+ && !TYPE_P (CP_DECL_CONTEXT (t))
+ /* Any other non-local variable must be at namespace scope. */
+ && TREE_CODE (CP_DECL_CONTEXT (t)) != NAMESPACE_DECL)
+ || (TREE_CODE (t) == PARM_DECL))
+ return t;
+
+ return NULL_TREE;
+}
+
+/* Check that ARG, which is a default-argument expression for a
+ parameter DECL, is legal. Returns ARG, or ERROR_MARK_NODE, if
+ something goes wrong. DECL may also be a _TYPE node, rather than a
+ DECL, if there is no DECL available. */
+
+tree
+check_default_argument (decl, arg)
+ tree decl;
+ tree arg;
+{
+ tree var;
+ tree decl_type;
+
+ if (TREE_CODE (arg) == DEFAULT_ARG)
+ /* We get a DEFAULT_ARG when looking at an in-class declaration
+ with a default argument. Ignore the argument for now; we'll
+ deal with it after the class is complete. */
+ return arg;
+
+ if (processing_template_decl || uses_template_parms (arg))
+ /* We don't do anything checking until instantiation-time. Note
+ that there may be uninstantiated arguments even for an
+ instantiated function, since default arguments are not
+ instantiated until they are needed. */
+ return arg;
+
+ if (TYPE_P (decl))
+ {
+ decl_type = decl;
+ decl = NULL_TREE;
+ }
+ else
+ decl_type = TREE_TYPE (decl);
+
+ if (arg == error_mark_node
+ || decl == error_mark_node
+ || TREE_TYPE (arg) == error_mark_node
+ || decl_type == error_mark_node)
+ /* Something already went wrong. There's no need to check
+ further. */
+ return error_mark_node;
+
+ /* [dcl.fct.default]
+
+ A default argument expression is implicitly converted to the
+ parameter type. */
+ if (!TREE_TYPE (arg)
+ || !can_convert_arg (decl_type, TREE_TYPE (arg), arg))
+ {
+ if (decl)
+ cp_error ("default argument for `%#D' has type `%T'",
+ decl, TREE_TYPE (arg));
+ else
+ cp_error ("default argument for paramter of type `%T' has type `%T'",
+ decl_type, TREE_TYPE (arg));
+
+ return error_mark_node;
+ }
+
+ /* [dcl.fct.default]
+
+ Local variables shall not be used in default argument
+ expressions.
+
+ The keyword `this' shall not be used in a default argument of a
+ member function. */
+ var = search_tree (arg, local_variable_p);
+ if (var)
+ {
+ cp_error ("default argument `%E' uses local variable `%D'",
+ arg, var);
+ return error_mark_node;
+ }
+
+ /* All is well. */
+ return arg;
+}
+
/* Decode the list of parameter types for a function type.
Given the list of things declared inside the parens,
return a list of types.
@@ -10986,7 +11618,7 @@ grokparms (first_parm, funcdef_flag)
TREE_PURPOSE (decl),
PARM, init != NULL_TREE,
NULL_TREE);
- if (! decl)
+ if (! decl || TREE_TYPE (decl) == error_mark_node)
continue;
/* Top-level qualifiers on the parameters are
@@ -11071,43 +11703,10 @@ grokparms (first_parm, funcdef_flag)
&& TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node))
DECL_ARG_TYPE (decl) = integer_type_node;
#endif
- if (!any_error)
+ if (!any_error && init)
{
- if (init)
- {
- any_init++;
- if (TREE_CODE (init) == SAVE_EXPR)
- PARM_DECL_EXPR (init) = 1;
- else if (processing_template_decl)
- ;
- /* Unparsed default arg from in-class decl. */
- else if (TREE_CODE (init) == DEFAULT_ARG)
- ;
- else if (TREE_CODE (init) == VAR_DECL
- || TREE_CODE (init) == PARM_DECL)
- {
- if (IDENTIFIER_LOCAL_VALUE (DECL_NAME (init)))
- {
- /* ``Local variables may not be used in default
- argument expressions.'' dpANSI C++ 8.2.6 */
- /* If extern int i; within a function is not
- considered a local variable, then this code is
- wrong. */
- cp_error ("local variable `%D' may not be used as a default argument", init);
- any_error = 1;
- }
- else if (TREE_READONLY_DECL_P (init))
- init = decl_constant_value (init);
- }
- else
- init = require_instantiated_type (type, init, integer_zero_node);
- if (! processing_template_decl
- && init != error_mark_node
- && TREE_CODE (init) != DEFAULT_ARG
- && ! can_convert_arg (type, TREE_TYPE (init), init))
- cp_pedwarn ("invalid type `%T' for default argument to `%#D'",
- TREE_TYPE (init), decl);
- }
+ any_init++;
+ init = check_default_argument (decl, init);
}
else
init = NULL_TREE;
@@ -11152,10 +11751,6 @@ grokparms (first_parm, funcdef_flag)
last_function_parms = decls;
- /* In a fcn definition, arg types must be complete. */
- if (funcdef_flag > 0)
- require_complete_types_for_parms (last_function_parms);
-
return result;
}
@@ -11220,19 +11815,45 @@ grok_ctor_properties (ctype, decl)
parmtype = TREE_VALUE (parmtypes);
}
+ /* [class.copy]
+
+ A non-template constructor for class X is a copy constructor if
+ its first parameter is of type X&, const X&, volatile X& or const
+ volatile X&, and either there are no other parameters or else all
+ other parameters have default arguments. */
if (TREE_CODE (parmtype) == REFERENCE_TYPE
&& TYPE_MAIN_VARIANT (TREE_TYPE (parmtype)) == ctype
&& (TREE_CHAIN (parmtypes) == NULL_TREE
|| TREE_CHAIN (parmtypes) == void_list_node
- || TREE_PURPOSE (TREE_CHAIN (parmtypes))))
+ || TREE_PURPOSE (TREE_CHAIN (parmtypes)))
+ && !(DECL_TEMPLATE_INSTANTIATION (decl)
+ && is_member_template (DECL_TI_TEMPLATE (decl))))
{
TYPE_HAS_INIT_REF (ctype) = 1;
- if (TYPE_READONLY (TREE_TYPE (parmtype)))
+ if (CP_TYPE_CONST_P (TREE_TYPE (parmtype)))
TYPE_HAS_CONST_INIT_REF (ctype) = 1;
}
+ /* [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. */
else if (TYPE_MAIN_VARIANT (parmtype) == ctype
- && TREE_CHAIN (parmtypes) != NULL_TREE
- && TREE_CHAIN (parmtypes) == void_list_node)
+ && (TREE_CHAIN (parmtypes) == NULL_TREE
+ || TREE_CHAIN (parmtypes) == void_list_node
+ || TREE_PURPOSE (TREE_CHAIN (parmtypes)))
+ && !(DECL_TEMPLATE_INSTANTIATION (decl)
+ && is_member_template (DECL_TI_TEMPLATE (decl))))
{
cp_error ("invalid constructor; you probably meant `%T (const %T&)'",
ctype, ctype);
@@ -11269,7 +11890,7 @@ unary_op_p (name)
return (name == ansi_opname [(int) TRUTH_NOT_EXPR]
|| name == ansi_opname [(int) BIT_NOT_EXPR]
|| name == ansi_opname [(int) COMPONENT_REF]
- || OPERATOR_TYPENAME_P (name));
+ || IDENTIFIER_TYPENAME_P (name));
}
/* Do a little sanity-checking on how they declared their operator. */
@@ -11288,8 +11909,16 @@ grok_op_properties (decl, virtualp, friendp)
if (! friendp)
{
- if (name == ansi_opname[(int) MODIFY_EXPR])
- TYPE_HAS_ASSIGNMENT (current_class_type) = 1;
+ /* [class.copy]
+
+ A user-declared copy assignment operator X::operator= is a
+ non-static non-template member function of class X with
+ exactly one parameter of type X, X&, const X&, volatile X& or
+ const volatile X&. */
+ if (name == ansi_opname[(int) MODIFY_EXPR]
+ && !(DECL_TEMPLATE_INSTANTIATION (decl)
+ && is_member_template (DECL_TI_TEMPLATE (decl))))
+ ;
else if (name == ansi_opname[(int) CALL_EXPR])
TYPE_OVERLOADS_CALL_EXPR (current_class_type) = 1;
else if (name == ansi_opname[(int) ARRAY_REF])
@@ -11352,7 +11981,7 @@ grok_op_properties (decl, virtualp, friendp)
an enumeration, or a reference to an enumeration. 13.4.0.6 */
if (! methodp || DECL_STATIC_FUNCTION_P (decl))
{
- if (OPERATOR_TYPENAME_P (name)
+ if (IDENTIFIER_TYPENAME_P (name)
|| name == ansi_opname[(int) CALL_EXPR]
|| name == ansi_opname[(int) MODIFY_EXPR]
|| name == ansi_opname[(int) COMPONENT_REF]
@@ -11398,7 +12027,7 @@ grok_op_properties (decl, virtualp, friendp)
else if (! friendp)
{
int ref = (TREE_CODE (t) == REFERENCE_TYPE);
- char *what = 0;
+ const char *what = 0;
if (ref)
t = TYPE_MAIN_VARIANT (TREE_TYPE (t));
@@ -11432,7 +12061,7 @@ grok_op_properties (decl, virtualp, friendp)
{
TYPE_HAS_ASSIGN_REF (current_class_type) = 1;
if (TREE_CODE (parmtype) != REFERENCE_TYPE
- || TYPE_READONLY (TREE_TYPE (parmtype)))
+ || CP_TYPE_CONST_P (TREE_TYPE (parmtype)))
TYPE_HAS_CONST_ASSIGN_REF (current_class_type) = 1;
}
}
@@ -11452,7 +12081,7 @@ grok_op_properties (decl, virtualp, friendp)
if ((name == ansi_opname[(int) POSTINCREMENT_EXPR]
|| name == ansi_opname[(int) POSTDECREMENT_EXPR])
&& ! processing_template_decl
- && TREE_VALUE (TREE_CHAIN (argtypes)) != integer_type_node)
+ && ! same_type_p (TREE_VALUE (TREE_CHAIN (argtypes)), integer_type_node))
{
if (methodp)
cp_error ("postfix `%D' must take `int' as its argument",
@@ -11484,14 +12113,14 @@ grok_op_properties (decl, virtualp, friendp)
if (list_length (argtypes) == 2)
{
if (TREE_CODE (ret) != REFERENCE_TYPE
- || !comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (ret)),
- arg, 1))
+ || !same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (ret)),
+ arg))
cp_warning ("prefix `%D' should return `%T'", decl,
build_reference_type (arg));
}
else
{
- if (!comptypes (TYPE_MAIN_VARIANT (ret), arg, 1))
+ if (!same_type_p (TYPE_MAIN_VARIANT (ret), arg))
cp_warning ("postfix `%D' should return `%T'", decl, arg);
}
}
@@ -11553,6 +12182,27 @@ grok_op_properties (decl, virtualp, friendp)
}
}
+static const char *
+tag_name (code)
+ enum tag_types code;
+{
+ switch (code)
+ {
+ case record_type:
+ return "struct";
+ case class_type:
+ return "class";
+ case union_type:
+ return "union ";
+ case enum_type:
+ return "enum";
+ case signature_type:
+ return "signature";
+ default:
+ my_friendly_abort (981122);
+ }
+}
+
/* Get the struct, enum or union (CODE says which) with tag NAME.
Define the tag as a forward-reference if it is not defined.
@@ -11622,19 +12272,9 @@ xref_tag (code_type_node, name, globalize)
if (! globalize)
{
- if (t && (TREE_CODE (t) == TEMPLATE_TYPE_PARM
- || TREE_CODE (t) == TEMPLATE_TEMPLATE_PARM))
- {
- cp_error ("redeclaration of template type-parameter `%T'", name);
- cp_error_at (" previously declared here `%#D'",
- TEMPLATE_TYPE_DECL (t));
- }
- if (t && TYPE_CONTEXT (t) && got_type)
- ref = t;
- else
- /* If we know we are defining this tag, only look it up in
- this scope and don't try to find it as a type. */
- ref = lookup_tag (code, name, b, 1);
+ /* If we know we are defining this tag, only look it up in
+ this scope and don't try to find it as a type. */
+ ref = lookup_tag (code, name, b, 1);
}
else
{
@@ -11667,7 +12307,12 @@ xref_tag (code_type_node, name, globalize)
else
{
if (t)
- ref = t;
+ {
+ if (t != TYPE_MAIN_VARIANT (t))
+ cp_pedwarn ("using typedef-name `%D' after `%s'",
+ TYPE_NAME (t), tag_name (tag_code));
+ ref = t;
+ }
else
ref = lookup_tag (code, name, b, 0);
@@ -11825,6 +12470,12 @@ xref_tag_from_type (old, id, globalize)
return xref_tag (code_type_node, id, globalize);
}
+/* REF is a type (named NAME), for which we have just seen some
+ baseclasses. BINFO is a list of those baseclasses; the
+ TREE_PURPOSE is an access_* node, and the TREE_VALUE is the type of
+ the base-class. CODE_TYPE_NODE indicates whether REF is a class,
+ struct, or union. */
+
void
xref_basetypes (code_type_node, name, ref, binfo)
tree code_type_node;
@@ -11834,6 +12485,8 @@ xref_basetypes (code_type_node, name, ref, binfo)
/* In the declaration `A : X, Y, ... Z' we mark all the types
(A, X, Y, ..., Z) so we can check for duplicates. */
tree binfos;
+ tree base;
+
int i, len;
enum tag_types tag_code = (enum tag_types) TREE_INT_CST_LOW (code_type_node);
@@ -11846,6 +12499,13 @@ xref_basetypes (code_type_node, name, ref, binfo)
len = list_length (binfo);
push_obstacks (TYPE_OBSTACK (ref), TYPE_OBSTACK (ref));
+ /* First, make sure that any templates in base-classes are
+ instantiated. This ensures that if we call ourselves recursively
+ we do not get confused about which classes are marked and which
+ are not. */
+ for (base = binfo; base; base = TREE_CHAIN (base))
+ complete_type (TREE_VALUE (base));
+
SET_CLASSTYPE_MARKED (ref);
BINFO_BASETYPES (TYPE_BINFO (ref)) = binfos = make_tree_vec (len);
@@ -11884,16 +12544,14 @@ xref_basetypes (code_type_node, name, ref, binfo)
GNU_xref_hier (name, basetype, via_public, via_virtual, 0);
-#if 1
/* This code replaces similar code in layout_basetypes.
We put the complete_type first for implicit `typename'. */
- if (TYPE_SIZE (complete_type (basetype)) == NULL_TREE
+ if (TYPE_SIZE (basetype) == NULL_TREE
&& ! (current_template_parms && uses_template_parms (basetype)))
{
cp_error ("base class `%T' has incomplete type", basetype);
continue;
}
-#endif
else
{
if (CLASSTYPE_MARKED (basetype))
@@ -11917,9 +12575,12 @@ xref_basetypes (code_type_node, name, ref, binfo)
individual inheritance contains flags which say what
the `accessibility' of that particular inheritance is.) */
- base_binfo = make_binfo (integer_zero_node, basetype,
- TYPE_BINFO_VTABLE (basetype),
- TYPE_BINFO_VIRTUALS (basetype));
+ base_binfo
+ = make_binfo (integer_zero_node, basetype,
+ CLASS_TYPE_P (basetype)
+ ? TYPE_BINFO_VTABLE (basetype) : NULL_TREE,
+ CLASS_TYPE_P (basetype)
+ ? TYPE_BINFO_VIRTUALS (basetype) : NULL_TREE);
TREE_VEC_ELT (binfos, i) = base_binfo;
TREE_VIA_PUBLIC (base_binfo) = via_public;
@@ -11941,8 +12602,12 @@ xref_basetypes (code_type_node, name, ref, binfo)
TYPE_USES_COMPLEX_INHERITANCE (ref) = 1;
}
- TYPE_GETS_NEW (ref) |= TYPE_GETS_NEW (basetype);
- TYPE_GETS_DELETE (ref) |= TYPE_GETS_DELETE (basetype);
+ if (CLASS_TYPE_P (basetype))
+ {
+ TYPE_GETS_NEW (ref) |= TYPE_GETS_NEW (basetype);
+ TYPE_GETS_DELETE (ref) |= TYPE_GETS_DELETE (basetype);
+ }
+
i += 1;
}
}
@@ -11954,8 +12619,14 @@ xref_basetypes (code_type_node, name, ref, binfo)
if (i > 1)
TYPE_USES_MULTIPLE_INHERITANCE (ref) = 1;
else if (i == 1)
- TYPE_USES_MULTIPLE_INHERITANCE (ref)
- = TYPE_USES_MULTIPLE_INHERITANCE (BINFO_TYPE (TREE_VEC_ELT (binfos, 0)));
+ {
+ tree basetype = BINFO_TYPE (TREE_VEC_ELT (binfos, 0));
+
+ if (CLASS_TYPE_P (basetype))
+ TYPE_USES_MULTIPLE_INHERITANCE (ref)
+ = TYPE_USES_MULTIPLE_INHERITANCE (basetype);
+ }
+
if (TYPE_USES_MULTIPLE_INHERITANCE (ref))
TYPE_USES_COMPLEX_INHERITANCE (ref) = 1;
@@ -11964,6 +12635,10 @@ xref_basetypes (code_type_node, name, ref, binfo)
CLEAR_CLASSTYPE_MARKED (BINFO_TYPE (TREE_VEC_ELT (binfos, i)));
CLEAR_CLASSTYPE_MARKED (ref);
+ /* Now that we know all the base-classes, set up the list of virtual
+ bases. */
+ CLASSTYPE_VBASECLASSES (ref) = get_vbase_types (ref);
+
pop_obstacks ();
}
@@ -11983,11 +12658,7 @@ start_enum (name)
/* We are wasting space here and putting these on the permanent_obstack so
that typeid(local enum) will work correctly. */
-#if 0
- if (processing_template_decl && current_function_decl)
-#endif
-
- end_temporary_allocation ();
+ push_obstacks (&permanent_obstack, &permanent_obstack);
/* If this is the real definition for a previous forward reference,
fill in the contents in the same object that used to be the
@@ -12089,61 +12760,58 @@ finish_enum (enumtype)
{
tree scope = current_scope ();
if (scope && TREE_CODE (scope) == FUNCTION_DECL)
- {
- add_tree (build_min (TAG_DEFN, enumtype));
- resume_temporary_allocation ();
- }
- return enumtype;
+ add_tree (build_min (TAG_DEFN, enumtype));
}
+ else
+ {
+ int unsignedp = tree_int_cst_sgn (minnode) >= 0;
+ int lowprec = min_precision (minnode, unsignedp);
+ int highprec = min_precision (maxnode, unsignedp);
+ int precision = MAX (lowprec, highprec);
+ tree tem;
- {
- int unsignedp = tree_int_cst_sgn (minnode) >= 0;
- int lowprec = min_precision (minnode, unsignedp);
- int highprec = min_precision (maxnode, unsignedp);
- int precision = MAX (lowprec, highprec);
-
- TYPE_SIZE (enumtype) = NULL_TREE;
-
- /* Set TYPE_MIN_VALUE and TYPE_MAX_VALUE according to `precision'. */
+ TYPE_SIZE (enumtype) = NULL_TREE;
- TYPE_PRECISION (enumtype) = precision;
- if (unsignedp)
- fixup_unsigned_type (enumtype);
- else
- fixup_signed_type (enumtype);
+ /* Set TYPE_MIN_VALUE and TYPE_MAX_VALUE according to `precision'. */
- if (flag_short_enums || (precision > TYPE_PRECISION (integer_type_node)))
- /* Use the width of the narrowest normal C type which is wide enough. */
- TYPE_PRECISION (enumtype) = TYPE_PRECISION (type_for_size
- (precision, 1));
- else
- TYPE_PRECISION (enumtype) = TYPE_PRECISION (integer_type_node);
+ TYPE_PRECISION (enumtype) = precision;
+ if (unsignedp)
+ fixup_unsigned_type (enumtype);
+ else
+ fixup_signed_type (enumtype);
- TYPE_SIZE (enumtype) = 0;
- layout_type (enumtype);
- }
+ if (flag_short_enums || (precision > TYPE_PRECISION (integer_type_node)))
+ /* Use the width of the narrowest normal C type which is wide
+ enough. */
+ TYPE_PRECISION (enumtype) = TYPE_PRECISION (type_for_size
+ (precision, 1));
+ else
+ TYPE_PRECISION (enumtype) = TYPE_PRECISION (integer_type_node);
- {
- register tree tem;
+ TYPE_SIZE (enumtype) = 0;
+ layout_type (enumtype);
- /* Fix up all variant types of this enum type. */
- for (tem = TYPE_MAIN_VARIANT (enumtype); tem;
- tem = TYPE_NEXT_VARIANT (tem))
- {
- TYPE_VALUES (tem) = TYPE_VALUES (enumtype);
- TYPE_MIN_VALUE (tem) = TYPE_MIN_VALUE (enumtype);
- TYPE_MAX_VALUE (tem) = TYPE_MAX_VALUE (enumtype);
- TYPE_SIZE (tem) = TYPE_SIZE (enumtype);
- TYPE_SIZE_UNIT (tem) = TYPE_SIZE_UNIT (enumtype);
- TYPE_MODE (tem) = TYPE_MODE (enumtype);
- TYPE_PRECISION (tem) = TYPE_PRECISION (enumtype);
- TYPE_ALIGN (tem) = TYPE_ALIGN (enumtype);
- TREE_UNSIGNED (tem) = TREE_UNSIGNED (enumtype);
- }
- }
+ /* Fix up all variant types of this enum type. */
+ for (tem = TYPE_MAIN_VARIANT (enumtype); tem;
+ tem = TYPE_NEXT_VARIANT (tem))
+ {
+ TYPE_VALUES (tem) = TYPE_VALUES (enumtype);
+ TYPE_MIN_VALUE (tem) = TYPE_MIN_VALUE (enumtype);
+ TYPE_MAX_VALUE (tem) = TYPE_MAX_VALUE (enumtype);
+ TYPE_SIZE (tem) = TYPE_SIZE (enumtype);
+ TYPE_SIZE_UNIT (tem) = TYPE_SIZE_UNIT (enumtype);
+ TYPE_MODE (tem) = TYPE_MODE (enumtype);
+ TYPE_PRECISION (tem) = TYPE_PRECISION (enumtype);
+ TYPE_ALIGN (tem) = TYPE_ALIGN (enumtype);
+ TREE_UNSIGNED (tem) = TREE_UNSIGNED (enumtype);
+ }
- /* Finish debugging output for this type. */
- rest_of_type_compilation (enumtype, namespace_bindings_p ());
+ /* Finish debugging output for this type. */
+ rest_of_type_compilation (enumtype, namespace_bindings_p ());
+ }
+
+ /* In start_enum we pushed obstacks. Here, we must pop them. */
+ pop_obstacks ();
return enumtype;
}
@@ -12257,6 +12925,15 @@ static int function_depth;
they describe the function's name and the type it returns,
but twisted together in a fashion that parallels the syntax of C.
+ If PRE_PARSED_P is non-zero then DECLARATOR is really the DECL for
+ the function we are about to process; DECLSPECS are ignored. For
+ example, we set PRE_PARSED_P when processing the definition of
+ inline function that was defined in-class; the definition is
+ actually processed when the class is complete. In this case,
+ PRE_PARSED_P is 2. We also set PRE_PARSED_P when instanting the
+ body of a template function, and when constructing thunk functions
+ and such; in these cases PRE_PARSED_P is 1.
+
This function creates a binding context for the function body
as well as setting up the FUNCTION_DECL in current_function_decl.
@@ -12293,7 +12970,6 @@ start_function (declspecs, declarator, attrs, pre_parsed_p)
/* Assume, until we see it does. */
current_function_returns_value = 0;
current_function_returns_null = 0;
- warn_about_return_type = 0;
named_labels = 0;
shadowed_labels = 0;
current_function_assigns_this = 0;
@@ -12358,17 +13034,6 @@ start_function (declspecs, declarator, attrs, pre_parsed_p)
doing_friend = 1;
}
- /* In a fcn definition, arg types must be complete. */
- require_complete_types_for_parms (DECL_ARGUMENTS (decl1));
-
- /* In case some arg types were completed since the declaration was
- parsed, fix up the decls. */
- {
- tree t = DECL_ARGUMENTS (decl1);
- for (; t; t = TREE_CHAIN (t))
- layout_decl (t, 0);
- }
-
last_function_parms = DECL_ARGUMENTS (decl1);
last_function_parm_tags = NULL_TREE;
}
@@ -12382,8 +13047,7 @@ start_function (declspecs, declarator, attrs, pre_parsed_p)
fntype = TREE_TYPE (decl1);
restype = TREE_TYPE (fntype);
- if (IS_AGGR_TYPE (restype) && ! TYPE_PTRMEMFUNC_P (restype)
- && ! CLASSTYPE_GOT_SEMICOLON (restype))
+ if (CLASS_TYPE_P (restype) && !CLASSTYPE_GOT_SEMICOLON (restype))
{
cp_error ("semicolon missing after declaration of `%#T'", restype);
shadow_tag (build_expr_list (NULL_TREE, restype));
@@ -12409,7 +13073,6 @@ start_function (declspecs, declarator, attrs, pre_parsed_p)
pedwarn ("return type for `main' changed to `int'");
TREE_TYPE (decl1) = fntype = default_function_type;
}
- warn_about_return_type = 0;
}
}
@@ -12419,16 +13082,37 @@ start_function (declspecs, declarator, attrs, pre_parsed_p)
&& IDENTIFIER_IMPLICIT_DECL (DECL_NAME (decl1)) != NULL_TREE)
cp_warning_at ("`%D' implicitly declared before its definition", IDENTIFIER_IMPLICIT_DECL (DECL_NAME (decl1)));
+ announce_function (decl1);
+
+ /* Set up current_class_type, and enter the scope of the class, if
+ appropriate. */
+ if (ctype)
+ push_nested_class (ctype, 1);
+ else if (DECL_STATIC_FUNCTION_P (decl1))
+ push_nested_class (DECL_CONTEXT (decl1), 2);
+
+ /* Now that we have entered the scope of the class, we must restore
+ the bindings for any template parameters surrounding DECL1, if it
+ is an inline member template. (Order is important; consider the
+ case where a template parameter has the same name as a field of
+ the class.) It is not until after this point that
+ PROCESSING_TEMPLATE_DECL is guaranteed to be set up correctly. */
+ if (pre_parsed_p == 2)
+ maybe_begin_member_template_processing (decl1);
+
+ /* We are now in the scope of the function being defined. */
current_function_decl = decl1;
+
/* Save the parm names or decls from this function's declarator
where store_parm_decls will find them. */
current_function_parms = last_function_parms;
current_function_parm_tags = last_function_parm_tags;
- announce_function (decl1);
-
if (! processing_template_decl)
{
+ /* In a function definition, arg types must be complete. */
+ require_complete_types_for_parms (current_function_parms);
+
if (TYPE_SIZE (complete_type (TREE_TYPE (fntype))) == NULL_TREE)
{
cp_error ("return-type `%#T' is an incomplete type",
@@ -12449,8 +13133,10 @@ start_function (declspecs, declarator, attrs, pre_parsed_p)
TYPE_ARG_TYPES (TREE_TYPE (decl1)));
DECL_RESULT (decl1)
= build_decl (RESULT_DECL, 0, TYPE_MAIN_VARIANT (TREE_TYPE (fntype)));
- TREE_READONLY (DECL_RESULT (decl1)) = TYPE_READONLY (TREE_TYPE (fntype));
- TREE_THIS_VOLATILE (DECL_RESULT (decl1)) = TYPE_VOLATILE (TREE_TYPE (fntype));
+ TREE_READONLY (DECL_RESULT (decl1))
+ = CP_TYPE_CONST_P (TREE_TYPE (fntype));
+ TREE_THIS_VOLATILE (DECL_RESULT (decl1))
+ = CP_TYPE_VOLATILE_P (TREE_TYPE (fntype));
}
if (TYPE_LANG_SPECIFIC (TREE_TYPE (fntype))
@@ -12458,9 +13144,6 @@ start_function (declspecs, declarator, attrs, pre_parsed_p)
abstract_virtuals_error (decl1, TREE_TYPE (fntype));
}
- if (warn_about_return_type)
- pedwarn ("return-type defaults to `int'");
-
/* Effective C++ rule 15. See also c_expand_return. */
if (warn_ecpp
&& DECL_NAME (decl1) == ansi_opname[(int) MODIFY_EXPR]
@@ -12472,20 +13155,13 @@ start_function (declspecs, declarator, attrs, pre_parsed_p)
DECL_INITIAL (decl1) = error_mark_node;
#ifdef SET_DEFAULT_DECL_ATTRIBUTES
- SET_DEFAULT_DECL_ATTRIBUTES (decl1, attributes);
+ SET_DEFAULT_DECL_ATTRIBUTES (decl1, attrs);
#endif
/* This function exists in static storage.
(This does not mean `static' in the C sense!) */
TREE_STATIC (decl1) = 1;
- /* Set up current_class_type, and enter the scope of the class, if
- appropriate. */
- if (ctype)
- push_nested_class (ctype, 1);
- else if (DECL_STATIC_FUNCTION_P (decl1))
- push_nested_class (DECL_CONTEXT (decl1), 2);
-
/* We must call push_template_decl after current_class_type is set
up. (If we are processing inline definitions after exiting a
class scope, current_class_type will be NULL_TREE until set above
@@ -12532,21 +13208,40 @@ start_function (declspecs, declarator, attrs, pre_parsed_p)
}
/* If this function belongs to an interface, it is public.
If it belongs to someone else's interface, it is also external.
- It doesn't matter whether it's inline or not. */
+ This only affects inlines and template instantiations. */
else if (interface_unknown == 0
&& (! DECL_TEMPLATE_INSTANTIATION (decl1)
|| flag_alt_external_templates))
{
if (DECL_THIS_INLINE (decl1) || DECL_TEMPLATE_INSTANTIATION (decl1)
|| processing_template_decl)
- DECL_EXTERNAL (decl1)
- = (interface_only
- || (DECL_THIS_INLINE (decl1) && ! flag_implement_inlines));
+ {
+ DECL_EXTERNAL (decl1)
+ = (interface_only
+ || (DECL_THIS_INLINE (decl1) && ! flag_implement_inlines));
+
+ /* For WIN32 we also want to put these in linkonce sections. */
+ maybe_make_one_only (decl1);
+ }
else
DECL_EXTERNAL (decl1) = 0;
DECL_NOT_REALLY_EXTERN (decl1) = 0;
DECL_INTERFACE_KNOWN (decl1) = 1;
}
+ else if (interface_unknown && interface_only
+ && (! DECL_TEMPLATE_INSTANTIATION (decl1)
+ || flag_alt_external_templates))
+ {
+ /* If MULTIPLE_SYMBOL_SPACES is defined and we saw a #pragma
+ interface, we will have interface_only set but not
+ interface_known. In that case, we don't want to use the normal
+ heuristics because someone will supply a #pragma implementation
+ elsewhere, and deducing it here would produce a conflict. */
+ comdat_linkage (decl1);
+ DECL_EXTERNAL (decl1) = 0;
+ DECL_INTERFACE_KNOWN (decl1) = 1;
+ DECL_DEFER_OUTPUT (decl1) = 1;
+ }
else
{
/* This is a definition, not a reference.
@@ -12592,13 +13287,24 @@ start_function (declspecs, declarator, attrs, pre_parsed_p)
if (TREE_CODE (TREE_TYPE (t)) == POINTER_TYPE)
{
- int i = suspend_momentary ();
+ int i;
+
+ if (! hack_decl_function_context (decl1))
+ temporary_allocation ();
+ i = suspend_momentary ();
- /* Fool build_indirect_ref. */
+ /* Normally, build_indirect_ref returns
+ current_class_ref whenever current_class_ptr is
+ dereferenced. This time, however, we want it to
+ *create* current_class_ref, so we temporarily clear
+ current_class_ptr to fool it. */
current_class_ptr = NULL_TREE;
current_class_ref = build_indirect_ref (t, NULL_PTR);
current_class_ptr = t;
+
resume_momentary (i);
+ if (! hack_decl_function_context (decl1))
+ end_temporary_allocation ();
}
else
/* We're having a signature pointer here. */
@@ -12607,9 +13313,7 @@ start_function (declspecs, declarator, attrs, pre_parsed_p)
}
}
else
- {
- current_class_ptr = current_class_ref = NULL_TREE;
- }
+ current_class_ptr = current_class_ref = NULL_TREE;
pushlevel (0);
current_binding_level->parm_flag = 1;
@@ -12634,8 +13338,8 @@ start_function (declspecs, declarator, attrs, pre_parsed_p)
{
DECL_RESULT (decl1)
= build_decl (RESULT_DECL, 0, TYPE_MAIN_VARIANT (restype));
- TREE_READONLY (DECL_RESULT (decl1)) = TYPE_READONLY (restype);
- TREE_THIS_VOLATILE (DECL_RESULT (decl1)) = TYPE_VOLATILE (restype);
+ TREE_READONLY (DECL_RESULT (decl1)) = CP_TYPE_CONST_P (restype);
+ TREE_THIS_VOLATILE (DECL_RESULT (decl1)) = CP_TYPE_VOLATILE_P (restype);
}
/* Allocate further tree nodes temporarily during compilation
@@ -12712,9 +13416,6 @@ store_parm_decls ()
/* Initialize RTL machinery. */
init_function_start (fndecl, input_filename, lineno);
- /* Declare __FUNCTION__ and __PRETTY_FUNCTION__ for this function. */
- declare_function_name ();
-
/* Create a binding level for the parms. */
expand_start_bindings (0);
@@ -12800,8 +13501,11 @@ store_parm_decls ()
storedecls (chainon (nonparms, DECL_ARGUMENTS (fndecl)));
+ /* Declare __FUNCTION__ and __PRETTY_FUNCTION__ for this function. */
+ declare_function_name ();
+
/* Initialize the RTL code for the function. */
- DECL_SAVED_INSNS (fndecl) = 0;
+ DECL_SAVED_INSNS (fndecl) = NULL_RTX;
if (! processing_template_decl)
expand_function_start (fndecl, parms_have_cleanups);
@@ -12910,26 +13614,34 @@ store_return_init (return_id, init)
This is called after parsing the body of the function definition.
LINENO is the current line number.
- C++: CALL_POPLEVEL is non-zero if an extra call to poplevel
- (and expand_end_bindings) must be made to take care of the binding
- contour for the base initializers. This is only relevant for
- constructors.
+ FLAGS is a bitwise or of the following values:
+ 1 - CALL_POPLEVEL
+ An extra call to poplevel (and expand_end_bindings) must be
+ made to take care of the binding contour for the base
+ initializers. This is only relevant for constructors.
+ 2 - INCLASS_INLINE
+ We just finished processing the body of an in-class inline
+ function definition. (This processing will have taken place
+ after the class definition is complete.)
NESTED is nonzero if we were in the middle of compiling another function
when we started on this one. */
void
-finish_function (lineno, call_poplevel, nested)
+finish_function (lineno, flags, nested)
int lineno;
- int call_poplevel;
+ int flags;
int nested;
{
register tree fndecl = current_function_decl;
tree fntype, ctype = NULL_TREE;
- rtx tmp_last_parm_insn, insns;
+ rtx last_parm_insn, insns;
/* Label to use if this function is supposed to return a value. */
tree no_return_label = NULL_TREE;
tree decls = NULL_TREE;
+ int call_poplevel = (flags & 1) != 0;
+ int inclass_inline = (flags & 2) != 0;
+ int in_template;
/* When we get some parse errors, we can end up without a
current_function_decl, so cope. */
@@ -13029,7 +13741,8 @@ finish_function (lineno, call_poplevel, nested)
pointer to represent the type of our base class. */
/* This side-effect makes call to `build_delete' generate the
- code we have to have at the end of this destructor. */
+ code we have to have at the end of this destructor.
+ `build_delete' will set the flag again. */
TYPE_HAS_DESTRUCTOR (current_class_type) = 0;
/* These are two cases where we cannot delegate deletion. */
@@ -13088,8 +13801,6 @@ finish_function (lineno, call_poplevel, nested)
expand_end_cond ();
}
- TYPE_HAS_DESTRUCTOR (current_class_type) = 1;
-
virtual_size = c_sizeof (current_class_type);
/* At the end, call delete if that's what's requested. */
@@ -13123,7 +13834,7 @@ finish_function (lineno, call_poplevel, nested)
/* End of destructor. */
expand_end_bindings (NULL_TREE, getdecls () != NULL_TREE, 0);
- poplevel (2, 0, 0); /* XXX change to 1 */
+ poplevel (getdecls () != NULL_TREE, 0, 0);
/* Back to the top of destructor. */
/* Don't execute destructor code if `this' is NULL. */
@@ -13160,13 +13871,13 @@ finish_function (lineno, call_poplevel, nested)
insns = get_insns ();
end_sequence ();
- tmp_last_parm_insn = get_first_nonparm_insn ();
- if (tmp_last_parm_insn == NULL_RTX)
- tmp_last_parm_insn = get_last_insn ();
+ last_parm_insn = get_first_nonparm_insn ();
+ if (last_parm_insn == NULL_RTX)
+ last_parm_insn = get_last_insn ();
else
- tmp_last_parm_insn = previous_insn (tmp_last_parm_insn);
+ last_parm_insn = previous_insn (last_parm_insn);
- emit_insns_after (insns, tmp_last_parm_insn);
+ emit_insns_after (insns, last_parm_insn);
if (! ok_to_optimize_dtor)
expand_end_cond ();
@@ -13336,6 +14047,20 @@ finish_function (lineno, call_poplevel, nested)
/* Generate rtl for function exit. */
expand_function_end (input_filename, lineno, 1);
}
+
+ /* If we're processing a template, squirrel away the definition
+ until we do an instantiation. */
+ if (processing_template_decl)
+ {
+ --minimal_parse_mode;
+ DECL_SAVED_TREE (fndecl) = TREE_CHAIN (DECL_SAVED_TREE (fndecl));
+ /* We have to save this value here in case
+ maybe_end_member_template_processing decides to pop all the
+ template parameters. */
+ in_template = 1;
+ }
+ else
+ in_template = 0;
/* This must come after expand_function_end because cleanups might
have declarations (from inline functions) that need to go into
@@ -13344,6 +14069,13 @@ finish_function (lineno, call_poplevel, nested)
my_friendly_abort (122);
poplevel (1, 0, 1);
+ /* If this is a in-class inline definition, we may have to pop the
+ bindings for the template parameters that we added in
+ maybe_begin_member_template_processing when start_function was
+ called. */
+ if (inclass_inline)
+ maybe_end_member_template_processing ();
+
/* Reset scope for C++: if we were in the scope of a class,
then when we finish this function, we are not longer so.
This cannot be done until we know for sure that no more
@@ -13362,7 +14094,7 @@ finish_function (lineno, call_poplevel, nested)
to the FUNCTION_DECL node itself. */
BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl;
- if (! processing_template_decl)
+ if (!in_template)
{
int saved_flag_keep_inline_functions =
flag_keep_inline_functions;
@@ -13446,16 +14178,10 @@ finish_function (lineno, call_poplevel, nested)
/* Free all the tree nodes making up this function. */
/* Switch back to allocating nodes permanently
until we start another function. */
- if (processing_template_decl)
- {
- --minimal_parse_mode;
- DECL_SAVED_TREE (fndecl) = TREE_CHAIN (DECL_SAVED_TREE (fndecl));
- }
-
if (! nested)
permanent_allocation (1);
- if (DECL_SAVED_INSNS (fndecl) == 0)
+ if (DECL_SAVED_INSNS (fndecl) == NULL_RTX)
{
tree t;
@@ -13486,8 +14212,6 @@ finish_function (lineno, call_poplevel, nested)
}
/* Create the FUNCTION_DECL for a function definition.
- LINE1 is the line number that the definition absolutely begins on.
- LINE2 is the line number that the name of the function appears on.
DECLSPECS and DECLARATOR are the parts of the declaration;
they describe the return type and the name of the function,
but twisted together in a fashion that parallels the syntax of C.
@@ -13509,11 +14233,11 @@ finish_function (lineno, call_poplevel, nested)
CHANGES TO CODE IN `grokfield'. */
tree
-start_method (declspecs, declarator)
- tree declarator, declspecs;
+start_method (declspecs, declarator, attrlist)
+ tree declarator, declspecs, attrlist;
{
tree fndecl = grokdeclarator (declarator, declspecs, MEMFUNCDEF, 0,
- NULL_TREE);
+ attrlist);
/* Something too ugly to handle. */
if (fndecl == NULL_TREE)
@@ -13542,6 +14266,8 @@ start_method (declspecs, declarator)
return void_type_node;
}
+ check_template_shadow (fndecl);
+
DECL_THIS_INLINE (fndecl) = 1;
if (flag_default_inline)
@@ -13623,23 +14349,11 @@ finish_method (decl)
for (link = current_binding_level->names; link; link = TREE_CHAIN (link))
{
if (DECL_NAME (link) != NULL_TREE)
- IDENTIFIER_LOCAL_VALUE (DECL_NAME (link)) = 0;
+ pop_binding (DECL_NAME (link), link);
my_friendly_assert (TREE_CODE (link) != FUNCTION_DECL, 163);
DECL_CONTEXT (link) = NULL_TREE;
}
- /* Restore all name-meanings of the outer levels
- that were shadowed by this level. */
-
- for (link = current_binding_level->shadowed; link; link = TREE_CHAIN (link))
- IDENTIFIER_LOCAL_VALUE (TREE_PURPOSE (link)) = TREE_VALUE (link);
- for (link = current_binding_level->class_shadowed;
- link; link = TREE_CHAIN (link))
- IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (link)) = TREE_VALUE (link);
- for (link = current_binding_level->type_shadowed;
- link; link = TREE_CHAIN (link))
- SET_IDENTIFIER_TYPE_VALUE (TREE_PURPOSE (link), TREE_VALUE (link));
-
GNU_xref_end_scope ((HOST_WIDE_INT) current_binding_level,
(HOST_WIDE_INT) current_binding_level->level_chain,
current_binding_level->parm_flag,
@@ -13720,7 +14434,7 @@ maybe_build_cleanup_1 (decl, auto_delete)
tree decl, auto_delete;
{
tree type = TREE_TYPE (decl);
- if (TYPE_NEEDS_DESTRUCTOR (type))
+ if (type != error_mark_node && TYPE_NEEDS_DESTRUCTOR (type))
{
int temp = 0, flags = LOOKUP_NORMAL|LOOKUP_DESTRUCTOR;
tree rval;
@@ -13797,38 +14511,30 @@ cplus_expand_expr_stmt (exp)
/* Arrange for all temps to disappear. */
expand_start_target_temps ();
- if (TREE_TYPE (exp) == unknown_type_node)
+ exp = require_complete_type_in_void (exp);
+
+ if (TREE_CODE (exp) == FUNCTION_DECL)
{
- if (TREE_CODE (exp) == ADDR_EXPR || TREE_CODE (exp) == TREE_LIST)
- error ("address of overloaded function with no contextual type information");
- else if (TREE_CODE (exp) == COMPONENT_REF)
- warning ("useless reference to a member function name, did you forget the ()?");
+ cp_warning ("reference, not call, to function `%D'", exp);
+ warning ("at this point in file");
}
- else
- {
- if (TREE_CODE (exp) == FUNCTION_DECL)
- {
- cp_warning ("reference, not call, to function `%D'", exp);
- warning ("at this point in file");
- }
#if 0
- /* We should do this eventually, but right now this causes regex.o from
- libg++ to miscompile, and tString to core dump. */
- exp = build1 (CLEANUP_POINT_EXPR, TREE_TYPE (exp), exp);
+ /* We should do this eventually, but right now this causes regex.o from
+ libg++ to miscompile, and tString to core dump. */
+ exp = build1 (CLEANUP_POINT_EXPR, TREE_TYPE (exp), exp);
#endif
- /* Strip unused implicit INDIRECT_REFs of references. */
- if (TREE_CODE (exp) == INDIRECT_REF
- && TREE_CODE (TREE_TYPE (TREE_OPERAND (exp, 0))) == REFERENCE_TYPE)
- exp = TREE_OPERAND (exp, 0);
+ /* Strip unused implicit INDIRECT_REFs of references. */
+ if (TREE_CODE (exp) == INDIRECT_REF
+ && TREE_CODE (TREE_TYPE (TREE_OPERAND (exp, 0))) == REFERENCE_TYPE)
+ exp = TREE_OPERAND (exp, 0);
- /* If we don't do this, we end up down inside expand_expr
- trying to do TYPE_MODE on the ERROR_MARK, and really
- go outside the bounds of the type. */
- if (exp != error_mark_node)
- expand_expr_stmt (break_out_cleanups (exp));
- }
+ /* If we don't do this, we end up down inside expand_expr
+ trying to do TYPE_MODE on the ERROR_MARK, and really
+ go outside the bounds of the type. */
+ if (exp != error_mark_node)
+ expand_expr_stmt (break_out_cleanups (exp));
/* Clean up any pending cleanups. This happens when a function call
returns a cleanup-needing value that nobody uses. */
@@ -13874,15 +14580,14 @@ revert_static_member_fn (decl, fn, argtypes)
tree function = fn ? *fn : TREE_TYPE (*decl);
tree args = argtypes ? *argtypes : TYPE_ARG_TYPES (function);
- if (TYPE_READONLY (TREE_TYPE (TREE_VALUE (args))))
- cp_error ("static member function `%#D' declared const", *decl);
- if (TYPE_VOLATILE (TREE_TYPE (TREE_VALUE (args))))
- cp_error ("static member function `%#D' declared volatile", *decl);
+ if (CP_TYPE_QUALS (TREE_TYPE (TREE_VALUE (args)))
+ != TYPE_UNQUALIFIED)
+ cp_error ("static member function `%#D' declared with type qualifiers",
+ *decl);
args = TREE_CHAIN (args);
tmp = build_function_type (TREE_TYPE (function), args);
- tmp = build_type_variant (tmp, TYPE_READONLY (function),
- TYPE_VOLATILE (function));
+ tmp = build_qualified_type (tmp, CP_TYPE_QUALS (function));
tmp = build_exception_variant (tmp,
TYPE_RAISES_EXCEPTIONS (function));
TREE_TYPE (*decl) = tmp;
@@ -13906,12 +14611,12 @@ struct language_function
{
int returns_value;
int returns_null;
- int warn_about_return_type;
int assigns_this;
int just_assigned_this;
int parms_stored;
int temp_name_counter;
tree named_labels;
+ struct named_label_list *named_label_uses;
tree shadowed_labels;
tree ctor_label;
tree dtor_label;
@@ -13941,10 +14646,10 @@ push_cp_function_context (f)
f->language = p;
p->named_labels = named_labels;
+ p->named_label_uses = named_label_uses;
p->shadowed_labels = shadowed_labels;
p->returns_value = current_function_returns_value;
p->returns_null = current_function_returns_null;
- p->warn_about_return_type = warn_about_return_type;
p->binding_level = current_binding_level;
p->ctor_label = ctor_label;
p->dtor_label = dtor_label;
@@ -13979,10 +14684,10 @@ pop_cp_function_context (f)
TREE_VALUE (link));
named_labels = p->named_labels;
+ named_label_uses = p->named_label_uses;
shadowed_labels = p->shadowed_labels;
current_function_returns_value = p->returns_value;
current_function_returns_null = p->returns_null;
- warn_about_return_type = p->warn_about_return_type;
current_binding_level = p->binding_level;
ctor_label = p->ctor_label;
dtor_label = p->dtor_label;
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index 01d0420ebe5..82b4d45e0ed 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -1,5 +1,5 @@
/* Process declarations and variables for C compiler.
- Copyright (C) 1988, 92, 93, 94, 95, 1996 Free Software Foundation, Inc.
+ Copyright (C) 1988, 92-98, 1999 Free Software Foundation, Inc.
Hacked by Michael Tiemann (tiemann@cygnus.com)
This file is part of GNU CC.
@@ -46,8 +46,6 @@ Boston, MA 02111-1307, USA. */
#if USE_CPPLIB
#include "cpplib.h"
extern cpp_reader parse_in;
-extern cpp_options parse_options;
-static int cpp_initialized;
#endif
static tree get_sentry PROTO((tree));
@@ -60,7 +58,18 @@ static int is_namespace_ancestor PROTO((tree, tree));
static void add_using_namespace PROTO((tree, tree, int));
static tree ambiguous_decl PROTO((tree, tree, tree,int));
static tree build_anon_union_vars PROTO((tree, tree*, int, int));
-static void check_decl_namespace PROTO((void));
+static int acceptable_java_type PROTO((tree));
+static void output_vtable_inherit PROTO((tree));
+static void setup_initp PROTO((void));
+static void start_objects PROTO((int, int));
+static void finish_objects PROTO((int, int));
+static void do_dtors PROTO((tree));
+static void do_ctors PROTO((tree));
+static tree merge_functions PROTO((tree, tree));
+static tree decl_namespace PROTO((tree));
+static tree validate_nonmember_using_decl PROTO((tree, tree *, tree *));
+static void do_nonmember_using_decl PROTO((tree, tree, tree, tree,
+ tree *, tree *));
extern int current_class_depth;
@@ -144,10 +153,6 @@ int flag_traditional;
int flag_signed_bitfields = 1;
-/* Nonzero means handle `#ident' directives. 0 means ignore them. */
-
-int flag_no_ident;
-
/* Nonzero means enable obscure ANSI features and disable GNU extensions
that might cause ANSI-compliant code to be miscompiled. */
@@ -179,14 +184,6 @@ int flag_implicit_templates = 1;
int flag_implicit_inline_templates = 1;
-/* Nonzero means allow numerical priorities on constructors. */
-
-#ifdef USE_INIT_PRIORITY
-int flag_init_priority = 1;
-#else
-int flag_init_priority;
-#endif
-
/* Nonzero means warn about implicit declarations. */
int warn_implicit = 1;
@@ -445,14 +442,21 @@ int flag_do_squangling;
int flag_vtable_gc;
+/* Nonzero means make the default pedwarns warnings instead of errors.
+ The value of this flag is ignored if -pedantic is specified. */
+
+int flag_permissive;
+
/* Table of language-dependent -f options.
STRING is the option name. VARIABLE is the address of the variable.
ON_VALUE is the value to store in VARIABLE
if `-fSTRING' is seen as an option.
(If `-fno-STRING' is seen as an option, the opposite value is stored.) */
-static struct { char *string; int *variable; int on_value;} lang_f_options[] =
+static struct { const char *string; int *variable; int on_value;}
+lang_f_options[] =
{
+ /* C/C++ options. */
{"signed-char", &flag_signed_char, 1},
{"unsigned-char", &flag_signed_char, 0},
{"signed-bitfields", &flag_signed_bitfields, 1},
@@ -460,41 +464,42 @@ static struct { char *string; int *variable; int on_value;} lang_f_options[] =
{"short-enums", &flag_short_enums, 1},
{"short-double", &flag_short_double, 1},
{"cond-mismatch", &flag_cond_mismatch, 1},
- {"squangle", &flag_do_squangling, 1},
{"asm", &flag_no_asm, 0},
{"builtin", &flag_no_builtin, 0},
- {"ident", &flag_no_ident, 0},
- {"labels-ok", &flag_labels_ok, 1},
+
+ /* C++-only options. */
+ {"access-control", &flag_access_control, 1},
+ {"check-new", &flag_check_new, 1},
+ {"conserve-space", &flag_conserve_space, 1},
{"const-strings", &flag_const_strings, 1},
- {"stats", &flag_detailed_statistics, 1},
- {"this-is-variable", &flag_this_is_variable, 1},
- {"strict-prototype", &flag_strict_prototype, 1},
+ {"default-inline", &flag_default_inline, 1},
+ {"dollars-in-identifiers", &dollars_in_ident, 1},
{"elide-constructors", &flag_elide_constructors, 1},
+ {"external-templates", &flag_external_templates, 1},
+ {"for-scope", &flag_new_for_scope, 2},
+ {"gnu-keywords", &flag_no_gnu_keywords, 0},
{"handle-exceptions", &flag_exceptions, 1},
{"handle-signatures", &flag_handle_signatures, 1},
- {"default-inline", &flag_default_inline, 1},
- {"dollars-in-identifiers", &dollars_in_ident, 1},
{"honor-std", &flag_honor_std, 1},
- {"rtti", &flag_rtti, 1},
- {"xref", &flag_gnu_xref, 1},
+ {"huge-objects", &flag_huge_objects, 1},
{"implement-inlines", &flag_implement_inlines, 1},
- {"external-templates", &flag_external_templates, 1},
- {"implicit-templates", &flag_implicit_templates, 1},
{"implicit-inline-templates", &flag_implicit_inline_templates, 1},
- {"init-priority", &flag_init_priority, 1},
- {"huge-objects", &flag_huge_objects, 1},
- {"conserve-space", &flag_conserve_space, 1},
- {"vtable-gc", &flag_vtable_gc, 1},
- {"vtable-thunks", &flag_vtable_thunks, 1},
- {"access-control", &flag_access_control, 1},
+ {"implicit-templates", &flag_implicit_templates, 1},
+ {"labels-ok", &flag_labels_ok, 1},
{"nonansi-builtins", &flag_no_nonansi_builtin, 0},
- {"gnu-keywords", &flag_no_gnu_keywords, 0},
{"operator-names", &flag_operator_names, 1},
{"optional-diags", &flag_optional_diags, 1},
- {"check-new", &flag_check_new, 1},
+ {"permissive", &flag_permissive, 1},
{"repo", &flag_use_repository, 1},
- {"for-scope", &flag_new_for_scope, 2},
- {"weak", &flag_weak, 1}
+ {"rtti", &flag_rtti, 1},
+ {"squangle", &flag_do_squangling, 1},
+ {"stats", &flag_detailed_statistics, 1},
+ {"strict-prototype", &flag_strict_prototype, 1},
+ {"this-is-variable", &flag_this_is_variable, 1},
+ {"vtable-gc", &flag_vtable_gc, 1},
+ {"vtable-thunks", &flag_vtable_thunks, 1},
+ {"weak", &flag_weak, 1},
+ {"xref", &flag_gnu_xref, 1}
};
/* Decode the string P as a language-specific option.
@@ -514,13 +519,6 @@ lang_decode_option (argc, argv)
int strings_processed;
char *p = argv[0];
#if USE_CPPLIB
- if (! cpp_initialized)
- {
- cpp_reader_init (&parse_in);
- parse_in.data = &parse_options;
- cpp_options_init (&parse_options);
- cpp_initialized = 1;
- }
strings_processed = cpp_handle_option (&parse_in, argc, argv);
#else
strings_processed = 0;
@@ -606,35 +604,13 @@ lang_decode_option (argc, argv)
}
else if (!strncmp (p, "template-depth-", 15))
{
- char *endp = p + 15;
- while (*endp)
- {
- if (*endp >= '0' && *endp <= '9')
- endp++;
- else
- {
- error ("Invalid option `%s'", p - 2);
- goto template_depth_lose;
- }
- }
- max_tinst_depth = atoi (p + 15);
- template_depth_lose: ;
+ max_tinst_depth =
+ read_integral_parameter (p + 15, p - 2, max_tinst_depth);
}
else if (!strncmp (p, "name-mangling-version-", 22))
{
- char *endp = p + 22;
- while (*endp)
- {
- if (*endp >= '0' && *endp <= '9')
- endp++;
- else
- {
- error ("Invalid option `%s'", p - 2);
- goto mangling_version_lose;
- }
- }
- name_mangling_version = atoi (p + 22);
- mangling_version_lose: ;
+ name_mangling_version =
+ read_integral_parameter (p + 22, p - 2, name_mangling_version);
}
else for (j = 0;
!found && j < sizeof (lang_f_options) / sizeof (lang_f_options[0]);
@@ -784,36 +760,27 @@ grok_method_quals (ctype, function, quals)
{
tree fntype = TREE_TYPE (function);
tree raises = TYPE_RAISES_EXCEPTIONS (fntype);
+ int type_quals = TYPE_UNQUALIFIED;
+ int dup_quals = TYPE_UNQUALIFIED;
do
{
- extern tree ridpointers[];
-
- if (TREE_VALUE (quals) == ridpointers[(int)RID_CONST])
- {
- if (TYPE_READONLY (ctype))
- error ("duplicate `%s' %s",
- IDENTIFIER_POINTER (TREE_VALUE (quals)),
- (TREE_CODE (function) == FUNCTION_DECL
- ? "for member function" : "in type declaration"));
- ctype = build_type_variant (ctype, 1, TYPE_VOLATILE (ctype));
- build_pointer_type (ctype);
- }
- else if (TREE_VALUE (quals) == ridpointers[(int)RID_VOLATILE])
- {
- if (TYPE_VOLATILE (ctype))
- error ("duplicate `%s' %s",
- IDENTIFIER_POINTER (TREE_VALUE (quals)),
- (TREE_CODE (function) == FUNCTION_DECL
- ? "for member function" : "in type declaration"));
- ctype = build_type_variant (ctype, TYPE_READONLY (ctype), 1);
- build_pointer_type (ctype);
- }
+ int tq = cp_type_qual_from_rid (TREE_VALUE (quals));
+
+ if (type_quals & tq)
+ dup_quals |= tq;
else
- my_friendly_abort (20);
+ type_quals |= tq;
quals = TREE_CHAIN (quals);
- }
+ }
while (quals);
+
+ if (dup_quals != TYPE_UNQUALIFIED)
+ cp_error ("duplicate type qualifiers in %s declaration",
+ TREE_CODE (function) == FUNCTION_DECL
+ ? "member function" : "type");
+
+ ctype = cp_build_qualified_type (ctype, type_quals);
fntype = build_cplus_method_type (ctype, TREE_TYPE (fntype),
(TREE_CODE (fntype) == METHOD_TYPE
? TREE_CHAIN (TYPE_ARG_TYPES (fntype))
@@ -867,17 +834,14 @@ grok_x_components (specs)
struct pending_inline **p;
tree t;
- t = groktypename (build_decl_list (strip_attrs (specs), NULL_TREE));
-
- if (t == NULL_TREE)
- {
- cp_error ("invalid member declaration");
- return;
- }
+ specs = strip_attrs (specs);
+
+ check_tag_decl (specs);
+ t = groktypename (build_decl_list (specs, NULL_TREE));
/* The only case where we need to do anything additional here is an
anonymous union field, e.g.: `struct S { union { int i; }; };'. */
- if (!ANON_UNION_TYPE_P (t))
+ if (t == NULL_TREE || !ANON_UNION_TYPE_P (t))
return;
fixup_anonymous_union (t);
@@ -1046,7 +1010,7 @@ grok_alignof (expr)
return build_min (ALIGNOF_EXPR, sizetype, expr);
if (TREE_CODE (expr) == COMPONENT_REF
- && DECL_BIT_FIELD (TREE_OPERAND (expr, 1)))
+ && DECL_C_BIT_FIELD (TREE_OPERAND (expr, 1)))
error ("`__alignof__' applied to a bit-field");
if (TREE_CODE (expr) == INDIRECT_REF)
@@ -1220,7 +1184,7 @@ delete_sanity (exp, size, doing_vec, use_global_delete)
if (doing_vec)
return build_vec_delete (t, maxindex, integer_one_node,
- integer_two_node, use_global_delete);
+ integer_zero_node, use_global_delete);
else
{
if (IS_AGGR_TYPE (TREE_TYPE (type))
@@ -1283,7 +1247,7 @@ check_member_template (tmpl)
/* Return true iff TYPE is a valid Java parameter or return type. */
-int
+static int
acceptable_java_type (type)
tree type;
{
@@ -1358,8 +1322,21 @@ check_classfn (ctype, function)
tree method_vec = CLASSTYPE_METHOD_VEC (complete_type (ctype));
tree *methods = 0;
tree *end = 0;
- tree templates = NULL_TREE;
-
+
+ if (DECL_USE_TEMPLATE (function)
+ && is_member_template (DECL_TI_TEMPLATE (function)))
+ /* Since this is a specialization of a member template,
+ we're not going to find the declaration in the class.
+ For example, in:
+
+ struct S { template <typename T> void f(T); };
+ template <> void S::f(int);
+
+ we're not going to find `S::f(int)', but there's no
+ reason we should, either. We let our callers know we didn't
+ find the method, but we don't complain. */
+ return NULL_TREE;
+
if (method_vec != 0)
{
methods = &TREE_VEC_ELT (method_vec, 0);
@@ -1383,14 +1360,19 @@ check_classfn (ctype, function)
fndecls = OVL_NEXT (fndecls))
{
fndecl = OVL_CURRENT (fndecls);
- /* The DECL_ASSEMBLER_NAME for a TEMPLATE_DECL is
+ /* The DECL_ASSEMBLER_NAME for a TEMPLATE_DECL, or
+ for a for member function of a template class, is
not mangled, so the check below does not work
- correctly in that case. Since mangled destructor names
- do not include the type of the arguments, we
- can't use this short-cut for them, either. */
- if (TREE_CODE (function) != TEMPLATE_DECL
- && TREE_CODE (fndecl) != TEMPLATE_DECL
- && !DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (function))
+ correctly in that case. Since mangled destructor
+ names do not include the type of the arguments,
+ we can't use this short-cut for them, either.
+ (It's not legal to declare arguments for a
+ destructor, but some people try.) */
+ if (!DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (function))
+ && (DECL_ASSEMBLER_NAME (function)
+ != DECL_NAME (function))
+ && (DECL_ASSEMBLER_NAME (fndecl)
+ != DECL_NAME (fndecl))
&& (DECL_ASSEMBLER_NAME (function)
== DECL_ASSEMBLER_NAME (fndecl)))
return fndecl;
@@ -1410,45 +1392,22 @@ check_classfn (ctype, function)
&& TREE_CODE (TREE_TYPE (function)) == METHOD_TYPE)
p1 = TREE_CHAIN (p1);
- if (comptypes (TREE_TYPE (TREE_TYPE (function)),
- TREE_TYPE (TREE_TYPE (fndecl)), 1)
- && compparms (p1, p2, 3)
+ if (same_type_p (TREE_TYPE (TREE_TYPE (function)),
+ TREE_TYPE (TREE_TYPE (fndecl)))
+ && compparms (p1, p2)
&& (DECL_TEMPLATE_SPECIALIZATION (function)
== DECL_TEMPLATE_SPECIALIZATION (fndecl))
&& (!DECL_TEMPLATE_SPECIALIZATION (function)
|| (DECL_TI_TEMPLATE (function)
== DECL_TI_TEMPLATE (fndecl))))
return fndecl;
-
- if (is_member_template (fndecl))
- /* This function might be an instantiation
- or specialization of fndecl. */
- templates =
- scratch_tree_cons (NULL_TREE, fndecl, templates);
}
}
break; /* loser */
}
- else if (TREE_CODE (fndecl) == TEMPLATE_DECL
- && IDENTIFIER_TYPENAME_P (DECL_NAME (fndecl))
- && IDENTIFIER_TYPENAME_P (fn_name))
- /* The method in the class is a member template
- conversion operator. We are declaring another
- conversion operator. It is possible that even though
- the names don't match, there is some specialization
- occurring. */
- templates =
- scratch_tree_cons (NULL_TREE, fndecl, templates);
}
}
- if (templates)
- /* This function might be an instantiation or a specialization.
- We should verify that this is possible. For now, we simply
- return NULL_TREE, which lets the caller know that this function
- is new, but we don't print an error message. */
- return NULL_TREE;
-
if (methods != end && *methods)
{
tree fndecl = *methods;
@@ -1462,13 +1421,19 @@ check_classfn (ctype, function)
else
{
methods = 0;
- cp_error ("no `%#D' member function declared in class `%T'",
- function, ctype);
+ if (TYPE_SIZE (ctype) == 0)
+ incomplete_type_error (function, ctype);
+ else
+ cp_error ("no `%#D' member function declared in class `%T'",
+ function, ctype);
}
/* If we did not find the method in the class, add it to avoid
- spurious errors. */
- add_method (ctype, methods, function);
+ spurious errors (unless the CTYPE is not yet defined, in which
+ case we'll only confuse ourselves when the function is declared
+ properly within the class. */
+ if (TYPE_SIZE (ctype))
+ add_method (ctype, methods, function);
return NULL_TREE;
}
@@ -1573,8 +1538,8 @@ grokfield (declarator, declspecs, init, asmspec_tree, attrlist)
if (DECL_IN_AGGR_P (value))
{
- cp_error ("`%D' is already defined in the class %T", value,
- DECL_CONTEXT (value));
+ cp_error ("`%D' is already defined in `%T'", value,
+ DECL_CONTEXT (value));
return void_type_node;
}
@@ -1646,18 +1611,7 @@ grokfield (declarator, declspecs, init, asmspec_tree, attrlist)
&& (TREE_CODE (value) == VAR_DECL || TREE_CODE (value) == FUNCTION_DECL))
value = push_template_decl (value);
- /* Check to see if a field redeclares a template parameter. */
- if (current_template_parms
- && TREE_CODE (declarator) == IDENTIFIER_NODE
- && IDENTIFIER_LOCAL_VALUE (declarator))
- {
- tree olddecl = IDENTIFIER_LOCAL_VALUE (declarator);
- if (decl_template_parm_p (olddecl))
- {
- cp_error ("redeclaration of template parameter `%T'", declarator);
- cp_error_at (" previously declared here `%#D'", olddecl);
- }
- }
+ check_template_shadow (value);
if (attrlist)
cplus_decl_attributes (value, TREE_PURPOSE (attrlist),
@@ -1694,7 +1648,7 @@ grokfield (declarator, declspecs, init, asmspec_tree, attrlist)
}
/* Force the compiler to know when an uninitialized static
const member is being used. */
- if (TYPE_READONLY (value) && init == 0)
+ if (CP_TYPE_CONST_P (TREE_TYPE (value)) && init == 0)
TREE_USED (value) = 1;
DECL_INITIAL (value) = init;
DECL_IN_AGGR_P (value) = 1;
@@ -1809,7 +1763,7 @@ grokbitfield (declarator, declspecs, width)
{
constant_expression_warning (width);
DECL_INITIAL (value) = width;
- DECL_BIT_FIELD (value) = 1;
+ SET_DECL_C_BIT_FIELD (value);
}
DECL_IN_AGGR_P (value) = 1;
@@ -2126,7 +2080,7 @@ get_temp_regvar (type, init)
returns a VAR_DECL whose size is the same as the size of the
ANON_DECL, if one is available. */
-tree
+static tree
build_anon_union_vars (anon_decl, elems, static_p, external_p)
tree anon_decl;
tree* elems;
@@ -2142,8 +2096,15 @@ build_anon_union_vars (anon_decl, elems, static_p, external_p)
field = TREE_CHAIN (field))
{
tree decl;
- if (TREE_CODE (field) != FIELD_DECL)
+
+ if (DECL_ARTIFICIAL (field))
continue;
+ if (TREE_CODE (field) != FIELD_DECL)
+ {
+ cp_pedwarn_at ("`%#D' invalid; an anonymous union can only have non-static data members",
+ field);
+ continue;
+ }
if (TREE_PRIVATE (field))
cp_pedwarn_at ("private member `%#D' in anonymous union", field);
@@ -2254,7 +2215,7 @@ finish_anon_union (anon_union_decl)
void
finish_builtin_type (type, name, fields, len, align_type)
tree type;
- char *name;
+ const char *name;
tree fields[];
int len;
tree align_type;
@@ -2293,15 +2254,14 @@ coerce_new_type (type)
if (TREE_CODE (type) == METHOD_TYPE)
type = build_function_type (TREE_TYPE (type), TREE_CHAIN (TYPE_ARG_TYPES (type)));
- if (TREE_TYPE (type) != ptr_type_node)
+ if (! same_type_p (TREE_TYPE (type), ptr_type_node))
e1 = 1, error ("`operator new' must return type `void *'");
/* Technically the type must be `size_t', but we may not know
what that is. */
if (TYPE_ARG_TYPES (type) == NULL_TREE)
e1 = 1, error ("`operator new' takes type `size_t' parameter");
- else if (TREE_CODE (TREE_VALUE (TYPE_ARG_TYPES (type))) != INTEGER_TYPE
- || TYPE_PRECISION (TREE_VALUE (TYPE_ARG_TYPES (type))) != TYPE_PRECISION (sizetype))
+ else if (! same_type_p (TREE_VALUE (TYPE_ARG_TYPES (type)), sizetype))
e2 = 1, error ("`operator new' takes type `size_t' as first parameter");
if (e2)
type = build_function_type (ptr_type_node, tree_cons (NULL_TREE, sizetype, TREE_CHAIN (TYPE_ARG_TYPES (type))));
@@ -2330,7 +2290,7 @@ coerce_delete_type (type)
e1 = 1, error ("`operator delete' must return type `void'");
if (arg_types == NULL_TREE
- || TREE_VALUE (arg_types) != ptr_type_node)
+ || ! same_type_p (TREE_VALUE (arg_types), ptr_type_node))
e2 = 1, error ("`operator delete' takes type `void *' as first parameter");
#if 0
@@ -2341,8 +2301,7 @@ coerce_delete_type (type)
/* Again, technically this argument must be `size_t', but again
we may not know what that is. */
tree t2 = TREE_VALUE (TREE_CHAIN (arg_types));
- if (TREE_CODE (t2) != INTEGER_TYPE
- || TYPE_PRECISION (t2) != TYPE_PRECISION (sizetype))
+ if (! same_type_p (t2, sizetype))
e3 = 1, error ("second argument to `operator delete' must be of type `size_t'");
else if (TREE_CHAIN (TREE_CHAIN (arg_types)) != void_list_node)
{
@@ -2422,8 +2381,30 @@ comdat_linkage (decl)
{
if (flag_weak)
make_decl_one_only (decl);
- else
+ else if (TREE_CODE (decl) == FUNCTION_DECL || DECL_VIRTUAL_P (decl))
+ /* We can just emit functions and vtables statically; it doesn't really
+ matter if we have multiple copies. */
TREE_PUBLIC (decl) = 0;
+ else
+ {
+ /* Static data member template instantiations, however, cannot
+ have multiple copies. */
+ if (DECL_INITIAL (decl) == 0
+ || DECL_INITIAL (decl) == error_mark_node)
+ DECL_COMMON (decl) = 1;
+ else if (EMPTY_CONSTRUCTOR_P (DECL_INITIAL (decl)))
+ {
+ DECL_COMMON (decl) = 1;
+ DECL_INITIAL (decl) = error_mark_node;
+ }
+ else
+ {
+ /* We can't do anything useful; leave vars for explicit
+ instantiation. */
+ DECL_EXTERNAL (decl) = 1;
+ DECL_NOT_REALLY_EXTERN (decl) = 0;
+ }
+ }
if (DECL_LANG_SPECIFIC (decl))
DECL_COMDAT (decl) = 1;
@@ -2443,14 +2424,14 @@ maybe_make_one_only (decl)
return;
/* We can't set DECL_COMDAT on functions, or finish_file will think
- we can get away with not emitting them if they aren't used.
- We can't use make_decl_one_only for variables, because their
- DECL_INITIAL may not have been set properly yet. */
+ we can get away with not emitting them if they aren't used. We need
+ to for variables so that cp_finish_decl will update their linkage,
+ because their DECL_INITIAL may not have been set properly yet. */
- if (TREE_CODE (decl) == FUNCTION_DECL)
- make_decl_one_only (decl);
- else
- comdat_linkage (decl);
+ make_decl_one_only (decl);
+
+ if (TREE_CODE (decl) == VAR_DECL && DECL_LANG_SPECIFIC (decl))
+ DECL_COMDAT (decl) = 1;
}
/* Set TREE_PUBLIC and/or DECL_EXTERN on the vtable DECL,
@@ -2478,10 +2459,6 @@ import_export_vtable (decl, type, final)
TREE_PUBLIC (decl) = 1;
DECL_EXTERNAL (decl) = ! CLASSTYPE_VTABLE_NEEDS_WRITING (type);
DECL_INTERFACE_KNOWN (decl) = 1;
-
- /* Always make vtables weak. */
- if (flag_weak)
- comdat_linkage (decl);
}
else
{
@@ -2490,7 +2467,6 @@ import_export_vtable (decl, type, final)
int found = CLASSTYPE_TEMPLATE_INSTANTIATION (type);
-#ifndef MULTIPLE_SYMBOL_SPACES
if (! found && ! final)
{
tree method;
@@ -2504,7 +2480,6 @@ import_export_vtable (decl, type, final)
break;
}
}
-#endif
if (final || ! found)
{
@@ -2532,6 +2507,14 @@ import_export_class (ctype)
if (CLASSTYPE_INTERFACE_KNOWN (ctype))
return;
+ /* If MULTIPLE_SYMBOL_SPACES is defined and we saw a #pragma interface,
+ we will have CLASSTYPE_INTERFACE_ONLY set but not
+ CLASSTYPE_INTERFACE_KNOWN. In that case, we don't want to use this
+ heuristic because someone will supply a #pragma implementation
+ elsewhere, and deducing it here would produce a conflict. */
+ if (CLASSTYPE_INTERFACE_ONLY (ctype))
+ return;
+
#ifdef VALID_MACHINE_TYPE_ATTRIBUTE
/* FIXME this should really use some sort of target-independent macro. */
if (lookup_attribute ("dllimport", TYPE_ATTRIBUTES (ctype)))
@@ -2547,7 +2530,6 @@ import_export_class (ctype)
&& ! flag_implicit_templates)
import_export = -1;
-#ifndef MULTIPLE_SYMBOL_SPACES
/* Base our import/export status on that of the first non-inline,
non-abstract virtual function, if any. */
if (import_export == 0
@@ -2567,6 +2549,10 @@ import_export_class (ctype)
}
}
}
+
+#ifdef MULTIPLE_SYMBOL_SPACES
+ if (import_export == -1)
+ import_export = 0;
#endif
if (import_export)
@@ -2577,16 +2563,6 @@ import_export_class (ctype)
}
}
-int
-finish_prevtable_vardecl (prev, vars)
- tree prev ATTRIBUTE_UNUSED, vars;
-{
- tree ctype = DECL_CONTEXT (vars);
- import_export_class (ctype);
- import_export_vtable (vars, ctype, 1);
- return 1;
-}
-
/* We need to describe to the assembler the relationship between
a vtable and the vtable of the parent class. */
@@ -2618,6 +2594,10 @@ static int
finish_vtable_vardecl (prev, vars)
tree prev, vars;
{
+ tree ctype = DECL_CONTEXT (vars);
+ import_export_class (ctype);
+ import_export_vtable (vars, ctype, 1);
+
if (! DECL_EXTERNAL (vars)
&& (DECL_INTERFACE_KNOWN (vars)
|| TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (vars))
@@ -2655,6 +2635,10 @@ finish_vtable_vardecl (prev, vars)
DECL_IGNORED_P (vars) = 1;
}
+ /* Always make vtables weak. */
+ if (flag_weak)
+ comdat_linkage (vars);
+
rest_of_decl_compilation (vars, NULL_PTR, 1, 1);
if (flag_vtable_gc)
@@ -2779,10 +2763,8 @@ import_export_decl (decl)
/* Templates are allowed to have internal linkage. See
[basic.link]. */
;
- else if (TREE_CODE (decl) == FUNCTION_DECL)
- comdat_linkage (decl);
else
- DECL_COMDAT (decl) = 1;
+ comdat_linkage (decl);
}
else
DECL_NOT_REALLY_EXTERN (decl) = 0;
@@ -2790,6 +2772,7 @@ import_export_decl (decl)
else if (DECL_FUNCTION_MEMBER_P (decl))
{
tree ctype = DECL_CLASS_CONTEXT (decl);
+ import_export_class (ctype);
if (CLASSTYPE_INTERFACE_KNOWN (ctype)
&& (! DECL_ARTIFICIAL (decl) || DECL_VINDEX (decl)))
{
@@ -2800,6 +2783,8 @@ import_export_decl (decl)
/* Always make artificials weak. */
if (DECL_ARTIFICIAL (decl) && flag_weak)
comdat_linkage (decl);
+ else
+ maybe_make_one_only (decl);
}
else
comdat_linkage (decl);
@@ -2808,6 +2793,10 @@ import_export_decl (decl)
else if (DECL_ARTIFICIAL (decl) && DECL_MUTABLE_P (decl))
{
tree ctype = TREE_TYPE (DECL_NAME (decl));
+
+ if (IS_AGGR_TYPE (ctype))
+ import_export_class (ctype);
+
if (IS_AGGR_TYPE (ctype) && CLASSTYPE_INTERFACE_KNOWN (ctype)
&& TYPE_VIRTUAL_P (ctype)
/* If the type is a cv-qualified variant of a type, then we
@@ -2901,18 +2890,13 @@ static void
setup_initp ()
{
tree t, *p, next_t;
-
- if (! flag_init_priority)
- {
- for (t = static_aggregates_initp; t; t = TREE_CHAIN (t))
- cp_warning ("init_priority for `%#D' ignored without -finit-priority",
- TREE_VALUE (t));
- return;
- }
+ tree default_pri = build_int_2 (DEFAULT_INIT_PRIORITY, 0);
+ int saw_default;
/* First, remove any entries from static_aggregates that are also in
- static_aggregates_initp, and update the entries in _initp to
- include the initializer. */
+ static_aggregates_initp, and update the entries in _initp to include
+ the initializer. For entries not in static_aggregates_initp, update
+ them in place to look the same way. */
p = &static_aggregates;
for (; *p; )
{
@@ -2920,22 +2904,40 @@ setup_initp ()
if (t)
{
+ /* We found an entry in s_a_initp; replace that entry with the
+ format we want and remove the entry in s_a. */
TREE_VALUE (t) = *p;
*p = TREE_CHAIN (*p);
TREE_CHAIN (TREE_VALUE (t)) = NULL_TREE;
}
else
- p = &TREE_CHAIN (*p);
+ {
+ /* We didn't find an entry in s_a_i; replace the entry in s_a
+ with the format we want. */
+ *p = perm_tree_cons (default_pri, *p, TREE_CHAIN (*p));
+ TREE_CHAIN (TREE_VALUE (*p)) = NULL_TREE;
+ p = &TREE_CHAIN (*p);
+ }
}
+ /* And then attach the two lists. By doing it this way, ctors with an
+ explicit priority equal to the default are run before ctors with no
+ explicit priority (i.e. the ones in s_a). */
+ static_aggregates_initp = chainon (static_aggregates,
+ static_aggregates_initp);
+ static_aggregates = NULL_TREE;
+
/* Then, group static_aggregates_initp. After this step, there will only
be one entry for each priority, with a chain coming off it. */
t = static_aggregates_initp;
static_aggregates_initp = NULL_TREE;
+ saw_default = 0;
for (; t; t = next_t)
{
next_t = TREE_CHAIN (t);
+ if (TREE_INT_CST_LOW (TREE_PURPOSE (t)) == DEFAULT_INIT_PRIORITY)
+ saw_default = 1;
for (p = &static_aggregates_initp; ; p = &TREE_CHAIN (*p))
{
@@ -2955,6 +2957,10 @@ setup_initp ()
}
}
+ if (! saw_default)
+ static_aggregates_initp = perm_tree_cons (default_pri, error_mark_node,
+ static_aggregates_initp);
+
/* Reverse each list to preserve the order (currently reverse declaration
order, for destructors). */
for (t = static_aggregates_initp; t; t = TREE_CHAIN (t))
@@ -2973,12 +2979,17 @@ start_objects (method_type, initp)
/* Make ctor or dtor function. METHOD_TYPE may be 'I' or 'D'. */
- if (flag_init_priority)
+ if (initp != DEFAULT_INIT_PRIORITY)
{
- if (initp == 0)
- initp = DEFAULT_INIT_PRIORITY;
+ char joiner;
+
+#ifdef JOINER
+ joiner = JOINER;
+#else
+ joiner = '_';
+#endif
- sprintf (type, "%c%c%.5u", method_type, JOINER, initp);
+ sprintf (type, "%c%c%.5u", method_type, joiner, initp);
}
else
sprintf (type, "%c", method_type);
@@ -2990,6 +3001,12 @@ start_objects (method_type, initp)
NULL_TREE),
NULL_TREE, 0);
+#if defined(ASM_OUTPUT_CONSTRUCTOR) && defined(ASM_OUTPUT_DESTRUCTOR)
+ /* It can be a static function as long as collect2 does not have
+ to scan the object file to find its ctor/dtor routine. */
+ TREE_PUBLIC (current_function_decl) = 0;
+#endif
+
store_parm_decls ();
pushlevel (0);
clear_last_expr ();
@@ -3006,7 +3023,7 @@ finish_objects (method_type, initp)
{
char *fnname;
- if (! initp)
+ if (initp == DEFAULT_INIT_PRIORITY)
{
tree list = (method_type == 'I' ? static_ctors : static_dtors);
@@ -3028,7 +3045,7 @@ finish_objects (method_type, initp)
pop_momentary ();
finish_function (lineno, 0, 0);
- if (! flag_init_priority)
+ if (initp == DEFAULT_INIT_PRIORITY)
{
if (method_type == 'I')
assemble_constructor (fnname);
@@ -3040,11 +3057,9 @@ finish_objects (method_type, initp)
/* If we're using init priority we can't use assemble_*tor, but on ELF
targets we can stick the references into named sections for GNU ld
to collect. */
- if (flag_init_priority)
+ else
{
char buf[15];
- if (initp == 0)
- initp = DEFAULT_INIT_PRIORITY;
sprintf (buf, ".%ctors.%.5u", method_type == 'I' ? 'c' : 'd',
/* invert the numbering so the linker puts us in the proper
order; constructors are run from right to left, and the
@@ -3068,18 +3083,10 @@ do_dtors (start)
tree vars;
int initp;
- if (start)
- {
- initp = TREE_INT_CST_LOW (TREE_PURPOSE (start));
- vars = TREE_VALUE (start);
- }
- else
- {
- initp = 0;
- vars = static_aggregates;
- }
+ initp = TREE_INT_CST_LOW (TREE_PURPOSE (start));
+ vars = TREE_VALUE (start);
- for (; vars; vars = TREE_CHAIN (vars))
+ for (; vars && vars != error_mark_node; vars = TREE_CHAIN (vars))
{
tree decl = TREE_VALUE (vars);
tree type = TREE_TYPE (decl);
@@ -3095,6 +3102,12 @@ do_dtors (start)
if (! current_function_decl)
start_objects ('D', initp);
+ /* Set these global variables so that GDB at least puts
+ us near the declaration which required the initialization. */
+ input_filename = DECL_SOURCE_FILE (decl);
+ lineno = DECL_SOURCE_LINE (decl);
+ emit_note (input_filename, lineno);
+
/* Because of:
[class.access.spec]
@@ -3150,21 +3163,13 @@ do_ctors (start)
tree vars;
int initp;
- if (start)
- {
- initp = TREE_INT_CST_LOW (TREE_PURPOSE (start));
- vars = TREE_VALUE (start);
- }
- else
- {
- initp = 0;
- vars = static_aggregates;
- }
+ initp = TREE_INT_CST_LOW (TREE_PURPOSE (start));
+ vars = TREE_VALUE (start);
/* Reverse the list so it's in the right order for ctors. */
vars = nreverse (vars);
- for (; vars; vars = TREE_CHAIN (vars))
+ for (; vars && vars != error_mark_node; vars = TREE_CHAIN (vars))
{
tree decl = TREE_VALUE (vars);
tree init = TREE_PURPOSE (vars);
@@ -3266,11 +3271,9 @@ finish_file ()
at_eof = 1;
/* Bad parse errors. Just forget about it. */
- if (! global_bindings_p () || current_class_type)
+ if (! global_bindings_p () || current_class_type || decl_namespace_list)
return;
- check_decl_namespace ();
-
start_time = get_run_time ();
/* Otherwise, GDB can get confused, because in only knows
@@ -3344,11 +3347,6 @@ finish_file ()
pushdecl (vars);
#endif
- /* Walk to mark the inline functions we need, then output them so
- that we can pick up any other tdecls that those routines need. */
- walk_vtables ((void (*) PROTO ((tree, tree))) 0,
- finish_prevtable_vardecl);
-
for (vars = static_aggregates; vars; vars = TREE_CHAIN (vars))
if (! TREE_ASM_WRITTEN (TREE_VALUE (vars)))
rest_of_decl_compilation (TREE_VALUE (vars), 0, 1, 1);
@@ -3364,35 +3362,31 @@ finish_file ()
/* After setup_initp, the aggregates are listed in reverse declaration
order, for cleaning. */
if (needs_cleaning)
- {
- do_dtors (NULL_TREE);
-
- if (flag_init_priority)
- for (vars = static_aggregates_initp; vars; vars = TREE_CHAIN (vars))
- do_dtors (vars);
- }
+ for (vars = static_aggregates_initp; vars; vars = TREE_CHAIN (vars))
+ do_dtors (vars);
/* do_ctors will reverse the lists for messing up. */
if (needs_messing_up)
- {
- do_ctors (NULL_TREE);
-
- if (flag_init_priority)
- for (vars = static_aggregates_initp; vars; vars = TREE_CHAIN (vars))
- do_ctors (vars);
- }
+ for (vars = static_aggregates_initp; vars; vars = TREE_CHAIN (vars))
+ do_ctors (vars);
permanent_allocation (1);
/* Done with C language context needs. */
pop_lang_context ();
+ /* Let expand_static_init know it's too late for more ctors. */
+ at_eof = 2;
+
/* Now write out any static class variables (which may have since
learned how to be initialized). */
- while (pending_statics)
+ for (; pending_statics; pending_statics = TREE_CHAIN (pending_statics))
{
tree decl = TREE_VALUE (pending_statics);
+ if (TREE_ASM_WRITTEN (decl))
+ continue;
+
/* Output DWARF debug information. */
#ifdef DWARF_DEBUGGING_INFO
if (write_symbols == DWARF_DEBUG)
@@ -3403,11 +3397,15 @@ finish_file ()
dwarf2out_decl (decl);
#endif
- DECL_DEFER_OUTPUT (decl) = 0;
+ /* We currently handle template statics here. We ought to handle
+ them the same way we do template functions, i.e. only emit them if
+ the symbol is needed. */
+ import_export_decl (decl);
+ if (DECL_NOT_REALLY_EXTERN (decl) && ! DECL_IN_AGGR_P (decl))
+ DECL_EXTERNAL (decl) = 0;
+
rest_of_decl_compilation
(decl, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)), 1, 1);
-
- pending_statics = TREE_CHAIN (pending_statics);
}
this_time = get_run_time ();
@@ -3469,7 +3467,8 @@ finish_file ()
continue;
if (TREE_ASM_WRITTEN (decl)
- || (DECL_SAVED_INSNS (decl) == 0 && ! DECL_ARTIFICIAL (decl)))
+ || (DECL_SAVED_INSNS (decl) == 0
+ && ! DECL_ARTIFICIAL (decl)))
*p = TREE_CHAIN (*p);
else if (DECL_INITIAL (decl) == 0)
p = &TREE_CHAIN (*p);
@@ -3518,7 +3517,8 @@ finish_file ()
}
/* Now delete from the chain of variables all virtual function tables.
- We output them all ourselves, because each will be treated specially. */
+ We output them all ourselves, because each will be treated
+ specially. */
walk_vtables ((void (*) PROTO((tree, tree))) 0,
prune_vtable_vardecl);
@@ -3554,11 +3554,13 @@ reparse_absdcl_as_expr (type, decl)
return build_functional_cast (type, NULL_TREE);
/* recurse */
- decl = reparse_decl_as_expr (type, TREE_OPERAND (decl, 0));
+ decl = reparse_absdcl_as_expr (type, TREE_OPERAND (decl, 0));
decl = build_x_function_call (decl, NULL_TREE, current_class_ref);
- if (TREE_CODE (decl) == CALL_EXPR && TREE_TYPE (decl) != void_type_node)
+ if (TREE_CODE (decl) == CALL_EXPR
+ && (! TREE_TYPE (decl)
+ || TREE_CODE (TREE_TYPE (decl)) != VOID_TYPE))
decl = require_complete_type (decl);
return decl;
@@ -3777,11 +3779,28 @@ build_expr_from_tree (t)
TREE_OPERAND (ref, 1),
build_expr_from_tree (TREE_OPERAND (t, 2)));
}
- return build_method_call
- (build_expr_from_tree (TREE_OPERAND (t, 1)),
- TREE_OPERAND (t, 0),
- build_expr_from_tree (TREE_OPERAND (t, 2)),
- NULL_TREE, LOOKUP_NORMAL);
+ else
+ {
+ tree fn = TREE_OPERAND (t, 0);
+
+ /* We can get a TEMPLATE_ID_EXPR here on code like:
+
+ x->f<2>();
+
+ so we must resolve that. However, we can also get things
+ like a BIT_NOT_EXPR here, when referring to a destructor,
+ and things like that are not correctly resolved by
+ build_expr_from_tree. So, just use build_expr_from_tree
+ when we really need it. */
+ if (TREE_CODE (fn) == TEMPLATE_ID_EXPR)
+ fn = build_expr_from_tree (fn);
+
+ return build_method_call
+ (build_expr_from_tree (TREE_OPERAND (t, 1)),
+ fn,
+ build_expr_from_tree (TREE_OPERAND (t, 2)),
+ NULL_TREE, LOOKUP_NORMAL);
+ }
case CALL_EXPR:
if (TREE_CODE (TREE_OPERAND (t, 0)) == SCOPE_REF)
@@ -3855,6 +3874,7 @@ build_expr_from_tree (t)
r = build_nt (CONSTRUCTOR, NULL_TREE,
build_expr_from_tree (CONSTRUCTOR_ELTS (t)));
+ TREE_HAS_CONSTRUCTOR (r) = TREE_HAS_CONSTRUCTOR (t);
if (TREE_TYPE (t))
return digest_init (TREE_TYPE (t), r, 0);
@@ -3922,6 +3942,10 @@ finish_decl_parsing (decl)
case ARRAY_REF:
TREE_OPERAND (decl, 0) = finish_decl_parsing (TREE_OPERAND (decl, 0));
return decl;
+ case TREE_LIST:
+ /* For attribute handling. */
+ TREE_VALUE (decl) = finish_decl_parsing (TREE_VALUE (decl));
+ return decl;
default:
my_friendly_abort (5);
return NULL_TREE;
@@ -4082,8 +4106,7 @@ ambiguous_decl (name, old, new, flags)
/* If we expect types or namespaces, and not templates,
or this is not a template class. */
if (LOOKUP_QUALIFIERS_ONLY (flags)
- && (!(flags & LOOKUP_TEMPLATES_EXPECTED)
- || !DECL_CLASS_TEMPLATE_P (val)))
+ && !DECL_CLASS_TEMPLATE_P (val))
val = NULL_TREE;
break;
case TYPE_DECL:
@@ -4114,9 +4137,15 @@ ambiguous_decl (name, old, new, flags)
/* Some declarations are functions, some are not. */
if (flags & LOOKUP_COMPLAIN)
{
- cp_error ("use of `%D' is ambiguous", name);
- cp_error_at (" first declared as `%#D' here",
- BINDING_VALUE (old));
+ /* If we've already given this error for this lookup,
+ BINDING_VALUE (old) is error_mark_node, so let's not
+ repeat ourselves. */
+ if (BINDING_VALUE (old) != error_mark_node)
+ {
+ cp_error ("use of `%D' is ambiguous", name);
+ cp_error_at (" first declared as `%#D' here",
+ BINDING_VALUE (old));
+ }
cp_error_at (" also declared as `%#D' here", val);
}
return error_mark_node;
@@ -4210,9 +4239,10 @@ qualified_lookup_using_namespace (name, scope, result, flags)
outside scope. */
void
-set_decl_namespace (decl, scope)
+set_decl_namespace (decl, scope, friendp)
tree decl;
tree scope;
+ int friendp;
{
tree old;
if (scope == std_node)
@@ -4220,7 +4250,8 @@ set_decl_namespace (decl, scope)
/* Get rid of namespace aliases. */
scope = ORIGINAL_NAMESPACE (scope);
- if (!is_namespace_ancestor (current_namespace, scope))
+ /* It is ok for friends to be qualified in parallel space. */
+ if (!friendp && !is_namespace_ancestor (current_namespace, scope))
cp_error ("declaration of `%D' not in a namespace surrounding `%D'",
decl, scope);
DECL_CONTEXT (decl) = FROB_CONTEXT (scope);
@@ -4252,7 +4283,7 @@ set_decl_namespace (decl, scope)
/* Compute the namespace where a declaration is defined. */
-tree
+static tree
decl_namespace (decl)
tree decl;
{
@@ -4305,10 +4336,28 @@ pop_decl_namespace ()
decl_namespace_list = TREE_CHAIN (decl_namespace_list);
}
-static void
-check_decl_namespace ()
+/* Enter a class or namespace scope. */
+
+void
+push_scope (t)
+ tree t;
{
- my_friendly_assert (decl_namespace_list == NULL_TREE, 980711);
+ if (TREE_CODE (t) == NAMESPACE_DECL)
+ push_decl_namespace (t);
+ else
+ pushclass (t, 2);
+}
+
+/* Leave scope pushed by push_scope. */
+
+void
+pop_scope (t)
+ tree t;
+{
+ if (TREE_CODE (t) == NAMESPACE_DECL)
+ pop_decl_namespace ();
+ else
+ popclass (1);
}
/* [basic.lookup.koenig] */
@@ -4326,6 +4375,9 @@ struct arg_lookup
static int arg_assoc PROTO((struct arg_lookup*, tree));
static int arg_assoc_args PROTO((struct arg_lookup*, tree));
static int arg_assoc_type PROTO((struct arg_lookup*, tree));
+static int add_function PROTO((struct arg_lookup *, tree));
+static int arg_assoc_namespace PROTO((struct arg_lookup *, tree));
+static int arg_assoc_class PROTO((struct arg_lookup *, tree));
/* Add a function to the lookup structure.
Returns 1 on error. */
@@ -4476,6 +4528,7 @@ arg_assoc_type (k, type)
/* Associate the return type. */
return arg_assoc_type (k, TREE_TYPE (type));
case TEMPLATE_TYPE_PARM:
+ case TEMPLATE_TEMPLATE_PARM:
return 0;
case LANG_TYPE:
if (type == unknown_type_node)
@@ -4518,9 +4571,13 @@ arg_assoc (k, n)
if (TREE_CODE (n) == ADDR_EXPR)
n = TREE_OPERAND (n, 0);
+ if (TREE_CODE (n) == COMPONENT_REF)
+ n = TREE_OPERAND (n, 1);
while (TREE_CODE (n) == TREE_LIST)
n = TREE_VALUE (n);
+ if (TREE_CODE (n) == FUNCTION_DECL)
+ return arg_assoc_type (k, TREE_TYPE (n));
if (TREE_CODE (n) == TEMPLATE_ID_EXPR)
{
/* [basic.lookup.koenig]
@@ -4583,7 +4640,7 @@ arg_assoc (k, n)
my_friendly_assert (TREE_CODE (n) == OVERLOAD, 980715);
for (; n; n = OVL_CHAIN (n))
- if (arg_assoc (k, OVL_FUNCTION (n)))
+ if (arg_assoc_type (k, TREE_TYPE (OVL_FUNCTION (n))))
return 1;
}
@@ -4643,14 +4700,41 @@ validate_nonmember_using_decl (decl, scope, name)
{
if (TREE_CODE (decl) == SCOPE_REF
&& TREE_OPERAND (decl, 0) == std_node)
- return NULL_TREE;
- if (TREE_CODE (decl) == SCOPE_REF)
+ {
+ if (namespace_bindings_p ()
+ && current_namespace == global_namespace)
+ /* There's no need for a using declaration at all, here,
+ since `std' is the same as `::'. We can't just pass this
+ on because we'll complain later about declaring something
+ in the same scope as a using declaration with the same
+ name. We return NULL_TREE which indicates to the caller
+ that there's no need to do any further processing. */
+ return NULL_TREE;
+
+ *scope = global_namespace;
+ *name = TREE_OPERAND (decl, 1);
+ }
+ else if (TREE_CODE (decl) == SCOPE_REF)
{
*scope = TREE_OPERAND (decl, 0);
*name = TREE_OPERAND (decl, 1);
+
+ /* [namespace.udecl]
+
+ A using-declaration for a class member shall be a
+ member-declaration. */
+ if (TREE_CODE (*scope) != NAMESPACE_DECL)
+ {
+ if (TYPE_P (*scope))
+ cp_error ("`%T' is not a namespace", *scope);
+ else
+ cp_error ("`%D' is not a namespace", *scope);
+ return NULL_TREE;
+ }
}
else if (TREE_CODE (decl) == IDENTIFIER_NODE
- || TREE_CODE (decl) == TYPE_DECL)
+ || TREE_CODE (decl) == TYPE_DECL
+ || TREE_CODE (decl) == TEMPLATE_DECL)
{
*scope = global_namespace;
*name = decl;
@@ -4700,17 +4784,37 @@ do_nonmember_using_decl (scope, name, oldval, oldtype, newval, newtype)
*newval = oldval;
for (tmp = BINDING_VALUE (decls); tmp; tmp = OVL_NEXT (tmp))
{
- /* Compare each new function with each old one.
- If the old function was also used, there is no conflict. */
+ tree new_fn = OVL_CURRENT (tmp);
+
+ /* [namespace.udecl]
+
+ If a function declaration in namespace scope or block
+ scope has the same name and the same parameter types as a
+ function introduced by a using declaration the program is
+ ill-formed. */
for (tmp1 = oldval; tmp1; tmp1 = OVL_NEXT (tmp1))
- if (OVL_CURRENT (tmp) == OVL_CURRENT (tmp1))
- break;
- else if (OVL_USED (tmp1))
- continue;
- else if (duplicate_decls (OVL_CURRENT (tmp), OVL_CURRENT (tmp1)))
- return;
+ {
+ tree old_fn = OVL_CURRENT (tmp1);
+
+ if (!OVL_USED (tmp1)
+ && compparms (TYPE_ARG_TYPES (TREE_TYPE (new_fn)),
+ TYPE_ARG_TYPES (TREE_TYPE (old_fn))))
+ {
+ /* There was already a non-using declaration in
+ this scope with the same parameter types. */
+ cp_error ("`%D' is already declared in this scope",
+ name);
+ break;
+ }
+ else if (duplicate_decls (new_fn, old_fn))
+ /* We're re-using something we already used
+ before. We don't need to add it again. */
+ break;
+ }
- /* Duplicate use, ignore */
+ /* If we broke out of the loop, there's no reason to add
+ this function to the using declarations for this
+ scope. */
if (tmp1)
continue;
@@ -4783,7 +4887,27 @@ do_local_using_decl (decl)
do_nonmember_using_decl (scope, name, oldval, oldtype, &newval, &newtype);
if (newval)
- set_identifier_local_value (name, newval);
+ {
+ if (is_overloaded_fn (newval))
+ {
+ tree fn, term;
+
+ /* We only need to push declarations for those functions
+ that were not already bound in the current level.
+ The old value might be NULL_TREE, it might be a single
+ function, or an OVERLOAD. */
+ if (oldval && TREE_CODE (oldval) == OVERLOAD)
+ term = OVL_FUNCTION (oldval);
+ else
+ term = oldval;
+ for (fn = newval; fn && OVL_CURRENT (fn) != term;
+ fn = OVL_NEXT (fn))
+ push_overloaded_decl (OVL_CURRENT (fn),
+ PUSH_LOCAL | PUSH_USING);
+ }
+ else
+ push_local_binding (name, newval, PUSH_USING);
+ }
if (newtype)
set_identifier_type_value (name, newtype);
}
@@ -4901,6 +5025,8 @@ handle_class_head (aggr, scope, id)
{
if (TREE_CODE (id) == TYPE_DECL)
return id;
+ if (DECL_CLASS_TEMPLATE_P (id))
+ return DECL_TEMPLATE_RESULT (id);
if (scope)
cp_error ("`%T' does not have a nested type named `%D'", scope, id);
diff --git a/gcc/cp/errfn.c b/gcc/cp/errfn.c
index a43bcf3f0e1..7d6e66dffac 100644
--- a/gcc/cp/errfn.c
+++ b/gcc/cp/errfn.c
@@ -1,5 +1,5 @@
/* Provide a call-back mechanism for handling error output.
- Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc.
+ Copyright (C) 1993, 94-98, 1999 Free Software Foundation, Inc.
Contributed by Jason Merrill (jason@cygnus.com)
This file is part of GNU CC.
@@ -22,6 +22,7 @@ Boston, MA 02111-1307, USA. */
#include "config.h"
#include "system.h"
#include "tree.h"
+#include "cp-tree.h"
#include "toplev.h"
/* cp_printer is the type of a function which converts an argument into
@@ -39,6 +40,7 @@ int cp_silent = 0;
typedef void errorfn (); /* deliberately vague */
+static void cp_thing PROTO ((errorfn *, int, const char *, va_list));
extern char* cp_file_of PROTO((tree));
extern int cp_line_of PROTO((tree));
@@ -47,17 +49,12 @@ extern int cp_line_of PROTO((tree));
/* This function supports only `%s', `%d', `%%', and the C++ print
codes. */
-#ifdef __STDC__
-static void
-cp_thing (errorfn *errfn, int atarg1, const char *format, va_list ap)
-#else
static void
cp_thing (errfn, atarg1, format, ap)
errorfn *errfn;
int atarg1;
const char *format;
va_list ap;
-#endif
{
static char *buf;
static long buflen;
@@ -194,81 +191,152 @@ cp_thing (errfn, atarg1, format, ap)
}
-#ifdef __STDC__
-#define DECLARE(name) void name (const char *format, ...)
-#define INIT va_start (ap, format)
-#else
-#define DECLARE(name) void name (format, va_alist) char *format; va_dcl
-#define INIT va_start (ap)
-#endif
-
-DECLARE (cp_error)
+void
+cp_error VPROTO((const char *format, ...))
{
+#ifndef ANSI_PROTOTYPES
+ char *format;
+#endif
va_list ap;
- INIT;
+
+ VA_START (ap, format);
+
+#ifndef ANSI_PROTOTYPES
+ format = va_arg (ap, char *);
+#endif
+
if (! cp_silent)
cp_thing ((errorfn *) error, 0, format, ap);
va_end (ap);
}
-DECLARE (cp_warning)
+void
+cp_warning VPROTO((const char *format, ...))
{
+#ifndef ANSI_PROTOTYPES
+ char *format;
+#endif
va_list ap;
- INIT;
+
+ VA_START (ap, format);
+
+#ifndef ANSI_PROTOTYPES
+ format = va_arg (ap, char *);
+#endif
+
if (! cp_silent)
cp_thing ((errorfn *) warning, 0, format, ap);
va_end (ap);
}
-DECLARE (cp_pedwarn)
+void
+cp_pedwarn VPROTO((const char *format, ...))
{
+#ifndef ANSI_PROTOTYPES
+ char *format;
+#endif
va_list ap;
- INIT;
+
+ VA_START (ap, format);
+
+#ifndef ANSI_PROTOTYPES
+ format = va_arg (ap, char *);
+#endif
+
if (! cp_silent)
cp_thing ((errorfn *) pedwarn, 0, format, ap);
va_end (ap);
}
-DECLARE (cp_compiler_error)
+void
+cp_compiler_error VPROTO((const char *format, ...))
{
- extern errorfn compiler_error;
+#ifndef ANSI_PROTOTYPES
+ char *format;
+#endif
va_list ap;
- INIT;
+
+ VA_START (ap, format);
+
+#ifndef ANSI_PROTOTYPES
+ format = va_arg (ap, char *);
+#endif
+
if (! cp_silent)
- cp_thing (compiler_error, 0, format, ap);
+ cp_thing ((errorfn *) compiler_error, 0, format, ap);
va_end (ap);
}
-DECLARE (cp_sprintf)
+void
+cp_sprintf VPROTO((const char *format, ...))
{
+#ifndef ANSI_PROTOTYPES
+ char *format;
+#endif
va_list ap;
- INIT;
+
+ VA_START (ap, format);
+
+#ifndef ANSI_PROTOTYPES
+ format = va_arg (ap, char *);
+#endif
+
cp_thing ((errorfn *) sprintf, 0, format, ap);
va_end (ap);
}
-DECLARE (cp_error_at)
+void
+cp_error_at VPROTO((const char *format, ...))
{
+#ifndef ANSI_PROTOTYPES
+ char *format;
+#endif
va_list ap;
- INIT;
+
+ VA_START (ap, format);
+
+#ifndef ANSI_PROTOTYPES
+ format = va_arg (ap, char *);
+#endif
+
if (! cp_silent)
cp_thing ((errorfn *) error_with_file_and_line, 1, format, ap);
va_end (ap);
}
-DECLARE (cp_warning_at)
+void
+cp_warning_at VPROTO((const char *format, ...))
{
+#ifndef ANSI_PROTOTYPES
+ char *format;
+#endif
va_list ap;
- INIT;
+
+ VA_START (ap, format);
+
+#ifndef ANSI_PROTOTYPES
+ format = va_arg (ap, char *);
+#endif
+
if (! cp_silent)
cp_thing ((errorfn *) warning_with_file_and_line, 1, format, ap);
va_end (ap);
}
-DECLARE (cp_pedwarn_at)
+void
+cp_pedwarn_at VPROTO((const char *format, ...))
{
+#ifndef ANSI_PROTOTYPES
+ char *format;
+#endif
va_list ap;
- INIT;
+
+ VA_START (ap, format);
+
+#ifndef ANSI_PROTOTYPES
+ format = va_arg (ap, char *);
+#endif
+
if (! cp_silent)
cp_thing ((errorfn *) pedwarn_with_file_and_line, 1, format, ap);
va_end (ap);
diff --git a/gcc/cp/error.c b/gcc/cp/error.c
index 52c519d692a..b230e1f1efc 100644
--- a/gcc/cp/error.c
+++ b/gcc/cp/error.c
@@ -1,6 +1,6 @@
/* Call-backs for C++ error reporting.
This code is non-reentrant.
- Copyright (C) 1993, 94-97, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1993, 94-97, 1998, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -32,6 +32,7 @@ typedef char* cp_printer ();
#define C code_as_string
#define D decl_as_string
#define E expr_as_string
+#define F fndecl_as_string
#define L language_as_string
#define O op_as_string
#define P parm_as_string
@@ -47,7 +48,7 @@ cp_printer * cp_printers[256] =
o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, /* 0x10 */
o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, /* 0x20 */
o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, /* 0x30 */
- o, A, o, C, D, E, o, o, o, o, o, o, L, o, o, O, /* 0x40 */
+ o, A, o, C, D, E, F, o, o, o, o, o, L, o, o, O, /* 0x40 */
P, Q, o, o, T, o, V, o, o, o, o, o, o, o, o, o, /* 0x50 */
o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, /* 0x60 */
o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, /* 0x70 */
@@ -55,6 +56,7 @@ cp_printer * cp_printers[256] =
#undef C
#undef D
#undef E
+#undef F
#undef L
#undef O
#undef P
@@ -102,10 +104,13 @@ static void dump_type_suffix PROTO((tree, int, int));
static void dump_function_name PROTO((tree));
static void dump_expr_list PROTO((tree));
static void dump_global_iord PROTO((tree));
-static void dump_readonly_or_volatile PROTO((tree, enum pad));
+static void dump_qualifiers PROTO((tree, enum pad));
static void dump_char PROTO((int));
+static void dump_parameters PROTO((tree, int, int));
+static void dump_exception_spec PROTO((tree, int));
static char *aggr_variety PROTO((tree));
static tree ident_fndecl PROTO((tree));
+static int interesting_scope_p PROTO((tree));
void
init_error ()
@@ -114,20 +119,61 @@ init_error ()
scratch_firstobj = (char *)obstack_alloc (&scratch_obstack, 0);
}
+/* Returns nonzero if SCOPE is something we want to print for random decls. */
+
+static int
+interesting_scope_p (scope)
+ tree scope;
+{
+ if (scope == NULL_TREE
+ || scope == global_namespace)
+ return 0;
+
+ return (TREE_CODE (scope) == NAMESPACE_DECL
+ || AGGREGATE_TYPE_P (scope));
+}
+
static void
-dump_readonly_or_volatile (t, p)
+dump_qualifiers (t, p)
tree t;
enum pad p;
{
- if (TYPE_READONLY (t) || TYPE_VOLATILE (t))
+ if (TYPE_QUALS (t))
{
if (p == before) OB_PUTC (' ');
- if (TYPE_READONLY (t))
- OB_PUTS ("const");
- if (TYPE_READONLY (t) && TYPE_VOLATILE (t))
- OB_PUTC (' ');
- if (TYPE_VOLATILE (t))
- OB_PUTS ("volatile");
+ switch (TYPE_QUALS (t))
+ {
+ case TYPE_QUAL_CONST:
+ OB_PUTS ("const");
+ break;
+
+ case TYPE_QUAL_VOLATILE:
+ OB_PUTS ("volatile");
+ break;
+
+ case TYPE_QUAL_RESTRICT:
+ OB_PUTS ("__restrict");
+ break;
+
+ case TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE:
+ OB_PUTS ("const volatile");
+ break;
+
+ case TYPE_QUAL_CONST | TYPE_QUAL_RESTRICT:
+ OB_PUTS ("const __restrict");
+ break;
+
+ case TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT:
+ OB_PUTS ("volatile __restrict");
+ break;
+
+ case TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT:
+ OB_PUTS ("const volatile __restrict");
+ break;
+
+ default:
+ my_friendly_abort (0);
+ }
if (p == after) OB_PUTC (' ');
}
}
@@ -160,29 +206,6 @@ dump_type_real (t, v, canonical_name)
OB_PUTS ("{unknown type}");
break;
- case TREE_LIST:
- /* i.e. function taking no arguments */
- if (t != void_list_node)
- {
- dump_type_real (TREE_VALUE (t), v, canonical_name);
- /* Can this happen other than for default arguments? */
- if (TREE_PURPOSE (t) && v)
- {
- OB_PUTS (" = ");
- dump_expr (TREE_PURPOSE (t), 0);
- }
- if (TREE_CHAIN (t))
- {
- if (TREE_CHAIN (t) != void_list_node)
- {
- OB_PUTC2 (',', ' ');
- dump_type_real (TREE_CHAIN (t), v, canonical_name);
- }
- }
- else OB_PUTS (" ...");
- }
- break;
-
case IDENTIFIER_NODE:
OB_PUTID (t);
break;
@@ -197,8 +220,7 @@ dump_type_real (t, v, canonical_name)
if (TYPE_LANG_SPECIFIC (t)
&& (IS_SIGNATURE_POINTER (t) || IS_SIGNATURE_REFERENCE (t)))
{
- if (TYPE_READONLY (t) | TYPE_VOLATILE (t))
- dump_readonly_or_volatile (t, after);
+ dump_qualifiers (t, after);
dump_type_real (SIGNATURE_TYPE (t), v, canonical_name);
if (IS_SIGNATURE_POINTER (t))
OB_PUTC ('*');
@@ -232,7 +254,7 @@ dump_type_real (t, v, canonical_name)
case BOOLEAN_TYPE:
{
tree type;
- dump_readonly_or_volatile (t, after);
+ dump_qualifiers (t, after);
type = canonical_name ? TYPE_MAIN_VARIANT (t) : t;
if (TYPE_NAME (type) && TYPE_IDENTIFIER (type))
OB_PUTID (TYPE_IDENTIFIER (type));
@@ -245,7 +267,7 @@ dump_type_real (t, v, canonical_name)
break;
case TEMPLATE_TEMPLATE_PARM:
- if (!CLASSTYPE_TEMPLATE_INFO (t))
+ if (!TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (t))
{
/* For parameters inside template signature. */
if (TYPE_IDENTIFIER (t))
@@ -256,7 +278,7 @@ dump_type_real (t, v, canonical_name)
else
{
int i;
- tree args = CLASSTYPE_TI_ARGS (t);
+ tree args = TYPE_TI_ARGS (t);
OB_PUTID (TYPE_IDENTIFIER (t));
OB_PUTC ('<');
for (i = 0; i < TREE_VEC_LENGTH (args); i++)
@@ -275,7 +297,7 @@ dump_type_real (t, v, canonical_name)
break;
case TEMPLATE_TYPE_PARM:
- dump_readonly_or_volatile (t, after);
+ dump_qualifiers (t, after);
if (TYPE_IDENTIFIER (t))
OB_PUTID (TYPE_IDENTIFIER (t));
else
@@ -302,6 +324,12 @@ dump_type_real (t, v, canonical_name)
OB_PUTID (TYPE_IDENTIFIER (t));
break;
+ case TYPEOF_TYPE:
+ OB_PUTS ("__typeof (");
+ dump_expr (TYPE_FIELDS (t), 1);
+ OB_PUTC (')');
+ break;
+
default:
sorry ("`%s' not supported by dump_type",
tree_code_name[(int) TREE_CODE (t)]);
@@ -343,7 +371,7 @@ dump_aggr_type (t, v, canonical_name)
tree name;
char *variety = aggr_variety (t);
- dump_readonly_or_volatile (t, after);
+ dump_qualifiers (t, after);
if (v > 0)
{
@@ -404,13 +432,14 @@ dump_type_prefix (t, v, canonical_name)
switch (TREE_CODE (t))
{
case POINTER_TYPE:
+ case REFERENCE_TYPE:
{
tree sub = TREE_TYPE (t);
dump_type_prefix (sub, v, canonical_name);
/* A tree for a member pointer looks like pointer to offset,
so let the OFFSET_TYPE case handle it. */
- if (TREE_CODE (sub) != OFFSET_TYPE)
+ if (!TYPE_PTRMEM_P (t))
{
switch (TREE_CODE (sub))
{
@@ -425,42 +454,20 @@ dump_type_prefix (t, v, canonical_name)
case POINTER_TYPE:
/* We don't want "char * *" */
- if (! (TYPE_READONLY (sub) || TYPE_VOLATILE (sub)))
+ if (TYPE_QUALS (sub) == TYPE_UNQUALIFIED)
break;
/* But we do want "char *const *" */
default:
OB_PUTC (' ');
}
- OB_PUTC ('*');
- dump_readonly_or_volatile (t, none);
- }
- }
- break;
-
- case REFERENCE_TYPE:
- {
- tree sub = TREE_TYPE (t);
- dump_type_prefix (sub, v, canonical_name);
-
- switch (TREE_CODE (sub))
- {
- case ARRAY_TYPE:
- OB_PUTC2 (' ', '(');
- break;
-
- case POINTER_TYPE:
- /* We don't want "char * &" */
- if (! (TYPE_READONLY (sub) || TYPE_VOLATILE (sub)))
- break;
- /* But we do want "char *const &" */
-
- default:
- OB_PUTC (' ');
+ if (TREE_CODE (t) == POINTER_TYPE)
+ OB_PUTC ('*');
+ else
+ OB_PUTC ('&');
+ dump_qualifiers (t, none);
}
}
- OB_PUTC ('&');
- dump_readonly_or_volatile (t, none);
break;
case OFFSET_TYPE:
@@ -473,7 +480,7 @@ dump_type_prefix (t, v, canonical_name)
OB_PUTC2 (':', ':');
}
OB_PUTC ('*');
- dump_readonly_or_volatile (t, none);
+ dump_qualifiers (t, none);
break;
/* Can only be reached through function pointer -- this would not be
@@ -544,20 +551,20 @@ dump_type_suffix (t, v, canonical_name)
case METHOD_TYPE:
{
tree arg;
- OB_PUTC2 (')', '(');
+ OB_PUTC (')');
arg = TYPE_ARG_TYPES (t);
if (TREE_CODE (t) == METHOD_TYPE)
arg = TREE_CHAIN (arg);
- if (arg)
- dump_type (arg, v);
- else
- OB_PUTS ("...");
- OB_PUTC (')');
+ /* Function pointers don't have default args. Not in standard C++,
+ anyway; they may in g++, but we'll just pretend otherwise. */
+ dump_parameters (arg, 0, canonical_name);
+
if (TREE_CODE (t) == METHOD_TYPE)
- dump_readonly_or_volatile
+ dump_qualifiers
(TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (t))), before);
dump_type_suffix (TREE_TYPE (t), v, canonical_name);
+ dump_exception_spec (TYPE_RAISES_EXCEPTIONS (t), canonical_name);
break;
}
@@ -668,10 +675,10 @@ dump_simple_decl (t, type, v)
dump_type_prefix (type, v, 0);
OB_PUTC (' ');
}
- if (DECL_CLASS_SCOPE_P (t))
+ if (interesting_scope_p (DECL_CONTEXT (t)))
{
- dump_type (DECL_CONTEXT (t), 0);
- OB_PUTC2 (':', ':');
+ dump_decl (DECL_CONTEXT (t), 0);
+ OB_PUTC2 (':',':');
}
if (DECL_NAME (t))
dump_decl (DECL_NAME (t), v);
@@ -718,7 +725,13 @@ dump_decl (t, v)
if (DECL_NAME (t) && VTABLE_NAME_P (DECL_NAME (t)))
{
OB_PUTS ("vtable for ");
- dump_type (DECL_CONTEXT (t), v);
+ if (TYPE_P (DECL_CONTEXT (t)))
+ dump_type (DECL_CONTEXT (t), v);
+ else
+ /* This case can arise with -fno-vtable-thunks. See
+ expand_upcast_fixups. It's not clear what to print
+ here. */
+ OB_PUTS ("{unknown type}");
break;
}
/* else fall through */
@@ -852,6 +865,8 @@ dump_decl (t, v)
if (TREE_CODE (DECL_TEMPLATE_RESULT (t)) == TYPE_DECL)
dump_type (TREE_TYPE (t), v);
+ else if (TREE_CODE (DECL_TEMPLATE_RESULT (t)) == VAR_DECL)
+ dump_decl (DECL_TEMPLATE_RESULT (t), v);
else if (TREE_TYPE (t) == NULL_TREE)
my_friendly_abort (353);
else switch (NEXT_CODE (t))
@@ -924,9 +939,15 @@ dump_decl (t, v)
}
}
-/* Pretty printing for announce_function. T is the declaration of the
- function we are interested in seeing. V is non-zero if we should print
- the type that this function returns. */
+/* Pretty print a function decl. There are several ways we want to print a
+ function declaration. We use V to tell us what.
+ V - 01 23
+ args - ++ ++
+ retval - -+ ++
+ default- -+ -+
+ throw - -- ++
+ As cp_error can only apply the '#' flag once to give 0 and 1 for V, there
+ is %D which doesn't print the throw specs, and %F which does. */
static void
dump_function_decl (t, v)
@@ -946,28 +967,28 @@ dump_function_decl (t, v)
parmtypes = TYPE_ARG_TYPES (fntype);
/* Friends have DECL_CLASS_CONTEXT set, but not DECL_CONTEXT. */
- if (DECL_CONTEXT (t))
+ if (DECL_CLASS_SCOPE_P (t))
cname = DECL_CLASS_CONTEXT (t);
/* this is for partially instantiated template methods */
else if (TREE_CODE (fntype) == METHOD_TYPE)
cname = TREE_TYPE (TREE_VALUE (parmtypes));
- v = (v > 0);
-
- if (v)
+ /* Print the return type. */
+ if (v > 0)
{
if (DECL_STATIC_FUNCTION_P (t))
OB_PUTS ("static ");
- if (! IDENTIFIER_TYPENAME_P (name)
+ if (! DECL_CONV_FN_P (t)
&& ! DECL_CONSTRUCTOR_P (t)
- && ! DESTRUCTOR_NAME_P (name))
+ && ! DECL_DESTRUCTOR_P (t))
{
dump_type_prefix (TREE_TYPE (fntype), 1, 0);
OB_PUTC (' ');
}
}
+ /* Print the function name. */
if (cname)
{
dump_type (cname, 0);
@@ -978,34 +999,98 @@ dump_function_decl (t, v)
/* Skip past "in_charge" identifier. */
parmtypes = TREE_CHAIN (parmtypes);
}
+ else if (CP_DECL_CONTEXT (t) != global_namespace)
+ {
+ dump_decl (DECL_CONTEXT (t), 0);
+ OB_PUTC2 (':',':');
+ }
if (DESTRUCTOR_NAME_P (name) && DECL_LANGUAGE (t) == lang_cplusplus)
parmtypes = TREE_CHAIN (parmtypes);
dump_function_name (t);
-
- OB_PUTC ('(');
-
- if (parmtypes)
- dump_type (parmtypes, v);
- else
- OB_PUTS ("...");
- OB_PUTC (')');
+ /* If V is negative, we don't print the argument types. */
+ if (v < 0)
+ return;
- if (v && ! IDENTIFIER_TYPENAME_P (name))
+ dump_parameters (parmtypes, v & 1, 0);
+
+ if (v && ! DECL_CONV_FN_P (t))
dump_type_suffix (TREE_TYPE (fntype), 1, 0);
if (TREE_CODE (fntype) == METHOD_TYPE)
{
if (IS_SIGNATURE (cname))
/* We look at the type pointed to by the `optr' field of `this.' */
- dump_readonly_or_volatile
+ dump_qualifiers
(TREE_TYPE (TREE_TYPE (TYPE_FIELDS (TREE_VALUE (TYPE_ARG_TYPES (fntype))))), before);
else
- dump_readonly_or_volatile
+ dump_qualifiers
(TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (fntype))), before);
}
+
+ if (v >= 2)
+ dump_exception_spec (TYPE_RAISES_EXCEPTIONS (fntype), 0);
+}
+
+/* Print a parameter list. V indicates if we show default values or not. If
+ these are for a member function, the member object ptr
+ (and any other hidden args) should have already been removed. */
+
+static void
+dump_parameters (parmtypes, v, canonical_name)
+ tree parmtypes;
+ int v;
+ int canonical_name;
+{
+ int first;
+ OB_PUTC ('(');
+
+ for (first = 1; parmtypes != void_list_node;
+ parmtypes = TREE_CHAIN (parmtypes))
+ {
+ if (!first)
+ OB_PUTC2 (',', ' ');
+ first = 0;
+ if (!parmtypes)
+ {
+ OB_PUTS ("...");
+ break;
+ }
+ dump_type_real (TREE_VALUE (parmtypes), 0, canonical_name);
+
+ if (TREE_PURPOSE (parmtypes) && v)
+ {
+ OB_PUTS (" = ");
+ dump_expr (TREE_PURPOSE (parmtypes), 0);
+ }
+ }
+
+ OB_PUTC (')');
+}
+
+/* Print an exception specification. T is the exception specification. */
+
+static void
+dump_exception_spec (t, canonical_name)
+ tree t;
+ int canonical_name;
+{
+ if (t)
+ {
+ OB_PUTS (" throw (");
+ if (TREE_VALUE (t) != NULL_TREE)
+ while (1)
+ {
+ dump_type_real (TREE_VALUE (t), 0, canonical_name);
+ t = TREE_CHAIN (t);
+ if (!t)
+ break;
+ OB_PUTC2 (',', ' ');
+ }
+ OB_PUTC (')');
+ }
}
/* Handle the function name for a FUNCTION_DECL node, grokking operators
@@ -1017,15 +1102,12 @@ dump_function_name (t)
{
tree name = DECL_NAME (t);
- /* There ought to be a better way to find out whether or not something is
- a destructor. */
- if (DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (t))
- && DECL_LANGUAGE (t) == lang_cplusplus)
+ if (DECL_DESTRUCTOR_P (t))
{
OB_PUTC ('~');
dump_decl (name, 0);
}
- else if (IDENTIFIER_TYPENAME_P (name))
+ else if (DECL_CONV_FN_P (t))
{
/* This cannot use the hack that the operator's return
type is stashed off of its name because it may be
@@ -1304,7 +1386,6 @@ dump_expr (t, nop)
{
OB_PUTS ("new ");
dump_type (TREE_TYPE (TREE_TYPE (t)), 0);
- PARM_DECL_EXPR (t) = 1;
}
else
{
@@ -1538,11 +1619,20 @@ dump_expr (t, nop)
if (integer_all_onesp (idx))
{
tree pfn = PFN_FROM_PTRMEMFUNC (t);
- dump_expr (pfn, 0);
+ dump_unary_op ("&", pfn, 0);
+ break;
+ }
+ else if (TREE_CODE (idx) == INTEGER_CST
+ && tree_int_cst_equal (idx, integer_zero_node))
+ {
+ /* A NULL pointer-to-member constant. */
+ OB_PUTS ("((");
+ dump_type (TREE_TYPE (t), 0);
+ OB_PUTS (") 0)");
break;
}
- if (TREE_CODE (idx) == INTEGER_CST
- && TREE_INT_CST_HIGH (idx) == 0)
+ else if (TREE_CODE (idx) == INTEGER_CST
+ && TREE_INT_CST_HIGH (idx) == 0)
{
tree virtuals;
unsigned HOST_WIDE_INT n;
@@ -1577,8 +1667,7 @@ dump_expr (t, nop)
case OFFSET_REF:
{
tree ob = TREE_OPERAND (t, 0);
- if (TREE_CODE (ob) == NOP_EXPR
- && TREE_OPERAND (ob, 0) == error_mark_node)
+ if (is_dummy_object (ob))
{
if (TREE_CODE (TREE_OPERAND (t, 1)) == FUNCTION_DECL)
/* A::f */
@@ -1588,8 +1677,16 @@ dump_expr (t, nop)
}
else
{
- dump_expr (TREE_OPERAND (t, 0), 0);
- OB_PUTS (" .* ");
+ if (TREE_CODE (ob) == INDIRECT_REF)
+ {
+ dump_expr (TREE_OPERAND (ob, 0), 0);
+ OB_PUTS (" ->* ");
+ }
+ else
+ {
+ dump_expr (ob, 0);
+ OB_PUTS (" .* ");
+ }
dump_expr (TREE_OPERAND (t, 1), 0);
}
break;
@@ -1712,12 +1809,20 @@ dump_unary_op (opstring, t, nop)
if (!nop) OB_PUTC (')');
}
+/* Print a function decl with exception specification included. */
+
char *
-fndecl_as_string (fndecl, print_ret_type_p)
+fndecl_as_string (fndecl, print_default_args_p)
tree fndecl;
- int print_ret_type_p;
+ int print_default_args_p;
{
- return decl_as_string (fndecl, print_ret_type_p);
+ OB_INIT ();
+
+ dump_function_decl (fndecl, 2 + print_default_args_p);
+
+ OB_FINISH ();
+
+ return (char *)obstack_base (&scratch_obstack);
}
/* Same, but handle a _TYPE.
@@ -1834,7 +1939,8 @@ cp_line_of (t)
int line = 0;
if (TREE_CODE (t) == PARM_DECL && DECL_CONTEXT (t))
line = DECL_SOURCE_LINE (DECL_CONTEXT (t));
- if (TREE_CODE (t) == TYPE_DECL && DECL_ARTIFICIAL (t))
+ if (TREE_CODE (t) == TYPE_DECL && DECL_ARTIFICIAL (t)
+ && TYPE_MAIN_DECL (TREE_TYPE (t)))
t = TREE_TYPE (t);
if (TREE_CODE_CLASS (TREE_CODE (t)) == 't')
@@ -1952,7 +2058,7 @@ cv_as_string (p, v)
{
OB_INIT ();
- dump_readonly_or_volatile (p, before);
+ dump_qualifiers (p, before);
OB_FINISH ();
diff --git a/gcc/cp/except.c b/gcc/cp/except.c
index 0f7c427d32b..4b340533a97 100644
--- a/gcc/cp/except.c
+++ b/gcc/cp/except.c
@@ -1,5 +1,5 @@
/* Handle exceptional things in C++.
- Copyright (C) 1989, 92-97, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1989, 92-97, 1998, 1999 Free Software Foundation, Inc.
Contributed by Michael Tiemann <tiemann@cygnus.com>
Rewritten by Mike Stump <mrs@cygnus.com>, based upon an
initial re-implementation courtesy Tad Hunt.
@@ -54,9 +54,9 @@ static tree get_eh_info PROTO((void));
static tree get_eh_value PROTO((void));
#if 0
static tree get_eh_type PROTO((void));
-#endif
static tree get_eh_caught PROTO((void));
static tree get_eh_handlers PROTO((void));
+#endif
static tree do_pop_exception PROTO((void));
static void process_start_catch_block PROTO((tree, tree));
static tree build_eh_type_type_ref PROTO((tree));
@@ -234,14 +234,14 @@ call_eh_info ()
{
tree fn;
- fn = get_identifier ("__cp_eh_info");
+ fn = get_identifier ("__start_cp_handler");
if (IDENTIFIER_GLOBAL_VALUE (fn))
fn = IDENTIFIER_GLOBAL_VALUE (fn);
else
{
tree t1, t, fields[7];
- /* Declare cp_eh_info * __cp_eh_info (void),
+ /* Declare cp_eh_info * __start_cp_handler (void),
as defined in exception.cc. */
push_obstacks_nochange ();
end_temporary_allocation ();
@@ -255,9 +255,11 @@ call_eh_info ()
get_identifier ("dynamic_handler_chain"), ptr_type_node);
fields[2] = build_lang_field_decl (FIELD_DECL,
get_identifier ("info"), ptr_type_node);
+ fields[3] = build_lang_field_decl (FIELD_DECL,
+ get_identifier ("table_index"), ptr_type_node);
/* N.B.: The fourth field LEN is expected to be
the number of fields - 1, not the total number of fields. */
- finish_builtin_type (t1, "eh_context", fields, 2, ptr_type_node);
+ finish_builtin_type (t1, "eh_context", fields, 3, ptr_type_node);
t1 = build_pointer_type (t1);
t1= make_lang_type (RECORD_TYPE);
@@ -301,9 +303,9 @@ call_eh_info ()
DECL_ARTIFICIAL (fn) = 1;
pushdecl_top_level (fn);
make_function_rtl (fn);
- assemble_external (fn);
pop_obstacks ();
}
+ mark_used (fn);
return build_function_call (fn, NULL_TREE);
}
@@ -353,7 +355,6 @@ get_eh_type ()
return build_component_ref (get_eh_info (), get_identifier ("type"),
NULL_TREE, 0);
}
-#endif
/* Returns a reference to whether or not the current exception
has been caught. */
@@ -374,6 +375,7 @@ get_eh_handlers ()
return build_component_ref (get_eh_info (), get_identifier ("handlers"),
NULL_TREE, 0);
}
+#endif
/* Build a type value for use at runtime for a type that is matched
against by the exception handling system. */
@@ -382,7 +384,7 @@ static tree
build_eh_type_type (type)
tree type;
{
- char *typestring;
+ const char *typestring;
tree exp;
if (type == error_mark_node)
@@ -396,9 +398,7 @@ build_eh_type_type (type)
type = TYPE_MAIN_VARIANT (type);
if (flag_rtti)
- {
- return build1 (ADDR_EXPR, ptr_type_node, get_typeid (type));
- }
+ return build1 (ADDR_EXPR, ptr_type_node, get_typeid_1 (type));
typestring = build_overload_name (type, 1, 1);
exp = combine_strings (build_string (strlen (typestring)+1, typestring));
@@ -412,7 +412,7 @@ static tree
build_eh_type_type_ref (type)
tree type;
{
- char *typestring;
+ const char *typestring;
tree exp;
if (type == error_mark_node)
@@ -516,10 +516,10 @@ do_pop_exception ()
DECL_ARTIFICIAL (fn) = 1;
pushdecl_top_level (fn);
make_function_rtl (fn);
- assemble_external (fn);
pop_obstacks ();
}
+ mark_used (fn);
/* Arrange to do a dynamically scoped cleanup upon exit from this region. */
cleanup = lookup_name (get_identifier ("__exception_info"), 0);
cleanup = build_function_call (fn, expr_tree_cons
@@ -534,9 +534,6 @@ push_eh_cleanup ()
{
int yes;
- expand_expr (build_unary_op (PREINCREMENT_EXPR, get_eh_handlers (), 1),
- const0_rtx, VOIDmode, EXPAND_NORMAL);
-
yes = suspend_momentary ();
/* All cleanups must last longer than normal. */
expand_decl_cleanup (NULL_TREE, do_pop_exception ());
@@ -674,7 +671,8 @@ process_start_catch_block (declspecs, declarator)
decl = pushdecl (decl);
start_decl_1 (decl);
- cp_finish_decl (decl, init, NULL_TREE, 0, LOOKUP_ONLYCONVERTING);
+ cp_finish_decl (decl, init, NULL_TREE, 0,
+ LOOKUP_ONLYCONVERTING|DIRECT_BIND);
}
else
{
@@ -687,9 +685,6 @@ process_start_catch_block (declspecs, declarator)
/* Fall into the catch all section. */
}
- init = build_modify_expr (get_eh_caught (), NOP_EXPR, integer_one_node);
- expand_expr (init, const0_rtx, VOIDmode, EXPAND_NORMAL);
-
emit_line_note (input_filename, lineno);
}
@@ -759,7 +754,7 @@ expand_end_eh_spec (raises)
TREE_HAS_CONSTRUCTOR (types) = 1;
/* We can't pass the CONSTRUCTOR directly, so stick it in a variable. */
- tmp = build_array_type (const_ptr_type_node, NULL_TREE);
+ tmp = build_cplus_array_type (const_ptr_type_node, NULL_TREE);
decl = build_decl (VAR_DECL, NULL_TREE, tmp);
DECL_ARTIFICIAL (decl) = 1;
DECL_INITIAL (decl) = types;
@@ -787,10 +782,10 @@ expand_end_eh_spec (raises)
TREE_THIS_VOLATILE (fn) = 1;
pushdecl_top_level (fn);
make_function_rtl (fn);
- assemble_external (fn);
pop_obstacks ();
}
+ mark_used (fn);
tmp = expr_tree_cons (NULL_TREE, build_int_2 (count, 0), expr_tree_cons
(NULL_TREE, decl, NULL_TREE));
tmp = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), tmp);
@@ -929,10 +924,10 @@ alloc_eh_object (type)
DECL_ARTIFICIAL (fn) = 1;
pushdecl_top_level (fn);
make_function_rtl (fn);
- assemble_external (fn);
pop_obstacks ();
}
+ mark_used (fn);
exp = build_function_call (fn, expr_tree_cons
(NULL_TREE, size_in_bytes (type), NULL_TREE));
exp = build1 (NOP_EXPR, build_pointer_type (type), exp);
@@ -982,11 +977,8 @@ expand_throw (exp)
pop_obstacks ();
}
- if (TREE_CODE (TREE_TYPE (exp)) == POINTER_TYPE)
- {
- throw_type = build_eh_type (exp);
- exp = build_reinterpret_cast (ptr_type_node, exp);
- }
+ if (TYPE_PTR_P (TREE_TYPE (exp)))
+ throw_type = build_eh_type (exp);
else
{
tree object, ptr;
@@ -1017,13 +1009,11 @@ expand_throw (exp)
ourselves into expand_call. */
if (TREE_SIDE_EFFECTS (exp))
{
- tree temp = build (VAR_DECL, TREE_TYPE (exp));
+ tree temp = build_decl (VAR_DECL, NULL_TREE, TREE_TYPE (exp));
DECL_ARTIFICIAL (temp) = 1;
- layout_decl (temp, 0);
DECL_RTL (temp) = assign_temp (TREE_TYPE (exp), 2, 0, 1);
- expand_expr (build (INIT_EXPR, TREE_TYPE (exp), temp, exp),
- NULL_RTX, VOIDmode, 0);
- expand_decl_cleanup (NULL_TREE, maybe_build_cleanup (temp));
+ DECL_INITIAL (temp) = exp;
+ cp_finish_decl (temp, exp, NULL_TREE, 0, LOOKUP_ONLYCONVERTING);
exp = temp;
}
#endif
@@ -1060,6 +1050,10 @@ expand_throw (exp)
exp = ptr;
}
+ /* Cast EXP to `void *' so that it will match the prototype for
+ __cp_push_exception. */
+ exp = convert (ptr_type_node, exp);
+
if (cleanup == NULL_TREE)
{
cleanup = build_int_2 (0, 0);
@@ -1087,10 +1081,10 @@ expand_throw (exp)
DECL_ARTIFICIAL (fn) = 1;
pushdecl_top_level (fn);
make_function_rtl (fn);
- assemble_external (fn);
pop_obstacks ();
}
+ mark_used (fn);
e = expr_tree_cons (NULL_TREE, exp, expr_tree_cons
(NULL_TREE, throw_type, expr_tree_cons
(NULL_TREE, cleanup, NULL_TREE)));
@@ -1118,10 +1112,10 @@ expand_throw (exp)
DECL_ARTIFICIAL (fn) = 1;
pushdecl_top_level (fn);
make_function_rtl (fn);
- assemble_external (fn);
pop_obstacks ();
}
+ mark_used (fn);
exp = build_function_call (fn, NULL_TREE);
expand_expr (exp, const0_rtx, VOIDmode, EXPAND_NORMAL);
}
diff --git a/gcc/cp/exception.cc b/gcc/cp/exception.cc
index 05b431521cc..8e8f35f50db 100644
--- a/gcc/cp/exception.cc
+++ b/gcc/cp/exception.cc
@@ -1,5 +1,5 @@
// Functions for Exception Support for -*- C++ -*-
-// Copyright (C) 1994, 1995, 1996, 1998 Free Software Foundation
+// Copyright (C) 1994, 95-97, 1998 Free Software Foundation
// This file is part of GNU CC.
@@ -30,6 +30,7 @@
#include "typeinfo"
#include "exception"
#include <stddef.h>
+#include "gansidecl.h" /* Needed to support macros used in eh-common.h. */
#include "eh-common.h"
/* Define terminate, unexpected, set_terminate, set_unexpected as
@@ -116,13 +117,29 @@ __cp_exception_info (void)
return &((*__get_eh_info ())->value);
}
-/* Compiler hook to return a pointer to the info for the current exception.
+#define CP_EH_INFO ((cp_eh_info *) *__get_eh_info ())
+
+/* Old Compiler hook to return a pointer to the info for the current exception.
Used by get_eh_info (). */
extern "C" cp_eh_info *
__cp_eh_info (void)
{
- return *__get_eh_info ();
+ cp_eh_info *p = CP_EH_INFO;
+ return p;
+}
+
+/* Compiler hook to return a pointer to the info for the current exception,
+ Set the caught bit, and increment the number of handlers that are
+ looking at this exception. This makes handlers smaller. */
+
+extern "C" cp_eh_info *
+__start_cp_handler (void)
+{
+ cp_eh_info *p = CP_EH_INFO;
+ p->caught = 1;
+ p->handlers++;
+ return p;
}
/* Allocate a buffer for a cp_eh_info and an exception object of size SIZE,
@@ -233,7 +250,7 @@ __cp_pop_exception (cp_eh_info *p)
p->cleanup (p->value, 2);
if (! __is_pointer (p->type))
- __eh_free (p->value);
+ __eh_free (p->original_value); // value may have been co-erced.
__eh_free (p);
}
@@ -241,7 +258,7 @@ __cp_pop_exception (cp_eh_info *p)
extern "C" void
__uncatch_exception (void)
{
- cp_eh_info *p = __cp_eh_info ();
+ cp_eh_info *p = CP_EH_INFO;
if (p == 0)
terminate ();
p->caught = false;
@@ -262,7 +279,7 @@ __uncatch_exception (void)
extern "C" void
__check_eh_spec (int n, const void **spec)
{
- cp_eh_info *p = __cp_eh_info ();
+ cp_eh_info *p = CP_EH_INFO;
for (int i = 0; i < n; ++i)
{
@@ -315,7 +332,7 @@ __throw_bad_typeid (void)
bool
std::uncaught_exception ()
{
- cp_eh_info *p = __cp_eh_info ();
+ cp_eh_info *p = CP_EH_INFO;
return p && ! p->caught;
}
diff --git a/gcc/cp/expr.c b/gcc/cp/expr.c
index 056f4d1f16a..22dd0751319 100644
--- a/gcc/cp/expr.c
+++ b/gcc/cp/expr.c
@@ -1,6 +1,6 @@
/* Convert language-specific tree expression to rtl instructions,
for GNU compiler.
- Copyright (C) 1988, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
+ Copyright (C) 1988, 92-97, 1998 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -188,10 +188,16 @@ cplus_expand_expr (exp, target, tmode, modifier)
}
else
{
- /* We don't yet handle pointer-to-member functions this
- way. */
- my_friendly_abort (0);
- return 0;
+ tree delta;
+ tree idx;
+ tree pfn;
+ tree delta2;
+
+ expand_ptrmemfunc_cst (exp, &delta, &idx, &pfn, &delta2);
+
+ return expand_expr (build_ptrmemfunc1 (type, delta, idx,
+ pfn, delta2),
+ target, tmode, modifier);
}
}
diff --git a/gcc/cp/friend.c b/gcc/cp/friend.c
index acb9657d666..2a69acd8d84 100644
--- a/gcc/cp/friend.c
+++ b/gcc/cp/friend.c
@@ -1,5 +1,5 @@
/* Help friends in C++.
- Copyright (C) 1997 Free Software Foundation, Inc.
+ Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -32,6 +32,8 @@ static void add_friends PROTO((tree, tree, tree));
/* Friend data structures are described in cp-tree.h. */
+/* Returns non-zero if SUPPLICANT is a friend of TYPE. */
+
int
is_friend (type, supplicant)
tree type, supplicant;
@@ -59,12 +61,12 @@ is_friend (type, supplicant)
for (; list ; list = TREE_CHAIN (list))
{
- if (name == TREE_PURPOSE (list))
+ if (name == FRIEND_NAME (list))
{
- tree friends = TREE_VALUE (list);
+ tree friends = FRIEND_DECLS (list);
for (; friends ; friends = TREE_CHAIN (friends))
{
- if (comptypes (ctype, TREE_PURPOSE (friends), 1))
+ if (same_type_p (ctype, TREE_PURPOSE (friends)))
return 1;
if (TREE_VALUE (friends) == NULL_TREE)
@@ -86,8 +88,8 @@ is_friend (type, supplicant)
FUNCTION_MEMBER_P bit can go. */
if ((flag_guiding_decls
|| DECL_FUNCTION_MEMBER_P (supplicant))
- && comptypes (TREE_TYPE (supplicant),
- TREE_TYPE (TREE_VALUE (friends)), 1))
+ && same_type_p (TREE_TYPE (supplicant),
+ TREE_TYPE (TREE_VALUE (friends))))
return 1;
if (TREE_CODE (TREE_VALUE (friends)) == TEMPLATE_DECL
@@ -112,7 +114,7 @@ is_friend (type, supplicant)
if (TREE_CODE (t) == TEMPLATE_DECL ?
is_specialization_of (TYPE_MAIN_DECL (supplicant), t) :
- comptypes (supplicant, t, 1))
+ same_type_p (supplicant, t))
return 1;
}
}
@@ -146,11 +148,13 @@ add_friend (type, decl)
tree list = DECL_FRIENDLIST (typedecl);
tree name = DECL_NAME (decl);
+ type = TREE_TYPE (typedecl);
+
while (list)
{
- if (name == TREE_PURPOSE (list))
+ if (name == FRIEND_NAME (list))
{
- tree friends = TREE_VALUE (list);
+ tree friends = FRIEND_DECLS (list);
for (; friends ; friends = TREE_CHAIN (friends))
{
if (decl == TREE_VALUE (friends))
@@ -168,21 +172,13 @@ add_friend (type, decl)
}
list = TREE_CHAIN (list);
}
+
DECL_FRIENDLIST (typedecl)
= tree_cons (DECL_NAME (decl), build_tree_list (error_mark_node, decl),
DECL_FRIENDLIST (typedecl));
- if (DECL_NAME (decl) == ansi_opname[(int) MODIFY_EXPR])
- {
- tree parmtypes = TYPE_ARG_TYPES (TREE_TYPE (decl));
- TYPE_HAS_ASSIGNMENT (TREE_TYPE (typedecl)) = 1;
- if (parmtypes && TREE_CHAIN (parmtypes))
- {
- tree parmtype = TREE_VALUE (TREE_CHAIN (parmtypes));
- if (TREE_CODE (parmtype) == REFERENCE_TYPE
- && TREE_TYPE (parmtypes) == TREE_TYPE (typedecl))
- TYPE_HAS_ASSIGN_REF (TREE_TYPE (typedecl)) = 1;
- }
- }
+ DECL_BEFRIENDING_CLASSES (decl)
+ = tree_cons (NULL_TREE, type,
+ DECL_BEFRIENDING_CLASSES (decl));
}
/* Declare that every member function NAME in FRIEND_TYPE
@@ -197,9 +193,9 @@ add_friends (type, name, friend_type)
while (list)
{
- if (name == TREE_PURPOSE (list))
+ if (name == FRIEND_NAME (list))
{
- tree friends = TREE_VALUE (list);
+ tree friends = FRIEND_DECLS (list);
while (friends && TREE_PURPOSE (friends) != friend_type)
friends = TREE_CHAIN (friends);
if (friends)
@@ -224,13 +220,6 @@ add_friends (type, name, friend_type)
= tree_cons (name,
build_tree_list (friend_type, NULL_TREE),
DECL_FRIENDLIST (typedecl));
- if (! strncmp (IDENTIFIER_POINTER (name),
- IDENTIFIER_POINTER (ansi_opname[(int) MODIFY_EXPR]),
- strlen (IDENTIFIER_POINTER (ansi_opname[(int) MODIFY_EXPR]))))
- {
- TYPE_HAS_ASSIGNMENT (TREE_TYPE (typedecl)) = 1;
- sorry ("declaring \"friend operator =\" will not find \"operator = (X&)\" if it exists");
- }
}
/* Make FRIEND_TYPE a friend class to TYPE. If FRIEND_TYPE has already
@@ -255,14 +244,14 @@ make_friend_class (type, friend_type)
error ("`friend' declaration in signature definition");
return;
}
- if (IS_SIGNATURE (friend_type))
+ if (IS_SIGNATURE (friend_type) || ! IS_AGGR_TYPE (friend_type))
{
- error ("signature type `%s' declared `friend'",
- IDENTIFIER_POINTER (TYPE_IDENTIFIER (friend_type)));
+ cp_error ("invalid type `%T' declared `friend'", friend_type);
return;
}
- if (CLASSTYPE_TEMPLATE_SPECIALIZATION (friend_type)
+ if (CLASS_TYPE_P (friend_type)
+ && CLASSTYPE_TEMPLATE_SPECIALIZATION (friend_type)
&& uses_template_parms (friend_type))
{
/* [temp.friend]
@@ -279,7 +268,7 @@ make_friend_class (type, friend_type)
friends with itself; this means that each instantiation is
friends with all other instantiations. */
is_template_friend = 1;
- else if (comptypes (type, friend_type, 1))
+ else if (same_type_p (type, friend_type))
{
pedwarn ("class `%s' is implicitly friends with itself",
TYPE_NAME_STRING (type));
@@ -298,7 +287,7 @@ make_friend_class (type, friend_type)
/* Stop if we find the same type on the list. */
&& !(TREE_CODE (TREE_VALUE (classes)) == TEMPLATE_DECL ?
friend_type == TREE_VALUE (classes) :
- comptypes (TREE_VALUE (classes), friend_type, 1)))
+ same_type_p (TREE_VALUE (classes), friend_type)))
classes = TREE_CHAIN (classes);
if (classes)
cp_warning ("`%T' is already a friend of `%T'",
@@ -307,6 +296,11 @@ make_friend_class (type, friend_type)
{
CLASSTYPE_FRIEND_CLASSES (type)
= tree_cons (NULL_TREE, friend_type, CLASSTYPE_FRIEND_CLASSES (type));
+ if (is_template_friend)
+ friend_type = TREE_TYPE (friend_type);
+ CLASSTYPE_BEFRIENDING_CLASSES (friend_type)
+ = tree_cons (NULL_TREE, type,
+ CLASSTYPE_BEFRIENDING_CLASSES (friend_type));
}
}
@@ -371,16 +365,20 @@ do_friend (ctype, declarator, decl, parmdecls, flags, quals, funcdef_flag)
if (is_friend_template)
decl = DECL_TI_TEMPLATE (push_template_decl (decl));
-
+ else if (template_class_depth (current_class_type))
+ decl = push_template_decl_real (decl, /*is_friend=*/1);
+
+ /* We can't do lookup in a type that involves template
+ parameters. Instead, we rely on tsubst_friend_function
+ to check the validity of the declaration later. */
+ if (uses_template_parms (ctype))
+ add_friend (current_class_type, decl);
/* A nested class may declare a member of an enclosing class
to be a friend, so we do lookup here even if CTYPE is in
the process of being defined. */
- if (TYPE_SIZE (ctype) != 0 || TYPE_BEING_DEFINED (ctype))
+ else if (TYPE_SIZE (ctype) != 0 || TYPE_BEING_DEFINED (ctype))
{
- /* But, we defer looup in template specializations until
- they are fully specialized. */
- if (template_class_depth (ctype) == 0)
- decl = check_classfn (ctype, decl);
+ decl = check_classfn (ctype, decl);
if (decl)
add_friend (current_class_type, decl);
@@ -405,20 +403,6 @@ do_friend (ctype, declarator, decl, parmdecls, flags, quals, funcdef_flag)
decl = void_type_node;
}
}
- else if (TREE_CODE (decl) == FUNCTION_DECL
- && (MAIN_NAME_P (declarator)
- || (IDENTIFIER_LENGTH (declarator) > 10
- && IDENTIFIER_POINTER (declarator)[0] == '_'
- && IDENTIFIER_POINTER (declarator)[1] == '_'
- && strncmp (IDENTIFIER_POINTER (declarator)+2,
- "builtin_", 8) == 0)))
- {
- /* raw "main", and builtin functions never gets overloaded,
- but they can become friends. */
- add_friend (current_class_type, decl);
- DECL_FRIEND_P (decl) = 1;
- decl = void_type_node;
- }
/* A global friend.
@@ or possibly a friend from a base class ?!? */
else if (TREE_CODE (decl) == FUNCTION_DECL)
@@ -428,7 +412,6 @@ do_friend (ctype, declarator, decl, parmdecls, flags, quals, funcdef_flag)
Note that because classes all wind up being top-level
in their scope, their friend wind up in top-level scope as well. */
- set_mangled_name_for_decl (decl);
DECL_ARGUMENTS (decl) = parmdecls;
if (funcdef_flag)
DECL_CLASS_CONTEXT (decl) = current_class_type;
diff --git a/gcc/cp/g++spec.c b/gcc/cp/g++spec.c
index 22060cd222d..806b90ea96f 100644
--- a/gcc/cp/g++spec.c
+++ b/gcc/cp/g++spec.c
@@ -1,5 +1,5 @@
/* Specific flags and argument handling of the C++ front-end.
- Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+ Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -19,11 +19,8 @@ the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include "config.h"
-
#include "system.h"
-#include "gansidecl.h"
-
/* This bit is set if we saw a `-xfoo' language specification. */
#define LANGSPEC (1<<1)
/* This bit is set if they did `-lm' or `-lmath'. */
@@ -35,7 +32,9 @@ Boston, MA 02111-1307, USA. */
#define MATH_LIBRARY "-lm"
#endif
-extern char *xmalloc PROTO((size_t));
+#ifndef LIBSTDCXX
+#define LIBSTDCXX "-lstdc++"
+#endif
void
lang_specific_driver (fn, in_argc, in_argv, in_added_libraries)
@@ -237,7 +236,7 @@ lang_specific_driver (fn, in_argc, in_argv, in_added_libraries)
/* Add `-lstdc++' if we haven't already done so. */
if (library)
{
- arglist[j++] = "-lstdc++";
+ arglist[j++] = LIBSTDCXX;
added_libraries++;
}
if (saw_math)
diff --git a/gcc/cp/gxx.gperf b/gcc/cp/gxx.gperf
index 868dfc426f0..5632f7f34a5 100644
--- a/gcc/cp/gxx.gperf
+++ b/gcc/cp/gxx.gperf
@@ -22,6 +22,8 @@ __label__, LABEL, NORID
__null, CONSTANT, RID_NULL
__real, REALPART, NORID
__real__, REALPART, NORID
+__restrict, CV_QUALIFIER, RID_RESTRICT
+__restrict__, CV_QUALIFIER, RID_RESTRICT
__signature__, AGGR, RID_SIGNATURE /* Extension */,
__signed, TYPESPEC, RID_SIGNED
__signed__, TYPESPEC, RID_SIGNED
diff --git a/gcc/cp/gxxint.texi b/gcc/cp/gxxint.texi
index c8f312ebfca..2f379052877 100644
--- a/gcc/cp/gxxint.texi
+++ b/gcc/cp/gxxint.texi
@@ -23,7 +23,6 @@ Questions and comments to Benjamin Kosnik @code{<bkoz@@cygnus.com>}.
* Access Control::
* Error Reporting::
* Parser::
-* Copying Objects::
* Exception Handling::
* Free Store::
* Mangling:: Function name mangling for C++ and Java
@@ -931,7 +930,7 @@ To have the line number on the error message indicate the line of the
DECL, use @code{cp_error_at} and its ilk; to indicate which argument you want,
use @code{%+D}, or it will default to the first.
-@node Parser, Copying Objects, Error Reporting, Top
+@node Parser, Exception Handling, Error Reporting, Top
@section Parser
Some comments on the parser:
@@ -1022,33 +1021,7 @@ conflicts.
Unlike the others, this ambiguity is not recognized by the Working Paper.
-@node Copying Objects, Exception Handling, Parser, Top
-@section Copying Objects
-
-The generated copy assignment operator in g++ does not currently do the
-right thing for multiple inheritance involving virtual bases; it just
-calls the copy assignment operators for its direct bases. What it
-should probably do is:
-
-1) Split up the copy assignment operator for all classes that have
-vbases into "copy my vbases" and "copy everything else" parts. Or do
-the trickiness that the constructors do to ensure that vbases don't get
-initialized by intermediate bases.
-
-2) Wander through the class lattice, find all vbases for which no
-intermediate base has a user-defined copy assignment operator, and call
-their "copy everything else" routines. If not all of my vbases satisfy
-this criterion, warn, because this may be surprising behavior.
-
-3) Call the "copy everything else" routine for my direct bases.
-
-If we only have one direct base, we can just foist everything off onto
-them.
-
-This issue is currently under discussion in the core reflector
-(2/28/94).
-
-@node Exception Handling, Free Store, Copying Objects, Top
+@node Exception Handling, Free Store, Parser, Top
@section Exception Handling
Note, exception handling in g++ is still under development.
@@ -1595,18 +1568,18 @@ as @samp{P} followed by the mangling of the class name.
@subsection Squangled type compression
-Squangling (enabled with the @samp{-fsquangle} option), utilizes
-the @samp{B} code to indicate reuse of a previously
-seen type within an indentifier. Types are recognized in a left to
-right manner and given increasing values, which are
-appended to the code in the standard manner. Ie, multiple digit numbers
-are delimited by @samp{_} characters. A type is considered to be any
-non primitive type, regardless of whether its a parameter, template
-parameter, or entire template. Certain codes are considered modifiers
-of a type, and are not included as part of the type. These are the
-@samp{C}, @samp{V}, @samp{P}, @samp{A}, @samp{R}, and @samp{U} codes,
-denoting constant, volatile, pointer, array, reference, and unsigned.
-These codes may precede a @samp{B} type in order to make the required
+Squangling (enabled with the @samp{-fsquangle} option), utilizes the
+@samp{B} code to indicate reuse of a previously seen type within an
+indentifier. Types are recognized in a left to right manner and given
+increasing values, which are appended to the code in the standard
+manner. Ie, multiple digit numbers are delimited by @samp{_}
+characters. A type is considered to be any non primitive type,
+regardless of whether its a parameter, template parameter, or entire
+template. Certain codes are considered modifiers of a type, and are not
+included as part of the type. These are the @samp{C}, @samp{V},
+@samp{P}, @samp{A}, @samp{R}, @samp{U} and @samp{u} codes, denoting
+constant, volatile, pointer, array, reference, unsigned, and restrict.
+These codes may precede a @samp{B} type in order to make the required
modifications to the type.
For example:
@@ -1783,12 +1756,21 @@ Used by squangling to compress qualified names.
@item l
Encodes the C++ @code{long} type.
+@item n
+Immediate repeated type. Followed by the repeat count.
+
+@item N
+Repeated type. Followed by the repeat count of the repeated type,
+followed by the type index of the repeated type. Due to a bug in
+g++ 2.7.2, this is only generated if index is 0. Superceded by
+@samp{n} when squangling.
+
@item P
Indicates a pointer type. Followed by the type pointed to.
@item Q
Used to mangle qualified names, which arise from nested classes.
-Should also be used for namespaces (?).
+Also used for namespaces.
In Java used to mangle package-qualified names, and inner classes.
@item r
@@ -1817,11 +1799,14 @@ A modifier that indicates that the following integer type is unsigned.
Also used to indicate that the following class or namespace name
is encoded using Unicode-mangling.
+@item u
+The @code{restrict} type qualifier.
+
@item v
Encodes the C++ and Java @code{void} types.
@item V
-A modified for a @code{const} type or method.
+A modifier for a @code{volatile} type or method.
@item w
Encodes the C++ @code{wchar_t} type, and the Java @code{char} types.
diff --git a/gcc/cp/hash.h b/gcc/cp/hash.h
index 21ebdd7901e..71c2f317ffe 100644
--- a/gcc/cp/hash.h
+++ b/gcc/cp/hash.h
@@ -1,14 +1,14 @@
/* KR-C code produced by gperf version 2.7.1 (19981006 egcs) */
-/* Command-line: gperf -L KR-C -F , 0, 0 -p -j1 -g -o -t -N is_reserved_word -k1,4,7,$ ./gxx.gperf */
+/* Command-line: gperf -L KR-C -F , 0, 0 -p -j1 -g -o -t -N is_reserved_word -k1,4,7,$ ../../../gcc/cp/gxx.gperf */
/* Command-line: gperf -L KR-C -F ', 0, 0' -p -j1 -g -o -t -N is_reserved_word -k1,4,$,7 gplus.gperf */
struct resword { char *name; short token; enum rid rid;};
-#define TOTAL_KEYWORDS 104
+#define TOTAL_KEYWORDS 106
#define MIN_WORD_LENGTH 2
#define MAX_WORD_LENGTH 16
#define MIN_HASH_VALUE 4
-#define MAX_HASH_VALUE 261
-/* maximum key range = 258, duplicates = 0 */
+#define MAX_HASH_VALUE 250
+/* maximum key range = 247, duplicates = 0 */
#ifdef __GNUC__
__inline
@@ -18,34 +18,34 @@ hash (str, len)
register char *str;
register unsigned int len;
{
- static unsigned short asso_values[] =
+ static unsigned char asso_values[] =
{
- 262, 262, 262, 262, 262, 262, 262, 262, 262, 262,
- 262, 262, 262, 262, 262, 262, 262, 262, 262, 262,
- 262, 262, 262, 262, 262, 262, 262, 262, 262, 262,
- 262, 262, 262, 262, 262, 262, 262, 262, 262, 262,
- 262, 262, 262, 262, 262, 262, 262, 262, 262, 262,
- 262, 262, 262, 262, 262, 262, 262, 262, 262, 262,
- 262, 262, 262, 262, 262, 262, 262, 262, 262, 262,
- 262, 262, 262, 262, 262, 262, 262, 262, 262, 262,
- 262, 262, 262, 262, 262, 262, 262, 262, 262, 262,
- 262, 262, 262, 262, 262, 0, 262, 87, 25, 96,
- 60, 0, 55, 7, 4, 41, 262, 2, 15, 49,
- 14, 63, 32, 29, 3, 23, 6, 8, 2, 2,
- 0, 7, 262, 262, 262, 262, 262, 262, 262, 262,
- 262, 262, 262, 262, 262, 262, 262, 262, 262, 262,
- 262, 262, 262, 262, 262, 262, 262, 262, 262, 262,
- 262, 262, 262, 262, 262, 262, 262, 262, 262, 262,
- 262, 262, 262, 262, 262, 262, 262, 262, 262, 262,
- 262, 262, 262, 262, 262, 262, 262, 262, 262, 262,
- 262, 262, 262, 262, 262, 262, 262, 262, 262, 262,
- 262, 262, 262, 262, 262, 262, 262, 262, 262, 262,
- 262, 262, 262, 262, 262, 262, 262, 262, 262, 262,
- 262, 262, 262, 262, 262, 262, 262, 262, 262, 262,
- 262, 262, 262, 262, 262, 262, 262, 262, 262, 262,
- 262, 262, 262, 262, 262, 262, 262, 262, 262, 262,
- 262, 262, 262, 262, 262, 262, 262, 262, 262, 262,
- 262, 262, 262, 262, 262, 262
+ 251, 251, 251, 251, 251, 251, 251, 251, 251, 251,
+ 251, 251, 251, 251, 251, 251, 251, 251, 251, 251,
+ 251, 251, 251, 251, 251, 251, 251, 251, 251, 251,
+ 251, 251, 251, 251, 251, 251, 251, 251, 251, 251,
+ 251, 251, 251, 251, 251, 251, 251, 251, 251, 251,
+ 251, 251, 251, 251, 251, 251, 251, 251, 251, 251,
+ 251, 251, 251, 251, 251, 251, 251, 251, 251, 251,
+ 251, 251, 251, 251, 251, 251, 251, 251, 251, 251,
+ 251, 251, 251, 251, 251, 251, 251, 251, 251, 251,
+ 251, 251, 251, 251, 251, 0, 251, 64, 93, 3,
+ 0, 0, 74, 35, 0, 26, 251, 2, 31, 65,
+ 23, 76, 7, 19, 45, 37, 6, 64, 12, 38,
+ 14, 4, 251, 251, 251, 251, 251, 251, 251, 251,
+ 251, 251, 251, 251, 251, 251, 251, 251, 251, 251,
+ 251, 251, 251, 251, 251, 251, 251, 251, 251, 251,
+ 251, 251, 251, 251, 251, 251, 251, 251, 251, 251,
+ 251, 251, 251, 251, 251, 251, 251, 251, 251, 251,
+ 251, 251, 251, 251, 251, 251, 251, 251, 251, 251,
+ 251, 251, 251, 251, 251, 251, 251, 251, 251, 251,
+ 251, 251, 251, 251, 251, 251, 251, 251, 251, 251,
+ 251, 251, 251, 251, 251, 251, 251, 251, 251, 251,
+ 251, 251, 251, 251, 251, 251, 251, 251, 251, 251,
+ 251, 251, 251, 251, 251, 251, 251, 251, 251, 251,
+ 251, 251, 251, 251, 251, 251, 251, 251, 251, 251,
+ 251, 251, 251, 251, 251, 251, 251, 251, 251, 251,
+ 251, 251, 251, 251, 251, 251
};
register int hval = len;
@@ -80,155 +80,145 @@ is_reserved_word (str, len)
{"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0},
{"else", ELSE, NORID,},
{"", 0, 0},
- {"xor", '^', NORID,},
- {"", 0, 0},
+ {"delete", DELETE, NORID,},
+ {"case", CASE, NORID,},
{"__real__", REALPART, NORID},
{"", 0, 0},
{"true", CXX_TRUE, NORID,},
- {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0},
+ {"catch", CATCH, NORID,},
+ {"typeid", TYPEID, NORID,},
{"try", TRY, NORID,},
{"", 0, 0}, {"", 0, 0},
- {"new", NEW, NORID,},
+ {"void", TYPESPEC, RID_VOID,},
+ {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0},
+ {"private", VISSPEC, RID_PRIVATE,},
+ {"template", TEMPLATE, RID_TEMPLATE,},
+ {"protected", VISSPEC, RID_PROTECTED,},
{"extern", SCSPEC, RID_EXTERN,},
- {"__real", REALPART, NORID},
- {"while", WHILE, NORID,},
+ {"", 0, 0}, {"", 0, 0},
{"not", '!', NORID,},
- {"", 0, 0}, {"", 0, 0}, {"", 0, 0},
- {"__extension__", EXTENSION, NORID},
{"", 0, 0},
- {"__null", CONSTANT, RID_NULL},
- {"__asm__", ASM_KEYWORD, NORID},
- {"return", RETURN, NORID,},
+ {"__signed", TYPESPEC, RID_SIGNED},
+ {"int", TYPESPEC, RID_INT,},
+ {"__signed__", TYPESPEC, RID_SIGNED},
+ {"__real", REALPART, NORID},
{"", 0, 0},
- {"long", TYPESPEC, RID_LONG,},
- {"using", USING, NORID,},
{"xor_eq", ASSIGN, NORID,},
- {"__inline", SCSPEC, RID_INLINE},
- {"short", TYPESPEC, RID_SHORT,},
- {"__inline__", SCSPEC, RID_INLINE},
+ {"", 0, 0}, {"", 0, 0}, {"", 0, 0},
+ {"__attribute", ATTRIBUTE, NORID},
+ {"__asm__", ASM_KEYWORD, NORID},
+ {"__attribute__", ATTRIBUTE, NORID},
+ {"compl", '~', NORID,},
+ {"public", VISSPEC, RID_PUBLIC,},
+ {"not_eq", EQCOMPARE, NORID,},
{"switch", SWITCH, NORID,},
- {"__alignof__", ALIGNOF, NORID},
- {"private", VISSPEC, RID_PRIVATE,},
- {"reinterpret_cast", REINTERPRET_CAST, NORID,},
- {"struct", AGGR, RID_RECORD,},
+ {"__extension__", EXTENSION, NORID},
+ {"const", CV_QUALIFIER, RID_CONST,},
+ {"static", SCSPEC, RID_STATIC,},
{"", 0, 0},
- {"virtual", SCSPEC, RID_VIRTUAL,},
+ {"__inline", SCSPEC, RID_INLINE},
+ {"", 0, 0},
+ {"__inline__", SCSPEC, RID_INLINE},
+ {"__restrict__", CV_QUALIFIER, RID_RESTRICT},
+ {"inline", SCSPEC, RID_INLINE,},
+ {"const_cast", CONST_CAST, NORID,},
{"static_cast", STATIC_CAST, NORID,},
- {"", 0, 0}, {"", 0, 0},
- {"not_eq", EQCOMPARE, NORID,},
- {"int", TYPESPEC, RID_INT,},
- {"__signed__", TYPESPEC, RID_SIGNED},
- {"template", TEMPLATE, RID_TEMPLATE,},
+ {"__restrict", CV_QUALIFIER, RID_RESTRICT},
+ {"xor", '^', NORID,},
+ {"__wchar_t", TYPESPEC, RID_WCHAR /* Unique to ANSI C++ */,},
+ {"new", NEW, NORID,},
+ {"__alignof__", ALIGNOF, NORID},
+ {"signed", TYPESPEC, RID_SIGNED,},
+ {"and", ANDAND, NORID,},
+ {"", 0, 0}, {"", 0, 0}, {"", 0, 0},
+ {"explicit", SCSPEC, RID_EXPLICIT,},
{"", 0, 0},
- {"signature", AGGR, RID_SIGNATURE /* Extension */,},
- {"register", SCSPEC, RID_REGISTER,},
- {"this", THIS, NORID,},
{"__imag__", IMAGPART, NORID},
- {"__attribute", ATTRIBUTE, NORID},
- {"bool", TYPESPEC, RID_BOOL,},
- {"__attribute__", ATTRIBUTE, NORID},
- {"for", FOR, NORID,},
- {"__imag", IMAGPART, NORID},
+ {"while", WHILE, NORID,},
+ {"", 0, 0}, {"", 0, 0}, {"", 0, 0},
+ {"do", DO, NORID,},
{"typename", TYPENAME_KEYWORD, NORID,},
- {"", 0, 0}, {"", 0, 0},
- {"delete", DELETE, NORID,},
+ {"friend", SCSPEC, RID_FRIEND,},
+ {"continue", CONTINUE, NORID,},
+ {"class", AGGR, RID_CLASS,},
+ {"default", DEFAULT, NORID,},
+ {"this", THIS, NORID,},
+ {"dynamic_cast", DYNAMIC_CAST, NORID,},
{"typeof", TYPEOF, NORID,},
- {"or", OROR, NORID,},
- {"", 0, 0},
- {"explicit", SCSPEC, RID_EXPLICIT,},
- {"", 0, 0},
- {"typeid", TYPEID, NORID,},
- {"", 0, 0}, {"", 0, 0},
+ {"virtual", SCSPEC, RID_VIRTUAL,},
{"export", SCSPEC, RID_EXPORT,},
- {"throw", THROW, NORID,},
- {"__asm", ASM_KEYWORD, NORID},
+ {"and_eq", ASSIGN, NORID,},
+ {"__typeof__", TYPEOF, NORID},
{"__const__", CV_QUALIFIER, RID_CONST},
{"__volatile", CV_QUALIFIER, RID_VOLATILE},
- {"__typeof__", TYPEOF, NORID},
+ {"short", TYPESPEC, RID_SHORT,},
{"__volatile__", CV_QUALIFIER, RID_VOLATILE},
{"__const", CV_QUALIFIER, RID_CONST},
- {"false", CXX_FALSE, NORID,},
- {"sizeof", SIZEOF, NORID,},
- {"", 0, 0}, {"", 0, 0},
- {"__complex", TYPESPEC, RID_COMPLEX},
- {"inline", SCSPEC, RID_INLINE,},
- {"__complex__", TYPESPEC, RID_COMPLEX},
- {"union", AGGR, RID_UNION,},
+ {"namespace", NAMESPACE, NORID,},
+ {"char", TYPESPEC, RID_CHAR,},
+ {"unsigned", TYPESPEC, RID_UNSIGNED,},
{"double", TYPESPEC, RID_DOUBLE,},
- {"", 0, 0},
- {"__alignof", ALIGNOF, NORID},
- {"", 0, 0}, {"", 0, 0},
- {"bitor", '|', NORID,},
{"or_eq", ASSIGN, NORID,},
+ {"__null", CONSTANT, RID_NULL},
{"if", IF, NORID,},
- {"", 0, 0},
- {"case", CASE, NORID,},
- {"", 0, 0},
- {"enum", ENUM, NORID,},
- {"signed", TYPESPEC, RID_SIGNED,},
- {"", 0, 0},
- {"__sigof__", SIGOF, NORID /* Extension */,},
- {"char", TYPESPEC, RID_CHAR,},
- {"", 0, 0}, {"", 0, 0},
- {"__signed", TYPESPEC, RID_SIGNED},
- {"namespace", NAMESPACE, NORID,},
+ {"__signature__", AGGR, RID_SIGNATURE /* Extension */,},
{"__label__", LABEL, NORID},
- {"volatile", CV_QUALIFIER, RID_VOLATILE,},
- {"protected", VISSPEC, RID_PROTECTED,},
- {"__wchar_t", TYPESPEC, RID_WCHAR /* Unique to ANSI C++ */,},
- {"", 0, 0}, {"", 0, 0},
- {"unsigned", TYPESPEC, RID_UNSIGNED,},
- {"continue", CONTINUE, NORID,},
- {"break", BREAK, NORID,},
- {"", 0, 0},
- {"friend", SCSPEC, RID_FRIEND,},
- {"and_eq", ASSIGN, NORID,},
- {"typedef", SCSPEC, RID_TYPEDEF,},
+ {"long", TYPESPEC, RID_LONG,},
+ {"__imag", IMAGPART, NORID},
+ {"__asm", ASM_KEYWORD, NORID},
{"", 0, 0},
- {"do", DO, NORID,},
- {"void", TYPESPEC, RID_VOID,},
+ {"__sigof__", SIGOF, NORID /* Extension */,},
{"", 0, 0}, {"", 0, 0}, {"", 0, 0},
- {"const", CV_QUALIFIER, RID_CONST,},
- {"static", SCSPEC, RID_STATIC,},
+ {"struct", AGGR, RID_RECORD,},
{"", 0, 0},
- {"__typeof", TYPEOF, NORID},
+ {"volatile", CV_QUALIFIER, RID_VOLATILE,},
+ {"false", CXX_FALSE, NORID,},
+ {"sizeof", SIZEOF, NORID,},
+ {"__complex__", TYPESPEC, RID_COMPLEX},
{"", 0, 0}, {"", 0, 0}, {"", 0, 0},
- {"goto", GOTO, NORID,},
+ {"for", FOR, NORID,},
+ {"or", OROR, NORID,},
+ {"register", SCSPEC, RID_REGISTER,},
+ {"throw", THROW, NORID,},
{"", 0, 0},
- {"asm", ASM_KEYWORD, NORID,},
- {"operator", OPERATOR, NORID,},
- {"__signature__", AGGR, RID_SIGNATURE /* Extension */,},
+ {"using", USING, NORID,},
+ {"", 0, 0}, {"", 0, 0},
+ {"__complex", TYPESPEC, RID_COMPLEX},
{"", 0, 0},
+ {"asm", ASM_KEYWORD, NORID,},
+ {"signature", AGGR, RID_SIGNATURE /* Extension */,},
+ {"enum", ENUM, NORID,},
+ {"reinterpret_cast", REINTERPRET_CAST, NORID,},
{"mutable", SCSPEC, RID_MUTABLE,},
- {"", 0, 0}, {"", 0, 0},
- {"sigof", SIGOF, NORID /* Extension */,},
- {"class", AGGR, RID_CLASS,},
- {"compl", '~', NORID,},
- {"public", VISSPEC, RID_PUBLIC,},
- {"and", ANDAND, NORID,},
- {"", 0, 0}, {"", 0, 0},
- {"float", TYPESPEC, RID_FLOAT,},
+ {"__alignof", ALIGNOF, NORID},
+ {"return", RETURN, NORID,},
{"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0},
- {"", 0, 0}, {"", 0, 0}, {"", 0, 0},
- {"default", DEFAULT, NORID,},
+ {"", 0, 0},
+ {"float", TYPESPEC, RID_FLOAT,},
{"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0},
- {"", 0, 0}, {"", 0, 0},
+ {"bool", TYPESPEC, RID_BOOL,},
+ {"", 0, 0},
+ {"typedef", SCSPEC, RID_TYPEDEF,},
+ {"__typeof", TYPEOF, NORID},
{"bitand", '&', NORID,},
+ {"break", BREAK, NORID,},
+ {"", 0, 0}, {"", 0, 0}, {"", 0, 0},
+ {"union", AGGR, RID_UNION,},
{"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0},
{"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0},
{"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0},
- {"catch", CATCH, NORID,},
+ {"goto", GOTO, NORID,},
+ {"sigof", SIGOF, NORID /* Extension */,},
{"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0},
- {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0},
- {"auto", SCSPEC, RID_AUTO,},
{"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0},
- {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0},
- {"const_cast", CONST_CAST, NORID,},
+ {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0},
+ {"bitor", '|', NORID,},
+ {"auto", SCSPEC, RID_AUTO,},
{"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0},
{"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0},
{"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0},
{"", 0, 0}, {"", 0, 0},
- {"dynamic_cast", DYNAMIC_CAST, NORID,}
+ {"operator", OPERATOR, NORID,}
};
if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
diff --git a/gcc/cp/inc/exception b/gcc/cp/inc/exception
index b7aa1f42d40..32efb9f82ca 100644
--- a/gcc/cp/inc/exception
+++ b/gcc/cp/inc/exception
@@ -1,5 +1,5 @@
// Exception Handling support header for -*- C++ -*-
-// Copyright (C) 1995, 1996 Free Software Foundation
+// Copyright (C) 1995, 96-97, 1998 Free Software Foundation
#ifndef __EXCEPTION__
#define __EXCEPTION__
diff --git a/gcc/cp/inc/new b/gcc/cp/inc/new
index 93a3231ab69..b66673dc3a6 100644
--- a/gcc/cp/inc/new
+++ b/gcc/cp/inc/new
@@ -1,5 +1,5 @@
// The -*- C++ -*- dynamic memory management header.
-// Copyright (C) 1994, 1996 Free Software Foundation
+// Copyright (C) 1994, 96-97, 1998 Free Software Foundation
#ifndef __NEW__
#define __NEW__
diff --git a/gcc/cp/inc/typeinfo b/gcc/cp/inc/typeinfo
index cf3b521af5e..934784968c5 100644
--- a/gcc/cp/inc/typeinfo
+++ b/gcc/cp/inc/typeinfo
@@ -1,9 +1,11 @@
// RTTI support for -*- C++ -*-
-// Copyright (C) 1994, 1995, 1996 Free Software Foundation
+// Copyright (C) 1994, 95-97, 1998 Free Software Foundation
#ifndef __TYPEINFO__
#define __TYPEINFO__
+#pragma interface "typeinfo"
+
#include <exception>
extern "C++" {
@@ -32,22 +34,11 @@ public:
bool operator!= (const type_info& arg) const;
};
-// We can't rely on common symbols being shared between translation units
-// under Windows. Sigh.
-
-#ifndef _WIN32
-inline bool type_info::
-operator== (const type_info& arg) const
-{
- return &arg == this;
-}
-
inline bool type_info::
operator!= (const type_info& arg) const
{
- return &arg != this;
+ return !operator== (arg);
}
-#endif
class bad_cast : public exception {
public:
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index a5857a10939..f38933b60f4 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -1,5 +1,5 @@
/* Handle initialization things in C++.
- Copyright (C) 1987, 89, 92-96, 1997 Free Software Foundation, Inc.
+ Copyright (C) 1987, 89, 92-98, 1999 Free Software Foundation, Inc.
Contributed by Michael Tiemann (tiemann@cygnus.com)
This file is part of GNU CC.
@@ -34,8 +34,6 @@ Boston, MA 02111-1307, USA. */
#include "toplev.h"
#include "ggc.h"
-extern void compiler_error ();
-
/* In C++, structures with well-defined constructors are initialized by
those constructors, unasked. CURRENT_BASE_INIT_LIST
holds a list of stmts for a BASE_INIT term in the grammar.
@@ -56,12 +54,14 @@ static tree build_vec_delete_1 PROTO((tree, tree, tree, tree, tree,
static void perform_member_init PROTO((tree, tree, tree, int));
static void sort_base_init PROTO((tree, tree *, tree *));
static tree build_builtin_delete_call PROTO((tree));
-static tree build_array_eh_cleanup PROTO((tree, tree, tree));
-static int member_init_ok_or_else PROTO((tree, tree, char *));
+static int member_init_ok_or_else PROTO((tree, tree, const char *));
static void expand_virtual_init PROTO((tree, tree));
static tree sort_member_init PROTO((tree));
static tree build_partial_cleanup_for PROTO((tree));
static tree initializing_context PROTO((tree));
+static void expand_vec_init_try_block PROTO((tree));
+static void expand_vec_init_catch_clause PROTO((tree, tree, tree, tree));
+static tree build_java_class_ref PROTO((tree));
/* Cache the identifier nodes for the magic field of a new cookie. */
static tree nc_nelts_field_id;
@@ -853,7 +853,7 @@ static int
member_init_ok_or_else (field, type, member_name)
tree field;
tree type;
- char *member_name;
+ const char *member_name;
{
if (field == error_mark_node)
return 0;
@@ -903,7 +903,7 @@ expand_member_init (exp, name, init)
if (name && TREE_CODE (name) == TYPE_DECL)
{
- basetype = TREE_TYPE (name);
+ basetype = TYPE_MAIN_VARIANT (TREE_TYPE (name));
name = DECL_NAME (name);
}
@@ -1063,7 +1063,7 @@ expand_aggr_init (exp, init, flags)
/* Must arrange to initialize each element of EXP
from elements of INIT. */
tree itype = init ? TREE_TYPE (init) : NULL_TREE;
- if (TYPE_READONLY (TREE_TYPE (type)) || TYPE_VOLATILE (TREE_TYPE (type)))
+ if (CP_TYPE_QUALS (type) != TYPE_UNQUALIFIED)
{
TREE_TYPE (exp) = TYPE_MAIN_VARIANT (type);
if (init)
@@ -1087,7 +1087,8 @@ expand_aggr_init (exp, init, flags)
return;
}
expand_vec_init (exp, exp, array_type_nelts (type), init,
- init && comptypes (TREE_TYPE (init), TREE_TYPE (exp), 1));
+ init && same_type_p (TREE_TYPE (init),
+ TREE_TYPE (exp)));
TREE_READONLY (exp) = was_const;
TREE_THIS_VOLATILE (exp) = was_volatile;
TREE_TYPE (exp) = type;
@@ -1142,14 +1143,13 @@ expand_default_init (binfo, true_exp, exp, init, flags)
if (true_exp != exp)
abort ();
- /* We special-case TARGET_EXPRs here to avoid an error about
- private copy constructors for temporaries bound to reference vars.
- If the TARGET_EXPR represents a call to a function that has
- permission to create such objects, a reference can bind directly
- to the return value. An object variable must be initialized
- via the copy constructor, even if the call is elided. */
- if (! (TREE_CODE (exp) == VAR_DECL && DECL_ARTIFICIAL (exp)
- && TREE_CODE (init) == TARGET_EXPR && TREE_TYPE (init) == type))
+ if (flags & DIRECT_BIND)
+ /* Do nothing. We hit this in two cases: Reference initialization,
+ where we aren't initializing a real variable, so we don't want
+ to run a new constructor; and catching an exception, where we
+ have already built up the constructor call so we could wrap it
+ in an exception region. */;
+ else
init = ocp_convert (type, init, CONV_IMPLICIT|CONV_FORCE_TEMP, flags);
if (TREE_CODE (init) == TRY_CATCH_EXPR)
@@ -1365,7 +1365,6 @@ build_member_call (type, name, parmlist)
tree t;
tree method_name;
int dtor = 0;
- int dont_use_this = 0;
tree basetype_path, decl;
if (TREE_CODE (name) == TEMPLATE_ID_EXPR
@@ -1387,7 +1386,11 @@ build_member_call (type, name, parmlist)
if (TREE_CODE (name) != TEMPLATE_ID_EXPR)
method_name = name;
else
- method_name = TREE_OPERAND (name, 0);
+ {
+ method_name = TREE_OPERAND (name, 0);
+ if (is_overloaded_fn (method_name))
+ method_name = DECL_NAME (OVL_CURRENT (method_name));
+ }
if (TREE_CODE (method_name) == BIT_NOT_EXPR)
{
@@ -1421,38 +1424,25 @@ build_member_call (type, name, parmlist)
return error_mark_node;
}
- /* No object? Then just fake one up, and let build_method_call
- figure out what to do. */
- if (current_class_type == 0
- || get_base_distance (type, current_class_type, 0, &basetype_path) == -1)
- dont_use_this = 1;
+ decl = maybe_dummy_object (type, &basetype_path);
- if (dont_use_this)
- {
- basetype_path = TYPE_BINFO (type);
- decl = build1 (NOP_EXPR, build_pointer_type (type), error_mark_node);
- }
- else if (current_class_ptr == 0)
- {
- dont_use_this = 1;
- decl = build1 (NOP_EXPR, build_pointer_type (type), error_mark_node);
- }
- else
+ /* Convert 'this' to the specified type to disambiguate conversion
+ to the function's context. Apparently Standard C++ says that we
+ shouldn't do this. */
+ if (decl == current_class_ref
+ && ! pedantic
+ && ACCESSIBLY_UNIQUELY_DERIVED_P (type, current_class_type))
{
tree olddecl = current_class_ptr;
tree oldtype = TREE_TYPE (TREE_TYPE (olddecl));
if (oldtype != type)
{
- tree newtype = build_type_variant (type, TYPE_READONLY (oldtype),
- TYPE_VOLATILE (oldtype));
+ tree newtype = build_qualified_type (type, TYPE_QUALS (oldtype));
decl = convert_force (build_pointer_type (newtype), olddecl, 0);
+ decl = build_indirect_ref (decl, NULL_PTR);
}
- else
- decl = olddecl;
}
- decl = build_indirect_ref (decl, NULL_PTR);
-
if (method_name == constructor_name (type)
|| method_name == constructor_name_full (type))
return build_functional_cast (type, parmlist);
@@ -1469,7 +1459,7 @@ build_member_call (type, name, parmlist)
return error_mark_node;
if (TREE_CODE (t) == FIELD_DECL)
{
- if (dont_use_this)
+ if (is_dummy_object (decl))
{
cp_error ("invalid use of non-static field `%D'", t);
return error_mark_node;
@@ -1509,7 +1499,8 @@ tree
build_offset_ref (type, name)
tree type, name;
{
- tree decl, fnfields, fields, t = error_mark_node;
+ tree decl, t = error_mark_node;
+ tree member;
tree basebinfo = NULL_TREE;
tree orig_name = name;
@@ -1575,28 +1566,19 @@ build_offset_ref (type, name)
return error_mark_node;
}
- if (current_class_type == 0
- || get_base_distance (type, current_class_type, 0, &basebinfo) == -1)
- {
- basebinfo = TYPE_BINFO (type);
- decl = build1 (NOP_EXPR, type, error_mark_node);
- }
- else if (current_class_ptr == 0)
- decl = build1 (NOP_EXPR, type, error_mark_node);
- else
- decl = current_class_ref;
+ decl = maybe_dummy_object (type, &basebinfo);
- fnfields = lookup_fnfields (basebinfo, name, 1);
- fields = lookup_field (basebinfo, name, 0, 0);
+ member = lookup_member (basebinfo, name, 1, 0);
- if (fields == error_mark_node || fnfields == error_mark_node)
+ if (member == error_mark_node)
return error_mark_node;
/* A lot of this logic is now handled in lookup_field and
lookup_fnfield. */
- if (fnfields)
+ if (member && TREE_CODE (member) == TREE_LIST)
{
/* Go from the TREE_BASELINK to the member function info. */
+ tree fnfields = member;
t = TREE_VALUE (fnfields);
if (TREE_CODE (orig_name) == TEMPLATE_ID_EXPR)
@@ -1624,27 +1606,16 @@ build_offset_ref (type, name)
if (!really_overloaded_fn (t))
{
- tree access;
-
/* Get rid of a potential OVERLOAD around it */
t = OVL_CURRENT (t);
/* unique functions are handled easily. */
basebinfo = TREE_PURPOSE (fnfields);
- access = compute_access (basebinfo, t);
- if (access == access_protected_node)
- {
- cp_error_at ("member function `%#D' is protected", t);
- error ("in this context");
- return error_mark_node;
- }
- if (access == access_private_node)
- {
- cp_error_at ("member function `%#D' is private", t);
- error ("in this context");
- return error_mark_node;
- }
+ if (!enforce_access (basebinfo, t))
+ return error_mark_node;
mark_used (t);
+ if (DECL_STATIC_FUNCTION_P (t))
+ return t;
return build (OFFSET_REF, TREE_TYPE (t), decl, t);
}
@@ -1670,8 +1641,7 @@ build_offset_ref (type, name)
t = lookup_field (basebinfo, name, 1, 0);
- if (t == error_mark_node)
- return error_mark_node;
+ t = member;
if (t == NULL_TREE)
{
@@ -1692,7 +1662,7 @@ build_offset_ref (type, name)
return convert_from_reference (t);
}
- if (TREE_CODE (t) == FIELD_DECL && DECL_BIT_FIELD (t))
+ if (TREE_CODE (t) == FIELD_DECL && DECL_C_BIT_FIELD (t))
{
cp_error ("illegal pointer to bit field `%D'", t);
return error_mark_node;
@@ -1746,7 +1716,8 @@ resolve_offset_ref (exp)
}
if ((TREE_CODE (member) == VAR_DECL
- && ! TYPE_PTRMEMFUNC_P (TREE_TYPE (member)))
+ && ! TYPE_PTRMEMFUNC_P (TREE_TYPE (member))
+ && ! TYPE_PTRMEM_P (TREE_TYPE (member)))
|| TREE_CODE (TREE_TYPE (member)) == FUNCTION_TYPE
|| TREE_CODE (TREE_TYPE (member)) == METHOD_TYPE)
{
@@ -1776,12 +1747,9 @@ resolve_offset_ref (exp)
/* The first case is really just a reference to a member of `this'. */
if (TREE_CODE (member) == FIELD_DECL
- && (base == current_class_ref
- || (TREE_CODE (base) == NOP_EXPR
- && TREE_OPERAND (base, 0) == error_mark_node)))
+ && (base == current_class_ref || is_dummy_object (base)))
{
tree basetype_path;
- tree access;
tree expr;
if (TREE_CODE (exp) == OFFSET_REF && TREE_CODE (type) == OFFSET_TYPE)
@@ -1798,19 +1766,9 @@ resolve_offset_ref (exp)
}
/* Kludge: we need to use basetype_path now, because
convert_pointer_to will bash it. */
- access = compute_access (basetype_path, member);
+ enforce_access (basetype_path, member);
addr = convert_pointer_to (basetype, base);
- /* Issue errors if there was an access violation. */
- if (access != access_public_node)
- {
- cp_error_at ("member `%D' is %s",
- access == access_private_node
- ? "private" : "protected",
- member);
- cp_error ("in this context");
- }
-
/* Even in the case of illegal access, we form the
COMPONENT_REF; that will allow better error recovery than
just feeding back error_mark_node. */
@@ -1820,8 +1778,7 @@ resolve_offset_ref (exp)
}
/* Ensure that we have an object. */
- if (TREE_CODE (base) == NOP_EXPR
- && TREE_OPERAND (base, 0) == error_mark_node)
+ if (is_dummy_object (base))
addr = error_mark_node;
else
/* If this is a reference to a member function, then return the
@@ -1830,7 +1787,7 @@ resolve_offset_ref (exp)
for the dereferenced pointer-to-member construct. */
addr = build_unary_op (ADDR_EXPR, base, 0);
- if (TREE_CODE (TREE_TYPE (member)) == OFFSET_TYPE)
+ if (TYPE_PTRMEM_P (TREE_TYPE (member)))
{
if (addr == error_mark_node)
{
@@ -1838,10 +1795,9 @@ resolve_offset_ref (exp)
return error_mark_node;
}
- basetype = TYPE_OFFSET_BASETYPE (TREE_TYPE (member));
+ basetype = TYPE_OFFSET_BASETYPE (TREE_TYPE (TREE_TYPE (member)));
addr = convert_pointer_to (basetype, addr);
- member = cp_convert (ptrdiff_type_node,
- build_unary_op (ADDR_EXPR, member, 0));
+ member = cp_convert (ptrdiff_type_node, member);
/* Pointer to data members are offset by one, so that a null
pointer with a real value of 0 is distinguishable from an
@@ -1890,11 +1846,9 @@ static tree
build_builtin_delete_call (addr)
tree addr;
{
- tree BID = get_first_fn
- (IDENTIFIER_GLOBAL_VALUE (ansi_opname[(int) DELETE_EXPR]));
-
- assemble_external (BID);
- return build_call (BID, void_type_node, build_expr_list (NULL_TREE, addr));
+ mark_used (global_delete_fndecl);
+ return build_call (global_delete_fndecl,
+ void_type_node, build_expr_list (NULL_TREE, addr));
}
/* Generate a C++ "new" expression. DECL is either a TREE_LIST
@@ -1988,6 +1942,11 @@ build_new (placement, decl, init, use_global_new)
}
else
{
+ int flags = pedantic ? WANT_INT : (WANT_INT | WANT_ENUM);
+ if (build_expr_type_conversion (flags, this_nelts, 0)
+ == NULL_TREE)
+ pedwarn ("size in array new must have integral type");
+
this_nelts = save_expr (cp_convert (sizetype, this_nelts));
absdcl = TREE_OPERAND (absdcl, 0);
if (this_nelts == integer_zero_node)
@@ -2113,7 +2072,7 @@ static tree jclass_node = NULL_TREE;
/* Given a Java class, return a decl for the corresponding java.lang.Class. */
-tree
+static tree
build_java_class_ref (type)
tree type;
{
@@ -2177,7 +2136,7 @@ build_new_1 (exp)
}
true_type = type;
- if (TYPE_READONLY (type) || TYPE_VOLATILE (type))
+ if (CP_TYPE_QUALS (type))
type = TYPE_MAIN_VARIANT (type);
/* If our base type is an array, then make sure we know how many elements
@@ -2189,7 +2148,7 @@ build_new_1 (exp)
true_type = TREE_TYPE (true_type);
}
- if (!complete_type_or_else (true_type))
+ if (!complete_type_or_else (true_type, exp))
return error_mark_node;
if (has_array)
@@ -2379,11 +2338,11 @@ build_new_1 (exp)
allow the expression to be non-const while we do the
initialization. */
deref_type = TREE_TYPE (deref);
- if (TYPE_READONLY (deref_type))
+ if (CP_TYPE_CONST_P (deref_type))
TREE_TYPE (deref)
- = cp_build_type_variant (deref_type,
- /*constp=*/0,
- TYPE_VOLATILE (deref_type));
+ = cp_build_qualified_type (deref_type,
+ CP_TYPE_QUALS (deref_type)
+ & ~TYPE_QUAL_CONST);
TREE_READONLY (deref) = 0;
if (TREE_CHAIN (init) != NULL_TREE)
@@ -2478,9 +2437,6 @@ build_new_1 (exp)
if (cleanup)
{
-#if 0
- /* Disable this until flow is fixed so that it doesn't
- think the initialization of sentry is a dead write. */
tree end, sentry, begin, buf, t = TREE_TYPE (rval);
begin = get_target_expr (boolean_true_node);
@@ -2503,18 +2459,10 @@ build_new_1 (exp)
rval = build (COMPOUND_EXPR, t, begin,
build (COMPOUND_EXPR, t, rval,
build (COMPOUND_EXPR, t, end, buf)));
-#else
- /* FIXME: this is a workaround for a crash due to overlapping
- exception regions. Cleanups shouldn't really happen here. */
- rval = build1 (CLEANUP_POINT_EXPR, TREE_TYPE (rval), rval);
-
- rval = build (TRY_CATCH_EXPR, TREE_TYPE (rval), rval, cleanup);
- rval = build (COMPOUND_EXPR, TREE_TYPE (rval), alloc_expr, rval);
-#endif
}
}
}
- else if (TYPE_READONLY (true_type))
+ else if (CP_TYPE_CONST_P (true_type))
cp_error ("uninitialized const in `new' of `%#T'", true_type);
done:
@@ -2638,8 +2586,7 @@ build_vec_delete_1 (base, maxindex, type, auto_delete_vec, auto_delete,
no_destructor:
/* If the delete flag is one, or anything else with the low bit set,
delete the storage. */
- if (auto_delete_vec == integer_zero_node
- || auto_delete_vec == integer_two_node)
+ if (auto_delete_vec == integer_zero_node)
deallocate_expr = integer_zero_node;
else
{
@@ -2695,18 +2642,80 @@ build_vec_delete_1 (base, maxindex, type, auto_delete_vec, auto_delete,
return cp_convert (void_type_node, body);
}
-/* Build a tree to cleanup partially built arrays.
- BASE is that starting address of the array.
- COUNT is the count of objects that have been built, that need destroying.
- TYPE is the type of elements in the array. */
+/* Protect the vector initialization with a try-block so that we can
+ destroy the first few elements if constructing a later element
+ causes an exception to be thrown. TYPE is the type of the array
+ elements. */
-static tree
-build_array_eh_cleanup (base, count, type)
- tree base, count, type;
+static void
+expand_vec_init_try_block (type)
+ tree type;
+{
+ if (!TYPE_NEEDS_DESTRUCTOR (type) || !flag_exceptions)
+ return;
+
+ /* The code we generate looks like:
+
+ try {
+ // Initialize the vector.
+ } catch (...) {
+ // Destory the elements that need destroying.
+ throw;
+ }
+
+ Here we're just beginning the `try'. */
+
+ expand_eh_region_start ();
+}
+
+/* Add code to destroy the array elements constructed so far if the
+ construction of some element in the array causes an exception to be
+ thrown. RVAL is the address of the last element in the array.
+ TYPE is the type of the array elements. MAXINDEX is the maximum
+ allowable index into the array. ITERATOR is an integer variable
+ indicating how many elements remain to be constructed. */
+
+static void
+expand_vec_init_catch_clause (rval, type, maxindex, iterator)
+ tree rval;
+ tree type;
+ tree maxindex;
+ tree iterator;
{
- tree expr = build_vec_delete_1 (base, count, type, integer_two_node,
- integer_zero_node, 0);
- return expr;
+ tree e;
+ tree cleanup;
+
+ if (!TYPE_NEEDS_DESTRUCTOR (type) || !flag_exceptions)
+ return;
+
+ /* We have to ensure that this can live to the cleanup expansion
+ time, since we know it is only ever needed once, generate code
+ now. */
+ push_obstacks_nochange ();
+ resume_temporary_allocation ();
+
+ cleanup = make_node (RTL_EXPR);
+ TREE_TYPE (cleanup) = void_type_node;
+ RTL_EXPR_RTL (cleanup) = const0_rtx;
+ TREE_SIDE_EFFECTS (cleanup) = 1;
+ do_pending_stack_adjust ();
+ start_sequence_for_rtl_expr (cleanup);
+
+ e = build_vec_delete_1 (rval,
+ build_binary_op (MINUS_EXPR, maxindex,
+ iterator, 1),
+ type,
+ /*auto_delete_vec=*/integer_zero_node,
+ /*auto_delete=*/integer_zero_node,
+ /*use_global_delete=*/0);
+ expand_expr (e, const0_rtx, VOIDmode, EXPAND_NORMAL);
+
+ do_pending_stack_adjust ();
+ RTL_EXPR_SEQUENCE (cleanup) = get_insns ();
+ end_sequence ();
+ cleanup = protect_with_terminate (cleanup);
+ expand_eh_region_end (cleanup);
+ pop_obstacks ();
}
/* `expand_vec_init' performs initialization of a vector of aggregate
@@ -2732,9 +2741,12 @@ expand_vec_init (decl, base, maxindex, init, from_array)
int from_array;
{
tree rval;
- tree iterator, base2 = NULL_TREE;
+ tree base2 = NULL_TREE;
tree type = TREE_TYPE (TREE_TYPE (base));
tree size;
+ tree itype = NULL_TREE;
+ tree iterator;
+ int num_initialized_elts = 0;
maxindex = cp_convert (ptrdiff_type_node, maxindex);
if (maxindex == error_mark_node)
@@ -2751,104 +2763,100 @@ expand_vec_init (decl, base, maxindex, init, from_array)
size = size_in_bytes (type);
- /* Set to zero in case size is <= 0. Optimizer will delete this if
- it is not needed. */
- rval = get_temp_regvar (build_pointer_type (type),
- cp_convert (build_pointer_type (type), null_pointer_node));
base = default_conversion (base);
base = cp_convert (build_pointer_type (type), base);
- expand_assignment (rval, base, 0, 0);
+ rval = get_temp_regvar (build_pointer_type (type), base);
base = get_temp_regvar (build_pointer_type (type), base);
+ iterator = get_temp_regvar (ptrdiff_type_node, maxindex);
- if (init != NULL_TREE
- && TREE_CODE (init) == CONSTRUCTOR
- && (! decl || TREE_TYPE (init) == TREE_TYPE (decl)))
+ /* Protect the entire array initialization so that we can destroy
+ the partially constructed array if an exception is thrown. */
+ expand_vec_init_try_block (type);
+
+ if (init != NULL_TREE && TREE_CODE (init) == CONSTRUCTOR
+ && (!decl || same_type_p (TREE_TYPE (init), TREE_TYPE (decl))))
{
- /* Initialization of array from {...}. */
- tree elts = CONSTRUCTOR_ELTS (init);
+ /* Do non-default initialization resulting from brace-enclosed
+ initializers. */
+
+ tree elts;
tree baseref = build1 (INDIRECT_REF, type, base);
- tree baseinc = build (PLUS_EXPR, build_pointer_type (type), base, size);
- int host_i = TREE_INT_CST_LOW (maxindex);
- if (IS_AGGR_TYPE (type))
+ from_array = 0;
+
+ for (elts = CONSTRUCTOR_ELTS (init); elts; elts = TREE_CHAIN (elts))
{
- while (elts)
- {
- host_i -= 1;
- expand_aggr_init (baseref, TREE_VALUE (elts), 0);
+ tree elt = TREE_VALUE (elts);
- expand_assignment (base, baseinc, 0, 0);
- elts = TREE_CHAIN (elts);
- }
- /* Initialize any elements by default if possible. */
- if (host_i >= 0)
- {
- if (TYPE_NEEDS_CONSTRUCTING (type) == 0)
- {
- if (obey_regdecls)
- use_variable (DECL_RTL (base));
- goto done_init;
- }
+ num_initialized_elts++;
- iterator = get_temp_regvar (ptrdiff_type_node,
- build_int_2 (host_i, 0));
- init = NULL_TREE;
- goto init_by_default;
- }
+ if (IS_AGGR_TYPE (type) || TREE_CODE (type) == ARRAY_TYPE)
+ expand_aggr_init (baseref, elt, 0);
+ else
+ expand_assignment (baseref, elt, 0, 0);
+
+ expand_assignment (base,
+ build (PLUS_EXPR, build_pointer_type (type),
+ base, size),
+ 0, 0);
+ expand_assignment (iterator,
+ build (MINUS_EXPR, ptrdiff_type_node,
+ iterator, integer_one_node),
+ 0, 0);
}
- else
- while (elts)
- {
- expand_assignment (baseref, TREE_VALUE (elts), 0, 0);
- expand_assignment (base, baseinc, 0, 0);
- elts = TREE_CHAIN (elts);
- }
+ /* Clear out INIT so that we don't get confused below. */
+ init = NULL_TREE;
if (obey_regdecls)
use_variable (DECL_RTL (base));
}
- else
+ else if (from_array)
{
- tree itype;
+ /* If initializing one array from another, initialize element by
+ element. We rely upon the below calls the do argument
+ checking. */
+ if (decl == NULL_TREE)
+ {
+ sorry ("initialization of array from dissimilar array type");
+ return error_mark_node;
+ }
+ if (init)
+ {
+ base2 = default_conversion (init);
+ itype = TREE_TYPE (base2);
+ base2 = get_temp_regvar (itype, base2);
+ itype = TREE_TYPE (itype);
+ }
+ else if (TYPE_LANG_SPECIFIC (type)
+ && TYPE_NEEDS_CONSTRUCTING (type)
+ && ! TYPE_HAS_DEFAULT_CONSTRUCTOR (type))
+ {
+ error ("initializer ends prematurely");
+ return error_mark_node;
+ }
+ }
- iterator = get_temp_regvar (ptrdiff_type_node, maxindex);
+ /* Now, default-initialize any remaining elements. We don't need to
+ do that if a) the type does not need constructing, or b) we've
+ already initialized all the elements.
- init_by_default:
- itype = NULL_TREE;
+ We do need to keep going if we're copying an array. */
- /* If initializing one array from another,
- initialize element by element. */
- if (from_array)
- {
- /* We rely upon the below calls the do argument checking */
- if (decl == NULL_TREE)
- {
- sorry ("initialization of array from dissimilar array type");
- return error_mark_node;
- }
- if (init)
- {
- base2 = default_conversion (init);
- itype = TREE_TYPE (base2);
- base2 = get_temp_regvar (itype, base2);
- itype = TREE_TYPE (itype);
- }
- else if (TYPE_LANG_SPECIFIC (type)
- && TYPE_NEEDS_CONSTRUCTING (type)
- && ! TYPE_HAS_DEFAULT_CONSTRUCTOR (type))
- {
- error ("initializer ends prematurely");
- return error_mark_node;
- }
- }
+ if (from_array
+ || (TYPE_NEEDS_CONSTRUCTING (type)
+ && !(TREE_CODE (maxindex) == INTEGER_CST
+ && num_initialized_elts == TREE_INT_CST_LOW (maxindex) + 1)))
+ {
+ /* If the ITERATOR is equal to -1, then we don't have to loop;
+ we've already initialized all the elements. */
+ expand_start_cond (build (NE_EXPR, boolean_type_node,
+ iterator, minus_one),
+ 0);
- expand_start_cond (build (GE_EXPR, boolean_type_node,
- iterator, integer_zero_node), 0);
- if (TYPE_NEEDS_DESTRUCTOR (type))
- expand_eh_region_start ();
+ /* Otherwise, loop through the elements. */
expand_start_loop_continue_elsewhere (1);
-
+
/* The initialization of each array element is a full-expression. */
expand_start_target_temps ();
@@ -2875,70 +2883,55 @@ expand_vec_init (decl, base, maxindex, init, from_array)
{
if (init != 0)
sorry ("cannot initialize multi-dimensional array with initializer");
- expand_vec_init (decl, build1 (NOP_EXPR, build_pointer_type (TREE_TYPE (type)), base),
+ expand_vec_init (decl,
+ build1 (NOP_EXPR,
+ build_pointer_type (TREE_TYPE
+ (type)),
+ base),
array_type_nelts (type), 0, 0);
}
else
expand_aggr_init (build1 (INDIRECT_REF, type, base), init, 0);
expand_assignment (base,
- build (PLUS_EXPR, build_pointer_type (type), base, size),
- 0, 0);
+ build (PLUS_EXPR, build_pointer_type (type),
+ base, size), 0, 0);
if (base2)
expand_assignment (base2,
- build (PLUS_EXPR, build_pointer_type (type), base2, size), 0, 0);
+ build (PLUS_EXPR, build_pointer_type (type),
+ base2, size), 0, 0);
/* Cleanup any temporaries needed for the initial value. */
expand_end_target_temps ();
-
+
expand_loop_continue_here ();
expand_exit_loop_if_false (0, build (NE_EXPR, boolean_type_node,
- build (PREDECREMENT_EXPR, ptrdiff_type_node, iterator, integer_one_node), minus_one));
-
+ build (PREDECREMENT_EXPR,
+ ptrdiff_type_node,
+ iterator,
+ integer_one_node),
+ minus_one));
+
if (obey_regdecls)
{
use_variable (DECL_RTL (base));
if (base2)
use_variable (DECL_RTL (base2));
}
+
expand_end_loop ();
- if (TYPE_NEEDS_DESTRUCTOR (type) && flag_exceptions)
- {
- /* We have to ensure that this can live to the cleanup
- expansion time, since we know it is only ever needed
- once, generate code now. */
- push_obstacks_nochange ();
- resume_temporary_allocation ();
- {
- tree e1, cleanup = make_node (RTL_EXPR);
- TREE_TYPE (cleanup) = void_type_node;
- RTL_EXPR_RTL (cleanup) = const0_rtx;
- TREE_SIDE_EFFECTS (cleanup) = 1;
- do_pending_stack_adjust ();
- start_sequence_for_rtl_expr (cleanup);
-
- e1 = build_array_eh_cleanup
- (rval,
- build_binary_op (MINUS_EXPR, maxindex, iterator, 1),
- type);
- expand_expr (e1, const0_rtx, VOIDmode, EXPAND_NORMAL);
- do_pending_stack_adjust ();
- RTL_EXPR_SEQUENCE (cleanup) = get_insns ();
- end_sequence ();
-
- cleanup = protect_with_terminate (cleanup);
- expand_eh_region_end (cleanup);
- }
- pop_obstacks ();
- }
expand_end_cond ();
- if (obey_regdecls)
- use_variable (DECL_RTL (iterator));
}
- done_init:
+
+ /* Make sure to cleanup any partially constructed elements. */
+ expand_vec_init_catch_clause (rval, type, maxindex, iterator);
if (obey_regdecls)
- use_variable (DECL_RTL (rval));
+ {
+ use_variable (DECL_RTL (iterator));
+ use_variable (DECL_RTL (rval));
+ }
+
return rval;
}
@@ -3006,7 +2999,7 @@ build_delete (type, addr, auto_delete, flags, use_global_delete)
if (TREE_CODE (type) == POINTER_TYPE)
{
type = TYPE_MAIN_VARIANT (TREE_TYPE (type));
- if (!complete_type_or_else (type))
+ if (type != void_type_node && !complete_type_or_else (type, addr))
return error_mark_node;
if (TREE_CODE (type) == ARRAY_TYPE)
goto handle_array;
@@ -3033,7 +3026,7 @@ build_delete (type, addr, auto_delete, flags, use_global_delete)
return error_mark_node;
}
return build_vec_delete (addr, array_type_nelts (type),
- auto_delete, integer_two_node,
+ auto_delete, integer_zero_node,
use_global_delete);
}
else
@@ -3122,6 +3115,10 @@ build_delete (type, addr, auto_delete, flags, use_global_delete)
tree parent_auto_delete = auto_delete;
tree cond;
+ /* Set this again before we call anything, as we might get called
+ recursively. */
+ TYPE_HAS_DESTRUCTOR (type) = 1;
+
/* If we have member delete or vbases, we call delete in
finish_function. */
if (auto_delete == integer_zero_node)
diff --git a/gcc/cp/input.c b/gcc/cp/input.c
index 5a73fea8bd0..9148c865623 100644
--- a/gcc/cp/input.c
+++ b/gcc/cp/input.c
@@ -1,5 +1,5 @@
/* Input handling for G++.
- Copyright (C) 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
+ Copyright (C) 1992, 93-98, 1999 Free Software Foundation, Inc.
Written by Ken Raeburn (raeburn@cygnus.com) while at Watchmaker Computing.
This file is part of GNU CC.
@@ -53,12 +53,6 @@ static struct input_source *input, *free_inputs;
extern char *input_filename;
extern int lineno;
-#ifdef __GNUC__
-#define inline __inline__
-#else
-#define inline
-#endif
-
#if USE_CPPLIB
extern unsigned char *yy_cur, *yy_lim;
extern int yy_get_token ();
diff --git a/gcc/cp/lang-options.h b/gcc/cp/lang-options.h
index 32f5ff90509..f9cfa8c85d5 100644
--- a/gcc/cp/lang-options.h
+++ b/gcc/cp/lang-options.h
@@ -1,5 +1,5 @@
/* Definitions for switches for C++.
- Copyright (C) 1995, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1995, 96-97, 1998 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -63,8 +63,10 @@ DEFINE_LANG_NAME ("C++")
{ "-fno-huge-objects", "" },
{ "-fimplement-inlines", "" },
{ "-fno-implement-inlines", "Export functions even if they can be inlined" },
- { "-fimplicit-templates", "Emit implicit template instatiations when used" },
- { "-fno-implicit-templates", "" },
+ { "-fimplicit-templates", "" },
+ { "-fno-implicit-templates", "Only emit explicit template instatiations" },
+ { "-fimplicit-inline-templates", "" },
+ { "-fno-implicit-inline-templates", "Only emit explicit instatiations of inline templates" },
{ "-finit-priority", "Handle the init_priority attribute" },
{ "-fno-init-priority", "" },
{ "-flabels-ok", "Labels can be used as first class objects" },
@@ -80,6 +82,8 @@ DEFINE_LANG_NAME ("C++")
{ "-fno-operator-names", "" },
{ "-foptional-diags", "" },
{ "-fno-optional-diags", "Disable optional diagnostics" },
+ { "-fpermissive", "Downgrade conformance errors to warnings" },
+ { "-fno-permissive", "" },
{ "-frepo", "Enable automatic template instantiation" },
{ "-fno-repo", "" },
{ "-fsave-memoized", "" },
diff --git a/gcc/cp/lang-specs.h b/gcc/cp/lang-specs.h
index 8daebbc308a..74518b7ab7c 100644
--- a/gcc/cp/lang-specs.h
+++ b/gcc/cp/lang-specs.h
@@ -1,5 +1,5 @@
/* Definitions for specs for C++.
- Copyright (C) 1995 Free Software Foundation, Inc.
+ Copyright (C) 1995, 96-98, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -37,21 +37,24 @@ Boston, MA 02111-1307, USA. */
%{ansi:-trigraphs -D__STRICT_ANSI__} %{!undef:%{!ansi:%p} %P}\
%{!fno-exceptions:-D__EXCEPTIONS}\
%c %{Os:-D__OPTIMIZE_SIZE__} %{O*:%{!O0:-D__OPTIMIZE__}} %{trigraphs}\
+ %{ffast-math:-D__FAST_MATH__}\
%{g*} %{W*} %{w} %{pedantic*} %{H} %{d*} %C %{D*} %{U*} %{i*} %Z\
%i %{E:%W{o*}}%{M:%W{o*}}%{MM:%W{o*}}\n}\
%{!E:%{!M:%{!MM:cc1plus %i %1 %2\
-lang-c++ %{nostdinc*} %{C} %{A*} %{I*} %{P} %I\
+ %{MD:-MD %b.d} %{MMD:-MMD %b.d} %{MG}\
-undef -D__GNUC__=%v1 -D__GNUG__=%v1 -D__cplusplus\
-D__GNUC_MINOR__=%v2\
%{ansi:-trigraphs -D__STRICT_ANSI__} %{!undef:%{!ansi:%p} %P}\
%{!fno-exceptions:-D__EXCEPTIONS}\
%c %{Os:-D__OPTIMIZE_SIZE__} %{O*:%{!O0:-D__OPTIMIZE__}}\
+ %{ffast-math:-D__FAST_MATH__}\
%{trigraphs}\
%{!Q:-quiet} -dumpbase %b.cc %{d*} %{m*} %{a}\
%{g*} %{O*} %{W*} %{w} %{pedantic*} %{ansi}\
%{H} %{d*} %C %{D*} %{U*} %{i*} %Z\
%{v:-version} %{pg:-p} %{p}\
- %{f*} %{+e*} %{aux-info*}\
+ %{f*} %{+e*} %{aux-info*} %{Qn:-fno-ident}\
%{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\
%{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%g.s}}|\n\
%{!S:as %a %Y\
@@ -65,13 +68,14 @@ Boston, MA 02111-1307, USA. */
%{ansi:-trigraphs -D__STRICT_ANSI__} %{!undef:%{!ansi:%p} %P}\
%{!fno-exceptions:-D__EXCEPTIONS}\
%c %{Os:-D__OPTIMIZE_SIZE__} %{O*:%{!O0:-D__OPTIMIZE__}} %{trigraphs}\
+ %{ffast-math:-D__FAST_MATH__}\
%{g*} %{W*} %{w} %{pedantic*} %{H} %{d*} %C %{D*} %{U*} %{i*} %Z\
%i %{!M:%{!MM:%{!E:%{!pipe:%g.ii}}}}%{E:%W{o*}}%{M:%W{o*}}%{MM:%W{o*}} |\n",
"%{!M:%{!MM:%{!E:cc1plus %{!pipe:%g.ii} %1 %2\
%{!Q:-quiet} -dumpbase %b.cc %{d*} %{m*} %{a}\
%{g*} %{O*} %{W*} %{w} %{pedantic*} %{ansi}\
%{v:-version} %{pg:-p} %{p}\
- %{f*} %{+e*} %{aux-info*}\
+ %{f*} %{+e*} %{aux-info*} %{Qn:-fno-ident}\
%{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\
%{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%g.s}}|\n\
%{!S:as %a %Y\
@@ -83,7 +87,7 @@ Boston, MA 02111-1307, USA. */
{"%{!M:%{!MM:%{!E:cc1plus %i %1 %2 %{!Q:-quiet} %{d*} %{m*} %{a}\
%{g*} %{O*} %{W*} %{w} %{pedantic*} %{ansi}\
%{v:-version} %{pg:-p} %{p}\
- %{f*} %{+e*} %{aux-info*}\
+ %{f*} %{+e*} %{aux-info*} %{Qn:-fno-ident}\
%{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\
%{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%g.s}} |\n\
%{!S:as %a %Y\
diff --git a/gcc/cp/lex.c b/gcc/cp/lex.c
index 77ea80eb745..5cccdbe2292 100644
--- a/gcc/cp/lex.c
+++ b/gcc/cp/lex.c
@@ -1,5 +1,5 @@
/* Separate lexical analyzer for GNU C++.
- Copyright (C) 1987, 89, 92-97, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1987, 89, 92-98, 1999 Free Software Foundation, Inc.
Hacked by Michael Tiemann (tiemann@cygnus.com)
This file is part of GNU CC.
@@ -27,7 +27,6 @@ Boston, MA 02111-1307, USA. */
#include "config.h"
#include "system.h"
-#include <setjmp.h>
#include "input.h"
#include "tree.h"
#include "function.h"
@@ -56,18 +55,16 @@ extern struct obstack permanent_obstack;
extern struct obstack *current_obstack, *saveable_obstack;
extern void yyprint PROTO((FILE *, int, YYSTYPE));
-extern void compiler_error PROTO((char *, HOST_WIDE_INT,
- HOST_WIDE_INT));
-static tree get_time_identifier PROTO((char *));
+static tree get_time_identifier PROTO((const char *));
static int check_newline PROTO((void));
static int skip_white_space PROTO((int));
static void finish_defarg PROTO((void));
static int my_get_run_time PROTO((void));
static int get_last_nonwhite_on_line PROTO((void));
-static int interface_strcmp PROTO((char *));
+static int interface_strcmp PROTO((const char *));
static int readescape PROTO((int *));
-static char *extend_token_buffer PROTO((char *));
+static char *extend_token_buffer PROTO((const char *));
static void consume_string PROTO((struct obstack *, int));
static void set_typedecl_interface_info PROTO((tree, tree));
static void feed_defarg PROTO((tree, tree));
@@ -75,7 +72,7 @@ static int set_vardecl_interface_info PROTO((tree, tree));
static void store_pending_inline PROTO((tree, struct pending_inline *));
static void reinit_parse_for_expr PROTO((struct obstack *));
static int *init_cpp_parse PROTO((void));
-static int handle_cp_pragma PROTO((char *));
+static int handle_cp_pragma PROTO((const char *));
#ifdef HANDLE_GENERIC_PRAGMAS
static int handle_generic_pragma PROTO((int));
#endif
@@ -85,12 +82,16 @@ static int reduce_cmp PROTO((int *, int *));
static int token_cmp PROTO((int *, int *));
#endif
#endif
+static void begin_definition_of_inclass_inline PROTO((struct pending_inline*));
+static void parse_float PROTO((PTR));
+static int is_global PROTO((tree));
+static void init_filename_times PROTO((void));
/* Given a file name X, return the nondirectory portion.
Keep in mind that X can be computed more than once. */
char *
file_name_nondirectory (x)
- char *x;
+ const char *x;
{
char *tmp = (char *) rindex (x, '/');
if (DIR_SEPARATOR != '/' && ! tmp)
@@ -98,7 +99,7 @@ file_name_nondirectory (x)
if (tmp)
return (char *) (tmp + 1);
else
- return x;
+ return (char *) x;
}
/* This obstack is needed to hold text. It is not safe to use
@@ -314,7 +315,7 @@ static int ignore_escape_flag = 0;
static tree
get_time_identifier (name)
- char *name;
+ const char *name;
{
tree time_identifier;
int len = strlen (name);
@@ -323,12 +324,13 @@ get_time_identifier (name)
bcopy (name, buf+5, len);
buf[len+5] = '\0';
time_identifier = get_identifier (buf);
- if (IDENTIFIER_LOCAL_VALUE (time_identifier) == NULL_TREE)
+ if (TIME_IDENTIFIER_TIME (time_identifier) == NULL_TREE)
{
push_obstacks_nochange ();
end_temporary_allocation ();
- IDENTIFIER_LOCAL_VALUE (time_identifier) = build_int_2 (0, 0);
- IDENTIFIER_CLASS_VALUE (time_identifier) = build_int_2 (0, 1);
+ TIME_IDENTIFIER_TIME (time_identifier) = build_int_2 (0, 0);
+ TIME_IDENTIFIER_FILEINFO (time_identifier)
+ = build_int_2 (0, 1);
SET_IDENTIFIER_GLOBAL_VALUE (time_identifier, filename_times);
filename_times = time_identifier;
pop_obstacks ();
@@ -378,7 +380,7 @@ int cplus_tree_code_length[] = {
Used for printing out the tree and error messages. */
#define DEFTREECODE(SYM, NAME, TYPE, LEN) NAME,
-char *cplus_tree_code_name[] = {
+const char *cplus_tree_code_name[] = {
"@@dummy",
#include "cp-tree.def"
};
@@ -389,6 +391,12 @@ char *cplus_tree_code_name[] = {
void
lang_init_options ()
{
+#if USE_CPPLIB
+ cpp_reader_init (&parse_in);
+ parse_in.opts = &parse_options;
+ cpp_options_init (&parse_options);
+#endif
+
/* Default exceptions on. */
flag_exceptions = 1;
}
@@ -396,11 +404,14 @@ lang_init_options ()
void
lang_init ()
{
-#if ! USE_CPPLIB
/* the beginning of the file is a new line; check for # */
/* With luck, we discover the real source file's name from that
and put it in input_filename. */
+#if ! USE_CPPLIB
put_back (check_newline ());
+#else
+ check_newline ();
+ yy_cur--;
#endif
if (flag_gnu_xref) GNU_xref_begin (input_filename);
init_repo (input_filename);
@@ -426,7 +437,7 @@ lang_identify ()
return "cplusplus";
}
-void
+static void
init_filename_times ()
{
this_filename_time = get_time_identifier ("<top level>");
@@ -434,7 +445,8 @@ init_filename_times ()
{
header_time = 0;
body_time = my_get_run_time ();
- TREE_INT_CST_LOW (IDENTIFIER_LOCAL_VALUE (this_filename_time)) = body_time;
+ TREE_INT_CST_LOW (TIME_IDENTIFIER_TIME (this_filename_time))
+ = body_time;
}
}
@@ -483,12 +495,15 @@ init_parse (filename)
#endif
#if USE_CPPLIB
- yy_cur = "\n";
- yy_lim = yy_cur + 1;
-
parse_in.show_column = 1;
if (! cpp_start_read (&parse_in, filename))
abort ();
+
+ /* cpp_start_read always puts at least one line directive into the
+ token buffer. We must arrange to read it out here. */
+ yy_cur = parse_in.token_buffer;
+ yy_lim = CPP_PWRITTEN (&parse_in);
+
#else
/* Open input file. */
if (filename == 0 || !strcmp (filename, "-"))
@@ -643,7 +658,7 @@ init_parse (filename)
IDENTIFIER_OPNAME_P (ansi_opname[(int) VEC_NEW_EXPR]) = 1;
ansi_opname[(int) VEC_DELETE_EXPR] = get_identifier ("__vd");
IDENTIFIER_OPNAME_P (ansi_opname[(int) VEC_DELETE_EXPR]) = 1;
- ansi_opname[(int) TYPE_EXPR] = get_identifier ("__op");
+ ansi_opname[(int) TYPE_EXPR] = get_identifier (OPERATOR_TYPENAME_FORMAT);
IDENTIFIER_OPNAME_P (ansi_opname[(int) TYPE_EXPR]) = 1;
/* This is not true: these operators are not defined in ANSI,
@@ -710,6 +725,9 @@ init_parse (filename)
ridpointers[(int) RID_VOLATILE] = get_identifier ("volatile");
SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_VOLATILE],
build_tree_list (NULL_TREE, ridpointers[(int) RID_VOLATILE]));
+ ridpointers[(int) RID_RESTRICT] = get_identifier ("__restrict");
+ SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_RESTRICT],
+ build_tree_list (NULL_TREE, ridpointers[(int) RID_RESTRICT]));
ridpointers[(int) RID_AUTO] = get_identifier ("auto");
SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_AUTO],
build_tree_list (NULL_TREE, ridpointers[(int) RID_AUTO]));
@@ -1138,7 +1156,7 @@ extract_interface_info ()
}
if (!fileinfo)
fileinfo = get_time_identifier (input_filename);
- fileinfo = IDENTIFIER_CLASS_VALUE (fileinfo);
+ fileinfo = TIME_IDENTIFIER_FILEINFO (fileinfo);
interface_only = TREE_INT_CST_LOW (fileinfo);
interface_unknown = TREE_INT_CST_HIGH (fileinfo);
}
@@ -1148,15 +1166,15 @@ extract_interface_info ()
static int
interface_strcmp (s)
- char *s;
+ const char *s;
{
/* Set the interface/implementation bits for this scope. */
struct impl_files *ifiles;
- char *s1;
+ const char *s1;
for (ifiles = impl_file_chain; ifiles; ifiles = ifiles->next)
{
- char *t1 = ifiles->filename;
+ const char *t1 = ifiles->filename;
s1 = s;
if (*s1 != *t1 || *s1 == 0)
@@ -1189,7 +1207,7 @@ set_typedecl_interface_info (prev, vars)
tree prev ATTRIBUTE_UNUSED, vars;
{
tree id = get_time_identifier (DECL_SOURCE_FILE (vars));
- tree fileinfo = IDENTIFIER_CLASS_VALUE (id);
+ tree fileinfo = TIME_IDENTIFIER_FILEINFO (id);
tree type = TREE_TYPE (vars);
CLASSTYPE_INTERFACE_ONLY (type) = TREE_INT_CST_LOW (fileinfo)
@@ -1215,6 +1233,37 @@ set_vardecl_interface_info (prev, vars)
return 0;
}
+/* Set up the state required to correctly handle the definition of the
+ inline function whose preparsed state has been saved in PI. */
+
+static void
+begin_definition_of_inclass_inline (pi)
+ struct pending_inline* pi;
+{
+ tree context;
+
+ if (!pi->fndecl)
+ return;
+
+ /* If this is an inline function in a local class, we must make sure
+ that we save all pertinent information about the function
+ surrounding the local class. */
+ context = hack_decl_function_context (pi->fndecl);
+ if (context)
+ push_cp_function_context (context);
+
+ feed_input (pi->buf, pi->len);
+ lineno = pi->lineno;
+ input_filename = pi->filename;
+ yychar = PRE_PARSED_FUNCTION_DECL;
+ yylval.ttype = build_tree_list ((tree) pi, pi->fndecl);
+ /* Pass back a handle to the rest of the inline functions, so that they
+ can be processed later. */
+ DECL_PENDING_INLINE_INFO (pi->fndecl) = 0;
+ interface_unknown = pi->interface == 1;
+ interface_only = pi->interface == 0;
+}
+
/* Called from the top level: if there are any pending inlines to
do, set up to process them now. This function sets up the first function
to be parsed; after it has been, the rule for fndef in parse.y will
@@ -1224,7 +1273,6 @@ void
do_pending_inlines ()
{
struct pending_inline *t;
- tree context;
/* Oops, we're still dealing with the last batch. */
if (yychar == PRE_PARSED_FUNCTION_DECL)
@@ -1251,32 +1299,7 @@ do_pending_inlines ()
return;
/* Now start processing the first inline function. */
- context = hack_decl_function_context (t->fndecl);
- if (context)
- push_function_context_to (context);
- maybe_begin_member_template_processing (t->fndecl);
- if (t->len > 0)
- {
- feed_input (t->buf, t->len);
- lineno = t->lineno;
-#if 0
- if (input_filename != t->filename)
- {
- input_filename = t->filename;
- /* Get interface/implementation back in sync. */
- extract_interface_info ();
- }
-#else
- input_filename = t->filename;
- interface_unknown = t->interface == 1;
- interface_only = t->interface == 0;
-#endif
- yychar = PRE_PARSED_FUNCTION_DECL;
- }
- /* Pass back a handle on the rest of the inline functions, so that they
- can be processed later. */
- yylval.ttype = build_tree_list ((tree) t, t->fndecl);
- DECL_PENDING_INLINE_INFO (t->fndecl) = 0;
+ begin_definition_of_inclass_inline (t);
}
static int nextchar = -1;
@@ -1292,7 +1315,6 @@ process_next_inline (t)
tree context;
struct pending_inline *i = (struct pending_inline *) TREE_PURPOSE (t);
context = hack_decl_function_context (i->fndecl);
- maybe_end_member_template_processing ();
if (context)
pop_function_context_from (context);
i = i->next;
@@ -1310,24 +1332,8 @@ process_next_inline (t)
}
yychar = YYEMPTY;
end_input ();
- if (i && i->fndecl != NULL_TREE)
- {
- context = hack_decl_function_context (i->fndecl);
- if (context)
- push_function_context_to (context);
- maybe_begin_member_template_processing (i->fndecl);
- feed_input (i->buf, i->len);
- lineno = i->lineno;
- input_filename = i->filename;
- yychar = PRE_PARSED_FUNCTION_DECL;
- yylval.ttype = build_tree_list ((tree) i, i->fndecl);
- DECL_PENDING_INLINE_INFO (i->fndecl) = 0;
- }
if (i)
- {
- interface_unknown = i->interface == 1;
- interface_only = i->interface == 0;
- }
+ begin_definition_of_inclass_inline (i);
else
extract_interface_info ();
}
@@ -1553,6 +1559,8 @@ reinit_parse_for_block (pyychar, obstackp)
else if (pyychar == ':')
{
obstack_1grow (obstackp, pyychar);
+ /* Add a space so we don't get confused by ': ::A(20)'. */
+ obstack_1grow (obstackp, ' ');
look_for_lbrac = 1;
blev = 0;
}
@@ -1991,7 +1999,7 @@ cons_up_default_function (type, full_name, kind)
break;
case 3:
- type = build_type_variant (type, 1, 0);
+ type = build_qualified_type (type, TYPE_QUAL_CONST);
/* Fall through... */
case 4:
/* According to ARM $12.8, the default copy ctor will be declared, but
@@ -2009,7 +2017,7 @@ cons_up_default_function (type, full_name, kind)
declspecs = build_decl_list (NULL_TREE, type);
if (kind == 5)
- type = build_type_variant (type, 1, 0);
+ type = build_qualified_type (type, TYPE_QUAL_CONST);
name = ansi_opname [(int) MODIFY_EXPR];
@@ -2127,7 +2135,7 @@ note_got_semicolon (type)
{
if (TREE_CODE_CLASS (TREE_CODE (type)) != 't')
my_friendly_abort (60);
- if (IS_AGGR_TYPE (type))
+ if (CLASS_TYPE_P (type))
CLASSTYPE_GOT_SEMICOLON (type) = 1;
}
@@ -2196,7 +2204,7 @@ skip_white_space (c)
static char *
extend_token_buffer (p)
- char *p;
+ const char *p;
{
int offset = p - token_buffer;
@@ -2255,13 +2263,12 @@ pragma_ungetc (arg)
int linemode;
-static int handle_cp_pragma PROTO((char *));
-
static int
check_newline ()
{
register int c;
register int token;
+ int saw_line = 0;
/* Read first nonwhite char on the line. Do this before incrementing the
line number, in case we're at the end of saved text. */
@@ -2291,7 +2298,7 @@ check_newline ()
it and ignore it; otherwise, ignore the line, with an error
if the word isn't `pragma'. */
- if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))
+ if (ISALPHA (c))
{
if (c == 'p')
{
@@ -2370,7 +2377,10 @@ check_newline ()
&& getch () == 'n'
&& getch () == 'e'
&& ((c = getch ()) == ' ' || c == '\t'))
- goto linenum;
+ {
+ saw_line = 1;
+ goto linenum;
+ }
}
else if (c == 'i')
{
@@ -2467,9 +2477,16 @@ linenum:
/* More follows: it must be a string constant (filename). */
- /* Read the string constant, but don't treat \ as special. */
- ignore_escape_flag = 1;
+ if (saw_line)
+ {
+ /* Don't treat \ as special if we are processing #line 1 "...".
+ If you want it to be treated specially, use # 1 "...". */
+ ignore_escape_flag = 1;
+ }
+
+ /* Read the string constant. */
token = real_yylex ();
+
ignore_escape_flag = 0;
if (token != STRING || TREE_CODE (yylval.ttype) != STRING_CST)
@@ -2486,7 +2503,7 @@ linenum:
int this_time = my_get_run_time ();
tree time_identifier = get_time_identifier (TREE_STRING_POINTER (yylval.ttype));
header_time += this_time - body_time;
- TREE_INT_CST_LOW (IDENTIFIER_LOCAL_VALUE (this_filename_time))
+ TREE_INT_CST_LOW (TIME_IDENTIFIER_TIME (this_filename_time))
+= this_time - body_time;
this_filename_time = time_identifier;
body_time = this_time;
@@ -2776,7 +2793,7 @@ readescape (ignore_ptr)
pedwarn ("unknown escape sequence `\\%c'", c);
return c;
}
- if (c >= 040 && c < 0177)
+ if (ISGRAPH (c))
pedwarn ("unknown escape sequence `\\%c'", c);
else
pedwarn ("unknown escape sequence: `\\' followed by char code 0x%x", c);
@@ -2805,6 +2822,10 @@ identifier_type (decl)
}
if (looking_for_template && really_overloaded_fn (decl))
{
+ /* See through a baselink. */
+ if (TREE_CODE (decl) == TREE_LIST)
+ decl = TREE_VALUE (decl);
+
for (t = decl; t != NULL_TREE; t = OVL_CHAIN (t))
if (DECL_FUNCTION_TEMPLATE_P (OVL_FUNCTION (t)))
return PFUNCNAME;
@@ -2909,8 +2930,7 @@ do_identifier (token, parsing, args)
my_friendly_abort (61);
else
{
- cp_error ("invalid use of member `%D' from base class `%T'", field,
- DECL_FIELD_CONTEXT (field));
+ cp_error ("invalid use of member `%D'", field);
id = error_mark_node;
return id;
}
@@ -2919,11 +2939,9 @@ do_identifier (token, parsing, args)
/* Do Koenig lookup if appropriate (inside templates we build lookup
expressions instead). */
if (args && !current_template_parms && (!id || is_global (id)))
- {
- /* If we have arguments and we only found global names,
- do Koenig lookup. */
- id = lookup_arg_dependent (token, id, args);
- }
+ /* If we have arguments and we only found global names, do Koenig
+ lookup. */
+ id = lookup_arg_dependent (token, id, args);
/* Remember that this name has been used in the class definition, as per
[class.scope0] */
@@ -2936,18 +2954,19 @@ do_identifier (token, parsing, args)
after the class is complete. (jason 3/12/97) */
&& TREE_CODE (id) != OVERLOAD)
pushdecl_class_level (id);
-
- if (!id || id == error_mark_node)
- {
- if (id == error_mark_node && current_class_type != NULL_TREE)
- {
- id = lookup_nested_field (token, 1);
- /* In lookup_nested_field(), we marked this so we can gracefully
- leave this whole mess. */
- if (id && id != error_mark_node && TREE_TYPE (id) == error_mark_node)
- return id;
- }
+ if (id == error_mark_node)
+ {
+ /* lookup_name quietly returns error_mark_node if we're parsing,
+ as we don't want to complain about an identifier that ends up
+ being used as a declarator. So we call it again to get the error
+ message. */
+ id = lookup_name (token, 0);
+ return error_mark_node;
+ }
+
+ if (!id)
+ {
if (current_template_parms)
return build_min_nt (LOOKUP_EXPR, token);
else if (IDENTIFIER_OPNAME_P (token))
@@ -3030,24 +3049,10 @@ do_identifier (token, parsing, args)
/* TREE_USED is set in `hack_identifier'. */
if (TREE_CODE (id) == CONST_DECL)
{
+ /* Check access. */
if (IDENTIFIER_CLASS_VALUE (token) == id)
- {
- /* Check access. */
- tree access = compute_access (TYPE_BINFO (current_class_type), id);
- if (access == access_private_node)
- cp_error ("enum `%D' is private", id);
- /* protected is OK, since it's an enum of `this'. */
- }
- if (!processing_template_decl
- /* Really, if we're processing a template, we just want to
- resolve template parameters, and not enumeration
- constants. But, they're hard to tell apart. (Note that
- a non-type template parameter may have enumeration type.)
- Fortunately, there's no harm in resolving *global*
- enumeration constants, since they can't depend on
- template parameters. */
- || (TREE_CODE (CP_DECL_CONTEXT (id)) == NAMESPACE_DECL
- && TREE_CODE (DECL_INITIAL (id)) == TEMPLATE_PARM_INDEX))
+ enforce_access (DECL_REAL_CONTEXT(id), id);
+ if (!processing_template_decl || DECL_TEMPLATE_PARM_P (id))
id = DECL_INITIAL (id);
}
else
@@ -3074,6 +3079,7 @@ do_identifier (token, parsing, args)
&& CP_DECL_CONTEXT (id)
&& TREE_CODE (CP_DECL_CONTEXT (id)) == FUNCTION_DECL)
|| TREE_CODE (id) == PARM_DECL
+ || TREE_CODE (id) == RESULT_DECL
|| TREE_CODE (id) == USING_DECL))
id = build_min_nt (LOOKUP_EXPR, token);
@@ -3158,16 +3164,20 @@ identifier_typedecl_value (node)
type = IDENTIFIER_TYPE_VALUE (node);
if (type == NULL_TREE)
return NULL_TREE;
-#define do(X) \
- { \
- t = (X); \
- if (t && TREE_CODE (t) == TYPE_DECL && TREE_TYPE (t) == type) \
- return t; \
- }
- do (IDENTIFIER_LOCAL_VALUE (node));
- do (IDENTIFIER_CLASS_VALUE (node));
- do (IDENTIFIER_NAMESPACE_VALUE (node));
-#undef do
+
+ if (IDENTIFIER_BINDING (node))
+ {
+ t = IDENTIFIER_VALUE (node);
+ if (t && TREE_CODE (t) == TYPE_DECL && TREE_TYPE (t) == type)
+ return t;
+ }
+ if (IDENTIFIER_NAMESPACE_VALUE (node))
+ {
+ t = IDENTIFIER_NAMESPACE_VALUE (node);
+ if (t && TREE_CODE (t) == TYPE_DECL && TREE_TYPE (t) == type)
+ return t;
+ }
+
/* Will this one ever happen? */
if (TYPE_MAIN_DECL (type))
return TYPE_MAIN_DECL (type);
@@ -3177,6 +3187,103 @@ identifier_typedecl_value (node)
return NULL_TREE;
}
+struct pf_args
+{
+ /* Input */
+ /* I/O */
+ char *p;
+ int c;
+ int imag;
+ tree type;
+ /* Output */
+ REAL_VALUE_TYPE value;
+};
+
+static void
+parse_float (data)
+ PTR data;
+{
+ struct pf_args * args = (struct pf_args *) data;
+ int fflag = 0, lflag = 0;
+ /* Copy token_buffer now, while it has just the number
+ and not the suffixes; once we add `f' or `i',
+ REAL_VALUE_ATOF may not work any more. */
+ char *copy = (char *) alloca (args->p - token_buffer + 1);
+ bcopy (token_buffer, copy, args->p - token_buffer + 1);
+
+ while (1)
+ {
+ int lose = 0;
+
+ /* Read the suffixes to choose a data type. */
+ switch (args->c)
+ {
+ case 'f': case 'F':
+ if (fflag)
+ error ("more than one `f' in numeric constant");
+ fflag = 1;
+ break;
+
+ case 'l': case 'L':
+ if (lflag)
+ error ("more than one `l' in numeric constant");
+ lflag = 1;
+ break;
+
+ case 'i': case 'I':
+ if (args->imag)
+ error ("more than one `i' or `j' in numeric constant");
+ else if (pedantic)
+ pedwarn ("ANSI C++ forbids imaginary numeric constants");
+ args->imag = 1;
+ break;
+
+ default:
+ lose = 1;
+ }
+
+ if (lose)
+ break;
+
+ if (args->p >= token_buffer + maxtoken - 3)
+ args->p = extend_token_buffer (args->p);
+ *(args->p++) = args->c;
+ *(args->p) = 0;
+ args->c = getch ();
+ }
+
+ /* The second argument, machine_mode, of REAL_VALUE_ATOF
+ tells the desired precision of the binary result
+ of decimal-to-binary conversion. */
+
+ if (fflag)
+ {
+ if (lflag)
+ error ("both `f' and `l' in floating constant");
+
+ args->type = float_type_node;
+ args->value = REAL_VALUE_ATOF (copy, TYPE_MODE (args->type));
+ /* A diagnostic is required here by some ANSI C testsuites.
+ This is not pedwarn, become some people don't want
+ an error for this. */
+ if (REAL_VALUE_ISINF (args->value) && pedantic)
+ warning ("floating point number exceeds range of `float'");
+ }
+ else if (lflag)
+ {
+ args->type = long_double_type_node;
+ args->value = REAL_VALUE_ATOF (copy, TYPE_MODE (args->type));
+ if (REAL_VALUE_ISINF (args->value) && pedantic)
+ warning ("floating point number exceeds range of `long double'");
+ }
+ else
+ {
+ args->value = REAL_VALUE_ATOF (copy, TYPE_MODE (args->type));
+ if (REAL_VALUE_ISINF (args->value) && pedantic)
+ warning ("floating point number exceeds range of `double'");
+ }
+}
+
int
real_yylex ()
{
@@ -3712,7 +3819,7 @@ real_yylex ()
int exceeds_double = 0;
int imag = 0;
REAL_VALUE_TYPE value;
- jmp_buf handler;
+ struct pf_args args;
/* Read explicit exponent if any, and put it in tokenbuf. */
@@ -3741,97 +3848,31 @@ real_yylex ()
*p = 0;
errno = 0;
+ /* Setup input for parse_float() */
+ args.p = p;
+ args.c = c;
+ args.imag = imag;
+ args.type = type;
+
/* Convert string to a double, checking for overflow. */
- if (setjmp (handler))
+ if (do_float_handler (parse_float, (PTR) &args))
{
- error ("floating constant out of range");
- value = dconst0;
+ /* Receive output from parse_float() */
+ value = args.value;
}
else
{
- int fflag = 0, lflag = 0;
- /* Copy token_buffer now, while it has just the number
- and not the suffixes; once we add `f' or `i',
- REAL_VALUE_ATOF may not work any more. */
- char *copy = (char *) alloca (p - token_buffer + 1);
- bcopy (token_buffer, copy, p - token_buffer + 1);
-
- set_float_handler (handler);
-
- while (1)
- {
- int lose = 0;
-
- /* Read the suffixes to choose a data type. */
- switch (c)
- {
- case 'f': case 'F':
- if (fflag)
- error ("more than one `f' in numeric constant");
- fflag = 1;
- break;
-
- case 'l': case 'L':
- if (lflag)
- error ("more than one `l' in numeric constant");
- lflag = 1;
- break;
-
- case 'i': case 'I':
- if (imag)
- error ("more than one `i' or `j' in numeric constant");
- else if (pedantic)
- pedwarn ("ANSI C++ forbids imaginary numeric constants");
- imag = 1;
- break;
-
- default:
- lose = 1;
- }
-
- if (lose)
- break;
-
- if (p >= token_buffer + maxtoken - 3)
- p = extend_token_buffer (p);
- *p++ = c;
- *p = 0;
- c = getch ();
- }
-
- /* The second argument, machine_mode, of REAL_VALUE_ATOF
- tells the desired precision of the binary result
- of decimal-to-binary conversion. */
-
- if (fflag)
- {
- if (lflag)
- error ("both `f' and `l' in floating constant");
-
- type = float_type_node;
- value = REAL_VALUE_ATOF (copy, TYPE_MODE (type));
- /* A diagnostic is required here by some ANSI C testsuites.
- This is not pedwarn, become some people don't want
- an error for this. */
- if (REAL_VALUE_ISINF (value) && pedantic)
- warning ("floating point number exceeds range of `float'");
- }
- else if (lflag)
- {
- type = long_double_type_node;
- value = REAL_VALUE_ATOF (copy, TYPE_MODE (type));
- if (REAL_VALUE_ISINF (value) && pedantic)
- warning ("floating point number exceeds range of `long double'");
- }
- else
- {
- value = REAL_VALUE_ATOF (copy, TYPE_MODE (type));
- if (REAL_VALUE_ISINF (value) && pedantic)
- warning ("floating point number exceeds range of `double'");
- }
-
- set_float_handler (NULL_PTR);
+ /* We got an exception from parse_float() */
+ error ("floating constant out of range");
+ value = dconst0;
}
+
+ /* Receive output from parse_float() */
+ p = args.p;
+ c = args.c;
+ imag = args.imag;
+ type = args.type;
+
#ifdef ERANGE
if (errno == ERANGE && pedantic)
{
@@ -4221,15 +4262,13 @@ real_yylex ()
/* mbtowc sometimes needs an extra char before accepting */
if (char_len <= i)
put_back (c);
- if (wide_flag)
+ if (! wide_flag)
{
- *(wchar_t *)p = wc;
- p += sizeof (wc);
+ p += (i + 1);
+ c = getch ();
+ continue;
}
- else
- p += (i + 1);
- c = getch ();
- continue;
+ c = wc;
}
#endif /* MULTIBYTE_CHARS */
}
@@ -4554,6 +4593,17 @@ build_lang_decl (code, name, type)
tree type;
{
register tree t = build_decl (code, name, type);
+ retrofit_lang_decl (t);
+ return t;
+}
+
+/* Add DECL_LANG_SPECIFIC info to T. Called from build_lang_decl
+ and pushdecl (for functions generated by the backend). */
+
+void
+retrofit_lang_decl (t)
+ tree t;
+{
struct obstack *obstack = current_obstack;
register int i = sizeof (struct lang_decl) / sizeof (int);
register int *pi;
@@ -4602,8 +4652,6 @@ build_lang_decl (code, name, type)
tree_node_counts[(int)lang_decl] += 1;
tree_node_sizes[(int)lang_decl] += sizeof (struct lang_decl);
#endif
-
- return t;
}
tree
@@ -4665,38 +4713,46 @@ make_lang_type (code)
{
extern struct obstack *current_obstack, *saveable_obstack;
register tree t = make_node (code);
- struct obstack *obstack = current_obstack;
- register int i = sizeof (struct lang_type) / sizeof (int);
- register int *pi;
/* Set up some flags that give proper default behavior. */
- IS_AGGR_TYPE (t) = 1;
+ if (IS_AGGR_TYPE_CODE (code))
+ {
+ struct obstack *obstack = current_obstack;
+ struct lang_type *pi;
- if (! TREE_PERMANENT (t))
- obstack = saveable_obstack;
- else
- my_friendly_assert (obstack == &permanent_obstack, 236);
+ SET_IS_AGGR_TYPE (t, 1);
- pi = (int *) obstack_alloc (obstack, sizeof (struct lang_type));
- while (i > 0)
- pi[--i] = 0;
+ if (! TREE_PERMANENT (t))
+ obstack = saveable_obstack;
+ else
+ my_friendly_assert (obstack == &permanent_obstack, 236);
+
+ pi = (struct lang_type *) obstack_alloc (obstack, sizeof (struct lang_type));
+ bzero ((char *) pi, (int) sizeof (struct lang_type));
- TYPE_LANG_SPECIFIC (t) = (struct lang_type *) pi;
- CLASSTYPE_AS_LIST (t) = build_expr_list (NULL_TREE, t);
- SET_CLASSTYPE_INTERFACE_UNKNOWN_X (t, interface_unknown);
- CLASSTYPE_INTERFACE_ONLY (t) = interface_only;
- TYPE_BINFO (t) = make_binfo (integer_zero_node, t, NULL_TREE, NULL_TREE);
- CLASSTYPE_BINFO_AS_LIST (t) = build_tree_list (NULL_TREE, TYPE_BINFO (t));
+ TYPE_LANG_SPECIFIC (t) = pi;
+ CLASSTYPE_AS_LIST (t) = build_expr_list (NULL_TREE, t);
+ SET_CLASSTYPE_INTERFACE_UNKNOWN_X (t, interface_unknown);
+ CLASSTYPE_INTERFACE_ONLY (t) = interface_only;
+ TYPE_BINFO (t) = make_binfo (integer_zero_node, t, NULL_TREE, NULL_TREE);
+ CLASSTYPE_BINFO_AS_LIST (t)
+ = build_tree_list (NULL_TREE, TYPE_BINFO (t));
- /* Make sure this is laid out, for ease of use later.
- In the presence of parse errors, the normal was of assuring
- this might not ever get executed, so we lay it out *immediately*. */
- build_pointer_type (t);
+ /* Make sure this is laid out, for ease of use later. In the
+ presence of parse errors, the normal was of assuring this
+ might not ever get executed, so we lay it out *immediately*. */
+ build_pointer_type (t);
#ifdef GATHER_STATISTICS
- tree_node_counts[(int)lang_type] += 1;
- tree_node_sizes[(int)lang_type] += sizeof (struct lang_type);
+ tree_node_counts[(int)lang_type] += 1;
+ tree_node_sizes[(int)lang_type] += sizeof (struct lang_type);
#endif
+ }
+ else
+ /* We use TYPE_ALIAS_SET for the CLASSTYPE_MARKED bits. But,
+ TYPE_ALIAS_SET is initialized to -1 by default, so we must
+ clear it here. */
+ TYPE_ALIAS_SET (t) = 0;
return t;
}
@@ -4706,7 +4762,7 @@ dump_time_statistics ()
{
register tree prev = 0, decl, next;
int this_time = my_get_run_time ();
- TREE_INT_CST_LOW (IDENTIFIER_LOCAL_VALUE (this_filename_time))
+ TREE_INT_CST_LOW (TIME_IDENTIFIER_TIME (this_filename_time))
+= this_time - body_time;
fprintf (stderr, "\n******\n");
@@ -4725,22 +4781,31 @@ dump_time_statistics ()
for (decl = prev; decl; decl = IDENTIFIER_GLOBAL_VALUE (decl))
print_time (IDENTIFIER_POINTER (decl),
- TREE_INT_CST_LOW (IDENTIFIER_LOCAL_VALUE (decl)));
+ TREE_INT_CST_LOW (TIME_IDENTIFIER_TIME (decl)));
}
void
-compiler_error (s, v, v2)
- char *s;
- HOST_WIDE_INT v, v2; /* @@also used as pointer */
+compiler_error VPROTO ((const char *msg, ...))
{
+#ifndef ANSI_PROTOTYPES
+ const char *msg;
+#endif
char buf[1024];
- sprintf (buf, s, v, v2);
+ va_list ap;
+
+ VA_START (ap, msg);
+
+#ifndef ANSI_PROTOTYPES
+ msg = va_arg (ap, const char *);
+#endif
+
+ vsprintf (buf, msg, ap);
error_with_file_and_line (input_filename, lineno, "%s (compiler error)", buf);
}
void
yyerror (string)
- char *string;
+ const char *string;
{
extern int end_of_file;
char buf[200];
@@ -4759,7 +4824,7 @@ yyerror (string)
strcat (buf, " before string constant");
else if (token_buffer[0] == '\'')
strcat (buf, " before character constant");
- else if (token_buffer[0] < 040 || (unsigned char) token_buffer[0] >= 0177)
+ else if (!ISGRAPH ((unsigned char)token_buffer[0]))
sprintf (buf + strlen (buf), " before character 0%o",
(unsigned char) token_buffer[0]);
else
@@ -4770,7 +4835,7 @@ yyerror (string)
static int
handle_cp_pragma (pname)
- char *pname;
+ const char *pname;
{
register int token;
@@ -4816,7 +4881,8 @@ handle_cp_pragma (pname)
}
else if (! strcmp (pname, "interface"))
{
- tree fileinfo = IDENTIFIER_CLASS_VALUE (get_time_identifier (input_filename));
+ tree fileinfo
+ = TIME_IDENTIFIER_FILEINFO (get_time_identifier (input_filename));
char *main_filename = input_filename;
main_filename = file_name_nondirectory (main_filename);
@@ -4838,7 +4904,6 @@ handle_cp_pragma (pname)
if (token != END_OF_LINE)
warning ("garbage after `#pragma interface' ignored");
-#ifndef NO_LINKAGE_HEURISTICS
write_virtuals = 3;
if (impl_file_chain == 0)
@@ -4851,7 +4916,7 @@ handle_cp_pragma (pname)
#ifdef AUTO_IMPLEMENT
filename = file_name_nondirectory (main_input_filename);
fi = get_time_identifier (filename);
- fi = IDENTIFIER_CLASS_VALUE (fi);
+ fi = TIME_IDENTIFIER_FILEINFO (fi);
TREE_INT_CST_LOW (fi) = 0;
TREE_INT_CST_HIGH (fi) = 1;
/* Get default. */
@@ -4862,16 +4927,21 @@ handle_cp_pragma (pname)
}
interface_only = interface_strcmp (main_filename);
+#ifdef MULTIPLE_SYMBOL_SPACES
+ if (! interface_only)
+ interface_unknown = 0;
+#else /* MULTIPLE_SYMBOL_SPACES */
interface_unknown = 0;
+#endif /* MULTIPLE_SYMBOL_SPACES */
TREE_INT_CST_LOW (fileinfo) = interface_only;
TREE_INT_CST_HIGH (fileinfo) = interface_unknown;
-#endif /* NO_LINKAGE_HEURISTICS */
return 1;
}
else if (! strcmp (pname, "implementation"))
{
- tree fileinfo = IDENTIFIER_CLASS_VALUE (get_time_identifier (input_filename));
+ tree fileinfo
+ = TIME_IDENTIFIER_FILEINFO (get_time_identifier (input_filename));
char *main_filename = main_input_filename ? main_input_filename : input_filename;
main_filename = file_name_nondirectory (main_filename);
@@ -4891,7 +4961,6 @@ handle_cp_pragma (pname)
if (token != END_OF_LINE)
warning ("garbage after `#pragma implementation' ignored");
-#ifndef NO_LINKAGE_HEURISTICS
if (write_virtuals == 3)
{
struct impl_files *ifiles = impl_file_chain;
@@ -4936,13 +5005,31 @@ handle_cp_pragma (pname)
#endif
TREE_INT_CST_LOW (fileinfo) = interface_only;
TREE_INT_CST_HIGH (fileinfo) = interface_unknown;
-#endif /* NO_LINKAGE_HEURISTICS */
return 1;
}
return 0;
}
+
+/* Return the type-qualifier corresponding to the identifier given by
+ RID. */
+
+int
+cp_type_qual_from_rid (rid)
+ tree rid;
+{
+ if (rid == ridpointers[(int) RID_CONST])
+ return TYPE_QUAL_CONST;
+ else if (rid == ridpointers[(int) RID_VOLATILE])
+ return TYPE_QUAL_VOLATILE;
+ else if (rid == ridpointers[(int) RID_RESTRICT])
+ return TYPE_QUAL_RESTRICT;
+
+ my_friendly_abort (0);
+ return TYPE_UNQUALIFIED;
+}
+
#ifdef HANDLE_GENERIC_PRAGMAS
@@ -4963,29 +5050,21 @@ handle_generic_pragma (token)
{
case IDENTIFIER:
case TYPENAME:
- case STRING:
- case CONSTANT:
- handle_pragma_token (IDENTIFIER_POINTER(yylval.ttype), yylval.ttype);
- break;
- case '(':
- handle_pragma_token ("(", NULL_TREE);
- break;
- case ')':
- handle_pragma_token (")", NULL_TREE);
- break;
- case ',':
- handle_pragma_token (",", NULL_TREE);
- break;
- case '=':
- handle_pragma_token ("=", NULL_TREE);
+ case STRING:
+ case CONSTANT:
+ handle_pragma_token (token_buffer, yylval.ttype);
break;
+
case LEFT_RIGHT:
handle_pragma_token ("(", NULL_TREE);
handle_pragma_token (")", NULL_TREE);
break;
+
case END_OF_LINE:
- default:
return handle_pragma_token (NULL_PTR, NULL_TREE);
+
+ default:
+ handle_pragma_token (token_buffer, NULL);
}
token = real_yylex ();
diff --git a/gcc/cp/lex.h b/gcc/cp/lex.h
index 98add36ff17..249eef9bb0f 100644
--- a/gcc/cp/lex.h
+++ b/gcc/cp/lex.h
@@ -1,5 +1,5 @@
/* Define constants and variables for communication with parse.y.
- Copyright (C) 1987, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
+ Copyright (C) 1987, 92-97, 1998 Free Software Foundation, Inc.
Hacked by Michael Tiemann (tiemann@cygnus.com)
and by Brendan Kehoe (brendan@cygnus.com).
@@ -64,6 +64,7 @@ enum rid
RID_AUTO,
RID_MUTABLE,
RID_COMPLEX,
+ RID_RESTRICT,
/* This is where grokdeclarator ends its search when setting the
specbits. */
diff --git a/gcc/cp/method.c b/gcc/cp/method.c
index 1dbf8a24cce..d05f61e7265 100644
--- a/gcc/cp/method.c
+++ b/gcc/cp/method.c
@@ -1,6 +1,6 @@
/* Handle the hair of processing (but not expanding) inline functions.
Also manage function and variable name overloading.
- Copyright (C) 1987, 89, 92-97, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1987, 89, 92-97, 1998, 1999 Free Software Foundation, Inc.
Contributed by Michael Tiemann (tiemann@cygnus.com)
This file is part of GNU CC.
@@ -58,7 +58,8 @@ static char *scratch_firstobj;
static void icat PROTO((HOST_WIDE_INT));
static void dicat PROTO((HOST_WIDE_INT, HOST_WIDE_INT));
-static void flush_repeats PROTO((int, tree));
+static int old_backref_index PROTO((tree));
+static int flush_repeats PROTO((int, tree));
static void build_overload_identifier PROTO((tree));
static void build_overload_nested_name PROTO((tree));
static void build_overload_int PROTO((tree, int));
@@ -81,6 +82,9 @@ static int check_ktype PROTO((tree, int));
static int issue_ktype PROTO((tree));
static void build_overload_scope_ref PROTO((tree));
static void build_mangled_template_parm_index PROTO((char *, tree));
+#if HOST_BITS_PER_WIDE_INT >= 64
+static void build_mangled_C9x_name PROTO((int));
+#endif
static int is_back_referenceable_type PROTO((tree));
static int check_btype PROTO((tree));
static void build_mangled_name_for_type PROTO((tree));
@@ -297,15 +301,48 @@ dicat (lo, hi)
OB_PUTC ('0' + ulo);
}
-static __inline void
+/* Returns the index of TYPE in the typevec, or -1 if it's not there. */
+
+static __inline int
+old_backref_index (type)
+ tree type;
+{
+ int tindex = 0;
+
+ if (! is_back_referenceable_type (type))
+ return -1;
+
+ /* The entry for this parm is at maxtype-1, so don't look there for
+ something to repeat. */
+ for (tindex = 0; tindex < maxtype - 1; ++tindex)
+ if (same_type_p (typevec[tindex], type))
+ break;
+
+ if (tindex == maxtype - 1)
+ return -1;
+
+ return tindex;
+}
+
+/* Old mangling style: If TYPE has already been used in the parameter list,
+ emit a backward reference and return non-zero; otherwise, return 0.
+
+ NREPEATS is the number of repeats we've recorded of this type, or 0 if
+ this is the first time we've seen it and we're just looking to see if
+ it had been used before. */
+
+static __inline int
flush_repeats (nrepeats, type)
int nrepeats;
tree type;
{
- int tindex = 0;
+ int tindex = old_backref_index (type);
- while (typevec[tindex] != type)
- tindex++;
+ if (tindex == -1)
+ {
+ my_friendly_assert (nrepeats == 0, 990316);
+ return 0;
+ }
if (nrepeats > 1)
{
@@ -319,17 +356,19 @@ flush_repeats (nrepeats, type)
icat (tindex);
if (tindex > 9)
OB_PUTC ('_');
+
+ return 1;
}
/* Returns nonzero iff this is a type to which we will want to make
back-references (using the `B' code). */
-int
+static int
is_back_referenceable_type (type)
tree type;
{
- if (btypelist == NULL)
- /* We're not generating any back-references. */
+ /* For some reason, the Java folks don't want back refs on these. */
+ if (TYPE_FOR_JAVA (type))
return 0;
switch (TREE_CODE (type))
@@ -375,8 +414,10 @@ issue_nrepeats (nrepeats, type)
}
}
-/* Check to see if a tree node has been entered into the Kcode typelist */
-/* if not, add it. Return -1 if it isn't found, otherwise return the index */
+/* Check to see if a tree node has been entered into the Kcode typelist.
+ If not, add it. Returns -1 if it isn't found, otherwise returns the
+ index. */
+
static int
check_ktype (node, add)
tree node;
@@ -393,10 +434,10 @@ check_ktype (node, add)
for (x=0; x < maxktype; x++)
{
- if (localnode == ktypelist[x])
- return x ;
+ if (same_type_p (localnode, ktypelist[x]))
+ return x;
}
- /* Didn't find it, so add it here */
+ /* Didn't find it, so add it here. */
if (add)
{
if (maxksize <= maxktype)
@@ -624,6 +665,42 @@ build_mangled_template_parm_index (s, index)
}
+/* Mangling for C9X integer types (and Cygnus extensions for 128-bit
+ and other types) is based on the letter "I" followed by the hex
+ representations of the bitsize for the type in question. For
+ encodings that result in larger than two digits, a leading and
+ trailing underscore is added.
+
+ Thus:
+ int1_t = 001 = I01
+ int8_t = 008 = I08
+ int16_t = 010 = I10
+ int24_t = 018 = I18
+ int32_t = 020 = I20
+ int64_t = 040 = I40
+ int80_t = 050 = I50
+ int128_t = 080 = I80
+ int256_t = 100 = I_100_
+ int512_t = 200 = I_200_
+
+ Given an integer in decimal format, mangle according to this scheme. */
+
+#if HOST_BITS_PER_WIDE_INT >= 64
+static void
+build_mangled_C9x_name (bits)
+ int bits;
+{
+ char mangled[10] = "";
+
+ if (bits > 255)
+ sprintf (mangled, "I_%x_", bits);
+ else
+ sprintf (mangled, "I%.2x", bits);
+
+ OB_PUTCP (mangled);
+}
+#endif
+
static void
build_overload_value (type, value, in_template)
tree type, value;
@@ -663,9 +740,6 @@ build_overload_value (type, value, in_template)
return;
}
- if (TYPE_PTRMEMFUNC_P (type))
- type = TYPE_PTRMEMFUNC_FN_TYPE (type);
-
switch (TREE_CODE (type))
{
case INTEGER_TYPE:
@@ -742,46 +816,6 @@ build_overload_value (type, value, in_template)
return;
}
case POINTER_TYPE:
- if (TREE_CODE (TREE_TYPE (type)) == METHOD_TYPE
- && TREE_CODE (value) != ADDR_EXPR)
- {
- if (TREE_CODE (value) == CONSTRUCTOR)
- {
- /* This is dangerous code, crack built up pointer to members. */
- tree args = CONSTRUCTOR_ELTS (value);
- tree a1 = TREE_VALUE (args);
- tree a2 = TREE_VALUE (TREE_CHAIN (args));
- tree a3 = CONSTRUCTOR_ELTS (TREE_VALUE (TREE_CHAIN (TREE_CHAIN (args))));
- a3 = TREE_VALUE (a3);
- STRIP_NOPS (a3);
- if (TREE_CODE (a1) == INTEGER_CST
- && TREE_CODE (a2) == INTEGER_CST)
- {
- build_overload_int (a1, in_template);
- OB_PUTC ('_');
- build_overload_int (a2, in_template);
- OB_PUTC ('_');
- if (TREE_CODE (a3) == ADDR_EXPR)
- {
- a3 = TREE_OPERAND (a3, 0);
- if (TREE_CODE (a3) == FUNCTION_DECL)
- {
- numeric_output_need_bar = 0;
- build_overload_identifier (DECL_ASSEMBLER_NAME (a3));
- return;
- }
- }
- else if (TREE_CODE (a3) == INTEGER_CST)
- {
- OB_PUTC ('i');
- build_overload_int (a3, in_template);
- return;
- }
- }
- }
- sorry ("template instantiation with pointer to method that is too complex");
- return;
- }
if (TREE_CODE (value) == INTEGER_CST)
{
build_overload_int (value, in_template);
@@ -795,6 +829,10 @@ build_overload_value (type, value, in_template)
}
value = TREE_OPERAND (value, 0);
+
+ /* Fall through. */
+
+ case REFERENCE_TYPE:
if (TREE_CODE (value) == VAR_DECL)
{
my_friendly_assert (DECL_NAME (value) != 0, 245);
@@ -813,6 +851,35 @@ build_overload_value (type, value, in_template)
my_friendly_abort (71);
break; /* not really needed */
+ case RECORD_TYPE:
+ {
+ tree delta;
+ tree idx;
+ tree pfn;
+ tree delta2;
+
+ my_friendly_assert (TYPE_PTRMEMFUNC_P (type), 0);
+ my_friendly_assert (TREE_CODE (value) == PTRMEM_CST, 0);
+
+ expand_ptrmemfunc_cst (value, &delta, &idx, &pfn, &delta2);
+ build_overload_int (delta, in_template);
+ OB_PUTC ('_');
+ build_overload_int (idx, in_template);
+ OB_PUTC ('_');
+ if (pfn)
+ {
+ numeric_output_need_bar = 0;
+ build_overload_identifier (DECL_ASSEMBLER_NAME
+ (PTRMEM_CST_MEMBER (value)));
+ }
+ else
+ {
+ OB_PUTC ('i');
+ build_overload_int (delta2, in_template);
+ }
+ }
+ break;
+
default:
sorry ("conversion of %s as template parameter",
tree_code_name [(int) TREE_CODE (type)]);
@@ -822,7 +889,7 @@ build_overload_value (type, value, in_template)
/* Add encodings for the declaration of template template parameters.
- PARMLIST must be a TREE_VEC */
+ PARMLIST must be a TREE_VEC. */
static void
build_template_template_parm_names (parmlist)
@@ -879,9 +946,9 @@ build_template_parm_names (parmlist, arglist)
}
else if (TREE_CODE (parm) == TEMPLATE_DECL)
{
- /* This parameter is a template. */
+ /* This parameter is a template. */
if (TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM)
- /* Output parameter declaration, argument index and level */
+ /* Output parameter declaration, argument index and level. */
build_mangled_name_for_type (arg);
else
{
@@ -889,14 +956,15 @@ build_template_parm_names (parmlist, arglist)
and template name */
OB_PUTC ('z');
- build_template_template_parm_names (DECL_INNERMOST_TEMPLATE_PARMS (parm));
+ build_template_template_parm_names
+ (DECL_INNERMOST_TEMPLATE_PARMS (parm));
icat (IDENTIFIER_LENGTH (DECL_NAME (arg)));
OB_PUTID (DECL_NAME (arg));
}
}
else
{
- parm = tsubst (parm, arglist, NULL_TREE);
+ parm = tsubst (parm, arglist, /*complain=*/1, NULL_TREE);
/* It's a PARM_DECL. */
build_mangled_name_for_type (TREE_TYPE (parm));
build_overload_value (TREE_TYPE (parm), arg,
@@ -913,7 +981,7 @@ build_overload_identifier (name)
tree name;
{
if (TREE_CODE (name) == TYPE_DECL
- && IS_AGGR_TYPE (TREE_TYPE (name))
+ && CLASS_TYPE_P (TREE_TYPE (name))
&& CLASSTYPE_TEMPLATE_INFO (TREE_TYPE (name))
&& (PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (TREE_TYPE (name)))
|| (TREE_CODE (DECL_CONTEXT (CLASSTYPE_TI_TEMPLATE
@@ -970,15 +1038,18 @@ build_qualified_name (decl)
}
context = decl;
- /* if we can't find a Ktype, do it the hard way */
+ /* If we can't find a Ktype, do it the hard way. */
if (check_ktype (context, FALSE) == -1)
{
- /* count type and namespace scopes */
- while (DECL_CONTEXT (context) && DECL_CONTEXT (context) != global_namespace)
+ /* Count type and namespace scopes. */
+ while (1)
{
+ context = CP_DECL_CONTEXT (context);
+ if (context == global_namespace)
+ break;
i += 1;
- context = DECL_CONTEXT (context);
- if (check_ktype (context, FALSE) != -1) /* found it! */
+ if (check_ktype (context, FALSE) != -1)
+ /* Found one! */
break;
if (TREE_CODE_CLASS (TREE_CODE (context)) == 't')
context = TYPE_NAME (context);
@@ -998,14 +1069,13 @@ build_qualified_name (decl)
non-zero, mangled names for structure/union types are intentionally
mangled differently from the method described in the ARM. */
-void
+static void
build_mangled_name_for_type_with_Gcode (type, extra_Gcode)
tree type;
int extra_Gcode;
{
if (TYPE_PTRMEMFUNC_P (type))
type = TYPE_PTRMEMFUNC_FN_TYPE (type);
- type = canonical_type_variant (type);
process_modifiers (type);
process_overload_item (type, extra_Gcode);
}
@@ -1013,7 +1083,7 @@ build_mangled_name_for_type_with_Gcode (type, extra_Gcode)
/* Like build_mangled_name_for_type_with_Gcode, but never outputs the
`G'. */
-void
+static void
build_mangled_name_for_type (type)
tree type;
{
@@ -1069,7 +1139,11 @@ build_mangled_name (parmtypes, begin, end)
for (; parmtypes && parmtypes != void_list_node;
parmtypes = TREE_CHAIN (parmtypes))
{
- tree parmtype = canonical_type_variant (TREE_VALUE (parmtypes));
+ /* We used to call canonical_type_variant here, but that isn't
+ good enough; it doesn't handle pointers to typedef types. So
+ we can't just set TREE_USED to say we've seen a type already;
+ we have to check each of the earlier types with same_type_p. */
+ tree parmtype = TREE_VALUE (parmtypes);
if (old_style_repeats)
{
@@ -1078,11 +1152,11 @@ build_mangled_name (parmtypes, begin, end)
typevec[maxtype++] = parmtype;
}
- if (parmtype == last_type)
+ if (last_type && same_type_p (parmtype, last_type))
{
if (flag_do_squangling
- || (old_style_repeats && TREE_USED (parmtype)
- && !TYPE_FOR_JAVA (parmtype)))
+ || (old_style_repeats
+ && is_back_referenceable_type (parmtype)))
{
/* The next type is the same as this one. Keep
track of the repetition, and output the repeat
@@ -1104,35 +1178,11 @@ build_mangled_name (parmtypes, begin, end)
last_type = parmtype;
- if (old_style_repeats)
- {
- if (nrepeats)
- {
- flush_repeats (nrepeats, last_type);
- nrepeats = 0;
- }
-
- if (TREE_USED (parmtype))
- {
-#if 0
- /* We can turn this on at some point when we want
- improved symbol mangling. */
- nrepeats++;
-#else
- /* This is bug compatible with 2.7.x */
- flush_repeats (nrepeats, parmtype);
-#endif
- nrepeats = 0;
- continue;
- }
-
- /* Only cache types which take more than one character. */
- if ((parmtype != TYPE_MAIN_VARIANT (parmtype)
- || (TREE_CODE (parmtype) != INTEGER_TYPE
- && TREE_CODE (parmtype) != REAL_TYPE))
- && ! TYPE_FOR_JAVA (parmtype))
- TREE_USED (parmtype) = 1;
- }
+ /* Note that for bug-compatibility with 2.7.2, we can't build up
+ repeats of types other than the most recent one. So we call
+ flush_repeats every round, if we get this far. */
+ if (old_style_repeats && flush_repeats (0, parmtype))
+ continue;
/* Output the PARMTYPE. */
build_mangled_name_for_type_with_Gcode (parmtype, 1);
@@ -1159,27 +1209,37 @@ build_mangled_name (parmtypes, begin, end)
return (char *)obstack_base (&scratch_obstack);
}
-/* handles emitting modifiers such as Constant, read-only, and volatile */
-void
+/* Emit modifiers such as constant, read-only, and volatile. */
+
+static void
process_modifiers (parmtype)
tree parmtype;
{
- if (TREE_READONLY (parmtype))
+ /* Note that here we do not use CP_TYPE_CONST_P and friends because
+ we describe types recursively; we will get the `const' in
+ `const int ()[10]' when processing the `const int' part. */
+ if (TYPE_READONLY (parmtype))
OB_PUTC ('C');
if (TREE_CODE (parmtype) == INTEGER_TYPE
+ && parmtype != char_type_node
+ && parmtype != wchar_type_node
&& (TYPE_MAIN_VARIANT (parmtype)
== unsigned_type (TYPE_MAIN_VARIANT (parmtype)))
&& ! TYPE_FOR_JAVA (parmtype))
OB_PUTC ('U');
if (TYPE_VOLATILE (parmtype))
OB_PUTC ('V');
+ /* It would be better to use `R' for `restrict', but that's already
+ used for reference types. And `r' is used for `long double'. */
+ if (TYPE_RESTRICT (parmtype))
+ OB_PUTC ('u');
}
/* Check to see if TYPE has been entered into the Bcode typelist. If
so, return 1 and emit a backreference to TYPE. Otherwise, add TYPE
to the list of back-referenceable types and return 0. */
-int
+static int
check_btype (type)
tree type;
{
@@ -1191,12 +1251,8 @@ check_btype (type)
if (!is_back_referenceable_type (type))
return 0;
- /* We assume that our caller has put out any necessary
- qualifiers. */
- type = TYPE_MAIN_VARIANT (type);
-
for (x = 0; x < maxbtype; x++)
- if (type == btypelist[x])
+ if (same_type_p (type, btypelist[x]))
{
OB_PUTC ('B');
icat (x);
@@ -1218,7 +1274,8 @@ check_btype (type)
return 0;
}
-/* handle emitting the correct code for various node types */
+/* Emit the correct code for various node types. */
+
static void
process_overload_item (parmtype, extra_Gcode)
tree parmtype;
@@ -1226,9 +1283,17 @@ process_overload_item (parmtype, extra_Gcode)
{
numeric_output_need_bar = 0;
- /* These tree types are considered modifiers for B code squangling , */
- /* and therefore should not get entries in the Btypelist */
- /* they are, however, repeatable types */
+ /* Our caller should have already handed any qualifiers, so pull out the
+ TYPE_MAIN_VARIANT to avoid typedef confusion. Except we can't do that
+ for arrays, because they are transparent to qualifiers. Sigh. */
+ if (TREE_CODE (parmtype) == ARRAY_TYPE)
+ parmtype = canonical_type_variant (parmtype);
+ else
+ parmtype = TYPE_MAIN_VARIANT (parmtype);
+
+ /* These tree types are considered modifiers for B code squangling,
+ and therefore should not get entries in the Btypelist. They are,
+ however, repeatable types. */
switch (TREE_CODE (parmtype))
{
@@ -1329,7 +1394,6 @@ process_overload_item (parmtype, extra_Gcode)
}
case INTEGER_TYPE:
- parmtype = TYPE_MAIN_VARIANT (parmtype);
if (parmtype == integer_type_node
|| parmtype == unsigned_type_node
|| parmtype == java_int_type_node)
@@ -1357,15 +1421,18 @@ process_overload_item (parmtype, extra_Gcode)
|| parmtype == long_long_unsigned_type_node
|| parmtype == java_long_type_node)
OB_PUTC ('x');
-#if 0
- /* it would seem there is no way to enter these in source code,
- yet. (mrs) */
- else if (parmtype == long_long_long_integer_type_node
- || parmtype == long_long_long_unsigned_type_node)
- OB_PUTC ('q');
-#endif
else if (parmtype == java_boolean_type_node)
OB_PUTC ('b');
+#if HOST_BITS_PER_WIDE_INT >= 64
+ else if (parmtype == intTI_type_node
+ || parmtype == unsigned_intTI_type_node)
+ {
+ /* Should just check a flag here instead of specific
+ *_type_nodes, because all C9x types could use this. */
+ int bits = TREE_INT_CST_LOW (TYPE_SIZE (parmtype));
+ build_mangled_C9x_name (bits);
+ }
+#endif
else
my_friendly_abort (73);
break;
@@ -1375,7 +1442,6 @@ process_overload_item (parmtype, extra_Gcode)
break;
case REAL_TYPE:
- parmtype = TYPE_MAIN_VARIANT (parmtype);
if (parmtype == long_double_type_node)
OB_PUTC ('r');
else if (parmtype == double_type_node
@@ -1425,14 +1491,14 @@ process_overload_item (parmtype, extra_Gcode)
case TEMPLATE_TEMPLATE_PARM:
/* Find and output the original template parameter
declaration. */
- if (CLASSTYPE_TEMPLATE_INFO (parmtype))
+ if (TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (parmtype))
{
build_mangled_template_parm_index ("tzX",
TEMPLATE_TYPE_PARM_INDEX
(parmtype));
build_template_parm_names
- (DECL_INNERMOST_TEMPLATE_PARMS (CLASSTYPE_TI_TEMPLATE (parmtype)),
- CLASSTYPE_TI_ARGS (parmtype));
+ (DECL_INNERMOST_TEMPLATE_PARMS (TYPE_TI_TEMPLATE (parmtype)),
+ TYPE_TI_ARGS (parmtype));
}
else
{
@@ -1553,12 +1619,13 @@ build_decl_overload_real (dname, parms, ret_type, tparms, targs,
OB_PUTC ('v');
else
{
- if (!flag_do_squangling) /* Allocate typevec array. */
+ if (!flag_do_squangling)
{
+ /* Allocate typevec array. */
maxtype = 0;
typevec_size = list_length (parms);
if (!for_method && current_namespace != global_namespace)
- /* the namespace of a global function needs one slot */
+ /* The namespace of a global function needs one slot. */
typevec_size++;
typevec = (tree *)alloca (typevec_size * sizeof (tree));
}
@@ -1579,12 +1646,6 @@ build_decl_overload_real (dname, parms, ret_type, tparms, targs,
{
my_friendly_assert (maxtype < typevec_size, 387);
typevec[maxtype++] = this_type;
- TREE_USED (this_type) = 1;
-
- /* By setting up PARMS in this way, the loop below will
- automatically clear TREE_USED on THIS_TYPE. */
- parms = temp_tree_cons (NULL_TREE, this_type,
- TREE_CHAIN (parms));
}
if (TREE_CHAIN (parms))
@@ -1605,20 +1666,9 @@ build_decl_overload_real (dname, parms, ret_type, tparms, targs,
build_mangled_name (parms, 0, 0);
}
- if (!flag_do_squangling) /* Deallocate typevec array */
- {
- tree t = parms;
- typevec = NULL;
- while (t)
- {
- tree temp = TREE_VALUE (t);
- TREE_USED (temp) = 0;
- /* clear out the type variant in case we used it */
- temp = canonical_type_variant (temp);
- TREE_USED (temp) = 0;
- t = TREE_CHAIN (t);
- }
- }
+ if (!flag_do_squangling)
+ /* Deallocate typevec array. */
+ typevec = NULL;
}
if (ret_type != NULL_TREE && for_method != 2)
@@ -1663,7 +1713,13 @@ void
set_mangled_name_for_decl (decl)
tree decl;
{
- tree parm_types = TYPE_ARG_TYPES (TREE_TYPE (decl));
+ tree parm_types;
+
+ if (processing_template_decl)
+ /* There's no need to mangle the name of a template function. */
+ return;
+
+ parm_types = TYPE_ARG_TYPES (TREE_TYPE (decl));
if (DECL_STATIC_FUNCTION_P (decl))
parm_types =
@@ -1861,6 +1917,17 @@ hack_identifier (value, name)
TREE_USED (value) = 1;
value = build_component_ref (current_class_ref, name, NULL_TREE, 1);
}
+ else if (TREE_CODE (value) == FUNCTION_DECL
+ && DECL_FUNCTION_MEMBER_P (value))
+ {
+ tree decl;
+
+ if (IS_SIGNATURE (DECL_CLASS_CONTEXT (value)))
+ return value;
+
+ decl = maybe_dummy_object (DECL_CLASS_CONTEXT (value), 0);
+ value = build_component_ref (decl, name, NULL_TREE, 1);
+ }
else if (really_overloaded_fn (value))
{
#if 0
@@ -1901,7 +1968,8 @@ hack_identifier (value, name)
else
mark_used (value);
- if (TREE_CODE (value) == VAR_DECL || TREE_CODE (value) == PARM_DECL)
+ if (TREE_CODE (value) == VAR_DECL || TREE_CODE (value) == PARM_DECL
+ || TREE_CODE (value) == RESULT_DECL)
{
tree context = decl_function_context (value);
if (context != NULL_TREE && context != current_function_decl
@@ -1920,35 +1988,22 @@ hack_identifier (value, name)
if (DECL_LANG_SPECIFIC (value)
&& DECL_CLASS_CONTEXT (value) != current_class_type)
{
- tree path, access;
+ tree path;
register tree context
= (TREE_CODE (value) == FUNCTION_DECL && DECL_VIRTUAL_P (value))
? DECL_CLASS_CONTEXT (value)
: DECL_CONTEXT (value);
get_base_distance (context, current_class_type, 0, &path);
- if (path)
- {
- access = compute_access (path, value);
- if (access != access_public_node)
- {
- if (TREE_CODE (value) == VAR_DECL)
- error ("static member `%s' is %s",
- IDENTIFIER_POINTER (name),
- TREE_PRIVATE (value) ? "private"
- : "from a private base class");
- else
- error ("enum `%s' is from private base class",
- IDENTIFIER_POINTER (name));
- return error_mark_node;
- }
- }
+ if (path && !enforce_access (current_class_type, value))
+ return error_mark_node;
}
}
else if (TREE_CODE (value) == TREE_LIST && TREE_NONLOCAL_FLAG (value))
{
error ("request for member `%s' is ambiguous in multiple inheritance lattice",
IDENTIFIER_POINTER (name));
+ print_candidates (value);
return error_mark_node;
}
diff --git a/gcc/cp/new.cc b/gcc/cp/new.cc
index 28187a43884..3197012150d 100644
--- a/gcc/cp/new.cc
+++ b/gcc/cp/new.cc
@@ -1,5 +1,5 @@
// Implementation file for the -*- C++ -*- dynamic memory management header.
-// Copyright (C) 1996 Free Software Foundation
+// Copyright (C) 1996, 1997, 1998 Free Software Foundation
// This file is part of GNU CC.
diff --git a/gcc/cp/new1.cc b/gcc/cp/new1.cc
index 5bb85c94f15..73fbcd2b1fd 100644
--- a/gcc/cp/new1.cc
+++ b/gcc/cp/new1.cc
@@ -1,5 +1,5 @@
// Support routines for the -*- C++ -*- dynamic memory management.
-// Copyright (C) 1997 Free Software Foundation
+// Copyright (C) 1997, 1998 Free Software Foundation
// This file is part of GNU CC.
diff --git a/gcc/cp/new2.cc b/gcc/cp/new2.cc
index 0be1c0d8c7f..2833ea23414 100644
--- a/gcc/cp/new2.cc
+++ b/gcc/cp/new2.cc
@@ -1,5 +1,5 @@
// Boilerplate support routines for -*- C++ -*- dynamic memory management.
-// Copyright (C) 1997 Free Software Foundation
+// Copyright (C) 1997, 1998 Free Software Foundation
// This file is part of GNU CC.
diff --git a/gcc/cp/parse.c b/gcc/cp/parse.c
index 9ac44964ab0..4ae0f0f4ad8 100644
--- a/gcc/cp/parse.c
+++ b/gcc/cp/parse.c
@@ -126,9 +126,10 @@ extern int end_of_file;
/* Contains the statement keyword (if/while/do) to include in an
error message if the user supplies an empty conditional expression. */
-static char *cond_stmt_keyword;
+static const char *cond_stmt_keyword;
static tree empty_parms PROTO((void));
+static int parse_decl PROTO((tree, tree, tree, int, tree *));
/* Nonzero if we have an `extern "C"' acting as an extern specifier. */
int have_extern_spec;
@@ -152,9 +153,9 @@ empty_parms ()
}
-#line 92 "parse.y"
+#line 93 "parse.y"
typedef union {long itype; tree ttype; char *strtype; enum tree_code code; flagged_type_tree ftype; } YYSTYPE;
-#line 281 "parse.y"
+#line 285 "parse.y"
/* List of types and structure classes of the current declaration. */
static tree current_declspecs;
@@ -215,11 +216,11 @@ parse_decl(declarator, specs_attrs, attributes, initialized, decl)
-#define YYFINAL 1609
+#define YYFINAL 1629
#define YYFLAG -32768
#define YYNTBASE 112
-#define YYTRANSLATE(x) ((unsigned)(x) <= 342 ? yytranslate[x] : 396)
+#define YYTRANSLATE(x) ((unsigned)(x) <= 342 ? yytranslate[x] : 399)
static const char yytranslate[] = { 0,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
@@ -278,457 +279,459 @@ static const short yyprhs[] = { 0,
465, 467, 469, 471, 473, 475, 477, 479, 481, 483,
485, 486, 493, 494, 501, 502, 508, 509, 515, 516,
524, 525, 533, 534, 541, 542, 549, 550, 551, 557,
- 563, 565, 571, 572, 574, 576, 577, 579, 581, 585,
- 587, 589, 591, 593, 595, 597, 599, 601, 603, 605,
- 607, 611, 613, 617, 618, 620, 622, 623, 631, 633,
- 635, 639, 644, 648, 649, 653, 655, 659, 663, 667,
- 671, 673, 675, 677, 680, 683, 686, 689, 692, 695,
- 698, 703, 706, 711, 714, 718, 722, 727, 733, 740,
- 747, 755, 758, 763, 769, 772, 775, 777, 778, 783,
- 788, 792, 794, 798, 801, 805, 810, 812, 815, 821,
- 823, 827, 831, 835, 839, 843, 847, 851, 855, 859,
+ 563, 565, 567, 573, 579, 580, 582, 584, 585, 587,
+ 589, 593, 595, 597, 599, 601, 603, 605, 607, 609,
+ 611, 613, 615, 619, 621, 625, 626, 628, 630, 631,
+ 639, 641, 643, 647, 652, 656, 657, 661, 663, 667,
+ 671, 675, 679, 681, 683, 685, 688, 691, 694, 697,
+ 700, 703, 706, 711, 714, 719, 722, 726, 730, 735,
+ 741, 748, 755, 763, 766, 771, 777, 780, 783, 785,
+ 786, 791, 796, 800, 802, 806, 809, 813, 818, 820,
+ 823, 829, 831, 835, 839, 843, 847, 851, 855, 859,
863, 867, 871, 875, 879, 883, 887, 891, 895, 899,
- 905, 909, 913, 915, 918, 922, 926, 928, 930, 932,
- 934, 936, 937, 943, 949, 955, 961, 967, 969, 971,
- 973, 975, 978, 981, 985, 990, 995, 997, 999, 1001,
- 1005, 1007, 1009, 1011, 1013, 1017, 1021, 1025, 1026, 1031,
- 1036, 1039, 1044, 1047, 1052, 1055, 1058, 1060, 1065, 1067,
- 1075, 1083, 1091, 1099, 1104, 1109, 1112, 1115, 1118, 1120,
- 1125, 1128, 1131, 1137, 1141, 1144, 1147, 1153, 1157, 1163,
- 1167, 1172, 1179, 1182, 1184, 1187, 1189, 1192, 1194, 1196,
- 1198, 1201, 1202, 1205, 1208, 1212, 1216, 1220, 1223, 1226,
- 1229, 1231, 1233, 1235, 1238, 1241, 1244, 1247, 1249, 1251,
- 1253, 1255, 1258, 1261, 1265, 1269, 1273, 1278, 1280, 1283,
- 1286, 1289, 1291, 1293, 1295, 1298, 1301, 1304, 1306, 1308,
- 1311, 1314, 1318, 1320, 1323, 1325, 1327, 1329, 1334, 1339,
- 1344, 1349, 1351, 1353, 1355, 1357, 1361, 1363, 1367, 1369,
- 1373, 1374, 1379, 1380, 1387, 1391, 1392, 1397, 1399, 1403,
- 1407, 1408, 1413, 1417, 1418, 1420, 1422, 1425, 1432, 1434,
- 1438, 1439, 1441, 1446, 1453, 1458, 1460, 1462, 1464, 1466,
- 1468, 1472, 1473, 1476, 1478, 1481, 1485, 1490, 1492, 1494,
- 1498, 1503, 1507, 1513, 1515, 1520, 1524, 1528, 1529, 1533,
- 1537, 1541, 1542, 1545, 1548, 1549, 1557, 1562, 1563, 1570,
- 1574, 1577, 1580, 1583, 1584, 1585, 1595, 1597, 1598, 1600,
- 1601, 1603, 1605, 1608, 1611, 1614, 1617, 1620, 1623, 1626,
- 1629, 1632, 1636, 1641, 1645, 1648, 1652, 1654, 1655, 1659,
- 1662, 1665, 1667, 1669, 1670, 1673, 1677, 1679, 1684, 1686,
- 1690, 1692, 1694, 1699, 1704, 1707, 1710, 1714, 1718, 1720,
- 1721, 1723, 1726, 1730, 1733, 1736, 1738, 1741, 1744, 1747,
- 1750, 1753, 1756, 1759, 1761, 1764, 1767, 1771, 1774, 1777,
- 1782, 1787, 1790, 1792, 1798, 1803, 1805, 1806, 1808, 1812,
- 1813, 1815, 1819, 1821, 1823, 1825, 1827, 1832, 1837, 1842,
- 1847, 1852, 1856, 1861, 1866, 1871, 1876, 1880, 1882, 1886,
- 1888, 1892, 1895, 1897, 1905, 1906, 1909, 1911, 1914, 1915,
- 1918, 1923, 1928, 1931, 1936, 1940, 1944, 1947, 1950, 1954,
- 1956, 1958, 1961, 1963, 1965, 1968, 1971, 1976, 1981, 1985,
- 1989, 1992, 1994, 1998, 2002, 2005, 2008, 2012, 2014, 2018,
- 2022, 2025, 2028, 2032, 2034, 2039, 2043, 2048, 2052, 2054,
- 2057, 2060, 2063, 2066, 2069, 2071, 2074, 2079, 2084, 2087,
- 2089, 2091, 2093, 2095, 2098, 2103, 2106, 2109, 2112, 2115,
- 2117, 2120, 2123, 2126, 2129, 2133, 2135, 2138, 2142, 2147,
- 2150, 2153, 2156, 2159, 2162, 2165, 2170, 2173, 2175, 2178,
- 2181, 2185, 2187, 2191, 2194, 2198, 2201, 2204, 2208, 2210,
- 2214, 2219, 2223, 2226, 2229, 2231, 2235, 2238, 2241, 2243,
- 2246, 2250, 2252, 2256, 2258, 2265, 2270, 2275, 2279, 2285,
- 2289, 2293, 2297, 2300, 2302, 2304, 2307, 2310, 2313, 2314,
- 2316, 2318, 2321, 2325, 2327, 2330, 2331, 2335, 2336, 2337,
- 2343, 2345, 2346, 2349, 2351, 2353, 2355, 2358, 2359, 2364,
- 2366, 2367, 2368, 2374, 2375, 2376, 2384, 2385, 2386, 2387,
- 2388, 2401, 2402, 2403, 2411, 2412, 2418, 2419, 2427, 2428,
- 2433, 2436, 2439, 2442, 2446, 2453, 2462, 2473, 2486, 2491,
- 2495, 2498, 2501, 2503, 2505, 2507, 2509, 2511, 2512, 2513,
- 2520, 2521, 2522, 2528, 2530, 2533, 2534, 2535, 2541, 2543,
- 2545, 2549, 2553, 2556, 2559, 2562, 2565, 2568, 2570, 2573,
- 2574, 2576, 2577, 2579, 2581, 2582, 2584, 2586, 2590, 2595,
- 2597, 2601, 2602, 2604, 2606, 2608, 2611, 2614, 2617, 2619,
- 2622, 2625, 2626, 2630, 2632, 2634, 2636, 2639, 2642, 2645,
- 2650, 2653, 2656, 2659, 2662, 2665, 2668, 2670, 2673, 2675,
- 2678, 2680, 2682, 2683, 2684, 2686, 2687, 2692, 2695, 2697,
- 2699, 2703, 2704, 2708, 2712, 2716, 2718, 2721, 2724, 2727,
- 2730, 2733, 2736, 2739, 2742, 2745, 2748, 2751, 2754, 2757,
- 2760, 2763, 2766, 2769, 2772, 2775, 2778, 2781, 2784, 2787,
- 2791, 2794, 2797, 2800, 2803, 2807, 2810, 2813, 2818, 2823,
- 2827
+ 903, 907, 913, 917, 921, 923, 926, 930, 934, 936,
+ 938, 940, 942, 944, 945, 951, 957, 963, 969, 975,
+ 977, 979, 981, 983, 986, 988, 991, 994, 998, 1003,
+ 1008, 1010, 1012, 1014, 1018, 1020, 1022, 1024, 1026, 1030,
+ 1034, 1038, 1039, 1044, 1049, 1052, 1057, 1060, 1065, 1068,
+ 1071, 1073, 1078, 1080, 1088, 1096, 1104, 1112, 1117, 1122,
+ 1125, 1128, 1131, 1133, 1138, 1141, 1144, 1150, 1154, 1157,
+ 1160, 1166, 1170, 1176, 1180, 1185, 1192, 1195, 1197, 1200,
+ 1202, 1205, 1207, 1209, 1211, 1214, 1215, 1218, 1221, 1225,
+ 1229, 1233, 1236, 1239, 1242, 1244, 1246, 1248, 1251, 1254,
+ 1257, 1260, 1262, 1264, 1266, 1268, 1271, 1274, 1278, 1282,
+ 1286, 1291, 1293, 1296, 1299, 1302, 1304, 1306, 1308, 1311,
+ 1314, 1317, 1319, 1321, 1324, 1327, 1331, 1333, 1336, 1338,
+ 1340, 1342, 1347, 1352, 1357, 1362, 1364, 1366, 1368, 1370,
+ 1374, 1376, 1380, 1382, 1386, 1387, 1392, 1393, 1400, 1404,
+ 1405, 1410, 1412, 1416, 1420, 1421, 1426, 1430, 1431, 1433,
+ 1435, 1438, 1445, 1447, 1451, 1452, 1454, 1459, 1466, 1471,
+ 1473, 1475, 1477, 1479, 1481, 1485, 1486, 1489, 1491, 1494,
+ 1498, 1503, 1505, 1507, 1511, 1516, 1520, 1526, 1528, 1533,
+ 1537, 1541, 1542, 1546, 1550, 1554, 1555, 1558, 1561, 1562,
+ 1570, 1575, 1576, 1583, 1587, 1590, 1593, 1596, 1597, 1598,
+ 1608, 1610, 1611, 1613, 1614, 1616, 1618, 1621, 1624, 1627,
+ 1630, 1633, 1636, 1639, 1642, 1645, 1649, 1654, 1658, 1661,
+ 1665, 1667, 1668, 1672, 1673, 1677, 1680, 1682, 1684, 1685,
+ 1688, 1692, 1694, 1699, 1701, 1705, 1707, 1709, 1714, 1719,
+ 1722, 1725, 1729, 1733, 1735, 1736, 1738, 1742, 1745, 1748,
+ 1750, 1753, 1756, 1759, 1762, 1765, 1768, 1771, 1773, 1776,
+ 1779, 1783, 1786, 1789, 1794, 1799, 1802, 1804, 1810, 1815,
+ 1817, 1818, 1820, 1824, 1825, 1827, 1831, 1833, 1835, 1837,
+ 1839, 1844, 1849, 1854, 1859, 1864, 1868, 1873, 1878, 1883,
+ 1888, 1892, 1894, 1898, 1900, 1904, 1907, 1909, 1917, 1918,
+ 1921, 1923, 1926, 1927, 1930, 1935, 1940, 1943, 1948, 1952,
+ 1956, 1959, 1962, 1966, 1968, 1970, 1973, 1975, 1977, 1980,
+ 1983, 1988, 1993, 1997, 2001, 2004, 2006, 2008, 2011, 2015,
+ 2019, 2022, 2025, 2029, 2031, 2035, 2039, 2042, 2045, 2049,
+ 2051, 2056, 2060, 2065, 2069, 2071, 2074, 2077, 2080, 2083,
+ 2086, 2088, 2091, 2096, 2101, 2104, 2106, 2108, 2110, 2112,
+ 2115, 2120, 2123, 2126, 2129, 2132, 2134, 2137, 2140, 2143,
+ 2146, 2150, 2152, 2155, 2159, 2164, 2167, 2170, 2173, 2176,
+ 2179, 2182, 2187, 2190, 2192, 2195, 2198, 2202, 2204, 2208,
+ 2211, 2215, 2218, 2221, 2225, 2227, 2231, 2236, 2240, 2243,
+ 2246, 2248, 2252, 2255, 2258, 2260, 2263, 2267, 2269, 2273,
+ 2275, 2282, 2287, 2292, 2296, 2302, 2306, 2310, 2314, 2317,
+ 2319, 2321, 2324, 2327, 2330, 2331, 2333, 2335, 2338, 2342,
+ 2344, 2347, 2348, 2352, 2353, 2354, 2360, 2362, 2363, 2366,
+ 2368, 2370, 2372, 2375, 2376, 2381, 2383, 2384, 2385, 2391,
+ 2392, 2393, 2401, 2402, 2403, 2404, 2405, 2418, 2419, 2420,
+ 2428, 2429, 2435, 2436, 2444, 2445, 2450, 2453, 2456, 2459,
+ 2463, 2470, 2479, 2490, 2503, 2508, 2512, 2515, 2518, 2520,
+ 2522, 2524, 2526, 2528, 2529, 2530, 2537, 2538, 2539, 2545,
+ 2547, 2550, 2551, 2552, 2558, 2560, 2562, 2566, 2570, 2573,
+ 2576, 2579, 2582, 2585, 2587, 2590, 2591, 2593, 2594, 2596,
+ 2598, 2599, 2601, 2603, 2607, 2612, 2614, 2618, 2619, 2621,
+ 2623, 2625, 2628, 2631, 2634, 2636, 2639, 2642, 2643, 2647,
+ 2649, 2651, 2653, 2656, 2659, 2662, 2667, 2670, 2673, 2676,
+ 2679, 2682, 2685, 2687, 2690, 2692, 2695, 2697, 2699, 2700,
+ 2701, 2703, 2704, 2709, 2712, 2714, 2716, 2720, 2721, 2725,
+ 2729, 2733, 2735, 2738, 2741, 2744, 2747, 2750, 2753, 2756,
+ 2759, 2762, 2765, 2768, 2771, 2774, 2777, 2780, 2783, 2786,
+ 2789, 2792, 2795, 2798, 2801, 2804, 2808, 2811, 2814, 2817,
+ 2820, 2824, 2827, 2830, 2835, 2840, 2844
};
static const short yyrhs[] = { -1,
113, 0, 0, 114, 120, 0, 113, 120, 0, 113,
0, 0, 0, 0, 32, 0, 27, 0, 0, 121,
122, 0, 148, 147, 0, 144, 0, 141, 0, 119,
- 93, 217, 108, 60, 0, 133, 58, 115, 109, 0,
+ 93, 219, 108, 60, 0, 133, 58, 115, 109, 0,
133, 116, 148, 117, 147, 0, 133, 116, 144, 117,
0, 0, 44, 163, 58, 123, 115, 109, 0, 0,
44, 58, 124, 115, 109, 0, 125, 0, 127, 60,
0, 129, 0, 118, 122, 0, 0, 44, 163, 64,
- 126, 132, 60, 0, 46, 310, 0, 46, 324, 310,
- 0, 46, 324, 208, 0, 46, 131, 163, 0, 46,
- 324, 163, 0, 46, 324, 131, 163, 0, 0, 46,
+ 126, 132, 60, 0, 46, 313, 0, 46, 327, 313,
+ 0, 46, 327, 209, 0, 46, 131, 163, 0, 46,
+ 327, 163, 0, 46, 327, 131, 163, 0, 0, 46,
44, 130, 132, 60, 0, 57, 54, 0, 131, 57,
- 54, 0, 208, 0, 310, 0, 324, 310, 0, 324,
- 208, 0, 98, 0, 133, 98, 0, 0, 48, 74,
+ 54, 0, 209, 0, 313, 0, 327, 313, 0, 327,
+ 209, 0, 98, 0, 133, 98, 0, 0, 48, 74,
135, 136, 75, 0, 48, 74, 75, 0, 140, 0,
- 136, 59, 140, 0, 163, 0, 0, 266, 137, 0,
- 45, 137, 0, 134, 266, 137, 0, 138, 0, 138,
- 64, 223, 0, 387, 0, 387, 64, 203, 0, 139,
- 0, 139, 64, 183, 0, 134, 142, 0, 134, 1,
+ 136, 59, 140, 0, 163, 0, 0, 268, 137, 0,
+ 45, 137, 0, 134, 268, 137, 0, 138, 0, 138,
+ 64, 225, 0, 390, 0, 390, 64, 204, 0, 139,
+ 0, 139, 64, 184, 0, 134, 142, 0, 134, 1,
0, 148, 147, 0, 143, 0, 141, 0, 133, 116,
148, 117, 147, 0, 133, 116, 143, 117, 0, 118,
- 142, 0, 234, 60, 0, 227, 233, 60, 0, 224,
- 232, 60, 0, 259, 60, 0, 234, 60, 0, 227,
- 233, 60, 0, 224, 232, 60, 0, 227, 60, 0,
- 166, 60, 0, 224, 60, 0, 1, 60, 0, 1,
- 109, 0, 60, 0, 218, 0, 159, 0, 0, 158,
+ 142, 0, 236, 60, 0, 229, 235, 60, 0, 226,
+ 234, 60, 0, 261, 60, 0, 236, 60, 0, 229,
+ 235, 60, 0, 226, 234, 60, 0, 229, 60, 0,
+ 166, 60, 0, 226, 60, 0, 1, 60, 0, 1,
+ 109, 0, 60, 0, 220, 0, 159, 0, 0, 158,
0, 158, 60, 0, 0, 107, 0, 154, 146, 145,
- 334, 0, 154, 146, 358, 0, 154, 146, 1, 0,
- 0, 315, 5, 93, 150, 378, 108, 297, 390, 0,
- 315, 5, 47, 297, 390, 0, 0, 324, 315, 5,
- 93, 151, 378, 108, 297, 390, 0, 324, 315, 5,
- 47, 297, 390, 0, 0, 315, 178, 93, 152, 378,
- 108, 297, 390, 0, 315, 178, 47, 297, 390, 0,
- 0, 324, 315, 178, 93, 153, 378, 108, 297, 390,
- 0, 324, 315, 178, 47, 297, 390, 0, 224, 221,
- 0, 227, 307, 0, 307, 0, 227, 149, 0, 149,
- 0, 5, 93, 378, 108, 297, 390, 0, 5, 47,
- 297, 390, 0, 178, 93, 378, 108, 297, 390, 0,
- 178, 47, 297, 390, 0, 227, 155, 0, 155, 0,
- 224, 221, 0, 227, 307, 0, 307, 0, 227, 149,
- 0, 149, 0, 25, 3, 0, 157, 251, 0, 157,
- 93, 195, 108, 0, 157, 47, 0, 62, 160, 161,
+ 337, 0, 154, 146, 361, 0, 154, 146, 1, 0,
+ 0, 318, 5, 93, 150, 381, 108, 299, 393, 0,
+ 318, 5, 47, 299, 393, 0, 0, 327, 318, 5,
+ 93, 151, 381, 108, 299, 393, 0, 327, 318, 5,
+ 47, 299, 393, 0, 0, 318, 179, 93, 152, 381,
+ 108, 299, 393, 0, 318, 179, 47, 299, 393, 0,
+ 0, 327, 318, 179, 93, 153, 381, 108, 299, 393,
+ 0, 327, 318, 179, 47, 299, 393, 0, 226, 223,
+ 0, 229, 310, 0, 310, 0, 229, 149, 0, 149,
+ 0, 5, 93, 381, 108, 299, 393, 0, 5, 47,
+ 299, 393, 0, 179, 93, 381, 108, 299, 393, 0,
+ 179, 47, 299, 393, 0, 229, 155, 0, 155, 0,
+ 226, 223, 0, 229, 310, 0, 310, 0, 229, 149,
+ 0, 149, 0, 25, 3, 0, 157, 253, 0, 157,
+ 93, 196, 108, 0, 157, 47, 0, 62, 160, 161,
0, 0, 0, 162, 0, 161, 59, 162, 0, 161,
- 1, 0, 93, 195, 108, 0, 47, 0, 164, 93,
- 195, 108, 0, 164, 47, 0, 303, 93, 195, 108,
- 0, 303, 47, 0, 317, 93, 195, 108, 0, 317,
+ 1, 0, 93, 196, 108, 0, 47, 0, 164, 93,
+ 196, 108, 0, 164, 47, 0, 305, 93, 196, 108,
+ 0, 305, 47, 0, 320, 93, 196, 108, 0, 320,
47, 0, 3, 0, 4, 0, 5, 0, 56, 0,
57, 0, 3, 0, 56, 0, 57, 0, 104, 0,
- 103, 0, 105, 0, 0, 48, 175, 230, 60, 167,
- 176, 0, 0, 48, 175, 224, 221, 168, 176, 0,
- 0, 48, 175, 307, 169, 176, 0, 0, 48, 175,
- 149, 170, 176, 0, 0, 7, 48, 175, 230, 60,
- 171, 176, 0, 0, 7, 48, 175, 224, 221, 172,
- 176, 0, 0, 7, 48, 175, 307, 173, 176, 0,
+ 103, 0, 105, 0, 0, 48, 175, 232, 60, 167,
+ 176, 0, 0, 48, 175, 226, 223, 168, 176, 0,
+ 0, 48, 175, 310, 169, 176, 0, 0, 48, 175,
+ 149, 170, 176, 0, 0, 7, 48, 175, 232, 60,
+ 171, 176, 0, 0, 7, 48, 175, 226, 223, 172,
+ 176, 0, 0, 7, 48, 175, 310, 173, 176, 0,
0, 7, 48, 175, 149, 174, 176, 0, 0, 0,
- 56, 74, 181, 180, 179, 0, 4, 74, 181, 180,
- 179, 0, 178, 0, 5, 74, 181, 180, 179, 0,
- 0, 75, 0, 77, 0, 0, 182, 0, 183, 0,
- 182, 59, 183, 0, 223, 0, 56, 0, 203, 0,
- 79, 0, 78, 0, 86, 0, 87, 0, 110, 0,
- 194, 0, 203, 0, 47, 0, 93, 185, 108, 0,
- 47, 0, 93, 189, 108, 0, 0, 189, 0, 1,
- 0, 0, 368, 221, 235, 244, 64, 190, 252, 0,
- 185, 0, 109, 0, 331, 329, 109, 0, 331, 329,
- 1, 109, 0, 331, 1, 109, 0, 0, 58, 193,
- 191, 0, 343, 0, 203, 59, 203, 0, 203, 59,
- 1, 0, 194, 59, 203, 0, 194, 59, 1, 0,
- 203, 0, 194, 0, 212, 0, 118, 202, 0, 80,
- 202, 0, 70, 202, 0, 88, 202, 0, 184, 202,
- 0, 67, 163, 0, 13, 196, 0, 13, 93, 223,
- 108, 0, 29, 196, 0, 29, 93, 223, 108, 0,
- 214, 296, 0, 214, 296, 200, 0, 214, 199, 296,
- 0, 214, 199, 296, 200, 0, 214, 93, 198, 223,
- 197, 0, 214, 93, 198, 223, 197, 200, 0, 214,
- 199, 93, 198, 223, 197, 0, 214, 199, 93, 198,
- 223, 197, 200, 0, 215, 202, 0, 215, 94, 111,
- 202, 0, 215, 94, 185, 111, 202, 0, 34, 202,
- 0, 35, 202, 0, 108, 0, 0, 93, 198, 195,
- 108, 0, 58, 198, 195, 109, 0, 93, 195, 108,
- 0, 47, 0, 93, 230, 108, 0, 64, 252, 0,
- 93, 223, 108, 0, 201, 93, 223, 108, 0, 196,
- 0, 201, 196, 0, 201, 58, 253, 264, 109, 0,
- 202, 0, 203, 83, 203, 0, 203, 84, 203, 0,
- 203, 78, 203, 0, 203, 79, 203, 0, 203, 80,
- 203, 0, 203, 81, 203, 0, 203, 82, 203, 0,
- 203, 76, 203, 0, 203, 77, 203, 0, 203, 73,
- 203, 0, 203, 74, 203, 0, 203, 75, 203, 0,
- 203, 72, 203, 0, 203, 71, 203, 0, 203, 70,
- 203, 0, 203, 68, 203, 0, 203, 69, 203, 0,
- 203, 67, 203, 0, 203, 66, 203, 0, 203, 65,
- 373, 62, 203, 0, 203, 64, 203, 0, 203, 63,
- 203, 0, 61, 0, 61, 203, 0, 88, 388, 163,
- 0, 88, 388, 177, 0, 206, 0, 395, 0, 3,
- 0, 56, 0, 57, 0, 0, 6, 74, 205, 181,
- 180, 0, 395, 74, 205, 181, 180, 0, 48, 163,
- 74, 181, 180, 0, 48, 6, 74, 181, 180, 0,
- 48, 395, 74, 181, 180, 0, 204, 0, 4, 0,
- 5, 0, 204, 0, 80, 209, 0, 70, 209, 0,
- 93, 209, 108, 0, 3, 74, 181, 180, 0, 57,
- 74, 182, 180, 0, 309, 0, 204, 0, 210, 0,
- 93, 209, 108, 0, 204, 0, 10, 0, 216, 0,
- 217, 0, 93, 185, 108, 0, 93, 209, 108, 0,
- 93, 1, 108, 0, 0, 93, 213, 335, 108, 0,
- 204, 93, 195, 108, 0, 204, 47, 0, 212, 93,
- 195, 108, 0, 212, 47, 0, 212, 94, 185, 111,
- 0, 212, 86, 0, 212, 87, 0, 40, 0, 9,
- 93, 195, 108, 0, 313, 0, 50, 74, 223, 75,
- 93, 185, 108, 0, 51, 74, 223, 75, 93, 185,
- 108, 0, 52, 74, 223, 75, 93, 185, 108, 0,
- 53, 74, 223, 75, 93, 185, 108, 0, 49, 93,
- 185, 108, 0, 49, 93, 223, 108, 0, 324, 3,
- 0, 324, 206, 0, 324, 395, 0, 312, 0, 312,
- 93, 195, 108, 0, 312, 47, 0, 219, 207, 0,
- 219, 207, 93, 195, 108, 0, 219, 207, 47, 0,
- 219, 208, 0, 219, 312, 0, 219, 208, 93, 195,
- 108, 0, 219, 208, 47, 0, 219, 312, 93, 195,
- 108, 0, 219, 312, 47, 0, 219, 88, 8, 47,
- 0, 219, 8, 54, 88, 8, 47, 0, 219, 1,
- 0, 39, 0, 324, 39, 0, 38, 0, 324, 215,
- 0, 42, 0, 43, 0, 11, 0, 217, 11, 0,
- 0, 212, 92, 0, 212, 91, 0, 230, 232, 60,
- 0, 224, 232, 60, 0, 227, 233, 60, 0, 224,
- 60, 0, 227, 60, 0, 118, 220, 0, 302, 0,
- 307, 0, 47, 0, 222, 47, 0, 228, 327, 0,
- 298, 327, 0, 230, 327, 0, 228, 0, 298, 0,
- 228, 0, 225, 0, 227, 230, 0, 230, 226, 0,
- 230, 229, 226, 0, 227, 230, 226, 0, 227, 230,
- 229, 0, 227, 230, 229, 226, 0, 7, 0, 226,
- 231, 0, 226, 7, 0, 226, 245, 0, 245, 0,
- 298, 0, 7, 0, 227, 9, 0, 227, 7, 0,
- 227, 245, 0, 245, 0, 230, 0, 298, 230, 0,
- 230, 229, 0, 298, 230, 229, 0, 231, 0, 229,
- 231, 0, 259, 0, 8, 0, 304, 0, 28, 93,
- 185, 108, 0, 28, 93, 223, 108, 0, 30, 93,
- 185, 108, 0, 30, 93, 223, 108, 0, 8, 0,
- 9, 0, 259, 0, 240, 0, 232, 59, 236, 0,
- 241, 0, 233, 59, 236, 0, 242, 0, 234, 59,
- 236, 0, 0, 119, 93, 217, 108, 0, 0, 221,
- 235, 244, 64, 237, 252, 0, 221, 235, 244, 0,
- 0, 244, 64, 239, 252, 0, 244, 0, 221, 235,
- 238, 0, 307, 235, 238, 0, 0, 307, 235, 243,
- 238, 0, 149, 235, 244, 0, 0, 245, 0, 246,
- 0, 245, 246, 0, 31, 93, 93, 247, 108, 108,
- 0, 248, 0, 247, 59, 248, 0, 0, 249, 0,
- 249, 93, 3, 108, 0, 249, 93, 3, 59, 195,
- 108, 0, 249, 93, 195, 108, 0, 163, 0, 7,
- 0, 8, 0, 9, 0, 163, 0, 250, 59, 163,
- 0, 0, 64, 252, 0, 203, 0, 58, 109, 0,
- 58, 253, 109, 0, 58, 253, 59, 109, 0, 1,
- 0, 252, 0, 253, 59, 252, 0, 94, 203, 111,
- 252, 0, 163, 62, 252, 0, 253, 59, 163, 62,
- 252, 0, 97, 0, 254, 146, 145, 334, 0, 254,
- 146, 358, 0, 254, 146, 1, 0, 0, 256, 255,
- 147, 0, 102, 203, 107, 0, 102, 1, 107, 0,
- 0, 258, 257, 0, 258, 1, 0, 0, 14, 163,
- 58, 260, 294, 265, 109, 0, 14, 163, 58, 109,
- 0, 0, 14, 58, 261, 294, 265, 109, 0, 14,
- 58, 109, 0, 14, 163, 0, 14, 322, 0, 45,
- 317, 0, 0, 0, 273, 279, 281, 109, 244, 262,
- 258, 263, 256, 0, 273, 0, 0, 59, 0, 0,
- 59, 0, 36, 0, 266, 7, 0, 266, 8, 0,
- 266, 9, 0, 266, 36, 0, 266, 245, 0, 266,
- 163, 0, 266, 165, 0, 267, 58, 0, 267, 62,
- 0, 266, 315, 163, 0, 266, 324, 315, 163, 0,
- 266, 324, 163, 0, 266, 177, 0, 266, 315, 177,
- 0, 267, 0, 0, 268, 271, 274, 0, 269, 274,
- 0, 266, 58, 0, 272, 0, 270, 0, 0, 62,
- 388, 0, 62, 388, 275, 0, 276, 0, 275, 59,
- 388, 276, 0, 277, 0, 278, 388, 277, 0, 317,
- 0, 303, 0, 30, 93, 185, 108, 0, 30, 93,
- 223, 108, 0, 37, 388, 0, 7, 388, 0, 278,
- 37, 388, 0, 278, 7, 388, 0, 58, 0, 0,
- 280, 0, 280, 283, 0, 281, 282, 283, 0, 281,
- 282, 0, 37, 62, 0, 284, 0, 283, 284, 0,
- 285, 60, 0, 285, 109, 0, 156, 62, 0, 156,
- 95, 0, 156, 25, 0, 156, 58, 0, 60, 0,
- 118, 284, 0, 134, 284, 0, 134, 224, 60, 0,
- 224, 286, 0, 227, 287, 0, 307, 235, 244, 251,
- 0, 149, 235, 244, 251, 0, 62, 203, 0, 1,
- 0, 227, 155, 235, 244, 251, 0, 155, 235, 244,
- 251, 0, 127, 0, 0, 288, 0, 286, 59, 289,
- 0, 0, 291, 0, 287, 59, 293, 0, 290, 0,
- 291, 0, 292, 0, 293, 0, 302, 235, 244, 251,
- 0, 4, 62, 203, 244, 0, 307, 235, 244, 251,
- 0, 149, 235, 244, 251, 0, 3, 62, 203, 244,
- 0, 62, 203, 244, 0, 302, 235, 244, 251, 0,
- 4, 62, 203, 244, 0, 307, 235, 244, 251, 0,
- 3, 62, 203, 244, 0, 62, 203, 244, 0, 295,
- 0, 294, 59, 295, 0, 163, 0, 163, 64, 203,
- 0, 368, 325, 0, 368, 0, 93, 198, 223, 197,
- 94, 185, 111, 0, 0, 297, 9, 0, 9, 0,
- 298, 9, 0, 0, 299, 185, 0, 299, 93, 195,
- 108, 0, 299, 93, 378, 108, 0, 299, 47, 0,
- 299, 93, 1, 108, 0, 80, 298, 302, 0, 70,
- 298, 302, 0, 80, 302, 0, 70, 302, 0, 323,
- 297, 302, 0, 306, 0, 314, 0, 324, 314, 0,
- 303, 0, 305, 0, 324, 305, 0, 315, 314, 0,
- 306, 301, 297, 390, 0, 306, 94, 300, 111, 0,
- 306, 94, 111, 0, 93, 302, 108, 0, 315, 314,
- 0, 314, 0, 80, 298, 307, 0, 70, 298, 307,
- 0, 80, 307, 0, 70, 307, 0, 323, 297, 307,
- 0, 211, 0, 80, 298, 307, 0, 70, 298, 307,
- 0, 80, 308, 0, 70, 308, 0, 323, 297, 307,
- 0, 309, 0, 211, 301, 297, 390, 0, 93, 308,
- 108, 0, 211, 94, 300, 111, 0, 211, 94, 111,
- 0, 311, 0, 315, 210, 0, 315, 208, 0, 315,
- 207, 0, 315, 204, 0, 315, 207, 0, 311, 0,
- 324, 311, 0, 230, 93, 195, 108, 0, 230, 93,
- 209, 108, 0, 230, 222, 0, 4, 0, 5, 0,
- 177, 0, 316, 0, 315, 316, 0, 315, 48, 321,
- 54, 0, 4, 54, 0, 5, 54, 0, 57, 54,
- 0, 177, 54, 0, 318, 0, 324, 318, 0, 319,
- 163, 0, 319, 177, 0, 319, 321, 0, 319, 48,
- 321, 0, 320, 0, 319, 320, 0, 319, 321, 54,
- 0, 319, 48, 321, 54, 0, 4, 54, 0, 5,
- 54, 0, 177, 54, 0, 56, 54, 0, 3, 54,
- 0, 57, 54, 0, 163, 74, 181, 180, 0, 324,
- 314, 0, 305, 0, 324, 305, 0, 315, 80, 0,
- 324, 315, 80, 0, 54, 0, 80, 297, 325, 0,
- 80, 297, 0, 70, 297, 325, 0, 70, 297, 0,
- 323, 297, 0, 323, 297, 325, 0, 326, 0, 94,
- 185, 111, 0, 326, 94, 300, 111, 0, 80, 298,
- 327, 0, 80, 327, 0, 80, 298, 0, 80, 0,
- 70, 298, 327, 0, 70, 327, 0, 70, 298, 0,
- 70, 0, 323, 297, 0, 323, 297, 327, 0, 328,
- 0, 93, 327, 108, 0, 90, 0, 328, 93, 378,
- 108, 297, 390, 0, 328, 47, 297, 390, 0, 328,
- 94, 300, 111, 0, 328, 94, 111, 0, 93, 379,
- 108, 297, 390, 0, 201, 297, 390, 0, 222, 297,
- 390, 0, 94, 300, 111, 0, 94, 111, 0, 342,
- 0, 330, 0, 329, 342, 0, 329, 330, 0, 1,
- 60, 0, 0, 332, 0, 333, 0, 332, 333, 0,
- 33, 250, 60, 0, 335, 0, 1, 335, 0, 0,
- 58, 336, 191, 0, 0, 0, 15, 338, 187, 339,
- 340, 0, 335, 0, 0, 341, 343, 0, 335, 0,
- 343, 0, 220, 0, 185, 60, 0, 0, 337, 16,
- 344, 340, 0, 337, 0, 0, 0, 17, 345, 187,
- 346, 192, 0, 0, 0, 18, 347, 340, 17, 348,
- 186, 60, 0, 0, 0, 0, 0, 19, 349, 93,
- 371, 350, 188, 60, 351, 373, 108, 352, 192, 0,
- 0, 0, 20, 353, 93, 189, 108, 354, 340, 0,
- 0, 21, 203, 62, 355, 342, 0, 0, 21, 203,
- 12, 203, 62, 356, 342, 0, 0, 22, 62, 357,
- 342, 0, 23, 60, 0, 24, 60, 0, 25, 60,
- 0, 25, 185, 60, 0, 119, 372, 93, 217, 108,
- 60, 0, 119, 372, 93, 217, 62, 374, 108, 60,
- 0, 119, 372, 93, 217, 62, 374, 62, 374, 108,
- 60, 0, 119, 372, 93, 217, 62, 374, 62, 374,
- 62, 377, 108, 60, 0, 26, 80, 185, 60, 0,
- 26, 163, 60, 0, 370, 342, 0, 370, 109, 0,
- 60, 0, 361, 0, 129, 0, 128, 0, 125, 0,
- 0, 0, 95, 359, 145, 335, 360, 364, 0, 0,
- 0, 95, 362, 335, 363, 364, 0, 365, 0, 364,
- 365, 0, 0, 0, 96, 366, 369, 367, 335, 0,
- 228, 0, 298, 0, 93, 12, 108, 0, 93, 387,
- 108, 0, 3, 62, 0, 56, 62, 0, 4, 62,
- 0, 5, 62, 0, 373, 60, 0, 220, 0, 58,
- 191, 0, 0, 9, 0, 0, 185, 0, 1, 0,
- 0, 375, 0, 376, 0, 375, 59, 376, 0, 11,
- 93, 185, 108, 0, 11, 0, 377, 59, 11, 0,
- 0, 379, 0, 223, 0, 383, 0, 384, 12, 0,
- 383, 12, 0, 223, 12, 0, 12, 0, 383, 62,
- 0, 223, 62, 0, 0, 64, 381, 382, 0, 101,
- 0, 252, 0, 385, 0, 387, 380, 0, 384, 386,
- 0, 384, 389, 0, 384, 389, 64, 252, 0, 383,
- 59, 0, 223, 59, 0, 225, 221, 0, 228, 221,
- 0, 230, 221, 0, 225, 327, 0, 225, 0, 227,
- 307, 0, 387, 0, 387, 380, 0, 385, 0, 223,
- 0, 0, 0, 307, 0, 0, 61, 93, 392, 108,
- 0, 61, 47, 0, 223, 0, 391, 0, 392, 59,
- 391, 0, 0, 80, 297, 393, 0, 70, 297, 393,
- 0, 323, 297, 393, 0, 41, 0, 394, 80, 0,
- 394, 81, 0, 394, 82, 0, 394, 78, 0, 394,
- 79, 0, 394, 70, 0, 394, 68, 0, 394, 69,
- 0, 394, 88, 0, 394, 59, 0, 394, 73, 0,
- 394, 74, 0, 394, 75, 0, 394, 72, 0, 394,
- 63, 0, 394, 64, 0, 394, 76, 0, 394, 77,
- 0, 394, 86, 0, 394, 87, 0, 394, 67, 0,
- 394, 66, 0, 394, 110, 0, 394, 65, 62, 0,
- 394, 71, 0, 394, 91, 0, 394, 83, 0, 394,
- 47, 0, 394, 94, 111, 0, 394, 39, 0, 394,
- 38, 0, 394, 39, 94, 111, 0, 394, 38, 94,
- 111, 0, 394, 368, 393, 0, 394, 1, 0
+ 56, 74, 182, 181, 180, 0, 4, 74, 182, 181,
+ 180, 0, 179, 0, 177, 0, 163, 74, 182, 75,
+ 180, 0, 5, 74, 182, 181, 180, 0, 0, 75,
+ 0, 77, 0, 0, 183, 0, 184, 0, 183, 59,
+ 184, 0, 225, 0, 56, 0, 204, 0, 79, 0,
+ 78, 0, 86, 0, 87, 0, 110, 0, 195, 0,
+ 204, 0, 47, 0, 93, 186, 108, 0, 47, 0,
+ 93, 190, 108, 0, 0, 190, 0, 1, 0, 0,
+ 371, 223, 237, 246, 64, 191, 254, 0, 186, 0,
+ 109, 0, 334, 332, 109, 0, 334, 332, 1, 109,
+ 0, 334, 1, 109, 0, 0, 58, 194, 192, 0,
+ 346, 0, 204, 59, 204, 0, 204, 59, 1, 0,
+ 195, 59, 204, 0, 195, 59, 1, 0, 204, 0,
+ 195, 0, 214, 0, 118, 203, 0, 80, 203, 0,
+ 70, 203, 0, 88, 203, 0, 185, 203, 0, 67,
+ 163, 0, 13, 197, 0, 13, 93, 225, 108, 0,
+ 29, 197, 0, 29, 93, 225, 108, 0, 216, 298,
+ 0, 216, 298, 201, 0, 216, 200, 298, 0, 216,
+ 200, 298, 201, 0, 216, 93, 199, 225, 198, 0,
+ 216, 93, 199, 225, 198, 201, 0, 216, 200, 93,
+ 199, 225, 198, 0, 216, 200, 93, 199, 225, 198,
+ 201, 0, 217, 203, 0, 217, 94, 111, 203, 0,
+ 217, 94, 186, 111, 203, 0, 34, 203, 0, 35,
+ 203, 0, 108, 0, 0, 93, 199, 196, 108, 0,
+ 58, 199, 196, 109, 0, 93, 196, 108, 0, 47,
+ 0, 93, 232, 108, 0, 64, 254, 0, 93, 225,
+ 108, 0, 202, 93, 225, 108, 0, 197, 0, 202,
+ 197, 0, 202, 58, 255, 266, 109, 0, 203, 0,
+ 204, 83, 204, 0, 204, 84, 204, 0, 204, 78,
+ 204, 0, 204, 79, 204, 0, 204, 80, 204, 0,
+ 204, 81, 204, 0, 204, 82, 204, 0, 204, 76,
+ 204, 0, 204, 77, 204, 0, 204, 73, 204, 0,
+ 204, 74, 204, 0, 204, 75, 204, 0, 204, 72,
+ 204, 0, 204, 71, 204, 0, 204, 70, 204, 0,
+ 204, 68, 204, 0, 204, 69, 204, 0, 204, 67,
+ 204, 0, 204, 66, 204, 0, 204, 65, 376, 62,
+ 204, 0, 204, 64, 204, 0, 204, 63, 204, 0,
+ 61, 0, 61, 204, 0, 88, 391, 163, 0, 88,
+ 391, 177, 0, 207, 0, 398, 0, 3, 0, 56,
+ 0, 57, 0, 0, 6, 74, 206, 182, 181, 0,
+ 398, 74, 206, 182, 181, 0, 48, 163, 74, 182,
+ 181, 0, 48, 6, 74, 182, 181, 0, 48, 398,
+ 74, 182, 181, 0, 205, 0, 4, 0, 5, 0,
+ 211, 0, 247, 211, 0, 205, 0, 80, 210, 0,
+ 70, 210, 0, 93, 210, 108, 0, 3, 74, 182,
+ 181, 0, 57, 74, 183, 181, 0, 312, 0, 205,
+ 0, 212, 0, 93, 210, 108, 0, 205, 0, 10,
+ 0, 218, 0, 219, 0, 93, 186, 108, 0, 93,
+ 210, 108, 0, 93, 1, 108, 0, 0, 93, 215,
+ 338, 108, 0, 205, 93, 196, 108, 0, 205, 47,
+ 0, 214, 93, 196, 108, 0, 214, 47, 0, 214,
+ 94, 186, 111, 0, 214, 86, 0, 214, 87, 0,
+ 40, 0, 9, 93, 196, 108, 0, 316, 0, 50,
+ 74, 225, 75, 93, 186, 108, 0, 51, 74, 225,
+ 75, 93, 186, 108, 0, 52, 74, 225, 75, 93,
+ 186, 108, 0, 53, 74, 225, 75, 93, 186, 108,
+ 0, 49, 93, 186, 108, 0, 49, 93, 225, 108,
+ 0, 327, 3, 0, 327, 207, 0, 327, 398, 0,
+ 315, 0, 315, 93, 196, 108, 0, 315, 47, 0,
+ 221, 208, 0, 221, 208, 93, 196, 108, 0, 221,
+ 208, 47, 0, 221, 209, 0, 221, 315, 0, 221,
+ 209, 93, 196, 108, 0, 221, 209, 47, 0, 221,
+ 315, 93, 196, 108, 0, 221, 315, 47, 0, 221,
+ 88, 8, 47, 0, 221, 8, 54, 88, 8, 47,
+ 0, 221, 1, 0, 39, 0, 327, 39, 0, 38,
+ 0, 327, 217, 0, 42, 0, 43, 0, 11, 0,
+ 219, 11, 0, 0, 214, 92, 0, 214, 91, 0,
+ 232, 234, 60, 0, 226, 234, 60, 0, 229, 235,
+ 60, 0, 226, 60, 0, 229, 60, 0, 118, 222,
+ 0, 304, 0, 310, 0, 47, 0, 224, 47, 0,
+ 230, 330, 0, 300, 330, 0, 232, 330, 0, 230,
+ 0, 300, 0, 230, 0, 227, 0, 229, 232, 0,
+ 232, 228, 0, 232, 231, 228, 0, 229, 232, 228,
+ 0, 229, 232, 231, 0, 229, 232, 231, 228, 0,
+ 7, 0, 228, 233, 0, 228, 7, 0, 228, 247,
+ 0, 247, 0, 300, 0, 7, 0, 229, 9, 0,
+ 229, 7, 0, 229, 247, 0, 247, 0, 232, 0,
+ 300, 232, 0, 232, 231, 0, 300, 232, 231, 0,
+ 233, 0, 231, 233, 0, 261, 0, 8, 0, 306,
+ 0, 28, 93, 186, 108, 0, 28, 93, 225, 108,
+ 0, 30, 93, 186, 108, 0, 30, 93, 225, 108,
+ 0, 8, 0, 9, 0, 261, 0, 242, 0, 234,
+ 59, 238, 0, 243, 0, 235, 59, 238, 0, 244,
+ 0, 236, 59, 238, 0, 0, 119, 93, 219, 108,
+ 0, 0, 223, 237, 246, 64, 239, 254, 0, 223,
+ 237, 246, 0, 0, 246, 64, 241, 254, 0, 246,
+ 0, 223, 237, 240, 0, 310, 237, 240, 0, 0,
+ 310, 237, 245, 240, 0, 149, 237, 246, 0, 0,
+ 247, 0, 248, 0, 247, 248, 0, 31, 93, 93,
+ 249, 108, 108, 0, 250, 0, 249, 59, 250, 0,
+ 0, 251, 0, 251, 93, 3, 108, 0, 251, 93,
+ 3, 59, 196, 108, 0, 251, 93, 196, 108, 0,
+ 163, 0, 7, 0, 8, 0, 9, 0, 163, 0,
+ 252, 59, 163, 0, 0, 64, 254, 0, 204, 0,
+ 58, 109, 0, 58, 255, 109, 0, 58, 255, 59,
+ 109, 0, 1, 0, 254, 0, 255, 59, 254, 0,
+ 94, 204, 111, 254, 0, 163, 62, 254, 0, 255,
+ 59, 163, 62, 254, 0, 97, 0, 256, 146, 145,
+ 337, 0, 256, 146, 361, 0, 256, 146, 1, 0,
+ 0, 258, 257, 147, 0, 102, 204, 107, 0, 102,
+ 1, 107, 0, 0, 260, 259, 0, 260, 1, 0,
+ 0, 14, 163, 58, 262, 296, 267, 109, 0, 14,
+ 163, 58, 109, 0, 0, 14, 58, 263, 296, 267,
+ 109, 0, 14, 58, 109, 0, 14, 163, 0, 14,
+ 325, 0, 45, 320, 0, 0, 0, 276, 282, 283,
+ 109, 246, 264, 260, 265, 258, 0, 276, 0, 0,
+ 59, 0, 0, 59, 0, 36, 0, 268, 7, 0,
+ 268, 8, 0, 268, 9, 0, 268, 36, 0, 268,
+ 247, 0, 268, 163, 0, 268, 165, 0, 269, 58,
+ 0, 269, 62, 0, 268, 318, 163, 0, 268, 327,
+ 318, 163, 0, 268, 327, 163, 0, 268, 178, 0,
+ 268, 318, 178, 0, 269, 0, 0, 270, 273, 277,
+ 0, 0, 271, 274, 277, 0, 268, 58, 0, 275,
+ 0, 272, 0, 0, 62, 391, 0, 62, 391, 278,
+ 0, 279, 0, 278, 59, 391, 279, 0, 280, 0,
+ 281, 391, 280, 0, 320, 0, 305, 0, 30, 93,
+ 186, 108, 0, 30, 93, 225, 108, 0, 37, 391,
+ 0, 7, 391, 0, 281, 37, 391, 0, 281, 7,
+ 391, 0, 58, 0, 0, 285, 0, 283, 284, 285,
+ 0, 283, 284, 0, 37, 62, 0, 286, 0, 285,
+ 286, 0, 287, 60, 0, 287, 109, 0, 156, 62,
+ 0, 156, 95, 0, 156, 25, 0, 156, 58, 0,
+ 60, 0, 118, 286, 0, 134, 286, 0, 134, 226,
+ 60, 0, 226, 288, 0, 229, 289, 0, 310, 237,
+ 246, 253, 0, 149, 237, 246, 253, 0, 62, 204,
+ 0, 1, 0, 229, 155, 237, 246, 253, 0, 155,
+ 237, 246, 253, 0, 127, 0, 0, 290, 0, 288,
+ 59, 291, 0, 0, 293, 0, 289, 59, 295, 0,
+ 292, 0, 293, 0, 294, 0, 295, 0, 304, 237,
+ 246, 253, 0, 4, 62, 204, 246, 0, 310, 237,
+ 246, 253, 0, 149, 237, 246, 253, 0, 3, 62,
+ 204, 246, 0, 62, 204, 246, 0, 304, 237, 246,
+ 253, 0, 4, 62, 204, 246, 0, 310, 237, 246,
+ 253, 0, 3, 62, 204, 246, 0, 62, 204, 246,
+ 0, 297, 0, 296, 59, 297, 0, 163, 0, 163,
+ 64, 204, 0, 371, 328, 0, 371, 0, 93, 199,
+ 225, 198, 94, 186, 111, 0, 0, 299, 9, 0,
+ 9, 0, 300, 9, 0, 0, 301, 186, 0, 301,
+ 93, 196, 108, 0, 301, 93, 381, 108, 0, 301,
+ 47, 0, 301, 93, 1, 108, 0, 80, 300, 304,
+ 0, 70, 300, 304, 0, 80, 304, 0, 70, 304,
+ 0, 326, 299, 304, 0, 308, 0, 317, 0, 327,
+ 317, 0, 305, 0, 307, 0, 327, 307, 0, 318,
+ 317, 0, 308, 303, 299, 393, 0, 308, 94, 302,
+ 111, 0, 308, 94, 111, 0, 93, 304, 108, 0,
+ 318, 317, 0, 317, 0, 310, 0, 247, 310, 0,
+ 80, 300, 309, 0, 70, 300, 309, 0, 80, 309,
+ 0, 70, 309, 0, 326, 299, 309, 0, 213, 0,
+ 80, 300, 309, 0, 70, 300, 309, 0, 80, 311,
+ 0, 70, 311, 0, 326, 299, 309, 0, 312, 0,
+ 213, 303, 299, 393, 0, 93, 311, 108, 0, 213,
+ 94, 302, 111, 0, 213, 94, 111, 0, 314, 0,
+ 318, 212, 0, 318, 209, 0, 318, 208, 0, 318,
+ 205, 0, 318, 208, 0, 314, 0, 327, 314, 0,
+ 232, 93, 196, 108, 0, 232, 93, 210, 108, 0,
+ 232, 224, 0, 4, 0, 5, 0, 177, 0, 319,
+ 0, 318, 319, 0, 318, 48, 324, 54, 0, 4,
+ 54, 0, 5, 54, 0, 57, 54, 0, 177, 54,
+ 0, 321, 0, 327, 321, 0, 322, 163, 0, 322,
+ 177, 0, 322, 324, 0, 322, 48, 324, 0, 323,
+ 0, 322, 323, 0, 322, 324, 54, 0, 322, 48,
+ 324, 54, 0, 4, 54, 0, 5, 54, 0, 177,
+ 54, 0, 56, 54, 0, 3, 54, 0, 57, 54,
+ 0, 163, 74, 182, 181, 0, 327, 317, 0, 307,
+ 0, 327, 307, 0, 318, 80, 0, 327, 318, 80,
+ 0, 54, 0, 80, 299, 328, 0, 80, 299, 0,
+ 70, 299, 328, 0, 70, 299, 0, 326, 299, 0,
+ 326, 299, 328, 0, 329, 0, 94, 186, 111, 0,
+ 329, 94, 302, 111, 0, 80, 300, 330, 0, 80,
+ 330, 0, 80, 300, 0, 80, 0, 70, 300, 330,
+ 0, 70, 330, 0, 70, 300, 0, 70, 0, 326,
+ 299, 0, 326, 299, 330, 0, 331, 0, 93, 330,
+ 108, 0, 90, 0, 331, 93, 381, 108, 299, 393,
+ 0, 331, 47, 299, 393, 0, 331, 94, 302, 111,
+ 0, 331, 94, 111, 0, 93, 382, 108, 299, 393,
+ 0, 202, 299, 393, 0, 224, 299, 393, 0, 94,
+ 302, 111, 0, 94, 111, 0, 345, 0, 333, 0,
+ 332, 345, 0, 332, 333, 0, 1, 60, 0, 0,
+ 335, 0, 336, 0, 335, 336, 0, 33, 252, 60,
+ 0, 338, 0, 1, 338, 0, 0, 58, 339, 192,
+ 0, 0, 0, 15, 341, 188, 342, 343, 0, 338,
+ 0, 0, 344, 346, 0, 338, 0, 346, 0, 222,
+ 0, 186, 60, 0, 0, 340, 16, 347, 343, 0,
+ 340, 0, 0, 0, 17, 348, 188, 349, 193, 0,
+ 0, 0, 18, 350, 343, 17, 351, 187, 60, 0,
+ 0, 0, 0, 0, 19, 352, 93, 374, 353, 189,
+ 60, 354, 376, 108, 355, 193, 0, 0, 0, 20,
+ 356, 93, 190, 108, 357, 343, 0, 0, 21, 204,
+ 62, 358, 345, 0, 0, 21, 204, 12, 204, 62,
+ 359, 345, 0, 0, 22, 62, 360, 345, 0, 23,
+ 60, 0, 24, 60, 0, 25, 60, 0, 25, 186,
+ 60, 0, 119, 375, 93, 219, 108, 60, 0, 119,
+ 375, 93, 219, 62, 377, 108, 60, 0, 119, 375,
+ 93, 219, 62, 377, 62, 377, 108, 60, 0, 119,
+ 375, 93, 219, 62, 377, 62, 377, 62, 380, 108,
+ 60, 0, 26, 80, 186, 60, 0, 26, 163, 60,
+ 0, 373, 345, 0, 373, 109, 0, 60, 0, 364,
+ 0, 129, 0, 128, 0, 125, 0, 0, 0, 95,
+ 362, 145, 338, 363, 367, 0, 0, 0, 95, 365,
+ 338, 366, 367, 0, 368, 0, 367, 368, 0, 0,
+ 0, 96, 369, 372, 370, 338, 0, 230, 0, 300,
+ 0, 93, 12, 108, 0, 93, 390, 108, 0, 3,
+ 62, 0, 56, 62, 0, 4, 62, 0, 5, 62,
+ 0, 376, 60, 0, 222, 0, 58, 192, 0, 0,
+ 9, 0, 0, 186, 0, 1, 0, 0, 378, 0,
+ 379, 0, 378, 59, 379, 0, 11, 93, 186, 108,
+ 0, 11, 0, 380, 59, 11, 0, 0, 382, 0,
+ 225, 0, 386, 0, 387, 12, 0, 386, 12, 0,
+ 225, 12, 0, 12, 0, 386, 62, 0, 225, 62,
+ 0, 0, 64, 384, 385, 0, 101, 0, 254, 0,
+ 388, 0, 390, 383, 0, 387, 389, 0, 387, 392,
+ 0, 387, 392, 64, 254, 0, 386, 59, 0, 225,
+ 59, 0, 227, 223, 0, 230, 223, 0, 232, 223,
+ 0, 227, 330, 0, 227, 0, 229, 310, 0, 390,
+ 0, 390, 383, 0, 388, 0, 225, 0, 0, 0,
+ 310, 0, 0, 61, 93, 395, 108, 0, 61, 47,
+ 0, 225, 0, 394, 0, 395, 59, 394, 0, 0,
+ 80, 299, 396, 0, 70, 299, 396, 0, 326, 299,
+ 396, 0, 41, 0, 397, 80, 0, 397, 81, 0,
+ 397, 82, 0, 397, 78, 0, 397, 79, 0, 397,
+ 70, 0, 397, 68, 0, 397, 69, 0, 397, 88,
+ 0, 397, 59, 0, 397, 73, 0, 397, 74, 0,
+ 397, 75, 0, 397, 72, 0, 397, 63, 0, 397,
+ 64, 0, 397, 76, 0, 397, 77, 0, 397, 86,
+ 0, 397, 87, 0, 397, 67, 0, 397, 66, 0,
+ 397, 110, 0, 397, 65, 62, 0, 397, 71, 0,
+ 397, 91, 0, 397, 83, 0, 397, 47, 0, 397,
+ 94, 111, 0, 397, 39, 0, 397, 38, 0, 397,
+ 39, 94, 111, 0, 397, 38, 94, 111, 0, 397,
+ 371, 396, 0, 397, 1, 0
};
#endif
#if YYDEBUG != 0
static const short yyrline[] = { 0,
- 334, 336, 344, 347, 348, 352, 354, 357, 362, 366,
- 372, 376, 379, 383, 386, 388, 390, 393, 395, 398,
- 401, 403, 405, 407, 409, 410, 412, 413, 417, 420,
- 429, 432, 434, 438, 441, 443, 447, 450, 462, 469,
- 477, 479, 480, 482, 486, 489, 495, 498, 500, 505,
- 508, 512, 515, 518, 521, 525, 530, 540, 542, 544,
- 546, 548, 561, 564, 568, 571, 573, 575, 578, 581,
- 585, 587, 589, 591, 596, 598, 600, 602, 604, 605,
- 612, 613, 614, 617, 620, 624, 626, 627, 630, 632,
- 635, 638, 640, 644, 647, 649, 653, 655, 657, 661,
- 663, 665, 669, 671, 673, 679, 683, 686, 689, 692,
- 697, 700, 702, 704, 710, 720, 722, 725, 728, 730,
- 733, 737, 746, 749, 751, 755, 768, 788, 791, 793,
- 794, 797, 804, 810, 812, 814, 816, 818, 821, 826,
- 828, 829, 830, 831, 834, 836, 837, 840, 842, 843,
- 846, 851, 851, 855, 855, 858, 858, 861, 861, 865,
- 865, 870, 870, 873, 873, 876, 878, 881, 888, 892,
- 895, 898, 904, 913, 915, 923, 926, 929, 932, 936,
- 939, 941, 944, 947, 949, 951, 953, 957, 960, 963,
- 968, 972, 977, 981, 984, 985, 989, 1008, 1015, 1018,
- 1020, 1021, 1022, 1025, 1029, 1030, 1034, 1038, 1041, 1043,
- 1047, 1050, 1053, 1057, 1060, 1062, 1064, 1066, 1069, 1073,
- 1075, 1077, 1079, 1085, 1088, 1091, 1094, 1106, 1111, 1115,
- 1119, 1124, 1126, 1130, 1134, 1136, 1145, 1149, 1152, 1155,
- 1160, 1163, 1165, 1173, 1186, 1191, 1197, 1199, 1201, 1214,
- 1217, 1219, 1221, 1223, 1225, 1227, 1229, 1231, 1233, 1235,
- 1237, 1239, 1241, 1243, 1245, 1247, 1249, 1251, 1253, 1255,
- 1257, 1261, 1263, 1265, 1282, 1285, 1287, 1288, 1289, 1290,
- 1291, 1294, 1297, 1300, 1304, 1307, 1309, 1314, 1316, 1317,
- 1320, 1322, 1324, 1326, 1330, 1333, 1337, 1341, 1342, 1343,
- 1347, 1355, 1356, 1357, 1371, 1373, 1376, 1378, 1389, 1394,
- 1396, 1398, 1400, 1402, 1404, 1406, 1409, 1411, 1455, 1456,
- 1460, 1464, 1468, 1472, 1474, 1478, 1480, 1482, 1490, 1492,
- 1494, 1496, 1500, 1502, 1504, 1506, 1511, 1513, 1515, 1517,
- 1520, 1522, 1524, 1568, 1571, 1575, 1578, 1582, 1585, 1590,
- 1592, 1596, 1609, 1612, 1619, 1626, 1631, 1633, 1638, 1640,
- 1647, 1649, 1653, 1657, 1663, 1667, 1670, 1673, 1676, 1686,
- 1688, 1691, 1695, 1698, 1701, 1704, 1707, 1713, 1719, 1721,
- 1726, 1728, 1737, 1740, 1742, 1745, 1751, 1753, 1763, 1767,
- 1770, 1773, 1778, 1781, 1789, 1791, 1793, 1795, 1798, 1801,
- 1816, 1835, 1838, 1840, 1843, 1845, 1849, 1851, 1855, 1857,
- 1861, 1864, 1868, 1874, 1875, 1887, 1894, 1897, 1903, 1907,
- 1912, 1918, 1919, 1927, 1930, 1934, 1937, 1941, 1946, 1949,
- 1953, 1956, 1958, 1960, 1962, 1969, 1971, 1972, 1973, 1977,
- 1980, 1984, 1987, 1993, 1995, 1998, 2001, 2004, 2010, 2013,
- 2016, 2018, 2020, 2024, 2030, 2038, 2040, 2044, 2046, 2051,
- 2054, 2057, 2059, 2061, 2065, 2070, 2077, 2081, 2085, 2092,
- 2096, 2099, 2102, 2108, 2120, 2122, 2125, 2145, 2147, 2150,
- 2152, 2157, 2159, 2161, 2163, 2165, 2167, 2171, 2179, 2182,
- 2184, 2188, 2194, 2199, 2204, 2206, 2210, 2213, 2215, 2221,
- 2238, 2244, 2246, 2249, 2252, 2254, 2258, 2260, 2264, 2269,
- 2275, 2278, 2279, 2300, 2323, 2325, 2329, 2340, 2354, 2359,
- 2366, 2368, 2369, 2370, 2373, 2388, 2393, 2399, 2401, 2406,
- 2408, 2410, 2412, 2414, 2416, 2419, 2429, 2436, 2461, 2467,
- 2470, 2473, 2475, 2486, 2491, 2494, 2499, 2502, 2509, 2519,
- 2522, 2529, 2539, 2541, 2544, 2546, 2549, 2556, 2564, 2571,
- 2577, 2583, 2591, 2595, 2600, 2604, 2607, 2616, 2618, 2622,
- 2625, 2630, 2634, 2640, 2651, 2654, 2658, 2662, 2670, 2675,
- 2681, 2684, 2686, 2688, 2694, 2697, 2699, 2701, 2703, 2707,
- 2710, 2728, 2738, 2740, 2741, 2745, 2750, 2753, 2755, 2757,
- 2759, 2763, 2769, 2772, 2774, 2776, 2778, 2782, 2785, 2788,
- 2790, 2792, 2794, 2798, 2801, 2804, 2806, 2808, 2810, 2812,
- 2819, 2823, 2828, 2832, 2837, 2839, 2843, 2846, 2848, 2851,
- 2853, 2854, 2857, 2859, 2861, 2867, 2882, 2888, 2894, 2908,
- 2910, 2914, 2928, 2930, 2932, 2936, 2942, 2955, 2957, 2961,
- 2974, 2980, 2982, 2983, 2984, 2992, 2997, 3006, 3007, 3011,
- 3014, 3020, 3026, 3029, 3031, 3033, 3035, 3039, 3043, 3047,
- 3050, 3055, 3058, 3060, 3062, 3064, 3066, 3068, 3070, 3072,
- 3076, 3080, 3084, 3088, 3089, 3091, 3093, 3095, 3097, 3099,
- 3101, 3103, 3105, 3113, 3115, 3116, 3117, 3120, 3126, 3128,
- 3133, 3135, 3138, 3152, 3155, 3158, 3162, 3165, 3172, 3174,
- 3177, 3179, 3181, 3184, 3187, 3190, 3193, 3195, 3198, 3202,
- 3204, 3210, 3212, 3213, 3215, 3220, 3222, 3224, 3226, 3228,
- 3231, 3232, 3234, 3237, 3238, 3241, 3241, 3244, 3244, 3247,
- 3247, 3249, 3251, 3253, 3255, 3261, 3267, 3270, 3273, 3279,
- 3281, 3283, 3287, 3289, 3290, 3291, 3293, 3296, 3303, 3308,
- 3316, 3320, 3322, 3325, 3327, 3330, 3334, 3336, 3339, 3341,
- 3344, 3361, 3367, 3375, 3377, 3379, 3383, 3386, 3387, 3395,
- 3399, 3403, 3406, 3407, 3413, 3416, 3419, 3421, 3425, 3430,
- 3433, 3443, 3448, 3449, 3456, 3459, 3462, 3464, 3467, 3469,
- 3479, 3493, 3497, 3500, 3502, 3506, 3510, 3513, 3516, 3518,
- 3522, 3524, 3531, 3538, 3541, 3544, 3548, 3552, 3558, 3562,
- 3567, 3569, 3572, 3577, 3583, 3594, 3597, 3599, 3603, 3608,
- 3610, 3617, 3620, 3622, 3624, 3630, 3635, 3638, 3640, 3642,
- 3644, 3646, 3648, 3650, 3652, 3654, 3656, 3658, 3660, 3662,
- 3664, 3666, 3668, 3670, 3672, 3674, 3676, 3678, 3680, 3682,
- 3684, 3686, 3688, 3690, 3692, 3694, 3696, 3698, 3700, 3703,
- 3705
+ 338, 340, 348, 351, 352, 356, 358, 361, 366, 370,
+ 376, 380, 383, 387, 390, 392, 394, 397, 399, 402,
+ 405, 407, 409, 411, 413, 414, 416, 417, 421, 424,
+ 433, 436, 438, 442, 445, 447, 451, 454, 466, 473,
+ 481, 483, 484, 486, 490, 493, 499, 502, 504, 509,
+ 512, 516, 519, 522, 525, 529, 534, 544, 546, 548,
+ 550, 552, 565, 568, 572, 575, 577, 579, 582, 585,
+ 589, 591, 593, 595, 600, 602, 604, 606, 608, 609,
+ 616, 617, 618, 621, 624, 628, 630, 631, 634, 636,
+ 639, 642, 648, 652, 655, 657, 661, 663, 665, 669,
+ 671, 673, 677, 679, 681, 687, 691, 694, 697, 700,
+ 705, 708, 710, 712, 718, 730, 733, 738, 743, 746,
+ 751, 756, 765, 768, 770, 774, 787, 807, 810, 812,
+ 813, 816, 823, 829, 831, 833, 835, 837, 840, 845,
+ 847, 848, 849, 850, 853, 855, 856, 859, 861, 862,
+ 865, 870, 870, 874, 874, 877, 877, 880, 880, 884,
+ 884, 889, 889, 892, 892, 895, 897, 900, 907, 911,
+ 914, 917, 919, 923, 929, 938, 940, 948, 951, 954,
+ 957, 961, 964, 966, 969, 972, 974, 976, 978, 982,
+ 985, 988, 993, 997, 1002, 1006, 1009, 1010, 1014, 1033,
+ 1040, 1043, 1045, 1046, 1047, 1050, 1054, 1055, 1059, 1063,
+ 1066, 1068, 1072, 1075, 1078, 1082, 1085, 1087, 1089, 1091,
+ 1094, 1098, 1100, 1103, 1105, 1111, 1114, 1117, 1120, 1132,
+ 1137, 1141, 1145, 1150, 1152, 1156, 1160, 1162, 1171, 1175,
+ 1178, 1181, 1186, 1189, 1191, 1199, 1212, 1217, 1223, 1225,
+ 1227, 1240, 1243, 1245, 1247, 1249, 1251, 1253, 1255, 1257,
+ 1259, 1261, 1263, 1265, 1267, 1269, 1271, 1273, 1275, 1277,
+ 1279, 1281, 1283, 1287, 1289, 1291, 1308, 1311, 1313, 1314,
+ 1315, 1316, 1317, 1320, 1332, 1335, 1339, 1342, 1344, 1349,
+ 1351, 1352, 1355, 1357, 1365, 1367, 1369, 1371, 1375, 1378,
+ 1382, 1386, 1387, 1388, 1392, 1400, 1401, 1402, 1416, 1418,
+ 1421, 1423, 1434, 1439, 1441, 1443, 1445, 1447, 1449, 1451,
+ 1454, 1456, 1473, 1474, 1478, 1482, 1486, 1490, 1492, 1496,
+ 1498, 1500, 1508, 1510, 1512, 1514, 1518, 1520, 1522, 1524,
+ 1529, 1531, 1533, 1535, 1538, 1540, 1542, 1586, 1589, 1593,
+ 1596, 1600, 1603, 1608, 1610, 1614, 1627, 1630, 1637, 1644,
+ 1649, 1651, 1656, 1658, 1665, 1667, 1671, 1675, 1681, 1685,
+ 1688, 1691, 1694, 1704, 1706, 1709, 1713, 1716, 1719, 1722,
+ 1725, 1731, 1737, 1739, 1744, 1746, 1755, 1758, 1760, 1763,
+ 1769, 1771, 1781, 1785, 1788, 1791, 1796, 1799, 1807, 1809,
+ 1811, 1813, 1816, 1819, 1834, 1853, 1856, 1858, 1861, 1863,
+ 1867, 1869, 1873, 1875, 1879, 1882, 1886, 1892, 1893, 1905,
+ 1912, 1915, 1921, 1925, 1930, 1936, 1937, 1945, 1948, 1952,
+ 1955, 1959, 1964, 1967, 1971, 1974, 1976, 1978, 1980, 1987,
+ 1989, 1990, 1991, 1995, 1998, 2002, 2005, 2011, 2013, 2016,
+ 2019, 2022, 2028, 2031, 2034, 2036, 2038, 2042, 2048, 2056,
+ 2063, 2067, 2069, 2074, 2077, 2080, 2082, 2084, 2088, 2093,
+ 2100, 2104, 2108, 2115, 2119, 2122, 2125, 2131, 2143, 2145,
+ 2148, 2168, 2170, 2173, 2175, 2180, 2182, 2184, 2186, 2188,
+ 2190, 2194, 2202, 2205, 2207, 2211, 2217, 2222, 2227, 2229,
+ 2233, 2236, 2240, 2246, 2252, 2277, 2283, 2285, 2288, 2291,
+ 2293, 2297, 2299, 2303, 2308, 2314, 2317, 2318, 2339, 2362,
+ 2364, 2368, 2379, 2393, 2398, 2399, 2400, 2401, 2404, 2419,
+ 2424, 2430, 2432, 2437, 2439, 2441, 2443, 2445, 2447, 2450,
+ 2460, 2467, 2492, 2498, 2501, 2504, 2506, 2517, 2522, 2525,
+ 2530, 2533, 2540, 2550, 2553, 2560, 2570, 2572, 2575, 2577,
+ 2580, 2587, 2595, 2602, 2608, 2614, 2622, 2626, 2631, 2635,
+ 2638, 2647, 2649, 2653, 2656, 2661, 2665, 2671, 2682, 2685,
+ 2689, 2693, 2701, 2706, 2712, 2715, 2717, 2719, 2725, 2728,
+ 2730, 2732, 2734, 2738, 2741, 2759, 2769, 2771, 2772, 2776,
+ 2781, 2784, 2786, 2788, 2790, 2794, 2800, 2802, 2810, 2813,
+ 2815, 2817, 2819, 2823, 2826, 2829, 2831, 2833, 2835, 2839,
+ 2842, 2845, 2847, 2849, 2851, 2853, 2860, 2864, 2869, 2873,
+ 2878, 2880, 2884, 2887, 2889, 2892, 2894, 2895, 2898, 2900,
+ 2902, 2908, 2923, 2929, 2935, 2949, 2951, 2955, 2969, 2971,
+ 2973, 2977, 2983, 2996, 2998, 3002, 3015, 3021, 3023, 3024,
+ 3025, 3033, 3038, 3047, 3048, 3052, 3055, 3061, 3067, 3070,
+ 3072, 3074, 3076, 3080, 3084, 3088, 3091, 3096, 3099, 3101,
+ 3103, 3105, 3107, 3109, 3111, 3113, 3117, 3121, 3125, 3129,
+ 3130, 3132, 3134, 3136, 3138, 3140, 3142, 3144, 3146, 3154,
+ 3156, 3157, 3158, 3161, 3167, 3169, 3174, 3176, 3179, 3193,
+ 3196, 3199, 3203, 3206, 3213, 3215, 3218, 3220, 3222, 3225,
+ 3228, 3231, 3234, 3236, 3239, 3243, 3245, 3251, 3253, 3254,
+ 3256, 3261, 3263, 3265, 3267, 3269, 3272, 3273, 3275, 3278,
+ 3279, 3282, 3282, 3285, 3285, 3288, 3288, 3290, 3292, 3294,
+ 3296, 3302, 3308, 3311, 3314, 3320, 3322, 3324, 3328, 3330,
+ 3331, 3332, 3334, 3337, 3344, 3349, 3355, 3359, 3361, 3364,
+ 3366, 3369, 3373, 3375, 3378, 3380, 3383, 3400, 3406, 3414,
+ 3416, 3418, 3422, 3425, 3426, 3434, 3438, 3442, 3445, 3446,
+ 3452, 3455, 3458, 3460, 3464, 3469, 3472, 3482, 3487, 3488,
+ 3495, 3498, 3501, 3503, 3506, 3508, 3518, 3532, 3536, 3539,
+ 3541, 3545, 3549, 3552, 3555, 3557, 3561, 3563, 3570, 3577,
+ 3580, 3583, 3587, 3591, 3597, 3601, 3606, 3608, 3611, 3616,
+ 3622, 3633, 3636, 3638, 3642, 3647, 3649, 3656, 3659, 3661,
+ 3663, 3669, 3674, 3677, 3679, 3681, 3683, 3685, 3687, 3689,
+ 3691, 3693, 3695, 3697, 3699, 3701, 3703, 3705, 3707, 3709,
+ 3711, 3713, 3715, 3717, 3719, 3721, 3723, 3725, 3727, 3729,
+ 3731, 3733, 3735, 3737, 3739, 3742, 3744
};
#endif
@@ -760,45 +763,46 @@ static const char * const yytname[] = { "$","error","$undefined.","IDENTIFIER"
".set_base_init","member_init_list","member_init","identifier","notype_identifier",
"identifier_defn","explicit_instantiation","@12","@13","@14","@15","@16","@17",
"@18","@19","begin_explicit_instantiation","end_explicit_instantiation","template_type",
-"self_template_type",".finish_template_type","template_close_bracket","template_arg_list_opt",
-"template_arg_list","template_arg","unop","expr","paren_expr_or_null","paren_cond_or_null",
-"xcond","condition","@20","compstmtend","already_scoped_stmt","@21","nontrivial_exprlist",
-"nonnull_exprlist","unary_expr",".finish_new_placement",".begin_new_placement",
-"new_placement","new_initializer","regcast_or_absdcl","cast_expr","expr_no_commas",
-"notype_unqualified_id","do_id","template_id","object_template_id","unqualified_id",
-"expr_or_declarator","notype_template_declarator","direct_notype_declarator",
-"primary","@22","new","delete","boolean.literal","string","nodecls","object",
-"decl","declarator","fcast_or_absdcl","type_id","typed_declspecs","typed_declspecs1",
-"reserved_declspecs","declmods","typed_typespecs","reserved_typespecquals","typespec",
-"typespecqual_reserved","initdecls","notype_initdecls","nomods_initdecls","maybeasm",
-"initdcl","@23","initdcl0_innards","@24","initdcl0","notype_initdcl0","nomods_initdcl0",
-"@25","maybe_attribute","attributes","attribute","attribute_list","attrib","any_word",
-"identifiers_or_typenames","maybe_init","init","initlist","fn.defpen","pending_inline",
-"pending_inlines","defarg_again","pending_defargs","structsp","@26","@27","@28",
-"@29","maybecomma","maybecomma_warn","aggr","named_class_head_sans_basetype",
-"named_class_head_sans_basetype_defn","named_complex_class_head_sans_basetype",
-"named_class_head","@30","unnamed_class_head","class_head","maybe_base_class_list",
-"base_class_list","base_class","base_class.1","base_class_access_list","left_curly",
-"self_reference","opt.component_decl_list","access_specifier","component_decl_list",
-"component_decl","component_decl_1","components","notype_components","component_declarator0",
-"component_declarator","after_type_component_declarator0","notype_component_declarator0",
-"after_type_component_declarator","notype_component_declarator","enumlist","enumerator",
-"new_type_id","cv_qualifiers","nonempty_cv_qualifiers","suspend_mom","nonmomentary_expr",
-"maybe_parmlist","after_type_declarator","nonnested_type","complete_type_name",
-"nested_type","direct_after_type_declarator","notype_declarator","complex_notype_declarator",
-"complex_direct_notype_declarator","qualified_id","notype_qualified_id","overqualified_id",
-"functional_cast","type_name","nested_name_specifier","nested_name_specifier_1",
-"typename_sub","typename_sub0","typename_sub1","typename_sub2","explicit_template_type",
-"complex_type_name","ptr_to_mem","global_scope","new_declarator","direct_new_declarator",
-"absdcl","direct_abstract_declarator","stmts","errstmt","maybe_label_decls",
-"label_decls","label_decl","compstmt_or_error","compstmt","@31","simple_if",
-"@32","@33","implicitly_scoped_stmt","@34","stmt","simple_stmt","@35","@36",
-"@37","@38","@39","@40","@41","@42","@43","@44","@45","@46","@47","@48","function_try_block",
-"@49","@50","try_block","@51","@52","handler_seq","handler","@53","@54","type_specifier_seq",
-"handler_args","label_colon","for.init.statement","maybe_cv_qualifier","xexpr",
-"asm_operands","nonnull_asm_operands","asm_operand","asm_clobbers","parmlist",
-"complex_parmlist","defarg","@55","defarg1","parms","parms_comma","named_parm",
-"full_parm","parm","see_typename","bad_parm","exception_specification_opt","ansi_raise_identifier",
+"apparent_template_type","self_template_type",".finish_template_type","template_close_bracket",
+"template_arg_list_opt","template_arg_list","template_arg","unop","expr","paren_expr_or_null",
+"paren_cond_or_null","xcond","condition","@20","compstmtend","already_scoped_stmt",
+"@21","nontrivial_exprlist","nonnull_exprlist","unary_expr",".finish_new_placement",
+".begin_new_placement","new_placement","new_initializer","regcast_or_absdcl",
+"cast_expr","expr_no_commas","notype_unqualified_id","do_id","template_id","object_template_id",
+"unqualified_id","expr_or_declarator_intern","expr_or_declarator","notype_template_declarator",
+"direct_notype_declarator","primary","@22","new","delete","boolean.literal",
+"string","nodecls","object","decl","declarator","fcast_or_absdcl","type_id",
+"typed_declspecs","typed_declspecs1","reserved_declspecs","declmods","typed_typespecs",
+"reserved_typespecquals","typespec","typespecqual_reserved","initdecls","notype_initdecls",
+"nomods_initdecls","maybeasm","initdcl","@23","initdcl0_innards","@24","initdcl0",
+"notype_initdcl0","nomods_initdcl0","@25","maybe_attribute","attributes","attribute",
+"attribute_list","attrib","any_word","identifiers_or_typenames","maybe_init",
+"init","initlist","fn.defpen","pending_inline","pending_inlines","defarg_again",
+"pending_defargs","structsp","@26","@27","@28","@29","maybecomma","maybecomma_warn",
+"aggr","named_class_head_sans_basetype","named_class_head_sans_basetype_defn",
+"named_complex_class_head_sans_basetype","named_class_head","@30","@31","unnamed_class_head",
+"class_head","maybe_base_class_list","base_class_list","base_class","base_class.1",
+"base_class_access_list","left_curly","opt.component_decl_list","access_specifier",
+"component_decl_list","component_decl","component_decl_1","components","notype_components",
+"component_declarator0","component_declarator","after_type_component_declarator0",
+"notype_component_declarator0","after_type_component_declarator","notype_component_declarator",
+"enumlist","enumerator","new_type_id","cv_qualifiers","nonempty_cv_qualifiers",
+"suspend_mom","nonmomentary_expr","maybe_parmlist","after_type_declarator","nonnested_type",
+"complete_type_name","nested_type","direct_after_type_declarator","notype_declarator_intern",
+"notype_declarator","complex_notype_declarator","complex_direct_notype_declarator",
+"qualified_id","notype_qualified_id","overqualified_id","functional_cast","type_name",
+"nested_name_specifier","nested_name_specifier_1","typename_sub","typename_sub0",
+"typename_sub1","typename_sub2","explicit_template_type","complex_type_name",
+"ptr_to_mem","global_scope","new_declarator","direct_new_declarator","absdcl",
+"direct_abstract_declarator","stmts","errstmt","maybe_label_decls","label_decls",
+"label_decl","compstmt_or_error","compstmt","@32","simple_if","@33","@34","implicitly_scoped_stmt",
+"@35","stmt","simple_stmt","@36","@37","@38","@39","@40","@41","@42","@43","@44",
+"@45","@46","@47","@48","@49","function_try_block","@50","@51","try_block","@52",
+"@53","handler_seq","handler","@54","@55","type_specifier_seq","handler_args",
+"label_colon","for.init.statement","maybe_cv_qualifier","xexpr","asm_operands",
+"nonnull_asm_operands","asm_operand","asm_clobbers","parmlist","complex_parmlist",
+"defarg","@56","defarg1","parms","parms_comma","named_parm","full_parm","parm",
+"see_typename","bad_parm","exception_specification_opt","ansi_raise_identifier",
"ansi_raise_identifiers","conversion_declarator","operator","operator_name", NULL
};
#endif
@@ -821,77 +825,77 @@ static const short yyr1[] = { 0,
163, 163, 163, 163, 164, 164, 164, 165, 165, 165,
167, 166, 168, 166, 169, 166, 170, 166, 171, 166,
172, 166, 173, 166, 174, 166, 175, 176, 177, 177,
- 177, 178, 179, 180, 180, 181, 181, 182, 182, 183,
- 183, 183, 184, 184, 184, 184, 184, 185, 185, 186,
- 186, 187, 187, 188, 188, 188, 190, 189, 189, 191,
- 191, 191, 191, 193, 192, 192, 194, 194, 194, 194,
- 195, 195, 196, 196, 196, 196, 196, 196, 196, 196,
- 196, 196, 196, 196, 196, 196, 196, 196, 196, 196,
- 196, 196, 196, 196, 196, 196, 197, 198, 199, 199,
- 200, 200, 200, 200, 201, 201, 202, 202, 202, 203,
- 203, 203, 203, 203, 203, 203, 203, 203, 203, 203,
- 203, 203, 203, 203, 203, 203, 203, 203, 203, 203,
- 203, 203, 203, 203, 204, 204, 204, 204, 204, 204,
- 204, 205, 206, 206, 207, 207, 207, 208, 208, 208,
- 209, 209, 209, 209, 210, 210, 211, 211, 211, 211,
- 212, 212, 212, 212, 212, 212, 212, 213, 212, 212,
- 212, 212, 212, 212, 212, 212, 212, 212, 212, 212,
- 212, 212, 212, 212, 212, 212, 212, 212, 212, 212,
- 212, 212, 212, 212, 212, 212, 212, 212, 212, 212,
- 212, 212, 212, 214, 214, 215, 215, 216, 216, 217,
- 217, 218, 219, 219, 220, 220, 220, 220, 220, 220,
- 221, 221, 222, 222, 223, 223, 223, 223, 223, 224,
- 224, 225, 225, 225, 225, 225, 225, 226, 226, 226,
- 226, 226, 227, 227, 227, 227, 227, 227, 228, 228,
- 228, 228, 229, 229, 230, 230, 230, 230, 230, 230,
- 230, 231, 231, 231, 232, 232, 233, 233, 234, 234,
- 235, 235, 237, 236, 236, 239, 238, 238, 240, 241,
- 243, 242, 242, 244, 244, 245, 245, 246, 247, 247,
- 248, 248, 248, 248, 248, 249, 249, 249, 249, 250,
- 250, 251, 251, 252, 252, 252, 252, 252, 253, 253,
- 253, 253, 253, 254, 255, 255, 255, 256, 256, 257,
- 257, 258, 258, 258, 260, 259, 259, 261, 259, 259,
- 259, 259, 259, 262, 263, 259, 259, 264, 264, 265,
- 265, 266, 266, 266, 266, 266, 266, 267, 268, 268,
- 268, 269, 269, 269, 269, 269, 270, 271, 270, 270,
- 272, 273, 273, 274, 274, 274, 275, 275, 276, 276,
- 277, 277, 277, 277, 278, 278, 278, 278, 279, 280,
- 281, 281, 281, 281, 282, 283, 283, 284, 284, 284,
- 284, 284, 284, 284, 284, 284, 284, 285, 285, 285,
- 285, 285, 285, 285, 285, 285, 286, 286, 286, 287,
- 287, 287, 288, 288, 289, 289, 290, 290, 291, 291,
- 291, 291, 292, 292, 293, 293, 293, 294, 294, 295,
- 295, 296, 296, 296, 297, 297, 298, 298, 299, 300,
- 301, 301, 301, 301, 302, 302, 302, 302, 302, 302,
- 303, 303, 304, 304, 304, 305, 306, 306, 306, 306,
- 306, 306, 307, 307, 307, 307, 307, 307, 308, 308,
- 308, 308, 308, 308, 309, 309, 309, 309, 309, 309,
- 310, 310, 311, 311, 312, 312, 313, 313, 313, 314,
- 314, 314, 315, 315, 315, 316, 316, 316, 316, 317,
- 317, 318, 318, 318, 318, 319, 319, 319, 319, 320,
- 320, 320, 320, 320, 320, 321, 322, 322, 322, 323,
- 323, 324, 325, 325, 325, 325, 325, 325, 325, 326,
- 326, 327, 327, 327, 327, 327, 327, 327, 327, 327,
- 327, 327, 328, 328, 328, 328, 328, 328, 328, 328,
- 328, 328, 328, 329, 329, 329, 329, 330, 331, 331,
- 332, 332, 333, 334, 334, 336, 335, 338, 339, 337,
- 340, 341, 340, 342, 342, 343, 343, 344, 343, 343,
- 345, 346, 343, 347, 348, 343, 349, 350, 351, 352,
- 343, 353, 354, 343, 355, 343, 356, 343, 357, 343,
- 343, 343, 343, 343, 343, 343, 343, 343, 343, 343,
- 343, 343, 343, 343, 343, 343, 343, 359, 360, 358,
- 362, 363, 361, 364, 364, 366, 367, 365, 368, 368,
- 369, 369, 370, 370, 370, 370, 371, 371, 371, 372,
- 372, 373, 373, 373, 374, 374, 375, 375, 376, 377,
- 377, 378, 378, 378, 379, 379, 379, 379, 379, 379,
- 379, 381, 380, 382, 382, 383, 383, 383, 383, 383,
- 384, 384, 385, 385, 385, 385, 385, 385, 386, 386,
- 387, 387, 388, 389, 389, 390, 390, 390, 391, 392,
- 392, 393, 393, 393, 393, 394, 395, 395, 395, 395,
- 395, 395, 395, 395, 395, 395, 395, 395, 395, 395,
- 395, 395, 395, 395, 395, 395, 395, 395, 395, 395,
- 395, 395, 395, 395, 395, 395, 395, 395, 395, 395,
- 395
+ 177, 178, 178, 179, 180, 181, 181, 182, 182, 183,
+ 183, 184, 184, 184, 185, 185, 185, 185, 185, 186,
+ 186, 187, 187, 188, 188, 189, 189, 189, 191, 190,
+ 190, 192, 192, 192, 192, 194, 193, 193, 195, 195,
+ 195, 195, 196, 196, 197, 197, 197, 197, 197, 197,
+ 197, 197, 197, 197, 197, 197, 197, 197, 197, 197,
+ 197, 197, 197, 197, 197, 197, 197, 197, 198, 199,
+ 200, 200, 201, 201, 201, 201, 202, 202, 203, 203,
+ 203, 204, 204, 204, 204, 204, 204, 204, 204, 204,
+ 204, 204, 204, 204, 204, 204, 204, 204, 204, 204,
+ 204, 204, 204, 204, 204, 204, 205, 205, 205, 205,
+ 205, 205, 205, 206, 207, 207, 208, 208, 208, 209,
+ 209, 209, 210, 210, 211, 211, 211, 211, 212, 212,
+ 213, 213, 213, 213, 214, 214, 214, 214, 214, 214,
+ 214, 215, 214, 214, 214, 214, 214, 214, 214, 214,
+ 214, 214, 214, 214, 214, 214, 214, 214, 214, 214,
+ 214, 214, 214, 214, 214, 214, 214, 214, 214, 214,
+ 214, 214, 214, 214, 214, 214, 214, 216, 216, 217,
+ 217, 218, 218, 219, 219, 220, 221, 221, 222, 222,
+ 222, 222, 222, 222, 223, 223, 224, 224, 225, 225,
+ 225, 225, 225, 226, 226, 227, 227, 227, 227, 227,
+ 227, 228, 228, 228, 228, 228, 229, 229, 229, 229,
+ 229, 229, 230, 230, 230, 230, 231, 231, 232, 232,
+ 232, 232, 232, 232, 232, 233, 233, 233, 234, 234,
+ 235, 235, 236, 236, 237, 237, 239, 238, 238, 241,
+ 240, 240, 242, 243, 245, 244, 244, 246, 246, 247,
+ 247, 248, 249, 249, 250, 250, 250, 250, 250, 251,
+ 251, 251, 251, 252, 252, 253, 253, 254, 254, 254,
+ 254, 254, 255, 255, 255, 255, 255, 256, 257, 257,
+ 257, 258, 258, 259, 259, 260, 260, 260, 262, 261,
+ 261, 263, 261, 261, 261, 261, 261, 264, 265, 261,
+ 261, 266, 266, 267, 267, 268, 268, 268, 268, 268,
+ 268, 269, 270, 270, 270, 271, 271, 271, 271, 271,
+ 272, 273, 272, 274, 272, 275, 276, 276, 277, 277,
+ 277, 278, 278, 279, 279, 280, 280, 280, 280, 281,
+ 281, 281, 281, 282, 283, 283, 283, 283, 284, 285,
+ 285, 286, 286, 286, 286, 286, 286, 286, 286, 286,
+ 286, 287, 287, 287, 287, 287, 287, 287, 287, 287,
+ 288, 288, 288, 289, 289, 289, 290, 290, 291, 291,
+ 292, 292, 293, 293, 293, 293, 294, 294, 295, 295,
+ 295, 296, 296, 297, 297, 298, 298, 298, 299, 299,
+ 300, 300, 301, 302, 303, 303, 303, 303, 304, 304,
+ 304, 304, 304, 304, 305, 305, 306, 306, 306, 307,
+ 308, 308, 308, 308, 308, 308, 309, 309, 310, 310,
+ 310, 310, 310, 310, 311, 311, 311, 311, 311, 311,
+ 312, 312, 312, 312, 312, 312, 313, 313, 314, 314,
+ 315, 315, 316, 316, 316, 317, 317, 317, 318, 318,
+ 318, 319, 319, 319, 319, 320, 320, 321, 321, 321,
+ 321, 322, 322, 322, 322, 323, 323, 323, 323, 323,
+ 323, 324, 325, 325, 325, 326, 326, 327, 328, 328,
+ 328, 328, 328, 328, 328, 329, 329, 330, 330, 330,
+ 330, 330, 330, 330, 330, 330, 330, 330, 331, 331,
+ 331, 331, 331, 331, 331, 331, 331, 331, 331, 332,
+ 332, 332, 332, 333, 334, 334, 335, 335, 336, 337,
+ 337, 339, 338, 341, 342, 340, 343, 344, 343, 345,
+ 345, 346, 346, 347, 346, 346, 348, 349, 346, 350,
+ 351, 346, 352, 353, 354, 355, 346, 356, 357, 346,
+ 358, 346, 359, 346, 360, 346, 346, 346, 346, 346,
+ 346, 346, 346, 346, 346, 346, 346, 346, 346, 346,
+ 346, 346, 346, 362, 363, 361, 365, 366, 364, 367,
+ 367, 369, 370, 368, 371, 371, 372, 372, 373, 373,
+ 373, 373, 374, 374, 374, 375, 375, 376, 376, 376,
+ 377, 377, 378, 378, 379, 380, 380, 381, 381, 381,
+ 382, 382, 382, 382, 382, 382, 382, 384, 383, 385,
+ 385, 386, 386, 386, 386, 386, 387, 387, 388, 388,
+ 388, 388, 388, 388, 389, 389, 390, 390, 391, 392,
+ 392, 393, 393, 393, 394, 395, 395, 396, 396, 396,
+ 396, 397, 398, 398, 398, 398, 398, 398, 398, 398,
+ 398, 398, 398, 398, 398, 398, 398, 398, 398, 398,
+ 398, 398, 398, 398, 398, 398, 398, 398, 398, 398,
+ 398, 398, 398, 398, 398, 398, 398
};
static const short yyr2[] = { 0,
@@ -912,2323 +916,2453 @@ static const short yyr2[] = { 0,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0, 6, 0, 6, 0, 5, 0, 5, 0, 7,
0, 7, 0, 6, 0, 6, 0, 0, 5, 5,
- 1, 5, 0, 1, 1, 0, 1, 1, 3, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 3, 1, 3, 0, 1, 1, 0, 7, 1, 1,
- 3, 4, 3, 0, 3, 1, 3, 3, 3, 3,
- 1, 1, 1, 2, 2, 2, 2, 2, 2, 2,
- 4, 2, 4, 2, 3, 3, 4, 5, 6, 6,
- 7, 2, 4, 5, 2, 2, 1, 0, 4, 4,
- 3, 1, 3, 2, 3, 4, 1, 2, 5, 1,
+ 1, 1, 5, 5, 0, 1, 1, 0, 1, 1,
+ 3, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 3, 1, 3, 0, 1, 1, 0, 7,
+ 1, 1, 3, 4, 3, 0, 3, 1, 3, 3,
+ 3, 3, 1, 1, 1, 2, 2, 2, 2, 2,
+ 2, 2, 4, 2, 4, 2, 3, 3, 4, 5,
+ 6, 6, 7, 2, 4, 5, 2, 2, 1, 0,
+ 4, 4, 3, 1, 3, 2, 3, 4, 1, 2,
+ 5, 1, 3, 3, 3, 3, 3, 3, 3, 3,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 5,
- 3, 3, 1, 2, 3, 3, 1, 1, 1, 1,
- 1, 0, 5, 5, 5, 5, 5, 1, 1, 1,
- 1, 2, 2, 3, 4, 4, 1, 1, 1, 3,
- 1, 1, 1, 1, 3, 3, 3, 0, 4, 4,
- 2, 4, 2, 4, 2, 2, 1, 4, 1, 7,
- 7, 7, 7, 4, 4, 2, 2, 2, 1, 4,
- 2, 2, 5, 3, 2, 2, 5, 3, 5, 3,
- 4, 6, 2, 1, 2, 1, 2, 1, 1, 1,
- 2, 0, 2, 2, 3, 3, 3, 2, 2, 2,
- 1, 1, 1, 2, 2, 2, 2, 1, 1, 1,
- 1, 2, 2, 3, 3, 3, 4, 1, 2, 2,
- 2, 1, 1, 1, 2, 2, 2, 1, 1, 2,
- 2, 3, 1, 2, 1, 1, 1, 4, 4, 4,
- 4, 1, 1, 1, 1, 3, 1, 3, 1, 3,
- 0, 4, 0, 6, 3, 0, 4, 1, 3, 3,
- 0, 4, 3, 0, 1, 1, 2, 6, 1, 3,
- 0, 1, 4, 6, 4, 1, 1, 1, 1, 1,
- 3, 0, 2, 1, 2, 3, 4, 1, 1, 3,
- 4, 3, 5, 1, 4, 3, 3, 0, 3, 3,
- 3, 0, 2, 2, 0, 7, 4, 0, 6, 3,
- 2, 2, 2, 0, 0, 9, 1, 0, 1, 0,
- 1, 1, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 3, 4, 3, 2, 3, 1, 0, 3, 2,
- 2, 1, 1, 0, 2, 3, 1, 4, 1, 3,
- 1, 1, 4, 4, 2, 2, 3, 3, 1, 0,
- 1, 2, 3, 2, 2, 1, 2, 2, 2, 2,
- 2, 2, 2, 1, 2, 2, 3, 2, 2, 4,
- 4, 2, 1, 5, 4, 1, 0, 1, 3, 0,
- 1, 3, 1, 1, 1, 1, 4, 4, 4, 4,
- 4, 3, 4, 4, 4, 4, 3, 1, 3, 1,
- 3, 2, 1, 7, 0, 2, 1, 2, 0, 2,
- 4, 4, 2, 4, 3, 3, 2, 2, 3, 1,
- 1, 2, 1, 1, 2, 2, 4, 4, 3, 3,
- 2, 1, 3, 3, 2, 2, 3, 1, 3, 3,
- 2, 2, 3, 1, 4, 3, 4, 3, 1, 2,
- 2, 2, 2, 2, 1, 2, 4, 4, 2, 1,
- 1, 1, 1, 2, 4, 2, 2, 2, 2, 1,
- 2, 2, 2, 2, 3, 1, 2, 3, 4, 2,
- 2, 2, 2, 2, 2, 4, 2, 1, 2, 2,
- 3, 1, 3, 2, 3, 2, 2, 3, 1, 3,
- 4, 3, 2, 2, 1, 3, 2, 2, 1, 2,
- 3, 1, 3, 1, 6, 4, 4, 3, 5, 3,
- 3, 3, 2, 1, 1, 2, 2, 2, 0, 1,
- 1, 2, 3, 1, 2, 0, 3, 0, 0, 5,
- 1, 0, 2, 1, 1, 1, 2, 0, 4, 1,
- 0, 0, 5, 0, 0, 7, 0, 0, 0, 0,
- 12, 0, 0, 7, 0, 5, 0, 7, 0, 4,
- 2, 2, 2, 3, 6, 8, 10, 12, 4, 3,
- 2, 2, 1, 1, 1, 1, 1, 0, 0, 6,
- 0, 0, 5, 1, 2, 0, 0, 5, 1, 1,
- 3, 3, 2, 2, 2, 2, 2, 1, 2, 0,
- 1, 0, 1, 1, 0, 1, 1, 3, 4, 1,
- 3, 0, 1, 1, 1, 2, 2, 2, 1, 2,
- 2, 0, 3, 1, 1, 1, 2, 2, 2, 4,
- 2, 2, 2, 2, 2, 2, 1, 2, 1, 2,
- 1, 1, 0, 0, 1, 0, 4, 2, 1, 1,
- 3, 0, 3, 3, 3, 1, 2, 2, 2, 2,
+ 3, 5, 3, 3, 1, 2, 3, 3, 1, 1,
+ 1, 1, 1, 0, 5, 5, 5, 5, 5, 1,
+ 1, 1, 1, 2, 1, 2, 2, 3, 4, 4,
+ 1, 1, 1, 3, 1, 1, 1, 1, 3, 3,
+ 3, 0, 4, 4, 2, 4, 2, 4, 2, 2,
+ 1, 4, 1, 7, 7, 7, 7, 4, 4, 2,
+ 2, 2, 1, 4, 2, 2, 5, 3, 2, 2,
+ 5, 3, 5, 3, 4, 6, 2, 1, 2, 1,
+ 2, 1, 1, 1, 2, 0, 2, 2, 3, 3,
+ 3, 2, 2, 2, 1, 1, 1, 2, 2, 2,
+ 2, 1, 1, 1, 1, 2, 2, 3, 3, 3,
+ 4, 1, 2, 2, 2, 1, 1, 1, 2, 2,
+ 2, 1, 1, 2, 2, 3, 1, 2, 1, 1,
+ 1, 4, 4, 4, 4, 1, 1, 1, 1, 3,
+ 1, 3, 1, 3, 0, 4, 0, 6, 3, 0,
+ 4, 1, 3, 3, 0, 4, 3, 0, 1, 1,
+ 2, 6, 1, 3, 0, 1, 4, 6, 4, 1,
+ 1, 1, 1, 1, 3, 0, 2, 1, 2, 3,
+ 4, 1, 1, 3, 4, 3, 5, 1, 4, 3,
+ 3, 0, 3, 3, 3, 0, 2, 2, 0, 7,
+ 4, 0, 6, 3, 2, 2, 2, 0, 0, 9,
+ 1, 0, 1, 0, 1, 1, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 3, 4, 3, 2, 3,
+ 1, 0, 3, 0, 3, 2, 1, 1, 0, 2,
+ 3, 1, 4, 1, 3, 1, 1, 4, 4, 2,
+ 2, 3, 3, 1, 0, 1, 3, 2, 2, 1,
+ 2, 2, 2, 2, 2, 2, 2, 1, 2, 2,
+ 3, 2, 2, 4, 4, 2, 1, 5, 4, 1,
+ 0, 1, 3, 0, 1, 3, 1, 1, 1, 1,
+ 4, 4, 4, 4, 4, 3, 4, 4, 4, 4,
+ 3, 1, 3, 1, 3, 2, 1, 7, 0, 2,
+ 1, 2, 0, 2, 4, 4, 2, 4, 3, 3,
+ 2, 2, 3, 1, 1, 2, 1, 1, 2, 2,
+ 4, 4, 3, 3, 2, 1, 1, 2, 3, 3,
+ 2, 2, 3, 1, 3, 3, 2, 2, 3, 1,
+ 4, 3, 4, 3, 1, 2, 2, 2, 2, 2,
+ 1, 2, 4, 4, 2, 1, 1, 1, 1, 2,
+ 4, 2, 2, 2, 2, 1, 2, 2, 2, 2,
+ 3, 1, 2, 3, 4, 2, 2, 2, 2, 2,
+ 2, 4, 2, 1, 2, 2, 3, 1, 3, 2,
+ 3, 2, 2, 3, 1, 3, 4, 3, 2, 2,
+ 1, 3, 2, 2, 1, 2, 3, 1, 3, 1,
+ 6, 4, 4, 3, 5, 3, 3, 3, 2, 1,
+ 1, 2, 2, 2, 0, 1, 1, 2, 3, 1,
+ 2, 0, 3, 0, 0, 5, 1, 0, 2, 1,
+ 1, 1, 2, 0, 4, 1, 0, 0, 5, 0,
+ 0, 7, 0, 0, 0, 0, 12, 0, 0, 7,
+ 0, 5, 0, 7, 0, 4, 2, 2, 2, 3,
+ 6, 8, 10, 12, 4, 3, 2, 2, 1, 1,
+ 1, 1, 1, 0, 0, 6, 0, 0, 5, 1,
+ 2, 0, 0, 5, 1, 1, 3, 3, 2, 2,
+ 2, 2, 2, 1, 2, 0, 1, 0, 1, 1,
+ 0, 1, 1, 3, 4, 1, 3, 0, 1, 1,
+ 1, 2, 2, 2, 1, 2, 2, 0, 3, 1,
+ 1, 1, 2, 2, 2, 4, 2, 2, 2, 2,
+ 2, 2, 1, 2, 1, 2, 1, 1, 0, 0,
+ 1, 0, 4, 2, 1, 1, 3, 0, 3, 3,
+ 3, 1, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 3,
- 2, 2, 2, 2, 3, 2, 2, 4, 4, 3,
- 2
+ 2, 2, 2, 2, 2, 3, 2, 2, 2, 2,
+ 3, 2, 2, 4, 4, 3, 2
};
static const short yydefact[] = { 3,
- 12, 12, 5, 0, 4, 0, 279, 630, 631, 0,
- 384, 396, 577, 0, 11, 0, 0, 0, 10, 482,
- 836, 0, 0, 0, 167, 662, 280, 281, 83, 0,
- 0, 823, 0, 45, 0, 0, 13, 25, 0, 27,
- 8, 0, 16, 15, 89, 110, 86, 0, 632, 171,
- 298, 277, 299, 608, 0, 371, 0, 370, 389, 0,
- 409, 388, 426, 395, 0, 497, 498, 504, 503, 502,
- 477, 383, 593, 397, 594, 108, 297, 619, 591, 0,
- 633, 575, 0, 0, 278, 81, 82, 176, 636, 176,
- 637, 176, 282, 167, 140, 141, 142, 143, 144, 468,
- 471, 0, 658, 0, 472, 0, 0, 0, 0, 141,
+ 12, 12, 5, 0, 4, 0, 281, 636, 637, 0,
+ 388, 400, 581, 0, 11, 0, 0, 0, 10, 486,
+ 842, 0, 0, 0, 167, 668, 282, 283, 83, 0,
+ 0, 829, 0, 45, 0, 0, 13, 25, 0, 27,
+ 8, 0, 16, 15, 89, 110, 86, 0, 638, 171,
+ 302, 279, 303, 614, 0, 375, 0, 374, 393, 0,
+ 413, 392, 430, 399, 0, 501, 502, 504, 508, 507,
+ 481, 387, 597, 401, 598, 108, 301, 625, 595, 0,
+ 639, 579, 0, 0, 280, 81, 82, 178, 642, 178,
+ 643, 178, 284, 167, 140, 141, 142, 143, 144, 472,
+ 475, 0, 664, 0, 476, 0, 0, 0, 0, 141,
142, 143, 144, 23, 0, 0, 0, 0, 0, 0,
- 0, 473, 640, 0, 646, 0, 0, 0, 37, 0,
- 0, 31, 0, 0, 47, 0, 176, 638, 0, 0,
- 606, 0, 0, 0, 605, 0, 0, 0, 0, 298,
- 0, 579, 0, 297, 575, 28, 0, 26, 3, 46,
- 0, 64, 384, 0, 0, 8, 67, 63, 66, 89,
- 0, 0, 0, 395, 90, 14, 0, 424, 0, 0,
- 442, 87, 79, 639, 579, 0, 575, 80, 0, 0,
- 0, 106, 0, 405, 361, 590, 362, 602, 0, 575,
- 386, 385, 78, 109, 372, 0, 407, 387, 107, 378,
- 402, 403, 373, 391, 393, 382, 404, 0, 75, 427,
- 483, 484, 485, 486, 501, 149, 148, 150, 488, 489,
- 495, 487, 0, 0, 490, 491, 504, 823, 500, 519,
- 520, 578, 390, 0, 421, 631, 0, 660, 171, 623,
- 624, 620, 596, 634, 0, 595, 592, 0, 871, 867,
- 866, 864, 846, 851, 852, 0, 858, 857, 843, 844,
- 842, 861, 850, 847, 848, 849, 853, 854, 840, 841,
- 837, 838, 839, 863, 855, 856, 845, 862, 0, 859,
- 769, 389, 770, 832, 282, 279, 577, 302, 350, 0,
- 0, 0, 0, 346, 344, 317, 348, 349, 0, 0,
- 0, 0, 0, 280, 281, 273, 0, 0, 184, 183,
- 0, 185, 186, 0, 0, 187, 0, 0, 177, 178,
- 0, 247, 0, 250, 182, 301, 213, 0, 0, 303,
- 304, 0, 180, 368, 389, 369, 625, 329, 319, 0,
- 0, 0, 0, 176, 0, 470, 0, 465, 0, 659,
- 657, 0, 188, 189, 0, 0, 0, 431, 3, 21,
- 29, 654, 650, 651, 653, 655, 652, 140, 141, 142,
- 0, 143, 144, 642, 643, 647, 644, 641, 0, 289,
- 290, 288, 622, 621, 33, 32, 49, 0, 157, 0,
- 0, 389, 155, 0, 0, 604, 0, 603, 141, 142,
- 275, 276, 293, 0, 612, 292, 0, 611, 0, 300,
- 616, 0, 0, 12, 0, 167, 9, 9, 70, 0,
- 65, 0, 0, 71, 74, 0, 423, 425, 122, 93,
- 127, 758, 0, 85, 84, 92, 125, 0, 0, 123,
- 88, 618, 0, 0, 583, 0, 826, 0, 588, 0,
- 587, 0, 0, 0, 0, 575, 424, 0, 77, 579,
- 575, 601, 0, 375, 376, 0, 76, 424, 380, 379,
- 381, 374, 394, 411, 410, 492, 496, 494, 0, 499,
- 505, 0, 0, 392, 424, 575, 94, 0, 0, 0,
- 0, 575, 100, 576, 607, 631, 661, 171, 0, 0,
- 860, 865, 391, 575, 575, 0, 575, 870, 176, 0,
- 0, 0, 220, 0, 0, 222, 235, 236, 0, 0,
- 0, 0, 0, 274, 219, 216, 215, 217, 0, 0,
- 0, 0, 0, 301, 0, 0, 0, 214, 174, 175,
- 295, 0, 218, 0, 0, 248, 0, 0, 0, 0,
+ 0, 477, 646, 0, 652, 0, 0, 0, 37, 0,
+ 0, 31, 0, 0, 47, 0, 178, 644, 0, 0,
+ 0, 612, 607, 0, 0, 0, 611, 0, 0, 0,
+ 0, 302, 0, 293, 583, 0, 0, 301, 579, 28,
+ 0, 26, 3, 46, 0, 64, 388, 0, 0, 8,
+ 67, 63, 66, 89, 0, 0, 0, 399, 90, 14,
+ 0, 428, 0, 0, 446, 87, 79, 645, 583, 0,
+ 579, 80, 0, 0, 0, 106, 0, 409, 365, 594,
+ 366, 606, 0, 579, 390, 389, 78, 109, 376, 0,
+ 411, 391, 107, 382, 406, 407, 377, 395, 397, 386,
+ 408, 0, 75, 431, 487, 488, 489, 490, 506, 149,
+ 148, 150, 492, 493, 172, 499, 491, 0, 0, 494,
+ 495, 509, 509, 524, 0, 582, 394, 0, 425, 637,
+ 0, 666, 171, 629, 630, 626, 600, 640, 0, 599,
+ 596, 0, 877, 873, 872, 870, 852, 857, 858, 0,
+ 864, 863, 849, 850, 848, 867, 856, 853, 854, 855,
+ 859, 860, 846, 847, 843, 844, 845, 869, 861, 862,
+ 851, 868, 0, 865, 775, 393, 776, 838, 284, 281,
+ 581, 306, 354, 0, 0, 0, 0, 350, 348, 321,
+ 352, 353, 0, 0, 0, 0, 0, 282, 283, 275,
+ 0, 0, 186, 185, 0, 187, 188, 0, 0, 189,
+ 0, 0, 179, 180, 0, 249, 0, 252, 184, 305,
+ 215, 0, 0, 307, 308, 0, 182, 372, 393, 373,
+ 631, 333, 323, 0, 0, 0, 0, 178, 0, 474,
+ 0, 469, 0, 665, 663, 0, 190, 191, 0, 0,
+ 0, 435, 3, 21, 29, 660, 656, 657, 659, 661,
+ 658, 140, 141, 142, 0, 143, 144, 648, 649, 653,
+ 650, 647, 0, 291, 292, 290, 628, 627, 33, 32,
+ 49, 0, 157, 0, 0, 393, 155, 0, 0, 608,
+ 610, 0, 609, 141, 142, 277, 278, 297, 0, 618,
+ 296, 0, 617, 0, 304, 282, 283, 0, 0, 0,
+ 295, 294, 622, 0, 0, 12, 0, 167, 9, 9,
+ 70, 0, 65, 0, 0, 71, 74, 0, 427, 429,
+ 122, 93, 127, 764, 0, 85, 84, 92, 125, 0,
+ 0, 123, 88, 624, 0, 0, 587, 0, 832, 0,
+ 592, 0, 591, 0, 0, 0, 0, 579, 428, 0,
+ 77, 583, 579, 605, 0, 379, 380, 0, 76, 428,
+ 384, 383, 385, 378, 398, 415, 414, 178, 496, 500,
+ 498, 0, 829, 503, 505, 547, 637, 0, 538, 0,
+ 0, 550, 0, 121, 116, 0, 171, 551, 554, 0,
+ 0, 530, 0, 119, 396, 428, 579, 94, 0, 0,
+ 0, 0, 579, 100, 580, 613, 637, 667, 171, 0,
+ 0, 866, 871, 395, 579, 579, 0, 579, 876, 178,
+ 0, 0, 0, 222, 0, 0, 224, 237, 238, 0,
+ 0, 0, 0, 0, 276, 221, 218, 217, 219, 0,
+ 0, 0, 0, 0, 305, 0, 0, 0, 216, 176,
+ 177, 299, 0, 220, 0, 0, 250, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 311, 0,
- 313, 315, 316, 354, 353, 0, 0, 238, 238, 0,
- 224, 573, 0, 232, 351, 343, 0, 0, 823, 332,
- 335, 336, 0, 0, 363, 679, 675, 684, 0, 579,
- 575, 575, 575, 365, 682, 0, 629, 367, 0, 0,
- 366, 331, 0, 326, 345, 327, 347, 626, 0, 328,
- 173, 173, 0, 165, 0, 389, 163, 570, 480, 568,
- 467, 0, 0, 398, 0, 0, 399, 400, 401, 437,
- 438, 439, 436, 0, 429, 432, 0, 3, 0, 645,
- 176, 648, 0, 41, 42, 0, 53, 0, 0, 57,
- 61, 50, 822, 817, 0, 368, 389, 53, 369, 821,
- 59, 168, 153, 151, 168, 173, 296, 610, 609, 300,
- 613, 0, 18, 20, 89, 9, 9, 73, 72, 0,
- 128, 352, 0, 706, 91, 704, 448, 0, 444, 443,
- 212, 0, 211, 580, 617, 0, 799, 0, 794, 389,
- 0, 793, 795, 824, 806, 0, 0, 615, 586, 585,
- 0, 0, 600, 0, 419, 418, 406, 599, 0, 826,
- 589, 377, 408, 420, 424, 493, 630, 631, 823, 0,
- 823, 632, 506, 507, 509, 823, 512, 511, 0, 543,
- 631, 0, 534, 0, 0, 546, 0, 121, 116, 0,
- 171, 547, 550, 0, 526, 0, 119, 0, 424, 0,
- 422, 826, 792, 176, 176, 635, 176, 826, 792, 575,
- 97, 575, 103, 869, 868, 832, 832, 832, 0, 0,
- 0, 0, 629, 0, 0, 0, 0, 389, 0, 0,
- 0, 307, 0, 305, 306, 0, 245, 179, 279, 630,
- 631, 280, 281, 0, 0, 449, 478, 0, 272, 271,
- 784, 783, 0, 269, 268, 266, 267, 265, 264, 263,
- 260, 261, 262, 258, 259, 253, 254, 255, 256, 257,
- 251, 252, 0, 0, 0, 0, 0, 238, 226, 242,
- 0, 0, 225, 575, 575, 0, 575, 572, 669, 0,
- 0, 0, 0, 0, 334, 0, 338, 0, 340, 0,
- 678, 677, 674, 673, 822, 0, 0, 693, 0, 0,
- 826, 364, 826, 680, 575, 792, 579, 679, 675, 0,
- 0, 575, 0, 0, 0, 0, 0, 170, 172, 283,
- 168, 161, 159, 168, 0, 481, 0, 480, 210, 209,
- 208, 207, 431, 0, 0, 24, 0, 0, 649, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 315,
+ 0, 317, 319, 320, 358, 357, 0, 0, 240, 240,
+ 0, 226, 577, 0, 234, 355, 347, 0, 0, 829,
+ 336, 339, 340, 0, 0, 367, 685, 681, 690, 0,
+ 583, 579, 579, 579, 369, 688, 0, 635, 371, 0,
+ 0, 370, 335, 0, 330, 349, 331, 351, 632, 0,
+ 332, 175, 175, 0, 165, 0, 393, 163, 574, 484,
+ 572, 471, 0, 0, 402, 0, 0, 403, 404, 405,
+ 441, 442, 443, 440, 0, 433, 436, 0, 3, 0,
+ 651, 178, 654, 0, 41, 42, 0, 53, 0, 0,
+ 57, 61, 50, 828, 823, 0, 372, 393, 53, 373,
+ 827, 59, 168, 153, 151, 168, 175, 300, 616, 615,
+ 304, 0, 619, 0, 18, 20, 89, 9, 9, 73,
+ 72, 0, 128, 356, 0, 712, 91, 710, 452, 0,
+ 448, 447, 214, 0, 213, 584, 623, 0, 805, 0,
+ 800, 393, 0, 799, 801, 830, 812, 0, 0, 621,
+ 590, 589, 0, 0, 604, 0, 423, 422, 410, 603,
+ 0, 832, 593, 381, 412, 424, 428, 0, 497, 510,
+ 579, 798, 546, 539, 551, 540, 428, 428, 536, 537,
+ 534, 535, 579, 798, 281, 636, 0, 415, 117, 542,
+ 552, 557, 558, 415, 415, 0, 0, 415, 115, 543,
+ 555, 415, 0, 428, 0, 531, 532, 533, 428, 426,
+ 832, 798, 178, 178, 641, 178, 832, 798, 579, 97,
+ 579, 103, 875, 874, 838, 838, 838, 0, 0, 0,
+ 0, 635, 0, 0, 0, 0, 393, 0, 0, 0,
+ 311, 0, 309, 310, 0, 247, 181, 281, 636, 637,
+ 282, 283, 0, 0, 453, 482, 0, 274, 273, 790,
+ 789, 0, 271, 270, 268, 269, 267, 266, 265, 262,
+ 263, 264, 260, 261, 255, 256, 257, 258, 259, 253,
+ 254, 0, 0, 0, 0, 0, 240, 228, 244, 0,
+ 0, 227, 579, 579, 0, 579, 576, 675, 0, 0,
+ 0, 0, 0, 338, 0, 342, 0, 344, 0, 684,
+ 683, 680, 679, 828, 0, 0, 699, 0, 0, 832,
+ 368, 832, 686, 579, 798, 583, 685, 681, 0, 0,
+ 579, 0, 392, 0, 0, 0, 0, 170, 174, 285,
+ 168, 161, 159, 168, 0, 485, 0, 484, 212, 211,
+ 210, 209, 435, 0, 0, 24, 0, 0, 655, 0,
38, 44, 43, 55, 52, 53, 0, 48, 0, 0,
- 679, 675, 0, 813, 575, 816, 818, 0, 814, 815,
- 54, 488, 0, 158, 168, 168, 156, 169, 17, 19,
- 69, 89, 412, 145, 133, 146, 147, 0, 126, 129,
- 0, 0, 0, 0, 705, 699, 445, 0, 124, 584,
- 581, 798, 812, 801, 0, 582, 797, 811, 800, 796,
- 825, 808, 819, 809, 802, 807, 828, 0, 416, 598,
- 597, 415, 516, 0, 515, 823, 823, 823, 0, 575,
- 792, 542, 535, 547, 536, 424, 424, 532, 533, 530,
- 531, 575, 792, 279, 630, 0, 411, 117, 538, 548,
- 553, 554, 411, 411, 0, 0, 411, 115, 539, 551,
- 411, 527, 528, 529, 424, 525, 474, 0, 96, 0,
- 0, 0, 0, 102, 0, 826, 792, 826, 792, 834,
- 833, 835, 284, 318, 221, 223, 324, 325, 0, 0,
- 0, 0, 306, 309, 0, 0, 0, 0, 246, 0,
- 310, 312, 314, 0, 0, 0, 0, 227, 244, 0,
- 0, 666, 664, 0, 667, 579, 233, 0, 0, 176,
- 341, 0, 0, 0, 676, 672, 683, 575, 692, 690,
- 691, 681, 826, 0, 688, 0, 627, 628, 0, 330,
- 166, 168, 168, 164, 571, 569, 469, 0, 430, 428,
- 279, 0, 22, 30, 656, 56, 51, 58, 62, 678,
- 674, 679, 675, 0, 591, 0, 575, 680, 60, 154,
+ 685, 681, 0, 819, 579, 822, 824, 0, 820, 821,
+ 54, 492, 0, 158, 168, 168, 156, 169, 298, 17,
+ 19, 69, 89, 416, 145, 636, 637, 133, 146, 147,
+ 0, 126, 129, 0, 638, 0, 0, 0, 0, 711,
+ 705, 449, 0, 124, 588, 585, 804, 818, 807, 0,
+ 586, 803, 817, 806, 802, 831, 814, 825, 815, 808,
+ 813, 834, 0, 420, 602, 601, 419, 175, 829, 0,
+ 829, 511, 512, 514, 829, 517, 516, 832, 0, 541,
+ 446, 446, 832, 0, 0, 0, 428, 428, 0, 428,
+ 428, 0, 428, 0, 529, 478, 0, 446, 96, 0,
+ 0, 0, 0, 102, 0, 832, 798, 832, 798, 840,
+ 839, 841, 286, 322, 223, 225, 328, 329, 0, 0,
+ 0, 0, 310, 313, 0, 0, 0, 0, 248, 0,
+ 314, 316, 318, 0, 0, 0, 0, 229, 246, 0,
+ 0, 672, 670, 0, 673, 583, 235, 0, 0, 178,
+ 345, 0, 0, 0, 682, 678, 689, 579, 698, 696,
+ 697, 687, 832, 0, 694, 0, 633, 634, 0, 334,
+ 166, 168, 168, 164, 575, 573, 473, 0, 434, 432,
+ 281, 0, 22, 30, 662, 56, 51, 58, 62, 684,
+ 680, 685, 681, 0, 595, 0, 579, 686, 60, 154,
152, 68, 0, 131, 0, 135, 0, 137, 0, 139,
- 0, 759, 0, 200, 707, 0, 700, 701, 0, 446,
- 679, 675, 0, 301, 0, 625, 820, 0, 0, 829,
- 830, 0, 0, 413, 0, 0, 0, 518, 517, 510,
- 826, 0, 537, 442, 442, 826, 0, 0, 0, 424,
- 424, 0, 424, 424, 0, 424, 0, 442, 462, 575,
- 286, 285, 287, 575, 99, 0, 105, 0, 0, 0,
- 0, 0, 0, 452, 0, 450, 249, 270, 240, 239,
- 237, 228, 0, 241, 243, 665, 663, 670, 668, 0,
- 234, 0, 0, 333, 337, 339, 826, 686, 575, 687,
- 162, 160, 466, 0, 433, 435, 678, 674, 596, 680,
- 132, 130, 0, 0, 0, 0, 440, 0, 0, 279,
- 630, 631, 708, 721, 724, 727, 732, 0, 0, 0,
- 0, 0, 0, 0, 0, 280, 753, 761, 0, 780,
- 757, 756, 755, 0, 716, 0, 0, 389, 0, 695,
- 714, 720, 694, 715, 754, 0, 702, 447, 0, 628,
- 810, 804, 805, 803, 0, 827, 417, 0, 513, 514,
- 508, 112, 575, 541, 545, 114, 575, 424, 424, 562,
- 442, 279, 630, 0, 549, 555, 556, 411, 411, 442,
- 442, 0, 442, 552, 540, 0, 826, 826, 575, 575,
- 0, 0, 0, 0, 451, 0, 0, 229, 230, 671,
- 342, 285, 689, 826, 0, 134, 136, 138, 766, 760,
- 764, 0, 703, 698, 203, 773, 775, 776, 0, 0,
- 712, 0, 0, 0, 739, 741, 742, 743, 0, 0,
- 0, 0, 0, 0, 0, 774, 0, 360, 781, 0,
- 717, 358, 411, 0, 359, 0, 411, 0, 0, 0,
- 201, 697, 696, 718, 752, 751, 306, 831, 414, 826,
- 826, 561, 558, 560, 0, 0, 424, 424, 424, 557,
- 559, 544, 464, 0, 463, 458, 95, 101, 826, 826,
- 320, 321, 322, 323, 453, 0, 231, 685, 434, 0,
- 765, 441, 192, 0, 709, 722, 711, 0, 0, 0,
- 0, 0, 735, 0, 744, 0, 750, 39, 144, 34,
- 144, 0, 35, 762, 0, 356, 357, 0, 0, 0,
- 355, 202, 712, 111, 113, 424, 424, 567, 442, 442,
- 0, 0, 476, 98, 104, 574, 0, 767, 199, 0,
- 389, 0, 712, 0, 725, 713, 699, 778, 728, 0,
- 0, 0, 0, 740, 749, 40, 36, 0, 0, 719,
- 566, 564, 563, 565, 461, 460, 454, 86, 89, 0,
- 0, 0, 193, 411, 710, 204, 723, 206, 0, 779,
- 0, 777, 733, 737, 736, 763, 785, 0, 0, 459,
- 771, 772, 768, 424, 699, 190, 0, 0, 196, 0,
- 195, 712, 0, 0, 0, 786, 787, 745, 457, 0,
- 456, 0, 205, 0, 726, 729, 734, 738, 0, 785,
- 0, 0, 455, 197, 191, 0, 0, 0, 746, 788,
- 0, 0, 789, 0, 0, 198, 730, 790, 0, 747,
- 0, 0, 0, 731, 791, 748, 0, 0, 0
+ 0, 765, 0, 202, 713, 0, 706, 707, 0, 450,
+ 685, 681, 0, 305, 0, 631, 826, 0, 0, 835,
+ 836, 0, 0, 417, 173, 521, 0, 520, 829, 829,
+ 829, 0, 112, 579, 545, 549, 114, 579, 428, 428,
+ 566, 446, 281, 636, 0, 553, 559, 560, 415, 415,
+ 446, 446, 0, 446, 556, 466, 544, 579, 288, 287,
+ 289, 579, 99, 0, 105, 0, 0, 0, 0, 0,
+ 0, 456, 0, 454, 251, 272, 242, 241, 239, 230,
+ 0, 243, 245, 671, 669, 676, 674, 0, 236, 0,
+ 0, 337, 341, 343, 832, 692, 579, 693, 162, 160,
+ 470, 0, 437, 439, 684, 680, 600, 686, 132, 130,
+ 0, 0, 0, 0, 444, 0, 0, 281, 636, 637,
+ 714, 727, 730, 733, 738, 0, 0, 0, 0, 0,
+ 0, 0, 0, 282, 759, 767, 0, 786, 763, 762,
+ 761, 0, 722, 0, 0, 393, 0, 701, 720, 726,
+ 700, 721, 760, 0, 708, 451, 0, 634, 816, 810,
+ 811, 809, 0, 833, 421, 0, 0, 0, 0, 523,
+ 522, 515, 832, 832, 565, 562, 564, 0, 0, 428,
+ 428, 428, 561, 563, 548, 0, 832, 832, 579, 579,
+ 0, 0, 0, 0, 455, 0, 0, 231, 232, 677,
+ 346, 287, 695, 832, 0, 134, 136, 138, 772, 766,
+ 770, 0, 709, 704, 205, 779, 781, 782, 0, 0,
+ 718, 0, 0, 0, 745, 747, 748, 749, 0, 0,
+ 0, 0, 0, 0, 0, 780, 0, 364, 787, 0,
+ 723, 362, 415, 0, 363, 0, 415, 0, 0, 0,
+ 203, 703, 702, 724, 758, 757, 310, 837, 418, 518,
+ 519, 513, 111, 113, 428, 428, 571, 446, 446, 468,
+ 0, 467, 462, 95, 101, 832, 832, 324, 325, 326,
+ 327, 457, 0, 233, 691, 438, 0, 771, 445, 194,
+ 0, 715, 728, 717, 0, 0, 0, 0, 0, 741,
+ 0, 750, 0, 756, 39, 144, 34, 144, 0, 35,
+ 768, 0, 360, 361, 0, 0, 0, 359, 204, 718,
+ 570, 568, 567, 569, 0, 0, 480, 98, 104, 578,
+ 0, 773, 201, 0, 393, 0, 718, 0, 731, 719,
+ 705, 784, 734, 0, 0, 0, 0, 746, 755, 40,
+ 36, 0, 0, 725, 465, 464, 458, 86, 89, 0,
+ 0, 0, 195, 415, 716, 206, 729, 208, 0, 785,
+ 0, 783, 739, 743, 742, 769, 791, 0, 0, 463,
+ 777, 778, 774, 428, 705, 192, 0, 0, 198, 0,
+ 197, 718, 0, 0, 0, 792, 793, 751, 461, 0,
+ 460, 0, 207, 0, 732, 735, 740, 744, 0, 791,
+ 0, 0, 459, 199, 193, 0, 0, 0, 752, 794,
+ 0, 0, 795, 0, 0, 200, 736, 796, 0, 753,
+ 0, 0, 0, 737, 797, 754, 0, 0, 0
};
-static const short yydefgoto[] = { 1607,
- 424, 2, 425, 161, 694, 327, 177, 3, 4, 37,
- 658, 369, 1291, 659, 766, 1292, 1293, 389, 1394, 663,
- 41, 767, 398, 669, 934, 670, 671, 672, 43, 168,
- 169, 44, 443, 180, 176, 45, 46, 783, 1057, 789,
- 1059, 47, 769, 770, 181, 182, 444, 701, 969, 970,
- 638, 971, 230, 48, 956, 955, 685, 682, 1123, 1122,
- 914, 911, 136, 954, 49, 50, 908, 551, 328, 329,
- 330, 331, 1294, 1558, 1455, 1560, 1500, 1591, 1165, 1537,
- 1555, 363, 901, 332, 1232, 856, 590, 863, 333, 334,
- 364, 336, 354, 52, 251, 664, 413, 53, 54, 337,
- 546, 338, 339, 340, 341, 445, 342, 1295, 484, 612,
- 343, 1296, 56, 213, 675, 344, 214, 524, 215, 193,
- 206, 60, 467, 485, 1318, 735, 1183, 194, 207, 61,
- 495, 736, 62, 63, 654, 655, 656, 1268, 450, 826,
- 827, 1528, 1529, 1493, 1435, 1346, 64, 642, 357, 1209,
- 1436, 1078, 917, 65, 66, 67, 68, 69, 237, 70,
- 71, 239, 753, 754, 755, 756, 241, 492, 493, 780,
- 774, 775, 776, 1029, 1039, 1030, 1335, 1031, 1032, 1336,
- 1337, 639, 640, 591, 891, 346, 453, 454, 187, 195,
- 73, 74, 75, 196, 197, 153, 77, 132, 347, 348,
- 349, 79, 350, 81, 758, 123, 124, 125, 500, 105,
- 82, 351, 868, 869, 886, 615, 1299, 1300, 1166, 1167,
- 1168, 705, 1301, 976, 1302, 1379, 1503, 1458, 1459, 1303,
- 1304, 1483, 1380, 1504, 1381, 1539, 1382, 1541, 1586, 1601,
- 1383, 1562, 1513, 1563, 1464, 446, 702, 1266, 1305, 1397,
- 1518, 1370, 1371, 1450, 1532, 1502, 1498, 1306, 1509, 1400,
- 833, 1565, 1566, 1567, 1599, 721, 722, 996, 1179, 1314,
- 723, 724, 725, 992, 726, 146, 994, 728, 1181, 1182,
- 518, 84, 85
+static const short yydefgoto[] = { 1627,
+ 436, 2, 437, 165, 726, 331, 181, 3, 4, 37,
+ 689, 373, 1329, 690, 512, 1330, 1331, 393, 1424, 694,
+ 41, 513, 402, 700, 974, 701, 702, 703, 43, 172,
+ 173, 44, 455, 184, 180, 45, 46, 822, 1087, 828,
+ 1089, 47, 515, 516, 185, 186, 456, 733, 1012, 1013,
+ 669, 1014, 234, 48, 996, 995, 716, 713, 1153, 1152,
+ 954, 951, 136, 994, 49, 236, 50, 948, 582, 332,
+ 333, 334, 335, 1332, 1578, 1482, 1580, 1524, 1611, 1195,
+ 1557, 1575, 367, 940, 336, 1270, 895, 621, 902, 337,
+ 338, 368, 340, 358, 52, 255, 695, 418, 154, 53,
+ 54, 341, 577, 342, 343, 344, 345, 457, 346, 1333,
+ 496, 643, 347, 1334, 56, 217, 706, 348, 218, 555,
+ 219, 197, 210, 60, 479, 497, 1356, 767, 1213, 198,
+ 211, 61, 526, 768, 62, 63, 685, 686, 687, 1306,
+ 462, 865, 866, 1548, 1549, 1517, 1462, 1376, 64, 673,
+ 361, 1246, 1463, 1108, 957, 65, 66, 67, 68, 69,
+ 242, 243, 70, 71, 504, 1052, 1053, 1054, 1055, 245,
+ 520, 815, 521, 522, 523, 800, 810, 801, 1236, 802,
+ 803, 1237, 1238, 670, 671, 622, 930, 350, 465, 466,
+ 191, 199, 73, 74, 75, 200, 142, 143, 157, 77,
+ 132, 351, 352, 353, 79, 354, 81, 1057, 123, 124,
+ 125, 531, 105, 82, 355, 907, 908, 925, 646, 1337,
+ 1338, 1196, 1197, 1198, 737, 1339, 1021, 1340, 1409, 1527,
+ 1485, 1486, 1341, 1342, 1510, 1410, 1528, 1411, 1559, 1412,
+ 1561, 1606, 1621, 1413, 1582, 1537, 1583, 1491, 458, 734,
+ 1304, 1343, 1427, 1542, 1400, 1401, 1477, 1552, 1526, 1522,
+ 1344, 1533, 1430, 872, 1585, 1586, 1587, 1619, 753, 754,
+ 1041, 1209, 1352, 755, 756, 757, 1037, 758, 148, 1039,
+ 760, 1211, 1212, 549, 84, 85
};
-static const short yypact[] = { 129,
- 148,-32768,-32768, 10535,-32768, 92, 171, 272, 418, 199,
- 124,-32768,-32768, 917,-32768, 270, 355, 360,-32768,-32768,
--32768, 1076, 1285, 1017, 216,-32768, 409, 499,-32768, 1618,
- 1618,-32768, 4295,-32768, 10535, 415,-32768,-32768, 457,-32768,
- 56, 4736,-32768,-32768, 412, 903, 509, 492, 505,-32768,
--32768,-32768,-32768, 404, 1979,-32768, 4015,-32768, 2281, 329,
--32768, 560,-32768,-32768, 798, 328,-32768, 548,-32768,-32768,
- 567, 3285,-32768,-32768,-32768, 580,-32768,-32768,-32768, 1021,
--32768,-32768, 274, 7834, 555,-32768,-32768, 9429,-32768, 9429,
--32768, 9429,-32768,-32768,-32768, 272, 418, 409, 578, 563,
- 600, 505,-32768, 760,-32768, 274, 9515, 9515, 607,-32768,
--32768,-32768,-32768,-32768, 601, 648, 549, 665, 680, 663,
- 670,-32768,-32768, 1357,-32768, 1247, 272, 418,-32768, 409,
- 578,-32768, 690, 1972, 657, 5887, 9429,-32768, 9429, 2223,
--32768, 2434, 402, 2223,-32768, 1599, 2316, 2316, 4295, 641,
- 654, 649, 658, 679,-32768,-32768, 781,-32768, 685,-32768,
- 3410,-32768,-32768, 216, 3278, 722,-32768,-32768,-32768, 412,
- 4520, 10740, 737, 749,-32768,-32768, 735, 560, 843, 98,
- 689, 791,-32768,-32768, 736, 66,-32768,-32768, 2840, 2840,
- 4591, 580, 855,-32768,-32768, 540,-32768,-32768, 2691,-32768,
--32768,-32768,-32768,-32768, 2281, 878,-32768, 560, 580,-32768,
--32768,-32768, 2369, 2281,-32768, 560,-32768, 4520,-32768,-32768,
+static const short yypact[] = { 136,
+ 169,-32768,-32768, 5066,-32768, 203, 163, 73, 77, 190,
+ 291,-32768,-32768, 1458,-32768, 259, 264, 279,-32768,-32768,
+-32768, 871, 2044, 1374, 330,-32768, 336, 320,-32768, 1976,
+ 1976,-32768, 2798,-32768, 5066, 351,-32768,-32768, 355,-32768,
+ 51, 3166,-32768,-32768, 344, 824, 443, 463, 483,-32768,
+-32768,-32768,-32768, 324, 5213,-32768, 5421,-32768, 2205, 804,
+-32768, 456,-32768,-32768, 1137, 623,-32768,-32768,-32768,-32768,
+ 435, 3747,-32768,-32768,-32768, 198,-32768,-32768,-32768, 906,
+-32768,-32768, 1174, 8340, 481,-32768,-32768, 10037,-32768, 10037,
+-32768, 10037,-32768,-32768,-32768, 73, 77, 336, 510, 472,
+ 539, 483,-32768, 1000,-32768, 1174, 10123, 10123, 509,-32768,
+-32768,-32768,-32768,-32768, 234, 550, 474, 541, 767, 554,
+ 564,-32768,-32768, 1006,-32768, 305, 73, 77,-32768, 336,
+ 510,-32768, 2508, 1031, 545, 5547, 10037,-32768, 10037, 4171,
+ 2952,-32768,-32768, 1311, 1265, 2952,-32768, 664, 3604, 3604,
+ 2798, 517, 538,-32768, 559, 876, 562, 592,-32768,-32768,
+ 700,-32768, 630,-32768, 3999,-32768,-32768, 330, 3843, 643,
+-32768,-32768,-32768, 344, 6652, 6133, 836, 690,-32768,-32768,
+ 684, 456, 778, 176, 458, 728,-32768,-32768, 691, 69,
+-32768,-32768, 3940, 3940, 6529, 198, 864,-32768,-32768, 546,
+-32768,-32768, 1679,-32768,-32768,-32768,-32768,-32768, 2205, 883,
+-32768, 456, 198,-32768,-32768,-32768, 2251, 2205,-32768, 456,
+-32768, 6652,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
+-32768,-32768, 749,-32768, 483,-32768, 456, 2169, 910,-32768,
+-32768, 766, 766,-32768, 4696,-32768, 715, 1174,-32768, 784,
+ 1757,-32768, 366,-32768,-32768,-32768,-32768,-32768, 4100,-32768,
+-32768, 769,-32768, 740, 758,-32768,-32768,-32768,-32768, 781,
-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
- 505, 560, 1485, 1636,-32768,-32768, 548,-32768,-32768,-32768,
--32768,-32768, 1027, 274,-32768, 217, 1224,-32768, 94,-32768,
--32768,-32768,-32768,-32768, 2883,-32768,-32768, 229,-32768, 765,
- 769,-32768,-32768,-32768,-32768, 811,-32768,-32768,-32768,-32768,
-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
--32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, 764,-32768,
--32768, 1027, 3285, 814,-32768,-32768, 790,-32768,-32768, 10123,
- 10209, 10295, 10295,-32768,-32768,-32768,-32768,-32768, 800, 825,
- 834, 853, 870, 1090, 578, 9601, 1697, 10295,-32768,-32768,
- 10295,-32768,-32768, 10295, 7312,-32768, 10295, 181, 894,-32768,
- 10295,-32768, 9687,-32768, 10982, 370, 1912, 4227, 9773,-32768,
- 948, 2212,-32768, 1316, 3488, 3177,-32768, 380,-32768, 1589,
- 1575, 181, 181, 9429, 5887,-32768, 1697, 857, 1697,-32768,
--32768, 871, 934, 10915, 889, 902, 908, 1438, 685,-32768,
--32768,-32768,-32768,-32768,-32768,-32768,-32768, 648, 549, 665,
- 1697, 680, 663, 932, 670,-32768, 969,-32768, 3160, 272,
- 418,-32768,-32768,-32768,-32768,-32768,-32768, 4962,-32768, 4520,
- 5717, 557,-32768, 181, 865,-32768, 366,-32768, 977, 985,
--32768,-32768,-32768, 2223,-32768,-32768, 2223,-32768, 935,-32768,
--32768, 2883, 96, 951, 957,-32768,-32768,-32768,-32768, 5887,
--32768, 890, 897,-32768,-32768, 781,-32768, 560,-32768,-32768,
--32768,-32768, 145,-32768,-32768,-32768,-32768, 7403, 9601,-32768,
--32768,-32768, 9601, 973,-32768, 6666, 131, 3139,-32768, 3139,
--32768, 3732, 3732, 4591, 978,-32768, 560, 4520,-32768, 974,
--32768,-32768, 3884, 2369, 2281, 4520,-32768, 560,-32768,-32768,
- 560, 2369,-32768, 1061,-32768,-32768, 505,-32768, 1485,-32768,
- 1755, 5946, 61, 1027, 560,-32768,-32768, 991, 1015, 1037,
- 1019,-32768,-32768,-32768,-32768, 387,-32768, 392, 983, 986,
--32768,-32768, 1027,-32768,-32768, 466,-32768,-32768, 9429, 9601,
- 790, 7312,-32768, 400, 7312,-32768,-32768,-32768, 9515, 3739,
- 3739, 3739, 3739, 10960,-32768,-32768,-32768,-32768, 990, 10381,
- 10381, 7312, 995, 50, 999, 1050, 1003,-32768,-32768,-32768,
--32768, 9429,-32768, 6942, 7312,-32768, 9601, 9601, 7494, 9601,
- 9601, 9601, 9601, 9601, 9601, 9601, 9601, 9601, 9601, 9601,
- 9601, 9601, 9601, 9601, 9601, 9601, 9601, 9601,-32768, 9601,
--32768,-32768,-32768,-32768,-32768, 9601, 9601,-32768,-32768, 4867,
- 796, 610, 8194,-32768,-32768,-32768, 1065, 1224, 1112, 448,
- 502, 520, 1832, 402,-32768, 1177, 1177,-32768, 2598, 1012,
- 1031, 1080,-32768,-32768, 575, 8884, 956,-32768, 711, 274,
--32768,-32768, 9601,-32768,-32768,-32768,-32768,-32768, 562, 555,
--32768,-32768, 181,-32768, 4520, 2080,-32768, 1067, 1070,-32768,
--32768, 1697, 932,-32768, 7926, 8017,-32768,-32768,-32768,-32768,
--32768,-32768,-32768, 141,-32768, 1049, 1039, 685, 3160, 1093,
- 9429,-32768, 1091,-32768,-32768, 1972, 1328, 1116, 481, 1092,
- 1096,-32768,-32768, 2423, 10740, 2423, 2100, 798, 4579,-32768,
- 1102,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, 1046,
--32768, 1097,-32768,-32768, 412,-32768,-32768,-32768,-32768, 97,
- 362, 1106, 1050,-32768,-32768,-32768,-32768, 6848, 10960,-32768,
- 934, 1062, 10915,-32768,-32768, 1063,-32768, 1066, 624, 2989,
- 1072,-32768, 154, 5663, 1109, 1111, 577,-32768,-32768,-32768,
- 3139, 3139,-32768, 3884,-32768, 1119,-32768,-32768, 1073, 131,
--32768, 2369,-32768,-32768, 560,-32768, 549, 665,-32768, 1095,
--32768, 670, 1133,-32768,-32768, 376,-32768,-32768, 1770,-32768,
- 635, 785,-32768, 9601, 10613,-32768, 10613, 365, 365, 343,
- 630, 3533, 5783, 8262,-32768, 191, 365, 1131, 560, 8332,
--32768, 131, 4646, 9429, 9429,-32768, 9429, 131, 4646,-32768,
--32768,-32768,-32768,-32768,-32768, 526, 526, 526, 181, 1086,
- 1089, 9865, 1080, 1098, 1099, 1100, 1125, 3672, 1134, 1142,
- 1146,-32768, 1114,-32768,-32768, 1115,-32768,-32768, 1163, 422,
- 547, 325, 85, 9601, 1164,-32768, 1173, 1127, 10960, 10960,
--32768,-32768, 1175, 4072, 3326, 5005, 3563, 5041, 4438, 2541,
- 3040, 3040, 3040, 2262, 2262, 1391, 1391, 146, 146, 146,
--32768,-32768, 1136, 1137, 1130, 9601, 9515,-32768, 796,-32768,
- 7403, 9601,-32768,-32768,-32768, 9601,-32768,-32768, 1148, 10295,
- 1143, 1178, 1198, 1226,-32768, 9601,-32768, 9601,-32768, 9601,
- 1792,-32768, 1792,-32768, 103, 1166, 1168,-32768, 1171, 3739,
- 131,-32768, 131, 2092,-32768, 4646, 1172, 9068, 9068, 6252,
- 1176, 9687, 1183, 2753, 1575, 861, 1186,-32768,-32768,-32768,
--32768,-32768,-32768,-32768, 9601, 1697, 1197, 1070,-32768, 10960,
--32768, 10960, 1438, 1202, 9951,-32768, 1204, 1255,-32768, 181,
--32768,-32768,-32768,-32768,-32768, 1207, 4962,-32768, 3739, 9429,
- 1346, 1346, 4301,-32768,-32768,-32768,-32768, 2691,-32768,-32768,
--32768, 993, 9601,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
--32768, 412,-32768, 648,-32768, 680, 663, 9601, 1227,-32768,
- 637, 644, 667, 1050,-32768, 93,-32768, 117,-32768,-32768,
--32768,-32768,-32768,-32768, 8976,-32768,-32768,-32768,-32768,-32768,
--32768,-32768, 1111, 1252,-32768,-32768,-32768, 3739,-32768,-32768,
--32768, 1253,-32768, 9515,-32768,-32768,-32768,-32768, 875,-32768,
- 4646, 10960,-32768, 1199,-32768, 560, 560,-32768,-32768,-32768,
--32768,-32768, 4646, 523, 898, 9601, 1061,-32768, 1263,-32768,
--32768,-32768, 197, 225, 1021, 402, 333, 365, 1267,-32768,
- 462,-32768,-32768,-32768, 560,-32768,-32768, 8402,-32768, 1222,
- 181, 181, 181,-32768, 1229, 131, 4646, 131, 4646,-32768,
--32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, 1241, 1242,
- 1245, 1250, 1046,-32768, 10848, 7403, 7036, 1231,-32768, 9601,
--32768,-32768,-32768, 1239, 1246, 1248, 3739,-32768,-32768, 1249,
- 361, 768, 768, 1257, 768,-32768,-32768, 10295, 1350, 9429,
--32768, 1266, 1280, 1281,-32768,-32768,-32768,-32768,-32768,-32768,
--32768,-32768, 131, 1282,-32768, 1260,-32768,-32768, 2901,-32768,
--32768,-32768,-32768,-32768, 10960,-32768,-32768, 1283,-32768,-32768,
- 210, 1286,-32768,-32768,-32768,-32768,-32768,-32768,-32768, 1374,
- 1374, 1710, 1710, 4301,-32768, 2691,-32768, 1851, 10982,-32768,
--32768,-32768, 1287,-32768, 362,-32768, 9601,-32768, 9601,-32768,
- 9601,-32768, 1697,-32768,-32768, 6460, 1342,-32768, 7127,-32768,
- 9160, 9160, 6572, 285, 1289, 373,-32768, 7403, 7218,-32768,
--32768, 268, 7403,-32768, 1290, 1291, 1755,-32768,-32768,-32768,
- 131, 1296,-32768, 1343, 1343, 131, 1304, 9601, 9601, 10826,
- 560, 3996, 560, 560, 921, 560, 4123, 1343,-32768,-32768,
--32768, 1365,-32768,-32768,-32768, 1312,-32768, 1317, 9601, 9601,
- 9601, 9601, 7403,-32768, 1367,-32768,-32768, 10960,-32768,-32768,
--32768, 496, 1248,-32768,-32768,-32768,-32768,-32768,-32768, 1321,
--32768, 1380, 181,-32768,-32768,-32768, 131,-32768,-32768,-32768,
--32768,-32768,-32768, 9601,-32768,-32768, 1374, 1374,-32768, 1851,
--32768,-32768, 1325, 1327, 1330, 1352,-32768, 923, 275, 1387,
- 980, 1038,-32768,-32768,-32768,-32768,-32768, 9601, 1396, 1399,
- 1401, 9252, 237, 1697, 421, 636,-32768,-32768, 9343, 1454,
--32768,-32768,-32768, 1409,-32768, 4396, 10681, 10795, 6350,-32768,
--32768, 1461,-32768,-32768,-32768, 8495,-32768,-32768, 1372, 614,
--32768,-32768,-32768,-32768, 3739,-32768,-32768, 7403,-32768,-32768,
--32768,-32768,-32768,-32768,-32768,-32768,-32768, 10826, 10826,-32768,
- 1343, 651, 1048, 9601,-32768,-32768,-32768, 1061, 1061, 1343,
- 1343, 387, 1343,-32768,-32768, 6089, 131, 131,-32768,-32768,
- 1376, 1377, 1379, 1383,-32768, 7403, 9601,-32768, 496,-32768,
--32768,-32768,-32768, 131, 1388,-32768,-32768,-32768,-32768, 1352,
--32768, 1697,-32768,-32768,-32768,-32768,-32768,-32768, 682, 682,
- 1050, 1404, 1410, 5995,-32768,-32768,-32768,-32768, 1442, 9601,
- 1444, 1441, 1458, 1840, 1872,-32768, 1050,-32768,-32768, 1422,
--32768,-32768, 1061, 927,-32768, 954, 1061, 10037, 987, 289,
--32768,-32768,-32768,-32768,-32768,-32768, 397,-32768,-32768, 131,
- 131,-32768,-32768,-32768, 9601, 9601, 10826, 560, 560,-32768,
--32768,-32768,-32768, 8108,-32768,-32768,-32768,-32768, 131, 131,
--32768,-32768,-32768,-32768,-32768, 1405,-32768,-32768,-32768, 1424,
--32768,-32768,-32768, 9515,-32768,-32768,-32768, 1501, 8791, 6757,
- 9515, 9601,-32768, 8603,-32768, 1460,-32768,-32768, 1467,-32768,
- 1458, 1840,-32768,-32768, 781,-32768,-32768, 10467, 10467, 7585,
--32768,-32768, 1050,-32768,-32768, 10826, 10826,-32768, 1343, 1343,
- 1415, 10870, 1430,-32768,-32768,-32768, 5586,-32768,-32768, 1420,
- 252, 4520, 1050, 8697,-32768,-32768, 93,-32768,-32768, 1471,
- 1427, 10938, 8603,-32768,-32768,-32768,-32768, 1352, 89,-32768,
--32768,-32768,-32768,-32768,-32768,-32768,-32768, 509, 412, 1431,
- 1432, 1050,-32768, 1061,-32768,-32768,-32768,-32768, 705,-32768,
- 7676,-32768,-32768,-32768,-32768, 1352, 1527, 1486, 170,-32768,
--32768,-32768,-32768, 560, 93,-32768, 9601, 1487,-32768, 1488,
--32768, 1050, 8603, 1452, 753, 1493,-32768,-32768,-32768, 145,
--32768, 1489,-32768, 1446,-32768,-32768,-32768,-32768, 9601, 1527,
- 1495, 1527,-32768,-32768,-32768, 7767, 1457, 787,-32768,-32768,
- 7403, 1459,-32768, 1557, 1511,-32768,-32768,-32768, 295,-32768,
- 8697, 1561, 1513,-32768,-32768,-32768, 1576, 1577,-32768
+-32768,-32768, 755,-32768,-32768, 715, 3747, 1632,-32768,-32768,
+ 776,-32768,-32768, 10731, 10817, 10903, 10903,-32768,-32768,-32768,
+-32768,-32768, 780, 786, 797, 825, 832, 1025, 510, 10209,
+ 1357, 10903,-32768,-32768, 10903,-32768,-32768, 10903, 7539,-32768,
+ 10903, 65, 849,-32768, 10903,-32768, 10295,-32768, 11119, 426,
+ 1563, 3740, 10381,-32768, 919, 2567,-32768, 1700, 2285, 3286,
+-32768, 431,-32768, 3387, 1998, 65, 65, 10037, 5547,-32768,
+ 1357, 827, 1357,-32768,-32768, 826, 879, 11052, 837, 842,
+ 857, 1966, 630,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
+-32768, 550, 474, 541, 1357, 767, 554, 881, 564,-32768,
+ 914,-32768, 270, 73, 77,-32768,-32768,-32768,-32768,-32768,
+-32768, 6834,-32768, 6652, 6645, 723,-32768, 65, 301,-32768,
+-32768, 811,-32768, 897, 903,-32768,-32768,-32768, 2952,-32768,
+-32768, 2952,-32768, 873,-32768,-32768,-32768, 876, 876, 876,
+-32768,-32768,-32768, 4100, 103, 875, 884,-32768,-32768,-32768,
+-32768, 5547,-32768, 900, 963,-32768,-32768, 700,-32768, 456,
+-32768,-32768,-32768,-32768, 165,-32768,-32768,-32768,-32768, 8091,
+ 10209,-32768,-32768,-32768, 10209, 877,-32768, 5311, 240, 4742,
+-32768, 4742,-32768, 5059, 5059, 6529, 882,-32768, 456, 6652,
+-32768, 891,-32768,-32768, 5849, 2251, 2205, 6652,-32768, 456,
+-32768,-32768, 456, 2251,-32768, 981,-32768, 10037, 749,-32768,
+-32768, 2169,-32768,-32768,-32768,-32768, 807, 385,-32768, 10209,
+ 1836,-32768, 1836, 219, 219, 220, 433, 3033, 4527, 108,
+ 4879,-32768, 274, 219, 715, 456,-32768,-32768, 941, 944,
+ 971, 955,-32768,-32768,-32768,-32768, 847,-32768, 439, 921,
+ 927,-32768,-32768, 715,-32768,-32768, 1100,-32768,-32768, 10037,
+ 10209, 776, 7539,-32768, 451, 7539,-32768,-32768,-32768, 10123,
+ 4970, 4970, 4970, 4970, 11097,-32768,-32768,-32768,-32768, 934,
+ 10473, 10473, 7539, 937, 437, 939, 991, 947,-32768,-32768,
+-32768,-32768, 10037,-32768, 7630, 7539,-32768, 10209, 10209, 5654,
+ 10209, 10209, 10209, 10209, 10209, 10209, 10209, 10209, 10209, 10209,
+ 10209, 10209, 10209, 10209, 10209, 10209, 10209, 10209, 10209,-32768,
+ 10209,-32768,-32768,-32768,-32768,-32768, 10209, 10209,-32768,-32768,
+ 339, 651, 1120, 8700,-32768,-32768,-32768, 998, 1757, 1053,
+ 469, 482, 581, 3585, 1265,-32768, 1659, 1659,-32768, 3502,
+ 960, 982, 1043,-32768,-32768, 590, 9320, 1173,-32768, 1103,
+ 1174,-32768,-32768, 10209,-32768,-32768,-32768,-32768,-32768, 90,
+ 481,-32768,-32768, 65,-32768, 6652, 1444,-32768, 1014, 1034,
+-32768,-32768, 1357, 881,-32768, 8432, 8523,-32768,-32768,-32768,
+-32768,-32768,-32768,-32768, 278,-32768, 1016, 1020, 630, 270,
+ 1062, 10037,-32768, 1073,-32768,-32768, 1031, 2198, 1102, 71,
+ 1079, 1083,-32768,-32768, 2306, 6133, 2306, 2152, 1137, 4350,
+-32768, 1094,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
+ 1046, 1054,-32768, 1107,-32768,-32768, 344,-32768,-32768,-32768,
+-32768, 104, 1493, 1101, 991,-32768,-32768,-32768,-32768, 7429,
+ 11097,-32768, 879, 1064, 11052,-32768,-32768, 1067,-32768, 1089,
+ 93, 3406, 1095,-32768, 571, 5919, 1140, 1145, 649,-32768,
+-32768,-32768, 4742, 4742,-32768, 5849,-32768, 1157,-32768,-32768,
+ 1111, 240,-32768, 2251,-32768,-32768, 456, 1109,-32768, 2385,
+-32768, 7162, 11097,-32768, 5202,-32768, 456, 456,-32768,-32768,
+-32768,-32768,-32768, 7162, 174, 966, 10209, 981,-32768, 1166,
+-32768,-32768,-32768, 485, 580, 906, 1265, 587, 219, 1177,
+-32768, 676, 1161, 456, 8768,-32768,-32768,-32768, 456,-32768,
+ 240, 7162, 10037, 10037,-32768, 10037, 240, 7162,-32768,-32768,
+-32768,-32768,-32768,-32768, 1688, 1688, 1688, 65, 1136, 1143,
+ 9688, 1043, 1147, 1149, 1152, 1170, 2853, 1186, 1189, 1190,
+-32768, 1167,-32768,-32768, 1168,-32768,-32768, 1211, 996, 1060,
+ 557, 601, 10209, 1217,-32768, 1232, 1191, 11097, 11097,-32768,
+-32768, 1235, 5746, 6217, 6158, 4780, 2387, 5364, 4442, 2354,
+ 2354, 2354, 1205, 1205, 1512, 1512, 1028, 1028, 1028,-32768,
+-32768, 1192, 1194, 1183, 10209, 10123,-32768, 651,-32768, 8091,
+ 10209,-32768,-32768,-32768, 10209,-32768,-32768, 1204, 10903, 1199,
+ 1215, 1231, 1264,-32768, 10209,-32768, 10209,-32768, 10209, 2925,
+-32768, 2925,-32768, 228, 1216, 1218,-32768, 1214, 4970, 240,
+-32768, 240, 3053,-32768, 7162, 1219, 9504, 9504, 6451, 1220,
+ 10295, 1221, 876, 2159, 1998, 1368, 1224,-32768,-32768,-32768,
+-32768,-32768,-32768,-32768, 10209, 1357, 1225, 1034,-32768, 11097,
+-32768, 11097, 1966, 1227, 10559,-32768, 1233, 1253,-32768, 65,
+-32768,-32768,-32768,-32768,-32768, 1852, 6834,-32768, 4970, 10037,
+ 1202, 1202, 4282,-32768,-32768,-32768,-32768, 1679,-32768,-32768,
+-32768, 1188, 10209,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
+-32768,-32768, 344,-32768, 550, 474, 541,-32768, 767, 554,
+ 10209, 1285,-32768, 672, 564, 702, 706, 1806, 991,-32768,
+ 96,-32768, 171,-32768,-32768,-32768,-32768,-32768,-32768, 9412,
+-32768,-32768,-32768,-32768,-32768,-32768,-32768, 1145, 1283,-32768,
+-32768,-32768, 4970,-32768,-32768,-32768, 1284,-32768,-32768, 1257,
+-32768, 1294,-32768,-32768, 298,-32768,-32768, 240, 1249,-32768,
+ 1305, 1305, 240, 1262, 10209, 10209, 7076, 456, 4960, 456,
+ 456, 1524, 456, 6356,-32768,-32768, 8838, 1305,-32768, 1266,
+ 65, 65, 65,-32768, 1267, 240, 7162, 240, 7162,-32768,
+-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, 1289, 1290,
+ 1291, 1293, 1046,-32768, 10985, 8091, 7724, 1280,-32768, 10209,
+-32768,-32768,-32768, 1281, 1287, 1295, 4970,-32768,-32768, 1298,
+ 569, 1012, 1012, 1296, 1012,-32768,-32768, 10903, 1384, 10037,
+-32768, 1309, 1313, 1319,-32768,-32768,-32768,-32768,-32768,-32768,
+-32768,-32768, 240, 1326,-32768, 1325,-32768,-32768, 2768,-32768,
+-32768,-32768,-32768,-32768, 11097,-32768,-32768, 1292,-32768,-32768,
+ 292, 1330,-32768,-32768,-32768,-32768,-32768,-32768,-32768, 2497,
+ 2497, 2557, 2557, 4282,-32768, 1679,-32768, 3088, 11119,-32768,
+-32768,-32768, 1331,-32768, 1493,-32768, 10209,-32768, 10209,-32768,
+ 10209,-32768, 1357,-32768,-32768, 7026, 1413,-32768, 7815,-32768,
+ 9596, 9596, 7226, 173, 1339, 209,-32768, 8091, 7906,-32768,
+-32768, 311, 8091,-32768,-32768,-32768, 10123,-32768,-32768,-32768,
+-32768, 1848,-32768,-32768,-32768,-32768,-32768,-32768, 7076, 7076,
+-32768, 1305, 585, 1127, 10209,-32768,-32768,-32768, 981, 981,
+ 1305, 1305, 847, 1305,-32768,-32768,-32768,-32768,-32768, 1395,
+-32768,-32768,-32768, 1342,-32768, 1346, 10209, 10209, 10209, 10209,
+ 8091,-32768, 1393,-32768,-32768, 11097,-32768,-32768,-32768, 60,
+ 1295,-32768,-32768,-32768,-32768,-32768,-32768, 1348,-32768, 1421,
+ 65,-32768,-32768,-32768, 240,-32768,-32768,-32768,-32768,-32768,
+-32768, 10209,-32768,-32768, 2497, 2497,-32768, 3088,-32768,-32768,
+ 1352, 1362, 1363, 1380,-32768, 1036, 321, 1407, 1164, 1165,
+-32768,-32768,-32768,-32768,-32768, 10209, 1416, 1419, 1425, 9774,
+ 653, 1357, 496, 693,-32768,-32768, 9865, 1477,-32768,-32768,
+-32768, 1430,-32768, 6551, 6039, 4418, 6895,-32768,-32768, 1475,
+-32768,-32768,-32768, 8931,-32768,-32768, 1386, 1373,-32768,-32768,
+-32768,-32768, 4970,-32768,-32768, 8091, 1391, 1399, 2385,-32768,
+-32768,-32768, 240, 240,-32768,-32768,-32768, 10209, 10209, 7076,
+ 456, 456,-32768,-32768,-32768, 6712, 240, 240,-32768,-32768,
+ 1400, 1401, 1405, 1410,-32768, 8091, 10209,-32768, 60,-32768,
+-32768,-32768,-32768, 240, 1415,-32768,-32768,-32768,-32768, 1380,
+-32768, 1357,-32768,-32768,-32768,-32768,-32768,-32768, 711, 711,
+ 991, 1432, 1433, 6200,-32768,-32768,-32768,-32768, 1467, 10209,
+ 1472, 1428, 1480, 1927, 1987,-32768, 991,-32768,-32768, 1451,
+-32768,-32768, 981, 1061,-32768, 1076, 981, 9951, 1090, 322,
+-32768,-32768,-32768,-32768,-32768,-32768, 364,-32768,-32768,-32768,
+-32768,-32768,-32768,-32768, 7076, 7076,-32768, 1305, 1305,-32768,
+ 8614,-32768,-32768,-32768,-32768, 240, 240,-32768,-32768,-32768,
+-32768,-32768, 1434,-32768,-32768,-32768, 1459,-32768,-32768,-32768,
+ 10123,-32768,-32768,-32768, 1538, 9227, 7336, 10123, 10209,-32768,
+ 9039,-32768, 1496,-32768,-32768, 1504,-32768, 1480, 1927,-32768,
+-32768, 700,-32768,-32768, 10645, 10645, 8000,-32768,-32768, 991,
+-32768,-32768,-32768,-32768, 1452, 11007, 1463,-32768,-32768,-32768,
+ 10990,-32768,-32768, 1455, 398, 6652, 991, 9133,-32768,-32768,
+ 96,-32768,-32768, 1507, 1460, 11075, 9039,-32768,-32768,-32768,
+-32768, 1380, 76,-32768,-32768,-32768,-32768, 443, 344, 1462,
+ 1466, 991,-32768, 981,-32768,-32768,-32768,-32768, 714,-32768,
+ 8182,-32768,-32768,-32768,-32768, 1380, 1566, 1522, 177,-32768,
+-32768,-32768,-32768, 456, 96,-32768, 10209, 1523,-32768, 1529,
+-32768, 991, 9039, 1491, 63, 1531,-32768,-32768,-32768, 165,
+-32768, 1534,-32768, 1494,-32768,-32768,-32768,-32768, 10209, 1566,
+ 1539, 1566,-32768,-32768,-32768, 8273, 1500, 572,-32768,-32768,
+ 8091, 1501,-32768, 1577, 1553,-32768,-32768,-32768, 332,-32768,
+ 9133, 1603, 1559,-32768,-32768,-32768, 1621, 1622,-32768
};
static const short yypgoto[] = {-32768,
- 1586,-32768, -336, 1421, -382, 70, 6, 1573,-32768, 1554,
--32768,-32768, 266,-32768, 277,-32768, 396,-32768, 195, 937,
- 52, 14,-32768,-32768, -628,-32768,-32768, 661, 53, 1426,
- 1179, 1439, -685, 77, -162, 13, 139,-32768,-32768,-32768,
--32768,-32768, 835,-32768,-32768,-32768,-32768,-32768,-32768, 456,
- 1536,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
--32768,-32768, 1518, -616, 5440, -68, -498, -295, 26, 1478,
- -508,-32768, -43,-32768, 245,-32768, -1359,-32768, -1380, 27,
--32768, 1476, 1201, -274, 405, -542,-32768, -817, 4764, 1360,
- 1170, 3522, 1349, -326, -85, -94, 105, -71, -27,-32768,
--32768,-32768, -327,-32768, -156,-32768,-32768, -1216, 68, -343,
- 4423, 107, 1101, -118, 19, 102, -200, -4, -138, -160,
- -169, 20, -42, -245,-32768, -342,-32768,-32768,-32768,-32768,
--32768, -5, 1809, -17,-32768, 724,-32768,-32768, -988, -428,
- 941,-32768,-32768,-32768,-32768,-32768, 168,-32768,-32768,-32768,
--32768,-32768, 733, -362,-32768,-32768,-32768,-32768,-32768,-32768,
--32768, 1416,-32768, 465, 645,-32768,-32768,-32768,-32768,-32768,
- 881, -684,-32768,-32768,-32768,-32768,-32768,-32768, 885,-32768,
- 460, 1022, 752, 1083, 4670, 47, 25, -441, 1474, 2689,
- -454,-32768, 18,-32768, 5069, -134, 156, -82, 4079, 1334,
--32768, 4154, 1775, 1562, -16, -107,-32768, 1555, -58,-32768,
- 4257, 2711, -195,-32768, 2673,-32768,-32768, 381,-32768,-32768,
- 516, 115, -427,-32768,-32768,-32768,-32768, -1353,-32768, -1239,
- -1387,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
--32768,-32768,-32768,-32768,-32768, 137,-32768,-32768,-32768,-32768,
--32768, 176, -1300,-32768,-32768, -54,-32768,-32768,-32768,-32768,
- -1367, 116,-32768, 123,-32768, -698, -581, 704,-32768,-32768,
--32768,-32768, -383,-32768, -376, -175,-32768, 1675, 393,-32768,
- 232,-32768, -226
+ 1624,-32768, -304, 1456, -364, 75, 2, 1623,-32768, 1593,
+-32768,-32768, 315,-32768, 373,-32768, 507,-32768, 206, 942,
+ 58, 24,-32768,-32768, -669,-32768,-32768, 657, 59, 1469,
+ 1197, 1478, -719, 111, -173, 29, 55,-32768,-32768,-32768,
+-32768,-32768, 1125,-32768,-32768,-32768,-32768,-32768,-32768, 466,
+ 1903,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
+-32768,-32768, 1568, -526, 6178, 1422, -58, -599, -235, -44,
+ 1533, -547,-32768, 388,-32768, 260,-32768, -1362,-32768, -1307,
+ 52,-32768, 1442, 1361, -254, 403, -557,-32768, -868, 3479,
+ -125, 1528, 4472, 1379, -332, -52, -76, 427, -140, -66,
+ 135,-32768,-32768,-32768, -344,-32768, -159,-32768,-32768, -1236,
+ -16, -329, 1934, 530, -150, -166, 78, 50, -206, -4,
+ -145, -165, -171, 32, -11, 357,-32768, -257,-32768,-32768,
+-32768,-32768,-32768, 734, 1247, -45,-32768, 716,-32768,-32768,
+ -765, -399, 940,-32768,-32768,-32768,-32768,-32768, 218,-32768,
+-32768,-32768,-32768,-32768, 729, -377,-32768,-32768,-32768,-32768,
+-32768,-32768,-32768,-32768, 1447,-32768, 335, 473,-32768,-32768,
+-32768,-32768, 885, -479,-32768,-32768,-32768,-32768,-32768,-32768,
+ 1172,-32768, 624, 1030, 745, 1086, 2837, 14, 54, -461,
+ 1510, 2756, -686,-32768, 13,-32768, 645, 20, -142, 271,
+ -105, 5046, 1365,-32768, 5682, 2642, 1651, -19, -113,-32768,
+ 1590, -54,-32768, 5135, 3513, -359,-32768, 1597,-32768,-32768,
+ 381,-32768,-32768, 527, 138, -429,-32768,-32768,-32768,-32768,
+ -1369,-32768, -1238, -1389,-32768,-32768,-32768,-32768,-32768,-32768,
+-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, 156,-32768,
+-32768,-32768,-32768,-32768, 188, -1311,-32768,-32768, -51,-32768,
+-32768,-32768,-32768, -1385, 140,-32768, 144,-32768, -606, -580,
+ 710,-32768,-32768,-32768,-32768, -393,-32768, -390, -333,-32768,
+ 1007, 397,-32768, 83,-32768, -232
};
-#define YYLAST 11066
+#define YYLAST 11203
static const short yytable[] = { 59,
- 423, 617, 433, 178, 475, 152, 122, 431, 252, 36,
- 432, 249, 415, 418, 680, 706, 974, 42, 388, 710,
- 501, 681, 57, 627, 626, 523, 526, 887, 739, 294,
- 59, 103, 657, 245, 887, 678, 757, 59, 394, 395,
- 36, 1088, 494, 818, 220, 695, 857, 393, 42, 951,
- 72, 396, 205, 57, 170, 42, 631, 632, 556, 1413,
- 172, 173, 491, 362, 366, 387, 1416, 243, 957, 1451,
- 252, 1506, 1398, 35, 480, 483, 140, 144, 186, 292,
- 1013, 72, 1015, 345, 1050, 345, 474, 345, 72, 1042,
- 1055, 513, 1510, 166, 167, 482, 579, 778, 440, 595,
- 256, 1511, 345, 345, 35, 58, 595, 595, 686, 687,
- 55, 165, 455, 159, 982, 352, 1538, 353, 816, 152,
- 152, 152, 192, 360, 630, 1163, 1540, 252, -1, 1520,
- 293, 402, 345, 909, 345, 744, 58, 151, 138, 504,
- 502, 55, 580, 58, 513, 703, -144, -2, 171, 1535,
- 1547, 86, 781, 160, 401, -352, 59, -291, 456, 441,
- 59, 983, 404, 152, 984, 987, 478, 205, 889, 779,
- 1569, 94, 437, 428, 1573, 1169, 186, 170, 42, 57,
- 803, 1561, 72, 172, 173, 291, 503, 958, 154, 508,
- 220, 727, 442, 414, 417, 204, 1548, 1114, 220, 923,
- 87, 1164, 704, 692, 963, 1324, 1325, 72, 1577, 174,
- 817, 72, 988, 1538, 220, 989, 166, 167, 1592, 1345,
- 186, -361, 737, 15, 1514, 1170, 217, -352, 577, 578,
- 743, 441, 8, 506, 165, 458, 460, 58, 192, 95,
- 110, 111, 400, 1508, 88, 1451, 972, 601, 924, -362,
- 1043, 15, 416, 419, -361, 549, 600, 550, -361, 211,
- 212, 256, 58, 496, 442, 14, 58, 55, 1254, 38,
- 91, 171, 93, 1545, 399, 975, 359, 8, 9, 700,
- 39, 543, -362, 592, 130, 131, -362, 20, 243, 135,
- 92, -361, 112, 113, 1121, 151, 23, 1124, 605, 1044,
- 38, 627, 154, 154, 154, 936, 665, 1136, 507, 497,
- 204, 39, 1192, 961, 962, 1087, 1390, 1255, 887, -362,
- 345, 927, 660, 1578, 1197, 89, 1315, 415, 418, 130,
- 131, -298, 174, 292, 1374, 480, 483, 910, 1150, 1151,
- 680, 243, 1424, 480, 802, 90, 154, 993, 1374, 345,
- 636, 1430, 1431, 1602, 1432, 483, 742, -120, 1216, 15,
- 1218, 887, 107, 1042, 964, 747, 748, 1018, 256, 127,
- 128, 501, 217, 401, 483, 1316, 617, -298, -298, 633,
- 217, 217, 1007, 1375, 293, 235, -143, 218, 219, 236,
- -120, 15, -291, 677, -120, -411, 205, 1482, 137, 40,
- 1019, 72, 1603, 887, 1020, 127, 128, 605, 965, 714,
- 217, 668, 1008, 359, 1358, 26, 579, 966, 967, -619,
- 220, 130, 131, 771, -411, 59, 622, -120, -411, 545,
- 40, 1139, 1089, 790, 152, 152, 152, 1021, 792, 291,
- 91, 745, 697, -300, 679, 507, 605, 108, 172, 173,
- -579, 720, 109, 802, 968, 1116, 58, 130, 131, 217,
- 92, 635, 580, 220, 129, -619, -619, 683, 1235, 127,
- 128, 91, 623, -411, 26, 89, 72, 1393, 543, 791,
- -619, 543, 137, -141, 793, 805, -118, 59, 15, -300,
- -300, 92, 802, 634, 875, 90, -579, 185, 543, 676,
- 1523, 1524, 679, 1063, -294, 1251, 1252, 157, 731, 732,
- 773, 543, 217, 359, 345, 832, 158, 345, 175, -118,
- 345, 130, 131, -118, 345, 808, 808, 808, 808, 127,
- 128, 58, 960, 179, 504, 592, 171, 345, 72, 937,
- 876, 1447, 860, 855, 799, 248, 1162, 345, 877, 871,
- 345, 183, 138, 680, 757, 938, -118, 676, 184, 861,
- 681, 765, 887, 210, 211, 212, 879, 416, 419, 217,
- 14, 932, 139, 1003, 678, 1005, 665, 627, 626, 26,
- 1009, 130, 131, 933, 1198, 292, -579, 18, 862, 1357,
- 18, 887, 20, 58, 878, 514, 88, 174, 772, 304,
- 91, 23, 373, 480, 677, 515, 15, 513, -142, 238,
- -411, 720, 880, 127, 128, 26, 684, 154, 154, 154,
- 92, 895, 90, 997, 240, -300, 545, 556, 295, 545,
- 768, 138, -579, 470, 1135, 982, 293, 256, -411, -411,
- -300, 217, 217, -411, -300, 416, 813, 1224, 1226, 217,
- 122, 388, 881, 883, 1240, 679, 345, 358, 370, 545,
- -300, 217, 679, 26, 371, 130, 131, 896, 897, 998,
- 205, 356, -300, -300, 243, -300, 1022, -300, 630, 864,
- 217, 1010, 983, 1156, 973, 984, 930, -822, 91, 865,
- 1158, 291, 296, 390, 391, 10, 771, 1396, 771, 368,
- 972, 372, 912, 866, 771, 771, -300, -300, 92, 137,
- 676, 771, 1425, 1160, 8, 9, 376, 676, 374, 677,
- 903, -300, 1023, 377, 88, 1016, 1017, 1011, 1453, 1157,
- 21, 397, 757, 375, 1045, 447, 1159, 247, 92, 1002,
- 1226, 944, 185, 949, 950, 27, 315, 803, -291, 1311,
- 1313, 1556, 448, 137, 1317, 1211, 1212, 1213, 359, 1161,
- 59, 420, 59, 8, 9, 421, 130, 131, 205, 59,
- 679, 127, 128, 1047, 1454, 59, 504, 32, 677, 345,
- 345, 449, 345, 773, 677, 773, -614, 950, 127, 128,
- 248, 299, 773, -7, 1355, 218, 434, 1557, 773, 1152,
- 95, 96, 97, 217, 221, 222, 223, 359, 435, 1051,
- 1052, 72, 1053, 72, 1580, 130, 131, 127, 128, 160,
- 72, 26, 1094, 130, 131, 676, 72, 436, 18, 679,
- 1187, 1188, 1189, 224, 765, 679, 765, 864, 26, 1028,
- 130, 131, 860, 765, 217, 439, 452, 865, 1594, 765,
- 451, 26, 345, 98, 99, 225, 543, 1091, 509, 861,
- 1581, 866, 510, 1570, 8, 9, 58, 26, 58, 130,
- 131, 772, 511, 1014, 512, 58, 252, 116, 747, 748,
- 772, 58, 520, 514, 676, 808, 772, 217, 862, 1419,
- 676, 677, 529, 515, 1595, 720, 1236, 1237, 530, 1239,
- 226, 227, 228, 768, 750, 768, 903, 531, 359, 217,
- 1027, 1037, 768, 468, 469, 152, 130, 131, 768, 95,
- 96, 97, 256, 552, 127, 1342, 532, 1445, 26, 15,
- 119, 120, 677, -411, 808, 345, 476, 477, 677, 549,
- 507, 550, 679, 533, 881, 883, 679, 1362, 468, 698,
- 668, 89, 552, 1457, 803, 476, 699, 152, 595, 1199,
- 1185, -411, -411, 252, -575, 641, 249, -575, 359, 1474,
- 26, 90, 98, 99, 100, 217, 130, 131, 644, 771,
- 720, 1372, 1373, 679, 1201, 468, 1476, 1140, 1141, 679,
- 1203, 1204, 645, 808, 1201, 1206, 647, 676, 1204, 345,
- 507, 676, 892, 416, 813, 661, 677, 415, 418, 648,
- 1194, 1195, 476, 1477, -575, 649, -575, -575, 677, -575,
- 127, 128, 662, 7, 8, 246, 10, 1060, 1061, 1062,
- -575, 679, -575, 89, 211, 212, 415, 418, 676, 1208,
- 14, 1377, 690, 59, 676, 468, 1481, 151, -575, -575,
- 90, -52, 677, 90, 677, 1457, -52, 679, 92, -6,
- 129, 21, 20, -575, 784, 693, 773, -52, 247, 679,
- 26, 23, 130, 131, 252, 1457, 27, 28, 95, 110,
- 111, 1028, 808, 715, 738, 733, 676, 15, 785, 1175,
- 786, 91, 787, 794, 72, 345, 795, 812, 154, 1378,
- 248, 89, 814, 679, 1553, 679, 815, 704, 32, 1426,
- 817, 92, 676, 680, 152, 152, 152, 765, 872, 874,
- 1531, 90, 888, 890, 676, 1243, 892, 1406, 916, 543,
- 915, 112, 113, 114, 1457, 1404, 508, 1409, 973, 677,
- 154, 925, 706, 152, 152, 152, 929, 926, -181, 58,
- 931, 20, 1027, -294, 772, 939, 959, 803, 676, 940,
- 676, 1298, 1596, 137, -181, 953, -181, 441, 720, 979,
- 980, 1290, -821, 981, 995, 1351, 1352, 1353, 1354, 986,
- 127, 128, 999, 1000, 1297, 13, 768, 1004, 1257, 1258,
- 679, 1006, 1046, 1064, 1330, 1331, 1065, 1340, 1341, 1069,
- 1343, 1024, 1025, 9, 10, 1066, 1067, 1068, 1070, 95,
- 110, 111, 72, 221, 222, 223, 1071, 1257, 1258, 679,
- 1072, 1073, 1074, 605, -140, 1076, 95, 110, 111, 498,
- 26, 1077, 130, 131, 1079, 1289, 1080, 18, 1389, 21,
- 1083, 1096, 224, 1081, 1082, 676, 606, 416, 419, 116,
- 117, 118, 26, 1098, 27, 28, 607, 335, 1193, 335,
- 1026, 335, 112, 113, 21, 1099, 608, 58, 189, 609,
- 610, 1100, 1101, 1107, 676, 1108, 416, 1309, 190, 112,
- 113, 1109, 1115, 1117, 1298, 1155, 32, 116, 117, 118,
- 1118, 191, 205, 1120, 1298, 1428, 1429, 154, 154, 154,
- 513, 1298, 119, 120, 1290, 1127, 335, 1297, 335, 1130,
- 808, 1290, 1133, 1446, 1134, 1178, 1184, 1297, 1519, 127,
- 128, 1202, 1422, 1423, 1297, 1207, 154, 154, 154, 1210,
- 378, 379, 380, 1219, 1220, 72, 1214, 1221, 26, 1227,
- 119, 120, 1222, 415, 418, 72, 1466, 1229, 7, 8,
- 9, 10, 72, 1230, 13, 1231, 1234, 1242, 1289, 378,
- 379, 380, 605, 1403, 478, 1403, 1550, 1238, 1289, 26,
- 1250, 130, 131, 1244, 1163, 1289, 7, 8, 9, 10,
- 152, 26, 242, 382, 383, 606, 21, 1245, 1246, 1249,
- 58, 1253, 605, 1256, 1261, 607, 1310, 1319, 1320, 26,
- 58, 27, 28, 1323, 381, 608, 448, 58, 609, 610,
- 1499, 1327, 382, 383, 21, 941, 832, 1499, -656, 1349,
- 605, 1488, 1489, 1490, 1350, 942, 1361, 26, 1356, 27,
- 28, 1360, 1366, 32, 1367, 608, 543, 1368, 943, 610,
- 95, 110, 111, 941, 650, 651, 652, 1369, 1376, 1501,
- 152, 152, 152, 942, 1298, 1298, 1501, 1385, 1386, 1298,
- 1387, 32, 1399, 608, 1290, 217, 943, 610, 1401, 1290,
- 574, 575, 576, 577, 578, 345, 1414, 1297, 1297, 1417,
- 1521, 1522, 1297, 1441, 1442, 534, 1443, 95, 96, 97,
- 1444, 1554, 677, 112, 113, 1449, 1460, 1499, 674, 1298,
- 293, 1465, 1461, 1467, 371, 72, 72, 293, 1298, 1290,
- 72, 1468, 1175, 1574, 1475, 1496, 1497, 1505, 1290, 1515,
- 1516, 1525, 1297, 335, 731, 732, 1527, 1533, 1289, 1289,
- 1542, 1297, 359, 1289, 1543, 1587, 1501, 1564, 1551, 1552,
- 98, 99, 832, 679, 1579, 1568, 1575, 1576, 1572, 101,
- 72, 1582, 1584, 1585, 1589, 291, 674, 115, 1298, 72,
- 58, 58, 291, 154, 1593, 58, 1597, 1598, 1290, 1534,
- 1600, 1605, 1606, 1289, 5, 1608, 1609, 624, 8, 9,
- 10, 1297, 1289, 416, 1309, 1, 430, 293, 156, 1472,
- 429, 296, 8, 9, 10, 928, 1298, 1137, 676, 427,
- 229, 95, 409, 410, 1549, 58, 1290, 1038, 696, 72,
- 1262, 355, 304, 625, 58, 21, 405, 709, 713, 1297,
- 7, 127, 128, 10, 1456, 713, 13, 1604, 26, 21,
- 130, 131, 1289, 154, 154, 154, 247, 1359, 95, 96,
- 97, 254, 291, 519, 27, 315, 1129, 72, 978, 712,
- 1128, 1321, 490, 1190, 98, 113, 718, 1040, 21, 384,
- 1048, 527, 528, 918, 58, 254, 1344, 1126, 217, 471,
- 1289, 26, 859, 27, 28, 602, 32, 536, 386, 1412,
- 537, 411, 1307, 538, 1583, 1571, 548, 30, 335, 713,
- 553, 98, 99, 1546, 254, 1588, 1177, 31, 594, 95,
- 110, 111, 58, 254, 1590, 32, 0, 1418, 0, 674,
- 33, 0, 7, 8, 9, 10, 674, 0, 13, 0,
- 800, 335, 0, 709, 0, 0, 829, 830, 0, 834,
- 835, 836, 837, 838, 839, 840, 841, 842, 843, 844,
- 845, 846, 847, 848, 849, 850, 851, 852, 0, 713,
- 21, 0, 112, 113, 0, 713, 605, 116, 747, 748,
- 254, 749, 0, 26, 0, 27, 28, 0, 486, 488,
- 0, 0, 116, 747, 748, 0, 0, 0, 80, 1142,
- 853, 0, 499, 0, 750, 713, 854, 0, 104, 1143,
- 0, 751, 713, 0, 254, 127, 128, 32, 133, 608,
- 242, 0, 1144, 610, 142, 142, 0, 142, 26, 80,
- 119, 120, 0, 0, 920, 922, 80, 0, 0, 254,
- 0, 0, 0, 907, 674, 119, 120, 0, 0, 199,
- 335, 80, 0, 0, 296, 127, 128, 10, 605, 233,
- 0, 0, 95, 110, 111, 26, 104, 130, 131, 0,
- 0, 0, 535, 7, 8, 9, 10, 258, 104, 504,
- 0, 606, 0, 0, 0, 208, 0, 216, 0, 0,
- 0, 607, 21, 232, 95, 110, 111, 709, 0, 247,
- 104, 608, 0, 674, 609, 610, 0, 27, 315, 674,
- 0, 21, 0, 0, 643, 112, 1469, 605, 0, 536,
- 537, 0, 0, 653, 26, 0, 27, 28, 133, 0,
- 80, 254, 0, 0, 142, 0, 643, 407, 142, 32,
- 941, 142, 142, 142, 711, 0, 0, 112, 1471, 0,
- 942, 711, 0, 1012, 0, 80, 0, 0, 32, 80,
- 608, 0, 0, 943, 610, 199, 80, 0, 0, 0,
- 0, 0, 0, 335, 335, 0, 335, 0, 581, 0,
- 0, 0, 0, 199, 199, 199, 0, 0, 254, 0,
- 0, 713, 0, 0, 296, 390, 391, 10, 0, 0,
- 208, 7, 8, 9, 10, 0, 438, 0, 0, 0,
- 0, 0, 199, 1075, 0, 711, 674, 582, 583, 0,
- 674, 0, 584, 585, 586, 587, 0, 0, 489, 0,
- 0, 0, 21, 216, 0, 0, 0, 0, 104, 21,
- 0, 481, 216, 0, 746, 713, 713, 27, 315, 142,
- 709, 713, 26, 0, 27, 28, 0, 674, 188, 0,
- 0, 0, 0, 674, 0, 713, 0, 713, 189, 713,
- 254, 0, 0, 0, 0, 711, 1084, 1085, 190, 32,
- 0, 711, 1090, 0, 0, 0, 32, 104, 516, 0,
- 0, 191, 0, 0, 0, 0, 1102, 254, 1103, 0,
- 1104, 0, 0, 0, 1125, 674, 210, 211, 212, 825,
- 0, 711, 0, 14, 713, 127, 128, 0, 711, 0,
- 504, 0, 7, 8, 9, 10, 210, 211, 212, 335,
- 18, 674, 104, 14, 0, 20, 603, 0, 516, 516,
- 619, 0, 1149, 674, 23, 1132, 0, 0, 0, 80,
- 18, 0, 0, 873, 0, 20, 0, 713, 605, 913,
- 21, 0, 0, 0, 23, 26, 605, 130, 131, 0,
- 0, 0, 0, 26, 713, 27, 28, 674, 0, 674,
- 0, 606, 0, 133, 254, 0, 0, 0, 1153, 941,
- 0, 607, 104, 0, 199, 104, 0, 0, 0, 942,
- 254, 608, 0, 0, 609, 610, 0, 32, 142, 608,
- 0, 142, 943, 610, 0, 1200, 142, 0, 0, 0,
- 0, 0, 935, 0, 80, 0, 0, 0, 0, 208,
- 216, 0, 596, 952, 296, 390, 391, 10, 0, 597,
- 0, 0, 0, 0, 0, 7, 127, 128, 10, 1097,
- 0, 242, 199, 0, 199, 0, 199, 199, 199, 0,
- 0, 0, 199, 825, 674, 709, 709, 199, 0, 1228,
- 199, 0, 21, 0, 0, 0, 0, 536, 537, 598,
- 0, 0, 0, 21, 0, 26, 80, 27, 315, 335,
- 0, 0, 0, 674, 0, 438, 26, 711, 27, 28,
- 0, 0, 481, 216, 0, 0, 438, 210, 211, 212,
- 481, 0, 30, 0, 14, 0, 0, 0, 0, 599,
- 0, 0, 31, 438, 104, 104, 104, 104, 0, 0,
- 32, 18, 0, 0, 0, 33, 20, 0, 7, 127,
- 128, 10, 0, 0, 13, 23, 713, 0, 713, 0,
- 713, 711, 711, 0, 0, 0, 0, 711, 709, 572,
- 573, 574, 575, 576, 577, 578, 0, 709, 709, 0,
- 0, 711, 709, 711, 0, 711, 21, 1263, 0, 1264,
- 0, 1265, 0, 0, 104, 0, 516, 1328, 1329, 26,
- 0, 27, 28, 0, 0, 479, 211, 212, 603, 0,
- 516, 516, 14, 619, 0, 147, 0, 0, 0, 0,
- 904, 0, 709, 0, 906, 148, 0, 0, 0, 18,
- 711, 0, 0, 32, 20, 0, 0, 0, 149, 199,
- 0, 0, 0, 23, 1001, 0, 0, 0, 0, 0,
- 0, 0, 0, 713, 0, 7, 8, 9, 10, 0,
- 0, 0, 0, 133, 0, 0, 7, 127, 128, 10,
- 133, 0, 0, 711, 216, 0, 0, 1384, 199, 948,
- 199, 199, 233, 619, 1365, 0, 1049, 1241, 653, 0,
- 711, 0, 1054, 21, 0, 254, 0, 254, 0, 605,
- 0, 935, 0, 0, 21, 0, 26, 0, 27, 28,
- 0, 247, 0, 208, 0, 216, 232, 709, 0, 27,
- 28, 0, 941, 0, 199, 0, 0, 0, 948, 0,
- 0, 0, 942, 1427, 0, 199, 199, 0, 199, 254,
- 32, 0, 608, 248, 0, 943, 610, 0, 0, 0,
- 0, 32, 0, 0, 0, 709, 0, 0, 216, 0,
- 536, 537, 0, 0, 0, 0, 133, 0, 0, 80,
- 0, 80, 0, 0, 0, 0, 1035, 80, 80, 0,
- 481, 0, 0, 438, 80, 0, 0, 104, 0, 0,
- 0, 0, 0, 104, 0, 1110, 0, 1111, 0, 0,
- 516, 516, 516, 0, 0, 0, 0, 713, 0, 0,
- 0, 208, 516, 0, 0, 0, 0, 438, 0, 0,
- 0, 0, 0, 0, 1486, 1487, 254, 674, 0, 0,
- 0, 8, 9, 1492, 163, 12, 13, 0, 0, 717,
- 0, 14, 1225, 567, 568, 569, 570, 571, 572, 573,
- 574, 575, 576, 577, 578, 16, 0, 17, 18, 0,
- 0, 1512, 711, 20, 711, 0, 711, 0, 0, 0,
- 0, 0, 23, 0, 605, 0, 0, 0, 548, 0,
- 0, 26, 0, 130, 131, 516, 0, 516, 0, 0,
- 0, 0, 0, 0, 104, 0, 0, 606, 516, 0,
- 104, 0, 904, 904, 904, 0, 0, 607, 0, 1119,
- 254, 0, 0, 0, 0, 0, 0, 608, 0, 0,
- 609, 610, 0, 7, 8, 9, 10, 0, 1267, 0,
- 0, 0, 0, 0, 1225, 0, 0, 254, 0, 0,
- 0, 104, 0, 104, 83, 199, 199, 1146, 0, 0,
- 0, 0, 0, 0, 106, 0, 0, 0, 0, 711,
- 1215, 21, 1217, 126, 134, 0, 0, 0, 247, 0,
- 143, 143, 0, 143, 232, 83, 27, 28, 0, 0,
- 0, 0, 83, 0, 0, 296, 8, 9, 10, 1146,
- 709, 0, 0, 0, 0, 143, 254, 83, 0, 0,
- 248, 0, 104, 0, 0, 234, 0, 0, 32, 0,
- 0, 0, 244, 0, 0, 104, 0, 1248, 1035, 0,
- 0, 0, 0, 21, 244, 0, 0, 104, 0, 0,
- 247, 0, 0, 0, 0, 0, 0, 0, 27, 315,
- 1205, 0, 0, 0, 0, 0, 0, 0, 1391, 1392,
- 0, 0, 80, 0, 438, 438, 0, 0, 0, 0,
- 0, 104, 248, 104, 0, 0, 0, 536, 537, 0,
- 32, 0, 7, 8, 9, 10, 83, 0, 13, 0,
- 143, 0, 0, 438, 143, 0, 0, 143, 143, 143,
- 0, 104, 0, 0, 0, 1322, 516, 516, 0, 516,
- 1326, 83, 0, 0, 0, 83, 0, 459, 461, 465,
- 21, 143, 83, 711, 0, 7, 127, 128, 10, 0,
- 0, 504, 0, 26, 0, 27, 28, 0, 0, 143,
- 143, 143, 0, 296, 8, 9, 10, 1452, 0, 189,
- 0, 0, 0, 0, 199, 199, 199, 199, 1146, 190,
- 0, 1363, 199, 21, 0, 0, 0, 32, 143, 1470,
- 1473, 0, 191, 0, 0, 0, 26, 0, 27, 28,
- 0, 21, 0, 0, 0, 1146, 1146, 1146, 247, 0,
- 0, 0, 30, 0, 0, 0, 27, 315, 0, 0,
- 0, 0, 31, 0, 0, 143, 0, 0, 0, 0,
- 32, 0, 0, 0, 0, 33, 199, 0, 0, 0,
- 507, 142, 0, 0, 0, 0, 0, 0, 32, 0,
- 0, 7, 8, 9, 10, 210, 211, 212, 0, 0,
- 0, 0, 14, 244, 143, 0, 0, 1517, 438, 438,
- 0, 438, 438, 0, 438, 0, 614, 618, 621, 18,
- 0, 1437, 1438, 0, 20, 0, 0, 0, 0, 21,
- 0, 199, 199, 23, 199, 605, 0, 0, 1448, 0,
- 0, 0, 26, 0, 27, 28, 0, 0, 244, 0,
- 0, 0, 604, 0, 143, 143, 620, 0, 941, 0,
- 0, 629, 0, 0, 0, 83, 0, 0, 942, 0,
- 199, 948, 199, 0, 0, 0, 32, 0, 608, 0,
- 0, 985, 610, 0, 0, 0, 0, 0, 0, 104,
- 0, 0, 0, 0, 1484, 1485, 0, 0, 0, 666,
- 0, 0, 0, 0, 0, 208, 216, 0, 244, 0,
- 143, 244, 0, 1494, 1495, 570, 571, 572, 573, 574,
- 575, 576, 577, 578, 143, 0, 0, 143, 0, 0,
- 0, 0, 143, 0, 0, 0, 438, 438, 0, 0,
- 83, 7, 8, 9, 10, 0, 729, 242, 730, 0,
- 459, 461, 465, 0, 0, 0, 0, 0, 0, 0,
- 0, 741, 296, 390, 391, 10, 0, 0, 143, 0,
- 143, 0, 143, 143, 143, 0, 0, 0, 143, 21,
- 8, 9, 1146, 143, 12, 242, 143, 0, 0, 0,
- 14, 0, 26, 0, 27, 28, 0, 0, 0, 0,
- 21, 759, 83, 0, 16, 0, 17, 0, 189, 0,
- 0, 0, 20, 26, 0, 27, 315, 0, 190, 0,
- 0, 23, 0, 605, 0, 0, 32, 0, 0, 0,
- 26, 191, 130, 131, 0, 438, 438, 438, 0, 0,
- 244, 244, 244, 244, 0, 0, 606, 32, 0, 0,
- 0, 0, 1146, 1146, 1146, 0, 607, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 608, 0, 0, 609,
- 610, 104, 0, 0, 0, 0, 199, 0, 882, 884,
- 7, 8, 9, 10, 163, 12, 13, 0, 8, 9,
- 0, 14, 12, 242, 438, 438, 0, 0, 14, 0,
- 244, 0, 143, 0, 0, 16, 0, 17, 18, 19,
- 0, 0, 16, 20, 17, 0, 143, 143, 21, 620,
- 20, 0, 23, 0, 0, 164, 905, 0, 0, 23,
- 0, 26, 0, 27, 28, 0, 0, 0, 26, 629,
- 130, 131, 0, 0, 0, 143, 946, 30, 614, 618,
- 0, 621, 0, 0, 0, 0, 0, 31, 0, 0,
- 0, 0, 438, 0, 0, 32, 0, 0, 0, 666,
- 33, 0, 0, 0, 0, 34, 0, 126, 0, 0,
- 0, 0, 0, 0, 143, 620, 143, 143, 234, 620,
- 0, 0, 618, 562, 563, 564, 565, 566, 567, 568,
- 569, 570, 571, 572, 573, 574, 575, 576, 577, 578,
- 6, 759, 7, 8, 9, 10, 11, 12, 13, 729,
- 730, 0, 741, 14, 0, 0, 0, 0, 0, 0,
- 143, 0, 0, 0, 620, 0, 0, 16, 0, 17,
- 18, 143, 143, 0, 143, 20, 0, 0, 0, 0,
- 21, 0, 0, 0, 23, 0, 0, 426, 0, 0,
- 1033, 0, 0, 26, 0, 27, 28, 0, 0, 29,
- 0, 0, 134, 0, 0, 83, 0, 83, 0, 30,
- 618, 0, 1036, 83, 83, 0, 0, 0, 0, 31,
- 83, 127, 128, 244, 0, 211, 212, 32, 0, 244,
- 0, 14, 33, 0, 0, 0, 143, 143, 143, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 143, 0,
- 0, 0, 0, 20, 0, 51, 0, 0, 0, 0,
- 0, 0, 23, 0, 605, 1024, 1025, 9, 10, 0,
- 0, 26, 0, 130, 131, 0, 0, 0, 0, 0,
- 0, 51, 51, 1105, 150, 1106, 51, 606, 0, 0,
- 0, 0, 0, 51, 0, 0, 1112, 607, 0, 0,
- 882, 884, 0, 21, 0, 0, 51, 608, 51, 0,
- 616, 610, 0, 0, 0, 0, 26, 0, 27, 28,
- 0, 143, 0, 143, 1026, 0, 0, 0, 0, 0,
- 244, 250, 189, 0, 143, 0, 244, 0, 905, 905,
- 905, 0, 190, 882, 884, 629, 0, 0, 0, 0,
- 32, 0, 0, 0, 0, 191, 0, 0, 0, 459,
- 461, 465, 564, 565, 566, 567, 568, 569, 570, 571,
- 572, 573, 574, 575, 576, 577, 578, 244, 0, 244,
- 0, 143, 143, 620, 392, 392, 0, 51, 0, 0,
- 0, 51, 0, 250, 0, 51, 0, 0, 150, 150,
- 150, 0, 0, 465, 0, 127, 128, 0, 0, 211,
- 212, 0, 51, 0, 0, 14, 51, 0, 0, 0,
- 0, 0, 51, 51, 0, 905, 0, 0, 0, 0,
- 0, 0, 1033, 0, 0, 0, 0, 20, 244, 0,
- 51, 51, 150, 0, 0, 0, 23, 0, 605, 759,
- 250, 244, 0, 0, 1036, 26, 0, 130, 131, 0,
- 0, 0, 0, 244, 7, 8, 9, 10, 0, 51,
- 13, 606, 8, 9, 0, 0, 12, 13, 0, 0,
- 0, 607, 14, 0, 0, 0, 0, 0, 83, 0,
- 0, 608, 0, 0, 609, 610, 16, 244, 17, 244,
- 0, 0, 21, 0, 20, 0, 51, 0, 0, 0,
- 0, 0, 0, 23, 0, 26, 0, 27, 28, 0,
- 0, 0, 26, 0, 130, 131, 0, 244, 0, 0,
- 0, 462, 143, 143, 0, 143, 0, 0, 0, 0,
- 0, 463, 1105, 1106, 882, 884, 0, 0, 0, 32,
- 1112, 0, 0, 0, 464, 0, 0, 0, 729, 730,
- 459, 461, 465, 0, 0, 0, 741, 0, 0, 0,
- 0, 0, 0, 882, 884, 0, 544, 0, 0, 0,
- 143, 143, 143, 143, 620, 0, 0, 0, 143, 459,
- 461, 465, 0, 392, 0, 759, 0, 0, 0, 0,
- 0, 250, 0, 0, 0, 0, 51, 0, 0, 0,
- 0, 905, 905, 905, 0, 0, 7, 8, 9, 10,
- 1338, 0, 504, 0, 0, 0, 0, 759, 0, 0,
+ 443, 435, 487, 122, 445, 36, 420, 423, 711, 444,
+ 658, 712, 392, 256, 1019, 432, 224, 72, 532, 648,
+ 771, 253, 657, 76, 709, 738, 103, 42, 400, 1118,
+ 59, 784, 298, 786, 182, 857, 36, 59, 196, 991,
+ 525, 816, 486, 141, 146, 356, 1016, 357, 72, 554,
+ 557, 494, 209, 58, 76, 72, 398, 399, 42, 926,
+ 742, 76, 896, 949, 249, 42, 926, 247, 688, 391,
+ 174, 492, 495, 177, 201, 727, 213, 256, 35, 296,
+ 397, 57, 587, 349, 58, 349, 626, 349, 1478, 544,
+ 1428, 58, 408, 1056, 224, 260, 1530, 297, 1443, 170,
+ 171, 1534, 349, 349, 1027, 1446, 899, 190, 163, 35,
+ 224, 208, 57, 626, 626, 467, 169, 998, 364, 176,
+ 662, 663, 661, 900, 1600, 1535, 89, 308, 1193, 977,
+ 91, 406, 349, 295, 349, -1, 256, 1567, 1558, 580,
+ 1544, 581, 544, 26, 813, 978, 90, 855, 164, 72,
+ 92, 1028, 901, 1387, 1029, 407, -828, 1555, 196, 410,
+ 59, 468, 419, 422, 59, 735, 224, 155, -2, 780,
+ 1601, 209, 717, 718, 224, 1059, 452, 1589, 72, 928,
+ 558, 559, 72, 1568, 76, 58, 517, 1064, 76, 997,
+ 403, 224, 42, 440, 201, 213, 567, 174, 1581, 568,
+ 177, 490, 569, 539, 1194, 579, 470, 472, 190, 584,
+ 724, 1004, 1597, 405, 58, 1080, 814, 625, 58, -302,
+ 1612, 1085, 736, 1560, 15, 842, 170, 171, -415, 1199,
+ 208, 1558, 776, -356, -356, 1065, 88, 453, 453, 1027,
+ 59, 201, 57, 169, 789, 15, 176, 88, 535, -415,
+ 1532, 705, 1538, 190, 1478, -625, -415, -415, 72, 178,
+ 260, -415, 86, 93, 524, -302, -302, 1593, 820, 632,
+ 454, 454, 300, 394, 395, 10, 221, 790, -415, 1200,
+ -295, 791, -415, 155, 155, 155, 1028, 696, 732, 1029,
+ 623, 374, 247, 631, 58, 1225, 1226, 375, 1565, 514,
+ 759, -625, -625, 158, 1220, 1020, 1166, 116, 117, 118,
+ 21, 87, 1247, 664, 792, 658, -625, 705, 38, 511,
+ 774, 976, 519, 26, 349, 27, 319, -415, 1144, 155,
+ 691, 420, 423, 817, 1221, 856, 963, 296, 94, 1117,
+ 492, 495, 8, 9, 1598, 247, 12, 13, 492, 38,
+ 1292, 107, 14, 349, 667, 297, 108, 32, 926, 583,
+ 119, 120, 711, 1002, 1003, 1038, 16, 260, 17, 1353,
+ -583, 109, 72, 138, 20, 580, 39, 581, 668, 495,
+ 1404, 1404, 818, 23, 967, 964, 178, 714, 127, 128,
+ 1622, 295, 26, 139, 130, 131, 532, 708, 495, 1293,
+ 209, 1388, 926, 135, 224, 215, 216, 39, 58, 137,
+ -304, 14, 533, 665, 162, 710, -583, 189, 1354, 158,
+ 158, 158, 648, 201, 1151, 699, 221, 1154, 950, 1405,
+ 1509, 897, 1169, 20, 221, 221, 405, 59, 26, 1623,
+ 130, 131, 23, 161, 636, 567, 568, 224, 1215, 926,
+ 179, 707, 517, 778, 517, 72, -304, -304, 534, 153,
+ 517, 76, 517, 752, 221, 158, 1367, 183, 1180, 1181,
+ 729, -298, 610, 177, 1146, 1373, 1374, 653, 1375, 793,
+ 1254, 710, 1256, 610, 777, 831, 18, 763, 764, 705,
+ 841, 58, 244, 349, 366, 370, 705, 636, 1016, 201,
+ 1119, 799, 787, 788, 459, 838, 59, 201, 59, -365,
+ 40, 15, 819, 221, 209, 914, 59, 707, 611, 176,
+ 1474, 460, 187, 654, 72, 794, 72, 377, 916, 611,
+ 524, 832, 524, 55, 72, 1056, 188, 805, 812, 129,
+ 524, 40, -365, 841, -295, 349, -365, 90, 349, 26,
+ 461, 349, 1423, 1001, 299, 349, 847, 847, 847, 847,
+ 58, 915, 58, 138, 55, 514, 221, 514, 349, 623,
+ 58, 175, 798, 808, 917, 514, 421, 424, 349, -365,
+ 360, 349, 1032, 711, 696, 511, 712, 511, 519, 1192,
+ 519, 973, -583, 926, 378, 511, 362, 816, 519, 709,
+ 658, 372, 1093, 376, -366, 705, 15, 380, 155, 155,
+ 155, -120, 657, 15, 92, 636, 296, 381, -143, 401,
+ 972, 153, 926, 221, -295, 1289, 1290, 918, 492, 1033,
+ 137, 705, 1034, 1614, 297, 708, 934, -366, -583, 482,
+ 544, -366, 752, 705, -120, 425, 1368, 970, -120, 952,
+ 920, 922, 189, 710, 138, 95, 110, 111, 88, 178,
+ 710, 841, -144, 260, 1278, 404, 95, 414, 415, 433,
+ 295, 705, 1056, 919, -366, 147, 1273, 705, 122, 1615,
+ 240, -120, 935, 936, 241, 201, 587, 349, 984, 707,
+ 989, 990, 1513, 1514, 55, 1042, 707, 899, 175, -620,
+ -118, 209, 15, 221, 221, 247, 1262, 1264, 112, 113,
+ 303, 221, 661, 1017, 900, 1216, 574, 1218, 1186, 98,
+ 113, 1222, 215, 216, 201, 987, 201, 201, 14, 214,
+ 215, 216, 1420, -118, 1165, 990, 14, -118, -7, 256,
+ 164, 1043, 221, 901, 158, 158, 158, 253, 1188, 447,
+ 20, 708, 1190, 18, 1426, 576, 517, 1480, 20, 23,
+ 1576, 221, 1274, 1275, 1187, 1277, 137, 23, 799, 710,
+ -118, 201, 8, 537, 518, 1036, 448, 708, 1081, 1082,
+ 451, 1083, 715, 1127, 705, 411, 1068, 463, 705, 708,
+ 413, 842, 1070, 1071, 1189, 710, 1068, 1073, 1191, 1264,
+ 1071, 464, 432, 1481, 805, 707, 1577, 710, 1349, 1351,
+ 59, 567, 568, 1355, 127, 128, 363, 708, 349, 349,
+ 379, 349, 498, 708, 130, 131, 705, 503, 72, 1182,
+ 527, 707, 705, 540, 524, 710, 769, 91, 147, 798,
+ 137, 710, 542, 707, 775, 1249, 1250, 1251, 538, 1590,
+ 15, 541, 746, 781, -415, 421, 722, 92, 363, 561,
+ 91, 1385, 222, 223, 58, 543, 130, 131, 551, 514,
+ 562, 707, 560, 95, 110, 111, 528, 707, 300, 705,
+ 92, 10, -415, -415, 221, 1359, 1360, 1361, 666, 511,
+ 538, 349, 519, 829, 222, 446, 1121, 224, 563, 782,
+ 91, 421, 424, 536, 392, 564, 18, 583, 7, 8,
+ 250, 10, 95, 96, 97, 449, 21, 1090, 1091, 1092,
+ 92, 256, 480, 481, 847, 221, 112, 113, 114, 626,
+ 708, 426, 427, 675, 752, 672, 705, 676, 705, 830,
+ 574, 488, 489, 574, 678, 428, 21, 844, 710, 679,
+ 920, 922, 710, 251, 692, 429, 1449, 260, 480, 730,
+ 574, 27, 28, 32, 680, 98, 99, 693, 430, 221,
+ 90, 175, 708, 574, 847, 349, 92, 871, 708, 576,
+ 721, 1484, 576, -6, 707, 252, 1472, 747, 707, 765,
+ 710, 221, 725, 32, 1170, 1171, 710, 1501, 421, 852,
+ 699, 770, 1279, 8, 9, 894, 842, 15, 382, 383,
+ 384, 910, 576, 539, 823, 127, 128, 824, 517, 89,
+ 535, 488, 731, 705, 825, 752, 707, 1066, 826, 420,
+ 423, 833, 707, 300, 394, 395, 10, 834, 847, 90,
+ 518, 851, 785, 710, 853, 1392, 854, 363, 736, 89,
+ 518, 911, 705, 385, 856, 130, 131, -141, 420, 423,
+ 913, 386, 387, 719, 221, 26, 720, 130, 131, 90,
+ 927, 21, 59, 942, 929, 567, 568, 955, 723, 707,
+ 1484, 903, 708, -183, 708, 1281, 27, 319, 1240, 931,
+ 72, 904, 956, 1240, 1402, 1403, 524, 1484, 137, -183,
+ 710, -183, 710, 127, 128, 905, 8, 9, 965, 256,
+ 608, 609, 847, 91, 411, 969, 413, 155, 32, 480,
+ 1503, -142, 1573, 127, 128, 349, 58, 711, 966, 536,
+ 1551, 514, 971, 92, 488, 1504, 707, 20, 707, 95,
+ 96, 97, 979, 225, 226, 227, 980, 363, 480, 1508,
+ 363, 511, 1484, -298, 519, 130, 131, 993, 130, 131,
+ 738, 999, 453, 1436, 155, 1017, 1000, 18, 1434, 708,
+ 1439, 1024, 228, 26, 1025, 130, 131, 8, 9, 252,
+ 89, -579, 252, 1048, -579, 1295, 1296, 710, 1369, 903,
+ 26, 1336, 98, 99, 229, 842, 1026, 1328, 752, 904,
+ 90, 579, 1031, -827, 7, 8, 9, 10, 1040, 72,
+ 13, 1616, 349, 905, 1295, 1296, 710, 89, 91, 931,
+ 1044, 1045, 1075, 707, 1069, 1407, 1408, 1371, 1372, 130,
+ 131, -579, 18, -579, -579, 1074, -579, 90, 92, 230,
+ 231, 232, 21, 1094, 1099, 58, -52, -579, 636, -579,
+ 1095, -52, 707, 158, 1096, 26, 1097, 27, 28, 1098,
+ 1100, 498, -52, 1101, 1102, -579, -579, 942, 127, 128,
+ 1327, 981, -140, 1335, 1103, 1104, 140, 140, 1106, 156,
+ -579, 982, 603, 604, 605, 606, 607, 608, 609, 32,
+ 1107, 639, 1124, 1113, 983, 641, 1110, 1126, 1109, 1111,
+ 158, 1112, 1129, 212, 1130, 220, 155, 155, 155, 1128,
+ 1131, 237, 1164, 7, 127, 128, 10, 1433, 544, 1433,
+ 130, 131, 1336, 1137, 1139, 1138, 574, 1147, 1148, 1145,
+ 209, 1150, 1336, 1157, 1160, 155, 155, 155, 1328, 1336,
+ 72, 1163, 1543, 1185, 518, 1328, 1208, 1214, 847, 1217,
+ 72, 21, 1219, 201, 1437, 201, 1224, 72, 251, 95,
+ 110, 111, 420, 423, 421, 852, 27, 28, 460, 1228,
+ 705, 8, 9, 1248, 1252, 1570, 58, 127, 128, 567,
+ 568, 1257, 1258, 1259, -304, 1260, 58, 140, 1265, 1267,
+ 252, 1280, 140, 58, 1268, 156, 156, 156, 32, -304,
+ 1291, 1327, 1269, -304, 1335, 1272, 1276, 719, 720, 153,
+ 723, 1327, 112, 113, 1335, 363, 1282, 129, 1327, -304,
+ 1283, 1335, 212, 130, 131, 490, 1284, 26, 450, 130,
+ 131, -304, -304, 1287, -304, 1288, -304, 1294, 1299, 140,
+ 140, 156, 158, 158, 158, 1193, 1348, 538, -662, 1379,
+ 214, 215, 216, 1380, 1386, 220, 1205, 14, 1390, 1396,
+ 95, 96, 97, 493, 220, -304, -304, 1391, 1406, 1397,
+ 1398, 158, 158, 158, 18, 1399, 1525, 1415, 1416, 20,
+ -304, 1336, 1336, 1525, 1417, 1429, 1336, 1328, 23, 1431,
+ 1444, 375, 1328, 1447, 297, 1005, 1006, 1007, 1450, 72,
+ 72, 297, 349, 953, 72, 140, 1451, 1468, 1469, 1554,
+ 1047, 26, 1470, 98, 99, 100, 708, 1471, 763, 764,
+ 1061, 1062, 1476, 1336, 1487, 1488, 1492, 127, 1243, 1328,
+ 295, 1494, 1336, 1495, 710, 58, 58, 295, 1328, 1008,
+ 58, 72, 1574, 1502, 1520, 201, 26, 1076, 1009, 1010,
+ 72, 1521, 1078, 221, 1529, 1539, 1525, 1540, 1545, 1547,
+ 1327, 1327, 1553, 1335, 1335, 1327, 1562, 1563, 1335, 1571,
+ 707, 363, 155, 1572, 297, 156, 1584, 58, 1336, 130,
+ 131, 1588, 1595, 1599, 1328, 1011, 58, 1618, 1596, 1602,
+ 574, 605, 606, 607, 608, 609, 72, 1604, 1609, 421,
+ 424, 1605, 1327, 538, 1357, 1335, 518, 1613, 1617, 612,
+ 295, 1327, 1620, 1625, 1335, 339, 1336, 339, 1626, 339,
+ 1628, 1629, 1328, 1, 5, 442, 147, 160, 421, 1347,
+ 1499, 968, 58, 1167, 72, 127, 128, 441, 728, 155,
+ 155, 155, 439, 809, 1381, 1382, 1383, 1384, 613, 614,
+ 1300, 212, 220, 615, 616, 617, 618, 1327, 1569, 500,
+ 1335, 359, 127, 128, 339, 140, 339, 13, 140, 1483,
+ 58, 409, 1624, 1389, 156, 156, 156, 550, 1159, 1023,
+ 140, 7, 8, 9, 10, 26, 1158, 130, 131, 505,
+ 811, 127, 128, 1452, 1362, 1327, 535, 1245, 1335, 1077,
+ 1156, 545, 958, 127, 128, 636, 898, 1419, 158, 483,
+ 633, 546, 26, 390, 130, 131, 140, 1442, 140, 21,
+ 156, 156, 156, 1345, 1591, 450, 251, 1603, 637, 1566,
+ 258, 140, 493, 220, 27, 28, 450, 0, 638, 1608,
+ 493, 26, 221, 130, 131, 1610, 636, 1207, 639, 1448,
+ 0, 640, 641, 26, 258, 130, 131, 545, 252, 95,
+ 110, 111, 529, 0, 0, 212, 32, 546, 0, 637,
+ 0, 0, 450, 0, 1473, 158, 158, 158, 1046, 638,
+ 0, 0, 0, 258, 0, 0, 0, 0, 0, 639,
+ 0, 0, 640, 641, 258, 0, 0, 21, 0, 156,
+ 1231, 1232, 156, 1241, 1242, 0, 1244, 1493, 116, 1006,
+ 1007, 0, 112, 113, 411, 413, 0, 156, 156, 156,
+ 0, 744, 536, 0, 0, 0, 0, 1079, 750, 0,
+ 0, 0, 156, 1084, 0, 0, 506, 0, 7, 8,
+ 507, 10, 167, 12, 13, 0, 0, 565, 0, 14,
+ 116, 1006, 1007, 258, 95, 110, 111, 0, 225, 226,
+ 227, 119, 120, 16, 1205, 17, 18, 19, 1523, 0,
+ 0, 20, 0, 0, 871, 1523, 21, 1050, 0, 0,
+ 23, 508, 18, 168, 0, 339, 0, 228, 258, 26,
+ 0, 27, 28, 943, 574, 509, 0, 510, 0, 0,
+ 0, 26, 743, 119, 120, 30, 0, 112, 113, 743,
+ 0, 839, 258, 220, 0, 31, 101, 0, 0, 0,
+ 0, 0, 0, 32, 115, 0, 0, 0, 33, 95,
+ 110, 111, 421, 1347, 0, 0, 1140, 0, 1141, 719,
+ 720, 0, 723, 0, 645, 649, 652, 0, 1523, 0,
+ 0, 0, 212, 0, 220, 237, 0, 0, 0, 0,
+ 0, 0, 1365, 1366, 1594, 0, 0, 233, 95, 110,
+ 111, 892, 681, 682, 683, 0, 0, 893, 7, 127,
+ 128, 10, 112, 1496, 13, 0, 1607, 741, 745, 95,
+ 110, 111, 743, 871, 0, 745, 0, 0, 220, 0,
+ 655, 8, 9, 10, 258, 0, 18, 0, 0, 140,
+ 140, 0, 140, 0, 947, 0, 21, 0, 0, 0,
+ 493, 112, 113, 450, 0, 339, 388, 0, 0, 26,
+ 0, 27, 28, 450, 450, 308, 656, 783, 21, 0,
+ 369, 371, 112, 1498, 0, 30, 116, 117, 118, 0,
+ 416, 26, 743, 130, 131, 31, 0, 0, 743, 0,
+ 450, 0, 258, 32, 1223, 450, 0, 0, 33, 1227,
+ 0, 0, 0, 0, 0, 0, 0, 339, 745, 0,
+ 0, 0, 0, 0, 0, 0, 0, 156, 743, 0,
+ 0, 0, 1253, 0, 1255, 743, 0, 26, 0, 119,
+ 120, 0, 0, 1457, 1458, 1459, 0, 0, 0, 0,
+ 339, 0, 741, 0, 0, 868, 869, 0, 873, 874,
+ 875, 876, 877, 878, 879, 880, 881, 882, 883, 884,
+ 885, 886, 887, 888, 889, 890, 891, 0, 745, 0,
+ 499, 501, 0, 0, 745, 0, 0, 0, 0, 1286,
+ 0, 0, 258, 530, 7, 8, 9, 10, 214, 215,
+ 216, 300, 8, 9, 10, 14, 0, 0, 0, 0,
+ 0, 95, 96, 97, 745, 0, 0, 0, 0, 0,
+ 0, 745, 18, 156, 156, 943, 0, 20, 1511, 1512,
+ 0, 0, 21, 0, 0, 0, 23, 258, 636, 21,
+ 382, 383, 384, 960, 962, 26, 251, 27, 28, 0,
+ 0, 214, 215, 216, 27, 319, 363, 0, 14, 339,
+ 0, 981, 237, 566, 98, 99, 0, 140, 140, 943,
+ 0, 982, 0, 921, 923, 18, 0, 0, 252, 32,
+ 20, 639, 0, 0, 983, 641, 32, 0, 0, 23,
+ 0, 26, 0, 386, 387, 1114, 1115, 491, 215, 216,
+ 0, 1120, 578, 0, 14, 674, 0, 741, 0, 0,
+ 0, 0, 0, 0, 684, 1132, 943, 1133, 0, 1134,
+ 0, 18, 743, 0, 258, 0, 20, 674, 127, 128,
+ 0, 1393, 215, 216, 0, 23, 0, 0, 14, 0,
+ 258, 986, 0, 645, 649, 0, 652, 1592, 7, 8,
+ 9, 10, 0, 450, 450, 0, 450, 450, 0, 450,
+ 20, 0, 0, 0, 1067, 1162, 0, 0, 0, 23,
+ 0, 636, 0, 0, 0, 704, 743, 743, 26, 0,
+ 130, 131, 743, 0, 0, 0, 21, 0, 649, 0,
+ 339, 339, 636, 339, 637, 0, 743, 0, 743, 26,
+ 743, 27, 28, 0, 638, 0, 0, 0, 745, 1453,
+ 1454, 1183, 0, 0, 639, 981, 0, 647, 641, 0,
+ 0, 0, 0, 1464, 1465, 982, 0, 116, 1006, 1007,
+ 1105, 1049, 0, 32, 0, 639, 0, 0, 983, 641,
+ 1475, 751, 0, 0, 779, 0, 743, 0, 0, 0,
+ 0, 0, 0, 0, 1050, 0, 140, 140, 156, 156,
+ 943, 1051, 745, 745, 140, 0, 0, 741, 745, 601,
+ 602, 603, 604, 605, 606, 607, 608, 609, 26, 0,
+ 119, 120, 745, 649, 745, 0, 745, 156, 156, 943,
+ 0, 0, 743, 0, 0, 0, 258, 596, 597, 598,
+ 599, 600, 601, 602, 603, 604, 605, 606, 607, 608,
+ 609, 743, 1518, 1519, 0, 450, 450, 0, 0, 0,
+ 0, 0, 1155, 0, 0, 0, 840, 864, 0, 843,
+ 0, 0, 745, 845, 846, 848, 849, 850, 0, 7,
+ 8, 9, 10, 0, 0, 246, 578, 339, 0, 0,
+ 300, 394, 395, 10, 0, 0, 1135, 0, 1136, 867,
+ 1179, 0, 0, 0, 0, 0, 0, 18, 0, 1142,
+ 0, 912, 0, 921, 923, 0, 0, 21, 745, 0,
+ 0, 140, 140, 636, 140, 0, 0, 1301, 21, 1302,
+ 26, 1303, 27, 28, 0, 251, 0, 745, 0, 7,
+ 8, 9, 10, 27, 319, 13, 981, 627, 0, 300,
+ 394, 395, 10, 924, 628, 0, 982, 921, 923, 0,
+ 924, 212, 220, 0, 32, 0, 639, 18, 0, 983,
+ 641, 0, 1229, 1230, 258, 32, 258, 21, 0, 0,
+ 975, 0, 0, 636, 0, 0, 0, 21, 0, 0,
+ 26, 992, 27, 28, 629, 0, 450, 450, 450, 0,
+ 26, 0, 27, 319, 0, 0, 1172, 0, 743, 0,
+ 743, 0, 743, 741, 741, 0, 1173, 1266, 258, 0,
+ 0, 0, 864, 0, 32, 80, 639, 0, 0, 1174,
+ 641, 0, 1395, 0, 630, 104, 0, 339, 0, 0,
+ 0, 0, 0, 0, 0, 133, 0, 0, 0, 0,
+ 0, 144, 144, 0, 144, 0, 80, 0, 0, 0,
+ 0, 0, 0, 80, 156, 0, 0, 0, 0, 704,
+ 0, 0, 0, 0, 0, 0, 203, 0, 80, 0,
+ 0, 450, 450, 0, 0, 0, 238, 0, 0, 0,
+ 0, 0, 0, 104, 745, 751, 745, 0, 745, 0,
+ 0, 0, 258, 0, 262, 104, 741, 751, 0, 0,
+ 0, 0, 0, 743, 0, 741, 741, 0, 0, 0,
+ 741, 0, 0, 0, 0, 0, 0, 104, 0, 0,
+ 0, 156, 156, 156, 0, 751, 0, 0, 0, 0,
+ 0, 751, 1370, 0, 0, 0, 1135, 1136, 921, 923,
+ 300, 8, 9, 10, 1142, 133, 0, 80, 0, 0,
+ 0, 144, 144, 0, 0, 0, 412, 144, 741, 0,
+ 144, 144, 144, 0, 0, 0, 0, 921, 923, 258,
+ 7, 127, 128, 10, 0, 0, 80, 0, 21, 0,
+ 80, 0, 0, 0, 0, 251, 203, 80, 0, 745,
+ 450, 0, 0, 27, 319, 0, 258, 0, 18, 1116,
+ 0, 0, 0, 0, 203, 203, 203, 0, 21, 0,
+ 0, 0, 0, 1414, 0, 0, 0, 538, 0, 0,
+ 0, 26, 0, 27, 28, 32, 127, 128, 0, 0,
+ 215, 216, 867, 203, 0, 684, 14, 149, 751, 0,
+ 0, 0, 924, 0, 0, 0, 0, 150, 975, 743,
+ 502, 0, 0, 741, 0, 32, 80, 0, 20, 104,
+ 151, 1135, 1136, 0, 1142, 1455, 1456, 23, 0, 636,
+ 144, 0, 0, 0, 0, 0, 26, 0, 130, 131,
+ 704, 0, 1168, 741, 0, 0, 924, 0, 259, 0,
+ 0, 0, 637, 0, 0, 0, 0, 0, 127, 128,
+ 0, 0, 638, 246, 0, 0, 0, 0, 104, 547,
+ 0, 0, 639, 0, 0, 640, 641, 0, 471, 473,
+ 477, 0, 0, 0, 7, 127, 128, 10, 0, 0,
+ 246, 0, 0, 924, 0, 745, 0, 0, 0, 0,
+ 0, 636, 0, 0, 0, 0, 1210, 0, 26, 0,
+ 130, 131, 18, 104, 0, 0, 0, 634, 1516, 547,
+ 547, 650, 21, 0, 637, 434, 0, 0, 0, 0,
+ 80, 0, 0, 0, 638, 26, 0, 27, 28, 1263,
+ 0, 0, 0, 0, 639, 0, 1536, 640, 641, 0,
+ 751, 30, 751, 0, 0, 0, 0, 469, 0, 0,
+ 0, 31, 0, 0, 133, 795, 796, 9, 10, 32,
+ 485, 0, 0, 104, 33, 203, 104, 0, 0, 0,
+ 1271, 0, 0, 0, 0, 0, 127, 128, 0, 0,
+ 144, 535, 0, 144, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 21, 0, 144, 0, 0, 0, 0,
+ 0, 0, 0, 80, 0, 0, 26, 0, 27, 28,
+ 7, 8, 9, 10, 797, 1305, 535, 0, 0, 636,
+ 0, 1263, 193, 0, 0, 0, 26, 924, 130, 131,
+ 0, 203, 194, 203, 0, 203, 203, 203, 18, 0,
+ 32, 203, 637, 0, 0, 195, 203, 0, 21, 203,
+ 0, 0, 638, 0, 636, 0, 924, 0, 741, 0,
+ 0, 26, 639, 27, 28, 640, 641, 0, 0, 133,
+ 1358, 0, 80, 0, 80, 0, 0, 981, 0, 806,
+ 80, 0, 80, 0, 0, 0, 166, 982, 7, 8,
+ 9, 10, 167, 12, 13, 32, 0, 639, 0, 14,
+ 983, 641, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 16, 0, 17, 18, 19, 0, 0,
+ 0, 20, 104, 104, 104, 104, 21, 0, 0, 0,
+ 23, 0, 0, 168, 0, 0, 0, 0, 0, 26,
+ 0, 27, 28, 1421, 1422, 761, 0, 762, 0, 471,
+ 473, 477, 0, 0, 0, 30, 0, 0, 0, 0,
+ 773, 0, 0, 0, 0, 31, 0, 0, 0, 0,
+ 0, 0, 0, 32, 0, 0, 0, 0, 33, 0,
+ 0, 0, 104, 34, 547, 0, 0, 0, 0, 0,
+ 0, 0, 0, 804, 0, 0, 634, 0, 547, 547,
+ 0, 650, 0, 0, 0, 0, 1210, 0, 944, 8,
+ 9, 0, 946, 12, 246, 0, 0, 0, 0, 14,
+ 0, 0, 0, 0, 1479, 0, 0, 203, 0, 0,
+ 0, 0, 0, 16, 766, 17, 0, 0, 0, 772,
+ 0, 20, 0, 0, 0, 0, 1497, 1500, 0, 0,
+ 23, 133, 636, 0, 0, 0, 0, 0, 133, 26,
+ 0, 130, 131, 0, 0, 0, 203, 988, 203, 203,
+ 238, 650, 0, 0, 0, 637, 0, 0, 0, 0,
+ 0, 0, 0, 821, 0, 638, 0, 0, 0, 827,
+ 0, 0, 0, 0, 0, 639, 0, 0, 640, 641,
+ 0, 835, 836, 0, 837, 0, 0, 0, 0, 300,
+ 8, 9, 10, 203, 0, 0, 0, 988, 0, 0,
+ 0, 1541, 0, 0, 203, 203, 0, 203, 7, 8,
+ 9, 10, 214, 215, 216, 0, 0, 0, 0, 14,
+ 0, 0, 0, 104, 0, 0, 806, 21, 0, 0,
+ 0, 0, 0, 0, 251, 104, 18, 0, 0, 0,
+ 578, 20, 27, 319, 0, 0, 21, 0, 1072, 0,
+ 23, 0, 636, 0, 704, 0, 80, 0, 0, 26,
+ 0, 27, 28, 104, 0, 0, 0, 0, 0, 104,
+ 0, 0, 0, 0, 32, 981, 547, 547, 547, 932,
+ 933, 0, 0, 0, 932, 982, 0, 0, 547, 0,
+ 0, 0, 0, 32, 0, 639, 0, 0, 1030, 641,
+ 0, 0, 0, 0, 0, 8, 9, 0, 167, 12,
+ 13, 0, 0, 749, 0, 14, 83, 0, 761, 762,
+ 0, 773, 0, 0, 0, 0, 106, 0, 0, 16,
+ 0, 17, 18, 0, 0, 126, 134, 20, 0, 0,
+ 804, 0, 145, 145, 0, 145, 23, 83, 636, 0,
+ 0, 0, 0, 0, 83, 26, 0, 130, 131, 0,
+ 0, 547, 0, 547, 0, 0, 0, 145, 0, 83,
+ 104, 637, 0, 0, 547, 0, 104, 239, 944, 944,
+ 944, 638, 0, 0, 248, 0, 1149, 300, 127, 128,
+ 10, 639, 0, 0, 640, 641, 248, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 7, 127, 128, 10,
+ 0, 0, 13, 0, 0, 0, 0, 1058, 104, 0,
+ 104, 0, 203, 203, 1176, 21, 0, 0, 0, 1063,
+ 0, 0, 251, 0, 18, 0, 0, 0, 0, 0,
+ 27, 319, 0, 0, 21, 0, 0, 0, 83, 0,
+ 0, 0, 145, 145, 0, 0, 0, 26, 145, 27,
+ 28, 145, 145, 145, 0, 1086, 0, 1088, 0, 0,
+ 0, 1176, 32, 149, 0, 0, 0, 83, 0, 0,
+ 0, 83, 0, 150, 104, 0, 0, 145, 83, 0,
+ 0, 32, 0, 0, 0, 0, 151, 0, 0, 0,
+ 0, 0, 0, 0, 0, 145, 145, 145, 0, 0,
+ 203, 0, 0, 0, 0, 144, 0, 0, 80, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 104, 0,
+ 104, 0, 0, 0, 145, 0, 471, 473, 477, 1122,
+ 1123, 0, 1125, 8, 9, 0, 0, 12, 13, 0,
+ 8, 9, 0, 14, 12, 246, 0, 83, 104, 0,
+ 14, 0, 0, 547, 547, 0, 547, 16, 0, 17,
+ 1143, 145, 0, 0, 16, 20, 17, 0, 0, 0,
+ 0, 0, 20, 0, 23, 477, 0, 0, 0, 0,
+ 0, 23, 0, 26, 0, 130, 131, 619, 0, 0,
+ 26, 0, 130, 131, 0, 0, 0, 0, 0, 248,
+ 145, 203, 203, 203, 203, 1176, 0, 0, 0, 203,
+ 0, 1178, 0, 0, 1239, 0, 642, 642, 642, 0,
+ 0, 0, 620, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 1176, 1176, 1176, 7, 8, 9, 10, 167,
+ 12, 13, 0, 0, 248, 0, 14, 0, 635, 0,
+ 145, 145, 651, 0, 0, 0, 0, 660, 0, 0,
+ 16, 83, 17, 18, 19, 0, 0, 0, 20, 0,
+ 0, 0, 0, 21, 0, 0, 0, 23, 0, 0,
+ 168, 0, 0, 0, 0, 0, 26, 0, 27, 28,
+ 0, 0, 0, 0, 0, 697, 0, 0, 0, 0,
+ 0, 0, 30, 0, 248, 0, 145, 248, 0, 0,
+ 0, 0, 31, 0, 0, 761, 762, 471, 473, 477,
+ 32, 145, 0, 773, 145, 33, 203, 203, 0, 203,
+ 34, 0, 7, 8, 9, 10, 145, 0, 13, 0,
+ 0, 0, 0, 0, 83, 0, 471, 473, 477, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 392, 0, 143, 0, 0, 0, 0, 143, 0, 0,
- 0, 51, 0, 0, 21, 0, 0, 0, 0, 1105,
- 1106, 0, 1112, 0, 0, 51, 0, 26, 51, 27,
- 28, 0, 0, 51, 0, 729, 730, 0, 741, 0,
- 0, 51, 0, 189, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 190, 0, 0, 0, 143, 143, 0,
- 143, 32, 0, 0, 0, 0, 191, 0, 0, 51,
- 0, 51, 0, 150, 150, 150, 0, 0, 0, 51,
- 0, 0, 0, 0, 51, 1395, 0, 51, 1332, 1333,
- 9, 10, 0, 0, 0, 0, 143, 620, 143, 0,
- 0, 0, 0, 51, 0, 0, 0, 7, 8, 9,
- 10, 201, 12, 202, 0, 244, 0, 0, 14, 0,
- 0, 0, 0, 0, 0, 0, 21, 0, 0, 0,
- 0, 0, 16, 544, 17, 18, 544, 0, 0, 26,
- 20, 27, 28, 0, 0, 21, 0, 1334, 0, 23,
- 0, 544, 544, 544, 0, 189, 0, 0, 26, 0,
- 27, 28, 0, 0, 203, 190, 544, 0, 0, 0,
- 0, 0, 78, 32, 30, 0, 0, 0, 191, 0,
- 0, 0, 0, 0, 31, 0, 465, 0, 0, 0,
- 0, 0, 32, 0, 0, 0, 0, 33, 78, 78,
- 0, 78, 0, 78, 0, 0, 0, 0, 905, 0,
- 78, 0, 0, 0, 250, 1332, 127, 128, 10, 0,
- 0, 0, 0, 78, 0, 78, 0, 544, 561, 562,
- 563, 564, 565, 566, 567, 568, 569, 570, 571, 572,
- 573, 574, 575, 576, 577, 578, 51, 0, 0, 0,
- 0, 0, 0, 21, 0, 0, 459, 461, 465, 0,
- 0, 0, 0, 0, 0, 0, 26, 0, 27, 28,
- 392, 0, 0, 0, 1334, 0, 0, 392, 905, 905,
- 905, 0, 30, 0, 0, 51, 51, 51, 51, 0,
- 0, 0, 31, 0, 0, 0, 0, 244, 198, 0,
- 32, 0, 143, 0, 78, 33, 0, 0, 78, 0,
- 0, 0, 78, 0, 0, 78, 78, 78, 0, 0,
- 8, 9, 0, 253, 12, 13, 257, 0, 0, 78,
- 14, 51, 0, 78, 0, 51, 0, 0, 0, 78,
- 78, 0, 51, 51, 16, 51, 17, 253, 0, 361,
- 0, 0, 20, 0, 0, 0, 0, 78, 78, 78,
+ 18, 0, 0, 0, 1285, 203, 988, 203, 0, 0,
+ 21, 0, 145, 0, 145, 0, 145, 145, 145, 0,
+ 0, 0, 145, 26, 104, 27, 28, 145, 0, 6,
+ 145, 7, 8, 9, 10, 11, 12, 13, 0, 193,
+ 0, 0, 14, 1298, 0, 0, 0, 0, 0, 194,
+ 134, 0, 0, 83, 0, 83, 16, 32, 17, 18,
+ 807, 83, 195, 83, 20, 0, 0, 0, 0, 21,
+ 0, 0, 0, 23, 0, 0, 438, 0, 0, 0,
+ 761, 762, 26, 773, 27, 28, 0, 0, 29, 0,
+ 1363, 0, 0, 0, 1364, 0, 0, 0, 30, 0,
+ 0, 0, 0, 248, 248, 248, 248, 0, 31, 1176,
+ 0, 0, 0, 0, 1377, 0, 32, 0, 1378, 0,
+ 0, 33, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 7, 127, 128, 10, 0, 0, 535, 0,
+ 0, 0, 0, 0, 0, 642, 642, 0, 642, 0,
+ 0, 0, 0, 1394, 0, 941, 0, 0, 0, 0,
+ 18, 0, 0, 248, 0, 145, 0, 0, 0, 0,
+ 21, 0, 0, 0, 0, 0, 1176, 1176, 1176, 145,
+ 145, 0, 651, 26, 0, 27, 28, 0, 0, 945,
+ 0, 0, 104, 0, 0, 0, 0, 203, 0, 30,
+ 0, 0, 660, 7, 127, 128, 10, 0, 145, 31,
+ 0, 0, 0, 642, 0, 642, 642, 32, 642, 0,
+ 0, 0, 33, 477, 0, 0, 0, 0, 0, 0,
+ 0, 18, 697, 0, 0, 0, 0, 0, 0, 0,
+ 126, 21, 0, 0, 0, 1466, 1467, 145, 651, 145,
+ 145, 239, 651, 0, 26, 0, 27, 28, 0, 0,
+ 642, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 30, 0, 0, 0, 0, 1018, 0, 0, 0, 0,
+ 31, 0, 0, 0, 0, 0, 0, 0, 32, 0,
+ 471, 473, 477, 33, 145, 0, 0, 0, 651, 0,
+ 0, 0, 0, 0, 0, 145, 145, 0, 145, 0,
+ 0, 0, 0, 0, 7, 8, 9, 10, 167, 12,
+ 13, 0, 1018, 749, 248, 14, 0, 807, 0, 0,
+ 0, 0, 0, 0, 0, 0, 248, 0, 0, 16,
+ 0, 17, 18, 0, 0, 0, 0, 20, 0, 0,
+ 0, 0, 21, 0, 0, 642, 23, 83, 636, 0,
+ 0, 0, 0, 0, 248, 26, 0, 27, 28, 0,
+ 248, 0, 0, 0, 0, 0, 0, 145, 145, 145,
+ 0, 1172, -387, 8, 9, -387, -387, 12, 246, 145,
+ 0, 1173, 0, 14, 0, 0, 0, 0, 0, 32,
+ 0, 639, 0, 0, 1174, 641, 0, 16, 0, 17,
+ -387, 0, 0, 0, 0, 20, 0, 0, 0, 0,
+ -387, 0, 0, 0, 23, 0, 636, 0, 642, 0,
+ 642, 0, 0, 26, 0, 130, 131, 0, 0, 0,
+ 0, 642, 0, 0, 0, 941, 941, 941, 0, 637,
+ 7, 8, 9, 10, 214, 215, 216, 0, 0, 638,
+ 0, 14, 145, 0, 145, 0, 0, -387, 0, 639,
+ 0, 248, 640, 641, 0, 145, 0, 248, 18, 945,
+ 945, 945, 0, 20, 0, 0, 0, 660, 21, 642,
+ 642, 642, 23, 0, 636, 0, 0, 0, 0, 0,
+ 0, 26, 0, 27, 28, 51, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 193, 0, 248,
+ 0, 248, 0, 145, 145, 651, 0, 194, 0, 0,
+ 0, 51, 51, 0, 152, 32, 51, 0, 941, 0,
+ 1438, 0, 0, 51, 598, 599, 600, 601, 602, 603,
+ 604, 605, 606, 607, 608, 609, 51, 0, 51, 795,
+ 8, 507, 10, 205, 12, 206, 0, 0, 0, 0,
+ 14, 0, 945, 0, 0, 0, 0, 0, 0, 0,
+ 0, 254, 0, 0, 16, 248, 17, 18, 0, 0,
+ 0, 0, 20, 0, 0, 0, 0, 21, 0, 0,
0, 23, 0, 0, 0, 0, 0, 0, 0, 0,
- 26, 0, 130, 131, 588, 0, 51, 0, 51, 155,
- 0, 0, 0, 51, 51, 51, 78, 7, 127, 128,
- 10, 51, 0, 7, 8, 9, 10, 163, 12, 13,
- 0, 200, 717, 0, 14, 0, 0, 0, 0, 589,
- 0, 0, 0, 544, 198, 0, 0, 0, 16, 0,
- 17, 18, 0, 78, 0, 21, 20, 0, 0, 0,
- 0, 21, 198, 198, 198, 23, 0, 605, 26, 0,
- 27, 28, 472, 0, 26, 0, 27, 28, 0, 0,
- 0, 0, 0, 0, 147, 0, 0, 0, 0, 0,
- 1142, 198, 0, 0, 148, 0, 0, 0, 0, 0,
- 1143, 0, 32, 0, 0, 0, 0, 149, 32, 0,
- 608, 0, 0, 1144, 610, 0, 0, 257, 7, 8,
- 9, 10, 0, 155, 155, 155, 0, 0, 0, 0,
- 0, 253, 0, 0, 0, 0, 0, 0, 0, 544,
- 544, 544, 0, 0, 0, 250, 0, 200, 0, 628,
- 0, 0, 0, 78, 0, 0, 21, 0, 0, 0,
- 0, 0, 0, 0, 0, 200, 200, 466, 0, 26,
- 0, 27, 28, 0, 0, 1402, 0, 0, 0, 0,
- 0, 0, 51, 51, 150, 189, 0, 0, 0, 250,
- 0, 0, 0, 0, 200, 190, 0, 0, 78, 0,
- 0, 0, 0, 32, 0, 0, 0, 0, 191, 0,
- 0, 0, 78, 0, 0, 78, 0, 0, 0, 0,
- 78, 0, 0, 253, 257, 0, 1174, 0, 78, 566,
- 567, 568, 569, 570, 571, 572, 573, 574, 575, 576,
- 577, 578, 7, 8, 9, 10, 0, 0, 0, 365,
- 367, 0, 0, 0, 0, 51, 78, 0, 78, 0,
- 78, 78, 78, 0, 0, 0, 78, 0, 0, 0,
- 517, 78, 0, 198, 78, 0, 250, 0, 0, 0,
- 21, 0, 0, 0, 0, 0, 0, 0, 0, 51,
- 78, 0, 0, 26, 0, 27, 28, 0, 0, 0,
- 0, -383, 8, 9, -383, -383, 12, 242, 0, 189,
- 0, 0, 14, 7, 8, 9, 10, 0, 0, 190,
- 613, 613, 613, 0, 0, 0, 16, 32, 17, -383,
- 0, 198, 191, 198, 20, 198, 198, 198, 0, -383,
- 0, 198, 0, 23, 0, 605, 198, 0, 0, 198,
- 0, 21, 26, 0, 130, 131, 0, 0, 0, 0,
- 250, 0, 0, 0, 26, 0, 27, 28, 606, 8,
- 9, 0, 163, 12, 13, 0, 200, 717, 607, 14,
- 462, 51, 51, 150, 150, 150, -383, 250, 608, 51,
- 463, 609, 610, 16, 0, 17, 18, 0, 32, 0,
- 0, 20, 628, 464, 0, 0, 0, 0, 0, 0,
- 23, 0, 1174, 1174, 1174, 0, 0, 0, 0, 26,
- 0, 130, 131, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 78, 200, 0, 200, 0, 466, 466,
- 466, 0, 0, 51, 200, 0, 0, 0, 51, 200,
- 0, 0, 200, 0, 0, 0, 162, 0, 7, 8,
- 9, 10, 163, 12, 13, 0, 0, 547, 0, 14,
- 0, 255, 78, 78, 78, 78, 0, 0, 0, 0,
+ 26, 145, 27, 28, 0, 0, 145, 0, 797, 83,
+ 0, 0, 0, 0, 0, 0, 30, 0, 0, 248,
+ 0, 248, 0, 0, 396, 396, 31, 51, 0, 0,
+ 0, 51, 51, 0, 32, 254, 0, 51, 0, 33,
+ 152, 152, 152, 0, 0, 0, 0, 431, 0, 248,
+ 0, 0, 0, 0, 145, 145, 51, 145, 0, 0,
+ 51, 0, 0, 0, 0, 0, 51, 51, 642, 642,
+ 642, 642, 642, 0, 0, 0, 642, 0, 0, 0,
+ 0, 0, 0, 0, 51, 51, 152, 0, 0, 0,
+ 0, 0, 0, 0, 254, 0, 0, 0, 0, 941,
+ 941, 941, 145, 145, 145, 145, 651, 0, 0, 0,
+ 145, 0, 0, 51, 0, 0, 506, 1018, 7, 8,
+ 507, 10, 167, 12, 13, 0, 0, 0, 0, 14,
+ 0, 0, 0, 945, 945, 945, 51, 0, 0, 0,
0, 0, 0, 16, 0, 17, 18, 19, 0, 0,
- 0, 20, 253, 257, 0, 0, 21, 0, 51, 51,
- 23, 51, 0, 164, 0, 0, 0, 0, 198, 26,
- 0, 27, 28, 0, 0, 0, 0, 0, 78, 0,
- 0, 0, 78, 0, 0, 30, 0, 0, 0, 78,
- 78, 0, 78, 0, 0, 31, 0, 51, 51, 51,
- 673, 0, 0, 32, 422, 0, 0, 198, 33, 198,
- 198, 0, 0, 34, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 78, 0, 78, 0, 0, 867, 0,
- 78, 78, 78, 0, 0, 0, 457, 0, 78, 0,
- 0, 0, 613, 613, 0, 613, 0, 0, 0, 473,
- 8, 9, 613, 198, 12, 13, 0, 0, 719, 0,
- 14, 0, 0, 0, 198, 198, 0, 198, 0, 0,
- 0, 200, 0, 0, 16, 0, 17, 0, 0, 0,
- 0, 0, 20, 0, 0, 0, 0, 0, 0, 0,
- 0, 23, 257, 0, 0, 0, 0, 0, 0, 0,
- 26, 0, 130, 131, 0, 198, 0, 0, 0, 1174,
- 945, 0, 945, 945, 0, 613, 0, 0, 0, 0,
- 0, 0, 0, 0, 801, 0, 0, 804, 0, 0,
- 0, 806, 807, 809, 810, 811, 0, 0, 0, 858,
- 0, 0, 0, 0, 547, 8, 9, 0, 163, 12,
- 13, 0, 0, 0, 0, 14, 945, 828, 0, 0,
- 0, 0, 0, 628, 0, 0, 0, 200, 200, 16,
- 200, 17, 18, 0, 0, 0, 0, 20, 0, 1174,
- 1174, 1174, 0, 0, 0, 0, 667, 0, 0, 164,
- 0, 0, 0, 0, 0, 26, 0, 130, 131, 78,
- 78, 78, 0, 51, 0, 0, 0, 0, 200, 0,
- 0, 885, 0, 0, 0, 0, 0, 0, 885, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 517, 517, 517, 0, 0, 253, 257, 253,
- 0, 0, 0, 1176, 613, 0, 0, 0, 0, 0,
- 0, 0, 76, 563, 564, 565, 566, 567, 568, 569,
- 570, 571, 572, 573, 574, 575, 576, 577, 578, 0,
- 0, 0, 78, 0, 198, 198, 1145, 0, 141, 145,
- 0, 253, 0, 76, 0, 0, 0, 611, 611, 611,
- 76, 565, 566, 567, 568, 569, 570, 571, 572, 573,
- 574, 575, 576, 577, 578, 209, 78, 0, 0, 0,
- 0, 0, 0, 0, 0, 734, 0, 613, 1145, 613,
- 740, 0, 0, 0, 0, 0, 673, 0, 0, 0,
- 613, 0, 0, 0, 613, 613, 613, 0, 0, 0,
- 0, 0, 0, 0, 0, 782, 0, 198, 0, 0,
- 0, 788, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 796, 797, 0, 798, 0, 472, 0,
- 0, 0, 0, 0, 0, 0, 0, 945, 945, 1147,
- 0, 0, 0, 0, 403, 719, 0, 0, 406, 0,
- 0, 719, 408, 0, 0, 0, 0, 0, 78, 78,
- 78, 78, 78, 0, 0, 0, 78, 0, 0, 76,
- 0, 0, 0, 76, 0, 0, 0, 0, 0, 0,
- 209, 1147, 0, 0, 0, 0, 0, 0, 0, 1176,
- 1176, 1176, 0, 0, 0, 0, 0, 141, 145, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 200, 0, 253, 0, 0, 0, 0, 0, 0, 1086,
- 78, 893, 894, 0, 0, 78, 893, 0, 0, 0,
- 0, 0, 0, 198, 198, 198, 198, 1145, 0, 1259,
- 0, 198, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 828, 0, 0, 0, 0, 0, 719, 0,
- 0, 0, 885, 505, 1145, 1145, 1145, 0, 0, 0,
- 0, 0, 0, 0, 0, 78, 78, 0, 78, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 867, 867,
- 0, 867, 0, 0, 0, 198, 0, 0, 0, 673,
- 0, 1138, 0, 0, 0, 885, 0, 0, 0, 611,
- 611, 0, 611, 0, 78, 78, 78, 0, 0, 902,
+ 51, 20, -525, 0, 1018, 0, 21, 0, 0, 0,
+ 23, 508, 0, 168, 7, 8, 9, 10, 0, 26,
+ 246, 27, 28, 0, 0, 509, 0, 510, 0, 0,
+ 0, 0, 0, 0, 0, 30, 0, 0, 0, 0,
+ 0, 0, 18, 642, 642, 31, 642, 0, 0, 0,
+ 0, 0, 21, 32, 0, 0, 0, 0, 33, 0,
+ 0, 0, 0, 0, 0, 26, 0, 27, 28, 0,
+ 575, 0, 0, 0, -525, 0, 0, 145, 145, 0,
+ 145, 193, 0, 0, 0, 0, 0, 396, 0, 0,
+ 0, 194, 0, 0, 0, 254, 0, 0, 0, 32,
+ 51, 0, 0, 0, 195, 1425, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 145, 651, 145, 595,
+ 596, 597, 598, 599, 600, 601, 602, 603, 604, 605,
+ 606, 607, 608, 609, 396, 248, 0, 0, 0, 0,
+ 0, 1018, 0, 0, 0, 51, 0, 0, 0, 506,
+ 0, 7, 8, 507, 10, 167, 12, 13, 0, 0,
+ 51, 0, 14, 51, 0, 0, 0, 0, 0, 431,
+ 431, 431, 0, 0, 0, 51, 16, 0, 17, 18,
+ 19, 0, 0, 51, 20, -526, 0, 0, 0, 21,
+ 0, 0, 0, 23, 508, 0, 168, 0, 0, 0,
+ 0, 0, 26, 0, 27, 28, 0, 0, 509, 0,
+ 510, 51, 0, 51, 0, 152, 152, 152, 30, 0,
+ 945, 51, 0, 0, 0, 0, 51, 0, 31, 51,
+ 0, 0, 1233, 1234, 9, 10, 32, 0, 0, 0,
+ 0, 33, 0, 8, 9, 0, 0, 12, 13, 0,
+ 0, 0, 51, 14, 51, 0, 0, -526, 0, 51,
+ 51, 0, 51, 0, 0, 0, 0, 16, 0, 17,
+ 21, 0, 0, 0, 0, 20, 0, 0, 0, 0,
+ 0, 0, 0, 26, 23, 27, 28, 945, 945, 945,
+ 0, 1235, 0, 26, 575, 130, 131, 575, 0, 193,
+ 0, 0, 0, 248, 0, 0, 0, 0, 145, 194,
+ 0, 0, 575, 575, 575, 0, 0, 32, 0, 78,
+ 0, 0, 195, 0, 0, 0, 0, 575, 0, 0,
+ 0, 7, 8, 9, 10, 0, 6, 13, 7, 8,
+ 9, 10, 11, 12, 13, 78, 78, 0, 78, 14,
+ 78, 0, 0, 0, 0, 0, 0, 78, 0, 18,
+ 0, 0, 15, 16, 0, 17, 18, 19, 0, 21,
+ 78, 20, 78, 0, 0, 254, 21, 0, 0, 22,
+ 23, 24, 26, 25, 27, 28, 0, 0, 575, 26,
+ 0, 27, 28, 0, 0, 29, 0, 0, 474, 0,
+ 0, 0, 0, 0, 0, 30, 0, 51, 475, 0,
+ 0, 0, 0, 0, 0, 31, 32, 0, 0, 0,
+ 0, 476, 0, 32, 0, 0, 0, 0, 33, 0,
+ 0, 396, 0, 34, 0, 0, 0, 159, 396, 0,
+ 0, 0, 0, 0, 0, 0, 51, 51, 51, 51,
+ 0, 78, 0, 0, 0, 78, 78, 0, 0, 204,
+ 0, 78, 0, 0, 78, 78, 78, 0, 0, 0,
+ 0, 0, 0, 0, 795, 796, 9, 10, 0, 0,
+ 78, 0, 0, 0, 78, 7, 8, 9, 10, 0,
+ 78, 78, 0, 51, 0, 0, 0, 51, 0, 0,
+ 0, 0, 0, 0, 51, 51, 0, 51, 78, 78,
+ 78, 0, 21, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 21, 0, 26, 51, 27, 28, 0,
+ 0, 1060, 0, 797, 0, 0, 26, 78, 27, 28,
+ 0, 193, 192, 0, 0, 0, 0, 254, 0, 0,
+ 0, 194, 193, 159, 159, 159, 51, 0, 0, 32,
+ 78, 0, 194, 0, 195, 0, 0, 0, 0, 0,
+ 32, 0, 0, 0, 78, 195, 0, 0, 0, 204,
+ 0, 748, 575, 300, 8, 9, 10, 167, 12, 301,
+ 302, 303, 749, 304, 14, 0, 0, 204, 204, 478,
+ 0, 0, 0, 0, 0, 0, 0, 0, 16, 305,
+ 17, 18, 19, 0, 306, 307, 20, 0, 308, 309,
+ 310, 21, 311, 312, 0, 23, 204, 0, 0, 313,
+ 314, 315, 316, 317, 26, 0, 27, 319, 0, 0,
+ 0, 320, 0, 0, 0, 0, 0, 321, 0, 0,
+ 322, 0, 0, 0, 0, 0, 0, 0, 323, 324,
+ 325, 0, 0, 0, 0, 0, 326, 327, 328, 0,
+ 659, 0, 0, 329, 78, 0, 0, 0, 575, 575,
+ 575, 0, 0, 0, 431, 254, 0, 0, -798, 0,
+ 330, 0, 0, 7, 8, 9, 10, 205, 12, 206,
+ 0, 0, 548, 0, 14, 597, 598, 599, 600, 601,
+ 602, 603, 604, 605, 606, 607, 608, 609, 16, 78,
+ 17, 18, 51, 51, 152, 0, 20, 0, 0, 254,
+ 0, 21, 0, 0, 78, 23, 0, 78, 0, 0,
+ 0, 0, 0, 0, 26, 0, 27, 28, 0, 78,
+ 207, 0, 644, 644, 644, 0, 0, 78, 0, 0,
+ 30, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 31, 1204, 0, 0, 0, 0, 0, 0, 32, 0,
+ 0, 0, 0, 33, 0, 78, 0, 78, 0, 78,
+ 78, 78, 0, 0, 0, 78, 0, 0, 0, 0,
+ 78, 0, 0, 78, 0, 0, 0, 0, 204, 0,
+ 51, 0, 0, 0, 0, 51, 0, 0, 51, 7,
+ 8, 9, 10, 167, 12, 13, 78, 0, 78, 0,
+ 14, 0, 0, 78, 78, 0, 78, 0, 0, 0,
+ 0, 0, 0, 0, 16, 0, 17, 18, 0, 0,
+ 0, 0, 20, 0, 0, 0, 0, 21, 0, 0,
+ 0, 23, 0, 0, 0, 0, 0, 0, 0, 0,
+ 26, 0, 27, 28, 204, 0, 204, 0, 478, 478,
+ 478, 0, 0, 0, 204, 0, 30, 0, 0, 204,
+ 254, 0, 204, 0, 0, 0, 31, 0, 0, 0,
+ 0, 0, 0, 0, 32, 0, 0, 0, 0, 33,
+ 0, 51, 51, 152, 152, 152, 0, 254, 0, 51,
+ 0, 0, 204, 0, 870, 0, 300, 8, 9, 10,
+ 0, 12, 552, 302, 303, 0, 304, 14, 0, 0,
+ 0, 0, 1204, 1204, 1204, 0, 0, 0, 0, 0,
+ 659, 16, 305, 17, 0, 19, 0, 306, 307, 20,
+ 0, 308, 309, 310, 21, 311, 312, 0, 23, 0,
+ 0, 0, 313, 314, 315, 316, 317, 26, 0, 27,
+ 319, 78, 0, 0, 320, -788, 0, 0, 0, 0,
+ 321, 0, 0, 322, 0, 0, 0, 0, 0, 0,
+ 0, 323, 324, 325, 0, 0, 202, 0, 0, 326,
+ 327, 328, 0, 0, 0, 0, 329, 0, 0, 0,
+ 78, 78, 78, 78, 0, 0, 0, 906, 0, 0,
+ 0, 257, 0, 330, 261, 0, 51, 51, 0, 51,
+ 0, 644, 644, 0, 644, 0, 0, 0, 0, 0,
+ 0, 644, 0, 0, 0, 257, 0, 365, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 78, 0, 0,
+ 204, 78, 0, 0, 0, 51, 51, 51, 78, 78,
+ 0, 78, 592, 593, 594, 595, 596, 597, 598, 599,
+ 600, 601, 602, 603, 604, 605, 606, 607, 608, 609,
+ 78, 0, 0, 0, 0, 0, 0, 0, 0, 985,
+ 0, 985, 985, 0, 644, 0, 0, 0, 0, 0,
+ 0, 7, 8, 9, 10, 0, 202, 535, 0, 0,
+ 78, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 202, 202, 202, 0, 0, 18,
+ 0, 0, 0, 0, 484, 0, 985, 0, 0, 21,
+ 0, 0, 0, 0, 0, 0, 0, 204, 204, 0,
+ 204, 0, 26, 202, 27, 28, 0, 0, 0, 1204,
+ 0, 0, 0, 0, 0, 0, 0, 0, 193, 204,
+ 0, 7, 8, 9, 10, 167, 12, 13, 194, 261,
+ 1035, 0, 14, 0, 0, 0, 32, 0, 0, 0,
+ 0, 195, 0, 257, 0, 0, 16, 0, 17, 18,
+ 0, 0, 0, 0, 20, 0, 0, 0, 0, 21,
+ 0, 0, 0, 23, 0, 0, 0, 0, 0, 548,
+ 548, 548, 26, 0, 27, 28, 1204, 1204, 1204, 0,
+ 0, 644, 0, 0, 0, 0, 0, 0, 30, 0,
+ 659, 0, 0, 0, 0, 0, 0, 51, 31, 0,
+ 0, 0, 0, 0, 0, 0, 32, 0, 0, 0,
+ 0, 33, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 78, 78, 78, 0,
+ 0, 0, 0, 0, 0, 257, 261, 0, 0, 0,
+ 0, 7, 8, 9, 10, 205, 12, 206, 0, 0,
+ 0, 0, 14, 0, 644, 0, 644, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 16, 644, 17, 18,
+ 0, 644, 644, 644, 20, 1206, 0, 0, 0, 21,
+ 0, 0, 0, 23, 0, 202, 0, 0, 0, 0,
+ 0, 0, 26, 0, 27, 28, 0, 0, 1435, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 30, 0,
+ 0, 0, 0, 0, 78, 985, 985, 1177, 31, 78,
+ 0, 0, 78, 0, 0, 0, 32, 0, 0, 0,
+ 0, 33, 0, 0, 0, 7, 8, 9, 10, 205,
+ 12, 206, 0, 0, 0, 0, 14, 0, 0, 0,
+ 0, 202, 0, 202, 0, 202, 202, 202, 0, 0,
+ 16, 202, 17, 18, 1177, 0, 202, 0, 20, 202,
+ 0, 0, 0, 21, 0, 0, 0, 23, 0, 0,
+ 0, 0, 0, 0, 0, 0, 26, 0, 27, 28,
+ 0, 102, 0, 0, 0, 0, 0, 0, 0, 202,
+ 121, 102, 30, 204, 0, 0, 0, 102, 102, 0,
+ 102, 1489, 31, 0, 0, 78, 78, 78, 78, 78,
+ 32, 0, 0, 78, 0, 33, 594, 595, 596, 597,
+ 598, 599, 600, 601, 602, 603, 604, 605, 606, 607,
+ 608, 609, 235, 0, 0, 0, 1206, 1206, 1206, 0,
+ 0, 0, 0, 0, 0, 0, 906, 906, 0, 906,
+ 0, 1490, 588, 589, 590, 591, 592, 593, 594, 595,
+ 596, 597, 598, 599, 600, 601, 602, 603, 604, 605,
+ 606, 607, 608, 609, 593, 594, 595, 596, 597, 598,
+ 599, 600, 601, 602, 603, 604, 605, 606, 607, 608,
+ 609, 389, 0, 121, 985, 985, 1177, 1177, 1177, 0,
+ 102, 102, 985, 0, 0, 0, 0, 102, 102, 0,
+ 0, 102, 102, 102, 0, 417, 102, 102, 102, 0,
+ 0, 257, 261, 0, 0, 1177, 1177, 1177, 0, 0,
+ 78, 78, 0, 78, 0, 0, 0, 202, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 1233, 127,
+ 128, 10, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 78,
+ 78, 78, 0, 0, 0, 0, 202, 0, 202, 202,
+ 0, 0, 0, 0, 0, 0, 21, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 26,
+ 0, 27, 28, 0, 0, 235, 102, 1235, 0, 0,
+ 0, 0, 0, 0, 0, 30, 0, 0, 0, 985,
+ 985, 0, 985, 202, 0, 31, 102, 0, 0, 0,
+ 0, 0, 0, 32, 202, 202, 0, 202, 33, 0,
+ 0, 570, 0, 300, 8, 9, 10, 167, 12, 301,
+ 302, 303, 749, 304, 14, 0, 202, 0, 204, 0,
+ 204, 0, 0, 0, 0, 102, 0, 0, 16, 305,
+ 17, 18, 19, 1206, 306, 307, 20, 484, 308, 309,
+ 310, 21, 311, 312, 0, 23, 0, 636, 0, 313,
+ 314, 315, 316, 317, 26, 0, 27, 319, -312, 0,
+ 0, 320, 0, 0, 0, 0, 0, 321, 0, 0,
+ 937, 0, 0, 102, 0, 102, 102, 0, 323, 324,
+ 938, 7, 8, 9, 10, 0, 326, 327, 328, 0,
+ 639, 0, 0, 939, 641, 0, 0, 0, 0, 0,
+ 1206, 1206, 1206, 7, 8, 9, 10, 0, 0, 18,
+ 330, 0, 0, 0, 0, 0, 0, 0, 0, 21,
+ 102, 78, 478, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 26, 0, 27, 28, 0, 0, 0, 102,
+ 0, 21, 0, 0, 0, 0, 102, 0, 474, 102,
+ 0, 0, 0, 0, 26, 0, 27, 28, 475, 0,
+ 1432, 102, 0, 0, 0, 0, 32, 0, 0, 0,
+ 193, 476, 0, 0, 0, 257, 261, 257, 0, 0,
+ 194, 0, 0, 0, 0, 0, 0, 0, 32, 478,
+ 478, 478, 0, 195, 0, 0, 0, 0, 8, 9,
+ 0, 205, 12, 206, 7, 8, 9, 10, 14, 0,
+ 204, 0, 202, 202, 1175, 0, 0, 0, 0, 257,
+ 0, 0, 16, 0, 17, 18, 0, 0, 0, 102,
+ 20, 0, 0, 0, 0, 102, 0, 0, 0, 23,
+ 0, 0, 21, 0, 0, 0, 0, 0, 26, 261,
+ 130, 131, 0, 0, 0, 26, 0, 27, 28, 0,
+ 0, 1175, 1460, 0, -479, -479, -479, -479, -479, -479,
+ -479, 193, 0, -479, 102, -479, 0, 0, 0, 0,
+ 0, 194, 0, 0, 0, 0, -479, 0, -479, 32,
+ 0, 0, -479, 0, 195, 0, 0, -479, 0, 0,
+ 202, 0, -479, 0, 0, 0, -479, 0, -479, 0,
+ 0, 0, 0, 0, 0, -479, 0, -479, -479, -479,
+ -479, -479, 0, -479, -479, -479, -479, -479, -479, -479,
+ -479, -479, -479, -479, -479, -479, -479, -479, -479, -479,
+ -479, -479, -479, -479, -479, -479, 0, -479, -479, -479,
+ 102, -479, -479, -479, -479, -479, -479, 0, -479, 0,
+ 0, 102, 102, 1461, 102, 102, 0, 0, -479, -479,
+ -479, 0, -479, 0, 0, 0, 0, 0, 0, 0,
+ 257, 0, 0, 0, 0, 0, 0, 8, 9, 0,
+ 167, 12, 13, 0, 0, 0, 0, 14, 0, 0,
+ 0, 202, 202, 202, 202, 1175, 0, 1297, 0, 202,
+ 0, 16, 0, 17, 18, 0, 0, 102, 0, 20,
+ 0, 0, 0, 0, 102, 121, 0, 0, 698, 0,
+ 0, 168, 1175, 1175, 1175, 0, 235, 26, 0, 130,
+ 131, 0, 0, 0, 0, 1440, 0, 1308, 1309, 1310,
+ 10, 167, 12, 301, 302, 303, 0, 304, 14, 1311,
+ 1015, 1312, 1313, 1314, 1315, 1316, 1317, 1318, 1319, 1320,
+ 1321, 15, 16, 305, 17, 18, 19, 0, 306, 307,
+ 20, 0, 308, 309, 310, 21, 311, 312, 1322, 23,
+ 1323, 0, 0, 313, 314, 315, 316, 317, 26, 0,
+ 1324, 319, 736, 0, 1325, 320, 0, 1015, 0, 0,
+ 0, 321, 0, 0, 322, 0, 0, 0, 0, 0,
+ 0, 0, 323, 324, 325, 0, 202, 202, 0, 202,
+ 326, 327, 328, 0, 102, 0, 0, 329, 0, 1326,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 945, 945, 1147, 1147,
- 1147, 0, 0, 0, 945, 0, 0, 885, 0, 0,
- 198, 198, 0, 198, 0, 0, 0, 0, 0, 0,
- 1180, 0, 0, 637, 0, 0, 1186, 1147, 1147, 1147,
- 0, 0, 0, 719, 0, 0, 0, 611, 0, 611,
- 611, 0, 611, 0, 0, 719, 0, 0, 0, 198,
- 0, 198, 0, 102, 0, 0, 0, 0, 200, 1056,
- 0, 1058, 121, 102, 0, 0, 0, 0, 0, 102,
- 102, 0, 102, 0, 0, 0, 0, 0, 0, 719,
- 0, 719, 688, 611, 0, 689, 1176, 0, 0, 0,
- 691, 0, 0, 0, 0, 0, 0, 0, 76, 0,
- 0, 0, 0, 0, 231, 0, 0, 0, 0, 1233,
- 0, 0, 0, 945, 945, 0, 945, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 406, 0, 408, 0,
- 0, 0, 0, 1092, 1093, 0, 1095, 0, 0, 0,
- 0, 505, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 200, 0, 200, 0, 1176, 1176, 1176, 0,
- 777, 1145, 0, 385, 1113, 121, 885, 0, 0, 0,
- 0, 611, 102, 102, 0, 0, 0, 0, 0, 102,
- 78, 102, 102, 102, 0, 412, 102, 102, 102, 8,
- 9, 0, 163, 12, 13, 885, 0, 1530, 0, 14,
+ 0, 0, 0, 1441, 330, 0, 0, 0, 0, 0,
+ 0, 0, 102, 102, 102, 202, 0, 202, 0, 0,
+ 0, 0, 0, 0, 102, 0, 1307, 0, 1308, 1309,
+ 1310, 10, 167, 12, 301, 302, 303, 0, 304, 14,
+ 1311, 0, 1312, 1313, 1314, 1315, 1316, 1317, 1318, 1319,
+ 1320, 1321, 15, 16, 305, 17, 18, 19, 0, 306,
+ 307, 20, 0, 308, 309, 310, 21, 311, 312, 1322,
+ 23, 1323, 0, 0, 313, 314, 315, 316, 317, 26,
+ 0, 1324, 319, 736, 0, 1325, 320, 0, 0, 0,
+ 0, 0, 321, 0, 0, 322, 0, 102, 0, 102,
+ 0, 0, 0, 323, 324, 325, 18, 0, 0, 0,
+ 102, 326, 327, 328, 0, 0, 0, 0, 329, 1175,
+ 1326, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 330, 0, 0, 588, 589,
+ 590, 591, 592, 593, 594, 595, 596, 597, 598, 599,
+ 600, 601, 602, 603, 604, 605, 606, 607, 608, 609,
+ 0, 0, 0, 0, 0, 8, 9, 0, 167, 12,
+ 13, 0, 0, 749, 0, 14, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 1175, 1175, 1175, 16,
+ 0, 17, 18, 0, 0, 1015, 0, 20, 0, 0,
+ 0, 0, 0, 0, 0, 0, 23, 202, 0, 0,
+ 0, 0, 0, 0, 0, 26, 0, 130, 131, 0,
+ 0, 0, 0, 0, 0, 0, 570, 0, 7, 8,
+ 9, 10, 167, 12, 301, 302, 303, 749, 304, 14,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 102,
+ 0, 102, 0, 16, 305, 17, 18, 19, 0, 306,
+ 307, 20, 0, 308, 309, 310, 21, 311, 312, 0,
+ 23, 0, 636, 0, 313, 314, 315, 316, 317, 26,
+ 0, 27, 28, -312, 0, 0, 320, 0, 0, 0,
+ 0, 0, 321, 0, 0, 1201, 0, 0, 0, 102,
+ 102, 0, 102, 323, 324, 1202, 0, 0, 0, 0,
+ 0, 326, 327, 328, 0, 639, 0, 0, 1203, 641,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 16, 1148, 17, 18, 0, 0, 0,
- 0, 20, 0, 0, 0, 0, 0, 0, 0, 0,
- 23, 1145, 1145, 1145, 0, 0, 0, 0, 0, 26,
- 0, 130, 131, 0, 611, 0, 611, 0, 0, 0,
- 0, 0, 0, 0, 0, 198, 0, 611, 0, 0,
- 0, 902, 902, 902, 466, 7, 8, 9, 10, 163,
- 12, 13, 487, 102, 990, 0, 14, 0, 0, 1191,
+ 0, 0, 0, 0, 0, 330, 870, 0, 300, 8,
+ 9, 10, 167, 12, 301, 302, 303, 0, 304, 14,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 16, 1196, 17, 18, 102, 0, 0, 0, 20, 0,
- 0, 0, 0, 21, 611, 611, 611, 23, 0, 0,
- 0, 0, 0, 0, 0, 0, 26, 0, 27, 28,
- 8, 9, 0, 201, 12, 202, 0, 0, 0, 0,
- 14, 0, 30, 102, 466, 466, 466, 1180, 0, 0,
- 0, 0, 31, 947, 16, 0, 17, 18, 902, 0,
- 32, 0, 20, 0, 0, 33, 0, 0, 200, 0,
- 0, 23, 0, 0, 0, 0, 0, 0, 0, 0,
- 26, 0, 130, 131, 0, 0, 0, 1247, 0, 0,
- 0, 102, 0, 102, 102, 1024, 8, 761, 10, 201,
- 12, 202, 991, 0, 0, 0, 14, 0, 0, 688,
- 689, 0, 691, 0, 0, 0, 0, 0, 0, 0,
- 16, 0, 17, 18, 0, 0, 1260, 0, 20, 0,
- 0, 0, 0, 21, 0, 0, 0, 23, 102, 0,
- 0, 0, 0, 777, 0, 777, 26, 0, 27, 28,
- 1034, 1041, 777, 0, 1026, 0, 102, 0, 777, 0,
- 0, 0, 30, 102, 0, 0, 102, 0, 0, 0,
- 0, 102, 31, 0, 0, 0, 0, 0, 0, 0,
- 32, 0, 0, 0, 0, 33, 0, 0, 0, 1347,
- 0, 0, 0, 1348, 0, 0, 0, 0, 0, 7,
- 8, 9, 10, 163, 12, 13, 0, 0, 0, 0,
- 14, 0, 547, 611, 611, 611, 611, 611, 0, 0,
- 0, 611, 0, 0, 16, 0, 17, 18, 1364, 673,
- 0, 0, 20, 0, 0, 0, 0, 21, 102, 0,
- 752, 23, 0, 0, 902, 902, 902, 0, 0, 0,
- 26, 0, 27, 28, 0, 0, 760, 0, 7, 8,
- 761, 10, 163, 12, 13, 102, 30, 0, 0, 14,
- 0, 0, 0, 0, 0, 0, 31, 0, 0, 0,
- 0, 0, 0, 16, 32, 17, 18, 19, 0, 33,
- 0, 20, -521, 0, 0, 0, 21, 0, 0, 0,
- 23, 762, 1420, 164, 0, 0, 1421, 0, 0, 26,
- 0, 27, 28, 0, 0, 763, 1462, 764, 0, 141,
- 145, 0, 0, 0, 0, 30, 0, 0, 1439, 1440,
- 611, 611, 0, 611, 0, 31, 0, 0, 0, 0,
- 0, 102, 0, 32, 0, 0, 0, 0, 33, 0,
- 0, 0, 102, 102, 0, 102, 102, 0, 0, 0,
- 0, 0, 0, 0, -521, 0, 1463, 557, 558, 559,
- 560, 561, 562, 563, 564, 565, 566, 567, 568, 569,
- 570, 571, 572, 573, 574, 575, 576, 577, 578, 0,
- 0, 0, 1034, 0, 0, 0, 0, 0, 0, 1433,
- 0, -475, -475, -475, -475, -475, -475, -475, 102, 0,
- -475, 0, -475, 0, 0, 102, 121, 0, 0, 0,
- 0, 0, 0, -475, 0, -475, 777, 231, 0, -475,
- 0, 0, 0, 0, -475, 0, 0, 0, 0, -475,
- 0, 0, 0, -475, 0, -475, 0, 0, 0, 0,
- 752, 0, -475, 0, -475, -475, -475, -475, -475, 0,
- -475, -475, -475, -475, -475, -475, -475, -475, -475, -475,
- -475, -475, -475, -475, -475, -475, -475, -475, -475, -475,
- -475, -475, -475, 0, -475, -475, -475, 0, -475, -475,
- -475, -475, -475, -475, 0, -475, 0, 0, 0, 0,
- 1434, 0, 0, 0, 0, -475, -475, -475, 752, -475,
- 0, 102, 0, 0, 0, 0, 0, 0, 406, 408,
- 0, 0, 0, 0, 0, 0, 505, 0, 0, 0,
+ 0, 0, 1015, 16, 305, 17, 18, 19, 0, 306,
+ 307, 20, 0, 308, 309, 310, 21, 311, 312, 0,
+ 23, 0, 0, 0, 313, 314, 315, 316, 317, 26,
+ 0, 27, 319, 1531, 0, -788, 320, 0, 0, 1015,
+ 0, 0, 321, 0, 0, 322, 0, 0, 0, 0,
+ 0, 0, 0, 323, 324, 325, 0, 0, 0, 0,
+ 0, 326, 327, 328, 0, 0, 0, 0, 329, 739,
+ 0, 858, 859, 860, 10, 0, 12, 552, 302, 303,
+ 0, 304, 14, 0, 0, 330, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 16, 305, 17, 0,
+ 19, 0, 306, 307, 20, 0, 308, 309, 310, 21,
+ 311, 312, 0, 23, 0, 0, 0, 313, 314, 315,
+ 316, 317, 26, 0, 861, 862, 740, 0, 0, 320,
+ 0, 0, 0, 0, 0, 321, 0, 0, 322, 0,
+ 0, 0, 0, 0, 0, 0, 323, 324, 325, 0,
+ 0, 0, 0, 0, 326, 327, 328, 0, 0, 0,
+ 0, 329, 863, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 1015, 1022, 330, 570,
+ 0, 300, 8, 9, 10, 0, 12, 301, 302, 303,
+ 0, 304, 14, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 16, 305, 17, 18,
+ 19, 0, 306, 307, 20, 0, 308, 309, 310, 21,
+ 311, 312, 0, 23, 0, 0, 0, 313, 314, 315,
+ 316, 317, 26, 0, 27, 319, -312, 0, 0, 320,
+ 0, 0, 0, 0, 0, 321, 0, 0, 571, 0,
+ 0, 0, 0, 0, 0, 0, 323, 324, 572, 0,
+ 0, 0, 0, 0, 326, 327, 328, 0, 0, 0,
+ 739, 573, 858, 859, 860, 10, 0, 12, 552, 302,
+ 303, 0, 304, 14, 0, 0, 0, 0, 330, 0,
+ 0, 0, 0, 0, 0, 0, 0, 16, 305, 17,
+ 0, 19, 0, 306, 307, 20, 0, 308, 309, 310,
+ 21, 311, 312, 0, 23, 0, 0, 0, 313, 314,
+ 315, 316, 317, 26, 0, 861, 862, 740, 0, 0,
+ 320, 0, 0, 0, 0, 0, 321, 0, 0, 322,
+ 0, 0, 0, 0, 0, 0, 0, 323, 324, 325,
+ 0, 0, 0, 0, 0, 326, 327, 328, 0, 0,
+ 0, 0, 329, 863, 739, 0, 858, 859, 860, 10,
+ 0, 12, 552, 302, 303, 0, 304, 14, 0, 330,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 102, 102, 102, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 102, 0, 0,
- 0, 0, 539, 0, 296, 8, 9, 10, 163, 12,
- 297, 298, 299, 717, 300, 14, 0, 0, 0, 0,
- 1339, 0, 0, 0, 0, 1339, 0, 0, 0, 16,
- 301, 17, 18, 19, 0, 302, 303, 20, 0, 304,
- 305, 306, 21, 307, 308, 0, 23, 0, 605, 0,
- 309, 310, 311, 312, 313, 26, 0, 27, 315, -308,
- 0, 0, 316, 0, 0, 0, 0, 0, 317, 0,
- 102, 898, 102, 0, 0, 688, 689, 0, 691, 319,
- 320, 899, 0, 102, 0, 0, 0, 322, 323, 324,
- 0, 608, 0, 0, 900, 610, 0, 0, 0, 0,
- 1410, 0, 1270, 1271, 1272, 10, 163, 12, 297, 298,
- 299, 326, 300, 14, 1273, 1407, 1274, 1275, 1276, 1277,
- 1278, 1279, 1280, 1281, 1282, 1283, 15, 16, 301, 17,
- 18, 19, 0, 302, 303, 20, 0, 304, 305, 306,
- 21, 307, 308, 1284, 23, 1285, 0, 0, 309, 310,
- 311, 312, 313, 26, 0, 1286, 315, 704, 0, 1287,
- 316, 0, 0, 0, 0, 0, 317, 0, 0, 318,
- 0, 0, 0, 0, 0, 0, 0, 319, 320, 321,
- 0, 0, 0, 0, 0, 322, 323, 324, 0, 0,
- 0, 0, 325, 0, 1288, 0, 0, 0, 752, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 1411, 326,
- 1269, 0, 1270, 1271, 1272, 10, 163, 12, 297, 298,
- 299, 0, 300, 14, 1273, 102, 1274, 1275, 1276, 1277,
- 1278, 1279, 1280, 1281, 1282, 1283, 15, 16, 301, 17,
- 18, 19, 0, 302, 303, 20, 0, 304, 305, 306,
- 21, 307, 308, 1284, 23, 1285, 0, 0, 309, 310,
- 311, 312, 313, 26, 0, 1286, 315, 704, 0, 1287,
- 316, 0, 0, 0, 0, 0, 317, 0, 0, 318,
- 0, 102, 102, 0, 102, 0, 0, 319, 320, 321,
- 0, 0, 0, 0, 0, 322, 323, 324, 0, 0,
- 0, 0, 325, 0, 1288, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 326,
- 0, 0, 539, 0, 7, 8, 9, 10, 163, 12,
- 297, 298, 299, 717, 300, 14, 0, 0, 0, 0,
- 0, 0, 0, 0, 752, 0, 0, 0, 0, 16,
- 301, 17, 18, 19, 0, 302, 303, 20, 0, 304,
- 305, 306, 21, 307, 308, 0, 23, 0, 605, 0,
- 309, 310, 311, 312, 313, 26, 752, 27, 28, -308,
- 0, 0, 316, 0, 0, 0, 0, 0, 317, 0,
- 0, 1171, 0, 0, 102, 0, 102, 0, 0, 319,
- 320, 1172, 0, 0, 0, 0, 0, 322, 323, 324,
- 0, 608, 0, 0, 1173, 610, 716, 0, 296, 8,
- 9, 10, 163, 12, 297, 298, 299, 717, 300, 14,
- 0, 326, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 16, 301, 17, 18, 19, 0, 302,
- 303, 20, 0, 304, 305, 306, 21, 307, 308, 0,
- 23, 0, 0, 0, 309, 310, 311, 312, 313, 26,
- 0, 27, 315, 0, 0, 0, 316, 0, 0, 0,
- 0, 0, 317, 0, 0, 318, 0, 0, 0, 0,
- 0, 0, 0, 319, 320, 321, 0, 0, 0, 0,
- 0, 322, 323, 324, 0, 0, 0, 831, 325, 296,
- 8, 9, 10, 163, 12, 297, 298, 299, 0, 300,
- 14, 0, 0, -792, 0, 326, 0, 0, 0, 0,
- 0, 0, 0, 0, 16, 301, 17, 18, 19, 0,
- 302, 303, 20, 0, 304, 305, 306, 21, 307, 308,
- 0, 23, 0, 0, 0, 309, 310, 311, 312, 313,
- 26, 0, 27, 315, 1507, 0, -782, 316, 0, 0,
- 0, 0, 0, 317, 0, 0, 318, 0, 0, 0,
- 0, 0, 0, 0, 319, 320, 321, 0, 0, 0,
- 0, 0, 322, 323, 324, 0, 0, 0, 707, 325,
- 819, 820, 821, 10, 0, 12, 521, 298, 299, 0,
- 300, 14, 0, 0, 0, 0, 326, 0, 0, 0,
- 0, 0, 0, 0, 0, 16, 301, 17, 0, 19,
- 0, 302, 303, 20, 0, 304, 305, 306, 21, 307,
- 308, 0, 23, 0, 0, 0, 309, 310, 311, 312,
- 313, 26, 0, 822, 823, 708, 0, 0, 316, 0,
- 0, 0, 0, 0, 317, 0, 0, 318, 0, 0,
- 0, 0, 0, 0, 0, 319, 320, 321, 0, 0,
- 0, 0, 0, 322, 323, 324, 0, 0, 0, 0,
- 325, 824, 707, 0, 819, 820, 821, 10, 0, 12,
- 521, 298, 299, 0, 300, 14, 977, 326, 0, 0,
+ 0, 16, 305, 17, 0, 19, 0, 306, 307, 20,
+ 0, 308, 309, 310, 21, 311, 312, 0, 23, 0,
+ 0, 0, 313, 314, 315, 316, 317, 26, 0, 861,
+ 862, 740, 0, 0, 320, 0, 0, 0, 0, 0,
+ 321, 0, 0, 322, 0, 0, 0, 0, 0, 0,
+ 0, 323, 324, 325, 0, 0, 0, 0, 0, 326,
+ 327, 328, 0, 0, 0, 739, 329, 858, 859, 860,
+ 10, 0, 12, 552, 302, 303, 0, 304, 14, 0,
+ 0, 0, -483, 330, 0, 0, 0, 0, 0, 0,
+ 0, 0, 16, 305, 17, 0, 19, 0, 306, 307,
+ 20, 0, 308, 309, 310, 21, 311, 312, 0, 23,
+ 0, 0, 0, 313, 314, 315, 316, 317, 26, 0,
+ 861, 862, 740, 0, 0, 320, 0, 0, 0, 0,
+ 0, 321, 0, 0, 322, 0, 0, 0, 0, 0,
+ 0, 0, 323, 324, 325, 0, 0, 0, 0, 0,
+ 326, 327, 328, 0, 0, 0, 739, 329, 300, 8,
+ 9, 10, 0, 12, 552, 302, 303, 0, 304, 14,
+ 0, 0, 0, 1346, 330, 0, 0, 0, 0, 0,
+ 0, 0, 0, 16, 305, 17, 0, 19, 0, 306,
+ 307, 20, 0, 308, 309, 310, 21, 311, 312, 0,
+ 23, 0, 0, 0, 313, 314, 315, 316, 317, 26,
+ 0, 27, 319, 740, 0, 0, 320, 0, 0, 0,
+ 0, 0, 321, 0, 0, 322, 0, 0, 0, 0,
+ 0, 0, 0, 323, 324, 325, 0, 0, 0, 0,
+ 0, 326, 327, 328, 0, 0, 0, 0, 329, 0,
+ 570, 0, 7, 8, 9, 10, 1350, 12, 301, 302,
+ 303, 0, 304, 14, 0, 330, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 16, 305, 17,
+ 18, 19, 0, 306, 307, 20, 0, 308, 309, 310,
+ 21, 311, 312, 0, 23, 0, 0, 0, 313, 314,
+ 315, 316, 317, 26, 0, 27, 28, -312, 0, 0,
+ 320, 0, 0, 0, 0, 0, 321, 0, 0, 1505,
+ 0, 0, 0, 0, 0, 0, 0, 323, 324, 1506,
+ 0, 0, 0, 0, 0, 326, 327, 328, 0, 0,
+ 0, 739, 1507, 300, 8, 9, 10, 0, 12, 552,
+ 302, 303, 0, 304, 14, 0, 0, 0, 0, 330,
+ 0, 0, 0, 0, 0, 0, 0, 0, 16, 305,
+ 17, 0, 19, 0, 306, 307, 20, 0, 308, 309,
+ 310, 21, 311, 312, 0, 23, 0, 0, 0, 313,
+ 314, 315, 316, 317, 26, 0, 27, 319, 740, 0,
+ 0, 320, 0, 0, 0, 0, 0, 321, 0, 0,
+ 322, 0, 0, 0, 0, 0, 0, 0, 323, 324,
+ 325, 0, 0, 0, 0, 0, 326, 327, 328, 0,
+ 0, 0, 1579, 329, 300, 8, 9, 10, 0, 12,
+ 301, 302, 303, 0, 304, 14, 0, 0, 0, 0,
+ 330, 0, 0, 0, 0, 0, 0, 0, 0, 16,
+ 305, 17, 0, 19, 0, 306, 307, 20, 0, 308,
+ 309, 310, 21, 311, 312, 0, 23, 0, 0, 0,
+ 313, 314, 315, 316, 317, 26, 0, 27, 319, 0,
+ 0, -196, 320, 0, 0, 0, 0, 0, 321, 0,
+ 0, 322, 0, 0, 0, 0, 0, 0, 0, 323,
+ 324, 325, 0, 0, 0, 0, 0, 326, 327, 328,
+ 0, 0, 0, 870, 329, 300, 8, 9, 10, 0,
+ 12, 552, 302, 303, 0, 304, 14, 0, 0, 0,
+ 0, 330, 0, 0, 0, 0, 0, 0, 0, 0,
+ 16, 305, 17, 0, 19, 0, 306, 307, 20, 0,
+ 308, 309, 310, 21, 311, 312, 0, 23, 0, 0,
+ 0, 313, 314, 315, 316, 317, 26, 0, 27, 319,
+ 0, 0, 0, 320, 0, 0, 0, 0, 0, 321,
+ 263, 0, 322, 8, 9, 0, 0, 12, 13, 0,
+ 323, 324, 325, 14, 0, 0, 0, 0, 326, 327,
+ 328, 0, 0, 0, 0, 329, 0, 16, 0, 17,
+ 0, 0, 0, 0, 0, 20, 0, 264, 265, 0,
+ -788, 0, 330, 0, 23, 0, 266, 0, 0, 0,
+ 0, 0, 0, 26, 0, 130, 131, 0, 267, 0,
+ 0, 0, 268, 269, 270, 271, 272, 273, 274, 275,
+ 276, 277, 278, 279, 280, 281, 282, 283, 284, 285,
+ 286, 287, 288, 0, 0, 289, 290, 291, 0, 0,
+ 292, 0, 959, 293, 300, 8, 9, 10, 0, 12,
+ 552, 302, 303, 0, 304, 14, 0, 0, 0, 294,
0, 0, 0, 0, 0, 0, 0, 0, 0, 16,
- 301, 17, 0, 19, 0, 302, 303, 20, 0, 304,
- 305, 306, 21, 307, 308, 0, 23, 0, 0, 0,
- 309, 310, 311, 312, 313, 26, 0, 822, 823, 708,
- 0, 0, 316, 0, 0, 0, 0, 0, 317, 0,
- 0, 318, 0, 0, 0, 0, 0, 0, 0, 319,
- 320, 321, 0, 0, 0, 0, 0, 322, 323, 324,
- 0, 0, 0, 0, 325, 824, 707, 0, 819, 820,
- 821, 10, 0, 12, 521, 298, 299, 0, 300, 14,
- 0, 326, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 16, 301, 17, 0, 19, 0, 302,
- 303, 20, 0, 304, 305, 306, 21, 307, 308, 0,
- 23, 0, 0, 0, 309, 310, 311, 312, 313, 26,
- 0, 822, 823, 708, 0, 0, 316, 0, 0, 0,
- 0, 0, 317, 0, 0, 318, 0, 0, 0, 0,
- 0, 0, 0, 319, 320, 321, 0, 0, 0, 0,
- 0, 322, 323, 324, 0, 0, 0, 707, 325, 819,
- 820, 821, 10, 0, 12, 521, 298, 299, 0, 300,
- 14, 0, 0, 0, -479, 326, 0, 0, 0, 0,
- 0, 0, 0, 0, 16, 301, 17, 0, 19, 0,
- 302, 303, 20, 0, 304, 305, 306, 21, 307, 308,
- 0, 23, 0, 0, 0, 309, 310, 311, 312, 313,
- 26, 0, 822, 823, 708, 0, 0, 316, 0, 0,
- 0, 0, 0, 317, 0, 0, 318, 0, 0, 0,
- 0, 0, 0, 0, 319, 320, 321, 0, 0, 0,
- 0, 0, 322, 323, 324, 0, 0, 0, 707, 325,
- 296, 8, 9, 10, 0, 12, 521, 298, 299, 0,
- 300, 14, 0, 0, 0, 1308, 326, 0, 0, 0,
- 0, 0, 0, 0, 0, 16, 301, 17, 0, 19,
- 0, 302, 303, 20, 0, 304, 305, 306, 21, 307,
- 308, 0, 23, 0, 0, 0, 309, 310, 311, 312,
- 313, 26, 0, 27, 315, 708, 0, 0, 316, 0,
- 0, 0, 0, 0, 317, 0, 0, 318, 0, 0,
- 0, 0, 0, 0, 0, 319, 320, 321, 0, 0,
- 0, 0, 0, 322, 323, 324, 0, 0, 0, 0,
- 325, 0, 539, 0, 296, 8, 9, 10, 1312, 12,
- 297, 298, 299, 0, 300, 14, 0, 326, 0, 0,
+ 305, 17, 0, 19, 0, 306, 307, 20, 0, 308,
+ 309, 310, 21, 311, 312, 0, 23, 0, 0, 0,
+ 313, 314, 315, 316, 317, 26, 0, 27, 319, 0,
+ 0, 0, 320, 0, 0, 0, 0, 0, 321, 0,
+ 0, 322, 0, 0, 0, 0, 0, 0, 0, 323,
+ 324, 325, 0, 0, 0, 0, 0, 326, 327, 328,
+ 0, 0, 0, 961, 329, 300, 8, 9, 10, 0,
+ 12, 552, 302, 303, 0, 304, 14, 0, 0, 0,
+ 0, 330, 0, 0, 0, 0, 0, 0, 0, 0,
+ 16, 305, 17, 0, 19, 0, 306, 307, 20, 0,
+ 308, 309, 310, 21, 311, 312, 0, 23, 0, 0,
+ 0, 313, 314, 315, 316, 317, 26, 0, 27, 319,
+ 0, 0, 0, 320, 0, 0, 0, 0, 0, 321,
+ 0, 0, 322, 0, 0, 0, 0, 0, 0, 0,
+ 323, 324, 325, 0, 0, 0, 0, 0, 326, 327,
+ 328, 0, 0, 0, 1515, 329, 300, 8, 9, 10,
+ 0, 12, 552, 302, 303, 0, 304, 14, 0, 0,
+ 0, 0, 330, 0, 0, 0, 0, 0, 0, 0,
+ 0, 16, 305, 17, 0, 19, 0, 306, 307, 20,
+ 0, 308, 309, 310, 21, 311, 312, 0, 23, 0,
+ 0, 0, 313, 314, 315, 316, 317, 26, 0, 27,
+ 319, 0, 0, 0, 320, 0, 0, 0, 0, 0,
+ 321, 0, 0, 322, 0, 0, 0, 0, 0, 0,
+ 0, 323, 324, 325, 0, 0, 0, 0, 0, 326,
+ 327, 328, 300, 8, 9, 10, 329, 12, 552, 302,
+ 303, 0, 304, 14, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 330, 0, 0, 0, 16, 305, 17,
+ 0, 19, 0, 306, 307, 20, 0, 308, 309, 310,
+ 21, 311, 312, 0, 23, 0, 0, 0, 313, 314,
+ 315, 316, 317, 26, 0, 27, 319, 0, 0, 0,
+ 320, 0, 0, 0, 0, 0, 321, 0, 506, 322,
+ 7, 8, 507, 10, 167, 12, 13, 323, 324, 325,
+ 0, 14, 0, 0, 0, 326, 327, 328, 0, 0,
+ 0, 0, 329, 0, 0, 16, 0, 17, 18, 19,
+ 0, 0, 0, 20, -528, 0, 0, 0, 21, 330,
+ 909, 0, 23, 508, 0, 168, 0, 0, 0, 0,
+ 0, 26, 0, 27, 28, 0, 0, 509, 0, 510,
+ 0, 0, 0, 0, 0, 0, 0, 30, 506, 0,
+ 7, 8, 507, 10, 167, 12, 13, 31, 0, 0,
+ 0, 14, 0, 0, 0, 32, 0, 0, 0, 0,
+ 33, 0, 0, 0, 0, 16, 0, 17, 18, 19,
+ 0, 0, 0, 20, -527, 0, -528, 0, 21, 0,
+ 0, 0, 23, 508, 0, 168, 0, 0, 0, 0,
+ 0, 26, 0, 27, 28, 0, 0, 509, 0, 510,
+ 0, 0, 0, 0, 0, 0, 0, 30, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 31, 0, 0,
+ 0, 0, 0, 0, 0, 32, 0, 0, 0, 0,
+ 33, 0, 0, 1308, 1309, 1310, 10, 167, 12, 301,
+ 302, 303, 0, 304, 14, 1311, -527, 1312, 1313, 1314,
+ 1315, 1316, 1317, 1318, 1319, 1320, 1321, 15, 16, 305,
+ 17, 18, 19, 0, 306, 307, 20, 0, 308, 309,
+ 310, 21, 311, 312, 1322, 23, 1323, 0, 0, 313,
+ 314, 315, 316, 317, 26, 0, 1324, 319, 736, 0,
+ 1325, 320, 0, 0, 0, 0, 0, 321, 0, 0,
+ 322, 0, 0, 0, 0, 0, 0, 0, 323, 324,
+ 325, 0, 0, 0, 0, 0, 326, 327, 328, 0,
+ 0, 0, 0, 329, 0, 1326, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1445,
+ 330, 1308, 1309, 1310, 10, 167, 12, 301, 302, 303,
+ 0, 304, 14, 1311, 0, 1312, 1313, 1314, 1315, 1316,
+ 1317, 1318, 1319, 1320, 1321, 15, 16, 305, 17, 18,
+ 19, 0, 306, 307, 20, 0, 308, 309, 310, 21,
+ 311, 312, 1322, 23, 1323, 0, 0, 313, 314, 315,
+ 316, 317, 26, 0, 1324, 319, 736, 0, 1325, 320,
+ 0, 0, 0, 0, 0, 321, 0, 0, 322, 0,
+ 0, 0, 0, 0, 0, 0, 323, 324, 325, 0,
+ 0, 0, 0, 0, 326, 327, 328, 0, 0, 0,
+ 0, 329, 0, 1326, 0, 1308, 1309, 1310, 10, 167,
+ 12, 301, 302, 303, 0, 304, 14, 1311, 330, 1312,
+ 1313, 1314, 1315, 1316, 1317, 1318, 1319, 1320, 1321, 15,
+ 16, 305, 17, 18, 19, 0, 306, 307, 20, 0,
+ 308, 309, 310, 21, 311, 312, 1322, 23, 1323, 0,
+ 0, 313, 314, 315, 316, 317, 26, 0, 1324, 319,
+ 1556, 0, 1325, 320, 0, 0, 0, 0, 0, 321,
+ 0, 0, 322, 0, 0, 0, 0, 0, 0, 0,
+ 323, 324, 325, 0, 0, 0, 0, 0, 326, 327,
+ 328, 0, 0, 0, 0, 329, 0, 1326, 0, 1308,
+ 1309, 1310, 10, 167, 12, 301, 302, 303, 0, 304,
+ 14, 1311, 330, 1312, 1313, 1314, 1315, 1316, 1317, 1318,
+ 1319, 1320, 1321, 15, 16, 305, 17, 18, 19, 0,
+ 306, 307, 20, 0, 308, 309, 310, 21, 311, 312,
+ 1322, 23, 1323, 0, 0, 313, 314, 315, 316, 317,
+ 26, 0, 1324, 319, 0, 0, 1325, 320, 0, 0,
+ 0, 0, 0, 321, 0, 0, 322, 0, 0, 0,
+ 0, 0, 0, 0, 323, 324, 325, 0, 0, 0,
+ 0, 0, 326, 327, 328, 0, 0, 0, 0, 329,
+ 0, 1326, 300, 8, 9, 10, 167, 12, 301, 302,
+ 303, 749, 304, 14, 0, 0, 330, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 16, 305, 17,
+ 18, 19, 0, 306, 307, 20, 0, 308, 309, 310,
+ 21, 311, 312, 0, 23, 0, 636, 0, 313, 314,
+ 315, 316, 317, 26, 0, 27, 319, 0, 0, 0,
+ 320, 0, 0, 0, 0, 0, 321, 0, 0, 937,
+ 0, 0, 0, 0, 0, 0, 0, 323, 324, 938,
+ 0, 0, 0, 0, 0, 326, 327, 328, 0, 639,
+ 0, 0, 939, 641, 7, 8, 9, 10, 167, 12,
+ 301, 302, 303, 749, 304, 14, 0, 0, 0, 330,
0, 0, 0, 0, 0, 0, 0, 0, 0, 16,
- 301, 17, 0, 19, 0, 302, 303, 20, 0, 304,
- 305, 306, 21, 307, 308, 0, 23, 0, 0, 0,
- 309, 310, 311, 312, 313, 26, 0, 27, 315, -308,
- 0, 0, 316, 0, 0, 0, 0, 0, 317, 0,
- 0, 540, 0, 0, 0, 0, 0, 0, 0, 319,
- 320, 541, 0, 0, 0, 0, 0, 322, 323, 324,
- 0, 0, 0, 707, 542, 296, 8, 9, 10, 0,
- 12, 521, 298, 299, 0, 300, 14, 0, 0, 0,
- 0, 326, 0, 0, 0, 0, 0, 0, 0, 0,
- 16, 301, 17, 0, 19, 0, 302, 303, 20, 0,
- 304, 305, 306, 21, 307, 308, 0, 23, 0, 0,
- 0, 309, 310, 311, 312, 313, 26, 0, 27, 315,
- 708, 0, 0, 316, 0, 0, 0, 0, 0, 317,
- 0, 0, 318, 0, 0, 0, 0, 0, 0, 0,
- 319, 320, 321, 0, 0, 0, 0, 0, 322, 323,
- 324, 0, 0, 0, 831, 325, 296, 8, 9, 10,
- 0, 12, 521, 298, 299, 0, 300, 14, 0, 0,
- 0, 0, 326, 0, 0, 0, 0, 0, 0, 0,
- 0, 16, 301, 17, 0, 19, 0, 302, 303, 20,
- 0, 304, 305, 306, 21, 307, 308, 0, 23, 0,
- 0, 0, 309, 310, 311, 312, 313, 26, 0, 27,
- 315, 0, 0, 0, 316, -782, 0, 0, 0, 0,
- 317, 0, 0, 318, 0, 0, 0, 0, 0, 0,
- 0, 319, 320, 321, 0, 0, 0, 0, 0, 322,
- 323, 324, 0, 0, 0, 539, 325, 7, 8, 9,
- 10, 0, 12, 297, 298, 299, 0, 300, 14, 0,
- 0, 0, 0, 326, 0, 0, 0, 0, 0, 0,
- 0, 0, 16, 301, 17, 0, 19, 0, 302, 303,
- 20, 0, 304, 305, 306, 21, 307, 308, 0, 23,
- 0, 0, 0, 309, 310, 311, 312, 313, 26, 0,
- 27, 28, -308, 0, 0, 316, 0, 0, 0, 0,
- 0, 317, 0, 0, 1478, 0, 0, 0, 0, 0,
- 0, 0, 319, 320, 1479, 0, 0, 0, 0, 0,
- 322, 323, 324, 0, 0, 0, 1559, 1480, 296, 8,
- 9, 10, 0, 12, 297, 298, 299, 0, 300, 14,
- 0, 0, 0, 0, 326, 0, 0, 0, 0, 0,
- 0, 0, 0, 16, 301, 17, 0, 19, 0, 302,
- 303, 20, 0, 304, 305, 306, 21, 307, 308, 0,
- 23, 0, 0, 0, 309, 310, 311, 312, 313, 26,
- 0, 27, 315, 0, 0, -194, 316, 0, 0, 0,
- 0, 0, 317, 0, 0, 318, 0, 0, 0, 0,
- 0, 0, 0, 319, 320, 321, 0, 0, 0, 0,
- 0, 322, 323, 324, 0, 0, 0, 831, 325, 296,
- 8, 9, 10, 0, 12, 521, 298, 299, 0, 300,
- 14, 0, 0, 0, 0, 326, 0, 0, 0, 0,
- 0, 0, 0, 0, 16, 301, 17, 0, 19, 0,
- 302, 303, 20, 0, 304, 305, 306, 21, 307, 308,
- 0, 23, 0, 0, 0, 309, 310, 311, 312, 313,
- 26, 0, 27, 315, 0, 0, 0, 316, 0, 0,
- 0, 0, 0, 317, 259, 0, 318, 8, 9, 0,
- 0, 12, 13, 0, 319, 320, 321, 14, 0, 0,
- 0, 0, 322, 323, 324, 0, 0, 0, 0, 325,
- 0, 16, 0, 17, 0, 0, 0, 0, 0, 20,
- 0, 260, 261, 0, -782, 0, 326, 0, 23, 0,
- 262, 0, 0, 0, 0, 0, 0, 26, 0, 130,
- 131, 0, 263, 0, 0, 0, 264, 265, 266, 267,
- 268, 269, 270, 271, 272, 273, 274, 275, 276, 277,
- 278, 279, 280, 281, 282, 283, 284, 0, 0, 285,
- 286, 287, 0, 0, 288, 0, 919, 289, 296, 8,
- 9, 10, 0, 12, 521, 298, 299, 0, 300, 14,
- 0, 0, 0, 290, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 16, 301, 17, 0, 19, 0, 302,
- 303, 20, 0, 304, 305, 306, 21, 307, 308, 0,
- 23, 0, 0, 0, 309, 310, 311, 312, 313, 26,
- 0, 27, 315, 0, 0, 0, 316, 0, 0, 0,
- 0, 0, 317, 0, 0, 318, 0, 0, 0, 0,
- 0, 0, 0, 319, 320, 321, 0, 0, 0, 0,
- 0, 322, 323, 324, 0, 0, 0, 921, 325, 296,
- 8, 9, 10, 0, 12, 521, 298, 299, 0, 300,
- 14, 0, 0, 0, 0, 326, 0, 0, 0, 0,
- 0, 0, 0, 0, 16, 301, 17, 0, 19, 0,
- 302, 303, 20, 0, 304, 305, 306, 21, 307, 308,
- 0, 23, 0, 0, 0, 309, 310, 311, 312, 313,
- 26, 0, 27, 315, 0, 0, 0, 316, 0, 0,
- 0, 0, 0, 317, 0, 0, 318, 0, 0, 0,
- 0, 0, 0, 0, 319, 320, 321, 0, 0, 0,
- 0, 0, 322, 323, 324, 0, 0, 0, 1491, 325,
- 296, 8, 9, 10, 0, 12, 521, 298, 299, 0,
- 300, 14, 0, 0, 0, 0, 326, 0, 0, 0,
- 0, 0, 0, 0, 0, 16, 301, 17, 0, 19,
- 0, 302, 303, 20, 0, 304, 305, 306, 21, 307,
- 308, 0, 23, 0, 0, 0, 309, 310, 311, 312,
- 313, 26, 0, 27, 315, 0, 0, 0, 316, 0,
- 0, 0, 0, 0, 317, 0, 0, 318, 0, 0,
- 0, 0, 0, 0, 0, 319, 320, 321, 0, 0,
- 0, 0, 0, 322, 323, 324, 296, 8, 9, 10,
- 325, 12, 521, 298, 299, 0, 300, 14, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 326, 0, 0,
- 0, 16, 301, 17, 0, 19, 0, 302, 303, 20,
- 0, 304, 305, 306, 21, 307, 308, 0, 23, 0,
- 0, 0, 309, 310, 311, 312, 313, 26, 0, 27,
- 315, 0, 0, 0, 316, 0, 0, 0, 0, 0,
- 317, 0, 760, 318, 7, 8, 761, 10, 163, 12,
- 13, 319, 320, 321, 0, 14, 0, 0, 0, 322,
- 323, 324, 0, 0, 0, 0, 325, 0, 0, 16,
- 0, 17, 18, 19, 0, 0, 0, 20, -522, 0,
- 0, 0, 21, 326, 870, 0, 23, 762, 0, 164,
- 0, 0, 0, 0, 0, 26, 0, 27, 28, 0,
- 0, 763, 0, 764, 0, 0, 0, 0, 0, 0,
- 0, 30, 760, 0, 7, 8, 761, 10, 163, 12,
- 13, 31, 0, 0, 0, 14, 0, 0, 0, 32,
- 0, 0, 0, 0, 33, 0, 0, 0, 0, 16,
- 0, 17, 18, 19, 0, 0, 0, 20, -524, 0,
- -522, 0, 21, 0, 0, 0, 23, 762, 0, 164,
- 0, 0, 0, 0, 0, 26, 0, 27, 28, 0,
- 0, 763, 0, 764, 0, 0, 0, 0, 0, 0,
- 0, 30, 760, 0, 7, 8, 761, 10, 163, 12,
- 13, 31, 0, 0, 0, 14, 0, 0, 0, 32,
- 0, 0, 0, 0, 33, 0, 0, 0, 0, 16,
- 0, 17, 18, 19, 0, 0, 0, 20, -523, 0,
- -524, 0, 21, 0, 0, 0, 23, 762, 0, 164,
- 0, 0, 0, 0, 0, 26, 0, 27, 28, 0,
- 0, 763, 0, 764, 0, 0, 0, 0, 0, 0,
- 0, 30, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 31, 0, 0, 0, 0, 0, 0, 0, 32,
- 0, 0, 0, 0, 33, 0, 0, 1270, 1271, 1272,
- 10, 163, 12, 297, 298, 299, 0, 300, 14, 1273,
- -523, 1274, 1275, 1276, 1277, 1278, 1279, 1280, 1281, 1282,
- 1283, 15, 16, 301, 17, 18, 19, 0, 302, 303,
- 20, 0, 304, 305, 306, 21, 307, 308, 1284, 23,
- 1285, 0, 0, 309, 310, 311, 312, 313, 26, 0,
- 1286, 315, 704, 0, 1287, 316, 0, 0, 0, 0,
- 0, 317, 0, 0, 318, 0, 0, 0, 0, 0,
- 0, 0, 319, 320, 321, 0, 0, 0, 0, 0,
- 322, 323, 324, 0, 0, 0, 0, 325, 0, 1288,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 1415, 326, 1270, 1271, 1272, 10, 163,
- 12, 297, 298, 299, 0, 300, 14, 1273, 0, 1274,
- 1275, 1276, 1277, 1278, 1279, 1280, 1281, 1282, 1283, 15,
- 16, 301, 17, 18, 19, 0, 302, 303, 20, 0,
- 304, 305, 306, 21, 307, 308, 1284, 23, 1285, 0,
- 0, 309, 310, 311, 312, 313, 26, 0, 1286, 315,
- 704, 0, 1287, 316, 0, 0, 0, 0, 0, 317,
- 0, 0, 318, 0, 0, 0, 0, 0, 0, 0,
- 319, 320, 321, 0, 0, 0, 0, 0, 322, 323,
- 324, 0, 0, 0, 0, 325, 0, 1288, 0, 1270,
- 1271, 1272, 10, 163, 12, 297, 298, 299, 0, 300,
- 14, 1273, 326, 1274, 1275, 1276, 1277, 1278, 1279, 1280,
- 1281, 1282, 1283, 15, 16, 301, 17, 18, 19, 0,
- 302, 303, 20, 0, 304, 305, 306, 21, 307, 308,
- 1284, 23, 1285, 0, 0, 309, 310, 311, 312, 313,
- 26, 0, 1286, 315, 1536, 0, 1287, 316, 0, 0,
- 0, 0, 0, 317, 0, 0, 318, 0, 0, 0,
- 0, 0, 0, 0, 319, 320, 321, 0, 0, 0,
- 0, 0, 322, 323, 324, 0, 0, 0, 0, 325,
- 0, 1288, 0, 1270, 1271, 1272, 10, 163, 12, 297,
- 298, 299, 0, 300, 14, 1273, 326, 1274, 1275, 1276,
- 1277, 1278, 1279, 1280, 1281, 1282, 1283, 15, 16, 301,
- 17, 18, 19, 0, 302, 303, 20, 0, 304, 305,
- 306, 21, 307, 308, 1284, 23, 1285, 0, 0, 309,
- 310, 311, 312, 313, 26, 0, 1286, 315, 0, 0,
- 1287, 316, 0, 0, 0, 0, 0, 317, 0, 0,
- 318, 0, 0, 0, 0, 0, 0, 0, 319, 320,
- 321, 0, 0, 0, 0, 0, 322, 323, 324, 0,
- 0, 0, 0, 325, 0, 1288, 296, 8, 9, 10,
- 163, 12, 297, 298, 299, 717, 300, 14, 0, 0,
- 326, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 16, 301, 17, 18, 19, 0, 302, 303, 20,
- 0, 304, 305, 306, 21, 307, 308, 0, 23, 0,
- 605, 0, 309, 310, 311, 312, 313, 26, 0, 27,
- 315, 0, 0, 0, 316, 0, 0, 0, 0, 0,
- 317, 0, 0, 898, 0, 0, 0, 0, 0, 0,
- 0, 319, 320, 899, 0, 0, 0, 0, 0, 322,
- 323, 324, 0, 608, 0, 0, 900, 610, 7, 8,
- 9, 10, 163, 12, 297, 298, 299, 717, 300, 14,
- 0, 0, 0, 326, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 16, 301, 17, 18, 19, 0, 302,
- 303, 20, 0, 304, 305, 306, 21, 307, 308, 0,
- 23, 0, 605, 0, 309, 310, 311, 312, 313, 26,
- 0, 27, 28, 0, 0, 0, 316, 0, 0, 0,
- 0, 0, 317, 0, 0, 1171, 0, 0, 0, 0,
- 0, 0, 0, 319, 320, 1172, 0, 0, 0, 0,
- 0, 322, 323, 324, 0, 608, 0, 0, 1173, 610,
- 296, 8, 9, 10, 0, 12, 297, 298, 299, 0,
- 300, 14, 0, 0, 0, 326, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 16, 301, 17, 0, 19,
- 0, 302, 303, 20, 0, 304, 305, 306, 21, 307,
- 308, 0, 23, 0, 605, 0, 309, 310, 311, 312,
- 313, 26, 0, 27, 315, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 317, 0, 0, 898, 0, 0,
- 0, 0, 0, 0, 0, 319, 320, 899, 0, 0,
- 0, 0, 0, 322, 323, 324, 0, 608, 0, 0,
- 900, 610, 7, 8, 9, 10, 0, 12, 297, 298,
- 299, 0, 300, 14, 0, 0, 0, 326, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 16, 301, 17,
- 0, 19, 0, 302, 303, 20, 0, 304, 305, 306,
- 21, 307, 308, 0, 23, 0, 605, 0, 309, 310,
- 311, 312, 313, 26, 0, 27, 28, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 317, 0, 0, 1171,
- 0, 0, 0, 0, 0, 0, 0, 319, 320, 1172,
- 0, 0, 0, 0, 0, 322, 323, 324, 0, 608,
- 0, 0, 1173, 610, 296, 8, 9, 10, 0, 12,
- 521, 298, 299, 0, 300, 14, 0, 0, 0, 326,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 16,
- 301, 17, 0, 19, 0, 302, 303, 20, 0, 304,
- 305, 306, 21, 307, 308, 0, 23, 0, 0, 0,
- 309, 310, 311, 312, 313, 26, 0, 27, 315, 0,
- 0, 1388, 316, 0, 0, 0, 0, 0, 317, 0,
- 0, 318, 0, 0, 0, 0, 0, 0, 0, 319,
- 320, 321, 0, 0, 0, 0, 0, 322, 323, 324,
- 0, 0, 0, 0, 325, 296, 8, 9, 10, 163,
- 12, 297, 298, 299, 0, 300, 14, 0, 0, 0,
- 0, 326, 0, 0, 0, 0, 0, 0, 0, 0,
- 16, 301, 17, 18, 19, 0, 302, 303, 20, 0,
- 304, 305, 306, 21, 307, 308, 0, 23, 0, 0,
- 0, 309, 310, 311, 312, 313, 26, 0, 27, 315,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 317,
- 0, 0, 318, 0, 0, 0, 0, 0, 0, 0,
- 319, 320, 321, 0, 0, 0, 0, 0, 322, 323,
- 324, 296, 8, 9, 10, 325, 12, 297, 298, 299,
- 0, 300, 14, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 326, 0, 0, 0, 16, 301, 17, 0,
- 19, 0, 302, 303, 20, 0, 304, 305, 306, 21,
- 307, 308, 0, 23, 0, 0, 0, 309, 310, 311,
- 312, 313, 26, 0, 314, 315, 0, 0, 0, 316,
- 0, 0, 0, 0, 0, 317, 0, 0, 318, 0,
- 0, 0, 0, 0, 0, 0, 319, 320, 321, 0,
- 0, 0, 0, 0, 322, 323, 324, 296, 8, 9,
- 10, 325, 12, 297, 298, 299, 0, 300, 14, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 326, 0,
- 0, 0, 16, 301, 17, 0, 19, 0, 302, 303,
- 20, 0, 304, 305, 306, 21, 307, 308, 0, 23,
- 0, 0, 0, 309, 310, 311, 312, 313, 26, 0,
- 27, 315, 0, 0, 0, 316, 0, 0, 0, 0,
- 0, 317, 0, 0, 318, 0, 0, 0, 0, 0,
- 0, 0, 319, 320, 321, 0, 0, 0, 0, 0,
- 322, 323, 324, 296, 8, 9, 10, 325, 12, 521,
- 298, 299, 0, 300, 14, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 326, 0, 0, 0, 16, 301,
- 17, 0, 19, 0, 302, 303, 20, 0, 304, 305,
- 306, 21, 307, 308, 0, 23, 0, 0, 0, 309,
- 310, 311, 312, 313, 26, 0, 27, 315, 0, 0,
- 0, 316, 0, 0, 0, 0, 0, 317, 0, 0,
- 318, 0, 0, 0, 0, 0, 0, 0, 319, 320,
- 321, 0, 0, 0, 0, 0, 322, 323, 324, 296,
- 8, 9, 10, 325, 12, 521, 298, 299, 0, 300,
- 14, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 326, 0, 0, 0, 16, 301, 17, 0, 19, 0,
- 302, 303, 20, 0, 304, 305, 306, 21, 307, 308,
- 0, 23, 0, 0, 0, 309, 310, 311, 312, 313,
- 26, 0, 27, 315, 554, 0, 0, 0, 0, 0,
- 0, 0, 0, 317, 0, 0, 318, 0, 0, 0,
- 0, 0, 0, 0, 319, 320, 321, 0, 0, 0,
- 0, 0, 322, 323, 324, 296, 8, 9, 10, 555,
- 12, 521, 298, 299, 0, 300, 14, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 326, 0, 0, 0,
- 16, 301, 17, 0, 19, 0, 302, 303, 20, 0,
- 304, 305, 306, 21, 307, 308, 0, 23, 0, 0,
- 0, 309, 310, 311, 312, 313, 26, 0, 27, 315,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 317,
- 0, 0, 318, 0, 0, 0, 0, 0, 0, 0,
- 319, 320, 321, 0, 0, 0, 0, 0, 322, 323,
- 324, 0, 0, 0, 0, 325, 593, 296, 8, 9,
- 10, 0, 12, 521, 298, 299, 0, 300, 14, 0,
- 0, 0, 326, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 16, 301, 17, 0, 19, 0, 302, 303,
- 20, 0, 304, 305, 306, 21, 307, 308, 0, 23,
- 0, 0, 0, 309, 310, 311, 312, 313, 26, 0,
- 27, 315, 0, 0, 0, 316, 0, 0, 0, 0,
- 0, 317, 0, 0, 540, 0, 0, 0, 0, 0,
- 0, 0, 319, 320, 541, 0, 0, 0, 0, 0,
- 322, 323, 324, 1131, 8, 9, 10, 542, 12, 521,
- 298, 299, 0, 300, 14, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 326, 0, 0, 0, 16, 301,
- 17, 0, 19, 0, 302, 303, 20, 0, 304, 305,
- 306, 21, 307, 308, 0, 23, 0, 0, 0, 309,
- 310, 311, 312, 313, 26, 0, 27, 315, 0, 0,
- 0, 316, 0, 0, 0, 0, 0, 317, 0, 0,
- 318, 0, 0, 0, 0, 0, 0, 0, 319, 320,
- 321, 0, 0, 0, 0, 0, 322, 323, 324, 7,
- 8, 9, 10, 325, 12, 521, 298, 299, 0, 300,
+ 305, 17, 18, 19, 0, 306, 307, 20, 0, 308,
+ 309, 310, 21, 311, 312, 0, 23, 0, 636, 0,
+ 313, 314, 315, 316, 317, 26, 0, 27, 28, 0,
+ 0, 0, 320, 0, 0, 0, 0, 0, 321, 0,
+ 0, 1201, 0, 0, 0, 0, 0, 0, 0, 323,
+ 324, 1202, 0, 0, 0, 0, 0, 326, 327, 328,
+ 0, 639, 0, 0, 1203, 641, 300, 8, 9, 10,
+ 0, 12, 301, 302, 303, 0, 304, 14, 0, 0,
+ 0, 330, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 16, 305, 17, 18, 19, 0, 306, 307, 20,
+ 0, 308, 309, 310, 21, 311, 312, 0, 23, 0,
+ 636, 0, 313, 314, 315, 316, 317, 26, 0, 27,
+ 319, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 321, 0, 0, 937, 0, 0, 0, 0, 0, 0,
+ 0, 323, 324, 938, 0, 0, 0, 0, 0, 326,
+ 327, 328, 0, 639, 0, 0, 939, 641, 7, 8,
+ 9, 10, 0, 12, 301, 302, 303, 0, 304, 14,
+ 0, 0, 0, 330, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 16, 305, 17, 18, 19, 0, 306,
+ 307, 20, 0, 308, 309, 310, 21, 311, 312, 0,
+ 23, 0, 636, 0, 313, 314, 315, 316, 317, 26,
+ 0, 27, 28, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 321, 0, 0, 1201, 0, 0, 0, 0,
+ 0, 0, 0, 323, 324, 1202, 0, 0, 0, 0,
+ 0, 326, 327, 328, 0, 639, 0, 0, 1203, 641,
+ 300, 8, 9, 10, 0, 12, 552, 302, 303, 0,
+ 304, 14, 0, 0, 0, 330, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 16, 305, 17, 18, 19,
+ 0, 306, 307, 20, 0, 308, 309, 310, 21, 311,
+ 312, 0, 23, 0, 0, 0, 313, 314, 315, 316,
+ 317, 26, 0, 27, 319, 0, 0, 0, 320, 0,
+ 0, 0, 0, 0, 321, 0, 0, 571, 0, 0,
+ 0, 0, 0, 0, 0, 323, 324, 572, 0, 0,
+ 0, 0, 0, 326, 327, 328, 300, 8, 9, 10,
+ 573, 12, 552, 302, 303, 0, 304, 14, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 330, 0, 0,
+ 0, 16, 305, 17, 0, 19, 0, 306, 307, 20,
+ 0, 308, 309, 310, 21, 311, 312, 0, 23, 0,
+ 0, 0, 313, 314, 315, 316, 317, 26, 0, 27,
+ 319, 0, 0, 1418, 320, 0, 0, 0, 0, 0,
+ 321, 0, 0, 322, 0, 0, 0, 0, 0, 0,
+ 0, 323, 324, 325, 0, 0, 0, 0, 0, 326,
+ 327, 328, 0, 0, 0, 0, 329, 300, 8, 9,
+ 10, 167, 12, 301, 302, 303, 0, 304, 14, 0,
+ 0, 0, 0, 330, 0, 0, 0, 0, 0, 0,
+ 0, 0, 16, 305, 17, 18, 19, 0, 306, 307,
+ 20, 0, 308, 309, 310, 21, 311, 312, 0, 23,
+ 0, 0, 0, 313, 314, 315, 316, 317, 26, 0,
+ 27, 319, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 321, 0, 0, 322, 0, 0, 0, 0, 0,
+ 0, 0, 323, 324, 325, 0, 0, 0, 0, 0,
+ 326, 327, 328, 7, 8, 9, 10, 329, 12, 552,
+ 302, 303, 0, 304, 14, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 330, 0, 0, 0, 16, 305,
+ 17, 18, 19, 0, 306, 307, 20, 0, 308, 309,
+ 310, 21, 311, 312, 0, 23, 0, 0, 0, 313,
+ 314, 315, 316, 317, 26, 0, 27, 28, 0, 0,
+ 0, 320, 0, 0, 0, 0, 0, 321, 0, 0,
+ 1505, 0, 0, 0, 0, 0, 0, 0, 323, 324,
+ 1506, 0, 0, 0, 0, 0, 326, 327, 328, 300,
+ 8, 9, 10, 1507, 12, 301, 302, 303, 0, 304,
14, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 326, 0, 0, 0, 16, 301, 17, 0, 19, 0,
- 302, 303, 20, 0, 304, 305, 306, 21, 307, 308,
- 0, 23, 0, 0, 0, 309, 310, 311, 312, 313,
- 26, 0, 27, 28, 0, 0, 0, 316, 0, 0,
- 0, 0, 0, 317, 0, 0, 1478, 0, 0, 0,
- 0, 0, 0, 0, 319, 320, 1479, 0, 0, 0,
- 0, 0, 322, 323, 324, 296, 8, 9, 10, 1480,
- 12, 521, 298, 299, 0, 300, 14, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 326, 0, 0, 0,
- 16, 301, 17, 0, 19, 0, 302, 303, 20, 0,
- 304, 305, 306, 21, 307, 308, 0, 23, 0, 0,
- 0, 309, 310, 311, 312, 313, 26, 0, 27, 315,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 317,
- 0, 0, 318, 0, 0, 0, 0, 0, 0, 0,
- 319, 320, 321, 0, 0, 0, 0, 0, 322, 323,
- 324, 296, 8, 9, 10, 522, 12, 521, 298, 299,
- 0, 300, 14, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 326, 0, 0, 0, 16, 301, 17, 0,
- 19, 0, 302, 303, 20, 0, 304, 305, 306, 21,
- 307, 308, 0, 23, 0, 0, 0, 309, 310, 311,
- 312, 313, 26, 0, 27, 315, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 317, 0, 0, 318, 0,
- 0, 0, 0, 0, 0, 0, 319, 320, 321, 0,
- 0, 0, 0, 0, 322, 323, 324, 296, 8, 9,
- 10, 525, 12, 521, 298, 299, 0, 300, 14, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 326, 0,
- 0, 0, 16, 301, 17, 0, 19, 0, 302, 303,
- 20, 0, 304, 305, 306, 21, 307, 308, 0, 23,
- 0, 0, 0, 309, 310, 311, 312, 313, 26, 0,
- 27, 315, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 317, 0, 0, 318, 0, 0, 0, 0, 0,
- 0, 0, 319, 320, 321, 0, 0, 0, 0, 0,
- 322, 323, 324, 296, 8, 9, 10, 325, 12, 521,
- 298, 299, 0, 300, 14, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 326, 0, 0, 0, 16, 301,
- 17, 0, 19, 0, 302, 303, 20, 0, 304, 305,
- 306, 21, 307, 308, 0, 23, 0, 0, 0, 309,
- 310, 311, 312, 313, 26, 0, 27, 315, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 317, 0, 0,
- 540, 0, 0, 0, 0, 0, 0, 0, 319, 320,
- 541, 0, 0, 0, 0, 0, 322, 323, 324, 7,
- 8, 9, 10, 542, 12, 297, 298, 299, 0, 300,
+ 330, 0, 0, 0, 16, 305, 17, 0, 19, 0,
+ 306, 307, 20, 0, 308, 309, 310, 21, 311, 312,
+ 0, 23, 0, 0, 0, 313, 314, 315, 316, 317,
+ 26, 0, 318, 319, 0, 0, 0, 320, 0, 0,
+ 0, 0, 0, 321, 0, 0, 322, 0, 0, 0,
+ 0, 0, 0, 0, 323, 324, 325, 0, 0, 0,
+ 0, 0, 326, 327, 328, 300, 8, 9, 10, 329,
+ 12, 301, 302, 303, 0, 304, 14, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 330, 0, 0, 0,
+ 16, 305, 17, 0, 19, 0, 306, 307, 20, 0,
+ 308, 309, 310, 21, 311, 312, 0, 23, 0, 0,
+ 0, 313, 314, 315, 316, 317, 26, 0, 27, 319,
+ 0, 0, 0, 320, 0, 0, 0, 0, 0, 321,
+ 0, 0, 322, 0, 0, 0, 0, 0, 0, 0,
+ 323, 324, 325, 0, 0, 0, 0, 0, 326, 327,
+ 328, 300, 8, 9, 10, 329, 12, 552, 302, 303,
+ 0, 304, 14, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 330, 0, 0, 0, 16, 305, 17, 0,
+ 19, 0, 306, 307, 20, 0, 308, 309, 310, 21,
+ 311, 312, 0, 23, 0, 0, 0, 313, 314, 315,
+ 316, 317, 26, 0, 27, 319, 0, 0, 0, 320,
+ 0, 0, 0, 0, 0, 321, 0, 0, 322, 0,
+ 0, 0, 0, 0, 0, 0, 323, 324, 325, 0,
+ 0, 0, 0, 0, 326, 327, 328, 300, 8, 9,
+ 10, 329, 12, 552, 302, 303, 0, 304, 14, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 330, 0,
+ 0, 0, 16, 305, 17, 0, 19, 0, 306, 307,
+ 20, 0, 308, 309, 310, 21, 311, 312, 0, 23,
+ 0, 0, 0, 313, 314, 315, 316, 317, 26, 0,
+ 27, 319, 585, 0, 0, 0, 0, 0, 0, 0,
+ 0, 321, 0, 0, 322, 0, 0, 0, 0, 0,
+ 0, 0, 323, 324, 325, 0, 0, 0, 0, 0,
+ 326, 327, 328, 300, 8, 9, 10, 586, 12, 552,
+ 302, 303, 0, 304, 14, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 330, 0, 0, 0, 16, 305,
+ 17, 0, 19, 0, 306, 307, 20, 0, 308, 309,
+ 310, 21, 311, 312, 0, 23, 0, 0, 0, 313,
+ 314, 315, 316, 317, 26, 0, 27, 319, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 321, 0, 0,
+ 322, 0, 0, 0, 0, 0, 0, 0, 323, 324,
+ 325, 0, 0, 0, 0, 0, 326, 327, 328, 0,
+ 0, 0, 0, 329, 624, 300, 8, 9, 10, 0,
+ 12, 552, 302, 303, 0, 304, 14, 0, 0, 0,
+ 330, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 16, 305, 17, 18, 19, 0, 306, 307, 20, 0,
+ 308, 309, 310, 21, 311, 312, 0, 23, 0, 0,
+ 0, 313, 314, 315, 316, 317, 26, 0, 27, 319,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 321,
+ 0, 0, 571, 0, 0, 0, 0, 0, 0, 0,
+ 323, 324, 572, 0, 0, 0, 0, 0, 326, 327,
+ 328, 1161, 8, 9, 10, 573, 12, 552, 302, 303,
+ 0, 304, 14, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 330, 0, 0, 0, 16, 305, 17, 0,
+ 19, 0, 306, 307, 20, 0, 308, 309, 310, 21,
+ 311, 312, 0, 23, 0, 0, 0, 313, 314, 315,
+ 316, 317, 26, 0, 27, 319, 0, 0, 0, 320,
+ 0, 0, 0, 0, 0, 321, 0, 0, 322, 0,
+ 0, 0, 0, 0, 0, 0, 323, 324, 325, 0,
+ 0, 0, 0, 0, 326, 327, 328, 7, 8, 9,
+ 10, 329, 12, 301, 302, 303, 0, 304, 14, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 330, 0,
+ 0, 0, 16, 305, 17, 18, 19, 0, 306, 307,
+ 20, 0, 308, 309, 310, 21, 311, 312, 0, 23,
+ 0, 0, 0, 313, 314, 315, 316, 317, 26, 0,
+ 27, 28, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 321, 0, 0, 1505, 0, 0, 0, 0, 0,
+ 0, 0, 323, 324, 1506, 0, 0, 0, 0, 0,
+ 326, 327, 328, 300, 8, 9, 10, 1507, 12, 552,
+ 302, 303, 0, 304, 14, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 330, 0, 0, 0, 16, 305,
+ 17, 0, 19, 0, 306, 307, 20, 0, 308, 309,
+ 310, 21, 311, 312, 0, 23, 0, 0, 0, 313,
+ 314, 315, 316, 317, 26, 0, 27, 319, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 321, 0, 0,
+ 322, 0, 0, 0, 0, 0, 0, 0, 323, 324,
+ 325, 0, 0, 0, 0, 0, 326, 327, 328, 300,
+ 8, 9, 10, 553, 12, 552, 302, 303, 0, 304,
14, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 326, 0, 0, 0, 16, 301, 17, 0, 19, 0,
- 302, 303, 20, 0, 304, 305, 306, 21, 307, 308,
- 0, 23, 0, 0, 0, 309, 310, 311, 312, 313,
- 26, 0, 27, 28, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 317, 0, 6, 1478, 7, 8, 9,
- 10, 11, 12, 13, 319, 320, 1479, 0, 14, 0,
- 0, 0, 322, 323, 324, 0, 0, 0, 0, 1480,
- 0, 15, 16, 0, 17, 18, 19, 0, 0, 0,
- 20, 0, 0, 0, 0, 21, 326, 0, 22, 23,
- 24, 0, 25, 0, 0, 0, 0, 0, 26, 0,
- 27, 28, 0, 0, 29, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 30, 0, 0, 0, 0, 0,
- 0, 0, 0, 760, 31, 7, 8, 761, 10, 163,
- 12, 13, 32, 0, 0, 0, 14, 33, 0, 0,
- 0, 0, 34, 0, 0, 0, 0, 0, 0, 0,
- 16, 0, 17, 18, 19, 0, 0, 0, 20, 0,
- 0, 0, 0, 21, 0, 0, 0, 23, 762, 0,
- 164, 0, 0, 0, 0, 0, 26, 0, 27, 28,
- 0, 0, 763, 0, 764, 0, 0, 0, 0, 0,
- 0, 0, 30, 7, 8, 9, 10, 201, 12, 202,
- 0, 0, 31, 0, 14, 0, 0, 0, 0, 0,
- 32, 0, 0, 0, 0, 33, 0, 0, 16, 0,
- 17, 18, 0, 0, 0, 0, 20, 0, 0, 0,
- 0, 21, 0, 0, 0, 23, 0, 0, 0, 0,
- 0, 0, 0, 0, 26, 0, 27, 28, 0, 0,
- 1405, 0, 7, 8, 9, 10, 201, 12, 202, 0,
- 30, 0, 0, 14, 0, 0, 0, 0, 0, 0,
- 31, 0, 0, 0, 0, 0, 0, 16, 32, 17,
- 18, 0, 0, 33, 0, 20, 0, 0, 0, 0,
- 21, 0, 0, 0, 23, 0, 0, 0, 0, 0,
- 0, 0, 0, 26, 0, 27, 28, 7, 8, 9,
- 10, 210, 211, 212, 0, 0, 0, 0, 14, 30,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 31,
- 0, 0, 0, 0, 0, 18, 0, 32, 0, 0,
- 20, 0, 33, 0, 0, 21, 0, 0, 0, 23,
- 0, 605, 0, 0, 0, 0, 0, 0, 26, 0,
- 27, 28, 0, 0, 0, 0, 18, 0, 0, 0,
- 0, 0, 0, 0, 189, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 190, 0, 0, 0, 0, 0,
- 0, 0, 32, 0, 0, 0, 0, 1408, 557, 558,
- 559, 560, 561, 562, 563, 564, 565, 566, 567, 568,
- 569, 570, 571, 572, 573, 574, 575, 576, 577, 578,
- 557, 558, 559, 560, 561, 562, 563, 564, 565, 566,
- 567, 568, 569, 570, 571, 572, 573, 574, 575, 576,
- 577, 578, 557, 558, 559, 560, 561, 562, 563, 564,
- 565, 566, 567, 568, 569, 570, 571, 572, 573, 574,
- 575, 576, 577, 578, 0, 0, 0, 0, 1223, 0,
+ 330, 0, 0, 0, 16, 305, 17, 0, 19, 0,
+ 306, 307, 20, 0, 308, 309, 310, 21, 311, 312,
+ 0, 23, 0, 0, 0, 313, 314, 315, 316, 317,
+ 26, 0, 27, 319, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 321, 0, 0, 322, 0, 0, 0,
+ 0, 0, 0, 0, 323, 324, 325, 0, 0, 0,
+ 0, 0, 326, 327, 328, 300, 8, 9, 10, 556,
+ 12, 552, 302, 303, 0, 304, 14, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 330, 0, 0, 0,
+ 16, 305, 17, 0, 19, 0, 306, 307, 20, 0,
+ 308, 309, 310, 21, 311, 312, 0, 23, 0, 0,
+ 0, 313, 314, 315, 316, 317, 26, 0, 27, 319,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 321,
+ 0, 0, 322, 0, 0, 0, 0, 0, 0, 0,
+ 323, 324, 325, 0, 0, 0, 0, 0, 326, 327,
+ 328, 0, 0, 8, 9, 329, 167, 12, 13, 0,
+ 0, 1550, 0, 14, 0, 0, 0, 0, 0, 0,
+ 0, 0, 330, 0, 0, 0, 0, 16, 0, 17,
+ 18, 0, 0, 0, 0, 20, 0, 0, 0, 0,
+ 0, 0, 0, 0, 23, 0, 0, 0, 0, 0,
+ 0, 0, 0, 26, 0, 130, 131, 588, 589, 590,
+ 591, 592, 593, 594, 595, 596, 597, 598, 599, 600,
+ 601, 602, 603, 604, 605, 606, 607, 608, 609, 588,
+ 589, 590, 591, 592, 593, 594, 595, 596, 597, 598,
+ 599, 600, 601, 602, 603, 604, 605, 606, 607, 608,
+ 609, 0, 0, 0, 0, 1261, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 646, 0, 0, 1526, 557, 558, 559,
- 560, 561, 562, 563, 564, 565, 566, 567, 568, 569,
- 570, 571, 572, 573, 574, 575, 576, 577, 578, 1544,
- 557, 558, 559, 560, 561, 562, 563, 564, 565, 566,
- 567, 568, 569, 570, 571, 572, 573, 574, 575, 576,
- 577, 578, 557, 558, 559, 560, 561, 562, 563, 564,
- 565, 566, 567, 568, 569, 570, 571, 572, 573, 574,
- 575, 576, 577, 578, 557, 558, 559, 560, 561, 562,
- 563, 564, 565, 566, 567, 568, 0, 570, 571, 572,
- 573, 574, 575, 576, 577, 578
+ 677, 0, 0, 1546, 588, 589, 590, 591, 592, 593,
+ 594, 595, 596, 597, 598, 599, 600, 601, 602, 603,
+ 604, 605, 606, 607, 608, 609, 1564, 588, 589, 590,
+ 591, 592, 593, 594, 595, 596, 597, 598, 599, 600,
+ 601, 602, 603, 604, 605, 606, 607, 608, 609, 588,
+ 589, 590, 591, 592, 593, 594, 595, 596, 597, 598,
+ 599, 600, 601, 602, 603, 604, 605, 606, 607, 608,
+ 609, 588, 589, 590, 591, 592, 593, 594, 595, 596,
+ 597, 598, 599, 0, 601, 602, 603, 604, 605, 606,
+ 607, 608, 609
};
static const short yycheck[] = { 4,
- 157, 345, 172, 46, 205, 33, 23, 170, 80, 4,
- 171, 80, 147, 148, 398, 443, 702, 4, 126, 448,
- 247, 398, 4, 351, 351, 300, 301, 609, 470, 84,
- 35, 14, 369, 76, 616, 398, 491, 42, 133, 134,
- 35, 859, 243, 552, 62, 428, 589, 133, 35, 678,
- 4, 134, 57, 35, 42, 42, 352, 353, 333, 1299,
- 42, 42, 238, 107, 108, 124, 1306, 72, 685, 1370,
- 142, 1459, 1289, 4, 213, 214, 30, 31, 54, 84,
- 765, 35, 767, 88, 783, 90, 205, 92, 42, 774,
- 789, 292, 1460, 42, 42, 214, 47, 37, 1, 11,
- 83, 1461, 107, 108, 35, 4, 11, 11, 404, 405,
- 4, 42, 47, 58, 12, 90, 1504, 92, 546, 147,
- 148, 149, 55, 106, 351, 33, 1507, 199, 0, 1483,
- 84, 136, 137, 632, 139, 478, 35, 33, 54, 9,
- 47, 35, 93, 42, 345, 1, 62, 0, 42, 1503,
- 62, 60, 495, 98, 136, 58, 161, 108, 93, 62,
- 165, 59, 137, 191, 62, 12, 209, 172, 610, 109,
- 1, 48, 178, 161, 1555, 59, 152, 165, 165, 161,
- 524, 1541, 136, 165, 165, 84, 93, 686, 33, 258,
- 208, 61, 95, 147, 148, 57, 108, 896, 216, 59,
- 109, 109, 58, 108, 108, 1194, 1195, 161, 1562, 42,
- 108, 165, 59, 1601, 232, 62, 165, 165, 1586, 1208,
- 196, 25, 468, 27, 1464, 109, 59, 58, 83, 84,
- 476, 62, 4, 5, 165, 189, 190, 136, 171, 3,
- 4, 5, 136, 1460, 74, 1546, 701, 342, 108, 25,
- 60, 27, 148, 149, 58, 75, 342, 77, 62, 8,
- 9, 244, 161, 47, 95, 14, 165, 161, 59, 4,
- 54, 165, 74, 1513, 136, 703, 48, 4, 5, 436,
- 4, 325, 58, 338, 56, 57, 62, 36, 293, 74,
- 74, 95, 56, 57, 911, 191, 45, 914, 47, 109,
- 35, 629, 147, 148, 149, 668, 389, 936, 80, 93,
- 172, 35, 1011, 696, 697, 858, 80, 108, 900, 95,
- 325, 658, 381, 1563, 1023, 54, 59, 462, 463, 56,
- 57, 47, 165, 338, 60, 474, 475, 633, 955, 956,
- 724, 346, 1331, 482, 93, 74, 191, 724, 60, 354,
- 355, 1340, 1341, 59, 1343, 494, 475, 25, 1057, 27,
- 1059, 943, 93, 1048, 3, 4, 5, 25, 351, 4,
- 5, 598, 205, 355, 513, 108, 720, 93, 94, 354,
- 213, 214, 7, 109, 338, 58, 62, 59, 60, 62,
- 58, 27, 108, 398, 62, 31, 401, 109, 74, 4,
- 58, 355, 108, 985, 62, 4, 5, 47, 47, 453,
- 243, 398, 37, 48, 1232, 54, 47, 56, 57, 47,
- 438, 56, 57, 492, 60, 430, 47, 95, 64, 325,
- 35, 940, 861, 47, 462, 463, 464, 95, 47, 338,
- 54, 484, 430, 47, 398, 80, 47, 93, 430, 430,
- 47, 456, 93, 93, 93, 897, 355, 56, 57, 292,
- 74, 355, 93, 481, 44, 93, 94, 400, 108, 4,
- 5, 54, 93, 109, 54, 54, 430, 57, 522, 93,
- 108, 525, 74, 62, 93, 529, 25, 492, 27, 93,
- 94, 74, 93, 355, 47, 74, 93, 94, 542, 398,
- 1489, 1490, 456, 799, 108, 1122, 1123, 93, 462, 463,
- 492, 555, 345, 48, 519, 559, 60, 522, 107, 58,
- 525, 56, 57, 62, 529, 530, 531, 532, 533, 4,
- 5, 430, 695, 25, 9, 590, 430, 542, 492, 59,
- 93, 1359, 47, 587, 519, 80, 974, 552, 47, 593,
- 555, 60, 54, 937, 1009, 75, 95, 456, 54, 64,
- 937, 492, 1144, 7, 8, 9, 47, 463, 464, 402,
- 14, 666, 74, 749, 937, 751, 659, 905, 905, 54,
- 756, 56, 57, 666, 62, 590, 47, 31, 93, 94,
- 31, 1173, 36, 492, 93, 70, 74, 430, 492, 38,
- 54, 45, 54, 742, 609, 80, 27, 808, 62, 62,
- 31, 616, 93, 4, 5, 54, 60, 462, 463, 464,
- 74, 47, 74, 47, 58, 12, 522, 902, 74, 525,
- 492, 54, 93, 94, 930, 12, 590, 620, 59, 60,
- 27, 474, 475, 64, 31, 541, 542, 1076, 1077, 482,
- 667, 759, 606, 607, 1096, 609, 661, 58, 58, 555,
- 47, 494, 616, 54, 64, 56, 57, 93, 94, 93,
- 675, 109, 59, 60, 679, 62, 47, 64, 905, 70,
- 513, 47, 59, 47, 701, 62, 661, 64, 54, 80,
- 47, 590, 3, 4, 5, 6, 765, 62, 767, 93,
- 1155, 54, 635, 94, 773, 774, 93, 94, 74, 74,
- 609, 780, 62, 47, 4, 5, 54, 616, 54, 724,
- 616, 108, 93, 54, 74, 768, 769, 93, 47, 93,
- 41, 75, 1187, 54, 777, 47, 93, 48, 74, 745,
- 1169, 674, 94, 676, 677, 56, 57, 1091, 108, 1178,
- 1179, 47, 64, 74, 1183, 1051, 1052, 1053, 48, 93,
- 765, 108, 767, 4, 5, 108, 56, 57, 773, 774,
- 724, 4, 5, 779, 93, 780, 9, 88, 783, 784,
- 785, 93, 787, 765, 789, 767, 108, 720, 4, 5,
- 80, 11, 774, 109, 1223, 59, 60, 93, 780, 962,
- 3, 4, 5, 636, 7, 8, 9, 48, 60, 784,
- 785, 765, 787, 767, 62, 56, 57, 4, 5, 98,
- 774, 54, 866, 56, 57, 724, 780, 93, 31, 783,
- 1006, 1007, 1008, 36, 765, 789, 767, 70, 54, 772,
- 56, 57, 47, 774, 677, 3, 111, 80, 62, 780,
- 60, 54, 857, 56, 57, 58, 900, 862, 94, 64,
- 108, 94, 94, 1549, 4, 5, 765, 54, 767, 56,
- 57, 765, 62, 767, 111, 774, 948, 3, 4, 5,
- 774, 780, 93, 70, 783, 890, 780, 720, 93, 1318,
- 789, 896, 93, 80, 108, 900, 1092, 1093, 74, 1095,
- 103, 104, 105, 765, 30, 767, 802, 74, 48, 742,
- 772, 773, 774, 59, 60, 943, 56, 57, 780, 3,
- 4, 5, 905, 59, 4, 5, 74, 1356, 54, 27,
- 56, 57, 937, 31, 939, 940, 59, 60, 943, 75,
- 80, 77, 896, 74, 898, 899, 900, 1243, 59, 60,
- 937, 54, 59, 1381, 1298, 59, 60, 985, 11, 62,
- 1004, 59, 60, 1035, 9, 109, 1035, 12, 48, 1397,
- 54, 74, 56, 57, 58, 808, 56, 57, 108, 1048,
- 985, 59, 60, 937, 1027, 59, 60, 941, 942, 943,
- 1033, 1034, 59, 998, 1037, 1038, 108, 896, 1041, 1004,
- 80, 900, 47, 899, 900, 74, 1011, 1142, 1143, 108,
- 1016, 1017, 59, 60, 59, 108, 61, 62, 1023, 64,
- 4, 5, 54, 3, 4, 5, 6, 796, 797, 798,
- 75, 985, 77, 54, 8, 9, 1171, 1172, 937, 1045,
- 14, 62, 108, 1048, 943, 59, 60, 943, 93, 94,
- 74, 59, 1057, 74, 1059, 1483, 64, 1011, 74, 109,
- 44, 41, 36, 108, 74, 109, 1048, 75, 48, 1023,
- 54, 45, 56, 57, 1146, 1503, 56, 57, 3, 4,
- 5, 1014, 1087, 111, 111, 108, 985, 27, 74, 985,
- 54, 54, 74, 111, 1048, 1100, 111, 108, 943, 62,
- 80, 54, 108, 1057, 1532, 1059, 108, 58, 88, 62,
- 108, 74, 1011, 1497, 1142, 1143, 1144, 1048, 54, 8,
- 1497, 74, 111, 93, 1023, 1100, 47, 1297, 59, 1173,
- 64, 56, 57, 58, 1562, 1296, 1205, 1298, 1155, 1144,
- 985, 93, 1570, 1171, 1172, 1173, 54, 109, 59, 1048,
- 60, 36, 1014, 108, 1048, 64, 60, 1501, 1057, 64,
- 1059, 1166, 1591, 74, 75, 64, 77, 62, 1173, 108,
- 108, 1166, 64, 108, 64, 1219, 1220, 1221, 1222, 108,
- 4, 5, 64, 111, 1166, 9, 1048, 93, 1142, 1143,
- 1144, 59, 62, 108, 1200, 1201, 108, 1203, 1204, 75,
- 1206, 3, 4, 5, 6, 108, 108, 108, 75, 3,
- 4, 5, 1166, 7, 8, 9, 75, 1171, 1172, 1173,
- 75, 108, 108, 47, 62, 62, 3, 4, 5, 6,
- 54, 59, 56, 57, 108, 1166, 62, 31, 1282, 41,
- 111, 94, 36, 108, 108, 1144, 70, 1143, 1144, 3,
- 4, 5, 54, 111, 56, 57, 80, 88, 60, 90,
- 62, 92, 56, 57, 41, 88, 90, 1166, 70, 93,
- 94, 74, 47, 108, 1173, 108, 1172, 1173, 80, 56,
- 57, 111, 111, 108, 1289, 59, 88, 3, 4, 5,
- 108, 93, 1297, 108, 1299, 1338, 1339, 1142, 1143, 1144,
- 1501, 1306, 56, 57, 1299, 109, 137, 1289, 139, 108,
- 1315, 1306, 109, 1357, 60, 64, 64, 1299, 1475, 4,
- 5, 59, 1328, 1329, 1306, 59, 1171, 1172, 1173, 108,
- 3, 4, 5, 93, 93, 1289, 108, 93, 54, 109,
- 56, 57, 93, 1478, 1479, 1299, 1390, 109, 3, 4,
- 5, 6, 1306, 108, 9, 108, 108, 8, 1289, 3,
- 4, 5, 47, 1296, 1407, 1298, 1529, 111, 1299, 54,
- 111, 56, 57, 108, 33, 1306, 3, 4, 5, 6,
- 1408, 54, 9, 56, 57, 70, 41, 108, 108, 108,
- 1289, 109, 47, 108, 108, 80, 108, 108, 108, 54,
- 1299, 56, 57, 108, 48, 90, 64, 1306, 93, 94,
- 1454, 108, 56, 57, 41, 70, 1460, 1461, 54, 108,
- 47, 1427, 1428, 1429, 108, 80, 47, 54, 62, 56,
- 57, 111, 108, 88, 108, 90, 1480, 108, 93, 94,
- 3, 4, 5, 70, 7, 8, 9, 96, 62, 1454,
- 1478, 1479, 1480, 80, 1459, 1460, 1461, 62, 60, 1464,
- 60, 88, 9, 90, 1459, 1298, 93, 94, 60, 1464,
- 80, 81, 82, 83, 84, 1480, 16, 1459, 1460, 108,
- 1486, 1487, 1464, 108, 108, 316, 108, 3, 4, 5,
- 108, 1534, 1497, 56, 57, 108, 93, 1541, 398, 1504,
- 1454, 60, 93, 60, 64, 1459, 1460, 1461, 1513, 1504,
- 1464, 54, 1408, 1557, 93, 111, 93, 17, 1513, 60,
- 54, 107, 1504, 354, 1478, 1479, 97, 108, 1459, 1460,
- 60, 1513, 48, 1464, 108, 1579, 1541, 11, 108, 108,
- 56, 57, 1586, 1497, 93, 60, 60, 60, 1554, 14,
- 1504, 59, 64, 108, 60, 1454, 456, 22, 1563, 1513,
- 1459, 1460, 1461, 1408, 108, 1464, 108, 11, 1563, 1502,
- 60, 11, 60, 1504, 2, 0, 0, 3, 4, 5,
- 6, 1563, 1513, 1479, 1480, 0, 166, 1541, 35, 1395,
- 165, 3, 4, 5, 6, 659, 1601, 937, 1497, 161,
- 65, 3, 4, 5, 1528, 1504, 1601, 773, 430, 1563,
- 1155, 94, 38, 39, 1513, 41, 139, 448, 449, 1601,
- 3, 4, 5, 6, 1380, 456, 9, 1601, 54, 41,
- 56, 57, 1563, 1478, 1479, 1480, 48, 1233, 3, 4,
- 5, 80, 1541, 295, 56, 57, 923, 1601, 708, 449,
- 918, 1187, 237, 1009, 56, 57, 456, 773, 41, 124,
- 780, 302, 303, 642, 1563, 104, 1207, 916, 1501, 196,
- 1601, 54, 590, 56, 57, 342, 88, 318, 124, 1299,
- 321, 146, 1167, 324, 1570, 1549, 327, 70, 519, 520,
- 331, 56, 57, 1518, 133, 1580, 993, 80, 339, 3,
- 4, 5, 1601, 142, 1582, 88, -1, 1315, -1, 609,
- 93, -1, 3, 4, 5, 6, 616, -1, 9, -1,
- 520, 552, -1, 554, -1, -1, 557, 558, -1, 560,
- 561, 562, 563, 564, 565, 566, 567, 568, 569, 570,
- 571, 572, 573, 574, 575, 576, 577, 578, -1, 580,
- 41, -1, 56, 57, -1, 586, 47, 3, 4, 5,
- 199, 7, -1, 54, -1, 56, 57, -1, 233, 234,
- -1, -1, 3, 4, 5, -1, -1, -1, 4, 70,
- 580, -1, 247, -1, 30, 616, 586, -1, 14, 80,
- -1, 37, 623, -1, 233, 4, 5, 88, 24, 90,
- 9, -1, 93, 94, 30, 31, -1, 33, 54, 35,
- 56, 57, -1, -1, 645, 646, 42, -1, -1, 258,
- -1, -1, -1, 623, 724, 56, 57, -1, -1, 55,
- 661, 57, -1, -1, 3, 4, 5, 6, 47, 65,
- -1, -1, 3, 4, 5, 54, 72, 56, 57, -1,
- -1, -1, 317, 3, 4, 5, 6, 83, 84, 9,
- -1, 70, -1, -1, -1, 57, -1, 59, -1, -1,
- -1, 80, 41, 65, 3, 4, 5, 708, -1, 48,
- 106, 90, -1, 783, 93, 94, -1, 56, 57, 789,
- -1, 41, -1, -1, 359, 56, 57, 47, -1, 540,
- 541, -1, -1, 368, 54, -1, 56, 57, 134, -1,
- 136, 350, -1, -1, 140, -1, 381, 143, 144, 88,
- 70, 147, 148, 149, 449, -1, -1, 56, 57, -1,
- 80, 456, -1, 764, -1, 161, -1, -1, 88, 165,
- 90, -1, -1, 93, 94, 171, 172, -1, -1, -1,
- -1, -1, -1, 784, 785, -1, 787, -1, 47, -1,
- -1, -1, -1, 189, 190, 191, -1, -1, 407, -1,
- -1, 802, -1, -1, 3, 4, 5, 6, -1, -1,
- 172, 3, 4, 5, 6, -1, 178, -1, -1, -1,
- -1, -1, 218, 824, -1, 520, 896, 86, 87, -1,
- 900, -1, 91, 92, 93, 94, -1, -1, 234, -1,
- -1, -1, 41, 205, -1, -1, -1, -1, 244, 41,
- -1, 213, 214, -1, 489, 856, 857, 56, 57, 255,
- 861, 862, 54, -1, 56, 57, -1, 937, 60, -1,
- -1, -1, -1, 943, -1, 876, -1, 878, 70, 880,
- 489, -1, -1, -1, -1, 580, 856, 857, 80, 88,
- -1, 586, 862, -1, -1, -1, 88, 293, 294, -1,
- -1, 93, -1, -1, -1, -1, 876, 516, 878, -1,
- 880, -1, -1, -1, 915, 985, 7, 8, 9, 554,
- -1, 616, -1, 14, 925, 4, 5, -1, 623, -1,
- 9, -1, 3, 4, 5, 6, 7, 8, 9, 940,
- 31, 1011, 338, 14, -1, 36, 342, -1, 344, 345,
- 346, -1, 953, 1023, 45, 925, -1, -1, -1, 355,
- 31, -1, -1, 598, -1, 36, -1, 968, 47, 60,
- 41, -1, -1, -1, 45, 54, 47, 56, 57, -1,
- -1, -1, -1, 54, 985, 56, 57, 1057, -1, 1059,
- -1, 70, -1, 389, 603, -1, -1, -1, 968, 70,
- -1, 80, 398, -1, 400, 401, -1, -1, -1, 80,
- 619, 90, -1, -1, 93, 94, -1, 88, 414, 90,
- -1, 417, 93, 94, -1, 1026, 422, -1, -1, -1,
- -1, -1, 667, -1, 430, -1, -1, -1, -1, 401,
- 402, -1, 1, 678, 3, 4, 5, 6, -1, 8,
- -1, -1, -1, -1, -1, 3, 4, 5, 6, 870,
- -1, 9, 458, -1, 460, -1, 462, 463, 464, -1,
- -1, -1, 468, 708, 1144, 1076, 1077, 473, -1, 1080,
- 476, -1, 41, -1, -1, -1, -1, 898, 899, 48,
- -1, -1, -1, 41, -1, 54, 492, 56, 57, 1100,
- -1, -1, -1, 1173, -1, 467, 54, 802, 56, 57,
- -1, -1, 474, 475, -1, -1, 478, 7, 8, 9,
- 482, -1, 70, -1, 14, -1, -1, -1, -1, 88,
- -1, -1, 80, 495, 530, 531, 532, 533, -1, -1,
- 88, 31, -1, -1, -1, 93, 36, -1, 3, 4,
- 5, 6, -1, -1, 9, 45, 1157, -1, 1159, -1,
- 1161, 856, 857, -1, -1, -1, -1, 862, 1169, 78,
- 79, 80, 81, 82, 83, 84, -1, 1178, 1179, -1,
- -1, 876, 1183, 878, -1, 880, 41, 1157, -1, 1159,
- -1, 1161, -1, -1, 590, -1, 592, 1198, 1199, 54,
- -1, 56, 57, -1, -1, 7, 8, 9, 604, -1,
- 606, 607, 14, 609, -1, 70, -1, -1, -1, -1,
- 616, -1, 1223, -1, 620, 80, -1, -1, -1, 31,
- 925, -1, -1, 88, 36, -1, -1, -1, 93, 635,
- -1, -1, -1, 45, 740, -1, -1, -1, -1, -1,
- -1, -1, -1, 1254, -1, 3, 4, 5, 6, -1,
- -1, -1, -1, 659, -1, -1, 3, 4, 5, 6,
- 666, -1, -1, 968, 636, -1, -1, 1278, 674, 675,
- 676, 677, 678, 679, 1254, -1, 782, 1098, 923, -1,
- 985, -1, 788, 41, -1, 904, -1, 906, -1, 47,
- -1, 936, -1, -1, 41, -1, 54, -1, 56, 57,
- -1, 48, -1, 675, -1, 677, 678, 1318, -1, 56,
- 57, -1, 70, -1, 720, -1, -1, -1, 724, -1,
- -1, -1, 80, 1334, -1, 731, 732, -1, 734, 948,
- 88, -1, 90, 80, -1, 93, 94, -1, -1, -1,
- -1, 88, -1, -1, -1, 1356, -1, -1, 720, -1,
- 1171, 1172, -1, -1, -1, -1, 762, -1, -1, 765,
- -1, 767, -1, -1, -1, -1, 772, 773, 774, -1,
- 742, -1, -1, 745, 780, -1, -1, 783, -1, -1,
- -1, -1, -1, 789, -1, 891, -1, 893, -1, -1,
- 796, 797, 798, -1, -1, -1, -1, 1408, -1, -1,
- -1, 773, 808, -1, -1, -1, -1, 779, -1, -1,
- -1, -1, -1, -1, 1425, 1426, 1035, 1497, -1, -1,
- -1, 4, 5, 1434, 7, 8, 9, -1, -1, 12,
- -1, 14, 1077, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 84, 28, -1, 30, 31, -1,
- -1, 1462, 1157, 36, 1159, -1, 1161, -1, -1, -1,
- -1, -1, 45, -1, 47, -1, -1, -1, 1289, -1,
- -1, 54, -1, 56, 57, 881, -1, 883, -1, -1,
- -1, -1, -1, -1, 890, -1, -1, 70, 894, -1,
- 896, -1, 898, 899, 900, -1, -1, 80, -1, 905,
- 1119, -1, -1, -1, -1, -1, -1, 90, -1, -1,
- 93, 94, -1, 3, 4, 5, 6, -1, 1163, -1,
- -1, -1, -1, -1, 1169, -1, -1, 1146, -1, -1,
- -1, 937, -1, 939, 4, 941, 942, 943, -1, -1,
- -1, -1, -1, -1, 14, -1, -1, -1, -1, 1254,
- 1056, 41, 1058, 23, 24, -1, -1, -1, 48, -1,
- 30, 31, -1, 33, 936, 35, 56, 57, -1, -1,
- -1, -1, 42, -1, -1, 3, 4, 5, 6, 985,
- 1591, -1, -1, -1, -1, 55, 1205, 57, -1, -1,
- 80, -1, 998, -1, -1, 65, -1, -1, 88, -1,
- -1, -1, 72, -1, -1, 1011, -1, 1113, 1014, -1,
- -1, -1, -1, 41, 84, -1, -1, 1023, -1, -1,
- 48, -1, -1, -1, -1, -1, -1, -1, 56, 57,
- 1036, -1, -1, -1, -1, -1, -1, -1, 1283, 1284,
- -1, -1, 1048, -1, 1016, 1017, -1, -1, -1, -1,
- -1, 1057, 80, 1059, -1, -1, -1, 1478, 1479, -1,
- 88, -1, 3, 4, 5, 6, 136, -1, 9, -1,
- 140, -1, -1, 1045, 144, -1, -1, 147, 148, 149,
- -1, 1087, -1, -1, -1, 1191, 1092, 1093, -1, 1095,
- 1196, 161, -1, -1, -1, 165, -1, 189, 190, 191,
- 41, 171, 172, 1408, -1, 3, 4, 5, 6, -1,
- -1, 9, -1, 54, -1, 56, 57, -1, -1, 189,
- 190, 191, -1, 3, 4, 5, 6, 1372, -1, 70,
- -1, -1, -1, -1, 1140, 1141, 1142, 1143, 1144, 80,
- -1, 1247, 1148, 41, -1, -1, -1, 88, 218, 1394,
- 1395, -1, 93, -1, -1, -1, 54, -1, 56, 57,
- -1, 41, -1, -1, -1, 1171, 1172, 1173, 48, -1,
- -1, -1, 70, -1, -1, -1, 56, 57, -1, -1,
- -1, -1, 80, -1, -1, 255, -1, -1, -1, -1,
- 88, -1, -1, -1, -1, 93, 1202, -1, -1, -1,
- 80, 1207, -1, -1, -1, -1, -1, -1, 88, -1,
+ 174, 161, 209, 23, 176, 4, 149, 150, 402, 175,
+ 355, 402, 126, 80, 734, 156, 62, 4, 251, 349,
+ 482, 80, 355, 4, 402, 455, 14, 4, 134, 898,
+ 35, 511, 84, 513, 46, 583, 35, 42, 55, 709,
+ 247, 521, 209, 30, 31, 90, 733, 92, 35, 304,
+ 305, 218, 57, 4, 35, 42, 133, 134, 35, 640,
+ 460, 42, 620, 663, 76, 42, 647, 72, 373, 124,
+ 42, 217, 218, 42, 55, 440, 57, 144, 4, 84,
+ 133, 4, 337, 88, 35, 90, 11, 92, 1400, 296,
+ 1327, 42, 137, 780, 140, 83, 1486, 84, 1337, 42,
+ 42, 1487, 107, 108, 12, 1344, 47, 54, 58, 35,
+ 156, 57, 35, 11, 11, 47, 42, 717, 106, 42,
+ 356, 357, 355, 64, 62, 1488, 54, 38, 33, 59,
+ 54, 136, 137, 84, 139, 0, 203, 62, 1528, 75,
+ 1510, 77, 349, 54, 37, 75, 74, 577, 98, 136,
+ 74, 59, 93, 94, 62, 136, 64, 1527, 175, 140,
+ 165, 93, 149, 150, 169, 1, 212, 33, 0, 503,
+ 108, 176, 408, 409, 220, 782, 1, 1, 165, 641,
+ 306, 307, 169, 108, 165, 136, 245, 794, 169, 716,
+ 136, 237, 169, 165, 175, 176, 322, 169, 1561, 325,
+ 169, 213, 328, 262, 109, 331, 193, 194, 155, 335,
+ 108, 108, 1582, 136, 165, 822, 109, 343, 169, 47,
+ 1606, 828, 58, 1531, 27, 555, 169, 169, 31, 59,
+ 176, 1621, 490, 58, 58, 62, 74, 62, 62, 12,
+ 245, 222, 165, 169, 25, 27, 169, 74, 9, 31,
+ 1487, 402, 1491, 200, 1566, 47, 59, 60, 245, 42,
+ 248, 64, 60, 74, 245, 93, 94, 1575, 526, 346,
+ 95, 95, 3, 4, 5, 6, 59, 58, 60, 109,
+ 108, 62, 64, 149, 150, 151, 59, 393, 448, 62,
+ 342, 58, 297, 346, 245, 1061, 1062, 64, 1537, 245,
+ 61, 93, 94, 33, 7, 735, 976, 3, 4, 5,
+ 41, 109, 1078, 358, 95, 660, 108, 468, 4, 245,
+ 487, 699, 245, 54, 329, 56, 57, 109, 935, 195,
+ 385, 474, 475, 60, 37, 108, 59, 342, 48, 897,
+ 486, 487, 4, 5, 1583, 350, 8, 9, 494, 35,
+ 59, 93, 14, 358, 359, 342, 93, 88, 939, 59,
+ 56, 57, 756, 728, 729, 756, 28, 355, 30, 59,
+ 47, 93, 359, 54, 36, 75, 4, 77, 359, 525,
+ 60, 60, 109, 45, 689, 108, 169, 404, 4, 5,
+ 59, 342, 54, 74, 56, 57, 629, 402, 544, 108,
+ 405, 1270, 983, 74, 450, 8, 9, 35, 359, 74,
+ 47, 14, 47, 359, 60, 402, 93, 94, 108, 149,
+ 150, 151, 752, 404, 951, 402, 209, 954, 664, 109,
+ 109, 93, 980, 36, 217, 218, 359, 442, 54, 108,
+ 56, 57, 45, 93, 47, 571, 572, 493, 1048, 1030,
+ 107, 402, 511, 498, 513, 442, 93, 94, 93, 33,
+ 519, 442, 521, 468, 247, 195, 1232, 25, 995, 996,
+ 442, 108, 47, 442, 936, 1241, 1242, 47, 1244, 47,
+ 1087, 468, 1089, 47, 496, 47, 31, 474, 475, 640,
+ 93, 442, 58, 498, 107, 108, 647, 47, 1185, 480,
+ 900, 518, 514, 515, 47, 550, 511, 488, 513, 25,
+ 4, 27, 524, 296, 519, 47, 521, 468, 93, 442,
+ 1389, 64, 60, 93, 511, 93, 513, 54, 47, 93,
+ 511, 93, 513, 4, 521, 1222, 54, 518, 519, 44,
+ 521, 35, 58, 93, 108, 550, 62, 74, 553, 54,
+ 93, 556, 57, 727, 74, 560, 561, 562, 563, 564,
+ 511, 93, 513, 54, 35, 511, 349, 513, 573, 621,
+ 521, 42, 518, 519, 93, 521, 150, 151, 583, 95,
+ 109, 586, 12, 977, 690, 511, 977, 513, 511, 1019,
+ 513, 697, 47, 1174, 54, 521, 58, 1077, 521, 977,
+ 945, 93, 838, 54, 25, 756, 27, 54, 474, 475,
+ 476, 25, 945, 27, 74, 47, 621, 54, 62, 75,
+ 697, 195, 1203, 406, 108, 1152, 1153, 47, 774, 59,
+ 74, 782, 62, 62, 621, 640, 47, 58, 93, 94,
+ 847, 62, 647, 794, 58, 108, 62, 692, 62, 666,
+ 637, 638, 94, 640, 54, 3, 4, 5, 74, 442,
+ 647, 93, 62, 651, 1126, 136, 3, 4, 5, 108,
+ 621, 822, 1359, 93, 95, 31, 108, 828, 698, 108,
+ 58, 95, 93, 94, 62, 666, 941, 692, 705, 640,
+ 707, 708, 1458, 1459, 165, 47, 647, 47, 169, 108,
+ 25, 706, 27, 486, 487, 710, 1106, 1107, 56, 57,
+ 11, 494, 945, 733, 64, 1049, 329, 1051, 47, 56,
+ 57, 1055, 8, 9, 705, 706, 707, 708, 14, 7,
+ 8, 9, 80, 58, 970, 752, 14, 62, 109, 806,
+ 98, 93, 525, 93, 474, 475, 476, 806, 47, 60,
+ 36, 756, 47, 31, 62, 329, 815, 47, 36, 45,
+ 47, 544, 1122, 1123, 93, 1125, 74, 45, 785, 756,
+ 95, 752, 4, 5, 245, 756, 93, 782, 823, 824,
+ 3, 826, 60, 909, 935, 141, 798, 60, 939, 794,
+ 146, 1121, 804, 805, 93, 782, 808, 809, 93, 1199,
+ 812, 111, 943, 93, 785, 756, 93, 794, 1208, 1209,
+ 815, 937, 938, 1213, 4, 5, 48, 822, 823, 824,
+ 54, 826, 74, 828, 56, 57, 977, 62, 815, 1003,
+ 47, 782, 983, 94, 815, 822, 480, 54, 194, 785,
+ 74, 828, 62, 794, 488, 1081, 1082, 1083, 80, 1569,
+ 27, 94, 465, 47, 31, 429, 430, 74, 48, 74,
+ 54, 1261, 59, 60, 815, 111, 56, 57, 93, 815,
+ 74, 822, 93, 3, 4, 5, 93, 828, 3, 1030,
+ 74, 6, 59, 60, 667, 1219, 1220, 1221, 359, 815,
+ 80, 896, 815, 47, 59, 60, 901, 943, 74, 93,
+ 54, 475, 476, 259, 1018, 74, 31, 59, 3, 4,
+ 5, 6, 3, 4, 5, 182, 41, 835, 836, 837,
+ 74, 988, 59, 60, 929, 708, 56, 57, 58, 11,
+ 935, 56, 57, 108, 939, 109, 1087, 59, 1089, 93,
+ 553, 59, 60, 556, 108, 70, 41, 560, 935, 108,
+ 937, 938, 939, 48, 74, 80, 1356, 945, 59, 60,
+ 573, 56, 57, 88, 108, 56, 57, 54, 93, 752,
+ 74, 442, 977, 586, 979, 980, 74, 590, 983, 553,
+ 108, 1411, 556, 109, 935, 80, 1386, 111, 939, 108,
+ 977, 774, 109, 88, 981, 982, 983, 1427, 572, 573,
+ 977, 111, 1128, 4, 5, 618, 1336, 27, 3, 4,
+ 5, 624, 586, 1072, 74, 4, 5, 74, 1077, 54,
+ 9, 59, 60, 1174, 54, 1030, 977, 62, 74, 1172,
+ 1173, 111, 983, 3, 4, 5, 6, 111, 1043, 74,
+ 511, 108, 513, 1030, 108, 1281, 108, 48, 58, 54,
+ 521, 54, 1203, 48, 108, 56, 57, 62, 1201, 1202,
+ 8, 56, 57, 419, 847, 54, 422, 56, 57, 74,
+ 111, 41, 1077, 647, 93, 1201, 1202, 64, 434, 1030,
+ 1510, 70, 1087, 59, 1089, 1130, 56, 57, 1069, 47,
+ 1077, 80, 59, 1074, 59, 60, 1077, 1527, 74, 75,
+ 1087, 77, 1089, 4, 5, 94, 4, 5, 93, 1176,
+ 83, 84, 1117, 54, 470, 54, 472, 983, 88, 59,
+ 60, 62, 1552, 4, 5, 1130, 1077, 1521, 109, 485,
+ 1521, 1077, 60, 74, 59, 60, 1087, 36, 1089, 3,
+ 4, 5, 64, 7, 8, 9, 64, 48, 59, 60,
+ 48, 1077, 1582, 108, 1077, 56, 57, 64, 56, 57,
+ 1590, 108, 62, 1335, 1030, 1185, 60, 31, 1334, 1174,
+ 1336, 108, 36, 54, 108, 56, 57, 4, 5, 80,
+ 54, 9, 80, 75, 12, 1172, 1173, 1174, 62, 70,
+ 54, 1196, 56, 57, 58, 1525, 108, 1196, 1203, 80,
+ 74, 1327, 108, 64, 3, 4, 5, 6, 64, 1196,
+ 9, 1611, 1217, 94, 1201, 1202, 1203, 54, 54, 47,
+ 64, 111, 62, 1174, 59, 62, 62, 1239, 1240, 56,
+ 57, 59, 31, 61, 62, 59, 64, 74, 74, 103,
+ 104, 105, 41, 108, 75, 1196, 59, 75, 47, 77,
+ 108, 64, 1203, 983, 108, 54, 108, 56, 57, 108,
+ 75, 74, 75, 75, 75, 93, 94, 841, 4, 5,
+ 1196, 70, 62, 1196, 108, 108, 30, 31, 62, 33,
+ 108, 80, 78, 79, 80, 81, 82, 83, 84, 88,
+ 59, 90, 905, 111, 93, 94, 62, 94, 108, 108,
+ 1030, 108, 88, 57, 74, 59, 1172, 1173, 1174, 111,
+ 47, 65, 60, 3, 4, 5, 6, 1334, 1525, 1336,
+ 56, 57, 1327, 108, 111, 108, 939, 108, 108, 111,
+ 1335, 108, 1337, 109, 108, 1201, 1202, 1203, 1337, 1344,
+ 1327, 109, 1502, 59, 815, 1344, 64, 64, 1353, 93,
+ 1337, 41, 59, 1334, 1335, 1336, 108, 1344, 48, 3,
+ 4, 5, 1505, 1506, 938, 939, 56, 57, 64, 108,
+ 1521, 4, 5, 108, 108, 1549, 1327, 4, 5, 1505,
+ 1506, 93, 93, 93, 12, 93, 1337, 141, 109, 109,
+ 80, 8, 146, 1344, 108, 149, 150, 151, 88, 27,
+ 109, 1327, 108, 31, 1327, 108, 111, 763, 764, 983,
+ 766, 1337, 56, 57, 1337, 48, 108, 44, 1344, 47,
+ 108, 1344, 176, 56, 57, 1437, 108, 54, 182, 56,
+ 57, 59, 60, 108, 62, 111, 64, 108, 108, 193,
+ 194, 195, 1172, 1173, 1174, 33, 108, 80, 54, 108,
+ 7, 8, 9, 108, 62, 209, 1030, 14, 111, 108,
+ 3, 4, 5, 217, 218, 93, 94, 47, 62, 108,
+ 108, 1201, 1202, 1203, 31, 96, 1481, 62, 60, 36,
+ 108, 1486, 1487, 1488, 60, 9, 1491, 1486, 45, 60,
+ 16, 64, 1491, 108, 1481, 3, 4, 5, 108, 1486,
+ 1487, 1488, 1507, 60, 1491, 259, 108, 108, 108, 1526,
+ 777, 54, 108, 56, 57, 58, 1521, 108, 1505, 1506,
+ 787, 788, 108, 1528, 93, 93, 60, 4, 5, 1528,
+ 1481, 60, 1537, 54, 1521, 1486, 1487, 1488, 1537, 47,
+ 1491, 1528, 1554, 93, 111, 1526, 54, 814, 56, 57,
+ 1537, 93, 819, 1336, 17, 60, 1561, 54, 107, 97,
+ 1486, 1487, 108, 1486, 1487, 1491, 60, 108, 1491, 108,
+ 1521, 48, 1438, 108, 1561, 329, 11, 1528, 1583, 56,
+ 57, 60, 60, 93, 1583, 93, 1537, 11, 60, 59,
+ 1203, 80, 81, 82, 83, 84, 1583, 64, 60, 1173,
+ 1174, 108, 1528, 80, 1217, 1528, 1077, 108, 108, 47,
+ 1561, 1537, 60, 11, 1537, 88, 1621, 90, 60, 92,
+ 0, 0, 1621, 0, 2, 170, 982, 35, 1202, 1203,
+ 1425, 690, 1583, 977, 1621, 4, 5, 169, 442, 1505,
+ 1506, 1507, 165, 519, 1257, 1258, 1259, 1260, 86, 87,
+ 1185, 405, 406, 91, 92, 93, 94, 1583, 1548, 238,
+ 1583, 94, 4, 5, 137, 419, 139, 9, 422, 1410,
+ 1621, 139, 1621, 1271, 428, 429, 430, 299, 963, 740,
+ 434, 3, 4, 5, 6, 54, 958, 56, 57, 243,
+ 519, 4, 5, 1359, 1222, 1621, 9, 1074, 1621, 815,
+ 956, 70, 673, 4, 5, 47, 621, 1320, 1438, 200,
+ 346, 80, 54, 124, 56, 57, 470, 1337, 472, 41,
+ 474, 475, 476, 1197, 1569, 479, 48, 1590, 70, 1542,
+ 80, 485, 486, 487, 56, 57, 490, -1, 80, 1600,
+ 494, 54, 1525, 56, 57, 1602, 47, 1038, 90, 1353,
+ -1, 93, 94, 54, 104, 56, 57, 70, 80, 3,
+ 4, 5, 6, -1, -1, 519, 88, 80, -1, 70,
+ -1, -1, 526, -1, 1387, 1505, 1506, 1507, 772, 80,
+ -1, -1, -1, 133, -1, -1, -1, -1, -1, 90,
+ -1, -1, 93, 94, 144, -1, -1, 41, -1, 553,
+ 1067, 1068, 556, 1070, 1071, -1, 1073, 1420, 3, 4,
+ 5, -1, 56, 57, 1170, 1171, -1, 571, 572, 573,
+ -1, 461, 1178, -1, -1, -1, -1, 821, 468, -1,
+ -1, -1, 586, 827, -1, -1, 1, -1, 3, 4,
+ 5, 6, 7, 8, 9, -1, -1, 320, -1, 14,
+ 3, 4, 5, 203, 3, 4, 5, -1, 7, 8,
+ 9, 56, 57, 28, 1438, 30, 31, 32, 1481, -1,
+ -1, 36, -1, -1, 1487, 1488, 41, 30, -1, -1,
+ 45, 46, 31, 48, -1, 358, -1, 36, 238, 54,
+ -1, 56, 57, 647, 1507, 60, -1, 62, -1, -1,
+ -1, 54, 461, 56, 57, 70, -1, 56, 57, 468,
+ -1, 551, 262, 667, -1, 80, 14, -1, -1, -1,
+ -1, -1, -1, 88, 22, -1, -1, -1, 93, 3,
+ 4, 5, 1506, 1507, -1, -1, 930, -1, 932, 1295,
+ 1296, -1, 1298, -1, 348, 349, 350, -1, 1561, -1,
+ -1, -1, 706, -1, 708, 709, -1, -1, -1, -1,
+ -1, -1, 1229, 1230, 1577, -1, -1, 65, 3, 4,
+ 5, 611, 7, 8, 9, -1, -1, 617, 3, 4,
+ 5, 6, 56, 57, 9, -1, 1599, 460, 461, 3,
+ 4, 5, 551, 1606, -1, 468, -1, -1, 752, -1,
+ 3, 4, 5, 6, 354, -1, 31, -1, -1, 763,
+ 764, -1, 766, -1, 654, -1, 41, -1, -1, -1,
+ 774, 56, 57, 777, -1, 498, 124, -1, -1, 54,
+ -1, 56, 57, 787, 788, 38, 39, 510, 41, -1,
+ 107, 108, 56, 57, -1, 70, 3, 4, 5, -1,
+ 148, 54, 611, 56, 57, 80, -1, -1, 617, -1,
+ 814, -1, 412, 88, 1058, 819, -1, -1, 93, 1063,
+ -1, -1, -1, -1, -1, -1, -1, 550, 551, -1,
+ -1, -1, -1, -1, -1, -1, -1, 841, 647, -1,
+ -1, -1, 1086, -1, 1088, 654, -1, 54, -1, 56,
+ 57, -1, -1, 1370, 1371, 1372, -1, -1, -1, -1,
+ 583, -1, 585, -1, -1, 588, 589, -1, 591, 592,
+ 593, 594, 595, 596, 597, 598, 599, 600, 601, 602,
+ 603, 604, 605, 606, 607, 608, 609, -1, 611, -1,
+ 238, 239, -1, -1, 617, -1, -1, -1, -1, 1143,
+ -1, -1, 502, 251, 3, 4, 5, 6, 7, 8,
+ 9, 3, 4, 5, 6, 14, -1, -1, -1, -1,
+ -1, 3, 4, 5, 647, -1, -1, -1, -1, -1,
+ -1, 654, 31, 937, 938, 939, -1, 36, 1455, 1456,
+ -1, -1, 41, -1, -1, -1, 45, 547, 47, 41,
+ 3, 4, 5, 676, 677, 54, 48, 56, 57, -1,
+ -1, 7, 8, 9, 56, 57, 48, -1, 14, 692,
+ -1, 70, 976, 321, 56, 57, -1, 981, 982, 983,
+ -1, 80, -1, 637, 638, 31, -1, -1, 80, 88,
+ 36, 90, -1, -1, 93, 94, 88, -1, -1, 45,
+ -1, 54, -1, 56, 57, 895, 896, 7, 8, 9,
+ -1, 901, 329, -1, 14, 363, -1, 740, -1, -1,
+ -1, -1, -1, -1, 372, 915, 1030, 917, -1, 919,
+ -1, 31, 841, -1, 634, -1, 36, 385, 4, 5,
+ -1, 1285, 8, 9, -1, 45, -1, -1, 14, -1,
+ 650, 705, -1, 707, 708, -1, 710, 1574, 3, 4,
+ 5, 6, -1, 1067, 1068, -1, 1070, 1071, -1, 1073,
+ 36, -1, -1, -1, 797, 965, -1, -1, -1, 45,
+ -1, 47, -1, -1, -1, 402, 895, 896, 54, -1,
+ 56, 57, 901, -1, -1, -1, 41, -1, 752, -1,
+ 823, 824, 47, 826, 70, -1, 915, -1, 917, 54,
+ 919, 56, 57, -1, 80, -1, -1, -1, 841, 1363,
+ 1364, 1011, -1, -1, 90, 70, -1, 93, 94, -1,
+ -1, -1, -1, 1377, 1378, 80, -1, 3, 4, 5,
+ 863, 7, -1, 88, -1, 90, -1, -1, 93, 94,
+ 1394, 468, -1, -1, 502, -1, 965, -1, -1, -1,
+ -1, -1, -1, -1, 30, -1, 1170, 1171, 1172, 1173,
+ 1174, 37, 895, 896, 1178, -1, -1, 900, 901, 76,
+ 77, 78, 79, 80, 81, 82, 83, 84, 54, -1,
+ 56, 57, 915, 847, 917, -1, 919, 1201, 1202, 1203,
+ -1, -1, 1011, -1, -1, -1, 806, 71, 72, 73,
+ 74, 75, 76, 77, 78, 79, 80, 81, 82, 83,
+ 84, 1030, 1466, 1467, -1, 1229, 1230, -1, -1, -1,
+ -1, -1, 955, -1, -1, -1, 553, 585, -1, 556,
+ -1, -1, 965, 560, 561, 562, 563, 564, -1, 3,
+ 4, 5, 6, -1, -1, 9, 573, 980, -1, -1,
+ 3, 4, 5, 6, -1, -1, 920, -1, 922, 586,
+ 993, -1, -1, -1, -1, -1, -1, 31, -1, 933,
+ -1, 629, -1, 937, 938, -1, -1, 41, 1011, -1,
+ -1, 1295, 1296, 47, 1298, -1, -1, 1187, 41, 1189,
+ 54, 1191, 56, 57, -1, 48, -1, 1030, -1, 3,
+ 4, 5, 6, 56, 57, 9, 70, 1, -1, 3,
+ 4, 5, 6, 640, 8, -1, 80, 981, 982, -1,
+ 647, 1335, 1336, -1, 88, -1, 90, 31, -1, 93,
+ 94, -1, 1065, 1066, 944, 88, 946, 41, -1, -1,
+ 698, -1, -1, 47, -1, -1, -1, 41, -1, -1,
+ 54, 709, 56, 57, 48, -1, 1370, 1371, 1372, -1,
+ 54, -1, 56, 57, -1, -1, 70, -1, 1187, -1,
+ 1189, -1, 1191, 1106, 1107, -1, 80, 1110, 988, -1,
+ -1, -1, 740, -1, 88, 4, 90, -1, -1, 93,
+ 94, -1, 1292, -1, 88, 14, -1, 1130, -1, -1,
+ -1, -1, -1, -1, -1, 24, -1, -1, -1, -1,
+ -1, 30, 31, -1, 33, -1, 35, -1, -1, -1,
+ -1, -1, -1, 42, 1438, -1, -1, -1, -1, 756,
+ -1, -1, -1, -1, -1, -1, 55, -1, 57, -1,
+ -1, 1455, 1456, -1, -1, -1, 65, -1, -1, -1,
+ -1, -1, -1, 72, 1187, 782, 1189, -1, 1191, -1,
+ -1, -1, 1072, -1, 83, 84, 1199, 794, -1, -1,
+ -1, -1, -1, 1292, -1, 1208, 1209, -1, -1, -1,
+ 1213, -1, -1, -1, -1, -1, -1, 106, -1, -1,
+ -1, 1505, 1506, 1507, -1, 822, -1, -1, -1, -1,
+ -1, 828, 1235, -1, -1, -1, 1170, 1171, 1172, 1173,
+ 3, 4, 5, 6, 1178, 134, -1, 136, -1, -1,
+ -1, 140, 141, -1, -1, -1, 145, 146, 1261, -1,
+ 149, 150, 151, -1, -1, -1, -1, 1201, 1202, 1149,
+ 3, 4, 5, 6, -1, -1, 165, -1, 41, -1,
+ 169, -1, -1, -1, -1, 48, 175, 176, -1, 1292,
+ 1574, -1, -1, 56, 57, -1, 1176, -1, 31, 896,
+ -1, -1, -1, -1, 193, 194, 195, -1, 41, -1,
+ -1, -1, -1, 1316, -1, -1, -1, 80, -1, -1,
+ -1, 54, -1, 56, 57, 88, 4, 5, -1, -1,
+ 8, 9, 929, 222, -1, 963, 14, 70, 935, -1,
+ -1, -1, 939, -1, -1, -1, -1, 80, 976, 1438,
+ 239, -1, -1, 1356, -1, 88, 245, -1, 36, 248,
+ 93, 1295, 1296, -1, 1298, 1368, 1369, 45, -1, 47,
+ 259, -1, -1, -1, -1, -1, 54, -1, 56, 57,
+ 977, -1, 979, 1386, -1, -1, 983, -1, 82, -1,
+ -1, -1, 70, -1, -1, -1, -1, -1, 4, 5,
+ -1, -1, 80, 9, -1, -1, -1, -1, 297, 298,
+ -1, -1, 90, -1, -1, 93, 94, -1, 193, 194,
+ 195, -1, -1, -1, 3, 4, 5, 6, -1, -1,
+ 9, -1, -1, 1030, -1, 1438, -1, -1, -1, -1,
+ -1, 47, -1, -1, -1, -1, 1043, -1, 54, -1,
+ 56, 57, 31, 342, -1, -1, -1, 346, 1461, 348,
+ 349, 350, 41, -1, 70, 159, -1, -1, -1, -1,
+ 359, -1, -1, -1, 80, 54, -1, 56, 57, 1107,
+ -1, -1, -1, -1, 90, -1, 1489, 93, 94, -1,
+ 1087, 70, 1089, -1, -1, -1, -1, 191, -1, -1,
+ -1, 80, -1, -1, 393, 3, 4, 5, 6, 88,
+ 204, -1, -1, 402, 93, 404, 405, -1, -1, -1,
+ 1117, -1, -1, -1, -1, -1, 4, 5, -1, -1,
+ 419, 9, -1, 422, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 41, -1, 434, -1, -1, -1, -1,
+ -1, -1, -1, 442, -1, -1, 54, -1, 56, 57,
+ 3, 4, 5, 6, 62, 1193, 9, -1, -1, 47,
+ -1, 1199, 70, -1, -1, -1, 54, 1174, 56, 57,
+ -1, 470, 80, 472, -1, 474, 475, 476, 31, -1,
+ 88, 480, 70, -1, -1, 93, 485, -1, 41, 488,
+ -1, -1, 80, -1, 47, -1, 1203, -1, 1611, -1,
+ -1, 54, 90, 56, 57, 93, 94, -1, -1, 508,
+ 1217, -1, 511, -1, 513, -1, -1, 70, -1, 518,
+ 519, -1, 521, -1, -1, -1, 1, 80, 3, 4,
+ 5, 6, 7, 8, 9, 88, -1, 90, -1, 14,
+ 93, 94, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 28, -1, 30, 31, 32, -1, -1,
+ -1, 36, 561, 562, 563, 564, 41, -1, -1, -1,
+ 45, -1, -1, 48, -1, -1, -1, -1, -1, 54,
+ -1, 56, 57, 1321, 1322, 470, -1, 472, -1, 474,
+ 475, 476, -1, -1, -1, 70, -1, -1, -1, -1,
+ 485, -1, -1, -1, -1, 80, -1, -1, -1, -1,
+ -1, -1, -1, 88, -1, -1, -1, -1, 93, -1,
+ -1, -1, 621, 98, 623, -1, -1, -1, -1, -1,
+ -1, -1, -1, 518, -1, -1, 635, -1, 637, 638,
+ -1, 640, -1, -1, -1, -1, 1353, -1, 647, 4,
+ 5, -1, 651, 8, 9, -1, -1, -1, -1, 14,
+ -1, -1, -1, -1, 1402, -1, -1, 666, -1, -1,
+ -1, -1, -1, 28, 478, 30, -1, -1, -1, 483,
+ -1, 36, -1, -1, -1, -1, 1424, 1425, -1, -1,
+ 45, 690, 47, -1, -1, -1, -1, -1, 697, 54,
+ -1, 56, 57, -1, -1, -1, 705, 706, 707, 708,
+ 709, 710, -1, -1, -1, 70, -1, -1, -1, -1,
+ -1, -1, -1, 527, -1, 80, -1, -1, -1, 533,
+ -1, -1, -1, -1, -1, 90, -1, -1, 93, 94,
+ -1, 545, 546, -1, 548, -1, -1, -1, -1, 3,
+ 4, 5, 6, 752, -1, -1, -1, 756, -1, -1,
+ -1, 1499, -1, -1, 763, 764, -1, 766, 3, 4,
+ 5, 6, 7, 8, 9, -1, -1, -1, -1, 14,
+ -1, -1, -1, 782, -1, -1, 785, 41, -1, -1,
+ -1, -1, -1, -1, 48, 794, 31, -1, -1, -1,
+ 1507, 36, 56, 57, -1, -1, 41, -1, 807, -1,
+ 45, -1, 47, -1, 1521, -1, 815, -1, -1, 54,
+ -1, 56, 57, 822, -1, -1, -1, -1, -1, 828,
+ -1, -1, -1, -1, 88, 70, 835, 836, 837, 643,
+ 644, -1, -1, -1, 648, 80, -1, -1, 847, -1,
+ -1, -1, -1, 88, -1, 90, -1, -1, 93, 94,
+ -1, -1, -1, -1, -1, 4, 5, -1, 7, 8,
+ 9, -1, -1, 12, -1, 14, 4, -1, 763, 764,
+ -1, 766, -1, -1, -1, -1, 14, -1, -1, 28,
+ -1, 30, 31, -1, -1, 23, 24, 36, -1, -1,
+ 785, -1, 30, 31, -1, 33, 45, 35, 47, -1,
+ -1, -1, -1, -1, 42, 54, -1, 56, 57, -1,
+ -1, 920, -1, 922, -1, -1, -1, 55, -1, 57,
+ 929, 70, -1, -1, 933, -1, 935, 65, 937, 938,
+ 939, 80, -1, -1, 72, -1, 945, 3, 4, 5,
+ 6, 90, -1, -1, 93, 94, 84, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 3, 4, 5, 6,
+ -1, -1, 9, -1, -1, -1, -1, 781, 977, -1,
+ 979, -1, 981, 982, 983, 41, -1, -1, -1, 793,
+ -1, -1, 48, -1, 31, -1, -1, -1, -1, -1,
+ 56, 57, -1, -1, 41, -1, -1, -1, 136, -1,
+ -1, -1, 140, 141, -1, -1, -1, 54, 146, 56,
+ 57, 149, 150, 151, -1, 829, -1, 831, -1, -1,
+ -1, 1030, 88, 70, -1, -1, -1, 165, -1, -1,
+ -1, 169, -1, 80, 1043, -1, -1, 175, 176, -1,
+ -1, 88, -1, -1, -1, -1, 93, -1, -1, -1,
+ -1, -1, -1, -1, -1, 193, 194, 195, -1, -1,
+ 1069, -1, -1, -1, -1, 1074, -1, -1, 1077, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, 1087, -1,
+ 1089, -1, -1, -1, 222, -1, 981, 982, 983, 903,
+ 904, -1, 906, 4, 5, -1, -1, 8, 9, -1,
+ 4, 5, -1, 14, 8, 9, -1, 245, 1117, -1,
+ 14, -1, -1, 1122, 1123, -1, 1125, 28, -1, 30,
+ 934, 259, -1, -1, 28, 36, 30, -1, -1, -1,
+ -1, -1, 36, -1, 45, 1030, -1, -1, -1, -1,
+ -1, 45, -1, 54, -1, 56, 57, 58, -1, -1,
+ 54, -1, 56, 57, -1, -1, -1, -1, -1, 297,
+ 298, 1170, 1171, 1172, 1173, 1174, -1, -1, -1, 1178,
+ -1, 985, -1, -1, 1069, -1, 348, 349, 350, -1,
+ -1, -1, 93, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 1201, 1202, 1203, 3, 4, 5, 6, 7,
+ 8, 9, -1, -1, 342, -1, 14, -1, 346, -1,
+ 348, 349, 350, -1, -1, -1, -1, 355, -1, -1,
+ 28, 359, 30, 31, 32, -1, -1, -1, 36, -1,
+ -1, -1, -1, 41, -1, -1, -1, 45, -1, -1,
+ 48, -1, -1, -1, -1, -1, 54, -1, 56, 57,
+ -1, -1, -1, -1, -1, 393, -1, -1, -1, -1,
+ -1, -1, 70, -1, 402, -1, 404, 405, -1, -1,
+ -1, -1, 80, -1, -1, 1170, 1171, 1172, 1173, 1174,
+ 88, 419, -1, 1178, 422, 93, 1295, 1296, -1, 1298,
+ 98, -1, 3, 4, 5, 6, 434, -1, 9, -1,
+ -1, -1, -1, -1, 442, -1, 1201, 1202, 1203, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 31, -1, -1, -1, 1138, 1334, 1335, 1336, -1, -1,
+ 41, -1, 470, -1, 472, -1, 474, 475, 476, -1,
+ -1, -1, 480, 54, 1353, 56, 57, 485, -1, 1,
+ 488, 3, 4, 5, 6, 7, 8, 9, -1, 70,
+ -1, -1, 14, 1177, -1, -1, -1, -1, -1, 80,
+ 508, -1, -1, 511, -1, 513, 28, 88, 30, 31,
+ 518, 519, 93, 521, 36, -1, -1, -1, -1, 41,
+ -1, -1, -1, 45, -1, -1, 48, -1, -1, -1,
+ 1295, 1296, 54, 1298, 56, 57, -1, -1, 60, -1,
+ 1224, -1, -1, -1, 1228, -1, -1, -1, 70, -1,
+ -1, -1, -1, 561, 562, 563, 564, -1, 80, 1438,
+ -1, -1, -1, -1, 1248, -1, 88, -1, 1252, -1,
+ -1, 93, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 3, 4, 5, 6, -1, -1, 9, -1,
+ -1, -1, -1, -1, -1, 637, 638, -1, 640, -1,
+ -1, -1, -1, 1287, -1, 647, -1, -1, -1, -1,
+ 31, -1, -1, 621, -1, 623, -1, -1, -1, -1,
+ 41, -1, -1, -1, -1, -1, 1505, 1506, 1507, 637,
+ 638, -1, 640, 54, -1, 56, 57, -1, -1, 647,
+ -1, -1, 1521, -1, -1, -1, -1, 1526, -1, 70,
+ -1, -1, 660, 3, 4, 5, 6, -1, 666, 80,
+ -1, -1, -1, 705, -1, 707, 708, 88, 710, -1,
+ -1, -1, 93, 1438, -1, -1, -1, -1, -1, -1,
+ -1, 31, 690, -1, -1, -1, -1, -1, -1, -1,
+ 698, 41, -1, -1, -1, 1379, 1380, 705, 706, 707,
+ 708, 709, 710, -1, 54, -1, 56, 57, -1, -1,
+ 752, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 70, -1, -1, -1, -1, 733, -1, -1, -1, -1,
+ 80, -1, -1, -1, -1, -1, -1, -1, 88, -1,
+ 1505, 1506, 1507, 93, 752, -1, -1, -1, 756, -1,
+ -1, -1, -1, -1, -1, 763, 764, -1, 766, -1,
+ -1, -1, -1, -1, 3, 4, 5, 6, 7, 8,
+ 9, -1, 780, 12, 782, 14, -1, 785, -1, -1,
+ -1, -1, -1, -1, -1, -1, 794, -1, -1, 28,
+ -1, 30, 31, -1, -1, -1, -1, 36, -1, -1,
+ -1, -1, 41, -1, -1, 847, 45, 815, 47, -1,
+ -1, -1, -1, -1, 822, 54, -1, 56, 57, -1,
+ 828, -1, -1, -1, -1, -1, -1, 835, 836, 837,
+ -1, 70, 3, 4, 5, 6, 7, 8, 9, 847,
+ -1, 80, -1, 14, -1, -1, -1, -1, -1, 88,
+ -1, 90, -1, -1, 93, 94, -1, 28, -1, 30,
+ 31, -1, -1, -1, -1, 36, -1, -1, -1, -1,
+ 41, -1, -1, -1, 45, -1, 47, -1, 920, -1,
+ 922, -1, -1, 54, -1, 56, 57, -1, -1, -1,
+ -1, 933, -1, -1, -1, 937, 938, 939, -1, 70,
+ 3, 4, 5, 6, 7, 8, 9, -1, -1, 80,
+ -1, 14, 920, -1, 922, -1, -1, 88, -1, 90,
+ -1, 929, 93, 94, -1, 933, -1, 935, 31, 937,
+ 938, 939, -1, 36, -1, -1, -1, 945, 41, 981,
+ 982, 983, 45, -1, 47, -1, -1, -1, -1, -1,
+ -1, 54, -1, 56, 57, 4, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 70, -1, 977,
+ -1, 979, -1, 981, 982, 983, -1, 80, -1, -1,
+ -1, 30, 31, -1, 33, 88, 35, -1, 1030, -1,
+ 93, -1, -1, 42, 73, 74, 75, 76, 77, 78,
+ 79, 80, 81, 82, 83, 84, 55, -1, 57, 3,
+ 4, 5, 6, 7, 8, 9, -1, -1, -1, -1,
+ 14, -1, 1030, -1, -1, -1, -1, -1, -1, -1,
+ -1, 80, -1, -1, 28, 1043, 30, 31, -1, -1,
+ -1, -1, 36, -1, -1, -1, -1, 41, -1, -1,
+ -1, 45, -1, -1, -1, -1, -1, -1, -1, -1,
+ 54, 1069, 56, 57, -1, -1, 1074, -1, 62, 1077,
+ -1, -1, -1, -1, -1, -1, 70, -1, -1, 1087,
+ -1, 1089, -1, -1, 133, 134, 80, 136, -1, -1,
+ -1, 140, 141, -1, 88, 144, -1, 146, -1, 93,
+ 149, 150, 151, -1, -1, -1, -1, 156, -1, 1117,
+ -1, -1, -1, -1, 1122, 1123, 165, 1125, -1, -1,
+ 169, -1, -1, -1, -1, -1, 175, 176, 1170, 1171,
+ 1172, 1173, 1174, -1, -1, -1, 1178, -1, -1, -1,
+ -1, -1, -1, -1, 193, 194, 195, -1, -1, -1,
+ -1, -1, -1, -1, 203, -1, -1, -1, -1, 1201,
+ 1202, 1203, 1170, 1171, 1172, 1173, 1174, -1, -1, -1,
+ 1178, -1, -1, 222, -1, -1, 1, 1185, 3, 4,
+ 5, 6, 7, 8, 9, -1, -1, -1, -1, 14,
+ -1, -1, -1, 1201, 1202, 1203, 245, -1, -1, -1,
+ -1, -1, -1, 28, -1, 30, 31, 32, -1, -1,
+ 259, 36, 37, -1, 1222, -1, 41, -1, -1, -1,
+ 45, 46, -1, 48, 3, 4, 5, 6, -1, 54,
+ 9, 56, 57, -1, -1, 60, -1, 62, -1, -1,
+ -1, -1, -1, -1, -1, 70, -1, -1, -1, -1,
+ -1, -1, 31, 1295, 1296, 80, 1298, -1, -1, -1,
+ -1, -1, 41, 88, -1, -1, -1, -1, 93, -1,
+ -1, -1, -1, -1, -1, 54, -1, 56, 57, -1,
+ 329, -1, -1, -1, 109, -1, -1, 1295, 1296, -1,
+ 1298, 70, -1, -1, -1, -1, -1, 346, -1, -1,
+ -1, 80, -1, -1, -1, 354, -1, -1, -1, 88,
+ 359, -1, -1, -1, 93, 1323, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 1334, 1335, 1336, 70,
+ 71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
+ 81, 82, 83, 84, 393, 1353, -1, -1, -1, -1,
+ -1, 1359, -1, -1, -1, 404, -1, -1, -1, 1,
-1, 3, 4, 5, 6, 7, 8, 9, -1, -1,
- -1, -1, 14, 293, 294, -1, -1, 1472, 1200, 1201,
- -1, 1203, 1204, -1, 1206, -1, 344, 345, 346, 31,
- -1, 1347, 1348, -1, 36, -1, -1, -1, -1, 41,
- -1, 1257, 1258, 45, 1260, 47, -1, -1, 1364, -1,
- -1, -1, 54, -1, 56, 57, -1, -1, 338, -1,
- -1, -1, 342, -1, 344, 345, 346, -1, 70, -1,
- -1, 351, -1, -1, -1, 355, -1, -1, 80, -1,
- 1296, 1297, 1298, -1, -1, -1, 88, -1, 90, -1,
- -1, 93, 94, -1, -1, -1, -1, -1, -1, 1315,
- -1, -1, -1, -1, 1420, 1421, -1, -1, -1, 389,
- -1, -1, -1, -1, -1, 1297, 1298, -1, 398, -1,
- 400, 401, -1, 1439, 1440, 76, 77, 78, 79, 80,
- 81, 82, 83, 84, 414, -1, -1, 417, -1, -1,
- -1, -1, 422, -1, -1, -1, 1328, 1329, -1, -1,
- 430, 3, 4, 5, 6, -1, 458, 9, 460, -1,
- 462, 463, 464, -1, -1, -1, -1, -1, -1, -1,
- -1, 473, 3, 4, 5, 6, -1, -1, 458, -1,
- 460, -1, 462, 463, 464, -1, -1, -1, 468, 41,
- 4, 5, 1408, 473, 8, 9, 476, -1, -1, -1,
- 14, -1, 54, -1, 56, 57, -1, -1, -1, -1,
- 41, 491, 492, -1, 28, -1, 30, -1, 70, -1,
- -1, -1, 36, 54, -1, 56, 57, -1, 80, -1,
- -1, 45, -1, 47, -1, -1, 88, -1, -1, -1,
- 54, 93, 56, 57, -1, 1427, 1428, 1429, -1, -1,
- 530, 531, 532, 533, -1, -1, 70, 88, -1, -1,
- -1, -1, 1478, 1479, 1480, -1, 80, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, 90, -1, -1, 93,
- 94, 1497, -1, -1, -1, -1, 1502, -1, 606, 607,
- 3, 4, 5, 6, 7, 8, 9, -1, 4, 5,
- -1, 14, 8, 9, 1486, 1487, -1, -1, 14, -1,
- 590, -1, 592, -1, -1, 28, -1, 30, 31, 32,
- -1, -1, 28, 36, 30, -1, 606, 607, 41, 609,
- 36, -1, 45, -1, -1, 48, 616, -1, -1, 45,
- -1, 54, -1, 56, 57, -1, -1, -1, 54, 629,
- 56, 57, -1, -1, -1, 635, 674, 70, 676, 677,
- -1, 679, -1, -1, -1, -1, -1, 80, -1, -1,
- -1, -1, 1554, -1, -1, 88, -1, -1, -1, 659,
- 93, -1, -1, -1, -1, 98, -1, 667, -1, -1,
- -1, -1, -1, -1, 674, 675, 676, 677, 678, 679,
- -1, -1, 720, 68, 69, 70, 71, 72, 73, 74,
+ 419, -1, 14, 422, -1, -1, -1, -1, -1, 428,
+ 429, 430, -1, -1, -1, 434, 28, -1, 30, 31,
+ 32, -1, -1, 442, 36, 37, -1, -1, -1, 41,
+ -1, -1, -1, 45, 46, -1, 48, -1, -1, -1,
+ -1, -1, 54, -1, 56, 57, -1, -1, 60, -1,
+ 62, 470, -1, 472, -1, 474, 475, 476, 70, -1,
+ 1438, 480, -1, -1, -1, -1, 485, -1, 80, 488,
+ -1, -1, 3, 4, 5, 6, 88, -1, -1, -1,
+ -1, 93, -1, 4, 5, -1, -1, 8, 9, -1,
+ -1, -1, 511, 14, 513, -1, -1, 109, -1, 518,
+ 519, -1, 521, -1, -1, -1, -1, 28, -1, 30,
+ 41, -1, -1, -1, -1, 36, -1, -1, -1, -1,
+ -1, -1, -1, 54, 45, 56, 57, 1505, 1506, 1507,
+ -1, 62, -1, 54, 553, 56, 57, 556, -1, 70,
+ -1, -1, -1, 1521, -1, -1, -1, -1, 1526, 80,
+ -1, -1, 571, 572, 573, -1, -1, 88, -1, 4,
+ -1, -1, 93, -1, -1, -1, -1, 586, -1, -1,
+ -1, 3, 4, 5, 6, -1, 1, 9, 3, 4,
+ 5, 6, 7, 8, 9, 30, 31, -1, 33, 14,
+ 35, -1, -1, -1, -1, -1, -1, 42, -1, 31,
+ -1, -1, 27, 28, -1, 30, 31, 32, -1, 41,
+ 55, 36, 57, -1, -1, 634, 41, -1, -1, 44,
+ 45, 46, 54, 48, 56, 57, -1, -1, 647, 54,
+ -1, 56, 57, -1, -1, 60, -1, -1, 70, -1,
+ -1, -1, -1, -1, -1, 70, -1, 666, 80, -1,
+ -1, -1, -1, -1, -1, 80, 88, -1, -1, -1,
+ -1, 93, -1, 88, -1, -1, -1, -1, 93, -1,
+ -1, 690, -1, 98, -1, -1, -1, 33, 697, -1,
+ -1, -1, -1, -1, -1, -1, 705, 706, 707, 708,
+ -1, 136, -1, -1, -1, 140, 141, -1, -1, 55,
+ -1, 146, -1, -1, 149, 150, 151, -1, -1, -1,
+ -1, -1, -1, -1, 3, 4, 5, 6, -1, -1,
+ 165, -1, -1, -1, 169, 3, 4, 5, 6, -1,
+ 175, 176, -1, 752, -1, -1, -1, 756, -1, -1,
+ -1, -1, -1, -1, 763, 764, -1, 766, 193, 194,
+ 195, -1, 41, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 41, -1, 54, 785, 56, 57, -1,
+ -1, 60, -1, 62, -1, -1, 54, 222, 56, 57,
+ -1, 70, 60, -1, -1, -1, -1, 806, -1, -1,
+ -1, 80, 70, 149, 150, 151, 815, -1, -1, 88,
+ 245, -1, 80, -1, 93, -1, -1, -1, -1, -1,
+ 88, -1, -1, -1, 259, 93, -1, -1, -1, 175,
+ -1, 1, 841, 3, 4, 5, 6, 7, 8, 9,
+ 10, 11, 12, 13, 14, -1, -1, 193, 194, 195,
+ -1, -1, -1, -1, -1, -1, -1, -1, 28, 29,
+ 30, 31, 32, -1, 34, 35, 36, -1, 38, 39,
+ 40, 41, 42, 43, -1, 45, 222, -1, -1, 49,
+ 50, 51, 52, 53, 54, -1, 56, 57, -1, -1,
+ -1, 61, -1, -1, -1, -1, -1, 67, -1, -1,
+ 70, -1, -1, -1, -1, -1, -1, -1, 78, 79,
+ 80, -1, -1, -1, -1, -1, 86, 87, 88, -1,
+ 355, -1, -1, 93, 359, -1, -1, -1, 937, 938,
+ 939, -1, -1, -1, 943, 944, -1, -1, 108, -1,
+ 110, -1, -1, 3, 4, 5, 6, 7, 8, 9,
+ -1, -1, 298, -1, 14, 72, 73, 74, 75, 76,
+ 77, 78, 79, 80, 81, 82, 83, 84, 28, 404,
+ 30, 31, 981, 982, 983, -1, 36, -1, -1, 988,
+ -1, 41, -1, -1, 419, 45, -1, 422, -1, -1,
+ -1, -1, -1, -1, 54, -1, 56, 57, -1, 434,
+ 60, -1, 348, 349, 350, -1, -1, 442, -1, -1,
+ 70, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 80, 1030, -1, -1, -1, -1, -1, -1, 88, -1,
+ -1, -1, -1, 93, -1, 470, -1, 472, -1, 474,
+ 475, 476, -1, -1, -1, 480, -1, -1, -1, -1,
+ 485, -1, -1, 488, -1, -1, -1, -1, 404, -1,
+ 1069, -1, -1, -1, -1, 1074, -1, -1, 1077, 3,
+ 4, 5, 6, 7, 8, 9, 511, -1, 513, -1,
+ 14, -1, -1, 518, 519, -1, 521, -1, -1, -1,
+ -1, -1, -1, -1, 28, -1, 30, 31, -1, -1,
+ -1, -1, 36, -1, -1, -1, -1, 41, -1, -1,
+ -1, 45, -1, -1, -1, -1, -1, -1, -1, -1,
+ 54, -1, 56, 57, 470, -1, 472, -1, 474, 475,
+ 476, -1, -1, -1, 480, -1, 70, -1, -1, 485,
+ 1149, -1, 488, -1, -1, -1, 80, -1, -1, -1,
+ -1, -1, -1, -1, 88, -1, -1, -1, -1, 93,
+ -1, 1170, 1171, 1172, 1173, 1174, -1, 1176, -1, 1178,
+ -1, -1, 518, -1, 1, -1, 3, 4, 5, 6,
+ -1, 8, 9, 10, 11, -1, 13, 14, -1, -1,
+ -1, -1, 1201, 1202, 1203, -1, -1, -1, -1, -1,
+ 635, 28, 29, 30, -1, 32, -1, 34, 35, 36,
+ -1, 38, 39, 40, 41, 42, 43, -1, 45, -1,
+ -1, -1, 49, 50, 51, 52, 53, 54, -1, 56,
+ 57, 666, -1, -1, 61, 62, -1, -1, -1, -1,
+ 67, -1, -1, 70, -1, -1, -1, -1, -1, -1,
+ -1, 78, 79, 80, -1, -1, 55, -1, -1, 86,
+ 87, 88, -1, -1, -1, -1, 93, -1, -1, -1,
+ 705, 706, 707, 708, -1, -1, -1, 623, -1, -1,
+ -1, 80, -1, 110, 83, -1, 1295, 1296, -1, 1298,
+ -1, 637, 638, -1, 640, -1, -1, -1, -1, -1,
+ -1, 647, -1, -1, -1, 104, -1, 106, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 752, -1, -1,
+ 666, 756, -1, -1, -1, 1334, 1335, 1336, 763, 764,
+ -1, 766, 67, 68, 69, 70, 71, 72, 73, 74,
75, 76, 77, 78, 79, 80, 81, 82, 83, 84,
- 1, 701, 3, 4, 5, 6, 7, 8, 9, 731,
- 732, -1, 734, 14, -1, -1, -1, -1, -1, -1,
- 720, -1, -1, -1, 724, -1, -1, 28, -1, 30,
- 31, 731, 732, -1, 734, 36, -1, -1, -1, -1,
- 41, -1, -1, -1, 45, -1, -1, 48, -1, -1,
- 772, -1, -1, 54, -1, 56, 57, -1, -1, 60,
- -1, -1, 762, -1, -1, 765, -1, 767, -1, 70,
- 808, -1, 772, 773, 774, -1, -1, -1, -1, 80,
- 780, 4, 5, 783, -1, 8, 9, 88, -1, 789,
- -1, 14, 93, -1, -1, -1, 796, 797, 798, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, 808, -1,
- -1, -1, -1, 36, -1, 4, -1, -1, -1, -1,
- -1, -1, 45, -1, 47, 3, 4, 5, 6, -1,
- -1, 54, -1, 56, 57, -1, -1, -1, -1, -1,
- -1, 30, 31, 881, 33, 883, 35, 70, -1, -1,
- -1, -1, -1, 42, -1, -1, 894, 80, -1, -1,
- 898, 899, -1, 41, -1, -1, 55, 90, 57, -1,
- 93, 94, -1, -1, -1, -1, 54, -1, 56, 57,
- -1, 881, -1, 883, 62, -1, -1, -1, -1, -1,
- 890, 80, 70, -1, 894, -1, 896, -1, 898, 899,
- 900, -1, 80, 941, 942, 905, -1, -1, -1, -1,
- 88, -1, -1, -1, -1, 93, -1, -1, -1, 941,
- 942, 943, 70, 71, 72, 73, 74, 75, 76, 77,
- 78, 79, 80, 81, 82, 83, 84, 937, -1, 939,
- -1, 941, 942, 943, 133, 134, -1, 136, -1, -1,
- -1, 140, -1, 142, -1, 144, -1, -1, 147, 148,
- 149, -1, -1, 985, -1, 4, 5, -1, -1, 8,
- 9, -1, 161, -1, -1, 14, 165, -1, -1, -1,
- -1, -1, 171, 172, -1, 985, -1, -1, -1, -1,
- -1, -1, 1014, -1, -1, -1, -1, 36, 998, -1,
- 189, 190, 191, -1, -1, -1, 45, -1, 47, 1009,
- 199, 1011, -1, -1, 1014, 54, -1, 56, 57, -1,
- -1, -1, -1, 1023, 3, 4, 5, 6, -1, 218,
- 9, 70, 4, 5, -1, -1, 8, 9, -1, -1,
- -1, 80, 14, -1, -1, -1, -1, -1, 1048, -1,
- -1, 90, -1, -1, 93, 94, 28, 1057, 30, 1059,
- -1, -1, 41, -1, 36, -1, 255, -1, -1, -1,
- -1, -1, -1, 45, -1, 54, -1, 56, 57, -1,
- -1, -1, 54, -1, 56, 57, -1, 1087, -1, -1,
- -1, 70, 1092, 1093, -1, 1095, -1, -1, -1, -1,
- -1, 80, 1140, 1141, 1142, 1143, -1, -1, -1, 88,
- 1148, -1, -1, -1, 93, -1, -1, -1, 1140, 1141,
- 1142, 1143, 1144, -1, -1, -1, 1148, -1, -1, -1,
- -1, -1, -1, 1171, 1172, -1, 325, -1, -1, -1,
- 1140, 1141, 1142, 1143, 1144, -1, -1, -1, 1148, 1171,
- 1172, 1173, -1, 342, -1, 1155, -1, -1, -1, -1,
- -1, 350, -1, -1, -1, -1, 355, -1, -1, -1,
- -1, 1171, 1172, 1173, -1, -1, 3, 4, 5, 6,
- 1202, -1, 9, -1, -1, -1, -1, 1187, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- 389, -1, 1202, -1, -1, -1, -1, 1207, -1, -1,
- -1, 400, -1, -1, 41, -1, -1, -1, -1, 1257,
- 1258, -1, 1260, -1, -1, 414, -1, 54, 417, 56,
- 57, -1, -1, 422, -1, 1257, 1258, -1, 1260, -1,
- -1, 430, -1, 70, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 80, -1, -1, -1, 1257, 1258, -1,
- 1260, 88, -1, -1, -1, -1, 93, -1, -1, 458,
- -1, 460, -1, 462, 463, 464, -1, -1, -1, 468,
- -1, -1, -1, -1, 473, 1285, -1, 476, 3, 4,
- 5, 6, -1, -1, -1, -1, 1296, 1297, 1298, -1,
- -1, -1, -1, 492, -1, -1, -1, 3, 4, 5,
- 6, 7, 8, 9, -1, 1315, -1, -1, 14, -1,
- -1, -1, -1, -1, -1, -1, 41, -1, -1, -1,
- -1, -1, 28, 522, 30, 31, 525, -1, -1, 54,
- 36, 56, 57, -1, -1, 41, -1, 62, -1, 45,
- -1, 540, 541, 542, -1, 70, -1, -1, 54, -1,
- 56, 57, -1, -1, 60, 80, 555, -1, -1, -1,
- -1, -1, 4, 88, 70, -1, -1, -1, 93, -1,
- -1, -1, -1, -1, 80, -1, 1408, -1, -1, -1,
- -1, -1, 88, -1, -1, -1, -1, 93, 30, 31,
- -1, 33, -1, 35, -1, -1, -1, -1, 1408, -1,
- 42, -1, -1, -1, 603, 3, 4, 5, 6, -1,
- -1, -1, -1, 55, -1, 57, -1, 616, 67, 68,
- 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,
- 79, 80, 81, 82, 83, 84, 635, -1, -1, -1,
- -1, -1, -1, 41, -1, -1, 1478, 1479, 1480, -1,
+ 785, -1, -1, -1, -1, -1, -1, -1, -1, 705,
+ -1, 707, 708, -1, 710, -1, -1, -1, -1, -1,
+ -1, 3, 4, 5, 6, -1, 175, 9, -1, -1,
+ 815, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 193, 194, 195, -1, -1, 31,
+ -1, -1, -1, -1, 203, -1, 752, -1, -1, 41,
+ -1, -1, -1, -1, -1, -1, -1, 763, 764, -1,
+ 766, -1, 54, 222, 56, 57, -1, -1, -1, 1438,
+ -1, -1, -1, -1, -1, -1, -1, -1, 70, 785,
+ -1, 3, 4, 5, 6, 7, 8, 9, 80, 248,
+ 12, -1, 14, -1, -1, -1, 88, -1, -1, -1,
+ -1, 93, -1, 262, -1, -1, 28, -1, 30, 31,
+ -1, -1, -1, -1, 36, -1, -1, -1, -1, 41,
+ -1, -1, -1, 45, -1, -1, -1, -1, -1, 835,
+ 836, 837, 54, -1, 56, 57, 1505, 1506, 1507, -1,
+ -1, 847, -1, -1, -1, -1, -1, -1, 70, -1,
+ 945, -1, -1, -1, -1, -1, -1, 1526, 80, -1,
+ -1, -1, -1, -1, -1, -1, 88, -1, -1, -1,
+ -1, 93, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 981, 982, 983, -1,
+ -1, -1, -1, -1, -1, 354, 355, -1, -1, -1,
+ -1, 3, 4, 5, 6, 7, 8, 9, -1, -1,
+ -1, -1, 14, -1, 920, -1, 922, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 28, 933, 30, 31,
+ -1, 937, 938, 939, 36, 1030, -1, -1, -1, 41,
+ -1, -1, -1, 45, -1, 404, -1, -1, -1, -1,
+ -1, -1, 54, -1, 56, 57, -1, -1, 60, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, 70, -1,
+ -1, -1, -1, -1, 1069, 981, 982, 983, 80, 1074,
+ -1, -1, 1077, -1, -1, -1, 88, -1, -1, -1,
+ -1, 93, -1, -1, -1, 3, 4, 5, 6, 7,
+ 8, 9, -1, -1, -1, -1, 14, -1, -1, -1,
+ -1, 470, -1, 472, -1, 474, 475, 476, -1, -1,
+ 28, 480, 30, 31, 1030, -1, 485, -1, 36, 488,
+ -1, -1, -1, 41, -1, -1, -1, 45, -1, -1,
-1, -1, -1, -1, -1, -1, 54, -1, 56, 57,
- 659, -1, -1, -1, 62, -1, -1, 666, 1478, 1479,
- 1480, -1, 70, -1, -1, 674, 675, 676, 677, -1,
- -1, -1, 80, -1, -1, -1, -1, 1497, 55, -1,
- 88, -1, 1502, -1, 136, 93, -1, -1, 140, -1,
- -1, -1, 144, -1, -1, 147, 148, 149, -1, -1,
- 4, 5, -1, 80, 8, 9, 83, -1, -1, 161,
- 14, 720, -1, 165, -1, 724, -1, -1, -1, 171,
- 172, -1, 731, 732, 28, 734, 30, 104, -1, 106,
- -1, -1, 36, -1, -1, -1, -1, 189, 190, 191,
- -1, 45, -1, -1, -1, -1, -1, -1, -1, -1,
- 54, -1, 56, 57, 58, -1, 765, -1, 767, 33,
- -1, -1, -1, 772, 773, 774, 218, 3, 4, 5,
- 6, 780, -1, 3, 4, 5, 6, 7, 8, 9,
- -1, 55, 12, -1, 14, -1, -1, -1, -1, 93,
- -1, -1, -1, 802, 171, -1, -1, -1, 28, -1,
- 30, 31, -1, 255, -1, 41, 36, -1, -1, -1,
- -1, 41, 189, 190, 191, 45, -1, 47, 54, -1,
- 56, 57, 199, -1, 54, -1, 56, 57, -1, -1,
- -1, -1, -1, -1, 70, -1, -1, -1, -1, -1,
- 70, 218, -1, -1, 80, -1, -1, -1, -1, -1,
- 80, -1, 88, -1, -1, -1, -1, 93, 88, -1,
- 90, -1, -1, 93, 94, -1, -1, 244, 3, 4,
- 5, 6, -1, 147, 148, 149, -1, -1, -1, -1,
- -1, 258, -1, -1, -1, -1, -1, -1, -1, 898,
- 899, 900, -1, -1, -1, 904, -1, 171, -1, 351,
- -1, -1, -1, 355, -1, -1, 41, -1, -1, -1,
- -1, -1, -1, -1, -1, 189, 190, 191, -1, 54,
- -1, 56, 57, -1, -1, 60, -1, -1, -1, -1,
- -1, -1, 941, 942, 943, 70, -1, -1, -1, 948,
- -1, -1, -1, -1, 218, 80, -1, -1, 400, -1,
- -1, -1, -1, 88, -1, -1, -1, -1, 93, -1,
- -1, -1, 414, -1, -1, 417, -1, -1, -1, -1,
- 422, -1, -1, 350, 351, -1, 985, -1, 430, 72,
+ -1, 14, -1, -1, -1, -1, -1, -1, -1, 518,
+ 23, 24, 70, 1069, -1, -1, -1, 30, 31, -1,
+ 33, 12, 80, -1, -1, 1170, 1171, 1172, 1173, 1174,
+ 88, -1, -1, 1178, -1, 93, 69, 70, 71, 72,
73, 74, 75, 76, 77, 78, 79, 80, 81, 82,
- 83, 84, 3, 4, 5, 6, -1, -1, -1, 107,
- 108, -1, -1, -1, -1, 1014, 458, -1, 460, -1,
- 462, 463, 464, -1, -1, -1, 468, -1, -1, -1,
- 294, 473, -1, 400, 476, -1, 1035, -1, -1, -1,
- 41, -1, -1, -1, -1, -1, -1, -1, -1, 1048,
- 492, -1, -1, 54, -1, 56, 57, -1, -1, -1,
- -1, 3, 4, 5, 6, 7, 8, 9, -1, 70,
- -1, -1, 14, 3, 4, 5, 6, -1, -1, 80,
- 344, 345, 346, -1, -1, -1, 28, 88, 30, 31,
- -1, 458, 93, 460, 36, 462, 463, 464, -1, 41,
- -1, 468, -1, 45, -1, 47, 473, -1, -1, 476,
- -1, 41, 54, -1, 56, 57, -1, -1, -1, -1,
- 1119, -1, -1, -1, 54, -1, 56, 57, 70, 4,
- 5, -1, 7, 8, 9, -1, 400, 12, 80, 14,
- 70, 1140, 1141, 1142, 1143, 1144, 88, 1146, 90, 1148,
- 80, 93, 94, 28, -1, 30, 31, -1, 88, -1,
- -1, 36, 604, 93, -1, -1, -1, -1, -1, -1,
- 45, -1, 1171, 1172, 1173, -1, -1, -1, -1, 54,
- -1, 56, 57, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 635, 458, -1, 460, -1, 462, 463,
- 464, -1, -1, 1202, 468, -1, -1, -1, 1207, 473,
- -1, -1, 476, -1, -1, -1, 1, -1, 3, 4,
- 5, 6, 7, 8, 9, -1, -1, 325, -1, 14,
- -1, 82, 674, 675, 676, 677, -1, -1, -1, -1,
- -1, -1, -1, 28, -1, 30, 31, 32, -1, -1,
- -1, 36, 619, 620, -1, -1, 41, -1, 1257, 1258,
- 45, 1260, -1, 48, -1, -1, -1, -1, 635, 54,
- -1, 56, 57, -1, -1, -1, -1, -1, 720, -1,
- -1, -1, 724, -1, -1, 70, -1, -1, -1, 731,
- 732, -1, 734, -1, -1, 80, -1, 1296, 1297, 1298,
- 398, -1, -1, 88, 155, -1, -1, 674, 93, 676,
- 677, -1, -1, 98, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 765, -1, 767, -1, -1, 592, -1,
- 772, 773, 774, -1, -1, -1, 187, -1, 780, -1,
- -1, -1, 606, 607, -1, 609, -1, -1, -1, 200,
- 4, 5, 616, 720, 8, 9, -1, -1, 456, -1,
- 14, -1, -1, -1, 731, 732, -1, 734, -1, -1,
- -1, 635, -1, -1, 28, -1, 30, -1, -1, -1,
- -1, -1, 36, -1, -1, -1, -1, -1, -1, -1,
- -1, 45, 759, -1, -1, -1, -1, -1, -1, -1,
- 54, -1, 56, 57, -1, 772, -1, -1, -1, 1408,
- 674, -1, 676, 677, -1, 679, -1, -1, -1, -1,
- -1, -1, -1, -1, 522, -1, -1, 525, -1, -1,
- -1, 529, 530, 531, 532, 533, -1, -1, -1, 93,
- -1, -1, -1, -1, 542, 4, 5, -1, 7, 8,
- 9, -1, -1, -1, -1, 14, 720, 555, -1, -1,
- -1, -1, -1, 905, -1, -1, -1, 731, 732, 28,
- 734, 30, 31, -1, -1, -1, -1, 36, -1, 1478,
- 1479, 1480, -1, -1, -1, -1, 45, -1, -1, 48,
- -1, -1, -1, -1, -1, 54, -1, 56, 57, 941,
- 942, 943, -1, 1502, -1, -1, -1, -1, 772, -1,
- -1, 609, -1, -1, -1, -1, -1, -1, 616, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, 796, 797, 798, -1, -1, 904, 905, 906,
- -1, -1, -1, 985, 808, -1, -1, -1, -1, -1,
- -1, -1, 4, 69, 70, 71, 72, 73, 74, 75,
- 76, 77, 78, 79, 80, 81, 82, 83, 84, -1,
- -1, -1, 1014, -1, 941, 942, 943, -1, 30, 31,
- -1, 948, -1, 35, -1, -1, -1, 344, 345, 346,
- 42, 71, 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 84, 57, 1048, -1, -1, -1,
- -1, -1, -1, -1, -1, 466, -1, 881, 985, 883,
- 471, -1, -1, -1, -1, -1, 724, -1, -1, -1,
- 894, -1, -1, -1, 898, 899, 900, -1, -1, -1,
- -1, -1, -1, -1, -1, 496, -1, 1014, -1, -1,
- -1, 502, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 514, 515, -1, 517, -1, 1035, -1,
- -1, -1, -1, -1, -1, -1, -1, 941, 942, 943,
- -1, -1, -1, -1, 136, 783, -1, -1, 140, -1,
- -1, 789, 144, -1, -1, -1, -1, -1, 1140, 1141,
- 1142, 1143, 1144, -1, -1, -1, 1148, -1, -1, 161,
- -1, -1, -1, 165, -1, -1, -1, -1, -1, -1,
- 172, 985, -1, -1, -1, -1, -1, -1, -1, 1171,
- 1172, 1173, -1, -1, -1, -1, -1, 189, 190, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- 1014, -1, 1119, -1, -1, -1, -1, -1, -1, 857,
- 1202, 612, 613, -1, -1, 1207, 617, -1, -1, -1,
- -1, -1, -1, 1140, 1141, 1142, 1143, 1144, -1, 1146,
- -1, 1148, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, 890, -1, -1, -1, -1, -1, 896, -1,
- -1, -1, 900, 255, 1171, 1172, 1173, -1, -1, -1,
- -1, -1, -1, -1, -1, 1257, 1258, -1, 1260, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, 1092, 1093,
- -1, 1095, -1, -1, -1, 1202, -1, -1, -1, 937,
- -1, 939, -1, -1, -1, 943, -1, -1, -1, 606,
- 607, -1, 609, -1, 1296, 1297, 1298, -1, -1, 616,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, 1140, 1141, 1142, 1143,
- 1144, -1, -1, -1, 1148, -1, -1, 985, -1, -1,
- 1257, 1258, -1, 1260, -1, -1, -1, -1, -1, -1,
- 998, -1, -1, 355, -1, -1, 1004, 1171, 1172, 1173,
- -1, -1, -1, 1011, -1, -1, -1, 674, -1, 676,
- 677, -1, 679, -1, -1, 1023, -1, -1, -1, 1296,
- -1, 1298, -1, 14, -1, -1, -1, -1, 1202, 790,
- -1, 792, 23, 24, -1, -1, -1, -1, -1, 30,
- 31, -1, 33, -1, -1, -1, -1, -1, -1, 1057,
- -1, 1059, 414, 720, -1, 417, 1408, -1, -1, -1,
- 422, -1, -1, -1, -1, -1, -1, -1, 430, -1,
- -1, -1, -1, -1, 65, -1, -1, -1, -1, 1087,
- -1, -1, -1, 1257, 1258, -1, 1260, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, 458, -1, 460, -1,
- -1, -1, -1, 864, 865, -1, 867, -1, -1, -1,
- -1, 473, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, 1296, -1, 1298, -1, 1478, 1479, 1480, -1,
- 492, 1408, -1, 124, 895, 126, 1144, -1, -1, -1,
- -1, 808, 133, 134, -1, -1, -1, -1, -1, 140,
- 1502, 142, 143, 144, -1, 146, 147, 148, 149, 4,
- 5, -1, 7, 8, 9, 1173, -1, 12, -1, 14,
+ 83, 84, 65, -1, -1, -1, 1201, 1202, 1203, -1,
+ -1, -1, -1, -1, -1, -1, 1122, 1123, -1, 1125,
+ -1, 62, 63, 64, 65, 66, 67, 68, 69, 70,
+ 71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
+ 81, 82, 83, 84, 68, 69, 70, 71, 72, 73,
+ 74, 75, 76, 77, 78, 79, 80, 81, 82, 83,
+ 84, 124, -1, 126, 1170, 1171, 1172, 1173, 1174, -1,
+ 133, 134, 1178, -1, -1, -1, -1, 140, 141, -1,
+ -1, 144, 145, 146, -1, 148, 149, 150, 151, -1,
+ -1, 650, 651, -1, -1, 1201, 1202, 1203, -1, -1,
+ 1295, 1296, -1, 1298, -1, -1, -1, 666, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, 3, 4,
+ 5, 6, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, 1334,
+ 1335, 1336, -1, -1, -1, -1, 705, -1, 707, 708,
+ -1, -1, -1, -1, -1, -1, 41, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, 54,
+ -1, 56, 57, -1, -1, 238, 239, 62, -1, -1,
+ -1, -1, -1, -1, -1, 70, -1, -1, -1, 1295,
+ 1296, -1, 1298, 752, -1, 80, 259, -1, -1, -1,
+ -1, -1, -1, 88, 763, 764, -1, 766, 93, -1,
+ -1, 1, -1, 3, 4, 5, 6, 7, 8, 9,
+ 10, 11, 12, 13, 14, -1, 785, -1, 1334, -1,
+ 1336, -1, -1, -1, -1, 298, -1, -1, 28, 29,
+ 30, 31, 32, 1438, 34, 35, 36, 806, 38, 39,
+ 40, 41, 42, 43, -1, 45, -1, 47, -1, 49,
+ 50, 51, 52, 53, 54, -1, 56, 57, 58, -1,
+ -1, 61, -1, -1, -1, -1, -1, 67, -1, -1,
+ 70, -1, -1, 346, -1, 348, 349, -1, 78, 79,
+ 80, 3, 4, 5, 6, -1, 86, 87, 88, -1,
+ 90, -1, -1, 93, 94, -1, -1, -1, -1, -1,
+ 1505, 1506, 1507, 3, 4, 5, 6, -1, -1, 31,
+ 110, -1, -1, -1, -1, -1, -1, -1, -1, 41,
+ 393, 1526, 1438, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 54, -1, 56, 57, -1, -1, -1, 412,
+ -1, 41, -1, -1, -1, -1, 419, -1, 70, 422,
+ -1, -1, -1, -1, 54, -1, 56, 57, 80, -1,
+ 60, 434, -1, -1, -1, -1, 88, -1, -1, -1,
+ 70, 93, -1, -1, -1, 944, 945, 946, -1, -1,
+ 80, -1, -1, -1, -1, -1, -1, -1, 88, 1505,
+ 1506, 1507, -1, 93, -1, -1, -1, -1, 4, 5,
+ -1, 7, 8, 9, 3, 4, 5, 6, 14, -1,
+ 1526, -1, 981, 982, 983, -1, -1, -1, -1, 988,
+ -1, -1, 28, -1, 30, 31, -1, -1, -1, 502,
+ 36, -1, -1, -1, -1, 508, -1, -1, -1, 45,
+ -1, -1, 41, -1, -1, -1, -1, -1, 54, 1018,
+ 56, 57, -1, -1, -1, 54, -1, 56, 57, -1,
+ -1, 1030, 1, -1, 3, 4, 5, 6, 7, 8,
+ 9, 70, -1, 12, 547, 14, -1, -1, -1, -1,
+ -1, 80, -1, -1, -1, -1, 25, -1, 27, 88,
+ -1, -1, 31, -1, 93, -1, -1, 36, -1, -1,
+ 1069, -1, 41, -1, -1, -1, 45, -1, 47, -1,
+ -1, -1, -1, -1, -1, 54, -1, 56, 57, 58,
+ 59, 60, -1, 62, 63, 64, 65, 66, 67, 68,
+ 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,
+ 79, 80, 81, 82, 83, 84, -1, 86, 87, 88,
+ 623, 90, 91, 92, 93, 94, 95, -1, 97, -1,
+ -1, 634, 635, 102, 637, 638, -1, -1, 107, 108,
+ 109, -1, 111, -1, -1, -1, -1, -1, -1, -1,
+ 1149, -1, -1, -1, -1, -1, -1, 4, 5, -1,
+ 7, 8, 9, -1, -1, -1, -1, 14, -1, -1,
+ -1, 1170, 1171, 1172, 1173, 1174, -1, 1176, -1, 1178,
+ -1, 28, -1, 30, 31, -1, -1, 690, -1, 36,
+ -1, -1, -1, -1, 697, 698, -1, -1, 45, -1,
+ -1, 48, 1201, 1202, 1203, -1, 709, 54, -1, 56,
+ 57, -1, -1, -1, -1, 1, -1, 3, 4, 5,
+ 6, 7, 8, 9, 10, 11, -1, 13, 14, 15,
+ 733, 17, 18, 19, 20, 21, 22, 23, 24, 25,
+ 26, 27, 28, 29, 30, 31, 32, -1, 34, 35,
+ 36, -1, 38, 39, 40, 41, 42, 43, 44, 45,
+ 46, -1, -1, 49, 50, 51, 52, 53, 54, -1,
+ 56, 57, 58, -1, 60, 61, -1, 780, -1, -1,
+ -1, 67, -1, -1, 70, -1, -1, -1, -1, -1,
+ -1, -1, 78, 79, 80, -1, 1295, 1296, -1, 1298,
+ 86, 87, 88, -1, 807, -1, -1, 93, -1, 95,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 28, 945, 30, 31, -1, -1, -1,
- -1, 36, -1, -1, -1, -1, -1, -1, -1, -1,
- 45, 1478, 1479, 1480, -1, -1, -1, -1, -1, 54,
- -1, 56, 57, -1, 881, -1, 883, -1, -1, -1,
- -1, -1, -1, -1, -1, 1502, -1, 894, -1, -1,
- -1, 898, 899, 900, 1408, 3, 4, 5, 6, 7,
- 8, 9, 233, 234, 12, -1, 14, -1, -1, 1010,
+ -1, -1, -1, 109, 110, -1, -1, -1, -1, -1,
+ -1, -1, 835, 836, 837, 1334, -1, 1336, -1, -1,
+ -1, -1, -1, -1, 847, -1, 1, -1, 3, 4,
+ 5, 6, 7, 8, 9, 10, 11, -1, 13, 14,
+ 15, -1, 17, 18, 19, 20, 21, 22, 23, 24,
+ 25, 26, 27, 28, 29, 30, 31, 32, -1, 34,
+ 35, 36, -1, 38, 39, 40, 41, 42, 43, 44,
+ 45, 46, -1, -1, 49, 50, 51, 52, 53, 54,
+ -1, 56, 57, 58, -1, 60, 61, -1, -1, -1,
+ -1, -1, 67, -1, -1, 70, -1, 920, -1, 922,
+ -1, -1, -1, 78, 79, 80, 31, -1, -1, -1,
+ 933, 86, 87, 88, -1, -1, -1, -1, 93, 1438,
+ 95, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 110, -1, -1, 63, 64,
+ 65, 66, 67, 68, 69, 70, 71, 72, 73, 74,
+ 75, 76, 77, 78, 79, 80, 81, 82, 83, 84,
+ -1, -1, -1, -1, -1, 4, 5, -1, 7, 8,
+ 9, -1, -1, 12, -1, 14, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 1505, 1506, 1507, 28,
+ -1, 30, 31, -1, -1, 1018, -1, 36, -1, -1,
+ -1, -1, -1, -1, -1, -1, 45, 1526, -1, -1,
+ -1, -1, -1, -1, -1, 54, -1, 56, 57, -1,
+ -1, -1, -1, -1, -1, -1, 1, -1, 3, 4,
+ 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, 1072,
+ -1, 1074, -1, 28, 29, 30, 31, 32, -1, 34,
+ 35, 36, -1, 38, 39, 40, 41, 42, 43, -1,
+ 45, -1, 47, -1, 49, 50, 51, 52, 53, 54,
+ -1, 56, 57, 58, -1, -1, 61, -1, -1, -1,
+ -1, -1, 67, -1, -1, 70, -1, -1, -1, 1122,
+ 1123, -1, 1125, 78, 79, 80, -1, -1, -1, -1,
+ -1, 86, 87, 88, -1, 90, -1, -1, 93, 94,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- 28, 1022, 30, 31, 255, -1, -1, -1, 36, -1,
- -1, -1, -1, 41, 941, 942, 943, 45, -1, -1,
- -1, -1, -1, -1, -1, -1, 54, -1, 56, 57,
- 4, 5, -1, 7, 8, 9, -1, -1, -1, -1,
- 14, -1, 70, 294, 1478, 1479, 1480, 1315, -1, -1,
- -1, -1, 80, 675, 28, -1, 30, 31, 985, -1,
- 88, -1, 36, -1, -1, 93, -1, -1, 1502, -1,
- -1, 45, -1, -1, -1, -1, -1, -1, -1, -1,
- 54, -1, 56, 57, -1, -1, -1, 1108, -1, -1,
- -1, 342, -1, 344, 345, 3, 4, 5, 6, 7,
- 8, 9, 724, -1, -1, -1, 14, -1, -1, 731,
- 732, -1, 734, -1, -1, -1, -1, -1, -1, -1,
- 28, -1, 30, 31, -1, -1, 1147, -1, 36, -1,
- -1, -1, -1, 41, -1, -1, -1, 45, 389, -1,
- -1, -1, -1, 765, -1, 767, 54, -1, 56, 57,
- 772, 773, 774, -1, 62, -1, 407, -1, 780, -1,
- -1, -1, 70, 414, -1, -1, 417, -1, -1, -1,
- -1, 422, 80, -1, -1, -1, -1, -1, -1, -1,
- 88, -1, -1, -1, -1, 93, -1, -1, -1, 1210,
- -1, -1, -1, 1214, -1, -1, -1, -1, -1, 3,
- 4, 5, 6, 7, 8, 9, -1, -1, -1, -1,
- 14, -1, 1480, 1140, 1141, 1142, 1143, 1144, -1, -1,
- -1, 1148, -1, -1, 28, -1, 30, 31, 1249, 1497,
- -1, -1, 36, -1, -1, -1, -1, 41, 489, -1,
- 491, 45, -1, -1, 1171, 1172, 1173, -1, -1, -1,
- 54, -1, 56, 57, -1, -1, 1, -1, 3, 4,
- 5, 6, 7, 8, 9, 516, 70, -1, -1, 14,
- -1, -1, -1, -1, -1, -1, 80, -1, -1, -1,
- -1, -1, -1, 28, 88, 30, 31, 32, -1, 93,
- -1, 36, 37, -1, -1, -1, 41, -1, -1, -1,
- 45, 46, 1323, 48, -1, -1, 1327, -1, -1, 54,
- -1, 56, 57, -1, -1, 60, 12, 62, -1, 941,
- 942, -1, -1, -1, -1, 70, -1, -1, 1349, 1350,
- 1257, 1258, -1, 1260, -1, 80, -1, -1, -1, -1,
- -1, 592, -1, 88, -1, -1, -1, -1, 93, -1,
- -1, -1, 603, 604, -1, 606, 607, -1, -1, -1,
- -1, -1, -1, -1, 109, -1, 62, 63, 64, 65,
- 66, 67, 68, 69, 70, 71, 72, 73, 74, 75,
- 76, 77, 78, 79, 80, 81, 82, 83, 84, -1,
- -1, -1, 1014, -1, -1, -1, -1, -1, -1, 1,
- -1, 3, 4, 5, 6, 7, 8, 9, 659, -1,
- 12, -1, 14, -1, -1, 666, 667, -1, -1, -1,
- -1, -1, -1, 25, -1, 27, 1048, 678, -1, 31,
- -1, -1, -1, -1, 36, -1, -1, -1, -1, 41,
- -1, -1, -1, 45, -1, 47, -1, -1, -1, -1,
- 701, -1, 54, -1, 56, 57, 58, 59, 60, -1,
- 62, 63, 64, 65, 66, 67, 68, 69, 70, 71,
- 72, 73, 74, 75, 76, 77, 78, 79, 80, 81,
- 82, 83, 84, -1, 86, 87, 88, -1, 90, 91,
- 92, 93, 94, 95, -1, 97, -1, -1, -1, -1,
- 102, -1, -1, -1, -1, 107, 108, 109, 759, 111,
- -1, 762, -1, -1, -1, -1, -1, -1, 1140, 1141,
- -1, -1, -1, -1, -1, -1, 1148, -1, -1, -1,
+ -1, -1, -1, -1, -1, 110, 1, -1, 3, 4,
+ 5, 6, 7, 8, 9, 10, 11, -1, 13, 14,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, 796, 797, 798, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, 808, -1, -1,
- -1, -1, 1, -1, 3, 4, 5, 6, 7, 8,
- 9, 10, 11, 12, 13, 14, -1, -1, -1, -1,
- 1202, -1, -1, -1, -1, 1207, -1, -1, -1, 28,
- 29, 30, 31, 32, -1, 34, 35, 36, -1, 38,
- 39, 40, 41, 42, 43, -1, 45, -1, 47, -1,
- 49, 50, 51, 52, 53, 54, -1, 56, 57, 58,
- -1, -1, 61, -1, -1, -1, -1, -1, 67, -1,
- 881, 70, 883, -1, -1, 1257, 1258, -1, 1260, 78,
- 79, 80, -1, 894, -1, -1, -1, 86, 87, 88,
- -1, 90, -1, -1, 93, 94, -1, -1, -1, -1,
- 1, -1, 3, 4, 5, 6, 7, 8, 9, 10,
- 11, 110, 13, 14, 15, 1297, 17, 18, 19, 20,
- 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
- 31, 32, -1, 34, 35, 36, -1, 38, 39, 40,
- 41, 42, 43, 44, 45, 46, -1, -1, 49, 50,
- 51, 52, 53, 54, -1, 56, 57, 58, -1, 60,
+ -1, -1, 1185, 28, 29, 30, 31, 32, -1, 34,
+ 35, 36, -1, 38, 39, 40, 41, 42, 43, -1,
+ 45, -1, -1, -1, 49, 50, 51, 52, 53, 54,
+ -1, 56, 57, 58, -1, 60, 61, -1, -1, 1222,
+ -1, -1, 67, -1, -1, 70, -1, -1, -1, -1,
+ -1, -1, -1, 78, 79, 80, -1, -1, -1, -1,
+ -1, 86, 87, 88, -1, -1, -1, -1, 93, 1,
+ -1, 3, 4, 5, 6, -1, 8, 9, 10, 11,
+ -1, 13, 14, -1, -1, 110, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 28, 29, 30, -1,
+ 32, -1, 34, 35, 36, -1, 38, 39, 40, 41,
+ 42, 43, -1, 45, -1, -1, -1, 49, 50, 51,
+ 52, 53, 54, -1, 56, 57, 58, -1, -1, 61,
+ -1, -1, -1, -1, -1, 67, -1, -1, 70, -1,
+ -1, -1, -1, -1, -1, -1, 78, 79, 80, -1,
+ -1, -1, -1, -1, 86, 87, 88, -1, -1, -1,
+ -1, 93, 94, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 1359, 109, 110, 1,
+ -1, 3, 4, 5, 6, -1, 8, 9, 10, 11,
+ -1, 13, 14, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 28, 29, 30, 31,
+ 32, -1, 34, 35, 36, -1, 38, 39, 40, 41,
+ 42, 43, -1, 45, -1, -1, -1, 49, 50, 51,
+ 52, 53, 54, -1, 56, 57, 58, -1, -1, 61,
+ -1, -1, -1, -1, -1, 67, -1, -1, 70, -1,
+ -1, -1, -1, -1, -1, -1, 78, 79, 80, -1,
+ -1, -1, -1, -1, 86, 87, 88, -1, -1, -1,
+ 1, 93, 3, 4, 5, 6, -1, 8, 9, 10,
+ 11, -1, 13, 14, -1, -1, -1, -1, 110, -1,
+ -1, -1, -1, -1, -1, -1, -1, 28, 29, 30,
+ -1, 32, -1, 34, 35, 36, -1, 38, 39, 40,
+ 41, 42, 43, -1, 45, -1, -1, -1, 49, 50,
+ 51, 52, 53, 54, -1, 56, 57, 58, -1, -1,
61, -1, -1, -1, -1, -1, 67, -1, -1, 70,
-1, -1, -1, -1, -1, -1, -1, 78, 79, 80,
-1, -1, -1, -1, -1, 86, 87, 88, -1, -1,
- -1, -1, 93, -1, 95, -1, -1, -1, 1009, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, 109, 110,
- 1, -1, 3, 4, 5, 6, 7, 8, 9, 10,
- 11, -1, 13, 14, 15, 1036, 17, 18, 19, 20,
- 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
- 31, 32, -1, 34, 35, 36, -1, 38, 39, 40,
- 41, 42, 43, 44, 45, 46, -1, -1, 49, 50,
- 51, 52, 53, 54, -1, 56, 57, 58, -1, 60,
- 61, -1, -1, -1, -1, -1, 67, -1, -1, 70,
- -1, 1092, 1093, -1, 1095, -1, -1, 78, 79, 80,
- -1, -1, -1, -1, -1, 86, 87, 88, -1, -1,
- -1, -1, 93, -1, 95, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, 110,
- -1, -1, 1, -1, 3, 4, 5, 6, 7, 8,
- 9, 10, 11, 12, 13, 14, -1, -1, -1, -1,
- -1, -1, -1, -1, 1155, -1, -1, -1, -1, 28,
- 29, 30, 31, 32, -1, 34, 35, 36, -1, 38,
- 39, 40, 41, 42, 43, -1, 45, -1, 47, -1,
- 49, 50, 51, 52, 53, 54, 1187, 56, 57, 58,
- -1, -1, 61, -1, -1, -1, -1, -1, 67, -1,
- -1, 70, -1, -1, 1205, -1, 1207, -1, -1, 78,
- 79, 80, -1, -1, -1, -1, -1, 86, 87, 88,
- -1, 90, -1, -1, 93, 94, 1, -1, 3, 4,
- 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
- -1, 110, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 28, 29, 30, 31, 32, -1, 34,
+ -1, -1, 93, 94, 1, -1, 3, 4, 5, 6,
+ -1, 8, 9, 10, 11, -1, 13, 14, -1, 110,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 28, 29, 30, -1, 32, -1, 34, 35, 36,
+ -1, 38, 39, 40, 41, 42, 43, -1, 45, -1,
+ -1, -1, 49, 50, 51, 52, 53, 54, -1, 56,
+ 57, 58, -1, -1, 61, -1, -1, -1, -1, -1,
+ 67, -1, -1, 70, -1, -1, -1, -1, -1, -1,
+ -1, 78, 79, 80, -1, -1, -1, -1, -1, 86,
+ 87, 88, -1, -1, -1, 1, 93, 3, 4, 5,
+ 6, -1, 8, 9, 10, 11, -1, 13, 14, -1,
+ -1, -1, 109, 110, -1, -1, -1, -1, -1, -1,
+ -1, -1, 28, 29, 30, -1, 32, -1, 34, 35,
+ 36, -1, 38, 39, 40, 41, 42, 43, -1, 45,
+ -1, -1, -1, 49, 50, 51, 52, 53, 54, -1,
+ 56, 57, 58, -1, -1, 61, -1, -1, -1, -1,
+ -1, 67, -1, -1, 70, -1, -1, -1, -1, -1,
+ -1, -1, 78, 79, 80, -1, -1, -1, -1, -1,
+ 86, 87, 88, -1, -1, -1, 1, 93, 3, 4,
+ 5, 6, -1, 8, 9, 10, 11, -1, 13, 14,
+ -1, -1, -1, 109, 110, -1, -1, -1, -1, -1,
+ -1, -1, -1, 28, 29, 30, -1, 32, -1, 34,
35, 36, -1, 38, 39, 40, 41, 42, 43, -1,
45, -1, -1, -1, 49, 50, 51, 52, 53, 54,
- -1, 56, 57, -1, -1, -1, 61, -1, -1, -1,
+ -1, 56, 57, 58, -1, -1, 61, -1, -1, -1,
-1, -1, 67, -1, -1, 70, -1, -1, -1, -1,
-1, -1, -1, 78, 79, 80, -1, -1, -1, -1,
- -1, 86, 87, 88, -1, -1, -1, 1, 93, 3,
- 4, 5, 6, 7, 8, 9, 10, 11, -1, 13,
- 14, -1, -1, 108, -1, 110, -1, -1, -1, -1,
- -1, -1, -1, -1, 28, 29, 30, 31, 32, -1,
- 34, 35, 36, -1, 38, 39, 40, 41, 42, 43,
- -1, 45, -1, -1, -1, 49, 50, 51, 52, 53,
- 54, -1, 56, 57, 58, -1, 60, 61, -1, -1,
- -1, -1, -1, 67, -1, -1, 70, -1, -1, -1,
- -1, -1, -1, -1, 78, 79, 80, -1, -1, -1,
- -1, -1, 86, 87, 88, -1, -1, -1, 1, 93,
- 3, 4, 5, 6, -1, 8, 9, 10, 11, -1,
- 13, 14, -1, -1, -1, -1, 110, -1, -1, -1,
- -1, -1, -1, -1, -1, 28, 29, 30, -1, 32,
- -1, 34, 35, 36, -1, 38, 39, 40, 41, 42,
- 43, -1, 45, -1, -1, -1, 49, 50, 51, 52,
- 53, 54, -1, 56, 57, 58, -1, -1, 61, -1,
- -1, -1, -1, -1, 67, -1, -1, 70, -1, -1,
- -1, -1, -1, -1, -1, 78, 79, 80, -1, -1,
- -1, -1, -1, 86, 87, 88, -1, -1, -1, -1,
- 93, 94, 1, -1, 3, 4, 5, 6, -1, 8,
- 9, 10, 11, -1, 13, 14, 109, 110, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, 28,
+ -1, 86, 87, 88, -1, -1, -1, -1, 93, -1,
+ 1, -1, 3, 4, 5, 6, 101, 8, 9, 10,
+ 11, -1, 13, 14, -1, 110, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 28, 29, 30,
+ 31, 32, -1, 34, 35, 36, -1, 38, 39, 40,
+ 41, 42, 43, -1, 45, -1, -1, -1, 49, 50,
+ 51, 52, 53, 54, -1, 56, 57, 58, -1, -1,
+ 61, -1, -1, -1, -1, -1, 67, -1, -1, 70,
+ -1, -1, -1, -1, -1, -1, -1, 78, 79, 80,
+ -1, -1, -1, -1, -1, 86, 87, 88, -1, -1,
+ -1, 1, 93, 3, 4, 5, 6, -1, 8, 9,
+ 10, 11, -1, 13, 14, -1, -1, -1, -1, 110,
+ -1, -1, -1, -1, -1, -1, -1, -1, 28, 29,
+ 30, -1, 32, -1, 34, 35, 36, -1, 38, 39,
+ 40, 41, 42, 43, -1, 45, -1, -1, -1, 49,
+ 50, 51, 52, 53, 54, -1, 56, 57, 58, -1,
+ -1, 61, -1, -1, -1, -1, -1, 67, -1, -1,
+ 70, -1, -1, -1, -1, -1, -1, -1, 78, 79,
+ 80, -1, -1, -1, -1, -1, 86, 87, 88, -1,
+ -1, -1, 1, 93, 3, 4, 5, 6, -1, 8,
+ 9, 10, 11, -1, 13, 14, -1, -1, -1, -1,
+ 110, -1, -1, -1, -1, -1, -1, -1, -1, 28,
29, 30, -1, 32, -1, 34, 35, 36, -1, 38,
39, 40, 41, 42, 43, -1, 45, -1, -1, -1,
- 49, 50, 51, 52, 53, 54, -1, 56, 57, 58,
- -1, -1, 61, -1, -1, -1, -1, -1, 67, -1,
+ 49, 50, 51, 52, 53, 54, -1, 56, 57, -1,
+ -1, 60, 61, -1, -1, -1, -1, -1, 67, -1,
-1, 70, -1, -1, -1, -1, -1, -1, -1, 78,
79, 80, -1, -1, -1, -1, -1, 86, 87, 88,
- -1, -1, -1, -1, 93, 94, 1, -1, 3, 4,
- 5, 6, -1, 8, 9, 10, 11, -1, 13, 14,
+ -1, -1, -1, 1, 93, 3, 4, 5, 6, -1,
+ 8, 9, 10, 11, -1, 13, 14, -1, -1, -1,
-1, 110, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 28, 29, 30, -1, 32, -1, 34,
- 35, 36, -1, 38, 39, 40, 41, 42, 43, -1,
- 45, -1, -1, -1, 49, 50, 51, 52, 53, 54,
- -1, 56, 57, 58, -1, -1, 61, -1, -1, -1,
- -1, -1, 67, -1, -1, 70, -1, -1, -1, -1,
- -1, -1, -1, 78, 79, 80, -1, -1, -1, -1,
- -1, 86, 87, 88, -1, -1, -1, 1, 93, 3,
- 4, 5, 6, -1, 8, 9, 10, 11, -1, 13,
- 14, -1, -1, -1, 109, 110, -1, -1, -1, -1,
- -1, -1, -1, -1, 28, 29, 30, -1, 32, -1,
- 34, 35, 36, -1, 38, 39, 40, 41, 42, 43,
- -1, 45, -1, -1, -1, 49, 50, 51, 52, 53,
- 54, -1, 56, 57, 58, -1, -1, 61, -1, -1,
- -1, -1, -1, 67, -1, -1, 70, -1, -1, -1,
- -1, -1, -1, -1, 78, 79, 80, -1, -1, -1,
- -1, -1, 86, 87, 88, -1, -1, -1, 1, 93,
- 3, 4, 5, 6, -1, 8, 9, 10, 11, -1,
- 13, 14, -1, -1, -1, 109, 110, -1, -1, -1,
- -1, -1, -1, -1, -1, 28, 29, 30, -1, 32,
- -1, 34, 35, 36, -1, 38, 39, 40, 41, 42,
- 43, -1, 45, -1, -1, -1, 49, 50, 51, 52,
- 53, 54, -1, 56, 57, 58, -1, -1, 61, -1,
- -1, -1, -1, -1, 67, -1, -1, 70, -1, -1,
- -1, -1, -1, -1, -1, 78, 79, 80, -1, -1,
- -1, -1, -1, 86, 87, 88, -1, -1, -1, -1,
- 93, -1, 1, -1, 3, 4, 5, 6, 101, 8,
- 9, 10, 11, -1, 13, 14, -1, 110, -1, -1,
+ 28, 29, 30, -1, 32, -1, 34, 35, 36, -1,
+ 38, 39, 40, 41, 42, 43, -1, 45, -1, -1,
+ -1, 49, 50, 51, 52, 53, 54, -1, 56, 57,
+ -1, -1, -1, 61, -1, -1, -1, -1, -1, 67,
+ 1, -1, 70, 4, 5, -1, -1, 8, 9, -1,
+ 78, 79, 80, 14, -1, -1, -1, -1, 86, 87,
+ 88, -1, -1, -1, -1, 93, -1, 28, -1, 30,
+ -1, -1, -1, -1, -1, 36, -1, 38, 39, -1,
+ 108, -1, 110, -1, 45, -1, 47, -1, -1, -1,
+ -1, -1, -1, 54, -1, 56, 57, -1, 59, -1,
+ -1, -1, 63, 64, 65, 66, 67, 68, 69, 70,
+ 71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
+ 81, 82, 83, -1, -1, 86, 87, 88, -1, -1,
+ 91, -1, 1, 94, 3, 4, 5, 6, -1, 8,
+ 9, 10, 11, -1, 13, 14, -1, -1, -1, 110,
-1, -1, -1, -1, -1, -1, -1, -1, -1, 28,
29, 30, -1, 32, -1, 34, 35, 36, -1, 38,
39, 40, 41, 42, 43, -1, 45, -1, -1, -1,
- 49, 50, 51, 52, 53, 54, -1, 56, 57, 58,
+ 49, 50, 51, 52, 53, 54, -1, 56, 57, -1,
-1, -1, 61, -1, -1, -1, -1, -1, 67, -1,
-1, 70, -1, -1, -1, -1, -1, -1, -1, 78,
79, 80, -1, -1, -1, -1, -1, 86, 87, 88,
@@ -3238,7 +3372,7 @@ static const short yycheck[] = { 4,
28, 29, 30, -1, 32, -1, 34, 35, 36, -1,
38, 39, 40, 41, 42, 43, -1, 45, -1, -1,
-1, 49, 50, 51, 52, 53, 54, -1, 56, 57,
- 58, -1, -1, 61, -1, -1, -1, -1, -1, 67,
+ -1, -1, -1, 61, -1, -1, -1, -1, -1, 67,
-1, -1, 70, -1, -1, -1, -1, -1, -1, -1,
78, 79, 80, -1, -1, -1, -1, -1, 86, 87,
88, -1, -1, -1, 1, 93, 3, 4, 5, 6,
@@ -3247,113 +3381,54 @@ static const short yycheck[] = { 4,
-1, 28, 29, 30, -1, 32, -1, 34, 35, 36,
-1, 38, 39, 40, 41, 42, 43, -1, 45, -1,
-1, -1, 49, 50, 51, 52, 53, 54, -1, 56,
- 57, -1, -1, -1, 61, 62, -1, -1, -1, -1,
+ 57, -1, -1, -1, 61, -1, -1, -1, -1, -1,
67, -1, -1, 70, -1, -1, -1, -1, -1, -1,
-1, 78, 79, 80, -1, -1, -1, -1, -1, 86,
- 87, 88, -1, -1, -1, 1, 93, 3, 4, 5,
- 6, -1, 8, 9, 10, 11, -1, 13, 14, -1,
- -1, -1, -1, 110, -1, -1, -1, -1, -1, -1,
- -1, -1, 28, 29, 30, -1, 32, -1, 34, 35,
- 36, -1, 38, 39, 40, 41, 42, 43, -1, 45,
- -1, -1, -1, 49, 50, 51, 52, 53, 54, -1,
- 56, 57, 58, -1, -1, 61, -1, -1, -1, -1,
- -1, 67, -1, -1, 70, -1, -1, -1, -1, -1,
- -1, -1, 78, 79, 80, -1, -1, -1, -1, -1,
- 86, 87, 88, -1, -1, -1, 1, 93, 3, 4,
- 5, 6, -1, 8, 9, 10, 11, -1, 13, 14,
- -1, -1, -1, -1, 110, -1, -1, -1, -1, -1,
- -1, -1, -1, 28, 29, 30, -1, 32, -1, 34,
- 35, 36, -1, 38, 39, 40, 41, 42, 43, -1,
- 45, -1, -1, -1, 49, 50, 51, 52, 53, 54,
- -1, 56, 57, -1, -1, 60, 61, -1, -1, -1,
- -1, -1, 67, -1, -1, 70, -1, -1, -1, -1,
- -1, -1, -1, 78, 79, 80, -1, -1, -1, -1,
- -1, 86, 87, 88, -1, -1, -1, 1, 93, 3,
- 4, 5, 6, -1, 8, 9, 10, 11, -1, 13,
- 14, -1, -1, -1, -1, 110, -1, -1, -1, -1,
- -1, -1, -1, -1, 28, 29, 30, -1, 32, -1,
- 34, 35, 36, -1, 38, 39, 40, 41, 42, 43,
- -1, 45, -1, -1, -1, 49, 50, 51, 52, 53,
- 54, -1, 56, 57, -1, -1, -1, 61, -1, -1,
- -1, -1, -1, 67, 1, -1, 70, 4, 5, -1,
- -1, 8, 9, -1, 78, 79, 80, 14, -1, -1,
- -1, -1, 86, 87, 88, -1, -1, -1, -1, 93,
- -1, 28, -1, 30, -1, -1, -1, -1, -1, 36,
- -1, 38, 39, -1, 108, -1, 110, -1, 45, -1,
- 47, -1, -1, -1, -1, -1, -1, 54, -1, 56,
- 57, -1, 59, -1, -1, -1, 63, 64, 65, 66,
- 67, 68, 69, 70, 71, 72, 73, 74, 75, 76,
- 77, 78, 79, 80, 81, 82, 83, -1, -1, 86,
- 87, 88, -1, -1, 91, -1, 1, 94, 3, 4,
- 5, 6, -1, 8, 9, 10, 11, -1, 13, 14,
- -1, -1, -1, 110, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 28, 29, 30, -1, 32, -1, 34,
- 35, 36, -1, 38, 39, 40, 41, 42, 43, -1,
- 45, -1, -1, -1, 49, 50, 51, 52, 53, 54,
- -1, 56, 57, -1, -1, -1, 61, -1, -1, -1,
- -1, -1, 67, -1, -1, 70, -1, -1, -1, -1,
- -1, -1, -1, 78, 79, 80, -1, -1, -1, -1,
- -1, 86, 87, 88, -1, -1, -1, 1, 93, 3,
- 4, 5, 6, -1, 8, 9, 10, 11, -1, 13,
- 14, -1, -1, -1, -1, 110, -1, -1, -1, -1,
- -1, -1, -1, -1, 28, 29, 30, -1, 32, -1,
- 34, 35, 36, -1, 38, 39, 40, 41, 42, 43,
- -1, 45, -1, -1, -1, 49, 50, 51, 52, 53,
- 54, -1, 56, 57, -1, -1, -1, 61, -1, -1,
- -1, -1, -1, 67, -1, -1, 70, -1, -1, -1,
- -1, -1, -1, -1, 78, 79, 80, -1, -1, -1,
- -1, -1, 86, 87, 88, -1, -1, -1, 1, 93,
- 3, 4, 5, 6, -1, 8, 9, 10, 11, -1,
- 13, 14, -1, -1, -1, -1, 110, -1, -1, -1,
- -1, -1, -1, -1, -1, 28, 29, 30, -1, 32,
- -1, 34, 35, 36, -1, 38, 39, 40, 41, 42,
- 43, -1, 45, -1, -1, -1, 49, 50, 51, 52,
- 53, 54, -1, 56, 57, -1, -1, -1, 61, -1,
- -1, -1, -1, -1, 67, -1, -1, 70, -1, -1,
- -1, -1, -1, -1, -1, 78, 79, 80, -1, -1,
- -1, -1, -1, 86, 87, 88, 3, 4, 5, 6,
- 93, 8, 9, 10, 11, -1, 13, 14, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, 110, -1, -1,
- -1, 28, 29, 30, -1, 32, -1, 34, 35, 36,
- -1, 38, 39, 40, 41, 42, 43, -1, 45, -1,
- -1, -1, 49, 50, 51, 52, 53, 54, -1, 56,
- 57, -1, -1, -1, 61, -1, -1, -1, -1, -1,
- 67, -1, 1, 70, 3, 4, 5, 6, 7, 8,
- 9, 78, 79, 80, -1, 14, -1, -1, -1, 86,
- 87, 88, -1, -1, -1, -1, 93, -1, -1, 28,
- -1, 30, 31, 32, -1, -1, -1, 36, 37, -1,
- -1, -1, 41, 110, 111, -1, 45, 46, -1, 48,
- -1, -1, -1, -1, -1, 54, -1, 56, 57, -1,
- -1, 60, -1, 62, -1, -1, -1, -1, -1, -1,
- -1, 70, 1, -1, 3, 4, 5, 6, 7, 8,
- 9, 80, -1, -1, -1, 14, -1, -1, -1, 88,
- -1, -1, -1, -1, 93, -1, -1, -1, -1, 28,
- -1, 30, 31, 32, -1, -1, -1, 36, 37, -1,
- 109, -1, 41, -1, -1, -1, 45, 46, -1, 48,
- -1, -1, -1, -1, -1, 54, -1, 56, 57, -1,
- -1, 60, -1, 62, -1, -1, -1, -1, -1, -1,
- -1, 70, 1, -1, 3, 4, 5, 6, 7, 8,
- 9, 80, -1, -1, -1, 14, -1, -1, -1, 88,
- -1, -1, -1, -1, 93, -1, -1, -1, -1, 28,
- -1, 30, 31, 32, -1, -1, -1, 36, 37, -1,
- 109, -1, 41, -1, -1, -1, 45, 46, -1, 48,
- -1, -1, -1, -1, -1, 54, -1, 56, 57, -1,
- -1, 60, -1, 62, -1, -1, -1, -1, -1, -1,
- -1, 70, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, 80, -1, -1, -1, -1, -1, -1, -1, 88,
- -1, -1, -1, -1, 93, -1, -1, 3, 4, 5,
- 6, 7, 8, 9, 10, 11, -1, 13, 14, 15,
- 109, 17, 18, 19, 20, 21, 22, 23, 24, 25,
- 26, 27, 28, 29, 30, 31, 32, -1, 34, 35,
- 36, -1, 38, 39, 40, 41, 42, 43, 44, 45,
- 46, -1, -1, 49, 50, 51, 52, 53, 54, -1,
- 56, 57, 58, -1, 60, 61, -1, -1, -1, -1,
- -1, 67, -1, -1, 70, -1, -1, -1, -1, -1,
- -1, -1, 78, 79, 80, -1, -1, -1, -1, -1,
- 86, 87, 88, -1, -1, -1, -1, 93, -1, 95,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 109, 110, 3, 4, 5, 6, 7,
- 8, 9, 10, 11, -1, 13, 14, 15, -1, 17,
+ 87, 88, 3, 4, 5, 6, 93, 8, 9, 10,
+ 11, -1, 13, 14, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 110, -1, -1, -1, 28, 29, 30,
+ -1, 32, -1, 34, 35, 36, -1, 38, 39, 40,
+ 41, 42, 43, -1, 45, -1, -1, -1, 49, 50,
+ 51, 52, 53, 54, -1, 56, 57, -1, -1, -1,
+ 61, -1, -1, -1, -1, -1, 67, -1, 1, 70,
+ 3, 4, 5, 6, 7, 8, 9, 78, 79, 80,
+ -1, 14, -1, -1, -1, 86, 87, 88, -1, -1,
+ -1, -1, 93, -1, -1, 28, -1, 30, 31, 32,
+ -1, -1, -1, 36, 37, -1, -1, -1, 41, 110,
+ 111, -1, 45, 46, -1, 48, -1, -1, -1, -1,
+ -1, 54, -1, 56, 57, -1, -1, 60, -1, 62,
+ -1, -1, -1, -1, -1, -1, -1, 70, 1, -1,
+ 3, 4, 5, 6, 7, 8, 9, 80, -1, -1,
+ -1, 14, -1, -1, -1, 88, -1, -1, -1, -1,
+ 93, -1, -1, -1, -1, 28, -1, 30, 31, 32,
+ -1, -1, -1, 36, 37, -1, 109, -1, 41, -1,
+ -1, -1, 45, 46, -1, 48, -1, -1, -1, -1,
+ -1, 54, -1, 56, 57, -1, -1, 60, -1, 62,
+ -1, -1, -1, -1, -1, -1, -1, 70, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 80, -1, -1,
+ -1, -1, -1, -1, -1, 88, -1, -1, -1, -1,
+ 93, -1, -1, 3, 4, 5, 6, 7, 8, 9,
+ 10, 11, -1, 13, 14, 15, 109, 17, 18, 19,
+ 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
+ 30, 31, 32, -1, 34, 35, 36, -1, 38, 39,
+ 40, 41, 42, 43, 44, 45, 46, -1, -1, 49,
+ 50, 51, 52, 53, 54, -1, 56, 57, 58, -1,
+ 60, 61, -1, -1, -1, -1, -1, 67, -1, -1,
+ 70, -1, -1, -1, -1, -1, -1, -1, 78, 79,
+ 80, -1, -1, -1, -1, -1, 86, 87, 88, -1,
+ -1, -1, -1, 93, -1, 95, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, 109,
+ 110, 3, 4, 5, 6, 7, 8, 9, 10, 11,
+ -1, 13, 14, 15, -1, 17, 18, 19, 20, 21,
+ 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+ 32, -1, 34, 35, 36, -1, 38, 39, 40, 41,
+ 42, 43, 44, 45, 46, -1, -1, 49, 50, 51,
+ 52, 53, 54, -1, 56, 57, 58, -1, 60, 61,
+ -1, -1, -1, -1, -1, 67, -1, -1, 70, -1,
+ -1, -1, -1, -1, -1, -1, 78, 79, 80, -1,
+ -1, -1, -1, -1, 86, 87, 88, -1, -1, -1,
+ -1, 93, -1, 95, -1, 3, 4, 5, 6, 7,
+ 8, 9, 10, 11, -1, 13, 14, 15, 110, 17,
18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
28, 29, 30, 31, 32, -1, 34, 35, 36, -1,
38, 39, 40, 41, 42, 43, 44, 45, 46, -1,
@@ -3367,95 +3442,77 @@ static const short yycheck[] = { 4,
24, 25, 26, 27, 28, 29, 30, 31, 32, -1,
34, 35, 36, -1, 38, 39, 40, 41, 42, 43,
44, 45, 46, -1, -1, 49, 50, 51, 52, 53,
- 54, -1, 56, 57, 58, -1, 60, 61, -1, -1,
+ 54, -1, 56, 57, -1, -1, 60, 61, -1, -1,
-1, -1, -1, 67, -1, -1, 70, -1, -1, -1,
-1, -1, -1, -1, 78, 79, 80, -1, -1, -1,
-1, -1, 86, 87, 88, -1, -1, -1, -1, 93,
- -1, 95, -1, 3, 4, 5, 6, 7, 8, 9,
- 10, 11, -1, 13, 14, 15, 110, 17, 18, 19,
- 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
- 30, 31, 32, -1, 34, 35, 36, -1, 38, 39,
- 40, 41, 42, 43, 44, 45, 46, -1, -1, 49,
- 50, 51, 52, 53, 54, -1, 56, 57, -1, -1,
- 60, 61, -1, -1, -1, -1, -1, 67, -1, -1,
- 70, -1, -1, -1, -1, -1, -1, -1, 78, 79,
- 80, -1, -1, -1, -1, -1, 86, 87, 88, -1,
- -1, -1, -1, 93, -1, 95, 3, 4, 5, 6,
- 7, 8, 9, 10, 11, 12, 13, 14, -1, -1,
- 110, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 95, 3, 4, 5, 6, 7, 8, 9, 10,
+ 11, 12, 13, 14, -1, -1, 110, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 28, 29, 30,
+ 31, 32, -1, 34, 35, 36, -1, 38, 39, 40,
+ 41, 42, 43, -1, 45, -1, 47, -1, 49, 50,
+ 51, 52, 53, 54, -1, 56, 57, -1, -1, -1,
+ 61, -1, -1, -1, -1, -1, 67, -1, -1, 70,
+ -1, -1, -1, -1, -1, -1, -1, 78, 79, 80,
+ -1, -1, -1, -1, -1, 86, 87, 88, -1, 90,
+ -1, -1, 93, 94, 3, 4, 5, 6, 7, 8,
+ 9, 10, 11, 12, 13, 14, -1, -1, -1, 110,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, 28,
+ 29, 30, 31, 32, -1, 34, 35, 36, -1, 38,
+ 39, 40, 41, 42, 43, -1, 45, -1, 47, -1,
+ 49, 50, 51, 52, 53, 54, -1, 56, 57, -1,
+ -1, -1, 61, -1, -1, -1, -1, -1, 67, -1,
+ -1, 70, -1, -1, -1, -1, -1, -1, -1, 78,
+ 79, 80, -1, -1, -1, -1, -1, 86, 87, 88,
+ -1, 90, -1, -1, 93, 94, 3, 4, 5, 6,
+ -1, 8, 9, 10, 11, -1, 13, 14, -1, -1,
+ -1, 110, -1, -1, -1, -1, -1, -1, -1, -1,
-1, 28, 29, 30, 31, 32, -1, 34, 35, 36,
-1, 38, 39, 40, 41, 42, 43, -1, 45, -1,
47, -1, 49, 50, 51, 52, 53, 54, -1, 56,
- 57, -1, -1, -1, 61, -1, -1, -1, -1, -1,
+ 57, -1, -1, -1, -1, -1, -1, -1, -1, -1,
67, -1, -1, 70, -1, -1, -1, -1, -1, -1,
-1, 78, 79, 80, -1, -1, -1, -1, -1, 86,
87, 88, -1, 90, -1, -1, 93, 94, 3, 4,
- 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 5, 6, -1, 8, 9, 10, 11, -1, 13, 14,
-1, -1, -1, 110, -1, -1, -1, -1, -1, -1,
-1, -1, -1, 28, 29, 30, 31, 32, -1, 34,
35, 36, -1, 38, 39, 40, 41, 42, 43, -1,
45, -1, 47, -1, 49, 50, 51, 52, 53, 54,
- -1, 56, 57, -1, -1, -1, 61, -1, -1, -1,
+ -1, 56, 57, -1, -1, -1, -1, -1, -1, -1,
-1, -1, 67, -1, -1, 70, -1, -1, -1, -1,
-1, -1, -1, 78, 79, 80, -1, -1, -1, -1,
-1, 86, 87, 88, -1, 90, -1, -1, 93, 94,
3, 4, 5, 6, -1, 8, 9, 10, 11, -1,
13, 14, -1, -1, -1, 110, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, 28, 29, 30, -1, 32,
+ -1, -1, -1, -1, -1, 28, 29, 30, 31, 32,
-1, 34, 35, 36, -1, 38, 39, 40, 41, 42,
- 43, -1, 45, -1, 47, -1, 49, 50, 51, 52,
- 53, 54, -1, 56, 57, -1, -1, -1, -1, -1,
+ 43, -1, 45, -1, -1, -1, 49, 50, 51, 52,
+ 53, 54, -1, 56, 57, -1, -1, -1, 61, -1,
-1, -1, -1, -1, 67, -1, -1, 70, -1, -1,
-1, -1, -1, -1, -1, 78, 79, 80, -1, -1,
- -1, -1, -1, 86, 87, 88, -1, 90, -1, -1,
- 93, 94, 3, 4, 5, 6, -1, 8, 9, 10,
- 11, -1, 13, 14, -1, -1, -1, 110, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, 28, 29, 30,
- -1, 32, -1, 34, 35, 36, -1, 38, 39, 40,
- 41, 42, 43, -1, 45, -1, 47, -1, 49, 50,
- 51, 52, 53, 54, -1, 56, 57, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, 67, -1, -1, 70,
- -1, -1, -1, -1, -1, -1, -1, 78, 79, 80,
- -1, -1, -1, -1, -1, 86, 87, 88, -1, 90,
- -1, -1, 93, 94, 3, 4, 5, 6, -1, 8,
- 9, 10, 11, -1, 13, 14, -1, -1, -1, 110,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, 28,
- 29, 30, -1, 32, -1, 34, 35, 36, -1, 38,
- 39, 40, 41, 42, 43, -1, 45, -1, -1, -1,
- 49, 50, 51, 52, 53, 54, -1, 56, 57, -1,
- -1, 60, 61, -1, -1, -1, -1, -1, 67, -1,
- -1, 70, -1, -1, -1, -1, -1, -1, -1, 78,
- 79, 80, -1, -1, -1, -1, -1, 86, 87, 88,
- -1, -1, -1, -1, 93, 3, 4, 5, 6, 7,
- 8, 9, 10, 11, -1, 13, 14, -1, -1, -1,
- -1, 110, -1, -1, -1, -1, -1, -1, -1, -1,
- 28, 29, 30, 31, 32, -1, 34, 35, 36, -1,
- 38, 39, 40, 41, 42, 43, -1, 45, -1, -1,
- -1, 49, 50, 51, 52, 53, 54, -1, 56, 57,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, 67,
- -1, -1, 70, -1, -1, -1, -1, -1, -1, -1,
- 78, 79, 80, -1, -1, -1, -1, -1, 86, 87,
- 88, 3, 4, 5, 6, 93, 8, 9, 10, 11,
- -1, 13, 14, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, 110, -1, -1, -1, 28, 29, 30, -1,
- 32, -1, 34, 35, 36, -1, 38, 39, 40, 41,
- 42, 43, -1, 45, -1, -1, -1, 49, 50, 51,
- 52, 53, 54, -1, 56, 57, -1, -1, -1, 61,
- -1, -1, -1, -1, -1, 67, -1, -1, 70, -1,
- -1, -1, -1, -1, -1, -1, 78, 79, 80, -1,
- -1, -1, -1, -1, 86, 87, 88, 3, 4, 5,
- 6, 93, 8, 9, 10, 11, -1, 13, 14, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, 110, -1,
- -1, -1, 28, 29, 30, -1, 32, -1, 34, 35,
+ -1, -1, -1, 86, 87, 88, 3, 4, 5, 6,
+ 93, 8, 9, 10, 11, -1, 13, 14, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 110, -1, -1,
+ -1, 28, 29, 30, -1, 32, -1, 34, 35, 36,
+ -1, 38, 39, 40, 41, 42, 43, -1, 45, -1,
+ -1, -1, 49, 50, 51, 52, 53, 54, -1, 56,
+ 57, -1, -1, 60, 61, -1, -1, -1, -1, -1,
+ 67, -1, -1, 70, -1, -1, -1, -1, -1, -1,
+ -1, 78, 79, 80, -1, -1, -1, -1, -1, 86,
+ 87, 88, -1, -1, -1, -1, 93, 3, 4, 5,
+ 6, 7, 8, 9, 10, 11, -1, 13, 14, -1,
+ -1, -1, -1, 110, -1, -1, -1, -1, -1, -1,
+ -1, -1, 28, 29, 30, 31, 32, -1, 34, 35,
36, -1, 38, 39, 40, 41, 42, 43, -1, 45,
-1, -1, -1, 49, 50, 51, 52, 53, 54, -1,
- 56, 57, -1, -1, -1, 61, -1, -1, -1, -1,
+ 56, 57, -1, -1, -1, -1, -1, -1, -1, -1,
-1, 67, -1, -1, 70, -1, -1, -1, -1, -1,
-1, -1, 78, 79, 80, -1, -1, -1, -1, -1,
86, 87, 88, 3, 4, 5, 6, 93, 8, 9,
10, 11, -1, 13, 14, -1, -1, -1, -1, -1,
-1, -1, -1, -1, 110, -1, -1, -1, 28, 29,
- 30, -1, 32, -1, 34, 35, 36, -1, 38, 39,
+ 30, 31, 32, -1, 34, 35, 36, -1, 38, 39,
40, 41, 42, 43, -1, 45, -1, -1, -1, 49,
50, 51, 52, 53, 54, -1, 56, 57, -1, -1,
-1, 61, -1, -1, -1, -1, -1, 67, -1, -1,
@@ -3466,7 +3523,7 @@ static const short yycheck[] = { 4,
110, -1, -1, -1, 28, 29, 30, -1, 32, -1,
34, 35, 36, -1, 38, 39, 40, 41, 42, 43,
-1, 45, -1, -1, -1, 49, 50, 51, 52, 53,
- 54, -1, 56, 57, 58, -1, -1, -1, -1, -1,
+ 54, -1, 56, 57, -1, -1, -1, 61, -1, -1,
-1, -1, -1, 67, -1, -1, 70, -1, -1, -1,
-1, -1, -1, -1, 78, 79, 80, -1, -1, -1,
-1, -1, 86, 87, 88, 3, 4, 5, 6, 93,
@@ -3475,16 +3532,24 @@ static const short yycheck[] = { 4,
28, 29, 30, -1, 32, -1, 34, 35, 36, -1,
38, 39, 40, 41, 42, 43, -1, 45, -1, -1,
-1, 49, 50, 51, 52, 53, 54, -1, 56, 57,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, 67,
+ -1, -1, -1, 61, -1, -1, -1, -1, -1, 67,
-1, -1, 70, -1, -1, -1, -1, -1, -1, -1,
78, 79, 80, -1, -1, -1, -1, -1, 86, 87,
- 88, -1, -1, -1, -1, 93, 94, 3, 4, 5,
- 6, -1, 8, 9, 10, 11, -1, 13, 14, -1,
- -1, -1, 110, -1, -1, -1, -1, -1, -1, -1,
+ 88, 3, 4, 5, 6, 93, 8, 9, 10, 11,
+ -1, 13, 14, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 110, -1, -1, -1, 28, 29, 30, -1,
+ 32, -1, 34, 35, 36, -1, 38, 39, 40, 41,
+ 42, 43, -1, 45, -1, -1, -1, 49, 50, 51,
+ 52, 53, 54, -1, 56, 57, -1, -1, -1, 61,
+ -1, -1, -1, -1, -1, 67, -1, -1, 70, -1,
+ -1, -1, -1, -1, -1, -1, 78, 79, 80, -1,
+ -1, -1, -1, -1, 86, 87, 88, 3, 4, 5,
+ 6, 93, 8, 9, 10, 11, -1, 13, 14, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, 110, -1,
-1, -1, 28, 29, 30, -1, 32, -1, 34, 35,
36, -1, 38, 39, 40, 41, 42, 43, -1, 45,
-1, -1, -1, 49, 50, 51, 52, 53, 54, -1,
- 56, 57, -1, -1, -1, 61, -1, -1, -1, -1,
+ 56, 57, 58, -1, -1, -1, -1, -1, -1, -1,
-1, 67, -1, -1, 70, -1, -1, -1, -1, -1,
-1, -1, 78, 79, 80, -1, -1, -1, -1, -1,
86, 87, 88, 3, 4, 5, 6, 93, 8, 9,
@@ -3493,21 +3558,13 @@ static const short yycheck[] = { 4,
30, -1, 32, -1, 34, 35, 36, -1, 38, 39,
40, 41, 42, 43, -1, 45, -1, -1, -1, 49,
50, 51, 52, 53, 54, -1, 56, 57, -1, -1,
- -1, 61, -1, -1, -1, -1, -1, 67, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 67, -1, -1,
70, -1, -1, -1, -1, -1, -1, -1, 78, 79,
- 80, -1, -1, -1, -1, -1, 86, 87, 88, 3,
- 4, 5, 6, 93, 8, 9, 10, 11, -1, 13,
- 14, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- 110, -1, -1, -1, 28, 29, 30, -1, 32, -1,
- 34, 35, 36, -1, 38, 39, 40, 41, 42, 43,
- -1, 45, -1, -1, -1, 49, 50, 51, 52, 53,
- 54, -1, 56, 57, -1, -1, -1, 61, -1, -1,
- -1, -1, -1, 67, -1, -1, 70, -1, -1, -1,
- -1, -1, -1, -1, 78, 79, 80, -1, -1, -1,
- -1, -1, 86, 87, 88, 3, 4, 5, 6, 93,
+ 80, -1, -1, -1, -1, -1, 86, 87, 88, -1,
+ -1, -1, -1, 93, 94, 3, 4, 5, 6, -1,
8, 9, 10, 11, -1, 13, 14, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, 110, -1, -1, -1,
- 28, 29, 30, -1, 32, -1, 34, 35, 36, -1,
+ 110, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 28, 29, 30, 31, 32, -1, 34, 35, 36, -1,
38, 39, 40, 41, 42, 43, -1, 45, -1, -1,
-1, 49, 50, 51, 52, 53, 54, -1, 56, 57,
-1, -1, -1, -1, -1, -1, -1, -1, -1, 67,
@@ -3518,13 +3575,13 @@ static const short yycheck[] = { 4,
-1, -1, 110, -1, -1, -1, 28, 29, 30, -1,
32, -1, 34, 35, 36, -1, 38, 39, 40, 41,
42, 43, -1, 45, -1, -1, -1, 49, 50, 51,
- 52, 53, 54, -1, 56, 57, -1, -1, -1, -1,
+ 52, 53, 54, -1, 56, 57, -1, -1, -1, 61,
-1, -1, -1, -1, -1, 67, -1, -1, 70, -1,
-1, -1, -1, -1, -1, -1, 78, 79, 80, -1,
-1, -1, -1, -1, 86, 87, 88, 3, 4, 5,
6, 93, 8, 9, 10, 11, -1, 13, 14, -1,
-1, -1, -1, -1, -1, -1, -1, -1, 110, -1,
- -1, -1, 28, 29, 30, -1, 32, -1, 34, 35,
+ -1, -1, 28, 29, 30, 31, 32, -1, 34, 35,
36, -1, 38, 39, 40, 41, 42, 43, -1, 45,
-1, -1, -1, 49, 50, 51, 52, 53, 54, -1,
56, 57, -1, -1, -1, -1, -1, -1, -1, -1,
@@ -3545,63 +3602,42 @@ static const short yycheck[] = { 4,
34, 35, 36, -1, 38, 39, 40, 41, 42, 43,
-1, 45, -1, -1, -1, 49, 50, 51, 52, 53,
54, -1, 56, 57, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 67, -1, 1, 70, 3, 4, 5,
- 6, 7, 8, 9, 78, 79, 80, -1, 14, -1,
- -1, -1, 86, 87, 88, -1, -1, -1, -1, 93,
- -1, 27, 28, -1, 30, 31, 32, -1, -1, -1,
- 36, -1, -1, -1, -1, 41, 110, -1, 44, 45,
- 46, -1, 48, -1, -1, -1, -1, -1, 54, -1,
- 56, 57, -1, -1, 60, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, 70, -1, -1, -1, -1, -1,
- -1, -1, -1, 1, 80, 3, 4, 5, 6, 7,
- 8, 9, 88, -1, -1, -1, 14, 93, -1, -1,
- -1, -1, 98, -1, -1, -1, -1, -1, -1, -1,
- 28, -1, 30, 31, 32, -1, -1, -1, 36, -1,
- -1, -1, -1, 41, -1, -1, -1, 45, 46, -1,
- 48, -1, -1, -1, -1, -1, 54, -1, 56, 57,
- -1, -1, 60, -1, 62, -1, -1, -1, -1, -1,
- -1, -1, 70, 3, 4, 5, 6, 7, 8, 9,
- -1, -1, 80, -1, 14, -1, -1, -1, -1, -1,
- 88, -1, -1, -1, -1, 93, -1, -1, 28, -1,
- 30, 31, -1, -1, -1, -1, 36, -1, -1, -1,
- -1, 41, -1, -1, -1, 45, -1, -1, -1, -1,
- -1, -1, -1, -1, 54, -1, 56, 57, -1, -1,
- 60, -1, 3, 4, 5, 6, 7, 8, 9, -1,
- 70, -1, -1, 14, -1, -1, -1, -1, -1, -1,
- 80, -1, -1, -1, -1, -1, -1, 28, 88, 30,
- 31, -1, -1, 93, -1, 36, -1, -1, -1, -1,
- 41, -1, -1, -1, 45, -1, -1, -1, -1, -1,
- -1, -1, -1, 54, -1, 56, 57, 3, 4, 5,
- 6, 7, 8, 9, -1, -1, -1, -1, 14, 70,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, 80,
- -1, -1, -1, -1, -1, 31, -1, 88, -1, -1,
- 36, -1, 93, -1, -1, 41, -1, -1, -1, 45,
- -1, 47, -1, -1, -1, -1, -1, -1, 54, -1,
- 56, 57, -1, -1, -1, -1, 31, -1, -1, -1,
- -1, -1, -1, -1, 70, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, 80, -1, -1, -1, -1, -1,
- -1, -1, 88, -1, -1, -1, -1, 93, 63, 64,
- 65, 66, 67, 68, 69, 70, 71, 72, 73, 74,
- 75, 76, 77, 78, 79, 80, 81, 82, 83, 84,
- 63, 64, 65, 66, 67, 68, 69, 70, 71, 72,
- 73, 74, 75, 76, 77, 78, 79, 80, 81, 82,
- 83, 84, 63, 64, 65, 66, 67, 68, 69, 70,
- 71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
- 81, 82, 83, 84, -1, -1, -1, -1, 111, -1,
+ -1, -1, -1, 67, -1, -1, 70, -1, -1, -1,
+ -1, -1, -1, -1, 78, 79, 80, -1, -1, -1,
+ -1, -1, 86, 87, 88, 3, 4, 5, 6, 93,
+ 8, 9, 10, 11, -1, 13, 14, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 110, -1, -1, -1,
+ 28, 29, 30, -1, 32, -1, 34, 35, 36, -1,
+ 38, 39, 40, 41, 42, 43, -1, 45, -1, -1,
+ -1, 49, 50, 51, 52, 53, 54, -1, 56, 57,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, 67,
+ -1, -1, 70, -1, -1, -1, -1, -1, -1, -1,
+ 78, 79, 80, -1, -1, -1, -1, -1, 86, 87,
+ 88, -1, -1, 4, 5, 93, 7, 8, 9, -1,
+ -1, 12, -1, 14, -1, -1, -1, -1, -1, -1,
+ -1, -1, 110, -1, -1, -1, -1, 28, -1, 30,
+ 31, -1, -1, -1, -1, 36, -1, -1, -1, -1,
+ -1, -1, -1, -1, 45, -1, -1, -1, -1, -1,
+ -1, -1, -1, 54, -1, 56, 57, 63, 64, 65,
+ 66, 67, 68, 69, 70, 71, 72, 73, 74, 75,
+ 76, 77, 78, 79, 80, 81, 82, 83, 84, 63,
+ 64, 65, 66, 67, 68, 69, 70, 71, 72, 73,
+ 74, 75, 76, 77, 78, 79, 80, 81, 82, 83,
+ 84, -1, -1, -1, -1, 111, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 59, -1, -1, 107, 63, 64, 65,
+ 59, -1, -1, 107, 63, 64, 65, 66, 67, 68,
+ 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,
+ 79, 80, 81, 82, 83, 84, 62, 63, 64, 65,
66, 67, 68, 69, 70, 71, 72, 73, 74, 75,
- 76, 77, 78, 79, 80, 81, 82, 83, 84, 62,
- 63, 64, 65, 66, 67, 68, 69, 70, 71, 72,
- 73, 74, 75, 76, 77, 78, 79, 80, 81, 82,
- 83, 84, 63, 64, 65, 66, 67, 68, 69, 70,
- 71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
- 81, 82, 83, 84, 63, 64, 65, 66, 67, 68,
- 69, 70, 71, 72, 73, 74, -1, 76, 77, 78,
- 79, 80, 81, 82, 83, 84
+ 76, 77, 78, 79, 80, 81, 82, 83, 84, 63,
+ 64, 65, 66, 67, 68, 69, 70, 71, 72, 73,
+ 74, 75, 76, 77, 78, 79, 80, 81, 82, 83,
+ 84, 63, 64, 65, 66, 67, 68, 69, 70, 71,
+ 72, 73, 74, -1, 76, 77, 78, 79, 80, 81,
+ 82, 83, 84
};
/* -*-C-*- Note some compilers choke on comments on `#line' lines. */
-#line 3 "/usr/lib/bison.simple"
+#line 3 "/usr/local/gnu/share/bison.simple"
/* Skeleton output parser for bison,
Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc.
@@ -3794,7 +3830,7 @@ __yy_memcpy (char *to, char *from, int count)
#endif
#endif
-#line 196 "/usr/lib/bison.simple"
+#line 196 "/usr/local/gnu/share/bison.simple"
/* The user can define YYPARSE_PARAM as the name of an argument to be passed
into yyparse. The argument should have type void *.
@@ -4099,106 +4135,106 @@ yyreduce:
switch (yyn) {
case 2:
-#line 337 "parse.y"
+#line 341 "parse.y"
{ finish_translation_unit (); ;
break;}
case 3:
-#line 345 "parse.y"
+#line 349 "parse.y"
{ yyval.ttype = NULL_TREE; ;
break;}
case 4:
-#line 347 "parse.y"
+#line 351 "parse.y"
{ yyval.ttype = NULL_TREE; ;
break;}
case 5:
-#line 349 "parse.y"
+#line 353 "parse.y"
{ yyval.ttype = NULL_TREE; ;
break;}
case 8:
-#line 358 "parse.y"
+#line 362 "parse.y"
{ have_extern_spec = 1;
used_extern_spec = 0;
yyval.ttype = NULL_TREE; ;
break;}
case 9:
-#line 363 "parse.y"
+#line 367 "parse.y"
{ have_extern_spec = 0; ;
break;}
case 10:
-#line 368 "parse.y"
+#line 372 "parse.y"
{ yyval.itype = pedantic;
pedantic = 0; ;
break;}
case 12:
-#line 377 "parse.y"
+#line 381 "parse.y"
{ if (pending_lang_change) do_pending_lang_change(); ;
break;}
case 13:
-#line 379 "parse.y"
+#line 383 "parse.y"
{ if (! toplevel_bindings_p () && ! pseudo_global_level_p())
pop_everything (); ;
break;}
case 14:
-#line 385 "parse.y"
+#line 389 "parse.y"
{ if (pending_inlines) do_pending_inlines (); ;
break;}
case 15:
-#line 387 "parse.y"
+#line 391 "parse.y"
{ if (pending_inlines) do_pending_inlines (); ;
break;}
case 16:
-#line 389 "parse.y"
+#line 393 "parse.y"
{ if (pending_inlines) do_pending_inlines (); ;
break;}
case 17:
-#line 391 "parse.y"
+#line 395 "parse.y"
{ if (TREE_CHAIN (yyvsp[-2].ttype)) yyvsp[-2].ttype = combine_strings (yyvsp[-2].ttype);
assemble_asm (yyvsp[-2].ttype); ;
break;}
case 18:
-#line 394 "parse.y"
+#line 398 "parse.y"
{ pop_lang_context (); ;
break;}
case 19:
-#line 396 "parse.y"
+#line 400 "parse.y"
{ if (pending_inlines) do_pending_inlines ();
pop_lang_context (); ;
break;}
case 20:
-#line 399 "parse.y"
+#line 403 "parse.y"
{ if (pending_inlines) do_pending_inlines ();
pop_lang_context (); ;
break;}
case 21:
-#line 402 "parse.y"
+#line 406 "parse.y"
{ push_namespace (yyvsp[-1].ttype); ;
break;}
case 22:
-#line 404 "parse.y"
+#line 408 "parse.y"
{ pop_namespace (); ;
break;}
case 23:
-#line 406 "parse.y"
+#line 410 "parse.y"
{ push_namespace (NULL_TREE); ;
break;}
case 24:
-#line 408 "parse.y"
+#line 412 "parse.y"
{ pop_namespace (); ;
break;}
case 26:
-#line 411 "parse.y"
+#line 415 "parse.y"
{ do_toplevel_using_decl (yyvsp[-1].ttype); ;
break;}
case 28:
-#line 414 "parse.y"
+#line 418 "parse.y"
{ pedantic = yyvsp[-1].itype; ;
break;}
case 29:
-#line 419 "parse.y"
+#line 423 "parse.y"
{ begin_only_namespace_names (); ;
break;}
case 30:
-#line 421 "parse.y"
+#line 425 "parse.y"
{
end_only_namespace_names ();
if (lastiddecl)
@@ -4207,35 +4243,35 @@ case 30:
;
break;}
case 31:
-#line 431 "parse.y"
+#line 435 "parse.y"
{ yyval.ttype = yyvsp[0].ttype; ;
break;}
case 32:
-#line 433 "parse.y"
+#line 437 "parse.y"
{ yyval.ttype = yyvsp[0].ttype; ;
break;}
case 33:
-#line 435 "parse.y"
+#line 439 "parse.y"
{ yyval.ttype = yyvsp[0].ttype; ;
break;}
case 34:
-#line 440 "parse.y"
+#line 444 "parse.y"
{ yyval.ttype = build_parse_node (SCOPE_REF, yyvsp[-1].ttype, yyvsp[0].ttype); ;
break;}
case 35:
-#line 442 "parse.y"
+#line 446 "parse.y"
{ yyval.ttype = build_parse_node (SCOPE_REF, global_namespace, yyvsp[0].ttype); ;
break;}
case 36:
-#line 444 "parse.y"
+#line 448 "parse.y"
{ yyval.ttype = build_parse_node (SCOPE_REF, yyvsp[-1].ttype, yyvsp[0].ttype); ;
break;}
case 37:
-#line 449 "parse.y"
+#line 453 "parse.y"
{ begin_only_namespace_names (); ;
break;}
case 38:
-#line 451 "parse.y"
+#line 455 "parse.y"
{
end_only_namespace_names ();
/* If no declaration was found, the using-directive is
@@ -4247,7 +4283,7 @@ case 38:
;
break;}
case 39:
-#line 464 "parse.y"
+#line 468 "parse.y"
{
if (TREE_CODE (yyval.ttype) == IDENTIFIER_NODE)
yyval.ttype = lastiddecl;
@@ -4255,7 +4291,7 @@ case 39:
;
break;}
case 40:
-#line 470 "parse.y"
+#line 474 "parse.y"
{
yyval.ttype = yyvsp[-1].ttype;
if (TREE_CODE (yyval.ttype) == IDENTIFIER_NODE)
@@ -4264,86 +4300,86 @@ case 40:
;
break;}
case 43:
-#line 481 "parse.y"
+#line 485 "parse.y"
{ yyval.ttype = yyvsp[0].ttype; ;
break;}
case 44:
-#line 483 "parse.y"
+#line 487 "parse.y"
{ yyval.ttype = yyvsp[0].ttype; ;
break;}
case 45:
-#line 488 "parse.y"
+#line 492 "parse.y"
{ push_lang_context (yyvsp[0].ttype); ;
break;}
case 46:
-#line 490 "parse.y"
+#line 494 "parse.y"
{ if (current_lang_name != yyvsp[0].ttype)
cp_error ("use of linkage spec `%D' is different from previous spec `%D'", yyvsp[0].ttype, current_lang_name);
pop_lang_context (); push_lang_context (yyvsp[0].ttype); ;
break;}
case 47:
-#line 497 "parse.y"
+#line 501 "parse.y"
{ begin_template_parm_list (); ;
break;}
case 48:
-#line 499 "parse.y"
+#line 503 "parse.y"
{ yyval.ttype = end_template_parm_list (yyvsp[-1].ttype); ;
break;}
case 49:
-#line 501 "parse.y"
+#line 505 "parse.y"
{ begin_specialization();
yyval.ttype = NULL_TREE; ;
break;}
case 50:
-#line 507 "parse.y"
+#line 511 "parse.y"
{ yyval.ttype = process_template_parm (NULL_TREE, yyvsp[0].ttype); ;
break;}
case 51:
-#line 509 "parse.y"
+#line 513 "parse.y"
{ yyval.ttype = process_template_parm (yyvsp[-2].ttype, yyvsp[0].ttype); ;
break;}
case 52:
-#line 514 "parse.y"
+#line 518 "parse.y"
{ yyval.ttype = yyvsp[0].ttype; ;
break;}
case 53:
-#line 516 "parse.y"
+#line 520 "parse.y"
{ yyval.ttype = NULL_TREE; ;
break;}
case 54:
-#line 520 "parse.y"
+#line 524 "parse.y"
{ yyval.ttype = finish_template_type_parm (yyvsp[-1].ttype, yyvsp[0].ttype); ;
break;}
case 55:
-#line 522 "parse.y"
+#line 526 "parse.y"
{ yyval.ttype = finish_template_type_parm (class_type_node, yyvsp[0].ttype); ;
break;}
case 56:
-#line 527 "parse.y"
+#line 531 "parse.y"
{ yyval.ttype = finish_template_template_parm (yyvsp[-1].ttype, yyvsp[0].ttype); ;
break;}
case 57:
-#line 539 "parse.y"
+#line 543 "parse.y"
{ yyval.ttype = build_tree_list (NULL_TREE, yyvsp[0].ttype); ;
break;}
case 58:
-#line 541 "parse.y"
+#line 545 "parse.y"
{ yyval.ttype = build_tree_list (groktypename (yyvsp[0].ftype.t), yyvsp[-2].ttype); ;
break;}
case 59:
-#line 543 "parse.y"
+#line 547 "parse.y"
{ yyval.ttype = build_tree_list (NULL_TREE, yyvsp[0].ftype.t); ;
break;}
case 60:
-#line 545 "parse.y"
+#line 549 "parse.y"
{ yyval.ttype = build_tree_list (yyvsp[0].ttype, yyvsp[-2].ftype.t); ;
break;}
case 61:
-#line 547 "parse.y"
+#line 551 "parse.y"
{ yyval.ttype = build_tree_list (NULL_TREE, yyvsp[0].ttype); ;
break;}
case 62:
-#line 549 "parse.y"
+#line 553 "parse.y"
{
if (TREE_CODE (yyvsp[0].ttype) != TEMPLATE_DECL
&& TREE_CODE (yyvsp[0].ttype) != TEMPLATE_TEMPLATE_PARM
@@ -4356,66 +4392,66 @@ case 62:
;
break;}
case 63:
-#line 563 "parse.y"
+#line 567 "parse.y"
{ finish_template_decl (yyvsp[-1].ttype); ;
break;}
case 64:
-#line 565 "parse.y"
+#line 569 "parse.y"
{ finish_template_decl (yyvsp[-1].ttype); ;
break;}
case 65:
-#line 570 "parse.y"
+#line 574 "parse.y"
{ if (pending_inlines) do_pending_inlines (); ;
break;}
case 66:
-#line 572 "parse.y"
+#line 576 "parse.y"
{ if (pending_inlines) do_pending_inlines (); ;
break;}
case 67:
-#line 574 "parse.y"
+#line 578 "parse.y"
{ if (pending_inlines) do_pending_inlines (); ;
break;}
case 68:
-#line 576 "parse.y"
+#line 580 "parse.y"
{ if (pending_inlines) do_pending_inlines ();
pop_lang_context (); ;
break;}
case 69:
-#line 579 "parse.y"
+#line 583 "parse.y"
{ if (pending_inlines) do_pending_inlines ();
pop_lang_context (); ;
break;}
case 70:
-#line 582 "parse.y"
+#line 586 "parse.y"
{ pedantic = yyvsp[-1].itype; ;
break;}
case 72:
-#line 588 "parse.y"
+#line 592 "parse.y"
{;
break;}
case 73:
-#line 590 "parse.y"
+#line 594 "parse.y"
{ note_list_got_semicolon (yyvsp[-2].ftype.t); ;
break;}
case 74:
-#line 592 "parse.y"
+#line 596 "parse.y"
{ maybe_process_partial_specialization (yyvsp[-1].ftype.t);
note_got_semicolon (yyvsp[-1].ftype.t); ;
break;}
case 76:
-#line 599 "parse.y"
+#line 603 "parse.y"
{;
break;}
case 77:
-#line 601 "parse.y"
+#line 605 "parse.y"
{ note_list_got_semicolon (yyvsp[-2].ftype.t); ;
break;}
case 78:
-#line 603 "parse.y"
+#line 607 "parse.y"
{ pedwarn ("empty declaration"); ;
break;}
case 80:
-#line 606 "parse.y"
+#line 610 "parse.y"
{
tree t, attrs;
split_specs_attrs (yyvsp[-1].ftype.t, &t, &attrs);
@@ -4424,126 +4460,132 @@ case 80:
;
break;}
case 84:
-#line 619 "parse.y"
+#line 623 "parse.y"
{ yyval.itype = 0; ;
break;}
case 85:
-#line 621 "parse.y"
+#line 625 "parse.y"
{ yyval.itype = 1; ;
break;}
case 91:
-#line 637 "parse.y"
+#line 641 "parse.y"
{ finish_function (lineno, (int)yyvsp[-1].itype, 0); ;
break;}
case 92:
-#line 639 "parse.y"
-{ ;
+#line 643 "parse.y"
+{
+ int nested = (hack_decl_function_context
+ (current_function_decl) != NULL_TREE);
+ finish_function (lineno, (int)yyvsp[0].itype, nested);
+ ;
break;}
case 93:
-#line 641 "parse.y"
+#line 649 "parse.y"
{ ;
break;}
case 94:
-#line 646 "parse.y"
+#line 654 "parse.y"
{ yyval.ttype = begin_constructor_declarator (yyvsp[-2].ttype, yyvsp[-1].ttype); ;
break;}
case 95:
-#line 648 "parse.y"
+#line 656 "parse.y"
{ yyval.ttype = make_call_declarator (yyvsp[-4].ttype, yyvsp[-3].ttype, yyvsp[-1].ttype, yyvsp[0].ttype); ;
break;}
case 96:
-#line 650 "parse.y"
+#line 658 "parse.y"
{ yyval.ttype = begin_constructor_declarator (yyvsp[-4].ttype, yyvsp[-3].ttype);
yyval.ttype = make_call_declarator (yyval.ttype, empty_parms (), yyvsp[-1].ttype, yyvsp[0].ttype);
;
break;}
case 97:
-#line 654 "parse.y"
+#line 662 "parse.y"
{ yyval.ttype = begin_constructor_declarator (yyvsp[-2].ttype, yyvsp[-1].ttype); ;
break;}
case 98:
-#line 656 "parse.y"
+#line 664 "parse.y"
{ yyval.ttype = make_call_declarator (yyvsp[-4].ttype, yyvsp[-3].ttype, yyvsp[-1].ttype, yyvsp[0].ttype); ;
break;}
case 99:
-#line 658 "parse.y"
+#line 666 "parse.y"
{ yyval.ttype = begin_constructor_declarator (yyvsp[-4].ttype, yyvsp[-3].ttype);
yyval.ttype = make_call_declarator (yyval.ttype, empty_parms (), yyvsp[-1].ttype, yyvsp[0].ttype);
;
break;}
case 100:
-#line 662 "parse.y"
+#line 670 "parse.y"
{ yyval.ttype = begin_constructor_declarator (yyvsp[-2].ttype, yyvsp[-1].ttype); ;
break;}
case 101:
-#line 664 "parse.y"
+#line 672 "parse.y"
{ yyval.ttype = make_call_declarator (yyvsp[-4].ttype, yyvsp[-3].ttype, yyvsp[-1].ttype, yyvsp[0].ttype); ;
break;}
case 102:
-#line 666 "parse.y"
+#line 674 "parse.y"
{ yyval.ttype = begin_constructor_declarator (yyvsp[-4].ttype, yyvsp[-3].ttype);
yyval.ttype = make_call_declarator (yyval.ttype, empty_parms (), yyvsp[-1].ttype, yyvsp[0].ttype);
;
break;}
case 103:
-#line 670 "parse.y"
+#line 678 "parse.y"
{ yyval.ttype = begin_constructor_declarator (yyvsp[-2].ttype, yyvsp[-1].ttype); ;
break;}
case 104:
-#line 672 "parse.y"
+#line 680 "parse.y"
{ yyval.ttype = make_call_declarator (yyvsp[-4].ttype, yyvsp[-3].ttype, yyvsp[-1].ttype, yyvsp[0].ttype); ;
break;}
case 105:
-#line 674 "parse.y"
+#line 682 "parse.y"
{ yyval.ttype = begin_constructor_declarator (yyvsp[-4].ttype, yyvsp[-3].ttype);
yyval.ttype = make_call_declarator (yyval.ttype, empty_parms (), yyvsp[-1].ttype, yyvsp[0].ttype);
;
break;}
case 106:
-#line 681 "parse.y"
+#line 689 "parse.y"
{ if (!begin_function_definition (yyvsp[-1].ftype.t, yyvsp[0].ttype))
YYERROR1; ;
break;}
case 107:
-#line 684 "parse.y"
+#line 692 "parse.y"
{ if (!begin_function_definition (yyvsp[-1].ttype, yyvsp[0].ttype))
YYERROR1; ;
break;}
case 108:
-#line 687 "parse.y"
+#line 695 "parse.y"
{ if (!begin_function_definition (NULL_TREE, yyvsp[0].ttype))
YYERROR1; ;
break;}
case 109:
-#line 690 "parse.y"
+#line 698 "parse.y"
{ if (!begin_function_definition (yyvsp[-1].ttype, yyvsp[0].ttype))
YYERROR1; ;
break;}
case 110:
-#line 693 "parse.y"
+#line 701 "parse.y"
{ if (!begin_function_definition (NULL_TREE, yyvsp[0].ttype))
YYERROR1; ;
break;}
case 111:
-#line 699 "parse.y"
+#line 707 "parse.y"
{ yyval.ttype = make_call_declarator (yyvsp[-5].ttype, yyvsp[-3].ttype, yyvsp[-1].ttype, yyvsp[0].ttype); ;
break;}
case 112:
-#line 701 "parse.y"
+#line 709 "parse.y"
{ yyval.ttype = make_call_declarator (yyvsp[-3].ttype, empty_parms (), yyvsp[-1].ttype, yyvsp[0].ttype); ;
break;}
case 113:
-#line 703 "parse.y"
+#line 711 "parse.y"
{ yyval.ttype = make_call_declarator (yyvsp[-5].ttype, yyvsp[-3].ttype, yyvsp[-1].ttype, yyvsp[0].ttype); ;
break;}
case 114:
-#line 705 "parse.y"
+#line 713 "parse.y"
{ yyval.ttype = make_call_declarator (yyvsp[-3].ttype, empty_parms (), yyvsp[-1].ttype, yyvsp[0].ttype); ;
break;}
case 115:
-#line 712 "parse.y"
-{ tree specs = strip_attrs (yyvsp[-1].ttype);
- yyval.ttype = start_method (specs, yyvsp[0].ttype);
+#line 720 "parse.y"
+{ tree specs, attrs;
+ split_specs_attrs (yyvsp[-1].ttype, &specs, &attrs);
+ attrs = build_tree_list (attrs, NULL_TREE);
+ yyval.ttype = start_method (specs, yyvsp[0].ttype, attrs);
rest_of_mdef:
if (! yyval.ttype)
YYERROR1;
@@ -4552,34 +4594,43 @@ case 115:
reinit_parse_for_method (yychar, yyval.ttype); ;
break;}
case 116:
-#line 721 "parse.y"
-{ yyval.ttype = start_method (NULL_TREE, yyvsp[0].ttype); goto rest_of_mdef; ;
+#line 731 "parse.y"
+{ yyval.ttype = start_method (NULL_TREE, yyvsp[0].ttype, NULL_TREE);
+ goto rest_of_mdef; ;
break;}
case 117:
-#line 723 "parse.y"
-{ tree specs = strip_attrs (yyvsp[-1].ftype.t);
- yyval.ttype = start_method (specs, yyvsp[0].ttype); goto rest_of_mdef; ;
+#line 734 "parse.y"
+{ tree specs, attrs;
+ split_specs_attrs (yyvsp[-1].ftype.t, &specs, &attrs);
+ attrs = build_tree_list (attrs, NULL_TREE);
+ yyval.ttype = start_method (specs, yyvsp[0].ttype, attrs); goto rest_of_mdef; ;
break;}
case 118:
-#line 726 "parse.y"
-{ tree specs = strip_attrs (yyvsp[-1].ttype);
- yyval.ttype = start_method (specs, yyvsp[0].ttype); goto rest_of_mdef; ;
+#line 739 "parse.y"
+{ tree specs, attrs;
+ split_specs_attrs (yyvsp[-1].ttype, &specs, &attrs);
+ attrs = build_tree_list (attrs, NULL_TREE);
+ yyval.ttype = start_method (specs, yyvsp[0].ttype, attrs); goto rest_of_mdef; ;
break;}
case 119:
-#line 729 "parse.y"
-{ yyval.ttype = start_method (NULL_TREE, yyval.ttype); goto rest_of_mdef; ;
+#line 744 "parse.y"
+{ yyval.ttype = start_method (NULL_TREE, yyval.ttype, NULL_TREE);
+ goto rest_of_mdef; ;
break;}
case 120:
-#line 731 "parse.y"
-{ tree specs = strip_attrs (yyvsp[-1].ttype);
- yyval.ttype = start_method (specs, yyvsp[0].ttype); goto rest_of_mdef; ;
+#line 747 "parse.y"
+{ tree specs, attrs;
+ split_specs_attrs (yyvsp[-1].ttype, &specs, &attrs);
+ attrs = build_tree_list (attrs, NULL_TREE);
+ yyval.ttype = start_method (specs, yyvsp[0].ttype, attrs); goto rest_of_mdef; ;
break;}
case 121:
-#line 734 "parse.y"
-{ yyval.ttype = start_method (NULL_TREE, yyval.ttype); goto rest_of_mdef; ;
+#line 752 "parse.y"
+{ yyval.ttype = start_method (NULL_TREE, yyval.ttype, NULL_TREE);
+ goto rest_of_mdef; ;
break;}
case 122:
-#line 739 "parse.y"
+#line 758 "parse.y"
{
if (! current_function_parms_stored)
store_parm_decls ();
@@ -4587,19 +4638,19 @@ case 122:
;
break;}
case 123:
-#line 748 "parse.y"
+#line 767 "parse.y"
{ store_return_init (yyval.ttype, yyvsp[0].ttype); ;
break;}
case 124:
-#line 750 "parse.y"
+#line 769 "parse.y"
{ store_return_init (yyval.ttype, yyvsp[-1].ttype); ;
break;}
case 125:
-#line 752 "parse.y"
+#line 771 "parse.y"
{ store_return_init (yyval.ttype, NULL_TREE); ;
break;}
case 126:
-#line 757 "parse.y"
+#line 776 "parse.y"
{
if (yyvsp[0].itype == 0)
error ("no base initializers given following ':'");
@@ -4611,7 +4662,7 @@ case 126:
;
break;}
case 127:
-#line 770 "parse.y"
+#line 789 "parse.y"
{
if (! current_function_parms_stored)
store_parm_decls ();
@@ -4630,15 +4681,15 @@ case 127:
;
break;}
case 128:
-#line 790 "parse.y"
+#line 809 "parse.y"
{ yyval.itype = 0; ;
break;}
case 129:
-#line 792 "parse.y"
+#line 811 "parse.y"
{ yyval.itype = 1; ;
break;}
case 132:
-#line 799 "parse.y"
+#line 818 "parse.y"
{
if (current_class_name)
pedwarn ("anachronistic old style base class initializer");
@@ -4646,7 +4697,7 @@ case 132:
;
break;}
case 133:
-#line 805 "parse.y"
+#line 824 "parse.y"
{
if (current_class_name)
pedwarn ("anachronistic old style base class initializer");
@@ -4654,89 +4705,93 @@ case 133:
;
break;}
case 134:
-#line 811 "parse.y"
+#line 830 "parse.y"
{ expand_member_init (current_class_ref, yyvsp[-3].ttype, yyvsp[-1].ttype); ;
break;}
case 135:
-#line 813 "parse.y"
+#line 832 "parse.y"
{ expand_member_init (current_class_ref, yyvsp[-1].ttype, void_type_node); ;
break;}
case 136:
-#line 815 "parse.y"
+#line 834 "parse.y"
{ expand_member_init (current_class_ref, yyvsp[-3].ttype, yyvsp[-1].ttype); ;
break;}
case 137:
-#line 817 "parse.y"
+#line 836 "parse.y"
{ expand_member_init (current_class_ref, yyvsp[-1].ttype, void_type_node); ;
break;}
case 138:
-#line 819 "parse.y"
+#line 838 "parse.y"
{ expand_member_init (current_class_ref, TYPE_MAIN_DECL (yyvsp[-3].ttype),
yyvsp[-1].ttype); ;
break;}
case 139:
-#line 822 "parse.y"
+#line 841 "parse.y"
{ expand_member_init (current_class_ref, TYPE_MAIN_DECL (yyvsp[-1].ttype),
void_type_node); ;
break;}
case 151:
-#line 848 "parse.y"
+#line 867 "parse.y"
{ do_type_instantiation (yyvsp[-1].ftype.t, NULL_TREE);
yyungetc (';', 1); ;
break;}
case 153:
-#line 852 "parse.y"
+#line 871 "parse.y"
{ tree specs = strip_attrs (yyvsp[-1].ftype.t);
do_decl_instantiation (specs, yyvsp[0].ttype, NULL_TREE); ;
break;}
case 155:
-#line 856 "parse.y"
+#line 875 "parse.y"
{ do_decl_instantiation (NULL_TREE, yyvsp[0].ttype, NULL_TREE); ;
break;}
case 157:
-#line 859 "parse.y"
+#line 878 "parse.y"
{ do_decl_instantiation (NULL_TREE, yyvsp[0].ttype, NULL_TREE); ;
break;}
case 159:
-#line 862 "parse.y"
+#line 881 "parse.y"
{ do_type_instantiation (yyvsp[-1].ftype.t, yyvsp[-4].ttype);
yyungetc (';', 1); ;
break;}
case 161:
-#line 867 "parse.y"
+#line 886 "parse.y"
{ tree specs = strip_attrs (yyvsp[-1].ftype.t);
do_decl_instantiation (specs, yyvsp[0].ttype, yyvsp[-4].ttype); ;
break;}
case 163:
-#line 871 "parse.y"
+#line 890 "parse.y"
{ do_decl_instantiation (NULL_TREE, yyvsp[0].ttype, yyvsp[-3].ttype); ;
break;}
case 165:
-#line 874 "parse.y"
+#line 893 "parse.y"
{ do_decl_instantiation (NULL_TREE, yyvsp[0].ttype, yyvsp[-3].ttype); ;
break;}
case 167:
-#line 879 "parse.y"
+#line 898 "parse.y"
{ begin_explicit_instantiation(); ;
break;}
case 168:
-#line 882 "parse.y"
+#line 901 "parse.y"
{ end_explicit_instantiation(); ;
break;}
case 169:
-#line 891 "parse.y"
+#line 910 "parse.y"
{ yyval.ttype = yyvsp[0].ttype; ;
break;}
case 170:
-#line 894 "parse.y"
+#line 913 "parse.y"
{ yyval.ttype = yyvsp[0].ttype; ;
break;}
-case 172:
-#line 901 "parse.y"
+case 173:
+#line 921 "parse.y"
{ yyval.ttype = yyvsp[0].ttype; ;
break;}
-case 173:
-#line 905 "parse.y"
+case 174:
+#line 926 "parse.y"
+{ yyval.ttype = yyvsp[0].ttype; ;
+ break;}
+case 175:
+#line 930 "parse.y"
{
if (yychar == YYEMPTY)
yychar = YYLEX;
@@ -4745,88 +4800,88 @@ case 173:
yychar == SCOPE);
;
break;}
-case 175:
-#line 916 "parse.y"
+case 177:
+#line 941 "parse.y"
{
/* Handle `Class<Class<Type>>' without space in the `>>' */
pedwarn ("`>>' should be `> >' in template class name");
yyungetc ('>', 1);
;
break;}
-case 176:
-#line 925 "parse.y"
+case 178:
+#line 950 "parse.y"
{ yyval.ttype = NULL_TREE; ;
break;}
-case 178:
-#line 931 "parse.y"
+case 180:
+#line 956 "parse.y"
{ yyval.ttype = build_tree_list (NULL_TREE, yyval.ttype); ;
break;}
-case 179:
-#line 933 "parse.y"
+case 181:
+#line 958 "parse.y"
{ yyval.ttype = chainon (yyval.ttype, build_tree_list (NULL_TREE, yyvsp[0].ttype)); ;
break;}
-case 180:
-#line 938 "parse.y"
+case 182:
+#line 963 "parse.y"
{ yyval.ttype = groktypename (yyvsp[0].ftype.t); ;
break;}
-case 181:
-#line 940 "parse.y"
+case 183:
+#line 965 "parse.y"
{ yyval.ttype = lastiddecl; ;
break;}
-case 183:
-#line 946 "parse.y"
+case 185:
+#line 971 "parse.y"
{ yyval.code = NEGATE_EXPR; ;
break;}
-case 184:
-#line 948 "parse.y"
+case 186:
+#line 973 "parse.y"
{ yyval.code = CONVERT_EXPR; ;
break;}
-case 185:
-#line 950 "parse.y"
+case 187:
+#line 975 "parse.y"
{ yyval.code = PREINCREMENT_EXPR; ;
break;}
-case 186:
-#line 952 "parse.y"
+case 188:
+#line 977 "parse.y"
{ yyval.code = PREDECREMENT_EXPR; ;
break;}
-case 187:
-#line 954 "parse.y"
+case 189:
+#line 979 "parse.y"
{ yyval.code = TRUTH_NOT_EXPR; ;
break;}
-case 188:
-#line 959 "parse.y"
+case 190:
+#line 984 "parse.y"
{ yyval.ttype = build_x_compound_expr (yyval.ttype); ;
break;}
-case 190:
-#line 965 "parse.y"
+case 192:
+#line 990 "parse.y"
{ error ("ANSI C++ forbids an empty condition for `%s'",
cond_stmt_keyword);
yyval.ttype = integer_zero_node; ;
break;}
-case 191:
-#line 969 "parse.y"
+case 193:
+#line 994 "parse.y"
{ yyval.ttype = yyvsp[-1].ttype; ;
break;}
-case 192:
-#line 974 "parse.y"
+case 194:
+#line 999 "parse.y"
{ error ("ANSI C++ forbids an empty condition for `%s'",
cond_stmt_keyword);
yyval.ttype = integer_zero_node; ;
break;}
-case 193:
-#line 978 "parse.y"
+case 195:
+#line 1003 "parse.y"
{ yyval.ttype = yyvsp[-1].ttype; ;
break;}
-case 194:
-#line 983 "parse.y"
+case 196:
+#line 1008 "parse.y"
{ yyval.ttype = NULL_TREE; ;
break;}
-case 196:
-#line 986 "parse.y"
+case 198:
+#line 1011 "parse.y"
{ yyval.ttype = NULL_TREE; ;
break;}
-case 197:
-#line 991 "parse.y"
+case 199:
+#line 1016 "parse.y"
{ {
tree d;
for (d = getdecls (); d; d = TREE_CHAIN (d))
@@ -4844,193 +4899,194 @@ case 197:
yyvsp[-1].ttype, /*prefix_attributes*/ NULL_TREE);
;
break;}
-case 198:
-#line 1008 "parse.y"
+case 200:
+#line 1033 "parse.y"
{
cp_finish_decl (yyvsp[-1].ttype, yyvsp[0].ttype, yyvsp[-3].ttype, 1, LOOKUP_ONLYCONVERTING);
resume_momentary (yyvsp[-2].itype);
- yyval.ttype = yyvsp[-1].ttype;
+ yyval.ttype = convert_from_reference (yyvsp[-1].ttype);
if (TREE_CODE (TREE_TYPE (yyval.ttype)) == ARRAY_TYPE)
cp_error ("definition of array `%#D' in condition", yyval.ttype);
;
break;}
-case 204:
-#line 1027 "parse.y"
+case 206:
+#line 1052 "parse.y"
{ yyval.ttype = begin_compound_stmt (1); ;
break;}
-case 205:
-#line 1029 "parse.y"
+case 207:
+#line 1054 "parse.y"
{ finish_compound_stmt (1, yyvsp[-1].ttype); ;
break;}
-case 207:
-#line 1036 "parse.y"
+case 209:
+#line 1061 "parse.y"
{ yyval.ttype = expr_tree_cons (NULL_TREE, yyval.ttype,
build_expr_list (NULL_TREE, yyvsp[0].ttype)); ;
break;}
-case 208:
-#line 1039 "parse.y"
+case 210:
+#line 1064 "parse.y"
{ yyval.ttype = expr_tree_cons (NULL_TREE, yyval.ttype,
build_expr_list (NULL_TREE, error_mark_node)); ;
break;}
-case 209:
-#line 1042 "parse.y"
+case 211:
+#line 1067 "parse.y"
{ chainon (yyval.ttype, build_expr_list (NULL_TREE, yyvsp[0].ttype)); ;
break;}
-case 210:
-#line 1044 "parse.y"
+case 212:
+#line 1069 "parse.y"
{ chainon (yyval.ttype, build_expr_list (NULL_TREE, error_mark_node)); ;
break;}
-case 211:
-#line 1049 "parse.y"
+case 213:
+#line 1074 "parse.y"
{ yyval.ttype = build_expr_list (NULL_TREE, yyval.ttype); ;
break;}
-case 213:
-#line 1055 "parse.y"
+case 215:
+#line 1080 "parse.y"
{ yyval.ttype = yyvsp[0].ttype; ;
break;}
-case 214:
-#line 1058 "parse.y"
+case 216:
+#line 1083 "parse.y"
{ yyval.ttype = yyvsp[0].ttype;
pedantic = yyvsp[-1].itype; ;
break;}
-case 215:
-#line 1061 "parse.y"
+case 217:
+#line 1086 "parse.y"
{ yyval.ttype = build_x_indirect_ref (yyvsp[0].ttype, "unary *"); ;
break;}
-case 216:
-#line 1063 "parse.y"
+case 218:
+#line 1088 "parse.y"
{ yyval.ttype = build_x_unary_op (ADDR_EXPR, yyvsp[0].ttype); ;
break;}
-case 217:
-#line 1065 "parse.y"
+case 219:
+#line 1090 "parse.y"
{ yyval.ttype = build_x_unary_op (BIT_NOT_EXPR, yyvsp[0].ttype); ;
break;}
-case 218:
-#line 1067 "parse.y"
+case 220:
+#line 1092 "parse.y"
{ yyval.ttype = finish_unary_op_expr (yyvsp[-1].code, yyvsp[0].ttype); ;
break;}
-case 219:
-#line 1070 "parse.y"
+case 221:
+#line 1095 "parse.y"
{ if (pedantic)
pedwarn ("ANSI C++ forbids `&&'");
yyval.ttype = finish_label_address_expr (yyvsp[0].ttype); ;
break;}
-case 220:
-#line 1074 "parse.y"
+case 222:
+#line 1099 "parse.y"
{ yyval.ttype = expr_sizeof (yyvsp[0].ttype); ;
break;}
-case 221:
-#line 1076 "parse.y"
-{ yyval.ttype = c_sizeof (groktypename (yyvsp[-1].ftype.t)); ;
+case 223:
+#line 1101 "parse.y"
+{ yyval.ttype = c_sizeof (groktypename (yyvsp[-1].ftype.t));
+ check_for_new_type ("sizeof", yyvsp[-1].ftype); ;
break;}
-case 222:
-#line 1078 "parse.y"
+case 224:
+#line 1104 "parse.y"
{ yyval.ttype = grok_alignof (yyvsp[0].ttype); ;
break;}
-case 223:
-#line 1080 "parse.y"
+case 225:
+#line 1106 "parse.y"
{ yyval.ttype = c_alignof (groktypename (yyvsp[-1].ftype.t));
check_for_new_type ("alignof", yyvsp[-1].ftype); ;
break;}
-case 224:
-#line 1086 "parse.y"
+case 226:
+#line 1112 "parse.y"
{ yyval.ttype = build_new (NULL_TREE, yyvsp[0].ftype.t, NULL_TREE, yyvsp[-1].itype);
check_for_new_type ("new", yyvsp[0].ftype); ;
break;}
-case 225:
-#line 1089 "parse.y"
+case 227:
+#line 1115 "parse.y"
{ yyval.ttype = build_new (NULL_TREE, yyvsp[-1].ftype.t, yyvsp[0].ttype, yyvsp[-2].itype);
check_for_new_type ("new", yyvsp[-1].ftype); ;
break;}
-case 226:
-#line 1092 "parse.y"
+case 228:
+#line 1118 "parse.y"
{ yyval.ttype = build_new (yyvsp[-1].ttype, yyvsp[0].ftype.t, NULL_TREE, yyvsp[-2].itype);
check_for_new_type ("new", yyvsp[0].ftype); ;
break;}
-case 227:
-#line 1095 "parse.y"
+case 229:
+#line 1121 "parse.y"
{ yyval.ttype = build_new (yyvsp[-2].ttype, yyvsp[-1].ftype.t, yyvsp[0].ttype, yyvsp[-3].itype);
check_for_new_type ("new", yyvsp[-1].ftype); ;
break;}
-case 228:
-#line 1108 "parse.y"
+case 230:
+#line 1134 "parse.y"
{ yyval.ttype = build_new (NULL_TREE, groktypename(yyvsp[-1].ftype.t),
NULL_TREE, yyvsp[-4].itype);
check_for_new_type ("new", yyvsp[-1].ftype); ;
break;}
-case 229:
-#line 1113 "parse.y"
+case 231:
+#line 1139 "parse.y"
{ yyval.ttype = build_new (NULL_TREE, groktypename(yyvsp[-2].ftype.t), yyvsp[0].ttype, yyvsp[-5].itype);
check_for_new_type ("new", yyvsp[-2].ftype); ;
break;}
-case 230:
-#line 1117 "parse.y"
+case 232:
+#line 1143 "parse.y"
{ yyval.ttype = build_new (yyvsp[-4].ttype, groktypename(yyvsp[-1].ftype.t), NULL_TREE, yyvsp[-5].itype);
check_for_new_type ("new", yyvsp[-1].ftype); ;
break;}
-case 231:
-#line 1121 "parse.y"
+case 233:
+#line 1147 "parse.y"
{ yyval.ttype = build_new (yyvsp[-5].ttype, groktypename(yyvsp[-2].ftype.t), yyvsp[0].ttype, yyvsp[-6].itype);
check_for_new_type ("new", yyvsp[-2].ftype); ;
break;}
-case 232:
-#line 1125 "parse.y"
+case 234:
+#line 1151 "parse.y"
{ yyval.ttype = delete_sanity (yyvsp[0].ttype, NULL_TREE, 0, yyvsp[-1].itype); ;
break;}
-case 233:
-#line 1127 "parse.y"
+case 235:
+#line 1153 "parse.y"
{ yyval.ttype = delete_sanity (yyvsp[0].ttype, NULL_TREE, 1, yyvsp[-3].itype);
if (yychar == YYEMPTY)
yychar = YYLEX; ;
break;}
-case 234:
-#line 1131 "parse.y"
+case 236:
+#line 1157 "parse.y"
{ yyval.ttype = delete_sanity (yyvsp[0].ttype, yyvsp[-2].ttype, 2, yyvsp[-4].itype);
if (yychar == YYEMPTY)
yychar = YYLEX; ;
break;}
-case 235:
-#line 1135 "parse.y"
+case 237:
+#line 1161 "parse.y"
{ yyval.ttype = build_x_unary_op (REALPART_EXPR, yyvsp[0].ttype); ;
break;}
-case 236:
-#line 1137 "parse.y"
+case 238:
+#line 1163 "parse.y"
{ yyval.ttype = build_x_unary_op (IMAGPART_EXPR, yyvsp[0].ttype); ;
break;}
-case 237:
-#line 1147 "parse.y"
+case 239:
+#line 1173 "parse.y"
{ finish_new_placement (NULL_TREE, yyvsp[-2].itype); ;
break;}
-case 238:
-#line 1150 "parse.y"
+case 240:
+#line 1176 "parse.y"
{ yyval.itype = begin_new_placement (); ;
break;}
-case 239:
-#line 1154 "parse.y"
+case 241:
+#line 1180 "parse.y"
{ yyval.ttype = finish_new_placement (yyvsp[-1].ttype, yyvsp[-2].itype); ;
break;}
-case 240:
-#line 1156 "parse.y"
+case 242:
+#line 1182 "parse.y"
{ cp_pedwarn ("old style placement syntax, use () instead");
yyval.ttype = finish_new_placement (yyvsp[-1].ttype, yyvsp[-2].itype); ;
break;}
-case 241:
-#line 1162 "parse.y"
+case 243:
+#line 1188 "parse.y"
{ yyval.ttype = yyvsp[-1].ttype; ;
break;}
-case 242:
-#line 1164 "parse.y"
+case 244:
+#line 1190 "parse.y"
{ yyval.ttype = NULL_TREE; ;
break;}
-case 243:
-#line 1166 "parse.y"
+case 245:
+#line 1192 "parse.y"
{
cp_error ("`%T' is not a valid expression", yyvsp[-1].ftype.t);
yyval.ttype = error_mark_node;
;
break;}
-case 244:
-#line 1174 "parse.y"
+case 246:
+#line 1200 "parse.y"
{
if (pedantic)
pedwarn ("ANSI C++ forbids initialization of new expression with `='");
@@ -5041,24 +5097,24 @@ case 244:
yyval.ttype = yyvsp[0].ttype;
;
break;}
-case 245:
-#line 1188 "parse.y"
+case 247:
+#line 1214 "parse.y"
{ yyvsp[-1].ftype.t = finish_parmlist (build_tree_list (NULL_TREE, yyvsp[-1].ftype.t), 0);
yyval.ttype = make_call_declarator (NULL_TREE, yyvsp[-1].ftype.t, NULL_TREE, NULL_TREE);
check_for_new_type ("cast", yyvsp[-1].ftype); ;
break;}
-case 246:
-#line 1192 "parse.y"
+case 248:
+#line 1218 "parse.y"
{ yyvsp[-1].ftype.t = finish_parmlist (build_tree_list (NULL_TREE, yyvsp[-1].ftype.t), 0);
yyval.ttype = make_call_declarator (yyval.ttype, yyvsp[-1].ftype.t, NULL_TREE, NULL_TREE);
check_for_new_type ("cast", yyvsp[-1].ftype); ;
break;}
-case 248:
-#line 1200 "parse.y"
+case 250:
+#line 1226 "parse.y"
{ yyval.ttype = reparse_absdcl_as_casts (yyval.ttype, yyvsp[0].ttype); ;
break;}
-case 249:
-#line 1202 "parse.y"
+case 251:
+#line 1228 "parse.y"
{
tree init = build_nt (CONSTRUCTOR, NULL_TREE,
nreverse (yyvsp[-2].ttype));
@@ -5070,162 +5126,179 @@ case 249:
yyval.ttype = reparse_absdcl_as_casts (yyval.ttype, init);
;
break;}
-case 251:
-#line 1218 "parse.y"
-{ yyval.ttype = build_x_binary_op (MEMBER_REF, yyval.ttype, yyvsp[0].ttype); ;
- break;}
-case 252:
-#line 1220 "parse.y"
-{ yyval.ttype = build_m_component_ref (yyval.ttype, yyvsp[0].ttype); ;
- break;}
case 253:
-#line 1222 "parse.y"
-{ yyval.ttype = build_x_binary_op (yyvsp[-1].code, yyval.ttype, yyvsp[0].ttype); ;
+#line 1244 "parse.y"
+{ yyval.ttype = build_x_binary_op (MEMBER_REF, yyval.ttype, yyvsp[0].ttype); ;
break;}
case 254:
-#line 1224 "parse.y"
-{ yyval.ttype = build_x_binary_op (yyvsp[-1].code, yyval.ttype, yyvsp[0].ttype); ;
+#line 1246 "parse.y"
+{ yyval.ttype = build_m_component_ref (yyval.ttype, yyvsp[0].ttype); ;
break;}
case 255:
-#line 1226 "parse.y"
+#line 1248 "parse.y"
{ yyval.ttype = build_x_binary_op (yyvsp[-1].code, yyval.ttype, yyvsp[0].ttype); ;
break;}
case 256:
-#line 1228 "parse.y"
+#line 1250 "parse.y"
{ yyval.ttype = build_x_binary_op (yyvsp[-1].code, yyval.ttype, yyvsp[0].ttype); ;
break;}
case 257:
-#line 1230 "parse.y"
+#line 1252 "parse.y"
{ yyval.ttype = build_x_binary_op (yyvsp[-1].code, yyval.ttype, yyvsp[0].ttype); ;
break;}
case 258:
-#line 1232 "parse.y"
+#line 1254 "parse.y"
{ yyval.ttype = build_x_binary_op (yyvsp[-1].code, yyval.ttype, yyvsp[0].ttype); ;
break;}
case 259:
-#line 1234 "parse.y"
+#line 1256 "parse.y"
{ yyval.ttype = build_x_binary_op (yyvsp[-1].code, yyval.ttype, yyvsp[0].ttype); ;
break;}
case 260:
-#line 1236 "parse.y"
+#line 1258 "parse.y"
{ yyval.ttype = build_x_binary_op (yyvsp[-1].code, yyval.ttype, yyvsp[0].ttype); ;
break;}
case 261:
-#line 1238 "parse.y"
-{ yyval.ttype = build_x_binary_op (LT_EXPR, yyval.ttype, yyvsp[0].ttype); ;
+#line 1260 "parse.y"
+{ yyval.ttype = build_x_binary_op (yyvsp[-1].code, yyval.ttype, yyvsp[0].ttype); ;
break;}
case 262:
-#line 1240 "parse.y"
-{ yyval.ttype = build_x_binary_op (GT_EXPR, yyval.ttype, yyvsp[0].ttype); ;
+#line 1262 "parse.y"
+{ yyval.ttype = build_x_binary_op (yyvsp[-1].code, yyval.ttype, yyvsp[0].ttype); ;
break;}
case 263:
-#line 1242 "parse.y"
-{ yyval.ttype = build_x_binary_op (yyvsp[-1].code, yyval.ttype, yyvsp[0].ttype); ;
+#line 1264 "parse.y"
+{ yyval.ttype = build_x_binary_op (LT_EXPR, yyval.ttype, yyvsp[0].ttype); ;
break;}
case 264:
-#line 1244 "parse.y"
-{ yyval.ttype = build_x_binary_op (yyvsp[-1].code, yyval.ttype, yyvsp[0].ttype); ;
+#line 1266 "parse.y"
+{ yyval.ttype = build_x_binary_op (GT_EXPR, yyval.ttype, yyvsp[0].ttype); ;
break;}
case 265:
-#line 1246 "parse.y"
+#line 1268 "parse.y"
{ yyval.ttype = build_x_binary_op (yyvsp[-1].code, yyval.ttype, yyvsp[0].ttype); ;
break;}
case 266:
-#line 1248 "parse.y"
+#line 1270 "parse.y"
{ yyval.ttype = build_x_binary_op (yyvsp[-1].code, yyval.ttype, yyvsp[0].ttype); ;
break;}
case 267:
-#line 1250 "parse.y"
+#line 1272 "parse.y"
{ yyval.ttype = build_x_binary_op (yyvsp[-1].code, yyval.ttype, yyvsp[0].ttype); ;
break;}
case 268:
-#line 1252 "parse.y"
-{ yyval.ttype = build_x_binary_op (TRUTH_ANDIF_EXPR, yyval.ttype, yyvsp[0].ttype); ;
+#line 1274 "parse.y"
+{ yyval.ttype = build_x_binary_op (yyvsp[-1].code, yyval.ttype, yyvsp[0].ttype); ;
break;}
case 269:
-#line 1254 "parse.y"
-{ yyval.ttype = build_x_binary_op (TRUTH_ORIF_EXPR, yyval.ttype, yyvsp[0].ttype); ;
+#line 1276 "parse.y"
+{ yyval.ttype = build_x_binary_op (yyvsp[-1].code, yyval.ttype, yyvsp[0].ttype); ;
break;}
case 270:
-#line 1256 "parse.y"
-{ yyval.ttype = build_x_conditional_expr (yyval.ttype, yyvsp[-2].ttype, yyvsp[0].ttype); ;
+#line 1278 "parse.y"
+{ yyval.ttype = build_x_binary_op (TRUTH_ANDIF_EXPR, yyval.ttype, yyvsp[0].ttype); ;
break;}
case 271:
-#line 1258 "parse.y"
+#line 1280 "parse.y"
+{ yyval.ttype = build_x_binary_op (TRUTH_ORIF_EXPR, yyval.ttype, yyvsp[0].ttype); ;
+ break;}
+case 272:
+#line 1282 "parse.y"
+{ yyval.ttype = build_x_conditional_expr (yyval.ttype, yyvsp[-2].ttype, yyvsp[0].ttype); ;
+ break;}
+case 273:
+#line 1284 "parse.y"
{ yyval.ttype = build_x_modify_expr (yyval.ttype, NOP_EXPR, yyvsp[0].ttype);
if (yyval.ttype != error_mark_node)
C_SET_EXP_ORIGINAL_CODE (yyval.ttype, MODIFY_EXPR); ;
break;}
-case 272:
-#line 1262 "parse.y"
+case 274:
+#line 1288 "parse.y"
{ yyval.ttype = build_x_modify_expr (yyval.ttype, yyvsp[-1].code, yyvsp[0].ttype); ;
break;}
-case 273:
-#line 1264 "parse.y"
+case 275:
+#line 1290 "parse.y"
{ yyval.ttype = build_throw (NULL_TREE); ;
break;}
-case 274:
-#line 1266 "parse.y"
+case 276:
+#line 1292 "parse.y"
{ yyval.ttype = build_throw (yyvsp[0].ttype); ;
break;}
-case 275:
-#line 1284 "parse.y"
+case 277:
+#line 1310 "parse.y"
{ yyval.ttype = build_parse_node (BIT_NOT_EXPR, yyvsp[0].ttype); ;
break;}
-case 276:
-#line 1286 "parse.y"
+case 278:
+#line 1312 "parse.y"
{ yyval.ttype = build_parse_node (BIT_NOT_EXPR, yyvsp[0].ttype); ;
break;}
-case 282:
-#line 1295 "parse.y"
-{ yyval.ttype = do_identifier (yyvsp[-1].ttype, 1, NULL_TREE); ;
+case 284:
+#line 1321 "parse.y"
+{
+ /* If lastiddecl is a TREE_LIST, it's a baselink, which
+ means that we're in an expression like S::f<int>, so
+ don't do_identifier; we only do that for unqualified
+ identifiers. */
+ if (lastiddecl && TREE_CODE (lastiddecl) != TREE_LIST)
+ yyval.ttype = do_identifier (yyvsp[-1].ttype, 1, NULL_TREE);
+ else
+ yyval.ttype = yyvsp[-1].ttype;
+ ;
break;}
-case 283:
-#line 1299 "parse.y"
+case 285:
+#line 1334 "parse.y"
{ yyval.ttype = lookup_template_function (yyvsp[-2].ttype, yyvsp[-1].ttype); ;
break;}
-case 284:
-#line 1301 "parse.y"
+case 286:
+#line 1336 "parse.y"
{ yyval.ttype = lookup_template_function (yyvsp[-2].ttype, yyvsp[-1].ttype); ;
break;}
-case 285:
-#line 1306 "parse.y"
+case 287:
+#line 1341 "parse.y"
{ yyval.ttype = lookup_template_function (yyvsp[-3].ttype, yyvsp[-1].ttype); ;
break;}
-case 286:
-#line 1308 "parse.y"
+case 288:
+#line 1343 "parse.y"
{ yyval.ttype = lookup_template_function (yyvsp[-3].ttype, yyvsp[-1].ttype); ;
break;}
-case 287:
-#line 1311 "parse.y"
+case 289:
+#line 1346 "parse.y"
{ yyval.ttype = lookup_template_function (yyvsp[-3].ttype, yyvsp[-1].ttype); ;
break;}
-case 292:
-#line 1323 "parse.y"
+case 294:
+#line 1358 "parse.y"
+{
+ /* Provide support for '(' attributes '*' declarator ')'
+ etc */
+ yyval.ttype = decl_tree_cons (yyvsp[-1].ttype, yyvsp[0].ttype, NULL_TREE);
+ ;
+ break;}
+case 296:
+#line 1368 "parse.y"
{ yyval.ttype = build_parse_node (INDIRECT_REF, yyvsp[0].ttype); ;
break;}
-case 293:
-#line 1325 "parse.y"
+case 297:
+#line 1370 "parse.y"
{ yyval.ttype = build_parse_node (ADDR_EXPR, yyvsp[0].ttype); ;
break;}
-case 294:
-#line 1327 "parse.y"
+case 298:
+#line 1372 "parse.y"
{ yyval.ttype = yyvsp[-1].ttype; ;
break;}
-case 295:
-#line 1332 "parse.y"
+case 299:
+#line 1377 "parse.y"
{ yyval.ttype = lookup_template_function (yyvsp[-3].ttype, yyvsp[-1].ttype); ;
break;}
-case 296:
-#line 1334 "parse.y"
+case 300:
+#line 1379 "parse.y"
{ yyval.ttype = lookup_template_function (yyvsp[-3].ttype, yyvsp[-1].ttype); ;
break;}
-case 300:
-#line 1344 "parse.y"
+case 304:
+#line 1389 "parse.y"
{ yyval.ttype = finish_decl_parsing (yyvsp[-1].ttype); ;
break;}
-case 301:
-#line 1349 "parse.y"
+case 305:
+#line 1394 "parse.y"
{
if (TREE_CODE (yyvsp[0].ttype) == BIT_NOT_EXPR)
yyval.ttype = build_x_unary_op (BIT_NOT_EXPR, TREE_OPERAND (yyvsp[0].ttype, 0));
@@ -5233,8 +5306,8 @@ case 301:
yyval.ttype = finish_id_expr (yyvsp[0].ttype);
;
break;}
-case 304:
-#line 1358 "parse.y"
+case 308:
+#line 1403 "parse.y"
{
if (processing_template_decl)
push_obstacks (&permanent_obstack, &permanent_obstack);
@@ -5249,21 +5322,21 @@ case 304:
pop_obstacks ();
;
break;}
-case 305:
-#line 1372 "parse.y"
+case 309:
+#line 1417 "parse.y"
{ yyval.ttype = finish_parenthesized_expr (yyvsp[-1].ttype); ;
break;}
-case 306:
-#line 1374 "parse.y"
+case 310:
+#line 1419 "parse.y"
{ yyvsp[-1].ttype = reparse_decl_as_expr (NULL_TREE, yyvsp[-1].ttype);
yyval.ttype = finish_parenthesized_expr (yyvsp[-1].ttype); ;
break;}
-case 307:
-#line 1377 "parse.y"
+case 311:
+#line 1422 "parse.y"
{ yyval.ttype = error_mark_node; ;
break;}
-case 308:
-#line 1379 "parse.y"
+case 312:
+#line 1424 "parse.y"
{ tree scope = current_scope ();
if (!scope || TREE_CODE (scope) != FUNCTION_DECL)
{
@@ -5275,132 +5348,105 @@ case 308:
yyval.ttype = begin_stmt_expr ();
;
break;}
-case 309:
-#line 1390 "parse.y"
+case 313:
+#line 1435 "parse.y"
{ yyval.ttype = finish_stmt_expr (yyvsp[-2].ttype, yyvsp[-1].ttype); ;
break;}
-case 310:
-#line 1395 "parse.y"
+case 314:
+#line 1440 "parse.y"
{ yyval.ttype = finish_call_expr (yyvsp[-3].ttype, yyvsp[-1].ttype, 1); ;
break;}
-case 311:
-#line 1397 "parse.y"
+case 315:
+#line 1442 "parse.y"
{ yyval.ttype = finish_call_expr (yyvsp[-1].ttype, NULL_TREE, 1); ;
break;}
-case 312:
-#line 1399 "parse.y"
+case 316:
+#line 1444 "parse.y"
{ yyval.ttype = finish_call_expr (yyvsp[-3].ttype, yyvsp[-1].ttype, 0); ;
break;}
-case 313:
-#line 1401 "parse.y"
+case 317:
+#line 1446 "parse.y"
{ yyval.ttype = finish_call_expr (yyvsp[-1].ttype, NULL_TREE, 0); ;
break;}
-case 314:
-#line 1403 "parse.y"
+case 318:
+#line 1448 "parse.y"
{ yyval.ttype = grok_array_decl (yyval.ttype, yyvsp[-1].ttype); ;
break;}
-case 315:
-#line 1405 "parse.y"
+case 319:
+#line 1450 "parse.y"
{ yyval.ttype = finish_increment_expr (yyvsp[-1].ttype, POSTINCREMENT_EXPR); ;
break;}
-case 316:
-#line 1407 "parse.y"
+case 320:
+#line 1452 "parse.y"
{ yyval.ttype = finish_increment_expr (yyvsp[-1].ttype, POSTDECREMENT_EXPR); ;
break;}
-case 317:
-#line 1410 "parse.y"
+case 321:
+#line 1455 "parse.y"
{ yyval.ttype = finish_this_expr (); ;
break;}
-case 318:
-#line 1412 "parse.y"
+case 322:
+#line 1457 "parse.y"
{
- tree type = NULL_TREE;
- tree id = yyval.ttype;
+ /* This is a C cast in C++'s `functional' notation
+ using the "implicit int" extension so that:
+ `const (3)' is equivalent to `const int (3)'. */
+ tree type;
- /* This is a C cast in C++'s `functional' notation. */
if (yyvsp[-1].ttype == error_mark_node)
{
yyval.ttype = error_mark_node;
break;
}
-#if 0
- if (yyvsp[-1].ttype == NULL_TREE)
- {
- error ("cannot cast null list to type `%s'",
- IDENTIFIER_POINTER (TYPE_NAME (id)));
- yyval.ttype = error_mark_node;
- break;
- }
-#endif
-#if 0
- /* type is not set! (mrs) */
- if (type == error_mark_node)
- yyval.ttype = error_mark_node;
- else
-#endif
- {
- if (id == ridpointers[(int) RID_CONST])
- type = build_type_variant (integer_type_node, 1, 0);
- else if (id == ridpointers[(int) RID_VOLATILE])
- type = build_type_variant (integer_type_node, 0, 1);
-#if 0
- /* should not be able to get here (mrs) */
- else if (id == ridpointers[(int) RID_FRIEND])
- {
- error ("cannot cast expression to `friend' type");
- yyval.ttype = error_mark_node;
- break;
- }
-#endif
- else my_friendly_abort (79);
- yyval.ttype = build_c_cast (type, build_compound_expr (yyvsp[-1].ttype));
- }
+
+ type = cp_build_qualified_type (integer_type_node,
+ cp_type_qual_from_rid (yyvsp[-3].ttype));
+ yyval.ttype = build_c_cast (type, build_compound_expr (yyvsp[-1].ttype));
;
break;}
-case 320:
-#line 1457 "parse.y"
+case 324:
+#line 1475 "parse.y"
{ tree type = groktypename (yyvsp[-4].ftype.t);
check_for_new_type ("dynamic_cast", yyvsp[-4].ftype);
yyval.ttype = build_dynamic_cast (type, yyvsp[-1].ttype); ;
break;}
-case 321:
-#line 1461 "parse.y"
+case 325:
+#line 1479 "parse.y"
{ tree type = groktypename (yyvsp[-4].ftype.t);
check_for_new_type ("static_cast", yyvsp[-4].ftype);
yyval.ttype = build_static_cast (type, yyvsp[-1].ttype); ;
break;}
-case 322:
-#line 1465 "parse.y"
+case 326:
+#line 1483 "parse.y"
{ tree type = groktypename (yyvsp[-4].ftype.t);
check_for_new_type ("reinterpret_cast", yyvsp[-4].ftype);
yyval.ttype = build_reinterpret_cast (type, yyvsp[-1].ttype); ;
break;}
-case 323:
-#line 1469 "parse.y"
+case 327:
+#line 1487 "parse.y"
{ tree type = groktypename (yyvsp[-4].ftype.t);
check_for_new_type ("const_cast", yyvsp[-4].ftype);
yyval.ttype = build_const_cast (type, yyvsp[-1].ttype); ;
break;}
-case 324:
-#line 1473 "parse.y"
+case 328:
+#line 1491 "parse.y"
{ yyval.ttype = build_x_typeid (yyvsp[-1].ttype); ;
break;}
-case 325:
-#line 1475 "parse.y"
+case 329:
+#line 1493 "parse.y"
{ tree type = groktypename (yyvsp[-1].ftype.t);
check_for_new_type ("typeid", yyvsp[-1].ftype);
yyval.ttype = get_typeid (TYPE_MAIN_VARIANT (type)); ;
break;}
-case 326:
-#line 1479 "parse.y"
+case 330:
+#line 1497 "parse.y"
{ yyval.ttype = do_scoped_id (yyvsp[0].ttype, 1); ;
break;}
-case 327:
-#line 1481 "parse.y"
+case 331:
+#line 1499 "parse.y"
{ yyval.ttype = yyvsp[0].ttype; ;
break;}
-case 328:
-#line 1483 "parse.y"
+case 332:
+#line 1501 "parse.y"
{
got_scope = NULL_TREE;
if (TREE_CODE (yyvsp[0].ttype) == IDENTIFIER_NODE)
@@ -5409,103 +5455,103 @@ case 328:
yyval.ttype = yyvsp[0].ttype;
;
break;}
-case 329:
-#line 1491 "parse.y"
+case 333:
+#line 1509 "parse.y"
{ yyval.ttype = build_offset_ref (OP0 (yyval.ttype), OP1 (yyval.ttype)); ;
break;}
-case 330:
-#line 1493 "parse.y"
+case 334:
+#line 1511 "parse.y"
{ yyval.ttype = finish_qualified_call_expr (yyvsp[-3].ttype, yyvsp[-1].ttype); ;
break;}
-case 331:
-#line 1495 "parse.y"
+case 335:
+#line 1513 "parse.y"
{ yyval.ttype = finish_qualified_call_expr (yyvsp[-1].ttype, NULL_TREE); ;
break;}
-case 332:
-#line 1497 "parse.y"
+case 336:
+#line 1515 "parse.y"
{
yyval.ttype = build_x_component_ref (yyval.ttype, yyvsp[0].ttype, NULL_TREE, 1);
;
break;}
-case 333:
-#line 1501 "parse.y"
+case 337:
+#line 1519 "parse.y"
{ yyval.ttype = finish_object_call_expr (yyvsp[-3].ttype, yyvsp[-4].ttype, yyvsp[-1].ttype); ;
break;}
-case 334:
-#line 1503 "parse.y"
+case 338:
+#line 1521 "parse.y"
{ yyval.ttype = finish_object_call_expr (yyvsp[-1].ttype, yyvsp[-2].ttype, NULL_TREE); ;
break;}
-case 335:
-#line 1505 "parse.y"
+case 339:
+#line 1523 "parse.y"
{ yyval.ttype = build_x_component_ref (yyval.ttype, yyvsp[0].ttype, NULL_TREE, 1); ;
break;}
-case 336:
-#line 1507 "parse.y"
+case 340:
+#line 1525 "parse.y"
{ if (processing_template_decl)
yyval.ttype = build_min_nt (COMPONENT_REF, yyvsp[-1].ttype, copy_to_permanent (yyvsp[0].ttype));
else
yyval.ttype = build_object_ref (yyval.ttype, OP0 (yyvsp[0].ttype), OP1 (yyvsp[0].ttype)); ;
break;}
-case 337:
-#line 1512 "parse.y"
+case 341:
+#line 1530 "parse.y"
{ yyval.ttype = finish_object_call_expr (yyvsp[-3].ttype, yyvsp[-4].ttype, yyvsp[-1].ttype); ;
break;}
-case 338:
-#line 1514 "parse.y"
+case 342:
+#line 1532 "parse.y"
{ yyval.ttype = finish_object_call_expr (yyvsp[-1].ttype, yyvsp[-2].ttype, NULL_TREE); ;
break;}
-case 339:
-#line 1516 "parse.y"
+case 343:
+#line 1534 "parse.y"
{ yyval.ttype = finish_qualified_object_call_expr (yyvsp[-3].ttype, yyvsp[-4].ttype, yyvsp[-1].ttype); ;
break;}
-case 340:
-#line 1518 "parse.y"
+case 344:
+#line 1536 "parse.y"
{ yyval.ttype = finish_qualified_object_call_expr (yyvsp[-1].ttype, yyvsp[-2].ttype, NULL_TREE); ;
break;}
-case 341:
-#line 1521 "parse.y"
+case 345:
+#line 1539 "parse.y"
{ yyval.ttype = finish_pseudo_destructor_call_expr (yyvsp[-3].ttype, NULL_TREE, yyvsp[-1].ttype); ;
break;}
-case 342:
-#line 1523 "parse.y"
+case 346:
+#line 1541 "parse.y"
{ yyval.ttype = finish_pseudo_destructor_call_expr (yyvsp[-5].ttype, yyvsp[-4].ttype, yyvsp[-1].ttype); ;
break;}
-case 343:
-#line 1525 "parse.y"
+case 347:
+#line 1543 "parse.y"
{
yyval.ttype = error_mark_node;
;
break;}
-case 344:
-#line 1570 "parse.y"
+case 348:
+#line 1588 "parse.y"
{ yyval.itype = 0; ;
break;}
-case 345:
-#line 1572 "parse.y"
+case 349:
+#line 1590 "parse.y"
{ got_scope = NULL_TREE; yyval.itype = 1; ;
break;}
-case 346:
-#line 1577 "parse.y"
+case 350:
+#line 1595 "parse.y"
{ yyval.itype = 0; ;
break;}
-case 347:
-#line 1579 "parse.y"
+case 351:
+#line 1597 "parse.y"
{ got_scope = NULL_TREE; yyval.itype = 1; ;
break;}
-case 348:
-#line 1584 "parse.y"
+case 352:
+#line 1602 "parse.y"
{ yyval.ttype = boolean_true_node; ;
break;}
-case 349:
-#line 1586 "parse.y"
+case 353:
+#line 1604 "parse.y"
{ yyval.ttype = boolean_false_node; ;
break;}
-case 351:
-#line 1593 "parse.y"
+case 355:
+#line 1611 "parse.y"
{ yyval.ttype = chainon (yyval.ttype, yyvsp[0].ttype); ;
break;}
-case 352:
-#line 1598 "parse.y"
+case 356:
+#line 1616 "parse.y"
{
if (! current_function_parms_stored)
store_parm_decls ();
@@ -5516,220 +5562,220 @@ case 352:
keep_next_level ();
;
break;}
-case 353:
-#line 1611 "parse.y"
+case 357:
+#line 1629 "parse.y"
{ got_object = TREE_TYPE (yyval.ttype); ;
break;}
-case 354:
-#line 1613 "parse.y"
+case 358:
+#line 1631 "parse.y"
{
yyval.ttype = build_x_arrow (yyval.ttype);
got_object = TREE_TYPE (yyval.ttype);
;
break;}
-case 355:
-#line 1621 "parse.y"
+case 359:
+#line 1639 "parse.y"
{
resume_momentary (yyvsp[-1].itype);
if (yyvsp[-2].ftype.t && IS_AGGR_TYPE_CODE (TREE_CODE (yyvsp[-2].ftype.t)))
note_got_semicolon (yyvsp[-2].ftype.t);
;
break;}
-case 356:
-#line 1627 "parse.y"
+case 360:
+#line 1645 "parse.y"
{
resume_momentary (yyvsp[-1].itype);
note_list_got_semicolon (yyvsp[-2].ftype.t);
;
break;}
-case 357:
-#line 1632 "parse.y"
+case 361:
+#line 1650 "parse.y"
{ resume_momentary (yyvsp[-1].itype); ;
break;}
-case 358:
-#line 1634 "parse.y"
+case 362:
+#line 1652 "parse.y"
{
shadow_tag (yyvsp[-1].ftype.t);
note_list_got_semicolon (yyvsp[-1].ftype.t);
;
break;}
-case 359:
-#line 1639 "parse.y"
+case 363:
+#line 1657 "parse.y"
{ warning ("empty declaration"); ;
break;}
-case 360:
-#line 1641 "parse.y"
+case 364:
+#line 1659 "parse.y"
{ pedantic = yyvsp[-1].itype; ;
break;}
-case 363:
-#line 1655 "parse.y"
+case 367:
+#line 1673 "parse.y"
{ yyval.ttype = make_call_declarator (NULL_TREE, empty_parms (),
NULL_TREE, NULL_TREE); ;
break;}
-case 364:
-#line 1658 "parse.y"
+case 368:
+#line 1676 "parse.y"
{ yyval.ttype = make_call_declarator (yyval.ttype, empty_parms (), NULL_TREE,
NULL_TREE); ;
break;}
-case 365:
-#line 1665 "parse.y"
+case 369:
+#line 1683 "parse.y"
{ yyval.ftype.t = build_decl_list (yyvsp[-1].ftype.t, yyvsp[0].ttype);
yyval.ftype.new_type_flag = yyvsp[-1].ftype.new_type_flag; ;
break;}
-case 366:
-#line 1668 "parse.y"
+case 370:
+#line 1686 "parse.y"
{ yyval.ftype.t = build_decl_list (yyvsp[-1].ftype.t, yyvsp[0].ttype);
yyval.ftype.new_type_flag = yyvsp[-1].ftype.new_type_flag; ;
break;}
-case 367:
-#line 1671 "parse.y"
+case 371:
+#line 1689 "parse.y"
{ yyval.ftype.t = build_decl_list (get_decl_list (yyvsp[-1].ftype.t), yyvsp[0].ttype);
yyval.ftype.new_type_flag = yyvsp[-1].ftype.new_type_flag; ;
break;}
-case 368:
-#line 1674 "parse.y"
+case 372:
+#line 1692 "parse.y"
{ yyval.ftype.t = build_decl_list (yyvsp[0].ftype.t, NULL_TREE);
yyval.ftype.new_type_flag = yyvsp[0].ftype.new_type_flag; ;
break;}
-case 369:
-#line 1677 "parse.y"
+case 373:
+#line 1695 "parse.y"
{ yyval.ftype.t = build_decl_list (yyvsp[0].ftype.t, NULL_TREE);
yyval.ftype.new_type_flag = yyvsp[0].ftype.new_type_flag; ;
break;}
-case 372:
-#line 1693 "parse.y"
+case 376:
+#line 1711 "parse.y"
{ yyval.ftype.t = decl_tree_cons (NULL_TREE, yyvsp[0].ftype.t, yyvsp[-1].ttype);
yyval.ftype.new_type_flag = yyvsp[0].ftype.new_type_flag; ;
break;}
-case 373:
-#line 1696 "parse.y"
+case 377:
+#line 1714 "parse.y"
{ yyval.ftype.t = decl_tree_cons (NULL_TREE, yyvsp[-1].ftype.t, yyvsp[0].ttype);
yyval.ftype.new_type_flag = yyvsp[-1].ftype.new_type_flag; ;
break;}
-case 374:
-#line 1699 "parse.y"
+case 378:
+#line 1717 "parse.y"
{ yyval.ftype.t = decl_tree_cons (NULL_TREE, yyvsp[-2].ftype.t, chainon (yyvsp[-1].ttype, yyvsp[0].ttype));
yyval.ftype.new_type_flag = yyvsp[-2].ftype.new_type_flag; ;
break;}
-case 375:
-#line 1702 "parse.y"
+case 379:
+#line 1720 "parse.y"
{ yyval.ftype.t = decl_tree_cons (NULL_TREE, yyvsp[-1].ftype.t, chainon (yyvsp[0].ttype, yyvsp[-2].ttype));
yyval.ftype.new_type_flag = yyvsp[-1].ftype.new_type_flag; ;
break;}
-case 376:
-#line 1705 "parse.y"
+case 380:
+#line 1723 "parse.y"
{ yyval.ftype.t = decl_tree_cons (NULL_TREE, yyvsp[-1].ftype.t, chainon (yyvsp[0].ttype, yyvsp[-2].ttype));
yyval.ftype.new_type_flag = yyvsp[-1].ftype.new_type_flag; ;
break;}
-case 377:
-#line 1708 "parse.y"
+case 381:
+#line 1726 "parse.y"
{ yyval.ftype.t = decl_tree_cons (NULL_TREE, yyvsp[-2].ftype.t,
chainon (yyvsp[-1].ttype, chainon (yyvsp[0].ttype, yyvsp[-3].ttype)));
yyval.ftype.new_type_flag = yyvsp[-2].ftype.new_type_flag; ;
break;}
-case 378:
-#line 1715 "parse.y"
+case 382:
+#line 1733 "parse.y"
{ if (extra_warnings)
warning ("`%s' is not at beginning of declaration",
IDENTIFIER_POINTER (yyval.ttype));
yyval.ttype = build_decl_list (NULL_TREE, yyval.ttype); ;
break;}
-case 379:
-#line 1720 "parse.y"
+case 383:
+#line 1738 "parse.y"
{ yyval.ttype = decl_tree_cons (NULL_TREE, yyvsp[0].ftype.t, yyval.ttype); ;
break;}
-case 380:
-#line 1722 "parse.y"
+case 384:
+#line 1740 "parse.y"
{ if (extra_warnings)
warning ("`%s' is not at beginning of declaration",
IDENTIFIER_POINTER (yyvsp[0].ttype));
yyval.ttype = decl_tree_cons (NULL_TREE, yyvsp[0].ttype, yyval.ttype); ;
break;}
-case 381:
-#line 1727 "parse.y"
+case 385:
+#line 1745 "parse.y"
{ yyval.ttype = decl_tree_cons (yyvsp[0].ttype, NULL_TREE, yyvsp[-1].ttype); ;
break;}
-case 382:
-#line 1729 "parse.y"
+case 386:
+#line 1747 "parse.y"
{ yyval.ttype = decl_tree_cons (yyvsp[0].ttype, NULL_TREE, NULL_TREE); ;
break;}
-case 383:
-#line 1739 "parse.y"
+case 387:
+#line 1757 "parse.y"
{ yyval.ttype = yyvsp[0].ftype.t; TREE_STATIC (yyval.ttype) = 1; ;
break;}
-case 384:
-#line 1741 "parse.y"
+case 388:
+#line 1759 "parse.y"
{ yyval.ttype = IDENTIFIER_AS_LIST (yyval.ttype); ;
break;}
-case 385:
-#line 1743 "parse.y"
+case 389:
+#line 1761 "parse.y"
{ yyval.ttype = decl_tree_cons (NULL_TREE, yyvsp[0].ttype, yyval.ttype);
TREE_STATIC (yyval.ttype) = 1; ;
break;}
-case 386:
-#line 1746 "parse.y"
+case 390:
+#line 1764 "parse.y"
{ if (extra_warnings && TREE_STATIC (yyval.ttype))
warning ("`%s' is not at beginning of declaration",
IDENTIFIER_POINTER (yyvsp[0].ttype));
yyval.ttype = decl_tree_cons (NULL_TREE, yyvsp[0].ttype, yyval.ttype);
TREE_STATIC (yyval.ttype) = TREE_STATIC (yyvsp[-1].ttype); ;
break;}
-case 387:
-#line 1752 "parse.y"
+case 391:
+#line 1770 "parse.y"
{ yyval.ttype = decl_tree_cons (yyvsp[0].ttype, NULL_TREE, yyvsp[-1].ttype); ;
break;}
-case 388:
-#line 1754 "parse.y"
+case 392:
+#line 1772 "parse.y"
{ yyval.ttype = decl_tree_cons (yyvsp[0].ttype, NULL_TREE, NULL_TREE); ;
break;}
-case 389:
-#line 1765 "parse.y"
+case 393:
+#line 1783 "parse.y"
{ yyval.ftype.t = get_decl_list (yyvsp[0].ftype.t);
yyval.ftype.new_type_flag = yyvsp[0].ftype.new_type_flag; ;
break;}
-case 390:
-#line 1768 "parse.y"
+case 394:
+#line 1786 "parse.y"
{ yyval.ftype.t = decl_tree_cons (NULL_TREE, yyvsp[0].ftype.t, yyvsp[-1].ftype.t);
yyval.ftype.new_type_flag = yyvsp[0].ftype.new_type_flag; ;
break;}
-case 391:
-#line 1771 "parse.y"
+case 395:
+#line 1789 "parse.y"
{ yyval.ftype.t = decl_tree_cons (NULL_TREE, yyvsp[-1].ftype.t, yyvsp[0].ttype);
yyval.ftype.new_type_flag = yyvsp[-1].ftype.new_type_flag; ;
break;}
-case 392:
-#line 1774 "parse.y"
+case 396:
+#line 1792 "parse.y"
{ yyval.ftype.t = decl_tree_cons (NULL_TREE, yyvsp[-1].ftype.t, chainon (yyvsp[0].ttype, yyvsp[-2].ftype.t));
yyval.ftype.new_type_flag = yyvsp[-2].ftype.new_type_flag; ;
break;}
-case 393:
-#line 1780 "parse.y"
+case 397:
+#line 1798 "parse.y"
{ yyval.ttype = build_decl_list (NULL_TREE, yyvsp[0].ftype.t); ;
break;}
-case 394:
-#line 1782 "parse.y"
+case 398:
+#line 1800 "parse.y"
{ yyval.ttype = decl_tree_cons (NULL_TREE, yyvsp[0].ftype.t, yyvsp[-1].ttype); ;
break;}
-case 396:
-#line 1792 "parse.y"
+case 400:
+#line 1810 "parse.y"
{ yyval.ftype.t = yyvsp[0].ttype; yyval.ftype.new_type_flag = 0; ;
break;}
-case 397:
-#line 1794 "parse.y"
+case 401:
+#line 1812 "parse.y"
{ yyval.ftype.t = yyvsp[0].ttype; yyval.ftype.new_type_flag = 0; ;
break;}
-case 398:
-#line 1796 "parse.y"
-{ yyval.ftype.t = TREE_TYPE (yyvsp[-1].ttype);
+case 402:
+#line 1814 "parse.y"
+{ yyval.ftype.t = finish_typeof (yyvsp[-1].ttype);
yyval.ftype.new_type_flag = 0; ;
break;}
-case 399:
-#line 1799 "parse.y"
+case 403:
+#line 1817 "parse.y"
{ yyval.ftype.t = groktypename (yyvsp[-1].ftype.t);
yyval.ftype.new_type_flag = 0; ;
break;}
-case 400:
-#line 1802 "parse.y"
+case 404:
+#line 1820 "parse.y"
{ tree type = TREE_TYPE (yyvsp[-1].ttype);
yyval.ftype.new_type_flag = 0;
@@ -5745,8 +5791,8 @@ case 400:
}
;
break;}
-case 401:
-#line 1817 "parse.y"
+case 405:
+#line 1835 "parse.y"
{ tree type = groktypename (yyvsp[-1].ftype.t);
yyval.ftype.new_type_flag = 0;
@@ -5762,240 +5808,245 @@ case 401:
}
;
break;}
-case 402:
-#line 1837 "parse.y"
+case 406:
+#line 1855 "parse.y"
{ yyval.ftype.t = yyvsp[0].ttype; yyval.ftype.new_type_flag = 0; ;
break;}
-case 403:
-#line 1839 "parse.y"
+case 407:
+#line 1857 "parse.y"
{ yyval.ftype.t = yyvsp[0].ttype; yyval.ftype.new_type_flag = 0; ;
break;}
-case 406:
-#line 1846 "parse.y"
+case 410:
+#line 1864 "parse.y"
{ check_multiple_declarators (); ;
break;}
-case 408:
-#line 1852 "parse.y"
+case 412:
+#line 1870 "parse.y"
{ check_multiple_declarators (); ;
break;}
-case 410:
-#line 1858 "parse.y"
+case 414:
+#line 1876 "parse.y"
{ check_multiple_declarators (); ;
break;}
-case 411:
-#line 1863 "parse.y"
+case 415:
+#line 1881 "parse.y"
{ yyval.ttype = NULL_TREE; ;
break;}
-case 412:
-#line 1865 "parse.y"
+case 416:
+#line 1883 "parse.y"
{ if (TREE_CHAIN (yyvsp[-1].ttype)) yyvsp[-1].ttype = combine_strings (yyvsp[-1].ttype); yyval.ttype = yyvsp[-1].ttype; ;
break;}
-case 413:
-#line 1870 "parse.y"
+case 417:
+#line 1888 "parse.y"
{ yyval.ttype = start_decl (yyvsp[-3].ttype, current_declspecs, 1,
yyvsp[-1].ttype, prefix_attributes); ;
break;}
-case 414:
-#line 1874 "parse.y"
+case 418:
+#line 1892 "parse.y"
{ cp_finish_decl (yyvsp[-1].ttype, yyvsp[0].ttype, yyvsp[-4].ttype, 1, LOOKUP_ONLYCONVERTING); ;
break;}
-case 415:
-#line 1876 "parse.y"
+case 419:
+#line 1894 "parse.y"
{ yyval.ttype = start_decl (yyvsp[-2].ttype, current_declspecs, 0,
yyvsp[0].ttype, prefix_attributes);
cp_finish_decl (yyval.ttype, NULL_TREE, yyvsp[-1].ttype, 1, 0); ;
break;}
-case 416:
-#line 1889 "parse.y"
+case 420:
+#line 1907 "parse.y"
{ yyvsp[0].itype = parse_decl (yyvsp[-3].ttype, yyvsp[-4].ttype,
yyvsp[-1].ttype, 1, &yyval.ttype); ;
break;}
-case 417:
-#line 1894 "parse.y"
+case 421:
+#line 1912 "parse.y"
{ cp_finish_decl (yyvsp[-1].ttype, yyvsp[0].ttype, yyvsp[-4].ttype, 1,
LOOKUP_ONLYCONVERTING);
yyval.itype = yyvsp[-2].itype; ;
break;}
-case 418:
-#line 1898 "parse.y"
+case 422:
+#line 1916 "parse.y"
{ tree d;
yyval.itype = parse_decl (yyvsp[-2].ttype, yyvsp[-3].ttype, yyvsp[0].ttype, 0, &d);
cp_finish_decl (d, NULL_TREE, yyvsp[-1].ttype, 1, 0); ;
break;}
-case 419:
-#line 1905 "parse.y"
+case 423:
+#line 1923 "parse.y"
{ yyval.itype = yyvsp[0].itype; ;
break;}
-case 420:
-#line 1909 "parse.y"
+case 424:
+#line 1927 "parse.y"
{ yyval.itype = yyvsp[0].itype; ;
break;}
-case 421:
-#line 1914 "parse.y"
+case 425:
+#line 1932 "parse.y"
{ /* Set things up as initdcl0_innards expects. */
yyvsp[0].ttype = yyvsp[-1].ttype;
yyvsp[-1].ttype = NULL_TREE; ;
break;}
-case 422:
-#line 1918 "parse.y"
+case 426:
+#line 1936 "parse.y"
{;
break;}
-case 423:
-#line 1920 "parse.y"
+case 427:
+#line 1938 "parse.y"
{ tree d;
parse_decl(yyvsp[-2].ttype, NULL_TREE, yyvsp[0].ttype, 0, &d);
cp_finish_decl (d, NULL_TREE, yyvsp[-1].ttype, 1, 0); ;
break;}
-case 424:
-#line 1929 "parse.y"
+case 428:
+#line 1947 "parse.y"
{ yyval.ttype = NULL_TREE; ;
break;}
-case 425:
-#line 1931 "parse.y"
+case 429:
+#line 1949 "parse.y"
{ yyval.ttype = yyvsp[0].ttype; ;
break;}
-case 426:
-#line 1936 "parse.y"
+case 430:
+#line 1954 "parse.y"
{ yyval.ttype = yyvsp[0].ttype; ;
break;}
-case 427:
-#line 1938 "parse.y"
+case 431:
+#line 1956 "parse.y"
{ yyval.ttype = chainon (yyvsp[-1].ttype, yyvsp[0].ttype); ;
break;}
-case 428:
-#line 1943 "parse.y"
+case 432:
+#line 1961 "parse.y"
{ yyval.ttype = yyvsp[-2].ttype; ;
break;}
-case 429:
-#line 1948 "parse.y"
+case 433:
+#line 1966 "parse.y"
{ yyval.ttype = yyvsp[0].ttype; ;
break;}
-case 430:
-#line 1950 "parse.y"
+case 434:
+#line 1968 "parse.y"
{ yyval.ttype = chainon (yyvsp[-2].ttype, yyvsp[0].ttype); ;
break;}
-case 431:
-#line 1955 "parse.y"
+case 435:
+#line 1973 "parse.y"
{ yyval.ttype = NULL_TREE; ;
break;}
-case 432:
-#line 1957 "parse.y"
+case 436:
+#line 1975 "parse.y"
{ yyval.ttype = build_tree_list (yyvsp[0].ttype, NULL_TREE); ;
break;}
-case 433:
-#line 1959 "parse.y"
+case 437:
+#line 1977 "parse.y"
{ yyval.ttype = build_tree_list (yyvsp[-3].ttype, build_tree_list (NULL_TREE, yyvsp[-1].ttype)); ;
break;}
-case 434:
-#line 1961 "parse.y"
+case 438:
+#line 1979 "parse.y"
{ yyval.ttype = build_tree_list (yyvsp[-5].ttype, tree_cons (NULL_TREE, yyvsp[-3].ttype, yyvsp[-1].ttype)); ;
break;}
-case 435:
-#line 1963 "parse.y"
+case 439:
+#line 1981 "parse.y"
{ yyval.ttype = build_tree_list (yyvsp[-3].ttype, yyvsp[-1].ttype); ;
break;}
-case 440:
-#line 1979 "parse.y"
+case 444:
+#line 1997 "parse.y"
{ yyval.ttype = build_tree_list (NULL_TREE, yyvsp[0].ttype); ;
break;}
-case 441:
-#line 1981 "parse.y"
+case 445:
+#line 1999 "parse.y"
{ yyval.ttype = chainon (yyvsp[-2].ttype, build_tree_list (NULL_TREE, yyvsp[0].ttype)); ;
break;}
-case 442:
-#line 1986 "parse.y"
+case 446:
+#line 2004 "parse.y"
{ yyval.ttype = NULL_TREE; ;
break;}
-case 443:
-#line 1988 "parse.y"
+case 447:
+#line 2006 "parse.y"
{ yyval.ttype = yyvsp[0].ttype; ;
break;}
-case 445:
-#line 1996 "parse.y"
+case 449:
+#line 2014 "parse.y"
{ yyval.ttype = build_nt (CONSTRUCTOR, NULL_TREE, NULL_TREE);
TREE_HAS_CONSTRUCTOR (yyval.ttype) = 1; ;
break;}
-case 446:
-#line 1999 "parse.y"
+case 450:
+#line 2017 "parse.y"
{ yyval.ttype = build_nt (CONSTRUCTOR, NULL_TREE, nreverse (yyvsp[-1].ttype));
TREE_HAS_CONSTRUCTOR (yyval.ttype) = 1; ;
break;}
-case 447:
-#line 2002 "parse.y"
+case 451:
+#line 2020 "parse.y"
{ yyval.ttype = build_nt (CONSTRUCTOR, NULL_TREE, nreverse (yyvsp[-2].ttype));
TREE_HAS_CONSTRUCTOR (yyval.ttype) = 1; ;
break;}
-case 448:
-#line 2005 "parse.y"
+case 452:
+#line 2023 "parse.y"
{ yyval.ttype = NULL_TREE; ;
break;}
-case 449:
-#line 2012 "parse.y"
+case 453:
+#line 2030 "parse.y"
{ yyval.ttype = build_tree_list (NULL_TREE, yyval.ttype); ;
break;}
-case 450:
-#line 2014 "parse.y"
+case 454:
+#line 2032 "parse.y"
{ yyval.ttype = expr_tree_cons (NULL_TREE, yyvsp[0].ttype, yyval.ttype); ;
break;}
-case 451:
-#line 2017 "parse.y"
+case 455:
+#line 2035 "parse.y"
{ yyval.ttype = build_expr_list (yyvsp[-2].ttype, yyvsp[0].ttype); ;
break;}
-case 452:
-#line 2019 "parse.y"
+case 456:
+#line 2037 "parse.y"
{ yyval.ttype = build_expr_list (yyval.ttype, yyvsp[0].ttype); ;
break;}
-case 453:
-#line 2021 "parse.y"
+case 457:
+#line 2039 "parse.y"
{ yyval.ttype = expr_tree_cons (yyvsp[-2].ttype, yyvsp[0].ttype, yyval.ttype); ;
break;}
-case 454:
-#line 2026 "parse.y"
+case 458:
+#line 2044 "parse.y"
{ start_function (NULL_TREE, TREE_VALUE (yyvsp[0].ttype),
- NULL_TREE, 1);
+ NULL_TREE, 2);
reinit_parse_for_function (); ;
break;}
-case 455:
-#line 2032 "parse.y"
+case 459:
+#line 2050 "parse.y"
{
int nested = (hack_decl_function_context
(current_function_decl) != NULL_TREE);
- finish_function (lineno, (int)yyvsp[-1].itype, nested);
+ finish_function (lineno, (int)yyvsp[-1].itype | 2, nested);
process_next_inline (yyvsp[-3].ttype);
;
break;}
-case 456:
-#line 2039 "parse.y"
-{ process_next_inline (yyvsp[-2].ttype); ;
+case 460:
+#line 2057 "parse.y"
+{
+ int nested = (hack_decl_function_context
+ (current_function_decl) != NULL_TREE);
+ finish_function (lineno, (int)yyvsp[0].itype | 2, nested);
+ process_next_inline (yyvsp[-2].ttype);
+ ;
break;}
-case 457:
-#line 2041 "parse.y"
+case 461:
+#line 2064 "parse.y"
{ process_next_inline (yyvsp[-2].ttype); ;
break;}
-case 460:
-#line 2053 "parse.y"
+case 464:
+#line 2076 "parse.y"
{ replace_defarg (yyvsp[-2].ttype, yyvsp[-1].ttype); ;
break;}
-case 461:
-#line 2055 "parse.y"
+case 465:
+#line 2078 "parse.y"
{ replace_defarg (yyvsp[-2].ttype, error_mark_node); ;
break;}
-case 463:
-#line 2060 "parse.y"
+case 467:
+#line 2083 "parse.y"
{ do_pending_defargs (); ;
break;}
-case 464:
-#line 2062 "parse.y"
+case 468:
+#line 2085 "parse.y"
{ do_pending_defargs (); ;
break;}
-case 465:
-#line 2067 "parse.y"
+case 469:
+#line 2090 "parse.y"
{ yyvsp[0].itype = suspend_momentary ();
yyval.ttype = current_enum_type;
current_enum_type = start_enum (yyvsp[-1].ttype); ;
break;}
-case 466:
-#line 2071 "parse.y"
+case 470:
+#line 2094 "parse.y"
{ TYPE_VALUES (current_enum_type) = yyvsp[-2].ttype;
yyval.ftype.t = finish_enum (current_enum_type);
yyval.ftype.new_type_flag = 1;
@@ -6003,52 +6054,52 @@ case 466:
resume_momentary ((int) yyvsp[-4].itype);
check_for_missing_semicolon (yyval.ftype.t); ;
break;}
-case 467:
-#line 2078 "parse.y"
+case 471:
+#line 2101 "parse.y"
{ yyval.ftype.t = finish_enum (start_enum (yyvsp[-2].ttype));
yyval.ftype.new_type_flag = 1;
check_for_missing_semicolon (yyval.ftype.t); ;
break;}
-case 468:
-#line 2082 "parse.y"
+case 472:
+#line 2105 "parse.y"
{ yyvsp[0].itype = suspend_momentary ();
yyval.ttype = current_enum_type;
current_enum_type = start_enum (make_anon_name ()); ;
break;}
-case 469:
-#line 2086 "parse.y"
+case 473:
+#line 2109 "parse.y"
{ TYPE_VALUES (current_enum_type) = yyvsp[-2].ttype;
yyval.ftype.t = finish_enum (current_enum_type);
yyval.ftype.new_type_flag = 1;
- current_enum_type = yyvsp[-2].ttype;
+ current_enum_type = yyvsp[-3].ttype;
resume_momentary ((int) yyvsp[-5].itype);
check_for_missing_semicolon (yyval.ftype.t); ;
break;}
-case 470:
-#line 2093 "parse.y"
+case 474:
+#line 2116 "parse.y"
{ yyval.ftype.t = finish_enum (start_enum (make_anon_name()));
yyval.ftype.new_type_flag = 1;
check_for_missing_semicolon (yyval.ftype.t); ;
break;}
-case 471:
-#line 2097 "parse.y"
+case 475:
+#line 2120 "parse.y"
{ yyval.ftype.t = xref_tag (enum_type_node, yyvsp[0].ttype, 1);
yyval.ftype.new_type_flag = 0; ;
break;}
-case 472:
-#line 2100 "parse.y"
+case 476:
+#line 2123 "parse.y"
{ yyval.ftype.t = xref_tag (enum_type_node, yyvsp[0].ttype, 1);
yyval.ftype.new_type_flag = 0; ;
break;}
-case 473:
-#line 2103 "parse.y"
+case 477:
+#line 2126 "parse.y"
{ yyval.ftype.t = yyvsp[0].ttype;
yyval.ftype.new_type_flag = 0;
if (!processing_template_decl)
cp_pedwarn ("using `typename' outside of template"); ;
break;}
-case 474:
-#line 2110 "parse.y"
+case 478:
+#line 2133 "parse.y"
{
int semi;
@@ -6059,18 +6110,18 @@ case 474:
yyval.ttype = finish_class_definition (yyvsp[-4].ttype, yyvsp[0].ttype, semi);
;
break;}
-case 475:
-#line 2120 "parse.y"
+case 479:
+#line 2143 "parse.y"
{ finish_default_args (); ;
break;}
-case 476:
-#line 2122 "parse.y"
+case 480:
+#line 2145 "parse.y"
{ yyval.ftype.t = yyvsp[-3].ttype;
yyval.ftype.new_type_flag = 1;
begin_inline_definitions (); ;
break;}
-case 477:
-#line 2126 "parse.y"
+case 481:
+#line 2149 "parse.y"
{
yyval.ftype.new_type_flag = 0;
if (TYPE_BINFO (yyvsp[0].ttype) == NULL_TREE)
@@ -6089,151 +6140,167 @@ case 477:
}
;
break;}
-case 481:
-#line 2153 "parse.y"
+case 485:
+#line 2176 "parse.y"
{ if (pedantic && !in_system_header)
pedwarn ("comma at end of enumerator list"); ;
break;}
-case 483:
-#line 2160 "parse.y"
+case 487:
+#line 2183 "parse.y"
{ error ("storage class specifier `%s' not allowed after struct or class", IDENTIFIER_POINTER (yyvsp[0].ttype)); ;
break;}
-case 484:
-#line 2162 "parse.y"
+case 488:
+#line 2185 "parse.y"
{ error ("type specifier `%s' not allowed after struct or class", IDENTIFIER_POINTER (yyvsp[0].ttype)); ;
break;}
-case 485:
-#line 2164 "parse.y"
+case 489:
+#line 2187 "parse.y"
{ error ("type qualifier `%s' not allowed after struct or class", IDENTIFIER_POINTER (yyvsp[0].ttype)); ;
break;}
-case 486:
-#line 2166 "parse.y"
+case 490:
+#line 2189 "parse.y"
{ error ("no body nor ';' separates two class, struct or union declarations"); ;
break;}
-case 487:
-#line 2168 "parse.y"
+case 491:
+#line 2191 "parse.y"
{ yyval.ttype = build_decl_list (yyvsp[0].ttype, yyvsp[-1].ttype); ;
break;}
-case 488:
-#line 2173 "parse.y"
+case 492:
+#line 2196 "parse.y"
{
current_aggr = yyvsp[-1].ttype;
yyval.ttype = yyvsp[0].ttype;
;
break;}
-case 489:
-#line 2181 "parse.y"
+case 493:
+#line 2204 "parse.y"
{ current_aggr = yyval.ttype; yyval.ttype = yyvsp[0].ttype; ;
break;}
-case 490:
-#line 2183 "parse.y"
+case 494:
+#line 2206 "parse.y"
{ yyungetc ('{', 1); ;
break;}
-case 491:
-#line 2185 "parse.y"
+case 495:
+#line 2208 "parse.y"
{ yyungetc (':', 1); ;
break;}
-case 492:
-#line 2190 "parse.y"
+case 496:
+#line 2213 "parse.y"
{
current_aggr = yyvsp[-2].ttype;
yyval.ttype = handle_class_head (yyvsp[-2].ttype, yyvsp[-1].ttype, yyvsp[0].ttype);
;
break;}
-case 493:
-#line 2195 "parse.y"
+case 497:
+#line 2218 "parse.y"
{
current_aggr = yyvsp[-3].ttype;
yyval.ttype = handle_class_head (yyvsp[-3].ttype, yyvsp[-1].ttype, yyvsp[0].ttype);
;
break;}
-case 494:
-#line 2200 "parse.y"
+case 498:
+#line 2223 "parse.y"
{
current_aggr = yyvsp[-2].ttype;
yyval.ttype = handle_class_head (yyvsp[-2].ttype, NULL_TREE, yyvsp[0].ttype);
;
break;}
-case 495:
-#line 2205 "parse.y"
+case 499:
+#line 2228 "parse.y"
{ current_aggr = yyval.ttype; yyval.ttype = yyvsp[0].ttype; ;
break;}
-case 496:
-#line 2207 "parse.y"
+case 500:
+#line 2230 "parse.y"
{ current_aggr = yyval.ttype; yyval.ttype = yyvsp[0].ttype; ;
break;}
-case 497:
-#line 2212 "parse.y"
+case 501:
+#line 2235 "parse.y"
{ yyval.ttype = xref_tag (current_aggr, yyvsp[0].ttype, 1); ;
break;}
-case 498:
-#line 2214 "parse.y"
+case 502:
+#line 2237 "parse.y"
{ yyval.ttype = xref_tag (current_aggr, yyvsp[0].ttype, 0); ;
break;}
-case 499:
-#line 2216 "parse.y"
+case 503:
+#line 2241 "parse.y"
{
yyval.ttype = yyvsp[-1].ttype;
if (yyvsp[0].ttype)
xref_basetypes (current_aggr, yyvsp[-2].ttype, yyvsp[-1].ttype, yyvsp[0].ttype);
;
break;}
-case 500:
-#line 2222 "parse.y"
+case 504:
+#line 2247 "parse.y"
{
- yyval.ttype = TREE_TYPE (yyvsp[-1].ttype);
- if (TREE_INT_CST_LOW (current_aggr) == union_type
- && TREE_CODE (yyval.ttype) != UNION_TYPE)
- cp_pedwarn ("`union' tag used in declaring `%#T'", yyval.ttype);
- else if (TREE_CODE (yyval.ttype) == UNION_TYPE
- && TREE_INT_CST_LOW (current_aggr) != union_type)
- cp_pedwarn ("non-`union' tag used in declaring `%#T'", yyval.ttype);
- if (yyvsp[0].ttype)
+ if (yyvsp[0].ttype != error_mark_node)
+ push_scope (CP_DECL_CONTEXT (yyvsp[0].ttype));
+ ;
+ break;}
+case 505:
+#line 2252 "parse.y"
+{
+ if (yyvsp[-2].ttype != error_mark_node)
{
- maybe_process_partial_specialization (yyval.ttype);
- xref_basetypes (current_aggr, yyvsp[-1].ttype, yyval.ttype, yyvsp[0].ttype);
+ pop_scope (CP_DECL_CONTEXT (yyvsp[-2].ttype));
+ yyval.ttype = TREE_TYPE (yyvsp[-2].ttype);
+ if (current_aggr == union_type_node
+ && TREE_CODE (yyval.ttype) != UNION_TYPE)
+ cp_pedwarn ("`union' tag used in declaring `%#T'", yyval.ttype);
+ else if (TREE_CODE (yyval.ttype) == UNION_TYPE
+ && current_aggr != union_type_node)
+ cp_pedwarn ("non-`union' tag used in declaring `%#T'", yyval.ttype);
+ else if (TREE_CODE (yyval.ttype) == RECORD_TYPE)
+ /* We might be specializing a template with a different
+ class-key; deal. */
+ CLASSTYPE_DECLARED_CLASS (yyval.ttype) = (current_aggr
+ == class_type_node);
+ if (yyvsp[0].ttype)
+ {
+ maybe_process_partial_specialization (yyval.ttype);
+ xref_basetypes (current_aggr, yyvsp[-2].ttype, yyval.ttype, yyvsp[0].ttype);
+ }
}
;
break;}
-case 501:
-#line 2240 "parse.y"
+case 506:
+#line 2279 "parse.y"
{ yyval.ttype = xref_tag (yyval.ttype, make_anon_name (), 0);
yyungetc ('{', 1); ;
break;}
-case 504:
-#line 2251 "parse.y"
+case 509:
+#line 2290 "parse.y"
{ yyval.ttype = NULL_TREE; ;
break;}
-case 505:
-#line 2253 "parse.y"
+case 510:
+#line 2292 "parse.y"
{ yyungetc(':', 1); yyval.ttype = NULL_TREE; ;
break;}
-case 506:
-#line 2255 "parse.y"
+case 511:
+#line 2294 "parse.y"
{ yyval.ttype = yyvsp[0].ttype; ;
break;}
-case 508:
-#line 2261 "parse.y"
+case 513:
+#line 2300 "parse.y"
{ yyval.ttype = chainon (yyval.ttype, yyvsp[0].ttype); ;
break;}
-case 509:
-#line 2266 "parse.y"
+case 514:
+#line 2305 "parse.y"
{ yyval.ttype = finish_base_specifier (access_default_node, yyvsp[0].ttype,
current_aggr
== signature_type_node); ;
break;}
-case 510:
-#line 2270 "parse.y"
+case 515:
+#line 2309 "parse.y"
{ yyval.ttype = finish_base_specifier (yyvsp[-2].ttype, yyvsp[0].ttype,
current_aggr
== signature_type_node); ;
break;}
-case 511:
-#line 2277 "parse.y"
+case 516:
+#line 2316 "parse.y"
{ if (yyval.ttype != error_mark_node) yyval.ttype = TYPE_MAIN_DECL (yyvsp[0].ttype); ;
break;}
-case 513:
-#line 2280 "parse.y"
+case 518:
+#line 2319 "parse.y"
{
if (current_aggr == signature_type_node)
{
@@ -6255,8 +6322,8 @@ case 513:
}
;
break;}
-case 514:
-#line 2301 "parse.y"
+case 519:
+#line 2340 "parse.y"
{
if (current_aggr == signature_type_node)
{
@@ -6278,14 +6345,14 @@ case 514:
}
;
break;}
-case 516:
-#line 2326 "parse.y"
+case 521:
+#line 2365 "parse.y"
{ if (yyvsp[-1].ttype != ridpointers[(int)RID_VIRTUAL])
cp_error ("`%D' access", yyvsp[-1].ttype);
yyval.ttype = access_default_virtual_node; ;
break;}
-case 517:
-#line 2330 "parse.y"
+case 522:
+#line 2369 "parse.y"
{
if (yyvsp[-2].ttype != access_default_virtual_node)
error ("multiple access specifiers");
@@ -6297,8 +6364,8 @@ case 517:
yyval.ttype = access_private_virtual_node;
;
break;}
-case 518:
-#line 2341 "parse.y"
+case 523:
+#line 2380 "parse.y"
{ if (yyvsp[-1].ttype != ridpointers[(int)RID_VIRTUAL])
cp_error ("`%D' access", yyvsp[-1].ttype);
else if (yyval.ttype == access_public_node)
@@ -6311,18 +6378,12 @@ case 518:
error ("multiple `virtual' specifiers");
;
break;}
-case 519:
-#line 2356 "parse.y"
+case 524:
+#line 2395 "parse.y"
{ yyvsp[-1].ttype = begin_class_definition (yyvsp[-1].ttype); ;
break;}
-case 520:
-#line 2361 "parse.y"
-{
- finish_member_declaration (build_self_reference ());
- ;
- break;}
-case 525:
-#line 2375 "parse.y"
+case 529:
+#line 2406 "parse.y"
{
if (current_aggr == signature_type_node)
{
@@ -6333,50 +6394,50 @@ case 525:
current_access_specifier = yyvsp[-1].ttype;
;
break;}
-case 526:
-#line 2390 "parse.y"
+case 530:
+#line 2421 "parse.y"
{
finish_member_declaration (yyvsp[0].ttype);
;
break;}
-case 527:
-#line 2394 "parse.y"
+case 531:
+#line 2425 "parse.y"
{
finish_member_declaration (yyvsp[0].ttype);
;
break;}
-case 529:
-#line 2402 "parse.y"
+case 533:
+#line 2433 "parse.y"
{ error ("missing ';' before right brace");
yyungetc ('}', 0); ;
break;}
-case 530:
-#line 2407 "parse.y"
+case 534:
+#line 2438 "parse.y"
{ yyval.ttype = finish_method (yyval.ttype); ;
break;}
-case 531:
-#line 2409 "parse.y"
+case 535:
+#line 2440 "parse.y"
{ yyval.ttype = finish_method (yyval.ttype); ;
break;}
-case 532:
-#line 2411 "parse.y"
+case 536:
+#line 2442 "parse.y"
{ yyval.ttype = finish_method (yyval.ttype); ;
break;}
-case 533:
-#line 2413 "parse.y"
+case 537:
+#line 2444 "parse.y"
{ yyval.ttype = finish_method (yyval.ttype); ;
break;}
-case 534:
-#line 2415 "parse.y"
+case 538:
+#line 2446 "parse.y"
{ yyval.ttype = NULL_TREE; ;
break;}
-case 535:
-#line 2417 "parse.y"
+case 539:
+#line 2448 "parse.y"
{ yyval.ttype = yyvsp[0].ttype;
pedantic = yyvsp[-1].itype; ;
break;}
-case 536:
-#line 2420 "parse.y"
+case 540:
+#line 2451 "parse.y"
{
if (yyvsp[0].ttype)
yyval.ttype = finish_member_template_decl (yyvsp[0].ttype);
@@ -6387,15 +6448,15 @@ case 536:
finish_template_decl (yyvsp[-1].ttype);
;
break;}
-case 537:
-#line 2430 "parse.y"
+case 541:
+#line 2461 "parse.y"
{
yyval.ttype = finish_member_class_template (yyvsp[-1].ftype.t);
finish_template_decl (yyvsp[-2].ttype);
;
break;}
-case 538:
-#line 2441 "parse.y"
+case 542:
+#line 2472 "parse.y"
{
/* Most of the productions for component_decl only
allow the creation of one new member, so we call
@@ -6417,54 +6478,54 @@ case 538:
yyval.ttype = NULL_TREE;
;
break;}
-case 539:
-#line 2462 "parse.y"
+case 543:
+#line 2493 "parse.y"
{
if (!yyvsp[0].itype)
grok_x_components (yyvsp[-1].ttype);
yyval.ttype = NULL_TREE;
;
break;}
-case 540:
-#line 2468 "parse.y"
+case 544:
+#line 2499 "parse.y"
{ yyval.ttype = grokfield (yyval.ttype, NULL_TREE, yyvsp[0].ttype, yyvsp[-2].ttype,
build_tree_list (yyvsp[-1].ttype, NULL_TREE)); ;
break;}
-case 541:
-#line 2471 "parse.y"
+case 545:
+#line 2502 "parse.y"
{ yyval.ttype = grokfield (yyval.ttype, NULL_TREE, yyvsp[0].ttype, yyvsp[-2].ttype,
build_tree_list (yyvsp[-1].ttype, NULL_TREE)); ;
break;}
-case 542:
-#line 2474 "parse.y"
+case 546:
+#line 2505 "parse.y"
{ yyval.ttype = grokbitfield (NULL_TREE, NULL_TREE, yyvsp[0].ttype); ;
break;}
-case 543:
-#line 2476 "parse.y"
+case 547:
+#line 2507 "parse.y"
{ yyval.ttype = NULL_TREE; ;
break;}
-case 544:
-#line 2487 "parse.y"
+case 548:
+#line 2518 "parse.y"
{ tree specs, attrs;
split_specs_attrs (yyvsp[-4].ttype, &specs, &attrs);
yyval.ttype = grokfield (yyvsp[-3].ttype, specs, yyvsp[0].ttype, yyvsp[-2].ttype,
build_tree_list (yyvsp[-1].ttype, attrs)); ;
break;}
-case 545:
-#line 2492 "parse.y"
+case 549:
+#line 2523 "parse.y"
{ yyval.ttype = grokfield (yyval.ttype, NULL_TREE, yyvsp[0].ttype, yyvsp[-2].ttype,
build_tree_list (yyvsp[-1].ttype, NULL_TREE)); ;
break;}
-case 546:
-#line 2495 "parse.y"
+case 550:
+#line 2526 "parse.y"
{ yyval.ttype = do_class_using_decl (yyvsp[0].ttype); ;
break;}
-case 547:
-#line 2501 "parse.y"
+case 551:
+#line 2532 "parse.y"
{ yyval.itype = 0; ;
break;}
-case 548:
-#line 2503 "parse.y"
+case 552:
+#line 2534 "parse.y"
{
if (PROCESSING_REAL_TEMPLATE_DECL_P ())
yyvsp[0].ttype = finish_member_template_decl (yyvsp[0].ttype);
@@ -6472,8 +6533,8 @@ case 548:
yyval.itype = 1;
;
break;}
-case 549:
-#line 2510 "parse.y"
+case 553:
+#line 2541 "parse.y"
{
check_multiple_declarators ();
if (PROCESSING_REAL_TEMPLATE_DECL_P ())
@@ -6482,12 +6543,12 @@ case 549:
yyval.itype = 2;
;
break;}
-case 550:
-#line 2521 "parse.y"
+case 554:
+#line 2552 "parse.y"
{ yyval.itype = 0; ;
break;}
-case 551:
-#line 2523 "parse.y"
+case 555:
+#line 2554 "parse.y"
{
if (PROCESSING_REAL_TEMPLATE_DECL_P ())
yyvsp[0].ttype = finish_member_template_decl (yyvsp[0].ttype);
@@ -6495,8 +6556,8 @@ case 551:
yyval.itype = 1;
;
break;}
-case 552:
-#line 2530 "parse.y"
+case 556:
+#line 2561 "parse.y"
{
check_multiple_declarators ();
if (PROCESSING_REAL_TEMPLATE_DECL_P ())
@@ -6505,103 +6566,103 @@ case 552:
yyval.itype = 2;
;
break;}
-case 557:
-#line 2551 "parse.y"
+case 561:
+#line 2582 "parse.y"
{ split_specs_attrs (yyvsp[-4].ttype, &current_declspecs,
&prefix_attributes);
yyvsp[-4].ttype = current_declspecs;
yyval.ttype = grokfield (yyval.ttype, current_declspecs, yyvsp[0].ttype, yyvsp[-2].ttype,
build_tree_list (yyvsp[-1].ttype, prefix_attributes)); ;
break;}
-case 558:
-#line 2557 "parse.y"
+case 562:
+#line 2588 "parse.y"
{ split_specs_attrs (yyvsp[-4].ttype, &current_declspecs,
&prefix_attributes);
yyvsp[-4].ttype = current_declspecs;
yyval.ttype = grokbitfield (yyval.ttype, current_declspecs, yyvsp[-1].ttype);
cplus_decl_attributes (yyval.ttype, yyvsp[0].ttype, prefix_attributes); ;
break;}
-case 559:
-#line 2566 "parse.y"
+case 563:
+#line 2597 "parse.y"
{ split_specs_attrs (yyvsp[-4].ttype, &current_declspecs,
&prefix_attributes);
yyvsp[-4].ttype = current_declspecs;
yyval.ttype = grokfield (yyval.ttype, current_declspecs, yyvsp[0].ttype, yyvsp[-2].ttype,
build_tree_list (yyvsp[-1].ttype, prefix_attributes)); ;
break;}
-case 560:
-#line 2572 "parse.y"
+case 564:
+#line 2603 "parse.y"
{ split_specs_attrs (yyvsp[-4].ttype, &current_declspecs,
&prefix_attributes);
yyvsp[-4].ttype = current_declspecs;
yyval.ttype = grokfield (yyval.ttype, current_declspecs, yyvsp[0].ttype, yyvsp[-2].ttype,
build_tree_list (yyvsp[-1].ttype, prefix_attributes)); ;
break;}
-case 561:
-#line 2578 "parse.y"
+case 565:
+#line 2609 "parse.y"
{ split_specs_attrs (yyvsp[-4].ttype, &current_declspecs,
&prefix_attributes);
yyvsp[-4].ttype = current_declspecs;
yyval.ttype = grokbitfield (yyval.ttype, current_declspecs, yyvsp[-1].ttype);
cplus_decl_attributes (yyval.ttype, yyvsp[0].ttype, prefix_attributes); ;
break;}
-case 562:
-#line 2584 "parse.y"
+case 566:
+#line 2615 "parse.y"
{ split_specs_attrs (yyvsp[-3].ttype, &current_declspecs,
&prefix_attributes);
yyvsp[-3].ttype = current_declspecs;
yyval.ttype = grokbitfield (NULL_TREE, current_declspecs, yyvsp[-1].ttype);
cplus_decl_attributes (yyval.ttype, yyvsp[0].ttype, prefix_attributes); ;
break;}
-case 563:
-#line 2593 "parse.y"
+case 567:
+#line 2624 "parse.y"
{ yyval.ttype = grokfield (yyval.ttype, current_declspecs, yyvsp[0].ttype, yyvsp[-2].ttype,
build_tree_list (yyvsp[-1].ttype, prefix_attributes)); ;
break;}
-case 564:
-#line 2596 "parse.y"
+case 568:
+#line 2627 "parse.y"
{ yyval.ttype = grokbitfield (yyval.ttype, current_declspecs, yyvsp[-1].ttype);
cplus_decl_attributes (yyval.ttype, yyvsp[0].ttype, prefix_attributes); ;
break;}
-case 565:
-#line 2602 "parse.y"
+case 569:
+#line 2633 "parse.y"
{ yyval.ttype = grokfield (yyval.ttype, current_declspecs, yyvsp[0].ttype, yyvsp[-2].ttype,
build_tree_list (yyvsp[-1].ttype, prefix_attributes)); ;
break;}
-case 566:
-#line 2605 "parse.y"
+case 570:
+#line 2636 "parse.y"
{ yyval.ttype = grokbitfield (yyval.ttype, current_declspecs, yyvsp[-1].ttype);
cplus_decl_attributes (yyval.ttype, yyvsp[0].ttype, prefix_attributes); ;
break;}
-case 567:
-#line 2608 "parse.y"
+case 571:
+#line 2639 "parse.y"
{ yyval.ttype = grokbitfield (NULL_TREE, current_declspecs, yyvsp[-1].ttype);
cplus_decl_attributes (yyval.ttype, yyvsp[0].ttype, prefix_attributes); ;
break;}
-case 569:
-#line 2619 "parse.y"
+case 573:
+#line 2650 "parse.y"
{ TREE_CHAIN (yyvsp[0].ttype) = yyval.ttype; yyval.ttype = yyvsp[0].ttype; ;
break;}
-case 570:
-#line 2624 "parse.y"
+case 574:
+#line 2655 "parse.y"
{ yyval.ttype = build_enumerator (yyval.ttype, NULL_TREE, current_enum_type); ;
break;}
-case 571:
-#line 2626 "parse.y"
+case 575:
+#line 2657 "parse.y"
{ yyval.ttype = build_enumerator (yyval.ttype, yyvsp[0].ttype, current_enum_type); ;
break;}
-case 572:
-#line 2632 "parse.y"
+case 576:
+#line 2663 "parse.y"
{ yyval.ftype.t = build_decl_list (yyvsp[-1].ftype.t, yyvsp[0].ttype);
yyval.ftype.new_type_flag = yyvsp[-1].ftype.new_type_flag; ;
break;}
-case 573:
-#line 2635 "parse.y"
+case 577:
+#line 2666 "parse.y"
{ yyval.ftype.t = build_decl_list (yyvsp[0].ftype.t, NULL_TREE);
yyval.ftype.new_type_flag = yyvsp[0].ftype.new_type_flag; ;
break;}
-case 574:
-#line 2642 "parse.y"
+case 578:
+#line 2673 "parse.y"
{
if (pedantic)
pedwarn ("ANSI C++ forbids array dimensions with parenthesized type in new");
@@ -6610,72 +6671,72 @@ case 574:
yyval.ftype.new_type_flag = yyvsp[-4].ftype.new_type_flag;
;
break;}
-case 575:
-#line 2653 "parse.y"
+case 579:
+#line 2684 "parse.y"
{ yyval.ttype = NULL_TREE; ;
break;}
-case 576:
-#line 2655 "parse.y"
+case 580:
+#line 2686 "parse.y"
{ yyval.ttype = decl_tree_cons (NULL_TREE, yyvsp[0].ttype, yyval.ttype); ;
break;}
-case 577:
-#line 2660 "parse.y"
+case 581:
+#line 2691 "parse.y"
{ yyval.ftype.t = IDENTIFIER_AS_LIST (yyvsp[0].ttype);
yyval.ftype.new_type_flag = 0; ;
break;}
-case 578:
-#line 2663 "parse.y"
+case 582:
+#line 2694 "parse.y"
{ yyval.ftype.t = decl_tree_cons (NULL_TREE, yyvsp[0].ttype, yyvsp[-1].ftype.t);
yyval.ftype.new_type_flag = yyvsp[-1].ftype.new_type_flag; ;
break;}
-case 579:
-#line 2672 "parse.y"
+case 583:
+#line 2703 "parse.y"
{ yyval.itype = suspend_momentary (); ;
break;}
-case 580:
-#line 2677 "parse.y"
+case 584:
+#line 2708 "parse.y"
{ resume_momentary ((int) yyvsp[-1].itype); yyval.ttype = yyvsp[0].ttype; ;
break;}
-case 581:
-#line 2683 "parse.y"
+case 585:
+#line 2714 "parse.y"
{ resume_momentary ((int) yyvsp[-3].itype); yyval.ttype = yyvsp[-1].ttype; ;
break;}
-case 582:
-#line 2685 "parse.y"
+case 586:
+#line 2716 "parse.y"
{ resume_momentary ((int) yyvsp[-3].itype); yyval.ttype = yyvsp[-1].ttype; ;
break;}
-case 583:
-#line 2687 "parse.y"
+case 587:
+#line 2718 "parse.y"
{ resume_momentary ((int) yyvsp[-1].itype); yyval.ttype = empty_parms (); ;
break;}
-case 584:
-#line 2689 "parse.y"
+case 588:
+#line 2720 "parse.y"
{ resume_momentary ((int) yyvsp[-3].itype); yyval.ttype = NULL_TREE; ;
break;}
-case 585:
-#line 2696 "parse.y"
+case 589:
+#line 2727 "parse.y"
{ yyval.ttype = make_pointer_declarator (yyvsp[-1].ftype.t, yyvsp[0].ttype); ;
break;}
-case 586:
-#line 2698 "parse.y"
+case 590:
+#line 2729 "parse.y"
{ yyval.ttype = make_reference_declarator (yyvsp[-1].ftype.t, yyvsp[0].ttype); ;
break;}
-case 587:
-#line 2700 "parse.y"
+case 591:
+#line 2731 "parse.y"
{ yyval.ttype = make_pointer_declarator (NULL_TREE, yyvsp[0].ttype); ;
break;}
-case 588:
-#line 2702 "parse.y"
+case 592:
+#line 2733 "parse.y"
{ yyval.ttype = make_reference_declarator (NULL_TREE, yyvsp[0].ttype); ;
break;}
-case 589:
-#line 2704 "parse.y"
+case 593:
+#line 2735 "parse.y"
{ tree arg = make_pointer_declarator (yyvsp[-1].ttype, yyvsp[0].ttype);
yyval.ttype = build_parse_node (SCOPE_REF, yyvsp[-2].ttype, arg);
;
break;}
-case 591:
-#line 2712 "parse.y"
+case 595:
+#line 2743 "parse.y"
{
if (TREE_CODE (yyvsp[0].ttype) == IDENTIFIER_NODE)
{
@@ -6693,8 +6754,8 @@ case 591:
yyval.ttype = yyvsp[0].ttype;
;
break;}
-case 592:
-#line 2729 "parse.y"
+case 596:
+#line 2760 "parse.y"
{
if (TREE_CODE (yyvsp[0].ttype) == IDENTIFIER_NODE)
yyval.ttype = IDENTIFIER_GLOBAL_VALUE (yyvsp[0].ttype);
@@ -6703,153 +6764,161 @@ case 592:
got_scope = NULL_TREE;
;
break;}
-case 595:
-#line 2742 "parse.y"
+case 599:
+#line 2773 "parse.y"
{ yyval.ttype = yyvsp[0].ttype; ;
break;}
-case 596:
-#line 2747 "parse.y"
+case 600:
+#line 2778 "parse.y"
{ yyval.ttype = get_type_decl (yyvsp[0].ttype); ;
break;}
-case 597:
-#line 2752 "parse.y"
+case 601:
+#line 2783 "parse.y"
{ yyval.ttype = make_call_declarator (yyval.ttype, yyvsp[-2].ttype, yyvsp[-1].ttype, yyvsp[0].ttype); ;
break;}
-case 598:
-#line 2754 "parse.y"
+case 602:
+#line 2785 "parse.y"
{ yyval.ttype = build_parse_node (ARRAY_REF, yyval.ttype, yyvsp[-1].ttype); ;
break;}
-case 599:
-#line 2756 "parse.y"
+case 603:
+#line 2787 "parse.y"
{ yyval.ttype = build_parse_node (ARRAY_REF, yyval.ttype, NULL_TREE); ;
break;}
-case 600:
-#line 2758 "parse.y"
+case 604:
+#line 2789 "parse.y"
{ yyval.ttype = yyvsp[-1].ttype; ;
break;}
-case 601:
-#line 2760 "parse.y"
+case 605:
+#line 2791 "parse.y"
{ push_nested_class (yyvsp[-1].ttype, 3);
yyval.ttype = build_parse_node (SCOPE_REF, yyval.ttype, yyvsp[0].ttype);
TREE_COMPLEXITY (yyval.ttype) = current_class_depth; ;
break;}
-case 603:
-#line 2771 "parse.y"
+case 608:
+#line 2803 "parse.y"
+{
+ /* Provide support for '(' attributes '*' declarator ')'
+ etc */
+ yyval.ttype = decl_tree_cons (yyvsp[-1].ttype, yyvsp[0].ttype, NULL_TREE);
+ ;
+ break;}
+case 609:
+#line 2812 "parse.y"
{ yyval.ttype = make_pointer_declarator (yyvsp[-1].ftype.t, yyvsp[0].ttype); ;
break;}
-case 604:
-#line 2773 "parse.y"
+case 610:
+#line 2814 "parse.y"
{ yyval.ttype = make_reference_declarator (yyvsp[-1].ftype.t, yyvsp[0].ttype); ;
break;}
-case 605:
-#line 2775 "parse.y"
+case 611:
+#line 2816 "parse.y"
{ yyval.ttype = make_pointer_declarator (NULL_TREE, yyvsp[0].ttype); ;
break;}
-case 606:
-#line 2777 "parse.y"
+case 612:
+#line 2818 "parse.y"
{ yyval.ttype = make_reference_declarator (NULL_TREE, yyvsp[0].ttype); ;
break;}
-case 607:
-#line 2779 "parse.y"
+case 613:
+#line 2820 "parse.y"
{ tree arg = make_pointer_declarator (yyvsp[-1].ttype, yyvsp[0].ttype);
yyval.ttype = build_parse_node (SCOPE_REF, yyvsp[-2].ttype, arg);
;
break;}
-case 609:
-#line 2787 "parse.y"
+case 615:
+#line 2828 "parse.y"
{ yyval.ttype = make_pointer_declarator (yyvsp[-1].ftype.t, yyvsp[0].ttype); ;
break;}
-case 610:
-#line 2789 "parse.y"
+case 616:
+#line 2830 "parse.y"
{ yyval.ttype = make_reference_declarator (yyvsp[-1].ftype.t, yyvsp[0].ttype); ;
break;}
-case 611:
-#line 2791 "parse.y"
+case 617:
+#line 2832 "parse.y"
{ yyval.ttype = make_pointer_declarator (NULL_TREE, yyvsp[0].ttype); ;
break;}
-case 612:
-#line 2793 "parse.y"
+case 618:
+#line 2834 "parse.y"
{ yyval.ttype = make_reference_declarator (NULL_TREE, yyvsp[0].ttype); ;
break;}
-case 613:
-#line 2795 "parse.y"
+case 619:
+#line 2836 "parse.y"
{ tree arg = make_pointer_declarator (yyvsp[-1].ttype, yyvsp[0].ttype);
yyval.ttype = build_parse_node (SCOPE_REF, yyvsp[-2].ttype, arg);
;
break;}
-case 615:
-#line 2803 "parse.y"
+case 621:
+#line 2844 "parse.y"
{ yyval.ttype = make_call_declarator (yyval.ttype, yyvsp[-2].ttype, yyvsp[-1].ttype, yyvsp[0].ttype); ;
break;}
-case 616:
-#line 2805 "parse.y"
+case 622:
+#line 2846 "parse.y"
{ yyval.ttype = yyvsp[-1].ttype; ;
break;}
-case 617:
-#line 2807 "parse.y"
+case 623:
+#line 2848 "parse.y"
{ yyval.ttype = build_parse_node (ARRAY_REF, yyval.ttype, yyvsp[-1].ttype); ;
break;}
-case 618:
-#line 2809 "parse.y"
+case 624:
+#line 2850 "parse.y"
{ yyval.ttype = build_parse_node (ARRAY_REF, yyval.ttype, NULL_TREE); ;
break;}
-case 619:
-#line 2811 "parse.y"
+case 625:
+#line 2852 "parse.y"
{ enter_scope_of (yyvsp[0].ttype); ;
break;}
-case 620:
-#line 2813 "parse.y"
+case 626:
+#line 2854 "parse.y"
{ got_scope = NULL_TREE;
yyval.ttype = build_parse_node (SCOPE_REF, yyvsp[-1].ttype, yyvsp[0].ttype);
enter_scope_of (yyval.ttype);
;
break;}
-case 621:
-#line 2821 "parse.y"
+case 627:
+#line 2862 "parse.y"
{ got_scope = NULL_TREE;
yyval.ttype = build_parse_node (SCOPE_REF, yyval.ttype, yyvsp[0].ttype); ;
break;}
-case 622:
-#line 2824 "parse.y"
+case 628:
+#line 2865 "parse.y"
{ got_scope = NULL_TREE;
yyval.ttype = build_parse_node (SCOPE_REF, yyvsp[-1].ttype, yyvsp[0].ttype); ;
break;}
-case 623:
-#line 2830 "parse.y"
+case 629:
+#line 2871 "parse.y"
{ got_scope = NULL_TREE;
yyval.ttype = build_parse_node (SCOPE_REF, yyval.ttype, yyvsp[0].ttype); ;
break;}
-case 624:
-#line 2833 "parse.y"
+case 630:
+#line 2874 "parse.y"
{ got_scope = NULL_TREE;
yyval.ttype = build_parse_node (SCOPE_REF, yyvsp[-1].ttype, yyvsp[0].ttype); ;
break;}
-case 626:
-#line 2840 "parse.y"
+case 632:
+#line 2881 "parse.y"
{ yyval.ttype = yyvsp[0].ttype; ;
break;}
-case 627:
-#line 2845 "parse.y"
+case 633:
+#line 2886 "parse.y"
{ yyval.ttype = build_functional_cast (yyvsp[-3].ftype.t, yyvsp[-1].ttype); ;
break;}
-case 628:
-#line 2847 "parse.y"
+case 634:
+#line 2888 "parse.y"
{ yyval.ttype = reparse_decl_as_expr (yyvsp[-3].ftype.t, yyvsp[-1].ttype); ;
break;}
-case 629:
-#line 2849 "parse.y"
+case 635:
+#line 2890 "parse.y"
{ yyval.ttype = reparse_absdcl_as_expr (yyvsp[-1].ftype.t, yyvsp[0].ttype); ;
break;}
-case 634:
-#line 2860 "parse.y"
+case 640:
+#line 2901 "parse.y"
{ yyval.ttype = yyvsp[0].ttype; ;
break;}
-case 635:
-#line 2862 "parse.y"
+case 641:
+#line 2903 "parse.y"
{ got_scope = yyval.ttype = make_typename_type (yyvsp[-3].ttype, yyvsp[-1].ttype); ;
break;}
-case 636:
-#line 2869 "parse.y"
+case 642:
+#line 2910 "parse.y"
{
if (TREE_CODE (yyvsp[-1].ttype) == IDENTIFIER_NODE)
{
@@ -6864,32 +6933,32 @@ case 636:
got_scope = yyval.ttype = TYPE_MAIN_VARIANT (TREE_TYPE (yyval.ttype));
;
break;}
-case 637:
-#line 2883 "parse.y"
+case 643:
+#line 2924 "parse.y"
{
if (TREE_CODE (yyvsp[-1].ttype) == IDENTIFIER_NODE)
yyval.ttype = lastiddecl;
got_scope = yyval.ttype = TREE_TYPE (yyval.ttype);
;
break;}
-case 638:
-#line 2889 "parse.y"
+case 644:
+#line 2930 "parse.y"
{
if (TREE_CODE (yyval.ttype) == IDENTIFIER_NODE)
yyval.ttype = lastiddecl;
got_scope = yyval.ttype;
;
break;}
-case 639:
-#line 2895 "parse.y"
+case 645:
+#line 2936 "parse.y"
{ got_scope = yyval.ttype = complete_type (TREE_TYPE (yyvsp[-1].ttype)); ;
break;}
-case 641:
-#line 2911 "parse.y"
+case 647:
+#line 2952 "parse.y"
{ yyval.ttype = yyvsp[0].ttype; ;
break;}
-case 642:
-#line 2916 "parse.y"
+case 648:
+#line 2957 "parse.y"
{
if (TREE_CODE_CLASS (TREE_CODE (yyvsp[-1].ttype)) == 't')
yyval.ttype = make_typename_type (yyvsp[-1].ttype, yyvsp[0].ttype);
@@ -6903,27 +6972,27 @@ case 642:
}
;
break;}
-case 643:
-#line 2929 "parse.y"
+case 649:
+#line 2970 "parse.y"
{ yyval.ttype = TREE_TYPE (yyvsp[0].ttype); ;
break;}
-case 644:
-#line 2931 "parse.y"
+case 650:
+#line 2972 "parse.y"
{ yyval.ttype = make_typename_type (yyvsp[-1].ttype, yyvsp[0].ttype); ;
break;}
-case 645:
-#line 2933 "parse.y"
+case 651:
+#line 2974 "parse.y"
{ yyval.ttype = make_typename_type (yyvsp[-2].ttype, yyvsp[0].ttype); ;
break;}
-case 646:
-#line 2938 "parse.y"
+case 652:
+#line 2979 "parse.y"
{
if (TREE_CODE (yyvsp[0].ttype) == IDENTIFIER_NODE)
cp_error ("`%T' is not a class or namespace", yyvsp[0].ttype);
;
break;}
-case 647:
-#line 2943 "parse.y"
+case 653:
+#line 2984 "parse.y"
{
if (TREE_CODE_CLASS (TREE_CODE (yyvsp[-1].ttype)) == 't')
yyval.ttype = make_typename_type (yyvsp[-1].ttype, yyvsp[0].ttype);
@@ -6937,16 +7006,16 @@ case 647:
}
;
break;}
-case 648:
-#line 2956 "parse.y"
+case 654:
+#line 2997 "parse.y"
{ got_scope = yyval.ttype = make_typename_type (yyvsp[-2].ttype, yyvsp[-1].ttype); ;
break;}
-case 649:
-#line 2958 "parse.y"
+case 655:
+#line 2999 "parse.y"
{ got_scope = yyval.ttype = make_typename_type (yyvsp[-3].ttype, yyvsp[-1].ttype); ;
break;}
-case 650:
-#line 2963 "parse.y"
+case 656:
+#line 3004 "parse.y"
{
if (TREE_CODE (yyvsp[-1].ttype) != IDENTIFIER_NODE)
yyvsp[-1].ttype = lastiddecl;
@@ -6959,32 +7028,32 @@ case 650:
cp_error ("`%T' is not a class or namespace", yyvsp[-1].ttype);
;
break;}
-case 651:
-#line 2975 "parse.y"
+case 657:
+#line 3016 "parse.y"
{
if (TREE_CODE (yyvsp[-1].ttype) != IDENTIFIER_NODE)
yyval.ttype = lastiddecl;
got_scope = yyval.ttype = complete_type (TREE_TYPE (yyval.ttype));
;
break;}
-case 652:
-#line 2981 "parse.y"
+case 658:
+#line 3022 "parse.y"
{ got_scope = yyval.ttype = complete_type (TREE_TYPE (yyval.ttype)); ;
break;}
-case 655:
-#line 2985 "parse.y"
+case 661:
+#line 3026 "parse.y"
{
if (TREE_CODE (yyval.ttype) == IDENTIFIER_NODE)
yyval.ttype = lastiddecl;
got_scope = yyval.ttype;
;
break;}
-case 656:
-#line 2994 "parse.y"
+case 662:
+#line 3035 "parse.y"
{ yyval.ttype = build_min_nt (TEMPLATE_ID_EXPR, yyvsp[-3].ttype, yyvsp[-1].ttype); ;
break;}
-case 657:
-#line 2999 "parse.y"
+case 663:
+#line 3040 "parse.y"
{
if (TREE_CODE (yyvsp[0].ttype) == IDENTIFIER_NODE)
yyval.ttype = IDENTIFIER_GLOBAL_VALUE (yyvsp[0].ttype);
@@ -6993,149 +7062,149 @@ case 657:
got_scope = NULL_TREE;
;
break;}
-case 659:
-#line 3008 "parse.y"
+case 665:
+#line 3049 "parse.y"
{ yyval.ttype = yyvsp[0].ttype; ;
break;}
-case 660:
-#line 3013 "parse.y"
+case 666:
+#line 3054 "parse.y"
{ got_scope = NULL_TREE; ;
break;}
-case 661:
-#line 3015 "parse.y"
+case 667:
+#line 3056 "parse.y"
{ yyval.ttype = yyvsp[-1].ttype; got_scope = NULL_TREE; ;
break;}
-case 662:
-#line 3022 "parse.y"
+case 668:
+#line 3063 "parse.y"
{ got_scope = void_type_node; ;
break;}
-case 663:
-#line 3028 "parse.y"
+case 669:
+#line 3069 "parse.y"
{ yyval.ttype = make_pointer_declarator (yyvsp[-1].ttype, yyvsp[0].ttype); ;
break;}
-case 664:
-#line 3030 "parse.y"
+case 670:
+#line 3071 "parse.y"
{ yyval.ttype = make_pointer_declarator (yyvsp[0].ttype, NULL_TREE); ;
break;}
-case 665:
-#line 3032 "parse.y"
+case 671:
+#line 3073 "parse.y"
{ yyval.ttype = make_reference_declarator (yyvsp[-1].ttype, yyvsp[0].ttype); ;
break;}
-case 666:
-#line 3034 "parse.y"
+case 672:
+#line 3075 "parse.y"
{ yyval.ttype = make_reference_declarator (yyvsp[0].ttype, NULL_TREE); ;
break;}
-case 667:
-#line 3036 "parse.y"
+case 673:
+#line 3077 "parse.y"
{ tree arg = make_pointer_declarator (yyvsp[0].ttype, NULL_TREE);
yyval.ttype = build_parse_node (SCOPE_REF, yyvsp[-1].ttype, arg);
;
break;}
-case 668:
-#line 3040 "parse.y"
+case 674:
+#line 3081 "parse.y"
{ tree arg = make_pointer_declarator (yyvsp[-1].ttype, yyvsp[0].ttype);
yyval.ttype = build_parse_node (SCOPE_REF, yyvsp[-2].ttype, arg);
;
break;}
-case 670:
-#line 3049 "parse.y"
+case 676:
+#line 3090 "parse.y"
{ yyval.ttype = build_parse_node (ARRAY_REF, NULL_TREE, yyvsp[-1].ttype); ;
break;}
-case 671:
-#line 3051 "parse.y"
+case 677:
+#line 3092 "parse.y"
{ yyval.ttype = build_parse_node (ARRAY_REF, yyval.ttype, yyvsp[-1].ttype); ;
break;}
-case 672:
-#line 3057 "parse.y"
+case 678:
+#line 3098 "parse.y"
{ yyval.ttype = make_pointer_declarator (yyvsp[-1].ftype.t, yyvsp[0].ttype); ;
break;}
-case 673:
-#line 3059 "parse.y"
+case 679:
+#line 3100 "parse.y"
{ yyval.ttype = make_pointer_declarator (NULL_TREE, yyvsp[0].ttype); ;
break;}
-case 674:
-#line 3061 "parse.y"
+case 680:
+#line 3102 "parse.y"
{ yyval.ttype = make_pointer_declarator (yyvsp[0].ftype.t, NULL_TREE); ;
break;}
-case 675:
-#line 3063 "parse.y"
+case 681:
+#line 3104 "parse.y"
{ yyval.ttype = make_pointer_declarator (NULL_TREE, NULL_TREE); ;
break;}
-case 676:
-#line 3065 "parse.y"
+case 682:
+#line 3106 "parse.y"
{ yyval.ttype = make_reference_declarator (yyvsp[-1].ftype.t, yyvsp[0].ttype); ;
break;}
-case 677:
-#line 3067 "parse.y"
+case 683:
+#line 3108 "parse.y"
{ yyval.ttype = make_reference_declarator (NULL_TREE, yyvsp[0].ttype); ;
break;}
-case 678:
-#line 3069 "parse.y"
+case 684:
+#line 3110 "parse.y"
{ yyval.ttype = make_reference_declarator (yyvsp[0].ftype.t, NULL_TREE); ;
break;}
-case 679:
-#line 3071 "parse.y"
+case 685:
+#line 3112 "parse.y"
{ yyval.ttype = make_reference_declarator (NULL_TREE, NULL_TREE); ;
break;}
-case 680:
-#line 3073 "parse.y"
+case 686:
+#line 3114 "parse.y"
{ tree arg = make_pointer_declarator (yyvsp[0].ttype, NULL_TREE);
yyval.ttype = build_parse_node (SCOPE_REF, yyvsp[-1].ttype, arg);
;
break;}
-case 681:
-#line 3077 "parse.y"
+case 687:
+#line 3118 "parse.y"
{ tree arg = make_pointer_declarator (yyvsp[-1].ttype, yyvsp[0].ttype);
yyval.ttype = build_parse_node (SCOPE_REF, yyvsp[-2].ttype, arg);
;
break;}
-case 683:
-#line 3086 "parse.y"
+case 689:
+#line 3127 "parse.y"
{ yyval.ttype = yyvsp[-1].ttype; ;
break;}
-case 685:
-#line 3090 "parse.y"
+case 691:
+#line 3131 "parse.y"
{ yyval.ttype = make_call_declarator (yyval.ttype, yyvsp[-3].ttype, yyvsp[-1].ttype, yyvsp[0].ttype); ;
break;}
-case 686:
-#line 3092 "parse.y"
+case 692:
+#line 3133 "parse.y"
{ yyval.ttype = make_call_declarator (yyval.ttype, empty_parms (), yyvsp[-1].ttype, yyvsp[0].ttype); ;
break;}
-case 687:
-#line 3094 "parse.y"
+case 693:
+#line 3135 "parse.y"
{ yyval.ttype = build_parse_node (ARRAY_REF, yyval.ttype, yyvsp[-1].ttype); ;
break;}
-case 688:
-#line 3096 "parse.y"
+case 694:
+#line 3137 "parse.y"
{ yyval.ttype = build_parse_node (ARRAY_REF, yyval.ttype, NULL_TREE); ;
break;}
-case 689:
-#line 3098 "parse.y"
+case 695:
+#line 3139 "parse.y"
{ yyval.ttype = make_call_declarator (NULL_TREE, yyvsp[-3].ttype, yyvsp[-1].ttype, yyvsp[0].ttype); ;
break;}
-case 690:
-#line 3100 "parse.y"
+case 696:
+#line 3141 "parse.y"
{ set_quals_and_spec (yyval.ttype, yyvsp[-1].ttype, yyvsp[0].ttype); ;
break;}
-case 691:
-#line 3102 "parse.y"
+case 697:
+#line 3143 "parse.y"
{ set_quals_and_spec (yyval.ttype, yyvsp[-1].ttype, yyvsp[0].ttype); ;
break;}
-case 692:
-#line 3104 "parse.y"
+case 698:
+#line 3145 "parse.y"
{ yyval.ttype = build_parse_node (ARRAY_REF, NULL_TREE, yyvsp[-1].ttype); ;
break;}
-case 693:
-#line 3106 "parse.y"
+case 699:
+#line 3147 "parse.y"
{ yyval.ttype = build_parse_node (ARRAY_REF, NULL_TREE, NULL_TREE); ;
break;}
-case 700:
-#line 3129 "parse.y"
+case 706:
+#line 3170 "parse.y"
{ if (pedantic)
pedwarn ("ANSI C++ forbids label declarations"); ;
break;}
-case 703:
-#line 3140 "parse.y"
+case 709:
+#line 3181 "parse.y"
{ tree link;
for (link = yyvsp[-1].ttype; link; link = TREE_CHAIN (link))
{
@@ -7145,269 +7214,267 @@ case 703:
}
;
break;}
-case 704:
-#line 3154 "parse.y"
+case 710:
+#line 3195 "parse.y"
{;
break;}
-case 706:
-#line 3160 "parse.y"
+case 712:
+#line 3201 "parse.y"
{ yyval.ttype = begin_compound_stmt (0); ;
break;}
-case 707:
-#line 3162 "parse.y"
+case 713:
+#line 3203 "parse.y"
{ yyval.ttype = finish_compound_stmt (0, yyvsp[-1].ttype); ;
break;}
-case 708:
-#line 3167 "parse.y"
+case 714:
+#line 3208 "parse.y"
{
yyval.ttype = begin_if_stmt ();
cond_stmt_keyword = "if";
;
break;}
-case 709:
-#line 3172 "parse.y"
+case 715:
+#line 3213 "parse.y"
{ finish_if_stmt_cond (yyvsp[0].ttype, yyvsp[-1].ttype); ;
break;}
-case 710:
-#line 3174 "parse.y"
+case 716:
+#line 3215 "parse.y"
{ yyval.ttype = finish_then_clause (yyvsp[-3].ttype); ;
break;}
-case 712:
-#line 3179 "parse.y"
+case 718:
+#line 3220 "parse.y"
{ yyval.ttype = begin_compound_stmt (0); ;
break;}
-case 713:
-#line 3181 "parse.y"
+case 719:
+#line 3222 "parse.y"
{ yyval.ttype = finish_compound_stmt (0, yyvsp[-1].ttype); ;
break;}
-case 714:
-#line 3186 "parse.y"
+case 720:
+#line 3227 "parse.y"
{;
break;}
-case 716:
-#line 3192 "parse.y"
+case 722:
+#line 3233 "parse.y"
{ finish_stmt (); ;
break;}
-case 717:
-#line 3194 "parse.y"
+case 723:
+#line 3235 "parse.y"
{ finish_expr_stmt (yyvsp[-1].ttype); ;
break;}
-case 718:
-#line 3196 "parse.y"
+case 724:
+#line 3237 "parse.y"
{ begin_else_clause (); ;
break;}
-case 719:
-#line 3198 "parse.y"
+case 725:
+#line 3239 "parse.y"
{
finish_else_clause (yyvsp[-3].ttype);
finish_if_stmt ();
;
break;}
-case 720:
-#line 3203 "parse.y"
+case 726:
+#line 3244 "parse.y"
{ finish_if_stmt (); ;
break;}
-case 721:
-#line 3205 "parse.y"
+case 727:
+#line 3246 "parse.y"
{
yyval.ttype = begin_while_stmt ();
cond_stmt_keyword = "while";
;
break;}
-case 722:
-#line 3210 "parse.y"
+case 728:
+#line 3251 "parse.y"
{ finish_while_stmt_cond (yyvsp[0].ttype, yyvsp[-1].ttype); ;
break;}
-case 723:
-#line 3212 "parse.y"
+case 729:
+#line 3253 "parse.y"
{ finish_while_stmt (yyvsp[-3].ttype); ;
break;}
-case 724:
-#line 3214 "parse.y"
+case 730:
+#line 3255 "parse.y"
{ yyval.ttype = begin_do_stmt (); ;
break;}
-case 725:
-#line 3216 "parse.y"
+case 731:
+#line 3257 "parse.y"
{
finish_do_body (yyvsp[-2].ttype);
cond_stmt_keyword = "do";
;
break;}
-case 726:
-#line 3221 "parse.y"
+case 732:
+#line 3262 "parse.y"
{ finish_do_stmt (yyvsp[-1].ttype, yyvsp[-5].ttype); ;
break;}
-case 727:
-#line 3223 "parse.y"
+case 733:
+#line 3264 "parse.y"
{ yyval.ttype = begin_for_stmt (); ;
break;}
-case 728:
-#line 3225 "parse.y"
+case 734:
+#line 3266 "parse.y"
{ finish_for_init_stmt (yyvsp[-2].ttype); ;
break;}
-case 729:
-#line 3227 "parse.y"
+case 735:
+#line 3268 "parse.y"
{ finish_for_cond (yyvsp[-1].ttype, yyvsp[-5].ttype); ;
break;}
-case 730:
-#line 3229 "parse.y"
+case 736:
+#line 3270 "parse.y"
{ finish_for_expr (yyvsp[-1].ttype, yyvsp[-8].ttype); ;
break;}
-case 731:
-#line 3231 "parse.y"
+case 737:
+#line 3272 "parse.y"
{ finish_for_stmt (yyvsp[-3].ttype, yyvsp[-10].ttype); ;
break;}
-case 732:
-#line 3233 "parse.y"
+case 738:
+#line 3274 "parse.y"
{ begin_switch_stmt (); ;
break;}
-case 733:
-#line 3235 "parse.y"
+case 739:
+#line 3276 "parse.y"
{ yyval.ttype = finish_switch_cond (yyvsp[-1].ttype); ;
break;}
-case 734:
-#line 3237 "parse.y"
+case 740:
+#line 3278 "parse.y"
{ finish_switch_stmt (yyvsp[-3].ttype, yyvsp[-1].ttype); ;
break;}
-case 735:
-#line 3239 "parse.y"
+case 741:
+#line 3280 "parse.y"
{ finish_case_label (yyvsp[-1].ttype, NULL_TREE); ;
break;}
-case 737:
-#line 3242 "parse.y"
+case 743:
+#line 3283 "parse.y"
{ finish_case_label (yyvsp[-3].ttype, yyvsp[-1].ttype); ;
break;}
-case 739:
-#line 3245 "parse.y"
+case 745:
+#line 3286 "parse.y"
{ finish_case_label (NULL_TREE, NULL_TREE); ;
break;}
-case 741:
-#line 3248 "parse.y"
+case 747:
+#line 3289 "parse.y"
{ finish_break_stmt (); ;
break;}
-case 742:
-#line 3250 "parse.y"
+case 748:
+#line 3291 "parse.y"
{ finish_continue_stmt (); ;
break;}
-case 743:
-#line 3252 "parse.y"
+case 749:
+#line 3293 "parse.y"
{ finish_return_stmt (NULL_TREE); ;
break;}
-case 744:
-#line 3254 "parse.y"
+case 750:
+#line 3295 "parse.y"
{ finish_return_stmt (yyvsp[-1].ttype); ;
break;}
-case 745:
-#line 3256 "parse.y"
+case 751:
+#line 3297 "parse.y"
{
finish_asm_stmt (yyvsp[-4].ttype, yyvsp[-2].ttype, NULL_TREE, NULL_TREE,
NULL_TREE);
;
break;}
-case 746:
-#line 3262 "parse.y"
+case 752:
+#line 3303 "parse.y"
{
finish_asm_stmt (yyvsp[-6].ttype, yyvsp[-4].ttype, yyvsp[-2].ttype, NULL_TREE,
NULL_TREE);
;
break;}
-case 747:
-#line 3268 "parse.y"
+case 753:
+#line 3309 "parse.y"
{ finish_asm_stmt (yyvsp[-8].ttype, yyvsp[-6].ttype, yyvsp[-4].ttype, yyvsp[-2].ttype, NULL_TREE); ;
break;}
-case 748:
-#line 3272 "parse.y"
+case 754:
+#line 3313 "parse.y"
{ finish_asm_stmt (yyvsp[-10].ttype, yyvsp[-8].ttype, yyvsp[-6].ttype, yyvsp[-4].ttype, yyvsp[-2].ttype); ;
break;}
-case 749:
-#line 3274 "parse.y"
+case 755:
+#line 3315 "parse.y"
{
if (pedantic)
pedwarn ("ANSI C++ forbids computed gotos");
finish_goto_stmt (yyvsp[-1].ttype);
;
break;}
-case 750:
-#line 3280 "parse.y"
+case 756:
+#line 3321 "parse.y"
{ finish_goto_stmt (yyvsp[-1].ttype); ;
break;}
-case 751:
-#line 3282 "parse.y"
+case 757:
+#line 3323 "parse.y"
{ finish_stmt (); ;
break;}
-case 752:
-#line 3284 "parse.y"
+case 758:
+#line 3325 "parse.y"
{ error ("label must be followed by statement");
yyungetc ('}', 0);
finish_stmt (); ;
break;}
-case 753:
-#line 3288 "parse.y"
+case 759:
+#line 3329 "parse.y"
{ finish_stmt (); ;
break;}
-case 756:
-#line 3292 "parse.y"
+case 762:
+#line 3333 "parse.y"
{ do_local_using_decl (yyvsp[0].ttype); ;
break;}
-case 758:
-#line 3298 "parse.y"
+case 764:
+#line 3339 "parse.y"
{
if (! current_function_parms_stored)
store_parm_decls ();
expand_start_early_try_stmts ();
;
break;}
-case 759:
-#line 3304 "parse.y"
+case 765:
+#line 3345 "parse.y"
{
expand_start_all_catch ();
;
break;}
-case 760:
-#line 3308 "parse.y"
+case 766:
+#line 3349 "parse.y"
{
- int nested = (hack_decl_function_context
- (current_function_decl) != NULL_TREE);
expand_end_all_catch ();
- finish_function (lineno, (int)yyvsp[-3].itype, nested);
+ yyval.itype = yyvsp[-3].itype;
;
break;}
-case 761:
-#line 3318 "parse.y"
+case 767:
+#line 3357 "parse.y"
{ yyval.ttype = begin_try_block (); ;
break;}
-case 762:
-#line 3320 "parse.y"
+case 768:
+#line 3359 "parse.y"
{ finish_try_block (yyvsp[-1].ttype); ;
break;}
-case 763:
-#line 3322 "parse.y"
+case 769:
+#line 3361 "parse.y"
{ finish_handler_sequence (yyvsp[-3].ttype); ;
break;}
-case 766:
-#line 3332 "parse.y"
+case 772:
+#line 3371 "parse.y"
{ yyval.ttype = begin_handler(); ;
break;}
-case 767:
-#line 3334 "parse.y"
+case 773:
+#line 3373 "parse.y"
{ finish_handler_parms (yyvsp[-1].ttype); ;
break;}
-case 768:
-#line 3336 "parse.y"
+case 774:
+#line 3375 "parse.y"
{ finish_handler (yyvsp[-3].ttype); ;
break;}
-case 771:
-#line 3346 "parse.y"
+case 777:
+#line 3385 "parse.y"
{ expand_start_catch_block (NULL_TREE, NULL_TREE); ;
break;}
-case 772:
-#line 3362 "parse.y"
+case 778:
+#line 3401 "parse.y"
{ check_for_new_type ("inside exception declarations", yyvsp[-1].ftype);
expand_start_catch_block (TREE_PURPOSE (yyvsp[-1].ftype.t),
TREE_VALUE (yyvsp[-1].ftype.t)); ;
break;}
-case 773:
-#line 3369 "parse.y"
+case 779:
+#line 3408 "parse.y"
{ tree label;
do_label:
label = define_label (input_filename, lineno, yyvsp[-1].ttype);
@@ -7415,99 +7482,99 @@ case 773:
expand_label (label);
;
break;}
-case 774:
-#line 3376 "parse.y"
+case 780:
+#line 3415 "parse.y"
{ goto do_label; ;
break;}
-case 775:
-#line 3378 "parse.y"
+case 781:
+#line 3417 "parse.y"
{ goto do_label; ;
break;}
-case 776:
-#line 3380 "parse.y"
+case 782:
+#line 3419 "parse.y"
{ goto do_label; ;
break;}
-case 777:
-#line 3385 "parse.y"
+case 783:
+#line 3424 "parse.y"
{ if (yyvsp[-1].ttype) cplus_expand_expr_stmt (yyvsp[-1].ttype); ;
break;}
-case 779:
-#line 3388 "parse.y"
+case 785:
+#line 3427 "parse.y"
{ if (pedantic)
pedwarn ("ANSI C++ forbids compound statements inside for initializations");
;
break;}
-case 780:
-#line 3397 "parse.y"
+case 786:
+#line 3436 "parse.y"
{ emit_line_note (input_filename, lineno);
yyval.ttype = NULL_TREE; ;
break;}
-case 781:
-#line 3400 "parse.y"
+case 787:
+#line 3439 "parse.y"
{ emit_line_note (input_filename, lineno); ;
break;}
-case 782:
-#line 3405 "parse.y"
+case 788:
+#line 3444 "parse.y"
{ yyval.ttype = NULL_TREE; ;
break;}
-case 784:
-#line 3408 "parse.y"
+case 790:
+#line 3447 "parse.y"
{ yyval.ttype = NULL_TREE; ;
break;}
-case 785:
-#line 3415 "parse.y"
+case 791:
+#line 3454 "parse.y"
{ yyval.ttype = NULL_TREE; ;
break;}
-case 788:
-#line 3422 "parse.y"
+case 794:
+#line 3461 "parse.y"
{ yyval.ttype = chainon (yyval.ttype, yyvsp[0].ttype); ;
break;}
-case 789:
-#line 3427 "parse.y"
+case 795:
+#line 3466 "parse.y"
{ yyval.ttype = build_tree_list (yyval.ttype, yyvsp[-1].ttype); ;
break;}
-case 790:
-#line 3432 "parse.y"
+case 796:
+#line 3471 "parse.y"
{ yyval.ttype = tree_cons (NULL_TREE, yyval.ttype, NULL_TREE); ;
break;}
-case 791:
-#line 3434 "parse.y"
+case 797:
+#line 3473 "parse.y"
{ yyval.ttype = tree_cons (NULL_TREE, yyvsp[0].ttype, yyval.ttype); ;
break;}
-case 792:
-#line 3445 "parse.y"
+case 798:
+#line 3484 "parse.y"
{
yyval.ttype = empty_parms();
;
break;}
-case 794:
-#line 3450 "parse.y"
+case 800:
+#line 3489 "parse.y"
{ yyval.ttype = finish_parmlist (build_tree_list (NULL_TREE, yyvsp[0].ftype.t), 0);
check_for_new_type ("inside parameter list", yyvsp[0].ftype); ;
break;}
-case 795:
-#line 3458 "parse.y"
+case 801:
+#line 3497 "parse.y"
{ yyval.ttype = finish_parmlist (yyval.ttype, 0); ;
break;}
-case 796:
-#line 3460 "parse.y"
+case 802:
+#line 3499 "parse.y"
{ yyval.ttype = finish_parmlist (yyvsp[-1].ttype, 1); ;
break;}
-case 797:
-#line 3463 "parse.y"
+case 803:
+#line 3502 "parse.y"
{ yyval.ttype = finish_parmlist (yyvsp[-1].ttype, 1); ;
break;}
-case 798:
-#line 3465 "parse.y"
+case 804:
+#line 3504 "parse.y"
{ yyval.ttype = finish_parmlist (build_tree_list (NULL_TREE,
yyvsp[-1].ftype.t), 1); ;
break;}
-case 799:
-#line 3468 "parse.y"
+case 805:
+#line 3507 "parse.y"
{ yyval.ttype = finish_parmlist (NULL_TREE, 1); ;
break;}
-case 800:
-#line 3470 "parse.y"
+case 806:
+#line 3509 "parse.y"
{
/* This helps us recover from really nasty
parse errors, for example, a missing right
@@ -7518,8 +7585,8 @@ case 800:
yychar = ')';
;
break;}
-case 801:
-#line 3480 "parse.y"
+case 807:
+#line 3519 "parse.y"
{
/* This helps us recover from really nasty
parse errors, for example, a missing right
@@ -7531,99 +7598,99 @@ case 801:
yychar = ')';
;
break;}
-case 802:
-#line 3495 "parse.y"
+case 808:
+#line 3534 "parse.y"
{ maybe_snarf_defarg (); ;
break;}
-case 803:
-#line 3497 "parse.y"
+case 809:
+#line 3536 "parse.y"
{ yyval.ttype = yyvsp[0].ttype; ;
break;}
-case 806:
-#line 3508 "parse.y"
+case 812:
+#line 3547 "parse.y"
{ check_for_new_type ("in a parameter list", yyvsp[0].ftype);
yyval.ttype = build_tree_list (NULL_TREE, yyvsp[0].ftype.t); ;
break;}
-case 807:
-#line 3511 "parse.y"
+case 813:
+#line 3550 "parse.y"
{ check_for_new_type ("in a parameter list", yyvsp[-1].ftype);
yyval.ttype = build_tree_list (yyvsp[0].ttype, yyvsp[-1].ftype.t); ;
break;}
-case 808:
-#line 3514 "parse.y"
+case 814:
+#line 3553 "parse.y"
{ check_for_new_type ("in a parameter list", yyvsp[0].ftype);
yyval.ttype = chainon (yyval.ttype, yyvsp[0].ftype.t); ;
break;}
-case 809:
-#line 3517 "parse.y"
+case 815:
+#line 3556 "parse.y"
{ yyval.ttype = chainon (yyval.ttype, build_tree_list (NULL_TREE, yyvsp[0].ttype)); ;
break;}
-case 810:
-#line 3519 "parse.y"
+case 816:
+#line 3558 "parse.y"
{ yyval.ttype = chainon (yyval.ttype, build_tree_list (yyvsp[0].ttype, yyvsp[-2].ttype)); ;
break;}
-case 812:
-#line 3525 "parse.y"
+case 818:
+#line 3564 "parse.y"
{ check_for_new_type ("in a parameter list", yyvsp[-1].ftype);
yyval.ttype = build_tree_list (NULL_TREE, yyvsp[-1].ftype.t); ;
break;}
-case 813:
-#line 3535 "parse.y"
+case 819:
+#line 3574 "parse.y"
{ tree specs = strip_attrs (yyvsp[-1].ftype.t);
yyval.ftype.new_type_flag = yyvsp[-1].ftype.new_type_flag;
yyval.ftype.t = build_tree_list (specs, yyvsp[0].ttype); ;
break;}
-case 814:
-#line 3539 "parse.y"
+case 820:
+#line 3578 "parse.y"
{ yyval.ftype.t = build_tree_list (yyvsp[-1].ftype.t, yyvsp[0].ttype);
yyval.ftype.new_type_flag = yyvsp[-1].ftype.new_type_flag; ;
break;}
-case 815:
-#line 3542 "parse.y"
+case 821:
+#line 3581 "parse.y"
{ yyval.ftype.t = build_tree_list (get_decl_list (yyvsp[-1].ftype.t), yyvsp[0].ttype);
yyval.ftype.new_type_flag = yyvsp[-1].ftype.new_type_flag; ;
break;}
-case 816:
-#line 3545 "parse.y"
+case 822:
+#line 3584 "parse.y"
{ tree specs = strip_attrs (yyvsp[-1].ftype.t);
yyval.ftype.t = build_tree_list (specs, yyvsp[0].ttype);
yyval.ftype.new_type_flag = yyvsp[-1].ftype.new_type_flag; ;
break;}
-case 817:
-#line 3549 "parse.y"
+case 823:
+#line 3588 "parse.y"
{ tree specs = strip_attrs (yyvsp[0].ftype.t);
yyval.ftype.t = build_tree_list (specs, NULL_TREE);
yyval.ftype.new_type_flag = yyvsp[0].ftype.new_type_flag; ;
break;}
-case 818:
-#line 3553 "parse.y"
+case 824:
+#line 3592 "parse.y"
{ tree specs = strip_attrs (yyvsp[-1].ttype);
yyval.ftype.t = build_tree_list (specs, yyvsp[0].ttype);
yyval.ftype.new_type_flag = 0; ;
break;}
-case 819:
-#line 3560 "parse.y"
+case 825:
+#line 3599 "parse.y"
{ yyval.ftype.t = build_tree_list (NULL_TREE, yyvsp[0].ftype.t);
yyval.ftype.new_type_flag = yyvsp[0].ftype.new_type_flag; ;
break;}
-case 820:
-#line 3563 "parse.y"
+case 826:
+#line 3602 "parse.y"
{ yyval.ftype.t = build_tree_list (yyvsp[0].ttype, yyvsp[-1].ftype.t);
yyval.ftype.new_type_flag = yyvsp[-1].ftype.new_type_flag; ;
break;}
-case 823:
-#line 3574 "parse.y"
+case 829:
+#line 3613 "parse.y"
{ see_typename (); ;
break;}
-case 824:
-#line 3579 "parse.y"
+case 830:
+#line 3618 "parse.y"
{
error ("type specifier omitted for parameter");
yyval.ttype = build_tree_list (integer_type_node, NULL_TREE);
;
break;}
-case 825:
-#line 3584 "parse.y"
+case 831:
+#line 3623 "parse.y"
{
error ("type specifier omitted for parameter");
if (TREE_CODE (yyval.ttype) == SCOPE_REF
@@ -7633,194 +7700,194 @@ case 825:
yyval.ttype = build_tree_list (integer_type_node, yyval.ttype);
;
break;}
-case 826:
-#line 3596 "parse.y"
+case 832:
+#line 3635 "parse.y"
{ yyval.ttype = NULL_TREE; ;
break;}
-case 827:
-#line 3598 "parse.y"
+case 833:
+#line 3637 "parse.y"
{ yyval.ttype = yyvsp[-1].ttype; ;
break;}
-case 828:
-#line 3600 "parse.y"
+case 834:
+#line 3639 "parse.y"
{ yyval.ttype = build_decl_list (NULL_TREE, NULL_TREE); ;
break;}
-case 829:
-#line 3605 "parse.y"
+case 835:
+#line 3644 "parse.y"
{ yyval.ttype = build_decl_list (NULL_TREE, groktypename(yyvsp[0].ftype.t)); ;
break;}
-case 831:
-#line 3611 "parse.y"
+case 837:
+#line 3650 "parse.y"
{
TREE_CHAIN (yyvsp[0].ttype) = yyval.ttype;
yyval.ttype = yyvsp[0].ttype;
;
break;}
-case 832:
-#line 3619 "parse.y"
+case 838:
+#line 3658 "parse.y"
{ yyval.ttype = NULL_TREE; ;
break;}
-case 833:
-#line 3621 "parse.y"
+case 839:
+#line 3660 "parse.y"
{ yyval.ttype = make_pointer_declarator (yyvsp[-1].ttype, yyvsp[0].ttype); ;
break;}
-case 834:
-#line 3623 "parse.y"
+case 840:
+#line 3662 "parse.y"
{ yyval.ttype = make_reference_declarator (yyvsp[-1].ttype, yyvsp[0].ttype); ;
break;}
-case 835:
-#line 3625 "parse.y"
+case 841:
+#line 3664 "parse.y"
{ tree arg = make_pointer_declarator (yyvsp[-1].ttype, yyvsp[0].ttype);
yyval.ttype = build_parse_node (SCOPE_REF, yyvsp[-2].ttype, arg);
;
break;}
-case 836:
-#line 3632 "parse.y"
+case 842:
+#line 3671 "parse.y"
{ got_scope = NULL_TREE; ;
break;}
-case 837:
-#line 3637 "parse.y"
+case 843:
+#line 3676 "parse.y"
{ yyval.ttype = ansi_opname[MULT_EXPR]; ;
break;}
-case 838:
-#line 3639 "parse.y"
+case 844:
+#line 3678 "parse.y"
{ yyval.ttype = ansi_opname[TRUNC_DIV_EXPR]; ;
break;}
-case 839:
-#line 3641 "parse.y"
+case 845:
+#line 3680 "parse.y"
{ yyval.ttype = ansi_opname[TRUNC_MOD_EXPR]; ;
break;}
-case 840:
-#line 3643 "parse.y"
+case 846:
+#line 3682 "parse.y"
{ yyval.ttype = ansi_opname[PLUS_EXPR]; ;
break;}
-case 841:
-#line 3645 "parse.y"
+case 847:
+#line 3684 "parse.y"
{ yyval.ttype = ansi_opname[MINUS_EXPR]; ;
break;}
-case 842:
-#line 3647 "parse.y"
+case 848:
+#line 3686 "parse.y"
{ yyval.ttype = ansi_opname[BIT_AND_EXPR]; ;
break;}
-case 843:
-#line 3649 "parse.y"
+case 849:
+#line 3688 "parse.y"
{ yyval.ttype = ansi_opname[BIT_IOR_EXPR]; ;
break;}
-case 844:
-#line 3651 "parse.y"
+case 850:
+#line 3690 "parse.y"
{ yyval.ttype = ansi_opname[BIT_XOR_EXPR]; ;
break;}
-case 845:
-#line 3653 "parse.y"
+case 851:
+#line 3692 "parse.y"
{ yyval.ttype = ansi_opname[BIT_NOT_EXPR]; ;
break;}
-case 846:
-#line 3655 "parse.y"
+case 852:
+#line 3694 "parse.y"
{ yyval.ttype = ansi_opname[COMPOUND_EXPR]; ;
break;}
-case 847:
-#line 3657 "parse.y"
+case 853:
+#line 3696 "parse.y"
{ yyval.ttype = ansi_opname[yyvsp[0].code]; ;
break;}
-case 848:
-#line 3659 "parse.y"
+case 854:
+#line 3698 "parse.y"
{ yyval.ttype = ansi_opname[LT_EXPR]; ;
break;}
-case 849:
-#line 3661 "parse.y"
+case 855:
+#line 3700 "parse.y"
{ yyval.ttype = ansi_opname[GT_EXPR]; ;
break;}
-case 850:
-#line 3663 "parse.y"
+case 856:
+#line 3702 "parse.y"
{ yyval.ttype = ansi_opname[yyvsp[0].code]; ;
break;}
-case 851:
-#line 3665 "parse.y"
+case 857:
+#line 3704 "parse.y"
{ yyval.ttype = ansi_assopname[yyvsp[0].code]; ;
break;}
-case 852:
-#line 3667 "parse.y"
+case 858:
+#line 3706 "parse.y"
{ yyval.ttype = ansi_opname [MODIFY_EXPR]; ;
break;}
-case 853:
-#line 3669 "parse.y"
+case 859:
+#line 3708 "parse.y"
{ yyval.ttype = ansi_opname[yyvsp[0].code]; ;
break;}
-case 854:
-#line 3671 "parse.y"
+case 860:
+#line 3710 "parse.y"
{ yyval.ttype = ansi_opname[yyvsp[0].code]; ;
break;}
-case 855:
-#line 3673 "parse.y"
+case 861:
+#line 3712 "parse.y"
{ yyval.ttype = ansi_opname[POSTINCREMENT_EXPR]; ;
break;}
-case 856:
-#line 3675 "parse.y"
+case 862:
+#line 3714 "parse.y"
{ yyval.ttype = ansi_opname[PREDECREMENT_EXPR]; ;
break;}
-case 857:
-#line 3677 "parse.y"
+case 863:
+#line 3716 "parse.y"
{ yyval.ttype = ansi_opname[TRUTH_ANDIF_EXPR]; ;
break;}
-case 858:
-#line 3679 "parse.y"
+case 864:
+#line 3718 "parse.y"
{ yyval.ttype = ansi_opname[TRUTH_ORIF_EXPR]; ;
break;}
-case 859:
-#line 3681 "parse.y"
+case 865:
+#line 3720 "parse.y"
{ yyval.ttype = ansi_opname[TRUTH_NOT_EXPR]; ;
break;}
-case 860:
-#line 3683 "parse.y"
+case 866:
+#line 3722 "parse.y"
{ yyval.ttype = ansi_opname[COND_EXPR]; ;
break;}
-case 861:
-#line 3685 "parse.y"
+case 867:
+#line 3724 "parse.y"
{ yyval.ttype = ansi_opname[yyvsp[0].code]; ;
break;}
-case 862:
-#line 3687 "parse.y"
+case 868:
+#line 3726 "parse.y"
{ yyval.ttype = ansi_opname[COMPONENT_REF]; ;
break;}
-case 863:
-#line 3689 "parse.y"
+case 869:
+#line 3728 "parse.y"
{ yyval.ttype = ansi_opname[MEMBER_REF]; ;
break;}
-case 864:
-#line 3691 "parse.y"
+case 870:
+#line 3730 "parse.y"
{ yyval.ttype = ansi_opname[CALL_EXPR]; ;
break;}
-case 865:
-#line 3693 "parse.y"
+case 871:
+#line 3732 "parse.y"
{ yyval.ttype = ansi_opname[ARRAY_REF]; ;
break;}
-case 866:
-#line 3695 "parse.y"
+case 872:
+#line 3734 "parse.y"
{ yyval.ttype = ansi_opname[NEW_EXPR]; ;
break;}
-case 867:
-#line 3697 "parse.y"
+case 873:
+#line 3736 "parse.y"
{ yyval.ttype = ansi_opname[DELETE_EXPR]; ;
break;}
-case 868:
-#line 3699 "parse.y"
+case 874:
+#line 3738 "parse.y"
{ yyval.ttype = ansi_opname[VEC_NEW_EXPR]; ;
break;}
-case 869:
-#line 3701 "parse.y"
+case 875:
+#line 3740 "parse.y"
{ yyval.ttype = ansi_opname[VEC_DELETE_EXPR]; ;
break;}
-case 870:
-#line 3704 "parse.y"
+case 876:
+#line 3743 "parse.y"
{ yyval.ttype = grokoptypename (yyvsp[-1].ftype.t, yyvsp[0].ttype); ;
break;}
-case 871:
-#line 3706 "parse.y"
+case 877:
+#line 3745 "parse.y"
{ yyval.ttype = ansi_opname[ERROR_MARK]; ;
break;}
}
/* the action file gets copied in in place of this dollarsign */
-#line 498 "/usr/lib/bison.simple"
+#line 498 "/usr/local/gnu/share/bison.simple"
yyvsp -= yylen;
yyssp -= yylen;
@@ -8016,7 +8083,7 @@ yyerrhandle:
yystate = yyn;
goto yynewstate;
}
-#line 3709 "parse.y"
+#line 3748 "parse.y"
#ifdef SPEW_DEBUG
diff --git a/gcc/cp/parse.y b/gcc/cp/parse.y
index 2def8f7a7e1..9d010726508 100644
--- a/gcc/cp/parse.y
+++ b/gcc/cp/parse.y
@@ -1,5 +1,5 @@
/* YACC parser for C++ syntax.
- Copyright (C) 1988, 89, 93, 94, 95, 1996 Free Software Foundation, Inc.
+ Copyright (C) 1988, 89, 93-98, 1999 Free Software Foundation, Inc.
Hacked by Michael Tiemann (tiemann@cygnus.com)
This file is part of GNU CC.
@@ -59,9 +59,10 @@ extern int end_of_file;
/* Contains the statement keyword (if/while/do) to include in an
error message if the user supplies an empty conditional expression. */
-static char *cond_stmt_keyword;
+static const char *cond_stmt_keyword;
static tree empty_parms PROTO((void));
+static int parse_decl PROTO((tree, tree, tree, int, tree *));
/* Nonzero if we have an `extern "C"' acting as an extern specifier. */
int have_extern_spec;
@@ -202,6 +203,7 @@ empty_parms ()
%type <ttype> compstmt implicitly_scoped_stmt
%type <ttype> declarator notype_declarator after_type_declarator
+%type <ttype> notype_declarator_intern
%type <ttype> direct_notype_declarator direct_after_type_declarator
%type <itype> components notype_components
%type <ttype> component_decl component_decl_1
@@ -215,7 +217,8 @@ empty_parms ()
%type <ttype> xexpr parmlist parms bad_parm
%type <ttype> identifiers_or_typenames
%type <ttype> fcast_or_absdcl regcast_or_absdcl
-%type <ttype> expr_or_declarator complex_notype_declarator
+%type <ttype> expr_or_declarator expr_or_declarator_intern
+%type <ttype> complex_notype_declarator
%type <ttype> notype_unqualified_id unqualified_id qualified_id
%type <ttype> template_id do_id object_template_id notype_template_declarator
%type <ttype> overqualified_id notype_qualified_id any_id
@@ -233,7 +236,7 @@ empty_parms ()
%token <ttype> PRE_PARSED_CLASS_DECL DEFARG DEFARG_MARKER
%type <ttype> component_constructor_declarator
%type <ttype> fn.def2 return_id fn.defpen constructor_declarator
-%type <itype> ctor_initializer_opt
+%type <itype> ctor_initializer_opt function_try_block
%type <ttype> named_class_head named_class_head_sans_basetype
%type <ttype> named_complex_class_head_sans_basetype
%type <ttype> unnamed_class_head
@@ -250,6 +253,7 @@ empty_parms ()
%type <ttype> template_header template_parm_list template_parm
%type <ttype> template_type_parm template_template_parm
%type <code> template_close_bracket
+%type <ttype> apparent_template_type
%type <ttype> template_type template_arg_list template_arg_list_opt
%type <ttype> template_arg
%type <ttype> condition xcond paren_cond_or_null
@@ -644,7 +648,11 @@ fndef:
fn.def1 maybe_return_init ctor_initializer_opt compstmt_or_error
{ finish_function (lineno, (int)$3, 0); }
| fn.def1 maybe_return_init function_try_block
- { }
+ {
+ int nested = (hack_decl_function_context
+ (current_function_decl) != NULL_TREE);
+ finish_function (lineno, (int)$3, nested);
+ }
| fn.def1 maybe_return_init error
{ }
;
@@ -717,8 +725,10 @@ component_constructor_declarator:
reduce/reduce conflict introduced by these rules. */
fn.def2:
declmods component_constructor_declarator
- { tree specs = strip_attrs ($1);
- $$ = start_method (specs, $2);
+ { tree specs, attrs;
+ split_specs_attrs ($1, &specs, &attrs);
+ attrs = build_tree_list (attrs, NULL_TREE);
+ $$ = start_method (specs, $2, attrs);
rest_of_mdef:
if (! $$)
YYERROR1;
@@ -726,20 +736,29 @@ fn.def2:
yychar = YYLEX;
reinit_parse_for_method (yychar, $$); }
| component_constructor_declarator
- { $$ = start_method (NULL_TREE, $1); goto rest_of_mdef; }
+ { $$ = start_method (NULL_TREE, $1, NULL_TREE);
+ goto rest_of_mdef; }
| typed_declspecs declarator
- { tree specs = strip_attrs ($1.t);
- $$ = start_method (specs, $2); goto rest_of_mdef; }
+ { tree specs, attrs;
+ split_specs_attrs ($1.t, &specs, &attrs);
+ attrs = build_tree_list (attrs, NULL_TREE);
+ $$ = start_method (specs, $2, attrs); goto rest_of_mdef; }
| declmods notype_declarator
- { tree specs = strip_attrs ($1);
- $$ = start_method (specs, $2); goto rest_of_mdef; }
+ { tree specs, attrs;
+ split_specs_attrs ($1, &specs, &attrs);
+ attrs = build_tree_list (attrs, NULL_TREE);
+ $$ = start_method (specs, $2, attrs); goto rest_of_mdef; }
| notype_declarator
- { $$ = start_method (NULL_TREE, $$); goto rest_of_mdef; }
+ { $$ = start_method (NULL_TREE, $$, NULL_TREE);
+ goto rest_of_mdef; }
| declmods constructor_declarator
- { tree specs = strip_attrs ($1);
- $$ = start_method (specs, $2); goto rest_of_mdef; }
+ { tree specs, attrs;
+ split_specs_attrs ($1, &specs, &attrs);
+ attrs = build_tree_list (attrs, NULL_TREE);
+ $$ = start_method (specs, $2, attrs); goto rest_of_mdef; }
| constructor_declarator
- { $$ = start_method (NULL_TREE, $$); goto rest_of_mdef; }
+ { $$ = start_method (NULL_TREE, $$, NULL_TREE);
+ goto rest_of_mdef; }
;
return_id:
@@ -903,6 +922,12 @@ template_type:
| self_template_type
;
+apparent_template_type:
+ template_type
+ | identifier '<' template_arg_list_opt '>'
+ .finish_template_type
+ { $$ = $5; }
+
self_template_type:
SELFNAME '<' template_arg_list_opt template_close_bracket
.finish_template_type
@@ -1016,7 +1041,7 @@ condition:
{
cp_finish_decl ($<ttype>6, $7, $4, 1, LOOKUP_ONLYCONVERTING);
resume_momentary ($<itype>5);
- $$ = $<ttype>6;
+ $$ = convert_from_reference ($<ttype>6);
if (TREE_CODE (TREE_TYPE ($$)) == ARRAY_TYPE)
cp_error ("definition of array `%#D' in condition", $$);
}
@@ -1081,7 +1106,8 @@ unary_expr:
| SIZEOF unary_expr %prec UNARY
{ $$ = expr_sizeof ($2); }
| SIZEOF '(' type_id ')' %prec HYPERUNARY
- { $$ = c_sizeof (groktypename ($3.t)); }
+ { $$ = c_sizeof (groktypename ($3.t));
+ check_for_new_type ("sizeof", $3); }
| ALIGNOF unary_expr %prec UNARY
{ $$ = grok_alignof ($2); }
| ALIGNOF '(' type_id ')' %prec HYPERUNARY
@@ -1300,7 +1326,16 @@ notype_unqualified_id:
;
do_id:
- { $$ = do_identifier ($<ttype>-1, 1, NULL_TREE); }
+ {
+ /* If lastiddecl is a TREE_LIST, it's a baselink, which
+ means that we're in an expression like S::f<int>, so
+ don't do_identifier; we only do that for unqualified
+ identifiers. */
+ if (lastiddecl && TREE_CODE (lastiddecl) != TREE_LIST)
+ $$ = do_identifier ($<ttype>-1, 1, NULL_TREE);
+ else
+ $$ = $<ttype>-1;
+ }
template_id:
PFUNCNAME '<' do_id template_arg_list_opt template_close_bracket
@@ -1325,13 +1360,23 @@ unqualified_id:
| SELFNAME
;
+expr_or_declarator_intern:
+ expr_or_declarator
+ | attributes expr_or_declarator
+ {
+ /* Provide support for '(' attributes '*' declarator ')'
+ etc */
+ $$ = decl_tree_cons ($1, $2, NULL_TREE);
+ }
+ ;
+
expr_or_declarator:
notype_unqualified_id
- | '*' expr_or_declarator %prec UNARY
+ | '*' expr_or_declarator_intern %prec UNARY
{ $$ = build_parse_node (INDIRECT_REF, $2); }
- | '&' expr_or_declarator %prec UNARY
+ | '&' expr_or_declarator_intern %prec UNARY
{ $$ = build_parse_node (ADDR_EXPR, $2); }
- | '(' expr_or_declarator ')'
+ | '(' expr_or_declarator_intern ')'
{ $$ = $2; }
;
@@ -1348,8 +1393,8 @@ direct_notype_declarator:
to the Koenig lookup shift in primary, below. I hate yacc. */
| notype_unqualified_id %prec '('
| notype_template_declarator
- | '(' expr_or_declarator ')'
- { $$ = finish_decl_parsing ($2); }
+ | '(' expr_or_declarator_intern ')'
+ { $$ = finish_decl_parsing ($2); }
;
primary:
@@ -1378,7 +1423,7 @@ primary:
}
| '(' expr ')'
{ $$ = finish_parenthesized_expr ($2); }
- | '(' expr_or_declarator ')'
+ | '(' expr_or_declarator_intern ')'
{ $2 = reparse_decl_as_expr (NULL_TREE, $2);
$$ = finish_parenthesized_expr ($2); }
| '(' error ')'
@@ -1418,47 +1463,20 @@ primary:
{ $$ = finish_this_expr (); }
| CV_QUALIFIER '(' nonnull_exprlist ')'
{
- tree type = NULL_TREE;
- tree id = $$;
+ /* This is a C cast in C++'s `functional' notation
+ using the "implicit int" extension so that:
+ `const (3)' is equivalent to `const int (3)'. */
+ tree type;
- /* This is a C cast in C++'s `functional' notation. */
if ($3 == error_mark_node)
{
$$ = error_mark_node;
break;
}
-#if 0
- if ($3 == NULL_TREE)
- {
- error ("cannot cast null list to type `%s'",
- IDENTIFIER_POINTER (TYPE_NAME (id)));
- $$ = error_mark_node;
- break;
- }
-#endif
-#if 0
- /* type is not set! (mrs) */
- if (type == error_mark_node)
- $$ = error_mark_node;
- else
-#endif
- {
- if (id == ridpointers[(int) RID_CONST])
- type = build_type_variant (integer_type_node, 1, 0);
- else if (id == ridpointers[(int) RID_VOLATILE])
- type = build_type_variant (integer_type_node, 0, 1);
-#if 0
- /* should not be able to get here (mrs) */
- else if (id == ridpointers[(int) RID_FRIEND])
- {
- error ("cannot cast expression to `friend' type");
- $$ = error_mark_node;
- break;
- }
-#endif
- else my_friendly_abort (79);
- $$ = build_c_cast (type, build_compound_expr ($3));
- }
+
+ type = cp_build_qualified_type (integer_type_node,
+ cp_type_qual_from_rid ($1));
+ $$ = build_c_cast (type, build_compound_expr ($3));
}
| functional_cast
| DYNAMIC_CAST '<' type_id '>' '(' expr ')'
@@ -1801,7 +1819,7 @@ typespec:
| complete_type_name
{ $$.t = $1; $$.new_type_flag = 0; }
| TYPEOF '(' expr ')'
- { $$.t = TREE_TYPE ($3);
+ { $$.t = finish_typeof ($3);
$$.new_type_flag = 0; }
| TYPEOF '(' type_id ')'
{ $$.t = groktypename ($3.t);
@@ -2032,7 +2050,7 @@ initlist:
fn.defpen:
PRE_PARSED_FUNCTION_DECL
{ start_function (NULL_TREE, TREE_VALUE ($1),
- NULL_TREE, 1);
+ NULL_TREE, 2);
reinit_parse_for_function (); }
pending_inline:
@@ -2040,11 +2058,16 @@ pending_inline:
{
int nested = (hack_decl_function_context
(current_function_decl) != NULL_TREE);
- finish_function (lineno, (int)$3, nested);
+ finish_function (lineno, (int)$3 | 2, nested);
process_next_inline ($1);
}
| fn.defpen maybe_return_init function_try_block
- { process_next_inline ($1); }
+ {
+ int nested = (hack_decl_function_context
+ (current_function_decl) != NULL_TREE);
+ finish_function (lineno, (int)$3 | 2, nested);
+ process_next_inline ($1);
+ }
| fn.defpen maybe_return_init error
{ process_next_inline ($1); }
;
@@ -2094,7 +2117,7 @@ structsp:
{ TYPE_VALUES (current_enum_type) = $4;
$$.t = finish_enum (current_enum_type);
$$.new_type_flag = 1;
- current_enum_type = $<ttype>4;
+ current_enum_type = $<ttype>3;
resume_momentary ((int) $<itype>1);
check_for_missing_semicolon ($$.t); }
| ENUM '{' '}'
@@ -2209,9 +2232,9 @@ named_complex_class_head_sans_basetype:
current_aggr = $1;
$$ = handle_class_head ($1, NULL_TREE, $3);
}
- | aggr template_type
+ | aggr apparent_template_type
{ current_aggr = $$; $$ = $2; }
- | aggr nested_name_specifier template_type
+ | aggr nested_name_specifier apparent_template_type
{ current_aggr = $$; $$ = $3; }
;
@@ -2220,25 +2243,41 @@ named_class_head:
{ $$ = xref_tag (current_aggr, $1, 1); }
| named_class_head_sans_basetype_defn
{ $<ttype>$ = xref_tag (current_aggr, $1, 0); }
+ /* Class name is unqualified, so we look for base classes
+ in the current scope. */
maybe_base_class_list %prec EMPTY
{
$$ = $<ttype>2;
if ($3)
xref_basetypes (current_aggr, $1, $<ttype>2, $3);
}
- | named_complex_class_head_sans_basetype maybe_base_class_list
+ | named_complex_class_head_sans_basetype
+ {
+ if ($1 != error_mark_node)
+ push_scope (CP_DECL_CONTEXT ($1));
+ }
+ maybe_base_class_list
{
- $$ = TREE_TYPE ($1);
- if (TREE_INT_CST_LOW (current_aggr) == union_type
- && TREE_CODE ($$) != UNION_TYPE)
- cp_pedwarn ("`union' tag used in declaring `%#T'", $$);
- else if (TREE_CODE ($$) == UNION_TYPE
- && TREE_INT_CST_LOW (current_aggr) != union_type)
- cp_pedwarn ("non-`union' tag used in declaring `%#T'", $$);
- if ($2)
+ if ($1 != error_mark_node)
{
- maybe_process_partial_specialization ($$);
- xref_basetypes (current_aggr, $1, $$, $2);
+ pop_scope (CP_DECL_CONTEXT ($1));
+ $$ = TREE_TYPE ($1);
+ if (current_aggr == union_type_node
+ && TREE_CODE ($$) != UNION_TYPE)
+ cp_pedwarn ("`union' tag used in declaring `%#T'", $$);
+ else if (TREE_CODE ($$) == UNION_TYPE
+ && current_aggr != union_type_node)
+ cp_pedwarn ("non-`union' tag used in declaring `%#T'", $$);
+ else if (TREE_CODE ($$) == RECORD_TYPE)
+ /* We might be specializing a template with a different
+ class-key; deal. */
+ CLASSTYPE_DECLARED_CLASS ($$) = (current_aggr
+ == class_type_node);
+ if ($3)
+ {
+ maybe_process_partial_specialization ($$);
+ xref_basetypes (current_aggr, $1, $$, $3);
+ }
}
}
;
@@ -2364,16 +2403,8 @@ left_curly:
{ $<ttype>0 = begin_class_definition ($<ttype>0); }
;
-self_reference:
- /* empty */
- {
- finish_member_declaration (build_self_reference ());
- }
- ;
-
opt.component_decl_list:
- self_reference
- | self_reference component_decl_list
+ | component_decl_list
| opt.component_decl_list access_specifier component_decl_list
| opt.component_decl_list access_specifier
;
@@ -2774,16 +2805,26 @@ direct_after_type_declarator:
/* A declarator allowed whether or not there has been
an explicit typespec. These cannot redeclare a typedef-name. */
+notype_declarator_intern:
+ notype_declarator
+ | attributes notype_declarator
+ {
+ /* Provide support for '(' attributes '*' declarator ')'
+ etc */
+ $$ = decl_tree_cons ($1, $2, NULL_TREE);
+ }
+ ;
+
notype_declarator:
- '*' nonempty_cv_qualifiers notype_declarator %prec UNARY
+ '*' nonempty_cv_qualifiers notype_declarator_intern %prec UNARY
{ $$ = make_pointer_declarator ($2.t, $3); }
- | '&' nonempty_cv_qualifiers notype_declarator %prec UNARY
+ | '&' nonempty_cv_qualifiers notype_declarator_intern %prec UNARY
{ $$ = make_reference_declarator ($2.t, $3); }
- | '*' notype_declarator %prec UNARY
+ | '*' notype_declarator_intern %prec UNARY
{ $$ = make_pointer_declarator (NULL_TREE, $2); }
- | '&' notype_declarator %prec UNARY
+ | '&' notype_declarator_intern %prec UNARY
{ $$ = make_reference_declarator (NULL_TREE, $2); }
- | ptr_to_mem cv_qualifiers notype_declarator
+ | ptr_to_mem cv_qualifiers notype_declarator_intern
{ tree arg = make_pointer_declarator ($2, $3);
$$ = build_parse_node (SCOPE_REF, $1, arg);
}
@@ -2791,15 +2832,15 @@ notype_declarator:
;
complex_notype_declarator:
- '*' nonempty_cv_qualifiers notype_declarator %prec UNARY
+ '*' nonempty_cv_qualifiers notype_declarator_intern %prec UNARY
{ $$ = make_pointer_declarator ($2.t, $3); }
- | '&' nonempty_cv_qualifiers notype_declarator %prec UNARY
+ | '&' nonempty_cv_qualifiers notype_declarator_intern %prec UNARY
{ $$ = make_reference_declarator ($2.t, $3); }
| '*' complex_notype_declarator %prec UNARY
{ $$ = make_pointer_declarator (NULL_TREE, $2); }
| '&' complex_notype_declarator %prec UNARY
{ $$ = make_reference_declarator (NULL_TREE, $2); }
- | ptr_to_mem cv_qualifiers notype_declarator
+ | ptr_to_mem cv_qualifiers notype_declarator_intern
{ tree arg = make_pointer_declarator ($2, $3);
$$ = build_parse_node (SCOPE_REF, $1, arg);
}
@@ -2851,7 +2892,7 @@ overqualified_id:
functional_cast:
typespec '(' nonnull_exprlist ')'
{ $$ = build_functional_cast ($1.t, $3); }
- | typespec '(' expr_or_declarator ')'
+ | typespec '(' expr_or_declarator_intern ')'
{ $$ = reparse_decl_as_expr ($1.t, $3); }
| typespec fcast_or_absdcl %prec EMPTY
{ $$ = reparse_absdcl_as_expr ($1.t, $2); }
@@ -3314,10 +3355,8 @@ function_try_block:
}
handler_seq
{
- int nested = (hack_decl_function_context
- (current_function_decl) != NULL_TREE);
expand_end_all_catch ();
- finish_function (lineno, (int)$3, nested);
+ $$ = $3;
}
;
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index c493bea4f5f..8d83ffafcb5 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -1,5 +1,5 @@
/* Handle parameterized types (templates) for GNU C++.
- Copyright (C) 1992, 93, 94, 95, 96, 1997 Free Software Foundation, Inc.
+ Copyright (C) 1992, 93-97, 1998, 1999 Free Software Foundation, Inc.
Written by Ken Raeburn (raeburn@cygnus.com) while at Watchmaker Computing.
Rewritten by Jason Merrill (jason@cygnus.com).
@@ -75,8 +75,19 @@ static tree saved_trees;
#define UNIFY_ALLOW_MORE_CV_QUAL 1
#define UNIFY_ALLOW_LESS_CV_QUAL 2
#define UNIFY_ALLOW_DERIVED 4
-
-static int unify PROTO((tree, tree, tree, tree, int, int*));
+#define UNIFY_ALLOW_INTEGER 8
+
+#define GTB_VIA_VIRTUAL 1 /* The base class we are examining is
+ virtual, or a base class of a virtual
+ base. */
+#define GTB_IGNORE_TYPE 2 /* We don't need to try to unify the current
+ type with the desired type. */
+
+static int resolve_overloaded_unification PROTO((tree, tree, tree, tree,
+ unification_kind_t, int));
+static int try_one_overload PROTO((tree, tree, tree, tree, tree,
+ unification_kind_t, int));
+static int unify PROTO((tree, tree, tree, tree, int));
static void add_pending_template PROTO((tree));
static int push_tinst_level PROTO((tree));
static tree classtype_mangled_name PROTO((tree));
@@ -91,7 +102,7 @@ static tree add_outermost_template_args PROTO((tree, tree));
static void maybe_adjust_types_for_deduction PROTO((unification_kind_t, tree*,
tree*));
static int type_unification_real PROTO((tree, tree, tree, tree,
- int, unification_kind_t, int, int*));
+ int, unification_kind_t, int));
static void note_template_header PROTO((int));
static tree maybe_fold_nontype_arg PROTO((tree));
static tree convert_nontype_argument PROTO((tree, tree));
@@ -105,7 +116,6 @@ static void push_inline_template_parms_recursive PROTO((tree, int));
static tree retrieve_specialization PROTO((tree, tree));
static tree register_specialization PROTO((tree, tree, tree));
static int unregister_specialization PROTO((tree, tree));
-static void print_candidates PROTO((tree));
static tree reduce_template_parm_level PROTO((tree, tree, int));
static tree build_template_decl PROTO((tree, tree));
static int mark_template_parm PROTO((tree, void *));
@@ -115,21 +125,32 @@ static tree get_bindings_real PROTO((tree, tree, tree, int));
static int template_decl_level PROTO((tree));
static tree maybe_get_template_decl_from_type_decl PROTO((tree));
static int check_cv_quals_for_unify PROTO((int, tree, tree));
-static tree tsubst_template_arg_vector PROTO((tree, tree));
-static tree tsubst_template_parms PROTO((tree, tree));
+static tree tsubst_template_arg_vector PROTO((tree, tree, int));
+static tree tsubst_template_parms PROTO((tree, tree, int));
static void regenerate_decl_from_template PROTO((tree, tree));
-static int is_member_template_class PROTO((tree));
static tree most_specialized PROTO((tree, tree, tree));
static tree most_specialized_class PROTO((tree, tree));
static tree most_general_template PROTO((tree));
static void set_mangled_name_for_template_decl PROTO((tree));
static int template_class_depth_real PROTO((tree, int));
-static tree tsubst_aggr_type PROTO((tree, tree, tree, int));
+static tree tsubst_aggr_type PROTO((tree, tree, int, tree, int));
static tree tsubst_decl PROTO((tree, tree, tree, tree));
-static tree tsubst_arg_types PROTO((tree, tree, tree));
+static tree tsubst_arg_types PROTO((tree, tree, int, tree));
+static tree tsubst_function_type PROTO((tree, tree, int, tree));
static void check_specialization_scope PROTO((void));
static tree process_partial_specialization PROTO((tree));
static void set_current_access_from_decl PROTO((tree));
+static void check_default_tmpl_args PROTO((tree, tree, int, int));
+static tree tsubst_call_declarator_parms PROTO((tree, tree, int, tree));
+static tree get_template_base_recursive PROTO((tree, tree,
+ tree, tree, tree, int));
+static tree get_template_base PROTO((tree, tree, tree, tree));
+static tree try_class_unification PROTO((tree, tree, tree, tree));
+static int coerce_template_template_parms PROTO((tree, tree, int,
+ tree, tree));
+static tree determine_specialization PROTO((tree, tree, tree *, int));
+static int template_args_equal PROTO((tree, tree));
+static void print_template_context PROTO((int));
/* We use TREE_VECs to hold template arguments. If there is only one
level of template arguments, then the TREE_VEC contains the
@@ -254,7 +275,7 @@ finish_member_template_decl (decl)
that, for example, `template_class_depth (current_class_type)' is
always safe. */
-int
+static int
template_class_depth_real (type, count_specializations)
tree type;
int count_specializations;
@@ -351,10 +372,15 @@ push_inline_template_parms_recursive (parmlist, levels)
case PARM_DECL:
{
- /* Make a CONST_DECL as is done in process_template_parm. */
+ /* Make a CONST_DECL as is done in process_template_parm.
+ It is ugly that we recreate this here; the original
+ version built in process_template_parm is no longer
+ available. */
tree decl = build_decl (CONST_DECL, DECL_NAME (parm),
TREE_TYPE (parm));
+ SET_DECL_ARTIFICIAL (decl);
DECL_INITIAL (decl) = DECL_INITIAL (parm);
+ DECL_TEMPLATE_PARM_P (decl) = 1;
pushdecl (decl);
}
break;
@@ -420,14 +446,14 @@ maybe_end_member_template_processing ()
template <class T> class C { template <class U> void f(U); }
then neither C<int>::f<char> nor C<T>::f<double> is considered
- to be a member template. */
+ to be a member template. But, `template <class U> void
+ C<int>::f(U)' is considered a member template. */
int
is_member_template (t)
tree t;
{
- if (TREE_CODE (t) != FUNCTION_DECL
- && !DECL_FUNCTION_TEMPLATE_P (t))
+ if (!DECL_FUNCTION_TEMPLATE_P (t))
/* Anything that isn't a function or a template function is
certainly not a member template. */
return 0;
@@ -436,33 +462,15 @@ is_member_template (t)
if (hack_decl_function_context (t))
return 0;
- if ((DECL_FUNCTION_MEMBER_P (t)
- && !DECL_TEMPLATE_SPECIALIZATION (t))
- || (TREE_CODE (t) == TEMPLATE_DECL
- && DECL_FUNCTION_MEMBER_P (DECL_TEMPLATE_RESULT (t))))
- {
- tree tmpl;
-
- if (DECL_FUNCTION_TEMPLATE_P (t))
- tmpl = t;
- else if (DECL_TEMPLATE_INFO (t)
- && DECL_FUNCTION_TEMPLATE_P (DECL_TI_TEMPLATE (t)))
- tmpl = DECL_TI_TEMPLATE (t);
- else
- tmpl = NULL_TREE;
-
- if (tmpl
+ return (DECL_FUNCTION_MEMBER_P (DECL_TEMPLATE_RESULT (t))
/* If there are more levels of template parameters than
there are template classes surrounding the declaration,
then we have a member template. */
- && (TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (tmpl)) >
- template_class_depth (DECL_CLASS_CONTEXT (t))))
- return 1;
- }
-
- return 0;
+ && (TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (t)) >
+ template_class_depth (DECL_CLASS_CONTEXT (t))));
}
+#if 0 /* UNUSED */
/* Returns non-zero iff T is a member template class. See
is_member_template for a description of what precisely constitutes
a member template. */
@@ -487,6 +495,7 @@ is_member_template_class (t)
return (TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (t)) >
template_class_depth (DECL_CONTEXT (t)));
}
+#endif
/* Return a new template argument vector which contains all of ARGS,
but has as its innermost set of arguments the EXTRA_ARGS. The
@@ -580,7 +589,7 @@ begin_template_parm_list ()
/* This routine is called when a specialization is declared. If it is
illegal to declare a specialization here, an error is reported. */
-void
+static void
check_specialization_scope ()
{
tree scope = current_scope ();
@@ -677,6 +686,13 @@ maybe_process_partial_specialization (type)
if (CLASSTYPE_IMPLICIT_INSTANTIATION (type)
&& TYPE_SIZE (type) == NULL_TREE)
{
+ if (current_namespace
+ != decl_namespace_context (CLASSTYPE_TI_TEMPLATE (type)))
+ {
+ cp_pedwarn ("specializing `%#T' in different namespace", type);
+ cp_pedwarn_at (" from definition of `%#D'",
+ CLASSTYPE_TI_TEMPLATE (type));
+ }
SET_CLASSTYPE_TEMPLATE_SPECIALIZATION (type);
if (processing_template_decl)
push_template_decl (TYPE_MAIN_DECL (type));
@@ -684,6 +700,8 @@ maybe_process_partial_specialization (type)
else if (CLASSTYPE_TEMPLATE_INSTANTIATION (type))
cp_error ("specialization of `%T' after instantiation", type);
}
+ else if (processing_specialization)
+ cp_error ("explicit specialization of non-template `%T'", type);
}
/* Retrieve the specialization (in the sense of [temp.spec] - a
@@ -742,8 +760,8 @@ is_specialization_of (decl, tmpl)
t != NULL_TREE;
t = CLASSTYPE_USE_TEMPLATE (t)
? TREE_TYPE (CLASSTYPE_TI_TEMPLATE (t)) : NULL_TREE)
- if (comptypes (TYPE_MAIN_VARIANT (t),
- TYPE_MAIN_VARIANT (TREE_TYPE (tmpl)), 1))
+ if (same_type_p (TYPE_MAIN_VARIANT (t),
+ TYPE_MAIN_VARIANT (TREE_TYPE (tmpl))))
return 1;
}
@@ -823,15 +841,22 @@ register_specialization (spec, tmpl, args)
We transform the existing DECL in place so that
any pointers to it become pointers to the
- updated declaration. */
- duplicate_decls (spec, TREE_VALUE (s));
- return TREE_VALUE (s);
+ updated declaration.
+
+ If there was a definition for the template, but
+ not for the specialization, we want this to
+ look as if there is no definition, and vice
+ versa. */
+ DECL_INITIAL (fn) = NULL_TREE;
+ duplicate_decls (spec, fn);
+
+ return fn;
}
}
else if (DECL_TEMPLATE_SPECIALIZATION (fn))
{
- duplicate_decls (spec, TREE_VALUE (s));
- return TREE_VALUE (s);
+ duplicate_decls (spec, fn);
+ return fn;
}
}
}
@@ -867,45 +892,53 @@ unregister_specialization (spec, tmpl)
/* Print the list of candidate FNS in an error message. */
-static void
+void
print_candidates (fns)
tree fns;
{
tree fn;
- char* str = "candidates are:";
+ const char *str = "candidates are:";
for (fn = fns; fn != NULL_TREE; fn = TREE_CHAIN (fn))
{
- cp_error_at ("%s %+#D", str, TREE_VALUE (fn));
+ tree f;
+
+ for (f = TREE_VALUE (fn); f; f = OVL_NEXT (f))
+ cp_error_at ("%s %+#D", str, OVL_CURRENT (f));
str = " ";
}
}
/* Returns the template (one of the functions given by TEMPLATE_ID)
which can be specialized to match the indicated DECL with the
- explicit template args given in TEMPLATE_ID. If
- NEED_MEMBER_TEMPLATE is true the function is a specialization of a
- member template. The template args (those explicitly specified and
- those deduced) are output in a newly created vector *TARGS_OUT. If
- it is impossible to determine the result, an error message is
- issued, unless COMPLAIN is 0. The DECL may be NULL_TREE if none is
- available. */
+ explicit template args given in TEMPLATE_ID. The DECL may be
+ NULL_TREE if none is available. In that case, the functions in
+ TEMPLATE_ID are non-members.
-tree
+ If NEED_MEMBER_TEMPLATE is non-zero the function is known to be a
+ specialization of a member template.
+
+ The template args (those explicitly specified and those deduced)
+ are output in a newly created vector *TARGS_OUT.
+
+ If it is impossible to determine the result, an error message is
+ issued. The error_mark_node is returned to indicate failure. */
+
+static tree
determine_specialization (template_id, decl, targs_out,
- need_member_template,
- complain)
+ need_member_template)
tree template_id;
tree decl;
tree* targs_out;
int need_member_template;
- int complain;
{
- tree fns, targs_in;
- tree templates = NULL_TREE;
tree fn;
- int i;
+ tree fns;
+ tree targs;
+ tree explicit_targs;
+ tree candidates = NULL_TREE;
+ tree templates = NULL_TREE;
*targs_out = NULL_TREE;
@@ -913,7 +946,7 @@ determine_specialization (template_id, decl, targs_out,
return error_mark_node;
fns = TREE_OPERAND (template_id, 0);
- targs_in = TREE_OPERAND (template_id, 1);
+ explicit_targs = TREE_OPERAND (template_id, 1);
if (fns == error_mark_node)
return error_mark_node;
@@ -927,99 +960,146 @@ determine_specialization (template_id, decl, targs_out,
tree tmpl;
fn = OVL_CURRENT (fns);
- if (!need_member_template
- && TREE_CODE (fn) == FUNCTION_DECL
- && DECL_FUNCTION_MEMBER_P (fn)
- && DECL_USE_TEMPLATE (fn)
- && DECL_TI_TEMPLATE (fn))
- /* We can get here when processing something like:
- template <class T> class X { void f(); }
- template <> void X<int>::f() {}
- We're specializing a member function, but not a member
- template. */
- tmpl = DECL_TI_TEMPLATE (fn);
- else if (TREE_CODE (fn) != TEMPLATE_DECL
- || (need_member_template && !is_member_template (fn)))
+
+ if (TREE_CODE (fn) == TEMPLATE_DECL)
+ /* DECL might be a specialization of FN. */
+ tmpl = fn;
+ else if (need_member_template)
+ /* FN is an ordinary member function, and we need a
+ specialization of a member template. */
+ continue;
+ else if (TREE_CODE (fn) != FUNCTION_DECL)
+ /* We can get IDENTIFIER_NODEs here in certain erroneous
+ cases. */
+ continue;
+ else if (!DECL_FUNCTION_MEMBER_P (fn))
+ /* This is just an ordinary non-member function. Nothing can
+ be a specialization of that. */
continue;
else
- tmpl = fn;
+ {
+ tree decl_arg_types;
- if (list_length (targs_in) > DECL_NTPARMS (tmpl))
- continue;
+ /* This is an ordinary member function. However, since
+ we're here, we can assume it's enclosing class is a
+ template class. For example,
+
+ template <typename T> struct S { void f(); };
+ template <> void S<int>::f() {}
- if (decl == NULL_TREE)
- {
- tree targs = make_scratch_vec (DECL_NTPARMS (tmpl));
-
- /* We allow incomplete unification here, because we are going to
- check all the functions. */
- i = type_unification (DECL_INNERMOST_TEMPLATE_PARMS (tmpl),
- targs,
- NULL_TREE,
- NULL_TREE,
- targs_in,
- DEDUCE_EXACT, 1);
-
- if (i == 0)
- /* Unification was successful. */
- templates = scratch_tree_cons (targs, tmpl, templates);
- }
- else
- templates = scratch_tree_cons (NULL_TREE, tmpl, templates);
- }
-
- if (decl != NULL_TREE)
- {
- tree tmpl = most_specialized (templates, decl, targs_in);
- tree inner_args;
- tree tmpl_args;
+ Here, S<int>::f is a non-template, but S<int> is a
+ template class. If FN has the same type as DECL, we
+ might be in business. */
+ if (!same_type_p (TREE_TYPE (TREE_TYPE (decl)),
+ TREE_TYPE (TREE_TYPE (fn))))
+ /* The return types differ. */
+ continue;
+
+ /* Adjust the type of DECL in case FN is a static member. */
+ decl_arg_types = TYPE_ARG_TYPES (TREE_TYPE (decl));
+ if (DECL_STATIC_FUNCTION_P (fn)
+ && DECL_NONSTATIC_MEMBER_FUNCTION_P (decl))
+ decl_arg_types = TREE_CHAIN (decl_arg_types);
- if (tmpl == error_mark_node)
- goto ambiguous;
- else if (tmpl == NULL_TREE)
- goto no_match;
+ if (compparms (TYPE_ARG_TYPES (TREE_TYPE (fn)),
+ decl_arg_types))
+ /* They match! */
+ candidates = tree_cons (NULL_TREE, fn, candidates);
- inner_args = get_bindings (tmpl, decl, targs_in);
- tmpl_args = DECL_TI_ARGS (DECL_RESULT (tmpl));
- if (TMPL_ARGS_HAVE_MULTIPLE_LEVELS (tmpl_args))
- {
- *targs_out = copy_node (tmpl_args);
- SET_TMPL_ARGS_LEVEL (*targs_out,
- TMPL_ARGS_DEPTH (*targs_out),
- inner_args);
+ continue;
}
- else
- *targs_out = inner_args;
-
- return tmpl;
+
+ /* See whether this function might be a specialization of this
+ template. */
+ targs = get_bindings (tmpl, decl, explicit_targs);
+
+ if (!targs)
+ /* We cannot deduce template arguments that when used to
+ specialize TMPL will produce DECL. */
+ continue;
+
+ /* Save this template, and the arguments deduced. */
+ templates = scratch_tree_cons (targs, tmpl, templates);
}
- if (templates == NULL_TREE)
+ if (templates && TREE_CHAIN (templates))
{
- no_match:
- if (complain)
- {
- cp_error_at ("template-id `%D' for `%+D' does not match any template declaration",
- template_id, decl);
- return error_mark_node;
- }
- return NULL_TREE;
+ /* We have:
+
+ [temp.expl.spec]
+
+ It is possible for a specialization with a given function
+ signature to be instantiated from more than one function
+ template. In such cases, explicit specification of the
+ template arguments must be used to uniquely identify the
+ function template specialization being specialized.
+
+ Note that here, there's no suggestion that we're supposed to
+ determine which of the candidate templates is most
+ specialized. However, we, also have:
+
+ [temp.func.order]
+
+ Partial ordering of overloaded function template
+ declarations is used in the following contexts to select
+ the function template to which a function template
+ specialization refers:
+
+ -- when an explicit specialization refers to a function
+ template.
+
+ So, we do use the partial ordering rules, at least for now.
+ This extension can only serve to make illegal programs legal,
+ so it's safe. And, there is strong anecdotal evidence that
+ the committee intended the partial ordering rules to apply;
+ the EDG front-end has that behavior, and John Spicer claims
+ that the committee simply forgot to delete the wording in
+ [temp.expl.spec]. */
+ tree tmpl = most_specialized (templates, decl, explicit_targs);
+ if (tmpl && tmpl != error_mark_node)
+ {
+ targs = get_bindings (tmpl, decl, explicit_targs);
+ templates = scratch_tree_cons (targs, tmpl, NULL_TREE);
+ }
}
- else if (TREE_CHAIN (templates) != NULL_TREE)
+
+ if (templates == NULL_TREE && candidates == NULL_TREE)
{
- ambiguous:
- if (complain)
- {
- cp_error_at ("ambiguous template specialization `%D' for `%+D'",
- template_id, decl);
- print_candidates (templates);
- return error_mark_node;
- }
- return NULL_TREE;
+ cp_error_at ("template-id `%D' for `%+D' does not match any template declaration",
+ template_id, decl);
+ return error_mark_node;
+ }
+ else if ((templates && TREE_CHAIN (templates))
+ || (candidates && TREE_CHAIN (candidates))
+ || (templates && candidates))
+ {
+ cp_error_at ("ambiguous template specialization `%D' for `%+D'",
+ template_id, decl);
+ chainon (candidates, templates);
+ print_candidates (candidates);
+ return error_mark_node;
}
/* We have one, and exactly one, match. */
- *targs_out = TREE_PURPOSE (templates);
+ if (candidates)
+ {
+ /* It was a specialization of an ordinary member function in a
+ template class. */
+ *targs_out = copy_node (DECL_TI_ARGS (TREE_VALUE (candidates)));
+ return DECL_TI_TEMPLATE (TREE_VALUE (candidates));
+ }
+
+ /* It was a specialization of a template. */
+ targs = DECL_TI_ARGS (DECL_RESULT (TREE_VALUE (templates)));
+ if (TMPL_ARGS_HAVE_MULTIPLE_LEVELS (targs))
+ {
+ *targs_out = copy_node (targs);
+ SET_TMPL_ARGS_LEVEL (*targs_out,
+ TMPL_ARGS_DEPTH (*targs_out),
+ TREE_PURPOSE (templates));
+ }
+ else
+ *targs_out = TREE_PURPOSE (templates);
return TREE_VALUE (templates);
}
@@ -1029,7 +1109,9 @@ determine_specialization (template_id, decl, targs_out,
instantiation at this point.
Returns DECL, or an equivalent declaration that should be used
- instead.
+ instead if all goes well. Issues an error message if something is
+ amiss. Returns error_mark_node if the error is not easily
+ recoverable.
FLAGS is a bitmask consisting of the following flags:
@@ -1083,10 +1165,9 @@ check_explicit_specialization (declarator, decl, template_count, flags)
/* There were more template headers than qualifying template
classes. */
if (template_header_count - template_count > 1)
- /* There shouldn't be that many template parameter
- lists. There can be at most one parameter list for
- every qualifying class, plus one for the function
- itself. */
+ /* There shouldn't be that many template parameter lists.
+ There can be at most one parameter list for every
+ qualifying class, plus one for the function itself. */
cp_error ("too many template parameter lists in declaration of `%D'", decl);
SET_DECL_TEMPLATE_SPECIALIZATION (decl);
@@ -1194,6 +1275,8 @@ check_explicit_specialization (declarator, decl, template_count, flags)
("default argument specified in explicit specialization");
break;
}
+ if (current_lang_name == lang_name_c)
+ cp_error ("template specialization with C linkage");
}
if (specialization || member_specialization || explicit_instantiation)
@@ -1264,8 +1347,9 @@ check_explicit_specialization (declarator, decl, template_count, flags)
/* Find the list of functions in ctype that have the same
name as the declared function. */
tree name = TREE_OPERAND (declarator, 0);
- tree fns;
-
+ tree fns = NULL_TREE;
+ int idx;
+
if (name == constructor_name (ctype)
|| name == constructor_name_full (ctype))
{
@@ -1283,21 +1367,52 @@ check_explicit_specialization (declarator, decl, template_count, flags)
Similar language is found in [temp.explicit]. */
cp_error ("specialization of implicitly-declared special member function");
-
- return decl;
+ return error_mark_node;
}
name = is_constructor ? ctor_identifier : dtor_identifier;
}
- fns = lookup_fnfields (TYPE_BINFO (ctype), name, 1);
-
+ if (!IDENTIFIER_TYPENAME_P (name))
+ {
+ idx = lookup_fnfields_1 (ctype, name);
+ if (idx >= 0)
+ fns = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (ctype), idx);
+ }
+ else
+ {
+ tree methods;
+
+ /* For a type-conversion operator, we cannot do a
+ name-based lookup. We might be looking for `operator
+ int' which will be a specialization of `operator T'.
+ So, we find *all* the conversion operators, and then
+ select from them. */
+ fns = NULL_TREE;
+
+ methods = CLASSTYPE_METHOD_VEC (ctype);
+ if (methods)
+ for (idx = 2; idx < TREE_VEC_LENGTH (methods); ++idx)
+ {
+ tree ovl = TREE_VEC_ELT (methods, idx);
+
+ if (!ovl || !DECL_CONV_FN_P (OVL_CURRENT (ovl)))
+ /* There are no more conversion functions. */
+ break;
+
+ /* Glue all these conversion functions together
+ with those we already have. */
+ for (; ovl; ovl = OVL_NEXT (ovl))
+ fns = ovl_cons (OVL_CURRENT (ovl), fns);
+ }
+ }
+
if (fns == NULL_TREE)
{
cp_error ("no member function `%s' declared in `%T'",
IDENTIFIER_POINTER (name),
ctype);
- return decl;
+ return error_mark_node;
}
else
TREE_OPERAND (declarator, 0) = fns;
@@ -1313,10 +1428,13 @@ check_explicit_specialization (declarator, decl, template_count, flags)
declaration. */
tmpl = determine_specialization (declarator, decl,
&targs,
- member_specialization,
- 1);
+ member_specialization);
- if (tmpl && tmpl != error_mark_node)
+ if (!tmpl || tmpl == error_mark_node)
+ /* We couldn't figure out what this declaration was
+ specializing. */
+ return error_mark_node;
+ else
{
gen_tmpl = most_general_template (tmpl);
@@ -1365,13 +1483,11 @@ check_explicit_specialization (declarator, decl, template_count, flags)
/* This is not really a declaration of a specialization.
It's just the name of an instantiation. But, it's not
a request for an instantiation, either. */
- SET_DECL_IMPLICIT_INSTANTIATION (decl);
+ SET_DECL_IMPLICIT_INSTANTIATION (decl);
/* Register this specialization so that we can find it
again. */
decl = register_specialization (decl, gen_tmpl, targs);
-
- return decl;
}
}
@@ -1460,8 +1576,7 @@ int comp_template_parms (parms1, parms2)
if (TREE_CODE (parm1) == TEMPLATE_TYPE_PARM)
continue;
- else if (!comptypes (TREE_TYPE (parm1),
- TREE_TYPE (parm2), 1))
+ else if (!same_type_p (TREE_TYPE (parm1), TREE_TYPE (parm2)))
return 0;
}
}
@@ -1474,36 +1589,32 @@ int comp_template_parms (parms1, parms2)
return 1;
}
+/* Complain if DECL shadows a template parameter.
-/* Returns 1 iff old_id is a template parameter. OLD_DECL is the decl
- from IDENTIFIER_LOCAL_VALUE (new identifier). */
+ [temp.local]: A template-parameter shall not be redeclared within its
+ scope (including nested scopes). */
-int decl_template_parm_p (old_decl)
- tree old_decl;
+void
+check_template_shadow (decl)
+ tree decl;
{
- /* For template template parms. */
- if (TREE_CODE (old_decl) == TEMPLATE_DECL
- && TREE_TYPE (old_decl)
- && TREE_CODE (TREE_TYPE (old_decl)) == TEMPLATE_TEMPLATE_PARM)
- return 1;
-
- /* For template type parms. */
- if (TREE_CODE (old_decl) == TYPE_DECL
- && TREE_TYPE (old_decl)
- && TREE_CODE (TREE_TYPE (old_decl)) == TEMPLATE_TYPE_PARM)
- return 1;
-
- /* For template non-type parms. */
- if (TREE_CODE (old_decl) == CONST_DECL
- && DECL_INITIAL (old_decl)
- && TREE_CODE (DECL_INITIAL (old_decl)) == TEMPLATE_PARM_INDEX)
- return 1;
+ tree olddecl = IDENTIFIER_VALUE (DECL_NAME (decl));
- return 0;
+ if (current_template_parms && olddecl)
+ {
+ /* We check for decl != olddecl to avoid bogus errors for using a
+ name inside a class. We check TPFI to avoid duplicate errors for
+ inline member templates. */
+ if (decl != olddecl && DECL_TEMPLATE_PARM_P (olddecl)
+ && ! TEMPLATE_PARMS_FOR_INLINE (current_template_parms))
+ {
+ cp_error_at ("declaration of `%#D'", decl);
+ cp_error_at (" shadows template parm `%#D'", olddecl);
+ }
+ }
}
-
- /* Return a new TEMPLATE_PARM_INDEX with the indicated INDEX, LEVEL,
+/* Return a new TEMPLATE_PARM_INDEX with the indicated INDEX, LEVEL,
ORIG_LEVEL, DECL, and TYPE. */
static tree
@@ -1597,6 +1708,13 @@ process_template_parm (list, next)
/* is a const-param */
parm = grokdeclarator (TREE_VALUE (parm), TREE_PURPOSE (parm),
PARM, 0, NULL_TREE);
+
+ /* [temp.param]
+
+ The top-level cv-qualifiers on the template-parameter are
+ ignored when determining its type. */
+ TREE_TYPE (parm) = TYPE_MAIN_VARIANT (TREE_TYPE (parm));
+
/* A template parameter is not modifiable. */
TREE_READONLY (parm) = 1;
if (IS_AGGR_TYPE (TREE_TYPE (parm))
@@ -1646,7 +1764,6 @@ process_template_parm (list, next)
decl = build_decl (TYPE_DECL, parm, t);
}
- CLASSTYPE_GOT_SEMICOLON (t) = 1;
TYPE_NAME (t) = decl;
TYPE_STUB_DECL (t) = decl;
parm = decl;
@@ -1656,6 +1773,7 @@ process_template_parm (list, next)
decl, TREE_TYPE (parm));
}
SET_DECL_ARTIFICIAL (decl);
+ DECL_TEMPLATE_PARM_P (decl) = 1;
pushdecl (decl);
parm = build_tree_list (defval, parm);
return chainon (list, parm);
@@ -1837,7 +1955,7 @@ mark_template_parm (t, data)
/* Process the partial specialization DECL. */
-tree
+static tree
process_partial_specialization (decl)
tree decl;
{
@@ -1851,28 +1969,9 @@ process_partial_specialization (decl)
int ntparms = TREE_VEC_LENGTH (inner_parms);
int i;
int did_error_intro = 0;
- int issued_default_arg_message = 0;
struct template_parm_data tpd;
struct template_parm_data tpd2;
- /* [temp.class.spec]
-
- The template parameter list of a specialization shall not
- contain default template argument values. */
- for (i = 0; i < ntparms; ++i)
- {
- if (TREE_PURPOSE (TREE_VEC_ELT (inner_parms, i)))
- {
- if (!issued_default_arg_message)
- {
- cp_error ("default argument in partial specialization `%T'",
- type);
- issued_default_arg_message = 1;
- }
- TREE_PURPOSE (TREE_VEC_ELT (inner_parms, i)) = NULL_TREE;
- }
- }
-
/* We check that each of the template parameters given in the
partial specialization is used in the argument list to the
specialization. For example:
@@ -1905,10 +2004,10 @@ process_partial_specialization (decl)
or some such would have been OK. */
tpd.level = TMPL_PARMS_DEPTH (current_template_parms);
tpd.parms = alloca (sizeof (int) * ntparms);
- bzero (tpd.parms, sizeof (int) * ntparms);
+ bzero ((PTR) tpd.parms, sizeof (int) * ntparms);
tpd.arg_uses_template_parms = alloca (sizeof (int) * nargs);
- bzero (tpd.arg_uses_template_parms, sizeof (int) * nargs);
+ bzero ((PTR) tpd.arg_uses_template_parms, sizeof (int) * nargs);
for (i = 0; i < nargs; ++i)
{
tpd.current_arg = i;
@@ -1978,7 +2077,7 @@ process_partial_specialization (decl)
/* We haven't yet initialized TPD2. Do so now. */
tpd2.arg_uses_template_parms
= (int*) alloca (sizeof (int) * nargs);
- /* The number of paramters here is the number in the
+ /* The number of parameters here is the number in the
main template, which, as checked in the assertion
above, is NARGS. */
tpd2.parms = (int*) alloca (sizeof (int) * nargs);
@@ -1986,12 +2085,12 @@ process_partial_specialization (decl)
TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (maintmpl));
}
- /* Mark the template paramters. But this time, we're
+ /* Mark the template parameters. But this time, we're
looking for the template parameters of the main
template, not in the specialization. */
tpd2.current_arg = i;
tpd2.arg_uses_template_parms[i] = 0;
- bzero (tpd2.parms, sizeof (int) * nargs);
+ bzero ((PTR) tpd2.parms, sizeof (int) * nargs);
for_each_template_parm (type,
&mark_template_parm,
&tpd2);
@@ -2006,7 +2105,7 @@ process_partial_specialization (decl)
if (tpd2.parms[j] != 0
&& tpd.arg_uses_template_parms [j])
{
- cp_error ("type `%T' of template argument `%E' depends on template paramter(s)",
+ cp_error ("type `%T' of template argument `%E' depends on template parameter(s)",
type,
arg);
break;
@@ -2027,6 +2126,107 @@ process_partial_specialization (decl)
return decl;
}
+/* Check that a template declaration's use of default arguments is not
+ invalid. Here, PARMS are the template parameters. IS_PRIMARY is
+ non-zero if DECL is the thing declared by a primary template.
+ IS_PARTIAL is non-zero if DECL is a partial specialization. */
+
+static void
+check_default_tmpl_args (decl, parms, is_primary, is_partial)
+ tree decl;
+ tree parms;
+ int is_primary;
+ int is_partial;
+{
+ const char *msg;
+ int last_level_to_check;
+
+ /* [temp.param]
+
+ A default template-argument shall not be specified in a
+ function template declaration or a function template definition, nor
+ in the template-parameter-list of the definition of a member of a
+ class template. */
+
+ if (current_class_type
+ && !TYPE_BEING_DEFINED (current_class_type)
+ && DECL_REAL_CONTEXT (decl) == current_class_type
+ && DECL_DEFINED_IN_CLASS_P (decl))
+ /* We already checked these parameters when the template was
+ declared, so there's no need to do it again now. This is an
+ inline member function definition. */
+ return;
+
+ if (TREE_CODE (decl) != TYPE_DECL || is_partial || !is_primary)
+ /* For an ordinary class template, default template arguments are
+ allowed at the innermost level, e.g.:
+ template <class T = int>
+ struct S {};
+ but, in a partial specialization, they're not allowed even
+ there, as we have in [temp.class.spec]:
+
+ The template parameter list of a specialization shall not
+ contain default template argument values.
+
+ So, for a partial specialization, or for a function template,
+ we look at all of them. */
+ ;
+ else
+ /* But, for a primary class template that is not a partial
+ specialization we look at all template parameters except the
+ innermost ones. */
+ parms = TREE_CHAIN (parms);
+
+ /* Figure out what error message to issue. */
+ if (TREE_CODE (decl) == FUNCTION_DECL)
+ msg = "default argument for template parameter in function template `%D'";
+ else if (is_partial)
+ msg = "default argument in partial specialization `%D'";
+ else
+ msg = "default argument for template parameter for class enclosing `%D'";
+
+ if (current_class_type && TYPE_BEING_DEFINED (current_class_type))
+ /* If we're inside a class definition, there's no need to
+ examine the parameters to the class itself. On the one
+ hand, they will be checked when the class is defined, and,
+ on the other, default arguments are legal in things like:
+ template <class T = double>
+ struct S { template <class U> void f(U); };
+ Here the default argument for `S' has no bearing on the
+ declaration of `f'. */
+ last_level_to_check = template_class_depth (current_class_type) + 1;
+ else
+ /* Check everything. */
+ last_level_to_check = 0;
+
+ for (; parms && TMPL_PARMS_DEPTH (parms) >= last_level_to_check;
+ parms = TREE_CHAIN (parms))
+ {
+ tree inner_parms = TREE_VALUE (parms);
+ int i, ntparms;
+
+ ntparms = TREE_VEC_LENGTH (inner_parms);
+ for (i = 0; i < ntparms; ++i)
+ if (TREE_PURPOSE (TREE_VEC_ELT (inner_parms, i)))
+ {
+ if (msg)
+ {
+ cp_error (msg, decl);
+ msg = 0;
+ }
+
+ /* Clear out the default argument so that we are not
+ confused later. */
+ TREE_PURPOSE (TREE_VEC_ELT (inner_parms, i)) = NULL_TREE;
+ }
+
+ /* At this point, if we're still interested in issuing messages,
+ they must apply to classes surrounding the object declared. */
+ if (msg)
+ msg = "default argument for template parameter for class enclosing `%D'";
+ }
+}
+
/* Creates a TEMPLATE_DECL for the indicated DECL using the template
parameters given by current_template_args, or reuses a
previously existing one, if appropriate. Returns the DECL, or an
@@ -2044,6 +2244,12 @@ push_template_decl_real (decl, is_friend)
tree info;
tree ctx;
int primary;
+ int is_partial;
+
+ /* See if this is a partial specialization. */
+ is_partial = (TREE_CODE (decl) == TYPE_DECL && DECL_ARTIFICIAL (decl)
+ && TREE_CODE (TREE_TYPE (decl)) != ENUMERAL_TYPE
+ && CLASSTYPE_TEMPLATE_SPECIALIZATION (TREE_TYPE (decl)));
is_friend |= (TREE_CODE (decl) == FUNCTION_DECL && DECL_FRIEND_P (decl));
@@ -2074,6 +2280,7 @@ push_template_decl_real (decl, is_friend)
else
info = ctx;
+ /* See if this is a primary template. */
if (info && TREE_CODE (info) == FUNCTION_DECL)
primary = 0;
/* Note that template_class_depth returns 0 if given NULL_TREE, so
@@ -2094,10 +2301,12 @@ push_template_decl_real (decl, is_friend)
cp_error ("template declaration of `%#T'", TREE_TYPE (decl));
}
- /* Partial specialization. */
- if (TREE_CODE (decl) == TYPE_DECL && DECL_ARTIFICIAL (decl)
- && TREE_CODE (TREE_TYPE (decl)) != ENUMERAL_TYPE
- && CLASSTYPE_TEMPLATE_SPECIALIZATION (TREE_TYPE (decl)))
+ /* Check to see that the rules regarding the use of default
+ arguments are not being violated. */
+ check_default_tmpl_args (decl, current_template_parms,
+ primary, is_partial);
+
+ if (is_partial)
return process_partial_specialization (decl);
args = current_template_args ();
@@ -2128,8 +2337,8 @@ push_template_decl_real (decl, is_friend)
}
else
{
- tree t;
- tree a;
+ tree a, t, current, parms;
+ int i;
if (CLASSTYPE_TEMPLATE_INSTANTIATION (ctx))
cp_error ("must specialize `%#T' before defining member `%#D'",
@@ -2155,75 +2364,67 @@ push_template_decl_real (decl, is_friend)
else
tmpl = DECL_TI_TEMPLATE (decl);
- if (is_member_template (tmpl) || is_member_template_class (tmpl))
+ if (is_member_template (tmpl)
+ && DECL_FUNCTION_TEMPLATE_P (tmpl)
+ && DECL_TEMPLATE_INFO (decl) && DECL_TI_ARGS (decl)
+ && DECL_TEMPLATE_SPECIALIZATION (decl))
{
- if (DECL_FUNCTION_TEMPLATE_P (tmpl)
- && DECL_TEMPLATE_INFO (decl) && DECL_TI_ARGS (decl)
- && DECL_TEMPLATE_SPECIALIZATION (decl))
- {
- tree new_tmpl;
-
- /* The declaration is a specialization of a member
- template, declared outside the class. Therefore, the
- innermost template arguments will be NULL, so we
- replace them with the arguments determined by the
- earlier call to check_explicit_specialization. */
- args = DECL_TI_ARGS (decl);
-
- new_tmpl
- = build_template_decl (decl, current_template_parms);
- DECL_TEMPLATE_RESULT (new_tmpl) = decl;
- TREE_TYPE (new_tmpl) = TREE_TYPE (decl);
- DECL_TI_TEMPLATE (decl) = new_tmpl;
- SET_DECL_TEMPLATE_SPECIALIZATION (new_tmpl);
- DECL_TEMPLATE_INFO (new_tmpl) =
- perm_tree_cons (tmpl, args, NULL_TREE);
-
- register_specialization (new_tmpl, tmpl, args);
- return decl;
- }
-
- a = innermost_args (args);
- t = DECL_INNERMOST_TEMPLATE_PARMS (tmpl);
- if (TREE_VEC_LENGTH (t) != TREE_VEC_LENGTH (a))
- {
- cp_error ("got %d template parameters for `%#D'",
- TREE_VEC_LENGTH (a), decl);
- cp_error (" but %d required", TREE_VEC_LENGTH (t));
- }
- if (TMPL_ARGS_DEPTH (args) > 1)
- /* Get the template parameters for the enclosing template
- class. */
- a = TMPL_ARGS_LEVEL (args, TMPL_ARGS_DEPTH (args) - 1);
- else
- a = NULL_TREE;
+ tree new_tmpl;
+
+ /* The declaration is a specialization of a member
+ template, declared outside the class. Therefore, the
+ innermost template arguments will be NULL, so we
+ replace them with the arguments determined by the
+ earlier call to check_explicit_specialization. */
+ args = DECL_TI_ARGS (decl);
+
+ new_tmpl
+ = build_template_decl (decl, current_template_parms);
+ DECL_TEMPLATE_RESULT (new_tmpl) = decl;
+ TREE_TYPE (new_tmpl) = TREE_TYPE (decl);
+ DECL_TI_TEMPLATE (decl) = new_tmpl;
+ SET_DECL_TEMPLATE_SPECIALIZATION (new_tmpl);
+ DECL_TEMPLATE_INFO (new_tmpl) =
+ perm_tree_cons (tmpl, args, NULL_TREE);
+
+ register_specialization (new_tmpl, tmpl, args);
+ return decl;
}
- else
- a = innermost_args (args);
- t = NULL_TREE;
+ /* Make sure the template headers we got make sense. */
- if (CLASSTYPE_TEMPLATE_SPECIALIZATION (ctx))
+ parms = DECL_TEMPLATE_PARMS (tmpl);
+ i = TMPL_PARMS_DEPTH (parms);
+ if (TMPL_ARGS_DEPTH (args) != i)
{
- /* When processing an inline member template of a
- specialized class, there is no CLASSTYPE_TI_SPEC_INFO. */
- if (CLASSTYPE_TI_SPEC_INFO (ctx))
- t = TREE_VALUE (CLASSTYPE_TI_SPEC_INFO (ctx));
+ cp_error ("expected %d levels of template parms for `%#D', got %d",
+ i, decl, TMPL_ARGS_DEPTH (args));
}
- else if (CLASSTYPE_TEMPLATE_INFO (ctx))
- t = DECL_INNERMOST_TEMPLATE_PARMS (CLASSTYPE_TI_TEMPLATE (ctx));
+ else
+ for (current = decl; i > 0; --i, parms = TREE_CHAIN (parms))
+ {
+ a = TMPL_ARGS_LEVEL (args, i);
+ t = INNERMOST_TEMPLATE_PARMS (parms);
- /* There should be template arguments if and only if there is a
- template class. */
- my_friendly_assert((a != NULL_TREE) == (t != NULL_TREE), 0);
+ if (TREE_VEC_LENGTH (t) != TREE_VEC_LENGTH (a))
+ {
+ if (current == decl)
+ cp_error ("got %d template parameters for `%#D'",
+ TREE_VEC_LENGTH (a), decl);
+ else
+ cp_error ("got %d template parameters for `%#T'",
+ TREE_VEC_LENGTH (a), current);
+ cp_error (" but %d required", TREE_VEC_LENGTH (t));
+ }
- if (t != NULL_TREE
- && TREE_VEC_LENGTH (t) != TREE_VEC_LENGTH (a))
- {
- cp_error ("got %d template parameters for `%#D'",
- TREE_VEC_LENGTH (a), decl);
- cp_error (" but `%#T' has %d", ctx, TREE_VEC_LENGTH (t));
- }
+ /* Perhaps we should also check that the parms are used in the
+ appropriate qualifying scopes in the declarator? */
+
+ if (current == decl)
+ current = ctx;
+ else
+ current = TYPE_CONTEXT (current);
+ }
}
DECL_TEMPLATE_RESULT (tmpl) = decl;
@@ -2378,22 +2579,16 @@ convert_nontype_argument (type, expr)
Check this first since if expr_type is the unknown_type_node
we would otherwise complain below. */
;
- else if (INTEGRAL_TYPE_P (expr_type)
- || TYPE_PTRMEM_P (expr_type)
- || TYPE_PTRMEMFUNC_P (expr_type)
- /* The next two are g++ extensions. */
- || TREE_CODE (expr_type) == REAL_TYPE
- || TREE_CODE (expr_type) == COMPLEX_TYPE)
+ else if (TYPE_PTRMEM_P (expr_type)
+ || TYPE_PTRMEMFUNC_P (expr_type))
{
- if (! TREE_CONSTANT (expr))
- {
- non_constant:
- cp_error ("non-constant `%E' cannot be used as template argument",
- expr);
- return NULL_TREE;
- }
+ if (TREE_CODE (expr) != PTRMEM_CST)
+ goto bad_argument;
}
- else if (TYPE_PTR_P (expr_type)
+ else if (TYPE_PTR_P (expr_type)
+ || TYPE_PTRMEM_P (expr_type)
+ || TREE_CODE (expr_type) == ARRAY_TYPE
+ || TREE_CODE (type) == REFERENCE_TYPE
/* If expr is the address of an overloaded function, we
will get the unknown_type_node at this point. */
|| expr_type == unknown_type_node)
@@ -2402,21 +2597,33 @@ convert_nontype_argument (type, expr)
tree e = expr;
STRIP_NOPS (e);
- if (TREE_CODE (e) != ADDR_EXPR)
+ if (TREE_CODE (type) == REFERENCE_TYPE
+ || TREE_CODE (expr_type) == ARRAY_TYPE)
+ referent = e;
+ else
{
- bad_argument:
- cp_error ("`%E' is not a valid template argument", expr);
- error ("it must be %s%s with external linkage",
- TREE_CODE (TREE_TYPE (expr)) == POINTER_TYPE
- ? "a pointer to " : "",
- TREE_CODE (TREE_TYPE (TREE_TYPE (expr))) == FUNCTION_TYPE
- ? "a function" : "an object");
- return NULL_TREE;
+ if (TREE_CODE (e) != ADDR_EXPR)
+ {
+ bad_argument:
+ cp_error ("`%E' is not a valid template argument", expr);
+ if (TYPE_PTR_P (expr_type))
+ {
+ if (TREE_CODE (TREE_TYPE (expr_type)) == FUNCTION_TYPE)
+ cp_error ("it must be the address of a function with external linkage");
+ else
+ cp_error ("it must be the address of an object with external linkage");
+ }
+ else if (TYPE_PTRMEM_P (expr_type)
+ || TYPE_PTRMEMFUNC_P (expr_type))
+ cp_error ("it must be a pointer-to-member of the form `&X::Y'");
+
+ return NULL_TREE;
+ }
+
+ referent = TREE_OPERAND (e, 0);
+ STRIP_NOPS (referent);
}
- referent = TREE_OPERAND (e, 0);
- STRIP_NOPS (referent);
-
if (TREE_CODE (referent) == STRING_CST)
{
cp_error ("string literal %E is not a valid template argument",
@@ -2436,10 +2643,20 @@ convert_nontype_argument (type, expr)
return error_mark_node;
}
}
- else if (TREE_CODE (expr) == VAR_DECL)
+ else if (INTEGRAL_TYPE_P (expr_type)
+ || TYPE_PTRMEM_P (expr_type)
+ || TYPE_PTRMEMFUNC_P (expr_type)
+ /* The next two are g++ extensions. */
+ || TREE_CODE (expr_type) == REAL_TYPE
+ || TREE_CODE (expr_type) == COMPLEX_TYPE)
{
- if (!TREE_PUBLIC (expr))
- goto bad_argument;
+ if (! TREE_CONSTANT (expr))
+ {
+ non_constant:
+ cp_error ("non-constant `%E' cannot be used as template argument",
+ expr);
+ return NULL_TREE;
+ }
}
else
{
@@ -2463,7 +2680,7 @@ convert_nontype_argument (type, expr)
expr = digest_init (type, expr, (tree*) 0);
if (TREE_CODE (expr) != INTEGER_CST)
- /* Curiously, some TREE_CONSTNAT integral expressions do not
+ /* Curiously, some TREE_CONSTANT integral expressions do not
simplify to integer constants. For example, `3 % 0',
remains a TRUNC_MOD_EXPR. */
goto non_constant;
@@ -2488,10 +2705,28 @@ convert_nontype_argument (type, expr)
tree type_pointed_to = TREE_TYPE (type);
if (TYPE_PTRMEM_P (type))
- /* For a non-type template-parameter of type pointer to data
- member, qualification conversions (_conv.qual_) are
- applied. */
- return perform_qualification_conversions (type, expr);
+ {
+ tree e;
+
+ /* For a non-type template-parameter of type pointer to data
+ member, qualification conversions (_conv.qual_) are
+ applied. */
+ e = perform_qualification_conversions (type, expr);
+ if (TREE_CODE (e) == NOP_EXPR)
+ {
+ /* The call to perform_qualification_conversions will
+ insert a NOP_EXPR over EXPR to do express
+ conversion, if necessary. But, that will confuse
+ us if we use this (converted) template parameter to
+ instantiate another template; then the thing will
+ not look like a valid template argument. So, just
+ make a new constant, of the appropriate type. */
+ e = make_node (PTRMEM_CST);
+ TREE_TYPE (e) = type;
+ PTRMEM_CST_MEMBER (e) = PTRMEM_CST_MEMBER (expr);
+ }
+ return e;
+ }
else if (TREE_CODE (type_pointed_to) == FUNCTION_TYPE)
{
/* For a non-type template-parameter of type pointer to
@@ -2523,7 +2758,7 @@ convert_nontype_argument (type, expr)
expr = build_unary_op (ADDR_EXPR, fn, 0);
- my_friendly_assert (comptypes (type, TREE_TYPE (expr), 1),
+ my_friendly_assert (same_type_p (type, TREE_TYPE (expr)),
0);
return expr;
}
@@ -2567,6 +2802,9 @@ convert_nontype_argument (type, expr)
fn = instantiate_type (type_referred_to, fns, 0);
+ if (fn == error_mark_node)
+ return error_mark_node;
+
if (!TREE_PUBLIC (fn))
{
if (really_overloaded_fn (fns))
@@ -2578,10 +2816,8 @@ convert_nontype_argument (type, expr)
goto bad_argument;
}
- if (fn == error_mark_node)
- return error_mark_node;
-
- my_friendly_assert (comptypes (type, TREE_TYPE (fn), 1),
+ my_friendly_assert (same_type_p (type_referred_to,
+ TREE_TYPE (fn)),
0);
return fn;
@@ -2594,12 +2830,10 @@ convert_nontype_argument (type, expr)
identical) type of the template-argument. The
template-parameter is bound directly to the
template-argument, which must be an lvalue. */
- if (!comptypes (TYPE_MAIN_VARIANT (expr_type),
- TYPE_MAIN_VARIANT (type), 1)
- || (TYPE_READONLY (expr_type) >
- TYPE_READONLY (type_referred_to))
- || (TYPE_VOLATILE (expr_type) >
- TYPE_VOLATILE (type_referred_to))
+ if ((TYPE_MAIN_VARIANT (expr_type)
+ != TYPE_MAIN_VARIANT (type_referred_to))
+ || !at_least_as_qualified_p (type_referred_to,
+ expr_type)
|| !real_lvalue_p (expr))
return error_mark_node;
else
@@ -2610,9 +2844,6 @@ convert_nontype_argument (type, expr)
case RECORD_TYPE:
{
- tree fns;
- tree fn;
-
if (!TYPE_PTRMEMFUNC_P (type))
/* This handles templates like
template<class T, T t> void f();
@@ -2631,10 +2862,10 @@ convert_nontype_argument (type, expr)
expr_type != unknown_type_node)
return error_mark_node;
- if (TREE_CODE (expr) == CONSTRUCTOR)
+ if (TREE_CODE (expr) == PTRMEM_CST)
{
/* A ptr-to-member constant. */
- if (!comptypes (type, expr_type, 1))
+ if (!same_type_p (type, expr_type))
return error_mark_node;
else
return expr;
@@ -2643,17 +2874,12 @@ convert_nontype_argument (type, expr)
if (TREE_CODE (expr) != ADDR_EXPR)
return error_mark_node;
- fns = TREE_OPERAND (expr, 0);
+ expr = instantiate_type (type, expr, 0);
- fn = instantiate_type (TREE_TYPE (TREE_TYPE (type)),
- fns, 0);
-
- if (fn == error_mark_node)
+ if (expr == error_mark_node)
return error_mark_node;
- expr = build_unary_op (ADDR_EXPR, fn, 0);
-
- my_friendly_assert (comptypes (type, TREE_TYPE (expr), 1),
+ my_friendly_assert (same_type_p (type, TREE_TYPE (expr)),
0);
return expr;
}
@@ -2686,8 +2912,11 @@ convert_nontype_argument (type, expr)
substitute the TT parameter. */
static int
-coerce_template_template_parms (parm_parms, arg_parms, in_decl, outer_args)
- tree parm_parms, arg_parms, in_decl, outer_args;
+coerce_template_template_parms (parm_parms, arg_parms, complain,
+ in_decl, outer_args)
+ tree parm_parms, arg_parms;
+ int complain;
+ tree in_decl, outer_args;
{
int nparms, nargs, i;
tree parm, arg;
@@ -2725,15 +2954,24 @@ coerce_template_template_parms (parm_parms, arg_parms, in_decl, outer_args)
/* We encounter instantiations of templates like
template <template <template <class> class> class TT>
class C; */
- sorry ("nested template template parameter");
- return 0;
+ {
+ tree parmparm = DECL_INNERMOST_TEMPLATE_PARMS (parm);
+ tree argparm = DECL_INNERMOST_TEMPLATE_PARMS (arg);
+
+ if (!coerce_template_template_parms (parmparm, argparm,
+ complain, in_decl,
+ outer_args))
+ return 0;
+ }
+ break;
case PARM_DECL:
/* The tsubst call is used to handle cases such as
template <class T, template <T> class TT> class D;
i.e. the parameter list of TT depends on earlier parameters. */
- if (!comptypes (tsubst (TREE_TYPE (parm), outer_args, in_decl),
- TREE_TYPE (arg), 1))
+ if (!same_type_p (tsubst (TREE_TYPE (parm), outer_args,
+ complain, in_decl),
+ TREE_TYPE (arg)))
return 0;
break;
@@ -2793,7 +3031,7 @@ convert_template_argument (parm, arg, args, complain, i, in_decl)
= ((TREE_CODE (arg) == TEMPLATE_DECL
&& TREE_CODE (DECL_TEMPLATE_RESULT (arg)) == TYPE_DECL)
|| (TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM
- && !CLASSTYPE_TEMPLATE_INFO (arg))
+ && !TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (arg))
|| (TREE_CODE (arg) == RECORD_TYPE
&& CLASSTYPE_TEMPLATE_INFO (arg)
&& TREE_CODE (TYPE_NAME (arg)) == TYPE_DECL
@@ -2856,7 +3094,7 @@ convert_template_argument (parm, arg, args, complain, i, in_decl)
tree parmparm = DECL_INNERMOST_TEMPLATE_PARMS (parm);
tree argparm = DECL_INNERMOST_TEMPLATE_PARMS (arg);
- if (coerce_template_template_parms (parmparm, argparm,
+ if (coerce_template_template_parms (parmparm, argparm, complain,
in_decl, inner_args))
{
val = arg;
@@ -2906,7 +3144,7 @@ convert_template_argument (parm, arg, args, complain, i, in_decl)
}
else
{
- tree t = tsubst (TREE_TYPE (parm), args, in_decl);
+ tree t = tsubst (TREE_TYPE (parm), args, complain, in_decl);
if (processing_template_decl)
arg = maybe_fold_nontype_arg (arg);
@@ -3013,9 +3251,10 @@ coerce_template_parms (parms, args, in_decl,
break;
}
else if (TREE_CODE (TREE_VALUE (parm)) == TYPE_DECL)
- arg = tsubst (TREE_PURPOSE (parm), new_args, in_decl);
+ arg = tsubst (TREE_PURPOSE (parm), new_args, complain, in_decl);
else
- arg = tsubst_expr (TREE_PURPOSE (parm), new_args, in_decl);
+ arg = tsubst_expr (TREE_PURPOSE (parm), new_args, complain,
+ in_decl);
/* Now, convert the Ith argument, as necessary. */
if (arg == NULL_TREE)
@@ -3045,7 +3284,26 @@ coerce_template_parms (parms, args, in_decl,
return new_inner_args;
}
-/* Renturns 1 iff the OLDARGS and NEWARGS are in fact identical sets
+/* Returns 1 if template args OT and NT are equivalent. */
+
+static int
+template_args_equal (ot, nt)
+ tree ot, nt;
+{
+ if (nt == ot)
+ return 1;
+ if (TREE_CODE (nt) != TREE_CODE (ot))
+ return 0;
+ if (TREE_CODE (nt) == TREE_VEC)
+ /* For member templates */
+ return comp_template_args (ot, nt);
+ else if (TREE_CODE_CLASS (TREE_CODE (ot)) == 't')
+ return same_type_p (ot, nt);
+ else
+ return (cp_tree_equal (ot, nt) > 0);
+}
+
+/* Returns 1 iff the OLDARGS and NEWARGS are in fact identical sets
of template arguments. Returns 0 otherwise. */
int
@@ -3062,26 +3320,8 @@ comp_template_args (oldargs, newargs)
tree nt = TREE_VEC_ELT (newargs, i);
tree ot = TREE_VEC_ELT (oldargs, i);
- if (nt == ot)
- continue;
- else if (!nt || !ot)
- return 0;
- else if (TREE_CODE (nt) != TREE_CODE (ot))
+ if (! template_args_equal (ot, nt))
return 0;
- else if (TREE_CODE (nt) == TREE_VEC)
- {
- /* For member templates */
- if (comp_template_args (ot, nt))
- continue;
- }
- else if (TREE_CODE_CLASS (TREE_CODE (ot)) == 't')
- {
- if (comptypes (ot, nt, 1))
- continue;
- }
- else if (cp_tree_equal (ot, nt) > 0)
- continue;
- return 0;
}
return 1;
}
@@ -3182,22 +3422,26 @@ classtype_mangled_name (t)
if (CLASSTYPE_TEMPLATE_INFO (t)
/* Specializations have already had their names set up in
lookup_template_class. */
- && !CLASSTYPE_TEMPLATE_SPECIALIZATION (t)
+ && !CLASSTYPE_TEMPLATE_SPECIALIZATION (t))
+ {
+ tree tmpl = most_general_template (CLASSTYPE_TI_TEMPLATE (t));
+
/* For non-primary templates, the template parameters are
implicit from their surrounding context. */
- && PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (t)))
- {
- tree name = DECL_NAME (CLASSTYPE_TI_TEMPLATE (t));
- char *mangled_name = mangle_class_name_for_template
- (IDENTIFIER_POINTER (name),
- DECL_INNERMOST_TEMPLATE_PARMS (CLASSTYPE_TI_TEMPLATE (t)),
- CLASSTYPE_TI_ARGS (t));
- tree id = get_identifier (mangled_name);
- IDENTIFIER_TEMPLATE (id) = name;
- return id;
+ if (PRIMARY_TEMPLATE_P (tmpl))
+ {
+ tree name = DECL_NAME (tmpl);
+ char *mangled_name = mangle_class_name_for_template
+ (IDENTIFIER_POINTER (name),
+ DECL_INNERMOST_TEMPLATE_PARMS (tmpl),
+ CLASSTYPE_TI_ARGS (t));
+ tree id = get_identifier (mangled_name);
+ IDENTIFIER_TEMPLATE (id) = name;
+ return id;
+ }
}
- else
- return TYPE_IDENTIFIER (t);
+
+ return TYPE_IDENTIFIER (t);
}
static void
@@ -3254,7 +3498,7 @@ lookup_template_function (fns, arglist)
return the associated TEMPLATE_DECL. Otherwise, the original
DECL is returned. */
-tree
+static tree
maybe_get_template_decl_from_type_decl (decl)
tree decl;
{
@@ -3297,9 +3541,9 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope)
if (TREE_CODE (d1) == IDENTIFIER_NODE)
{
- if (IDENTIFIER_LOCAL_VALUE (d1)
- && DECL_TEMPLATE_TEMPLATE_PARM_P (IDENTIFIER_LOCAL_VALUE (d1)))
- template = IDENTIFIER_LOCAL_VALUE (d1);
+ if (IDENTIFIER_VALUE (d1)
+ && DECL_TEMPLATE_TEMPLATE_PARM_P (IDENTIFIER_VALUE (d1)))
+ template = IDENTIFIER_VALUE (d1);
else
{
if (context)
@@ -3318,10 +3562,11 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope)
}
else if (TREE_CODE (d1) == TYPE_DECL && IS_AGGR_TYPE (TREE_TYPE (d1)))
{
- if (CLASSTYPE_TEMPLATE_INFO (TREE_TYPE (d1)) == NULL_TREE)
- return error_mark_node;
- template = CLASSTYPE_TI_TEMPLATE (TREE_TYPE (d1));
- d1 = DECL_NAME (template);
+ if (CLASSTYPE_TEMPLATE_INFO (TREE_TYPE (d1)))
+ {
+ template = CLASSTYPE_TI_TEMPLATE (TREE_TYPE (d1));
+ d1 = DECL_NAME (template);
+ }
}
else if (TREE_CODE (d1) == ENUMERAL_TYPE
|| (TREE_CODE_CLASS (TREE_CODE (d1)) == 't'
@@ -3341,11 +3586,15 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope)
my_friendly_abort (272);
/* With something like `template <class T> class X class X { ... };'
- we could end up with D1 having nothing but an IDENTIFIER_LOCAL_VALUE.
- We don't want to do that, but we have to deal with the situation, so
- let's give them some syntax errors to chew on instead of a crash. */
+ we could end up with D1 having nothing but an IDENTIFIER_VALUE.
+ We don't want to do that, but we have to deal with the situation,
+ so let's give them some syntax errors to chew on instead of a
+ crash. */
if (! template)
- return error_mark_node;
+ {
+ cp_error ("`%T' is not a template", d1);
+ return error_mark_node;
+ }
if (context == NULL_TREE)
context = global_namespace;
@@ -3367,7 +3616,6 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope)
tree template2 = TYPE_STUB_DECL (parm);
tree arglist2;
- CLASSTYPE_GOT_SEMICOLON (parm) = 1;
parmlist = DECL_INNERMOST_TEMPLATE_PARMS (template);
arglist2 = coerce_template_parms (parmlist, arglist, template, 1, 1);
@@ -3375,7 +3623,7 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope)
return error_mark_node;
arglist2 = copy_to_permanent (arglist2);
- CLASSTYPE_TEMPLATE_INFO (parm)
+ TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (parm)
= perm_tree_cons (template2, arglist2, NULL_TREE);
TYPE_SIZE (parm) = 0;
return parm;
@@ -3394,6 +3642,10 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope)
parm_depth = TMPL_PARMS_DEPTH (parmlist);
arg_depth = TMPL_ARGS_DEPTH (arglist);
+ /* We build up the coerced arguments and such on the
+ momentary_obstack. */
+ push_momentary ();
+
if (arg_depth == 1 && parm_depth > 1)
{
/* We've been given an incomplete set of template arguments.
@@ -3505,7 +3757,7 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope)
ctx;
ctx = (TREE_CODE_CLASS (TREE_CODE (ctx)) == 't')
? TYPE_CONTEXT (ctx) : DECL_CONTEXT (ctx))
- if (comptypes (ctx, template_type, 1))
+ if (same_type_p (ctx, template_type))
break;
if (!ctx)
@@ -3529,8 +3781,7 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope)
if (found)
{
- if (can_free (&permanent_obstack, arglist))
- obstack_free (&permanent_obstack, arglist);
+ pop_momentary ();
return found;
}
@@ -3540,7 +3791,9 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope)
push_obstacks (&permanent_obstack, &permanent_obstack);
/* This type is a "partial instantiation" if any of the template
- arguments still inolve template parameters. */
+ arguments still inolve template parameters. Note that we set
+ IS_PARTIAL_INSTANTIATION for partial specializations as
+ well. */
is_partial_instantiation = uses_template_parms (arglist);
/* Create the type. */
@@ -3584,10 +3837,59 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope)
else
type_decl = TYPE_NAME (t);
- /* Set up the template information. */
+ /* Set up the template information. We have to figure out which
+ template is the immediate parent if this is a full
+ instantiation. */
+ if (parm_depth == 1 || is_partial_instantiation
+ || !PRIMARY_TEMPLATE_P (template))
+ /* This case is easy; there are no member templates involved. */
+ found = template;
+ else
+ {
+ /* This is a full instantiation of a member template. There
+ should be some partial instantiation of which this is an
+ instance. */
+
+ for (found = DECL_TEMPLATE_INSTANTIATIONS (template);
+ found; found = TREE_CHAIN (found))
+ {
+ int success;
+ tree tmpl = CLASSTYPE_TI_TEMPLATE (TREE_VALUE (found));
+
+ /* We only want partial instantiations, here, not
+ specializations or full instantiations. */
+ if (CLASSTYPE_TEMPLATE_SPECIALIZATION (TREE_VALUE (found))
+ || !uses_template_parms (TREE_VALUE (found)))
+ continue;
+
+ /* Temporarily reduce by one the number of levels in the
+ ARGLIST and in FOUND so as to avoid comparing the
+ last set of arguments. */
+ TREE_VEC_LENGTH (arglist)--;
+ TREE_VEC_LENGTH (TREE_PURPOSE (found)) --;
+
+ /* See if the arguments match. If they do, then TMPL is
+ the partial instantiation we want. */
+ success = comp_template_args (TREE_PURPOSE (found), arglist);
+
+ /* Restore the argument vectors to their full size. */
+ TREE_VEC_LENGTH (arglist)++;
+ TREE_VEC_LENGTH (TREE_PURPOSE (found))++;
+
+ if (success)
+ {
+ found = tmpl;
+ break;
+ }
+ }
+
+ if (!found)
+ my_friendly_abort (0);
+ }
+
arglist = copy_to_permanent (arglist);
SET_TYPE_TEMPLATE_INFO (t,
- tree_cons (template, arglist, NULL_TREE));
+ tree_cons (found, arglist, NULL_TREE));
DECL_TEMPLATE_INSTANTIATIONS (template)
= tree_cons (arglist, t,
DECL_TEMPLATE_INSTANTIATIONS (template));
@@ -3605,6 +3907,9 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope)
/* We're done with the permanent obstack, now. */
pop_obstacks ();
+ /* We're also done with the momentary allocation we started
+ above. */
+ pop_momentary ();
/* Reset the name of the type, now that CLASSTYPE_TEMPLATE_INFO
is set up. */
@@ -3643,7 +3948,7 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope)
returned by for_each_template_parm is 0. If FN is NULL, it is
considered to be the function which always returns 1. */
-int
+static int
for_each_template_parm (t, fn, data)
tree t;
tree_fn_t fn;
@@ -3665,6 +3970,10 @@ for_each_template_parm (t, fn, data)
COMPONENT_REF uses template parms. */
return for_each_template_parm (TREE_TYPE (t), fn, data);
+ case ARRAY_REF:
+ return (for_each_template_parm (TREE_OPERAND (t, 0), fn, data)
+ || for_each_template_parm (TREE_OPERAND (t, 1), fn, data));
+
case IDENTIFIER_NODE:
if (!IDENTIFIER_TEMPLATE (t))
return 0;
@@ -3708,10 +4017,29 @@ for_each_template_parm (t, fn, data)
return for_each_template_parm (TREE_VALUE
(TYPE_TEMPLATE_INFO (t)),
fn, data);
- case FUNCTION_TYPE:
- if (for_each_template_parm (TYPE_ARG_TYPES (t), fn, data))
+ case METHOD_TYPE:
+ if (for_each_template_parm (TYPE_METHOD_BASETYPE (t), fn, data))
return 1;
+ /* Fall through. */
+
+ case FUNCTION_TYPE:
+ /* Check the parameter types. Since default arguments are not
+ instantiated until they are needed, the TYPE_ARG_TYPES may
+ contain expressions that involve template parameters. But,
+ no-one should be looking at them yet. And, once they're
+ instantiated, they don't contain template parameters, so
+ there's no point in looking at them then, either. */
+ {
+ tree parm;
+
+ for (parm = TYPE_ARG_TYPES (t); parm; parm = TREE_CHAIN (parm))
+ if (for_each_template_parm (TREE_VALUE (parm), fn, data))
+ return 1;
+ }
+
+ /* Check the return type, too. */
return for_each_template_parm (TREE_TYPE (t), fn, data);
+
case ARRAY_TYPE:
if (for_each_template_parm (TYPE_DOMAIN (t), fn, data))
return 1;
@@ -3720,12 +4048,6 @@ for_each_template_parm (t, fn, data)
if (for_each_template_parm (TYPE_OFFSET_BASETYPE (t), fn, data))
return 1;
return for_each_template_parm (TREE_TYPE (t), fn, data);
- case METHOD_TYPE:
- if (for_each_template_parm (TYPE_METHOD_BASETYPE (t), fn, data))
- return 1;
- if (for_each_template_parm (TYPE_ARG_TYPES (t), fn, data))
- return 1;
- return for_each_template_parm (TREE_TYPE (t), fn, data);
/* decl nodes */
case TYPE_DECL:
@@ -3760,15 +4082,17 @@ for_each_template_parm (t, fn, data)
return 0;
case CALL_EXPR:
- return for_each_template_parm (TREE_TYPE (t), fn, data);
+ return (for_each_template_parm (TREE_OPERAND (t, 0), fn, data)
+ || for_each_template_parm (TREE_OPERAND (t, 1), fn, data));
+
case ADDR_EXPR:
return for_each_template_parm (TREE_OPERAND (t, 0), fn, data);
/* template parm nodes */
case TEMPLATE_TEMPLATE_PARM:
/* Record template parameters such as `T' inside `TT<T>'. */
- if (CLASSTYPE_TEMPLATE_INFO (t)
- && for_each_template_parm (CLASSTYPE_TI_ARGS (t), fn, data))
+ if (TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (t)
+ && for_each_template_parm (TYPE_TI_ARGS (t), fn, data))
return 1;
case TEMPLATE_TYPE_PARM:
case TEMPLATE_PARM_INDEX:
@@ -4045,21 +4369,22 @@ tsubst_friend_function (decl, args)
template_id
= lookup_template_function (tsubst_expr (DECL_TI_TEMPLATE (decl),
- args, NULL_TREE),
+ args, /*complain=*/1,
+ NULL_TREE),
tsubst (DECL_TI_ARGS (decl),
- args, NULL_TREE));
+ args, /*complain=*/1,
+ NULL_TREE));
/* FIXME: The decl we create via the next tsubst could be
created on a temporary obstack. */
- new_friend = tsubst (decl, args, NULL_TREE);
+ new_friend = tsubst (decl, args, /*complain=*/1, NULL_TREE);
tmpl = determine_specialization (template_id, new_friend,
&new_args,
- /*need_member_template=*/0,
- /*complain=*/1);
+ /*need_member_template=*/0);
new_friend = instantiate_template (tmpl, new_args);
goto done;
}
- new_friend = tsubst (decl, args, NULL_TREE);
+ new_friend = tsubst (decl, args, /*complain=*/1, NULL_TREE);
/* The NEW_FRIEND will look like an instantiation, to the
compiler, but is not an instantiation from the point of view of
@@ -4093,16 +4418,30 @@ tsubst_friend_function (decl, args)
if (DECL_NAMESPACE_SCOPE_P (new_friend))
{
tree old_decl;
- tree new_friend_args;
-
+ tree new_friend_template_info;
+ tree new_friend_result_template_info;
+ int new_friend_is_defn;
+
+ /* We must save some information from NEW_FRIEND before calling
+ duplicate decls since that function will free NEW_FRIEND if
+ possible. */
+ new_friend_template_info = DECL_TEMPLATE_INFO (new_friend);
if (TREE_CODE (new_friend) == TEMPLATE_DECL)
- /* This declaration is a `primary' template. */
- DECL_PRIMARY_TEMPLATE (new_friend) = new_friend;
+ {
+ /* This declaration is a `primary' template. */
+ DECL_PRIMARY_TEMPLATE (new_friend) = new_friend;
+
+ new_friend_is_defn
+ = DECL_INITIAL (DECL_RESULT (new_friend)) != NULL_TREE;
+ new_friend_result_template_info
+ = DECL_TEMPLATE_INFO (DECL_RESULT (new_friend));
+ }
+ else
+ {
+ new_friend_is_defn = DECL_INITIAL (new_friend) != NULL_TREE;
+ new_friend_result_template_info = NULL_TREE;
+ }
- /* We must save the DECL_TI_ARGS for NEW_FRIEND here because
- pushdecl may call duplicate_decls which will free NEW_FRIEND
- if possible. */
- new_friend_args = DECL_TI_ARGS (new_friend);
old_decl = pushdecl_namespace_level (new_friend);
if (old_decl != new_friend)
@@ -4141,36 +4480,55 @@ tsubst_friend_function (decl, args)
when `C<int>' is instantiated. Now, `f(int)' is defined
in the class. */
- if (TREE_CODE (old_decl) != TEMPLATE_DECL)
- /* duplicate_decls will take care of this case. */
+ if (!new_friend_is_defn)
+ /* On the other hand, if the in-class declaration does
+ *not* provide a definition, then we don't want to alter
+ existing definitions. We can just leave everything
+ alone. */
;
- else
+ else
{
- tree t;
-
- for (t = DECL_TEMPLATE_SPECIALIZATIONS (old_decl);
- t != NULL_TREE;
- t = TREE_CHAIN (t))
+ /* Overwrite whatever template info was there before, if
+ any, with the new template information pertaining to
+ the declaration. */
+ DECL_TEMPLATE_INFO (old_decl) = new_friend_template_info;
+
+ if (TREE_CODE (old_decl) != TEMPLATE_DECL)
+ /* duplicate_decls will take care of this case. */
+ ;
+ else
{
- tree spec = TREE_VALUE (t);
+ tree t;
+ tree new_friend_args;
+
+ DECL_TEMPLATE_INFO (DECL_RESULT (old_decl))
+ = new_friend_result_template_info;
+
+ new_friend_args = TI_ARGS (new_friend_template_info);
+ for (t = DECL_TEMPLATE_SPECIALIZATIONS (old_decl);
+ t != NULL_TREE;
+ t = TREE_CHAIN (t))
+ {
+ tree spec = TREE_VALUE (t);
- DECL_TI_ARGS (spec)
- = add_outermost_template_args (new_friend_args,
- DECL_TI_ARGS (spec));
- DECL_TI_ARGS (spec)
- = copy_to_permanent (DECL_TI_ARGS (spec));
- }
-
- /* Now, since specializations are always supposed to
- hang off of the most general template, we must move
- them. */
- t = most_general_template (old_decl);
- if (t != old_decl)
- {
- DECL_TEMPLATE_SPECIALIZATIONS (t)
- = chainon (DECL_TEMPLATE_SPECIALIZATIONS (t),
- DECL_TEMPLATE_SPECIALIZATIONS (old_decl));
- DECL_TEMPLATE_SPECIALIZATIONS (old_decl) = NULL_TREE;
+ DECL_TI_ARGS (spec)
+ = add_outermost_template_args (new_friend_args,
+ DECL_TI_ARGS (spec));
+ DECL_TI_ARGS (spec)
+ = copy_to_permanent (DECL_TI_ARGS (spec));
+ }
+
+ /* Now, since specializations are always supposed to
+ hang off of the most general template, we must move
+ them. */
+ t = most_general_template (old_decl);
+ if (t != old_decl)
+ {
+ DECL_TEMPLATE_SPECIALIZATIONS (t)
+ = chainon (DECL_TEMPLATE_SPECIALIZATIONS (t),
+ DECL_TEMPLATE_SPECIALIZATIONS (old_decl));
+ DECL_TEMPLATE_SPECIALIZATIONS (old_decl) = NULL_TREE;
+ }
}
}
@@ -4221,7 +4579,7 @@ tsubst_friend_class (friend_tmpl, args)
at. */
tree parms
= tsubst_template_parms (DECL_TEMPLATE_PARMS (friend_tmpl),
- args);
+ args, /*complain=*/1);
redeclare_class_template (TREE_TYPE (tmpl), parms);
friend_type = TREE_TYPE (tmpl);
}
@@ -4230,7 +4588,7 @@ tsubst_friend_class (friend_tmpl, args)
/* The friend template has not already been declared. In this
case, the instantiation of the template class will cause the
injection of this template into the global scope. */
- tmpl = tsubst (friend_tmpl, args, NULL_TREE);
+ tmpl = tsubst (friend_tmpl, args, /*complain=*/1, NULL_TREE);
/* The new TMPL is not an instantiation of anything, so we
forget its origins. We don't reset CLASSTYPE_TI_TEMPLATE for
@@ -4260,34 +4618,116 @@ instantiate_class_template (type)
if (TYPE_BEING_DEFINED (type) || TYPE_SIZE (type))
return type;
+ /* We want to allocate temporary vectors of template arguments and
+ template argument expressions on the momentary obstack, not on
+ the expression obstack. Otherwise, all the space allocated in
+ argument coercion and such is simply lost. */
+ push_momentary ();
+
+ /* Figure out which template is being instantiated. */
template = most_general_template (CLASSTYPE_TI_TEMPLATE (type));
- args = CLASSTYPE_TI_ARGS (type);
my_friendly_assert (TREE_CODE (template) == TEMPLATE_DECL, 279);
- t = most_specialized_class (template, args);
- if (t == error_mark_node)
+ /* Figure out which arguments are being used to do the
+ instantiation. */
+ args = CLASSTYPE_TI_ARGS (type);
+ PARTIAL_INSTANTIATION_P (type) = uses_template_parms (args);
+
+ if (pedantic && PARTIAL_INSTANTIATION_P (type))
+ /* If this is a partial instantiation, then we can't instantiate
+ the type; there's no telling whether or not one of the
+ template parameters might eventually be instantiated to some
+ value that results in a specialization being used. For
+ example, consider:
+
+ template <class T>
+ struct S {};
+
+ template <class U>
+ void f(S<U>);
+
+ template <>
+ struct S<int> {};
+
+ Now, the `S<U>' in `f<int>' is the specialization, not an
+ instantiation of the original template. */
+ goto end;
+
+ /* Determine what specialization of the original template to
+ instantiate. */
+ if (PARTIAL_INSTANTIATION_P (type))
+ /* There's no telling which specialization is appropriate at this
+ point. Since all peeking at the innards of this partial
+ instantiation are extensions (like the "implicit typename"
+ extension, which allows users to omit the keyword `typename' on
+ names that are declared as types in template base classes), we
+ are free to do what we please.
+
+ Trying to figure out which partial instantiation to use can
+ cause a crash. (Some of the template arguments don't even have
+ types.) So, we just use the most general version. */
+ t = NULL_TREE;
+ else
{
- char *str = "candidates are:";
- cp_error ("ambiguous class template instantiation for `%#T'", type);
- for (t = DECL_TEMPLATE_SPECIALIZATIONS (template); t; t = TREE_CHAIN (t))
+ t = most_specialized_class (template, args);
+
+ if (t == error_mark_node)
{
- if (get_class_bindings (TREE_VALUE (t), TREE_PURPOSE (t),
- args))
+ const char *str = "candidates are:";
+ cp_error ("ambiguous class template instantiation for `%#T'", type);
+ for (t = DECL_TEMPLATE_SPECIALIZATIONS (template); t;
+ t = TREE_CHAIN (t))
{
- cp_error_at ("%s %+#T", str, TREE_TYPE (t));
- str = " ";
+ if (get_class_bindings (TREE_VALUE (t), TREE_PURPOSE (t),
+ args))
+ {
+ cp_error_at ("%s %+#T", str, TREE_TYPE (t));
+ str = " ";
+ }
}
+ TYPE_BEING_DEFINED (type) = 1;
+ type = error_mark_node;
+ goto end;
}
- TYPE_BEING_DEFINED (type) = 1;
- return error_mark_node;
}
- else if (t)
+
+ if (t)
pattern = TREE_TYPE (t);
else
pattern = TREE_TYPE (template);
+ /* If the template we're instantiating is incomplete, then clearly
+ there's nothing we can do. */
if (TYPE_SIZE (pattern) == NULL_TREE)
- return type;
+ goto end;
+
+ /* If this is a partial instantiation, don't tsubst anything. We will
+ only use this type for implicit typename, so the actual contents don't
+ matter. All that matters is whether a particular name is a type. */
+ if (PARTIAL_INSTANTIATION_P (type))
+ {
+ /* The fields set here must be kept in sync with those cleared
+ in begin_class_definition. */
+ TYPE_BINFO_BASETYPES (type) = TYPE_BINFO_BASETYPES (pattern);
+ TYPE_FIELDS (type) = TYPE_FIELDS (pattern);
+ TYPE_METHODS (type) = TYPE_METHODS (pattern);
+ CLASSTYPE_TAGS (type) = CLASSTYPE_TAGS (pattern);
+ /* Pretend that the type is complete, so that we will look
+ inside it during name lookup and such. */
+ TYPE_SIZE (type) = integer_zero_node;
+ goto end;
+ }
+
+ /* If we've recursively instantiated too many templates, stop. */
+ if (! push_tinst_level (type))
+ goto end;
+
+ /* Now we're really doing the instantiation. Mark the type as in
+ the process of being defined. */
+ TYPE_BEING_DEFINED (type) = 1;
+
+ maybe_push_to_top_level (uses_template_parms (type));
+ pushclass (type, 0);
if (t)
{
@@ -4317,31 +4757,6 @@ instantiate_class_template (type)
args = inner_args;
}
- if (pedantic && uses_template_parms (args))
- {
- /* If there are still template parameters amongst the args, then
- we can't instantiate the type; there's no telling whether or not one
- of the template parameters might eventually be instantiated to some
- value that results in a specialization being used. We do the
- type as complete so that, for example, declaring one of its
- members to be a friend will not be rejected. */
- TYPE_SIZE (type) = integer_zero_node;
- return type;
- }
-
- TYPE_BEING_DEFINED (type) = 1;
-
- if (! push_tinst_level (type))
- return type;
-
- maybe_push_to_top_level (uses_template_parms (type));
- pushclass (type, 0);
-
- /* We must copy the arguments to the permanent obstack since
- during the tsubst'ing below they may wind up in the
- DECL_TI_ARGS of some instantiated member template. */
- args = copy_to_permanent (args);
-
if (flag_external_templates)
{
if (flag_alt_external_templates)
@@ -4370,7 +4785,6 @@ instantiate_class_template (type)
TYPE_HAS_CONSTRUCTOR (type) = TYPE_HAS_CONSTRUCTOR (pattern);
TYPE_HAS_DESTRUCTOR (type) = TYPE_HAS_DESTRUCTOR (pattern);
- TYPE_HAS_ASSIGNMENT (type) = TYPE_HAS_ASSIGNMENT (pattern);
TYPE_OVERLOADS_CALL_EXPR (type) = TYPE_OVERLOADS_CALL_EXPR (pattern);
TYPE_OVERLOADS_ARRAY_REF (type) = TYPE_OVERLOADS_ARRAY_REF (pattern);
TYPE_OVERLOADS_ARROW (type) = TYPE_OVERLOADS_ARROW (pattern);
@@ -4394,65 +4808,69 @@ instantiate_class_template (type)
TYPE_ALIGN (type) = TYPE_ALIGN (pattern);
TYPE_FOR_JAVA (type) = TYPE_FOR_JAVA (pattern); /* For libjava's JArray<T> */
- /* If this is a partial instantiation, don't tsubst anything. We will
- only use this type for implicit typename, so the actual contents don't
- matter. All that matters is whether a particular name is a type. */
- if (uses_template_parms (type))
- {
- TYPE_BINFO_BASETYPES (type) = TYPE_BINFO_BASETYPES (pattern);
- TYPE_FIELDS (type) = TYPE_FIELDS (pattern);
- TYPE_METHODS (type) = TYPE_METHODS (pattern);
- CLASSTYPE_TAGS (type) = CLASSTYPE_TAGS (pattern);
- TYPE_SIZE (type) = integer_zero_node;
- goto end;
- }
+ /* We must copy the arguments to the permanent obstack since
+ during the tsubst'ing below they may wind up in the
+ DECL_TI_ARGS of some instantiated member template. */
+ args = copy_to_permanent (args);
- {
- tree binfo = TYPE_BINFO (type);
- tree pbases = TYPE_BINFO_BASETYPES (pattern);
+ if (TYPE_BINFO_BASETYPES (pattern))
+ {
+ tree base_list = NULL_TREE;
+ tree pbases = TYPE_BINFO_BASETYPES (pattern);
+ int i;
- if (pbases)
- {
- tree bases;
- int i;
- int len = TREE_VEC_LENGTH (pbases);
- bases = make_tree_vec (len);
- for (i = 0; i < len; ++i)
- {
- tree elt, basetype;
+ /* Substitute into each of the bases to determine the actual
+ basetypes. */
+ for (i = 0; i < TREE_VEC_LENGTH (pbases); ++i)
+ {
+ tree base;
+ tree access;
+ tree pbase;
- TREE_VEC_ELT (bases, i) = elt
- = tsubst (TREE_VEC_ELT (pbases, i), args, NULL_TREE);
- BINFO_INHERITANCE_CHAIN (elt) = binfo;
+ pbase = TREE_VEC_ELT (pbases, i);
- basetype = TREE_TYPE (elt);
+ /* Substitue to figure out the base class. */
+ base = tsubst (BINFO_TYPE (pbase), args,
+ /*complain=*/1, NULL_TREE);
+ if (base == error_mark_node)
+ continue;
- if (! IS_AGGR_TYPE (basetype))
- cp_error
- ("base type `%T' of `%T' fails to be a struct or class type",
- basetype, type);
- else if (TYPE_SIZE (complete_type (basetype)) == NULL_TREE)
- cp_error ("base class `%T' of `%T' has incomplete type",
- basetype, type);
+ /* Calculate the correct access node. */
+ if (TREE_VIA_VIRTUAL (pbase))
+ {
+ if (TREE_VIA_PUBLIC (pbase))
+ access = access_public_virtual_node;
+ else if (TREE_VIA_PROTECTED (pbase))
+ access = access_protected_virtual_node;
+ else
+ access = access_private_virtual_node;
+ }
+ else
+ {
+ if (TREE_VIA_PUBLIC (pbase))
+ access = access_public_node;
+ else if (TREE_VIA_PROTECTED (pbase))
+ access = access_protected_node;
+ else
+ access = access_private_node;
+ }
- /* These are set up in xref_basetypes for normal classes, so
- we have to handle them here for template bases. */
+ base_list = tree_cons (access, base, base_list);
+ }
- unshare_base_binfos (elt);
+ /* The list is now in reverse order; correct that. */
+ base_list = nreverse (base_list);
- if (TYPE_USES_VIRTUAL_BASECLASSES (basetype))
- {
- TYPE_USES_VIRTUAL_BASECLASSES (type) = 1;
- TYPE_USES_COMPLEX_INHERITANCE (type) = 1;
- }
- TYPE_GETS_NEW (type) |= TYPE_GETS_NEW (basetype);
- TYPE_GETS_DELETE (type) |= TYPE_GETS_DELETE (basetype);
- }
- /* Don't initialize this until the vector is filled out, or
- lookups will crash. */
- BINFO_BASETYPES (binfo) = bases;
- }
- }
+ /* Now call xref_basetypes to set up all the base-class
+ information. */
+ xref_basetypes (TREE_CODE (pattern) == RECORD_TYPE
+ ? (CLASSTYPE_DECLARED_CLASS (pattern)
+ ? class_type_node : record_type_node)
+ : union_type_node,
+ DECL_NAME (TYPE_NAME (pattern)),
+ type,
+ base_list);
+ }
for (t = CLASSTYPE_TAGS (pattern); t; t = TREE_CHAIN (t))
{
@@ -4460,9 +4878,20 @@ instantiate_class_template (type)
tree name = TYPE_IDENTIFIER (tag);
tree newtag;
- newtag = tsubst (tag, args, NULL_TREE);
+ newtag = tsubst (tag, args, /*complain=*/1, NULL_TREE);
if (TREE_CODE (newtag) != ENUMERAL_TYPE)
{
+ if (TYPE_LANG_SPECIFIC (tag) && CLASSTYPE_IS_TEMPLATE (tag))
+ /* Unfortunately, lookup_template_class sets
+ CLASSTYPE_IMPLICIT_INSTANTIATION for a partial
+ instantiation (i.e., for the type of a member template
+ class nested within a template class.) This behavior is
+ required for maybe_process_partial_specialization to work
+ correctly, but is not accurate in this case; the TAG is not
+ an instantiation of anything. (The corresponding
+ TEMPLATE_DECL is an instantiation, but the TYPE is not.) */
+ CLASSTYPE_USE_TEMPLATE (newtag) = 0;
+
/* Now, we call pushtag to put this NEWTAG into the scope of
TYPE. We first set up the IDENTIFIER_TYPE_VALUE to avoid
pushtag calling push_template_decl. We don't have to do
@@ -4486,15 +4915,21 @@ instantiate_class_template (type)
lineno = DECL_SOURCE_LINE (t);
input_filename = DECL_SOURCE_FILE (t);
- r = tsubst (t, args, NULL_TREE);
+ r = tsubst (t, args, /*complain=*/1, NULL_TREE);
if (TREE_CODE (r) == VAR_DECL)
{
pending_statics = perm_tree_cons (NULL_TREE, r, pending_statics);
/* Perhaps we should do more of grokfield here. */
+ if (DECL_DEFINED_IN_CLASS_P (r))
+ /* Set up DECL_INITIAL, since tsubst doesn't. */
+ DECL_INITIAL (r) = tsubst_expr (DECL_INITIAL (t), args,
+ /*complain=*/1, NULL_TREE);
start_decl_1 (r);
DECL_IN_AGGR_P (r) = 1;
DECL_EXTERNAL (r) = 1;
cp_finish_decl (r, DECL_INITIAL (r), NULL_TREE, 0, 0);
+ if (DECL_DEFINED_IN_CLASS_P (r))
+ check_static_variable_definition (r, TREE_TYPE (r));
}
/* R will have a TREE_CHAIN if and only if it has already been
@@ -4513,7 +4948,7 @@ instantiate_class_template (type)
for this instantiation. */
for (t = TYPE_METHODS (pattern); t; t = TREE_CHAIN (t))
{
- tree r = tsubst (t, args, NULL_TREE);
+ tree r = tsubst (t, args, /*complain=*/1, NULL_TREE);
set_current_access_from_decl (r);
finish_member_declaration (r);
}
@@ -4545,7 +4980,8 @@ instantiate_class_template (type)
else
{
TREE_VALUE (DECL_FRIENDLIST (typedecl))
- = tree_cons (tsubst (TREE_PURPOSE (friends), args, NULL_TREE),
+ = tree_cons (tsubst (TREE_PURPOSE (friends), args,
+ /*complain=*/1, NULL_TREE),
NULL_TREE,
TREE_VALUE (DECL_FRIENDLIST (typedecl)));
@@ -4563,7 +4999,8 @@ instantiate_class_template (type)
if (TREE_CODE (friend_type) == TEMPLATE_DECL)
new_friend_type = tsubst_friend_class (friend_type, args);
else if (uses_template_parms (friend_type))
- new_friend_type = tsubst (friend_type, args, NULL_TREE);
+ new_friend_type = tsubst (friend_type, args, /*complain=*/1,
+ NULL_TREE);
else
/* The call to xref_tag_from_type does injection for friend
classes. */
@@ -4588,7 +5025,8 @@ instantiate_class_template (type)
/* This does injection for friend functions. */
if (!processing_template_decl)
{
- t = tsubst (DECL_TEMPLATE_INJECT (template), args, NULL_TREE);
+ t = tsubst (DECL_TEMPLATE_INJECT (template), args,
+ /*complain=*/1, NULL_TREE);
for (; t; t = TREE_CHAIN (t))
{
@@ -4619,17 +5057,17 @@ instantiate_class_template (type)
type = finish_struct_1 (type, 0);
CLASSTYPE_GOT_SEMICOLON (type) = 1;
+ /* Clear this now so repo_template_used is happy. */
+ TYPE_BEING_DEFINED (type) = 0;
repo_template_used (type);
- if (at_eof && TYPE_BINFO_VTABLE (type) != NULL_TREE)
- finish_prevtable_vardecl (NULL, TYPE_BINFO_VTABLE (type));
- end:
- TYPE_BEING_DEFINED (type) = 0;
popclass (0);
-
pop_from_top_level ();
pop_tinst_level ();
+ end:
+ pop_momentary ();
+
return type;
}
@@ -4688,10 +5126,11 @@ innermost_args (args)
/* Substitute ARGS into the vector of template arguments T. */
-tree
-tsubst_template_arg_vector (t, args)
+static tree
+tsubst_template_arg_vector (t, args, complain)
tree t;
tree args;
+ int complain;
{
int len = TREE_VEC_LENGTH (t), need_new = 0, i;
tree *elts = (tree *) alloca (len * sizeof (tree));
@@ -4702,10 +5141,12 @@ tsubst_template_arg_vector (t, args)
{
if (TREE_VEC_ELT (t, i) != NULL_TREE
&& TREE_CODE (TREE_VEC_ELT (t, i)) == TREE_VEC)
- elts[i] = tsubst_template_arg_vector (TREE_VEC_ELT (t, i), args);
+ elts[i] = tsubst_template_arg_vector (TREE_VEC_ELT (t, i),
+ args, complain);
else
elts[i] = maybe_fold_nontype_arg
- (tsubst_expr (TREE_VEC_ELT (t, i), args, NULL_TREE));
+ (tsubst_expr (TREE_VEC_ELT (t, i), args, complain,
+ NULL_TREE));
if (elts[i] != TREE_VEC_ELT (t, i))
need_new = 1;
@@ -4714,7 +5155,7 @@ tsubst_template_arg_vector (t, args)
if (!need_new)
return t;
- t = make_tree_vec (len);
+ t = make_temp_vec (len);
for (i = 0; i < len; i++)
TREE_VEC_ELT (t, i) = elts[i];
@@ -4728,10 +5169,11 @@ tsubst_template_arg_vector (t, args)
template <T*, U, class V>' and ARGS is {{int}, {double}} then the
result will be `template <int*, double, class V>'. */
-tree
-tsubst_template_parms (parms, args)
+static tree
+tsubst_template_parms (parms, args, complain)
tree parms;
tree args;
+ int complain;
{
tree r;
tree* new_parms = &r;
@@ -4753,9 +5195,10 @@ tsubst_template_parms (parms, args)
TREE_VALUE (TREE_VEC_ELT (TREE_VALUE (parms), i));
TREE_VEC_ELT (new_vec, i)
- = build_tree_list (tsubst (default_value, args, NULL_TREE),
- tsubst (parm_decl, args, NULL_TREE));
-
+ = build_tree_list (tsubst (default_value, args, complain,
+ NULL_TREE),
+ tsubst (parm_decl, args, complain,
+ NULL_TREE));
}
*new_parms =
@@ -4773,10 +5216,11 @@ tsubst_template_parms (parms, args)
ENTERING_SCOPE is non-zero, T is the context for a template which
we are presently tsubst'ing. Return the subsituted value. */
-tree
-tsubst_aggr_type (t, args, in_decl, entering_scope)
+static tree
+tsubst_aggr_type (t, args, complain, in_decl, entering_scope)
tree t;
tree args;
+ int complain;
tree in_decl;
int entering_scope;
{
@@ -4789,15 +5233,14 @@ tsubst_aggr_type (t, args, in_decl, entering_scope)
if (TYPE_PTRMEMFUNC_P (t))
{
tree r = build_ptrmemfunc_type
- (tsubst (TYPE_PTRMEMFUNC_FN_TYPE (t), args, in_decl));
- return cp_build_type_variant (r, TYPE_READONLY (t),
- TYPE_VOLATILE (t));
+ (tsubst (TYPE_PTRMEMFUNC_FN_TYPE (t), args, complain, in_decl));
+ return cp_build_qualified_type (r, TYPE_QUALS (t));
}
/* else fall through */
case ENUMERAL_TYPE:
case UNION_TYPE:
- if (uses_template_parms (t))
+ if (TYPE_TEMPLATE_INFO (t))
{
tree argvec;
tree context;
@@ -4807,6 +5250,7 @@ tsubst_aggr_type (t, args, in_decl, entering_scope)
up. */
if (TYPE_CONTEXT (t) != NULL_TREE)
context = tsubst_aggr_type (TYPE_CONTEXT (t), args,
+ complain,
in_decl, /*entering_scope=*/1);
else
context = NULL_TREE;
@@ -4820,20 +5264,22 @@ tsubst_aggr_type (t, args, in_decl, entering_scope)
and supposing that we are instantiating f<int, double>,
then our ARGS will be {int, double}, but, when looking up
S we only want {double}. */
- argvec = tsubst (TYPE_TI_ARGS (t), args, in_decl);
+ push_momentary ();
+ argvec = tsubst_template_arg_vector (TYPE_TI_ARGS (t), args,
+ complain);
r = lookup_template_class (t, argvec, in_decl, context,
entering_scope);
+ pop_momentary ();
- return cp_build_type_variant (r, TYPE_READONLY (t),
- TYPE_VOLATILE (t));
+ return cp_build_qualified_type (r, TYPE_QUALS (t));
}
else
/* This is not a template type, so there's nothing to do. */
return t;
default:
- return tsubst (t, args, in_decl);
+ return tsubst (t, args, complain, in_decl);
}
}
@@ -4842,7 +5288,7 @@ tsubst_aggr_type (t, args, in_decl, entering_scope)
appropriate. Return the result of the substitution. IN_DECL is as
for tsubst. */
-tree
+static tree
tsubst_decl (t, args, type, in_decl)
tree t;
tree args;
@@ -4878,7 +5324,11 @@ tsubst_decl (t, args, type, in_decl)
tree tmpl_args = DECL_CLASS_TEMPLATE_P (t)
? CLASSTYPE_TI_ARGS (TREE_TYPE (t))
: DECL_TI_ARGS (DECL_RESULT (t));
- tree full_args = tsubst (tmpl_args, args, in_decl);
+ tree full_args;
+
+ push_momentary ();
+ full_args = tsubst_template_arg_vector (tmpl_args, args,
+ /*complain=*/1);
/* tsubst_template_arg_vector doesn't copy the vector if
nothing changed. But, *something* should have
@@ -4886,6 +5336,7 @@ tsubst_decl (t, args, type, in_decl)
my_friendly_assert (full_args != tmpl_args, 0);
spec = retrieve_specialization (t, full_args);
+ pop_momentary ();
if (spec != NULL_TREE)
{
r = spec;
@@ -4905,23 +5356,25 @@ tsubst_decl (t, args, type, in_decl)
if (is_template_template_parm)
{
- tree new_decl = tsubst (decl, args, in_decl);
+ tree new_decl = tsubst (decl, args, /*complain=*/1, in_decl);
DECL_RESULT (r) = new_decl;
TREE_TYPE (r) = TREE_TYPE (new_decl);
break;
}
DECL_CONTEXT (r)
- = tsubst_aggr_type (DECL_CONTEXT (t), args, in_decl,
- /*entering_scope=*/1);
+ = tsubst_aggr_type (DECL_CONTEXT (t), args, /*complain=*/1,
+ in_decl, /*entering_scope=*/1);
DECL_CLASS_CONTEXT (r)
- = tsubst_aggr_type (DECL_CLASS_CONTEXT (t), args, in_decl,
- /*entering_scope=*/1);
+ = tsubst_aggr_type (DECL_CLASS_CONTEXT (t), args,
+ /*complain=*/1, in_decl,
+ /*entering_scope=*/1);
DECL_TEMPLATE_INFO (r) = build_tree_list (t, args);
if (TREE_CODE (decl) == TYPE_DECL)
{
- tree new_type = tsubst (TREE_TYPE (t), args, in_decl);
+ tree new_type = tsubst (TREE_TYPE (t), args,
+ /*complain=*/1, in_decl);
TREE_TYPE (r) = new_type;
CLASSTYPE_TI_TEMPLATE (new_type) = r;
DECL_RESULT (r) = TYPE_MAIN_DECL (new_type);
@@ -4929,7 +5382,7 @@ tsubst_decl (t, args, type, in_decl)
}
else
{
- tree new_decl = tsubst (decl, args, in_decl);
+ tree new_decl = tsubst (decl, args, /*complain=*/1, in_decl);
DECL_RESULT (r) = new_decl;
DECL_TI_TEMPLATE (new_decl) = r;
TREE_TYPE (r) = TREE_TYPE (new_decl);
@@ -4944,7 +5397,8 @@ tsubst_decl (t, args, type, in_decl)
template parameters for the old template, except the
outermost level of parameters. */
DECL_TEMPLATE_PARMS (r)
- = tsubst_template_parms (DECL_TEMPLATE_PARMS (t), args);
+ = tsubst_template_parms (DECL_TEMPLATE_PARMS (t), args,
+ /*complain=*/1);
if (PRIMARY_TEMPLATE_P (t))
DECL_PRIMARY_TEMPLATE (r) = r;
@@ -4998,9 +5452,10 @@ tsubst_decl (t, args, type, in_decl)
that here. */
continue;
- spec_args = tsubst (DECL_TI_ARGS (fn), args, in_decl);
+ spec_args = tsubst (DECL_TI_ARGS (fn), args,
+ /*complain=*/1, in_decl);
new_fn = tsubst (DECL_RESULT (most_general_template (fn)),
- spec_args, in_decl);
+ spec_args, /*complain=*/1, in_decl);
DECL_TI_TEMPLATE (new_fn) = fn;
register_specialization (new_fn, r,
innermost_args (spec_args));
@@ -5017,6 +5472,7 @@ tsubst_decl (t, args, type, in_decl)
{
tree ctx;
tree argvec = NULL_TREE;
+ tree *friends;
tree gen_tmpl;
int member;
int args_depth;
@@ -5029,21 +5485,34 @@ tsubst_decl (t, args, type, in_decl)
{
tree spec;
+ /* Allocate template arguments on the momentary obstack,
+ in case we don't need to keep them. */
+ push_momentary ();
+
/* Calculate the most general template of which R is a
specialization, and the complete set of arguments used to
specialize R. */
gen_tmpl = most_general_template (DECL_TI_TEMPLATE (t));
- argvec = tsubst (DECL_TI_ARGS (DECL_TEMPLATE_RESULT (gen_tmpl)),
- args, in_decl);
+ argvec
+ = tsubst_template_arg_vector (DECL_TI_ARGS
+ (DECL_TEMPLATE_RESULT (gen_tmpl)),
+ args, /*complain=*/1);
/* Check to see if we already have this specialization. */
spec = retrieve_specialization (gen_tmpl, argvec);
+
if (spec)
{
r = spec;
+ pop_momentary ();
break;
}
+ /* We're going to need to keep the ARGVEC, so we copy it
+ here. */
+ argvec = copy_to_permanent (argvec);
+ pop_momentary ();
+
/* Here, we deal with the peculiar case:
template <class T> struct S {
@@ -5111,7 +5580,8 @@ tsubst_decl (t, args, type, in_decl)
member = 2;
else
member = 1;
- ctx = tsubst_aggr_type (DECL_CLASS_CONTEXT (t), args, t,
+ ctx = tsubst_aggr_type (DECL_CLASS_CONTEXT (t), args,
+ /*complain=*/1, t,
/*entering_scope=*/1);
}
else
@@ -5119,7 +5589,7 @@ tsubst_decl (t, args, type, in_decl)
member = 0;
ctx = NULL_TREE;
}
- type = tsubst (type, args, in_decl);
+ type = tsubst (type, args, /*complain=*/1, in_decl);
/* We do NOT check for matching decls pushed separately at this
point, as they may not represent instantiations of this
@@ -5132,22 +5602,19 @@ tsubst_decl (t, args, type, in_decl)
TREE_TYPE (r) = type;
DECL_CONTEXT (r)
- = tsubst_aggr_type (DECL_CONTEXT (t), args, t, /*entering_scope=*/1);
+ = tsubst_aggr_type (DECL_CONTEXT (t), args, /*complain=*/1, t,
+ /*entering_scope=*/1);
DECL_CLASS_CONTEXT (r) = ctx;
- if (member && !strncmp (OPERATOR_TYPENAME_FORMAT,
- IDENTIFIER_POINTER (DECL_NAME (r)),
- sizeof (OPERATOR_TYPENAME_FORMAT) - 1))
- {
- /* Type-conversion operator. Reconstruct the name, in
- case it's the name of one of the template's parameters. */
- DECL_NAME (r) = build_typename_overload (TREE_TYPE (type));
- }
+ if (member && IDENTIFIER_TYPENAME_P (DECL_NAME (r)))
+ /* Type-conversion operator. Reconstruct the name, in
+ case it's the name of one of the template's parameters. */
+ DECL_NAME (r) = build_typename_overload (TREE_TYPE (type));
- DECL_ARGUMENTS (r) = tsubst (DECL_ARGUMENTS (t), args, t);
+ DECL_ARGUMENTS (r) = tsubst (DECL_ARGUMENTS (t), args,
+ /*complain=*/1, t);
DECL_MAIN_VARIANT (r) = r;
DECL_RESULT (r) = NULL_TREE;
- DECL_INITIAL (r) = NULL_TREE;
TREE_STATIC (r) = 0;
TREE_PUBLIC (r) = TREE_PUBLIC (t);
@@ -5158,19 +5625,14 @@ tsubst_decl (t, args, type, in_decl)
DECL_PENDING_INLINE_INFO (r) = 0;
TREE_USED (r) = 0;
- if (DECL_CONSTRUCTOR_P (r))
- {
- maybe_retrofit_in_chrg (r);
- grok_ctor_properties (ctx, r);
- }
- if (IDENTIFIER_OPNAME_P (DECL_NAME (r)))
- grok_op_properties (r, DECL_VIRTUAL_P (r), DECL_FRIEND_P (r));
-
/* Set up the DECL_TEMPLATE_INFO for R and compute its mangled
name. There's no need to do this in the special friend
case mentioned above where GEN_TMPL is NULL. */
if (gen_tmpl)
{
+ /* The ARGVEC was built on the momentary obstack. Make it
+ permanent now. */
+ argvec = copy_to_permanent (argvec);
DECL_TEMPLATE_INFO (r)
= perm_tree_cons (gen_tmpl, argvec, NULL_TREE);
SET_DECL_IMPLICIT_INSTANTIATION (r);
@@ -5204,10 +5666,30 @@ tsubst_decl (t, args, type, in_decl)
mess up our TREE_CHAIN because it doesn't find a
previous decl. Sigh. */
if (member
+ && ! uses_template_parms (r)
&& (IDENTIFIER_GLOBAL_VALUE (DECL_ASSEMBLER_NAME (r))
== NULL_TREE))
SET_IDENTIFIER_GLOBAL_VALUE (DECL_ASSEMBLER_NAME (r), r);
}
+
+ /* Copy the list of befriending classes. */
+ for (friends = &DECL_BEFRIENDING_CLASSES (r);
+ *friends;
+ friends = &TREE_CHAIN (*friends))
+ {
+ *friends = copy_node (*friends);
+ TREE_VALUE (*friends) = tsubst (TREE_VALUE (*friends),
+ args, /*complain=*/1,
+ in_decl);
+ }
+
+ if (DECL_CONSTRUCTOR_P (r))
+ {
+ maybe_retrofit_in_chrg (r);
+ grok_ctor_properties (ctx, r);
+ }
+ if (IDENTIFIER_OPNAME_P (DECL_NAME (r)))
+ grok_op_properties (r, DECL_VIRTUAL_P (r), DECL_FRIEND_P (r));
}
break;
@@ -5218,7 +5700,8 @@ tsubst_decl (t, args, type, in_decl)
if (TREE_CODE (DECL_INITIAL (r)) != TEMPLATE_PARM_INDEX)
DECL_INITIAL (r) = TREE_TYPE (r);
else
- DECL_INITIAL (r) = tsubst (DECL_INITIAL (r), args, in_decl);
+ DECL_INITIAL (r) = tsubst (DECL_INITIAL (r), args,
+ /*complain=*/1, in_decl);
DECL_CONTEXT (r) = NULL_TREE;
#ifdef PROMOTE_PROTOTYPES
@@ -5228,7 +5711,8 @@ tsubst_decl (t, args, type, in_decl)
DECL_ARG_TYPE (r) = integer_type_node;
#endif
if (TREE_CHAIN (t))
- TREE_CHAIN (r) = tsubst (TREE_CHAIN (t), args, TREE_CHAIN (t));
+ TREE_CHAIN (r) = tsubst (TREE_CHAIN (t), args,
+ /*complain=*/1, TREE_CHAIN (t));
}
break;
@@ -5238,11 +5722,13 @@ tsubst_decl (t, args, type, in_decl)
TREE_TYPE (r) = type;
copy_lang_decl (r);
#if 0
- DECL_FIELD_CONTEXT (r) = tsubst (DECL_FIELD_CONTEXT (t), args, in_decl);
+ DECL_FIELD_CONTEXT (r) = tsubst (DECL_FIELD_CONTEXT (t), args,
+ /*complain=*/1, in_decl);
#endif
- DECL_INITIAL (r) = tsubst_expr (DECL_INITIAL (t), args, in_decl);
+ DECL_INITIAL (r) = tsubst_expr (DECL_INITIAL (t), args,
+ /*complain=*/1, in_decl);
TREE_CHAIN (r) = NULL_TREE;
- if (TREE_CODE (type) == VOID_TYPE)
+ if (TREE_CODE (type) == VOID_TYPE)
cp_error_at ("instantiation of `%D' as type void", r);
}
break;
@@ -5251,7 +5737,7 @@ tsubst_decl (t, args, type, in_decl)
{
r = copy_node (t);
DECL_INITIAL (r)
- = tsubst_copy (DECL_INITIAL (t), args, in_decl);
+ = tsubst_copy (DECL_INITIAL (t), args, /*complain=*/1, in_decl);
TREE_CHAIN (r) = NULL_TREE;
}
break;
@@ -5262,8 +5748,9 @@ tsubst_decl (t, args, type, in_decl)
tree gen_tmpl;
tree spec;
tree tmpl;
- tree ctx = tsubst_aggr_type (DECL_CONTEXT (t), args, in_decl,
- /*entering_scope=*/1);
+ tree ctx = tsubst_aggr_type (DECL_CONTEXT (t), args,
+ /*complain=*/1,
+ in_decl, /*entering_scope=*/1);
/* Nobody should be tsubst'ing into non-template variables. */
my_friendly_assert (DECL_LANG_SPECIFIC (t)
@@ -5272,7 +5759,7 @@ tsubst_decl (t, args, type, in_decl)
/* Check to see if we already have this specialization. */
tmpl = DECL_TI_TEMPLATE (t);
gen_tmpl = most_general_template (tmpl);
- argvec = tsubst (DECL_TI_ARGS (t), args, in_decl);
+ argvec = tsubst (DECL_TI_ARGS (t), args, /*complain=*/1, in_decl);
spec = retrieve_specialization (gen_tmpl, argvec);
if (spec)
@@ -5331,10 +5818,11 @@ tsubst_decl (t, args, type, in_decl)
/* Substitue into the ARG_TYPES of a function type. */
-tree
-tsubst_arg_types (arg_types, args, in_decl)
+static tree
+tsubst_arg_types (arg_types, args, complain, in_decl)
tree arg_types;
tree args;
+ int complain;
tree in_decl;
{
tree remaining_arg_types;
@@ -5344,13 +5832,17 @@ tsubst_arg_types (arg_types, args, in_decl)
return arg_types;
remaining_arg_types = tsubst_arg_types (TREE_CHAIN (arg_types),
- args, in_decl);
+ args, complain, in_decl);
+ if (remaining_arg_types == error_mark_node)
+ return error_mark_node;
+
+ type = tsubst (TREE_VALUE (arg_types), args, complain, in_decl);
+ if (type == error_mark_node)
+ return error_mark_node;
- /* We use TYPE_MAIN_VARIANT is because top-level qualifiers don't
- matter on function types. */
- type = TYPE_MAIN_VARIANT (type_decays_to
- (tsubst (TREE_VALUE (arg_types),
- args, in_decl)));
+ /* Do array-to-pointer, function-to-pointer conversion, and ignore
+ top-level qualifiers as required. */
+ type = TYPE_MAIN_VARIANT (type_decays_to (type));
/* Note that we do not substitute into default arguments here. The
standard mandates that they be instantiated only when needed,
@@ -5360,19 +5852,137 @@ tsubst_arg_types (arg_types, args, in_decl)
}
-/* Take the tree structure T and replace template parameters used therein
- with the argument vector ARGS. IN_DECL is an associated decl for
- diagnostics.
+/* Substitute into a FUNCTION_TYPE or METHOD_TYPE. This routine does
+ *not* handle the exception-specification for FNTYPE, because the
+ initial substitution of explicitly provided template parameters
+ during argument deduction forbids substitution into the
+ exception-specification:
+
+ [temp.deduct]
+
+ All references in the function type of the function template to the
+ corresponding template parameters are replaced by the specified tem-
+ plate argument values. If a substitution in a template parameter or
+ in the function type of the function template results in an invalid
+ type, type deduction fails. [Note: The equivalent substitution in
+ exception specifications is done only when the function is instanti-
+ ated, at which point a program is ill-formed if the substitution
+ results in an invalid type.] */
+
+static tree
+tsubst_function_type (t, args, complain, in_decl)
+ tree t;
+ tree args;
+ int complain;
+ tree in_decl;
+{
+ tree return_type;
+ tree arg_types;
+ tree fntype;
+
+ /* The TYPE_CONTEXT is not used for function/method types. */
+ my_friendly_assert (TYPE_CONTEXT (t) == NULL_TREE, 0);
+
+ /* Substitue the return type. */
+ return_type = tsubst (TREE_TYPE (t), args, complain, in_decl);
+ if (return_type == error_mark_node)
+ return error_mark_node;
+
+ /* Substitue the argument types. */
+ arg_types = tsubst_arg_types (TYPE_ARG_TYPES (t), args,
+ complain, in_decl);
+ if (arg_types == error_mark_node)
+ return error_mark_node;
+
+ /* Construct a new type node and return it. */
+ if (TREE_CODE (t) == FUNCTION_TYPE)
+ fntype = build_function_type (return_type, arg_types);
+ else
+ {
+ tree r = TREE_TYPE (TREE_VALUE (arg_types));
+ if (! IS_AGGR_TYPE (r))
+ {
+ /* [temp.deduct]
+
+ Type deduction may fail for any of the following
+ reasons:
+
+ -- Attempting to create "pointer to member of T" when T
+ is not a class type. */
+ if (complain)
+ cp_error ("creating pointer to member function of non-class type `%T'",
+ r);
+ return error_mark_node;
+ }
+
+ fntype = build_cplus_method_type (r, return_type, TREE_CHAIN
+ (arg_types));
+ }
+ fntype = build_qualified_type (fntype, TYPE_QUALS (t));
+
+ return fntype;
+}
+
+/* Substitute into the PARMS of a call-declarator. */
+
+static tree
+tsubst_call_declarator_parms (parms, args, complain, in_decl)
+ tree parms;
+ tree args;
+ int complain;
+ tree in_decl;
+{
+ tree new_parms;
+ tree type;
+ tree defarg;
+
+ if (!parms || parms == void_list_node)
+ return parms;
+
+ new_parms = tsubst_call_declarator_parms (TREE_CHAIN (parms),
+ args, complain, in_decl);
+
+ /* Figure out the type of this parameter. */
+ type = tsubst (TREE_VALUE (parms), args, complain, in_decl);
+
+ /* Figure out the default argument as well. Note that we use
+ tsubst_expr since the default argument is really an expression. */
+ defarg = tsubst_expr (TREE_PURPOSE (parms), args, complain, in_decl);
+
+ /* Chain this parameter on to the front of those we have already
+ processed. We don't use hash_tree_cons because that function
+ doesn't check TREE_PARMLIST. */
+ new_parms = tree_cons (defarg, type, new_parms);
+
+ /* And note that these are parameters. */
+ TREE_PARMLIST (new_parms) = 1;
+
+ return new_parms;
+}
- tsubst is used for dealing with types, decls and the like; for
- expressions, use tsubst_expr or tsubst_copy. */
+/* Take the tree structure T and replace template parameters used
+ therein with the argument vector ARGS. IN_DECL is an associated
+ decl for diagnostics. If an error occurs, returns ERROR_MARK_NODE.
+ An appropriate error message is issued only if COMPLAIN is
+ non-zero. Note that we must be relatively non-tolerant of
+ extensions here, in order to preserve conformance; if we allow
+ substitutions that should not be allowed, we may allow argument
+ deductions that should not succeed, and therefore report ambiguous
+ overload situations where there are none. In theory, we could
+ allow the substitution, but indicate that it should have failed,
+ and allow our caller to make sure that the right thing happens, but
+ we don't try to do this yet.
+
+ This function is used for dealing with types, decls and the like;
+ for expressions, use tsubst_expr or tsubst_copy. */
tree
-tsubst (t, args, in_decl)
+tsubst (t, args, complain, in_decl)
tree t, args;
+ int complain;
tree in_decl;
{
- tree type;
+ tree type, r;
if (t == NULL_TREE || t == error_mark_node
|| t == integer_type_node
@@ -5391,8 +6001,12 @@ tsubst (t, args, in_decl)
if (type && TREE_CODE (t) != FUNCTION_DECL
&& TREE_CODE (t) != TYPENAME_TYPE
&& TREE_CODE (t) != TEMPLATE_DECL
- && TREE_CODE (t) != IDENTIFIER_NODE)
- type = tsubst (type, args, in_decl);
+ && TREE_CODE (t) != IDENTIFIER_NODE
+ && TREE_CODE (t) != FUNCTION_TYPE
+ && TREE_CODE (t) != METHOD_TYPE)
+ type = tsubst (type, args, complain, in_decl);
+ if (type == error_mark_node)
+ return error_mark_node;
if (TREE_CODE_CLASS (TREE_CODE (t)) == 'd')
return tsubst_decl (t, args, type, in_decl);
@@ -5402,7 +6016,8 @@ tsubst (t, args, in_decl)
case RECORD_TYPE:
case UNION_TYPE:
case ENUMERAL_TYPE:
- return tsubst_aggr_type (t, args, in_decl, /*entering_scope=*/0);
+ return tsubst_aggr_type (t, args, complain, in_decl,
+ /*entering_scope=*/0);
case ERROR_MARK:
case IDENTIFIER_NODE:
@@ -5425,8 +6040,12 @@ tsubst (t, args, in_decl)
return t;
{
- tree max = TREE_OPERAND (TYPE_MAX_VALUE (t), 0);
- max = tsubst_expr (max, args, in_decl);
+ tree max, omax = TREE_OPERAND (TYPE_MAX_VALUE (t), 0);
+
+ max = tsubst_expr (omax, args, complain, in_decl);
+ if (max == error_mark_node)
+ return error_mark_node;
+
if (processing_template_decl)
{
tree itype = make_node (INTEGER_TYPE);
@@ -5436,8 +6055,31 @@ tsubst (t, args, in_decl)
return itype;
}
+ if (integer_zerop (omax))
+ {
+ /* Still allow an explicit array of size zero. */
+ if (pedantic)
+ pedwarn ("creating array with size zero");
+ }
+ else if (integer_zerop (max) || INT_CST_LT (max, integer_zero_node))
+ {
+ /* [temp.deduct]
+
+ Type deduction may fail for any of the following
+ reasons:
+
+ Attempting to create an array with a size that is
+ zero or negative. */
+ if (complain)
+ cp_error ("creating array with size `%E'", max);
+
+ return error_mark_node;
+ }
+
max = fold (build_binary_op (MINUS_EXPR, max, integer_one_node, 1));
- return build_index_2_type (size_zero_node, max);
+ if (!TREE_PERMANENT (max) && !allocation_temporary_p ())
+ max = copy_to_permanent (max);
+ return build_index_type (max);
}
case TEMPLATE_TYPE_PARM:
@@ -5447,7 +6089,8 @@ tsubst (t, args, in_decl)
int idx;
int level;
int levels;
- tree r = NULL_TREE;
+
+ r = NULL_TREE;
if (TREE_CODE (t) == TEMPLATE_TYPE_PARM
|| TREE_CODE (t) == TEMPLATE_TEMPLATE_PARM)
@@ -5477,20 +6120,20 @@ tsubst (t, args, in_decl)
{
my_friendly_assert (TREE_CODE_CLASS (TREE_CODE (arg))
== 't', 0);
- return cp_build_type_variant
- (arg, TYPE_READONLY (arg) || TYPE_READONLY (t),
- TYPE_VOLATILE (arg) || TYPE_VOLATILE (t));
+ return cp_build_qualified_type
+ (arg, CP_TYPE_QUALS (arg) | CP_TYPE_QUALS (t));
}
else if (TREE_CODE (t) == TEMPLATE_TEMPLATE_PARM)
{
- if (CLASSTYPE_TEMPLATE_INFO (t))
+ if (TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (t))
{
/* We are processing a type constructed from
a template template parameter */
- tree argvec = tsubst (CLASSTYPE_TI_ARGS (t),
- args, in_decl);
- tree r;
-
+ tree argvec = tsubst (TYPE_TI_ARGS (t),
+ args, complain, in_decl);
+ if (argvec == error_mark_node)
+ return error_mark_node;
+
/* We can get a TEMPLATE_TEMPLATE_PARM here when
we are resolving nested-types in the signature of
a member function templates.
@@ -5503,8 +6146,7 @@ tsubst (t, args, in_decl)
argvec, in_decl,
DECL_CONTEXT (arg),
/*entering_scope=*/0);
- return cp_build_type_variant (r, TYPE_READONLY (t),
- TYPE_VOLATILE (t));
+ return cp_build_qualified_type (r, TYPE_QUALS (t));
}
else
/* We are processing a template argument list. */
@@ -5514,6 +6156,8 @@ tsubst (t, args, in_decl)
return arg;
}
}
+ else
+ my_friendly_abort (981018);
if (level == 1)
/* This can happen during the attempted tsubst'ing in
@@ -5538,10 +6182,14 @@ tsubst (t, args, in_decl)
TYPE_REFERENCE_TO (r) = NULL_TREE;
if (TREE_CODE (t) == TEMPLATE_TEMPLATE_PARM
- && CLASSTYPE_TEMPLATE_INFO (t))
+ && TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (t))
{
- tree argvec = tsubst (CLASSTYPE_TI_ARGS (t), args, in_decl);
- CLASSTYPE_TEMPLATE_INFO (r)
+ tree argvec = tsubst (TYPE_TI_ARGS (t), args,
+ complain, in_decl);
+ if (argvec == error_mark_node)
+ return error_mark_node;
+
+ TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (r)
= perm_tree_cons (TYPE_NAME (t), argvec, NULL_TREE);
}
break;
@@ -5571,13 +6219,25 @@ tsubst (t, args, in_decl)
purpose = TREE_PURPOSE (t);
if (purpose)
- purpose = tsubst (purpose, args, in_decl);
+ {
+ purpose = tsubst (purpose, args, complain, in_decl);
+ if (purpose == error_mark_node)
+ return error_mark_node;
+ }
value = TREE_VALUE (t);
if (value)
- value = tsubst (value, args, in_decl);
+ {
+ value = tsubst (value, args, complain, in_decl);
+ if (value == error_mark_node)
+ return error_mark_node;
+ }
chain = TREE_CHAIN (t);
if (chain && chain != void_type_node)
- chain = tsubst (chain, args, in_decl);
+ {
+ chain = tsubst (chain, args, complain, in_decl);
+ if (chain == error_mark_node)
+ return error_mark_node;
+ }
if (purpose == TREE_PURPOSE (t)
&& value == TREE_VALUE (t)
&& chain == TREE_CHAIN (t))
@@ -5610,19 +6270,29 @@ tsubst (t, args, in_decl)
}
/* Otherwise, a vector of template arguments. */
- return tsubst_template_arg_vector (t, args);
+ return tsubst_template_arg_vector (t, args, complain);
case POINTER_TYPE:
case REFERENCE_TYPE:
{
- tree r;
enum tree_code code;
if (type == TREE_TYPE (t))
return t;
code = TREE_CODE (t);
- if (TREE_CODE (type) == REFERENCE_TYPE)
+
+
+ /* [temp.deduct]
+
+ Type deduction may fail for any of the following
+ reasons:
+
+ -- Attempting to create a pointer to reference type.
+ -- Attempting to create a reference to a reference type or
+ a reference to void. */
+ if (TREE_CODE (type) == REFERENCE_TYPE
+ || (code == REFERENCE_TYPE && TREE_CODE (type) == VOID_TYPE))
{
static int last_line = 0;
static char* last_file = 0;
@@ -5630,141 +6300,235 @@ tsubst (t, args, in_decl)
/* We keep track of the last time we issued this error
message to avoid spewing a ton of messages during a
single bad template instantiation. */
- if (last_line != lineno ||
- last_file != input_filename)
+ if (complain && (last_line != lineno ||
+ last_file != input_filename))
{
- cp_error ("cannot form type %s to reference type %T during template instantiation",
- (code == POINTER_TYPE) ? "pointer" : "reference",
- type);
+ if (TREE_CODE (type) == VOID_TYPE)
+ cp_error ("forming reference to void");
+ else
+ cp_error ("forming %s to reference type `%T'",
+ (code == POINTER_TYPE) ? "pointer" : "reference",
+ type);
last_line = lineno;
last_file = input_filename;
}
- /* Use the underlying type in an attempt at error
- recovery; maybe the user meant vector<int> and wrote
- vector<int&>, or some such. */
- if (code == REFERENCE_TYPE)
- r = type;
- else
- r = build_pointer_type (TREE_TYPE (type));
+ return error_mark_node;
}
else if (code == POINTER_TYPE)
r = build_pointer_type (type);
else
r = build_reference_type (type);
- r = cp_build_type_variant (r, TYPE_READONLY (t), TYPE_VOLATILE (t));
+ r = cp_build_qualified_type (r, TYPE_QUALS (t));
/* Will this ever be needed for TYPE_..._TO values? */
layout_type (r);
return r;
}
case OFFSET_TYPE:
- return build_offset_type
- (tsubst (TYPE_OFFSET_BASETYPE (t), args, in_decl), type);
+ {
+ r = tsubst (TYPE_OFFSET_BASETYPE (t), args, complain, in_decl);
+ if (r == error_mark_node || !IS_AGGR_TYPE (r))
+ {
+ /* [temp.deduct]
+
+ Type deduction may fail for any of the following
+ reasons:
+
+ -- Attempting to create "pointer to member of T" when T
+ is not a class type. */
+ if (complain)
+ cp_error ("creating pointer to member of non-class type `%T'",
+ r);
+ return error_mark_node;
+ }
+ return build_offset_type (r, type);
+ }
case FUNCTION_TYPE:
case METHOD_TYPE:
{
- tree arg_types;
- tree raises;
tree fntype;
+ tree raises;
- /* The TYPE_CONTEXT is not used for function/method types. */
- my_friendly_assert (TYPE_CONTEXT (t) == NULL_TREE, 0);
-
- /* Substitue the argument types. */
- arg_types = tsubst_arg_types (TYPE_ARG_TYPES (t), args, in_decl);
-
- /* Construct a new type node and return it. */
- if (TREE_CODE (t) == FUNCTION_TYPE)
- fntype = build_function_type (type, arg_types);
- else
- fntype
- = build_cplus_method_type (TREE_TYPE (TREE_VALUE (arg_types)),
- type,
- TREE_CHAIN (arg_types));
-
- fntype = build_type_variant (fntype,
- TYPE_READONLY (t),
- TYPE_VOLATILE (t));
+ fntype = tsubst_function_type (t, args, complain, in_decl);
+ if (fntype == error_mark_node)
+ return error_mark_node;
/* Substitue the exception specification. */
raises = TYPE_RAISES_EXCEPTIONS (t);
if (raises)
{
- raises = tsubst (raises, args, in_decl);
+ raises = tsubst (raises, args, complain, in_decl);
+ if (raises == error_mark_node)
+ return raises;
fntype = build_exception_variant (fntype, raises);
}
return fntype;
}
case ARRAY_TYPE:
{
- tree domain = tsubst (TYPE_DOMAIN (t), args, in_decl);
- tree r;
+ tree domain = tsubst (TYPE_DOMAIN (t), args, complain, in_decl);
+ if (domain == error_mark_node)
+ return error_mark_node;
+
+ /* As an optimization, we avoid regenerating the array type if
+ it will obviously be the same as T. */
if (type == TREE_TYPE (t) && domain == TYPE_DOMAIN (t))
return t;
+
+ /* These checks should match the ones in grokdeclarator.
+
+ [temp.deduct]
+
+ The deduction may fail for any of the following reasons:
+
+ -- Attempting to create an array with an element type that
+ is void, a function type, or a reference type. */
+ if (TREE_CODE (type) == VOID_TYPE
+ || TREE_CODE (type) == FUNCTION_TYPE
+ || TREE_CODE (type) == REFERENCE_TYPE)
+ {
+ if (complain)
+ cp_error ("creating array of `%T'", type);
+ return error_mark_node;
+ }
+
r = build_cplus_array_type (type, domain);
return r;
}
case PLUS_EXPR:
case MINUS_EXPR:
- return fold (build (TREE_CODE (t), TREE_TYPE (t),
- tsubst (TREE_OPERAND (t, 0), args, in_decl),
- tsubst (TREE_OPERAND (t, 1), args, in_decl)));
+ {
+ tree e1 = tsubst (TREE_OPERAND (t, 0), args, complain,
+ in_decl);
+ tree e2 = tsubst (TREE_OPERAND (t, 1), args, complain,
+ in_decl);
+
+ if (e1 == error_mark_node || e2 == error_mark_node)
+ return error_mark_node;
+
+ return fold (build (TREE_CODE (t), TREE_TYPE (t), e1, e2));
+ }
case NEGATE_EXPR:
case NOP_EXPR:
- return fold (build1 (TREE_CODE (t), TREE_TYPE (t),
- tsubst (TREE_OPERAND (t, 0), args, in_decl)));
+ {
+ tree e = tsubst (TREE_OPERAND (t, 0), args, complain,
+ in_decl);
+ if (e == error_mark_node)
+ return error_mark_node;
+
+ return fold (build (TREE_CODE (t), TREE_TYPE (t), e));
+ }
case TYPENAME_TYPE:
{
- tree ctx = tsubst_aggr_type (TYPE_CONTEXT (t), args, in_decl,
- /*entering_scope=*/1);
- tree f = tsubst_copy (TYPENAME_TYPE_FULLNAME (t), args, in_decl);
+ tree ctx = tsubst_aggr_type (TYPE_CONTEXT (t), args, complain,
+ in_decl, /*entering_scope=*/1);
+ tree f = tsubst_copy (TYPENAME_TYPE_FULLNAME (t), args,
+ complain, in_decl);
+
+ if (ctx == error_mark_node || f == error_mark_node)
+ return error_mark_node;
- /* Normally, make_typename_type does not require that the CTX
- have complete type in order to allow things like:
+ if (!IS_AGGR_TYPE (ctx))
+ {
+ if (complain)
+ cp_error ("`%T' is not a class, struct, or union type",
+ ctx);
+ return error_mark_node;
+ }
+ else if (!uses_template_parms (ctx) && !TYPE_BEING_DEFINED (ctx))
+ {
+ /* Normally, make_typename_type does not require that the CTX
+ have complete type in order to allow things like:
- template <class T> struct S { typename S<T>::X Y; };
+ template <class T> struct S { typename S<T>::X Y; };
- But, such constructs have already been resolved by this
- point, so here CTX really should have complete type, unless
- it's a partial instantiation. */
- if (!uses_template_parms (ctx)
- && !complete_type_or_else (ctx))
- return error_mark_node;
+ But, such constructs have already been resolved by this
+ point, so here CTX really should have complete type, unless
+ it's a partial instantiation. */
+ ctx = complete_type (ctx);
+ if (!TYPE_SIZE (ctx))
+ {
+ if (complain)
+ incomplete_type_error (NULL_TREE, ctx);
+ return error_mark_node;
+ }
+ }
f = make_typename_type (ctx, f);
- return cp_build_type_variant
- (f, TYPE_READONLY (f) || TYPE_READONLY (t),
- TYPE_VOLATILE (f) || TYPE_VOLATILE (t));
+ return cp_build_qualified_type (f,
+ CP_TYPE_QUALS (f)
+ | CP_TYPE_QUALS (t));
}
case INDIRECT_REF:
- return make_pointer_declarator
- (type, tsubst (TREE_OPERAND (t, 0), args, in_decl));
-
+ {
+ tree e = tsubst (TREE_OPERAND (t, 0), args, complain,
+ in_decl);
+ if (e == error_mark_node)
+ return error_mark_node;
+ return make_pointer_declarator (type, e);
+ }
+
case ADDR_EXPR:
- return make_reference_declarator
- (type, tsubst (TREE_OPERAND (t, 0), args, in_decl));
+ {
+ tree e = tsubst (TREE_OPERAND (t, 0), args, complain,
+ in_decl);
+ if (e == error_mark_node)
+ return error_mark_node;
+ return make_reference_declarator (type, e);
+ }
case ARRAY_REF:
- return build_parse_node
- (ARRAY_REF, tsubst (TREE_OPERAND (t, 0), args, in_decl),
- tsubst_expr (TREE_OPERAND (t, 1), args, in_decl));
+ {
+ tree e1 = tsubst (TREE_OPERAND (t, 0), args, complain,
+ in_decl);
+ tree e2 = tsubst_expr (TREE_OPERAND (t, 1), args, complain,
+ in_decl);
+ if (e1 == error_mark_node || e2 == error_mark_node)
+ return error_mark_node;
+
+ return build_parse_node (ARRAY_REF, e1, e2, tsubst_expr);
+ }
case CALL_EXPR:
- return make_call_declarator
- (tsubst (TREE_OPERAND (t, 0), args, in_decl),
- tsubst (TREE_OPERAND (t, 1), args, in_decl),
- TREE_OPERAND (t, 2),
- tsubst (TREE_TYPE (t), args, in_decl));
+ {
+ tree e1 = tsubst (TREE_OPERAND (t, 0), args, complain,
+ in_decl);
+ tree e2 = tsubst_call_declarator_parms (TREE_OPERAND (t, 1), args,
+ complain, in_decl);
+ tree e3 = tsubst (TREE_TYPE (t), args, complain, in_decl);
+
+ if (e1 == error_mark_node || e2 == error_mark_node
+ || e3 == error_mark_node)
+ return error_mark_node;
+
+ return make_call_declarator (e1, e2, TREE_OPERAND (t, 2), e3);
+ }
case SCOPE_REF:
- return build_parse_node
- (TREE_CODE (t), tsubst (TREE_OPERAND (t, 0), args, in_decl),
- tsubst (TREE_OPERAND (t, 1), args, in_decl));
+ {
+ tree e1 = tsubst (TREE_OPERAND (t, 0), args, complain,
+ in_decl);
+ tree e2 = tsubst (TREE_OPERAND (t, 1), args, complain, in_decl);
+ if (e1 == error_mark_node || e2 == error_mark_node)
+ return error_mark_node;
+
+ return build_parse_node (TREE_CODE (t), e1, e2);
+ }
+
+ case TYPEOF_TYPE:
+ {
+ tree e1 = tsubst_expr (TYPE_FIELDS (t), args, complain,
+ in_decl);
+ if (e1 == error_mark_node)
+ return error_mark_node;
+
+ return TREE_TYPE (e1);
+ }
default:
sorry ("use of `%s' in template",
@@ -5807,11 +6571,13 @@ do_poplevel ()
tsubst_expr. */
tree
-tsubst_copy (t, args, in_decl)
+tsubst_copy (t, args, complain, in_decl)
tree t, args;
+ int complain;
tree in_decl;
{
enum tree_code code;
+ tree r;
if (t == NULL_TREE || t == error_mark_node)
return t;
@@ -5843,7 +6609,7 @@ tsubst_copy (t, args, in_decl)
When we instantiate f<7>::S::g(), say, lookup_name is not
clever enough to find f<7>::a. */
enum_type
- = tsubst_aggr_type (TREE_TYPE (t), args, in_decl,
+ = tsubst_aggr_type (TREE_TYPE (t), args, complain, in_decl,
/*entering_scope=*/0);
for (v = TYPE_VALUES (enum_type);
@@ -5864,7 +6630,7 @@ tsubst_copy (t, args, in_decl)
{
tree ctx;
- ctx = tsubst_aggr_type (DECL_CONTEXT (t), args, in_decl,
+ ctx = tsubst_aggr_type (DECL_CONTEXT (t), args, complain, in_decl,
/*entering_scope=*/1);
if (ctx != DECL_CONTEXT (t))
return lookup_field (ctx, DECL_NAME (t), 0, 0);
@@ -5874,13 +6640,13 @@ tsubst_copy (t, args, in_decl)
case VAR_DECL:
case FUNCTION_DECL:
if (DECL_LANG_SPECIFIC (t) && DECL_TEMPLATE_INFO (t))
- t = tsubst (t, args, in_decl);
+ t = tsubst (t, args, complain, in_decl);
mark_used (t);
return t;
case TEMPLATE_DECL:
if (is_member_template (t))
- return tsubst (t, args, in_decl);
+ return tsubst (t, args, complain, in_decl);
else
return t;
@@ -5891,11 +6657,11 @@ tsubst_copy (t, args, in_decl)
name will change. We avoid making unnecessary copies,
however. */
- tree id = tsubst_copy (TREE_OPERAND (t, 0), args, in_decl);
+ tree id = tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl);
if (id != TREE_OPERAND (t, 0))
{
- tree r = build_nt (LOOKUP_EXPR, id);
+ r = build_nt (LOOKUP_EXPR, id);
LOOKUP_EXPR_GLOBAL (r) = LOOKUP_EXPR_GLOBAL (t);
t = r;
}
@@ -5908,9 +6674,10 @@ tsubst_copy (t, args, in_decl)
case CONST_CAST_EXPR:
case STATIC_CAST_EXPR:
case DYNAMIC_CAST_EXPR:
+ case NOP_EXPR:
return build1
- (code, tsubst (TREE_TYPE (t), args, in_decl),
- tsubst_copy (TREE_OPERAND (t, 0), args, in_decl));
+ (code, tsubst (TREE_TYPE (t), args, complain, in_decl),
+ tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl));
case INDIRECT_REF:
case PREDECREMENT_EXPR:
@@ -5928,8 +6695,8 @@ tsubst_copy (t, args, in_decl)
case THROW_EXPR:
case TYPEID_EXPR:
return build1
- (code, NULL_TREE,
- tsubst_copy (TREE_OPERAND (t, 0), args, in_decl));
+ (code, tsubst (TREE_TYPE (t), args, complain, in_decl),
+ tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl));
case PLUS_EXPR:
case MINUS_EXPR:
@@ -5968,19 +6735,20 @@ tsubst_copy (t, args, in_decl)
case DOTSTAR_EXPR:
case MEMBER_REF:
return build_nt
- (code, tsubst_copy (TREE_OPERAND (t, 0), args, in_decl),
- tsubst_copy (TREE_OPERAND (t, 1), args, in_decl));
+ (code, tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl),
+ tsubst_copy (TREE_OPERAND (t, 1), args, complain, in_decl));
case CALL_EXPR:
{
tree fn = TREE_OPERAND (t, 0);
if (is_overloaded_fn (fn))
- fn = tsubst_copy (get_first_fn (fn), args, in_decl);
+ fn = tsubst_copy (get_first_fn (fn), args, complain, in_decl);
else
/* Sometimes FN is a LOOKUP_EXPR. */
- fn = tsubst_copy (fn, args, in_decl);
+ fn = tsubst_copy (fn, args, complain, in_decl);
return build_nt
- (code, fn, tsubst_copy (TREE_OPERAND (t, 1), args, in_decl),
+ (code, fn, tsubst_copy (TREE_OPERAND (t, 1), args, complain,
+ in_decl),
NULL_TREE);
}
@@ -5989,23 +6757,27 @@ tsubst_copy (t, args, in_decl)
tree name = TREE_OPERAND (t, 0);
if (TREE_CODE (name) == BIT_NOT_EXPR)
{
- name = tsubst_copy (TREE_OPERAND (name, 0), args, in_decl);
+ name = tsubst_copy (TREE_OPERAND (name, 0), args,
+ complain, in_decl);
name = build1 (BIT_NOT_EXPR, NULL_TREE, name);
}
else if (TREE_CODE (name) == SCOPE_REF
&& TREE_CODE (TREE_OPERAND (name, 1)) == BIT_NOT_EXPR)
{
- tree base = tsubst_copy (TREE_OPERAND (name, 0), args, in_decl);
+ tree base = tsubst_copy (TREE_OPERAND (name, 0), args,
+ complain, in_decl);
name = TREE_OPERAND (name, 1);
- name = tsubst_copy (TREE_OPERAND (name, 0), args, in_decl);
+ name = tsubst_copy (TREE_OPERAND (name, 0), args,
+ complain, in_decl);
name = build1 (BIT_NOT_EXPR, NULL_TREE, name);
name = build_nt (SCOPE_REF, base, name);
}
else
- name = tsubst_copy (TREE_OPERAND (t, 0), args, in_decl);
+ name = tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl);
return build_nt
- (code, name, tsubst_copy (TREE_OPERAND (t, 1), args, in_decl),
- tsubst_copy (TREE_OPERAND (t, 2), args, in_decl),
+ (code, name, tsubst_copy (TREE_OPERAND (t, 1), args,
+ complain, in_decl),
+ tsubst_copy (TREE_OPERAND (t, 2), args, complain, in_decl),
NULL_TREE);
}
@@ -6013,21 +6785,22 @@ tsubst_copy (t, args, in_decl)
case COND_EXPR:
case MODOP_EXPR:
{
- tree r = build_nt
- (code, tsubst_copy (TREE_OPERAND (t, 0), args, in_decl),
- tsubst_copy (TREE_OPERAND (t, 1), args, in_decl),
- tsubst_copy (TREE_OPERAND (t, 2), args, in_decl));
+ r = build_nt
+ (code, tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl),
+ tsubst_copy (TREE_OPERAND (t, 1), args, complain, in_decl),
+ tsubst_copy (TREE_OPERAND (t, 2), args, complain, in_decl));
if (code == BIND_EXPR && !processing_template_decl)
{
- /* This processing should really occur in tsubst_expr,
+ /* This processing should really occur in tsubst_expr,
However, tsubst_expr does not recurse into expressions,
since it assumes that there aren't any statements
inside them. Instead, it simply calls
build_expr_from_tree. So, we need to expand the
BIND_EXPR here. */
tree rtl_expr = begin_stmt_expr ();
- tree block = tsubst_expr (TREE_OPERAND (r, 1), args, in_decl);
+ tree block = tsubst_expr (TREE_OPERAND (r, 1), args,
+ complain, in_decl);
r = finish_stmt_expr (rtl_expr, block);
}
@@ -6036,19 +6809,19 @@ tsubst_copy (t, args, in_decl)
case NEW_EXPR:
{
- tree r = build_nt
- (code, tsubst_copy (TREE_OPERAND (t, 0), args, in_decl),
- tsubst_copy (TREE_OPERAND (t, 1), args, in_decl),
- tsubst_copy (TREE_OPERAND (t, 2), args, in_decl));
+ r = build_nt
+ (code, tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl),
+ tsubst_copy (TREE_OPERAND (t, 1), args, complain, in_decl),
+ tsubst_copy (TREE_OPERAND (t, 2), args, complain, in_decl));
NEW_EXPR_USE_GLOBAL (r) = NEW_EXPR_USE_GLOBAL (t);
return r;
}
case DELETE_EXPR:
{
- tree r = build_nt
- (code, tsubst_copy (TREE_OPERAND (t, 0), args, in_decl),
- tsubst_copy (TREE_OPERAND (t, 1), args, in_decl));
+ r = build_nt
+ (code, tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl),
+ tsubst_copy (TREE_OPERAND (t, 1), args, complain, in_decl));
DELETE_EXPR_USE_GLOBAL (r) = DELETE_EXPR_USE_GLOBAL (t);
DELETE_EXPR_USE_VEC (r) = DELETE_EXPR_USE_VEC (t);
return r;
@@ -6057,13 +6830,14 @@ tsubst_copy (t, args, in_decl)
case TEMPLATE_ID_EXPR:
{
/* Substituted template arguments */
- tree targs = tsubst_copy (TREE_OPERAND (t, 1), args, in_decl);
+ tree targs = tsubst_copy (TREE_OPERAND (t, 1), args, complain,
+ in_decl);
tree chain;
for (chain = targs; chain; chain = TREE_CHAIN (chain))
TREE_VALUE (chain) = maybe_fold_nontype_arg (TREE_VALUE (chain));
return lookup_template_function
- (tsubst_copy (TREE_OPERAND (t, 0), args, in_decl), targs);
+ (tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl), targs);
}
case TREE_LIST:
@@ -6075,13 +6849,13 @@ tsubst_copy (t, args, in_decl)
purpose = TREE_PURPOSE (t);
if (purpose)
- purpose = tsubst_copy (purpose, args, in_decl);
+ purpose = tsubst_copy (purpose, args, complain, in_decl);
value = TREE_VALUE (t);
if (value)
- value = tsubst_copy (value, args, in_decl);
+ value = tsubst_copy (value, args, complain, in_decl);
chain = TREE_CHAIN (t);
if (chain && chain != void_type_node)
- chain = tsubst_copy (chain, args, in_decl);
+ chain = tsubst_copy (chain, args, complain, in_decl);
if (purpose == TREE_PURPOSE (t)
&& value == TREE_VALUE (t)
&& chain == TREE_CHAIN (t))
@@ -6104,7 +6878,7 @@ tsubst_copy (t, args, in_decl)
case ARRAY_TYPE:
case TYPENAME_TYPE:
case TYPE_DECL:
- return tsubst (t, args, in_decl);
+ return tsubst (t, args, complain, in_decl);
case IDENTIFIER_NODE:
if (IDENTIFIER_TYPENAME_P (t)
@@ -6112,14 +6886,19 @@ tsubst_copy (t, args, in_decl)
which can occur in some existing code. */
&& TREE_TYPE (t))
return build_typename_overload
- (tsubst (TREE_TYPE (t), args, in_decl));
+ (tsubst (TREE_TYPE (t), args, complain, in_decl));
else
return t;
case CONSTRUCTOR:
- return build
- (CONSTRUCTOR, tsubst (TREE_TYPE (t), args, in_decl), NULL_TREE,
- tsubst_copy (CONSTRUCTOR_ELTS (t), args, in_decl));
+ {
+ r = build
+ (CONSTRUCTOR, tsubst (TREE_TYPE (t), args, complain, in_decl),
+ NULL_TREE, tsubst_copy (CONSTRUCTOR_ELTS (t), args,
+ complain, in_decl));
+ TREE_HAS_CONSTRUCTOR (r) = TREE_HAS_CONSTRUCTOR (t);
+ return r;
+ }
default:
return t;
@@ -6129,28 +6908,29 @@ tsubst_copy (t, args, in_decl)
/* Like tsubst_copy, but also does semantic processing and RTL expansion. */
tree
-tsubst_expr (t, args, in_decl)
+tsubst_expr (t, args, complain, in_decl)
tree t, args;
+ int complain;
tree in_decl;
{
if (t == NULL_TREE || t == error_mark_node)
return t;
if (processing_template_decl)
- return tsubst_copy (t, args, in_decl);
+ return tsubst_copy (t, args, complain, in_decl);
switch (TREE_CODE (t))
{
case RETURN_STMT:
lineno = TREE_COMPLEXITY (t);
finish_return_stmt (tsubst_expr (RETURN_EXPR (t),
- args, in_decl));
+ args, complain, in_decl));
break;
case EXPR_STMT:
lineno = TREE_COMPLEXITY (t);
finish_expr_stmt (tsubst_expr (EXPR_STMT_EXPR (t),
- args, in_decl));
+ args, complain, in_decl));
break;
case DECL_STMT:
@@ -6161,10 +6941,10 @@ tsubst_expr (t, args, in_decl)
lineno = TREE_COMPLEXITY (t);
emit_line_note (input_filename, lineno);
dcl = start_decl
- (tsubst (TREE_OPERAND (t, 0), args, in_decl),
- tsubst (TREE_OPERAND (t, 1), args, in_decl),
+ (tsubst (TREE_OPERAND (t, 0), args, complain, in_decl),
+ tsubst (TREE_OPERAND (t, 1), args, complain, in_decl),
TREE_OPERAND (t, 2) != 0, NULL_TREE, NULL_TREE);
- init = tsubst_expr (TREE_OPERAND (t, 2), args, in_decl);
+ init = tsubst_expr (TREE_OPERAND (t, 2), args, complain, in_decl);
cp_finish_decl
(dcl, init, NULL_TREE, 1, /*init ? LOOKUP_ONLYCONVERTING :*/ 0);
resume_momentary (i);
@@ -6178,14 +6958,14 @@ tsubst_expr (t, args, in_decl)
begin_for_stmt ();
for (tmp = FOR_INIT_STMT (t); tmp; tmp = TREE_CHAIN (tmp))
- tsubst_expr (tmp, args, in_decl);
+ tsubst_expr (tmp, args, complain, in_decl);
finish_for_init_stmt (NULL_TREE);
finish_for_cond (tsubst_expr (FOR_COND (t), args,
- in_decl),
+ complain, in_decl),
NULL_TREE);
- tmp = tsubst_expr (FOR_EXPR (t), args, in_decl);
+ tmp = tsubst_expr (FOR_EXPR (t), args, complain, in_decl);
finish_for_expr (tmp, NULL_TREE);
- tsubst_expr (FOR_BODY (t), args, in_decl);
+ tsubst_expr (FOR_BODY (t), args, complain, in_decl);
finish_for_stmt (tmp, NULL_TREE);
}
break;
@@ -6195,9 +6975,9 @@ tsubst_expr (t, args, in_decl)
lineno = TREE_COMPLEXITY (t);
begin_while_stmt ();
finish_while_stmt_cond (tsubst_expr (WHILE_COND (t),
- args, in_decl),
+ args, complain, in_decl),
NULL_TREE);
- tsubst_expr (WHILE_BODY (t), args, in_decl);
+ tsubst_expr (WHILE_BODY (t), args, complain, in_decl);
finish_while_stmt (NULL_TREE);
}
break;
@@ -6206,10 +6986,10 @@ tsubst_expr (t, args, in_decl)
{
lineno = TREE_COMPLEXITY (t);
begin_do_stmt ();
- tsubst_expr (DO_BODY (t), args, in_decl);
+ tsubst_expr (DO_BODY (t), args, complain, in_decl);
finish_do_body (NULL_TREE);
finish_do_stmt (tsubst_expr (DO_COND (t), args,
- in_decl),
+ complain, in_decl),
NULL_TREE);
}
break;
@@ -6221,19 +7001,19 @@ tsubst_expr (t, args, in_decl)
lineno = TREE_COMPLEXITY (t);
begin_if_stmt ();
finish_if_stmt_cond (tsubst_expr (IF_COND (t),
- args, in_decl),
+ args, complain, in_decl),
NULL_TREE);
if (tmp = THEN_CLAUSE (t), tmp)
{
- tsubst_expr (tmp, args, in_decl);
+ tsubst_expr (tmp, args, complain, in_decl);
finish_then_clause (NULL_TREE);
}
if (tmp = ELSE_CLAUSE (t), tmp)
{
begin_else_clause ();
- tsubst_expr (tmp, args, in_decl);
+ tsubst_expr (tmp, args, complain, in_decl);
finish_else_clause (NULL_TREE);
}
@@ -6250,7 +7030,7 @@ tsubst_expr (t, args, in_decl)
for (substmt = COMPOUND_BODY (t);
substmt != NULL_TREE;
substmt = TREE_CHAIN (substmt))
- tsubst_expr (substmt, args, in_decl);
+ tsubst_expr (substmt, args, complain, in_decl);
return finish_compound_stmt (COMPOUND_STMT_NO_SCOPE (t),
NULL_TREE);
}
@@ -6272,19 +7052,19 @@ tsubst_expr (t, args, in_decl)
lineno = TREE_COMPLEXITY (t);
begin_switch_stmt ();
- val = tsubst_expr (SWITCH_COND (t), args, in_decl);
+ val = tsubst_expr (SWITCH_COND (t), args, complain, in_decl);
finish_switch_cond (val);
if (tmp = TREE_OPERAND (t, 1), tmp)
- tsubst_expr (tmp, args, in_decl);
+ tsubst_expr (tmp, args, complain, in_decl);
finish_switch_stmt (val, NULL_TREE);
}
break;
case CASE_LABEL:
- finish_case_label (tsubst_expr (CASE_LOW (t), args, in_decl),
- tsubst_expr (CASE_HIGH (t), args, in_decl));
+ finish_case_label (tsubst_expr (CASE_LOW (t), args, complain, in_decl),
+ tsubst_expr (CASE_HIGH (t), args, complain, in_decl));
break;
case LABEL_DECL:
@@ -6301,28 +7081,29 @@ tsubst_expr (t, args, in_decl)
/* Computed goto's must be tsubst'd into. On the other hand,
non-computed gotos must not be; the identifier in question
will have no binding. */
- t = tsubst_expr (t, args, in_decl);
+ t = tsubst_expr (t, args, complain, in_decl);
finish_goto_stmt (t);
break;
case ASM_STMT:
lineno = TREE_COMPLEXITY (t);
- finish_asm_stmt (tsubst_expr (ASM_CV_QUAL (t), args, in_decl),
- tsubst_expr (ASM_STRING (t), args, in_decl),
- tsubst_expr (ASM_OUTPUTS (t), args, in_decl),
- tsubst_expr (ASM_INPUTS (t), args, in_decl),
- tsubst_expr (ASM_CLOBBERS (t), args, in_decl));
+ finish_asm_stmt (tsubst_expr (ASM_CV_QUAL (t), args, complain, in_decl),
+ tsubst_expr (ASM_STRING (t), args, complain, in_decl),
+ tsubst_expr (ASM_OUTPUTS (t), args, complain, in_decl),
+ tsubst_expr (ASM_INPUTS (t), args, complain, in_decl),
+ tsubst_expr (ASM_CLOBBERS (t), args, complain,
+ in_decl));
break;
case TRY_BLOCK:
lineno = TREE_COMPLEXITY (t);
begin_try_block ();
- tsubst_expr (TRY_STMTS (t), args, in_decl);
+ tsubst_expr (TRY_STMTS (t), args, complain, in_decl);
finish_try_block (NULL_TREE);
{
tree handler = TRY_HANDLERS (t);
for (; handler; handler = TREE_CHAIN (handler))
- tsubst_expr (handler, args, in_decl);
+ tsubst_expr (handler, args, complain, in_decl);
}
finish_handler_sequence (NULL_TREE);
break;
@@ -6334,13 +7115,13 @@ tsubst_expr (t, args, in_decl)
{
tree d = HANDLER_PARMS (t);
expand_start_catch_block
- (tsubst (TREE_OPERAND (d, 1), args, in_decl),
- tsubst (TREE_OPERAND (d, 0), args, in_decl));
+ (tsubst (TREE_OPERAND (d, 1), args, complain, in_decl),
+ tsubst (TREE_OPERAND (d, 0), args, complain, in_decl));
}
else
expand_start_catch_block (NULL_TREE, NULL_TREE);
finish_handler_parms (NULL_TREE);
- tsubst_expr (HANDLER_BODY (t), args, in_decl);
+ tsubst_expr (HANDLER_BODY (t), args, complain, in_decl);
finish_handler (NULL_TREE);
break;
@@ -6348,16 +7129,16 @@ tsubst_expr (t, args, in_decl)
lineno = TREE_COMPLEXITY (t);
t = TREE_TYPE (t);
if (TREE_CODE (t) == ENUMERAL_TYPE)
- tsubst (t, args, NULL_TREE);
+ tsubst (t, args, complain, NULL_TREE);
break;
default:
- return build_expr_from_tree (tsubst_copy (t, args, in_decl));
+ return build_expr_from_tree (tsubst_copy (t, args, complain, in_decl));
}
return NULL_TREE;
}
-/* Instantiate the indicated variable of function template TMPL with
+/* Instantiate the indicated variable or function template TMPL with
the template arguments in TARG_PTR. */
tree
@@ -6424,7 +7205,7 @@ instantiate_template (tmpl, targ_ptr)
targ_ptr = copy_to_permanent (targ_ptr);
/* substitute template parameters */
- fndecl = tsubst (DECL_RESULT (gen_tmpl), targ_ptr, gen_tmpl);
+ fndecl = tsubst (DECL_RESULT (gen_tmpl), targ_ptr, /*complain=*/1, gen_tmpl);
/* The DECL_TI_TEMPLATE should always be the immediate parent
template, not the most general template. */
DECL_TI_TEMPLATE (fndecl) = tmpl;
@@ -6457,76 +7238,18 @@ overload_template_name (type)
pushdecl_class_level (decl);
}
-/* Like type_unification but designed specially to handle conversion
- operators.
-
- The FN is a TEMPLATE_DECL for a function. The ARGS are the
- arguments that are being used when calling it.
-
- If FN is a conversion operator, RETURN_TYPE is the type desired as
- the result of the conversion operator.
-
- The EXTRA_FN_ARG, if any, is the type of an additional
- parameter to be added to the beginning of FN's parameter list.
-
- The other arguments are as for type_unification. */
-
-int
-fn_type_unification (fn, explicit_targs, targs, args, return_type,
- strict, extra_fn_arg)
- tree fn, explicit_targs, targs, args, return_type;
- unification_kind_t strict;
- tree extra_fn_arg;
-{
- tree parms;
-
- my_friendly_assert (TREE_CODE (fn) == TEMPLATE_DECL, 0);
-
- parms = TYPE_ARG_TYPES (TREE_TYPE (fn));
-
- if (IDENTIFIER_TYPENAME_P (DECL_NAME (fn)))
- {
- /* This is a template conversion operator. Use the return types
- as well as the argument types. */
- parms = scratch_tree_cons (NULL_TREE,
- TREE_TYPE (TREE_TYPE (fn)),
- parms);
- args = scratch_tree_cons (NULL_TREE, return_type, args);
- }
-
- if (extra_fn_arg != NULL_TREE)
- parms = scratch_tree_cons (NULL_TREE, extra_fn_arg, parms);
-
- /* We allow incomplete unification without an error message here
- because the standard doesn't seem to explicitly prohibit it. Our
- callers must be ready to deal with unification failures in any
- event. */
- return type_unification (DECL_INNERMOST_TEMPLATE_PARMS (fn),
- targs,
- parms,
- args,
- explicit_targs,
- strict, 1);
-}
-
-
-/* Type unification.
-
- We have a function template signature with one or more references to
- template parameters, and a parameter list we wish to fit to this
- template. If possible, produce a list of parameters for the template
- which will cause it to fit the supplied parameter list.
+/* The FN is a TEMPLATE_DECL for a function. The ARGS are the
+ arguments that are being used when calling it. TARGS is a vector
+ into which the deduced template arguments are placed.
Return zero for success, 2 for an incomplete match that doesn't resolve
all the types, and 1 for complete failure. An error message will be
printed only for an incomplete match.
- TPARMS[NTPARMS] is an array of template parameter types.
+ If FN is a conversion operator, RETURN_TYPE is the type desired as
+ the result of the conversion operator.
- TARGS[NTPARMS] is the array into which the deduced template
- parameter values are placed. PARMS is the function template's
- signature (using TEMPLATE_PARM_IDX nodes), and ARGS is the argument
- list we're trying to match against it.
+ TPARMS is a vector of template parameters.
The EXPLICIT_TARGS are explicit template arguments provided via a
template-id.
@@ -6548,49 +7271,78 @@ fn_type_unification (fn, explicit_targs, targs, args, return_type,
when doing an explicit instantiation as in [temp.explicit],
when determining an explicit specialization as in
[temp.expl.spec], or when taking the address of a function
- template, as in [temp.deduct.funcaddr]. */
+ template, as in [temp.deduct.funcaddr].
+
+ The other arguments are as for type_unification. */
int
-type_unification (tparms, targs, parms, args, explicit_targs,
- strict, allow_incomplete)
- tree tparms, targs, parms, args, explicit_targs;
+fn_type_unification (fn, explicit_targs, targs, args, return_type,
+ strict)
+ tree fn, explicit_targs, targs, args, return_type;
unification_kind_t strict;
- int allow_incomplete;
{
- int* explicit_mask;
- int i;
-
- for (i = 0; i < TREE_VEC_LENGTH (tparms); i++)
- TREE_VEC_ELT (targs, i) = NULL_TREE;
+ tree parms;
+ tree fntype;
- if (explicit_targs != NULL_TREE)
+ my_friendly_assert (TREE_CODE (fn) == TEMPLATE_DECL, 0);
+
+ fntype = TREE_TYPE (fn);
+ if (explicit_targs)
{
- tree arg_vec;
- arg_vec = coerce_template_parms (tparms, explicit_targs, NULL_TREE, 0,
- 0);
+ /* [temp.deduct]
+
+ The specified template arguments must match the template
+ parameters in kind (i.e., type, nontype, template), and there
+ must not be more arguments than there are parameters;
+ otherwise type deduction fails.
+
+ Nontype arguments must match the types of the corresponding
+ nontype template parameters, or must be convertible to the
+ types of the corresponding nontype parameters as specified in
+ _temp.arg.nontype_, otherwise type deduction fails.
+
+ All references in the function type of the function template
+ to the corresponding template parameters are replaced by the
+ specified template argument values. If a substitution in a
+ template parameter or in the function type of the function
+ template results in an invalid type, type deduction fails. */
+ int i;
+ tree converted_args;
- if (arg_vec == error_mark_node)
+ converted_args
+ = (coerce_template_parms (DECL_INNERMOST_TEMPLATE_PARMS (fn),
+ explicit_targs, NULL_TREE, /*complain=*/0,
+ /*require_all_arguments=*/0));
+ if (converted_args == error_mark_node)
return 1;
- explicit_mask = alloca (sizeof (int) * TREE_VEC_LENGTH (targs));
- bzero ((char *) explicit_mask, sizeof(int) * TREE_VEC_LENGTH (targs));
+ fntype = tsubst (fntype, converted_args, /*complain=*/0, NULL_TREE);
+ if (fntype == error_mark_node)
+ return 1;
- for (i = 0;
- i < TREE_VEC_LENGTH (arg_vec)
- && TREE_VEC_ELT (arg_vec, i) != NULL_TREE;
- ++i)
- {
- TREE_VEC_ELT (targs, i) = TREE_VEC_ELT (arg_vec, i);
- /* Let unify know that this argument was explicit. */
- explicit_mask [i] = 1;
- }
+ /* Place the explicitly specified arguments in TARGS. */
+ for (i = 0; i < TREE_VEC_LENGTH (targs); i++)
+ TREE_VEC_ELT (targs, i) = TREE_VEC_ELT (converted_args, i);
}
- else
- explicit_mask = 0;
+
+ parms = TYPE_ARG_TYPES (fntype);
- return
- type_unification_real (tparms, targs, parms, args, 0,
- strict, allow_incomplete, explicit_mask);
+ if (DECL_CONV_FN_P (fn))
+ {
+ /* This is a template conversion operator. Use the return types
+ as well as the argument types. */
+ parms = scratch_tree_cons (NULL_TREE, TREE_TYPE (fntype),
+ parms);
+ args = scratch_tree_cons (NULL_TREE, return_type, args);
+ }
+
+ /* We allow incomplete unification without an error message here
+ because the standard doesn't seem to explicitly prohibit it. Our
+ callers must be ready to deal with unification failures in any
+ event. */
+ return type_unification_real (DECL_INNERMOST_TEMPLATE_PARMS (fn),
+ targs, parms, args, /*subr=*/0,
+ strict, /*allow_incomplete*/1);
}
/* Adjust types before performing type deduction, as described in
@@ -6600,7 +7352,7 @@ type_unification (tparms, targs, parms, args, explicit_targs,
the argument passed to the call, or the type of the value
intialized with the result of the conversion function. */
-void
+static void
maybe_adjust_types_for_deduction (strict, parm, arg)
unification_kind_t strict;
tree* parm;
@@ -6650,8 +7402,7 @@ maybe_adjust_types_for_deduction (strict, parm, arg)
deduction. */
if (TREE_CODE (*arg) == ARRAY_TYPE)
*arg = build_pointer_type (TREE_TYPE (*arg));
- else if (TREE_CODE (*arg) == FUNCTION_TYPE
- || TREE_CODE (*arg) == METHOD_TYPE)
+ else if (TREE_CODE (*arg) == FUNCTION_TYPE)
*arg = build_pointer_type (*arg);
else
*arg = TYPE_MAIN_VARIANT (*arg);
@@ -6668,9 +7419,7 @@ maybe_adjust_types_for_deduction (strict, parm, arg)
*parm = TREE_TYPE (*parm);
}
-/* Like type_unfication. EXPLICIT_MASK, if non-NULL, is an array of
- integers, with ones in positions corresponding to arguments in
- targs that were provided explicitly, and zeros elsewhere.
+/* Like type_unfication.
If SUBR is 1, we're being called recursively (to unify the
arguments of a function or method parameter of a function
@@ -6678,12 +7427,11 @@ maybe_adjust_types_for_deduction (strict, parm, arg)
static int
type_unification_real (tparms, targs, parms, args, subr,
- strict, allow_incomplete, explicit_mask)
+ strict, allow_incomplete)
tree tparms, targs, parms, args;
int subr;
unification_kind_t strict;
int allow_incomplete;
- int* explicit_mask;
{
tree parm, arg;
int i;
@@ -6730,7 +7478,9 @@ type_unification_real (tparms, targs, parms, args, subr,
if (arg == error_mark_node)
return 1;
if (arg == unknown_type_node)
- return 1;
+ /* We can't deduce anything from this, but we might get all the
+ template args from other function args. */
+ continue;
/* Conversions will be performed on a function argument that
corresponds with a function parameter that contains only
@@ -6750,7 +7500,7 @@ type_unification_real (tparms, targs, parms, args, subr,
if (strict == DEDUCE_EXACT)
{
- if (comptypes (parm, type, 1))
+ if (same_type_p (parm, type))
continue;
}
else
@@ -6762,46 +7512,30 @@ type_unification_real (tparms, targs, parms, args, subr,
return 1;
}
-#if 0
- if (TREE_CODE (arg) == VAR_DECL)
- arg = TREE_TYPE (arg);
- else if (TREE_CODE_CLASS (TREE_CODE (arg)) == 'e')
- arg = TREE_TYPE (arg);
-#else
if (TREE_CODE_CLASS (TREE_CODE (arg)) != 't')
{
my_friendly_assert (TREE_TYPE (arg) != NULL_TREE, 293);
- if (TREE_CODE (arg) == OVERLOAD
- && TREE_CODE (OVL_FUNCTION (arg)) == TEMPLATE_DECL)
+ if (type_unknown_p (arg))
{
- tree targs;
- tree arg_type;
- int r;
-
- /* Have to back unify here */
- arg = OVL_FUNCTION (arg);
- targs = make_scratch_vec (DECL_NTPARMS (arg));
- arg_type = TREE_TYPE (arg);
- maybe_adjust_types_for_deduction (strict, &parm, &arg_type);
- parm = expr_tree_cons (NULL_TREE, parm, NULL_TREE);
- arg_type = scratch_tree_cons (NULL_TREE, arg_type, NULL_TREE);
- r = type_unification (DECL_INNERMOST_TEMPLATE_PARMS (arg),
- targs, arg_type, parm, NULL_TREE,
- DEDUCE_EXACT, allow_incomplete);
- if (r)
- /* If the back-unification failed, just bail out. */
- return r;
- else
- continue;
+ /* [temp.deduct.type] A template-argument can be deduced from
+ a pointer to function or pointer to member function
+ argument if the set of overloaded functions does not
+ contain function templates and at most one of a set of
+ overloaded functions provides a unique match. */
+
+ if (resolve_overloaded_unification
+ (tparms, targs, parm, arg, strict, sub_strict)
+ != 0)
+ return 1;
+ continue;
}
arg = TREE_TYPE (arg);
}
-#endif
+
if (!subr)
maybe_adjust_types_for_deduction (strict, &parm, &arg);
- switch (unify (tparms, targs, parm, arg, sub_strict,
- explicit_mask))
+ switch (unify (tparms, targs, parm, arg, sub_strict))
{
case 0:
break;
@@ -6829,9 +7563,338 @@ type_unification_real (tparms, targs, parms, args, subr,
return 0;
}
+/* Subroutine of type_unification_real. Args are like the variables at the
+ call site. ARG is an overloaded function (or template-id); we try
+ deducing template args from each of the overloads, and if only one
+ succeeds, we go with that. Modifies TARGS and returns 0 on success. */
+
+static int
+resolve_overloaded_unification (tparms, targs, parm, arg, strict,
+ sub_strict)
+ tree tparms, targs, parm, arg;
+ unification_kind_t strict;
+ int sub_strict;
+{
+ tree tempargs = copy_node (targs);
+ int good = 0;
+
+ if (TREE_CODE (arg) == ADDR_EXPR)
+ arg = TREE_OPERAND (arg, 0);
+
+ if (TREE_CODE (arg) == COMPONENT_REF)
+ /* Handle `&x' where `x' is some static or non-static member
+ function name. */
+ arg = TREE_OPERAND (arg, 1);
+
+ /* Strip baselink information. */
+ while (TREE_CODE (arg) == TREE_LIST)
+ arg = TREE_VALUE (arg);
+
+ if (TREE_CODE (arg) == TEMPLATE_ID_EXPR)
+ {
+ /* If we got some explicit template args, we need to plug them into
+ the affected templates before we try to unify, in case the
+ explicit args will completely resolve the templates in question. */
+
+ tree expl_subargs = TREE_OPERAND (arg, 1);
+ arg = TREE_OPERAND (arg, 0);
+
+ for (; arg; arg = OVL_NEXT (arg))
+ {
+ tree fn = OVL_CURRENT (arg);
+ tree subargs, elem;
+
+ if (TREE_CODE (fn) != TEMPLATE_DECL)
+ continue;
+
+ subargs = get_bindings_overload (fn, DECL_RESULT (fn), expl_subargs);
+ if (subargs)
+ {
+ elem = tsubst (TREE_TYPE (fn), subargs, /*complain=*/0,
+ NULL_TREE);
+ if (TREE_CODE (elem) == METHOD_TYPE)
+ elem = build_ptrmemfunc_type (build_pointer_type (elem));
+ good += try_one_overload (tparms, targs, tempargs, parm, elem,
+ strict, sub_strict);
+ }
+ }
+ }
+ else if (TREE_CODE (arg) == OVERLOAD)
+ {
+ for (; arg; arg = OVL_NEXT (arg))
+ {
+ tree type = TREE_TYPE (OVL_CURRENT (arg));
+ if (TREE_CODE (type) == METHOD_TYPE)
+ type = build_ptrmemfunc_type (build_pointer_type (type));
+ good += try_one_overload (tparms, targs, tempargs, parm,
+ type,
+ strict, sub_strict);
+ }
+ }
+ else
+ my_friendly_abort (981006);
+
+ /* [temp.deduct.type] A template-argument can be deduced from a pointer
+ to function or pointer to member function argument if the set of
+ overloaded functions does not contain function templates and at most
+ one of a set of overloaded functions provides a unique match.
+
+ So if we found multiple possibilities, we return success but don't
+ deduce anything. */
+
+ if (good == 1)
+ {
+ int i = TREE_VEC_LENGTH (targs);
+ for (; i--; )
+ if (TREE_VEC_ELT (tempargs, i))
+ TREE_VEC_ELT (targs, i) = TREE_VEC_ELT (tempargs, i);
+ }
+ if (good)
+ return 0;
+
+ return 1;
+}
+
+/* Subroutine of resolve_overloaded_unification; does deduction for a single
+ overload. Fills TARGS with any deduced arguments, or error_mark_node if
+ different overloads deduce different arguments for a given parm.
+ Returns 1 on success. */
+
+static int
+try_one_overload (tparms, orig_targs, targs, parm, arg, strict,
+ sub_strict)
+ tree tparms, orig_targs, targs, parm, arg;
+ unification_kind_t strict;
+ int sub_strict;
+{
+ int nargs;
+ tree tempargs;
+ int i;
+
+ /* [temp.deduct.type] A template-argument can be deduced from a pointer
+ to function or pointer to member function argument if the set of
+ overloaded functions does not contain function templates and at most
+ one of a set of overloaded functions provides a unique match.
+
+ So if this is a template, just return success. */
+
+ if (uses_template_parms (arg))
+ return 1;
+
+ maybe_adjust_types_for_deduction (strict, &parm, &arg);
+
+ /* We don't copy orig_targs for this because if we have already deduced
+ some template args from previous args, unify would complain when we
+ try to deduce a template parameter for the same argument, even though
+ there isn't really a conflict. */
+ nargs = TREE_VEC_LENGTH (targs);
+ tempargs = make_scratch_vec (nargs);
+
+ if (unify (tparms, tempargs, parm, arg, sub_strict) != 0)
+ return 0;
+
+ /* First make sure we didn't deduce anything that conflicts with
+ explicitly specified args. */
+ for (i = nargs; i--; )
+ {
+ tree elt = TREE_VEC_ELT (tempargs, i);
+ tree oldelt = TREE_VEC_ELT (orig_targs, i);
+
+ if (elt == NULL_TREE)
+ continue;
+ else if (uses_template_parms (elt))
+ {
+ /* Since we're unifying against ourselves, we will fill in template
+ args used in the function parm list with our own template parms.
+ Discard them. */
+ TREE_VEC_ELT (tempargs, i) = NULL_TREE;
+ continue;
+ }
+ else if (oldelt && ! template_args_equal (oldelt, elt))
+ return 0;
+ }
+
+ for (i = nargs; i--; )
+ {
+ tree elt = TREE_VEC_ELT (tempargs, i);
+
+ if (elt)
+ TREE_VEC_ELT (targs, i) = elt;
+ }
+
+ return 1;
+}
+
+/* PARM is a template class (perhaps with unbound template
+ parameters). ARG is a fully instantiated type. If ARG can be
+ bound to PARM, return ARG, otherwise return NULL_TREE. TPARMS and
+ TARGS are as for unify. */
+
+static tree
+try_class_unification (tparms, targs, parm, arg)
+ tree tparms;
+ tree targs;
+ tree parm;
+ tree arg;
+{
+ int i;
+ tree copy_of_targs;
+
+ if (!CLASSTYPE_TEMPLATE_INFO (arg)
+ || CLASSTYPE_TI_TEMPLATE (arg) != CLASSTYPE_TI_TEMPLATE (parm))
+ return NULL_TREE;
+
+ /* We need to make a new template argument vector for the call to
+ unify. If we used TARGS, we'd clutter it up with the result of
+ the attempted unification, even if this class didn't work out.
+ We also don't want to commit ourselves to all the unifications
+ we've already done, since unification is supposed to be done on
+ an argument-by-argument basis. In other words, consider the
+ following pathological case:
+
+ template <int I, int J, int K>
+ struct S {};
+
+ template <int I, int J>
+ struct S<I, J, 2> : public S<I, I, I>, S<J, J, J> {};
+
+ template <int I, int J, int K>
+ void f(S<I, J, K>, S<I, I, I>);
+
+ void g() {
+ S<0, 0, 0> s0;
+ S<0, 1, 2> s2;
+
+ f(s0, s2);
+ }
+
+ Now, by the time we consider the unification involving `s2', we
+ already know that we must have `f<0, 0, 0>'. But, even though
+ `S<0, 1, 2>' is derived from `S<0, 0, 0>', the code is not legal
+ because there are two ways to unify base classes of S<0, 1, 2>
+ with S<I, I, I>. If we kept the already deduced knowledge, we
+ would reject the possibility I=1. */
+ push_momentary ();
+ copy_of_targs = make_temp_vec (TREE_VEC_LENGTH (targs));
+ i = unify (tparms, copy_of_targs, CLASSTYPE_TI_ARGS (parm),
+ CLASSTYPE_TI_ARGS (arg), UNIFY_ALLOW_NONE);
+ pop_momentary ();
+
+ /* If unification failed, we're done. */
+ if (i != 0)
+ return NULL_TREE;
+ else
+ return arg;
+}
+
+/* Subroutine of get_template_base. RVAL, if non-NULL, is a base we
+ have alreay discovered to be satisfactory. ARG_BINFO is the binfo
+ for the base class of ARG that we are currently examining. */
+
+static tree
+get_template_base_recursive (tparms, targs, parm,
+ arg_binfo, rval, flags)
+ tree tparms;
+ tree targs;
+ tree arg_binfo;
+ tree rval;
+ tree parm;
+ int flags;
+{
+ tree binfos;
+ int i, n_baselinks;
+ tree arg = BINFO_TYPE (arg_binfo);
+
+ if (!(flags & GTB_IGNORE_TYPE))
+ {
+ tree r = try_class_unification (tparms, targs,
+ parm, arg);
+
+ /* If there is more than one satisfactory baseclass, then:
+
+ [temp.deduct.call]
+
+ If they yield more than one possible deduced A, the type
+ deduction fails.
+
+ applies. */
+ if (r && rval && !same_type_p (r, rval))
+ return error_mark_node;
+ else if (r)
+ rval = r;
+ }
+
+ binfos = BINFO_BASETYPES (arg_binfo);
+ n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;
+
+ /* Process base types. */
+ for (i = 0; i < n_baselinks; i++)
+ {
+ tree base_binfo = TREE_VEC_ELT (binfos, i);
+ int this_virtual;
+
+ /* Skip this base, if we've already seen it. */
+ if (BINFO_MARKED (base_binfo))
+ continue;
+
+ this_virtual =
+ (flags & GTB_VIA_VIRTUAL) || TREE_VIA_VIRTUAL (base_binfo);
+
+ /* When searching for a non-virtual, we cannot mark virtually
+ found binfos. */
+ if (! this_virtual)
+ SET_BINFO_MARKED (base_binfo);
+
+ rval = get_template_base_recursive (tparms, targs,
+ parm,
+ base_binfo,
+ rval,
+ GTB_VIA_VIRTUAL * this_virtual);
+
+ /* If we discovered more than one matching base class, we can
+ stop now. */
+ if (rval == error_mark_node)
+ return error_mark_node;
+ }
+
+ return rval;
+}
+
+/* Given a template type PARM and a class type ARG, find the unique
+ base type in ARG that is an instance of PARM. We do not examine
+ ARG itself; only its base-classes. If there is no appropriate base
+ class, return NULL_TREE. If there is more than one, return
+ error_mark_node. PARM may be the type of a partial specialization,
+ as well as a plain template type. Used by unify. */
+
+static tree
+get_template_base (tparms, targs, parm, arg)
+ tree tparms;
+ tree targs;
+ tree parm;
+ tree arg;
+{
+ tree rval;
+ tree arg_binfo;
+
+ my_friendly_assert (IS_AGGR_TYPE_CODE (TREE_CODE (arg)), 92);
+
+ arg_binfo = TYPE_BINFO (complete_type (arg));
+ rval = get_template_base_recursive (tparms, targs,
+ parm, arg_binfo,
+ NULL_TREE,
+ GTB_IGNORE_TYPE);
+
+ /* Since get_template_base_recursive marks the bases classes, we
+ must unmark them here. */
+ dfs_walk (arg_binfo, dfs_unmark, markedp, 0);
+
+ return rval;
+}
+
/* Returns the level of DECL, which declares a template parameter. */
-int
+static int
template_decl_level (decl)
tree decl;
{
@@ -6854,18 +7917,16 @@ template_decl_level (decl)
cv-qualifiers of each type, given STRICT as documented for unify.
Returns non-zero iff the unification is OK on that basis.*/
-int
+static int
check_cv_quals_for_unify (strict, arg, parm)
int strict;
tree arg;
tree parm;
{
return !((!(strict & UNIFY_ALLOW_MORE_CV_QUAL)
- && (TYPE_READONLY (arg) < TYPE_READONLY (parm)
- || TYPE_VOLATILE (arg) < TYPE_VOLATILE (parm)))
+ && !at_least_as_qualified_p (arg, parm))
|| (!(strict & UNIFY_ALLOW_LESS_CV_QUAL)
- && (TYPE_READONLY (arg) > TYPE_READONLY (parm)
- || TYPE_VOLATILE (arg) > TYPE_VOLATILE (parm))));
+ && (!at_least_as_qualified_p (parm, arg))));
}
/* Takes parameters as for type_unification. Returns 0 if the
@@ -6881,13 +7942,15 @@ check_cv_quals_for_unify (strict, arg, parm)
UNIFY_ALLOW_DERIVED:
Allow the deduced ARG to be a template base class of ARG,
or a pointer to a template base class of the type pointed to by
- ARG. */
+ ARG.
+ UNIFY_ALLOW_INTEGER:
+ Allow any integral type to be deduced. See the TEMPLATE_PARM_INDEX
+ case for more information. */
-int
-unify (tparms, targs, parm, arg, strict, explicit_mask)
+static int
+unify (tparms, targs, parm, arg, strict)
tree tparms, targs, parm, arg;
int strict;
- int* explicit_mask;
{
int idx;
tree targ;
@@ -6903,9 +7966,12 @@ unify (tparms, targs, parm, arg, strict, explicit_mask)
if (arg == error_mark_node)
return 1;
if (arg == unknown_type_node)
- return 1;
+ /* We can't deduce anything from this, but we might get all the
+ template args from other function args. */
+ return 0;
+
/* If PARM uses template parameters, then we can't bail out here,
- even in ARG == PARM, since we won't record unifications for the
+ even if ARG == PARM, since we won't record unifications for the
template parameters. We might need them if we're trying to
figure out which of two things is more specialized. */
if (arg == parm && !uses_template_parms (parm))
@@ -6940,7 +8006,7 @@ unify (tparms, targs, parm, arg, strict, explicit_mask)
/* The PARM is not one we're trying to unify. Just check
to see if it matches ARG. */
return (TREE_CODE (arg) == TREE_CODE (parm)
- && comptypes (parm, arg, 1)) ? 0 : 1;
+ && same_type_p (parm, arg)) ? 0 : 1;
idx = TEMPLATE_TYPE_IDX (parm);
targ = TREE_VEC_ELT (targs, idx);
tparm = TREE_VALUE (TREE_VEC_ELT (tparms, idx));
@@ -6952,16 +8018,9 @@ unify (tparms, targs, parm, arg, strict, explicit_mask)
&& TREE_CODE (tparm) != TEMPLATE_DECL))
return 1;
- if (!strict && targ != NULL_TREE
- && explicit_mask && explicit_mask[idx])
- /* An explicit template argument. Don't even try to match
- here; the overload resolution code will manage check to
- see whether the call is legal. */
- return 0;
-
if (TREE_CODE (parm) == TEMPLATE_TEMPLATE_PARM)
{
- if (CLASSTYPE_TEMPLATE_INFO (parm))
+ if (TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (parm))
{
/* We arrive here when PARM does not involve template
specialization. */
@@ -6971,8 +8030,8 @@ unify (tparms, targs, parm, arg, strict, explicit_mask)
return 1;
{
- tree parmtmpl = CLASSTYPE_TI_TEMPLATE (parm);
- tree parmvec = CLASSTYPE_TI_ARGS (parm);
+ tree parmtmpl = TYPE_TI_TEMPLATE (parm);
+ tree parmvec = TYPE_TI_ARGS (parm);
tree argvec = CLASSTYPE_TI_ARGS (arg);
tree argtmplvec
= DECL_INNERMOST_TEMPLATE_PARMS (CLASSTYPE_TI_TEMPLATE (arg));
@@ -6985,24 +8044,22 @@ unify (tparms, targs, parm, arg, strict, explicit_mask)
template <class T, class Allocator = allocator>
class vector. */
- if (coerce_template_parms (argtmplvec, parmvec, parmtmpl, 1, 1)
+ if (coerce_template_parms (argtmplvec, parmvec, parmtmpl, 0, 1)
== error_mark_node)
return 1;
- /* Deduce arguments T, i from TT<T> or TT<i>. */
+ /* Deduce arguments T, i from TT<T> or TT<i>.
+ We check each element of PARMVEC and ARGVEC individually
+ rather than the whole TREE_VEC since they can have
+ different number of elements. */
+
for (i = 0; i < TREE_VEC_LENGTH (parmvec); ++i)
{
tree t = TREE_VEC_ELT (parmvec, i);
- if (TREE_CODE (t) != TEMPLATE_TYPE_PARM
- && TREE_CODE (t) != TEMPLATE_TEMPLATE_PARM
- && TREE_CODE (t) != TEMPLATE_PARM_INDEX)
- continue;
-
- /* This argument can be deduced. */
if (unify (tparms, targs, t,
TREE_VEC_ELT (argvec, i),
- UNIFY_ALLOW_NONE, explicit_mask))
+ UNIFY_ALLOW_NONE))
return 1;
}
}
@@ -7022,18 +8079,30 @@ unify (tparms, targs, parm, arg, strict, explicit_mask)
/* Consider the case where ARG is `const volatile int' and
PARM is `const T'. Then, T should be `volatile int'. */
arg =
- cp_build_type_variant (arg,
- TYPE_READONLY (arg) > TYPE_READONLY (parm),
- TYPE_VOLATILE (arg) > TYPE_VOLATILE (parm));
+ cp_build_qualified_type (arg,
+ CP_TYPE_QUALS (arg)
+ & ~CP_TYPE_QUALS (parm));
}
/* Simple cases: Value already set, does match or doesn't. */
- if (targ != NULL_TREE
- && (comptypes (targ, arg, 1)
- || (explicit_mask && explicit_mask[idx])))
+ if (targ != NULL_TREE && same_type_p (targ, arg))
return 0;
else if (targ)
return 1;
+
+ /* Make sure that ARG is not a variable-sized array. (Note that
+ were talking about variable-sized arrays (like `int[n]'),
+ rather than arrays of unknown size (like `int[]').) We'll
+ get very confused by such a type since the bound of the array
+ will not be computable in an instantiation. Besides, such
+ types are not allowed in ISO C++, so we can do as we please
+ here. */
+ if (TREE_CODE (arg) == ARRAY_TYPE
+ && !uses_template_parms (arg)
+ && (TREE_CODE (TYPE_MAX_VALUE (TYPE_DOMAIN (arg)))
+ != INTEGER_CST))
+ return 1;
+
TREE_VEC_ELT (targs, idx) = arg;
return 0;
@@ -7061,6 +8130,22 @@ unify (tparms, targs, parm, arg, strict, explicit_mask)
my_friendly_abort (42);
}
+ /* [temp.deduct.type] If, in the declaration of a function template
+ with a non-type template-parameter, the non-type
+ template-parameter is used in an expression in the function
+ parameter-list and, if the corresponding template-argument is
+ deduced, the template-argument type shall match the type of the
+ template-parameter exactly, except that a template-argument
+ deduced from an array bound may be of any integral type. */
+ if (same_type_p (TREE_TYPE (arg), TREE_TYPE (parm)))
+ /* OK */;
+ else if ((strict & UNIFY_ALLOW_INTEGER)
+ && (TREE_CODE (TREE_TYPE (parm)) == INTEGER_TYPE
+ || TREE_CODE (TREE_TYPE (parm)) == BOOLEAN_TYPE))
+ /* OK */;
+ else
+ return 1;
+
TREE_VEC_ELT (targs, idx) = copy_to_permanent (arg);
return 0;
@@ -7070,8 +8155,7 @@ unify (tparms, targs, parm, arg, strict, explicit_mask)
if (TREE_CODE (arg) == RECORD_TYPE && TYPE_PTRMEMFUNC_FLAG (arg))
return (unify (tparms, targs, parm,
- TYPE_PTRMEMFUNC_FN_TYPE (arg), strict,
- explicit_mask));
+ TYPE_PTRMEMFUNC_FN_TYPE (arg), strict));
if (TREE_CODE (arg) != POINTER_TYPE)
return 1;
@@ -7099,14 +8183,14 @@ unify (tparms, targs, parm, arg, strict, explicit_mask)
sub_strict &= ~UNIFY_ALLOW_DERIVED;
return unify (tparms, targs, TREE_TYPE (parm), TREE_TYPE
- (arg), sub_strict, explicit_mask);
+ (arg), sub_strict);
}
case REFERENCE_TYPE:
if (TREE_CODE (arg) != REFERENCE_TYPE)
return 1;
return unify (tparms, targs, TREE_TYPE (parm), TREE_TYPE (arg),
- UNIFY_ALLOW_NONE, explicit_mask);
+ UNIFY_ALLOW_NONE);
case ARRAY_TYPE:
if (TREE_CODE (arg) != ARRAY_TYPE)
@@ -7116,10 +8200,10 @@ unify (tparms, targs, parm, arg, strict, explicit_mask)
return 1;
if (TYPE_DOMAIN (parm) != NULL_TREE
&& unify (tparms, targs, TYPE_DOMAIN (parm),
- TYPE_DOMAIN (arg), UNIFY_ALLOW_NONE, explicit_mask) != 0)
+ TYPE_DOMAIN (arg), UNIFY_ALLOW_NONE) != 0)
return 1;
return unify (tparms, targs, TREE_TYPE (parm), TREE_TYPE (arg),
- UNIFY_ALLOW_NONE, explicit_mask);
+ UNIFY_ALLOW_NONE);
case REAL_TYPE:
case COMPLEX_TYPE:
@@ -7134,18 +8218,18 @@ unify (tparms, targs, parm, arg, strict, explicit_mask)
{
if (TYPE_MIN_VALUE (parm) && TYPE_MIN_VALUE (arg)
&& unify (tparms, targs, TYPE_MIN_VALUE (parm),
- TYPE_MIN_VALUE (arg), UNIFY_ALLOW_NONE, explicit_mask))
+ TYPE_MIN_VALUE (arg), UNIFY_ALLOW_INTEGER))
return 1;
if (TYPE_MAX_VALUE (parm) && TYPE_MAX_VALUE (arg)
&& unify (tparms, targs, TYPE_MAX_VALUE (parm),
- TYPE_MAX_VALUE (arg), UNIFY_ALLOW_NONE, explicit_mask))
+ TYPE_MAX_VALUE (arg), UNIFY_ALLOW_INTEGER))
return 1;
}
/* We use the TYPE_MAIN_VARIANT since we have already
checked cv-qualification at the top of the
function. */
- else if (!comptypes (TYPE_MAIN_VARIANT (arg),
- TYPE_MAIN_VARIANT (parm), 1))
+ else if (!same_type_p (TYPE_MAIN_VARIANT (arg),
+ TYPE_MAIN_VARIANT (parm)))
return 1;
/* As far as unification is concerned, this wins. Later checks
@@ -7172,44 +8256,63 @@ unify (tparms, targs, parm, arg, strict, explicit_mask)
for (i = TREE_VEC_LENGTH (parm) - 1; i >= 0; i--)
if (unify (tparms, targs,
TREE_VEC_ELT (parm, i), TREE_VEC_ELT (arg, i),
- UNIFY_ALLOW_NONE, explicit_mask))
+ UNIFY_ALLOW_NONE))
return 1;
return 0;
}
case RECORD_TYPE:
+ case UNION_TYPE:
if (TYPE_PTRMEMFUNC_FLAG (parm))
return unify (tparms, targs, TYPE_PTRMEMFUNC_FN_TYPE (parm),
- arg, strict, explicit_mask);
+ arg, strict);
- if (TREE_CODE (arg) != RECORD_TYPE)
+ if (TREE_CODE (arg) != TREE_CODE (parm))
return 1;
- if (CLASSTYPE_TEMPLATE_INFO (parm) && uses_template_parms (parm))
+ if (CLASSTYPE_TEMPLATE_INFO (parm))
{
tree t = NULL_TREE;
+
if (strict & UNIFY_ALLOW_DERIVED)
- /* [temp.deduct.call]
-
- If P is a class, and P has the form template-id, then A
- can be a derived class of the deduced A. Likewise, if
- P is a pointer to a class of the form template-id, A
- can be a pointer to a derived class pointed to by the
- deduced A. */
- t = get_template_base (CLASSTYPE_TI_TEMPLATE (parm), arg);
- else if
- (CLASSTYPE_TEMPLATE_INFO (arg)
- && CLASSTYPE_TI_TEMPLATE (parm) == CLASSTYPE_TI_TEMPLATE (arg))
+ {
+ /* First, we try to unify the PARM and ARG directly. */
+ t = try_class_unification (tparms, targs,
+ parm, arg);
+
+ if (!t)
+ {
+ /* Fallback to the special case allowed in
+ [temp.deduct.call]:
+
+ If P is a class, and P has the form
+ template-id, then A can be a derived class of
+ the deduced A. Likewise, if P is a pointer to
+ a class of the form template-id, A can be a
+ pointer to a derived class pointed to by the
+ deduced A. */
+ t = get_template_base (tparms, targs,
+ parm, arg);
+
+ if (! t || t == error_mark_node)
+ return 1;
+ }
+ }
+ else if (CLASSTYPE_TEMPLATE_INFO (arg)
+ && (CLASSTYPE_TI_TEMPLATE (parm)
+ == CLASSTYPE_TI_TEMPLATE (arg)))
+ /* Perhaps PARM is something like S<U> and ARG is S<int>.
+ Then, we should unify `int' and `U'. */
t = arg;
- if (! t || t == error_mark_node)
+ else
+ /* There's no chance of unication succeeding. */
return 1;
return unify (tparms, targs, CLASSTYPE_TI_ARGS (parm),
- CLASSTYPE_TI_ARGS (t), UNIFY_ALLOW_NONE,
- explicit_mask);
+ CLASSTYPE_TI_ARGS (t), UNIFY_ALLOW_NONE);
}
- else if (!comptypes (TYPE_MAIN_VARIANT (parm),
- TYPE_MAIN_VARIANT (arg), 1))
+ else if (!same_type_p (TYPE_MAIN_VARIANT (parm),
+ TYPE_MAIN_VARIANT (arg)))
return 1;
return 0;
@@ -7219,20 +8322,20 @@ unify (tparms, targs, parm, arg, strict, explicit_mask)
return 1;
if (unify (tparms, targs, TREE_TYPE (parm),
- TREE_TYPE (arg), UNIFY_ALLOW_NONE, explicit_mask))
+ TREE_TYPE (arg), UNIFY_ALLOW_NONE))
return 1;
return type_unification_real (tparms, targs, TYPE_ARG_TYPES (parm),
TYPE_ARG_TYPES (arg), 1,
- DEDUCE_EXACT, 0, explicit_mask);
+ DEDUCE_EXACT, 0);
case OFFSET_TYPE:
if (TREE_CODE (arg) != OFFSET_TYPE)
return 1;
if (unify (tparms, targs, TYPE_OFFSET_BASETYPE (parm),
- TYPE_OFFSET_BASETYPE (arg), UNIFY_ALLOW_NONE, explicit_mask))
+ TYPE_OFFSET_BASETYPE (arg), UNIFY_ALLOW_NONE))
return 1;
return unify (tparms, targs, TREE_TYPE (parm), TREE_TYPE (arg),
- UNIFY_ALLOW_NONE, explicit_mask);
+ strict);
case CONST_DECL:
if (arg != decl_constant_value (parm))
@@ -7262,41 +8365,31 @@ unify (tparms, targs, parm, arg, strict, explicit_mask)
integer_type_node,
arg, t2));
- return unify (tparms, targs, t1, t, UNIFY_ALLOW_NONE,
- explicit_mask);
+ return unify (tparms, targs, t1, t, strict);
}
/* else fall through */
default:
if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (TREE_CODE (parm))))
- {
- /* We're looking at an expression. This can happen with
- something like:
-
- template <int I>
- void foo(S<I>, S<I + 2>);
+ /* We're looking at an expression. This can happen with
+ something like:
+
+ template <int I>
+ void foo(S<I>, S<I + 2>);
- If the call looked like:
+ This is a "nondeduced context":
- foo(S<2>(), S<4>());
+ [deduct.type]
+
+ The nondeduced contexts are:
- we would have already matched `I' with `2'. Now, we'd
- like to know if `4' matches `I + 2'. So, we substitute
- into that expression, and fold constants, in the hope of
- figuring it out. */
- tree t =
- maybe_fold_nontype_arg (tsubst_expr (parm, targs, NULL_TREE));
- tree a = maybe_fold_nontype_arg (arg);
+ --A type that is a template-id in which one or more of
+ the template-arguments is an expression that references
+ a template-parameter.
- if (!IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (TREE_CODE (t))))
- /* Good, we mangaged to simplify the exression. */
- return unify (tparms, targs, t, a, UNIFY_ALLOW_NONE,
- explicit_mask);
- else
- /* Bad, we couldn't simplify this. Assume it doesn't
- unify. */
- return 1;
- }
+ In these cases, we assume deduction succeeded, but don't
+ actually infer any unifications. */
+ return 0;
else
sorry ("use of `%s' in template type unification",
tree_code_name [(int) TREE_CODE (parm)]);
@@ -7350,11 +8443,11 @@ more_specialized (pat1, pat2, explicit_args)
tree targs;
int winner = 0;
- targs = get_bindings_overload (pat1, pat2, explicit_args);
+ targs = get_bindings_overload (pat1, DECL_RESULT (pat2), explicit_args);
if (targs)
--winner;
- targs = get_bindings_overload (pat2, pat1, explicit_args);
+ targs = get_bindings_overload (pat2, DECL_RESULT (pat1), explicit_args);
if (targs)
++winner;
@@ -7390,7 +8483,8 @@ more_specialized_class (pat1, pat2)
/* Return the template arguments that will produce the function signature
DECL from the function template FN, with the explicit template
arguments EXPLICIT_ARGS. If CHECK_RETTYPE is 1, the return type must
- also match. */
+ also match. Return NULL_TREE if no satisfactory arguments could be
+ found. */
static tree
get_bindings_real (fn, decl, explicit_args, check_rettype)
@@ -7399,35 +8493,50 @@ get_bindings_real (fn, decl, explicit_args, check_rettype)
{
int ntparms = DECL_NTPARMS (fn);
tree targs = make_scratch_vec (ntparms);
- tree decl_arg_types = TYPE_ARG_TYPES (TREE_TYPE (decl));
- tree extra_fn_arg = NULL_TREE;
+ tree decl_type;
+ tree decl_arg_types;
int i;
- if (DECL_STATIC_FUNCTION_P (fn)
- && DECL_NONSTATIC_MEMBER_FUNCTION_P (decl))
+ /* Substitute the explicit template arguments into the type of DECL.
+ The call to fn_type_unification will handle substitution into the
+ FN. */
+ decl_type = TREE_TYPE (decl);
+ if (explicit_args && uses_template_parms (decl_type))
{
- /* Sometimes we are trying to figure out what's being
- specialized by a declaration that looks like a method, and it
- turns out to be a static member function. */
- if (CLASSTYPE_TEMPLATE_INFO (DECL_REAL_CONTEXT (fn))
- && !is_member_template (fn))
- /* The natural thing to do here seems to be to remove the
- spurious `this' parameter from the DECL, but that prevents
- unification from making use of the class type. So,
- instead, we have fn_type_unification add to the parameters
- for FN. */
- extra_fn_arg = build_pointer_type (DECL_REAL_CONTEXT (fn));
+ tree tmpl;
+ tree converted_args;
+
+ if (DECL_TEMPLATE_INFO (decl))
+ tmpl = DECL_TI_TEMPLATE (decl);
else
- /* In this case, though, adding the extra_fn_arg can confuse
- things, so we remove from decl_arg_types instead. */
- decl_arg_types = TREE_CHAIN (decl_arg_types);
+ /* We can get here for some illegal specializations. */
+ return NULL_TREE;
+
+ converted_args
+ = (coerce_template_parms (DECL_INNERMOST_TEMPLATE_PARMS (tmpl),
+ explicit_args, NULL_TREE,
+ /*complain=*/0,
+ /*require_all_arguments=*/0));
+ if (converted_args == error_mark_node)
+ return NULL_TREE;
+
+ decl_type = tsubst (decl_type, converted_args, /*complain=*/0,
+ NULL_TREE);
+ if (decl_type == error_mark_node)
+ return NULL_TREE;
}
+ /* If FN is a static member function, adjust the type of DECL
+ appropriately. */
+ decl_arg_types = TYPE_ARG_TYPES (decl_type);
+ if (DECL_STATIC_FUNCTION_P (fn)
+ && DECL_NONSTATIC_MEMBER_FUNCTION_P (decl))
+ decl_arg_types = TREE_CHAIN (decl_arg_types);
+
i = fn_type_unification (fn, explicit_args, targs,
decl_arg_types,
- TREE_TYPE (TREE_TYPE (decl)),
- DEDUCE_EXACT,
- extra_fn_arg);
+ TREE_TYPE (decl_type),
+ DEDUCE_EXACT);
if (i != 0)
return NULL_TREE;
@@ -7436,9 +8545,9 @@ get_bindings_real (fn, decl, explicit_args, check_rettype)
{
/* Check to see that the resulting return type is also OK. */
tree t = tsubst (TREE_TYPE (TREE_TYPE (fn)), targs,
- NULL_TREE);
+ /*complain=*/0, NULL_TREE);
- if (!comptypes (t, TREE_TYPE (TREE_TYPE (decl)), 1))
+ if (!same_type_p (t, TREE_TYPE (TREE_TYPE (decl))))
return NULL_TREE;
}
@@ -7487,18 +8596,8 @@ get_class_bindings (tparms, parms, args)
args = innermost_args (args);
- for (i = 0; i < TREE_VEC_LENGTH (parms); ++i)
- {
- switch (unify (tparms, vec,
- TREE_VEC_ELT (parms, i), TREE_VEC_ELT (args, i),
- UNIFY_ALLOW_NONE, 0))
- {
- case 0:
- break;
- case 1:
- return NULL_TREE;
- }
- }
+ if (unify (tparms, vec, parms, args, UNIFY_ALLOW_NONE))
+ return NULL_TREE;
for (i = 0; i < ntparms; ++i)
if (! TREE_VEC_ELT (vec, i))
@@ -7507,35 +8606,30 @@ get_class_bindings (tparms, parms, args)
return vec;
}
-/* Return the most specialized of the list of templates in FNS that can
- produce an instantiation matching DECL, given the explicit template
- arguments EXPLICIT_ARGS. */
+/* In INSTANTIATIONS is a list of <INSTANTIATION, TEMPLATE> pairs.
+ Pick the most specialized template, and return the corresponding
+ instantiation, or if there is no corresponding instantiation, the
+ template itself. EXPLICIT_ARGS is any template arguments explicity
+ mentioned in a template-id. If there is no most specialized
+ tempalte, error_mark_node is returned. If there are no templates
+ at all, NULL_TREE is returned. */
tree
-most_specialized (fns, decl, explicit_args)
- tree fns, decl, explicit_args;
+most_specialized_instantiation (instantiations, explicit_args)
+ tree instantiations;
+ tree explicit_args;
{
- tree candidates = NULL_TREE;
- tree fn, champ, args;
+ tree fn, champ;
int fate;
- for (fn = fns; fn; fn = TREE_CHAIN (fn))
- {
- tree candidate = TREE_VALUE (fn);
-
- args = get_bindings (candidate, decl, explicit_args);
- if (args)
- candidates = scratch_tree_cons (NULL_TREE, candidate,
- candidates);
- }
-
- if (!candidates)
+ if (!instantiations)
return NULL_TREE;
- champ = TREE_VALUE (candidates);
- for (fn = TREE_CHAIN (candidates); fn; fn = TREE_CHAIN (fn))
+ champ = instantiations;
+ for (fn = TREE_CHAIN (instantiations); fn; fn = TREE_CHAIN (fn))
{
- fate = more_specialized (champ, TREE_VALUE (fn), explicit_args);
+ fate = more_specialized (TREE_VALUE (champ),
+ TREE_VALUE (fn), explicit_args);
if (fate == 1)
;
else
@@ -7546,18 +8640,43 @@ most_specialized (fns, decl, explicit_args)
if (! fn)
return error_mark_node;
}
- champ = TREE_VALUE (fn);
+ champ = fn;
}
}
- for (fn = candidates; fn && TREE_VALUE (fn) != champ; fn = TREE_CHAIN (fn))
+ for (fn = instantiations; fn && fn != champ; fn = TREE_CHAIN (fn))
{
- fate = more_specialized (champ, TREE_VALUE (fn), explicit_args);
+ fate = more_specialized (TREE_VALUE (champ),
+ TREE_VALUE (fn), explicit_args);
if (fate != 1)
return error_mark_node;
}
- return champ;
+ return TREE_PURPOSE (champ) ? TREE_PURPOSE (champ) : TREE_VALUE (champ);
+}
+
+/* Return the most specialized of the list of templates in FNS that can
+ produce an instantiation matching DECL, given the explicit template
+ arguments EXPLICIT_ARGS. */
+
+static tree
+most_specialized (fns, decl, explicit_args)
+ tree fns, decl, explicit_args;
+{
+ tree candidates = NULL_TREE;
+ tree fn, args;
+
+ for (fn = fns; fn; fn = TREE_CHAIN (fn))
+ {
+ tree candidate = TREE_VALUE (fn);
+
+ args = get_bindings (candidate, decl, explicit_args);
+ if (args)
+ candidates = scratch_tree_cons (NULL_TREE, candidate,
+ candidates);
+ }
+
+ return most_specialized_instantiation (candidates, explicit_args);
}
/* If DECL is a specialization of some template, return the most
@@ -7574,7 +8693,7 @@ most_specialized (fns, decl, explicit_args)
if TMPL is `template <class U> void S<int*>::f(U)' this will return
`template <class T> template <class U> S<T*>::f(U)'. */
-tree
+static tree
most_general_template (decl)
tree decl;
{
@@ -7588,7 +8707,7 @@ most_general_template (decl)
of TMPL which can produce an instantiation matching ARGS, or
error_mark_node if the choice is ambiguous. */
-tree
+static tree
most_specialized_class (tmpl, args)
tree tmpl;
tree args;
@@ -7776,7 +8895,7 @@ do_type_instantiation (t, storage)
if (TREE_CODE (t) == TYPE_DECL)
t = TREE_TYPE (t);
- if (! IS_AGGR_TYPE (t) || ! CLASSTYPE_TEMPLATE_INFO (t))
+ if (! CLASS_TYPE_P (t) || ! CLASSTYPE_TEMPLATE_INFO (t))
{
cp_error ("explicit instantiation of non-template type `%T'", t);
return;
@@ -7919,7 +9038,7 @@ do_type_instantiation (t, storage)
first parameter, and the wrong type for the second. So, when we go
to instantiate the DECL, we regenerate it. */
-void
+static void
regenerate_decl_from_template (decl, tmpl)
tree decl;
tree tmpl;
@@ -7953,22 +9072,25 @@ regenerate_decl_from_template (decl, tmpl)
pushclass (DECL_CONTEXT (decl), 2);
/* Do the substitution to get the new declaration. */
- new_decl = tsubst (code_pattern, args, NULL_TREE);
+ new_decl = tsubst (code_pattern, args, /*complain=*/1, NULL_TREE);
if (TREE_CODE (decl) == VAR_DECL)
{
/* Set up DECL_INITIAL, since tsubst doesn't. */
DECL_INITIAL (new_decl) =
tsubst_expr (DECL_INITIAL (code_pattern), args,
- DECL_TI_TEMPLATE (decl));
+ /*complain=*/1, DECL_TI_TEMPLATE (decl));
/* Pop the class context we pushed above. */
popclass (1);
}
-
- if (TREE_CODE (decl) == FUNCTION_DECL)
- /* Convince duplicate_decls to use the DECL_ARGUMENTS from the
- new decl. */
- DECL_INITIAL (new_decl) = error_mark_node;
+ else if (TREE_CODE (decl) == FUNCTION_DECL)
+ {
+ /* Convince duplicate_decls to use the DECL_ARGUMENTS from the
+ new decl. */
+ DECL_INITIAL (new_decl) = error_mark_node;
+ /* And don't complain about a duplicate definition. */
+ DECL_INITIAL (decl) = NULL_TREE;
+ }
/* The immediate parent of the new template is still whatever it was
before, even though tsubst sets DECL_TI_TEMPLATE up as the most
@@ -7984,9 +9106,6 @@ regenerate_decl_from_template (decl, tmpl)
/* Call duplicate decls to merge the old and new declarations. */
duplicate_decls (new_decl, decl);
- if (TREE_CODE (decl) == FUNCTION_DECL)
- DECL_INITIAL (new_decl) = NULL_TREE;
-
/* Now, re-register the specialization. */
register_specialization (decl, gen_tmpl, args);
}
@@ -8013,8 +9132,7 @@ instantiate_decl (d)
my_friendly_assert (TREE_CODE (d) == FUNCTION_DECL
|| TREE_CODE (d) == VAR_DECL, 0);
- if ((TREE_CODE (d) == FUNCTION_DECL && DECL_INITIAL (d))
- || (TREE_CODE (d) == VAR_DECL && !DECL_IN_AGGR_P (d)))
+ if (DECL_TEMPLATE_INSTANTIATED (d))
/* D has already been instantiated. It might seem reasonable to
check whether or not D is an explict instantiation, and, if so,
stop here. But when an explicit instantiation is deferred
@@ -8079,9 +9197,6 @@ instantiate_decl (d)
cannot restructure the loop to just keep going until we find
a template with a definition, since that might go too far if
a specialization was declared, but not defined. */
- my_friendly_assert (!(TREE_CODE (d) == FUNCTION_DECL
- && DECL_INITIAL (DECL_TEMPLATE_RESULT (td))),
- 0);
my_friendly_assert (!(TREE_CODE (d) == VAR_DECL
&& !DECL_IN_AGGR_P (DECL_TEMPLATE_RESULT (td))),
0);
@@ -8163,6 +9278,13 @@ instantiate_decl (d)
goto out;
}
+ /* We're now committed to instantiating this template. Mark it as
+ instantiated so that recursive calls to instantiate_decl do not
+ try to instantiate it again. */
+ DECL_TEMPLATE_INSTANTIATED (d) = 1;
+
+ /* Regenerate the declaration in case the template has been modified
+ by a subsequent redeclaration. */
regenerate_decl_from_template (d, td);
/* We already set the file and line above. Reset them now in case
@@ -8193,7 +9315,7 @@ instantiate_decl (d)
{
store_return_init
(TREE_OPERAND (t, 0),
- tsubst_expr (TREE_OPERAND (t, 1), args, tmpl));
+ tsubst_expr (TREE_OPERAND (t, 1), args, /*complain=*/1, tmpl));
t = TREE_CHAIN (t);
}
@@ -8213,7 +9335,7 @@ instantiate_decl (d)
keep_next_level ();
my_friendly_assert (TREE_CODE (t) == COMPOUND_STMT, 42);
- tsubst_expr (t, args, tmpl);
+ tsubst_expr (t, args, /*complain=*/1, tmpl);
finish_function (lineno, 0, nested);
}
@@ -8228,6 +9350,10 @@ out:
return d;
}
+/* Substitute ARGVEC into T, which is a TREE_LIST. In particular, it
+ is an initializer list: the TREE_PURPOSEs are DECLs, and the
+ TREE_VALUEs are initializer values. Used by instantiate_decl. */
+
static tree
tsubst_expr_values (t, argvec)
tree t, argvec;
@@ -8237,8 +9363,10 @@ tsubst_expr_values (t, argvec)
for (; t; t = TREE_CHAIN (t))
{
- tree pur = tsubst_copy (TREE_PURPOSE (t), argvec, NULL_TREE);
- tree val = tsubst_expr (TREE_VALUE (t), argvec, NULL_TREE);
+ tree pur = tsubst_copy (TREE_PURPOSE (t), argvec,
+ /*complain=*/1, NULL_TREE);
+ tree val = tsubst_expr (TREE_VALUE (t), argvec, /*complain=*/1,
+ NULL_TREE);
*p = build_tree_list (pur, val);
p = &TREE_CHAIN (*p);
}
@@ -8334,8 +9462,8 @@ tsubst_enum (tag, newtag, args)
/* Note that in a template enum, the TREE_VALUE is the
CONST_DECL, not the corresponding INTEGER_CST. */
value = tsubst_expr (DECL_INITIAL (TREE_VALUE (e)),
- args,
- NULL_TREE);
+ args, /*complain=*/1,
+ NULL_TREE);
/* Give this enumeration constant the correct access. */
set_current_access_from_decl (TREE_VALUE (e));
@@ -8440,16 +9568,16 @@ set_mangled_name_for_template_decl (decl)
/* Now, do the (partial) substitution to figure out the
appropriate function type. */
- fn_type = tsubst (fn_type, partial_args, NULL_TREE);
+ fn_type = tsubst (fn_type, partial_args, /*complain=*/1, NULL_TREE);
if (DECL_STATIC_FUNCTION_P (decl))
- context = tsubst (context, partial_args, NULL_TREE);
+ context = tsubst (context, partial_args, /*complain=*/1, NULL_TREE);
/* Substitute into the template parameters to obtain the real
innermost set of parameters. This step is important if the
innermost set of template parameters contains value
parameters whose types depend on outer template parameters. */
TREE_VEC_LENGTH (partial_args)--;
- tparms = tsubst_template_parms (tparms, partial_args);
+ tparms = tsubst_template_parms (tparms, partial_args, /*complain=*/1);
}
/* Now, get the innermost parameters and arguments, and figure out
@@ -8496,5 +9624,3 @@ set_mangled_name_for_template_decl (decl)
/* Restore the previously active namespace. */
current_namespace = saved_namespace;
}
-
-
diff --git a/gcc/cp/ptree.c b/gcc/cp/ptree.c
index aa3066cbb44..2cff6552ed9 100644
--- a/gcc/cp/ptree.c
+++ b/gcc/cp/ptree.c
@@ -1,5 +1,5 @@
/* Prints out trees in human readable form.
- Copyright (C) 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
+ Copyright (C) 1992, 93-96, 1998 Free Software Foundation, Inc.
Hacked by Michael Tiemann (tiemann@cygnus.com)
This file is part of GNU CC.
@@ -113,8 +113,6 @@ print_lang_type (file, node, indent)
fputs (" delete", file);
if (TYPE_GETS_DELETE (node) & 2)
fputs (" delete[]", file);
- if (TYPE_HAS_ASSIGNMENT (node))
- fputs (" has=", file);
if (TYPE_HAS_ASSIGN_REF (node))
fputs (" this=(X&)", file);
if (TYPE_OVERLOADS_CALL_EXPR (node))
@@ -152,7 +150,7 @@ print_lang_identifier (file, node, indent)
{
print_node (file, "bindings", IDENTIFIER_NAMESPACE_BINDINGS (node), indent + 4);
print_node (file, "class", IDENTIFIER_CLASS_VALUE (node), indent + 4);
- print_node (file, "local", IDENTIFIER_LOCAL_VALUE (node), indent + 4);
+ print_node (file, "local bindings", IDENTIFIER_BINDING (node), indent + 4);
print_node (file, "label", IDENTIFIER_LABEL_VALUE (node), indent + 4);
print_node (file, "template", IDENTIFIER_TEMPLATE (node), indent + 4);
print_node (file, "implicit", IDENTIFIER_IMPLICIT_DECL (node), indent + 4);
@@ -168,7 +166,8 @@ lang_print_xnode (file, node, indent)
switch (TREE_CODE (node))
{
case CPLUS_BINDING:
- print_node (file, "scope", BINDING_SCOPE (node), indent+4);
+ fprintf (file, " scope ");
+ fprintf (file, HOST_PTR_PRINTF, BINDING_SCOPE (node));
print_node (file, "value", BINDING_VALUE (node), indent+4);
print_node (file, "chain", TREE_CHAIN (node), indent+4);
break;
diff --git a/gcc/cp/repo.c b/gcc/cp/repo.c
index 742250dc632..9fa8e5c4ece 100644
--- a/gcc/cp/repo.c
+++ b/gcc/cp/repo.c
@@ -1,5 +1,5 @@
/* Code to maintain a C++ template repository.
- Copyright (C) 1995, 1997 Free Software Foundation, Inc.
+ Copyright (C) 1995, 96-97, 1998 Free Software Foundation, Inc.
Contributed by Jason Merrill (jason@cygnus.com)
This file is part of GNU CC.
@@ -37,8 +37,8 @@ extern char *getpwd PROTO((void));
static tree repo_get_id PROTO((tree));
static char *extract_string PROTO((char **));
-static char *get_base_filename PROTO((char *));
-static void open_repo_file PROTO((char *));
+static char *get_base_filename PROTO((const char *));
+static void open_repo_file PROTO((const char *));
static char *afgets PROTO((FILE *));
static void reopen_repo_file_for_write PROTO((void));
@@ -99,6 +99,12 @@ repo_get_id (t)
{
if (TREE_CODE_CLASS (TREE_CODE (t)) == 't')
{
+ /* If we're not done setting up the class, we may not have set up
+ the vtable, so going ahead would give the wrong answer.
+ See g++.pt/instantiate4.C. */
+ if (TYPE_SIZE (t) == NULL_TREE || TYPE_BEING_DEFINED (t))
+ my_friendly_abort (981113);
+
t = TYPE_BINFO_VTABLE (t);
if (t == NULL_TREE)
return t;
@@ -233,7 +239,7 @@ extract_string (pp)
static char *
get_base_filename (filename)
- char *filename;
+ const char *filename;
{
char *p = getenv ("COLLECT_GCC_OPTIONS");
char *output = NULL;
@@ -264,10 +270,10 @@ get_base_filename (filename)
static void
open_repo_file (filename)
- char *filename;
+ const char *filename;
{
- register char *p;
- char *s = get_base_filename (filename);
+ register const char *p;
+ const char *s = get_base_filename (filename);
if (s == NULL)
return;
@@ -298,7 +304,7 @@ afgets (stream)
void
init_repo (filename)
- char *filename;
+ const char *filename;
{
char *buf;
diff --git a/gcc/cp/rtti.c b/gcc/cp/rtti.c
index 63f6cf409c3..41c59bbb85d 100644
--- a/gcc/cp/rtti.c
+++ b/gcc/cp/rtti.c
@@ -1,5 +1,5 @@
/* RunTime Type Identification
- Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+ Copyright (C) 1995, 96-97, 1998, 1999 Free Software Foundation, Inc.
Mostly written by Jason Merrill (jason@cygnus.com).
This file is part of GNU CC.
@@ -35,18 +35,17 @@ Boston, MA 02111-1307, USA. */
extern struct obstack permanent_obstack;
-static tree call_void_fn PROTO((char *));
+static tree call_void_fn PROTO((const char *));
static tree build_headof_sub PROTO((tree));
static tree build_headof PROTO((tree));
static tree get_tinfo_var PROTO((tree));
-static tree get_typeid_1 PROTO((tree));
static tree ifnonnull PROTO((tree, tree));
static tree build_dynamic_cast_1 PROTO((tree, tree));
static void expand_si_desc PROTO((tree, tree));
static void expand_class_desc PROTO((tree, tree));
static void expand_attr_desc PROTO((tree, tree));
static void expand_ptr_desc PROTO((tree, tree));
-static void expand_generic_desc PROTO((tree, tree, char *));
+static void expand_generic_desc PROTO((tree, tree, const char *));
static tree throw_bad_cast PROTO((void));
static tree throw_bad_typeid PROTO((void));
@@ -61,7 +60,8 @@ init_rtti_processing ()
pop_namespace ();
tinfo_fn_id = get_identifier ("__tf");
tinfo_fn_type = build_function_type
- (build_reference_type (build_type_variant (type_info_type_node, 1, 0)),
+ (build_reference_type (build_qualified_type (type_info_type_node,
+ TYPE_QUAL_CONST)),
void_list_node);
}
@@ -119,8 +119,8 @@ build_headof (exp)
else
offset = build_component_ref (aref, delta_identifier, NULL_TREE, 0);
- type = build_type_variant (ptr_type_node, TREE_READONLY (exp),
- TREE_THIS_VOLATILE (exp));
+ type = build_qualified_type (ptr_type_node,
+ CP_TYPE_QUALS (TREE_TYPE (exp)));
return build (PLUS_EXPR, type, exp,
cp_convert (ptrdiff_type_node, offset));
}
@@ -129,7 +129,7 @@ build_headof (exp)
static tree
call_void_fn (name)
- char *name;
+ const char *name;
{
tree d = get_identifier (name);
tree type;
@@ -147,11 +147,10 @@ call_void_fn (name)
DECL_ARTIFICIAL (d) = 1;
pushdecl_top_level (d);
make_function_rtl (d);
- assemble_external (d);
-
pop_obstacks ();
}
+ mark_used (d);
return build_call (d, void_type_node, NULL_TREE);
}
@@ -199,6 +198,12 @@ get_tinfo_fn_dynamic (exp)
/* Peel off cv qualifiers. */
type = TYPE_MAIN_VARIANT (type);
+ if (TYPE_SIZE (complete_type (type)) == NULL_TREE)
+ {
+ cp_error ("taking typeid of incomplete type `%T'", type);
+ return error_mark_node;
+ }
+
/* If exp is a reference to polymorphic type, get the real type_info. */
if (TYPE_VIRTUAL_P (type) && ! resolves_to_fixed_type_p (exp, 0))
{
@@ -206,13 +211,7 @@ get_tinfo_fn_dynamic (exp)
tree t;
if (! flag_rtti)
- {
- warning ("taking dynamic typeid of object without -frtti");
- push_obstacks (&permanent_obstack, &permanent_obstack);
- init_rtti_processing ();
- pop_obstacks ();
- flag_rtti = 1;
- }
+ error ("taking dynamic typeid of object with -fno-rtti");
/* If we don't have rtti stuff, get to a sub-object that does. */
if (! CLASSTYPE_VFIELDS (type))
@@ -251,6 +250,12 @@ build_x_typeid (exp)
tree type = TREE_TYPE (tinfo_fn_type);
int nonnull;
+ if (TYPE_SIZE (type_info_type_node) == NULL_TREE)
+ {
+ error ("must #include <typeinfo> before using typeid");
+ return error_mark_node;
+ }
+
if (processing_template_decl)
return build_min_nt (TYPEID_EXPR, exp);
@@ -298,7 +303,7 @@ get_tinfo_var (type)
/* Figure out how much space we need to allocate for the type_info object.
If our struct layout or the type_info classes are changed, this will
need to be modified. */
- if (TYPE_VOLATILE (type) || TYPE_READONLY (type))
+ if (TYPE_QUALS (type) != TYPE_UNQUALIFIED)
size = 3 * POINTER_SIZE + INT_TYPE_SIZE;
else if (TREE_CODE (type) == POINTER_TYPE
&& ! (TREE_CODE (TREE_TYPE (type)) == OFFSET_TYPE
@@ -367,21 +372,20 @@ get_tinfo_fn (type)
pushdecl_top_level (d);
make_function_rtl (d);
- assemble_external (d);
+ mark_used (d);
mark_inline_for_output (d);
- if (at_eof)
- import_export_decl (d);
-
pop_obstacks ();
return d;
}
-static tree
+tree
get_typeid_1 (type)
tree type;
{
- tree t = build_call
+ tree t;
+
+ t = build_call
(get_tinfo_fn (type), TREE_TYPE (tinfo_fn_type), NULL_TREE);
return convert_from_reference (t);
}
@@ -394,15 +398,15 @@ get_typeid (type)
{
if (type == error_mark_node)
return error_mark_node;
-
- if (! flag_rtti)
+
+ if (TYPE_SIZE (type_info_type_node) == NULL_TREE)
{
- warning ("requesting typeid of object without -frtti");
- push_obstacks (&permanent_obstack, &permanent_obstack);
- init_rtti_processing ();
- pop_obstacks ();
- flag_rtti = 1;
+ error ("must #include <typeinfo> before using typeid");
+ return error_mark_node;
}
+
+ if (! flag_rtti)
+ error ("requesting typeid with -fno-rtti");
if (processing_template_decl)
return build_min_nt (TYPEID_EXPR, type);
@@ -417,6 +421,12 @@ get_typeid (type)
that is the operand of typeid are always ignored. */
type = TYPE_MAIN_VARIANT (type);
+ if (TYPE_SIZE (complete_type (type)) == NULL_TREE)
+ {
+ cp_error ("taking typeid of incomplete type `%T'", type);
+ return error_mark_node;
+ }
+
return get_typeid_1 (type);
}
@@ -441,10 +451,15 @@ build_dynamic_cast_1 (type, expr)
tree type, expr;
{
enum tree_code tc = TREE_CODE (type);
- tree exprtype = TREE_TYPE (expr);
+ tree exprtype;
enum tree_code ec;
tree dcast_fn;
+ tree old_expr = expr;
+ if (TREE_CODE (expr) == OFFSET_REF)
+ expr = resolve_offset_ref (expr);
+
+ exprtype = TREE_TYPE (expr);
assert (exprtype != NULL_TREE);
ec = TREE_CODE (exprtype);
@@ -463,8 +478,8 @@ build_dynamic_cast_1 (type, expr)
goto fail;
if (TYPE_SIZE (complete_type (TREE_TYPE (exprtype))) == NULL_TREE)
goto fail;
- if (TREE_READONLY (TREE_TYPE (exprtype))
- && ! TYPE_READONLY (TREE_TYPE (type)))
+ if (!at_least_as_qualified_p (TREE_TYPE (type),
+ TREE_TYPE (exprtype)))
goto fail;
if (TYPE_MAIN_VARIANT (TREE_TYPE (type)) == void_type_node)
break;
@@ -483,8 +498,6 @@ build_dynamic_cast_1 (type, expr)
/* Apply trivial conversion T -> T& for dereferenced ptrs. */
if (ec == RECORD_TYPE)
{
- exprtype = build_type_variant (exprtype, TREE_READONLY (expr),
- TREE_THIS_VOLATILE (expr));
exprtype = build_reference_type (exprtype);
expr = convert_to_reference (exprtype, expr, CONV_IMPLICIT,
LOOKUP_NORMAL, NULL_TREE);
@@ -499,8 +512,8 @@ build_dynamic_cast_1 (type, expr)
goto fail;
if (TYPE_SIZE (complete_type (TREE_TYPE (exprtype))) == NULL_TREE)
goto fail;
- if (TREE_READONLY (TREE_TYPE (exprtype))
- && ! TYPE_READONLY (TREE_TYPE (type)))
+ if (!at_least_as_qualified_p (TREE_TYPE (type),
+ TREE_TYPE (exprtype)))
goto fail;
}
@@ -512,6 +525,20 @@ build_dynamic_cast_1 (type, expr)
distance = get_base_distance (TREE_TYPE (type), TREE_TYPE (exprtype), 1,
&path);
+
+ if (distance == -2)
+ {
+ cp_error ("dynamic_cast from `%T' to ambiguous base class `%T'",
+ TREE_TYPE (exprtype), TREE_TYPE (type));
+ return error_mark_node;
+ }
+ if (distance == -3)
+ {
+ cp_error ("dynamic_cast from `%T' to private base class `%T'",
+ TREE_TYPE (exprtype), TREE_TYPE (type));
+ return error_mark_node;
+ }
+
if (distance >= 0)
return build_vbase_path (PLUS_EXPR, type, expr, path, 0);
}
@@ -547,11 +574,11 @@ build_dynamic_cast_1 (type, expr)
dynamic_cast<D&>(b) (b an object) cannot succeed. */
if (ec == REFERENCE_TYPE)
{
- if (TREE_CODE (expr) == VAR_DECL
- && TREE_CODE (TREE_TYPE (expr)) == RECORD_TYPE)
+ if (TREE_CODE (old_expr) == VAR_DECL
+ && TREE_CODE (TREE_TYPE (old_expr)) == RECORD_TYPE)
{
cp_warning ("dynamic_cast of `%#D' to `%#T' can never succeed",
- expr, type);
+ old_expr, type);
return throw_bad_cast ();
}
}
@@ -563,7 +590,7 @@ build_dynamic_cast_1 (type, expr)
&& TREE_CODE (TREE_TYPE (op)) == RECORD_TYPE)
{
cp_warning ("dynamic_cast of `%#D' to `%#T' can never succeed",
- expr, type);
+ op, type);
retval = build_int_2 (0, 0);
TREE_TYPE (retval) = type;
return retval;
@@ -621,10 +648,10 @@ build_dynamic_cast_1 (type, expr)
DECL_ARTIFICIAL (dcast_fn) = 1;
pushdecl_top_level (dcast_fn);
make_function_rtl (dcast_fn);
- assemble_external (dcast_fn);
pop_obstacks ();
}
+ mark_used (dcast_fn);
result = build_call
(dcast_fn, TREE_TYPE (TREE_TYPE (dcast_fn)), elems);
@@ -686,7 +713,7 @@ expand_si_desc (tdecl, type)
tree type;
{
tree t, elems, fn;
- char *name = build_overload_name (type, 1, 1);
+ const char *name = build_overload_name (type, 1, 1);
tree name_string = combine_strings (build_string (strlen (name)+1, name));
type = BINFO_TYPE (TREE_VEC_ELT (TYPE_BINFO_BASETYPES (type), 0));
@@ -717,10 +744,10 @@ expand_si_desc (tdecl, type)
DECL_ARTIFICIAL (fn) = 1;
pushdecl_top_level (fn);
make_function_rtl (fn);
- assemble_external (fn);
pop_obstacks ();
}
+ mark_used (fn);
fn = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), elems);
expand_expr_stmt (fn);
}
@@ -734,7 +761,7 @@ expand_class_desc (tdecl, type)
{
tree name_string;
tree fn, tmp;
- char *name;
+ const char *name;
int i = CLASSTYPE_N_BASECLASSES (type);
int base_cnt = 0;
@@ -760,7 +787,9 @@ expand_class_desc (tdecl, type)
/* Actually const __user_type_info * */
fields [0] = build_lang_field_decl
(FIELD_DECL, NULL_TREE,
- build_pointer_type (build_type_variant (type_info_type_node, 1, 0)));
+ build_pointer_type (build_qualified_type
+ (type_info_type_node,
+ TYPE_QUAL_CONST)));
fields [1] = build_lang_field_decl
(FIELD_DECL, NULL_TREE, unsigned_intSI_type_node);
DECL_BIT_FIELD (fields[1]) = 1;
@@ -792,7 +821,7 @@ expand_class_desc (tdecl, type)
if (TREE_VIA_VIRTUAL (binfo))
{
tree t = BINFO_TYPE (binfo);
- char *name;
+ const char *name;
tree field;
FORMAT_VBASE_NAME (name, t);
@@ -896,10 +925,10 @@ expand_class_desc (tdecl, type)
DECL_ARTIFICIAL (fn) = 1;
pushdecl_top_level (fn);
make_function_rtl (fn);
- assemble_external (fn);
pop_obstacks ();
}
+ mark_used (fn);
fn = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), elems);
expand_expr_stmt (fn);
}
@@ -912,7 +941,7 @@ expand_ptr_desc (tdecl, type)
tree type;
{
tree t, elems, fn;
- char *name = build_overload_name (type, 1, 1);
+ const char *name = build_overload_name (type, 1, 1);
tree name_string = combine_strings (build_string (strlen (name)+1, name));
type = TREE_TYPE (type);
@@ -943,10 +972,10 @@ expand_ptr_desc (tdecl, type)
DECL_ARTIFICIAL (fn) = 1;
pushdecl_top_level (fn);
make_function_rtl (fn);
- assemble_external (fn);
pop_obstacks ();
}
+ mark_used (fn);
fn = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), elems);
expand_expr_stmt (fn);
}
@@ -959,10 +988,9 @@ expand_attr_desc (tdecl, type)
tree type;
{
tree elems, t, fn;
- char *name = build_overload_name (type, 1, 1);
+ const char *name = build_overload_name (type, 1, 1);
tree name_string = combine_strings (build_string (strlen (name)+1, name));
- tree attrval = build_int_2
- (TYPE_READONLY (type) | TYPE_VOLATILE (type) * 2, 0);
+ tree attrval = build_int_2 (TYPE_QUALS (type), 0);
expand_expr_stmt (get_typeid_1 (TYPE_MAIN_VARIANT (type)));
t = decay_conversion (get_tinfo_var (TYPE_MAIN_VARIANT (type)));
@@ -992,10 +1020,10 @@ expand_attr_desc (tdecl, type)
DECL_ARTIFICIAL (fn) = 1;
pushdecl_top_level (fn);
make_function_rtl (fn);
- assemble_external (fn);
pop_obstacks ();
}
+ mark_used (fn);
fn = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), elems);
expand_expr_stmt (fn);
}
@@ -1006,9 +1034,9 @@ static void
expand_generic_desc (tdecl, type, fnname)
tree tdecl;
tree type;
- char *fnname;
+ const char *fnname;
{
- char *name = build_overload_name (type, 1, 1);
+ const char *name = build_overload_name (type, 1, 1);
tree name_string = combine_strings (build_string (strlen (name)+1, name));
tree elems = tree_cons
(NULL_TREE, decay_conversion (tdecl), tree_cons
@@ -1032,10 +1060,10 @@ expand_generic_desc (tdecl, type, fnname)
DECL_ARTIFICIAL (fn) = 1;
pushdecl_top_level (fn);
make_function_rtl (fn);
- assemble_external (fn);
pop_obstacks ();
}
+ mark_used (fn);
fn = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), elems);
expand_expr_stmt (fn);
}
@@ -1058,9 +1086,16 @@ synthesize_tinfo_fn (fndecl)
tree fndecl;
{
tree type = TREE_TYPE (DECL_NAME (fndecl));
- tree tmp, addr;
+ tree tmp, addr, tdecl;
+
+ if (at_eof)
+ {
+ import_export_decl (fndecl);
+ if (DECL_REALLY_EXTERN (fndecl))
+ return;
+ }
- tree tdecl = get_tinfo_var (type);
+ tdecl = get_tinfo_var (type);
DECL_EXTERNAL (tdecl) = 0;
TREE_STATIC (tdecl) = 1;
DECL_COMMON (tdecl) = 1;
@@ -1085,7 +1120,7 @@ synthesize_tinfo_fn (fndecl)
expand_generic_desc (tdecl, type, "__rtti_func");
else if (TREE_CODE (type) == ARRAY_TYPE)
expand_generic_desc (tdecl, type, "__rtti_array");
- else if (TYPE_VOLATILE (type) || TYPE_READONLY (type))
+ else if (TYPE_QUALS (type) != TYPE_UNQUALIFIED)
expand_attr_desc (tdecl, type);
else if (TREE_CODE (type) == POINTER_TYPE)
{
diff --git a/gcc/cp/search.c b/gcc/cp/search.c
index da3cccc5e10..5ba5ce10766 100644
--- a/gcc/cp/search.c
+++ b/gcc/cp/search.c
@@ -1,6 +1,6 @@
/* Breadth-first and depth-first routines for
searching multiple-inheritance lattice for GNU C++.
- Copyright (C) 1987, 89, 92-96, 1997 Free Software Foundation, Inc.
+ Copyright (C) 1987, 89, 92-97, 1998, 1999 Free Software Foundation, Inc.
Contributed by Michael Tiemann (tiemann@cygnus.com)
This file is part of GNU CC.
@@ -31,6 +31,7 @@ Boston, MA 02111-1307, USA. */
#include "rtl.h"
#include "output.h"
#include "toplev.h"
+#include "varray.h"
#define obstack_chunk_alloc xmalloc
#define obstack_chunk_free free
@@ -80,16 +81,12 @@ static tree get_vbase_1 PROTO((tree, tree, unsigned int *));
static tree convert_pointer_to_vbase PROTO((tree, tree));
static tree lookup_field_1 PROTO((tree, tree));
static tree convert_pointer_to_single_level PROTO((tree, tree));
-static int lookup_fnfields_1 PROTO((tree, tree));
static int lookup_fnfields_here PROTO((tree, tree));
static int is_subobject_of_p PROTO((tree, tree));
static int hides PROTO((tree, tree));
static tree virtual_context PROTO((tree, tree, tree));
-static tree get_template_base_recursive
- PROTO((tree, tree, tree, int));
-static void dfs_walk PROTO((tree, void (*) (tree), int (*) (tree)));
-static void dfs_check_overlap PROTO((tree));
-static int dfs_no_overlap_yet PROTO((tree));
+static tree dfs_check_overlap PROTO((tree, void *));
+static tree dfs_no_overlap_yet PROTO((tree, void *));
static void envelope_add_decl PROTO((tree, tree, tree *));
static int get_base_distance_recursive
PROTO((tree, int, int, int, int *, tree *, tree,
@@ -99,37 +96,58 @@ static void expand_upcast_fixups
static void fixup_virtual_upcast_offsets
PROTO((tree, tree, int, int, tree, tree, tree, tree,
tree *));
-static int markedp PROTO((tree));
-static int unmarkedp PROTO((tree));
-static int marked_vtable_pathp PROTO((tree));
-static int unmarked_vtable_pathp PROTO((tree));
-static int marked_new_vtablep PROTO((tree));
-static int unmarked_new_vtablep PROTO((tree));
-static int dfs_debug_unmarkedp PROTO((tree));
-static void dfs_debug_mark PROTO((tree));
-static void dfs_find_vbases PROTO((tree));
-static void dfs_clear_vbase_slots PROTO((tree));
-static void dfs_unmark PROTO((tree));
-static void dfs_init_vbase_pointers PROTO((tree));
-static void dfs_get_vbase_types PROTO((tree));
-static void dfs_pushdecls PROTO((tree));
-static void dfs_compress_decls PROTO((tree));
-static void dfs_unuse_fields PROTO((tree));
-static void add_conversions PROTO((tree));
-static tree get_virtuals_named_this PROTO((tree));
-static tree get_virtual_destructor PROTO((tree, int));
-static int tree_has_any_destructor_p PROTO((tree, int));
+static tree unmarkedp PROTO((tree, void *));
+static tree marked_vtable_pathp PROTO((tree, void *));
+static tree unmarked_vtable_pathp PROTO((tree, void *));
+static tree marked_new_vtablep PROTO((tree, void *));
+static tree unmarked_new_vtablep PROTO((tree, void *));
+static tree marked_pushdecls_p PROTO((tree, void *));
+static tree unmarked_pushdecls_p PROTO((tree, void *));
+static tree dfs_debug_unmarkedp PROTO((tree, void *));
+static tree dfs_debug_mark PROTO((tree, void *));
+static tree dfs_find_vbases PROTO((tree, void *));
+static tree dfs_clear_vbase_slots PROTO((tree, void *));
+static tree dfs_init_vbase_pointers PROTO((tree, void *));
+static tree dfs_get_vbase_types PROTO((tree, void *));
+static tree dfs_pushdecls PROTO((tree, void *));
+static tree dfs_compress_decls PROTO((tree, void *));
+static tree dfs_unuse_fields PROTO((tree, void *));
+static tree add_conversions PROTO((tree, void *));
+static tree get_virtuals_named_this PROTO((tree, tree));
+static tree get_virtual_destructor PROTO((tree, void *));
+static tree tree_has_any_destructor_p PROTO((tree, void *));
static int covariant_return_p PROTO((tree, tree));
static struct search_level *push_search_level
PROTO((struct stack_level *, struct obstack *));
static struct search_level *pop_search_level
PROTO((struct stack_level *));
-static HOST_WIDE_INT breadth_first_search
- PROTO((tree, int (*) (tree, int), int (*) (tree, int)));
-
-static tree vbase_types;
-static tree vbase_decl_ptr_intermediate, vbase_decl_ptr;
-static tree vbase_init_result;
+static tree bfs_walk
+ PROTO((tree, tree (*) (tree, void *), tree (*) (tree, void *),
+ void *));
+static tree lookup_field_queue_p PROTO((tree, void *));
+static tree lookup_field_r PROTO((tree, void *));
+static tree dfs_walk_real PROTO ((tree,
+ tree (*) (tree, void *),
+ tree (*) (tree, void *),
+ tree (*) (tree, void *),
+ void *));
+static tree dfs_bfv_queue_p PROTO ((tree, void *));
+static tree dfs_bfv_helper PROTO ((tree, void *));
+static tree get_virtuals_named_this_r PROTO ((tree, void *));
+static tree context_for_name_lookup PROTO ((tree));
+static tree canonical_binfo PROTO ((tree));
+static tree shared_marked_p PROTO ((tree, void *));
+static tree shared_unmarked_p PROTO ((tree, void *));
+static int dependent_base_p PROTO ((tree));
+static tree dfs_accessible_queue_p PROTO ((tree, void *));
+static tree dfs_accessible_p PROTO ((tree, void *));
+static tree dfs_access_in_type PROTO ((tree, void *));
+static tree access_in_type PROTO ((tree, tree));
+static tree dfs_canonical_queue PROTO ((tree, void *));
+static tree dfs_assert_unmarked_p PROTO ((tree, void *));
+static void assert_canonical_unmarked PROTO ((tree));
+static int protected_accessible_p PROTO ((tree, tree, tree, tree));
+static int friend_accessible_p PROTO ((tree, tree, tree, tree));
/* Allocate a level of searching. */
@@ -167,9 +185,6 @@ static int n_outer_fields_searched;
static int n_contexts_saved;
#endif /* GATHER_STATISTICS */
-/* This list is used by push_class_decls to know what decls need to
- be pushed into class scope. */
-static tree closed_envelopes = NULL_TREE;
/* Get a virtual binfo that is found inside BINFO's hierarchy that is
the same type as the type given in PARENT. To be optimal, we want
@@ -522,7 +537,14 @@ lookup_field_1 (type, name)
if (temp)
return temp;
}
- if (DECL_NAME (field) == name)
+ if (TREE_CODE (field) == USING_DECL)
+ /* For now, we're just treating member using declarations as
+ old ARM-style access declarations. Thus, there's no reason
+ to return a USING_DECL, and the rest of the compiler can't
+ handle it. Once the class is defined, these are purged
+ from TYPE_FIELDS anyhow; see handle_using_decl. */
+ ;
+ else if (DECL_NAME (field) == name)
{
if ((TREE_CODE(field) == VAR_DECL || TREE_CODE(field) == CONST_DECL)
&& DECL_ASSEMBLER_NAME (field) != NULL)
@@ -571,209 +593,461 @@ current_scope ()
return current_class_type;
}
-/* Compute the access of FIELD. This is done by computing
- the access available to each type in BASETYPES (which comes
- as a list of [via_public/basetype] in reverse order, namely base
- class before derived class). The first one which defines a
- access defines the access for the field. Otherwise, the
- access of the field is that which occurs normally.
+/* Return the scope of DECL, as appropriate when doing name-lookup. */
- Uses global variables CURRENT_CLASS_TYPE and
- CURRENT_FUNCTION_DECL to use friend relationships
- if necessary.
+static tree
+context_for_name_lookup (decl)
+ tree decl;
+{
+ /* [class.union]
+
+ For the purposes of name lookup, after the anonymous union
+ definition, the members of the anonymous union are considered to
+ have been defined in the scope in which teh anonymous union is
+ declared. */
+ tree context = DECL_REAL_CONTEXT (decl);
+
+ while (TYPE_P (context) && ANON_UNION_TYPE_P (context))
+ context = TYPE_CONTEXT (context);
+ if (!context)
+ context = global_namespace;
- This will be static when lookup_fnfield comes into this file.
+ return context;
+}
- access_public_node means that the field can be accessed by the current lexical
- scope.
+/* Return a canonical BINFO if BINFO is a virtual base, or just BINFO
+ otherwise. */
- access_protected_node means that the field cannot be accessed by the current
- lexical scope because it is protected.
+static tree
+canonical_binfo (binfo)
+ tree binfo;
+{
+ return (TREE_VIA_VIRTUAL (binfo)
+ ? TYPE_BINFO (BINFO_TYPE (binfo)) : binfo);
+}
- access_private_node means that the field cannot be accessed by the current
- lexical scope because it is private. */
+/* A queue function that simply ensures that we walk into the
+ canonical versions of virtual bases. */
-#if 0
-#define PUBLIC_RETURN return (DECL_PUBLIC (field) = 1), access_public_node
-#define PROTECTED_RETURN return (DECL_PROTECTED (field) = 1), access_protected_node
-#define PRIVATE_RETURN return (DECL_PRIVATE (field) = 1), access_private_node
-#else
-#define PUBLIC_RETURN return access_public_node
-#define PROTECTED_RETURN return access_protected_node
-#define PRIVATE_RETURN return access_private_node
-#endif
+static tree
+dfs_canonical_queue (binfo, data)
+ tree binfo;
+ void *data ATTRIBUTE_UNUSED;
+{
+ return canonical_binfo (binfo);
+}
-#if 0
-/* Disabled with DECL_PUBLIC &c. */
-static tree previous_scope = NULL_TREE;
-#endif
+/* Called via dfs_walk from assert_canonical_unmarked. */
-tree
-compute_access (basetype_path, field)
- tree basetype_path, field;
+static tree
+dfs_assert_unmarked_p (binfo, data)
+ tree binfo;
+ void *data ATTRIBUTE_UNUSED;
{
- tree access;
- tree types;
- tree context;
- int protected_ok, via_protected;
- extern int flag_access_control;
-#if 1
- /* Replaces static decl above. */
- tree previous_scope;
-#endif
- int static_mem
- = ((TREE_CODE (field) == FUNCTION_DECL && DECL_STATIC_FUNCTION_P (field))
- || (TREE_CODE (field) != FUNCTION_DECL && TREE_STATIC (field)));
+ my_friendly_assert (!BINFO_MARKED (binfo), 0);
+ return NULL_TREE;
+}
- if (! flag_access_control)
- return access_public_node;
+/* Asserts that all the nodes below BINFO (using the canonical
+ versions of virtual bases) are unmarked. */
- /* The field lives in the current class. */
- if (BINFO_TYPE (basetype_path) == current_class_type)
- return access_public_node;
+static void
+assert_canonical_unmarked (binfo)
+ tree binfo;
+{
+ dfs_walk (binfo, dfs_assert_unmarked_p, dfs_canonical_queue, 0);
+}
-#if 0
- /* Disabled until pushing function scope clears these out. If ever. */
- /* Make these special cases fast. */
- if (current_scope () == previous_scope)
- {
- if (DECL_PUBLIC (field))
- return access_public_node;
- if (DECL_PROTECTED (field))
- return access_protected_node;
- if (DECL_PRIVATE (field))
- return access_private_node;
- }
-#endif
+/* If BINFO is marked, return a canonical version of BINFO.
+ Otherwise, return NULL_TREE. */
- /* We don't currently support access control on nested types. */
- if (TREE_CODE (field) == TYPE_DECL)
- return access_public_node;
+static tree
+shared_marked_p (binfo, data)
+ tree binfo;
+ void *data;
+{
+ binfo = canonical_binfo (binfo);
+ return markedp (binfo, data) ? binfo : NULL_TREE;
+}
- previous_scope = current_scope ();
+/* If BINFO is not marked, return a canonical version of BINFO.
+ Otherwise, return NULL_TREE. */
- context = DECL_REAL_CONTEXT (field);
+static tree
+shared_unmarked_p (binfo, data)
+ tree binfo;
+ void *data;
+{
+ binfo = canonical_binfo (binfo);
+ return unmarkedp (binfo, data) ? binfo : NULL_TREE;
+}
- /* Fields coming from nested anonymous unions have their DECL_CLASS_CONTEXT
- slot set to the union type rather than the record type containing
- the anonymous union. */
- if (context && ANON_UNION_TYPE_P (context)
- && TREE_CODE (field) == FIELD_DECL)
- context = TYPE_CONTEXT (context);
+/* Called from access_in_type via dfs_walk. Calculate the access to
+ DATA (which is really a DECL) in BINFO. */
- /* Virtual function tables are never private. But we should know that
- we are looking for this, and not even try to hide it. */
- if (DECL_NAME (field) && VFIELD_NAME_P (DECL_NAME (field)) == 1)
- PUBLIC_RETURN;
-
- /* Member found immediately within object. */
- if (BINFO_INHERITANCE_CHAIN (basetype_path) == NULL_TREE)
- {
- /* Are we (or an enclosing scope) friends with the class that has
- FIELD? */
- if (is_friend (context, previous_scope))
- PUBLIC_RETURN;
-
- /* If it's private, it's private, you letch. */
- if (TREE_PRIVATE (field))
- PRIVATE_RETURN;
-
- /* ARM $11.5. Member functions of a derived class can access the
- non-static protected members of a base class only through a
- pointer to the derived class, a reference to it, or an object
- of it. Also any subsequently derived classes also have
- access. */
- else if (TREE_PROTECTED (field))
- {
- if (current_class_type
- && (static_mem || DECL_CONSTRUCTOR_P (field))
- && ACCESSIBLY_DERIVED_FROM_P (context, current_class_type))
- PUBLIC_RETURN;
- else
- PROTECTED_RETURN;
- }
+static tree
+dfs_access_in_type (binfo, data)
+ tree binfo;
+ void *data;
+{
+ tree decl = (tree) data;
+ tree type = BINFO_TYPE (binfo);
+ tree access = NULL_TREE;
+
+ if (context_for_name_lookup (decl) == type)
+ {
+ /* If we have desceneded to the scope of DECL, just note the
+ appropriate access. */
+ if (TREE_PRIVATE (decl))
+ access = access_private_node;
+ else if (TREE_PROTECTED (decl))
+ access = access_protected_node;
else
- PUBLIC_RETURN;
+ access = access_public_node;
}
-
- /* must reverse more than one element */
- basetype_path = reverse_path (basetype_path);
- types = basetype_path;
- via_protected = 0;
- access = access_default_node;
- protected_ok = static_mem && current_class_type
- && ACCESSIBLY_DERIVED_FROM_P (BINFO_TYPE (types), current_class_type);
-
- while (1)
+ else
{
- tree member;
- tree binfo = types;
- tree type = BINFO_TYPE (binfo);
- int private_ok = 0;
-
- /* Friends of a class can see protected members of its bases.
- Note that classes are their own friends. */
- if (is_friend (type, previous_scope))
+ /* First, check for an access-declaration that gives us more
+ access to the DECL. The CONST_DECL for an enumeration
+ constant will not have DECL_LANG_SPECIFIC, and thus no
+ DECL_ACCESS. */
+ if (DECL_LANG_SPECIFIC (decl))
{
- protected_ok = 1;
- private_ok = 1;
+ access = purpose_member (type, DECL_ACCESS (decl));
+ if (access)
+ access = TREE_VALUE (access);
}
- member = purpose_member (type, DECL_ACCESS (field));
- if (member)
+ if (!access)
{
- access = TREE_VALUE (member);
- break;
- }
-
- types = BINFO_INHERITANCE_CHAIN (types);
-
- /* If the next type was VIA_PROTECTED, then fields of all remaining
- classes past that one are *at least* protected. */
- if (types)
- {
- if (TREE_VIA_PROTECTED (types))
- via_protected = 1;
- else if (! TREE_VIA_PUBLIC (types) && ! private_ok)
+ int i;
+ int n_baselinks;
+ tree binfos;
+
+ /* Otherwise, scan our baseclasses, and pick the most favorable
+ access. */
+ binfos = BINFO_BASETYPES (binfo);
+ n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;
+ for (i = 0; i < n_baselinks; ++i)
{
- access = access_private_node;
- break;
+ tree base_binfo = TREE_VEC_ELT (binfos, i);
+ tree base_access = TREE_CHAIN (canonical_binfo (base_binfo));
+
+ if (!base_access || base_access == access_private_node)
+ /* If it was not accessible in the base, or only
+ accessible as a private member, we can't access it
+ all. */
+ base_access = NULL_TREE;
+ else if (TREE_VIA_PROTECTED (base_binfo))
+ /* Public and protected members in the base are
+ protected here. */
+ base_access = access_protected_node;
+ else if (!TREE_VIA_PUBLIC (base_binfo))
+ /* Public and protected members in the base are
+ private here. */
+ base_access = access_private_node;
+
+ /* See if the new access, via this base, gives more
+ access than our previous best access. */
+ if (base_access &&
+ (base_access == access_public_node
+ || (base_access == access_protected_node
+ && access != access_public_node)
+ || (base_access == access_private_node
+ && !access)))
+ {
+ access = base_access;
+
+ /* If the new access is public, we can't do better. */
+ if (access == access_public_node)
+ break;
+ }
}
}
- else
- break;
}
- /* No special visibilities apply. Use normal rules. */
+ /* Note the access to DECL in TYPE. */
+ TREE_CHAIN (binfo) = access;
+
+ /* Mark TYPE as visited so that if we reach it again we do not
+ duplicate our efforts here. */
+ SET_BINFO_MARKED (binfo);
+
+ return NULL_TREE;
+}
+
+/* Return the access to DECL in TYPE. */
+
+static tree
+access_in_type (type, decl)
+ tree type;
+ tree decl;
+{
+ tree binfo = TYPE_BINFO (type);
+
+ /* We must take into account
+
+ [class.paths]
+
+ If a name can be reached by several paths through a multiple
+ inheritance graph, the access is that of the path that gives
+ most access.
+
+ The algorithm we use is to make a post-order depth-first traversal
+ of the base-class hierarchy. As we come up the tree, we annotate
+ each node with the most lenient access. */
+ dfs_walk_real (binfo, 0, dfs_access_in_type, shared_unmarked_p, decl);
+ dfs_walk (binfo, dfs_unmark, shared_marked_p, 0);
+ assert_canonical_unmarked (binfo);
+
+ return TREE_CHAIN (binfo);
+}
+
+/* Called from dfs_accessible_p via dfs_walk. */
+
+static tree
+dfs_accessible_queue_p (binfo, data)
+ tree binfo;
+ void *data ATTRIBUTE_UNUSED;
+{
+ if (BINFO_MARKED (binfo))
+ return NULL_TREE;
+
+ /* If this class is inherited via private or protected inheritance,
+ then we can't see it, unless we are a friend of the subclass. */
+ if (!TREE_VIA_PUBLIC (binfo)
+ && !is_friend (BINFO_TYPE (BINFO_INHERITANCE_CHAIN (binfo)),
+ current_scope ()))
+ return NULL_TREE;
+
+ return canonical_binfo (binfo);
+}
+
+/* Called from dfs_accessible_p via dfs_walk. */
+
+static tree
+dfs_accessible_p (binfo, data)
+ tree binfo;
+ void *data;
+{
+ int protected_ok = data != 0;
+ tree access;
+
+ /* We marked the binfos while computing the access in each type.
+ So, we unmark as we go now. */
+ SET_BINFO_MARKED (binfo);
+
+ access = TREE_CHAIN (binfo);
+ if (access == access_public_node
+ || (access == access_protected_node && protected_ok))
+ return binfo;
+ else if (access && is_friend (BINFO_TYPE (binfo), current_scope ()))
+ return binfo;
+
+ return NULL_TREE;
+}
+
+/* Returns non-zero if it is OK to access DECL when named in TYPE
+ through an object indiated by BINFO in the context of DERIVED. */
+
+static int
+protected_accessible_p (type, decl, derived, binfo)
+ tree type;
+ tree decl;
+ tree derived;
+ tree binfo;
+{
+ tree access;
+
+ /* We're checking this clause from [class.access.base]
+
+ m as a member of N is protected, and the reference occurs in a
+ member or friend of class N, or in a member or friend of a
+ class P derived from N, where m as a member of P is private or
+ protected.
+
+ If DERIVED isn't derived from TYPE, then it certainly does not
+ apply. */
+ if (!DERIVED_FROM_P (type, derived))
+ return 0;
+
+ access = access_in_type (derived, decl);
+ if (same_type_p (derived, type))
+ {
+ if (access != access_private_node)
+ return 0;
+ }
+ else if (access != access_private_node
+ && access != access_protected_node)
+ return 0;
+
+ /* [class.protected]
+
+ When a friend or a member function of a derived class references
+ a protected nonstatic member of a base class, an access check
+ applies in addition to those described earlier in clause
+ _class.access_.4) Except when forming a pointer to member
+ (_expr.unary.op_), the access must be through a pointer to,
+ reference to, or object of the derived class itself (or any class
+ derived from that class) (_expr.ref_). If the access is to form
+ a pointer to member, the nested-name-specifier shall name the
+ derived class (or any class derived from that class). */
+ if (DECL_NONSTATIC_MEMBER_P (decl))
+ {
+ /* We can tell through what the reference is occurring by
+ chasing BINFO up to the root. */
+ tree t = binfo;
+ while (BINFO_INHERITANCE_CHAIN (t))
+ t = BINFO_INHERITANCE_CHAIN (t);
+
+ if (!DERIVED_FROM_P (derived, BINFO_TYPE (t)))
+ return 0;
+ }
+
+ return 1;
+}
+
+/* Returns non-zero if SCOPE is a friend of a type which would be able
+ to acces DECL, named in TYPE, through the object indicated by
+ BINFO. */
+
+static int
+friend_accessible_p (scope, type, decl, binfo)
+ tree scope;
+ tree type;
+ tree decl;
+ tree binfo;
+{
+ tree befriending_classes;
+ tree t;
+
+ if (!scope)
+ return 0;
+
+ if (TREE_CODE (scope) == FUNCTION_DECL
+ || DECL_FUNCTION_TEMPLATE_P (scope))
+ befriending_classes = DECL_BEFRIENDING_CLASSES (scope);
+ else if (TYPE_P (scope))
+ befriending_classes = CLASSTYPE_BEFRIENDING_CLASSES (scope);
+ else
+ return 0;
+
+ for (t = befriending_classes; t; t = TREE_CHAIN (t))
+ if (protected_accessible_p (type, decl, TREE_VALUE (t), binfo))
+ return 1;
+
+ if (TREE_CODE (scope) == FUNCTION_DECL
+ || DECL_FUNCTION_TEMPLATE_P (scope))
+ {
+ /* Perhaps this SCOPE is a member of a class which is a
+ friend. */
+ if (friend_accessible_p (DECL_CLASS_CONTEXT (scope), type,
+ decl, binfo))
+ return 1;
+
+ /* Or an instantiation of something which is a friend. */
+ if (DECL_TEMPLATE_INFO (scope))
+ return friend_accessible_p (DECL_TI_TEMPLATE (scope),
+ type, decl, binfo);
+ }
+ else if (CLASSTYPE_TEMPLATE_INFO (scope))
+ return friend_accessible_p (CLASSTYPE_TI_TEMPLATE (scope),
+ type, decl, binfo);
+
+ return 0;
+}
+
+/* DECL is a declaration from a base class of TYPE, which was the
+ classs used to name DECL. Return non-zero if, in the current
+ context, DECL is accessible. If TYPE is actually a BINFO node,
+ then we can tell in what context the access is occurring by looking
+ at the most derived class along the path indicated by BINFO. */
+
+int
+accessible_p (type, decl)
+ tree type;
+ tree decl;
+
+{
+ tree binfo;
+ tree t;
+
+ /* Non-zero if it's OK to access DECL if it has protected
+ accessibility in TYPE. */
+ int protected_ok = 0;
+
+ /* If we're not checking access, everything is accessible. */
+ if (!flag_access_control)
+ return 1;
- if (access == access_default_node)
+ /* If this declaration is in a block or namespace scope, there's no
+ access control. */
+ if (!TYPE_P (context_for_name_lookup (decl)))
+ return 1;
+
+ /* We don't do access control for types yet. */
+ if (TREE_CODE (decl) == TYPE_DECL)
+ return 1;
+
+ if (!TYPE_P (type))
{
- if (is_friend (context, previous_scope))
- access = access_public_node;
- else if (TREE_PRIVATE (field))
- access = access_private_node;
- else if (TREE_PROTECTED (field))
- access = access_protected_node;
- else
- access = access_public_node;
+ binfo = type;
+ type = BINFO_TYPE (type);
}
+ else
+ binfo = TYPE_BINFO (type);
- if (access == access_public_node && via_protected)
- access = access_protected_node;
+ /* [class.access.base]
- if (access == access_protected_node && protected_ok)
- access = access_public_node;
+ A member m is accessible when named in class N if
-#if 0
- if (access == access_public_node)
- DECL_PUBLIC (field) = 1;
- else if (access == access_protected_node)
- DECL_PROTECTED (field) = 1;
- else if (access == access_private_node)
- DECL_PRIVATE (field) = 1;
- else my_friendly_abort (96);
-#endif
- return access;
+ --m as a member of N is public, or
+
+ --m as a member of N is private, and the reference occurs in a
+ member or friend of class N, or
+
+ --m as a member of N is protected, and the reference occurs in a
+ member or friend of class N, or in a member or friend of a
+ class P derived from N, where m as a member of P is private or
+ protected, or
+
+ --there exists a base class B of N that is accessible at the point
+ of reference, and m is accessible when named in class B.
+
+ We walk the base class hierarchy, checking these conditions. */
+
+ /* Figure out where the reference is occurring. Check to see if
+ DECL is private or protected in this scope, since that will
+ determine whether protected access in TYPE allowed. */
+ if (current_class_type)
+ protected_ok
+ = protected_accessible_p (type, decl, current_class_type,
+ binfo);
+
+ /* Now, loop through the classes of which we are a friend. */
+ if (!protected_ok)
+ protected_ok = friend_accessible_p (current_scope (),
+ type, decl, binfo);
+
+ /* Standardize on the same that will access_in_type will use. We
+ don't need to know what path was chosen from this point onwards. */
+ binfo = TYPE_BINFO (type);
+
+ /* Compute the accessibility of DECL in the class hierarchy
+ dominated by type. */
+ access_in_type (type, decl);
+ /* Walk the hierarchy again, looking for a base class that allows
+ access. */
+ t = dfs_walk (binfo, dfs_accessible_p,
+ dfs_accessible_queue_p,
+ protected_ok ? &protected_ok : 0);
+ /* Clear any mark bits. Note that we have to walk the whole tree
+ here, since we have aborted the previous walk from some point
+ deep in the tree. */
+ dfs_walk (binfo, dfs_unmark, dfs_canonical_queue, 0);
+ assert_canonical_unmarked (binfo);
+
+ return t != NULL_TREE;
}
/* Routine to see if the sub-object denoted by the binfo PARENT can be
@@ -788,15 +1062,18 @@ is_subobject_of_p (parent, binfo)
tree binfos = BINFO_BASETYPES (binfo);
int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;
+ if (TREE_VIA_VIRTUAL (parent))
+ parent = TYPE_BINFO (TREE_TYPE (parent));
+ if (TREE_VIA_VIRTUAL (binfo))
+ binfo = TYPE_BINFO (TREE_TYPE (binfo));
+
if (parent == binfo)
return 1;
/* Process and/or queue base types. */
for (i = 0; i < n_baselinks; i++)
{
- tree base_binfo = TREE_VEC_ELT (binfos, i);
- if (TREE_VIA_VIRTUAL (base_binfo))
- base_binfo = TYPE_BINFO (BINFO_TYPE (base_binfo));
+ tree base_binfo = canonical_binfo (TREE_VEC_ELT (binfos, i));
if (is_subobject_of_p (parent, base_binfo))
return 1;
}
@@ -847,7 +1124,180 @@ lookup_fnfields_here (type, name)
return -1;
}
-/* Look for a field named NAME in an inheritance lattice dominated by
+struct lookup_field_info {
+ /* The type in which we're looking. */
+ tree type;
+ /* The name of the field for which we're looking. */
+ tree name;
+ /* If non-NULL, the current result of the lookup. */
+ tree rval;
+ /* The path to RVAL. */
+ tree rval_binfo;
+ /* If non-NULL, the lookup was ambiguous, and this is a list of the
+ candidates. */
+ tree ambiguous;
+ /* If non-zero, we are looking for types, not data members. */
+ int want_type;
+ /* If non-zero, RVAL was found by looking through a dependent base. */
+ int from_dep_base_p;
+ /* If something went wrong, a message indicating what. */
+ const char *errstr;
+};
+
+/* Returns non-zero if BINFO is not hidden by the value found by the
+ lookup so far. If BINFO is hidden, then there's no need to look in
+ it. DATA is really a struct lookup_field_info. Called from
+ lookup_field via breadth_first_search. */
+
+static tree
+lookup_field_queue_p (binfo, data)
+ tree binfo;
+ void *data;
+{
+ struct lookup_field_info *lfi = (struct lookup_field_info *) data;
+
+ /* Don't look for constructors or destructors in base classes. */
+ if (lfi->name == ctor_identifier || lfi->name == dtor_identifier)
+ return NULL_TREE;
+
+ /* If this base class is hidden by the best-known value so far, we
+ don't need to look. */
+ if (!lfi->from_dep_base_p && lfi->rval_binfo
+ && hides (lfi->rval_binfo, binfo))
+ return NULL_TREE;
+
+ if (TREE_VIA_VIRTUAL (binfo))
+ return binfo_member (BINFO_TYPE (binfo),
+ CLASSTYPE_VBASECLASSES (lfi->type));
+ else
+ return binfo;
+}
+
+/* DATA is really a struct lookup_field_info. Look for a field with
+ the name indicated there in BINFO. If this function returns a
+ non-NULL value it is the result of the lookup. Called from
+ lookup_field via breadth_first_search. */
+
+static tree
+lookup_field_r (binfo, data)
+ tree binfo;
+ void *data;
+{
+ struct lookup_field_info *lfi = (struct lookup_field_info *) data;
+ tree type = BINFO_TYPE (binfo);
+ tree nval;
+ int idx;
+ int from_dep_base_p;
+
+ /* First, look for a function. There can't be a function and a data
+ member with the same name, and if there's a function and a type
+ with the same name, the type is hidden by the function. */
+ idx = lookup_fnfields_here (type, lfi->name);
+ if (idx >= 0)
+ nval = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type), idx);
+ else
+ /* Look for a data member or type. */
+ nval = lookup_field_1 (type, lfi->name);
+
+ /* If there is no declaration with the indicated name in this type,
+ then there's nothing to do. */
+ if (!nval)
+ return NULL_TREE;
+
+ from_dep_base_p = dependent_base_p (binfo);
+ if (lfi->from_dep_base_p && !from_dep_base_p)
+ {
+ /* If the new declaration is not found via a dependent base, and
+ the old one was, then we must prefer the new one. We weren't
+ really supposed to be able to find the old one, so we don't
+ want to be affected by a specialization. Consider:
+
+ struct B { typedef int I; };
+ template <typename T> struct D1 : virtual public B {};
+ template <typename T> struct D :
+ public D1, virtual pubic B { I i; };
+
+ The `I' in `D<T>' is unambigousuly `B::I', regardless of how
+ D1 is specialized. */
+ lfi->from_dep_base_p = 0;
+ lfi->rval = NULL_TREE;
+ lfi->rval_binfo = NULL_TREE;
+ lfi->ambiguous = NULL_TREE;
+ lfi->errstr = 0;
+ }
+ else if (lfi->rval_binfo && !lfi->from_dep_base_p && from_dep_base_p)
+ /* Similarly, if the old declaration was not found via a dependent
+ base, and the new one is, ignore the new one. */
+ return NULL_TREE;
+
+ /* If the lookup already found a match, and the new value doesn't
+ hide the old one, we might have an ambiguity. */
+ if (lfi->rval_binfo && !hides (binfo, lfi->rval_binfo))
+ {
+ if (nval == lfi->rval && SHARED_MEMBER_P (nval))
+ /* The two things are really the same. */
+ ;
+ else if (hides (lfi->rval_binfo, binfo))
+ /* The previous value hides the new one. */
+ ;
+ else
+ {
+ /* We have a real ambiguity. We keep a chain of all the
+ candidates. */
+ if (!lfi->ambiguous && lfi->rval)
+ /* This is the first time we noticed an ambiguity. Add
+ what we previously thought was a reasonable candidate
+ to the list. */
+ lfi->ambiguous = scratch_tree_cons (NULL_TREE, lfi->rval,
+ NULL_TREE);
+ /* Add the new value. */
+ lfi->ambiguous = scratch_tree_cons (NULL_TREE, nval,
+ lfi->ambiguous);
+ lfi->errstr = "request for member `%D' is ambiguous";
+ }
+ }
+ else
+ {
+ /* The new lookup is the best we've got so far. Verify that
+ it's the kind of thing we're looking for. */
+ if (lfi->want_type && TREE_CODE (nval) != TYPE_DECL)
+ {
+ nval = purpose_member (lfi->name, CLASSTYPE_TAGS (type));
+ if (nval)
+ nval = TYPE_MAIN_DECL (TREE_VALUE (nval));
+ }
+
+ if (nval)
+ {
+ /* If the thing we're looking for is a virtual base class,
+ then we know we've got what we want at this point;
+ there's no way to get an ambiguity. */
+ if (VBASE_NAME_P (lfi->name))
+ {
+ lfi->rval = nval;
+ return nval;
+ }
+
+ if (from_dep_base_p && TREE_CODE (nval) != TYPE_DECL
+ /* We need to return a member template class so we can
+ define partial specializations. Is there a better
+ way? */
+ && !DECL_CLASS_TEMPLATE_P (nval))
+ /* The thing we're looking for isn't a type, so the implicit
+ typename extension doesn't apply, so we just pretend we
+ didn't find anything. */
+ return NULL_TREE;
+ }
+
+ lfi->rval = nval;
+ lfi->from_dep_base_p = from_dep_base_p;
+ lfi->rval_binfo = binfo;
+ }
+
+ return NULL_TREE;
+}
+
+/* Look for a memer named NAME in an inheritance lattice dominated by
XBASETYPE. PROTECT is zero if we can avoid computing access
information, otherwise it is 1. WANT_TYPE is 1 when we should only
return TYPE_DECLs, if no TYPE_DECL can be found return NULL_TREE.
@@ -857,17 +1307,13 @@ lookup_fnfields_here (type, name)
the error. */
tree
-lookup_field (xbasetype, name, protect, want_type)
+lookup_member (xbasetype, name, protect, want_type)
register tree xbasetype, name;
int protect, want_type;
{
- int head = 0, tail = 0;
- tree rval, rval_binfo = NULL_TREE, rval_binfo_h = NULL_TREE;
- tree type = NULL_TREE, basetype_chain, basetype_path = NULL_TREE;
- tree this_v = access_default_node;
- tree entry, binfo, binfo_h;
- tree own_access = access_default_node;
- int vbase_name_p = VBASE_NAME_P (name);
+ tree rval, rval_binfo = NULL_TREE;
+ tree type = NULL_TREE, basetype_path = NULL_TREE;
+ struct lookup_field_info lfi;
/* rval_binfo is the binfo associated with the found member, note,
this can be set with useful information, even when rval is not
@@ -883,16 +1329,7 @@ lookup_field (xbasetype, name, protect, want_type)
we know that binfo of a virtual base class will always == itself when
found along any line. (mrs) */
- char *errstr = 0;
-
-#if 0
- /* We cannot search for constructor/destructor names like this. */
- /* This can't go here, but where should it go? */
- /* If we are looking for a constructor in a templated type, use the
- unspecialized name, as that is how we store it. */
- if (IDENTIFIER_TEMPLATE (name))
- name = constructor_name (name);
-#endif
+ const char *errstr = 0;
if (xbasetype == current_class_type && TYPE_BEING_DEFINED (xbasetype)
&& IDENTIFIER_CLASS_VALUE (name))
@@ -924,276 +1361,83 @@ lookup_field (xbasetype, name, protect, want_type)
n_calls_lookup_field++;
#endif /* GATHER_STATISTICS */
- rval = lookup_field_1 (type, name);
-
- if (rval || lookup_fnfields_here (type, name) >= 0)
- {
- if (rval)
- {
- if (want_type)
- {
- if (TREE_CODE (rval) != TYPE_DECL)
- {
- rval = purpose_member (name, CLASSTYPE_TAGS (type));
- if (rval)
- rval = TYPE_MAIN_DECL (TREE_VALUE (rval));
- }
- }
- else
- {
- if (TREE_CODE (rval) == TYPE_DECL
- && lookup_fnfields_here (type, name) >= 0)
- rval = NULL_TREE;
- }
- }
-
- if (protect && rval)
- {
- if (TREE_PRIVATE (rval) | TREE_PROTECTED (rval))
- this_v = compute_access (basetype_path, rval);
- if (TREE_CODE (rval) == CONST_DECL)
- {
- if (this_v == access_private_node)
- errstr = "enum `%D' is a private value of class `%T'";
- else if (this_v == access_protected_node)
- errstr = "enum `%D' is a protected value of class `%T'";
- }
- else
- {
- if (this_v == access_private_node)
- errstr = "member `%D' is a private member of class `%T'";
- else if (this_v == access_protected_node)
- errstr = "member `%D' is a protected member of class `%T'";
- }
- }
-
- rval_binfo = basetype_path;
- goto out;
- }
-
- basetype_chain = build_expr_list (NULL_TREE, basetype_path);
-
- /* The ambiguity check relies upon breadth first searching. */
+ bzero ((PTR) &lfi, sizeof (lfi));
+ lfi.type = type;
+ lfi.name = name;
+ lfi.want_type = want_type;
+ bfs_walk (basetype_path, &lookup_field_r, &lookup_field_queue_p, &lfi);
+ rval = lfi.rval;
+ rval_binfo = lfi.rval_binfo;
+ if (rval_binfo)
+ type = BINFO_TYPE (rval_binfo);
+ errstr = lfi.errstr;
+
+ /* If we are not interested in ambiguities, don't report them;
+ just return NULL_TREE. */
+ if (!protect && lfi.ambiguous)
+ return NULL_TREE;
+
+ /* [class.access]
- search_stack = push_search_level (search_stack, &search_obstack);
- binfo = basetype_path;
- binfo_h = binfo;
+ In the case of overloaded function names, access control is
+ applied to the function selected by overloaded resolution. */
+ if (rval && protect && !is_overloaded_fn (rval)
+ && !IS_SIGNATURE_POINTER (DECL_REAL_CONTEXT (rval))
+ && !IS_SIGNATURE_REFERENCE (DECL_REAL_CONTEXT (rval))
+ && !enforce_access (xbasetype, rval))
+ return error_mark_node;
- while (1)
+ if (errstr && protect)
{
- tree binfos = BINFO_BASETYPES (binfo);
- int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;
- tree nval;
-
- /* Process and/or queue base types. */
- for (i = 0; i < n_baselinks; i++)
- {
- tree base_binfo = TREE_VEC_ELT (binfos, i);
- if (BINFO_FIELDS_MARKED (base_binfo) == 0)
- {
- tree btypes;
-
- SET_BINFO_FIELDS_MARKED (base_binfo);
- btypes = scratch_tree_cons (NULL_TREE, base_binfo, basetype_chain);
- if (TREE_VIA_VIRTUAL (base_binfo))
- btypes = scratch_tree_cons (NULL_TREE,
- TYPE_BINFO (BINFO_TYPE (TREE_VEC_ELT (BINFO_BASETYPES (binfo_h), i))),
- btypes);
- else
- btypes = scratch_tree_cons (NULL_TREE,
- TREE_VEC_ELT (BINFO_BASETYPES (binfo_h), i),
- btypes);
- obstack_ptr_grow (&search_obstack, btypes);
- tail += 1;
- if (tail >= search_stack->limit)
- my_friendly_abort (98);
- }
- }
-
- /* Process head of queue, if one exists. */
- if (head >= tail)
- break;
-
- basetype_chain = search_stack->first[head++];
- binfo_h = TREE_VALUE (basetype_chain);
- basetype_chain = TREE_CHAIN (basetype_chain);
- basetype_path = TREE_VALUE (basetype_chain);
- if (TREE_CHAIN (basetype_chain))
- my_friendly_assert
- ((BINFO_INHERITANCE_CHAIN (basetype_path)
- == TREE_VALUE (TREE_CHAIN (basetype_chain)))
- /* We only approximate base info for partial instantiations. */
- || current_template_parms,
- 980827);
- else
- my_friendly_assert (BINFO_INHERITANCE_CHAIN (basetype_path)
- == NULL_TREE, 980827);
-
- binfo = basetype_path;
- type = BINFO_TYPE (binfo);
-
- /* See if we can find NAME in TYPE. If RVAL is nonzero,
- and we do find NAME in TYPE, verify that such a second
- sighting is in fact valid. */
-
- nval = lookup_field_1 (type, name);
-
- if (nval || lookup_fnfields_here (type, name)>=0)
- {
- if (nval && nval == rval && SHARED_MEMBER_P (nval))
- {
- /* This is ok, the member found is the same [class.ambig] */
- }
- else if (rval_binfo && hides (rval_binfo_h, binfo_h))
- {
- /* This is ok, the member found is in rval_binfo, not
- here (binfo). */
- }
- else if (rval_binfo==NULL_TREE || hides (binfo_h, rval_binfo_h))
- {
- /* This is ok, the member found is here (binfo), not in
- rval_binfo. */
- if (nval)
- {
- rval = nval;
- if (protect)
- this_v = compute_access (basetype_path, rval);
- /* These may look ambiguous, but they really are not. */
- if (vbase_name_p)
- break;
- }
- else
- {
- /* Undo finding it before, as something else hides it. */
- rval = NULL_TREE;
- }
- rval_binfo = binfo;
- rval_binfo_h = binfo_h;
- }
- else
- {
- /* This is ambiguous. */
- errstr = "request for member `%D' is ambiguous";
- protect += 2;
- break;
- }
- }
+ cp_error (errstr, name, type);
+ if (lfi.ambiguous)
+ print_candidates (lfi.ambiguous);
+ rval = error_mark_node;
}
- {
- tree *tp = search_stack->first;
- tree *search_tail = tp + tail;
- if (rval_binfo)
- {
- type = BINFO_TYPE (rval_binfo);
+ /* If the thing we found was found via the implicit typename
+ extension, build the typename type. */
+ if (rval && lfi.from_dep_base_p && !DECL_CLASS_TEMPLATE_P (rval))
+ rval = TYPE_STUB_DECL (build_typename_type (BINFO_TYPE (basetype_path),
+ name, name,
+ TREE_TYPE (rval)));
- if (rval)
- {
- if (want_type)
- {
- if (TREE_CODE (rval) != TYPE_DECL)
- {
- rval = purpose_member (name, CLASSTYPE_TAGS (type));
- if (rval)
- rval = TYPE_MAIN_DECL (TREE_VALUE (rval));
- }
- }
- else
- {
- if (TREE_CODE (rval) == TYPE_DECL
- && lookup_fnfields_here (type, name) >= 0)
- rval = NULL_TREE;
- }
- }
- }
+ if (rval && is_overloaded_fn (rval))
+ rval = scratch_tree_cons (basetype_path, rval, NULL_TREE);
- if (rval == NULL_TREE)
- errstr = 0;
+ return rval;
+}
- /* If this FIELD_DECL defines its own access level, deal with that. */
- if (rval && errstr == 0
- && (protect & 1)
- && DECL_LANG_SPECIFIC (rval)
- && DECL_ACCESS (rval))
- {
- while (tp < search_tail)
- {
- /* If is possible for one of the derived types on the path to
- have defined special access for this field. Look for such
- declarations and report an error if a conflict is found. */
- tree new_v = NULL_TREE;
-
- if (this_v != access_default_node)
- new_v = compute_access (TREE_VALUE (TREE_CHAIN (*tp)), rval);
- if (this_v != access_default_node && new_v != this_v)
- {
- errstr = "conflicting access to member `%D'";
- this_v = access_default_node;
- }
- own_access = new_v;
- CLEAR_BINFO_FIELDS_MARKED (TREE_VALUE (TREE_CHAIN (*tp)));
- tp += 1;
- }
- }
- else
- {
- while (tp < search_tail)
- {
- CLEAR_BINFO_FIELDS_MARKED (TREE_VALUE (TREE_CHAIN (*tp)));
- tp += 1;
- }
- }
- }
- search_stack = pop_search_level (search_stack);
+/* Like lookup_member, except that if we find a function member we
+ return NULL_TREE. */
- if (errstr == 0)
- {
- if (own_access == access_private_node)
- errstr = "member `%D' declared private";
- else if (own_access == access_protected_node)
- errstr = "member `%D' declared protected";
- else if (this_v == access_private_node)
- errstr = TREE_PRIVATE (rval)
- ? "member `%D' is private"
- : "member `%D' is from private base class";
- else if (this_v == access_protected_node)
- errstr = TREE_PROTECTED (rval)
- ? "member `%D' is protected"
- : "member `%D' is from protected base class";
- }
+tree
+lookup_field (xbasetype, name, protect, want_type)
+ register tree xbasetype, name;
+ int protect, want_type;
+{
+ tree rval = lookup_member (xbasetype, name, protect, want_type);
+
+ /* Ignore functions. */
+ if (rval && TREE_CODE (rval) == TREE_LIST)
+ return NULL_TREE;
- out:
- if (protect == 2)
- {
- /* If we are not interested in ambiguities, don't report them,
- just return NULL_TREE. */
- rval = NULL_TREE;
- protect = 0;
- }
+ return rval;
+}
- if (errstr && protect)
- {
- cp_error (errstr, name, type);
- rval = error_mark_node;
- }
+/* Like lookup_member, except that if we find a non-function member we
+ return NULL_TREE. */
- /* Do implicit typename stuff. */
- if (rval && TREE_CODE (rval) == TYPE_DECL
- && processing_template_decl
- && ! currently_open_class (BINFO_TYPE (rval_binfo))
- && uses_template_parms (type))
- {
- binfo = rval_binfo;
- for (; ; binfo = BINFO_INHERITANCE_CHAIN (binfo))
- if (BINFO_INHERITANCE_CHAIN (binfo) == NULL_TREE
- || (BINFO_TYPE (BINFO_INHERITANCE_CHAIN (binfo))
- == current_class_type))
- break;
+tree
+lookup_fnfields (xbasetype, name, protect)
+ register tree xbasetype, name;
+ int protect;
+{
+ tree rval = lookup_member (xbasetype, name, protect, /*want_type=*/0);
- entry = make_typename_type (BINFO_TYPE (binfo), name);
- TREE_TYPE (entry) = TREE_TYPE (rval);
- rval = TYPE_MAIN_DECL (entry);
- }
+ /* Ignore non-functions. */
+ if (rval && TREE_CODE (rval) != TREE_LIST)
+ return NULL_TREE;
return rval;
}
@@ -1265,11 +1509,12 @@ lookup_nested_field (name, complain)
/* TYPE is a class type. Return the index of the fields within
the method vector with name NAME, or -1 is no such field exists. */
-static int
+int
lookup_fnfields_1 (type, name)
tree type, name;
{
- register tree method_vec = CLASSTYPE_METHOD_VEC (type);
+ register tree method_vec
+ = CLASS_TYPE_P (type) ? CLASSTYPE_METHOD_VEC (type) : NULL_TREE;
if (method_vec != 0)
{
@@ -1327,391 +1572,224 @@ lookup_fnfields_1 (type, name)
return -1;
}
+
+/* Walk the class hierarchy dominated by TYPE. FN is called for each
+ type in the hierarchy, in a breadth-first preorder traversal. .
+ If it ever returns a non-NULL value, that value is immediately
+ returned and the walk is terminated. At each node FN, is passed a
+ BINFO indicating the path from the curently visited base-class to
+ TYPE. The TREE_CHAINs of the BINFOs may be used for scratch space;
+ they are otherwise unused. Before each base-class is walked QFN is
+ called. If the value returned is non-zero, the base-class is
+ walked; otherwise it is not. If QFN is NULL, it is treated as a
+ function which always returns 1. Both FN and QFN are passed the
+ DATA whenever they are called. */
-/* Starting from BASETYPE, return a TREE_BASELINK-like object
- which gives the following information (in a list):
-
- TREE_TYPE: list of basetypes needed to get to...
- TREE_VALUE: list of all functions in a given type
- which have name NAME.
-
- No access information is computed by this function,
- other then to adorn the list of basetypes with
- TREE_VIA_PUBLIC.
-
- If there are two ways to find a name (two members), if COMPLAIN is
- non-zero, then error_mark_node is returned, and an error message is
- printed, otherwise, just an error_mark_node is returned.
-
- As a special case, is COMPLAIN is -1, we don't complain, and we
- don't return error_mark_node, but rather the complete list of
- virtuals. This is used by get_virtuals_named_this. */
-
-tree
-lookup_fnfields (basetype_path, name, complain)
- tree basetype_path, name;
- int complain;
+static tree
+bfs_walk (binfo, fn, qfn, data)
+ tree binfo;
+ tree (*fn) PROTO((tree, void *));
+ tree (*qfn) PROTO((tree, void *));
+ void *data;
{
- int head = 0, tail = 0;
- tree type, rval, rval_binfo = NULL_TREE, rvals = NULL_TREE;
- tree rval_binfo_h = NULL_TREE, binfo, basetype_chain, binfo_h;
- int idx, find_all = 0;
-
- /* rval_binfo is the binfo associated with the found member, note,
- this can be set with useful information, even when rval is not
- set, because it must deal with ALL members, not just function
- members. It is used for ambiguity checking and the hidden
- checks. Whereas rval is only set if a proper (not hidden)
- function member is found. */
-
- /* rval_binfo_h and binfo_h are binfo values used when we perform the
- hiding checks, as virtual base classes may not be shared. The strategy
- is we always go into the binfo hierarchy owned by TYPE_BINFO of
- virtual base classes, as we cross virtual base class lines. This way
- we know that binfo of a virtual base class will always == itself when
- found along any line. (mrs) */
-
- /* For now, don't try this. */
- int protect = complain;
-
- char *errstr = 0;
-
- if (complain == -1)
- {
- find_all = 1;
- protect = complain = 0;
- }
-
-#if 0
- /* We cannot search for constructor/destructor names like this. */
- /* This can't go here, but where should it go? */
- /* If we are looking for a constructor in a templated type, use the
- unspecialized name, as that is how we store it. */
- if (IDENTIFIER_TEMPLATE (name))
- name = constructor_name (name);
-#endif
-
- binfo = basetype_path;
- binfo_h = binfo;
- type = complete_type (BINFO_TYPE (basetype_path));
-
-#ifdef GATHER_STATISTICS
- n_calls_lookup_fnfields++;
-#endif /* GATHER_STATISTICS */
-
- idx = lookup_fnfields_here (type, name);
- if (idx >= 0 || lookup_field_1 (type, name))
- {
- rval_binfo = basetype_path;
- rval_binfo_h = rval_binfo;
- }
+ size_t head;
+ size_t tail;
+ tree rval = NULL_TREE;
+ /* An array of the base classes of BINFO. These will be built up in
+ breadth-first order, except where QFN prunes the search. */
+ varray_type bfs_bases;
- if (idx >= 0)
- {
- rval = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type), idx);
- rvals = scratch_tree_cons (basetype_path, rval, rvals);
- if (BINFO_BASETYPES (binfo) && CLASSTYPE_BASELINK_VEC (type))
- TREE_TYPE (rvals) = TREE_VEC_ELT (CLASSTYPE_BASELINK_VEC (type), idx);
+ /* Start with enough room for ten base classes. That will be enough
+ for most hierarchies. */
+ VARRAY_TREE_INIT (bfs_bases, 10, "search_stack");
- return rvals;
- }
- rval = NULL_TREE;
+ /* Put the first type into the stack. */
+ VARRAY_TREE (bfs_bases, 0) = binfo;
+ tail = 1;
- if (name == ctor_identifier || name == dtor_identifier)
+ for (head = 0; head < tail; ++head)
{
- /* Don't allow lookups of constructors and destructors to go
- deeper than the first place we look. */
- return NULL_TREE;
- }
-
- if (basetype_path == TYPE_BINFO (type))
- {
- basetype_chain = CLASSTYPE_BINFO_AS_LIST (type);
- my_friendly_assert (BINFO_INHERITANCE_CHAIN (basetype_path) == NULL_TREE,
- 980827);
- }
- else
- basetype_chain = build_expr_list (NULL_TREE, basetype_path);
-
- /* The ambiguity check relies upon breadth first searching. */
+ int i;
+ int n_baselinks;
+ tree binfos;
- search_stack = push_search_level (search_stack, &search_obstack);
- binfo = basetype_path;
- binfo_h = binfo;
+ /* Pull the next type out of the queue. */
+ binfo = VARRAY_TREE (bfs_bases, head);
- while (1)
- {
- tree binfos = BINFO_BASETYPES (binfo);
- int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;
- int idx;
+ /* If this is the one we're looking for, we're done. */
+ rval = (*fn) (binfo, data);
+ if (rval)
+ break;
- /* Process and/or queue base types. */
+ /* Queue up the base types. */
+ binfos = BINFO_BASETYPES (binfo);
+ n_baselinks = binfos ? TREE_VEC_LENGTH (binfos): 0;
for (i = 0; i < n_baselinks; i++)
{
tree base_binfo = TREE_VEC_ELT (binfos, i);
- if (BINFO_FIELDS_MARKED (base_binfo) == 0)
- {
- tree btypes;
-
- SET_BINFO_FIELDS_MARKED (base_binfo);
- btypes = scratch_tree_cons (NULL_TREE, base_binfo, basetype_chain);
- if (TREE_VIA_VIRTUAL (base_binfo))
- btypes = scratch_tree_cons (NULL_TREE,
- TYPE_BINFO (BINFO_TYPE (TREE_VEC_ELT (BINFO_BASETYPES (binfo_h), i))),
- btypes);
- else
- btypes = scratch_tree_cons (NULL_TREE,
- TREE_VEC_ELT (BINFO_BASETYPES (binfo_h), i),
- btypes);
- obstack_ptr_grow (&search_obstack, btypes);
- tail += 1;
- if (tail >= search_stack->limit)
- my_friendly_abort (99);
- }
- }
-
- /* Process head of queue, if one exists. */
- if (head >= tail)
- break;
- basetype_chain = search_stack->first[head++];
- binfo_h = TREE_VALUE (basetype_chain);
- basetype_chain = TREE_CHAIN (basetype_chain);
- basetype_path = TREE_VALUE (basetype_chain);
- if (TREE_CHAIN (basetype_chain))
- my_friendly_assert
- ((BINFO_INHERITANCE_CHAIN (basetype_path)
- == TREE_VALUE (TREE_CHAIN (basetype_chain)))
- /* We only approximate base info for partial instantiations. */
- || current_template_parms,
- 980827);
- else
- my_friendly_assert (BINFO_INHERITANCE_CHAIN (basetype_path)
- == NULL_TREE, 980827);
-
- binfo = basetype_path;
- type = BINFO_TYPE (binfo);
+ if (qfn)
+ base_binfo = (*qfn) (base_binfo, data);
- /* See if we can find NAME in TYPE. If RVAL is nonzero,
- and we do find NAME in TYPE, verify that such a second
- sighting is in fact valid. */
-
- idx = lookup_fnfields_here (type, name);
-
- if (idx >= 0 || (lookup_field_1 (type, name)!=NULL_TREE && !find_all))
- {
- if (rval_binfo && !find_all && hides (rval_binfo_h, binfo_h))
+ if (base_binfo)
{
- /* This is ok, the member found is in rval_binfo, not
- here (binfo). */
- }
- else if (rval_binfo==NULL_TREE || find_all || hides (binfo_h, rval_binfo_h))
- {
- /* This is ok, the member found is here (binfo), not in
- rval_binfo. */
- if (idx >= 0)
- {
- rval = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type), idx);
- /* Note, rvals can only be previously set if find_all is
- true. */
- rvals = scratch_tree_cons (basetype_path, rval, rvals);
- if (TYPE_BINFO_BASETYPES (type)
- && CLASSTYPE_BASELINK_VEC (type))
- TREE_TYPE (rvals) = TREE_VEC_ELT (CLASSTYPE_BASELINK_VEC (type), idx);
- }
- else
- {
- /* Undo finding it before, as something else hides it. */
- rval = NULL_TREE;
- rvals = NULL_TREE;
- }
- rval_binfo = binfo;
- rval_binfo_h = binfo_h;
- }
- else
- {
- /* This is ambiguous. */
- errstr = "request for method `%D' is ambiguous";
- rvals = error_mark_node;
- break;
+ if (tail == VARRAY_SIZE (bfs_bases))
+ VARRAY_GROW (bfs_bases, 2 * VARRAY_SIZE (bfs_bases));
+ VARRAY_TREE (bfs_bases, tail) = base_binfo;
+ ++tail;
}
}
}
- {
- tree *tp = search_stack->first;
- tree *search_tail = tp + tail;
- while (tp < search_tail)
- {
- CLEAR_BINFO_FIELDS_MARKED (TREE_VALUE (TREE_CHAIN (*tp)));
- tp += 1;
- }
- }
- search_stack = pop_search_level (search_stack);
+ /* Clean up. */
+ VARRAY_FREE (bfs_bases);
- if (errstr && protect)
- {
- cp_error (errstr, name);
- rvals = error_mark_node;
- }
-
- return rvals;
+ return rval;
}
-/* Look for a field or function named NAME in an inheritance lattice
- dominated by XBASETYPE. PROTECT is zero if we can avoid computing
- access information, otherwise it is 1. WANT_TYPE is 1 when we should
- only return TYPE_DECLs, if no TYPE_DECL can be found return NULL_TREE. */
+/* Exactly like bfs_walk, except that a depth-first traversal is
+ performed, and PREFN is called in preorder, while POSTFN is called
+ in postorder. */
-tree
-lookup_member (xbasetype, name, protect, want_type)
- tree xbasetype, name;
- int protect, want_type;
+static tree
+dfs_walk_real (binfo, prefn, postfn, qfn, data)
+ tree binfo;
+ tree (*prefn) PROTO((tree, void *));
+ tree (*postfn) PROTO((tree, void *));
+ tree (*qfn) PROTO((tree, void *));
+ void *data;
{
- tree ret, basetype_path;
+ int i;
+ int n_baselinks;
+ tree binfos;
+ tree rval = NULL_TREE;
- if (TREE_CODE (xbasetype) == TREE_VEC)
- basetype_path = xbasetype;
- else if (IS_AGGR_TYPE_CODE (TREE_CODE (xbasetype)))
+ /* Call the pre-order walking function. */
+ if (prefn)
{
- basetype_path = TYPE_BINFO (xbasetype);
- my_friendly_assert (BINFO_INHERITANCE_CHAIN (basetype_path)
- == NULL_TREE, 980827);
+ rval = (*prefn) (binfo, data);
+ if (rval)
+ return rval;
}
- else
- my_friendly_abort (97);
+
+ /* Process the basetypes. */
+ binfos = BINFO_BASETYPES (binfo);
+ n_baselinks = binfos ? TREE_VEC_LENGTH (binfos): 0;
+ for (i = 0; i < n_baselinks; i++)
+ {
+ tree base_binfo = TREE_VEC_ELT (binfos, i);
+
+ if (qfn)
+ base_binfo = (*qfn) (base_binfo, data);
+
+ if (base_binfo)
+ {
+ rval = dfs_walk_real (base_binfo, prefn, postfn, qfn, data);
+ if (rval)
+ return rval;
+ }
+ }
+
+ /* Call the post-order walking function. */
+ if (postfn)
+ rval = (*postfn) (binfo, data);
- ret = lookup_field (basetype_path, name, protect, want_type);
- if (! ret && ! want_type)
- ret = lookup_fnfields (basetype_path, name, protect);
- return ret;
+ return rval;
}
-
-/* BREADTH-FIRST SEARCH ROUTINES. */
-
-/* Search a multiple inheritance hierarchy by breadth-first search.
- BINFO is an aggregate type, possibly in a multiple-inheritance hierarchy.
- TESTFN is a function, which, if true, means that our condition has been met,
- and its return value should be returned.
- QFN, if non-NULL, is a predicate dictating whether the type should
- even be queued. */
+/* Exactly like bfs_walk, except that a depth-first post-order traversal is
+ performed. */
-static HOST_WIDE_INT
-breadth_first_search (binfo, testfn, qfn)
+tree
+dfs_walk (binfo, fn, qfn, data)
tree binfo;
- int (*testfn) PROTO((tree, int));
- int (*qfn) PROTO((tree, int));
+ tree (*fn) PROTO((tree, void *));
+ tree (*qfn) PROTO((tree, void *));
+ void *data;
{
- int head = 0, tail = 0;
- int rval = 0;
-
- search_stack = push_search_level (search_stack, &search_obstack);
+ return dfs_walk_real (binfo, 0, fn, qfn, data);
+}
- while (1)
- {
- tree binfos = BINFO_BASETYPES (binfo);
- int n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;
- int i;
+struct gvnt_info
+{
+ /* The name of the function we are looking for. */
+ tree name;
+ /* The overloaded functions we have found. */
+ tree fields;
+};
- /* Process and/or queue base types. */
- for (i = 0; i < n_baselinks; i++)
- {
- tree base_binfo = TREE_VEC_ELT (binfos, i);
+/* Called from get_virtuals_named_this via bfs_walk. */
- if (BINFO_MARKED (base_binfo) == 0
- && (qfn == 0 || (*qfn) (binfo, i)))
- {
- SET_BINFO_MARKED (base_binfo);
- obstack_ptr_grow (&search_obstack, binfo);
- obstack_ptr_grow (&search_obstack, (HOST_WIDE_INT) i);
- tail += 2;
- if (tail >= search_stack->limit)
- my_friendly_abort (100);
- }
- }
- /* Process head of queue, if one exists. */
- if (head >= tail)
- {
- rval = 0;
- break;
- }
+static tree
+get_virtuals_named_this_r (binfo, data)
+ tree binfo;
+ void *data;
+{
+ struct gvnt_info *gvnti = (struct gvnt_info *) data;
+ tree type = BINFO_TYPE (binfo);
+ int idx;
- binfo = search_stack->first[head++];
- i = (HOST_WIDE_INT) search_stack->first[head++];
- if ((rval = (*testfn) (binfo, i)))
- break;
- binfo = BINFO_BASETYPE (binfo, i);
- }
- {
- tree *tp = search_stack->first;
- tree *search_tail = tp + tail;
- while (tp < search_tail)
- {
- tree binfo = *tp++;
- int i = (HOST_WIDE_INT)(*tp++);
- CLEAR_BINFO_MARKED (BINFO_BASETYPE (binfo, i));
- }
- }
+ idx = lookup_fnfields_here (BINFO_TYPE (binfo), gvnti->name);
+ if (idx >= 0)
+ gvnti->fields
+ = scratch_tree_cons (binfo,
+ TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type),
+ idx),
+ gvnti->fields);
- search_stack = pop_search_level (search_stack);
- return rval;
+ return NULL_TREE;
}
-/* Functions to use in breadth first searches. */
-typedef int (*pfi) PROTO((tree, int));
-
-static tree declarator;
+/* Return the virtual functions with the indicated NAME in the type
+ indicated by BINFO. The result is a TREE_LIST whose TREE_PURPOSE
+ indicates the base class from which the TREE_VALUE (an OVERLOAD or
+ just a FUNCTION_DECL) originated. */
static tree
-get_virtuals_named_this (binfo)
+get_virtuals_named_this (binfo, name)
tree binfo;
+ tree name;
{
+ struct gvnt_info gvnti;
tree fields;
- fields = lookup_fnfields (binfo, declarator, -1);
- /* fields cannot be error_mark_node */
+ gvnti.name = name;
+ gvnti.fields = NULL_TREE;
- if (fields == 0)
- return 0;
+ bfs_walk (binfo, get_virtuals_named_this_r, 0, &gvnti);
/* Get to the function decls, and return the first virtual function
with this name, if there is one. */
- while (fields)
+ for (fields = gvnti.fields; fields; fields = next_baselink (fields))
{
tree fndecl;
for (fndecl = TREE_VALUE (fields); fndecl; fndecl = OVL_NEXT (fndecl))
if (DECL_VINDEX (OVL_CURRENT (fndecl)))
return fields;
- fields = next_baselink (fields);
}
return NULL_TREE;
}
static tree
-get_virtual_destructor (binfo, i)
+get_virtual_destructor (binfo, data)
tree binfo;
- int i;
+ void *data ATTRIBUTE_UNUSED;
{
tree type = BINFO_TYPE (binfo);
- if (i >= 0)
- type = BINFO_TYPE (TREE_VEC_ELT (BINFO_BASETYPES (binfo), i));
if (TYPE_HAS_DESTRUCTOR (type)
&& DECL_VINDEX (TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type), 1)))
return TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type), 1);
return 0;
}
-static int
-tree_has_any_destructor_p (binfo, i)
+static tree
+tree_has_any_destructor_p (binfo, data)
tree binfo;
- int i;
+ void *data ATTRIBUTE_UNUSED;
{
tree type = BINFO_TYPE (binfo);
- if (i >= 0)
- type = BINFO_TYPE (TREE_VEC_ELT (BINFO_BASETYPES (binfo), i));
- return TYPE_NEEDS_DESTRUCTOR (type);
+ return TYPE_NEEDS_DESTRUCTOR (type) ? binfo : NULL_TREE;
}
/* Returns > 0 if a function with type DRETTYPE overriding a function
@@ -1738,14 +1816,13 @@ covariant_return_p (brettype, drettype)
drettype = TREE_TYPE (drettype);
}
- if (comptypes (brettype, drettype, 1))
+ if (same_type_p (brettype, drettype))
return 0;
if (! (TREE_CODE (brettype) == TREE_CODE (drettype)
&& (TREE_CODE (brettype) == POINTER_TYPE
|| TREE_CODE (brettype) == REFERENCE_TYPE)
- && TYPE_READONLY (brettype) == TYPE_READONLY (drettype)
- && TYPE_VOLATILE (brettype) == TYPE_VOLATILE (drettype)))
+ && TYPE_QUALS (brettype) == TYPE_QUALS (drettype)))
return 0;
if (! can_convert (brettype, drettype))
@@ -1795,30 +1872,19 @@ get_matching_virtual (binfo, fndecl, dtorp)
/* Breadth first search routines start searching basetypes
of TYPE, so we must perform first ply of search here. */
if (dtorp)
- {
- if (tree_has_any_destructor_p (binfo, -1))
- tmp = get_virtual_destructor (binfo, -1);
-
- if (tmp)
- return tmp;
-
- tmp = (tree) breadth_first_search (binfo,
- (pfi) get_virtual_destructor,
- tree_has_any_destructor_p);
- return tmp;
- }
+ return bfs_walk (binfo, get_virtual_destructor,
+ tree_has_any_destructor_p, 0);
else
{
tree drettype, dtypes, btypes, instptr_type;
tree basetype = DECL_CLASS_CONTEXT (fndecl);
tree baselink, best = NULL_TREE;
tree name = DECL_ASSEMBLER_NAME (fndecl);
-
- declarator = DECL_NAME (fndecl);
+ tree declarator = DECL_NAME (fndecl);
if (IDENTIFIER_VIRTUAL_P (declarator) == 0)
return NULL_TREE;
- baselink = get_virtuals_named_this (binfo);
+ baselink = get_virtuals_named_this (binfo, declarator);
if (baselink == NULL_TREE)
return NULL_TREE;
@@ -1841,18 +1907,22 @@ get_matching_virtual (binfo, fndecl, dtorp)
btypes = TYPE_ARG_TYPES (TREE_TYPE (tmp));
if (instptr_type == NULL_TREE)
{
- if (compparms (TREE_CHAIN (btypes), dtypes, 3))
+ if (compparms (TREE_CHAIN (btypes), dtypes))
/* Caller knows to give error in this case. */
return tmp;
return NULL_TREE;
}
- if ((TYPE_READONLY (TREE_TYPE (TREE_VALUE (btypes)))
- == TYPE_READONLY (instptr_type))
- && compparms (TREE_CHAIN (btypes), TREE_CHAIN (dtypes), 3))
+ if (/* The first parameter is the `this' parameter,
+ which has POINTER_TYPE, and we can therefore
+ safely use TYPE_QUALS, rather than
+ CP_TYPE_QUALS. */
+ (TYPE_QUALS (TREE_TYPE (TREE_VALUE (btypes)))
+ == TYPE_QUALS (instptr_type))
+ && compparms (TREE_CHAIN (btypes), TREE_CHAIN (dtypes)))
{
tree brettype = TREE_TYPE (TREE_TYPE (tmp));
- if (comptypes (brettype, drettype, 1))
+ if (same_type_p (brettype, drettype))
/* OK */;
else if ((i = covariant_return_p (brettype, drettype)))
{
@@ -1866,7 +1936,7 @@ get_matching_virtual (binfo, fndecl, dtorp)
}
}
else if (IS_AGGR_TYPE_2 (brettype, drettype)
- && comptypes (brettype, drettype, 0))
+ && same_or_base_type_p (brettype, drettype))
{
error ("invalid covariant return type (must use pointer or reference)");
cp_error_at (" overriding `%#D'", tmp);
@@ -1878,15 +1948,15 @@ get_matching_virtual (binfo, fndecl, dtorp)
cp_error_at (" overriding definition as `%#D'", tmp);
SET_IDENTIFIER_ERROR_LOCUS (name, basetype);
}
- break;
+
+ /* FNDECL overrides this function. We continue to
+ check all the other functions in order to catch
+ errors; it might be that in some other baseclass
+ a virtual function was declared with the same
+ parameter types, but a different return type. */
+ best = tmp;
}
}
- /* If not at the end */
- if (tmps)
- {
- best = tmp;
- break;
- }
}
return best;
@@ -1944,7 +2014,7 @@ get_abstract_virtuals (type)
tree type;
{
tree vbases;
- tree abstract_virtuals = CLASSTYPE_ABSTRACT_VIRTUALS (type);
+ tree abstract_virtuals = NULL;
/* First get all from non-virtual bases. */
abstract_virtuals
@@ -1960,7 +2030,9 @@ get_abstract_virtuals (type)
{
tree base_pfn = FNADDR_FROM_VTABLE_ENTRY (TREE_VALUE (virtuals));
tree base_fndecl = TREE_OPERAND (base_pfn, 0);
- if (DECL_ABSTRACT_VIRTUAL_P (base_fndecl))
+ if (DECL_NEEDS_FINAL_OVERRIDER_P (base_fndecl))
+ cp_error ("`%#D' needs a final overrider", base_fndecl);
+ else if (DECL_ABSTRACT_VIRTUAL_P (base_fndecl))
abstract_virtuals = tree_cons (NULL_TREE, base_fndecl, abstract_virtuals);
virtuals = TREE_CHAIN (virtuals);
}
@@ -2079,151 +2151,82 @@ convert_pointer_to_single_level (to_type, expr)
last, 1);
}
-/* The main function which implements depth first search.
-
- This routine has to remember the path it walked up, when
- dfs_init_vbase_pointers is the work function, as otherwise there
- would be no record. */
+tree markedp (binfo, data)
+ tree binfo;
+ void *data ATTRIBUTE_UNUSED;
+{
+ return BINFO_MARKED (binfo) ? binfo : NULL_TREE;
+}
-static void
-dfs_walk (binfo, fn, qfn)
+static tree
+unmarkedp (binfo, data)
tree binfo;
- void (*fn) PROTO((tree));
- int (*qfn) PROTO((tree));
+ void *data ATTRIBUTE_UNUSED;
{
- tree binfos = BINFO_BASETYPES (binfo);
- int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;
-
- for (i = 0; i < n_baselinks; i++)
- {
- tree base_binfo = TREE_VEC_ELT (binfos, i);
-
- if (qfn == 0 || (*qfn)(base_binfo))
- {
- if (TREE_CODE (BINFO_TYPE (base_binfo)) == TEMPLATE_TYPE_PARM
- || TREE_CODE (BINFO_TYPE (base_binfo)) == TEMPLATE_TEMPLATE_PARM)
- /* Pass */;
- else if (fn == dfs_init_vbase_pointers)
- {
- /* When traversing an arbitrary MI hierarchy, we need to keep
- a record of the path we took to get down to the final base
- type, as otherwise there would be no record of it, and just
- trying to blindly convert at the bottom would be ambiguous.
-
- The easiest way is to do the conversions one step at a time,
- as we know we want the immediate base class at each step.
-
- The only special trick to converting one step at a time,
- is that when we hit the last virtual base class, we must
- use the SLOT value for it, and not use the normal convert
- routine. We use the last virtual base class, as in our
- implementation, we have pointers to all virtual base
- classes in the base object. */
-
- tree saved_vbase_decl_ptr_intermediate
- = vbase_decl_ptr_intermediate;
-
- if (TREE_VIA_VIRTUAL (base_binfo))
- {
- /* No need for the conversion here, as we know it is the
- right type. */
- vbase_decl_ptr_intermediate
- = CLASSTYPE_SEARCH_SLOT (BINFO_TYPE (base_binfo));
- }
- else
- {
- vbase_decl_ptr_intermediate
- = convert_pointer_to_single_level (BINFO_TYPE (base_binfo),
- vbase_decl_ptr_intermediate);
- }
+ return !BINFO_MARKED (binfo) ? binfo : NULL_TREE;
+}
- dfs_walk (base_binfo, fn, qfn);
+static tree
+marked_vtable_pathp (binfo, data)
+ tree binfo;
+ void *data ATTRIBUTE_UNUSED;
+{
+ return BINFO_VTABLE_PATH_MARKED (binfo) ? binfo : NULL_TREE;
+}
- vbase_decl_ptr_intermediate = saved_vbase_decl_ptr_intermediate;
- }
- else
- dfs_walk (base_binfo, fn, qfn);
- }
- }
+static tree
+unmarked_vtable_pathp (binfo, data)
+ tree binfo;
+ void *data ATTRIBUTE_UNUSED;
+{
+ return !BINFO_VTABLE_PATH_MARKED (binfo) ? binfo : NULL_TREE;
+}
- fn (binfo);
+static tree
+marked_new_vtablep (binfo, data)
+ tree binfo;
+ void *data ATTRIBUTE_UNUSED;
+{
+ return BINFO_NEW_VTABLE_MARKED (binfo) ? binfo : NULL_TREE;
}
-/* Like dfs_walk, but only walk until fn returns something, and return
- that. We also use the real vbase binfos instead of the placeholders
- in the normal binfo hierarchy. START is the most-derived type for this
- hierarchy, so that we can find the vbase binfos. */
+static tree
+unmarked_new_vtablep (binfo, data)
+ tree binfo;
+ void *data ATTRIBUTE_UNUSED;
+{
+ return !BINFO_NEW_VTABLE_MARKED (binfo) ? binfo : NULL_TREE;
+}
static tree
-dfs_search (binfo, fn, start)
- tree binfo, start;
- tree (*fn) PROTO((tree));
+marked_pushdecls_p (binfo, data)
+ tree binfo;
+ void *data ATTRIBUTE_UNUSED;
{
- tree binfos = BINFO_BASETYPES (binfo);
- int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;
- tree retval;
-
- for (i = 0; i < n_baselinks; i++)
- {
- tree base_binfo = TREE_VEC_ELT (binfos, i);
-
- if (TREE_CODE (BINFO_TYPE (base_binfo)) == TEMPLATE_TYPE_PARM
- || TREE_CODE (BINFO_TYPE (base_binfo)) == TEMPLATE_TEMPLATE_PARM)
- /* Pass */;
- else
- {
- if (TREE_VIA_VIRTUAL (base_binfo) && start)
- base_binfo = binfo_member (BINFO_TYPE (base_binfo),
- CLASSTYPE_VBASECLASSES (start));
- retval = dfs_search (base_binfo, fn, start);
- if (retval)
- return retval;
- }
- }
-
- return fn (binfo);
+ return BINFO_PUSHDECLS_MARKED (binfo) ? binfo : NULL_TREE;
}
-static int markedp (binfo) tree binfo;
-{ return BINFO_MARKED (binfo); }
-static int unmarkedp (binfo) tree binfo;
-{ return BINFO_MARKED (binfo) == 0; }
-
-#if 0
-static int bfs_markedp (binfo, i) tree binfo; int i;
-{ return BINFO_MARKED (BINFO_BASETYPE (binfo, i)); }
-static int bfs_unmarkedp (binfo, i) tree binfo; int i;
-{ return BINFO_MARKED (BINFO_BASETYPE (binfo, i)) == 0; }
-static int bfs_marked_vtable_pathp (binfo, i) tree binfo; int i;
-{ return BINFO_VTABLE_PATH_MARKED (BINFO_BASETYPE (binfo, i)); }
-static int bfs_unmarked_vtable_pathp (binfo, i) tree binfo; int i;
-{ return BINFO_VTABLE_PATH_MARKED (BINFO_BASETYPE (binfo, i)) == 0; }
-static int bfs_marked_new_vtablep (binfo, i) tree binfo; int i;
-{ return BINFO_NEW_VTABLE_MARKED (BINFO_BASETYPE (binfo, i)); }
-static int bfs_unmarked_new_vtablep (binfo, i) tree binfo; int i;
-{ return BINFO_NEW_VTABLE_MARKED (BINFO_BASETYPE (binfo, i)) == 0; }
-#endif
-
-static int marked_vtable_pathp (binfo) tree binfo;
-{ return BINFO_VTABLE_PATH_MARKED (binfo); }
-static int unmarked_vtable_pathp (binfo) tree binfo;
-{ return BINFO_VTABLE_PATH_MARKED (binfo) == 0; }
-static int marked_new_vtablep (binfo) tree binfo;
-{ return BINFO_NEW_VTABLE_MARKED (binfo); }
-static int unmarked_new_vtablep (binfo) tree binfo;
-{ return BINFO_NEW_VTABLE_MARKED (binfo) == 0; }
-static int marked_pushdecls_p (binfo) tree binfo;
-{ return BINFO_PUSHDECLS_MARKED (binfo); }
-static int unmarked_pushdecls_p (binfo) tree binfo;
-{ return BINFO_PUSHDECLS_MARKED (binfo) == 0; }
+static tree
+unmarked_pushdecls_p (binfo, data)
+ tree binfo;
+ void *data ATTRIBUTE_UNUSED;
+{
+ return !BINFO_PUSHDECLS_MARKED (binfo) ? binfo : NULL_TREE;
+}
#if 0
static int dfs_search_slot_nonempty_p (binfo) tree binfo;
{ return CLASSTYPE_SEARCH_SLOT (BINFO_TYPE (binfo)) != 0; }
#endif
-static int dfs_debug_unmarkedp (binfo) tree binfo;
-{ return CLASSTYPE_DEBUG_REQUESTED (BINFO_TYPE (binfo)) == 0; }
+static tree
+dfs_debug_unmarkedp (binfo, data)
+ tree binfo;
+ void *data ATTRIBUTE_UNUSED;
+{
+ return (!CLASSTYPE_DEBUG_REQUESTED (BINFO_TYPE (binfo))
+ ? binfo : NULL_TREE);
+}
/* The worker functions for `dfs_walk'. These do not need to
test anything (vis a vis marking) if they are paired with
@@ -2235,9 +2238,14 @@ dfs_mark (binfo) tree binfo;
{ SET_BINFO_MARKED (binfo); }
#endif
-static void
-dfs_unmark (binfo) tree binfo;
-{ CLEAR_BINFO_MARKED (binfo); }
+tree
+dfs_unmark (binfo, data)
+ tree binfo;
+ void *data ATTRIBUTE_UNUSED;
+{
+ CLEAR_BINFO_MARKED (binfo);
+ return NULL_TREE;
+}
#if 0
static void
@@ -2261,9 +2269,10 @@ dfs_clear_search_slot (binfo) tree binfo;
{ CLASSTYPE_SEARCH_SLOT (BINFO_TYPE (binfo)) = 0; }
#endif
-static void
-dfs_debug_mark (binfo)
+static tree
+dfs_debug_mark (binfo, data)
tree binfo;
+ void *data ATTRIBUTE_UNUSED;
{
tree t = BINFO_TYPE (binfo);
@@ -2274,12 +2283,12 @@ dfs_debug_mark (binfo)
CLASSTYPE_DEBUG_REQUESTED (t) = 1;
if (methods == 0)
- return;
+ return NULL_TREE;
/* If interface info is known, either we've already emitted the debug
info or we don't need to. */
if (CLASSTYPE_INTERFACE_KNOWN (t))
- return;
+ return NULL_TREE;
/* If debug info is requested from this context for this type, supply it.
If debug info is requested from another context for this type,
@@ -2303,7 +2312,7 @@ dfs_debug_mark (binfo)
/* Somebody, somewhere is going to have to define this
virtual function. When they do, they will provide
the debugging info. */
- return;
+ return NULL_TREE;
}
methods = TREE_CHAIN (methods);
}
@@ -2312,17 +2321,26 @@ dfs_debug_mark (binfo)
so we must write out the debug info ourselves. */
TYPE_DECL_SUPPRESS_DEBUG (TYPE_NAME (t)) = 0;
rest_of_type_compilation (t, toplevel_bindings_p ());
+
+ return NULL_TREE;
}
-/* Attach to the type of the virtual base class, the pointer to the
- virtual base class, given the global pointer vbase_decl_ptr.
+struct vbase_info
+{
+ tree decl_ptr;
+ tree inits;
+ tree vbase_types;
+};
- We use the global vbase_types. ICK! */
+/* Attach to the type of the virtual base class, the pointer to the
+ virtual base class. */
-static void
-dfs_find_vbases (binfo)
+static tree
+dfs_find_vbases (binfo, data)
tree binfo;
+ void *data;
{
+ struct vbase_info *vi = (struct vbase_info *) data;
tree binfos = BINFO_BASETYPES (binfo);
int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;
@@ -2334,21 +2352,25 @@ dfs_find_vbases (binfo)
&& CLASSTYPE_SEARCH_SLOT (BINFO_TYPE (base_binfo)) == 0)
{
tree vbase = BINFO_TYPE (base_binfo);
- tree binfo = binfo_member (vbase, vbase_types);
+ tree binfo = binfo_member (vbase, vi->vbase_types);
CLASSTYPE_SEARCH_SLOT (vbase)
= build (PLUS_EXPR, build_pointer_type (vbase),
- vbase_decl_ptr, BINFO_OFFSET (binfo));
+ vi->decl_ptr, BINFO_OFFSET (binfo));
}
}
SET_BINFO_VTABLE_PATH_MARKED (binfo);
SET_BINFO_NEW_VTABLE_MARKED (binfo);
+
+ return NULL_TREE;
}
-static void
-dfs_init_vbase_pointers (binfo)
+static tree
+dfs_init_vbase_pointers (binfo, data)
tree binfo;
+ void *data;
{
+ struct vbase_info *vi = (struct vbase_info *) data;
tree type = BINFO_TYPE (binfo);
tree fields = TYPE_FIELDS (type);
tree this_vbase_ptr;
@@ -2362,42 +2384,57 @@ dfs_init_vbase_pointers (binfo)
fields = TREE_CHAIN (fields);
#endif
+ if (BINFO_INHERITANCE_CHAIN (binfo))
+ {
+ this_vbase_ptr = TREE_CHAIN (BINFO_INHERITANCE_CHAIN (binfo));
+ if (TREE_VIA_VIRTUAL (binfo))
+ this_vbase_ptr = CLASSTYPE_SEARCH_SLOT (type);
+ else
+ this_vbase_ptr = convert_pointer_to_single_level (type,
+ this_vbase_ptr);
+ TREE_CHAIN (binfo) = this_vbase_ptr;
+ }
+ else
+ this_vbase_ptr = TREE_CHAIN (binfo);
+
if (fields == NULL_TREE
|| DECL_NAME (fields) == NULL_TREE
|| ! VBASE_NAME_P (DECL_NAME (fields)))
- return;
-
- this_vbase_ptr = vbase_decl_ptr_intermediate;
+ return NULL_TREE;
- if (build_pointer_type (type) != TYPE_MAIN_VARIANT (TREE_TYPE (this_vbase_ptr)))
+ if (build_pointer_type (type)
+ != TYPE_MAIN_VARIANT (TREE_TYPE (this_vbase_ptr)))
my_friendly_abort (125);
- while (fields && DECL_NAME (fields)
- && VBASE_NAME_P (DECL_NAME (fields)))
+ while (fields && DECL_NAME (fields) && VBASE_NAME_P (DECL_NAME (fields)))
{
tree ref = build (COMPONENT_REF, TREE_TYPE (fields),
build_indirect_ref (this_vbase_ptr, NULL_PTR), fields);
tree init = CLASSTYPE_SEARCH_SLOT (TREE_TYPE (TREE_TYPE (fields)));
- vbase_init_result = tree_cons (binfo_member (TREE_TYPE (TREE_TYPE (fields)),
- vbase_types),
- build_modify_expr (ref, NOP_EXPR, init),
- vbase_init_result);
+ vi->inits = tree_cons (binfo_member (TREE_TYPE (TREE_TYPE (fields)),
+ vi->vbase_types),
+ build_modify_expr (ref, NOP_EXPR, init),
+ vi->inits);
fields = TREE_CHAIN (fields);
}
+
+ return NULL_TREE;
}
/* Sometimes this needs to clear both VTABLE_PATH and NEW_VTABLE. Other
times, just NEW_VTABLE, but optimizer should make both with equal
efficiency (though it does not currently). */
-static void
-dfs_clear_vbase_slots (binfo)
+static tree
+dfs_clear_vbase_slots (binfo, data)
tree binfo;
+ void *data ATTRIBUTE_UNUSED;
{
tree type = BINFO_TYPE (binfo);
CLASSTYPE_SEARCH_SLOT (type) = 0;
CLEAR_BINFO_VTABLE_PATH_MARKED (binfo);
CLEAR_BINFO_NEW_VTABLE_MARKED (binfo);
+ return NULL_TREE;
}
tree
@@ -2407,17 +2444,29 @@ init_vbase_pointers (type, decl_ptr)
{
if (TYPE_USES_VIRTUAL_BASECLASSES (type))
{
+ struct vbase_info vi;
int old_flag = flag_this_is_variable;
tree binfo = TYPE_BINFO (type);
flag_this_is_variable = -2;
- vbase_types = CLASSTYPE_VBASECLASSES (type);
- vbase_decl_ptr = vbase_decl_ptr_intermediate = decl_ptr;
- vbase_init_result = NULL_TREE;
- dfs_walk (binfo, dfs_find_vbases, unmarked_vtable_pathp);
- dfs_walk (binfo, dfs_init_vbase_pointers, marked_vtable_pathp);
- dfs_walk (binfo, dfs_clear_vbase_slots, marked_new_vtablep);
+
+ /* Find all the virtual base classes, marking them for later
+ initialization. */
+ vi.decl_ptr = decl_ptr;
+ vi.vbase_types = CLASSTYPE_VBASECLASSES (type);
+ vi.inits = NULL_TREE;
+
+ dfs_walk (binfo, dfs_find_vbases, unmarked_vtable_pathp, &vi);
+
+ /* Build up a list of the initializers. */
+ TREE_CHAIN (binfo) = decl_ptr;
+ dfs_walk_real (binfo,
+ dfs_init_vbase_pointers, 0,
+ marked_vtable_pathp,
+ &vi);
+
+ dfs_walk (binfo, dfs_clear_vbase_slots, marked_new_vtablep, 0);
flag_this_is_variable = old_flag;
- return vbase_init_result;
+ return vi.inits;
}
return 0;
}
@@ -2531,7 +2580,7 @@ expand_upcast_fixups (binfo, addr, orig_addr, vbase, vbase_addr, t,
/* Dup it if it isn't in local scope yet. */
nvtbl = build_decl
(VAR_DECL, DECL_NAME (vtbl),
- TYPE_MAIN_VARIANT (TREE_TYPE (BINFO_VTABLE (binfo))));
+ TYPE_MAIN_VARIANT (TREE_TYPE (vtbl)));
DECL_ALIGN (nvtbl) = MAX (TYPE_ALIGN (double_type_node),
DECL_ALIGN (nvtbl));
TREE_READONLY (nvtbl) = 0;
@@ -2556,8 +2605,7 @@ expand_upcast_fixups (binfo, addr, orig_addr, vbase, vbase_addr, t,
(build_indirect_ref (addr, NULL_PTR),
DECL_CONTEXT (CLASSTYPE_VFIELD (BINFO_TYPE (binfo))));
expand_expr_stmt
- (build_modify_expr (ref, NOP_EXPR,
- build_unary_op (ADDR_EXPR, nvtbl, 0)));
+ (build_modify_expr (ref, NOP_EXPR, nvtbl));
}
assemble_external (vtbl);
aref = build_array_ref (vtbl, idx);
@@ -2596,8 +2644,9 @@ expand_upcast_fixups (binfo, addr, orig_addr, vbase, vbase_addr, t,
TREE_READONLY (new_delta) = 0;
TREE_TYPE (new_delta) =
- cp_build_type_variant (TREE_TYPE (new_delta), /*constp=*/0,
- TYPE_VOLATILE (TREE_TYPE (new_delta)));
+ cp_build_qualified_type (TREE_TYPE (new_delta),
+ CP_TYPE_QUALS (TREE_TYPE (new_delta))
+ & ~TYPE_QUAL_CONST);
expand_expr_stmt (build_modify_expr (new_delta, NOP_EXPR,
old_delta));
}
@@ -2655,10 +2704,7 @@ fixup_virtual_upcast_offsets (real_binfo, binfo, init_self, can_elide, addr, ori
When USE_COMPUTED_OFFSETS is non-zero, we can assume that the
object was laid out by a top-level constructor and the computed
offsets are valid to store vtables. When zero, we must store new
- vtables through virtual baseclass pointers.
-
- We setup and use the globals: vbase_decl_ptr, vbase_types
- ICK! */
+ vtables through virtual baseclass pointers. */
void
expand_indirect_vtbls_init (binfo, true_exp, decl_ptr)
@@ -2682,17 +2728,19 @@ expand_indirect_vtbls_init (binfo, true_exp, decl_ptr)
{
rtx fixup_insns = NULL_RTX;
tree vbases = CLASSTYPE_VBASECLASSES (type);
- vbase_types = vbases;
- vbase_decl_ptr = true_exp ? build_unary_op (ADDR_EXPR, true_exp, 0) : decl_ptr;
+ struct vbase_info vi;
+ vi.decl_ptr = (true_exp ? build_unary_op (ADDR_EXPR, true_exp, 0)
+ : decl_ptr);
+ vi.vbase_types = vbases;
- dfs_walk (binfo, dfs_find_vbases, unmarked_new_vtablep);
+ dfs_walk (binfo, dfs_find_vbases, unmarked_new_vtablep, &vi);
/* Initialized with vtables of type TYPE. */
for (; vbases; vbases = TREE_CHAIN (vbases))
{
tree addr;
- addr = convert_pointer_to_vbase (TREE_TYPE (vbases), vbase_decl_ptr);
+ addr = convert_pointer_to_vbase (TREE_TYPE (vbases), vi.decl_ptr);
/* Do all vtables from this virtual base. */
/* This assumes that virtual bases can never serve as parent
@@ -2717,7 +2765,7 @@ expand_indirect_vtbls_init (binfo, true_exp, decl_ptr)
push_to_sequence (fixup_insns);
fixup_virtual_upcast_offsets (vbases,
TYPE_BINFO (BINFO_TYPE (vbases)),
- 1, 0, addr, vbase_decl_ptr,
+ 1, 0, addr, vi.decl_ptr,
type, vbases, &vbase_offsets);
fixup_insns = get_insns ();
end_sequence ();
@@ -2739,7 +2787,7 @@ expand_indirect_vtbls_init (binfo, true_exp, decl_ptr)
expand_end_cond ();
}
- dfs_walk (binfo, dfs_clear_vbase_slots, marked_new_vtablep);
+ dfs_walk (binfo, dfs_clear_vbase_slots, marked_new_vtablep, 0);
}
}
@@ -2747,36 +2795,43 @@ expand_indirect_vtbls_init (binfo, true_exp, decl_ptr)
This adds type to the vbase_types list in reverse dfs order.
Ordering is very important, so don't change it. */
-static void
-dfs_get_vbase_types (binfo)
+static tree
+dfs_get_vbase_types (binfo, data)
tree binfo;
+ void *data;
{
+ tree *vbase_types = (tree *) data;
+
if (TREE_VIA_VIRTUAL (binfo) && ! BINFO_VBASE_MARKED (binfo))
{
tree new_vbase = make_binfo (integer_zero_node, binfo,
BINFO_VTABLE (binfo),
BINFO_VIRTUALS (binfo));
- TREE_CHAIN (new_vbase) = vbase_types;
+ TREE_CHAIN (new_vbase) = *vbase_types;
TREE_VIA_VIRTUAL (new_vbase) = 1;
- vbase_types = new_vbase;
+ *vbase_types = new_vbase;
SET_BINFO_VBASE_MARKED (binfo);
}
SET_BINFO_MARKED (binfo);
+ return NULL_TREE;
}
-/* get a list of virtual base classes in dfs order. */
+/* Return a list of binfos for the virtual base classes for TYPE, in
+ depth-first search order. The list is freshly allocated, so
+ no modification is made to the current binfo hierarchy. */
tree
get_vbase_types (type)
tree type;
{
+ tree vbase_types;
tree vbases;
tree binfo;
binfo = TYPE_BINFO (type);
vbase_types = NULL_TREE;
- dfs_walk (binfo, dfs_get_vbase_types, unmarkedp);
- dfs_walk (binfo, dfs_unmark, markedp);
+ dfs_walk (binfo, dfs_get_vbase_types, unmarkedp, &vbase_types);
+ dfs_walk (binfo, dfs_unmark, markedp, 0);
/* Rely upon the reverse dfs ordering from dfs_get_vbase_types, and now
reverse it so that we get normal dfs ordering. */
vbase_types = nreverse (vbase_types);
@@ -2814,13 +2869,13 @@ note_debug_info_needed (type)
if (write_symbols == DWARF_DEBUG || write_symbols == DWARF2_DEBUG)
return;
- dfs_walk (TYPE_BINFO (type), dfs_debug_mark, dfs_debug_unmarkedp);
+ dfs_walk (TYPE_BINFO (type), dfs_debug_mark, dfs_debug_unmarkedp, 0);
for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
{
tree ttype;
if (TREE_CODE (field) == FIELD_DECL
&& IS_AGGR_TYPE (ttype = target_type (TREE_TYPE (field)))
- && dfs_debug_unmarkedp (TYPE_BINFO (ttype)))
+ && dfs_debug_unmarkedp (TYPE_BINFO (ttype), 0))
note_debug_info_needed (ttype);
}
}
@@ -2937,7 +2992,7 @@ dependent_base_p (binfo)
{
for (; binfo; binfo = BINFO_INHERITANCE_CHAIN (binfo))
{
- if (TREE_TYPE (binfo) == current_class_type)
+ if (currently_open_class (TREE_TYPE (binfo)))
break;
if (uses_template_parms (TREE_TYPE (binfo)))
return 1;
@@ -2964,10 +3019,12 @@ dependent_base_p (binfo)
Because if it is, it could be a set of overloaded methods from an
outer scope. */
-static void
-dfs_pushdecls (binfo)
+static tree
+dfs_pushdecls (binfo, data)
tree binfo;
+ void *data;
{
+ tree *closed_envelopes = (tree *) data;
tree type = BINFO_TYPE (binfo);
tree fields;
tree method_vec;
@@ -2993,7 +3050,7 @@ dfs_pushdecls (binfo)
if (DECL_NAME (fields) == NULL_TREE
&& TREE_CODE (TREE_TYPE (fields)) == UNION_TYPE)
{
- dfs_pushdecls (TYPE_BINFO (TREE_TYPE (fields)));
+ dfs_pushdecls (TYPE_BINFO (TREE_TYPE (fields)), data);
continue;
}
@@ -3004,22 +3061,24 @@ dfs_pushdecls (binfo)
/* If the class value is not an envelope of the kind described in
the comment above, we create a new envelope. */
+ maybe_push_cache_obstack ();
if (class_value == NULL_TREE || TREE_CODE (class_value) != TREE_LIST
|| TREE_PURPOSE (class_value) == NULL_TREE
|| TREE_CODE (TREE_PURPOSE (class_value)) == IDENTIFIER_NODE)
{
/* See comment above for a description of envelopes. */
- closed_envelopes = tree_cons (NULL_TREE, class_value,
- closed_envelopes);
- IDENTIFIER_CLASS_VALUE (name) = closed_envelopes;
+ *closed_envelopes = tree_cons (NULL_TREE, class_value,
+ *closed_envelopes);
+ IDENTIFIER_CLASS_VALUE (name) = *closed_envelopes;
class_value = IDENTIFIER_CLASS_VALUE (name);
}
envelope_add_decl (type, fields, &TREE_PURPOSE (class_value));
+ pop_obstacks ();
}
}
- method_vec = CLASSTYPE_METHOD_VEC (type);
+ method_vec = CLASS_TYPE_P (type) ? CLASSTYPE_METHOD_VEC (type) : NULL_TREE;
if (method_vec && ! dummy)
{
tree *methods;
@@ -3041,6 +3100,8 @@ dfs_pushdecls (binfo)
name = DECL_NAME (OVL_CURRENT (*methods));
class_value = IDENTIFIER_CLASS_VALUE (name);
+ maybe_push_cache_obstack ();
+
/* If the class value is not an envelope of the kind described in
the comment above, we create a new envelope. */
if (class_value == NULL_TREE || TREE_CODE (class_value) != TREE_LIST
@@ -3048,16 +3109,15 @@ dfs_pushdecls (binfo)
|| TREE_CODE (TREE_PURPOSE (class_value)) == IDENTIFIER_NODE)
{
/* See comment above for a description of envelopes. */
- closed_envelopes = tree_cons (NULL_TREE, class_value,
- closed_envelopes);
- IDENTIFIER_CLASS_VALUE (name) = closed_envelopes;
+ *closed_envelopes = tree_cons (NULL_TREE, class_value,
+ *closed_envelopes);
+ IDENTIFIER_CLASS_VALUE (name) = *closed_envelopes;
class_value = IDENTIFIER_CLASS_VALUE (name);
}
/* Here we try to rule out possible ambiguities.
If we can't do that, keep a TREE_LIST with possibly ambiguous
decls in there. */
- maybe_push_cache_obstack ();
/* Arbitrarily choose the first function in the list. This is OK
because this is only used for initial lookup; anything that
actually uses the function will look it up again. */
@@ -3070,16 +3130,20 @@ dfs_pushdecls (binfo)
/* We can't just use BINFO_MARKED because envelope_add_decl uses
DERIVED_FROM_P, which calls get_base_distance. */
SET_BINFO_PUSHDECLS_MARKED (binfo);
+
+ return NULL_TREE;
}
/* Consolidate unique (by name) member functions. */
-static void
-dfs_compress_decls (binfo)
+static tree
+dfs_compress_decls (binfo, data)
tree binfo;
+ void *data ATTRIBUTE_UNUSED;
{
tree type = BINFO_TYPE (binfo);
- tree method_vec = CLASSTYPE_METHOD_VEC (type);
+ tree method_vec
+ = CLASS_TYPE_P (type) ? CLASSTYPE_METHOD_VEC (type) : NULL_TREE;
if (processing_template_decl && type != current_class_type
&& dependent_base_p (binfo))
@@ -3113,6 +3177,8 @@ dfs_compress_decls (binfo)
}
}
CLEAR_BINFO_PUSHDECLS_MARKED (binfo);
+
+ return NULL_TREE;
}
/* When entering the scope of a class, we cache all of the
@@ -3127,14 +3193,22 @@ push_class_decls (type)
tree type;
{
struct obstack *ambient_obstack = current_obstack;
+ tree closed_envelopes = NULL_TREE;
search_stack = push_search_level (search_stack, &search_obstack);
+ /* Build up all the relevant bindings and such on the cache
+ obstack. That way no memory is wasted when we throw away the
+ cache later. */
+ maybe_push_cache_obstack ();
+
/* Push class fields into CLASS_VALUE scope, and mark. */
- dfs_walk (TYPE_BINFO (type), dfs_pushdecls, unmarked_pushdecls_p);
+ dfs_walk (TYPE_BINFO (type), dfs_pushdecls, unmarked_pushdecls_p,
+ &closed_envelopes);
/* Compress fields which have only a single entry
by a given name, and unmark. */
- dfs_walk (TYPE_BINFO (type), dfs_compress_decls, marked_pushdecls_p);
+ dfs_walk (TYPE_BINFO (type), dfs_compress_decls, marked_pushdecls_p,
+ 0);
/* Open up all the closed envelopes and push the contained decls into
class scope. */
@@ -3196,14 +3270,19 @@ push_class_decls (type)
pushdecl_class_level (new);
closed_envelopes = TREE_CHAIN (closed_envelopes);
}
+
+ /* Undo the call to maybe_push_cache_obstack above. */
+ pop_obstacks ();
+
current_obstack = ambient_obstack;
}
/* Here's a subroutine we need because C lacks lambdas. */
-static void
-dfs_unuse_fields (binfo)
+static tree
+dfs_unuse_fields (binfo, data)
tree binfo;
+ void *data ATTRIBUTE_UNUSED;
{
tree type = TREE_TYPE (binfo);
tree fields;
@@ -3218,13 +3297,15 @@ dfs_unuse_fields (binfo)
&& TREE_CODE (TREE_TYPE (fields)) == UNION_TYPE)
unuse_fields (TREE_TYPE (fields));
}
+
+ return NULL_TREE;
}
void
unuse_fields (type)
tree type;
{
- dfs_walk (TYPE_BINFO (type), dfs_unuse_fields, unmarkedp);
+ dfs_walk (TYPE_BINFO (type), dfs_unuse_fields, unmarkedp, 0);
}
void
@@ -3272,147 +3353,92 @@ reinit_search_statistics ()
#define scratch_tree_cons expr_tree_cons
-static tree conversions;
-static void
-add_conversions (binfo)
+static tree
+add_conversions (binfo, data)
tree binfo;
+ void *data;
{
int i;
tree method_vec = CLASSTYPE_METHOD_VEC (BINFO_TYPE (binfo));
+ tree *conversions = (tree *) data;
for (i = 2; i < TREE_VEC_LENGTH (method_vec); ++i)
{
tree tmp = TREE_VEC_ELT (method_vec, i);
+ tree name;
- if (!tmp
- || !IDENTIFIER_TYPENAME_P (DECL_NAME (OVL_CURRENT (tmp))))
+ if (!tmp || ! DECL_CONV_FN_P (OVL_CURRENT (tmp)))
break;
- conversions = scratch_tree_cons (binfo, tmp, conversions);
- }
- SET_BINFO_MARKED (binfo);
-}
-tree
-lookup_conversions (type)
- tree type;
-{
- conversions = NULL_TREE;
- if (TYPE_SIZE (type))
- {
- dfs_walk (TYPE_BINFO (type), add_conversions, unmarkedp);
- dfs_walk (TYPE_BINFO (type), dfs_unmark, markedp);
- }
- return conversions;
-}
-
-/* Subroutine of get_template_base. */
-
-static tree
-get_template_base_recursive (binfo, rval, template, via_virtual)
- tree binfo, template, rval;
- int via_virtual;
-{
- tree binfos;
- int i, n_baselinks;
- tree type = BINFO_TYPE (binfo);
+ name = DECL_NAME (OVL_CURRENT (tmp));
- if (CLASSTYPE_TEMPLATE_INFO (type)
- && CLASSTYPE_TI_TEMPLATE (type) == template)
- {
- if (rval == NULL_TREE || rval == type)
- return type;
- else
- return error_mark_node;
- }
-
- binfos = BINFO_BASETYPES (binfo);
- n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;
-
- /* Process base types. */
- for (i = 0; i < n_baselinks; i++)
- {
- tree base_binfo = TREE_VEC_ELT (binfos, i);
-
- /* Find any specific instance of a virtual base, when searching with
- a binfo... */
- if (BINFO_MARKED (base_binfo) == 0)
+ /* Make sure we don't already have this conversion. */
+ if (! IDENTIFIER_MARKED (name))
{
- int this_virtual = via_virtual || TREE_VIA_VIRTUAL (base_binfo);
-
- /* When searching for a non-virtual, we cannot mark
- virtually found binfos. */
- if (! this_virtual)
- SET_BINFO_MARKED (base_binfo);
-
- rval = get_template_base_recursive
- (base_binfo, rval, template, this_virtual);
- if (rval == error_mark_node)
- return rval;
+ *conversions = scratch_tree_cons (binfo, tmp, *conversions);
+ IDENTIFIER_MARKED (name) = 1;
}
}
-
- return rval;
+ return NULL_TREE;
}
-/* Given a class template TEMPLATE and a class type or binfo node BINFO,
- find the unique base type in BINFO that is an instance of TEMPLATE.
- If there are more than one, return error_mark_node. Used by unify. */
-
tree
-get_template_base (template, binfo)
- register tree template, binfo;
+lookup_conversions (type)
+ tree type;
{
- tree type = NULL_TREE, rval;
-
- if (TREE_CODE (binfo) == TREE_VEC)
- type = BINFO_TYPE (binfo);
- else if (IS_AGGR_TYPE_CODE (TREE_CODE (binfo)))
- {
- type = complete_type (binfo);
- binfo = TYPE_BINFO (type);
- }
- else
- my_friendly_abort (92);
+ tree t;
+ tree conversions = NULL_TREE;
- if (CLASSTYPE_TEMPLATE_INFO (type)
- && CLASSTYPE_TI_TEMPLATE (type) == template)
- return type;
+ if (TYPE_SIZE (type))
+ bfs_walk (TYPE_BINFO (type), add_conversions, 0, &conversions);
- rval = get_template_base_recursive (binfo, NULL_TREE, template, 0);
- dfs_walk (binfo, dfs_unmark, markedp);
+ for (t = conversions; t; t = TREE_CHAIN (t))
+ IDENTIFIER_MARKED (DECL_NAME (OVL_CURRENT (TREE_VALUE (t)))) = 0;
- return rval;
+ return conversions;
}
+struct overlap_info
+{
+ tree compare_type;
+ int found_overlap;
+};
+
/* Check whether the empty class indicated by EMPTY_BINFO is also present
at offset 0 in COMPARE_TYPE, and set found_overlap if so. */
-static tree compare_type;
-static int found_overlap;
-static void
-dfs_check_overlap (empty_binfo)
+static tree
+dfs_check_overlap (empty_binfo, data)
tree empty_binfo;
+ void *data;
{
+ struct overlap_info *oi = (struct overlap_info *) data;
tree binfo;
- for (binfo = TYPE_BINFO (compare_type); ; binfo = BINFO_BASETYPE (binfo, 0))
+ for (binfo = TYPE_BINFO (oi->compare_type);
+ ;
+ binfo = BINFO_BASETYPE (binfo, 0))
{
if (BINFO_TYPE (binfo) == BINFO_TYPE (empty_binfo))
{
- found_overlap = 1;
+ oi->found_overlap = 1;
break;
}
else if (BINFO_BASETYPES (binfo) == NULL_TREE)
break;
}
+
+ return NULL_TREE;
}
/* Trivial function to stop base traversal when we find something. */
-static int
-dfs_no_overlap_yet (t)
- tree t ATTRIBUTE_UNUSED;
+static tree
+dfs_no_overlap_yet (binfo, data)
+ tree binfo;
+ void *data;
{
- return found_overlap == 0;
+ struct overlap_info *oi = (struct overlap_info *) data;
+ return !oi->found_overlap ? binfo : NULL_TREE;
}
/* Returns nonzero if EMPTY_TYPE or any of its bases can also be found at
@@ -3422,34 +3448,63 @@ int
types_overlap_p (empty_type, next_type)
tree empty_type, next_type;
{
+ struct overlap_info oi;
+
if (! IS_AGGR_TYPE (next_type))
return 0;
- compare_type = next_type;
- found_overlap = 0;
- dfs_walk (TYPE_BINFO (empty_type), dfs_check_overlap, dfs_no_overlap_yet);
- return found_overlap;
+ oi.compare_type = next_type;
+ oi.found_overlap = 0;
+ dfs_walk (TYPE_BINFO (empty_type), dfs_check_overlap,
+ dfs_no_overlap_yet, &oi);
+ return oi.found_overlap;
}
-/* Passed to dfs_search by binfo_for_vtable; determine if bvtable comes
- from BINFO. */
+struct bfv_info {
+ tree vbases;
+ tree var;
+};
-static tree bvtable;
static tree
-dfs_bfv_helper (binfo)
+dfs_bfv_queue_p (binfo, data)
tree binfo;
+ void *data;
{
- if (BINFO_VTABLE (binfo) == bvtable)
+ struct bfv_info *bfvi = (struct bfv_info *) data;
+
+ /* Use the real virtual base class objects, not the placeholders in
+ the usual hierarchy. */
+ if (TREE_VIA_VIRTUAL (binfo))
+ return binfo_member (BINFO_TYPE (binfo), bfvi->vbases);
+
+ return binfo;
+}
+
+/* Passed to dfs_walk_real by binfo_for_vtable; determine if bvtable
+ comes from BINFO. */
+
+static tree
+dfs_bfv_helper (binfo, data)
+ tree binfo;
+ void *data;
+{
+ struct bfv_info *bfvi = (struct bfv_info *) data;
+
+ if (BINFO_VTABLE (binfo) == bfvi->var)
return binfo;
return NULL_TREE;
}
-/* Given a vtable VARS, determine which binfo it comes from. */
+/* Given a vtable VAR, determine which binfo it comes from. */
tree
-binfo_for_vtable (vars)
- tree vars;
+binfo_for_vtable (var)
+ tree var;
{
- bvtable = vars;
- return dfs_search (TYPE_BINFO (DECL_CONTEXT (vars)), dfs_bfv_helper,
- DECL_CONTEXT (vars));
+ tree type;
+ struct bfv_info bfvi;
+
+ type = DECL_CONTEXT (var);
+ bfvi.vbases = CLASSTYPE_VBASECLASSES (type);
+ return dfs_walk_real (TYPE_BINFO (type),
+ 0, dfs_bfv_helper, dfs_bfv_queue_p, &bfvi);
}
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 9579d44d96b..0e028d2bdb7 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -3,7 +3,7 @@
building RTL. These routines are used both during actual parsing
and during the instantiation of template functions.
- Copyright (C) 1998 Free Software Foundation, Inc.
+ Copyright (C) 1998, 1999 Free Software Foundation, Inc.
Written by Mark Mitchell (mmitchell@usa.net) based on code found
formerly in parse.y and pt.c.
@@ -490,12 +490,20 @@ finish_switch_cond (cond)
r = build_min_nt (SWITCH_STMT, cond, NULL_TREE);
add_tree (r);
}
- else
+ else if (cond != error_mark_node)
{
emit_line_note (input_filename, lineno);
c_expand_start_case (cond);
r = NULL_TREE;
}
+ else
+ {
+ /* The code is in error, but we don't want expand_end_case to
+ crash. */
+ c_expand_start_case (boolean_false_node);
+ r = NULL_TREE;
+ }
+
push_switch ();
/* Don't let the tree nodes for COND be discarded by
@@ -730,19 +738,31 @@ finish_asm_stmt (cv_qualifier, string, output_operands,
else
{
emit_line_note (input_filename, lineno);
-
- if (cv_qualifier != NULL_TREE
- && cv_qualifier != ridpointers[(int) RID_VOLATILE])
- cp_warning ("%s qualifier ignored on asm",
- IDENTIFIER_POINTER (cv_qualifier));
+ if (output_operands != NULL_TREE || input_operands != NULL_TREE
+ || clobbers != NULL_TREE)
+ {
+ if (cv_qualifier != NULL_TREE
+ && cv_qualifier != ridpointers[(int) RID_VOLATILE])
+ cp_warning ("%s qualifier ignored on asm",
+ IDENTIFIER_POINTER (cv_qualifier));
+
+ c_expand_asm_operands (string, output_operands,
+ input_operands,
+ clobbers,
+ cv_qualifier
+ == ridpointers[(int) RID_VOLATILE],
+ input_filename, lineno);
+ }
+ else
+ {
+ /* Don't warn about redundant specification of 'volatile' here. */
+ if (cv_qualifier != NULL_TREE
+ && cv_qualifier != ridpointers[(int) RID_VOLATILE])
+ cp_warning ("%s qualifier ignored on asm",
+ IDENTIFIER_POINTER (cv_qualifier));
+ expand_asm (string);
+ }
- c_expand_asm_operands (string, output_operands,
- input_operands,
- clobbers,
- cv_qualifier
- == ridpointers[(int) RID_VOLATILE],
- input_filename, lineno);
-
finish_stmt ();
}
}
@@ -797,8 +817,8 @@ finish_stmt_expr (rtl_expr, expr)
{
/* Make a BIND_EXPR for the BLOCK already made. */
if (processing_template_decl)
- result = build (BIND_EXPR, NULL_TREE,
- NULL_TREE, last_tree, expr);
+ result = build_min_nt (BIND_EXPR, NULL_TREE, last_tree,
+ NULL_TREE);
else
result = build (BIND_EXPR, TREE_TYPE (rtl_expr),
NULL_TREE, rtl_expr, expr);
@@ -843,7 +863,8 @@ finish_call_expr (fn, args, koenig)
result = build_x_function_call (fn, args, current_class_ref);
if (TREE_CODE (result) == CALL_EXPR
- && TREE_TYPE (result) != void_type_node)
+ && (! TREE_TYPE (result)
+ || TREE_CODE (TREE_TYPE (result)) != VOID_TYPE))
result = require_complete_type (result);
return result;
@@ -1212,19 +1233,68 @@ begin_class_definition (t)
implicit typename, a TYPENAME_TYPE with a type. */
if (TREE_CODE (t) == TYPENAME_TYPE)
t = TREE_TYPE (t);
+
+ /* If we generated a partial instantiation of this type, but now
+ we're seeing a real definition, we're actually looking at a
+ partial specialization. Consider:
+
+ template <class T, class U>
+ struct Y {};
+
+ template <class T>
+ struct X {};
+
+ template <class T, class U>
+ void f()
+ {
+ typename X<Y<T, U> >::A a;
+ }
+
+ template <class T, class U>
+ struct X<Y<T, U> >
+ {
+ };
+
+ We have to undo the effects of the previous partial
+ instantiation. */
+ if (PARTIAL_INSTANTIATION_P (t))
+ {
+ if (!pedantic)
+ {
+ /* Unfortunately, when we're not in pedantic mode, we
+ attempt to actually fill in some of the fields of the
+ partial instantiation, in order to support the implicit
+ typename extension. Clear those fields now, in
+ preparation for the definition here. The fields cleared
+ here must match those set in instantiate_class_template.
+ Look for a comment mentioning begin_class_definition
+ there. */
+ TYPE_BINFO_BASETYPES (t) = NULL_TREE;
+ TYPE_FIELDS (t) = NULL_TREE;
+ TYPE_METHODS (t) = NULL_TREE;
+ CLASSTYPE_TAGS (t) = NULL_TREE;
+ TYPE_SIZE (t) = NULL_TREE;
+ }
- if (TYPE_SIZE (t))
+ /* This isn't a partial instantiation any more. */
+ PARTIAL_INSTANTIATION_P (t) = 0;
+ }
+ /* If this type was already complete, and we see another definition,
+ that's an error. */
+ else if (TYPE_SIZE (t))
duplicate_tag_error (t);
- if (TYPE_SIZE (t) || TYPE_BEING_DEFINED (t))
+
+ if (TYPE_BEING_DEFINED (t))
{
t = make_lang_type (TREE_CODE (t));
pushtag (TYPE_IDENTIFIER (t), t, 0);
}
- if (processing_template_decl && TYPE_CONTEXT (t)
- && TREE_CODE (TYPE_CONTEXT (t)) != NAMESPACE_DECL
+ maybe_process_partial_specialization (t);
+ if (processing_template_decl
+ && ! CLASSTYPE_TEMPLATE_SPECIALIZATION (t)
+ && TYPE_CONTEXT (t) && TYPE_P (TYPE_CONTEXT (t))
&& ! current_class_type)
push_template_decl (TYPE_STUB_DECL (t));
- maybe_process_partial_specialization (t);
pushclass (t, 0);
TYPE_BEING_DEFINED (t) = 1;
/* Reset the interface data, at the earliest possible
@@ -1265,6 +1335,9 @@ begin_class_definition (t)
that we can get it back later. */
begin_tree ();
+ /* Make a declaration for this class in its own scope. */
+ build_self_reference ();
+
return t;
}
@@ -1303,11 +1376,6 @@ finish_member_declaration (decl)
finish_struct. Presumably it is already set as the function is
parsed. Perhaps DECL_CLASS_CONTEXT is already set, too? */
DECL_CLASS_CONTEXT (decl) = current_class_type;
- else if (TREE_CODE (decl) == TYPE_DECL)
- /* Historically, DECL_CONTEXT was not set for a TYPE_DECL in
- finish_struct, so we do not do it here either. Perhaps we
- should, though. */
- ;
else
DECL_CONTEXT (decl) = current_class_type;
@@ -1594,3 +1662,24 @@ check_multiple_declarators ()
cp_error ("multiple declarators in template declaration");
}
+tree
+finish_typeof (expr)
+ tree expr;
+{
+ if (processing_template_decl)
+ {
+ tree t;
+
+ push_obstacks_nochange ();
+ end_temporary_allocation ();
+
+ t = make_lang_type (TYPEOF_TYPE);
+ TYPE_FIELDS (t) = expr;
+
+ pop_obstacks ();
+
+ return t;
+ }
+
+ return TREE_TYPE (expr);
+}
diff --git a/gcc/cp/sig.c b/gcc/cp/sig.c
index 6f8d14dd19d..f170df52a60 100644
--- a/gcc/cp/sig.c
+++ b/gcc/cp/sig.c
@@ -1,5 +1,5 @@
/* Functions dealing with signatures and signature pointers/references.
- Copyright (C) 1992, 93, 94, 95, 1996 Free Software Foundation, Inc.
+ Copyright (C) 1992, 93-97, 1998 Free Software Foundation, Inc.
Contributed by Gerald Baumgartner (gb@cs.purdue.edu)
This file is part of GNU CC.
@@ -33,18 +33,16 @@ extern struct obstack *current_obstack;
extern struct obstack permanent_obstack;
extern struct obstack *saveable_obstack;
-extern void compiler_error ();
-
static tree save_this PROTO((tree));
static tree build_sptr_ref PROTO((tree));
static tree build_member_function_pointer PROTO((tree));
static void undo_casts PROTO((tree));
static tree build_signature_pointer_or_reference_name
- PROTO((tree, int, int, int));
+ PROTO((tree, int, int));
static void build_signature_pointer_or_reference_decl
PROTO((tree, tree));
static tree build_signature_pointer_or_reference_type
- PROTO((tree, int, int, int));
+ PROTO((tree, int, int));
static tree get_sigtable_name PROTO((tree, tree));
static tree build_signature_table_constructor PROTO((tree, tree));
static int match_method_types PROTO((tree, tree));
@@ -58,25 +56,31 @@ static int global_sigtable_name_counter;
can use it's name in function name mangling. */
static tree
-build_signature_pointer_or_reference_name (to_type, constp, volatilep, refp)
+build_signature_pointer_or_reference_name (to_type, type_quals, refp)
tree to_type;
- int constp, volatilep, refp;
+ int type_quals;
+ int refp;
{
- char * sig_name = TYPE_NAME_STRING (to_type);
- int name_len = TYPE_NAME_LENGTH (to_type) + constp + volatilep;
+ const char * sig_name = TYPE_NAME_STRING (to_type);
+ int name_len = TYPE_NAME_LENGTH (to_type) + 3 /* Enough room for
+ C,V,R. */;
char * name;
+ const char *const_rep = (type_quals & TYPE_QUAL_CONST) ? "C" : "";
+ const char *restrict_rep = (type_quals & TYPE_QUAL_RESTRICT) ? "R" : "";
+ const char *volatile_rep = (type_quals & TYPE_QUAL_VOLATILE) ? "C" : "";
+
if (refp)
{
name = (char *) alloca (name_len + sizeof (SIGNATURE_REFERENCE_NAME) +2);
sprintf (name, SIGNATURE_REFERENCE_NAME_FORMAT,
- constp ? "C" : "", volatilep ? "V": "", sig_name);
+ const_rep, volatile_rep, restrict_rep, sig_name);
}
else
{
name = (char *) alloca (name_len + sizeof (SIGNATURE_POINTER_NAME) + 2);
sprintf (name, SIGNATURE_POINTER_NAME_FORMAT,
- constp ? "C" : "", volatilep ? "V": "", sig_name);
+ const_rep, volatile_rep, restrict_rep, sig_name);
}
return get_identifier (name);
}
@@ -98,21 +102,22 @@ build_signature_pointer_or_reference_decl (type, name)
TREE_CHAIN (type) = decl;
}
-/* Construct, lay out and return the type of pointers or references
- to signature TO_TYPE. If such a type has already been constructed,
- reuse it. If CONSTP or VOLATILEP is specified, make the `optr' const
- or volatile, respectively. If we are constructing a const/volatile
- type variant and the main type variant doesn't exist yet, it is built
- as well. If REFP is 1, we construct a signature reference, otherwise
- a signature pointer is constructed.
+/* Construct, lay out and return the type of pointers or references to
+ signature TO_TYPE. If such a type has already been constructed,
+ reuse it. If TYPE_QUALS are specified, qualify the `optr'. If we
+ are constructing a const/volatile type variant and the main type
+ variant doesn't exist yet, it is built as well. If REFP is 1, we
+ construct a signature reference, otherwise a signature pointer is
+ constructed.
This function is a subroutine of `build_signature_pointer_type' and
`build_signature_reference_type'. */
static tree
-build_signature_pointer_or_reference_type (to_type, constp, volatilep, refp)
+build_signature_pointer_or_reference_type (to_type, type_quals, refp)
tree to_type;
- int constp, volatilep, refp;
+ int type_quals;
+ int refp;
{
register tree t, m;
register struct obstack *ambient_obstack = current_obstack;
@@ -121,13 +126,11 @@ build_signature_pointer_or_reference_type (to_type, constp, volatilep, refp)
m = refp ? SIGNATURE_REFERENCE_TO (to_type) : SIGNATURE_POINTER_TO (to_type);
/* If we don't have the main variant yet, construct it. */
- if (m == NULL_TREE
- && (constp || volatilep))
- m = build_signature_pointer_or_reference_type (to_type, 0, 0, refp);
+ if (m == NULL_TREE && type_quals != TYPE_UNQUALIFIED)
+ m = build_signature_pointer_or_reference_type (to_type,
+ TYPE_UNQUALIFIED, refp);
/* Treat any nonzero argument as 1. */
- constp = !!constp;
- volatilep = !!volatilep;
refp = !!refp;
/* If not generating auxiliary info, search the chain of variants to see
@@ -141,8 +144,8 @@ build_signature_pointer_or_reference_type (to_type, constp, volatilep, refp)
if (m && !flag_gen_aux_info)
for (t = m; t; t = TYPE_NEXT_VARIANT (t))
- if (constp == TYPE_READONLY (TREE_TYPE (TREE_TYPE (TYPE_FIELDS (t))))
- && volatilep == TYPE_VOLATILE (TREE_TYPE (TREE_TYPE (TYPE_FIELDS (t)))))
+ if (type_quals == CP_TYPE_QUALS (TREE_TYPE (TREE_TYPE
+ (TYPE_FIELDS (t)))))
return t;
/* We need a new one. If TO_TYPE is permanent, make this permanent too. */
@@ -170,7 +173,7 @@ build_signature_pointer_or_reference_type (to_type, constp, volatilep, refp)
t = make_lang_type (RECORD_TYPE);
{
- tree obj_type = build_type_variant (void_type_node, constp, volatilep);
+ tree obj_type = build_qualified_type (void_type_node, type_quals);
tree optr_type = build_pointer_type (obj_type);
tree optr, sptr;
@@ -185,7 +188,8 @@ build_signature_pointer_or_reference_type (to_type, constp, volatilep, refp)
sptr = TREE_CHAIN (TYPE_FIELDS (m));
else
{
- tree sig_tbl_type = cp_build_type_variant (to_type, 1, 0);
+ tree sig_tbl_type =
+ cp_build_qualified_type (to_type, TYPE_QUAL_CONST);
sptr = build_lang_field_decl (FIELD_DECL,
get_identifier (SIGNATURE_SPTR_NAME),
@@ -203,12 +207,13 @@ build_signature_pointer_or_reference_type (to_type, constp, volatilep, refp)
TYPE_ALIGN (optr_type));
/* A signature pointer/reference type isn't a `real' class type. */
- IS_AGGR_TYPE (t) = 0;
+ SET_IS_AGGR_TYPE (t, 0);
}
{
- tree name = build_signature_pointer_or_reference_name (to_type, constp,
- volatilep, refp);
+ tree name = build_signature_pointer_or_reference_name (to_type,
+ type_quals,
+ refp);
/* Build a DECL node for this type, so the debugger has access to it. */
build_signature_pointer_or_reference_decl (t, name);
@@ -255,8 +260,7 @@ build_signature_pointer_type (to_type)
{
return
build_signature_pointer_or_reference_type (TYPE_MAIN_VARIANT (to_type),
- TYPE_READONLY (to_type),
- TYPE_VOLATILE (to_type), 0);
+ CP_TYPE_QUALS (to_type), 0);
}
/* Construct, lay out and return the type of pointers to signature TO_TYPE. */
@@ -267,8 +271,7 @@ build_signature_reference_type (to_type)
{
return
build_signature_pointer_or_reference_type (TYPE_MAIN_VARIANT (to_type),
- TYPE_READONLY (to_type),
- TYPE_VOLATILE (to_type), 1);
+ CP_TYPE_QUALS (to_type), 1);
}
/* Return the name of the signature table (as an IDENTIFIER_NODE)
@@ -283,8 +286,8 @@ get_sigtable_name (sig_type, rhs_type)
char *buf = (char *) alloca (sizeof (SIGTABLE_NAME_FORMAT_LONG)
+ IDENTIFIER_LENGTH (sig_type_id)
+ IDENTIFIER_LENGTH (rhs_type_id) + 20);
- char *sig_ptr = IDENTIFIER_POINTER (sig_type_id);
- char *rhs_ptr = IDENTIFIER_POINTER (rhs_type_id);
+ const char *sig_ptr = IDENTIFIER_POINTER (sig_type_id);
+ const char *rhs_ptr = IDENTIFIER_POINTER (rhs_type_id);
int i, j;
for (i = 0; sig_ptr[i] == OPERATOR_TYPENAME_FORMAT[i]; i++)
@@ -311,7 +314,7 @@ static tree
build_member_function_pointer (member)
tree member;
{
- char *namstr = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (member));
+ const char *namstr = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (member));
int namlen = IDENTIFIER_LENGTH (DECL_ASSEMBLER_NAME (member));
char *name;
tree entry;
@@ -403,7 +406,7 @@ match_method_types (sig_mtype, class_mtype)
tree class_arg_types = TYPE_ARG_TYPES (class_mtype);
/* The return types have to be the same. */
- if (! comptypes (sig_return_type, class_return_type, 1))
+ if (!same_type_p (sig_return_type, class_return_type))
return 0;
/* Compare the first argument `this.' */
@@ -420,8 +423,7 @@ match_method_types (sig_mtype, class_mtype)
/* If a signature method's `this' is const or volatile, so has to be
the corresponding class method's `this.' */
- if ((TYPE_READONLY (sig_this) && ! TYPE_READONLY (class_this))
- || (TYPE_VOLATILE (sig_this) && ! TYPE_VOLATILE (class_this)))
+ if (!at_least_as_qualified_p (class_this, sig_this))
return 0;
}
@@ -429,7 +431,7 @@ match_method_types (sig_mtype, class_mtype)
class_arg_types = TREE_CHAIN (class_arg_types);
/* The number of arguments and the argument types have to be the same. */
- return compparms (sig_arg_types, class_arg_types, 3);
+ return compparms (sig_arg_types, class_arg_types);
}
/* Undo casts of opaque type variables to the RHS types. */
@@ -544,12 +546,10 @@ build_signature_table_constructor (sig_ty, rhs)
break;
if (rhs_methods == NULL_TREE
- || (compute_access (basetypes, rhs_method)
- != access_public_node))
+ || !accessible_p (basetypes, rhs_method))
{
- error ("class `%s' does not contain a method conforming to `%s'",
- TYPE_NAME_STRING (rhstype),
- fndecl_as_string (sig_method, 1));
+ cp_error ("`%T' does not contain a method conforming to `%#D'",
+ rhstype, sig_method);
undo_casts (sig_ty);
return error_mark_node;
}
@@ -884,7 +884,7 @@ build_signature_pointer_constructor (lhs, rhs)
}
else
{
- if (TREE_READONLY (lhs) || TYPE_READONLY (lhstype))
+ if (TREE_READONLY (lhs) || CP_TYPE_CONST_P (lhstype))
readonly_error (lhs, "assignment", 0);
optr_expr = build_modify_expr (build_optr_ref (lhs), NOP_EXPR,
@@ -978,9 +978,8 @@ build_signature_method_call (function, parms)
tree old_this = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (TREE_TYPE (pfn))));
TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (TREE_TYPE (pfn))))
- = build_type_variant (build_pointer_type (basetype),
- TYPE_READONLY (old_this),
- TYPE_VOLATILE (old_this));
+ = build_qualified_type (build_pointer_type (basetype),
+ TYPE_QUALS (old_this));
direct_call = build_function_call (pfn, new_parms);
diff --git a/gcc/cp/spew.c b/gcc/cp/spew.c
index ff93ac7e120..a573cbac2b0 100644
--- a/gcc/cp/spew.c
+++ b/gcc/cp/spew.c
@@ -1,5 +1,5 @@
/* Type Analyzer for GNU C++.
- Copyright (C) 1987, 89, 92, 93, 94, 1995 Free Software Foundation, Inc.
+ Copyright (C) 1987, 89, 92-97, 1998 Free Software Foundation, Inc.
Hacked... nay, bludgeoned... by Mark Eichin (eichin@cygnus.com)
This file is part of GNU CC.
@@ -401,6 +401,11 @@ yylex ()
if (tmp_token.yychar != '~')
got_object = NULL_TREE;
+ /* Clear looking_for_typename if we got 'enum { ... };'. */
+ if (tmp_token.yychar == '{' || tmp_token.yychar == ':'
+ || tmp_token.yychar == ';')
+ looking_for_typename = 0;
+
yylval = tmp_token.yylval;
yychar = tmp_token.yychar;
end_of_file = tmp_token.end_of_file;
diff --git a/gcc/cp/tinfo.cc b/gcc/cp/tinfo.cc
index 4b68fd1b3fb..0d782ea375a 100644
--- a/gcc/cp/tinfo.cc
+++ b/gcc/cp/tinfo.cc
@@ -1,5 +1,5 @@
// Methods for type_info for -*- C++ -*- Run Time Type Identification.
-// Copyright (C) 1994, 1996 Free Software Foundation
+// Copyright (C) 1994, 1996, 1998 Free Software Foundation
// This file is part of GNU CC.
@@ -25,6 +25,8 @@
// This exception does not however invalidate any other reasons why
// the executable file might be covered by the GNU General Public License.
+#pragma implementation "typeinfo"
+
#include <stddef.h>
#include "tinfo.h"
#include "new" // for placement new
@@ -37,6 +39,13 @@ std::type_info::
~type_info ()
{ }
+// We can't rely on common symbols being shared between shared objects.
+bool type_info::
+operator== (const type_info& arg) const
+{
+ return (&arg == this) || (strcmp (name (), arg.name ()) == 0);
+}
+
extern "C" void
__rtti_class (void *addr, const char *name,
const __class_type_info::base_info *bl, size_t bn)
diff --git a/gcc/cp/tinfo.h b/gcc/cp/tinfo.h
index 3cfee04cec0..2601ce25eda 100644
--- a/gcc/cp/tinfo.h
+++ b/gcc/cp/tinfo.h
@@ -1,5 +1,5 @@
// RTTI support internals for -*- C++ -*-
-// Copyright (C) 1994, 1995, 1996 Free Software Foundation
+// Copyright (C) 1994, 1995, 1996, 1998 Free Software Foundation
#include "typeinfo"
diff --git a/gcc/cp/tinfo2.cc b/gcc/cp/tinfo2.cc
index b797cc3e1db..b101db3c054 100644
--- a/gcc/cp/tinfo2.cc
+++ b/gcc/cp/tinfo2.cc
@@ -1,5 +1,5 @@
// Methods for type_info for -*- C++ -*- Run Time Type Identification.
-// Copyright (C) 1994, 1996 Free Software Foundation
+// Copyright (C) 1994, 96-97, 1998 Free Software Foundation
// This file is part of GNU CC.
@@ -30,39 +30,13 @@
#include "new" // for placement new
using std::type_info;
-// service function for comparing types by name.
-
-static inline int
-fast_compare (const char *n1, const char *n2) {
- int c;
- if (n1 == n2) return 0;
- if (n1 == 0) return *n2;
- else if (n2 == 0) return *n1;
-
- c = (int)*n1++ - (int)*n2++;
- return c == 0 ? strcmp (n1, n2) : c;
-};
bool
type_info::before (const type_info &arg) const
{
- return fast_compare (name (), arg.name ()) < 0;
-}
-
-#ifdef _WIN32
-bool type_info::
-operator== (const type_info& arg) const
-{
- return fast_compare (name (), arg.name ()) == 0;
+ return strcmp (name (), arg.name ()) < 0;
}
-bool type_info::
-operator!= (const type_info& arg) const
-{
- return fast_compare (name (), arg.name ()) != 0;
-}
-#endif
-
// type info for pointer type.
struct __pointer_type_info : public type_info {
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index 1f55e56b1d8..fc8d5844582 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -1,5 +1,5 @@
/* Language-dependent node constructors for parse phase of GNU compiler.
- Copyright (C) 1987, 88, 92, 93, 94, 95, 1996 Free Software Foundation, Inc.
+ Copyright (C) 1987, 88, 92-98, 1999 Free Software Foundation, Inc.
Hacked by Michael Tiemann (tiemann@cygnus.com)
This file is part of GNU CC.
@@ -28,8 +28,6 @@ Boston, MA 02111-1307, USA. */
#include "rtl.h"
#include "toplev.h"
-extern void compiler_error ();
-
static tree get_identifier_list PROTO((tree));
static tree bot_manip PROTO((tree));
static tree perm_manip PROTO((tree));
@@ -41,6 +39,9 @@ static tree list_hash_lookup PROTO((int, int, int, int, tree, tree,
static void propagate_binfo_offsets PROTO((tree, tree));
static int avoid_overlap PROTO((tree, tree));
static int lvalue_p_1 PROTO((tree, int));
+static int equal_functions PROTO((tree, tree));
+static tree no_linkage_helper PROTO((tree));
+static tree build_srcloc PROTO((char *, int));
#define CEIL(x,y) (((x) + (y) - 1) / (y))
@@ -87,8 +88,7 @@ lvalue_p_1 (ref, treat_class_rvalues_as_lvalues)
case ARRAY_REF:
case PARM_DECL:
case RESULT_DECL:
- if (TREE_CODE (TREE_TYPE (ref)) != FUNCTION_TYPE
- && TREE_CODE (TREE_TYPE (ref)) != METHOD_TYPE)
+ if (TREE_CODE (TREE_TYPE (ref)) != METHOD_TYPE)
return 1;
break;
@@ -171,7 +171,7 @@ lvalue_p (ref)
int
lvalue_or_else (ref, string)
tree ref;
- char *string;
+ const char *string;
{
int win = lvalue_p (ref);
if (! win)
@@ -417,7 +417,8 @@ build_cplus_array_type_1 (elt_type, index_type)
saveable_obstack = &permanent_obstack;
}
- if (processing_template_decl
+ if (processing_template_decl
+ || uses_template_parms (elt_type)
|| uses_template_parms (index_type))
{
t = make_node (ARRAY_TYPE);
@@ -442,14 +443,14 @@ build_cplus_array_type (elt_type, index_type)
tree index_type;
{
tree t;
- int constp = TYPE_READONLY (elt_type);
- int volatilep = TYPE_VOLATILE (elt_type);
+ int type_quals = CP_TYPE_QUALS (elt_type);
+
elt_type = TYPE_MAIN_VARIANT (elt_type);
t = build_cplus_array_type_1 (elt_type, index_type);
- if (constp || volatilep)
- t = cp_build_type_variant (t, constp, volatilep);
+ if (type_quals != TYPE_UNQUALIFIED)
+ t = cp_build_qualified_type (t, type_quals);
return t;
}
@@ -458,21 +459,32 @@ build_cplus_array_type (elt_type, index_type)
down to the element type of an array. */
tree
-cp_build_type_variant (type, constp, volatilep)
+cp_build_qualified_type (type, type_quals)
tree type;
- int constp, volatilep;
+ int type_quals;
{
if (type == error_mark_node)
return type;
+ /* A restrict-qualified pointer type must be a pointer (or reference)
+ to object or incomplete type. */
+ if ((type_quals & TYPE_QUAL_RESTRICT)
+ && (!POINTER_TYPE_P (type)
+ || TYPE_PTRMEM_P (type)
+ || TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE))
+ {
+ cp_error ("`%T' cannot be `restrict'-qualified", type);
+ type_quals &= ~TYPE_QUAL_RESTRICT;
+ }
+
if (TREE_CODE (type) == ARRAY_TYPE)
{
tree real_main_variant = TYPE_MAIN_VARIANT (type);
push_obstacks (TYPE_OBSTACK (real_main_variant),
TYPE_OBSTACK (real_main_variant));
- type = build_cplus_array_type_1 (cp_build_type_variant
- (TREE_TYPE (type), constp, volatilep),
+ type = build_cplus_array_type_1 (cp_build_qualified_type
+ (TREE_TYPE (type), type_quals),
TYPE_DOMAIN (type));
/* TYPE must be on same obstack as REAL_MAIN_VARIANT. If not,
@@ -489,7 +501,7 @@ cp_build_type_variant (type, constp, volatilep)
pop_obstacks ();
return type;
}
- return build_type_variant (type, constp, volatilep);
+ return build_qualified_type (type, type_quals);
}
/* Returns the canonical version of TYPE. In other words, if TYPE is
@@ -501,18 +513,7 @@ tree
canonical_type_variant (t)
tree t;
{
- int constp, volatilep;
- if (TREE_CODE (t) == ARRAY_TYPE)
- {
- constp = TYPE_READONLY (TREE_TYPE (t));
- volatilep = TYPE_VOLATILE (TREE_TYPE (t));
- }
- else
- {
- constp = TYPE_READONLY (t);
- volatilep = TYPE_VOLATILE (t);
- }
- return cp_build_type_variant (TYPE_MAIN_VARIANT (t), constp, volatilep);
+ return cp_build_qualified_type (TYPE_MAIN_VARIANT (t), CP_TYPE_QUALS (t));
}
/* Add OFFSET to all base types of T.
@@ -639,7 +640,7 @@ layout_basetypes (rec, max)
TREE_VALUE slot holds the virtual baseclass type. Note that
get_vbase_types makes copies of the virtual base BINFOs, so that
the vbase_types are unshared. */
- CLASSTYPE_VBASECLASSES (rec) = vbase_types = get_vbase_types (rec);
+ vbase_types = CLASSTYPE_VBASECLASSES (rec);
my_friendly_assert (TREE_CODE (TYPE_SIZE (rec)) == INTEGER_CST, 19970302);
const_size = TREE_INT_CST_LOW (TYPE_SIZE (rec));
@@ -806,7 +807,7 @@ build_base_fields (rec)
base_align = MAX (base_align, DECL_ALIGN (decl));
DECL_SIZE (decl)
= size_int (MAX (TREE_INT_CST_LOW (DECL_SIZE (decl)),
- base_align));
+ (int) base_align));
}
else if (DECL_SIZE (decl) == integer_zero_node)
saw_empty = 1;
@@ -880,7 +881,7 @@ build_vbase_pointer_fields (rec)
if (TREE_VIA_VIRTUAL (base_binfo))
{
int j;
- char *name;
+ const char *name;
/* The offset for a virtual base class is only used in computing
virtual function tables and for initializing virtual base
@@ -1169,7 +1170,7 @@ make_binfo (offset, binfo, vtable, virtuals)
else
{
type = binfo;
- binfo = TYPE_BINFO (binfo);
+ binfo = CLASS_TYPE_P (type) ? TYPE_BINFO (binfo) : NULL_TREE;
}
TREE_TYPE (new_binfo) = TYPE_MAIN_VARIANT (type);
@@ -1295,9 +1296,15 @@ is_overloaded_fn (x)
tree x;
{
/* XXX A baselink is also considered an overloaded function.
- As is a placeholder from push_class_decls. */
+ As is a placeholder from push_class_decls.
+ As is an expression like X::f. */
if (TREE_CODE (x) == TREE_LIST)
{
+ if (TREE_PURPOSE (x) == error_mark_node)
+ {
+ x = TREE_VALUE (x);
+ my_friendly_assert (TREE_CODE (x) == TREE_LIST, 981121);
+ }
my_friendly_assert (TREE_CODE (TREE_PURPOSE (x)) == TREE_VEC
|| TREE_CODE (TREE_PURPOSE (x)) == IDENTIFIER_NODE,
388);
@@ -1333,6 +1340,17 @@ get_first_fn (from)
return OVL_CURRENT (from);
}
+/* Returns nonzero if T is a ->* or .* expression that refers to a
+ member function. */
+
+int
+bound_pmf_p (t)
+ tree t;
+{
+ return (TREE_CODE (t) == OFFSET_REF
+ && TYPE_PTRMEMFUNC_P (TREE_TYPE (TREE_OPERAND (t, 1))));
+}
+
/* Return a new OVL node, concatenating it with the old one. */
tree
@@ -1371,13 +1389,27 @@ build_overload (decl, chain)
tree decl;
tree chain;
{
- if (!chain)
+ if (! chain && TREE_CODE (decl) != TEMPLATE_DECL)
return decl;
- if (TREE_CODE (chain) != OVERLOAD)
+ if (chain && TREE_CODE (chain) != OVERLOAD)
chain = ovl_cons (chain, NULL_TREE);
return ovl_cons (decl, chain);
}
+/* Returns true iff functions are equivalent. Equivalent functions are
+ not identical only if one is a function-local extern function.
+ This assumes that function-locals don't have TREE_PERMANENT. */
+
+static int
+equal_functions (fn1, fn2)
+ tree fn1;
+ tree fn2;
+{
+ if (!TREE_PERMANENT (fn1) || !TREE_PERMANENT (fn2))
+ return decls_match (fn1, fn2);
+ return fn1 == fn2;
+}
+
/* True if fn is in ovl. */
int
@@ -1388,9 +1420,9 @@ ovl_member (fn, ovl)
if (ovl == NULL_TREE)
return 0;
if (TREE_CODE (ovl) != OVERLOAD)
- return decls_match (ovl, fn);
+ return equal_functions (ovl, fn);
for (; ovl; ovl = OVL_CHAIN (ovl))
- if (decls_match (OVL_FUNCTION (ovl), fn))
+ if (equal_functions (OVL_FUNCTION (ovl), fn))
return 1;
return 0;
}
@@ -1458,21 +1490,26 @@ build_exception_variant (type, raises)
tree raises;
{
tree v = TYPE_MAIN_VARIANT (type);
- int constp = TYPE_READONLY (type);
- int volatilep = TYPE_VOLATILE (type);
+ int type_quals = TYPE_QUALS (type);
for (; v; v = TYPE_NEXT_VARIANT (v))
{
- if (TYPE_READONLY (v) != constp
- || TYPE_VOLATILE (v) != volatilep)
+ tree t;
+ tree u;
+
+ if (TYPE_QUALS (v) != type_quals)
continue;
- /* @@ This should do set equality, not exact match. */
- if (simple_cst_list_equal (TYPE_RAISES_EXCEPTIONS (v), raises))
- /* List of exceptions raised matches previously found list.
+ for (t = TYPE_RAISES_EXCEPTIONS (v), u = raises;
+ t != NULL_TREE && u != NULL_TREE;
+ t = TREE_CHAIN (t), u = TREE_CHAIN (v))
+ if (((TREE_VALUE (t) != NULL_TREE)
+ != (TREE_VALUE (u) != NULL_TREE))
+ || !same_type_p (TREE_VALUE (t), TREE_VALUE (u)))
+ break;
- @@ Nice to free up storage used in consing up the
- @@ list of exceptions raised. */
+ if (!t && !u)
+ /* There's a memory leak here; RAISES is not freed. */
return v;
}
@@ -1480,12 +1517,7 @@ build_exception_variant (type, raises)
v = build_type_copy (type);
if (raises && ! TREE_PERMANENT (raises))
- {
- push_obstacks_nochange ();
- end_temporary_allocation ();
- raises = copy_list (raises);
- pop_obstacks ();
- }
+ raises = copy_to_permanent (raises);
TYPE_RAISES_EXCEPTIONS (v) = raises;
return v;
@@ -1499,23 +1531,33 @@ copy_template_template_parm (t)
tree t;
{
tree template = TYPE_NAME (t);
- tree t2 = make_lang_type (TEMPLATE_TEMPLATE_PARM);
+ tree t2;
+
+ /* Make sure these end up on the permanent_obstack. */
+ push_obstacks_nochange ();
+ end_temporary_allocation ();
+
+ t2 = make_lang_type (TEMPLATE_TEMPLATE_PARM);
template = copy_node (template);
copy_lang_decl (template);
+
+ pop_obstacks ();
+
TREE_TYPE (template) = t2;
TYPE_NAME (t2) = template;
TYPE_STUB_DECL (t2) = template;
/* No need to copy these */
TYPE_FIELDS (t2) = TYPE_FIELDS (t);
- CLASSTYPE_TEMPLATE_INFO (t2) = CLASSTYPE_TEMPLATE_INFO (t);
+ TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (t2)
+ = TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (t);
return t2;
}
/* Walk through the tree structure T, applying func. If func ever returns
non-null, return that value. */
-static tree
+tree
search_tree (t, func)
tree t;
tree (*func) PROTO((tree));
@@ -1688,6 +1730,7 @@ search_tree (t, func)
case TYPENAME_TYPE:
case UNION_TYPE:
case ENUMERAL_TYPE:
+ case TYPEOF_TYPE:
break;
case POINTER_TYPE:
@@ -1798,11 +1841,13 @@ mapcar (t, func)
void g() { const int i = 7; f<i>(7); }
however, we must actually return the constant initializer. */
- tmp = decl_constant_value (t);
- if (tmp != t)
- return mapcar (tmp, func);
- else
- return error_mark_node;
+ if (TREE_READONLY_DECL_P (t))
+ {
+ tmp = decl_constant_value (t);
+ if (tmp != t)
+ return mapcar (tmp, func);
+ }
+ return error_mark_node;
case PARM_DECL:
{
@@ -1936,36 +1981,37 @@ mapcar (t, func)
case COMPONENT_REF:
case CLEANUP_POINT_EXPR:
t = copy_node (t);
+ TREE_TYPE (t) = mapcar (TREE_TYPE (t), func);
TREE_OPERAND (t, 0) = mapcar (TREE_OPERAND (t, 0), func);
return t;
case POINTER_TYPE:
tmp = build_pointer_type (mapcar (TREE_TYPE (t), func));
- return cp_build_type_variant (tmp, TYPE_READONLY (t), TYPE_VOLATILE (t));
+ return cp_build_qualified_type (tmp, TYPE_QUALS (t));
case REFERENCE_TYPE:
tmp = build_reference_type (mapcar (TREE_TYPE (t), func));
- return cp_build_type_variant (tmp, TYPE_READONLY (t), TYPE_VOLATILE (t));
+ return cp_build_qualified_type (tmp, TYPE_QUALS (t));
case FUNCTION_TYPE:
tmp = build_function_type (mapcar (TREE_TYPE (t), func),
mapcar (TYPE_ARG_TYPES (t), func));
- return cp_build_type_variant (tmp, TYPE_READONLY (t), TYPE_VOLATILE (t));
+ return cp_build_qualified_type (tmp, TYPE_QUALS (t));
case ARRAY_TYPE:
tmp = build_cplus_array_type (mapcar (TREE_TYPE (t), func),
mapcar (TYPE_DOMAIN (t), func));
- return cp_build_type_variant (tmp, TYPE_READONLY (t), TYPE_VOLATILE (t));
+ return cp_build_qualified_type (tmp, CP_TYPE_QUALS (t));
case INTEGER_TYPE:
tmp = build_index_type (mapcar (TYPE_MAX_VALUE (t), func));
- return cp_build_type_variant (tmp, TYPE_READONLY (t), TYPE_VOLATILE (t));
+ return cp_build_qualified_type (tmp, TYPE_QUALS (t));
case OFFSET_TYPE:
tmp = build_offset_type (mapcar (TYPE_OFFSET_BASETYPE (t), func),
mapcar (TREE_TYPE (t), func));
- return cp_build_type_variant (tmp, TYPE_READONLY (t), TYPE_VOLATILE (t));
+ return cp_build_qualified_type (tmp, TYPE_QUALS (t));
case METHOD_TYPE:
tmp = build_cplus_method_type
(mapcar (TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (t))), func),
mapcar (TREE_TYPE (t), func),
mapcar (TREE_CHAIN (TYPE_ARG_TYPES (t)), func));
- return cp_build_type_variant (tmp, TYPE_READONLY (t), TYPE_VOLATILE (t));
+ return cp_build_qualified_type (tmp, TYPE_QUALS (t));
case COMPLEX_CST:
t = copy_node (t);
@@ -2086,17 +2132,10 @@ print_lang_statistics ()
void
__eprintf (string, expression, line, filename)
-#ifdef __STDC__
const char *string;
const char *expression;
unsigned line;
const char *filename;
-#else
- char *string;
- char *expression;
- unsigned line;
- char *filename;
-#endif
{
fprintf (stderr, string, expression, line, filename);
fflush (stderr);
@@ -2315,7 +2354,7 @@ vec_binfo_member (elem, vec)
if (vec)
for (i = 0; i < TREE_VEC_LENGTH (vec); ++i)
- if (comptypes (elem, BINFO_TYPE (TREE_VEC_ELT (vec, i)), 1))
+ if (same_type_p (elem, BINFO_TYPE (TREE_VEC_ELT (vec, i))))
return TREE_VEC_ELT (vec, i);
return NULL_TREE;
@@ -2335,6 +2374,24 @@ hack_decl_function_context (decl)
return decl_function_context (decl);
}
+/* Returns the namespace that contains DECL, whether directly or
+ indirectly. */
+
+tree
+decl_namespace_context (decl)
+ tree decl;
+{
+ while (1)
+ {
+ if (TREE_CODE (decl) == NAMESPACE_DECL)
+ return decl;
+ else if (TYPE_P (decl))
+ decl = CP_DECL_CONTEXT (TYPE_MAIN_DECL (decl));
+ else
+ decl = CP_DECL_CONTEXT (decl);
+ }
+}
+
/* Return truthvalue of whether T1 is the same tree structure as T2.
Return 1 if they are the same.
Return 0 if they are understandably different.
@@ -2388,7 +2445,7 @@ cp_tree_equal (t1, t2)
/* We need to do this when determining whether or not two
non-type pointer to member function template arguments
are the same. */
- if (!(comptypes (TREE_TYPE (t1), TREE_TYPE (t2), 1)
+ if (!(same_type_p (TREE_TYPE (t1), TREE_TYPE (t2))
/* The first operand is RTL. */
&& TREE_OPERAND (t1, 0) == TREE_OPERAND (t2, 0)))
return 0;
@@ -2456,15 +2513,14 @@ cp_tree_equal (t1, t2)
if (TREE_CODE (TREE_OPERAND (t1, 0)) != TREE_CODE (TREE_OPERAND (t2, 0)))
return 0;
if (TREE_CODE_CLASS (TREE_CODE (TREE_OPERAND (t1, 0))) == 't')
- return comptypes (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0), 1);
+ return same_type_p (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0));
break;
case PTRMEM_CST:
/* Two pointer-to-members are the same if they point to the same
field or function in the same class. */
return (PTRMEM_CST_MEMBER (t1) == PTRMEM_CST_MEMBER (t2)
- && comptypes (PTRMEM_CST_CLASS (t1), PTRMEM_CST_CLASS (t2),
- 1));
+ && same_type_p (PTRMEM_CST_CLASS (t1), PTRMEM_CST_CLASS (t2)));
default:
break;
@@ -2492,17 +2548,17 @@ cp_tree_equal (t1, t2)
return -1;
}
-/* Similar to make_tree_vec, but build on a temporary obstack. */
+/* Similar to make_tree_vec, but build on the momentary_obstack.
+ Thus, these vectors are really and truly temporary. */
tree
make_temp_vec (len)
int len;
{
register tree node;
- register struct obstack *ambient_obstack = current_obstack;
- current_obstack = expression_obstack;
+ push_expression_obstack ();
node = make_tree_vec (len);
- current_obstack = ambient_obstack;
+ pop_obstacks ();
return node;
}
@@ -2541,7 +2597,7 @@ build_int_wrapper (i)
return t;
}
-tree
+static tree
build_srcloc (file, line)
char *file;
int line;
@@ -2629,3 +2685,89 @@ member_p (decl)
tree ctx = DECL_CONTEXT (decl);
return (ctx && TREE_CODE_CLASS (TREE_CODE (ctx)) == 't');
}
+
+/* Create a placeholder for member access where we don't actually have an
+ object that the access is against. */
+
+tree
+build_dummy_object (type)
+ tree type;
+{
+ tree decl = build1 (NOP_EXPR, build_pointer_type (type), void_zero_node);
+ return build_indirect_ref (decl, NULL_PTR);
+}
+
+/* We've gotten a reference to a member of TYPE. Return *this if appropriate,
+ or a dummy object otherwise. If BINFOP is non-0, it is filled with the
+ binfo path from current_class_type to TYPE, or 0. */
+
+tree
+maybe_dummy_object (type, binfop)
+ tree type;
+ tree *binfop;
+{
+ tree decl, context;
+
+ if (current_class_type
+ && get_base_distance (type, current_class_type, 0, binfop) != -1)
+ context = current_class_type;
+ else
+ {
+ /* Reference from a nested class member function. */
+ context = type;
+ if (binfop)
+ *binfop = TYPE_BINFO (type);
+ }
+
+ if (current_class_ref && context == current_class_type)
+ decl = current_class_ref;
+ else
+ decl = build_dummy_object (context);
+
+ return decl;
+}
+
+/* Returns 1 if OB is a placeholder object, or a pointer to one. */
+
+int
+is_dummy_object (ob)
+ tree ob;
+{
+ if (TREE_CODE (ob) == INDIRECT_REF)
+ ob = TREE_OPERAND (ob, 0);
+ return (TREE_CODE (ob) == NOP_EXPR
+ && TREE_OPERAND (ob, 0) == void_zero_node);
+}
+
+/* Returns 1 iff type T is a POD type, as defined in [basic.types]. */
+
+int
+pod_type_p (t)
+ tree t;
+{
+ tree f;
+
+ while (TREE_CODE (t) == ARRAY_TYPE)
+ t = TREE_TYPE (t);
+
+ if (! IS_AGGR_TYPE (t))
+ return 1;
+
+ if (CLASSTYPE_NON_AGGREGATE (t)
+ || TYPE_HAS_COMPLEX_ASSIGN_REF (t)
+ || TYPE_HAS_DESTRUCTOR (t))
+ return 0;
+
+ for (f = TYPE_FIELDS (t); f; f = TREE_CHAIN (f))
+ {
+ if (TREE_CODE (f) != FIELD_DECL)
+ continue;
+
+ if (TREE_CODE (TREE_TYPE (f)) == REFERENCE_TYPE
+ || TYPE_PTRMEMFUNC_P (TREE_TYPE (f))
+ || TYPE_PTRMEM_P (TREE_TYPE (f)))
+ return 0;
+ }
+
+ return 1;
+}
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index e1b8dfbe350..8a90901b851 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -1,5 +1,5 @@
/* Build expressions with type checking for C++ compiler.
- Copyright (C) 1987, 88, 89, 92-97, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1987, 88, 89, 92-98, 1999 Free Software Foundation, Inc.
Hacked by Michael Tiemann (tiemann@cygnus.com)
This file is part of GNU CC.
@@ -40,9 +40,7 @@ Boston, MA 02111-1307, USA. */
#include "expr.h"
#include "toplev.h"
-extern void compiler_error ();
-
-static tree convert_for_assignment PROTO((tree, tree, char*, tree,
+static tree convert_for_assignment PROTO((tree, tree, const char *, tree,
int));
static tree pointer_int_sum PROTO((enum tree_code, tree, tree));
static tree rationalize_conditional_expr PROTO((enum tree_code, tree));
@@ -52,7 +50,6 @@ static int comp_ptr_ttypes_const PROTO((tree, tree));
static int comp_ptr_ttypes_reinterpret PROTO((tree, tree));
static int comp_array_types PROTO((int (*) (tree, tree, int), tree,
tree, int));
-static tree build_ptrmemfunc1 PROTO((tree, tree, tree, tree, tree));
static tree common_base_type PROTO((tree, tree));
#if 0
static tree convert_sequence PROTO((tree, tree));
@@ -61,6 +58,7 @@ static tree lookup_anon_field PROTO((tree, tree));
static tree pointer_diff PROTO((tree, tree, tree));
static tree qualify_type PROTO((tree, tree));
static tree get_delta_difference PROTO((tree, tree, int));
+static int comp_cv_target_types PROTO((tree, tree, int));
/* Return the target type of TYPE, which meas return T for:
T*, T&, T[], T (...), and otherwise, just T. */
@@ -91,7 +89,7 @@ require_complete_type (value)
{
tree type;
- if (processing_template_decl)
+ if (processing_template_decl || value == error_mark_node)
return value;
if (TREE_CODE (value) == OVERLOAD)
@@ -101,7 +99,7 @@ require_complete_type (value)
/* First, detect a valid value with a complete type. */
if (TYPE_SIZE (type) != 0
- && type != void_type_node
+ && TYPE_SIZE (type) != size_zero_node
&& ! (TYPE_LANG_SPECIFIC (type)
&& (IS_SIGNATURE_POINTER (type) || IS_SIGNATURE_REFERENCE (type))
&& TYPE_SIZE (SIGNATURE_TYPE (type)) == 0))
@@ -123,12 +121,105 @@ require_complete_type (value)
return require_complete_type (value);
}
- if (complete_type_or_else (type))
+ if (complete_type_or_else (type, value))
return value;
else
return error_mark_node;
}
+/* Makes sure EXPR is a complete type when used in a void context, like a
+ whole expression, or lhs of a comma operator. Issue a diagnostic and
+ return error_mark_node on failure. This is a little tricky, because some
+ valid void types look stunningly similar to invalid void types. We err on
+ the side of caution */
+
+tree
+require_complete_type_in_void (expr)
+ tree expr;
+{
+ switch (TREE_CODE (expr))
+ {
+ case COND_EXPR:
+ {
+ tree op;
+
+ op = TREE_OPERAND (expr,2);
+ op = require_complete_type_in_void (op);
+ TREE_OPERAND (expr,2) = op;
+ if (op == error_mark_node)
+ {
+ expr = op;
+ break;
+ }
+
+ /* fallthrough */
+ }
+
+ case COMPOUND_EXPR:
+ {
+ tree op;
+
+ op = TREE_OPERAND (expr,1);
+ op = require_complete_type_in_void (op);
+ TREE_OPERAND (expr,1) = op;
+ if (op == error_mark_node)
+ {
+ expr = op;
+ break;
+ }
+
+ break;
+ }
+
+ case NON_LVALUE_EXPR:
+ case NOP_EXPR:
+ {
+ tree op;
+
+ op = TREE_OPERAND (expr,0);
+ op = require_complete_type_in_void (op);
+ TREE_OPERAND (expr,0) = op;
+ if (op == error_mark_node)
+ {
+ expr = op;
+ break;
+ }
+ break;
+ }
+
+ case CALL_EXPR: /* function call return can be ignored */
+ case RTL_EXPR: /* RTL nodes have no value */
+ case DELETE_EXPR: /* delete expressions have no type */
+ case VEC_DELETE_EXPR:
+ case INTEGER_CST: /* used for null pointer */
+ case EXIT_EXPR: /* have no return */
+ case LOOP_EXPR: /* have no return */
+ case BIND_EXPR: /* have no return */
+ case THROW_EXPR: /* have no return */
+ case MODIFY_EXPR: /* sometimes this has a void type, but that's ok */
+ case CONVERT_EXPR: /* sometimes has a void type */
+ break;
+
+ case INDIRECT_REF:
+ {
+ tree op = TREE_OPERAND (expr,0);
+
+ /* Calling a function returning a reference has an implicit
+ dereference applied. We don't want to make that an error. */
+ if (TREE_CODE (op) == CALL_EXPR
+ && TREE_CODE (TREE_TYPE (op)) == REFERENCE_TYPE)
+ break;
+ /* else fallthrough */
+ }
+
+ default:
+ expr = require_complete_type (expr);
+ break;
+ }
+
+ return expr;
+}
+
/* Try to complete TYPE, if it is incomplete. For example, if TYPE is
a template instantiation, do the instantiation. Returns TYPE,
whether or not it could be completed, unless something goes
@@ -155,27 +246,28 @@ complete_type (type)
TYPE_NEEDS_DESTRUCTOR (type)
= TYPE_NEEDS_DESTRUCTOR (TYPE_MAIN_VARIANT (t));
}
- else if (IS_AGGR_TYPE (type) && CLASSTYPE_TEMPLATE_INSTANTIATION (type))
+ else if (CLASS_TYPE_P (type) && CLASSTYPE_TEMPLATE_INSTANTIATION (type))
instantiate_class_template (TYPE_MAIN_VARIANT (type));
return type;
}
/* Like complete_type, but issue an error if the TYPE cannot be
- completed. Returns NULL_TREE if the type cannot be made
- complete. */
+ completed. VALUE is used for informative diagnostics.
+ Returns NULL_TREE if the type cannot be made complete. */
tree
-complete_type_or_else (type)
+complete_type_or_else (type, value)
tree type;
+ tree value;
{
type = complete_type (type);
if (type == error_mark_node)
/* We already issued an error. */
return NULL_TREE;
- else if (!TYPE_SIZE (type))
+ else if (!TYPE_SIZE (type) || TYPE_SIZE (type) == size_zero_node)
{
- incomplete_type_error (NULL_TREE, type);
+ incomplete_type_error (value, type);
return NULL_TREE;
}
else
@@ -207,32 +299,6 @@ fntype_p (t)
|| TREE_CODE (TREE_TYPE (t)) == METHOD_TYPE)));
}
-/* Do `exp = require_instantiated_type (type, exp);' to make sure EXP
- does not have an uninstantiated type.
- TYPE is type to instantiate with, if uninstantiated. */
-
-tree
-require_instantiated_type (type, exp, errval)
- tree type, exp, errval;
-{
- if (TREE_TYPE (exp) == NULL_TREE)
- {
- error ("argument list may not have an initializer list");
- return errval;
- }
-
- if (TREE_CODE (exp) == OVERLOAD
- || TREE_TYPE (exp) == unknown_type_node
- || (TREE_CODE (TREE_TYPE (exp)) == OFFSET_TYPE
- && TREE_TYPE (TREE_TYPE (exp)) == unknown_type_node))
- {
- exp = instantiate_type (type, exp, 1);
- if (TREE_TYPE (exp) == error_mark_node)
- return errval;
- }
- return exp;
-}
-
/* Return a variant of TYPE which has all the type qualifiers of LIKE
as well as those of TYPE. */
@@ -240,10 +306,9 @@ static tree
qualify_type (type, like)
tree type, like;
{
- int constflag = TYPE_READONLY (type) || TYPE_READONLY (like);
- int volflag = TYPE_VOLATILE (type) || TYPE_VOLATILE (like);
/* @@ Must do member pointers here. */
- return cp_build_type_variant (type, constflag, volflag);
+ return cp_build_qualified_type (type, (CP_TYPE_QUALS (type)
+ | CP_TYPE_QUALS (like)));
}
/* Return the common type of two parameter lists.
@@ -497,16 +562,33 @@ common_type (t1, t2)
But ANSI C++ specifies doing this with the qualifiers.
So I turned it on again. */
{
- tree tt1 = TYPE_MAIN_VARIANT (TREE_TYPE (t1));
- tree tt2 = TYPE_MAIN_VARIANT (TREE_TYPE (t2));
- int constp
- = TYPE_READONLY (TREE_TYPE (t1)) || TYPE_READONLY (TREE_TYPE (t2));
- int volatilep
- = TYPE_VOLATILE (TREE_TYPE (t1)) || TYPE_VOLATILE (TREE_TYPE (t2));
+ tree tt1 = TREE_TYPE (t1);
+ tree tt2 = TREE_TYPE (t2);
+ tree b1, b2;
+ int type_quals;
tree target;
+ if (TREE_CODE (tt1) == OFFSET_TYPE)
+ {
+ b1 = TYPE_OFFSET_BASETYPE (tt1);
+ b2 = TYPE_OFFSET_BASETYPE (tt2);
+ tt1 = TREE_TYPE (tt1);
+ tt2 = TREE_TYPE (tt2);
+ }
+ else
+ b1 = b2 = NULL_TREE;
+
+ type_quals = (CP_TYPE_QUALS (tt1) | CP_TYPE_QUALS (tt2));
+ tt1 = TYPE_MAIN_VARIANT (tt1);
+ tt2 = TYPE_MAIN_VARIANT (tt2);
+
if (tt1 == tt2)
target = tt1;
+ else if (b1)
+ {
+ compiler_error ("common_type called with uncommon member types");
+ target = tt1;
+ }
else if (tt1 == void_type_node || tt2 == void_type_node)
target = void_type_node;
else if (tt1 == unknown_type_node)
@@ -516,7 +598,17 @@ common_type (t1, t2)
else
target = common_type (tt1, tt2);
- target = cp_build_type_variant (target, constp, volatilep);
+ target = cp_build_qualified_type (target, type_quals);
+
+ if (b1)
+ {
+ if (same_type_p (b1, b2)
+ || (DERIVED_FROM_P (b1, b2) && binfo_or_else (b1, b2)))
+ target = build_offset_type (b2, target);
+ else if (binfo_or_else (b2, b1))
+ target = build_offset_type (b1, target);
+ }
+
if (code1 == POINTER_TYPE)
t1 = build_pointer_type (target);
else
@@ -606,7 +698,7 @@ common_type (t1, t2)
tree b1 = TYPE_OFFSET_BASETYPE (t1);
tree b2 = TYPE_OFFSET_BASETYPE (t2);
- if (comptypes (b1, b2, 1)
+ if (same_type_p (b1, b2)
|| (DERIVED_FROM_P (b1, b2) && binfo_or_else (b1, b2)))
basetype = TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (t2)));
else
@@ -636,18 +728,9 @@ common_type (t1, t2)
return build_type_attribute_variant (t1, attributes);
case OFFSET_TYPE:
- if (TREE_TYPE (t1) == TREE_TYPE (t2))
- {
- tree b1 = TYPE_OFFSET_BASETYPE (t1);
- tree b2 = TYPE_OFFSET_BASETYPE (t2);
-
- if (comptypes (b1, b2, 1)
- || (DERIVED_FROM_P (b1, b2) && binfo_or_else (b1, b2)))
- return build_type_attribute_variant (t2, attributes);
- else if (binfo_or_else (b2, b1))
- return build_type_attribute_variant (t1, attributes);
- }
- compiler_error ("common_type called with uncommon member types");
+ /* Pointers to members should now be handled by the POINTER_TYPE
+ case above. */
+ my_friendly_abort (990325);
default:
return build_type_attribute_variant (t1, attributes);
@@ -663,61 +746,58 @@ compexcepttypes (t1, t2)
return TYPE_RAISES_EXCEPTIONS (t1) == TYPE_RAISES_EXCEPTIONS (t2);
}
+/* Compare the array types T1 and T2, using CMP as the type comparison
+ function for the element types. STRICT is as for comptypes. */
+
static int
comp_array_types (cmp, t1, t2, strict)
register int (*cmp) PROTO((tree, tree, int));
tree t1, t2;
int strict;
{
- tree d1 = TYPE_DOMAIN (t1);
- tree d2 = TYPE_DOMAIN (t2);
+ tree d1;
+ tree d2;
- /* Target types must match incl. qualifiers. */
+ if (t1 == t2)
+ return 1;
+
+ /* The type of the array elements must be the same. */
if (!(TREE_TYPE (t1) == TREE_TYPE (t2)
- || (*cmp) (TREE_TYPE (t1), TREE_TYPE (t2), strict)))
+ || (*cmp) (TREE_TYPE (t1), TREE_TYPE (t2),
+ strict & ~COMPARE_REDECLARATION)))
return 0;
- /* Sizes must match unless one is missing or variable. */
- if (d1 == 0 || d2 == 0 || d1 == d2
- || TREE_CODE (TYPE_MIN_VALUE (d1)) != INTEGER_CST
- || TREE_CODE (TYPE_MIN_VALUE (d2)) != INTEGER_CST
- || TREE_CODE (TYPE_MAX_VALUE (d1)) != INTEGER_CST
- || TREE_CODE (TYPE_MAX_VALUE (d2)) != INTEGER_CST)
+ d1 = TYPE_DOMAIN (t1);
+ d2 = TYPE_DOMAIN (t2);
+
+ if (d1 == d2)
return 1;
- return ((TREE_INT_CST_LOW (TYPE_MIN_VALUE (d1))
- == TREE_INT_CST_LOW (TYPE_MIN_VALUE (d2)))
- && (TREE_INT_CST_HIGH (TYPE_MIN_VALUE (d1))
- == TREE_INT_CST_HIGH (TYPE_MIN_VALUE (d2)))
- && (TREE_INT_CST_LOW (TYPE_MAX_VALUE (d1))
- == TREE_INT_CST_LOW (TYPE_MAX_VALUE (d2)))
- && (TREE_INT_CST_HIGH (TYPE_MAX_VALUE (d1))
- == TREE_INT_CST_HIGH (TYPE_MAX_VALUE (d2))));
+ /* If one of the arrays is dimensionless, and the other has a
+ dimension, they are of different types. However, it is legal to
+ write:
+
+ extern int a[];
+ int a[3];
+
+ by [basic.link]:
+
+ declarations for an array object can specify
+ array types that differ by the presence or absence of a major
+ array bound (_dcl.array_). */
+ if (!d1 || !d2)
+ return strict & COMPARE_REDECLARATION;
+
+ /* Check that the dimensions are the same. */
+ return (cp_tree_equal (TYPE_MIN_VALUE (d1),
+ TYPE_MIN_VALUE (d2))
+ && cp_tree_equal (TYPE_MAX_VALUE (d1),
+ TYPE_MAX_VALUE (d2)));
}
/* Return 1 if TYPE1 and TYPE2 are compatible types for assignment
- or various other operations. This is what ANSI C++ speaks of as
- "being the same".
-
- For C++: argument STRICT says we should be strict about this
- comparison:
-
- 2 : strict, except that if one type is a reference and
- the other is not, compare the target type of the
- reference to the type that's not a reference (ARM, p308).
- This is used for checking for invalid overloading.
- 1 : strict (compared according to ANSI C)
- This is used for checking whether two function decls match.
- 0 : <= (compared according to C++)
- -1: <= or >= (relaxed)
-
- Otherwise, pointers involving base classes and derived classes can
- be mixed as valid: i.e. a pointer to a derived class may be converted
- to a pointer to one of its base classes, as per C++. A pointer to
- a derived class may be passed as a parameter to a function expecting a
- pointer to a base classes. These allowances do not commute. In this
- case, TYPE1 is assumed to be the base class, and TYPE2 is assumed to
- be the derived class. */
+ or various other operations. STRICT is a bitwise-or of the
+ COMPARE_* flags. */
int
comptypes (type1, type2, strict)
@@ -727,9 +807,18 @@ comptypes (type1, type2, strict)
register tree t1 = type1;
register tree t2 = type2;
int attrval, val;
+ int orig_strict = strict;
- /* Suppress errors caused by previously reported errors */
+ /* The special exemption for redeclaring array types without an
+ array bound only applies at the top level:
+ extern int (*i)[];
+ int (*i)[8];
+
+ is not legal, for example. */
+ strict &= ~COMPARE_REDECLARATION;
+
+ /* Suppress errors caused by previously reported errors */
if (t1 == t2)
return 1;
@@ -739,7 +828,7 @@ comptypes (type1, type2, strict)
if (t2 == error_mark_node)
return 0;
- if (strict < 0)
+ if (strict & COMPARE_RELAXED)
{
/* Treat an enum type as the unsigned integer type of the same width. */
@@ -758,30 +847,14 @@ comptypes (type1, type2, strict)
t2 = TYPE_PTRMEMFUNC_FN_TYPE (t2);
/* Different classes of types can't be compatible. */
-
if (TREE_CODE (t1) != TREE_CODE (t2))
- {
- if (strict == 2
- && ((TREE_CODE (t1) == REFERENCE_TYPE)
- ^ (TREE_CODE (t2) == REFERENCE_TYPE)))
- {
- if (TREE_CODE (t1) == REFERENCE_TYPE)
- return comptypes (TREE_TYPE (t1), t2, 1);
- return comptypes (t1, TREE_TYPE (t2), 1);
- }
-
- return 0;
- }
- if (strict > 1)
- strict = 1;
+ return 0;
/* Qualifiers must match. */
-
- if (TYPE_READONLY (t1) != TYPE_READONLY (t2))
- return 0;
- if (TYPE_VOLATILE (t1) != TYPE_VOLATILE (t2))
+ if (CP_TYPE_QUALS (t1) != CP_TYPE_QUALS (t2))
return 0;
- if (strict > 0 && TYPE_FOR_JAVA (t1) != TYPE_FOR_JAVA (t2))
+ if (strict == COMPARE_STRICT
+ && TYPE_FOR_JAVA (t1) != TYPE_FOR_JAVA (t2))
return 0;
/* Allow for two different type nodes which have essentially the same
@@ -813,22 +886,32 @@ comptypes (type1, type2, strict)
if (! comp_template_parms (DECL_TEMPLATE_PARMS (TYPE_NAME (t1)),
DECL_TEMPLATE_PARMS (TYPE_NAME (t2))))
return 0;
- if (! CLASSTYPE_TEMPLATE_INFO (t1) && ! CLASSTYPE_TEMPLATE_INFO (t2))
+ if (!TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (t1)
+ && ! TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (t2))
return 1;
/* Don't check inheritance. */
- strict = 1;
+ strict = COMPARE_STRICT;
/* fall through */
case RECORD_TYPE:
case UNION_TYPE:
- if (CLASSTYPE_TEMPLATE_INFO (t1) && CLASSTYPE_TEMPLATE_INFO (t2)
- && (CLASSTYPE_TI_TEMPLATE (t1) == CLASSTYPE_TI_TEMPLATE (t2)
+ if (TYPE_TEMPLATE_INFO (t1) && TYPE_TEMPLATE_INFO (t2)
+ && (TYPE_TI_TEMPLATE (t1) == TYPE_TI_TEMPLATE (t2)
|| TREE_CODE (t1) == TEMPLATE_TEMPLATE_PARM))
- return comp_template_args (CLASSTYPE_TI_ARGS (t1),
- CLASSTYPE_TI_ARGS (t2));
- if (strict <= 0)
- goto look_hard;
- return 0;
+ val = comp_template_args (TYPE_TI_ARGS (t1),
+ TYPE_TI_ARGS (t2));
+ look_hard:
+ if ((strict & COMPARE_BASE) && DERIVED_FROM_P (t1, t2))
+ {
+ val = 1;
+ break;
+ }
+ if ((strict & COMPARE_RELAXED) && DERIVED_FROM_P (t2, t1))
+ {
+ val = 1;
+ break;
+ }
+ break;
case OFFSET_TYPE:
val = (comptypes (build_pointer_type (TYPE_OFFSET_BASETYPE (t1)),
@@ -846,8 +929,7 @@ comptypes (type1, type2, strict)
but not vice-versa! */
val = (comptypes (TREE_TYPE (t1), TREE_TYPE (t2), strict)
- && compparms (TYPE_ARG_TYPES (t1),
- TYPE_ARG_TYPES (t2), strict));
+ && compparms (TYPE_ARG_TYPES (t1), TYPE_ARG_TYPES (t2)));
break;
case POINTER_TYPE:
@@ -859,28 +941,9 @@ comptypes (type1, type2, strict)
val = comptypes (t1, t2, strict);
if (val)
break;
- /* if they do not, try more relaxed alternatives */
- if (strict <= 0)
- {
- if (TREE_CODE (t1) == RECORD_TYPE && TREE_CODE (t2) == RECORD_TYPE)
- {
- int rval;
- look_hard:
- rval = t1 == t2 || DERIVED_FROM_P (t1, t2);
-
- if (rval)
- {
- val = 1;
- break;
- }
- if (strict < 0)
- {
- val = DERIVED_FROM_P (t2, t1);
- break;
- }
- }
- return 0;
- }
+ if (TREE_CODE (t1) == RECORD_TYPE
+ && TREE_CODE (t2) == RECORD_TYPE)
+ goto look_hard;
break;
case FUNCTION_TYPE:
@@ -889,12 +952,14 @@ comptypes (type1, type2, strict)
val = ((TREE_TYPE (t1) == TREE_TYPE (t2)
|| comptypes (TREE_TYPE (t1), TREE_TYPE (t2), strict))
- && compparms (TYPE_ARG_TYPES (t1), TYPE_ARG_TYPES (t2), strict));
+ && compparms (TYPE_ARG_TYPES (t1), TYPE_ARG_TYPES (t2)));
break;
case ARRAY_TYPE:
- /* Target types must match incl. qualifiers. */
- val = comp_array_types (comptypes, t1, t2, strict);
+ /* Target types must match incl. qualifiers. We use ORIG_STRICT
+ here since this is the one place where
+ COMPARE_REDECLARATION should be used. */
+ val = comp_array_types (comptypes, t1, t2, orig_strict);
break;
case TEMPLATE_TYPE_PARM:
@@ -904,7 +969,7 @@ comptypes (type1, type2, strict)
case TYPENAME_TYPE:
if (TYPE_IDENTIFIER (t1) != TYPE_IDENTIFIER (t2))
return 0;
- return comptypes (TYPE_CONTEXT (t1), TYPE_CONTEXT (t2), 1);
+ return same_type_p (TYPE_CONTEXT (t1), TYPE_CONTEXT (t2));
default:
break;
@@ -921,17 +986,18 @@ comp_cv_target_types (ttl, ttr, nptrs)
int nptrs;
{
int t;
- int c = TYPE_READONLY (ttl) - TYPE_READONLY (ttr);
- int v = TYPE_VOLATILE (ttl) - TYPE_VOLATILE (ttr);
- if ((c > 0 && v < 0) || (c < 0 && v > 0))
+ if (!at_least_as_qualified_p (ttl, ttr)
+ && !at_least_as_qualified_p (ttr, ttl))
+ /* The qualifications are incomparable. */
return 0;
if (TYPE_MAIN_VARIANT (ttl) == TYPE_MAIN_VARIANT (ttr))
- return (c + v < 0) ? -1 : 1;
+ return more_qualified_p (ttr, ttl) ? -1 : 1;
t = comp_target_types (ttl, ttr, nptrs);
- if ((t == 1 && c + v >= 0) || (t == -1 && c + v <= 0))
+ if ((t == 1 && at_least_as_qualified_p (ttl, ttr))
+ || (t == -1 && at_least_as_qualified_p (ttr, ttl)))
return t;
return 0;
@@ -1010,7 +1076,7 @@ comp_target_types (ttl, ttr, nptrs)
}
if (TREE_CODE (ttr) == ARRAY_TYPE)
- return comp_array_types (comp_target_types, ttl, ttr, 0);
+ return comp_array_types (comp_target_types, ttl, ttr, COMPARE_STRICT);
else if (TREE_CODE (ttr) == FUNCTION_TYPE || TREE_CODE (ttr) == METHOD_TYPE)
{
tree argsl, argsr;
@@ -1018,7 +1084,7 @@ comp_target_types (ttl, ttr, nptrs)
if (pedantic)
{
- if (comptypes (TREE_TYPE (ttl), TREE_TYPE (ttr), 1) == 0)
+ if (!same_type_p (TREE_TYPE (ttl), TREE_TYPE (ttr)))
return 0;
}
else
@@ -1041,9 +1107,9 @@ comp_target_types (ttl, ttr, nptrs)
tree tl = TYPE_METHOD_BASETYPE (ttl);
tree tr = TYPE_METHOD_BASETYPE (ttr);
- if (comptypes (tr, tl, 0) == 0)
+ if (!same_or_base_type_p (tr, tl))
{
- if (comptypes (tl, tr, 0))
+ if (same_or_base_type_p (tl, tr))
saw_contra = 1;
else
return 0;
@@ -1071,11 +1137,11 @@ comp_target_types (ttl, ttr, nptrs)
/* Contravariance: we can assign a pointer to base member to a pointer
to derived member. Note difference from simple pointer case, where
we can pass a pointer to derived to a pointer to base. */
- if (comptypes (TYPE_OFFSET_BASETYPE (ttr),
- TYPE_OFFSET_BASETYPE (ttl), 0))
+ if (same_or_base_type_p (TYPE_OFFSET_BASETYPE (ttr),
+ TYPE_OFFSET_BASETYPE (ttl)))
base = 1;
- else if (comptypes (TYPE_OFFSET_BASETYPE (ttl),
- TYPE_OFFSET_BASETYPE (ttr), 0))
+ else if (same_or_base_type_p (TYPE_OFFSET_BASETYPE (ttl),
+ TYPE_OFFSET_BASETYPE (ttr)))
{
tree tmp = ttl;
ttl = ttr;
@@ -1106,9 +1172,11 @@ comp_target_types (ttl, ttr, nptrs)
{
if (nptrs < 0)
return 0;
- if (comptypes (build_pointer_type (ttl), build_pointer_type (ttr), 0))
+ if (same_or_base_type_p (build_pointer_type (ttl),
+ build_pointer_type (ttr)))
return 1;
- if (comptypes (build_pointer_type (ttr), build_pointer_type (ttl), 0))
+ if (same_or_base_type_p (build_pointer_type (ttr),
+ build_pointer_type (ttl)))
return -1;
return 0;
}
@@ -1116,6 +1184,29 @@ comp_target_types (ttl, ttr, nptrs)
return 0;
}
+/* Returns 1 if TYPE1 is at least as qualified as TYPE2. */
+
+int
+at_least_as_qualified_p (type1, type2)
+ tree type1;
+ tree type2;
+{
+ /* All qualifiers for TYPE2 must also appear in TYPE1. */
+ return ((CP_TYPE_QUALS (type1) & CP_TYPE_QUALS (type2))
+ == CP_TYPE_QUALS (type2));
+}
+
+/* Returns 1 if TYPE1 is more qualified than TYPE2. */
+
+int
+more_qualified_p (type1, type2)
+ tree type1;
+ tree type2;
+{
+ return (CP_TYPE_QUALS (type1) != CP_TYPE_QUALS (type2)
+ && at_least_as_qualified_p (type1, type2));
+}
+
/* Returns 1 if TYPE1 is more cv-qualified than TYPE2, -1 if TYPE2 is
more cv-qualified that TYPE1, and 0 otherwise. */
@@ -1124,16 +1215,13 @@ comp_cv_qualification (type1, type2)
tree type1;
tree type2;
{
- if (TYPE_READONLY (type1) == TYPE_READONLY (type2)
- && TYPE_VOLATILE (type1) == TYPE_VOLATILE (type2))
+ if (CP_TYPE_QUALS (type1) == CP_TYPE_QUALS (type2))
return 0;
- if (TYPE_READONLY (type1) >= TYPE_READONLY (type2)
- && TYPE_VOLATILE (type1) >= TYPE_VOLATILE (type2))
+ if (at_least_as_qualified_p (type1, type2))
return 1;
- if (TYPE_READONLY (type2) >= TYPE_READONLY (type1)
- && TYPE_VOLATILE (type2) >= TYPE_VOLATILE (type1))
+ else if (at_least_as_qualified_p (type2, type1))
return -1;
return 0;
@@ -1210,20 +1298,16 @@ common_base_type (tt1, tt2)
/* Subroutines of `comptypes'. */
-/* Return 1 if two parameter type lists PARMS1 and PARMS2
- are equivalent in the sense that functions with those parameter types
- can have equivalent types.
- If either list is empty, we win.
- Otherwise, the two lists must be equivalent, element by element.
+/* Return 1 if two parameter type lists PARMS1 and PARMS2 are
+ equivalent in the sense that functions with those parameter types
+ can have equivalent types. The two lists must be equivalent,
+ element by element.
- C++: See comment above about TYPE1, TYPE2.
-
- STRICT is no longer used. */
+ C++: See comment above about TYPE1, TYPE2. */
int
-compparms (parms1, parms2, strict)
+compparms (parms1, parms2)
tree parms1, parms2;
- int strict ATTRIBUTE_UNUSED;
{
register tree t1 = parms1, t2 = parms2;
@@ -1238,7 +1322,7 @@ compparms (parms1, parms2, strict)
they fail to match. */
if (t1 == 0 || t2 == 0)
return 0;
- if (! comptypes (TREE_VALUE (t2), TREE_VALUE (t1), 1))
+ if (!same_type_p (TREE_VALUE (t2), TREE_VALUE (t1)))
return 0;
t1 = TREE_CHAIN (t1);
@@ -1292,7 +1376,7 @@ comp_target_parms (parms1, parms2, strict)
}
p1 = TREE_VALUE (t1);
p2 = TREE_VALUE (t2);
- if (comptypes (p1, p2, 1))
+ if (same_type_p (p1, p2))
continue;
if (pedantic)
@@ -1316,12 +1400,10 @@ comp_target_parms (parms1, parms2, strict)
warn_contravariance = 1;
continue;
}
- if (IS_AGGR_TYPE (TREE_TYPE (p1)))
- {
- if (comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (p1)),
- TYPE_MAIN_VARIANT (TREE_TYPE (p2)), 1) == 0)
- return 0;
- }
+ if (IS_AGGR_TYPE (TREE_TYPE (p1))
+ && !same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (p1)),
+ TYPE_MAIN_VARIANT (TREE_TYPE (p2))))
+ return 0;
}
/* Note backwards order due to contravariance. */
if (comp_target_types (p2, p1, 1) <= 0)
@@ -1384,8 +1466,10 @@ unsigned_type (type)
return long_unsigned_type_node;
if (type1 == long_long_integer_type_node)
return long_long_unsigned_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)
@@ -1415,8 +1499,10 @@ signed_type (type)
return long_integer_type_node;
if (type1 == long_long_unsigned_type_node)
return long_long_integer_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)
@@ -1535,7 +1621,7 @@ expr_sizeof (e)
return build_min (SIZEOF_EXPR, sizetype, e);
if (TREE_CODE (e) == COMPONENT_REF
- && DECL_BIT_FIELD (TREE_OPERAND (e, 1)))
+ && DECL_C_BIT_FIELD (TREE_OPERAND (e, 1)))
error ("sizeof applied to a bit-field");
/* ANSI says arrays and functions are converted inside comma.
But we can't really convert them in build_compound_expr
@@ -1545,15 +1631,12 @@ expr_sizeof (e)
&& (TREE_CODE (TREE_TYPE (e)) == ARRAY_TYPE
|| TREE_CODE (TREE_TYPE (e)) == FUNCTION_TYPE))
e = default_conversion (e);
- else if (TREE_CODE (e) == TREE_LIST)
+ else if (is_overloaded_fn (e))
{
- tree t = TREE_VALUE (e);
- if (t != NULL_TREE
- && ((TREE_TYPE (t)
- && TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE)
- || is_overloaded_fn (t)))
- pedwarn ("ANSI C++ forbids taking the sizeof a function type");
+ pedwarn ("ANSI C++ forbids taking the sizeof a function type");
+ return size_int (1);
}
+
return c_sizeof (TREE_TYPE (e));
}
@@ -1619,12 +1702,11 @@ c_alignof (type)
return t;
}
-/* Perform default promotions for C data used in expressions.
- Arrays and functions are converted to pointers;
- enumeral types or short or char, to int.
- In addition, manifest constants symbols are replaced by their values.
+/* Perform the array-to-pointer and function-to-pointer conversions
+ for EXP.
- C++: this will automatically bash references to their target type. */
+ In addition, references are converted to rvalues and manifest
+ constants are replaced by their values. */
tree
decay_conversion (exp)
@@ -1658,8 +1740,15 @@ decay_conversion (exp)
/* Constants can be used directly unless they're not loadable. */
if (TREE_CODE (exp) == CONST_DECL)
exp = DECL_INITIAL (exp);
- /* Replace a nonvolatile const static variable with its value. */
- else if (TREE_READONLY_DECL_P (exp))
+ /* Replace a nonvolatile const static variable with its value. We
+ don't do this for arrays, though; we want the address of the
+ first element of the array, not the address of the first element
+ of its initializing constant. We *do* replace variables that the
+ user isn't really supposed to know about; this is a hack to deal
+ with __PRETTY_FUNCTION__ and the like. */
+ else if (TREE_READONLY_DECL_P (exp)
+ && (code != ARRAY_TYPE
+ || (TREE_CODE (exp) == VAR_DECL && DECL_IGNORED_P (exp))))
{
exp = decl_constant_value (exp);
type = TREE_TYPE (exp);
@@ -1673,15 +1762,13 @@ decay_conversion (exp)
error ("void value not ignored as it ought to be");
return error_mark_node;
}
- if (code == FUNCTION_TYPE)
- {
- return build_unary_op (ADDR_EXPR, exp, 0);
- }
if (code == METHOD_TYPE)
{
cp_pedwarn ("assuming & on `%E'", exp);
return build_unary_op (ADDR_EXPR, exp, 0);
}
+ if (code == FUNCTION_TYPE || is_overloaded_fn (exp))
+ return build_unary_op (ADDR_EXPR, exp, 0);
if (code == ARRAY_TYPE)
{
register tree adr;
@@ -1771,11 +1858,8 @@ inline_conversion (exp)
tree exp;
{
if (TREE_CODE (exp) == FUNCTION_DECL)
- {
- tree type = build_type_variant
- (TREE_TYPE (exp), TREE_READONLY (exp), TREE_THIS_VOLATILE (exp));
- exp = build1 (ADDR_EXPR, build_pointer_type (type), exp);
- }
+ exp = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (exp)), exp);
+
return exp;
}
@@ -1793,14 +1877,21 @@ string_conv_p (totype, exp, warn)
return 0;
t = TREE_TYPE (totype);
- if (! comptypes (t, char_type_node, 1)
- && ! comptypes (t, wchar_type_node, 1))
+ if (!same_type_p (t, char_type_node)
+ && !same_type_p (t, wchar_type_node))
return 0;
- if (TREE_CODE (exp) != STRING_CST)
+ if (TREE_CODE (exp) == STRING_CST)
+ {
+ /* Make sure that we don't try to convert between char and wchar_t. */
+ if (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (exp))) != t)
+ return 0;
+ }
+ else
{
- t = build_pointer_type (build_type_variant (t, 1, 0));
- if (! comptypes (TREE_TYPE (exp), t, 1))
+ /* Is this a string constant which has decayed to 'const char *'? */
+ t = build_pointer_type (build_qualified_type (t, TYPE_QUAL_CONST));
+ if (!same_type_p (TREE_TYPE (exp), t))
return 0;
STRIP_NOPS (exp);
if (TREE_CODE (exp) != ADDR_EXPR
@@ -1810,7 +1901,7 @@ string_conv_p (totype, exp, warn)
/* This warning is not very useful, as it complains about printf. */
if (warn && warn_write_strings)
- cp_warning ("deprecated conversion from string constant to `char *'");
+ cp_warning ("deprecated conversion from string constant to `%T'", totype);
return 1;
}
@@ -1944,8 +2035,7 @@ build_component_ref (datum, component, basetype_path, protect)
register tree field = NULL;
register tree ref;
tree field_type;
- int constp;
- int volatilep;
+ int type_quals;
if (processing_template_decl)
return build_min_nt (COMPONENT_REF, datum, component);
@@ -2020,7 +2110,7 @@ build_component_ref (datum, component, basetype_path, protect)
return error_mark_node;
}
- if (!complete_type_or_else (basetype))
+ if (!complete_type_or_else (basetype, datum))
return error_mark_node;
if (TREE_CODE (component) == BIT_NOT_EXPR)
@@ -2050,8 +2140,8 @@ build_component_ref (datum, component, basetype_path, protect)
field = component;
else if (TREE_CODE (component) == TYPE_DECL)
{
- cp_pedwarn ("invalid use of type decl `%#D' as expression", component);
- return component;
+ cp_error ("invalid use of type decl `%#D' as expression", component);
+ return error_mark_node;
}
else
{
@@ -2075,58 +2165,35 @@ build_component_ref (datum, component, basetype_path, protect)
return error_mark_node;
if (fndecls)
{
+ /* If the function is unique and static, we can resolve it
+ now. Otherwise, we have to wait and see what context it is
+ used in; a component_ref involving a non-static member
+ function can only be used in a call (expr.ref). */
+
if (TREE_CHAIN (fndecls) == NULL_TREE
- && TREE_CODE (TREE_VALUE (fndecls)) != OVERLOAD)
+ && TREE_CODE (TREE_VALUE (fndecls)) == FUNCTION_DECL)
{
- tree access, fndecl;
-
- /* Unique, so use this one now. */
- basetype = TYPE_MAIN_VARIANT (TREE_PURPOSE (fndecls));
- fndecl = TREE_VALUE (fndecls);
- access = compute_access (TREE_PURPOSE (fndecls), fndecl);
- if (access == access_public_node)
+ if (DECL_STATIC_FUNCTION_P (TREE_VALUE (fndecls)))
{
- if (DECL_VINDEX (fndecl)
- && ! resolves_to_fixed_type_p (datum, 0))
- {
- tree addr = build_unary_op (ADDR_EXPR, datum, 0);
- tree fntype = TREE_TYPE (fndecl);
-
- addr = convert_pointer_to (DECL_CONTEXT (fndecl),
- addr);
- datum = build_indirect_ref (addr, NULL_PTR);
- my_friendly_assert (datum != error_mark_node, 310);
- fndecl = build_vfn_ref (&addr, datum,
- DECL_VINDEX (fndecl));
- /* The type of fndecl is a function type,
- not a pointer-to-function type, since
- build_vfn_ref returns not the correct
- vtable slot, but the indirection of the
- correct vtable slot. */
- TREE_TYPE (fndecl) = fntype;
- }
- else
- mark_used (fndecl);
- return build (OFFSET_REF, TREE_TYPE (fndecl),
- datum, fndecl);
+ tree fndecl = TREE_VALUE (fndecls);
+ enforce_access (TREE_PURPOSE (fndecls), fndecl);
+ mark_used (fndecl);
+ return fndecl;
}
- if (access == access_protected_node)
- cp_error ("member function `%D' is protected", fndecl);
else
- cp_error ("member function `%D' is private", fndecl);
- return error_mark_node;
- }
- else
- {
- /* Just act like build_offset_ref, since the object does
- not matter unless we're actually calling the function. */
- tree t;
-
- t = build_tree_list (error_mark_node, fndecls);
- TREE_TYPE (t) = build_offset_type (basetype,
- unknown_type_node);
- return t;
+ {
+ /* A unique non-static member function. Other parts
+ of the compiler expect something with
+ unknown_type_node to be really overloaded, so
+ let's oblige. */
+ TREE_VALUE (fndecls)
+ = scratch_ovl_cons (TREE_VALUE (fndecls), NULL_TREE);
+ }
}
+
+ ref = build (COMPONENT_REF, unknown_type_node,
+ datum, fndecls);
+ return ref;
}
cp_error ("`%#T' has no member named `%D'", basetype, name);
@@ -2153,7 +2220,7 @@ build_component_ref (datum, component, basetype_path, protect)
{
tree context = DECL_FIELD_CONTEXT (field);
tree base = context;
- while (!comptypes (base, basetype,1) && TYPE_NAME (base)
+ while (!same_type_p (base, basetype) && TYPE_NAME (base)
&& ANON_UNION_TYPE_P (base))
{
base = TYPE_CONTEXT (base);
@@ -2194,8 +2261,7 @@ build_component_ref (datum, component, basetype_path, protect)
}
/* Compute the type of the field, as described in [expr.ref]. */
- constp = 0;
- volatilep = 0;
+ type_quals = TYPE_UNQUALIFIED;
field_type = TREE_TYPE (field);
if (TREE_CODE (field_type) == REFERENCE_TYPE)
/* The standard says that the type of the result should be the
@@ -2204,17 +2270,16 @@ build_component_ref (datum, component, basetype_path, protect)
;
else
{
+ type_quals = (CP_TYPE_QUALS (field_type)
+ | CP_TYPE_QUALS (TREE_TYPE (datum)));
+
/* A field is const (volatile) if the enclosing object, or the
field itself, is const (volatile). But, a mutable field is
not const, even within a const object. */
- constp = (!(DECL_LANG_SPECIFIC (field)
- && DECL_MUTABLE_P (field))
- && (TYPE_READONLY (field_type)
- || TYPE_READONLY (TREE_TYPE (datum))));
- volatilep = (TYPE_VOLATILE (field_type)
- || TYPE_VOLATILE (TREE_TYPE (datum)));
+ if (DECL_LANG_SPECIFIC (field) && DECL_MUTABLE_P (field))
+ type_quals &= ~TYPE_QUAL_CONST;
if (!IS_SIGNATURE (field_type))
- field_type = cp_build_type_variant (field_type, constp, volatilep);
+ field_type = cp_build_qualified_type (field_type, type_quals);
}
ref = fold (build (COMPONENT_REF, field_type,
@@ -2223,9 +2288,9 @@ build_component_ref (datum, component, basetype_path, protect)
/* Mark the expression const or volatile, as appropriate. Even
though we've dealt with the type above, we still have to mark the
expression itself. */
- if (constp)
+ if (type_quals & TYPE_QUAL_CONST)
TREE_READONLY (ref) = 1;
- else if (volatilep)
+ else if (type_quals & TYPE_QUAL_VOLATILE)
TREE_THIS_VOLATILE (ref) = 1;
return ref;
@@ -2257,7 +2322,7 @@ build_x_component_ref (datum, component, basetype_path, protect)
tree
build_x_indirect_ref (ptr, errorstring)
tree ptr;
- char *errorstring;
+ const char *errorstring;
{
tree rval;
@@ -2274,21 +2339,21 @@ build_x_indirect_ref (ptr, errorstring)
tree
build_indirect_ref (ptr, errorstring)
tree ptr;
- char *errorstring;
+ const char *errorstring;
{
register tree pointer, type;
if (ptr == error_mark_node)
return error_mark_node;
+ if (ptr == current_class_ptr)
+ return current_class_ref;
+
pointer = (TREE_CODE (TREE_TYPE (ptr)) == REFERENCE_TYPE
? ptr : default_conversion (ptr));
type = TREE_TYPE (pointer);
- if (ptr == current_class_ptr)
- return current_class_ref;
-
- if (TREE_CODE (type) == POINTER_TYPE || TREE_CODE (type) == REFERENCE_TYPE)
+ if (TYPE_PTR_P (type) || TREE_CODE (type) == REFERENCE_TYPE)
{
/* [expr.unary.op]
@@ -2302,7 +2367,7 @@ build_indirect_ref (ptr, errorstring)
if (TREE_CODE (pointer) == ADDR_EXPR
&& !flag_volatile
- && comptypes (t, TREE_TYPE (TREE_OPERAND (pointer, 0)), 1))
+ && same_type_p (t, TREE_TYPE (TREE_OPERAND (pointer, 0))))
/* The POINTER was something like `&x'. We simplify `*&x' to
`x'. */
return TREE_OPERAND (pointer, 0);
@@ -2313,8 +2378,8 @@ build_indirect_ref (ptr, errorstring)
/* We *must* set TREE_READONLY when dereferencing a pointer to const,
so that we get the proper error message if the result is used
to assign to. Also, &* is supposed to be a no-op. */
- TREE_READONLY (ref) = TYPE_READONLY (t);
- TREE_THIS_VOLATILE (ref) = TYPE_VOLATILE (t);
+ TREE_READONLY (ref) = CP_TYPE_CONST_P (t);
+ TREE_THIS_VOLATILE (ref) = CP_TYPE_VOLATILE_P (t);
TREE_SIDE_EFFECTS (ref)
= (TREE_THIS_VOLATILE (ref) || TREE_SIDE_EFFECTS (pointer)
|| flag_volatile);
@@ -2323,8 +2388,8 @@ build_indirect_ref (ptr, errorstring)
}
/* `pointer' won't be an error_mark_node if we were given a
pointer to member, so it's cool to check for this here. */
- else if (TYPE_PTRMEMFUNC_P (type))
- error ("invalid use of `%s' on pointer to member function", errorstring);
+ else if (TYPE_PTRMEM_P (type) || TYPE_PTRMEMFUNC_P (type))
+ error ("invalid use of `%s' on pointer to member", errorstring);
else if (TREE_CODE (type) == RECORD_TYPE
&& (IS_SIGNATURE_POINTER (type) || IS_SIGNATURE_REFERENCE (type)))
error ("cannot dereference signature pointer/reference");
@@ -2433,11 +2498,11 @@ build_array_ref (array, idx)
/* Array ref is const/volatile if the array elements are
or if the array is.. */
TREE_READONLY (rval)
- |= (TYPE_READONLY (type) | TREE_READONLY (array));
+ |= (CP_TYPE_CONST_P (type) | TREE_READONLY (array));
TREE_SIDE_EFFECTS (rval)
- |= (TYPE_VOLATILE (type) | TREE_SIDE_EFFECTS (array));
+ |= (CP_TYPE_VOLATILE_P (type) | TREE_SIDE_EFFECTS (array));
TREE_THIS_VOLATILE (rval)
- |= (TYPE_VOLATILE (type) | TREE_THIS_VOLATILE (array));
+ |= (CP_TYPE_VOLATILE_P (type) | TREE_THIS_VOLATILE (array));
return require_complete_type (fold (rval));
}
@@ -2539,6 +2604,15 @@ build_x_function_call (function, params, decl)
TYPE_BINFO (type), LOOKUP_NORMAL);
}
+ if ((TREE_CODE (function) == FUNCTION_DECL
+ && DECL_STATIC_FUNCTION_P (function))
+ || (TREE_CODE (function) == TEMPLATE_DECL
+ && DECL_STATIC_FUNCTION_P (DECL_RESULT (function))))
+ return build_member_call(DECL_CONTEXT (function),
+ template_id
+ ? template_id : DECL_NAME (function),
+ params);
+
is_method = ((TREE_CODE (function) == TREE_LIST
&& current_class_type != NULL_TREE
&& (IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (function))
@@ -2547,13 +2621,6 @@ build_x_function_call (function, params, decl)
|| TREE_CODE (type) == METHOD_TYPE
|| TYPE_PTRMEMFUNC_P (type));
- if ((TREE_CODE (function) == FUNCTION_DECL
- && DECL_STATIC_FUNCTION_P (function))
- || (TREE_CODE (function) == TEMPLATE_DECL
- && DECL_STATIC_FUNCTION_P (DECL_RESULT (function))))
- return build_member_call
- (DECL_CONTEXT (function), DECL_NAME (function), params);
-
/* A friend template. Make it look like a toplevel declaration. */
if (! is_method && TREE_CODE (function) == TEMPLATE_DECL)
function = scratch_ovl_cons (function, NULL_TREE);
@@ -2619,9 +2686,7 @@ build_x_function_call (function, params, decl)
return error_mark_node;
}
/* Yow: call from a static member function. */
- decl = build1 (NOP_EXPR, build_pointer_type (current_class_type),
- error_mark_node);
- decl = build_indirect_ref (decl, NULL_PTR);
+ decl = build_dummy_object (current_class_type);
}
/* Put back explicit template arguments, if any. */
@@ -2633,12 +2698,10 @@ build_x_function_call (function, params, decl)
else if (TREE_CODE (function) == COMPONENT_REF
&& type == unknown_type_node)
{
- /* Should we undo what was done in build_component_ref? */
- if (TREE_CODE (TREE_PURPOSE (TREE_OPERAND (function, 1))) == TREE_VEC)
- /* Get the name that build_component_ref hid. */
- function = DECL_NAME (TREE_VALUE (TREE_OPERAND (function, 1)));
- else
- function = TREE_PURPOSE (TREE_OPERAND (function, 1));
+ /* Undo what we did in build_component_ref. */
+ decl = TREE_OPERAND (function, 0);
+ function = TREE_OPERAND (function, 1);
+ function = DECL_NAME (OVL_CURRENT (TREE_VALUE (function)));
return build_method_call (decl, function, params,
NULL_TREE, LOOKUP_NORMAL);
}
@@ -2980,7 +3043,7 @@ build_function_call_real (function, params, require_complete, flags)
if (require_complete)
{
- if (value_type == void_type_node)
+ if (TREE_CODE (value_type) == VOID_TYPE)
return result;
result = require_complete_type (result);
}
@@ -3021,7 +3084,7 @@ convert_arguments (typelist, values, fndecl, flags)
{
register tree typetail, valtail;
register tree result = NULL_TREE;
- char *called_thing = 0;
+ const char *called_thing = 0;
int i = 0;
/* Argument passing is always copy-initialization. */
@@ -3055,7 +3118,7 @@ convert_arguments (typelist, values, fndecl, flags)
{
if (fndecl)
{
- cp_error_at ("too many arguments to %s `%+D'", called_thing,
+ cp_error_at ("too many arguments to %s `%+#D'", called_thing,
fndecl);
error ("at this point in file");
}
@@ -3068,31 +3131,7 @@ convert_arguments (typelist, values, fndecl, flags)
break;
}
- /* The tree type of the parameter being passed may not yet be
- known. In this case, its type is TYPE_UNKNOWN, and will
- be instantiated by the type given by TYPE. If TYPE
- is also NULL, the tree type of VAL is ERROR_MARK_NODE. */
- if (type && type_unknown_p (val))
- val = require_instantiated_type (type, val, integer_zero_node);
- else if (type_unknown_p (val))
- {
- /* Strip the `&' from an overloaded FUNCTION_DECL. */
- if (TREE_CODE (val) == ADDR_EXPR)
- val = TREE_OPERAND (val, 0);
- if (really_overloaded_fn (val))
- cp_error ("insufficient type information to resolve address of overloaded function `%D'",
- DECL_NAME (get_first_fn (val)));
- else
- error ("insufficient type information in parameter list");
- val = integer_zero_node;
- }
- else if (TREE_CODE (val) == OFFSET_REF
- && TREE_CODE (TREE_TYPE (val)) == METHOD_TYPE)
- {
- /* This is unclean. Should be handled elsewhere. */
- val = build_unary_op (ADDR_EXPR, val, 0);
- }
- else if (TREE_CODE (val) == OFFSET_REF)
+ if (TREE_CODE (val) == OFFSET_REF)
val = resolve_offset_ref (val);
/* build_c_cast puts on a NOP_EXPR to make the result not an lvalue.
@@ -3108,8 +3147,6 @@ convert_arguments (typelist, values, fndecl, flags)
|| TREE_CODE (TREE_TYPE (val)) == FUNCTION_TYPE
|| TREE_CODE (TREE_TYPE (val)) == METHOD_TYPE)
val = default_conversion (val);
-
- val = require_complete_type (val);
}
if (val == error_mark_node)
@@ -3165,9 +3202,10 @@ convert_arguments (typelist, values, fndecl, flags)
{
for (; typetail != void_list_node; ++i)
{
- tree type = TREE_VALUE (typetail);
- tree val = TREE_PURPOSE (typetail);
- tree parmval = convert_default_arg (type, val);
+ tree parmval
+ = convert_default_arg (TREE_VALUE (typetail),
+ TREE_PURPOSE (typetail),
+ fndecl);
if (parmval == error_mark_node)
return error_mark_node;
@@ -3183,9 +3221,8 @@ convert_arguments (typelist, values, fndecl, flags)
{
if (fndecl)
{
- char *buf = (char *)alloca (32 + strlen (called_thing));
- sprintf (buf, "too few arguments to %s `%%#D'", called_thing);
- cp_error_at (buf, fndecl);
+ cp_error_at ("too few arguments to %s `%+#D'",
+ called_thing, fndecl);
error ("at this point in file");
}
else
@@ -3215,41 +3252,9 @@ tree
build_binary_op (code, arg1, arg2, convert_p)
enum tree_code code;
tree arg1, arg2;
- int convert_p;
+ int convert_p ATTRIBUTE_UNUSED;
{
- tree args[2];
-
- args[0] = arg1;
- args[1] = arg2;
-
- if (convert_p)
- {
- tree type0, type1;
- args[0] = decay_conversion (args[0]);
- args[1] = decay_conversion (args[1]);
-
- if (args[0] == error_mark_node || args[1] == error_mark_node)
- return error_mark_node;
-
- type0 = TREE_TYPE (args[0]);
- type1 = TREE_TYPE (args[1]);
-
- if (type_unknown_p (args[0]))
- {
- args[0] = instantiate_type (type1, args[0], 1);
- args[0] = decay_conversion (args[0]);
- }
- else if (type_unknown_p (args[1]))
- {
- args[1] = require_instantiated_type (type0, args[1],
- error_mark_node);
- args[1] = decay_conversion (args[1]);
- }
-
- if (IS_AGGR_TYPE (type0) || IS_AGGR_TYPE (type1))
- my_friendly_abort (754867);
- }
- return build_binary_op_nodefault (code, args[0], args[1], code);
+ return build_binary_op_nodefault (code, arg1, arg2, code);
}
/* Build a binary-operation expression without default conversions.
@@ -4059,6 +4064,9 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code)
op0 = cp_convert (result_type, op0);
if (TREE_TYPE (op1) != result_type)
op1 = cp_convert (result_type, op1);
+
+ if (op0 == error_mark_node || op1 == error_mark_node)
+ return error_mark_node;
}
if (build_type == NULL_TREE)
@@ -4094,7 +4102,7 @@ pointer_int_sum (resultcode, ptrop, intop)
register tree result_type = TREE_TYPE (ptrop);
- if (!complete_type_or_else (result_type))
+ if (!complete_type_or_else (result_type, ptrop))
return error_mark_node;
if (TREE_CODE (TREE_TYPE (result_type)) == VOID_TYPE)
@@ -4186,7 +4194,7 @@ pointer_diff (op0, op1, ptrtype)
tree restype = ptrdiff_type_node;
tree target_type = TREE_TYPE (ptrtype);
- if (!complete_type_or_else (target_type))
+ if (!complete_type_or_else (target_type, NULL_TREE))
return error_mark_node;
if (pedantic || warn_pointer_arith)
@@ -4239,13 +4247,15 @@ pointer_diff (op0, op1, ptrtype)
tree
build_component_addr (arg, argtype, msg)
tree arg, argtype;
- char *msg;
+ const char *msg;
{
tree field = TREE_OPERAND (arg, 1);
tree basetype = decl_type_context (field);
tree rval = build_unary_op (ADDR_EXPR, TREE_OPERAND (arg, 0), 0);
- if (DECL_BIT_FIELD (field))
+ my_friendly_assert (TREE_CODE (field) == FIELD_DECL, 981018);
+
+ if (DECL_C_BIT_FIELD (field))
{
error (msg, IDENTIFIER_POINTER (DECL_NAME (field)));
return error_mark_node;
@@ -4349,7 +4359,7 @@ build_unary_op (code, xarg, noconvert)
/* No default_conversion here. It causes trouble for ADDR_EXPR. */
register tree arg = xarg;
register tree argtype = 0;
- char *errstring = NULL;
+ const char *errstring = NULL;
tree val;
if (arg == error_mark_node)
@@ -4478,7 +4488,7 @@ build_unary_op (code, xarg, noconvert)
/* Report something read-only. */
- if (TYPE_READONLY (TREE_TYPE (arg))
+ if (CP_TYPE_CONST_P (TREE_TYPE (arg))
|| TREE_READONLY (arg))
readonly_error (arg, ((code == PREINCREMENT_EXPR
|| code == POSTINCREMENT_EXPR)
@@ -4662,46 +4672,8 @@ build_unary_op (code, xarg, noconvert)
return build1 (ADDR_EXPR, unknown_type_node, arg);
}
- if (TREE_CODE (arg) == OVERLOAD
- || (TREE_CODE (arg) == OFFSET_REF
- && TREE_CODE (TREE_OPERAND (arg, 1)) == TEMPLATE_ID_EXPR))
+ if (type_unknown_p (arg))
return build1 (ADDR_EXPR, unknown_type_node, arg);
- else if (TREE_CODE (arg) == TREE_LIST)
- {
- if (TREE_CODE (TREE_VALUE (arg)) == FUNCTION_DECL)
- /* Unique overloaded non-member function. */
- return build_unary_op (ADDR_EXPR, TREE_VALUE (arg), 0);
- if (TREE_CHAIN (arg) == NULL_TREE
- && TREE_CODE (TREE_VALUE (arg)) == TREE_LIST
- && TREE_CODE (TREE_VALUE (TREE_VALUE (arg))) != OVERLOAD)
- /* Unique overloaded member function. */
- return build_unary_op (ADDR_EXPR, TREE_VALUE (TREE_VALUE (arg)),
- 0);
- return build1 (ADDR_EXPR, unknown_type_node, arg);
- }
- else if (TREE_CODE (arg) == TEMPLATE_ID_EXPR)
- {
- tree targs;
- tree fn;
-
- /* We don't require a match here; it's possible that the
- context (like a cast to a particular type) will resolve
- the particular choice of template. */
- fn = determine_specialization (arg,
- NULL_TREE,
- &targs,
- 0,
- 0);
-
- if (fn)
- {
- fn = instantiate_template (fn, targs);
- mark_addressable (fn);
- return build_unary_op (ADDR_EXPR, fn, 0);
- }
-
- return build1 (ADDR_EXPR, unknown_type_node, arg);
- }
/* Handle complex lvalues (when permitted)
by reduction to simpler cases. */
@@ -4752,7 +4724,7 @@ build_unary_op (code, xarg, noconvert)
(arg, argtype,
"attempt to take address of bit-field structure member `%s'");
else
- addr = build1 (code, argtype, arg);
+ addr = build1 (ADDR_EXPR, argtype, arg);
/* Address of a static or external variable or
function counts as a constant */
@@ -4887,9 +4859,7 @@ unary_complex_lvalue (code, arg)
tree type;
if (TREE_OPERAND (arg, 0)
- && (TREE_CODE (TREE_OPERAND (arg, 0)) != NOP_EXPR
- || (TREE_OPERAND (TREE_OPERAND (arg, 0), 0)
- != error_mark_node))
+ && ! is_dummy_object (TREE_OPERAND (arg, 0))
&& TREE_CODE (t) != FIELD_DECL)
{
cp_error ("taking address of bound pointer-to-member expression");
@@ -4980,7 +4950,8 @@ mark_addressable (exp)
TREE_ASM_WRITTEN (x) = 0;
DECL_RTL (x) = 0;
- rest_of_decl_compilation (x, 0, IDENTIFIER_LOCAL_VALUE (x) == 0,
+ rest_of_decl_compilation (x, 0,
+ !DECL_FUNCTION_SCOPE_P (x),
0);
TREE_ADDRESSABLE (x) = 1;
@@ -5070,13 +5041,6 @@ build_conditional_expr (ifexp, op1, op2)
if (TREE_CODE (ifexp) == ERROR_MARK)
return error_mark_node;
- op1 = require_instantiated_type (TREE_TYPE (op2), op1, error_mark_node);
- if (op1 == error_mark_node)
- return error_mark_node;
- op2 = require_instantiated_type (TREE_TYPE (op1), op2, error_mark_node);
- if (op2 == error_mark_node)
- return error_mark_node;
-
/* C++: REFERENCE_TYPES must be dereferenced. */
type1 = TREE_TYPE (op1);
code1 = TREE_CODE (type1);
@@ -5121,10 +5085,9 @@ build_conditional_expr (ifexp, op1, op2)
else if (TREE_READONLY_DECL_P (op2))
op2 = decl_constant_value (op2);
if (type1 != type2)
- type1 = cp_build_type_variant
- (type1,
- TYPE_READONLY (op1) || TYPE_READONLY (op2),
- TYPE_VOLATILE (op1) || TYPE_VOLATILE (op2));
+ type1 = cp_build_qualified_type
+ (type1, (CP_TYPE_QUALS (TREE_TYPE (op1))
+ | CP_TYPE_QUALS (TREE_TYPE (op2))));
/* ??? This is a kludge to deal with the fact that
we don't sort out integers and enums properly, yet. */
result = fold (build (COND_EXPR, type1, ifexp, op1, op2));
@@ -5180,7 +5143,7 @@ build_conditional_expr (ifexp, op1, op2)
if (code1 == RECORD_TYPE && code2 == RECORD_TYPE
&& real_lvalue_p (op1) && real_lvalue_p (op2)
- && comptypes (type1, type2, -1))
+ && comptypes (type1, type2, COMPARE_BASE | COMPARE_RELAXED))
{
type1 = build_reference_type (type1);
type2 = build_reference_type (type2);
@@ -5197,10 +5160,10 @@ build_conditional_expr (ifexp, op1, op2)
if (type1 == type2)
result_type = type1;
else
- result_type = cp_build_type_variant
- (type1,
- TREE_READONLY (op1) || TREE_READONLY (op2),
- TREE_THIS_VOLATILE (op1) || TREE_THIS_VOLATILE (op2));
+ result_type =
+ cp_build_qualified_type (type1,
+ CP_TYPE_QUALS (TREE_TYPE (op1))
+ | CP_TYPE_QUALS (TREE_TYPE (op2)));
}
else if ((code1 == INTEGER_TYPE || code1 == REAL_TYPE)
&& (code2 == INTEGER_TYPE || code2 == REAL_TYPE))
@@ -5234,7 +5197,7 @@ build_conditional_expr (ifexp, op1, op2)
result_type = qualify_type (type2, type1);
}
/* C++ */
- else if (comptypes (type2, type1, 0))
+ else if (same_or_base_type_p (type2, type1))
result_type = type2;
else if (IS_AGGR_TYPE (TREE_TYPE (type1))
&& IS_AGGR_TYPE (TREE_TYPE (type2))
@@ -5274,6 +5237,10 @@ build_conditional_expr (ifexp, op1, op2)
pedwarn ("pointer/integer type mismatch in conditional expression");
result_type = type2;
}
+ if (type2 == unknown_type_node)
+ result_type = type1;
+ else if (type1 == unknown_type_node)
+ result_type = type2;
if (!result_type)
{
@@ -5293,10 +5260,13 @@ build_conditional_expr (ifexp, op1, op2)
tree tmp;
if (code2 == POINTER_TYPE)
tmp = build_pointer_type
- (build_type_variant (TREE_TYPE (type2), 1, 1));
+ (cp_build_qualified_type (TREE_TYPE (type2),
+ TYPE_QUAL_CONST
+ | TYPE_QUAL_VOLATILE
+ | TYPE_QUAL_RESTRICT));
else
tmp = type2;
- tmp = build_type_conversion (CONVERT_EXPR, tmp, op1, 0);
+ tmp = build_type_conversion (tmp, op1, 0);
if (tmp == NULL_TREE)
{
cp_error ("incompatible types `%T' and `%T' in `?:'",
@@ -5315,11 +5285,14 @@ build_conditional_expr (ifexp, op1, op2)
tree tmp;
if (code1 == POINTER_TYPE)
tmp = build_pointer_type
- (build_type_variant (TREE_TYPE (type1), 1, 1));
+ (cp_build_qualified_type (TREE_TYPE (type1),
+ TYPE_QUAL_CONST
+ | TYPE_QUAL_VOLATILE
+ | TYPE_QUAL_RESTRICT));
else
tmp = type1;
- tmp = build_type_conversion (CONVERT_EXPR, tmp, op2, 0);
+ tmp = build_type_conversion (tmp, op2, 0);
if (tmp == NULL_TREE)
{
cp_error ("incompatible types `%T' and `%T' in `?:'",
@@ -5411,6 +5384,7 @@ build_compound_expr (list)
tree list;
{
register tree rest;
+ tree first;
if (TREE_READONLY_DECL_P (TREE_VALUE (list)))
TREE_VALUE (list) = decl_constant_value (TREE_VALUE (list));
@@ -5430,14 +5404,21 @@ build_compound_expr (list)
return TREE_VALUE (list);
}
+ first = TREE_VALUE (list);
+ first = require_complete_type_in_void (first);
+ if (first == error_mark_node)
+ return error_mark_node;
+
rest = build_compound_expr (TREE_CHAIN (list));
+ if (rest == error_mark_node)
+ return error_mark_node;
/* When pedantic, a compound expression cannot be a constant expression. */
- if (! TREE_SIDE_EFFECTS (TREE_VALUE (list)) && ! pedantic)
+ if (! TREE_SIDE_EFFECTS (first) && ! pedantic)
return rest;
return build (COMPOUND_EXPR, TREE_TYPE (rest),
- break_out_cleanups (TREE_VALUE (list)), rest);
+ break_out_cleanups (first), rest);
}
tree
@@ -5470,13 +5451,6 @@ build_static_cast (type, expr)
if (TREE_CODE (type) == VOID_TYPE)
return build1 (CONVERT_EXPR, type, expr);
- if (type_unknown_p (expr))
- {
- expr = instantiate_type (type, expr, 1);
- if (expr == error_mark_node)
- return error_mark_node;
- }
-
if (TREE_CODE (type) == REFERENCE_TYPE)
return (convert_from_reference
(convert_to_reference (type, expr, CONV_STATIC|CONV_IMPLICIT,
@@ -5500,22 +5474,18 @@ build_static_cast (type, expr)
{
tree binfo;
if (IS_AGGR_TYPE (TREE_TYPE (type)) && IS_AGGR_TYPE (TREE_TYPE (intype))
- && (TYPE_READONLY (TREE_TYPE (type))
- >= TYPE_READONLY (TREE_TYPE (intype)))
- && (TYPE_VOLATILE (TREE_TYPE (type))
- >= TYPE_VOLATILE (TREE_TYPE (intype)))
+ && at_least_as_qualified_p (TREE_TYPE (type),
+ TREE_TYPE (intype))
&& (binfo = get_binfo (TREE_TYPE (intype), TREE_TYPE (type), 0))
&& ! TREE_VIA_VIRTUAL (binfo))
ok = 1;
}
else if (TYPE_PTRMEM_P (type) && TYPE_PTRMEM_P (intype))
{
- if (comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (type))),
- TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (intype))), 1)
- && (TYPE_READONLY (TREE_TYPE (TREE_TYPE (type)))
- >= TYPE_READONLY (TREE_TYPE (TREE_TYPE (intype))))
- && (TYPE_VOLATILE (TREE_TYPE (TREE_TYPE (type)))
- >= TYPE_VOLATILE (TREE_TYPE (TREE_TYPE (intype))))
+ if (same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (type))),
+ TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (intype))))
+ && at_least_as_qualified_p (TREE_TYPE (TREE_TYPE (type)),
+ TREE_TYPE (TREE_TYPE (intype)))
&& (binfo = get_binfo (TYPE_OFFSET_BASETYPE (TREE_TYPE (type)),
TYPE_OFFSET_BASETYPE (TREE_TYPE (intype)), 0))
&& ! TREE_VIA_VIRTUAL (binfo))
@@ -5564,13 +5534,6 @@ build_reinterpret_cast (type, expr)
expr = TREE_OPERAND (expr, 0);
}
- if (type_unknown_p (expr))
- {
- expr = instantiate_type (type, expr, 1);
- if (expr == error_mark_node)
- return error_mark_node;
- }
-
intype = TREE_TYPE (expr);
if (TREE_CODE (type) == REFERENCE_TYPE)
@@ -5588,7 +5551,8 @@ build_reinterpret_cast (type, expr)
expr = build_indirect_ref (expr, 0);
return expr;
}
- else if (comptypes (TYPE_MAIN_VARIANT (intype), TYPE_MAIN_VARIANT (type), 1))
+ else if (same_type_p (TYPE_MAIN_VARIANT (intype),
+ TYPE_MAIN_VARIANT (type)))
return build_static_cast (type, expr);
if (TYPE_PTR_P (type) && (TREE_CODE (intype) == INTEGER_TYPE
@@ -5619,7 +5583,7 @@ build_reinterpret_cast (type, expr)
return fold (build1 (NOP_EXPR, type, expr));
}
else if ((TYPE_PTRFN_P (type) && TYPE_PTROBV_P (intype))
- || (TYPE_PTRFN_P (type) && TYPE_PTROBV_P (intype)))
+ || (TYPE_PTRFN_P (intype) && TYPE_PTROBV_P (type)))
{
pedwarn ("ANSI C++ forbids casting between pointers to functions and objects");
if (TREE_READONLY_DECL_P (expr))
@@ -5665,16 +5629,9 @@ build_const_cast (type, expr)
expr = TREE_OPERAND (expr, 0);
}
- if (type_unknown_p (expr))
- {
- expr = instantiate_type (type, expr, 1);
- if (expr == error_mark_node)
- return error_mark_node;
- }
-
intype = TREE_TYPE (expr);
- if (comptypes (TYPE_MAIN_VARIANT (intype), TYPE_MAIN_VARIANT (type), 1))
+ if (same_type_p (TYPE_MAIN_VARIANT (intype), TYPE_MAIN_VARIANT (type)))
return build_static_cast (type, expr);
else if (TREE_CODE (type) == REFERENCE_TYPE)
{
@@ -5710,6 +5667,7 @@ build_c_cast (type, expr)
tree type, expr;
{
register tree value = expr;
+ tree otype;
if (type == error_mark_node || expr == error_mark_node)
return error_mark_node;
@@ -5764,116 +5722,99 @@ build_c_cast (type, expr)
return t;
}
+ /* Convert functions and arrays to pointers and
+ convert references to their expanded types,
+ but don't convert any other types. If, however, we are
+ casting to a class type, there's no reason to do this: the
+ cast will only succeed if there is a converting constructor,
+ and the default conversions will be done at that point. In
+ fact, doing the default conversion here is actually harmful
+ in cases like this:
+
+ typedef int A[2];
+ struct S { S(const A&); };
+
+ since we don't want the array-to-pointer conversion done. */
+ if (!IS_AGGR_TYPE (type))
+ {
+ if (TREE_CODE (TREE_TYPE (value)) == FUNCTION_TYPE
+ || (TREE_CODE (TREE_TYPE (value)) == METHOD_TYPE
+ /* Don't do the default conversion on a ->* expression. */
+ && ! (TREE_CODE (type) == POINTER_TYPE
+ && bound_pmf_p (value)))
+ || TREE_CODE (TREE_TYPE (value)) == ARRAY_TYPE
+ || TREE_CODE (TREE_TYPE (value)) == REFERENCE_TYPE)
+ value = default_conversion (value);
+ }
+ else if (TREE_CODE (TREE_TYPE (value)) == REFERENCE_TYPE)
+ /* However, even for class types, we still need to strip away
+ the reference type, since the call to convert_force below
+ does not expect the input expression to be of reference
+ type. */
+ value = convert_from_reference (value);
+
+ otype = TREE_TYPE (value);
+
+ /* Optionally warn about potentially worrisome casts. */
+
+ if (warn_cast_qual
+ && TREE_CODE (type) == POINTER_TYPE
+ && TREE_CODE (otype) == POINTER_TYPE
+ && !at_least_as_qualified_p (TREE_TYPE (type),
+ TREE_TYPE (otype)))
+ cp_warning ("cast discards qualifiers from pointer target type");
+
+ /* Warn about possible alignment problems. */
+ if (STRICT_ALIGNMENT && warn_cast_align
+ && TREE_CODE (type) == POINTER_TYPE
+ && TREE_CODE (otype) == POINTER_TYPE
+ && TREE_CODE (TREE_TYPE (otype)) != VOID_TYPE
+ && TREE_CODE (TREE_TYPE (otype)) != FUNCTION_TYPE
+ && TYPE_ALIGN (TREE_TYPE (type)) > TYPE_ALIGN (TREE_TYPE (otype)))
+ warning ("cast increases required alignment of target type");
+
+#if 0
+ /* We should see about re-enabling these, they seem useful to
+ me. */
+ if (TREE_CODE (type) == INTEGER_TYPE
+ && TREE_CODE (otype) == POINTER_TYPE
+ && TYPE_PRECISION (type) != TYPE_PRECISION (otype))
+ warning ("cast from pointer to integer of different size");
+
+ if (TREE_CODE (type) == POINTER_TYPE
+ && TREE_CODE (otype) == INTEGER_TYPE
+ && TYPE_PRECISION (type) != TYPE_PRECISION (otype)
+ /* Don't warn about converting 0 to pointer,
+ provided the 0 was explicit--not cast or made by folding. */
+ && !(TREE_CODE (value) == INTEGER_CST && integer_zerop (value)))
+ warning ("cast to pointer from integer of different size");
+#endif
+
if (TREE_CODE (type) == VOID_TYPE)
- value = build1 (CONVERT_EXPR, type, value);
- else if (TREE_TYPE (value) == NULL_TREE
- || type_unknown_p (value))
{
- value = instantiate_type (type, value, 1);
- /* Did we lose? */
- if (value == error_mark_node)
- return error_mark_node;
+ value = require_complete_type_in_void (value);
+ if (value != error_mark_node)
+ value = build1 (CONVERT_EXPR, void_type_node, value);
}
+ else if (TREE_CODE (type) == REFERENCE_TYPE)
+ value = (convert_from_reference
+ (convert_to_reference (type, value, CONV_C_CAST,
+ LOOKUP_COMPLAIN, NULL_TREE)));
else
{
- tree otype;
-
- /* Convert functions and arrays to pointers and
- convert references to their expanded types,
- but don't convert any other types. If, however, we are
- casting to a class type, there's no reason to do this: the
- cast will only succeed if there is a converting constructor,
- and the default conversions will be done at that point. In
- fact, doing the default conversion here is actually harmful
- in cases like this:
-
- typedef int A[2];
- struct S { S(const A&); };
-
- since we don't want the array-to-pointer conversion done. */
- if (!IS_AGGR_TYPE (type))
- {
- if (TREE_CODE (TREE_TYPE (value)) == FUNCTION_TYPE
- || (TREE_CODE (TREE_TYPE (value)) == METHOD_TYPE
- /* Don't do the default conversion if we want a
- pointer to a function. */
- && ! (TREE_CODE (type) == POINTER_TYPE
- && TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE))
- || TREE_CODE (TREE_TYPE (value)) == ARRAY_TYPE
- || TREE_CODE (TREE_TYPE (value)) == REFERENCE_TYPE)
- value = default_conversion (value);
- }
- else if (TREE_CODE (TREE_TYPE (value)) == REFERENCE_TYPE)
- /* However, even for class types, we still need to strip away
- the reference type, since the call to convert_force below
- does not expect the input expression to be of reference
- type. */
- value = convert_from_reference (value);
-
- otype = TREE_TYPE (value);
+ tree ovalue;
- /* Optionally warn about potentially worrisome casts. */
-
- if (warn_cast_qual
- && TREE_CODE (type) == POINTER_TYPE
- && TREE_CODE (otype) == POINTER_TYPE)
- {
- /* For C++ we make these regular warnings, rather than
- softening them into pedwarns. */
- if (TYPE_VOLATILE (TREE_TYPE (otype))
- && ! TYPE_VOLATILE (TREE_TYPE (type)))
- warning ("cast discards `volatile' from pointer target type");
- if (TYPE_READONLY (TREE_TYPE (otype))
- && ! TYPE_READONLY (TREE_TYPE (type)))
- warning ("cast discards `const' from pointer target type");
- }
+ if (TREE_READONLY_DECL_P (value))
+ value = decl_constant_value (value);
- /* Warn about possible alignment problems. */
- if (STRICT_ALIGNMENT && warn_cast_align
- && TREE_CODE (type) == POINTER_TYPE
- && TREE_CODE (otype) == POINTER_TYPE
- && TREE_CODE (TREE_TYPE (otype)) != VOID_TYPE
- && TREE_CODE (TREE_TYPE (otype)) != FUNCTION_TYPE
- && TYPE_ALIGN (TREE_TYPE (type)) > TYPE_ALIGN (TREE_TYPE (otype)))
- warning ("cast increases required alignment of target type");
+ ovalue = value;
+ value = convert_force (type, value, CONV_C_CAST);
-#if 0
- /* We should see about re-enabling these, they seem useful to
- me. */
- if (TREE_CODE (type) == INTEGER_TYPE
- && TREE_CODE (otype) == POINTER_TYPE
- && TYPE_PRECISION (type) != TYPE_PRECISION (otype))
- warning ("cast from pointer to integer of different size");
-
- if (TREE_CODE (type) == POINTER_TYPE
- && TREE_CODE (otype) == INTEGER_TYPE
- && TYPE_PRECISION (type) != TYPE_PRECISION (otype)
- /* Don't warn about converting 0 to pointer,
- provided the 0 was explicit--not cast or made by folding. */
- && !(TREE_CODE (value) == INTEGER_CST && integer_zerop (value)))
- warning ("cast to pointer from integer of different size");
-#endif
-
- if (TREE_CODE (type) == REFERENCE_TYPE)
- value = (convert_from_reference
- (convert_to_reference (type, value, CONV_C_CAST,
- LOOKUP_COMPLAIN, NULL_TREE)));
- else
+ /* Ignore any integer overflow caused by the cast. */
+ if (TREE_CODE (value) == INTEGER_CST)
{
- tree ovalue;
-
- if (TREE_READONLY_DECL_P (value))
- value = decl_constant_value (value);
-
- ovalue = value;
- value = convert_force (type, value, CONV_C_CAST);
-
- /* Ignore any integer overflow caused by the cast. */
- if (TREE_CODE (value) == INTEGER_CST)
- {
- TREE_OVERFLOW (value) = TREE_OVERFLOW (ovalue);
- TREE_CONSTANT_OVERFLOW (value) = TREE_CONSTANT_OVERFLOW (ovalue);
- }
+ TREE_OVERFLOW (value) = TREE_OVERFLOW (ovalue);
+ TREE_CONSTANT_OVERFLOW (value) = TREE_CONSTANT_OVERFLOW (ovalue);
}
}
@@ -6000,6 +5941,9 @@ build_modify_expr (lhs, modifycode, rhs)
olhstype = lhstype = TREE_TYPE (lhs);
}
+ if (lhs == error_mark_node)
+ return lhs;
+
if (TREE_CODE (lhstype) == REFERENCE_TYPE
&& modifycode != INIT_EXPR)
{
@@ -6113,7 +6057,7 @@ build_modify_expr (lhs, modifycode, rhs)
&& ! (TREE_CODE (lhs) == COMPONENT_REF
&& (IS_SIGNATURE_POINTER (TREE_TYPE (TREE_OPERAND (lhs, 0)))
|| IS_SIGNATURE_REFERENCE (TREE_TYPE (TREE_OPERAND (lhs, 0)))))
- && (TREE_READONLY (lhs) || TYPE_READONLY (lhstype)
+ && (TREE_READONLY (lhs) || CP_TYPE_CONST_P (lhstype)
/* Functions are not modifiable, even though they are
lvalues. */
|| TREE_CODE (TREE_TYPE (lhs)) == FUNCTION_TYPE
@@ -6121,7 +6065,7 @@ build_modify_expr (lhs, modifycode, rhs)
|| TREE_CODE (lhstype) == UNION_TYPE)
&& C_TYPE_FIELDS_READONLY (lhstype))
|| (TREE_CODE (lhstype) == REFERENCE_TYPE
- && TYPE_READONLY (TREE_TYPE (lhstype)))))
+ && CP_TYPE_CONST_P (TREE_TYPE (lhstype)))))
readonly_error (lhs, "assignment", 0);
/* If storing into a structure or union member,
@@ -6157,14 +6101,6 @@ build_modify_expr (lhs, modifycode, rhs)
current_function_just_assigned_this = 1;
}
- /* The TREE_TYPE of RHS may be TYPE_UNKNOWN. This can happen
- when the type of RHS is not yet known, i.e. its type
- is inherited from LHS. */
- rhs = require_instantiated_type (lhstype, newrhs, error_mark_node);
- if (rhs == error_mark_node)
- return error_mark_node;
- newrhs = rhs;
-
if (modifycode != INIT_EXPR)
{
/* Make modifycode now either a NOP_EXPR or an INIT_EXPR. */
@@ -6205,7 +6141,7 @@ build_modify_expr (lhs, modifycode, rhs)
{
int from_array;
- if (! comptypes (lhstype, TREE_TYPE (rhs), 0))
+ if (!same_or_base_type_p (lhstype, TREE_TYPE (rhs)))
{
cp_error ("incompatible types in assignment of `%T' to `%T'",
TREE_TYPE (rhs), lhstype);
@@ -6435,7 +6371,7 @@ get_delta_difference (from, to, force)
return BINFO_OFFSET (binfo);
}
-static tree
+tree
build_ptrmemfunc1 (type, delta, idx, pfn, delta2)
tree type, delta, idx, pfn, delta2;
{
@@ -6527,9 +6463,9 @@ build_ptrmemfunc (type, pfn, force)
tree idx = integer_zero_node;
tree delta = integer_zero_node;
tree delta2 = integer_zero_node;
- tree vfield_offset;
tree npfn = NULL_TREE;
-
+ tree fn;
+
/* Handle multiple conversions of pointer to member functions. */
if (TYPE_PTRMEMFUNC_P (TREE_TYPE (pfn)))
{
@@ -6579,55 +6515,116 @@ build_ptrmemfunc (type, pfn, force)
pfn, NULL_TREE);
}
- if (TREE_CODE (pfn) == TREE_LIST
- || (TREE_CODE (pfn) == ADDR_EXPR
- && TREE_CODE (TREE_OPERAND (pfn, 0)) == TREE_LIST))
+ if (type_unknown_p (pfn))
return instantiate_type (type, pfn, 1);
- if (!force
- && comp_target_types (type, TREE_TYPE (pfn), 0) != 1)
- cp_error ("conversion to `%T' from `%T'", type, TREE_TYPE (pfn));
-
- /* Allow pointer to member conversions here. */
- delta = get_delta_difference (TYPE_METHOD_BASETYPE (TREE_TYPE (TREE_TYPE (pfn))),
- TYPE_METHOD_BASETYPE (TREE_TYPE (type)),
- force);
- delta2 = build_binary_op (PLUS_EXPR, delta2, delta, 1);
+ fn = TREE_OPERAND (pfn, 0);
+ my_friendly_assert (TREE_CODE (fn) == FUNCTION_DECL, 0);
+ npfn = make_node (PTRMEM_CST);
+ TREE_TYPE (npfn) = build_ptrmemfunc_type (type);
+ PTRMEM_CST_MEMBER (npfn) = fn;
+ return npfn;
+}
- if (TREE_CODE (TREE_OPERAND (pfn, 0)) != FUNCTION_DECL)
- warning ("assuming pointer to member function is non-virtual");
+/* Return the DELTA, IDX, PFN, and DELTA2 values for the PTRMEM_CST
+ given by CST. */
- if (TREE_CODE (TREE_OPERAND (pfn, 0)) == FUNCTION_DECL
- && DECL_VINDEX (TREE_OPERAND (pfn, 0)))
- {
- /* Find the offset to the vfield pointer in the object. */
- vfield_offset = get_binfo (DECL_CONTEXT (TREE_OPERAND (pfn, 0)),
- DECL_CLASS_CONTEXT (TREE_OPERAND (pfn, 0)),
- 0);
- vfield_offset = get_vfield_offset (vfield_offset);
- delta2 = size_binop (PLUS_EXPR, vfield_offset, delta2);
+void
+expand_ptrmemfunc_cst (cst, delta, idx, pfn, delta2)
+ tree cst;
+ tree *delta;
+ tree *idx;
+ tree *pfn;
+ tree *delta2;
+{
+ tree type = TREE_TYPE (cst);
+ tree fn = PTRMEM_CST_MEMBER (cst);
- /* Map everything down one to make room for the null pointer to member. */
- idx = size_binop (PLUS_EXPR,
- DECL_VINDEX (TREE_OPERAND (pfn, 0)),
- integer_one_node);
+ my_friendly_assert (TREE_CODE (fn) == FUNCTION_DECL, 0);
+
+ *delta
+ = get_delta_difference (TYPE_METHOD_BASETYPE
+ (TREE_TYPE (fn)),
+ TYPE_PTRMEMFUNC_OBJECT_TYPE (type),
+ /*force=*/0);
+ if (!DECL_VIRTUAL_P (fn))
+ {
+ *idx = size_binop (MINUS_EXPR, integer_zero_node,
+ integer_one_node);
+ *pfn = build_addr_func (fn);
+ if (!same_type_p (TYPE_METHOD_BASETYPE (TREE_TYPE (fn)),
+ TYPE_PTRMEMFUNC_OBJECT_TYPE (type)))
+ *pfn = build1 (NOP_EXPR, TYPE_PTRMEMFUNC_FN_TYPE (type),
+ *pfn);
+ *delta2 = NULL_TREE;
}
else
{
- idx = size_binop (MINUS_EXPR, integer_zero_node, integer_one_node);
+ *idx = size_binop (PLUS_EXPR, DECL_VINDEX (fn),
+ integer_one_node);
+ *pfn = NULL_TREE;
+ *delta2 = get_binfo (DECL_CONTEXT (fn),
+ DECL_CLASS_CONTEXT (fn),
+ 0);
+ *delta2 = get_vfield_offset (*delta2);
+ *delta2 = size_binop (PLUS_EXPR, *delta2,
+ build_binary_op (PLUS_EXPR,
+ *delta,
+ integer_zero_node,
+ 1));
+ }
+}
- if (type == TREE_TYPE (pfn))
- {
- npfn = pfn;
- }
- else
- {
- npfn = build1 (NOP_EXPR, type, pfn);
- TREE_CONSTANT (npfn) = TREE_CONSTANT (pfn);
- }
+/* Return an expression for DELTA2 from the pointer-to-member function
+ given by T. */
+
+tree
+delta2_from_ptrmemfunc (t)
+ tree t;
+{
+ if (TREE_CODE (t) == PTRMEM_CST)
+ {
+ tree delta;
+ tree idx;
+ tree pfn;
+ tree delta2;
+
+ expand_ptrmemfunc_cst (t, &delta, &idx, &pfn, &delta2);
+ if (delta2)
+ return delta2;
+ }
+
+ return (build_component_ref
+ (build_component_ref (t,
+ pfn_or_delta2_identifier, NULL_TREE,
+ 0),
+ delta2_identifier, NULL_TREE, 0));
+}
+
+/* Return an expression for PFN from the pointer-to-member function
+ given by T. */
+
+tree
+pfn_from_ptrmemfunc (t)
+ tree t;
+{
+ if (TREE_CODE (t) == PTRMEM_CST)
+ {
+ tree delta;
+ tree idx;
+ tree pfn;
+ tree delta2;
+
+ expand_ptrmemfunc_cst (t, &delta, &idx, &pfn, &delta2);
+ if (pfn)
+ return pfn;
}
- return build_ptrmemfunc1 (TYPE_GET_PTRMEMFUNC_TYPE (type), delta, idx, npfn, delta2);
+ return (build_component_ref
+ (build_component_ref (t,
+ pfn_or_delta2_identifier, NULL_TREE,
+ 0),
+ pfn_identifier, NULL_TREE, 0));
}
/* Convert value RHS to type TYPE as preparation for an assignment
@@ -6646,7 +6643,7 @@ build_ptrmemfunc (type, pfn, force)
static tree
convert_for_assignment (type, rhs, errtype, fndecl, parmnum)
tree type, rhs;
- char *errtype;
+ const char *errtype;
tree fndecl;
int parmnum;
{
@@ -6658,9 +6655,6 @@ convert_for_assignment (type, rhs, errtype, fndecl, parmnum)
if (ARITHMETIC_TYPE_P (type) && rhs == null_node)
cp_warning ("converting NULL to non-pointer type");
- if (coder == UNKNOWN_TYPE)
- rhs = instantiate_type (type, rhs, 1);
-
if (coder == ERROR_MARK)
return error_mark_node;
@@ -6690,12 +6684,17 @@ convert_for_assignment (type, rhs, errtype, fndecl, parmnum)
}
if (TREE_CODE (TREE_TYPE (rhs)) == ARRAY_TYPE
- || TREE_CODE (TREE_TYPE (rhs)) == FUNCTION_TYPE
- || TREE_CODE (TREE_TYPE (rhs)) == METHOD_TYPE)
+ || is_overloaded_fn (rhs))
rhs = default_conversion (rhs);
else if (TREE_CODE (TREE_TYPE (rhs)) == REFERENCE_TYPE)
rhs = convert_from_reference (rhs);
+ /* If rhs is some sort of overloaded function, ocp_convert will either
+ do the right thing or complain; we don't need to check anything else.
+ So just hand off. */
+ if (type_unknown_p (rhs))
+ return ocp_convert (type, rhs, CONV_IMPLICIT, LOOKUP_NORMAL);
+
rhstype = TREE_TYPE (rhs);
coder = TREE_CODE (rhstype);
@@ -6705,7 +6704,7 @@ convert_for_assignment (type, rhs, errtype, fndecl, parmnum)
else if (TREE_READONLY_DECL_P (rhs))
rhs = decl_constant_value (rhs);
- if (comptypes (type, rhstype, 1))
+ if (same_type_p (type, rhstype))
{
overflow_warning (rhs);
return rhs;
@@ -6797,23 +6796,14 @@ convert_for_assignment (type, rhs, errtype, fndecl, parmnum)
if (binfo == 0)
return error_not_base_type (ttl, ttr);
- if (! TYPE_READONLY (ttl) && TYPE_READONLY (ttr))
- {
- if (fndecl)
- cp_error ("passing `%T' as argument %P of `%D' discards const",
- rhstype, parmnum, fndecl);
- else
- cp_error ("%s to `%T' from `%T' discards const",
- errtype, type, rhstype);
- }
- if (! TYPE_VOLATILE (ttl) && TYPE_VOLATILE (ttr))
+ if (!at_least_as_qualified_p (ttl, ttr))
{
if (fndecl)
- cp_error ("passing `%T' as argument %P of `%D' discards volatile",
- rhstype, parmnum, fndecl);
+ cp_pedwarn ("passing `%T' as argument %P of `%D' discards qualifiers",
+ rhstype, parmnum, fndecl);
else
- cp_error ("%s to `%T' from `%T' discards volatile",
- errtype, type, rhstype);
+ cp_pedwarn ("%s to `%T' from `%T' discards qualifiers",
+ errtype, type, rhstype);
}
}
@@ -6861,24 +6851,15 @@ convert_for_assignment (type, rhs, errtype, fndecl, parmnum)
error ("%s between pointer to members converting across virtual baseclasses", errtype);
return error_mark_node;
}
- else if (! TYPE_READONLY (ttl) && TYPE_READONLY (ttr))
+ else if (!at_least_as_qualified_p (ttl, ttr))
{
if (string_conv_p (type, rhs, 1))
/* converting from string constant to char *, OK. */;
else if (fndecl)
- cp_error ("passing `%T' as argument %P of `%D' discards const",
- rhstype, parmnum, fndecl);
- else
- cp_error ("%s to `%T' from `%T' discards const",
- errtype, type, rhstype);
- }
- else if (! TYPE_VOLATILE (ttl) && TYPE_VOLATILE (ttr))
- {
- if (fndecl)
- cp_error ("passing `%T' as argument %P of `%D' discards volatile",
+ cp_pedwarn ("passing `%T' as argument %P of `%D' discards qualifiers",
rhstype, parmnum, fndecl);
else
- cp_error ("%s to `%T' from `%T' discards volatile",
+ cp_pedwarn ("%s to `%T' from `%T' discards qualifiers",
errtype, type, rhstype);
}
else if (TREE_CODE (ttl) == TREE_CODE (ttr)
@@ -6895,7 +6876,8 @@ convert_for_assignment (type, rhs, errtype, fndecl, parmnum)
}
else
{
- int add_quals = 0, const_parity = 0, volatile_parity = 0;
+ int add_quals = 0;
+ int drops_quals = 0;
int left_const = 1;
int unsigned_parity;
int nptrs = 0;
@@ -6904,12 +6886,10 @@ convert_for_assignment (type, rhs, errtype, fndecl, parmnum)
for (; ; ttl = TREE_TYPE (ttl), ttr = TREE_TYPE (ttr))
{
nptrs -= 1;
- const_parity |= (TYPE_READONLY (ttl) < TYPE_READONLY (ttr));
- volatile_parity |= (TYPE_VOLATILE (ttl) < TYPE_VOLATILE (ttr));
+ drops_quals |= !at_least_as_qualified_p (ttl, ttr);
if (! left_const
- && (TYPE_READONLY (ttl) > TYPE_READONLY (ttr)
- || TYPE_VOLATILE (ttl) > TYPE_VOLATILE (ttr)))
+ && !at_least_as_qualified_p (ttr, ttl))
add_quals = 1;
left_const &= TYPE_READONLY (ttl);
@@ -6937,24 +6917,15 @@ convert_for_assignment (type, rhs, errtype, fndecl, parmnum)
cp_pedwarn ("%s to `%T' from `%T' adds cv-quals without intervening `const'",
errtype, type, rhstype);
}
- if (const_parity)
+ if (drops_quals)
{
if (fndecl)
- cp_error ("passing `%T' as argument %P of `%D' discards const",
- rhstype, parmnum, fndecl);
+ cp_pedwarn ("passing `%T' as argument %P of `%D' discards qualifiers",
+ rhstype, parmnum, fndecl);
else
- cp_error ("%s to `%T' from `%T' discards const",
+ cp_pedwarn ("%s to `%T' from `%T' discards qualifiers",
errtype, type, rhstype);
}
- if (volatile_parity)
- {
- if (fndecl)
- cp_error ("passing `%T' as argument %P of `%D' discards volatile",
- rhstype, parmnum, fndecl);
- else
- cp_error ("%s to `%T' from `%T' discards volatile",
- errtype, type, rhstype);
- }
if (unsigned_parity > 0)
{
if (fndecl)
@@ -6978,7 +6949,7 @@ convert_for_assignment (type, rhs, errtype, fndecl, parmnum)
member function pointers as C. Emit warnings here. */
if (TREE_CODE (ttl) == FUNCTION_TYPE
|| TREE_CODE (ttl) == METHOD_TYPE)
- if (! comptypes (ttl, ttr, 0))
+ if (!same_or_base_type_p (ttl, ttr))
{
warning ("conflicting function types in %s:", errtype);
cp_warning ("\t`%T' != `%T'", type, rhstype);
@@ -6996,7 +6967,9 @@ convert_for_assignment (type, rhs, errtype, fndecl, parmnum)
}
return cp_convert (type, rhs);
}
- else if (codel == POINTER_TYPE && coder == INTEGER_TYPE)
+ else if (codel == POINTER_TYPE
+ && (coder == INTEGER_TYPE
+ || coder == BOOLEAN_TYPE))
{
/* An explicit constant 0 can convert to a pointer,
but not a 0 that results from casting or folding. */
@@ -7105,7 +7078,7 @@ tree
convert_for_initialization (exp, type, rhs, flags, errtype, fndecl, parmnum)
tree exp, type, rhs;
int flags;
- char *errtype;
+ const char *errtype;
tree fndecl;
int parmnum;
{
@@ -7138,20 +7111,15 @@ convert_for_initialization (exp, type, rhs, flags, errtype, fndecl, parmnum)
&& TREE_CODE (type) != ARRAY_TYPE
&& (TREE_CODE (type) != REFERENCE_TYPE
|| TREE_CODE (TREE_TYPE (type)) != ARRAY_TYPE))
- || TREE_CODE (TREE_TYPE (rhs)) == FUNCTION_TYPE
+ || (TREE_CODE (TREE_TYPE (rhs)) == FUNCTION_TYPE
+ && (TREE_CODE (type) != REFERENCE_TYPE
+ || TREE_CODE (TREE_TYPE (type)) != FUNCTION_TYPE))
|| TREE_CODE (TREE_TYPE (rhs)) == METHOD_TYPE)
rhs = default_conversion (rhs);
rhstype = TREE_TYPE (rhs);
coder = TREE_CODE (rhstype);
- if (coder == UNKNOWN_TYPE)
- {
- rhs = instantiate_type (type, rhs, 1);
- rhstype = TREE_TYPE (rhs);
- coder = TREE_CODE (rhstype);
- }
-
if (coder == ERROR_MARK)
return error_mark_node;
@@ -7178,11 +7146,8 @@ convert_for_initialization (exp, type, rhs, flags, errtype, fndecl, parmnum)
return rhs;
}
- rhs = require_complete_type (rhs);
- if (rhs == error_mark_node)
- return error_mark_node;
-
- if (exp != 0) exp = require_complete_type (exp);
+ if (exp != 0)
+ exp = require_complete_type (exp);
if (exp == error_mark_node)
return error_mark_node;
@@ -7261,7 +7226,7 @@ c_expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line)
else
{
tree type = TREE_TYPE (o[i]);
- if (TYPE_READONLY (type)
+ if (CP_TYPE_CONST_P (type)
|| ((TREE_CODE (type) == RECORD_TYPE
|| TREE_CODE (type) == UNION_TYPE)
&& C_TYPE_FIELDS_READONLY (type)))
@@ -7381,7 +7346,7 @@ c_expand_return (retval)
if (retval == result
|| DECL_CONSTRUCTOR_P (current_function_decl))
/* It's already done for us. */;
- else if (TREE_TYPE (retval) == void_type_node)
+ else if (TREE_CODE (TREE_TYPE (retval)) == VOID_TYPE)
{
pedwarn ("return of void value in function returning non-void");
expand_expr_stmt (retval);
@@ -7449,9 +7414,9 @@ c_expand_return (retval)
if (TEMP_NAME_P (DECL_NAME (whats_returned)))
warning ("reference to non-lvalue returned");
else if (TREE_CODE (TREE_TYPE (whats_returned)) != REFERENCE_TYPE
- && ! TREE_STATIC (whats_returned)
- && IDENTIFIER_LOCAL_VALUE (DECL_NAME (whats_returned))
- && !TREE_PUBLIC (whats_returned))
+ && DECL_FUNCTION_SCOPE_P (whats_returned)
+ && !(TREE_STATIC (whats_returned)
+ || TREE_PUBLIC (whats_returned)))
cp_warning_at ("reference to local variable `%D' returned", whats_returned);
}
}
@@ -7461,9 +7426,9 @@ c_expand_return (retval)
if (TREE_CODE (whats_returned) == VAR_DECL
&& DECL_NAME (whats_returned)
- && IDENTIFIER_LOCAL_VALUE (DECL_NAME (whats_returned))
- && !TREE_STATIC (whats_returned)
- && !TREE_PUBLIC (whats_returned))
+ && DECL_FUNCTION_SCOPE_P (whats_returned)
+ && !(TREE_STATIC (whats_returned)
+ || TREE_PUBLIC (whats_returned)))
cp_warning_at ("address of local variable `%D' returned", whats_returned);
}
}
@@ -7501,45 +7466,26 @@ tree
c_expand_start_case (exp)
tree exp;
{
- tree type;
- register enum tree_code code;
-
- /* Convert from references, etc. */
- exp = default_conversion (exp);
- type = TREE_TYPE (exp);
- code = TREE_CODE (type);
-
- if (IS_AGGR_TYPE_CODE (code))
- exp = build_type_conversion (CONVERT_EXPR, integer_type_node, exp, 1);
+ tree type, idx;
+ exp = build_expr_type_conversion (WANT_INT | WANT_ENUM, exp, 1);
if (exp == NULL_TREE)
{
error ("switch quantity not an integer");
exp = error_mark_node;
}
- type = TREE_TYPE (exp);
- code = TREE_CODE (type);
-
- if (code != INTEGER_TYPE && code != ENUMERAL_TYPE && code != ERROR_MARK)
- {
- error ("switch quantity not an integer");
- exp = error_mark_node;
- }
- else
- {
- tree idx;
+ if (exp == error_mark_node)
+ return error_mark_node;
- exp = default_conversion (exp);
- type = TREE_TYPE (exp);
- idx = get_unwidened (exp, 0);
- /* We can't strip a conversion from a signed type to an unsigned,
- because if we did, int_fits_type_p would do the wrong thing
- when checking case values for being in range,
- and it's too hard to do the right thing. */
- if (TREE_UNSIGNED (TREE_TYPE (exp))
- == TREE_UNSIGNED (TREE_TYPE (idx)))
- exp = idx;
- }
+ exp = default_conversion (exp);
+ type = TREE_TYPE (exp);
+ idx = get_unwidened (exp, 0);
+ /* We can't strip a conversion from a signed type to an unsigned,
+ because if we did, int_fits_type_p would do the wrong thing
+ when checking case values for being in range,
+ and it's too hard to do the right thing. */
+ if (TREE_UNSIGNED (TREE_TYPE (exp)) == TREE_UNSIGNED (TREE_TYPE (idx)))
+ exp = idx;
expand_start_case
(1, fold (build1 (CLEANUP_POINT_EXPR, TREE_TYPE (exp), exp)),
@@ -7569,20 +7515,18 @@ comp_ptr_ttypes_real (to, from, constp)
return 0;
if (TREE_CODE (from) == OFFSET_TYPE
- && comptypes (TYPE_OFFSET_BASETYPE (from),
- TYPE_OFFSET_BASETYPE (to), 1))
+ && same_type_p (TYPE_OFFSET_BASETYPE (from),
+ TYPE_OFFSET_BASETYPE (to)))
continue;
/* Const and volatile mean something different for function types,
so the usual checks are not appropriate. */
if (TREE_CODE (to) != FUNCTION_TYPE && TREE_CODE (to) != METHOD_TYPE)
{
- if (TYPE_READONLY (from) > TYPE_READONLY (to)
- || TYPE_VOLATILE (from) > TYPE_VOLATILE (to))
+ if (!at_least_as_qualified_p (to, from))
return 0;
- if (TYPE_READONLY (to) > TYPE_READONLY (from)
- || TYPE_VOLATILE (to) > TYPE_VOLATILE (from))
+ if (!at_least_as_qualified_p (from, to))
{
if (constp == 0)
return 0;
@@ -7596,7 +7540,7 @@ comp_ptr_ttypes_real (to, from, constp)
if (TREE_CODE (to) != POINTER_TYPE)
return
- comptypes (TYPE_MAIN_VARIANT (to), TYPE_MAIN_VARIANT (from), 1)
+ same_type_p (TYPE_MAIN_VARIANT (to), TYPE_MAIN_VARIANT (from))
&& (constp >= 0 || to_more_cv_qualified);
}
}
@@ -7626,12 +7570,14 @@ ptr_reasonably_similar (to, from)
if (TREE_CODE (from) == OFFSET_TYPE
&& comptypes (TYPE_OFFSET_BASETYPE (to),
- TYPE_OFFSET_BASETYPE (from), -1))
+ TYPE_OFFSET_BASETYPE (from),
+ COMPARE_BASE | COMPARE_RELAXED))
continue;
if (TREE_CODE (to) != POINTER_TYPE)
return comptypes
- (TYPE_MAIN_VARIANT (to), TYPE_MAIN_VARIANT (from), -1);
+ (TYPE_MAIN_VARIANT (to), TYPE_MAIN_VARIANT (from),
+ COMPARE_BASE | COMPARE_RELAXED);
}
}
@@ -7647,12 +7593,13 @@ comp_ptr_ttypes_const (to, from)
return 0;
if (TREE_CODE (from) == OFFSET_TYPE
- && comptypes (TYPE_OFFSET_BASETYPE (from),
- TYPE_OFFSET_BASETYPE (to), 1))
+ && same_type_p (TYPE_OFFSET_BASETYPE (from),
+ TYPE_OFFSET_BASETYPE (to)))
continue;
if (TREE_CODE (to) != POINTER_TYPE)
- return comptypes (TYPE_MAIN_VARIANT (to), TYPE_MAIN_VARIANT (from), 1);
+ return same_type_p (TYPE_MAIN_VARIANT (to),
+ TYPE_MAIN_VARIANT (from));
}
}
@@ -7671,25 +7618,46 @@ comp_ptr_ttypes_reinterpret (to, from)
if (TREE_CODE (to) == OFFSET_TYPE)
to = TREE_TYPE (to);
- if (TREE_CODE (to) != TREE_CODE (from))
- return 1;
-
/* Const and volatile mean something different for function types,
so the usual checks are not appropriate. */
- if (TREE_CODE (to) != FUNCTION_TYPE && TREE_CODE (to) != METHOD_TYPE)
+ if (TREE_CODE (from) != FUNCTION_TYPE && TREE_CODE (from) != METHOD_TYPE
+ && TREE_CODE (to) != FUNCTION_TYPE && TREE_CODE (to) != METHOD_TYPE)
{
- if (TYPE_READONLY (from) > TYPE_READONLY (to)
- || TYPE_VOLATILE (from) > TYPE_VOLATILE (to))
+ if (!at_least_as_qualified_p (to, from))
return 0;
if (! constp
- && (TYPE_READONLY (to) > TYPE_READONLY (from)
- || TYPE_VOLATILE (to) > TYPE_READONLY (from)))
+ && !at_least_as_qualified_p (from, to))
return 0;
constp &= TYPE_READONLY (to);
}
- if (TREE_CODE (to) != POINTER_TYPE)
+ if (TREE_CODE (from) != POINTER_TYPE
+ || TREE_CODE (to) != POINTER_TYPE)
return 1;
}
}
+
+/* Returns the type-qualifier set corresponding to TYPE. */
+
+int
+cp_type_quals (type)
+ tree type;
+{
+ while (TREE_CODE (type) == ARRAY_TYPE)
+ type = TREE_TYPE (type);
+
+ return TYPE_QUALS (type);
+}
+
+/* Returns non-zero if the TYPE contains a mutable member */
+
+int
+cp_has_mutable_p (type)
+ tree type;
+{
+ while (TREE_CODE (type) == ARRAY_TYPE)
+ type = TREE_TYPE (type);
+
+ return CLASS_TYPE_P (type) && CLASSTYPE_HAS_MUTABLE (type);
+}
diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c
index a00a4f13ffc..76a30b202d6 100644
--- a/gcc/cp/typeck2.c
+++ b/gcc/cp/typeck2.c
@@ -1,6 +1,6 @@
/* Report error messages, build initializers, and perform
some front-end optimizations for C++ compiler.
- Copyright (C) 1987, 88, 89, 92, 93, 94, 1995 Free Software Foundation, Inc.
+ Copyright (C) 1987, 88, 89, 92-98, 1999 Free Software Foundation, Inc.
Hacked by Michael Tiemann (tiemann@cygnus.com)
This file is part of GNU CC.
@@ -38,6 +38,7 @@ Boston, MA 02111-1307, USA. */
#include "toplev.h"
static tree process_init_constructor PROTO((tree, tree, tree *));
+static void ack PVPROTO ((const char *, ...)) ATTRIBUTE_PRINTF_1;
extern int errorcount;
extern int sorrycount;
@@ -80,11 +81,11 @@ binfo_or_else (parent_or_type, type)
void
readonly_error (arg, string, soft)
tree arg;
- char *string;
+ const char *string;
int soft;
{
- char *fmt;
- void (*fn)();
+ const char *fmt;
+ void (*fn) PVPROTO ((const char *, ...));
if (soft)
fn = cp_pedwarn;
@@ -133,30 +134,8 @@ abstract_virtuals_error (decl, type)
tree type;
{
tree u = CLASSTYPE_ABSTRACT_VIRTUALS (type);
- int has_abstract_virtuals, needs_final_overriders;
tree tu;
- /* Count how many abstract methods need to be defined. */
- for (has_abstract_virtuals = 0, tu = u; tu; tu = TREE_CHAIN (tu))
- {
- if (DECL_ABSTRACT_VIRTUAL_P (TREE_VALUE (tu))
- && ! DECL_NEEDS_FINAL_OVERRIDER_P (TREE_VALUE (tu)))
- {
- has_abstract_virtuals = 1;
- break;
- }
- }
-
- /* Count how many virtual methods need a final overrider. */
- for (needs_final_overriders = 0, tu = u; tu; tu = TREE_CHAIN (tu))
- {
- if (DECL_NEEDS_FINAL_OVERRIDER_P (TREE_VALUE (tu)))
- {
- needs_final_overriders = 1;
- break;
- }
- }
-
if (decl)
{
if (TREE_CODE (decl) == RESULT_DECL)
@@ -185,44 +164,12 @@ abstract_virtuals_error (decl, type)
{
TREE_PURPOSE (u) = error_mark_node;
- if (has_abstract_virtuals)
- error (" since the following virtual functions are abstract:");
- tu = u;
- while (tu)
- {
- if (DECL_ABSTRACT_VIRTUAL_P (TREE_VALUE (tu))
- && ! DECL_NEEDS_FINAL_OVERRIDER_P (TREE_VALUE (tu)))
- cp_error ("\t%#D", TREE_VALUE (tu));
- tu = TREE_CHAIN (tu);
- }
-
- if (needs_final_overriders)
- {
- if (has_abstract_virtuals)
- error (" and the following virtual functions need a final overrider:");
- else
- error (" since the following virtual functions need a final overrider:");
- }
- tu = u;
- while (tu)
- {
- if (DECL_NEEDS_FINAL_OVERRIDER_P (TREE_VALUE (tu)))
- cp_error ("\t%#D", TREE_VALUE (tu));
- tu = TREE_CHAIN (tu);
- }
+ error (" since the following virtual functions are abstract:");
+ for (tu = u; tu; tu = TREE_CHAIN (tu))
+ cp_error_at ("\t%#D", TREE_VALUE (tu));
}
else
- {
- if (has_abstract_virtuals)
- {
- if (needs_final_overriders)
- cp_error (" since type `%T' has abstract virtual functions and must override virtual functions", type);
- else
- cp_error (" since type `%T' has abstract virtual functions", type);
- }
- else
- cp_error (" since type `%T' must override virtual functions", type);
- }
+ cp_error (" since type `%T' has abstract virtual functions", type);
}
/* Print an error message for invalid use of a signature type.
@@ -267,73 +214,89 @@ incomplete_type_error (value, type)
tree value;
tree type;
{
- char *errmsg = 0;
-
/* Avoid duplicate error message. */
if (TREE_CODE (type) == ERROR_MARK)
return;
- if (value != 0 && (TREE_CODE (value) == VAR_DECL
- || TREE_CODE (value) == PARM_DECL))
- cp_error ("`%D' has incomplete type", value);
- else
- {
- retry:
- /* We must print an error message. Be clever about what it says. */
-
- switch (TREE_CODE (type))
- {
- case RECORD_TYPE:
- case UNION_TYPE:
- case ENUMERAL_TYPE:
- errmsg = "invalid use of undefined type `%#T'";
- break;
+retry:
+ /* We must print an error message. Be clever about what it says. */
- case VOID_TYPE:
- error ("invalid use of void expression");
- return;
+ switch (TREE_CODE (type))
+ {
+ case RECORD_TYPE:
+ case UNION_TYPE:
+ case ENUMERAL_TYPE:
+ cp_error ("invalid use of undefined type `%#T'", type);
+ cp_error_at ("forward declaration of `%#T'", type);
+ break;
- case ARRAY_TYPE:
- if (TYPE_DOMAIN (type))
- {
- type = TREE_TYPE (type);
- goto retry;
- }
- error ("invalid use of array with unspecified bounds");
- return;
+ case VOID_TYPE:
+ cp_error ("invalid use of void expression");
+ break;
- case OFFSET_TYPE:
- error ("invalid use of member type (did you forget the `&' ?)");
- return;
+ case ARRAY_TYPE:
+ if (TYPE_DOMAIN (type))
+ {
+ type = TREE_TYPE (type);
+ goto retry;
+ }
+ cp_error ("invalid use of array with unspecified bounds");
+ break;
- case TEMPLATE_TYPE_PARM:
- error ("invalid use of template type parameter");
- return;
+ case OFFSET_TYPE:
+ bad_member:
+ cp_error ("invalid use of member (did you forget the `&' ?)");
+ break;
- default:
- my_friendly_abort (108);
- }
+ case TEMPLATE_TYPE_PARM:
+ cp_error ("invalid use of template type parameter");
+ break;
- cp_error (errmsg, type);
+ case UNKNOWN_TYPE:
+ if (value && TREE_CODE (value) == COMPONENT_REF)
+ goto bad_member;
+ else if (value && TREE_CODE (value) == ADDR_EXPR)
+ cp_error ("address of overloaded function with no contextual type information");
+ else if (value && TREE_CODE (value) == OVERLOAD)
+ cp_error ("overloaded function with no contextual type information");
+ else
+ cp_error ("insufficient contextual information to determine type");
+ break;
+
+ default:
+ my_friendly_abort (108);
}
+
+ if (value != 0 && (TREE_CODE (value) == VAR_DECL
+ || TREE_CODE (value) == PARM_DECL))
+ cp_error_at ("incomplete `%D' defined here", value);
}
/* Like error(), but don't call report_error_function(). */
static void
-ack (s, v, v2)
- char *s;
- HOST_WIDE_INT v;
- HOST_WIDE_INT v2;
+ack VPROTO ((const char *msg, ...))
{
+#ifndef ANSI_PROTOTYPES
+ const char *msg;
+#endif
+ va_list ap;
extern char * progname;
+ VA_START (ap, msg);
+
+#ifndef ANSI_PROTOTYPES
+ msg = va_arg (ap, const char *);
+#endif
+
if (input_filename)
fprintf (stderr, "%s:%d: ", input_filename, lineno);
else
fprintf (stderr, "%s: ", progname);
- fprintf (stderr, s, v, v2);
+ vfprintf (stderr, msg, ap);
+ va_end (ap);
+
fprintf (stderr, "\n");
}
@@ -352,19 +315,14 @@ ack (s, v, v2)
59 is, so they can understand how to work around it, should they
ever run into it.
- Note, there will be no more calls in the C++ front end to abort,
- because the C++ front end is so unreliable still. The C front end
- can get away with calling abort, because for most of the calls to
- abort on most machines, it, I suspect, can be proven that it is
- impossible to ever call abort. The same is not yet true for C++,
- one day, maybe it will be.
-
We used to tell people to "fix the above error[s] and try recompiling
the program" via a call to fatal, but that message tended to look
silly. So instead, we just do the equivalent of a call to fatal in the
- same situation (call exit). */
+ same situation (call exit).
-/* First used: 0 (reserved), Last used: 369. Free: */
+ We used to assign sequential numbers for the aborts; now we use an
+ encoding of the date the abort was added, since that has more meaning
+ when we only see the error message. */
static int abortcount = 0;
@@ -385,7 +343,8 @@ my_friendly_abort (i)
ack ("Internal compiler error.");
else
ack ("Internal compiler error %d.", i);
- ack ("Please submit a full bug report to `egcs-bugs@cygnus.com'.");
+ ack ("Please submit a full bug report to `egcs-bugs@egcs.cygnus.com'.");
+ ack ("See <URL:http://egcs.cygnus.com/faq.html#bugreport> for details.");
}
else
error ("confused by earlier errors, bailing out");
@@ -399,7 +358,8 @@ my_friendly_abort (i)
else
error ("Internal compiler error %d.", i);
- fatal ("Please submit a full bug report to `egcs-bugs@cygnus.com'.");
+ error ("Please submit a full bug report to `egcs-bugs@egcs.cygnus.com'.");
+ fatal ("See <URL:http://egcs.cygnus.com/faq.html#bugreport> for details.");
}
void
@@ -650,13 +610,6 @@ store_init_value (decl, init)
else
init = TREE_VALUE (init);
}
- else if (TREE_TYPE (init) != 0
- && TREE_CODE (TREE_TYPE (init)) == OFFSET_TYPE)
- {
- /* Use the type of our variable to instantiate
- the type of our initializer. */
- init = instantiate_type (type, init, 1);
- }
else if (TREE_CODE (init) == TREE_LIST
&& TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
{
@@ -767,6 +720,9 @@ digest_init (type, init, tail)
if (TREE_CODE (init) == NON_LVALUE_EXPR)
init = TREE_OPERAND (init, 0);
+ if (TREE_CODE (init) == CONSTRUCTOR && TREE_TYPE (init) == type)
+ return init;
+
raw_constructor = TREE_CODE (init) == CONSTRUCTOR && TREE_TYPE (init) == 0;
if (raw_constructor
@@ -937,6 +893,7 @@ process_init_constructor (type, init, elts)
/* List of the elements of the result constructor,
in reverse order. */
register tree members = NULL;
+ register tree next1;
tree result;
int allconstant = 1;
int allsimple = 1;
@@ -971,42 +928,62 @@ process_init_constructor (type, init, elts)
else
len = -1; /* Take as many as there are */
- for (i = 0; (len < 0 || i < len) && tail != 0; i++)
+ for (i = 0; len < 0 || i < len; i++)
{
- register tree next1;
-
- if (TREE_PURPOSE (tail)
- && (TREE_CODE (TREE_PURPOSE (tail)) != INTEGER_CST
- || TREE_INT_CST_LOW (TREE_PURPOSE (tail)) != i))
- sorry ("non-trivial labeled initializers");
-
- if (TREE_VALUE (tail) != 0)
+ if (tail)
{
- tree tail1 = tail;
- next1 = digest_init (TREE_TYPE (type),
- TREE_VALUE (tail), &tail1);
- if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (type))
- && TYPE_MAIN_VARIANT (TREE_TYPE (type)) != TYPE_MAIN_VARIANT (TREE_TYPE (next1)))
+ if (TREE_PURPOSE (tail)
+ && (TREE_CODE (TREE_PURPOSE (tail)) != INTEGER_CST
+ || TREE_INT_CST_LOW (TREE_PURPOSE (tail)) != i))
+ sorry ("non-trivial labeled initializers");
+
+ if (TREE_VALUE (tail) != 0)
{
- /* The fact this needs to be done suggests this code needs
- to be totally rewritten. */
- next1 = convert_for_initialization (NULL_TREE, TREE_TYPE (type), next1, LOOKUP_NORMAL, "initialization", NULL_TREE, 0);
+ tree tail1 = tail;
+ next1 = digest_init (TREE_TYPE (type),
+ TREE_VALUE (tail), &tail1);
+ if (next1 == error_mark_node)
+ return next1;
+ my_friendly_assert
+ (same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (type)),
+ TYPE_MAIN_VARIANT (TREE_TYPE (next1))),
+ 981123);
+ my_friendly_assert (tail1 == 0
+ || TREE_CODE (tail1) == TREE_LIST, 319);
+ if (tail == tail1 && len < 0)
+ {
+ error ("non-empty initializer for array of empty elements");
+ /* Just ignore what we were supposed to use. */
+ tail1 = NULL_TREE;
+ }
+ tail = tail1;
}
- my_friendly_assert (tail1 == 0
- || TREE_CODE (tail1) == TREE_LIST, 319);
- if (tail == tail1 && len < 0)
+ else
{
- error ("non-empty initializer for array of empty elements");
- /* Just ignore what we were supposed to use. */
- tail1 = NULL_TREE;
+ next1 = error_mark_node;
+ tail = TREE_CHAIN (tail);
}
- tail = tail1;
}
- else
+ else if (len < 0)
+ /* We're done. */
+ break;
+ else if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (type)))
{
- next1 = error_mark_node;
- tail = TREE_CHAIN (tail);
+ /* If this type needs constructors run for
+ default-initialization, we can't rely on the backend to do it
+ for us, so build up TARGET_EXPRs. If the type in question is
+ a class, just build one up; if it's an array, recurse. */
+
+ if (IS_AGGR_TYPE (TREE_TYPE (type)))
+ next1 = build_functional_cast (TREE_TYPE (type), NULL_TREE);
+ else
+ next1 = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, NULL_TREE);
+ next1 = digest_init (TREE_TYPE (type), next1, 0);
}
+ else
+ /* The default zero-initialization is fine for us; don't
+ add anything to the CONSTRUCTOR. */
+ break;
if (next1 == error_mark_node)
erroneous = 1;
@@ -1017,7 +994,7 @@ process_init_constructor (type, init, elts)
members = expr_tree_cons (NULL_TREE, next1, members);
}
}
- if (TREE_CODE (type) == RECORD_TYPE)
+ else if (TREE_CODE (type) == RECORD_TYPE)
{
register tree field;
@@ -1042,12 +1019,10 @@ process_init_constructor (type, init, elts)
}
}
- for (field = TYPE_FIELDS (type); field && tail;
+ for (field = TYPE_FIELDS (type); field;
field = TREE_CHAIN (field))
{
- register tree next1;
-
- if (! DECL_NAME (field))
+ if (! DECL_NAME (field) && DECL_C_BIT_FIELD (field))
{
members = expr_tree_cons (field, integer_zero_node, members);
continue;
@@ -1056,25 +1031,67 @@ process_init_constructor (type, init, elts)
if (TREE_CODE (field) != FIELD_DECL)
continue;
- if (TREE_PURPOSE (tail)
- && TREE_PURPOSE (tail) != field
- && TREE_PURPOSE (tail) != DECL_NAME (field))
- sorry ("non-trivial labeled initializers");
+ if (tail)
+ {
+ if (TREE_PURPOSE (tail)
+ && TREE_PURPOSE (tail) != field
+ && TREE_PURPOSE (tail) != DECL_NAME (field))
+ sorry ("non-trivial labeled initializers");
+
+ if (TREE_VALUE (tail) != 0)
+ {
+ tree tail1 = tail;
- if (TREE_VALUE (tail) != 0)
+ next1 = digest_init (TREE_TYPE (field),
+ TREE_VALUE (tail), &tail1);
+ my_friendly_assert (tail1 == 0
+ || TREE_CODE (tail1) == TREE_LIST, 320);
+ tail = tail1;
+ }
+ else
+ {
+ next1 = error_mark_node;
+ tail = TREE_CHAIN (tail);
+ }
+ }
+ else if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (field)))
{
- tree tail1 = tail;
+ /* If this type needs constructors run for
+ default-initialization, we can't rely on the backend to do it
+ for us, so build up TARGET_EXPRs. If the type in question is
+ a class, just build one up; if it's an array, recurse. */
+
+ if (IS_AGGR_TYPE (TREE_TYPE (field)))
+ next1 = build_functional_cast (TREE_TYPE (field),
+ NULL_TREE);
+ else
+ next1 = build (CONSTRUCTOR, NULL_TREE, NULL_TREE,
+ NULL_TREE);
+ next1 = digest_init (TREE_TYPE (field), next1, 0);
- next1 = digest_init (TREE_TYPE (field),
- TREE_VALUE (tail), &tail1);
- my_friendly_assert (tail1 == 0
- || TREE_CODE (tail1) == TREE_LIST, 320);
- tail = tail1;
+ /* Warn when some struct elements are implicitly initialized. */
+ if (extra_warnings)
+ cp_warning ("missing initializer for member `%D'", field);
}
else
{
- next1 = error_mark_node;
- tail = TREE_CHAIN (tail);
+ if (TREE_READONLY (field))
+ cp_error ("uninitialized const member `%D'", field);
+ else if (TYPE_LANG_SPECIFIC (TREE_TYPE (field))
+ && CLASSTYPE_READONLY_FIELDS_NEED_INIT (TREE_TYPE (field)))
+ cp_error ("member `%D' with uninitialized const fields",
+ field);
+ else if (TREE_CODE (TREE_TYPE (field)) == REFERENCE_TYPE)
+ cp_error ("member `%D' is uninitialized reference", field);
+
+ /* Warn when some struct elements are implicitly initialized
+ to zero. */
+ if (extra_warnings)
+ cp_warning ("missing initializer for member `%D'", field);
+
+ /* The default zero-initialization is fine for us; don't
+ add anything to the CONSTRUCTOR. */
+ continue;
}
if (next1 == error_mark_node)
@@ -1085,45 +1102,10 @@ process_init_constructor (type, init, elts)
allsimple = 0;
members = expr_tree_cons (field, next1, members);
}
- for (; field; field = TREE_CHAIN (field))
- {
- if (TREE_CODE (field) != FIELD_DECL)
- continue;
-
- /* Does this field have a default initialization? */
- if (DECL_INITIAL (field))
- {
- register tree next1 = DECL_INITIAL (field);
- if (TREE_CODE (next1) == ERROR_MARK)
- erroneous = 1;
- else if (!TREE_CONSTANT (next1))
- allconstant = 0;
- else if (! initializer_constant_valid_p (next1, TREE_TYPE (next1)))
- allsimple = 0;
- members = expr_tree_cons (field, next1, members);
- }
- else if (TREE_READONLY (field))
- error ("uninitialized const member `%s'",
- IDENTIFIER_POINTER (DECL_NAME (field)));
- else if (TYPE_LANG_SPECIFIC (TREE_TYPE (field))
- && CLASSTYPE_READONLY_FIELDS_NEED_INIT (TREE_TYPE (field)))
- error ("member `%s' with uninitialized const fields",
- IDENTIFIER_POINTER (DECL_NAME (field)));
- else if (TREE_CODE (TREE_TYPE (field)) == REFERENCE_TYPE)
- error ("member `%s' is uninitialized reference",
- IDENTIFIER_POINTER (DECL_NAME (field)));
- /* Warn when some struct elements are implicitly initialized
- to zero. */
- else if (extra_warnings)
- warning ("missing initializer for member `%s'",
- IDENTIFIER_POINTER (DECL_NAME (field)));
- }
}
-
- if (TREE_CODE (type) == UNION_TYPE)
+ else if (TREE_CODE (type) == UNION_TYPE)
{
register tree field = TYPE_FIELDS (type);
- register tree next1;
/* Find the first named field. ANSI decided in September 1990
that only named fields count here. */
@@ -1152,8 +1134,8 @@ process_init_constructor (type, init, elts)
if (temp)
field = temp, win = 1;
else
- error ("no field `%s' in union being initialized",
- IDENTIFIER_POINTER (TREE_PURPOSE (tail)));
+ cp_error ("no field `%D' in union being initialized",
+ TREE_PURPOSE (tail));
}
if (!win)
TREE_VALUE (tail) = error_mark_node;
@@ -1392,8 +1374,7 @@ build_m_component_ref (datum, component)
}
else
{
- component = build_indirect_ref (component, NULL_PTR);
- type = TREE_TYPE (component);
+ type = TREE_TYPE (TREE_TYPE (component));
rettype = TREE_TYPE (type);
}
@@ -1504,6 +1485,11 @@ build_functional_cast (exp, parms)
cp_error ("type `%T' is not yet defined", type);
return error_mark_node;
}
+ if (IS_AGGR_TYPE (type) && CLASSTYPE_ABSTRACT_VIRTUALS (type))
+ {
+ abstract_virtuals_error (NULL_TREE, type);
+ return error_mark_node;
+ }
if (parms && TREE_CHAIN (parms) == NULL_TREE)
return build_c_cast (type, TREE_VALUE (parms));
@@ -1659,11 +1645,15 @@ report_case_error (code, type, new_value, old_value)
}
#endif
+/* Complain about defining new types in inappropriate places. We give an
+ exception for C-style casts, to accommodate GNU C stylings. */
+
void
check_for_new_type (string, inptree)
- char *string;
+ const char *string;
flagged_type_tree inptree;
{
- if (pedantic && inptree.new_type_flag)
+ if (inptree.new_type_flag
+ && (pedantic || strcmp (string, "cast") != 0))
pedwarn ("ANSI C++ forbids defining types within %s",string);
}
diff --git a/gcc/cp/xref.c b/gcc/cp/xref.c
index e38546e0367..6e06eda92fb 100644
--- a/gcc/cp/xref.c
+++ b/gcc/cp/xref.c
@@ -86,8 +86,8 @@ typedef struct _XREF_SCOPE * XREF_SCOPE;
typedef struct _XREF_FILE
{
- char *name;
- char *outname;
+ const char *name;
+ const char *outname;
XREF_FILE next;
} XREF_FILE_INFO;
@@ -122,19 +122,20 @@ static tree last_fndecl = NULL;
/* */
/************************************************************************/
static void gen_assign PROTO((XREF_FILE, tree));
-static XREF_FILE find_file PROTO((char *));
-static char * filename PROTO((XREF_FILE));
-static char * fctname PROTO((tree));
-static char * declname PROTO((tree));
+static XREF_FILE find_file PROTO((const char *));
+static const char * filename PROTO((XREF_FILE));
+static const char * fctname PROTO((tree));
+static const char * declname PROTO((tree));
static void simplify_type PROTO((char *));
-static char * fixname PROTO((char *, char *));
-static void open_xref_file PROTO((char *));
+static const char * fixname PROTO((const char *, char *));
+static void open_xref_file PROTO((const char *));
+static const char * classname PROTO((tree));
/* Start cross referencing. FILE is the name of the file we xref. */
void
GNU_xref_begin (file)
- char *file;
+ const char *file;
{
doing_xref = 1;
@@ -178,7 +179,7 @@ GNU_xref_end (ect)
void
GNU_xref_file (name)
- char *name;
+ const char *name;
{
XREF_FILE xf;
@@ -209,8 +210,8 @@ GNU_xref_file (name)
else
{
char *nmbuf
- = (char *) malloc (strlen (wd_name) + strlen (FILE_NAME_JOINER)
- + strlen (name) + 1);
+ = (char *) xmalloc (strlen (wd_name) + strlen (FILE_NAME_JOINER)
+ + strlen (name) + 1);
sprintf (nmbuf, "%s%s%s", wd_name, FILE_NAME_JOINER, name);
name = nmbuf;
xf->outname = nmbuf;
@@ -259,7 +260,7 @@ GNU_xref_end_scope (id,inid,prm,keep)
{
XREF_FILE xf;
XREF_SCOPE xs,lxs,oxs;
- char *stype;
+ const char *stype;
if (!doing_xref) return;
xf = find_file (input_filename);
@@ -302,7 +303,7 @@ GNU_xref_end_scope (id,inid,prm,keep)
void
GNU_xref_ref (fndecl,name)
tree fndecl;
- char *name;
+ const char *name;
{
XREF_FILE xf;
@@ -322,8 +323,8 @@ GNU_xref_decl (fndecl,decl)
tree decl;
{
XREF_FILE xf,xf1;
- char *cls = 0;
- char *name;
+ const char *cls = 0;
+ const char *name;
char buf[10240];
int uselin;
@@ -432,11 +433,11 @@ GNU_xref_decl (fndecl,decl)
void
GNU_xref_call (fndecl, name)
tree fndecl;
- char *name;
+ const char *name;
{
XREF_FILE xf;
char buf[1024];
- char *s;
+ const char *s;
if (!doing_xref) return;
xf = find_file (input_filename);
@@ -508,7 +509,7 @@ gen_assign(xf, name)
XREF_FILE xf;
tree name;
{
- char *s;
+ const char *s;
s = NULL;
@@ -541,7 +542,7 @@ gen_assign(xf, name)
fprintf(xref_file, "ASG %s %d %s\n", filename(xf), lineno, s);
}
-static char*
+static const char *
classname (cls)
tree cls;
{
@@ -590,9 +591,9 @@ GNU_xref_member(cls, fld)
tree fld;
{
XREF_FILE xf;
- char *prot;
+ const char *prot;
int confg, pure;
- char *d;
+ const char *d;
#ifdef XREF_SHORT_MEMBER_NAMES
int i;
#endif
@@ -651,7 +652,7 @@ GNU_xref_member(cls, fld)
static XREF_FILE
find_file(name)
- char *name;
+ const char *name;
{
XREF_FILE xf;
@@ -664,7 +665,7 @@ find_file(name)
/* Return filename for output purposes. */
-static char *
+static const char *
filename(xf)
XREF_FILE xf;
{
@@ -682,12 +683,12 @@ filename(xf)
/* Return function name for output purposes. */
-static char *
+static const char *
fctname(fndecl)
tree fndecl;
{
static char fctbuf[1024];
- char *s;
+ const char *s;
if (fndecl == NULL && last_fndecl == NULL) return "*";
@@ -709,7 +710,7 @@ fctname(fndecl)
/* Return decl name for output purposes. */
-static char *
+static const char *
declname(dcl)
tree dcl;
{
@@ -773,12 +774,13 @@ simplify_type(typ)
/* Fixup a function name (take care of embedded spaces). */
-static char *
+static const char *
fixname(nam, buf)
- char *nam;
+ const char *nam;
char *buf;
{
- char *s, *t;
+ const char *s;
+ char *t;
int fg;
s = nam;
@@ -806,9 +808,10 @@ fixname(nam, buf)
static void
open_xref_file(file)
- char *file;
+ const char *file;
{
- char *s, *t;
+ const char *s;
+ char *t;
#ifdef XREF_FILE_NAME
XREF_FILE_NAME (xref_name, file);
diff --git a/gcc/cpp.texi b/gcc/cpp.texi
index c81554b6a92..47a50dafe7e 100644
--- a/gcc/cpp.texi
+++ b/gcc/cpp.texi
@@ -16,7 +16,7 @@
@ifinfo
This file documents the GNU C Preprocessor.
-Copyright 1987, 1989, 1991, 1992, 1993, 1994, 1995 Free Software
+Copyright 1987, 1989, 1991, 1992, 1993, 1994, 1995, 1997, 1998 Free Software
Foundation, Inc.
Permission is granted to make and distribute verbatim copies of
diff --git a/gcc/cppalloc.c b/gcc/cppalloc.c
index bd3a6051971..5c96aff7cb8 100644
--- a/gcc/cppalloc.c
+++ b/gcc/cppalloc.c
@@ -1,5 +1,5 @@
/* Part of CPP library. (memory allocation - xmalloc etc)
- Copyright (C) 1986, 87, 89, 92 - 95, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1986, 87, 89, 92, 93, 94, 1995, 1998 Free Software Foundation, Inc.
Written by Per Bothner, 1994.
Based on CCCP program by Paul Rubin, June 1986
Adapted to ANSI C, Richard Stallman, Jan 1987
@@ -24,33 +24,58 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "config.h"
#include "system.h"
-#include "gansidecl.h"
#include "cpplib.h"
+static void memory_full PROTO ((void)) ATTRIBUTE_NORETURN;
+
static void
memory_full ()
{
- fprintf (stderr, "%s: Memory exhausted.\n", progname);
+ cpp_notice ("%s: Memory exhausted.\n", progname);
exit (FATAL_EXIT_CODE);
}
-char *
+PTR
xmalloc (size)
- unsigned size;
+ size_t size;
{
- register char *ptr = (char *) malloc (size);
+ register PTR ptr = (PTR) malloc (size);
if (ptr == 0)
memory_full ();
return ptr;
}
-char *
+PTR
+xcalloc (number, size)
+ size_t number, size;
+{
+ register PTR ptr = (PTR) calloc (number, size);
+ if (ptr == 0)
+ memory_full ();
+ return ptr;
+}
+
+PTR
xrealloc (old, size)
- char *old;
- unsigned size;
+ PTR old;
+ size_t size;
{
- register char *ptr = (char *) realloc (old, size);
+ register PTR ptr;
+ if (old)
+ ptr = (PTR) realloc (old, size);
+ else
+ ptr = (PTR) malloc (size);
if (ptr == 0)
memory_full ();
return ptr;
}
+
+char *
+xstrdup (input)
+ const char *input;
+{
+ unsigned size = strlen (input);
+ char *output = xmalloc (size + 1);
+ strcpy (output, input);
+ return output;
+}
diff --git a/gcc/cpperror.c b/gcc/cpperror.c
index 308ef299a18..af018815d93 100644
--- a/gcc/cpperror.c
+++ b/gcc/cpperror.c
@@ -1,5 +1,5 @@
/* Default error handlers for CPP Library.
- Copyright (C) 1986, 87, 89, 92 - 95, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1986, 87, 89, 92-95, 98, 1999 Free Software Foundation, Inc.
Written by Per Bothner, 1994.
Based on CCCP program by Paul Rubin, June 1986
Adapted to ANSI C, Richard Stallman, Jan 1987
@@ -25,12 +25,12 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef EMACS
#include "config.h"
#include "system.h"
-#include "gansidecl.h"
#else
#include <stdio.h>
#endif /* not EMACS */
#include "cpplib.h"
+#include "intl.h"
/* Print the file names and line numbers of the #include
commands which led to the current file. */
@@ -63,16 +63,16 @@ cpp_print_containing_files (pfile)
if (first)
{
first = 0;
- fprintf (stderr, "In file included");
+ cpp_notice ("In file included from %s:%ld",
+ ip->nominal_fname, line);
}
else
- fprintf (stderr, ",\n ");
+ cpp_message (pfile, -1, ",\n from %s:%ld",
+ ip->nominal_fname, line);
}
-
- fprintf (stderr, " from %s:%ld", ip->nominal_fname, line);
}
if (! first)
- fprintf (stderr, ":\n");
+ fputs (":\n", stderr);
/* Record we have printed the status as of this time. */
pfile->input_stack_listing_current = 1;
@@ -90,44 +90,58 @@ cpp_file_line_for_message (pfile, filename, line, column)
fprintf (stderr, "%s:%d: ", filename, line);
}
-/* IS_ERROR is 2 for "fatal" error, 1 for error, 0 for warning */
+/* IS_ERROR is 2 for "fatal" error, 1 for error, 0 for warning, -1 for notice */
void
-v_cpp_message (pfile, is_error, msg, ap)
+v_cpp_message (pfile, is_error, msgid, ap)
cpp_reader * pfile;
int is_error;
- const char *msg;
+ const char *msgid;
va_list ap;
{
- if (!is_error)
- fprintf (stderr, "warning: ");
- else if (is_error == 2)
- pfile->errors = CPP_FATAL_LIMIT;
- else if (pfile->errors < CPP_FATAL_LIMIT)
- pfile->errors++;
- vfprintf (stderr, msg, ap);
- fprintf (stderr, "\n");
+ switch (is_error)
+ {
+ case -1:
+ break;
+ case 0:
+ fprintf (stderr, _("warning: "));
+ break;
+ case 1:
+ if (pfile->errors < CPP_FATAL_LIMIT)
+ pfile->errors++;
+ break;
+ case 2:
+ pfile->errors = CPP_FATAL_LIMIT;
+ break;
+ default:
+ abort ();
+ }
+
+ vfprintf (stderr, _(msgid), ap);
+
+ if (0 <= is_error)
+ fprintf (stderr, "\n");
}
void
-cpp_message VPROTO ((cpp_reader *pfile, int is_error, const char *msg, ...))
+cpp_message VPROTO ((cpp_reader *pfile, int is_error, const char *msgid, ...))
{
-#ifndef __STDC__
+#ifndef ANSI_PROTOTYPES
cpp_reader *pfile;
int is_error;
- const char *msg;
+ const char *msgid;
#endif
va_list ap;
- VA_START (ap, msg);
+ VA_START (ap, msgid);
-#ifndef __STDC__
+#ifndef ANSI_PROTOTYPES
pfile = va_arg (ap, cpp_reader *);
is_error = va_arg (ap, int);
- msg = va_arg (ap, const char *);
+ msgid = va_arg (ap, const char *);
#endif
- v_cpp_message(pfile, is_error, msg, ap);
+ v_cpp_message(pfile, is_error, msgid, ap);
va_end(ap);
}
@@ -138,23 +152,23 @@ cpp_message VPROTO ((cpp_reader *pfile, int is_error, const char *msg, ...))
CPP_FATAL_ERRORS. */
void
-cpp_fatal VPROTO ((cpp_reader *pfile, const char *str, ...))
+cpp_fatal VPROTO ((cpp_reader *pfile, const char *msgid, ...))
{
-#ifndef __STDC__
+#ifndef ANSI_PROTOTYPES
cpp_reader *pfile;
- const char *str;
+ const char *msgid;
#endif
va_list ap;
- VA_START (ap, str);
+ VA_START (ap, msgid);
-#ifndef __STDC__
+#ifndef ANSI_PROTOTYPES
pfile = va_arg (ap, cpp_reader *);
- str = va_arg (ap, const char *);
+ msgid = va_arg (ap, const char *);
#endif
fprintf (stderr, "%s: ", progname);
- v_cpp_message (pfile, 2, str, ap);
+ v_cpp_message (pfile, 2, msgid, ap);
va_end(ap);
}
@@ -170,3 +184,25 @@ cpp_pfatal_with_name (pfile, name)
exit (FATAL_EXIT_CODE);
#endif
}
+
+/* Print an error message. */
+
+void
+cpp_notice VPROTO ((const char *msgid, ...))
+{
+#ifndef ANSI_PROTOTYPES
+ const char *msgid;
+#endif
+ va_list ap;
+
+ VA_START (ap, msgid);
+
+#ifndef ANSI_PROTOTYPES
+ msgid = va_arg (ap, const char *);
+#endif
+
+ fprintf (stderr, "%s: ", progname);
+ v_cpp_message ((cpp_reader *) 0, -1, msgid, ap);
+ va_end(ap);
+}
+
diff --git a/gcc/cppexp.c b/gcc/cppexp.c
index 44f8a66547c..eaec4686d75 100644
--- a/gcc/cppexp.c
+++ b/gcc/cppexp.c
@@ -1,5 +1,5 @@
/* Parse C expressions for CCCP.
- Copyright (C) 1987, 1992, 1994, 1995, 1997, 1998 Free Software Foundation.
+ Copyright (C) 1987, 92, 94, 95, 97, 98, 1999 Free Software Foundation.
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
@@ -26,24 +26,12 @@ Written by Per Bothner 1994. */
#include "config.h"
#include "system.h"
-#include "gansidecl.h"
#include "cpplib.h"
-extern char *xmalloc PARAMS ((unsigned));
-extern char *xrealloc PARAMS ((void *, unsigned));
-
#ifdef MULTIBYTE_CHARS
#include <locale.h>
#endif
-/* This is used for communicating lists of keywords with cccp.c. */
-struct arglist {
- struct arglist *next;
- U_CHAR *name;
- int length;
- int argno;
-};
-
#ifndef CHAR_TYPE_SIZE
#define CHAR_TYPE_SIZE BITS_PER_UNIT
#endif
@@ -76,13 +64,21 @@ struct arglist {
#define MAX_WCHAR_TYPE_SIZE WCHAR_TYPE_SIZE
#endif
+#define MAX_CHAR_TYPE_MASK (MAX_CHAR_TYPE_SIZE < HOST_BITS_PER_WIDEST_INT \
+ ? (~ (~ (HOST_WIDEST_INT) 0 << MAX_CHAR_TYPE_SIZE)) \
+ : ~ (HOST_WIDEST_INT) 0)
+
+#define MAX_WCHAR_TYPE_MASK (MAX_WCHAR_TYPE_SIZE < HOST_BITS_PER_WIDEST_INT \
+ ? ~ (~ (HOST_WIDEST_INT) 0 << MAX_WCHAR_TYPE_SIZE) \
+ : ~ (HOST_WIDEST_INT) 0)
+
/* Yield nonzero if adding two numbers with A's and B's signs can yield a
number with SUM's sign, where A, B, and SUM are all C integers. */
#define possible_sum_sign(a, b, sum) ((((a) ^ (b)) | ~ ((a) ^ (sum))) < 0)
static void integer_overflow PARAMS ((cpp_reader *));
-static long left_shift PARAMS ((cpp_reader *, long, int, unsigned long));
-static long right_shift PARAMS ((cpp_reader *, long, int, unsigned long));
+static HOST_WIDEST_INT left_shift PARAMS ((cpp_reader *, HOST_WIDEST_INT, int, unsigned HOST_WIDEST_INT));
+static HOST_WIDEST_INT right_shift PARAMS ((cpp_reader *, HOST_WIDEST_INT, int, unsigned HOST_WIDEST_INT));
#define ERROR 299
#define OROR 300
@@ -105,135 +101,117 @@ static long right_shift PARAMS ((cpp_reader *, long, int, unsigned long));
#define SKIP_OPERAND 8
/*#define UNSIGNEDP 16*/
-/* Find the largest host integer type and set its size and type.
- Watch out: on some crazy hosts `long' is shorter than `int'. */
-
-#ifndef HOST_WIDE_INT
-# if HAVE_INTTYPES_H
-# include <inttypes.h>
-# define HOST_WIDE_INT intmax_t
-# else
-# if (HOST_BITS_PER_LONG <= HOST_BITS_PER_INT \
- && HOST_BITS_PER_LONGLONG <= HOST_BITS_PER_INT)
-# define HOST_WIDE_INT int
-# else
-# if (HOST_BITS_PER_LONGLONG <= HOST_BITS_PER_LONG \
- || ! (defined LONG_LONG_MAX || defined LLONG_MAX))
-# define HOST_WIDE_INT long
-# else
-# define HOST_WIDE_INT long long
-# endif
-# endif
-# endif
-#endif
-
-#ifndef CHAR_BIT
-#define CHAR_BIT 8
-#endif
-
-#ifndef HOST_BITS_PER_WIDE_INT
-#define HOST_BITS_PER_WIDE_INT (CHAR_BIT * sizeof (HOST_WIDE_INT))
-#endif
-
struct operation {
short op;
char rprio; /* Priority of op (relative to it right operand). */
char flags;
char unsignedp; /* true if value should be treated as unsigned */
- HOST_WIDE_INT value; /* The value logically "right" of op. */
+ HOST_WIDEST_INT value; /* The value logically "right" of op. */
};
-
-/* Take care of parsing a number (anything that starts with a digit).
- LEN is the number of characters in it. */
-/* maybe needs to actually deal with floating point numbers */
+/* Parse and convert an integer for #if. Accepts decimal, hex, or octal
+ with or without size suffixes. */
-struct operation
-parse_number (pfile, start, olen)
+static struct operation
+parse_number (pfile, start, end)
cpp_reader *pfile;
- char *start;
- int olen;
+ U_CHAR *start;
+ U_CHAR *end;
{
struct operation op;
- register char *p = start;
- register int c;
- register unsigned long n = 0, nd, ULONG_MAX_over_base;
- register int base = 10;
- register int len = olen;
- register int overflow = 0;
- register int digit, largest_digit = 0;
+ U_CHAR *p = start;
+ int c;
+ unsigned HOST_WIDEST_INT n = 0, nd, MAX_over_base;
+ int base = 10;
+ int overflow = 0;
+ int digit, largest_digit = 0;
int spec_long = 0;
op.unsignedp = 0;
- for (c = 0; c < len; c++)
- if (p[c] == '.') {
- /* It's a float since it contains a point. */
- cpp_error (pfile,
- "floating point numbers not allowed in #if expressions");
- op.op = ERROR;
- return op;
+ if (p[0] == '0')
+ {
+ if (end - start >= 3 && (p[1] == 'x' || p[1] == 'X'))
+ {
+ p += 2;
+ base = 16;
+ }
+ else
+ {
+ p += 1;
+ base = 8;
+ }
}
- if (len >= 3 && (!strncmp (p, "0x", 2) || !strncmp (p, "0X", 2))) {
- p += 2;
- base = 16;
- len -= 2;
- }
- else if (*p == '0')
- base = 8;
-
/* Some buggy compilers (e.g. MPW C) seem to need both casts. */
- ULONG_MAX_over_base = ((unsigned long) -1) / ((unsigned long) base);
-
- for (; len > 0; len--) {
- c = *p++;
-
- if (c >= '0' && c <= '9')
- digit = c - '0';
- else if (base == 16 && c >= 'a' && c <= 'f')
- digit = c - 'a' + 10;
- else if (base == 16 && c >= 'A' && c <= 'F')
- digit = c - 'A' + 10;
- else {
- /* `l' means long, and `u' means unsigned. */
- while (1) {
- if (c == 'l' || c == 'L')
- {
- if (spec_long)
- cpp_error (pfile, "two `l's in integer constant");
- spec_long = 1;
- }
- else if (c == 'u' || c == 'U')
- {
- if (op.unsignedp)
- cpp_error (pfile, "two `u's in integer constant");
- op.unsignedp = 1;
- }
- else
- break;
+ MAX_over_base = (((unsigned HOST_WIDEST_INT) -1)
+ / ((unsigned HOST_WIDEST_INT) base));
- if (--len == 0)
+ while (p < end)
+ {
+ c = *p++;
+
+ if (c >= '0' && c <= '9')
+ digit = c - '0';
+ else if (base == 16 && c >= 'a' && c <= 'f') /* FIXME: assumes ASCII */
+ digit = c - 'a' + 10;
+ else if (base == 16 && c >= 'A' && c <= 'F')
+ digit = c - 'A' + 10;
+ else if (c == '.')
+ {
+ /* It's a float since it contains a point. */
+ cpp_error (pfile,
+ "floating point numbers are not allowed in #if expressions");
+ goto error;
+ }
+ else
+ {
+ /* `l' means long, and `u' means unsigned. */
+ for (;;)
+ {
+ if (c == 'l' || c == 'L')
+ spec_long++;
+ else if (c == 'u' || c == 'U')
+ op.unsignedp++;
+ else
+ {
+ /* Decrement p here so that the error for an invalid number
+ will be generated below in the case where this is the
+ last character in the buffer. */
+ p--;
+ break;
+ }
+ if (p == end)
+ break;
+ c = *p++;
+ }
+ /* Don't look for any more digits after the suffixes. */
break;
- c = *p++;
- }
- /* Don't look for any more digits after the suffixes. */
- break;
+ }
+
+ if (largest_digit < digit)
+ largest_digit = digit;
+ nd = n * base + digit;
+ overflow |= MAX_over_base < n || nd < n;
+ n = nd;
}
- if (largest_digit < digit)
- largest_digit = digit;
- nd = n * base + digit;
- overflow |= ULONG_MAX_over_base < n || nd < n;
- n = nd;
- }
- if (len != 0)
+ if (p != end)
{
- cpp_error (pfile, "Invalid number in #if expression");
- op.op = ERROR;
- return op;
+ cpp_error (pfile, "invalid number in #if expression");
+ goto error;
}
-
+ else if (spec_long > (CPP_OPTIONS (pfile)->c89 ? 1 : 2))
+ {
+ cpp_error (pfile, "too many `l' suffixes in integer constant");
+ goto error;
+ }
+ else if (op.unsignedp > 1)
+ {
+ cpp_error (pfile, "too many `u' suffixes in integer constant");
+ goto error;
+ }
+
if (base <= largest_digit)
cpp_pedwarn (pfile, "integer constant contains digits beyond the radix");
@@ -241,18 +219,132 @@ parse_number (pfile, start, olen)
cpp_pedwarn (pfile, "integer constant out of range");
/* If too big to be signed, consider it unsigned. */
- if ((long) n < 0 && ! op.unsignedp)
+ else if ((HOST_WIDEST_INT) n < 0 && ! op.unsignedp)
{
if (base == 10)
- cpp_warning (pfile, "integer constant is so large that it is unsigned");
+ cpp_warning (pfile,
+ "integer constant is so large that it is unsigned");
op.unsignedp = 1;
}
op.value = n;
op.op = INT;
return op;
+
+ error:
+ op.op = ERROR;
+ return op;
}
+/* Parse and convert a character constant for #if. Understands backslash
+ escapes (\n, \031) and multibyte characters (if so configured). */
+static struct operation
+parse_charconst (pfile, start, end)
+ cpp_reader *pfile;
+ U_CHAR *start;
+ U_CHAR *end;
+{
+ struct operation op;
+ HOST_WIDEST_INT result = 0;
+ int num_chars = 0;
+ int num_bits;
+ unsigned int width = MAX_CHAR_TYPE_SIZE, mask = MAX_CHAR_TYPE_MASK;
+ int max_chars;
+ U_CHAR *ptr = start;
+
+ /* FIXME: Should use reentrant multibyte functions. */
+#ifdef MULTIBYTE_CHARS
+ wchar_t c;
+ (void) mbtowc (NULL_PTR, NULL_PTR, 0);
+#else
+ int c;
+#endif
+
+ if (*ptr == 'L')
+ {
+ ++ptr;
+ width = MAX_WCHAR_TYPE_SIZE, mask = MAX_WCHAR_TYPE_MASK;
+ }
+ max_chars = MAX_LONG_TYPE_SIZE / width;
+
+ ++ptr; /* skip initial quote */
+
+ while (ptr < end)
+ {
+#ifndef MULTIBYTE_CHARS
+ c = *ptr++;
+#else
+ ptr += mbtowc (&c, ptr, end - ptr);
+#endif
+ if (c == '\'' || c == '\0')
+ break;
+ else if (c == '\\')
+ {
+ /* Hopefully valid assumption: if mbtowc returns a backslash,
+ we are in initial shift state. No valid escape-sequence
+ character can take us out of initial shift state or begin
+ an unshifted multibyte char, so cpp_parse_escape doesn't
+ need to know about multibyte chars. */
+
+ c = cpp_parse_escape (pfile, (char **) &ptr, mask);
+ if (width < HOST_BITS_PER_INT
+ && (unsigned int) c >= (unsigned int)(1 << width))
+ cpp_pedwarn (pfile, "escape sequence out of range for character");
+ }
+
+ /* Merge character into result; ignore excess chars. */
+ if (++num_chars <= max_chars)
+ {
+ if (width < HOST_BITS_PER_INT)
+ result = (result << width) | (c & ((1 << width) - 1));
+ else
+ result = c;
+ }
+ }
+
+ if (num_chars == 0)
+ {
+ cpp_error (pfile, "empty character constant");
+ goto error;
+ }
+ else if (c != '\'')
+ {
+ /* cpp_get_token has already emitted an error if !traditional. */
+ if (! CPP_TRADITIONAL (pfile))
+ cpp_error (pfile, "malformatted character constant");
+ goto error;
+ }
+ else if (num_chars > max_chars)
+ {
+ cpp_error (pfile, "character constant too long");
+ goto error;
+ }
+ else if (num_chars != 1 && ! CPP_TRADITIONAL (pfile))
+ cpp_warning (pfile, "multi-character character constant");
+
+ /* If char type is signed, sign-extend the constant. */
+ num_bits = num_chars * width;
+
+ if (cpp_lookup (pfile, (U_CHAR *)"__CHAR_UNSIGNED__",
+ sizeof ("__CHAR_UNSIGNED__")-1, -1)
+ || ((result >> (num_bits - 1)) & 1) == 0)
+ op.value = result & ((unsigned HOST_WIDEST_INT) ~0
+ >> (HOST_BITS_PER_WIDEST_INT - num_bits));
+ else
+ op.value = result | ~((unsigned HOST_WIDEST_INT) ~0
+ >> (HOST_BITS_PER_WIDEST_INT - num_bits));
+
+ /* This is always a signed type. */
+ op.unsignedp = 0;
+ op.op = CHAR;
+ return op;
+
+ error:
+ op.op = ERROR;
+ return op;
+}
+
+
struct token {
char *operator;
int token;
@@ -274,13 +366,13 @@ static struct token tokentab2[] = {
/* Read one token. */
-struct operation
+static struct operation
cpp_lex (pfile, skip_evaluation)
cpp_reader *pfile;
int skip_evaluation;
{
- register int c;
- register struct token *toktab;
+ U_CHAR c;
+ struct token *toktab;
enum cpp_token token;
struct operation op;
U_CHAR *tok_start, *tok_end;
@@ -292,8 +384,11 @@ cpp_lex (pfile, skip_evaluation)
cpp_skip_hspace (pfile);
c = CPP_BUF_PEEK (CPP_BUFFER (pfile));
if (c == '#')
- return parse_number (pfile,
- cpp_read_check_assertion (pfile) ? "1" : "0", 1);
+ {
+ op.op = INT;
+ op.value = cpp_read_check_assertion (pfile);
+ return op;
+ }
if (c == '\n')
{
@@ -319,131 +414,66 @@ cpp_lex (pfile, skip_evaluation)
}
cpp_pop_buffer (pfile);
goto retry;
- case CPP_HSPACE: case CPP_COMMENT:
+ case CPP_HSPACE:
+ case CPP_COMMENT:
goto retry;
case CPP_NUMBER:
- return parse_number (pfile, tok_start, tok_end - tok_start);
+ return parse_number (pfile, tok_start, tok_end);
case CPP_STRING:
cpp_error (pfile, "string constants not allowed in #if expressions");
op.op = ERROR;
return op;
case CPP_CHAR:
- /* This code for reading a character constant
- handles multicharacter constants and wide characters.
- It is mostly copied from c-lex.c. */
- {
- register int result = 0;
- register int num_chars = 0;
- unsigned width = MAX_CHAR_TYPE_SIZE;
- int wide_flag = 0;
- int max_chars;
- U_CHAR *ptr = tok_start;
-#ifdef MULTIBYTE_CHARS
- char token_buffer[MAX_LONG_TYPE_SIZE/MAX_CHAR_TYPE_SIZE + MB_CUR_MAX];
-#else
- char token_buffer[MAX_LONG_TYPE_SIZE/MAX_CHAR_TYPE_SIZE + 1];
-#endif
-
- if (*ptr == 'L')
- {
- ptr++;
- wide_flag = 1;
- width = MAX_WCHAR_TYPE_SIZE;
-#ifdef MULTIBYTE_CHARS
- max_chars = MB_CUR_MAX;
-#else
- max_chars = 1;
-#endif
- }
- else
- max_chars = MAX_LONG_TYPE_SIZE / width;
+ return parse_charconst (pfile, tok_start, tok_end);
- ++ptr;
- while (ptr < tok_end && ((c = *ptr++) != '\''))
- {
- if (c == '\\')
- {
- c = cpp_parse_escape (pfile, (char **) &ptr);
- if (width < HOST_BITS_PER_INT
- && (unsigned) c >= (1 << width))
- cpp_pedwarn (pfile,
- "escape sequence out of range for character");
- }
-
- num_chars++;
-
- /* Merge character into result; ignore excess chars. */
- if (num_chars < max_chars + 1)
- {
- if (width < HOST_BITS_PER_INT)
- result = (result << width) | (c & ((1 << width) - 1));
- else
- result = c;
- token_buffer[num_chars - 1] = c;
- }
- }
-
- token_buffer[num_chars] = 0;
-
- if (c != '\'')
- cpp_error (pfile, "malformatted character constant");
- else if (num_chars == 0)
- cpp_error (pfile, "empty character constant");
- else if (num_chars > max_chars)
- {
- num_chars = max_chars;
- cpp_error (pfile, "character constant too long");
- }
- else if (num_chars != 1 && ! CPP_TRADITIONAL (pfile))
- cpp_warning (pfile, "multi-character character constant");
+ case CPP_NAME:
+ op.op = INT;
+ op.unsignedp = 0;
+ op.value = 0;
+ if (strcmp (tok_start, "defined"))
+ {
+ if (CPP_WARN_UNDEF (pfile) && !skip_evaluation)
+ cpp_warning (pfile, "`%.*s' is not defined",
+ (int) (tok_end - tok_start), tok_start);
+ }
+ else
+ {
+ int paren = 0, len;
+ cpp_buffer *ip = CPP_BUFFER (pfile);
+ U_CHAR *tok;
- /* If char type is signed, sign-extend the constant. */
- if (! wide_flag)
- {
- int num_bits = num_chars * width;
+ cpp_skip_hspace (pfile);
+ if (*ip->cur == '(')
+ {
+ paren++;
+ ip->cur++; /* Skip over the paren */
+ cpp_skip_hspace (pfile);
+ }
- if (cpp_lookup (pfile, (U_CHAR *)"__CHAR_UNSIGNED__",
- sizeof ("__CHAR_UNSIGNED__")-1, -1)
- || ((result >> (num_bits - 1)) & 1) == 0)
- op.value
- = result & ((unsigned long) ~0 >> (HOST_BITS_PER_LONG - num_bits));
- else
- op.value
- = result | ~((unsigned long) ~0 >> (HOST_BITS_PER_LONG - num_bits));
- }
- else
- {
-#ifdef MULTIBYTE_CHARS
- /* Set the initial shift state and convert the next sequence. */
- result = 0;
- /* In all locales L'\0' is zero and mbtowc will return zero,
- so don't use it. */
- if (num_chars > 1
- || (num_chars == 1 && token_buffer[0] != '\0'))
- {
- wchar_t wc;
- (void) mbtowc (NULL_PTR, NULL_PTR, 0);
- if (mbtowc (& wc, token_buffer, num_chars) == num_chars)
- result = wc;
- else
- cpp_pedwarn (pfile,"Ignoring invalid multibyte character");
- }
-#endif
- op.value = result;
+ if (!is_idstart[*ip->cur])
+ goto oops;
+ if (ip->cur[0] == 'L' && (ip->cur[1] == '\'' || ip->cur[1] == '"'))
+ goto oops;
+ tok = ip->cur;
+ while (is_idchar[*ip->cur])
+ ++ip->cur;
+ len = ip->cur - tok;
+ cpp_skip_hspace (pfile);
+ if (paren)
+ {
+ if (*ip->cur != ')')
+ goto oops;
+ ++ip->cur;
}
- }
+ if (cpp_lookup (pfile, tok, len, -1))
+ op.value = 1;
- /* This is always a signed type. */
- op.unsignedp = 0;
- op.op = CHAR;
-
+ }
return op;
- case CPP_NAME:
- if (CPP_WARN_UNDEF (pfile) && !skip_evaluation)
- cpp_warning (pfile, "`%.*s' is not defined",
- (int) (tok_end - tok_start), tok_start);
- return parse_number (pfile, "0", 0);
+ oops:
+ cpp_error (pfile, "`defined' without an identifier");
+ return op;
case CPP_OTHER:
/* See if it is a special token of length 2. */
@@ -454,11 +484,8 @@ cpp_lex (pfile, skip_evaluation)
&& tok_start[1] == toktab->operator[1])
break;
if (toktab->token == ERROR)
- {
- char *buf = (char *) alloca (40);
- sprintf (buf, "`%s' not allowed in operand of `#if'", tok_start);
- cpp_error (pfile, buf);
- }
+ cpp_error (pfile, "`%s' not allowed in operand of `#if'",
+ tok_start);
op.op = toktab->token;
return op;
}
@@ -484,10 +511,11 @@ cpp_lex (pfile, skip_evaluation)
If \ is followed by 000, we return 0 and leave the string pointer
after the zeros. A value of 0 does not mean end of string. */
-int
-cpp_parse_escape (pfile, string_ptr)
+HOST_WIDEST_INT
+cpp_parse_escape (pfile, string_ptr, result_mask)
cpp_reader *pfile;
char **string_ptr;
+ HOST_WIDEST_INT result_mask;
{
register int c = *(*string_ptr)++;
switch (c)
@@ -498,7 +526,7 @@ cpp_parse_escape (pfile, string_ptr)
return TARGET_BS;
case 'e':
case 'E':
- if (CPP_PEDANTIC (pfile))
+ if (CPP_OPTIONS (pfile)->pedantic)
cpp_pedwarn (pfile, "non-ANSI-standard escape sequence, `\\%c'", c);
return 033;
case 'f':
@@ -526,7 +554,7 @@ cpp_parse_escape (pfile, string_ptr)
case '6':
case '7':
{
- register int i = c - '0';
+ register HOST_WIDEST_INT i = c - '0';
register int count = 0;
while (++count < 3)
{
@@ -539,17 +567,17 @@ cpp_parse_escape (pfile, string_ptr)
break;
}
}
- if ((i & ~((1 << MAX_CHAR_TYPE_SIZE) - 1)) != 0)
+ if (i != (i & result_mask))
{
- i &= (1 << MAX_CHAR_TYPE_SIZE) - 1;
- cpp_pedwarn (pfile,
- "octal character constant does not fit in a byte");
+ i &= result_mask;
+ cpp_pedwarn (pfile, "octal escape sequence out of range");
}
return i;
}
case 'x':
{
- register unsigned i = 0, overflow = 0, digits_found = 0, digit;
+ register unsigned HOST_WIDEST_INT i = 0, overflow = 0;
+ register int digits_found = 0, digit;
for (;;)
{
c = *(*string_ptr)++;
@@ -570,11 +598,10 @@ cpp_parse_escape (pfile, string_ptr)
}
if (!digits_found)
cpp_error (pfile, "\\x used with no following hex digits");
- if (overflow | (i & ~((1 << BITS_PER_UNIT) - 1)))
+ if (overflow | (i != (i & result_mask)))
{
- i &= (1 << BITS_PER_UNIT) - 1;
- cpp_pedwarn (pfile,
- "hex character constant does not fit in a byte");
+ i &= result_mask;
+ cpp_pedwarn (pfile, "hex escape sequence out of range");
}
return i;
}
@@ -591,41 +618,41 @@ integer_overflow (pfile)
cpp_pedwarn (pfile, "integer overflow in preprocessor expression");
}
-static long
+static HOST_WIDEST_INT
left_shift (pfile, a, unsignedp, b)
cpp_reader *pfile;
- long a;
+ HOST_WIDEST_INT a;
int unsignedp;
- unsigned long b;
+ unsigned HOST_WIDEST_INT b;
{
- if (b >= HOST_BITS_PER_LONG)
+ if (b >= HOST_BITS_PER_WIDEST_INT)
{
if (! unsignedp && a != 0)
integer_overflow (pfile);
return 0;
}
else if (unsignedp)
- return (unsigned long) a << b;
+ return (unsigned HOST_WIDEST_INT) a << b;
else
{
- long l = a << b;
+ HOST_WIDEST_INT l = a << b;
if (l >> b != a)
integer_overflow (pfile);
return l;
}
}
-static long
+static HOST_WIDEST_INT
right_shift (pfile, a, unsignedp, b)
cpp_reader *pfile ATTRIBUTE_UNUSED;
- long a;
+ HOST_WIDEST_INT a;
int unsignedp;
- unsigned long b;
+ unsigned HOST_WIDEST_INT b;
{
- if (b >= HOST_BITS_PER_LONG)
- return unsignedp ? 0 : a >> (HOST_BITS_PER_LONG - 1);
+ if (b >= HOST_BITS_PER_WIDEST_INT)
+ return unsignedp ? 0 : a >> (HOST_BITS_PER_WIDEST_INT - 1);
else if (unsignedp)
- return (unsigned long) a >> b;
+ return (unsigned HOST_WIDEST_INT) a >> b;
else
return a >> b;
}
@@ -649,12 +676,13 @@ right_shift (pfile, a, unsignedp, b)
#define COMPARE(OP) \
top->unsignedp = 0;\
- top->value = (unsigned1 || unsigned2) ? (unsigned long) v1 OP v2 : (v1 OP v2)
+ top->value = (unsigned1 || unsigned2) \
+ ? (unsigned HOST_WIDEST_INT) v1 OP (unsigned HOST_WIDEST_INT) v2 : (v1 OP v2)
/* Parse and evaluate a C expression, reading from PFILE.
Returns the value of the expression. */
-HOST_WIDE_INT
+HOST_WIDEST_INT
cpp_parse_expr (pfile)
cpp_reader *pfile;
{
@@ -734,6 +762,8 @@ cpp_parse_expr (pfile)
case '?':
lprio = COND_PRIO + 1; rprio = COND_PRIO;
goto maybe_reduce;
+ case ERROR:
+ goto syntax_error;
binop:
flags = LEFT_OPERAND_REQUIRED|RIGHT_OPERAND_REQUIRED;
rprio = lprio + 1;
@@ -757,7 +787,7 @@ cpp_parse_expr (pfile)
/* Push an operator, and check if we can reduce now. */
while (top->rprio > lprio)
{
- long v1 = top[-1].value, v2 = top[0].value;
+ HOST_WIDEST_INT v1 = top[-1].value, v2 = top[0].value;
int unsigned1 = top[-1].unsignedp, unsigned2 = top[0].unsignedp;
top--;
if ((top[1].flags & LEFT_OPERAND_REQUIRED)
@@ -812,7 +842,7 @@ cpp_parse_expr (pfile)
case '*':
top->unsignedp = unsigned1 || unsigned2;
if (top->unsignedp)
- top->value = (unsigned long) v1 * v2;
+ top->value = (unsigned HOST_WIDEST_INT) v1 * v2;
else if (!skip_evaluation)
{
top->value = v1 * v2;
@@ -832,7 +862,7 @@ cpp_parse_expr (pfile)
}
top->unsignedp = unsigned1 || unsigned2;
if (top->unsignedp)
- top->value = (unsigned long) v1 / v2;
+ top->value = (unsigned HOST_WIDEST_INT) v1 / v2;
else
{
top->value = v1 / v2;
@@ -850,7 +880,7 @@ cpp_parse_expr (pfile)
}
top->unsignedp = unsigned1 || unsigned2;
if (top->unsignedp)
- top->value = (unsigned long) v1 % v2;
+ top->value = (unsigned HOST_WIDEST_INT) v1 % v2;
else
top->value = v1 % v2;
break;
@@ -967,11 +997,11 @@ cpp_parse_expr (pfile)
}
break;
default:
- fprintf (stderr,
- top[1].op >= ' ' && top[1].op <= '~'
- ? "unimplemented operator '%c'\n"
- : "unimplemented operator '\\%03o'\n",
- top[1].op);
+ cpp_error (pfile,
+ (top[1].op >= ' ' && top[1].op <= '~'
+ ? "unimplemented operator '%c'\n"
+ : "unimplemented operator '\\%03o'\n"),
+ top[1].op);
}
}
if (op.op == 0)
diff --git a/gcc/cpphash.c b/gcc/cpphash.c
index 6aa9e9c7c12..ff63bd81681 100644
--- a/gcc/cpphash.c
+++ b/gcc/cpphash.c
@@ -1,5 +1,5 @@
-/* Part of CPP library. (Macro hash table support.)
- Copyright (C) 1986, 87, 89, 92-95, 1996 Free Software Foundation, Inc.
+/* Part of CPP library. (Macro handling.)
+ Copyright (C) 1986, 87, 89, 92-95, 1996, 1998 Free Software Foundation, Inc.
Written by Per Bothner, 1994.
Based on CCCP program by Paul Rubin, June 1986
Adapted to ANSI C, Richard Stallman, Jan 1987
@@ -24,11 +24,65 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "config.h"
#include "system.h"
-#include "gansidecl.h"
#include "cpplib.h"
#include "cpphash.h"
-extern char *xmalloc PARAMS ((unsigned));
+static int comp_def_part PARAMS ((int, U_CHAR *, int, U_CHAR *,
+ int, int));
+static int change_newlines PARAMS ((U_CHAR *, int));
+static void push_macro_expansion PARAMS ((cpp_reader *,
+ U_CHAR *, int, HASHNODE *));
+static int unsafe_chars PARAMS ((int, int));
+
+#define SKIP_WHITE_SPACE(p) do { while (is_hor_space[*p]) p++; } while (0)
+#define CPP_IS_MACRO_BUFFER(PBUF) ((PBUF)->data != NULL)
+#define FORWARD(N) CPP_FORWARD (CPP_BUFFER (pfile), (N))
+
+extern char *version_string;
+
+/* The arglist structure is built by create_definition to tell
+ collect_expansion where the argument names begin. That
+ is, for a define like "#define f(x,y,z) foo+x-bar*y", the arglist
+ would contain pointers to the strings x, y, and z.
+ collect_expansion would then build a DEFINITION node,
+ with reflist nodes pointing to the places x, y, and z had
+ appeared. So the arglist is just convenience data passed
+ between these two routines. It is not kept around after
+ the current #define has been processed and entered into the
+ hash table. */
+
+struct arglist
+{
+ struct arglist *next;
+ U_CHAR *name;
+ int length;
+ int argno;
+ char rest_args;
+};
+
+/* This structure represents one parsed argument in a macro call.
+ `raw' points to the argument text as written (`raw_length' is its length).
+ `expanded' points to the argument's macro-expansion
+ (its length is `expand_length').
+ `stringified_length' is the length the argument would have
+ if stringified.
+ `use_count' is the number of times this macro arg is substituted
+ into the macro. If the actual use count exceeds 10,
+ the value stored is 10. */
+
+/* raw and expanded are relative to ARG_BASE */
+#define ARG_BASE ((pfile)->token_buffer)
+
+struct argdata
+{
+ /* Strings relative to pfile->token_buffer */
+ long raw, expanded, stringified;
+ int raw_length, expand_length;
+ int stringified_length;
+ char newlines;
+ char use_count;
+};
+
/* Return hash function on name. must be compatible with the one
computed a step at a time, elsewhere */
@@ -48,7 +102,7 @@ hashf (name, len, hashsize)
}
/* Find the most recent hash node for name "name" (ending with first
- non-identifier char) installed by install
+ non-identifier char) installed by cpp_install
If LEN is >= 0, it is the length of the name.
Otherwise, compute the length by scanning the entire name.
@@ -68,19 +122,20 @@ cpp_lookup (pfile, name, len, hash)
if (len < 0)
{
- for (bp = name; is_idchar[*bp]; bp++) ;
+ for (bp = name; is_idchar[*bp]; bp++);
len = bp - name;
}
if (hash < 0)
hash = hashf (name, len, HASHSIZE);
- bucket = hashtab[hash];
- while (bucket) {
- if (bucket->length == len && strncmp (bucket->name, name, len) == 0)
- return bucket;
- bucket = bucket->next;
- }
+ bucket = pfile->hashtab[hash];
+ while (bucket)
+ {
+ if (bucket->length == len && strncmp (bucket->name, name, len) == 0)
+ return bucket;
+ bucket = bucket->next;
+ }
return (HASHNODE *) 0;
}
@@ -132,9 +187,9 @@ delete_macro (hp)
}
/* Install a name in the main hash table, even if it is already there.
- name stops with first non alphanumeric, except leading '#'.
- caller must check against redefinition if that is desired.
- delete_macro () removes things installed by install () in fifo order.
+ Name stops with first non alphanumeric, except leading '#'.
+ Caller must check against redefinition if that is desired.
+ delete_macro () removes things installed by cpp_install () in fifo order.
this is important because of the `defined' special symbol used
in #if, and also if pushdef/popdef directives are ever implemented.
@@ -145,24 +200,25 @@ delete_macro (hp)
Otherwise, compute the hash code. */
HASHNODE *
-install (name, len, type, ivalue, value, hash)
+cpp_install (pfile, name, len, type, value, hash)
+ cpp_reader *pfile;
U_CHAR *name;
int len;
enum node_type type;
- int ivalue;
- char *value;
+ const char *value;
int hash;
{
register HASHNODE *hp;
register int i, bucket;
- register U_CHAR *p, *q;
+ register U_CHAR *p;
- if (len < 0) {
- p = name;
- while (is_idchar[*p])
- p++;
- len = p - name;
- }
+ if (len < 0)
+ {
+ p = name;
+ while (is_idchar[*p])
+ p++;
+ len = p - name;
+ }
if (hash < 0)
hash = hashf (name, len, HASHSIZE);
@@ -170,35 +226,1436 @@ install (name, len, type, ivalue, value, hash)
i = sizeof (HASHNODE) + len + 1;
hp = (HASHNODE *) xmalloc (i);
bucket = hash;
- hp->bucket_hdr = &hashtab[bucket];
- hp->next = hashtab[bucket];
- hashtab[bucket] = hp;
+ hp->bucket_hdr = &pfile->hashtab[bucket];
+ hp->next = pfile->hashtab[bucket];
+ pfile->hashtab[bucket] = hp;
hp->prev = NULL;
if (hp->next != NULL)
hp->next->prev = hp;
hp->type = type;
hp->length = len;
- if (hp->type == T_CONST)
- hp->value.ival = ivalue;
- else
- hp->value.cpval = value;
+ hp->value.cpval = value;
hp->name = ((U_CHAR *) hp) + sizeof (HASHNODE);
- p = hp->name;
- q = name;
- for (i = 0; i < len; i++)
- *p++ = *q++;
+ bcopy (name, hp->name, len);
hp->name[len] = 0;
return hp;
}
-void
-cpp_hash_cleanup (pfile)
+static int
+macro_cleanup (pbuf, pfile)
+ cpp_buffer *pbuf;
cpp_reader *pfile ATTRIBUTE_UNUSED;
{
+ HASHNODE *macro = (HASHNODE *) pbuf->data;
+ if (macro->type == T_DISABLED)
+ macro->type = T_MACRO;
+ if (macro->type != T_MACRO || pbuf->buf != macro->value.defn->expansion)
+ free (pbuf->buf);
+ return 0;
+}
+
+
+/* Read a replacement list for a macro with parameters.
+ Build the DEFINITION structure.
+ Reads characters of text starting at BUF until END.
+ ARGLIST specifies the formal parameters to look for
+ in the text of the definition; NARGS is the number of args
+ in that list, or -1 for a macro name that wants no argument list.
+ MACRONAME is the macro name itself (so we can avoid recursive expansion)
+ and NAMELEN is its length in characters.
+
+ Note that comments, backslash-newlines, and leading white space
+ have already been deleted from the argument. */
+
+static DEFINITION *
+collect_expansion (pfile, buf, limit, nargs, arglist)
+ cpp_reader *pfile;
+ U_CHAR *buf, *limit;
+ int nargs;
+ struct arglist *arglist;
+{
+ DEFINITION *defn;
+ register U_CHAR *p, *lastp, *exp_p;
+ struct reflist *endpat = NULL;
+ /* Pointer to first nonspace after last ## seen. */
+ U_CHAR *concat = 0;
+ /* Pointer to first nonspace after last single-# seen. */
+ U_CHAR *stringify = 0;
+ int maxsize;
+ int expected_delimiter = '\0';
+
+ /* Scan thru the replacement list, ignoring comments and quoted
+ strings, picking up on the macro calls. It does a linear search
+ thru the arg list on every potential symbol. Profiling might say
+ that something smarter should happen. */
+
+ if (limit < buf)
+ abort ();
+
+ /* Find the beginning of the trailing whitespace. */
+ p = buf;
+ while (p < limit && is_space[limit[-1]])
+ limit--;
+
+ /* Allocate space for the text in the macro definition.
+ Leading and trailing whitespace chars need 2 bytes each.
+ Each other input char may or may not need 1 byte,
+ so this is an upper bound. The extra 5 are for invented
+ leading and trailing newline-marker and final null. */
+ maxsize = (sizeof (DEFINITION)
+ + (limit - p) + 5);
+ /* Occurrences of '@' get doubled, so allocate extra space for them. */
+ while (p < limit)
+ if (*p++ == '@')
+ maxsize++;
+ defn = (DEFINITION *) xcalloc (1, maxsize);
+
+ defn->nargs = nargs;
+ exp_p = defn->expansion = (U_CHAR *) defn + sizeof (DEFINITION);
+ lastp = exp_p;
+
+ p = buf;
+
+ /* Add one initial space escape-marker to prevent accidental
+ token-pasting (often removed by macroexpand). */
+ *exp_p++ = '@';
+ *exp_p++ = ' ';
+
+ if (limit - p >= 2 && p[0] == '#' && p[1] == '#')
+ {
+ cpp_error (pfile, "`##' at start of macro definition");
+ p += 2;
+ }
+
+ /* Process the main body of the definition. */
+ while (p < limit)
+ {
+ int skipped_arg = 0;
+ register U_CHAR c = *p++;
+
+ *exp_p++ = c;
+
+ if (!CPP_TRADITIONAL (pfile))
+ {
+ switch (c)
+ {
+ case '\'':
+ case '\"':
+ if (expected_delimiter != '\0')
+ {
+ if (c == expected_delimiter)
+ expected_delimiter = '\0';
+ }
+ else
+ expected_delimiter = c;
+ break;
+
+ case '\\':
+ if (p < limit && expected_delimiter)
+ {
+ /* In a string, backslash goes through
+ and makes next char ordinary. */
+ *exp_p++ = *p++;
+ }
+ break;
+
+ case '@':
+ /* An '@' in a string or character constant stands for itself,
+ and does not need to be escaped. */
+ if (!expected_delimiter)
+ *exp_p++ = c;
+ break;
+
+ case '#':
+ /* # is ordinary inside a string. */
+ if (expected_delimiter)
+ break;
+ if (p < limit && *p == '#')
+ {
+ /* ##: concatenate preceding and following tokens. */
+ /* Take out the first #, discard preceding whitespace. */
+ exp_p--;
+ while (exp_p > lastp && is_hor_space[exp_p[-1]])
+ --exp_p;
+ /* Skip the second #. */
+ p++;
+ /* Discard following whitespace. */
+ SKIP_WHITE_SPACE (p);
+ concat = p;
+ if (p == limit)
+ cpp_error (pfile, "`##' at end of macro definition");
+ }
+ else if (nargs >= 0)
+ {
+ /* Single #: stringify following argument ref.
+ Don't leave the # in the expansion. */
+ exp_p--;
+ SKIP_WHITE_SPACE (p);
+ if (p == limit || !is_idstart[*p]
+ || (*p == 'L' && p + 1 < limit && (p[1] == '\'' ||
+ p[1] == '"')))
+ cpp_error (pfile,
+ "`#' operator is not followed by a macro argument name");
+ else
+ stringify = p;
+ }
+ break;
+ }
+ }
+ else
+ {
+ /* In -traditional mode, recognize arguments inside strings and
+ character constants, and ignore special properties of #.
+ Arguments inside strings are considered "stringified", but no
+ extra quote marks are supplied. */
+ switch (c)
+ {
+ case '\'':
+ case '\"':
+ if (expected_delimiter != '\0')
+ {
+ if (c == expected_delimiter)
+ expected_delimiter = '\0';
+ }
+ else
+ expected_delimiter = c;
+ break;
+
+ case '\\':
+ /* Backslash quotes delimiters and itself,
+ but not macro args. */
+ if (expected_delimiter != 0 && p < limit
+ && (*p == expected_delimiter || *p == '\\'))
+ {
+ *exp_p++ = *p++;
+ continue;
+ }
+ break;
+
+ case '/':
+ if (expected_delimiter != '\0')
+ /* No comments inside strings. */
+ break;
+ if (*p == '*')
+ {
+ /* If we find a comment that wasn't removed by
+ handle_directive, this must be -traditional.
+ So replace the comment with nothing at all. */
+ exp_p--;
+ p += 1;
+ while (p < limit && !(p[-2] == '*' && p[-1] == '/'))
+ p++;
+#if 0
+ /* Mark this as a concatenation-point,
+ as if it had been ##. */
+ concat = p;
+#endif
+ }
+ break;
+ }
+ }
+
+ /* Handle the start of a symbol. */
+ if (is_idchar[c] && nargs > 0)
+ {
+ U_CHAR *id_beg = p - 1;
+ int id_len;
+
+ --exp_p;
+ while (p != limit && is_idchar[*p])
+ p++;
+ id_len = p - id_beg;
+
+ if (is_idstart[c]
+ && !(id_len == 1 && c == 'L' && (*p == '\'' || *p == '"')))
+ {
+ register struct arglist *arg;
+
+ for (arg = arglist; arg != NULL; arg = arg->next)
+ {
+ struct reflist *tpat;
+
+ if (arg->name[0] == c
+ && arg->length == id_len
+ && strncmp (arg->name, id_beg, id_len) == 0)
+ {
+ if (expected_delimiter && CPP_OPTIONS
+ (pfile)->warn_stringify)
+ {
+ if (CPP_TRADITIONAL (pfile))
+ {
+ cpp_warning (pfile,
+ "macro argument `%.*s' is stringified.",
+ id_len, arg->name);
+ }
+ else
+ {
+ cpp_warning (pfile,
+ "macro arg `%.*s' would be stringified with -traditional.",
+ id_len, arg->name);
+ }
+ }
+ /* If ANSI, don't actually substitute
+ inside a string. */
+ if (!CPP_TRADITIONAL (pfile) && expected_delimiter)
+ break;
+ /* make a pat node for this arg and append it
+ to the end of the pat list */
+ tpat = (struct reflist *)
+ xmalloc (sizeof (struct reflist));
+ tpat->next = NULL;
+ tpat->raw_before = concat == id_beg;
+ tpat->raw_after = 0;
+ tpat->rest_args = arg->rest_args;
+ tpat->stringify = (CPP_TRADITIONAL (pfile)
+ ? expected_delimiter != '\0'
+ : stringify == id_beg);
+
+ if (endpat == NULL)
+ defn->pattern = tpat;
+ else
+ endpat->next = tpat;
+ endpat = tpat;
+
+ tpat->argno = arg->argno;
+ tpat->nchars = exp_p - lastp;
+ {
+ register U_CHAR *p1 = p;
+ SKIP_WHITE_SPACE (p1);
+ if (p1 + 2 <= limit && p1[0] == '#' && p1[1] == '#')
+ tpat->raw_after = 1;
+ }
+ lastp = exp_p;
+ skipped_arg = 1;
+ break;
+ }
+ }
+ }
+
+ /* If this was not a macro arg, copy it into the expansion. */
+ if (!skipped_arg)
+ {
+ register U_CHAR *lim1 = p;
+ p = id_beg;
+ while (p != lim1)
+ *exp_p++ = *p++;
+ if (stringify == id_beg)
+ cpp_error (pfile,
+ "`#' operator should be followed by a macro argument name");
+ }
+ }
+ }
+
+ if (!CPP_TRADITIONAL (pfile) && expected_delimiter == 0)
+ {
+ /* If ANSI, put in a "@ " marker to prevent token pasting.
+ But not if "inside a string" (which in ANSI mode
+ happens only for -D option). */
+ *exp_p++ = '@';
+ *exp_p++ = ' ';
+ }
+
+ *exp_p = '\0';
+
+ defn->length = exp_p - defn->expansion;
+
+ /* Crash now if we overrun the allocated size. */
+ if (defn->length + 1 > maxsize)
+ abort ();
+
+#if 0
+/* This isn't worth the time it takes. */
+ /* give back excess storage */
+ defn->expansion = (U_CHAR *) xrealloc (defn->expansion, defn->length + 1);
+#endif
+
+ return defn;
+}
+
+/*
+ * special extension string that can be added to the last macro argument to
+ * allow it to absorb the "rest" of the arguments when expanded. Ex:
+ * #define wow(a, b...) process (b, a, b)
+ * { wow (1, 2, 3); } -> { process (2, 3, 1, 2, 3); }
+ * { wow (one, two); } -> { process (two, one, two); }
+ * if this "rest_arg" is used with the concat token '##' and if it is not
+ * supplied then the token attached to with ## will not be outputted. Ex:
+ * #define wow (a, b...) process (b ## , a, ## b)
+ * { wow (1, 2); } -> { process (2, 1, 2); }
+ * { wow (one); } -> { process (one); {
+ */
+static char rest_extension[] = "...";
+#define REST_EXTENSION_LENGTH (sizeof (rest_extension) - 1)
+
+/* Create a DEFINITION node from a #define directive. Arguments are
+ as for do_define. */
+
+MACRODEF
+create_definition (buf, limit, pfile, predefinition)
+ U_CHAR *buf, *limit;
+ cpp_reader *pfile;
+ int predefinition;
+{
+ U_CHAR *bp; /* temp ptr into input buffer */
+ U_CHAR *symname; /* remember where symbol name starts */
+ int sym_length; /* and how long it is */
+ int rest_args = 0;
+ long line, col;
+ char *file = CPP_BUFFER (pfile) ? CPP_BUFFER (pfile)->nominal_fname : "";
+ DEFINITION *defn;
+ int arglengths = 0; /* Accumulate lengths of arg names
+ plus number of args. */
+ MACRODEF mdef;
+ cpp_buf_line_and_col (CPP_BUFFER (pfile), &line, &col);
+
+ bp = buf;
+
+ while (is_hor_space[*bp])
+ bp++;
+
+ symname = bp; /* remember where it starts */
+
+ sym_length = check_macro_name (pfile, bp, 0);
+ bp += sym_length;
+
+ /* Lossage will occur if identifiers or control keywords are broken
+ across lines using backslash. This is not the right place to take
+ care of that. */
+
+ if (*bp == '(')
+ {
+ struct arglist *arg_ptrs = NULL;
+ int argno = 0;
+
+ bp++; /* skip '(' */
+ SKIP_WHITE_SPACE (bp);
+
+ /* Loop over macro argument names. */
+ while (*bp != ')')
+ {
+ struct arglist *temp;
+
+ temp = (struct arglist *) alloca (sizeof (struct arglist));
+ temp->name = bp;
+ temp->next = arg_ptrs;
+ temp->argno = argno++;
+ temp->rest_args = 0;
+ arg_ptrs = temp;
+
+ if (rest_args)
+ cpp_pedwarn (pfile, "another parameter follows `%s'",
+ rest_extension);
+
+ if (!is_idstart[*bp])
+ cpp_pedwarn (pfile, "invalid character in macro parameter name");
+
+ /* Find the end of the arg name. */
+ while (is_idchar[*bp])
+ {
+ bp++;
+ /* do we have a "special" rest-args extension here? */
+ if ((size_t) (limit - bp) > REST_EXTENSION_LENGTH
+ && !strncmp (rest_extension, bp, REST_EXTENSION_LENGTH))
+ {
+ rest_args = 1;
+ temp->rest_args = 1;
+ break;
+ }
+ }
+ temp->length = bp - temp->name;
+ if (rest_args == 1)
+ bp += REST_EXTENSION_LENGTH;
+ arglengths += temp->length + 2;
+ SKIP_WHITE_SPACE (bp);
+ if (temp->length == 0 || (*bp != ',' && *bp != ')'))
+ {
+ cpp_error (pfile,
+ "badly punctuated parameter list in `#define'");
+ goto nope;
+ }
+ if (*bp == ',')
+ {
+ bp++;
+ SKIP_WHITE_SPACE (bp);
+ }
+ if (bp >= limit)
+ {
+ cpp_error (pfile, "unterminated parameter list in `#define'");
+ goto nope;
+ }
+ {
+ struct arglist *otemp;
+
+ for (otemp = temp->next; otemp != NULL; otemp = otemp->next)
+ if (temp->length == otemp->length
+ && strncmp (temp->name, otemp->name, temp->length) == 0)
+ {
+ U_CHAR *name;
+
+ name = (U_CHAR *) alloca (temp->length + 1);
+ (void) strncpy (name, temp->name, temp->length);
+ name[temp->length] = '\0';
+ cpp_error (pfile,
+ "duplicate argument name `%s' in `#define'",
+ name);
+ goto nope;
+ }
+ }
+ }
+
+ ++bp; /* skip paren */
+ SKIP_WHITE_SPACE (bp);
+ /* now everything from bp before limit is the definition. */
+ defn = collect_expansion (pfile, bp, limit, argno, arg_ptrs);
+ defn->rest_args = rest_args;
+
+ /* Now set defn->args.argnames to the result of concatenating
+ the argument names in reverse order
+ with comma-space between them. */
+ defn->args.argnames = (U_CHAR *) xmalloc (arglengths + 1);
+ {
+ struct arglist *temp;
+ int i = 0;
+ for (temp = arg_ptrs; temp; temp = temp->next)
+ {
+ bcopy (temp->name, &defn->args.argnames[i], temp->length);
+ i += temp->length;
+ if (temp->next != 0)
+ {
+ defn->args.argnames[i++] = ',';
+ defn->args.argnames[i++] = ' ';
+ }
+ }
+ defn->args.argnames[i] = 0;
+ }
+ }
+ else
+ {
+ /* Simple expansion or empty definition. */
+
+ if (bp < limit)
+ {
+ if (is_hor_space[*bp])
+ {
+ bp++;
+ SKIP_WHITE_SPACE (bp);
+ }
+ else
+ /* Per C9x, missing white space after the name in a #define
+ of an object-like macro is always a constraint violation. */
+ cpp_pedwarn (pfile,
+ "missing white space after `#define %.*s'",
+ sym_length, symname);
+ }
+ /* now everything from bp before limit is the definition. */
+ defn = collect_expansion (pfile, bp, limit, -1, NULL_PTR);
+ defn->args.argnames = (U_CHAR *) "";
+ }
+
+ defn->line = line;
+ defn->file = file;
+
+ /* OP is null if this is a predefinition */
+ defn->predefined = predefinition;
+ mdef.defn = defn;
+ mdef.symnam = symname;
+ mdef.symlen = sym_length;
+
+ return mdef;
+
+nope:
+ mdef.defn = 0;
+ return mdef;
+}
+
+/*
+ * Parse a macro argument and append the info on PFILE's token_buffer.
+ * REST_ARGS means to absorb the rest of the args.
+ * Return nonzero to indicate a syntax error.
+ */
+
+static enum cpp_token
+macarg (pfile, rest_args)
+ cpp_reader *pfile;
+ int rest_args;
+{
+ int paren = 0;
+ enum cpp_token token;
+ char save_put_out_comments = CPP_OPTIONS (pfile)->put_out_comments;
+ CPP_OPTIONS (pfile)->put_out_comments = 0;
+
+ /* Try to parse as much of the argument as exists at this
+ input stack level. */
+ pfile->no_macro_expand++;
+ CPP_OPTIONS (pfile)->no_line_commands++;
+ for (;;)
+ {
+ token = cpp_get_token (pfile);
+ switch (token)
+ {
+ case CPP_EOF:
+ goto done;
+ case CPP_POP:
+ /* If we've hit end of file, it's an error (reported by caller).
+ Ditto if it's the end of cpp_expand_to_buffer text.
+ If we've hit end of macro, just continue. */
+ if (!CPP_IS_MACRO_BUFFER (CPP_BUFFER (pfile)))
+ goto done;
+ break;
+ case CPP_LPAREN:
+ paren++;
+ break;
+ case CPP_RPAREN:
+ if (--paren < 0)
+ goto found;
+ break;
+ case CPP_COMMA:
+ /* if we've returned to lowest level and
+ we aren't absorbing all args */
+ if (paren == 0 && rest_args == 0)
+ goto found;
+ break;
+ found:
+ /* Remove ',' or ')' from argument buffer. */
+ CPP_ADJUST_WRITTEN (pfile, -1);
+ goto done;
+ default:;
+ }
+ }
+
+done:
+ CPP_OPTIONS (pfile)->put_out_comments = save_put_out_comments;
+ CPP_OPTIONS (pfile)->no_line_commands--;
+ pfile->no_macro_expand--;
+
+ return token;
+}
+
+/* Turn newlines to spaces in the string of length LENGTH at START,
+ except inside of string constants.
+ The string is copied into itself with its beginning staying fixed. */
+
+static int
+change_newlines (start, length)
+ U_CHAR *start;
+ int length;
+{
+ register U_CHAR *ibp;
+ register U_CHAR *obp;
+ register U_CHAR *limit;
+ register int c;
+
+ ibp = start;
+ limit = start + length;
+ obp = start;
+
+ while (ibp < limit)
+ {
+ *obp++ = c = *ibp++;
+ switch (c)
+ {
+
+ case '\'':
+ case '\"':
+ /* Notice and skip strings, so that we don't
+ delete newlines in them. */
+ {
+ int quotec = c;
+ while (ibp < limit)
+ {
+ *obp++ = c = *ibp++;
+ if (c == quotec)
+ break;
+ if (c == '\n' && quotec == '\'')
+ break;
+ }
+ }
+ break;
+ }
+ }
+
+ return obp - start;
+}
+
+
+static struct tm *
+timestamp (pfile)
+ cpp_reader *pfile;
+{
+ if (!pfile->timebuf)
+ {
+ time_t t = time ((time_t *) 0);
+ pfile->timebuf = localtime (&t);
+ }
+ return pfile->timebuf;
+}
+
+static char *monthnames[] =
+{
+ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
+};
+
+/*
+ * expand things like __FILE__. Place the expansion into the output
+ * buffer *without* rescanning.
+ */
+
+static void
+special_symbol (hp, pfile)
+ HASHNODE *hp;
+ cpp_reader *pfile;
+{
+ const char *buf;
+ int len;
+ cpp_buffer *ip;
+
+ switch (hp->type)
+ {
+ case T_FILE:
+ case T_BASE_FILE:
+ {
+ ip = CPP_BUFFER (pfile);
+ if (hp->type == T_BASE_FILE)
+ {
+ while (CPP_PREV_BUFFER (ip) != CPP_NULL_BUFFER (pfile))
+ ip = CPP_PREV_BUFFER (ip);
+ }
+ else
+ {
+ ip = CPP_BUFFER (pfile);
+ while (!ip->nominal_fname && ip != CPP_NULL_BUFFER (pfile))
+ ip = CPP_PREV_BUFFER (ip);
+ }
+
+ buf = ip->nominal_fname;
+
+ if (!buf)
+ buf = "";
+ CPP_RESERVE (pfile, 3 + 4 * strlen (buf));
+ quote_string (pfile, buf);
+ return;
+ }
+
+ case T_INCLUDE_LEVEL:
+ {
+ int true_indepth = 0;
+ ip = CPP_BUFFER (pfile);
+ for (; ip != CPP_NULL_BUFFER (pfile); ip = CPP_PREV_BUFFER (ip))
+ if (ip->fname != NULL)
+ true_indepth++;
+
+ CPP_RESERVE (pfile, 10);
+ sprintf (CPP_PWRITTEN (pfile), "%d", true_indepth);
+ CPP_ADJUST_WRITTEN (pfile, strlen (CPP_PWRITTEN (pfile)));
+ return;
+ }
+
+ case T_VERSION:
+ len = strlen (version_string);
+ CPP_RESERVE (pfile, 3 + len);
+ CPP_PUTC_Q (pfile, '"');
+ CPP_PUTS_Q (pfile, version_string, len);
+ CPP_PUTC_Q (pfile, '"');
+ CPP_NUL_TERMINATE_Q (pfile);
+ return;
+
+ case T_CONST:
+ buf = hp->value.cpval;
+ if (!buf)
+ return;
+ if (*buf == '\0')
+ buf = "@ ";
+
+ len = strlen (buf);
+ CPP_RESERVE (pfile, len + 1);
+ CPP_PUTS_Q (pfile, buf, len);
+ CPP_NUL_TERMINATE_Q (pfile);
+ return;
+
+ case T_STDC:
+ CPP_RESERVE (pfile, 2);
+#ifdef STDC_0_IN_SYSTEM_HEADERS
+ ip = CPP_BUFFER (pfile);
+ while (!ip->nominal_fname && ip != CPP_NULL_BUFFER (pfile))
+ ip = CPP_PREV_BUFFER (ip);
+ if (ip->system_header_p
+ && !cpp_lookup (pfile, (U_CHAR *) "__STRICT_ANSI__", 15, -1))
+ CPP_PUTC_Q (pfile, '0');
+ else
+#endif
+ CPP_PUTC_Q (pfile, '1');
+ CPP_NUL_TERMINATE_Q (pfile);
+ return;
+
+ case T_SPECLINE:
+ {
+ long line;
+ cpp_buf_line_and_col (CPP_BUFFER (pfile), &line, NULL);
+
+ CPP_RESERVE (pfile, 10);
+ sprintf (CPP_PWRITTEN (pfile), "%ld", line);
+ CPP_ADJUST_WRITTEN (pfile, strlen (CPP_PWRITTEN (pfile)));
+ return;
+ }
+
+ case T_DATE:
+ case T_TIME:
+ {
+ struct tm *timebuf;
+
+ CPP_RESERVE (pfile, 20);
+ timebuf = timestamp (pfile);
+ if (hp->type == T_DATE)
+ sprintf (CPP_PWRITTEN (pfile), "\"%s %2d %4d\"",
+ monthnames[timebuf->tm_mon],
+ timebuf->tm_mday, timebuf->tm_year + 1900);
+ else
+ sprintf (CPP_PWRITTEN (pfile), "\"%02d:%02d:%02d\"",
+ timebuf->tm_hour, timebuf->tm_min, timebuf->tm_sec);
+
+ CPP_ADJUST_WRITTEN (pfile, strlen (CPP_PWRITTEN (pfile)));
+ return;
+ }
+
+ default:
+ cpp_fatal (pfile, "cpplib internal error: invalid special hash type");
+ return;
+ }
+
+ /* This point should be unreachable. */
+ abort ();
+}
+
+/* Expand a macro call.
+ HP points to the symbol that is the macro being called.
+ Put the result of expansion onto the input stack
+ so that subsequent input by our caller will use it.
+
+ If macro wants arguments, caller has already verified that
+ an argument list follows; arguments come from the input stack. */
+
+void
+macroexpand (pfile, hp)
+ cpp_reader *pfile;
+ HASHNODE *hp;
+{
+ int nargs;
+ DEFINITION *defn;
+ register U_CHAR *xbuf;
+ long start_line, start_column;
+ int xbuf_len;
+ struct argdata *args;
+ long old_written = CPP_WRITTEN (pfile);
+#if 0
+ int start_line = instack[indepth].lineno;
+#endif
+ int rest_args, rest_zero;
register int i;
- for (i = HASHSIZE; --i >= 0; )
+
+#if 0
+ /* This macro is being used inside a #if, which means it must be */
+ /* recorded as a precondition. */
+ if (pcp_inside_if && pcp_outfile && defn->predefined)
+ dump_single_macro (hp, pcp_outfile);
+#endif
+
+ cpp_buf_line_and_col (cpp_file_buffer (pfile), &start_line, &start_column);
+
+ /* Check for and handle special symbols. */
+ if (hp->type != T_MACRO)
+ {
+ special_symbol (hp, pfile);
+ xbuf_len = CPP_WRITTEN (pfile) - old_written;
+ xbuf = (U_CHAR *) xmalloc (xbuf_len + 1);
+ CPP_SET_WRITTEN (pfile, old_written);
+ bcopy (CPP_PWRITTEN (pfile), xbuf, xbuf_len + 1);
+ push_macro_expansion (pfile, xbuf, xbuf_len, hp);
+ CPP_BUFFER (pfile)->has_escapes = 1;
+ return;
+ }
+
+ defn = hp->value.defn;
+ nargs = defn->nargs;
+ pfile->output_escapes++;
+
+ if (nargs >= 0)
{
- while (hashtab[i])
- delete_macro (hashtab[i]);
+ enum cpp_token token;
+
+ args = (struct argdata *) alloca ((nargs + 1) * sizeof (struct argdata));
+
+ for (i = 0; i < nargs; i++)
+ {
+ args[i].raw = args[i].expanded = 0;
+ args[i].raw_length = 0;
+ args[i].expand_length = args[i].stringified_length = -1;
+ args[i].use_count = 0;
+ }
+
+ /* Parse all the macro args that are supplied. I counts them.
+ The first NARGS args are stored in ARGS.
+ The rest are discarded. If rest_args is set then we assume
+ macarg absorbed the rest of the args. */
+ i = 0;
+ rest_args = 0;
+ rest_args = 0;
+ FORWARD (1); /* Discard open-parenthesis before first arg. */
+ do
+ {
+ if (rest_args)
+ continue;
+ if (i < nargs || (nargs == 0 && i == 0))
+ {
+ /* if we are working on last arg which absorbs rest of args... */
+ if (i == nargs - 1 && defn->rest_args)
+ rest_args = 1;
+ args[i].raw = CPP_WRITTEN (pfile);
+ token = macarg (pfile, rest_args);
+ args[i].raw_length = CPP_WRITTEN (pfile) - args[i].raw;
+ args[i].newlines = 0; /* FIXME */
+ }
+ else
+ token = macarg (pfile, 0);
+ if (token == CPP_EOF || token == CPP_POP)
+ {
+ cpp_error_with_line (pfile, start_line, start_column,
+ "unterminated macro call");
+ return;
+ }
+ i++;
+ }
+ while (token == CPP_COMMA);
+
+ /* If we got one arg but it was just whitespace, call that 0 args. */
+ if (i == 1)
+ {
+ register U_CHAR *bp = ARG_BASE + args[0].raw;
+ register U_CHAR *lim = bp + args[0].raw_length;
+ /* cpp.texi says for foo ( ) we provide one argument.
+ However, if foo wants just 0 arguments, treat this as 0. */
+ if (nargs == 0)
+ while (bp != lim && is_space[*bp])
+ bp++;
+ if (bp == lim)
+ i = 0;
+ }
+
+ /* Don't output an error message if we have already output one for
+ a parse error above. */
+ rest_zero = 0;
+ if (nargs == 0 && i > 0)
+ {
+ cpp_error (pfile, "arguments given to macro `%s'", hp->name);
+ }
+ else if (i < nargs)
+ {
+ /* traditional C allows foo() if foo wants one argument. */
+ if (nargs == 1 && i == 0 && CPP_TRADITIONAL (pfile))
+ ;
+ /* the rest args token is allowed to absorb 0 tokens */
+ else if (i == nargs - 1 && defn->rest_args)
+ rest_zero = 1;
+ else if (i == 0)
+ cpp_error (pfile, "macro `%s' used without args", hp->name);
+ else if (i == 1)
+ cpp_error (pfile, "macro `%s' used with just one arg", hp->name);
+ else
+ cpp_error (pfile, "macro `%s' used with only %d args",
+ hp->name, i);
+ }
+ else if (i > nargs)
+ {
+ cpp_error (pfile,
+ "macro `%s' used with too many (%d) args", hp->name, i);
+ }
+ }
+
+ /* If macro wants zero args, we parsed the arglist for checking only.
+ Read directly from the macro definition. */
+ if (nargs <= 0)
+ {
+ xbuf = defn->expansion;
+ xbuf_len = defn->length;
+ }
+ else
+ {
+ register U_CHAR *exp = defn->expansion;
+ register int offset; /* offset in expansion,
+ copied a piece at a time */
+ register int totlen; /* total amount of exp buffer filled so far */
+
+ register struct reflist *ap, *last_ap;
+
+ /* Macro really takes args. Compute the expansion of this call. */
+
+ /* Compute length in characters of the macro's expansion.
+ Also count number of times each arg is used. */
+ xbuf_len = defn->length;
+ for (ap = defn->pattern; ap != NULL; ap = ap->next)
+ {
+ if (ap->stringify)
+ {
+ register struct argdata *arg = &args[ap->argno];
+ /* Stringify if it hasn't already been */
+ if (arg->stringified_length < 0)
+ {
+ int arglen = arg->raw_length;
+ int escaped = 0;
+ int in_string = 0;
+ int c;
+ /* Initially need_space is -1. Otherwise, 1 means the
+ previous character was a space, but we suppressed it;
+ 0 means the previous character was a non-space. */
+ int need_space = -1;
+ i = 0;
+ arg->stringified = CPP_WRITTEN (pfile);
+ if (!CPP_TRADITIONAL (pfile))
+ CPP_PUTC (pfile, '\"'); /* insert beginning quote */
+ for (; i < arglen; i++)
+ {
+ c = (ARG_BASE + arg->raw)[i];
+
+ if (!in_string)
+ {
+ /* Internal sequences of whitespace are
+ replaced by one space except within
+ a string or char token. */
+ if (is_space[c])
+ {
+ if (CPP_WRITTEN (pfile) > (unsigned) arg->stringified
+ && (CPP_PWRITTEN (pfile))[-1] == '@')
+ {
+ /* "@ " escape markers are removed */
+ CPP_ADJUST_WRITTEN (pfile, -1);
+ continue;
+ }
+ if (need_space == 0)
+ need_space = 1;
+ continue;
+ }
+ else if (need_space > 0)
+ CPP_PUTC (pfile, ' ');
+ need_space = 0;
+ }
+
+ if (escaped)
+ escaped = 0;
+ else
+ {
+ if (c == '\\')
+ escaped = 1;
+ if (in_string)
+ {
+ if (c == in_string)
+ in_string = 0;
+ }
+ else if (c == '\"' || c == '\'')
+ in_string = c;
+ }
+
+ /* Escape these chars */
+ if (c == '\"' || (in_string && c == '\\'))
+ CPP_PUTC (pfile, '\\');
+ if (ISPRINT (c))
+ CPP_PUTC (pfile, c);
+ else
+ {
+ CPP_RESERVE (pfile, 4);
+ sprintf ((char *) CPP_PWRITTEN (pfile), "\\%03o",
+ (unsigned int) c);
+ CPP_ADJUST_WRITTEN (pfile, 4);
+ }
+ }
+ if (!CPP_TRADITIONAL (pfile))
+ CPP_PUTC (pfile, '\"'); /* insert ending quote */
+ arg->stringified_length
+ = CPP_WRITTEN (pfile) - arg->stringified;
+ }
+ xbuf_len += args[ap->argno].stringified_length;
+ }
+ else if (ap->raw_before || ap->raw_after || CPP_TRADITIONAL (pfile))
+ /* Add 4 for two newline-space markers to prevent
+ token concatenation. */
+ xbuf_len += args[ap->argno].raw_length + 4;
+ else
+ {
+ /* We have an ordinary (expanded) occurrence of the arg.
+ So compute its expansion, if we have not already. */
+ if (args[ap->argno].expand_length < 0)
+ {
+ args[ap->argno].expanded = CPP_WRITTEN (pfile);
+ cpp_expand_to_buffer (pfile,
+ ARG_BASE + args[ap->argno].raw,
+ args[ap->argno].raw_length);
+
+ args[ap->argno].expand_length
+ = CPP_WRITTEN (pfile) - args[ap->argno].expanded;
+ }
+
+ /* Add 4 for two newline-space markers to prevent
+ token concatenation. */
+ xbuf_len += args[ap->argno].expand_length + 4;
+ }
+ if (args[ap->argno].use_count < 10)
+ args[ap->argno].use_count++;
+ }
+
+ xbuf = (U_CHAR *) xmalloc (xbuf_len + 1);
+
+ /* Generate in XBUF the complete expansion
+ with arguments substituted in.
+ TOTLEN is the total size generated so far.
+ OFFSET is the index in the definition
+ of where we are copying from. */
+ offset = totlen = 0;
+ for (last_ap = NULL, ap = defn->pattern; ap != NULL;
+ last_ap = ap, ap = ap->next)
+ {
+ register struct argdata *arg = &args[ap->argno];
+ int count_before = totlen;
+
+ /* Add chars to XBUF. */
+ for (i = 0; i < ap->nchars; i++, offset++)
+ xbuf[totlen++] = exp[offset];
+
+ /* If followed by an empty rest arg with concatenation,
+ delete the last run of nonwhite chars. */
+ if (rest_zero && totlen > count_before
+ && ((ap->rest_args && ap->raw_before)
+ || (last_ap != NULL && last_ap->rest_args
+ && last_ap->raw_after)))
+ {
+ /* Delete final whitespace. */
+ while (totlen > count_before && is_space[xbuf[totlen - 1]])
+ totlen--;
+
+ /* Delete the nonwhites before them. */
+ while (totlen > count_before && !is_space[xbuf[totlen - 1]])
+ totlen--;
+ }
+
+ if (ap->stringify != 0)
+ {
+ bcopy (ARG_BASE + arg->stringified,
+ xbuf + totlen, arg->stringified_length);
+ totlen += arg->stringified_length;
+ }
+ else if (ap->raw_before || ap->raw_after || CPP_TRADITIONAL (pfile))
+ {
+ U_CHAR *p1 = ARG_BASE + arg->raw;
+ U_CHAR *l1 = p1 + arg->raw_length;
+ if (ap->raw_before)
+ {
+ while (p1 != l1 && is_space[*p1])
+ p1++;
+ while (p1 != l1 && is_idchar[*p1])
+ xbuf[totlen++] = *p1++;
+ }
+ if (ap->raw_after)
+ {
+ /* Arg is concatenated after: delete trailing whitespace,
+ whitespace markers, and no-reexpansion markers. */
+ while (p1 != l1)
+ {
+ if (is_space[l1[-1]])
+ l1--;
+ else if (l1[-1] == '@')
+ {
+ U_CHAR *p2 = l1 - 1;
+ /* If whitespace is preceded by an odd number
+ of `@' signs, the last `@' was a whitespace
+ marker; drop it too. */
+ while (p2 != p1 && p2[0] == '@')
+ p2--;
+ if ((l1 - p2) & 1)
+ l1--;
+ break;
+ }
+ else if (l1[-1] == '-')
+ {
+ U_CHAR *p2 = l1 - 1;
+ /* If a `-' is preceded by an odd number of
+ `@' signs then it and the last `@' are
+ a no-reexpansion marker. */
+ while (p2 != p1 && p2[0] == '@')
+ p2--;
+ if ((l1 - p2) & 1)
+ l1 -= 2;
+ else
+ break;
+ }
+ else
+ break;
+ }
+ }
+
+ /* Delete any no-reexpansion marker that precedes
+ an identifier at the beginning of the argument. */
+ if (p1[0] == '@' && p1[1] == '-')
+ p1 += 2;
+
+ bcopy (p1, xbuf + totlen, l1 - p1);
+ totlen += l1 - p1;
+ }
+ else
+ {
+ U_CHAR *expanded = ARG_BASE + arg->expanded;
+ if (!ap->raw_before && totlen > 0 && arg->expand_length
+ && !CPP_TRADITIONAL (pfile)
+ && unsafe_chars (xbuf[totlen - 1], expanded[0]))
+ {
+ xbuf[totlen++] = '@';
+ xbuf[totlen++] = ' ';
+ }
+
+ bcopy (expanded, xbuf + totlen, arg->expand_length);
+ totlen += arg->expand_length;
+
+ if (!ap->raw_after && totlen > 0 && offset < defn->length
+ && !CPP_TRADITIONAL (pfile)
+ && unsafe_chars (xbuf[totlen - 1], exp[offset]))
+ {
+ xbuf[totlen++] = '@';
+ xbuf[totlen++] = ' ';
+ }
+
+ /* If a macro argument with newlines is used multiple times,
+ then only expand the newlines once. This avoids creating
+ output lines which don't correspond to any input line,
+ which confuses gdb and gcov. */
+ if (arg->use_count > 1 && arg->newlines > 0)
+ {
+ /* Don't bother doing change_newlines for subsequent
+ uses of arg. */
+ arg->use_count = 1;
+ arg->expand_length
+ = change_newlines (expanded, arg->expand_length);
+ }
+ }
+
+ if (totlen > xbuf_len)
+ abort ();
+ }
+
+ /* if there is anything left of the definition
+ after handling the arg list, copy that in too. */
+
+ for (i = offset; i < defn->length; i++)
+ {
+ /* if we've reached the end of the macro */
+ if (exp[i] == ')')
+ rest_zero = 0;
+ if (!(rest_zero && last_ap != NULL && last_ap->rest_args
+ && last_ap->raw_after))
+ xbuf[totlen++] = exp[i];
+ }
+
+ xbuf[totlen] = 0;
+ xbuf_len = totlen;
+
+ }
+
+ pfile->output_escapes--;
+
+ /* Now put the expansion on the input stack
+ so our caller will commence reading from it. */
+ push_macro_expansion (pfile, xbuf, xbuf_len, hp);
+ CPP_BUFFER (pfile)->has_escapes = 1;
+
+ /* Pop the space we've used in the token_buffer for argument expansion. */
+ CPP_SET_WRITTEN (pfile, old_written);
+
+ /* Recursive macro use sometimes works traditionally.
+ #define foo(x,y) bar (x (y,0), y)
+ foo (foo, baz) */
+
+ if (!CPP_TRADITIONAL (pfile))
+ hp->type = T_DISABLED;
+}
+
+/* Return 1 iff a token ending in C1 followed directly by a token C2
+ could cause mis-tokenization. */
+
+static int
+unsafe_chars (c1, c2)
+ int c1, c2;
+{
+ switch (c1)
+ {
+ case '+':
+ case '-':
+ if (c2 == c1 || c2 == '=')
+ return 1;
+ goto letter;
+
+ case '.': case '0': case '1': case '2': case '3':
+ case '4': case '5': case '6': case '7': case '8':
+ case '9': case 'e': case 'E': case 'p': case 'P':
+ if (c2 == '-' || c2 == '+')
+ return 1; /* could extend a pre-processing number */
+ goto letter;
+
+ case 'L':
+ if (c2 == '\'' || c2 == '\"')
+ return 1; /* Could turn into L"xxx" or L'xxx'. */
+ goto letter;
+
+ case '_': case 'a': case 'b': case 'c': case 'd': case 'f':
+ case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
+ case 'm': case 'n': case 'o': 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 'F':
+ case 'G': case 'H': case 'I': case 'J': case 'K': case 'M':
+ case 'N': case 'O': case 'Q': case 'R': case 'S': case 'T':
+ case 'U': case 'V': case 'W': case 'X': case 'Y': case 'Z':
+ letter:
+ /* We're in the middle of either a name or a pre-processing number. */
+ return (is_idchar[c2] || c2 == '.');
+
+ case '<': case '>': case '!': case '%': case '#': case ':':
+ case '^': case '&': case '|': case '*': case '/': case '=':
+ return (c2 == c1 || c2 == '=');
+ }
+ return 0;
+}
+
+static void
+push_macro_expansion (pfile, xbuf, xbuf_len, hp)
+ cpp_reader *pfile;
+ register U_CHAR *xbuf;
+ int xbuf_len;
+ HASHNODE *hp;
+{
+ register cpp_buffer *mbuf = cpp_push_buffer (pfile, xbuf, xbuf_len);
+ if (mbuf == NULL)
+ return;
+ mbuf->cleanup = macro_cleanup;
+ mbuf->data = hp;
+
+ /* The first chars of the expansion should be a "@ " added by
+ collect_expansion. This is to prevent accidental token-pasting
+ between the text preceding the macro invocation, and the macro
+ expansion text.
+
+ We would like to avoid adding unneeded spaces (for the sake of
+ tools that use cpp, such as imake). In some common cases we can
+ tell that it is safe to omit the space.
+
+ The character before the macro invocation cannot have been an
+ idchar (or else it would have been pasted with the idchars of
+ the macro name). Therefore, if the first non-space character
+ of the expansion is an idchar, we do not need the extra space
+ to prevent token pasting.
+
+ Also, we don't need the extra space if the first char is '(',
+ or some other (less common) characters. */
+
+ if (xbuf[0] == '@' && xbuf[1] == ' '
+ && (is_idchar[xbuf[2]] || xbuf[2] == '(' || xbuf[2] == '\''
+ || xbuf[2] == '\"'))
+ mbuf->cur += 2;
+
+ /* Likewise, avoid the extra space at the end of the macro expansion
+ if this is safe. We can do a better job here since we can know
+ what the next char will be. */
+ if (xbuf_len >= 3
+ && mbuf->rlimit[-2] == '@'
+ && mbuf->rlimit[-1] == ' ')
+ {
+ int c1 = mbuf->rlimit[-3];
+ int c2 = CPP_BUF_PEEK (CPP_PREV_BUFFER (CPP_BUFFER (pfile)));
+ if (c2 == EOF || !unsafe_chars (c1, c2))
+ mbuf->rlimit -= 2;
+ }
+}
+
+/* Return zero if two DEFINITIONs are isomorphic. */
+
+int
+compare_defs (pfile, d1, d2)
+ cpp_reader *pfile;
+ DEFINITION *d1, *d2;
+{
+ register struct reflist *a1, *a2;
+ register U_CHAR *p1 = d1->expansion;
+ register U_CHAR *p2 = d2->expansion;
+ int first = 1;
+
+ if (d1->nargs != d2->nargs)
+ return 1;
+ if (CPP_PEDANTIC (pfile)
+ && strcmp ((char *) d1->args.argnames, (char *) d2->args.argnames))
+ return 1;
+ for (a1 = d1->pattern, a2 = d2->pattern; a1 && a2;
+ a1 = a1->next, a2 = a2->next)
+ {
+ if (!((a1->nchars == a2->nchars && !strncmp (p1, p2, a1->nchars))
+ || !comp_def_part (first, p1, a1->nchars, p2, a2->nchars, 0))
+ || a1->argno != a2->argno
+ || a1->stringify != a2->stringify
+ || a1->raw_before != a2->raw_before
+ || a1->raw_after != a2->raw_after)
+ return 1;
+ first = 0;
+ p1 += a1->nchars;
+ p2 += a2->nchars;
+ }
+ if (a1 != a2)
+ return 1;
+
+ return comp_def_part (first, p1, d1->length - (p1 - d1->expansion),
+ p2, d2->length - (p2 - d2->expansion), 1);
+}
+
+/* Return 1 if two parts of two macro definitions are effectively different.
+ One of the parts starts at BEG1 and has LEN1 chars;
+ the other has LEN2 chars at BEG2.
+ Any sequence of whitespace matches any other sequence of whitespace.
+ FIRST means these parts are the first of a macro definition;
+ so ignore leading whitespace entirely.
+ LAST means these parts are the last of a macro definition;
+ so ignore trailing whitespace entirely. */
+
+static int
+comp_def_part (first, beg1, len1, beg2, len2, last)
+ int first;
+ U_CHAR *beg1, *beg2;
+ int len1, len2;
+ int last;
+{
+ register U_CHAR *end1 = beg1 + len1;
+ register U_CHAR *end2 = beg2 + len2;
+ if (first)
+ {
+ while (beg1 != end1 && is_space[*beg1])
+ beg1++;
+ while (beg2 != end2 && is_space[*beg2])
+ beg2++;
+ }
+ if (last)
+ {
+ while (beg1 != end1 && is_space[end1[-1]])
+ end1--;
+ while (beg2 != end2 && is_space[end2[-1]])
+ end2--;
+ }
+ while (beg1 != end1 && beg2 != end2)
+ {
+ if (is_space[*beg1] && is_space[*beg2])
+ {
+ while (beg1 != end1 && is_space[*beg1])
+ beg1++;
+ while (beg2 != end2 && is_space[*beg2])
+ beg2++;
+ }
+ else if (*beg1 == *beg2)
+ {
+ beg1++;
+ beg2++;
+ }
+ else
+ break;
}
+ return (beg1 != end1) || (beg2 != end2);
}
diff --git a/gcc/cpphash.h b/gcc/cpphash.h
index 2b0668d3eb2..d304f1a169e 100644
--- a/gcc/cpphash.h
+++ b/gcc/cpphash.h
@@ -1,12 +1,27 @@
+/* Part of CPP library. (Macro hash table support.)
+ Copyright (C) 1997, 1998, 1999 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
/* different kinds of things that can appear in the value field
- of a hash node. Actually, this may be useless now. */
-union hashval {
- int ival;
- char *cpval;
- DEFINITION *defn;
-#if 0
- KEYDEF *keydef;
-#endif
+ of a hash node. */
+union hashval
+{
+ const char *cpval; /* some predefined macros */
+ DEFINITION *defn; /* #define */
+ struct hashnode *aschain; /* #assert */
};
struct hashnode {
@@ -30,11 +45,16 @@ typedef struct hashnode HASHNODE;
the hashf () function. Hashf () only exists for the sake of
politeness, for use when speed isn't so important. */
-#define HASHSIZE 1403
-static HASHNODE *hashtab[HASHSIZE];
#define HASHSTEP(old, c) ((old << 2) + c)
#define MAKE_POS(v) (v & 0x7fffffff) /* make number positive */
-extern HASHNODE *install PARAMS ((U_CHAR *,int,enum node_type, int,char *,int));
-extern int hashf PARAMS ((const U_CHAR *, int, int));
-extern void delete_macro PARAMS ((HASHNODE *));
+extern HASHNODE *cpp_install PARAMS ((cpp_reader *, U_CHAR *, int,
+ enum node_type, const char *, int));
+extern int hashf PARAMS ((const U_CHAR *, int, int));
+extern void delete_macro PARAMS ((HASHNODE *));
+
+extern MACRODEF create_definition PARAMS ((U_CHAR *, U_CHAR *,
+ cpp_reader *, int));
+extern int compare_defs PARAMS ((cpp_reader *, DEFINITION *,
+ DEFINITION *));
+extern void macroexpand PARAMS ((cpp_reader *, HASHNODE *));
diff --git a/gcc/cpplib.c b/gcc/cpplib.c
index 874a1759a50..d50848698b0 100644
--- a/gcc/cpplib.c
+++ b/gcc/cpplib.c
@@ -1,5 +1,5 @@
/* CPP Library.
- Copyright (C) 1986, 87, 89, 92-97, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1986, 87, 89, 92-98, 1999 Free Software Foundation, Inc.
Contributed by Per Bothner, 1994-95.
Based on CCCP program by Paul Rubin, June 1986
Adapted to ANSI C, Richard Stallman, Jan 1987
@@ -21,146 +21,10 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "config.h"
#include "system.h"
-#ifndef STDC_VALUE
-#define STDC_VALUE 1
-#endif
-
-#include <signal.h>
-
-#ifdef HAVE_SYS_TIMES_H
-#include <sys/times.h>
-#endif
-
-#ifdef HAVE_SYS_RESOURCE_H
-# include <sys/resource.h>
-#endif
-
-#include "gansidecl.h"
#include "cpplib.h"
#include "cpphash.h"
+#include "intl.h"
-#ifndef GET_ENV_PATH_LIST
-#define GET_ENV_PATH_LIST(VAR,NAME) do { (VAR) = getenv (NAME); } while (0)
-#endif
-
-extern char *update_path PARAMS ((char *, char *));
-
-#undef MIN
-#undef MAX
-#define MIN(X,Y) ((X) < (Y) ? (X) : (Y))
-#define MAX(X,Y) ((X) > (Y) ? (X) : (Y))
-
-/* Find the largest host integer type and set its size and type.
- Watch out: on some crazy hosts `long' is shorter than `int'. */
-
-#ifndef HOST_WIDE_INT
-# if HAVE_INTTYPES_H
-# include <inttypes.h>
-# define HOST_WIDE_INT intmax_t
-# else
-# if (HOST_BITS_PER_LONG <= HOST_BITS_PER_INT \
- && HOST_BITS_PER_LONGLONG <= HOST_BITS_PER_INT)
-# define HOST_WIDE_INT int
-# else
-# if (HOST_BITS_PER_LONGLONG <= HOST_BITS_PER_LONG \
- || ! (defined LONG_LONG_MAX || defined LLONG_MAX))
-# define HOST_WIDE_INT long
-# else
-# define HOST_WIDE_INT long long
-# endif
-# endif
-# endif
-#endif
-
-#ifndef S_ISREG
-#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
-#endif
-
-#ifndef S_ISDIR
-#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
-#endif
-
-/* By default, colon separates directories in a path. */
-#ifndef PATH_SEPARATOR
-#define PATH_SEPARATOR ':'
-#endif
-
-#ifndef STANDARD_INCLUDE_DIR
-#define STANDARD_INCLUDE_DIR "/usr/include"
-#endif
-#ifndef INCLUDE_LEN_FUDGE
-#define INCLUDE_LEN_FUDGE 0
-#endif
-
-/* Symbols to predefine. */
-
-#ifdef CPP_PREDEFINES
-static char *predefs = CPP_PREDEFINES;
-#else
-static char *predefs = "";
-#endif
-
-/* We let tm.h override the types used here, to handle trivial differences
- such as the choice of unsigned int or long unsigned int for size_t.
- When machines start needing nontrivial differences in the size type,
- it would be best to do something here to figure out automatically
- from other information what type to use. */
-
-/* The string value for __SIZE_TYPE__. */
-
-#ifndef SIZE_TYPE
-#define SIZE_TYPE "long unsigned int"
-#endif
-
-/* The string value for __PTRDIFF_TYPE__. */
-
-#ifndef PTRDIFF_TYPE
-#define PTRDIFF_TYPE "long int"
-#endif
-
-/* The string value for __WCHAR_TYPE__. */
-
-#ifndef WCHAR_TYPE
-#define WCHAR_TYPE "int"
-#endif
-#define CPP_WCHAR_TYPE(PFILE) \
- (CPP_OPTIONS (PFILE)->cplusplus ? "__wchar_t" : WCHAR_TYPE)
-
-/* The string value for __USER_LABEL_PREFIX__ */
-
-#ifndef USER_LABEL_PREFIX
-#define USER_LABEL_PREFIX ""
-#endif
-
-/* The string value for __REGISTER_PREFIX__ */
-
-#ifndef REGISTER_PREFIX
-#define REGISTER_PREFIX ""
-#endif
-
-/* In the definition of a #assert name, this structure forms
- a list of the individual values asserted.
- Each value is itself a list of "tokens".
- These are strings that are compared by name. */
-
-struct tokenlist_list {
- struct tokenlist_list *next;
- struct arglist *tokens;
-};
-
-struct assertion_hashnode {
- struct assertion_hashnode *next; /* double links for easy deletion */
- struct assertion_hashnode *prev;
- /* also, a back pointer to this node's hash
- chain is kept, in case the node is the head
- of the chain and gets deleted. */
- struct assertion_hashnode **bucket_hdr;
- int length; /* length of token, for quick comparison */
- U_CHAR *name; /* the actual name */
- /* List of token-sequences. */
- struct tokenlist_list *value;
-};
-
#define SKIP_WHITE_SPACE(p) do { while (is_hor_space[*p]) p++; } while (0)
#define SKIP_ALL_WHITE_SPACE(p) do { while (is_space[*p]) p++; } while (0)
@@ -169,206 +33,59 @@ struct assertion_hashnode {
#define GETC() CPP_BUF_GET (CPP_BUFFER (pfile))
#define PEEKC() CPP_BUF_PEEK (CPP_BUFFER (pfile))
/* CPP_IS_MACRO_BUFFER is true if the buffer contains macro expansion.
- (Note that it is false while we're expanding marco *arguments*.) */
-#define CPP_IS_MACRO_BUFFER(PBUF) ((PBUF)->cleanup == macro_cleanup)
-
-/* Move all backslash-newline pairs out of embarrassing places.
- Exchange all such pairs following BP
- with any potentially-embarrassing characters that follow them.
- Potentially-embarrassing characters are / and *
- (because a backslash-newline inside a comment delimiter
- would cause it not to be recognized). */
-
-#define NEWLINE_FIX \
- do {while (PEEKC() == '\\' && PEEKN(1) == '\n') FORWARD(2); } while(0)
-
-/* Same, but assume we've already read the potential '\\' into C. */
-#define NEWLINE_FIX1(C) do { \
- while ((C) == '\\' && PEEKC() == '\n') { FORWARD(1); (C) = GETC(); }\
- } while(0)
-
-struct cpp_pending {
- struct cpp_pending *next;
- char *cmd;
- char *arg;
-};
+ (Note that it is false while we're expanding macro *arguments*.) */
+#define CPP_IS_MACRO_BUFFER(PBUF) ((PBUF)->data != NULL)
/* Forward declarations. */
-char *xmalloc ();
-extern void cpp_hash_cleanup PARAMS ((cpp_reader *));
-
static char *my_strerror PROTO ((int));
-static void add_import PROTO ((cpp_reader *, int, char *));
-static void append_include_chain PROTO ((cpp_reader *,
- struct file_name_list *,
- struct file_name_list *));
-static void make_assertion PROTO ((cpp_reader *, char *, U_CHAR *));
-static void path_include PROTO ((cpp_reader *, char *));
-static void initialize_builtins PROTO ((cpp_reader *));
-static void initialize_char_syntax PROTO ((struct cpp_options *));
-#if 0
-static void trigraph_pcp ();
-#endif
-static int finclude PROTO ((cpp_reader *, int, char *,
- int, struct file_name_list *));
static void validate_else PROTO ((cpp_reader *, char *));
-static int comp_def_part PROTO ((int, U_CHAR *, int, U_CHAR *,
- int, int));
-#ifdef abort
-extern void fancy_abort ();
-#endif
-static int lookup_import PROTO ((cpp_reader *, char *,
- struct file_name_list *));
-static int redundant_include_p PROTO ((cpp_reader *, char *));
-static int is_system_include PROTO ((cpp_reader *, char *));
-static struct file_name_map *read_name_map PROTO ((cpp_reader *, char *));
-static char *read_filename_string PROTO ((int, FILE *));
-static int open_include_file PROTO ((cpp_reader *, char *,
- struct file_name_list *));
-static int check_macro_name PROTO ((cpp_reader *, U_CHAR *, char *));
-static int compare_defs PROTO ((cpp_reader *,
- DEFINITION *, DEFINITION *));
-static int compare_token_lists PROTO ((struct arglist *,
- struct arglist *));
-static HOST_WIDE_INT eval_if_expression PROTO ((cpp_reader *, U_CHAR *, int));
-static int change_newlines PROTO ((U_CHAR *, int));
-static struct arglist *read_token_list PROTO ((cpp_reader *, int *));
-static void free_token_list PROTO ((struct arglist *));
-static int safe_read PROTO ((int, char *, int));
-static void push_macro_expansion PARAMS ((cpp_reader *,
- U_CHAR *, int, HASHNODE *));
-static struct cpp_pending *nreverse_pending PARAMS ((struct cpp_pending *));
-extern char *xrealloc ();
-static char *xcalloc PROTO ((unsigned, unsigned));
-static char *savestring PROTO ((char *));
+static HOST_WIDEST_INT eval_if_expression PROTO ((cpp_reader *));
static void conditional_skip PROTO ((cpp_reader *, int,
- enum node_type, U_CHAR *));
-static void skip_if_group PROTO ((cpp_reader *, int));
-static int parse_name PARAMS ((cpp_reader *, int));
-static void print_help PROTO ((void));
+ enum node_type, U_CHAR *));
+static void skip_if_group PROTO ((cpp_reader *));
-/* Last arg to output_line_command. */
-enum file_change_code {same_file, enter_file, leave_file};
+static void parse_name PARAMS ((cpp_reader *, int));
+static void parse_string PARAMS ((cpp_reader *, int));
+static int parse_assertion PARAMS ((cpp_reader *));
/* External declarations. */
-extern HOST_WIDE_INT cpp_parse_expr PARAMS ((cpp_reader *));
-
-extern char *version_string;
-extern struct tm *localtime ();
-
-struct file_name_list
- {
- struct file_name_list *next;
- char *fname;
- /* If the following is nonzero, it is a macro name.
- Don't include the file again if that macro is defined. */
- U_CHAR *control_macro;
- /* If the following is nonzero, it is a C-language system include
- directory. */
- int c_system_include_path;
- /* Mapping of file names for this directory. */
- struct file_name_map *name_map;
- /* Non-zero if name_map is valid. */
- int got_name_map;
- };
-
-/* If a buffer's dir field is SELF_DIR_DUMMY, it means the file was found
- via the same directory as the file that #included it. */
-#define SELF_DIR_DUMMY ((struct file_name_list *) (~0))
-
-/* #include "file" looks in source file dir, then stack. */
-/* #include <file> just looks in the stack. */
-/* -I directories are added to the end, then the defaults are added. */
-/* The */
-static struct default_include {
- char *fname; /* The name of the directory. */
- char *component; /* The component containing the directory */
- int cplusplus; /* Only look here if we're compiling C++. */
- int cxx_aware; /* Includes in this directory don't need to
- be wrapped in extern "C" when compiling
- C++. */
-} include_defaults_array[]
-#ifdef INCLUDE_DEFAULTS
- = INCLUDE_DEFAULTS;
-#else
- = {
- /* Pick up GNU C++ specific include files. */
- { GPLUSPLUS_INCLUDE_DIR, "G++", 1, 1 },
-#ifdef CROSS_COMPILE
- /* This is the dir for fixincludes. Put it just before
- the files that we fix. */
- { GCC_INCLUDE_DIR, "GCC", 0, 0 },
- /* For cross-compilation, this dir name is generated
- automatically in Makefile.in. */
- { CROSS_INCLUDE_DIR, "GCC",0, 0 },
-#ifdef TOOL_INCLUDE_DIR
- /* This is another place that the target system's headers might be. */
- { TOOL_INCLUDE_DIR, "BINUTILS", 0, 1 },
-#endif
-#else /* not CROSS_COMPILE */
-#ifdef LOCAL_INCLUDE_DIR
- /* This should be /usr/local/include and should come before
- the fixincludes-fixed header files. */
- { LOCAL_INCLUDE_DIR, 0, 0, 1 },
-#endif
-#ifdef TOOL_INCLUDE_DIR
- /* This is here ahead of GCC_INCLUDE_DIR because assert.h goes here.
- Likewise, behind LOCAL_INCLUDE_DIR, where glibc puts its assert.h. */
- { TOOL_INCLUDE_DIR, "BINUTILS", 0, 1 },
-#endif
- /* This is the dir for fixincludes. Put it just before
- the files that we fix. */
- { GCC_INCLUDE_DIR, "GCC", 0, 0 },
- /* Some systems have an extra dir of include files. */
-#ifdef SYSTEM_INCLUDE_DIR
- { SYSTEM_INCLUDE_DIR, 0, 0, 0 },
-#endif
-#ifndef STANDARD_INCLUDE_COMPONENT
-#define STANDARD_INCLUDE_COMPONENT 0
-#endif
- { STANDARD_INCLUDE_DIR, STANDARD_INCLUDE_COMPONENT, 0, 0 },
-#endif /* not CROSS_COMPILE */
- { 0, 0, 0, 0 }
- };
-#endif /* no INCLUDE_DEFAULTS */
+extern HOST_WIDEST_INT cpp_parse_expr PARAMS ((cpp_reader *));
/* `struct directive' defines one #-directive, including how to handle it. */
struct directive {
int length; /* Length of name */
int (*func) /* Function to handle directive */
- PARAMS ((cpp_reader *, struct directive *, U_CHAR *, U_CHAR *));
+ PARAMS ((cpp_reader *, struct directive *));
char *name; /* Name of directive */
enum node_type type; /* Code which describes which directive. */
- char command_reads_line; /* One if rest of line is read by func. */
};
/* These functions are declared to return int instead of void since they
are going to be placed in a table and some old compilers have trouble with
pointers to functions returning void. */
-static int do_define PARAMS ((cpp_reader *, struct directive *, U_CHAR *, U_CHAR *));
-static int do_line PARAMS ((cpp_reader *, struct directive *, U_CHAR *, U_CHAR *));
-static int do_include PARAMS ((cpp_reader *, struct directive *, U_CHAR *, U_CHAR *));
-static int do_undef PARAMS ((cpp_reader *, struct directive *, U_CHAR *, U_CHAR *));
-static int do_error PARAMS ((cpp_reader *, struct directive *, U_CHAR *, U_CHAR *));
-static int do_pragma PARAMS ((cpp_reader *, struct directive *, U_CHAR *, U_CHAR *));
-static int do_ident PARAMS ((cpp_reader *, struct directive *, U_CHAR *, U_CHAR *));
-static int do_if PARAMS ((cpp_reader *, struct directive *, U_CHAR *, U_CHAR *));
-static int do_xifdef PARAMS ((cpp_reader *, struct directive *, U_CHAR *, U_CHAR *));
-static int do_else PARAMS ((cpp_reader *, struct directive *, U_CHAR *, U_CHAR *));
-static int do_elif PARAMS ((cpp_reader *, struct directive *, U_CHAR *, U_CHAR *));
-static int do_endif PARAMS ((cpp_reader *, struct directive *, U_CHAR *, U_CHAR *));
+static int do_define PARAMS ((cpp_reader *, struct directive *));
+static int do_line PARAMS ((cpp_reader *, struct directive *));
+static int do_include PARAMS ((cpp_reader *, struct directive *));
+static int do_undef PARAMS ((cpp_reader *, struct directive *));
+static int do_error PARAMS ((cpp_reader *, struct directive *));
+static int do_pragma PARAMS ((cpp_reader *, struct directive *));
+static int do_ident PARAMS ((cpp_reader *, struct directive *));
+static int do_if PARAMS ((cpp_reader *, struct directive *));
+static int do_xifdef PARAMS ((cpp_reader *, struct directive *));
+static int do_else PARAMS ((cpp_reader *, struct directive *));
+static int do_elif PARAMS ((cpp_reader *, struct directive *));
+static int do_endif PARAMS ((cpp_reader *, struct directive *));
#ifdef SCCS_DIRECTIVE
-static int do_sccs PARAMS ((cpp_reader *, struct directive *, U_CHAR *, U_CHAR *));
+static int do_sccs PARAMS ((cpp_reader *, struct directive *));
#endif
-static int do_once PARAMS ((cpp_reader *, struct directive *, U_CHAR *, U_CHAR *));
-static int do_assert PARAMS ((cpp_reader *, struct directive *, U_CHAR *, U_CHAR *));
-static int do_unassert PARAMS ((cpp_reader *, struct directive *, U_CHAR *, U_CHAR *));
-static int do_warning PARAMS ((cpp_reader *, struct directive *, U_CHAR *, U_CHAR *));
+static int do_assert PARAMS ((cpp_reader *, struct directive *));
+static int do_unassert PARAMS ((cpp_reader *, struct directive *));
+static int do_warning PARAMS ((cpp_reader *, struct directive *));
#define IS_INCLUDE_DIRECTIVE_TYPE(t) \
((int) T_INCLUDE <= (int) (t) && (int) (t) <= (int) T_IMPORT)
@@ -377,89 +94,37 @@ static int do_warning PARAMS ((cpp_reader *, struct directive *, U_CHAR *, U_CHA
The initialize_builtins function assumes #define is the very first. */
static struct directive directive_table[] = {
- { 6, do_define, "define", T_DEFINE},
- { 5, do_xifdef, "ifdef", T_IFDEF, 1},
- { 6, do_xifdef, "ifndef", T_IFNDEF, 1},
- { 7, do_include, "include", T_INCLUDE, 1},
- { 12, do_include, "include_next", T_INCLUDE_NEXT, 1},
- { 6, do_include, "import", T_IMPORT, 1},
- { 5, do_endif, "endif", T_ENDIF, 1},
- { 4, do_else, "else", T_ELSE, 1},
- { 2, do_if, "if", T_IF, 1},
- { 4, do_elif, "elif", T_ELIF, 1},
- { 5, do_undef, "undef", T_UNDEF},
- { 5, do_error, "error", T_ERROR},
- { 7, do_warning, "warning", T_WARNING},
- { 6, do_pragma, "pragma", T_PRAGMA},
- { 4, do_line, "line", T_LINE, 1},
- { 5, do_ident, "ident", T_IDENT, 1},
+ { 6, do_define, "define", T_DEFINE },
+ { 5, do_xifdef, "ifdef", T_IFDEF },
+ { 6, do_xifdef, "ifndef", T_IFNDEF },
+ { 7, do_include, "include", T_INCLUDE },
+ { 12, do_include, "include_next", T_INCLUDE_NEXT },
+ { 6, do_include, "import", T_IMPORT },
+ { 5, do_endif, "endif", T_ENDIF },
+ { 4, do_else, "else", T_ELSE },
+ { 2, do_if, "if", T_IF },
+ { 4, do_elif, "elif", T_ELIF },
+ { 5, do_undef, "undef", T_UNDEF },
+ { 5, do_error, "error", T_ERROR },
+ { 7, do_warning, "warning", T_WARNING },
+ { 6, do_pragma, "pragma", T_PRAGMA },
+ { 4, do_line, "line", T_LINE },
+ { 5, do_ident, "ident", T_IDENT },
#ifdef SCCS_DIRECTIVE
- { 4, do_sccs, "sccs", T_SCCS},
+ { 4, do_sccs, "sccs", T_SCCS },
#endif
- { 6, do_assert, "assert", T_ASSERT, 1},
- { 8, do_unassert, "unassert", T_UNASSERT, 1},
- { -1, 0, "", T_UNUSED},
+ { 6, do_assert, "assert", T_ASSERT },
+ { 8, do_unassert, "unassert", T_UNASSERT },
+ { -1, 0, "", T_UNUSED }
};
-
-/* table to tell if char can be part of a C identifier. */
-U_CHAR is_idchar[256];
-/* table to tell if char can be first char of a c identifier. */
-U_CHAR is_idstart[256];
-/* table to tell if c is horizontal space. */
-U_CHAR is_hor_space[256];
-/* table to tell if c is horizontal or vertical space. */
-static U_CHAR is_space[256];
-
-/* Initialize syntactic classifications of characters. */
-
-static void
-initialize_char_syntax (opts)
- struct cpp_options *opts;
-{
- register int i;
-
- /*
- * Set up is_idchar and is_idstart tables. These should be
- * faster than saying (is_alpha (c) || c == '_'), etc.
- * Set up these things before calling any routines tthat
- * refer to them.
- */
- for (i = 'a'; i <= 'z'; i++) {
- is_idchar[i - 'a' + 'A'] = 1;
- is_idchar[i] = 1;
- is_idstart[i - 'a' + 'A'] = 1;
- is_idstart[i] = 1;
- }
- for (i = '0'; i <= '9'; i++)
- is_idchar[i] = 1;
- is_idchar['_'] = 1;
- is_idstart['_'] = 1;
- is_idchar['$'] = opts->dollars_in_ident;
- is_idstart['$'] = opts->dollars_in_ident;
-
- /* horizontal space table */
- is_hor_space[' '] = 1;
- is_hor_space['\t'] = 1;
- is_hor_space['\v'] = 1;
- is_hor_space['\f'] = 1;
- is_hor_space['\r'] = 1;
-
- is_space[' '] = 1;
- is_space['\t'] = 1;
- is_space['\v'] = 1;
- is_space['\f'] = 1;
- is_space['\n'] = 1;
- is_space['\r'] = 1;
-}
-
/* Place into PFILE a quoted string representing the string SRC.
Caller must reserve enough space in pfile->token_buffer. */
-static void
+void
quote_string (pfile, src)
cpp_reader *pfile;
- char *src;
+ const char *src;
{
U_CHAR c;
@@ -504,13 +169,10 @@ cpp_grow_buffer (pfile, n)
CPP_SET_WRITTEN (pfile, old_written);
}
-
-/*
- * process a given definition string, for initialization
- * If STR is just an identifier, define it with value 1.
- * If STR has anything after the identifier, then it should
- * be identifier=definition.
- */
+/* Process the string STR as if it appeared as the body of a #define
+ If STR is just an identifier, define it with value 1.
+ If STR has anything after the identifier, then it should
+ be identifier=definition. */
void
cpp_define (pfile, str)
@@ -518,273 +180,52 @@ cpp_define (pfile, str)
U_CHAR *str;
{
U_CHAR *buf, *p;
+ size_t count;
- buf = str;
- p = str;
- if (!is_idstart[*p])
- {
- cpp_error (pfile, "malformed option `-D %s'", str);
- return;
- }
- while (is_idchar[*++p])
- ;
- if (*p == '(') {
- while (is_idchar[*++p] || *p == ',' || is_hor_space[*p])
- ;
- if (*p++ != ')')
- p = (U_CHAR *) str; /* Error */
- }
- if (*p == 0)
- {
- buf = (U_CHAR *) alloca (p - buf + 4);
- strcpy ((char *)buf, str);
- strcat ((char *)buf, " 1");
- }
- else if (*p != '=')
+ /* Copy the entire option so we can modify it. */
+ count = strlen (str) + 3;
+ buf = (U_CHAR *) alloca (count);
+ memcpy (buf, str, count - 2);
+ /* Change the first "=" in the string to a space. If there is none,
+ tack " 1" on the end. */
+ p = (U_CHAR *) strchr (buf, '=');
+ if (p)
{
- cpp_error (pfile, "malformed option `-D %s'", str);
- return;
+ *p = ' ';
+ count -= 2;
}
else
- {
- U_CHAR *q;
- /* Copy the entire option so we can modify it. */
- buf = (U_CHAR *) alloca (2 * strlen (str) + 1);
- strncpy (buf, str, p - str);
- /* Change the = to a space. */
- buf[p - str] = ' ';
- /* Scan for any backslash-newline and remove it. */
- p++;
- q = &buf[p - str];
- while (*p)
- {
- if (*p == '\\' && p[1] == '\n')
- p += 2;
- else
- *q++ = *p++;
- }
- *q = 0;
- }
-
- do_define (pfile, NULL, buf, buf + strlen (buf));
-}
-
-/* Process the string STR as if it appeared as the body of a #assert.
- OPTION is the option name for which STR was the argument. */
-
-static void
-make_assertion (pfile, option, str)
- cpp_reader *pfile;
- char *option;
- U_CHAR *str;
-{
- U_CHAR *buf, *p, *q;
-
- /* Copy the entire option so we can modify it. */
- buf = (U_CHAR *) alloca (strlen (str) + 1);
- strcpy ((char *) buf, str);
- /* Scan for any backslash-newline and remove it. */
- p = q = buf;
- while (*p) {
-#if 0
- if (*p == '\\' && p[1] == '\n')
- p += 2;
- else
-#endif
- *q++ = *p++;
- }
- *q = 0;
-
- p = buf;
- if (!is_idstart[*p]) {
- cpp_error (pfile, "malformed option `%s %s'", option, str);
- return;
- }
- while (is_idchar[*++p])
- ;
- while (*p == ' ' || *p == '\t') p++;
- if (! (*p == 0 || *p == '(')) {
- cpp_error (pfile, "malformed option `%s %s'", option, str);
- return;
- }
+ strcpy (&buf[count-3], " 1");
- if (cpp_push_buffer (pfile, buf, strlen (buf)) != NULL)
+ if (cpp_push_buffer (pfile, buf, count - 1) != NULL)
{
- do_assert (pfile, NULL, NULL, NULL);
+ do_define (pfile, NULL);
cpp_pop_buffer (pfile);
}
}
-
-/* Append a chain of `struct file_name_list's
- to the end of the main include chain.
- FIRST is the beginning of the chain to append, and LAST is the end. */
-
-static void
-append_include_chain (pfile, first, last)
- cpp_reader *pfile;
- struct file_name_list *first, *last;
-{
- struct cpp_options *opts = CPP_OPTIONS (pfile);
- struct file_name_list *dir;
-
- if (!first || !last)
- return;
- if (opts->include == 0)
- opts->include = first;
- else
- opts->last_include->next = first;
-
- if (opts->first_bracket_include == 0)
- opts->first_bracket_include = first;
-
- for (dir = first; ; dir = dir->next) {
- int len = strlen (dir->fname) + INCLUDE_LEN_FUDGE;
- if (len > pfile->max_include_len)
- pfile->max_include_len = len;
- if (dir == last)
- break;
- }
-
- last->next = NULL;
- opts->last_include = last;
-}
-
-/* Add output to `deps_buffer' for the -M switch.
- STRING points to the text to be output.
- SPACER is ':' for targets, ' ' for dependencies, zero for text
- to be inserted literally. */
-
-static void
-deps_output (pfile, string, spacer)
+/* Process the string STR as if it appeared as the body of a #assert. */
+void
+cpp_assert (pfile, str)
cpp_reader *pfile;
- char *string;
- int spacer;
+ U_CHAR *str;
{
- int size = strlen (string);
-
- if (size == 0)
- return;
-
-#ifndef MAX_OUTPUT_COLUMNS
-#define MAX_OUTPUT_COLUMNS 72
-#endif
- if (spacer
- && pfile->deps_column > 0
- && (pfile->deps_column + size) > MAX_OUTPUT_COLUMNS)
- {
- deps_output (pfile, " \\\n ", 0);
- pfile->deps_column = 0;
- }
-
- if (pfile->deps_size + size + 8 > pfile->deps_allocated_size)
+ if (cpp_push_buffer (pfile, str, strlen (str)) != NULL)
{
- pfile->deps_allocated_size = (pfile->deps_size + size + 50) * 2;
- pfile->deps_buffer = (char *) xrealloc (pfile->deps_buffer,
- pfile->deps_allocated_size);
+ do_assert (pfile, NULL);
+ cpp_pop_buffer (pfile);
}
- if (spacer == ' ' && pfile->deps_column > 0)
- pfile->deps_buffer[pfile->deps_size++] = ' ';
- bcopy (string, &pfile->deps_buffer[pfile->deps_size], size);
- pfile->deps_size += size;
- pfile->deps_column += size;
- if (spacer == ':')
- pfile->deps_buffer[pfile->deps_size++] = ':';
- pfile->deps_buffer[pfile->deps_size] = 0;
}
-
-/* Given a colon-separated list of file names PATH,
- add all the names to the search path for include files. */
-
-static void
-path_include (pfile, path)
- cpp_reader *pfile;
- char *path;
-{
- char *p;
-
- p = path;
-
- if (*p)
- while (1) {
- char *q = p;
- char *name;
- struct file_name_list *dirtmp;
-
- /* Find the end of this name. */
- while (*q != 0 && *q != PATH_SEPARATOR) q++;
- if (p == q) {
- /* An empty name in the path stands for the current directory. */
- name = (char *) xmalloc (2);
- name[0] = '.';
- name[1] = 0;
- } else {
- /* Otherwise use the directory that is named. */
- name = (char *) xmalloc (q - p + 1);
- bcopy (p, name, q - p);
- name[q - p] = 0;
- }
- dirtmp = (struct file_name_list *)
- xmalloc (sizeof (struct file_name_list));
- dirtmp->next = 0; /* New one goes on the end */
- dirtmp->control_macro = 0;
- dirtmp->c_system_include_path = 0;
- dirtmp->fname = name;
- dirtmp->got_name_map = 0;
- append_include_chain (pfile, dirtmp, dirtmp);
-
- /* Advance past this name. */
- p = q;
- if (*p == 0)
- break;
- /* Skip the colon. */
- p++;
- }
-}
-
-void
-cpp_options_init (opts)
- cpp_options *opts;
-{
- bzero ((char *) opts, sizeof *opts);
- opts->in_fname = NULL;
- opts->out_fname = NULL;
-
- /* Initialize is_idchar to allow $. */
- opts->dollars_in_ident = 1;
- initialize_char_syntax (opts);
-
- opts->no_line_commands = 0;
- opts->no_trigraphs = 1;
- opts->put_out_comments = 0;
- opts->print_include_names = 0;
- opts->dump_macros = dump_none;
- opts->no_output = 0;
- opts->remap = 0;
- opts->cplusplus = 0;
- opts->cplusplus_comments = 1;
-
- opts->verbose = 0;
- opts->objc = 0;
- opts->lang_asm = 0;
- opts->for_lint = 0;
- opts->chill = 0;
- opts->pedantic_errors = 0;
- opts->inhibit_warnings = 0;
- opts->warn_comments = 0;
- opts->warn_import = 1;
- opts->warnings_are_errors = 0;
-}
-enum cpp_token
+static enum cpp_token
null_underflow (pfile)
cpp_reader *pfile ATTRIBUTE_UNUSED;
{
return CPP_EOF;
}
-int
+static int
null_cleanup (pbuf, pfile)
cpp_buffer *pbuf ATTRIBUTE_UNUSED;
cpp_reader *pfile ATTRIBUTE_UNUSED;
@@ -792,97 +233,144 @@ null_cleanup (pbuf, pfile)
return 0;
}
-int
-macro_cleanup (pbuf, pfile)
- cpp_buffer *pbuf;
- cpp_reader *pfile ATTRIBUTE_UNUSED;
-{
- HASHNODE *macro = (HASHNODE *) pbuf->data;
- if (macro->type == T_DISABLED)
- macro->type = T_MACRO;
- if (macro->type != T_MACRO || pbuf->buf != macro->value.defn->expansion)
- free (pbuf->buf);
- return 0;
-}
+/* Skip a comment - C, C++, or Chill style. M is the first character
+ of the comment marker. If this really is a comment, skip to its
+ end and return ' '. If we hit end-of-file before end-of-comment,
+ return EOF. If this is not a comment, return M (which will be
+ '/' or '-'). */
-int
-file_cleanup (pbuf, pfile)
- cpp_buffer *pbuf;
- cpp_reader *pfile ATTRIBUTE_UNUSED;
+static int
+skip_comment (pfile, m)
+ cpp_reader *pfile;
+ int m;
{
- if (pbuf->buf)
+ if (m == '/' && PEEKC() == '*')
{
- free (pbuf->buf);
- pbuf->buf = 0;
+ int c, prev_c = -1;
+ long line, col;
+
+ FORWARD(1);
+ cpp_buf_line_and_col (CPP_BUFFER (pfile), &line, &col);
+ for (;;)
+ {
+ c = GETC ();
+ if (c == EOF)
+ {
+ cpp_error_with_line (pfile, line, col, "unterminated comment");
+ return EOF;
+ }
+ else if (c == '\n' || c == '\r')
+ CPP_BUMP_LINE (pfile);
+ else if (c == '/' && prev_c == '*')
+ return ' ';
+ else if (c == '*' && prev_c == '/'
+ && CPP_OPTIONS (pfile)->warn_comments)
+ cpp_warning (pfile, "`/*' within comment");
+
+ prev_c = c;
+ }
}
- return 0;
+ else if ((m == '/' && PEEKC() == '/'
+ && CPP_OPTIONS (pfile)->cplusplus_comments)
+ || (m == '-' && PEEKC() == '-'
+ && CPP_OPTIONS (pfile)->chill))
+ {
+ FORWARD(1);
+ for (;;)
+ {
+ int c = GETC ();
+ if (c == EOF)
+ return ' '; /* Allow // to be terminated by EOF. */
+ if (c == '\n')
+ {
+ /* Don't consider final '\n' to be part of comment. */
+ FORWARD(-1);
+ return ' ';
+ }
+ else if (c == '\r')
+ CPP_BUMP_LINE (pfile);
+ }
+ }
+ else
+ return m;
}
-/* Assuming we have read '/'.
- If this is the start of a comment (followed by '*' or '/'),
- skip to the end of the comment, and return ' '.
- Return EOF if we reached the end of file before the end of the comment.
- If not the start of a comment, return '/'. */
-
+/* Identical to skip_comment except that it copies the comment into the
+ token_buffer. This is used if put_out_comments. */
static int
-skip_comment (pfile, linep)
+copy_comment (pfile, m)
cpp_reader *pfile;
- long *linep;
+ int m;
{
- int c = 0;
- while (PEEKC() == '\\' && PEEKN(1) == '\n')
- {
- if (linep)
- (*linep)++;
- FORWARD(2);
- }
- if (PEEKC() == '*')
+ if (m == '/' && PEEKC() == '*')
{
+ int c, prev_c = -1;
+ long line, col;
+
+ CPP_PUTC (pfile, '/');
+ CPP_PUTC (pfile, '*');
FORWARD(1);
+ cpp_buf_line_and_col (CPP_BUFFER (pfile), &line, &col);
for (;;)
{
- int prev_c = c;
c = GETC ();
if (c == EOF)
- return EOF;
- while (c == '\\' && PEEKC() == '\n')
{
- if (linep)
- (*linep)++;
- FORWARD(1), c = GETC();
+ cpp_error_with_line (pfile, line, col, "unterminated comment");
+ /* We must pretend this was a legitimate comment, so that the
+ output in token_buffer is not passed back tagged CPP_POP. */
+ return ' ';
+ }
+ else if (c == '\r')
+ {
+ CPP_BUMP_LINE (pfile);
+ continue;
+ }
+
+ CPP_PUTC (pfile, c);
+ if (c == '\n')
+ {
+ pfile->lineno++;
+ CPP_BUMP_LINE (pfile);
}
- if (prev_c == '*' && c == '/')
+ else if (c == '/' && prev_c == '*')
return ' ';
- if (c == '\n' && linep)
- (*linep)++;
+ else if (c == '*' && prev_c == '/'
+ && CPP_OPTIONS (pfile)->warn_comments)
+ cpp_warning (pfile, "`/*' within comment");
+
+ prev_c = c;
}
}
- else if (PEEKC() == '/' && CPP_OPTIONS (pfile)->cplusplus_comments)
+ else if ((m == '/' && PEEKC() == '/'
+ && CPP_OPTIONS (pfile)->cplusplus_comments)
+ || (m == '-' && PEEKC() == '-'
+ && CPP_OPTIONS (pfile)->chill))
{
+ CPP_PUTC (pfile, m);
+ CPP_PUTC (pfile, m);
FORWARD(1);
for (;;)
{
- c = GETC ();
+ int c = GETC ();
if (c == EOF)
- return ' '; /* Allow // to be terminated by EOF. */
- while (c == '\\' && PEEKC() == '\n')
- {
- FORWARD(1);
- c = GETC();
- if (linep)
- (*linep)++;
- }
- if (c == '\n')
+ return ' '; /* Allow line comments to be terminated by EOF. */
+ else if (c == '\n')
{
/* Don't consider final '\n' to be part of comment. */
FORWARD(-1);
return ' ';
}
+ else if (c == '\r')
+ CPP_BUMP_LINE (pfile);
+
+ CPP_PUTC (pfile, c);
}
}
else
- return '/';
-}
+ return m;
+}
+
/* Skip whitespace \-newline and comments. Does not macro-expand. */
@@ -890,34 +378,43 @@ void
cpp_skip_hspace (pfile)
cpp_reader *pfile;
{
+ int c;
while (1)
{
- int c = PEEKC();
+ c = GETC();
if (c == EOF)
- return; /* FIXME */
- if (is_hor_space[c])
+ return;
+ else if (is_hor_space[c])
{
if ((c == '\f' || c == '\v') && CPP_PEDANTIC (pfile))
cpp_pedwarn (pfile, "%s in preprocessing directive",
c == '\f' ? "formfeed" : "vertical tab");
- FORWARD(1);
}
- else if (c == '/')
+ else if (c == '\r')
+ {
+ CPP_BUFFER (pfile)->lineno++;
+ }
+ else if (c == '/' || c == '-')
{
- FORWARD (1);
- c = skip_comment (pfile, NULL);
- if (c == '/')
- FORWARD(-1);
- if (c == EOF || c == '/')
+ c = skip_comment (pfile, c);
+ if (c == EOF)
return;
+ else if (c != ' ')
+ {
+ FORWARD(-1);
+ return;
+ }
}
- else if (c == '\\' && PEEKN(1) == '\n') {
- FORWARD(2);
- }
else if (c == '@' && CPP_BUFFER (pfile)->has_escapes
- && is_hor_space[PEEKN(1)])
- FORWARD(2);
- else return;
+ && PEEKC() == ' ')
+ {
+ FORWARD(1);
+ }
+ else
+ {
+ FORWARD(-1);
+ return;
+ }
}
}
@@ -928,30 +425,36 @@ static void
copy_rest_of_line (pfile)
cpp_reader *pfile;
{
- struct cpp_options *opts = CPP_OPTIONS (pfile);
for (;;)
{
int c = GETC();
- int nextc;
switch (c)
{
+ case '\n':
+ FORWARD(-1);
case EOF:
- goto end_directive;
- case '\\':
- if (PEEKC() == '\n')
- {
- FORWARD (1);
- continue;
- }
+ CPP_NUL_TERMINATE (pfile);
+ return;
+
+ case '\r':
+ CPP_BUFFER (pfile)->lineno++;
+ continue;
case '\'':
case '\"':
- goto scan_directive_token;
- break;
+ parse_string (pfile, c);
+ continue;
case '/':
- nextc = PEEKC();
- if (nextc == '*' || (opts->cplusplus_comments && nextc == '/'))
- goto scan_directive_token;
+ if (PEEKC() == '*' && CPP_TRADITIONAL (pfile))
+ {
+ CPP_PUTS (pfile, "/**/", 4);
+ skip_comment (pfile, c);
+ continue;
+ }
+ /* else fall through */
+ case '-':
+ c = skip_comment (pfile, c);
break;
+
case '\f':
case '\v':
if (CPP_PEDANTIC (pfile))
@@ -959,20 +462,15 @@ copy_rest_of_line (pfile)
c == '\f' ? "formfeed" : "vertical tab");
break;
- case '\n':
- FORWARD(-1);
- goto end_directive;
- scan_directive_token:
- FORWARD(-1);
- cpp_get_token (pfile);
- continue;
}
CPP_PUTC (pfile, c);
}
- end_directive: ;
- CPP_NUL_TERMINATE (pfile);
}
+/* FIXME: It is almost definitely a performance win to make this do
+ the scan itself. >75% of calls to copy_r_o_l are from here or
+ skip_if_group, which means the common case is to copy stuff into the
+ token_buffer only to discard it. */
void
skip_rest_of_line (pfile)
cpp_reader *pfile;
@@ -985,14 +483,14 @@ skip_rest_of_line (pfile)
/* Handle a possible # directive.
'#' has already been read. */
-int
+static int
handle_directive (pfile)
cpp_reader *pfile;
-{ int c;
+{
+ int c;
register struct directive *kt;
int ident_length;
- long after_ident;
- U_CHAR *ident, *line_end;
+ U_CHAR *ident;
long old_written = CPP_WRITTEN (pfile);
cpp_skip_hspace (pfile);
@@ -1003,7 +501,7 @@ handle_directive (pfile)
/* Handle # followed by a line number. */
if (CPP_PEDANTIC (pfile))
cpp_pedwarn (pfile, "`#' followed by integer");
- do_line (pfile, NULL, NULL, NULL);
+ do_line (pfile, NULL);
goto done_a_directive;
}
@@ -1049,40 +547,23 @@ handle_directive (pfile)
for (kt = directive_table; ; kt++) {
if (kt->length <= 0)
goto not_a_directive;
- if (kt->length == ident_length && !strncmp (kt->name, ident, ident_length))
+ if (kt->length == ident_length
+ && !strncmp (kt->name, ident, ident_length))
break;
}
- if (kt->command_reads_line)
- after_ident = 0;
- else
- {
- /* Nonzero means do not delete comments within the directive.
- #define needs this when -traditional. */
- int comments = CPP_TRADITIONAL (pfile) && kt->type == T_DEFINE;
- int save_put_out_comments = CPP_OPTIONS (pfile)->put_out_comments;
- CPP_OPTIONS (pfile)->put_out_comments = comments;
- after_ident = CPP_WRITTEN (pfile);
- copy_rest_of_line (pfile);
- CPP_OPTIONS (pfile)->put_out_comments = save_put_out_comments;
- }
-
- /* We may want to pass through #define, #pragma, and #include.
+ /* We may want to pass through #define, #undef, #pragma, and #include.
Other directives may create output, but we don't want the directive
itself out, so we pop it now. For example conditionals may emit
- #failed ... #endfailed stuff. But note that popping the buffer
- means the parameters to kt->func may point after pfile->limit
- so these parameters are invalid as soon as something gets appended
- to the token_buffer. */
+ #failed ... #endfailed stuff. */
- line_end = CPP_PWRITTEN (pfile);
if (! (kt->type == T_DEFINE
|| kt->type == T_PRAGMA
|| (IS_INCLUDE_DIRECTIVE_TYPE (kt->type)
&& CPP_OPTIONS (pfile)->dump_includes)))
CPP_SET_WRITTEN (pfile, old_written);
- (*kt->func) (pfile, kt, pfile->token_buffer + after_ident, line_end);
+ (*kt->func) (pfile, kt);
if (kt->type == T_DEFINE)
{
@@ -1109,7 +590,7 @@ handle_directive (pfile)
/* Pass a directive through to the output file.
BUF points to the contents of the directive, as a contiguous string.
- LIMIT points to the first character past the end of the directive.
+m LIMIT points to the first character past the end of the directive.
KEYWORD is the keyword-table entry for the directive. */
static void
@@ -1133,505 +614,15 @@ pass_thru_directive (buf, limit, pfile, keyword)
pfile->lineno++;
#endif
}
-
-/* The arglist structure is built by do_define to tell
- collect_definition where the argument names begin. That
- is, for a define like "#define f(x,y,z) foo+x-bar*y", the arglist
- would contain pointers to the strings x, y, and z.
- Collect_definition would then build a DEFINITION node,
- with reflist nodes pointing to the places x, y, and z had
- appeared. So the arglist is just convenience data passed
- between these two routines. It is not kept around after
- the current #define has been processed and entered into the
- hash table. */
-
-struct arglist {
- struct arglist *next;
- U_CHAR *name;
- int length;
- int argno;
- char rest_args;
-};
-
-/* Read a replacement list for a macro with parameters.
- Build the DEFINITION structure.
- Reads characters of text starting at BUF until END.
- ARGLIST specifies the formal parameters to look for
- in the text of the definition; NARGS is the number of args
- in that list, or -1 for a macro name that wants no argument list.
- MACRONAME is the macro name itself (so we can avoid recursive expansion)
- and NAMELEN is its length in characters.
-
- Note that comments, backslash-newlines, and leading white space
- have already been deleted from the argument. */
-
-static DEFINITION *
-collect_expansion (pfile, buf, limit, nargs, arglist)
- cpp_reader *pfile;
- U_CHAR *buf, *limit;
- int nargs;
- struct arglist *arglist;
-{
- DEFINITION *defn;
- register U_CHAR *p, *lastp, *exp_p;
- struct reflist *endpat = NULL;
- /* Pointer to first nonspace after last ## seen. */
- U_CHAR *concat = 0;
- /* Pointer to first nonspace after last single-# seen. */
- U_CHAR *stringify = 0;
- int maxsize;
- int expected_delimiter = '\0';
-
- /* Scan thru the replacement list, ignoring comments and quoted
- strings, picking up on the macro calls. It does a linear search
- thru the arg list on every potential symbol. Profiling might say
- that something smarter should happen. */
-
- if (limit < buf)
- abort ();
-
- /* Find the beginning of the trailing whitespace. */
- p = buf;
- while (p < limit && is_space[limit[-1]]) limit--;
-
- /* Allocate space for the text in the macro definition.
- Leading and trailing whitespace chars need 2 bytes each.
- Each other input char may or may not need 1 byte,
- so this is an upper bound. The extra 5 are for invented
- leading and trailing newline-marker and final null. */
- maxsize = (sizeof (DEFINITION)
- + (limit - p) + 5);
- /* Occurrences of '@' get doubled, so allocate extra space for them. */
- while (p < limit)
- if (*p++ == '@')
- maxsize++;
- defn = (DEFINITION *) xcalloc (1, maxsize);
-
- defn->nargs = nargs;
- exp_p = defn->expansion = (U_CHAR *) defn + sizeof (DEFINITION);
- lastp = exp_p;
-
- p = buf;
-
- /* Add one initial space escape-marker to prevent accidental
- token-pasting (often removed by macroexpand). */
- *exp_p++ = '@';
- *exp_p++ = ' ';
-
- if (limit - p >= 2 && p[0] == '#' && p[1] == '#') {
- cpp_error (pfile, "`##' at start of macro definition");
- p += 2;
- }
-
- /* Process the main body of the definition. */
- while (p < limit) {
- int skipped_arg = 0;
- register U_CHAR c = *p++;
-
- *exp_p++ = c;
-
- if (!CPP_TRADITIONAL (pfile)) {
- switch (c) {
- case '\'':
- case '\"':
- if (expected_delimiter != '\0') {
- if (c == expected_delimiter)
- expected_delimiter = '\0';
- } else
- expected_delimiter = c;
- break;
-
- case '\\':
- if (p < limit && expected_delimiter) {
- /* In a string, backslash goes through
- and makes next char ordinary. */
- *exp_p++ = *p++;
- }
- break;
-
- case '@':
- /* An '@' in a string or character constant stands for itself,
- and does not need to be escaped. */
- if (!expected_delimiter)
- *exp_p++ = c;
- break;
-
- case '#':
- /* # is ordinary inside a string. */
- if (expected_delimiter)
- break;
- if (p < limit && *p == '#') {
- /* ##: concatenate preceding and following tokens. */
- /* Take out the first #, discard preceding whitespace. */
- exp_p--;
- while (exp_p > lastp && is_hor_space[exp_p[-1]])
- --exp_p;
- /* Skip the second #. */
- p++;
- /* Discard following whitespace. */
- SKIP_WHITE_SPACE (p);
- concat = p;
- if (p == limit)
- cpp_error (pfile, "`##' at end of macro definition");
- } else if (nargs >= 0) {
- /* Single #: stringify following argument ref.
- Don't leave the # in the expansion. */
- exp_p--;
- SKIP_WHITE_SPACE (p);
- if (p == limit || ! is_idstart[*p]
- || (*p == 'L' && p + 1 < limit && (p[1] == '\'' || p[1] == '"')))
- cpp_error (pfile,
- "`#' operator is not followed by a macro argument name");
- else
- stringify = p;
- }
- break;
- }
- } else {
- /* In -traditional mode, recognize arguments inside strings and
- character constants, and ignore special properties of #.
- Arguments inside strings are considered "stringified", but no
- extra quote marks are supplied. */
- switch (c) {
- case '\'':
- case '\"':
- if (expected_delimiter != '\0') {
- if (c == expected_delimiter)
- expected_delimiter = '\0';
- } else
- expected_delimiter = c;
- break;
-
- case '\\':
- /* Backslash quotes delimiters and itself, but not macro args. */
- if (expected_delimiter != 0 && p < limit
- && (*p == expected_delimiter || *p == '\\')) {
- *exp_p++ = *p++;
- continue;
- }
- break;
-
- case '/':
- if (expected_delimiter != '\0') /* No comments inside strings. */
- break;
- if (*p == '*') {
- /* If we find a comment that wasn't removed by handle_directive,
- this must be -traditional. So replace the comment with
- nothing at all. */
- exp_p--;
- p += 1;
- while (p < limit && !(p[-2] == '*' && p[-1] == '/'))
- p++;
-#if 0
- /* Mark this as a concatenation-point, as if it had been ##. */
- concat = p;
-#endif
- }
- break;
- }
- }
-
- /* Handle the start of a symbol. */
- if (is_idchar[c] && nargs > 0) {
- U_CHAR *id_beg = p - 1;
- int id_len;
-
- --exp_p;
- while (p != limit && is_idchar[*p]) p++;
- id_len = p - id_beg;
-
- if (is_idstart[c]
- && ! (id_len == 1 && c == 'L' && (*p == '\'' || *p == '"'))) {
- register struct arglist *arg;
-
- for (arg = arglist; arg != NULL; arg = arg->next) {
- struct reflist *tpat;
-
- if (arg->name[0] == c
- && arg->length == id_len
- && strncmp (arg->name, id_beg, id_len) == 0) {
- if (expected_delimiter && CPP_OPTIONS (pfile)->warn_stringify) {
- if (CPP_TRADITIONAL (pfile)) {
- cpp_warning (pfile, "macro argument `%.*s' is stringified.",
- id_len, arg->name);
- } else {
- cpp_warning (pfile,
- "macro arg `%.*s' would be stringified with -traditional.",
- id_len, arg->name);
- }
- }
- /* If ANSI, don't actually substitute inside a string. */
- if (!CPP_TRADITIONAL (pfile) && expected_delimiter)
- break;
- /* make a pat node for this arg and append it to the end of
- the pat list */
- tpat = (struct reflist *) xmalloc (sizeof (struct reflist));
- tpat->next = NULL;
- tpat->raw_before = concat == id_beg;
- tpat->raw_after = 0;
- tpat->rest_args = arg->rest_args;
- tpat->stringify = (CPP_TRADITIONAL (pfile)
- ? expected_delimiter != '\0'
- : stringify == id_beg);
-
- if (endpat == NULL)
- defn->pattern = tpat;
- else
- endpat->next = tpat;
- endpat = tpat;
-
- tpat->argno = arg->argno;
- tpat->nchars = exp_p - lastp;
- {
- register U_CHAR *p1 = p;
- SKIP_WHITE_SPACE (p1);
- if (p1 + 2 <= limit && p1[0] == '#' && p1[1] == '#')
- tpat->raw_after = 1;
- }
- lastp = exp_p; /* place to start copying from next time */
- skipped_arg = 1;
- break;
- }
- }
- }
-
- /* If this was not a macro arg, copy it into the expansion. */
- if (! skipped_arg) {
- register U_CHAR *lim1 = p;
- p = id_beg;
- while (p != lim1)
- *exp_p++ = *p++;
- if (stringify == id_beg)
- cpp_error (pfile,
- "`#' operator should be followed by a macro argument name");
- }
- }
- }
-
- if (!CPP_TRADITIONAL (pfile) && expected_delimiter == 0)
- {
- /* If ANSI, put in a "@ " marker to prevent token pasting.
- But not if "inside a string" (which in ANSI mode
- happens only for -D option). */
- *exp_p++ = '@';
- *exp_p++ = ' ';
- }
-
- *exp_p = '\0';
-
- defn->length = exp_p - defn->expansion;
-
- /* Crash now if we overrun the allocated size. */
- if (defn->length + 1 > maxsize)
- abort ();
-
-#if 0
-/* This isn't worth the time it takes. */
- /* give back excess storage */
- defn->expansion = (U_CHAR *) xrealloc (defn->expansion, defn->length + 1);
-#endif
-
- return defn;
-}
-
-/*
- * special extension string that can be added to the last macro argument to
- * allow it to absorb the "rest" of the arguments when expanded. Ex:
- * #define wow(a, b...) process (b, a, b)
- * { wow (1, 2, 3); } -> { process (2, 3, 1, 2, 3); }
- * { wow (one, two); } -> { process (two, one, two); }
- * if this "rest_arg" is used with the concat token '##' and if it is not
- * supplied then the token attached to with ## will not be outputted. Ex:
- * #define wow (a, b...) process (b ## , a, ## b)
- * { wow (1, 2); } -> { process (2, 1, 2); }
- * { wow (one); } -> { process (one); {
- */
-static char rest_extension[] = "...";
-#define REST_EXTENSION_LENGTH (sizeof (rest_extension) - 1)
-
-/* Create a DEFINITION node from a #define directive. Arguments are
- as for do_define. */
-
-static MACRODEF
-create_definition (buf, limit, pfile, predefinition)
- U_CHAR *buf, *limit;
- cpp_reader *pfile;
- int predefinition;
-{
- U_CHAR *bp; /* temp ptr into input buffer */
- U_CHAR *symname; /* remember where symbol name starts */
- int sym_length; /* and how long it is */
- int rest_args = 0;
- long line, col;
- char *file = CPP_BUFFER (pfile) ? CPP_BUFFER (pfile)->nominal_fname : "";
- DEFINITION *defn;
- int arglengths = 0; /* Accumulate lengths of arg names
- plus number of args. */
- MACRODEF mdef;
- cpp_buf_line_and_col (CPP_BUFFER (pfile), &line, &col);
-
- bp = buf;
-
- while (is_hor_space[*bp])
- bp++;
-
- symname = bp; /* remember where it starts */
-
- sym_length = check_macro_name (pfile, bp, "macro");
- bp += sym_length;
-
- /* Lossage will occur if identifiers or control keywords are broken
- across lines using backslash. This is not the right place to take
- care of that. */
-
- if (*bp == '(') {
- struct arglist *arg_ptrs = NULL;
- int argno = 0;
-
- bp++; /* skip '(' */
- SKIP_WHITE_SPACE (bp);
-
- /* Loop over macro argument names. */
- while (*bp != ')') {
- struct arglist *temp;
-
- temp = (struct arglist *) alloca (sizeof (struct arglist));
- temp->name = bp;
- temp->next = arg_ptrs;
- temp->argno = argno++;
- temp->rest_args = 0;
- arg_ptrs = temp;
-
- if (rest_args)
- cpp_pedwarn (pfile, "another parameter follows `%s'", rest_extension);
-
- if (!is_idstart[*bp])
- cpp_pedwarn (pfile, "invalid character in macro parameter name");
-
- /* Find the end of the arg name. */
- while (is_idchar[*bp]) {
- bp++;
- /* do we have a "special" rest-args extension here? */
- if (limit - bp > REST_EXTENSION_LENGTH
- && strncmp (rest_extension, bp, REST_EXTENSION_LENGTH) == 0) {
- rest_args = 1;
- temp->rest_args = 1;
- break;
- }
- }
- temp->length = bp - temp->name;
- if (rest_args == 1)
- bp += REST_EXTENSION_LENGTH;
- arglengths += temp->length + 2;
- SKIP_WHITE_SPACE (bp);
- if (temp->length == 0 || (*bp != ',' && *bp != ')')) {
- cpp_error (pfile, "badly punctuated parameter list in `#define'");
- goto nope;
- }
- if (*bp == ',') {
- bp++;
- SKIP_WHITE_SPACE (bp);
- }
- if (bp >= limit) {
- cpp_error (pfile, "unterminated parameter list in `#define'");
- goto nope;
- }
- {
- struct arglist *otemp;
-
- for (otemp = temp->next; otemp != NULL; otemp = otemp->next)
- if (temp->length == otemp->length
- && strncmp (temp->name, otemp->name, temp->length) == 0) {
- U_CHAR *name;
-
- name = (U_CHAR *) alloca (temp->length + 1);
- (void) strncpy (name, temp->name, temp->length);
- name[temp->length] = '\0';
- cpp_error (pfile,
- "duplicate argument name `%s' in `#define'", name);
- goto nope;
- }
- }
- }
-
- ++bp; /* skip paren */
- SKIP_WHITE_SPACE (bp);
- /* now everything from bp before limit is the definition. */
- defn = collect_expansion (pfile, bp, limit, argno, arg_ptrs);
- defn->rest_args = rest_args;
-
- /* Now set defn->args.argnames to the result of concatenating
- the argument names in reverse order
- with comma-space between them. */
- defn->args.argnames = (U_CHAR *) xmalloc (arglengths + 1);
- {
- struct arglist *temp;
- int i = 0;
- for (temp = arg_ptrs; temp; temp = temp->next) {
- bcopy (temp->name, &defn->args.argnames[i], temp->length);
- i += temp->length;
- if (temp->next != 0) {
- defn->args.argnames[i++] = ',';
- defn->args.argnames[i++] = ' ';
- }
- }
- defn->args.argnames[i] = 0;
- }
- } else {
- /* Simple expansion or empty definition. */
-
- if (bp < limit)
- {
- if (is_hor_space[*bp]) {
- bp++;
- SKIP_WHITE_SPACE (bp);
- } else {
- switch (*bp) {
- case '!': case '"': case '#': case '%': case '&': case '\'':
- case ')': case '*': case '+': case ',': case '-': case '.':
- case '/': case ':': case ';': case '<': case '=': case '>':
- case '?': case '[': case '\\': case ']': case '^': case '{':
- case '|': case '}': case '~':
- cpp_warning (pfile, "missing white space after `#define %.*s'",
- sym_length, symname);
- break;
-
- default:
- cpp_pedwarn (pfile, "missing white space after `#define %.*s'",
- sym_length, symname);
- break;
- }
- }
- }
- /* now everything from bp before limit is the definition. */
- defn = collect_expansion (pfile, bp, limit, -1, NULL_PTR);
- defn->args.argnames = (U_CHAR *) "";
- }
-
- defn->line = line;
- defn->file = file;
-
- /* OP is null if this is a predefinition */
- defn->predefined = predefinition;
- mdef.defn = defn;
- mdef.symnam = symname;
- mdef.symlen = sym_length;
-
- return mdef;
-
- nope:
- mdef.defn = 0;
- return mdef;
-}
/* Check a purported macro name SYMNAME, and yield its length.
- USAGE is the kind of name this is intended for. */
+ ASSERTION is nonzero if this is really for an assertion name. */
-static int
-check_macro_name (pfile, symname, usage)
+int
+check_macro_name (pfile, symname, assertion)
cpp_reader *pfile;
U_CHAR *symname;
- char *usage;
+ int assertion;
{
U_CHAR *p;
int sym_length;
@@ -1641,118 +632,58 @@ check_macro_name (pfile, symname, usage)
sym_length = p - symname;
if (sym_length == 0
|| (sym_length == 1 && *symname == 'L' && (*p == '\'' || *p == '"')))
- cpp_error (pfile, "invalid %s name", usage);
- else if (!is_idstart[*symname]) {
+ cpp_error (pfile,
+ assertion ? "invalid assertion name" : "invalid macro name");
+ else if (!is_idstart[*symname]
+ || (! strncmp (symname, "defined", 7) && sym_length == 7)) {
U_CHAR *msg; /* what pain... */
msg = (U_CHAR *) alloca (sym_length + 1);
bcopy (symname, msg, sym_length);
msg[sym_length] = 0;
- cpp_error (pfile, "invalid %s name `%s'", usage, msg);
- } else {
- if (! strncmp (symname, "defined", 7) && sym_length == 7)
- cpp_error (pfile, "invalid %s name `defined'", usage);
+ cpp_error (pfile,
+ (assertion
+ ? "invalid assertion name `%s'"
+ : "invalid macro name `%s'"),
+ msg);
}
return sym_length;
}
-/* Return zero if two DEFINITIONs are isomorphic. */
-
-static int
-compare_defs (pfile, d1, d2)
- cpp_reader *pfile;
- DEFINITION *d1, *d2;
-{
- register struct reflist *a1, *a2;
- register U_CHAR *p1 = d1->expansion;
- register U_CHAR *p2 = d2->expansion;
- int first = 1;
-
- if (d1->nargs != d2->nargs)
- return 1;
- if (CPP_PEDANTIC (pfile)
- && strcmp ((char *)d1->args.argnames, (char *)d2->args.argnames))
- return 1;
- for (a1 = d1->pattern, a2 = d2->pattern; a1 && a2;
- a1 = a1->next, a2 = a2->next) {
- if (!((a1->nchars == a2->nchars && ! strncmp (p1, p2, a1->nchars))
- || ! comp_def_part (first, p1, a1->nchars, p2, a2->nchars, 0))
- || a1->argno != a2->argno
- || a1->stringify != a2->stringify
- || a1->raw_before != a2->raw_before
- || a1->raw_after != a2->raw_after)
- return 1;
- first = 0;
- p1 += a1->nchars;
- p2 += a2->nchars;
- }
- if (a1 != a2)
- return 1;
- if (comp_def_part (first, p1, d1->length - (p1 - d1->expansion),
- p2, d2->length - (p2 - d2->expansion), 1))
- return 1;
- return 0;
-}
-
-/* Return 1 if two parts of two macro definitions are effectively different.
- One of the parts starts at BEG1 and has LEN1 chars;
- the other has LEN2 chars at BEG2.
- Any sequence of whitespace matches any other sequence of whitespace.
- FIRST means these parts are the first of a macro definition;
- so ignore leading whitespace entirely.
- LAST means these parts are the last of a macro definition;
- so ignore trailing whitespace entirely. */
-
-static int
-comp_def_part (first, beg1, len1, beg2, len2, last)
- int first;
- U_CHAR *beg1, *beg2;
- int len1, len2;
- int last;
-{
- register U_CHAR *end1 = beg1 + len1;
- register U_CHAR *end2 = beg2 + len2;
- if (first) {
- while (beg1 != end1 && is_space[*beg1]) beg1++;
- while (beg2 != end2 && is_space[*beg2]) beg2++;
- }
- if (last) {
- while (beg1 != end1 && is_space[end1[-1]]) end1--;
- while (beg2 != end2 && is_space[end2[-1]]) end2--;
- }
- while (beg1 != end1 && beg2 != end2) {
- if (is_space[*beg1] && is_space[*beg2]) {
- while (beg1 != end1 && is_space[*beg1]) beg1++;
- while (beg2 != end2 && is_space[*beg2]) beg2++;
- } else if (*beg1 == *beg2) {
- beg1++; beg2++;
- } else break;
- }
- return (beg1 != end1) || (beg2 != end2);
-}
/* Process a #define command.
-BUF points to the contents of the #define command, as a contiguous string.
-LIMIT points to the first character past the end of the definition.
KEYWORD is the keyword-table entry for #define,
or NULL for a "predefined" macro. */
static int
-do_define (pfile, keyword, buf, limit)
+do_define (pfile, keyword)
cpp_reader *pfile;
struct directive *keyword;
- U_CHAR *buf, *limit;
{
int hashcode;
MACRODEF mdef;
HASHNODE *hp;
+ long here;
+ U_CHAR *macro, *buf, *end;
+
+ here = CPP_WRITTEN (pfile);
+ copy_rest_of_line (pfile);
+
+ /* Copy out the line so we can pop the token buffer. */
+ buf = pfile->token_buffer + here;
+ end = CPP_PWRITTEN (pfile);
+ macro = alloca (end - buf + 1);
+ bcopy (buf, macro, end - buf + 1);
+ end = macro + (end - buf);
+
+ CPP_SET_WRITTEN (pfile, here);
#if 0
/* If this is a precompiler run (with -pcp) pass thru #define commands. */
if (pcp_outfile && keyword)
- pass_thru_directive (buf, limit, pfile, keyword);
+ pass_thru_directive (macro, end, pfile, keyword);
#endif
- mdef = create_definition (buf, limit, pfile, keyword == NULL);
+ mdef = create_definition (macro, end, pfile, keyword == NULL);
if (mdef.defn == 0)
goto nope;
@@ -1768,23 +699,17 @@ do_define (pfile, keyword, buf, limit)
else if (hp->type == T_MACRO)
ok = ! compare_defs (pfile, mdef.defn, hp->value.defn);
/* Redefining a constant is ok with -D. */
- else if (hp->type == T_CONST)
+ else if (hp->type == T_CONST || hp->type == T_STDC)
ok = ! CPP_OPTIONS (pfile)->done_initializing;
/* Print the warning if it's not ok. */
if (!ok)
{
- U_CHAR *msg; /* what pain... */
-
/* If we are passing through #define and #undef directives, do
that for this re-definition now. */
if (CPP_OPTIONS (pfile)->debug_output && keyword)
- pass_thru_directive (buf, limit, pfile, keyword);
+ pass_thru_directive (macro, end, pfile, keyword);
- msg = (U_CHAR *) alloca (mdef.symlen + 22);
- *msg = '`';
- bcopy (mdef.symnam, msg + 1, mdef.symlen);
- strcpy ((char *) (msg + mdef.symlen + 1), "' redefined");
- cpp_pedwarn (pfile, msg);
+ cpp_pedwarn (pfile, "`%.*s' redefined", mdef.symlen, mdef.symnam);
if (hp->type == T_MACRO)
cpp_pedwarn_with_file_and_line (pfile, hp->value.defn->file, hp->value.defn->line,
"this is the location of the previous definition");
@@ -1798,9 +723,9 @@ do_define (pfile, keyword, buf, limit)
/* If we are passing through #define and #undef directives, do
that for this new definition now. */
if (CPP_OPTIONS (pfile)->debug_output && keyword)
- pass_thru_directive (buf, limit, pfile, keyword);
- install (mdef.symnam, mdef.symlen, T_MACRO, 0,
- (char *) mdef.defn, hashcode);
+ pass_thru_directive (macro, end, pfile, keyword);
+ cpp_install (pfile, mdef.symnam, mdef.symlen, T_MACRO,
+ (char *) mdef.defn, hashcode);
}
return 0;
@@ -1810,27 +735,6 @@ nope:
return 1;
}
-/* This structure represents one parsed argument in a macro call.
- `raw' points to the argument text as written (`raw_length' is its length).
- `expanded' points to the argument's macro-expansion
- (its length is `expand_length').
- `stringified_length' is the length the argument would have
- if stringified.
- `use_count' is the number of times this macro arg is substituted
- into the macro. If the actual use count exceeds 10,
- the value stored is 10. */
-
-/* raw and expanded are relative to ARG_BASE */
-#define ARG_BASE ((pfile)->token_buffer)
-
-struct argdata {
- /* Strings relative to pfile->token_buffer */
- long raw, expanded, stringified;
- int raw_length, expand_length;
- int stringified_length;
- char newlines;
- char use_count;
-};
/* Allocate a new cpp_buffer for PFILE, and push it on the input buffer stack.
If BUFFER != NULL, then use the LENGTH characters in BUFFER
@@ -1843,23 +747,26 @@ cpp_push_buffer (pfile, buffer, length)
U_CHAR *buffer;
long length;
{
- register cpp_buffer *buf = CPP_BUFFER (pfile);
- if (buf == pfile->buffer_stack)
+ cpp_buffer *buf = CPP_BUFFER (pfile);
+ cpp_buffer *new;
+ if (++pfile->buffer_stack_depth == CPP_STACK_MAX)
{
- cpp_fatal (pfile, "%s: macro or `#include' recursion too deep",
- buf->fname);
+ cpp_fatal (pfile, "macro or `#include' recursion too deep");
return NULL;
}
- buf--;
- bzero ((char *) buf, sizeof (cpp_buffer));
- CPP_BUFFER (pfile) = buf;
- buf->if_stack = pfile->if_stack;
- buf->cleanup = null_cleanup;
- buf->underflow = null_underflow;
- buf->buf = buf->cur = buffer;
- buf->alimit = buf->rlimit = buffer + length;
-
- return buf;
+
+ new = (cpp_buffer *) xcalloc (sizeof (cpp_buffer), 1);
+
+ new->if_stack = pfile->if_stack;
+ new->cleanup = null_cleanup;
+ new->underflow = null_underflow;
+ new->buf = new->cur = buffer;
+ new->alimit = new->rlimit = buffer + length;
+ new->prev = buf;
+ new->mark = -1;
+
+ CPP_BUFFER (pfile) = new;
+ return new;
}
cpp_buffer *
@@ -1868,7 +775,10 @@ cpp_pop_buffer (pfile)
{
cpp_buffer *buf = CPP_BUFFER (pfile);
(*buf->cleanup) (buf, pfile);
- return ++CPP_BUFFER (pfile);
+ CPP_BUFFER (pfile) = CPP_PREV_BUFFER (buf);
+ free (buf);
+ pfile->buffer_stack_depth--;
+ return CPP_BUFFER (pfile);
}
/* Scan until CPP_BUFFER (PFILE) is exhausted into PFILE->token_buffer.
@@ -1901,7 +811,7 @@ cpp_scan_buffer (pfile)
* (because it follows CPP_WRITTEN). This is used by do_include.
*/
-static void
+void
cpp_expand_to_buffer (pfile, buf, length)
cpp_reader *pfile;
U_CHAR *buf;
@@ -1911,7 +821,6 @@ cpp_expand_to_buffer (pfile, buf, length)
#if 0
cpp_buffer obuf;
#endif
- U_CHAR *limit = buf + length;
U_CHAR *buf1;
#if 0
int odepth = indepth;
@@ -1923,13 +832,7 @@ cpp_expand_to_buffer (pfile, buf, length)
/* Set up the input on the input stack. */
buf1 = (U_CHAR *) alloca (length + 1);
- {
- register U_CHAR *p1 = buf;
- register U_CHAR *p2 = buf1;
-
- while (p1 != limit)
- *p2++ = *p1++;
- }
+ memcpy (buf1, buf, length);
buf1[length] = 0;
ip = cpp_push_buffer (pfile, buf1, length);
@@ -1943,68 +846,25 @@ cpp_expand_to_buffer (pfile, buf, length)
/* Scan the input, create the output. */
cpp_scan_buffer (pfile);
-#if 0
- if (indepth != odepth)
- abort ();
-#endif
-
CPP_NUL_TERMINATE (pfile);
}
-
-static void
-adjust_position (buf, limit, linep, colp)
- U_CHAR *buf;
- U_CHAR *limit;
- long *linep;
- long *colp;
-{
- while (buf < limit)
- {
- U_CHAR ch = *buf++;
- if (ch == '\n')
- (*linep)++, (*colp) = 1;
- else
- (*colp)++;
- }
-}
-
-/* Move line_base forward, updating lineno and colno. */
-
-static void
-update_position (pbuf)
- register cpp_buffer *pbuf;
-{
- unsigned char *old_pos = pbuf->buf + pbuf->line_base;
- unsigned char *new_pos = pbuf->cur;
- register struct parse_marker *mark;
- for (mark = pbuf->marks; mark != NULL; mark = mark->next)
- {
- if (pbuf->buf + mark->position < new_pos)
- new_pos = pbuf->buf + mark->position;
- }
- pbuf->line_base += new_pos - old_pos;
- adjust_position (old_pos, new_pos, &pbuf->lineno, &pbuf->colno);
-}
-
void
cpp_buf_line_and_col (pbuf, linep, colp)
register cpp_buffer *pbuf;
long *linep, *colp;
{
- long dummy;
- if (colp == NULL)
- colp = &dummy;
if (pbuf)
{
*linep = pbuf->lineno;
- *colp = pbuf->colno;
- adjust_position (pbuf->buf + pbuf->line_base, pbuf->cur, linep, colp);
+ if (colp)
+ *colp = pbuf->cur - pbuf->line_base;
}
else
{
*linep = 0;
- *colp = 0;
+ if (colp)
+ *colp = 0;
}
}
@@ -2022,21 +882,6 @@ cpp_file_buffer (pfile)
return NULL;
}
-static long
-count_newlines (buf, limit)
- register U_CHAR *buf;
- register U_CHAR *limit;
-{
- register long count = 0;
- while (buf < limit)
- {
- U_CHAR ch = *buf++;
- if (ch == '\n')
- count++;
- }
- return count;
-}
-
/*
* write out a #line command, for instance, after an #include file.
* If CONDITIONAL is nonzero, we can omit the #line if it would
@@ -2045,7 +890,7 @@ count_newlines (buf, limit)
* FILE_CHANGE says whether we are entering a file, leaving, or neither.
*/
-static void
+void
output_line_command (pfile, conditional, file_change)
cpp_reader *pfile;
int conditional;
@@ -2057,979 +902,62 @@ output_line_command (pfile, conditional, file_change)
if (ip->fname == NULL)
return;
- update_position (ip);
-
if (CPP_OPTIONS (pfile)->no_line_commands
|| CPP_OPTIONS (pfile)->no_output)
return;
- line = CPP_BUFFER (pfile)->lineno;
- col = CPP_BUFFER (pfile)->colno;
- adjust_position (CPP_LINE_BASE (ip), ip->cur, &line, &col);
+ cpp_buf_line_and_col (CPP_BUFFER (pfile), &line, &col);
- if (CPP_OPTIONS (pfile)->no_line_commands)
- return;
+ if (conditional)
+ {
+ if (line == pfile->lineno)
+ return;
- if (conditional) {
- if (line == pfile->lineno)
- return;
-
- /* If the inherited line number is a little too small,
- output some newlines instead of a #line command. */
- if (line > pfile->lineno && line < pfile->lineno + 8) {
- CPP_RESERVE (pfile, 20);
- while (line > pfile->lineno) {
- CPP_PUTC_Q (pfile, '\n');
- pfile->lineno++;
- }
- return;
+ /* If the inherited line number is a little too small,
+ output some newlines instead of a #line command. */
+ if (line > pfile->lineno && line < pfile->lineno + 8)
+ {
+ CPP_RESERVE (pfile, 20);
+ while (line > pfile->lineno)
+ {
+ CPP_PUTC_Q (pfile, '\n');
+ pfile->lineno++;
+ }
+ return;
+ }
}
- }
-
-#if 0
- /* Don't output a line number of 0 if we can help it. */
- if (ip->lineno == 0 && ip->bufp - ip->buf < ip->length
- && *ip->bufp == '\n') {
- ip->lineno++;
- ip->bufp++;
- }
-#endif
CPP_RESERVE (pfile, 4 * strlen (ip->nominal_fname) + 50);
- {
-#ifdef OUTPUT_LINE_COMMANDS
- static char sharp_line[] = "#line ";
-#else
- static char sharp_line[] = "# ";
-#endif
- CPP_PUTS_Q (pfile, sharp_line, sizeof(sharp_line)-1);
- }
+ CPP_PUTS_Q (pfile, "# ", 2);
sprintf ((char *) CPP_PWRITTEN (pfile), "%ld ", line);
CPP_ADJUST_WRITTEN (pfile, strlen (CPP_PWRITTEN (pfile)));
quote_string (pfile, ip->nominal_fname);
- if (file_change != same_file) {
- CPP_PUTC_Q (pfile, ' ');
- CPP_PUTC_Q (pfile, file_change == enter_file ? '1' : '2');
- }
- /* Tell cc1 if following text comes from a system header file. */
- if (ip->system_header_p) {
- CPP_PUTC_Q (pfile, ' ');
- CPP_PUTC_Q (pfile, '3');
- }
-#ifndef NO_IMPLICIT_EXTERN_C
- /* Tell cc1plus if following text should be treated as C. */
- if (ip->system_header_p == 2 && CPP_OPTIONS (pfile)->cplusplus) {
- CPP_PUTC_Q (pfile, ' ');
- CPP_PUTC_Q (pfile, '4');
- }
-#endif
- CPP_PUTC_Q (pfile, '\n');
- pfile->lineno = line;
-}
-
-/*
- * Parse a macro argument and append the info on PFILE's token_buffer.
- * REST_ARGS means to absorb the rest of the args.
- * Return nonzero to indicate a syntax error.
- */
-
-static enum cpp_token
-macarg (pfile, rest_args)
- cpp_reader *pfile;
- int rest_args;
-{
- int paren = 0;
- enum cpp_token token;
- char save_put_out_comments = CPP_OPTIONS (pfile)->put_out_comments;
- CPP_OPTIONS (pfile)->put_out_comments = 0;
-
- /* Try to parse as much of the argument as exists at this
- input stack level. */
- pfile->no_macro_expand++;
- for (;;)
+ if (file_change != same_file)
{
- token = cpp_get_token (pfile);
- switch (token)
- {
- case CPP_EOF:
- goto done;
- case CPP_POP:
- /* If we've hit end of file, it's an error (reported by caller).
- Ditto if it's the end of cpp_expand_to_buffer text.
- If we've hit end of macro, just continue. */
- if (! CPP_IS_MACRO_BUFFER (CPP_BUFFER (pfile)))
- goto done;
- break;
- case CPP_LPAREN:
- paren++;
- break;
- case CPP_RPAREN:
- if (--paren < 0)
- goto found;
- break;
- case CPP_COMMA:
- /* if we've returned to lowest level and
- we aren't absorbing all args */
- if (paren == 0 && rest_args == 0)
- goto found;
- break;
- found:
- /* Remove ',' or ')' from argument buffer. */
- CPP_ADJUST_WRITTEN (pfile, -1);
- goto done;
- default: ;
- }
+ CPP_PUTC_Q (pfile, ' ');
+ CPP_PUTC_Q (pfile, file_change == enter_file ? '1' : '2');
}
-
- done:
- CPP_OPTIONS (pfile)->put_out_comments = save_put_out_comments;
- pfile->no_macro_expand--;
-
- return token;
-}
-
-/* Turn newlines to spaces in the string of length LENGTH at START,
- except inside of string constants.
- The string is copied into itself with its beginning staying fixed. */
-
-static int
-change_newlines (start, length)
- U_CHAR *start;
- int length;
-{
- register U_CHAR *ibp;
- register U_CHAR *obp;
- register U_CHAR *limit;
- register int c;
-
- ibp = start;
- limit = start + length;
- obp = start;
-
- while (ibp < limit) {
- *obp++ = c = *ibp++;
- switch (c) {
-
- case '\'':
- case '\"':
- /* Notice and skip strings, so that we don't delete newlines in them. */
- {
- int quotec = c;
- while (ibp < limit) {
- *obp++ = c = *ibp++;
- if (c == quotec)
- break;
- if (c == '\n' && quotec == '\'')
- break;
- }
- }
- break;
- }
- }
-
- return obp - start;
-}
-
-
-static struct tm *
-timestamp (pfile)
- cpp_reader *pfile;
-{
- if (!pfile->timebuf) {
- time_t t = time ((time_t *) 0);
- pfile->timebuf = localtime (&t);
- }
- return pfile->timebuf;
-}
-
-static char *monthnames[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
- "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
- };
-
-/*
- * expand things like __FILE__. Place the expansion into the output
- * buffer *without* rescanning.
- */
-
-static void
-special_symbol (hp, pfile)
- HASHNODE *hp;
- cpp_reader *pfile;
-{
- char *buf;
- int len;
- int true_indepth;
- cpp_buffer *ip = NULL;
- struct tm *timebuf;
-
- int paren = 0; /* For special `defined' keyword */
-
-#if 0
- if (pcp_outfile && pcp_inside_if
- && hp->type != T_SPEC_DEFINED && hp->type != T_CONST)
- cpp_error (pfile,
- "Predefined macro `%s' used inside `#if' during precompilation",
- hp->name);
-#endif
-
- for (ip = CPP_BUFFER (pfile); ; ip = CPP_PREV_BUFFER (ip))
+ /* Tell cc1 if following text comes from a system header file. */
+ if (ip->system_header_p)
{
- if (ip == CPP_NULL_BUFFER (pfile))
- {
- cpp_error (pfile, "cccp error: not in any file?!");
- return; /* the show must go on */
- }
- if (ip->fname != NULL)
- break;
+ CPP_PUTC_Q (pfile, ' ');
+ CPP_PUTC_Q (pfile, '3');
}
-
- switch (hp->type)
+#ifndef NO_IMPLICIT_EXTERN_C
+ /* Tell cc1plus if following text should be treated as C. */
+ if (ip->system_header_p == 2 && CPP_OPTIONS (pfile)->cplusplus)
{
- case T_FILE:
- case T_BASE_FILE:
- {
- char *string;
- if (hp->type == T_BASE_FILE)
- {
- while (CPP_PREV_BUFFER (ip) != CPP_NULL_BUFFER (pfile))
- ip = CPP_PREV_BUFFER (ip);
- }
- string = ip->nominal_fname;
-
- if (!string)
- string = "";
- CPP_RESERVE (pfile, 3 + 4 * strlen (string));
- quote_string (pfile, string);
- return;
- }
-
- case T_INCLUDE_LEVEL:
- true_indepth = 0;
- ip = CPP_BUFFER (pfile);
- for (; ip != CPP_NULL_BUFFER (pfile); ip = CPP_PREV_BUFFER (ip))
- if (ip->fname != NULL)
- true_indepth++;
-
- buf = (char *) alloca (8); /* Eight bytes ought to be more than enough */
- sprintf (buf, "%d", true_indepth - 1);
- break;
-
- case T_VERSION:
- buf = (char *) alloca (3 + strlen (version_string));
- sprintf (buf, "\"%s\"", version_string);
- break;
-
-#ifndef NO_BUILTIN_SIZE_TYPE
- case T_SIZE_TYPE:
- buf = SIZE_TYPE;
- break;
-#endif
-
-#ifndef NO_BUILTIN_PTRDIFF_TYPE
- case T_PTRDIFF_TYPE:
- buf = PTRDIFF_TYPE;
- break;
-#endif
-
- case T_WCHAR_TYPE:
- buf = CPP_WCHAR_TYPE (pfile);
- break;
-
- case T_USER_LABEL_PREFIX_TYPE:
- buf = USER_LABEL_PREFIX;
- break;
-
- case T_REGISTER_PREFIX_TYPE:
- buf = REGISTER_PREFIX;
- break;
-
- case T_CONST:
- buf = (char *) alloca (4 * sizeof (int));
- sprintf (buf, "%d", hp->value.ival);
-#ifdef STDC_0_IN_SYSTEM_HEADERS
- if (ip->system_header_p
- && hp->length == 8 && bcmp (hp->name, "__STDC__", 8) == 0
- && ! cpp_lookup (pfile, (U_CHAR *) "__STRICT_ANSI__", -1, -1))
- strcpy (buf, "0");
-#endif
-#if 0
- if (pcp_inside_if && pcp_outfile)
- /* Output a precondition for this macro use */
- fprintf (pcp_outfile, "#define %s %d\n", hp->name, hp->value.ival);
-#endif
- break;
-
- case T_SPECLINE:
- {
- long line = ip->lineno;
- long col = ip->colno;
- adjust_position (CPP_LINE_BASE (ip), ip->cur, &line, &col);
-
- buf = (char *) alloca (10);
- sprintf (buf, "%ld", line);
- }
- break;
-
- case T_DATE:
- case T_TIME:
- buf = (char *) alloca (20);
- timebuf = timestamp (pfile);
- if (hp->type == T_DATE)
- sprintf (buf, "\"%s %2d %4d\"", monthnames[timebuf->tm_mon],
- timebuf->tm_mday, timebuf->tm_year + 1900);
- else
- sprintf (buf, "\"%02d:%02d:%02d\"", timebuf->tm_hour, timebuf->tm_min,
- timebuf->tm_sec);
- break;
-
- case T_SPEC_DEFINED:
- buf = " 0 "; /* Assume symbol is not defined */
- ip = CPP_BUFFER (pfile);
- SKIP_WHITE_SPACE (ip->cur);
- if (*ip->cur == '(')
- {
- paren++;
- ip->cur++; /* Skip over the paren */
- SKIP_WHITE_SPACE (ip->cur);
- }
-
- if (!is_idstart[*ip->cur])
- goto oops;
- if (ip->cur[0] == 'L' && (ip->cur[1] == '\'' || ip->cur[1] == '"'))
- goto oops;
- if ((hp = cpp_lookup (pfile, ip->cur, -1, -1)))
- {
-#if 0
- if (pcp_outfile && pcp_inside_if
- && (hp->type == T_CONST
- || (hp->type == T_MACRO && hp->value.defn->predefined)))
- /* Output a precondition for this macro use. */
- fprintf (pcp_outfile, "#define %s\n", hp->name);
-#endif
- buf = " 1 ";
- }
-#if 0
- else
- if (pcp_outfile && pcp_inside_if)
- {
- /* Output a precondition for this macro use */
- U_CHAR *cp = ip->bufp;
- fprintf (pcp_outfile, "#undef ");
- while (is_idchar[*cp]) /* Ick! */
- fputc (*cp++, pcp_outfile);
- putc ('\n', pcp_outfile);
- }
-#endif
- while (is_idchar[*ip->cur])
- ++ip->cur;
- SKIP_WHITE_SPACE (ip->cur);
- if (paren)
- {
- if (*ip->cur != ')')
- goto oops;
- ++ip->cur;
- }
- break;
-
- oops:
-
- cpp_error (pfile, "`defined' without an identifier");
- break;
-
- default:
- cpp_error (pfile, "cccp error: invalid special hash type"); /* time for gdb */
- abort ();
+ CPP_PUTC_Q (pfile, ' ');
+ CPP_PUTC_Q (pfile, '4');
}
- len = strlen (buf);
- CPP_RESERVE (pfile, len + 1);
- CPP_PUTS_Q (pfile, buf, len);
- CPP_NUL_TERMINATE_Q (pfile);
-
- return;
-}
-
-/* Write out a #define command for the special named MACRO_NAME
- to PFILE's token_buffer. */
-
-static void
-dump_special_to_buffer (pfile, macro_name)
- cpp_reader *pfile;
- char *macro_name;
-{
- static char define_directive[] = "#define ";
- int macro_name_length = strlen (macro_name);
- output_line_command (pfile, 0, same_file);
- CPP_RESERVE (pfile, sizeof(define_directive) + macro_name_length);
- CPP_PUTS_Q (pfile, define_directive, sizeof(define_directive)-1);
- CPP_PUTS_Q (pfile, macro_name, macro_name_length);
- CPP_PUTC_Q (pfile, ' ');
- cpp_expand_to_buffer (pfile, macro_name, macro_name_length);
- CPP_PUTC (pfile, '\n');
-}
-
-/* Initialize the built-in macros. */
-
-static void
-initialize_builtins (pfile)
- cpp_reader *pfile;
-{
- install ((U_CHAR *)"__LINE__", -1, T_SPECLINE, 0, 0, -1);
- install ((U_CHAR *)"__DATE__", -1, T_DATE, 0, 0, -1);
- install ((U_CHAR *)"__FILE__", -1, T_FILE, 0, 0, -1);
- install ((U_CHAR *)"__BASE_FILE__", -1, T_BASE_FILE, 0, 0, -1);
- install ((U_CHAR *)"__INCLUDE_LEVEL__", -1, T_INCLUDE_LEVEL, 0, 0, -1);
- install ((U_CHAR *)"__VERSION__", -1, T_VERSION, 0, 0, -1);
-#ifndef NO_BUILTIN_SIZE_TYPE
- install ((U_CHAR *)"__SIZE_TYPE__", -1, T_SIZE_TYPE, 0, 0, -1);
-#endif
-#ifndef NO_BUILTIN_PTRDIFF_TYPE
- install ((U_CHAR *)"__PTRDIFF_TYPE__ ", -1, T_PTRDIFF_TYPE, 0, 0, -1);
#endif
- install ((U_CHAR *)"__WCHAR_TYPE__", -1, T_WCHAR_TYPE, 0, 0, -1);
- install ((U_CHAR *)"__USER_LABEL_PREFIX__", -1, T_USER_LABEL_PREFIX_TYPE, 0, 0, -1);
- install ((U_CHAR *)"__REGISTER_PREFIX__", -1, T_REGISTER_PREFIX_TYPE, 0, 0, -1);
- install ((U_CHAR *)"__TIME__", -1, T_TIME, 0, 0, -1);
- if (!CPP_TRADITIONAL (pfile))
- install ((U_CHAR *)"__STDC__", -1, T_CONST, STDC_VALUE, 0, -1);
- if (CPP_OPTIONS (pfile)->objc)
- install ((U_CHAR *)"__OBJC__", -1, T_CONST, 1, 0, -1);
-/* This is supplied using a -D by the compiler driver
- so that it is present only when truly compiling with GNU C. */
-/* install ("__GNUC__", -1, T_CONST, 2, 0, -1); */
-
- if (CPP_OPTIONS (pfile)->debug_output)
- {
- dump_special_to_buffer (pfile, "__BASE_FILE__");
- dump_special_to_buffer (pfile, "__VERSION__");
-#ifndef NO_BUILTIN_SIZE_TYPE
- dump_special_to_buffer (pfile, "__SIZE_TYPE__");
-#endif
-#ifndef NO_BUILTIN_PTRDIFF_TYPE
- dump_special_to_buffer (pfile, "__PTRDIFF_TYPE__");
-#endif
- dump_special_to_buffer (pfile, "__WCHAR_TYPE__");
- dump_special_to_buffer (pfile, "__DATE__");
- dump_special_to_buffer (pfile, "__TIME__");
- if (!CPP_TRADITIONAL (pfile))
- dump_special_to_buffer (pfile, "__STDC__");
- if (CPP_OPTIONS (pfile)->objc)
- dump_special_to_buffer (pfile, "__OBJC__");
- }
-}
-
-/* Return 1 iff a token ending in C1 followed directly by a token C2
- could cause mis-tokenization. */
-
-static int
-unsafe_chars (c1, c2)
- int c1, c2;
-{
- switch (c1)
- {
- case '+': case '-':
- if (c2 == c1 || c2 == '=')
- return 1;
- goto letter;
- case '.':
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- case 'e': case 'E': case 'p': case 'P':
- if (c2 == '-' || c2 == '+')
- return 1; /* could extend a pre-processing number */
- goto letter;
- case 'L':
- if (c2 == '\'' || c2 == '\"')
- return 1; /* Could turn into L"xxx" or L'xxx'. */
- goto letter;
- letter:
- case '_':
- case 'a': case 'b': case 'c': case 'd': case 'f':
- case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
- case 'm': case 'n': case 'o': 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 'F':
- case 'G': case 'H': case 'I': case 'J': case 'K':
- case 'M': case 'N': case 'O': case 'Q': case 'R':
- case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
- case 'Y': case 'Z':
- /* We're in the middle of either a name or a pre-processing number. */
- return (is_idchar[c2] || c2 == '.');
- case '<': case '>': case '!': case '%': case '#': case ':':
- case '^': case '&': case '|': case '*': case '/': case '=':
- return (c2 == c1 || c2 == '=');
- }
- return 0;
+ CPP_PUTC_Q (pfile, '\n');
+ pfile->lineno = line;
}
-/* Expand a macro call.
- HP points to the symbol that is the macro being called.
- Put the result of expansion onto the input stack
- so that subsequent input by our caller will use it.
-
- If macro wants arguments, caller has already verified that
- an argument list follows; arguments come from the input stack. */
-
-static void
-macroexpand (pfile, hp)
- cpp_reader *pfile;
- HASHNODE *hp;
-{
- int nargs;
- DEFINITION *defn = hp->value.defn;
- register U_CHAR *xbuf;
- long start_line, start_column;
- int xbuf_len;
- struct argdata *args;
- long old_written = CPP_WRITTEN (pfile);
-#if 0
- int start_line = instack[indepth].lineno;
-#endif
- int rest_args, rest_zero;
- register int i;
-
-#if 0
- CHECK_DEPTH (return;);
-#endif
-
-#if 0
- /* This macro is being used inside a #if, which means it must be */
- /* recorded as a precondition. */
- if (pcp_inside_if && pcp_outfile && defn->predefined)
- dump_single_macro (hp, pcp_outfile);
-#endif
-
- pfile->output_escapes++;
- cpp_buf_line_and_col (cpp_file_buffer (pfile), &start_line, &start_column);
-
- nargs = defn->nargs;
-
- if (nargs >= 0)
- {
- enum cpp_token token;
-
- args = (struct argdata *) alloca ((nargs + 1) * sizeof (struct argdata));
-
- for (i = 0; i < nargs; i++)
- {
- args[i].raw = args[i].expanded = 0;
- args[i].raw_length = 0;
- args[i].expand_length = args[i].stringified_length = -1;
- args[i].use_count = 0;
- }
-
- /* Parse all the macro args that are supplied. I counts them.
- The first NARGS args are stored in ARGS.
- The rest are discarded. If rest_args is set then we assume
- macarg absorbed the rest of the args. */
- i = 0;
- rest_args = 0;
- rest_args = 0;
- FORWARD(1); /* Discard the open-parenthesis before the first arg. */
- do
- {
- if (rest_args)
- continue;
- if (i < nargs || (nargs == 0 && i == 0))
- {
- /* if we are working on last arg which absorbs rest of args... */
- if (i == nargs - 1 && defn->rest_args)
- rest_args = 1;
- args[i].raw = CPP_WRITTEN (pfile);
- token = macarg (pfile, rest_args);
- args[i].raw_length = CPP_WRITTEN (pfile) - args[i].raw;
- args[i].newlines = 0; /* FIXME */
- }
- else
- token = macarg (pfile, 0);
- if (token == CPP_EOF || token == CPP_POP)
- {
- cpp_error_with_line (pfile, start_line, start_column,
- "unterminated macro call");
- return;
- }
- i++;
- } while (token == CPP_COMMA);
-
- /* If we got one arg but it was just whitespace, call that 0 args. */
- if (i == 1)
- {
- register U_CHAR *bp = ARG_BASE + args[0].raw;
- register U_CHAR *lim = bp + args[0].raw_length;
- /* cpp.texi says for foo ( ) we provide one argument.
- However, if foo wants just 0 arguments, treat this as 0. */
- if (nargs == 0)
- while (bp != lim && is_space[*bp]) bp++;
- if (bp == lim)
- i = 0;
- }
-
- /* Don't output an error message if we have already output one for
- a parse error above. */
- rest_zero = 0;
- if (nargs == 0 && i > 0)
- {
- cpp_error (pfile, "arguments given to macro `%s'", hp->name);
- }
- else if (i < nargs)
- {
- /* traditional C allows foo() if foo wants one argument. */
- if (nargs == 1 && i == 0 && CPP_TRADITIONAL (pfile))
- ;
- /* the rest args token is allowed to absorb 0 tokens */
- else if (i == nargs - 1 && defn->rest_args)
- rest_zero = 1;
- else if (i == 0)
- cpp_error (pfile, "macro `%s' used without args", hp->name);
- else if (i == 1)
- cpp_error (pfile, "macro `%s' used with just one arg", hp->name);
- else
- cpp_error (pfile, "macro `%s' used with only %d args",
- hp->name, i);
- }
- else if (i > nargs)
- {
- cpp_error (pfile,
- "macro `%s' used with too many (%d) args", hp->name, i);
- }
- }
-
- /* If macro wants zero args, we parsed the arglist for checking only.
- Read directly from the macro definition. */
- if (nargs <= 0)
- {
- xbuf = defn->expansion;
- xbuf_len = defn->length;
- }
- else
- {
- register U_CHAR *exp = defn->expansion;
- register int offset; /* offset in expansion,
- copied a piece at a time */
- register int totlen; /* total amount of exp buffer filled so far */
-
- register struct reflist *ap, *last_ap;
-
- /* Macro really takes args. Compute the expansion of this call. */
-
- /* Compute length in characters of the macro's expansion.
- Also count number of times each arg is used. */
- xbuf_len = defn->length;
- for (ap = defn->pattern; ap != NULL; ap = ap->next)
- {
- if (ap->stringify)
- {
- register struct argdata *arg = &args[ap->argno];
- /* Stringify if it hasn't already been */
- if (arg->stringified_length < 0)
- {
- int arglen = arg->raw_length;
- int escaped = 0;
- int in_string = 0;
- int c;
- /* Initially need_space is -1. Otherwise, 1 means the
- previous character was a space, but we suppressed it;
- 0 means the previous character was a non-space. */
- int need_space = -1;
- i = 0;
- arg->stringified = CPP_WRITTEN (pfile);
- if (!CPP_TRADITIONAL (pfile))
- CPP_PUTC (pfile, '\"'); /* insert beginning quote */
- for (; i < arglen; i++)
- {
- c = (ARG_BASE + arg->raw)[i];
-
- if (! in_string)
- {
- /* Internal sequences of whitespace are replaced by
- one space except within an string or char token.*/
- if (is_space[c])
- {
- if (CPP_WRITTEN (pfile) > arg->stringified
- && (CPP_PWRITTEN (pfile))[-1] == '@')
- {
- /* "@ " escape markers are removed */
- CPP_ADJUST_WRITTEN (pfile, -1);
- continue;
- }
- if (need_space == 0)
- need_space = 1;
- continue;
- }
- else if (need_space > 0)
- CPP_PUTC (pfile, ' ');
- need_space = 0;
- }
-
- if (escaped)
- escaped = 0;
- else
- {
- if (c == '\\')
- escaped = 1;
- if (in_string)
- {
- if (c == in_string)
- in_string = 0;
- }
- else if (c == '\"' || c == '\'')
- in_string = c;
- }
-
- /* Escape these chars */
- if (c == '\"' || (in_string && c == '\\'))
- CPP_PUTC (pfile, '\\');
- if (ISPRINT (c))
- CPP_PUTC (pfile, c);
- else
- {
- CPP_RESERVE (pfile, 4);
- sprintf ((char *)CPP_PWRITTEN (pfile), "\\%03o",
- (unsigned int) c);
- CPP_ADJUST_WRITTEN (pfile, 4);
- }
- }
- if (!CPP_TRADITIONAL (pfile))
- CPP_PUTC (pfile, '\"'); /* insert ending quote */
- arg->stringified_length
- = CPP_WRITTEN (pfile) - arg->stringified;
- }
- xbuf_len += args[ap->argno].stringified_length;
- }
- else if (ap->raw_before || ap->raw_after || CPP_TRADITIONAL (pfile))
- /* Add 4 for two newline-space markers to prevent
- token concatenation. */
- xbuf_len += args[ap->argno].raw_length + 4;
- else
- {
- /* We have an ordinary (expanded) occurrence of the arg.
- So compute its expansion, if we have not already. */
- if (args[ap->argno].expand_length < 0)
- {
- args[ap->argno].expanded = CPP_WRITTEN (pfile);
- cpp_expand_to_buffer (pfile,
- ARG_BASE + args[ap->argno].raw,
- args[ap->argno].raw_length);
-
- args[ap->argno].expand_length
- = CPP_WRITTEN (pfile) - args[ap->argno].expanded;
- }
-
- /* Add 4 for two newline-space markers to prevent
- token concatenation. */
- xbuf_len += args[ap->argno].expand_length + 4;
- }
- if (args[ap->argno].use_count < 10)
- args[ap->argno].use_count++;
- }
-
- xbuf = (U_CHAR *) xmalloc (xbuf_len + 1);
-
- /* Generate in XBUF the complete expansion
- with arguments substituted in.
- TOTLEN is the total size generated so far.
- OFFSET is the index in the definition
- of where we are copying from. */
- offset = totlen = 0;
- for (last_ap = NULL, ap = defn->pattern; ap != NULL;
- last_ap = ap, ap = ap->next)
- {
- register struct argdata *arg = &args[ap->argno];
- int count_before = totlen;
-
- /* Add chars to XBUF. */
- for (i = 0; i < ap->nchars; i++, offset++)
- xbuf[totlen++] = exp[offset];
-
- /* If followed by an empty rest arg with concatenation,
- delete the last run of nonwhite chars. */
- if (rest_zero && totlen > count_before
- && ((ap->rest_args && ap->raw_before)
- || (last_ap != NULL && last_ap->rest_args
- && last_ap->raw_after)))
- {
- /* Delete final whitespace. */
- while (totlen > count_before && is_space[xbuf[totlen - 1]])
- totlen--;
- /* Delete the nonwhites before them. */
- while (totlen > count_before && ! is_space[xbuf[totlen - 1]])
- totlen--;
- }
-
- if (ap->stringify != 0)
- {
- bcopy (ARG_BASE + arg->stringified,
- xbuf + totlen, arg->stringified_length);
- totlen += arg->stringified_length;
- }
- else if (ap->raw_before || ap->raw_after || CPP_TRADITIONAL (pfile))
- {
- U_CHAR *p1 = ARG_BASE + arg->raw;
- U_CHAR *l1 = p1 + arg->raw_length;
- if (ap->raw_before)
- {
- while (p1 != l1 && is_space[*p1]) p1++;
- while (p1 != l1 && is_idchar[*p1])
- xbuf[totlen++] = *p1++;
- }
- if (ap->raw_after)
- {
- /* Arg is concatenated after: delete trailing whitespace,
- whitespace markers, and no-reexpansion markers. */
- while (p1 != l1)
- {
- if (is_space[l1[-1]]) l1--;
- else if (l1[-1] == '@')
- {
- U_CHAR *p2 = l1 - 1;
- /* If whitespace is preceded by an odd number
- of `@' signs, the last `@' was a whitespace
- marker; drop it too. */
- while (p2 != p1 && p2[0] == '@') p2--;
- if ((l1 - p2) & 1)
- l1--;
- break;
- }
- else if (l1[-1] == '-')
- {
- U_CHAR *p2 = l1 - 1;
- /* If a `-' is preceded by an odd number of
- `@' signs then it and the last `@' are
- a no-reexpansion marker. */
- while (p2 != p1 && p2[0] == '@') p2--;
- if ((l1 - p2) & 1)
- l1 -= 2;
- else
- break;
- }
- else break;
- }
- }
-
- /* Delete any no-reexpansion marker that precedes
- an identifier at the beginning of the argument. */
- if (p1[0] == '@' && p1[1] == '-')
- p1 += 2;
-
- bcopy (p1, xbuf + totlen, l1 - p1);
- totlen += l1 - p1;
- }
- else
- {
- U_CHAR *expanded = ARG_BASE + arg->expanded;
- if (!ap->raw_before && totlen > 0 && arg->expand_length
- && !CPP_TRADITIONAL(pfile)
- && unsafe_chars (xbuf[totlen-1], expanded[0]))
- {
- xbuf[totlen++] = '@';
- xbuf[totlen++] = ' ';
- }
-
- bcopy (expanded, xbuf + totlen, arg->expand_length);
- totlen += arg->expand_length;
-
- if (!ap->raw_after && totlen > 0 && offset < defn->length
- && !CPP_TRADITIONAL(pfile)
- && unsafe_chars (xbuf[totlen-1], exp[offset]))
- {
- xbuf[totlen++] = '@';
- xbuf[totlen++] = ' ';
- }
-
- /* If a macro argument with newlines is used multiple times,
- then only expand the newlines once. This avoids creating
- output lines which don't correspond to any input line,
- which confuses gdb and gcov. */
- if (arg->use_count > 1 && arg->newlines > 0)
- {
- /* Don't bother doing change_newlines for subsequent
- uses of arg. */
- arg->use_count = 1;
- arg->expand_length
- = change_newlines (expanded, arg->expand_length);
- }
- }
-
- if (totlen > xbuf_len)
- abort ();
- }
-
- /* if there is anything left of the definition
- after handling the arg list, copy that in too. */
-
- for (i = offset; i < defn->length; i++)
- {
- /* if we've reached the end of the macro */
- if (exp[i] == ')')
- rest_zero = 0;
- if (! (rest_zero && last_ap != NULL && last_ap->rest_args
- && last_ap->raw_after))
- xbuf[totlen++] = exp[i];
- }
-
- xbuf[totlen] = 0;
- xbuf_len = totlen;
-
- }
-
- pfile->output_escapes--;
-
- /* Now put the expansion on the input stack
- so our caller will commence reading from it. */
- push_macro_expansion (pfile, xbuf, xbuf_len, hp);
- CPP_BUFFER (pfile)->has_escapes = 1;
-
- /* Pop the space we've used in the token_buffer for argument expansion. */
- CPP_SET_WRITTEN (pfile, old_written);
-
- /* Recursive macro use sometimes works traditionally.
- #define foo(x,y) bar (x (y,0), y)
- foo (foo, baz) */
-
- if (!CPP_TRADITIONAL (pfile))
- hp->type = T_DISABLED;
-}
-
-static void
-push_macro_expansion (pfile, xbuf, xbuf_len, hp)
- cpp_reader *pfile;
- register U_CHAR *xbuf;
- int xbuf_len;
- HASHNODE *hp;
-{
- register cpp_buffer *mbuf = cpp_push_buffer (pfile, xbuf, xbuf_len);
- if (mbuf == NULL)
- return;
- mbuf->cleanup = macro_cleanup;
- mbuf->data = hp;
-
- /* The first chars of the expansion should be a "@ " added by
- collect_expansion. This is to prevent accidental token-pasting
- between the text preceding the macro invocation, and the macro
- expansion text.
-
- We would like to avoid adding unneeded spaces (for the sake of
- tools that use cpp, such as imake). In some common cases we can
- tell that it is safe to omit the space.
-
- The character before the macro invocation cannot have been an
- idchar (or else it would have been pasted with the idchars of
- the macro name). Therefore, if the first non-space character
- of the expansion is an idchar, we do not need the extra space
- to prevent token pasting.
-
- Also, we don't need the extra space if the first char is '(',
- or some other (less common) characters. */
-
- if (xbuf[0] == '@' && xbuf[1] == ' '
- && (is_idchar[xbuf[2]] || xbuf[2] == '(' || xbuf[2] == '\''
- || xbuf[2] == '\"'))
- mbuf->cur += 2;
-}
-
/* Like cpp_get_token, except that it does not read past end-of-line.
Also, horizontal space is skipped, and macros are popped. */
@@ -3069,36 +997,27 @@ get_directive_token (pfile)
This is safe. */
static int
-do_include (pfile, keyword, unused1, unused2)
+do_include (pfile, keyword)
cpp_reader *pfile;
struct directive *keyword;
- U_CHAR *unused1 ATTRIBUTE_UNUSED, *unused2 ATTRIBUTE_UNUSED;
{
int importing = (keyword->type == T_IMPORT);
int skip_dirs = (keyword->type == T_INCLUDE_NEXT);
- char *fname; /* Dynamically allocated fname buffer */
- char *pcftry;
- U_CHAR *fbeg, *fend; /* Beginning and end of fname */
+ int angle_brackets = 0; /* 0 for "...", 1 for <...> */
+ int before; /* included before? */
+ long flen;
+ unsigned char *fbeg, *fend;
+ cpp_buffer *fp;
+
enum cpp_token token;
/* Chain of dirs to search */
- struct file_name_list *search_start = CPP_OPTIONS (pfile)->include;
- struct file_name_list dsp[1]; /* First in chain, if #include "..." */
- struct file_name_list *searchptr = 0;
+ struct include_hash *ihash;
+ struct file_name_list *search_start;
+
long old_written = CPP_WRITTEN (pfile);
- int flen;
-
- int f; /* file number */
-
- int angle_brackets = 0; /* 0 for "...", 1 for <...> */
- char *pcfbuf;
-#if 0
- int pcf = -1;
- char *pcfbuflimit;
-#endif
- int pcfnum;
- f= -1; /* JF we iz paranoid! */
+ int fd;
if (CPP_PEDANTIC (pfile) && !CPP_BUFFER (pfile)->system_header_p)
{
@@ -3113,17 +1032,7 @@ do_include (pfile, keyword, unused1, unused2)
&& !CPP_BUFFER (pfile)->system_header_p && !pfile->import_warning)
{
pfile->import_warning = 1;
- cpp_warning (pfile, "using `#import' is not recommended");
- fprintf (stderr, "The fact that a certain header file need not be processed more than once\n");
- fprintf (stderr, "should be indicated in the header file, not where it is used.\n");
- fprintf (stderr, "The best way to do this is with a conditional of this form:\n\n");
- fprintf (stderr, " #ifndef _FOO_H_INCLUDED\n");
- fprintf (stderr, " #define _FOO_H_INCLUDED\n");
- fprintf (stderr, " ... <real contents of file> ...\n");
- fprintf (stderr, " #endif /* Not _FOO_H_INCLUDED */\n\n");
- fprintf (stderr, "Then users can use `#include' any number of times.\n");
- fprintf (stderr, "GNU C automatically avoids processing the file more than once\n");
- fprintf (stderr, "when it is equipped with such a conditional.\n");
+ cpp_warning (pfile, "`#import' is obsolete, use an #ifndef wrapper in the header file");
}
pfile->parsing_include_directive++;
@@ -3132,75 +1041,26 @@ do_include (pfile, keyword, unused1, unused2)
if (token == CPP_STRING)
{
- /* FIXME - check no trailing garbage */
fbeg = pfile->token_buffer + old_written + 1;
fend = CPP_PWRITTEN (pfile) - 1;
+ *fend = '\0';
if (fbeg[-1] == '<')
- {
angle_brackets = 1;
- /* If -I-, start with the first -I dir after the -I-. */
- if (CPP_OPTIONS (pfile)->first_bracket_include)
- search_start = CPP_OPTIONS (pfile)->first_bracket_include;
- }
- /* If -I- was specified, don't search current dir, only spec'd ones. */
- else if (! CPP_OPTIONS (pfile)->ignore_srcdir)
- {
- cpp_buffer *fp = CPP_BUFFER (pfile);
- /* We have "filename". Figure out directory this source
- file is coming from and put it on the front of the list. */
-
- for ( ; fp != CPP_NULL_BUFFER (pfile); fp = CPP_PREV_BUFFER (fp))
- {
- int n;
- char *ep,*nam;
-
- if ((nam = fp->nominal_fname) != NULL)
- {
- /* Found a named file. Figure out dir of the file,
- and put it in front of the search list. */
- dsp[0].next = search_start;
- search_start = dsp;
-#ifndef VMS
- ep = rindex (nam, '/');
-#else /* VMS */
- ep = rindex (nam, ']');
- if (ep == NULL) ep = rindex (nam, '>');
- if (ep == NULL) ep = rindex (nam, ':');
- if (ep != NULL) ep++;
-#endif /* VMS */
- if (ep != NULL)
- {
- n = ep - nam;
- dsp[0].fname = (char *) alloca (n + 1);
- strncpy (dsp[0].fname, nam, n);
- dsp[0].fname[n] = '\0';
- if (n + INCLUDE_LEN_FUDGE > pfile->max_include_len)
- pfile->max_include_len = n + INCLUDE_LEN_FUDGE;
- }
- else
- {
- dsp[0].fname = 0; /* Current directory */
- }
- dsp[0].got_name_map = 0;
- break;
- }
- }
- }
}
#ifdef VMS
else if (token == CPP_NAME)
{
- /*
- * Support '#include xyz' like VAX-C to allow for easy use of all the
- * decwindow include files. It defaults to '#include <xyz.h>' (so the
- * code from case '<' is repeated here) and generates a warning.
- */
+ /* Support '#include xyz' like VAX-C to allow for easy use of
+ * all the decwindow include files. It defaults to '#include
+ * <xyz.h>' and generates a warning. */
cpp_warning (pfile,
"VAX-C-style include specification found, use '#include <filename.h>' !");
angle_brackets = 1;
- /* If -I-, start with the first -I dir after the -I-. */
- if (CPP_OPTIONS (pfile)->first_bracket_include)
- search_start = CPP_OPTIONS (pfile)->first_bracket_include;
+
+ /* Append the missing `.h' to the name. */
+ CPP_PUTS (pfile, ".h", 3)
+ CPP_NUL_TERMINATE_Q (pfile);
+
fbeg = pfile->token_buffer + old_written;
fend = CPP_PWRITTEN (pfile);
}
@@ -3214,32 +1074,11 @@ do_include (pfile, keyword, unused1, unused2)
return 0;
}
- *fend = 0;
-
token = get_directive_token (pfile);
if (token != CPP_VSPACE)
{
cpp_error (pfile, "junk at end of `#include'");
- while (token != CPP_VSPACE && token != CPP_EOF && token != CPP_POP)
- token = get_directive_token (pfile);
- }
-
- /* For #include_next, skip in the search path
- past the dir in which the containing file was found. */
- if (skip_dirs)
- {
- cpp_buffer *fp = CPP_BUFFER (pfile);
- for (; fp != CPP_NULL_BUFFER (pfile); fp = CPP_PREV_BUFFER (fp))
- if (fp->fname != NULL)
- {
- /* fp->dir is null if the containing file was specified with
- an absolute file name. In that case, don't skip anything. */
- if (fp->dir == SELF_DIR_DUMMY)
- search_start = CPP_OPTIONS (pfile)->include;
- else if (fp->dir)
- search_start = fp->dir->next;
- break;
- }
+ skip_rest_of_line (pfile);
}
CPP_SET_WRITTEN (pfile, old_written);
@@ -3252,586 +1091,310 @@ do_include (pfile, keyword, unused1, unused2)
return 0;
}
- /* Allocate this permanently, because it gets stored in the definitions
- of macros. */
- fname = (char *) xmalloc (pfile->max_include_len + flen + 4);
- /* + 2 above for slash and terminating null. */
- /* + 2 added for '.h' on VMS (to support '#include filename') */
+ search_start = 0;
- /* If specified file name is absolute, just open it. */
+ for (fp = CPP_BUFFER (pfile);
+ fp != CPP_NULL_BUFFER (pfile);
+ fp = CPP_PREV_BUFFER (fp))
+ if (fp->fname != NULL)
+ break;
- if (*fbeg == '/') {
- strncpy (fname, fbeg, flen);
- fname[flen] = 0;
- if (redundant_include_p (pfile, fname))
- return 0;
- if (importing)
- f = lookup_import (pfile, fname, NULL_PTR);
- else
- f = open_include_file (pfile, fname, NULL_PTR);
- if (f == -2)
- return 0; /* Already included this file */
- } else {
- /* Search directory path, trying to open the file.
- Copy each filename tried into FNAME. */
-
- for (searchptr = search_start; searchptr; searchptr = searchptr->next) {
- if (searchptr->fname) {
- /* The empty string in a search path is ignored.
- This makes it possible to turn off entirely
- a standard piece of the list. */
- if (searchptr->fname[0] == 0)
- continue;
- strcpy (fname, searchptr->fname);
- strcat (fname, "/");
- fname[strlen (fname) + flen] = 0;
- } else {
- fname[0] = 0;
- }
- strncat (fname, fbeg, flen);
-#ifdef VMS
- /* Change this 1/2 Unix 1/2 VMS file specification into a
- full VMS file specification */
- if (searchptr->fname && (searchptr->fname[0] != 0)) {
- /* Fix up the filename */
- hack_vms_include_specification (fname);
- } else {
- /* This is a normal VMS filespec, so use it unchanged. */
- strncpy (fname, fbeg, flen);
- fname[flen] = 0;
- /* if it's '#include filename', add the missing .h */
- if (index(fname,'.')==NULL) {
- strcat (fname, ".h");
- }
- }
-#endif /* VMS */
- /* ??? There are currently 3 separate mechanisms for avoiding processing
- of redundant include files: #import, #pragma once, and
- redundant_include_p. It would be nice if they were unified. */
- if (redundant_include_p (pfile, fname))
- return 0;
- if (importing)
- f = lookup_import (pfile, fname, searchptr);
- else
- f = open_include_file (pfile, fname, searchptr);
- if (f == -2)
- return 0; /* Already included this file */
-#ifdef EACCES
- else if (f == -1 && errno == EACCES)
- cpp_warning (pfile, "Header file %s exists, but is not readable",
- fname);
-#endif
- if (f >= 0)
- break;
+ if (fp == CPP_NULL_BUFFER (pfile))
+ {
+ cpp_fatal (pfile, "cpp internal error: fp == NULL_BUFFER in do_include");
+ return 1;
}
- }
-
- if (f < 0)
+
+ /* For #include_next, skip in the search path past the dir in which the
+ containing file was found. Treat files specified using an absolute path
+ as if there are no more directories to search. Treat the primary source
+ file like any other included source, but generate a warning. */
+ if (skip_dirs && CPP_PREV_BUFFER(fp) != CPP_NULL_BUFFER (pfile))
{
- /* A file that was not found. */
- strncpy (fname, fbeg, flen);
- fname[flen] = 0;
- /* If generating dependencies and -MG was specified, we assume missing
- files are leaf files, living in the same directory as the source file
- or other similar place; these missing files may be generated from
- other files and may not exist yet (eg: y.tab.h). */
-
- if (CPP_OPTIONS(pfile)->print_deps_missing_files
- && CPP_PRINT_DEPS (pfile)
- > (angle_brackets || (pfile->system_include_depth > 0)))
- {
- /* If it was requested as a system header file,
- then assume it belongs in the first place to look for such. */
- if (angle_brackets)
+ if (fp->ihash->foundhere != ABSOLUTE_PATH)
+ search_start = fp->ihash->foundhere->next;
+ }
+ else
+ {
+ if (skip_dirs)
+ cpp_warning (pfile, "#include_next in primary source file");
+
+ if (angle_brackets)
+ search_start = CPP_OPTIONS (pfile)->bracket_include;
+ else
+ {
+ if (!CPP_OPTIONS (pfile)->ignore_srcdir)
{
- for (searchptr = search_start; searchptr;
- searchptr = searchptr->next)
- {
- if (searchptr->fname)
- {
- char *p;
-
- if (searchptr->fname[0] == 0)
- continue;
- p = (char *) alloca (strlen (searchptr->fname)
- + strlen (fname) + 2);
- strcpy (p, searchptr->fname);
- strcat (p, "/");
- strcat (p, fname);
- deps_output (pfile, p, ' ');
- break;
- }
- }
+ if (fp)
+ search_start = fp->actual_dir;
}
else
- {
- /* Otherwise, omit the directory, as if the file existed
- in the directory with the source. */
- deps_output (pfile, fname, ' ');
- }
+ search_start = CPP_OPTIONS (pfile)->quote_include;
}
- /* If -M was specified, and this header file won't be added to the
- dependency list, then don't count this as an error, because we can
- still produce correct output. Otherwise, we can't produce correct
- output, because there may be dependencies we need inside the missing
- file, and we don't know what directory this missing file exists in.*/
- else if (CPP_PRINT_DEPS (pfile)
- && (CPP_PRINT_DEPS (pfile)
- <= (angle_brackets || (pfile->system_include_depth > 0))))
- cpp_warning (pfile, "No include path in which to find %s", fname);
- else if (search_start)
- cpp_error_from_errno (pfile, fname);
- else
- cpp_error (pfile, "No include path in which to find %s", fname);
- }
- else {
- /* Check to see if this include file is a once-only include file.
- If so, give up. */
-
- struct file_name_list *ptr;
-
- for (ptr = pfile->dont_repeat_files; ptr; ptr = ptr->next) {
- if (!strcmp (ptr->fname, fname)) {
- close (f);
- return 0; /* This file was once'd. */
- }
}
- for (ptr = pfile->all_include_files; ptr; ptr = ptr->next) {
- if (!strcmp (ptr->fname, fname))
- break; /* This file was included before. */
+ if (!search_start)
+ {
+ cpp_error (pfile, "No include path in which to find %s", fbeg);
+ return 0;
}
- if (ptr == 0) {
- /* This is the first time for this file. */
- /* Add it to list of files included. */
-
- ptr = (struct file_name_list *) xmalloc (sizeof (struct file_name_list));
- ptr->control_macro = 0;
- ptr->c_system_include_path = 0;
- ptr->next = pfile->all_include_files;
- pfile->all_include_files = ptr;
- ptr->fname = savestring (fname);
- ptr->got_name_map = 0;
-
- /* For -M, add this file to the dependencies. */
- if (CPP_PRINT_DEPS (pfile)
- > (angle_brackets || (pfile->system_include_depth > 0)))
- deps_output (pfile, fname, ' ');
- }
-
- /* Handle -H option. */
- if (CPP_OPTIONS(pfile)->print_include_names)
- {
- cpp_buffer *buf = CPP_BUFFER (pfile);
- while ((buf = CPP_PREV_BUFFER (buf)) != CPP_NULL_BUFFER (pfile))
- putc ('.', stderr);
- fprintf (stderr, "%s\n", fname);
- }
-
- if (angle_brackets)
- pfile->system_include_depth++;
-
- /* Actually process the file. */
-
- /* Record file on "seen" list for #import. */
- add_import (pfile, f, fname);
+ fd = find_include_file (pfile, fbeg, search_start, &ihash, &before);
- pcftry = (char *) alloca (strlen (fname) + 30);
- pcfbuf = 0;
- pcfnum = 0;
-
-#if 0
- if (!no_precomp)
- {
- struct stat stat_f;
-
- fstat (f, &stat_f);
-
- do {
- sprintf (pcftry, "%s%d", fname, pcfnum++);
-
- pcf = open (pcftry, O_RDONLY, 0666);
- if (pcf != -1)
+ if (fd == -2)
+ return 0;
+
+ if (fd == -1)
+ {
+ if (CPP_OPTIONS (pfile)->print_deps_missing_files
+ && CPP_PRINT_DEPS (pfile) > (angle_brackets ||
+ (pfile->system_include_depth > 0)))
+ {
+ if (!angle_brackets)
+ deps_output (pfile, fbeg, ' ');
+ else
{
- struct stat s;
-
- fstat (pcf, &s);
- if (bcmp ((char *) &stat_f.st_ino, (char *) &s.st_ino,
- sizeof (s.st_ino))
- || stat_f.st_dev != s.st_dev)
- {
- pcfbuf = check_precompiled (pcf, fname, &pcfbuflimit);
- /* Don't need it any more. */
- close (pcf);
- }
+ char *p;
+ struct file_name_list *ptr;
+ /* If requested as a system header, assume it belongs in
+ the first system header directory. */
+ if (CPP_OPTIONS (pfile)->bracket_include)
+ ptr = CPP_OPTIONS (pfile)->bracket_include;
else
- {
- /* Don't need it at all. */
- close (pcf);
- break;
- }
- }
- } while (pcf != -1 && !pcfbuf);
- }
-#endif
-
- /* Actually process the file */
- if (cpp_push_buffer (pfile, NULL, 0) == NULL)
- return 0;
- if (finclude (pfile, f, fname, is_system_include (pfile, fname),
- searchptr != dsp ? searchptr : SELF_DIR_DUMMY))
- {
- output_line_command (pfile, 0, enter_file);
- pfile->only_seen_white = 2;
- }
-
- if (angle_brackets)
- pfile->system_include_depth--;
- }
- return 0;
-}
-
-/* Return nonzero if there is no need to include file NAME
- because it has already been included and it contains a conditional
- to make a repeated include do nothing. */
-
-static int
-redundant_include_p (pfile, name)
- cpp_reader *pfile;
- char *name;
-{
- struct file_name_list *l = pfile->all_include_files;
- for (; l; l = l->next)
- if (! strcmp (name, l->fname)
- && l->control_macro
- && cpp_lookup (pfile, l->control_macro, -1, -1))
- return 1;
- return 0;
-}
-
-/* Return nonzero if the given FILENAME is an absolute pathname which
- designates a file within one of the known "system" include file
- directories. We assume here that if the given FILENAME looks like
- it is the name of a file which resides either directly in a "system"
- include file directory, or within any subdirectory thereof, then the
- given file must be a "system" include file. This function tells us
- if we should suppress pedantic errors/warnings for the given FILENAME.
+ ptr = CPP_OPTIONS (pfile)->quote_include;
- The value is 2 if the file is a C-language system header file
- for which C++ should (on most systems) assume `extern "C"'. */
-
-static int
-is_system_include (pfile, filename)
- cpp_reader *pfile;
- register char *filename;
-{
- struct file_name_list *searchptr;
-
- for (searchptr = CPP_OPTIONS (pfile)->first_system_include; searchptr;
- searchptr = searchptr->next)
- if (searchptr->fname) {
- register char *sys_dir = searchptr->fname;
- register unsigned length = strlen (sys_dir);
-
- if (! strncmp (sys_dir, filename, length) && filename[length] == '/')
- {
- if (searchptr->c_system_include_path)
- return 2;
- else
- return 1;
+ p = (char *) alloca (strlen (ptr->name)
+ + strlen (fbeg) + 2);
+ if (*ptr->name != '\0')
+ {
+ strcpy (p, ptr->name);
+ strcat (p, "/");
+ }
+ strcat (p, fbeg);
+ deps_output (pfile, p, ' ');
+ }
}
- }
- return 0;
-}
-
-
-/*
- * Install a name in the assertion hash table.
- *
- * If LEN is >= 0, it is the length of the name.
- * Otherwise, compute the length by scanning the entire name.
- *
- * If HASH is >= 0, it is the precomputed hash code.
- * Otherwise, compute the hash code.
- */
+ /* If -M was specified, and this header file won't be added to
+ the dependency list, then don't count this as an error,
+ because we can still produce correct output. Otherwise, we
+ can't produce correct output, because there may be
+ dependencies we need inside the missing file, and we don't
+ know what directory this missing file exists in. */
+ else if (CPP_PRINT_DEPS (pfile)
+ && (CPP_PRINT_DEPS (pfile)
+ <= (angle_brackets || (pfile->system_include_depth > 0))))
+ cpp_warning (pfile, "No include path in which to find %s", fbeg);
+ else
+ cpp_error_from_errno (pfile, fbeg);
-static ASSERTION_HASHNODE *
-assertion_install (pfile, name, len, hash)
- cpp_reader *pfile;
- U_CHAR *name;
- int len;
- int hash;
-{
- register ASSERTION_HASHNODE *hp;
- register int i, bucket;
- register U_CHAR *p, *q;
-
- i = sizeof (ASSERTION_HASHNODE) + len + 1;
- hp = (ASSERTION_HASHNODE *) xmalloc (i);
- bucket = hash;
- hp->bucket_hdr = &pfile->assertion_hashtab[bucket];
- hp->next = pfile->assertion_hashtab[bucket];
- pfile->assertion_hashtab[bucket] = hp;
- hp->prev = NULL;
- if (hp->next != NULL)
- hp->next->prev = hp;
- hp->length = len;
- hp->value = 0;
- hp->name = ((U_CHAR *) hp) + sizeof (ASSERTION_HASHNODE);
- p = hp->name;
- q = name;
- for (i = 0; i < len; i++)
- *p++ = *q++;
- hp->name[len] = 0;
- return hp;
-}
-/*
- * find the most recent hash node for name "name" (ending with first
- * non-identifier char) installed by install
- *
- * If LEN is >= 0, it is the length of the name.
- * Otherwise, compute the length by scanning the entire name.
- *
- * If HASH is >= 0, it is the precomputed hash code.
- * Otherwise, compute the hash code.
- */
+ return 0;
+ }
-static ASSERTION_HASHNODE *
-assertion_lookup (pfile, name, len, hash)
- cpp_reader *pfile;
- U_CHAR *name;
- int len;
- int hash;
-{
- register ASSERTION_HASHNODE *bucket;
+ /* For -M, add the file to the dependencies on its first inclusion. */
+ if (!before && (CPP_PRINT_DEPS (pfile)
+ > (angle_brackets || (pfile->system_include_depth > 0))))
+ deps_output (pfile, ihash->name, ' ');
- bucket = pfile->assertion_hashtab[hash];
- while (bucket) {
- if (bucket->length == len && strncmp (bucket->name, name, len) == 0)
- return bucket;
- bucket = bucket->next;
- }
- return NULL;
-}
+ /* Handle -H option. */
+ if (CPP_OPTIONS(pfile)->print_include_names)
+ {
+ fp = CPP_BUFFER (pfile);
+ while ((fp = CPP_PREV_BUFFER (fp)) != CPP_NULL_BUFFER (pfile))
+ putc ('.', stderr);
+ fprintf (stderr, " %s\n", ihash->name);
+ }
-static void
-delete_assertion (hp)
- ASSERTION_HASHNODE *hp;
-{
- struct tokenlist_list *tail;
- if (hp->prev != NULL)
- hp->prev->next = hp->next;
- if (hp->next != NULL)
- hp->next->prev = hp->prev;
+ /* Actually process the file */
- for (tail = hp->value; tail; )
+ if (importing)
+ ihash->control_macro = "";
+
+ if (cpp_push_buffer (pfile, NULL, 0) == NULL)
{
- struct tokenlist_list *next = tail->next;
- free_token_list (tail->tokens);
- free (tail);
- tail = next;
+ close (fd);
+ return 0;
}
+
+ if (angle_brackets)
+ pfile->system_include_depth++; /* Decremented in file_cleanup. */
- /* Make sure that the bucket chain header that
- the deleted guy was on points to the right thing afterwards. */
- if (hp == *hp->bucket_hdr)
- *hp->bucket_hdr = hp->next;
-
- free (hp);
-}
-
-/* Convert a character string literal into a nul-terminated string.
- The input string is [IN ... LIMIT).
- The result is placed in RESULT. RESULT can be the same as IN.
- The value returned in the end of the string written to RESULT,
- or NULL on error. */
-
-static U_CHAR *
-convert_string (pfile, result, in, limit, handle_escapes)
- cpp_reader *pfile;
- register U_CHAR *result, *in, *limit;
- int handle_escapes;
-{
- U_CHAR c;
- c = *in++;
- if (c != '\"')
- return NULL;
- while (in < limit)
+ if (finclude (pfile, fd, ihash))
{
- U_CHAR c = *in++;
- switch (c)
- {
- case '\0':
- return NULL;
- case '\"':
- limit = in;
- break;
- case '\\':
- if (handle_escapes)
- {
- char *bpc = (char *) in;
- int i = (U_CHAR) cpp_parse_escape (pfile, &bpc);
- in = (U_CHAR *) bpc;
- if (i >= 0)
- *result++ = (U_CHAR)c;
- break;
- }
- /* else fall through */
- default:
- *result++ = c;
- }
+ output_line_command (pfile, 0, enter_file);
+ pfile->only_seen_white = 2;
}
- *result = 0;
- return result;
+
+ return 0;
}
-/*
- * interpret #line command. Remembers previously seen fnames
- * in its very own hash table.
- */
-#define FNAME_HASHSIZE 37
+/* Interpret #line command.
+ Note that the filename string (if any) is treated as if it were an
+ include filename. That means no escape handling. */
static int
-do_line (pfile, keyword, unused1, unused2)
+do_line (pfile, keyword)
cpp_reader *pfile;
struct directive *keyword ATTRIBUTE_UNUSED;
- U_CHAR *unused1 ATTRIBUTE_UNUSED, *unused2 ATTRIBUTE_UNUSED;
{
cpp_buffer *ip = CPP_BUFFER (pfile);
int new_lineno;
long old_written = CPP_WRITTEN (pfile);
enum file_change_code file_change = same_file;
enum cpp_token token;
+ char *x;
token = get_directive_token (pfile);
- if (token != CPP_NUMBER
- || !ISDIGIT(pfile->token_buffer[old_written]))
+ if (token != CPP_NUMBER)
{
- cpp_error (pfile, "invalid format `#line' command");
+ cpp_error (pfile, "token after `#line' is not an integer");
goto bad_line_directive;
}
- /* The Newline at the end of this line remains to be processed.
- To put the next line at the specified line number,
- we must store a line number now that is one less. */
- new_lineno = atoi ((char *)(pfile->token_buffer + old_written)) - 1;
+ new_lineno = strtol (pfile->token_buffer + old_written, &x, 10);
+ if (x[0] != '\0')
+ {
+ cpp_error (pfile, "token after `#line' is not an integer");
+ goto bad_line_directive;
+ }
CPP_SET_WRITTEN (pfile, old_written);
- /* NEW_LINENO is one less than the actual line number here. */
- if (CPP_PEDANTIC (pfile) && new_lineno < 0)
+ if (CPP_PEDANTIC (pfile) && new_lineno <= 0)
cpp_pedwarn (pfile, "line number out of range in `#line' command");
-#if 0 /* #line 10"foo.c" is supposed to be allowed. */
- if (PEEKC() && !is_space[PEEKC()]) {
- cpp_error (pfile, "invalid format `#line' command");
- goto bad_line_directive;
- }
-#endif
-
token = get_directive_token (pfile);
- if (token == CPP_STRING) {
- U_CHAR *fname = pfile->token_buffer + old_written;
- U_CHAR *end_name;
- static HASHNODE *fname_table[FNAME_HASHSIZE];
- HASHNODE *hp, **hash_bucket;
- U_CHAR *p;
- long num_start;
- int fname_length;
-
- /* Turn the file name, which is a character string literal,
- into a null-terminated string. Do this in place. */
- end_name = convert_string (pfile, fname, fname, CPP_PWRITTEN (pfile), 1);
- if (end_name == NULL)
+ if (token == CPP_STRING)
{
- cpp_error (pfile, "invalid format `#line' command");
- goto bad_line_directive;
- }
+ U_CHAR *fname = pfile->token_buffer + old_written + 1;
+ U_CHAR *end_name = CPP_PWRITTEN (pfile) - 1;
+ long num_start = CPP_WRITTEN (pfile);
- fname_length = end_name - fname;
+ token = get_directive_token (pfile);
+ if (token != CPP_VSPACE && token != CPP_EOF && token != CPP_POP)
+ {
+ U_CHAR *p = pfile->token_buffer + num_start;
+ if (CPP_PEDANTIC (pfile))
+ cpp_pedwarn (pfile, "garbage at end of `#line' command");
- num_start = CPP_WRITTEN (pfile);
- token = get_directive_token (pfile);
- if (token != CPP_VSPACE && token != CPP_EOF && token != CPP_POP) {
- p = pfile->token_buffer + num_start;
- if (CPP_PEDANTIC (pfile))
- cpp_pedwarn (pfile, "garbage at end of `#line' command");
+ if (token != CPP_NUMBER || *p < '0' || *p > '4' || p[1] != '\0')
+ {
+ cpp_error (pfile, "invalid format `#line' command");
+ goto bad_line_directive;
+ }
+ if (*p == '1')
+ file_change = enter_file;
+ else if (*p == '2')
+ file_change = leave_file;
+ else if (*p == '3')
+ ip->system_header_p = 1;
+ else /* if (*p == '4') */
+ ip->system_header_p = 2;
+
+ CPP_SET_WRITTEN (pfile, num_start);
+ token = get_directive_token (pfile);
+ p = pfile->token_buffer + num_start;
+ if (token == CPP_NUMBER && p[1] == '\0' && (*p == '3' || *p== '4'))
+ {
+ ip->system_header_p = *p == '3' ? 1 : 2;
+ token = get_directive_token (pfile);
+ }
+ if (token != CPP_VSPACE)
+ {
+ cpp_error (pfile, "invalid format `#line' command");
+ goto bad_line_directive;
+ }
+ }
+
+ *end_name = '\0';
+
+ if (strcmp (fname, ip->nominal_fname))
+ {
+ char *newname, *oldname;
+ if (!strcmp (fname, ip->fname))
+ newname = ip->fname;
+ else if (ip->last_nominal_fname
+ && !strcmp (fname, ip->last_nominal_fname))
+ newname = ip->last_nominal_fname;
+ else
+ newname = xstrdup (fname);
- if (token != CPP_NUMBER || *p < '0' || *p > '4' || p[1] != '\0')
- {
- cpp_error (pfile, "invalid format `#line' command");
- goto bad_line_directive;
- }
- if (*p == '1')
- file_change = enter_file;
- else if (*p == '2')
- file_change = leave_file;
- else if (*p == '3')
- ip->system_header_p = 1;
- else /* if (*p == '4') */
- ip->system_header_p = 2;
-
- CPP_SET_WRITTEN (pfile, num_start);
- token = get_directive_token (pfile);
- p = pfile->token_buffer + num_start;
- if (token == CPP_NUMBER && p[1] == '\0' && (*p == '3' || *p== '4')) {
- ip->system_header_p = *p == '3' ? 1 : 2;
- token = get_directive_token (pfile);
- }
- if (token != CPP_VSPACE) {
- cpp_error (pfile, "invalid format `#line' command");
- goto bad_line_directive;
- }
- }
+ oldname = ip->nominal_fname;
+ ip->nominal_fname = newname;
- hash_bucket = &fname_table[hashf (fname, fname_length, FNAME_HASHSIZE)];
- for (hp = *hash_bucket; hp != NULL; hp = hp->next)
- if (hp->length == fname_length
- && strncmp (hp->value.cpval, fname, fname_length) == 0) {
- ip->nominal_fname = hp->value.cpval;
- break;
- }
- if (hp == 0) {
- /* Didn't find it; cons up a new one. */
- hp = (HASHNODE *) xcalloc (1, sizeof (HASHNODE) + fname_length + 1);
- hp->next = *hash_bucket;
- *hash_bucket = hp;
-
- hp->length = fname_length;
- ip->nominal_fname = hp->value.cpval = ((char *) hp) + sizeof (HASHNODE);
- bcopy (fname, hp->value.cpval, fname_length);
+ if (ip->last_nominal_fname
+ && ip->last_nominal_fname != oldname
+ && ip->last_nominal_fname != newname
+ && ip->last_nominal_fname != ip->fname)
+ free (ip->last_nominal_fname);
+
+ if (newname == ip->fname)
+ ip->last_nominal_fname = NULL;
+ else
+ ip->last_nominal_fname = oldname;
+ }
+ }
+ else if (token != CPP_VSPACE && token != CPP_EOF)
+ {
+ cpp_error (pfile, "token after `#line %d' is not a string", new_lineno);
+ goto bad_line_directive;
}
- }
- else if (token != CPP_VSPACE && token != CPP_EOF) {
- cpp_error (pfile, "invalid format `#line' command");
- goto bad_line_directive;
- }
- ip->lineno = new_lineno;
+ /* The Newline at the end of this line remains to be processed.
+ To put the next line at the specified line number,
+ we must store a line number now that is one less. */
+ ip->lineno = new_lineno - 1;
+ CPP_SET_WRITTEN (pfile, old_written);
+ output_line_command (pfile, 0, file_change);
+ return 0;
+
bad_line_directive:
skip_rest_of_line (pfile);
CPP_SET_WRITTEN (pfile, old_written);
- output_line_command (pfile, 0, file_change);
return 0;
}
-/*
- * remove the definition of a symbol from the symbol table.
- * according to un*x /lib/cpp, it is not an error to undef
- * something that has no definitions, so it isn't one here either.
- */
-
+/* Remove the definition of a symbol from the symbol table.
+ According to the C standard, it is not an error to undef
+ something that has no definitions. */
static int
-do_undef (pfile, keyword, buf, limit)
+do_undef (pfile, keyword)
cpp_reader *pfile;
struct directive *keyword;
- U_CHAR *buf, *limit;
{
int sym_length;
HASHNODE *hp;
- U_CHAR *orig_buf = buf;
+ U_CHAR *buf, *name, *limit;
+ int c;
+ long here = CPP_WRITTEN (pfile);
+ enum cpp_token token;
+
+ cpp_skip_hspace (pfile);
+ c = GETC();
+ if (! is_idstart[c])
+ {
+ cpp_error (pfile, "token after #undef is not an identifier");
+ skip_rest_of_line (pfile);
+ return 1;
+ }
+
+ parse_name (pfile, c);
+ buf = pfile->token_buffer + here;
+ limit = CPP_PWRITTEN(pfile);
+
+ /* Copy out the token so we can pop the token buffer. */
+ name = alloca (limit - buf + 1);
+ bcopy(buf, name, limit - buf);
+ name[limit - buf] = '\0';
+
+ token = get_directive_token (pfile);
+ if (token != CPP_VSPACE && token != CPP_POP)
+ {
+ cpp_pedwarn (pfile, "junk on line after #undef");
+ skip_rest_of_line (pfile);
+ }
+
+ CPP_SET_WRITTEN (pfile, here);
#if 0
/* If this is a precompiler run (with -pcp) pass thru #undef commands. */
@@ -3839,28 +1402,35 @@ do_undef (pfile, keyword, buf, limit)
pass_thru_directive (buf, limit, pfile, keyword);
#endif
- SKIP_WHITE_SPACE (buf);
- sym_length = check_macro_name (pfile, buf, "macro");
+ sym_length = check_macro_name (pfile, buf, 0);
- while ((hp = cpp_lookup (pfile, buf, sym_length, -1)) != NULL)
+ while ((hp = cpp_lookup (pfile, name, sym_length, -1)) != NULL)
{
/* If we are generating additional info for debugging (with -g) we
need to pass through all effective #undef commands. */
if (CPP_OPTIONS (pfile)->debug_output && keyword)
- pass_thru_directive (orig_buf, limit, pfile, keyword);
+ pass_thru_directive (name, name+sym_length, pfile, keyword);
if (hp->type != T_MACRO)
cpp_warning (pfile, "undefining `%s'", hp->name);
delete_macro (hp);
}
- if (CPP_PEDANTIC (pfile)) {
- buf += sym_length;
- SKIP_WHITE_SPACE (buf);
- if (buf != limit)
- cpp_pedwarn (pfile, "garbage after `#undef' directive");
- }
return 0;
}
+
+/* Wrap do_undef for -U processing. */
+void
+cpp_undef (pfile, macro)
+ cpp_reader *pfile;
+ U_CHAR *macro;
+{
+ if (cpp_push_buffer (pfile, macro, strlen (macro)))
+ {
+ do_undef (pfile, NULL);
+ cpp_pop_buffer (pfile);
+ }
+}
+
/*
* Report an error detected by the program we are processing.
@@ -3869,182 +1439,139 @@ do_undef (pfile, keyword, buf, limit)
*/
static int
-do_error (pfile, keyword, buf, limit)
+do_error (pfile, keyword)
cpp_reader *pfile;
struct directive *keyword ATTRIBUTE_UNUSED;
- U_CHAR *buf, *limit;
{
- int length = limit - buf;
- U_CHAR *copy = (U_CHAR *) alloca (length + 1);
- bcopy (buf, copy, length);
- copy[length] = 0;
- SKIP_WHITE_SPACE (copy);
- cpp_error (pfile, "#error %s", copy);
+ long here = CPP_WRITTEN (pfile);
+ U_CHAR *text;
+ copy_rest_of_line (pfile);
+ text = pfile->token_buffer + here;
+ SKIP_WHITE_SPACE(text);
+
+ cpp_error (pfile, "#error %s", text);
+ CPP_SET_WRITTEN (pfile, here);
return 0;
}
/*
* Report a warning detected by the program we are processing.
* Use the text of the line in the warning message, then continue.
- * (We use error because it prints the filename & line#.)
*/
static int
-do_warning (pfile, keyword, buf, limit)
+do_warning (pfile, keyword)
cpp_reader *pfile;
struct directive *keyword ATTRIBUTE_UNUSED;
- U_CHAR *buf, *limit;
{
- int length = limit - buf;
- U_CHAR *copy = (U_CHAR *) alloca (length + 1);
- bcopy (buf, copy, length);
- copy[length] = 0;
- SKIP_WHITE_SPACE (copy);
+ U_CHAR *text;
+ long here = CPP_WRITTEN(pfile);
+ copy_rest_of_line (pfile);
+ text = pfile->token_buffer + here;
+ SKIP_WHITE_SPACE(text);
if (CPP_PEDANTIC (pfile) && !CPP_BUFFER (pfile)->system_header_p)
cpp_pedwarn (pfile, "ANSI C does not allow `#warning'");
/* Use `pedwarn' not `warning', because #warning isn't in the C Standard;
if -pedantic-errors is given, #warning should cause an error. */
- cpp_pedwarn (pfile, "#warning %s", copy);
- return 0;
-}
-
-/* Remember the name of the current file being read from so that we can
- avoid ever including it again. */
-
-static int
-do_once (pfile, keyword, unused1, unused2)
- cpp_reader *pfile;
- struct directive *keyword ATTRIBUTE_UNUSED;
- U_CHAR *unused1 ATTRIBUTE_UNUSED, *unused2 ATTRIBUTE_UNUSED;
-{
- cpp_buffer *ip = NULL;
- struct file_name_list *new;
-
- for (ip = CPP_BUFFER (pfile); ; ip = CPP_PREV_BUFFER (ip))
- {
- if (ip == CPP_NULL_BUFFER (pfile))
- return 0;
- if (ip->fname != NULL)
- break;
- }
-
-
- new = (struct file_name_list *) xmalloc (sizeof (struct file_name_list));
- new->next = pfile->dont_repeat_files;
- pfile->dont_repeat_files = new;
- new->fname = savestring (ip->fname);
- new->control_macro = 0;
- new->got_name_map = 0;
- new->c_system_include_path = 0;
-
+ cpp_pedwarn (pfile, "#warning %s", text);
+ CPP_SET_WRITTEN (pfile, here);
return 0;
}
/* Report program identification. */
static int
-do_ident (pfile, keyword, buf, limit)
+do_ident (pfile, keyword)
cpp_reader *pfile;
struct directive *keyword ATTRIBUTE_UNUSED;
- U_CHAR *buf ATTRIBUTE_UNUSED, *limit ATTRIBUTE_UNUSED;
{
-/* long old_written = CPP_WRITTEN (pfile);*/
-
/* Allow #ident in system headers, since that's not user's fault. */
if (CPP_PEDANTIC (pfile) && !CPP_BUFFER (pfile)->system_header_p)
cpp_pedwarn (pfile, "ANSI C does not allow `#ident'");
- /* Leave rest of line to be read by later calls to cpp_get_token. */
+ skip_rest_of_line (pfile); /* Correct? Appears to match cccp. */
return 0;
}
-/* #pragma and its argument line have already been copied to the output file.
- Just check for some recognized pragmas that need validation here. */
+/* Just check for some recognized pragmas that need validation here,
+ and leave the text in the token buffer to be output. */
static int
-do_pragma (pfile, keyword, buf, limit)
+do_pragma (pfile, keyword)
cpp_reader *pfile;
struct directive *keyword ATTRIBUTE_UNUSED;
- U_CHAR *buf, *limit ATTRIBUTE_UNUSED;
{
- while (*buf == ' ' || *buf == '\t')
- buf++;
- if (!strncmp (buf, "once", 4)) {
- /* Allow #pragma once in system headers, since that's not the user's
- fault. */
- if (!CPP_BUFFER (pfile)->system_header_p)
- cpp_warning (pfile, "`#pragma once' is obsolete");
- do_once (pfile, NULL, NULL, NULL);
- }
+ long here = CPP_WRITTEN (pfile);
+ U_CHAR *buf;
+
+ copy_rest_of_line (pfile);
+ buf = pfile->token_buffer + here;
+ SKIP_WHITE_SPACE (buf);
+
+ if (!strncmp (buf, "once", 4))
+ {
+ cpp_buffer *ip = NULL;
- if (!strncmp (buf, "implementation", 14)) {
- /* Be quiet about `#pragma implementation' for a file only if it hasn't
- been included yet. */
- struct file_name_list *ptr;
- U_CHAR *p = buf + 14, *fname, *inc_fname;
- int fname_len;
- SKIP_WHITE_SPACE (p);
- if (*p == '\n' || *p != '\"')
- return 0;
+ /* Allow #pragma once in system headers, since that's not the user's
+ fault. */
+ if (!CPP_BUFFER (pfile)->system_header_p)
+ cpp_warning (pfile, "`#pragma once' is obsolete");
+
+ for (ip = CPP_BUFFER (pfile); ; ip = CPP_PREV_BUFFER (ip))
+ {
+ if (ip == CPP_NULL_BUFFER (pfile))
+ return 0;
+ if (ip->fname != NULL)
+ break;
+ }
- fname = p + 1;
- p = (U_CHAR *) index (fname, '\"');
- fname_len = p != NULL ? p - fname : strlen (fname);
-
- for (ptr = pfile->all_include_files; ptr; ptr = ptr->next) {
- inc_fname = (U_CHAR *) rindex (ptr->fname, '/');
- inc_fname = inc_fname ? inc_fname + 1 : (U_CHAR *) ptr->fname;
- if (inc_fname && !strncmp (inc_fname, fname, fname_len))
- cpp_warning (pfile,
- "`#pragma implementation' for `%s' appears after file is included",
- fname);
+ if (CPP_PREV_BUFFER (ip) == CPP_NULL_BUFFER (pfile))
+ cpp_warning (pfile, "`#pragma once' outside include file");
+ else
+ ip->ihash->control_macro = ""; /* never repeat */
}
- }
- return 0;
-}
+ if (!strncmp (buf, "implementation", 14))
+ {
+ /* Be quiet about `#pragma implementation' for a file only if it hasn't
+ been included yet. */
+ struct include_hash *ptr;
+ U_CHAR *p = buf + 14, *fname, *fcopy;
+ SKIP_WHITE_SPACE (p);
+ if (*p == '\n' || *p != '\"')
+ return 0;
-#if 0
-/* This was a fun hack, but #pragma seems to start to be useful.
- By failing to recognize it, we pass it through unchanged to cc1. */
+ fname = p + 1;
+ p = (U_CHAR *) index (fname, '\"');
-/*
- * the behavior of the #pragma directive is implementation defined.
- * this implementation defines it as follows.
- */
+ fcopy = alloca (p - fname + 1);
+ bcopy (fname, fcopy, p - fname);
+ fcopy[p-fname] = '\0';
-static int
-do_pragma ()
-{
- close (0);
- if (open ("/dev/tty", O_RDONLY, 0666) != 0)
- goto nope;
- close (1);
- if (open ("/dev/tty", O_WRONLY, 0666) != 1)
- goto nope;
- execl ("/usr/games/hack", "#pragma", 0);
- execl ("/usr/games/rogue", "#pragma", 0);
- execl ("/usr/new/emacs", "-f", "hanoi", "9", "-kill", 0);
- execl ("/usr/local/emacs", "-f", "hanoi", "9", "-kill", 0);
-nope:
- fatal ("You are in a maze of twisty compiler features, all different");
+ ptr = include_hash (pfile, fcopy, 0);
+ if (ptr)
+ cpp_warning (pfile,
+ "`#pragma implementation' for `%s' appears after file is included",
+ fcopy);
+ }
+
+ return 0;
}
-#endif
#ifdef SCCS_DIRECTIVE
/* Just ignore #sccs, on systems where we define it at all. */
static int
-do_sccs (pfile, keyword, buf, limit)
+do_sccs (pfile, keyword)
cpp_reader *pfile;
struct directive *keyword ATTRIBUTE_UNUSED;
- U_CHAR *buf ATTRIBUTE_UNUSED, *limit ATTRIBUTE_UNUSED;
{
if (CPP_PEDANTIC (pfile))
cpp_pedwarn (pfile, "ANSI C does not allow `#sccs'");
+ skip_rest_of_line (pfile);
return 0;
}
#endif
@@ -4063,12 +1590,11 @@ do_sccs (pfile, keyword, buf, limit)
*/
static int
-do_if (pfile, keyword, buf, limit)
+do_if (pfile, keyword)
cpp_reader *pfile;
struct directive *keyword ATTRIBUTE_UNUSED;
- U_CHAR *buf, *limit;
{
- HOST_WIDE_INT value = eval_if_expression (pfile, buf, limit - buf);
+ HOST_WIDEST_INT value = eval_if_expression (pfile);
conditional_skip (pfile, value == 0, T_IF, NULL_PTR);
return 0;
}
@@ -4079,10 +1605,9 @@ do_if (pfile, keyword, buf, limit)
*/
static int
-do_elif (pfile, keyword, buf, limit)
+do_elif (pfile, keyword)
cpp_reader *pfile;
struct directive *keyword ATTRIBUTE_UNUSED;
- U_CHAR *buf, *limit;
{
if (pfile->if_stack == CPP_BUFFER (pfile)->if_stack) {
cpp_error (pfile, "`#elif' not within a conditional");
@@ -4103,11 +1628,11 @@ do_elif (pfile, keyword, buf, limit)
}
if (pfile->if_stack->if_succeeded)
- skip_if_group (pfile, 0);
+ skip_if_group (pfile);
else {
- HOST_WIDE_INT value = eval_if_expression (pfile, buf, limit - buf);
+ HOST_WIDEST_INT value = eval_if_expression (pfile);
if (value == 0)
- skip_if_group (pfile, 0);
+ skip_if_group (pfile);
else {
++pfile->if_stack->if_succeeded; /* continue processing input */
output_line_command (pfile, 1, same_file);
@@ -4121,22 +1646,16 @@ do_elif (pfile, keyword, buf, limit)
* then parse the result as a C expression and return the value as an int.
*/
-static HOST_WIDE_INT
-eval_if_expression (pfile, buf, length)
+static HOST_WIDEST_INT
+eval_if_expression (pfile)
cpp_reader *pfile;
- U_CHAR *buf ATTRIBUTE_UNUSED;
- int length ATTRIBUTE_UNUSED;
{
- HASHNODE *save_defined;
- HOST_WIDE_INT value;
+ HOST_WIDEST_INT value;
long old_written = CPP_WRITTEN (pfile);
- save_defined = install ((U_CHAR *)"defined", -1, T_SPEC_DEFINED, 0, 0, -1);
pfile->pcp_inside_if = 1;
-
value = cpp_parse_expr (pfile);
pfile->pcp_inside_if = 0;
- delete_macro (save_defined); /* clean up special symbol */
CPP_SET_WRITTEN (pfile, old_written); /* Pop */
@@ -4150,10 +1669,9 @@ eval_if_expression (pfile, buf, length)
*/
static int
-do_xifdef (pfile, keyword, unused1, unused2)
+do_xifdef (pfile, keyword)
cpp_reader *pfile;
struct directive *keyword;
- U_CHAR *unused1 ATTRIBUTE_UNUSED, *unused2 ATTRIBUTE_UNUSED;
{
int skip;
cpp_buffer *ip = CPP_BUFFER (pfile);
@@ -4252,7 +1770,7 @@ conditional_skip (pfile, skip, type, control_macro)
pfile->if_stack->type = type;
if (skip != 0) {
- skip_if_group (pfile, 0);
+ skip_if_group (pfile);
return;
} else {
++pfile->if_stack->if_succeeded;
@@ -4260,167 +1778,160 @@ conditional_skip (pfile, skip, type, control_macro)
}
}
-/*
- * skip to #endif, #else, or #elif. adjust line numbers, etc.
+/* Subroutine of skip_if_group. Examine one preprocessing directive and
+ return 0 if skipping should continue, 1 if it should halt. Also
+ adjusts the if_stack as appropriate.
+ The `#' has been read, but not the identifier. */
+
+static int
+consider_directive_while_skipping (pfile, stack)
+ cpp_reader *pfile;
+ IF_STACK_FRAME *stack;
+{
+ long ident_len, ident;
+ struct directive *kt;
+ IF_STACK_FRAME *temp;
+
+ cpp_skip_hspace (pfile);
+
+ ident = CPP_WRITTEN (pfile);
+ parse_name (pfile, GETC());
+ ident_len = CPP_WRITTEN (pfile) - ident;
+
+ CPP_SET_WRITTEN (pfile, ident);
+
+ for (kt = directive_table; kt->length >= 0; kt++)
+ if (kt->length == ident_len
+ && strncmp (pfile->token_buffer + ident, kt->name, kt->length) == 0)
+ switch (kt->type)
+ {
+ case T_IF:
+ case T_IFDEF:
+ case T_IFNDEF:
+ temp = (IF_STACK_FRAME *) xmalloc (sizeof (IF_STACK_FRAME));
+ temp->next = pfile->if_stack;
+ pfile->if_stack = temp;
+ temp->fname = CPP_BUFFER(pfile)->nominal_fname;
+ temp->type = kt->type;
+ return 0;
+
+ case T_ELSE:
+ if (CPP_PEDANTIC (pfile) && pfile->if_stack != stack)
+ validate_else (pfile, "#else");
+ /* fall through */
+ case T_ELIF:
+ if (pfile->if_stack->type == T_ELSE)
+ cpp_error (pfile, "`%s' after `#else'", kt->name);
+
+ if (pfile->if_stack == stack)
+ return 1;
+ else
+ {
+ pfile->if_stack->type = kt->type;
+ return 0;
+ }
+
+ case T_ENDIF:
+ if (CPP_PEDANTIC (pfile) && pfile->if_stack != stack)
+ validate_else (pfile, "#endif");
+
+ if (pfile->if_stack == stack)
+ return 1;
+
+ temp = pfile->if_stack;
+ pfile->if_stack = temp->next;
+ free (temp);
+ return 0;
+
+ default:
+ return 0;
+ }
+
+ /* Don't let erroneous code go by. */
+ if (!CPP_OPTIONS (pfile)->lang_asm && CPP_PEDANTIC (pfile))
+ cpp_pedwarn (pfile, "invalid preprocessor directive name");
+ return 0;
+}
+
+/* skip to #endif, #else, or #elif. adjust line numbers, etc.
* leaves input ptr at the sharp sign found.
- * If ANY is nonzero, return at next directive of any sort.
*/
-
static void
-skip_if_group (pfile, any)
- cpp_reader *pfile;
- int any;
+skip_if_group (pfile)
+ cpp_reader *pfile;
{
int c;
- struct directive *kt;
IF_STACK_FRAME *save_if_stack = pfile->if_stack; /* don't pop past here */
-#if 0
- U_CHAR *beg_of_line = bp;
-#endif
- register int ident_length;
- U_CHAR *ident;
- struct parse_marker line_start_mark;
-
- parse_set_mark (&line_start_mark, pfile);
-
- if (CPP_OPTIONS (pfile)->output_conditionals) {
- static char failed[] = "#failed\n";
- CPP_PUTS (pfile, failed, sizeof(failed)-1);
- pfile->lineno++;
- output_line_command (pfile, 1, same_file);
- }
+ U_CHAR *beg_of_line;
+ long old_written;
- beg_of_line:
if (CPP_OPTIONS (pfile)->output_conditionals)
{
- cpp_buffer *pbuf = CPP_BUFFER (pfile);
- U_CHAR *start_line = pbuf->buf + line_start_mark.position;
- CPP_PUTS (pfile, start_line, pbuf->cur - start_line);
+ CPP_PUTS (pfile, "#failed\n", 8);
+ pfile->lineno++;
+ output_line_command (pfile, 1, same_file);
}
- parse_move_mark (&line_start_mark, pfile);
- if (!CPP_TRADITIONAL (pfile))
- cpp_skip_hspace (pfile);
- c = GETC();
- if (c == '#')
- {
- int old_written = CPP_WRITTEN (pfile);
- cpp_skip_hspace (pfile);
- parse_name (pfile, GETC());
- ident_length = CPP_WRITTEN (pfile) - old_written;
- ident = pfile->token_buffer + old_written;
- pfile->limit = ident;
-#if 0
- if (ident_length == 0)
- goto not_a_directive;
+ old_written = CPP_WRITTEN (pfile);
+
+ for (;;)
+ {
+ beg_of_line = CPP_BUFFER (pfile)->cur;
- /* Handle # followed by a line number. */
+ if (! CPP_TRADITIONAL (pfile))
+ cpp_skip_hspace (pfile);
+ c = GETC();
+ if (c == '\n')
+ {
+ if (CPP_OPTIONS (pfile)->output_conditionals)
+ CPP_PUTC (pfile, c);
+ CPP_BUMP_LINE (pfile);
+ continue;
+ }
+ else if (c == '#')
+ {
+ if (consider_directive_while_skipping (pfile, save_if_stack))
+ break;
+ }
+ else if (c == EOF)
+ return; /* Caller will issue error. */
- /* Avoid error for `###' and similar cases unless -pedantic. */
-#endif
+ FORWARD(-1);
+ if (CPP_OPTIONS (pfile)->output_conditionals)
+ {
+ CPP_PUTS (pfile, beg_of_line, CPP_BUFFER (pfile)->cur - beg_of_line);
+ copy_rest_of_line (pfile);
+ }
+ else
+ {
+ copy_rest_of_line (pfile);
+ CPP_SET_WRITTEN (pfile, old_written); /* discard it */
+ }
- for (kt = directive_table; kt->length >= 0; kt++)
+ c = GETC();
+ if (c == EOF)
+ return; /* Caller will issue error. */
+ else
{
- IF_STACK_FRAME *temp;
- if (ident_length == kt->length
- && strncmp (ident, kt->name, kt->length) == 0)
+ /* \n */
+ if (CPP_OPTIONS (pfile)->output_conditionals)
{
- /* If we are asked to return on next directive, do so now. */
- if (any)
- goto done;
-
- switch (kt->type)
- {
- case T_IF:
- case T_IFDEF:
- case T_IFNDEF:
- temp
- = (IF_STACK_FRAME *) xcalloc (1, sizeof (IF_STACK_FRAME));
- temp->next = pfile->if_stack;
- pfile->if_stack = temp;
-#if 0
- temp->lineno = CPP_BUFFER(pfile)->lineno;
-#endif
- temp->fname = CPP_BUFFER(pfile)->nominal_fname;
- temp->type = kt->type;
- break;
- case T_ELSE:
- case T_ENDIF:
- if (CPP_PEDANTIC (pfile) && pfile->if_stack != save_if_stack)
- validate_else (pfile,
- kt->type == T_ELSE ? "#else" : "#endif");
- case T_ELIF:
- if (pfile->if_stack == CPP_BUFFER (pfile)->if_stack)
- {
- cpp_error (pfile,
- "`#%s' not within a conditional", kt->name);
- break;
- }
- else if (pfile->if_stack == save_if_stack)
- goto done; /* found what we came for */
-
- if (kt->type != T_ENDIF)
- {
- if (pfile->if_stack->type == T_ELSE)
- cpp_error (pfile, "`#else' or `#elif' after `#else'");
- pfile->if_stack->type = kt->type;
- break;
- }
-
- temp = pfile->if_stack;
- pfile->if_stack = temp->next;
- free (temp);
- break;
- default: ;
- }
- break;
+ CPP_PUTC (pfile, c);
+ pfile->lineno++;
}
- /* Don't let erroneous code go by. */
- if (kt->length < 0 && !CPP_OPTIONS (pfile)->lang_asm
- && CPP_PEDANTIC (pfile))
- cpp_pedwarn (pfile, "invalid preprocessor directive name");
+ CPP_BUMP_LINE (pfile);
}
- c = GETC ();
- }
- /* We're in the middle of a line. Skip the rest of it. */
- for (;;) {
- switch (c)
- {
- long old;
- case EOF:
- goto done;
- case '/': /* possible comment */
- c = skip_comment (pfile, NULL);
- if (c == EOF)
- goto done;
- break;
- case '\"':
- case '\'':
- FORWARD(-1);
- old = CPP_WRITTEN (pfile);
- cpp_get_token (pfile);
- CPP_SET_WRITTEN (pfile, old);
- break;
- case '\\':
- /* Char after backslash loses its special meaning. */
- if (PEEKC() == '\n')
- FORWARD (1);
- break;
- case '\n':
- goto beg_of_line;
- break;
- }
- c = GETC ();
- }
- done:
- if (CPP_OPTIONS (pfile)->output_conditionals) {
- static char end_failed[] = "#endfailed\n";
- CPP_PUTS (pfile, end_failed, sizeof(end_failed)-1);
- pfile->lineno++;
- }
+ }
+
+ /* Back up to the beginning of this line. Caller will process the
+ directive. */
+ CPP_BUFFER (pfile)->cur = beg_of_line;
pfile->only_seen_white = 1;
- parse_goto_mark (&line_start_mark, pfile);
- parse_clear_mark (&line_start_mark);
+ if (CPP_OPTIONS (pfile)->output_conditionals)
+ {
+ CPP_PUTS (pfile, "#endfailed\n", 11);
+ pfile->lineno++;
+ }
}
/*
@@ -4431,10 +1942,9 @@ skip_if_group (pfile, any)
*/
static int
-do_else (pfile, keyword, buf, limit)
+do_else (pfile, keyword)
cpp_reader *pfile;
struct directive *keyword ATTRIBUTE_UNUSED;
- U_CHAR *buf ATTRIBUTE_UNUSED, *limit ATTRIBUTE_UNUSED;
{
cpp_buffer *ip = CPP_BUFFER (pfile);
@@ -4461,7 +1971,7 @@ do_else (pfile, keyword, buf, limit)
}
if (pfile->if_stack->if_succeeded)
- skip_if_group (pfile, 0);
+ skip_if_group (pfile);
else {
++pfile->if_stack->if_succeeded; /* continue processing input */
output_line_command (pfile, 1, same_file);
@@ -4474,10 +1984,9 @@ do_else (pfile, keyword, buf, limit)
*/
static int
-do_endif (pfile, keyword, buf, limit)
+do_endif (pfile, keyword)
cpp_reader *pfile;
struct directive *keyword ATTRIBUTE_UNUSED;
- U_CHAR *buf ATTRIBUTE_UNUSED, *limit ATTRIBUTE_UNUSED;
{
if (CPP_PEDANTIC (pfile))
validate_else (pfile, "#endif");
@@ -4493,10 +2002,9 @@ do_endif (pfile, keyword, buf, limit)
{
/* This #endif matched a #ifndef at the start of the file.
See if it is at the end of the file. */
- struct parse_marker start_mark;
int c;
- parse_set_mark (&start_mark, pfile);
+ parse_set_mark (pfile);
for (;;)
{
@@ -4505,36 +2013,19 @@ do_endif (pfile, keyword, buf, limit)
if (c != '\n')
break;
}
- parse_goto_mark (&start_mark, pfile);
- parse_clear_mark (&start_mark);
+ parse_goto_mark (pfile);
if (c == EOF)
{
- /* If we get here, this #endif ends a #ifndef
+ /* This #endif ends a #ifndef
that contains all of the file (aside from whitespace).
Arrange not to include the file again
- if the macro that was tested is defined.
-
- Do not do this for the top-level file in a -include or any
- file in a -imacros. */
-#if 0
-FIXME!
- if (indepth != 0
- && ! (indepth == 1 && pfile->no_record_file)
- && ! (pfile->no_record_file && no_output))
-#endif
- {
- struct file_name_list *ifile = pfile->all_include_files;
-
- for ( ; ifile != NULL; ifile = ifile->next)
- {
- if (!strcmp (ifile->fname, CPP_BUFFER (pfile)->fname))
- {
- ifile->control_macro = temp->control_macro;
- break;
- }
- }
- }
+ if the macro that was tested is defined. */
+ struct cpp_buffer *ip;
+ for (ip = CPP_BUFFER (pfile); ; ip = CPP_PREV_BUFFER (ip))
+ if (ip->fname != NULL)
+ break;
+ ip->ihash->control_macro = (char *) temp->control_macro;
}
}
free (temp);
@@ -4568,11 +2059,9 @@ cpp_get_token (pfile)
cpp_reader *pfile;
{
register int c, c2, c3;
- long old_written;
- long start_line, start_column;
enum cpp_token token;
struct cpp_options *opts = CPP_OPTIONS (pfile);
- CPP_BUFFER (pfile)->prev = CPP_BUFFER (pfile)->cur;
+
get_next:
c = GETC();
if (c == EOF)
@@ -4580,10 +2069,11 @@ cpp_get_token (pfile)
handle_eof:
if (CPP_BUFFER (pfile)->seen_eof)
{
- if (cpp_pop_buffer (pfile) != CPP_NULL_BUFFER (pfile))
- goto get_next;
- else
+ if (CPP_PREV_BUFFER (CPP_BUFFER (pfile)) == CPP_NULL_BUFFER (pfile))
return CPP_EOF;
+
+ cpp_pop_buffer (pfile);
+ goto get_next;
}
else
{
@@ -4609,68 +2099,27 @@ cpp_get_token (pfile)
{
switch (c)
{
- long newlines;
- struct parse_marker start_mark;
case '/':
if (PEEKC () == '=')
goto op2;
+
+ comment:
if (opts->put_out_comments)
- parse_set_mark (&start_mark, pfile);
- newlines = 0;
- cpp_buf_line_and_col (cpp_file_buffer (pfile),
- &start_line, &start_column);
- c = skip_comment (pfile, &newlines);
- if (opts->put_out_comments && (c == '/' || c == EOF))
- parse_clear_mark (&start_mark);
- if (c == '/')
- goto randomchar;
+ c = copy_comment (pfile, c);
+ else
+ c = skip_comment (pfile, c);
if (c == EOF)
- {
- cpp_error_with_line (pfile, start_line, start_column,
- "unterminated comment");
- goto handle_eof;
- }
- c = '/'; /* Initial letter of comment. */
- return_comment:
+ goto handle_eof;
+ else if (c != ' ')
+ goto randomchar;
+
/* Comments are equivalent to spaces.
For -traditional, a comment is equivalent to nothing. */
- if (opts->put_out_comments)
- {
- cpp_buffer *pbuf = CPP_BUFFER (pfile);
- U_CHAR *start = pbuf->buf + start_mark.position;
- int len = pbuf->cur - start;
- CPP_RESERVE(pfile, 1 + len);
- CPP_PUTC_Q (pfile, c);
- CPP_PUTS_Q (pfile, start, len);
- pfile->lineno += newlines;
- parse_clear_mark (&start_mark);
- return CPP_COMMENT;
- }
- else if (CPP_TRADITIONAL (pfile))
- {
- return CPP_COMMENT;
- }
+ if (opts->traditional || opts->put_out_comments)
+ return CPP_COMMENT;
else
{
-#if 0
- /* This may not work if cpp_get_token is called recursively,
- since many places look for horizontal space. */
- if (newlines)
- {
- /* Copy the newlines into the output buffer, in order to
- avoid the pain of a #line every time a multiline comment
- is seen. */
- CPP_RESERVE(pfile, newlines);
- while (--newlines >= 0)
- {
- CPP_PUTC_Q (pfile, '\n');
- pfile->lineno++;
- }
- return CPP_VSPACE;
- }
-#endif
- CPP_RESERVE(pfile, 1);
- CPP_PUTC_Q (pfile, ' ');
+ CPP_PUTC (pfile, c);
return CPP_HSPACE;
}
#if 0
@@ -4727,96 +2176,8 @@ cpp_get_token (pfile)
case '\"':
case '\'':
- /* A single quoted string is treated like a double -- some
- programs (e.g., troff) are perverse this way */
- cpp_buf_line_and_col (cpp_file_buffer (pfile),
- &start_line, &start_column);
- old_written = CPP_WRITTEN (pfile);
string:
- CPP_PUTC (pfile, c);
- while (1)
- {
- int cc = GETC();
- if (cc == EOF)
- {
- if (CPP_IS_MACRO_BUFFER (CPP_BUFFER (pfile)))
- {
- /* try harder: this string crosses a macro expansion
- boundary. This can happen naturally if -traditional.
- Otherwise, only -D can make a macro with an unmatched
- quote. */
- cpp_buffer *next_buf
- = CPP_PREV_BUFFER (CPP_BUFFER (pfile));
- (*CPP_BUFFER (pfile)->cleanup)
- (CPP_BUFFER (pfile), pfile);
- CPP_BUFFER (pfile) = next_buf;
- continue;
- }
- if (!CPP_TRADITIONAL (pfile))
- {
- cpp_error_with_line (pfile, start_line, start_column,
- "unterminated string or character constant");
- if (pfile->multiline_string_line != start_line
- && pfile->multiline_string_line != 0)
- cpp_error_with_line (pfile,
- pfile->multiline_string_line, -1,
- "possible real start of unterminated constant");
- pfile->multiline_string_line = 0;
- }
- break;
- }
- CPP_PUTC (pfile, cc);
- switch (cc)
- {
- case '\n':
- /* Traditionally, end of line ends a string constant with
- no error. So exit the loop and record the new line. */
- if (CPP_TRADITIONAL (pfile))
- goto while2end;
- if (c == '\'')
- {
- cpp_error_with_line (pfile, start_line, start_column,
- "unterminated character constant");
- goto while2end;
- }
- if (CPP_PEDANTIC (pfile)
- && pfile->multiline_string_line == 0)
- {
- cpp_pedwarn_with_line (pfile, start_line, start_column,
- "string constant runs past end of line");
- }
- if (pfile->multiline_string_line == 0)
- pfile->multiline_string_line = start_line;
- break;
-
- case '\\':
- cc = GETC();
- if (cc == '\n')
- {
- /* Backslash newline is replaced by nothing at all. */
- CPP_ADJUST_WRITTEN (pfile, -1);
- pfile->lineno++;
- }
- else
- {
- /* ANSI stupidly requires that in \\ the second \
- is *not* prevented from combining with a newline. */
- NEWLINE_FIX1(cc);
- if (cc != EOF)
- CPP_PUTC (pfile, cc);
- }
- break;
-
- case '\"':
- case '\'':
- if (cc == c)
- goto while2end;
- break;
- }
- }
- while2end:
- pfile->lineno += count_newlines (pfile->token_buffer + old_written,
- CPP_PWRITTEN (pfile));
+ parse_string (pfile, c);
pfile->only_seen_white = 0;
return c == '\'' ? CPP_CHAR : CPP_STRING;
@@ -4833,7 +2194,6 @@ cpp_get_token (pfile)
case '&':
case '+':
case '|':
- NEWLINE_FIX;
c2 = PEEKC ();
if (c2 == c || c2 == '=')
goto op2;
@@ -4844,35 +2204,14 @@ cpp_get_token (pfile)
case '%':
case '=':
case '^':
- NEWLINE_FIX;
if (PEEKC () == '=')
goto op2;
goto randomchar;
case '-':
- NEWLINE_FIX;
c2 = PEEKC ();
if (c2 == '-' && opts->chill)
- {
- /* Chill style comment */
- if (opts->put_out_comments)
- parse_set_mark (&start_mark, pfile);
- FORWARD(1); /* Skip second '-'. */
- for (;;)
- {
- c = GETC ();
- if (c == EOF)
- break;
- if (c == '\n')
- {
- /* Don't consider final '\n' to be part of comment. */
- FORWARD(-1);
- break;
- }
- }
- c = '-';
- goto return_comment;
- }
+ goto comment; /* Chill style comment */
if (c2 == '-' || c2 == '=' || c2 == '>')
goto op2;
goto randomchar;
@@ -4886,19 +2225,23 @@ cpp_get_token (pfile)
if (c == '>')
break;
c = GETC ();
- NEWLINE_FIX1 (c);
if (c == '\n' || c == EOF)
{
cpp_error (pfile,
"missing '>' in `#include <FILENAME>'");
break;
}
+ else if (c == '\r')
+ {
+ /* Backslash newline is replaced by nothing. */
+ CPP_ADJUST_WRITTEN (pfile, -1);
+ CPP_BUMP_LINE (pfile);
+ }
}
return CPP_STRING;
}
/* else fall through */
case '>':
- NEWLINE_FIX;
c2 = PEEKC ();
if (c2 == '=')
goto op2;
@@ -4908,7 +2251,6 @@ cpp_get_token (pfile)
CPP_RESERVE (pfile, 4);
CPP_PUTC (pfile, c);
CPP_PUTC (pfile, c2);
- NEWLINE_FIX;
c3 = PEEKC ();
if (c3 == '=')
CPP_PUTC_Q (pfile, GETC ());
@@ -4927,7 +2269,7 @@ cpp_get_token (pfile)
parse_name (pfile, GETC ());
return CPP_NAME;
}
- else if (is_space [c])
+ else if (c == ' ')
{
CPP_RESERVE (pfile, 2);
if (pfile->output_escapes)
@@ -4944,7 +2286,6 @@ cpp_get_token (pfile)
goto randomchar;
case '.':
- NEWLINE_FIX;
c2 = PEEKC ();
if (ISDIGIT(c2))
{
@@ -4953,7 +2294,6 @@ cpp_get_token (pfile)
c = GETC ();
goto number;
}
- /* FIXME - misses the case "..\\\n." */
if (c2 == '.' && PEEKN(1) == '.')
{
CPP_RESERVE(pfile, 4);
@@ -4970,7 +2310,6 @@ cpp_get_token (pfile)
op2:
token = CPP_OTHER;
pfile->only_seen_white = 0;
- op2any:
CPP_RESERVE(pfile, 3);
CPP_PUTC_Q (pfile, c);
CPP_PUTC_Q (pfile, GETC ());
@@ -4978,7 +2317,6 @@ cpp_get_token (pfile)
return token;
case 'L':
- NEWLINE_FIX;
c2 = PEEKC ();
if ((c2 == '\'' || c2 == '\"') && !CPP_TRADITIONAL (pfile))
{
@@ -4996,7 +2334,6 @@ cpp_get_token (pfile)
{
CPP_RESERVE (pfile, 2);
CPP_PUTC_Q (pfile, c);
- NEWLINE_FIX;
c = PEEKC ();
if (c == EOF)
break;
@@ -5026,14 +2363,7 @@ cpp_get_token (pfile)
if (c == EOF)
goto chill_number_eof;
if (!is_idchar[c])
- {
- if (c == '\\' && PEEKC() == '\n')
- {
- FORWARD(2);
- continue;
- }
- break;
- }
+ break;
CPP_PUTC (pfile, c);
}
if (c == '\'')
@@ -5098,72 +2428,58 @@ cpp_get_token (pfile)
decide this is not a macro call and leave things that way. */
if (hp->type == T_MACRO && hp->value.defn->nargs >= 0)
{
- struct parse_marker macro_mark;
- int is_macro_call;
- while (CPP_IS_MACRO_BUFFER (CPP_BUFFER (pfile)))
- {
- cpp_buffer *next_buf;
- cpp_skip_hspace (pfile);
- if (PEEKC () != EOF)
- break;
- next_buf = CPP_PREV_BUFFER (CPP_BUFFER (pfile));
- (*CPP_BUFFER (pfile)->cleanup) (CPP_BUFFER (pfile), pfile);
- CPP_BUFFER (pfile) = next_buf;
- }
- parse_set_mark (&macro_mark, pfile);
+ int is_macro_call, macbuf_whitespace = 0;
+
+ parse_set_mark (pfile);
for (;;)
{
cpp_skip_hspace (pfile);
c = PEEKC ();
is_macro_call = c == '(';
- if (c != '\n')
- break;
- FORWARD (1);
+ if (c != EOF)
+ {
+ if (c != '\n')
+ break;
+ FORWARD (1);
+ }
+ else
+ {
+ if (CPP_IS_MACRO_BUFFER (CPP_BUFFER (pfile)))
+ {
+ if (CPP_BUFFER (pfile)->mark !=
+ (CPP_BUFFER (pfile)->cur
+ - CPP_BUFFER (pfile)->buf))
+ macbuf_whitespace = 1;
+
+ /* The mark goes away automatically when
+ the buffer is popped. */
+ cpp_pop_buffer (pfile);
+ parse_set_mark (pfile);
+ }
+ else
+ break;
+ }
}
if (!is_macro_call)
- parse_goto_mark (&macro_mark, pfile);
- parse_clear_mark (&macro_mark);
+ {
+ parse_goto_mark (pfile);
+ if (macbuf_whitespace)
+ CPP_PUTC (pfile, ' ');
+ }
+ else
+ parse_clear_mark (pfile);
if (!is_macro_call)
return CPP_NAME;
}
- /* This is now known to be a macro call. */
-
- /* it might not actually be a macro. */
- if (hp->type != T_MACRO) {
- int xbuf_len; U_CHAR *xbuf;
- CPP_SET_WRITTEN (pfile, before_name_written);
- special_symbol (hp, pfile);
- xbuf_len = CPP_WRITTEN (pfile) - before_name_written;
- xbuf = (U_CHAR *) xmalloc (xbuf_len + 1);
- CPP_SET_WRITTEN (pfile, before_name_written);
- bcopy (CPP_PWRITTEN (pfile), xbuf, xbuf_len + 1);
- push_macro_expansion (pfile, xbuf, xbuf_len, hp);
- }
- else
- {
- /* Expand the macro, reading arguments as needed,
- and push the expansion on the input stack. */
- macroexpand (pfile, hp);
- CPP_SET_WRITTEN (pfile, before_name_written);
- }
-
- /* An extra "@ " is added to the end of a macro expansion
- to prevent accidental token pasting. We prefer to avoid
- unneeded extra spaces (for the sake of cpp-using tools like
- imake). Here we remove the space if it is safe to do so. */
- if (pfile->buffer->rlimit - pfile->buffer->cur >= 3
- && pfile->buffer->rlimit[-2] == '@'
- && pfile->buffer->rlimit[-1] == ' ')
- {
- int c1 = pfile->buffer->rlimit[-3];
- int c2 = CPP_BUF_PEEK (CPP_PREV_BUFFER (CPP_BUFFER (pfile)));
- if (c2 == EOF || ! unsafe_chars (c1, c2))
- pfile->buffer->rlimit -= 2;
- }
+ /* This is now known to be a macro call.
+ Expand the macro, reading arguments as needed,
+ and push the expansion on the input stack. */
+ macroexpand (pfile, hp);
+ CPP_SET_WRITTEN (pfile, before_name_written);
}
goto get_next;
- case ' ': case '\t': case '\v': case '\r':
+ case ' ': case '\t': case '\v':
for (;;)
{
CPP_PUTC (pfile, c);
@@ -5175,18 +2491,21 @@ cpp_get_token (pfile)
return CPP_HSPACE;
case '\\':
- c2 = PEEKC ();
- if (c2 != '\n')
- goto randomchar;
- token = CPP_HSPACE;
- goto op2any;
+ goto randomchar;
+
+ case '\r':
+ /* Backslash newline is ignored. */
+ CPP_BUMP_LINE (pfile);
+ goto get_next;
case '\n':
CPP_PUTC (pfile, c);
if (pfile->only_seen_white == 0)
pfile->only_seen_white = 1;
+ CPP_BUMP_LINE (pfile);
pfile->lineno++;
- output_line_command (pfile, 1, same_file);
+ if (CPP_BUFFER (pfile)->lineno != pfile->lineno)
+ output_line_command (pfile, 1, same_file);
return CPP_VSPACE;
case '(': token = CPP_LPAREN; goto char1;
@@ -5226,19 +2545,15 @@ cpp_get_non_space_token (pfile)
/* Parse an identifier starting with C. */
-static int
+static void
parse_name (pfile, c)
- cpp_reader *pfile; int c;
+ cpp_reader *pfile;
+ int c;
{
for (;;)
{
if (! is_idchar[c])
{
- if (c == '\\' && PEEKC() == '\n')
- {
- FORWARD(2);
- continue;
- }
FORWARD (-1);
break;
}
@@ -5253,2179 +2568,385 @@ parse_name (pfile, c)
break;
}
CPP_NUL_TERMINATE_Q (pfile);
- return 1;
-}
-
-
-/* Maintain and search list of included files, for #import. */
-
-/* Hash a file name for import_hash_table. */
-
-static int
-import_hash (f)
- char *f;
-{
- int val = 0;
-
- while (*f) val += *f++;
- return (val%IMPORT_HASH_SIZE);
-}
-
-/* Search for file FILENAME in import_hash_table.
- Return -2 if found, either a matching name or a matching inode.
- Otherwise, open the file and return a file descriptor if successful
- or -1 if unsuccessful. */
-
-static int
-lookup_import (pfile, filename, searchptr)
- cpp_reader *pfile;
- char *filename;
- struct file_name_list *searchptr;
-{
- struct import_file *i;
- int h;
- int hashval;
- struct stat sb;
- int fd;
-
- hashval = import_hash (filename);
-
- /* Attempt to find file in list of already included files */
- i = pfile->import_hash_table[hashval];
-
- while (i) {
- if (!strcmp (filename, i->name))
- return -2; /* return found */
- i = i->next;
- }
- /* Open it and try a match on inode/dev */
- fd = open_include_file (pfile, filename, searchptr);
- if (fd < 0)
- return fd;
- fstat (fd, &sb);
- for (h = 0; h < IMPORT_HASH_SIZE; h++) {
- i = pfile->import_hash_table[h];
- while (i) {
- /* Compare the inode and the device.
- Supposedly on some systems the inode is not a scalar. */
- if (!bcmp ((char *) &i->inode, (char *) &sb.st_ino, sizeof (sb.st_ino))
- && i->dev == sb.st_dev) {
- close (fd);
- return -2; /* return found */
- }
- i = i->next;
- }
- }
- return fd; /* Not found, return open file */
+ return;
}
-/* Add the file FNAME, open on descriptor FD, to import_hash_table. */
-
+/* Parse a string starting with C. A single quoted string is treated
+ like a double -- some programs (e.g., troff) are perverse this way.
+ (However, a single quoted string is not allowed to extend over
+ multiple lines. */
static void
-add_import (pfile, fd, fname)
+parse_string (pfile, c)
cpp_reader *pfile;
- int fd;
- char *fname;
-{
- struct import_file *i;
- int hashval;
- struct stat sb;
-
- hashval = import_hash (fname);
- fstat (fd, &sb);
- i = (struct import_file *)xmalloc (sizeof (struct import_file));
- i->name = (char *)xmalloc (strlen (fname)+1);
- strcpy (i->name, fname);
- bcopy ((char *) &sb.st_ino, (char *) &i->inode, sizeof (sb.st_ino));
- i->dev = sb.st_dev;
- i->next = pfile->import_hash_table[hashval];
- pfile->import_hash_table[hashval] = i;
-}
-
-/* The file_name_map structure holds a mapping of file names for a
- particular directory. This mapping is read from the file named
- FILE_NAME_MAP_FILE in that directory. Such a file can be used to
- map filenames on a file system with severe filename restrictions,
- such as DOS. The format of the file name map file is just a series
- of lines with two tokens on each line. The first token is the name
- to map, and the second token is the actual name to use. */
-
-struct file_name_map
-{
- struct file_name_map *map_next;
- char *map_from;
- char *map_to;
-};
-
-#define FILE_NAME_MAP_FILE "header.gcc"
-
-/* Read a space delimited string of unlimited length from a stdio
- file. */
-
-static char *
-read_filename_string (ch, f)
- int ch;
- FILE *f;
+ int c;
{
- char *alloc, *set;
- int len;
+ long start_line, start_column;
+
+ cpp_buf_line_and_col (cpp_file_buffer (pfile), &start_line, &start_column);
- len = 20;
- set = alloc = xmalloc (len + 1);
- if (! is_space[ch])
+ CPP_PUTC (pfile, c);
+ while (1)
{
- *set++ = ch;
- while ((ch = getc (f)) != EOF && ! is_space[ch])
+ int cc = GETC();
+ if (cc == EOF)
{
- if (set - alloc == len)
+ if (CPP_IS_MACRO_BUFFER (CPP_BUFFER (pfile)))
{
- len *= 2;
- alloc = xrealloc (alloc, len + 1);
- set = alloc + len / 2;
+ /* try harder: this string crosses a macro expansion
+ boundary. This can happen naturally if -traditional.
+ Otherwise, only -D can make a macro with an unmatched
+ quote. */
+ cpp_pop_buffer (pfile);
+ continue;
}
- *set++ = ch;
- }
- }
- *set = '\0';
- ungetc (ch, f);
- return alloc;
-}
-
-/* This structure holds a linked list of file name maps, one per directory. */
-
-struct file_name_map_list
-{
- struct file_name_map_list *map_list_next;
- char *map_list_name;
- struct file_name_map *map_list_map;
-};
-
-/* Read the file name map file for DIRNAME. */
-
-static struct file_name_map *
-read_name_map (pfile, dirname)
- cpp_reader *pfile;
- char *dirname;
-{
- register struct file_name_map_list *map_list_ptr;
- char *name;
- FILE *f;
-
- for (map_list_ptr = CPP_OPTIONS (pfile)->map_list; map_list_ptr;
- map_list_ptr = map_list_ptr->map_list_next)
- if (! strcmp (map_list_ptr->map_list_name, dirname))
- return map_list_ptr->map_list_map;
-
- map_list_ptr = ((struct file_name_map_list *)
- xmalloc (sizeof (struct file_name_map_list)));
- map_list_ptr->map_list_name = savestring (dirname);
- map_list_ptr->map_list_map = NULL;
-
- name = (char *) alloca (strlen (dirname) + strlen (FILE_NAME_MAP_FILE) + 2);
- strcpy (name, dirname);
- if (*dirname)
- strcat (name, "/");
- strcat (name, FILE_NAME_MAP_FILE);
- f = fopen (name, "r");
- if (!f)
- map_list_ptr->map_list_map = NULL;
- else
- {
- int ch;
- int dirlen = strlen (dirname);
-
- while ((ch = getc (f)) != EOF)
- {
- char *from, *to;
- struct file_name_map *ptr;
-
- if (is_space[ch])
- continue;
- from = read_filename_string (ch, f);
- while ((ch = getc (f)) != EOF && is_hor_space[ch])
- ;
- to = read_filename_string (ch, f);
-
- ptr = ((struct file_name_map *)
- xmalloc (sizeof (struct file_name_map)));
- ptr->map_from = from;
-
- /* Make the real filename absolute. */
- if (*to == '/')
- ptr->map_to = to;
- else
+ if (!CPP_TRADITIONAL (pfile))
{
- ptr->map_to = xmalloc (dirlen + strlen (to) + 2);
- strcpy (ptr->map_to, dirname);
- ptr->map_to[dirlen] = '/';
- strcpy (ptr->map_to + dirlen + 1, to);
- free (to);
- }
-
- ptr->map_next = map_list_ptr->map_list_map;
- map_list_ptr->map_list_map = ptr;
-
- while ((ch = getc (f)) != '\n')
- if (ch == EOF)
- break;
- }
- fclose (f);
- }
-
- map_list_ptr->map_list_next = CPP_OPTIONS (pfile)->map_list;
- CPP_OPTIONS (pfile)->map_list = map_list_ptr;
-
- return map_list_ptr->map_list_map;
-}
-
-/* Try to open include file FILENAME. SEARCHPTR is the directory
- being tried from the include file search path. This function maps
- filenames on file systems based on information read by
- read_name_map. */
-
-static int
-open_include_file (pfile, filename, searchptr)
- cpp_reader *pfile;
- char *filename;
- struct file_name_list *searchptr;
-{
- if (CPP_OPTIONS (pfile)->remap)
- {
- register struct file_name_map *map;
- register char *from;
- char *p, *dir;
-
- if (searchptr && ! searchptr->got_name_map)
- {
- searchptr->name_map = read_name_map (pfile,
- searchptr->fname
- ? searchptr->fname : ".");
- searchptr->got_name_map = 1;
+ cpp_error_with_line (pfile, start_line, start_column,
+ "unterminated string or character constant");
+ if (pfile->multiline_string_line != start_line
+ && pfile->multiline_string_line != 0)
+ cpp_error_with_line (pfile,
+ pfile->multiline_string_line, -1,
+ "possible real start of unterminated constant");
+ pfile->multiline_string_line = 0;
+ }
+ break;
}
-
- /* First check the mapping for the directory we are using. */
- if (searchptr && searchptr->name_map)
+ CPP_PUTC (pfile, cc);
+ switch (cc)
{
- from = filename;
- if (searchptr->fname)
- from += strlen (searchptr->fname) + 1;
- for (map = searchptr->name_map; map; map = map->map_next)
+ case '\n':
+ CPP_BUMP_LINE (pfile);
+ pfile->lineno++;
+ /* Traditionally, end of line ends a string constant with
+ no error. */
+ if (CPP_TRADITIONAL (pfile))
+ return;
+ /* Character constants may not extend over multiple lines. */
+ if (c == '\'')
{
- if (! strcmp (map->map_from, from))
- {
- /* Found a match. */
- return open (map->map_to, O_RDONLY, 0666);
- }
+ cpp_error_with_line (pfile, start_line, start_column,
+ "unterminated character constant");
+ return;
}
- }
+ if (CPP_PEDANTIC (pfile) && pfile->multiline_string_line == 0)
+ {
+ cpp_pedwarn_with_line (pfile, start_line, start_column,
+ "string constant runs past end of line");
+ }
+ if (pfile->multiline_string_line == 0)
+ pfile->multiline_string_line = start_line;
+ break;
- /* Try to find a mapping file for the particular directory we are
- looking in. Thus #include <sys/types.h> will look up sys/types.h
- in /usr/include/header.gcc and look up types.h in
- /usr/include/sys/header.gcc. */
- p = rindex (filename, '/');
- if (! p)
- p = filename;
- if (searchptr
- && searchptr->fname
- && strlen (searchptr->fname) == p - filename
- && ! strncmp (searchptr->fname, filename, p - filename))
- {
- /* FILENAME is in SEARCHPTR, which we've already checked. */
- return open (filename, O_RDONLY, 0666);
- }
+ case '\r':
+ /* Backslash newline is replaced by nothing at all. */
+ CPP_ADJUST_WRITTEN (pfile, -1);
+ CPP_BUMP_LINE (pfile);
+ break;
- if (p == filename)
- {
- dir = ".";
- from = filename;
- }
- else
- {
- dir = (char *) alloca (p - filename + 1);
- bcopy (filename, dir, p - filename);
- dir[p - filename] = '\0';
- from = p + 1;
+ case '\\':
+ cc = GETC();
+ if (cc != EOF)
+ CPP_PUTC (pfile, cc);
+ break;
+
+ case '\"':
+ case '\'':
+ if (cc == c)
+ return;
+ break;
}
- for (map = read_name_map (pfile, dir); map; map = map->map_next)
- if (! strcmp (map->map_from, from))
- return open (map->map_to, O_RDONLY, 0666);
}
-
- return open (filename, O_RDONLY, 0666);
}
-/* Process the contents of include file FNAME, already open on descriptor F,
- with output to OP.
- SYSTEM_HEADER_P is 1 if this file resides in any one of the known
- "system" include directories (as decided by the `is_system_include'
- function above).
- DIRPTR is the link in the dir path through which this file was found,
- or 0 if the file name was absolute or via the current directory.
- Return 1 on success, 0 on failure.
-
- The caller is responsible for the cpp_push_buffer. */
-
+/* Read an assertion into the token buffer, converting to
+ canonical form: `#predicate(a n swe r)' The next non-whitespace
+ character to read should be the first letter of the predicate.
+ Returns 0 for syntax error, 1 for bare predicate, 2 for predicate
+ with answer (see callers for why). In case of 0, an error has been
+ printed. */
static int
-finclude (pfile, f, fname, system_header_p, dirptr)
+parse_assertion (pfile)
cpp_reader *pfile;
- int f;
- char *fname;
- int system_header_p;
- struct file_name_list *dirptr;
{
- struct stat st;
- size_t st_size;
- long i;
- int length;
- cpp_buffer *fp; /* For input stack frame */
-#if 0
- int missing_newline = 0;
-#endif
-
- if (fstat (f, &st) < 0)
+ int c, dropwhite;
+ cpp_skip_hspace (pfile);
+ c = PEEKC();
+ if (! is_idstart[c])
{
- cpp_perror_with_name (pfile, fname);
- close (f);
- cpp_pop_buffer (pfile);
+ cpp_error (pfile, "assertion predicate is not an identifier");
return 0;
}
+ CPP_PUTC(pfile, '#');
+ FORWARD(1);
+ parse_name(pfile, c);
- fp = CPP_BUFFER (pfile);
- fp->nominal_fname = fp->fname = fname;
-#if 0
- fp->length = 0;
-#endif
- fp->dir = dirptr;
- fp->system_header_p = system_header_p;
- fp->lineno = 1;
- fp->colno = 1;
- fp->cleanup = file_cleanup;
-
- if (S_ISREG (st.st_mode)) {
- st_size = (size_t) st.st_size;
- if (st_size != st.st_size || st_size + 2 < st_size) {
- cpp_error (pfile, "file `%s' too large", fname);
- close (f);
- return 0;
- }
- fp->buf = (U_CHAR *) xmalloc (st_size + 2);
- fp->alimit = fp->buf + st_size + 2;
- fp->cur = fp->buf;
-
- /* Read the file contents, knowing that st_size is an upper bound
- on the number of bytes we can read. */
- length = safe_read (f, fp->buf, st_size);
- fp->rlimit = fp->buf + length;
- if (length < 0) goto nope;
- }
- else if (S_ISDIR (st.st_mode)) {
- cpp_error (pfile, "directory `%s' specified in #include", fname);
- close (f);
- return 0;
- } else {
- /* Cannot count its file size before reading.
- First read the entire file into heap and
- copy them into buffer on stack. */
-
- int bsize = 2000;
-
- st_size = 0;
- fp->buf = (U_CHAR *) xmalloc (bsize + 2);
-
- for (;;) {
- i = safe_read (f, fp->buf + st_size, bsize - st_size);
- if (i < 0)
- goto nope; /* error! */
- st_size += i;
- if (st_size != bsize)
- break; /* End of file */
- bsize *= 2;
- fp->buf = (U_CHAR *) xrealloc (fp->buf, bsize + 2);
- }
- fp->cur = fp->buf;
- length = st_size;
- }
-
- if ((length > 0 && fp->buf[length - 1] != '\n')
- /* Backslash-newline at end is not good enough. */
- || (length > 1 && fp->buf[length - 2] == '\\')) {
- fp->buf[length++] = '\n';
-#if 0
- missing_newline = 1;
-#endif
- }
- fp->buf[length] = '\0';
- fp->rlimit = fp->buf + length;
-
- /* Close descriptor now, so nesting does not use lots of descriptors. */
- close (f);
-
- /* Must do this before calling trigraph_pcp, so that the correct file name
- will be printed in warning messages. */
-
- pfile->input_stack_listing_current = 0;
-
-#if 0
- if (!no_trigraphs)
- trigraph_pcp (fp);
-#endif
-
-#if 0
- rescan (op, 0);
-
- if (missing_newline)
- fp->lineno--;
-
- if (CPP_PEDANTIC (pfile) && missing_newline)
- pedwarn ("file does not end in newline");
-
- indepth--;
- input_file_stack_tick++;
- free (fp->buf);
-#endif
- return 1;
-
- nope:
-
- cpp_perror_with_name (pfile, fname);
- close (f);
- free (fp->buf);
- return 1;
-}
-
-/* This is called after options have been processed.
- * Check options for consistency, and setup for processing input
- * from the file named FNAME. (Use standard input if FNAME==NULL.)
- * Return 1 on success, 0 on failure.
- */
-
-int
-cpp_start_read (pfile, fname)
- cpp_reader *pfile;
- char *fname;
-{
- struct cpp_options *opts = CPP_OPTIONS (pfile);
- struct cpp_pending *pend;
- char *p;
- int f;
- cpp_buffer *fp;
-
- /* The code looks at the defaults through this pointer, rather than through
- the constant structure above. This pointer gets changed if an environment
- variable specifies other defaults. */
- struct default_include *include_defaults = include_defaults_array;
-
- /* Add dirs from CPATH after dirs from -I. */
- /* There seems to be confusion about what CPATH should do,
- so for the moment it is not documented. */
- /* Some people say that CPATH should replace the standard include dirs,
- but that seems pointless: it comes before them, so it overrides them
- anyway. */
- GET_ENV_PATH_LIST (p, "CPATH");
- if (p != 0 && ! opts->no_standard_includes)
- path_include (pfile, p);
-
- /* Now that dollars_in_ident is known, initialize is_idchar. */
- initialize_char_syntax (opts);
-
- /* Do partial setup of input buffer for the sake of generating
- early #line directives (when -g is in effect). */
- fp = cpp_push_buffer (pfile, NULL, 0);
- if (!fp)
- return 0;
- if (opts->in_fname == NULL)
- opts->in_fname = "";
- fp->nominal_fname = fp->fname = opts->in_fname;
- fp->lineno = 0;
-
- /* Install __LINE__, etc. Must follow initialize_char_syntax
- and option processing. */
- initialize_builtins (pfile);
-
- /* Do standard #defines and assertions
- that identify system and machine type. */
-
- if (!opts->inhibit_predefs) {
- char *p = (char *) alloca (strlen (predefs) + 1);
- strcpy (p, predefs);
- while (*p) {
- char *q;
- while (*p == ' ' || *p == '\t')
- p++;
- /* Handle -D options. */
- if (p[0] == '-' && p[1] == 'D') {
- q = &p[2];
- while (*p && *p != ' ' && *p != '\t')
- p++;
- if (*p != 0)
- *p++= 0;
- if (opts->debug_output)
- output_line_command (pfile, 0, same_file);
- cpp_define (pfile, q);
- while (*p == ' ' || *p == '\t')
- p++;
- } else if (p[0] == '-' && p[1] == 'A') {
- /* Handle -A options (assertions). */
- char *assertion;
- char *past_name;
- char *value;
- char *past_value;
- char *termination;
- int save_char;
-
- assertion = &p[2];
- past_name = assertion;
- /* Locate end of name. */
- while (*past_name && *past_name != ' '
- && *past_name != '\t' && *past_name != '(')
- past_name++;
- /* Locate `(' at start of value. */
- value = past_name;
- while (*value && (*value == ' ' || *value == '\t'))
- value++;
- if (*value++ != '(')
- abort ();
- while (*value && (*value == ' ' || *value == '\t'))
- value++;
- past_value = value;
- /* Locate end of value. */
- while (*past_value && *past_value != ' '
- && *past_value != '\t' && *past_value != ')')
- past_value++;
- termination = past_value;
- while (*termination && (*termination == ' ' || *termination == '\t'))
- termination++;
- if (*termination++ != ')')
- abort ();
- if (*termination && *termination != ' ' && *termination != '\t')
- abort ();
- /* Temporarily null-terminate the value. */
- save_char = *termination;
- *termination = '\0';
- /* Install the assertion. */
- make_assertion (pfile, "-A", assertion);
- *termination = (char) save_char;
- p = termination;
- while (*p == ' ' || *p == '\t')
- p++;
- } else {
- abort ();
- }
- }
- }
-
- /* Now handle the command line options. */
-
- /* Do -U's, -D's and -A's in the order they were seen. */
- /* First reverse the list. */
- opts->pending = nreverse_pending (opts->pending);
-
- for (pend = opts->pending; pend; pend = pend->next)
- {
- if (pend->cmd != NULL && pend->cmd[0] == '-')
- {
- switch (pend->cmd[1])
- {
- case 'U':
- if (opts->debug_output)
- output_line_command (pfile, 0, same_file);
- do_undef (pfile, NULL, pend->arg, pend->arg + strlen (pend->arg));
- break;
- case 'D':
- if (opts->debug_output)
- output_line_command (pfile, 0, same_file);
- cpp_define (pfile, pend->arg);
- break;
- case 'A':
- make_assertion (pfile, "-A", pend->arg);
- break;
- }
- }
- }
-
- opts->done_initializing = 1;
-
- { /* Read the appropriate environment variable and if it exists
- replace include_defaults with the listed path. */
- char *epath = 0;
- switch ((opts->objc << 1) + opts->cplusplus)
- {
- case 0:
- GET_ENV_PATH_LIST (epath, "C_INCLUDE_PATH");
- break;
- case 1:
- GET_ENV_PATH_LIST (epath, "CPLUS_INCLUDE_PATH");
- break;
- case 2:
- GET_ENV_PATH_LIST (epath, "OBJC_INCLUDE_PATH");
- break;
- case 3:
- GET_ENV_PATH_LIST (epath, "OBJCPLUS_INCLUDE_PATH");
- break;
- }
- /* If the environment var for this language is set,
- add to the default list of include directories. */
- if (epath) {
- char *nstore = (char *) alloca (strlen (epath) + 2);
- int num_dirs;
- char *startp, *endp;
-
- for (num_dirs = 1, startp = epath; *startp; startp++)
- if (*startp == PATH_SEPARATOR)
- num_dirs++;
- include_defaults
- = (struct default_include *) xmalloc ((num_dirs
- * sizeof (struct default_include))
- + sizeof (include_defaults_array));
- startp = endp = epath;
- num_dirs = 0;
- while (1) {
- /* Handle cases like c:/usr/lib:d:/gcc/lib */
- if ((*endp == PATH_SEPARATOR)
- || *endp == 0) {
- strncpy (nstore, startp, endp-startp);
- if (endp == startp)
- strcpy (nstore, ".");
- else
- nstore[endp-startp] = '\0';
-
- include_defaults[num_dirs].fname = savestring (nstore);
- include_defaults[num_dirs].component = 0;
- include_defaults[num_dirs].cplusplus = opts->cplusplus;
- include_defaults[num_dirs].cxx_aware = 1;
- num_dirs++;
- if (*endp == '\0')
- break;
- endp = startp = endp + 1;
- } else
- endp++;
- }
- /* Put the usual defaults back in at the end. */
- bcopy ((char *) include_defaults_array,
- (char *) &include_defaults[num_dirs],
- sizeof (include_defaults_array));
- }
- }
-
- append_include_chain (pfile, opts->before_system, opts->last_before_system);
- opts->first_system_include = opts->before_system;
-
- /* Unless -fnostdinc,
- tack on the standard include file dirs to the specified list */
- if (!opts->no_standard_includes) {
- struct default_include *p = include_defaults;
- char *specd_prefix = opts->include_prefix;
- char *default_prefix = savestring (GCC_INCLUDE_DIR);
- int default_len = 0;
- /* Remove the `include' from /usr/local/lib/gcc.../include. */
- if (!strcmp (default_prefix + strlen (default_prefix) - 8, "/include")) {
- default_len = strlen (default_prefix) - 7;
- default_prefix[default_len] = 0;
- }
- /* Search "translated" versions of GNU directories.
- These have /usr/local/lib/gcc... replaced by specd_prefix. */
- if (specd_prefix != 0 && default_len != 0)
- for (p = include_defaults; p->fname; p++) {
- /* Some standard dirs are only for C++. */
- if (!p->cplusplus
- || (opts->cplusplus && !opts->no_standard_cplusplus_includes)) {
- /* Does this dir start with the prefix? */
- if (!strncmp (p->fname, default_prefix, default_len)) {
- /* Yes; change prefix and add to search list. */
- struct file_name_list *new
- = (struct file_name_list *) xmalloc (sizeof (struct file_name_list));
- int this_len = strlen (specd_prefix) + strlen (p->fname) - default_len;
- char *str = (char *) xmalloc (this_len + 1);
- strcpy (str, specd_prefix);
- strcat (str, p->fname + default_len);
- new->fname = str;
- new->control_macro = 0;
- new->c_system_include_path = !p->cxx_aware;
- new->got_name_map = 0;
- append_include_chain (pfile, new, new);
- if (opts->first_system_include == 0)
- opts->first_system_include = new;
- }
- }
- }
- /* Search ordinary names for GNU include directories. */
- for (p = include_defaults; p->fname; p++) {
- /* Some standard dirs are only for C++. */
- if (!p->cplusplus
- || (opts->cplusplus && !opts->no_standard_cplusplus_includes)) {
- struct file_name_list *new
- = (struct file_name_list *) xmalloc (sizeof (struct file_name_list));
- new->control_macro = 0;
- new->c_system_include_path = !p->cxx_aware;
- new->fname = update_path (p->fname, p->component);
- new->got_name_map = 0;
- append_include_chain (pfile, new, new);
- if (opts->first_system_include == 0)
- opts->first_system_include = new;
- }
- }
- }
-
- /* Tack the after_include chain at the end of the include chain. */
- append_include_chain (pfile, opts->after_include, opts->last_after_include);
- if (opts->first_system_include == 0)
- opts->first_system_include = opts->after_include;
-
- /* With -v, print the list of dirs to search. */
- if (opts->verbose) {
- struct file_name_list *p;
- fprintf (stderr, "#include \"...\" search starts here:\n");
- for (p = opts->include; p; p = p->next) {
- if (p == opts->first_bracket_include)
- fprintf (stderr, "#include <...> search starts here:\n");
- fprintf (stderr, " %s\n", p->fname);
- }
- fprintf (stderr, "End of search list.\n");
- }
-
- /* Copy the entire contents of the main input file into
- the stacked input buffer previously allocated for it. */
- if (fname == NULL || *fname == 0) {
- fname = "";
- f = 0;
- } else if ((f = open (fname, O_RDONLY, 0666)) < 0)
- cpp_pfatal_with_name (pfile, fname);
-
- /* -MG doesn't select the form of output and must be specified with one of
- -M or -MM. -MG doesn't make sense with -MD or -MMD since they don't
- inhibit compilation. */
- if (opts->print_deps_missing_files
- && (opts->print_deps == 0 || !opts->no_output))
+ c = PEEKC();
+ if (c != '(')
{
- cpp_fatal (pfile, "-MG must be specified with one of -M or -MM");
- return 0;
+ if (is_hor_space[c] || c == '\r')
+ cpp_skip_hspace (pfile);
+ c = PEEKC();
}
+ if (c != '(')
+ return 1;
- /* Either of two environment variables can specify output of deps.
- Its value is either "OUTPUT_FILE" or "OUTPUT_FILE DEPS_TARGET",
- where OUTPUT_FILE is the file to write deps info to
- and DEPS_TARGET is the target to mention in the deps. */
-
- if (opts->print_deps == 0
- && (getenv ("SUNPRO_DEPENDENCIES") != 0
- || getenv ("DEPENDENCIES_OUTPUT") != 0)) {
- char *spec = getenv ("DEPENDENCIES_OUTPUT");
- char *s;
- char *output_file;
-
- if (spec == 0)
- {
- spec = getenv ("SUNPRO_DEPENDENCIES");
- opts->print_deps = 2;
- }
- else
- opts->print_deps = 1;
-
- s = spec;
- /* Find the space before the DEPS_TARGET, if there is one. */
- /* This should use index. (mrs) */
- while (*s != 0 && *s != ' ') s++;
- if (*s != 0)
- {
- opts->deps_target = s + 1;
- output_file = (char *) xmalloc (s - spec + 1);
- bcopy (spec, output_file, s - spec);
- output_file[s - spec] = 0;
- }
- else
- {
- opts->deps_target = 0;
- output_file = spec;
- }
-
- opts->deps_file = output_file;
- opts->print_deps_append = 1;
- }
-
- /* For -M, print the expected object file name
- as the target of this Make-rule. */
- if (opts->print_deps)
+ CPP_PUTC(pfile, '(');
+ FORWARD(1);
+ dropwhite = 1;
+ while ((c = GETC()) != ')')
{
- pfile->deps_allocated_size = 200;
- pfile->deps_buffer = (char *) xmalloc (pfile->deps_allocated_size);
- pfile->deps_buffer[0] = 0;
- pfile->deps_size = 0;
- pfile->deps_column = 0;
-
- if (opts->deps_target)
- deps_output (pfile, opts->deps_target, ':');
- else if (*opts->in_fname == 0)
- deps_output (pfile, "-", ':');
- else
+ if (is_hor_space[c])
{
- char *p, *q, *r;
- int len, x;
- static char *known_suffixes[] = { ".c", ".C", ".s", ".S", ".m",
- ".cc", ".cxx", ".cpp", ".cp",
- ".c++", 0
- };
-
- /* Discard all directory prefixes from filename. */
- if ((q = rindex (opts->in_fname, '/')) != NULL
-#ifdef DIR_SEPARATOR
- && (q = rindex (opts->in_fname, DIR_SEPARATOR)) != NULL
-#endif
- )
- ++q;
- else
- q = opts->in_fname;
-
- /* Copy remainder to mungable area. */
- p = (char *) alloca (strlen(q) + 8);
- strcpy (p, q);
-
- /* Output P, but remove known suffixes. */
- len = strlen (p);
- q = p + len;
- /* Point to the filename suffix. */
- r = rindex (p, '.');
- /* Compare against the known suffixes. */
- x = 0;
- while (known_suffixes[x] != 0)
+ if (! dropwhite)
{
- if (strncmp (known_suffixes[x], r, q - r) == 0)
- {
- /* Make q point to the bit we're going to overwrite
- with an object suffix. */
- q = r;
- break;
- }
- x++;
+ CPP_PUTC(pfile, ' ');
+ dropwhite = 1;
}
-
- /* Supply our own suffix. */
-#ifndef VMS
- strcpy (q, ".o");
-#else
- strcpy (q, ".obj");
-#endif
-
- deps_output (pfile, p, ':');
- deps_output (pfile, opts->in_fname, ' ');
}
- }
-
-#if 0
- /* Make sure data ends with a newline. And put a null after it. */
-
- if ((fp->length > 0 && fp->buf[fp->length - 1] != '\n')
- /* Backslash-newline at end is not good enough. */
- || (fp->length > 1 && fp->buf[fp->length - 2] == '\\')) {
- fp->buf[fp->length++] = '\n';
- missing_newline = 1;
- }
- fp->buf[fp->length] = '\0';
-
- /* Unless inhibited, convert trigraphs in the input. */
-
- if (!no_trigraphs)
- trigraph_pcp (fp);
-#endif
-
- /* Avoid a #line 0 if -include files are present. */
- CPP_BUFFER (pfile)->lineno = 1;
- output_line_command (pfile, 0, same_file);
-
- /* Scan the -include and -imacros files before the main input. */
-
- pfile->no_record_file++;
- for (pend = opts->pending; pend; pend = pend->next)
- {
- if (pend->cmd != NULL)
- {
- if (strcmp (pend->cmd, "-include") == 0)
- {
- int fd = open (pend->arg, O_RDONLY, 0666);
- if (fd < 0)
- {
- cpp_perror_with_name (pfile, pend->arg);
- return 0;
- }
- if (!cpp_push_buffer (pfile, NULL, 0))
- return 0;
- if (finclude (pfile, fd, pend->arg, 0, NULL_PTR))
- {
- output_line_command (pfile, 0, enter_file);
- cpp_scan_buffer (pfile);
- }
- }
- else if (strcmp (pend->cmd, "-imacros") == 0)
- {
- int fd = open (pend->arg, O_RDONLY, 0666);
- if (fd < 0)
- {
- cpp_perror_with_name (pfile, pend->arg);
- return 0;
- }
- opts->no_output++;
- if (!cpp_push_buffer (pfile, NULL, 0))
- return 0;
- if (finclude (pfile, fd, pend->arg, 0, NULL_PTR))
- cpp_scan_buffer (pfile);
- opts->no_output--;
- }
- }
- }
- pfile->no_record_file--;
-
- /* Free the pending list. */
- for (pend = opts->pending; pend; )
- {
- struct cpp_pending *next = pend->next;
- free (pend);
- pend = next;
- }
- opts->pending = NULL;
-
-#if 0
- /* Scan the input, processing macros and directives. */
-
- rescan (&outbuf, 0);
-
- if (missing_newline)
- fp->lineno--;
-
- if (CPP_PEDANTIC (pfile) && missing_newline)
- pedwarn ("file does not end in newline");
-
-#endif
- finclude (pfile, f, fname, 0, NULL_PTR);
- return 1;
-}
-
-void
-cpp_reader_init (pfile)
- cpp_reader *pfile;
-{
- bzero ((char *) pfile, sizeof (cpp_reader));
- pfile->get_token = cpp_get_token;
-
- pfile->token_buffer_size = 200;
- pfile->token_buffer = (U_CHAR *) xmalloc (pfile->token_buffer_size);
- CPP_SET_WRITTEN (pfile, 0);
-
- pfile->system_include_depth = 0;
- pfile->dont_repeat_files = 0;
- pfile->all_include_files = 0;
- pfile->max_include_len = 0;
- pfile->timebuf = NULL;
- pfile->only_seen_white = 1;
- pfile->buffer = CPP_NULL_BUFFER(pfile);
-}
-
-static struct cpp_pending *
-nreverse_pending (list)
- struct cpp_pending *list;
-
-{
- register struct cpp_pending *prev = 0, *next, *pend;
- for (pend = list; pend; pend = next)
- {
- next = pend->next;
- pend->next = prev;
- prev = pend;
- }
- return prev;
-}
-
-static void
-push_pending (pfile, cmd, arg)
- cpp_reader *pfile;
- char *cmd;
- char *arg;
-{
- struct cpp_pending *pend
- = (struct cpp_pending *) xmalloc (sizeof (struct cpp_pending));
- pend->cmd = cmd;
- pend->arg = arg;
- pend->next = CPP_OPTIONS (pfile)->pending;
- CPP_OPTIONS (pfile)->pending = pend;
-}
-
-
-static void
-print_help ()
-{
- printf ("Usage: %s [switches] input output\n", progname);
- printf ("Switches:\n");
- printf (" -include <file> Include the contents of <file> before other files\n");
- printf (" -imacros <file> Accept definition of marcos in <file>\n");
- printf (" -iprefix <path> Specify <path> as a prefix for next two options\n");
- printf (" -iwithprefix <dir> Add <dir> to the end of the system include paths\n");
- printf (" -iwithprefixbefore <dir> Add <dir> to the end of the main include paths\n");
- printf (" -isystem <dir> Add <dir> to the start of the system include paths\n");
- printf (" -idirafter <dir> Add <dir> to the end of the system include paths\n");
- printf (" -I <dir> Add <dir> to the end of the main include paths\n");
- printf (" -nostdinc Do not search the system include directories\n");
- printf (" -nostdinc++ Do not search the system include directories for C++\n");
- printf (" -o <file> Put output into <file>\n");
- printf (" -pedantic Issue all warnings demanded by strict ANSI C\n");
- printf (" -traditional Follow K&R pre-processor behaviour\n");
- printf (" -trigraphs Support ANSI C trigraphs\n");
- printf (" -lang-c Assume that the input sources are in C\n");
- printf (" -lang-c89 Assume that the input sources are in C89\n");
- printf (" -lang-c++ Assume that the input sources are in C++\n");
- printf (" -lang-objc Assume that the input sources are in ObjectiveC\n");
- printf (" -lang-objc++ Assume that the input sources are in ObjectiveC++\n");
- printf (" -lang-asm Assume that the input sources are in assembler\n");
- printf (" -lang-chill Assume that the input sources are in Chill\n");
- printf (" -+ Allow parsing of C++ style features\n");
- printf (" -w Inhibit warning messages\n");
- printf (" -Wtrigraphs Warn if trigraphs are encountered\n");
- printf (" -Wno-trigraphs Do not warn about trigraphs\n");
- printf (" -Wcomment{s} Warn if one comment starts inside another\n");
- printf (" -Wno-comment{s} Do not warn about comments\n");
- printf (" -Wtraditional Warn if a macro argument is/would be turned into\n");
- printf (" a string if -tradtional is specified\n");
- printf (" -Wno-traditional Do not warn about stringification\n");
- printf (" -Wundef Warn if an undefined macro is used by #if\n");
- printf (" -Wno-undef Do not warn about testing udefined macros\n");
- printf (" -Wimport Warn about the use of the #import directive\n");
- printf (" -Wno-import Do not warn about the use of #import\n");
- printf (" -Werror Treat all warnings as errors\n");
- printf (" -Wno-error Do not treat warnings as errors\n");
- printf (" -Wall Enable all preprocessor warnings\n");
- printf (" -M Generate make dependencies\n");
- printf (" -MM As -M, but ignore system header files\n");
- printf (" -MD As -M, but put output in a .d file\n");
- printf (" -MMD As -MD, but ignore system header files\n");
- printf (" -MG Treat missing header file as generated files\n");
- printf (" -g Include #define and #undef directives in the output\n");
- printf (" -D<macro> Define a <macro> with string '1' as its value\n");
- printf (" -D<macro>=<val> Define a <macro> with <val> as its value\n");
- printf (" -A<question> (<answer>) Assert the <answer> to <question>\n");
- printf (" -U<macro> Undefine <macro> \n");
- printf (" -u or -undef Do not predefine any macros\n");
- printf (" -v Display the version number\n");
- printf (" -H Print the name of header files as they are used\n");
- printf (" -C Do not discard comments\n");
- printf (" -dM Display a list of macro definitions active at end\n");
- printf (" -dD Preserve macro definitions in output\n");
- printf (" -dN As -dD except that only the names are preserved\n");
- printf (" -dI Include #include directives in the output\n");
- printf (" -ifoutput Describe skipped code blocks in output \n");
- printf (" -P Do not generate #line directives\n");
- printf (" -$ Do not include '$' in identifiers\n");
- printf (" -remap Remap file names when including files.\n");
- printf (" -h or --help Display this information\n");
-}
-
-
-/* Handle one command-line option in (argc, argv).
- Can be called multiple times, to handle multiple sets of options.
- Returns number of strings consumed. */
-int
-cpp_handle_option (pfile, argc, argv)
- cpp_reader *pfile;
- int argc;
- char **argv;
-{
- struct cpp_options *opts = CPP_OPTIONS (pfile);
- int i = 0;
- if (argv[i][0] != '-') {
- if (opts->out_fname != NULL)
- {
- print_help ();
- cpp_fatal (pfile, "Too many arguments");
- }
- else if (opts->in_fname != NULL)
- opts->out_fname = argv[i];
- else
- opts->in_fname = argv[i];
- } else {
- switch (argv[i][1]) {
-
- missing_filename:
- cpp_fatal (pfile, "Filename missing after `%s' option", argv[i]);
- return argc;
- missing_dirname:
- cpp_fatal (pfile, "Directory name missing after `%s' option", argv[i]);
- return argc;
-
- case 'i':
- if (!strcmp (argv[i], "-include")
- || !strcmp (argv[i], "-imacros")) {
- if (i + 1 == argc)
- goto missing_filename;
- else
- push_pending (pfile, argv[i], argv[i+1]), i++;
- }
- if (!strcmp (argv[i], "-iprefix")) {
- if (i + 1 == argc)
- goto missing_filename;
- else
- opts->include_prefix = argv[++i];
- }
- if (!strcmp (argv[i], "-ifoutput")) {
- opts->output_conditionals = 1;
- }
- if (!strcmp (argv[i], "-isystem")) {
- struct file_name_list *dirtmp;
-
- if (i + 1 == argc)
- goto missing_filename;
-
- dirtmp = (struct file_name_list *)
- xmalloc (sizeof (struct file_name_list));
- dirtmp->next = 0;
- dirtmp->control_macro = 0;
- dirtmp->c_system_include_path = 1;
- dirtmp->fname = (char *) xmalloc (strlen (argv[i+1]) + 1);
- strcpy (dirtmp->fname, argv[++i]);
- dirtmp->got_name_map = 0;
-
- if (opts->before_system == 0)
- opts->before_system = dirtmp;
- else
- opts->last_before_system->next = dirtmp;
- opts->last_before_system = dirtmp; /* Tail follows the last one */
- }
- /* Add directory to end of path for includes,
- with the default prefix at the front of its name. */
- if (!strcmp (argv[i], "-iwithprefix")) {
- struct file_name_list *dirtmp;
- char *prefix;
-
- if (opts->include_prefix != 0)
- prefix = opts->include_prefix;
- else {
- prefix = savestring (GCC_INCLUDE_DIR);
- /* Remove the `include' from /usr/local/lib/gcc.../include. */
- if (!strcmp (prefix + strlen (prefix) - 8, "/include"))
- prefix[strlen (prefix) - 7] = 0;
- }
-
- dirtmp = (struct file_name_list *)
- xmalloc (sizeof (struct file_name_list));
- dirtmp->next = 0; /* New one goes on the end */
- dirtmp->control_macro = 0;
- dirtmp->c_system_include_path = 0;
- if (i + 1 == argc)
- goto missing_dirname;
-
- dirtmp->fname = (char *) xmalloc (strlen (argv[i+1])
- + strlen (prefix) + 1);
- strcpy (dirtmp->fname, prefix);
- strcat (dirtmp->fname, argv[++i]);
- dirtmp->got_name_map = 0;
-
- if (opts->after_include == 0)
- opts->after_include = dirtmp;
- else
- opts->last_after_include->next = dirtmp;
- opts->last_after_include = dirtmp; /* Tail follows the last one */
- }
- /* Add directory to main path for includes,
- with the default prefix at the front of its name. */
- if (!strcmp (argv[i], "-iwithprefixbefore")) {
- struct file_name_list *dirtmp;
- char *prefix;
-
- if (opts->include_prefix != 0)
- prefix = opts->include_prefix;
- else {
- prefix = savestring (GCC_INCLUDE_DIR);
- /* Remove the `include' from /usr/local/lib/gcc.../include. */
- if (!strcmp (prefix + strlen (prefix) - 8, "/include"))
- prefix[strlen (prefix) - 7] = 0;
- }
-
- dirtmp = (struct file_name_list *)
- xmalloc (sizeof (struct file_name_list));
- dirtmp->next = 0; /* New one goes on the end */
- dirtmp->control_macro = 0;
- dirtmp->c_system_include_path = 0;
- if (i + 1 == argc)
- goto missing_dirname;
-
- dirtmp->fname = (char *) xmalloc (strlen (argv[i+1])
- + strlen (prefix) + 1);
- strcpy (dirtmp->fname, prefix);
- strcat (dirtmp->fname, argv[++i]);
- dirtmp->got_name_map = 0;
-
- append_include_chain (pfile, dirtmp, dirtmp);
- }
- /* Add directory to end of path for includes. */
- if (!strcmp (argv[i], "-idirafter")) {
- struct file_name_list *dirtmp;
-
- dirtmp = (struct file_name_list *)
- xmalloc (sizeof (struct file_name_list));
- dirtmp->next = 0; /* New one goes on the end */
- dirtmp->control_macro = 0;
- dirtmp->c_system_include_path = 0;
- if (i + 1 == argc)
- goto missing_dirname;
- else
- dirtmp->fname = argv[++i];
- dirtmp->got_name_map = 0;
-
- if (opts->after_include == 0)
- opts->after_include = dirtmp;
- else
- opts->last_after_include->next = dirtmp;
- opts->last_after_include = dirtmp; /* Tail follows the last one */
- }
- break;
-
- case 'o':
- if (opts->out_fname != NULL)
- {
- cpp_fatal (pfile, "Output filename specified twice");
- return argc;
- }
- if (i + 1 == argc)
- goto missing_filename;
- opts->out_fname = argv[++i];
- if (!strcmp (opts->out_fname, "-"))
- opts->out_fname = "";
- break;
-
- case 'p':
- if (!strcmp (argv[i], "-pedantic"))
- CPP_PEDANTIC (pfile) = 1;
- else if (!strcmp (argv[i], "-pedantic-errors")) {
- CPP_PEDANTIC (pfile) = 1;
- opts->pedantic_errors = 1;
- }
-#if 0
- else if (!strcmp (argv[i], "-pcp")) {
- char *pcp_fname = argv[++i];
- pcp_outfile = ((pcp_fname[0] != '-' || pcp_fname[1] != '\0')
- ? fopen (pcp_fname, "w")
- : fdopen (dup (fileno (stdout)), "w"));
- if (pcp_outfile == 0)
- cpp_pfatal_with_name (pfile, pcp_fname);
- no_precomp = 1;
- }
-#endif
- break;
-
- case 't':
- if (!strcmp (argv[i], "-traditional")) {
- opts->traditional = 1;
- opts->cplusplus_comments = 0;
- } else if (!strcmp (argv[i], "-trigraphs")) {
- if (!opts->chill)
- opts->no_trigraphs = 0;
- }
- break;
-
- case 'l':
- if (! strcmp (argv[i], "-lang-c"))
- opts->cplusplus = 0, opts->cplusplus_comments = 1, opts->c89 = 0,
- opts->objc = 0;
- if (! strcmp (argv[i], "-lang-c89"))
- opts->cplusplus = 0, opts->cplusplus_comments = 0, opts->c89 = 1,
- opts->objc = 0;
- if (! strcmp (argv[i], "-lang-c++"))
- opts->cplusplus = 1, opts->cplusplus_comments = 1, opts->c89 = 0,
- opts->objc = 0;
- if (! strcmp (argv[i], "-lang-objc"))
- opts->cplusplus = 0, opts->cplusplus_comments = 1, opts->c89 = 0,
- opts->objc = 1;
- if (! strcmp (argv[i], "-lang-objc++"))
- opts->cplusplus = 1, opts->cplusplus_comments = 1, opts->c89 = 0,
- opts->objc = 1;
- if (! strcmp (argv[i], "-lang-asm"))
- opts->lang_asm = 1;
- if (! strcmp (argv[i], "-lint"))
- opts->for_lint = 1;
- if (! strcmp (argv[i], "-lang-chill"))
- opts->objc = 0, opts->cplusplus = 0, opts->chill = 1,
- opts->traditional = 1, opts->no_trigraphs = 1;
- break;
-
- case '+':
- opts->cplusplus = 1, opts->cplusplus_comments = 1;
- break;
-
- case 'w':
- opts->inhibit_warnings = 1;
- break;
-
- case 'W':
- if (!strcmp (argv[i], "-Wtrigraphs"))
- opts->warn_trigraphs = 1;
- else if (!strcmp (argv[i], "-Wno-trigraphs"))
- opts->warn_trigraphs = 0;
- else if (!strcmp (argv[i], "-Wcomment"))
- opts->warn_comments = 1;
- else if (!strcmp (argv[i], "-Wno-comment"))
- opts->warn_comments = 0;
- else if (!strcmp (argv[i], "-Wcomments"))
- opts->warn_comments = 1;
- else if (!strcmp (argv[i], "-Wno-comments"))
- opts->warn_comments = 0;
- else if (!strcmp (argv[i], "-Wtraditional"))
- opts->warn_stringify = 1;
- else if (!strcmp (argv[i], "-Wno-traditional"))
- opts->warn_stringify = 0;
- else if (!strcmp (argv[i], "-Wundef"))
- opts->warn_undef = 1;
- else if (!strcmp (argv[i], "-Wno-undef"))
- opts->warn_undef = 0;
- else if (!strcmp (argv[i], "-Wimport"))
- opts->warn_import = 1;
- else if (!strcmp (argv[i], "-Wno-import"))
- opts->warn_import = 0;
- else if (!strcmp (argv[i], "-Werror"))
- opts->warnings_are_errors = 1;
- else if (!strcmp (argv[i], "-Wno-error"))
- opts->warnings_are_errors = 0;
- else if (!strcmp (argv[i], "-Wall"))
- {
- opts->warn_trigraphs = 1;
- opts->warn_comments = 1;
- }
- break;
-
- case 'M':
- /* The style of the choices here is a bit mixed.
- The chosen scheme is a hybrid of keeping all options in one string
- and specifying each option in a separate argument:
- -M|-MM|-MD file|-MMD file [-MG]. An alternative is:
- -M|-MM|-MD file|-MMD file|-MG|-MMG; or more concisely:
- -M[M][G][D file]. This is awkward to handle in specs, and is not
- as extensible. */
- /* ??? -MG must be specified in addition to one of -M or -MM.
- This can be relaxed in the future without breaking anything.
- The converse isn't true. */
-
- /* -MG isn't valid with -MD or -MMD. This is checked for later. */
- if (!strcmp (argv[i], "-MG"))
- {
- opts->print_deps_missing_files = 1;
- break;
- }
- if (!strcmp (argv[i], "-M"))
- opts->print_deps = 2;
- else if (!strcmp (argv[i], "-MM"))
- opts->print_deps = 1;
- else if (!strcmp (argv[i], "-MD"))
- opts->print_deps = 2;
- else if (!strcmp (argv[i], "-MMD"))
- opts->print_deps = 1;
- /* For -MD and -MMD options, write deps on file named by next arg. */
- if (!strcmp (argv[i], "-MD") || !strcmp (argv[i], "-MMD"))
- {
- if (i+1 == argc)
- goto missing_filename;
- opts->deps_file = argv[++i];
- }
- else
- {
- /* For -M and -MM, write deps on standard output
- and suppress the usual output. */
- opts->no_output = 1;
- }
- break;
-
- case 'd':
- {
- char *p = argv[i] + 2;
- char c;
- while ((c = *p++) != 0) {
- /* Arg to -d specifies what parts of macros to dump */
- switch (c) {
- case 'M':
- opts->dump_macros = dump_only;
- opts->no_output = 1;
- break;
- case 'N':
- opts->dump_macros = dump_names;
- break;
- case 'D':
- opts->dump_macros = dump_definitions;
- break;
- case 'I':
- opts->dump_includes = 1;
- break;
- }
- }
- }
- break;
-
- case 'g':
- if (argv[i][2] == '3')
- opts->debug_output = 1;
- break;
-
- case '-':
- if (strcmp (argv[i], "--help") != 0)
- return i;
- print_help ();
- break;
-
- case 'v':
- fprintf (stderr, "GNU CPP version %s", version_string);
-#ifdef TARGET_VERSION
- TARGET_VERSION;
-#endif
- fprintf (stderr, "\n");
- opts->verbose = 1;
- break;
-
- case 'H':
- opts->print_include_names = 1;
- break;
-
- case 'D':
- if (argv[i][2] != 0)
- push_pending (pfile, "-D", argv[i] + 2);
- else if (i + 1 == argc)
+ else if (c == '\n' || c == EOF)
{
- cpp_fatal (pfile, "Macro name missing after -D option");
- return argc;
+ if (c == '\n') FORWARD(-1);
+ cpp_error (pfile, "un-terminated assertion answer");
+ return 0;
}
+ else if (c == '\r')
+ CPP_BUMP_LINE (pfile);
else
- i++, push_pending (pfile, "-D", argv[i]);
- break;
-
- case 'A':
- {
- char *p;
-
- if (argv[i][2] != 0)
- p = argv[i] + 2;
- else if (i + 1 == argc)
- {
- cpp_fatal (pfile, "Assertion missing after -A option");
- return argc;
- }
- else
- p = argv[++i];
-
- if (!strcmp (p, "-")) {
- struct cpp_pending **ptr;
- /* -A- eliminates all predefined macros and assertions.
- Let's include also any that were specified earlier
- on the command line. That way we can get rid of any
- that were passed automatically in from GCC. */
- opts->inhibit_predefs = 1;
- for (ptr = &opts->pending; *ptr != NULL; )
- {
- struct cpp_pending *pend = *ptr;
- if (pend->cmd && pend->cmd[0] == '-'
- && (pend->cmd[1] == 'D' || pend->cmd[1] == 'A'))
- {
- *ptr = pend->next;
- free (pend);
- }
- else
- ptr = &pend->next;
- }
- } else {
- push_pending (pfile, "-A", p);
- }
- }
- break;
-
- case 'U': /* JF #undef something */
- if (argv[i][2] != 0)
- push_pending (pfile, "-U", argv[i] + 2);
- else if (i + 1 == argc)
{
- cpp_fatal (pfile, "Macro name missing after -U option");
- return argc;
- }
- else
- push_pending (pfile, "-U", argv[i+1]), i++;
- break;
-
- case 'C':
- opts->put_out_comments = 1;
- break;
-
- case 'E': /* -E comes from cc -E; ignore it. */
- break;
-
- case 'P':
- opts->no_line_commands = 1;
- break;
-
- case '$': /* Don't include $ in identifiers. */
- opts->dollars_in_ident = 0;
- break;
-
- case 'I': /* Add directory to path for includes. */
- {
- struct file_name_list *dirtmp;
-
- if (! CPP_OPTIONS(pfile)->ignore_srcdir
- && !strcmp (argv[i] + 2, "-")) {
- CPP_OPTIONS (pfile)->ignore_srcdir = 1;
- /* Don't use any preceding -I directories for #include <...>. */
- CPP_OPTIONS (pfile)->first_bracket_include = 0;
- }
- else {
- dirtmp = (struct file_name_list *)
- xmalloc (sizeof (struct file_name_list));
- dirtmp->next = 0; /* New one goes on the end */
- dirtmp->control_macro = 0;
- dirtmp->c_system_include_path = 0;
- if (argv[i][2] != 0)
- dirtmp->fname = argv[i] + 2;
- else if (i + 1 == argc)
- goto missing_dirname;
- else
- dirtmp->fname = argv[++i];
- dirtmp->got_name_map = 0;
- append_include_chain (pfile, dirtmp, dirtmp);
+ CPP_PUTC (pfile, c);
+ dropwhite = 0;
}
- }
- break;
-
- case 'n':
- if (!strcmp (argv[i], "-nostdinc"))
- /* -nostdinc causes no default include directories.
- You must specify all include-file directories with -I. */
- opts->no_standard_includes = 1;
- else if (!strcmp (argv[i], "-nostdinc++"))
- /* -nostdinc++ causes no default C++-specific include directories. */
- opts->no_standard_cplusplus_includes = 1;
-#if 0
- else if (!strcmp (argv[i], "-noprecomp"))
- no_precomp = 1;
-#endif
- break;
-
- case 'r':
- if (!strcmp (argv[i], "-remap"))
- opts->remap = 1;
- break;
-
- case 'u':
- /* Sun compiler passes undocumented switch "-undef".
- Let's assume it means to inhibit the predefined symbols. */
- opts->inhibit_predefs = 1;
- break;
-
- case '\0': /* JF handle '-' as file name meaning stdin or stdout */
- if (opts->in_fname == NULL) {
- opts->in_fname = "";
- break;
- } else if (opts->out_fname == NULL) {
- opts->out_fname = "";
- break;
- } /* else fall through into error */
-
- default:
- return i;
}
- }
-
- return i + 1;
-}
-
-/* Handle command-line options in (argc, argv).
- Can be called multiple times, to handle multiple sets of options.
- Returns if an unrecognized option is seen.
- Returns number of strings consumed. */
-int
-cpp_handle_options (pfile, argc, argv)
- cpp_reader *pfile;
- int argc;
- char **argv;
-{
- int i;
- int strings_processed;
- for (i = 0; i < argc; i += strings_processed)
+ if (pfile->limit[-1] == ' ')
+ pfile->limit[-1] = ')';
+ else if (pfile->limit[-1] == '(')
{
- strings_processed = cpp_handle_option (pfile, argc - i, argv + i);
- if (strings_processed == 0)
- break;
+ cpp_error (pfile, "empty token sequence in assertion");
+ return 0;
}
- return i;
-}
-
-void
-cpp_finish (pfile)
- cpp_reader *pfile;
-{
- struct cpp_options *opts = CPP_OPTIONS (pfile);
-
- if (opts->print_deps)
- {
- /* Stream on which to print the dependency information. */
- FILE *deps_stream;
+ else
+ CPP_PUTC (pfile, ')');
- /* Don't actually write the deps file if compilation has failed. */
- if (pfile->errors == 0)
- {
- char *deps_mode = opts->print_deps_append ? "a" : "w";
- if (opts->deps_file == 0)
- deps_stream = stdout;
- else if ((deps_stream = fopen (opts->deps_file, deps_mode)) == 0)
- cpp_pfatal_with_name (pfile, opts->deps_file);
- fputs (pfile->deps_buffer, deps_stream);
- putc ('\n', deps_stream);
- if (opts->deps_file)
- {
- if (ferror (deps_stream) || fclose (deps_stream) != 0)
- cpp_fatal (pfile, "I/O error on output");
- }
- }
- }
+ CPP_NUL_TERMINATE (pfile);
+ return 2;
}
-/* Free resources used by PFILE.
- This is the cpp_reader 'finalizer' or 'destructor' (in C++ terminology). */
-
-void
-cpp_cleanup (pfile)
- cpp_reader *pfile;
-{
- int i;
- while ( CPP_BUFFER (pfile) != CPP_NULL_BUFFER (pfile))
- cpp_pop_buffer (pfile);
-
- if (pfile->token_buffer)
- {
- free (pfile->token_buffer);
- pfile->token_buffer = NULL;
- }
-
- if (pfile->deps_buffer)
- {
- free (pfile->deps_buffer);
- pfile->deps_buffer = NULL;
- pfile->deps_allocated_size = 0;
- }
-
- while (pfile->if_stack)
- {
- IF_STACK_FRAME *temp = pfile->if_stack;
- pfile->if_stack = temp->next;
- free (temp);
- }
-
- while (pfile->dont_repeat_files)
- {
- struct file_name_list *temp = pfile->dont_repeat_files;
- pfile->dont_repeat_files = temp->next;
- free (temp->fname);
- free (temp);
- }
-
- while (pfile->all_include_files)
- {
- struct file_name_list *temp = pfile->all_include_files;
- pfile->all_include_files = temp->next;
- free (temp->fname);
- free (temp);
- }
-
- for (i = IMPORT_HASH_SIZE; --i >= 0; )
- {
- register struct import_file *imp = pfile->import_hash_table[i];
- while (imp)
- {
- struct import_file *next = imp->next;
- free (imp->name);
- free (imp);
- imp = next;
- }
- pfile->import_hash_table[i] = 0;
- }
-
- for (i = ASSERTION_HASHSIZE; --i >= 0; )
- {
- while (pfile->assertion_hashtab[i])
- delete_assertion (pfile->assertion_hashtab[i]);
- }
-
- cpp_hash_cleanup (pfile);
-}
-
static int
-do_assert (pfile, keyword, buf, limit)
+do_assert (pfile, keyword)
cpp_reader *pfile;
struct directive *keyword ATTRIBUTE_UNUSED;
- U_CHAR *buf ATTRIBUTE_UNUSED, *limit ATTRIBUTE_UNUSED;
{
- long symstart; /* remember where symbol name starts */
- int c;
- int sym_length; /* and how long it is */
- struct arglist *tokens = NULL;
+ char *sym;
+ int ret, c;
+ HASHNODE *base, *this;
+ int baselen, thislen;
if (CPP_PEDANTIC (pfile) && CPP_OPTIONS (pfile)->done_initializing
&& !CPP_BUFFER (pfile)->system_header_p)
cpp_pedwarn (pfile, "ANSI C does not allow `#assert'");
cpp_skip_hspace (pfile);
- symstart = CPP_WRITTEN (pfile); /* remember where it starts */
- parse_name (pfile, GETC());
- sym_length = check_macro_name (pfile, pfile->token_buffer + symstart,
- "assertion");
-
- cpp_skip_hspace (pfile);
- if (PEEKC() != '(') {
- cpp_error (pfile, "missing token-sequence in `#assert'");
+ sym = (char *) CPP_PWRITTEN (pfile); /* remember where it starts */
+ ret = parse_assertion (pfile);
+ if (ret == 0)
goto error;
- }
-
- {
- int error_flag = 0;
- tokens = read_token_list (pfile, &error_flag);
- if (error_flag)
- goto error;
- if (tokens == 0) {
- cpp_error (pfile, "empty token-sequence in `#assert'");
+ else if (ret == 1)
+ {
+ cpp_error (pfile, "missing token-sequence in `#assert'");
goto error;
}
+
cpp_skip_hspace (pfile);
- c = PEEKC ();
+ c = PEEKC();
if (c != EOF && c != '\n')
- cpp_pedwarn (pfile, "junk at end of `#assert'");
- skip_rest_of_line (pfile);
- }
-
- /* If this name isn't already an assertion name, make it one.
- Error if it was already in use in some other way. */
+ {
+ cpp_error (pfile, "junk at end of `#assert'");
+ goto error;
+ }
- {
- ASSERTION_HASHNODE *hp;
- U_CHAR *symname = pfile->token_buffer + symstart;
- int hashcode = hashf (symname, sym_length, ASSERTION_HASHSIZE);
- struct tokenlist_list *value
- = (struct tokenlist_list *) xmalloc (sizeof (struct tokenlist_list));
-
- hp = assertion_lookup (pfile, symname, sym_length, hashcode);
- if (hp == NULL) {
- if (sym_length == 7 && ! strncmp (symname, "defined", sym_length))
- cpp_error (pfile, "`defined' redefined as assertion");
- hp = assertion_install (pfile, symname, sym_length, hashcode);
+ thislen = strlen (sym);
+ baselen = index (sym, '(') - sym;
+ this = cpp_lookup (pfile, sym, thislen, -1);
+ if (this)
+ {
+ cpp_warning (pfile, "`%s' re-asserted", sym);
+ goto error;
}
- /* Add the spec'd token-sequence to the list of such. */
- value->tokens = tokens;
- value->next = hp->value;
- hp->value = value;
+ base = cpp_lookup (pfile, sym, baselen, -1);
+ if (! base)
+ base = cpp_install (pfile, sym, baselen, T_ASSERT, 0, -1);
+ else if (base->type != T_ASSERT)
+ {
+ /* Token clash - but with what?! */
+ cpp_fatal (pfile,
+ "cpp internal error: base->type != T_ASSERT in do_assert");
+ goto error;
}
- CPP_SET_WRITTEN (pfile, symstart); /* Pop */
+
+ this = cpp_install (pfile, sym, thislen, T_ASSERT,
+ (char *)base->value.aschain, -1);
+ base->value.aschain = this;
+
+ pfile->limit = (unsigned char *) sym; /* Pop */
return 0;
+
error:
- CPP_SET_WRITTEN (pfile, symstart); /* Pop */
+ pfile->limit = (unsigned char *) sym; /* Pop */
skip_rest_of_line (pfile);
return 1;
}
-
+
static int
-do_unassert (pfile, keyword, buf, limit)
+do_unassert (pfile, keyword)
cpp_reader *pfile;
struct directive *keyword ATTRIBUTE_UNUSED;
- U_CHAR *buf ATTRIBUTE_UNUSED, *limit ATTRIBUTE_UNUSED;
{
- long symstart; /* remember where symbol name starts */
- int sym_length; /* and how long it is */
- int c;
-
- struct arglist *tokens = NULL;
- int tokens_specified = 0;
-
+ int c, ret;
+ char *sym;
+ long baselen, thislen;
+ HASHNODE *base, *this, *next;
+
if (CPP_PEDANTIC (pfile) && CPP_OPTIONS (pfile)->done_initializing
&& !CPP_BUFFER (pfile)->system_header_p)
cpp_pedwarn (pfile, "ANSI C does not allow `#unassert'");
cpp_skip_hspace (pfile);
- symstart = CPP_WRITTEN (pfile); /* remember where it starts */
- parse_name (pfile, GETC());
- sym_length = check_macro_name (pfile, pfile->token_buffer + symstart,
- "assertion");
-
- cpp_skip_hspace (pfile);
- if (PEEKC() == '(') {
- int error_flag = 0;
-
- tokens = read_token_list (pfile, &error_flag);
- if (error_flag)
- goto error;
- if (tokens == 0) {
- cpp_error (pfile, "empty token list in `#unassert'");
- goto error;
- }
-
- tokens_specified = 1;
- }
-
+ sym = (char *) CPP_PWRITTEN (pfile); /* remember where it starts */
+ ret = parse_assertion (pfile);
+ if (ret == 0)
+ goto error;
+
cpp_skip_hspace (pfile);
c = PEEKC ();
if (c != EOF && c != '\n')
cpp_error (pfile, "junk at end of `#unassert'");
- skip_rest_of_line (pfile);
-
- {
- ASSERTION_HASHNODE *hp;
- U_CHAR *symname = pfile->token_buffer + symstart;
- int hashcode = hashf (symname, sym_length, ASSERTION_HASHSIZE);
- struct tokenlist_list *tail, *prev;
- hp = assertion_lookup (pfile, symname, sym_length, hashcode);
- if (hp == NULL)
- return 1;
-
- /* If no token list was specified, then eliminate this assertion
- entirely. */
- if (! tokens_specified)
- delete_assertion (hp);
- else {
- /* If a list of tokens was given, then delete any matching list. */
-
- tail = hp->value;
- prev = 0;
- while (tail) {
- struct tokenlist_list *next = tail->next;
- if (compare_token_lists (tail->tokens, tokens)) {
- if (prev)
- prev->next = next;
- else
- hp->value = tail->next;
- free_token_list (tail->tokens);
- free (tail);
- } else {
- prev = tail;
+ thislen = strlen (sym);
+ if (ret == 1)
+ {
+ base = cpp_lookup (pfile, sym, thislen, -1);
+ if (! base)
+ goto error; /* It isn't an error to #undef what isn't #defined,
+ so it isn't an error to #unassert what isn't
+ #asserted either. */
+
+ for (this = base->value.aschain; this; this = next)
+ {
+ next = this->value.aschain;
+ delete_macro (this);
}
- tail = next;
- }
+ delete_macro (base);
}
- }
+ else
+ {
+ baselen = index (sym, '(') - sym;
+ base = cpp_lookup (pfile, sym, baselen, -1);
+ if (! base) goto error;
+ this = cpp_lookup (pfile, sym, thislen, -1);
+ if (! this) goto error;
+
+ next = base;
+ while (next->value.aschain != this)
+ next = next->value.aschain;
- CPP_SET_WRITTEN (pfile, symstart); /* Pop */
+ next->value.aschain = this->value.aschain;
+ delete_macro (this);
+
+ if (base->value.aschain == NULL)
+ delete_macro (base); /* Last answer for this predicate deleted. */
+ }
+
+ pfile->limit = (unsigned char *) sym; /* Pop */
return 0;
error:
- CPP_SET_WRITTEN (pfile, symstart); /* Pop */
+ pfile->limit = (unsigned char *) sym; /* Pop */
skip_rest_of_line (pfile);
return 1;
}
-
-/* Test whether there is an assertion named NAME
- and optionally whether it has an asserted token list TOKENS.
- NAME is not null terminated; its length is SYM_LENGTH.
- If TOKENS_SPECIFIED is 0, then don't check for any token list. */
-int
-check_assertion (pfile, name, sym_length, tokens_specified, tokens)
+/* Process STR as if it appeared as the body of an #unassert. */
+void
+cpp_unassert (pfile, str)
cpp_reader *pfile;
- U_CHAR *name;
- int sym_length;
- int tokens_specified;
- struct arglist *tokens;
-{
- ASSERTION_HASHNODE *hp;
- int hashcode = hashf (name, sym_length, ASSERTION_HASHSIZE);
-
- if (CPP_PEDANTIC (pfile) && !CPP_BUFFER (pfile)->system_header_p)
- cpp_pedwarn (pfile, "ANSI C does not allow testing assertions");
-
- hp = assertion_lookup (pfile, name, sym_length, hashcode);
- if (hp == NULL)
- /* It is not an assertion; just return false. */
- return 0;
-
- /* If no token list was specified, then value is 1. */
- if (! tokens_specified)
- return 1;
-
- {
- struct tokenlist_list *tail;
-
- tail = hp->value;
-
- /* If a list of tokens was given,
- then succeed if the assertion records a matching list. */
-
- while (tail) {
- if (compare_token_lists (tail->tokens, tokens))
- return 1;
- tail = tail->next;
- }
-
- /* Fail if the assertion has no matching list. */
- return 0;
- }
-}
-
-/* Compare two lists of tokens for equality including order of tokens. */
-
-static int
-compare_token_lists (l1, l2)
- struct arglist *l1, *l2;
+ unsigned char *str;
{
- while (l1 && l2) {
- if (l1->length != l2->length)
- return 0;
- if (strncmp (l1->name, l2->name, l1->length))
- return 0;
- l1 = l1->next;
- l2 = l2->next;
- }
-
- /* Succeed if both lists end at the same time. */
- return l1 == l2;
-}
-
-struct arglist *
-reverse_token_list (tokens)
- struct arglist *tokens;
-{
- register struct arglist *prev = 0, *this, *next;
- for (this = tokens; this; this = next)
+ if (cpp_push_buffer (pfile, str, strlen (str)) != NULL)
{
- next = this->next;
- this->next = prev;
- prev = this;
+ do_assert (pfile, NULL);
+ cpp_pop_buffer (pfile);
}
- return prev;
-}
-
-/* Read a space-separated list of tokens ending in a close parenthesis.
- Return a list of strings, in the order they were written.
- (In case of error, return 0 and store -1 in *ERROR_FLAG.) */
+}
-static struct arglist *
-read_token_list (pfile, error_flag)
+int
+cpp_read_check_assertion (pfile)
cpp_reader *pfile;
- int *error_flag;
{
- struct arglist *token_ptrs = 0;
- int depth = 1;
- int length;
-
- *error_flag = 0;
- FORWARD (1); /* Skip '(' */
-
- /* Loop over the assertion value tokens. */
- while (depth > 0)
+ U_CHAR *name = CPP_PWRITTEN (pfile);
+ int result;
+ HASHNODE *hp;
+
+ FORWARD (1); /* Skip '#' */
+ cpp_skip_hspace (pfile);
+ if (! parse_assertion (pfile))
+ result = 0;
+ else
{
- struct arglist *temp;
- long name_written = CPP_WRITTEN (pfile);
- int c;
-
- cpp_skip_hspace (pfile);
-
- c = GETC ();
-
- /* Find the end of the token. */
- if (c == '(')
- {
- CPP_PUTC (pfile, c);
- depth++;
- }
- else if (c == ')')
- {
- depth--;
- if (depth == 0)
- break;
- CPP_PUTC (pfile, c);
- }
- else if (c == '"' || c == '\'')
- {
- FORWARD(-1);
- cpp_get_token (pfile);
- }
- else if (c == '\n')
- break;
- else
- {
- while (c != EOF && ! is_space[c] && c != '(' && c != ')'
- && c != '"' && c != '\'')
- {
- CPP_PUTC (pfile, c);
- c = GETC();
- }
- if (c != EOF) FORWARD(-1);
- }
-
- length = CPP_WRITTEN (pfile) - name_written;
- temp = (struct arglist *)
- xmalloc (sizeof (struct arglist) + length + 1);
- temp->name = (U_CHAR *) (temp + 1);
- bcopy ((char *) (pfile->token_buffer + name_written),
- (char *) temp->name, length);
- temp->name[length] = 0;
- temp->next = token_ptrs;
- token_ptrs = temp;
- temp->length = length;
-
- CPP_ADJUST_WRITTEN (pfile, -length); /* pop */
-
- if (c == EOF || c == '\n')
- { /* FIXME */
- cpp_error (pfile,
- "unterminated token sequence following `#' operator");
- return 0;
- }
+ hp = cpp_lookup (pfile, name, CPP_PWRITTEN (pfile) - name, -1);
+ result = (hp != 0);
}
- /* We accumulated the names in reverse order.
- Now reverse them to get the proper order. */
- return reverse_token_list (token_ptrs);
-}
-
-static void
-free_token_list (tokens)
- struct arglist *tokens;
-{
- while (tokens) {
- struct arglist *next = tokens->next;
- free (tokens->name);
- free (tokens);
- tokens = next;
- }
-}
-
-/* Read LEN bytes at PTR from descriptor DESC, for file FILENAME,
- retrying if necessary. If MAX_READ_LEN is defined, read at most
- that bytes at a time. Return a negative value if an error occurs,
- otherwise return the actual number of bytes read,
- which must be LEN unless end-of-file was reached. */
-
-static int
-safe_read (desc, ptr, len)
- int desc;
- char *ptr;
- int len;
-{
- int left, rcount, nchars;
-
- left = len;
- while (left > 0) {
- rcount = left;
-#ifdef MAX_READ_LEN
- if (rcount > MAX_READ_LEN)
- rcount = MAX_READ_LEN;
-#endif
- nchars = read (desc, ptr, rcount);
- if (nchars < 0)
- {
-#ifdef EINTR
- if (errno == EINTR)
- continue;
-#endif
- return nchars;
- }
- if (nchars == 0)
- break;
- ptr += nchars;
- left -= nchars;
- }
- return len - left;
-}
-
-static char *
-xcalloc (number, size)
- unsigned number, size;
-{
- register unsigned total = number * size;
- register char *ptr = (char *) xmalloc (total);
- bzero (ptr, total);
- return ptr;
+ pfile->limit = name;
+ return result;
}
-static char *
-savestring (input)
- char *input;
-{
- unsigned size = strlen (input);
- char *output = xmalloc (size + 1);
- strcpy (output, input);
- return output;
-}
-
-/* Initialize PMARK to remember the current position of PFILE. */
+/* Remember the current position of PFILE. */
void
-parse_set_mark (pmark, pfile)
- struct parse_marker *pmark;
+parse_set_mark (pfile)
cpp_reader *pfile;
{
- cpp_buffer *pbuf = CPP_BUFFER (pfile);
- pmark->next = pbuf->marks;
- pbuf->marks = pmark;
- pmark->buf = pbuf;
- pmark->position = pbuf->cur - pbuf->buf;
-}
-
-/* Cleanup PMARK - we no longer need it. */
+ cpp_buffer *ip = CPP_BUFFER (pfile);
+ if (ip->mark != -1)
+ cpp_fatal (pfile,
+ "cpp internal error: ip->mark != -1 in parse_set_mark");
-void
-parse_clear_mark (pmark)
- struct parse_marker *pmark;
-{
- struct parse_marker **pp = &pmark->buf->marks;
- for (; ; pp = &(*pp)->next) {
- if (*pp == NULL) abort ();
- if (*pp == pmark) break;
- }
- *pp = pmark->next;
+ ip->mark = ip->cur - ip->buf;
}
-/* Backup the current position of PFILE to that saved in PMARK. */
+/* Clear the current mark - we no longer need it. */
void
-parse_goto_mark (pmark, pfile)
- struct parse_marker *pmark;
+parse_clear_mark (pfile)
cpp_reader *pfile;
{
- cpp_buffer *pbuf = CPP_BUFFER (pfile);
- if (pbuf != pmark->buf)
- cpp_fatal (pfile, "internal error %s", "parse_goto_mark");
- pbuf->cur = pbuf->buf + pmark->position;
+ cpp_buffer *ip = CPP_BUFFER (pfile);
+ if (ip->mark == -1)
+ cpp_fatal (pfile,
+ "cpp internal error: ip->mark == -1 in parse_clear_mark");
+
+ ip->mark = -1;
}
-/* Reset PMARK to point to the current position of PFILE. (Same
- as parse_clear_mark (PMARK), parse_set_mark (PMARK, PFILE) but faster. */
+/* Backup the current position of PFILE to that saved in its mark,
+ and clear the mark. */
void
-parse_move_mark (pmark, pfile)
- struct parse_marker *pmark;
+parse_goto_mark (pfile)
cpp_reader *pfile;
{
- cpp_buffer *pbuf = CPP_BUFFER (pfile);
- if (pbuf != pmark->buf)
- cpp_fatal (pfile, "internal error %s", "parse_move_mark");
- pmark->position = pbuf->cur - pbuf->buf;
-}
+ cpp_buffer *ip = CPP_BUFFER (pfile);
+ if (ip->mark == -1)
+ cpp_fatal (pfile,
+ "cpp internal error: ip->mark == -1 in parse_goto_mark");
-int
-cpp_read_check_assertion (pfile)
- cpp_reader *pfile;
-{
- int name_start = CPP_WRITTEN (pfile);
- int name_length, name_written;
- int result;
- FORWARD (1); /* Skip '#' */
- cpp_skip_hspace (pfile);
- parse_name (pfile, GETC ());
- name_written = CPP_WRITTEN (pfile);
- name_length = name_written - name_start;
- cpp_skip_hspace (pfile);
- if (CPP_BUF_PEEK (CPP_BUFFER (pfile)) == '(')
- {
- int error_flag;
- struct arglist *token_ptrs = read_token_list (pfile, &error_flag);
- result = check_assertion (pfile,
- pfile->token_buffer + name_start, name_length,
- 1, token_ptrs);
- }
- else
- result = check_assertion (pfile,
- pfile->token_buffer + name_start, name_length,
- 0, NULL_PTR);
- CPP_ADJUST_WRITTEN (pfile, - name_length); /* pop */
- return result;
+ ip->cur = ip->buf + ip->mark;
+ ip->mark = -1;
}
-
+
void
cpp_print_file_and_line (pfile)
cpp_reader *pfile;
@@ -7442,42 +2963,42 @@ cpp_print_file_and_line (pfile)
}
static void
-v_cpp_error (pfile, msg, ap)
+v_cpp_error (pfile, msgid, ap)
cpp_reader *pfile;
- const char *msg;
+ const char *msgid;
va_list ap;
{
cpp_print_containing_files (pfile);
cpp_print_file_and_line (pfile);
- v_cpp_message (pfile, 1, msg, ap);
+ v_cpp_message (pfile, 1, msgid, ap);
}
void
-cpp_error VPROTO ((cpp_reader * pfile, const char *msg, ...))
+cpp_error VPROTO ((cpp_reader * pfile, const char *msgid, ...))
{
-#ifndef __STDC__
+#ifndef ANSI_PROTOTYPES
cpp_reader *pfile;
- const char *msg;
+ const char *msgid;
#endif
va_list ap;
- VA_START(ap, msg);
+ VA_START(ap, msgid);
-#ifndef __STDC__
+#ifndef ANSI_PROTOTYPES
pfile = va_arg (ap, cpp_reader *);
- msg = va_arg (ap, const char *);
+ msgid = va_arg (ap, const char *);
#endif
- v_cpp_error (pfile, msg, ap);
+ v_cpp_error (pfile, msgid, ap);
va_end(ap);
}
/* Print error message but don't count it. */
static void
-v_cpp_warning (pfile, msg, ap)
+v_cpp_warning (pfile, msgid, ap)
cpp_reader *pfile;
- const char *msg;
+ const char *msgid;
va_list ap;
{
if (CPP_OPTIONS (pfile)->inhibit_warnings)
@@ -7488,60 +3009,60 @@ v_cpp_warning (pfile, msg, ap)
cpp_print_containing_files (pfile);
cpp_print_file_and_line (pfile);
- v_cpp_message (pfile, 0, msg, ap);
+ v_cpp_message (pfile, 0, msgid, ap);
}
void
-cpp_warning VPROTO ((cpp_reader * pfile, const char *msg, ...))
+cpp_warning VPROTO ((cpp_reader * pfile, const char *msgid, ...))
{
-#ifndef __STDC__
+#ifndef ANSI_PROTOTYPES
cpp_reader *pfile;
- const char *msg;
+ const char *msgid;
#endif
va_list ap;
- VA_START (ap, msg);
+ VA_START (ap, msgid);
-#ifndef __STDC__
+#ifndef ANSI_PROTOTYPES
pfile = va_arg (ap, cpp_reader *);
- msg = va_arg (ap, const char *);
+ msgid = va_arg (ap, const char *);
#endif
- v_cpp_warning (pfile, msg, ap);
+ v_cpp_warning (pfile, msgid, ap);
va_end(ap);
}
/* Print an error message and maybe count it. */
void
-cpp_pedwarn VPROTO ((cpp_reader * pfile, const char *msg, ...))
+cpp_pedwarn VPROTO ((cpp_reader * pfile, const char *msgid, ...))
{
-#ifndef __STDC__
+#ifndef ANSI_PROTOTYPES
cpp_reader *pfile;
- const char *msg;
+ const char *msgid;
#endif
va_list ap;
- VA_START (ap, msg);
+ VA_START (ap, msgid);
-#ifndef __STDC__
+#ifndef ANSI_PROTOTYPES
pfile = va_arg (ap, cpp_reader *);
- msg = va_arg (ap, const char *);
+ msgid = va_arg (ap, const char *);
#endif
if (CPP_OPTIONS (pfile)->pedantic_errors)
- v_cpp_error (pfile, msg, ap);
+ v_cpp_error (pfile, msgid, ap);
else
- v_cpp_warning (pfile, msg, ap);
+ v_cpp_warning (pfile, msgid, ap);
va_end(ap);
}
static void
-v_cpp_error_with_line (pfile, line, column, msg, ap)
+v_cpp_error_with_line (pfile, line, column, msgid, ap)
cpp_reader * pfile;
int line;
int column;
- const char * msg;
+ const char * msgid;
va_list ap;
{
cpp_buffer *ip = cpp_file_buffer (pfile);
@@ -7551,39 +3072,40 @@ v_cpp_error_with_line (pfile, line, column, msg, ap)
if (ip != NULL)
cpp_file_line_for_message (pfile, ip->nominal_fname, line, column);
- v_cpp_message (pfile, 1, msg, ap);
+ v_cpp_message (pfile, 1, msgid, ap);
}
void
-cpp_error_with_line VPROTO ((cpp_reader * pfile, int line, int column, const char *msg, ...))
+cpp_error_with_line VPROTO ((cpp_reader * pfile, int line, int column,
+ const char *msgid, ...))
{
-#ifndef __STDC__
+#ifndef ANSI_PROTOTYPES
cpp_reader *pfile;
int line;
int column;
- const char *msg;
+ const char *msgid;
#endif
va_list ap;
- VA_START (ap, msg);
+ VA_START (ap, msgid);
-#ifndef __STDC__
+#ifndef ANSI_PROTOTYPES
pfile = va_arg (ap, cpp_reader *);
line = va_arg (ap, int);
column = va_arg (ap, int);
- msg = va_arg (ap, const char *);
+ msgid = va_arg (ap, const char *);
#endif
- v_cpp_error_with_line(pfile, line, column, msg, ap);
+ v_cpp_error_with_line(pfile, line, column, msgid, ap);
va_end(ap);
}
static void
-v_cpp_warning_with_line (pfile, line, column, msg, ap)
+v_cpp_warning_with_line (pfile, line, column, msgid, ap)
cpp_reader * pfile;
int line;
int column;
- const char *msg;
+ const char *msgid;
va_list ap;
{
cpp_buffer *ip;
@@ -7601,59 +3123,59 @@ v_cpp_warning_with_line (pfile, line, column, msg, ap)
if (ip != NULL)
cpp_file_line_for_message (pfile, ip->nominal_fname, line, column);
- v_cpp_message (pfile, 0, msg, ap);
+ v_cpp_message (pfile, 0, msgid, ap);
}
-#if 0
-static void
-cpp_warning_with_line VPROTO ((cpp_reader * pfile, int line, int column, const char *msg, ...))
+void
+cpp_warning_with_line VPROTO ((cpp_reader * pfile, int line, int column,
+ const char *msgid, ...))
{
-#ifndef __STDC__
+#ifndef ANSI_PROTOTYPES
cpp_reader *pfile;
int line;
int column;
- const char *msg;
+ const char *msgid;
#endif
va_list ap;
- VA_START (ap, msg);
+ VA_START (ap, msgid);
-#ifndef __STDC__
+#ifndef ANSI_PROTOTYPES
pfile = va_arg (ap, cpp_reader *);
line = va_arg (ap, int);
column = va_arg (ap, int);
- msg = va_arg (ap, const char *);
+ msgid = va_arg (ap, const char *);
#endif
- v_cpp_warning_with_line (pfile, line, column, msg, ap);
+ v_cpp_warning_with_line (pfile, line, column, msgid, ap);
va_end(ap);
}
-#endif
void
-cpp_pedwarn_with_line VPROTO ((cpp_reader * pfile, int line, int column, const char *msg, ...))
+cpp_pedwarn_with_line VPROTO ((cpp_reader * pfile, int line, int column,
+ const char *msgid, ...))
{
-#ifndef __STDC__
+#ifndef ANSI_PROTOTYPES
cpp_reader *pfile;
int line;
int column;
- const char *msg;
+ const char *msgid;
#endif
va_list ap;
- VA_START (ap, msg);
+ VA_START (ap, msgid);
-#ifndef __STDC__
+#ifndef ANSI_PROTOTYPES
pfile = va_arg (ap, cpp_reader *);
line = va_arg (ap, int);
column = va_arg (ap, int);
- msg = va_arg (ap, const char *);
+ msgid = va_arg (ap, const char *);
#endif
if (CPP_OPTIONS (pfile)->pedantic_errors)
- v_cpp_error_with_line (pfile, column, line, msg, ap);
+ v_cpp_error_with_line (pfile, column, line, msgid, ap);
else
- v_cpp_warning_with_line (pfile, line, column, msg, ap);
+ v_cpp_warning_with_line (pfile, line, column, msgid, ap);
va_end(ap);
}
@@ -7661,23 +3183,24 @@ cpp_pedwarn_with_line VPROTO ((cpp_reader * pfile, int line, int column, const c
giving specified file name and line number, not current. */
void
-cpp_pedwarn_with_file_and_line VPROTO ((cpp_reader *pfile, char *file, int line, const char *msg, ...))
+cpp_pedwarn_with_file_and_line VPROTO ((cpp_reader *pfile, char *file, int line,
+ const char *msgid, ...))
{
-#ifndef __STDC__
+#ifndef ANSI_PROTOTYPES
cpp_reader *pfile;
char *file;
int line;
- const char *msg;
+ const char *msgid;
#endif
va_list ap;
- VA_START (ap, msg);
+ VA_START (ap, msgid);
-#ifndef __STDC__
+#ifndef ANSI_PROTOTYPES
pfile = va_arg (ap, cpp_reader *);
file = va_arg (ap, char *);
line = va_arg (ap, int);
- msg = va_arg (ap, const char *);
+ msgid = va_arg (ap, const char *);
#endif
if (!CPP_OPTIONS (pfile)->pedantic_errors
@@ -7685,7 +3208,7 @@ cpp_pedwarn_with_file_and_line VPROTO ((cpp_reader *pfile, char *file, int line,
return;
if (file != NULL)
cpp_file_line_for_message (pfile, file, line, -1);
- v_cpp_message (pfile, CPP_OPTIONS (pfile)->pedantic_errors, msg, ap);
+ v_cpp_message (pfile, CPP_OPTIONS (pfile)->pedantic_errors, msgid, ap);
va_end(ap);
}
@@ -7716,7 +3239,7 @@ my_strerror (errnum)
#endif
if (!result)
- result = "undocumented I/O error";
+ result = "errno = ?";
return result;
}
@@ -7761,13 +3284,8 @@ cpp_perror_with_name (pfile, name)
*
* Possibly different enum token codes for each C/C++ token.
*
- * Should clean up remaining directives to that do_XXX functions
- * only take two arguments and all have command_reads_line.
- *
* Find and cleanup remaining uses of static variables,
*
- * Support for trigraphs.
- *
* Support -dM flag (dump_all_macros).
*
* Support for_lint flag.
diff --git a/gcc/cpplib.h b/gcc/cpplib.h
index ad69646d4fe..9af3b4b6343 100644
--- a/gcc/cpplib.h
+++ b/gcc/cpplib.h
@@ -1,5 +1,5 @@
/* Definitions for CPP library.
- Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
+ Copyright (C) 1995, 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
Written by Per Bothner, 1994-95.
This program is free software; you can redistribute it and/or modify it
@@ -19,9 +19,10 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
In other words, you are welcome to use, share and improve this program.
You are forbidden to forbid anyone else to use, share and improve
what you give them. Help stamp out software-hoarding! */
+#ifndef __GCC_CPPLIB__
+#define __GCC_CPPLIB__
#include <sys/types.h>
-#include <sys/stat.h>
#ifdef __cplusplus
extern "C" {
@@ -68,26 +69,12 @@ enum cpp_token {
CPP_POP
};
-#ifndef PARAMS
-#define PARAMS(P) PROTO(P)
-#endif /* !PARAMS */
-
typedef enum cpp_token (*parse_underflow_t) PARAMS((cpp_reader *));
typedef int (*parse_cleanup_t) PARAMS((cpp_buffer *, cpp_reader *));
-/* A parse_marker indicates a previous position,
- which we can backtrack to. */
-
-struct parse_marker {
- cpp_buffer *buf;
- struct parse_marker *next;
- int position;
-};
-
-extern void parse_set_mark PARAMS ((struct parse_marker *, cpp_reader *));
-extern void parse_clear_mark PARAMS ((struct parse_marker *));
-extern void parse_goto_mark PARAMS((struct parse_marker *, cpp_reader *));
-extern void parse_move_mark PARAMS((struct parse_marker *, cpp_reader *));
+extern void parse_set_mark PARAMS ((cpp_reader *));
+extern void parse_clear_mark PARAMS ((cpp_reader *));
+extern void parse_goto_mark PARAMS ((cpp_reader *));
extern int cpp_handle_option PARAMS ((cpp_reader *, int, char **));
extern int cpp_handle_options PARAMS ((cpp_reader *, int, char **));
@@ -98,42 +85,36 @@ extern enum cpp_token cpp_get_non_space_token PARAMS ((cpp_reader *));
/* This frees resources used by PFILE. */
extern void cpp_cleanup PARAMS ((cpp_reader *PFILE));
-/* Maintain and search list of included files, for #import. */
-
-#define IMPORT_HASH_SIZE 31
-
-struct import_file {
- char *name;
- ino_t inode;
- dev_t dev;
- struct import_file *next;
-};
-
-/* If we have a huge buffer, may need to cache more recent counts */
-#define CPP_LINE_BASE(BUF) ((BUF)->buf + (BUF)->line_base)
-
-struct cpp_buffer {
- unsigned char *buf;
- unsigned char *cur;
+struct cpp_buffer
+{
+ unsigned char *cur; /* current position */
unsigned char *rlimit; /* end of valid data */
+ unsigned char *buf; /* entire buffer */
unsigned char *alimit; /* end of allocated buffer */
- unsigned char *prev; /* start of current token */
+ unsigned char *line_base; /* start of current line */
+
+ struct cpp_buffer *prev;
+ /* Real filename. (Alias to ->ihash->fname, obsolete). */
char *fname;
/* Filename specified with #line command. */
char *nominal_fname;
+ /* Last filename specified with #line command. */
+ char *last_nominal_fname;
+ /* Actual directory of this file, used only for "" includes */
+ struct file_name_list *actual_dir;
- /* Record where in the search path this file was found.
- For #include_next. */
- struct file_name_list *dir;
+ /* Pointer into the include hash table. Used for include_next and
+ to record control macros. */
+ struct include_hash *ihash;
- long line_base;
long lineno; /* Line number at CPP_LINE_BASE. */
long colno; /* Column number at CPP_LINE_BASE. */
+ long mark; /* Saved position for lengthy backtrack. */
parse_underflow_t underflow;
parse_cleanup_t cleanup;
void *data;
- struct parse_marker *marks;
+
/* Value of if_stack at start of this file.
Used to prohibit unmatched #endif (etc) in an include file. */
struct if_stack *if_stack;
@@ -152,12 +133,8 @@ struct cpp_buffer {
char has_escapes;
};
-struct cpp_pending; /* Forward declaration - for C++. */
struct file_name_map_list;
-typedef struct assertion_hashnode ASSERTION_HASHNODE;
-#define ASSERTION_HASHSIZE 37
-
/* Maximum nesting of cpp_buffers. We use a static limit, partly for
efficiency, and partly to limit runaway recursion. */
#define CPP_STACK_MAX 200
@@ -166,41 +143,46 @@ typedef struct assertion_hashnode ASSERTION_HASHNODE;
Applying cpp_get_token repeatedly yields a stream of pre-processor
tokens. Usually, there is only one cpp_reader object active. */
-struct cpp_reader {
+struct cpp_reader
+{
parse_underflow_t get_token;
cpp_buffer *buffer;
- cpp_buffer buffer_stack[CPP_STACK_MAX];
-
- int errors; /* Error counter for exit code */
- void *data;
+ cpp_options *opts;
/* A buffer used for both for cpp_get_token's output, and also internally. */
unsigned char *token_buffer;
/* Allocated size of token_buffer. CPP_RESERVE allocates space. */
- int token_buffer_size;
+ unsigned int token_buffer_size;
/* End of the written part of token_buffer. */
unsigned char *limit;
+ /* Error counter for exit code */
+ int errors;
+
/* Line where a newline was first seen in a string constant. */
int multiline_string_line;
/* Current depth in #include directives that use <...>. */
int system_include_depth;
- /* List of included files that contained #pragma once. */
- struct file_name_list *dont_repeat_files;
+ /* Current depth of buffer stack. */
+ int buffer_stack_depth;
+
+ /* Hash table of macros and assertions. See cpphash.c */
+#define HASHSIZE 1403
+ struct hashnode **hashtab;
+
+ /* Hash table of other included files. See cppfiles.c */
+#define ALL_INCLUDE_HASHSIZE 71
+ struct include_hash *all_include_files[ALL_INCLUDE_HASHSIZE];
- /* List of other included files.
- If ->control_macro if nonzero, the file had a #ifndef
- around the entire contents, and ->control_macro gives the macro name. */
- struct file_name_list *all_include_files;
+ /* Chain of `actual directory' file_name_list entries,
+ for "" inclusion. */
+ struct file_name_list *actual_dirs;
/* Current maximum length of directory names in the search path
for include files. (Altered as we get more of them.) */
- int max_include_len;
-
- /* Hash table of files already included with #include or #import. */
- struct import_file *import_hash_table[IMPORT_HASH_SIZE];
+ unsigned int max_include_len;
struct if_stack *if_stack;
@@ -243,8 +225,6 @@ struct cpp_reader {
struct tm *timebuf;
- ASSERTION_HASHNODE *assertion_hashtab[ASSERTION_HASHSIZE];
-
/* Buffer of -M output. */
char *deps_buffer;
@@ -256,10 +236,6 @@ struct cpp_reader {
/* Number of bytes since the last newline. */
int deps_column;
-
-#ifdef __cplusplus
- ~cpp_reader () { cpp_cleanup (this); }
-#endif
};
#define CPP_FATAL_LIMIT 1000
@@ -277,12 +253,12 @@ struct cpp_reader {
#define CPP_OUT_BUFFER(PFILE) ((PFILE)->token_buffer)
/* Number of characters currently in PFILE's output buffer. */
-#define CPP_WRITTEN(PFILE) ((PFILE)->limit - (PFILE)->token_buffer)
+#define CPP_WRITTEN(PFILE) ((size_t)((PFILE)->limit - (PFILE)->token_buffer))
#define CPP_PWRITTEN(PFILE) ((PFILE)->limit)
/* Make sure PFILE->token_buffer has space for at least N more characters. */
#define CPP_RESERVE(PFILE, N) \
- (CPP_WRITTEN (PFILE) + N > (PFILE)->token_buffer_size \
+ (CPP_WRITTEN (PFILE) + (size_t)(N) > (PFILE)->token_buffer_size \
&& (cpp_grow_buffer (PFILE, N), 0))
/* Append string STR (of length N) to PFILE's output buffer.
@@ -301,14 +277,36 @@ struct cpp_reader {
#define CPP_ADJUST_WRITTEN(PFILE,DELTA) ((PFILE)->limit += (DELTA))
#define CPP_SET_WRITTEN(PFILE,N) ((PFILE)->limit = (PFILE)->token_buffer + (N))
-#define CPP_OPTIONS(PFILE) ((cpp_options *) (PFILE)->data)
+/* Advance the current line by one. */
+#define CPP_BUMP_BUFFER_LINE(PBUF) ((PBUF)->lineno++,\
+ (PBUF)->line_base = (PBUF)->cur)
+#define CPP_BUMP_LINE(PFILE) CPP_BUMP_BUFFER_LINE(CPP_BUFFER(PFILE))
+#define CPP_OPTIONS(PFILE) ((PFILE)->opts)
#define CPP_BUFFER(PFILE) ((PFILE)->buffer)
-#define CPP_PREV_BUFFER(BUFFER) ((BUFFER)+1)
+#define CPP_PREV_BUFFER(BUFFER) ((BUFFER)->prev)
/* The bottom of the buffer stack. */
-#define CPP_NULL_BUFFER(PFILE) (&(PFILE)->buffer_stack[CPP_STACK_MAX])
+#define CPP_NULL_BUFFER(PFILE) NULL
+
+/* The `pending' structure accumulates all the options that are not
+ actually processed until we hit cpp_start_read. It consists of
+ several lists, one for each type of option. We keep both head and
+ tail pointers for quick insertion. */
+struct cpp_pending
+{
+ struct pending_option *define_head, *define_tail;
+ struct pending_option *assert_head, *assert_tail;
+
+ struct file_name_list *quote_head, *quote_tail;
+ struct file_name_list *brack_head, *brack_tail;
+ struct file_name_list *systm_head, *systm_tail;
+ struct file_name_list *after_head, *after_tail;
-/* Pointed to by cpp_reader::data. */
+ struct pending_option *imacros_head, *imacros_tail;
+ struct pending_option *include_head, *include_tail;
+};
+
+/* Pointed to by cpp_reader.opts. */
struct cpp_options {
char *in_fname;
@@ -350,9 +348,9 @@ struct cpp_options {
char put_out_comments;
- /* Nonzero means don't process the ANSI trigraph sequences. */
+ /* Nonzero means process the ANSI trigraph sequences. */
- char no_trigraphs;
+ char trigraphs;
/* Nonzero means print the names of included files rather than
the preprocessed output. 1 means just the #include "...",
@@ -438,32 +436,22 @@ struct cpp_options {
/* Nonzero for the 1989 C Standard, including corrigenda and amendments. */
char c89;
+ /* Nonzero for the 199x C Standard, including corrigenda and amendments. */
+ char c9x;
+
/* Nonzero means give all the error messages the ANSI standard requires. */
char pedantic;
char done_initializing;
- struct file_name_list *include; /* First dir to search */
- /* First dir to search for <file> */
- /* This is the first element to use for #include <...>.
- If it is 0, use the entire chain for such includes. */
- struct file_name_list *first_bracket_include;
- /* This is the first element in the chain that corresponds to
- a directory of system header files. */
- struct file_name_list *first_system_include;
- struct file_name_list *last_include; /* Last in chain */
-
- /* Chain of include directories to put at the end of the other chain. */
- struct file_name_list *after_include;
- struct file_name_list *last_after_include; /* Last in chain */
-
- /* Chain to put at the start of the system include files. */
- struct file_name_list *before_system;
- struct file_name_list *last_before_system; /* Last in chain */
-
- /* Directory prefix that should replace `/usr' in the standard
- include file directories. */
+ /* Search paths for include files. */
+ struct file_name_list *quote_include; /* First dir to search for "file" */
+ struct file_name_list *bracket_include;/* First dir to search for <file> */
+
+ /* Directory prefix that should replace `/usr/lib/gcc-lib/TARGET/VERSION'
+ in the standard include file directories. */
char *include_prefix;
+ int include_prefix_len;
char inhibit_predefs;
char no_standard_includes;
@@ -491,7 +479,7 @@ struct cpp_options {
even if they are ifdefed out. */
int dump_includes;
- /* Pending -D, -U and -A options, in reverse order. */
+ /* Pending options - -D, -U, -A, -I, -ixxx. */
struct cpp_pending *pending;
/* File name which deps are being written to.
@@ -508,6 +496,47 @@ struct cpp_options {
#define CPP_PEDANTIC(PFILE) (CPP_OPTIONS (PFILE)->pedantic)
#define CPP_PRINT_DEPS(PFILE) (CPP_OPTIONS (PFILE)->print_deps)
+/* List of directories to look for include files in. */
+struct file_name_list
+{
+ struct file_name_list *next;
+ struct file_name_list *alloc; /* for the cache of
+ current directory entries */
+ char *name;
+ unsigned int nlen;
+ /* We use these to tell if the directory mentioned here is a duplicate
+ of an earlier directory on the search path. */
+ ino_t ino;
+ dev_t dev;
+ /* If the following is nonzero, it is a C-language system include
+ directory. */
+ int sysp;
+ /* Mapping of file names for this directory.
+ Only used on MS-DOS and related platforms. */
+ struct file_name_map *name_map;
+};
+#define ABSOLUTE_PATH ((struct file_name_list *)-1)
+
+/* This structure is used for the table of all includes. It is
+ indexed by the `short name' (the name as it appeared in the
+ #include statement) which is stored in *nshort. */
+struct include_hash
+{
+ struct include_hash *next;
+ /* Next file with the same short name but a
+ different (partial) pathname). */
+ struct include_hash *next_this_file;
+
+ /* Location of the file in the include search path.
+ Used for include_next */
+ struct file_name_list *foundhere;
+ char *name; /* (partial) pathname of file */
+ char *nshort; /* name of file as referenced in #include */
+ char *control_macro; /* macro, if any, preventing reinclusion - see
+ redundant_include_p */
+ char *buf, *limit; /* for file content cache, not yet implemented */
+};
+
/* Name under which this program was invoked. */
extern char *progname;
@@ -546,16 +575,11 @@ enum node_type {
T_BASE_FILE, /* `__BASE_FILE__' */
T_INCLUDE_LEVEL, /* `__INCLUDE_LEVEL__' */
T_VERSION, /* `__VERSION__' */
- T_SIZE_TYPE, /* `__SIZE_TYPE__' */
- T_PTRDIFF_TYPE, /* `__PTRDIFF_TYPE__' */
- T_WCHAR_TYPE, /* `__WCHAR_TYPE__' */
- T_USER_LABEL_PREFIX_TYPE, /* `__USER_LABEL_PREFIX__' */
- T_REGISTER_PREFIX_TYPE, /* `__REGISTER_PREFIX__' */
T_TIME, /* `__TIME__' */
- T_CONST, /* Constant value, used by `__STDC__' */
+ T_STDC, /* `__STDC__' */
+ T_CONST, /* Constant string, used by `__SIZE_TYPE__' etc */
T_MACRO, /* macro defined by `#define' */
T_DISABLED, /* macro temporarily turned off for rescan */
- T_SPEC_DEFINED, /* special `defined' macro for use in #if statements */
T_PCSTRING, /* precompiled string (hashval is KEYDEF *) */
T_UNUSED /* Used for something not defined. */
};
@@ -620,7 +644,19 @@ struct definition {
} args;
};
-extern unsigned char is_idchar[256];
+/* These tables are not really `const', but they are only modified at
+ initialization time, in a separate translation unit from the rest
+ of the library. We let the rest of the library think they are `const'
+ to get better code and some additional sanity checks. */
+#ifndef FAKE_CONST
+#define FAKE_CONST const
+#endif
+extern FAKE_CONST unsigned char is_idstart[256];
+extern FAKE_CONST unsigned char is_idchar[256];
+extern FAKE_CONST unsigned char is_hor_space[256];
+extern FAKE_CONST unsigned char is_space[256];
+extern FAKE_CONST unsigned char trigraph_table[256];
+#undef FAKE_CONST
/* Stack of conditionals currently in progress
(including both successful and failing conditionals). */
@@ -639,7 +675,10 @@ typedef struct if_stack IF_STACK_FRAME;
extern void cpp_buf_line_and_col PARAMS((cpp_buffer *, long *, long *));
extern cpp_buffer* cpp_file_buffer PARAMS((cpp_reader *));
-extern void cpp_define PARAMS ((cpp_reader*, unsigned char *));
+extern void cpp_define PARAMS ((cpp_reader *, unsigned char *));
+extern void cpp_assert PARAMS ((cpp_reader *, unsigned char *));
+extern void cpp_undef PARAMS ((cpp_reader *, unsigned char *));
+extern void cpp_unassert PARAMS ((cpp_reader *, unsigned char *));
extern void cpp_error PVPROTO ((cpp_reader *, const char *, ...))
ATTRIBUTE_PRINTF_2;
@@ -649,6 +688,8 @@ extern void cpp_pedwarn PVPROTO ((cpp_reader *, const char *, ...))
ATTRIBUTE_PRINTF_2;
extern void cpp_error_with_line PVPROTO ((cpp_reader *, int, int, const char *, ...))
ATTRIBUTE_PRINTF_4;
+extern void cpp_warning_with_line PVPROTO ((cpp_reader *, int, int, const char *, ...))
+ ATTRIBUTE_PRINTF_4;
extern void cpp_pedwarn_with_line PVPROTO ((cpp_reader *, int, int, const char *, ...))
ATTRIBUTE_PRINTF_4;
extern void cpp_pedwarn_with_file_and_line PVPROTO ((cpp_reader *, char *, int, const char *, ...))
@@ -659,7 +700,7 @@ extern void cpp_perror_with_name PROTO ((cpp_reader *, const char *));
extern void v_cpp_message PROTO ((cpp_reader *, int, const char *, va_list));
extern void cpp_grow_buffer PARAMS ((cpp_reader *, long));
-extern int cpp_parse_escape PARAMS ((cpp_reader *, char **));
+extern HOST_WIDEST_INT cpp_parse_escape PARAMS ((cpp_reader *, char **, HOST_WIDEST_INT));
extern cpp_buffer *cpp_push_buffer PARAMS ((cpp_reader *,
unsigned char *, long));
extern cpp_buffer *cpp_pop_buffer PARAMS ((cpp_reader *));
@@ -674,6 +715,16 @@ extern int scan_decls PARAMS ((cpp_reader *, int, char **));
extern void skip_rest_of_line PARAMS ((cpp_reader *));
extern void cpp_finish PARAMS ((cpp_reader *));
+extern void quote_string PARAMS ((cpp_reader *, const char *));
+extern void cpp_expand_to_buffer PARAMS ((cpp_reader *, U_CHAR *, int));
+extern void cpp_scan_buffer PARAMS ((cpp_reader *));
+extern int check_macro_name PARAMS ((cpp_reader *, U_CHAR *, int));
+
+/* Last arg to output_line_command. */
+enum file_change_code {same_file, enter_file, leave_file};
+extern void output_line_command PARAMS ((cpp_reader *, int,
+ enum file_change_code));
+
/* From cpperror.c */
extern void cpp_fatal PVPROTO ((cpp_reader *, const char *, ...))
ATTRIBUTE_PRINTF_2;
@@ -682,7 +733,27 @@ extern void cpp_message PVPROTO ((cpp_reader *, int, const char *, ...))
extern void cpp_pfatal_with_name PROTO ((cpp_reader *, const char *));
extern void cpp_file_line_for_message PROTO ((cpp_reader *, char *, int, int));
extern void cpp_print_containing_files PROTO ((cpp_reader *));
+extern void cpp_notice PVPROTO ((const char *msgid, ...)) ATTRIBUTE_PRINTF_1;
+
+/* In cppfiles.c */
+extern void simplify_pathname PROTO ((char *));
+extern void merge_include_chains PROTO ((struct cpp_options *));
+extern int find_include_file PROTO ((cpp_reader *, char *,
+ struct file_name_list *,
+ struct include_hash **,
+ int *));
+extern int finclude PROTO ((cpp_reader *, int,
+ struct include_hash *));
+extern void deps_output PROTO ((cpp_reader *, char *, int));
+extern struct include_hash *include_hash PROTO ((cpp_reader *, char *, int));
+
+#ifndef INCLUDE_LEN_FUDGE
+#define INCLUDE_LEN_FUDGE 0
+#endif
+
#ifdef __cplusplus
}
#endif
+#endif /* __GCC_CPPLIB__ */
+
diff --git a/gcc/cppmain.c b/gcc/cppmain.c
index 0a45e86907b..5e3ed90f5b3 100644
--- a/gcc/cppmain.c
+++ b/gcc/cppmain.c
@@ -1,5 +1,5 @@
/* CPP main program, using CPP Library.
- Copyright (C) 1995, 1997 Free Software Foundation, Inc.
+ Copyright (C) 1995, 1997, 1998, 1999 Free Software Foundation, Inc.
Written by Per Bothner, 1994-95.
This program is free software; you can redistribute it and/or modify it
@@ -23,7 +23,6 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef EMACS
#include "config.h"
#include "system.h"
-#include "gansidecl.h"
#else
#include <stdio.h>
@@ -31,6 +30,7 @@ extern char *getenv ();
#endif /* not EMACS */
#include "cpplib.h"
+#include "intl.h"
char *progname;
@@ -69,8 +69,14 @@ main (argc, argv)
while (p != argv[0] && p[-1] != '/') --p;
progname = p;
+#ifdef HAVE_LC_MESSAGES
+ setlocale (LC_MESSAGES, "");
+#endif
+ (void) bindtextdomain (PACKAGE, localedir);
+ (void) textdomain (PACKAGE);
+
cpp_reader_init (&parse_in);
- parse_in.data = opts;
+ parse_in.opts = opts;
cpp_options_init (opts);
diff --git a/gcc/cross-make b/gcc/cross-make
index 810f5051a63..84be67fd605 100644
--- a/gcc/cross-make
+++ b/gcc/cross-make
@@ -3,14 +3,6 @@
# and gives up immediately if the user has not done so.
LIBGCC1 = $(CROSS_LIBGCC1)
-# Specify tools and options for manipulating libraries for the target machine.
-AR = $(AR_FOR_TARGET)
-AR_FLAGS = $(AR_FOR_TARGET_FLAGS)
-OLDAR = $(AR_FOR_TARGET)
-OLDAR_FLAGS = $(AR_FOR_TARGET_FLAGS)
-RANLIB = $(RANLIB_FOR_TARGET)
-RANLIB_TEST = $(RANLIB_TEST_FOR_TARGET)
-
# Dir to search for system headers. Normally /usr/include.
# Use CROSS_INCLUDE_DIR not TOOL_INCLUDE_DIR for other vendor's headers.
SYSTEM_HEADER_DIR = $(tooldir)/sys-include
@@ -18,8 +10,5 @@ SYSTEM_HEADER_DIR = $(tooldir)/sys-include
# Don't try to compile the things we can't compile.
ALL = all.cross
-# Use cross-compiler version of float.h.
-FLOAT_H = $(CROSS_FLOAT_H)
-
# Don't install assert.h in /usr/local/include.
assertdir = $(tooldir)/include
diff --git a/gcc/crtstuff.c b/gcc/crtstuff.c
index ce2c9561e64..ccebde1d2c9 100644
--- a/gcc/crtstuff.c
+++ b/gcc/crtstuff.c
@@ -56,6 +56,34 @@ Boston, MA 02111-1307, USA. */
#include <stddef.h>
#include "frame.h"
+/* We do not want to add the weak attribute to the declarations of these
+ routines in frame.h because that will cause the definition of these
+ symbols to be weak as well.
+
+ This exposes a core issue, how to handle creating weak references vs
+ how to create weak definitions. Either we have to have the definition
+ of TARGET_WEAK_ATTRIBUTE be conditional in the shared header files or
+ have a second declaration if we want a function's references to be weak,
+ but not its definition.
+
+ Making TARGET_WEAK_ATTRIBUTE conditional seems like a good solution until
+ one thinks about scaling to larger problems -- ie, the condition under
+ which TARGET_WEAK_ATTRIBUTE is active will eventually get far too
+ complicated.
+
+ So, we take an approach similar to #pragma weak -- we have a second
+ declaration for functions that we want to have weak references.
+
+ Neither way is particularly good. */
+
+/* References to __register_frame_info and __deregister_frame_info should
+ be weak in this file if at all possible. */
+extern void __register_frame_info (void *, struct object *)
+ TARGET_ATTRIBUTE_WEAK;
+
+extern void *__deregister_frame_info (void *)
+ TARGET_ATTRIBUTE_WEAK;
+
#ifndef OBJECT_FORMAT_MACHO
/* Provide default definitions for the pseudo-ops used to switch to the
@@ -129,7 +157,7 @@ typedef void (*func_ptr) (void);
static char __EH_FRAME_BEGIN__[];
static func_ptr __DTOR_LIST__[];
static void
-__do_global_dtors_aux ()
+__do_global_dtors_aux (void)
{
static func_ptr *p = __DTOR_LIST__ + 1;
static int completed = 0;
@@ -144,7 +172,8 @@ __do_global_dtors_aux ()
}
#ifdef EH_FRAME_SECTION_ASM_OP
- __deregister_frame_info (__EH_FRAME_BEGIN__);
+ if (__deregister_frame_info)
+ __deregister_frame_info (__EH_FRAME_BEGIN__);
#endif
completed = 1;
}
@@ -153,7 +182,7 @@ __do_global_dtors_aux ()
/* Stick a call to __do_global_dtors_aux into the .fini section. */
static void __attribute__ ((__unused__))
-fini_dummy ()
+fini_dummy (void)
{
asm (FINI_SECTION_ASM_OP);
__do_global_dtors_aux ();
@@ -169,14 +198,15 @@ fini_dummy ()
call in another function. */
static void
-frame_dummy ()
+frame_dummy (void)
{
static struct object object;
- __register_frame_info (__EH_FRAME_BEGIN__, &object);
+ if (__register_frame_info)
+ __register_frame_info (__EH_FRAME_BEGIN__, &object);
}
static void __attribute__ ((__unused__))
-init_dummy ()
+init_dummy (void)
{
asm (INIT_SECTION_ASM_OP);
frame_dummy ();
@@ -197,7 +227,8 @@ init_dummy ()
to switch to the .text section. */
static void __do_global_ctors_aux ();
-void __do_global_ctors ()
+void
+__do_global_ctors (void)
{
#ifdef INVOKE__main /* If __main won't actually call __do_global_ctors
then it doesn't matter what's inside the function.
@@ -227,7 +258,7 @@ asm (INIT_SECTION_ASM_OP); /* cc1 doesn't know that we are switching! */
file-scope static-storage C++ objects within shared libraries. */
static void
-__do_global_ctors_aux () /* prologue goes in .init section */
+__do_global_ctors_aux (void) /* prologue goes in .init section */
{
#ifdef FORCE_INIT_SECTION_ALIGN
FORCE_INIT_SECTION_ALIGN; /* Explicit align before switch to .text */
@@ -249,14 +280,15 @@ __do_global_ctors_aux () /* prologue goes in .init section */
static char __EH_FRAME_BEGIN__[];
static func_ptr __DTOR_LIST__[];
void
-__do_global_dtors ()
+__do_global_dtors (void)
{
func_ptr *p;
for (p = __DTOR_LIST__ + 1; *p; p++)
(*p) ();
#ifdef EH_FRAME_SECTION_ASM_OP
- __deregister_frame_info (__EH_FRAME_BEGIN__);
+ if (__deregister_frame_info)
+ __deregister_frame_info (__EH_FRAME_BEGIN__);
#endif
}
@@ -265,10 +297,11 @@ __do_global_dtors ()
after libgcc.a, and hence can't call libgcc.a functions directly. That
can lead to unresolved function references. */
void
-__frame_dummy ()
+__frame_dummy (void)
{
static struct object object;
- __register_frame_info (__EH_FRAME_BEGIN__, &object);
+ if (__register_frame_info)
+ __register_frame_info (__EH_FRAME_BEGIN__, &object);
}
#endif
#endif
@@ -328,7 +361,7 @@ char __EH_FRAME_BEGIN__[] = { };
static func_ptr __CTOR_END__[];
static void
-__do_global_ctors_aux ()
+__do_global_ctors_aux (void)
{
func_ptr *p;
for (p = __CTOR_END__ - 1; *p != (func_ptr) -1; p--)
@@ -338,7 +371,7 @@ __do_global_ctors_aux ()
/* Stick a call to __do_global_ctors_aux into the .init section. */
static void __attribute__ ((__unused__))
-init_dummy ()
+init_dummy (void)
{
asm (INIT_SECTION_ASM_OP);
__do_global_ctors_aux ();
@@ -387,7 +420,7 @@ init_dummy ()
before we start to execute any of the user's code. */
static void
-__do_global_ctors_aux () /* prologue goes in .text section */
+__do_global_ctors_aux (void) /* prologue goes in .text section */
{
asm (INIT_SECTION_ASM_OP);
DO_GLOBAL_CTORS_BODY;
@@ -413,7 +446,7 @@ static func_ptr __CTOR_END__[];
extern void __frame_dummy (void);
#endif
void
-__do_global_ctors ()
+__do_global_ctors (void)
{
func_ptr *p;
#ifdef EH_FRAME_SECTION_ASM_OP
@@ -489,7 +522,7 @@ extern const struct section *
static void __reg_frame_ctor () __attribute__ ((constructor));
static void
-__reg_frame_ctor ()
+__reg_frame_ctor (void)
{
static struct object object;
const struct section *eh_frame;
@@ -506,7 +539,8 @@ __reg_frame_ctor ()
static void __dereg_frame_dtor () __attribute__ ((destructor));
static
-void __dereg_frame_dtor ()
+void
+__dereg_frame_dtor (void)
{
const struct section *eh_frame;
diff --git a/gcc/cse.c b/gcc/cse.c
index 06f859aa8a4..3fd1b938d8b 100644
--- a/gcc/cse.c
+++ b/gcc/cse.c
@@ -1,5 +1,5 @@
/* Common subexpression elimination for GNU compiler.
- Copyright (C) 1987, 88, 89, 92-7, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1987, 88, 89, 92-7, 1998, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -664,9 +664,30 @@ static void cse_check_loop_start PROTO((rtx, rtx));
static void cse_set_around_loop PROTO((rtx, rtx, rtx));
static rtx cse_basic_block PROTO((rtx, rtx, struct branch_path *, int));
static void count_reg_usage PROTO((rtx, int *, rtx, int));
+extern void dump_class PROTO((struct table_elt*));
+static void check_fold_consts PROTO((PTR));
extern int rtx_equal_function_value_matters;
+/* Dump the expressions in the equivalence class indicated by CLASSP.
+ This function is used only for debugging. */
+void
+dump_class (classp)
+ struct table_elt *classp;
+{
+ struct table_elt *elt;
+
+ fprintf (stderr, "Equivalence chain for ");
+ print_rtl (stderr, classp->exp);
+ fprintf (stderr, ": \n");
+
+ for (elt = classp->first_same_value; elt; elt = elt->next_same_value)
+ {
+ print_rtl (stderr, elt->exp);
+ fprintf (stderr, "\n");
+ }
+}
+
/* Return an estimate of the cost of computing rtx X.
One use is in cse, to decide which expression to keep in the hash table.
Another is in rtl generation, to pick the cheapest way to multiply.
@@ -703,7 +724,7 @@ notreg_cost (x)
int
rtx_cost (x, outer_code)
rtx x;
- enum rtx_code outer_code;
+ enum rtx_code outer_code ATTRIBUTE_UNUSED;
{
register int i, j;
register enum rtx_code code;
@@ -1652,7 +1673,7 @@ invalidate (x, full_mode)
tendregno
= tregno + HARD_REGNO_NREGS (tregno, GET_MODE (p->exp));
if (tendregno > regno && tregno < endregno)
- remove_from_table (p, hash);
+ remove_from_table (p, hash);
}
}
@@ -1773,7 +1794,7 @@ static void
rehash_using_reg (x)
rtx x;
{
- int i;
+ unsigned int i;
struct table_elt *p, *next;
unsigned hash;
@@ -1990,7 +2011,12 @@ canon_hash (x, mode)
/* On some machines, we can't record any non-fixed hard register,
because extending its life will cause reload problems. We
- consider ap, fp, and sp to be fixed for this purpose.
+ consider ap, fp, and sp to be fixed for this purpose.
+
+ We also consider CCmode registers to be fixed for this purpose;
+ failure to do so leads to failure to simplify 0<100 type of
+ conditionals.
+
On all machines, we can't record any global registers. */
if (regno < FIRST_PSEUDO_REGISTER
@@ -2000,7 +2026,8 @@ canon_hash (x, mode)
&& regno != FRAME_POINTER_REGNUM
&& regno != HARD_FRAME_POINTER_REGNUM
&& regno != ARG_POINTER_REGNUM
- && regno != STACK_POINTER_REGNUM)))
+ && regno != STACK_POINTER_REGNUM
+ && GET_MODE_CLASS (GET_MODE (x)) != MODE_CC)))
{
do_not_record = 1;
return 0;
@@ -3243,6 +3270,19 @@ simplify_unary_operation (code, mode, op, op_mode)
!= ((HOST_WIDE_INT) (-1) << (width - 1))))
val &= ((HOST_WIDE_INT) 1 << width) - 1;
+ /* If this would be an entire word for the target, but is not for
+ the host, then sign-extend on the host so that the number will look
+ the same way on the host that it would on the target.
+
+ For example, when building a 64 bit alpha hosted 32 bit sparc
+ targeted compiler, then we want the 32 bit unsigned value -1 to be
+ represented as a 64 bit value -1, and not as 0x00000000ffffffff.
+ The later confuses the sparc backend. */
+
+ if (BITS_PER_WORD < HOST_BITS_PER_WIDE_INT && BITS_PER_WORD == width
+ && (val & ((HOST_WIDE_INT) 1 << (width - 1))))
+ val |= ((HOST_WIDE_INT) (-1) << width);
+
return GEN_INT (val);
}
@@ -4556,6 +4596,28 @@ cse_gen_binary (code, mode, op0, op1)
return gen_rtx_fmt_ee (code, mode, op0, op1);
}
+struct cfc_args
+{
+ /* Input */
+ rtx op0, op1;
+ /* Output */
+ int equal, op0lt, op1lt;
+};
+
+static void
+check_fold_consts (data)
+ PTR data;
+{
+ struct cfc_args * args = (struct cfc_args *) data;
+ REAL_VALUE_TYPE d0, d1;
+
+ REAL_VALUE_FROM_CONST_DOUBLE (d0, args->op0);
+ REAL_VALUE_FROM_CONST_DOUBLE (d1, args->op1);
+ args->equal = REAL_VALUES_EQUAL (d0, d1);
+ args->op0lt = REAL_VALUES_LESS (d0, d1);
+ args->op1lt = REAL_VALUES_LESS (d1, d0);
+}
+
/* Like simplify_binary_operation except used for relational operators.
MODE is the mode of the operands, not that of the result. If MODE
is VOIDmode, both operands must also be VOIDmode and we compare the
@@ -4617,19 +4679,20 @@ simplify_relational_operation (code, mode, op0, op1)
else if (GET_CODE (op0) == CONST_DOUBLE && GET_CODE (op1) == CONST_DOUBLE
&& GET_MODE_CLASS (GET_MODE (op0)) == MODE_FLOAT)
{
- REAL_VALUE_TYPE d0, d1;
- jmp_buf handler;
+ struct cfc_args args;
+
+ /* Setup input for check_fold_consts() */
+ args.op0 = op0;
+ args.op1 = op1;
- if (setjmp (handler))
+ if (do_float_handler(check_fold_consts, (PTR) &args) == 0)
+ /* We got an exception from check_fold_consts() */
return 0;
- set_float_handler (handler);
- REAL_VALUE_FROM_CONST_DOUBLE (d0, op0);
- REAL_VALUE_FROM_CONST_DOUBLE (d1, op1);
- equal = REAL_VALUES_EQUAL (d0, d1);
- op0lt = op0ltu = REAL_VALUES_LESS (d0, d1);
- op1lt = op1ltu = REAL_VALUES_LESS (d1, d0);
- set_float_handler (NULL_PTR);
+ /* Receive output from check_fold_consts() */
+ equal = args.equal;
+ op0lt = op0ltu = args.op0lt;
+ op1lt = op1ltu = args.op1lt;
}
#endif /* not REAL_IS_NOT_DOUBLE, or REAL_ARITHMETIC */
@@ -5260,7 +5323,11 @@ fold_rtx (x, insn)
/* Indicate this is a constant. This isn't a
valid form of CONST, but it will only be used
to fold the next insns and then discarded, so
- it should be safe. */
+ it should be safe.
+
+ Note this expression must be explicitly discarded,
+ by cse_insn, else it may end up in a REG_EQUAL note
+ and "escape" to cause problems elsewhere. */
return gen_rtx_CONST (GET_MODE (new), new);
}
}
@@ -5761,14 +5828,14 @@ fold_rtx (x, insn)
identical powers of two with post decrement. */
if (code == PLUS && INTVAL (const_arg1) == INTVAL (inner_const)
- && (0
-#if defined(HAVE_PRE_INCREMENT) || defined(HAVE_POST_INCREMENT)
- || exact_log2 (INTVAL (const_arg1)) >= 0
-#endif
-#if defined(HAVE_PRE_DECREMENT) || defined(HAVE_POST_DECREMENT)
- || exact_log2 (- INTVAL (const_arg1)) >= 0
-#endif
- ))
+ && ((HAVE_PRE_INCREMENT
+ && exact_log2 (INTVAL (const_arg1)) >= 0)
+ || (HAVE_POST_INCREMENT
+ && exact_log2 (INTVAL (const_arg1)) >= 0)
+ || (HAVE_PRE_DECREMENT
+ && exact_log2 (- INTVAL (const_arg1)) >= 0)
+ || (HAVE_POST_DECREMENT
+ && exact_log2 (- INTVAL (const_arg1)) >= 0)))
break;
/* Compute the code used to compose the constants. For example,
@@ -5861,7 +5928,7 @@ equiv_constant (x)
&& qty_const[reg_qty[REGNO (x)]])
x = gen_lowpart_if_possible (GET_MODE (x), qty_const[reg_qty[REGNO (x)]]);
- if (x != 0 && CONSTANT_P (x))
+ if (x == 0 || CONSTANT_P (x))
return x;
/* If X is a MEM, try to fold it outside the context of any insn to see if
@@ -5924,9 +5991,8 @@ gen_lowpart_if_possible (mode, x)
new = gen_rtx_MEM (mode, plus_constant (XEXP (x, 0), offset));
if (! memory_address_p (mode, XEXP (new, 0)))
return 0;
- MEM_VOLATILE_P (new) = MEM_VOLATILE_P (x);
RTX_UNCHANGING_P (new) = RTX_UNCHANGING_P (x);
- MEM_IN_STRUCT_P (new) = MEM_IN_STRUCT_P (x);
+ MEM_COPY_ATTRIBUTES (new, x);
return new;
}
else
@@ -6006,7 +6072,7 @@ record_jump_cond (code, mode, op0, op1, reversed_nonequality)
/* If OP0 and OP1 are known equal, and either is a paradoxical SUBREG,
we know that they are also equal in the smaller mode (this is also
true for all smaller modes whether or not there is a SUBREG, but
- is not worth testing for with no SUBREG. */
+ is not worth testing for with no SUBREG). */
/* Note that GET_MODE (op0) may not equal MODE. */
if (code == EQ && GET_CODE (op0) == SUBREG
@@ -7139,9 +7205,18 @@ cse_insn (insn, libcall_insn)
equivalent constant, we want to add a REG_NOTE. We don't want
to write a REG_EQUAL note for a constant pseudo since verifying that
that pseudo hasn't been eliminated is a pain. Such a note also
- won't help anything. */
+ won't help anything.
+
+ Avoid a REG_EQUAL note for (CONST (MINUS (LABEL_REF) (LABEL_REF)))
+ which can be created for a reference to a compile time computable
+ entry in a jump table. */
+
if (n_sets == 1 && src_const && GET_CODE (dest) == REG
- && GET_CODE (src_const) != REG)
+ && GET_CODE (src_const) != REG
+ && ! (GET_CODE (src_const) == CONST
+ && GET_CODE (XEXP (src_const, 0)) == MINUS
+ && GET_CODE (XEXP (XEXP (src_const, 0), 0)) == LABEL_REF
+ && GET_CODE (XEXP (XEXP (src_const, 0), 1)) == LABEL_REF))
{
tem = find_reg_note (insn, REG_EQUAL, NULL_RTX);
@@ -7728,7 +7803,11 @@ cse_insn (insn, libcall_insn)
then be used in the sequel and we may be changing a two-operand insn
into a three-operand insn.
- Also do not do this if we are operating on a copy of INSN. */
+ Also do not do this if we are operating on a copy of INSN.
+
+ Also don't do this if INSN ends a libcall; this would cause an unrelated
+ register to be set in the middle of a libcall, and we then get bad code
+ if the libcall is deleted. */
if (n_sets == 1 && sets[0].rtl && GET_CODE (SET_DEST (sets[0].rtl)) == REG
&& NEXT_INSN (PREV_INSN (insn)) == insn
@@ -7736,7 +7815,8 @@ cse_insn (insn, libcall_insn)
&& REGNO (SET_SRC (sets[0].rtl)) >= FIRST_PSEUDO_REGISTER
&& REGNO_QTY_VALID_P (REGNO (SET_SRC (sets[0].rtl)))
&& (qty_first_reg[reg_qty[REGNO (SET_SRC (sets[0].rtl))]]
- == REGNO (SET_DEST (sets[0].rtl))))
+ == REGNO (SET_DEST (sets[0].rtl)))
+ && ! find_reg_note (insn, REG_RETVAL, NULL_RTX))
{
rtx prev = PREV_INSN (insn);
while (prev && GET_CODE (prev) == NOTE)
@@ -7810,7 +7890,7 @@ cse_insn (insn, libcall_insn)
prev_insn = insn;
}
-/* Remove from the ahsh table all expressions that reference memory. */
+/* Remove from the hash table all expressions that reference memory. */
static void
invalidate_memory ()
{
@@ -8120,6 +8200,7 @@ invalidate_skipped_block (start)
invalidate_for_call ();
}
+ invalidate_from_clobbers (PATTERN (insn));
note_stores (PATTERN (insn), invalidate_skipped_set);
}
}
@@ -8609,7 +8690,7 @@ cse_main (f, nregs, after_loop, file)
max_qty = val.nsets * 2;
if (file)
- fprintf (file, ";; Processing block from %d to %d, %d sets.\n",
+ fnotice (file, ";; Processing block from %d to %d, %d sets.\n",
INSN_UID (insn), val.last ? INSN_UID (val.last) : 0,
val.nsets);
@@ -8707,7 +8788,7 @@ cse_basic_block (from, to, next_branch, around_loop)
{
register enum rtx_code code = GET_CODE (insn);
int i;
- struct table_elt *p, *next;
+ struct table_elt *p;
/* If we have processed 1,000 insns, flush the hash table to
avoid extreme quadratic behavior. We must not include NOTEs
@@ -8721,10 +8802,10 @@ cse_basic_block (from, to, next_branch, around_loop)
if (code != NOTE && num_insns++ > 1000)
{
for (i = 0; i < NBUCKETS; i++)
- for (p = table[i]; p; p = next)
+ for (p = table[i]; p; p = table[i])
{
- next = p->next_same_hash;
-
+ /* Note that invalidate can remove elements
+ after P in the current hash chain. */
if (GET_CODE (p->exp) == REG)
invalidate (p->exp, p->mode);
else
diff --git a/gcc/dbxout.c b/gcc/dbxout.c
index b00b8467ec5..1926804d952 100644
--- a/gcc/dbxout.c
+++ b/gcc/dbxout.c
@@ -163,10 +163,12 @@ static int source_label_number = 1;
#define FORCE_TEXT
#endif
-/* If there is a system stabs.h, use it. Otherwise, use our own. */
-
-#ifndef HAVE_STABS_H
-#include "gstab.h"
+/* If there is a system stab.h, use it. Otherwise, use our own. */
+/* ??? This is supposed to describe the target's stab format, so using
+ the host HAVE_STAB_H appears to be wrong. For now, we use our own file
+ when cross compiling. */
+#if defined (USG) || !defined (HAVE_STAB_H) || defined (CROSS_COMPILE)
+#include "gstab.h" /* If doing DBX on sysV, use our own stab.h. */
#else
#include <stab.h>
@@ -494,7 +496,7 @@ dbxout_typedefs (syms)
void
dbxout_start_new_source_file (filename)
- char *filename;
+ char *filename ATTRIBUTE_UNUSED;
{
#ifdef DBX_USE_BINCL
struct dbx_file *n = (struct dbx_file *) xmalloc (sizeof *n);
@@ -579,8 +581,8 @@ dbxout_source_line (file, filename, lineno)
void
dbxout_finish (file, filename)
- FILE *file;
- char *filename;
+ FILE *file ATTRIBUTE_UNUSED;
+ char *filename ATTRIBUTE_UNUSED;
{
#ifdef DBX_OUTPUT_MAIN_SOURCE_FILE_END
DBX_OUTPUT_MAIN_SOURCE_FILE_END (file, filename);
@@ -2187,7 +2189,7 @@ dbxout_symbol_name (decl, suffix, letter)
static void
dbxout_prepare_symbol (decl)
- tree decl;
+ tree decl ATTRIBUTE_UNUSED;
{
#ifdef WINNING_GDB
char *filename = DECL_SOURCE_FILE (decl);
@@ -2680,7 +2682,7 @@ dbxout_really_begin_function (decl)
void
dbxout_begin_function (decl)
- tree decl;
+ tree decl ATTRIBUTE_UNUSED;
{
#ifdef DBX_FUNCTION_FIRST
dbxout_really_begin_function (decl);
diff --git a/gcc/defaults.h b/gcc/defaults.h
index 434d761afed..a0e3bfca57a 100644
--- a/gcc/defaults.h
+++ b/gcc/defaults.h
@@ -1,7 +1,7 @@
/* Definitions of various defaults for how to do assembler output
(most of which are designed to be appropriate for GAS or for
some BSD assembler).
- Copyright (C) 1992, 1996 Free Software Foundation, Inc.
+ Copyright (C) 1992, 1996, 1997, 1998 Free Software Foundation, Inc.
Contributed by Ron Guilmette (rfg@monkeys.com)
This file is part of GNU CC.
@@ -121,8 +121,7 @@ do { fprintf (FILE, "\t%s\t", ASM_LONG); \
/* This is how to output a reference to a user-level label named NAME. */
#ifndef ASM_OUTPUT_LABELREF
-#define ASM_OUTPUT_LABELREF(FILE,NAME) \
- do { fputs (USER_LABEL_PREFIX, FILE); fputs (NAME, FILE); } while (0)
+#define ASM_OUTPUT_LABELREF(FILE,NAME) asm_fprintf ((FILE), "%U%s", (NAME))
#endif
/* This determines whether or not we support weak symbols. */
@@ -134,6 +133,22 @@ do { fprintf (FILE, "\t%s\t", ASM_LONG); \
#endif
#endif
+/* If the target supports weak symbols, define TARGET_ATTRIBUTE_WEAK to
+ provide a weak attribute. Else define it to nothing.
+
+ This would normally belong in gansidecl.h, but SUPPORTS_WEAK is
+ not available at that time.
+
+ Note, this is only for use by target files which we know are to be
+ compiled by GCC. */
+#ifndef TARGET_ATTRIBUTE_WEAK
+# if SUPPORTS_WEAK
+# define TARGET_ATTRIBUTE_WEAK __attribute__ ((weak))
+# else
+# define TARGET_ATTRIBUTE_WEAK
+# endif
+#endif
+
/* If we have a definition of INCOMING_RETURN_ADDR_RTX, assume that
the rest of the DWARF 2 frame unwind support is also provided. */
#if !defined (DWARF2_UNWIND_INFO) && defined (INCOMING_RETURN_ADDR_RTX)
diff --git a/gcc/demangle.h b/gcc/demangle.h
deleted file mode 100644
index 1e1e705512a..00000000000
--- a/gcc/demangle.h
+++ /dev/null
@@ -1,108 +0,0 @@
-/* Defs for interface to demanglers.
- Copyright 1992, 1995, 1996 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. */
-
-
-#if !defined (DEMANGLE_H)
-#define DEMANGLE_H
-
-#ifdef IN_GCC
-#include "gansidecl.h"
-#define PARAMS(ARGS) PROTO(ARGS)
-#else /* ! IN_GCC */
-#include <ansidecl.h>
-#endif /* IN_GCC */
-
-/* Options passed to cplus_demangle (in 2nd parameter). */
-
-#define DMGL_NO_OPTS 0 /* For readability... */
-#define DMGL_PARAMS (1 << 0) /* Include function args */
-#define DMGL_ANSI (1 << 1) /* Include const, volatile, etc */
-#define DMGL_JAVA (1 << 2) /* Demangle as Java rather than C++. */
-
-#define DMGL_AUTO (1 << 8)
-#define DMGL_GNU (1 << 9)
-#define DMGL_LUCID (1 << 10)
-#define DMGL_ARM (1 << 11)
-/* If none of these are set, use 'current_demangling_style' as the default. */
-#define DMGL_STYLE_MASK (DMGL_AUTO|DMGL_GNU|DMGL_LUCID|DMGL_ARM)
-
-/* Enumeration of possible demangling styles.
-
- Lucid and ARM styles are still kept logically distinct, even though
- they now both behave identically. The resulting style is actual the
- union of both. I.E. either style recognizes both "__pt__" and "__rf__"
- for operator "->", even though the first is lucid style and the second
- is ARM style. (FIXME?) */
-
-extern enum demangling_styles
-{
- unknown_demangling = 0,
- auto_demangling = DMGL_AUTO,
- gnu_demangling = DMGL_GNU,
- lucid_demangling = DMGL_LUCID,
- arm_demangling = DMGL_ARM
-} current_demangling_style;
-
-/* Define string names for the various demangling styles. */
-
-#define AUTO_DEMANGLING_STYLE_STRING "auto"
-#define GNU_DEMANGLING_STYLE_STRING "gnu"
-#define LUCID_DEMANGLING_STYLE_STRING "lucid"
-#define ARM_DEMANGLING_STYLE_STRING "arm"
-
-/* Some macros to test what demangling style is active. */
-
-#define CURRENT_DEMANGLING_STYLE current_demangling_style
-#define AUTO_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_AUTO)
-#define GNU_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_GNU)
-#define LUCID_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_LUCID)
-#define ARM_DEMANGLING (CURRENT_DEMANGLING_STYLE & DMGL_ARM)
-
-extern char *
-cplus_demangle PARAMS ((const char *mangled, int options));
-
-extern int
-cplus_demangle_opname PARAMS ((const char *opname, char *result, int options));
-
-extern const char *
-cplus_mangle_opname PARAMS ((const char *opname, int options));
-
-/* Note: This sets global state. FIXME if you care about multi-threading. */
-
-extern void
-set_cplus_marker_for_demangling PARAMS ((int ch));
-
-extern void
-do_tlink PARAMS ((char **, char **));
-
-extern void
-collect_execute PARAMS ((char *, char **, char *));
-
-extern void
-collect_exit PARAMS ((int));
-
-extern int
-collect_wait PARAMS ((char *));
-
-extern void
-dump_file PARAMS ((char *));
-
-extern int
-file_exists PARAMS ((char *));
-
-#endif /* DEMANGLE_H */
diff --git a/gcc/doprint.c b/gcc/doprint.c
index e09e1988122..2dc4ddef976 100644
--- a/gcc/doprint.c
+++ b/gcc/doprint.c
@@ -1,11 +1,25 @@
/* Provide a version _doprnt in terms of fprintf.
- By Kaveh Ghazi (ghazi@caip.rutgers.edu) 3/29/98
Copyright (C) 1998 Free Software Foundation, Inc.
+ Contributed by Kaveh Ghazi (ghazi@caip.rutgers.edu) 3/29/98
+
+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. */
+
*/
#include "config.h"
#include "system.h"
-#include "gansidecl.h"
#undef _doprnt
#ifdef TEST /* Make sure to use the internal one. */
@@ -200,13 +214,13 @@ checkit VPROTO ((const char* format, ...))
va_list args;
int result;
-#ifndef __STDC__
+#ifndef ANSI_PROTOTYPES
char *format;
#endif
VA_START (args, format);
-#ifndef __STDC__
+#ifndef ANSI_PROTOTYPES
format = va_arg (args, char *);
#endif
diff --git a/gcc/dwarf2.h b/gcc/dwarf2.h
index db19904802c..ddbe1b823bb 100644
--- a/gcc/dwarf2.h
+++ b/gcc/dwarf2.h
@@ -4,21 +4,22 @@
Contributed by Gary Funck (gary@intrepid.com). Derived from the
DWARF 1 implementation written by Ron Guilmette (rfg@monkeys.com).
- 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
+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 derived from the DWARF specification (a public document)
Revision 2.0.0 (July 27, 1993) developed by the UNIX International
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 2d8bbc90e4b..b0c37a7c66a 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -1,5 +1,5 @@
/* Output Dwarf2 format symbol table information from the GNU C compiler.
- Copyright (C) 1992, 93, 95, 96, 97, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1992, 93, 95-98, 1999 Free Software Foundation, Inc.
Contributed by Gary Funck (gary@intrepid.com).
Derived from DWARF 1 implementation of Ron Guilmette (rfg@monkeys.com).
Extensively modified by Jason Merrill (jason@cygnus.com).
@@ -18,7 +18,8 @@ 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
/* The first part of this file deals with the DWARF 2 frame unwind
information, which is also used by the GCC efficient exception handling
@@ -71,10 +72,6 @@ dwarf2out_do_frame ()
#if defined (DWARF2_DEBUGGING_INFO) || defined (DWARF2_UNWIND_INFO)
-#ifndef __GNUC__
-#define inline
-#endif
-
/* How to start an assembler comment. */
#ifndef ASM_COMMENT_START
#define ASM_COMMENT_START ";#"
@@ -663,7 +660,7 @@ expand_builtin_dwarf_reg_size (reg_tree, target)
t = fold (build (COND_EXPR, integer_type_node, t2,
build_int_2 (ranges[n_ranges].size, 0), t));
}
- while (--n_ranges > 0);
+ while (--n_ranges >= 0);
}
return expand_expr (t, target, Pmode, 0);
}
@@ -1040,7 +1037,7 @@ static void
initial_return_save (rtl)
register rtx rtl;
{
- unsigned reg = -1;
+ unsigned int reg = (unsigned int) -1;
long offset = 0;
switch (GET_CODE (rtl))
@@ -1189,6 +1186,230 @@ dwarf2out_stack_adjust (insn)
dwarf2out_args_size (label, args_size);
}
+/* A temporary register used in adjusting SP or setting up the store_reg. */
+static unsigned cfa_temp_reg;
+
+/* A temporary value used in adjusting SP or setting up the store_reg. */
+static long cfa_temp_value;
+
+/* Record call frame debugging information for an expression, which either
+ sets SP or FP (adjusting how we calculate the frame address) or saves a
+ register to the stack. */
+
+static void
+dwarf2out_frame_debug_expr (expr, label)
+ rtx expr;
+ char *label;
+{
+ rtx src, dest;
+ long offset;
+
+ /* If RTX_FRAME_RELATED_P is set on a PARALLEL, process each member of
+ the PARALLEL independantly. The first element is always processed if
+ it is a SET. This is for backward compatability. Other elements
+ are processed only if they are SETs and the RTX_FRAME_RELATED_P
+ flag is set in them. */
+
+ if (GET_CODE (expr) == PARALLEL)
+ {
+ int par_index;
+ int limit = XVECLEN (expr, 0);
+
+ for (par_index = 0; par_index < limit; par_index++)
+ {
+ rtx x = XVECEXP (expr, 0, par_index);
+
+ if (GET_CODE (x) == SET &&
+ (RTX_FRAME_RELATED_P (x) || par_index == 0))
+ dwarf2out_frame_debug_expr (x, label);
+ }
+ return;
+ }
+
+ if (GET_CODE (expr) != SET)
+ abort ();
+
+ src = SET_SRC (expr);
+ dest = SET_DEST (expr);
+
+ switch (GET_CODE (dest))
+ {
+ case REG:
+ /* Update the CFA rule wrt SP or FP. Make sure src is
+ relative to the current CFA register. */
+ switch (GET_CODE (src))
+ {
+ /* Setting FP from SP. */
+ case REG:
+ if (cfa_reg != (unsigned) REGNO (src))
+ abort ();
+ if (REGNO (dest) != STACK_POINTER_REGNUM
+ && !(frame_pointer_needed
+ && REGNO (dest) == HARD_FRAME_POINTER_REGNUM))
+ abort ();
+ cfa_reg = REGNO (dest);
+ break;
+
+ case PLUS:
+ case MINUS:
+ if (dest == stack_pointer_rtx)
+ {
+ /* Adjusting SP. */
+ switch (GET_CODE (XEXP (src, 1)))
+ {
+ case CONST_INT:
+ offset = INTVAL (XEXP (src, 1));
+ break;
+ case REG:
+ if ((unsigned) REGNO (XEXP (src, 1)) != cfa_temp_reg)
+ abort ();
+ offset = cfa_temp_value;
+ break;
+ default:
+ abort ();
+ }
+
+ if (XEXP (src, 0) == hard_frame_pointer_rtx)
+ {
+ /* Restoring SP from FP in the epilogue. */
+ if (cfa_reg != (unsigned) HARD_FRAME_POINTER_REGNUM)
+ abort ();
+ cfa_reg = STACK_POINTER_REGNUM;
+ }
+ else if (XEXP (src, 0) != stack_pointer_rtx)
+ abort ();
+
+ if (GET_CODE (src) == PLUS)
+ offset = -offset;
+ if (cfa_reg == STACK_POINTER_REGNUM)
+ cfa_offset += offset;
+ if (cfa_store_reg == STACK_POINTER_REGNUM)
+ cfa_store_offset += offset;
+ }
+ else if (dest == hard_frame_pointer_rtx)
+ {
+ /* Either setting the FP from an offset of the SP,
+ or adjusting the FP */
+ if (! frame_pointer_needed
+ || REGNO (dest) != HARD_FRAME_POINTER_REGNUM)
+ abort ();
+
+ if (XEXP (src, 0) == stack_pointer_rtx
+ && GET_CODE (XEXP (src, 1)) == CONST_INT)
+ {
+ if (cfa_reg != STACK_POINTER_REGNUM)
+ abort ();
+ offset = INTVAL (XEXP (src, 1));
+ if (GET_CODE (src) == PLUS)
+ offset = -offset;
+ cfa_offset += offset;
+ cfa_reg = HARD_FRAME_POINTER_REGNUM;
+ }
+ else if (XEXP (src, 0) == hard_frame_pointer_rtx
+ && GET_CODE (XEXP (src, 1)) == CONST_INT)
+ {
+ if (cfa_reg != (unsigned) HARD_FRAME_POINTER_REGNUM)
+ abort ();
+ offset = INTVAL (XEXP (src, 1));
+ if (GET_CODE (src) == PLUS)
+ offset = -offset;
+ cfa_offset += offset;
+ }
+
+ else
+ abort();
+ }
+ else
+ {
+ if (GET_CODE (src) != PLUS
+ || XEXP (src, 1) != stack_pointer_rtx)
+ abort ();
+ if (GET_CODE (XEXP (src, 0)) != REG
+ || (unsigned) REGNO (XEXP (src, 0)) != cfa_temp_reg)
+ abort ();
+ if (cfa_reg != STACK_POINTER_REGNUM)
+ abort ();
+ cfa_store_reg = REGNO (dest);
+ cfa_store_offset = cfa_offset - cfa_temp_value;
+ }
+ break;
+
+ case CONST_INT:
+ cfa_temp_reg = REGNO (dest);
+ cfa_temp_value = INTVAL (src);
+ break;
+
+ case IOR:
+ if (GET_CODE (XEXP (src, 0)) != REG
+ || (unsigned) REGNO (XEXP (src, 0)) != cfa_temp_reg
+ || (unsigned) REGNO (dest) != cfa_temp_reg
+ || GET_CODE (XEXP (src, 1)) != CONST_INT)
+ abort ();
+ cfa_temp_value |= INTVAL (XEXP (src, 1));
+ break;
+
+ default:
+ abort ();
+ }
+ dwarf2out_def_cfa (label, cfa_reg, cfa_offset);
+ break;
+
+ case MEM:
+ /* Saving a register to the stack. Make sure dest is relative to the
+ CFA register. */
+ if (GET_CODE (src) != REG)
+ abort ();
+ switch (GET_CODE (XEXP (dest, 0)))
+ {
+ /* With a push. */
+ case PRE_INC:
+ case PRE_DEC:
+ offset = GET_MODE_SIZE (GET_MODE (dest));
+ if (GET_CODE (XEXP (dest, 0)) == PRE_INC)
+ offset = -offset;
+
+ if (REGNO (XEXP (XEXP (dest, 0), 0)) != STACK_POINTER_REGNUM
+ || cfa_store_reg != STACK_POINTER_REGNUM)
+ abort ();
+ cfa_store_offset += offset;
+ if (cfa_reg == STACK_POINTER_REGNUM)
+ cfa_offset = cfa_store_offset;
+
+ offset = -cfa_store_offset;
+ break;
+
+ /* With an offset. */
+ case PLUS:
+ case MINUS:
+ offset = INTVAL (XEXP (XEXP (dest, 0), 1));
+ if (GET_CODE (XEXP (dest, 0)) == MINUS)
+ offset = -offset;
+
+ if (cfa_store_reg != (unsigned) REGNO (XEXP (XEXP (dest, 0), 0)))
+ abort ();
+ offset -= cfa_store_offset;
+ break;
+
+ /* Without an offset. */
+ case REG:
+ if (cfa_store_reg != (unsigned) REGNO (XEXP (dest, 0)))
+ abort();
+ offset = -cfa_store_offset;
+ break;
+
+ default:
+ abort ();
+ }
+ dwarf2out_def_cfa (label, cfa_reg, cfa_offset);
+ dwarf2out_reg_save (label, REGNO (src), offset);
+ break;
+
+ default:
+ abort ();
+ }
+}
+
+
/* Record call frame debugging information for INSN, which either
sets SP or FP (adjusting how we calculate the frame address) or saves a
register to the stack. If INSN is NULL_RTX, initialize our state. */
@@ -1198,12 +1419,7 @@ dwarf2out_frame_debug (insn)
rtx insn;
{
char *label;
- rtx src, dest;
- long offset;
-
- /* A temporary register used in adjusting SP or setting up the store_reg. */
- static unsigned cfa_temp_reg;
- static long cfa_temp_value;
+ rtx src;
if (insn == NULL_RTX)
{
@@ -1230,194 +1446,10 @@ dwarf2out_frame_debug (insn)
src = find_reg_note (insn, REG_FRAME_RELATED_EXPR, NULL_RTX);
if (src)
insn = XEXP (src, 0);
- else
+ else
insn = PATTERN (insn);
- /* Assume that in a PARALLEL prologue insn, only the first elt is
- significant. Currently this is true. */
- if (GET_CODE (insn) == PARALLEL)
- insn = XVECEXP (insn, 0, 0);
- if (GET_CODE (insn) != SET)
- abort ();
-
- src = SET_SRC (insn);
- dest = SET_DEST (insn);
-
- switch (GET_CODE (dest))
- {
- case REG:
- /* Update the CFA rule wrt SP or FP. Make sure src is
- relative to the current CFA register. */
- switch (GET_CODE (src))
- {
- /* Setting FP from SP. */
- case REG:
- if (cfa_reg != REGNO (src))
- abort ();
- if (REGNO (dest) != STACK_POINTER_REGNUM
- && !(frame_pointer_needed
- && REGNO (dest) == HARD_FRAME_POINTER_REGNUM))
- abort ();
- cfa_reg = REGNO (dest);
- break;
-
- case PLUS:
- case MINUS:
- if (dest == stack_pointer_rtx)
- {
- /* Adjusting SP. */
- switch (GET_CODE (XEXP (src, 1)))
- {
- case CONST_INT:
- offset = INTVAL (XEXP (src, 1));
- break;
- case REG:
- if (REGNO (XEXP (src, 1)) != cfa_temp_reg)
- abort ();
- offset = cfa_temp_value;
- break;
- default:
- abort ();
- }
-
- if (XEXP (src, 0) == hard_frame_pointer_rtx)
- {
- /* Restoring SP from FP in the epilogue. */
- if (cfa_reg != HARD_FRAME_POINTER_REGNUM)
- abort ();
- cfa_reg = STACK_POINTER_REGNUM;
- }
- else if (XEXP (src, 0) != stack_pointer_rtx)
- abort ();
-
- if (GET_CODE (src) == PLUS)
- offset = -offset;
- if (cfa_reg == STACK_POINTER_REGNUM)
- cfa_offset += offset;
- if (cfa_store_reg == STACK_POINTER_REGNUM)
- cfa_store_offset += offset;
- }
- else if (dest == hard_frame_pointer_rtx)
- {
- /* Either setting the FP from an offset of the SP,
- or adjusting the FP */
- if (! frame_pointer_needed
- || REGNO (dest) != HARD_FRAME_POINTER_REGNUM)
- abort ();
-
- if (XEXP (src, 0) == stack_pointer_rtx
- && GET_CODE (XEXP (src, 1)) == CONST_INT)
- {
- if (cfa_reg != STACK_POINTER_REGNUM)
- abort ();
- offset = INTVAL (XEXP (src, 1));
- if (GET_CODE (src) == PLUS)
- offset = -offset;
- cfa_offset += offset;
- cfa_reg = HARD_FRAME_POINTER_REGNUM;
- }
- else if (XEXP (src, 0) == hard_frame_pointer_rtx
- && GET_CODE (XEXP (src, 1)) == CONST_INT)
- {
- if (cfa_reg != HARD_FRAME_POINTER_REGNUM)
- abort ();
- offset = INTVAL (XEXP (src, 1));
- if (GET_CODE (src) == PLUS)
- offset = -offset;
- cfa_offset += offset;
- }
-
- else
- abort();
- }
- else
- {
- if (GET_CODE (src) != PLUS
- || XEXP (src, 1) != stack_pointer_rtx)
- abort ();
- if (GET_CODE (XEXP (src, 0)) != REG
- || REGNO (XEXP (src, 0)) != cfa_temp_reg)
- abort ();
- if (cfa_reg != STACK_POINTER_REGNUM)
- abort ();
- cfa_store_reg = REGNO (dest);
- cfa_store_offset = cfa_offset - cfa_temp_value;
- }
- break;
-
- case CONST_INT:
- cfa_temp_reg = REGNO (dest);
- cfa_temp_value = INTVAL (src);
- break;
-
- case IOR:
- if (GET_CODE (XEXP (src, 0)) != REG
- || REGNO (XEXP (src, 0)) != cfa_temp_reg
- || REGNO (dest) != cfa_temp_reg
- || GET_CODE (XEXP (src, 1)) != CONST_INT)
- abort ();
- cfa_temp_value |= INTVAL (XEXP (src, 1));
- break;
-
- default:
- abort ();
- }
- dwarf2out_def_cfa (label, cfa_reg, cfa_offset);
- break;
-
- case MEM:
- /* Saving a register to the stack. Make sure dest is relative to the
- CFA register. */
- if (GET_CODE (src) != REG)
- abort ();
- switch (GET_CODE (XEXP (dest, 0)))
- {
- /* With a push. */
- case PRE_INC:
- case PRE_DEC:
- offset = GET_MODE_SIZE (GET_MODE (dest));
- if (GET_CODE (XEXP (dest, 0)) == PRE_INC)
- offset = -offset;
-
- if (REGNO (XEXP (XEXP (dest, 0), 0)) != STACK_POINTER_REGNUM
- || cfa_store_reg != STACK_POINTER_REGNUM)
- abort ();
- cfa_store_offset += offset;
- if (cfa_reg == STACK_POINTER_REGNUM)
- cfa_offset = cfa_store_offset;
-
- offset = -cfa_store_offset;
- break;
-
- /* With an offset. */
- case PLUS:
- case MINUS:
- offset = INTVAL (XEXP (XEXP (dest, 0), 1));
- if (GET_CODE (src) == MINUS)
- offset = -offset;
-
- if (cfa_store_reg != REGNO (XEXP (XEXP (dest, 0), 0)))
- abort ();
- offset -= cfa_store_offset;
- break;
-
- /* Without an offset. */
- case REG:
- if (cfa_store_reg != REGNO (XEXP (dest, 0)))
- abort();
- offset = -cfa_store_offset;
- break;
-
- default:
- abort ();
- }
- dwarf2out_def_cfa (label, cfa_reg, cfa_offset);
- dwarf2out_reg_save (label, REGNO (src), offset);
- break;
-
- default:
- abort ();
- }
+ dwarf2out_frame_debug_expr (insn, label);
}
/* Return the size of an unsigned LEB128 quantity. */
@@ -1691,7 +1723,7 @@ output_call_frame_info (for_eh)
#else
tree label = get_file_function_name ('F');
- data_section ();
+ force_data_section ();
ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (PTR_SIZE));
ASM_GLOBALIZE_LABEL (asm_out_file, IDENTIFIER_POINTER (label));
ASM_OUTPUT_LABEL (asm_out_file, IDENTIFIER_POINTER (label));
@@ -1829,8 +1861,16 @@ output_call_frame_info (for_eh)
fputc ('\n', asm_out_file);
ASM_OUTPUT_LABEL (asm_out_file, l1);
+ /* ??? This always emits a 4 byte offset when for_eh is true, but it
+ emits a target dependent sized offset when for_eh is not true.
+ This inconsistency may confuse gdb. The only case where we need a
+ non-4 byte offset is for the Irix6 N64 ABI, so we may lose SGI
+ compatibility if we emit a 4 byte offset. We need a 4 byte offset
+ though in order to be compatible with the dwarf_fde struct in frame.c.
+ If the for_eh case is changed, then the struct in frame.c has
+ to be adjusted appropriately. */
if (for_eh)
- ASM_OUTPUT_DWARF_DELTA (asm_out_file, l1, "__FRAME_BEGIN__");
+ ASM_OUTPUT_DWARF_DELTA4 (asm_out_file, l1, "__FRAME_BEGIN__");
else
ASM_OUTPUT_DWARF_OFFSET (asm_out_file, stripattributes (FRAME_SECTION));
if (flag_debug_asm)
@@ -2006,7 +2046,7 @@ typedef enum
dw_val_class_die_ref,
dw_val_class_fde_ref,
dw_val_class_lbl_id,
- dw_val_class_section_offset,
+ dw_val_class_lbl_offset,
dw_val_class_str
}
dw_val_class;
@@ -2085,7 +2125,6 @@ typedef struct dw_val_struct
unsigned val_fde_index;
char *val_str;
char *val_lbl_id;
- char *val_section;
unsigned char val_flag;
}
v;
@@ -2444,7 +2483,7 @@ static void add_AT_addr PROTO((dw_die_ref,
enum dwarf_attribute, char *));
static void add_AT_lbl_id PROTO((dw_die_ref,
enum dwarf_attribute, char *));
-static void add_AT_section_offset PROTO((dw_die_ref,
+static void add_AT_lbl_offset PROTO((dw_die_ref,
enum dwarf_attribute, char *));
static int is_extern_subr_die PROTO((dw_die_ref));
static dw_attr_ref get_AT PROTO((dw_die_ref,
@@ -2617,6 +2656,22 @@ static unsigned lookup_filename PROTO((char *));
#define BSS_SECTION ".bss"
#endif
+/* Labels we insert at beginning sections we can reference instead of
+ the section names themselves. */
+
+#ifndef TEXT_SECTION_LABEL
+#define TEXT_SECTION_LABEL "Ltext"
+#endif
+#ifndef DEBUG_LINE_SECTION_LABEL
+#define DEBUG_LINE_SECTION_LABEL "Ldebug_line"
+#endif
+#ifndef DEBUG_INFO_SECTION_LABEL
+#define DEBUG_INFO_SECTION_LABEL "Ldebug_info"
+#endif
+#ifndef ABBREV_SECTION_LABEL
+#define ABBREV_SECTION_LABEL "Ldebug_abbrev"
+#endif
+
/* Definitions of defaults for formats and names of various special
(artificial) labels which may be generated within this file (when the -g
@@ -2625,6 +2680,10 @@ static unsigned lookup_filename PROTO((char *));
typically, overriding these defaults is unnecessary. */
static char text_end_label[MAX_ARTIFICIAL_LABEL_BYTES];
+static char text_section_label[MAX_ARTIFICIAL_LABEL_BYTES];
+static char abbrev_section_label[MAX_ARTIFICIAL_LABEL_BYTES];
+static char debug_info_section_label[MAX_ARTIFICIAL_LABEL_BYTES];
+static char debug_line_section_label[MAX_ARTIFICIAL_LABEL_BYTES];
#ifndef TEXT_END_LABEL
#define TEXT_END_LABEL "Letext"
@@ -2661,13 +2720,16 @@ static char text_end_label[MAX_ARTIFICIAL_LABEL_BYTES];
macro has the same effect as ASM_OUTPUT_LABELREF, but copies to
a string rather than writing to a file. */
#ifndef ASM_NAME_TO_STRING
-#define ASM_NAME_TO_STRING(STR, NAME) \
- do { \
- if ((NAME)[0] == '*') \
- dyn_string_append (STR, NAME + 1); \
- else \
- dyn_string_append (STR, NAME); \
- } \
+#define ASM_NAME_TO_STRING(STR, NAME) \
+ do { \
+ if ((NAME)[0] == '*') \
+ dyn_string_append (STR, NAME + 1); \
+ else \
+ { \
+ dyn_string_append (STR, user_label_prefix); \
+ dyn_string_append (STR, NAME); \
+ } \
+ } \
while (0)
#endif
@@ -3821,17 +3883,17 @@ add_AT_lbl_id (die, attr_kind, lbl_id)
/* Add a section offset attribute value to a DIE. */
static inline void
-add_AT_section_offset (die, attr_kind, section)
+add_AT_lbl_offset (die, attr_kind, label)
register dw_die_ref die;
register enum dwarf_attribute attr_kind;
- register char *section;
+ register char *label;
{
register dw_attr_ref attr = (dw_attr_ref) xmalloc (sizeof (dw_attr_node));
attr->dw_attr_next = NULL;
attr->dw_attr = attr_kind;
- attr->dw_attr_val.val_class = dw_val_class_section_offset;
- attr->dw_attr_val.v.val_section = section;
+ attr->dw_attr_val.val_class = dw_val_class_lbl_offset;
+ attr->dw_attr_val.v.val_lbl_id = label;
add_dwarf_attr (die, attr);
}
@@ -4294,11 +4356,9 @@ print_die (die, outfile)
fprintf (outfile, "die -> <null>");
break;
case dw_val_class_lbl_id:
+ case dw_val_class_lbl_offset:
fprintf (outfile, "label: %s", a->dw_attr_val.v.val_lbl_id);
break;
- case dw_val_class_section_offset:
- fprintf (outfile, "section: %s", a->dw_attr_val.v.val_section);
- break;
case dw_val_class_str:
if (a->dw_attr_val.v.val_str != NULL)
fprintf (outfile, "\"%s\"", a->dw_attr_val.v.val_str);
@@ -4662,7 +4722,7 @@ size_of_die (die)
case dw_val_class_lbl_id:
size += PTR_SIZE;
break;
- case dw_val_class_section_offset:
+ case dw_val_class_lbl_offset:
size += DWARF_OFFSET_SIZE;
break;
case dw_val_class_str:
@@ -4975,7 +5035,7 @@ value_format (v)
return DW_FORM_data;
case dw_val_class_lbl_id:
return DW_FORM_addr;
- case dw_val_class_section_offset:
+ case dw_val_class_lbl_offset:
return DW_FORM_data;
case dw_val_class_str:
return DW_FORM_string;
@@ -5197,7 +5257,6 @@ output_die (die)
register unsigned long ref_offset;
register unsigned long size;
register dw_loc_descr_ref loc;
- register int i;
output_uleb128 (die->die_abbrev);
if (flag_debug_asm)
@@ -5300,24 +5359,27 @@ output_die (die)
break;
case dw_val_class_float:
- ASM_OUTPUT_DWARF_DATA1 (asm_out_file,
- a->dw_attr_val.v.val_float.length * 4);
- if (flag_debug_asm)
- fprintf (asm_out_file, "\t%s %s",
- ASM_COMMENT_START, dwarf_attr_name (a->dw_attr));
-
- fputc ('\n', asm_out_file);
- for (i = 0; i < a->dw_attr_val.v.val_float.length; ++i)
- {
- ASM_OUTPUT_DWARF_DATA4 (asm_out_file,
- a->dw_attr_val.v.val_float.array[i]);
- if (flag_debug_asm)
- fprintf (asm_out_file, "\t%s fp constant word %d",
- ASM_COMMENT_START, i);
+ {
+ register unsigned int i;
+ ASM_OUTPUT_DWARF_DATA1 (asm_out_file,
+ a->dw_attr_val.v.val_float.length * 4);
+ if (flag_debug_asm)
+ fprintf (asm_out_file, "\t%s %s",
+ ASM_COMMENT_START, dwarf_attr_name (a->dw_attr));
+
+ fputc ('\n', asm_out_file);
+ for (i = 0; i < a->dw_attr_val.v.val_float.length; ++i)
+ {
+ ASM_OUTPUT_DWARF_DATA4 (asm_out_file,
+ a->dw_attr_val.v.val_float.array[i]);
+ if (flag_debug_asm)
+ fprintf (asm_out_file, "\t%s fp constant word %u",
+ ASM_COMMENT_START, i);
- fputc ('\n', asm_out_file);
- }
+ fputc ('\n', asm_out_file);
+ }
break;
+ }
case dw_val_class_flag:
ASM_OUTPUT_DWARF_DATA1 (asm_out_file, a->dw_attr_val.v.val_flag);
@@ -5348,10 +5410,8 @@ output_die (die)
ASM_OUTPUT_DWARF_ADDR (asm_out_file, a->dw_attr_val.v.val_lbl_id);
break;
- case dw_val_class_section_offset:
- ASM_OUTPUT_DWARF_OFFSET (asm_out_file,
- stripattributes
- (a->dw_attr_val.v.val_section));
+ case dw_val_class_lbl_offset:
+ ASM_OUTPUT_DWARF_OFFSET (asm_out_file, a->dw_attr_val.v.val_lbl_id);
break;
case dw_val_class_str:
@@ -5360,7 +5420,7 @@ output_die (die)
else
ASM_OUTPUT_ASCII (asm_out_file,
a->dw_attr_val.v.val_str,
- strlen (a->dw_attr_val.v.val_str) + 1);
+ (int) strlen (a->dw_attr_val.v.val_str) + 1);
break;
default:
@@ -5411,7 +5471,7 @@ output_compilation_unit_header ()
fprintf (asm_out_file, "\t%s DWARF version number", ASM_COMMENT_START);
fputc ('\n', asm_out_file);
- ASM_OUTPUT_DWARF_OFFSET (asm_out_file, stripattributes (ABBREV_SECTION));
+ ASM_OUTPUT_DWARF_OFFSET (asm_out_file, abbrev_section_label);
if (flag_debug_asm)
fprintf (asm_out_file, "\t%s Offset Into Abbrev. Section",
ASM_COMMENT_START);
@@ -5484,7 +5544,7 @@ output_pubnames ()
fprintf (asm_out_file, "\t%s DWARF Version", ASM_COMMENT_START);
fputc ('\n', asm_out_file);
- ASM_OUTPUT_DWARF_OFFSET (asm_out_file, stripattributes (DEBUG_INFO_SECTION));
+ ASM_OUTPUT_DWARF_OFFSET (asm_out_file, debug_info_section_label);
if (flag_debug_asm)
fprintf (asm_out_file, "\t%s Offset of Compilation Unit Info.",
ASM_COMMENT_START);
@@ -5512,7 +5572,8 @@ output_pubnames ()
}
else
{
- ASM_OUTPUT_ASCII (asm_out_file, pub->name, strlen (pub->name) + 1);
+ ASM_OUTPUT_ASCII (asm_out_file, pub->name,
+ (int) strlen (pub->name) + 1);
}
fputc ('\n', asm_out_file);
@@ -5564,7 +5625,7 @@ output_aranges ()
fprintf (asm_out_file, "\t%s DWARF Version", ASM_COMMENT_START);
fputc ('\n', asm_out_file);
- ASM_OUTPUT_DWARF_OFFSET (asm_out_file, stripattributes (DEBUG_INFO_SECTION));
+ ASM_OUTPUT_DWARF_OFFSET (asm_out_file, debug_info_section_label);
if (flag_debug_asm)
fprintf (asm_out_file, "\t%s Offset of Compilation Unit Info.",
ASM_COMMENT_START);
@@ -5590,13 +5651,13 @@ output_aranges ()
ASM_COMMENT_START, 2 * PTR_SIZE);
fputc ('\n', asm_out_file);
- ASM_OUTPUT_DWARF_ADDR (asm_out_file, stripattributes (TEXT_SECTION));
+ ASM_OUTPUT_DWARF_ADDR (asm_out_file, text_section_label);
if (flag_debug_asm)
fprintf (asm_out_file, "\t%s Address", ASM_COMMENT_START);
fputc ('\n', asm_out_file);
ASM_OUTPUT_DWARF_ADDR_DELTA (asm_out_file, text_end_label,
- stripattributes (TEXT_SECTION));
+ text_section_label);
if (flag_debug_asm)
fprintf (asm_out_file, "%s Length", ASM_COMMENT_START);
@@ -5749,7 +5810,7 @@ output_line_info ()
{
ASM_OUTPUT_ASCII (asm_out_file,
file_table[ft_index],
- strlen (file_table[ft_index]) + 1);
+ (int) strlen (file_table[ft_index]) + 1);
}
fputc ('\n', asm_out_file);
@@ -5781,14 +5842,14 @@ output_line_info ()
fputc ('\n', asm_out_file);
ASM_OUTPUT_DWARF_DATA1 (asm_out_file, DW_LNE_set_address);
fputc ('\n', asm_out_file);
- ASM_OUTPUT_DWARF_ADDR (asm_out_file, stripattributes (TEXT_SECTION));
+ ASM_OUTPUT_DWARF_ADDR (asm_out_file, text_section_label);
fputc ('\n', asm_out_file);
/* Generate the line number to PC correspondence table, encoded as
a series of state machine operations. */
current_file = 1;
current_line = 1;
- strcpy (prev_line_label, stripattributes (TEXT_SECTION));
+ strcpy (prev_line_label, text_section_label);
for (lt_index = 1; lt_index < line_info_table_in_use; ++lt_index)
{
register dw_line_info_ref line_info;
@@ -7071,6 +7132,38 @@ add_location_or_const_value_attribute (die, decl)
&& TYPE_SIZE (declared_type) <= TYPE_SIZE (passed_type))
rtl = DECL_INCOMING_RTL (decl);
}
+
+ /* If the parm was passed in registers, but lives on the stack, then
+ make a big endian correction if the mode of the type of the
+ parameter is not the same as the mode of the rtl. */
+ /* ??? This is the same series of checks that are made in dbxout.c before
+ we reach the big endian correction code there. It isn't clear if all
+ of these checks are necessary here, but keeping them all is the safe
+ thing to do. */
+ else if (GET_CODE (rtl) == MEM
+ && XEXP (rtl, 0) != const0_rtx
+ && ! CONSTANT_P (XEXP (rtl, 0))
+ /* Not passed in memory. */
+ && GET_CODE (DECL_INCOMING_RTL (decl)) != MEM
+ /* Not passed by invisible reference. */
+ && (GET_CODE (XEXP (rtl, 0)) != REG
+ || REGNO (XEXP (rtl, 0)) == HARD_FRAME_POINTER_REGNUM
+ || REGNO (XEXP (rtl, 0)) == STACK_POINTER_REGNUM
+#if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
+ || REGNO (XEXP (rtl, 0)) == ARG_POINTER_REGNUM
+#endif
+ )
+ /* Big endian correction check. */
+ && BYTES_BIG_ENDIAN
+ && TYPE_MODE (TREE_TYPE (decl)) != GET_MODE (rtl)
+ && (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (decl)))
+ < UNITS_PER_WORD))
+ {
+ int offset = (UNITS_PER_WORD
+ - GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (decl))));
+ rtl = gen_rtx_MEM (TYPE_MODE (TREE_TYPE (decl)),
+ plus_constant (XEXP (rtl, 0), offset));
+ }
}
if (rtl == NULL_RTX)
@@ -7543,7 +7636,7 @@ push_decl_scope (scope)
subtype. In such a case, we need to search the decl_scope_table to
find the parent of this subtype. */
- if (TREE_CODE_CLASS (TREE_CODE (scope)) == 't')
+ if (AGGREGATE_TYPE_P (scope))
containing_scope = TYPE_CONTEXT (scope);
else
containing_scope = NULL_TREE;
@@ -7595,6 +7688,12 @@ scope_die_for (t, context_die)
if (containing_scope && TREE_CODE (containing_scope) == NAMESPACE_DECL)
containing_scope = NULL_TREE;
+ /* Ignore function type "scopes" from the C frontend. They mean that
+ a tagged type is local to a parmlist of a function declarator, but
+ that isn't useful to DWARF. */
+ if (containing_scope && TREE_CODE (containing_scope) == FUNCTION_TYPE)
+ containing_scope = NULL_TREE;
+
/* Function-local tags and functions get stuck in limbo until they are
fixed up by decls_for_scope. */
if (context_die == NULL && containing_scope != NULL_TREE
@@ -7631,12 +7730,14 @@ scope_die_for (t, context_die)
if (i < 0)
{
- if (scope_die != comp_unit_die
- || TREE_CODE_CLASS (TREE_CODE (containing_scope)) != 't')
+ if (TREE_CODE_CLASS (TREE_CODE (containing_scope)) != 't')
abort ();
if (debug_info_level > DINFO_LEVEL_TERSE
&& !TREE_ASM_WRITTEN (containing_scope))
abort ();
+
+ /* If none of the current dies are suitable, we get file scope. */
+ scope_die = comp_unit_die;
}
}
@@ -8515,7 +8616,13 @@ gen_label_die (decl, context_die)
else
{
insn = DECL_RTL (decl);
- if (GET_CODE (insn) == CODE_LABEL)
+
+ /* Deleted labels are programmer specified labels which have been
+ eliminated because of various optimisations. We still emit them
+ here so that it is possible to put breakpoints on them. */
+ if (GET_CODE (insn) == CODE_LABEL
+ || ((GET_CODE (insn) == NOTE
+ && NOTE_LINE_NUMBER (insn) == NOTE_INSN_DELETED_LABEL)))
{
/* When optimization is enabled (via -O) some parts of the compiler
(e.g. jump.c and cse.c) may try to delete CODE_LABEL insns which
@@ -8822,7 +8929,7 @@ gen_struct_or_union_type_die (type, context_die)
return;
if (TYPE_CONTEXT (type) != NULL_TREE
- && TREE_CODE_CLASS (TREE_CODE (TYPE_CONTEXT (type))) == 't')
+ && AGGREGATE_TYPE_P (TYPE_CONTEXT (type)))
nested = 1;
scope_die = scope_die_for (type, context_die);
@@ -9035,7 +9142,7 @@ gen_type_die (type, context_die)
/* If this is a nested type whose containing class hasn't been
written out yet, writing it out will cover this one, too. */
if (TYPE_CONTEXT (type)
- && TREE_CODE_CLASS (TREE_CODE (TYPE_CONTEXT (type))) == 't'
+ && AGGREGATE_TYPE_P (TYPE_CONTEXT (type))
&& ! TREE_ASM_WRITTEN (TYPE_CONTEXT (type)))
{
gen_type_die (TYPE_CONTEXT (type), context_die);
@@ -9054,7 +9161,7 @@ gen_type_die (type, context_die)
gen_struct_or_union_type_die (type, context_die);
if (TYPE_CONTEXT (type)
- && TREE_CODE_CLASS (TREE_CODE (TYPE_CONTEXT (type))) == 't'
+ && AGGREGATE_TYPE_P (TYPE_CONTEXT (type))
&& ! TREE_ASM_WRITTEN (TYPE_CONTEXT (type)))
pop_decl_scope ();
@@ -9791,6 +9898,21 @@ dwarf2out_init (asm_out_file, main_input_filename)
gen_compile_unit_die (main_input_filename);
ASM_GENERATE_INTERNAL_LABEL (text_end_label, TEXT_END_LABEL, 0);
+ ASM_GENERATE_INTERNAL_LABEL (abbrev_section_label, ABBREV_SECTION_LABEL, 0);
+ ASM_GENERATE_INTERNAL_LABEL (text_section_label, TEXT_SECTION_LABEL, 0);
+ ASM_GENERATE_INTERNAL_LABEL (debug_info_section_label,
+ DEBUG_INFO_SECTION_LABEL, 0);
+ ASM_GENERATE_INTERNAL_LABEL (debug_line_section_label,
+ DEBUG_LINE_SECTION_LABEL, 0);
+
+ ASM_OUTPUT_SECTION (asm_out_file, ABBREV_SECTION);
+ ASM_OUTPUT_LABEL (asm_out_file, abbrev_section_label);
+ ASM_OUTPUT_SECTION (asm_out_file, TEXT_SECTION);
+ ASM_OUTPUT_LABEL (asm_out_file, text_section_label);
+ ASM_OUTPUT_SECTION (asm_out_file, DEBUG_INFO_SECTION);
+ ASM_OUTPUT_LABEL (asm_out_file, debug_info_section_label);
+ ASM_OUTPUT_SECTION (asm_out_file, DEBUG_LINE_SECTION);
+ ASM_OUTPUT_LABEL (asm_out_file, debug_line_section_label);
}
/* Output stuff that dwarf requires at the end of every file,
@@ -9858,12 +9980,12 @@ dwarf2out_finish ()
was in .text. */
if (separate_line_info_table_in_use == 0)
{
- add_AT_lbl_id (comp_unit_die, DW_AT_low_pc,
- stripattributes (TEXT_SECTION));
+ add_AT_lbl_id (comp_unit_die, DW_AT_low_pc, text_section_label);
add_AT_lbl_id (comp_unit_die, DW_AT_high_pc, text_end_label);
}
- add_AT_section_offset (comp_unit_die, DW_AT_stmt_list, DEBUG_LINE_SECTION);
+ add_AT_lbl_offset (comp_unit_die, DW_AT_stmt_list,
+ debug_line_section_label);
}
/* Output the abbreviation table. */
diff --git a/gcc/dwarfout.c b/gcc/dwarfout.c
index 660865b11d6..388c4a40081 100644
--- a/gcc/dwarfout.c
+++ b/gcc/dwarfout.c
@@ -1,5 +1,5 @@
/* Output Dwarf format symbol table information from the GNU C compiler.
- Copyright (C) 1992, 1993, 1995, 1996, 1997 Free Software Foundation, Inc.
+ Copyright (C) 1992, 1993, 95-98, 1999 Free Software Foundation, Inc.
Contributed by Ron Guilmette (rfg@monkeys.com) of Network Computing Devices.
This file is part of GNU CC.
@@ -63,10 +63,6 @@ extern char *getpwd PROTO((void));
/* Note that the implementation of C++ support herein is (as yet) unfinished.
If you want to try to complete it, more power to you. */
-#if !defined(__GNUC__) || (NDEBUG != 1)
-#define inline
-#endif
-
/* How to start an assembler comment. */
#ifndef ASM_COMMENT_START
#define ASM_COMMENT_START ";#"
@@ -857,10 +853,20 @@ static int is_redundant_typedef PROTO((tree));
} while (0)
#endif
+/* ASM_OUTPUT_DWARF_STRING is defined to output an ascii string, but to
+ NOT issue a trailing newline. We define ASM_OUTPUT_DWARF_STRING_NEWLINE
+ based on whether ASM_OUTPUT_DWARF_STRING is defined or not. If it is
+ defined, we call it, then issue the line feed. If not, we supply a
+ default defintion of calling ASM_OUTPUT_ASCII */
+
#ifndef ASM_OUTPUT_DWARF_STRING
-#define ASM_OUTPUT_DWARF_STRING(FILE,P) \
+#define ASM_OUTPUT_DWARF_STRING_NEWLINE(FILE,P) \
ASM_OUTPUT_ASCII ((FILE), P, strlen (P)+1)
+#else
+#define ASM_OUTPUT_DWARF_STRING_NEWLINE(FILE,P) \
+ ASM_OUTPUT_DWARF_STRING (FILE,P), ASM_OUTPUT_DWARF_STRING (FILE,"\n")
#endif
+
/************************ general utility functions **************************/
@@ -1893,7 +1899,7 @@ output_enumeral_list (link)
output_enumeral_list (TREE_CHAIN (link));
ASM_OUTPUT_DWARF_DATA4 (asm_out_file,
(unsigned) TREE_INT_CST_LOW (TREE_VALUE (link)));
- ASM_OUTPUT_DWARF_STRING (asm_out_file,
+ ASM_OUTPUT_DWARF_STRING_NEWLINE (asm_out_file,
IDENTIFIER_POINTER (TREE_PURPOSE (link)));
}
}
@@ -2256,7 +2262,7 @@ const_value_attribute (rtl)
break;
case CONST_STRING:
- ASM_OUTPUT_DWARF_STRING (asm_out_file, XSTR (rtl, 0));
+ ASM_OUTPUT_DWARF_STRING_NEWLINE (asm_out_file, XSTR (rtl, 0));
break;
case SYMBOL_REF:
@@ -2466,7 +2472,7 @@ name_attribute (name_string)
if (name_string && *name_string)
{
ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_name);
- ASM_OUTPUT_DWARF_STRING (asm_out_file, name_string);
+ ASM_OUTPUT_DWARF_STRING_NEWLINE (asm_out_file, name_string);
}
}
@@ -2904,7 +2910,7 @@ comp_dir_attribute (dirname)
register char *dirname;
{
ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_comp_dir);
- ASM_OUTPUT_DWARF_STRING (asm_out_file, dirname);
+ ASM_OUTPUT_DWARF_STRING_NEWLINE (asm_out_file, dirname);
}
static inline void
@@ -2942,7 +2948,7 @@ prototyped_attribute (func_type)
&& (TYPE_ARG_TYPES (func_type) != NULL))
{
ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_prototyped);
- ASM_OUTPUT_DWARF_STRING (asm_out_file, "");
+ ASM_OUTPUT_DWARF_STRING_NEWLINE (asm_out_file, "");
}
}
@@ -2951,7 +2957,7 @@ producer_attribute (producer)
register char *producer;
{
ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_producer);
- ASM_OUTPUT_DWARF_STRING (asm_out_file, producer);
+ ASM_OUTPUT_DWARF_STRING_NEWLINE (asm_out_file, producer);
}
static inline void
@@ -2961,7 +2967,7 @@ inline_attribute (decl)
if (DECL_INLINE (decl))
{
ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_inline);
- ASM_OUTPUT_DWARF_STRING (asm_out_file, "");
+ ASM_OUTPUT_DWARF_STRING_NEWLINE (asm_out_file, "");
}
}
@@ -3024,7 +3030,7 @@ pure_or_virtual_attribute (func_decl)
else
#endif
ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_virtual);
- ASM_OUTPUT_DWARF_STRING (asm_out_file, "");
+ ASM_OUTPUT_DWARF_STRING_NEWLINE (asm_out_file, "");
}
}
@@ -3513,7 +3519,12 @@ output_label_die (arg)
{
register rtx insn = DECL_RTL (decl);
- if (GET_CODE (insn) == CODE_LABEL)
+ /* Deleted labels are programmer specified labels which have been
+ eliminated because of various optimisations. We still emit them
+ here so that it is possible to put breakpoints on them. */
+ if (GET_CODE (insn) == CODE_LABEL
+ || ((GET_CODE (insn) == NOTE
+ && NOTE_LINE_NUMBER (insn) == NOTE_INSN_DELETED_LABEL)))
{
char label[MAX_ARTIFICIAL_LABEL_BYTES];
@@ -3751,17 +3762,17 @@ output_inheritance_die (arg)
if (TREE_VIA_VIRTUAL (binfo))
{
ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_virtual);
- ASM_OUTPUT_DWARF_STRING (asm_out_file, "");
+ ASM_OUTPUT_DWARF_STRING_NEWLINE (asm_out_file, "");
}
if (TREE_VIA_PUBLIC (binfo))
{
ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_public);
- ASM_OUTPUT_DWARF_STRING (asm_out_file, "");
+ ASM_OUTPUT_DWARF_STRING_NEWLINE (asm_out_file, "");
}
else if (TREE_VIA_PROTECTED (binfo))
{
ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_protected);
- ASM_OUTPUT_DWARF_STRING (asm_out_file, "");
+ ASM_OUTPUT_DWARF_STRING_NEWLINE (asm_out_file, "");
}
}
@@ -5121,7 +5132,7 @@ dwarfout_file_scope_decl (decl, set_finalizing)
ASM_OUTPUT_PUSH_SECTION (asm_out_file, PUBNAMES_SECTION);
sprintf (label, PUB_DIE_LABEL_FMT, next_pubname_number);
ASM_OUTPUT_DWARF_ADDR (asm_out_file, label);
- ASM_OUTPUT_DWARF_STRING (asm_out_file,
+ ASM_OUTPUT_DWARF_STRING_NEWLINE (asm_out_file,
IDENTIFIER_POINTER (DECL_NAME (decl)));
ASM_OUTPUT_POP_SECTION (asm_out_file);
}
@@ -5159,7 +5170,7 @@ dwarfout_file_scope_decl (decl, set_finalizing)
ASM_OUTPUT_PUSH_SECTION (asm_out_file, PUBNAMES_SECTION);
sprintf (label, PUB_DIE_LABEL_FMT, next_pubname_number);
ASM_OUTPUT_DWARF_ADDR (asm_out_file, label);
- ASM_OUTPUT_DWARF_STRING (asm_out_file,
+ ASM_OUTPUT_DWARF_STRING_NEWLINE (asm_out_file,
IDENTIFIER_POINTER (DECL_NAME (decl)));
ASM_OUTPUT_POP_SECTION (asm_out_file);
}
@@ -5247,10 +5258,16 @@ dwarfout_file_scope_decl (decl, set_finalizing)
output_pending_types_for_scope (NULL_TREE);
- /* The above call should have totally emptied the pending_types_list. */
-
- if (pending_types != 0)
- abort ();
+ /* The above call should have totally emptied the pending_types_list
+ if this is not a nested function or class. If this is a nested type,
+ then the remaining pending_types will be emitted when the containing type
+ is handled. */
+
+ if (! DECL_CONTEXT (decl))
+ {
+ if (pending_types != 0)
+ abort ();
+ }
ASM_OUTPUT_POP_SECTION (asm_out_file);
@@ -5386,7 +5403,7 @@ generate_new_sfname_entry ()
ASM_OUTPUT_PUSH_SECTION (asm_out_file, SFNAMES_SECTION);
sprintf (label, SFNAMES_ENTRY_LABEL_FMT, filename_table[0].number);
ASM_OUTPUT_LABEL (asm_out_file, label);
- ASM_OUTPUT_DWARF_STRING (asm_out_file,
+ ASM_OUTPUT_DWARF_STRING_NEWLINE (asm_out_file,
filename_table[0].name
? filename_table[0].name
: "");
@@ -5559,7 +5576,7 @@ generate_macinfo_entry (type_and_offset, string)
fputc ('\n', asm_out_file);
ASM_OUTPUT_PUSH_SECTION (asm_out_file, MACINFO_SECTION);
fprintf (asm_out_file, "\t%s\t%s\n", UNALIGNED_INT_ASM_OP, type_and_offset);
- ASM_OUTPUT_DWARF_STRING (asm_out_file, string);
+ ASM_OUTPUT_DWARF_STRING_NEWLINE (asm_out_file, string);
ASM_OUTPUT_POP_SECTION (asm_out_file);
}
@@ -5740,7 +5757,7 @@ dwarfout_init (asm_out_file, main_input_filename)
strcpy (dirname, pwd);
strcpy (dirname + len, "/");
- ASM_OUTPUT_DWARF_STRING (asm_out_file, dirname);
+ ASM_OUTPUT_DWARF_STRING_NEWLINE (asm_out_file, dirname);
free (dirname);
}
ASM_OUTPUT_POP_SECTION (asm_out_file);
@@ -5944,7 +5961,7 @@ dwarfout_finish ()
fputc ('\n', asm_out_file);
ASM_OUTPUT_PUSH_SECTION (asm_out_file, MACINFO_SECTION);
ASM_OUTPUT_DWARF_DATA4 (asm_out_file, 0);
- ASM_OUTPUT_DWARF_STRING (asm_out_file, "");
+ ASM_OUTPUT_DWARF_STRING_NEWLINE (asm_out_file, "");
ASM_OUTPUT_POP_SECTION (asm_out_file);
}
@@ -5953,7 +5970,7 @@ dwarfout_finish ()
fputc ('\n', asm_out_file);
ASM_OUTPUT_PUSH_SECTION (asm_out_file, PUBNAMES_SECTION);
ASM_OUTPUT_DWARF_DATA4 (asm_out_file, 0);
- ASM_OUTPUT_DWARF_STRING (asm_out_file, "");
+ ASM_OUTPUT_DWARF_STRING_NEWLINE (asm_out_file, "");
ASM_OUTPUT_POP_SECTION (asm_out_file);
/* Generate the terminating entries for the .debug_aranges section.
@@ -6003,6 +6020,12 @@ dwarfout_finish ()
ASM_OUTPUT_POP_SECTION (asm_out_file);
}
+
+ /* There should not be any pending types left at the end. We need
+ this now because it may not have been checked on the last call to
+ dwarfout_file_scope_decl. */
+ if (pending_types != 0)
+ abort ();
}
#endif /* DWARF_DEBUGGING_INFO */
diff --git a/gcc/dwarfout.h b/gcc/dwarfout.h
index b4bb9b9fc16..29c8dd39d5f 100644
--- a/gcc/dwarfout.h
+++ b/gcc/dwarfout.h
@@ -35,6 +35,8 @@ extern void dwarfout_end_epilogue PROTO ((void));
extern void dwarfout_begin_block PROTO ((unsigned));
extern void dwarfout_end_block PROTO ((unsigned));
+#ifdef RTX_CODE
extern void dwarfout_label PROTO ((rtx));
+#endif
extern void dwarfout_line PROTO ((char *, unsigned));
diff --git a/gcc/dyn-string.c b/gcc/dyn-string.c
index cfcace95584..c9edfcb076e 100644
--- a/gcc/dyn-string.c
+++ b/gcc/dyn-string.c
@@ -1,31 +1,28 @@
/* An abstract string datatype.
- Copyright (C) 1998 Free Software Foundation, Inc.
+ Copyright (C) 1998, 1999 Free Software Foundation, Inc.
Contributed by Mark Mitchell (mark@markmitchell.com).
- This file is part of GNU CC.
+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 free software; you can redistribute it and/or modify it
+under the 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.
+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, 675 Mass Ave, Cambridge, MA 02139, USA. */
+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 "config.h"
#include "system.h"
-#include "gansidecl.h"
#include "dyn-string.h"
-extern char *xmalloc ();
-extern char *xrealloc ();
-
/* Create a new dynamic string capable of holding at least SPACE
characters, including the terminating NUL. If SPACE is 0, it
will be silently increased to 1. */
@@ -65,7 +62,7 @@ dyn_string_delete (ds)
dyn_string_t
dyn_string_append (ds, s)
dyn_string_t ds;
- char *s;
+ const char *s;
{
int len = strlen (s);
dyn_string_resize (ds, ds->length + len + 1 /* '\0' */);
diff --git a/gcc/dyn-string.h b/gcc/dyn-string.h
index ed8071f8b08..9f9330886ca 100644
--- a/gcc/dyn-string.h
+++ b/gcc/dyn-string.h
@@ -1,22 +1,23 @@
/* An abstract string datatype.
- Copyright (C) 1998 Free Software Foundation, Inc.
+ Copyright (C) 1998, 1999 Free Software Foundation, Inc.
Contributed by Mark Mitchell (mark@markmitchell.com).
- This file is part of GNU CC.
+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 free software; you can redistribute it and/or modify it
+under the 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.
+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, 675 Mass Ave, Cambridge, MA 02139, USA. */
+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. */
typedef struct dyn_string
{
@@ -27,5 +28,5 @@ typedef struct dyn_string
extern dyn_string_t dyn_string_new PROTO((int));
extern void dyn_string_delete PROTO((dyn_string_t));
-extern dyn_string_t dyn_string_append PROTO((dyn_string_t, char*));
+extern dyn_string_t dyn_string_append PROTO((dyn_string_t, const char*));
extern dyn_string_t dyn_string_resize PROTO((dyn_string_t, int));
diff --git a/gcc/eh-common.h b/gcc/eh-common.h
index 143ddff10d7..c0ff7e73b1a 100644
--- a/gcc/eh-common.h
+++ b/gcc/eh-common.h
@@ -1,5 +1,22 @@
-/* Copyright (C) 1997 Free Software Foundation, Inc.
- This file is part of GNU CC. */
+/* EH stuff
+ Copyright (C) 1997, 1998 Free Software Foundation, Inc.
+
+This file is part of GNU CC.
+
+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 file contains the structures required for the language
independant exception handling model. Both the static compiler and
@@ -15,8 +32,6 @@
checking of runtime conditions. If the handler wasn't suppose to
get the exception, it performs a re-throw. */
-#include "gansidecl.h"
-
/* The handler_label field MUST be the first field in this structure. The
__throw() library routine expects uses __eh_stub() from except.c, which
@@ -31,6 +46,8 @@ struct eh_context
void **dynamic_handler_chain;
/* This is language dependent part of the eh context. */
void *info;
+ /* This is used to remember where we threw for re-throws */
+ void *table_index; /* address of exception table entry to rethrow from */
};
#ifndef EH_TABLE_LOOKUP
diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c
index d5f6b471863..80583c430d1 100644
--- a/gcc/emit-rtl.c
+++ b/gcc/emit-rtl.c
@@ -1,5 +1,5 @@
/* Emit RTL for the GNU C-Compiler expander.
- Copyright (C) 1987, 88, 92-97, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1987, 88, 92-97, 1998, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -83,19 +83,27 @@ static int no_line_numbers;
All of these except perhaps the floating-point CONST_DOUBLEs
are unique; no other rtx-object will be equal to any of these. */
+/* Avoid warnings by initializing the `fld' field. Since its a union,
+ bypass problems with KNR compilers by only doing so when __GNUC__. */
+#ifdef __GNUC__
+#define FLDI , {{0}}
+#else
+#define FLDI
+#endif
+
struct _global_rtl global_rtl =
{
- {PC, VOIDmode}, /* pc_rtx */
- {CC0, VOIDmode}, /* cc0_rtx */
- {REG}, /* stack_pointer_rtx */
- {REG}, /* frame_pointer_rtx */
- {REG}, /* hard_frame_pointer_rtx */
- {REG}, /* arg_pointer_rtx */
- {REG}, /* virtual_incoming_args_rtx */
- {REG}, /* virtual_stack_vars_rtx */
- {REG}, /* virtual_stack_dynamic_rtx */
- {REG}, /* virtual_outgoing_args_rtx */
- {REG}, /* virtual_cfa_rtx */
+ {PC, VOIDmode, 0, 0, 0, 0, 0, 0, 0, 0 FLDI }, /* pc_rtx */
+ {CC0, VOIDmode, 0, 0, 0, 0, 0, 0, 0, 0 FLDI }, /* cc0_rtx */
+ {REG, VOIDmode, 0, 0, 0, 0, 0, 0, 0, 0 FLDI }, /* stack_pointer_rtx */
+ {REG, VOIDmode, 0, 0, 0, 0, 0, 0, 0, 0 FLDI }, /* frame_pointer_rtx */
+ {REG, VOIDmode, 0, 0, 0, 0, 0, 0, 0, 0 FLDI }, /* hard_frame_pointer_rtx */
+ {REG, VOIDmode, 0, 0, 0, 0, 0, 0, 0, 0 FLDI }, /* arg_pointer_rtx */
+ {REG, VOIDmode, 0, 0, 0, 0, 0, 0, 0, 0 FLDI }, /* virtual_incoming_args_rtx */
+ {REG, VOIDmode, 0, 0, 0, 0, 0, 0, 0, 0 FLDI }, /* virtual_stack_vars_rtx */
+ {REG, VOIDmode, 0, 0, 0, 0, 0, 0, 0, 0 FLDI }, /* virtual_stack_dynamic_rtx */
+ {REG, VOIDmode, 0, 0, 0, 0, 0, 0, 0, 0 FLDI }, /* virtual_outgoing_args_rtx */
+ {REG, VOIDmode, 0, 0, 0, 0, 0, 0, 0, 0 FLDI }, /* virtual_cfa_rtx */
};
/* We record floating-point CONST_DOUBLEs in each floating-point mode for
@@ -277,7 +285,7 @@ gen_rtx_MEM (mode, addr)
rtx
gen_rtx VPROTO((enum rtx_code code, enum machine_mode mode, ...))
{
-#ifndef __STDC__
+#ifndef ANSI_PROTOTYPES
enum rtx_code code;
enum machine_mode mode;
#endif
@@ -288,7 +296,7 @@ gen_rtx VPROTO((enum rtx_code code, enum machine_mode mode, ...))
VA_START (p, mode);
-#ifndef __STDC__
+#ifndef ANSI_PROTOTYPES
code = va_arg (p, enum rtx_code);
mode = va_arg (p, enum machine_mode);
#endif
@@ -367,7 +375,7 @@ gen_rtx VPROTO((enum rtx_code code, enum machine_mode mode, ...))
rtvec
gen_rtvec VPROTO((int n, ...))
{
-#ifndef __STDC__
+#ifndef ANSI_PROTOTYPES
int n;
#endif
int i;
@@ -376,7 +384,7 @@ gen_rtvec VPROTO((int n, ...))
VA_START (p, n);
-#ifndef __STDC__
+#ifndef ANSI_PROTOTYPES
n = va_arg (p, int);
#endif
@@ -439,11 +447,9 @@ gen_reg_rtx (mode)
{
register rtx val;
- /* Don't let anything called by or after reload create new registers
- (actually, registers can't be created after flow, but this is a good
- approximation). */
-
- if (reload_in_progress || reload_completed)
+ /* Don't let anything called after initial flow analysis create new
+ registers. */
+ if (no_new_pseudos)
abort ();
if (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT
@@ -713,9 +719,6 @@ gen_lowpart_common (mode, x)
i = INTVAL (x);
r = REAL_VALUE_FROM_TARGET_SINGLE (i);
- /* Avoid changing the bit pattern of a NaN. */
- if (REAL_VALUE_ISNAN (r))
- return 0;
return CONST_DOUBLE_FROM_REAL_VALUE (r, mode);
}
#else
@@ -754,8 +757,6 @@ gen_lowpart_common (mode, x)
i[0] = low, i[1] = high;
r = REAL_VALUE_FROM_TARGET_DOUBLE (i);
- if (REAL_VALUE_ISNAN (r))
- return 0;
return CONST_DOUBLE_FROM_REAL_VALUE (r, mode);
}
#else
@@ -879,7 +880,7 @@ subreg_realpart_p (x)
if (GET_CODE (x) != SUBREG)
abort ();
- return SUBREG_WORD (x) == 0;
+ return SUBREG_WORD (x) * UNITS_PER_WORD < GET_MODE_UNIT_SIZE (GET_MODE (SUBREG_REG (x)));
}
/* Assuming that X is an rtx (e.g., MEM, REG or SUBREG) for a value,
@@ -1073,12 +1074,16 @@ operand_subword (op, i, validate_address, mode)
if (mode == VOIDmode)
abort ();
- /* If OP is narrower than a word or if we want a word outside OP, fail. */
+ /* If OP is narrower than a word, fail. */
if (mode != BLKmode
- && (GET_MODE_SIZE (mode) < UNITS_PER_WORD
- || (i + 1) * UNITS_PER_WORD > GET_MODE_SIZE (mode)))
+ && (GET_MODE_SIZE (mode) < UNITS_PER_WORD))
return 0;
+ /* If we want a word outside OP, return zero. */
+ if (mode != BLKmode
+ && (i + 1) * UNITS_PER_WORD > GET_MODE_SIZE (mode))
+ return const0_rtx;
+
/* If OP is already an integer word, return it. */
if (GET_MODE_CLASS (mode) == MODE_INT
&& GET_MODE_SIZE (mode) == UNITS_PER_WORD)
@@ -1136,8 +1141,7 @@ operand_subword (op, i, validate_address, mode)
new = gen_rtx_MEM (word_mode, addr);
- MEM_VOLATILE_P (new) = MEM_VOLATILE_P (op);
- MEM_IN_STRUCT_P (new) = MEM_IN_STRUCT_P (op);
+ MEM_COPY_ATTRIBUTES (new, op);
RTX_UNCHANGING_P (new) = RTX_UNCHANGING_P (op);
return new;
@@ -1237,6 +1241,18 @@ operand_subword (op, i, validate_address, mode)
REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
REAL_VALUE_TO_TARGET_SINGLE (rv, l);
+ /* If 32 bits is an entire word for the target, but not for the host,
+ then sign-extend on the host so that the number will look the same
+ way on the host that it would on the target. See for instance
+ simplify_unary_operation. The #if is needed to avoid compiler
+ warnings. */
+
+#if HOST_BITS_PER_LONG > 32
+ if (BITS_PER_WORD < HOST_BITS_PER_LONG && BITS_PER_WORD == 32
+ && (l & ((long) 1 << 31)))
+ l |= ((long) (-1) << 32);
+#endif
+
if (BITS_PER_WORD == 16)
{
if ((i & 0x1) == !WORDS_BIG_ENDIAN)
@@ -1436,9 +1452,8 @@ change_address (memref, mode, addr)
return memref;
new = gen_rtx_MEM (mode, addr);
- MEM_VOLATILE_P (new) = MEM_VOLATILE_P (memref);
RTX_UNCHANGING_P (new) = RTX_UNCHANGING_P (memref);
- MEM_IN_STRUCT_P (new) = MEM_IN_STRUCT_P (memref);
+ MEM_COPY_ATTRIBUTES (new, memref);
return new;
}
@@ -2142,7 +2157,8 @@ try_split (pat, trial, last)
Ignore deleted insns, which can be occur if not optimizing. */
for (tem = NEXT_INSN (before); tem != after;
tem = NEXT_INSN (tem))
- if (! INSN_DELETED_P (tem))
+ if (! INSN_DELETED_P (tem)
+ && GET_RTX_CLASS (GET_CODE (tem)) == 'i')
tem = try_split (PATTERN (tem), tem, 1);
}
/* Avoid infinite loop if the result matches the original pattern. */
@@ -2338,6 +2354,64 @@ add_insn_before (insn, before)
PREV_INSN (XVECEXP (PATTERN (before), 0, 0)) = insn;
}
+/* Remove an insn from its doubly-linked list. This function knows how
+ to handle sequences. */
+void
+remove_insn (insn)
+ rtx insn;
+{
+ rtx next = NEXT_INSN (insn);
+ rtx prev = PREV_INSN (insn);
+ if (prev)
+ {
+ NEXT_INSN (prev) = next;
+ if (GET_CODE (prev) == INSN && GET_CODE (PATTERN (prev)) == SEQUENCE)
+ {
+ rtx sequence = PATTERN (prev);
+ NEXT_INSN (XVECEXP (sequence, 0, XVECLEN (sequence, 0) - 1)) = next;
+ }
+ }
+ else if (first_insn == insn)
+ first_insn = next;
+ else
+ {
+ struct sequence_stack *stack = sequence_stack;
+ /* Scan all pending sequences too. */
+ for (; stack; stack = stack->next)
+ if (insn == stack->first)
+ {
+ stack->first = next;
+ break;
+ }
+
+ if (stack == 0)
+ abort ();
+ }
+
+ if (next)
+ {
+ PREV_INSN (next) = prev;
+ if (GET_CODE (next) == INSN && GET_CODE (PATTERN (next)) == SEQUENCE)
+ PREV_INSN (XVECEXP (PATTERN (next), 0, 0)) = prev;
+ }
+ else if (last_insn == insn)
+ last_insn = prev;
+ else
+ {
+ struct sequence_stack *stack = sequence_stack;
+ /* Scan all pending sequences too. */
+ for (; stack; stack = stack->next)
+ if (insn == stack->last)
+ {
+ stack->last = prev;
+ break;
+ }
+
+ if (stack == 0)
+ abort ();
+ }
+}
+
/* Delete all insns made since FROM.
FROM becomes the new last instruction. */
@@ -2503,7 +2577,7 @@ emit_call_insn_before (pattern, before)
}
/* Make an insn of code BARRIER
- and output it before the insn AFTER. */
+ and output it before the insn BEFORE. */
rtx
emit_barrier_before (before)
@@ -2517,6 +2591,23 @@ emit_barrier_before (before)
return insn;
}
+/* Emit the label LABEL before the insn BEFORE. */
+
+rtx
+emit_label_before (label, before)
+ rtx label, before;
+{
+ /* This can be called twice for the same label as a result of the
+ confusion that follows a syntax error! So make it harmless. */
+ if (INSN_UID (label) == 0)
+ {
+ INSN_UID (label) = cur_insn_uid++;
+ add_insn_before (label, before);
+ }
+
+ return label;
+}
+
/* Emit a note of subtype SUBTYPE before the insn BEFORE. */
rtx
@@ -2901,7 +2992,7 @@ emit_note (file, line)
return note;
}
-/* Emit a NOTE, and don't omit it even if LINE it the previous note. */
+/* Emit a NOTE, and don't omit it even if LINE is the previous note. */
rtx
emit_line_note_force (file, line)
@@ -2920,6 +3011,24 @@ force_next_line_note ()
{
last_linenum = -1;
}
+
+/* Place a note of KIND on insn INSN with DATUM as the datum. If a
+ note of this type already exists, remove it first. */
+
+void
+set_unique_reg_note (insn, kind, datum)
+ rtx insn;
+ enum reg_note kind;
+ rtx datum;
+{
+ rtx note = find_reg_note (insn, kind, NULL_RTX);
+
+ /* First remove the note if there already is one. */
+ if (note)
+ remove_note (insn, note);
+
+ REG_NOTES (insn) = gen_rtx_EXPR_LIST (kind, datum, REG_NOTES (insn));
+}
/* Return an indication of which type of insn should have X as a body.
The value is CODE_LABEL, INSN, CALL_INSN or JUMP_INSN. */
@@ -3426,6 +3535,14 @@ init_emit_once (line_numbers)
pic_offset_table_rtx = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
#endif
+#ifdef INIT_EXPANDERS
+ /* This is to initialize save_machine_status and restore_machine_status before
+ the first call to push_function_context_to. This is needed by the Chill
+ front end which calls push_function_context_to before the first cal to
+ init_function_start. */
+ INIT_EXPANDERS;
+#endif
+
ggc_add_rtx_root (&const_tiny_rtx[0][0], sizeof(const_tiny_rtx)/sizeof(rtx));
ggc_add_rtx_root (&pic_offset_table_rtx, 1);
diff --git a/gcc/except.c b/gcc/except.c
index a6a5ef4f352..a0fba7f7e81 100644
--- a/gcc/except.c
+++ b/gcc/except.c
@@ -406,6 +406,7 @@ Boston, MA 02111-1307, USA. */
#include "recog.h"
#include "output.h"
#include "toplev.h"
+#include "obstack.h"
#include "ggc.h"
/* One to use setjmp/longjmp method of generating code for exception
@@ -446,6 +447,15 @@ static rtx eh_return_handler;
rtx eh_return_stub_label;
+/* This is used for targets which can call rethrow with an offset instead
+ of an address. This is subtracted from the rethrow label we are
+ interested in. */
+
+static rtx first_rethrow_symbol = NULL_RTX;
+static rtx final_rethrow = NULL_RTX;
+static rtx last_rethrow_symbol = NULL_RTX;
+
+
/* Prototypes for local functions. */
static void mark_eh_node PROTO((struct eh_node *));
@@ -478,6 +488,29 @@ rtx expand_builtin_return_addr PROTO((enum built_in_function,
/* Various support routines to manipulate the various data structures
used by the exception handling code. */
+extern struct obstack permanent_obstack;
+
+/* Generate a SYMBOL_REF for rethrow to use */
+static rtx
+create_rethrow_ref (region_num)
+ int region_num;
+{
+ rtx def;
+ char *ptr;
+ char buf[60];
+
+ push_obstacks_nochange ();
+ end_temporary_allocation ();
+
+ ASM_GENERATE_INTERNAL_LABEL (buf, "LRTH", region_num);
+ ptr = (char *) obstack_copy0 (&permanent_obstack, buf, strlen (buf));
+ def = gen_rtx_SYMBOL_REF (Pmode, ptr);
+ SYMBOL_REF_NEED_ADJUST (def) = 1;
+
+ pop_obstacks ();
+ return def;
+}
+
/* Push a label entry onto the given STACK. */
void
@@ -535,11 +568,7 @@ rtx
gen_exception_label ()
{
rtx lab;
-
- push_obstacks_nochange ();
- end_temporary_allocation ();
lab = gen_label_rtx ();
- pop_obstacks ();
return lab;
}
@@ -552,11 +581,16 @@ push_eh_entry (stack)
struct eh_node *node = (struct eh_node *) xmalloc (sizeof (struct eh_node));
struct eh_entry *entry = (struct eh_entry *) xmalloc (sizeof (struct eh_entry));
- entry->outer_context = gen_label_rtx ();
+ rtx rlab = gen_exception_label ();
entry->finalization = NULL_TREE;
entry->label_used = 0;
- entry->exception_handler_label = gen_exception_label ();
+ entry->exception_handler_label = rlab;
entry->false_label = NULL_RTX;
+ if (! flag_new_exceptions)
+ entry->outer_context = gen_label_rtx ();
+ else
+ entry->outer_context = create_rethrow_ref (CODE_LABEL_NUMBER (rlab));
+ entry->rethrow_label = entry->outer_context;
node->entry = entry;
node->chain = stack->top;
@@ -659,6 +693,7 @@ receive_exception_label (handler_label)
struct func_eh_entry
{
int range_number; /* EH region number from EH NOTE insn's */
+ rtx rethrow_label; /* Label for rethrow */
struct handler_info *handlers;
};
@@ -671,12 +706,14 @@ static int current_func_eh_entry = 0;
#define SIZE_FUNC_EH(X) (sizeof (struct func_eh_entry) * X)
/* Add a new eh_entry for this function, and base it off of the information
- in the EH_ENTRY parameter. A NULL parameter is invalid. The number
+ in the EH_ENTRY parameter. A NULL parameter is invalid.
+ OUTER_CONTEXT is a label which is used for rethrowing. The number
returned is an number which uniquely identifies this exception range. */
-int
-new_eh_region_entry (note_eh_region)
+static int
+new_eh_region_entry (note_eh_region, rethrow)
int note_eh_region;
+ rtx rethrow;
{
if (current_func_eh_entry == num_func_eh_entries)
{
@@ -694,6 +731,11 @@ new_eh_region_entry (note_eh_region)
}
}
function_eh_regions[current_func_eh_entry].range_number = note_eh_region;
+ if (rethrow == NULL_RTX)
+ function_eh_regions[current_func_eh_entry].rethrow_label =
+ create_rethrow_ref (note_eh_region);
+ else
+ function_eh_regions[current_func_eh_entry].rethrow_label = rethrow;
function_eh_regions[current_func_eh_entry].handlers = NULL;
return current_func_eh_entry++;
@@ -719,8 +761,13 @@ add_new_handler (region, newhandler)
function_eh_regions[region].handlers = newhandler;
else
{
- for ( ; last->next != NULL; last = last->next)
- ;
+ for ( ; ; last = last->next)
+ {
+ if (last->type_info == CATCH_ALL_TYPE)
+ pedwarn ("additional handler after ...");
+ if (last->next == NULL)
+ break;
+ }
last->next = newhandler;
}
}
@@ -825,6 +872,7 @@ get_new_handler (handler, typeinfo)
struct handler_info* ptr;
ptr = (struct handler_info *) malloc (sizeof (struct handler_info));
ptr->handler_label = handler;
+ ptr->handler_number = CODE_LABEL_NUMBER (handler);
ptr->type_info = typeinfo;
ptr->next = NULL;
@@ -876,34 +924,97 @@ clear_function_eh_region ()
}
/* Make a duplicate of an exception region by copying all the handlers
- for an exception region. Return the new handler index. */
+ for an exception region. Return the new handler index. The final
+ parameter is a routine which maps old labels to new ones. */
int
-duplicate_handlers (old_note_eh_region, new_note_eh_region)
+duplicate_eh_handlers (old_note_eh_region, new_note_eh_region, map)
int old_note_eh_region, new_note_eh_region;
+ rtx (*map) PARAMS ((rtx));
{
struct handler_info *ptr, *new_ptr;
int new_region, region;
region = find_func_region (old_note_eh_region);
if (region == -1)
- error ("Cannot duplicate non-existant exception region.");
+ fatal ("Cannot duplicate non-existant exception region.");
+
+ /* duplicate_eh_handlers may have been called during a symbol remap. */
+ new_region = find_func_region (new_note_eh_region);
+ if (new_region != -1)
+ return (new_region);
- if (find_func_region (new_note_eh_region) != -1)
- error ("Cannot duplicate EH region because new note region already exists");
+ new_region = new_eh_region_entry (new_note_eh_region, NULL_RTX);
- new_region = new_eh_region_entry (new_note_eh_region);
ptr = function_eh_regions[region].handlers;
for ( ; ptr; ptr = ptr->next)
{
- new_ptr = get_new_handler (ptr->handler_label, ptr->type_info);
+ new_ptr = get_new_handler (map (ptr->handler_label), ptr->type_info);
add_new_handler (new_region, new_ptr);
}
return new_region;
}
+
+/* Given a rethrow symbol, find the EH region number this is for. */
+int
+eh_region_from_symbol (sym)
+ rtx sym;
+{
+ int x;
+ if (sym == last_rethrow_symbol)
+ return 1;
+ for (x = 0; x < current_func_eh_entry; x++)
+ if (function_eh_regions[x].rethrow_label == sym)
+ return function_eh_regions[x].range_number;
+ return -1;
+}
+
+
+/* When inlining/unrolling, we have to map the symbols passed to
+ __rethrow as well. This performs the remap. If a symbol isn't foiund,
+ the original one is returned. This is not an efficient routine,
+ so don't call it on everything!! */
+rtx
+rethrow_symbol_map (sym, map)
+ rtx sym;
+ rtx (*map) PARAMS ((rtx));
+{
+ int x, y;
+ for (x = 0; x < current_func_eh_entry; x++)
+ if (function_eh_regions[x].rethrow_label == sym)
+ {
+ /* We've found the original region, now lets determine which region
+ this now maps to. */
+ rtx l1 = function_eh_regions[x].handlers->handler_label;
+ rtx l2 = map (l1);
+ y = CODE_LABEL_NUMBER (l2); /* This is the new region number */
+ x = find_func_region (y); /* Get the new permanent region */
+ if (x == -1) /* Hmm, Doesn't exist yet */
+ {
+ x = duplicate_eh_handlers (CODE_LABEL_NUMBER (l1), y, map);
+ /* Since we're mapping it, it must be used. */
+ SYMBOL_REF_USED (function_eh_regions[x].rethrow_label) = 1;
+ }
+ return function_eh_regions[x].rethrow_label;
+ }
+ return sym;
+}
+
+int
+rethrow_used (region)
+ int region;
+{
+ if (flag_new_exceptions)
+ {
+ rtx lab = function_eh_regions[find_func_region (region)].rethrow_label;
+ return (SYMBOL_REF_USED (lab));
+ }
+ return 0;
+}
+
/* Routine to see if exception handling is turned on.
DO_WARN is non-zero if we want to inform the user that exception
@@ -1357,6 +1468,7 @@ expand_eh_region_end (handler)
{
struct eh_entry *entry;
rtx note;
+ int ret, r;
if (! doing_eh (0))
return;
@@ -1364,9 +1476,9 @@ expand_eh_region_end (handler)
entry = pop_eh_entry (&ehstack);
note = emit_note (NULL_PTR, NOTE_INSN_EH_REGION_END);
- NOTE_BLOCK_NUMBER (note)
+ ret = NOTE_BLOCK_NUMBER (note)
= CODE_LABEL_NUMBER (entry->exception_handler_label);
- if (exceptions_via_longjmp == 0
+ if (exceptions_via_longjmp == 0 && ! flag_new_exceptions
/* We share outer_context between regions; only emit it once. */
&& INSN_UID (entry->outer_context) == 0)
{
@@ -1386,7 +1498,7 @@ expand_eh_region_end (handler)
entry->finalization = handler;
/* create region entry in final exception table */
- new_eh_region_entry (NOTE_BLOCK_NUMBER (note));
+ r = new_eh_region_entry (NOTE_BLOCK_NUMBER (note), entry->rethrow_label);
enqueue_eh_entry (&ehqueue, entry);
@@ -1428,6 +1540,7 @@ expand_fixup_region_end (cleanup)
tree cleanup;
{
struct eh_node *node;
+ int dont_issue;
if (! doing_eh (0) || exceptions_via_longjmp)
return;
@@ -1440,10 +1553,31 @@ expand_fixup_region_end (cleanup)
if (node == 0)
abort ();
+ /* If the outer context label has not been issued yet, we don't want
+ to issue it as a part of this region, unless this is the
+ correct region for the outer context. If we did, then the label for
+ the outer context will be WITHIN the begin/end labels,
+ and we could get an infinte loop when it tried to rethrow, or just
+ generally incorrect execution following a throw. */
+
+ dont_issue = ((INSN_UID (node->entry->outer_context) == 0)
+ && (ehstack.top->entry != node->entry));
+
ehstack.top->entry->outer_context = node->entry->outer_context;
+ /* Since we are rethrowing to the OUTER region, we know we don't need
+ a jump around sequence for this region, so we'll pretend the outer
+ context label has been issued by setting INSN_UID to 1, then clearing
+ it again afterwards. */
+
+ if (dont_issue)
+ INSN_UID (node->entry->outer_context) = 1;
+
/* Just rethrow. size_zero_node is just a NOP. */
expand_eh_region_end (size_zero_node);
+
+ if (dont_issue)
+ INSN_UID (node->entry->outer_context) = 0;
}
/* If we are using the setjmp/longjmp EH codegen method, we emit a
@@ -1585,9 +1719,9 @@ start_catch_handler (rtime)
0, SImode, 1, rtime_address, Pmode);
/* Did the function return true? */
- emit_cmp_insn (call_rtx, const0_rtx, EQ, NULL_RTX,
- GET_MODE (call_rtx), 0 ,0);
- emit_jump_insn (gen_beq (catchstack.top->entry->false_label));
+ emit_cmp_and_jump_insns (call_rtx, const0_rtx, EQ, NULL_RTX,
+ GET_MODE (call_rtx), 0, 0,
+ catchstack.top->entry->false_label);
}
}
@@ -1598,8 +1732,14 @@ start_catch_handler (rtime)
void
end_catch_handler ()
{
- if (! doing_eh (1) || (flag_new_exceptions && ! exceptions_via_longjmp))
+ if (! doing_eh (1))
return;
+
+ if (flag_new_exceptions && ! exceptions_via_longjmp)
+ {
+ emit_barrier ();
+ return;
+ }
/* A NULL label implies the catch clause was a catch all or cleanup */
if (catchstack.top->entry->false_label == NULL_RTX)
@@ -1711,7 +1851,7 @@ expand_start_all_catch ()
void
expand_end_all_catch ()
{
- rtx new_catch_clause, outer_context = NULL_RTX;
+ rtx new_catch_clause;
struct eh_entry *entry;
if (! doing_eh (1))
@@ -1723,11 +1863,17 @@ expand_end_all_catch ()
if (! exceptions_via_longjmp)
{
- outer_context = ehstack.top->entry->outer_context;
+ rtx outer_context = ehstack.top->entry->outer_context;
/* Finish the rethrow region. size_zero_node is just a NOP. */
expand_eh_region_end (size_zero_node);
+ /* New exceptions handling models will never have a fall through
+ of a catch clause */
+ if (!flag_new_exceptions)
+ expand_rethrow (outer_context);
}
+ else
+ expand_rethrow (NULL_RTX);
/* Code to throw out to outer context, if we fall off end of catch
handlers. This is rethrow (Lresume, same id, same obj) in the
@@ -1738,7 +1884,6 @@ expand_end_all_catch ()
do a "throw" (using the address of Lresume as the point being
thrown from) so that the outer EH region can then try to process
the exception. */
- expand_rethrow (outer_context);
/* Now we have the complete catch sequence. */
new_catch_clause = get_insns ();
@@ -1767,7 +1912,28 @@ expand_rethrow (label)
if (exceptions_via_longjmp)
emit_throw ();
else
- emit_jump (label);
+ if (flag_new_exceptions)
+ {
+ rtx insn, val;
+ if (label == NULL_RTX)
+ label = last_rethrow_symbol;
+ emit_library_call (rethrow_libfunc, 0, VOIDmode, 1, label, Pmode);
+ SYMBOL_REF_USED (label) = 1;
+
+ /* Search backwards for the actual call insn. */
+ insn = get_last_insn ();
+ while (GET_CODE (insn) != CALL_INSN)
+ insn = PREV_INSN (insn);
+ delete_insns_since (insn);
+
+ /* Mark the label/symbol on the call. */
+ val = GEN_INT (eh_region_from_symbol (label));
+ REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EH_RETHROW, val,
+ REG_NOTES (insn));
+ emit_barrier ();
+ }
+ else
+ emit_jump (label);
}
/* End all the pending exception regions on protect_list. The handlers
@@ -1901,12 +2067,29 @@ output_exception_table_entry (file, n)
{
char buf[256];
rtx sym;
- struct handler_info *handler;
+ struct handler_info *handler = get_first_handler (n);
+ int index = find_func_region (n);
+ rtx rethrow;
+
+ /* form and emit the rethrow label, if needed */
+ rethrow = function_eh_regions[index].rethrow_label;
+ if (rethrow != NULL_RTX && !flag_new_exceptions)
+ rethrow = NULL_RTX;
+ if (rethrow != NULL_RTX && handler == NULL)
+ if (! SYMBOL_REF_USED (rethrow))
+ rethrow = NULL_RTX;
- handler = get_first_handler (n);
- for ( ; handler != NULL; handler = handler->next)
+ for ( ; handler != NULL || rethrow != NULL_RTX; handler = handler->next)
{
+ /* rethrow label should indicate the LAST entry for a region */
+ if (rethrow != NULL_RTX && (handler == NULL || handler->next == NULL))
+ {
+ ASM_GENERATE_INTERNAL_LABEL (buf, "LRTH", n);
+ assemble_label(buf);
+ rethrow = NULL_RTX;
+ }
+
ASM_GENERATE_INTERNAL_LABEL (buf, "LEHB", n);
sym = gen_rtx_SYMBOL_REF (Pmode, buf);
assemble_integer (sym, POINTER_SIZE / BITS_PER_UNIT, 1);
@@ -1915,12 +2098,18 @@ output_exception_table_entry (file, n)
sym = gen_rtx_SYMBOL_REF (Pmode, buf);
assemble_integer (sym, POINTER_SIZE / BITS_PER_UNIT, 1);
- assemble_integer (handler->handler_label,
- POINTER_SIZE / BITS_PER_UNIT, 1);
+ if (handler == NULL)
+ assemble_integer (GEN_INT (0), POINTER_SIZE / BITS_PER_UNIT, 1);
+ else
+ {
+ ASM_GENERATE_INTERNAL_LABEL (buf, "L", handler->handler_number);
+ sym = gen_rtx_SYMBOL_REF (Pmode, buf);
+ assemble_integer (sym, POINTER_SIZE / BITS_PER_UNIT, 1);
+ }
if (flag_new_exceptions)
{
- if (handler->type_info == NULL)
+ if (handler == NULL || handler->type_info == NULL)
assemble_integer (const0_rtx, POINTER_SIZE / BITS_PER_UNIT, 1);
else
if (handler->type_info == CATCH_ALL_TYPE)
@@ -1932,7 +2121,7 @@ output_exception_table_entry (file, n)
}
putc ('\n', file); /* blank line */
/* We only output the first label under the old scheme */
- if (! flag_new_exceptions)
+ if (! flag_new_exceptions || handler == NULL)
break;
}
}
@@ -1953,7 +2142,7 @@ set_exception_lang_code (code)
/* This routine will set the language version code for exceptions. */
void
set_exception_version_code (code)
- short code;
+ int code;
{
version_code = code;
}
@@ -1963,6 +2152,7 @@ void
output_exception_table ()
{
int i;
+ char buf[256];
extern FILE *asm_out_file;
if (! doing_eh (0) || ! eh_table)
@@ -1987,6 +2177,10 @@ output_exception_table ()
;
if (i != 0)
assemble_integer (const0_rtx, i , 1);
+
+ /* Generate the label for offset calculations on rethrows */
+ ASM_GENERATE_INTERNAL_LABEL (buf, "LRTH", 0);
+ assemble_label(buf);
}
for (i = 0; i < eh_table_size; ++i)
@@ -1996,6 +2190,9 @@ output_exception_table ()
clear_function_eh_region ();
/* Ending marker for table. */
+ /* Generate the label for end of table. */
+ ASM_GENERATE_INTERNAL_LABEL (buf, "LRTH", CODE_LABEL_NUMBER (final_rethrow));
+ assemble_label(buf);
assemble_integer (constm1_rtx, POINTER_SIZE / BITS_PER_UNIT, 1);
/* for binary compatability, the old __throw checked the second
@@ -2046,6 +2243,14 @@ emit_eh_context ()
end_sequence ();
emit_insns_before (insns, insn);
+
+ /* At -O0, we must make the context register stay alive so
+ that the stupid.c register allocator doesn't get confused. */
+ if (obey_regdecls != 0)
+ {
+ insns = gen_rtx_USE (GET_MODE (XEXP (reg,0)), XEXP (reg,0));
+ emit_insn_before (insns, get_last_insn ());
+ }
}
}
}
@@ -2220,6 +2425,9 @@ mark_eh_state (arg)
void
init_eh ()
{
+ first_rethrow_symbol = create_rethrow_ref (0);
+ final_rethrow = gen_exception_label ();
+ last_rethrow_symbol = create_rethrow_ref (CODE_LABEL_NUMBER (final_rethrow));
}
/* Initialize the per-function EH information. */
@@ -2296,6 +2504,11 @@ scan_region (insn, n, delete_outer)
/* Assume we can delete the region. */
int delete = 1;
+ int r = find_func_region (n);
+ /* Can't delete something which is rethrown to. */
+ if (SYMBOL_REF_USED((function_eh_regions[r].rethrow_label)))
+ delete = 0;
+
if (insn == NULL_RTX
|| GET_CODE (insn) != NOTE
|| NOTE_LINE_NUMBER (insn) != NOTE_INSN_EH_REGION_BEG
@@ -2590,7 +2803,9 @@ expand_eh_return ()
#ifdef RETURN_ADDR_OFFSET
tmp = plus_constant (tmp, -RETURN_ADDR_OFFSET);
#endif
- emit_move_insn (ra, tmp);
+ tmp = force_operand (tmp, ra);
+ if (tmp != ra)
+ emit_move_insn (ra, tmp);
/* Indicate that the registers are in fact used. */
emit_insn (gen_rtx_USE (VOIDmode, reg1));
diff --git a/gcc/except.h b/gcc/except.h
index 607544706e3..0ebdd9f3275 100644
--- a/gcc/except.h
+++ b/gcc/except.h
@@ -1,5 +1,5 @@
/* Exception Handling interface routines.
- Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+ Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
Contributed by Mike Stump <mrs@cygnus.com>.
This file is part of GNU CC.
@@ -65,6 +65,7 @@ struct eh_entry {
tree finalization;
int label_used;
rtx false_label;
+ rtx rethrow_label;
};
/* A list of EH_ENTRYs. ENTRY is the entry; CHAIN points to the next
@@ -228,19 +229,13 @@ void set_exception_version_code PROTO((int));
typedef struct handler_info
{
- rtx handler_label;
+ rtx handler_label;
+ int handler_number;
void *type_info;
struct handler_info *next;
} handler_info;
-/* Add a new eh_entry for this function, The parameter specifies what
- exception region number NOTE insns use to delimit this range.
- The integer returned is uniquely identifies this exception range
- within an internal table. */
-
-int new_eh_region_entry PROTO((int));
-
/* Add new handler information to an exception range. The first parameter
specifies the range number (returned from new_eh_entry()). The second
parameter specifies the handler. By default the handler is inserted at
@@ -265,8 +260,19 @@ struct handler_info *get_new_handler PROTO((rtx, void *));
/* Make a duplicate of an exception region by copying all the handlers
for an exception region. Return the new handler index. */
-int duplicate_handlers PROTO((int, int));
+int duplicate_eh_handlers PROTO((int, int, rtx (*)(rtx)));
+
+/* map symbol refs for rethrow */
+
+rtx rethrow_symbol_map PROTO((rtx, rtx (*)(rtx)));
+
+/* Is the rethrow label for a region used? */
+
+int rethrow_used PROTO((int));
+
+/* Return the region number a this is the rethrow label for. */
+int eh_region_from_symbol PROTO((rtx));
/* Get a pointer to the first handler in an exception region's list. */
diff --git a/gcc/explow.c b/gcc/explow.c
index a15afade550..41d5269a88c 100644
--- a/gcc/explow.c
+++ b/gcc/explow.c
@@ -1,5 +1,5 @@
/* Subroutines for manipulating rtx's in semantically interesting ways.
- Copyright (C) 1987, 91, 94-97, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1987, 91, 94-97, 1998, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -32,6 +32,10 @@ Boston, MA 02111-1307, USA. */
#include "insn-flags.h"
#include "insn-codes.h"
+#if !defined PREFERRED_STACK_BOUNDARY && defined STACK_BOUNDARY
+#define PREFERRED_STACK_BOUNDARY STACK_BOUNDARY
+#endif
+
static rtx break_out_memory_refs PROTO((rtx));
static void emit_stack_probe PROTO((rtx));
/* Return an rtx for the sum of X and the integer C.
@@ -113,19 +117,32 @@ plus_constant_wide (x, c)
integer. For a constant term that is not an explicit integer,
we cannot really combine, but group them together anyway.
- Use a recursive call in case the remaining operand is something
- that we handle specially, such as a SYMBOL_REF. */
+ Restart or use a recursive call in case the remaining operand is
+ something that we handle specially, such as a SYMBOL_REF.
+
+ We may not immediately return from the recursive call here, lest
+ all_constant gets lost. */
if (GET_CODE (XEXP (x, 1)) == CONST_INT)
- return plus_constant (XEXP (x, 0), c + INTVAL (XEXP (x, 1)));
+ {
+ c += INTVAL (XEXP (x, 1));
+ x = XEXP (x, 0);
+ goto restart;
+ }
else if (CONSTANT_P (XEXP (x, 0)))
- return gen_rtx_PLUS (mode,
- plus_constant (XEXP (x, 0), c),
- XEXP (x, 1));
+ {
+ x = gen_rtx_PLUS (mode,
+ plus_constant (XEXP (x, 0), c),
+ XEXP (x, 1));
+ c = 0;
+ }
else if (CONSTANT_P (XEXP (x, 1)))
- return gen_rtx_PLUS (mode,
- XEXP (x, 0),
- plus_constant (XEXP (x, 1), c));
+ {
+ x = gen_rtx_PLUS (mode,
+ XEXP (x, 0),
+ plus_constant (XEXP (x, 1), c));
+ c = 0;
+ }
break;
default:
@@ -590,9 +607,10 @@ stabilize (x)
/* Mark returned memref with in_struct if it's in an array or
structure. Copy const and volatile from original memref. */
- MEM_IN_STRUCT_P (mem) = MEM_IN_STRUCT_P (x) || GET_CODE (addr) == PLUS;
RTX_UNCHANGING_P (mem) = RTX_UNCHANGING_P (x);
- MEM_VOLATILE_P (mem) = MEM_VOLATILE_P (x);
+ MEM_COPY_ATTRIBUTES (mem, x);
+ if (GET_CODE (addr) == PLUS)
+ MEM_SET_IN_STRUCT_P (mem, 1);
/* Since the new MEM is just like the old X, it can alias only
the things that X could. */
@@ -737,7 +755,7 @@ promote_mode (type, mode, punsignedp, for_call)
tree type;
enum machine_mode mode;
int *punsignedp;
- int for_call;
+ int for_call ATTRIBUTE_UNUSED;
{
enum tree_code code = TREE_CODE (type);
int unsignedp = *punsignedp;
@@ -831,8 +849,8 @@ rtx
round_push (size)
rtx size;
{
-#ifdef STACK_BOUNDARY
- int align = STACK_BOUNDARY / BITS_PER_UNIT;
+#ifdef PREFERRED_STACK_BOUNDARY
+ int align = PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT;
if (align == 1)
return size;
if (GET_CODE (size) == CONST_INT)
@@ -852,7 +870,7 @@ round_push (size)
NULL_RTX, 1);
size = expand_mult (Pmode, size, GEN_INT (align), NULL_RTX, 1);
}
-#endif /* STACK_BOUNDARY */
+#endif /* PREFERRED_STACK_BOUNDARY */
return size;
}
@@ -1125,10 +1143,10 @@ allocate_dynamic_stack_space (size, target, known_align)
If we have to align, we must leave space in SIZE for the hole
that might result from the alignment operation. */
-#if defined (STACK_DYNAMIC_OFFSET) || defined (STACK_POINTER_OFFSET) || ! defined (STACK_BOUNDARY)
+#if defined (STACK_DYNAMIC_OFFSET) || defined (STACK_POINTER_OFFSET) || ! defined (PREFERRED_STACK_BOUNDARY)
#define MUST_ALIGN 1
#else
-#define MUST_ALIGN (STACK_BOUNDARY < BIGGEST_ALIGNMENT)
+#define MUST_ALIGN (PREFERRED_STACK_BOUNDARY < BIGGEST_ALIGNMENT)
#endif
if (MUST_ALIGN)
@@ -1155,12 +1173,12 @@ allocate_dynamic_stack_space (size, target, known_align)
if (!current_function_calls_setjmp)
{
- int align = STACK_BOUNDARY / BITS_PER_UNIT;
+ int align = PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT;
/* See optimize_save_area_alloca to understand what is being
set up here. */
-#if !defined(STACK_BOUNDARY) || !defined(MUST_ALIGN) || (STACK_BOUNDARY != BIGGEST_ALIGNMENT)
+#if !defined(PREFERRED_STACK_BOUNDARY) || !defined(MUST_ALIGN) || (PREFERRED_STACK_BOUNDARY != BIGGEST_ALIGNMENT)
/* If anyone creates a target with these characteristics, let them
know that our optimization cannot work correctly in such a case. */
abort();
@@ -1187,7 +1205,7 @@ allocate_dynamic_stack_space (size, target, known_align)
/* Our optimization works based upon being able to perform a simple
transformation of this RTL into a (set REG REG) so make sure things
did in fact end up in a REG. */
- if (!arith_operand (setjmpless_size, Pmode))
+ if (!register_operand (setjmpless_size, Pmode))
setjmpless_size = force_reg (Pmode, setjmpless_size);
}
@@ -1210,11 +1228,11 @@ allocate_dynamic_stack_space (size, target, known_align)
way of knowing which systems have this problem. So we avoid even
momentarily mis-aligning the stack. */
-#ifdef STACK_BOUNDARY
+#ifdef PREFERRED_STACK_BOUNDARY
/* If we added a variable amount to SIZE,
we can no longer assume it is aligned. */
#if !defined (SETJMP_VIA_SAVE_AREA)
- if (MUST_ALIGN || known_align % STACK_BOUNDARY != 0)
+ if (MUST_ALIGN || known_align % PREFERRED_STACK_BOUNDARY != 0)
#endif
size = round_push (size);
#endif
@@ -1300,7 +1318,7 @@ allocate_dynamic_stack_space (size, target, known_align)
#endif
/* Record the new stack level for nonlocal gotos. */
- if (nonlocal_goto_handler_slot != 0)
+ if (nonlocal_goto_handler_slots != 0)
emit_stack_save (SAVE_NONLOCAL, &nonlocal_goto_stack_level, NULL_RTX);
return target;
@@ -1428,8 +1446,8 @@ probe_stack_range (first, size)
abort ();
emit_label (test_lab);
- emit_cmp_insn (test_addr, last_addr, CMP_OPCODE, NULL_RTX, Pmode, 1, 0);
- emit_jump_insn ((*bcc_gen_fctn[(int) CMP_OPCODE]) (loop_lab));
+ emit_cmp_and_jump_insns (test_addr, last_addr, CMP_OPCODE,
+ NULL_RTX, Pmode, 1, 0, loop_lab);
emit_jump (end_lab);
emit_note (NULL_PTR, NOTE_INSN_LOOP_END);
emit_label (end_lab);
@@ -1451,7 +1469,7 @@ probe_stack_range (first, size)
rtx
hard_function_value (valtype, func)
tree valtype;
- tree func;
+ tree func ATTRIBUTE_UNUSED;
{
rtx val = FUNCTION_VALUE (valtype, func);
if (GET_CODE (val) == REG
diff --git a/gcc/expmed.c b/gcc/expmed.c
index f9bd9ad20be..37116e30e05 100644
--- a/gcc/expmed.c
+++ b/gcc/expmed.c
@@ -261,6 +261,21 @@ store_bit_field (str_rtx, bitsize, bitnum, fieldmode, value, align, total_size)
op0 = SUBREG_REG (op0);
}
+ /* Make sure we are playing with integral modes. Pun with subregs
+ if we aren't. */
+ {
+ enum machine_mode imode = int_mode_for_mode (GET_MODE (op0));
+ if (imode != GET_MODE (op0))
+ {
+ if (GET_CODE (op0) == MEM)
+ op0 = change_address (op0, imode, NULL_RTX);
+ else if (imode != BLKmode)
+ op0 = gen_lowpart (imode, op0);
+ else
+ abort ();
+ }
+ }
+
/* If OP0 is a register, BITPOS must count within a word.
But as we have it, it counts within whatever size OP0 now has.
On a bigendian machine, these are not the same, so convert. */
@@ -287,6 +302,18 @@ store_bit_field (str_rtx, bitsize, bitnum, fieldmode, value, align, total_size)
can be done with just SUBREG. */
if (GET_MODE (op0) != fieldmode)
{
+ if (GET_CODE (op0) == SUBREG)
+ {
+ if (GET_MODE (SUBREG_REG (op0)) == fieldmode
+ || GET_MODE_CLASS (fieldmode) == MODE_INT
+ || GET_MODE_CLASS (fieldmode) == MODE_PARTIAL_INT)
+ op0 = SUBREG_REG (op0);
+ else
+ /* Else we've got some float mode source being extracted into
+ a different float mode destination -- this combination of
+ subregs results in Severe Tire Damage. */
+ abort ();
+ }
if (GET_CODE (op0) == REG)
op0 = gen_rtx_SUBREG (fieldmode, op0, offset);
else
@@ -320,8 +347,22 @@ store_bit_field (str_rtx, bitsize, bitnum, fieldmode, value, align, total_size)
else
{
int icode = movstrict_optab->handlers[(int) fieldmode].insn_code;
- if(! (*insn_operand_predicate[icode][1]) (value, fieldmode))
+ if (! (*insn_operand_predicate[icode][1]) (value, fieldmode))
value = copy_to_mode_reg (fieldmode, value);
+
+ if (GET_CODE (op0) == SUBREG)
+ {
+ if (GET_MODE (SUBREG_REG (op0)) == fieldmode
+ || GET_MODE_CLASS (fieldmode) == MODE_INT
+ || GET_MODE_CLASS (fieldmode) == MODE_PARTIAL_INT)
+ op0 = SUBREG_REG (op0);
+ else
+ /* Else we've got some float mode source being extracted into
+ a different float mode destination -- this combination of
+ subregs results in Severe Tire Damage. */
+ abort ();
+ }
+
emit_insn (GEN_FCN (icode)
(gen_rtx_SUBREG (fieldmode, op0, offset), value));
}
@@ -376,12 +417,27 @@ store_bit_field (str_rtx, bitsize, bitnum, fieldmode, value, align, total_size)
/* OFFSET is the number of words or bytes (UNIT says which)
from STR_RTX to the first word or byte containing part of the field. */
- if (GET_CODE (op0) == REG)
+ if (GET_CODE (op0) != MEM)
{
if (offset != 0
|| GET_MODE_SIZE (GET_MODE (op0)) > UNITS_PER_WORD)
- op0 = gen_rtx_SUBREG (TYPE_MODE (type_for_size (BITS_PER_WORD, 0)),
- op0, offset);
+ {
+ if (GET_CODE (op0) != REG)
+ {
+ /* Since this is a destination (lvalue), we can't copy it to a
+ pseudo. We can trivially remove a SUBREG that does not
+ change the size of the operand. Such a SUBREG may have been
+ added above. Otherwise, abort. */
+ if (GET_CODE (op0) == SUBREG
+ && (GET_MODE_SIZE (GET_MODE (op0))
+ == GET_MODE_SIZE (GET_MODE (SUBREG_REG (op0)))))
+ op0 = SUBREG_REG (op0);
+ else
+ abort ();
+ }
+ op0 = gen_rtx_SUBREG (mode_for_size (BITS_PER_WORD, MODE_INT, 0),
+ op0, offset);
+ }
offset = 0;
}
else
@@ -512,7 +568,7 @@ store_bit_field (str_rtx, bitsize, bitnum, fieldmode, value, align, total_size)
{
/* Avoid making subreg of a subreg, or of a mem. */
if (GET_CODE (value1) != REG)
- value1 = copy_to_reg (value1);
+ value1 = copy_to_reg (value1);
value1 = gen_rtx_SUBREG (maxmode, value1, 0);
}
else
@@ -955,6 +1011,21 @@ extract_bit_field (str_rtx, bitsize, bitnum, unsignedp,
op0 = SUBREG_REG (op0);
}
+ /* Make sure we are playing with integral modes. Pun with subregs
+ if we aren't. */
+ {
+ enum machine_mode imode = int_mode_for_mode (GET_MODE (op0));
+ if (imode != GET_MODE (op0))
+ {
+ if (GET_CODE (op0) == MEM)
+ op0 = change_address (op0, imode, NULL_RTX);
+ else if (imode != BLKmode)
+ op0 = gen_lowpart (imode, op0);
+ else
+ abort ();
+ }
+ }
+
/* ??? We currently assume TARGET is at least as big as BITSIZE.
If that's wrong, the solution is to test for it and set TARGET to 0
if needed. */
@@ -973,7 +1044,7 @@ extract_bit_field (str_rtx, bitsize, bitnum, unsignedp,
So too extracting a subword value in
the least significant part of the register. */
- if (((GET_CODE (op0) == REG
+ if (((GET_CODE (op0) != MEM
&& TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (mode),
GET_MODE_BITSIZE (GET_MODE (op0))))
|| (GET_CODE (op0) == MEM
@@ -996,6 +1067,18 @@ extract_bit_field (str_rtx, bitsize, bitnum, unsignedp,
if (mode1 != GET_MODE (op0))
{
+ if (GET_CODE (op0) == SUBREG)
+ {
+ if (GET_MODE (SUBREG_REG (op0)) == mode1
+ || GET_MODE_CLASS (mode1) == MODE_INT
+ || GET_MODE_CLASS (mode1) == MODE_PARTIAL_INT)
+ op0 = SUBREG_REG (op0);
+ else
+ /* Else we've got some float mode source being extracted into
+ a different float mode destination -- this combination of
+ subregs results in Severe Tire Damage. */
+ abort ();
+ }
if (GET_CODE (op0) == REG)
op0 = gen_rtx_SUBREG (mode1, op0, offset);
else
@@ -1088,12 +1171,16 @@ extract_bit_field (str_rtx, bitsize, bitnum, unsignedp,
/* OFFSET is the number of words or bytes (UNIT says which)
from STR_RTX to the first word or byte containing part of the field. */
- if (GET_CODE (op0) == REG)
+ if (GET_CODE (op0) != MEM)
{
if (offset != 0
|| GET_MODE_SIZE (GET_MODE (op0)) > UNITS_PER_WORD)
- op0 = gen_rtx_SUBREG (TYPE_MODE (type_for_size (BITS_PER_WORD, 0)),
- op0, offset);
+ {
+ if (GET_CODE (op0) != REG)
+ op0 = copy_to_reg (op0);
+ op0 = gen_rtx_SUBREG (mode_for_size (BITS_PER_WORD, MODE_INT, 0),
+ op0, offset);
+ }
offset = 0;
}
else
@@ -1800,7 +1887,8 @@ expand_shift (code, mode, shifted, amount, target, unsignedp)
if (SHIFT_COUNT_TRUNCATED)
{
if (GET_CODE (op1) == CONST_INT
- && (unsigned HOST_WIDE_INT) INTVAL (op1) >= GET_MODE_BITSIZE (mode))
+ && ((unsigned HOST_WIDE_INT) INTVAL (op1) >=
+ (unsigned HOST_WIDE_INT) GET_MODE_BITSIZE (mode)))
op1 = GEN_INT ((unsigned HOST_WIDE_INT) INTVAL (op1)
% GET_MODE_BITSIZE (mode));
else if (GET_CODE (op1) == SUBREG
@@ -1975,7 +2063,7 @@ synth_mult (alg_out, t, cost_limit)
{
int m;
struct algorithm *alg_in, *best_alg;
- unsigned int cost;
+ int cost;
unsigned HOST_WIDE_INT q;
/* Indicate that no algorithm is yet found. If no algorithm
@@ -2385,10 +2473,10 @@ expand_mult (mode, op0, op1, target, unsignedp)
multiplication sequences. */
insn = get_last_insn ();
- REG_NOTES (insn)
- = gen_rtx_EXPR_LIST (REG_EQUAL,
- gen_rtx_MULT (mode, op0, GEN_INT (val_so_far)),
- REG_NOTES (insn));
+ set_unique_reg_note (insn,
+ REG_EQUAL,
+ gen_rtx_MULT (mode, op0,
+ GEN_INT (val_so_far)));
}
if (variant == negate_variant)
@@ -2764,6 +2852,27 @@ expand_mult_highpart (mode, op0, cnst1, target, unsignedp, max_cost)
This could optimize to a bfexts instruction.
But C doesn't use these operations, so their optimizations are
left for later. */
+/* ??? For modulo, we don't actually need the highpart of the first product,
+ the low part will do nicely. And for small divisors, the second multiply
+ can also be a low-part only multiply or even be completely left out.
+ E.g. to calculate the remainder of a division by 3 with a 32 bit
+ multiply, multiply with 0x55555556 and extract the upper two bits;
+ the result is exact for inputs up to 0x1fffffff.
+ The input range can be reduced by using cross-sum rules.
+ For odd divisors >= 3, the following table gives right shift counts
+ so that if an number is shifted by an integer multiple of the given
+ amount, the remainder stays the same:
+ 2, 4, 3, 6, 10, 12, 4, 8, 18, 6, 11, 20, 18, 0, 5, 10, 12, 0, 12, 20,
+ 14, 12, 23, 21, 8, 0, 20, 18, 0, 0, 6, 12, 0, 22, 0, 18, 20, 30, 0, 0,
+ 0, 8, 0, 11, 12, 10, 36, 0, 30, 0, 0, 12, 0, 0, 0, 0, 44, 12, 24, 0,
+ 20, 0, 7, 14, 0, 18, 36, 0, 0, 46, 60, 0, 42, 0, 15, 24, 20, 0, 0, 33,
+ 0, 20, 0, 0, 18, 0, 60, 0, 0, 0, 0, 0, 40, 18, 0, 0, 12
+
+ Cross-sum rules for even numbers can be derived by leaving as many bits
+ to the right alone as the divisor has zeros to the right.
+ E.g. if x is an unsigned 32 bit number:
+ (x mod 12) == (((x & 1023) + ((x >> 8) & ~3)) * 0x15555558 >> 2 * 3) >> 28
+ */
#define EXACT_POWER_OF_2_OR_ZERO_P(x) (((x) & ((x) - 1)) == 0)
@@ -3061,10 +3170,9 @@ expand_divmod (rem_flag, code, mode, op0, op1, target, unsignedp)
if (insn != last
&& (set = single_set (insn)) != 0
&& SET_DEST (set) == quotient)
- REG_NOTES (insn)
- = gen_rtx_EXPR_LIST (REG_EQUAL,
- gen_rtx_UDIV (compute_mode, op0, op1),
- REG_NOTES (insn));
+ set_unique_reg_note (insn,
+ REG_EQUAL,
+ gen_rtx_UDIV (compute_mode, op0, op1));
}
else /* TRUNC_DIV, signed */
{
@@ -3138,12 +3246,11 @@ expand_divmod (rem_flag, code, mode, op0, op1, target, unsignedp)
if (insn != last
&& (set = single_set (insn)) != 0
&& SET_DEST (set) == quotient)
- REG_NOTES (insn)
- = gen_rtx_EXPR_LIST (REG_EQUAL,
- gen_rtx_DIV (compute_mode,
- op0,
- GEN_INT (abs_d)),
- REG_NOTES (insn));
+ set_unique_reg_note (insn,
+ REG_EQUAL,
+ gen_rtx_DIV (compute_mode,
+ op0,
+ GEN_INT (abs_d)));
quotient = expand_unop (compute_mode, neg_optab,
quotient, quotient, 0);
@@ -3208,10 +3315,9 @@ expand_divmod (rem_flag, code, mode, op0, op1, target, unsignedp)
if (insn != last
&& (set = single_set (insn)) != 0
&& SET_DEST (set) == quotient)
- REG_NOTES (insn)
- = gen_rtx_EXPR_LIST (REG_EQUAL,
- gen_rtx_DIV (compute_mode, op0, op1),
- REG_NOTES (insn));
+ set_unique_reg_note (insn,
+ REG_EQUAL,
+ gen_rtx_DIV (compute_mode, op0, op1));
}
break;
}
@@ -3624,12 +3730,11 @@ expand_divmod (rem_flag, code, mode, op0, op1, target, unsignedp)
NULL_RTX, unsignedp);
insn = get_last_insn ();
- REG_NOTES (insn)
- = gen_rtx_EXPR_LIST (REG_EQUAL,
- gen_rtx_fmt_ee (unsignedp ? UDIV : DIV,
- compute_mode,
- op0, op1),
- REG_NOTES (insn));
+ set_unique_reg_note (insn,
+ REG_EQUAL,
+ gen_rtx_fmt_ee (unsignedp ? UDIV : DIV,
+ compute_mode,
+ op0, op1));
}
break;
@@ -3675,8 +3780,8 @@ expand_divmod (rem_flag, code, mode, op0, op1, target, unsignedp)
remainder = expand_binop (compute_mode, sub_optab, op0, tem,
remainder, 0, OPTAB_LIB_WIDEN);
}
- abs_rem = expand_abs (compute_mode, remainder, NULL_RTX, 0, 0);
- abs_op1 = expand_abs (compute_mode, op1, NULL_RTX, 0, 0);
+ abs_rem = expand_abs (compute_mode, remainder, NULL_RTX, 0);
+ abs_op1 = expand_abs (compute_mode, op1, NULL_RTX, 0);
tem = expand_shift (LSHIFT_EXPR, compute_mode, abs_rem,
build_int_2 (1, 0), NULL_RTX, 1);
do_cmp_and_jump (tem, abs_op1, LTU, compute_mode, label);
@@ -4238,7 +4343,7 @@ emit_store_flag (target, code, op0, op1, mode, unsignedp, normalizep)
else if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
&& ((STORE_FLAG_VALUE & GET_MODE_MASK (mode))
- == (HOST_WIDE_INT) 1 << (GET_MODE_BITSIZE (mode) - 1)))
+ == (unsigned HOST_WIDE_INT) 1 << (GET_MODE_BITSIZE (mode) - 1)))
;
else
return 0;
@@ -4465,9 +4570,6 @@ do_cmp_and_jump (arg1, arg2, op, mode, label)
}
else
{
- emit_cmp_insn(arg1, arg2, op, NULL_RTX, mode, 0, 0);
- if (bcc_gen_fctn[(int) op] == 0)
- abort ();
- emit_jump_insn ((*bcc_gen_fctn[(int) op]) (label));
+ emit_cmp_and_jump_insns (arg1, arg2, op, NULL_RTX, mode, 0, 0, label);
}
}
diff --git a/gcc/expr.c b/gcc/expr.c
index 3be3a547a31..24b56195ac9 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -1,5 +1,5 @@
/* Convert tree expression to rtl instructions, for GNU compiler.
- Copyright (C) 1988, 92-97, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1988, 92-98, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -65,9 +65,6 @@ Boston, MA 02111-1307, USA. */
#endif
#endif
-/* Like STACK_BOUNDARY but in units of bytes, not bits. */
-#define STACK_BYTES (STACK_BOUNDARY / BITS_PER_UNIT)
-
/* Assume that case vectors are not pc-relative. */
#ifndef CASE_VECTOR_PC_RELATIVE
#define CASE_VECTOR_PC_RELATIVE 0
@@ -86,16 +83,14 @@ int cse_not_expected;
Nowadays this is never zero. */
int do_preexpand_calls = 1;
-/* Nonzero if the machine description has been fixed to accept
- CONSTANT_P_RTX patterns. We will emit a warning and continue
- if we find we must actually use such a beast. */
-static int can_handle_constant_p;
-
/* Don't check memory usage, since code is being emitted to check a memory
- usage. Used when flag_check_memory_usage is true, to avoid infinite
- recursion. */
+ usage. Used when current_function_check_memory_usage is true, to avoid
+ infinite recursion. */
static int in_check_memory_usage;
+/* Postincrements that still need to be expanded. */
+static rtx pending_chain;
+
/* This structure is used by move_by_pieces to describe the move to
be performed. */
struct move_by_pieces
@@ -135,7 +130,6 @@ extern struct obstack permanent_obstack;
static rtx get_push_address PROTO ((int));
static rtx enqueue_insn PROTO((rtx, rtx));
-static int queued_subexp_p PROTO((rtx));
static void init_queue PROTO((void));
static int move_by_pieces_ninsns PROTO((unsigned int, int));
static void move_by_pieces_1 PROTO((rtx (*) (rtx, ...), enum machine_mode,
@@ -197,6 +191,13 @@ static char direct_store[NUM_MACHINE_MODES];
#endif
#endif
+/* This macro is used to determine whether move_by_pieces should be called
+ to perform a structure copy. */
+#ifndef MOVE_BY_PIECES_P
+#define MOVE_BY_PIECES_P(SIZE, ALIGN) (move_by_pieces_ninsns \
+ (SIZE, ALIGN) < MOVE_RATIO)
+#endif
+
/* This array records the insn_code of insns to perform block moves. */
enum insn_code movstr_optab[NUM_MACHINE_MODES];
@@ -290,14 +291,6 @@ init_expr_once ()
}
}
- /* Find out if CONSTANT_P_RTX is accepted. */
- SET_DEST (pat) = gen_rtx_REG (TYPE_MODE (integer_type_node),
- FIRST_PSEUDO_REGISTER);
- SET_SRC (pat) = gen_rtx_CONSTANT_P_RTX (TYPE_MODE (integer_type_node),
- SET_DEST (pat));
- if (recog (pat, insn, &num_clobbers) >= 0)
- can_handle_constant_p = 1;
-
end_sequence ();
obfree (free_point);
}
@@ -321,8 +314,6 @@ init_expr ()
/* Manage the queue of increment instructions to be output
for POSTINCREMENT_EXPR expressions, etc. */
-static rtx pending_chain;
-
/* Queue up to increment (or change) VAR later. BODY says how:
BODY should be the same thing you would pass to emit_insn
to increment right away. It will go to emit_insn later on.
@@ -381,9 +372,8 @@ protect_from_queue (x, modify)
register rtx y = XEXP (x, 0);
register rtx new = gen_rtx_MEM (GET_MODE (x), QUEUED_VAR (y));
- MEM_IN_STRUCT_P (new) = MEM_IN_STRUCT_P (x);
RTX_UNCHANGING_P (new) = RTX_UNCHANGING_P (x);
- MEM_VOLATILE_P (new) = MEM_VOLATILE_P (x);
+ MEM_COPY_ATTRIBUTES (new, x);
MEM_ALIAS_SET (new) = MEM_ALIAS_SET (x);
if (QUEUED_INSN (y))
@@ -439,7 +429,7 @@ protect_from_queue (x, modify)
We handle only combinations of MEM, PLUS, MINUS and MULT operators
since memory addresses generally contain only those. */
-static int
+int
queued_subexp_p (x)
rtx x;
{
@@ -1045,6 +1035,8 @@ convert_move (to, from, unsignedp)
else
{
enum machine_mode intermediate;
+ rtx tmp;
+ tree shift_amount;
/* Search for a mode to convert via. */
for (intermediate = from_mode; intermediate != VOIDmode;
@@ -1061,8 +1053,18 @@ convert_move (to, from, unsignedp)
return;
}
- /* No suitable intermediate mode. */
- abort ();
+ /* No suitable intermediate mode.
+ Generate what we need with shifts. */
+ shift_amount = build_int_2 (GET_MODE_BITSIZE (to_mode)
+ - GET_MODE_BITSIZE (from_mode), 0);
+ from = gen_lowpart (to_mode, force_reg (from_mode, from));
+ tmp = expand_shift (LSHIFT_EXPR, to_mode, from, shift_amount,
+ to, unsignedp);
+ tmp = expand_shift (RSHIFT_EXPR, to_mode, tmp, shift_amount,
+ to, unsignedp);
+ if (tmp != to)
+ emit_move_insn (to, tmp);
+ return;
}
}
@@ -1334,6 +1336,38 @@ convert_modes (mode, oldmode, x, unsignedp)
return temp;
}
+
+/* This macro is used to determine what the largest unit size that
+ move_by_pieces can use is. */
+
+/* MOVE_MAX_PIECES is the number of bytes at a time which we can
+ move efficiently, as opposed to MOVE_MAX which is the maximum
+ number of bhytes we can move with a single instruction. */
+
+#ifndef MOVE_MAX_PIECES
+#define MOVE_MAX_PIECES MOVE_MAX
+#endif
+
+/* Some architectures do not have complete pre/post increment/decrement
+ instruction sets, or only move some modes efficiently. these macros
+ allow us to fine tune move_by_pieces for these targets. */
+
+#ifndef USE_LOAD_POST_INCREMENT
+#define USE_LOAD_POST_INCREMENT(MODE) HAVE_POST_INCREMENT
+#endif
+
+#ifndef USE_LOAD_PRE_DECREMENT
+#define USE_LOAD_PRE_DECREMENT(MODE) HAVE_PRE_DECREMENT
+#endif
+
+#ifndef USE_STORE_POST_INCREMENT
+#define USE_STORE_POST_INCREMENT(MODE) HAVE_POST_INCREMENT
+#endif
+
+#ifndef USE_STORE_PRE_DECREMENT
+#define USE_STORE_PRE_DECREMENT(MODE) HAVE_PRE_DECREMENT
+#endif
+
/* Generate several move instructions to copy LEN bytes
from block FROM to block TO. (These are MEM rtx's with BLKmode).
The caller must pass FROM and TO
@@ -1347,7 +1381,9 @@ move_by_pieces (to, from, len, align)
{
struct move_by_pieces data;
rtx to_addr = XEXP (to, 0), from_addr = XEXP (from, 0);
- int max_size = MOVE_MAX + 1;
+ int max_size = MOVE_MAX_PIECES + 1;
+ enum machine_mode mode = VOIDmode, tmode;
+ enum insn_code icode;
data.offset = 0;
data.to_addr = to_addr;
@@ -1378,40 +1414,38 @@ move_by_pieces (to, from, len, align)
if (!(data.autinc_from && data.autinc_to)
&& move_by_pieces_ninsns (len, align) > 2)
{
-#ifdef HAVE_PRE_DECREMENT
- if (data.reverse && ! data.autinc_from)
+ /* Find the mode of the largest move... */
+ for (tmode = GET_CLASS_NARROWEST_MODE (MODE_INT);
+ tmode != VOIDmode; tmode = GET_MODE_WIDER_MODE (tmode))
+ if (GET_MODE_SIZE (tmode) < max_size)
+ mode = tmode;
+
+ if (USE_LOAD_PRE_DECREMENT (mode) && data.reverse && ! data.autinc_from)
{
data.from_addr = copy_addr_to_reg (plus_constant (from_addr, len));
data.autinc_from = 1;
data.explicit_inc_from = -1;
}
-#endif
-#ifdef HAVE_POST_INCREMENT
- if (! data.autinc_from)
+ if (USE_LOAD_POST_INCREMENT (mode) && ! data.autinc_from)
{
data.from_addr = copy_addr_to_reg (from_addr);
data.autinc_from = 1;
data.explicit_inc_from = 1;
}
-#endif
if (!data.autinc_from && CONSTANT_P (from_addr))
data.from_addr = copy_addr_to_reg (from_addr);
-#ifdef HAVE_PRE_DECREMENT
- if (data.reverse && ! data.autinc_to)
+ if (USE_STORE_PRE_DECREMENT (mode) && data.reverse && ! data.autinc_to)
{
data.to_addr = copy_addr_to_reg (plus_constant (to_addr, len));
data.autinc_to = 1;
data.explicit_inc_to = -1;
}
-#endif
-#ifdef HAVE_POST_INCREMENT
- if (! data.reverse && ! data.autinc_to)
+ if (USE_STORE_POST_INCREMENT (mode) && ! data.reverse && ! data.autinc_to)
{
data.to_addr = copy_addr_to_reg (to_addr);
data.autinc_to = 1;
data.explicit_inc_to = 1;
}
-#endif
if (!data.autinc_to && CONSTANT_P (to_addr))
data.to_addr = copy_addr_to_reg (to_addr);
}
@@ -1425,9 +1459,6 @@ move_by_pieces (to, from, len, align)
while (max_size > 1)
{
- enum machine_mode mode = VOIDmode, tmode;
- enum insn_code icode;
-
for (tmode = GET_CLASS_NARROWEST_MODE (MODE_INT);
tmode != VOIDmode; tmode = GET_MODE_WIDER_MODE (tmode))
if (GET_MODE_SIZE (tmode) < max_size)
@@ -1522,20 +1553,16 @@ move_by_pieces_1 (genfun, mode, data)
data->offset))));
MEM_IN_STRUCT_P (from1) = data->from_struct;
-#ifdef HAVE_PRE_DECREMENT
- if (data->explicit_inc_to < 0)
+ if (HAVE_PRE_DECREMENT && data->explicit_inc_to < 0)
emit_insn (gen_add2_insn (data->to_addr, GEN_INT (-size)));
- if (data->explicit_inc_from < 0)
+ if (HAVE_PRE_DECREMENT && data->explicit_inc_from < 0)
emit_insn (gen_add2_insn (data->from_addr, GEN_INT (-size)));
-#endif
emit_insn ((*genfun) (to1, from1));
-#ifdef HAVE_POST_INCREMENT
- if (data->explicit_inc_to > 0)
+ if (HAVE_POST_INCREMENT && data->explicit_inc_to > 0)
emit_insn (gen_add2_insn (data->to_addr, GEN_INT (size)));
- if (data->explicit_inc_from > 0)
+ if (HAVE_POST_INCREMENT && data->explicit_inc_from > 0)
emit_insn (gen_add2_insn (data->from_addr, GEN_INT (size)));
-#endif
if (! data->reverse) data->offset += size;
@@ -1585,8 +1612,7 @@ emit_block_move (x, y, size, align)
if (size == 0)
abort ();
- if (GET_CODE (size) == CONST_INT
- && (move_by_pieces_ninsns (INTVAL (size), align) < MOVE_RATIO))
+ if (GET_CODE (size) == CONST_INT && MOVE_BY_PIECES_P (INTVAL (size), align))
move_by_pieces (x, y, INTVAL (size), align);
else
{
@@ -1984,7 +2010,7 @@ emit_group_store (orig_dst, src, ssize, align)
mem_in_struct_p set; we might not. */
dst = copy_rtx (orig_dst);
- MEM_IN_STRUCT_P (dst) = 1;
+ MEM_SET_IN_STRUCT_P (dst, 1);
}
/* Process the pieces. */
@@ -2048,13 +2074,13 @@ copy_blkmode_from_reg(tgtblk,srcreg,type)
{
int bytes = int_size_in_bytes (type);
rtx src = NULL, dst = NULL;
- int bitsize = MIN (TYPE_ALIGN (type), BITS_PER_WORD);
+ int bitsize = MIN (TYPE_ALIGN (type), (unsigned int) BITS_PER_WORD);
int bitpos, xbitpos, big_endian_correction = 0;
if (tgtblk == 0)
{
tgtblk = assign_stack_temp (BLKmode, bytes, 0);
- MEM_IN_STRUCT_P (tgtblk) = AGGREGATE_TYPE_P (type);
+ MEM_SET_IN_STRUCT_P (tgtblk, AGGREGATE_TYPE_P (type));
preserve_temp_slots (tgtblk);
}
@@ -2181,7 +2207,9 @@ clear_by_pieces (to, len, align)
{
struct clear_by_pieces data;
rtx to_addr = XEXP (to, 0);
- int max_size = MOVE_MAX + 1;
+ int max_size = MOVE_MAX_PIECES + 1;
+ enum machine_mode mode = VOIDmode, tmode;
+ enum insn_code icode;
data.offset = 0;
data.to_addr = to_addr;
@@ -2204,22 +2232,24 @@ clear_by_pieces (to, len, align)
if (!data.autinc_to
&& move_by_pieces_ninsns (len, align) > 2)
{
-#ifdef HAVE_PRE_DECREMENT
- if (data.reverse && ! data.autinc_to)
+ /* Determine the main mode we'll be using */
+ for (tmode = GET_CLASS_NARROWEST_MODE (MODE_INT);
+ tmode != VOIDmode; tmode = GET_MODE_WIDER_MODE (tmode))
+ if (GET_MODE_SIZE (tmode) < max_size)
+ mode = tmode;
+
+ if (USE_STORE_PRE_DECREMENT (mode) && data.reverse && ! data.autinc_to)
{
data.to_addr = copy_addr_to_reg (plus_constant (to_addr, len));
data.autinc_to = 1;
data.explicit_inc_to = -1;
}
-#endif
-#ifdef HAVE_POST_INCREMENT
- if (! data.reverse && ! data.autinc_to)
+ if (USE_STORE_POST_INCREMENT (mode) && ! data.reverse && ! data.autinc_to)
{
data.to_addr = copy_addr_to_reg (to_addr);
data.autinc_to = 1;
data.explicit_inc_to = 1;
}
-#endif
if (!data.autinc_to && CONSTANT_P (to_addr))
data.to_addr = copy_addr_to_reg (to_addr);
}
@@ -2233,9 +2263,6 @@ clear_by_pieces (to, len, align)
while (max_size > 1)
{
- enum machine_mode mode = VOIDmode, tmode;
- enum insn_code icode;
-
for (tmode = GET_CLASS_NARROWEST_MODE (MODE_INT);
tmode != VOIDmode; tmode = GET_MODE_WIDER_MODE (tmode))
if (GET_MODE_SIZE (tmode) < max_size)
@@ -2282,16 +2309,12 @@ clear_by_pieces_1 (genfun, mode, data)
data->offset))));
MEM_IN_STRUCT_P (to1) = data->to_struct;
-#ifdef HAVE_PRE_DECREMENT
- if (data->explicit_inc_to < 0)
+ if (HAVE_PRE_DECREMENT && data->explicit_inc_to < 0)
emit_insn (gen_add2_insn (data->to_addr, GEN_INT (-size)));
-#endif
emit_insn ((*genfun) (to1, const0_rtx));
-#ifdef HAVE_POST_INCREMENT
- if (data->explicit_inc_to > 0)
+ if (HAVE_POST_INCREMENT && data->explicit_inc_to > 0)
emit_insn (gen_add2_insn (data->to_addr, GEN_INT (size)));
-#endif
if (! data->reverse) data->offset += size;
@@ -2323,7 +2346,7 @@ clear_storage (object, size, align)
size = protect_from_queue (size, 0);
if (GET_CODE (size) == CONST_INT
- && (move_by_pieces_ninsns (INTVAL (size), align) < MOVE_RATIO))
+ && MOVE_BY_PIECES_P (INTVAL (size), align))
clear_by_pieces (object, INTVAL (size), align);
else
@@ -2469,7 +2492,10 @@ emit_move_insn (x, y)
if (mode == BLKmode || (GET_MODE (y) != mode && GET_MODE (y) != VOIDmode))
abort ();
- if (CONSTANT_P (y) && ! LEGITIMATE_CONSTANT_P (y))
+ /* Never force constant_p_rtx to memory. */
+ if (GET_CODE (y) == CONSTANT_P_RTX)
+ ;
+ else if (CONSTANT_P (y) && ! LEGITIMATE_CONSTANT_P (y))
y = force_const_mem (mode, y);
/* If X or Y are memory references, verify that their addresses are valid
@@ -2550,9 +2576,14 @@ emit_move_insn_1 (x, y)
}
else
{
- /* Show the output dies here. */
- if (x != y)
- emit_insn (gen_rtx_CLOBBER (VOIDmode, x));
+ /* Show the output dies here. This is necessary for pseudos;
+ hard regs shouldn't appear here except as return values.
+ We never want to emit such a clobber after reload. */
+ if (x != y
+ && ! (reload_in_progress || reload_completed))
+ {
+ emit_insn (gen_rtx_CLOBBER (VOIDmode, x));
+ }
emit_insn (GEN_FCN (mov_optab->handlers[(int) submode].insn_code)
(gen_realpart (submode, x), gen_realpart (submode, y)));
@@ -2581,9 +2612,14 @@ emit_move_insn_1 (x, y)
}
#endif
- /* Show the output dies here. */
- if (x != y)
- emit_insn (gen_rtx_CLOBBER (VOIDmode, x));
+ /* Show the output dies here. This is necessary for pseudos;
+ hard regs shouldn't appear here except as return values.
+ We never want to emit such a clobber after reload. */
+ if (x != y
+ && ! (reload_in_progress || reload_completed))
+ {
+ emit_insn (gen_rtx_CLOBBER (VOIDmode, x));
+ }
for (i = 0;
i < (GET_MODE_SIZE (mode) + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD;
@@ -2647,7 +2683,13 @@ push_block (size, extra, below)
anti_adjust_stack (temp);
}
-#ifdef STACK_GROWS_DOWNWARD
+#if defined (STACK_GROWS_DOWNWARD) \
+ || (defined (ARGS_GROW_DOWNWARD) \
+ && !defined (ACCUMULATE_OUTGOING_ARGS))
+
+ /* Return the lowest stack address when STACK or ARGS grow downward and
+ we are not aaccumulating outgoing arguments (the c4x port uses such
+ conventions). */
temp = virtual_outgoing_args_rtx;
if (extra != 0 && below)
temp = plus_constant (temp, extra);
@@ -2792,8 +2834,7 @@ emit_push_insn (x, mode, type, size, align, partial, reg, extra,
if (args_addr == 0
&& GET_CODE (size) == CONST_INT
&& skip == 0
- && (move_by_pieces_ninsns ((unsigned) INTVAL (size) - used, align)
- < MOVE_RATIO)
+ && (MOVE_BY_PIECES_P ((unsigned) INTVAL (size) - used, align))
/* Here we avoid the case of a structure whose weak alignment
forces many pushes of a small amount of data,
and such small pushes do rounding that causes trouble. */
@@ -2812,7 +2853,7 @@ emit_push_insn (x, mode, type, size, align, partial, reg, extra,
move_by_pieces (gen_rtx_MEM (BLKmode, gen_push_operand ()), xinner,
INTVAL (size) - used, align);
- if (flag_check_memory_usage && ! in_check_memory_usage)
+ if (current_function_check_memory_usage && ! in_check_memory_usage)
{
rtx temp;
@@ -2869,7 +2910,7 @@ emit_push_insn (x, mode, type, size, align, partial, reg, extra,
args_addr,
args_so_far),
skip));
- if (flag_check_memory_usage && ! in_check_memory_usage)
+ if (current_function_check_memory_usage && ! in_check_memory_usage)
{
rtx target;
@@ -2891,8 +2932,7 @@ emit_push_insn (x, mode, type, size, align, partial, reg, extra,
/* TEMP is the address of the block. Copy the data there. */
if (GET_CODE (size) == CONST_INT
- && (move_by_pieces_ninsns ((unsigned) INTVAL (size), align)
- < MOVE_RATIO))
+ && (MOVE_BY_PIECES_P ((unsigned) INTVAL (size), align)))
{
move_by_pieces (gen_rtx_MEM (BLKmode, temp), xinner,
INTVAL (size), align);
@@ -3069,7 +3109,7 @@ emit_push_insn (x, mode, type, size, align, partial, reg, extra,
emit_move_insn (gen_rtx_MEM (mode, addr), x);
- if (flag_check_memory_usage && ! in_check_memory_usage)
+ if (current_function_check_memory_usage && ! in_check_memory_usage)
{
in_check_memory_usage = 1;
if (target == 0)
@@ -3183,8 +3223,11 @@ expand_assignment (to, from, want_value, suggest_reg)
#endif
}
+ /* A constant address in TO_RTX can have VOIDmode, we must not try
+ to call force_reg for that case. Avoid that case. */
if (GET_CODE (to_rtx) == MEM
&& GET_MODE (to_rtx) == BLKmode
+ && GET_MODE (XEXP (to_rtx, 0)) != VOIDmode
&& bitsize
&& (bitpos % bitsize) == 0
&& (bitsize % GET_MODE_ALIGNMENT (mode1)) == 0
@@ -3237,7 +3280,7 @@ expand_assignment (to, from, want_value, suggest_reg)
}
/* Check the access. */
- if (flag_check_memory_usage && GET_CODE (to_rtx) == MEM)
+ if (current_function_check_memory_usage && GET_CODE (to_rtx) == MEM)
{
rtx to_addr;
int size;
@@ -3363,7 +3406,7 @@ expand_assignment (to, from, want_value, suggest_reg)
EXPAND_MEMORY_USE_DONT);
/* Copy the rights of the bitmap. */
- if (flag_check_memory_usage)
+ if (current_function_check_memory_usage)
emit_library_call (chkr_copy_bitmap_libfunc, 1, VOIDmode, 3,
XEXP (to_rtx, 0), ptr_mode,
XEXP (from_rtx, 0), ptr_mode,
@@ -3474,21 +3517,6 @@ store_expr (exp, target, want_value)
return want_value ? target : NULL_RTX;
}
- else if (want_value && GET_CODE (target) == MEM && ! MEM_VOLATILE_P (target)
- && GET_MODE (target) != BLKmode)
- /* If target is in memory and caller wants value in a register instead,
- arrange that. Pass TARGET as target for expand_expr so that,
- if EXP is another assignment, WANT_VALUE will be nonzero for it.
- We know expand_expr will not use the target in that case.
- Don't do this if TARGET is volatile because we are supposed
- to write it and then read it. */
- {
- temp = expand_expr (exp, cse_not_expected ? NULL_RTX : target,
- GET_MODE (target), 0);
- if (GET_MODE (temp) != BLKmode && GET_MODE (temp) != VOIDmode)
- temp = copy_to_reg (temp);
- dont_return_target = 1;
- }
else if (queued_subexp_p (target))
/* If target contains a postincrement, let's not risk
using it as the place to generate the rhs. */
@@ -3508,6 +3536,21 @@ store_expr (exp, target, want_value)
if (! MEM_VOLATILE_P (target) && want_value)
dont_return_target = 1;
}
+ else if (want_value && GET_CODE (target) == MEM && ! MEM_VOLATILE_P (target)
+ && GET_MODE (target) != BLKmode)
+ /* If target is in memory and caller wants value in a register instead,
+ arrange that. Pass TARGET as target for expand_expr so that,
+ if EXP is another assignment, WANT_VALUE will be nonzero for it.
+ We know expand_expr will not use the target in that case.
+ Don't do this if TARGET is volatile because we are supposed
+ to write it and then read it. */
+ {
+ temp = expand_expr (exp, cse_not_expected ? NULL_RTX : target,
+ GET_MODE (target), 0);
+ if (GET_MODE (temp) != BLKmode && GET_MODE (temp) != VOIDmode)
+ temp = copy_to_reg (temp);
+ dont_return_target = 1;
+ }
else if (GET_CODE (target) == SUBREG && SUBREG_PROMOTED_VAR_P (target))
/* If this is an scalar in a register that is stored in a wider mode
than the declared mode, compute the result into its declared mode
@@ -3585,7 +3628,7 @@ store_expr (exp, target, want_value)
temp = convert_modes (GET_MODE (target), TYPE_MODE (TREE_TYPE (exp)),
temp, TREE_UNSIGNED (TREE_TYPE (exp)));
- if (flag_check_memory_usage
+ if (current_function_check_memory_usage
&& GET_CODE (target) == MEM
&& AGGREGATE_TYPE_P (TREE_TYPE (exp)))
{
@@ -3604,10 +3647,21 @@ store_expr (exp, target, want_value)
/* If value was not generated in the target, store it there.
Convert the value to TARGET's type first if nec. */
+ /* If TEMP and TARGET compare equal according to rtx_equal_p, but
+ one or both of them are volatile memory refs, we have to distinguish
+ two cases:
+ - expand_expr has used TARGET. In this case, we must not generate
+ another copy. This can be detected by TARGET being equal according
+ to == .
+ - expand_expr has not used TARGET - that means that the source just
+ happens to have the same RTX form. Since temp will have been created
+ by expand_expr, it will compare unequal according to == .
+ We must generate a copy in this case, to reach the correct number
+ of volatile memory references. */
if ((! rtx_equal_p (temp, target)
- || side_effects_p (temp)
- || side_effects_p (target))
+ || (temp != target && (side_effects_p (temp)
+ || side_effects_p (target))))
&& TREE_CODE (exp) != ERROR_MARK)
{
target = protect_from_queue (target, 1);
@@ -3680,16 +3734,15 @@ store_expr (exp, target, want_value)
copy_size_rtx, NULL_RTX, 0,
OPTAB_LIB_WIDEN);
- emit_cmp_insn (size, const0_rtx, LT, NULL_RTX,
- GET_MODE (size), 0, 0);
label = gen_label_rtx ();
- emit_jump_insn (gen_blt (label));
+ emit_cmp_and_jump_insns (size, const0_rtx, LT, NULL_RTX,
+ GET_MODE (size), 0, 0, label);
}
if (size != const0_rtx)
{
/* Be sure we can write on ADDR. */
- if (flag_check_memory_usage)
+ if (current_function_check_memory_usage)
emit_library_call (chkr_check_addr_libfunc, 1, VOIDmode, 3,
addr, ptr_mode,
size, TYPE_MODE (sizetype),
@@ -4480,8 +4533,8 @@ store_field (target, bitsize, bitpos, mode, exp, value_mode,
GET_MODE_SIZE (GET_MODE (target)), 0);
rtx blk_object = copy_rtx (object);
- MEM_IN_STRUCT_P (object) = 1;
- MEM_IN_STRUCT_P (blk_object) = 1;
+ MEM_SET_IN_STRUCT_P (object, 1);
+ MEM_SET_IN_STRUCT_P (blk_object, 1);
PUT_MODE (blk_object, BLKmode);
if (bitsize != GET_MODE_BITSIZE (GET_MODE (target)))
@@ -4602,7 +4655,7 @@ store_field (target, bitsize, bitpos, mode, exp, value_mode,
plus_constant (addr,
(bitpos
/ BITS_PER_UNIT))));
- MEM_IN_STRUCT_P (to_rtx) = 1;
+ MEM_SET_IN_STRUCT_P (to_rtx, 1);
MEM_ALIAS_SET (to_rtx) = alias_set;
return store_expr (exp, to_rtx, value_mode != VOIDmode);
@@ -4650,7 +4703,7 @@ get_inner_reference (exp, pbitsize, pbitpos, poffset, pmode,
tree size_tree = 0;
enum machine_mode mode = VOIDmode;
tree offset = integer_zero_node;
- int alignment = BIGGEST_ALIGNMENT;
+ unsigned int alignment = BIGGEST_ALIGNMENT;
if (TREE_CODE (exp) == COMPONENT_REF)
{
@@ -4667,6 +4720,9 @@ get_inner_reference (exp, pbitsize, pbitpos, poffset, pmode,
else
{
mode = TYPE_MODE (TREE_TYPE (exp));
+ if (mode == BLKmode)
+ size_tree = TYPE_SIZE (TREE_TYPE (exp));
+
*pbitsize = GET_MODE_BITSIZE (mode);
*punsignedp = TREE_UNSIGNED (TREE_TYPE (exp));
}
@@ -5365,21 +5421,34 @@ expand_expr (exp, target, tmode, modifier)
register rtx op0, op1, temp;
tree type = TREE_TYPE (exp);
int unsignedp = TREE_UNSIGNED (type);
- register enum machine_mode mode = TYPE_MODE (type);
+ register enum machine_mode mode;
register enum tree_code code = TREE_CODE (exp);
optab this_optab;
- /* Use subtarget as the target for operand 0 of a binary operation. */
- rtx subtarget = (target != 0 && GET_CODE (target) == REG ? target : 0);
- rtx original_target = target;
- int ignore = (target == const0_rtx
- || ((code == NON_LVALUE_EXPR || code == NOP_EXPR
- || code == CONVERT_EXPR || code == REFERENCE_EXPR
- || code == COND_EXPR)
- && TREE_CODE (type) == VOID_TYPE));
+ rtx subtarget, original_target;
+ int ignore;
tree context;
/* Used by check-memory-usage to make modifier read only. */
enum expand_modifier ro_modifier;
+ /* Handle ERROR_MARK before anybody tries to access its type. */
+ if (TREE_CODE (exp) == ERROR_MARK)
+ {
+ op0 = CONST0_RTX (tmode);
+ if (op0 != 0)
+ return op0;
+ return const0_rtx;
+ }
+
+ mode = TYPE_MODE (type);
+ /* Use subtarget as the target for operand 0 of a binary operation. */
+ subtarget = (target != 0 && GET_CODE (target) == REG ? target : 0);
+ original_target = target;
+ ignore = (target == const0_rtx
+ || ((code == NON_LVALUE_EXPR || code == NOP_EXPR
+ || code == CONVERT_EXPR || code == REFERENCE_EXPR
+ || code == COND_EXPR)
+ && TREE_CODE (type) == VOID_TYPE));
+
/* Make a read-only version of the modifier. */
if (modifier == EXPAND_NORMAL || modifier == EXPAND_SUM
|| modifier == EXPAND_CONST_ADDRESS || modifier == EXPAND_INITIALIZER)
@@ -5446,6 +5515,7 @@ expand_expr (exp, target, tmode, modifier)
&& TREE_CODE (exp) != COMPONENT_REF
&& TREE_CODE (exp) != BIT_FIELD_REF
&& TREE_CODE (exp) != INDIRECT_REF
+ && TREE_CODE (exp) != CALL_EXPR
&& TREE_CODE (exp) != VAR_DECL)
{
enum machine_mode mode = GET_MODE (target);
@@ -5462,6 +5532,7 @@ expand_expr (exp, target, tmode, modifier)
&& TREE_CODE (exp) != BIT_FIELD_REF
&& TREE_CODE (exp) != INDIRECT_REF
&& TREE_CODE (exp) != VAR_DECL
+ && TREE_CODE (exp) != CALL_EXPR
&& GET_MODE_CLASS (tmode) == MODE_INT
&& tmode > MAX_INTEGER_COMPUTATION_MODE)
fatal ("unsupported wide integer operation");
@@ -5498,9 +5569,13 @@ expand_expr (exp, target, tmode, modifier)
p->expr->x_forced_labels);
pop_obstacks ();
}
- else if (modifier == EXPAND_INITIALIZER)
- forced_labels = gen_rtx_EXPR_LIST (VOIDmode,
- label_rtx (exp), forced_labels);
+ else
+ {
+ if (modifier == EXPAND_INITIALIZER)
+ forced_labels = gen_rtx_EXPR_LIST (VOIDmode,
+ label_rtx (exp),
+ forced_labels);
+ }
temp = gen_rtx_MEM (FUNCTION_MODE,
gen_rtx_LABEL_REF (Pmode, label_rtx (exp)));
if (function != current_function_decl
@@ -5531,13 +5606,16 @@ expand_expr (exp, target, tmode, modifier)
pop_obstacks ();
}
- /* Only check automatic variables. Currently, function arguments are
- not checked (this can be done at compile-time with prototypes).
- Aggregates are not checked. */
- if (flag_check_memory_usage && code == VAR_DECL
+ /* Although static-storage variables start off initialized, according to
+ ANSI C, a memcpy could overwrite them with uninitialized values. So
+ we check them too. This also lets us check for read-only variables
+ accessed via a non-const declaration, in case it won't be detected
+ any other way (e.g., in an embedded system or OS kernel without
+ memory protection).
+
+ Aggregates are not checked here; they're handled elsewhere. */
+ if (current_function_check_memory_usage && code == VAR_DECL
&& GET_CODE (DECL_RTL (exp)) == MEM
- && DECL_CONTEXT (exp) != NULL_TREE
- && ! TREE_STATIC (exp)
&& ! AGGREGATE_TYPE_P (TREE_TYPE (exp)))
{
enum memory_use_mode memory_usage;
@@ -5905,7 +5983,7 @@ expand_expr (exp, target, tmode, modifier)
case EXIT_BLOCK_EXPR:
if (EXIT_BLOCK_RETURN (exp))
- really_sorry ("returned value in block_exit_expr");
+ sorry ("returned value in block_exit_expr");
expand_goto (LABELED_BLOCK_LABEL (EXIT_BLOCK_LABELED_BLOCK (exp)));
return const0_rtx;
@@ -5987,10 +6065,9 @@ expand_expr (exp, target, tmode, modifier)
&& ! (target != 0 && safe_from_p (target, exp, 1)))
|| TREE_ADDRESSABLE (exp)
|| (TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
- && (move_by_pieces_ninsns
- (TREE_INT_CST_LOW (TYPE_SIZE (type))/BITS_PER_UNIT,
- TYPE_ALIGN (type) / BITS_PER_UNIT)
- >= MOVE_RATIO)
+ && (!MOVE_BY_PIECES_P
+ (TREE_INT_CST_LOW (TYPE_SIZE (type))/BITS_PER_UNIT,
+ TYPE_ALIGN (type) / BITS_PER_UNIT))
&& ! mostly_zeros_p (exp))))
|| (modifier == EXPAND_INITIALIZER && TREE_CONSTANT (exp)))
{
@@ -6054,7 +6131,7 @@ expand_expr (exp, target, tmode, modifier)
op0 = expand_expr (exp1, NULL_RTX, VOIDmode, EXPAND_SUM);
op0 = memory_address (mode, op0);
- if (flag_check_memory_usage && !AGGREGATE_TYPE_P (TREE_TYPE (exp)))
+ if (current_function_check_memory_usage && !AGGREGATE_TYPE_P (TREE_TYPE (exp)))
{
enum memory_use_mode memory_usage;
memory_usage = get_memory_usage_from_modifier (modifier);
@@ -6082,26 +6159,7 @@ expand_expr (exp, target, tmode, modifier)
|| (TREE_CODE (exp1) == ADDR_EXPR
&& (exp2 = TREE_OPERAND (exp1, 0))
&& AGGREGATE_TYPE_P (TREE_TYPE (exp2))))
- MEM_IN_STRUCT_P (temp) = 1;
-
- /* If the pointer is actually a REFERENCE_TYPE, this could be pointing
- into some aggregate too. In theory we could fold this into the
- previous check and use rtx_addr_varies_p there too.
-
- However, this seems safer. */
- if (!MEM_IN_STRUCT_P (temp)
- && (TREE_CODE (TREE_TYPE (exp1)) == REFERENCE_TYPE
- /* This may have been an array reference to the first element
- that was optimized away from being an addition. */
- || (TREE_CODE (exp1) == NOP_EXPR
- && ((TREE_CODE (TREE_TYPE (TREE_OPERAND (exp1, 0)))
- == REFERENCE_TYPE)
- || ((TREE_CODE (TREE_TYPE (TREE_OPERAND (exp1, 0)))
- == POINTER_TYPE)
- && (AGGREGATE_TYPE_P
- (TREE_TYPE (TREE_TYPE
- (TREE_OPERAND (exp1, 0))))))))))
- MEM_IN_STRUCT_P (temp) = ! rtx_addr_varies_p (temp);
+ MEM_SET_IN_STRUCT_P (temp, 1);
MEM_VOLATILE_P (temp) = TREE_THIS_VOLATILE (exp) | flag_volatile;
MEM_ALIAS_SET (temp) = get_alias_set (exp);
@@ -6358,7 +6416,7 @@ expand_expr (exp, target, tmode, modifier)
}
/* Check the access. */
- if (flag_check_memory_usage && GET_CODE (op0) == MEM)
+ if (current_function_check_memory_usage && GET_CODE (op0) == MEM)
{
enum memory_use_mode memory_usage;
memory_usage = get_memory_usage_from_modifier (modifier);
@@ -6400,7 +6458,7 @@ expand_expr (exp, target, tmode, modifier)
/* If the field isn't aligned enough to fetch as a memref,
fetch it as a bit field. */
|| (SLOW_UNALIGNED_ACCESS
- && ((TYPE_ALIGN (TREE_TYPE (tem)) < GET_MODE_ALIGNMENT (mode))
+ && ((TYPE_ALIGN (TREE_TYPE (tem)) < (unsigned int) GET_MODE_ALIGNMENT (mode))
|| (bitpos % GET_MODE_ALIGNMENT (mode) != 0))))))
{
enum machine_mode ext_mode = mode;
@@ -6460,7 +6518,7 @@ expand_expr (exp, target, tmode, modifier)
emit_move_insn (new, op0);
op0 = copy_rtx (new);
PUT_MODE (op0, BLKmode);
- MEM_IN_STRUCT_P (op0) = 1;
+ MEM_SET_IN_STRUCT_P (op0, 1);
}
return op0;
@@ -6487,7 +6545,7 @@ expand_expr (exp, target, tmode, modifier)
if (GET_CODE (XEXP (op0, 0)) == REG)
mark_reg_pointer (XEXP (op0, 0), alignment);
- MEM_IN_STRUCT_P (op0) = 1;
+ MEM_SET_IN_STRUCT_P (op0, 1);
MEM_VOLATILE_P (op0) |= volatilep;
if (mode == mode1 || mode1 == BLKmode || mode1 == tmode
|| modifier == EXPAND_CONST_ADDRESS
@@ -6559,17 +6617,15 @@ expand_expr (exp, target, tmode, modifier)
if (! (GET_CODE (index_val) == CONST_INT
&& GET_CODE (lo_r) == CONST_INT))
{
- emit_cmp_insn (index_val, lo_r, LT, NULL_RTX,
- GET_MODE (index_val), iunsignedp, 0);
- emit_jump_insn (gen_blt (op1));
+ emit_cmp_and_jump_insns (index_val, lo_r, LT, NULL_RTX,
+ GET_MODE (index_val), iunsignedp, 0, op1);
}
if (! (GET_CODE (index_val) == CONST_INT
&& GET_CODE (hi_r) == CONST_INT))
{
- emit_cmp_insn (index_val, hi_r, GT, NULL_RTX,
- GET_MODE (index_val), iunsignedp, 0);
- emit_jump_insn (gen_bgt (op1));
+ emit_cmp_and_jump_insns (index_val, hi_r, GT, NULL_RTX,
+ GET_MODE (index_val), iunsignedp, 0, op1);
}
/* Calculate the element number of bit zero in the first word
@@ -7112,7 +7168,7 @@ expand_expr (exp, target, tmode, modifier)
if (TREE_UNSIGNED (type))
return op0;
- return expand_abs (mode, op0, target, unsignedp,
+ return expand_abs (mode, op0, target,
safe_from_p (target, TREE_OPERAND (exp, 0), 1));
case MAX_EXPR:
@@ -7266,9 +7322,8 @@ expand_expr (exp, target, tmode, modifier)
temp = copy_to_reg (temp);
op1 = gen_label_rtx ();
- emit_cmp_insn (temp, const0_rtx, EQ, NULL_RTX,
- GET_MODE (temp), unsignedp, 0);
- emit_jump_insn (gen_beq (op1));
+ emit_cmp_and_jump_insns (temp, const0_rtx, EQ, NULL_RTX,
+ GET_MODE (temp), unsignedp, 0, op1);
emit_move_insn (temp, const1_rtx);
emit_label (op1);
return temp;
@@ -7997,6 +8052,47 @@ expand_expr (exp, target, tmode, modifier)
return op0;
}
+ case TRY_FINALLY_EXPR:
+ {
+ tree try_block = TREE_OPERAND (exp, 0);
+ tree finally_block = TREE_OPERAND (exp, 1);
+ rtx finally_label = gen_label_rtx ();
+ rtx done_label = gen_label_rtx ();
+ rtx return_link = gen_reg_rtx (Pmode);
+ tree cleanup = build (GOTO_SUBROUTINE_EXPR, void_type_node,
+ (tree) finally_label, (tree) return_link);
+ TREE_SIDE_EFFECTS (cleanup) = 1;
+
+ /* Start a new binding layer that will keep track of all cleanup
+ actions to be performed. */
+ expand_start_bindings (0);
+
+ target_temp_slot_level = temp_slot_level;
+
+ expand_decl_cleanup (NULL_TREE, cleanup);
+ op0 = expand_expr (try_block, target, tmode, modifier);
+
+ preserve_temp_slots (op0);
+ expand_end_bindings (NULL_TREE, 0, 0);
+ emit_jump (done_label);
+ emit_label (finally_label);
+ expand_expr (finally_block, const0_rtx, VOIDmode, 0);
+ emit_indirect_jump (return_link);
+ emit_label (done_label);
+ return op0;
+ }
+
+ case GOTO_SUBROUTINE_EXPR:
+ {
+ rtx subr = (rtx) TREE_OPERAND (exp, 0);
+ rtx return_link = *(rtx *) &TREE_OPERAND (exp, 1);
+ rtx return_address = gen_label_rtx ();
+ emit_move_insn (return_link, gen_rtx_LABEL_REF (Pmode, return_address));
+ emit_jump (subr);
+ emit_label (return_address);
+ return const0_rtx;
+ }
+
case POPDCC_EXPR:
{
rtx dcc = get_dynamic_cleanup_chain ();
@@ -8011,12 +8107,6 @@ expand_expr (exp, target, tmode, modifier)
return const0_rtx;
}
- case ERROR_MARK:
- op0 = CONST0_RTX (tmode);
- if (op0 != 0)
- return op0;
- return const0_rtx;
-
default:
return (*lang_expand_expr) (exp, original_target, tmode, modifier);
}
@@ -8359,7 +8449,7 @@ expand_builtin_setjmp (buf_addr, target, first_label, next_label)
if (fixed_regs[ARG_POINTER_REGNUM])
{
#ifdef ELIMINABLE_REGS
- int i;
+ size_t i;
static struct elims {int from, to;} elim_regs[] = ELIMINABLE_REGS;
for (i = 0; i < sizeof elim_regs / sizeof elim_regs[0]; i++)
@@ -8505,7 +8595,7 @@ get_memory_rtx (exp)
is_aggregate = AGGREGATE_TYPE_P (type);
}
- MEM_IN_STRUCT_P (mem) = is_aggregate;
+ MEM_SET_IN_STRUCT_P (mem, is_aggregate);
return mem;
}
@@ -8614,8 +8704,8 @@ expand_builtin (exp, target, subtarget, mode, ignore)
/* Test the result; if it is NaN, set errno=EDOM because
the argument was not in the domain. */
- emit_cmp_insn (target, target, EQ, 0, GET_MODE (target), 0, 0);
- emit_jump_insn (gen_beq (lab1));
+ emit_cmp_and_jump_insns (target, target, EQ, 0, GET_MODE (target),
+ 0, 0, lab1);
#ifdef TARGET_EDOM
{
@@ -8928,36 +9018,37 @@ expand_builtin (exp, target, subtarget, mode, ignore)
else
{
tree arg = TREE_VALUE (arglist);
+ rtx tmp;
+ /* We return 1 for a numeric type that's known to be a constant
+ value at compile-time or for an aggregate type that's a
+ literal constant. */
STRIP_NOPS (arg);
- if (really_constant_p (arg)
+
+ /* If we know this is a constant, emit the constant of one. */
+ if (TREE_CODE_CLASS (TREE_CODE (arg)) == 'c'
+ || (TREE_CODE (arg) == CONSTRUCTOR
+ && TREE_CONSTANT (arg))
|| (TREE_CODE (arg) == ADDR_EXPR
&& TREE_CODE (TREE_OPERAND (arg, 0)) == STRING_CST))
return const1_rtx;
- /* Only emit CONSTANT_P_RTX if CSE will be run.
- Moreover, we don't want to expand trees that have side effects,
- as the original __builtin_constant_p did not evaluate its
- argument at all, and we would break existing usage by changing
- this. This quirk was generally useful, eliminating a bit of hair
- in the writing of the macros that use this function. Now the
- same thing can be better accomplished in an inline function. */
+ /* If we aren't going to be running CSE or this expression
+ has side effects, show we don't know it to be a constant.
+ Likewise if it's a pointer or aggregate type since in those
+ case we only want literals, since those are only optimized
+ when generating RTL, not later. */
+ if (TREE_SIDE_EFFECTS (arg) || cse_not_expected
+ || AGGREGATE_TYPE_P (TREE_TYPE (arg))
+ || POINTER_TYPE_P (TREE_TYPE (arg)))
+ return const0_rtx;
- if (! cse_not_expected && ! TREE_SIDE_EFFECTS (arg))
- {
- /* Lazy fixup of old code: issue a warning and fail the test. */
- if (! can_handle_constant_p)
- {
- warning ("Delayed evaluation of __builtin_constant_p not supported on this target.");
- warning ("Please report this as a bug to egcs-bugs@cygnus.com.");
- return const0_rtx;
- }
- return gen_rtx_CONSTANT_P_RTX (TYPE_MODE (integer_type_node),
- expand_expr (arg, NULL_RTX,
- VOIDmode, 0));
- }
+ /* Otherwise, emit (constant_p_rtx (ARG)) and let CSE get a
+ chance to see if it can deduce whether ARG is constant. */
- return const0_rtx;
+ tmp = expand_expr (arg, NULL_RTX, VOIDmode, 0);
+ tmp = gen_rtx_CONSTANT_P_RTX (value_mode, tmp);
+ return tmp;
}
case BUILT_IN_FRAME_ADDRESS:
@@ -9109,7 +9200,7 @@ expand_builtin (exp, target, subtarget, mode, ignore)
src_rtx = copy_to_mode_reg (Pmode, src_rtx);
/* Check the string is readable and has an end. */
- if (flag_check_memory_usage)
+ if (current_function_check_memory_usage)
emit_library_call (chkr_check_str_libfunc, 1, VOIDmode, 2,
src_rtx, ptr_mode,
GEN_INT (MEMORY_USE_RO),
@@ -9202,7 +9293,7 @@ expand_builtin (exp, target, subtarget, mode, ignore)
len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
/* Just copy the rights of SRC to the rights of DEST. */
- if (flag_check_memory_usage)
+ if (current_function_check_memory_usage)
emit_library_call (chkr_copy_bitmap_libfunc, 1, VOIDmode, 3,
XEXP (dest_mem, 0), ptr_mode,
XEXP (src_mem, 0), ptr_mode,
@@ -9273,7 +9364,7 @@ expand_builtin (exp, target, subtarget, mode, ignore)
dest_mem = get_memory_rtx (dest);
/* Just check DST is writable and mark it as readable. */
- if (flag_check_memory_usage)
+ if (current_function_check_memory_usage)
emit_library_call (chkr_check_addr_libfunc, 1, VOIDmode, 3,
XEXP (dest_mem, 0), ptr_mode,
len_rtx, TYPE_MODE (sizetype),
@@ -9299,7 +9390,7 @@ expand_builtin (exp, target, subtarget, mode, ignore)
break;
/* If we need to check memory accesses, call the library function. */
- if (flag_check_memory_usage)
+ if (current_function_check_memory_usage)
break;
if (arglist == 0
@@ -9355,7 +9446,7 @@ expand_builtin (exp, target, subtarget, mode, ignore)
break;
/* If we need to check memory accesses, call the library function. */
- if (flag_check_memory_usage)
+ if (current_function_check_memory_usage)
break;
if (arglist == 0
@@ -10184,7 +10275,7 @@ expand_increment (exp, post, ignore)
/* Increment however we can. */
op1 = expand_binop (mode, this_optab, value, op1,
- flag_check_memory_usage ? NULL_RTX : op0,
+ current_function_check_memory_usage ? NULL_RTX : op0,
TREE_UNSIGNED (TREE_TYPE (exp)), OPTAB_LIB_WIDEN);
/* Make sure the value is stored into OP0. */
if (op1 != op0)
@@ -10962,7 +11053,8 @@ do_jump_for_compare (comparison, if_false_label, if_true_label)
if (if_true_label)
{
if (bcc_gen_fctn[(int) GET_CODE (comparison)] != 0)
- emit_jump_insn ((*bcc_gen_fctn[(int) GET_CODE (comparison)]) (if_true_label));
+ emit_jump_insn ((*bcc_gen_fctn[(int) GET_CODE (comparison)])
+ (if_true_label));
else
abort ();
@@ -10971,52 +11063,80 @@ do_jump_for_compare (comparison, if_false_label, if_true_label)
}
else if (if_false_label)
{
- rtx insn;
- rtx prev = get_last_insn ();
- rtx branch = 0;
+ rtx first = get_last_insn (), insn, branch;
+ int br_count;
/* Output the branch with the opposite condition. Then try to invert
what is generated. If more than one insn is a branch, or if the
branch is not the last insn written, abort. If we can't invert
the branch, emit make a true label, redirect this jump to that,
emit a jump to the false label and define the true label. */
+ /* ??? Note that we wouldn't have to do any of this nonsense if
+ we passed both labels into a combined compare-and-branch.
+ Ah well, jump threading does a good job of repairing the damage. */
if (bcc_gen_fctn[(int) GET_CODE (comparison)] != 0)
- emit_jump_insn ((*bcc_gen_fctn[(int) GET_CODE (comparison)])(if_false_label));
+ emit_jump_insn ((*bcc_gen_fctn[(int) GET_CODE (comparison)])
+ (if_false_label));
else
abort ();
- /* Here we get the first insn that was just emitted. It used to be the
+ /* Here we get the first insn that was just emitted. It used to be the
case that, on some machines, emitting the branch would discard
the previous compare insn and emit a replacement. This isn't
- done anymore, but abort if we see that PREV is deleted. */
+ done anymore, but abort if we see that FIRST is deleted. */
- if (prev == 0)
- insn = get_insns ();
- else if (INSN_DELETED_P (prev))
+ if (first == 0)
+ first = get_insns ();
+ else if (INSN_DELETED_P (first))
abort ();
else
- insn = NEXT_INSN (prev);
+ first = NEXT_INSN (first);
+
+ /* Look for multiple branches in this sequence, as might be generated
+ for a multi-word integer comparison. */
- for (; insn; insn = NEXT_INSN (insn))
+ br_count = 0;
+ branch = NULL_RTX;
+ for (insn = first; insn ; insn = NEXT_INSN (insn))
if (GET_CODE (insn) == JUMP_INSN)
{
- if (branch)
- abort ();
branch = insn;
+ br_count += 1;
}
- if (branch != get_last_insn ())
- abort ();
+ /* If we've got one branch at the end of the sequence,
+ we can try to reverse it. */
- JUMP_LABEL (branch) = if_false_label;
- if (! invert_jump (branch, if_false_label))
+ if (br_count == 1 && NEXT_INSN (branch) == NULL_RTX)
{
- if_true_label = gen_label_rtx ();
- redirect_jump (branch, if_true_label);
- emit_jump (if_false_label);
- emit_label (if_true_label);
+ rtx insn_label;
+ insn_label = XEXP (condjump_label (branch), 0);
+ JUMP_LABEL (branch) = insn_label;
+
+ if (insn_label != if_false_label)
+ abort ();
+
+ if (invert_jump (branch, if_false_label))
+ return;
}
+
+ /* Multiple branches, or reversion failed. Convert to branches
+ around an unconditional jump. */
+
+ if_true_label = gen_label_rtx ();
+ for (insn = first; insn; insn = NEXT_INSN (insn))
+ if (GET_CODE (insn) == JUMP_INSN)
+ {
+ rtx insn_label;
+ insn_label = XEXP (condjump_label (insn), 0);
+ JUMP_LABEL (insn) = insn_label;
+
+ if (insn_label == if_false_label)
+ redirect_jump (insn, if_true_label);
+ }
+ emit_jump (if_false_label);
+ emit_label (if_true_label);
}
}
@@ -11437,8 +11557,8 @@ do_tablejump (index, mode, range, table_label, default_label)
or equal to the minimum value of the range and less than or equal to
the maximum value of the range. */
- emit_cmp_insn (index, range, GTU, NULL_RTX, mode, 1, 0);
- emit_jump_insn (gen_bgtu (default_label));
+ emit_cmp_and_jump_insns (index, range, GTU, NULL_RTX, mode, 1,
+ 0, default_label);
/* If index is in range, it must fit in Pmode.
Convert to Pmode so we can index with it. */
diff --git a/gcc/expr.h b/gcc/expr.h
index e992bd52711..0e8c35d6fd6 100644
--- a/gcc/expr.h
+++ b/gcc/expr.h
@@ -1,5 +1,5 @@
/* Definitions for code generation pass of GNU compiler.
- Copyright (C) 1987, 91-97, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1987, 91-98, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -144,6 +144,17 @@ enum direction {none, upward, downward}; /* Value has this type. */
#define STRICT_ARGUMENT_NAMING 0
#endif
+/* Provide a default value for PRETEND_OUTGOING_VARARGS_NAMED. */
+#ifdef SETUP_INCOMING_VARARGS
+#ifndef PRETEND_OUTGOING_VARARGS_NAMED
+#define PRETEND_OUTGOING_VARARGS_NAMED 1
+#endif
+#else
+/* It is an error to define PRETEND_OUTGOING_VARARGS_NAMED without
+ defining SETUP_INCOMING_VARARGS. */
+#define PRETEND_OUTGOING_VARARGS_NAMED 0
+#endif
+
/* Nonzero if we do not know how to pass TYPE solely in registers.
We cannot do so in the following cases:
@@ -528,7 +539,7 @@ extern int expand_twoval_binop PROTO((optab, rtx, rtx, rtx, rtx, int));
extern rtx expand_unop PROTO((enum machine_mode, optab, rtx, rtx, int));
/* Expand the absolute value operation. */
-extern rtx expand_abs PROTO((enum machine_mode, rtx, rtx, int, int));
+extern rtx expand_abs PROTO((enum machine_mode, rtx, rtx, int));
/* Expand the complex absolute value operation. */
extern rtx expand_complex_abs PROTO((enum machine_mode, rtx, rtx, int));
@@ -554,6 +565,11 @@ extern void emit_0_to_1_insn PROTO((rtx));
extern void emit_cmp_insn PROTO((rtx, rtx, enum rtx_code, rtx,
enum machine_mode, int, int));
+/* Emit a pair of rtl insns to compare two rtx's and to jump
+ to a label if the comparison is true. */
+extern void emit_cmp_and_jump_insns PROTO((rtx, rtx, enum rtx_code, rtx,
+ enum machine_mode, int, int, rtx));
+
/* Nonzero if a compare of mode MODE can be done straightforwardly
(without splitting it into pieces). */
extern int can_compare_p PROTO((enum machine_mode));
@@ -654,6 +670,9 @@ extern rtx protect_from_queue PROTO((rtx, int));
/* Perform all the pending incrementations. */
extern void emit_queue PROTO((void));
+/* Tell if something has a queued subexpression. */
+extern int queued_subexp_p PROTO((rtx));
+
/* Emit some rtl insns to move data between rtx's, converting machine modes.
Both modes must be floating or both fixed. */
extern void convert_move PROTO((rtx, rtx, int));
diff --git a/gcc/extend.texi b/gcc/extend.texi
index 45b31b82322..629cc900ee6 100644
--- a/gcc/extend.texi
+++ b/gcc/extend.texi
@@ -1,4 +1,4 @@
-@c Copyright (C) 1988,89,92,93,94,96 Free Software Foundation, Inc.
+@c Copyright (C) 1988,89,92,93,94,96,99 Free Software Foundation, Inc.
@c This is part of the GCC manual.
@c For copying conditions, see the file gcc.texi.
@@ -33,6 +33,7 @@ C++ Language}, for extensions that apply @emph{only} to C++.
* Conditionals:: Omitting the middle operand of a @samp{?:} expression.
* Long Long:: Double-word integers---@code{long long int}.
* Complex:: Data types for complex numbers.
+* Hex Floats:: Hexadecimal floating-point constants.
* Zero Length:: Zero-length arrays.
* Variable Length:: Arrays whose length is computed at run time.
* Macro Varargs:: Macros with variable number of arguments.
@@ -63,6 +64,7 @@ C++ Language}, for extensions that apply @emph{only} to C++.
* Function Names:: Printable strings which are the name of the current
function.
* Return Address:: Getting the return or frame address of a function.
+* Other Builtins:: Other built-in functions.
@end menu
@end ifset
@ifclear INTERNALS
@@ -78,6 +80,7 @@ C++ Language}, for extensions that apply @emph{only} to C++.
* Conditionals:: Omitting the middle operand of a @samp{?:} expression.
* Long Long:: Double-word integers---@code{long long int}.
* Complex:: Data types for complex numbers.
+* Hex Floats:: Hexadecimal floating-point constants.
* Zero Length:: Zero-length arrays.
* Variable Length:: Arrays whose length is computed at run time.
* Macro Varargs:: Macros with variable number of arguments.
@@ -791,6 +794,24 @@ examine and set these two fictitious variables with your debugger.
A future version of GDB will know how to recognize such pairs and treat
them as a single variable with a complex type.
+@node Hex Floats
+@section Hex Floats
+@cindex hex floats
+GNU CC recognizes floating-point numbers written not only in the usual
+decimal notation, such as @code{1.55e1}, but also numbers such as
+@code{0x1.fp3} written in hexadecimal format. In that format the
+@code{0x} hex introducer and the @code{p} or @code{P} exponent field are
+mandatory. The exponent is a decimal number that indicates the power of
+2 by which the significand part will be multiplied. Thus @code{0x1.f} is
+1 15/16, @code{p3} multiplies it by 8, and the value of @code{0x1.fp3}
+is the same as @code{1.55e1}.
+
+Unlike for floating-point numbers in the decimal notation the exponent
+is always required in the hexadecimal notation. Otherwise the compiler
+would not be able to resolve the ambiguity of, e.g., @code{0x1.f}. This
+could mean @code{1.0f} or @code{1.9375} since @code{f} is also the
+extension for floating-point constants of type @code{float}.
+
@node Zero Length
@section Arrays of Length Zero
@cindex arrays of length zero
@@ -1518,6 +1539,19 @@ mangled name for the target must be used.
Not all target machines support this attribute.
+@item no_check_memory_usage
+@cindex @code{no_check_memory_usage} function attribute
+If @samp{-fcheck-memory-usage} is given, calls to support routines will
+be generated before most memory accesses, to permit support code to
+record usage and detect uses of uninitialized or unallocated storage.
+Since the compiler cannot handle them properly, @code{asm} statements
+are not allowed. Declaring a function with this attribute disables the
+memory checking code for that function, permitting the use of @code{asm}
+statements without requiring separate compilation with different
+options, and allowing you to write support routines of your own if you
+wish, without getting infinite recursion if they get compiled with this
+option.
+
@item regparm (@var{number})
@cindex functions that are passed arguments in registers on the 386
On the Intel 386, the @code{regparm} attribute causes the compiler to
@@ -2224,10 +2258,16 @@ inc (int *a)
(If you are writing a header file to be included in ANSI C programs, write
@code{__inline__} instead of @code{inline}. @xref{Alternate Keywords}.)
-
You can also make all ``simple enough'' functions inline with the option
-@samp{-finline-functions}. Note that certain usages in a function
-definition can make it unsuitable for inline substitution.
+@samp{-finline-functions}.
+
+Note that certain usages in a function definition can make it unsuitable
+for inline substitution. Among these usages are: use of varargs, use of
+alloca, use of variable sized data types (@pxref{Variable Length}),
+use of computed goto (@pxref{Labels as Values}), use of nonlocal goto,
+and nested functions (@pxref{Nested Functions}). Using @samp{-Winline}
+will warn when a function marked @code{inline} could not be substituted,
+and will give the reason for the failure.
Note that in C and Objective C, unlike C++, the @code{inline} keyword
does not affect the linkage of the function.
@@ -2391,6 +2431,14 @@ asm volatile ("movc3 %0,%1,%2"
: "r0", "r1", "r2", "r3", "r4", "r5");
@end example
+It is an error for a clobber description to overlap an input or output
+operand (for example, an operand describing a register class with one
+member, mentioned in the clobber list). Most notably, it is invalid to
+describe that an input operand is modified, but unused as output. It has
+to be specified as an input and output operand anyway. Note that if there
+are only unused output operands, you will then also need to specify
+@code{volatile} for the @code{asm} construct, as described below.
+
If you refer to a particular hardware register from the assembler code,
you will probably have to list the register after the third colon to
tell the compiler the register's value is modified. In some assemblers,
@@ -2787,6 +2835,7 @@ macros to replace them with the customary keywords. It looks like this:
#endif
@end example
+@findex __extension__
@samp{-pedantic} causes warnings for many GNU C extensions. You can
prevent such warnings within one expression by writing
@code{__extension__} before the expression. @code{__extension__} has no
@@ -2863,6 +2912,7 @@ These functions may be used to get information about the callers of a
function.
@table @code
+@findex __builtin_return_address
@item __builtin_return_address (@var{level})
This function returns the return address of the current function, or of
one of its callers. The @var{level} argument is number of frames to
@@ -2879,6 +2929,7 @@ of the stack has been reached, this function will return @code{0}.
This function should only be used with a non-zero argument for debugging
purposes.
+@findex __builtin_frame_address
@item __builtin_frame_address (@var{level})
This function is similar to @code{__builtin_return_address}, but it
returns the address of the function frame rather than the return address
@@ -2899,6 +2950,56 @@ The caveats that apply to @code{__builtin_return_address} apply to this
function as well.
@end table
+@node Other Builtins
+@section Other built-in functions provided by GNU CC
+
+GNU CC provides a large number of built-in functions other than the ones
+mentioned above. Some of these are for internal use in the processing
+of exceptions or variable-length argument lists and will not be
+documented here because they may change from time to time; we do not
+recommend general use of these functions.
+
+The remaining functions are provided for optimization purposes.
+
+GNU CC includes builtin versions of many of the functions in the
+standard C library. These will always be treated as having the same
+meaning as the C library function even if you specify the
+@samp{-fno-builtin} (@pxref{C Dialect Options}) option. These functions
+correspond to the C library functions @code{alloca}, @code{ffs},
+@code{abs}, @code{fabsf}, @code{fabs}, @code{fabsl}, @code{labs},
+@code{memcpy}, @code{memcmp}, @code{strcmp}, @code{strcpy},
+@code{strlen}, @code{sqrtf}, @code{sqrt}, @code{sqrtl}, @code{sinf},
+@code{sin}, @code{sinl}, @code{cosf}, @code{cos}, and @code{cosl}.
+
+@findex __builtin_constant_p
+You can use the builtin function @code{__builtin_constant_p} to
+determine if a value is known to be constant at compile-time and hence
+that GNU CC can perform constant-folding on expressions involving that
+value. The argument of the function is the value to test. The function
+returns the integer 1 if the argument is known to be a compile-time
+constant and 0 if it is not known to be a compile-time constant. A
+return of 0 does not indicate that the value is @emph{not} a constant,
+but merely that GNU CC cannot prove it is a constant with the specified
+value of the @samp{-O} option.
+
+You would typically use this function in an embedded application where
+memory was a critical resource. If you have some complex calculation,
+you may want it to be folded if it involves constants, but need to call
+a function if it does not. For example:
+
+@smallexample
+#define Scale_Value(X) \
+ (__builtin_constant_p (X) ? ((X) * SCALE + OFFSET) : Scale (X))
+@end smallexample
+
+You may use this builtin function in either a macro or an inline
+function. However, if you use it in an inlined function and pass an
+argument of the function as the argument to the builtin, GNU CC will
+never return 1 when you call the inline function with a string constant
+or constructor expression (@pxref{Constructors}) and will not return 1
+when you pass a constant numeric value to the inline function unless you
+specify the @samp{-O} option.
+
@node C++ Extensions
@chapter Extensions to the C++ Language
@cindex extensions, C++ language
@@ -2921,8 +3022,11 @@ Predefined Macros,cpp.info,The C Preprocessor}).
declarations and definitions.
* Template Instantiation:: Methods for ensuring that exactly one copy of
each needed template instantiation is emitted.
+* Bound member functions:: You can extract a function pointer to the
+ method denoted by a @samp{->*} or @samp{.*} expression.
* C++ Signatures:: You can specify abstract types to get subtype
polymorphism independent from inheritance.
+
@end menu
@node Naming Results
@@ -3382,6 +3486,40 @@ be the same in all translation units, or things are likely to break.
more discussion of these pragmas.
@end enumerate
+@node Bound member functions
+@section Extracting the function pointer from a bound pointer to member function
+
+@cindex pmf
+@cindex pointer to member function
+@cindex bound pointer to member function
+
+In C++, pointer to member functions (PMFs) are implemented using a wide
+pointer of sorts to handle all the possible call mechanisms; the PMF
+needs to store information about how to adjust the @samp{this} pointer,
+and if the function pointed to is virtual, where to find the vtable, and
+where in the vtable to look for the member function. If you are using
+PMFs in an inner loop, you should really reconsider that decision. If
+that is not an option, you can extract the pointer to the function that
+would be called for a given object/PMF pair and call it directly inside
+the inner loop, to save a bit of time.
+
+Note that you will still be paying the penalty for the call through a
+function pointer; on most modern architectures, such a call defeats the
+branch prediction features of the CPU. This is also true of normal
+virtual function calls.
+
+The syntax for this extension is
+
+@example
+extern A a;
+extern int (A::*fp)();
+typedef int (*fptr)(A *);
+
+fptr p = (fptr)(a.*fp);
+@end example
+
+You must specify @samp{-Wno-pmf-conversions} to use this extension.
+
@node C++ Signatures
@section Type Abstraction using Signatures
diff --git a/gcc/f/BUGS b/gcc/f/BUGS
index 2f136287080..fb129568739 100644
--- a/gcc/f/BUGS
+++ b/gcc/f/BUGS
@@ -1,54 +1,57 @@
-This file lists known bugs in the GNU Fortran compiler. Copyright (C)
-1995, 1996 Free Software Foundation, Inc. You may copy, distribute,
-and modify it freely as long as you preserve this copyright notice and
-permission notice.
-
-Bugs in GNU Fortran
-*******************
-
- This section identifies bugs that `g77' *users* might run into.
-This includes bugs that are actually in the `gcc' back end (GBE) or in
-`libf2c', because those sets of code are at least somewhat under the
-control of (and necessarily intertwined with) `g77', so it isn't worth
-separating them out.
+*Note:* This file is automatically generated from the files
+`bugs0.texi' and `bugs.texi'. `BUGS' is *not* a source file, although
+it is normally included within source distributions.
+
+ This file lists known bugs in the EGCS-1.2 version of the GNU
+Fortran compiler. Copyright (C) 1995-1999 Free Software Foundation,
+Inc. You may copy, distribute, and modify it freely as long as you
+preserve this copyright notice and permission notice.
+
+Known Bugs In GNU Fortran
+*************************
+
+ This section identifies bugs that `g77' *users* might run into in
+the EGCS-1.2 version of `g77'. This includes bugs that are actually in
+the `gcc' back end (GBE) or in `libf2c', because those sets of code are
+at least somewhat under the control of (and necessarily intertwined
+with) `g77', so it isn't worth separating them out.
+
+ For information on bugs in *other* versions of `g77', see
+`egcs/gcc/f/NEWS'. There, lists of bugs fixed in various versions of
+`g77' can help determine what bugs existed in prior versions.
+
+ *Warning:* The information below is still under development, and
+might not accurately reflect the `g77' code base of which it is a part.
+Efforts are made to keep it somewhat up-to-date, but they are
+particularly concentrated on any version of this information that is
+distributed as part of a *released* `g77'.
+
+ In particular, while this information is intended to apply to the
+EGCS-1.2 version of `g77', only an official *release* of that version
+is expected to contain documentation that is most consistent with the
+`g77' product in that version.
+
+ An online, "live" version of this document (derived directly from
+the mainline, development version of `g77' within `egcs') is available
+via `http://egcs.cygnus.com/onlinedocs/g77_bugs.html'. Follow the
+"Known Bugs" link.
For information on bugs that might afflict people who configure,
-port, build, and install `g77', *Note Problems Installing::.
-
- * `g77' sometimes crashes when compiling code containing the
- construct `CMPLX(0.)' or similar. This is a `gcc' back-end bug.
- It can be worked around using `-fno-emulate-complex', though that
- might trigger other, older bugs. Compiling without optimization
- is another work-around.
+port, build, and install `g77', see "Problems Installing" in
+`egcs/gcc/f/INSTALL'.
- Fixed in `egcs' 1.1.
+ The following information was last updated on 1999-03-15:
- * Automatic arrays aren't working on HP-UX systems, at least in
- HP-UX version 10.20. Writing into them apparently causes
+ * Automatic arrays possibly aren't working on HP-UX systems, at
+ least in HP-UX version 10.20. Writing into them apparently causes
over-writing of statically declared data in the main program.
This probably means the arrays themselves are being
under-allocated, or pointers to them being improperly handled,
e.g. not passed to other procedures as they should be.
- * Some Fortran code has been found to be miscompiled by `g77' built
- on `gcc' version 2.8.1 on m68k-next-nextstep3 configurations when
- using the `-O2' option. Even a C function is known to miscompile
- on that configuration when using the `-O2 -funroll-loops' options.
-
- Fixed in `egcs'.
-
- * A code-generation bug afflicts Intel x86 targets when `-O2' is
- specified compiling, for example, an old version of the `DNRM2'
- routine. The x87 coprocessor stack is being mismanaged in cases
- where assigned `GOTO' and `ASSIGN' are involved.
-
- Fixed in `egcs' version 1.1.
-
- * A compiler crash, or apparently infinite run time, can result when
- compiling complicated expressions involving `COMPLEX' arithmetic
- (especially multiplication).
-
- Fixed in `egcs' version 1.1.
+ * `g77' fails to warn about use of a "live" iterative-DO variable as
+ an implied-DO variable in a `WRITE' or `PRINT' statement (although
+ it does warn about this in a `READ' statement).
* Something about `g77''s straightforward handling of label
references and definitions sometimes prevents the GBE from
@@ -94,10 +97,7 @@ port, build, and install `g77', *Note Problems Installing::.
compiler.)
Note that `g77' does display a warning message to notify the user
- before the compiler appears to hang. *Note Initialization of
- Large Aggregate Areas: Large Initialization, for information on
- how to change the point at which `g77' decides to issue this
- warning.
+ before the compiler appears to hang.
* `g77' doesn't emit variable and array members of common blocks for
use with a debugger (the `-g' command-line option). The code is
@@ -110,9 +110,6 @@ port, build, and install `g77', *Note Problems Installing::.
whereby some rudimentary information on a member is written as a
string that is the member's value as a character string.
- *Note Options for Code Generation Conventions: Code Gen Options,
- for information on the `-fdebug-kludge' option.
-
* When debugging, after starting up the debugger but before being
able to see the source code for the main program unit, the user
must currently set a breakpoint at `MAIN__' (or `MAIN___' or
@@ -144,11 +141,12 @@ port, build, and install `g77', *Note Problems Installing::.
0.6 should solve most or all remaining problems (such as
cross-compiling involving 64-bit machines).
- * Maintainers of gcc report that the back end definitely has "broken"
- support for `COMPLEX' types. Based on their input, it seems many
- of the problems affect only the more-general facilities for gcc's
- `__complex__' type, such as `__complex__ int' (where the real and
- imaginary parts are integers) that GNU Fortran does not use.
+ * Maintainers of `gcc' report that the back end definitely has
+ "broken" support for `COMPLEX' types. Based on their input, it
+ seems many of the problems affect only the more-general facilities
+ for gcc's `__complex__' type, such as `__complex__ int' (where the
+ real and imaginary parts are integers) that GNU Fortran does not
+ use.
Version 0.5.20 of `g77' works around this problem by not using the
back end's support for `COMPLEX'. The new option
@@ -156,16 +154,6 @@ port, build, and install `g77', *Note Problems Installing::.
the same "broken" mechanism as that used by versions of `g77'
prior to 0.5.20.
- * There seem to be some problems with passing constants, and perhaps
- general expressions (other than simple variables/arrays), to
- procedures when compiling on some systems (such as i386) with
- `-fPIC', as in when compiling for ELF targets. The symptom is
- that the assembler complains about invalid opcodes. This bug is
- in the gcc back end, and it apparently occurs only when compiling
- sufficiently complicated functions *without* the `-O' option.
-
- Fixed in `egcs' version 1.1.
-
* `g77' currently inserts needless padding for things like `COMMON
A,IPAD' where `A' is `CHARACTER*1' and `IPAD' is `INTEGER(KIND=1)'
on machines like x86, because the back end insists that `IPAD' be
diff --git a/gcc/f/ChangeLog b/gcc/f/ChangeLog
index 1806bbb4673..6b3f09fb96a 100644
--- a/gcc/f/ChangeLog
+++ b/gcc/f/ChangeLog
@@ -1,3 +1,461 @@
+Sat Mar 27 13:00:43 1999 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * bad.c (_ffebad_message_, ffebad_string_, ffebad_message_,
+ ffebad_bufputs_, ffebad_bufputs_, ffebad_start_, ffebad_string,
+ ffebad_finish): Const-ify a char*.
+
+ * bld.c (ffebld_op_string_, ffebld_op_string): Likewise.
+
+ * bld.h (ffebld_op_string): Likewise.
+
+ * com.c (ffecom_arglist_expr_, ffecom_build_f2c_string_,
+ ffecom_debug_kludge_, ffecom_f2c_make_type_,
+ ffecom_get_appended_identifier_, ffecom_get_identifier_,
+ ffecom_gfrt_args_): Likewise.
+ (ffecom_convert_narrow_, ffecom_convert_widen_): Add prototype.
+ (builtin_function, ffecom_gfrt_name_, ffecom_gfrt_argstring_,
+ ffecom_arglist_expr_, ffecom_build_f2c_string_,
+ ffecom_debug_kludge_, ffecom_f2c_make_type_,
+ ffecom_get_appended_identifier_, ffecom_get_external_identifier_,
+ ffecom_get_identifier_, ffecom_decl_field,
+ ffecom_get_invented_identifier, lang_print_error_function,
+ skip_redundant_dir_prefix, read_name_map, print_containing_files):
+ Const-ify a char*.
+ (savestring): Remove, use `xstrdup' instead.
+
+ * com.h (ffecom_decl_field, ffecom_get_invented_identifier):
+ Const-ify a char*.
+
+ * data.c (ffebld, ffedata_gather_): Make explicitly static.
+
+ * expr.c (ffeexpr_isdigits_, ffeexpr_percent_,
+ ffeexpr_reduced_concatenate_, ffeexpr_nil_real_,
+ ffeexpr_nil_number_, ffeexpr_nil_number_period_,
+ ffeexpr_nil_number_real_, ffeexpr_token_real_,
+ ffeexpr_token_number_, ffeexpr_token_number_period_,
+ ffeexpr_token_number_real_): Const-ify a char*.
+
+ * fini.c (xspaces): Likewise.
+
+ * global.c (ffeglobal_type_string_): Likewise.
+ (ffeglobal_drive): Protoize.
+ (ffeglobal_proc_def_arg): Const-ify a char*.
+
+ * global.h (ffeglobal_drive): Protoize.
+ (ffeglobal_proc_def_arg): Const-ify a char*.
+
+ * implic.c (ffeimplic_none, ffeimplic_peek_symbol_type):
+ Likewise.
+
+ * implic.h (ffeimplic_peek_symbol_type): Likewise.
+
+ * info.c (ffeinfo_basictype_string_, ffeinfo_kind_message_,
+ ffeinfo_kind_string_, ffeinfo_kindtype_string_,
+ ffeinfo_where_string_, ffeinfo_basictype_string,
+ ffeinfo_kind_message, ffeinfo_kind_string,
+ ffeinfo_kindtype_string, ffeinfo_where_string): Likewise.
+
+ * info.h (ffeinfo_basictype_string, ffeinfo_kind_message,
+ ffeinfo_kind_string, ffeinfo_kindtype_string,
+ ffeinfo_where_string): Likewise.
+
+ * intrin.c (_ffeintrin_name_, _ffeintrin_gen_, _ffeintrin_spec_,
+ _ffeintrin_imp_, ffeintrin_check_, ffeintrin_cmp_name_,
+ ffeintrin_fulfill_specific, ffeintrin_init_0,
+ ffeintrin_is_actualarg, ffeintrin_is_intrinsic,
+ ffeintrin_name_generic, ffeintrin_name_implementation,
+ ffeintrin_name_specific): Likewise.
+
+ * intrin.h (ffeintrin_is_intrinsic, ffeintrin_name_generic,
+ ffeintrin_name_implementation, ffeintrin_name_specific): Likewise.
+
+ * lex.c (ffelex_type_string_, ffelex_token_new_character,
+ ffelex_token_new_name, ffelex_token_new_names,
+ ffelex_token_new_number): Likewise.
+
+ * lex.h (ffelex_token_new_character, ffelex_token_new_name,
+ ffelex_token_new_names, ffelex_token_new_number): Likewise.
+
+ * malloc.c (malloc_types_, malloc_pool_new, malloc_new_inpool_,
+ malloc_new_zinpool_): Likewise.
+
+ * malloc.h (malloc_new_inpool_, malloc_new_zinpool_,
+ malloc_pool_new): Likewise.
+
+ * name.c (ffename_space_drive_global, ffename_space_drive_symbol):
+ Protoize.
+
+ * name.h (ffename_space_drive_global, ffename_space_drive_symbol):
+ Likewise.
+
+ * symbol.c (ffesymbol_state_name_, ffesymbol_attr_name_,
+ ffesymbol_attrs_string): Const-ify a char*.
+ (ffesymbol_drive, ffesymbol_drive_sfnames): Protoize.
+ (ffesymbol_state_string): Const-ify a char*.
+
+ * symbol.h (ffesymbol_attrs_string): Likewise.
+ (ffesymbol_drive, ffesymbol_drive_sfnames): Protoize.
+ (ffesymbol_state_string): Const-ify a char*.
+
+ * target.c (ffetarget_layout): Likewise.
+
+ * target.h (ffetarget_layout): Likewise.
+
+1999-03-25 Zack Weinberg <zack@rabi.columbia.edu>
+
+ * Make-lang.in: Remove all references to g77.o/g77.c.
+ Link g77 from gcc.o.
+
+1999-03-21 Manfred Hollstein <manfred@s-direktnet.de>
+
+ * Makefile.in (g77$(exeext)): Depend on intl.o. Link in intl.o.
+
+Wed Mar 17 11:39:44 1999 Craig Burley <craig@jcb-sc.com>
+
+ * news.texi: Editorial fix.
+
+Mon Mar 15 17:12:07 1999 Craig Burley <craig@jcb-sc.com>
+
+ * bugs.texi, g77.texi, news.texi: Editorial fixes.
+
+Sat Mar 13 17:51:55 1999 Craig Burley <craig@jcb-sc.com>
+
+ Fix 19990313-0.f, 19990313-1.f, 19990313-2.f, 19990313-3.f:
+ * bad.def (FFEBAD_NOCANDO): New error code for internal use only.
+ * expr.c (ffeexpr_collapse_convert): If FFEBAD_NOCANDO returned
+ by convertor, just return original expr.
+ * target.h: Return FFEBAD_NOCANDO for (usually) 64-bit
+ conversions that aren't yet working properly.
+ * news.texi: Explain.
+
+ * version.c: Bump version.
+
+Sat Mar 13 14:26:55 1999 Craig Burley <craig@jcb-sc.com>
+
+ * RELEASE-PREP: New file, lists things to do for a release.
+
+ * Make-lang.in, bugs.texi, bugs0.texi, g77.texi, g77install.texi,
+ install0.texi, news.texi, news0.texi: Accommodate new doc
+ architecture.
+ Consolidate news items. Don't describe old news items in
+ various generated docs.
+ Don't describe FSF-g77 installation stuff in various EGCS-g77
+ generated docs.
+ Move description of AUTOMATIC to more suitable location.
+ * root.texi: New file for new doc architecture.
+
+Thu Mar 11 17:32:55 1999 Craig Burley <craig@jcb-sc.com>
+
+ * g77.texi: Add AUTOMATIC to list of unsupported extensions.
+
+Sat Mar 6 02:28:35 1999 Craig Burley <craig@jcb-sc.com>
+
+ Warn about non-Y2K-compliant intrinsics:
+ * bad.def (FFEBAD_INTRINSIC_Y2KBAD): New diagnostic.
+ * intrin.def (FFEINTRIN_impDATE, FFEINTRIN_impIDATE_vxt):
+ Use new DEFIMPY macro to flag these as non-Y2K-compliant.
+ * intdoc.c (DEFIMPY): Support new Y2K macro.
+ * intrin.h (DEFIMPY): Ditto.
+ * intrin.c (DEFIMPY): Ditto.
+ (ffeintrin_fulfill_generic, ffeintrin_fulfill_specific):
+ Warn about invocation of non-Y2K-compliant intrinsic.
+ * com-rt.def (FFECOM_gfrtDATE, FFECOM_gfrtVXTIDATE):
+ Rename external procedure names, to keep previously-
+ compiled (sans-new-warnings) code from linking to
+ new library.
+ * g77.texi: Document all this stuff.
+ * news.texi: Spread the joy.
+ * version.c: Bump version.
+
+Fri Mar 5 13:22:44 1999 Craig Burley <craig@jcb-sc.com>
+
+ * news.texi: Relocate IDATE (VXT) fix: we put it in 1.1.2
+ so describe it there, instead of under 1.2.
+
+Wed Mar 3 00:57:56 1999 Craig Burley <craig@jcb-sc.com>
+
+ * news.texi: IDATE (VXT) fixed to return year as 0..99.
+
+Wed Mar 3 00:43:49 1999 Craig Burley <craig@jcb-sc.com>
+
+ * g77.texi: Add remaining changes pending from Dave Love.
+
+Wed Mar 3 00:38:42 1999 Craig Burley <craig@jcb-sc.com>
+
+ * bugs.texi, news.texi: Conditionalize cross-references
+ on non-html processing, providing temporary HTML "links".
+
+ * g77.texi: Fix up a reference.
+
+Wed Mar 3 00:12:31 1999 Craig Burley <craig@jcb-sc.com>
+
+ * news.texi, bugs.texi: Delete fixed bugs, make one
+ of them into the appropriate news item.
+
+Wed Mar 3 00:05:52 1999 Craig Burley <craig@jcb-sc.com>
+
+ * news.texi: Copy over 1.1.2 news.
+
+1999-03-02 Craig Burley <craig@jcb-sc.com>
+
+ * g77.texi (Bug Reporting): Clarify whether to use -E.
+ Clarify other instructions.
+
+1999-02-27 Craig Burley <craig@jcb-sc.com>
+
+ * lang-specs.h: Fix specs to pass `-ax' as well as `-a' option.
+
+1999-02-26 Craig Burley <craig@jcb-sc.com>
+
+ * intdoc.in (STAT_func, STAT_subr,
+ FSTAT_func, FSTAT_subr, LSTAT_func, LSTAT_subr):
+ Properly order array elements. Specify N/A return values.
+
+1999-02-26 Craig Burley <craig@jcb-sc.com>
+
+ * intdoc.in (DATE_AND_TIME): Explain that VALUES(7) holds
+ seconds, and VALUES(8), therefore, milliseconds.
+
+1999-02-26 Craig Burley <craig@jcb-sc.com>
+
+ * news.texi: Clarify IOSTAT= fix.
+
+1999-02-25 Richard Henderson <rth@cygnus.com>
+
+ * lang-specs.h: Define __FAST_MATH__ when appropriate.
+
+1999-02-25 Craig Burley <craig@jcb-sc.com>
+
+ * g77.texi: Clarify/index lack of run-time allocation for
+ concatenation.
+
+1999-02-25 Andreas Jaeger <aj@arthur.rhein-neckar.de>
+
+ * f/intdoc.in: Add missing `,' after cross references.
+
+1999-02-20 Craig Burley <craig@jcb-sc.com>
+
+ * Make-lang.in (f77.install-common, f77.install-info,
+ f77.install-man, f77.uninstall): Use `$(prefix)/lang-f77'
+ instead of `lang-f77' for flag file, to be sure of a
+ writable directory, and remove the flag file after each
+ operation to keep things clean.
+
+1999-02-20 Craig Burley <craig@jcb-sc.com>
+
+ * g77.texi: Properly attribute Priest document; clarify
+ that it is in the .ps version of the Goldberg document.
+
+1999-02-19 Craig Burley <craig@jcb-sc.com>
+
+ * bugs0.texi, bugs.texi, install0.texi, g77install.texi,
+ news0.texi, news.texi: Update copyright dates.
+ Clarify which files are source, which are derived,
+ and remind maintainers where copyright dates are sourced.
+ * BUGS, INSTALL, NEWS: Regenerated.
+
+1999-02-19 Craig Burley <craig@jcb-sc.com>
+
+ * global.c (ffeglobal_ref_progunit_): Warn about a function
+ definition that disagrees with the type of a previous reference.
+ Improve commentary. Fix a couple of minor bugs. Clean up
+ some code.
+ * news.texi: Spread the joy.
+
+1999-02-18 Craig Burley <craig@jcb-sc.com>
+
+ * expr.c (ffeexpr_finished_): Disallow non-default INTEGER
+ as argument for FILEINT and FILEASSOC as lhs.
+ * news.texi: Document fix.
+ * version.c: Bump.
+
+1999-02-18 Craig Burley <craig@jcb-sc.com>
+
+ * g77.texi: Clarify -fno-globals vs. -Wno-globals.
+
+1999-02-18 Craig Burley <craig@jcb-sc.com>
+
+ * intdoc.in (LOG10): Fix typo.
+
+1999-02-17 Ulrich Drepper <drepper@cygnus.com>
+
+ * intdoc.in: Fix typo.
+
+1999-02-17 Craig Burley <craig@jcb-sc.com>
+
+ * g77.texi, intdoc.in: Document Y2K and some other known
+ limitations.
+ * intrin.def (DTIME, FDATE): Fix capitalization of
+ case-sensitive forms of these intrinsics' names.
+
+1999-02-17 Dave Love <fx@gnu.org>
+
+ * intdoc.in: Say `common' logarithm for log10.
+
+1999-02-16 Ulrich Drepper <drepper@cygnus.com>
+
+ * g77.texi: Add missing @ in email addresses.
+
+1999-02-15 Craig Burley <craig@jcb-sc.com>
+
+ * *.*: Delete my (old) email address in most places, change it
+ in a few.
+
+1999-02-14 Craig Burley <craig@jcb-sc.com>
+
+ * version.c: Bump.
+
+1999-02-14 Craig Burley <craig@jcb-sc.com>
+
+ * version.c: Bump for 1998-10-02 change (forgot to do this
+ before).
+
+1999-02-14 Craig Burley <craig@jcb-sc.com>
+
+ * lang-specs.h, g77.1, g77.texi, news.texi: Recognize `.FOR'
+ and `.FPP' as well as `.for' and `.fpp'.
+
+1999-02-14 Craig Burley <craig@jcb-sc.com>
+
+ * intdoc.in (LOG10): Fix description.
+
+1999-02-14 Craig Burley <craig@jcb-sc.com>
+
+ * news.texi: Mention fix for SIGNAL invocation circa egcs-1.1.
+
+1999-02-14 Craig Burley <craig@jcb-sc.com>
+
+ * g77.texi, g77install.texi, bugs.texi, g77install.texi: Clean
+ up and improve indexing, and some other areas of docs.
+
+1999-02-14 Craig Burley <craig@jcb-sc.com>
+
+ * intdoc.in (MCLOCK8, TIME8): Warn about lower range on
+ 32-bit systems.
+
+Sat Feb 6 18:02:17 1999 Jeffrey A Law (law@cygnus.com)
+
+ * g77.texi: Update email addresses.
+
+Wed Feb 3 22:50:17 1999 Marc Espie <Marc.Espie@liafa.jussieu.fr>
+
+ * Make-lang.in (g77$(exeext)): Get choose-temp.o, pexecute.o and
+ mkstemp.o from libiberty.
+
+1999-02-01 Zack Weinberg <zack@rabi.columbia.edu>
+
+ * top.c: Don't define ffe_is_ident_. Don't process
+ -f(no-)ident here.
+ * top.h: Remove declaration of ffe_is_ident_ and macros
+ ffe_is_ident() and ffe_set_is_ident().
+ * lex.c: Use flag_no_ident instead of ffe_is_ident().
+
+Sun Jan 31 20:34:29 1999 Zack Weinberg <zack@rabi.columbia.edu>
+
+ * lang-specs.h: Map -Qn to -fno-ident.
+
+Tue Jan 5 22:12:41 1999 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * Make-lang.in (g77.o): Depend on prefix.h.
+
+Fri Nov 27 13:10:32 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * fini.c: Rename variable `spaces' to `xspaces' to avoid
+ conflicting with function `spaces' from libiberty.
+
+ * g77spec.c: Don't prototype libiberty functions.
+ * malloc.c: Likewise.
+
+1998-11-20 Dave Love <d.love@dl.ac.uk>
+
+ * g77.texi: Assorted minor changes.
+
+1998-11-19 Dave Love <d.love@dl.ac.uk>
+
+ * bugs.texi: Formatting changes from Craig.
+
+ * intdoc.in: Terminate some @xrefs with `,'.
+
+1998-11-19 Manfred Hollstein <manfred@s-direktnet.de>
+
+ * Make-lang.in (mandir): Replace all uses of $(mandir) by $(man1dir).
+
+Mon Nov 9 23:15:39 1998 Jeffrey A Law (law@cygnus.com)
+
+ * g77.texi, news.texi: Updates from Craig.
+
+Sun Nov 8 17:47:56 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * Makefile.in (INCLUDES): Add "-I$(srcdir)/../../include".
+
+Sat Nov 7 15:58:54 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * g77spec.c: Don't include gansidecl.h.
+ * output.j: Likewise.
+
+1998-11-04 Dave Love <d.love@dl.ac.uk>
+
+ * g77.texi: Small formatting/indexing fixes.
+
+Mon Oct 12 20:41:59 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * bad.c (ffebad_finish): Change type of variable `c' to unsigned
+ char, change type of variable `s' to unsigned char *.
+
+ * com.c (ffecom_symbol_null_): Add missing initializers.
+
+ * fini.c (MAXNAMELEN): Undef it before defining.
+
+ * implic.c (ffeimplic_lookup_): Change type of parameter `c' to
+ unsigned char.
+
+ * intrin.c (ffeintrin_init_0): Cast the argument of ctype macros
+ to (unsigned char).
+
+ * lex.c (ffelex_splice_tokens): Change type of variable `p' to
+ unsigned char *.
+ (ffelex_token_name_from_names): Cast the argument of
+ `ffelex_is_firstnamechar' to (unsigned char).
+ (ffelex_token_names_from_names): Likewise.
+ (ffelex_token_new_name): Likewise.
+ (ffelex_token_new_names): Likewise.
+
+ * malloc.c (malloc_root_): Add missing initializer.
+
+ * stb.c (ffestb_do): Change type of variable `p' to unsigned char *.
+ (ffestb_else) Likewise.
+ (ffestb_else3_) Likewise.
+ (ffestb_endxyz) Likewise.
+ (ffestb_goto) Likewise.
+ (ffestb_let) Likewise.
+ (ffestb_varlist) Likewise.
+ (ffestb_R522) Likewise.
+ (ffestb_R528) Likewise.
+ (ffestb_R834) Likewise.
+ (ffestb_R835) Likewise.
+ (ffestb_R838) Likewise.
+ (ffestb_R1102) Likewise.
+ (ffestb_blockdata) Likewise.
+ (ffestb_R1212) Likewise.
+ (ffestb_R810) Likewise.
+ (ffestb_R10014_): Cast the argument of `ffelex_is_firstnamechar'
+ to (unsigned char).
+ (ffestb_V014): Change type of variable `p' to unsigned char *.
+ (ffestb_dummy) Likewise.
+ (ffestb_R524) Likewise.
+ (ffestb_R547) Likewise.
+ (ffestb_decl_chartype) Likewise.
+ (ffestb_decl_dbltype) Likewise.
+ (ffestb_decl_gentype) Likewise.
+ (ffestb_decl_entsp_2_) Likewise.
+ (ffestb_V027) Likewise.
+ (ffestb_decl_R539) Likewise.
+
+ * top.c (ffe_decode_option): Mark parameter `argc' with
+ ATTRIBUTE_UNUSED.
+
+ * where.c (ffewhere_unknown_line_): Add missing initializers.
+
1998-10-02 Dave Love <d.love@dl.ac.uk>
* com.c (ffecom_expr_intrinsic_): Fix return type for RAND.
@@ -237,4805 +695,8 @@ Wed Jul 1 11:19:13 1998 Craig Burley <burley@gnu.org>
* target.c (ffetarget_align): Make sure alignments
are non-zero, just in case.
-Mon Jun 29 09:47:33 1998 Craig Burley <burley@gnu.org>
-
- Fix 980628-*.f:
- * bld.h: New `pad' field and accessor macros for
- ACCTER, ARRTER, and CONTER ops.
- * bld.c (ffebld_new_accter, ffebld_new_arrter,
- ffebld_new_conter_with_orig): Initialize `pad' field
- to zero.
- * com.c (ffecom_transform_common_): Include initial
- padding (aka modulo aka offset) in size calculation.
- Copy initial padding value into FFE initialization expression
- so the GBE transformation of that expression includes it.
- Make array low bound 0 instead of 1, for consistency.
- (ffecom_transform_equiv_): Include initial
- padding (aka modulo aka offset) in size calculation.
- Copy initial padding value into FFE initialization expression
- so the GBE transformation of that expression includes it.
- Make array low bound 0 instead of 1, for consistency.
- (ffecom_expr_, case FFEBLD_opACCTER): Delete unused `size'
- variable.
- Track destination offset separately, allowing for
- initial padding.
- Don't bother setting initial PURPOSE offset if zero.
- Include initial padding in size calculation.
- (ffecom_expr_, case FFEBLD_opARRTER): Allow for
- initial padding.
- Include initial padding in size calculation.
- Make array low bound 0 instead of 1, for consistency.
- (ffecom_finish_global_): Make array low bound 0 instead
- of 1, for consistency.
- (ffecom_notify_init_storage): Copy `pad' field from old
- ACCTER to new ARRTER.
- (ffecom_notify_init_symbol): Ditto.
- * data.c (ffedata_gather_): Initialize `pad' field in new
- ARRTER to 0.
- (ffedata_value_): Ditto.
- * equiv.c (ffeequiv_layout_local_): When lowering start
- of equiv area, extend lowering to maintain needed alignment.
- * target.c (ffetarget_align): Handle negative offset correctly.
-
- * global.c (ffeglobal_pad_common): Warn about non-zero
- padding only the first time its seen.
- If new padding larger than old, update old.
- (ffeglobal_save_common): Use correct type for size throughout.
- * global.h: Use correct type for size throughout.
- (ffeglobal_common_pad): New macro.
- (ffeglobal_pad): Delete this unused and broken macro.
-
-Sat Jun 27 12:18:33 1998 Jeffrey A Law (law@cygnus.com)
-
- * Make-lang.in (g77): Depend on mkstemp.o. Link in mkstemp.o.
-
-Fri Jun 26 11:54:19 1998 Craig Burley <burley@gnu.org>
-
- * g77spec.c (lang_specific_driver): Put `-lg2c' in
- front of any `-lm' that is seen.
-
-Wed Jun 24 01:01:23 1998 Jeffrey A Law (law@cygnus.com)
-
- * g77spec.c (lang_specific_driver): Revert last change.
-
-Mon Jun 22 23:12:05 1998 H.J. Lu (hjl@gnu.org)
-
- * Make-lang.in (G77STAGESTUFF): Add g77.c.
-
-Fri Jun 19 07:54:40 1998 H.J. Lu (hjl@gnu.org)
-
- * g77spec.c (lang_specific_driver): Check n_infiles before
- appending args.
-
-Mon Jun 15 23:39:24 1998 Craig Burley <burley@gnu.org>
-
- * Make-lang.in (f/g77.info): Use -f when removing
- pre-existing Info files, if any. (This rm command
- can go away once makeinfo has been changed to delete
- .info-N files beyond the last one it creates.)
-
- * Make-lang.in ($(srcdir)/f/intdoc.texi): Compile
- using $(INCLUDES) macro to get the new hconfig.h
- and system.h headers.
-
-Mon Jun 15 22:21:57 1998 Craig Burley <burley@gnu.org>
-
- Cutover to system.h:
- * Make-lang.in:
- * Makefile.in:
- * ansify.c:
- * bad.c:
- * bld.c:
- * com.c:
- * com.h:
- * expr.c:
- * fini.c:
- * g77spec.c:
- * implic.c:
- * intdoc.c:
- * intrin.c:
- * lex.c:
- * lex.h:
- * parse.c:
- * proj.c:
- * proj.h:
- * src.c:
- * src.h:
- * stb.c:
- * ste.c:
- * target.c:
- * top.c:
- * system.j: New file.
-
- Use toplev.h where appropriate:
- * Make-lang.in:
- * Makefile.in:
- * bad.c:
- * bld.c:
- * com.c:
- * lex.c:
- * ste.c:
- * top.c:
- * toplev.j: New file.
-
- Conditionalize all dumping/reporting routines so they don't
- get built for gcc/egcs:
- * bld.c:
- * bld.h:
- * com.c:
- * equiv.c:
- * equiv.h:
- * sta.c:
- * stt.c:
- * stt.h:
- * symbol.c:
- * symbol.h:
-
- Use hconfig.h instead of config.h where appropriate:
- * Makefile.in (proj-h.o): Compile with -DUSE_HCONFIG.
- * fini.c: Define USE_HCONFIG before including proj.h.
-
- * Makefile.in (deps-kinda): Redirect stderr to stdout,
- to eliminate diagnostics vis-a-vis g77spec.c.
-
- * Makefile.in: Regenerate dependencies via deps-kinda.
-
- * lex.c (ffelex_file_fixed, ffelex_file_free): Eliminate
- apparently spurious warnings about uninitialized variables
- `c', `column', and so on.
-
-Sat Jun 13 03:13:18 1998 Craig Burley <burley@gnu.org>
-
- * g77spec.c (lang_specific_driver): Print out egcs
- version info first, to be compatible with what some
- test facilities expect.
-
-Wed Jun 10 13:17:32 1998 Dave Brolley <brolley@cygnus.com>
-
- * top.h (ffe_decode_option): New argc/argv interface.
- * top.c (ffe_decode_option): New argc/argv interface.
- * parse.c (yyparse): New argc/argv interface for ffe_decode_option.
- * com.c (lang_decode_option): New argc/argv interface.
-
-Sun Jun 7 14:04:34 1998 Richard Henderson <rth@cygnus.com>
-
- * com.c (lang_init_options): New function.
- * top.c (ffe_decode_option): Remove all trace of -fset-g77-defaults.
- Set ffe_is_do_internal_checks_ with -version.
- * lang-options.h: Likewise.
- * lang-specs.h: Likewise.
-
-Fri Jun 5 15:53:17 1998 Per Bothner <bothner@cygnus.com>
-
- * g77spec.c (lang_specific_pre_link, lang_specific_extra_ofiles):
- Define - update needed by gcc.c change.
-
-Mon Jun 1 19:37:42 1998 Craig Burley <burley@gnu.org>
-
- * com.c (ffecom_init_0): Fix setup of INTEGER(KIND=7)
- pointer type.
- * info.c (ffeinfo_type): Don't crash on null type.
- * expr.c (ffeexpr_fulfill_call_): Don't special-case
- %LOC(expr) or LOC(expr).
- Delete FFEGLOBAL_argsummaryPTR.
- * global.c, global.h: Delete FFEGLOBAL_argsummaryPTR.
-
-Thu May 28 21:32:18 1998 Craig Burley <burley@gnu.org>
-
- Restore circa-0.5.22 capabilities of `g77' driver:
- * Make-lang.in (g77spec.o): Depend on f/version.h.
- (g77version.o): New rule to compile g77 version info.
- (g77$(exeext)): Depend on and link in g77version.o.
- * g77spec.c: Rewrite to be more like 0.5.22 version
- of g77.c, making filtering of command line smarter
- so mixed Fortran and C (etc.) can be compiled, verbose
- version info can be obtained, etc.
- * lang-specs.h (f77-version): New "language" to support
- "g77 -v" command under new gcc 2.8 regime.
- * lex.c (ffelex_file_fixed): If -fnull-version, just
- substitute a "source file" that prints out version info.
- * top.c, top.h: Support -fnull-version.
-
- * lang-specs.h: Use "%O" instead of OO macro to specify
- object extension. Remove old stringizing cruft.
-
- * Make-lang.in (g77.c, g77spec.o, g77.o, g77$(exeext),
- g77-cross$(exeext), f771,
- $(srcdir)/f/g77.info, $(srcdir)/f/g77.dvi,
- $(srcdir)/f/intdoc.texi,
- f77.install-common, f77.install-info, f77.install-man,
- f77.uninstall, $(G77STAGESTUFF), f77.stage1, f77.stage2,
- f77.stage3, f77.stage4, f77.distdir): Don't do anything
- unless user specified "f77" or "F77" in $LANGUAGES either
- during configuration or explicitly. For convenience of
- various tests and to work around lack of the assignment
- "LANGUAGES=$(BOOT_LANGUAGES)" in the "make stage1" command
- of "make bootstrap" in gcc, use a touch file named "lang-f77"
- to communicate whether this is the case.
-
- * Make-lang.in (F77_FLAGS_TO_PASS): Delete this macro,
- replace with minimal expansion of its former self in
- each of the two instances where it was used.
-
- * Makefile.in (HOST_CC): Delete this definition.
-
- * com.c (index, rindex): Delete these declarations.
-
- * proj.h: (isascii): Delete this.
-
- * Make-lang.in (f77.install-common): Warn if `f77-install-ok'
- flag-file exists, since it no longer triggers any activity.
-
- Rename libf2c.a and f2c.h to libg2c.a and g2c.h,
- normalize and simplify g77/libg2c build process:
- * Make-lang.in: Remove all support for overwriting
- /usr/bin/f77 etc., or whatever the actual names are
- via $(prefix) and $(local_prefix). (g++ overwrites
- /usr/bin/c++, but then it's often the only C++ compiler
- on the system; f77 often exists on systems that are
- installing g77.)
- (f77.realclean): Remove obsolete target.
- (g77.c, g77$(exeext)): Minor changes to look more like g++'s
- stuff.
- (f771): Now built with srcdir=gcc/f, not srcdir=gcc, to be
- more like g++ and such.
- (f/Makefile): Removed, as g++ doesn't need this rule.
- (f77.install-common): No longer install f77, etc.
- (f77.install-man): No longer install f77.1.
- (f77.uninstall): No longer uninstall f77, f77.1, etc.
- (f77.stage1, f77.stage2, f77.stage3, f77.stage4): Do work
- only if "f77" appears in $(LANGUAGES).
- (Note: gcc's Makefile.in's bootstrap target should set
- LANGUAGES=$(BOOT_LANGUAGES) when making the stage1 target.)
- * Makefile.in: Update vis-a-vis gcc/cp/Makefile.in.
- (none): Remove.
- (g77-only): Relocate.
- (all.indirect, f771, *.o): Now assumes current directory
- is this dir (gcc/f), not the parent directory.
- (TAGS): Remove "echo 'parse.y,0' >> TAGS ;" line.
- * config-lang.in: Delete commented-out code.
- Fix stagestuff definition. Add more stuff to
- diff_excludes definition. Don't create any directories.
- Set outputs to f/Makefile, to get variable substition
- to happen (what does that really do, anyway?!).
- * g77spec.c: Rename libf2c to libg2c.
-
- * com.h: Remove all of the gcc back-end decls,
- since egcs should have all of them correct.
-
- * com.c: Include "proj.h" before anything else,
- as that's how things are supposed to work.
- * ste.c: Ditto.
-
- * bad.c: Include "flags.j" here, since some diagnostics
- check flag_pedantic_errors.
-
- * Makefile.in (f/*.o): Rebuild dependencies via
- deps-kinda.
-
- * output.j: New source file.
- * Make-lang.in (F77_SRCS): Update accordingly.
- * Makefile.in (OUTPUT_H): Ditto.
- (deps-kinda): Ditto.
- * com.c: Include "output.j" here.
- * lex.c: Ditto.
-
-Mon May 25 03:34:42 1998 Craig Burley <burley@gnu.org>
-
- * com.c (ffecom_expr_): Fix D**I and Z**I cases to
- not convert (DOUBLE PRECISION) D and (DOUBLE COMPLEX) Z
- to INTEGER. (This is dead code here anyway.)
-
-Sat May 23 06:32:52 1998 Craig Burley <burley@gnu.org>
-
- * com.c (ffecom_finish_symbol_transform_): Don't transform
- statement (nested) functions, to avoid gcc compiling them
- and thus producing linker errors if they refer to undefined
- external functions. But warn if they're unused and -Wunused.
- * bad.def (FFEBAD_SFUNC_UNUSED): New diagnostic.
-
-Wed May 20 12:12:55 1998 Craig Burley <burley@gnu.org>
-
- * Version 0.5.23 released.
-
-Tue May 19 14:52:41 1998 Craig Burley <burley@gnu.org>
-
- * bad.def (FFEBAD_OPEN_UNSUPPORTED, FFEBAD_INQUIRE_UNSUPPORTED,
- FFEBAD_READ_UNSUPPORTED, FFEBAD_WRITE_UNSUPPORTED,
- FFEBAD_QUAD_UNSUPPORTED, FFEBAD_BLOCKDATA_STMT,
- FFEBAD_TRUNCATING_CHARACTER, FFEBAD_TRUNCATING_HOLLERITH,
- FFEBAD_TRUNCATING_NUMERIC, FFEBAD_TRUNCATING_TYPELESS,
- FFEBAD_TYPELESS_OVERFLOW): Change these from warnings
- to errors.
-
-Tue May 19 14:51:59 1998 Craig Burley <burley@gnu.org>
-
- * Make-lang.in (f77.install-info, f77.uninstall):
- Use install-info as appropriate.
-
-Tue May 19 12:56:54 1998 Craig Burley <burley@gnu.org>
-
- * com.c (ffecom_init_0): Rename xargc to f__xargc,
- in accord with same-dated change to f/runtime.
-
-Fri May 15 10:52:49 1998 Craig Burley <burley@gnu.org>
-
- * com.c (ffecom_convert_narrow_, ffecom_convert_widen_):
- Be even more persnickety in checking for internal bugs.
- Also, if precision isn't changing, just return the expr.
-
- * expr.c (ffeexpr_token_number_): Call
- ffeexpr_make_float_const_ to make an integer.
- (ffeexpr_make_float_const_): Handle making an integer.
-
- * intrin.c (ffeintrin_init_0): Distinguish between
- crashes on bad arg base and kind types.
-
-Fri May 15 01:44:22 1998 Mumit Khan <khan@xraylith.wisc.edu>
-
- * Make-lang.in (f77.mostlyclean): Add missing exeext.
-
-Thu May 14 13:30:59 1998 Craig Burley <burley@gnu.org>
-
- * Make-lang.in (f/expr.c): Now depends on f/stamp-str.
- * expr.c: Use ffestrOther in place of ffeexprDotdot_.
- * str-ot.fin: Add more keywords for expr.c.
-
- * intdoc.c (dumpimp): Trivial fix.
-
- * com.c (ffecom_expr_): Add ltkt variable for clarity.
-
-Wed May 13 13:05:34 1998 Craig Burley <burley@gnu.org>
-
- * Make-lang.in (G77STAGESTUFF): Add g77.o, g77spec.o,
- and g77version.o.
- (f77.clean): Add removal of g77.c, g77.o, g77spec.o,
- and g77version.o.
- (f77.distclean): Delete removal of g77.c.
-
-Thu Apr 30 18:59:43 1998 Jim Wilson <wilson@cygnus.com>
-
- * Make-lang.in (g77.info, g77.dvi, BUGS, INSTALL, NEWS): Put -o
- option before input file.
-
-Tue Apr 28 09:23:10 1998 Craig Burley <burley@gnu.org>
-
- Fix 980427-0.f:
- * global.c (ffeglobal_ref_progunit_): When transitioning
- from EXT to FUNC, discard hook, since the decl, if any, is
- probably wrong.
-
-Sun Apr 26 09:05:50 1998 Craig Burley <burley@gnu.org>
-
- * com.c (ffecom_char_enhance_arg_): Wrap the upper bound
- (the PARM_DECL specifying the length of the CHARACTER*(*)
- dummy arg) in a variable_size invocation, to prevent
- dwarf2out.c crashing when compiling code with -g.
-
-Sat Apr 18 15:26:57 1998 Jim Wilson <wilson@cygnus.com>
-
- * g77spec.c (lang_specific_driver): New argument in_added_libraries.
- New local added_libraries. Increment count when add library to
- arglist.
-
-Sat Apr 18 05:03:21 1998 Craig Burley <burley@gnu.org>
-
- * com.c (ffecom_check_size_overflow_): Ignore overflow
- as well if dummy argument.
-
-Fri Apr 17 17:18:04 1998 Craig Burley <burley@gnu.org>
-
- * version.h: Get rid of the overly large headers
- here too, as done in version.c.
-
-Tue Apr 14 15:51:37 1998 Dave Brolley <brolley@cygnus.com>
-
- * com.c (init_parse): Now returns char* containing filename;
-
-Tue Apr 14 14:40:40 1998 Craig Burley <burley@gnu.org>
-
- * com.c (ffecom_start_progunit_): Mark function decl
- as used, to avoid spurious warning (-Wunused) for ENTRY.
-
-Tue Apr 14 14:19:34 1998 Craig Burley <burley@gnu.org>
-
- * sta.c (ffesta_second_): Check for CASE DEFAULT
- as well as CASE, or it won't be recognized.
-
-Thu Apr 9 00:18:44 1998 Dave Brolley (brolley@cygnus.com)
-
- * com.c (finput): New variable.
- (init_parse): Handle !USE_CPPLIB.
- (finish_parse): New function.
- (lang_init): No longer declare finput.
-
-Sat Apr 4 17:45:01 1998 Richard Henderson <rth@cygnus.com>
-
- * com.c (ffecom_expr_): Revert Oct 22 change. Instead take a WIDENP
- argument so that we can respect the signedness of the original type.
- (ffecom_init_0): Do sizetype initialization first.
-
-1998-03-28 Dave Love <d.love@dl.ac.uk>
-
- * Make-lang.in (f771$(exeext)): Fix typo.
-
-1998-03-24 Martin von Loewis <loewis@informatik.hu-berlin.de>
-
- * com.c (lang_print_xnode): New function.
-
-Mon Mar 23 21:20:35 1998 Craig Burley <burley@gnu.org>
-
- * version.c: Reduce to a one-line file, like
- gcc's version.c, since there's really no content
- there.
-
-Mon Mar 23 11:58:43 1998 Craig Burley <burley@gnu.org>
-
- * bugs.texi: Various updates.
-
- * com.c (ffecom_tree_canonize_ptr_): Fix up spacing a bit.
-
-Sun Mar 22 00:50:42 1998 Nick Clifton <nickc@cygnus.com>
- Geoff Noer <noer@cygnus.com>
-
- * Makefile.in: Various fixes for building cygwin32 native toolchains.
- * Make-lang.in: Likewise.
-
-Mon Mar 16 21:20:35 1998 Craig Burley <burley@gnu.org>
-
- * expr.c (ffeexpr_sym_impdoitem_): Don't blindly
- reset symbol info after calling ffesymbol_error,
- to avoid crash.
-
-Mon Mar 16 15:38:50 1998 Craig Burley <burley@gnu.org>
-
- * Version 0.5.22 released.
-
-Mon Mar 16 14:36:02 1998 Craig Burley <burley@gnu.org>
-
- Make -g work better for ENTRY:
- * com.c (ffecom_start_progunit_): Master function
- for ENTRY-laden procedure is not really invented,
- so it can be debugged.
- (ffecom_do_entry_): Push/set/pop lineno for each
- entry point.
-
-Sun Mar 15 05:48:49 1998 Craig Burley <burley@gnu.org>
-
- * intrin.def: Fix spelling of mixed-case form
- of `CPU_Time' (was `Cpu_Time').
-
-Thu Mar 12 13:50:21 1998 Craig Burley <burley@gnu.org>
-
- * lang-options.h: Sort all -f*-intrinsics-* options,
- for consistency with other g77 versions.
-
-Thu Mar 12 09:39:40 1998 Manfred Hollstein <manfred@s-direktnet.de>
-
- * lang-specs.h: Properly put brackets around array elements in initializer.
-
-1998-03-09 Dave Love <d.love@dl.ac.uk>
-
- * Make-lang.in: Set CONFIG_SITE to a non-existent file since
- /dev/null loses with bash 2.0/autoconf 2.12. Put
- F77_FLAGS_TO_PASS before CC.
-
-Sun Mar 8 16:35:34 1998 Craig Burley <burley@gnu.org>
-
- * intrin.def: Use tabs instead of blanks more
- consistently (excepting DEFGEN section for now).
-
-Wed Mar 4 17:38:21 1998 Jeffrey A Law (law@cygnus.com)
-
- * Make-lang.in: Remove more references to libf77.
-
-Tue Mar 3 10:52:35 1998 Manfred Hollstein <manfred@s-direktnet.de>
-
- * g77.texi: Use @url for citing URLs.
-
-Sat Feb 28 15:24:38 1998 Craig Burley <burley@gnu.org>
-
- * intrin.def: Make CPU_TIME's arg generic real to be just
- like SECOND_subr.
-
-Fri Feb 20 12:45:53 1998 Craig Burley <burley@gnu.org>
-
- * expr.c (ffeexpr_token_arguments_): Make sure
- outer exprstack isn't null.
-
-1998-02-16 Dave Love <d.love@dl.ac.uk>
-
- * Makefile.in (f/fini): Don't use -W -Wall with HOST_CC.
-
-Fri Feb 13 00:14:56 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
-
- * com.c (type_for_mode): Add explicit braces to avoid ambiguous `else'.
-
- * expr.c (ffeexpr_type_combine): Likewise.
- (ffeexpr_reduce_): Likewise.
- (ffeexpr_declare_parenthesized_): Likewise.
-
- * src.c (ffesrc_strcmp_1ns2i): Likewise.
- (ffesrc_strcmp_2c): Likewise.
- (ffesrc_strncmp_2c): Likewise.
-
- * stb.c (ffestb_halt1_): Likewise.
- (ffestb_R90910_): Likewise.
- (ffestb_R9109_): Likewise.
-
- * stc.c (ffestc_R544_equiv_): Likewise.
-
- * std.c (ffestd_subr_copy_easy_): Likewise.
- (ffestd_R1001dump_): Likewise.
- (ffestd_R1001dump_1005_1_): Likewise.
- (ffestd_R1001dump_1005_2_): Likewise.
- (ffestd_R1001dump_1005_3_): Likewise.
- (ffestd_R1001dump_1005_4_): Likewise.
- (ffestd_R1001dump_1005_5_): Likewise.
- (ffestd_R1001dump_1010_2_): Likewise.
-
- * ste.c (ffeste_R840): Likewise.
-
- * sts.c (ffests_puttext): Likewise.
-
- * symbol.c (ffesymbol_check_token_): Likewise.
-
- * target.c (ffetarget_real1): Likewise.
- (ffetarget_real2): Likewise.
-
-Wed Feb 11 01:44:48 1998 Richard Henderson (rth@cygnus.com)
-
- * com.c (ffecom_ptr_to_expr) [FFEBLD_opARRAYREF]: Do upper - lower
- in the native type, so as to properly handle negative indices.
-
-Tue Feb 3 20:13:05 1998 Richard Henderson <rth@cygnus.com>
-
- * config-lang.in: Remove references to runtime/.
-
-Sun Feb 1 12:43:49 1998 J"orn Rennecke <amylaar@cygnus.co.uk>
-
- * com.c (ffecom_tree_canonize_ptr_): Place bitsizetype typed expr
- as first agument in MULT_EXPR.
- Use bitsize_int (0L, 0L) as zero for bitsizes.
- (ffecom_tree_canonize_ref_):
- Use bitsize_int (0L, 0L) as zero for bitsizes.
- (ffecom_init_0): Use set_sizetype.
-
-Sun Feb 1 02:26:58 1998 Richard Henderson <rth@cygnus.com>
-
- * runtime directory -- moved into "libf2c" in the toplevel
- directory.
- * Make-lang.in: Remove all runtime related stuff.
-
-Sun Jan 25 12:32:15 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
-
- * Make-lang.in (f77.stage1): Depend on stage1-start so parallel
- make works better.
- * (f77.stage2): Likewise for stage2-start.
- * (f77.stage3): Likewise for stage3-start.
- * (f77.stage4): Likewise for stage4-start.
-
-Sat Jan 17 21:28:08 1998 Pieter Nagel <pnagel@epiuse.co.za>
-
- * Makefile.in (FLAGS_TO_PASS): Pass down gcc_include_dir and
- local_prefix to sub-make invocations.
-
-Tue Jan 13 22:07:54 1998 Jeffrey A Law (law@cygnus.com)
-
- * lang-options.h: Add missing options.
-
-Sun Jan 11 02:14:47 1998 Craig Burley <burley@gnu.org>
-
- Support FORMAT(I<1+2>) (constant variable-FORMAT
- expressions):
- * bad.def (FFEBAD_FORMAT_VARIABLE): New diagnostic.
- * std.c (ffestd_R1001rtexpr_): New function.
- (ffestd_R1001dump_, ffestd_R1001dump_1005_1_,
- ffestd_R1001dump_1005_2_, ffestd_R1001dump_1005_3_,
- ffestd_R1001dump_1005_4_, ffestd_R1001dump_1005_5_,
- ffestd_R1001dump_1010_2_, ffestd_R1001dump_1010_3_,
- ffestd_R1001dump_1010_4_, ffestd_R1001dump_1010_5_):
- Use new function instead of ffestd_R1001error_.
-
- * stb.c (ffestb_R10014_, ffestb_R10016_, ffestb_R10018_,
- ffestb_R100110_): Restructure `for' loop for style.
-
- Fix 970626-2.f by not doing most back-end processing
- when current_function_decl is an ERROR_MARK, and by
- making that the case when its type would be an ERROR_MARK:
- * com.c (ffecom_start_progunit_, finish_function,
- lang_printable_name, start_function,
- ffecom_finish_symbol_transform_): Test for ERROR_MARK.
- * std.c (ffestd_stmt_pass_): Don't do any downstream
- processing if ERROR_MARK.
-
- * Make-lang.in (f77.install-common): Don't install, and
- don't uninstall existing, Info files if f/g77.info
- doesn't exit. (This is a somewhat modified version
- of an egcs patch on 1998-01-07 12:05:51 by Bruno Haible
- <bruno@linuix.mathematik.uni-karlsruhe.de>.)
-
-Fri Jan 9 19:09:07 1998 Craig Burley <burley@gnu.org>
-
- Fix -fpedantic combined with `F()' invocation,
- also -fugly-comma combined with `IARGC()' invocation:
- * bad.def (FFEBAD_NULL_ARGUMENT_W): New diagnostic.
- * expr.c (ffeexpr_finished_): Don't reject null expressions
- in the argument-expression context -- let outer context
- handle that.
- (ffeexpr_token_arguments_): Warn about null expressions
- here if -fpedantic (as appropriate).
- Obey -fugly-comma for only external-procedure invocations.
- * intrin.c (ffeintrin_check_): No longer ignore explicit
- omitted trailing args.
-
-Tue Dec 23 14:58:04 1997 Craig Burley <burley@gnu.org>
-
- * intrin.c (ffeintrin_fulfill_generic): Don't generate
- FFEBAD_INTRINSIC_TYPE for CHARACTER*(*) intrinsic.
-
- * com.c (ffecom_gfrt_basictype):
- (ffecom_gfrt_kindtype):
- (ffecom_make_gfrt_):
- (FFECOM_rttypeVOIDSTAR_): New return type `void *', for
- the SIGNAL intrinsic.
- * com-rt.def (FFECOM_rttypeSIGNAL): Now returns `void *'.
- * intdoc.c: Replace `p' kind specifier with `7'.
- * intrin.c (ffeintrin_check_, ffeintrin_init_0): Replace
- `p' kind specifier with `7'.
- * intrin.def (FFEINTRIN_impLOC, FFEINTRIN_impSIGNAL_func,
- FFEINTRIN_impSIGNAL_subr): Replace `p' specifier with `7'.
- Also, SIGNAL now returns a `void *' status, not `int'.
-
- Improve run-time diagnostic for "PRINT '(I1', 42":
- * com.c (ffecom_char_args_x_): Renamed from ffecom_char_args_,
- which is now a macro (to avoid lots of changes to other code)
- with new arg, ffecom_char_args_with_null_ being another new
- macro to call same function with different value for new arg.
- This function now appends a null byte to opCONTER expression
- if the new arg is TRUE.
- (ffecom_arg_ptr_to_expr): Support NULL length pointer.
- * ste.c (ffeste_io_cilist_):
- (ffeste_io_icilist_): Pass NULL length ptr for
- FORMAT expression, so null byte gets appended where
- feasible.
- * target.c (ffetarget_character1):
- (ffetarget_concatenate_character1):
- (ffetarget_substr_character1):
- (ffetarget_convert_character1_character1):
- (ffetarget_convert_character1_hollerith):
- (ffetarget_convert_character1_integer4):
- (ffetarget_convert_character1_logical4):
- (ffetarget_convert_character1_typeless):
- (ffetarget_hollerith): Append extra phantom null byte as
- part of FFETARGET-NULL-BYTE kludge.
-
- * intrin.def (FFEINTRIN_impCPU_TIME): Point to
- FFECOM_gfrtSECOND as primary run-time routine.
-
-Mon Dec 22 12:41:07 1997 Craig Burley <burley@gnu.org>
-
- * intrin.c (ffeintrin_init_0): Remove duplicate
- check for `!'.
-
-Fri Dec 19 00:12:01 1997 Richard Henderson <rth@cygnus.com>
-
- * com.c (ffecom_sym_transform_): Assumed arrays have no upper bound.
-
-Mon Dec 15 17:35:35 1997 Richard Henderson <rth@cygnus.com>
-
- * com.c (ffecom_type_vardesc_): Vardesc.dims is a `ftnlen*'.
-
-Sun Dec 14 02:49:58 1997 Craig Burley <burley@gnu.org>
-
- * intrin.c (ffeintrin_init_0): Fix up indentation a bit.
- Fix bug that prevented checking of arguments other
- than the first.
-
- * intdoc.c: Fix up indentation a bit.
-
-Tue Dec 9 16:20:57 1997 Richard Henderson <rth@cygnus.com>
-
- * com.c (ffecom_type_vardesc_): Vardesc.dims is a `ftnlen*'.
-
-Tue Dec 2 09:57:16 1997 Jeffrey A Law (law@cygnus.com)
-
- * Make-lang.in (f77.clean): Remove g77.c.
-
-Mon Dec 1 19:12:36 1997 Craig Burley <burley@gnu.org>
-
- * intrin.c (ffeintrin_check_): Fix up indentation a bit more.
-
-Mon Dec 1 16:21:08 1997 Craig Burley <burley@gnu.org>
-
- * com.c (ffecom_arglist_expr_): Crash if non-supplied
- optional arg isn't passed as an address.
- Pass null pointer explicitly, instead of via ffecom routine.
- If incoming argstring is NULL, substitute pointer to "0".
- Recognize '0' as ending the usual arg stuff, just like '\0'.
-
-Sun Nov 30 22:22:22 1997 Craig Burley <burley@gnu.org>
-
- * intdoc.c: Minor fix-ups.
-
- * intrin.c (ffeintrin_check_): Fix up indentation a bit.
-
- * intrin.def: Fix up spacing a bit.
-
-Tue Nov 25 15:33:28 1997 Jeffrey A Law (law@cygnus.com)
-
- * Make-lang.in (f77.all.build): Add $(exeext) to binary files.
- (f77.all.cross, f77.start.encap): Simliarly.
-
-Fri Nov 21 09:35:20 1997 Fred Fish <fnf@cygnus.com>
-
- * Make-lang.in (stmp-f2c.h): Move inclusion of F77_FLAGS_TO_PASS
- to before override of CC so that the override works.
-
-Thu Nov 20 00:58:14 1997 H.J. Lu (hjl@gnu.ai.mit.edu)
-
- * Make-lang.in (f77.install-info): Depend on f77.info.
-
-1997-11-17 Dave Love <d.love@dl.ac.uk>
-
- * com.c (ffecom_arglist_expr_): Pass null pointers for optional
- args which aren't supplied.
-
-Sun Nov 16 21:45:43 1997 H.J. Lu (hjl@gnu.ai.mit.edu)
-
- * Make-lang.in (f77.install-info): Depend on f77.info.
-
-1997-11-14 Dave Love <d.love@dl.ac.uk>
-
- * intrin.def: Supply gfrt for CPU_TIME. Generalize arg types of
- INT2, INT8, per doc.
-
-1997-11-06 Dave Love <d.love@dl.ac.uk>
-
- * intrin.def: Allow non-integer args for INT2 and INT8 (per
- documentation).
-
-Sun Nov 2 19:49:51 1997 Richard Henderson <rth@cygnus.com>
-
- * com.c (ffecom_expr_): Only use TREE_TYPE argument for simple
- arithmetic; convert types as necessary; recurse with target tree type.
-
-Tue Oct 28 02:21:25 1997 Craig Burley <burley@gnu.ai.mit.edu>
-
- * lang-options.h: Add -fgnu-intrinsics-* and
- -fbadu77-intrinsics-* options.
-
-Sun Oct 26 02:36:21 1997 Craig Burley <burley@gnu.ai.mit.edu>
-
- * com.c (lang_print_error_function): Fix to more
- reliably notice when the diagnosed region changes.
-
-Sat Oct 25 23:43:36 1997 Craig Burley <burley@gnu.ai.mit.edu>
-
- Fix 950327-0.f:
- * sta.c, sta.h (ffesta_outpooldisp): New function.
- * std.c (ffestd_stmt_pass_): Don't kill NULL pool.
- (ffestd_R842): If pool already preserved, save NULL
- for pool, because it should be killed only once.
-
- * malloc.c [MALLOC_DEBUG]: Put initializer for `name'
- component in braces, to avoid compiler warning.
-
-Wed Oct 22 11:37:41 1997 Richard Henderson <rth@cygnus.com>
-
- * com.c (ffecom_expr_): Take an new arg TREE_TYPE that if non-null
- specifies the type in which to do the calculation. Change all callers.
- [FFEBLD_opARRAYREF]: Force the index expr to use sizetype.
-
-Thu Oct 16 02:04:08 1997 Paul Koning <pkoning@xedia.com>
-
- * Make-lang.in (stmp-f2c.h): Don't configure the runtime
- directory if LANGUAGES does not include f77.
-
-Mon Oct 13 12:12:41 1997 Richard Henderson <rth@cygnus.com>
-
- * Make-lang.in (g77*): Copied from cp/Make-lang.in g++*.
- * g77spec.c: New file, mostly copied from g++spec.c
- * g77.c: Removed.
-
-Fri Oct 10 13:00:48 1997 Craig Burley <burley@gnu.ai.mit.edu>
-
- * ste.c (ffeste_begin_iterdo_): Fix loop setup so iteration
- variable is modified only after the #iterations is calculated;
- otherwise if the iteration variable is aliased to any of the
- operands in the start, end, or increment expressions, the
- wrong #iterations might be calculated.
-
- * com.c (ffecom_save_tree): Fix indentation.
-
-Mon Oct 6 14:15:03 1997 Jeffrey A Law (law@cygnus.com)
-
- * Make-lang.in (f77.mostlyclean): Clean up stuff in the
- object tree too.
- (f77.clean, f77.distclean, f77.maintainer-clean): Likewise.
-
-1997-10-05 Dave Love <d.love@dl.ac.uk>
-
- * intrin.def: Make SECOND_subr's arg generic real for people
- porting from Cray and making everything double precision.
-
-Wed Oct 1 01:45:36 1997 Philippe De Muyter <phdm@info.ucl.ac.be>
-
- * g77.c (pexecute, main): Use unlink, not remove.
-
-Mon Sep 29 16:18:21 1997 Craig Burley <burley@gnu.ai.mit.edu>
-
- * stu.c (ffestu_list_exec_transition_,
- ffestu_dummies_transition_): Specify `bool' type for
- `in_progress' variables.
-
- * com.h (assemble_string): Declare this routine (instead
- of #include'ing "output.h" from gcc) to eliminate warnings
- from lex.c.
-
-Mon Sep 29 10:37:07 1997 Jeffrey A Law (law@cygnus.com)
-
- * intdoc.c (main): Remove unused attribute for main's arguments.
-
-Sun Sep 28 01:47:17 1997 Jeffrey A Law (law@cygnus.com)
-
- * Make-lang.in (G77_FLAGS_TO_PASS): Pass down RANLIB, RANLIB_TEST
- and AR instead of the _FOR_TARGET versions.
-
-Tue Sep 23 00:39:57 1997 Alexandre Oliva <oliva@dcc.unicamp.br>
-
- * Make-lang.in: install.texi was renamed to g77install.texi
- * install0.texi: Likewise.
-
-Fri Sep 19 01:12:27 1997 Craig Burley <burley@gnu.ai.mit.edu>
-
- * expr.c (ffeexpr_reduced_eqop2_):
- (ffeexpr_reduced_relop2_): Minor fixes to diagnostic code.
-
- * fini.c (main): Change return type to `int'.
-
-Thu Sep 18 17:31:38 1997 Jeffrey A Law (law@cygnus.com)
-
- * proj.h (FFEPROJ_BSEARCH): Delete all references.
- (FFEPROJ_STRTOUL): Likewise.
- * proj.c (bsearch): Compile this if no bsearch is provided by the
- host system.
- (strtoul): Similarly.
-
- * g77install.texi: Renamed from install.texi
- * g77.texi: Corresponding changes.
-
- * fini.c (main): Return type is int.
-
- * com.c (lang_printable_name): Use verbosity argument.
-
-Thu Sep 18 16:08:40 1997 Jeffrey A Law (law@cygnus.com)
-
- * Make-lang.in: Fix merge problems.
-
-Wed Sep 17 10:47:08 1997 Craig Burley <burley@gnu.ai.mit.edu>
-
- * com-rt.def (FFECOM_gfrtDSIGN, FFECOM_gfrtISIGN,
- FFECOM_gfrtSIGN): Add second argument.
-
- * expr.c (ffeexpr_cb_comma_c_): Trivial fixes.
-
-Sun Sep 14 21:01:23 1997 Jeffrey A Law (law@cygnus.com)
-
- * Make-lang.in: Various changes to build info files
- in the object tree rather than the source tree.
-
- * proj.h: Include ctype.h.
-
-Sun Sep 14 12:35:20 1997 Fred Fish (fnf@ninemoons.com)
-
- * proj.h (isascii): Provide a default definition if none is available.
-
-Thu Sep 11 19:26:10 1997 Dave Love <d.love@dl.ac.uk>
-
- * config-lang.in: Remove the messages about possible build problems.
-
-Wed Sep 10 16:39:47 1997 Jim Wilson <wilson@cygnus.com>
-
- * Make-lang.in (LN, LN_S): New macros, use where appropriate.
-
-Tue Sep 9 13:20:40 1997 Jim Wilson <wilson@cygnus.com>
-
- * g77.c (pexecute, doit): Add checks for __CYGWIN32__.
-
-Tue Sep 9 01:59:35 1997 Craig Burley <burley@gnu.ai.mit.edu>
-
- * Version 0.5.21 released.
-
-Tue Sep 9 00:31:01 1997 Craig Burley <burley@gnu.ai.mit.edu>
-
- * intdoc.c (dumpem): Put appropriate commentary in
- output file, so readers know it isn't source.
-
-Wed Aug 27 20:32:03 1997 Jeffrey A Law (law@cygnus.com)
-
- * top.c (ffe_decode_option): Turn on flag_move_all_moveables
- and flag_reduce_all_givs.
-
-Wed Aug 27 08:08:25 1997 Craig Burley <burley@gnu.ai.mit.edu>
-
- * proj.h: Always #include "config.j" first, to pick up
- gcc's configuration.
- * com.c: Change bcopy() and bzero() calls to memcpy()
- and memset() calls, to make more of g77 ANSI C.
-
-1997-08-26 Dave Love <d.love@dl.ac.uk>
-
- * Make-lang.in ($(srcdir)/f/runtime/configure,
- $(srcdir)/f/runtime/libU77/configure): Fix for when srcdir isn't
- relative.
-
-Tue Aug 26 05:59:21 1997 Craig Burley <burley@gnu.ai.mit.edu>
-
- * ansify.c (main): Make sure readers of stdout know
- it's derived from stdin; omit comment text; get source
- line numbers in future stderr output to be correct.
-
-Tue Aug 26 01:36:01 1997 Craig Burley <burley@gnu.ai.mit.edu>
-
- Fix 970825-0.f:
- * stb.c (ffestb_R5284_): Allow OPEN_PAREN after closing
- SLASH as well as NAME.
-
-Mon Aug 25 23:48:17 1997 Craig Burley <burley@gnu.ai.mit.edu>
-
- Changes to allow g77 docs to be built entirely from scratch
- using any ANSI C compiler, not requiring GNU C:
- * Make-lang.in ($(srcdir)/f/intdoc.texi): "Pipe" new
- location of intrinsic documentation data base, f/intdoc.in,
- through new `ansify' program to append `\n\' to quoted
- newlines, into f/intdoc.h0. Do appropriate cleanups. Explain.
- (f77.mostlyclean): Add f/ansify and f/intdoc.h0 to cleanups.
- * f/ansify.c: New program.
- * f/intdoc.c: Fix so it conforms to ANSI C.
- #include f/intdoc.h0 instead of f/intdoc.h.
- Avoid some warnings.
- * f/intdoc.h, f/intdoc.in: Rename the former to the latter; no
- changes made to the content in this patch!
- * f/intrin.h (ffeintrinFamily): Fix to conform to ANSI C.
-
-Mon Aug 25 23:24:32 1997 H.J. Lu (hjl@gnu.ai.mit.edu)
-
- * Make-lang.in ($(srcdir)/f/runtime/configure,
- $(srcdir)/f/runtime/libU77/configure, f77.mostlyclean,
- f77.clean, f77.distclean, f77.maintainer-clean, f77.realclean):
- Handle absolute pathname of $(srcdir).
- (stmp-f2c.h): New.
- (include/f2c.h, f/runtime/Makefile, f/runtime/libF77/Makefile,
- f/runtime/libI77/Makefile, f/runtime/libU77/Makefile): Only
- depend on stmp-f2c.h.
- (f77.maintainer-clean): Don't make itself.
-
-Sun Aug 24 17:00:27 1997 Jim Wilson <wilson@cygnus.com>
-
- * Make-lang.in (f77.install-info): Don't cd into srcdir. Add srcdir
- to filenames. Use sed to extract base filename for install.
-
-Sun Aug 24 06:52:48 1997 Craig Burley <burley@gnu.ai.mit.edu>
-
- Fix up g77 compiler data base for libf2c routines:
- * com-rt.def (FFECOM_gfrtSIGNAL): Change return type to
- FTNINT to match actual code.
-
- * com.c (ffecomRttype_): Replace FFECOM_rttypeINT_ with
- FFECOM_rttypeFTNINT_.
- Add and fix up comments.
- (ffecom_make_gfrt_, ffecom_gfrt_basictype,
- ffecom_gfrt_kindtype): Replace FFECOM_rttypeINT_ with
- FFECOM_rttypeFTNINT_; add FFECOM_rttypeDOUBLEREAL_.
-
-Thu Aug 21 13:15:29 1997 Jim Wilson <wilson@cygnus.com>
-
- * Make-lang.in (f77): Delete f77-runtime.
- (f77.all.build, f77.all.cross, f77.rest.encap): Add f77-runtime.
-
-Wed Aug 20 17:18:40 1997 Craig Burley <burley@gnu.ai.mit.edu>
-
- * global.c (ffeglobal_ref_progunit_): It's okay to have
- a different CHARACTER*n length for a reference if the
- existing length is for another reference, not a definition.
-
-Wed Aug 20 16:36:59 1997 Jim Wilson <wilson@cygnus.com>
-
- * intdoc.texi: Readd generated file.
-
-Mon Aug 18 14:27:18 1997 Craig Burley <burley@gnu.ai.mit.edu>
-
- Fix 970814-0.f:
- * global.c (ffeglobal_new_progunit_): Distinguish
- between previously defined, versus inferred, filewide
- when it comes to diagnostics.
-
- Fix 970816-1.f:
- * global.c (ffeglobal_ref_progunit_): Change BDATA into EXT
- right at the beginning, so EXTERNAL FOO followed later
- by SUBROUTINE FOO is not diagnosed.
-
- Fix 970813-0.f:
- * com-rt.def (FFECOM_gfrtALARM): Returns `integer', not
- `void'.
-
-Mon Aug 18 09:01:54 1997 Jeffrey A Law (law@cygnus.com)
-
- * Makefile.in (F77_OBJS): Re-alphabetize.
- * Make-lang.in (F77_SRCS): Likewise.
-
-Sun Aug 17 08:35:11 1997 Jeffrey A Law (law@cygnus.com)
-
- * INSTALL: Rebuilt.
- * install.texi: Remove "Object File Differences" section. Remove
- all references to zzz.o failing comparison tests.
- * version.c, version.h: Renamed from zzz.c and zzz.h. Remove
- date and time stamps so a 3 stage build reports no differences.
- * Make-lang.in: Corresponding changes.
- * Makefile.in: Likewise.
- * g77.c, parse.c: Likewise.
-
- * intdoc.texi: Remove generated file from distribution.
-
-Sun Aug 17 03:32:44 1997 Craig Burley <burley@gnu.ai.mit.edu>
-
- Fix up problems when virtual memory exhausted:
- * malloc.c (malloc_new_): Use gcc's xmalloc(), so we
- print a nicer message when malloc returns no memory.
- (malloc_resize_): Ditto for xrealloc().
-
- * Make-lang.in, Makefile.in: Comment out lines containing
- just formfeeds.
-
-Sat Aug 16 19:41:33 1997 Craig Burley <burley@gnu.ai.mit.edu>
-
- * com.c (ffecom_make_gfrt_): For rttypeREAL_F2C_, return
- double_type_node; for rttypeREAL_GNU_, return
- _real_type_node.
-
-1997-08-13 Dave Love <d.love@dl.ac.uk>
-
- * config-lang.in (diff_excludes): Add some hints about known
- problematic platforms.
-
-1997-08-13 Dave Love <d.love@dl.ac.uk>
-
- * intdoc.h: Document `alarm'.
-
-Tue Aug 12 10:23:02 1997 Jeffrey A Law (law@cygnus.com)
-
- * config-lang.in: Don't demand the backend patch.
- * com.c (lang_printable_name): Second argument is now an int. Don't
- store into the value of the second argument.
- * top.c (ffe_decode_option): Temporarily disable setting
- of "Toon" loop options until we figure out how to address
- them.
-
-Mon Aug 11 23:18:35 1997 Jeffrey A Law (law@cygnus.com)
-
- * g77-0.5.21-19970811 Imported.
- This file describes changes to the front end necessary to make
- it work with egcs.
-
-Mon Aug 11 21:19:22 1997 Craig Burley <burley@gnu.ai.mit.edu>
-
- * Make-lang.in ($(RUNTIMESTAGESTUFF)): Add
- f/runtime/stamp-lib.
-
-Mon Aug 11 01:52:03 1997 Craig Burley <burley@gnu.ai.mit.edu>
-
- * com.c (ffecom_build_complex_constant_): Go with the
- new build_complex() approach used in gcc-2.8.
-
- * com.c (ffecom_sym_transform_): Don't set
- DECL_IN_SYSTEM_HEADER for a tree node that isn't
- a VAR_DECL, which happens when var is in common!
-
- * com.c (ffecom_expr_intrinsic_) (case FFEINTRIN_impALARM):
- No need to test codegen_imp -- there's only one valid here.
-
- * intrin.def (FFEINTRIN_impALARM): Specify `Status' argument
- as write-only.
-
-Fri Aug 8 05:40:23 1997 Craig Burley <burley@gnu.ai.mit.edu>
-
- Substantial changes to accommodate distinctions among
- run-time routines that support intrinsics, and between
- routines that compute and return the same type vs. those
- that compute one type and return another (or `void'):
- * com-rt.def: Specify new return type REAL_F2C_ instead
- of many DOUBLE_, COMPLEX_F2C_ instead of COMPLEX_, and
- so on.
- Clear up the *BES* routines "once and for all".
- * com.c: New return types.
- (ffecom_convert_narrow_, ffecom_convert_widen_):
- New functions that are "safe" variants of convert(),
- to catch errors that ffecom_expr_intrinsic_() now
- no longer catches.
- (ffecom_arglist_expr_): Ensure arguments are not
- converted to narrower types.
- (ffecom_call_): Ensure return value is not converted
- to a wider type.
- (ffecom_char_args_): Use new ffeintrin_gfrt_direct()
- routine.
- (ffecom_expr_intrinsic_): Simplify how run-time
- routine is selected (via `gfrt' only now; lose the
- redundant `ix' variable).
- Eliminate the `library' label; any code that doesn't
- return directly just `break's out now with `gfrt'
- set appropriately.
- Set `gfrt' to default choice initially, either a
- fast direct form or, if not available, a slower
- indirect-callable form.
- (ffecom_make_gfrt_): No longer need to do special
- check for complex; it's built into the new return-type
- regime.
- (ffecom_ptr_to_expr): Use new ffeintrin_gfrt_indirect()
- routine.
- * intrin.c, intrin.h: `gfrt' field replaced with three fields,
- so it is easier to provide faster direct-callable and
- GNU-convention indirect-callable routines in the future.
- DEFIMP macro adjusted accordingly, along with all its uses.
- (ffeintrin_gfrt_direct): New function.
- (ffeintrin_gfrt_indirect): Ditto.
- (ffeintrin_is_actualarg): If `-fno-f2c' is in effect,
- require a GNU-callable version of intrinsic instead of
- an f2c-callable version, so indirect calling is still checked.
- * intrin.def: Replace one GFRT field with the three new fields,
- as appropriate for each DEFIMP intrinsic.
-
- * com.c (ffecom_stabilize_aggregate_,
- ffecom_convert_to_complex_): Make these `static'.
-
-Thu Aug 7 11:24:34 1997 Craig Burley <burley@gnu.ai.mit.edu>
-
- Provide means for front end to determine actual
- "standard" return type for an intrinsic if it is
- passed as an actual argument:
- * com.h, com.c (ffecom_gfrt_basictype,
- ffecom_gfrt_kindtype): New functions.
- (ffecom_gfrt_kind_type_): Replaced with new function.
- All callers updated.
- (ffecom_make_gfrt_): No longer need do anything
- with kind type.
-
- * intrin.c (ffeintrin_basictype, ffeintrin_kindtype):
- Now returns correct type info for specific intrinsic
- (based on type of run-time-library implementation).
-
-Wed Aug 6 23:08:46 1997 Craig Burley <burley@gnu.ai.mit.edu>
-
- * global.c (ffeglobal_ref_progunit_): Don't reset
- number of arguments just due to new type info,
- so useful warnings can be issued.
-
-1997-08-06 Dave Love <d.love@dl.ac.uk>
-
- * intrin.def: Fix IDATE_vxt argument order.
- * intdoc.h: Likewise.
-
-Thu Jul 31 22:22:03 1997 Craig Burley <burley@gnu.ai.mit.edu>
-
- * global.c (ffeglobal_proc_ref_arg): If REF/DESCR
- disagreement, DESCR is CHARACTER, and types disagree,
- pretend the argsummary agrees so the message ends up
- being about type disagreement.
- (ffeglobal_proc_def_arg): Ditto.
-
- * expr.c (ffeexpr_token_first_rhs_3_): Set info for LABTOK
- to NONE of everything, to avoid misdiagnosing filewide
- usage of alternate returns.
-
-Sun Jul 20 23:07:47 1997 Craig Burley <burley@gnu.ai.mit.edu>
-
- * com.c (ffecom_sym_transform_): If type gets set
- to error_mark_node, just return that for transformed symbol.
- (ffecom_member_phase2_): If type gets set to error_mark_node,
- just return.
- (ffecom_check_size_overflow_): Add `dummy' argument to
- flag that type is for a dummy, update all callers.
-
-Sun Jul 13 17:40:53 1997 Craig Burley <burley@gnu.ai.mit.edu>
-
- Fix 970712-1.f:
- * where.c (ffewhere_set_from_track): If start point
- is too large, just use initial start point. 0.6 should
- fix all this properly.
-
- Fix 970712-2.f:
- * com.c (ffecom_sym_transform_): Preserve error_mark_node for type.
- (ffecom_type_localvar_): Ditto.
- (ffecom_sym_transform_): If type is error_mark_node,
- don't error-check decl size, because back end responds by
- setting that to an integer 0 instead of error_mark_node.
- (ffecom_transform_common_): Same as earlier fix to _transform_
- in that size is checked by dividing BITS_PER_UNIT instead of
- multiplying.
- (ffecom_transform_equiv_): Ditto.
-
- Fix 970712-3.f:
- * stb.c (ffestb_R10014_): Fix flaky fall-through in error
- test for FFELEX_typeCONCAT by just replicating the code,
- and do FFELEX_typeCOLONCOLON while at it.
-
-1997-07-07 Dave Love <d.love@dl.ac.uk>
-
- * intdoc.h: Add various missing pieces; correct GMTIME, LTIME
- result ordering.
-
- * intrin.def, com-rt.def: Add alarm.
-
- * com.c (ffecom_expr_intrinsic_): Add case for alarm.
-
-Thu Jun 26 04:19:40 1997 Craig Burley <burley@gnu.ai.mit.edu>
-
- Fix 970302-3.f:
- * com.c (ffecom_sym_transform_): For sanity-check compare
- of gbe size of local variable to g77 expectation,
- use varasm.c/assemble_variable technique of dividing
- BITS_PER_UNIT out of gbe info instead of multiplying
- g77 info up, to avoid crash when size in bytes is very
- large, and overflows an `int' or similar when multiplied.
-
- Fix 970626-2.f:
- * com.c (ffecom_finish_symbol_transform_): Don't bother
- transforming a dummy argument, to avoid a crash.
- * ste.c (ffeste_R1227): Don't return a value if the
- result decl, or its type, is error_mark_node.
-
- Fix 970626-4.f:
- * lex.c (ffelex_splice_tokens): `-fdollar-ok' is
- irrelevant to whether a DOLLAR token should be made
- from an initial character of `$'.
-
- Fix 970626-6.f:
- * stb.c (ffestb_do3_): DO iteration variable is an
- lhs, not rhs, expression.
-
- Fix 970626-7.f and 970626-8.f:
- * expr.c (ffeexpr_cb_comma_i_1_): Set IMPDO expression
- to have clean info, because undefined rank, for example,
- caused crash on mangled source on UltraSPARC but not
- on Alpha for a series of weird reasons.
- (ffeexpr_cb_close_paren_): If not CLOSE_PAREN, push
- opANY expression onto stack instead of attempting
- to mimic what program might have wanted.
- (ffeexpr_cb_close_paren_): Don't wrap opPAREN around
- opIMPDO, just warn that it's gratuitous.
- * bad.def (FFEBAD_IMPDO_PAREN): New warning.
-
- Fix 970626-9.f:
- * expr.c (ffeexpr_declare_parenthesized_): Must shut down
- parsing in kindANY case, otherwise the parsing engine might
- decide there's an ambiguity.
- (ffeexpr_token_name_rhs_): Eliminate parentypeSUBROUTINE_
- case, so we crash right away if it comes through.
- * st.c, st.h, sta.c, sta.h (ffest_shutdown, ffesta_shutdown):
- New functions.
-
-Tue Jun 24 19:47:29 1997 Craig Burley <burley@gnu.ai.mit.edu>
-
- * com.c (ffecom_check_size_overflow_): New function
- catches some cases of the size of a type getting
- too large. varasm.c must catch the rest.
- (ffecom_sym_transform_): Use new function.
- (ffecom_type_localvar_): Ditto.
-
-Mon Jun 23 01:09:28 1997 Craig Burley <burley@gnu.ai.mit.edu>
-
- * global.c (ffeglobal_proc_def_arg): Fix comparison
- of argno to #args.
- (ffeglobal_proc_ref_arg): Ditto.
-
- * lang-options.h, top.c: Rename `-fdebug' to `-fxyzzy',
- since it's an unsupported internals option and some
- poor user might guess that it does something.
-
- * bad.def: Make a warning for each filewide diagnostic.
- Put all filewides together.
- * com.c (ffecom_sym_transform_): Don't substitute
- known global tree for global entities when `-fno-globals'.
- * global.c (ffeglobal_new_progunit_): Don't produce
- fatal diagnostics about globals when `-fno-globals'.
- Instead, produce equivalent warning when `-Wglobals'.
- (ffeglobal_proc_ref_arg): Ditto.
- (ffeglobal_proc_ref_nargs): Ditto.
- (ffeglobal_ref_progunit_): Ditto.
- * lang-options.h, top.c, top.h: New `-fno-globals' option.
-
-Sat Jun 21 12:32:54 1997 Craig Burley <burley@gnu.ai.mit.edu>
-
- * expr.c (ffeexpr_fulfill_call_): Set array variable
- to avoid warning about uninitialized variable.
-
- * Make-lang.in: Get rid of any setting of HOST_* macros,
- since these will break gcc's build!
- * makefile: New file to make building derived files
- easier.
-
-Thu Jun 19 18:19:28 1997 Craig Burley <burley@gnu.ai.mit.edu>
-
- * g77.c (main): Install Emilio Lopes' patch to support
- Ratfor, and to fix the printing of the version string
- to go to stderr, not stdout.
- * lang-specs.h: Install Emilio Lopes' patch to support
- Ratfor, and patch the result to support picking up
- `*f771' from the `specs' file.
-
-Thu Jun 12 14:36:25 1997 Craig Burley <burley@gnu.ai.mit.edu>
-
- * storag.c (ffestorag_update_init, ffestorag_update_save):
- Also update parent, in case equivalence processing
- has already eliminated pointers to it via the
- local equivalence info.
-
-Tue Jun 10 14:08:26 1997 Craig Burley <burley@gnu.ai.mit.edu>
-
- * intdoc.c: Add cross-reference to end of description
- of any generic intrinsic pointing to other intrinsics
- with the same name.
-
- Warn about explicit type declaration for intrinsic
- that disagrees with invocation:
- * expr.c (ffeexpr_paren_rhs_let_): Preserve type info
- for intrinsic functions.
- (ffeexpr_token_funsubstr_): Ditto.
- * intrin.c (ffeintrin_fulfill_generic): Warn if type
- info of fulfilled intrinsic invocation disagrees with
- explicit type info given symbol.
- (ffeintrin_fulfill_specific): Ditto.
- * stc.c (ffestc_R1208_item): Preserve type info
- for intrinsics.
- (ffestc_R501_item): Ditto.
-
-Mon Jun 9 17:45:44 1997 Craig Burley <burley@gnu.ai.mit.edu>
-
- * com.c (ffecom_expr_intrinsic_): Fix several of the
- libU77/libF77-unix handlers to properly convert their
- arguments.
-
- * com-rt.def (FFECOM_gfrtFSTAT): Append missing "i" to
- arg string.
-
-Fri Jun 6 14:37:30 1997 Craig Burley <burley@gnu.ai.mit.edu>
-
- * com.c (ffecom_expr_intrinsic_): Have a case statement
- for every intrinsic implementation, so missing ones
- are caught via gcc warnings.
- Don't call ffeintrin_codegen_imp anymore.
- * intrin.c (ffeintrin_fulfill_generic): Remove cg_imp
- stuff from here.
- (ffeintrin_codegen_imp): Delete this function.
- * intrin.def, intrin.h: Remove DEFIMQ stuff from here
- as well.
-
-Thu Jun 5 13:03:07 1997 Craig Burley <burley@gnu.ai.mit.edu>
-
- * top.c (ffe_decode_option): New -fbadu77-intrinsics-*
- options.
- * top.h: Ditto.
- * intrin.h: New BADU77 family.
- * intrin.c (ffeintrin_state_family): Ditto.
-
- Implement new scheme to track intrinsic names vs. forms:
- * intrin.c (ffeintrin_fulfill_generic),
- (ffeintrin_fulfill_specific), (ffeintrin_is_intrinsic),
- intrin.def: The documented name is now either in the
- generic info or, if no generic, in the specific info.
- For a generic, the specific info contains merely the
- distinguishing form (usually "function" or "subroutine"),
- used for diagnostics about ambiguous references and
- in the documentation.
-
- * intrin.def: Clean up formatting of DEFNAME block.
- Convert many libU77 intrinsics into generics that
- support both subroutine and function forms.
- Put the function forms of side-effect routines into
- the new BADU77 family.
- Make MCLOCK and TIME return INTEGER*4 again, and add
- INTEGER*8 equivalents called MCLOCK8 and TIME8.
- Fix up more status return values to be written and
- insist on them being I1 as well.
- * com.c (ffecom_expr_intrinsic_): Lots of changes to
- support new libU77 intrinsic interfaces.
-
-Mon Jun 2 00:37:53 1997 Craig Burley <burley@gnu.ai.mit.edu>
-
- * com.c (ffecom_init_0): Pointer type is now INTEGER(KIND=7),
- not INTEGER(KIND=0), since we want to reserve KIND=0 for
- future use.
-
-Thu May 29 14:30:33 1997 Craig Burley <burley@gnu.ai.mit.edu>
-
- Fix bugs preventing CTIME(I*4) from working correctly:
- * com.c (ffecom_char_args_): For FUNCREF case, process
- args to intrinsic just as they would be in
- ffecom_expr_intrinsic_.
- * com-rt.def (FFECOM_gfrtCTIME, FFECOM_gfrtTTYNAM): Fix
- argument decls to specify `&'.
-
-Wed May 28 22:19:49 1997 Craig Burley <burley@gnu.ai.mit.edu>
-
- Fix gratuitous warnings exposed by dophot aka 970528-1:
- * global.c (ffeglobal_proc_def_arg, ffeglobal_proc_ref_arg):
- Support distinct function/subroutine arguments instead of
- just procedures.
- * global.h: Ditto.
- * expr.c (ffeexpr_fulfill_call_): A SYMTER with kindNONE
- also is a procedure (either function or subroutine).
-
-Mon May 26 20:25:31 1997 Craig Burley <burley@gnu.ai.mit.edu>
-
- * bad.def: Have several lexer diagnostics refer to
- documentation for people who need more info on what Fortran
- source code is supposed to look like.
-
- * expr.c (ffeexpr_reduced_bool1_), bad.def: New diagnostics
- specific to .NOT. now mention only one operand instead
- of two.
-
- * g77.c: Recognize -fsyntax-only, similar to -c etc.
- (lookup_option): Fix bug that prevented non-`--' options
- from being recognized.
-
-Sun May 25 04:29:04 1997 Craig Burley <burley@gnu.ai.mit.edu>
-
- * intrin.def (FFEINTRIN_impCTIME): Accept `I*' expression
- for STime instead of requiring `I2'.
-
-Tue May 20 16:14:40 1997 Craig Burley <burley@gnu.ai.mit.edu>
-
- * symbol.c (ffesymbol_reference): All references to
- standard intrinsics are considered explicit, so as
- to avoid generating basically useless warnings.
- * intrin.c, intrin.h (ffeintrin_is_standard): Returns TRUE
- if intrinsic is standard.
-
-Sun May 18 21:14:59 1997 Craig Burley <burley@gnu.ai.mit.edu>
-
- * com-rt.def: Changed all external names of the
- form `"\([a-z0-9]*\)_' to `"G77_\1_0"' so as to
- allow any name valid as an intrinsic to be used
- as such and as a user-defined external procedure
- name or common block as well.
-
-Thu May 8 13:07:10 1997 Craig Burley <burley@gnu.ai.mit.edu>
-
- * expr.c (ffeexpr_cb_end_notloc_): For %VAL, %REF, and
- %DESCR, copy arg info into new node.
-
-Mon May 5 14:42:17 1997 Craig Burley <burley@gnu.ai.mit.edu>
-
- From Uwe F. Mayer <mayer@math.Vanderbilt.Edu>:
- * Make-lang.in (g77-cross): Fix typo in g77.c path.
-
- From Brian McIlwrath <bkm@star.rl.ac.uk>:
- * lang-specs.h: Have g77 pick up options from a section
- labeled `*f771' of the `specs' file.
-
-Sat May 3 02:46:08 1997 Craig Burley <burley@gnu.ai.mit.edu>
-
- * intrin.def (FFEINTRIN_defSIGNAL): Add optional `Status'
- argument that com.c already expects (per Dave Love).
-
- More changes to support better tracking of (filewide)
- globals, in particular, the arguments to procedures:
- * bad.def (FFEBAD_FILEWIDE_NARGS, FFEBAD_FILEWIDE_NARGS_W,
- FFEBAD_FILEWIDE_ARG, FFEBAD_FILEWIDE_ARG_W): New diagnostics.
- * expr.c (ffebad_fulfill_call_): Provide info on each
- argument to ffeglobal.
- * global.c, global.h (ffeglobal_proc_def_arg,
- ffeglobal_proc_def_nargs, ffeglobal_proc_ref_arg,
- ffeglobal_proc_ref_args): New functions.
- (ffeglobalArgSummary, ffeglobalArgInfo_): New types.
-
-Tue Apr 29 18:35:41 1997 Craig Burley <burley@gnu.ai.mit.edu>
-
- More changes to support better tracking of (filewide)
- globals:
- * expr.c (ffeexpr_fulfill_call_): New function.
- (ffeexpr_token_name_lhs_): Call after building procedure
- reference expression. Also leave info field for ANY-ized
- expression alone.
- (ffeexpr_token_arguments_): Ditto.
-
-Mon Apr 28 20:04:18 1997 Craig Burley <burley@gnu.ai.mit.edu>
-
- Changes to support better tracking of (filewide)
- globals, mainly to avoid crashes due to inlining:
- * bad.def: Go back to quoting intrinsic names,
- (FFEBAD_FILEWIDE_DISAGREEMENT, FFEBAD_FILEWIDE_TIFF,
- FFEBAD_FILEWIDE_TYPE_MISMATCH): New diagnostics.
- (FFEBAD_INTRINSIC_EXPIMP, FFEBAD_INTRINSIC_GLOBAL): Reword
- for clarity.
- * com.c (ffecom_do_entry_, ffecom_start_progunit_,
- ffecom_sym_transform_): Accommodate new FFEGLOBAL_typeEXT
- possibility.
- * expr.c (ffeexpr_sym_lhs_call_, ffeexpr_sym_lhs_extfunc_,
- ffeexpr_sym_rhs_actualarg_, ffeexpr_declare_parenthesized_,
- ffeexpr_paren_rhs_let_, ffeexpr_token_funsubstr_):
- Fill in real kind info instead of leaving NONE where
- appropriate.
- Register references to intrinsics and globals with ffesymbol
- using new ffesymbol_reference function instead of
- ffesymbol_globalize.
- * global.c (ffeglobal_type_string_): New array for
- new diagnostics.
- * global.h, global.c:
- Replace ->init mechanism with ->tick mechanism.
- Move other common-related members into a substructure of
- a union, so the proc substructure can be introduced
- to include members related to externals other than commons.
- Don't complain about ANY-ized globals; ANY-ize globals
- once they're complained about, in any case where code
- generation could become a problem.
- Handle global entries that have NONE type (seen as
- intrinsics), EXT type (seen as EXTERNAL), and so on.
- Keep track of kind and type of externals, both via
- definition and via reference.
- Diagnose disagreements about kind or type of externals
- (such as functions).
- (ffeglobal_ref_intrinsic, ffeglobal_ref_progunit_): New
- functions.
- * stc.c (ffestc_R1207_item, ffestc_R1208_item,
- ffestc_R1219, ffestc_R1226):
- Call ffesymbol_reference, not ffesymbol_globalize.
- * stu.c (ffestu_sym_end_transition,
- ffestu_sym_exec_transition):
- Call ffesymbol_reference, not ffesymbol_globalize.
- * symbol.c (ffesymbol_globalize): Removed...
- (ffesymbol_reference): ...to this new function,
- which more generally registers references to symbols,
- globalizes globals, and calls on the ffeglobal module
- to check globals filewide.
-
- * global.h, global.c: Rename some macros and functions
- to more clearly distinguish common from other globals.
- All callers changed.
-
- * com.c (ffecom_sym_transform_): Trees describing
- filewide globals must be allocated on permanent obstack.
-
- * expr.c (ffeexpr_token_name_lhs_): Don't generate
- gratuitous diagnostics for FFEINFO_whereANY case.
-
-Thu Apr 17 03:27:18 1997 Craig Burley <burley@gnu.ai.mit.edu>
-
- * global.c: Add support for flagging intrinsic/global
- confusion via warnings.
- * bad.def (FFEBAD_INTRINSIC_EXPIMP,
- FFEBAD_INTRINSIC_GLOBAL): New diagnostics.
- * expr.c (ffeexpr_token_funsubstr_): Ditto.
- (ffeexpr_sym_lhs_call_): Ditto.
- (ffeexpr_paren_rhs_let_): Ditto.
- * stc.c (ffestc_R1208_item): Ditto.
-
-Wed Apr 16 22:40:56 1997 Craig Burley <burley@gnu.ai.mit.edu>
-
- * expr.c (ffeexpr_declare_parenthesized_): INCLUDE
- context can't be an intrinsic invocation either.
-
-Fri Mar 28 10:43:28 1997 Craig Burley <burley@gnu.ai.mit.edu>
-
- * expr.c (ffeexpr_token_arguments_): Make sure top of
- exprstack is operand before dereferencing operand field.
-
- * lex.c (ffelex_prepare_eos_): Fill up truncated
- hollerith token, so crash on null ->text field doesn't
- happen later.
-
- * stb.c (ffestb_R10014_): If NAMES isn't recognized (or
- the recognized part is followed in the token by a
- non-digit), don't try and collect digits, as there
- might be more than FFEWHERE_indexMAX letters to skip
- past to do so -- and the code is diagnosed anyway.
-
-Thu Mar 27 00:02:48 1997 Craig Burley <burley@gnu.ai.mit.edu>
-
- * com.c (ffecom_sym_transform_): Force local
- adjustable array onto stack.
-
- * stc.c (ffestc_R547_item_object): Don't actually put
- the symbol in COMMON if the symbol has already been
- EQUIVALENCE'd to a different COMMON area.
-
- * equiv.c (ffeequiv_add): Don't actually do anything
- if there's a disagreement over which COMMON area is
- involved.
-
-Tue Mar 25 03:35:19 1997 Craig Burley <burley@gnu.ai.mit.edu>
-
- * com.c (ffecom_transform_common_): If no explicit init
- of COMMON area, don't actually init it even though
- storage area suggests it.
-
-Mon Mar 24 12:10:08 1997 Craig Burley <burley@gnu.ai.mit.edu>
-
- * lex.c (ffelex_image_char_): Avoid overflowing the
- column counter itself, as well as the card image.
-
- * where.c (ffewhere_line_new): Cast ffelex_line_length()
- to (size_t) so 255 doesn't overflow to 0!
-
- * stc.c (ffestc_labeldef_notloop_begin_): Don't gratuitously
- terminate loop before processing statement, so block
- doesn't disappear out from under EXIT/CYCLE processing.
- (ffestc_labeldef_notloop_): Has old code from above
- function, instead of just calling it.
-
- * expr.c (ffeexpr_cb_comma_i_4_): Don't skip over
- arbitrary token (such as EOS).
-
- * com.c (ffecom_init_zero_): Handle RECORD_TYPE and
- UNION_TYPE so -fno-zeros works with -femulated-complex.
-
-1997-03-12 Dave Love <d.love@dl.ac.uk>
-
- * intrin.def: New intrinsics INT2, INT8, CPU_TIME. Fix AND, OR,
- XOR. [Integrated by burley, AND/OR/XOR already fixed, INT8
- implementation changed/fixed.]
-
-Wed Mar 12 10:40:08 1997 Craig Burley <burley@gnu.ai.mit.edu>
-
- * Make-lang.in ($(srcdir)/f/intdoc.texi): Simplify rules
- so building f/intdoc is not always necessary; remove
- f/intdoc after running it if it is built.
-
-Tue Mar 11 23:42:00 1997 Craig Burley <burley@gnu.ai.mit.edu>
-
- * intrin.def (FFEINTRIN_impAND, FFEINTRIN_impOR,
- FFEINTRIN_impXOR): Use the IAND, IOR, and IEOR implementations
- of these, instead of crashing in ffecom_expr_intrinsic_
- or adding case labels there.
-
-Mon Mar 10 22:51:23 1997 Craig Burley <burley@gnu.ai.mit.edu>
-
- * intdoc.c: Fix so any C compiler can compile this.
-
-Fri Feb 28 13:16:50 1997 Craig Burley <burley@gnu.ai.mit.edu>
-
- * Version 0.5.20 released.
-
-Fri Feb 28 01:45:25 1997 Craig Burley <burley@gnu.ai.mit.edu>
-
- * Make-lang.in (RUNTIMESTAGESTUFF, LIBU77STAGESTUFF):
- Move some files incorrectly in the former to the latter,
- and add another file or two to the latter.
-
- New meanings for (KIND=n), and new denotations in the
- little language describing intrinsics:
- * com.c (ffecom_init_0): Assign new meanings.
- * intdoc.c: Document new meanings.
- Support the new denotations.
- * intrin.c: Employ new meanings, mapping them to internal
- values (which are the same as they ever were for now).
- Support the new denotations.
- * intrin.def: Switch DEFIMP table to the new denotations.
-
- * intrin.c (ffeintrin_check_): Fix bug that was leaving
- LOC() and %LOC() returning INTEGER*4 on systems where
- it should return INTEGER*8.
-
- * type.c: Canonicalize function definitions, for etags
- and such.
-
-Wed Feb 26 20:43:03 1997 Craig Burley <burley@gnu.ai.mit.edu>
-
- * com.c (ffecom_init_0): Choose INTEGER(KIND=n) types,
- where n is 2, 3, and 4, according to the new docs
- instead of according to the old C correspondences
- (which seem less useful at this point).
-
- * equiv.c (ffeequiv_destroy_): New function.
- (ffeequiv_layout_local_): Use this new function
- whenever the laying out of a local equivalence chain
- is aborted for any reason.
- Otherwise ensure that symbols no longer reference
- the stale ffeequiv entries that result when they
- are killed off in this procedure.
- Also, the rooted symbol is one that has storage,
- it really is irrelevant whether it has an equiv entry
- at this point (though the code to remove the equiv
- entry was put in at the end, just in case).
- (ffeequiv_kill): When doing internal checks, make
- sure the victim isn't named by any symbols it points
- to. Not as complete a check as looking through the
- entire symbol table (which does matter, since some
- code in equiv.c used to remove symbols from the lists
- for an ffeequiv victim but not remove that victim as the
- symbol's equiv info), but this check did find some
- real bugs in the code (that were fixed).
-
-Mon Feb 24 16:42:13 1997 Craig Burley <burley@gnu.ai.mit.edu>
-
- * com.c (ffecom_expr_intrinsic_): Fix a couple of
- warnings about uninitialized variables.
- * intrin.c (ffeintrin_check_): Ditto, but there were
- a couple of _real_ uninitialized-variable _bugs_ here!
- (ffeintrin_fulfill_specific): Ditto, no real bug here.
-
-Sun Feb 23 15:01:20 1997 Craig Burley <burley@gnu.ai.mit.edu>
-
- Clean up diagnostics (especially about intrinsics):
- * bad.def (FFEBAD_UNIMPL_STMT): Remove.
- (FFEBAD_INTRINSIC_*, FFEBAD_NEED_INTRINSIC): Clean these
- up so they're friendlier.
- (FFEBAD_INTRINSIC_CMPAMBIG): New.
- * intrin.c (ffeintrin_fulfill_generic,
- ffeintrin_fulfill_specific, ffeintrin_is_intrinsic):
- Always choose
- generic or specific name text (which is for doc purposes
- anyway) over implementation name text (which is for
- internal use).
- * intrin.def: Use more descriptive name texts for generics
- and specifics in cases where the names themselves are not
- enough (e.g. IDATE, which has two forms).
-
- Fix some intrinsic mappings:
- * intrin.def (FFEINTRIN_specIDINT, FFEINTRIN_specAND,
- FFEINTRIN_specDFLOAT, FFEINTRIN_specDREAL, FFEINTRIN_specOR,
- FFEINTRIN_specXOR): Now have their own implementations,
- instead of borrowing from others.
- (FFEINTRIN_specAJMAX0, FFEINTRIN_specAJMIN0, FFEINTRIN_specBJTEST,
- FFEINTRIN_specDFLOTJ, FFEINTRIN_specFLOATJ, FFEINTRIN_specJIABS,
- FFEINTRIN_specJIAND, FFEINTRIN_specJIBCLR, FFEINTRIN_specJIBITS,
- FFEINTRIN_specJIBSET, FFEINTRIN_specJIDIM, FFEINTRIN_specJIDINT,
- FFEINTRIN_specJIDNNT, FFEINTRIN_specJIEOR, FFEINTRIN_specJIFIX,
- FFEINTRIN_specJINT, FFEINTRIN_specJIOR, FFEINTRIN_specJISHFT,
- FFEINTRIN_specJISHFTC, FFEINTRIN_specJISIN, FFEINTRIN_specJMAX0,
- FFEINTRIN_specJMAX1, FFEINTRIN_specJMIN0, FFEINTRIN_specJMIN1,
- FFEINTRIN_specJMOD, FFEINTRIN_specJNINT, FFEINTRIN_specJNOT,):
- Turn these implementations off, since it's not clear
- just what types they expect in the context of portable Fortran.
- (DFLOAT): Now in FVZ family, since f2c supports them
-
- Support intrinsic inquiry functions (BIT_SIZE, LEN):
- * intrin.c: Allow `i' in <arg_extra>.
- * intrin.def (FFEINTRIN_impBIT_SIZE, FFEINTRIN_impLEN):
- Mark args with `i'.
-
-Sat Feb 22 13:34:09 1997 Craig Burley <burley@gnu.ai.mit.edu>
-
- Only warn, don't error, for reference to unimplemented
- intrinsic:
- * bad.def (FFEBAD_INTRINSIC_UNIMPLW): Warning version
- of _UNIMPL.
- * intrin.c (ffeintrin_is_intrinsic): Use new warning
- version of _UNIMPL (FFEBAD_INTRINSIC_UNIMPLW).
-
- Complain about REAL(Z) and AIMAG(Z) (Z is DOUBLE COMPLEX):
- * bad.def (FFEBAD_INTRINSIC_CMPAMBIG): New diagnostic.
- * expr.c: Needed #include "intrin.h" anyway.
- (ffeexpr_token_intrincheck_): New function handles delayed
- diagnostic for "REAL(REAL(expr)" if next token isn't ")".
- (ffeexpr_token_arguments_): Do most of the actual checking here.
- * intrin.h, intrin.c (ffeintrin_fulfill_specific): New
- argument, check_intrin, to tell caller that intrin is REAL(Z)
- or AIMAG(Z). All callers updated, mostly to pass NULL in
- for this.
- (ffeintrin_check_): Also has new arg check_intrin for same
- purpose. All callers updated the same way.
- * intrin.def (FFEINTRIN_impAIMAG): Change return type
- from "R0" to "RC", to accommodate f2c (and perhaps other
- non-F90 F77 compilers).
- * top.h, top.c: New option -fugly-complex.
-
- New GNU intrinsics REALPART, IMAGPART, and COMPLEX:
- * com.c (ffecom_expr_intrinsic_): Implement impCOMPLEX
- and impREALPART here. (specIMAGPART => specAIMAG.)
- * intrin.def: Add the intrinsics here.
-
- Rename implementations of VXTIDATE and VXTTIME to IDATEVXT
- and TIMEVXT, so they sort more consistently:
- * com.c (ffecom_expr_intrinsic_):
- * intrin.def:
-
- Delete intrinsic group `dcp', add `gnu', etc.:
- * intrin.c (ffeintrin_state_family): FFEINTRIN_familyGNU
- replaces FFEINTRIN_familyDCP, and gets state from `gnu'
- group.
- Get rid of FFEINTRIN_familyF2Z, nobody needs it.
- Move FFEINTRIN_specDCMPLX from DCP family to FVZ family,
- as f2c has it.
- Move FFEINTRIN_specDFLOAT from F2C family to FVZ family.
- (FFEINTRIN_specZABS, FFEINTRIN_specZCOS, FFEINTRIN_specZEXP,
- FFEINTRIN_specZLOG, FFEINTRIN_specZSIN, FFEINTRIN_specZSQRT):
- Move these from F2Z family to F2C family.
- * intrin.h (FFEINTRIN_familyF2Z, FFEINTRIN_familyDCP): Remove.
- (FFEINTRIN_familyGNU): Add.
- * top.h, top.c: Replace `dcp' with `gnu'.
-
- * com.c (ffecom_expr_intrinsic_): Clean up by collecting
- simple conversions into one nice, conceptual place.
- Fix up some intrinsic subroutines (MVBITS, KILL, UMASK) to
- properly push and pop call temps, to avoid wasting temp
- registers.
-
- * g77.c (doit): Toon says variables should be defined
- before being referenced. Spoilsport.
-
- * intrin.c (ffeintrin_check_): Now Dave's worried about
- warnings about uninitialized variables. Okay, so for
- basic return values 'g' and 's', they _were_
- uninitialized -- is determinism really _that_ useful?
-
- * intrin.def (FFEINTRIN_impFGETC): Fix STATUS argument
- so that it is INTENT(OUT) instead of INTENT(IN).
-
-1997-02-21 Dave Love <d.love@dl.ac.uk>
-
- * intrin.def, com.c: Support Sun-type `short' and `long'
- intrinsics. Perhaps should also do Microcruft-style `int2'.
-
-Thu Feb 20 15:16:53 1997 Craig Burley <burley@gnu.ai.mit.edu>
-
- * com.c (ffecom_expr_intrinsic_): Clean up indentation.
- Support SECONDSUBR intrinsic implementation.
- Rename SECOND to SECONDFUNC for direct support via library.
-
- * g77.c: Fix to return proper status value to shell,
- by obtaining it from processes it spawns.
-
- * intdoc.c: Fix minor typo.
-
- * intrin.def: Turn SECOND into generic that maps into
- function and subroutine forms.
-
- * intrin.def: Make FLOAT and SNGL into specific intrinsics.
-
- * intrin.def, intrin.h: Change the way DEFGEN and DEFSPEC
- macros work, to save on verbage.
-
-Mon Feb 17 02:08:04 1997 Craig Burley <burley@gnu.ai.mit.edu>
-
- New subsystem to automatically generate documentation
- on intrinsics:
- * Make-lang.in ($(srcdir)/f/g77.info,
- $(srcdir)/f/g77.dvi): Move g77 doc rules around.
- Add to g77 doc rules the new subsystem.
- (f77.mostlyclean, f77.maintainer-clean): Also clean up
- after new doc subsystem.
- * intdoc.c, intdoc.h: New doc subsystem code.
- * intrin.h [FFEINTRIN_DOC]: When 1, don't pull in
- stuff not needed by doc subsystem.
-
- Improve on intrinsics mechanism to both be more
- self-documenting and to catch more user errors:
- * intrin.c (ffeintrin_check_): Recognize new arg-len
- and arg-rank information, and check it.
- Move goto and signal indicators to the basic type.
- Permit reference to arbitrary argument number, not
- just first argument (for BESJN and BESYN).
- (ffeintrin_init_0): Check and accept new notations.
- * intrin.c, intrin.def: Value in COL now identifies
- arguments starting with number 0 being the first.
-
- Some minor intrinsics cleanups (resulting from doc work):
- * com.c (ffecom_expr_intrinsic_): Implement FLUSH
- directly once again, handle its optional argument,
- so it need not be a generic (awkward to handle in docs).
- * intrin.def (BESJ0, BESJ1, BESJN, BESY0, BESY1, BESYN,
- CHDIR, CHMOD, CTIME, DBESJ0, DBESJ1, DBESJN, DBESY0,
- DBESY1, DBESYN, DDIM, ETIME, FGETC, FNUM, FPUTC, FSTAT,
- GERROR, GETCWD, GETGID, GETLOG, GETPID, GETUID, GMTIME,
- HOSTNM, IDATE, IERRNO, IIDINT, IRAND, ISATTY, ITIME, JIDINT,
- LNBLNK, LSTAT, LTIME, MCLOCK, PERROR, SRAND, SYMLNK, TTYNAM,
- UMASK): Change capitalization of initcaps (official) name
- to be consistent with Burley's somewhat arbitrary rules.
- (BESJN, BESYN): These have return arguments of same type
- as their _second_ argument.
- (FLUSH): Now a specific, not generic, intrinsic, with one
- optional argument.
- (FLUSH1): Eliminated.
- Add arg-len and arg-rank info to several intrinsics.
- (ITIME): Change argument type from REAL to INTEGER.
-
-Tue Feb 11 14:04:42 1997 Craig Burley <burley@gnu.ai.mit.edu>
-
- * Make-lang.in (f771): Invocation of Makefile now done
- with $(srcdir)=gcc to go along with $(VPATH)=gcc.
- ($(srcdir)/f/runtime/configure,
- $(srcdir)/f/runtime/libU77/configure): Break these out
- so spurious triggers of this rule don't happen (as when
- configure.in is more recent than libU77/configure).
- (f77.rebuilt): Distinguish source versus build files,
- so this target can be invoked from build directory and
- still work.
- * Makefile.in: This now expects $(srcdir) to be the gcc
- source directory, not gcc/f, to agree with $(VPATH).
- Accordingly, $(INCLUDES) has been fixed, various cruft
- removed, the removal of f771 has been fixed to remove
- the _real_ f771 (not the one in gcc's parent directory),
- and so on.
-
- * lex.c: Part of ffelex_finish_statement_() now done
- by new function ffelex_prepare_eos_(), so that, in one
- popular case, the EOS can be prepared while the pointer
- is at the end of the non-continued line instead of the
- end of the line that marks no continuation. This improves
- the appearance of diagnostics substantially.
-
-Mon Feb 10 12:44:06 1997 Craig Burley <burley@gnu.ai.mit.edu>
-
- * Make-lang.in: runtime Makefile's, and include/f2c.h,
- also depend on f/runtime/configure and f/runtime/libU77/configure.
-
- Fix various libU77 routines:
- * com-rt.def (FFECOM_gfrtCTIME, FFECOM_gfrtMCLOCK,
- FFECOM_gfrtTIME): These now use INTEGER*8 for time values,
- for compatibility with systems like Alpha.
- (FFECOM_gfrtSYSTEM_CLOCK, FFECOM_gfrtTTYNAM): Delete incorrect
- trailing underscore in routine names.
- * intrin.c, intrin.def: Support INTEGER*8 return values and
- arguments ('4'). Change FFEINTRIN_impCTIME, FFEINTRIN_impMCLOCK,
- and FFEINTRIN_impTIME accordingly.
- (ffeintrin_is_intrinsic): Don't give caller a clue about
- form of intrinsic -- shouldn't be needed at this point.
-
- Cope with generic intrinsics that are subroutines and functions:
- * com.c (ffecom_finish_symbol_transform_, ffecom_expr_transform_):
- Don't transform an intrinsic that is not known to be a subroutine
- or a function. (Maybe someday have to avoid transforming
- any intrinsic with an undecided or unknown implementation.)
- * expr.c (ffeexpr_declare_unadorned_,
- ffeexpr_declare_parenthesized_): Ok to invoke generic
- intrinsic that has at least one subroutine form as a
- subroutine.
- Ok to pass intrinsic as actual arg if it has a known specific
- intrinsic form that is valid as actual arg.
- (ffeexpr_declare_parenthesized_): An unknown kind of
- intrinsic has a paren_type chosen based on context.
- (ffeexpr_token_arguments_): Build funcref/subrref based
- on context, not on kind of procedure being called.
- * intrin.h, intrin.c (ffeintrin_is_intrinsic): Undo changes of
- Tue Feb 4 23:12:04 1997 by me, change all callers to leave
- intrinsics as FFEINFO_kindNONE at this point. (Some callers
- also had unused variables deleted as a result.)
-
- Enable all intrinsic groups (especially f90 and vxt):
- * target.h (FFETARGET_defaultSTATE_DCP, FFETARGET_defaultSTATE_F2C,
- FFETARGET_defaultSTATE_F90, FFETARGET_defaultSTATE_MIL,
- FFETARGET_defaultSTATE_UNIX, FFETARGET_defaultSTATE_VXT):
- Delete these macros, let top.c set them directly.
- * top.c (ffeintrinsic_state_dcp_, ffe_intrinsic_state_f2c_,
- ffe_intrinsic_state_f90_, ffe_intrinsic_state_mil_,
- ffe_intrinsic_state_unix_, ffe_intrinsic_state_vxt_):
- Enable all these directly.
-
-Sat Feb 8 03:21:50 1997 Craig Burley <burley@gnu.ai.mit.edu>
-
- * g77.c: Incorporate recent changes to ../gcc.c.
- For version magic (e.g. `g77 -v'), instead of compiling
- /dev/null, write, compile, run, and then delete a small
- program that prints the version numbers of the three
- components of libf2c (libF77, libI77, and libU77),
- so we get this info with bug reports.
- Also, this change reduces the chances of accidentally
- linking to an old (complex-alias-problem) libf2c.
- Fix `-L' so the argument is expected in `-Larg'.
-
- * com.h (FFECOM_f2cLONGINT): For INTEGER*8 support in f2c.h,
- dynamically determine proper type here, instead of
- assuming `long long int' is correct.
-
-Tue Feb 4 23:12:04 1997 Craig Burley <burley@gnu.ai.mit.edu>
-
- Add libU77 library from Dave Love <d.love@dl.ac.uk>:
- * Make-lang.in (f77-runtime): Depend on new Makefile.
- (f/runtime/libU77/Makefile): New rule.
- Also configure libU77.
- ($(srcdir)/f/runtime/configure: Use Makefile.in,
- so configuration doesn't have to have happened.
- (f77.mostlyclean, f77.clean, f77.distclean,
- f77.maintainer-clean): Some fixups here, but more work
- needed.
- (RUNTIMESTAGESTUFF): Add libU77's config.status.
- (LIBU77STAGESTUFF, f77.stage1, f77.stage2, f77.stage3,
- f77.stage4): New macro, appropriate uses added.
- * com-rt.def: Add libU77 procedures.
- * com.c (ffecom_f2c_ptr_to_integer_type_node,
- ffecom_f2c_ptr_to_real_type_node): New type nodes.
- (FFECOM_rttypeCHARACTER_): New type of run-time function.
- (ffecom_char_args_): Handle CHARACTER*n intrinsics
- where n != 1 here, instead of in ffecom_expr_intrinsic_.
- (ffecom_expr_intrinsic_): New code to handle new
- intrinsics.
- In particular, change how FFEINTRIN_impFLUSH is handled.
- (ffecom_make_gfrt_): Handle new type of run-time function.
- (ffecom_init_0): Initialize new type nodes.
- * config-lang.in: New libU77 directory.
- * intrin.h, intrin.c (ffeintrin_is_intrinsic): Handle
- potential generic for subroutine _and_ function
- specifics via two new arguments. All callers changed.
- Properly ignore deleted/disabled intrinsics in resolving
- generics.
- (ffeintrin_check_, ffeintrin_init_0): Handle CHARACTER intrinsics of (*)
- length.
- * intrin.def: Permission granted by FSF to place this in
- public domain, which will allow it to serve as source
- for both g77 program and its documentation.
- Add libU77 intrinsics.
- (FLUSH): Now a generic, not specific, intrinsic.
- (DEFIMP): Now support return modifier for CHARACTER intrinsics.
-
- * com-rt.def (FFECOM_gfrtDIM, FFECOM_gfrtERF,
- FFECOM_gfrtERFC, FFECOM_gfrtEXP, FFECOM_gfrtSIGN,
- FFECOM_gfrtSIN, FFECOM_gfrtSINH, FFECOM_gfrtTAN,
- FFECOM_gfrtTANH, FFECOM_gfrtPOW_RI): Change "&r" to "&f".
-
-Sat Feb 1 12:15:09 1997 Craig Burley <burley@gnu.ai.mit.edu>
-
- * Version 0.5.19.1 released.
-
- * com.c (ffecom_expr_, ffecom_expr_intrinsic_,
- ffecom_tree_divide_): FFECOM_gfrtPOW_ZI,
- FFECOM_gfrtCONJG, FFECOM_gfrtDCONJG,
- FFECOM_gfrtCCOS, FFECOM_gfrtCDCOS,
- FFECOM_gfrtCLOG, FFECOM_gfrtCDLOG,
- FFECOM_gfrtCSIN, FFECOM_gfrtCDSIN,
- FFECOM_gfrtCSQRT, FFECOM_gfrtCDSQRT,
- FFECOM_gfrtDIV_CC, FFECOM_gfrtDIV_ZZ: These all require
- result to _not_ overlap one or more inputs.
-
-Sat Feb 1 00:25:55 1997 Craig Burley <burley@gnu.ai.mit.edu>
-
- * com.c (ffecom_init_0): Do internal checks only if
- -fset-g77-defaults not specified.
-
- Fix %LOC(), LOC() to return sufficiently wide type:
- * com.h, com.c (ffecom_pointer_kind_, ffecom_label_kind_,
- ffecom_pointer_kind(), ffecom_label_kind()): New globals
- and accessor macros hold kind for integer pointers on target
- machine.
- (ffecom_init_0): Determine narrowest INTEGER type that
- can hold a pointer (usually INTEGER*4 or INTEGER*8),
- store it in ffecom_pointer_kind_, etc.
- * expr.c (ffeexpr_cb_end_loc_): Use right type for %LOC().
- * intrin.c (ffeintrin_check_, ffeintrin_init_0): Support
- new 'p' kind for type of intrinsic.
- * intrin.def (FFEINTRIN_impLOC): Returns "Ip" instead of "I1",
- so LOC() type is correct for target machine.
-
- Support -fugly-assign:
- * lang-options.h, top.h, top.c (ffe_decode_option):
- Accept -fugly-assign and -fno-ugly-assign.
- * com.c (ffecom_expr_): Handle -fugly-assign.
- * expr.c (ffeexpr_finished_): Check right type for ASSIGN
- contexts.
-
-Fri Jan 31 14:30:00 1997 Craig Burley <burley@gnu.ai.mit.edu>
-
- Remove last vestiges of -fvxt-not-f90:
- * stb.c (ffestb_R10012_, ffestb_R10014_, ffestb_V0201_):
- top.c, top.h:
-
-Fri Jan 31 02:13:54 1997 Craig Burley <burley@gnu.ai.mit.edu>
-
- * top.c (ffe_decode_option): Warn if -fugly is specified,
- it'll go away soon.
-
- * symbol.h: No need to #include "bad.h".
-
- Reorganize features from -fvxt-not-f90 to -fvxt:
- * lang-options.h, top.h, top.c:
- Accept -fvxt and -fno-vxt, but not -fvxt-not-f90 or -ff90-not-vxt.
- Warn if the latter two are used.
- * expr.c (ffeexpr_nil_rhs_): Double-quote means octal constant.
- (ffeexpr_token_rhs_): Double-quote means octal constant.
- * target.h (FFETARGET_defaultIS_VXT_NOT_90): Delete macro
- definition, no longer needed.
-
- Make some -ff90 features the default:
- * data.c (ffedata_value): DATA implies SAVE.
- * src.h (ffesrc_is_name_noninit): Underscores always okay.
-
- Fix up some more #error directives by quoting their text:
- * bld.c (ffebld_constant_is_zero):
- * target.h:
-
-Sat Jan 18 18:22:09 1997 Craig Burley <burley@gnu.ai.mit.edu>
-
- * g77.c (lookup_option, main): Recognize `-Xlinker',
- `-Wl,', `-l', `-L', `--library-directory', `-o',
- `--output'.
- (lookup_option): Don't depend on SWITCH_TAKES_ARG
- being correct, it might or might not have `-x' in
- it depending on host.
- Return NULL argument if it would be an empty string.
- (main): If no input files (by gcc.c's definition)
- but `-o' or `--output' specified, produce diagnostic
- to avoid overwriting output via gcc.
- Recognize C++ `+e' options.
- Treat -L as another non-magical option (like -B).
- Don't append_arg `-x' twice.
-
-Fri Jan 10 23:36:00 1997 Craig Burley <burley@gnu.ai.mit.edu>
-
- * top.c [BUILT_FOR_270] (ffe_decode_option): Make
- -fargument-noalias-global the default.
-
-Fri Jan 10 07:42:27 1997 Craig Burley <burley@gnu.ai.mit.edu>
-
- Enable inlining of previously-compiled program units:
- * com.c (ffecom_do_entry_, ffecom_start_progunit_):
- Register new public function in ffeglobal database.
- (ffecom_sym_transform_): Any GLOBAL or potentially GLOBAL
- symbol should be looked up in ffeglobal database and
- that tree node used, if found. That way, gcc knows
- the references are to those earlier definitions, so it
- can emit shorter branches/calls, inline, etc.
- (ffecom_transform_common_): Minor change for clarity.
- * expr.c (ffeexpr_sym-lhs_call_, ffeexpr_sym_lhs_extfunc_,
- ffeexpr_sym_rhs_actualarg_, ffeexpr_paren_rhs_let_,
- ffeexpr_token_funsubstr_): Globalize symbol as needed.
- * global.c (ffeglobal_promoted): New function to look up
- existing local symbol in ffeglobal database.
- * global.h: Declare new function.
- * name.h (ffename_token): New macro, plus alphabetize.
- * stc.c (ffestc_R1207_item): Globalize EXTERNAL symbol.
- * stu.c (ffestu_sym_end_transition, ffestu_sym_exec_transition):
- Globalize symbol as needed.
- * symbol.h, symbol.c (ffesymbol_globalize): New function.
-
-Thu Jan 9 14:20:00 1997 Craig Burley <burley@gnu.ai.mit.edu>
-
- * ste.c (ffeste_R809): Produce a diagnostic for SELECT CASE
- on CHARACTER type, instead of crashing.
-
-Thu Jan 9 00:52:45 1997 Craig Burley <burley@gnu.ai.mit.edu>
-
- * stc.c (ffestc_order_entry_, ffestc_order_format_,
- ffestc_R1226): Allow ENTRY and FORMAT before IMPLICIT
- NONE, by having them transition only to state 1 instead
- of state 2 (which is disallowed by IMPLICIT NONE).
-
-Mon Jan 6 22:44:53 1997 Craig Burley <burley@gnu.ai.mit.edu>
-
- Fix AXP bug found by Rick Niles (961201-1.f):
- * com.c (ffecom_init_0): Undo my 1996-05-14 change, as
- it is incorrect and prevented easily finding this bug.
- * target.h [__alpha__] (ffetargetReal1, ffetargetReal2):
- Use int instead of long.
- (ffetarget_cvt_r1_to_rv_, ffetarget_cvt_rv_to_r1_,
- ffetarget_cvt_r2_to_rv_, ffetarget_cvt_rv_to_r2_):
- New functions that intercede for callers of
- REAL_VALUE_(TO|UNTO)_TARGET_(SINGLE|DOUBLE).
- All callers changed, and damaging casts to (long *) removed.
-
-Sun Jan 5 03:26:11 1997 Craig Burley <burley@gnu.ai.mit.edu>
-
- * Make-lang.in (g77, g77-cross): Depend on both g77.c and
- zzz.c, in $(srcdir)/f/.
-
- Better design for -fugly-assumed:
- * stc.c (ffestc_R501_item, ffestc_R524_item,
- ffestc_R547_item_object): Pass new is_ugly_assumed flag.
- * stt.c, stt.h (ffestt_dimlist_as_expr,
- ffestt_dimlist_type): New is_ugly_assumed flag now
- controls whether "1" is treated as "*".
- Don't treat "2-1" or other collapsed constants as "*".
-
-Sat Jan 4 15:26:22 1997 Craig Burley <burley@gnu.ai.mit.edu>
-
- * stb.c (ffestb_R10012_): Don't confirm on FORMAT(A,)
- or even FORMAT(A,,B), as R1229 only warns about the
- former currently, and this seems reasonable.
-
- Improvements to diagnostics:
- * sta.c (ffesta_second_): Don't add any ffestb parsers
- unless they're specifically called for.
- Set up ffesta_tokens[0] before calling ffestc_exec_transition,
- else stale info might get used.
- (ffesta_save_): Do a better job picking which parser to run
- after running all parsers with no confirmed possibles.
- (FFESTA_maxPOSSIBLES_): Decrease from 100 now that so few
- possibles are ever on the list at a given time.
- (struct _ffesta_possible): Add named attribute.
- (ffesta_add_possible_exec_, ffesta_add_possible_nonexec_):
- Make these into macros that call a single function that now
- sets the named attribute.
- (ffesta_add_possible_unnamed_exec_,
- ffeseta_add_possible_unnamed_nonexec_): New macros.
- (ffesta_second_): Designate unnamed possibles as
- appropriate.
- * stb.c (ffestb_R1229, ffestb_R12291_): Use more general
- diagnostic, so things like "POINTER (FOO, BAR)" are
- diagnosed as unrecognized statements, not invalid statement
- functions.
- * stb.h, stb.c (ffestb_unimplemented): Remove function.
-
-1996-12-30 Dave Love <d.love@dl.ac.uk>
-
- * com.c: #include libU77/config.h
- (ffecom_f2c_ptr_to_integer_type_node,
- ffecom_f2c_ptr_to_integer_type_node): New variables.
- (ffecom_init_0): Use them.
- (ffecom_expr_intrinsic_): Many news cases for libU77 intrinsics.
-
- * com-rt.def: New definitions for libU77.
- * intrin.def: Likewise. Also correct ftell arg spec.
-
- * Makefile.in (f/runtime/libU77/config.h): New target for com.c
- dependency.
- * Make-lang.in (f771): Depend on f/runtime/Makefile for the above.
-
-Sat Dec 28 12:28:29 1996 Craig Burley <burley@gnu.ai.mit.edu>
-
- * stt.c (ffestt_dimlist_type): Treat ([...,]1) in dimlist
- as ([...,]*) if -fugly-assumed, so assumed-size array
- detected early enough.
-
-Thu Dec 19 14:01:57 1996 Craig Burley <burley@gnu.ai.mit.edu>
-
- * target.h (FFETARGET_REAL_VALUE_FROM_INT_): Conditionalize
- definition on BUILT_FOR_280, not BUILT_WITH_280, since
- the name of the macro was (properly) changed since 0.5.19.
-
- Fix warnings/errors resulting from ffetargetOffset becoming
- `long long int' instead of `unsigned long' as of 0.5.19,
- while ffebitCount remains `unsigned long':
- * bld.c (ffebld_constantarray_dump): Avoid warnings by
- using loop var of appropriate type, and using casts.
- * com.c (ffecom_expr_): Use right type for loop var.
- (ffecom_sym_transform_, ffecom_transform_equiv_):
- Cast to right type in assertions.
- * data.c (ffedata_gather_, ffedata_value_): Cast to right
- type in assertions and comparisons.
-
-Wed Dec 18 12:07:11 1996 Craig Burley <burley@gnu.ai.mit.edu>
-
- Patch from Alexandre Oliva <oliva@dcc.unicamp.br>:
- * Makefile.in (all.indirect): Don't pass -bbigtoc option
- to GNU ld.
-
- Cope with new versions of gcc:
- * com.h (BUILT_FOR_280): New macro.
- * com.c (ffecom_ptr_to_expr): Conditionalize test of
- OFFSET_REF.
- (ffecom_build_complex_constant_): Conditionalize calling
- sequence for build_complex.
-
-Sat Dec 7 07:15:17 1996 Craig Burley <burley@gnu.ai.mit.edu>
-
- * Version 0.5.19 released.
-
-Fri Dec 6 12:23:55 1996 Craig Burley <burley@gnu.ai.mit.edu>
-
- * g77.c: Default to assuming "f77" is in $LANGUAGES, since
- the LANGUAGE_F77 macro isn't defined by anyone anymore (but
- might as well leave the no-f77 code in just in case).
- * Make-lang.in (g77, g77-cross): Don't define LANGUAGE_F77
- anymore.
-
-1996-12-06 Dave Love <d.love@dl.ac.uk>
-
- * Make-lang.in (g77, g77-cross): Revert to building `g77' or not
- conditional on `f77' in LANGUAGES.
-
-Wed Dec 4 13:08:44 1996 Craig Burley <burley@gnu.ai.mit.edu>
-
- * Make-lang.in (g77, g77-cross): No libs or lib dependencies
- in case where "f77" is not in $LANGUAGES.
-
- * lex.c (ffelex_image_char_, ffelex_file_fixed,
- ffelex_file_free): Fixes to properly handle lines with
- null character, and too-long lines as well.
-
- * lex.c: Call ffebad_start_msg_lex instead of
- ffebad_start_msg throughout.
-
-Sun Dec 1 21:19:55 1996 Craig Burley <burley@gnu.ai.mit.edu>
-
- Fix-up for 1996-11-25 changes:
- * com.c (ffecom_member_phase2_): Subtract out 0 offset for
- elegance and consistency with EQUIVALENCE aggregates.
- (ffecom_sym_transform_): Ditto for LOCAL/COMMON, and
- ensure we get the same parent storage area.
- * data.c (ffedata_gather_, ffedata_value_): Subtract out
- aggregate offset.
-
-Wed Nov 27 13:55:57 1996 Craig Burley <burley@gnu.ai.mit.edu>
-
- * proj.h: Quote the text of the #error message, to avoid
- strange-looking diagnostics from non-gcc ANSI compilers.
-
- * top.c: Make -fno-debug-kludge the default.
-
-Mon Nov 25 20:13:45 1996 Craig Burley <burley@gnu.ai.mit.edu>
-
- Provide more info on EQUIVALENCE mismatches:
- * bad.def (FFEBAD_EQUIV_MISMATCH): More detailed message.
- * equiv.c (ffeequiv_layout_local_, ffeequiv_layout_cblock):
- More details for FFEBAD_EQUIV_MISMATCH.
-
- Fix problem with EQUIVALENCE handling:
- * equiv.c (ffeequiv_layout_local_): Redesign algorithm --
- old one was broken, resulting in rejection of good code.
- (ffeequiv_offset_): Add argument, change callers.
- Clean up the code, fix up the (probably unused) negative-value
- case for SYMTER.
- * com.c (ffecom_sym_transform_): For local EQUIVALENCE
- member, subtract out aggregate offset (which is <= 0).
-
-Thu Nov 21 12:44:56 1996 Craig Burley <burley@gnu.ai.mit.edu>
-
- Change type of ffetargetOffset from `unsigned long' to `long long':
- * bld.c (ffebld_constantarray_dump): Change printf formats.
- * storag.c (ffestorag_dump): Ditto.
- * symbol.c (ffesymbol_report): Ditto.
- * target.h (ffetargetOffset_f): Ditto and change type itself.
-
- Handle situation where list of languages does not include f77:
- * Make-lang.in: Define LANGUAGE_F77 to 1 only if `f77' is in
- the $LANGUAGES macro for the build.
- * g77.c: Compile to a (nearly) no-op program if LANGUAGE_F77
- is not defined to 1.
-
- Fixes to delay confirmation of READ, WRITE, and GOTO statements
- so the corresponding assignments to same-named CHAR*(*) arrays
- work:
- * stb.c (ffestb_R90915_, ffestb_91014_): New functions.
- (ffestb_goto3_, ffestb_goto5_): Move confirmation from 3 to 5
- for the OPEN_PAREN case.
- (ffestb_R9091_, ffestb_R9094_, ffestb_R90913_, ffestb_R90914_,
- ffestb_R91012_, ffestb_R91013_): Use new functions, and confirm
- except for the OPEN_PAREN case.
-
- Fixes to not confirm declarations with an open paren where
- an equal sign or other assignment-like token might be, so the
- corresponding assignments to same-named CHAR*(*) arrays work:
- (ffestb_decl_entsp_5_): Move assertion so we crash on that first,
- if it turns out to be wrong, before the less-debuggable crash
- on mistaken confirmation.
- (ffestb_decl_entsp_6_, ffestb_decl_entsp_7_, ffestb_decl_entsp_8_):
- Include OPEN_PAREN in list of assignment-only tokens.
-
- Fix more diagnosed-crash bugs:
- * stu.c (ffestu_sym_end_transition): ANY-ize an adjustable array
- with bad dimension expressions even if still stateUNCERTAIN.
- (ffestu_symter_end_transition_, ffestu_symter_exec_transition_):
- Return TRUE for opANY as well.
- For code elegance, move opSYMTER case into first switch.
-
-1996-11-17 Dave Love <d.love@dl.ac.uk>
-
- * lex.c: Fix last change.
-
-1996-11-14 Dave Love <d.love@dl.ac.uk>
-
- * Make-lang.in, config-lang.in: Remove the (broken) libU77 stuff,
- pending 0.5.20.
-
-Thu Nov 14 15:40:59 1996 Craig Burley <burley@gnu.ai.mit.edu>
-
- * bad.def (FFEBAD_UNIMPL_STMT): Explain that invalid
- intrinsic references can trigger this message, too.
-
-1996-11-12 Dave Love <d.love@dl.ac.uk>
-
- * lex.c: Declare dwarfout routines.
-
- * config-lang.in: Sink grep o/p.
-
-Mon Nov 11 14:21:13 1996 Craig Burley <burley@gnu.ai.mit.edu>
-
- * g77.c (main): Might as well print version number
- for --verbose as well.
-
-Thu Nov 7 18:41:41 1996 Craig Burley <burley@gnu.ai.mit.edu>
-
- * expr.c, lang-options.h, target.h, top.c, top.h: Split out
- remaining -fugly stuff into -fugly-logint and -fugly-comma,
- leaving -fugly as simply a `macro' that expands into other
- options, and eliminate defaults for some of the ugly stuff
- in target.h.
-
- * Make-lang.in (gcc-cross): Compile zzz.c, not version.o (!),
- in to get version info for this target.
-
- * config-lang.in: Test for GBE patch application based
- on whether 2.6.x or 2.7.x GBE is detected.
-
-Wed Nov 6 14:19:45 1996 Craig Burley <burley@gnu.ai.mit.edu>
-
- * Make-lang.in (g77): Compile zzz.c in to get version info.
- * g77.c: Add support for --help and --version.
-
- * g77.c (lookup_option): Short-circuit long-winded tests
- when second char is not hyphen, just to save a spot of time.
-
-Sat Nov 2 13:50:31 1996 Craig Burley <burley@gnu.ai.mit.edu>
-
- * intrin.def: Add FTELL and FSEEK intrinsics, plus new
- `g' codes for alternate-return (GOTO) arguments.
- * intrin.c (ffeintrin_check_): Support `g' codes.
- * com-rt.def: Add ftell_() and fseek_() to database.
- * com.c (ffecom_expr_intrinsic_): Ditto. Also, let each
- subroutine intrinsic decide for itself what to do with
- tree_type, the default being NULL_TREE once again (so
- ffecom_call_ doesn't think it's supposed to cast the
- function call to the type in the fall-through case).
-
- * ste.c (ffeste_R909_finish): Don't special-case list-directed
- I/O, now that libf2c can return non-zero status codes.
- (ffeste_R910_finish): Ditto.
- (ffeste_io_call_): Simplify logic.
- (ffeste_io_impdo_):
- (ffeste_subr_beru_):
- (ffeste_R904):
- (ffeste_R907):
- (ffeste_R909_start):
- (ffeste_R909_item):
- (ffeste_R909_finish):
- (ffeste_R910_start):
- (ffeste_R910_item):
- (ffeste_R910_finish):
- (ffeste_R911_start):
- (ffeste_R923A): Ditto all the above.
-
-Thu Oct 31 20:56:28 1996 Craig Burley <burley@gnu.ai.mit.edu>
-
- * config-lang.in, Make-lang.in: Rename flag file
- build-u77 to build-libu77, for consistency with
- install-libf2c and such.
-
- * config-lang.in: Don't complain about failure to patch
- if pre-2.7.0 gcc is involved (since our patch for that
- doesn't add support for tooning).
-
-Sat Oct 26 05:56:51 1996 Craig Burley <burley@gnu.ai.mit.edu>
-
- * bad.def (FFEBAD_TYPELESS_TOO_LARGE): Remove this
- unused and redundant diagnostic.
-
-Sat Oct 26 00:45:42 1996 Craig Burley <burley@gnu.ai.mit.edu>
-
- * target.c (ffetarget_integerhex): Fix dumb bug.
-
-1996-10-20 Dave Love <d.love@dl.ac.uk>
-
- * gbe/2.7.2.1.diff: New file.
-
- * Makefile.in (F771_LDFLAGS): Add -bbigtoc for AIX4.1 up, suggested by
- endo@material.tohoku.ac.jp [among others!].
-
-Sat Oct 19 03:11:14 1996 Craig Burley <burley@gnu.ai.mit.edu>
-
- * bad.def, bld.c, bld.h, expr.c, lang-options.h, target.c,
- target.h, top.c, top.h (ffebld_constant_new_integerbinary,
- ffebld_constant_new_integerhex, ffebld_constant_new_integeroctal,
- ffeexpr_token_name_apos_name_, ffetarget_integerbinary,
- ffetarget_integerhex, ffetarget_integeroctal): Support
- new -fno-typeless-boz option with new functions, mods to
- existing octal-handling functions, new macros, new error
- messages, and so on.
-
- * com.c, lang-options.h, top.c, top.h (ffecom_notify_primary_entry):
- Print program unit name on stderr if -fno-silent (new option).
-
- * lang-options.h, top.c, top.h, stt.c (ffestt_dimlist_as_expr):
- Treat ([...,]1) in dimlist as ([...,]*) if -fugly-assumed
- (new option).
-
- * lang-options.h: Comment out options duplicated in gcc/toplev.c,
- because, somehow, having them commented in and building on my
- DEC Alpha results in a cc1 that always segfaults, and gdb that
- also segfaults whenever it debugs it up to init_lex() calling
- xmalloc() or so.
-
-Thu Oct 17 00:39:27 1996 Craig Burley <burley@gnu.ai.mit.edu>
-
- * stb.c (ffestb_R10013_): Don't change meaning of .sign until
- after previous meaning/value used to set sign of value
- (960507-1.f).
-
-Sun Oct 13 22:15:23 1996 Craig Burley <burley@gnu.ai.mit.edu>
-
- * top.c (ffe_decode_option): Don't set back-end flags
- that are nonexistent prior to gcc 2.7.0.
-
-Sun Oct 13 12:48:45 1996 Craig Burley <burley@gnu.ai.mit.edu>
-
- * com.c (convert): Don't convert emulated complex expr to
- real (via REALPART_EXPR) if the target type is (emulated)
- complex.
-
-Wed Oct 2 21:57:12 1996 Craig Burley <burley@gnu.ai.mit.edu>
-
- * com.c (ffecom_debug_kludge_): Set DECL_IN_SYSTEM_HEADER so
- -Wunused doesn't complain about these manufactured decls.
- (ffecom_expr_): Ditto, for original (non-ASSIGN'ed) variable.
- (ffecom_transform_equiv_): Clear DECL_IGNORED_P for aggregate
- area so it shows up as a debug-accessible symbol.
- (pushdecl): Default for "invented" identifiers (a g77-specific
- concept for now) is that they are artificial, in system header,
- ignored for debugging purposes, used, and (for types) suppressed.
- This ought to be overkill.
-
-Fri Sep 27 23:13:07 1996 Craig Burley <burley@gnu.ai.mit.edu>
-
- * ste.c (ffeste_begin_iterdo_, ffeste_end_iterdo_): Support
- one-trip DO loops (F66-style).
- * lang-options.h, top.c, top.h (-fonetrip): New option.
-
-Thu Sep 26 00:18:40 1996 Craig Burley <burley@gnu.ai.mit.edu>
-
- * com.c (ffecom_debug_kludge_): New function.
- (ffecom_sym_transform_): Use new function for COMMON and EQUIVALENCE
- members.
-
- * lang-options.h, top.c, top.h (-fno-debug-kludge):
- New option.
-
-1996-09-24 Dave Love <d.love@dl.ac.uk>
-
- * Make-lang.in (include/f2c.h):
- Remove dependencies on xmake_file and tmake_file.
- They expand inconsistently in 2.8 c.f. 2.7; $(GCC_PARTS) depends on
- them anyhow.
-
-1996-09-22 Dave Love <d.love@dl.ac.uk>
-
- * config-lang.in: Add --enable-libu77 option handling.
-
- * Make-lang.in:
- Conditionally add --enable-libu77 when running runtime configure.
- Define LIBU77STAGESTUFF and use it in relevant rules.
-
-1996-08-21 Dave Love <d.love@dl.ac.uk>
-
- * Make-lang.in (f77-runtime):
- `stmp-hdrs' should have been `stmp-headers'.
-
-1996-08-20 Dave Love <d.love@dl.ac.uk>
-
- * Make-lang.in (f77-runtime):
- Depend on stmp-hdrs, not stmp-int-hdrs, since libF77
- needs float.h.
-
-Sat Jun 22 18:17:11 1996 Craig Burley <burley@gnu.ai.mit.edu>
-
- * com.c (ffecom_tree_divide_): Fix RECORD_TYPE case to
- look at type of first field, properly, to determine
- whether to call c_div or z_div.
-
-Tue Jun 4 04:27:18 1996 Craig Burley <burley@gnu.ai.mit.edu>
-
- * com.c (ffecom_build_complex_constant_): Explicitly specify
- TREE_PURPOSE.
- (ffecom_expr_): Fix thinko.
- (ffecom_2): For COMPLEX_EXPR, explicitly specify TREE_PURPOSE.
-
-Mon May 27 16:23:43 1996 Craig Burley <burley@gnu.ai.mit.edu>
-
- Changes to optionally avoid gcc's back-end complex support:
- * com.c (ffecom_stabilize_aggregate_): New function.
- (ffecom_convert_to_complex_): New function.
- (ffecom_make_complex_type_): New function.
- (ffecom_build_complex_constant_): New function.
- (ffecom_expr_): For opCONVERT of non-COMPLEX to COMPLEX,
- don't bother explicitly converting to the subtype first,
- because gcc does that anyway, and more code would have
- to be added to find the subtype for the emulated-complex
- case.
- (ffecom_f2c_make_type_): Use ffecom_make_complex_type_
- instead of make_node etc. to make a complex type.
- (ffecom_1, ffecom_2): Translate operations on COMPLEX operands
- to appropriate operations when emulating complex.
- (ffecom_constantunion): Use ffecom_build_complex_constant_
- instead of build_complex to build a complex constant.
- (ffecom_init_0): Change point at which types are laid out
- for improved consistency.
- Use ffecom_make_complex_type_ instead of make_node etc.
- to make a complex type.
- Always calculate storage sizes from TYPE_SIZE, never TYPE_PRECISION.
- (convert): Use e, not expr, since we've copied into that anyway.
- For RECORD_TYPE cases, do emulated-complex conversions.
- (ffecom_f2c_set_lio_code_): Always calculate storage sizes
- from TYPE_SIZE, never TYPE_PRECISION.
- (ffecom_tree_divide_): Allow RECORD_TYPE to also be handled
- by run-time library.
- (ffecom_expr_intrinsic_): Handle possible RECORD_TYPE as argument
- to AIMAG intrinsic.
-
- * top.h, top.c, lang-options.h: Support new -f(no-)emulate-complex option.
-
- * com.c (ffecom_sym_transform_): Clarify and fix typos in comments.
-
-Mon May 20 02:06:27 1996 Craig Burley <burley@gnu.ai.mit.edu>
-
- * target.h: Use new REAL_VALUE_UNTO_TARGET_* macros instead
- of REAL_VALUE_FROM_TARGET_DOUBLE and _SINGLE.
- Explicitly use long instead of HOST_WIDE_INT for emulation
- of ffetargetReal1 and ffetargetReal2.
-
-1996-05-20 Dave Love <d.love@dl.ac.uk>
-
- * config-lang.in:
- Test for patch being applied with flag_move_all_movables in toplev.c.
-
- * install.texi (Patching GNU Fortran):
- Mention overriding X_CFLAGS rather than
- editing proj.h on SunOS4.
-
- * Make-lang.in (F77_FLAGS_TO_PASS):
- Add X_CFLAGS (convenient for SunOS4 kluge, in
- particular).
- (f77.{,mostly,dist}clean): Reorder things, in particular not to delete
- Makefiles too early.
-
- * g77.c (DEFAULT_SWITCH_TAKES_ARG): Define a la gcc.c in the
- current GCC snapshot.
-
-Tue May 14 00:24:07 1996 Craig Burley <burley@gnu.ai.mit.edu>
-
- Changes for DEC Alpha AXP support:
- * com.c (ffecom_init_0): REAL_ARITHMETIC means internal
- REAL/DOUBLE PRECISION might well have a different size
- than the compiled type, so don't crash if this is the
- case.
- * target.h: Use `int' for ffetargetInteger1,
- ffetargetLogical1, and magical tests. Set _f format
- strings accordingly.
-
-Tue Apr 16 14:08:28 1996 Craig Burley <burley@gnu.ai.mit.edu>
-
- * top.c (ffe_decode_option): -Wall no longer implies
- -Wsurprising.
-
-Sat Apr 13 14:50:06 1996 Craig Burley <burley@gnu.ai.mit.edu>
-
- * com.c (ffecom_char_args_): If item is error_mark_node,
- set *length that way, too.
-
- * com.c (ffecom_expr_power_integer_): If either operand
- is error_mark_node, return that.
-
- * com.c (ffecom_intrinsic_len_): If item is error_mark_node,
- return that for length.
-
- * expr.c (ffeexpr_declare_unadorned_,
- ffeexpr_declare_parenthesized_): Instead of crashing
- on unexpected contexts, produce a diagnostic.
-
- * intrin.c (ffeintrin_check_), intrin.def (impSIGNAL):
- Allow procedure as second arg to SIGNAL intrinsic.
-
- * stu.c (ffestu_symter_end_transition_): New function.
- (ffestu_symter_exec_transition_): Return bool arg.
- Always transition symbol (don't inhibit when !whereNONE).
- (ffestu_sym_end_transition): If DUMMY/LOCAL arg has any
- opANY exprs in its dimlist, diagnose it so it doesn't
- make it through to later stages that try to deal with
- dimlist stuff.
- (ffestu_sym_exec_transition): If sym has any opANY exprs
- in its dimlist, diagnose it so it becomes opANY itself.
-
- * symbol.c (ffesymbol_error): If token arg is NULL,
- just ANY-ize the symbol -- don't produce diagnostic.
-
-Mon Apr 1 10:14:02 1996 Craig Burley <burley@gnu.ai.mit.edu>
-
- * Version 0.5.18 released.
-
-Mon Mar 25 20:52:24 1996 Craig Burley <burley@gnu.ai.mit.edu>
-
- * com.c (ffecom_expr_power_integer_): Don't generate code
- that compares COMPLEX (or, as it happens, REAL) via "LT_EXPR",
- since the back end crashes on that. (This code would never
- be executed anyway, but the test that avoids it has now been
- translated to control whether the code gets generated at all.)
- Fixes 960323-3.f.
-
- * com.c (ffecom_type_localvar_): Handle variable-sized
- dimension bounds expressions here, so they get calculated
- and saved on procedure entry. Fixes 960323-4.f.
-
- * com.c (ffecom_notify_init_symbol): Symbol has no init
- info at all if only zeros have been used to initialize it.
- Fixes 960324-0.f.
-
- * expr.c, expr.h (ffeexpr_type_combine): Renamed from
- ffeexpr_type_combine_ and now a public procedure; last arg now
- a token, instead of an internal structure used to extract a token.
- Now allows the outputs to be aliased with the inputs.
- Now allows a NULL token to mean "don't report error".
- (ffeexpr_reduced_bool2_, ffeexpr_reduced_eqop2_,
- ffeexpr_reduced_math2_, ffeexpr_reduced_power_,
- ffeexpr_reduced_relop2_): Handle new calling sequence for
- ffeexpr_type_combine.
- * (ffeexpr_convert): Don't put an opCONVERT node
- in just because the size is unknown; all downstream code
- should be able to deal without it being there anyway, and
- getting rid of it allows new intrinsic code to more easily
- combine types and such without generating bad code.
- * info.c, info.h (ffeinfo_kindtype_max): Rewrite to do
- proper comparison of size of types, not just comparison
- of their internal kind numbers (so I2.eq.I1 doesn't promote
- I1 to I2, rather the other way around).
- * intrin.c (ffeintrin_check_): Combine types of arguments
- in COL a la expression handling, for greater flexibility
- and permissiveness (though, someday, -fpedantic should
- report use of this kind of thing).
- Make sure Hollerith/typeless where CHARACTER expected is
- rejected. This all fixes 960323-2.f.
-
- * ste.c (ffeste_begin_iterdo_): Fix some more type conversions
- so INTEGER*2-laden DO loops don't crash at compile time on
- certain machines. Believed to fix 960323-1.f.
-
- * stu.c (ffestu_sym_end_transition): Certainly reject
- whereDUMMY not in any dummy list, whether stateUNCERTAIN
- or stateUNDERSTOOD. Fixes 960323-0.f.
-
-Tue Mar 19 13:12:40 1996 Craig Burley <burley@gnu.ai.mit.edu>
-
- * data.c (ffedata_value): Fix crash on opANY, and simplify
- the code at the same time.
-
- * Make-lang.in (f77-runtime): Also depends on lib[FI]77/Makefile...
- (include/f2c.h...): ...which in turn depend on */Makefile.in.
- (f77.rebuilt): Rebuild runtime stuff too.
-
- * intrin.c (ffeintrin_check_): Accommodate TYPELESS/HOLLERITH
- types, convert args as necessary, etc.
-
- * expr.c (ffeexpr_convert): Fix test for TYPELESS/HOLLERITH
- to obey the docs; crash if no source token when error.
- (ffeexpr_collapse_convert): Crash if no token when error.
-
-Mon Mar 18 15:51:30 1996 Craig Burley <burley@gnu.ai.mit.edu>
-
- * com.c (ffecom_init_zero_): Renamed from
- ffecom_init_local_zero_; now handles top-level
- (COMMON) initializations too.
-
- * bld.c (ffebld_constant_is_zero):
- * com.c (ffecom_symbol_transform_, ffecom_sym_transform_assign_,
- ffecom_transform_common_, ffecom_transform_equiv_):
- * data.c:
- * equiv.c:
- * equiv.h:
- * lang-options.h:
- * stc.c:
- * storag.c:
- * storag.h:
- * symbol.c:
- * symbol.h:
- * target.c:
- * target.h:
- * top.c:
- * top.h: All of this is mostly housekeeping-type changes
- to support -f(no-)zeros, i.e. not always stuff zero
- values into the initializer fields of symbol/storage objects,
- but still track that they have been given initial values.
-
- * bad.def: Fix wording for DATA-related diagnostics.
-
- * com.c (ffecom_sym_transform_assign_): Don't check
- any EQUIVALENCE stuff for local ASSIGN, the check was
- bad (crashing), and it's not necessary, anyway.
-
- * com.c (ffecom_expr_intrinsic_): For MAX and MIN,
- ignore null arguments as far arg[123], and fix handling
- of ANY arguments. (New intrinsic support now allows
- spurious trailing null arguments.)
-
- * com.c (ffecom_init_0): Add HOLLERITH (unsigned)
- equivalents for INTEGER*2, *4, and *8, so shift intrinsics
- and other things that need unsigned versions of signed
- types work.
-
-Sat Mar 16 12:11:40 1996 Craig Burley <burley@gnu.ai.mit.edu>
-
- * storag.c (ffestorag_exec_layout): Treat adjustable
- local array like dummy -- don't create storage object.
- * com.c (ffecom_sym_transform_): Allow for NULL storage
- object in LOCAL case (adjustable array).
-
-Fri Mar 15 13:09:41 1996 Craig Burley <burley@gnu.ai.mit.edu>
-
- * com.c (ffecom_sym_transform_): Allow local symbols
- with nonconstant sizes (adjustable local arrays).
- (ffecom_type_localvar_): Allow dimensions with nonconstant
- component (adjustable local arrays).
- * expr.c: Various minor changes to handle adjustable
- local arrays (a new case of stateUNCERTAIN).
- * stu.c (ffestu_sym_end_transition,
- ffestu_sym_exec_transition): Ditto.
- * symbol.def: Update docs to reflect these changes.
-
- * com.c (ffecom_expr_): Reduce space/time needed for
- opACCTER case by handling it here instead of converting
- it to opARRTER earlier on.
- (ffecom_notify_init_storage): Don't convert ACCTER to ARRTER.
- (ffecom_notify_init_symbol): Ditto.
-
- * com.c (ffecom_init_0): Crash and burn if any of the types'
- sizes, according to the GBE, disagrees with the sizes of
- the FFE's internal implementation. This might catch
- Alpha/SGI bugs earlier.
-
-Fri Mar 15 01:09:41 1996 Craig Burley <burley@gnu.ai.mit.edu>
-
- * com-rt.def, com.c, com.h: Changes for rewrite of intrinsic
- handling.
- * com.c (ffecom_arglist_expr_): New function.
- (ffecom_widest_expr_type_): New function.
- (ffecom_expr_intrinsic_): Reorganize, some rewriting.
- (ffecom_f2c_make_type_): Layout complex types.
- (ffecom_gfrt_args_): New function.
- (ffecom_list_expr): Trivial change for consistency.
-
- * expr.c (ffeexpr_token_name_rhs_): Go back to getting
- type from specific, not implementation, info.
- (ffeexpr_token_funsubstr_): Set intrinsic implementation too!
- * intrin.c: Major rewrite of most portions.
- * intrin.def: Major rearchitecting of tables.
- * intrin.h (ffeintrin_basictype, ffeintrin_kindtype):
- Now (once again) take ffeintrinSpec as arg, not ffeintrinImp;
- for now, these return NONE, since they're not really needed
- and adding the necessary info to the tables is not trivial.
- (ffeintrin_codegen_imp): New function.
- * stc.c (ffestc_R1208_item): Change way ffeintrin funcs called,
- back to original per above; but comment out the code anyway.
-
- * intrin.c (ffe_init_0): Do internal checks only if
- -fset-g77-defaults not specified.
-
- * lang-options.h: Add -fset-g77-defaults option.
- * lang-specs.h: Always pass -fset-g77-defaults.
- * top.c, top.h: New option.
-
-Sat Mar 9 17:49:50 1996 Craig Burley <burley@gnu.ai.mit.edu>
-
- * Make-lang.in (stmp-int-hdrs): Use --no-validate when
- generating the f77.rebuilt files (BUGS, INSTALL, NEWS)
- so cross-references can work properly in g77.info
- without a lot of hassle. Users can probably deal with
- the way they end up looking in the f77.rebuilt files.
-
- * bld.c (ffebld_constant_new_integer4_val): INTEGER*8
- support -- new function.
- (ffebld_constant_new_logical4_val): New function.
- * com.c (ffecom_f2c_longint_type_node): New type.
- (FFECOM_rttypeLONGINT_): New return type code.
- (ffecom_expr_): Add code to invoke pow_qq instead
- of pow_ii for INTEGER4 (INTEGER*8) case.
- If ffecom_expr_power_integer_ returns NULL_TREE, just do
- the usual work.
- (ffecom_make_gfrt_): Handle new type.
- (ffecom_expr_power_integer_): Let caller do the work if in
- dummy-transforming case, since
- caller now knows about INTEGER*8 and such, by returning
- NULL_TREE.
- * expr.c (ffeexpr_reduced_power_): Complain about non-INTEGER
- raised to INTEGER4 (INTEGER*8) power.
-
- * target.c (ffetarget_power_integerdefault_integerdefault):
- Fix any**negative.
- * com.c (ffecom_expr_power_integer_): Fix (-1)**(-8) and similar
- to ABS() the integral result if the exponent is negative
- and even.
-
- * ste.c (ffeste_begin_iterdo_): Clean up a type ref.
- Always convert iteration count to _default_ INTEGER.
-
- * sta.c (ffesta_second_): Add BYTE and WORD type/stmts;
- changes by Scott Snyder <snyder@d0sgif.fnal.gov>.
- * stb.c (ffestb_decl_recursive): Ditto.
- (ffestb_decl_recursive): Ditto.
- (ffestb_decl_entsp_2_): Ditto.
- (ffestb_decl_entsp_3_): Ditto.
- (ffestb_decl_funcname_2_): Ditto.
- (ffestb_decl_R539): Ditto.
- (ffestb_decl_R5395_): Ditto.
- * stc.c (ffestc_establish_declstmt_): Ditto.
- * std.c (ffestd_R539item): Ditto.
- (ffestd_R1219): Ditto.
- * stp.h: Ditto.
- * str-1t.fin: Ditto.
- * str-2t.fin: Ditto.
-
- * expr.c (ffeexpr_finished_): For DO loops, allow
- any INTEGER type; convert LOGICAL (assuming -fugly)
- to corresponding INTEGER type instead of always default
- INTEGER; let later phases do conversion of DO start,
- end, incr vars for implied-DO; change checks for non-integral
- DO vars to be -Wsurprising warnings.
- * ste.c (ffeste_io_impdo_): Convert start, end, and incr
- to type of DO variable.
-
- * com.c (ffecom_init_0): Add new types for [IL][234],
- much of which was done by Scott Snyder <snyder@d0sgif.fnal.gov>.
- * target.c: Ditto.
- * target.h: Ditto.
-
-Wed Mar 6 14:08:45 1996 Craig Burley <burley@gnu.ai.mit.edu>
-
- * top.c (ffe_init_gbe_): Make -frerun-loop-opt the default.
-
-Mon Mar 4 12:27:00 1996 Craig Burley <burley@gnu.ai.mit.edu>
-
- * expr.c (ffeexpr_exprstack_push_unary_): Really warn only
- about two successive _arithmetic_ operators.
-
- * stc.c (ffestc_R522item_object): Allow SAVE of (understood)
- local entity.
-
- * top.c (ffe_decode_option): New -f(no-)second-underscore options.
- * top.h: New options.
- * com.c (ffecom_get_external_identifier_, ffecom_get_identifier_):
- New options.
-
- * Make-lang.in (f77.maintainer-clean): Clean f/BUGS, f/INSTALL,
- f/NEWS.
- ($(srcdir)/f/BUGS, $(srcdir)/f/INSTALL, $(srcdir)/f/NEWS):
- New rules.
- ($(srcdir)/f/g77.info, $(srcdir)/f/g77.dvi): Depend on
- f/bugs.texi and f/news.texi.
- (f77.install-man): Install f77 man pages (if enabled).
- (f77.uninstall): Uninstall info docs, f77 man pages (if enabled).
-
- * top.c (ffe_init_gbe_): New function.
- (ffe_decode_option, ffe_file): Call ffe_init_gbe_ to
- set defaults for gcc options.
-
-Sat Jan 20 13:57:19 1996 Craig Burley <burley@gnu.ai.mit.edu>
-
- * com.c (ffecom_get_identifier_): Eliminate needless
- comparison of results of strchr.
-
-Tue Dec 26 11:41:56 1995 Craig Burley <burley@gnu.ai.mit.edu>
-
- * Make-lang.in: Add rules for new files g77.texi, g77.info,
- and g77.dvi.
- Reorganize the *clean rules to more closely parallel gcc's.
-
- * config-lang.in: Exclude g77.info from diffs.
-
-Sun Dec 10 02:29:13 1995 Craig Burley <burley@gnu.ai.mit.edu>
-
- * expr.c (ffeexpr_declare_unadorned_,
- ffeexpr_declare_parenthesized_): Break out handling of
- contextDATAIMPDO[INDEX,CTRL] so it's independent of symbol state.
- Don't exec-transition these here (let ffeexpr_sym_impdoitem_
- handle that when appropriate). Don't "declare" them twice.
-
-Tue Dec 5 06:48:26 1995 Craig Burley <burley@gnu.ai.mit.edu>
-
- * stc.c (ffestc_promote_sfdummy_): Allow whereNONE parent
- symbol, since it is not necessarily known whether it will
- become LOCAL or DUMMY.
-
-Mon Dec 4 03:46:55 1995 Craig Burley <burley@gnu.ai.mit.edu>
-
- * lex.c (ffelex_display_token, ffelex_type_string_): Resurrect
- these from their old versions and update them for possible invocation
- from debugger.
- * lex.h (ffelex_display_token): Declare this in case anyone
- else wants to call it.
-
- * lex.c (ffelex_total_tokens_): Have this reflect actual allocated
- tokens, no longer include outstanding "uses" of tokens.
-
- * malloc.c, malloc.h (MALLOC_DEBUG): New macro to control
- checking of whether callers follow rules, now defaults to 0
- for "no checking" to improve compile times.
-
- * malloc.c (malloc_pool_kill): Fix bug that could prevent
- subpool from actually being killed (wasn't setting its use
- count to 1).
-
- * proj.h, *.c (dmpout): Replace all occurrences of `stdout'
- and some of `stderr' with `dmpout', so where to dump debugging
- output can be easily controlled during build; add default
- for `dmpout' of `stderr' to proj.h.
-
-Sun Dec 3 00:56:29 1995 Craig Burley <burley@gnu.ai.mit.edu>
-
- * com.c (ffecom_return_expr): Eliminate attempt at warning
- about unset return values, since the back end does this better,
- with better wording, and is not triggered by clearly working
- (but spaghetti) code as easily as this test.
-
-Sat Dec 2 08:28:56 1995 Craig Burley <burley@gnu.ai.mit.edu>
-
- * target.c (ffetarget_power_*_integerdefault): Raising 0 to
- integer constant power should not be an error condition;
- if so, other code should catch 0 to any power, etc.
-
- * bad.def (FFEBAD_BAD_POWER): 0**integer now a warning instead
- of an error.
-
-Fri Dec 1 00:12:03 1995 Craig Burley (burley@gnu.ai.mit.edu)
-
- * bad.def: Clarify diagnostic regarding complex constant elements.
- * expr.c (ffeexpr_cb_comma_c_): Capitalize real/imaginary
- for clarified diagnostic.
-
- * com.c (ffecom_close_include_): Close the file!
-
- * lex.c (ffelex_file_fixed): Update line info if the line
- has any content, not just if it finishes a previous line
- or has a label.
- (ffelex_file_free): Clarify switch statement code.
-
-Sat Nov 18 19:37:22 1995 Craig Burley (burley@gnu.ai.mit.edu)
-
- * Version 0.5.17 released.
-
-Fri Nov 17 14:27:24 1995 Craig Burley (burley@gnu.ai.mit.edu)
-
- * Make-lang.in: Fix typo in comment.
-
- * Makefile.in (f/fini.o, f/proj-h.o): Don't use `$<' since
- not all makes support it (e.g. NeXT make), use explicit
- source name instead (with $(srcdir) and munging).
- (ASSERT_H): assert.h lives in source dir, not build dir.
-
-Thu Nov 16 12:47:50 1995 Craig Burley (burley@gnu.ai.mit.edu)
-
- * com.c (ffecom_init_0): Fix dumb bug in code to produce
- warning message about non-32-bit-systems.
-
- * stc.c (ffestc_R501_item): Parenthesize test to make
- warning go away (and perhaps fix bug).
-
-Thu Nov 16 03:43:33 1995 Craig Burley (burley@gnu.ai.mit.edu)
-
- * g77.c: Upgrade to 2.7.0's gcc.c.
- Fix -v to pass a temp name instead of "/dev/null" for "-o".
-
-Fri Nov 10 19:16:05 1995 Craig Burley (burley@gnu.ai.mit.edu)
-
- * ste.c (ffeste_begin_iterdo_): Add Toon's change to
- make loops faster on some machines (implement termination
- condition as "--i >= 0" instead of "i-- > 0").
-
-Thu Nov 2 03:58:17 1995 Craig Burley (burley@gnu.ai.mit.edu)
-
- * Make-lang.in: Remove unnecessary $(exeext) a la cp/Make-lang.in.
-
- * com.c (ffecom_expr_): Restore old strategy for assignp variant
- of opSYMTER case...always return the ASSIGN version of var.
- That way, `-O -Wuninitialized' will catch "I=3;GOTO I;END"
- (though the diagnostic will refer to `__g77_ASSIGN_i').
-
- * com.c (ffecom_expr_power_integer_): For constant rhs case,
- wrap every new eval of lhs in save_expr() so it is clear to
- back end that MULT_EXPR(lhs,lhs) has identical operands,
- otherwise for an rhs like 32767 it generates around 65K pseudo
- registers, with which stupid_life_analysis cannot cope
- (due to reg_renumber in regs.h being `short *' instead of
- `int *').
-
- * com.c (ffecom_expr_): Speed up implementation of LOGICAL
- versions of opNOT, opAND, opOR, opXOR/opNEQV, and opEQV by
- assuming the values actually are kosher LOGICAL bit patterns.
- Also simplify code that implements some of the INTEGER versions
- of these.
-
- * com.c (skip_redundant_dir_prefix, read_name_map,
- ffecom_open_include_, signed_type, unsigned_type): Fold in
- changes to cccp.c made from 2.7.0 through ss-950826.
-
- * equiv.c (ffeequiv_layout_local_): Kill the equiv list
- if no syms in list.
-
- * expr.c (ffeexpr_reduced_eqop2_): Issue specific diagnostic
- regarding usage of .EQV./.NEQV. in preference to .EQ./.NE..
-
- * intrin.c: Add ERF and ERFC as generic intrinsics.
- intrin.def: Same.
-
- * sta.c (ffesta_save_, ffesta_second_): Whoever calls
- ffestd_exec_begin must also set ffesta_seen_first_exec = TRUE,
- and anytime stc sees an exec transition, it must do both.
- stc.c (ffestc_eof): Same.
-
- * stc.c (ffestc_promote_sfdummy_): If failed implicit typing
- or CHARACTER*(*) arg, after calling ffesymbol_error, don't
- reset info to ENTITY/DUMMY, because ffecom_sym_transform_
- doesn't expect such a thing with ANY/ANY type.
-
- * target.h (*logical*): Change some of these so they parallel
- changes in com.c, e.g. for _eqv_, use (l)==(r) instead of
- !!(l)==!!(r), to get a more faithful result.
-
-Fri Oct 27 07:06:59 1995 Craig Burley (burley@gnu.ai.mit.edu)
-
- * com.c (ffecom_sym_transform_): Simplify code for local
- EQUIVALENCE case.
-
- * expr.c (ffeexpr_exprstack_push_unary_): Warn about two
- successive operators.
- (ffeexpr_exprstack_push_binary_): Warn about "surprising"
- operator precedence, as in "-2**2".
-
- * lang-options.h: Add -W(no-)surprising options.
-
- * parse.c (yyparse): Don't reset -fpedantic if not -pedantic.
-
- * top.c (ffe_decode_option): Support new -Wsurprising option.
- * top.h: Ditto.
-
-Mon Oct 23 09:14:15 1995 Craig Burley (burley@gnu.ai.mit.edu)
-
- * com.c (ffecom_finish_symbol_transform_): Don't transform
- NONE/NONE (CHARACTER*(*)) vars, as these don't mean anything
- in debugging terms, and can't be turned into anything
- in the back end (so ffecom_sym_transform_ crashes on them).
-
- * com.c (ffecom_expr_): Change strategy for assignp variant
- of opSYMTER case...always return the original var unless
- it is not wide enough.
-
- * ste.c (ffeste_io_cilist_): Clarify diagnostic for ASSIGN
- involving too-narrow variable. This shouldn't happen, though.
- (ffeste_io_icilist_): Ditto.
- (ffeste_R838): Ditto.
- (ffeste_R839): Ditto.
-
-Thu Oct 19 03:21:20 1995 Craig Burley (burley@gnu.ai.mit.edu)
-
- * com.c (ffecom_sym_transform_assign_): Set TREE_STATIC
- using the same decision-making process as used for their twin
- variables, so ASSIGN can last across RETURN/CALL as appropriate.
-
-Fri Sep 22 20:21:18 1995 Craig Burley (burley@gnu.ai.mit.edu)
-
- * Makefile.in: fini is a host program, so it needs a host-compiled
- version of proj.o, named proj-h.o. f/fini, f/fini.o, and
- f/proj-h.o targets updated accordingly.
-
- * com.c (__eprintf): New function.
-
-Wed Sep 20 02:26:36 1995 Craig Burley (burley@gnu.ai.mit.edu)
-
- * lang-options.h: Add omitted -funix-intrinsics-* options.
-
- * malloc.c (malloc_find_inpool_): Check for infinite
- loop, crash if detected (user reports encountering
- them in some large programs, this might help track
- down the bugs).
-
-Thu Sep 7 13:00:32 1995 Craig Burley (burley@gnu.ai.mit.edu)
-
- * com.c (lang_print_error_function): Don't dereference null
- pointer when outside any program unit.
- (ffecom_let_char_, ffecom_arg_ptr_to_expr): If catlist
- item or length ever error_mark_node, don't continue processing,
- since back-end functions like build_pointer_type crash on
- error_mark_node's (due to pushing bad obstacks, etc.).
-
-Wed Aug 30 15:58:35 1995 Craig Burley (burley@gnu.ai.mit.edu)
-
- * Version 0.5.16 released.
-
-Mon Aug 28 12:24:20 1995 Craig Burley (burley@gnu.ai.mit.edu)
-
- * bad.c (ffebad_finish): Fix botched message when no places
- are printed (due to unknown line info, etc.).
-
- * std.c (ffestd_subr_labels_): Do a better job finding
- line info in the case of typeANY and diagnostics.
-
-Fri Aug 25 15:19:29 1995 Craig Burley (burley@gnu.ai.mit.edu)
-
- * com.c (DECL_ARTIFICIAL): Surround all references to this
- macro with #if !BUILT_FOR_270 and #endif.
- (init_lex): Surround print_error_function decl with
- #if !BUILT_FOR_270 and #endif.
- (lang_init): Call new ffelex_hash_kludge function to solve
- problem with preprocessed files that have INCLUDE statements.
-
- * lex.c (ffelex_getc_): New function.
- (ffelex_cfelex_): Use ffelex_getc_ instead of getc in any
- paths of code that can be affected by ffelex_hash_kludge.
- Don't make an EOF token for unrecognized token; set token
- to NULL instead, to avoid problems when not initialized.
- (ffelex_hash_): Use ffelex_getc_ instead of getc in any
- paths of code that can be affected by ffelex_hash_kludge.
- Test token returned by ffelex_cfelex_ for NULL, meaning
- unrecognized token.
- Get rid of useless used_up variable.
- Don't do ffewhere stuff or kill any tokens if in
- ffelex_hash_kludge.
- (ffelex_file_fixed, ffelex_file_free): Use ffelex_getc_
- instead of getc in any paths of code that can be affected
- by ffelex_hash_kludge.
- (ffelex_hash_kludge): New function.
-
- * lex.h (ffelex_hash_kludge): New function.
-
-Wed Aug 23 15:17:40 1995 Craig Burley (burley@gnu.ai.mit.edu)
-
- * com.c: Implement -f(no-)underscoring options by always
- compiling in code to do it, and having that code inhibit
- itself when -fno-underscoring is in effect. This option
- overrides -f(no-)f2c for this purpose; -f(no-)f2c returns
- to it's <=0.5.15 behavior of affecting only how code
- is generated, not how/whether names are mangled.
-
- * target.h: Redo specification of appending underscores so
- the macros are named "_default" instead of "_is" and the
- two-underscore macro defaults to 1.
-
- * top.c, top.h (underscoring): Add appropriate stuff
- for the -f(no-)underscoring options.
-
-Tue Aug 22 10:25:01 1995 Craig Burley (burley@gnu.ai.mit.edu)
-
- * bad.c (ffebad_finish): Call report_error_function (in toplev.c)
- to better identify location of problem.
- Say "(continued):" instead of "(continued:)" for consistency.
-
- * com.c (ffecom_gen_sfuncdef_): Set and reset new
- ffecom_nested_entry_ variable to hold ffesymbol being compiled.
- (lang_print_error_function): New function from toplev.c.
- Use ffecom_nested_entry_ to help determine which name
- and kind-string to print.
- (ffecom_expr_intrinsic_): Handle EXIT and FLUSH invocations
- with different calling sequences than library functions.
- Have SIGNAL and SYSTEM push and pop calltemps, and convert
- their return values to the destination type (just in case).
- (FFECOM_rttypeINT_): New return type for `int', in case
- gcc/f/runtime/libF77/system_.c(system_) is really supposed
- to return `int' instead of `ftnint'.
-
- * com.h (report_error_function): Declare this.
-
- * equiv.c (ffeequiv_layout_local_): Don't forget to consider
- root variable itself as possible "first rooted variable",
- else might never set symbol and then crash later.
-
- * intrin.c (ffeintrin_check_exit_): Change to allow no args
- and rename to ffeintrin_check_int_1_o_ for `optional'.
- #define ffeintrin_check_exit_ and _flush_ to this new
- function, so intrin.def can refer to the appropriate names.
-
- * intrin.def (FFEINTRIN_impFLUSH): Validate using
- ffeintrin_check_flush_ so passing an INTEGER arg is allowed.
-
- * lex.c (ffelex_file_push_, ffelex_file_pop_): New functions
- to manage input_file_stack in gbe.
- (ffelex_hash_): Call new functions (instead of doing code).
- (ffelex_include_): Call new functions to update stack for
- INCLUDE (_hash_ handles cpp output of #include).
-
-Mon Aug 21 08:09:04 1995 Craig Burley (burley@gnu.ai.mit.edu)
-
- * Makefile.in: Put `-W' in front of every `-Wall', since
- 2.7.0 requires that to engage `-Wunused' for parameters.
-
- * com.c: Mark all parameters as artificial, so
- `-W -Wunused' doesn't complain about unused ones (since
- there's no way right not to individually specify attributes
- like `unused').
-
- * proj.h: Don't #define UNUSED if already defined, regardless
- of host compiler.
-
-Sun Aug 20 16:03:56 1995 Craig Burley (burley@gnu.ai.mit.edu)
-
- * gbe/2.7.0.diff: Regenerate.
-
- * lang-options.h, lang-specs.h: If not __STDC__ (ANSI C),
- avoid doing anything, especially the stringizing in -specs.h.
-
-Thu Aug 17 03:36:12 1995 Craig Burley (burley@gnu.ai.mit.edu)
-
- * lang-specs.h: Remove useless optional settings of -traditional,
- since -traditional is always set anyway.
-
-Wed Aug 16 16:56:46 1995 Craig Burley (burley@gnu.ai.mit.edu)
-
- * Make-lang.in (F2C_INSTALL_FLAG, F2CLIBOK): More
- control over whether to install f2c-related stuff.
- (install-f2c-*): New targets to install f2c-related
- stuff in system, not just gcc, directories.
-
- * com.c: Change calls to ffecom_get_invented_identifier
- to use generally more predictable names.
- Change calls to build_range_type to ensure consistency
- of types of operands.
- (ffecom_get_external_identifier_): Change to accept
- symbol info, not just text, so it can use f2c flag for
- symbol to decide whether to append underscore(s).
- (ffecom_get_identifier_): Don't change names if f2c flag
- off for compilation.
- (ffecom_type_permanent_copy_): Use same type for new max as
- used for min.
- (ffecom_notify_init_storage): Offline fixups for stand-alone.
-
- * data.c (ffedata_gather): Explicitly test for common block,
- since it's no longer always the case that a local EQUIVALENCE
- group has no symbol ptr (it now can, if a user-predictable
- "rooted" symbol has been identified).
-
- * equiv.c: Add some debugging stuff.
- (ffeequiv_layout_local_): Set symbol ptr with user-predictable
- "rooted" symbol, for giving the invented aggregate a
- predictable name.
-
- * g77.c (append_arg): Allow for 20 extra args instead of 10.
- (main): For version-only case, add `-fnull-version' and, unless
- explicitly omitted, `-lf2c -lm'.
-
- * lang-options.h: New "-fnull-version" option.
-
- * lang-specs.h: Support ".fpp" suffix for preprocessed source
- (useful for OS/2, MS-DOS, other case-insensitive systems).
-
- * stc.c (ffestc_R544_equiv_): Swap way lists are merged so this
- is consistent with the order in which lists are built, making
- user predictability of invented aggregate name much higher.
-
- * storag.c, storag.h (FFESTORAG_typeDUMMY): Delete this enum.
-
- * top.c: Accept, but otherwise ignore, `-fnull-version'.
-
-Tue Aug 15 07:01:07 1995 Craig Burley (burley@gnu.ai.mit.edu)
-
- * DOC, INSTALL, PROJECTS: Extensive improvements to documentation.
-
-Sun Aug 13 01:55:18 1995 Craig Burley (burley@gnu.ai.mit.edu)
-
- * INSTALL (f77-install-ok): Document the use of this file.
-
- * Make-lang.in (F77_INSTALL_FLAG): New flag to control
- whether to install an `f77' command (based on whether
- a file named `f77-install-ok' exists in the source or
- build directory) to replace the broken attempt to use
- comment lines to avoid installing `f77' (broken in the
- sense that it prevented installation of `g77').
-
-Mon Aug 7 06:14:26 1995 Craig Burley (burley@gnu.ai.mit.edu)
-
- * DOC: Add new sections for g77 & gcc compiler options,
- source code form, and types, sizes and precisions.
- Remove lots of old "delta-version" info, or at least
- summarize it.
-
- * INSTALL: Add info here that used to be in DOC.
- Other changes.
-
- * g77.c (lookup_option, main): Check for --print-* options,
- so we avoid adding version-determining stuff.
-
-Wed Jul 26 15:51:03 1995 Craig Burley (burley@gnu.ai.mit.edu)
-
- * Make-lang.in, Makefile.in (input.j, INPUT_H): New file.
- Update dependencies accordingly.
-
- * bad.c (ffebad_here): Okay to use unknown line/col.
-
- * compilers.h (@f77-cpp-input): Remove -P option now that
- # directives are handled by f771. Update other options
- to be more consistent with @c in gcc/gcc.c. Don't run f771
- if -E specified, etc., a la @c.
- (@f77): Don't run f771 if -E specified, etc., a la @c.
-
- * config-lang.in: Avoid use of word "guaranteed".
-
- * input.j: New file to wrap around gcc/input.h.
-
- * lex.j: Add support for parsing # directives output by cpp.
- (ffelex_cfebackslash_): New function.
- (ffelex_cfelex_): New function.
- (ffelex_get_directive_line_): New function.
- (ffelex_hash_): New function.
- (ffelex_include_): Change to not use ffewhere_file_(begin|end).
- Also fix bug in pointing to next line (for diagnostics, &c)
- following successful INCLUDE.
- (ffelex_next_line_): New function that does chunk of code
- seen in several places elsewhere in the lexers.
- (ffelex_file_fixed): Delay finishing statement until source
- line is registered with ffewhere, so INCLUDE processing
- picks up the info correctly.
- Okay to kill or use unknown line/col objects now.
- Handle HASH (#) lines.
- Reorder tests for insubstantial lines to put most frequent
- occurrences at top, for possible minor speedup.
- Some general consolidation of code.
- (ffelex_file_free): Handle HASH (#) lines.
- Okay to kill or use unknown line/col objects now.
- Some general consolidation of code.
- (ffelex_init_1): Detect HASH (#) lines.
- (ffelex_set_expecting_hollerith): Okay to kill or use unknown
- line/col objects now.
-
- * lex.h (FFELEX_typeHASH): New enum.
-
- * options-lang.h (-fident, -fno-ident): New options.
-
- * stw.c (ffestw_update): Okay to kill unknown line/col objects
- now.
-
- * target.h (FFETARGET_okREALQUAD, FFETARGET_okCOMPLEXDOUBLE,
- FFETARGET_okCOMPLEXQUAD): #define these appropriately.
-
- * top.c: Include flag.j wrapper, not flags.h directly.
- (ffe_is_ident_): New flag.
- (ffe_decode_option): Handle -fident and -fno-ident.
- (ffe_file): Replace obsolete ffewhere_file_(begin|end) with
- ffewhere_file_set.
-
- * top.h (ffe_is_ident_, ffe_is_ident, ffe_set_is_ident):
- New flag and access functions.
-
- * where.c, where.h: Remove all tracking of parent file.
- (ffewhere_file_begin, ffewhere_file_end): Delete these.
- (ffewhere_line_use): Make it work with unknown line object.
-
-Mon Jul 17 03:04:09 1995 Craig Burley (burley@gnu.ai.mit.edu)
-
- * com.c (ffecom_sym_transform_): Set DECL_IN_SYSTEM_HEADER
- flag for any local vars used as stmtfunc dummies or DATA
- implied-DO iter vars, so no -Wunused warnings are produced
- for them (a la f2c).
- (ffecom_init_0): Do "extern int xargc;" for IARGC() intrinsic.
- Warn if target machine not 32 bits, since g77 isn't yet
- working on them at all well.
-
- * expr.c (ffeexpr_sym_lhs_call_, ffeexpr_sym_lhs_data_,
- ffeexpr_sym_lhs_extfunc_, ffeexpr_sym_rhs_actualarg_,
- ffeexpr_sym_rhs_let_, ffeexpr_paren_rhs_let_): Don't
- gratuitously set attr bits that don't apply just
- to avoid null set meaning error; instead, use explicit
- error flag, and allow null attr set, to
- fix certain bugs discovered by looking at this code.
-
- * g77.c: Major changes to improve support for gcc long options,
- to make `g77 -v' report more useful info, and so on.
-
-Mon Jul 3 14:49:16 1995 Craig Burley (burley@gnu.ai.mit.edu)
-
- * DOC, com.c, intrin.h, intrin.c, intrin.def, target.h, top.c,
- top.h: Add new `unix' group of intrinsics, which includes the
- newly added ERF, ERFC, EXIT, plus even newer ABORT, DERF, DERFC,
- FLUSH, GETARG, GETENV, SIGNAL, and SYSTEM.
-
-Tue Jun 27 23:01:05 1995 Craig Burley (burley@gnu.ai.mit.edu)
-
- * bld.c, bld.h (ffebld_constant_pool,
- ffebld_constant_character_pool): Use a single macro (the
- former) to access the pool for allocating constants, instead
- of latter in public and FFEBLD_CONSTANT_POOL_ internally
- in bld.c (which was the only one that was correct before
- these changes). Add verification of integrity of certain
- heap-allocated areas.
-
- * com.c (ffecom_overlap_, ffecom_args_overlap_,
- ffecom_tree_canonize_ptr_, ffecom_tree_canonize_ref_): New
- functions to optimize calling COMPLEX and, someday, CHARACTER
- functions requiring additional argument to be passed.
- (ffecom_call_, ffecom_call_binop_, ffecom_expr_,
- ffecom_expr_intrinsic_): Change calling
- sequences to include more info on possible destination.
- (ffecom_expr_intrinsic_): Add ERF(), ERFC(), and EXIT()
- intrinsic code.
- (ffecom_sym_transform_): For assumed-size arrays, set high
- bound to highest possible value instead of low bound, to
- improve validity of overlap checking.
- (duplicate_decls): If olddecl and newdecl are the same,
- don't do any munging, just return affirmative.
-
- * expr.c: Change ffecom_constant_character_pool() to
- ffecom_constant_pool().
-
- * info.c (ffeinfo_new): Compile this version if not being
- compiled by GNU C.
-
- * info.h (ffeinfo_new): Don't define macro if not being
- compiled by GNU C.
-
- * intrin.c, intrin.def: Add ERF(), ERFC(), and EXIT() intrinsics.
- (ffeintrin_check_exit_): New for EXIT() subroutine intrinsic.
-
- * malloc.c, malloc.h (malloc_verify_*): New functions to verify
- integrity of heap-storage areas.
-
- * stc.c (ffestc_R834, ffestc_R835): Handle possibility that
- an enclosing DO won't have a construct name even when the
- CYCLE/EXIT does (i.e. without dereferencing NULL).
-
- * target.c, target.h (ffetarget_verify_character1): New function
- to verify integrity of heap storage used to hold character constant.
-
-Thu Jun 22 15:36:39 1995 Howard Gordon (flash@super.org)
-
- * stp.h (ffestpVxtcodeIx): Fix typo in typedef for this.
-
-Mon May 29 15:22:31 1995 Craig Burley (burley@gnu.ai.mit.edu)
-
- * *: Make all sorts of changes to accommodate upcoming gcc-2.7.0.
- I didn't keep track of them, nor just when I made them, nor
- when I (much later, probably in early August 1995) modified
- them so they could properly handle both 2.7.0 and 2.6.x.
-
- * com.c (ffecom_expr_power_integer_): Don't expand_start_stmt_expr
- if transforming dummy args, because the back end cannot handle
- that (it's rejected by the gcc front end), just generate
- call to run-time library.
- Back out changes in 0.5.15 because more temporaries might be
- needed anyway (for COMPLEX**INTEGER).
- (ffecom_push_tempvar): Remove inhibitor.
- Around start_decl and finish_decl (in particular, arround
- expand_decl, which is called by them), push NULL_TREE into
- sequence_rtl_expr, an external published by gcc/function.c.
- This makes sure the temporary is truly in the function's
- context, not the inner context of a statement-valued expression.
- (I think the back end is inconsistent here, but am not
- interested in convincing the gbe maintainers about this now.)
- (pushdecl): Make sure that when pushing PARM_DECLs, nothing
- other than them are pushed, as happened for 0.5.15 and which,
- if done for other reasons not fixed here, might well indicate
- some other problem -- so crash if it happens.
-
- * equiv.c (ffeequiv_layout_local_): If the local equiv group
- has a non-nil COMMON field, it should mean that an error has
- occurred and been reported, so just trash the local equiv
- group and do nothing.
-
- * stc.c (ffestc_promote_sfdummy_): Set sfdummy arg state to
- UNDERSTOOD so above checking for duplicate args actually
- works, and so we don't crash later in pushdecl.
-
- * ste.c (ffeste_R1001): Set initial value only for VAR_DECLs,
- not for, e.g., LABEL_DECLs, which the FORMAT label can be
- if it was previously treated as an executable label.
-
-Sat May 20 01:53:53 1995 Craig Burley (burley@gnu.ai.mit.edu)
-
- * com.c (ffecom_sym_transform_): For adjustable arrays,
- pass high bound through variable_size in case its primaries
- are changed (dumb0.f, and this might also improve
- performance so it approaches f2c|gcc).
-
-Fri May 19 11:00:36 1995 Craig Burley (burley@gnu.ai.mit.edu)
-
- * Version 0.5.15 released.
-
- * com.c (ffecom_expr_power_integer_): Push temp vars
- before expanding a statement expression, since that seems
- to cause temp vars to be "forgotten" after the end of the
- expansion in the back end. Disallow more temp-var
- pushing during such an expansion, just in case.
- (ffecom_push_tempvar): Crash if a new variable needs to be
- pushed but cannot be at this point (should never happen).
-
-Wed May 17 12:26:16 1995 Craig Burley (burley@gnu.ai.mit.edu)
-
- * expr.c (ffeexpr_collapse_convert): Add code to convert
- LOGICAL to CHARACTER. Reject conversion of REAL or COMPLEX
- to CHARACTER entirely, as it cannot be supported with all
- configurations.
-
- * target.h, target.c (ffetarget_convert_character1_logical1):
- New function.
-
-Sun May 14 00:00:09 1995 Craig Burley (burley@gnu.ai.mit.edu)
-
- * com.c (ffecom_do_entry_, ffecom_gen_sfuncdef_,
- ffecom_start_progunit_, ffecom_sym_transform_,
- ffecom_init_0, start_function): Changes to have REAL
- external functions return same type as DOUBLE PRECISION
- external functions when -ff2c is in force; while at it,
- some code cleanups done.
-
- * stc.c (ffestc_R547_item_object): Disallow array declarator
- if one already exists for symbol.
-
- * ste.c (ffeste_R1227): Convert result variable to type
- of function result as seen by back end (e.g. for when REAL
- external function actually returns result as double).
-
- * target.h (FFETARGET_defaultFIXED_LINE_LENGTH): New
- macro for default for -ffixed-line-length-N option.
-
- * top.c (ffe_fixed_line_length_): Initialize this to new
- target.h macro instead of constant 72.
-
-Tue May 9 01:20:03 1995 Craig Burley (burley@gnu.ai.mit.edu)
-
- * lex.c (ffelex_send_token_): If sending CHARACTER token with
- null text field, put a single '\0' in it and set length/size
- fields to 0 (to fix 950508-0.f).
- (ffelex_image_char_): When setting ffelex_bad_line_ to TRUE,
- always "close" card image by appending a null char and setting
- ffelex_card_length_. As part of this, append useful text
- to identify the two kinds of problems that involve this.
- (ffelex_file_fixed): Reset ffelex_bad_line_ to FALSE after
- seeing a line with invalid first character (fixes 950508-1.f).
- If final nontab column is zero, assume tab seen in line.
- (ffelex_card_image_): Always make this array 8 characters
- longer than reflected by ffelex_card_size_.
- (ffelex_init_1): Get final nontab column info from top instead
- of assuming 72.
-
- * options-lang.h: Add -ffixed-line-length- prefix.
-
- * top.h: Add ffe_fixed_line_length() and _set_ version, plus
- corresponding extern.
-
- * top.c: Handle -ffixed-line-length- option prefix.
-
-Fri Apr 28 05:40:25 1995 Craig Burley (burley@gnu.ai.mit.edu)
-
- * Version 0.5.14 released.
-
- * Make-lang.in: Add assert.j.
-
- * Makefile.in: Add assert.j.
-
- * assert.j: New file.
-
-Thu Apr 27 16:24:22 1995 Craig Burley (burley@gnu.ai.mit.edu)
-
- * bad.h (ffebad_severity): New function.
-
- * bad.c (ffebad_severity): New function.
-
- * bad.def (FFEBAD_OPEN_INCLUDE): Change severity from SEVERE
- to FATAL, since processing continues, and that seems fine.
-
- * com.c: Add facility to handle -I.
- (ffecom_file, ffecom_close_include, ffecom_open_include,
- ffecom_decode_include_option): New global functions for -I.
- (ffecom_file_, ffecom_initialize_char_syntax_,
- ffecom_close_include_, ffecom_decode_include_option_,
- ffecom_open_include_, append_include_chain, open_include_file,
- print_containing_files, read_filename_string, file_name_map,
- savestring): New internal functions for -I.
-
- * compilers.h: Pass -I flag(s) to f771 (via "%{I*}").
-
- * lex.c (ffelex_include_): Call ffecom_close_include
- to close include file, for its tracking needs for -I,
- instead of using fclose.
-
- * options-lang.h: Add -I prefix.
-
- * parse.c (yyparse): Call ffecom_file for main input file,
- so -I handling works (diagnostics).
-
- * std.c (ffestd_S3P4): Have ffecom_open_include handle
- opening and diagnosing errors with INCLUDE files.
-
- * ste.c (ffeste_begin_iterdo_): Use correct algorithm for
- calculating # of iterations -- mathematically similar but
- computationally different algorithm was not handling cases
- like "DO I=6,5,2" correctly, because (5-6)/2+1 => 1, not 0.
-
- * top.c (ffe_decode_option): Allow -I, restructure a bit
- for clarity and, maybe, speed.
-
-Mon Apr 17 13:31:11 1995 Craig Burley (burley@gnu.ai.mit.edu)
-
- * g77.c: Remove -lc, turns out not all systems has it, but
- leave other changes in for clarity of code.
-
-Sun Apr 16 21:50:33 1995 Craig Burley (burley@gnu.ai.mit.edu)
-
- * com.c (ffecom_expr_): Implement ARRAY_EXPR as INDIRECT_REF
- of appropriate PLUS_EXPRs of ptr_to_expr of array, to see
- if this generates better code. (Conditional on
- FFECOM_FASTER_ARRAY_REFS.)
-
-Sun Apr 16 00:22:48 1995 Craig Burley (burley@gnu.ai.mit.edu)
-
- * Make-lang.in (F77_SRCS): Remove g77.c, since it doesn't
- contribute to building f771.
-
- * Makefile.in (dircheck): Remove/replace with f/Makefile, because
- phony targets that are referenced in other real targets get run
- when those targets are specified, which is a waste of time (e.g.
- when rebuilding and only g77.c has changed, f771 was being linked
- anyway).
-
- * g77.c: Include -lc between -lf2c and -lm throughout.
-
- * implic.c (ffeimplic_establish_symbol): If -Wimplicit, warn if
- implicit type given to symbol.
-
- * lex.c (ffelex_include_): Don't gratuitously increment line
- number here.
-
- * top.h, top.c (ffe_is_warn_implicit_): New global variable and
- related access macros.
- (ffe_decode_option): Handle -W options, including -Wall and
- -Wimplicit.
-
- * where.c (ffewhere_line_new): Don't muck with root line (was
- crashing on null input since lexer changes over the past week
- or so).
-
-Thu Apr 13 16:48:30 1995 Craig Burley (burley@gnu.ai.mit.edu)
-
- * com.c (ffecom_init_0): Register built-in functions for cos,
- sin, and sqrt.
- (ffecom_tree_fun_type_double): New variable.
- (ffecom_expr_intrinsic_): Update f2c input and output files
- to latest version of f2c (no important g77-related changes
- noted, just bug fixes to f2c and such).
- (builtin_function): New function from c-decl.c.
-
- * com-rt.def: Refer to built-in functions for cos, sin, and sqrt.
-
-Thu Apr 13 10:25:09 1995 Craig Burley (burley@gnu.ai.mit.edu)
-
- * com.c (ffecom_expr_intrinsic_): Convert 0. to appropriate
- type to keep DCMPLX(I) from crashing the compiler.
- (ffecom_expr_): Don't convert result from ffecom_tree_divide_.
- (ffecom_tree_divide_): Add tree_type argument, have all callers
- pass one, and don't convert right-hand operand to it (this is
- to make this new function work as much like the old in-line
- code used in ffecom_expr_ as possible).
-
- * lex.c: Maintain lineno and input_filename the way the gcc
- lexer does.
-
- * std.c (ffestd_exec_end): Save and restore lineno and
- input_filename around the second pass, which sets them
- appropriately for each saved statement.
-
-Wed Apr 12 09:44:45 1995 Craig Burley (burley@gnu.ai.mit.edu)
-
- * com.c (ffecom_expr_power_integer_): New function.
- (ffecom_expr_): Call new function for power op with integer second
- argument, for generating better code. Also replace divide
- code with call to new ffecom_tree_divide_ function.
- Canonicalize calls to ffecom_truth_value(_invert).
- (ffecom_tree_divide_): New function.
-
-Wed Apr 5 14:15:44 1995 Craig Burley (burley@gnu.ai.mit.edu)
-
- * lex.c: Change to allocate text for tokens only when actually
- needed, which should speed compilation up somewhat.
- Change to allow INCLUDE at any point where a statement
- can end, i.e. in ffelex_finish_statement_ or when a SEMICOLON
- token is sent.
- Remove some old, obsolete code.
- Clean up layout of entire file to improve formatting,
- readability, etc.
- (ffelex_set_expecting_hollerith): Remove include argument.
-
-Fri Mar 31 23:19:08 1995 Craig Burley (burley@gnu.ai.mit.edu)
-
- * bad.h, bad.c (ffebad_start_msg, ffebad_start_msg_lex):
- New functions to generate arbitrary messages.
- (FFEBAD_severityPEDANTIC): New severity, to correspond
- to toplev's pedwarn() function.
-
- * lex.c (ffelex_backslash_): New function to implement
- backslash processing.
- (ffelex_file_fixed, ffelex_file_free): Implement new
- backslash processing.
-
- * std.c (ffestd_R1001dump_): Don't assume CHARACTER and
- HOLLERITH tokens stop at '\0' characters, now that backslash
- processing is supported -- use their advertised lengths instead,
- and double up the '\002' character for libf2c.
-
-Mon Mar 27 17:10:33 1995 Craig Burley (burley@gnu.ai.mit.edu)
-
- * com.c (ffecom_init_local_zero_): Implement -finit-local-zero.
- (ffecom_sym_transform_): Same.
- (ffecom_transform_equiv_): Same.
-
- * options-lang.h: Add -f(no-)(init-local-zero,backslash,ugly-init).
-
- * stb.c (ffestb_V020): Reject "TYPEblah(...", which might be
- an array assignment.
-
- * target.h, top.h, top.c: Implement -finit-local-zero.
-
-Fri Mar 24 19:56:22 1995 Craig Burley (burley@gnu.ai.mit.edu)
-
- * Make-lang.in, Makefile.in: Remove conf-proj(.in) and
- proj.h(.in) rules, plus related config.log, config.cache,
- and config.status stuff.
-
- * com.c (ffecom_init_0): Change messages when atof(), bsearch(),
- or strtoul() do not work as expected in the start-up test.
-
- * conf-proj, conf-proj.in: Delete.
-
- * lex.c (ffelex_file_fixed): Allow f2c's '&' in column 1
- to mean continuation line.
-
- * options-lang.h: New file, #include'd by ../toplev.c.
-
- * proj.h.in: Rename back to proj.h.
-
- * proj.h (LAME_ASSERT): Remove.
- (LAME_STDIO): Remove.
- (NO_STDDEF): Remove.
- (NO_STDLIB): Remove.
- (NO_BSEARCH): Remove auto detection, rename to !FFEPROJ_BSEARCH.
- (NO_STRTOUL): Remove auto detection, rename to !FFEPROJ_STRTOUL.
- (USE_HOST_LIMITS): Remove (maybe still needed by stand-alone?).
- (STR, STRX): Do only ANSI C definitions.
-
-Mon Mar 13 10:46:13 1995 Craig Burley (burley@gnu.ai.mit.edu)
-
- * BUGS: Add item about g77 requiring gcc to compile it.
-
- * NEWS: New file listing user-visible changes in the release.
-
- * PROJECTS: Update to include a new item or two, and modify
- or delete items that are addressed in this or previous releases.
-
- * bad.c (ffebad_finish): Don't crash if missing string &c,
- just substitute obviously distressed string "[REPORT BUG!!]"
- for cases where the message/caller are fudgy.
-
- * bad.def: Clean up error messages in a major way, add new ones
- for use by changes in target.c.
-
- * com.c (ffecom_expr_): Handle opANY in opCONVERT.
- (ffecom_let_char_): Disregard destinations with ERROR_MARK.
- (ffecom_1, ffecom_1_fn, ffecom_2, ffecom_2s, ffecom_3,
- ffecom_3s, &c): Check all inputs for error_mark_node.
- (ffecom_start_progunit_): Don't transform all symbols
- in BLOCK DATA, since it never executes, and it is silly
- to, e.g., generate all the structures for NAMELIST.
- (ffecom_char_length_expr_): Rename to ffecom_intrinsic_len_.
- (ffecom_intrinsic_ichar_): New function to handle ICHAR of
- arbitrary expression with possible 0-length operands.
- (ffecom_expr_intrinsic_): Use ffecom_intrinsic_char_.
- For MVBITS, set tree_type to void_type_node.
- (ffecom_start_progunit_): Name master function for entry points
- after primary entry point so users can easily guess it while
- debugging.
- (ffecom_arg_ptr_to_expr): Change treatment of Hollerith,
- Typeless, and %DESCR.
- (ffecom_expr_): Change treatment of Hollerith.
-
- * data.c (ffedata_gather_): Handle opANY in opCONVERT.
-
- * expr.c (ffeexpr_token_apostrophe_): Issue FFEBAD_NULL_CHAR_CONST
- warning as necessary.
- (ffeexpr_token_name_rhs_): Set context for args to intrinsic
- so that assignment-like concatenation is allowed for ICHAR(),
- IACHAR(), and LEN() intrinsics.
- (ffeexpr_reduced_*_): Say "an array" instead of "an entity" in
- diagnostics, since it's more informative.
- (ffeexpr_finished_): For many contexts, check for null expression
- and array before trying to do a conversion, to avoid redundant
- diagnostics.
-
- * g77.1: Fix typo for preprocessed suffix (.F, not .f).
-
- * global.c (ffeglobal_init_common): Warn if initializing
- blank common.
- (ffeglobal_pad_common): Enable code to warn if initial
- padding needed.
- (ffeglobal_size_common): Complain if enlarging already-
- initialized common, since it won't work right anyway.
-
- * intrin.c: Add IMAG() intrinsic.
- (ffeintrin_check_loc_): Allow opSUBSTR in LOC().
-
- * intrin.def: Add IMAG() intrinsic.
-
- * lex.c: Don't report FFEBAD_NULL_CHAR_CONST errors.
-
- * sta.c, sta.h, stb.c: Changes to clean up error messages (see
- bad.def).
-
- * stb.c (ffestb_R100113_): Issue FFEBAD_NULL_CHAR_CONST
- warning as necessary.
-
- * stc.c (ffestc_shriek_do_): Don't try to reference doref_line
- stuff in ANY case, since it won't be valid.
- (ffestc_R1227): Allow RETURN in main program unit, with
- appropriate warnings/errors.
- (ffestc_subr_format_): Array of any type is a CHAREXPR (F77 C5).
-
- * ste.c (ffeste_begin_doiter_): Couple of fixes to accurately
- determine if loop never executes.
-
- * target.c (ffetarget_convert_*_hollerith_): Append spaces,
- not zeros, to follow F77 Appendix C, and to warn when
- truncation of non-blanks done.
- (ffetarget_convert_*_typeless): Rewrite to do typeless
- conversions properly, and warn when truncation done.
- (ffetarget_print_binary, ffetarget_print_octal,
- ffetarget_print_hex): Rewrite to use new implementation of
- typeless.
- (ffetarget_typeless_*): Rewrite to use new implementation
- of typeless, and to warn about overflow.
-
- * target.h (ffetargetTypeless): New implementation of
- this type.
-
- * type.h, type.c (ffetype_size_typeless): Remove (incorrect)
- implementation of this function and its extern.
-
-Sun Mar 5 18:46:42 1995 Craig Burley (burley@gnu.ai.mit.edu)
-
- * BUGS: Clarify that constant handling would also fix lack of
- adequate IEEE-754/854 support to some degree, and typeless
- and non-decimal constants.
-
- * com.c (ffecom_type_permanent_copy_): Comment out to avoid
- warnings.
- (duplicate_decls): New function a la gcc/c-decl.c.
- (pushdecl): Use duplicate_decls to decide whether to return
- existing decl or new one, instead of always returning existing
- decl.
- (ffecom_expr_): opPERCENT_LOC now supports CHARACTER arguments.
- (ffecom_init_0): Give f2c I/O code 0 for basictypeANY/kindtypeANY.
- (ffecom_sym_transform_): For adjustable arrays, pass low bound
- through variable_size in case its primaries are changed (950302-1.f).
-
- * com.h: More decls that belong in tree.h &c.
-
- * data.c (ffedata_eval_integer1_): Fix opPAREN case to not
- treat value of expression as an error code.
-
- * expr.c (ffeexpr_finished_): Allow opSUBSTR in contextLOC case.
-
- * proj.c: Add "const" as appropriate.
-
-Mon Feb 27 10:04:03 1995 Craig Burley (burley@gnu.ai.mit.edu)
-
- * bad.def (FFEBAD_BAD_SUBSTR): Fix bad grammar in message.
-
-Fri Feb 24 16:21:31 1995 Craig Burley (burley@gnu.ai.mit.edu)
-
- * Version 0.5.13 released.
-
- * INSTALL: Warn that f/zzz.o will compare differently between
- stages, since it puts the __TIME__ macro into a string.
-
- * com.c (ffecom_sym_transform_): Transform kindFUNCTION/whereDUMMY
- to pointer-to-function, not function.
- (ffecom_expr_): Use ffecom_arg_ptr_to_expr instead of
- ffecom_char_args_ to handle comparison between CHARACTER
- types, so either operand can be a CONCATENATE.
- (ffecom_transform_common_): Set size of initialized common area
- to global (largest-known) size, even though size of init might
- be smaller.
-
- * equiv.c (ffeequiv_offset_): Check symbol info for ANY.
-
- * expr.c (ffeexpr_find_close_paren_, ffeexpr_nil_*): New functions
- to handle following the contour of a rejected expression, so
- statements like "PRINT(I,I,I)=0" don't cause the PRINT statement
- code to get the second passed back to it as if there was a
- missing close-paren before it, the comma causing the PRINT code
- to confirm the statement, resulting in an ambiguity vis-a-vis
- the let statement code.
- Use the new ffecom_find_close_paren_ handler when an expected
- close-paren is missing.
- (ffeexpr_isdigits_): New function, use in all places that
- currently use isdigit in repetitive code.
- (ffeexpr_collapse_symter): Collapse to ANY if init-expr is ANY,
- so as to avoid having symbol get "transformed" if used to
- dimension an array.
- (ffeexpr_token_real_, ffeexpr_token_number_real_): Don't issue
- diagnostic about exponent, since it'll be passed along the
- handler path, resulting in a diagnostic anyway.
- (ffeexpr_token_apos_char_): Use consistent handler path
- regardless of whether diagnostics inhibited.
- (ffeexpr_token_name_apos_name_): Skip past closing quote/apos
- even if not a match or other diagnostic issued.
- (ffeexpr_sym_impdoitem_): Exec-transition local SEEN symbol.
-
- * lex.c (ffelex_image_char_): Set ffelex_saw_tab_ if TAB
- seen, not if anything other than TAB seen!
-
- * stc.c (ffestc_R537_item): If source is ANY but dest isn't,
- set dest symbol's init expr to ANY.
- (ffestc_R501_attrib, ffestc_R522, ffestc_R522start): Complain
- about conflict between "SAVE" by itself and other uses of
- SAVE only in pedantic mode.
-
- * ste.c (ffeste_R1212): Fix loop over labels to always
- increment caseno, to avoid pushcase returning 2 for duplicate
- values when one of the labels is invalid.
-
-Thu Feb 23 12:42:04 1995 Craig Burley (burley@gnu.ai.mit.edu)
-
- * Version 0.5.12 released.
-
- * Make-lang.in (f77.install-common): Add "else true;" before outer
- "fi" per Makefile.in patch.
-
- * Makefile.in (dircheck): Add "else true;" before "fi" per
- patch from chs1pm@surrey.ac.uk.
-
- * com.c (ffecom_push_tempvar): If type desired is ERROR_MARK,
- return error_mark_node, to avoid crash that results from
- making a VAR_DECL with error_mark_node as its type.
-
- * ste.c (ffeste_begin_iterdo_): Convert itercount to INTEGER
- anytime calculation of number of iterations ends up with type
- other than INTEGER (e.g. DOUBLE PRECISION, REAL).
-
-Thu Feb 23 02:48:38 1995 Craig Burley (burley@gnu.ai.mit.edu)
-
- * Version 0.5.11 released.
-
- * DOC: Explain -fugly-args.
-
- * bad.def (FFEBAD_ACTUALARG): Explain -fugly-args and how to
- rewrite code to not require it.
-
- * com.c (ffecom_vardesc_): Handle negative type code, just in
- case.
- (ffecom_arg_ptr_to_expr): Let ffecom_expr handle hollerith
- and typeless constants (move code to ffecom_constantunion).
- (ffecom_constantunion): Handle hollerith and typeless constants.
-
- * expr.c (ffecom_finished_): Check -fugly-args in actual-arg
- context where hollerith/typeless provided.
-
- * intrin.def (FFEINTRIN_genDFLOAT): Add FFEINTRIN_specDFLOAT.
- (FFEINTRIN_specDFLOAT): Add as f2c intrinsic.
-
- * target.h (ffetarget_convert_real[12]_integer,
- ffetarget_convert_complex[12]_integer): Pass -1 for high integer
- value if low part is negative.
- (FFETARGET_defaultIS_UGLY_ARGS): New macro.
-
- * top.c (ffe_is_ugly_args_): New variable.
- (ffe_decode_option): Handle -fugly-args and -fno-ugly-args.
-
- * top.h (ffe_is_ugly_args_, ffe_is_ugly_args(),
- ffe_set_is_ugly_args()): New variable and macros.
-
-Thu Feb 23 02:48:38 1995 Pedro A M Vazquez (vazquez@iqm.unicamp.br)
-
- * g77.c (sys_errlist): Use const for __FreeBSD__ systems
- as well.
-
-Wed Feb 22 13:33:43 1995 Craig Burley (burley@gnu.ai.mit.edu)
-
- * Version 0.5.10 released.
-
- * CREDITS: Add Rick Niles.
-
- * INSTALL: Note how to get around lack of makeinfo.
-
- * Make-lang.in (f/proj.h): Remove # comment.
-
- * Makefile.in (f/proj.h): Remove # comment.
-
- * com.c (ffecom_expr_): Simplify opFUNCREF/opSUBRREF conversion.
- (ffecom_sym_transform_): For whereGLOBAL and whereDUMMY
- kindFUNCTION, use ffecom_tree_fun_type[][] only for non-constant
- (non-statement-function) f2c functions.
- (ffecom_init_0): ffecom_tree_fun_type[][] and _ptr_to_*_* are
- really f2c-interface arrays, so use base type void for COMPLEX
- (like CHARACTER).
-
-Tue Feb 21 19:01:18 1995 Dave Love <d.love@dl.ac.uk>
-
- * Make-lang.in (f77.install-common): Expurgate the test for and
- possible installation of f2c in line with elsewhere. Seems to have
- been missing a semicolon anyhow!
-
-Tue Feb 21 11:45:25 1995 Craig Burley (burley@gnu.ai.mit.edu)
-
- * Version 0.5.9 released.
-
- * Make-lang.in (f/proj.h): touch file to register update,
- because the previous commands won't necessarily modify it.
-
- * Makefile.in (f/proj.h): touch file to register update,
- because the previous commands won't necessarily modify it.
-
- * Makefile.in (f/str-*.h, f/str-*.j): Explicitly specify
- output file names, so these targets go in build, not source,
- directory.
-
- * bits.c, bits.h: Switch to valid ANSI C replacement for
- ARRAY_ZERO.
-
- * com.c (ffecom_expr_): Add assignp arg to support ASSIGN better.
- If assignp is TRUE, use different tree for FFEBLD_opSYMTER case.
- (ffecom_sym_transform_assign_): New function.
- (ffecom_expr_assign): New function.
- (ffecom_expr_assign_w): New function.
-
- * com.c (ffecom_f2c_make_type_): Do make_signed_type instead
- of make_unsigned_type throughout.
-
- * com.c (ffecom_finish_symbol_transform_): Expand scope of
- commented-out code to probably produce faster compiler code.
-
- * com.c (ffecom_gen_sfuncdef_): Push/pop calltemps so
- COMPLEX works right.
- Remove obsolete comment.
-
- * com.c (ffecom_start_progunit_): If non-multi alt-entry
- COMPLEX function, primary (static) entry point returns result
- directory, not via extra arg -- to agree with ffecom_return_expr
- and others.
- Pretransform all symbols so statement functions are defined
- before any code emitted.
-
- * com.c (ffecom_finish_progunit): Don't posttransform all
- symbols here -- pretransform them instead.
-
- * com.c (ffecom_init_0): Don't warn about possible ASSIGN
- crash, as this shouldn't happen now.
-
- * com.c (ffecom_push_tempvar): Fix to handle temp vars
- pushed while context is a statement (nested) function, and
- add appropriate commentary.
-
- * com.c (ffecom_return_expr): Check TREE_USED to determine
- where return value is unset.
-
- * com.h (struct _ffecom_symbol_): Add note about length_tree
- now being used to keep tree for ASSIGN version of symbol.
-
- * com.h (ffecom_expr_assign, ffecom_expr_assign_rw): New decls.
- (error): Add this prototype for back-end function.
-
- * fini.c (main): Grab input, output, and include names
- directly off the command line instead of making the latter
- two out of the first.
-
- * lex.c: Improve tab handling for both fixed and free source
- forms, and ignore carriage-returns on input, while generally
- improving the code. ffelex_handle_tab_ has been renamed and
- reinvented as ffelex_image_char_, among other things.
-
- * malloc.c, malloc.h: Switch to valid ANSI C replacement for
- ARRAY_ZERO, and kill the full number of bytes in pools and
- areas.
-
- * proj.h.in (ARRAY_ZERO, ARRAY_ZERO_SIZE): Remove.
-
- * ste.c (ffeste_io_cilist_, ffeste_io_icilist_, ffeste_R838,
- ffeste_R839): Issue diagnostic if a too-narrow variable used in an
- ASSIGN context despite changes to this code and code in com.c.
-
- * where.c, where.h: Switch to valid ANSI C replacement for
- ARRAY_ZERO.
-
-Fri Feb 17 03:35:19 1995 Craig Burley (burley@gnu.ai.mit.edu)
-
- * Version 0.5.8 released.
-
- * INSTALL: In quick-build case, list g77 target first so g77
- gets installed. Also, explain that gcc gets built and installed
- as well, even though this isn't really what we want (and maybe
- we'll find a way around this someday).
-
-Fri Feb 17 02:35:41 1995 Craig Burley (burley@gnu.ai.mit.edu)
-
- * Version 0.5.7 released.
-
- * Makefile.in (CONFIG_H, HCONFIG_H, TCONFIG_H, TM_H): Remove
- ../ prefix in front of .h files, since they're in the cd.
-
-Fri Feb 17 01:50:48 1995 Craig Burley (burley@gnu.ai.mit.edu)
-
- * Version 0.5.6 released.
-
-Thu Feb 16 20:26:54 1995 Craig Burley (burley@gnu.ai.mit.edu)
-
- * ../README.g77: Remove description of g77 as "not-yet-published".
-
- * CREDITS: More changes.
-
- * Make-lang.in (G77STAGESTUFF): Remove cktyps stuff.
-
- * Makefile.in (CONFIG_H, HCONFIG_H, TCONFIG_H, TM_H): Don't
- prefix gcc dir with $(srcdir) since these don't live there,
- they are created in the build dir by gcc's configure. Add
- a note explaining what these macros are about.
- Update dependencies via deps-kinda.
-
- * README.NEXTSTEP: Credit Toon, and per his request, add his
- email address.
-
- * com.h (FFECOM_DETERMINE_TYPES): #include "config.j".
-
- * config.j, convert.j, flags.j, hconfig.j, rtl.j, tconfig.j,
- tm.j, tree.j: Don't #include if already done.
-
- * convert.j: #include "tree.j" first, as convert.h clearly depends
- on trees being defined.
-
- * rtl.j: #include "config.j" first, since there's some stuff
- in rtl.h that assumes it has been #included.
-
- * tree.j: #include "config.j" first, or real.h makes inconsistent
- decision about return type of ereal_atof, leading to bugs, and
- because tree.h/real.h assume config.h already included.
-
-Wed Feb 15 14:40:20 1995 Craig Burley (burley@gnu.ai.mit.edu)
-
- * Version 0.5.5 released.
-
- * Copyright notices updated to be FSF-style.
-
- * INSTALL: Some more clarification regarding building just f77.
-
- * Make-lang.in (F77_SRCS): Update wrt changing some .h to .j.
- (install-libf77): Fix typo in new parenthetical note.
-
- * Makefile.in (f/*.o): Update.
- (CONFIG_H, CONVERT_H, FLAGS_H, GLIMITS_H, HCONFIG_H, RTL_H,
- TCONFIG_H, TM_H, TREE_H): Update/new symbols.
- (deps-kinda): More fixes wrt changing some .h to .j.
- Document and explain this rule a bit better.
- Accommodate changes in output of gcc -MM.
-
- * *.h, *.c: Change #include's so proj.h not assumed to #include
- malloc.h or config.h (now config.j), and so new .j files are
- used instead of old .h ones.
-
- * com.c (ffecom_init_0): Use FLOAT_TYPE_SIZE for f2c's
- TYLONG/TYLOGICAL type codes, to get g77 working on Alpha.
-
- * com.h: Make all f2c-related integral types "int", not "long
- int".
-
- * config.j, convert.j, flags.j, glimits.j, hconfig.j, rtl.j,
- tconfig.j, tm.j, tree.j: New files wrapping around gbe
- .h files.
-
- * config.h, convert.h, flags.h, glimits.h, hconfig.h, rtl.h,
- tconfig.h, tm.h, tree.h: Deleted so new .j files
- can #include the gbe files directly, instead of using "../",
- and thus do better with various kinds of builds.
-
- * proj.h: Delete unused NO_STDDEF and related stuff.
-
-Tue Feb 14 08:28:08 1995 Craig Burley (burley@gnu.ai.mit.edu)
-
- * BUGS: Remove item #12, cross-compiling & autoconf scripts
- reportedly expected to work properly (according to d.love).
-
- * INSTALL: Add explanation of d.love's patch to config-lang.in.
- Add explanation of how to install just g77 when gcc already installed.
- Add note about usability of "-Wall". Add note about bug-
- reporting.
-
- * Make-lang.in ($(srcdir)/f/conf-proj): Add comment about why
- conf-proj.out.
- (install-libf77): Echo parenthetical note to user about how to do
- just the (aborted) libf2c installation.
- (deps-kinda): Update to work with new configuration/build stuff.
-
- * bad.c (ffebad_finish): Put capitalized "warning:" &c message
- as prefix on any diagnostic without pointers into source.
-
- * bad.def (FFEBAD_TOO_BIG_INIT): Add this warning message.
-
- * config-lang.in: Add Dave Love's patch to catch case where
- back-end patches not applied and abort configuration.
-
- * data.c (ffedata_gather_, ffedata_value_): Warn when about
- to initialize a large aggregate area, due to design flaw resulting
- in too much time/space used to handle such cases.
- Use COMMON area name, and first notice of symbol, for multiple-
- initialization diagnostic, instead of member symbol and unknown
- location.
- (FFEDATA_sizeTOO_BIG_INIT_): New macro per above.
-
-Mon Feb 13 13:54:26 1995 Dave Love <d.love@dl.ac.uk>
-
- * Make-lang.in (F77_SRCS): Use $(srcdir)/f/proj.h.in, not
- $(srcdir)/f/proj.h for build outside srcdir.
-
-Sun Feb 12 13:37:11 1995 Craig Burley (burley@gnu.ai.mit.edu)
-
- * ../README.g77: Clarify procedures for unpacking, add asterisks
- to mark important things the user must do.
-
- * Fix dates in/add dates to ../README.g77, BUGS, CREDITS, DOC,
- INSTALL, PROJECTS, README.
-
-Sun Feb 12 00:26:10 1995 Craig Burley (burley@gnu.ai.mit.edu)
-
- * Version 0.5.4 released.
-
- * Make-lang.in (f/proj.h): Reproduce this rule here from
- Makefile.in.
- ($(srcdir)/f/conf-proj): Put autoconf's stdout in temp file
- conf-proj.out, then mv to conf-proj only if successful, so
- conf-proj not touched if autoconf not installed.
-
- * Makefile.in ($(srcdir)/conf-proj): See Make-lang.in's similar
- rule.
-
-Sat Feb 11 20:56:02 1995 Craig Burley (burley@gnu.ai.mit.edu)
-
- * BUGS: Clarify some bugs.
-
- * DOC: Many improvements and fixes.
-
- * README: Move bulk of text, edited, to ../README.g77, and
- replace with pointer to that file.
-
- * com.c (ffecom_init_0): Comment out warning about sizeof(ftnlen)
- as per ste.c change. Add text about ASSIGN to help user understand
- what is being warned about.
-
- * conf-proj.in: Fix typos in comments.
-
- * proj.h.in: Add ARRAY_ZERO_SIZE to parallel malloc.h's version,
- in case it proves to be needed.
-
- * ste.c: Comment out assertions requiring sizeof(ftnlen) >=
- sizeof(char *), in the hopes that overflow will never happen.
- (ffeste_R838): Change assertion to fatal() with at least
- partially helpful message.
-
-Sat Feb 11 12:38:00 1995 Craig Burley (burley@gnu.ai.mit.edu)
-
- * com.c (ffecom_vardesc_): Crash if typecode is -1.
-
- * ste.c (ffeste_io_dolio_): Crash if typecode is -1.
-
-Sat Feb 11 09:51:57 1995 Craig Burley (burley@gnu.ai.mit.edu)
-
- * ste.c: In I/O code tests for item arrayness, sort of revert
- to much earlier code that tests original exp, but also check
- in newer way just in case. Newer way alone treated FOO(1:40)
- as an array, not sure why older way alone didn't work, but I
- think maybe it was when diagnosed code was involved, and
- since there are now checks for error_mark_node, maybe the old
- way alone would work. But better to be safe; both original
- ffebld exp _and_ the transformed tree must indicate an array
- for the size-determination code to be used, else just 1/2 elements
- assumed. And this text is for EMACS: (foo at bar).
-
-Fri Feb 10 11:05:50 1995 Craig Burley (burley@gnu.ai.mit.edu)
-
- * ste.c: In many cases, surround statement-expansion code
- with ffecom_push_calltemps () and ffecom_pop_calltemps ()
- so COMPLEX-returning functions can have temporaries pushed
- in "auto-pop" mode and have them auto-popped at the end of
- the statement.
-
-Wed Feb 8 14:35:10 1995 Dave Love <d.love@dl.ac.uk>
-
- * runtime/f2c.h.in (ftnlen, ftnint): Make same size as integer.
-
- * runtime/libI77/err.c (f_init): Thinko in MISSING_FILE_ELEMS
- conditional.
- * runtime/libI77/wrtfmt.c (mv_cur): Likewise.
- * runtime/libI77/wsfe.c (x_putc): Likewise.
-
- * runtime/libF77/signal_.c (signal_): Return 0 (this is a
- subroutine).
-
- * Makefile.in (f/proj.h): Depend on com.h.
- * Make-lang.in (include/f2c.h): Likewise (and proj.h).
- (install-libf77): Also install f2c.h.
-
- * runtime/libI77/Makefile.in (*.o): Add f2c.h dependency.
- * runtime/libF77/Makefile.in: Likewise.
-
-Wed Feb 8 13:56:47 1995 Craig Burley (burley@gnu.ai.mit.edu)
-
- * stc.c (ffestc_R501_item): Don't reset kind/where to NONE when
- setting basictype/kindtype info for symbol, or especially
- its function/result twin, because kind/where might not be NONE.
-
-Tue Feb 7 14:47:26 1995 Dave Love <d.love@dl.ac.uk>
-
- * Make-lang.in (include/f2c.h:): Set shell variable src more
- robustly (independent of whether srcdir is relative or absolute).
- * Makefile.in (f/proj.h:): Likewise.
-
- * conf-proj.in: Check need for LAME_ASSERT. Fix indentation in
- check for LAME_STDIO (cosmetic only with ANSI C).
-
- * com.h: Extra ...SIZE stuff taken from com.c.
-
- * com.c (FFECOM_DETERMINE_TYPES): Define before including com.h.
- (BITS_PER_WORD etc.) Remove and use conditional definitions to com.h.
-
- * runtime/configure.in: #define FFECOM_DETERMINE_TYPES for com.h in
- f2c type determination.
-
- * tm.h: Remove (at least pro tem) because of relative path and use
- top-level one.
-
- * Make-lang.in (include/f2c.h:): Set shell variable src more
- robustly (independent of whether srcdir is relative or absolute).
- * Makefile.in (f/proj.h:): Likewise.
-
-Mon Feb 6 19:58:32 1995 Dave Love <d.love@dl.ac.uk>
-
- * g77.c (append_arg): Use K&R declaration for, e.g. SunOS4 build.
-
-Fri Feb 3 20:33:14 1995 Craig Burley (burley@gnu.ai.mit.edu)
-
- * g77.c (main): Treat -l like filename in terms of -x handling.
- Rewrite arglist mechanism for ease of maintenance.
- Make sure every -lf2c is followed by -lm and vice versa.
-
- * Make-lang.in: Put complete list of sources in F77_SRCS def
- so changing a .h file, for example, causes rebuild.
-
- * Makefile.in: Change test for nextstep to m68k-next-nextstep* so
- all versions of nextstep on m68k get the necessary flag.
-
-Fri Feb 3 19:10:32 1995 Dave Love <d.love@dl.ac.uk>
-
- * INSTALL: Note about possible conflict with existing libf2c.a and
- f2c.h.
-
- * Make-lang.in (f77.distclean): Tidy and move deletion of
- f/config.cache to mostlyclean.
- (install-libf77): Test for $(libdir)/libf2c.* and barf if found
- unless F2CLIBOK defined.
-
- * runtime/Makefile.in (all): Change path to include directory (and
- elsewhere).
- (INCLUDES): Remove (unused/misleading).
- (distclean): Include f2c.h.
- (clean): Include config.cache.
-
- * runtime/libF77/Makefile.in (.SUFFIXES): Correct typo.
- (ALL_CFLAGS) Fix up include search path to find f2c.h in top level
- includes always.
- (all): Depend on f2c.h.
- * runtime/libI77/Makefile.in (.SUFFIXES): Likewise.
-
-Thu Feb 2 17:17:06 1995 Dave Love <d.love@dl.ac.uk>
-
- * INSTALL: Note about --srcdir and GNU make.
-
- * runtime/f2c.h.in (Pad_UDread, ALWAYS_FLUSH): Reomve the #defines
- per below.
-
- * runtime/configure.in (Pad_UDread, ALWAYS_FLUSH): Define these
- here, not in f2c.h as they'r eonly relevant for building.
- * runtime/configure: Regenerated.
-
- * config-lang.in: Warn about using GNU make outside source tree
- since I can't get Irix5 or SunOS4 makes to work in this case.
-
- * Makefile.in (VPATH): Don't set it here.
- (srcdir): Make it the normal `.' (overridden) at top level.
- (all.indirect): New dependency `dircheck'.
- (f771): Likewise
- (dircheck): New target for foolproofing.
- (f/proj.h:): Change finding source.
- (CONFIG_H): Don't use this as the relative path in the include loses
- f builddir != srcdir.
-
- * config.h: Remove per CONFIG_H change above.
-
- * Make-lang.in (F77_FLAGS_TO_PASS): Remove GCC_FOR_TARGET.
- (f771:): Pass VPATH, srcdir to sub-make.
- (f/Makefile:): New target.
- (stmp-int-hdrs): new variable for cheating build.
- (f77-runtime:): Alter GCC_FOR_TARGET treatment.
- (include/f2c.h f/runtime/Makefile:) Likewise.
- (f77-runtime-unsafe:): New (cheating) target.
-
-Thu Feb 2 12:09:51 1995 Craig Burley (burley@gnu.ai.mit.edu)
-
- * BUGS: Update regarding losing EQUIVALENCE members in -g, and
- regarding RS/6000 problems in the back end.
-
- * CREDITS: Make some changes as requested.
-
- * com.c (ffecom_member_trunk_): Remove unused static variable.
- (ffecom_finish_symbol_transform_): Improve comments.
- (ffecom_let_char_): Fix size of temp address-type var.
- (ffecom_member_phase2_): Try fixing problem fixed by change
- to ffecom_transform_equiv_ (f_m_p2_ function currently not used).
- (ffecom_transform_equiv_): Remove def of unused static variable.
- Comment-out use of ffecom_member_phase2_, until problems with
- back end fixed.
- (ffecom_push_tempvar): Fix assertion to not crash okay code.
-
- * com.h: Remove old, commented-out code.
- Add prototype for warning() in back end.
-
- * ste.c (ffeste_io_dofio_, ffeste_io_dolio_, ffeste_io_douio_,
- ffeste_io_icilist_): Check correct type of variable for arrayness.
-
-Sun Jan 29 14:41:42 1995 Dave Love <d.love@dl.ac.uk>
-
- * BUGS: Remove references to my configure bugs; add another.
-
- * runtime/Makefile.in (AR_FLAGS): Provide default value.
-
- * runtime/f2c.h.in (integer, logical): Take typedefs from
- F2C_INTEGER configuration parameter again.
- (NON_UNIX_STDIO): don't define it.
-
- * runtime/configure.in: Bring type checks for f2c.h in line with
- com.h.
- (MISSING_FILE_ELEMS): New variable to determine whether the relevant
- elements of the FILE struct exist, independent of NON_UNIX_STDIO.
- * runtime/libI77/{err,wrtfmt,wsfe}.c (MISSING_FILE_ELEMS): Use new
- parameter.
-
- * config-lang.in: Comment out more of f2c rules (c.f. Make-lang.in).
- (This stuff is relevant iff you gave configure --enable-f2c.)
- Create f/runtime directory tree iff not building in source
- directory.
-
- * Makefile.in (srcdir): Append slash so we get the right value when
- not building in the source directory. This is a consequence of not
- building the `f' sources in `f'.
- (VPATH): Override configure's value for reasons above.
- (f/proj.h f/conf-proj): New rules to build proj.h by
- autoconfiguration.
-
- * proj.h: Rename to proj.h.in for autoconfiguration.
- * proj.h.in: New as above.
- * conf-proj conf-proj.in: New files for autoconfiguration.
-
- * Make-lang.in (include/f2c.h f/runtime/Makefile:): Change the order
- of setting the sh variables so that the right GCC_FOR_TARGET is
- used.
- (f77.*clean:) Add products of new configuration files and make sure
- all the *clean targets do something (unlike the ones in
- cp/Make-lange.in).
-
- * com.h (FFECOM_f2cINTEGER, FFECOM_f2cLOGICAL): Define as long or
- int appropriately to ensure sizeof(real) == sizeof(integer).
-
- * PROJECTS: Library section.
-
- * runtime/libI77/endfile.c: Don't #include sys/types.h conditional
- on NON_UNIX_STDIO since rawio.h needs size_t.
- * runtime/libI77/uio.c: #include <sys/types.h> for size_t if not
- KR_headers.
-
-Wed Jan 25 03:31:51 1995 Craig Burley (burley@gnu.ai.mit.edu)
-
- * Version 0.5.3 released.
-
- * INSTALL: Revise.
-
- * Make-lang.in: Comment out rules for building f2c itself (f/f2c/).
-
- * README: Revise.
-
- * com.c (ffecom_init_0): Warn if ftnlen or INTEGER not big enough
- to hold a char *.
-
- * gbe/2.6.2.diff: Update.
-
-Mon Jan 23 17:10:49 1995 Craig Burley (burley@gnu.ai.mit.edu)
-
- * TODO: Remove.
- BUGS: New file.
- PROJECTS: New file.
- CREDITS: New file.
-
- * cktyps*: Remove.
- Make-lang.in: Remove cktyps stuff.
- Makefile.in: Remove cktyps stuff.
-
- * DOC: Add info on changes for 0.5.3.
-
- * bad.c: Put "warning:" &c on diagnostic messages.
- Don't output informational messages if warnings disabled.
-
-Thu Jan 19 12:38:13 1995 Craig Burley (burley@gnu.ai.mit.edu)
-
- * g77.c: Avoid putting out useless "-xnone -xf77" pairs so
- larger command lines can be accommodated.
- Recognize both `-xlang' and `-x lang'.
- Recognize `-xnone' and `-x none' to mean what it does, instead
- of treating "none" as any other language.
- Some minor, slight improvements in the way args are handled
- (hopefully for clearer, more maintainable code), including
- consistency checks on arg count just in case.
-
-Wed Jan 18 16:41:57 1995 Craig Burley (burley@gnu.ai.mit.edu)
-
- * DOC: Explain -fautomatic better.
-
- * INSTALL: Describe libf2c.a better.
-
- * Make-lang.in, Makefile.in: Build f771 &c with gcc/ as cd instead
- of gcc/f/ so debugging info is better (source file tracking).
- Add new source file type.c.
-
- * Makefile.in: For nextstep3, link f771 with -segaddr __DATA
- 6000000. Fix typo. Change deps-kinda target to handle building
- from gcc/. Update dependencies.
-
- * bld-op.def, bld.h, bld.c: Remove opBACKEND and all related
- stuff.
- Remove consistency tests that cause compiler warnings.
-
- * cktyps.c: Remove all typing checking.
-
- * com-rt.def: Change all rttypeFLOAT_ intrinsics to rttypeDOUBLE_,
- to precisely match how they're declared in libf2c.
-
- * com.h, com.c: Revise to more elegantly track related stuff
- in the version of f2c.h used to build libf2c.
-
- * com.c: Increase FFECOM_sizeMAXSTACKITEM, and if 0 or undefined
- when checked to determine where to put entity, treat as infinite.
- Rewrite temporary mechanism to be based on trees instead of
- ffeinfo stuff, and make it much simpler. Change interface
- accordingly.
- Fixes to better track types of things, make appropriate
- conversions, etc. E.g. when making an arg for a libf2c
- function, make sure it's of the right type (such as ftnlen).
- Delete opBACKEND transformation code.
- (ffecom_init_0): Smoother initialization of types, especially
- paying attention to using consistent rules for making INTEGER,
- REAL, DOUBLE PRECISION, etc., and for deciding their "*N"
- and kind values that will work across all g77 platforms.
- No longer require per-target configuration info in target.h
- or config/*/*; use new type module to store size, alignment.
- (ffecom_member_phase2): Declare COMMON/EQUIVALENCE group members
- so debugger sees them.
- (ffecom_finish_progunit): Transform all symbols in program unit,
- so -g will show they all exist.
-
- * expr.c (ffeexpr_collapse_substr): Handle strange substring
- range values.
-
- * info.h, info.c: Provide connection to new type module.
- Remove tests that yield compiler warnings.
-
- * intrin.c (ffeintrin_is_intrinsic): Properly handle deleted
- intrinsic.
-
- * lex.c (ffelex_file_fixed): Remove redundant/buggy code.
-
- * stc.c (ffestc_kindtype_kind_, ffestc_kindtype_star_): Replace
- boring switch stmt with simple call to new type module. This
- sort of thing is a reason to get up in the morning.
-
- * ste.c: Update to handle new interface for
- ffecom_push/pop_tempvar.
- Fixes to better track types of things.
- Fixes to not crash for certain diagnosed constructs.
- (ffeste_begin_iterdo_): Check only constants for overflow to avoid
- spurious diagnostics.
- Don't convert larger integer (say, INTEGER*8) to canonical integer
- for iteration count.
-
- * stw.h: Track DO iteration count temporary variable.
-
- * symbol.c: Remove consistency tests that cause compiler warnings.
-
- * target.c (ffetarget_aggregate_info): Replace big switch with
- little call to new type module.
- (ffetarget_layout): Remove consistency tests that cause
- compiler warnings.
- (ffetarget_convert_character1_typeless): Pick up length of
- typeless type from new type module.
-
- * target.h: Crash build if target float bit pattern cannot be
- precisely determined.
- Remove all the type cruft now determined by ffecom_init_0
- at invocation time and maintained in new type module.
- Put casts on second arg of all REAL_VALUE_TO_TARGET_DOUBLE
- uses so compiler warnings avoided (requires target float bit
- pattern to be precisely determined, hence code to crash build).
-
- * top.c: Add inits/terminates for new type module.
-
- * type.h, type.c: New module.
-
- * gbe/2.6.2.diff: Remove all patches to files in gcc/config/
- directory and its subdirectories.
-
-Mon Jan 9 19:23:25 1995 Dave Love <d.love@dl.ac.uk>
-
- * com.h (FFECOM_F2C_INTEGER_TYPE_NODE): Define and use instead of
- long_integer_type_node where appropriate.
-
-Tue Jan 3 14:56:18 1995 Dave Love <d.love@dl.ac.uk>
-
- * com.h: Make ffecom_f2c_logical_type_node long, consistent with
- integer.
-
-Fri Dec 2 20:07:37 1994 Dave Love <d.love@dl.ac.uk>
-
- * config-lang.in (stagestuff): Add f2c conditionally.
- * Make-lang.in: Add f2c and related targets.
- * f2c: Add the directory.
-
-Fri Nov 25 22:17:26 1994 Dave Love <d.love@dl.ac.uk>
-
- * Makefile.in (FLAGS_TO_PASS): pass $(CROSS)
- * Make-lang.in: more changes to runtime targets
-
-Thu Nov 24 18:03:21 1994 Dave Love <d.love@dl.ac.uk>
-
- * Makefile.in (FLAGS_TO_PASS): define for sub-makes
-
- * g77.c (main): change f77-cpp-output to f77-cpp-input (.F files)
-
-Wed Nov 23 15:22:53 1994 Dave Love <d.love@dl.ac.uk>
-
- * bad.c (ffebad_finish): kluge to fool emacs19 into finding errors:
- add trailing space to <file>:<line>:
-
-Tue Nov 22 11:30:50 1994 Dave Love <d.love@dl.ac.uk>
-
- * runtime/libF77/signal_.c (RETSIGTYPE): added
-
-Mon Nov 21 13:04:13 1994 Dave Love <d.love@dl.ac.uk>
-
- * Makefile.in (compiler): add runtime
-
- * config-lang.in (stagestuff): add libf2c.a to stagestuff
-
- * Make-lang.in:
- G77STAGESTUFF <- MORESTAGESTUFF
- f77-runtime: new target, plus supporting ones
-
- * runtime: add the directory, containing libI77, libF77 and autoconf
- stuff
-
- * g++.1: remove
-
- * g77.1: minor fixes
-
-Thu Nov 17 15:18:05 1994 Craig Burley (burley@gnu.ai.mit.edu)
-
- * Version 0.5.2 released.
-
- * bad.def: Modify wording of FFEBAD_UNIMPL_STMT to indicate
- that it covers a wide array of possible problems (that, someday,
- should be handled via separate diagnostics).
-
- * lex.c: Allow $ in identifiers if -fdollar-ok.
- * top.c: Support -fdollar-ok.
- * top.h: Support -fdollar-ok.
- * target.h: Support -fdollar-ok.
- * DOC: Describe -fdollar-ok.
-
- * std.c (ffestd_R1229_finish): Fix bug so stand-alone build works.
- * ste.c (ffeste_R819A): Fix bug so stand-alone build works.
-
- * Make: Improvements for stand-alone build.
-
- * Makefile.in: Fix copyright text at top of file.
-
- * LINK, SRCS, UNLINK: Removed. Not particularly useful now that
- g77 sources live in their own subdirectory.
-
- * g77.c (main): Cast arg to bzero to avoid warning. (This is
- identical to Kenner's fix to cp/g++.c.)
-
- * gbe/: New subdirectory, to contain .diff files for various
- versions of the GNU CC back end.
-
- * gbe/README: New file.
- * gbe/2.6.2.diff: New file.
-
-Tue Nov 8 10:23:10 1994 Dave Love <d.love@dl.ac.uk>
-
- * Make-lang.in: don't install as f77 as well as g77 to avoid
- confusion with system's compiler (especially while testing)
-
- * g77.c (main): use -lf2c and -lm; fix sense of test for .f/.F files
-
-Fri Oct 28 09:45:00 1994 Craig Burley (burley@gnu.ai.mit.edu)
-
- * Version 0.5.1 released.
-
- * gcc.c: Invoke f771 instead of f-771.
-
-Fri Oct 28 02:00:44 1994 Craig Burley (burley@gnu.ai.mit.edu)
-
- * Version 0.5.0 released.
-
-Fri Oct 14 15:03:35 1994 Craig Burley (burley@gnu.ai.mit.edu)
+See ChangeLog.0 for earlier changes.
- * Makefile.in: Handle the Fortran-77 front-end in a subdirectory.
- * f-*: Move Fortran-77 front-end to f/*.
+Local Variables:
+add-log-time-format: current-time-string
+End:
diff --git a/gcc/f/INSTALL b/gcc/f/INSTALL
index ab0d5b43fc4..e1bac001019 100644
--- a/gcc/f/INSTALL
+++ b/gcc/f/INSTALL
@@ -1,248 +1,40 @@
-This file contains installation information for the GNU Fortran
-compiler. Copyright (C) 1995, 1996 Free Software Foundation, Inc. You
-may copy, distribute, and modify it freely as long as you preserve this
-copyright notice and permission notice.
+*Note:* This file is automatically generated from the files
+`install0.texi' and `g77install.texi'. `INSTALL' is *not* a source
+file, although it is normally included within source distributions.
+
+ This file contains installation information for the GNU Fortran
+compiler. Copyright (C) {No Value For "copyrights-install"} Free
+Software Foundation, Inc. You may copy, distribute, and modify it
+freely as long as you preserve this copyright notice and permission
+notice.
Installing GNU Fortran
**********************
The following information describes how to install `g77'.
- Note that, for `egcs' users, much of this information is obsolete,
+ Note that, for `egcs' users, much of the information is obsolete,
and is superceded by the `egcs' installation procedures. Such
-information is explicitly flagged as such.
+information is accordingly omitted and flagged as such.
+
+ *Warning:* The information below is still under development, and
+might not accurately reflect the `g77' code base of which it is a part.
+Efforts are made to keep it somewhat up-to-date, but they are
+particularly concentrated on any version of this information that is
+distributed as part of a *released* `g77'.
- The information in this file generally pertains to dealing with
-*source* distributions of `g77' and `gcc'. It is possible that some of
-this information will be applicable to some *binary* distributions of
-these products--however, since these distributions are not made by the
-maintainers of `g77', responsibility for binary distributions rests with
-whoever built and first distributed them.
+ In particular, while this information is intended to apply to the
+EGCS-1.2 version of `g77', only an official *release* of that version
+is expected to contain documentation that is most consistent with the
+`g77' product in that version.
- Nevertheless, efforts to make `g77' easier to both build and install
-from source and package up as a binary distribution are ongoing.
+ The following information was last updated on 1999-03-13:
Prerequisites
=============
- *Version info:* For `egcs' users, the following information is
-superceded by the `egcs' installation instructions.
-
- The procedures described to unpack, configure, build, and install
-`g77' assume your system has certain programs already installed.
-
- The following prerequisites should be met by your system before you
-follow the `g77' installation instructions:
-
-`gzip' and `tar'
- To unpack the `gcc' and `g77' distributions, you'll need the
- `gunzip' utility in the `gzip' distribution. Most UNIX systems
- already have `gzip' installed. If yours doesn't, you can get it
- from the FSF.
-
- Note that you'll need `tar' and other utilities as well, but all
- UNIX systems have these. There are GNU versions of all these
- available--in fact, a complete GNU UNIX system can be put together
- on most systems, if desired.
-
- The version of GNU `gzip' used to package this release is
- 1.2.4. (The version of GNU `tar' used to package this release is
- 1.12.)
-
-`gcc-2.8.1.tar.gz'
- You need to have this, or some other applicable, version of `gcc'
- on your system. The version should be an exact copy of a
- distribution from the FSF. Its size is approximately 8.4MB.
-
- If you've already unpacked `gcc-2.8.1.tar.gz' into a directory
- (named `gcc-2.8.1') called the "source tree" for `gcc', you can
- delete the distribution itself, but you'll need to remember to
- skip any instructions to unpack this distribution.
-
- Without an applicable `gcc' source tree, you cannot build `g77'.
- You can obtain an FSF distribution of `gcc' from the FSF.
-
-`g77-0.5.24.tar.gz'
- You probably have already unpacked this package, or you are
- reading an advance copy of these installation instructions, which
- are contained in this distribution. The size of this package is
- approximately 1.4MB.
-
- You can obtain an FSF distribution of `g77' from the FSF, the same
- way you obtained `gcc'.
-
-Enough disk space
- The amount of disk space needed to unpack, build, install, and use
- `g77' depends on the type of system you're using, how you build
- `g77', and how much of it you install (primarily, which languages
- you install).
-
- The sizes shown below assume all languages distributed in
- `gcc-2.8.1', plus `g77', will be built and installed. These sizes
- are indicative of GNU/Linux systems on Intel x86 running COFF and
- on Digital Alpha (AXP) systems running ELF. These should be
- fairly representative of 32-bit and 64-bit systems, respectively.
-
- Note that all sizes are approximate and subject to change without
- notice! They are based on preliminary releases of g77 made shortly
- before the public beta release.
-
- -- `gcc' and `g77' distributions occupy 10MB packed, 40MB
- unpacked. These consist of the source code and documentation,
- plus some derived files (mostly documentation), for `gcc' and
- `g77'. Any deviations from these numbers for different kinds
- of systems are likely to be very minor.
-
- -- A "bootstrap" build requires an additional 91MB for a total
- of 132MB on an ix86, and an additional 136MB for a total of
- 177MB on an Alpha.
-
- -- Removing `gcc/stage1' after the build recovers 13MB for a
- total of 119MB on an ix86, and recovers 21MB for a total of
- 155MB on an Alpha.
-
- After doing this, the integrity of the build can still be
- verified via `make compare', and the `gcc' compiler modified
- and used to build itself for testing fairly quickly, using
- the copy of the compiler kept in `gcc/stage2'.
-
- -- Removing `gcc/stage2' after the build further recovers 39MB
- for a total of 80MB, and recovers 57MB for a total of 98MB on
- an Alpha.
-
- After doing this, the compiler can still be installed,
- especially if GNU `make' is used to avoid gratuitous rebuilds
- (or, the installation can be done by hand).
-
- -- Installing `gcc' and `g77' copies 23MB onto the `--prefix'
- disk for a total of 103MB on an ix86, and copies 31MB onto
- the `--prefix' disk for a total of 130MB on an Alpha.
-
- After installation, if no further modifications and builds of
- `gcc' or `g77' are planned, the source and build directory may be
- removed, leaving the total impact on a system's disk storage as
- that of the amount copied during installation.
-
- Systems with the appropriate version of `gcc' installed don't
- require the complete bootstrap build. Doing a "straight build"
- requires about as much space as does a bootstrap build followed by
- removing both the `gcc/stage1' and `gcc/stage2' directories.
-
- Installing `gcc' and `g77' over existing versions might require
- less *new* disk space, but note that, unlike many products, `gcc'
- installs itself in a way that avoids overwriting other installed
- versions of itself, so that other versions may easily be invoked
- (via `gcc -V VERSION').
-
- So, the amount of space saved as a result of having an existing
- version of `gcc' and `g77' already installed is not
- much--typically only the command drivers (`gcc', `g77', `g++', and
- so on, which are small) and the documentation is overwritten by
- the new installation. The rest of the new installation is done
- without replacing existing installed versions (assuming they have
- different version numbers).
-
-`make'
- Your system must have `make', and you will probably save yourself
- a lot of trouble if it is GNU `make' (sometimes referred to as
- `gmake'). In particular, you probably need GNU `make' to build
- outside the source directory (with `configure''s `--srcdir'
- option.)
-
- The version of GNU `make' used to develop this release is
- 3.76.1.
-
-`cc'
- Your system must have a working C compiler. If it doesn't, you
- might be able to obtain a prebuilt binary of some version of `gcc'
- from the network or on CD-ROM, perhaps from the FSF. The best
- source of information about binaries is probably a system-specific
- Usenet news group, initially via its FAQ.
-
- *Note Installing GNU CC: (gcc)Installation, for more information
- on prerequisites for installing `gcc'.
-
-`sed'
- All UNIX systems have `sed', but some have a broken version that
- cannot handle configuring, building, or installing `gcc' or `g77'.
-
- The version of GNU `sed' used to develop this release is
- 2.05. (Note that GNU `sed' version 3.0 was withdrawn by the
- FSF--if you happen to have this version installed, replace it with
- version 2.05 immediately. See a GNU distribution site for further
- explanation.)
-
-`root' access or equivalent
- To perform the complete installation procedures on a system, you
- need to have `root' access to that system, or equivalent access to
- the `--prefix' directory tree specified on the `configure' command
- line.
-
- Portions of the procedure (such as configuring and building `g77')
- can be performed by any user with enough disk space and virtual
- memory.
-
- However, these instructions are oriented towards less-experienced
- users who want to install `g77' on their own personal systems.
-
- System administrators with more experience will want to determine
- for themselves how they want to modify the procedures described
- below to suit the needs of their installation.
-
-`autoconf'
- The version of GNU `autoconf' used to develop this release is
- 2.12.
-
- `autoconf' is not needed in the typical case of installing `gcc'
- and `g77'. *Note Missing tools?::, for information on when it
- might be needed and how to work around not having it.
-
-`bison'
- The version of GNU `bison' used to develop this release is
- 1.25.
-
- `bison' is not needed in the typical case of installing `gcc' and
- `g77'. *Note Missing tools?::, for information on when it might
- be needed and how to work around not having it.
-
-`gperf'
- The version of GNU `gperf' used to develop this release is
- 2.5.
-
- `gperf' is not needed in the typical case of installing `gcc' and
- `g77'. *Note Missing tools?::, for information on when it might
- be needed and how to work around not having it.
-
-`makeinfo'
- The version of GNU `makeinfo' used to develop this release is
- 1.68.
-
- `makeinfo' is part of the GNU `texinfo' package; `makeinfo'
- version 1.68 is distributed as part of GNU `texinfo' version
- 3.11.
-
- `makeinfo' is not needed in the typical case of installing `gcc'
- and `g77'. *Note Missing tools?::, for information on when it
- might be needed and how to work around not having it.
-
- An up-to-date version of GNU `makeinfo' is still convenient when
- obtaining a new version of a GNU distribution such as `gcc' or
- `g77', as it allows you to obtain the `.diff.gz' file instead of
- the entire `.tar.gz' distribution (assuming you have installed
- `patch').
-
-`patch'
- The version of GNU `patch' used to develop this release is
- 2.5.
-
- Beginning with `g77' version 0.5.23, it is no longer necessary to
- patch the `gcc' back end to build `g77'.
-
- An up-to-date version of GNU `patch' is still convenient when
- obtaining a new version of a GNU distribution such as `gcc' or
- `g77', as it allows you to obtain the `.diff.gz' file instead of
- the entire `.tar.gz' distribution (assuming you have installed the
- tools needed to rebuild derived files, such as `makeinfo').
+ For `egcs' users, this information is superceded by the `egcs'
+installation instructions.
Problems Installing
===================
@@ -270,7 +62,7 @@ are no plans for an interim fix.
This requirement does not mean you must already have `gcc' installed
to build `g77'. As long as you have a working C compiler, you can use a
-bootstrap build to automate the process of first building `gcc' using
+"bootstrap" build to automate the process of first building `gcc' using
the working C compiler you have, then building `g77' and rebuilding
`gcc' using that just-built `gcc', and so on.
@@ -291,47 +83,7 @@ not yet established.
Missing strtoul or bsearch
..........................
- *Version info:* The following information does not apply to the
-`egcs' version of `g77'.
-
- On SunOS4 systems, linking the `f771' program used to produce an
-error message concerning an undefined symbol named `_strtoul', because
-the `strtoul' library function is not provided on that system.
-
- Other systems have, in the past, been reported to not provide their
-own `strtoul' or `bsearch' function.
-
- Some versions `g77' tried to default to providing bare-bones
-versions of `bsearch' and `strtoul' automatically, but every attempt at
-this has failed for at least one kind of system.
-
- To limit the failures to those few systems actually missing the
-required routines, the bare-bones versions are still provided, in
-`gcc/f/proj.c', if the appropriate macros are defined. These are
-`NEED_BSEARCH' for `bsearch' and `NEED_STRTOUL' for `NEED_STRTOUL'.
-
- Therefore, if you are sure your system is missing `bsearch' or
-`strtoul' in its library, define the relevant macro(s) before building
-`g77'. This can be done by editing `gcc/f/proj.c' and inserting either
-or both of the following `#define' statements before the comment shown:
-
- /* Insert #define statements here. */
-
- #define NEED_BSEARCH
- #define NEED_STRTOUL
-
- Then, continue configuring and building `g77' as usual.
-
- Or, you can define these on the `make' command line. To build with
-the bundled `cc' on SunOS4, for example, try:
- make bootstrap BOOT_CFLAGS='-O2 -g -DNEED_STRTOUL'
-
- If you then encounter problems compiling `gcc/f/proj.c', it might be
-due to a discrepancy between how `bsearch' or `strtoul' are defined by
-that file and how they're declared by your system's header files.
-
- In that case, you'll have to use some basic knowledge of C to work
-around the problem, perhaps by editing `gcc/f/proj.c' somewhat.
+ This information does not apply to the `egcs' version of `g77'.
Cleanup Kills Stage Directories
...............................
@@ -371,7 +123,7 @@ System-specific Problems
A linker bug on some versions of AIX 4.1 might prevent building when
`g77' is built within `gcc'. It might also occur when building within
-`egcs'. *Note LINKFAIL::.
+`egcs'.
Cross-compiler Problems
-----------------------
@@ -422,7 +174,7 @@ Changing Settings Before Building
=================================
Here are some internal `g77' settings that can be changed by editing
-source files in `gcc/f/' before building.
+source files in `egcs/gcc/f/' before building.
This information, and perhaps even these settings, represent
stop-gap solutions to problems people doing various ports of `g77' have
@@ -442,7 +194,7 @@ use of unit numbers higher than 99, you can change the value of the
`MXUNIT' macro, which represents the maximum unit number, to an
appropriately higher value.
- To do this, edit the file `f/runtime/libI77/fio.h' in your `g77'
+ To do this, edit the file `egcs/libf2c/libI77/fio.h' in your `g77'
source tree, changing the following line:
#define MXUNIT 100
@@ -491,8 +243,8 @@ are building, you might wish to modify the `g77' source tree so that
the version of `libg2c' is built with the `ALWAYS_FLUSH' macro defined,
enabling this behavior.
- To do this, find this line in `f/runtime/f2c.h' in your `g77' source
-tree:
+ To do this, find this line in `egcs/libf2c/f2c.h' in your `g77'
+source tree:
/* #define ALWAYS_FLUSH */
@@ -506,7 +258,7 @@ Maximum Stackable Size
`g77', on most machines, puts many variables and arrays on the stack
where possible, and can be configured (by changing
-`FFECOM_sizeMAXSTACKITEM' in `gcc/f/com.c') to force smaller-sized
+`FFECOM_sizeMAXSTACKITEM' in `egcs/gcc/f/com.c') to force smaller-sized
entities into static storage (saving on stack space) or permit
larger-sized entities to be put on the stack (which can improve
run-time performance, as it presents more opportunities for the GBE to
@@ -541,9 +293,9 @@ factor of 10.
This size currently is quite small, since `g77' currently has a
known bug requiring too much memory and time to handle such cases. In
-`gcc/f/data.c', the macro `FFEDATA_sizeTOO_BIG_INIT_' is defined to the
-minimum size for the warning to appear. The size is specified in
-storage units, which can be bytes, words, or whatever, on a
+`egcs/gcc/f/data.c', the macro `FFEDATA_sizeTOO_BIG_INIT_' is defined
+to the minimum size for the warning to appear. The size is specified
+in storage units, which can be bytes, words, or whatever, on a
case-by-case basis.
After changing this macro definition, you must (of course) rebuild
@@ -582,977 +334,18 @@ support 64-bit systems.
Quick Start
===========
- *Version info:* For `egcs' users, the following information is
-superceded by the `egcs' installation instructions.
-
- This procedure configures, builds, and installs `g77' "out of the
-box" and works on most UNIX systems. Each command is identified by a
-unique number, used in the explanatory text that follows. For the most
-part, the output of each command is not shown, though indications of
-the types of responses are given in a few cases.
-
- To perform this procedure, the installer must be logged in as user
-`root'. Much of it can be done while not logged in as `root', and
-users experienced with UNIX administration should be able to modify the
-procedure properly to do so.
-
- Following traditional UNIX conventions, it is assumed that the
-source trees for `g77' and `gcc' will be placed in `/usr/src'. It also
-is assumed that the source distributions themselves already reside in
-`/usr/FSF', a naming convention used by the author of `g77' on his own
-system:
-
- /usr/FSF/gcc-2.8.1.tar.gz
- /usr/FSF/g77-0.5.24.tar.gz
-
- If you vary *any* of the steps below, you might run into trouble,
-including possibly breaking existing programs for other users of your
-system. Before doing so, it is wise to review the explanations of some
-of the steps. These explanations follow this list of steps.
-
- sh[ 1]# cd /usr/src
-
- sh[ 2]# gunzip -c < /usr/FSF/gcc-2.8.1.tar.gz | tar xf -
- [Might say "Broken pipe"...that is normal on some systems.]
-
- sh[ 3]# gunzip -c < /usr/FSF/g77-0.5.24.tar.gz | tar xf -
- ["Broken pipe" again possible.]
-
- sh[ 4]# ln -s gcc-2.8.1 gcc
-
- sh[ 5]# ln -s g77-0.5.24 g77
-
- sh[ 6]# mv -i g77/* gcc
- [No questions should be asked by mv here; or, you made a mistake.]
-
- sh[ 7]# cd gcc
- sh[ 8]# ./configure --prefix=/usr
- [Do not do the above if gcc is not installed in /usr/bin.
- You might need a different --prefix=..., as
- described below.]
-
- sh[ 9]# make bootstrap
- [This takes a long time, and is where most problems occur.]
-
- sh[10]# make compare
- [This verifies that the compiler is `sane'.
- If any files are printed, you have likely found a g77 bug.]
-
- sh[11]# rm -fr stage1
-
- sh[12]# make -k install
- [The actual installation.]
-
- sh[13]# g77 -v
- [Verify that g77 is installed, obtain version info.]
-
- sh[14]#
-
- *Note Updating Your Info Directory: Updating Documentation, for
-information on how to update your system's top-level `info' directory
-to contain a reference to this manual, so that users of `g77' can
-easily find documentation instead of having to ask you for it.
-
- Elaborations of many of the above steps follows:
-
-Step 1: `cd /usr/src'
- You can build `g77' pretty much anyplace. By convention, this
- manual assumes `/usr/src'. It might be helpful if other users on
- your system knew where to look for the source code for the
- installed version of `g77' and `gcc' in any case.
-
-Step 3: `gunzip -d < /usr/FSF/g77-0.5.24.tar.gz | tar xf -'
- It is not always necessary to obtain the latest version of `g77'
- as a complete `.tar.gz' file if you have a complete, earlier
- distribution of `g77'. If appropriate, you can unpack that earlier
- version of `g77', and then apply the appropriate patches to
- achieve the same result--a source tree containing version
- 0.5.24 of `g77'.
-
-Step 4: `ln -s gcc-2.8.1 gcc'
-
-Step 5: `ln -s g77-0.5.24 g77'
- These commands mainly help reduce typing, and help reduce visual
- clutter in examples in this manual showing what to type to install
- `g77'.
-
- *Note Unpacking::, for information on using distributions of `g77'
- made by organizations other than the FSF.
-
-Step 6: `mv -i g77/* gcc'
- After doing this, you can, if you like, type `rm g77' and `rmdir
- g77-0.5.24' to remove the empty directory and the symbol link to
- it. But, it might be helpful to leave them around as quick
- reminders of which version(s) of `g77' are installed on your
- system.
-
- *Note Unpacking::, for information on the contents of the `g77'
- directory (as merged into the `gcc' directory).
-
-Step 8: `./configure --prefix=/usr'
- This is where you specify that the `g77' and `gcc' executables are
- to be installed in `/usr/bin/', the `g77' and `gcc' documentation
- is to be installed in `/usr/info/' and `/usr/man/', and so on.
-
- You should ensure that any existing installation of the `gcc'
- executable is in `/usr/bin/'.
-
- However, if that existing version of `gcc' is not 2.8.1, or if you
- simply wish to avoid risking overwriting it with a newly built
- copy of the same version, you can specify `--prefix=/usr/local'
- (which is the default) or some other path, and invoke the newly
- installed version directly from that path's `bin' directory.
-
- *Note Where in the World Does Fortran (and GNU CC) Go?: Where to
- Install, for more information on determining where to install
- `g77'. *Note Configuring gcc::, for more information on the
- configuration process triggered by invoking the `./configure'
- script.
-
-Step 9: `make bootstrap'
- *Note Installing GNU CC: (gcc)Installation, for information on the
- kinds of diagnostics you should expect during this procedure.
-
- *Note Building gcc::, for complete `g77'-specific information on
- this step.
-
-Step 10: `make compare'
- *Note Where to Port Bugs: Bug Lists, for information on where to
- report that you observed files having different contents during
- this phase.
-
- *Note How to Report Bugs: Bug Reporting, for information on *how*
- to report bugs like this.
-
-Step 11: `rm -fr stage1'
- You don't need to do this, but it frees up disk space.
-
-Step 12: `make -k install'
- If this doesn't seem to work, try:
-
- make -k install install-libf77
-
- Or, make sure you're using GNU `make'.
-
- *Note Installation of Binaries::, for more information.
-
- *Note Updating Your Info Directory: Updating Documentation, for
- information on entering this manual into your system's list of
- texinfo manuals.
-
-Step 13: `g77 -v'
- If this command prints approximately 25 lines of output, including
- the GNU Fortran Front End version number (which should be the same
- as the version number for the version of `g77' you just built and
- installed) and the version numbers for the three parts of the
- `libf2c' library (`libF77', `libI77', `libU77'), and those version
- numbers are all in agreement, then there is a high likelihood that
- the installation has been successfully completed.
-
- You might consider doing further testing. For example, log in as
- a non-privileged user, then create a small Fortran program, such
- as:
-
- PROGRAM SMTEST
- DO 10 I=1, 10
- PRINT *, 'Hello World #', I
- 10 CONTINUE
- END
-
- Compile, link, and run the above program, and, assuming you named
- the source file `smtest.f', the session should look like this:
-
- sh# g77 -o smtest smtest.f
- sh# ./smtest
- Hello World # 1
- Hello World # 2
- Hello World # 3
- Hello World # 4
- Hello World # 5
- Hello World # 6
- Hello World # 7
- Hello World # 8
- Hello World # 9
- Hello World # 10
- sh#
-
- If invoking `g77' doesn't seem to work, the problem might be that
- you've installed it in a location that is not in your shell's
- search path. For example, if you specified `--prefix=/gnu', and
- `/gnu/bin' is not in your `PATH' environment variable, you must
- explicitly specify the location of the compiler via `/gnu/bin/g77
- -o smtest smtest.f'.
-
- After proper installation, you don't need to keep your gcc and g77
- source and build directories around anymore. Removing them can
- free up a lot of disk space.
+ For `egcs' users, this information is superceded by the `egcs'
+installation instructions.
Complete Installation
=====================
- *Version info:* For `egcs' users, the following information is
-mostly superceded by the `egcs' installation instructions.
-
- Here is the complete `g77'-specific information on how to configure,
-build, and install `g77'.
-
-Unpacking
----------
-
- The `gcc' source distribution is a stand-alone distribution. It is
-designed to be unpacked (producing the `gcc' source tree) and built as
-is, assuming certain prerequisites are met (including the availability
-of compatible UNIX programs such as `make', `cc', and so on).
-
- However, before building `gcc', you will want to unpack and merge
-the `g77' distribution in with it, so that you build a Fortran-capable
-version of `gcc', which includes the `g77' command, the necessary
-run-time libraries, and this manual.
-
- Unlike `gcc', the `g77' source distribution is *not* a stand-alone
-distribution. It is designed to be unpacked and, afterwards,
-immediately merged into an applicable `gcc' source tree. That is, the
-`g77' distribution *augments* a `gcc' distribution--without `gcc',
-generally only the documentation is immediately usable.
-
- A sequence of commands typically used to unpack `gcc' and `g77' is:
-
- sh# cd /usr/src
- sh# gunzip -c /usr/FSF/gcc-2.8.1.tar.gz | tar xf -
- sh# gunzip -c /usr/FSF/g77-0.5.24.tar.gz | tar xf -
- sh# ln -s gcc-2.8.1 gcc
- sh# ln -s g77-0.5.24 g77
- sh# mv -i g77/* gcc
-
- *Notes:* The commands beginning with `gunzip...' might print `Broken
-pipe...' as they complete. That is nothing to worry about, unless you
-actually *hear* a pipe breaking. The `ln' commands are helpful in
-reducing typing and clutter in installation examples in this manual.
-Hereafter, the top level of `gcc' source tree is referred to as `gcc',
-and the top level of just the `g77' source tree (prior to issuing the
-`mv' command, above) is referred to as `g77'.
-
- There are three top-level names in a `g77' distribution:
-
- g77/COPYING.g77
- g77/README.g77
- g77/f
-
- All three entries should be moved (or copied) into a `gcc' source
-tree (typically named after its version number and as it appears in the
-FSF distributions--e.g. `gcc-2.8.1').
-
- `g77/f' is the subdirectory containing all of the code,
-documentation, and other information that is specific to `g77'. The
-other two files exist to provide information on `g77' to someone
-encountering a `gcc' source tree with `g77' already present, who has
-not yet read these installation instructions and thus needs help
-understanding that the source tree they are looking at does not come
-from a single FSF distribution. They also help people encountering an
-unmerged `g77' source tree for the first time.
-
- *Note:* Please use *only* `gcc' and `g77' source trees as
-distributed by the FSF. Use of modified versions is likely to result
-in problems that appear to be in the `g77' code but, in fact, are not.
-Do not use such modified versions unless you understand all the
-differences between them and the versions the FSF distributes--in which
-case you should be able to modify the `g77' (or `gcc') source trees
-appropriately so `g77' and `gcc' can coexist as they do in the stock
-FSF distributions.
-
-Merging Distributions
----------------------
-
- After merging the `g77' source tree into the `gcc' source tree, you
-have put together a complete `g77' source tree.
-
- As of version 0.5.23, `g77' no longer modifies the version number of
-`gcc', nor does it patch `gcc' itself.
-
- `g77' still depends on being merged with an appropriate version of
-`gcc'. For version 0.5.24 of `g77', the specific version of `gcc'
-supported is 2.8.1.
-
- However, other versions of `gcc' might be suitable "hosts" for this
-version of `g77'.
-
- GNU version numbers make it easy to figure out whether a particular
-version of a distribution is newer or older than some other version of
-that distribution. The format is, generally, MAJOR.MINOR.PATCH, with
-each field being a decimal number. (You can safely ignore leading
-zeros; for example, 1.5.3 is the same as 1.5.03.) The MAJOR field only
-increases with time. The other two fields are reset to 0 when the
-field to their left is incremented; otherwise, they, too, only increase
-with time. So, version 2.6.2 is newer than version 2.5.8, and version
-3.0 is newer than both. (Trailing `.0' fields often are omitted in
-announcements and in names for distributions and the directories they
-create.)
-
- If your version of `gcc' is older than the oldest version supported
-by `g77' (as casually determined by listing the contents of
-`gcc/f/INSTALL/', which contains these installation instructions in
-plain-text format), you should obtain a newer, supported version of
-`gcc'. (You could instead obtain an older version of `g77', or try and
-get your `g77' to work with the old `gcc', but neither approach is
-recommended, and you shouldn't bother reporting any bugs you find if you
-take either approach, because they're probably already fixed in the
-newer versions you're not using.)
-
- If your version of `gcc' is newer than the newest version supported
-by `g77', it is possible that your `g77' will work with it anyway. If
-the version number for `gcc' differs only in the PATCH field, you might
-as well try that version of `gcc'. Since it has the same MAJOR and
-MINOR fields, the resulting combination is likely to work.
-
- So, for example, if a particular version of `g77' has support for
-`gcc' versions 2.8.0 and 2.8.1, it is likely that `gcc-2.8.2' would
-work well with `g77'.
-
- However, `gcc-2.9.0' would almost certainly not work with that
-version of `g77' without appropriate modifications, so a new version of
-`g77' would be needed (and you should wait for it rather than bothering
-the maintainers--*note User-Visible Changes: Changes.).
-
- This complexity is the result of `gcc' and `g77' being separate
-distributions. By keeping them separate, each product is able to be
-independently improved and distributed to its user base more frequently.
-
- However, the GBE interface defined by `gcc' typically undergoes some
-incompatible changes at least every time the MINOR field of the version
-number is incremented, and such changes require corresponding changes to
-the `g77' front end (FFE).
-
-Where in the World Does Fortran (and GNU CC) Go?
-------------------------------------------------
-
- Before configuring, you should make sure you know where you want the
-`g77' and `gcc' binaries to be installed after they're built, because
-this information is given to the configuration tool and used during the
-build itself.
-
- A `g77' installation normally includes installation of a
-Fortran-aware version of `gcc', so that the `gcc' command recognizes
-Fortran source files and knows how to compile them.
-
- For this to work, the version of `gcc' that you will be building as
-part of `g77' *must* be installed as the "active" version of `gcc' on
-the system.
-
- Sometimes people make the mistake of installing `gcc' as
-`/usr/local/bin/gcc', leaving an older, non-Fortran-aware version in
-`/usr/bin/gcc'. (Or, the opposite happens.) This can result in `gcc'
-being unable to compile Fortran source files, because when the older
-version of `gcc' is invoked, it complains that it does not recognize
-the language, or the file name suffix.
-
- So, determine whether `gcc' already is installed on your system,
-and, if so, *where* it is installed, and prepare to configure the new
-version of `gcc' you'll be building so that it installs over the
-existing version of `gcc'.
-
- You might want to back up your existing copy of `/usr/bin/gcc', and
-the entire `/usr/lib' directory, before you perform the actual
-installation (as described in this manual).
-
- Existing `gcc' installations typically are found in `/usr' or
-`/usr/local'. (This means the commands are installed in `/usr/bin' or
-`/usr/local/bin', the libraries in `/usr/lib' or `/usr/local/lib', and
-so on.)
-
- If you aren't certain where the currently installed version of `gcc'
-and its related programs reside, look at the output of this command:
-
- gcc -v -o /tmp/delete-me -xc /dev/null -xnone
-
- All sorts of interesting information on the locations of various
-`gcc'-related programs and data files should be visible in the output
-of the above command. (The output also is likely to include a
-diagnostic from the linker, since there's no `main_()' function.)
-However, you do have to sift through it yourself; `gcc' currently
-provides no easy way to ask it where it is installed and where it looks
-for the various programs and data files it calls on to do its work.
-
- Just *building* `g77' should not overwrite any installed
-programs--but, usually, after you build `g77', you will want to install
-it, so backing up anything it might overwrite is a good idea. (This is
-true for any package, not just `g77', though in this case it is
-intentional that `g77' overwrites `gcc' if it is already installed--it
-is unusual that the installation process for one distribution
-intentionally overwrites a program or file installed by another
-distribution, although, in this case, `g77' is an augmentation of the
-`gcc' distribution.)
-
- Another reason to back up the existing version first, or make sure
-you can restore it easily, is that it might be an older version on
-which other users have come to depend for certain behaviors. However,
-even the new version of `gcc' you install will offer users the ability
-to specify an older version of the actual compilation programs if
-desired, and these older versions need not include any `g77' components.
-*Note Specifying Target Machine and Compiler Version: (gcc)Target
-Options, for information on the `-V' option of `gcc'.
-
-Configuring GNU CC
-------------------
-
- `g77' is configured automatically when you configure `gcc'. There
-are two parts of `g77' that are configured in two different
-ways--`g77', which "camps on" to the `gcc' configuration mechanism, and
-`libg2c', which uses a variation of the GNU `autoconf' configuration
-system.
-
- Generally, you shouldn't have to be concerned with either `g77' or
-`libg2c' configuration, unless you're configuring `g77' as a
-cross-compiler. In this case, the `libg2c' configuration, and possibly
-the `g77' and `gcc' configurations as well, might need special
-attention. (This also might be the case if you're porting `gcc' to a
-whole new system--even if it is just a new operating system on an
-existing, supported CPU.)
-
- To configure the system, see *Note Installing GNU CC:
-(gcc)Installation, following the instructions for running `./configure'.
-Pay special attention to the `--prefix=' option, which you almost
-certainly will need to specify.
-
- (Note that `gcc' installation information is provided as a
-plain-text file in `gcc/INSTALL'.)
-
- The information printed by the invocation of `./configure' should
-show that the `f' directory (the Fortran language) has been configured.
-If it does not, there is a problem.
-
- *Note:* Configuring with the `--srcdir' argument, or by starting in
-an empty directory and typing a command such as `../gcc/configure' to
-build with separate build and source directories, is known to work with
-GNU `make', but it is known to not work with other variants of `make'.
-Irix5.2 and SunOS4.1 versions of `make' definitely won't work outside
-the source directory at present.
-
- `g77''s portion of the `configure' script used to issue a warning
-message about this when configuring for building binaries outside the
-source directory, but no longer does this as of version 0.5.23.
-
- Instead, `g77' simply rejects most common attempts to build it using
-a non-GNU `make' when the build directory is not the same as the source
-directory, issuing an explanatory diagnostic.
-
-Building GNU CC
----------------
-
- Building `g77' requires building enough of `gcc' that these
-instructions assume you're going to build all of `gcc', including
-`g++', `protoize', and so on. You can save a little time and disk
-space by changes the `LANGUAGES' macro definition in `gcc/Makefile.in'
-or `gcc/Makefile', but if you do that, you're on your own. One change
-is almost *certainly* going to cause failures: removing `c' or `f77'
-from the definition of the `LANGUAGES' macro.
-
- After configuring `gcc', which configures `g77' and `libg2c'
-automatically, you're ready to start the actual build by invoking
-`make'.
-
- *Note:* You *must* have run the `configure' script in `gcc' before
-you run `make', even if you're using an already existing `gcc'
-development directory, because `./configure' does the work to recognize
-that you've added `g77' to the configuration.
-
- There are two general approaches to building GNU CC from scratch:
-
-"bootstrap"
- This method uses minimal native system facilities to build a
- barebones, unoptimized `gcc', that is then used to compile
- ("bootstrap") the entire system.
-
-"straight"
- This method assumes a more complete native system exists, and uses
- that just once to build the entire system.
-
- On all systems without a recent version of `gcc' already installed,
-the bootstrap method must be used. In particular, `g77' uses
-extensions to the C language offered, apparently, only by `gcc'.
-
- On most systems with a recent version of `gcc' already installed,
-the straight method can be used. This is an advantage, because it
-takes less CPU time and disk space for the build. However, it does
-require that the system have fairly recent versions of many GNU
-programs and other programs, which are not enumerated here.
-
-Bootstrap Build
-...............
-
- A complete bootstrap build is done by issuing a command beginning
-with `make bootstrap ...', as described in *Note Installing GNU CC:
-(gcc)Installation. This is the most reliable form of build, but it
-does require the most disk space and CPU time, since the complete system
-is built twice (in Stages 2 and 3), after an initial build (during
-Stage 1) of a minimal `gcc' compiler using the native compiler and
-libraries.
-
- You might have to, or want to, control the way a bootstrap build is
-done by entering the `make' commands to build each stage one at a time,
-as described in the `gcc' manual. For example, to save time or disk
-space, you might want to not bother doing the Stage 3 build, in which
-case you are assuming that the `gcc' compiler you have built is
-basically sound (because you are giving up the opportunity to compare a
-large number of object files to ensure they're identical).
-
- To save some disk space during installation, after Stage 2 is built,
-you can type `rm -fr stage1' to remove the binaries built during Stage
-1.
-
- Also, *Note Installing GNU CC: (gcc)Installation, for important
-information on building `gcc' that is not described in this `g77'
-manual. For example, explanations of diagnostic messages and whether
-they're expected, or indicate trouble, are found there.
-
-Straight Build
-..............
-
- If you have a recent version of `gcc' already installed on your
-system, and if you're reasonably certain it produces code that is
-object-compatible with the version of `gcc' you want to build as part
-of building `g77', you can save time and disk space by doing a straight
-build.
-
- To build just the compilers along with the necessary run-time
-libraries, issue the following command:
-
- make -k CC=gcc
-
- If you run into problems using this method, you have two options:
-
- * Abandon this approach and do a bootstrap build.
-
- * Try to make this approach work by diagnosing the problems you're
- running into and retrying.
-
- Especially if you do the latter, you might consider submitting any
-solutions as bug/fix reports. *Note Known Causes of Trouble with GNU
-Fortran: Trouble.
-
- However, understand that many problems preventing a straight build
-from working are not `g77' problems, and, in such cases, are not likely
-to be addressed in future versions of `g77'. Consider treating them as
-`gcc' bugs instead.
-
-Pre-installation Checks
------------------------
-
- Before installing the system, which includes installing `gcc', you
-might want to do some minimum checking to ensure that some basic things
-work.
-
- Here are some commands you can try, and output typically printed by
-them when they work:
-
- sh# cd /usr/src/gcc
- sh# ./g77 -B./ -v
- g77 version 0.5.24
- Driving: ./g77 -B./ -v -c -xf77-version /dev/null -xnone
- Reading specs from ./specs
- gcc version 2.8.1
- cpp -lang-c -v -isystem ./include -undef -D__GNUC__=2 ...
- GNU CPP version 2.8.1 (Alpha GNU/Linux with ELF)
- #include "..." search starts here:
- #include <...> search starts here:
- include
- /usr/alpha-linux/include
- /usr/lib/gcc-lib/alpha-linux/2.8.1/include
- /usr/include
- End of search list.
- ./f771 -fnull-version -quiet -dumpbase g77-version.f -version ...
- GNU F77 version 2.8.1 (alpha-linux) compiled ...
- GNU Fortran Front End version 0.5.24
- as -nocpp -o /tmp/cca14485.o /tmp/cca14485.s
- ld -m elf64alpha -G 8 -O1 -dynamic-linker /lib/ld-linux.so.2 ...
- /tmp/cca14485
- __G77_LIBF77_VERSION__: 0.5.24
- @(#)LIBF77 VERSION 19970919
- __G77_LIBI77_VERSION__: 0.5.24
- @(#) LIBI77 VERSION pjw,dmg-mods 19980405
- __G77_LIBU77_VERSION__: 0.5.24
- @(#) LIBU77 VERSION 19970919
- sh# ./xgcc -B./ -v -o /tmp/delete-me -xc /dev/null -xnone
- Reading specs from ./specs
- gcc version 2.8.1
- ./cpp -lang-c -v -isystem ./include -undef ...
- GNU CPP version 2.8.1 (Alpha GNU/Linux with ELF)
- #include "..." search starts here:
- #include <...> search starts here:
- include
- /usr/alpha-linux/include
- /usr/lib/gcc-lib/alpha-linux/2.8.1/include
- /usr/include
- End of search list.
- ./cc1 /tmp/cca18063.i -quiet -dumpbase null.c -version ...
- GNU C version 2.8.1 (alpha-linux) compiled ...
- as -nocpp -o /tmp/cca180631.o /tmp/cca18063.s
- ld -m elf64alpha -G 8 -O1 -dynamic-linker /lib/ld-linux.so.2 ...
- /usr/lib/crt1.o: In function `_start':
- ../sysdeps/alpha/elf/start.S:77: undefined reference to `main'
- ../sysdeps/alpha/elf/start.S:77: undefined reference to `main'
- sh#
-
- (Note that long lines have been truncated, and `...' used to
-indicate such truncations.)
-
- The above two commands test whether `g77' and `gcc', respectively,
-are able to compile empty (null) source files, whether invocation of
-the C preprocessor works, whether libraries can be linked, and so on.
-
- If the output you get from either of the above two commands is
-noticeably different, especially if it is shorter or longer in ways
-that do not look consistent with the above sample output, you probably
-should not install `gcc' and `g77' until you have investigated further.
-
- For example, you could try compiling actual applications and seeing
-how that works. (You might want to do that anyway, even if the above
-tests work.)
-
- To compile using the not-yet-installed versions of `gcc' and `g77',
-use the following commands to invoke them.
-
- To invoke `g77', type:
-
- /usr/src/gcc/g77 -B/usr/src/gcc/ ...
-
- To invoke `gcc', type:
-
- /usr/src/gcc/xgcc -B/usr/src/gcc/ ...
-
-Installation of Binaries
-------------------------
-
- After configuring, building, and testing `g77' and `gcc', when you
-are ready to install them on your system, type:
-
- make -k CC=gcc install
-
- As described in *Note Installing GNU CC: (gcc)Installation, the
-values for the `CC' and `LANGUAGES' macros should be the same as those
-you supplied for the build itself.
-
- So, the details of the above command might vary if you used a
-bootstrap build (where you might be able to omit both definitions, or
-might have to supply the same definitions you used when building the
-final stage) or if you deviated from the instructions for a straight
-build.
-
- If the above command does not install `libg2c.a' as expected, try
-this:
-
- make -k ... install install-libf77
-
- We don't know why some non-GNU versions of `make' sometimes require
-this alternate command, but they do. (Remember to supply the
-appropriate definition for `CC' where you see `...' in the above
-command.)
-
- Note that using the `-k' option tells `make' to continue after some
-installation problems, like not having `makeinfo' installed on your
-system. It might not be necessary for your system.
-
- *Note:* `g77' no longer installs files not directly part of `g77',
-such as `/usr/bin/f77', `/usr/lib/libf2c.a', and `/usr/include/f2c.h',
-or their `/usr/local' equivalents.
-
- *Note Distributing Binaries::, for information on how to accommodate
-systems with no existing non-`g77' `f77' compiler and systems with
-`f2c' installed.
-
-Updating Your Info Directory
-----------------------------
-
- As part of installing `g77', you should make sure users of `info'
-can easily access this manual on-line.
-
- `g77' does this automatically by invoking the `install-info' command
-when you use `make install' to install `g77'.
-
- If that fails, or if the `info' directory it updates is not the one
-normally accessed by users, consider invoking it yourself. For example:
-
- install-info --info-dir=/usr/info /usr/info/g77.info
-
- The above example assumes the `g77' documentation already is
-installed in `/usr/info' and that `/usr/info/dir' is the file you wish
-to update. Adjust the command accordingly, if those assumptions are
-wrong.
-
-Missing tools?
---------------
-
- A build of `gcc' might fail due to one or more tools being called
-upon by `make' (during the build or install process), when those tools
-are not installed on your system.
-
- This situation can result from any of the following actions
-(performed by you or someone else):
-
- * Changing the source code or documentation yourself (as a developer
- or technical writer).
-
- * Applying a patch that changes the source code or documentation
- (including, sometimes, the official patches distributed by the
- FSF).
-
- * Deleting the files that are created by the (missing) tools.
-
- The `make maintainer-clean' command is supposed to delete these
- files, so invoking this command without having all the appropriate
- tools installed is not recommended.
-
- * Creating the source directory using a method that does not
- preserve the date-time-modified information in the original
- distribution.
-
- For example, the UNIX `cp -r' command copies a directory tree
- without preserving the date-time-modified information. Use `cp
- -pr' instead.
-
- The reason these activities cause `make' to try and invoke tools
-that it probably wouldn't when building from a perfectly "clean" source
-directory containing `gcc' and `g77' is that some files in the source
-directory (and the corresponding distribution) aren't really source
-files, but *derived* files that are produced by running tools with the
-corresponding source files as input. These derived files "depend", in
-`make' terminology, on the corresponding source files.
-
- `make' determines that a file that depends on another needs to be
-updated if the date-time-modified information for the source file shows
-that it is newer than the corresponding information for the derived
-file.
-
- If it makes that determination, `make' runs the appropriate commands
-(specified in the "Makefile") to update the derived file, and this
-process typically calls upon one or more installed tools to do the work.
-
- The "safest" approach to dealing with this situation is to recreate
-the `gcc' and `g77' source directories from complete `gcc' and `g77'
-distributions known to be provided by the FSF.
-
- Another fairly "safe" approach is to simply install the tools you
-need to complete the build process. This is especially appropriate if
-you've changed the source code or applied a patch to do so.
-
- However, if you're certain that the problem is limited entirely to
-incorrect date-time-modified information, that there are no
-discrepancies between the contents of source files and files derived
-from them in the source directory, you can often update the
-date-time-modified information for the derived files to work around the
-problem of not having the appropriate tools installed.
-
- On UNIX systems, the simplest way to update the date-time-modified
-information of a file is to use the use the `touch' command.
-
- How to use `touch' to update the derived files updated by each of
-the tools is described below. *Note:* New versions of `g77' might
-change the set of files it generates by invoking each of these tools.
-If you cannot figure out for yourself how to handle such a situation,
-try an older version of `g77' until you find someone who can (or until
-you obtain and install the relevant tools).
-
-Missing `autoconf'?
-...................
-
- If you cannot install `autoconf', make sure you have started with a
-*fresh* distribution of `gcc' and `g77', do *not* do `make
-maintainer-clean', and, to ensure that `autoconf' is not invoked by
-`make' during the build, type these commands:
-
- sh# cd gcc/f/runtime
- sh# touch configure libU77/configure
- sh# cd ../../..
- sh#
-
-Missing `bison'?
-................
-
- If you cannot install `bison', make sure you have started with a
-*fresh* distribution of `gcc', do *not* do `make maintainer-clean',
-and, to ensure that `bison' is not invoked by `make' during the build,
-type these commands:
-
- sh# cd gcc
- sh# touch bi-parser.c bi-parser.h c-parse.c c-parse.h cexp.c
- sh# touch cp/parse.c cp/parse.h objc-parse.c
- sh# cd ..
- sh#
-
-Missing `gperf'?
-................
-
- If you cannot install `gperf', make sure you have started with a
-*fresh* distribution of `gcc', do *not* do `make maintainer-clean',
-and, to ensure that `gperf' is not invoked by `make' during the build,
-type these commands:
-
- sh# cd gcc
- sh# touch c-gperf.h
- sh# cd ..
- sh#
-
-Missing `makeinfo'?
-...................
-
- If `makeinfo' is needed but unavailable when installing (via `make
-install'), some files, like `libg2c.a', might not be installed, because
-once `make' determines that it cannot invoke `makeinfo', it cancels any
-further processing.
-
- If you cannot install `makeinfo', an easy work-around is to specify
-`MAKEINFO=true' on the `make' command line, or to specify the `-k'
-option (`make -k install').
-
- Another approach is to force the relevant files to be up-to-date by
-typing these commands and then re-trying the installation step:
-
- sh# cd gcc
- sh# touch f/g77.info f/BUGS f/INSTALL f/NEWS
- sh# cd ..
- sh#
+ For `egcs' users, this information is superceded by the `egcs'
+installation instructions.
Distributing Binaries
=====================
- If you are building `g77' for distribution to others in binary form,
-first make sure you are aware of your legal responsibilities (read the
-file `gcc/COPYING' thoroughly).
-
- Then, consider your target audience and decide where `g77' should be
-installed.
-
- For systems like GNU/Linux that have no native Fortran compiler (or
-where `g77' could be considered the native compiler for Fortran and
-`gcc' for C, etc.), you should definitely configure `g77' for
-installation in `/usr/bin' instead of `/usr/local/bin'. Specify the
-`--prefix=/usr' option when running `./configure'.
-
- You might also want to set up the distribution so the `f77' command
-is a link to `g77', although a script that accepts "classic" UNIX `f77'
-options and translates the command-line to the appropriate `g77'
-command line would be more appropriate. If you do this, *please* also
-provide a "man page" in `man/man1/f77.1' describing the command. (A
-link to `man/man1/g77.1' is appropriate if `bin/f77' is a link to
-`bin/g77'.)
-
- For a system that might already have `f2c' installed, consider
-whether inter-operation with `g77' will be important to users of `f2c'
-on that system. If you want to improve the likelihood that users will
-be able to use both `f2c' and `g77' to compile code for a single program
-without encountering link-time or run-time incompatibilities, make sure
-that, whenever they intend to combine `f2c'-produced code with
-`g77'-produced code in an executable, they:
-
- * Use the `lib/gcc-lib/.../include/g2c.h' file generated by the
- `g77' build in place of the `f2c.h' file that normally comes with
- `f2c' (or versions of `g77' prior to 0.5.23) when compiling *all*
- of the `f2c'-produced C code
-
- * Link to the `lib/gcc-lib/.../libg2c.a' library built by the `g77'
- build instead of the `libf2c.a' library that normally comes with
- `f2c' (or versions of `g77' prior to 0.5.23)
-
- How you choose to effect the above depends on whether the existing
-installation of `f2c' must be maintained.
-
- In any case, it is important to try and ensure that the installation
-keeps working properly even after subsequent re-installation of `f2c',
-which probably involves overwriting `/usr/local/lib/libf2c.a' and
-`/usr/local/include/f2c.h', or similar.
-
- At least, copying `libg2c.a' and `g2c.h' into the appropriate
-"public" directories allows users to more easily select the version of
-`libf2c' they wish to use for a particular build. The names are
-changed by `g77' to make this coexistence easier to maintain; even if
-`f2c' is installed later, the `g77' files normally installed by its
-installation process aren't disturbed. Use of symbolic links from one
-set of files to another might result in problems after a subsequent
-reinstallation of either `f2c' or `g77', so be sure to alert users of
-your distribution accordingly.
-
- (Make sure you clearly document, in the description of your
-distribution, how installation of your distribution will affect
-existing installations of `gcc', `f2c', `f77', `libf2c.a', and so on.
-Similarly, you should clearly document any requirements you assume will
-be met by users of your distribution.)
-
- For other systems with native `f77' (and `cc') compilers, configure
-`g77' as you (or most of your audience) would configure `gcc' for their
-installations. Typically this is for installation in `/usr/local', and
-would not include a new version of `/usr/bin/f77' or
-`/usr/local/bin/f77', so users could still use the native `f77'.
-
- In any case, for `g77' to work properly, you *must* ensure that the
-binaries you distribute include:
-
-`bin/g77'
- This is the command most users use to compile Fortran.
-
-`bin/gcc'
- This is the command some users use to compile Fortran, typically
- when compiling programs written in other languages at the same
- time. The `bin/gcc' executable file must have been built from a
- `gcc' source tree into which a `g77' source tree was merged and
- configured, or it will not know how to compile Fortran programs.
-
-`info/g77.info*'
- This is the documentation for `g77'. If it is not included, users
- will have trouble understanding diagnostics messages and other
- such things, and will send you a lot of email asking questions.
-
- Please edit this documentation (by editing `gcc/f/*.texi' and
- doing `make doc' from the `/usr/src/gcc' directory) to reflect any
- changes you've made to `g77', or at least to encourage users of
- your binary distribution to report bugs to you first.
-
- Also, whether you distribute binaries or install `g77' on your own
- system, it might be helpful for everyone to add a line listing
- this manual by name and topic to the top-level `info' node in
- `/usr/info/dir'. That way, users can find `g77' documentation more
- easily. *Note Updating Your Info Directory: Updating
- Documentation.
-
-`man/man1/g77.1'
- This is the short man page for `g77'. It is not always kept
- up-to-date, but you might as well include it for people who really
- like "man" pages.
-
-`lib/gcc-lib'
- This is the directory containing the "private" files installed by
- and for `gcc', `g77', `g++', and other GNU compilers.
-
-`lib/gcc-lib/.../f771'
- This is the actual Fortran compiler.
-
-`lib/gcc-lib/.../libg2c.a'
- This is the run-time library for `g77'-compiled programs.
-
- Whether you want to include the slightly updated (and possibly
-improved) versions of `cc1', `cc1plus', and whatever other binaries get
-rebuilt with the changes the GNU Fortran distribution makes to the GNU
-back end, is up to you. These changes are highly unlikely to break any
-compilers, because they involve doing things like adding to the list of
-acceptable compiler options (so, for example, `cc1plus' accepts, and
-ignores, options that only `f771' actually processes).
-
- Please assure users that unless they have a specific need for their
-existing, older versions of `gcc' command, they are unlikely to
-experience any problems by overwriting it with your version--though
-they could certainly protect themselves by making backup copies first!
-
- Otherwise, users might try and install your binaries in a "safe"
-place, find they cannot compile Fortran programs with your distribution
-(because, perhaps, they're invoking their old version of the `gcc'
-command, which does not recognize Fortran programs), and assume that
-your binaries (or, more generally, GNU Fortran distributions in
-general) are broken, at least for their system.
-
- Finally, *please* ask for bug reports to go to you first, at least
-until you're sure your distribution is widely used and has been well
-tested. This especially goes for those of you making any changes to
-the `g77' sources to port `g77', e.g. to OS/2. <fortran@gnu.org> has
-received a fair number of bug reports that turned out to be problems
-with other peoples' ports and distributions, about which nothing could
-be done for the user. Once you are quite certain a bug report does not
-involve your efforts, you can forward it to us.
+ For `egcs' users, this information is superceded by the `egcs'
+installation instructions.
diff --git a/gcc/f/Make-lang.in b/gcc/f/Make-lang.in
index a180760348a..c1a2814cd18 100644
--- a/gcc/f/Make-lang.in
+++ b/gcc/f/Make-lang.in
@@ -59,16 +59,6 @@ F77 f77: f771$(exeext)
f77.extraclean f77.maintainer-clean f77.distdir f77.rebuilt \
f77.stage1 f77.stage2 f77.stage3 f77.stage4
-g77.c: $(srcdir)/gcc.c
- case "$(LANGUAGES)" in \
- *[fF]77*) touch lang-f77;; \
- *) rm -f lang-f77;; \
- esac
- if [ -f lang-f77 ]; then \
- rm -f g77.c; \
- $(LN_S) $(srcdir)/gcc.c g77.c; \
- else true; fi
-
g77spec.o: $(srcdir)/f/g77spec.c $(srcdir)/f/version.h
case "$(LANGUAGES)" in \
*[fF]77*) touch lang-f77;; \
@@ -88,26 +78,12 @@ g77version.o: $(srcdir)/f/version.c
$(srcdir)/f/version.c; \
else true; fi
-# N.B.: This is a copy of the gcc.o rule, with -DLANG_SPECIFIC_DRIVER added.
-# It'd be nice if we could find an easier way to do this---rather than have
-# to track changes to the toplevel gcc Makefile as well.
-# We depend on g77.c last, to make it obvious where it came from.
-g77.o: $(CONFIG_H) multilib.h config.status $(lang_specs_files) g77.c
- case "$(LANGUAGES)" in \
- *[fF]77*) touch lang-f77;; \
- *) rm -f lang-f77;; \
- esac
- if [ -f lang-f77 ]; then \
- $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $(DRIVER_DEFINES) \
- -DLANG_SPECIFIC_DRIVER -c g77.c; \
- else true; fi
-
# Create the compiler driver for g77.
-g77$(exeext): g77.o g77spec.o g77version.o version.o choose-temp.o pexecute.o prefix.o mkstemp.o \
+g77$(exeext): gcc.o g77spec.o g77version.o version.o prefix.o intl.o \
$(LIBDEPS) $(EXTRA_GCC_OBJS)
if [ -f lang-f77 ]; then \
- $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ g77.o g77spec.o g77version.o \
- version.o choose-temp.o pexecute.o prefix.o mkstemp.o $(EXTRA_GCC_OBJS) $(LIBS); \
+ $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ gcc.o g77spec.o g77version.o \
+ version.o prefix.o intl.o $(EXTRA_GCC_OBJS) $(LIBS); \
else true; fi
# Create a version of the g77 driver which calls the cross-compiler.
@@ -244,7 +220,7 @@ f77.dvi: f/g77.dvi
# g77 documentation.
f/g77.info: $(srcdir)/f/g77.texi $(srcdir)/f/bugs.texi \
$(srcdir)/f/g77install.texi $(srcdir)/f/news.texi \
- $(srcdir)/f/intdoc.texi
+ $(srcdir)/f/intdoc.texi $(srcdir)/f/root.texi
case "$(LANGUAGES)" in \
*[fF]77*) touch lang-f77;; \
*) rm -f lang-f77;; \
@@ -256,7 +232,7 @@ f/g77.info: $(srcdir)/f/g77.texi $(srcdir)/f/bugs.texi \
f/g77.dvi: $(srcdir)/f/g77.texi $(srcdir)/f/bugs.texi \
$(srcdir)/f/g77install.texi $(srcdir)/f/news.texi \
- $(srcdir)/f/intdoc.texi
+ $(srcdir)/f/intdoc.texi $(srcdir)/f/root.texi
case "$(LANGUAGES)" in \
*[fF]77*) touch lang-f77;; \
*) rm -f lang-f77;; \
@@ -306,15 +282,15 @@ $(srcdir)/f/intdoc.texi: f/intdoc.c f/intdoc.in f/ansify.c f/intrin.def f/intrin
rm f/intdoc f/ansify f/intdoc.h0; \
else true; fi
-$(srcdir)/f/BUGS: f/bugs0.texi f/bugs.texi
+$(srcdir)/f/BUGS: f/bugs0.texi f/bugs.texi f/root.texi
cd $(srcdir)/f; $(MAKEINFO) -D BUGSONLY --no-header --no-split \
--no-validate -o BUGS bugs0.texi
-$(srcdir)/f/INSTALL: f/install0.texi f/g77install.texi
+$(srcdir)/f/INSTALL: f/install0.texi f/g77install.texi f/root.texi
cd $(srcdir)/f; $(MAKEINFO) -D INSTALLONLY --no-header --no-split \
--no-validate -o INSTALL install0.texi
-$(srcdir)/f/NEWS: f/news0.texi f/news.texi
+$(srcdir)/f/NEWS: f/news0.texi f/news.texi f/root.texi
cd $(srcdir)/f; $(MAKEINFO) -D NEWSONLY --no-header --no-split \
--no-validate -o NEWS news0.texi
@@ -331,10 +307,10 @@ f77.install-normal:
# and also as either g77 (if native) or $(tooldir)/bin/g77.
f77.install-common:
case "$(LANGUAGES)" in \
- *[fF]77*) touch lang-f77;; \
- *) rm -f lang-f77;; \
+ *[fF]77*) touch $(prefix)/lang-f77;; \
+ *) rm -f $(prefix)/lang-f77;; \
esac
- -if [ -f lang-f77 -a -f f771$(exeext) ] ; then \
+ -if [ -f $(prefix)/lang-f77 -a -f f771$(exeext) ] ; then \
if [ -f g77-cross$(exeext) ] ; then \
rm -f $(bindir)/$(G77_CROSS_NAME)$(exeext); \
$(INSTALL_PROGRAM) g77-cross$(exeext) $(bindir)/$(G77_CROSS_NAME)$(exeext); \
@@ -354,15 +330,16 @@ f77.install-common:
echo ' f77-install-ok in the source or build directory.)'; \
echo ''; \
else true; fi
+ rm -f $(prefix)/lang-f77
# $(INSTALL_DATA) might be a relative pathname, so we can't cd into srcdir
# to do the install. The sed rule was copied from stmp-int-hdrs.
f77.install-info: f77.info
case "$(LANGUAGES)" in \
- *[fF]77*) touch lang-f77;; \
- *) rm -f lang-f77;; \
+ *[fF]77*) touch $(prefix)/lang-f77;; \
+ *) rm -f $(prefix)/lang-f77;; \
esac
- if [ -f lang-f77 -a -f f/g77.info ] ; then \
+ if [ -f $(prefix)/lang-f77 -a -f f/g77.info ] ; then \
rm -f $(infodir)/g77.info*; \
for f in f/g77.info*; do \
realfile=`echo $$f | sed -e 's|.*/\([^/]*\)$$|\1|'`; \
@@ -370,48 +347,51 @@ f77.install-info: f77.info
done; \
chmod a-x $(infodir)/g77.info*; \
else true; fi
- @if [ -f lang-f77 -a -f $(srcdir)/f/g77.info ] ; then \
+ @if [ -f $(prefix)/lang-f77 -a -f $(srcdir)/f/g77.info ] ; then \
if $(SHELL) -c 'install-info --version | sed 1q | fgrep -s -v -i debian' >/dev/null 2>&1; then \
echo " install-info --info-dir=$(infodir) $(infodir)/g77.info"; \
install-info --info-dir=$(infodir) $(infodir)/g77.info || : ; \
else : ; fi; \
else : ; fi
+ rm -f $(prefix)/lang-f77
f77.install-man: $(srcdir)/f/g77.1
case "$(LANGUAGES)" in \
- *[fF]77*) touch lang-f77;; \
- *) rm -f lang-f77;; \
+ *[fF]77*) touch $(prefix)/lang-f77;; \
+ *) rm -f $(prefix)/lang-f77;; \
esac
- -if [ -f lang-f77 -a -f f771$(exeext) ] ; then \
+ -if [ -f $(prefix)/lang-f77 -a -f f771$(exeext) ] ; then \
if [ -f g77-cross$(exeext) ] ; then \
- rm -f $(mandir)/$(G77_CROSS_NAME)$(manext); \
- $(INSTALL_DATA) $(srcdir)/f/g77.1 $(mandir)/$(G77_CROSS_NAME)$(manext); \
- chmod a-x $(mandir)/$(G77_CROSS_NAME)$(manext); \
+ rm -f $(man1dir)/$(G77_CROSS_NAME)$(manext); \
+ $(INSTALL_DATA) $(srcdir)/f/g77.1 $(man1dir)/$(G77_CROSS_NAME)$(manext); \
+ chmod a-x $(man1dir)/$(G77_CROSS_NAME)$(manext); \
else \
- rm -f $(mandir)/$(G77_INSTALL_NAME)$(manext); \
- $(INSTALL_DATA) $(srcdir)/f/g77.1 $(mandir)/$(G77_INSTALL_NAME)$(manext); \
- chmod a-x $(mandir)/$(G77_INSTALL_NAME)$(manext); \
+ rm -f $(man1dir)/$(G77_INSTALL_NAME)$(manext); \
+ $(INSTALL_DATA) $(srcdir)/f/g77.1 $(man1dir)/$(G77_INSTALL_NAME)$(manext); \
+ chmod a-x $(man1dir)/$(G77_INSTALL_NAME)$(manext); \
fi; \
else true; fi
+ rm -f $(prefix)/lang-f77
f77.uninstall:
case "$(LANGUAGES)" in \
- *[fF]77*) touch lang-f77;; \
- *) rm -f lang-f77;; \
+ *[fF]77*) touch $(prefix)/lang-f77;; \
+ *) rm -f $(prefix)/lang-f77;; \
esac
- @if [ -f lang-f77 ] ; then \
+ @if [ -f $(prefix)/lang-f77 ] ; then \
if $(SHELL) -c 'install-info --version | sed 1q | fgrep -s -v -i debian' >/dev/null 2>&1; then \
echo " install-info --delete --info-dir=$(infodir) $(infodir)/g77.info"; \
install-info --delete --info-dir=$(infodir) $(infodir)/g77.info || : ; \
else : ; fi; \
else : ; fi
- -if [ -f lang-f77 ]; then \
+ -if [ -f $(prefix)/lang-f77 ]; then \
rm -rf $(bindir)/$(G77_INSTALL_NAME)$(exeext); \
rm -rf $(bindir)/$(G77_CROSS_NAME)$(exeext); \
- rm -rf $(mandir)/$(G77_INSTALL_NAME)$(manext); \
- rm -rf $(mandir)/$(G77_CROSS_NAME)$(manext); \
+ rm -rf $(man1dir)/$(G77_INSTALL_NAME)$(manext); \
+ rm -rf $(man1dir)/$(G77_CROSS_NAME)$(manext); \
rm -rf $(infodir)/g77.info*; \
fi
+ rm -f $(prefix)/lang-f77
#
# Clean hooks:
# A lot of the ancillary files are deleted by the main makefile.
@@ -424,7 +404,7 @@ f77.mostlyclean:
-rm -f g77.aux g77.cps g77.ky g77.toc g77.vr g77.fn g77.kys \
g77.pg g77.tp g77.vrs g77.cp g77.fns g77.log g77.pgs g77.tps
f77.clean:
- -rm -f g77.c g77.o g77spec.o g77version.o
+ -rm -f g77spec.o g77version.o
f77.distclean:
-rm -f lang-f77 f/Makefile
f77.extraclean:
@@ -435,7 +415,7 @@ f77.maintainer-clean:
# The main makefile has already created stage?/f.
G77STAGESTUFF = f/*$(objext) f/fini f/stamp-str f/str-*.h f/str-*.j \
- lang-f77 g77.c g77.o g77spec.o g77version.o
+ lang-f77 g77spec.o g77version.o
f77.stage1: stage1-start
-if [ -f lang-f77 ]; then \
diff --git a/gcc/f/Makefile.in b/gcc/f/Makefile.in
index 639d633b5e5..96975a5d7cd 100644
--- a/gcc/f/Makefile.in
+++ b/gcc/f/Makefile.in
@@ -154,7 +154,7 @@ LIBS = $(SUBDIR_OBSTACK) $(SUBDIR_USE_ALLOCA) $(SUBDIR_MALLOC) $(CLIB)
# Both . and srcdir are used, in that order,
# so that tm.h and config.h will be found in the compilation
# subdirectory rather than in the source directory.
-INCLUDES = -I. -I.. -I$(srcdir) -I$(srcdir)/.. -I$(srcdir)/../config
+INCLUDES = -I. -I.. -I$(srcdir) -I$(srcdir)/.. -I$(srcdir)/../config -I$(srcdir)/../../include
# Always use -I$(srcdir)/config when compiling.
.c.o:
diff --git a/gcc/f/NEWS b/gcc/f/NEWS
index 2cc6cbfe5a2..4ac7f7b3705 100644
--- a/gcc/f/NEWS
+++ b/gcc/f/NEWS
@@ -1,7 +1,12 @@
-This file lists recent changes to the GNU Fortran compiler. Copyright
-(C) 1995, 1996 Free Software Foundation, Inc. You may copy,
-distribute, and modify it freely as long as you preserve this copyright
-notice and permission notice.
+*Note:* This file is automatically generated from the files
+`news0.texi' and `news.texi'. `NEWS' is *not* a source file, although
+it is normally included within source distributions.
+
+ This file lists news about the EGCS-1.2 version (and some other
+versions) of the GNU Fortran compiler. Copyright (C) 1995-1999 Free
+Software Foundation, Inc. You may copy, distribute, and modify it
+freely as long as you preserve this copyright notice and permission
+notice.
News About GNU Fortran
**********************
@@ -29,128 +34,199 @@ with the most recent version first.
This order is not strict--for example, some items involve a
combination of these elements.
-In `egcs' 1.1:
-==============
+ Note that two variants of `g77' are tracked below. The `egcs'
+variant is described vis-a-vis previous versions of `egcs' and/or an
+official FSF version, as appropriate.
- * `g77' no longer produces incorrect code and initial values for
- `EQUIVALENCE' and `COMMON' aggregates that, due to "unnatural"
- ordering of members vis-a-vis their types, require initial padding.
+ Therefore, `egcs' versions sometimes have multiple listings to help
+clarify how they differ from other versions, though this can make
+getting a complete picture of what a particular `egcs' version contains
+somewhat more difficult.
- * `g77' no longer crashes when compiling code containing
- specification statements such as `INTEGER(KIND=7) PTR'.
+ *Warning:* The information below is still under development, and
+might not accurately reflect the `g77' code base of which it is a part.
+Efforts are made to keep it somewhat up-to-date, but they are
+particularly concentrated on any version of this information that is
+distributed as part of a *released* `g77'.
- * `g77' now treats `%LOC(EXPR)' and `LOC(EXPR)' as "ordinary"
- expressions when they are used as arguments in procedure calls.
- This change applies only to global (filewide) analysis, making it
- consistent with how `g77' actually generates code for these cases.
+ In particular, while this information is intended to apply to the
+EGCS-1.2 version of `g77', only an official *release* of that version
+is expected to contain documentation that is most consistent with the
+`g77' product in that version.
- Previously, `g77' treated these expressions as denoting special
- "pointer" arguments for the purposes of filewide analysis.
+ Nevertheless, information on *previous* releases of `g77', below, is
+likely to be more up-to-date and accurate than the equivalent
+information that accompanied those releases, assuming the last-updated
+date of the information below is later than the dates of those releases.
- * The `g77' driver now ensures that `-lg2c' is specified in the link
- phase prior to any occurrence of `-lm'. This prevents
- accidentally linking to a routine in the SunOS4 `-lm' library when
- the generated code wants to link to the one in `libf2c' (`libg2c').
+ That's due to attempts to keep this development version of news
+about previous `g77' versions up-to-date.
- * `g77' emits more debugging information when `-g' is used.
+ An online, "live" version of this document (derived directly from
+the mainline, development version of `g77' within `egcs') is available
+at `http://egcs.cygnus.com/onlinedocs/g77_news.html'.
- This new information allows, for example, `which __g77_length_a'
- to be used in `gdb' to determine the type of the phantom length
- argument supplied with `CHARACTER' variables.
+ The following information was last updated on 1999-03-17:
- This information pertains to internally-generated type, variable,
- and other information, not to the longstanding deficiencies
- vis-a-vis `COMMON' and `EQUIVALENCE'.
+In `egcs' 1.2 (versus 1.1.2):
+=============================
- * The F90 `DATE_AND_TIME' intrinsic now is supported.
+ 1. `g77' no longer generates bad code for assignments, or other
+ conversions, of `REAL' or `COMPLEX' constant expressions to type
+ `INTEGER(KIND=2)' (often referred to as `INTEGER*8').
- * The F90 `SYSTEM_CLOCK' intrinsic allows the optional arguments
- (except for the `Count' argument) to be omitted.
+ For example, `INTEGER*8 J; J = 4E10' now works as documented.
+
+ 2. Fix `g77' so it no longer crashes when compiling I/O statements
+ using keywords that define `INTEGER' values, such as `IOSTAT=J',
+ where J is other than default `INTEGER' (such as `INTEGER*2').
+ Instead, it issues a diagnostic.
+
+ 3. The `-ax' option is now obeyed when compiling Fortran programs.
+ (It is passed to the `f771' driver.)
+
+ * Source file names with the suffixes `.FOR' and `.FPP' now are
+ recognized by `g77' as if they ended in `.for' and `.fpp',
+ respectively.
+
+ * `g77' now warns about a reference to an intrinsic that has an
+ interface that is not Year 2000 (Y2K) compliant. Also, the
+ `libg2c' has been changed to increase the likelihood of catching
+ references to the implementations of these intrinsics using the
+ `EXTERNAL' mechanism (which would avoid the new warnings).
- * Upgrade to `libf2c' as of 1998-06-18.
+ 4. `g77' now warns about a reference to a function when the
+ corresponding *subsequent* function program unit disagrees with
+ the reference concerning the type of the function.
- * Improve documentation and indexing.
+ 5. Improve documentation and indexing, including information on Year
+ 2000 (Y2K) compliance.
-In 0.5.23:
-==========
+In 0.5.24 and `egcs' 1.1.2 (versus 0.5.23 and 1.1.1):
+=====================================================
- * This release contains several regressions against version 0.5.22
- of `g77', due to using the "vanilla" `gcc' back end instead of
- patching it to fix a few bugs and improve performance in a few
- cases.
+ * Fix the `IDate' intrinsic (VXT) (in `libg2c') so the returned year
+ is in the documented, non-Y2K-compliant range of 0-99, instead of
+ being returned as 100 in the year 2000.
- *Note Actual Bugs We Haven't Fixed Yet: Actual Bugs, available in
- plain-text format in `gcc/f/BUGS', for information on the known
- bugs in this version, including the regressions.
+ * Fix the `Date_and_Time' intrinsic (in `libg2c') to return the
+ milliseconds value properly in VALUES(8).
- Features that have been dropped from this version of `g77' due to
- their being implemented via `g77'-specific patches to the `gcc'
- back end in previous releases include:
+ * Fix the `LStat' intrinsic (in `libg2c') to return device-ID
+ information properly in SARRAY(7).
- - Support for `__restrict__' keyword, the options
- `-fargument-alias', `-fargument-noalias', and
- `-fargument-noalias-global', and the corresponding
- alias-analysis code.
+ * Improve documentation.
- (Version 1.0.1 of `egcs' has the alias-analysis code, but not
- the `__restrict__' keyword. `egcs' `g77' users benefit from
- the alias-analysis code despite the lack of the
- `__restrict__' keyword, which is a C-language construct.)
+In 0.5.24 and `egcs' 1.1.1 (versus 0.5.23 and 1.1):
+===================================================
- - Support for the GNU compiler options `-fmove-all-movables',
- `-freduce-all-givs', and `-frerun-loop-opt'.
+ * Fix `libg2c' so it performs an implicit `ENDFILE' operation (as
+ appropriate) whenever a `REWIND' is done.
- (Version 1.0.1 of `egcs' supports these options. `g77' users
- of `egcs' benefit from them even if they are not explicitly
- specified, because the defaults are optimized for `g77'
- users.)
+ (This bug was introduced in 0.5.23 and `egcs' 1.1 in `g77''s
+ version of `libf2c'.)
- - Support for the `-W' option warning about integer division by
- zero.
+ * Fix `libg2c' so it no longer crashes with a spurious diagnostic
+ upon doing any I/O following a direct formatted write.
- - The Intel x86-specific option `-malign-double' applying to
- stack-allocated data as well as statically-allocate data.
+ (This bug was introduced in 0.5.23 and `egcs' 1.1 in `g77''s
+ version of `libf2c'.)
- Note that the `gcc/f/gbe/' subdirectory has been removed from this
- distribution as a result of `g77' no longer including patches for
- the `gcc' back end.
+ * Fix `g77' so it no longer crashes compiling references to the
+ `Rand' intrinsic on some systems.
- * Fix bugs in the `libU77' intrinsic `HostNm' that wrote one byte
+ * Fix `g77' portion of installation process so it works better on
+ some systems (those with shells requiring `else true' clauses on
+ `if' constructs for the completion code to be set properly).
+
+In `egcs' 1.1 (versus 0.5.24):
+==============================
+
+ 6. Fix `g77' crash compiling code containing the construct
+ `CMPLX(0.)' or similar.
+
+ 7. Fix `g77' crash (or apparently infinite run-time) when compiling
+ certain complicated expressions involving `COMPLEX' arithmetic
+ (especially multiplication).
+
+ 8. Fix a code-generation bug that afflicted Intel x86 targets when
+ `-O2' was specified compiling, for example, an old version of the
+ `DNRM2' routine.
+
+ The x87 coprocessor stack was being mismanaged in cases involving
+ assigned `GOTO' and `ASSIGN'.
+
+ * Align static double-precision variables and arrays on Intel x86
+ targets regardless of whether `-malign-double' is specified.
+
+ Generally, this affects only local variables and arrays having the
+ `SAVE' attribute or given initial values via `DATA'.
+
+In `egcs' 1.1 (versus `egcs' 1.0.3):
+====================================
+
+ 9. Fix bugs in the `libU77' intrinsic `HostNm' that wrote one byte
beyond the end of its `CHARACTER' argument, and in the `libU77'
intrinsics `GMTime' and `LTime' that overwrote their arguments.
- * Support `gcc' version 2.8, and remove support for prior versions
- of `gcc'.
+ 10. Assumed arrays with negative bounds (such as `REAL A(-1:*)') no
+ longer elicit spurious diagnostics from `g77', even on systems
+ with pointers having different sizes than integers.
- * Remove support for the `--driver' option, as `g77' now does all
- the driving, just like `gcc'.
+ This bug is not known to have existed in any recent version of
+ `gcc'. It was introduced in an early release of `egcs'.
- * `CASE DEFAULT' no longer crashes `g77'.
-
- * Valid combinations of `EXTERNAL', passing that external as a dummy
+ 11. Valid combinations of `EXTERNAL', passing that external as a dummy
argument without explicitly giving it a type, and, in a subsequent
program unit, referencing that external as an external function
with a different type no longer crash `g77'.
- * `g77' no longer installs the `f77' command and `f77.1' man page in
+ 12. `CASE DEFAULT' no longer crashes `g77'.
+
+ 13. The `-Wunused' option no longer issues a spurious warning about
+ the "master" procedure generated by `g77' for procedures
+ containing `ENTRY' statements.
+
+ * Support `FORMAT(I<EXPR>)' when EXPR is a compile-time constant
+ `INTEGER' expression.
+
+ * Fix `g77' `-g' option so procedures that use `ENTRY' can be
+ stepped through, line by line, in `gdb'.
+
+ * Allow any `REAL' argument to intrinsics `Second' and `CPU_Time'.
+
+ * Use `tempnam', if available, to open scratch files (as in
+ `OPEN(STATUS='SCRATCH')') so that the `TMPDIR' environment
+ variable, if present, is used.
+
+ * `g77''s version of `libf2c' separates out the setting of global
+ state (such as command-line arguments and signal handling) from
+ `main.o' into distinct, new library archive members.
+
+ This should make it easier to write portable applications that
+ have their own (non-Fortran) `main()' routine properly set up the
+ `libf2c' environment, even when `libf2c' (now `libg2c') is a
+ shared library.
+
+ 14. `g77' no longer installs the `f77' command and `f77.1' man page in
the `/usr' or `/usr/local' heirarchy, even if the `f77-install-ok'
file exists in the source or build directory. See the
installation documentation for more information.
- * `g77' no longer installs the `libf2c.a' library and `f2c.h'
+ 15. `g77' no longer installs the `libf2c.a' library and `f2c.h'
include file in the `/usr' or `/usr/local' heirarchy, even if the
`f2c-install-ok' or `f2c-exists-ok' files exist in the source or
build directory. See the installation documentation for more
information.
- * The `libf2c.a' library produced by `g77' has been renamed to
+ 16. The `libf2c.a' library produced by `g77' has been renamed to
`libg2c.a'. It is installed only in the `gcc' "private" directory
heirarchy, `gcc-lib'. This allows system administrators and users
to choose which version of the `libf2c' library from `netlib' they
wish to use on a case-by-case basis. See the installation
documentation for more information.
- * The `f2c.h' include (header) file produced by `g77' has been
+ 17. The `f2c.h' include (header) file produced by `g77' has been
renamed to `g2c.h'. It is installed only in the `gcc' "private"
directory heirarchy, `gcc-lib'. This allows system administrators
and users to choose which version of the include file from
@@ -162,26 +238,11 @@ In 0.5.23:
than the one built and installed as part of the same `g77' version
is picked up.
- * The `-Wunused' option no longer issues a spurious warning about
- the "master" procedure generated by `g77' for procedures
- containing `ENTRY' statements.
+ 18. During the configuration and build process, `g77' creates
+ subdirectories it needs only as it needs them. Other cleaning up
+ of the configuration and build process has been performed as well.
- * `g77''s version of `libf2c' separates out the setting of global
- state (such as command-line arguments and signal handling) from
- `main.o' into distinct, new library archive members.
-
- This should make it easier to write portable applications that
- have their own (non-Fortran) `main()' routine properly set up the
- `libf2c' environment, even when `libf2c' (now `libg2c') is a
- shared library.
-
- * During the configuration and build process, `g77' creates
- subdirectories it needs only as it needs them, thus avoiding
- unnecessary creation of, for example, `stage1/f/runtime' when
- doing a non-bootstrap build. Other cleaning up of the
- configuration and build process has been performed as well.
-
- * `install-info' now used to update the directory of Info
+ 19. `install-info' now used to update the directory of Info
documentation to contain an entry for `g77' (during installation).
* Some diagnostics have been changed from warnings to errors, to
@@ -190,1175 +251,67 @@ In 0.5.23:
in the `OPEN', `INQUIRE', `READ', and `WRITE' statements, and
about truncations of various sorts of constants.
- * Improve documentation and indexing.
-
- * Upgrade to `libf2c' as of 1998-04-20.
-
- This should fix a variety of problems, including those involving
- some uses of the `T' format specifier, and perhaps some build
- (porting) problems as well.
-
-In 0.5.22:
-==========
-
- * Fix code generation for iterative `DO' loops that have one or more
- references to the iteration variable, or to aliases of it, in
- their control expressions. For example, `DO 10 J=2,J' now is
- compiled correctly.
-
- * Fix a code-generation bug that afflicted Intel x86 targets when
- `-O2' was specified compiling, for example, an old version of the
- `DNRM2' routine.
-
- The x87 coprocessor stack was being mismanaged in cases involving
- assigned `GOTO' and `ASSIGN'.
-
- * Fix `DTime' intrinsic so as not to truncate results to integer
- values (on some systems).
-
- * Fix `SIGNAL' intrinsic so it offers portable support for 64-bit
- systems (such as Digital Alphas running GNU/Linux).
-
- * Fix run-time crash involving `NAMELIST' on 64-bit machines such as
- Alphas.
-
- * Fix `g77' version of `libf2c' so it no longer produces a spurious
- `I/O recursion' diagnostic at run time when an I/O operation (such
- as `READ *,I') is interrupted in a manner that causes the program
- to be terminated via the `f_exit' routine (such as via `C-c').
-
- * Fix `g77' crash triggered by `CASE' statement with an omitted
- lower or upper bound.
-
- * Fix `g77' crash compiling references to `CPU_Time' intrinsic.
-
- * Fix `g77' crash (or apparently infinite run-time) when compiling
- certain complicated expressions involving `COMPLEX' arithmetic
- (especially multiplication).
-
- * Fix `g77' crash on statements such as `PRINT *,
- (REAL(Z(I)),I=1,2)', where `Z' is `DOUBLE COMPLEX'.
-
- * Fix a `g++' crash.
-
- * Support `FORMAT(I<EXPR>)' when EXPR is a compile-time constant
- `INTEGER' expression.
-
- * Fix `g77' `-g' option so procedures that use `ENTRY' can be
- stepped through, line by line, in `gdb'.
-
- * Fix a profiling-related bug in `gcc' back end for Intel x86
- architecture.
-
- * Allow any `REAL' argument to intrinsics `Second' and `CPU_Time'.
-
- * Allow any numeric argument to intrinsics `Int2' and `Int8'.
-
- * Use `tempnam', if available, to open scratch files (as in
- `OPEN(STATUS='SCRATCH')' so that the `TMPDIR' environment variable,
- if present, is used.
-
- * Rename the `gcc' keyword `restrict' to `__restrict__', to avoid
- rejecting valid, existing, C programs. Support for `restrict' is
- now more like support for `complex'.
-
- * Fix `-fpedantic' to not reject procedure invocations such as
- `I=J()' and `CALL FOO()'.
-
- * Fix `-fugly-comma' to affect invocations of only external
- procedures. Restore rejection of gratuitous trailing omitted
- arguments to intrinsics, as in `I=MAX(3,4,,)'.
-
- * Fix compiler so it accepts `-fgnu-intrinsics-*' and
- `-fbadu77-intrinsics-*' options.
-
- * Improve diagnostic messages from `libf2c' so it is more likely
- that the printing of the active format string is limited to the
- string, with no trailing garbage being printed.
-
- (Unlike `f2c', `g77' did not append a null byte to its compiled
- form of every format string specified via a `FORMAT' statement.
- However, `f2c' would exhibit the problem anyway for a statement
- like `PRINT '(I)garbage', 1' by printing `(I)garbage' as the
- format string.)
-
- * Improve compilation of FORMAT expressions so that a null byte is
+ 20. Improve compilation of `FORMAT' expressions so that a null byte is
appended to the last operand if it is a constant. This provides a
cleaner run-time diagnostic as provided by `libf2c' for statements
like `PRINT '(I1', 42'.
- * Fix various crashes involving code with diagnosed errors.
-
- * Fix cross-compilation bug when configuring `libf2c'.
-
- * Improve diagnostics.
-
- * Improve documentation and indexing.
-
- * Upgrade to `libf2c' as of 1997-09-23. This fixes a formatted-I/O
- bug that afflicted 64-bit systems with 32-bit integers (such as
- Digital Alpha running GNU/Linux).
-
-In 0.5.21:
-==========
-
- * Fix a code-generation bug introduced by 0.5.20 caused by loop
- unrolling (by specifying `-funroll-loops' or similar). This bug
- afflicted all code compiled by version 2.7.2.2.f.2 of `gcc' (C,
- C++, Fortran, and so on).
-
- * Fix a code-generation bug manifested when combining local
- `EQUIVALENCE' with a `DATA' statement that follows the first
- executable statement (or is treated as an executable-context
- statement as a result of using the `-fpedantic' option).
-
- * Fix a compiler crash that occured when an integer division by a
- constant zero is detected. Instead, when the `-W' option is
- specified, the `gcc' back end issues a warning about such a case.
- This bug afflicted all code compiled by version 2.7.2.2.f.2 of
- `gcc' (C, C++, Fortran, and so on).
-
- * Fix a compiler crash that occurred in some cases of procedure
- inlining. (Such cases became more frequent in 0.5.20.)
-
- * Fix a compiler crash resulting from using `DATA' or similar to
- initialize a `COMPLEX' variable or array to zero.
-
- * Fix compiler crashes involving use of `AND', `OR', or `XOR'
- intrinsics.
-
- * Fix compiler bug triggered when using a `COMMON' or `EQUIVALENCE'
- variable as the target of an `ASSIGN' or assigned-`GOTO' statement.
-
- * Fix compiler crashes due to using the name of a some non-standard
- intrinsics (such as `FTELL' or `FPUTC') as such and as the name of
- a procedure or common block. Such dual use of a name in a program
- is allowed by the standard.
-
- * Place automatic arrays on the stack, even if `SAVE' or the
- `-fno-automatic' option is in effect. This avoids a compiler
- crash in some cases.
-
- * The `-malign-double' option now reliably aligns `DOUBLE PRECISION'
- optimally on Pentium and Pentium Pro architectures (586 and 686 in
- `gcc').
-
- * New option `-Wno-globals' disables warnings about "suspicious" use
- of a name both as a global name and as the implicit name of an
- intrinsic, and warnings about disagreements over the number or
- natures of arguments passed to global procedures, or the natures
- of the procedures themselves.
-
- The default is to issue such warnings, which are new as of this
- version of `g77'.
-
- * New option `-fno-globals' disables diagnostics about potentially
- fatal disagreements analysis problems, such as disagreements over
- the number or natures of arguments passed to global procedures, or
- the natures of those procedures themselves.
-
- The default is to issue such diagnostics and flag the compilation
- as unsuccessful. With this option, the diagnostics are issued as
- warnings, or, if `-Wno-globals' is specified, are not issued at
- all.
-
- This option also disables inlining of global procedures, to avoid
- compiler crashes resulting from coding errors that these
- diagnostics normally would identify.
-
- * Diagnose cases where a reference to a procedure disagrees with the
- type of that procedure, or where disagreements about the number or
- nature of arguments exist. This avoids a compiler crash.
-
- * Fix parsing bug whereby `g77' rejected a second initialization
- specification immediately following the first's closing `/' without
- an intervening comma in a `DATA' statement, and the second
- specification was an implied-DO list.
-
- * Improve performance of the `gcc' back end so certain complicated
- expressions involving `COMPLEX' arithmetic (especially
- multiplication) don't appear to take forever to compile.
-
- * Fix a couple of profiling-related bugs in `gcc' back end.
-
- * Integrate GNU Ada's (GNAT's) changes to the back end, which
- consist almost entirely of bug fixes. These fixes are circa
- version 3.10p of GNAT.
-
- * Include some other `gcc' fixes that seem useful in `g77''s version
- of `gcc'. (See `gcc/ChangeLog' for details--compare it to that
- file in the vanilla `gcc-2.7.2.3.tar.gz' distribution.)
-
- * Fix `libU77' routines that accept file and other names to strip
- trailing blanks from them, for consistency with other
- implementations. Blanks may be forcibly appended to such names by
- appending a single null character (`CHAR(0)') to the significant
- trailing blanks.
-
- * Fix `CHMOD' intrinsic to work with file names that have embedded
- blanks, commas, and so on.
-
- * Fix `SIGNAL' intrinsic so it accepts an optional third `Status'
- argument.
-
- * Fix `IDATE()' intrinsic subroutine (VXT form) so it accepts
- arguments in the correct order. Documentation fixed accordingly,
- and for `GMTIME()' and `LTIME()' as well.
-
- * Make many changes to `libU77' intrinsics to support existing code
- more directly.
-
- Such changes include allowing both subroutine and function forms
- of many routines, changing `MCLOCK()' and `TIME()' to return
- `INTEGER(KIND=1)' values, introducing `MCLOCK8()' and `TIME8()' to
- return `INTEGER(KIND=2)' values, and placing functions that are
- intended to perform side effects in a new intrinsic group,
- `badu77'.
-
- * Improve `libU77' so it is more portable.
-
- * Add options `-fbadu77-intrinsics-delete',
- `-fbadu77-intrinsics-hide', and so on.
-
- * Fix crashes involving diagnosed or invalid code.
-
- * `g77' and `gcc' now do a somewhat better job detecting and
- diagnosing arrays that are too large to handle before these cause
- diagnostics during the assembler or linker phase, a compiler
- crash, or generation of incorrect code.
-
- * Make some fixes to alias analysis code.
-
- * Add support for `restrict' keyword in `gcc' front end.
-
- * Support `gcc' version 2.7.2.3 (modified by `g77' into version
- 2.7.2.3.f.1), and remove support for prior versions of `gcc'.
-
- * Incorporate GNAT's patches to the `gcc' back end into `g77''s, so
- GNAT users do not need to apply GNAT's patches to build both GNAT
- and `g77' from the same source tree.
-
- * Modify `make' rules and related code so that generation of Info
- documentation doesn't require compilation using `gcc'. Now, any
- ANSI C compiler should be adequate to produce the `g77'
- documentation (in particular, the tables of intrinsics) from
- scratch.
-
- * Add `INT2' and `INT8' intrinsics.
-
- * Add `CPU_TIME' intrinsic.
-
- * Add `ALARM' intrinsic.
-
- * `CTIME' intrinsic now accepts any `INTEGER' argument, not just
- `INTEGER(KIND=2)'.
-
- * Warn when explicit type declaration disagrees with the type of an
- intrinsic invocation.
-
- * Support `*f771' entry in `gcc' `specs' file.
-
- * Fix typo in `make' rule `g77-cross', used only for cross-compiling.
-
- * Fix `libf2c' build procedure to re-archive library if previous
- attempt to archive was interrupted.
-
- * Change `gcc' to unroll loops only during the last invocation (of
- as many as two invocations) of loop optimization.
-
- * Improve handling of `-fno-f2c' so that code that attempts to pass
- an intrinsic as an actual argument, such as `CALL FOO(ABS)', is
- rejected due to the fact that the run-time-library routine is,
- effectively, compiled with `-ff2c' in effect.
-
- * Fix `g77' driver to recognize `-fsyntax-only' as an option that
- inhibits linking, just like `-c' or `-S', and to recognize and
- properly handle the `-nostdlib', `-M', `-MM', `-nodefaultlibs',
- and `-Xlinker' options.
-
- * Upgrade to `libf2c' as of 1997-08-16.
-
- * Modify `libf2c' to consistently and clearly diagnose recursive I/O
- (at run time).
-
- * `g77' driver now prints version information (such as produced by
- `g77 -v') to `stderr' instead of `stdout'.
-
- * The `.r' suffix now designates a Ratfor source file, to be
- preprocessed via the `ratfor' command, available separately.
-
- * Fix some aspects of how `gcc' determines what kind of system is
- being configured and what kinds are supported. For example, GNU
- Linux/Alpha ELF systems now are directly supported.
-
- * Improve diagnostics.
-
- * Improve documentation and indexing.
-
- * Include all pertinent files for `libf2c' that come from
- `netlib.bell-labs.com'; give any such files that aren't quite
- accurate in `g77''s version of `libf2c' the suffix `.netlib'.
-
- * Reserve `INTEGER(KIND=0)' for future use.
-
-In 0.5.20:
-==========
-
- * The `-fno-typeless-boz' option is now the default.
-
- This option specifies that non-decimal-radix constants using the
- prefixed-radix form (such as `Z'1234'') are to be interpreted as
- `INTEGER' constants. Specify `-ftypeless-boz' to cause such
- constants to be interpreted as typeless.
-
- (Version 0.5.19 introduced `-fno-typeless-boz' and its inverse.)
-
- * Options `-ff90-intrinsics-enable' and `-fvxt-intrinsics-enable'
- now are the defaults.
-
- Some programs might use names that clash with intrinsic names
- defined (and now enabled) by these options or by the new `libU77'
- intrinsics. Users of such programs might need to compile them
- differently (using, for example, `-ff90-intrinsics-disable') or,
- better yet, insert appropriate `EXTERNAL' statements specifying
- that these names are not intended to be names of intrinsics.
-
- * The `ALWAYS_FLUSH' macro is no longer defined when building
- `libf2c', which should result in improved I/O performance,
- especially over NFS.
-
- *Note:* If you have code that depends on the behavior of `libf2c'
- when built with `ALWAYS_FLUSH' defined, you will have to modify
- `libf2c' accordingly before building it from this and future
- versions of `g77'.
-
- * Dave Love's implementation of `libU77' has been added to the
- version of `libf2c' distributed with and built as part of `g77'.
- `g77' now knows about the routines in this library as intrinsics.
-
- * New option `-fvxt' specifies that the source file is written in
- VXT Fortran, instead of GNU Fortran.
-
- * The `-fvxt-not-f90' option has been deleted, along with its
- inverse, `-ff90-not-vxt'.
-
- If you used one of these deleted options, you should re-read the
- pertinent documentation to determine which options, if any, are
- appropriate for compiling your code with this version of `g77'.
-
- * The `-fugly' option now issues a warning, as it likely will be
- removed in a future version.
-
- (Enabling all the `-fugly-*' options is unlikely to be feasible,
- or sensible, in the future, so users should learn to specify only
- those `-fugly-*' options they really need for a particular source
- file.)
-
- * The `-fugly-assumed' option, introduced in version 0.5.19, has
- been changed to better accommodate old and new code.
-
- * Make a number of fixes to the `g77' front end and the `gcc' back
- end to better support Alpha (AXP) machines. This includes
- providing at least one bug-fix to the `gcc' back end for Alphas.
-
- * Related to supporting Alpha (AXP) machines, the `LOC()' intrinsic
- and `%LOC()' construct now return values of integer type that is
- the same width (holds the same number of bits) as the pointer type
- on the machine.
-
- On most machines, this won't make a difference, whereas on Alphas,
- the type these constructs return is `INTEGER*8' instead of the
- more common `INTEGER*4'.
-
- * Emulate `COMPLEX' arithmetic in the `g77' front end, to avoid bugs
- in `complex' support in the `gcc' back end. New option
- `-fno-emulate-complex' causes `g77' to revert the 0.5.19 behavior.
-
- * Fix bug whereby `REAL A(1)', for example, caused a compiler crash
- if `-fugly-assumed' was in effect and A was a local (automatic)
- array. That case is no longer affected by the new handling of
- `-fugly-assumed'.
-
- * Fix `g77' command driver so that `g77 -o foo.f' no longer deletes
- `foo.f' before issuing other diagnostics, and so the `-x' option
- is properly handled.
-
- * Enable inlining of subroutines and functions by the `gcc' back end.
- This works as it does for `gcc' itself--program units may be
- inlined for invocations that follow them in the same program unit,
- as long as the appropriate compile-time options are specified.
-
- * Dummy arguments are no longer assumed to potentially alias
- (overlap) other dummy arguments or `COMMON' areas when any of
- these are defined (assigned to) by Fortran code.
-
- This can result in faster and/or smaller programs when compiling
- with optimization enabled, though on some systems this effect is
- observed only when `-fforce-addr' also is specified.
-
- New options `-falias-check', `-fargument-alias',
- `-fargument-noalias', and `-fno-argument-noalias-global' control
- the way `g77' handles potential aliasing.
-
- * The `CONJG()' and `DCONJG()' intrinsics now are compiled in-line.
-
- * The bug-fix for 0.5.19.1 has been re-done. The `g77' compiler has
- been changed back to assume `libf2c' has no aliasing problems in
- its implementations of the `COMPLEX' (and `DOUBLE COMPLEX')
- intrinsics. The `libf2c' has been changed to have no such
- problems.
+ 21. Improve documentation and indexing.
- As a result, 0.5.20 is expected to offer improved performance over
- 0.5.19.1, perhaps as good as 0.5.19 in most or all cases, due to
- this change alone.
+ 22. The upgrade to `libf2c' as of 1998-06-18 should fix a variety of
+ problems, including those involving some uses of the `T' format
+ specifier, and perhaps some build (porting) problems as well.
- *Note:* This change requires version 0.5.20 of `libf2c', at least,
- when linking code produced by any versions of `g77' other than
- 0.5.19.1. Use `g77 -v' to determine the version numbers of the
- `libF77', `libI77', and `libU77' components of the `libf2c'
- library. (If these version numbers are not printed--in
- particular, if the linker complains about unresolved references to
- names like `g77__fvers__'--that strongly suggests your
- installation has an obsolete version of `libf2c'.)
+In 0.5.24 and `egcs' 1.1 (versus 0.5.23):
+=========================================
- * New option `-fugly-assign' specifies that the same memory
- locations are to be used to hold the values assigned by both
- statements `I = 3' and `ASSIGN 10 TO I', for example. (Normally,
- `g77' uses a separate memory location to hold assigned statement
- labels.)
-
- * `FORMAT' and `ENTRY' statements now are allowed to precede
- `IMPLICIT NONE' statements.
-
- * Produce diagnostic for unsupported `SELECT CASE' on `CHARACTER'
- type, instead of crashing, at compile time.
-
- * Fix crashes involving diagnosed or invalid code.
-
- * Change approach to building `libf2c' archive (`libf2c.a') so that
- members are added to it only when truly necessary, so the user
- that installs an already-built `g77' doesn't need to have write
- access to the build tree (whereas the user doing the build might
- not have access to install new software on the system).
-
- * Support `gcc' version 2.7.2.2 (modified by `g77' into version
- 2.7.2.2.f.2), and remove support for prior versions of `gcc'.
-
- * Upgrade to `libf2c' as of 1997-02-08, and fix up some of the build
- procedures.
-
- * Improve general build procedures for `g77', fixing minor bugs
- (such as deletion of any file named `f771' in the parent directory
- of `gcc/').
-
- * Enable full support of `INTEGER*8' available in `libf2c' and
- `f2c.h' so that `f2c' users may make full use of its features via
- the `g77' version of `f2c.h' and the `INTEGER*8' support routines
- in the `g77' version of `libf2c'.
-
- * Improve `g77' driver and `libf2c' so that `g77 -v' yields version
- information on the library.
-
- * The `SNGL' and `FLOAT' intrinsics now are specific intrinsics,
- instead of synonyms for the generic intrinsic `REAL'.
-
- * New intrinsics have been added. These are `REALPART', `IMAGPART',
- `COMPLEX', `LONG', and `SHORT'.
-
- * A new group of intrinsics, `gnu', has been added to contain the
- new `REALPART', `IMAGPART', and `COMPLEX' intrinsics. An old
- group, `dcp', has been removed.
-
- * Complain about industry-wide ambiguous references `REAL(EXPR)' and
- `AIMAG(EXPR)', where EXPR is `DOUBLE COMPLEX' (or any complex type
- other than `COMPLEX'), unless `-ff90' option specifies Fortran 90
- interpretation or new `-fugly-complex' option, in conjunction with
- `-fnot-f90', specifies `f2c' interpretation.
-
- * Make improvements to diagnostics.
-
- * Speed up compiler a bit.
-
- * Improvements to documentation and indexing, including a new
- chapter containing information on one, later more, diagnostics
- that users are directed to pull up automatically via a message in
- the diagnostic itself.
-
- (Hence the menu item `M' for the node `Diagnostics' in the
- top-level menu of the Info documentation.)
-
-In 0.5.19.1:
-============
-
- * Code-generation bugs afflicting operations on complex data have
- been fixed.
-
- These bugs occurred when assigning the result of an operation to a
- complex variable (or array element) that also served as an input
- to that operation.
-
- The operations affected by this bug were: `CONJG()', `DCONJG()',
- `CCOS()', `CDCOS()', `CLOG()', `CDLOG()', `CSIN()', `CDSIN()',
- `CSQRT()', `CDSQRT()', complex division, and raising a `DOUBLE
- COMPLEX' operand to an `INTEGER' power. (The related generic and
- `Z'-prefixed intrinsics, such as `ZSIN()', also were affected.)
-
- For example, `C = CSQRT(C)', `Z = Z/C', and `Z = Z**I' (where `C'
- is `COMPLEX' and `Z' is `DOUBLE COMPLEX') have been fixed.
-
-In 0.5.19:
-==========
-
- * Fix `FORMAT' statement parsing so negative values for specifiers
- such as `P' (e.g. `FORMAT(-1PF8.1)') are correctly processed as
- negative.
-
- * Fix `SIGNAL' intrinsic so it once again accepts a procedure as its
- second argument.
-
- * A temporary kludge option provides bare-bones information on
- `COMMON' and `EQUIVALENCE' members at debug time.
-
- * New `-fonetrip' option specifies FORTRAN-66-style one-trip `DO'
- loops.
-
- * New `-fno-silent' option causes names of program units to be
- printed as they are compiled, in a fashion similar to UNIX `f77'
- and `f2c'.
-
- * New `-fugly-assumed' option specifies that arrays dimensioned via
- `DIMENSION X(1)', for example, are to be treated as assumed-size.
-
- * New `-fno-typeless-boz' option specifies that non-decimal-radix
- constants using the prefixed-radix form (such as `Z'1234'') are to
- be interpreted as `INTEGER' constants.
-
- * New `-ff66' option is a "shorthand" option that specifies
- behaviors considered appropriate for FORTRAN 66 programs.
-
- * New `-ff77' option is a "shorthand" option that specifies
- behaviors considered appropriate for UNIX `f77' programs.
-
- * New `-fugly-comma' and `-fugly-logint' options provided to perform
- some of what `-fugly' used to do. `-fugly' and `-fno-ugly' are
- now "shorthand" options, in that they do nothing more than enable
- (or disable) other `-fugly-*' options.
-
- * Fix parsing of assignment statements involving targets that are
- substrings of elements of `CHARACTER' arrays having names such as
- `READ', `WRITE', `GOTO', and `REALFUNCTIONFOO'.
-
- * Fix crashes involving diagnosed code.
-
- * Fix handling of local `EQUIVALENCE' areas so certain cases of
- valid Fortran programs are not misdiagnosed as improperly
- extending the area backwards.
-
- * Support `gcc' version 2.7.2.1.
-
- * Upgrade to `libf2c' as of 1996-09-26, and fix up some of the build
- procedures.
-
- * Change code generation for list-directed I/O so it allows for new
- versions of `libf2c' that might return non-zero status codes for
- some operations previously assumed to always return zero.
-
- This change not only affects how `IOSTAT=' variables are set by
- list-directed I/O, it also affects whether `END=' and `ERR='
- labels are reached by these operations.
-
- * Add intrinsic support for new `FTELL' and `FSEEK' procedures in
- `libf2c'.
-
- * Modify `fseek_()' in `libf2c' to be more portable (though, in
- practice, there might be no systems where this matters) and to
- catch invalid `whence' arguments.
-
- * Some useless warnings from the `-Wunused' option have been
- eliminated.
-
- * Fix a problem building the `f771' executable on AIX systems by
- linking with the `-bbigtoc' option.
-
- * Abort configuration if `gcc' has not been patched using the patch
- file provided in the `gcc/f/gbe/' subdirectory.
-
- * Add options `--help' and `--version' to the `g77' command, to
- conform to GNU coding guidelines. Also add printing of `g77'
- version number when the `--verbose' (`-v') option is used.
-
- * Change internally generated name for local `EQUIVALENCE' areas to
- one based on the alphabetically sorted first name in the list of
- names for entities placed at the beginning of the areas.
-
- * Improvements to documentation and indexing.
-
-In 0.5.18:
-==========
-
- * Add some rudimentary support for `INTEGER*1', `INTEGER*2',
- `INTEGER*8', and their `LOGICAL' equivalents. (This support works
- on most, maybe all, `gcc' targets.)
-
- Thanks to Scott Snyder (<snyder@d0sgif.fnal.gov>) for providing
- the patch for this!
-
- Among the missing elements from the support for these features are
- full intrinsic support and constants.
-
- * Add some rudimentary support for the `BYTE' and `WORD'
- type-declaration statements. `BYTE' corresponds to `INTEGER*1',
- while `WORD' corresponds to `INTEGER*2'.
-
- Thanks to Scott Snyder (<snyder@d0sgif.fnal.gov>) for providing
- the patch for this!
-
- * The compiler code handling intrinsics has been largely rewritten
- to accommodate the new types. No new intrinsics or arguments for
- existing intrinsics have been added, so there is, at this point,
- no intrinsic to convert to `INTEGER*8', for example.
-
- * Support automatic arrays in procedures.
-
- * Reduce space/time requirements for handling large *sparsely*
- initialized aggregate arrays. This improvement applies to only a
- subset of the general problem to be addressed in 0.6.
-
- * Treat initial values of zero as if they weren't specified (in DATA
- and type-declaration statements). The initial values will be set
- to zero anyway, but the amount of compile time processing them
- will be reduced, in some cases significantly (though, again, this
- is only a subset of the general problem to be addressed in 0.6).
-
- A new option, `-fzeros', is introduced to enable the traditional
- treatment of zeros as any other value.
-
- * With `-ff90' in force, `g77' incorrectly interpreted `REAL(Z)' as
- returning a `REAL' result, instead of as a `DOUBLE PRECISION'
- result. (Here, `Z' is `DOUBLE COMPLEX'.)
-
- With `-fno-f90' in force, the interpretation remains unchanged,
- since this appears to be how at least some F77 code using the
- `DOUBLE COMPLEX' extension expected it to work.
-
- Essentially, `REAL(Z)' in F90 is the same as `DBLE(Z)', while in
- extended F77, it appears to be the same as `REAL(REAL(Z))'.
-
- * An expression involving exponentiation, where both operands were
- type `INTEGER' and the right-hand operand was negative, was
- erroneously evaluated.
-
- * Fix bugs involving `DATA' implied-`DO' constructs (these involved
- an errant diagnostic and a crash, both on good code, one involving
- subsequent statement-function definition).
-
- * Close `INCLUDE' files after processing them, so compiling source
- files with lots of `INCLUDE' statements does not result in being
- unable to open `INCLUDE' files after all the available file
- descriptors are used up.
-
- * Speed up compiling, especially of larger programs, and perhaps
- slightly reduce memory utilization while compiling (this is *not*
- the improvement planned for 0.6 involving large aggregate
- areas)--these improvements result from simply turning off some
- low-level code to do self-checking that hasn't been triggered in a
- long time.
-
- * Introduce three new options that implement optimizations in the
- `gcc' back end (GBE). These options are `-fmove-all-movables',
- `-freduce-all-givs', and `-frerun-loop-opt', which are enabled, by
- default, for Fortran compilations. These optimizations are
- intended to help toon Fortran programs.
-
- * Patch the GBE to do a better job optimizing certain kinds of
- references to array elements.
-
- * Due to patches to the GBE, the version number of `gcc' also is
- patched to make it easier to manage installations, especially
- useful if it turns out a `g77' change to the GBE has a bug.
-
- The `g77'-modified version number is the `gcc' version number with
- the string `.f.N' appended, where `f' identifies the version as
- enhanced for Fortran, and N is `1' for the first Fortran patch for
- that version of `gcc', `2' for the second, and so on.
-
- So, this introduces version 2.7.2.f.1 of `gcc'.
-
- * Make several improvements and fixes to diagnostics, including the
- removal of two that were inappropriate or inadequate.
-
- * Warning about two successive arithmetic operators, produced by
- `-Wsurprising', now produced *only* when both operators are,
- indeed, arithmetic (not relational/boolean).
-
- * `-Wsurprising' now warns about the remaining cases of using
- non-integral variables for implied-`DO' loops, instead of these
- being rejected unless `-fpedantic' or `-fugly' specified.
-
- * Allow `SAVE' of a local variable or array, even after it has been
- given an initial value via `DATA', for example.
-
- * Introduce an Info version of `g77' documentation, which supercedes
- `gcc/f/CREDITS', `gcc/f/DOC', and `gcc/f/PROJECTS'. These files
- will be removed in a future release. The files `gcc/f/BUGS',
- `gcc/f/INSTALL', and `gcc/f/NEWS' now are automatically built from
- the texinfo source when distributions are made.
-
- This effort was inspired by a first pass at translating
- `g77-0.5.16/f/DOC' that was contributed to Craig by David Ronis
- (<ronis@onsager.chem.mcgill.ca>).
-
- * New `-fno-second-underscore' option to specify that, when
- `-funderscoring' is in effect, a second underscore is not to be
- appended to Fortran names already containing an underscore.
-
- * Change the way iterative `DO' loops work to follow the F90
- standard. In particular, calculation of the iteration count is
- still done by converting the start, end, and increment parameters
- to the type of the `DO' variable, but the result of the
- calculation is always converted to the default `INTEGER' type.
-
- (This should have no effect on existing code compiled by `g77',
- but code written to assume that use of a *wider* type for the `DO'
- variable will result in an iteration count being fully calculated
- using that wider type (wider than default `INTEGER') must be
- rewritten.)
-
- * Support `gcc' version 2.7.2.
-
- * Upgrade to `libf2c' as of 1996-03-23, and fix up some of the build
- procedures.
-
- Note that the email addresses related to `f2c' have changed--the
- distribution site now is named `netlib.bell-labs.com', and the
- maintainer's new address is <dmg@bell-labs.com>.
-
-In 0.5.17:
-==========
-
- * *Fix serious bug* in `g77 -v' command that can cause removal of a
- system's `/dev/null' special file if run by user `root'.
-
- *All users* of version 0.5.16 should ensure that they have not
- removed `/dev/null' or replaced it with an ordinary file (e.g. by
- comparing the output of `ls -l /dev/null' with `ls -l /dev/zero'.
- If the output isn't basically the same, contact your system
- administrator about restoring `/dev/null' to its proper status).
-
- This bug is particularly insidious because removing `/dev/null' as
- a special file can go undetected for quite a while, aside from
- various applications and programs exhibiting sudden, strange
- behaviors.
-
- I sincerely apologize for not realizing the implications of the
- fact that when `g77 -v' runs the `ld' command with `-o /dev/null'
- that `ld' tries to *remove* the executable it is supposed to build
- (especially if it reports unresolved references, which it should
- in this case)!
-
- * Fix crash on `CHARACTER*(*) FOO' in a main or block data program
- unit.
-
- * Fix crash that can occur when diagnostics given outside of any
- program unit (such as when input file contains `@foo').
-
- * Fix crashes, infinite loops (hangs), and such involving diagnosed
- code.
-
- * Fix `ASSIGN''ed variables so they can be `SAVE''d or dummy
- arguments, and issue clearer error message in cases where target
- of `ASSIGN' or `ASSIGN'ed `GOTO'/`FORMAT' is too small (which
- should never happen).
-
- * Make `libf2c' build procedures work on more systems again by
- eliminating unnecessary invocations of `ld -r -x' and `mv'.
-
- * Fix omission of `-funix-intrinsics-...' options in list of
- permitted options to compiler.
-
- * Fix failure to always diagnose missing type declaration for
- `IMPLICIT NONE'.
-
- * Fix compile-time performance problem (which could sometimes crash
- the compiler, cause a hang, or whatever, due to a bug in the back
- end) involving exponentiation with a large `INTEGER' constant for
- the right-hand operator (e.g. `I**32767').
-
- * Fix build procedures so cross-compiling `g77' (the `fini' utility
- in particular) is properly built using the host compiler.
-
- * Add new `-Wsurprising' option to warn about constructs that are
- interpreted by the Fortran standard (and `g77') in ways that are
- surprising to many programmers.
-
- * Add `ERF()' and `ERFC()' as generic intrinsics mapping to existing
- `ERF'/`DERF' and `ERFC'/`DERFC' specific intrinsics.
-
- *Note:* You should specify `INTRINSIC ERF,ERFC' in any code where
- you might use these as generic intrinsics, to improve likelihood
- of diagnostics (instead of subtle run-time bugs) when using a
- compiler that doesn't support these as intrinsics (e.g. `f2c').
-
- * Remove from `-fno-pedantic' the diagnostic about `DO' with
- non-`INTEGER' index variable; issue that under `-Wsurprising'
- instead.
-
- * Clarify some diagnostics that say things like "ignored" when that's
- misleading.
-
- * Clarify diagnostic on use of `.EQ.'/`.NE.' on `LOGICAL' operands.
-
- * Minor improvements to code generation for various operations on
- `LOGICAL' operands.
-
- * Minor improvement to code generation for some `DO' loops on some
- machines.
-
- * Support `gcc' version 2.7.1.
-
- * Upgrade to `libf2c' as of 1995-11-15.
-
-In 0.5.16:
-==========
-
- * Fix a code-generation bug involving complicated `EQUIVALENCE'
- statements not involving `COMMON'.
-
- * Fix code-generation bugs involving invoking "gratis" library
- procedures in `libf2c' from code compiled with `-fno-f2c' by
- making these procedures known to `g77' as intrinsics (not affected
- by -fno-f2c). This is known to fix code invoking `ERF()',
- `ERFC()', `DERF()', and `DERFC()'.
-
- * Update `libf2c' to include netlib patches through 1995-08-16, and
- `#define' `WANT_LEAD_0' to 1 to make `g77'-compiled code more
- consistent with other Fortran implementations by outputting
- leading zeros in formatted and list-directed output.
-
- * Fix a code-generation bug involving adjustable dummy arrays with
- high bounds whose primaries are changed during procedure
- execution, and which might well improve code-generation
- performance for such arrays compared to `f2c' plus `gcc' (but
- apparently only when using `gcc-2.7.0' or later).
-
- * Fix a code-generation bug involving invocation of `COMPLEX' and
- `DOUBLE COMPLEX' `FUNCTION's and doing `COMPLEX' and `DOUBLE
- COMPLEX' divides, when the result of the invocation or divide is
- assigned directly to a variable that overlaps one or more of the
- arguments to the invocation or divide.
-
- * Fix crash by not generating new optimal code for `X**I' if `I' is
- nonconstant and the expression is used to dimension a dummy array,
- since the `gcc' back end does not support the necessary mechanics
- (and the `gcc' front end rejects the equivalent construct, as it
- turns out).
-
- * Fix crash on expressions like `COMPLEX**INTEGER'.
-
- * Fix crash on expressions like `(1D0,2D0)**2', i.e. raising a
- `DOUBLE COMPLEX' constant to an `INTEGER' constant power.
-
- * Fix crashes and such involving diagnosed code.
-
- * Diagnose, instead of crashing on, statement function definitions
- having duplicate dummy argument names.
-
- * Fix bug causing rejection of good code involving statement function
- definitions.
-
- * Fix bug resulting in debugger not knowing size of local equivalence
- area when any member of area has initial value (via `DATA', for
- example).
-
- * Fix installation bug that prevented installation of `g77' driver.
- Provide for easy selection of whether to install copy of `g77' as
- `f77' to replace the broken code.
-
- * Fix `gcc' driver (affects `g77' thereby) to not gratuitously
- invoke the `f771' program (e.g. when `-E' is specified).
-
- * Fix diagnostic to point to correct source line when it immediately
- follows an `INCLUDE' statement.
-
- * Support more compiler options in `gcc'/`g77' when compiling
- Fortran files. These options include `-p', `-pg', `-aux-info',
- `-P', correct setting of version-number macros for preprocessing,
- full recognition of `-O0', and automatic insertion of
- configuration-specific linker specs.
-
- * Add new intrinsics that interface to existing routines in `libf2c':
- `ABORT', `DERF', `DERFC', `ERF', `ERFC', `EXIT', `FLUSH',
- `GETARG', `GETENV', `IARGC', `SIGNAL', and `SYSTEM'. Note that
- `ABORT', `EXIT', `FLUSH', `SIGNAL', and `SYSTEM' are intrinsic
- subroutines, not functions (since they have side effects), so to
- get the return values from `SIGNAL' and `SYSTEM', append a final
- argument specifying an `INTEGER' variable or array element (e.g.
- `CALL SYSTEM('rm foo',ISTAT)').
-
- * Add new intrinsic group named `unix' to contain the new intrinsics,
- and by default enable this new group.
-
- * Move `LOC()' intrinsic out of the `vxt' group to the new `unix'
- group.
-
- * Improve `g77' so that `g77 -v' by itself (or with certain other
- options, including `-B', `-b', `-i', `-nostdlib', and `-V')
- reports lots more useful version info, and so that long-form
- options `gcc' accepts are understood by `g77' as well (even in
- truncated, unambiguous forms).
-
- * Add new `g77' option `--driver=name' to specify driver when
- default, `gcc', isn't appropriate.
-
- * Add support for `#' directives (as output by the preprocessor) in
- the compiler, and enable generation of those directives by the
- preprocessor (when compiling `.F' files) so diagnostics and
- debugging info are more useful to users of the preprocessor.
-
- * Produce better diagnostics, more like `gcc', with info such as `In
- function `foo':' and `In file included from...:'.
-
- * Support `gcc''s `-fident' and `-fno-ident' options.
-
- * When `-Wunused' in effect, don't warn about local variables used as
- statement-function dummy arguments or `DATA' implied-`DO' iteration
- variables, even though, strictly speaking, these are not uses of
- the variables themselves.
-
- * When `-W -Wunused' in effect, don't warn about unused dummy
- arguments at all, since there's no way to turn this off for
- individual cases (`g77' might someday start warning about
- these)--applies to `gcc' versions 2.7.0 and later, since earlier
- versions didn't warn about unused dummy arguments.
-
- * New option `-fno-underscoring' that inhibits transformation of
- names (by appending one or two underscores) so users may experiment
- with implications of such an environment.
-
- * Minor improvement to `gcc/f/info' module to make it easier to build
- `g77' using the native (non-`gcc') compiler on certain machines
- (but definitely not all machines nor all non-`gcc' compilers).
- Please do not report bugs showing problems compilers have with
- macros defined in `gcc/f/target.h' and used in places like
- `gcc/f/expr.c'.
-
- * Add warning to be printed for each invocation of the compiler if
- the target machine `INTEGER', `REAL', or `LOGICAL' size is not 32
- bits, since `g77' is known to not work well for such cases (to be
- fixed in Version 0.6--*note Actual Bugs We Haven't Fixed Yet:
- Actual Bugs.).
-
- * Lots of new documentation (though work is still needed to put it
- into canonical GNU format).
-
- * Build `libf2c' with `-g0', not `-g2', in effect (by default), to
- produce smaller library without lots of debugging clutter.
-
-In 0.5.15:
-==========
-
- * Fix bad code generation involving `X**I' and temporary, internal
- variables generated by `g77' and the back end (such as for `DO'
- loops).
-
- * Fix crash given `CHARACTER A;DATA A/.TRUE./'.
-
- * Replace crash with diagnostic given `CHARACTER A;DATA A/1.0/'.
-
- * Fix crash or other erratic behavior when null character constant
- (`''') is encountered.
-
- * Fix crash or other erratic behavior involving diagnosed code.
-
- * Fix code generation for external functions returning type `REAL'
- when the `-ff2c' option is in force (which it is by default) so
- that `f2c' compatibility is indeed provided.
-
- * Disallow `COMMON I(10)' if `I' has previously been specified with
- an array declarator.
-
- * New `-ffixed-line-length-N' option, where N is the maximum length
- of a typical fixed-form line, defaulting to 72 columns, such that
- characters beyond column N are ignored, or N is `none', meaning no
- characters are ignored. does not affect lines with `&' in column
- 1, which are always processed as if `-ffixed-line-length-none' was
- in effect.
-
- * No longer generate better code for some kinds of array references,
- as `gcc' back end is to be fixed to do this even better, and it
- turned out to slow down some code in some cases after all.
-
- * In `COMMON' and `EQUIVALENCE' areas with any members given initial
- values (e.g. via `DATA'), uninitialized members now always
- initialized to binary zeros (though this is not required by the
- standard, and might not be done in future versions of `g77').
- Previously, in some `COMMON'/`EQUIVALENCE' areas (essentially
- those with members of more than one type), the uninitialized
- members were initialized to spaces, to cater to `CHARACTER' types,
- but it seems no existing code expects that, while much existing
- code expects binary zeros.
-
-In 0.5.14:
-==========
-
- * Don't emit bad code when low bound of adjustable array is
- nonconstant and thus might vary as an expression at run time.
-
- * Emit correct code for calculation of number of trips in `DO' loops
- for cases where the loop should not execute at all. (This bug
- affected cases where the difference between the begin and end
- values was less than the step count, though probably not for
- floating-point cases.)
-
- * Fix crash when extra parentheses surround item in `DATA'
- implied-`DO' list.
-
- * Fix crash over minor internal inconsistencies in handling
- diagnostics, just substitute dummy strings where necessary.
-
- * Fix crash on some systems when compiling call to `MVBITS()'
- intrinsic.
-
- * Fix crash on array assignment `TYPEDDD(...)=...', where DDD is a
- string of one or more digits.
-
- * Fix crash on `DCMPLX()' with a single `INTEGER' argument.
-
- * Fix various crashes involving code with diagnosed errors.
-
- * Support `-I' option for `INCLUDE' statement, plus `gcc''s
- `header.gcc' facility for handling systems like MS-DOS.
-
- * Allow `INCLUDE' statement to be continued across multiple lines,
- even allow it to coexist with other statements on the same line.
-
- * Incorporate Bellcore fixes to `libf2c' through 1995-03-15--this
- fixes a bug involving infinite loops reading EOF with empty
- list-directed I/O list.
-
- * Remove all the `g77'-specific auto-configuration scripts, code,
- and so on, except for temporary substitutes for bsearch() and
- strtoul(), as too many configure/build problems were reported in
- these areas. People will have to fix their systems' problems
- themselves, or at least somewhere other than `g77', which expects
- a working ANSI C environment (and, for now, a GNU C compiler to
- compile `g77' itself).
-
- * Complain if initialized common redeclared as larger in subsequent
- program unit.
-
- * Warn if blank common initialized, since its size can vary and hence
- related warnings that might be helpful won't be seen.
-
- * New `-fbackslash' option, on by default, that causes `\' within
- `CHARACTER' and Hollerith constants to be interpreted a la GNU C.
- Note that this behavior is somewhat different from `f2c''s, which
- supports only a limited subset of backslash (escape) sequences.
-
- * Make `-fugly-args' the default.
-
- * New `-fugly-init' option, on by default, that allows
- typeless/Hollerith to be specified as initial values for variables
- or named constants (`PARAMETER'), and also allows
- character<->numeric conversion in those contexts--turn off via
- `-fno-ugly-init'.
-
- * New `-finit-local-zero' option to initialize local variables to
- binary zeros. This does not affect whether they are `SAVE'd, i.e.
- made automatic or static.
-
- * New `-Wimplicit' option to warn about implicitly typed variables,
- arrays, and functions. (Basically causes all program units to
- default to `IMPLICIT NONE'.)
-
- * `-Wall' now implies `-Wuninitialized' as with `gcc' (i.e. unless
- `-O' not specified, since `-Wuninitialized' requires `-O'), and
- implies `-Wunused' as well.
-
- * `-Wunused' no longer gives spurious messages for unused `EXTERNAL'
- names (since they are assumed to refer to block data program
- units, to make use of libraries more reliable).
-
- * Support `%LOC()' and `LOC()' of character arguments.
-
- * Support null (zero-length) character constants and expressions.
-
- * Support `f2c''s `IMAG()' generic intrinsic.
-
- * Support `ICHAR()', `IACHAR()', and `LEN()' of character
- expressions that are valid in assignments but not normally as
- actual arguments.
-
- * Support `f2c'-style `&' in column 1 to mean continuation line.
-
- * Allow `NAMELIST', `EXTERNAL', `INTRINSIC', and `VOLATILE' in
- `BLOCK DATA', even though these are not allowed by the standard.
-
- * Allow `RETURN' in main program unit.
-
- * Changes to Hollerith-constant support to obey Appendix C of the
- standard:
-
- - Now padded on the right with zeros, not spaces.
-
- - Hollerith "format specifications" in the form of arrays of
- non-character allowed.
-
- - Warnings issued when non-space truncation occurs when
- converting to another type.
-
- - When specified as actual argument, now passed by reference to
- `INTEGER' (padded on right with spaces if constant too small,
- otherwise fully intact if constant wider the `INTEGER' type)
- instead of by value.
-
- *Warning:* `f2c' differs on the interpretation of `CALL FOO(1HX)',
- which it treats exactly the same as `CALL FOO('X')', but which the
- standard and `g77' treat as `CALL FOO(%REF('X '))' (padded with
- as many spaces as necessary to widen to `INTEGER'), essentially.
-
- * Changes and fixes to typeless-constant support:
-
- - Now treated as a typeless double-length `INTEGER' value.
+ 23. `g77' no longer produces incorrect code and initial values for
+ `EQUIVALENCE' and `COMMON' aggregates that, due to "unnatural"
+ ordering of members vis-a-vis their types, require initial padding.
- - Warnings issued when overflow occurs.
+ 24. `g77' no longer crashes when compiling code containing
+ specification statements such as `INTEGER(KIND=7) PTR'.
- - Padded on the left with zeros when converting to a larger
- type.
+ 25. `g77' no longer crashes when compiling code such as `J = SIGNAL(1,
+ 2)'.
- - Should be properly aligned and ordered on the target machine
- for whatever type it is turned into.
+ * `g77' now treats `%LOC(EXPR)' and `LOC(EXPR)' as "ordinary"
+ expressions when they are used as arguments in procedure calls.
+ This change applies only to global (filewide) analysis, making it
+ consistent with how `g77' actually generates code for these cases.
- - When specified as actual argument, now passed as reference to
- a default `INTEGER' constant.
+ Previously, `g77' treated these expressions as denoting special
+ "pointer" arguments for the purposes of filewide analysis.
- * `%DESCR()' of a non-`CHARACTER' expression now passes a pointer to
- the expression plus a length for the expression just as if it were
- a `CHARACTER' expression. For example, `CALL FOO(%DESCR(D))',
- where `D' is `REAL*8', is the same as `CALL FOO(D,%VAL(8)))'.
+ * The `g77' driver now ensures that `-lg2c' is specified in the link
+ phase prior to any occurrence of `-lm'. This prevents
+ accidentally linking to a routine in the SunOS4 `-lm' library when
+ the generated code wants to link to the one in `libf2c' (`libg2c').
- * Name of multi-entrypoint master function changed to incorporate
- the name of the primary entry point instead of a decimal value, so
- the name of the master function for `SUBROUTINE X' with alternate
- entry points is now `__g77_masterfun_x'.
+ * `g77' emits more debugging information when `-g' is used.
- * Remove redundant message about zero-step-count `DO' loops.
+ This new information allows, for example, `which __g77_length_a'
+ to be used in `gdb' to determine the type of the phantom length
+ argument supplied with `CHARACTER' variables.
- * Clean up diagnostic messages, shortening many of them.
+ This information pertains to internally-generated type, variable,
+ and other information, not to the longstanding deficiencies
+ vis-a-vis `COMMON' and `EQUIVALENCE'.
- * Fix typo in `g77' man page.
+ * The F90 `Date_and_Time' intrinsic now is supported.
- * Clarify implications of constant-handling bugs in `f/BUGS'.
+ * The F90 `System_Clock' intrinsic allows the optional arguments
+ (except for the `Count' argument) to be omitted.
- * Generate better code for `**' operator with a right-hand operand of
- type `INTEGER'.
+ 26. Upgrade to `libf2c' as of 1998-06-18.
- * Generate better code for `SQRT()' and `DSQRT()', also when
- `-ffast-math' specified, enable better code generation for `SIN()'
- and `COS()'.
+ 27. Improve documentation and indexing.
- * Generate better code for some kinds of array references.
+In previous versions:
+=====================
- * Speed up lexing somewhat (this makes the compilation phase
- noticeably faster).
+ Information on previous versions is not provided in this
+`egcs/gcc/f/NEWS' file, to keep it short. See `egcs/gcc/f/news.texi',
+or any of its other derivations (Info, HTML, dvi forms) for such
+information.
diff --git a/gcc/f/ansify.c b/gcc/f/ansify.c
index 3af68e55483..15b05e8fd90 100644
--- a/gcc/f/ansify.c
+++ b/gcc/f/ansify.c
@@ -1,6 +1,6 @@
/* ansify.c
Copyright (C) 1997 Free Software Foundation, Inc.
- Contributed by James Craig Burley (burley@gnu.org).
+ Contributed by James Craig Burley.
This file is part of GNU Fortran.
diff --git a/gcc/f/assert.j b/gcc/f/assert.j
index 5bf37928672..b12daeba195 100644
--- a/gcc/f/assert.j
+++ b/gcc/f/assert.j
@@ -1 +1,2 @@
Contributed by James Craig Burley (burley@gnu.org).
+ Contributed by James Craig Burley.
diff --git a/gcc/f/bad.c b/gcc/f/bad.c
index a9b84d156ad..ef95af366d5 100644
--- a/gcc/f/bad.c
+++ b/gcc/f/bad.c
@@ -1,6 +1,18 @@
Contributed by James Craig Burley (burley@gnu.org).
#include "flags.j"
-#include "toplev.j"
+ Contributed by James Craig Burley.
if ((s[0] != '\0') && ISALPHA (s[0]) && ISLOWER (s[0]))
if (ISALPHA (c) && ISUPPER (c))
else if (ISDIGIT (c))
+ const char *message;
+static const char *ffebad_string_[FFEBAD_MAX_];
+static const char *ffebad_message_;
+static int ffebad_bufputs_ (char buf[], int bufi, const char *s);
+ffebad_bufputs_ (char buf[], int bufi, const char *s)
+ const char *message)
+ ffebad_string(const char *string);
+ffebad_string (const char *string)
+ static const char *spaces
+ unsigned char c;
+ unsigned const char *s;
+ const char *fn;
diff --git a/gcc/f/bad.def b/gcc/f/bad.def
index 3a86a1f1ffc..4c7bfe475f2 100644
--- a/gcc/f/bad.def
+++ b/gcc/f/bad.def
@@ -1,6 +1,6 @@
/* bad.def -- Public #include File (module.h template V1.0)
Copyright (C) 1995-1997 Free Software Foundation, Inc.
- Contributed by James Craig Burley (burley@gnu.org).
+ Contributed by James Craig Burley.
This file is part of GNU Fortran.
@@ -700,6 +700,10 @@ FFEBAD_MSGS1 (FFEBAD_ARRAY_LARGE, FATAL,
"Array `%A' at %0 is too large to handle")
FFEBAD_MSGS1 (FFEBAD_SFUNC_UNUSED, WARN,
"Statement function `%A' defined at %0 is not used")
+FFEBAD_MSGS1 (FFEBAD_INTRINSIC_Y2KBAD, WARN,
+"Intrinsic `%A', invoked at %0, known to be non-Y2K-compliant [info -f g77 M Y2KBAD]")
+FFEBAD_MSGS1 (FFEBAD_NOCANDO, DISASTER,
+"Internal compiler error -- cannot perform operation")
#undef INFORM
#undef TRIVIAL
diff --git a/gcc/f/bad.h b/gcc/f/bad.h
index 5bf37928672..6f3690894b6 100644
--- a/gcc/f/bad.h
+++ b/gcc/f/bad.h
@@ -1 +1,4 @@
Contributed by James Craig Burley (burley@gnu.org).
+ Contributed by James Craig Burley.
+ const char *message);
+void ffebad_string (const char *string);
diff --git a/gcc/f/bit.c b/gcc/f/bit.c
index 5bf37928672..b12daeba195 100644
--- a/gcc/f/bit.c
+++ b/gcc/f/bit.c
@@ -1 +1,2 @@
Contributed by James Craig Burley (burley@gnu.org).
+ Contributed by James Craig Burley.
diff --git a/gcc/f/bit.h b/gcc/f/bit.h
index 5bf37928672..b12daeba195 100644
--- a/gcc/f/bit.h
+++ b/gcc/f/bit.h
@@ -1 +1,2 @@
Contributed by James Craig Burley (burley@gnu.org).
+ Contributed by James Craig Burley.
diff --git a/gcc/f/bld-op.def b/gcc/f/bld-op.def
index 5bf37928672..b12daeba195 100644
--- a/gcc/f/bld-op.def
+++ b/gcc/f/bld-op.def
@@ -1 +1,2 @@
Contributed by James Craig Burley (burley@gnu.org).
+ Contributed by James Craig Burley.
diff --git a/gcc/f/bld.c b/gcc/f/bld.c
index c27e525eb66..c798e18d086 100644
--- a/gcc/f/bld.c
+++ b/gcc/f/bld.c
@@ -1,6 +1,6 @@
Contributed by James Craig Burley (burley@gnu.org).
#if FFECOM_targetCURRENT == FFECOM_targetFFE
-#endif
+ Contributed by James Craig Burley.
#if FFECOM_targetCURRENT == FFECOM_targetFFE
#endif
#if FFECOM_targetCURRENT == FFECOM_targetFFE
@@ -12,3 +12,5 @@
x->u.accter.pad = 0;
x->u.arrter.pad = 0;
x->u.conter.pad = 0;
+static const char *ffebld_op_string_[]
+const char *
diff --git a/gcc/f/bld.h b/gcc/f/bld.h
index 071d78230a1..040fc30d4c4 100644
--- a/gcc/f/bld.h
+++ b/gcc/f/bld.h
@@ -1,6 +1,6 @@
Contributed by James Craig Burley (burley@gnu.org).
ffetargetAlign pad; /* Initial padding (for DATA, etc.). */
- ffetargetAlign pad; /* Initial padding (for DATA, etc.). */
+ Contributed by James Craig Burley.
ffetargetAlign pad; /* Initial padding (for DATA, etc.). */
#if FFECOM_targetCURRENT == FFECOM_targetFFE
#endif
@@ -14,3 +14,4 @@
#define ffebld_arrter_set_pad(b,p) ((b)->u.arrter.pad = (p))
#define ffebld_conter_pad(b) ((b)->u.conter.pad)
#define ffebld_conter_set_pad(b,p) ((b)->u.conter.pad = (p))
+const char *ffebld_op_string (ffebldOp o);
diff --git a/gcc/f/bugs.texi b/gcc/f/bugs.texi
index af18d80cdbc..637f205be01 100644
--- a/gcc/f/bugs.texi
+++ b/gcc/f/bugs.texi
@@ -1,43 +1,105 @@
-@c Copyright (C) 1995-1998 Free Software Foundation, Inc.
+@c Copyright (C) 1995-1999 Free Software Foundation, Inc.
@c This is part of the G77 manual.
@c For copying conditions, see the file g77.texi.
@c The text of this file appears in the file BUGS
@c in the G77 distribution, as well as in the G77 manual.
-@c 1998-09-01
+@c Keep this the same as the dates above, since it's used
+@c in the standalone derivations of this file (e.g. BUGS).
+@set copyrights-bugs 1995-1999
-@ifclear BUGSONLY
-@node Actual Bugs
-@section Actual Bugs We Haven't Fixed Yet
-@end ifclear
+@set last-update-bugs 1999-03-15
+
+@include root.texi
+
+@ifset DOC-BUGS
+@c The immediately following lines apply to the BUGS file
+@c which is derived from this file.
+@emph{Note:} This file is automatically generated from the files
+@file{bugs0.texi} and @file{bugs.texi}.
+@file{BUGS} is @emph{not} a source file,
+although it is normally included within source distributions.
+
+This file lists known bugs in the @value{which-g77} version
+of the GNU Fortran compiler.
+Copyright (C) @value{copyrights-bugs} Free Software Foundation, Inc.
+You may copy, distribute, and modify it freely as long as you preserve
+this copyright notice and permission notice.
+
+@node Top,,, (dir)
+@chapter Known Bugs In GNU Fortran
+@end ifset
+
+@ifset DOC-G77
+@node Known Bugs
+@section Known Bugs In GNU Fortran
+@end ifset
This section identifies bugs that @code{g77} @emph{users}
-might run into.
+might run into in the @value{which-g77} version
+of @code{g77}.
This includes bugs that are actually in the @code{gcc}
back end (GBE) or in @code{libf2c}, because those
sets of code are at least somewhat under the control
-of (and necessarily intertwined with) @code{g77}, so it
-isn't worth separating them out.
-
+of (and necessarily intertwined with) @code{g77},
+so it isn't worth separating them out.
+
+@ifset DOC-G77
+For information on bugs in @emph{other} versions of @code{g77},
+see @ref{News,,News About GNU Fortran}.
+There, lists of bugs fixed in various versions of @code{g77}
+can help determine what bugs existed in prior versions.
+@end ifset
+
+@ifset DOC-BUGS
+For information on bugs in @emph{other} versions of @code{g77},
+see @file{@value{path-g77}/NEWS}.
+There, lists of bugs fixed in various versions of @code{g77}
+can help determine what bugs existed in prior versions.
+@end ifset
+
+@ifset DEVELOPMENT
+@emph{Warning:} The information below is still under development,
+and might not accurately reflect the @code{g77} code base
+of which it is a part.
+Efforts are made to keep it somewhat up-to-date,
+but they are particularly concentrated
+on any version of this information
+that is distributed as part of a @emph{released} @code{g77}.
+
+In particular, while this information is intended to apply to
+the @value{which-g77} version of @code{g77},
+only an official @emph{release} of that version
+is expected to contain documentation that is
+most consistent with the @code{g77} product in that version.
+@end ifset
+
+An online, ``live'' version of this document
+(derived directly from the mainline, development version
+of @code{g77} within @code{egcs})
+is available via
+@uref{http://egcs.cygnus.com/onlinedocs/g77_bugs.html}.
+Follow the ``Known Bugs'' link.
+
+@ifset DOC-G77
For information on bugs that might afflict people who
configure, port, build, and install @code{g77},
-@ref{Problems Installing}.
+see @ref{Problems Installing}.
+@end ifset
-@itemize @bullet
-@item
-@code{g77} sometimes crashes when compiling code
-containing the construct @samp{CMPLX(0.)} or similar.
-This is a @code{gcc} back-end bug.
-It can be worked around using @samp{-fno-emulate-complex},
-though that might trigger other, older bugs.
-Compiling without optimization is another work-around.
+@ifset DOC-BUGS
+For information on bugs that might afflict people who
+configure, port, build, and install @code{g77},
+see "Problems Installing" in @file{@value{path-g77}/INSTALL}.
+@end ifset
-Fixed in @code{egcs} 1.1.
+The following information was last updated on @value{last-update-bugs}:
+@itemize @bullet
@item
@c Tim Prince discovered this.
-Automatic arrays aren't working on HP-UX systems,
+Automatic arrays possibly aren't working on HP-UX systems,
at least in HP-UX version 10.20.
Writing into them apparently causes over-writing
of statically declared data in the main program.
@@ -46,33 +108,6 @@ or pointers to them being improperly handled,
e.g. not passed to other procedures as they should be.
@item
-@c Toon Moene discovered these.
-Some Fortran code has been found to be miscompiled
-by @code{g77} built on @code{gcc} version 2.8.1
-on m68k-next-nextstep3 configurations
-when using the @samp{-O2} option.
-Even a C function is known to miscompile
-on that configuration
-when using the @samp{-O2 -funroll-loops} options.
-
-Fixed in @code{egcs}.
-
-@cindex DNRM2
-@cindex stack, 387 coprocessor
-@cindex ix86
-@cindex -O2
-@item
-A code-generation bug afflicts
-Intel x86 targets when @samp{-O2} is specified
-compiling, for example, an old version of
-the @samp{DNRM2} routine.
-The x87 coprocessor stack is being
-mismanaged in cases where assigned @code{GOTO}
-and @code{ASSIGN} are involved.
-
-Fixed in @code{egcs} version 1.1.
-
-@item
@code{g77} fails to warn about
use of a ``live'' iterative-DO variable
as an implied-DO variable
@@ -80,14 +115,6 @@ in a @samp{WRITE} or @samp{PRINT} statement
(although it does warn about this in a @samp{READ} statement).
@item
-A compiler crash, or apparently infinite run time,
-can result when compiling complicated expressions
-involving @code{COMPLEX} arithmetic
-(especially multiplication).
-
-Fixed in @code{egcs} version 1.1.
-
-@item
Something about @code{g77}'s straightforward handling of
label references and definitions sometimes prevents the GBE
from unrolling loops.
@@ -123,7 +150,7 @@ This is to be fixed in version 0.6, when @code{g77} will use the
@cindex compiler memory usage
@cindex memory usage, of compiler
@cindex large aggregate areas
-@cindex initialization
+@cindex initialization, bug
@cindex DATA statement
@cindex statements, DATA
@item
@@ -149,9 +176,11 @@ improvements to the compiler.)
Note that @code{g77} does display a warning message to
notify the user before the compiler appears to hang.
+@ifset DOC-G77
@xref{Large Initialization,,Initialization of Large Aggregate Areas},
for information on how to change the point at which
@code{g77} decides to issue this warning.
+@end ifset
@cindex debugging
@cindex common blocks
@@ -169,8 +198,10 @@ As of Version 0.5.19, a temporary kludge solution is provided whereby
some rudimentary information on a member is written as a string that
is the member's value as a character string.
+@ifset DOC-G77
@xref{Code Gen Options,,Options for Code Generation Conventions},
for information on the @samp{-fdebug-kludge} option.
+@end ifset
@cindex code, displaying main source
@cindex displaying main source code
@@ -219,7 +250,7 @@ Version 0.6 should solve most or all remaining problems
@cindex COMPLEX support
@cindex support, COMPLEX
@item
-Maintainers of gcc report that the back end definitely has ``broken''
+Maintainers of @code{gcc} report that the back end definitely has ``broken''
support for @code{COMPLEX} types.
Based on their input, it seems many of
the problems affect only the more-general facilities for gcc's
@@ -233,19 +264,6 @@ The new option @samp{-fno-emulate-complex} avoids the work-around,
reverting to using the same ``broken'' mechanism as that used
by versions of @code{g77} prior to 0.5.20.
-@cindex ELF support
-@cindex support, ELF
-@cindex -fPIC option
-@cindex options, -fPIC
-@item
-@code{g77} sometimes produces invalid assembler code
-when using the @samp{-fPIC} option (such as compiling for ELF targets)
-on the Intel x86 architecture target.
-The symptom is that the assembler complains about invalid opcodes.
-This bug is in the gcc back end.
-
-Fixed in @code{egcs} version 1.0.2.
-
@cindex padding
@cindex structures
@cindex common blocks
diff --git a/gcc/f/bugs0.texi b/gcc/f/bugs0.texi
index e8f6d22e339..817300e1518 100644
--- a/gcc/f/bugs0.texi
+++ b/gcc/f/bugs0.texi
@@ -1,17 +1,3 @@
-\input texinfo @c -*-texinfo-*-
-@c %**start of header
-@setfilename BUGS
-@set BUGSONLY
-@c %**end of header
-
-@c The immediately following lines apply to the BUGS file
-@c which is generated using this file.
-This file lists known bugs in the GNU Fortran compiler.
-Copyright (C) 1995, 1996 Free Software Foundation, Inc.
-You may copy, distribute, and modify it freely as long as you preserve
-this copyright notice and permission notice.
-
-@node Top,,, (dir)
-@chapter Bugs in GNU Fortran
-@include bugs.texi
-@bye
+@c %**start of header
+@c This tells bugs.texi that it's generating just the BUGS file.
+@set DOC-BUGS
diff --git a/gcc/f/com-rt.def b/gcc/f/com-rt.def
index 6ceaf17db76..5c08fee6c3e 100644
--- a/gcc/f/com-rt.def
+++ b/gcc/f/com-rt.def
@@ -1,6 +1,6 @@
/* com-rt.def -- Public #include File (module.h template V1.0)
Copyright (C) 1995-1997 Free Software Foundation, Inc.
- Contributed by James Craig Burley (burley@gnu.org).
+ Contributed by James Craig Burley.
This file is part of GNU Fortran.
@@ -142,7 +142,7 @@ DEFGFRT (FFECOM_gfrtDACOS, "d_acos", FFECOM_rttypeDOUBLE_, "&d", FALSE, FALSE)
DEFGFRT (FFECOM_gfrtDASIN, "d_asin", FFECOM_rttypeDOUBLE_, "&d", FALSE, FALSE)
DEFGFRT (FFECOM_gfrtDATAN, "d_atan", FFECOM_rttypeDOUBLE_, "&d", FALSE, FALSE)
DEFGFRT (FFECOM_gfrtDATAN2, "d_atn2", FFECOM_rttypeDOUBLE_, "&d", FALSE, FALSE)
-DEFGFRT (FFECOM_gfrtDATE, "G77_date_0", FFECOM_rttypeVOID_, "&a", FALSE, FALSE)
+DEFGFRT (FFECOM_gfrtDATE, "G77_date_y2kbug_0", FFECOM_rttypeVOID_, "&a", FALSE, FALSE)
DEFGFRT (FFECOM_gfrtDATE_AND_TIME, "G77_date_and_time_0", FFECOM_rttypeVOID_, "&a&a&a&i", FALSE, FALSE)
DEFGFRT (FFECOM_gfrtL_BESJ0, "j0", FFECOM_rttypeDOUBLE_, "d", FALSE, FALSE)
DEFGFRT (FFECOM_gfrtL_BESJ1, "j1", FFECOM_rttypeDOUBLE_, "d", FALSE, FALSE)
@@ -242,7 +242,7 @@ DEFGFRT (FFECOM_gfrtTIME, "G77_time_0", FFECOM_rttypeLONGINT_, 0, FALSE, FALSE)
DEFGFRT (FFECOM_gfrtTTYNAM, "G77_ttynam_0", FFECOM_rttypeCHARACTER_, "&i", FALSE, FALSE)
DEFGFRT (FFECOM_gfrtUNLINK, "G77_unlink_0", FFECOM_rttypeINTEGER_, "&a", FALSE, FALSE)
DEFGFRT (FFECOM_gfrtUMASK, "G77_umask_0", FFECOM_rttypeINTEGER_, "&i", FALSE, FALSE)
-DEFGFRT (FFECOM_gfrtVXTIDATE, "G77_vxtidate_0", FFECOM_rttypeVOID_, "&i&i&i", FALSE, FALSE)
+DEFGFRT (FFECOM_gfrtVXTIDATE, "G77_vxtidate_y2kbug_0", FFECOM_rttypeVOID_, "&i&i&i", FALSE, FALSE)
DEFGFRT (FFECOM_gfrtVXTTIME, "G77_vxttime_0", FFECOM_rttypeVOID_, "&a", FALSE, FALSE)
DEFGFRT (FFECOM_gfrtCDABS, "z_abs", FFECOM_rttypeDOUBLE_, "&e", FALSE, FALSE)
DEFGFRT (FFECOM_gfrtCDCOS, "z_cos", FFECOM_rttypeDBLCMPLX_F2C_, "&e", FALSE, TRUE)
diff --git a/gcc/f/com.c b/gcc/f/com.c
index 9db1f8462f4..2c03fae2710 100644
--- a/gcc/f/com.c
+++ b/gcc/f/com.c
@@ -1,6 +1,6 @@
/* com.c -- Implementation File (module.c template V1.0)
Copyright (C) 1995-1998 Free Software Foundation, Inc.
- Contributed by James Craig Burley (burley@gnu.org).
+ Contributed by James Craig Burley.
This file is part of GNU Fortran.
@@ -302,6 +302,8 @@ ffecomSymbol ffecom_symbol_null_
NULL_TREE,
NULL_TREE,
NULL_TREE,
+ NULL_TREE,
+ false
};
ffeinfoKindtype ffecom_pointer_kind_ = FFEINFO_basictypeNONE;
ffeinfoKindtype ffecom_label_kind_ = FFEINFO_basictypeNONE;
@@ -401,7 +403,7 @@ struct _ffecom_temp_
/* Static functions (internal). */
#if FFECOM_targetCURRENT == FFECOM_targetGCC
-static tree ffecom_arglist_expr_ (char *argstring, ffebld args);
+static tree ffecom_arglist_expr_ (const char *argstring, ffebld args);
static tree ffecom_widest_expr_type_ (ffebld list);
static bool ffecom_overlap_ (tree dest_decl, tree dest_offset,
tree dest_size, tree source_tree,
@@ -409,7 +411,7 @@ static bool ffecom_overlap_ (tree dest_decl, tree dest_offset,
static bool ffecom_args_overlapping_ (tree dest_tree, ffebld dest,
tree args, tree callee_commons,
bool scalar_args);
-static tree ffecom_build_f2c_string_ (int i, char *s);
+static tree ffecom_build_f2c_string_ (int i, const char *s);
static tree ffecom_call_ (tree fn, ffeinfoKindtype kt,
bool is_f2c_complex, tree type,
tree args, tree dest_tree,
@@ -432,8 +434,9 @@ static ffecomConcatList_
static void ffecom_concat_list_kill_ (ffecomConcatList_ catlist);
static ffecomConcatList_ ffecom_concat_list_new_ (ffebld expr,
ffetargetCharacterSize max);
-static void ffecom_debug_kludge_ (tree aggr, char *aggr_type, ffesymbol member,
- tree member_type, ffetargetOffset offset);
+static void ffecom_debug_kludge_ (tree aggr, const char *aggr_type,
+ ffesymbol member, tree member_type,
+ ffetargetOffset offset);
static void ffecom_do_entry_ (ffesymbol fn, int entrynum);
static tree ffecom_expr_ (ffebld expr, tree dest_tree, ffebld dest,
bool *dest_used, bool assignp, bool widenp);
@@ -441,18 +444,18 @@ static tree ffecom_expr_intrinsic_ (ffebld expr, tree dest_tree,
ffebld dest, bool *dest_used);
static tree ffecom_expr_power_integer_ (ffebld left, ffebld right);
static void ffecom_expr_transform_ (ffebld expr);
-static void ffecom_f2c_make_type_ (tree *type, int tcode, char *name);
+static void ffecom_f2c_make_type_ (tree *type, int tcode, const char *name);
static void ffecom_f2c_set_lio_code_ (ffeinfoBasictype bt, int size,
int code);
static ffeglobal ffecom_finish_global_ (ffeglobal global);
static ffesymbol ffecom_finish_symbol_transform_ (ffesymbol s);
-static tree ffecom_get_appended_identifier_ (char us, char *text);
+static tree ffecom_get_appended_identifier_ (char us, const char *text);
static tree ffecom_get_external_identifier_ (ffesymbol s);
-static tree ffecom_get_identifier_ (char *text);
+static tree ffecom_get_identifier_ (const char *text);
static tree ffecom_gen_sfuncdef_ (ffesymbol s,
ffeinfoBasictype bt,
ffeinfoKindtype kt);
-static char *ffecom_gfrt_args_ (ffecomGfrt ix);
+static const char *ffecom_gfrt_args_ (ffecomGfrt ix);
static tree ffecom_gfrt_tree_ (ffecomGfrt ix);
static tree ffecom_init_zero_ (tree decl);
static tree ffecom_intrinsic_ichar_ (tree tree_type, ffebld arg,
@@ -493,6 +496,8 @@ static tree ffecom_type_vardesc_ (void);
static tree ffecom_vardesc_ (ffebld expr);
static tree ffecom_vardesc_array_ (ffesymbol s);
static tree ffecom_vardesc_dims_ (ffesymbol s);
+static tree ffecom_convert_narrow_ (tree type, tree expr);
+static tree ffecom_convert_widen_ (tree type, tree expr);
#endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */
/* These are static functions that parallel those found in the C front
@@ -501,9 +506,9 @@ static tree ffecom_vardesc_dims_ (ffesymbol s);
#if FFECOM_targetCURRENT == FFECOM_targetGCC
static void bison_rule_compstmt_ (void);
static void bison_rule_pushlevel_ (void);
-static tree builtin_function (char *name, tree type,
+static tree builtin_function (const char *name, tree type,
enum built_in_function function_code,
- char *library_name);
+ const char *library_name);
static int duplicate_decls (tree newdecl, tree olddecl);
static void finish_decl (tree decl, tree init, bool is_top_level);
static void finish_function (int nested);
@@ -575,7 +580,7 @@ static tree ffecom_gfrt_[FFECOM_gfrt]
/* Holds the external names of the functions. */
-static char *ffecom_gfrt_name_[FFECOM_gfrt]
+static const char *ffecom_gfrt_name_[FFECOM_gfrt]
=
{
#define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX) NAME,
@@ -615,7 +620,7 @@ static ffecomRttype_ ffecom_gfrt_type_[FFECOM_gfrt]
/* String of codes for the function's arguments. */
-static char *ffecom_gfrt_argstring_[FFECOM_gfrt]
+static const char *ffecom_gfrt_argstring_[FFECOM_gfrt]
=
{
#define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX) ARGS,
@@ -1095,7 +1100,7 @@ ffecom_build_complex_constant_ (tree type, tree realpart, tree imagpart)
#if FFECOM_targetCURRENT == FFECOM_targetGCC
static tree
-ffecom_arglist_expr_ (char *c, ffebld expr)
+ffecom_arglist_expr_ (const char *c, ffebld expr)
{
tree list;
tree *plist = &list;
@@ -1517,14 +1522,14 @@ ffecom_args_overlapping_ (tree dest_tree, ffebld dest UNUSED,
#if FFECOM_targetCURRENT == FFECOM_targetGCC
static tree
-ffecom_build_f2c_string_ (int i, char *s)
+ffecom_build_f2c_string_ (int i, const char *s)
{
if (!ffe_is_f2c_library ())
return build_string (i, s);
{
char *tmp;
- char *p;
+ const char *p;
char *q;
char space[34];
tree t;
@@ -2266,7 +2271,7 @@ ffecom_concat_list_new_ (ffebld expr, ffetargetCharacterSize max)
#if FFECOM_targetCURRENT == FFECOM_targetGCC
static void
-ffecom_debug_kludge_ (tree aggr, char *aggr_type, ffesymbol member,
+ffecom_debug_kludge_ (tree aggr, const char *aggr_type, ffesymbol member,
tree member_type UNUSED, ffetargetOffset offset)
{
tree value;
@@ -6560,7 +6565,7 @@ tail_recurse: /* :::::::::::::::::::: */
#if FFECOM_targetCURRENT == FFECOM_targetGCC
static void
-ffecom_f2c_make_type_ (tree *type, int tcode, char *name)
+ffecom_f2c_make_type_ (tree *type, int tcode, const char *name)
{
switch (tcode)
{
@@ -6760,7 +6765,7 @@ ffecom_finish_symbol_transform_ (ffesymbol s)
#if FFECOM_targetCURRENT == FFECOM_targetGCC
static tree
-ffecom_get_appended_identifier_ (char us, char *name)
+ffecom_get_appended_identifier_ (char us, const char *name)
{
int i;
char *newname;
@@ -6789,7 +6794,7 @@ static tree
ffecom_get_external_identifier_ (ffesymbol s)
{
char us;
- char *name = ffesymbol_text (s);
+ const char *name = ffesymbol_text (s);
/* If name is a built-in name, just return it as is. */
@@ -6828,7 +6833,7 @@ ffecom_get_external_identifier_ (ffesymbol s)
#if FFECOM_targetCURRENT == FFECOM_targetGCC
static tree
-ffecom_get_identifier_ (char *name)
+ffecom_get_identifier_ (const char *name)
{
/* If name does not contain an underscore, just return it as is. */
@@ -6989,7 +6994,7 @@ ffecom_gen_sfuncdef_ (ffesymbol s, ffeinfoBasictype bt, ffeinfoKindtype kt)
#endif
#if FFECOM_targetCURRENT == FFECOM_targetGCC
-static char *
+static const char *
ffecom_gfrt_args_ (ffecomGfrt ix)
{
return ffecom_gfrt_argstring_[ix];
@@ -11476,7 +11481,7 @@ ffecom_constantunion (ffebldConstantUnion *cu, ffeinfoBasictype bt,
#if FFECOM_targetCURRENT == FFECOM_targetGCC
tree
ffecom_decl_field (tree context, tree prevfield,
- char *name, tree type)
+ const char *name, tree type)
{
tree field;
@@ -11786,7 +11791,7 @@ ffecom_finish_progunit ()
#if FFECOM_targetCURRENT == FFECOM_targetGCC
tree
-ffecom_get_invented_identifier (char *pattern, char *text, int number)
+ffecom_get_invented_identifier (const char *pattern, const char *text, int number)
{
tree decl;
char *nam;
@@ -13811,8 +13816,9 @@ bison_rule_pushlevel_ ()
the name to be called if we can't opencode the function. */
static tree
-builtin_function (char *name, tree type,
- enum built_in_function function_code, char *library_name)
+builtin_function (const char *name, tree type,
+ enum built_in_function function_code,
+ const char *library_name)
{
tree decl = build_decl (FUNCTION_DECL, get_identifier (name), type);
DECL_EXTERNAL (decl) = 1;
@@ -14416,7 +14422,7 @@ lang_print_error_function (file)
static ffesymbol last_s = NULL;
ffeglobal g;
ffesymbol s;
- char *kind;
+ const char *kind;
if ((ffecom_primary_entry_ == NULL)
|| (ffesymbol_global (ffecom_primary_entry_) == NULL))
@@ -14470,7 +14476,7 @@ lang_print_error_function (file)
fprintf (stderr, "Outside of any program unit:\n");
else
{
- char *name = ffesymbol_text (s);
+ const char *name = ffesymbol_text (s);
fprintf (stderr, "In %s `%s':\n", kind, name);
}
@@ -15822,8 +15828,8 @@ unsigned_type (type)
/* Skip leading "./" from a directory name.
This may yield the empty string, which represents the current directory. */
-static char *
-skip_redundant_dir_prefix (char *dir)
+static const char *
+skip_redundant_dir_prefix (const char *dir)
{
while (dir[0] == '.' && dir[1] == '/')
for (dir += 2; *dir == '/'; dir++)
@@ -15921,10 +15927,9 @@ static void append_include_chain (struct file_name_list *first,
static FILE *open_include_file (char *filename,
struct file_name_list *searchptr);
static void print_containing_files (ffebadSeverity sev);
-static char *skip_redundant_dir_prefix (char *);
+static const char *skip_redundant_dir_prefix (const char *);
static char *read_filename_string (int ch, FILE *f);
-static struct file_name_map *read_name_map (char *dirname);
-static char *savestring (char *input);
+static struct file_name_map *read_name_map (const char *dirname);
/* Append a chain of `struct file_name_list's
to the end of the main include chain.
@@ -16046,8 +16051,8 @@ print_containing_files (ffebadSeverity sev)
FILE_BUF *ip = NULL;
int i;
int first = 1;
- char *str1;
- char *str2;
+ const char *str1;
+ const char *str2;
/* If stack of files hasn't changed since we last printed
this info, don't repeat it. */
@@ -16132,7 +16137,7 @@ read_filename_string (ch, f)
static struct file_name_map *
read_name_map (dirname)
- char *dirname;
+ const char *dirname;
{
/* This structure holds a linked list of file name maps, one per
directory. */
@@ -16158,7 +16163,7 @@ read_name_map (dirname)
map_list_ptr = ((struct file_name_map_list *)
xmalloc (sizeof (struct file_name_map_list)));
- map_list_ptr->map_list_name = savestring (dirname);
+ map_list_ptr->map_list_name = xstrdup (dirname);
map_list_ptr->map_list_map = NULL;
dirlen = strlen (dirname);
@@ -16219,16 +16224,6 @@ read_name_map (dirname)
return map_list_ptr->map_list_map;
}
-static char *
-savestring (input)
- char *input;
-{
- unsigned size = strlen (input);
- char *output = xmalloc (size + 1);
- strcpy (output, input);
- return output;
-}
-
static void
ffecom_file_ (char *name)
{
diff --git a/gcc/f/com.h b/gcc/f/com.h
index db8f4693f87..a438d0bdc86 100644
--- a/gcc/f/com.h
+++ b/gcc/f/com.h
@@ -1,6 +1,6 @@
/* com.h -- Public #include File (module.h template V1.0)
Copyright (C) 1995-1997 Free Software Foundation, Inc.
- Contributed by James Craig Burley (burley@gnu.org).
+ Contributed by James Craig Burley.
This file is part of GNU Fortran.
@@ -283,7 +283,7 @@ tree ffecom_arg_ptr_to_expr (ffebld expr, tree *length);
tree ffecom_call_gfrt (ffecomGfrt ix, tree args);
tree ffecom_constantunion (ffebldConstantUnion *cu, ffeinfoBasictype bt,
ffeinfoKindtype kt, tree tree_type);
-tree ffecom_decl_field (tree context, tree prevfield, char *name,
+tree ffecom_decl_field (tree context, tree prevfield, const char *name,
tree type);
#endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */
void ffecom_close_include (FILE *f);
@@ -299,7 +299,7 @@ tree ffecom_expr_rw (ffebld expr);
void ffecom_finish_compile (void);
void ffecom_finish_decl (tree decl, tree init, bool is_top_level);
void ffecom_finish_progunit (void);
-tree ffecom_get_invented_identifier (char *pattern, char *text,
+tree ffecom_get_invented_identifier (const char *pattern, const char *text,
int number);
ffeinfoKindtype ffecom_gfrt_basictype (ffecomGfrt ix);
ffeinfoKindtype ffecom_gfrt_kindtype (ffecomGfrt ix);
diff --git a/gcc/f/config.j b/gcc/f/config.j
index 5bf37928672..b12daeba195 100644
--- a/gcc/f/config.j
+++ b/gcc/f/config.j
@@ -1 +1,2 @@
Contributed by James Craig Burley (burley@gnu.org).
+ Contributed by James Craig Burley.
diff --git a/gcc/f/convert.j b/gcc/f/convert.j
index 5bf37928672..b12daeba195 100644
--- a/gcc/f/convert.j
+++ b/gcc/f/convert.j
@@ -1 +1,2 @@
Contributed by James Craig Burley (burley@gnu.org).
+ Contributed by James Craig Burley.
diff --git a/gcc/f/data.c b/gcc/f/data.c
index 4e359ac39d5..080b02dd8ac 100644
--- a/gcc/f/data.c
+++ b/gcc/f/data.c
@@ -1,7 +1,9 @@
Contributed by James Craig Burley (burley@gnu.org).
ffebld_arrter_set_pad (ffestorag_init (mst), 0);
- ffebld_arrter_set_pad (ffestorag_init (mst), 0);
+ Contributed by James Craig Burley.
ffebld_arrter_set_pad (ffestorag_init (mst), 0);
ffebld_arrter_set_pad (ffestorag_init (ffedata_storage_),
0);
ffebld_arrter_set_pad (ffestorag_init (ffedata_symbol_), 0);
+static ffebld
+static void
diff --git a/gcc/f/data.h b/gcc/f/data.h
index 5bf37928672..b12daeba195 100644
--- a/gcc/f/data.h
+++ b/gcc/f/data.h
@@ -1 +1,2 @@
Contributed by James Craig Burley (burley@gnu.org).
+ Contributed by James Craig Burley.
diff --git a/gcc/f/equiv.c b/gcc/f/equiv.c
index 3e4818ee545..8603b1591ac 100644
--- a/gcc/f/equiv.c
+++ b/gcc/f/equiv.c
@@ -1,6 +1,6 @@
Copyright (C) 1995-1998 Free Software Foundation, Inc.
Contributed by James Craig Burley (burley@gnu.org).
- ffetargetOffset new_size;
+ Contributed by James Craig Burley.
/* Increase size of equiv area to start for lower offset
relative to root symbol. */
if (! ffetarget_offset_add (&new_size,
diff --git a/gcc/f/equiv.h b/gcc/f/equiv.h
index eb0758ab9c5..59b3931f03f 100644
--- a/gcc/f/equiv.h
+++ b/gcc/f/equiv.h
@@ -1,3 +1,3 @@
Contributed by James Craig Burley (burley@gnu.org).
#if FFECOM_targetCURRENT == FFECOM_targetFFE
-#endif
+ Contributed by James Craig Burley.
diff --git a/gcc/f/expr.c b/gcc/f/expr.c
index 7e7bf867875..72a6264dbf4 100644
--- a/gcc/f/expr.c
+++ b/gcc/f/expr.c
@@ -1,6 +1,6 @@
/* expr.c -- Implementation File (module.c template V1.0)
Copyright (C) 1995-1998 Free Software Foundation, Inc.
- Contributed by James Craig Burley (burley@gnu.org).
+ Contributed by James Craig Burley.
This file is part of GNU Fortran.
@@ -268,7 +268,7 @@ static void ffeexpr_update_impdo_sym_ (ffebld expr, ffesymbol dovar);
static ffeexprContext ffeexpr_context_outer_ (ffeexprStack_ s);
static ffeexprExpr_ ffeexpr_expr_new_ (void);
static void ffeexpr_fulfill_call_ (ffebld *expr, ffelexToken t);
-static bool ffeexpr_isdigits_ (char *p);
+static bool ffeexpr_isdigits_ (const char *p);
static ffelexHandler ffeexpr_token_first_lhs_ (ffelexToken t);
static ffelexHandler ffeexpr_token_first_lhs_1_ (ffelexToken t);
static ffelexHandler ffeexpr_token_first_rhs_ (ffelexToken t);
@@ -633,6 +633,10 @@ ffeexpr_collapse_convert (ffebld expr, ffelexToken t)
break;
}
+ /* If conversion operation is not implemented, return original expr. */
+ if (error == FFEBAD_NOCANDO)
+ return expr;
+
expr = ffebld_new_conter_with_orig
(ffebld_constant_new_integer1_val
(ffebld_cu_val_integer1 (u)), expr);
@@ -822,6 +826,10 @@ ffeexpr_collapse_convert (ffebld expr, ffelexToken t)
break;
}
+ /* If conversion operation is not implemented, return original expr. */
+ if (error == FFEBAD_NOCANDO)
+ return expr;
+
expr = ffebld_new_conter_with_orig
(ffebld_constant_new_integer2_val
(ffebld_cu_val_integer2 (u)), expr);
@@ -1011,6 +1019,10 @@ ffeexpr_collapse_convert (ffebld expr, ffelexToken t)
break;
}
+ /* If conversion operation is not implemented, return original expr. */
+ if (error == FFEBAD_NOCANDO)
+ return expr;
+
expr = ffebld_new_conter_with_orig
(ffebld_constant_new_integer3_val
(ffebld_cu_val_integer3 (u)), expr);
@@ -1200,6 +1212,10 @@ ffeexpr_collapse_convert (ffebld expr, ffelexToken t)
break;
}
+ /* If conversion operation is not implemented, return original expr. */
+ if (error == FFEBAD_NOCANDO)
+ return expr;
+
expr = ffebld_new_conter_with_orig
(ffebld_constant_new_integer4_val
(ffebld_cu_val_integer4 (u)), expr);
@@ -1317,6 +1333,10 @@ ffeexpr_collapse_convert (ffebld expr, ffelexToken t)
break;
}
+ /* If conversion operation is not implemented, return original expr. */
+ if (error == FFEBAD_NOCANDO)
+ return expr;
+
expr = ffebld_new_conter_with_orig
(ffebld_constant_new_logical1_val
(ffebld_cu_val_logical1 (u)), expr);
@@ -1424,6 +1444,10 @@ ffeexpr_collapse_convert (ffebld expr, ffelexToken t)
break;
}
+ /* If conversion operation is not implemented, return original expr. */
+ if (error == FFEBAD_NOCANDO)
+ return expr;
+
expr = ffebld_new_conter_with_orig
(ffebld_constant_new_logical2_val
(ffebld_cu_val_logical2 (u)), expr);
@@ -1531,6 +1555,10 @@ ffeexpr_collapse_convert (ffebld expr, ffelexToken t)
break;
}
+ /* If conversion operation is not implemented, return original expr. */
+ if (error == FFEBAD_NOCANDO)
+ return expr;
+
expr = ffebld_new_conter_with_orig
(ffebld_constant_new_logical3_val
(ffebld_cu_val_logical3 (u)), expr);
@@ -1638,6 +1666,10 @@ ffeexpr_collapse_convert (ffebld expr, ffelexToken t)
break;
}
+ /* If conversion operation is not implemented, return original expr. */
+ if (error == FFEBAD_NOCANDO)
+ return expr;
+
expr = ffebld_new_conter_with_orig
(ffebld_constant_new_logical4_val
(ffebld_cu_val_logical4 (u)), expr);
@@ -1796,6 +1828,10 @@ ffeexpr_collapse_convert (ffebld expr, ffelexToken t)
break;
}
+ /* If conversion operation is not implemented, return original expr. */
+ if (error == FFEBAD_NOCANDO)
+ return expr;
+
expr = ffebld_new_conter_with_orig
(ffebld_constant_new_real1_val
(ffebld_cu_val_real1 (u)), expr);
@@ -1944,6 +1980,10 @@ ffeexpr_collapse_convert (ffebld expr, ffelexToken t)
break;
}
+ /* If conversion operation is not implemented, return original expr. */
+ if (error == FFEBAD_NOCANDO)
+ return expr;
+
expr = ffebld_new_conter_with_orig
(ffebld_constant_new_real2_val
(ffebld_cu_val_real2 (u)), expr);
@@ -2092,6 +2132,10 @@ ffeexpr_collapse_convert (ffebld expr, ffelexToken t)
break;
}
+ /* If conversion operation is not implemented, return original expr. */
+ if (error == FFEBAD_NOCANDO)
+ return expr;
+
expr = ffebld_new_conter_with_orig
(ffebld_constant_new_real3_val
(ffebld_cu_val_real3 (u)), expr);
@@ -2240,6 +2284,10 @@ ffeexpr_collapse_convert (ffebld expr, ffelexToken t)
break;
}
+ /* If conversion operation is not implemented, return original expr. */
+ if (error == FFEBAD_NOCANDO)
+ return expr;
+
expr = ffebld_new_conter_with_orig
(ffebld_constant_new_real4_val
(ffebld_cu_val_real4 (u)), expr);
@@ -2398,6 +2446,10 @@ ffeexpr_collapse_convert (ffebld expr, ffelexToken t)
break;
}
+ /* If conversion operation is not implemented, return original expr. */
+ if (error == FFEBAD_NOCANDO)
+ return expr;
+
expr = ffebld_new_conter_with_orig
(ffebld_constant_new_complex1_val
(ffebld_cu_val_complex1 (u)), expr);
@@ -2546,6 +2598,10 @@ ffeexpr_collapse_convert (ffebld expr, ffelexToken t)
break;
}
+ /* If conversion operation is not implemented, return original expr. */
+ if (error == FFEBAD_NOCANDO)
+ return expr;
+
expr = ffebld_new_conter_with_orig
(ffebld_constant_new_complex2_val
(ffebld_cu_val_complex2 (u)), expr);
@@ -2694,6 +2750,10 @@ ffeexpr_collapse_convert (ffebld expr, ffelexToken t)
break;
}
+ /* If conversion operation is not implemented, return original expr. */
+ if (error == FFEBAD_NOCANDO)
+ return expr;
+
expr = ffebld_new_conter_with_orig
(ffebld_constant_new_complex3_val
(ffebld_cu_val_complex3 (u)), expr);
@@ -2842,6 +2902,10 @@ ffeexpr_collapse_convert (ffebld expr, ffelexToken t)
break;
}
+ /* If conversion operation is not implemented, return original expr. */
+ if (error == FFEBAD_NOCANDO)
+ return expr;
+
expr = ffebld_new_conter_with_orig
(ffebld_constant_new_complex4_val
(ffebld_cu_val_complex4 (u)), expr);
@@ -8520,7 +8584,7 @@ ffeexpr_context_outer_ (ffeexprStack_ s)
static ffeexprPercent_
ffeexpr_percent_ (ffelexToken t)
{
- char *p;
+ const char *p;
switch (ffelex_token_length (t))
{
@@ -9473,7 +9537,7 @@ ffeexpr_fulfill_call_ (ffebld *expr, ffelexToken t)
/* Check whether rest of string is all decimal digits. */
static bool
-ffeexpr_isdigits_ (char *p)
+ffeexpr_isdigits_ (const char *p)
{
for (; *p != '\0'; ++p)
if (! ISDIGIT (*p))
@@ -10314,7 +10378,7 @@ ffeexpr_reduced_concatenate_ (ffebld reduced, ffeexprExpr_ l, ffeexprExpr_ op,
if ((lkd != FFEINFO_kindANY)
&& ffebad_start (FFEBAD_CONCAT_ARG_KIND))
{
- char *what;
+ const char *what;
if (lrk != 0)
what = "an array";
@@ -10330,7 +10394,7 @@ ffeexpr_reduced_concatenate_ (ffebld reduced, ffeexprExpr_ l, ffeexprExpr_ op,
{
if (ffebad_start (FFEBAD_CONCAT_ARG_KIND))
{
- char *what;
+ const char *what;
if (rrk != 0)
what = "an array";
@@ -11602,7 +11666,7 @@ static ffelexHandler
ffeexpr_nil_real_ (ffelexToken t)
{
char d;
- char *p;
+ const char *p;
if (((ffelex_token_type (t) != FFELEX_typeNAME)
&& (ffelex_token_type (t) != FFELEX_typeNAMES))
@@ -11640,7 +11704,7 @@ static ffelexHandler
ffeexpr_nil_number_ (ffelexToken t)
{
char d;
- char *p;
+ const char *p;
if (ffeexpr_hollerith_count_ > 0)
ffelex_set_expecting_hollerith (0, '\0',
@@ -11715,7 +11779,7 @@ ffeexpr_nil_number_period_ (ffelexToken t)
{
ffelexHandler nexthandler;
char d;
- char *p;
+ const char *p;
switch (ffelex_token_type (t))
{
@@ -11772,7 +11836,7 @@ static ffelexHandler
ffeexpr_nil_number_real_ (ffelexToken t)
{
char d;
- char *p;
+ const char *p;
if (((ffelex_token_type (t) != FFELEX_typeNAME)
&& (ffelex_token_type (t) != FFELEX_typeNAMES))
@@ -12853,7 +12917,11 @@ again: /* :::::::::::::::::::: */
: ffeinfo_basictype (info))
{
case FFEINFO_basictypeINTEGER:
- error = FALSE;
+ /* Maybe this should be supported someday, but, right now,
+ g77 can't generate a call to libf2c to write to an
+ integer other than the default size. */
+ error = ((! ffeexpr_stack_->is_rhs)
+ && ffeinfo_kindtype (info) != FFEINFO_kindtypeINTEGERDEFAULT);
break;
default:
@@ -13584,7 +13652,7 @@ static ffelexHandler
ffeexpr_token_real_ (ffelexToken t)
{
char d;
- char *p;
+ const char *p;
if (((ffelex_token_type (t) != FFELEX_typeNAME)
&& (ffelex_token_type (t) != FFELEX_typeNAMES))
@@ -13741,7 +13809,7 @@ ffeexpr_token_number_ (ffelexToken t)
ffeexprExpr_ e;
ffeinfo ni;
char d;
- char *p;
+ const char *p;
if (ffeexpr_hollerith_count_ > 0)
ffelex_set_expecting_hollerith (0, '\0',
@@ -13897,7 +13965,7 @@ ffeexpr_token_number_period_ (ffelexToken t)
{
ffeexprExpr_ e;
ffelexHandler nexthandler;
- char *p;
+ const char *p;
char d;
switch (ffelex_token_type (t))
@@ -14015,7 +14083,7 @@ static ffelexHandler
ffeexpr_token_number_real_ (ffelexToken t)
{
char d;
- char *p;
+ const char *p;
if (((ffelex_token_type (t) != FFELEX_typeNAME)
&& (ffelex_token_type (t) != FFELEX_typeNAMES))
diff --git a/gcc/f/expr.h b/gcc/f/expr.h
index 5bf37928672..b12daeba195 100644
--- a/gcc/f/expr.h
+++ b/gcc/f/expr.h
@@ -1 +1,2 @@
Contributed by James Craig Burley (burley@gnu.org).
+ Contributed by James Craig Burley.
diff --git a/gcc/f/fini.c b/gcc/f/fini.c
index 3b98949524b..1b7c9819409 100644
--- a/gcc/f/fini.c
+++ b/gcc/f/fini.c
@@ -1,6 +1,6 @@
/* fini.c
Copyright (C) 1995 Free Software Foundation, Inc.
- Contributed by James Craig Burley (burley@gnu.org).
+ Contributed by James Craig Burley.
This file is part of GNU Fortran.
@@ -24,6 +24,7 @@ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "proj.h"
#include "malloc.h"
+#undef MAXNAMELEN
#define MAXNAMELEN 100
typedef struct _name_ *name;
@@ -61,7 +62,7 @@ static FILE *out;
static char prefix[32];
static char postfix[32];
static char storage[32];
-static char *spaces[]
+static const char *xspaces[]
=
{
"", /* 0 */
@@ -635,7 +636,7 @@ testname (bool nested, int indent, name first, name last)
int numhalf;
assert (!nested || indent >= 2);
- assert (((size_t) indent) + 4 < ARRAY_SIZE (spaces));
+ assert (((size_t) indent) + 4 < ARRAY_SIZE (xspaces));
num = 0;
numhalf = 0;
@@ -653,15 +654,15 @@ testname (bool nested, int indent, name first, name last)
"\
%s{\n\
",
- spaces[indent - 2]);
+ xspaces[indent - 2]);
fprintf (out,
"\
%sif ((c = ffesrc_strcmp_2c (ffe_case_match (), p, \"%s\", \"%s\", \"%s\")) == 0)\n\
%sreturn %s%s%s;\n\
",
- spaces[indent], nhalf->name_uc, nhalf->name_lc, nhalf->name_ic,
- spaces[indent + 2], prefix, nhalf->kwname, postfix);
+ xspaces[indent], nhalf->name_uc, nhalf->name_lc, nhalf->name_ic,
+ xspaces[indent + 2], prefix, nhalf->kwname, postfix);
if (num != 1)
{
@@ -669,14 +670,14 @@ testname (bool nested, int indent, name first, name last)
"\
%selse if (c < 0)\n\
",
- spaces[indent]);
+ xspaces[indent]);
if (numhalf == 0)
fprintf (out,
"\
%s;\n\
",
- spaces[indent + 2]);
+ xspaces[indent + 2]);
else
testname (TRUE, indent + 4, first, nhalf->previous);
@@ -686,7 +687,7 @@ testname (bool nested, int indent, name first, name last)
"\
%selse\n\
",
- spaces[indent]);
+ xspaces[indent]);
testname (TRUE, indent + 4, nhalf->next, last);
}
@@ -697,7 +698,7 @@ testname (bool nested, int indent, name first, name last)
"\
%s}\n\
",
- spaces[indent - 2]);
+ xspaces[indent - 2]);
}
void
@@ -709,7 +710,7 @@ testnames (bool nested, int indent, int len, name first, name last)
int numhalf;
assert (!nested || indent >= 2);
- assert (((size_t) indent) + 4 < ARRAY_SIZE (spaces));
+ assert (((size_t) indent) + 4 < ARRAY_SIZE (xspaces));
num = 0;
numhalf = 0;
@@ -727,15 +728,15 @@ testnames (bool nested, int indent, int len, name first, name last)
"\
%s{\n\
",
- spaces[indent - 2]);
+ xspaces[indent - 2]);
fprintf (out,
"\
%sif ((c = ffesrc_strncmp_2c (ffe_case_match (), p, \"%s\", \"%s\", \"%s\", %d)) == 0)\n\
%sreturn %s%s%s;\n\
",
- spaces[indent], nhalf->name_uc, nhalf->name_lc, nhalf->name_ic,
- len, spaces[indent + 2], prefix, nhalf->kwname, postfix);
+ xspaces[indent], nhalf->name_uc, nhalf->name_lc, nhalf->name_ic,
+ len, xspaces[indent + 2], prefix, nhalf->kwname, postfix);
if (num != 1)
{
@@ -743,14 +744,14 @@ testnames (bool nested, int indent, int len, name first, name last)
"\
%selse if (c < 0)\n\
",
- spaces[indent]);
+ xspaces[indent]);
if (numhalf == 0)
fprintf (out,
"\
%s;\n\
",
- spaces[indent + 2]);
+ xspaces[indent + 2]);
else
testnames (TRUE, indent + 4, len, first, nhalf->previous);
@@ -760,7 +761,7 @@ testnames (bool nested, int indent, int len, name first, name last)
"\
%selse\n\
",
- spaces[indent]);
+ xspaces[indent]);
testnames (TRUE, indent + 4, len, nhalf->next, last);
}
@@ -771,5 +772,5 @@ testnames (bool nested, int indent, int len, name first, name last)
"\
%s}\n\
",
- spaces[indent - 2]);
+ xspaces[indent - 2]);
}
diff --git a/gcc/f/flags.j b/gcc/f/flags.j
index 5bf37928672..b12daeba195 100644
--- a/gcc/f/flags.j
+++ b/gcc/f/flags.j
@@ -1 +1,2 @@
Contributed by James Craig Burley (burley@gnu.org).
+ Contributed by James Craig Burley.
diff --git a/gcc/f/g77.1 b/gcc/f/g77.1
index d6a465b07ea..3f20af9fffd 100644
--- a/gcc/f/g77.1
+++ b/gcc/f/g77.1
@@ -1,7 +1,7 @@
.\" Copyright (c) 1995-1997 Free Software Foundation -*-Text-*-
.\" See section COPYING for conditions for redistribution
.\" FIXME: no info here on predefines. Should there be? extra for F77...
-.TH G77 1 "1998-09-01" "GNU Tools" "GNU Tools"
+.TH G77 1 "1999-02-14" "GNU Tools" "GNU Tools"
.de BP
.sp
.ti \-.2i
@@ -88,14 +88,18 @@ For complete documentation on GNU Fortran, type `\|\c
F77 source files use the suffix `\|\c
.B .f\c
-\&\|' or `\|\c
+\&\|', `\|\c
.B .for\c
+\&\|', or `\|\c
+.B .FOR\c
\&\|'; F77 files to be preprocessed by
.BR cpp ( 1 )
use the suffix `\|\c
.B .F\c
-\&\|' or `\|\c
+\&\|', `\|\c
.B .fpp\c
+\&\|', or `\|\c
+.B .FPP\c
\&\|'; Ratfor source files use the suffix `\|\c
.B .r\c
\&\|' (though
@@ -250,10 +254,14 @@ file.f Fortran source file
.br
file.for Fortran source file
.br
+file.FOR Fortran source file
+.br
file.F preprocessed Fortran source file
.br
file.fpp preprocessed Fortran source file
.br
+file.FPP preprocessed Fortran source file
+.br
file.r Ratfor source file (ratfor not included)
.br
file.s assembly language file
diff --git a/gcc/f/g77.texi b/gcc/f/g77.texi
index b799e6f7bb3..4775a3d6f91 100644
--- a/gcc/f/g77.texi
+++ b/gcc/f/g77.texi
@@ -1,25 +1,15 @@
\input texinfo @c -*-texinfo-*-
-@c fix @set inside @example:
-@tex
-\gdef\set{\begingroup\catcode` =10 \parsearg\setxxx}
-\gdef\setyyy#1 #2\endsetyyy{%
- \def\temp{#2}%
- \ifx\temp\empty \global\expandafter\let\csname SET#1\endcsname = \empty
- \else \setzzz{#1}#2\endsetzzz % Remove the trailing space \setxxx inserted.
- \fi
- \endgroup
-}
-@end tex
-
-@c %**start of header
+@c %**start of header
@setfilename g77.info
-@set last-up-date 1998-09-01
-@set version-g77 0.5.24
-@set email-general egcs@@cygnus.com
-@set email-bugs egcs-bugs@@cygnus.com
-@set path-g77 egcs/gcc/f
-@set path-libf2c egcs/libf2c
+@set last-update 1999-03-15
+@set copyrights-g77 1995-1999
+
+@include root.texi
+
+@c This tells @include'd files that they're part of the overall G77 doc
+@c set. (They might be part of a higher-level doc set too.)
+@set DOC-G77
@c @setfilename useg77.info
@c @setfilename portg77.info
@@ -34,9 +24,13 @@
@c and make sure the following does NOT begin with '@c':
@c @clear USING
-@c (For FSF printing, turn on smallbook; that is all that is needed.)
+@c 6/27/96 FSF DO wants smallbook fmt for 1st bound edition. (from gcc.texi)
+@c @smallbook
-@c smallbook
+@c i also commented out the finalout command, so if there *are* any
+@c overfulls, you'll (hopefully) see the rectangle in the right hand
+@c margin. -- burley 1999-03-13 (from mew's comment in gcc.texi).
+@c @finalout
@ifset INTERNALS
@ifset USING
@@ -49,7 +43,7 @@
@end ifclear
@ifclear USING
@settitle Porting GNU Fortran
-@end ifclear
+@end ifclear
@c then again, have some fun
@ifclear INTERNALS
@ifclear USING
@@ -60,16 +54,48 @@
@syncodeindex fn cp
@syncodeindex vr cp
@c %**end of header
-@setchapternewpage odd
+
+@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
@ifinfo
-This file explains how to use the GNU Fortran system.
+@dircategory Programming
+@direntry
+* g77: (g77). The GNU Fortran compiler.
+@end direntry
+@ifset INTERNALS
+@ifset USING
+This file documents the use and the internals of the GNU Fortran (@code{g77})
+compiler.
+It corresponds to the @value{which-g77} version of @code{g77}.
+@end ifset
+@end ifset
+@ifclear USING
+This file documents the internals of the GNU Fortran (@code{g77}) compiler.
+It corresponds to the @value{which-g77} version of @code{g77}.
+@end ifclear
+@ifclear INTERNALS
+This file documents the use of the GNU Fortran (@code{g77}) compiler.
+It corresponds to the @value{which-g77} version of @code{g77}.
+@end ifclear
Published by the Free Software Foundation
59 Temple Place - Suite 330
Boston, MA 02111-1307 USA
-Copyright (C) 1995-1997 Free Software Foundation, Inc.
+Copyright (C) @value{copyrights-g77} Free Software Foundation, Inc.
Permission is granted to make and distribute verbatim copies of
this manual provided the copyright notice and this permission notice
@@ -99,27 +125,36 @@ translations approved by the Free Software Foundation instead of in the
original English.
@end ifinfo
-Contributed by James Craig Burley (@email{burley@@gnu.org}).
+Contributed by James Craig Burley (@email{@value{email-burley}}).
Inspired by a first pass at translating @file{g77-0.5.16/f/DOC} that
was contributed to Craig by David Ronis (@email{ronis@@onsager.chem.mcgill.ca}).
-@finalout
+@setchapternewpage odd
+@c @finalout
@titlepage
-@comment The title is printed in a large font.
-@center @titlefont{Using GNU Fortran}
+@ifset INTERNALS
+@ifset USING
+@center @titlefont{Using and Porting GNU Fortran}
+
+@end ifset
+@end ifset
+@ifclear INTERNALS
+@title Using GNU Fortran
+@end ifclear
+@ifclear USING
+@title Porting GNU Fortran
+@end ifclear
@sp 2
@center James Craig Burley
@sp 3
-@center Last updated @value{last-up-date}
+@center Last updated @value{last-update}
@sp 1
-@c The version number appears some more times in this file.
-
@center for version @value{version-g77}
@page
@vskip 0pt plus 1filll
-Copyright @copyright{} 1995-1997 Free Software Foundation, Inc.
+Copyright @copyright{} @value{copyrights-g77} Free Software Foundation, Inc.
@sp 2
-For GNU Fortran Version @value{version-g77}*
+For the @value{which-g77} Version*
@sp 1
Published by the Free Software Foundation @*
59 Temple Place - Suite 330@*
@@ -152,34 +187,50 @@ original English.
@ifinfo
-@dircategory Programming
-@direntry
-* g77: (g77). The GNU Fortran compiler.
-@end direntry
@node Top, Copying,, (DIR)
@top Introduction
@cindex Introduction
@ifset INTERNALS
@ifset USING
-This manual documents how to run, install and port the GNU Fortran
-compiler, as well as its new features and incompatibilities, and how to
-report bugs. It corresponds to GNU Fortran version @value{version-g77}.
+This manual documents how to run, install and port @code{g77},
+as well as its new features and incompatibilities,
+and how to report bugs.
+It corresponds to the @value{which-g77} version of @code{g77}.
@end ifset
@end ifset
@ifclear INTERNALS
-This manual documents how to run and install the GNU Fortran compiler,
+This manual documents how to run and install @code{g77},
as well as its new features and incompatibilities, and how to report
-bugs. It corresponds to GNU Fortran version @value{version-g77}.
+bugs.
+It corresponds to the @value{which-g77} version of @code{g77}.
@end ifclear
@ifclear USING
-This manual documents how to port the GNU Fortran compiler,
-as well as its new features and incompatibilities, and how to report
-bugs. It corresponds to GNU Fortran version @value{version-g77}.
+This manual documents how to port @code{g77},
+as well as its new features and incompatibilities,
+and how to report bugs.
+It corresponds to the @value{which-g77} version of @code{g77}.
@end ifclear
@end ifinfo
+
+@ifset DEVELOPMENT
+@emph{Warning:} This document is still under development,
+and might not accurately reflect the @code{g77} code base
+of which it is a part.
+Efforts are made to keep it somewhat up-to-date,
+but they are particularly concentrated
+on any version of this information
+that is distributed as part of a @emph{released} @code{g77}.
+
+In particular, while this document is intended to apply to
+the @value{which-g77} version of @code{g77},
+only an official @emph{release} of that version
+is expected to contain documentation that is
+most consistent with the @code{g77} product in that version.
+@end ifset
+
@menu
* Copying:: GNU General Public License says
how you can copy and share GNU Fortran.
@@ -558,9 +609,9 @@ the ``copyright'' line and a pointer to where the full notice is found.
@var{one line to give the program's name and a brief idea of what it does.}
Copyright (C) 19@var{yy} @var{name of author}
-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
+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,
@@ -581,8 +632,8 @@ when it starts in an interactive mode:
@smallexample
Gnomovision version 69, Copyright (C) 19@var{yy} @var{name of author}
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details
-type `show w'.
-This is free software, and you are welcome to redistribute it
+type `show w'.
+This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
@end smallexample
@@ -775,7 +826,7 @@ without royalty; alteration is not permitted.
@cindex improvements, funding
Work on GNU Fortran is still being done mostly by its author,
-James Craig Burley (@email{burley@@gnu.org}), who is a volunteer
+James Craig Burley (@email{@value{email-burley}}), who is a volunteer
for, not an employee of, the Free Software Foundation (FSF).
As with other GNU software, funding is important because it can pay for
needed equipment, personnel, and so on.
@@ -829,7 +880,7 @@ Email @email{@value{email-general}} to volunteer for this work.
@node Look and Feel
@chapter Protect Your Freedom---Fight ``Look And Feel''
-@c the above chapter heading overflows onto the next line. --mew 1/26/93
+@c the above chapter heading overflows onto the next line. --mew 1/26/93
To preserve the ability to write free software, including replacements
for proprietary software, authors must be free to replicate the
@@ -863,7 +914,7 @@ Everyone except experienced @code{g77} users should
see @ref{Invoking G77}.
If you're acquainted with previous versions of @code{g77},
-you should see @ref{News}.
+you should see @ref{News,,News About GNU Fortran}.
Further, if you've actually used previous versions of @code{g77},
especially if you've written or modified Fortran code to
be compiled by previous versions of @code{g77}, you
@@ -957,8 +1008,8 @@ to make big mistakes.
@cindex debugger
@cindex bugs, finding
-@cindex gdb command
-@cindex commands, gdb
+@cindex @code{gdb}, command
+@cindex commands, @code{gdb}
@item
They provide information in the generated machine code
that can make it easier to find bugs in the program
@@ -967,8 +1018,8 @@ such as @code{gdb}).
@cindex libraries
@cindex linking
-@cindex ld command
-@cindex commands, ld
+@cindex @code{ld} command
+@cindex commands, @code{ld}
@item
They locate and gather machine code already generated
to perform actions requested by statements in
@@ -1027,11 +1078,11 @@ of the language), how much time to spend making
the generated machine code run faster, and so on.
@cindex components of g77
-@cindex g77, components of
+@cindex @code{g77}, components of
@code{g77} consists of several components:
-@cindex gcc command
-@cindex commands, gcc
+@cindex @code{gcc}, command
+@cindex commands, @code{gcc}
@itemize @bullet
@item
A modified version of the @code{gcc} command, which also might be
@@ -1042,8 +1093,8 @@ might be a non-GNU compiler, or an older version
of @code{gcc} considered more stable or that is
used to build the operating system kernel.)
-@cindex g77 command
-@cindex commands, g77
+@cindex @code{g77}, command
+@cindex commands, @code{g77}
@item
The @code{g77} command itself, which also might be installed as the
system's @code{f77} command.
@@ -1052,7 +1103,7 @@ system's @code{f77} command.
@cindex libf2c library
@cindex libraries, libf2c
@cindex libraries, libg2c
-@cindex run-time library
+@cindex run-time, library
@item
The @code{libg2c} run-time library.
This library contains the machine code needed to support
@@ -1070,11 +1121,11 @@ on the system.
The maintainer of @code{libf2c} currently is
@email{dmg@@bell-labs.com}.
-@cindex f771 program
-@cindex programs, f771
+@cindex @code{f771}, program
+@cindex programs, @code{f771}
@cindex assembler
-@cindex as command
-@cindex commands, as
+@cindex @code{as} command
+@cindex commands, @code{as}
@cindex assembly code
@cindex code, assembly
@item
@@ -1094,7 +1145,7 @@ preprocessing, compiling (in a variety of possible languages), assembling,
and linking.
@cindex driver, gcc command as
-@cindex gcc command as driver
+@cindex @code{gcc}, command as driver
@cindex executable file
@cindex files, executable
@cindex cc1 program
@@ -1115,14 +1166,14 @@ As another example, the command @samp{gcc foo.cc} would do much the same as
@samp{gcc foo.c}, but instead of using the C compiler named @code{cc1},
@code{gcc} would use the C++ compiler (named @code{cc1plus}).
-@cindex f771 program
-@cindex programs, f771
+@cindex @code{f771}, program
+@cindex programs, @code{f771}
In a GNU Fortran installation, @code{gcc} recognizes Fortran source
files by name just like it does C and C++ source files.
It knows to use the Fortran compiler named @code{f771}, instead of
@code{cc1} or @code{cc1plus}, to compile Fortran files.
-@cindex gcc not recognizing Fortran source
+@cindex @code{gcc}, not recognizing Fortran source
@cindex unrecognized file format
@cindex file format not recognized
Non-Fortran-related operation of @code{gcc} is generally
@@ -1132,8 +1183,8 @@ GNU Fortran version, @code{gcc} will not be able to compile
and link Fortran programs---and since @code{g77} uses @code{gcc}
to do most of the actual work, neither will @code{g77}!
-@cindex g77 command
-@cindex commands, g77
+@cindex @code{g77}, command
+@cindex commands, @code{g77}
The @code{g77} command is essentially just a front-end for
the @code{gcc} command.
Fortran users will normally use @code{g77} instead of @code{gcc},
@@ -1192,7 +1243,7 @@ large chunks of code.
@cindex GNU Back End (GBE)
@cindex GBE
-@cindex gcc back end
+@cindex @code{gcc}, back end
@cindex back end, gcc
@cindex code generator
One chunk is the so-called @dfn{GNU Back End}, or GBE,
@@ -1205,7 +1256,7 @@ whenever the distinction is important.
@cindex GNU Fortran Front End (FFE)
@cindex FFE
-@cindex g77 front end
+@cindex @code{g77}, front end
@cindex front end, g77
The other chunk of @code{f771} is the
majority of what is unique about GNU Fortran---the code that knows how
@@ -1236,8 +1287,8 @@ of generated code (in terms of speed and size) is roughly similar
@cindex compiling programs
@cindex programs, compiling
-@cindex gcc command
-@cindex commands, gcc
+@cindex @code{gcc}, command
+@cindex commands, @code{gcc}
A GNU Fortran installation includes a modified version of the @code{gcc}
command.
@@ -1253,8 +1304,8 @@ but apply to other languages as well.
for information on the way different languages are handled
by the GNU CC compiler (@code{gcc}).
-@cindex g77 command
-@cindex commands, g77
+@cindex @code{g77}, command
+@cindex commands, @code{g77}
Also provided as part of GNU Fortran is the @code{g77} command.
The @code{g77} command is designed to make compiling and linking Fortran
programs somewhat easier than when using the @code{gcc} command for
@@ -1263,7 +1314,7 @@ It does this by analyzing the command line somewhat and changing it
appropriately before submitting it to the @code{gcc} command.
@cindex -v option
-@cindex g77 options, -v
+@cindex @code{g77} options, -v
@cindex options, -v
Use the @samp{-v} option with @code{g77}
to see what is going on---the first line of output is the invocation
@@ -1464,13 +1515,21 @@ Suffixes specific to GNU Fortran are listed below.
information on suffixes recognized by GNU CC.
@table @code
+@cindex .f filename suffix
+@cindex .for filename suffix
+@cindex .FOR filename suffix
@item @var{file}.f
@item @var{file}.for
+@item @var{file}.FOR
Fortran source code that should not be preprocessed.
Such source code cannot contain any preprocessor directives, such
as @code{#include}, @code{#define}, @code{#if}, and so on.
+You can force @samp{.f} files to be preprocessed by @samp{cpp} by using
+@samp{-x f77-cpp-input}.
+@xref{LEX}.
+
@cindex preprocessor
@cindex C preprocessor
@cindex cpp preprocessor
@@ -1479,8 +1538,10 @@ as @code{#include}, @code{#define}, @code{#if}, and so on.
@cindex programs, cpp
@cindex .F filename suffix
@cindex .fpp filename suffix
+@cindex .FPP filename suffix
@item @var{file}.F
@item @var{file}.fpp
+@item @var{file}.FPP
Fortran source code that must be preprocessed (by the C preprocessor
@code{cpp}, which is part of GNU CC).
@@ -1489,12 +1550,17 @@ files included by the @code{INCLUDE} directive---the @code{#include}
preprocessor directive must be used instead.
@cindex Ratfor preprocessor
-@cindex programs, ratfor
-@cindex .r filename suffix
+@cindex programs, @code{ratfor}
+@cindex @samp{.r} filename suffix
+@cindex @code{ratfor}
@item @var{file}.r
Ratfor source code, which must be preprocessed by the @code{ratfor}
-command, which is available separately (as it is not yet part of
-the GNU Fortran distribution).
+command, which is available separately (as it is not yet part of the GNU
+Fortran distribution).
+One version in Fortran, adapted for use with @code{g77}, is at
+@uref{ftp://members.aol.com/n8tm/rat7.uue} (of uncertain copyright
+status). Another, public domain version in C is at
+@uref{http://sepwww.stanford.edu/sep/prof/ratfor.shar.2}.
@end table
UNIX users typically use the @file{@var{file}.f} and @file{@var{file}.F}
@@ -1606,10 +1672,10 @@ with a diagnostic if it detects an inconsistency.
@cindex -fno-silent option
@cindex options, -fno-silent
-@cindex @code{f2c} compatibility
-@cindex compatibility, @code{f2c}
+@cindex f2c compatibility
+@cindex compatibility, f2c
@cindex status, compilation
-@cindex compilation status
+@cindex compilation, status
@cindex reporting compilation status
@cindex printing compilation status
@item -fno-silent
@@ -1696,10 +1762,10 @@ existing and obsolete Fortran implementations.
@cindex options, -ff77
@item -ff77
@cindex UNIX f77
-@cindex @code{f2c} compatibility
-@cindex compatibility, @code{f2c}
-@cindex @code{f77} compatibility
-@cindex compatibility, @code{f77}
+@cindex f2c compatibility
+@cindex compatibility, f2c
+@cindex f77 compatibility
+@cindex compatibility, f77
Specify that the program is written in idiomatic UNIX FORTRAN 77
and/or the dialect accepted by the @code{f2c} product.
Same as @samp{-fbackslash -fno-typeless-boz}.
@@ -1726,7 +1792,7 @@ existing and obsolete Fortran implementations.
@node Fortran Dialect Options
@section Options Controlling Fortran Dialect
@cindex dialect options
-@cindex language dialect options
+@cindex language, dialect options
@cindex options, dialect
The following options control the dialect of Fortran
@@ -1737,10 +1803,10 @@ that the compiler accepts:
@cindex options, -ffree-form
@cindex -fno-fixed-form option
@cindex options, -fno-fixed-form
-@cindex source file form
+@cindex source file format
@cindex free form
@cindex fixed form
-@cindex Fortran 90 features
+@cindex Fortran 90, features
@item -ffree-form
@item -fno-fixed-form
Specify that the source file is written in free form
@@ -1748,7 +1814,7 @@ Specify that the source file is written in free form
@cindex -ff90 option
@cindex options, -ff90
-@cindex Fortran 90 features
+@cindex Fortran 90, features
@item -ff90
Allow certain Fortran-90 constructs.
@@ -1764,8 +1830,8 @@ current level of support for Fortran 90.)
@cindex -fvxt option
@cindex options, -fvxt
@item -fvxt
-@cindex Fortran 90 features
-@cindex VXT features
+@cindex Fortran 90, features
+@cindex VXT extensions
Specify the treatment of certain constructs that have different
meanings depending on whether the code is written in
GNU Fortran (based on FORTRAN 77 and akin to Fortran 90)
@@ -1905,14 +1971,16 @@ For example, automatic conversion between @code{INTEGER} and
@cindex options, -fonetrip
@item -fonetrip
@cindex FORTRAN 66
-@cindex DO loops, one-trip
-@cindex one-trip DO loops
+@cindex @code{DO} loops, one-trip
+@cindex one-trip @code{DO} loops
+@cindex @code{DO} loops, zero-trip
+@cindex zero-trip @code{DO} loops
@cindex compatibility, FORTRAN 66
-Imperative executable @code{DO} loops are to be executed at
+Executable iterative @code{DO} loops are to be executed at
least once each time they are reached.
ANSI FORTRAN 77 and more recent versions of the Fortran standard
-specify that the body of an imperative @code{DO} loop is not executed
+specify that the body of an iterative @code{DO} loop is not executed
if the number of iterations calculated from the parameters of the
loop is less than 1.
(For example, @samp{DO 10 I = 1, 0}.)
@@ -1930,7 +1998,7 @@ standard did not specify this behavior.
The @samp{-fonetrip} option specifies that the source file(s) being
compiled require one-trip loops.
-This option affects only those loops specified by the (imperative) @code{DO}
+This option affects only those loops specified by the (iterative) @code{DO}
statement and by implied-@code{DO} lists in I/O statements.
Loops specified by implied-@code{DO} lists in @code{DATA} and
specification (non-executable) statements are not affected.
@@ -2079,8 +2147,8 @@ variables named @samp{i} and @samp{I} to a procedure named @samp{Foo}.)
@cindex -fbadu77-intrinsics-enable option
@cindex options, -fbadu77-intrinsics-enable
@item -fbadu77-intrinsics-enable
-@cindex badu77 intrinsics
-@cindex intrinsics, badu77
+@cindex @code{badu77} intrinsics
+@cindex intrinsics, @code{badu77}
Specify status of UNIX intrinsics having inappropriate forms.
@samp{-fbadu77-intrinsics-enable} is the default.
@xref{Intrinsic Groups}.
@@ -2097,8 +2165,8 @@ Specify status of UNIX intrinsics having inappropriate forms.
@cindex -ff2c-intrinsics-enable option
@cindex options, -ff2c-intrinsics-enable
@item -ff2c-intrinsics-enable
-@cindex f2c intrinsics
-@cindex intrinsics, f2c
+@cindex @code{f2c} intrinsics
+@cindex intrinsics, @code{f2c}
Specify status of f2c-specific intrinsics.
@samp{-ff2c-intrinsics-enable} is the default.
@xref{Intrinsic Groups}.
@@ -2115,7 +2183,7 @@ Specify status of f2c-specific intrinsics.
@cindex -ff90-intrinsics-enable option
@cindex options, -ff90-intrinsics-enable
@item -ff90-intrinsics-enable
-@cindex Fortran 90 intrinsics
+@cindex Fortran 90, intrinsics
@cindex intrinsics, Fortran 90
Specify status of F90-specific intrinsics.
@samp{-ff90-intrinsics-enable} is the default.
@@ -2134,8 +2202,8 @@ Specify status of F90-specific intrinsics.
@cindex options, -fgnu-intrinsics-enable
@item -fgnu-intrinsics-enable
@cindex Digital Fortran features
-@cindex COMPLEX intrinsics
-@cindex intrinsics, COMPLEX
+@cindex @code{COMPLEX} intrinsics
+@cindex intrinsics, @code{COMPLEX}
Specify status of Digital's COMPLEX-related intrinsics.
@samp{-fgnu-intrinsics-enable} is the default.
@xref{Intrinsic Groups}.
@@ -2198,9 +2266,10 @@ Specify status of VXT intrinsics.
@cindex options, -ffixed-line-length-@var{n}
@item -ffixed-line-length-@var{n}
@cindex source file format
-@cindex line length
+@cindex lines, length
@cindex length of source lines
-@cindex fixed-form line length
+@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.
@@ -2221,8 +2290,8 @@ to them to fill out the line.
@node Warning Options
@section Options to Request or Suppress Warnings
-@cindex options to control warnings
-@cindex warning messages
+@cindex options, warnings
+@cindex warnings, suppressing
@cindex messages, warning
@cindex suppressing warnings
@@ -2396,12 +2465,12 @@ use, on occasion, in clean programs.
@table @code
@c @item -W
@c Print extra warning messages for these events:
-@c
+@c
@c @itemize @bullet
@c @item
@c If @samp{-Wall} or @samp{-Wunused} is also specified, warn about unused
@c arguments.
-@c
+@c
@c @end itemize
@c
@cindex -Wsurprising option
@@ -2645,16 +2714,16 @@ is @samp{-mno-align-double}, not @samp{-benign-double}.
@cindex -ffloat-store option
@cindex options, -ffloat-store
@item -ffloat-store
-@cindex IEEE conformance
-@cindex conformance, IEEE
-@cindex floating point precision
+@cindex IEEE 754 conformance
+@cindex conformance, IEEE 754
+@cindex floating-point, precision
Might help a Fortran program that depends on exact IEEE conformance on
some machines, but might slow down a program that doesn't.
-This option is effective when the floating point unit is set to work in
+This option is effective when the floating-point unit is set to work in
IEEE 854 `extended precision'---as it typically is on x86 and m68k GNU
systems---rather than IEEE 754 double precision. @code{-ffloat-store}
-tries to remove the extra precision by spilling data from floating point
+tries to remove the extra precision by spilling data from floating-point
registers into memory and this typically involves a big performance
hit. However, it doesn't affect intermediate results, so that it is
only partially effective. `Excess precision' is avoided in code like:
@@ -2667,8 +2736,8 @@ but not in code like:
d = (b + c) * e
@end smallexample
-@xref{Floating point precision} for another, potentially better way of
-controlling the precision.
+For another, potentially better, way of controlling the precision,
+see @ref{Floating-point precision}.
@cindex -fforce-mem option
@cindex options, -fforce-mem
@@ -2677,13 +2746,13 @@ controlling the precision.
@cindex options, -fforce-addr
@item -fforce-addr
@cindex loops, speeding up
-@cindex speeding up loops
+@cindex speed, of loops
Might improve optimization of loops.
@cindex -fno-inline option
@cindex options, -fno-inline
@item -fno-inline
-@cindex in-line compilation
+@cindex in-line code
@cindex compilation, in-line
@c DL: Only relevant for -O3?
Don't compile statement functions inline.
@@ -2694,8 +2763,8 @@ Note that if you are not optimizing, no functions can be expanded inline.
@cindex -ffast-math option
@cindex options, -ffast-math
@item -ffast-math
-@cindex IEEE conformance
-@cindex conformance, IEEE
+@cindex IEEE 754 conformance
+@cindex conformance, IEEE 754
Might allow some programs designed to not be too dependent
on IEEE behavior for floating-point to run faster, or die trying.
@@ -2703,7 +2772,7 @@ on IEEE behavior for floating-point to run faster, or die trying.
@cindex options, -fstrength-reduce
@item -fstrength-reduce
@cindex loops, speeding up
-@cindex speeding up loops
+@cindex speed, of loops
@c DL: normally defaulted?
Might make some loops run faster.
@@ -2733,14 +2802,19 @@ Might improve performance on some code.
@item -funroll-loops
@cindex loops, unrolling
@cindex unrolling loops
-@cindex loop optimization
+@cindex loops, optimizing
+@cindex indexed (iterative) @code{DO}
+@cindex iterative @code{DO}
@c DL: fixme: Craig doesn't like `indexed' but f95 doesn't seem to
@c provide a suitable term
-Typically improves performance on code using indexed @code{DO} loops by
+@c CB: I've decided on `iterative', for the time being, and changed
+@c my previous, rather bizarre, use of `imperative' to that
+@c (though `precomputed-trip' would be a more precise adjective)
+Typically improves performance on code using iterative @code{DO} loops by
unrolling them and is probably generally appropriate for Fortran, though
-it is not turned on at any optimization level.
+it is not turned on at any optimization level.
Note that outer loop unrolling isn't done specifically; decisions about
-whether to unroll a loop are made on the basis of its instruction count.
+whether to unroll a loop are made on the basis of its instruction count.
@c DL: Fixme: This should obviously go somewhere else...
Also, no `loop discovery'@footnote{@dfn{loop discovery} refers to the
@@ -2756,17 +2830,17 @@ constructed out of lower-level constructs (such as @code{IF} and
@code{GOTO}) can lead to generation of more optimal code
than otherwise.} is done, so only loops written with @code{DO}
benefit from loop optimizations, including---but not limited
-to---unrolling. Loops written with @code{IF} and @code{GOTO} will not
-be recognized as such. This option only unrolls indexed @code{DO}
-loops, not @code{DO WHILE} loops.
+to---unrolling. Loops written with @code{IF} and @code{GOTO} are not
+currently recognized as such. This option unrolls only iterative
+@code{DO} loops, not @code{DO WHILE} loops.
@cindex -funroll-all-loops option
@cindex options, -funroll-all-loops
-@cindex @code{DO WHILE}
+@cindex DO WHILE
@item -funroll-all-loops
@c DL: Check my understanding of -funroll-all-loops v. -funroll-loops is correct.
Probably improves performance on code using @code{DO WHILE} loops by
-unrolling them in addition to indexed @code{DO} loops. In the absence
+unrolling them in addition to iterative @code{DO} loops. In the absence
of @code{DO WHILE}, this option is equivalent to @code{-funroll-loops}
but possibly slower.
@@ -2840,7 +2914,7 @@ contains preprocessor directives.
@node Directory Options
@section Options for Directory Search
-@cindex directory options
+@cindex directory, options
@cindex options, directory search
@cindex search path
@@ -2864,9 +2938,10 @@ These options are:
@cindex -Idir option
@cindex options, -Idir
@item -I@var{dir}
-@cindex directory search paths for inclusion
+@cindex directory, search paths for inclusion
@cindex inclusion, directory search paths for
-@cindex searching for included files
+@cindex search paths, for included files
+@cindex paths, search
These affect interpretation of the @code{INCLUDE} directive
(as well as of the @code{#include} directive of the @code{cpp}
preprocessor).
@@ -2888,9 +2963,9 @@ gcc,Using and Porting GNU CC}, for information on the @samp{-I} option.
@node Code Gen Options
@section Options for Code Generation Conventions
-@cindex code generation conventions
-@cindex options, code generation
-@cindex run-time options
+@cindex code generation, conventions
+@cindex options, code generation
+@cindex run-time, options
These machine-independent options control the interface conventions
used in code generation.
@@ -2918,7 +2993,7 @@ the name @samp{-static}.)
@item -finit-local-zero
@cindex DATA statement
@cindex statements, DATA
-@cindex initialization of local variables
+@cindex initialization, of local variables
@cindex variables, initialization of
@cindex uninitialized variables
@cindex variables, uninitialized
@@ -2992,7 +3067,7 @@ generating code for an incompatible library.
@cindex -fno-underscoring option
@cindex options, -fno-underscoring
@item -fno-underscoring
-@cindex underscores
+@cindex underscore
@cindex symbol names, underscores
@cindex transforming symbol names
@cindex symbol names, transforming
@@ -3067,7 +3142,7 @@ interfaces.
@cindex -fno-second-underscore option
@cindex options, -fno-second-underscore
@item -fno-second-underscore
-@cindex underscores
+@cindex underscore
@cindex symbol names, underscores
@cindex transforming symbol names
@cindex symbol names, transforming
@@ -3167,7 +3242,7 @@ $6 = "At (EQUIVALENCE) `__g77_equiv_xx' plus 20 bytes"
(gdb) p xx
$7 = "At (EQUIVALENCE) `__g77_equiv_xx' plus 1 bytes"
(gdb) set language fortran
-(gdb)
+(gdb)
@end smallexample
@noindent
@@ -3258,6 +3333,8 @@ arguments.
@item -fno-globals
@cindex global names, warning
@cindex warnings, global names
+@cindex in-line code
+@cindex compilation, in-line
Disable diagnostics about inter-procedural
analysis problems, such as disagreements about the
type of a function or a procedure's argument,
@@ -3274,9 +3351,8 @@ code that would otherwise be diagnosed.
As such, this option might be quite useful when
compiling existing, ``working'' code that happens
-to have a few bugs that do not generally show
-themselves, but @code{g77} exposes via a
-diagnostic.
+to have a few bugs that do not generally show themselves,
+but which @code{g77} diagnoses.
Use of this option therefore has the effect of
instructing @code{g77} to behave more like it did
@@ -3290,7 +3366,11 @@ Without this option, @code{g77} defaults to performing
the potentially inlining procedures as it started doing
in version 0.5.20, but as of version 0.5.21, it also
diagnoses disagreements that might cause such inlining
-to crash the compiler.
+to crash the compiler as (fatal) errors,
+and warns about similar disagreements
+that are currently believed to not
+likely to result in the compiler later crashing
+or producing incorrect code.
@end table
@xref{Code Gen Options,,Options for Code Generation Conventions,
@@ -3345,798 +3425,9 @@ variables.
@include news.texi
-@node Changes
-@chapter User-visible Changes
-@cindex versions, recent
-@cindex recent versions
-@cindex changes, user-visible
-@cindex user-visible changes
-
-This section describes changes to @code{g77} that are visible
-to the programmers who actually write and maintain Fortran
-code they compile with @code{g77}.
-Information on changes to installation procedures,
-changes to the documentation, and bug fixes is
-not provided here, unless it is likely to affect how
-users use @code{g77}.
-@xref{News,,News About GNU Fortran}, for information on
-such changes to @code{g77}.
-
-To find out about existing bugs and ongoing plans for GNU
-Fortran, retrieve @uref{ftp://alpha.gnu.org/g77.plan}
-or, if you cannot do that, email
-@email{fortran@@gnu.org} asking for a recent copy of the
-GNU Fortran @file{.plan} file.
-
-@heading In @code{egcs} 1.1 (versus 0.5.24):
-@itemize @bullet
-@cindex alignment
-@cindex double-precision performance
-@cindex -malign-double
-@item
-Align static double-precision variables and arrays
-on Intel x86 targets
-regardless of whether @samp{-malign-double} is specified.
-
-Generally, this affects only local variables and arrays
-having the @code{SAVE} attribute
-or given initial values via @code{DATA}.
-@end itemize
-
-@heading In @code{egcs} 1.1 (versus @code{egcs} 1.0.3):
-@itemize @bullet
-@item
-Support @samp{FORMAT(I<@var{expr}>)} when @var{expr} is a
-compile-time constant @code{INTEGER} expression.
-
-@item
-Fix @code{g77} @samp{-g} option so procedures that
-use @samp{ENTRY} can be stepped through, line by line,
-in @code{gdb}.
-
-@item
-Allow any @code{REAL} argument to intrinsics
-@code{Second} and @code{CPU_Time}.
-
-@item
-Use @code{tempnam}, if available, to open scratch files
-(as in @samp{OPEN(STATUS='SCRATCH')})
-so that the @code{TMPDIR} environment variable,
-if present, is used.
-
-@item
-@code{g77}'s version of @code{libf2c} separates out
-the setting of global state
-(such as command-line arguments and signal handling)
-from @file{main.o} into distinct, new library
-archive members.
-
-This should make it easier to write portable applications
-that have their own (non-Fortran) @code{main()} routine
-properly set up the @code{libf2c} environment, even
-when @code{libf2c} (now @code{libg2c}) is a shared library.
-
-@item
-The @code{g77} command now expects the run-time library
-to be named @code{libg2c.a} instead of @code{libf2c.a},
-to ensure that a version other than the one built and
-installed as part of the same @code{g77} version is picked up.
-
-@item
-Some diagnostics have been changed from warnings to errors,
-to prevent inadvertent use of the resulting, probably buggy,
-programs.
-These mostly include diagnostics about use of unsupported features
-in the @code{OPEN}, @code{INQUIRE}, @code{READ}, and
-@code{WRITE} statements,
-and about truncations of various sorts of constants.
-@end itemize
-
-@heading In 0.5.24 and @code{egcs} 1.1 (versus 0.5.23):
-@itemize @bullet
-@item
-@code{g77} now treats @samp{%LOC(@var{expr})} and
-@samp{LOC(@var{expr})} as ``ordinary'' expressions
-when they are used as arguments in procedure calls.
-This change applies only to global (filewide) analysis,
-making it consistent with
-how @code{g77} actually generates code
-for these cases.
-
-Previously, @code{g77} treated these expressions
-as denoting special ``pointer'' arguments
-for the purposes of filewide analysis.
-
-@item
-The @code{g77} driver now ensures that @samp{-lg2c}
-is specified in the link phase prior to any
-occurrence of @samp{-lm}.
-This prevents accidentally linking to a routine
-in the SunOS4 @samp{-lm} library
-when the generated code wants to link to the one
-in @code{libf2c} (@code{libg2c}).
-
-@item
-@code{g77} emits more debugging information when
-@samp{-g} is used.
-
-This new information allows, for example,
-@kbd{which __g77_length_a} to be used in @code{gdb}
-to determine the type of the phantom length argument
-supplied with @samp{CHARACTER} variables.
-
-This information pertains to internally-generated
-type, variable, and other information,
-not to the longstanding deficiencies vis-a-vis
-@samp{COMMON} and @samp{EQUIVALENCE}.
-
-@item
-The F90 @samp{Date_and_Time} intrinsic now is
-supported.
-
-@item
-The F90 @samp{System_Clock} intrinsic allows
-the optional arguments (except for the @samp{Count}
-argument) to be omitted.
-@end itemize
-
-@heading In 0.5.23:
-@itemize @bullet
-@item
-This release contains several regressions against
-version 0.5.22 of @code{g77}, due to using the
-``vanilla'' @code{gcc} back end instead of patching
-it to fix a few bugs and improve performance in a
-few cases.
-
-@xref{Actual Bugs,,Actual Bugs We Haven't Fixed Yet},
-available in plain-text format in @code{gcc/f/BUGS},
-for information on the known bugs in this version,
-including the regressions.
-
-Features that have been dropped from this version
-of @code{g77} due to their being implemented
-via @code{g77}-specific patches to the @code{gcc}
-back end in previous releases include:
-
-@itemize --
-@item
-Support for @code{__restrict__} keyword,
-the options @samp{-fargument-alias}, @samp{-fargument-noalias},
-and @samp{-fargument-noalias-global},
-and the corresponding alias-analysis code.
-
-(@code{egcs} has the alias-analysis
-code, but not the @code{__restrict__} keyword.
-@code{egcs} @code{g77} users benefit from the alias-analysis
-code despite the lack of the @code{__restrict__} keyword,
-which is a C-language construct.)
-
-@item
-Support for the GNU compiler options
-@samp{-fmove-all-movables},
-@samp{-freduce-all-givs},
-and @samp{-frerun-loop-opt}.
-
-(@code{egcs} supports these options.
-@code{g77} users of @code{egcs} benefit from them even if
-they are not explicitly specified,
-because the defaults are optimized for @code{g77} users.)
-
-@item
-Support for the @samp{-W} option warning about
-integer division by zero.
-
-@item
-The Intel x86-specific option @samp{-malign-double}
-applying to stack-allocated data
-as well as statically-allocate data.
-@end itemize
-
-@item
-Support @code{gcc} version 2.8,
-and remove support for prior versions of @code{gcc}.
-
-@cindex -@w{}-driver option
-@cindex g77 options, -@w{}-driver
-@cindex options, -@w{}-driver
-@item
-Remove support for the @samp{--driver} option,
-as @code{g77} now does all the driving,
-just like @code{gcc}.
-
-@item
-The @code{g77} command now expects the run-time library
-to be named @code{libg2c.a} instead of @code{libf2c.a},
-to ensure that a version other than the one built and
-installed as part of the same @code{g77} version is picked up.
-
-@item
-@code{g77}'s version of @code{libf2c} separates out
-the setting of global state
-(such as command-line arguments and signal handling)
-from @file{main.o} into distinct, new library
-archive members.
-
-This should make it easier to write portable applications
-that have their own (non-Fortran) @code{main()} routine
-properly set up the @code{libf2c} environment, even
-when @code{libf2c} (now @code{libg2c}) is a shared library.
-
-@item
-Some diagnostics have been changed from warnings to errors,
-to prevent inadvertent use of the resulting, probably buggy,
-programs.
-These mostly include diagnostics about use of unsupported features
-in the @code{OPEN}, @code{INQUIRE}, @code{READ}, and
-@code{WRITE} statements,
-and about truncations of various sorts of constants.
-@end itemize
-
-@heading In 0.5.22:
-@itemize @bullet
-@item
-Fix @code{Signal} intrinsic so it offers portable
-support for 64-bit systems (such as Digital Alphas
-running GNU/Linux).
-
-@item
-Support @samp{FORMAT(I<@var{expr}>)} when @var{expr} is a
-compile-time constant @code{INTEGER} expression.
-
-@item
-Fix @code{g77} @samp{-g} option so procedures that
-use @samp{ENTRY} can be stepped through, line by line,
-in @code{gdb}.
-
-@item
-Allow any @code{REAL} argument to intrinsics
-@code{Second} and @code{CPU_Time}.
-
-@item
-Allow any numeric argument to intrinsics
-@code{Int2} and @code{Int8}.
-
-@item
-Use @code{tempnam}, if available, to open scratch files
-(as in @samp{OPEN(STATUS='SCRATCH')})
-so that the @code{TMPDIR} environment variable,
-if present, is used.
-
-@item
-Rename the @code{gcc} keyword @code{restrict} to
-@code{__restrict__}, to avoid rejecting valid, existing,
-C programs.
-Support for @code{restrict} is now more like support
-for @code{complex}.
-
-@item
-Fix @samp{-fugly-comma} to affect invocations of
-only external procedures.
-Restore rejection of gratuitous trailing omitted
-arguments to intrinsics, as in @samp{I=MAX(3,4,,)}.
-
-@item
-Fix compiler so it accepts @samp{-fgnu-intrinsics-*} and
-@samp{-fbadu77-intrinsics-*} options.
-@end itemize
-
-@heading In @code{egcs} 1.0.2 (versus @code{egcs} 1.0.1):
-@itemize @bullet
-@item
-Fix compiler so it accepts @samp{-fgnu-intrinsics-*} and
-@samp{-fbadu77-intrinsics-*} options.
-@end itemize
-
-@heading In @code{egcs} 1.0 (versus 0.5.21):
-@itemize @bullet
-@item
-Version 1.0 of @code{egcs}
-contains several regressions against
-version 0.5.21 of @code{g77},
-due to using the
-``vanilla'' @code{gcc} back end instead of patching
-it to fix a few bugs and improve performance in a
-few cases.
-
-@xref{Actual Bugs,,Actual Bugs We Haven't Fixed Yet},
-available in plain-text format in @code{gcc/f/BUGS},
-for information on the known bugs in this version,
-including the regressions.
-
-Features that have been dropped from this version
-of @code{g77} due to their being implemented
-via @code{g77}-specific patches to the @code{gcc}
-back end in previous releases include:
-
-@itemize --
-@item
-Support for the C-language @code{restrict} keyword.
-
-@item
-Support for the @samp{-W} option warning about
-integer division by zero.
-
-@item
-The Intel x86-specific option @samp{-malign-double}
-applying to stack-allocated data
-as well as statically-allocate data.
-@end itemize
-
-@cindex -@w{}-driver option
-@cindex g77 options, -@w{}-driver
-@cindex options, -@w{}-driver
-@item
-Remove support for the @samp{--driver} option,
-as @code{g77} now does all the driving,
-just like @code{gcc}.
-
-@item
-Allow any numeric argument to intrinsics
-@code{Int2} and @code{Int8}.
-@end itemize
-
-@heading In 0.5.21:
-@itemize @bullet
-@item
-When the @samp{-W} option is specified, @code{gcc}, @code{g77},
-and other GNU compilers that incorporate the @code{gcc}
-back end as modified by @code{g77}, issue
-a warning about integer division by constant zero.
-
-@item
-New option @samp{-Wno-globals} disables warnings
-about ``suspicious'' use of a name both as a global
-name and as the implicit name of an intrinsic, and
-warnings about disagreements over the number or natures of
-arguments passed to global procedures, or the
-natures of the procedures themselves.
-
-The default is to issue such warnings, which are
-new as of this version of @code{g77}.
-
-@item
-New option @samp{-fno-globals} disables diagnostics
-about potentially fatal disagreements
-analysis problems, such as disagreements over the
-number or natures of arguments passed to global
-procedures, or the natures of those procedures themselves.
-
-The default is to issue such diagnostics and flag
-the compilation as unsuccessful.
-With this option, the diagnostics are issued as
-warnings, or, if @samp{-Wno-globals} is specified,
-are not issued at all.
-
-This option also disables inlining of global procedures,
-to avoid compiler crashes resulting from coding errors
-that these diagnostics normally would identify.
-
-@item
-Fix @code{libU77} routines that accept file and other names
-to strip trailing blanks from them, for consistency
-with other implementations.
-Blanks may be forcibly appended to such names by
-appending a single null character (@samp{CHAR(0)})
-to the significant trailing blanks.
-
-@item
-Fix @code{CHMOD} intrinsic to work with file names
-that have embedded blanks, commas, and so on.
-
-@item
-Fix @code{SIGNAL} intrinsic so it accepts an
-optional third @samp{Status} argument.
-
-@item
-Make many changes to @code{libU77} intrinsics to
-support existing code more directly.
-
-Such changes include allowing both subroutine and
-function forms of many routines, changing @code{MCLOCK()}
-and @code{TIME()} to return @code{INTEGER(KIND=1)} values,
-introducing @code{MCLOCK8()} and @code{TIME8()} to
-return @code{INTEGER(KIND=2)} values,
-and placing functions that are intended to perform
-side effects in a new intrinsic group, @code{badu77}.
-
-@item
-Add options @samp{-fbadu77-intrinsics-delete},
-@samp{-fbadu77-intrinsics-hide}, and so on.
-
-@item
-Add @code{INT2} and @code{INT8} intrinsics.
-
-@item
-Add @code{CPU_TIME} intrinsic.
-
-@item
-Add @code{ALARM} intrinsic.
-
-@item
-@code{CTIME} intrinsic now accepts any @code{INTEGER}
-argument, not just @code{INTEGER(KIND=2)}.
-
-@item
-@code{g77} driver now prints version information (such as produced
-by @kbd{g77 -v}) to @code{stderr} instead of @code{stdout}.
-
-@item
-The @samp{.r} suffix now designates a Ratfor source file,
-to be preprocessed via the @code{ratfor} command, available
-separately.
-@end itemize
-
-@heading In 0.5.20:
-@itemize @bullet
-@item
-The @samp{-fno-typeless-boz} option is now the default.
-
-This option specifies that non-decimal-radix
-constants using the prefixed-radix form (such as @samp{Z'1234'})
-are to be interpreted as @code{INTEGER(KIND=1)} constants.
-Specify @samp{-ftypeless-boz} to cause such
-constants to be interpreted as typeless.
-
-(Version 0.5.19 introduced @samp{-fno-typeless-boz} and
-its inverse.)
-
-@xref{Fortran Dialect Options,,Options Controlling Fortran Dialect},
-for information on the @samp{-ftypeless-boz} option.
-
-@item
-Options @samp{-ff90-intrinsics-enable} and
-@samp{-fvxt-intrinsics-enable} now are the
-defaults.
-
-Some programs might use names that clash with
-intrinsic names defined (and now enabled) by these
-options or by the new @code{libU77} intrinsics.
-Users of such programs might need to compile them
-differently (using, for example, @samp{-ff90-intrinsics-disable})
-or, better yet, insert appropriate @code{EXTERNAL}
-statements specifying that these names are not intended
-to be names of intrinsics.
-
-@item
-The @samp{ALWAYS_FLUSH} macro is no longer defined when
-building @code{libf2c}, which should result in improved
-I/O performance, especially over NFS.
-
-@emph{Note:} If you have code that depends on the behavior
-of @code{libf2c} when built with @samp{ALWAYS_FLUSH} defined,
-you will have to modify @code{libf2c} accordingly before
-building it from this and future versions of @code{g77}.
-
-@xref{Output Assumed To Flush}, for more information.
-
-@item
-Dave Love's implementation of @code{libU77} has been
-added to the version of @code{libf2c} distributed with
-and built as part of @code{g77}.
-@code{g77} now knows about the routines in this library
-as intrinsics.
-
-@item
-New option @samp{-fvxt} specifies that the
-source file is written in VXT Fortran, instead of GNU Fortran.
-
-@xref{VXT Fortran}, for more information on the constructs
-recognized when the @samp{-fvxt} option is specified.
-
-@item
-The @samp{-fvxt-not-f90} option has been deleted,
-along with its inverse, @samp{-ff90-not-vxt}.
-
-If you used one of these deleted options, you should
-re-read the pertinent documentation to determine which
-options, if any, are appropriate for compiling your
-code with this version of @code{g77}.
-
-@xref{Other Dialects}, for more information.
-
-@item
-The @samp{-fugly} option now issues a warning, as it
-likely will be removed in a future version.
-
-(Enabling all the @samp{-fugly-*} options is unlikely
-to be feasible, or sensible, in the future,
-so users should learn to specify only those
-@samp{-fugly-*} options they really need for a
-particular source file.)
-
-@item
-The @samp{-fugly-assumed} option, introduced in
-version 0.5.19, has been changed to
-better accommodate old and new code.
-@xref{Ugly Assumed-Size Arrays}, for more information.
-
-@item
-Related to supporting Alpha (AXP) machines, the @code{LOC()}
-intrinsic and @code{%LOC()} construct now return
-values of @code{INTEGER(KIND=0)} type,
-as defined by the GNU Fortran language.
-
-This type is wide enough
-(holds the same number of bits)
-as the character-pointer type on the machine.
-
-On most machines, this won't make a difference,
-whereas, on Alphas and other systems with 64-bit pointers,
-the @code{INTEGER(KIND=0)} type is equivalent to @code{INTEGER(KIND=2)}
-(often referred to as @code{INTEGER*8})
-instead of the more common @code{INTEGER(KIND=1)}
-(often referred to as @code{INTEGER*4}).
-
-@item
-Emulate @code{COMPLEX} arithmetic in the @code{g77} front
-end, to avoid bugs in @code{complex} support in the
-@code{gcc} back end.
-New option @samp{-fno-emulate-complex}
-causes @code{g77} to revert the 0.5.19 behavior.
-
-@item
-Dummy arguments are no longer assumed to potentially alias
-(overlap)
-other dummy arguments or @code{COMMON} areas when any of
-these are defined (assigned to) by Fortran code.
-
-This can result in faster and/or smaller programs when
-compiling with optimization enabled, though on some
-systems this effect is observed only when @samp{-fforce-addr}
-also is specified.
-
-New options @samp{-falias-check}, @samp{-fargument-alias},
-@samp{-fargument-noalias},
-and @samp{-fno-argument-noalias-global} control the
-way @code{g77} handles potential aliasing.
-
-@xref{Aliasing Assumed To Work}, for detailed information on why the
-new defaults might result in some programs no longer working the way they
-did when compiled by previous versions of @code{g77}.
-
-@item
-New option @samp{-fugly-assign} specifies that the
-same memory locations are to be used to hold the
-values assigned by both statements @samp{I = 3} and
-@samp{ASSIGN 10 TO I}, for example.
-(Normally, @code{g77} uses a separate memory location
-to hold assigned statement labels.)
-
-@xref{Ugly Assigned Labels}, for more information.
-
-@item
-@code{FORMAT} and @code{ENTRY} statements now are allowed to
-precede @code{IMPLICIT NONE} statements.
-
-@item
-Enable full support of @code{INTEGER(KIND=2)}
-(often referred to as @code{INTEGER*8})
-available in
-@code{libf2c} and @file{f2c.h} so that @code{f2c} users
-may make full use of its features via the @code{g77}
-version of @file{f2c.h} and the @code{INTEGER(KIND=2)}
-support routines in the @code{g77} version of @code{libf2c}.
-
-@item
-Improve @code{g77} driver and @code{libf2c} so that @samp{g77 -v}
-yields version information on the library.
-
-@item
-The @code{SNGL} and @code{FLOAT} intrinsics now are
-specific intrinsics, instead of synonyms for the
-generic intrinsic @code{REAL}.
-
-@item
-New intrinsics have been added.
-These are @code{REALPART}, @code{IMAGPART},
-@code{COMPLEX},
-@code{LONG}, and @code{SHORT}.
-
-@item
-A new group of intrinsics, @samp{gnu}, has been added
-to contain the new @code{REALPART}, @code{IMAGPART},
-and @code{COMPLEX} intrinsics.
-An old group, @samp{dcp}, has been removed.
-
-@item
-Complain about industry-wide ambiguous references
-@samp{REAL(@var{expr})} and @samp{AIMAG(@var{expr})},
-where @var{expr} is @code{DOUBLE COMPLEX} (or any
-complex type other than @code{COMPLEX}), unless
-@samp{-ff90} option specifies Fortran 90 interpretation
-or new @samp{-fugly-complex} option, in conjunction with
-@samp{-fnot-f90}, specifies @code{f2c} interpretation.
-@end itemize
-
-@heading In 0.5.19:
-
-@itemize @bullet
-@item
-A temporary kludge option provides bare-bones information on
-@code{COMMON} and @code{EQUIVALENCE} members at debug time.
-@xref{Code Gen Options,,Options for Code Generation Conventions},
-for information on the @samp{-fdebug-kludge} option.
-
-@item
-New @samp{-fonetrip} option specifies FORTRAN-66-style
-one-trip @code{DO} loops.
-
-@item
-New @samp{-fno-silent} option causes names of program units
-to be printed as they are compiled, in a fashion similar to
-UNIX @code{f77} and @code{f2c}.
-
-@item
-New @samp{-fugly-assumed} option specifies that arrays
-dimensioned via @samp{DIMENSION X(1)}, for example, are to be
-treated as assumed-size.
-
-@item
-New @samp{-fno-typeless-boz} option specifies that non-decimal-radix
-constants using the prefixed-radix form (such as @samp{Z'1234'})
-are to be interpreted as @code{INTEGER(KIND=1)} constants.
-
-@item
-New @samp{-ff66} option is a ``shorthand'' option that specifies
-behaviors considered appropriate for FORTRAN 66 programs.
-
-@item
-New @samp{-ff77} option is a ``shorthand'' option that specifies
-behaviors considered appropriate for UNIX @code{f77} programs.
-
-@item
-New @samp{-fugly-comma} and @samp{-fugly-logint} options provided
-to perform some of what @samp{-fugly} used to do.
-@samp{-fugly} and @samp{-fno-ugly} are now ``shorthand'' options,
-in that they do nothing more than enable (or disable) other
-@samp{-fugly-*} options.
-
-@item
-Change code generation for list-directed I/O so it allows
-for new versions of @code{libf2c} that might return non-zero
-status codes for some operations previously assumed to always
-return zero.
-
-This change not only affects how @code{IOSTAT=} variables
-are set by list-directed I/O, it also affects whether
-@code{END=} and @code{ERR=} labels are reached by these
-operations.
-
-@item
-Add intrinsic support for new @code{FTELL} and @code{FSEEK}
-procedures in @code{libf2c}.
-
-@item
-Add options @samp{--help} and @samp{--version} to the
-@code{g77} command, to conform to GNU coding guidelines.
-Also add printing of @code{g77} version number when
-the @samp{--verbose} (@samp{-v}) option is used.
-@end itemize
-
-@heading In 0.5.18:
-
-@itemize @bullet
-@item
-The @code{BYTE} and @code{WORD} statements now are supported,
-to a limited extent.
-
-@item
-@code{INTEGER*1}, @code{INTEGER*2}, @code{INTEGER*8},
-and their @code{LOGICAL}
-equivalents, now are supported to a limited extent.
-Among the missing elements are complete intrinsic and constant
-support.
-
-@item
-Support automatic arrays in procedures.
-For example, @samp{REAL A(N)}, where @samp{A} is
-not a dummy argument, specifies that @samp{A} is
-an automatic array.
-The size of @samp{A} is calculated from the value
-of @samp{N} each time the procedure is called,
-that amount of space is allocated, and that space
-is freed when the procedure returns to its caller.
-
-@item
-Add @samp{-fno-zeros} option, enabled by default,
-to reduce compile-time CPU and memory usage for
-code that provides initial zero values for variables
-and arrays.
-
-@item
-Introduce three new options that apply to all compilations
-by @code{g77}-aware GNU compilers---@samp{-fmove-all-movables},
-@samp{-freduce-all-givs}, and @samp{-frerun-loop-opt}---which
-can improve the run-time performance of some programs.
-
-@item
-Replace much of the existing documentation with a single
-Info document.
-
-@item
-New option @samp{-fno-second-underscore}.
-@end itemize
-
-@heading In 0.5.17:
-
-@itemize @bullet
-@item
-The @code{ERF()} and @code{ERFC()} intrinsics now are generic
-intrinsics, mapping to @code{ERF}/@code{DERF} and
-@code{ERFC}/@code{DERFC}, respectively.
-@emph{Note:} Use @samp{INTRINSIC ERF,ERFC} in any code that
-might reference these as generic intrinsics, to
-improve the likelihood of diagnostics (instead of subtle run-time
-bugs) when using compilers that don't support these as intrinsics.
-
-@item
-New option @samp{-Wsurprising}.
-
-@item
-DO loops with non-@code{INTEGER} variables now diagnosed only when
-@samp{-Wsurprising} specified.
-Previously, this was diagnosed @emph{unless} @samp{-fpedantic} or
-@samp{-fugly} was specified.
-@end itemize
-
-@heading In 0.5.16:
-
-@itemize @bullet
-@item
-@code{libf2c} changed to output a leading zero (0) digit for floating-point
-values output via list-directed and formatted output (to bring @code{g77}
-more into line with many existing Fortran implementations---the
-ANSI FORTRAN 77 standard leaves this choice to the implementation).
-
-@item
-@code{libf2c} no longer built with debugging information
-intact, making it much smaller.
-
-@item
-Automatic installation of the @code{g77} command now works.
-
-@item
-Diagnostic messages now more informative, a la @code{gcc},
-including messages like @samp{In function `foo':} and @samp{In file
-included from...:}.
-
-@item
-New group of intrinsics called @samp{unix}, including @code{ABORT},
-@code{DERF}, @code{DERFC}, @code{ERF}, @code{ERFC}, @code{EXIT},
-@code{FLUSH}, @code{GETARG}, @code{GETENV}, @code{SIGNAL}, and
-@code{SYSTEM}.
-
-@item
-@samp{-funix-intrinsics-@{delete,hide,disable,enable@}}
-options added.
-
-@item
-@samp{-fno-underscoring} option added.
-
-@item
-@samp{--driver} option added to the @code{g77} command.
-
-@item
-Support for the @code{gcc} options @samp{-fident} and @samp{-fno-ident}
-added.
-
-@item
-@samp{g77 -v} returns much more version info, making the submission
-of better bug reports easily.
-
-@item
-Many improvements to the @code{g77} command to better fulfill its role as
-a front-end to the @code{gcc} driver.
-For example, @code{g77} now
-recognizes @samp{--verbose} as a verbose way of specifying @samp{-v}.
-
-@item
-Compiling preprocessed (@file{*.F} and @file{*.fpp}) files now
-results in better diagnostics and debugging information, as the
-source-location info now is passed all the
-way through the compilation process instead of being lost.
-@end itemize
+@set USERVISONLY
+@include news.texi
+@clear USERVISONLY
@node Language
@chapter The GNU Fortran Language
@@ -4161,7 +3452,10 @@ by GNU Fortran.
@cindex textbooks
(If you need a text on Fortran,
a few freely available electronic references have pointers from
-@uref{http://www.fortran.com/fortran/Books/}.)
+@uref{http://www.fortran.com/fortran/Books/}. There is a `cooperative
+net project', @cite{User Notes on Fortran Programming} at
+@uref{ftp://vms.huji.ac.il/fortran/} and mirrors elsewhere; some of this
+material might not apply specifically to @code{g77}.)
Part of what defines a particular implementation of a Fortran
system, such as @code{g77}, is the particular characteristics
@@ -4203,7 +3497,7 @@ Extensions to the ANSI FORTRAN 77 standard:
@section Direction of Language Development
@cindex direction of language development
@cindex features, language
-@cindex language features
+@cindex language, features
The purpose of the following description of the GNU Fortran
language is to promote wide portability of GNU Fortran programs.
@@ -4348,8 +3642,8 @@ of @code{g77}).
@node Standard Support
@section ANSI FORTRAN 77 Standard Support
@cindex ANSI FORTRAN 77 support
-@cindex standard support
-@cindex support for ANSI FORTRAN 77
+@cindex standard, support for
+@cindex support, FORTRAN 77
@cindex compatibility, FORTRAN 77
@cindex FORTRAN 77 compatibility
@@ -4624,6 +3918,7 @@ for the relevant aspects of GNU Fortran.)
(Corresponds to Section 2.2 of ANSI X3.9-1978 FORTRAN 77.)
+@cindex limits, lengths of names
In GNU Fortran, a symbolic name is at least one character long,
and has no arbitrary upper limit on length.
However, names of entities requiring external linkage (such as
@@ -4640,8 +3935,13 @@ character (which must be a letter).
(Corresponds to Section 2.3 of ANSI X3.9-1978 FORTRAN 77.)
-@cindex comments, trailing
-@cindex trailing comments
+@cindex trailing comment
+@cindex comment
+@cindex characters, comment
+@cindex !
+@cindex exclamation point
+@cindex continuation character
+@cindex characters, continuation
Use of an exclamation point (@samp{!}) to begin a
trailing comment (a comment that extends to the end of the same
source line) is permitted under the following conditions:
@@ -4665,7 +3965,8 @@ That is, a trailing comment may contain exclamation points
in their commentary text.
@end itemize
-@cindex semicolons
+@cindex ;
+@cindex semicolon
@cindex statements, separated by semicolon
Use of a semicolon (@samp{;}) as a statement separator
is permitted under the following conditions:
@@ -4751,36 +4052,65 @@ Special characters include:
@itemize @bullet
@item
+@cindex ;
+@cindex semicolon
Semicolon (@samp{;})
@item
+@cindex !
+@cindex exclamation point
Exclamation point (@samp{!})
@item
+@cindex "
+@cindex double quote
Double quote (@samp{"})
@item
+@cindex \
+@cindex backslash
Backslash (@samp{\})
@item
+@cindex ?
+@cindex question mark
Question mark (@samp{?})
@item
+@cindex #
+@cindex hash mark
+@cindex pound sign
Hash mark (@samp{#})
@item
+@cindex &
+@cindex ampersand
Ampersand (@samp{&})
@item
+@cindex %
+@cindex percent sign
Percent sign (@samp{%})
@item
+@cindex _
+@cindex underscore
Underscore (@samp{_})
@item
+@cindex <
+@cindex open angle
+@cindex left angle
+@cindex open bracket
+@cindex left bracket
Open angle (@samp{<})
@item
+@cindex >
+@cindex close angle
+@cindex right angle
+@cindex close bracket
+@cindex right bracket
Close angle (@samp{>})
@item
@@ -4790,7 +4120,9 @@ The FORTRAN 77 special characters (@key{SPC}, @samp{=},
and @samp{:})
@end itemize
-@cindex blanks (spaces)
+@cindex blank
+@cindex space
+@cindex SPC
Note that this document refers to @key{SPC} as @dfn{space},
while X3.9-1978 FORTRAN 77 refers to it as @dfn{blank}.
@@ -4798,8 +4130,8 @@ while X3.9-1978 FORTRAN 77 refers to it as @dfn{blank}.
@subsection Lines
@cindex lines
@cindex source file format
-@cindex source form
-@cindex files, source
+@cindex source format
+@cindex file, source
@cindex source code
@cindex code, source
@cindex fixed form
@@ -4841,7 +4173,9 @@ The end-of-file marker (@code{EOF}) also serves to end the line
of text that precedes it (and that does not contain a newline).
@item
-@cindex blanks (spaces)
+@cindex blank
+@cindex space
+@cindex SPC
Any line of text that is shorter than 72 characters is padded to that length
with spaces (called ``blanks'' in the standard).
@@ -4870,10 +4204,10 @@ line containing 72 spaces.
@node Continuation Line
@subsection Continuation Line
-@cindex continuation lines, number of
+@cindex continuation line, number of
@cindex lines, continuation
@cindex number of continuation lines
-@cindex limits on continuation lines
+@cindex limits, continuation lines
(Corresponds to Section 3.2.3 of ANSI X3.9-1978 FORTRAN 77.)
@@ -4987,7 +4321,7 @@ An @code{END BLOCK DATA} statement, if the program unit is a block data.
@node INCLUDE
@subsection Including Source Text
-@cindex INCLUDE
+@cindex INCLUDE directive
Additional source text may be included in the processing of
the source file via the @code{INCLUDE} directive:
@@ -5592,6 +4926,11 @@ and @samp{0123456789ABCDEFabcdef}, respectively.
(The value for @samp{A} (and @samp{a}) is 10, for @samp{B} and @samp{b}
is 11, and so on.)
+A prefix-radix constant, such as @samp{Z'ABCD'}, can optionally be
+treated as typeless. @xref{Fortran Dialect Options,, Options
+Controlling Fortran Dialect}, for information on the
+@samp{-ftypeless-boz} option.
+
Typeless constants have values that depend on the context in which
they are used.
@@ -5876,6 +5215,10 @@ as appropriate.
@node CYCLE and EXIT
@subsection The @code{CYCLE} and @code{EXIT} Statements
+@cindex CYCLE statement
+@cindex EXIT statement
+@cindex statements, CYCLE
+@cindex statements, EXIT
The @code{CYCLE} and @code{EXIT} statements specify that
the remaining statements in the current iteration of a
particular active (enclosing) @code{DO} loop are to be skipped.
@@ -6212,12 +5555,12 @@ are given arguments that do not conform to their stated requirements:
@smallexample
PROGRAM JCB002
C Version 1:
+C Modified 1999-02-15 (Burley) to delete my email address.
C Modified 1997-05-21 (Burley) to accommodate compilers that implement
C INT(I1-I2) as INT(I1)-INT(I2) given INTEGER*2 I1,I2.
C
C Version 0:
C Written by James Craig Burley 1997-02-20.
-C Contact via Internet email: burley@@gnu.org
C
C Purpose:
C Determine how compilers handle non-standard IDIM
@@ -6355,10 +5698,10 @@ worth adding to the above list, please let us know the details
@node REAL() and AIMAG() of Complex
@subsection @code{REAL()} and @code{AIMAG()} of Complex
-@cindex REAL intrinsic
-@cindex intrinsics, REAL
-@cindex AIMAG intrinsic
-@cindex intrinsics, AIMAG
+@cindex @code{Real} intrinsic
+@cindex intrinsics, @code{Real}
+@cindex @code{AImag} intrinsic
+@cindex intrinsics, @code{AImag}
The GNU Fortran language disallows @code{REAL(@var{expr})}
and @code{AIMAG(@var{expr})},
@@ -6415,8 +5758,8 @@ treated as @samp{REAL(REALPART(@var{expr}))}.
@node CMPLX() of DOUBLE PRECISION
@subsection @code{CMPLX()} of @code{DOUBLE PRECISION}
-@cindex CMPLX intrinsic
-@cindex intrinsics, CMPLX
+@cindex @code{Cmplx} intrinsic
+@cindex intrinsics, @code{Cmplx}
In accordance with Fortran 90 and at least some (perhaps all)
other compilers, the GNU Fortran language defines @code{CMPLX()}
@@ -6548,7 +5891,7 @@ and definable by, invocation of the intrinsic (a combination of
the requirements of @code{INTENT(IN)} and @code{INTENT(OUT)}.
@item
-@xref{Kind Notation} for explanation of @code{KIND}.
+@xref{Kind Notation}, for an explanation of @code{KIND}.
@end itemize
@ifinfo
@@ -6579,7 +5922,7 @@ did not exist, would leave this document in far worse shape!)
@node Scope and Classes of Names
@section Scope and Classes of Symbolic Names
-@cindex symbolic names
+@cindex symbol names, scope and classes
@cindex scope
(The following information augments or overrides the information in
@@ -6594,7 +5937,7 @@ for the relevant aspects of GNU Fortran.)
@node Underscores in Symbol Names
@subsection Underscores in Symbol Names
-@cindex underscores
+@cindex underscore
Underscores (@samp{_}) are accepted in symbol names after the first
character (which must be a letter).
@@ -6616,12 +5959,16 @@ Edit descriptors in @code{FORMAT} statements may contain compile-time
The @code{OPEN} specifier @code{NAME=} is equivalent to @code{FILE=}.
-These Fortran 90 features are supported:
+These Fortran 90 features are supported:
@itemize @bullet
@item
+@cindex FORMAT descriptors
@cindex Z edit descriptor
@cindex edit descriptor, Z
-The @code{Z} edit descriptor is supported.
+@cindex O edit descriptor
+@cindex edit descriptor, O
+The @code{O} and @code{Z} edit descriptors are supported for I/O of
+integers in octal and hexadecimal formats, respectively.
@item
The @code{FILE=} specifier may be omitted in an @code{OPEN} statement if
@code{STATUS='SCRATCH'} is supplied. The @code{STATUS='REPLACE'}
@@ -6631,6 +5978,7 @@ specifier is supported.
@node Fortran 90 Features
@section Fortran 90 Features
@cindex Fortran 90
+@cindex extensions, from Fortran 90
For convenience this section collects a list (probably incomplete) of
the Fortran 90 features supported by the GNU Fortran language, even if
@@ -6642,14 +5990,15 @@ they are documented elsewhere.
@ifinfo
@xref{Characters Lines Sequence},
@end ifinfo
-for information on additional fixed source form lexical issues. In
-addition, the free source form is supported through the
+for information on additional fixed source form lexical issues.
@cindex @samp{-ffree-form}
-@samp{-ffree-form} option. @xref{Fortran 90} for other Fortran 90
-features be turned on by the
+Further, the free source form is supported through the
+@samp{-ffree-form} option.
@cindex @samp{-ff90}
-@samp{-ff90} option. @xref{Table of Intrinsic Functions} for
-information on the Fortran 90 intrinsics available.
+Other Fortran 90 features can be turned on by the @samp{-ff90} option;
+see @ref{Fortran 90}.
+For information on the Fortran 90 intrinsics available,
+see @ref{Table of Intrinsic Functions}.
@table @asis
@item Automatic arrays in procedures
@@ -6679,14 +6028,22 @@ permitted. Character constants may be enclosed in double quotes
@item @code{IMPLICIT NONE}
@item @code{INCLUDE} statements
@xref{INCLUDE}.
-@item List directed and namelist i/o on internal files
+@item List-directed and namelist I/O on internal files
@item Binary, octal and hexadecimal constants
These are supported more generally than required by Fortran 90.
@xref{Integer Type}.
+@item @samp{O} and @samp{Z} edit descriptors
@item @code{NAMELIST}
@xref{NAMELIST}.
@item @code{OPEN} specifiers
@code{STATUS='REPLACE'} is supported.
+The @code{FILE=} specifier may be omitted in an @code{OPEN} statement if
+@code{STATUS='SCRATCH'} is supplied.
+@item @code{FORMAT} edit descriptors
+@cindex FORMAT descriptors
+@cindex Z edit descriptor
+@cindex edit descriptor, Z
+The @code{Z} edit descriptor is supported.
@item Relational operators
The operators @code{<}, @code{<=}, @code{==}, @code{/=}, @code{>} and
@code{>=} may be used instead of @code{.LT.}, @code{.LE.}, @code{.EQ.},
@@ -6740,8 +6097,8 @@ of work!}
@node Source Form
@section Source Form
@cindex source file format
-@cindex source form
-@cindex files, source
+@cindex source format
+@cindex file, source
@cindex source code
@cindex code, source
@cindex fixed form
@@ -6790,7 +6147,8 @@ inside such constants.
@node Tabs
@subsection Tabs
-@cindex tab characters
+@cindex tab character
+@cindex horizontal tab
A source line with a @key{TAB} character anywhere in it is treated as
entirely significant---however long it is---instead of ending in
@@ -6824,8 +6182,7 @@ the way continued character/Hollerith constants are interpreted).
@node Short Lines
@subsection Short Lines
@cindex short source lines
-@cindex space-padding
-@cindex spaces
+@cindex space, padding with
@cindex source lines, short
@cindex lines, short
@@ -6851,7 +6208,7 @@ like @samp{-ffixed-line-length-none}, for example.
@node Long Lines
@subsection Long Lines
@cindex long source lines
-@cindex truncation
+@cindex truncation, of long lines
@cindex lines, long
@cindex source lines, long
@@ -6878,8 +6235,11 @@ continuation line, imitating the behavior of @code{f2c}.
@section Trailing Comment
@cindex trailing comment
-@cindex comment, trailing
+@cindex comment
+@cindex characters, comment
@cindex /*
+@cindex !
+@cindex exclamation point
@code{g77} supports use of @samp{/*} to start a trailing
comment.
In the GNU Fortran language, @samp{!} is used for this purpose.
@@ -7272,7 +6632,8 @@ both constructs in the general case, since statements like
@node Exclamation Point
@subsection Meaning of Exclamation Point in Column 6
-@cindex exclamation points
+@cindex !
+@cindex exclamation point
@cindex continuation character
@cindex characters, continuation
@cindex comment character
@@ -7306,7 +6667,7 @@ marks a line as a continuation line when it appears in column 6.)
@node Fortran 90
@section Fortran 90
@cindex compatibility, Fortran 90
-@cindex Fortran 90 compatibility
+@cindex Fortran 90, compatibility
The GNU Fortran language includes a number of features that are
part of Fortran 90, even when the @samp{-ff90} option is not specified.
@@ -7659,8 +7020,9 @@ without conversion.
@node Ugly Null Arguments
@subsection Ugly Null Arguments
-@cindex trailing commas
-@cindex commas, trailing
+@cindex trailing comma
+@cindex comma, trailing
+@cindex characters, comma
@cindex null arguments
@cindex arguments, null
@@ -7874,6 +7236,7 @@ of work!}
@menu
* Compiler Limits::
+* Run-time Environment Limits::
* Compiler Types::
* Compiler Constants::
* Compiler Intrinsics::
@@ -7892,6 +7255,8 @@ symbols in a program, and so on.
@cindex -Nl option
@cindex options, -Nx
@cindex -Nx option
+@cindex limits, continuation lines
+@cindex limits, lengths of names
For example, some other Fortran compiler have an option
(such as @samp{-Nl@var{x}}) to increase the limit on the
number of continuation lines.
@@ -7907,9 +7272,315 @@ limits in these areas.
@cindex maximum rank
@cindex number of dimensions, maximum
@cindex maximum number of dimensions
+@cindex limits, rank
+@cindex limits, array dimensions
@code{g77} does currently limit the number of dimensions in an array
to the same degree as do the Fortran standards---seven (7).
-This restriction might well be lifted in a future version.
+This restriction might be lifted in a future version.
+
+@node Run-time Environment Limits
+@section Run-time Environment Limits
+@cindex limits, run-time library
+@cindex wraparound
+
+As a portable Fortran implementation,
+@code{g77} offers its users direct access to,
+and otherwise depends upon,
+the underlying facilities of the system
+used to build @code{g77},
+the system on which @code{g77} itself is used to compile programs,
+and the system on which the @code{g77}-compiled program is actually run.
+(For most users, the three systems are of the same
+type---combination of operating environment and hardware---often
+the same physical system.)
+
+The run-time environment for a particular system
+inevitably imposes some limits on a program's use
+of various system facilities.
+These limits vary from system to system.
+
+Even when such limits might be well beyond the
+possibility of being encountered on a particular system,
+the @code{g77} run-time environment
+has certain built-in limits,
+usually, but not always, stemming from intrinsics
+with inherently limited interfaces.
+
+Currently, the @code{g77} run-time environment
+does not generally offer a less-limiting environment
+by augmenting the underlying system's own environment.
+
+Therefore, code written in the GNU Fortran language,
+while syntactically and semantically portable,
+might nevertheless make non-portable assumptions
+about the run-time environment---assumptions that
+prove to be false for some particular environments.
+
+The GNU Fortran language,
+the @code{g77} compiler and run-time environment,
+and the @code{g77} documentation
+do not yet offer comprehensive portable work-arounds for such limits,
+though programmers should be able to
+find their own in specific instances.
+
+Not all of the limitations are described in this document.
+Some of the known limitations include:
+
+@menu
+* Timer Wraparounds::
+* Year 2000 (Y2K) Problems::
+* Array Size::
+* Character-variable Length::
+* Year 10000 (Y10K) Problems::
+@end menu
+
+@node Timer Wraparounds
+@subsection Timer Wraparounds
+
+Intrinsics that return values computed from system timers,
+whether elapsed (wall-clock) timers,
+process CPU timers,
+or other kinds of timers,
+are prone to experiencing wrap-around errors
+(or returning wrapped-around values from successive calls)
+due to insufficient ranges
+offered by the underlying system's timers.
+
+@cindex negative time
+@cindex short time
+@cindex long time
+Some of the symptoms of such behaviors include
+apparently negative time being computed for a duration,
+an extremely short amount of time being computed for a long duration,
+and an extremely long amount of time being computed for a short duration.
+
+See the following for intrinsics
+known to have potential problems in these areas
+on at least some systems:
+@ref{CPU_Time Intrinsic},
+@ref{DTime Intrinsic (function)}, @ref{DTime Intrinsic (subroutine)},
+@ref{ETime Intrinsic (function)}, @ref{ETime Intrinsic (subroutine)},
+@ref{MClock Intrinsic}, @ref{MClock8 Intrinsic},
+@ref{Secnds Intrinsic},
+@ref{Second Intrinsic (function)}, @ref{Second Intrinsic (subroutine)},
+@ref{System_Clock Intrinsic},
+@ref{Time Intrinsic (UNIX)}, @ref{Time Intrinsic (VXT)},
+@ref{Time8 Intrinsic}.
+
+@node Year 2000 (Y2K) Problems
+@subsection Year 2000 (Y2K) Problems
+@cindex Y2K compliance
+@cindex Year 2000 compliance
+
+While the @code{g77} compiler itself is believed to
+be Year-2000 (Y2K) compliant,
+some intrinsics are not,
+and, potentially, some underlying systems are not,
+perhaps rendering some Y2K-compliant intrinsics
+non-compliant when used on those particular systems.
+
+Fortran code that uses non-Y2K-compliant intrinsics
+(listed below)
+is, itself, almost certainly not compliant,
+and should be modified to use Y2K-compliant intrinsics instead.
+
+Fortran code that uses no non-Y2K-compliant intrinsics,
+but which currently is running on a non-Y2K-compliant system,
+can be made more Y2K compliant by compiling and
+linking it for use on a new Y2K-compliant system,
+such as a new version of an old, non-Y2K-compliant, system.
+
+Currently, information on Y2K and related issues
+is being maintained at
+@uref{http://www.gnu.org/software/year2000-list.html}.
+
+See the following for intrinsics
+known to have potential problems in these areas
+on at least some systems:
+@ref{Date Intrinsic},
+@ref{IDate Intrinsic (VXT)}.
+
+@cindex y2kbuggy
+@cindex date_y2kbuggy_0
+@cindex vxtidate_y2kbuggy_0
+@cindex G77_date_y2kbuggy_0
+@cindex G77_vxtidate_y2kbuggy_0
+The @code{libg2c} library
+shipped with any @code{g77} that warns
+about invocation of a non-Y2K-compliant intrinsic
+has renamed the @samp{EXTERNAL} procedure names
+of those intrinsics.
+This is done so that
+the @code{libg2c} implementations of these intrinsics
+cannot be directly linked to
+as @samp{EXTERNAL} names
+(which normally would avoid the non-Y2K-intrinsic warning).
+
+The renamed forms of the @samp{EXTERNAL} names
+of these renamed procedures
+may be linked to
+by appending the string @samp{_y2kbug}
+to the name of the procedure
+in the source code.
+For example:
+
+@smallexample
+CHARACTER*20 STR
+INTEGER YY, MM, DD
+EXTERNAL DATE_Y2KBUG, VXTIDATE_Y2KBUG
+CALL DATE_Y2KBUG (STR)
+CALL VXTIDATE_Y2KBUG (MM, DD, YY)
+@end smallexample
+
+(Note that the @samp{EXTERNAL} statement
+is not actually required,
+since the modified names are not recognized as intrinsics
+by the current version of @code{g77}.
+But it is shown in this specific case,
+for purposes of illustration.)
+
+The renaming of @samp{EXTERNAL} procedure names of these intrinsics
+causes unresolved references at link time.
+For example, @samp{EXTERNAL DATE; CALL DATE(STR)}
+is normally compiled by @code{g77}
+as, in C, @samp{date_(&str, 20);}.
+This, in turn, links to the @samp{date_} procedure
+in the @samp{libE77} portion of @code{libg2c},
+which purposely calls a nonexistent procedure
+named @samp{G77_date_y2kbuggy_0}.
+The resulting link-time error is designed, via this name,
+to encourage the programmer to look up the
+index entries to this portion of the @code{g77} documentation.
+
+Generally, we recommend that the @samp{EXTERNAL} method
+of invoking procedures in @code{libg2c}
+@emph{not} be used.
+When used, some of the correctness checking
+normally performed by @code{g77}
+is skipped.
+
+In particular, it is probably better to use the
+@samp{INTRINSIC} method of invoking
+non-Y2K-compliant procedures,
+so anyone compiling the code
+can quickly notice the potential Y2K problems
+(via the warnings printing by @code{g77})
+without having to even look at the code itself.
+
+If there are problems linking @code{libg2c}
+to code compiled by @code{g77}
+that involve the string @samp{y2kbug},
+and these are not explained above,
+that probably indicates
+that a version of @code{libg2c}
+older than @code{g77}
+is being linked to,
+or that the new library is being linked
+to code compiled by an older version of @code{g77}.
+
+That's because, as of the version that warns about
+non-Y2K-compliant intrinsic invocation,
+@code{g77} references the @code{libg2c} implementations
+of those intrinsics
+using new names, containing the string @samp{y2kbug}.
+
+So, linking newly-compiled code
+(invoking one of the intrinsics in question)
+to an old library
+might yield an unresolved reference
+to @samp{G77_date_y2kbug_0}.
+(The old library calls it @samp{G77_date_0}.)
+
+Similarly, linking previously-compiled code
+to a new library
+might yield an unresolved reference
+to @samp{G77_vxtidate_0}.
+(The new library calls it @samp{G77_vxtidate_y2kbug_0}.)
+
+The proper fix for the above problems
+is to obtain the latest release of @code{g77}
+and related products
+(including @code{libg2c})
+and install them on all systems,
+then recompile, relink, and install
+(as appropriate)
+all existing Fortran programs.
+
+(Normally, this sort of renaming is steadfastly avoided.
+In this case, however, it seems more important to highlight
+potential Y2K problems
+than to ease the transition
+of potentially non-Y2K-compliant code
+to new versions of @code{g77} and @code{libg2c}.)
+
+@node Array Size
+@subsection Array Size
+@cindex limits, array size
+@cindex array size
+
+Currently, @code{g77} uses the default @code{INTEGER} type
+for array indexes,
+which limits the sizes of single-dimension arrays
+on systems offering a larger address space
+than can be addressed by that type.
+(That @code{g77} puts all arrays in memory
+could be considered another limitation---it
+could use large temporary files---but that decision
+is left to the programmer as an implementation choice
+by most Fortran implementations.)
+
+@c ??? Investigate this, to offer a more clear statement
+@c than the following paragraphs do. -- burley 1999-02-17
+It is not yet clear whether this limitation
+never, sometimes, or always applies to the
+sizes of multiple-dimension arrays as a whole.
+
+For example, on a system with 64-bit addresses
+and 32-bit default @code{INTEGER},
+an array with a size greater than can be addressed
+by a 32-bit offset
+can be declared using multiple dimensions.
+Such an array is therefore larger
+than a single-dimension array can be,
+on the same system.
+
+@cindex limits, multi-dimension arrays
+@cindex multi-dimension arrays
+@cindex arrays, dimensioning
+Whether large multiple-dimension arrays are reliably supported
+depends mostly on the @code{gcc} back end (code generator)
+used by @code{g77}, and has not yet been fully investigated.
+
+@node Character-variable Length
+@subsection Character-variable Length
+@cindex limits, on character-variable length
+@cindex character-variable length
+
+Currently, @code{g77} uses the default @code{INTEGER} type
+for the lengths of @code{CHARACTER} variables
+and array elements.
+
+This means that, for example,
+a system with a 64-bit address space
+and a 32-bit default @code{INTEGER} type
+does not, under @code{g77},
+support a @code{CHARACTER*@var{n}} declaration
+where @var{n} is greater than 2147483647.
+
+@node Year 10000 (Y10K) Problems
+@subsection Year 10000 (Y10K) Problems
+@cindex Y10K compliance
+@cindex Year 10000 compliance
+
+Most intrinsics returning, or computing values based on,
+date information are prone to Year-10000 (Y10K) problems,
+due to supporting only 4 digits for the year.
+
+See the following for examples:
+@ref{FDate Intrinsic (function)}, @ref{FDate Intrinsic (subroutine)},
+@ref{IDate Intrinsic (UNIX)},
+@ref{Time Intrinsic (VXT)},
+@ref{Date_and_Time Intrinsic}.
@node Compiler Types
@section Compiler Types
@@ -8445,7 +8116,7 @@ command.
of work!}
@menu
-* Interoperating with C and C++::
+* Interoperating with C and C++::
@end menu
@node Interoperating with C and C++
@@ -8574,8 +8245,8 @@ avoid clashes with C++ reserved words in addition to those in C@.
@subsection Startup Code
@cindex startup code
-@cindex runtime initialization
-@cindex initialization, runtime
+@cindex run-time, initialization
+@cindex initialization, run-time
Unlike with some runtime systems,
it shouldn't be necessary
(unless there are bugs)
@@ -8810,10 +8481,10 @@ file @file{@value{path-libf2c}/libF77/main.c}, to see what kinds of things
might need to be done by your @code{main()} in order to provide the
Fortran environment your Fortran code is expecting.
-@cindex IARGC() intrinsic
-@cindex intrinsics, IARGC()
-@cindex GETARG() intrinsic
-@cindex intrinsics, GETARG()
+@cindex @code{IArgC} intrinsic
+@cindex intrinsics, @code{IArgC}
+@cindex @code{GetArg} intrinsic
+@cindex intrinsics, @code{GetArg}
For example, @code{libg2c}'s @code{main()} sets up the information used by
the @code{IARGC} and @code{GETARG} intrinsics.
Bypassing @code{libg2c}'s @code{main()}
@@ -8984,7 +8655,7 @@ functions return @code{float}.
@node Names
@section Names
@cindex symbol names
-@cindex transformation of symbol names
+@cindex transforming symbol names
Fortran permits each implementation to decide how to represent
names as far as how they're seen in other contexts, such as debuggers
@@ -9084,8 +8755,8 @@ could be used to inhibit the appending of the underscore to the name.
@node Common Blocks
@section Common Blocks (COMMON)
@cindex common blocks
-@cindex COMMON statement
-@cindex statements, COMMON
+@cindex @code{COMMON} statement
+@cindex statements, @code{COMMON}
@code{g77} names and lays out @code{COMMON} areas
the same way @code{f2c} does,
@@ -9199,7 +8870,7 @@ previous method in the documentation.)
@node Complex Variables
@section Complex Variables (COMPLEX)
@cindex complex variables
-@cindex imaginary part of complex
+@cindex imaginary part
@cindex COMPLEX statement
@cindex statements, COMPLEX
@@ -9923,8 +9594,8 @@ Microsoft's rumored patent on the digits 0 and 1 is upheld.)
@cindex BLOCK DATA statement
@cindex statements, BLOCK DATA
@cindex libraries, containing BLOCK DATA
-@cindex @code{f2c} compatibility
-@cindex compatibility, @code{f2c}
+@cindex f2c compatibility
+@cindex compatibility, f2c
To ensure that block data program units are linked, especially a concern
when they are put into libraries, give each one a name (as in
@@ -10024,7 +9695,7 @@ The meaning of a @code{DO} loop in Fortran is precisely specified
in the Fortran standard@dots{}and is quite different from what
many programmers might expect.
-In particular, Fortran indexed @code{DO} loops are implemented as if
+In particular, Fortran iterative @code{DO} loops are implemented as if
the number of trips through the loop is calculated @emph{before}
the loop is entered.
@@ -10208,7 +9879,7 @@ tracking down bugs in such programs.
* Aliasing Assumed To Work::
* Output Assumed To Flush::
* Large File Unit Numbers::
-* Floating point precision::
+* Floating-point precision::
* Inconsistent Calling Sequences::
@end menu
@@ -10267,7 +9938,7 @@ are given types and then evaluated.
@node Variables Assumed To Be Zero
@subsection Variables Assumed To Be Zero
@cindex zero-initialized variables
-@cindex variables assumed to be zero
+@cindex variables, assumed to be zero
@cindex uninitialized variables
Many Fortran programs were developed on systems that provided
@@ -10292,7 +9963,7 @@ options using @code{g77}.
@node Variables Assumed To Be Saved
@subsection Variables Assumed To Be Saved
-@cindex variables retaining values across calls
+@cindex variables, retaining values across calls
@cindex saved variables
@cindex static variables
@@ -10627,22 +10298,23 @@ open by a running program.
Information on how to increase these limits should be found
in your system's documentation.
-@node Floating point precision
-@subsection Floating point precision
+@node Floating-point precision
+@subsection Floating-point precision
-@cindex IEEE 754
-@cindex IEEE conformance
-@cindex conformance, IEEE
-@cindex floating point precision
-If your program depends on exact IEEE 754 floating point handling it may
+@cindex IEEE 754 conformance
+@cindex conformance, IEEE 754
+@cindex floating-point, precision
+@cindex ix86 floating-point
+@cindex x86 floating-point
+If your program depends on exact IEEE 754 floating-point handling it may
help on some systems---specifically x86 or m68k hardware---to use
the @code{-ffloat-store} option or to reset the precision flag on the
-floating point unit @xref{Optimize Options}.
+floating-point unit @xref{Optimize Options}.
However, it might be better simply to put the FPU into double precision
mode and not take the performance hit of @code{-ffloat-store}. On x86
and m68k GNU systems you can do this with a technique similar to that
-for turning on floating point exceptions @xref{Floating-point Exception
+for turning on floating-point exceptions @xref{Floating-point Exception
Handling}. The control word could be set to double precision by
replacing the @code{__setfpucw} call with one like this:
@smallexample
@@ -10659,11 +10331,12 @@ Configurations,gcc,Using and Porting GNU CC}.
@subsection Inconsistent Calling Sequences
@pindex ftnchek
-@cindex floating point errors
+@cindex floating-point, errors
+@cindex ix86 FPU stack
@cindex x86 FPU stack
Code containing inconsistent calling sequences in the same file is
normally rejected @xref{GLOBALS}. (Use, say, @code{ftnchek} to ensure
-consistency across source files
+consistency across source files
@c makeinfo 1.68 objects to the nested parens
@ifinfo
@xref{f2c Skeletons and Prototypes}.)
@@ -10675,11 +10348,11 @@ consistency across source files
Mysterious errors, which may appear to be code generation problems, can
appear specifically on the x86 architecture with some such
-inconsistencies. On x86 hardware, floating point return values of
-functions are placed on the floating point unit's register stack, not
+inconsistencies. On x86 hardware, floating-point return values of
+functions are placed on the floating-point unit's register stack, not
the normal stack. Thus calling a @code{REAL} or @code{DOUBLE PRECISION}
@code{FUNCTION} as some other sort of procedure, or vice versa,
-scrambles the floating point stack. This may break unrelated code
+scrambles the floating-point stack. This may break unrelated code
executed later. Similarly if, say, external C routines are written
incorrectly.
@@ -10778,7 +10451,7 @@ It is easy to find these using @samp{-f@var{group}-intrinsics-disable}.
@node Faster Programs
@section Faster Programs
-@cindex speeding up programs
+@cindex speed, of programs
@cindex programs, speeding up
Aside from the usual @code{gcc} options, such as @samp{-O},
@@ -10800,7 +10473,7 @@ it working).
@cindex aligned data
@cindex aligned stack
@cindex Pentium optimizations
-@cindex optimizations, Pentium
+@cindex optimization, for Pentium
On some systems, such as those with Pentium Pro CPUs, programs
that make heavy use of @code{REAL(KIND=2)} (@code{DOUBLE PRECISION})
@@ -10822,8 +10495,8 @@ There are a variety of approaches to use to address this problem:
@itemize @bullet
@item
-@cindex COMMON, layout
-@cindex layout of common blocks
+@cindex @code{COMMON} layout
+@cindex layout of @code{COMMON} blocks
Order your @code{COMMON} and @code{EQUIVALENCE} areas such
that the variables and arrays with the widest alignment
guidelines come first.
@@ -10853,7 +10526,7 @@ avoid having to carefully count the number of bytes
occupied by each entity to determine whether the
actual alignment of each subsequent entity meets the
alignment guidelines for the type of that entity.
-
+
If you don't ensure correct alignment of @code{COMMON} elements, the
compiler may be forced by some systems to violate the Fortran semantics by
adding padding to get @code{DOUBLE PRECISION} data properly aligned.
@@ -10964,7 +10637,7 @@ compiler, typically @code{gcc}.)
@node Use Submodel Options
@subsection Use Submodel Options
@cindex Pentium optimizations
-@cindex optimizations, Pentium
+@cindex optimization, for Pentium
@cindex 586/686 CPUs
@cindex submodels
@@ -11008,7 +10681,7 @@ or installing @code{g77} is not provided here.
@xref{Problems Installing}.
To find out about major bugs discovered in the current release and
-possible workarounds for them, retrieve
+possible workarounds for them, see
@uref{ftp://alpha.gnu.org/g77.plan}.
(Note that some of this portion of the manual is lifted
@@ -11021,7 +10694,7 @@ gcc,Using and Porting GNU CC}.)
@menu
* But-bugs:: Bugs really in other programs or elsewhere.
-* Actual Bugs:: Bugs and misfeatures we will fix later.
+* Known Bugs:: Bugs known to be in this version of @code{g77}.
* Missing Features:: Features we already know we want to add later.
* Disappointments:: Regrettable things we can't change.
* Non-bugs:: Things we think are right, but some others disagree.
@@ -11130,8 +10803,8 @@ a reference to it in future versions of this manual.
@cindex unresolved reference (various)
@cindex linking error for user code
@cindex code, user
-@cindex ld error for user code
-@cindex ld can't find strange names
+@cindex @code{ld}, error linking user code
+@cindex @code{ld}, can't find strange names
On some systems, perhaps just those with out-of-date (shared?)
libraries, unresolved-reference errors happen when linking @code{g77}-compiled
programs (which should be done using @code{g77}).
@@ -11147,10 +10820,10 @@ systems where @samp{-lg2c -lm} is insufficient to resolve code produced
by @code{g77}.
@cindex undefined reference (_main)
-@cindex linking error for user code
-@cindex ld error for user code
+@cindex linking error, user code
+@cindex @code{ld}, error linking user code
@cindex code, user
-@cindex ld can't find _main
+@cindex @code{ld}, can't find @samp{_main}
If your program doesn't link due to unresolved references to names
like @samp{_main}, make sure you're using the @code{g77} command to do the
link, since this command ensures that the necessary libraries are
@@ -11167,8 +10840,8 @@ command line, in case that helps.
@subsection Large Common Blocks
@cindex common blocks, large
@cindex large common blocks
-@cindex linker errors
-@cindex ld errors
+@cindex linking, errors
+@cindex @code{ld}, errors
@cindex errors, linker
On some older GNU/Linux systems, programs with common blocks larger
than 16MB cannot be linked without some kind of error
@@ -11179,7 +10852,7 @@ more recent versions of @code{binutils}, such as version 2.6.
@node Debugger Problems
@subsection Debugger Problems
-@cindex @code{gdb} support
+@cindex @code{gdb}, support
@cindex support, @code{gdb}
There are some known problems when using @code{gdb} on code
compiled by @code{g77}.
@@ -11249,7 +10922,7 @@ not enough.)
@node Stack Overflow
@subsection Stack Overflow
-@cindex stack overflow
+@cindex stack, overflow
@cindex segmentation violation
@code{g77} code might fail at runtime (probably with a ``segmentation
violation'') due to overflowing the stack.
@@ -11301,9 +10974,9 @@ simply too large for the system, or buggy.)
@node Nothing Happens
@subsection Nothing Happens
@cindex nothing happens
-@cindex naming programs @samp{test}
+@cindex naming programs
@cindex @samp{test} programs
-@cindex programs named @samp{test}
+@cindex programs, @samp{test}
It is occasionally reported that a ``simple'' program,
such as a ``Hello, World!'' program, does nothing when
it is run, even though the compiler reported no errors,
@@ -11390,8 +11063,8 @@ In the meantime, finding and fixing the programming
bugs that lead to these behaviors is, ultimately, the user's
responsibility, as difficult as that task can sometimes be.
-@cindex ``infinite spaces'' printed
-@cindex spaces, endless printing of
+@cindex infinite spaces printed
+@cindex space, endless printing of
@cindex libc, non-ANSI or non-default
@cindex C library
@cindex linking against non-standard library
@@ -11520,24 +11193,50 @@ instead of converting them to double precision first.
This would tend to result in output that is more consistent
with that produced by some other Fortran implementations.
-A useful source of information on floating point computation is David
+A useful source of information on floating-point computation is David
Goldberg, `What Every Computer Scientist Should Know About
Floating-Point Arithmetic', Computing Surveys, 23, March 1991, pp.@:
-5--48. At the time of writing this is available online under
-@uref{http://docs.sun.com} and there is a supplemented version at
-@uref{http://www.validgh.com/}. Information related to the IEEE 754
-floating point standard by a leading light can be found at
-@uref{http://http.cs.berkeley.edu/%7Ewkahan/ieee754status }; see also
-slides from the short course referenced from
+5--48.
+An online version is available at
+@uref{http://docs.sun.com},
+and there is a supplemented version, in PostScript form, at
+@uref{http://www.validgh.com/goldberg/paper.ps}.
+
+Information related to the IEEE 754
+floating-point standard by a leading light can be found at
+@uref{http://http.cs.berkeley.edu/%7Ewkahan/ieee754status};
+see also slides from the short course referenced from
@uref{http://http.cs.berkeley.edu/%7Efateman/}.
-@uref{http://www.suburbia.net/%7Ebillm/floating-point/} has a brief
-guide to IEEE 754, a somewhat x86 GNU/Linux-specific FAQ and library
-code for GNU/Linux x86 systems.
+@uref{http://www.linuxsupportline.com/%7Ebillm/} has a brief
+guide to IEEE 754, a somewhat x86-GNU/Linux-specific FAQ,
+and library code for GNU/Linux x86 systems.
+
+The supplement to the PostScript-formatted Goldberg document,
+referenced above, is available in HTML format.
+See `Differences Among IEEE 754 Implementations' by Doug Priest,
+available online at
+@uref{http://www.validgh.com/goldberg/addendum.html}.
+This document explores some of the issues surrounding computing
+of extended (80-bit) results on processors such as the x86,
+especially when those results are arbitrarily truncated
+to 32-bit or 64-bit values by the compiler
+as ``spills''.
+
+@cindex spills of floating-point results
+@cindex 80-bit spills
+@cindex truncation, of floating-point values
+(@emph{Note:} @code{g77} specifically, and @code{gcc} generally,
+does arbitrarily truncate 80-bit results during spills
+as of this writing.
+It is not yet clear whether a future version of
+the GNU compiler suite will offer 80-bit spills
+as an option, or perhaps even as the default behavior.)
+
@c xref would be different between editions:
The GNU C library provides routines for controlling the FPU, and other
documentation about this.
-@xref{Floating point precision}, regarding IEEE 754 conformance.
+@xref{Floating-point precision}, regarding IEEE 754 conformance.
@include bugs.texi
@@ -11571,6 +11270,7 @@ GNU Fortran dialects:
* STRUCTURE UNION RECORD MAP::
* OPEN CLOSE and INQUIRE Keywords::
* ENCODE and DECODE::
+* AUTOMATIC Statement::
* Suppressing Space Padding::
* Fortran Preprocessor::
* Bit Operations on Floating-point Data::
@@ -11648,7 +11348,7 @@ having to specify, say, a @code{-Wno-col73to80} option.
@node Fortran 90 Support
@subsection Fortran 90 Support
-@cindex Fortran 90 support
+@cindex Fortran 90, support
@cindex support, Fortran 90
@code{g77} does not support many of the features that
@@ -11716,6 +11416,7 @@ but the result is not pretty.
@node Increasing Precision/Range
@subsection Increasing Precision/Range
@cindex -r8
+@cindex -qrealsize=8
@cindex -i8
@cindex f2c
@cindex increasing precision
@@ -11725,7 +11426,8 @@ but the result is not pretty.
@cindex Toolpack
@cindex Netlib
-Some compilers, such as @code{f2c}, have an option (@samp{-r8} or
+Some compilers, such as @code{f2c}, have an option (@samp{-r8},
+@samp{-qrealsize=8} or
similar) that provides automatic treatment of @code{REAL}
entities such that they have twice the storage size, and
a corresponding increase in the range and precision, of what
@@ -11758,8 +11460,10 @@ alleviate this problem).
@node Popular Non-standard Types
@subsection Popular Non-standard Types
-@cindex INTEGER*2 support
-@cindex LOGICAL*1 support
+@cindex @code{INTEGER*2} support
+@cindex types, @code{INTEGER*2}
+@cindex @code{LOGICAL*1} support
+@cindex types, @code{LOGICAL*1}
@code{g77} doesn't fully support @code{INTEGER*2}, @code{LOGICAL*1},
and similar.
@@ -11771,7 +11475,10 @@ for them.
@node Full Support for Compiler Types
@subsection Full Support for Compiler Types
-@cindex REAL*16 support
+@cindex @code{REAL*16} support
+@cindex types, @code{REAL*16}
+@cindex @code{INTEGER*8} support
+@cindex types, @code{INTEGER*8}
@code{g77} doesn't support @code{INTEGER}, @code{REAL}, and @code{COMPLEX} equivalents
for @emph{all} applicable back-end-supported types (@code{char}, @code{short int},
@code{int}, @code{long int}, @code{long long int}, and @code{long double}).
@@ -11787,8 +11494,8 @@ This is scheduled for version 0.6.
@cindex array elements, in adjustable array bounds
@cindex function references, in adjustable array bounds
@cindex array bounds, adjustable
-@cindex DIMENSION statement
-@cindex statements, DIMENSION
+@cindex @code{DIMENSION} statement
+@cindex statements, @code{DIMENSION}
@code{g77} doesn't support more general expressions to dimension
arrays, such as array element references, function
@@ -12022,11 +11729,11 @@ require much more work on @code{libg2c}.
@cindex FORM='PRINT'
@cindex ANS carriage control
-@cindex carraige control
+@cindex carriage control
@pindex asa
@pindex fpr
@code{g77} doesn't support @code{FORM='PRINT'} or an equivalent to
-translate the traditional `carraige control' characters in column 1 of
+translate the traditional `carriage control' characters in column 1 of
output to use backspaces, carriage returns and the like. However
programs exist to translate them in output files (or standard output).
These are typically called either @code{fpr} or @code{asa}. You can get
@@ -12036,8 +11743,9 @@ systems which will probably build easily on other systems.
Alternatively, @code{fpr} is in BSD distributions in various archive
sites.
-I think both programs can either be used in a pipeline.
-
+@c (Can both programs can be used in a pipeline,
+@c with a named input file,
+@c and/or with a named output file???)
@node ENCODE and DECODE
@subsection @code{ENCODE} and @code{DECODE}
@@ -12096,6 +11804,30 @@ with:
It is entirely possible that @code{ENCODE} and @code{DECODE} will
be supported by a future version of @code{g77}.
+@node AUTOMATIC Statement
+@subsection @code{AUTOMATIC} Statement
+@cindex @code{AUTOMATIC} statement
+@cindex statements, @code{AUTOMATIC}
+@cindex automatic variables
+@cindex variables, automatic
+
+@code{g77} doesn't support the @code{AUTOMATIC} keyword that
+@code{f2c} does.
+
+It is not yet clear exactly what this statement would achieve.
+The semantic equivalent would be provided by @code{RECURSIVE}
+combined with lack of @code{SAVE}.
+In that sense, perhaps all it would provide is an
+overriding of an unadorned (blanket) @code{SAVE} statement
+for specific variables.
+
+It might also serve as a hint to the compiler that placing
+even a very large array on the stack is acceptable.
+
+Perhaps it should disallow @code{DATA}
+or other specification of any initial values
+for affected variables as well.
+
@node Suppressing Space Padding
@subsection Suppressing Space Padding of Source Lines
@@ -12142,18 +11874,18 @@ files included via the @code{INCLUDE} directive.
@node Bit Operations on Floating-point Data
@subsection Bit Operations on Floating-point Data
-@cindex AND intrinsic
-@cindex intrinsics, AND
-@cindex OR intrinsic
-@cindex intrinsics, OR
-@cindex SHIFT intrinsic
-@cindex intrinsics, SHIFT
+@cindex @code{And} intrinsic
+@cindex intrinsics, @code{And}
+@cindex @code{Or} intrinsic
+@cindex intrinsics, @code{Or}
+@cindex @code{Shift} intrinsic
+@cindex intrinsics, @code{Shift}
@code{g77} does not allow @code{REAL} and other non-integral types for
-arguments to intrinsics like @code{AND}, @code{OR}, and @code{SHIFT}.
+arguments to intrinsics like @code{And}, @code{Or}, and @code{Shift}.
For example, this program is rejected by @code{g77}, because
-the intrinsic @code{IAND} does not accept @code{REAL} arguments:
+the intrinsic @code{Iand} does not accept @code{REAL} arguments:
@smallexample
DATA A/7.54/, B/9.112/
@@ -12168,8 +11900,8 @@ END
@node Floating-point Exception Handling
@subsection Floating-point Exception Handling
-@cindex floating point exceptions
-@cindex exceptions, floating point
+@cindex floating-point, exceptions
+@cindex exceptions, floating-point
@cindex FPE handling
@cindex NaN values
@@ -12448,6 +12180,7 @@ A number giving the length of the record contents;
@item
the length of record contents again (for backspace).
@end enumerate
+
The record length is of C type
@code{long}; this means that it is 8 bytes on 64-bit systems such as
Alpha GNU/Linux and 4 bytes on other systems, such as x86 GNU/Linux.
@@ -12467,7 +12200,7 @@ written.
Thus for exchanging a sequential or direct access unformatted file
between big- and little-endian 32-bit systems using IEEE 754 floating
point it would be sufficient to reverse the bytes in consecutive words
-in the file @emph{iff} only @code{REAL*4}, @code{COMPLEX},
+in the file if, and @emph{only} if, only @code{REAL*4}, @code{COMPLEX},
@code{INTEGER*4} and/or @code{LOGICAL*4} data have been written to it by
@code{g77}.
@@ -12516,7 +12249,7 @@ way around them for now.
@cindex external names
@cindex common blocks
@cindex name space
-@cindex underscores
+@cindex underscore
The current external-interface design, which includes naming of
external procedures, COMMON blocks, and the library interface,
@@ -12536,8 +12269,8 @@ with popular existing compilers.
@cindex block data
@cindex BLOCK DATA statement
@cindex statements, BLOCK DATA
-@cindex COMMON statement
-@cindex statements, COMMON
+@cindex @code{COMMON} statement
+@cindex statements, @code{COMMON}
@cindex naming conflicts
@code{g77} doesn't allow a common block and an external procedure or
@@ -12599,8 +12332,8 @@ we do not make because we think GNU Fortran is better without them.
@node Backslash in Constants
@subsection Backslash in Constants
@cindex backslash
-@cindex f77 support
-@cindex support, f77
+@cindex @code{f77} support
+@cindex support, @code{f77}
In the opinion of many experienced Fortran users,
@samp{-fno-backslash} should be the default, not @samp{-fbackslash},
@@ -13015,7 +12748,7 @@ warnings.
Each kind has a different purpose:
@itemize @w{}
-@item
+@item
@emph{Errors} report problems that make it impossible to compile your
program.
GNU Fortran reports errors with the source file name, line
@@ -13100,7 +12833,7 @@ Bug reports are your contribution to the maintenance of GNU Fortran.
Since the maintainers are very overloaded, we cannot respond to every
bug report.
However, if the bug has not been fixed, we are likely to
-send you a patch and ask you to tell us whether it works.
+send you a patch and ask you to tell us whether it works.
In order for a bug report to serve its purpose, you must include the
information that makes for fixing the bug.
@@ -13409,24 +13142,32 @@ the bug in the current version of GNU Fortran.
@cindex preprocessor
@cindex cpp program
@cindex programs, cpp
+@pindex cpp
A complete input file that will reproduce the bug.
-If the bug is in the compiler proper (@file{f771}) and
-you are using the C preprocessor, run your
-source file through the C preprocessor by doing @samp{g77 -E
-@var{sourcefile} > @var{outfile}}, then include the contents of
-@var{outfile} in the bug report. (When you do this, use the same
-@samp{-I}, @samp{-D} or @samp{-U} options that you used in actual
+
+If your source file(s) require preprocessing
+(for example, their names have suffixes like
+@samp{.F}, @samp{.fpp}, @samp{.FPP}, and @samp{.r}),
+and the bug is in the compiler proper (@file{f771})
+or in a subsequent phase of processing,
+run your source file through the C preprocessor
+by doing @samp{g77 -E @var{sourcefile} > @var{newfile}}.
+Then, include the contents of @var{newfile} in the bug report.
+(When you do this, use the same preprocessor options---such as
+@samp{-I}, @samp{-D}, and @samp{-U}---that you used in actual
compilation.)
A single statement is not enough of an example.
In order to compile it,
-it must be embedded in a complete file of compiler input; and the bug
-might depend on the details of how this is done.
+it must be embedded in a complete file of compiler input.
+The bug might depend on the details of how this is done.
-Without a real example one can compile, all anyone can do about your bug
-report is wish you luck. It would be futile to try to guess how to
-provoke the bug. For example, bugs in register allocation and reloading
-frequently depend on every little detail of the function they happen in.
+Without a real example one can compile,
+all anyone can do about your bug report is wish you luck.
+It would be futile to try to guess how to provoke the bug.
+For example, bugs in register allocation and reloading
+can depend on every little detail of the source and include files
+that trigger them.
@item
@cindex included files
@@ -14120,8 +13861,16 @@ It is not worth repeating them here.
@item
@cindex concatenation
@cindex CHARACTER*(*)
+@cindex run-time, dynamic allocation
Support arbitrary operands for concatenation, even in contexts where
run-time allocation is required.
+For example:
+
+@smallexample
+SUBROUTINE X(A)
+CHARACTER*(*) A
+CALL FOO(A // 'suffix')
+@end smallexample
@item
Consider adding a @code{NUMERIC} type to designate typeless numeric constants,
@@ -14400,6 +14149,7 @@ as the above is just a sample, no such section exists.
* LEX:: Various lexer messages
* GLOBALS:: Disagreements about globals.
* LINKFAIL:: When linking @samp{f771} fails.
+* Y2KBAD:: Use of non-Y2K-compliant intrinsic.
@end menu
@node CMPAMBIG
@@ -14571,7 +14321,6 @@ The following sample program might help:
PROGRAM JCB003
C
C Written by James Craig Burley 1997-02-23.
-C Contact via Internet email: burley@@gnu.org
C
C Determine how compilers handle non-standard REAL
C and AIMAG on DOUBLE COMPLEX operands.
@@ -14747,6 +14496,8 @@ was not specified on the command line to compile it.
Free form is a newer form for Fortran code.
The older, classic form is called fixed form.
+@cindex continuation character
+@cindex characters, continuation
Fixed-form code is visually fairly distinctive, because
numerical labels and comments are all that appear in
the first five columns of a line, the sixth column is
@@ -14755,8 +14506,15 @@ and actual statements start at or beyond column 7.
Spaces generally are not significant, so if you
see statements such as @samp{REALX,Y} and @samp{DO10I=1,100},
you are looking at fixed-form code.
+@cindex *
+@cindex asterisk
Comment lines are indicated by the letter @samp{C} or the symbol
@samp{*} in column 1.
+@cindex trailing comment
+@cindex comment
+@cindex characters, comment
+@cindex !
+@cindex exclamation point
(Some code uses @samp{!} or @samp{/*} to begin in-line comments,
which many compilers support.)
@@ -14822,15 +14580,24 @@ A source file containing lines beginning with @code{#define},
@code{#include}, @code{#if}, and so on is likely one that
requires preprocessing.
-If the file's suffix is @samp{.f} or @samp{.for}, the file
-will normally be compiled @emph{without} preprocessing by @code{g77}.
+If the file's suffix is @samp{.f}, @samp{.for}, or @samp{.FOR},
+the file normally will be compiled @emph{without} preprocessing
+by @code{g77}.
-Change the file's suffix from @samp{.f} to @samp{.F} (or, on
-systems with case-insensitive file names, to @samp{.fpp}) or
-from @samp{.for} to @samp{.fpp}.
+Change the file's suffix from @samp{.f} to @samp{.F}
+(or, on systems with case-insensitive file names,
+to @samp{.fpp} or @samp{.FPP}),
+from @samp{.for} to @samp{.fpp},
+or from @samp{.FOR} to @samp{.FPP}.
@code{g77} compiles files with such names @emph{with}
preprocessing.
+@pindex cpp
+@cindex preprocessor
+@cindex cpp program
+@cindex programs, cpp
+@cindex @samp{-x f77-cpp-input} option
+@cindex options, @samp{-x f77-cpp-input}
Or, learn how to use @code{gcc}'s @samp{-x} option to specify
the language @samp{f77-cpp-input} for Fortran files that
require preprocessing.
@@ -14865,29 +14632,54 @@ Argument #@var{n} of @var{name} is @dots{}
@end smallexample
These messages all identify disagreements about the
-global procedure named @var{name} among different program
-units (usually including @var{name} itself).
-
-These disagreements, if not diagnosed, could result in a
-compiler crash if the compiler attempted to inline a reference
-to @var{name} within a calling program unit that disagreed
-with the @var{name} program unit regarding whether the
-procedure is a subroutine or function, the type of the
-return value of the procedure (if it is a function), the
-number of arguments the procedure accepts, or the type
-of each argument.
-
-Such disagreements @emph{should} be fixed in the Fortran
-code itself.
-However, if that is not immediately practical, and the code
-has been working for some time, it is possible it will work
-when compiled by @code{g77} with the @samp{-fno-globals} option.
-
-The @samp{-fno-globals} option disables these diagnostics, and
-also disables all inlining of references to global procedures
-to avoid compiler crashes.
-The diagnostics are actually produced, but as warnings, unless
-the @samp{-Wno-globals} option also is specified.
+global procedure named @var{name} among different program units
+(usually including @var{name} itself).
+
+Whether a particular disagreement is reported
+as a warning or an error
+can depend on the relative order
+of the disagreeing portions of the source file.
+
+Disagreements between a procedure invocation
+and the @emph{subsequent} procedure itself
+are, usually, diagnosed as errors
+when the procedure itself @emph{precedes} the invocation.
+Other disagreements are diagnosed via warnings.
+
+@cindex forward references
+@cindex in-line code
+@cindex compilation, in-line
+This distinction, between warnings and errors,
+is due primarily to the present tendency of the @code{gcc} back end
+to inline only those procedure invocations that are
+@emph{preceded} by the corresponding procedure definitions.
+If the @code{gcc} back end is changed
+to inline ``forward references'',
+in which invocations precede definitions,
+the @code{g77} front end will be changed
+to treat both orderings as errors, accordingly.
+
+The sorts of disagreements that are diagnosed by @code{g77} include
+whether a procedure is a subroutine or function;
+if it is a function, the type of the return value of the procedure;
+the number of arguments the procedure accepts;
+and the type of each argument.
+
+Disagreements regarding global names among program units
+in a Fortran program @emph{should} be fixed in the code itself.
+However, if that is not immediately practical,
+and the code has been working for some time,
+it is possible it will work
+when compiled with the @samp{-fno-globals} option.
+
+The @samp{-fno-globals} option
+causes these diagnostics to all be warnings
+and disables all inlining of references to global procedures
+(to avoid subsequent compiler crashes and bad-code generation).
+Use of the @samp{-Wno-globals} option as well as @samp{-fno-globals}
+suppresses all of these diagnostics.
+(@samp{-Wno-globals} by itself disables only the warnings,
+not the errors.)
After using @samp{-fno-globals} to work around these problems,
it is wise to stop using that option and address them by fixing
@@ -14929,6 +14721,24 @@ might solve this problem, e.g.@: by adding
BOOT_CFLAGS='-mminimal-toc -O2 -g'
@end smallexample
to the @code{make bootstrap} command line.
+
+@node Y2KBAD
+@section @code{Y2KBAD}
+@cindex Y2K compliance
+@cindex Year 2000 compliance
+
+@noindent
+@smallexample
+Intrinsic `@var{name}', invoked at (^), known to be non-Y2K-compliant@dots{}
+@end smallexample
+
+This diagnostic indicates that
+the specific intrinsic invoked by the name @var{name}
+is known to have an interface
+that is not Year-2000 (Y2K) compliant.
+
+@xref{Year 2000 (Y2K) Problems}.
+
@end ifset
@node Index
diff --git a/gcc/f/g77install.texi b/gcc/f/g77install.texi
index 70411078f83..c73fc06c62a 100644
--- a/gcc/f/g77install.texi
+++ b/gcc/f/g77install.texi
@@ -1,13 +1,35 @@
-@c Copyright (C) 1995-1997 Free Software Foundation, Inc.
+@c Copyright (C) 1995-1999 Free Software Foundation, Inc.
@c This is part of the G77 manual.
@c For copying conditions, see the file g77.texi.
@c The text of this file appears in the file INSTALL
@c in the G77 distribution, as well as in the G77 manual.
-@c 1998-07-13
+@c Keep this the same as the dates above, since it's used
+@c in the standalone derivations of this file (e.g. INSTALL).
+@set copyrights 1995-1999
+
+@set last-update-install 1999-03-13
+
+@include root.texi
+
+@ifset DOC-INSTALL
+@c The immediately following lines apply to the INSTALL file
+@c which is generated using this file.
+@emph{Note:} This file is automatically generated from the files
+@file{install0.texi} and @file{g77install.texi}.
+@file{INSTALL} is @emph{not} a source file,
+although it is normally included within source distributions.
+
+This file contains installation information for the GNU Fortran compiler.
+Copyright (C) @value{copyrights-install} Free Software Foundation, Inc.
+You may copy, distribute, and modify it freely as long as you preserve
+this copyright notice and permission notice.
+
+@node Top,,, (dir)
+@chapter Installing GNU Fortran
+@end ifset
-@set version-g77 0.5.24
@set version-gcc 2.8.1
@set version-autoconf 2.12
@set version-bison 1.25
@@ -20,20 +42,32 @@
@set version-tar 1.12
@set version-texinfo 3.12
-@ifclear INSTALLONLY
+@ifset DOC-G77
@node Installation
@chapter Installing GNU Fortran
-@end ifclear
-@cindex installing GNU Fortran
+@cindex installing, GNU Fortran
+@end ifset
The following information describes how to install @code{g77}.
+@ifset EGCS-G77
+@set OMIT-FSF-G77
Note that, for @code{egcs} users,
-much of this information is obsolete,
+much of the information is obsolete,
and is superceded by the
@code{egcs} installation procedures.
-Such information is explicitly flagged as such.
+Such information is accordingly omitted and flagged as such.
+@ifset DEVELOPMENT
+@ifclear DOC-INSTALL
+@clear OMIT-FSF-G77
+(It is not actually omitted from the development version of this documentation,
+so the @code{g77} developers can easily find all the documentation
+for all versions of @code{g77} in one place.)
+@end ifclear
+@end ifset
+@end ifset
+@ifclear OMIT-FSF-G77
The information in this file generally pertains to dealing
with @emph{source} distributions of @code{g77} and @code{gcc}.
It is possible that some of this information will be applicable
@@ -45,6 +79,25 @@ whoever built and first distributed them.
Nevertheless, efforts to make @code{g77} easier to both build
and install from source and package up as a binary distribution
are ongoing.
+@end ifclear
+
+@ifset DEVELOPMENT
+@emph{Warning:} The information below is still under development,
+and might not accurately reflect the @code{g77} code base
+of which it is a part.
+Efforts are made to keep it somewhat up-to-date,
+but they are particularly concentrated
+on any version of this information
+that is distributed as part of a @emph{released} @code{g77}.
+
+In particular, while this information is intended to apply to
+the @value{which-g77} version of @code{g77},
+only an official @emph{release} of that version
+is expected to contain documentation that is
+most consistent with the @code{g77} product in that version.
+@end ifset
+
+The following information was last updated on @value{last-update-install}:
@menu
* Prerequisites:: Make sure your system is ready for @code{g77}.
@@ -59,10 +112,12 @@ are ongoing.
@section Prerequisites
@cindex prerequisites
-@emph{Version info:}
-For @code{egcs} users, the following information is
+@ifset EGCS-G77
+For @code{egcs} users, this information is
superceded by the @code{egcs} installation instructions.
+@end ifset
+@ifclear OMIT-FSF-G77
The procedures described to unpack, configure, build, and
install @code{g77} assume your system has certain programs
already installed.
@@ -338,6 +393,8 @@ instead of the entire @file{.tar.gz} distribution
to rebuild derived files, such as @code{makeinfo}).
@end table
+@end ifclear
+
@node Problems Installing
@section Problems Installing
@cindex problems installing
@@ -385,7 +442,7 @@ so there are no plans for an interim fix.
This requirement does not mean you must already have @code{gcc}
installed to build @code{g77}.
As long as you have a working C compiler, you can use a
-bootstrap build to automate the process of first building
+``bootstrap'' build to automate the process of first building
@code{gcc} using the working C compiler you have, then building
@code{g77} and rebuilding @code{gcc} using that just-built @code{gcc},
and so on.
@@ -403,7 +460,7 @@ and @code{egcs} version 1.0.
@node Building GNU CC Necessary
@subsubsection Building GNU CC Necessary
-@cindex gcc, building
+@cindex @code{gcc}, building
@cindex building gcc
It should be possible to build the runtime without building @code{cc1}
@@ -420,15 +477,17 @@ is not yet established.
@cindex undefined reference (_strtoul)
@cindex f771, linking error for
@cindex linking error for f771
-@cindex ld error for f771
-@cindex ld can't find _bsearch
-@cindex ld can't find _strtoul
+@cindex @code{ld}, error linking f771
+@cindex @code{ld}, can't find _bsearch
+@cindex @code{ld}, can't find _strtoul
@cindex SunOS4
-@emph{Version info:}
-The following information does not apply to the
+@ifset EGCS-G77
+This information does not apply to the
@code{egcs} version of @code{g77}.
+@end ifset
+@ifclear OMIT-FSF-G77
On SunOS4 systems, linking the @code{f771} program used to
produce an error message concerning an undefined symbol named
@samp{_strtoul}, because the @samp{strtoul} library function
@@ -443,7 +502,7 @@ but every attempt at this has failed for at least one kind of system.
To limit the failures to those few systems actually missing the
required routines, the bare-bones versions are still provided,
-in @file{gcc/f/proj.c},
+in @file{@value{path-g77}/proj.c},
if the appropriate macros are defined.
These are @code{NEED_BSEARCH} for @samp{bsearch} and
@code{NEED_STRTOUL} for @samp{NEED_STRTOUL}.
@@ -451,7 +510,7 @@ These are @code{NEED_BSEARCH} for @samp{bsearch} and
Therefore, if you are sure your system is missing
@code{bsearch} or @code{strtoul} in its library,
define the relevant macro(s) before building @code{g77}.
-This can be done by editing @file{gcc/f/proj.c} and inserting
+This can be done by editing @file{@value{path-g77}/proj.c} and inserting
either or both of the following @samp{#define} statements
before the comment shown:
@@ -470,15 +529,17 @@ To build with the bundled @code{cc} on SunOS4, for example, try:
make bootstrap BOOT_CFLAGS='-O2 -g -DNEED_STRTOUL'
@end smallexample
-If you then encounter problems compiling @file{gcc/f/proj.c},
+If you then encounter problems compiling @file{@value{path-g77}/proj.c},
it might be due to a discrepancy between how @samp{bsearch}
or @samp{strtoul} are defined by that file and how they're
declared by your system's header files.
In that case, you'll have to use some basic knowledge of C
-to work around the problem, perhaps by editing @file{gcc/f/proj.c}
+to work around the problem, perhaps by editing @file{@value{path-g77}/proj.c}
somewhat.
+@end ifclear
+
@node Cleanup Kills Stage Directories
@subsubsection Cleanup Kills Stage Directories
@cindex stage directories
@@ -532,7 +593,9 @@ be fixed in a future version of @code{gcc}.
A linker bug on some versions of AIX 4.1 might prevent building
when @code{g77} is built within @code{gcc}.
It might also occur when building within @code{egcs}.
+@ifset DOC-G77
@xref{LINKFAIL}.
+@end ifset
@node Cross-compiler Problems
@subsection Cross-compiler Problems
@@ -597,7 +660,7 @@ system, depending on the systems involved in the configuration.
@section Changing Settings Before Building
Here are some internal @code{g77} settings that can be changed
-by editing source files in @file{gcc/f/} before building.
+by editing source files in @file{@value{path-g77}/} before building.
This information, and perhaps even these settings, represent
stop-gap solutions to problems people doing various ports
@@ -637,7 +700,7 @@ the use of unit numbers higher than 99, you can change the
value of the @samp{MXUNIT} macro, which represents the maximum unit
number, to an appropriately higher value.
-To do this, edit the file @file{f/runtime/libI77/fio.h} in your
+To do this, edit the file @file{@value{path-libf2c}/libI77/fio.h} in your
@code{g77} source tree, changing the following line:
@example
@@ -703,7 +766,7 @@ modify the @code{g77} source tree so that the version of
@code{libg2c} is built with the @samp{ALWAYS_FLUSH} macro
defined, enabling this behavior.
-To do this, find this line in @file{f/runtime/f2c.h} in
+To do this, find this line in @file{@value{path-libf2c}/f2c.h} in
your @code{g77} source tree:
@example
@@ -721,11 +784,11 @@ Then build or rebuild @code{g77} as appropriate.
@vindex FFECOM_sizeMAXSTACKITEM
@cindex code, stack variables
@cindex maximum stackable size
-@cindex stack allocation
+@cindex stack, allocation
@cindex segmentation violation
@code{g77}, on most machines, puts many variables and arrays on the stack
where possible, and can be configured (by changing
-@samp{FFECOM_sizeMAXSTACKITEM} in @file{gcc/f/com.c}) to force
+@samp{FFECOM_sizeMAXSTACKITEM} in @file{@value{path-g77}/com.c}) to force
smaller-sized entities into static storage (saving
on stack space) or permit larger-sized entities to be put on the
stack (which can improve run-time performance, as it presents
@@ -758,7 +821,7 @@ something like @samp{EQUIVALENCE (I,R)} and @samp{DATA R/9.43578/}.)
@node Large Initialization
@subsection Initialization of Large Aggregate Areas
-@cindex speed, compiler
+@cindex speed, of compiler
@cindex slow compiler
@cindex memory utilization
@cindex large initialization
@@ -773,7 +836,7 @@ a factor of 10.
This size currently is quite small, since @code{g77}
currently has a known bug requiring too much memory
and time to handle such cases.
-In @file{gcc/f/data.c}, the macro
+In @file{@value{path-g77}/data.c}, the macro
@samp{FFEDATA_sizeTOO_BIG_INIT_} is defined
to the minimum size for the warning to appear.
The size is specified in storage units,
@@ -827,10 +890,12 @@ systems.
@section Quick Start
@cindex quick start
-@emph{Version info:}
-For @code{egcs} users, the following information is
+@ifset EGCS-G77
+For @code{egcs} users, this information is
superceded by the @code{egcs} installation instructions.
+@end ifset
+@ifclear OMIT-FSF-G77
This procedure configures, builds, and installs @code{g77}
``out of the box'' and works on most UNIX systems.
Each command is identified by a unique number,
@@ -1108,13 +1173,17 @@ around anymore.
Removing them can free up a lot of disk space.
@end table
+@end ifclear
+
@node Complete Installation
@section Complete Installation
-@emph{Version info:}
-For @code{egcs} users, the following information is
-mostly superceded by the @code{egcs} installation instructions.
+@ifset EGCS-G77
+For @code{egcs} users, this information is
+superceded by the @code{egcs} installation instructions.
+@end ifset
+@ifclear OMIT-FSF-G77
Here is the complete @code{g77}-specific information on how
to configure, build, and install @code{g77}.
@@ -1209,7 +1278,7 @@ tree for the first time.
@cindex modifying @code{g77}
@cindex code, modifying
@cindex Pentium optimizations
-@cindex optimizations, Pentium
+@cindex optimization, for Pentium
@emph{Note:} Please use @strong{only} @code{gcc} and @code{g77}
source trees as distributed by the FSF.
Use of modified versions is likely to result in problems that appear to be
@@ -1223,16 +1292,16 @@ and @code{gcc} can coexist as they do in the stock FSF distributions.
@node Merging Distributions
@subsection Merging Distributions
@cindex merging distributions
-@cindex @code{gcc} versions supported by @code{g77}
-@cindex versions of @code{gcc}
-@cindex support for @code{gcc} versions
+@cindex @code{gcc}, versions supported by @code{g77}
+@cindex versions, of @code{gcc}
+@cindex support, @code{gcc} versions
After merging the @code{g77} source tree into the @code{gcc} source tree,
you have put together a complete @code{g77} source tree.
-@cindex gcc version numbering
-@cindex version numbering
-@cindex g77 version number
+@cindex @code{gcc}, version number
+@cindex version number
+@cindex @code{g77}, version number
@cindex GNU version numbering
As of version 0.5.23, @code{g77} no longer modifies
the version number of @code{gcc},
@@ -1266,7 +1335,7 @@ the directories they create.)
If your version of @code{gcc} is older than the oldest version
supported by @code{g77}
-(as casually determined by listing the contents of @file{gcc/f/INSTALL/},
+(as casually determined by listing the contents of @file{@value{path-g77}/INSTALL/},
which contains these installation instructions in plain-text format),
you should obtain a newer, supported version of @code{gcc}.
(You could instead obtain an older version of @code{g77},
@@ -1291,9 +1360,7 @@ it is likely that @file{gcc-2.8.2} would work well with @code{g77}.
However, @file{gcc-2.9.0} would almost certainly
not work with that version of @code{g77}
without appropriate modifications,
-so a new version of @code{g77} would be needed (and you should
-wait for it rather than bothering the maintainers---@pxref{Changes,,
-User-Visible Changes}).
+so a new version of @code{g77} would be needed.
@cindex distributions, why separate
@cindex separate distributions
@@ -1310,7 +1377,7 @@ and such changes require corresponding changes to
the @code{g77} front end (FFE).
@c @pindex config-lang.in
-@c @emph{Note:} @code{g77}'s configuration file @file{gcc/f/config-lang.in}
+@c @emph{Note:} @code{g77}'s configuration file @file{@value{path-g77}/config-lang.in}
@c sometimes ensures that the source code for the version of @code{gcc}
@c being configured has at least one indication of being an appropriate
@c version as required specifically by @code{g77}.
@@ -1325,7 +1392,7 @@ the @code{g77} front end (FFE).
@node Where to Install
@subsection Where in the World Does Fortran (and GNU CC) Go?
@cindex language f77 not recognized
-@cindex gcc will not compile Fortran programs
+@cindex @code{gcc}, will not compile Fortran programs
Before configuring, you should make sure you know
where you want the @code{g77} and @code{gcc}
@@ -1470,7 +1537,7 @@ issuing an explanatory diagnostic.
@cindex building @code{gcc}
@cindex building @code{g77}
-@vindex LANGUAGES
+@cindex @samp{LANGUAGES} macro
Building @code{g77} requires building enough of @code{gcc} that
these instructions assume you're going to build all of
@code{gcc}, including @code{g++}, @code{protoize}, and so on.
@@ -1903,7 +1970,7 @@ do @emph{not} do @samp{make maintainer-clean}, and, to ensure that
type these commands:
@example
-sh# @kbd{cd gcc/f/runtime}
+sh# @kbd{cd @value{path-libf2c}}
sh# @kbd{touch configure libU77/configure}
sh# @kbd{cd ../../..}
sh#
@@ -1974,11 +2041,19 @@ sh# @kbd{cd ..}
sh#
@end example
+@end ifclear
+
@node Distributing Binaries
@section Distributing Binaries
@cindex binaries, distributing
@cindex code, distributing
+@ifset EGCS-G77
+For @code{egcs} users, this information is
+superceded by the @code{egcs} installation instructions.
+@end ifset
+
+@ifclear OMIT-FSF-G77
If you are building @code{g77} for distribution to others in binary form,
first make sure you are aware of your legal responsibilities (read
the file @file{gcc/COPYING} thoroughly).
@@ -2097,7 +2172,7 @@ If it is not included, users will have trouble understanding
diagnostics messages and other such things, and will send
you a lot of email asking questions.
-Please edit this documentation (by editing @file{gcc/f/*.texi}
+Please edit this documentation (by editing @file{@value{path-g77}/*.texi}
and doing @samp{make doc} from the @file{/usr/src/gcc} directory)
to reflect any changes you've made to @code{g77}, or at
least to encourage users of your binary distribution to
@@ -2168,3 +2243,5 @@ and distributions, about which nothing could be done for the
user.
Once you are quite certain a bug report does not involve
your efforts, you can forward it to us.
+
+@end ifclear
diff --git a/gcc/f/g77spec.c b/gcc/f/g77spec.c
index 79d36379a71..3cc2ac7724c 100644
--- a/gcc/f/g77spec.c
+++ b/gcc/f/g77spec.c
@@ -46,7 +46,6 @@ Boston, MA 02111-1307, USA. */
#include "config.h"
#include "system.h"
-#include "gansidecl.h"
#include <f/version.h>
#ifndef MATH_LIBRARY
@@ -93,8 +92,6 @@ static void (*g77_fn)();
static int g77_newargc;
static char **g77_newargv;
-extern char *xmalloc PROTO((size_t));
-
extern char *version_string;
/* --- This comes from gcc.c (2.8.1) verbatim: */
diff --git a/gcc/f/glimits.j b/gcc/f/glimits.j
index 5bf37928672..b12daeba195 100644
--- a/gcc/f/glimits.j
+++ b/gcc/f/glimits.j
@@ -1 +1,2 @@
Contributed by James Craig Burley (burley@gnu.org).
+ Contributed by James Craig Burley.
diff --git a/gcc/f/global.c b/gcc/f/global.c
index 8be7d0c4c66..85311f18601 100644
--- a/gcc/f/global.c
+++ b/gcc/f/global.c
@@ -1,6 +1,6 @@
/* global.c -- Implementation File (module.c template V1.0)
Copyright (C) 1995, 1997 Free Software Foundation, Inc.
- Contributed by James Craig Burley (burley@gnu.org).
+ Contributed by James Craig Burley.
This file is part of GNU Fortran.
@@ -60,7 +60,7 @@ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#if FFEGLOBAL_ENABLED
static ffenameSpace ffeglobal_filewide_ = NULL;
-static char *ffeglobal_type_string_[] =
+static const char *ffeglobal_type_string_[] =
{
[FFEGLOBAL_typeNONE] "??",
[FFEGLOBAL_typeMAIN] "main program",
@@ -86,7 +86,7 @@ static char *ffeglobal_type_string_[] =
#if FFEGLOBAL_ENABLED
void
-ffeglobal_drive (ffeglobal (*fn) ())
+ffeglobal_drive (ffeglobal (*fn) (ffeglobal))
{
if (ffeglobal_filewide_ != NULL)
ffename_space_drive_global (ffeglobal_filewide_, fn);
@@ -181,6 +181,7 @@ ffeglobal_init_common (ffesymbol s, ffelexToken t)
{
if (g->u.common.blank)
{
+ /* Not supposed to initialize blank common, though it works. */
ffebad_start (FFEBAD_COMMON_BLANK_INIT);
ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t));
ffebad_finish ();
@@ -229,10 +230,13 @@ ffeglobal_new_common (ffesymbol s, ffelexToken t, bool blank)
{
if (g->type == FFEGLOBAL_typeCOMMON)
{
+ /* The names match, so the "blankness" should match too! */
assert (g->u.common.blank == blank);
}
else
{
+ /* This global name has already been established,
+ but as something other than a common block. */
if (ffe_is_globals () || ffe_is_warn_globals ())
{
ffebad_start (ffe_is_globals ()
@@ -258,6 +262,10 @@ ffeglobal_new_common (ffesymbol s, ffelexToken t, bool blank)
&& !g->explicit_intrinsic
&& ffe_is_warn_globals ())
{
+ /* Common name previously used as intrinsic. Though it works,
+ warn, because the intrinsic reference might have been intended
+ as a ref to an external procedure, but g77's vast list of
+ intrinsics happened to snarf the name. */
ffebad_start (FFEBAD_INTRINSIC_GLOBAL);
ffebad_string (ffelex_token_text (t));
ffebad_string ("common block");
@@ -308,6 +316,7 @@ ffeglobal_new_progunit_ (ffesymbol s, ffelexToken t, ffeglobalType type)
|| (g->type == FFEGLOBAL_typeBDATA))
&& g->u.proc.defined)
{
+ /* This program unit has already been defined. */
if (ffe_is_globals () || ffe_is_warn_globals ())
{
ffebad_start (ffe_is_globals ()
@@ -327,6 +336,13 @@ ffeglobal_new_progunit_ (ffesymbol s, ffelexToken t, ffeglobalType type)
&& (g->type != FFEGLOBAL_typeEXT)
&& (g->type != type))
{
+ /* A reference to this program unit has been seen, but its
+ context disagrees about the new definition regarding
+ what kind of program unit it is. (E.g. `call foo' followed
+ by `function foo'.) But `external foo' alone doesn't mean
+ disagreement with either a function or subroutine, though
+ g77 normally interprets it as a request to force-load
+ a block data program unit by that name (to cope with libs). */
if (ffe_is_globals () || ffe_is_warn_globals ())
{
ffebad_start (ffe_is_globals ()
@@ -353,11 +369,16 @@ ffeglobal_new_progunit_ (ffesymbol s, ffelexToken t, ffeglobalType type)
g->u.proc.other_t = NULL;
}
else if ((ffesymbol_basictype (s) != FFEINFO_basictypeNONE)
+ && (g->type == FFEGLOBAL_typeFUNC)
&& ((ffesymbol_basictype (s) != g->u.proc.bt)
|| (ffesymbol_kindtype (s) != g->u.proc.kt)
|| ((ffesymbol_size (s) != FFETARGET_charactersizeNONE)
&& (ffesymbol_size (s) != g->u.proc.sz))))
{
+ /* The previous reference and this new function definition
+ disagree about the type of the function. I (Burley) think
+ this rarely occurs, because when this code is reached,
+ the type info doesn't appear to be filled in yet. */
if (ffe_is_globals () || ffe_is_warn_globals ())
{
ffebad_start (ffe_is_globals ()
@@ -377,6 +398,10 @@ ffeglobal_new_progunit_ (ffesymbol s, ffelexToken t, ffeglobalType type)
&& !g->explicit_intrinsic
&& ffe_is_warn_globals ())
{
+ /* This name, previously used as an intrinsic, now is known
+ to also be a global procedure name. Warn, since the previous
+ use as an intrinsic might have been intended to refer to
+ this procedure. */
ffebad_start (FFEBAD_INTRINSIC_GLOBAL);
ffebad_string (ffelex_token_text (t));
ffebad_string ("global");
@@ -395,10 +420,12 @@ ffeglobal_new_progunit_ (ffesymbol s, ffelexToken t, ffeglobalType type)
g->u.proc.kt = ffesymbol_kindtype (s);
g->u.proc.sz = ffesymbol_size (s);
}
- g->tick = ffe_count_2;
+ /* If there's a known disagreement about the kind of program
+ unit, then don't even bother tracking arglist argreement. */
if ((g->tick != 0)
&& (g->type != type))
g->u.proc.n_args = -1;
+ g->tick = ffe_count_2;
g->type = type;
g->u.proc.defined = TRUE;
}
@@ -487,7 +514,7 @@ ffeglobal_pad_common (ffesymbol s, ffetargetAlign pad, ffewhereLine wl,
/* Collect info for a global's argument. */
void
-ffeglobal_proc_def_arg (ffesymbol s, int argno, char *name, ffeglobalArgSummary as,
+ffeglobal_proc_def_arg (ffesymbol s, int argno, const char *name, ffeglobalArgSummary as,
ffeinfoBasictype bt, ffeinfoKindtype kt,
bool array)
{
@@ -511,8 +538,8 @@ ffeglobal_proc_def_arg (ffesymbol s, int argno, char *name, ffeglobalArgSummary
if ((ai->t != NULL)
&& ffe_is_warn_globals ())
{
- char *refwhy = NULL;
- char *defwhy = NULL;
+ const char *refwhy = NULL;
+ const char *defwhy = NULL;
bool warn = FALSE;
switch (as)
@@ -789,8 +816,8 @@ ffeglobal_proc_ref_arg (ffesymbol s, int argno, ffeglobalArgSummary as,
if (ai->t != NULL)
{
- char *refwhy = NULL;
- char *defwhy = NULL;
+ const char *refwhy = NULL;
+ const char *defwhy = NULL;
bool fail = FALSE;
bool warn = FALSE;
@@ -1160,6 +1187,10 @@ ffeglobal_ref_intrinsic (ffesymbol s, ffelexToken t, bool explicit)
&& ! g->intrinsic
&& ffe_is_warn_globals ())
{
+ /* This name, previously used as a global, now is used
+ for an intrinsic. Warn, since this new use as an
+ intrinsic might have been intended to refer to
+ the global procedure. */
ffebad_start (FFEBAD_INTRINSIC_GLOBAL);
ffebad_string (ffelex_token_text (t));
ffebad_string ("intrinsic");
@@ -1186,6 +1217,11 @@ ffeglobal_ref_intrinsic (ffesymbol s, ffelexToken t, bool explicit)
&& (g->tick != ffe_count_2)
&& ffe_is_warn_globals ())
{
+ /* An earlier reference to this intrinsic disagrees with
+ this reference vis-a-vis explicit `intrinsic foo',
+ which suggests that the one relying on implicit
+ intrinsicacity might have actually intended to refer
+ to a global of the same name. */
ffebad_start (FFEBAD_INTRINSIC_EXPIMP);
ffebad_string (ffelex_token_text (t));
ffebad_string (explicit ? "explicit" : "implicit");
@@ -1235,10 +1271,13 @@ ffeglobal_ref_progunit_ (ffesymbol s, ffelexToken t, ffeglobalType type)
if ((g != NULL)
&& (g->type != FFEGLOBAL_typeNONE)
- && (g->type != type)
&& (g->type != FFEGLOBAL_typeEXT)
+ && (g->type != type)
&& (type != FFEGLOBAL_typeEXT))
{
+ /* Disagreement about (fully refined) class of program unit
+ (main, subroutine, function, block data). Treat EXTERNAL/
+ COMMON disagreements distinctly. */
if ((((type == FFEGLOBAL_typeBDATA)
&& (g->type != FFEGLOBAL_typeCOMMON))
|| ((g->type == FFEGLOBAL_typeBDATA)
@@ -1248,6 +1287,7 @@ ffeglobal_ref_progunit_ (ffesymbol s, ffelexToken t, ffeglobalType type)
#if 0 /* This is likely to just annoy people. */
if (ffe_is_warn_globals ())
{
+ /* Warn about EXTERNAL of a COMMON name, though it works. */
ffebad_start (FFEBAD_FILEWIDE_TIFF);
ffebad_string (ffelex_token_text (t));
ffebad_string (ffeglobal_type_string_[type]);
@@ -1260,23 +1300,11 @@ ffeglobal_ref_progunit_ (ffesymbol s, ffelexToken t, ffeglobalType type)
}
#endif
}
- else if (ffe_is_globals ())
+ else if (ffe_is_globals () || ffe_is_warn_globals ())
{
- ffebad_start (FFEBAD_FILEWIDE_DISAGREEMENT);
- ffebad_string (ffelex_token_text (t));
- ffebad_string (ffeglobal_type_string_[type]);
- ffebad_string (ffeglobal_type_string_[g->type]);
- ffebad_here (0, ffelex_token_where_line (t),
- ffelex_token_where_column (t));
- ffebad_here (1, ffelex_token_where_line (g->t),
- ffelex_token_where_column (g->t));
- ffebad_finish ();
- g->type = FFEGLOBAL_typeANY;
- return FALSE;
- }
- else if (ffe_is_warn_globals ())
- {
- ffebad_start (FFEBAD_FILEWIDE_DISAGREEMENT_W);
+ ffebad_start (ffe_is_globals ()
+ ? FFEBAD_FILEWIDE_DISAGREEMENT
+ : FFEBAD_FILEWIDE_DISAGREEMENT_W);
ffebad_string (ffelex_token_text (t));
ffebad_string (ffeglobal_type_string_[type]);
ffebad_string (ffeglobal_type_string_[g->type]);
@@ -1286,7 +1314,7 @@ ffeglobal_ref_progunit_ (ffesymbol s, ffelexToken t, ffeglobalType type)
ffelex_token_where_column (g->t));
ffebad_finish ();
g->type = FFEGLOBAL_typeANY;
- return TRUE;
+ return (! ffe_is_globals ());
}
}
@@ -1302,39 +1330,65 @@ ffeglobal_ref_progunit_ (ffesymbol s, ffelexToken t, ffeglobalType type)
g->u.proc.kt = ffesymbol_kindtype (s);
g->u.proc.sz = ffesymbol_size (s);
}
- /* Else, make sure there is type agreement. */
- else if ((g->u.proc.bt != FFEINFO_basictypeNONE)
- && (ffesymbol_basictype (s) != FFEINFO_basictypeNONE)
- && ((ffesymbol_basictype (s) != g->u.proc.bt)
- || (ffesymbol_kindtype (s) != g->u.proc.kt)
- || ((ffesymbol_size (s) != g->u.proc.sz)
- && g->u.proc.defined
- && (g->u.proc.sz != FFETARGET_charactersizeNONE))))
+ /* Make sure there is type agreement. */
+ if (g->type == FFEGLOBAL_typeFUNC
+ && g->u.proc.bt != FFEINFO_basictypeNONE
+ && ffesymbol_basictype (s) != FFEINFO_basictypeNONE
+ && (ffesymbol_basictype (s) != g->u.proc.bt
+ || ffesymbol_kindtype (s) != g->u.proc.kt
+ /* CHARACTER*n disagreements matter only once a
+ definition is involved, since the definition might
+ be CHARACTER*(*), which accepts all references. */
+ || (g->u.proc.defined
+ && ffesymbol_size (s) != g->u.proc.sz
+ && ffesymbol_size (s) != FFETARGET_charactersizeNONE
+ && g->u.proc.sz != FFETARGET_charactersizeNONE)))
{
- if (ffe_is_globals ())
+ int error;
+
+ /* Type mismatch between function reference/definition and
+ this subsequent reference (which might just be the filling-in
+ of type info for the definition, but we can't reach here
+ if that's the case and there was a previous definition).
+
+ It's an error given a previous definition, since that
+ implies inlining can crash the compiler, unless the user
+ asked for no such inlining. */
+ error = (g->tick != ffe_count_2
+ && g->u.proc.defined
+ && ffe_is_globals ());
+ if (error || ffe_is_warn_globals ())
{
- ffebad_start (FFEBAD_FILEWIDE_TYPE_MISMATCH);
+ ffebad_start (error
+ ? FFEBAD_FILEWIDE_TYPE_MISMATCH
+ : FFEBAD_FILEWIDE_TYPE_MISMATCH_W);
ffebad_string (ffelex_token_text (t));
- ffebad_here (0, ffelex_token_where_line (t),
- ffelex_token_where_column (t));
- ffebad_here (1, ffelex_token_where_line (g->t),
- ffelex_token_where_column (g->t));
+ if (g->tick == ffe_count_2)
+ {
+ /* Current reference fills in type info for definition.
+ The current token doesn't necessarily point to the actual
+ definition of the function, so use the definition pointer
+ and the pointer to the pre-definition type info. */
+ ffebad_here (0, ffelex_token_where_line (g->t),
+ ffelex_token_where_column (g->t));
+ ffebad_here (1, ffelex_token_where_line (g->u.proc.other_t),
+ ffelex_token_where_column (g->u.proc.other_t));
+ }
+ else
+ {
+ /* Current reference is not a filling-in of a current
+ definition. The current token is fine, as is
+ the previous-mention token. */
+ ffebad_here (0, ffelex_token_where_line (t),
+ ffelex_token_where_column (t));
+ ffebad_here (1, ffelex_token_where_line (g->t),
+ ffelex_token_where_column (g->t));
+ }
ffebad_finish ();
- g->type = FFEGLOBAL_typeANY;
+ if (error)
+ g->type = FFEGLOBAL_typeANY;
return FALSE;
}
- if (ffe_is_warn_globals ())
- {
- ffebad_start (FFEBAD_FILEWIDE_TYPE_MISMATCH_W);
- ffebad_string (ffelex_token_text (t));
- ffebad_here (0, ffelex_token_where_line (t),
- ffelex_token_where_column (t));
- ffebad_here (1, ffelex_token_where_line (g->t),
- ffelex_token_where_column (g->t));
- ffebad_finish ();
- }
- g->type = FFEGLOBAL_typeANY;
- return TRUE;
}
}
@@ -1357,6 +1411,9 @@ ffeglobal_ref_progunit_ (ffesymbol s, ffelexToken t, ffeglobalType type)
&& (g->tick != ffe_count_2)
&& ffe_is_warn_globals ())
{
+ /* Now known as a global, this name previously was seen as an
+ intrinsic. Warn, in case the previous reference was intended
+ for the same global. */
ffebad_start (FFEBAD_INTRINSIC_GLOBAL);
ffebad_string (ffelex_token_text (t));
ffebad_string ("global");
diff --git a/gcc/f/global.h b/gcc/f/global.h
index 38cf8d55cfc..eaf99214b8c 100644
--- a/gcc/f/global.h
+++ b/gcc/f/global.h
@@ -1,6 +1,6 @@
/* global.h -- Public #include File (module.h template V1.0)
Copyright (C) 1995, 1997 Free Software Foundation, Inc.
- Contributed by James Craig Burley (burley@gnu.org).
+ Contributed by James Craig Burley.
This file is part of GNU Fortran.
@@ -128,14 +128,14 @@ struct _ffeglobal_
/* Declare functions with prototypes. */
-void ffeglobal_drive (ffeglobal (*fn) ());
+void ffeglobal_drive (ffeglobal (*fn) (ffeglobal));
void ffeglobal_init_1 (void);
void ffeglobal_init_common (ffesymbol s, ffelexToken t);
void ffeglobal_new_progunit_ (ffesymbol s, ffelexToken t, ffeglobalType type);
void ffeglobal_new_common (ffesymbol s, ffelexToken t, bool blank);
void ffeglobal_pad_common (ffesymbol s, ffetargetAlign pad, ffewhereLine wl,
ffewhereColumn wc);
-void ffeglobal_proc_def_arg (ffesymbol s, int argno, char *name, ffeglobalArgSummary as,
+void ffeglobal_proc_def_arg (ffesymbol s, int argno, const char *name, ffeglobalArgSummary as,
ffeinfoBasictype bt, ffeinfoKindtype kt,
bool array);
void ffeglobal_proc_def_nargs (ffesymbol s, int n_args);
diff --git a/gcc/f/hconfig.j b/gcc/f/hconfig.j
index 5bf37928672..b12daeba195 100644
--- a/gcc/f/hconfig.j
+++ b/gcc/f/hconfig.j
@@ -1 +1,2 @@
Contributed by James Craig Burley (burley@gnu.org).
+ Contributed by James Craig Burley.
diff --git a/gcc/f/implic.c b/gcc/f/implic.c
index 5c721890a21..286a1aa34ca 100644
--- a/gcc/f/implic.c
+++ b/gcc/f/implic.c
@@ -1,2 +1,7 @@
Contributed by James Craig Burley (burley@gnu.org).
if (ISALPHA (c) || (c == '_'))
+ Contributed by James Craig Burley.
+static ffeimplic_ ffeimplic_lookup_ (unsigned char c);
+ffeimplic_lookup_ (unsigned char c)
+ const char *name; // name for s in case it is NULL, or NULL if s never NULL
+ffeimplic_peek_symbol_type (ffesymbol s, const char *name)
diff --git a/gcc/f/implic.h b/gcc/f/implic.h
index 5bf37928672..2f76353a41e 100644
--- a/gcc/f/implic.h
+++ b/gcc/f/implic.h
@@ -1 +1,3 @@
Contributed by James Craig Burley (burley@gnu.org).
+ Contributed by James Craig Burley.
+ffeinfoBasictype ffeimplic_peek_symbol_type (ffesymbol s, const char *name);
diff --git a/gcc/f/info-b.def b/gcc/f/info-b.def
index 5bf37928672..b12daeba195 100644
--- a/gcc/f/info-b.def
+++ b/gcc/f/info-b.def
@@ -1 +1,2 @@
Contributed by James Craig Burley (burley@gnu.org).
+ Contributed by James Craig Burley.
diff --git a/gcc/f/info-k.def b/gcc/f/info-k.def
index 5bf37928672..b12daeba195 100644
--- a/gcc/f/info-k.def
+++ b/gcc/f/info-k.def
@@ -1 +1,2 @@
Contributed by James Craig Burley (burley@gnu.org).
+ Contributed by James Craig Burley.
diff --git a/gcc/f/info-w.def b/gcc/f/info-w.def
index 5bf37928672..b12daeba195 100644
--- a/gcc/f/info-w.def
+++ b/gcc/f/info-w.def
@@ -1 +1,2 @@
Contributed by James Craig Burley (burley@gnu.org).
+ Contributed by James Craig Burley.
diff --git a/gcc/f/info.c b/gcc/f/info.c
index 5bf37928672..cae9d605597 100644
--- a/gcc/f/info.c
+++ b/gcc/f/info.c
@@ -1 +1,12 @@
Contributed by James Craig Burley (burley@gnu.org).
+ Contributed by James Craig Burley.
+static const char *ffeinfo_basictype_string_[]
+static const char *ffeinfo_kind_message_[]
+static const char *ffeinfo_kind_string_[]
+static const char *ffeinfo_kindtype_string_[]
+static const char *ffeinfo_where_string_[]
+const char *
+const char *
+const char *
+const char *
+const char *
diff --git a/gcc/f/info.h b/gcc/f/info.h
index 5bf37928672..577c6476c25 100644
--- a/gcc/f/info.h
+++ b/gcc/f/info.h
@@ -1 +1,7 @@
Contributed by James Craig Burley (burley@gnu.org).
+ Contributed by James Craig Burley.
+const char *ffeinfo_basictype_string (ffeinfoBasictype basictype);
+const char *ffeinfo_kind_message (ffeinfoKind kind);
+const char *ffeinfo_kind_string (ffeinfoKind kind);
+const char *ffeinfo_kindtype_string (ffeinfoKindtype kind_type);
+const char *ffeinfo_where_string (ffeinfoWhere where);
diff --git a/gcc/f/input.j b/gcc/f/input.j
index 5bf37928672..b12daeba195 100644
--- a/gcc/f/input.j
+++ b/gcc/f/input.j
@@ -1 +1,2 @@
Contributed by James Craig Burley (burley@gnu.org).
+ Contributed by James Craig Burley.
diff --git a/gcc/f/install0.texi b/gcc/f/install0.texi
index bbc8ab5c223..44311dd226e 100644
--- a/gcc/f/install0.texi
+++ b/gcc/f/install0.texi
@@ -1,14 +1,9 @@
+\input texinfo @c -*-texinfo-*-
+@c %**start of header
@setfilename INSTALL
-@set INSTALLONLY
+@c %**end of header
-@c The immediately following lines apply to the INSTALL file
-@c which is generated using this file.
-This file contains installation information for the GNU Fortran compiler.
-Copyright (C) 1995, 1996 Free Software Foundation, Inc.
-You may copy, distribute, and modify it freely as long as you preserve
-this copyright notice and permission notice.
-
-@node Top,,, (dir)
-@chapter Installing GNU Fortran
+@c This tells g77install.texi that it's generating just the INSTALL file.
+@set DOC-INSTALL
@include g77install.texi
@bye
diff --git a/gcc/f/intdoc.c b/gcc/f/intdoc.c
index 0ac39ff43ce..917fc2ea808 100644
--- a/gcc/f/intdoc.c
+++ b/gcc/f/intdoc.c
@@ -1,6 +1,6 @@
/* intdoc.c
Copyright (C) 1997 Free Software Foundation, Inc.
- Contributed by James Craig Burley (burley@gnu.org).
+ Contributed by James Craig Burley.
This file is part of GNU Fortran.
@@ -124,11 +124,13 @@ static struct _ffeintrin_name_ names[] = {
#define DEFGEN(CODE,NAME,SPEC1,SPEC2)
#define DEFSPEC(CODE,NAME,CALLABLE,FAMILY,IMP)
#define DEFIMP(CODE,NAME,GFRTDIRECT,GFRTF2C,GFRTGNU,CONTROL)
+#define DEFIMPY(CODE,NAME,GFRTDIRECT,GFRTF2C,GFRTGNU,CONTROL,Y2KBAD)
#include "intrin.def"
#undef DEFNAME
#undef DEFGEN
#undef DEFSPEC
#undef DEFIMP
+#undef DEFIMPY
};
static struct _ffeintrin_gen_ gens[] = {
@@ -137,11 +139,13 @@ static struct _ffeintrin_gen_ gens[] = {
{ NAME, { SPEC1, SPEC2, }, },
#define DEFSPEC(CODE,NAME,CALLABLE,FAMILY,IMP)
#define DEFIMP(CODE,NAME,GFRTDIRECT,GFRTF2C,GFRTGNU,CONTROL)
+#define DEFIMPY(CODE,NAME,GFRTDIRECT,GFRTF2C,GFRTGNU,CONTROL,Y2KBAD)
#include "intrin.def"
#undef DEFNAME
#undef DEFGEN
#undef DEFSPEC
#undef DEFIMP
+#undef DEFIMPY
};
static struct _ffeintrin_imp_ imps[] = {
@@ -151,9 +155,13 @@ static struct _ffeintrin_imp_ imps[] = {
#if 0 /* FFECOM_targetCURRENT == FFECOM_targetGCC */
#define DEFIMP(CODE,NAME,GFRTDIRECT,GFRTF2C,GFRTGNU,CONTROL) \
{ NAME, FFECOM_gfrt ## GFRT, CONTROL },
+#define DEFIMPY(CODE,NAME,GFRTDIRECT,GFRTF2C,GFRTGNU,CONTROL,Y2KBAD) \
+ { NAME, FFECOM_gfrt ## GFRT, CONTROL },
#elif 1 /* FFECOM_targetCURRENT == FFECOM_targetFFE */
#define DEFIMP(CODE,NAME,GFRTDIRECT,GFRTF2C,GFRTGNU,CONTROL) \
{ NAME, CONTROL },
+#define DEFIMPY(CODE,NAME,GFRTDIRECT,GFRTF2C,GFRTGNU,CONTROL,Y2KBAD) \
+ { NAME, CONTROL },
#else
#error
#endif
@@ -162,6 +170,7 @@ static struct _ffeintrin_imp_ imps[] = {
#undef DEFGEN
#undef DEFSPEC
#undef DEFIMP
+#undef DEFIMPY
};
static struct _ffeintrin_spec_ specs[] = {
@@ -170,10 +179,12 @@ static struct _ffeintrin_spec_ specs[] = {
#define DEFSPEC(CODE,NAME,CALLABLE,FAMILY,IMP) \
{ NAME, CALLABLE, FAMILY, IMP, },
#define DEFIMP(CODE,NAME,GFRTDIRECT,GFRTF2C,GFRTGNU,CONTROL)
+#define DEFIMPY(CODE,NAME,GFRTDIRECT,GFRTF2C,GFRTGNU,CONTROL,Y2KBAD)
#include "intrin.def"
#undef DEFGEN
#undef DEFSPEC
#undef DEFIMP
+#undef DEFIMPY
};
struct cc_pair { ffeintrinImp imp; char *text; };
diff --git a/gcc/f/intdoc.in b/gcc/f/intdoc.in
index a0b90ae3907..2027c5a4d7a 100644
--- a/gcc/f/intdoc.in
+++ b/gcc/f/intdoc.in
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997 Free Software Foundation, Inc.
+/* Copyright (C) 1997, 1999 Free Software Foundation, Inc.
* This is part of the G77 manual.
* For copying conditions, see the file g77.texi. */
@@ -285,7 +285,7 @@ be zero.
@xref{Exp Intrinsic}, for the inverse of this function.
-@xref{Log10 Intrinsic}, for the base-10 logarithm function.
+@xref{Log10 Intrinsic}, for the `common' (base-10) logarithm function.
")
DEFDOC (ALOG, "Natural logarithm (archaic).", ARCHAIC (LOG, Log))
@@ -296,19 +296,18 @@ DEFDOC (DLOG, "Natural logarithm (archaic).", ARCHAIC (LOG, Log))
DEFDOC (CDLOG, "Natural logarithm (archaic).", ARCHAIC (LOG, Log))
-DEFDOC (LOG10, "Natural logarithm.", "\
-Returns the natural logarithm of @var{@1@}, which must
-be greater than zero or, if type @code{COMPLEX}, must not
-be zero.
+DEFDOC (LOG10, "Common logarithm.", "\
+Returns the common logarithm (base 10) of @var{@1@}, which must
+be greater than zero.
The inverse of this function is @samp{10. ** LOG10(@var{@1@})}.
@xref{Log Intrinsic}, for the natural logarithm function.
")
-DEFDOC (ALOG10, "Natural logarithm (archaic).", ARCHAIC (LOG10, Log10))
+DEFDOC (ALOG10, "Common logarithm (archaic).", ARCHAIC (LOG10, Log10))
-DEFDOC (DLOG10, "Natural logarithm (archaic).", ARCHAIC (LOG10, Log10))
+DEFDOC (DLOG10, "Common logarithm (archaic).", ARCHAIC (LOG10, Log10))
DEFDOC (MAX, "Maximum value.", "\
Returns the argument with the largest value.
@@ -1060,7 +1059,11 @@ representing the numeric day of the month @var{dd}, a three-character
abbreviation of the month name @var{mmm} and the last two digits of
the year @var{yy}, e.g.@: @samp{25-Nov-96}.
+@cindex Y2K compliance
+@cindex Year 2000 compliance
This intrinsic is not recommended, due to the year 2000 approaching.
+Therefore, programs making use of this intrinsic
+might not be Year 2000 (Y2K) compliant.
@xref{CTime Intrinsic (subroutine)}, for information on obtaining more digits
for the current (or any) date.
")
@@ -1076,6 +1079,16 @@ The functions' value is equal to @samp{@var{@1@}(1) + @var{@1@}(2)}.
Subsequent invocations of @samp{@0@()} return values accumulated since the
previous invocation.
+@cindex wraparound, timings
+@cindex limits, timings
+On some systems, the underlying timings are represented
+using types with sufficiently small limits that overflows
+(wraparounds) are possible, such as 32-bit types.
+Therefore, the values returned by this intrinsic
+might be, or become, negative,
+or numerically less than previous values,
+during a single run of the compiled program.
+
Due to the side effects performed by this intrinsic, the function
form is not recommended.
")
@@ -1091,6 +1104,16 @@ The value of @var{@1@} is equal to @samp{@var{@2@}(1) + @var{@2@}(2)}.
Subsequent invocations of @samp{@0@()} set values based on accumulations
since the previous invocation.
+@cindex wraparound, timings
+@cindex limits, timings
+On some systems, the underlying timings are represented
+using types with sufficiently small limits that overflows
+(wraparounds) are possible, such as 32-bit types.
+Therefore, the values returned by this intrinsic
+might be, or become, negative,
+or numerically less than previous values,
+during a single run of the compiled program.
+
Some non-GNU implementations of Fortran provide this intrinsic as
only a function, not as a subroutine.
")
@@ -1102,6 +1125,16 @@ as the function value,
and the user and system components of this in @samp{@var{@1@}(1)}
and @samp{@var{@1@}(2)} respectively.
The functions' value is equal to @samp{@var{@1@}(1) + @var{@1@}(2)}.
+
+@cindex wraparound, timings
+@cindex limits, timings
+On some systems, the underlying timings are represented
+using types with sufficiently small limits that overflows
+(wraparounds) are possible, such as 32-bit types.
+Therefore, the values returned by this intrinsic
+might be, or become, negative,
+or numerically less than previous values,
+during a single run of the compiled program.
")
DEFDOC (ETIME_subr, "Get elapsed time for process.", "\
@@ -1112,6 +1145,16 @@ and the user and system components of this in @samp{@var{@2@}(1)}
and @samp{@var{@2@}(2)} respectively.
The value of @var{@1@} is equal to @samp{@var{@2@}(1) + @var{@2@}(2)}.
+@cindex wraparound, timings
+@cindex limits, timings
+On some systems, the underlying timings are represented
+using types with sufficiently small limits that overflows
+(wraparounds) are possible, such as 32-bit types.
+Therefore, the values returned by this intrinsic
+might be, or become, negative,
+or numerically less than previous values,
+during a single run of the compiled program.
+
Some non-GNU implementations of Fortran provide this intrinsic as
only a function, not as a subroutine.
")
@@ -1125,6 +1168,17 @@ Equivalent to:
CTIME(TIME8())
@end example
+@cindex Y10K compliance
+@cindex Year 10000 compliance
+@cindex wraparound, Y10K
+@cindex limits, Y10K
+Programs making use of this intrinsic
+might not be Year 10000 (Y10K) compliant.
+For example, the date might appear,
+to such programs, to wrap around
+(change from a larger value to a smaller one)
+as of the Year 10000.
+
@xref{CTime Intrinsic (function)}.
")
@@ -1138,6 +1192,17 @@ Equivalent to:
CALL CTIME(@var{@1@}, TIME8())
@end example
+@cindex Y10K compliance
+@cindex Year 10000 compliance
+@cindex wraparound, Y10K
+@cindex limits, Y10K
+Programs making use of this intrinsic
+might not be Year 10000 (Y10K) compliant.
+For example, the date might appear,
+to such programs, to wrap around
+(change from a larger value to a smaller one)
+as of the Year 10000.
+
@xref{CTime Intrinsic (subroutine)}.
Some non-GNU implementations of Fortran provide this intrinsic as
@@ -1227,6 +1292,17 @@ Fills @var{@1@} with the numerical values at the current local time
of day, month (in the range 1--12), and year in elements 1, 2, and 3,
respectively.
The year has four significant digits.
+
+@cindex Y10K compliance
+@cindex Year 10000 compliance
+@cindex wraparound, Y10K
+@cindex limits, Y10K
+Programs making use of this intrinsic
+might not be Year 10000 (Y10K) compliant.
+For example, the date might appear,
+to such programs, to wrap around
+(change from a larger value to a smaller one)
+as of the Year 10000.
")
DEFDOC (IDATE_vxt, "Get local time info (VAX/VMS).", "\
@@ -1235,7 +1311,20 @@ The month (in the range 1--12) is returned in @var{@1@},
the day (in the range 1--7) in @var{@2@},
and the year in @var{@3@} (in the range 0--99).
+@cindex Y2K compliance
+@cindex Year 2000 compliance
+@cindex wraparound, Y2K
+@cindex limits, Y2K
This intrinsic is not recommended, due to the year 2000 approaching.
+Therefore, programs making use of this intrinsic
+might not be Year 2000 (Y2K) compliant.
+For example, the date might appear,
+to such programs, to wrap around
+(change from a larger value to a smaller one)
+as of the Year 2000.
+
+@xref{IDate Intrinsic (UNIX)}, for information on obtaining more digits
+for the current date.
")
DEFDOC (ITIME, "Get local time of day.", "\
@@ -1247,9 +1336,16 @@ DEFDOC (MCLOCK, "Get number of clock ticks for process.", "\
Returns the number of clock ticks since the start of the process.
Supported on systems with @code{clock(3)} (q.v.).
+@cindex wraparound, timings
+@cindex limits, timings
This intrinsic is not fully portable, such as to systems
with 32-bit @code{INTEGER} types but supporting times
wider than 32 bits.
+Therefore, the values returned by this intrinsic
+might be, or become, negative,
+or numerically less than previous values,
+during a single run of the compiled program.
+
@xref{MClock8 Intrinsic}, for information on a
similar intrinsic that might be portable to more
GNU Fortran implementations, though to fewer
@@ -1263,6 +1359,19 @@ DEFDOC (MCLOCK8, "Get number of clock ticks for process.", "\
Returns the number of clock ticks since the start of the process.
Supported on systems with @code{clock(3)} (q.v.).
+@cindex wraparound, timings
+@cindex limits, timings
+@emph{Warning:} this intrinsic does not increase the range
+of the timing values over that returned by @code{clock(3)}.
+On a system with a 32-bit @code{clock(3)},
+@code{@0@} will return a 32-bit value,
+even though converted to an @samp{INTEGER(KIND=2)} value.
+That means overflows of the 32-bit value can still occur.
+Therefore, the values returned by this intrinsic
+might be, or become, negative,
+or numerically less than previous values,
+during a single run of the compiled program.
+
No Fortran implementations other than GNU Fortran are
known to support this intrinsic at the time of this
writing.
@@ -1277,18 +1386,46 @@ If the system does not support @code{clock(3)},
DEFDOC (SECNDS, "Get local time offset since midnight.", "\
Returns the local time in seconds since midnight minus the value
@var{@1@}.
+
+@cindex wraparound, timings
+@cindex limits, timings
+This values returned by this intrinsic
+become numerically less than previous values
+(they wrap around) during a single run of the
+compiler program, under normal circumstances
+(such as running through the midnight hour).
")
DEFDOC (SECOND_func, "Get CPU time for process in seconds.", "\
Returns the process's runtime in seconds---the same value as the
UNIX function @code{etime} returns.
+
+@cindex wraparound, timings
+@cindex limits, timings
+On some systems, the underlying timings are represented
+using types with sufficiently small limits that overflows
+(wraparounds) are possible, such as 32-bit types.
+Therefore, the values returned by this intrinsic
+might be, or become, negative,
+or numerically less than previous values,
+during a single run of the compiled program.
")
DEFDOC (SECOND_subr, "Get CPU time for process@99@in seconds.", "\
Returns the process's runtime in seconds in @var{@1@}---the same value
as the UNIX function @code{etime} returns.
-This routine is known from Cray Fortran. @xref{CPU_Time Intrinsic}
+@cindex wraparound, timings
+@cindex limits, timings
+On some systems, the underlying timings are represented
+using types with sufficiently small limits that overflows
+(wraparounds) are possible, such as 32-bit types.
+Therefore, the values returned by this intrinsic
+might be, or become, negative,
+or numerically less than previous values,
+during a single run of the compiled program.
+
+This routine is known from Cray Fortran. @xref{CPU_Time Intrinsic},
for a standard equivalent.
")
@@ -1301,12 +1438,32 @@ isn't in general.
@var{@3@} is the maximum value this can take, which isn't very useful
in this implementation since it's just the maximum C @code{unsigned
int} value.
+
+@cindex wraparound, timings
+@cindex limits, timings
+On some systems, the underlying timings are represented
+using types with sufficiently small limits that overflows
+(wraparounds) are possible, such as 32-bit types.
+Therefore, the values returned by this intrinsic
+might be, or become, negative,
+or numerically less than previous values,
+during a single run of the compiled program.
")
DEFDOC (CPU_TIME, "Get current CPU time.", "\
Returns in @var{@1@} the current value of the system time.
This implementation of the Fortran 95 intrinsic is just an alias for
@code{second} @xref{Second Intrinsic (subroutine)}.
+
+@cindex wraparound, timings
+@cindex limits, timings
+On some systems, the underlying timings are represented
+using types with sufficiently small limits that overflows
+(wraparounds) are possible, such as 32-bit types.
+Therefore, the values returned by this intrinsic
+might be, or become, negative,
+or numerically less than previous values,
+during a single run of the compiled program.
")
DEFDOC (TIME8, "Get current time as time value.", "\
@@ -1315,6 +1472,19 @@ Returns the current time encoded as a long integer
This value is suitable for passing to @code{CTIME},
@code{GMTIME}, and @code{LTIME}.
+@cindex wraparound, timings
+@cindex limits, timings
+@emph{Warning:} this intrinsic does not increase the range
+of the timing values over that returned by @code{time(3)}.
+On a system with a 32-bit @code{time(3)},
+@code{@0@} will return a 32-bit value,
+even though converted to an @samp{INTEGER(KIND=2)} value.
+That means overflows of the 32-bit value can still occur.
+Therefore, the values returned by this intrinsic
+might be, or become, negative,
+or numerically less than previous values,
+during a single run of the compiled program.
+
No Fortran implementations other than GNU Fortran are
known to support this intrinsic at the time of this
writing.
@@ -1329,9 +1499,16 @@ Returns the current time encoded as an integer
This value is suitable for passing to @code{CTIME},
@code{GMTIME}, and @code{LTIME}.
+@cindex wraparound, timings
+@cindex limits, timings
This intrinsic is not fully portable, such as to systems
with 32-bit @code{INTEGER} types but supporting times
wider than 32 bits.
+Therefore, the values returned by this intrinsic
+might be, or become, negative,
+or numerically less than previous values,
+during a single run of the compiled program.
+
@xref{Time8 Intrinsic}, for information on a
similar intrinsic that might be portable to more
GNU Fortran implementations, though to fewer
@@ -1538,16 +1715,13 @@ extracted from the @code{stat} structure as returned by
@enumerate
@item
-File mode
+Device ID
@item
Inode number
@item
-ID of device containing directory entry for file
-
-@item
-Device id (if relevant)
+File mode
@item
Number of links
@@ -1559,6 +1733,10 @@ Owner's uid
Owner's gid
@item
+ID of device containing directory entry for file
+(0 if not available)
+
+@item
File size (bytes)
@item
@@ -1571,10 +1749,10 @@ Last modification time
Last file status change time
@item
-Preferred I/O block size
+Preferred I/O block size (-1 if not available)
@item
-Number of blocks allocated
+Number of blocks allocated (-1 if not available)
@end enumerate
Not all these elements are relevant on all systems.
@@ -1592,16 +1770,13 @@ extracted from the @code{stat} structure as returned by
@enumerate
@item
-File mode
+Device ID
@item
Inode number
@item
-ID of device containing directory entry for file
-
-@item
-Device id (if relevant)
+File mode
@item
Number of links
@@ -1613,6 +1788,10 @@ Owner's uid
Owner's gid
@item
+ID of device containing directory entry for file
+(0 if not available)
+
+@item
File size (bytes)
@item
@@ -1625,10 +1804,10 @@ Last modification time
Last file status change time
@item
-Preferred I/O block size
+Preferred I/O block size (-1 if not available)
@item
-Number of blocks allocated
+Number of blocks allocated (-1 if not available)
@end enumerate
Not all these elements are relevant on all systems.
@@ -1656,16 +1835,13 @@ The values in this array are extracted from the
@enumerate
@item
-File mode
+Device ID
@item
Inode number
@item
-ID of device containing directory entry for file
-
-@item
-Device id (if relevant)
+File mode
@item
Number of links
@@ -1677,6 +1853,10 @@ Owner's uid
Owner's gid
@item
+ID of device containing directory entry for file
+(0 if not available)
+
+@item
File size (bytes)
@item
@@ -1689,10 +1869,10 @@ Last modification time
Last file status change time
@item
-Preferred I/O block size
+Preferred I/O block size (-1 if not available)
@item
-Number of blocks allocated
+Number of blocks allocated (-1 if not available)
@end enumerate
Not all these elements are relevant on all systems.
@@ -1716,16 +1896,13 @@ The values in this array are extracted from the
@enumerate
@item
-File mode
+Device ID
@item
Inode number
@item
-ID of device containing directory entry for file
-
-@item
-Device id (if relevant)
+File mode
@item
Number of links
@@ -1737,6 +1914,10 @@ Owner's uid
Owner's gid
@item
+ID of device containing directory entry for file
+(0 if not available)
+
+@item
File size (bytes)
@item
@@ -1749,10 +1930,10 @@ Last modification time
Last file status change time
@item
-Preferred I/O block size
+Preferred I/O block size (-1 if not available)
@item
-Number of blocks allocated
+Number of blocks allocated (-1 if not available)
@end enumerate
Not all these elements are relevant on all systems.
@@ -1778,16 +1959,13 @@ The values in this array are extracted from the
@enumerate
@item
-File mode
+Device ID
@item
Inode number
@item
-ID of device containing directory entry for file
-
-@item
-Device id (if relevant)
+File mode
@item
Number of links
@@ -1799,6 +1977,10 @@ Owner's uid
Owner's gid
@item
+ID of device containing directory entry for file
+(0 if not available)
+
+@item
File size (bytes)
@item
@@ -1811,10 +1993,10 @@ Last modification time
Last file status change time
@item
-Preferred I/O block size
+Preferred I/O block size (-1 if not available)
@item
-Number of blocks allocated
+Number of blocks allocated (-1 if not available)
@end enumerate
Not all these elements are relevant on all systems.
@@ -1834,16 +2016,13 @@ The values in this array are extracted from the
@enumerate
@item
-File mode
+Device ID
@item
Inode number
@item
-ID of device containing directory entry for file
-
-@item
-Device id (if relevant)
+File mode
@item
Number of links
@@ -1855,6 +2034,10 @@ Owner's uid
Owner's gid
@item
+ID of device containing directory entry for file
+(0 if not available)
+
+@item
File size (bytes)
@item
@@ -1867,10 +2050,10 @@ Last modification time
Last file status change time
@item
-Preferred I/O block size
+Preferred I/O block size (-1 if not available)
@item
-Number of blocks allocated
+Number of blocks allocated (-1 if not available)
@end enumerate
Not all these elements are relevant on all systems.
@@ -2396,18 +2579,29 @@ DEFDOC (TIME_vxt, "Get the time as a character value.", "\
Returns in @var{@1@} a character representation of the current time as
obtained from @code{ctime(3)}.
-@xref{Fdate Intrinsic (subroutine)} for an equivalent routine.
+@cindex Y10K compliance
+@cindex Year 10000 compliance
+@cindex wraparound, Y10K
+@cindex limits, Y10K
+Programs making use of this intrinsic
+might not be Year 10000 (Y10K) compliant.
+For example, the date might appear,
+to such programs, to wrap around
+(change from a larger value to a smaller one)
+as of the Year 10000.
+
+@xref{FDate Intrinsic (subroutine)}, for an equivalent routine.
")
DEFDOC (IBCLR, "Clear a bit.", "\
Returns the value of @var{@1@} with bit @var{@2@} cleared (set to
zero).
-@xref{BTest Intrinsic} for information on bit positions.
+@xref{BTest Intrinsic}, for information on bit positions.
")
DEFDOC (IBSET, "Set a bit.", "\
Returns the value of @var{@1@} with bit @var{@2@} set (to one).
-@xref{BTest Intrinsic} for information on bit positions.
+@xref{BTest Intrinsic}, for information on bit positions.
")
DEFDOC (IBITS, "Extract a bit subfield of a variable.", "\
@@ -2429,7 +2623,7 @@ If the absolute value of the shift count is greater than
Bits shifted out from the left end or the right end are lost.
Zeros are shifted in from the opposite end.
-@xref{IShftC Intrinsic} for the circular-shift equivalent.
+@xref{IShftC Intrinsic}, for the circular-shift equivalent.
")
DEFDOC (ISHFTC, "Circular bit shift.", "\
@@ -2445,7 +2639,7 @@ must be less than or equal to @var{@3@}.
The value of @var{@3@} must be greater than or equal to one and less than
or equal to @samp{BIT_SIZE(@var{@1@})}.
-@xref{IShft Intrinsic} for the logical shift equivalent.
+@xref{IShft Intrinsic}, for the logical shift equivalent.
")
DEFDOC (MVBITS, "Moving a bit field.", "\
@@ -2489,10 +2683,22 @@ The difference between local time and UTC (GMT) in the form @var{Shhmm}:
sign, hours and minutes, e.g.@: @samp{-0500} (winter in New York);
@item @4@
The year, month of the year, day of the month, time difference in
-minutes from UTC, hour of the day, minutes of the hour and milliseconds
+minutes from UTC, hour of the day, minutes of the hour, seconds
+of the minute, and milliseconds
of the second in successive values of the array.
@end table
+@cindex Y10K compliance
+@cindex Year 10000 compliance
+@cindex wraparound, Y10K
+@cindex limits, Y10K
+Programs making use of this intrinsic
+might not be Year 10000 (Y10K) compliant.
+For example, the date might appear,
+to such programs, to wrap around
+(change from a larger value to a smaller one)
+as of the Year 10000.
+
On systems where a millisecond timer isn't available, the millisecond
value is returned as zero.
")
diff --git a/gcc/f/intdoc.texi b/gcc/f/intdoc.texi
index 1da381111c2..817124e0a1e 100644
--- a/gcc/f/intdoc.texi
+++ b/gcc/f/intdoc.texi
@@ -46,7 +46,7 @@
@end ifset
@ifset familyF77
* ALog Intrinsic:: Natural logarithm (archaic).
-* ALog10 Intrinsic:: Natural logarithm (archaic).
+* ALog10 Intrinsic:: Common logarithm (archaic).
* AMax0 Intrinsic:: Maximum value (archaic).
* AMax1 Intrinsic:: Maximum value (archaic).
* AMin0 Intrinsic:: Minimum value (archaic).
@@ -240,7 +240,7 @@
@ifset familyF77
* DInt Intrinsic:: Truncate to whole number (archaic).
* DLog Intrinsic:: Natural logarithm (archaic).
-* DLog10 Intrinsic:: Natural logarithm (archaic).
+* DLog10 Intrinsic:: Common logarithm (archaic).
* DMax1 Intrinsic:: Maximum value (archaic).
* DMin1 Intrinsic:: Minimum value (archaic).
* DMod Intrinsic:: Remainder (archaic).
@@ -274,10 +274,10 @@
* DTanH Intrinsic:: Hyperbolic tangent (archaic).
@end ifset
@ifset familyF2U
-* Dtime Intrinsic (subroutine):: Get elapsed time since last time.
+* DTime Intrinsic (subroutine):: Get elapsed time since last time.
@end ifset
@ifset familyBADU77
-* Dtime Intrinsic (function):: Get elapsed time since last time.
+* DTime Intrinsic (function):: Get elapsed time since last time.
@end ifset
@ifset familyF90
* EOShift Intrinsic:: (Reserved for future use.)
@@ -297,8 +297,8 @@
* Exponent Intrinsic:: (Reserved for future use.)
@end ifset
@ifset familyF2U
-* Fdate Intrinsic (subroutine):: Get current time as Day Mon dd hh:mm:ss yyyy.
-* Fdate Intrinsic (function):: Get current time as Day Mon dd hh:mm:ss yyyy.
+* FDate Intrinsic (subroutine):: Get current time as Day Mon dd hh:mm:ss yyyy.
+* FDate Intrinsic (function):: Get current time as Day Mon dd hh:mm:ss yyyy.
* FGet Intrinsic (subroutine):: Read a character from unit 5 stream-wise.
@end ifset
@ifset familyBADU77
@@ -530,7 +530,7 @@
@end ifset
@ifset familyF77
* Log Intrinsic:: Natural logarithm.
-* Log10 Intrinsic:: Natural logarithm.
+* Log10 Intrinsic:: Common logarithm.
@end ifset
@ifset familyF90
* Logical Intrinsic:: (Reserved for future use.)
@@ -2231,7 +2231,7 @@ See @code{chdir(3)}.
@emph{Caution:} Using this routine during I/O to a unit connected with a
non-absolute file name can cause subsequent I/O on such a unit to fail
-because the I/O library may reopen files by name.
+because the I/O library might reopen files by name.
Some non-GNU implementations of Fortran provide this intrinsic as
only a function, not as a subroutine, or do not support the
@@ -2270,7 +2270,7 @@ See @code{chdir(3)}.
@emph{Caution:} Using this routine during I/O to a unit connected with a
non-absolute file name can cause subsequent I/O on such a unit to fail
-because the I/O library may reopen files by name.
+because the I/O library might reopen files by name.
Due to the side effects performed by this intrinsic, the function
form is not recommended.
@@ -2319,7 +2319,7 @@ If the @var{Status} argument is supplied, it contains
Note that this currently works
by actually invoking @code{/bin/chmod} (or the @code{chmod} found when
-the library was configured) and so may fail in some circumstances and
+the library was configured) and so might fail in some circumstances and
will, anyway, be slow.
Some non-GNU implementations of Fortran provide this intrinsic as
@@ -2369,7 +2369,7 @@ Returns 0 on success or a non-zero error code otherwise.
Note that this currently works
by actually invoking @code{/bin/chmod} (or the @code{chmod} found when
-the library was configured) and so may fail in some circumstances and
+the library was configured) and so might fail in some circumstances and
will, anyway, be slow.
Due to the side effects performed by this intrinsic, the function
@@ -2626,6 +2626,16 @@ Returns in @var{Seconds} the current value of the system time.
This implementation of the Fortran 95 intrinsic is just an alias for
@code{second} @xref{Second Intrinsic (subroutine)}.
+@cindex wraparound, timings
+@cindex limits, timings
+On some systems, the underlying timings are represented
+using types with sufficiently small limits that overflows
+(wraparounds) are possible, such as 32-bit types.
+Therefore, the values returned by this intrinsic
+might be, or become, negative,
+or numerically less than previous values,
+during a single run of the compiled program.
+
@node CShift Intrinsic
@subsubsection CShift Intrinsic
@cindex CShift intrinsic
@@ -2966,7 +2976,11 @@ representing the numeric day of the month @var{dd}, a three-character
abbreviation of the month name @var{mmm} and the last two digits of
the year @var{yy}, e.g.@: @samp{25-Nov-96}.
+@cindex Y2K compliance
+@cindex Year 2000 compliance
This intrinsic is not recommended, due to the year 2000 approaching.
+Therefore, programs making use of this intrinsic
+might not be Year 2000 (Y2K) compliant.
@xref{CTime Intrinsic (subroutine)}, for information on obtaining more digits
for the current (or any) date.
@@ -3012,10 +3026,22 @@ The difference between local time and UTC (GMT) in the form @var{Shhmm}:
sign, hours and minutes, e.g.@: @samp{-0500} (winter in New York);
@item Values
The year, month of the year, day of the month, time difference in
-minutes from UTC, hour of the day, minutes of the hour and milliseconds
+minutes from UTC, hour of the day, minutes of the hour, seconds
+of the minute, and milliseconds
of the second in successive values of the array.
@end table
+@cindex Y10K compliance
+@cindex Year 10000 compliance
+@cindex wraparound, Y10K
+@cindex limits, Y10K
+Programs making use of this intrinsic
+might not be Year 10000 (Y10K) compliant.
+For example, the date might appear,
+to such programs, to wrap around
+(change from a larger value to a smaller one)
+as of the Year 10000.
+
On systems where a millisecond timer isn't available, the millisecond
value is returned as zero.
@@ -4087,14 +4113,14 @@ to one type for @var{X}.
@end ifset
@ifset familyF2U
-@node Dtime Intrinsic (subroutine)
-@subsubsection Dtime Intrinsic (subroutine)
-@cindex Dtime intrinsic
-@cindex intrinsics, Dtime
+@node DTime Intrinsic (subroutine)
+@subsubsection DTime Intrinsic (subroutine)
+@cindex DTime intrinsic
+@cindex intrinsics, DTime
@noindent
@example
-CALL Dtime(@var{Result}, @var{TArray})
+CALL DTime(@var{Result}, @var{TArray})
@end example
@noindent
@@ -4119,26 +4145,36 @@ The value of @var{Result} is equal to @samp{@var{TArray}(1) + @var{TArray}(2)}.
Subsequent invocations of @samp{DTIME()} set values based on accumulations
since the previous invocation.
+@cindex wraparound, timings
+@cindex limits, timings
+On some systems, the underlying timings are represented
+using types with sufficiently small limits that overflows
+(wraparounds) are possible, such as 32-bit types.
+Therefore, the values returned by this intrinsic
+might be, or become, negative,
+or numerically less than previous values,
+during a single run of the compiled program.
+
Some non-GNU implementations of Fortran provide this intrinsic as
only a function, not as a subroutine.
For information on other intrinsics with the same name:
-@xref{Dtime Intrinsic (function)}.
+@xref{DTime Intrinsic (function)}.
@end ifset
@ifset familyBADU77
-@node Dtime Intrinsic (function)
-@subsubsection Dtime Intrinsic (function)
-@cindex Dtime intrinsic
-@cindex intrinsics, Dtime
+@node DTime Intrinsic (function)
+@subsubsection DTime Intrinsic (function)
+@cindex DTime intrinsic
+@cindex intrinsics, DTime
@noindent
@example
-Dtime(@var{TArray})
+DTime(@var{TArray})
@end example
@noindent
-Dtime: @code{REAL(KIND=1)} function.
+DTime: @code{REAL(KIND=1)} function.
@noindent
@var{TArray}: @code{REAL(KIND=1)}; DIMENSION(2); INTENT(OUT).
@@ -4159,11 +4195,21 @@ The functions' value is equal to @samp{@var{TArray}(1) + @var{TArray}(2)}.
Subsequent invocations of @samp{DTIME()} return values accumulated since the
previous invocation.
+@cindex wraparound, timings
+@cindex limits, timings
+On some systems, the underlying timings are represented
+using types with sufficiently small limits that overflows
+(wraparounds) are possible, such as 32-bit types.
+Therefore, the values returned by this intrinsic
+might be, or become, negative,
+or numerically less than previous values,
+during a single run of the compiled program.
+
Due to the side effects performed by this intrinsic, the function
form is not recommended.
For information on other intrinsics with the same name:
-@xref{Dtime Intrinsic (subroutine)}.
+@xref{DTime Intrinsic (subroutine)}.
@end ifset
@ifset familyF90
@@ -4237,7 +4283,7 @@ Intrinsic groups: @code{unix}.
Description:
Returns the complementary error function of @var{X}:
-@samp{ERFC(R) = 1 - ERF(R)} (except that the result may be more
+@samp{ERFC(R) = 1 - ERF(R)} (except that the result might be more
accurate than explicitly evaluating that formulae would give).
See @code{erfc(3m)}, which provides the implementation.
@@ -4270,6 +4316,16 @@ and the user and system components of this in @samp{@var{TArray}(1)}
and @samp{@var{TArray}(2)} respectively.
The value of @var{Result} is equal to @samp{@var{TArray}(1) + @var{TArray}(2)}.
+@cindex wraparound, timings
+@cindex limits, timings
+On some systems, the underlying timings are represented
+using types with sufficiently small limits that overflows
+(wraparounds) are possible, such as 32-bit types.
+Therefore, the values returned by this intrinsic
+might be, or become, negative,
+or numerically less than previous values,
+during a single run of the compiled program.
+
Some non-GNU implementations of Fortran provide this intrinsic as
only a function, not as a subroutine.
@@ -4305,6 +4361,16 @@ and the user and system components of this in @samp{@var{TArray}(1)}
and @samp{@var{TArray}(2)} respectively.
The functions' value is equal to @samp{@var{TArray}(1) + @var{TArray}(2)}.
+@cindex wraparound, timings
+@cindex limits, timings
+On some systems, the underlying timings are represented
+using types with sufficiently small limits that overflows
+(wraparounds) are possible, such as 32-bit types.
+Therefore, the values returned by this intrinsic
+might be, or become, negative,
+or numerically less than previous values,
+during a single run of the compiled program.
+
For information on other intrinsics with the same name:
@xref{ETime Intrinsic (subroutine)}.
@@ -4375,14 +4441,14 @@ external procedure.
@end ifset
@ifset familyF2U
-@node Fdate Intrinsic (subroutine)
-@subsubsection Fdate Intrinsic (subroutine)
-@cindex Fdate intrinsic
-@cindex intrinsics, Fdate
+@node FDate Intrinsic (subroutine)
+@subsubsection FDate Intrinsic (subroutine)
+@cindex FDate intrinsic
+@cindex intrinsics, FDate
@noindent
@example
-CALL Fdate(@var{Date})
+CALL FDate(@var{Date})
@end example
@noindent
@@ -4403,26 +4469,37 @@ Equivalent to:
CALL CTIME(@var{Date}, TIME8())
@end example
+@cindex Y10K compliance
+@cindex Year 10000 compliance
+@cindex wraparound, Y10K
+@cindex limits, Y10K
+Programs making use of this intrinsic
+might not be Year 10000 (Y10K) compliant.
+For example, the date might appear,
+to such programs, to wrap around
+(change from a larger value to a smaller one)
+as of the Year 10000.
+
@xref{CTime Intrinsic (subroutine)}.
Some non-GNU implementations of Fortran provide this intrinsic as
only a function, not as a subroutine.
For information on other intrinsics with the same name:
-@xref{Fdate Intrinsic (function)}.
+@xref{FDate Intrinsic (function)}.
-@node Fdate Intrinsic (function)
-@subsubsection Fdate Intrinsic (function)
-@cindex Fdate intrinsic
-@cindex intrinsics, Fdate
+@node FDate Intrinsic (function)
+@subsubsection FDate Intrinsic (function)
+@cindex FDate intrinsic
+@cindex intrinsics, FDate
@noindent
@example
-Fdate()
+FDate()
@end example
@noindent
-Fdate: @code{CHARACTER*(*)} function.
+FDate: @code{CHARACTER*(*)} function.
@noindent
Intrinsic groups: @code{unix}.
@@ -4438,10 +4515,21 @@ Equivalent to:
CTIME(TIME8())
@end example
+@cindex Y10K compliance
+@cindex Year 10000 compliance
+@cindex wraparound, Y10K
+@cindex limits, Y10K
+Programs making use of this intrinsic
+might not be Year 10000 (Y10K) compliant.
+For example, the date might appear,
+to such programs, to wrap around
+(change from a larger value to a smaller one)
+as of the Year 10000.
+
@xref{CTime Intrinsic (function)}.
For information on other intrinsics with the same name:
-@xref{Fdate Intrinsic (subroutine)}.
+@xref{FDate Intrinsic (subroutine)}.
@node FGet Intrinsic (subroutine)
@subsubsection FGet Intrinsic (subroutine)
@@ -4896,10 +4984,10 @@ Intrinsic groups: @code{unix}.
Description:
Attempts to move Fortran unit @var{Unit} to the specified
-@var{Offset}: absolute offset if @var{Offset}=0; relative to the
-current offset if @var{Offset}=1; relative to the end of the file if
-@var{Offset}=2.
-It branches to label @var{Whence} if @var{Unit} is
+@var{Offset}: absolute offset if @var{Whence}=0; relative to the
+current offset if @var{Whence}=1; relative to the end of the file if
+@var{Whence}=2.
+It branches to label @var{ErrLab} if @var{Unit} is
not open or if the call otherwise fails.
@node FStat Intrinsic (subroutine)
@@ -4935,16 +5023,13 @@ extracted from the @code{stat} structure as returned by
@enumerate
@item
-File mode
+Device ID
@item
Inode number
@item
-ID of device containing directory entry for file
-
-@item
-Device id (if relevant)
+File mode
@item
Number of links
@@ -4956,6 +5041,10 @@ Owner's uid
Owner's gid
@item
+ID of device containing directory entry for file
+(0 if not available)
+
+@item
File size (bytes)
@item
@@ -4968,10 +5057,10 @@ Last modification time
Last file status change time
@item
-Preferred I/O block size
+Preferred I/O block size (-1 if not available)
@item
-Number of blocks allocated
+Number of blocks allocated (-1 if not available)
@end enumerate
Not all these elements are relevant on all systems.
@@ -5020,16 +5109,13 @@ extracted from the @code{stat} structure as returned by
@enumerate
@item
-File mode
+Device ID
@item
Inode number
@item
-ID of device containing directory entry for file
-
-@item
-Device id (if relevant)
+File mode
@item
Number of links
@@ -5041,6 +5127,10 @@ Owner's uid
Owner's gid
@item
+ID of device containing directory entry for file
+(0 if not available)
+
+@item
File size (bytes)
@item
@@ -5053,10 +5143,10 @@ Last modification time
Last file status change time
@item
-Preferred I/O block size
+Preferred I/O block size (-1 if not available)
@item
-Number of blocks allocated
+Number of blocks allocated (-1 if not available)
@end enumerate
Not all these elements are relevant on all systems.
@@ -5455,8 +5545,9 @@ only a function, not as a subroutine, or do not support the
(optional) @var{Status} argument.
On some systems (specifically SCO) it might be necessary to link the
-``socket'' library if you call this routine, i.e.@: append
-@samp{-lg2c -lsocket -lm} to the @code{g77} arguments.
+``socket'' library if you call this routine.
+Typically this means adding @samp{-lg2c -lsocket -lm}
+to the @code{g77} command line when linking the program.
For information on other intrinsics with the same name:
@xref{HostNm Intrinsic (function)}.
@@ -5488,8 +5579,9 @@ Fills @var{Name} with the system's host name returned by
(@code{ENOSYS} if the system does not provide @code{gethostname(2)}).
On some systems (specifically SCO) it might be necessary to link the
-``socket'' library if you call this routine, i.e.@: append
-@samp{-lg2c -lsocket -lm} to the @code{g77} arguments.
+``socket'' library if you call this routine.
+Typically this means adding @samp{-lg2c -lsocket -lm}
+to the @code{g77} command line when linking the program.
For information on other intrinsics with the same name:
@xref{HostNm Intrinsic (subroutine)}.
@@ -5652,7 +5744,7 @@ Description:
Returns the value of @var{I} with bit @var{Pos} cleared (set to
zero).
-@xref{BTest Intrinsic} for information on bit positions.
+@xref{BTest Intrinsic}, for information on bit positions.
@node IBits Intrinsic
@subsubsection IBits Intrinsic
@@ -5716,7 +5808,7 @@ Intrinsic groups: @code{mil}, @code{f90}, @code{vxt}.
Description:
Returns the value of @var{I} with bit @var{Pos} set (to one).
-@xref{BTest Intrinsic} for information on bit positions.
+@xref{BTest Intrinsic}, for information on bit positions.
@end ifset
@ifset familyF77
@@ -5806,6 +5898,17 @@ of day, month (in the range 1--12), and year in elements 1, 2, and 3,
respectively.
The year has four significant digits.
+@cindex Y10K compliance
+@cindex Year 10000 compliance
+@cindex wraparound, Y10K
+@cindex limits, Y10K
+Programs making use of this intrinsic
+might not be Year 10000 (Y10K) compliant.
+For example, the date might appear,
+to such programs, to wrap around
+(change from a larger value to a smaller one)
+as of the Year 10000.
+
For information on other intrinsics with the same name:
@xref{IDate Intrinsic (VXT)}.
@@ -5841,7 +5944,20 @@ The month (in the range 1--12) is returned in @var{M},
the day (in the range 1--7) in @var{D},
and the year in @var{Y} (in the range 0--99).
+@cindex Y2K compliance
+@cindex Year 2000 compliance
+@cindex wraparound, Y2K
+@cindex limits, Y2K
This intrinsic is not recommended, due to the year 2000 approaching.
+Therefore, programs making use of this intrinsic
+might not be Year 2000 (Y2K) compliant.
+For example, the date might appear,
+to such programs, to wrap around
+(change from a larger value to a smaller one)
+as of the Year 2000.
+
+@xref{IDate Intrinsic (UNIX)}, for information on obtaining more digits
+for the current date.
For information on other intrinsics with the same name:
@xref{IDate Intrinsic (UNIX)}.
@@ -6598,11 +6714,10 @@ All bits representing @var{I} are shifted @var{Shift} places.
indicates no shift and @samp{@var{Shift}.LT.0} indicates a right shift.
If the absolute value of the shift count is greater than
@samp{BIT_SIZE(@var{I})}, the result is undefined.
-Bits shifted out from the left end or the right end, as the case may be,
-are lost.
+Bits shifted out from the left end or the right end are lost.
Zeros are shifted in from the opposite end.
-@xref{IShftC Intrinsic} for the circular-shift equivalent.
+@xref{IShftC Intrinsic}, for the circular-shift equivalent.
@node IShftC Intrinsic
@subsubsection IShftC Intrinsic
@@ -6644,7 +6759,7 @@ must be less than or equal to @var{Size}.
The value of @var{Size} must be greater than or equal to one and less than
or equal to @samp{BIT_SIZE(@var{I})}.
-@xref{IShft Intrinsic} for the logical shift equivalent.
+@xref{IShft Intrinsic}, for the logical shift equivalent.
@end ifset
@ifset familyF77
@@ -7478,7 +7593,7 @@ be zero.
@xref{Exp Intrinsic}, for the inverse of this function.
-@xref{Log10 Intrinsic}, for the base-10 logarithm function.
+@xref{Log10 Intrinsic}, for the `common' (base-10) logarithm function.
@node Log10 Intrinsic
@subsubsection Log10 Intrinsic
@@ -7502,9 +7617,8 @@ Intrinsic groups: (standard FORTRAN 77).
@noindent
Description:
-Returns the natural logarithm of @var{X}, which must
-be greater than zero or, if type @code{COMPLEX}, must not
-be zero.
+Returns the common logarithm (base 10) of @var{X}, which must
+be greater than zero.
The inverse of this function is @samp{10. ** LOG10(@var{X})}.
@@ -7644,16 +7758,13 @@ The values in this array are extracted from the
@enumerate
@item
-File mode
+Device ID
@item
Inode number
@item
-ID of device containing directory entry for file
-
-@item
-Device id (if relevant)
+File mode
@item
Number of links
@@ -7665,6 +7776,10 @@ Owner's uid
Owner's gid
@item
+ID of device containing directory entry for file
+(0 if not available)
+
+@item
File size (bytes)
@item
@@ -7677,10 +7792,10 @@ Last modification time
Last file status change time
@item
-Preferred I/O block size
+Preferred I/O block size (-1 if not available)
@item
-Number of blocks allocated
+Number of blocks allocated (-1 if not available)
@end enumerate
Not all these elements are relevant on all systems.
@@ -7735,16 +7850,13 @@ The values in this array are extracted from the
@enumerate
@item
-File mode
+Device ID
@item
Inode number
@item
-ID of device containing directory entry for file
-
-@item
-Device id (if relevant)
+File mode
@item
Number of links
@@ -7756,6 +7868,10 @@ Owner's uid
Owner's gid
@item
+ID of device containing directory entry for file
+(0 if not available)
+
+@item
File size (bytes)
@item
@@ -7768,10 +7884,10 @@ Last modification time
Last file status change time
@item
-Preferred I/O block size
+Preferred I/O block size (-1 if not available)
@item
-Number of blocks allocated
+Number of blocks allocated (-1 if not available)
@end enumerate
Not all these elements are relevant on all systems.
@@ -7991,9 +8107,16 @@ Description:
Returns the number of clock ticks since the start of the process.
Supported on systems with @code{clock(3)} (q.v.).
+@cindex wraparound, timings
+@cindex limits, timings
This intrinsic is not fully portable, such as to systems
with 32-bit @code{INTEGER} types but supporting times
wider than 32 bits.
+Therefore, the values returned by this intrinsic
+might be, or become, negative,
+or numerically less than previous values,
+during a single run of the compiled program.
+
@xref{MClock8 Intrinsic}, for information on a
similar intrinsic that might be portable to more
GNU Fortran implementations, though to fewer
@@ -8024,6 +8147,19 @@ Description:
Returns the number of clock ticks since the start of the process.
Supported on systems with @code{clock(3)} (q.v.).
+@cindex wraparound, timings
+@cindex limits, timings
+@emph{Warning:} this intrinsic does not increase the range
+of the timing values over that returned by @code{clock(3)}.
+On a system with a 32-bit @code{clock(3)},
+@code{MCLOCK8} will return a 32-bit value,
+even though converted to an @samp{INTEGER(KIND=2)} value.
+That means overflows of the 32-bit value can still occur.
+Therefore, the values returned by this intrinsic
+might be, or become, negative,
+or numerically less than previous values,
+during a single run of the compiled program.
+
No Fortran implementations other than GNU Fortran are
known to support this intrinsic at the time of this
writing.
@@ -9128,6 +9264,14 @@ Description:
Returns the local time in seconds since midnight minus the value
@var{T}.
+@cindex wraparound, timings
+@cindex limits, timings
+This values returned by this intrinsic
+become numerically less than previous values
+(they wrap around) during a single run of the
+compiler program, under normal circumstances
+(such as running through the midnight hour).
+
@end ifset
@ifset familyF2U
@node Second Intrinsic (function)
@@ -9152,6 +9296,16 @@ Description:
Returns the process's runtime in seconds---the same value as the
UNIX function @code{etime} returns.
+@cindex wraparound, timings
+@cindex limits, timings
+On some systems, the underlying timings are represented
+using types with sufficiently small limits that overflows
+(wraparounds) are possible, such as 32-bit types.
+Therefore, the values returned by this intrinsic
+might be, or become, negative,
+or numerically less than previous values,
+during a single run of the compiled program.
+
For information on other intrinsics with the same name:
@xref{Second Intrinsic (subroutine)}.
@@ -9177,7 +9331,17 @@ Description:
Returns the process's runtime in seconds in @var{Seconds}---the same value
as the UNIX function @code{etime} returns.
-This routine is known from Cray Fortran. @xref{CPU_Time Intrinsic}
+@cindex wraparound, timings
+@cindex limits, timings
+On some systems, the underlying timings are represented
+using types with sufficiently small limits that overflows
+(wraparounds) are possible, such as 32-bit types.
+Therefore, the values returned by this intrinsic
+might be, or become, negative,
+or numerically less than previous values,
+during a single run of the compiled program.
+
+This routine is known from Cray Fortran. @xref{CPU_Time Intrinsic},
for a standard equivalent.
For information on other intrinsics with the same name:
@@ -9723,16 +9887,13 @@ The values in this array are extracted from the
@enumerate
@item
-File mode
+Device ID
@item
Inode number
@item
-ID of device containing directory entry for file
-
-@item
-Device id (if relevant)
+File mode
@item
Number of links
@@ -9744,6 +9905,10 @@ Owner's uid
Owner's gid
@item
+ID of device containing directory entry for file
+(0 if not available)
+
+@item
File size (bytes)
@item
@@ -9756,10 +9921,10 @@ Last modification time
Last file status change time
@item
-Preferred I/O block size
+Preferred I/O block size (-1 if not available)
@item
-Number of blocks allocated
+Number of blocks allocated (-1 if not available)
@end enumerate
Not all these elements are relevant on all systems.
@@ -9810,16 +9975,13 @@ The values in this array are extracted from the
@enumerate
@item
-File mode
+Device ID
@item
Inode number
@item
-ID of device containing directory entry for file
-
-@item
-Device id (if relevant)
+File mode
@item
Number of links
@@ -9831,6 +9993,10 @@ Owner's uid
Owner's gid
@item
+ID of device containing directory entry for file
+(0 if not available)
+
+@item
File size (bytes)
@item
@@ -9843,10 +10009,10 @@ Last modification time
Last file status change time
@item
-Preferred I/O block size
+Preferred I/O block size (-1 if not available)
@item
-Number of blocks allocated
+Number of blocks allocated (-1 if not available)
@end enumerate
Not all these elements are relevant on all systems.
@@ -10071,6 +10237,16 @@ isn't in general.
in this implementation since it's just the maximum C @code{unsigned
int} value.
+@cindex wraparound, timings
+@cindex limits, timings
+On some systems, the underlying timings are represented
+using types with sufficiently small limits that overflows
+(wraparounds) are possible, such as 32-bit types.
+Therefore, the values returned by this intrinsic
+might be, or become, negative,
+or numerically less than previous values,
+during a single run of the compiled program.
+
@end ifset
@ifset familyF77
@node Tan Intrinsic
@@ -10164,9 +10340,16 @@ Returns the current time encoded as an integer
This value is suitable for passing to @code{CTIME},
@code{GMTIME}, and @code{LTIME}.
+@cindex wraparound, timings
+@cindex limits, timings
This intrinsic is not fully portable, such as to systems
with 32-bit @code{INTEGER} types but supporting times
wider than 32 bits.
+Therefore, the values returned by this intrinsic
+might be, or become, negative,
+or numerically less than previous values,
+during a single run of the compiled program.
+
@xref{Time8 Intrinsic}, for information on a
similar intrinsic that might be portable to more
GNU Fortran implementations, though to fewer
@@ -10199,7 +10382,18 @@ Description:
Returns in @var{Time} a character representation of the current time as
obtained from @code{ctime(3)}.
-@xref{Fdate Intrinsic (subroutine)} for an equivalent routine.
+@cindex Y10K compliance
+@cindex Year 10000 compliance
+@cindex wraparound, Y10K
+@cindex limits, Y10K
+Programs making use of this intrinsic
+might not be Year 10000 (Y10K) compliant.
+For example, the date might appear,
+to such programs, to wrap around
+(change from a larger value to a smaller one)
+as of the Year 10000.
+
+@xref{FDate Intrinsic (subroutine)}, for an equivalent routine.
For information on other intrinsics with the same name:
@xref{Time Intrinsic (UNIX)}.
@@ -10230,6 +10424,19 @@ Returns the current time encoded as a long integer
This value is suitable for passing to @code{CTIME},
@code{GMTIME}, and @code{LTIME}.
+@cindex wraparound, timings
+@cindex limits, timings
+@emph{Warning:} this intrinsic does not increase the range
+of the timing values over that returned by @code{time(3)}.
+On a system with a 32-bit @code{time(3)},
+@code{TIME8} will return a 32-bit value,
+even though converted to an @samp{INTEGER(KIND=2)} value.
+That means overflows of the 32-bit value can still occur.
+Therefore, the values returned by this intrinsic
+might be, or become, negative,
+or numerically less than previous values,
+during a single run of the compiled program.
+
No Fortran implementations other than GNU Fortran are
known to support this intrinsic at the time of this
writing.
diff --git a/gcc/f/intrin.c b/gcc/f/intrin.c
index 6e27d210142..dbf375b849f 100644
--- a/gcc/f/intrin.c
+++ b/gcc/f/intrin.c
@@ -1,6 +1,6 @@
/* intrin.c -- Recognize references to intrinsics
Copyright (C) 1995-1998 Free Software Foundation, Inc.
- Contributed by James Craig Burley (burley@gnu.org).
+ Contributed by James Craig Burley.
This file is part of GNU Fortran.
@@ -32,22 +32,22 @@ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
struct _ffeintrin_name_
{
- char *name_uc;
- char *name_lc;
- char *name_ic;
+ const char *name_uc;
+ const char *name_lc;
+ const char *name_ic;
ffeintrinGen generic;
ffeintrinSpec specific;
};
struct _ffeintrin_gen_
{
- char *name; /* Name as seen in program. */
+ const char *name; /* Name as seen in program. */
ffeintrinSpec specs[2];
};
struct _ffeintrin_spec_
{
- char *name; /* Uppercase name as seen in source code,
+ const char *name; /* Uppercase name as seen in source code,
lowercase if no source name, "none" if no
name at all (NONE case). */
bool is_actualarg; /* Ok to pass as actual arg if -pedantic. */
@@ -57,13 +57,14 @@ struct _ffeintrin_spec_
struct _ffeintrin_imp_
{
- char *name; /* Name of implementation. */
+ const char *name; /* Name of implementation. */
#if FFECOM_targetCURRENT == FFECOM_targetGCC
ffecomGfrt gfrt_direct; /* library routine, direct-callable form. */
ffecomGfrt gfrt_f2c; /* library routine, f2c-callable form. */
ffecomGfrt gfrt_gnu; /* library routine, gnu-callable form. */
#endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */
- char *control;
+ const char *control;
+ char y2kbad;
};
static ffebad ffeintrin_check_ (ffeintrinImp imp, ffebldOp op,
@@ -84,11 +85,13 @@ static struct _ffeintrin_name_ ffeintrin_names_[]
#define DEFGEN(CODE,NAME,SPEC1,SPEC2)
#define DEFSPEC(CODE,NAME,CALLABLE,FAMILY,IMP)
#define DEFIMP(CODE,NAME,GFRTDIRECT,GFRTF2C,GFRTGNU,CONTROL)
+#define DEFIMPY(CODE,NAME,GFRTDIRECT,GFRTF2C,GFRTGNU,CONTROL,Y2KBAD)
#include "intrin.def"
#undef DEFNAME
#undef DEFGEN
#undef DEFSPEC
#undef DEFIMP
+#undef DEFIMPY
};
static struct _ffeintrin_gen_ ffeintrin_gens_[]
@@ -99,11 +102,13 @@ static struct _ffeintrin_gen_ ffeintrin_gens_[]
{ NAME, { SPEC1, SPEC2, }, },
#define DEFSPEC(CODE,NAME,CALLABLE,FAMILY,IMP)
#define DEFIMP(CODE,NAME,GFRTDIRECT,GFRTF2C,GFRTGNU,CONTROL)
+#define DEFIMPY(CODE,NAME,GFRTDIRECT,GFRTF2C,GFRTGNU,CONTROL,Y2KBAD)
#include "intrin.def"
#undef DEFNAME
#undef DEFGEN
#undef DEFSPEC
#undef DEFIMP
+#undef DEFIMPY
};
static struct _ffeintrin_imp_ ffeintrin_imps_[]
@@ -115,10 +120,15 @@ static struct _ffeintrin_imp_ ffeintrin_imps_[]
#if FFECOM_targetCURRENT == FFECOM_targetGCC
#define DEFIMP(CODE,NAME,GFRTDIRECT,GFRTF2C,GFRTGNU,CONTROL) \
{ NAME, FFECOM_gfrt ## GFRTDIRECT, FFECOM_gfrt ## GFRTF2C, \
- FFECOM_gfrt ## GFRTGNU, CONTROL },
+ FFECOM_gfrt ## GFRTGNU, CONTROL, FALSE },
+#define DEFIMPY(CODE,NAME,GFRTDIRECT,GFRTF2C,GFRTGNU,CONTROL,Y2KBAD) \
+ { NAME, FFECOM_gfrt ## GFRTDIRECT, FFECOM_gfrt ## GFRTF2C, \
+ FFECOM_gfrt ## GFRTGNU, CONTROL, Y2KBAD },
#elif FFECOM_targetCURRENT == FFECOM_targetFFE
#define DEFIMP(CODE,NAME,GFRTDIRECT,GFRTF2C,GFRTGNU,CONTROL) \
- { NAME, CONTROL },
+ { NAME, CONTROL, FALSE },
+#define DEFIMPY(CODE,NAME,GFRTDIRECT,GFRTF2C,GFRTGNU,CONTROL,Y2KBAD) \
+ { NAME, CONTROL, Y2KBAD },
#else
#error
#endif
@@ -127,6 +137,7 @@ static struct _ffeintrin_imp_ ffeintrin_imps_[]
#undef DEFGEN
#undef DEFSPEC
#undef DEFIMP
+#undef DEFIMPY
};
static struct _ffeintrin_spec_ ffeintrin_specs_[]
@@ -137,10 +148,12 @@ static struct _ffeintrin_spec_ ffeintrin_specs_[]
#define DEFSPEC(CODE,NAME,CALLABLE,FAMILY,IMP) \
{ NAME, CALLABLE, FAMILY, IMP, },
#define DEFIMP(CODE,NAME,GFRTDIRECT,GFRTF2C,GFRTGNU,CONTROL)
+#define DEFIMPY(CODE,NAME,GFRTDIRECT,GFRTF2C,GFRTGNU,CONTROL,Y2KBAD)
#include "intrin.def"
#undef DEFGEN
#undef DEFSPEC
#undef DEFIMP
+#undef DEFIMPY
};
@@ -153,9 +166,9 @@ ffeintrin_check_ (ffeintrinImp imp, ffebldOp op,
ffelexToken t,
bool commit)
{
- char *c = ffeintrin_imps_[imp].control;
+ const char *c = ffeintrin_imps_[imp].control;
bool subr = (c[0] == '-');
- char *argc;
+ const char *argc;
ffebld arg;
ffeinfoBasictype bt;
ffeinfoKindtype kt;
@@ -1152,9 +1165,9 @@ ffeintrin_check_any_ (ffebld arglist)
static int
ffeintrin_cmp_name_ (const void *name, const void *intrinsic)
{
- char *uc = (char *) ((struct _ffeintrin_name_ *) intrinsic)->name_uc;
- char *lc = (char *) ((struct _ffeintrin_name_ *) intrinsic)->name_lc;
- char *ic = (char *) ((struct _ffeintrin_name_ *) intrinsic)->name_ic;
+ const char *uc = ((struct _ffeintrin_name_ *) intrinsic)->name_uc;
+ const char *lc = ((struct _ffeintrin_name_ *) intrinsic)->name_lc;
+ const char *ic = ((struct _ffeintrin_name_ *) intrinsic)->name_ic;
return ffesrc_strcmp_2c (ffe_case_intrin (), name, uc, lc, ic);
}
@@ -1374,6 +1387,14 @@ ffeintrin_fulfill_generic (ffebld *expr, ffeinfo *info, ffelexToken t)
ffebad_string (ffeintrin_gens_[gen].name);
ffebad_finish ();
}
+ if (ffeintrin_imps_[imp].y2kbad)
+ {
+ ffebad_start (FFEBAD_INTRINSIC_Y2KBAD);
+ ffebad_here (0, ffelex_token_where_line (t),
+ ffelex_token_where_column (t));
+ ffebad_string (ffeintrin_gens_[gen].name);
+ ffebad_finish ();
+ }
}
}
@@ -1408,7 +1429,7 @@ ffeintrin_fulfill_specific (ffebld *expr, ffeinfo *info,
ffeIntrinsicState state;
ffebad error;
bool any = FALSE;
- char *name;
+ const char *name;
op = ffebld_op (*expr);
assert ((op == FFEBLD_opFUNCREF) || (op == FFEBLD_opSUBRREF));
@@ -1489,6 +1510,14 @@ ffeintrin_fulfill_specific (ffebld *expr, ffeinfo *info,
ffebad_string (name);
ffebad_finish ();
}
+ if (ffeintrin_imps_[imp].y2kbad)
+ {
+ ffebad_start (FFEBAD_INTRINSIC_Y2KBAD);
+ ffebad_here (0, ffelex_token_where_line (t),
+ ffelex_token_where_column (t));
+ ffebad_string (name);
+ ffebad_finish ();
+ }
}
}
@@ -1522,9 +1551,9 @@ void
ffeintrin_init_0 ()
{
int i;
- char *p1;
- char *p2;
- char *p3;
+ const char *p1;
+ const char *p2;
+ const char *p3;
int colon;
if (!ffe_is_do_internal_checks ())
@@ -1558,8 +1587,9 @@ ffeintrin_init_0 ()
break;
if ((ISDIGIT (*p1) || (*p1 == '_')) && (*p1 == *p2) && (*p1 == *p3))
continue;
- if (! ISUPPER (*p1) || ! ISLOWER (*p2)
- || (*p1 != toupper (*p2)) || ((*p3 != *p1) && (*p3 != *p2)))
+ if (! ISUPPER ((unsigned char)*p1) || ! ISLOWER ((unsigned char)*p2)
+ || (*p1 != toupper ((unsigned char)*p2))
+ || ((*p3 != *p1) && (*p3 != *p2)))
break;
}
assert ((*p1 == *p2) && (*p1 == *p3) && (*p1 == '\0'));
@@ -1567,7 +1597,7 @@ ffeintrin_init_0 ()
for (i = 0; ((size_t) i) < ARRAY_SIZE (ffeintrin_imps_); ++i)
{
- char *c = ffeintrin_imps_[i].control;
+ const char *c = ffeintrin_imps_[i].control;
if (c[0] == '\0')
continue;
@@ -1745,7 +1775,7 @@ ffeintrin_is_actualarg (ffeintrinSpec spec)
/* Determine if name is intrinsic, return info.
- char *name; // C-string name of possible intrinsic.
+ const char *name; // C-string name of possible intrinsic.
ffelexToken t; // NULL if no diagnostic to be given.
bool explicit; // TRUE if INTRINSIC name.
ffeintrinGen gen; // (TRUE only) Generic id of intrinsic.
@@ -1757,7 +1787,7 @@ ffeintrin_is_actualarg (ffeintrinSpec spec)
// kind accordingly. */
bool
-ffeintrin_is_intrinsic (char *name, ffelexToken t, bool explicit,
+ffeintrin_is_intrinsic (const char *name, ffelexToken t, bool explicit,
ffeintrinGen *xgen, ffeintrinSpec *xspec,
ffeintrinImp *ximp)
{
@@ -1968,7 +1998,7 @@ ffeintrin_kindtype (ffeintrinSpec spec)
/* Return name of generic intrinsic. */
-char *
+const char *
ffeintrin_name_generic (ffeintrinGen gen)
{
assert (gen < FFEINTRIN_gen);
@@ -1977,7 +2007,7 @@ ffeintrin_name_generic (ffeintrinGen gen)
/* Return name of intrinsic implementation. */
-char *
+const char *
ffeintrin_name_implementation (ffeintrinImp imp)
{
assert (imp < FFEINTRIN_imp);
@@ -1986,7 +2016,7 @@ ffeintrin_name_implementation (ffeintrinImp imp)
/* Return external/internal name of specific intrinsic. */
-char *
+const char *
ffeintrin_name_specific (ffeintrinSpec spec)
{
assert (spec < FFEINTRIN_spec);
diff --git a/gcc/f/intrin.def b/gcc/f/intrin.def
index 0c00dccfb01..9d9626bc7c2 100644
--- a/gcc/f/intrin.def
+++ b/gcc/f/intrin.def
@@ -133,7 +133,7 @@ DEFNAME ("DSQRT", "dsqrt", "DSqRt", genNONE, specDSQRT)
DEFNAME ("DTAN", "dtan", "DTan", genNONE, specDTAN)
DEFNAME ("DTAND", "dtand", "DTanD", genNONE, specDTAND) /* VXT */
DEFNAME ("DTANH", "dtanh", "DTanH", genNONE, specDTANH)
-DEFNAME ("DTIME", "dtime", "Dtime", genDTIME, specNONE) /* UNIX */
+DEFNAME ("DTIME", "dtime", "DTime", genDTIME, specNONE) /* UNIX */
DEFNAME ("EOSHIFT", "eoshift", "EOShift", genNONE, specEOSHIFT) /* F90 */
DEFNAME ("EPSILON", "epsilon", "Epsilon", genNONE, specEPSILON) /* F90 */
DEFNAME ("ERF", "erf", "ErF", genNONE, specERF) /* UNIX */
@@ -142,7 +142,7 @@ DEFNAME ("ETIME", "etime", "ETime", genETIME, specNONE) /* UNIX */
DEFNAME ("EXIT", "exit", "Exit", genNONE, specEXIT) /* UNIX */
DEFNAME ("EXP", "exp", "Exp", genNONE, specEXP)
DEFNAME ("EXPONENT", "exponent", "Exponent", genNONE, specEXPONENT) /* F90 */
-DEFNAME ("FDATE", "fdate", "Fdate", genFDATE, specNONE) /* UNIX */
+DEFNAME ("FDATE", "fdate", "FDate", genFDATE, specNONE) /* UNIX */
DEFNAME ("FGET", "fget", "FGet", genFGET, specNONE) /* UNIX */
DEFNAME ("FGETC", "fgetc", "FGetC", genFGETC, specNONE) /* UNIX */
DEFNAME ("FLOAT", "float", "Float", genNONE, specFLOAT)
@@ -3006,6 +3006,12 @@ DEFSPEC (NONE,
CONTROL -- A control string, described below.
+ The DEFIMPY macro specifies the above, plus:
+
+ Y2KBAD -- TRUE if the intrinsic is known to be non-Y2K-compliant,
+ FALSE if it is known to be Y2K-compliant. (In terms of
+ interface and libg2c implementation.)
+
*/
/* The control string has the following format:
@@ -3232,7 +3238,7 @@ DEFIMP (COMPLEX, "COMPLEX", ,,, "C=:*:Real=S*,Imag=S*")
DEFIMP (CPU_TIME, "CPU_TIME", SECOND,,, "--:-:Seconds=R*w")
DEFIMP (CTIME_func, "CTIME_func", CTIME,,, "A1*:-:STime=I*")
DEFIMP (CTIME_subr, "CTIME_subr", CTIME,,, "--:-:Result=A1w,STime=I*")
-DEFIMP (DATE, "DATE", DATE,,, "--:-:Date=A1w")
+DEFIMPY (DATE, "DATE", DATE,,, "--:-:Date=A1w", TRUE)
DEFIMP (DATE_AND_TIME, "DATE_AND_TIME", DATE_AND_TIME,,, "--:-:Date=A1w,Time=?A1w,Zone=?A1w,Values=?I1(8)w")
DEFIMP (DBESJ0, "DBESJ0", L_BESJ0,,, "R2:-:X=R2")
DEFIMP (DBESJ1, "DBESJ1", L_BESJ1,,, "R2:-:X=R2")
@@ -3289,7 +3295,7 @@ DEFIMP (IBCLR, "IBCLR", ,,, "I=:0:I=I*,Pos=I*")
DEFIMP (IBITS, "IBITS", ,,, "I=:0:I=I*,Pos=I*,Len=I*")
DEFIMP (IBSET, "IBSET", ,,, "I=:0:I=I*,Pos=I*")
DEFIMP (IDATE_unix, "IDATE_unix", IDATE,,, "--:-:TArray=I1(3)w")
-DEFIMP (IDATE_vxt, "IDATE_vxt", VXTIDATE,,, "--:-:M=I1w,D=I1w,Y=I1w")
+DEFIMPY (IDATE_vxt, "IDATE_vxt", VXTIDATE,,, "--:-:M=I1w,D=I1w,Y=I1w", TRUE)
DEFIMP (IEOR, "IEOR", ,,, "I=:*:I=I*,J=I*")
DEFIMP (IOR, "IOR", ,,, "I=:*:I=I*,J=I*")
DEFIMP (IERRNO, "IERRNO", IERRNO,,, "I1:-:")
diff --git a/gcc/f/intrin.h b/gcc/f/intrin.h
index 0006c8aa7d5..5b8d725da43 100644
--- a/gcc/f/intrin.h
+++ b/gcc/f/intrin.h
@@ -1,6 +1,6 @@
/* intrin.h -- Public interface for intrin.c
Copyright (C) 1995-1997 Free Software Foundation, Inc.
- Contributed by James Craig Burley (burley@gnu.org).
+ Contributed by James Craig Burley.
This file is part of GNU Fortran.
@@ -51,11 +51,13 @@ typedef enum
#define DEFGEN(CODE,NAME,SPEC1,SPEC2) FFEINTRIN_gen ## CODE,
#define DEFSPEC(CODE,NAME,CALLABLE,FAMILY,IMP)
#define DEFIMP(CODE,NAME,GFRTDIRECT,GFRTF2C,GFRTGNU,CONTROL)
+#define DEFIMPY(CODE,NAME,GFRTDIRECT,GFRTF2C,GFRTGNU,CONTROL,Y2KBAD)
#include "intrin.def"
#undef DEFNAME
#undef DEFGEN
#undef DEFSPEC
#undef DEFIMP
+#undef DEFIMPY
FFEINTRIN_gen
} ffeintrinGen;
@@ -65,11 +67,13 @@ typedef enum
#define DEFGEN(CODE,NAME,SPEC1,SPEC2)
#define DEFSPEC(CODE,NAME,CALLABLE,FAMILY,IMP) FFEINTRIN_spec ## CODE,
#define DEFIMP(CODE,NAME,GFRTDIRECT,GFRTF2C,GFRTGNU,CONTROL)
+#define DEFIMPY(CODE,NAME,GFRTDIRECT,GFRTF2C,GFRTGNU,CONTROL,Y2KBAD)
#include "intrin.def"
#undef DEFNAME
#undef DEFGEN
#undef DEFSPEC
#undef DEFIMP
+#undef DEFIMPY
FFEINTRIN_spec
} ffeintrinSpec;
@@ -80,11 +84,14 @@ typedef enum
#define DEFSPEC(CODE,NAME,CALLABLE,FAMILY,IMP)
#define DEFIMP(CODE,NAME,GFRTDIRECT,GFRTF2C,GFRTGNU,CONTROL) \
FFEINTRIN_imp ## CODE,
+#define DEFIMPY(CODE,NAME,GFRTDIRECT,GFRTF2C,GFRTGNU,CONTROL,Y2KBAD) \
+ FFEINTRIN_imp ## CODE,
#include "intrin.def"
#undef DEFNAME
#undef DEFGEN
#undef DEFSPEC
#undef DEFIMP
+#undef DEFIMPY
FFEINTRIN_imp
} ffeintrinImp;
@@ -108,14 +115,14 @@ void ffeintrin_init_0 (void);
#define ffeintrin_init_3()
#define ffeintrin_init_4()
bool ffeintrin_is_actualarg (ffeintrinSpec spec);
-bool ffeintrin_is_intrinsic (char *name, ffelexToken t, bool explicit,
+bool ffeintrin_is_intrinsic (const char *name, ffelexToken t, bool explicit,
ffeintrinGen *gen, ffeintrinSpec *spec,
ffeintrinImp *imp);
bool ffeintrin_is_standard (ffeintrinGen gen, ffeintrinSpec spec);
ffeinfoKindtype ffeintrin_kindtype (ffeintrinSpec spec);
-char *ffeintrin_name_generic (ffeintrinGen gen);
-char *ffeintrin_name_implementation (ffeintrinImp imp);
-char *ffeintrin_name_specific (ffeintrinSpec spec);
+const char *ffeintrin_name_generic (ffeintrinGen gen);
+const char *ffeintrin_name_implementation (ffeintrinImp imp);
+const char *ffeintrin_name_specific (ffeintrinSpec spec);
ffeIntrinsicState ffeintrin_state_family (ffeintrinFamily family);
#define ffeintrin_terminate_0()
#define ffeintrin_terminate_1()
diff --git a/gcc/f/lab.c b/gcc/f/lab.c
index 5bf37928672..b12daeba195 100644
--- a/gcc/f/lab.c
+++ b/gcc/f/lab.c
@@ -1 +1,2 @@
Contributed by James Craig Burley (burley@gnu.org).
+ Contributed by James Craig Burley.
diff --git a/gcc/f/lab.h b/gcc/f/lab.h
index 5bf37928672..b12daeba195 100644
--- a/gcc/f/lab.h
+++ b/gcc/f/lab.h
@@ -1 +1,2 @@
Contributed by James Craig Burley (burley@gnu.org).
+ Contributed by James Craig Burley.
diff --git a/gcc/f/lang-options.h b/gcc/f/lang-options.h
index 0fa927a2156..e1446ddde44 100644
--- a/gcc/f/lang-options.h
+++ b/gcc/f/lang-options.h
@@ -1,6 +1,6 @@
/* lang-options.h file for Fortran
Copyright (C) 1995-1998 Free Software Foundation, Inc.
- Contributed by James Craig Burley (burley@gnu.org).
+ Contributed by James Craig Burley.
This file is part of GNU Fortran.
diff --git a/gcc/f/lang-specs.h b/gcc/f/lang-specs.h
index bf8786febde..ba777ebee92 100644
--- a/gcc/f/lang-specs.h
+++ b/gcc/f/lang-specs.h
@@ -1,6 +1,6 @@
/* lang-specs.h file for Fortran
- Copyright (C) 1995-1997 Free Software Foundation, Inc.
- Contributed by James Craig Burley (burley@gnu.org).
+ Copyright (C) 1995-1997, 1999 Free Software Foundation, Inc.
+ Contributed by James Craig Burley.
This file is part of GNU Fortran.
@@ -26,6 +26,7 @@ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
{".F", {"@f77-cpp-input"}},
{".fpp", {"@f77-cpp-input"}},
+ {".FPP", {"@f77-cpp-input"}},
{"@f77-cpp-input",
/* For f77 we want -traditional to avoid errors with, for
instance, mismatched '. Also, we avoid unpleasant surprises
@@ -41,13 +42,14 @@ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
%{ansi:-trigraphs -$ -D__STRICT_ANSI__}\
%{!undef:%P} -D_LANGUAGE_FORTRAN %{trigraphs} \
%c %{Os:-D__OPTIMIZE_SIZE__} %{O*:%{!O0:-D__OPTIMIZE__}} -traditional\
+ %{ffast-math:-D__FAST_MATH__}\
%{g*} %{W*} %{w} %{pedantic*} %{H} %{d*} %C %{D*} %{U*} %{i*} %Z\
%i %{!M:%{!MM:%{!E:%{!pipe:%g.i}}}}%{E:%W{o*}}%{M:%W{o*}}%{MM:%W{o*}} |\n",
"%{!M:%{!MM:%{!E:f771 %{!pipe:%g.i} %(f771) \
- %{!Q:-quiet} -dumpbase %b.F %{d*} %{m*} %{a}\
+ %{!Q:-quiet} -dumpbase %b.F %{d*} %{m*} %{a*}\
%{g*} %{O*} %{W*} %{w} %{pedantic*} \
%{v:-version -fversion} %{pg:-p} %{p} %{f*} %{I*}\
- %{aux-info*}\
+ %{aux-info*} %{Qn:-fno-ident}\
%{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\
%{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%g.s}} |\n\
%{!S:as %a %Y\
@@ -59,10 +61,10 @@ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
%{C:%{!E:%eGNU C does not support -C without using -E}}\
%{!E:%{!pipe:-o %g.f}}%{E:%W{o*}} %i |\n",
"%{!E:f771 %{!pipe:%g.f} %(f771) \
- %{!Q:-quiet} -dumpbase %b.r %{d*} %{m*} %{a}\
+ %{!Q:-quiet} -dumpbase %b.r %{d*} %{m*} %{a*}\
%{g*} %{O*} %{W*} %{w} %{pedantic*} \
%{v:-version -fversion} %{pg:-p} %{p} %{f*} %{I*}\
- %{aux-info*}\
+ %{aux-info*} %{Qn:-fno-ident}\
%{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\
%{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%g.s}} |\n\
%{!S:as %a %Y\
@@ -70,12 +72,13 @@ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
%{!pipe:%g.s} %A\n }}"}},
{".f", {"@f77"}},
{".for", {"@f77"}},
+ {".FOR", {"@f77"}},
{"@f77",
{"%{!M:%{!MM:%{!E:f771 %i %(f771) \
- %{!Q:-quiet} -dumpbase %b.f %{d*} %{m*} %{a}\
+ %{!Q:-quiet} -dumpbase %b.f %{d*} %{m*} %{a*}\
%{g*} %{O*} %{W*} %{w} %{pedantic*}\
%{v:-version -fversion} %{pg:-p} %{p} %{f*} %{I*}\
- %{aux-info*}\
+ %{aux-info*} %{Qn:-fno-ident}\
%{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\
%{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%g.s}} |\n\
%{!S:as %a %Y\
@@ -89,10 +92,11 @@ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
%{ansi:-trigraphs -$ -D__STRICT_ANSI__} \
%{!undef:%P} -D_LANGUAGE_FORTRAN %{trigraphs} \
%c %{Os:-D__OPTIMIZE_SIZE__} %{O*:%{!O0:-D__OPTIMIZE__}} -traditional \
+ %{ffast-math:-D__FAST_MATH__}\
%{g*} %{W*} %{w} %{pedantic*} %{H} %{d*} %C %{D*} %{U*} %{i*} %Z \
/dev/null /dev/null \n\
f771 -fnull-version %(f771) \
- %{!Q:-quiet} -dumpbase g77-version.f %{d*} %{m*} %{a} \
+ %{!Q:-quiet} -dumpbase g77-version.f %{d*} %{m*} %{a*} \
%{g*} %{O*} %{W*} %{w} %{pedantic*} \
-version -fversion %{f*} %{I*} -o %g.s /dev/null \n\
as %a %Y -o %g%O %g.s %A \n\
diff --git a/gcc/f/lex.c b/gcc/f/lex.c
index c43aa7e05b9..3136d402528 100644
--- a/gcc/f/lex.c
+++ b/gcc/f/lex.c
@@ -1,6 +1,6 @@
/* Implementation of Fortran lexer
Copyright (C) 1995-1998 Free Software Foundation, Inc.
- Contributed by James Craig Burley (burley@gnu.org).
+ Contributed by James Craig Burley.
This file is part of GNU Fortran.
@@ -1243,7 +1243,7 @@ ffelex_hash_ (FILE *finput)
goto skipline;
}
- if (ffe_is_ident ())
+ if (! flag_no_ident)
{
#ifdef ASM_OUTPUT_IDENT
ASM_OUTPUT_IDENT (asm_out_file,
@@ -1751,10 +1751,10 @@ ffelex_token_new_ ()
return t;
}
-static char *
+static const char *
ffelex_type_string_ (ffelexType type)
{
- static char *types[] = {
+ static const char *types[] = {
"FFELEX_typeNONE",
"FFELEX_typeCOMMENT",
"FFELEX_typeEOS",
@@ -4347,7 +4347,7 @@ ffelexHandler
ffelex_splice_tokens (ffelexHandler first, ffelexToken master,
ffeTokenLength start)
{
- char *p;
+ unsigned char *p;
ffeTokenLength i;
ffelexToken t;
@@ -4490,7 +4490,7 @@ ffelex_token_name_from_names (ffelexToken t, ffeTokenLength start,
assert (len > 0);
assert ((start + len) <= t->length);
}
- assert (ffelex_is_firstnamechar (t->text[start]));
+ assert (ffelex_is_firstnamechar ((unsigned char)(t->text[start])));
nt = ffelex_token_new_ ();
nt->type = FFELEX_typeNAME;
@@ -4525,7 +4525,7 @@ ffelex_token_names_from_names (ffelexToken t, ffeTokenLength start,
assert (len > 0);
assert ((start + len) <= t->length);
}
- assert (ffelex_is_firstnamechar (t->text[start]));
+ assert (ffelex_is_firstnamechar ((unsigned char)(t->text[start])));
nt = ffelex_token_new_ ();
nt->type = FFELEX_typeNAMES;
@@ -4546,7 +4546,7 @@ ffelex_token_names_from_names (ffelexToken t, ffeTokenLength start,
/* Make a new CHARACTER token. */
ffelexToken
-ffelex_token_new_character (char *s, ffewhereLine l, ffewhereColumn c)
+ffelex_token_new_character (const char *s, ffewhereLine l, ffewhereColumn c)
{
ffelexToken t;
@@ -4581,11 +4581,11 @@ ffelex_token_new_eof ()
/* Make a new NAME token. */
ffelexToken
-ffelex_token_new_name (char *s, ffewhereLine l, ffewhereColumn c)
+ffelex_token_new_name (const char *s, ffewhereLine l, ffewhereColumn c)
{
ffelexToken t;
- assert (ffelex_is_firstnamechar (*s));
+ assert (ffelex_is_firstnamechar ((unsigned char)*s));
t = ffelex_token_new_ ();
t->type = FFELEX_typeNAME;
@@ -4602,11 +4602,11 @@ ffelex_token_new_name (char *s, ffewhereLine l, ffewhereColumn c)
/* Make a new NAMES token. */
ffelexToken
-ffelex_token_new_names (char *s, ffewhereLine l, ffewhereColumn c)
+ffelex_token_new_names (const char *s, ffewhereLine l, ffewhereColumn c)
{
ffelexToken t;
- assert (ffelex_is_firstnamechar (*s));
+ assert (ffelex_is_firstnamechar ((unsigned char)*s));
t = ffelex_token_new_ ();
t->type = FFELEX_typeNAMES;
@@ -4631,7 +4631,7 @@ ffelex_token_new_names (char *s, ffewhereLine l, ffewhereColumn c)
in the original string. */
ffelexToken
-ffelex_token_new_number (char *s, ffewhereLine l, ffewhereColumn c)
+ffelex_token_new_number (const char *s, ffewhereLine l, ffewhereColumn c)
{
ffelexToken t;
ffeTokenLength len;
diff --git a/gcc/f/lex.h b/gcc/f/lex.h
index b5235f86279..e4d2ba18e70 100644
--- a/gcc/f/lex.h
+++ b/gcc/f/lex.h
@@ -1,2 +1,7 @@
Contributed by James Craig Burley (burley@gnu.org).
(ISALPHA ((c)) || ((c) == '_'))
+ Contributed by James Craig Burley.
+ffelexToken ffelex_token_new_character (const char *s, ffewhereLine l,
+ffelexToken ffelex_token_new_name (const char *s, ffewhereLine l,
+ffelexToken ffelex_token_new_names (const char *s, ffewhereLine l,
+ffelexToken ffelex_token_new_number (const char *s, ffewhereLine l,
diff --git a/gcc/f/malloc.c b/gcc/f/malloc.c
index 456021149ea..b0d31af81ef 100644
--- a/gcc/f/malloc.c
+++ b/gcc/f/malloc.c
@@ -1,6 +1,6 @@
/* malloc.c -- Implementation File (module.c template V1.0)
Copyright (C) 1995 Free Software Foundation, Inc.
- Contributed by James Craig Burley (burley@gnu.org).
+ Contributed by James Craig Burley.
This file is part of GNU Fortran.
@@ -33,10 +33,6 @@ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "proj.h"
#include "malloc.h"
-/* Assume gcc/toplev.o is linked in. */
-void *xmalloc (unsigned size);
-void *xrealloc (void *ptr, int size);
-
/* Externals defined here. */
struct _malloc_root_ malloc_root_
@@ -52,6 +48,8 @@ struct _malloc_root_ malloc_root_
0,
#if MALLOC_DEBUG
0, 0, 0, 0, 0, 0, 0, { '/' }
+#else
+ { 0 }
#endif
},
};
@@ -72,7 +70,7 @@ struct _malloc_root_ malloc_root_
static void *malloc_reserve_ = NULL; /* For crashes. */
#if MALLOC_DEBUG
-static char *malloc_types_[] =
+static const char *malloc_types_[] =
{"KS", "KSR", "NF", "NFR", "US", "USR"};
#endif
@@ -236,7 +234,7 @@ malloc_pool_kill (mallocPool p)
Makes a new pool with the given name and default new-chunk allocation. */
mallocPool
-malloc_pool_new (char *name, mallocPool parent,
+malloc_pool_new (const char *name, mallocPool parent,
unsigned long chunks UNUSED)
{
mallocPool p;
@@ -386,7 +384,7 @@ malloc_new_ (mallocSize s)
add it to the list of mallocArea_s for the pool. */
void *
-malloc_new_inpool_ (mallocPool pool, mallocType_ type, char *name, mallocSize s)
+malloc_new_inpool_ (mallocPool pool, mallocType_ type, const char *name, mallocSize s)
{
void *ptr;
mallocArea_ a;
@@ -439,7 +437,7 @@ malloc_new_inpool_ (mallocPool pool, mallocType_ type, char *name, mallocSize s)
you pass it a 0). */
void *
-malloc_new_zinpool_ (mallocPool pool, mallocType_ type, char *name, mallocSize s,
+malloc_new_zinpool_ (mallocPool pool, mallocType_ type, const char *name, mallocSize s,
int z)
{
void *ptr;
diff --git a/gcc/f/malloc.h b/gcc/f/malloc.h
index 5bf37928672..0655f9c0d61 100644
--- a/gcc/f/malloc.h
+++ b/gcc/f/malloc.h
@@ -1 +1,5 @@
Contributed by James Craig Burley (burley@gnu.org).
+ Contributed by James Craig Burley.
+void *malloc_new_inpool_ (mallocPool pool, mallocType_ type, const char *name,
+void *malloc_new_zinpool_ (mallocPool pool, mallocType_ type, const char *name,
+mallocPool malloc_pool_new (const char *name, mallocPool parent, unsigned long chunks);
diff --git a/gcc/f/name.c b/gcc/f/name.c
index 5bf37928672..ed823afecda 100644
--- a/gcc/f/name.c
+++ b/gcc/f/name.c
@@ -1 +1,4 @@
Contributed by James Craig Burley (burley@gnu.org).
+ Contributed by James Craig Burley.
+ffename_space_drive_global (ffenameSpace ns, ffeglobal (*fn) (ffeglobal))
+ffename_space_drive_symbol (ffenameSpace ns, ffesymbol (*fn) (ffesymbol))
diff --git a/gcc/f/name.h b/gcc/f/name.h
index 5bf37928672..8c3129f0434 100644
--- a/gcc/f/name.h
+++ b/gcc/f/name.h
@@ -1 +1,4 @@
Contributed by James Craig Burley (burley@gnu.org).
+ Contributed by James Craig Burley.
+void ffename_space_drive_global (ffenameSpace ns, ffeglobal (*fn) (ffeglobal));
+void ffename_space_drive_symbol (ffenameSpace ns, ffesymbol (*fn) (ffesymbol));
diff --git a/gcc/f/news.texi b/gcc/f/news.texi
index dea4e6626fa..a5c1e781ce2 100644
--- a/gcc/f/news.texi
+++ b/gcc/f/news.texi
@@ -1,19 +1,65 @@
-@c Copyright (C) 1995-1997 Free Software Foundation, Inc.
+@c Copyright (C) 1995-1999 Free Software Foundation, Inc.
@c This is part of the G77 manual.
@c For copying conditions, see the file g77.texi.
-@c The text of this file appears in the file BUGS
+@c The text of this file appears in the file NEWS
@c in the G77 distribution, as well as in the G77 manual.
-@c 1998-09-04
+@c Keep this the same as the dates above, since it's used
+@c in the standalone derivations of this file (e.g. NEWS).
+@set copyrights-news 1995-1999
-@ifclear NEWSONLY
+@set last-update-news 1999-03-17
+
+@include root.texi
+
+@ifset DOC-NEWS
+@c The immediately following lines apply to the NEWS file
+@c which is derived from this file.
+@emph{Note:} This file is automatically generated from the files
+@file{news0.texi} and @file{news.texi}.
+@file{NEWS} is @emph{not} a source file,
+although it is normally included within source distributions.
+
+This file lists news about the @value{which-g77} version
+(and some other versions) of the GNU Fortran compiler.
+Copyright (C) @value{copyrights-news} Free Software Foundation, Inc.
+You may copy, distribute, and modify it freely as long as you preserve
+this copyright notice and permission notice.
+
+@node Top,,, (dir)
+@chapter News About GNU Fortran
+@end ifset
+
+@ifset DOC-G77
+@ifset USERVISONLY
+@node Changes
+@chapter User-visible Changes
+@cindex versions, recent
+@cindex recent versions
+@cindex changes, user-visible
+@cindex user-visible changes
+
+This chapter describes changes to @code{g77} that are visible
+to the programmers who actually write and maintain Fortran
+code they compile with @code{g77}.
+Information on changes to installation procedures,
+changes to the documentation, and bug fixes is
+not provided here, unless it is likely to affect how
+users use @code{g77}.
+@xref{News,,News About GNU Fortran}, for information on
+such changes to @code{g77}.
+@end ifset
+
+@ifclear USERVISONLY
@node News
@chapter News About GNU Fortran
-@end ifclear
@cindex versions, recent
@cindex recent versions
+@end ifclear
+@end ifset
+@ifclear USERVISONLY
Changes made to recent versions of GNU Fortran are listed
below, with the most recent version first.
@@ -45,6 +91,7 @@ Miscellany
This order is not strict---for example, some items
involve a combination of these elements.
+@end ifclear
Note that two variants of @code{g77} are tracked below.
The @code{egcs} variant is described vis-a-vis
@@ -58,19 +105,190 @@ though this can make getting a complete picture
of what a particular @code{egcs} version contains
somewhat more difficult.
+@ifset DOC-G77
+For information on bugs in the @value{which-g77} version of @code{g77},
+see @ref{Known Bugs,,Known Bugs In GNU Fortran}.
+@end ifset
+
+@ifset DOC-BUGS
+For information on bugs in the @value{which-g77} version of @code{g77},
+see @file{@value{path-g77}/BUGS}.
+@end ifset
+
+@ifset DEVELOPMENT
+@emph{Warning:} The information below is still under development,
+and might not accurately reflect the @code{g77} code base
+of which it is a part.
+Efforts are made to keep it somewhat up-to-date,
+but they are particularly concentrated
+on any version of this information
+that is distributed as part of a @emph{released} @code{g77}.
+
+In particular, while this information is intended to apply to
+the @value{which-g77} version of @code{g77},
+only an official @emph{release} of that version
+is expected to contain documentation that is
+most consistent with the @code{g77} product in that version.
+
+Nevertheless, information on @emph{previous} releases of @code{g77}, below,
+is likely to be more up-to-date and accurate
+than the equivalent information that accompanied
+those releases,
+assuming the last-updated date of the information below
+is later than the dates of those releases.
+
+That's due to attempts to keep this development version
+of news about previous @code{g77} versions up-to-date.
+@end ifset
+
+@ifclear USERVISONLY
+An online, ``live'' version of this document
+(derived directly from the mainline, development version
+of @code{g77} within @code{egcs})
+is available at
+@uref{http://egcs.cygnus.com/onlinedocs/g77_news.html}.
+@end ifclear
+
+The following information was last updated on @value{last-update-news}:
+
+@heading In @code{egcs} 1.2 (versus 1.1.2):
+@itemize @bullet
+@ifclear USERVISONLY
+@item
+@code{g77} no longer generates bad code for assignments,
+or other conversions,
+of @code{REAL} or @code{COMPLEX} constant expressions
+to type @code{INTEGER(KIND=2)}
+(often referred to as @code{INTEGER*8}).
+
+For example, @samp{INTEGER*8 J; J = 4E10} now works as documented.
+@end ifclear
+
+@ifclear USERVISONLY
+@item
+Fix @code{g77} so it no longer crashes when compiling
+I/O statements using keywords that define @code{INTEGER} values,
+such as @samp{IOSTAT=@var{j}},
+where @var{j} is other than default @code{INTEGER}
+(such as @code{INTEGER*2}).
+Instead, it issues a diagnostic.
+@end ifclear
+
+@ifclear USERVISONLY
+@item
+The @samp{-ax} option is now obeyed when compiling Fortran programs.
+(It is passed to the @file{f771} driver.)
+@end ifclear
+
+@item
+Source file names with the suffixes @samp{.FOR} and @samp{.FPP}
+now are recognized by @code{g77}
+as if they ended in @samp{.for} and @samp{.fpp}, respectively.
+
+@item
+@code{g77} now warns about a reference to an intrinsic
+that has an interface that is not Year 2000 (Y2K) compliant.
+Also, the @code{libg2c} has been changed to increase the likelihood
+of catching references to the implementations of these intrinsics
+using the @samp{EXTERNAL} mechanism
+(which would avoid the new warnings).
+
+@ifset DOC-G77
+@xref{Year 2000 (Y2K) Problems}, for more information.
+@end ifset
+
+@ifclear USERVISONLY
+@item
+@code{g77} now warns about a reference to a function
+when the corresponding @emph{subsequent} function program unit
+disagrees with the reference concerning the type of the function.
+@end ifclear
+
+@ifclear USERVISONLY
+@item
+Improve documentation and indexing,
+including information on Year 2000 (Y2K) compliance.
+@end ifclear
+@end itemize
+
+@heading In 0.5.24 and @code{egcs} 1.1.2 (versus 0.5.23 and 1.1.1):
+@ifclear USERVISONLY
+@itemize @bullet
+@item
+Fix the @code{IDate} intrinsic (VXT) (in @code{libg2c})
+so the returned year is in the documented, non-Y2K-compliant range
+of 0--99,
+instead of being returned as 100 in the year 2000.
+
+@ifset DOC-G77
+@xref{IDate Intrinsic (VXT)},
+for more information.
+@end ifset
+
+@item
+Fix the @samp{Date_and_Time} intrinsic (in @code{libg2c})
+to return the milliseconds value properly
+in @var{Values}(8).
+
+@item
+Fix the @samp{LStat} intrinsic (in @code{libg2c})
+to return device-ID information properly
+in @var{SArray}(7).
+
+@item
+Improve documentation.
+@end itemize
+@end ifclear
+
+@heading In 0.5.24 and @code{egcs} 1.1.1 (versus 0.5.23 and 1.1):
+@ifclear USERVISONLY
+@itemize @bullet
+@item
+Fix @code{libg2c} so it performs an implicit @code{ENDFILE} operation
+(as appropriate)
+whenever a @code{REWIND} is done.
+
+(This bug was introduced in 0.5.23 and @code{egcs} 1.1 in
+@code{g77}'s version of @code{libf2c}.)
+
+@item
+Fix @code{libg2c} so it no longer crashes with a spurious diagnostic
+upon doing any I/O following a direct formatted write.
+
+(This bug was introduced in 0.5.23 and @code{egcs} 1.1 in
+@code{g77}'s version of @code{libf2c}.)
+
+@item
+Fix @code{g77} so it no longer crashes compiling references
+to the @samp{Rand} intrinsic on some systems.
+
+@item
+Fix @code{g77} portion of installation process so it works
+better on some systems
+(those with shells requiring @samp{else true} clauses
+on @samp{if} constructs
+for the completion code to be set properly).
+@end itemize
+@end ifclear
+
@heading In @code{egcs} 1.1 (versus 0.5.24):
@itemize @bullet
+@ifclear USERVISONLY
@item
Fix @code{g77} crash compiling code
containing the construct @samp{CMPLX(0.)} or similar.
+@end ifclear
+@ifclear USERVISONLY
@item
Fix @code{g77} crash
(or apparently infinite run-time)
when compiling certain complicated expressions
involving @code{COMPLEX} arithmetic
(especially multiplication).
+@end ifclear
+@ifclear USERVISONLY
@cindex DNRM2
@cindex stack, 387 coprocessor
@cindex Intel x86
@@ -84,6 +302,7 @@ the @samp{DNRM2} routine.
The x87 coprocessor stack was being
mismanaged in cases involving assigned @code{GOTO}
and @code{ASSIGN}.
+@end ifclear
@cindex alignment
@cindex double-precision performance
@@ -98,8 +317,10 @@ having the @code{SAVE} attribute
or given initial values via @code{DATA}.
@end itemize
+@c 1998-09-01: egcs-1.1 released.
@heading In @code{egcs} 1.1 (versus @code{egcs} 1.0.3):
@itemize @bullet
+@ifclear USERVISONLY
@item
Fix bugs in the @code{libU77} intrinsic @samp{HostNm}
that wrote one byte beyond the end of its @samp{CHARACTER}
@@ -107,7 +328,9 @@ argument,
and in the @code{libU77} intrinsics
@samp{GMTime} and @samp{LTime}
that overwrote their arguments.
+@end ifclear
+@ifclear USERVISONLY
@item
Assumed arrays with negative bounds
(such as @samp{REAL A(-1:*)})
@@ -118,7 +341,9 @@ different sizes than integers.
This bug is not known to have existed in any
recent version of @code{gcc}.
It was introduced in an early release of @code{egcs}.
+@end ifclear
+@ifclear USERVISONLY
@item
Valid combinations of @code{EXTERNAL},
passing that external as a dummy argument
@@ -127,14 +352,19 @@ and, in a subsequent program unit,
referencing that external as
an external function with a different type
no longer crash @code{g77}.
+@end ifclear
+@ifclear USERVISONLY
@item
@code{CASE DEFAULT} no longer crashes @code{g77}.
+@end ifclear
+@ifclear USERVISONLY
@item
The @samp{-Wunused} option no longer issues a spurious
warning about the ``master'' procedure generated by
@code{g77} for procedures containing @code{ENTRY} statements.
+@end ifclear
@item
Support @samp{FORMAT(I<@var{expr}>)} when @var{expr} is a
@@ -167,6 +397,7 @@ that have their own (non-Fortran) @code{main()} routine
properly set up the @code{libf2c} environment, even
when @code{libf2c} (now @code{libg2c}) is a shared library.
+@ifclear USERVISONLY
@item
@code{g77} no longer installs the @file{f77} command
and @file{f77.1} man page
@@ -174,7 +405,9 @@ in the @file{/usr} or @file{/usr/local} heirarchy,
even if the @file{f77-install-ok} file exists
in the source or build directory.
See the installation documentation for more information.
+@end ifclear
+@ifclear USERVISONLY
@item
@code{g77} no longer installs the @file{libf2c.a} library
and @file{f2c.h} include file
@@ -182,7 +415,9 @@ in the @file{/usr} or @file{/usr/local} heirarchy,
even if the @file{f2c-install-ok} or @file{f2c-exists-ok} files exist
in the source or build directory.
See the installation documentation for more information.
+@end ifclear
+@ifclear USERVISONLY
@item
The @file{libf2c.a} library produced by @code{g77} has been
renamed to @file{libg2c.a}.
@@ -192,7 +427,9 @@ This allows system administrators and users to choose which
version of the @code{libf2c} library from @code{netlib} they
wish to use on a case-by-case basis.
See the installation documentation for more information.
+@end ifclear
+@ifclear USERVISONLY
@item
The @file{f2c.h} include (header) file produced by @code{g77}
has been renamed to @file{g2c.h}.
@@ -202,6 +439,7 @@ This allows system administrators and users to choose which
version of the include file from @code{netlib} they
wish to use on a case-by-case basis.
See the installation documentation for more information.
+@end ifclear
@item
The @code{g77} command now expects the run-time library
@@ -209,17 +447,21 @@ to be named @code{libg2c.a} instead of @code{libf2c.a},
to ensure that a version other than the one built and
installed as part of the same @code{g77} version is picked up.
+@ifclear USERVISONLY
@item
During the configuration and build process,
@code{g77} creates subdirectories it needs only as it
needs them.
Other cleaning up of the configuration and build process
has been performed as well.
+@end ifclear
+@ifclear USERVISONLY
@item
@code{install-info} now used to update the directory of
Info documentation to contain an entry for @code{g77}
(during installation).
+@end ifclear
@item
Some diagnostics have been changed from warnings to errors,
@@ -230,37 +472,53 @@ in the @code{OPEN}, @code{INQUIRE}, @code{READ}, and
@code{WRITE} statements,
and about truncations of various sorts of constants.
+@ifclear USERVISONLY
@item
Improve compilation of @code{FORMAT} expressions so that
a null byte is appended to the last operand if it
is a constant.
This provides a cleaner run-time diagnostic as provided
by @code{libf2c} for statements like @samp{PRINT '(I1', 42}.
+@end ifclear
+@ifclear USERVISONLY
@item
Improve documentation and indexing.
+@end ifclear
+@ifclear USERVISONLY
@item
The upgrade to @code{libf2c} as of 1998-06-18
should fix a variety of problems, including
those involving some uses of the @samp{T} format
specifier, and perhaps some build (porting) problems
as well.
+@end ifclear
@end itemize
@heading In 0.5.24 and @code{egcs} 1.1 (versus 0.5.23):
@itemize @bullet
+@ifclear USERVISONLY
@item
@code{g77} no longer produces incorrect code
and initial values
for @samp{EQUIVALENCE} and @samp{COMMON}
aggregates that, due to ``unnatural'' ordering of members
vis-a-vis their types, require initial padding.
+@end ifclear
+@ifclear USERVISONLY
@item
@code{g77} no longer crashes when compiling code
containing specification statements such as
@samp{INTEGER(KIND=7) PTR}.
+@end ifclear
+
+@ifclear USERVISONLY
+@item
+@code{g77} no longer crashes when compiling code
+such as @samp{J = SIGNAL(1, 2)}.
+@end ifclear
@item
@code{g77} now treats @samp{%LOC(@var{expr})} and
@@ -307,13 +565,30 @@ The F90 @samp{System_Clock} intrinsic allows
the optional arguments (except for the @samp{Count}
argument) to be omitted.
+@ifclear USERVISONLY
@item
Upgrade to @code{libf2c} as of 1998-06-18.
+@end ifclear
+@ifclear USERVISONLY
@item
Improve documentation and indexing.
+@end ifclear
@end itemize
+@ifset DOC-NEWS
+@heading In previous versions:
+
+Information on previous versions is not provided
+in this @file{@value{path-g77}/NEWS} file,
+to keep it short.
+See @file{@value{path-g77}/news.texi},
+or any of its other derivations
+(Info, HTML, dvi forms)
+for such information.
+@end ifset
+
+@ifclear DOC-NEWS
@c 1998-05-20: 0.5.23 released.
@heading In 0.5.23 (versus 0.5.22):
@itemize @bullet
@@ -324,11 +599,6 @@ version 0.5.22 of @code{g77}, due to using the
it to fix a few bugs and improve performance in a
few cases.
-@xref{Actual Bugs,,Actual Bugs We Haven't Fixed Yet},
-available in plain-text format in @code{gcc/f/BUGS},
-for information on the known bugs in this version,
-including the regressions.
-
Features that have been dropped from this version
of @code{g77} due to their being implemented
via @code{g77}-specific patches to the @code{gcc}
@@ -368,10 +638,13 @@ applying to stack-allocated data
as well as statically-allocate data.
@end itemize
+@ifclear USERVISONLY
Note that the @file{gcc/f/gbe/} subdirectory has been removed
from this distribution as a result of @code{g77} no longer
including patches for the @code{gcc} back end.
+@end ifclear
+@ifclear USERVISONLY
@item
Fix bugs in the @code{libU77} intrinsic @samp{HostNm}
that wrote one byte beyond the end of its @samp{CHARACTER}
@@ -379,22 +652,26 @@ argument,
and in the @code{libU77} intrinsics
@samp{GMTime} and @samp{LTime}
that overwrote their arguments.
+@end ifclear
@item
Support @code{gcc} version 2.8,
and remove support for prior versions of @code{gcc}.
@cindex -@w{}-driver option
-@cindex g77 options, -@w{}-driver
+@cindex @code{g77} options, -@w{}-driver
@cindex options, -@w{}-driver
@item
Remove support for the @samp{--driver} option,
as @code{g77} now does all the driving,
just like @code{gcc}.
+@ifclear USERVISONLY
@item
@code{CASE DEFAULT} no longer crashes @code{g77}.
+@end ifclear
+@ifclear USERVISONLY
@item
Valid combinations of @code{EXTERNAL},
passing that external as a dummy argument
@@ -403,7 +680,9 @@ and, in a subsequent program unit,
referencing that external as
an external function with a different type
no longer crash @code{g77}.
+@end ifclear
+@ifclear USERVISONLY
@item
@code{g77} no longer installs the @file{f77} command
and @file{f77.1} man page
@@ -411,7 +690,9 @@ in the @file{/usr} or @file{/usr/local} heirarchy,
even if the @file{f77-install-ok} file exists
in the source or build directory.
See the installation documentation for more information.
+@end ifclear
+@ifclear USERVISONLY
@item
@code{g77} no longer installs the @file{libf2c.a} library
and @file{f2c.h} include file
@@ -419,7 +700,9 @@ in the @file{/usr} or @file{/usr/local} heirarchy,
even if the @file{f2c-install-ok} or @file{f2c-exists-ok} files exist
in the source or build directory.
See the installation documentation for more information.
+@end ifclear
+@ifclear USERVISONLY
@item
The @file{libf2c.a} library produced by @code{g77} has been
renamed to @file{libg2c.a}.
@@ -429,7 +712,9 @@ This allows system administrators and users to choose which
version of the @code{libf2c} library from @code{netlib} they
wish to use on a case-by-case basis.
See the installation documentation for more information.
+@end ifclear
+@ifclear USERVISONLY
@item
The @file{f2c.h} include (header) file produced by @code{g77}
has been renamed to @file{g2c.h}.
@@ -439,6 +724,7 @@ This allows system administrators and users to choose which
version of the include file from @code{netlib} they
wish to use on a case-by-case basis.
See the installation documentation for more information.
+@end ifclear
@item
The @code{g77} command now expects the run-time library
@@ -446,10 +732,12 @@ to be named @code{libg2c.a} instead of @code{libf2c.a},
to ensure that a version other than the one built and
installed as part of the same @code{g77} version is picked up.
+@ifclear USERVISONLY
@item
The @samp{-Wunused} option no longer issues a spurious
warning about the ``master'' procedure generated by
@code{g77} for procedures containing @code{ENTRY} statements.
+@end ifclear
@item
@code{g77}'s version of @code{libf2c} separates out
@@ -463,6 +751,7 @@ that have their own (non-Fortran) @code{main()} routine
properly set up the @code{libf2c} environment, even
when @code{libf2c} (now @code{libg2c}) is a shared library.
+@ifclear USERVISONLY
@item
During the configuration and build process,
@code{g77} creates subdirectories it needs only as it
@@ -470,11 +759,14 @@ needs them, thus avoiding unnecessary creation of, for example,
@file{stage1/f/runtime} when doing a non-bootstrap build.
Other cleaning up of the configuration and build process
has been performed as well.
+@end ifclear
+@ifclear USERVISONLY
@item
@code{install-info} now used to update the directory of
Info documentation to contain an entry for @code{g77}
(during installation).
+@end ifclear
@item
Some diagnostics have been changed from warnings to errors,
@@ -485,9 +777,12 @@ in the @code{OPEN}, @code{INQUIRE}, @code{READ}, and
@code{WRITE} statements,
and about truncations of various sorts of constants.
+@ifclear USERVISONLY
@item
Improve documentation and indexing.
+@end ifclear
+@ifclear USERVISONLY
@item
Upgrade to @code{libf2c} as of 1998-04-20.
@@ -495,17 +790,21 @@ This should fix a variety of problems, including
those involving some uses of the @samp{T} format
specifier, and perhaps some build (porting) problems
as well.
+@end ifclear
@end itemize
@c 1998-03-16: 0.5.22 released.
@heading In 0.5.22 (versus 0.5.21):
@itemize @bullet
+@ifclear USERVISONLY
@item
Fix code generation for iterative @code{DO} loops that
have one or more references to the iteration variable,
or to aliases of it, in their control expressions.
For example, @samp{DO 10 J=2,J} now is compiled correctly.
+@end ifclear
+@ifclear USERVISONLY
@cindex DNRM2
@cindex stack, 387 coprocessor
@cindex Intel x86
@@ -519,49 +818,66 @@ the @samp{DNRM2} routine.
The x87 coprocessor stack was being
mismanaged in cases involving assigned @code{GOTO}
and @code{ASSIGN}.
+@end ifclear
+@ifclear USERVISONLY
@item
Fix @code{DTime} intrinsic so as not to truncate
results to integer values (on some systems).
+@end ifclear
@item
Fix @code{Signal} intrinsic so it offers portable
support for 64-bit systems (such as Digital Alphas
running GNU/Linux).
+@ifclear USERVISONLY
@item
Fix run-time crash involving @code{NAMELIST} on 64-bit
machines such as Alphas.
+@end ifclear
+@ifclear USERVISONLY
@item
Fix @code{g77} version of @code{libf2c} so it no longer
produces a spurious @samp{I/O recursion} diagnostic at run time
when an I/O operation (such as @samp{READ *,I}) is interrupted
in a manner that causes the program to be terminated
via the @samp{f_exit} routine (such as via @kbd{C-c}).
+@end ifclear
+@ifclear USERVISONLY
@item
Fix @code{g77} crash triggered by @code{CASE} statement with
an omitted lower or upper bound.
+@end ifclear
+@ifclear USERVISONLY
@item
Fix @code{g77} crash compiling references to @code{CPU_Time}
intrinsic.
+@end ifclear
+@ifclear USERVISONLY
@item
Fix @code{g77} crash
(or apparently infinite run-time)
when compiling certain complicated expressions
involving @code{COMPLEX} arithmetic
(especially multiplication).
+@end ifclear
+@ifclear USERVISONLY
@item
Fix @code{g77} crash on statements such as
@samp{PRINT *, (REAL(Z(I)),I=1,2)}, where
@samp{Z} is @code{DOUBLE COMPLEX}.
+@end ifclear
+@ifclear USERVISONLY
@item
Fix a @code{g++} crash.
+@end ifclear
@item
Support @samp{FORMAT(I<@var{expr}>)} when @var{expr} is a
@@ -572,9 +888,11 @@ Fix @code{g77} @samp{-g} option so procedures that
use @samp{ENTRY} can be stepped through, line by line,
in @code{gdb}.
+@ifclear USERVISONLY
@item
Fix a profiling-related bug in @code{gcc} back end for
Intel x86 architecture.
+@end ifclear
@item
Allow any @code{REAL} argument to intrinsics
@@ -597,9 +915,11 @@ C programs.
Support for @code{restrict} is now more like support
for @code{complex}.
+@ifclear USERVISONLY
@item
Fix @samp{-fpedantic} to not reject procedure invocations
such as @samp{I=J()} and @samp{CALL FOO()}.
+@end ifclear
@item
Fix @samp{-fugly-comma} to affect invocations of
@@ -611,6 +931,7 @@ arguments to intrinsics, as in @samp{I=MAX(3,4,,)}.
Fix compiler so it accepts @samp{-fgnu-intrinsics-*} and
@samp{-fbadu77-intrinsics-*} options.
+@ifclear USERVISONLY
@item
Improve diagnostic messages from @code{libf2c}
so it is more likely that the printing of the
@@ -623,45 +944,63 @@ format string specified via a @code{FORMAT} statement.
However, @code{f2c} would exhibit the problem
anyway for a statement like @samp{PRINT '(I)garbage', 1}
by printing @samp{(I)garbage} as the format string.)
+@end ifclear
+@ifclear USERVISONLY
@item
Improve compilation of @code{FORMAT} expressions so that
a null byte is appended to the last operand if it
is a constant.
This provides a cleaner run-time diagnostic as provided
by @code{libf2c} for statements like @samp{PRINT '(I1', 42}.
+@end ifclear
+@ifclear USERVISONLY
@item
Fix various crashes involving code with diagnosed errors.
+@end ifclear
+@ifclear USERVISONLY
@item
Fix cross-compilation bug when configuring @code{libf2c}.
+@end ifclear
+@ifclear USERVISONLY
@item
Improve diagnostics.
+@end ifclear
+@ifclear USERVISONLY
@item
Improve documentation and indexing.
+@end ifclear
+@ifclear USERVISONLY
@item
Upgrade to @code{libf2c} as of 1997-09-23.
This fixes a formatted-I/O bug that afflicted
64-bit systems with 32-bit integers
(such as Digital Alpha running GNU/Linux).
+@end ifclear
@end itemize
@c 1998-03-15: egcs-1.0.2 released.
@heading In @code{egcs} 1.0.2 (versus @code{egcs} 1.0.1):
@itemize @bullet
+@ifclear USERVISONLY
@item
Fix @code{g77} crash triggered by @code{CASE} statement with
an omitted lower or upper bound.
+@end ifclear
+@ifclear USERVISONLY
@item
Fix @code{g77} crash on statements such as
@samp{PRINT *, (REAL(Z(I)),I=1,2)}, where
@samp{Z} is @code{DOUBLE COMPLEX}.
+@end ifclear
+@ifclear USERVISONLY
@cindex ELF support
@cindex support, ELF
@cindex -fPIC option
@@ -670,16 +1009,21 @@ Fix @code{g77} crash on statements such as
Fix @samp{-fPIC} (such as compiling for ELF targets)
on the Intel x86 architecture target
so invalid assembler code is no longer produced.
+@end ifclear
+@ifclear USERVISONLY
@item
Fix @samp{-fpedantic} to not reject procedure invocations
such as @samp{I=J()} and @samp{CALL FOO()}.
+@end ifclear
+@ifclear USERVISONLY
@item
Fix @samp{-fugly-comma} to affect invocations of
only external procedures.
Restore rejection of gratuitous trailing omitted
arguments to intrinsics, as in @samp{I=MAX(3,4,,)}.
+@end ifclear
@item
Fix compiler so it accepts @samp{-fgnu-intrinsics-*} and
@@ -688,11 +1032,13 @@ Fix compiler so it accepts @samp{-fgnu-intrinsics-*} and
@c 1998-01-02: egcs-1.0.1 released.
@heading In @code{egcs} 1.0.1 (versus @code{egcs} 1.0):
+@ifclear USERVISONLY
@itemize @bullet
@item
Fix run-time crash involving @code{NAMELIST} on 64-bit
machines such as Alphas.
@end itemize
+@end ifclear
@c 1997-12-03: egcs-1.0 released.
@heading In @code{egcs} 1.0 (versus 0.5.21):
@@ -706,11 +1052,6 @@ due to using the
it to fix a few bugs and improve performance in a
few cases.
-@xref{Actual Bugs,,Actual Bugs We Haven't Fixed Yet},
-available in plain-text format in @code{gcc/f/BUGS},
-for information on the known bugs in this version,
-including the regressions.
-
Features that have been dropped from this version
of @code{g77} due to their being implemented
via @code{g77}-specific patches to the @code{gcc}
@@ -730,26 +1071,48 @@ applying to stack-allocated data
as well as statically-allocate data.
@end itemize
+@ifclear USERVISONLY
Note that the @file{gcc/f/gbe/} subdirectory has been removed
from this distribution as a result of @code{g77}
being fully integrated with
the @code{egcs} variant of the @code{gcc} back end.
+@end ifclear
+@ifclear USERVISONLY
@item
Fix code generation for iterative @code{DO} loops that
have one or more references to the iteration variable,
or to aliases of it, in their control expressions.
For example, @samp{DO 10 J=2,J} now is compiled correctly.
+@end ifclear
+@ifclear USERVISONLY
@item
Fix @code{DTime} intrinsic so as not to truncate
results to integer values (on some systems).
+@end ifclear
+@ifclear USERVISONLY
+@item
+@c Toon Moene discovered these.
+Some Fortran code, miscompiled
+by @code{g77} built on @code{gcc} version 2.8.1
+on m68k-next-nextstep3 configurations
+when using the @samp{-O2} option,
+is now compiled correctly.
+It is believed that a C function known to miscompile
+on that configuration
+when using the @samp{-O2 -funroll-loops} options
+also is now compiled correctly.
+@end ifclear
+
+@ifclear USERVISONLY
@item
Remove support for non-@code{egcs} versions of @code{gcc}.
+@end ifclear
@cindex -@w{}-driver option
-@cindex g77 options, -@w{}-driver
+@cindex @code{g77} options, -@w{}-driver
@cindex options, -@w{}-driver
@item
Remove support for the @samp{--driver} option,
@@ -760,6 +1123,7 @@ just like @code{gcc}.
Allow any numeric argument to intrinsics
@code{Int2} and @code{Int8}.
+@ifclear USERVISONLY
@item
Improve diagnostic messages from @code{libf2c}
so it is more likely that the printing of the
@@ -772,17 +1136,21 @@ format string specified via a @code{FORMAT} statement.
However, @code{f2c} would exhibit the problem
anyway for a statement like @samp{PRINT '(I)garbage', 1}
by printing @samp{(I)garbage} as the format string.)
+@end ifclear
+@ifclear USERVISONLY
@item
Upgrade to @code{libf2c} as of 1997-09-23.
This fixes a formatted-I/O bug that afflicted
64-bit systems with 32-bit integers
(such as Digital Alpha running GNU/Linux).
+@end ifclear
@end itemize
@c 1997-09-09: 0.5.21 released.
@heading In 0.5.21:
@itemize @bullet
+@ifclear USERVISONLY
@item
Fix a code-generation bug introduced by 0.5.20
caused by loop unrolling (by specifying
@@ -790,7 +1158,9 @@ caused by loop unrolling (by specifying
This bug afflicted all code compiled by
version 2.7.2.2.f.2 of @code{gcc} (C, C++,
Fortran, and so on).
+@end ifclear
+@ifclear USERVISONLY
@item
Fix a code-generation bug manifested when
combining local @code{EQUIVALENCE} with a
@@ -799,7 +1169,9 @@ the first executable statement (or is
treated as an executable-context statement
as a result of using the @samp{-fpedantic}
option).
+@end ifclear
+@ifclear USERVISONLY
@item
Fix a compiler crash that occured when an
integer division by a constant zero is detected.
@@ -808,27 +1180,44 @@ the @code{gcc} back end issues a warning about such a case.
This bug afflicted all code compiled by
version 2.7.2.2.f.2 of @code{gcc} (C, C++,
Fortran, and so on).
+@end ifclear
+@ifset USERVISONLY
+@item
+When the @samp{-W} option is specified, @code{gcc}, @code{g77},
+and other GNU compilers that incorporate the @code{gcc}
+back end as modified by @code{g77}, issue
+a warning about integer division by constant zero.
+@end ifset
+@ifclear USERVISONLY
@item
Fix a compiler crash that occurred in some cases
of procedure inlining.
(Such cases became more frequent in 0.5.20.)
+@end ifclear
+@ifclear USERVISONLY
@item
Fix a compiler crash resulting from using @code{DATA}
or similar to initialize a @code{COMPLEX} variable or
array to zero.
+@end ifclear
+@ifclear USERVISONLY
@item
Fix compiler crashes involving use of @code{AND}, @code{OR},
or @code{XOR} intrinsics.
+@end ifclear
+@ifclear USERVISONLY
@item
Fix compiler bug triggered when using a @code{COMMON}
or @code{EQUIVALENCE} variable
as the target of an @code{ASSIGN}
or assigned-@code{GOTO} statement.
+@end ifclear
+@ifclear USERVISONLY
@item
Fix compiler crashes due to using the name of a some
non-standard intrinsics (such as @samp{FTELL} or
@@ -836,6 +1225,7 @@ non-standard intrinsics (such as @samp{FTELL} or
or common block.
Such dual use of a name in a program is allowed by
the standard.
+@end ifclear
@c @code{g77}'s version of @code{libf2c} has been modified
@c so that the external names of library's procedures do not
@@ -862,16 +1252,20 @@ the standard.
@c the new @code{libf2c} routine @samp{fputc_}, which is
@c simply a jacket routine that calls @samp{G77_fputc_0}.
+@ifclear USERVISONLY
@item
Place automatic arrays on the stack, even if
@code{SAVE} or the @samp{-fno-automatic} option
is in effect.
This avoids a compiler crash in some cases.
+@end ifclear
+@ifclear USERVISONLY
@item
The @samp{-malign-double} option now reliably aligns
@code{DOUBLE PRECISION} optimally on Pentium and
Pentium Pro architectures (586 and 686 in @code{gcc}).
+@end ifclear
@item
New option @samp{-Wno-globals} disables warnings
@@ -901,41 +1295,53 @@ This option also disables inlining of global procedures,
to avoid compiler crashes resulting from coding errors
that these diagnostics normally would identify.
+@ifclear USERVISONLY
@item
Diagnose cases where a reference to a procedure
disagrees with the type of that procedure, or
where disagreements about the number or nature
of arguments exist.
This avoids a compiler crash.
+@end ifclear
+@ifclear USERVISONLY
@item
Fix parsing bug whereby @code{g77} rejected a
second initialization specification immediately
following the first's closing @samp{/} without
an intervening comma in a @code{DATA} statement,
and the second specification was an implied-DO list.
+@end ifclear
+@ifclear USERVISONLY
@item
Improve performance of the @code{gcc} back end so
certain complicated expressions involving @code{COMPLEX}
arithmetic (especially multiplication) don't appear to
take forever to compile.
+@end ifclear
+@ifclear USERVISONLY
@item
Fix a couple of profiling-related bugs in @code{gcc}
back end.
+@end ifclear
+@ifclear USERVISONLY
@item
Integrate GNU Ada's (GNAT's) changes to the back end,
which consist almost entirely of bug fixes.
These fixes are circa version 3.10p of GNAT.
+@end ifclear
+@ifclear USERVISONLY
@item
Include some other @code{gcc} fixes that seem useful in
@code{g77}'s version of @code{gcc}.
(See @file{gcc/ChangeLog} for details---compare it
to that file in the vanilla @code{gcc-2.7.2.3.tar.gz}
distribution.)
+@end ifclear
@item
Fix @code{libU77} routines that accept file and other names
@@ -953,11 +1359,13 @@ that have embedded blanks, commas, and so on.
Fix @code{SIGNAL} intrinsic so it accepts an
optional third @samp{Status} argument.
+@ifclear USERVISONLY
@item
Fix @code{IDATE()} intrinsic subroutine (VXT form)
so it accepts arguments in the correct order.
Documentation fixed accordingly, and for
@code{GMTIME()} and @code{LTIME()} as well.
+@end ifclear
@item
Make many changes to @code{libU77} intrinsics to
@@ -971,42 +1379,57 @@ return @code{INTEGER(KIND=2)} values,
and placing functions that are intended to perform
side effects in a new intrinsic group, @code{badu77}.
+@ifclear USERVISONLY
@item
Improve @code{libU77} so it is more portable.
+@end ifclear
@item
Add options @samp{-fbadu77-intrinsics-delete},
@samp{-fbadu77-intrinsics-hide}, and so on.
+@ifclear USERVISONLY
@item
Fix crashes involving diagnosed or invalid code.
+@end ifclear
+@ifclear USERVISONLY
@item
@code{g77} and @code{gcc} now do a somewhat better
job detecting and diagnosing arrays that are too
large to handle before these cause diagnostics
during the assembler or linker phase, a compiler
crash, or generation of incorrect code.
+@end ifclear
+@ifclear USERVISONLY
@item
Make some fixes to alias analysis code.
+@end ifclear
+@ifclear USERVISONLY
@item
Add support for @code{restrict} keyword in @code{gcc}
front end.
+@end ifclear
+@ifclear USERVISONLY
@item
Support @code{gcc} version 2.7.2.3
(modified by @code{g77} into version 2.7.2.3.f.1),
and remove
support for prior versions of @code{gcc}.
+@end ifclear
+@ifclear USERVISONLY
@item
Incorporate GNAT's patches to the @code{gcc} back
end into @code{g77}'s, so GNAT users do not need
to apply GNAT's patches to build both GNAT and @code{g77}
from the same source tree.
+@end ifclear
+@ifclear USERVISONLY
@item
Modify @code{make} rules and related code so that
generation of Info documentation doesn't require
@@ -1014,6 +1437,7 @@ compilation using @code{gcc}.
Now, any ANSI C compiler should be adequate to
produce the @code{g77} documentation (in particular,
the tables of intrinsics) from scratch.
+@end ifclear
@item
Add @code{INT2} and @code{INT8} intrinsics.
@@ -1028,46 +1452,64 @@ Add @code{ALARM} intrinsic.
@code{CTIME} intrinsic now accepts any @code{INTEGER}
argument, not just @code{INTEGER(KIND=2)}.
+@ifclear USERVISONLY
@item
Warn when explicit type declaration disagrees with
the type of an intrinsic invocation.
+@end ifclear
+@ifclear USERVISONLY
@item
Support @samp{*f771} entry in @code{gcc} @file{specs} file.
+@end ifclear
+@ifclear USERVISONLY
@item
Fix typo in @code{make} rule @samp{g77-cross}, used only for
cross-compiling.
+@end ifclear
+@ifclear USERVISONLY
@item
Fix @code{libf2c} build procedure to re-archive library
if previous attempt to archive was interrupted.
+@end ifclear
+@ifclear USERVISONLY
@item
Change @code{gcc} to unroll loops only during the last
invocation (of as many as two invocations) of loop
optimization.
+@end ifclear
+@ifclear USERVISONLY
@item
Improve handling of @samp{-fno-f2c} so that code that
attempts to pass an intrinsic as an actual argument,
such as @samp{CALL FOO(ABS)}, is rejected due to the fact
that the run-time-library routine is, effectively,
compiled with @samp{-ff2c} in effect.
+@end ifclear
+@ifclear USERVISONLY
@item
Fix @code{g77} driver to recognize @samp{-fsyntax-only}
as an option that inhibits linking, just like @samp{-c} or
@samp{-S}, and to recognize and properly handle the
@samp{-nostdlib}, @samp{-M}, @samp{-MM}, @samp{-nodefaultlibs},
and @samp{-Xlinker} options.
+@end ifclear
+@ifclear USERVISONLY
@item
Upgrade to @code{libf2c} as of 1997-08-16.
+@end ifclear
+@ifclear USERVISONLY
@item
Modify @code{libf2c} to consistently and clearly diagnose
recursive I/O (at run time).
+@end ifclear
@item
@code{g77} driver now prints version information (such as produced
@@ -1078,26 +1520,36 @@ The @samp{.r} suffix now designates a Ratfor source file,
to be preprocessed via the @code{ratfor} command, available
separately.
+@ifclear USERVISONLY
@item
Fix some aspects of how @code{gcc} determines what kind of
system is being configured and what kinds are supported.
For example, GNU Linux/Alpha ELF systems now are directly
supported.
+@end ifclear
+@ifclear USERVISONLY
@item
Improve diagnostics.
+@end ifclear
+@ifclear USERVISONLY
@item
Improve documentation and indexing.
+@end ifclear
+@ifclear USERVISONLY
@item
Include all pertinent files for @code{libf2c} that come
from @code{netlib.bell-labs.com}; give any such files
that aren't quite accurate in @code{g77}'s version of
@code{libf2c} the suffix @samp{.netlib}.
+@end ifclear
+@ifclear USERVISONLY
@item
Reserve @code{INTEGER(KIND=0)} for future use.
+@end ifclear
@end itemize
@c 1997-02-28: 0.5.20 released.
@@ -1108,13 +1560,18 @@ The @samp{-fno-typeless-boz} option is now the default.
This option specifies that non-decimal-radix
constants using the prefixed-radix form (such as @samp{Z'1234'})
-are to be interpreted as @code{INTEGER} constants.
+are to be interpreted as @code{INTEGER(KIND=1)} constants.
Specify @samp{-ftypeless-boz} to cause such
constants to be interpreted as typeless.
(Version 0.5.19 introduced @samp{-fno-typeless-boz} and
its inverse.)
+@ifset DOC-G77
+@xref{Fortran Dialect Options,,Options Controlling Fortran Dialect},
+for information on the @samp{-ftypeless-boz} option.
+@end ifset
+
@item
Options @samp{-ff90-intrinsics-enable} and
@samp{-fvxt-intrinsics-enable} now are the
@@ -1139,6 +1596,10 @@ of @code{libf2c} when built with @samp{ALWAYS_FLUSH} defined,
you will have to modify @code{libf2c} accordingly before
building it from this and future versions of @code{g77}.
+@ifset DOC-G77
+@xref{Output Assumed To Flush}, for more information.
+@end ifset
+
@item
Dave Love's implementation of @code{libU77} has been
added to the version of @code{libf2c} distributed with
@@ -1150,6 +1611,11 @@ as intrinsics.
New option @samp{-fvxt} specifies that the
source file is written in VXT Fortran, instead of GNU Fortran.
+@ifset DOC-G77
+@xref{VXT Fortran}, for more information on the constructs
+recognized when the @samp{-fvxt} option is specified.
+@end ifset
+
@item
The @samp{-fvxt-not-f90} option has been deleted,
along with its inverse, @samp{-ff90-not-vxt}.
@@ -1159,6 +1625,10 @@ re-read the pertinent documentation to determine which
options, if any, are appropriate for compiling your
code with this version of @code{g77}.
+@ifset DOC-G77
+@xref{Other Dialects}, for more information.
+@end ifset
+
@item
The @samp{-fugly} option now issues a warning, as it
likely will be removed in a future version.
@@ -1174,23 +1644,35 @@ The @samp{-fugly-assumed} option, introduced in
version 0.5.19, has been changed to
better accommodate old and new code.
+@ifset DOC-G77
+@xref{Ugly Assumed-Size Arrays}, for more information.
+@end ifset
+
+@ifclear USERVISONLY
@item
Make a number of fixes to the @code{g77} front end and
the @code{gcc} back end to better support Alpha (AXP)
machines.
This includes providing at least one bug-fix to the
@code{gcc} back end for Alphas.
+@end ifclear
@item
Related to supporting Alpha (AXP) machines, the @code{LOC()}
intrinsic and @code{%LOC()} construct now return
-values of integer type that is the same width (holds
-the same number of bits) as the pointer type on the
-machine.
+values of @code{INTEGER(KIND=0)} type,
+as defined by the GNU Fortran language.
+
+This type is wide enough
+(holds the same number of bits)
+as the character-pointer type on the machine.
-On most machines, this won't make a difference, whereas
-on Alphas, the type these constructs return is
-@code{INTEGER*8} instead of the more common @code{INTEGER*4}.
+On most machines, this won't make a difference,
+whereas, on Alphas and other systems with 64-bit pointers,
+the @code{INTEGER(KIND=0)} type is equivalent to @code{INTEGER(KIND=2)}
+(often referred to as @code{INTEGER*8})
+instead of the more common @code{INTEGER(KIND=1)}
+(often referred to as @code{INTEGER*4}).
@item
Emulate @code{COMPLEX} arithmetic in the @code{g77} front
@@ -1199,19 +1681,24 @@ end, to avoid bugs in @code{complex} support in the
New option @samp{-fno-emulate-complex}
causes @code{g77} to revert the 0.5.19 behavior.
+@ifclear USERVISONLY
@item
Fix bug whereby @samp{REAL A(1)}, for example, caused
a compiler crash if @samp{-fugly-assumed} was in effect
and @var{A} was a local (automatic) array.
That case is no longer affected by the new
handling of @samp{-fugly-assumed}.
+@end ifclear
+@ifclear USERVISONLY
@item
Fix @code{g77} command driver so that @samp{g77 -o foo.f}
no longer deletes @file{foo.f} before issuing other
diagnostics, and so the @samp{-x} option is properly
handled.
+@end ifclear
+@ifclear USERVISONLY
@item
Enable inlining of subroutines and functions by the @code{gcc}
back end.
@@ -1219,6 +1706,7 @@ This works as it does for @code{gcc} itself---program units
may be inlined for invocations that follow them in the same
program unit, as long as the appropriate compile-time
options are specified.
+@end ifclear
@item
Dummy arguments are no longer assumed to potentially alias
@@ -1236,10 +1724,19 @@ New options @samp{-falias-check}, @samp{-fargument-alias},
and @samp{-fno-argument-noalias-global} control the
way @code{g77} handles potential aliasing.
+@ifset DOC-G77
+@xref{Aliasing Assumed To Work}, for detailed information on why the
+new defaults might result in some programs no longer working the way they
+did when compiled by previous versions of @code{g77}.
+@end ifset
+
+@ifclear USERVISONLY
@item
The @code{CONJG()} and @code{DCONJG()} intrinsics now
are compiled in-line.
+@end ifclear
+@ifclear USERVISONLY
@item
The bug-fix for 0.5.19.1 has been re-done.
The @code{g77} compiler has been changed back to
@@ -1264,6 +1761,7 @@ particular, if the linker complains about unresolved
references to names like @samp{g77__fvers__}---that
strongly suggests your installation has an obsolete
version of @code{libf2c}.)
+@end ifclear
@item
New option @samp{-fugly-assign} specifies that the
@@ -1273,17 +1771,26 @@ values assigned by both statements @samp{I = 3} and
(Normally, @code{g77} uses a separate memory location
to hold assigned statement labels.)
+@ifset DOC-G77
+@xref{Ugly Assigned Labels}, for more information.
+@end ifset
+
@item
@code{FORMAT} and @code{ENTRY} statements now are allowed to
precede @code{IMPLICIT NONE} statements.
+@ifclear USERVISONLY
@item
Produce diagnostic for unsupported @code{SELECT CASE} on
@code{CHARACTER} type, instead of crashing, at compile time.
+@end ifclear
+@ifclear USERVISONLY
@item
Fix crashes involving diagnosed or invalid code.
+@end ifclear
+@ifclear USERVISONLY
@item
Change approach to building @code{libf2c} archive
(@file{libf2c.a}) so that members are added to it
@@ -1292,27 +1799,36 @@ an already-built @code{g77} doesn't need to have write
access to the build tree (whereas the user doing the
build might not have access to install new software
on the system).
+@end ifclear
+@ifclear USERVISONLY
@item
Support @code{gcc} version 2.7.2.2
(modified by @code{g77} into version 2.7.2.2.f.2),
and remove
support for prior versions of @code{gcc}.
+@end ifclear
+@ifclear USERVISONLY
@item
Upgrade to @code{libf2c} as of 1997-02-08, and
fix up some of the build procedures.
+@end ifclear
+@ifclear USERVISONLY
@item
Improve general build procedures for @code{g77},
fixing minor bugs (such as deletion of any file
named @file{f771} in the parent directory of @code{gcc/}).
+@end ifclear
@item
-Enable full support of @code{INTEGER*8} available in
+Enable full support of @code{INTEGER(KIND=2)}
+(often referred to as @code{INTEGER*8})
+available in
@code{libf2c} and @file{f2c.h} so that @code{f2c} users
may make full use of its features via the @code{g77}
-version of @file{f2c.h} and the @code{INTEGER*8}
+version of @file{f2c.h} and the @code{INTEGER(KIND=2)}
support routines in the @code{g77} version of @code{libf2c}.
@item
@@ -1345,12 +1861,17 @@ complex type other than @code{COMPLEX}), unless
or new @samp{-fugly-complex} option, in conjunction with
@samp{-fnot-f90}, specifies @code{f2c} interpretation.
+@ifclear USERVISONLY
@item
Make improvements to diagnostics.
+@end ifclear
+@ifclear USERVISONLY
@item
Speed up compiler a bit.
+@end ifclear
+@ifclear USERVISONLY
@item
Improvements to documentation and indexing, including
a new chapter containing information on one, later
@@ -1360,8 +1881,18 @@ up automatically via a message in the diagnostic itself.
(Hence the menu item @samp{M} for the node
@samp{Diagnostics} in the top-level menu of
the Info documentation.)
+@end ifclear
@end itemize
+@ifclear DOC-OLDNEWS
+@heading In previous versions:
+
+Information on previous versions is archived
+in @file{@value{path-g77}/news.texi}
+following the test of the @samp{DOC-OLDNEWS} macro.
+@end ifclear
+
+@ifset DOC-OLDNEWS
@c 1997-02-01: 0.5.19.1 released.
@heading In 0.5.19.1:
@itemize @bullet
@@ -1962,8 +2493,7 @@ macros defined in @file{gcc/f/target.h} and used in places like
Add warning to be printed for each invocation of the compiler
if the target machine @code{INTEGER}, @code{REAL}, or @code{LOGICAL} size
is not 32 bits,
-since @code{g77} is known to not work well for such cases (to be
-fixed in Version 0.6---@pxref{Actual Bugs,,Actual Bugs We Haven't Fixed Yet}).
+since @code{g77} is known to not work well for such cases.
@item
Lots of new documentation (though work is still needed to put it into
@@ -2252,3 +2782,6 @@ Generate better code for some kinds of array references.
Speed up lexing somewhat (this makes the compilation phase noticeably
faster).
@end itemize
+
+@end ifset
+@end ifclear
diff --git a/gcc/f/news0.texi b/gcc/f/news0.texi
index 8fb85f456da..3c283d874c3 100644
--- a/gcc/f/news0.texi
+++ b/gcc/f/news0.texi
@@ -1,14 +1,6 @@
-@setfilename NEW
-@set NEWSONLY
-
-@c The immediately following lines apply to the NEWS file
-@c which is generated using this file.
-This file lists recent changes to the GNU Fortran compiler.
-Copyright (C) 1995, 1996 Free Software Foundation, Inc.
-You may copy, distribute, and modify it freely as long as you preserve
-this copyright notice and permission notice.
-
-@node Top,,, (dir)
-@chapter News About GNU Fortran
-@include news.texi
-@bye
+\input texinfo @c -*-texinfo-*-
+@c %**start of header
+@setfilename NEWS
+@c %**end of header
+@c This tells news.texi that it's generating just the NEWS file.
+@set DOC-NEWS
diff --git a/gcc/f/output.j b/gcc/f/output.j
index f995fcbd936..8816b75e666 100644
--- a/gcc/f/output.j
+++ b/gcc/f/output.j
@@ -1,6 +1,6 @@
/* output.j -- Wrapper for GCC's output.h
Copyright (C) 1998 Free Software Foundation, Inc.
- Contributed by James Craig Burley (burley@gnu.org).
+ Contributed by James Craig Burley.
This file is part of GNU Fortran.
@@ -22,7 +22,6 @@ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#ifndef MAKING_DEPENDENCIES
#ifndef _J_f_output
#define _J_f_output
-#include "gansidecl.h"
#include "output.h"
#endif
#endif
diff --git a/gcc/f/parse.c b/gcc/f/parse.c
index 6c92de9230e..1ffd6b3c935 100644
--- a/gcc/f/parse.c
+++ b/gcc/f/parse.c
@@ -1,6 +1,6 @@
/* GNU Fortran
Copyright (C) 1995 Free Software Foundation, Inc.
- Contributed by James Craig Burley (burley@gnu.org).
+ Contributed by James Craig Burley.
This file is part of GNU Fortran.
diff --git a/gcc/f/proj.c b/gcc/f/proj.c
index 6af2df50885..237ebe0ddf4 100644
--- a/gcc/f/proj.c
+++ b/gcc/f/proj.c
@@ -1,6 +1,6 @@
/* proj.c file for GNU Fortran
Copyright (C) 1995 Free Software Foundation, Inc.
- Contributed by James Craig Burley (burley@gnu.org).
+ Contributed by James Craig Burley.
This file is part of GNU Fortran.
diff --git a/gcc/f/proj.h b/gcc/f/proj.h
index 93b12b330c8..47fc2f94ab7 100644
--- a/gcc/f/proj.h
+++ b/gcc/f/proj.h
@@ -1,6 +1,6 @@
/* proj.h file for Gnu Fortran
Copyright (C) 1995, 1996 Free Software Foundation, Inc.
- Contributed by James Craig Burley (burley@gnu.org).
+ Contributed by James Craig Burley.
This file is part of GNU Fortran.
diff --git a/gcc/f/rtl.j b/gcc/f/rtl.j
index 5bf37928672..b12daeba195 100644
--- a/gcc/f/rtl.j
+++ b/gcc/f/rtl.j
@@ -1 +1,2 @@
Contributed by James Craig Burley (burley@gnu.org).
+ Contributed by James Craig Burley.
diff --git a/gcc/f/src.c b/gcc/f/src.c
index 3fd17552441..7b239310408 100644
--- a/gcc/f/src.c
+++ b/gcc/f/src.c
@@ -1,6 +1,6 @@
/* src.c -- Implementation File
Copyright (C) 1995 Free Software Foundation, Inc.
- Contributed by James Craig Burley (burley@gnu.org).
+ Contributed by James Craig Burley.
This file is part of GNU Fortran.
diff --git a/gcc/f/src.h b/gcc/f/src.h
index 6f8bff2f3fc..36c5058f17c 100644
--- a/gcc/f/src.h
+++ b/gcc/f/src.h
@@ -1,3 +1,3 @@
Contributed by James Craig Burley (burley@gnu.org).
((ISALPHA ((c))) || (! (1 || ffe_is_90 ()) && ((c) == '_')))
- ((ISALNUM ((c))) || (! (1 || ffe_is_90 ()) && ((c) == '_')))
+ Contributed by James Craig Burley.
diff --git a/gcc/f/st.c b/gcc/f/st.c
index 5bf37928672..b12daeba195 100644
--- a/gcc/f/st.c
+++ b/gcc/f/st.c
@@ -1 +1,2 @@
Contributed by James Craig Burley (burley@gnu.org).
+ Contributed by James Craig Burley.
diff --git a/gcc/f/st.h b/gcc/f/st.h
index 5bf37928672..b12daeba195 100644
--- a/gcc/f/st.h
+++ b/gcc/f/st.h
@@ -1 +1,2 @@
Contributed by James Craig Burley (burley@gnu.org).
+ Contributed by James Craig Burley.
diff --git a/gcc/f/sta.c b/gcc/f/sta.c
index 58156f592ba..dd825b5388d 100644
--- a/gcc/f/sta.c
+++ b/gcc/f/sta.c
@@ -1,6 +1,6 @@
/* sta.c -- Implementation File (module.c template V1.0)
Copyright (C) 1995-1997 Free Software Foundation, Inc.
- Contributed by James Craig Burley (burley@gnu.org).
+ Contributed by James Craig Burley.
This file is part of GNU Fortran.
diff --git a/gcc/f/sta.h b/gcc/f/sta.h
index 6bb9913d1ff..87e2d9708c2 100644
--- a/gcc/f/sta.h
+++ b/gcc/f/sta.h
@@ -1,6 +1,6 @@
/* sta.h -- Private #include File (module.h template V1.0)
Copyright (C) 1995 Free Software Foundation, Inc.
- Contributed by James Craig Burley (burley@gnu.org).
+ Contributed by James Craig Burley.
This file is part of GNU Fortran.
diff --git a/gcc/f/stb.c b/gcc/f/stb.c
index dc4bda4d98a..7046f74072c 100644
--- a/gcc/f/stb.c
+++ b/gcc/f/stb.c
@@ -1,6 +1,6 @@
/* stb.c -- Implementation File (module.c template V1.0)
Copyright (C) 1995, 1996 Free Software Foundation, Inc.
- Contributed by James Craig Burley (burley@gnu.org).
+ Contributed by James Craig Burley.
This file is part of GNU Fortran.
@@ -1859,7 +1859,7 @@ ffelexHandler
ffestb_do (ffelexToken t)
{
ffeTokenLength i;
- char *p;
+ unsigned char *p;
ffelexHandler next;
ffelexToken nt;
ffestrSecond kw;
@@ -2507,7 +2507,7 @@ ffelexHandler
ffestb_else (ffelexToken t)
{
ffeTokenLength i;
- char *p;
+ unsigned char *p;
switch (ffelex_token_type (ffesta_tokens[0]))
{
@@ -2787,7 +2787,7 @@ static ffelexHandler
ffestb_else3_ (ffelexToken t)
{
ffeTokenLength i;
- char *p;
+ unsigned char *p;
ffelex_set_names (FALSE);
@@ -3013,7 +3013,7 @@ ffelexHandler
ffestb_endxyz (ffelexToken t)
{
ffeTokenLength i;
- char *p;
+ unsigned char *p;
switch (ffelex_token_type (ffesta_tokens[0]))
{
@@ -3319,7 +3319,7 @@ ffelexHandler
ffestb_goto (ffelexToken t)
{
ffeTokenLength i;
- char *p;
+ unsigned char *p;
ffelexHandler next;
ffelexToken nt;
@@ -4152,7 +4152,7 @@ ffestb_let (ffelexToken t)
ffelexHandler next;
bool vxtparam; /* TRUE if it might really be a VXT PARAMETER
stmt. */
- char *p;
+ unsigned char *p;
switch (ffelex_token_type (ffesta_tokens[0]))
{
@@ -4537,7 +4537,7 @@ ffelexHandler
ffestb_varlist (ffelexToken t)
{
ffeTokenLength i;
- char *p;
+ unsigned char *p;
ffelexToken nt;
ffelexHandler next;
@@ -5284,7 +5284,7 @@ ffelexHandler
ffestb_R522 (ffelexToken t)
{
ffeTokenLength i;
- char *p;
+ unsigned char *p;
ffelexToken nt;
ffelexHandler next;
@@ -5528,7 +5528,7 @@ ffestb_R5224_ (ffelexToken t)
ffelexHandler
ffestb_R528 (ffelexToken t)
{
- char *p;
+ unsigned char *p;
ffeTokenLength i;
ffelexToken nt;
ffelexHandler next;
@@ -6419,7 +6419,7 @@ ffelexHandler
ffestb_R834 (ffelexToken t)
{
ffeTokenLength i;
- char *p;
+ unsigned char *p;
switch (ffelex_token_type (ffesta_tokens[0]))
{
@@ -6534,7 +6534,7 @@ ffelexHandler
ffestb_R835 (ffelexToken t)
{
ffeTokenLength i;
- char *p;
+ unsigned char *p;
switch (ffelex_token_type (ffesta_tokens[0]))
{
@@ -6648,7 +6648,7 @@ ffestb_R8351_ (ffelexToken t)
ffelexHandler
ffestb_R838 (ffelexToken t)
{
- char *p;
+ unsigned char *p;
ffeTokenLength i;
ffelexHandler next;
ffelexToken et; /* First token in target. */
@@ -7141,7 +7141,7 @@ ffelexHandler
ffestb_R1102 (ffelexToken t)
{
ffeTokenLength i;
- char *p;
+ unsigned char *p;
switch (ffelex_token_type (ffesta_tokens[0]))
{
@@ -7293,7 +7293,7 @@ ffelexHandler
ffestb_blockdata (ffelexToken t)
{
ffeTokenLength i;
- char *p;
+ unsigned char *p;
switch (ffelex_token_type (ffesta_tokens[0]))
{
@@ -7436,7 +7436,7 @@ ffelexHandler
ffestb_R1212 (ffelexToken t)
{
ffeTokenLength i;
- char *p;
+ unsigned char *p;
ffelexHandler next;
ffelexToken nt;
@@ -8630,7 +8630,7 @@ ffelexHandler
ffestb_R810 (ffelexToken t)
{
ffeTokenLength i;
- char *p;
+ unsigned char *p;
switch (ffelex_token_type (ffesta_tokens[0]))
{
@@ -9709,7 +9709,8 @@ ffestb_R10014_ (ffelexToken t)
i += ffelex_token_length (ffestb_local_.format.post.t);
if (*p == '\0')
return (ffelexHandler) ffestb_R10016_;
- if ((kw != FFESTR_formatP) || !ffelex_is_firstnamechar (*p))
+ if ((kw != FFESTR_formatP) ||
+ !ffelex_is_firstnamechar ((unsigned char)*p))
{
if (ffestb_local_.format.current != FFESTP_formattypeH)
ffesta_ffebad_1p (FFEBAD_FORMAT_TEXT_IN_NUMBER, t, i, NULL);
@@ -12165,7 +12166,7 @@ ffelexHandler
ffestb_V014 (ffelexToken t)
{
ffeTokenLength i;
- char *p;
+ unsigned char *p;
ffelexToken nt;
ffelexHandler next;
@@ -19399,7 +19400,7 @@ ffelexHandler
ffestb_dummy (ffelexToken t)
{
ffeTokenLength i;
- char *p;
+ unsigned char *p;
switch (ffelex_token_type (ffesta_tokens[0]))
{
@@ -19618,7 +19619,7 @@ ffelexHandler
ffestb_R524 (ffelexToken t)
{
ffeTokenLength i;
- char *p;
+ unsigned char *p;
ffelexToken nt;
ffelexHandler next;
@@ -19847,7 +19848,7 @@ ffelexHandler
ffestb_R547 (ffelexToken t)
{
ffeTokenLength i;
- char *p;
+ unsigned char *p;
ffelexToken nt;
ffelexHandler next;
@@ -20485,7 +20486,7 @@ ffelexHandler
ffestb_decl_chartype (ffelexToken t)
{
ffeTokenLength i;
- char *p;
+ unsigned char *p;
ffestb_local_.decl.type = FFESTP_typeCHARACTER;
ffestb_local_.decl.recursive = NULL;
@@ -20672,7 +20673,7 @@ ffelexHandler
ffestb_decl_dbltype (ffelexToken t)
{
ffeTokenLength i;
- char *p;
+ unsigned char *p;
ffestb_local_.decl.type = ffestb_args.decl.type;
ffestb_local_.decl.recursive = NULL;
@@ -20863,7 +20864,7 @@ ffelexHandler
ffestb_decl_gentype (ffelexToken t)
{
ffeTokenLength i;
- char *p;
+ unsigned char *p;
ffestb_local_.decl.type = ffestb_args.decl.type;
ffestb_local_.decl.recursive = NULL;
@@ -22667,7 +22668,7 @@ ffestb_decl_entsp_2_ (ffelexToken t)
{
ffelexToken nt;
bool asterisk_ok;
- char *p;
+ unsigned char *p;
ffeTokenLength i;
switch (ffelex_token_type (t))
@@ -24156,7 +24157,7 @@ ffestb_V0166_ (ffelexToken t)
ffelexHandler
ffestb_V027 (ffelexToken t)
{
- char *p;
+ unsigned char *p;
ffeTokenLength i;
switch (ffelex_token_type (ffesta_tokens[0]))
@@ -24336,7 +24337,7 @@ ffelexHandler
ffestb_decl_R539 (ffelexToken t)
{
ffeTokenLength i;
- char *p;
+ unsigned char *p;
ffelexToken nt;
ffestrSecond kw;
diff --git a/gcc/f/stb.h b/gcc/f/stb.h
index 5bf37928672..b12daeba195 100644
--- a/gcc/f/stb.h
+++ b/gcc/f/stb.h
@@ -1 +1,2 @@
Contributed by James Craig Burley (burley@gnu.org).
+ Contributed by James Craig Burley.
diff --git a/gcc/f/stc.c b/gcc/f/stc.c
index e720f9dd03e..83c2ad6a208 100644
--- a/gcc/f/stc.c
+++ b/gcc/f/stc.c
@@ -1,6 +1,6 @@
/* stc.c -- Implementation File (module.c template V1.0)
Copyright (C) 1995-1997 Free Software Foundation, Inc.
- Contributed by James Craig Burley (burley@gnu.org).
+ Contributed by James Craig Burley.
This file is part of GNU Fortran.
diff --git a/gcc/f/stc.h b/gcc/f/stc.h
index 5bf37928672..b12daeba195 100644
--- a/gcc/f/stc.h
+++ b/gcc/f/stc.h
@@ -1 +1,2 @@
Contributed by James Craig Burley (burley@gnu.org).
+ Contributed by James Craig Burley.
diff --git a/gcc/f/std.c b/gcc/f/std.c
index 540da6c5498..26757bc9df1 100644
--- a/gcc/f/std.c
+++ b/gcc/f/std.c
@@ -1,6 +1,6 @@
/* std.c -- Implementation File (module.c template V1.0)
Copyright (C) 1995, 1996 Free Software Foundation, Inc.
- Contributed by James Craig Burley (burley@gnu.org).
+ Contributed by James Craig Burley.
This file is part of GNU Fortran.
diff --git a/gcc/f/std.h b/gcc/f/std.h
index 5bf37928672..b12daeba195 100644
--- a/gcc/f/std.h
+++ b/gcc/f/std.h
@@ -1 +1,2 @@
Contributed by James Craig Burley (burley@gnu.org).
+ Contributed by James Craig Burley.
diff --git a/gcc/f/ste.c b/gcc/f/ste.c
index 4a2476dde51..113548c127d 100644
--- a/gcc/f/ste.c
+++ b/gcc/f/ste.c
@@ -1,6 +1,6 @@
/* ste.c -- Implementation File (module.c template V1.0)
Copyright (C) 1995, 1996 Free Software Foundation, Inc.
- Contributed by James Craig Burley (burley@gnu.org).
+ Contributed by James Craig Burley.
This file is part of GNU Fortran.
diff --git a/gcc/f/ste.h b/gcc/f/ste.h
index 5bf37928672..b12daeba195 100644
--- a/gcc/f/ste.h
+++ b/gcc/f/ste.h
@@ -1 +1,2 @@
Contributed by James Craig Burley (burley@gnu.org).
+ Contributed by James Craig Burley.
diff --git a/gcc/f/storag.c b/gcc/f/storag.c
index 5bf37928672..b12daeba195 100644
--- a/gcc/f/storag.c
+++ b/gcc/f/storag.c
@@ -1 +1,2 @@
Contributed by James Craig Burley (burley@gnu.org).
+ Contributed by James Craig Burley.
diff --git a/gcc/f/storag.h b/gcc/f/storag.h
index 5bf37928672..b12daeba195 100644
--- a/gcc/f/storag.h
+++ b/gcc/f/storag.h
@@ -1 +1,2 @@
Contributed by James Craig Burley (burley@gnu.org).
+ Contributed by James Craig Burley.
diff --git a/gcc/f/stp.c b/gcc/f/stp.c
index 5bf37928672..b12daeba195 100644
--- a/gcc/f/stp.c
+++ b/gcc/f/stp.c
@@ -1 +1,2 @@
Contributed by James Craig Burley (burley@gnu.org).
+ Contributed by James Craig Burley.
diff --git a/gcc/f/stp.h b/gcc/f/stp.h
index 5bf37928672..b12daeba195 100644
--- a/gcc/f/stp.h
+++ b/gcc/f/stp.h
@@ -1 +1,2 @@
Contributed by James Craig Burley (burley@gnu.org).
+ Contributed by James Craig Burley.
diff --git a/gcc/f/str-1t.fin b/gcc/f/str-1t.fin
index 716adefc4c8..94acdd4cef4 100644
--- a/gcc/f/str-1t.fin
+++ b/gcc/f/str-1t.fin
@@ -1,2 +1,3 @@
Contributed by James Craig Burley (burley@gnu.org).
GoTo GOTO
+ Contributed by James Craig Burley.
diff --git a/gcc/f/str-2t.fin b/gcc/f/str-2t.fin
index 5bf37928672..b12daeba195 100644
--- a/gcc/f/str-2t.fin
+++ b/gcc/f/str-2t.fin
@@ -1 +1,2 @@
Contributed by James Craig Burley (burley@gnu.org).
+ Contributed by James Craig Burley.
diff --git a/gcc/f/str-fo.fin b/gcc/f/str-fo.fin
index 5bf37928672..b12daeba195 100644
--- a/gcc/f/str-fo.fin
+++ b/gcc/f/str-fo.fin
@@ -1 +1,2 @@
Contributed by James Craig Burley (burley@gnu.org).
+ Contributed by James Craig Burley.
diff --git a/gcc/f/str-io.fin b/gcc/f/str-io.fin
index 5bf37928672..b12daeba195 100644
--- a/gcc/f/str-io.fin
+++ b/gcc/f/str-io.fin
@@ -1 +1,2 @@
Contributed by James Craig Burley (burley@gnu.org).
+ Contributed by James Craig Burley.
diff --git a/gcc/f/str-nq.fin b/gcc/f/str-nq.fin
index 5bf37928672..b12daeba195 100644
--- a/gcc/f/str-nq.fin
+++ b/gcc/f/str-nq.fin
@@ -1 +1,2 @@
Contributed by James Craig Burley (burley@gnu.org).
+ Contributed by James Craig Burley.
diff --git a/gcc/f/str-op.fin b/gcc/f/str-op.fin
index 5bf37928672..b12daeba195 100644
--- a/gcc/f/str-op.fin
+++ b/gcc/f/str-op.fin
@@ -1 +1,2 @@
Contributed by James Craig Burley (burley@gnu.org).
+ Contributed by James Craig Burley.
diff --git a/gcc/f/str-ot.fin b/gcc/f/str-ot.fin
index ae7329efef9..0671e8052d3 100644
--- a/gcc/f/str-ot.fin
+++ b/gcc/f/str-ot.fin
@@ -1,6 +1,6 @@
Contributed by James Craig Burley (burley@gnu.org).
And AND
-Eq EQ
+ Contributed by James Craig Burley.
Eqv EQV
False FALSE
GE GE
diff --git a/gcc/f/str.c b/gcc/f/str.c
index 5bf37928672..b12daeba195 100644
--- a/gcc/f/str.c
+++ b/gcc/f/str.c
@@ -1 +1,2 @@
Contributed by James Craig Burley (burley@gnu.org).
+ Contributed by James Craig Burley.
diff --git a/gcc/f/str.h b/gcc/f/str.h
index 5bf37928672..b12daeba195 100644
--- a/gcc/f/str.h
+++ b/gcc/f/str.h
@@ -1 +1,2 @@
Contributed by James Craig Burley (burley@gnu.org).
+ Contributed by James Craig Burley.
diff --git a/gcc/f/sts.c b/gcc/f/sts.c
index 1229ad55dc7..6fa239c9a1d 100644
--- a/gcc/f/sts.c
+++ b/gcc/f/sts.c
@@ -1,6 +1,6 @@
/* sts.c -- Implementation File (module.c template V1.0)
Copyright (C) 1995 Free Software Foundation, Inc.
- Contributed by James Craig Burley (burley@gnu.org).
+ Contributed by James Craig Burley.
This file is part of GNU Fortran.
diff --git a/gcc/f/sts.h b/gcc/f/sts.h
index 5bf37928672..b12daeba195 100644
--- a/gcc/f/sts.h
+++ b/gcc/f/sts.h
@@ -1 +1,2 @@
Contributed by James Craig Burley (burley@gnu.org).
+ Contributed by James Craig Burley.
diff --git a/gcc/f/stt.c b/gcc/f/stt.c
index 521fd4c58a4..bc04139cda4 100644
--- a/gcc/f/stt.c
+++ b/gcc/f/stt.c
@@ -1,6 +1,6 @@
Contributed by James Craig Burley (burley@gnu.org).
#if FFECOM_targetCURRENT == FFECOM_targetFFE
-#endif
+ Contributed by James Craig Burley.
#if FFECOM_targetCURRENT == FFECOM_targetFFE
#endif
#if FFECOM_targetCURRENT == FFECOM_targetFFE
diff --git a/gcc/f/stt.h b/gcc/f/stt.h
index e1aceb68b35..2dd04cbb281 100644
--- a/gcc/f/stt.h
+++ b/gcc/f/stt.h
@@ -1,6 +1,6 @@
Contributed by James Craig Burley (burley@gnu.org).
#if FFECOM_targetCURRENT == FFECOM_targetFFE
-#endif
+ Contributed by James Craig Burley.
#if FFECOM_targetCURRENT == FFECOM_targetFFE
#endif
#if FFECOM_targetCURRENT == FFECOM_targetFFE
diff --git a/gcc/f/stu.c b/gcc/f/stu.c
index 7dcbdcbb67b..e201c310166 100644
--- a/gcc/f/stu.c
+++ b/gcc/f/stu.c
@@ -1,6 +1,6 @@
/* stu.c -- Implementation File (module.c template V1.0)
Copyright (C) 1995-1997 Free Software Foundation, Inc.
- Contributed by James Craig Burley (burley@gnu.org).
+ Contributed by James Craig Burley.
This file is part of GNU Fortran.
diff --git a/gcc/f/stu.h b/gcc/f/stu.h
index 5bf37928672..b12daeba195 100644
--- a/gcc/f/stu.h
+++ b/gcc/f/stu.h
@@ -1 +1,2 @@
Contributed by James Craig Burley (burley@gnu.org).
+ Contributed by James Craig Burley.
diff --git a/gcc/f/stv.c b/gcc/f/stv.c
index 5bf37928672..b12daeba195 100644
--- a/gcc/f/stv.c
+++ b/gcc/f/stv.c
@@ -1 +1,2 @@
Contributed by James Craig Burley (burley@gnu.org).
+ Contributed by James Craig Burley.
diff --git a/gcc/f/stv.h b/gcc/f/stv.h
index 5bf37928672..b12daeba195 100644
--- a/gcc/f/stv.h
+++ b/gcc/f/stv.h
@@ -1 +1,2 @@
Contributed by James Craig Burley (burley@gnu.org).
+ Contributed by James Craig Burley.
diff --git a/gcc/f/stw.c b/gcc/f/stw.c
index 5bf37928672..b12daeba195 100644
--- a/gcc/f/stw.c
+++ b/gcc/f/stw.c
@@ -1 +1,2 @@
Contributed by James Craig Burley (burley@gnu.org).
+ Contributed by James Craig Burley.
diff --git a/gcc/f/stw.h b/gcc/f/stw.h
index 5bf37928672..b12daeba195 100644
--- a/gcc/f/stw.h
+++ b/gcc/f/stw.h
@@ -1 +1,2 @@
Contributed by James Craig Burley (burley@gnu.org).
+ Contributed by James Craig Burley.
diff --git a/gcc/f/symbol.c b/gcc/f/symbol.c
index 8aa72306eca..98b27fedbb3 100644
--- a/gcc/f/symbol.c
+++ b/gcc/f/symbol.c
@@ -1,6 +1,6 @@
/* Implementation of Fortran symbol manager
Copyright (C) 1995-1997 Free Software Foundation, Inc.
- Contributed by James Craig Burley (burley@gnu.org).
+ Contributed by James Craig Burley.
This file is part of GNU Fortran.
@@ -117,7 +117,7 @@ static ffesymbolRetract_ *ffesymbol_retract_list_;
/* List of state names. */
-static char *ffesymbol_state_name_[] =
+static const char *ffesymbol_state_name_[] =
{
"?",
"@",
@@ -127,7 +127,7 @@ static char *ffesymbol_state_name_[] =
/* List of attribute names. */
-static char *ffesymbol_attr_name_[] =
+static const char *ffesymbol_attr_name_[] =
{
#define DEFATTR(ATTR,ATTRS,NAME) NAME,
#include "symbol.def"
@@ -316,7 +316,7 @@ ffesymbol_whine_state_ (ffebad bad, ffelexToken t, char c)
/* Returns a string representing the attributes set. */
-char *
+const char *
ffesymbol_attrs_string (ffesymbolAttrs attrs)
{
static char string[FFESYMBOL_attr * 12 + 20];
@@ -773,7 +773,7 @@ ffesymbol_declare_subrunit (ffelexToken t)
ffesymbol_drive (fn); */
void
-ffesymbol_drive (ffesymbol (*fn) ())
+ffesymbol_drive (ffesymbol (*fn) (ffesymbol))
{
assert (ffesymbol_sfunc_ == NULL); /* Might be ok, but not for current
uses. */
@@ -787,7 +787,7 @@ ffesymbol_drive (ffesymbol (*fn) ())
ffesymbol_drive_sfnames (fn); */
void
-ffesymbol_drive_sfnames (ffesymbol (*fn) ())
+ffesymbol_drive_sfnames (ffesymbol (*fn) (ffesymbol))
{
ffename_space_drive_symbol (ffesymbol_sfunc_, fn);
}
@@ -1348,7 +1348,7 @@ ffesymbol_signal_change (ffesymbol s)
/* Returns the string based on the state. */
-char *
+const char *
ffesymbol_state_string (ffesymbolState state)
{
if (state >= ARRAY_SIZE (ffesymbol_state_name_))
diff --git a/gcc/f/symbol.def b/gcc/f/symbol.def
index 5bf37928672..b12daeba195 100644
--- a/gcc/f/symbol.def
+++ b/gcc/f/symbol.def
@@ -1 +1,2 @@
Contributed by James Craig Burley (burley@gnu.org).
+ Contributed by James Craig Burley.
diff --git a/gcc/f/symbol.h b/gcc/f/symbol.h
index bb3a6670163..028ca364181 100644
--- a/gcc/f/symbol.h
+++ b/gcc/f/symbol.h
@@ -1,5 +1,9 @@
Contributed by James Craig Burley (burley@gnu.org).
#if FFECOM_targetCURRENT == FFECOM_targetFFE
-#endif
+ Contributed by James Craig Burley.
#if FFECOM_targetCURRENT == FFECOM_targetFFE
#endif
+const char *ffesymbol_attrs_string (ffesymbolAttrs attrs);
+void ffesymbol_drive (ffesymbol (*fn) (ffesymbol));
+void ffesymbol_drive_sfnames (ffesymbol (*fn) (ffesymbol));
+const char *ffesymbol_state_string (ffesymbolState state);
diff --git a/gcc/f/system.j b/gcc/f/system.j
index 6a37324350d..38547c83008 100644
--- a/gcc/f/system.j
+++ b/gcc/f/system.j
@@ -1,6 +1,6 @@
/* system.j -- Wrapper for GCC's system.h
Copyright (C) 1998 Free Software Foundation, Inc.
- Contributed by James Craig Burley (burley@gnu.org).
+ Contributed by James Craig Burley.
This file is part of GNU Fortran.
diff --git a/gcc/f/target.c b/gcc/f/target.c
index 5de05ff07ca..5712bdd798a 100644
--- a/gcc/f/target.c
+++ b/gcc/f/target.c
@@ -1,6 +1,6 @@
/* target.c -- Implementation File (module.c template V1.0)
Copyright (C) 1995-1998 Free Software Foundation, Inc.
- Contributed by James Craig Burley (burley@gnu.org).
+ Contributed by James Craig Burley.
This file is part of GNU Fortran.
@@ -469,7 +469,7 @@ ffetarget_iszero_hollerith (ffetargetHollerith constant)
data type info and the number of elements an array (1 for a scalar). */
void
-ffetarget_layout (char *error_text UNUSED, ffetargetAlign *alignment,
+ffetarget_layout (const char *error_text UNUSED, ffetargetAlign *alignment,
ffetargetAlign *modulo, ffetargetOffset *size,
ffeinfoBasictype bt, ffeinfoKindtype kt,
ffetargetCharacterSize charsize,
diff --git a/gcc/f/target.h b/gcc/f/target.h
index 5bf37928672..3bae67c9cf8 100644
--- a/gcc/f/target.h
+++ b/gcc/f/target.h
@@ -1 +1,29 @@
Contributed by James Craig Burley (burley@gnu.org).
+ Contributed by James Craig Burley.
+void ffetarget_layout (const char *error_text, ffetargetAlign *alignment,
+#ifdef REAL_ARITHMETIC
+#define ffetarget_convert_complex1_integer4(res,l) FFEBAD_NOCANDO
+#else
+#endif
+#ifdef REAL_ARITHMETIC
+#define ffetarget_convert_complex2_integer4(res,l) FFEBAD_NOCANDO
+#else
+#endif
+#ifdef REAL_ARITHMETIC
+#define ffetarget_convert_integer4_complex1(res,l) FFEBAD_NOCANDO
+#define ffetarget_convert_integer4_complex2(res,l) FFEBAD_NOCANDO
+#else
+#endif
+#ifdef REAL_ARITHMETIC
+#define ffetarget_convert_integer4_real1(res,l) FFEBAD_NOCANDO
+#define ffetarget_convert_integer4_real2(res,l) FFEBAD_NOCANDO
+#else
+#endif
+#ifdef REAL_ARITHMETIC
+#define ffetarget_convert_real1_integer4(res,l) FFEBAD_NOCANDO
+#else
+#endif
+#ifdef REAL_ARITHMETIC
+#define ffetarget_convert_real2_integer4(res,l) FFEBAD_NOCANDO
+#else
+#endif
diff --git a/gcc/f/tconfig.j b/gcc/f/tconfig.j
index 5bf37928672..b12daeba195 100644
--- a/gcc/f/tconfig.j
+++ b/gcc/f/tconfig.j
@@ -1 +1,2 @@
Contributed by James Craig Burley (burley@gnu.org).
+ Contributed by James Craig Burley.
diff --git a/gcc/f/tm.j b/gcc/f/tm.j
index 5bf37928672..b12daeba195 100644
--- a/gcc/f/tm.j
+++ b/gcc/f/tm.j
@@ -1 +1,2 @@
Contributed by James Craig Burley (burley@gnu.org).
+ Contributed by James Craig Burley.
diff --git a/gcc/f/top.c b/gcc/f/top.c
index 17e4139bb7d..6f94b1ce0fd 100644
--- a/gcc/f/top.c
+++ b/gcc/f/top.c
@@ -1,6 +1,6 @@
/* top.c -- Implementation File (module.c template V1.0)
Copyright (C) 1995-1997 Free Software Foundation, Inc.
- Contributed by James Craig Burley (burley@gnu.org).
+ Contributed by James Craig Burley.
This file is part of GNU Fortran.
@@ -76,7 +76,6 @@ bool ffe_is_f2c_library_ = FFETARGET_defaultIS_F2C_LIBRARY;
bool ffe_is_ffedebug_ = FALSE;
bool ffe_is_free_form_ = FFETARGET_defaultIS_FREE_FORM;
bool ffe_is_globals_ = TRUE;
-bool ffe_is_ident_ = TRUE;
bool ffe_is_init_local_zero_ = FFETARGET_defaultIS_INIT_LOCAL_ZERO;
bool ffe_is_mainprog_; /* TRUE if current prog unit known to be
main. */
@@ -162,7 +161,7 @@ ffe_is_digit_string_ (char *s)
int
ffe_decode_option (argc, argv)
- int argc;
+ int argc ATTRIBUTE_UNUSED;
char **argv;
{
char *opt = argv[0];
@@ -177,10 +176,6 @@ ffe_decode_option (argc, argv)
}
else if (strcmp (&opt[2], "null-version") == 0)
ffe_set_is_null_version (TRUE);
- else if (strcmp (&opt[2], "ident") == 0)
- ffe_set_is_ident (TRUE);
- else if (strcmp (&opt[2], "no-ident") == 0)
- ffe_set_is_ident (FALSE);
else if (strcmp (&opt[2], "f66") == 0)
{
ffe_set_is_onetrip (TRUE);
diff --git a/gcc/f/top.h b/gcc/f/top.h
index 41ce6af1e11..d7c3ed36bd6 100644
--- a/gcc/f/top.h
+++ b/gcc/f/top.h
@@ -1,6 +1,6 @@
Contributed by James Craig Burley (burley@gnu.org).
extern bool ffe_is_null_version_;
-int ffe_decode_option (int argc, char **argv);
+ Contributed by James Craig Burley.
#define ffe_is_null_version() ffe_is_null_version_
#define ffe_set_is_do_internal_checks(f) (ffe_is_do_internal_checks_ = (f))
#define ffe_set_is_null_version(f) (ffe_is_null_version_ = (f))
diff --git a/gcc/f/toplev.j b/gcc/f/toplev.j
index 9ee892bed8f..4b8b7970cd0 100644
--- a/gcc/f/toplev.j
+++ b/gcc/f/toplev.j
@@ -1,6 +1,6 @@
/* toplev.j -- Wrapper for GCC's toplev.h
Copyright (C) 1998 Free Software Foundation, Inc.
- Contributed by James Craig Burley (burley@gnu.org).
+ Contributed by James Craig Burley.
This file is part of GNU Fortran.
diff --git a/gcc/f/tree.j b/gcc/f/tree.j
index 5bf37928672..b12daeba195 100644
--- a/gcc/f/tree.j
+++ b/gcc/f/tree.j
@@ -1 +1,2 @@
Contributed by James Craig Burley (burley@gnu.org).
+ Contributed by James Craig Burley.
diff --git a/gcc/f/type.c b/gcc/f/type.c
index 5bf37928672..b12daeba195 100644
--- a/gcc/f/type.c
+++ b/gcc/f/type.c
@@ -1 +1,2 @@
Contributed by James Craig Burley (burley@gnu.org).
+ Contributed by James Craig Burley.
diff --git a/gcc/f/type.h b/gcc/f/type.h
index 5bf37928672..b12daeba195 100644
--- a/gcc/f/type.h
+++ b/gcc/f/type.h
@@ -1 +1,2 @@
Contributed by James Craig Burley (burley@gnu.org).
+ Contributed by James Craig Burley.
diff --git a/gcc/f/version.c b/gcc/f/version.c
index 417a538b18c..7b978f4e888 100644
--- a/gcc/f/version.c
+++ b/gcc/f/version.c
@@ -1 +1 @@
-char *ffe_version_string = "0.5.24-19980804";
+char *ffe_version_string = "0.5.24-19990313";
diff --git a/gcc/f/where.c b/gcc/f/where.c
index 5bf37928672..fa6792b517f 100644
--- a/gcc/f/where.c
+++ b/gcc/f/where.c
@@ -1 +1,3 @@
Contributed by James Craig Burley (burley@gnu.org).
+ Contributed by James Craig Burley.
+{NULL, NULL, 0, 0, 0, {0}};
diff --git a/gcc/f/where.h b/gcc/f/where.h
index 5bf37928672..b12daeba195 100644
--- a/gcc/f/where.h
+++ b/gcc/f/where.h
@@ -1 +1,2 @@
Contributed by James Craig Burley (burley@gnu.org).
+ Contributed by James Craig Burley.
diff --git a/gcc/final.c b/gcc/final.c
index 29c0db5b9db..350a24e0f32 100644
--- a/gcc/final.c
+++ b/gcc/final.c
@@ -1,5 +1,5 @@
/* Convert RTL to assembler code and output it, for GNU compiler.
- Copyright (C) 1987, 88, 89, 92-97, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1987, 88, 89, 92-98, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -65,6 +65,7 @@ Boston, MA 02111-1307, USA. */
#include "except.h"
#include "toplev.h"
#include "reload.h"
+#include "intl.h"
/* Get N_SLINE and N_SOL from stab.h if we can expect the file to exist. */
#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
@@ -283,7 +284,7 @@ static int bb_func_label_num = -1; /* Current label # for func */
struct bb_str {
struct bb_str *next; /* pointer to next string */
- char *string; /* string */
+ const char *string; /* string */
int label_num; /* label number */
int length; /* string length */
};
@@ -300,7 +301,7 @@ static int asm_insn_count PROTO((rtx));
static void profile_function PROTO((FILE *));
static void profile_after_prologue PROTO((FILE *));
static void add_bb PROTO((FILE *));
-static int add_bb_string PROTO((char *, int));
+static int add_bb_string PROTO((const char *, int));
static void output_source_line PROTO((FILE *, rtx));
static rtx walk_alter_subreg PROTO((rtx));
static void output_asm_name PROTO((void));
@@ -336,7 +337,7 @@ init_final (filename)
void
end_final (filename)
- char *filename;
+ const char *filename;
{
int i;
@@ -413,7 +414,7 @@ end_final (filename)
assemble_integer (const0_rtx, pointer_bytes, 1);
/* byte count for extended structure. */
- assemble_integer (GEN_INT (10 * UNITS_PER_WORD), long_bytes, 1);
+ assemble_integer (GEN_INT (11 * UNITS_PER_WORD), long_bytes, 1);
/* address of function name table */
if (profile_block_flag)
@@ -1312,6 +1313,8 @@ shorten_branches (first)
/* If needed, do any adjustment. */
#ifdef ADJUST_INSN_LENGTH
ADJUST_INSN_LENGTH (insn, insn_lengths[uid]);
+ if (insn_lengths[uid] < 0)
+ fatal_insn ("Negative insn length", insn);
#endif
}
@@ -1861,7 +1864,7 @@ add_bb (file)
static int
add_bb_string (string, perm_p)
- char *string;
+ const char *string;
int perm_p;
{
int len;
@@ -2030,7 +2033,6 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
int prescan;
int nopeepholes;
{
- register int i;
#ifdef HAVE_cc0
rtx set;
#endif
@@ -2179,28 +2181,30 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
PENDING_BLOCKS and output debugging info based on that. */
--block_depth;
+ if (block_depth < 0)
+ abort ();
#ifdef XCOFF_DEBUGGING_INFO
- if (write_symbols == XCOFF_DEBUG && block_depth >= 0)
+ if (write_symbols == XCOFF_DEBUG)
xcoffout_end_block (file, high_block_linenum,
pending_blocks[block_depth]);
#endif
#ifdef DBX_DEBUGGING_INFO
- if (write_symbols == DBX_DEBUG && block_depth >= 0)
+ if (write_symbols == DBX_DEBUG)
ASM_OUTPUT_INTERNAL_LABEL (file, "LBE",
pending_blocks[block_depth]);
#endif
#ifdef SDB_DEBUGGING_INFO
- if (write_symbols == SDB_DEBUG && block_depth >= 0)
+ if (write_symbols == SDB_DEBUG)
sdbout_end_block (file, high_block_linenum,
pending_blocks[block_depth]);
#endif
#ifdef DWARF_DEBUGGING_INFO
- if (write_symbols == DWARF_DEBUG && block_depth >= 0)
+ if (write_symbols == DWARF_DEBUG)
dwarfout_end_block (pending_blocks[block_depth]);
#endif
#ifdef DWARF2_DEBUGGING_INFO
- if (write_symbols == DWARF2_DEBUG && block_depth >= 0)
+ if (write_symbols == DWARF2_DEBUG)
dwarf2out_end_block (pending_blocks[block_depth]);
#endif
}
@@ -2389,7 +2393,7 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
{
register rtx body = PATTERN (insn);
int insn_code_number;
- char *template;
+ const char *template;
#ifdef HAVE_cc0
rtx note;
#endif
@@ -2420,7 +2424,9 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
if (GET_CODE (body) == ADDR_VEC || GET_CODE (body) == ADDR_DIFF_VEC)
{
+#if !(defined(ASM_OUTPUT_ADDR_VEC) || defined(ASM_OUTPUT_ADDR_DIFF_VEC))
register int vlen, idx;
+#endif
if (prescan > 0)
break;
@@ -2836,27 +2842,11 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
since `reload' should have changed them so that they do. */
insn_code_number = recog_memoized (insn);
- insn_extract (insn);
- for (i = 0; i < insn_n_operands[insn_code_number]; i++)
- {
- if (GET_CODE (recog_operand[i]) == SUBREG)
- recog_operand[i] = alter_subreg (recog_operand[i]);
- else if (GET_CODE (recog_operand[i]) == PLUS
- || GET_CODE (recog_operand[i]) == MULT)
- recog_operand[i] = walk_alter_subreg (recog_operand[i]);
- }
-
- for (i = 0; i < insn_n_dups[insn_code_number]; i++)
- {
- if (GET_CODE (*recog_dup_loc[i]) == SUBREG)
- *recog_dup_loc[i] = alter_subreg (*recog_dup_loc[i]);
- else if (GET_CODE (*recog_dup_loc[i]) == PLUS
- || GET_CODE (*recog_dup_loc[i]) == MULT)
- *recog_dup_loc[i] = walk_alter_subreg (*recog_dup_loc[i]);
- }
+ extract_insn (insn);
+ cleanup_subreg_operands (insn);
#ifdef REGISTER_CONSTRAINTS
- if (! constrain_operands (insn_code_number, 1))
+ if (! constrain_operands (1))
fatal_insn_not_found (insn);
#endif
@@ -2864,8 +2854,7 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
it is output. */
#ifdef FINAL_PRESCAN_INSN
- FINAL_PRESCAN_INSN (insn, recog_operand,
- insn_n_operands[insn_code_number]);
+ FINAL_PRESCAN_INSN (insn, recog_operand, recog_n_operands);
#endif
#ifdef HAVE_cc0
@@ -3032,6 +3021,35 @@ output_source_line (file, insn)
}
}
+
+/* For each operand in INSN, simplify (subreg (reg)) so that it refers
+ directly to the desired hard register. */
+void
+cleanup_subreg_operands (insn)
+ rtx insn;
+{
+ int i;
+
+ extract_insn (insn);
+ for (i = 0; i < recog_n_operands; i++)
+ {
+ if (GET_CODE (recog_operand[i]) == SUBREG)
+ recog_operand[i] = alter_subreg (recog_operand[i]);
+ else if (GET_CODE (recog_operand[i]) == PLUS
+ || GET_CODE (recog_operand[i]) == MULT)
+ recog_operand[i] = walk_alter_subreg (recog_operand[i]);
+ }
+
+ for (i = 0; i < recog_n_dups; i++)
+ {
+ if (GET_CODE (*recog_dup_loc[i]) == SUBREG)
+ *recog_dup_loc[i] = alter_subreg (*recog_dup_loc[i]);
+ else if (GET_CODE (*recog_dup_loc[i]) == PLUS
+ || GET_CODE (*recog_dup_loc[i]) == MULT)
+ *recog_dup_loc[i] = walk_alter_subreg (*recog_dup_loc[i]);
+ }
+}
+
/* If X is a SUBREG, replace it with a REG or a MEM,
based on the thing it is a subreg of. */
@@ -3065,6 +3083,9 @@ alter_subreg (x)
#else
REGNO (x) = REGNO (y) + SUBREG_WORD (x);
#endif
+ /* This field has a different meaning for REGs and SUBREGs. Make sure
+ to clear it! */
+ x->used = 0;
}
else if (GET_CODE (y) == MEM)
{
@@ -3073,8 +3094,7 @@ alter_subreg (x)
offset -= (MIN (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (x)))
- MIN (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (y))));
PUT_CODE (x, MEM);
- MEM_VOLATILE_P (x) = MEM_VOLATILE_P (y);
- MEM_IN_STRUCT_P (x) = MEM_IN_STRUCT_P (y);
+ MEM_COPY_ATTRIBUTES (x, y);
MEM_ALIAS_SET (x) = MEM_ALIAS_SET (y);
XEXP (x, 0) = plus_constant (XEXP (y, 0), offset);
}
@@ -3276,13 +3296,13 @@ alter_cond (cond)
In an `asm', it's the user's fault; otherwise, the compiler's fault. */
void
-output_operand_lossage (str)
- char *str;
+output_operand_lossage (msgid)
+ const char *msgid;
{
if (this_is_asm_operands)
- error_for_asm (this_is_asm_operands, "invalid `asm': %s", str);
+ error_for_asm (this_is_asm_operands, "invalid `asm': %s", _(msgid));
else
- fatal ("Internal compiler error, output_operand_lossage `%s'", str);
+ fatal ("Internal compiler error, output_operand_lossage `%s'", _(msgid));
}
/* Output of assembler code from a template, and its subroutines. */
@@ -3313,11 +3333,13 @@ output_asm_name ()
if (debug_insn)
{
register int num = INSN_CODE (debug_insn);
- fprintf (asm_out_file, " %s %d %s",
+ fprintf (asm_out_file, "\t%s %d\t%s",
ASM_COMMENT_START, INSN_UID (debug_insn), insn_name[num]);
if (insn_n_alternatives[num] > 1)
fprintf (asm_out_file, "/%d", which_alternative + 1);
-
+#ifdef HAVE_ATTR_length
+ fprintf (asm_out_file, "\t[length = %d]", get_attr_length (debug_insn));
+#endif
/* Clear this so only the first assembler insn
of any rtl insn will get the special comment for -dp. */
debug_insn = 0;
@@ -3327,10 +3349,10 @@ output_asm_name ()
void
output_asm_insn (template, operands)
- char *template;
+ const char *template;
rtx *operands;
{
- register char *p;
+ register const char *p;
register int c;
/* An insn may return a null string template
@@ -3460,7 +3482,7 @@ output_asm_insn (template, operands)
punctuation character alone, with no operand.
The PRINT_OPERAND macro decides what is actually done. */
#ifdef PRINT_OPERAND_PUNCT_VALID_P
- else if (PRINT_OPERAND_PUNCT_VALID_P (*p))
+ else if (PRINT_OPERAND_PUNCT_VALID_P ((unsigned char)*p))
output_operand (NULL_RTX, *p++);
#endif
else
@@ -3655,11 +3677,11 @@ output_addr_const (file, x)
We handle alternate assembler dialects here, just like output_asm_insn. */
void
-asm_fprintf VPROTO((FILE *file, char *p, ...))
+asm_fprintf VPROTO((FILE *file, const char *p, ...))
{
-#ifndef __STDC__
+#ifndef ANSI_PROTOTYPES
FILE *file;
- char *p;
+ const char *p;
#endif
va_list argptr;
char buf[10];
@@ -3667,9 +3689,9 @@ asm_fprintf VPROTO((FILE *file, char *p, ...))
VA_START (argptr, p);
-#ifndef __STDC__
+#ifndef ANSI_PROTOTYPES
file = va_arg (argptr, FILE *);
- p = va_arg (argptr, char *);
+ p = va_arg (argptr, const char *);
#endif
buf[0] = '%';
@@ -3793,9 +3815,7 @@ asm_fprintf VPROTO((FILE *file, char *p, ...))
break;
case 'U':
-#ifdef USER_LABEL_PREFIX
- fprintf (file, "%s", USER_LABEL_PREFIX);
-#endif
+ fputs (user_label_prefix, file);
break;
default:
@@ -3906,6 +3926,22 @@ split_double (value, first, second)
not necessarily BITS_PER_WORD bits. */
REAL_VALUE_TO_TARGET_DOUBLE (r, l);
+ /* If 32 bits is an entire word for the target, but not for the host,
+ then sign-extend on the host so that the number will look the same
+ way on the host that it would on the target. See for instance
+ simplify_unary_operation. The #if is needed to avoid compiler
+ warnings. */
+
+#if HOST_BITS_PER_LONG > 32
+ if (BITS_PER_WORD < HOST_BITS_PER_LONG && BITS_PER_WORD == 32)
+ {
+ if (l[0] & ((long) 1 << 31))
+ l[0] |= ((long) (-1) << 32);
+ if (l[1] & ((long) 1 << 31))
+ l[1] |= ((long) (-1) << 32);
+ }
+#endif
+
*first = GEN_INT ((HOST_WIDE_INT) l[0]);
*second = GEN_INT ((HOST_WIDE_INT) l[1]);
#else
diff --git a/gcc/fix-header.c b/gcc/fix-header.c
index 698c69de80b..35942d25db6 100644
--- a/gcc/fix-header.c
+++ b/gcc/fix-header.c
@@ -1,5 +1,5 @@
/* fix-header.c - Make C header file suitable for C++.
- Copyright (C) 1993, 94-97, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1993, 94-98, 1999 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
@@ -72,13 +72,13 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "hconfig.h"
#include "system.h"
-#include "gansidecl.h"
#include "obstack.h"
#include "scan.h"
#include "cpplib.h"
#include "cpphash.h"
-void fatal PVPROTO ((const char *, ...)) ATTRIBUTE_PRINTF_1;
+static void v_fatal PROTO ((const char *, va_list)) ATTRIBUTE_NORETURN;
+void fatal PVPROTO ((const char *, ...)) ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN;
sstring buf;
@@ -396,7 +396,7 @@ lookup_std_proto (name, name_length)
if (hash_tab[i] == 0)
return NULL;
fn = &std_protos[hash_tab[i]];
- if (strlen (fn->fname) == name_length
+ if ((int) strlen (fn->fname) == name_length
&& strncmp (fn->fname, name, name_length) == 0)
return fn;
i = (i+1) % HASH_SIZE;
@@ -632,7 +632,7 @@ read_scan_file (in_fname, argc, argv)
obstack_init (&scan_file_obstack);
cpp_reader_init (&scan_in);
- scan_in.data = &scan_options;
+ scan_in.opts = &scan_options;
cpp_options_init (&scan_options);
i = cpp_handle_options (&scan_in, argc, argv);
if (i < argc && ! CPP_FATAL_ERRORS (&scan_in))
@@ -692,7 +692,7 @@ read_scan_file (in_fname, argc, argv)
/* Append "_filbuf" and/or "_flsbuf" to the required functions. */
if (need_filbuf + need_flsbuf)
{
- char *new_list;
+ const char *new_list;
if (need_filbuf)
SET_REQUIRED (fn);
if (need_flsbuf)
@@ -871,15 +871,6 @@ write_rbrac ()
#endif
}
-char *
-xstrdup (str)
- char *str;
-{
- char *copy = (char *) xmalloc (strlen (str) + 1);
- strcpy (copy, str);
- return copy;
-}
-
/* Returns 1 iff the file is properly protected from multiple inclusion:
#ifndef PROTECT_NAME
#define PROTECT_NAME
@@ -1320,71 +1311,6 @@ main (argc, argv)
return 0;
}
-/* Stub error functions. These replace cpperror.c,
- because we want to suppress error messages. */
-
-void
-cpp_file_line_for_message (pfile, filename, line, column)
- cpp_reader * pfile;
- char *filename;
- int line, column;
-{
- if (!verbose)
- return;
- if (column > 0)
- fprintf (stderr, "%s:%d:%d: ", filename, line, column);
- else
- fprintf (stderr, "%s:%d: ", filename, line);
-}
-
-void
-cpp_print_containing_files (pfile)
- cpp_reader *pfile ATTRIBUTE_UNUSED;
-{
-}
-
-/* IS_ERROR is 2 for fatal error, 1 for error, 0 for warning */
-
-void
-v_cpp_message (pfile, is_error, msg, ap)
- cpp_reader *pfile;
- int is_error;
- const char *msg;
- va_list ap;
-{
- if (is_error == 1)
- pfile->errors++;
- else if (is_error > 1)
- pfile->errors = CPP_FATAL_LIMIT;
- if (!verbose)
- return;
- if (!is_error)
- fprintf (stderr, "warning: ");
- vfprintf (stderr, msg, ap);
- fprintf (stderr, "\n");
-}
-
-void
-cpp_message VPROTO ((cpp_reader *pfile, int is_error, const char *msg, ...))
-{
-#ifndef __STDC__
- cpp_reader *pfile;
- int is_error;
- const char *msg;
-#endif
- va_list ap;
-
- VA_START (ap, msg);
-
-#ifndef __STDC__
- pfile = va_arg (ap, cpp_reader *);
- is_error = va_arg (ap, const int);
- msg = va_arg (ap, const char *);
-#endif
-
- v_cpp_message(pfile, is_error, msg, ap);
- va_end(ap);
-}
static void
v_fatal (str, ap)
@@ -1401,46 +1327,17 @@ v_fatal (str, ap)
void
fatal VPROTO ((const char *str, ...))
{
-#ifndef __STDC__
- const char *str;
-#endif
- va_list ap;
-
- VA_START(ap, str);
-
-#ifndef __STDC__
- str = va_arg (ap, const char *);
-#endif
-
- v_fatal(str, ap);
- va_end(ap);
-}
-
-void
-cpp_fatal VPROTO ((cpp_reader * pfile, const char *str, ...))
-{
-#ifndef __STDC__
- cpp_reader * pfile;
+#ifndef ANSI_PROTOTYPES
const char *str;
#endif
va_list ap;
VA_START(ap, str);
-#ifndef __STDC__
- pfile = va_arg (ap, cpp_reader *);
+#ifndef ANSI_PROTOTYPES
str = va_arg (ap, const char *);
#endif
v_fatal(str, ap);
va_end(ap);
}
-
-void
-cpp_pfatal_with_name (pfile, name)
- cpp_reader *pfile;
- const char *name;
-{
- cpp_perror_with_name (pfile, name);
- exit (FATAL_EXIT_CODE);
-}
diff --git a/gcc/fixinc.irix b/gcc/fixinc.irix
index 6562581df6e..d29228a156f 100755
--- a/gcc/fixinc.irix
+++ b/gcc/fixinc.irix
@@ -2,7 +2,7 @@
# Install modified versions of certain problematic Irix include files.
# If possible, create a wrapper (see fixinc.wrap) instead of copying files.
#
-# Copyright (C) 1997 Free Software Foundation, Inc.
+# Copyright (C) 1997, 1998 Free Software Foundation, Inc.
# Contributed by Brendan Kehoe (brendan@cygnus.com).
#
# This file is part of GNU CC.
diff --git a/gcc/fixinc.sco b/gcc/fixinc.sco
index 205a8822af1..6e63c67140f 100755
--- a/gcc/fixinc.sco
+++ b/gcc/fixinc.sco
@@ -6,7 +6,7 @@
# Based on fixinc.svr4 script by Ron Guilmette (rfg@ncd.com) (SCO
# modifications by Ian Lance Taylor (ian@airs.com)).
#
-# Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
+# Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
#
# This file is part of GNU CC.
#
@@ -381,12 +381,12 @@ do
then
echo Fixed $file
rm -f $LIB/$file
- cat <<'__EOF__' >$LIB/$file
+ cat << __EOF__ >$LIB/$file
#ifndef _CURSES_H_WRAPPER
#ifdef __cplusplus
# define bool __curses_bool_t
#endif
-#include_next <curses.h>
+#include_next <$file>
#ifdef __cplusplus
# undef bool
#endif
@@ -396,7 +396,7 @@ __EOF__
# Define _CURSES_H_WRAPPER at the end of the wrapper, not the start,
# so that if #include_next gets another instance of the wrapper,
# this will follow the #include_next chain until we arrive at
- # the real <curses.h>.
+ # the real system include file.
chmod a+r $LIB/$file
fi
fi
diff --git a/gcc/fixinc.svr4 b/gcc/fixinc.svr4
index 46e07ce0ac9..e633ed5bb15 100755
--- a/gcc/fixinc.svr4
+++ b/gcc/fixinc.svr4
@@ -1,7 +1,7 @@
#! /bin/sh
# Install modified versions of certain ANSI-incompatible
# native System V Release 4 system include files.
-# Copyright (C) 1994, 1996, 1997 Free Software Foundation, Inc.
+# Copyright (C) 1994, 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
# Contributed by Ron Guilmette (rfg@monkeys.com).
#
# This file is part of GNU CC.
@@ -1527,6 +1527,40 @@ if [ \! -z "$file_to_fix" ]; then
rm -f /tmp/$base
fi
+# Similarly for struct queue in sys/stream.h.
+file=sys/stream.h
+base=`basename $file`
+if [ -r ${LIB}/$file ]; then
+ file_to_fix=${LIB}/$file
+else
+ if [ -r ${INPUT}/$file ]; then
+ file_to_fix=${INPUT}/$file
+ else
+ file_to_fix=""
+ fi
+fi
+if [ \! -z "$file_to_fix" ]; then
+ echo Checking $file_to_fix
+ sed -e '/struct[ ]*queue/i\
+#ifdef __cplusplus\
+#define queue __stream_queue\
+#endif'\
+ -e '/struct[ ]*queue/a\
+#ifdef __cplusplus\
+#undef queue\
+#endif' $file_to_fix > /tmp/$base
+ if cmp $file_to_fix /tmp/$base >/dev/null 2>&1; then \
+ true
+ else
+ echo Fixed $file_to_fix
+ mkdir -p $LIB/`dirname $file`
+ rm -f ${LIB}/$file
+ cp /tmp/$base ${LIB}/$file
+ chmod a+r ${LIB}/$file
+ fi
+ rm -f /tmp/$base
+fi
+
echo 'Removing unneeded directories:'
cd $LIB
files=`find . -type d -print | sort -r`
diff --git a/gcc/fixinc.wrap b/gcc/fixinc.wrap
index 406c87e9c03..bb783f95589 100755
--- a/gcc/fixinc.wrap
+++ b/gcc/fixinc.wrap
@@ -53,6 +53,35 @@ __EOF__
fi
fi
+# Similarly for struct queue in sys/stream.h.
+file=sys/stream.h
+if [ -r $INPUT/$file ]; then
+ echo Checking $INPUT/$file
+ if grep 'struct[ ]*queue' $INPUT/$file >/dev/null
+ then
+ echo Fixed $file
+ mkdir -p $LIB/`dirname $file`
+ rm -f $LIB/$file
+ cat <<'__EOF__' >$LIB/$file
+#ifndef _SYS_STREAM_H_WRAPPER
+#ifdef __cplusplus
+# define queue __stream_queue
+#endif
+#include_next <sys/stream.h>
+#ifdef __cplusplus
+# undef queue
+#endif
+#define _SYS_STREAM_H_WRAPPER
+#endif /* _SYS_STREAM_H_WRAPPER */
+__EOF__
+ # Define _SYS_STREAM_H_WRAPPER at the end of the wrapper, not the start,
+ # so that if #include_next gets another instance of the wrapper,
+ # this will follow the #include_next chain until we arrive at
+ # the real <sys/stream.h>.
+ chmod a+r $LIB/$file
+ fi
+fi
+
# Avoid the definition of the bool type in the Solaris 2.x curses.h when using
# g++, since it's now an official type in the C++ language.
file=curses.h
diff --git a/gcc/fixincludes b/gcc/fixincludes
index b795a940aaf..03792ea2acf 100755
--- a/gcc/fixincludes
+++ b/gcc/fixincludes
@@ -1657,6 +1657,34 @@ if [ -r ${LIB}/$file ]; then
fi
fi
+# sys/utsname.h on Ultrix V4.[35] puts the declaration of uname before the
+# definition of struct utsname, so the prototype (added by fixproto) causes
+# havoc.
+file=sys/utsname.h
+if [ -r $file ] && [ ! -r ${LIB}/$file ]; then
+ cp $file ${LIB}/$file >/dev/null 2>&1 || echo "Can't copy $file"
+ chmod +w ${LIB}/$file 2>/dev/null
+fi
+
+if [ -r ${LIB}/$file ] \
+ && grep 'ULTRIX' ${LIB}/$file >/dev/null; then
+ echo Fixing $file, uname declaration
+ sed -e '/^[ ]*extern[ ]*int[ ]*uname();$/i\
+struct utsname;
+'\
+ ${LIB}/$file > ${LIB}/${file}.sed
+ rm -f ${LIB}/$file; mv ${LIB}/${file}.sed ${LIB}/$file
+ if cmp $file ${LIB}/$file >/dev/null 2>&1; then
+ rm -f ${LIB}/$file
+ else
+ # Find any include directives that use "file".
+ for include in `egrep '^[ ]*#[ ]*include[ ]*"[^/]' ${LIB}/$file | sed -e 's/^[ ]*#[ ]*include[ ]*"\([^"]*\)".*$/\1/'`; do
+ dir=`echo $file | sed -e s'|/[^/]*$||'`
+ required="$required ${INPUT} $dir/$include ${LIB}/$dir/$include"
+ done
+ fi
+fi
+
# sys/wait.h on AIX 3.2.5 puts the declaration of wait3 before the definition
# of struct rusage, so the prototype (added by fixproto) causes havoc.
file=sys/wait.h
@@ -2186,16 +2214,16 @@ if [ -r ${LIB}/$file ]; then
fi
# For C++, avoid any typedef or macro definition of bool, and use the
-# built in type instead.
-for files in curses.h; do
- if [ -r $file ] && egrep bool $file >/dev/null 2>&1; then
- if [ ! -r ${LIB}/$file ]; then
- cp $file ${LIB}/$file >/dev/null 2>&1 || echo "Can't copy $file"
- chmod +w ${LIB}/$file 2>/dev/null
- chmod a+r ${LIB}/$file 2>/dev/null
- fi
-
- echo Fixing $file
+# built in type instead. HP/UX 10.20, at least, also has it
+# in curses_colr/curses.h.
+for file in curses.h curses_colr/curses.h ; do
+ if [ -r $file ] && [ ! -r ${LIB}/$file ]; then
+ cp $file ${LIB}/$file >/dev/null 2>&1 || echo "Can't copy $file"
+ chmod +w ${LIB}/$file 2>/dev/null
+ chmod a+r ${LIB}/$file 2>/dev/null
+ fi
+ if [ -r ${LIB}/$file ] && egrep bool ${LIB}/$file >/dev/null 2>&1; then
+ echo Fixing $file, typedef or macro for bool is invalid in C++
sed -e '/^#[ ]*define[ ][ ]*bool[ ][ ]*char[ ]*$/i\
#ifndef __cplusplus
'\
@@ -2537,6 +2565,36 @@ if [ -r ${LIB}/$file ]; then
fi
fi
+# Fix <c_asm.h> on Digital UNIX V4.0:
+# It contains a prototype for a DEC C internal asm() function, clashing with
+# gcc's asm keyword. So protect this with __DECC.
+file=c_asm.h
+if [ -r $file ] && [ ! -r ${LIB}/$file ]; then
+ cp $file ${LIB}/$file >/dev/null 2>&1 || echo "Can't copy $file"
+ chmod +w ${LIB}/$file 2>/dev/null
+ chmod a+r ${LIB}/$file 2>/dev/null
+fi
+
+if [ -r ${LIB}/$file ]; then
+ echo Fixing $file
+ sed -e '/^[ ]*float[ ]*fasm/i\
+#ifdef __DECC
+' \
+ -e '/^[ ]*#[ ]*pragma[ ]*intrinsic([ ]*dasm/a\
+#endif
+' ${LIB}/$file > ${LIB}/${file}.sed
+ rm -f ${LIB}/$file; mv ${LIB}/${file}.sed ${LIB}/$file
+ if cmp $file ${LIB}/$file >/dev/null 2>&1; then
+ rm ${LIB}/$file
+ else
+ # Find any include directives that use "file".
+ for include in `egrep '^[ ]*#[ ]*include[ ]*"[^/]' ${LIB}/$file | sed -e 's/^[ ]*#[ ]*include[ ]*"\([^"]*\)".*$/\1/'`; do
+ dir=`echo $file | sed -e s'|/[^/]*$||'`
+ required="$required ${INPUT} $dir/$include ${LIB}/$dir/$include"
+ done
+ fi
+fi
+
# This file on SunOS 4 has a very large macro. When the sed loop
# tries pull it in, it overflows the pattern space size of the SunOS
# sed (GNU sed does not have this problem). Since the file does not
@@ -2921,17 +2979,42 @@ if [ -r ${LIB}/$file ]; then
fi
fi
-# rpc/xdr.h on SunOS needs prototypes for its XDR->xdr_ops function pointers.
-file=rpc/xdr.h
-if [ -r $file ] && [ ! -r ${LIB}/$file ]; then
- cp $file ${LIB}/$file >/dev/null 2>&1 || echo "Can't copy $file"
- chmod +w ${LIB}/$file 2>/dev/null
- chmod a+r ${LIB}/$file 2>/dev/null
-fi
+# rpc/auth.h on SunOS needs prototypes for its AUTH->auth_ops function pointers
+# Similarly for
+# rpc/clnt.h CLIENT->clnt_ops
+# rpc/svc.h SVCXPRT->xp_ops
+# rpc/xdr.h XDR->xdr_ops
+for file in rpc/auth.h rpc/clnt.h rpc/svc.h rpc/xdr.h; do
+ # each file has a different name to replace, so if you add a file to
+ # that list please update the following case statement.
+ case "$file" in
+ rpc/auth.h)
+ prefix="ah_"
+ ;;
+ rpc/clnt.h)
+ prefix="cl_"
+ ;;
+ rpc/svc.h)
+ prefix="xp_"
+ ;;
+ rpc/xdr.h)
+ prefix="x_"
+ ;;
+ *)
+ # Oh Oh, we shouldn't be here
+ exit 1;
+ ;;
+ esac
-if [ -r ${LIB}/$file ]; then
- echo "Checking for needed C++ prototype in $file"
- sed -e 's/^\(.*\)\*\(x_.*\)();\(.*\)/\
+ if [ -r $file ] && [ ! -r ${LIB}/$file ]; then
+ cp $file ${LIB}/$file >/dev/null 2>&1 || echo "Can't copy $file"
+ chmod +w ${LIB}/$file 2>/dev/null
+ chmod a+r ${LIB}/$file 2>/dev/null
+ fi
+
+ if [ -r ${LIB}/$file ]; then
+ echo "Checking for needed C++ prototype in $file"
+ sed -e 's/^\(.*\)\*\('$prefix'.*\)();\(.*\)/\
#ifdef __cplusplus\
\1*\2(...);\3\
#else\
@@ -2939,17 +3022,18 @@ if [ -r ${LIB}/$file ]; then
#endif/g' \
$LIB/$file > ${LIB}/${file}.sed
- rm -f ${LIB}/$file; mv ${LIB}/${file}.sed ${LIB}/$file
- if cmp $file ${LIB}/$file >/dev/null 2>&1; then
- rm -f ${LIB}/$file
- else
- # Find any include directives that use "file".
- for include in `egrep '^[ ]*#[ ]*include[ ]*"[^/]' ${LIB}/$file | sed -e 's/^[ ]*#[ ]*include[ ]*"\([^"]*\)".*$/\1/'`; do
+ rm -f ${LIB}/$file; mv ${LIB}/${file}.sed ${LIB}/$file
+ if cmp $file ${LIB}/$file >/dev/null 2>&1; then
+ rm -f ${LIB}/$file
+ else
+ # Find any include directives that use "file".
+ for include in `egrep '^[ ]*#[ ]*include[ ]*"[^/]' ${LIB}/$file | sed -e 's/^[ ]*#[ ]*include[ ]*"\([^"]*\)".*$/\1/'`; do
dir=`echo $file | sed -e s'|/[^/]*$||'`
required="$required ${INPUT} $dir/$include ${LIB}/$dir/$include"
- done
+ done
+ fi
fi
-fi
+done
# sys/lc_core.h on some versions of OSF1/4.x pollutes the namespace by
# defining regex.h types. This causes C++ library build and usage failures.
diff --git a/gcc/fixproto b/gcc/fixproto
index cd495e6f6c3..b9f8e43f11b 100755
--- a/gcc/fixproto
+++ b/gcc/fixproto
@@ -4,7 +4,7 @@
# fixproto TARGET-DIR SOURCE-DIR-ALL SOURCE-DIR-STD
#
# COPYRIGHT
-# Copyright (C) 1993, 1994 Free Software Foundation, Inc.
+# Copyright (C) 1993, 1994, 1997, 1998 Free Software Foundation, Inc.
# This file is part of GNU CC.
#
# GNU CC is free software; you can redistribute it and/or modify
diff --git a/gcc/flags.h b/gcc/flags.h
index c37f5925a44..5e368ac1ab4 100644
--- a/gcc/flags.h
+++ b/gcc/flags.h
@@ -1,5 +1,5 @@
/* Compilation switch flag definitions for GNU CC.
- Copyright (C) 1987, 88, 94, 95, 96, 97, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1987, 88, 94-98, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -276,10 +276,14 @@ extern int flag_no_peephole;
extern int flag_volatile;
-/* Nonzero means treat all global and extern variables as global. */
+/* Nonzero means treat all global and extern variables as volatile. */
extern int flag_volatile_global;
+/* Nonzero means treat all static variables as volatile. */
+
+extern int flag_volatile_static;
+
/* Nonzero allows GCC to violate some IEEE or ANSI rules regarding math
operations in the interest of optimization. For example it allows
GCC to assume arguments to sqrt are nonnegative numbers, allowing
@@ -345,11 +349,11 @@ extern int flag_schedule_interblock;
extern int flag_schedule_speculative;
extern int flag_schedule_speculative_load;
extern int flag_schedule_speculative_load_dangerous;
+#endif /* HAIFA */
/* flag_on_branch_count_reg means try to replace add-1,compare,branch tupple
by a cheaper branch, on a count register. */
extern int flag_branch_on_count_reg;
-#endif /* HAIFA */
/* Nonzero means put things in delayed-branch slots if supported. */
@@ -489,3 +493,20 @@ extern int flag_prefix_function_name;
/* Value of the -G xx switch, and whether it was passed or not. */
extern int g_switch_value;
extern int g_switch_set;
+
+/* Nonzero if we dump in VCG format, not plain text. */
+extern int dump_for_graph;
+
+/* Selection of the graph form. */
+enum graph_dump_types
+{
+ no_graph = 0,
+ vcg
+};
+extern enum graph_dump_types graph_dump_format;
+
+/* Nonzero means ignore `#ident' directives. 0 means handle them.
+ On SVR4 targets, it also controls whether or not to emit a
+ string identifying the compiler. */
+
+extern int flag_no_ident;
diff --git a/gcc/floatlib.c b/gcc/floatlib.c
index e9e9dea125d..dc791393724 100644
--- a/gcc/floatlib.c
+++ b/gcc/floatlib.c
@@ -17,6 +17,7 @@ host such as a VAX.
If you'd like to work on completing this, please talk to rms@gnu.ai.mit.edu.
+--> Double precision floating support added by James Carlson on 20 April 1998.
**
** Pat Wood
@@ -54,7 +55,6 @@ If you'd like to work on completing this, please talk to rms@gnu.ai.mit.edu.
*/
/* the following deal with IEEE single-precision numbers */
-#define D_PHANTOM_BIT 0x00100000
#define EXCESS 126
#define SIGNBIT 0x80000000
#define HIDDEN (1 << 23)
@@ -70,10 +70,12 @@ If you'd like to work on completing this, please talk to rms@gnu.ai.mit.edu.
#define SIGND(fp) ((fp.l.upper) & SIGNBIT)
#define MANTD(fp) (((((fp.l.upper) & 0xFFFFF) | HIDDEND) << 10) | \
(fp.l.lower >> 22))
+#define HIDDEND_LL ((long long)1 << 52)
+#define MANTD_LL(fp) ((fp.ll & (HIDDEND_LL-1)) | HIDDEND_LL)
+#define PACKD_LL(s,e,m) (((long long)((s)+((e)<<20))<<32)|(m))
/* define SWAP for 386/960 reverse-byte-order brain-damaged CPUs */
-union double_long
- {
+union double_long {
double d;
#ifdef SWAP
struct {
@@ -86,7 +88,8 @@ union double_long
unsigned long lower;
} l;
#endif
- };
+ long long ll;
+};
union float_long
{
@@ -94,38 +97,7 @@ union float_long
long l;
};
- struct _ieee {
-#ifdef SWAP
- unsigned mantissa2 : 32;
- unsigned mantissa1 : 20;
- unsigned exponent : 11;
- unsigned sign : 1;
-#else
- unsigned exponent : 11;
- unsigned sign : 1;
- unsigned mantissa2 : 32;
- unsigned mantissa1 : 20;
-#endif
- };
-
- union _doubleu {
- double d;
- struct _ieee ieee;
-#ifdef SWAP
- struct {
- unsigned long lower;
- long upper;
- } l;
-#else
- struct {
- long upper;
- unsigned long lower;
- } l;
-#endif
- };
-
/* add two floats */
-
float
__addsf3 (float a1, float a2)
{
@@ -138,18 +110,22 @@ __addsf3 (float a1, float a2)
fl2.f = a2;
/* check for zero args */
- if (!fl1.l)
- return (fl2.f);
+ if (!fl1.l) {
+ fl1.f = fl2.f;
+ goto test_done;
+ }
if (!fl2.l)
- return (fl1.f);
+ goto test_done;
exp1 = EXP (fl1.l);
exp2 = EXP (fl2.l);
if (exp1 > exp2 + 25)
- return (fl1.l);
- if (exp2 > exp1 + 25)
- return (fl2.l);
+ goto test_done;
+ if (exp2 > exp1 + 25) {
+ fl1.f = fl2.f;
+ goto test_done;
+ }
/* do everything in excess precision so's we can round later */
mant1 = MANT (fl1.l) << 6;
@@ -176,8 +152,10 @@ __addsf3 (float a1, float a2)
mant1 = -mant1;
sign = SIGNBIT;
}
- else if (!mant1)
- return (0);
+ else if (!mant1) {
+ fl1.f = 0;
+ goto test_done;
+ }
/* normalize up */
while (!(mant1 & 0xE0000000))
@@ -211,11 +189,11 @@ __addsf3 (float a1, float a2)
/* pack up and go home */
fl1.l = PACK (sign, exp1, mant1);
+test_done:
return (fl1.f);
}
/* subtract two floats */
-
float
__subsf3 (float a1, float a2)
{
@@ -236,7 +214,6 @@ __subsf3 (float a1, float a2)
}
/* compare two floats */
-
long
__cmpsf2 (float a1, float a2)
{
@@ -258,7 +235,6 @@ __cmpsf2 (float a1, float a2)
}
/* multiply two floats */
-
float
__mulsf3 (float a1, float a2)
{
@@ -270,8 +246,10 @@ __mulsf3 (float a1, float a2)
fl1.f = a1;
fl2.f = a2;
- if (!fl1.l || !fl2.l)
- return (0);
+ if (!fl1.l || !fl2.l) {
+ fl1.f = 0;
+ goto test_done;
+ }
/* compute sign and exponent */
sign = SIGN (fl1.l) ^ SIGN (fl2.l);
@@ -286,29 +264,34 @@ __mulsf3 (float a1, float a2)
result += ((fl1.l & 0xFF) * (fl2.l >> 8)) >> 8;
result += ((fl2.l & 0xFF) * (fl1.l >> 8)) >> 8;
- if (result & 0x80000000)
+ result >>= 2;
+ if (result & 0x20000000)
{
/* round */
- result += 0x80;
- result >>= 8;
+ result += 0x20;
+ result >>= 6;
}
else
{
/* round */
- result += 0x40;
- result >>= 7;
+ result += 0x10;
+ result >>= 5;
exp--;
}
+ if (result & (HIDDEN<<1)) {
+ result >>= 1;
+ exp++;
+ }
result &= ~HIDDEN;
/* pack up and go home */
fl1.l = PACK (sign, exp, result);
+test_done:
return (fl1.f);
}
/* divide two floats */
-
float
__divsf3 (float a1, float a2)
{
@@ -375,7 +358,6 @@ __divsf3 (float a1, float a2)
}
/* convert int to double */
-
double
__floatsidf (register long a1)
{
@@ -415,9 +397,51 @@ __floatsidf (register long a1)
return (dl.d);
}
-/* negate a float */
+double
+__floatdidf (register long long a1)
+{
+ register int exp = 63 + EXCESSD;
+ union double_long dl;
+
+ dl.l.upper = dl.l.lower = 0;
+ if (a1 == 0)
+ return (dl.d);
+
+ if (a1 < 0) {
+ dl.l.upper = SIGNBIT;
+ a1 = -a1;
+ }
+
+ while (a1 < (long long)1<<54) {
+ a1 <<= 8;
+ exp -= 8;
+ }
+ while (a1 < (long long)1<<62) {
+ a1 <<= 1;
+ exp -= 1;
+ }
+
+ /* pack up and go home */
+ dl.ll |= (a1 >> 10) & ~HIDDEND_LL;
+ dl.l.upper |= exp << 20;
+
+ return (dl.d);
+}
float
+__floatsisf (register long a1)
+{
+ (float)__floatsidf(a1);
+}
+
+float
+__floatdisf (register long long a1)
+{
+ (float)__floatdidf(a1);
+}
+
+/* negate a float */
+float
__negsf2 (float a1)
{
register union float_long fl1;
@@ -431,7 +455,6 @@ __negsf2 (float a1)
}
/* negate a double */
-
double
__negdf2 (double a1)
{
@@ -447,7 +470,6 @@ __negdf2 (double a1)
}
/* convert float to double */
-
double
__extendsfdf2 (float a1)
{
@@ -473,7 +495,6 @@ __extendsfdf2 (float a1)
}
/* convert double to float */
-
float
__truncdfsf2 (double a1)
{
@@ -485,7 +506,7 @@ __truncdfsf2 (double a1)
dl1.d = a1;
if (!dl1.l.upper && !dl1.l.lower)
- return (0);
+ return (float)(0);
exp = EXPD (dl1) - EXCESSD + EXCESS;
@@ -497,7 +518,7 @@ __truncdfsf2 (double a1)
mant >>= 1;
/* did the round overflow? */
- if (mant & 0xFF000000)
+ if (mant & 0xFE000000)
{
mant >>= 1;
exp++;
@@ -511,7 +532,6 @@ __truncdfsf2 (double a1)
}
/* compare two doubles */
-
long
__cmpdf2 (double a1, double a2)
{
@@ -537,7 +557,6 @@ __cmpdf2 (double a1, double a2)
}
/* convert double to int */
-
long
__fixdfsi (double a1)
{
@@ -554,7 +573,7 @@ __fixdfsi (double a1)
l = MANTD (dl1);
if (exp > 0)
- return (0x7FFFFFFF | SIGND (dl1)); /* largest integer */
+ return SIGND(dl1) ? (1<<31) : ((1ul<<31)-1);
/* shift down until exp = 0 or l = 0 */
if (exp < 0 && exp > -32 && l)
@@ -565,10 +584,41 @@ __fixdfsi (double a1)
return (SIGND (dl1) ? -l : l);
}
-/* convert double to unsigned int */
+/* convert double to int */
+long long
+__fixdfdi (double a1)
+{
+ register union double_long dl1;
+ register int exp;
+ register long long l;
+
+ dl1.d = a1;
+
+ if (!dl1.l.upper && !dl1.l.lower)
+ return (0);
+
+ exp = EXPD (dl1) - EXCESSD - 64;
+ l = MANTD_LL(dl1);
+
+ if (exp > 0) {
+ l = (long long)1<<63;
+ if (!SIGND(dl1))
+ l--;
+ return l;
+ }
+
+ /* shift down until exp = 0 or l = 0 */
+ if (exp < 0 && exp > -64 && l)
+ l >>= -exp;
+ else
+ return (0);
+
+ return (SIGND (dl1) ? -l : l);
+}
-unsigned
-long __fixunsdfsi (double a1)
+/* convert double to unsigned int */
+unsigned long
+__fixunsdfsi (double a1)
{
register union double_long dl1;
register int exp;
@@ -583,7 +633,7 @@ long __fixunsdfsi (double a1)
l = (((((dl1.l.upper) & 0xFFFFF) | HIDDEND) << 11) | (dl1.l.lower >> 21));
if (exp > 0)
- return (0xFFFFFFFF); /* largest integer */
+ return (0xFFFFFFFFul); /* largest integer */
/* shift down until exp = 0 or l = 0 */
if (exp < 0 && exp > -32 && l)
@@ -594,245 +644,302 @@ long __fixunsdfsi (double a1)
return (l);
}
-/* For now, the hard double-precision routines simply
- punt and do it in single */
-/* addtwo doubles */
-
-double
-__adddf3 (double a1, double a2)
-{
- return ((float) a1 + (float) a2);
-}
-
-/* subtract two doubles */
-
-double
-__subdf3 (double a1, double a2)
-{
- return ((float) a1 - (float) a2);
-}
-
-/* multiply two doubles */
-
-double
-__muldf3 (double a1, double a2)
+/* convert double to unsigned int */
+unsigned long long
+__fixunsdfdi (double a1)
{
- return ((float) a1 * (float) a2);
-}
-
-/*
- *
- * Name: Barrett Richardson
- * E-mail: barrett@iglou.com
- * When: Thu Dec 15 10:31:11 EST 1994
- *
- * callable function:
- *
- * double __divdf3(double a1, double a2);
- *
- * Does software divide of a1 / a2.
- *
- * Based largely on __divsf3() in floatlib.c in the gcc
- * distribution.
- *
- * Purpose: To be used in conjunction with the -msoft-float
- * option of gcc. You should be able to tack it to the
- * end of floatlib.c included in the gcc distribution,
- * and delete the __divdf3() already there which just
- * calls the single precision function (or may just
- * use the floating point processor with some configurations).
- *
- * You may use this code for whatever your heart desires.
- */
+ register union double_long dl1;
+ register int exp;
+ register unsigned long long l;
+ dl1.d = a1;
+ if (dl1.ll == 0)
+ return (0);
+ exp = EXPD (dl1) - EXCESSD - 64;
-/*
- * Compare the mantissas of two doubles.
- * Each mantissa is in two longs.
- *
- * return 1 if x1's mantissa is greater than x2's
- * -1 if x1's mantissa is less than x2's
- * 0 if the two mantissa's are equal.
- *
- * The Mantissas won't fit into a 4 byte word, so they are
- * broken up into two parts.
- *
- * This function is used internally by __divdf3()
- */
-
-int
-__dcmp (long x1m1, long x1m2, long x2m1, long x2m2)
-{
- if (x1m1 > x2m1)
- return 1;
-
- if (x1m1 < x2m1)
- return -1;
+ l = dl1.ll;
- /* If the first word in the two mantissas were equal check the second word */
+ if (exp > 0)
+ return (unsigned long long)-1;
- if (x1m2 > x2m2)
- return 1;
+ /* shift down until exp = 0 or l = 0 */
+ if (exp < 0 && exp > -64 && l)
+ l >>= -exp;
+ else
+ return (0);
- if (x1m2 < x2m2)
- return -1;
-
- return 0;
+ return (l);
}
-
-/* divide two doubles */
-
+/* addtwo doubles */
double
-__divdf3 (double a1, double a2)
+__adddf3 (double a1, double a2)
{
+ register long long mant1, mant2;
+ register union double_long fl1, fl2;
+ register int exp1, exp2;
+ int sign = 0;
+
+ fl1.d = a1;
+ fl2.d = a2;
+
+ /* check for zero args */
+ if (!fl2.ll)
+ goto test_done;
+ if (!fl1.ll) {
+ fl1.d = fl2.d;
+ goto test_done;
+ }
- int sign,
- exponent,
- bit_bucket;
-
- register unsigned long mantissa1,
- mantissa2,
- x1m1,
- x1m2,
- x2m1,
- x2m2,
- mask;
-
- union _doubleu x1,
- x2,
- result;
-
-
- x1.d = a1;
- x2.d = a2;
-
- exponent = x1.ieee.exponent - x2.ieee.exponent + EXCESSD;
-
- sign = x1.ieee.sign ^ x2.ieee.sign;
-
- x2.ieee.sign = 0; /* don't want the sign bit to affect any zero */
- /* comparisons when checking for zero divide */
-
- if (!x2.l.lower && !x2.l.upper) { /* check for zero divide */
- result.l.lower = 0x0;
- if (sign)
- result.l.upper = 0xFFF00000; /* negative infinity */
- else
- result.l.upper = 0x7FF00000; /* positive infinity */
- return result.d;
- }
+ exp1 = EXPD(fl1);
+ exp2 = EXPD(fl2);
- if (!x1.l.upper && !x1.l.lower) /* check for 0.0 numerator */
- return (0.0);
+ if (exp1 > exp2 + 54)
+ goto test_done;
+ if (exp2 > exp1 + 54) {
+ fl1.d = fl2.d;
+ goto test_done;
+ }
- x1m1 = x1.ieee.mantissa1 | D_PHANTOM_BIT; /* turn on phantom bit */
- x1m2 = x1.ieee.mantissa2;
+ /* do everything in excess precision so's we can round later */
+ mant1 = MANTD_LL(fl1) << 9;
+ mant2 = MANTD_LL(fl2) << 9;
- x2m1 = x2.ieee.mantissa1 | D_PHANTOM_BIT; /* turn on phantom bit */
- x2m2 = x2.ieee.mantissa2;
+ if (SIGND(fl1))
+ mant1 = -mant1;
+ if (SIGND(fl2))
+ mant2 = -mant2;
- if (__dcmp(x1m1,x1m2,x2m1,x2m2) < 0) {
+ if (exp1 > exp2)
+ mant2 >>= exp1 - exp2;
+ else {
+ mant1 >>= exp2 - exp1;
+ exp1 = exp2;
+ }
+ mant1 += mant2;
+
+ if (mant1 < 0) {
+ mant1 = -mant1;
+ sign = SIGNBIT;
+ } else if (!mant1) {
+ fl1.d = 0;
+ goto test_done;
+ }
- /* if x1's mantissa is less than x2's shift it left one and decrement */
- /* the exponent to accommodate the change in the mantissa */
+ /* normalize up */
+ while (!(mant1 & ((long long)7<<61))) {
+ mant1 <<= 1;
+ exp1--;
+ }
- x1m1 <<= 1; /* */
- bit_bucket = x1m2 >> 31; /* Shift mantissa left one */
- x1m1 |= bit_bucket; /* */
- x1m2 <<= 1; /* */
+ /* normalize down? */
+ if (mant1 & ((long long)3<<62)) {
+ mant1 >>= 1;
+ exp1++;
+ }
- exponent--;
- }
+ /* round to even */
+ mant1 += (mant1 & (1<<9)) ? (1<<8) : ((1<<8)-1);
+ /* normalize down? */
+ if (mant1 & ((long long)3<<62)) {
+ mant1 >>= 1;
+ exp1++;
+ }
- mantissa1 = 0;
- mantissa2 = 0;
+ /* lose extra precision */
+ mant1 >>= 9;
+ /* turn off hidden bit */
+ mant1 &= ~HIDDEND_LL;
- /* Get the first part of the results mantissa using successive */
- /* subtraction. */
+ /* pack up and go home */
+ fl1.ll = PACKD_LL(sign,exp1,mant1);
- mask = 0x00200000;
- while (mask) {
+test_done:
+ return (fl1.d);
+}
- if (__dcmp(x1m1,x1m2,x2m1,x2m2) >= 0) {
+/* subtract two doubles */
+double
+__subdf3 (double a1, double a2)
+{
+ register union double_long fl1, fl2;
+
+ fl1.d = a1;
+ fl2.d = a2;
+
+ /* check for zero args */
+ if (!fl2.ll)
+ return (fl1.d);
+ /* twiddle sign bit and add */
+ fl2.l.upper ^= SIGNBIT;
+ if (!fl1.ll)
+ return (fl2.d);
+ return __adddf3 (a1, fl2.d);
+}
- /* subtract x2's mantissa from x1's */
+/* multiply two doubles */
+double
+__muldf3 (double a1, double a2)
+{
+ register union double_long fl1, fl2;
+ register unsigned long long result;
+ register int exp;
+ int sign;
- mantissa1 |= mask; /* turn on a bit in the result */
+ fl1.d = a1;
+ fl2.d = a2;
- if (x2m2 > x1m2)
- x1m1--;
- x1m2 -= x2m2;
- x1m1 -= x2m1;
- }
+ if (!fl1.ll || !fl2.ll) {
+ fl1.d = 0;
+ goto test_done;
+ }
- x1m1 <<= 1; /* */
- bit_bucket = x1m2 >> 31; /* Shift mantissa left one */
- x1m1 |= bit_bucket; /* */
- x1m2 <<= 1; /* */
+ /* compute sign and exponent */
+ sign = SIGND(fl1) ^ SIGND(fl2);
+ exp = EXPD(fl1) - EXCESSD;
+ exp += EXPD(fl2);
+
+ fl1.ll = MANTD_LL(fl1);
+ fl2.ll = MANTD_LL(fl2);
+
+ /* the multiply is done as one 31x31 multiply and two 31x21 multiples */
+ result = (fl1.ll >> 21) * (fl2.ll >> 21);
+ result += ((fl1.ll & 0x1FFFFF) * (fl2.ll >> 21)) >> 21;
+ result += ((fl2.ll & 0x1FFFFF) * (fl1.ll >> 21)) >> 21;
+
+ result >>= 2;
+ if (result & ((long long)1<<61)) {
+ /* round */
+ result += 1<<8;
+ result >>= 9;
+ } else {
+ /* round */
+ result += 1<<7;
+ result >>= 8;
+ exp--;
+ }
+ if (result & (HIDDEND_LL<<1)) {
+ result >>= 1;
+ exp++;
+ }
- mask >>= 1;
- }
+ result &= ~HIDDEND_LL;
- /* Get the second part of the results mantissa using successive */
- /* subtraction. */
+ /* pack up and go home */
+ fl1.ll = PACKD_LL(sign,exp,result);
+test_done:
+ return (fl1.d);
+}
- mask = 0x80000000;
- while (mask) {
+/* divide two doubles */
+double
+__divdf3 (double a1, double a2)
+{
+ register union double_long fl1, fl2;
+ register long long mask,result;
+ register int exp, sign;
+
+ fl1.d = a1;
+ fl2.d = a2;
+
+ /* subtract exponents */
+ exp = EXPD(fl1) - EXPD(fl2) + EXCESSD;
+
+ /* compute sign */
+ sign = SIGND(fl1) ^ SIGND(fl2);
+
+ /* numerator zero??? */
+ if (fl1.ll == 0) {
+ /* divide by zero??? */
+ if (fl2.ll == 0)
+ fl1.ll = ((unsigned long long)1<<63)-1; /* NaN */
+ else
+ fl1.ll = 0;
+ goto test_done;
+ }
- if (__dcmp(x1m1,x1m2,x2m1,x2m2) >= 0) {
+ /* return +Inf or -Inf */
+ if (fl2.ll == 0) {
+ fl1.ll = PACKD_LL(SIGND(fl1),2047,0);
+ goto test_done;
+ }
- /* subtract x2's mantissa from x1's */
- mantissa2 |= mask; /* turn on a bit in the result */
+ /* now get mantissas */
+ fl1.ll = MANTD_LL(fl1);
+ fl2.ll = MANTD_LL(fl2);
- if (x2m2 > x1m2)
- x1m1--;
- x1m2 -= x2m2;
- x1m1 -= x2m1;
- }
- x1m1 <<= 1; /* */
- bit_bucket = x1m2 >> 31; /* Shift mantissa left one */
- x1m1 |= bit_bucket; /* */
- x1m2 <<= 1; /* */
+ /* this assures we have 54 bits of precision in the end */
+ if (fl1.ll < fl2.ll) {
+ fl1.ll <<= 1;
+ exp--;
+ }
- mask >>= 1;
- }
+ /* now we perform repeated subtraction of fl2.ll from fl1.ll */
+ mask = (long long)1<<53;
+ result = 0;
+ while (mask) {
+ if (fl1.ll >= fl2.ll)
+ {
+ result |= mask;
+ fl1.ll -= fl2.ll;
+ }
+ fl1.ll <<= 1;
+ mask >>= 1;
+ }
- /* round up by adding 1 to mantissa */
+ /* round */
+ result += 1;
- if (mantissa2 == 0xFFFFFFFF) { /* check for over flow */
+ /* normalize down */
+ exp++;
+ result >>= 1;
- /* spill if overflow */
+ result &= ~HIDDEND_LL;
- mantissa2 = 0;
- mantissa1++;
- }
- else
- mantissa2++;
+ /* pack up and go home */
+ fl1.ll = PACKD_LL(sign, exp, result);
- exponent++; /* increment exponent (mantissa must be shifted right */
- /* also) */
+test_done:
+ return (fl1.d);
+}
- /* shift mantissa right one and assume a phantom bit (which really gives */
- /* 53 bits of precision in the mantissa) */
+int
+__gtdf2 (double a1, double a2)
+{
+ return __cmpdf2 ((float) a1, (float) a2) > 0;
+}
- mantissa2 >>= 1;
- bit_bucket = mantissa1 & 1;
- mantissa2 |= (bit_bucket << 31);
- mantissa1 >>= 1;
+int
+__gedf2 (double a1, double a2)
+{
+ return (__cmpdf2 ((float) a1, (float) a2) >= 0) - 1;
+}
- /* put all the info into the result */
+int
+__ltdf2 (double a1, double a2)
+{
+ return - (__cmpdf2 ((float) a1, (float) a2) < 0);
+}
- result.ieee.exponent = exponent;
- result.ieee.sign = sign;
- result.ieee.mantissa1 = mantissa1;
- result.ieee.mantissa2 = mantissa2;
+int
+__ledf2 (double a1, double a2)
+{
+ return __cmpdf2 ((float) a1, (float) a2) > 0;
+}
+int
+__eqdf2 (double a1, double a2)
+{
+ return *(long long *) &a1 == *(long long *) &a2;
+}
- return result.d;
+int
+__nedf2 (double a1, double a2)
+{
+ return *(long long *) &a1 != *(long long *) &a2;
}
diff --git a/gcc/flow.c b/gcc/flow.c
index bf875bb2708..3f482639d1c 100644
--- a/gcc/flow.c
+++ b/gcc/flow.c
@@ -1,5 +1,5 @@
/* Data flow analysis for GNU compiler.
- Copyright (C) 1987, 88, 92-97, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1987, 88, 92-98, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -19,14 +19,13 @@ the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-/* This file contains the data flow analysis pass of the compiler.
- It computes data flow information
- which tells combine_instructions which insns to consider combining
- and controls register allocation.
+/* This file contains the data flow analysis pass of the compiler. It
+ computes data flow information which tells combine_instructions
+ which insns to consider combining and controls register allocation.
- Additional data flow information that is too bulky to record
- is generated during the analysis, and is used at that time to
- create autoincrement and autodecrement addressing.
+ Additional data flow information that is too bulky to record is
+ generated during the analysis, and is used at that time to create
+ autoincrement and autodecrement addressing.
The first step is dividing the function into basic blocks.
find_basic_blocks does this. Then life_analysis determines
@@ -34,13 +33,12 @@ Boston, MA 02111-1307, USA. */
** find_basic_blocks **
- find_basic_blocks divides the current function's rtl
- into basic blocks. It records the beginnings and ends of the
- basic blocks in the vectors basic_block_head and basic_block_end,
- and the number of blocks in n_basic_blocks.
+ find_basic_blocks divides the current function's rtl into basic
+ blocks and constructs the CFG. The blocks are recorded in the
+ basic_block_info array; the CFG exists in the edge structures
+ referenced by the blocks.
- find_basic_blocks also finds any unreachable loops
- and deletes them.
+ find_basic_blocks also finds any unreachable loops and deletes them.
** life_analysis **
@@ -51,12 +49,12 @@ Boston, MA 02111-1307, USA. */
** live-register info **
The information about where each register is live is in two parts:
- the REG_NOTES of insns, and the vector basic_block_live_at_start.
+ the REG_NOTES of insns, and the vector basic_block->global_live_at_start.
- basic_block_live_at_start has an element for each basic block,
- and the element is a bit-vector with a bit for each hard or pseudo
- register. The bit is 1 if the register is live at the beginning
- of the basic block.
+ basic_block->global_live_at_start has an element for each basic
+ block, and the element is a bit-vector with a bit for each hard or
+ pseudo register. The bit is 1 if the register is live at the
+ beginning of the basic block.
Two types of elements can be added to an insn's REG_NOTES.
A REG_DEAD note is added to an insn's REG_NOTES for any register
@@ -106,12 +104,23 @@ Boston, MA 02111-1307, USA. */
life_analysis fills in certain vectors containing information about
register usage: reg_n_refs, reg_n_deaths, reg_n_sets, reg_live_length,
- reg_n_calls_crosses and reg_basic_block. */
+ reg_n_calls_crosses and reg_basic_block.
+
+ life_analysis sets current_function_sp_is_unchanging if the function
+ doesn't modify the stack pointer. */
+
+/* TODO:
+
+ Split out from life_analysis:
+ - local property discovery (bb->local_live, bb->local_set)
+ - global property computation
+ - log links creation
+ - pre/post modify transformation
+*/
#include "config.h"
#include "system.h"
#include "rtl.h"
-#include "function.h"
#include "basic-block.h"
#include "insn-config.h"
#include "regs.h"
@@ -120,11 +129,23 @@ Boston, MA 02111-1307, USA. */
#include "output.h"
#include "except.h"
#include "toplev.h"
+#include "recog.h"
+#include "insn-flags.h"
#include "obstack.h"
#define obstack_chunk_alloc xmalloc
#define obstack_chunk_free free
+
+/* EXIT_IGNORE_STACK should be nonzero if, when returning from a function,
+ the stack pointer does not matter. The value is tested only in
+ functions that have frame pointers.
+ No definition is equivalent to always zero. */
+#ifndef EXIT_IGNORE_STACK
+#define EXIT_IGNORE_STACK 0
+#endif
+
+
/* The contents of the current function definition are allocated
in this obstack, and all are freed at the end of the function.
For top-level functions, this is temporary_obstack.
@@ -132,44 +153,51 @@ Boston, MA 02111-1307, USA. */
extern struct obstack *function_obstack;
-/* Get the basic block number of an insn.
- This info should not be expected to remain available
- after the end of life_analysis. */
-
-/* This is the limit of the allocated space in the following two arrays. */
-
-static int max_uid_for_flow;
-
-#define BLOCK_NUM(INSN) uid_block_number[INSN_UID (INSN)]
+/* Number of basic blocks in the current function. */
-/* This is where the BLOCK_NUM values are really stored.
- This is set up by find_basic_blocks and used there and in life_analysis,
- and then freed. */
+int n_basic_blocks;
-int *uid_block_number;
+/* The basic block array. */
-/* INSN_VOLATILE (insn) is 1 if the insn refers to anything volatile. */
+varray_type basic_block_info;
-#define INSN_VOLATILE(INSN) uid_volatile[INSN_UID (INSN)]
-static char *uid_volatile;
+/* The special entry and exit blocks. */
-/* Number of basic blocks in the current function. */
+struct basic_block_def entry_exit_blocks[2] =
+{
+ {
+ NULL, /* head */
+ NULL, /* end */
+ NULL, /* pred */
+ NULL, /* succ */
+ NULL, /* local_set */
+ NULL, /* global_live_at_start */
+ NULL, /* global_live_at_end */
+ NULL, /* aux */
+ ENTRY_BLOCK, /* index */
+ 0 /* loop_depth */
+ },
+ {
+ NULL, /* head */
+ NULL, /* end */
+ NULL, /* pred */
+ NULL, /* succ */
+ NULL, /* local_set */
+ NULL, /* global_live_at_start */
+ NULL, /* global_live_at_end */
+ NULL, /* aux */
+ EXIT_BLOCK, /* index */
+ 0 /* loop_depth */
+ }
+};
-int n_basic_blocks;
+/* Nonzero if the second flow pass has completed. */
+int flow2_completed;
/* Maximum register number used in this function, plus one. */
int max_regno;
-/* Maximum number of SCRATCH rtx's used in any basic block of this
- function. */
-
-int max_scratch;
-
-/* Number of SCRATCH rtx's in the current block. */
-
-static int num_scratch;
-
/* Indexed by n, giving various register information */
varray_type reg_n_info;
@@ -190,28 +218,8 @@ static rtx *reg_next_use;
int regset_bytes;
int regset_size;
-/* Element N is first insn in basic block N.
- This info lasts until we finish compiling the function. */
-
-rtx *basic_block_head;
-
-/* Element N is last insn in basic block N.
- This info lasts until we finish compiling the function. */
-
-rtx *basic_block_end;
-
-/* Element N indicates whether basic block N can be reached through a
- computed jump. */
-
-char *basic_block_computed_jump_target;
-
-/* Element N is a regset describing the registers live
- at the start of basic block N.
- This info lasts until we finish compiling the function. */
-
-regset *basic_block_live_at_start;
-
/* Regset of regs live when calls to `setjmp'-like functions happen. */
+/* ??? Does this exist only for the setjmp-clobbered warning message? */
regset regs_live_at_setjmp;
@@ -221,21 +229,6 @@ regset regs_live_at_setjmp;
are another pair, etc. */
rtx regs_may_share;
-/* Element N is nonzero if control can drop into basic block N
- from the preceding basic block. Freed after life_analysis. */
-
-static char *basic_block_drops_in;
-
-/* Element N is depth within loops of the last insn in basic block number N.
- Freed after life_analysis. */
-
-static short *basic_block_loop_depth;
-
-/* Element N nonzero if basic block N can actually be reached.
- Vector exists only during find_basic_blocks. */
-
-static char *block_live_static;
-
/* Depth within loops of basic block being scanned for lifetime analysis,
plus one. This is the weight attached to references to registers. */
@@ -245,24 +238,73 @@ static int loop_depth;
static int cc0_live;
-/* During propagate_block, this contains the last MEM stored into. It
- is used to eliminate consecutive stores to the same location. */
+/* During propagate_block, this contains a list of all the MEMs we are
+ tracking for dead store elimination.
+
+ ?!? Note we leak memory by not free-ing items on this list. We need to
+ write some generic routines to operate on memory lists since cse, gcse,
+ loop, sched, flow and possibly other passes all need to do basically the
+ same operations on these lists. */
-static rtx last_mem_set;
+static rtx mem_set_list;
/* Set of registers that may be eliminable. These are handled specially
in updating regs_ever_live. */
static HARD_REG_SET elim_reg_set;
+/* The basic block structure for every insn, indexed by uid. */
+
+varray_type basic_block_for_insn;
+
+/* The labels mentioned in non-jump rtl. Valid during find_basic_blocks. */
+/* ??? Should probably be using LABEL_NUSES instead. It would take a
+ bit of surgery to be able to use or co-opt the routines in jump. */
+
+static rtx label_value_list;
+
+/* INSN_VOLATILE (insn) is 1 if the insn refers to anything volatile. */
+
+#define INSN_VOLATILE(INSN) bitmap_bit_p (uid_volatile, INSN_UID (INSN))
+#define SET_INSN_VOLATILE(INSN) bitmap_set_bit (uid_volatile, INSN_UID (INSN))
+static bitmap uid_volatile;
+
/* Forward declarations */
-static void find_basic_blocks_1 PROTO((rtx, rtx, int));
-static void mark_label_ref PROTO((rtx, rtx, int));
+static int count_basic_blocks PROTO((rtx));
+static rtx find_basic_blocks_1 PROTO((rtx, rtx*));
+static void create_basic_block PROTO((int, rtx, rtx, rtx));
+static void compute_bb_for_insn PROTO((varray_type, int));
+static void clear_edges PROTO((void));
+static void make_edges PROTO((rtx, rtx*));
+static void make_edge PROTO((basic_block, basic_block, int));
+static void make_label_edge PROTO((basic_block, rtx, int));
+static void mark_critical_edges PROTO((void));
+
+static void commit_one_edge_insertion PROTO((edge));
+
+static void delete_unreachable_blocks PROTO((void));
+static void delete_eh_regions PROTO((void));
+static void delete_insn_chain PROTO((rtx, rtx));
+static int delete_block PROTO((basic_block));
+static void expunge_block PROTO((basic_block));
+static rtx flow_delete_insn PROTO((rtx));
+static int can_delete_label_p PROTO((rtx));
+static void merge_blocks_nomove PROTO((basic_block, basic_block));
+static int merge_blocks PROTO((edge,basic_block,basic_block));
+static void tidy_fallthru_edge PROTO((edge,basic_block,basic_block));
+static void calculate_loop_depth PROTO((rtx));
+
+static int set_noop_p PROTO((rtx));
+static int noop_move_p PROTO((rtx));
+static void notice_stack_pointer_modification PROTO ((rtx, rtx));
+static void record_volatile_insns PROTO((rtx));
+static void mark_regs_live_at_end PROTO((regset));
static void life_analysis_1 PROTO((rtx, int));
+static void init_regset_vector PROTO ((regset *, int,
+ struct obstack *));
static void propagate_block PROTO((regset, rtx, rtx, int,
regset, int));
-static rtx flow_delete_insn PROTO((rtx));
-static int insn_dead_p PROTO((rtx, regset, int));
+static int insn_dead_p PROTO((rtx, regset, int, rtx));
static int libcall_dead_p PROTO((rtx, regset, rtx, rtx));
static void mark_set_regs PROTO((regset, regset, rtx,
rtx, regset));
@@ -275,777 +317,1720 @@ static int try_pre_increment PROTO((rtx, rtx, HOST_WIDE_INT));
#endif
static void mark_used_regs PROTO((regset, regset, rtx, int, rtx));
void dump_flow_info PROTO((FILE *));
-static void add_pred_succ PROTO ((int, int, int_list_ptr *,
- int_list_ptr *, int *, int *));
+static void dump_edge_info PROTO((FILE *, edge, int));
+
static int_list_ptr alloc_int_list_node PROTO ((int_list_block **));
static int_list_ptr add_int_list_node PROTO ((int_list_block **,
int_list **, int));
-static void init_regset_vector PROTO ((regset *, int,
- struct obstack *));
+
+static void add_pred_succ PROTO ((int, int, int_list_ptr *,
+ int_list_ptr *, int *, int *));
+
static void count_reg_sets_1 PROTO ((rtx));
static void count_reg_sets PROTO ((rtx));
static void count_reg_references PROTO ((rtx));
+static void notice_stack_pointer_modification PROTO ((rtx, rtx));
+static void invalidate_mems_from_autoinc PROTO ((rtx));
/* Find basic blocks of the current function.
- F is the first insn of the function and NREGS the number of register numbers
- in use.
- LIVE_REACHABLE_P is non-zero if the caller needs all live blocks to
- be reachable. This turns on a kludge that causes the control flow
- information to be inaccurate and not suitable for passes like GCSE. */
+ F is the first insn of the function and NREGS the number of register
+ numbers in use. */
void
-find_basic_blocks (f, nregs, file, live_reachable_p)
+find_basic_blocks (f, nregs, file)
rtx f;
- int nregs;
- FILE *file;
- int live_reachable_p;
+ int nregs ATTRIBUTE_UNUSED;
+ FILE *file ATTRIBUTE_UNUSED;
{
- register rtx insn;
- register int i;
- rtx nonlocal_label_list = nonlocal_label_rtx_list ();
- int in_libcall_block = 0;
- int extra_uids_for_flow = 0;
+ rtx *bb_eh_end;
+ int max_uid;
- /* Count the basic blocks. Also find maximum insn uid value used. */
+ /* Flush out existing data. */
+ if (basic_block_info != NULL)
+ {
+ int i;
- {
- register RTX_CODE prev_code = JUMP_INSN;
- register RTX_CODE code;
- int eh_region = 0;
+ clear_edges ();
- max_uid_for_flow = 0;
+ /* Clear bb->aux on all extant basic blocks. We'll use this as a
+ tag for reuse during create_basic_block, just in case some pass
+ copies around basic block notes improperly. */
+ for (i = 0; i < n_basic_blocks; ++i)
+ BASIC_BLOCK (i)->aux = NULL;
- for (insn = f, i = 0; insn; insn = NEXT_INSN (insn))
- {
- /* Track when we are inside in LIBCALL block. */
- if (GET_RTX_CLASS (GET_CODE (insn)) == 'i'
- && find_reg_note (insn, REG_LIBCALL, NULL_RTX))
- in_libcall_block = 1;
-
- code = GET_CODE (insn);
- if (INSN_UID (insn) > max_uid_for_flow)
- max_uid_for_flow = INSN_UID (insn);
- if (code == CODE_LABEL)
- i++;
- else if (GET_RTX_CLASS (code) == 'i')
- {
- if (prev_code == JUMP_INSN || prev_code == BARRIER)
- i++;
- else if (prev_code == CALL_INSN)
- {
- if (nonlocal_label_list != 0 || eh_region)
- i++;
- else
- {
- /* Else this call does not force a new block to be
- created. However, it may still be the end of a basic
- block if it is followed by a CODE_LABEL or a BARRIER.
-
- To disambiguate calls which force new blocks to be
- created from those which just happen to be at the end
- of a block we insert nops during find_basic_blocks_1
- after calls which are the last insn in a block by
- chance. We must account for such insns in
- max_uid_for_flow. */
-
- extra_uids_for_flow++;
- }
- }
- }
+ VARRAY_FREE (basic_block_info);
+ }
- /* We change the code of the CALL_INSN, so that it won't start a
- new block. */
- if (code == CALL_INSN && in_libcall_block)
- code = INSN;
-
- if (code != NOTE)
- prev_code = code;
- else if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_BEG)
- ++eh_region;
- else if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_END)
- --eh_region;
-
- if (GET_RTX_CLASS (GET_CODE (insn)) == 'i'
- && find_reg_note (insn, REG_RETVAL, NULL_RTX))
- in_libcall_block = 0;
- }
- }
+ n_basic_blocks = count_basic_blocks (f);
+
+ /* Size the basic block table. The actual structures will be allocated
+ by find_basic_blocks_1, since we want to keep the structure pointers
+ stable across calls to find_basic_blocks. */
+ /* ??? This whole issue would be much simpler if we called find_basic_blocks
+ exactly once, and thereafter we don't have a single long chain of
+ instructions at all until close to the end of compilation when we
+ actually lay them out. */
+
+ VARRAY_BB_INIT (basic_block_info, n_basic_blocks, "basic_block_info");
- n_basic_blocks = i;
+ /* An array to record the active exception region at the end of each
+ basic block. It is filled in by find_basic_blocks_1 for make_edges. */
+ bb_eh_end = (rtx *) alloca (n_basic_blocks * sizeof (rtx));
+ label_value_list = find_basic_blocks_1 (f, bb_eh_end);
+
+ /* Record the block to which an insn belongs. */
+ /* ??? This should be done another way, by which (perhaps) a label is
+ tagged directly with the basic block that it starts. It is used for
+ more than that currently, but IMO that is the only valid use. */
+
+ max_uid = get_max_uid ();
#ifdef AUTO_INC_DEC
/* Leave space for insns life_analysis makes in some cases for auto-inc.
These cases are rare, so we don't need too much space. */
- max_uid_for_flow += max_uid_for_flow / 10;
+ max_uid += max_uid / 10;
#endif
- max_uid_for_flow += extra_uids_for_flow;
- /* Allocate some tables that last till end of compiling this function
- and some needed only in find_basic_blocks and life_analysis. */
+ VARRAY_BB_INIT (basic_block_for_insn, max_uid, "basic_block_for_insn");
+ compute_bb_for_insn (basic_block_for_insn, max_uid);
- basic_block_head = (rtx *) xmalloc (n_basic_blocks * sizeof (rtx));
- basic_block_end = (rtx *) xmalloc (n_basic_blocks * sizeof (rtx));
- basic_block_drops_in = (char *) xmalloc (n_basic_blocks);
- basic_block_computed_jump_target = (char *) oballoc (n_basic_blocks);
- basic_block_loop_depth = (short *) xmalloc (n_basic_blocks * sizeof (short));
- uid_block_number
- = (int *) xmalloc ((max_uid_for_flow + 1) * sizeof (int));
- uid_volatile = (char *) xcalloc (max_uid_for_flow + 1, 1);
+ /* Discover the edges of our cfg. */
- find_basic_blocks_1 (f, nonlocal_label_list, live_reachable_p);
-}
+ make_edges (label_value_list, bb_eh_end);
-/* Find all basic blocks of the function whose first insn is F.
- Store the correct data in the tables that describe the basic blocks,
- set up the chains of references for each CODE_LABEL, and
- delete any entire basic blocks that cannot be reached.
+ /* Delete unreachable blocks. */
+ /* ??? Do this conditionally, or make this another entry point? */
- NONLOCAL_LABEL_LIST is a list of non-local labels in the function.
- Blocks that are otherwise unreachable may be reachable with a non-local
- goto.
- LIVE_REACHABLE_P is non-zero if the caller needs all live blocks to
- be reachable. This turns on a kludge that causes the control flow
- information to be inaccurate and not suitable for passes like GCSE. */
+ delete_unreachable_blocks ();
-static void
-find_basic_blocks_1 (f, nonlocal_label_list, live_reachable_p)
- rtx f, nonlocal_label_list;
- int live_reachable_p;
+ /* Mark critical edges. */
+
+ mark_critical_edges ();
+
+ /* Discover the loop depth at the start of each basic block to aid
+ register allocation. */
+ calculate_loop_depth (f);
+
+ /* Kill the data we won't maintain. */
+ label_value_list = 0;
+}
+
+/* Count the basic blocks of the function. */
+
+static int
+count_basic_blocks (f)
+ rtx f;
{
register rtx insn;
- register int i;
- register char *block_live = (char *) alloca (n_basic_blocks);
- register char *block_marked = (char *) alloca (n_basic_blocks);
- /* An array of CODE_LABELs, indexed by UID for the start of the active
- EH handler for each insn in F. */
- int *active_eh_region;
- int *nested_eh_region;
- /* List of label_refs to all labels whose addresses are taken
- and used as data. */
- rtx label_value_list;
- rtx x, note, eh_note;
- enum rtx_code prev_code, code;
- int depth, pass;
+ register RTX_CODE prev_code;
+ register int count = 0;
+ int eh_region = 0;
int in_libcall_block = 0;
- int deleted_handler = 0;
int call_had_abnormal_edge = 0;
+ rtx prev_call = NULL_RTX;
- pass = 1;
- active_eh_region = (int *) alloca ((max_uid_for_flow + 1) * sizeof (int));
- nested_eh_region = (int *) alloca ((max_label_num () + 1) * sizeof (int));
- restart:
+ prev_code = JUMP_INSN;
+ for (insn = f; insn; insn = NEXT_INSN (insn))
+ {
+ register RTX_CODE code = GET_CODE (insn);
- label_value_list = 0;
- block_live_static = block_live;
- bzero (block_live, n_basic_blocks);
- bzero (block_marked, n_basic_blocks);
- bzero (basic_block_computed_jump_target, n_basic_blocks);
- bzero ((char *) active_eh_region, (max_uid_for_flow + 1) * sizeof (int));
- bzero ((char *) nested_eh_region, (max_label_num () + 1) * sizeof (int));
- current_function_has_computed_jump = 0;
+ /* Track when we are inside in LIBCALL block. */
+ if (GET_RTX_CLASS (code) == 'i'
+ && find_reg_note (insn, REG_LIBCALL, NULL_RTX))
+ in_libcall_block = 1;
- /* Initialize with just block 0 reachable and no blocks marked. */
- if (n_basic_blocks > 0)
- block_live[0] = 1;
+ if (code == CODE_LABEL
+ || (GET_RTX_CLASS (code) == 'i'
+ && (prev_code == JUMP_INSN
+ || prev_code == BARRIER
+ || (prev_code == CALL_INSN && call_had_abnormal_edge))))
+ {
+ count++;
+
+ /* If the previous insn was a call that did not create an
+ abnormal edge, we want to add a nop so that the CALL_INSN
+ itself is not at basic_block_end. This allows us to
+ easily distinguish between normal calls and those which
+ create abnormal edges in the flow graph. */
+
+ if (count > 0 && prev_call != 0 && !call_had_abnormal_edge)
+ {
+ rtx nop = gen_rtx_USE (VOIDmode, const0_rtx);
+ emit_insn_after (nop, prev_call);
+ }
+ }
- /* Initialize the ref chain of each label to 0. Record where all the
- blocks start and end and their depth in loops. For each insn, record
- the block it is in. Also mark as reachable any blocks headed by labels
- that must not be deleted. */
+ /* Record whether this call created an edge. */
+ if (code == CALL_INSN)
+ {
+ prev_call = insn;
+ call_had_abnormal_edge = 0;
+ if (nonlocal_goto_handler_labels)
+ call_had_abnormal_edge = !in_libcall_block;
+ else if (eh_region)
+ {
+ rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
+ if (!note || XINT (XEXP (note, 0), 0) != 0)
+ call_had_abnormal_edge = 1;
+ }
+ }
+ else if (code != NOTE)
+ prev_call = NULL_RTX;
- for (eh_note = NULL_RTX, insn = f, i = -1, prev_code = JUMP_INSN, depth = 1;
- insn; insn = NEXT_INSN (insn))
+ if (code != NOTE)
+ prev_code = code;
+ else if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_BEG)
+ ++eh_region;
+ else if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_END)
+ --eh_region;
+
+ if (GET_RTX_CLASS (GET_CODE (insn)) == 'i'
+ && find_reg_note (insn, REG_RETVAL, NULL_RTX))
+ in_libcall_block = 0;
+ }
+
+ /* The rest of the compiler works a bit smoother when we don't have to
+ check for the edge case of do-nothing functions with no basic blocks. */
+ if (count == 0)
{
+ emit_insn (gen_rtx_USE (VOIDmode, const0_rtx));
+ count = 1;
+ }
+
+ return count;
+}
+
+/* Find all basic blocks of the function whose first insn is F.
+ Store the correct data in the tables that describe the basic blocks,
+ set up the chains of references for each CODE_LABEL, and
+ delete any entire basic blocks that cannot be reached.
+
+ NONLOCAL_LABEL_LIST is a list of non-local labels in the function. Blocks
+ that are otherwise unreachable may be reachable with a non-local goto.
+
+ BB_EH_END is an array in which we record the list of exception regions
+ active at the end of every basic block. */
+
+static rtx
+find_basic_blocks_1 (f, bb_eh_end)
+ rtx f;
+ rtx *bb_eh_end;
+{
+ register rtx insn, next;
+ int in_libcall_block = 0;
+ int call_has_abnormal_edge = 0;
+ int i = 0;
+ rtx bb_note = NULL_RTX;
+ rtx eh_list = NULL_RTX;
+ rtx label_value_list = NULL_RTX;
+ rtx head = NULL_RTX;
+ rtx end = NULL_RTX;
+
+ /* We process the instructions in a slightly different way than we did
+ previously. This is so that we see a NOTE_BASIC_BLOCK after we have
+ closed out the previous block, so that it gets attached at the proper
+ place. Since this form should be equivalent to the previous,
+ find_basic_blocks_0 continues to use the old form as a check. */
+
+ for (insn = f; insn; insn = next)
+ {
+ enum rtx_code code = GET_CODE (insn);
+
+ next = NEXT_INSN (insn);
/* Track when we are inside in LIBCALL block. */
- if (GET_RTX_CLASS (GET_CODE (insn)) == 'i'
+ if (GET_RTX_CLASS (code) == 'i'
&& find_reg_note (insn, REG_LIBCALL, NULL_RTX))
in_libcall_block = 1;
- code = GET_CODE (insn);
- if (code == NOTE)
+ if (code == CALL_INSN)
{
- if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_BEG)
- depth++;
- else if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_END)
- depth--;
+ /* Record whether this call created an edge. */
+ call_has_abnormal_edge = 0;
+ if (nonlocal_goto_handler_labels)
+ call_has_abnormal_edge = !in_libcall_block;
+ else if (eh_list)
+ {
+ rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
+ if (!note || XINT (XEXP (note, 0), 0) != 0)
+ call_has_abnormal_edge = 1;
+ }
}
- /* A basic block starts at label, or after something that can jump. */
- else if (code == CODE_LABEL
- || (GET_RTX_CLASS (code) == 'i'
- && (prev_code == JUMP_INSN
- || (prev_code == CALL_INSN && call_had_abnormal_edge)
- || prev_code == BARRIER)))
+ switch (code)
{
- basic_block_head[++i] = insn;
- basic_block_end[i] = insn;
- basic_block_loop_depth[i] = depth;
+ case NOTE:
+ {
+ int kind = NOTE_LINE_NUMBER (insn);
+
+ /* Keep a LIFO list of the currently active exception notes. */
+ if (kind == NOTE_INSN_EH_REGION_BEG)
+ eh_list = gen_rtx_INSN_LIST (VOIDmode, insn, eh_list);
+ else if (kind == NOTE_INSN_EH_REGION_END)
+ eh_list = XEXP (eh_list, 1);
+
+ /* Look for basic block notes with which to keep the
+ basic_block_info pointers stable. Unthread the note now;
+ we'll put it back at the right place in create_basic_block.
+ Or not at all if we've already found a note in this block. */
+ else if (kind == NOTE_INSN_BASIC_BLOCK)
+ {
+ if (bb_note == NULL_RTX)
+ bb_note = insn;
+ next = flow_delete_insn (insn);
+ }
+
+ break;
+ }
- if (code == CODE_LABEL)
+ case CODE_LABEL:
+ /* A basic block starts at a label. If we've closed one off due
+ to a barrier or some such, no need to do it again. */
+ if (head != NULL_RTX)
{
- LABEL_REFS (insn) = insn;
- /* Any label that cannot be deleted
- is considered to start a reachable block. */
- if (LABEL_PRESERVE_P (insn))
- block_live[i] = 1;
+ /* While we now have edge lists with which other portions of
+ the compiler might determine a call ending a basic block
+ does not imply an abnormal edge, it will be a bit before
+ everything can be updated. So continue to emit a noop at
+ the end of such a block. */
+ if (GET_CODE (end) == CALL_INSN)
+ {
+ rtx nop = gen_rtx_USE (VOIDmode, const0_rtx);
+ end = emit_insn_after (nop, end);
+ }
+
+ bb_eh_end[i] = eh_list;
+ create_basic_block (i++, head, end, bb_note);
+ bb_note = NULL_RTX;
}
+ head = end = insn;
+ break;
- /* If the previous insn was a call that did not create an
- abnormal edge, we want to add a nop so that the CALL_INSN
- itself is not at basic_block_end. This allows us to easily
- distinguish between normal calls and those which create
- abnormal edges in the flow graph. */
+ case JUMP_INSN:
+ /* A basic block ends at a jump. */
+ if (head == NULL_RTX)
+ head = insn;
+ else
+ {
+ /* ??? Make a special check for table jumps. The way this
+ happens is truely and amazingly gross. We are about to
+ create a basic block that contains just a code label and
+ an addr*vec jump insn. Worse, an addr_diff_vec creates
+ its own natural loop.
+
+ Prevent this bit of brain damage, pasting things together
+ correctly in make_edges.
- if (i > 0 && !call_had_abnormal_edge
- && GET_CODE (basic_block_end[i-1]) == CALL_INSN)
+ The correct solution involves emitting the table directly
+ on the tablejump instruction as a note, or JUMP_LABEL. */
+
+ if (GET_CODE (PATTERN (insn)) == ADDR_VEC
+ || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC)
+ {
+ head = end = NULL;
+ n_basic_blocks--;
+ break;
+ }
+ }
+ end = insn;
+ goto new_bb_inclusive;
+
+ case BARRIER:
+ /* A basic block ends at a barrier. It may be that an unconditional
+ jump already closed the basic block -- no need to do it again. */
+ if (head == NULL_RTX)
+ break;
+
+ /* While we now have edge lists with which other portions of the
+ compiler might determine a call ending a basic block does not
+ imply an abnormal edge, it will be a bit before everything can
+ be updated. So continue to emit a noop at the end of such a
+ block. */
+ if (GET_CODE (end) == CALL_INSN)
{
rtx nop = gen_rtx_USE (VOIDmode, const0_rtx);
- nop = emit_insn_after (nop, basic_block_end[i-1]);
- basic_block_end[i-1] = nop;
+ end = emit_insn_after (nop, end);
}
- }
+ goto new_bb_exclusive;
- else if (GET_RTX_CLASS (code) == 'i')
- {
- basic_block_end[i] = insn;
- basic_block_loop_depth[i] = depth;
+ case CALL_INSN:
+ /* A basic block ends at a call that can either throw or
+ do a non-local goto. */
+ if (call_has_abnormal_edge)
+ {
+ new_bb_inclusive:
+ if (head == NULL_RTX)
+ head = insn;
+ end = insn;
+
+ new_bb_exclusive:
+ bb_eh_end[i] = eh_list;
+ create_basic_block (i++, head, end, bb_note);
+ head = end = NULL_RTX;
+ bb_note = NULL_RTX;
+ break;
+ }
+ /* FALLTHRU */
+
+ default:
+ if (GET_RTX_CLASS (code) == 'i')
+ {
+ if (head == NULL_RTX)
+ head = insn;
+ end = insn;
+ }
+ break;
}
if (GET_RTX_CLASS (code) == 'i')
{
- /* Make a list of all labels referred to other than by jumps. */
+ rtx note;
+
+ /* Make a list of all labels referred to other than by jumps
+ (which just don't have the REG_LABEL notes).
+
+ Make a special exception for labels followed by an ADDR*VEC,
+ as this would be a part of the tablejump setup code.
+
+ Make a special exception for the eh_return_stub_label, which
+ we know isn't part of any otherwise visible control flow. */
+
for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
- if (REG_NOTE_KIND (note) == REG_LABEL
- && XEXP (note, 0) != eh_return_stub_label)
- label_value_list = gen_rtx_EXPR_LIST (VOIDmode, XEXP (note, 0),
- label_value_list);
+ if (REG_NOTE_KIND (note) == REG_LABEL)
+ {
+ rtx lab = XEXP (note, 0), next;
+
+ if (lab == eh_return_stub_label)
+ ;
+ else if ((next = next_nonnote_insn (lab)) != NULL
+ && GET_CODE (next) == JUMP_INSN
+ && (GET_CODE (PATTERN (next)) == ADDR_VEC
+ || GET_CODE (PATTERN (next)) == ADDR_DIFF_VEC))
+ ;
+ else
+ label_value_list
+ = gen_rtx_EXPR_LIST (VOIDmode, XEXP (note, 0),
+ label_value_list);
+ }
+
+ if (find_reg_note (insn, REG_RETVAL, NULL_RTX))
+ in_libcall_block = 0;
}
+ }
- /* Keep a lifo list of the currently active exception notes. */
- if (GET_CODE (insn) == NOTE)
+ if (head != NULL_RTX)
+ {
+ bb_eh_end[i] = eh_list;
+ create_basic_block (i++, head, end, bb_note);
+ }
+
+ if (i != n_basic_blocks)
+ abort ();
+
+ return label_value_list;
+}
+
+/* Create a new basic block consisting of the instructions between
+ HEAD and END inclusive. Reuses the note and basic block struct
+ in BB_NOTE, if any. */
+
+static void
+create_basic_block (index, head, end, bb_note)
+ int index;
+ rtx head, end, bb_note;
+{
+ basic_block bb;
+
+ if (bb_note
+ && ! RTX_INTEGRATED_P (bb_note)
+ && (bb = NOTE_BASIC_BLOCK (bb_note)) != NULL
+ && bb->aux == NULL)
+ {
+ /* If we found an existing note, thread it back onto the chain. */
+
+ if (GET_CODE (head) == CODE_LABEL)
+ add_insn_after (bb_note, head);
+ else
+ {
+ add_insn_before (bb_note, head);
+ head = bb_note;
+ }
+ }
+ else
+ {
+ /* Otherwise we must create a note and a basic block structure.
+ Since we allow basic block structs in rtl, give the struct
+ the same lifetime by allocating it off the function obstack
+ rather than using malloc. */
+
+ bb = (basic_block) obstack_alloc (function_obstack, sizeof (*bb));
+ memset (bb, 0, sizeof (*bb));
+
+ if (GET_CODE (head) == CODE_LABEL)
+ bb_note = emit_note_after (NOTE_INSN_BASIC_BLOCK, head);
+ else
+ {
+ bb_note = emit_note_before (NOTE_INSN_BASIC_BLOCK, head);
+ head = bb_note;
+ }
+ NOTE_BASIC_BLOCK (bb_note) = bb;
+ }
+
+ bb->head = head;
+ bb->end = end;
+ bb->index = index;
+ BASIC_BLOCK (index) = bb;
+
+ /* Tag the block so that we know it has been used when considering
+ other basic block notes. */
+ bb->aux = bb;
+}
+
+/* Records the basic block struct in BB_FOR_INSN, for every instruction
+ indexed by INSN_UID. MAX is the size of the array. */
+
+static void
+compute_bb_for_insn (bb_for_insn, max)
+ varray_type bb_for_insn;
+ int max;
+{
+ int i;
+
+ for (i = 0; i < n_basic_blocks; ++i)
+ {
+ basic_block bb = BASIC_BLOCK (i);
+ rtx insn, end;
+
+ end = bb->end;
+ insn = bb->head;
+ while (1)
+ {
+ int uid = INSN_UID (insn);
+ if (uid < max)
+ VARRAY_BB (bb_for_insn, uid) = bb;
+ if (insn == end)
+ break;
+ insn = NEXT_INSN (insn);
+ }
+ }
+}
+
+/* Free the memory associated with the edge structures. */
+
+static void
+clear_edges ()
+{
+ int i;
+ edge n, e;
+
+ for (i = 0; i < n_basic_blocks; ++i)
+ {
+ basic_block bb = BASIC_BLOCK (i);
+
+ for (e = bb->succ; e ; e = n)
{
- if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_BEG)
+ n = e->succ_next;
+ free (e);
+ }
+
+ bb->succ = 0;
+ bb->pred = 0;
+ }
+
+ for (e = ENTRY_BLOCK_PTR->succ; e ; e = n)
+ {
+ n = e->succ_next;
+ free (e);
+ }
+
+ ENTRY_BLOCK_PTR->succ = 0;
+ EXIT_BLOCK_PTR->pred = 0;
+}
+
+/* Identify the edges between basic blocks.
+
+ NONLOCAL_LABEL_LIST is a list of non-local labels in the function. Blocks
+ that are otherwise unreachable may be reachable with a non-local goto.
+
+ BB_EH_END is an array indexed by basic block number in which we record
+ the list of exception regions active at the end of the basic block. */
+
+static void
+make_edges (label_value_list, bb_eh_end)
+ rtx label_value_list;
+ rtx *bb_eh_end;
+{
+ int i;
+
+ /* Assume no computed jump; revise as we create edges. */
+ current_function_has_computed_jump = 0;
+
+ /* By nature of the way these get numbered, block 0 is always the entry. */
+ make_edge (ENTRY_BLOCK_PTR, BASIC_BLOCK (0), EDGE_FALLTHRU);
+
+ for (i = 0; i < n_basic_blocks; ++i)
+ {
+ basic_block bb = BASIC_BLOCK (i);
+ rtx insn, x, eh_list;
+ enum rtx_code code;
+ int force_fallthru = 0;
+
+ /* If we have asynchronous exceptions, scan the notes for all exception
+ regions active in the block. In the normal case, we only need the
+ one active at the end of the block, which is bb_eh_end[i]. */
+
+ eh_list = bb_eh_end[i];
+ if (asynchronous_exceptions)
+ {
+ for (insn = bb->end; insn != bb->head; insn = PREV_INSN (insn))
{
- if (eh_note)
- nested_eh_region [NOTE_BLOCK_NUMBER (insn)] =
- NOTE_BLOCK_NUMBER (XEXP (eh_note, 0));
- else
- nested_eh_region [NOTE_BLOCK_NUMBER (insn)] = 0;
- eh_note = gen_rtx_EXPR_LIST (VOIDmode,
- insn, eh_note);
+ if (GET_CODE (insn) == NOTE
+ && NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_END)
+ eh_list = gen_rtx_INSN_LIST (VOIDmode, insn, eh_list);
}
- else if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_END)
- eh_note = XEXP (eh_note, 1);
}
- /* If we encounter a CALL_INSN, note which exception handler it
- might pass control to.
-
- If doing asynchronous exceptions, record the active EH handler
- for every insn, since most insns can throw. */
- else if (eh_note
- && (asynchronous_exceptions
- || (GET_CODE (insn) == CALL_INSN
- && ! in_libcall_block)))
- active_eh_region[INSN_UID (insn)] =
- NOTE_BLOCK_NUMBER (XEXP (eh_note, 0));
- BLOCK_NUM (insn) = i;
-
- /* We change the code of the CALL_INSN, so that it won't start a
- new block. */
- if (code == CALL_INSN && in_libcall_block)
- code = INSN;
- /* Record whether this call created an edge. */
- if (code == CALL_INSN)
- call_had_abnormal_edge = (nonlocal_label_list != 0 || eh_note);
+ /* Now examine the last instruction of the block, and discover the
+ ways we can leave the block. */
- if (code != NOTE)
- prev_code = code;
+ insn = bb->end;
+ code = GET_CODE (insn);
- if (GET_RTX_CLASS (GET_CODE (insn)) == 'i'
- && find_reg_note (insn, REG_RETVAL, NULL_RTX))
- in_libcall_block = 0;
+ /* A branch. */
+ if (code == JUMP_INSN)
+ {
+ rtx tmp;
+
+ /* ??? Recognize a tablejump and do the right thing. */
+ if ((tmp = JUMP_LABEL (insn)) != NULL_RTX
+ && (tmp = NEXT_INSN (tmp)) != NULL_RTX
+ && GET_CODE (tmp) == JUMP_INSN
+ && (GET_CODE (PATTERN (tmp)) == ADDR_VEC
+ || GET_CODE (PATTERN (tmp)) == ADDR_DIFF_VEC))
+ {
+ rtvec vec;
+ int j;
+
+ if (GET_CODE (PATTERN (tmp)) == ADDR_VEC)
+ vec = XVEC (PATTERN (tmp), 0);
+ else
+ vec = XVEC (PATTERN (tmp), 1);
+
+ for (j = GET_NUM_ELEM (vec) - 1; j >= 0; --j)
+ make_label_edge (bb, XEXP (RTVEC_ELT (vec, j), 0), 0);
+
+ /* Some targets (eg, ARM) emit a conditional jump that also
+ contains the out-of-range target. Scan for these and
+ add an edge if necessary. */
+ if ((tmp = single_set (insn)) != NULL
+ && SET_DEST (tmp) == pc_rtx
+ && GET_CODE (SET_SRC (tmp)) == IF_THEN_ELSE
+ && GET_CODE (XEXP (SET_SRC (tmp), 2)) == LABEL_REF)
+ make_label_edge (bb, XEXP (XEXP (SET_SRC (tmp), 2), 0), 0);
+
+#ifdef CASE_DROPS_THROUGH
+ /* Silly VAXen. The ADDR_VEC is going to be in the way of
+ us naturally detecting fallthru into the next block. */
+ force_fallthru = 1;
+#endif
+ }
+
+ /* If this is a computed jump, then mark it as reaching
+ everything on the label_value_list and forced_labels list. */
+ else if (computed_jump_p (insn))
+ {
+ current_function_has_computed_jump = 1;
+
+ for (x = label_value_list; x; x = XEXP (x, 1))
+ make_label_edge (bb, XEXP (x, 0), EDGE_ABNORMAL);
+
+ for (x = forced_labels; x; x = XEXP (x, 1))
+ make_label_edge (bb, XEXP (x, 0), EDGE_ABNORMAL);
+ }
+
+ /* Returns create an exit out. */
+ else if (returnjump_p (insn))
+ make_edge (bb, EXIT_BLOCK_PTR, 0);
+
+ /* Otherwise, we have a plain conditional or unconditional jump. */
+ else
+ {
+ if (! JUMP_LABEL (insn))
+ abort ();
+ make_label_edge (bb, JUMP_LABEL (insn), 0);
+ }
+ }
+
+ /* If this is a CALL_INSN, then mark it as reaching the active EH
+ handler for this CALL_INSN. If we're handling asynchronous
+ exceptions then any insn can reach any of the active handlers.
+
+ Also mark the CALL_INSN as reaching any nonlocal goto handler. */
+
+ else if (code == CALL_INSN || asynchronous_exceptions)
+ {
+ int is_call = (code == CALL_INSN ? EDGE_ABNORMAL_CALL : 0);
+ handler_info *ptr;
+
+ /* Use REG_EH_RETHROW and REG_EH_REGION if available. */
+ /* ??? REG_EH_REGION is not generated presently. Is it
+ inteded that there be multiple notes for the regions?
+ or is my eh_list collection redundant with handler linking? */
+
+ x = find_reg_note (insn, REG_EH_RETHROW, 0);
+ if (!x)
+ x = find_reg_note (insn, REG_EH_REGION, 0);
+ if (x)
+ {
+ if (XINT (XEXP (x, 0), 0) != 0)
+ {
+ ptr = get_first_handler (XINT (XEXP (x, 0), 0));
+ while (ptr)
+ {
+ make_label_edge (bb, ptr->handler_label,
+ EDGE_ABNORMAL | EDGE_EH | is_call);
+ ptr = ptr->next;
+ }
+ }
+ }
+ else
+ {
+ for (x = eh_list; x; x = XEXP (x, 1))
+ {
+ ptr = get_first_handler (NOTE_BLOCK_NUMBER (XEXP (x, 0)));
+ while (ptr)
+ {
+ make_label_edge (bb, ptr->handler_label,
+ EDGE_ABNORMAL | EDGE_EH | is_call);
+ ptr = ptr->next;
+ }
+ }
+ }
+
+ if (code == CALL_INSN && nonlocal_goto_handler_labels)
+ {
+ /* ??? This could be made smarter: in some cases it's possible
+ to tell that certain calls will not do a nonlocal goto.
+
+ For example, if the nested functions that do the nonlocal
+ gotos do not have their addresses taken, then only calls to
+ those functions or to other nested functions that use them
+ could possibly do nonlocal gotos. */
+
+ for (x = nonlocal_goto_handler_labels; x ; x = XEXP (x, 1))
+ make_label_edge (bb, XEXP (x, 0),
+ EDGE_ABNORMAL | EDGE_ABNORMAL_CALL);
+ }
+ }
+
+ /* We know something about the structure of the function __throw in
+ libgcc2.c. It is the only function that ever contains eh_stub
+ labels. It modifies its return address so that the last block
+ returns to one of the eh_stub labels within it. So we have to
+ make additional edges in the flow graph. */
+ if (i + 1 == n_basic_blocks && eh_return_stub_label != 0)
+ make_label_edge (bb, eh_return_stub_label, EDGE_EH);
+
+ /* Find out if we can drop through to the next block. */
+ insn = next_nonnote_insn (insn);
+ if (!insn || (i + 1 == n_basic_blocks && force_fallthru))
+ make_edge (bb, EXIT_BLOCK_PTR, EDGE_FALLTHRU);
+ else if (i + 1 < n_basic_blocks)
+ {
+ rtx tmp = BLOCK_HEAD (i + 1);
+ if (GET_CODE (tmp) == NOTE)
+ tmp = next_nonnote_insn (tmp);
+ if (force_fallthru || insn == tmp)
+ make_edge (bb, BASIC_BLOCK (i + 1), EDGE_FALLTHRU);
+ }
}
+}
+
+/* Create an edge between two basic blocks. FLAGS are auxiliary information
+ about the edge that is accumulated between calls. */
+
+static void
+make_edge (src, dst, flags)
+ basic_block src, dst;
+ int flags;
+{
+ edge e;
+
+ /* Make sure we don't add duplicate edges. */
- /* During the second pass, `n_basic_blocks' is only an upper bound.
- Only perform the sanity check for the first pass, and on the second
- pass ensure `n_basic_blocks' is set to the correct value. */
- if (pass == 1 && i + 1 != n_basic_blocks)
+ for (e = src->succ; e ; e = e->succ_next)
+ if (e->dest == dst)
+ {
+ e->flags |= flags;
+ return;
+ }
+
+ e = (edge) xcalloc (1, sizeof (*e));
+
+ e->succ_next = src->succ;
+ e->pred_next = dst->pred;
+ e->src = src;
+ e->dest = dst;
+ e->flags = flags;
+
+ src->succ = e;
+ dst->pred = e;
+}
+
+/* Create an edge from a basic block to a label. */
+
+static void
+make_label_edge (src, label, flags)
+ basic_block src;
+ rtx label;
+ int flags;
+{
+ if (GET_CODE (label) != CODE_LABEL)
abort ();
- n_basic_blocks = i + 1;
- /* Record which basic blocks control can drop in to. */
+ /* If the label was never emitted, this insn is junk, but avoid a
+ crash trying to refer to BLOCK_FOR_INSN (label). This can happen
+ as a result of a syntax error and a diagnostic has already been
+ printed. */
- for (i = 0; i < n_basic_blocks; i++)
+ if (INSN_UID (label) == 0)
+ return;
+
+ make_edge (src, BLOCK_FOR_INSN (label), flags);
+}
+
+/* Identify critical edges and set the bits appropriately. */
+static void
+mark_critical_edges ()
+{
+ int i, n = n_basic_blocks;
+ basic_block bb;
+
+ /* We begin with the entry block. This is not terribly important now,
+ but could be if a front end (Fortran) implemented alternate entry
+ points. */
+ bb = ENTRY_BLOCK_PTR;
+ i = -1;
+
+ while (1)
{
- for (insn = PREV_INSN (basic_block_head[i]);
- insn && GET_CODE (insn) == NOTE; insn = PREV_INSN (insn))
- ;
+ edge e;
- basic_block_drops_in[i] = insn && GET_CODE (insn) != BARRIER;
+ /* (1) Critical edges must have a source with multiple successors. */
+ if (bb->succ && bb->succ->succ_next)
+ {
+ for (e = bb->succ; e ; e = e->succ_next)
+ {
+ /* (2) Critical edges must have a destination with multiple
+ predecessors. Note that we know there is at least one
+ predecessor -- the edge we followed to get here. */
+ if (e->dest->pred->pred_next)
+ e->flags |= EDGE_CRITICAL;
+ else
+ e->flags &= ~EDGE_CRITICAL;
+ }
+ }
+ else
+ {
+ for (e = bb->succ; e ; e = e->succ_next)
+ e->flags &= ~EDGE_CRITICAL;
+ }
+
+ if (++i >= n)
+ break;
+ bb = BASIC_BLOCK (i);
}
+}
+
+/* Split a (typically critical) edge. Return the new block.
+ Abort on abnormal edges.
- /* Now find which basic blocks can actually be reached
- and put all jump insns' LABEL_REFS onto the ref-chains
- of their target labels. */
+ ??? The code generally expects to be called on critical edges.
+ The case of a block ending in an unconditional jump to a
+ block with multiple predecessors is not handled optimally. */
- if (n_basic_blocks > 0)
+basic_block
+split_edge (edge_in)
+ edge edge_in;
+{
+ basic_block old_pred, bb, old_succ;
+ edge edge_out;
+ rtx bb_note;
+ int i;
+
+ /* Abnormal edges cannot be split. */
+ if ((edge_in->flags & EDGE_ABNORMAL) != 0)
+ abort ();
+
+ old_pred = edge_in->src;
+ old_succ = edge_in->dest;
+
+ /* Remove the existing edge from the destination's pred list. */
+ {
+ edge *pp;
+ for (pp = &old_succ->pred; *pp != edge_in; pp = &(*pp)->pred_next)
+ continue;
+ *pp = edge_in->pred_next;
+ }
+
+ /* Create the new structures. */
+ bb = (basic_block) obstack_alloc (function_obstack, sizeof (*bb));
+ edge_out = (edge) xcalloc (1, sizeof (*edge_out));
+
+ memset (bb, 0, sizeof (*bb));
+ bb->local_set = OBSTACK_ALLOC_REG_SET (function_obstack);
+ bb->global_live_at_start = OBSTACK_ALLOC_REG_SET (function_obstack);
+ bb->global_live_at_end = OBSTACK_ALLOC_REG_SET (function_obstack);
+
+ /* ??? This info is likely going to be out of date very soon. */
+ CLEAR_REG_SET (bb->local_set);
+ if (old_succ->global_live_at_start)
+ {
+ COPY_REG_SET (bb->global_live_at_start, old_succ->global_live_at_start);
+ COPY_REG_SET (bb->global_live_at_end, old_succ->global_live_at_start);
+ }
+ else
{
- int something_marked = 1;
- int deleted;
+ CLEAR_REG_SET (bb->global_live_at_start);
+ CLEAR_REG_SET (bb->global_live_at_end);
+ }
- /* Pass over all blocks, marking each block that is reachable
- and has not yet been marked.
- Keep doing this until, in one pass, no blocks have been marked.
- Then blocks_live and blocks_marked are identical and correct.
- In addition, all jumps actually reachable have been marked. */
+ /* Wire them up. */
+ bb->pred = edge_in;
+ bb->succ = edge_out;
+ edge_in->dest = bb;
+ edge_out->src = bb;
+ edge_out->dest = old_succ;
+
+ /* Tricky case -- if there existed a fallthru into the successor
+ (and we're not it) we must add a new unconditional jump around
+ the new block we're actually interested in.
+
+ Further, if that edge is critical, this means a second new basic
+ block must be created to hold it. In order to simplify correct
+ insn placement, do this before we touch the existing basic block
+ ordering for the block we were really wanting. */
+ if ((edge_in->flags & EDGE_FALLTHRU) == 0)
+ {
+ edge e;
+ for (e = old_succ->pred; e ; e = e->pred_next)
+ if (e->flags & EDGE_FALLTHRU)
+ break;
- while (something_marked)
+ if (e)
{
- something_marked = 0;
- for (i = 0; i < n_basic_blocks; i++)
- if (block_live[i] && !block_marked[i])
+ basic_block jump_block;
+ rtx pos;
+
+ if ((e->flags & EDGE_CRITICAL) == 0)
+ {
+ /* Non critical -- we can simply add a jump to the end
+ of the existing predecessor. */
+ jump_block = e->src;
+ pos = jump_block->end;
+ }
+ else
+ {
+ /* We need a new block to hold the jump. The simplest
+ way to do the bulk of the work here is to recursively
+ call ourselves. */
+ jump_block = split_edge (e);
+ e = jump_block->succ;
+ pos = jump_block->head;
+ }
+
+ /* Now add the jump insn... */
+ pos = emit_jump_insn_after (gen_jump (old_succ->head), pos);
+ jump_block->end = pos;
+ emit_barrier_after (pos);
+
+ /* ... and clear fallthru on the outgoing edge. */
+ e->flags &= ~EDGE_FALLTHRU;
+
+ /* Continue splitting the interesting edge. */
+ }
+ }
+
+ /* Place the new block just in front of the successor. */
+ VARRAY_GROW (basic_block_info, ++n_basic_blocks);
+ for (i = n_basic_blocks - 1; i > old_succ->index; --i)
+ {
+ basic_block tmp = BASIC_BLOCK (i - 1);
+ BASIC_BLOCK (i) = tmp;
+ tmp->index = i;
+ }
+ BASIC_BLOCK (i) = bb;
+ bb->index = i;
+
+ /* Create the basic block note. */
+ bb_note = emit_note_before (NOTE_INSN_BASIC_BLOCK, old_succ->head);
+ NOTE_BASIC_BLOCK (bb_note) = bb;
+ bb->head = bb->end = bb_note;
+
+ /* Not quite simple -- for non-fallthru edges, we must adjust the
+ predecessor's jump instruction to target our new block. */
+ if ((edge_in->flags & EDGE_FALLTHRU) == 0)
+ {
+ rtx tmp, insn = old_pred->end;
+ rtx old_label = old_succ->head;
+ rtx new_label = gen_label_rtx ();
+
+ if (GET_CODE (insn) != JUMP_INSN)
+ abort ();
+
+ /* ??? Recognize a tablejump and adjust all matching cases. */
+ if ((tmp = JUMP_LABEL (insn)) != NULL_RTX
+ && (tmp = NEXT_INSN (tmp)) != NULL_RTX
+ && GET_CODE (tmp) == JUMP_INSN
+ && (GET_CODE (PATTERN (tmp)) == ADDR_VEC
+ || GET_CODE (PATTERN (tmp)) == ADDR_DIFF_VEC))
+ {
+ rtvec vec;
+ int j;
+
+ if (GET_CODE (PATTERN (tmp)) == ADDR_VEC)
+ vec = XVEC (PATTERN (tmp), 0);
+ else
+ vec = XVEC (PATTERN (tmp), 1);
+
+ for (j = GET_NUM_ELEM (vec) - 1; j >= 0; --j)
+ if (XEXP (RTVEC_ELT (vec, j), 0) == old_label)
{
- block_marked[i] = 1;
- something_marked = 1;
- if (i + 1 < n_basic_blocks && basic_block_drops_in[i + 1])
- block_live[i + 1] = 1;
- insn = basic_block_end[i];
- if (GET_CODE (insn) == JUMP_INSN)
- mark_label_ref (PATTERN (insn), insn, 0);
-
- /* If we have any forced labels, mark them as potentially
- reachable from this block. */
- for (x = forced_labels; x; x = XEXP (x, 1))
- if (! LABEL_REF_NONLOCAL_P (x))
- mark_label_ref (gen_rtx_LABEL_REF (VOIDmode, XEXP (x, 0)),
- insn, 0);
-
- /* Now scan the insns for this block, we may need to make
- edges for some of them to various non-obvious locations
- (exception handlers, nonlocal labels, etc). */
- for (insn = basic_block_head[i];
- insn != NEXT_INSN (basic_block_end[i]);
- insn = NEXT_INSN (insn))
- {
- if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
- {
- /* References to labels in non-jumping insns have
- REG_LABEL notes attached to them.
-
- This can happen for computed gotos; we don't care
- about them here since the values are also on the
- label_value_list and will be marked live if we find
- a live computed goto.
-
- This can also happen when we take the address of
- a label to pass as an argument to __throw. Note
- throw only uses the value to determine what handler
- should be called -- ie the label is not used as
- a jump target, it just marks regions in the code.
-
- In theory we should be able to ignore the REG_LABEL
- notes, but we have to make sure that the label and
- associated insns aren't marked dead, so we make
- the block in question live and create an edge from
- this insn to the label. This is not strictly
- correct, but it is close enough for now.
-
- See below for code that handles the eh_stub labels
- specially. */
- for (note = REG_NOTES (insn);
- note;
- note = XEXP (note, 1))
- {
- if (REG_NOTE_KIND (note) == REG_LABEL
- && XEXP (note, 0) != eh_return_stub_label)
- {
- x = XEXP (note, 0);
- block_live[BLOCK_NUM (x)] = 1;
- mark_label_ref (gen_rtx_LABEL_REF (VOIDmode, x),
- insn, 0);
- }
- }
-
- /* If this is a computed jump, then mark it as
- reaching everything on the label_value_list
- and forced_labels list. */
- if (computed_jump_p (insn))
- {
- current_function_has_computed_jump = 1;
- for (x = label_value_list; x; x = XEXP (x, 1))
- {
- int b = BLOCK_NUM (XEXP (x, 0));
- basic_block_computed_jump_target[b] = 1;
- mark_label_ref (gen_rtx_LABEL_REF (VOIDmode,
- XEXP (x, 0)),
- insn, 0);
- }
-
- for (x = forced_labels; x; x = XEXP (x, 1))
- {
- int b = BLOCK_NUM (XEXP (x, 0));
- basic_block_computed_jump_target[b] = 1;
- mark_label_ref (gen_rtx_LABEL_REF (VOIDmode,
- XEXP (x, 0)),
- insn, 0);
- }
- }
-
- /* If this is a CALL_INSN, then mark it as reaching
- the active EH handler for this CALL_INSN. If
- we're handling asynchronous exceptions mark every
- insn as reaching the active EH handler.
-
- Also mark the CALL_INSN as reaching any nonlocal
- goto sites. */
- else if (asynchronous_exceptions
- || (GET_CODE (insn) == CALL_INSN
- && ! find_reg_note (insn, REG_RETVAL,
- NULL_RTX)))
- {
- if (active_eh_region[INSN_UID (insn)])
- {
- int region;
- handler_info *ptr;
- region = active_eh_region[INSN_UID (insn)];
- for ( ; region;
- region = nested_eh_region[region])
- {
- ptr = get_first_handler (region);
- for ( ; ptr ; ptr = ptr->next)
- mark_label_ref (gen_rtx_LABEL_REF
- (VOIDmode, ptr->handler_label), insn, 0);
- }
- }
- if (!asynchronous_exceptions)
- {
- for (x = nonlocal_label_list;
- x;
- x = XEXP (x, 1))
- mark_label_ref (gen_rtx_LABEL_REF (VOIDmode,
- XEXP (x, 0)),
- insn, 0);
- }
- /* ??? This could be made smarter:
- in some cases it's possible to tell that
- certain calls will not do a nonlocal goto.
-
- For example, if the nested functions that
- do the nonlocal gotos do not have their
- addresses taken, then only calls to those
- functions or to other nested functions that
- use them could possibly do nonlocal gotos. */
- }
- }
- }
- /* We know something about the structure of the function
- __throw in libgcc2.c. It is the only function that ever
- contains eh_stub labels. It modifies its return address
- so that the last block returns to one of the eh_stub labels
- within it. So we have to make additional edges in the
- flow graph. */
- if (i + 1 == n_basic_blocks
- && eh_return_stub_label != 0)
- {
- mark_label_ref (gen_rtx_LABEL_REF (VOIDmode,
- eh_return_stub_label),
- basic_block_end[i], 0);
- }
+ RTVEC_ELT (vec, j) = gen_rtx_LABEL_REF (VOIDmode, new_label);
+ --LABEL_NUSES (old_label);
+ ++LABEL_NUSES (new_label);
}
}
+ else
+ {
+ /* This would have indicated an abnormal edge. */
+ if (computed_jump_p (insn))
+ abort ();
+
+ /* A return instruction can't be redirected. */
+ if (returnjump_p (insn))
+ abort ();
+
+ /* If the insn doesn't go where we think, we're confused. */
+ if (JUMP_LABEL (insn) != old_label)
+ abort ();
+
+ redirect_jump (insn, new_label);
+ }
+
+ emit_label_before (new_label, bb_note);
+ bb->head = new_label;
+ }
+
+ /* In all cases, the new block falls through to the successor. */
+ edge_out->flags = EDGE_FALLTHRU;
+
+ return bb;
+}
+
+/* Queue instructions for insertion on an edge between two basic blocks.
+ The new instructions and basic blocks (if any) will not appear in the
+ CFG until commit_edge_insertions is called. */
+
+void
+insert_insn_on_edge (pattern, e)
+ rtx pattern;
+ edge e;
+{
+ /* We cannot insert instructions on an abnormal critical edge.
+ It will be easier to find the culprit if we die now. */
+ if ((e->flags & (EDGE_ABNORMAL|EDGE_CRITICAL))
+ == (EDGE_ABNORMAL|EDGE_CRITICAL))
+ abort ();
+
+ if (e->insns == NULL_RTX)
+ start_sequence ();
+ else
+ push_to_sequence (e->insns);
+
+ emit_insn (pattern);
+
+ e->insns = get_insns ();
+ end_sequence();
+}
+
+/* Update the CFG for the instructions queued on edge E. */
+
+static void
+commit_one_edge_insertion (e)
+ edge e;
+{
+ rtx before = NULL_RTX, after = NULL_RTX, tmp;
+ basic_block bb;
+
+ /* Figure out where to put these things. If the destination has
+ one predecessor, insert there. Except for the exit block. */
+ if (e->dest->pred->pred_next == NULL
+ && e->dest != EXIT_BLOCK_PTR)
+ {
+ bb = e->dest;
+
+ /* Get the location correct wrt a code label, and "nice" wrt
+ a basic block note, and before everything else. */
+ tmp = bb->head;
+ if (GET_CODE (tmp) == CODE_LABEL)
+ tmp = NEXT_INSN (tmp);
+ if (GET_CODE (tmp) == NOTE
+ && NOTE_LINE_NUMBER (tmp) == NOTE_INSN_BASIC_BLOCK)
+ tmp = NEXT_INSN (tmp);
+ if (tmp == bb->head)
+ before = tmp;
+ else
+ after = PREV_INSN (tmp);
+ }
+
+ /* If the source has one successor and the edge is not abnormal,
+ insert there. Except for the entry block. */
+ else if ((e->flags & EDGE_ABNORMAL) == 0
+ && e->src->succ->succ_next == NULL
+ && e->src != ENTRY_BLOCK_PTR)
+ {
+ bb = e->src;
+ if (GET_CODE (bb->end) == JUMP_INSN)
+ {
+ /* ??? Is it possible to wind up with non-simple jumps? Perhaps
+ a jump with delay slots already filled? */
+ if (! simplejump_p (bb->end))
+ abort ();
+
+ before = bb->end;
+ }
+ else
+ {
+ /* We'd better be fallthru, or we've lost track of what's what. */
+ if ((e->flags & EDGE_FALLTHRU) == 0)
+ abort ();
+
+ after = bb->end;
+ }
+ }
+
+ /* Otherwise we must split the edge. */
+ else
+ {
+ bb = split_edge (e);
+ after = bb->end;
+ }
+
+ /* Now that we've found the spot, do the insertion. */
+ tmp = e->insns;
+ e->insns = NULL_RTX;
+ if (before)
+ {
+ emit_insns_before (tmp, before);
+ if (before == bb->head)
+ bb->head = before;
+ }
+ else
+ {
+ tmp = emit_insns_after (tmp, after);
+ if (after == bb->end)
+ bb->end = tmp;
+ }
+}
+
+/* Update the CFG for all queued instructions. */
+
+void
+commit_edge_insertions ()
+{
+ int i;
+ basic_block bb;
+
+ i = -1;
+ bb = ENTRY_BLOCK_PTR;
+ while (1)
+ {
+ edge e, next;
+
+ for (e = bb->succ; e ; e = next)
+ {
+ next = e->succ_next;
+ if (e->insns)
+ commit_one_edge_insertion (e);
+ }
+
+ if (++i >= n_basic_blocks)
+ break;
+ bb = BASIC_BLOCK (i);
+ }
+}
+
+/* Delete all unreachable basic blocks. */
+
+static void
+delete_unreachable_blocks ()
+{
+ basic_block *worklist, *tos;
+ int deleted_handler;
+ edge e;
+ int i, n;
+
+ n = n_basic_blocks;
+ tos = worklist = (basic_block *) alloca (sizeof (basic_block) * n);
+
+ /* Use basic_block->aux as a marker. Clear them all. */
+
+ for (i = 0; i < n; ++i)
+ BASIC_BLOCK (i)->aux = NULL;
+
+ /* Add our starting points to the worklist. Almost always there will
+ be only one. It isn't inconcievable that we might one day directly
+ support Fortran alternate entry points. */
+
+ for (e = ENTRY_BLOCK_PTR->succ; e ; e = e->succ_next)
+ {
+ *tos++ = e->dest;
+
+ /* Mark the block with a handy non-null value. */
+ e->dest->aux = e;
+ }
+
+ /* Iterate: find everything reachable from what we've already seen. */
+
+ while (tos != worklist)
+ {
+ basic_block b = *--tos;
- /* This should never happen. If it does that means we've computed an
- incorrect flow graph, which can lead to aborts/crashes later in the
- compiler or incorrect code generation.
-
- We used to try and continue here, but that's just asking for trouble
- later during the compile or at runtime. It's easier to debug the
- problem here than later! */
- for (i = 1; i < n_basic_blocks; i++)
- if (block_live[i] && ! basic_block_drops_in[i]
- && GET_CODE (basic_block_head[i]) == CODE_LABEL
- && LABEL_REFS (basic_block_head[i]) == basic_block_head[i])
- abort ();
-
- /* Now delete the code for any basic blocks that can't be reached.
- They can occur because jump_optimize does not recognize
- unreachable loops as unreachable. */
-
- deleted = 0;
- for (i = 0; i < n_basic_blocks; i++)
- if (!block_live[i])
+ for (e = b->succ; e ; e = e->succ_next)
+ if (!e->dest->aux)
{
- deleted++;
-
- /* Delete the insns in a (non-live) block. We physically delete
- every non-note insn except the start and end (so
- basic_block_head/end needn't be updated), we turn the latter
- into NOTE_INSN_DELETED notes.
- We use to "delete" the insns by turning them into notes, but
- we may be deleting lots of insns that subsequent passes would
- otherwise have to process. Secondly, lots of deleted blocks in
- a row can really slow down propagate_block since it will
- otherwise process insn-turned-notes multiple times when it
- looks for loop begin/end notes. */
- if (basic_block_head[i] != basic_block_end[i])
- {
- /* It would be quicker to delete all of these with a single
- unchaining, rather than one at a time, but we need to keep
- the NOTE's. */
- insn = NEXT_INSN (basic_block_head[i]);
- while (insn != basic_block_end[i])
- {
- if (GET_CODE (insn) == BARRIER)
- abort ();
- else if (GET_CODE (insn) != NOTE)
- insn = flow_delete_insn (insn);
- else
- insn = NEXT_INSN (insn);
- }
- }
- insn = basic_block_head[i];
- if (GET_CODE (insn) != NOTE)
- {
- /* Turn the head into a deleted insn note. */
- if (GET_CODE (insn) == BARRIER)
- abort ();
-
- /* If the head of this block is a CODE_LABEL, then it might
- be the label for an exception handler which can't be
- reached.
-
- We need to remove the label from the exception_handler_label
- list and remove the associated NOTE_EH_REGION_BEG and
- NOTE_EH_REGION_END notes. */
- if (GET_CODE (insn) == CODE_LABEL)
- {
- rtx x, *prev = &exception_handler_labels;
-
- for (x = exception_handler_labels; x; x = XEXP (x, 1))
- {
- if (XEXP (x, 0) == insn)
- {
- /* Found a match, splice this label out of the
- EH label list. */
- *prev = XEXP (x, 1);
- XEXP (x, 1) = NULL_RTX;
- XEXP (x, 0) = NULL_RTX;
-
- /* Remove the handler from all regions */
- remove_handler (insn);
- deleted_handler = 1;
- break;
- }
- prev = &XEXP (x, 1);
- }
- }
-
- PUT_CODE (insn, NOTE);
- NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
- NOTE_SOURCE_FILE (insn) = 0;
- }
- insn = basic_block_end[i];
- if (GET_CODE (insn) != NOTE)
+ *tos++ = e->dest;
+ e->dest->aux = e;
+ }
+ }
+
+ /* Delete all unreachable basic blocks. Count down so that we don't
+ interfere with the block renumbering that happens in delete_block. */
+
+ deleted_handler = 0;
+
+ for (i = n - 1; i >= 0; --i)
+ {
+ basic_block b = BASIC_BLOCK (i);
+
+ if (b->aux != NULL)
+ /* This block was found. Tidy up the mark. */
+ b->aux = NULL;
+ else
+ deleted_handler |= delete_block (b);
+ }
+
+ /* Fix up edges that now fall through, or rather should now fall through
+ but previously required a jump around now deleted blocks. Simplify
+ the search by only examining blocks numerically adjacent, since this
+ is how find_basic_blocks created them. */
+
+ for (i = 1; i < n_basic_blocks; ++i)
+ {
+ basic_block b = BASIC_BLOCK (i - 1);
+ basic_block c = BASIC_BLOCK (i);
+ edge s;
+
+ /* We only need care for simple unconditional jumps, which implies
+ a single successor. */
+ if ((s = b->succ) != NULL
+ && s->succ_next == NULL
+ && s->dest == c
+ && ! (s->flags & EDGE_FALLTHRU))
+ tidy_fallthru_edge (s, b, c);
+ }
+
+ /* Attempt to merge blocks as made possible by edge removal. If a block
+ has only one successor, and the successor has only one predecessor,
+ they may be combined. */
+
+ for (i = 0; i < n_basic_blocks; )
+ {
+ basic_block c, b = BASIC_BLOCK (i);
+ edge s;
+
+ /* A loop because chains of blocks might be combineable. */
+ while ((s = b->succ) != NULL
+ && s->succ_next == NULL
+ && (c = s->dest) != EXIT_BLOCK_PTR
+ && c->pred->pred_next == NULL
+ && merge_blocks (s, b, c))
+ continue;
+
+ /* Don't get confused by the index shift caused by deleting blocks. */
+ i = b->index + 1;
+ }
+
+ /* If we deleted an exception handler, we may have EH region begin/end
+ blocks to remove as well. */
+ if (deleted_handler)
+ delete_eh_regions ();
+}
+
+/* Find EH regions for which there is no longer a handler, and delete them. */
+
+static void
+delete_eh_regions ()
+{
+ rtx insn;
+
+ for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
+ if (GET_CODE (insn) == NOTE)
+ {
+ if ((NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_BEG) ||
+ (NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_END))
+ {
+ int num = CODE_LABEL_NUMBER (insn);
+ /* A NULL handler indicates a region is no longer needed */
+ if (get_first_handler (num) == NULL)
{
- /* Turn the tail into a deleted insn note. */
- if (GET_CODE (insn) == BARRIER)
- abort ();
- PUT_CODE (insn, NOTE);
NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
NOTE_SOURCE_FILE (insn) = 0;
}
- /* BARRIERs are between basic blocks, not part of one.
- Delete a BARRIER if the preceding jump is deleted.
- We cannot alter a BARRIER into a NOTE
- because it is too short; but we can really delete
- it because it is not part of a basic block. */
- if (NEXT_INSN (insn) != 0
- && GET_CODE (NEXT_INSN (insn)) == BARRIER)
- delete_insn (NEXT_INSN (insn));
-
- /* Each time we delete some basic blocks,
- see if there is a jump around them that is
- being turned into a no-op. If so, delete it. */
-
- if (block_live[i - 1])
- {
- register int j;
- for (j = i + 1; j < n_basic_blocks; j++)
- if (block_live[j])
- {
- rtx label;
- insn = basic_block_end[i - 1];
- if (GET_CODE (insn) == JUMP_INSN
- /* An unconditional jump is the only possibility
- we must check for, since a conditional one
- would make these blocks live. */
- && simplejump_p (insn)
- && (label = XEXP (SET_SRC (PATTERN (insn)), 0), 1)
- && INSN_UID (label) != 0
- && BLOCK_NUM (label) == j)
- {
- int k;
-
- /* The deleted blocks still show up in the cfg,
- so we must set basic_block_drops_in for blocks
- I to J inclusive to keep the cfg accurate. */
- for (k = i; k <= j; k++)
- basic_block_drops_in[k] = 1;
-
- PUT_CODE (insn, NOTE);
- NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
- NOTE_SOURCE_FILE (insn) = 0;
- if (GET_CODE (NEXT_INSN (insn)) != BARRIER)
- abort ();
- delete_insn (NEXT_INSN (insn));
- }
- break;
- }
- }
}
- /* If we deleted an exception handler, we may have EH region
- begin/end blocks to remove as well. */
- if (deleted_handler)
- for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
- if (GET_CODE (insn) == NOTE)
- {
- if ((NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_BEG) ||
- (NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_END))
- {
- int num = CODE_LABEL_NUMBER (insn);
- /* A NULL handler indicates a region is no longer needed */
- if (get_first_handler (num) == NULL)
- {
- NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
- NOTE_SOURCE_FILE (insn) = 0;
- }
- }
- }
-
- /* There are pathological cases where one function calling hundreds of
- nested inline functions can generate lots and lots of unreachable
- blocks that jump can't delete. Since we don't use sparse matrices
- a lot of memory will be needed to compile such functions.
- Implementing sparse matrices is a fair bit of work and it is not
- clear that they win more than they lose (we don't want to
- unnecessarily slow down compilation of normal code). By making
- another pass for the pathological case, we can greatly speed up
- their compilation without hurting normal code. This works because
- all the insns in the unreachable blocks have either been deleted or
- turned into notes.
- Note that we're talking about reducing memory usage by 10's of
- megabytes and reducing compilation time by several minutes. */
- /* ??? The choice of when to make another pass is a bit arbitrary,
- and was derived from empirical data. */
- if (pass == 1
- && deleted > 200)
+ }
+}
+
+/* Return true if NOTE is not one of the ones that must be kept paired,
+ so that we may simply delete them. */
+
+static int
+delete_note_p (note)
+ rtx note;
+{
+ return (NOTE_LINE_NUMBER (note) == NOTE_INSN_DELETED
+ || NOTE_LINE_NUMBER (note) == NOTE_INSN_BASIC_BLOCK);
+}
+
+/* Unlink a chain of insns between START and FINISH, leaving notes
+ that must be paired. */
+
+static void
+delete_insn_chain (start, finish)
+ rtx start, finish;
+{
+ /* Unchain the insns one by one. It would be quicker to delete all
+ of these with a single unchaining, rather than one at a time, but
+ we need to keep the NOTE's. */
+
+ rtx next;
+
+ while (1)
+ {
+ next = NEXT_INSN (start);
+ if (GET_CODE (start) != NOTE || delete_note_p (start))
+ next = flow_delete_insn (start);
+
+ if (start == finish)
+ break;
+ start = next;
+ }
+}
+
+/* Delete the insns in a (non-live) block. We physically delete every
+ non-deleted-note insn, and update the flow graph appropriately.
+
+ Return nonzero if we deleted an exception handler. */
+
+/* ??? Preserving all such notes strikes me as wrong. It would be nice
+ to post-process the stream to remove empty blocks, loops, ranges, etc. */
+
+static int
+delete_block (b)
+ basic_block b;
+{
+ int deleted_handler = 0;
+ rtx insn, end;
+
+ /* If the head of this block is a CODE_LABEL, then it might be the
+ label for an exception handler which can't be reached.
+
+ We need to remove the label from the exception_handler_label list
+ and remove the associated NOTE_EH_REGION_BEG and NOTE_EH_REGION_END
+ notes. */
+
+ insn = b->head;
+
+ if (GET_CODE (insn) == CODE_LABEL)
+ {
+ rtx x, *prev = &exception_handler_labels;
+
+ for (x = exception_handler_labels; x; x = XEXP (x, 1))
+ {
+ if (XEXP (x, 0) == insn)
+ {
+ /* Found a match, splice this label out of the EH label list. */
+ *prev = XEXP (x, 1);
+ XEXP (x, 1) = NULL_RTX;
+ XEXP (x, 0) = NULL_RTX;
+
+ /* Remove the handler from all regions */
+ remove_handler (insn);
+ deleted_handler = 1;
+ break;
+ }
+ prev = &XEXP (x, 1);
+ }
+
+ /* This label may be referenced by code solely for its value, or
+ referenced by static data, or something. We have determined
+ that it is not reachable, but cannot delete the label itself.
+ Save code space and continue to delete the balance of the block,
+ along with properly updating the cfg. */
+ if (!can_delete_label_p (insn))
{
- pass++;
- n_basic_blocks -= deleted;
- /* `n_basic_blocks' may not be correct at this point: two previously
- separate blocks may now be merged. That's ok though as we
- recalculate it during the second pass. It certainly can't be
- any larger than the current value. */
- goto restart;
+ /* If we've only got one of these, skip the whole deleting
+ insns thing. */
+ if (insn == b->end)
+ goto no_delete_insns;
+ insn = NEXT_INSN (insn);
}
}
+
+ /* Selectively unlink the insn chain. Include any BARRIER that may
+ follow the basic block. */
+ end = next_nonnote_insn (b->end);
+ if (!end || GET_CODE (end) != BARRIER)
+ end = b->end;
+ delete_insn_chain (insn, end);
+
+no_delete_insns:
+
+ /* Remove the edges into and out of this block. Note that there may
+ indeed be edges in, if we are removing an unreachable loop. */
+ {
+ edge e, next, *q;
+
+ for (e = b->pred; e ; e = next)
+ {
+ for (q = &e->src->succ; *q != e; q = &(*q)->succ_next)
+ continue;
+ *q = e->succ_next;
+ next = e->pred_next;
+ free (e);
+ }
+ for (e = b->succ; e ; e = next)
+ {
+ for (q = &e->dest->pred; *q != e; q = &(*q)->pred_next)
+ continue;
+ *q = e->pred_next;
+ next = e->succ_next;
+ free (e);
+ }
+
+ b->pred = NULL;
+ b->succ = NULL;
+ }
+
+ /* Remove the basic block from the array, and compact behind it. */
+ expunge_block (b);
+
+ return deleted_handler;
}
-/* Record INSN's block number as BB. */
+/* Remove block B from the basic block array and compact behind it. */
-void
-set_block_num (insn, bb)
- rtx insn;
- int bb;
+static void
+expunge_block (b)
+ basic_block b;
{
- if (INSN_UID (insn) >= max_uid_for_flow)
+ int i, n = n_basic_blocks;
+
+ for (i = b->index; i + 1 < n; ++i)
{
- /* Add one-eighth the size so we don't keep calling xrealloc. */
- max_uid_for_flow = INSN_UID (insn) + (INSN_UID (insn) + 7) / 8;
- uid_block_number = (int *)
- xrealloc (uid_block_number, (max_uid_for_flow + 1) * sizeof (int));
+ basic_block x = BASIC_BLOCK (i + 1);
+ BASIC_BLOCK (i) = x;
+ x->index = i;
}
- BLOCK_NUM (insn) = bb;
+
+ basic_block_info->num_elements--;
+ n_basic_blocks--;
}
-
-/* Subroutines of find_basic_blocks. */
+/* Delete INSN by patching it out. Return the next insn. */
+
+static rtx
+flow_delete_insn (insn)
+ rtx insn;
+{
+ rtx prev = PREV_INSN (insn);
+ rtx next = NEXT_INSN (insn);
+
+ PREV_INSN (insn) = NULL_RTX;
+ NEXT_INSN (insn) = NULL_RTX;
+
+ if (prev)
+ NEXT_INSN (prev) = next;
+ if (next)
+ PREV_INSN (next) = prev;
+ else
+ set_last_insn (prev);
+
+ /* If deleting a jump, decrement the use count of the label. Deleting
+ the label itself should happen in the normal course of block merging. */
+ if (GET_CODE (insn) == JUMP_INSN && JUMP_LABEL (insn))
+ LABEL_NUSES (JUMP_LABEL (insn))--;
+
+ return next;
+}
+
+/* True if a given label can be deleted. */
-/* Check expression X for label references;
- if one is found, add INSN to the label's chain of references.
+static int
+can_delete_label_p (label)
+ rtx label;
+{
+ rtx x;
- CHECKDUP means check for and avoid creating duplicate references
- from the same insn. Such duplicates do no serious harm but
- can slow life analysis. CHECKDUP is set only when duplicates
- are likely. */
+ if (LABEL_PRESERVE_P (label))
+ return 0;
+
+ for (x = forced_labels; x ; x = XEXP (x, 1))
+ if (label == XEXP (x, 0))
+ return 0;
+ for (x = label_value_list; x ; x = XEXP (x, 1))
+ if (label == XEXP (x, 0))
+ return 0;
+ for (x = exception_handler_labels; x ; x = XEXP (x, 1))
+ if (label == XEXP (x, 0))
+ return 0;
+
+ /* User declared labels must be preserved, but we can
+ convert them into a NOTE instead. */
+ if (LABEL_NAME (label) != 0)
+ {
+ PUT_CODE (label, NOTE);
+ NOTE_LINE_NUMBER (label) = NOTE_INSN_DELETED_LABEL;
+ NOTE_SOURCE_FILE (label) = 0;
+ return 0;
+ }
+
+ return 1;
+}
+
+/* Blocks A and B are to be merged into a single block. The insns
+ are already contiguous, hence `nomove'. */
static void
-mark_label_ref (x, insn, checkdup)
- rtx x, insn;
- int checkdup;
+merge_blocks_nomove (a, b)
+ basic_block a, b;
{
- register RTX_CODE code;
- register int i;
- register char *fmt;
+ edge e;
+ rtx insn;
+ int done = 0;
- /* We can be called with NULL when scanning label_value_list. */
- if (x == 0)
- return;
+ /* If there was a jump out of A, delete it. */
+ if (GET_CODE (a->end) == JUMP_INSN)
+ {
+ /* If the jump was the only insn in A, turn the jump into a deleted
+ note, since we may yet not be able to merge the blocks. */
+ if (a->end == a->head)
+ {
+ PUT_CODE (a->head, NOTE);
+ NOTE_LINE_NUMBER (a->head) = NOTE_INSN_DELETED;
+ NOTE_SOURCE_FILE (a->head) = 0;
+ }
+ else
+ {
+ rtx tmp = a->end;
- code = GET_CODE (x);
- if (code == LABEL_REF)
+ a->end = prev_nonnote_insn (tmp);
+
+#ifdef HAVE_cc0
+ /* If this was a conditional jump, we need to also delete
+ the insn that set cc0. */
+ if (! simplejump_p (tmp) && condjump_p (tmp))
+ {
+ PUT_CODE (PREV_INSN (tmp), NOTE);
+ NOTE_LINE_NUMBER (PREV_INSN (tmp)) = NOTE_INSN_DELETED;
+ NOTE_SOURCE_FILE (PREV_INSN (tmp)) = 0;
+ }
+#endif
+
+ flow_delete_insn (tmp);
+ }
+ }
+
+ /* By definition, there should only be one successor of A, and that is
+ B. Free that edge struct. */
+ free (a->succ);
+
+ /* Adjust the edges out of B for the new owner. */
+ for (e = b->succ; e ; e = e->succ_next)
+ e->src = a;
+ a->succ = b->succ;
+
+ /* If there was a CODE_LABEL beginning B, delete it. */
+ insn = b->head;
+ if (GET_CODE (insn) == CODE_LABEL)
{
- register rtx label = XEXP (x, 0);
- register rtx y;
- if (GET_CODE (label) != CODE_LABEL)
- abort ();
- /* If the label was never emitted, this insn is junk,
- but avoid a crash trying to refer to BLOCK_NUM (label).
- This can happen as a result of a syntax error
- and a diagnostic has already been printed. */
- if (INSN_UID (label) == 0)
- return;
- CONTAINING_INSN (x) = insn;
- /* if CHECKDUP is set, check for duplicate ref from same insn
- and don't insert. */
- if (checkdup)
- for (y = LABEL_REFS (label); y != label; y = LABEL_NEXTREF (y))
- if (CONTAINING_INSN (y) == insn)
- return;
- LABEL_NEXTREF (x) = LABEL_REFS (label);
- LABEL_REFS (label) = x;
- block_live_static[BLOCK_NUM (label)] = 1;
- return;
+ /* Detect basic blocks with nothing but a label. This can happen
+ in particular at the end of a function. */
+ if (insn == b->end)
+ done = 1;
+ insn = flow_delete_insn (insn);
}
- fmt = GET_RTX_FORMAT (code);
- for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
+ /* Delete the basic block note. */
+ if (GET_CODE (insn) == NOTE
+ && NOTE_LINE_NUMBER (insn) == NOTE_INSN_BASIC_BLOCK)
{
- if (fmt[i] == 'e')
- mark_label_ref (XEXP (x, i), insn, 0);
- if (fmt[i] == 'E')
+ if (insn == b->end)
+ done = 1;
+ insn = flow_delete_insn (insn);
+ }
+
+ /* Reassociate the insns of B with A. */
+ if (!done)
+ {
+ BLOCK_FOR_INSN (insn) = a;
+ while (insn != b->end)
{
- register int j;
- for (j = 0; j < XVECLEN (x, i); j++)
- mark_label_ref (XVECEXP (x, i, j), insn, 1);
+ insn = NEXT_INSN (insn);
+ BLOCK_FOR_INSN (insn) = a;
}
+ a->end = insn;
}
+
+ /* Compact the basic block array. */
+ expunge_block (b);
}
-/* Delete INSN by patching it out.
- Return the next insn. */
+/* Attempt to merge basic blocks that are potentially non-adjacent.
+ Return true iff the attempt succeeded. */
-static rtx
-flow_delete_insn (insn)
- rtx insn;
+static int
+merge_blocks (e, b, c)
+ edge e;
+ basic_block b, c;
+{
+ /* If B has a fallthru edge to C, no need to move anything. */
+ if (!(e->flags & EDGE_FALLTHRU))
+ {
+ /* ??? From here on out we must make sure to not munge nesting
+ of exception regions and lexical blocks. Need to think about
+ these cases before this gets implemented. */
+ return 0;
+
+ /* If C has an outgoing fallthru, and B does not have an incoming
+ fallthru, move B before C. The later clause is somewhat arbitrary,
+ but avoids modifying blocks other than the two we've been given. */
+
+ /* Otherwise, move C after B. If C had a fallthru, which doesn't
+ happen to be the physical successor to B, insert an unconditional
+ branch. If C already ended with a conditional branch, the new
+ jump must go in a new basic block D. */
+ }
+
+ /* If a label still appears somewhere, we cannot delete the label, which
+ means we cannot merge the blocks. We have still won a tad by tidying
+ the interface between the two blocks. */
+ if (GET_CODE (c->head) == CODE_LABEL
+ && ! can_delete_label_p (c->head))
+ {
+ tidy_fallthru_edge (e, b, c);
+ return 0;
+ }
+
+ merge_blocks_nomove (b, c);
+ return 1;
+}
+
+/* The given edge should potentially a fallthru edge. If that is in
+ fact true, delete the unconditional jump and barriers that are in
+ the way. */
+
+static void
+tidy_fallthru_edge (e, b, c)
+ edge e;
+ basic_block b, c;
+{
+ rtx q, h;
+
+ /* ??? In a late-running flow pass, other folks may have deleted basic
+ blocks by nopping out blocks, leaving multiple BARRIERs between here
+ and the target label. They ought to be chastized and fixed.
+
+ In the mean time, search for the last barrier in a sequence of
+ barriers and notes. */
+
+ q = NEXT_INSN (b->end);
+ if (q && GET_CODE (q) == NOTE)
+ q = next_nonnote_insn (q);
+ while (q && GET_CODE (q) == BARRIER)
+ q = next_nonnote_insn (q);
+
+ /* Assert that we now actually do fall through. */
+ h = c->head;
+ if (GET_CODE (h) == NOTE)
+ h = next_nonnote_insn (h);
+ if (q != h)
+ return;
+
+ /* Remove what will soon cease being the jump insn from the source block.
+ If block B consisted only of this single jump, turn it into a deleted
+ note. */
+ q = b->end;
+ if (GET_CODE (q) == JUMP_INSN)
+ {
+#ifdef HAVE_cc0
+ /* If this was a conditional jump, we need to also delete
+ the insn that set cc0. */
+ if (! simplejump_p (q) && condjump_p (q))
+ q = PREV_INSN (q);
+#endif
+
+ if (b->head == q)
+ {
+ PUT_CODE (q, NOTE);
+ NOTE_LINE_NUMBER (q) = NOTE_INSN_DELETED;
+ NOTE_SOURCE_FILE (q) = 0;
+ }
+ else
+ b->end = q = PREV_INSN (q);
+ }
+
+ /* Selectively unlink the sequence. */
+ if (q != PREV_INSN (c->head))
+ delete_insn_chain (NEXT_INSN (q), PREV_INSN (c->head));
+
+ e->flags |= EDGE_FALLTHRU;
+}
+
+/* Discover and record the loop depth at the head of each basic block. */
+
+static void
+calculate_loop_depth (insns)
+ rtx insns;
{
- /* ??? For the moment we assume we don't have to watch for NULLs here
- since the start/end of basic blocks aren't deleted like this. */
- NEXT_INSN (PREV_INSN (insn)) = NEXT_INSN (insn);
- PREV_INSN (NEXT_INSN (insn)) = PREV_INSN (insn);
- return NEXT_INSN (insn);
+ basic_block bb;
+ rtx insn;
+ int i = 0, depth = 1;
+
+ bb = BASIC_BLOCK (i);
+ for (insn = insns; insn ; insn = NEXT_INSN (insn))
+ {
+ if (insn == bb->head)
+ {
+ bb->loop_depth = depth;
+ if (++i >= n_basic_blocks)
+ break;
+ bb = BASIC_BLOCK (i);
+ }
+
+ if (GET_CODE (insn) == NOTE)
+ {
+ if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_BEG)
+ depth++;
+ else if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_END)
+ depth--;
+
+ /* If we have LOOP_DEPTH == 0, there has been a bookkeeping error. */
+ if (depth == 0)
+ abort ();
+ }
+ }
}
/* Perform data flow analysis.
@@ -1075,51 +2060,212 @@ life_analysis (f, nregs, file)
SET_HARD_REG_BIT (elim_reg_set, FRAME_POINTER_REGNUM);
#endif
+ /* Allocate a bitmap to be filled in by record_volatile_insns. */
+ uid_volatile = BITMAP_ALLOCA ();
+
+ /* We want alias analysis information for local dead store elimination. */
+ init_alias_analysis ();
life_analysis_1 (f, nregs);
+ end_alias_analysis ();
+
if (file)
dump_flow_info (file);
+ BITMAP_FREE (uid_volatile);
free_basic_block_vars (1);
}
/* Free the variables allocated by find_basic_blocks.
- KEEP_HEAD_END_P is non-zero if basic_block_head and basic_block_end
- are not to be freed. */
+ KEEP_HEAD_END_P is non-zero if basic_block_info is not to be freed. */
void
free_basic_block_vars (keep_head_end_p)
int keep_head_end_p;
{
- if (basic_block_drops_in)
+ if (basic_block_for_insn)
{
- free (basic_block_drops_in);
- /* Tell dump_flow_info this isn't available anymore. */
- basic_block_drops_in = 0;
+ VARRAY_FREE (basic_block_for_insn);
+ basic_block_for_insn = NULL;
}
- if (basic_block_loop_depth)
+
+ if (! keep_head_end_p)
{
- free (basic_block_loop_depth);
- basic_block_loop_depth = 0;
+ clear_edges ();
+ VARRAY_FREE (basic_block_info);
+ n_basic_blocks = 0;
}
- if (uid_block_number)
+}
+
+/* Return nonzero if the destination of SET equals the source. */
+static int
+set_noop_p (set)
+ rtx set;
+{
+ rtx src = SET_SRC (set);
+ rtx dst = SET_DEST (set);
+ if (GET_CODE (src) == REG && GET_CODE (dst) == REG
+ && REGNO (src) == REGNO (dst))
+ return 1;
+ if (GET_CODE (src) != SUBREG || GET_CODE (dst) != SUBREG
+ || SUBREG_WORD (src) != SUBREG_WORD (dst))
+ return 0;
+ src = SUBREG_REG (src);
+ dst = SUBREG_REG (dst);
+ if (GET_CODE (src) == REG && GET_CODE (dst) == REG
+ && REGNO (src) == REGNO (dst))
+ return 1;
+ return 0;
+}
+
+/* Return nonzero if an insn consists only of SETs, each of which only sets a
+ value to itself. */
+static int
+noop_move_p (insn)
+ rtx insn;
+{
+ rtx pat = PATTERN (insn);
+
+ /* Insns carrying these notes are useful later on. */
+ if (find_reg_note (insn, REG_EQUAL, NULL_RTX))
+ return 0;
+
+ if (GET_CODE (pat) == SET && set_noop_p (pat))
+ return 1;
+
+ if (GET_CODE (pat) == PARALLEL)
{
- free (uid_block_number);
- uid_block_number = 0;
+ int i;
+ /* If nothing but SETs of registers to themselves,
+ this insn can also be deleted. */
+ for (i = 0; i < XVECLEN (pat, 0); i++)
+ {
+ rtx tem = XVECEXP (pat, 0, i);
+
+ if (GET_CODE (tem) == USE
+ || GET_CODE (tem) == CLOBBER)
+ continue;
+
+ if (GET_CODE (tem) != SET || ! set_noop_p (tem))
+ return 0;
+ }
+
+ return 1;
}
- if (uid_volatile)
+ return 0;
+}
+
+static void
+notice_stack_pointer_modification (x, pat)
+ rtx x;
+ rtx pat ATTRIBUTE_UNUSED;
+{
+ if (x == stack_pointer_rtx
+ /* The stack pointer is only modified indirectly as the result
+ of a push until later in flow. See the comments in rtl.texi
+ regarding Embedded Side-Effects on Addresses. */
+ || (GET_CODE (x) == MEM
+ && (GET_CODE (XEXP (x, 0)) == PRE_DEC
+ || GET_CODE (XEXP (x, 0)) == PRE_INC
+ || GET_CODE (XEXP (x, 0)) == POST_DEC
+ || GET_CODE (XEXP (x, 0)) == POST_INC)
+ && XEXP (XEXP (x, 0), 0) == stack_pointer_rtx))
+ current_function_sp_is_unchanging = 0;
+}
+
+/* Record which insns refer to any volatile memory
+ or for any reason can't be deleted just because they are dead stores.
+ Also, delete any insns that copy a register to itself.
+ And see if the stack pointer is modified. */
+static void
+record_volatile_insns (f)
+ rtx f;
+{
+ rtx insn;
+ for (insn = f; insn; insn = NEXT_INSN (insn))
{
- free (uid_volatile);
- uid_volatile = 0;
+ enum rtx_code code1 = GET_CODE (insn);
+ if (code1 == CALL_INSN)
+ SET_INSN_VOLATILE (insn);
+ else if (code1 == INSN || code1 == JUMP_INSN)
+ {
+ if (GET_CODE (PATTERN (insn)) != USE
+ && volatile_refs_p (PATTERN (insn)))
+ SET_INSN_VOLATILE (insn);
+
+ /* A SET that makes space on the stack cannot be dead.
+ (Such SETs occur only for allocating variable-size data,
+ so they will always have a PLUS or MINUS according to the
+ direction of stack growth.)
+ Even if this function never uses this stack pointer value,
+ signal handlers do! */
+ else if (code1 == INSN && GET_CODE (PATTERN (insn)) == SET
+ && SET_DEST (PATTERN (insn)) == stack_pointer_rtx
+#ifdef STACK_GROWS_DOWNWARD
+ && GET_CODE (SET_SRC (PATTERN (insn))) == MINUS
+#else
+ && GET_CODE (SET_SRC (PATTERN (insn))) == PLUS
+#endif
+ && XEXP (SET_SRC (PATTERN (insn)), 0) == stack_pointer_rtx)
+ SET_INSN_VOLATILE (insn);
+
+ /* Delete (in effect) any obvious no-op moves. */
+ else if (noop_move_p (insn))
+ {
+ PUT_CODE (insn, NOTE);
+ NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
+ NOTE_SOURCE_FILE (insn) = 0;
+ }
+ }
+
+ /* Check if insn modifies the stack pointer. */
+ if ( current_function_sp_is_unchanging
+ && GET_RTX_CLASS (GET_CODE (insn)) == 'i')
+ note_stores (PATTERN (insn), notice_stack_pointer_modification);
}
+}
- if (! keep_head_end_p && basic_block_head)
+/* Mark those regs which are needed at the end of the function as live
+ at the end of the last basic block. */
+static void
+mark_regs_live_at_end (set)
+ regset set;
+{
+ int i;
+
+ /* If exiting needs the right stack value, consider the stack pointer
+ live at the end of the function. */
+ if (! EXIT_IGNORE_STACK
+ || (! FRAME_POINTER_REQUIRED
+ && ! current_function_calls_alloca
+ && flag_omit_frame_pointer)
+ || current_function_sp_is_unchanging)
{
- free (basic_block_head);
- basic_block_head = 0;
- free (basic_block_end);
- basic_block_end = 0;
+ SET_REGNO_REG_SET (set, STACK_POINTER_REGNUM);
}
+
+ /* Mark the frame pointer if needed at the end of the function. If
+ we end up eliminating it, it will be removed from the live list
+ of each basic block by reload. */
+
+ SET_REGNO_REG_SET (set, FRAME_POINTER_REGNUM);
+#if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
+ /* If they are different, also mark the hard frame pointer as live */
+ SET_REGNO_REG_SET (set, HARD_FRAME_POINTER_REGNUM);
+#endif
+
+ /* Mark all global registers, and all registers used by the epilogue
+ as being live at the end of the function since they may be
+ referenced by our caller. */
+ for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+ if (global_regs[i]
+#ifdef EPILOGUE_USES
+ || EPILOGUE_USES (i)
+#endif
+ )
+ SET_REGNO_REG_SET (set, i);
+
+ /* ??? Mark function return value here rather than as uses. */
}
/* Determine which registers are live at the start of each
@@ -1136,22 +2282,9 @@ life_analysis_1 (f, nregs)
{
int first_pass;
int changed;
- /* For each basic block, a bitmask of regs
- live on exit from the block. */
- regset *basic_block_live_at_end;
- /* For each basic block, a bitmask of regs
- live on entry to a successor-block of this block.
- If this does not match basic_block_live_at_end,
- that must be updated, and the block must be rescanned. */
- regset *basic_block_new_live_at_end;
- /* For each basic block, a bitmask of regs
- whose liveness at the end of the basic block
- can make a difference in which regs are live on entry to the block.
- These are the regs that are set within the basic block,
- possibly excluding those that are used after they are set. */
- regset *basic_block_significant;
register int i;
- rtx insn;
+ char save_regs_ever_live[FIRST_PSEUDO_REGISTER];
+ regset *new_live_at_end;
struct obstack flow_obstack;
@@ -1159,178 +2292,60 @@ life_analysis_1 (f, nregs)
max_regno = nregs;
- bzero (regs_ever_live, sizeof regs_ever_live);
-
/* Allocate and zero out many data structures
that will record the data from lifetime analysis. */
allocate_for_life_analysis ();
reg_next_use = (rtx *) alloca (nregs * sizeof (rtx));
- bzero ((char *) reg_next_use, nregs * sizeof (rtx));
+ memset (reg_next_use, 0, nregs * sizeof (rtx));
- /* Set up several regset-vectors used internally within this function.
+ /* Set up regset-vectors used internally within this function.
Their meanings are documented above, with their declarations. */
- basic_block_live_at_end
- = (regset *) alloca (n_basic_blocks * sizeof (regset));
+ new_live_at_end = (regset *) alloca ((n_basic_blocks + 1) * sizeof (regset));
+ init_regset_vector (new_live_at_end, n_basic_blocks + 1, &flow_obstack);
- /* Don't use alloca since that leads to a crash rather than an error message
- if there isn't enough space.
- Don't use oballoc since we may need to allocate other things during
- this function on the temporary obstack. */
- init_regset_vector (basic_block_live_at_end, n_basic_blocks, &flow_obstack);
+ /* Stick these vectors into the AUX field of the basic block, so that
+ we don't have to keep going through the index. */
- basic_block_new_live_at_end
- = (regset *) alloca (n_basic_blocks * sizeof (regset));
- init_regset_vector (basic_block_new_live_at_end, n_basic_blocks,
- &flow_obstack);
+ for (i = 0; i < n_basic_blocks; ++i)
+ BASIC_BLOCK (i)->aux = new_live_at_end[i];
+ ENTRY_BLOCK_PTR->aux = new_live_at_end[i];
- basic_block_significant
- = (regset *) alloca (n_basic_blocks * sizeof (regset));
- init_regset_vector (basic_block_significant, n_basic_blocks, &flow_obstack);
+ /* Assume that the stack pointer is unchanging if alloca hasn't been used.
+ This will be cleared by record_volatile_insns if it encounters an insn
+ which modifies the stack pointer. */
+ current_function_sp_is_unchanging = !current_function_calls_alloca;
- /* Record which insns refer to any volatile memory
- or for any reason can't be deleted just because they are dead stores.
- Also, delete any insns that copy a register to itself. */
+ record_volatile_insns (f);
- for (insn = f; insn; insn = NEXT_INSN (insn))
+ if (n_basic_blocks > 0)
{
- enum rtx_code code1 = GET_CODE (insn);
- if (code1 == CALL_INSN)
- INSN_VOLATILE (insn) = 1;
- else if (code1 == INSN || code1 == JUMP_INSN)
+ regset theend;
+ register edge e;
+
+ theend = EXIT_BLOCK_PTR->global_live_at_start;
+ mark_regs_live_at_end (theend);
+
+ /* Propogate this exit data to each of EXIT's predecessors. */
+ for (e = EXIT_BLOCK_PTR->pred; e ; e = e->pred_next)
{
- /* Delete (in effect) any obvious no-op moves. */
- if (GET_CODE (PATTERN (insn)) == SET
- && GET_CODE (SET_DEST (PATTERN (insn))) == REG
- && GET_CODE (SET_SRC (PATTERN (insn))) == REG
- && (REGNO (SET_DEST (PATTERN (insn)))
- == REGNO (SET_SRC (PATTERN (insn))))
- /* Insns carrying these notes are useful later on. */
- && ! find_reg_note (insn, REG_EQUAL, NULL_RTX))
- {
- PUT_CODE (insn, NOTE);
- NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
- NOTE_SOURCE_FILE (insn) = 0;
- }
- /* Delete (in effect) any obvious no-op moves. */
- else if (GET_CODE (PATTERN (insn)) == SET
- && GET_CODE (SET_DEST (PATTERN (insn))) == SUBREG
- && GET_CODE (SUBREG_REG (SET_DEST (PATTERN (insn)))) == REG
- && GET_CODE (SET_SRC (PATTERN (insn))) == SUBREG
- && GET_CODE (SUBREG_REG (SET_SRC (PATTERN (insn)))) == REG
- && (REGNO (SUBREG_REG (SET_DEST (PATTERN (insn))))
- == REGNO (SUBREG_REG (SET_SRC (PATTERN (insn)))))
- && SUBREG_WORD (SET_DEST (PATTERN (insn))) ==
- SUBREG_WORD (SET_SRC (PATTERN (insn)))
- /* Insns carrying these notes are useful later on. */
- && ! find_reg_note (insn, REG_EQUAL, NULL_RTX))
- {
- PUT_CODE (insn, NOTE);
- NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
- NOTE_SOURCE_FILE (insn) = 0;
- }
- else if (GET_CODE (PATTERN (insn)) == PARALLEL)
- {
- /* If nothing but SETs of registers to themselves,
- this insn can also be deleted. */
- for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
- {
- rtx tem = XVECEXP (PATTERN (insn), 0, i);
-
- if (GET_CODE (tem) == USE
- || GET_CODE (tem) == CLOBBER)
- continue;
-
- if (GET_CODE (tem) != SET
- || GET_CODE (SET_DEST (tem)) != REG
- || GET_CODE (SET_SRC (tem)) != REG
- || REGNO (SET_DEST (tem)) != REGNO (SET_SRC (tem)))
- break;
- }
-
- if (i == XVECLEN (PATTERN (insn), 0)
- /* Insns carrying these notes are useful later on. */
- && ! find_reg_note (insn, REG_EQUAL, NULL_RTX))
- {
- PUT_CODE (insn, NOTE);
- NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
- NOTE_SOURCE_FILE (insn) = 0;
- }
- else
- INSN_VOLATILE (insn) = volatile_refs_p (PATTERN (insn));
- }
- else if (GET_CODE (PATTERN (insn)) != USE)
- INSN_VOLATILE (insn) = volatile_refs_p (PATTERN (insn));
- /* A SET that makes space on the stack cannot be dead.
- (Such SETs occur only for allocating variable-size data,
- so they will always have a PLUS or MINUS according to the
- direction of stack growth.)
- Even if this function never uses this stack pointer value,
- signal handlers do! */
- else if (code1 == INSN && GET_CODE (PATTERN (insn)) == SET
- && SET_DEST (PATTERN (insn)) == stack_pointer_rtx
-#ifdef STACK_GROWS_DOWNWARD
- && GET_CODE (SET_SRC (PATTERN (insn))) == MINUS
-#else
- && GET_CODE (SET_SRC (PATTERN (insn))) == PLUS
-#endif
- && XEXP (SET_SRC (PATTERN (insn)), 0) == stack_pointer_rtx)
- INSN_VOLATILE (insn) = 1;
+ COPY_REG_SET (e->src->global_live_at_end, theend);
+ COPY_REG_SET ((regset) e->src->aux, theend);
}
}
- if (n_basic_blocks > 0)
-#ifdef EXIT_IGNORE_STACK
- if (! EXIT_IGNORE_STACK
- || (! FRAME_POINTER_REQUIRED
- && ! current_function_calls_alloca
- && flag_omit_frame_pointer))
-#endif
- {
- /* If exiting needs the right stack value,
- consider the stack pointer live at the end of the function. */
- SET_REGNO_REG_SET (basic_block_live_at_end[n_basic_blocks - 1],
- STACK_POINTER_REGNUM);
- SET_REGNO_REG_SET (basic_block_new_live_at_end[n_basic_blocks - 1],
- STACK_POINTER_REGNUM);
- }
-
- /* Mark the frame pointer is needed at the end of the function. If
- we end up eliminating it, it will be removed from the live list
- of each basic block by reload. */
-
- if (n_basic_blocks > 0)
- {
- SET_REGNO_REG_SET (basic_block_live_at_end[n_basic_blocks - 1],
- FRAME_POINTER_REGNUM);
- SET_REGNO_REG_SET (basic_block_new_live_at_end[n_basic_blocks - 1],
- FRAME_POINTER_REGNUM);
-#if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
- /* If they are different, also mark the hard frame pointer as live */
- SET_REGNO_REG_SET (basic_block_live_at_end[n_basic_blocks - 1],
- HARD_FRAME_POINTER_REGNUM);
- SET_REGNO_REG_SET (basic_block_new_live_at_end[n_basic_blocks - 1],
- HARD_FRAME_POINTER_REGNUM);
-#endif
- }
+ /* The post-reload life analysis have (on a global basis) the same registers
+ live as was computed by reload itself.
- /* Mark all global registers and all registers used by the epilogue
- as being live at the end of the function since they may be
- referenced by our caller. */
+ Otherwise elimination offsets and such may be incorrect.
- if (n_basic_blocks > 0)
- for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
- if (global_regs[i]
-#ifdef EPILOGUE_USES
- || EPILOGUE_USES (i)
-#endif
- )
- {
- SET_REGNO_REG_SET (basic_block_live_at_end[n_basic_blocks - 1], i);
- SET_REGNO_REG_SET (basic_block_new_live_at_end[n_basic_blocks - 1], i);
- }
+ Reload will make some registers as live even though they do not appear
+ in the rtl. */
+ if (reload_completed)
+ memcpy (save_regs_ever_live, regs_ever_live, sizeof (regs_ever_live));
+ memset (regs_ever_live, 0, sizeof regs_ever_live);
/* Propagate life info through the basic blocks
around the graph of basic blocks.
@@ -1349,6 +2364,7 @@ life_analysis_1 (f, nregs)
changed = 0;
for (i = n_basic_blocks - 1; i >= 0; i--)
{
+ basic_block bb = BASIC_BLOCK (i);
int consider = first_pass;
int must_rescan = first_pass;
register int j;
@@ -1365,11 +2381,10 @@ life_analysis_1 (f, nregs)
is one of the significant regs of this basic block). */
EXECUTE_IF_AND_COMPL_IN_REG_SET
- (basic_block_new_live_at_end[i],
- basic_block_live_at_end[i], 0, j,
+ ((regset) bb->aux, bb->global_live_at_end, 0, j,
{
consider = 1;
- if (REGNO_REG_SET_P (basic_block_significant[i], j))
+ if (REGNO_REG_SET_P (bb->local_set, j))
{
must_rescan = 1;
goto done;
@@ -1389,51 +2404,35 @@ life_analysis_1 (f, nregs)
/* No complete rescan needed;
just record those variables newly known live at end
as live at start as well. */
- IOR_AND_COMPL_REG_SET (basic_block_live_at_start[i],
- basic_block_new_live_at_end[i],
- basic_block_live_at_end[i]);
+ IOR_AND_COMPL_REG_SET (bb->global_live_at_start,
+ (regset) bb->aux,
+ bb->global_live_at_end);
- IOR_AND_COMPL_REG_SET (basic_block_live_at_end[i],
- basic_block_new_live_at_end[i],
- basic_block_live_at_end[i]);
+ IOR_AND_COMPL_REG_SET (bb->global_live_at_end,
+ (regset) bb->aux,
+ bb->global_live_at_end);
}
else
{
/* Update the basic_block_live_at_start
by propagation backwards through the block. */
- COPY_REG_SET (basic_block_live_at_end[i],
- basic_block_new_live_at_end[i]);
- COPY_REG_SET (basic_block_live_at_start[i],
- basic_block_live_at_end[i]);
- propagate_block (basic_block_live_at_start[i],
- basic_block_head[i], basic_block_end[i], 0,
- first_pass ? basic_block_significant[i]
- : (regset) 0,
+ COPY_REG_SET (bb->global_live_at_end, (regset) bb->aux);
+ COPY_REG_SET (bb->global_live_at_start,
+ bb->global_live_at_end);
+ propagate_block (bb->global_live_at_start,
+ bb->head, bb->end, 0,
+ first_pass ? bb->local_set : (regset) 0,
i);
}
+ /* Update the new_live_at_end's of the block's predecessors. */
{
- register rtx jump, head;
-
- /* Update the basic_block_new_live_at_end's of the block
- that falls through into this one (if any). */
- head = basic_block_head[i];
- if (basic_block_drops_in[i])
- IOR_REG_SET (basic_block_new_live_at_end[i-1],
- basic_block_live_at_start[i]);
-
- /* Update the basic_block_new_live_at_end's of
- all the blocks that jump to this one. */
- if (GET_CODE (head) == CODE_LABEL)
- for (jump = LABEL_REFS (head);
- jump != head;
- jump = LABEL_NEXTREF (jump))
- {
- register int from_block = BLOCK_NUM (CONTAINING_INSN (jump));
- IOR_REG_SET (basic_block_new_live_at_end[from_block],
- basic_block_live_at_start[i]);
- }
+ register edge e;
+
+ for (e = bb->pred; e ; e = e->pred_next)
+ IOR_REG_SET ((regset) e->src->aux, bb->global_live_at_start);
}
+
#ifdef USE_C_ALLOCA
alloca (0);
#endif
@@ -1447,59 +2446,36 @@ life_analysis_1 (f, nregs)
one basic block. */
if (n_basic_blocks > 0)
- EXECUTE_IF_SET_IN_REG_SET (basic_block_live_at_start[0],
+ EXECUTE_IF_SET_IN_REG_SET (BASIC_BLOCK (0)->global_live_at_start,
FIRST_PSEUDO_REGISTER, i,
{
REG_BASIC_BLOCK (i) = REG_BLOCK_GLOBAL;
});
- /* Now the life information is accurate.
- Make one more pass over each basic block
- to delete dead stores, create autoincrement addressing
- and record how many times each register is used, is set, or dies.
-
- To save time, we operate directly in basic_block_live_at_end[i],
- thus destroying it (in fact, converting it into a copy of
- basic_block_live_at_start[i]). This is ok now because
- basic_block_live_at_end[i] is no longer used past this point. */
-
- max_scratch = 0;
+ /* Now the life information is accurate. Make one more pass over each
+ basic block to delete dead stores, create autoincrement addressing
+ and record how many times each register is used, is set, or dies. */
for (i = 0; i < n_basic_blocks; i++)
{
- propagate_block (basic_block_live_at_end[i],
- basic_block_head[i], basic_block_end[i], 1,
- (regset) 0, i);
+ basic_block bb = BASIC_BLOCK (i);
+
+ /* We start with global_live_at_end to determine which stores are
+ dead. This process is destructive, and we wish to preserve the
+ contents of global_live_at_end for posterity. Fortunately,
+ new_live_at_end, due to the way we converged on a solution,
+ contains a duplicate of global_live_at_end that we can kill. */
+ propagate_block ((regset) bb->aux, bb->head, bb->end, 1, (regset) 0, i);
+
#ifdef USE_C_ALLOCA
alloca (0);
#endif
}
-#if 0
- /* Something live during a setjmp should not be put in a register
- on certain machines which restore regs from stack frames
- rather than from the jmpbuf.
- But we don't need to do this for the user's variables, since
- ANSI says only volatile variables need this. */
-#ifdef LONGJMP_RESTORE_FROM_STACK
- EXECUTE_IF_SET_IN_REG_SET (regs_live_at_setjmp,
- FIRST_PSEUDO_REGISTER, i,
- {
- if (regno_reg_rtx[i] != 0
- && ! REG_USERVAR_P (regno_reg_rtx[i]))
- {
- REG_LIVE_LENGTH (i) = -1;
- REG_BASIC_BLOCK (i) = -1;
- }
- });
-#endif
-#endif
-
- /* We have a problem with any pseudoreg that
- lives across the setjmp. ANSI says that if a
- user variable does not change in value
- between the setjmp and the longjmp, then the longjmp preserves it.
- This includes longjmp from a place where the pseudo appears dead.
+ /* We have a problem with any pseudoreg that lives across the setjmp.
+ ANSI says that if a user variable does not change in value between
+ the setjmp and the longjmp, then the longjmp preserves it. This
+ includes longjmp from a place where the pseudo appears dead.
(In principle, the value still exists if it is in scope.)
If the pseudo goes in a hard reg, some other value may occupy
that hard reg where this pseudo is dead, thus clobbering the pseudo.
@@ -1514,15 +2490,16 @@ life_analysis_1 (f, nregs)
}
});
+ /* Restore regs_ever_live that was provided by reload. */
+ if (reload_completed)
+ memcpy (regs_ever_live, save_regs_ever_live, sizeof (regs_ever_live));
- free_regset_vector (basic_block_live_at_end, n_basic_blocks);
- free_regset_vector (basic_block_new_live_at_end, n_basic_blocks);
- free_regset_vector (basic_block_significant, n_basic_blocks);
- basic_block_live_at_end = (regset *)0;
- basic_block_new_live_at_end = (regset *)0;
- basic_block_significant = (regset *)0;
-
+ free_regset_vector (new_live_at_end, n_basic_blocks);
obstack_free (&flow_obstack, NULL_PTR);
+
+ for (i = 0; i < n_basic_blocks; ++i)
+ BASIC_BLOCK (i)->aux = NULL;
+ ENTRY_BLOCK_PTR->aux = NULL;
}
/* Subroutines of life analysis. */
@@ -1546,10 +2523,19 @@ allocate_for_life_analysis ()
for (i = 0; i < max_regno; i++)
REG_N_SETS (i) = 0;
- basic_block_live_at_start
- = (regset *) oballoc (n_basic_blocks * sizeof (regset));
- init_regset_vector (basic_block_live_at_start, n_basic_blocks,
- function_obstack);
+ for (i = 0; i < n_basic_blocks; i++)
+ {
+ basic_block bb = BASIC_BLOCK (i);
+
+ bb->local_set = OBSTACK_ALLOC_REG_SET (function_obstack);
+ bb->global_live_at_start = OBSTACK_ALLOC_REG_SET (function_obstack);
+ bb->global_live_at_end = OBSTACK_ALLOC_REG_SET (function_obstack);
+ }
+
+ ENTRY_BLOCK_PTR->global_live_at_end
+ = OBSTACK_ALLOC_REG_SET (function_obstack);
+ EXIT_BLOCK_PTR->global_live_at_start
+ = OBSTACK_ALLOC_REG_SET (function_obstack);
regs_live_at_setjmp = OBSTACK_ALLOC_REG_SET (function_obstack);
CLEAR_REG_SET (regs_live_at_setjmp);
@@ -1621,57 +2607,27 @@ propagate_block (old, first, last, final, significant, bnum)
regset live;
regset dead;
- /* The following variables are used only if FINAL is nonzero. */
- /* This vector gets one element for each reg that has been live
- at any point in the basic block that has been scanned so far.
- SOMETIMES_MAX says how many elements are in use so far. */
- register int *regs_sometimes_live;
- int sometimes_max = 0;
- /* This regset has 1 for each reg that we have seen live so far.
- It and REGS_SOMETIMES_LIVE are updated together. */
- regset maxlive;
-
- /* The loop depth may change in the middle of a basic block. Since we
- scan from end to beginning, we start with the depth at the end of the
- current basic block, and adjust as we pass ends and starts of loops. */
- loop_depth = basic_block_loop_depth[bnum];
+ /* Find the loop depth for this block. Ignore loop level changes in the
+ middle of the basic block -- for register allocation purposes, the
+ important uses will be in the blocks wholely contained within the loop
+ not in the loop pre-header or post-trailer. */
+ loop_depth = BASIC_BLOCK (bnum)->loop_depth;
dead = ALLOCA_REG_SET ();
live = ALLOCA_REG_SET ();
cc0_live = 0;
- last_mem_set = 0;
-
- /* Include any notes at the end of the block in the scan.
- This is in case the block ends with a call to setjmp. */
-
- while (NEXT_INSN (last) != 0 && GET_CODE (NEXT_INSN (last)) == NOTE)
- {
- /* Look for loop boundaries, we are going forward here. */
- last = NEXT_INSN (last);
- if (NOTE_LINE_NUMBER (last) == NOTE_INSN_LOOP_BEG)
- loop_depth++;
- else if (NOTE_LINE_NUMBER (last) == NOTE_INSN_LOOP_END)
- loop_depth--;
- }
+ mem_set_list = NULL_RTX;
if (final)
{
register int i;
- num_scratch = 0;
- maxlive = ALLOCA_REG_SET ();
- COPY_REG_SET (maxlive, old);
- regs_sometimes_live = (int *) alloca (max_regno * sizeof (int));
-
/* Process the regs live at the end of the block.
- Enter them in MAXLIVE and REGS_SOMETIMES_LIVE.
- Also mark them as not local to any one basic block. */
+ Mark them as not local to any one basic block. */
EXECUTE_IF_SET_IN_REG_SET (old, 0, i,
{
REG_BASIC_BLOCK (i) = REG_BLOCK_GLOBAL;
- regs_sometimes_live[sometimes_max] = i;
- sometimes_max++;
});
}
@@ -1683,18 +2639,6 @@ propagate_block (old, first, last, final, significant, bnum)
if (GET_CODE (insn) == NOTE)
{
- /* Look for loop boundaries, remembering that we are going
- backwards. */
- if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_END)
- loop_depth++;
- else if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_BEG)
- loop_depth--;
-
- /* If we have LOOP_DEPTH == 0, there has been a bookkeeping error.
- Abort now rather than setting register status incorrectly. */
- if (loop_depth == 0)
- abort ();
-
/* If this is a call to `setjmp' et al,
warn if any non-volatile datum is live. */
@@ -1714,7 +2658,7 @@ propagate_block (old, first, last, final, significant, bnum)
register int i;
rtx note = find_reg_note (insn, REG_RETVAL, NULL_RTX);
int insn_is_dead
- = (insn_dead_p (PATTERN (insn), old, 0)
+ = (insn_dead_p (PATTERN (insn), old, 0, REG_NOTES (insn))
/* Don't delete something that refers to volatile storage! */
&& ! INSN_VOLATILE (insn));
int libcall_is_dead
@@ -1765,7 +2709,8 @@ propagate_block (old, first, last, final, significant, bnum)
register rtx x = single_set (insn);
/* Does this instruction increment or decrement a register? */
- if (final && x != 0
+ if (!reload_completed
+ && final && x != 0
&& GET_CODE (SET_DEST (x)) == REG
&& (GET_CODE (SET_SRC (x)) == PLUS
|| GET_CODE (SET_SRC (x)) == MINUS)
@@ -1804,6 +2749,16 @@ propagate_block (old, first, last, final, significant, bnum)
;
else
{
+ /* Any regs live at the time of a call instruction
+ must not go in a register clobbered by calls.
+ Find all regs now live and record this for them. */
+
+ if (GET_CODE (insn) == CALL_INSN && final)
+ EXECUTE_IF_SET_IN_REG_SET (old, 0, i,
+ {
+ REG_N_CALLS_CROSSED (i)++;
+ });
+
/* LIVE gets the regs used in INSN;
DEAD gets those set by it. Dead insns don't make anything
live. */
@@ -1861,51 +2816,20 @@ propagate_block (old, first, last, final, significant, bnum)
final, insn);
/* Calls also clobber memory. */
- last_mem_set = 0;
+ mem_set_list = NULL_RTX;
}
/* Update OLD for the registers used or set. */
AND_COMPL_REG_SET (old, dead);
IOR_REG_SET (old, live);
- if (GET_CODE (insn) == CALL_INSN && final)
- {
- /* Any regs live at the time of a call instruction
- must not go in a register clobbered by calls.
- Find all regs now live and record this for them. */
-
- register int *p = regs_sometimes_live;
-
- for (i = 0; i < sometimes_max; i++, p++)
- if (REGNO_REG_SET_P (old, *p))
- REG_N_CALLS_CROSSED (*p)++;
- }
}
- /* On final pass, add any additional sometimes-live regs
- into MAXLIVE and REGS_SOMETIMES_LIVE.
- Also update counts of how many insns each reg is live at. */
-
+ /* On final pass, update counts of how many insns each reg is live
+ at. */
if (final)
- {
- register int regno;
- register int *p;
-
- EXECUTE_IF_AND_COMPL_IN_REG_SET
- (live, maxlive, 0, regno,
- {
- regs_sometimes_live[sometimes_max++] = regno;
- SET_REGNO_REG_SET (maxlive, regno);
- });
-
- p = regs_sometimes_live;
- for (i = 0; i < sometimes_max; i++)
- {
- regno = *p++;
- if (REGNO_REG_SET_P (old, regno))
- REG_LIVE_LENGTH (regno)++;
- }
- }
+ EXECUTE_IF_SET_IN_REG_SET (old, 0, i,
+ { REG_LIVE_LENGTH (i)++; });
}
flushed: ;
if (insn == first)
@@ -1914,27 +2838,46 @@ propagate_block (old, first, last, final, significant, bnum)
FREE_REG_SET (dead);
FREE_REG_SET (live);
- if (final)
- FREE_REG_SET (maxlive);
-
- if (num_scratch > max_scratch)
- max_scratch = num_scratch;
}
/* Return 1 if X (the body of an insn, or part of it) is just dead stores
(SET expressions whose destinations are registers dead after the insn).
NEEDED is the regset that says which regs are alive after the insn.
- Unless CALL_OK is non-zero, an insn is needed if it contains a CALL. */
+ Unless CALL_OK is non-zero, an insn is needed if it contains a CALL.
+
+ If X is the entire body of an insn, NOTES contains the reg notes
+ pertaining to the insn. */
static int
-insn_dead_p (x, needed, call_ok)
+insn_dead_p (x, needed, call_ok, notes)
rtx x;
regset needed;
int call_ok;
+ rtx notes ATTRIBUTE_UNUSED;
{
enum rtx_code code = GET_CODE (x);
+#ifdef AUTO_INC_DEC
+ /* If flow is invoked after reload, we must take existing AUTO_INC
+ expresions into account. */
+ if (reload_completed)
+ {
+ for ( ; notes; notes = XEXP (notes, 1))
+ {
+ if (REG_NOTE_KIND (notes) == REG_INC)
+ {
+ int regno = REGNO (XEXP (notes, 0));
+
+ /* Don't delete insns to set global regs. */
+ if ((regno < FIRST_PSEUDO_REGISTER && global_regs[regno])
+ || REGNO_REG_SET_P (needed, regno))
+ return 0;
+ }
+ }
+ }
+#endif
+
/* If setting something that's a reg or part of one,
see if that register's altered value will be live. */
@@ -1951,9 +2894,21 @@ insn_dead_p (x, needed, call_ok)
return ! cc0_live;
#endif
- if (GET_CODE (r) == MEM && last_mem_set && ! MEM_VOLATILE_P (r)
- && rtx_equal_p (r, last_mem_set))
- return 1;
+ if (GET_CODE (r) == MEM && ! MEM_VOLATILE_P (r))
+ {
+ rtx temp;
+ /* Walk the set of memory locations we are currently tracking
+ and see if one is an identical match to this memory location.
+ If so, this memory write is dead (remember, we're walking
+ backwards from the end of the block to the start. */
+ temp = mem_set_list;
+ while (temp)
+ {
+ if (rtx_equal_p (XEXP (temp, 0), r))
+ return 1;
+ temp = XEXP (temp, 1);
+ }
+ }
while (GET_CODE (r) == SUBREG || GET_CODE (r) == STRICT_LOW_PART
|| GET_CODE (r) == ZERO_EXTRACT)
@@ -2005,7 +2960,7 @@ insn_dead_p (x, needed, call_ok)
for (i--; i >= 0; i--)
if (GET_CODE (XVECEXP (x, 0, i)) != CLOBBER
&& GET_CODE (XVECEXP (x, 0, i)) != USE
- && ! insn_dead_p (XVECEXP (x, 0, i), needed, call_ok))
+ && ! insn_dead_p (XVECEXP (x, 0, i), needed, call_ok, NULL_RTX))
return 0;
return 1;
@@ -2052,6 +3007,7 @@ libcall_dead_p (x, needed, note, insn)
if (GET_CODE (r) == REG)
{
rtx call = XEXP (note, 0);
+ rtx call_pat;
register int i;
/* Find the call insn. */
@@ -2065,12 +3021,12 @@ libcall_dead_p (x, needed, note, insn)
/* See if the hard reg holding the value is dead.
If this is a PARALLEL, find the call within it. */
- call = PATTERN (call);
- if (GET_CODE (call) == PARALLEL)
+ call_pat = PATTERN (call);
+ if (GET_CODE (call_pat) == PARALLEL)
{
- for (i = XVECLEN (call, 0) - 1; i >= 0; i--)
- if (GET_CODE (XVECEXP (call, 0, i)) == SET
- && GET_CODE (SET_SRC (XVECEXP (call, 0, i))) == CALL)
+ for (i = XVECLEN (call_pat, 0) - 1; i >= 0; i--)
+ if (GET_CODE (XVECEXP (call_pat, 0, i)) == SET
+ && GET_CODE (SET_SRC (XVECEXP (call_pat, 0, i))) == CALL)
break;
/* This may be a library call that is returning a value
@@ -2079,10 +3035,10 @@ libcall_dead_p (x, needed, note, insn)
if (i < 0)
return 0;
- call = XVECEXP (call, 0, i);
+ call_pat = XVECEXP (call_pat, 0, i);
}
- return insn_dead_p (call, needed, 1);
+ return insn_dead_p (call_pat, needed, 1, REG_NOTES (call));
}
}
return 1;
@@ -2104,7 +3060,7 @@ regno_uninitialized (regno)
|| FUNCTION_ARG_REGNO_P (regno))))
return 0;
- return REGNO_REG_SET_P (basic_block_live_at_start[0], regno);
+ return REGNO_REG_SET_P (BASIC_BLOCK (0)->global_live_at_start, regno);
}
/* 1 if register REGNO was alive at a place where `setjmp' was called
@@ -2119,10 +3075,43 @@ regno_clobbered_at_setjmp (regno)
return 0;
return ((REG_N_SETS (regno) > 1
- || REGNO_REG_SET_P (basic_block_live_at_start[0], regno))
+ || REGNO_REG_SET_P (BASIC_BLOCK (0)->global_live_at_start, regno))
&& REGNO_REG_SET_P (regs_live_at_setjmp, regno));
}
+/* INSN references memory, possibly using autoincrement addressing modes.
+ Find any entries on the mem_set_list that need to be invalidated due
+ to an address change. */
+static void
+invalidate_mems_from_autoinc (insn)
+ rtx insn;
+{
+ rtx note = REG_NOTES (insn);
+ for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
+ {
+ if (REG_NOTE_KIND (note) == REG_INC)
+ {
+ rtx temp = mem_set_list;
+ rtx prev = NULL_RTX;
+
+ while (temp)
+ {
+ if (reg_overlap_mentioned_p (XEXP (note, 0), XEXP (temp, 0)))
+ {
+ /* Splice temp out of list. */
+ if (prev)
+ XEXP (prev, 1) = XEXP (temp, 1);
+ else
+ mem_set_list = XEXP (temp, 1);
+ }
+ else
+ prev = temp;
+ temp = XEXP (temp, 1);
+ }
+ }
+ }
+}
+
/* Process the registers that are set within X.
Their bits are set to 1 in the regset DEAD,
because they are dead prior to this insn.
@@ -2199,21 +3188,45 @@ mark_set_1 (needed, dead, x, insn, significant)
|| GET_CODE (reg) == STRICT_LOW_PART)
reg = XEXP (reg, 0);
- /* If we are writing into memory or into a register mentioned in the
- address of the last thing stored into memory, show we don't know
- what the last store was. If we are writing memory, save the address
- unless it is volatile. */
+ /* If this set is a MEM, then it kills any aliased writes.
+ If this set is a REG, then it kills any MEMs which use the reg. */
if (GET_CODE (reg) == MEM
- || (GET_CODE (reg) == REG
- && last_mem_set != 0 && reg_overlap_mentioned_p (reg, last_mem_set)))
- last_mem_set = 0;
-
+ || GET_CODE (reg) == REG)
+ {
+ rtx temp = mem_set_list;
+ rtx prev = NULL_RTX;
+
+ while (temp)
+ {
+ if ((GET_CODE (reg) == MEM
+ && output_dependence (XEXP (temp, 0), reg))
+ || (GET_CODE (reg) == REG
+ && reg_overlap_mentioned_p (reg, XEXP (temp, 0))))
+ {
+ /* Splice this entry out of the list. */
+ if (prev)
+ XEXP (prev, 1) = XEXP (temp, 1);
+ else
+ mem_set_list = XEXP (temp, 1);
+ }
+ else
+ prev = temp;
+ temp = XEXP (temp, 1);
+ }
+ }
+
+ /* If the memory reference had embedded side effects (autoincrement
+ address modes. Then we may need to kill some entries on the
+ memory set list. */
+ if (insn && GET_CODE (reg) == MEM)
+ invalidate_mems_from_autoinc (insn);
+
if (GET_CODE (reg) == MEM && ! side_effects_p (reg)
/* There are no REG_INC notes for SP, so we can't assume we'll see
everything that invalidates it. To be safe, don't eliminate any
stores though SP; none of them should be redundant anyway. */
&& ! reg_mentioned_p (stack_pointer_rtx, reg))
- last_mem_set = reg;
+ mem_set_list = gen_rtx_EXPR_LIST (VOIDmode, reg, mem_set_list);
if (GET_CODE (reg) == REG
&& (regno = REGNO (reg), regno != FRAME_POINTER_REGNUM)
@@ -2366,7 +3379,6 @@ mark_set_1 (needed, dead, x, insn, significant)
{
REG_NOTES (insn)
= gen_rtx_EXPR_LIST (REG_UNUSED, reg, REG_NOTES (insn));
- num_scratch++;
}
}
@@ -2410,20 +3422,14 @@ find_auto_inc (needed, x, insn)
&& (y = SET_SRC (set), GET_CODE (y) == PLUS)
&& XEXP (y, 0) == addr
&& GET_CODE (XEXP (y, 1)) == CONST_INT
- && (0
-#ifdef HAVE_POST_INCREMENT
- || (INTVAL (XEXP (y, 1)) == size && offset == 0)
-#endif
-#ifdef HAVE_POST_DECREMENT
- || (INTVAL (XEXP (y, 1)) == - size && offset == 0)
-#endif
-#ifdef HAVE_PRE_INCREMENT
- || (INTVAL (XEXP (y, 1)) == size && offset == size)
-#endif
-#ifdef HAVE_PRE_DECREMENT
- || (INTVAL (XEXP (y, 1)) == - size && offset == - size)
-#endif
- )
+ && ((HAVE_POST_INCREMENT
+ && (INTVAL (XEXP (y, 1)) == size && offset == 0))
+ || (HAVE_POST_DECREMENT
+ && (INTVAL (XEXP (y, 1)) == - size && offset == 0))
+ || (HAVE_PRE_INCREMENT
+ && (INTVAL (XEXP (y, 1)) == size && offset == size))
+ || (HAVE_PRE_DECREMENT
+ && (INTVAL (XEXP (y, 1)) == - size && offset == - size)))
/* Make sure this reg appears only once in this insn. */
&& (use = find_use_as_address (PATTERN (insn), addr, offset),
use != 0 && use != (rtx) 1))
@@ -2458,21 +3464,16 @@ find_auto_inc (needed, x, insn)
Change it to q = p, ...*q..., q = q+size.
Then fall into the usual case. */
rtx insns, temp;
+ basic_block bb;
start_sequence ();
emit_move_insn (q, addr);
insns = get_insns ();
end_sequence ();
- /* If anything in INSNS have UID's that don't fit within the
- extra space we allocate earlier, we can't make this auto-inc.
- This should never happen. */
+ bb = BLOCK_FOR_INSN (insn);
for (temp = insns; temp; temp = NEXT_INSN (temp))
- {
- if (INSN_UID (temp) > max_uid_for_flow)
- return;
- BLOCK_NUM (temp) = BLOCK_NUM (insn);
- }
+ set_block_for_insn (temp, bb);
/* If we can't make the auto-inc, or can't make the
replacement into Y, exit. There's no point in making
@@ -2490,8 +3491,8 @@ find_auto_inc (needed, x, insn)
new insn(s) and do the updates. */
emit_insns_before (insns, insn);
- if (basic_block_head[BLOCK_NUM (insn)] == insn)
- basic_block_head[BLOCK_NUM (insn)] = insns;
+ if (BLOCK_FOR_INSN (insn)->head == insn)
+ BLOCK_FOR_INSN (insn)->head = insns;
/* INCR will become a NOTE and INSN won't contain a
use of ADDR. If a use of ADDR was just placed in
@@ -2594,7 +3595,6 @@ mark_used_regs (needed, live, x, final, insn)
case PC:
case ADDR_VEC:
case ADDR_DIFF_VEC:
- case ASM_INPUT:
return;
#ifdef HAVE_cc0
@@ -2615,9 +3615,33 @@ mark_used_regs (needed, live, x, final, insn)
something that can be stored into. */
if (GET_CODE (XEXP (x, 0)) == SYMBOL_REF
&& CONSTANT_POOL_ADDRESS_P (XEXP (x, 0)))
- ; /* needn't clear last_mem_set */
+ ; /* needn't clear the memory set list */
else
- last_mem_set = 0;
+ {
+ rtx temp = mem_set_list;
+ rtx prev = NULL_RTX;
+
+ while (temp)
+ {
+ if (anti_dependence (XEXP (temp, 0), x))
+ {
+ /* Splice temp out of the list. */
+ if (prev)
+ XEXP (prev, 1) = XEXP (temp, 1);
+ else
+ mem_set_list = XEXP (temp, 1);
+ }
+ else
+ prev = temp;
+ temp = XEXP (temp, 1);
+ }
+ }
+
+ /* If the memory reference had embedded side effects (autoincrement
+ address modes. Then we may need to kill some entries on the
+ memory set list. */
+ if (insn)
+ invalidate_mems_from_autoinc (insn);
#ifdef AUTO_INC_DEC
if (final)
@@ -2869,13 +3893,11 @@ mark_used_regs (needed, live, x, final, insn)
/* If exiting needs the right stack value, consider this insn as
using the stack pointer. In any event, consider it as using
all global registers and all registers used by return. */
-
-#ifdef EXIT_IGNORE_STACK
if (! EXIT_IGNORE_STACK
|| (! FRAME_POINTER_REQUIRED
&& ! current_function_calls_alloca
- && flag_omit_frame_pointer))
-#endif
+ && flag_omit_frame_pointer)
+ || current_function_sp_is_unchanging)
SET_REGNO_REG_SET (live, STACK_POINTER_REGNUM);
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
@@ -2887,6 +3909,44 @@ mark_used_regs (needed, live, x, final, insn)
SET_REGNO_REG_SET (live, i);
break;
+ case ASM_OPERANDS:
+ case UNSPEC_VOLATILE:
+ case TRAP_IF:
+ case ASM_INPUT:
+ {
+ /* Traditional and volatile asm instructions must be considered to use
+ and clobber all hard registers, all pseudo-registers and all of
+ memory. So must TRAP_IF and UNSPEC_VOLATILE operations.
+
+ Consider for instance a volatile asm that changes the fpu rounding
+ mode. An insn should not be moved across this even if it only uses
+ pseudo-regs because it might give an incorrectly rounded result.
+
+ ?!? Unfortunately, marking all hard registers as live causes massive
+ problems for the register allocator and marking all pseudos as live
+ creates mountains of uninitialized variable warnings.
+
+ So for now, just clear the memory set list and mark any regs
+ we can find in ASM_OPERANDS as used. */
+ if (code != ASM_OPERANDS || MEM_VOLATILE_P (x))
+ mem_set_list = NULL_RTX;
+
+ /* For all ASM_OPERANDS, we must traverse the vector of input operands.
+ We can not just fall through here since then we would be confused
+ by the ASM_INPUT rtx inside ASM_OPERANDS, which do not indicate
+ traditional asms unlike their normal usage. */
+ if (code == ASM_OPERANDS)
+ {
+ int j;
+
+ for (j = 0; j < ASM_OPERANDS_INPUT_LENGTH (x); j++)
+ mark_used_regs (needed, live, ASM_OPERANDS_INPUT (x, j),
+ final, insn);
+ }
+ break;
+ }
+
+
default:
break;
}
@@ -2986,23 +4046,15 @@ try_pre_increment (insn, reg, amount)
/* From the sign of increment, see which possibilities are conceivable
on this target machine. */
-#ifdef HAVE_PRE_INCREMENT
- if (amount > 0)
+ if (HAVE_PRE_INCREMENT && amount > 0)
pre_ok = 1;
-#endif
-#ifdef HAVE_POST_INCREMENT
- if (amount > 0)
+ if (HAVE_POST_INCREMENT && amount > 0)
post_ok = 1;
-#endif
-#ifdef HAVE_PRE_DECREMENT
- if (amount < 0)
+ if (HAVE_PRE_DECREMENT && amount < 0)
pre_ok = 1;
-#endif
-#ifdef HAVE_POST_DECREMENT
- if (amount < 0)
+ if (HAVE_POST_DECREMENT && amount < 0)
post_ok = 1;
-#endif
if (! (pre_ok || post_ok))
return 0;
@@ -3123,7 +4175,6 @@ dump_flow_info (file)
static char *reg_class_names[] = REG_CLASS_NAMES;
fprintf (file, "%d registers.\n", max_regno);
-
for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
if (REG_N_REFS (i))
{
@@ -3162,40 +4213,91 @@ dump_flow_info (file)
fprintf (file, "; pointer");
fprintf (file, ".\n");
}
+
fprintf (file, "\n%d basic blocks.\n", n_basic_blocks);
for (i = 0; i < n_basic_blocks; i++)
{
- register rtx head, jump;
+ register basic_block bb = BASIC_BLOCK (i);
register int regno;
+ register edge e;
+
fprintf (file, "\nBasic block %d: first insn %d, last %d.\n",
- i,
- INSN_UID (basic_block_head[i]),
- INSN_UID (basic_block_end[i]));
- /* The control flow graph's storage is freed
- now when flow_analysis returns.
- Don't try to print it if it is gone. */
- if (basic_block_drops_in)
+ i, INSN_UID (bb->head), INSN_UID (bb->end));
+
+ fprintf (file, "Predecessors: ");
+ for (e = bb->pred; e ; e = e->pred_next)
+ dump_edge_info (file, e, 0);
+
+ fprintf (file, "\nSuccessors: ");
+ for (e = bb->succ; e ; e = e->succ_next)
+ dump_edge_info (file, e, 1);
+
+ fprintf (file, "\nRegisters live at start:");
+ if (bb->global_live_at_start)
{
- fprintf (file, "Reached from blocks: ");
- head = basic_block_head[i];
- if (GET_CODE (head) == CODE_LABEL)
- for (jump = LABEL_REFS (head);
- jump != head;
- jump = LABEL_NEXTREF (jump))
- {
- register int from_block = BLOCK_NUM (CONTAINING_INSN (jump));
- fprintf (file, " %d", from_block);
- }
- if (basic_block_drops_in[i])
- fprintf (file, " previous");
+ for (regno = 0; regno < max_regno; regno++)
+ if (REGNO_REG_SET_P (bb->global_live_at_start, regno))
+ fprintf (file, " %d", regno);
}
- fprintf (file, "\nRegisters live at start:");
- for (regno = 0; regno < max_regno; regno++)
- if (REGNO_REG_SET_P (basic_block_live_at_start[i], regno))
- fprintf (file, " %d", regno);
- fprintf (file, "\n");
+ else
+ fprintf (file, " n/a");
+
+ fprintf (file, "\nRegisters live at end:");
+ if (bb->global_live_at_end)
+ {
+ for (regno = 0; regno < max_regno; regno++)
+ if (REGNO_REG_SET_P (bb->global_live_at_end, regno))
+ fprintf (file, " %d", regno);
+ }
+ else
+ fprintf (file, " n/a");
+
+ putc('\n', file);
+ }
+
+ putc('\n', file);
+}
+
+static void
+dump_edge_info (file, e, do_succ)
+ FILE *file;
+ edge e;
+ int do_succ;
+{
+ basic_block side = (do_succ ? e->dest : e->src);
+
+ if (side == ENTRY_BLOCK_PTR)
+ fputs (" ENTRY", file);
+ else if (side == EXIT_BLOCK_PTR)
+ fputs (" EXIT", file);
+ else
+ fprintf (file, " %d", side->index);
+
+ if (e->flags)
+ {
+ static char * bitnames[] = {
+ "fallthru", "crit", "ab", "abcall", "eh", "fake"
+ };
+ int comma = 0;
+ int i, flags = e->flags;
+
+ fputc (' ', file);
+ fputc ('(', file);
+ for (i = 0; flags; i++)
+ if (flags & (1 << i))
+ {
+ flags &= ~(1 << i);
+
+ if (comma)
+ fputc (',', file);
+ if (i < (int)(sizeof (bitnames) / sizeof (*bitnames)))
+ fputs (bitnames[i], file);
+ else
+ fprintf (file, "%d", i);
+ comma = 1;
+ }
+ fputc (')', file);
}
- fprintf (file, "\n");
}
@@ -3211,33 +4313,37 @@ print_rtl_with_bb (outf, rtx_first)
if (rtx_first == 0)
fprintf (outf, "(nil)\n");
-
else
{
- int i, bb;
+ int i;
enum bb_state { NOT_IN_BB, IN_ONE_BB, IN_MULTIPLE_BB };
int max_uid = get_max_uid ();
- int *start = (int *) alloca (max_uid * sizeof (int));
- int *end = (int *) alloca (max_uid * sizeof (int));
- char *in_bb_p = (char *) alloca (max_uid * sizeof (enum bb_state));
+ basic_block *start = (basic_block *)
+ alloca (max_uid * sizeof (basic_block));
+ basic_block *end = (basic_block *)
+ alloca (max_uid * sizeof (basic_block));
+ enum bb_state *in_bb_p = (enum bb_state *)
+ alloca (max_uid * sizeof (enum bb_state));
- for (i = 0; i < max_uid; i++)
- {
- start[i] = end[i] = -1;
- in_bb_p[i] = NOT_IN_BB;
- }
+ memset (start, 0, max_uid * sizeof (basic_block));
+ memset (end, 0, max_uid * sizeof (basic_block));
+ memset (in_bb_p, 0, max_uid * sizeof (enum bb_state));
- for (i = n_basic_blocks-1; i >= 0; i--)
+ for (i = n_basic_blocks - 1; i >= 0; i--)
{
+ basic_block bb = BASIC_BLOCK (i);
rtx x;
- start[INSN_UID (basic_block_head[i])] = i;
- end[INSN_UID (basic_block_end[i])] = i;
- for (x = basic_block_head[i]; x != NULL_RTX; x = NEXT_INSN (x))
+
+ start[INSN_UID (bb->head)] = bb;
+ end[INSN_UID (bb->end)] = bb;
+ for (x = bb->head; x != NULL_RTX; x = NEXT_INSN (x))
{
- in_bb_p[ INSN_UID(x)]
- = (in_bb_p[ INSN_UID(x)] == NOT_IN_BB)
- ? IN_ONE_BB : IN_MULTIPLE_BB;
- if (x == basic_block_end[i])
+ enum bb_state state = IN_MULTIPLE_BB;
+ if (in_bb_p[INSN_UID(x)] == NOT_IN_BB)
+ state = IN_ONE_BB;
+ in_bb_p[INSN_UID(x)] = state;
+
+ if (x == bb->end)
break;
}
}
@@ -3245,13 +4351,14 @@ print_rtl_with_bb (outf, rtx_first)
for (tmp_rtx = rtx_first; NULL != tmp_rtx; tmp_rtx = NEXT_INSN (tmp_rtx))
{
int did_output;
+ basic_block bb;
- if ((bb = start[INSN_UID (tmp_rtx)]) >= 0)
+ if ((bb = start[INSN_UID (tmp_rtx)]) != NULL)
{
fprintf (outf, ";; Start of basic block %d, registers live:",
- bb);
+ bb->index);
- EXECUTE_IF_SET_IN_REG_SET (basic_block_live_at_start[bb], 0, i,
+ EXECUTE_IF_SET_IN_REG_SET (bb->global_live_at_start, 0, i,
{
fprintf (outf, " %d", i);
if (i < FIRST_PSEUDO_REGISTER)
@@ -3261,17 +4368,18 @@ print_rtl_with_bb (outf, rtx_first)
putc ('\n', outf);
}
- if (in_bb_p[ INSN_UID(tmp_rtx)] == NOT_IN_BB
+ if (in_bb_p[INSN_UID(tmp_rtx)] == NOT_IN_BB
&& GET_CODE (tmp_rtx) != NOTE
- && GET_CODE (tmp_rtx) != BARRIER)
+ && GET_CODE (tmp_rtx) != BARRIER
+ && ! obey_regdecls)
fprintf (outf, ";; Insn is not within a basic block\n");
- else if (in_bb_p[ INSN_UID(tmp_rtx)] == IN_MULTIPLE_BB)
+ else if (in_bb_p[INSN_UID(tmp_rtx)] == IN_MULTIPLE_BB)
fprintf (outf, ";; Insn is in multiple basic blocks\n");
did_output = print_rtl_single (outf, tmp_rtx);
- if ((bb = end[INSN_UID (tmp_rtx)]) >= 0)
- fprintf (outf, ";; End of basic block %d\n", bb);
+ if ((bb = end[INSN_UID (tmp_rtx)]) != NULL)
+ fprintf (outf, ";; End of basic block %d\n", bb->index);
if (did_output)
putc ('\n', outf);
@@ -3369,7 +4477,8 @@ add_pred_succ (pred_bb, succ_bb, s_preds, s_succs, num_preds, num_succs)
}
}
-/* Compute the predecessors and successors for each block. */
+/* Convert edge lists into pred/succ lists for backward compatibility. */
+
void
compute_preds_succs (s_preds, s_succs, num_preds, num_succs)
int_list_ptr *s_preds;
@@ -3377,117 +4486,34 @@ compute_preds_succs (s_preds, s_succs, num_preds, num_succs)
int *num_preds;
int *num_succs;
{
- int bb, clear_local_bb_vars = 0;
+ int i, n = n_basic_blocks;
+ edge e;
- bzero ((char *) s_preds, n_basic_blocks * sizeof (int_list_ptr));
- bzero ((char *) s_succs, n_basic_blocks * sizeof (int_list_ptr));
- bzero ((char *) num_preds, n_basic_blocks * sizeof (int));
- bzero ((char *) num_succs, n_basic_blocks * sizeof (int));
+ memset (s_preds, 0, n_basic_blocks * sizeof (int_list_ptr));
+ memset (s_succs, 0, n_basic_blocks * sizeof (int_list_ptr));
+ memset (num_preds, 0, n_basic_blocks * sizeof (int));
+ memset (num_succs, 0, n_basic_blocks * sizeof (int));
- /* This routine can be called after life analysis; in that case
- basic_block_drops_in and uid_block_number will not be available
- and we must recompute their values. */
- if (basic_block_drops_in == NULL || uid_block_number == NULL)
+ for (i = 0; i < n; ++i)
{
- clear_local_bb_vars = 1;
- basic_block_drops_in = (char *) alloca (n_basic_blocks);
- uid_block_number = (int *) alloca ((get_max_uid () + 1) * sizeof (int));
-
- bzero ((char *) basic_block_drops_in, n_basic_blocks * sizeof (char));
- bzero ((char *) uid_block_number, n_basic_blocks * sizeof (int));
-
- /* Scan each basic block setting basic_block_drops_in and
- uid_block_number as needed. */
- for (bb = 0; bb < n_basic_blocks; bb++)
- {
- rtx insn, stop_insn;
-
- if (bb == 0)
- stop_insn = NULL_RTX;
- else
- stop_insn = basic_block_end[bb-1];
-
- /* Look backwards from the start of this block. Stop if we
- hit the start of the function or the end of a previous
- block. Don't walk backwards through blocks that are just
- deleted insns! */
- for (insn = PREV_INSN (basic_block_head[bb]);
- insn && insn != stop_insn && GET_CODE (insn) == NOTE;
- insn = PREV_INSN (insn))
- ;
-
- /* Never set basic_block_drops_in for the first block. It is
- implicit.
-
- If we stopped on anything other than a BARRIER, then this
- block drops in. */
- if (bb != 0)
- basic_block_drops_in[bb] = (insn ? GET_CODE (insn) != BARRIER : 1);
-
- insn = basic_block_head[bb];
- while (insn)
- {
- BLOCK_NUM (insn) = bb;
- if (insn == basic_block_end[bb])
- break;
- insn = NEXT_INSN (insn);
- }
- }
- }
+ basic_block bb = BASIC_BLOCK (i);
- for (bb = 0; bb < n_basic_blocks; bb++)
- {
- rtx head;
- rtx jump;
-
- head = BLOCK_HEAD (bb);
-
- if (GET_CODE (head) == CODE_LABEL)
- for (jump = LABEL_REFS (head);
- jump != head;
- jump = LABEL_NEXTREF (jump))
- {
- if (! INSN_DELETED_P (CONTAINING_INSN (jump))
- && (GET_CODE (CONTAINING_INSN (jump)) != NOTE
- || (NOTE_LINE_NUMBER (CONTAINING_INSN (jump))
- != NOTE_INSN_DELETED)))
- add_pred_succ (BLOCK_NUM (CONTAINING_INSN (jump)), bb,
- s_preds, s_succs, num_preds, num_succs);
- }
-
- jump = BLOCK_END (bb);
- /* If this is a RETURN insn or a conditional jump in the last
- basic block, or a non-jump insn in the last basic block, then
- this block reaches the exit block. */
- if ((GET_CODE (jump) == JUMP_INSN && GET_CODE (PATTERN (jump)) == RETURN)
- || (((GET_CODE (jump) == JUMP_INSN
- && condjump_p (jump) && !simplejump_p (jump))
- || GET_CODE (jump) != JUMP_INSN)
- && (bb == n_basic_blocks - 1)))
- add_pred_succ (bb, EXIT_BLOCK, s_preds, s_succs, num_preds, num_succs);
-
- if (basic_block_drops_in[bb])
- add_pred_succ (bb - 1, bb, s_preds, s_succs, num_preds, num_succs);
+ for (e = bb->succ; e ; e = e->succ_next)
+ add_pred_succ (i, e->dest->index, s_preds, s_succs,
+ num_preds, num_succs);
}
- add_pred_succ (ENTRY_BLOCK, 0, s_preds, s_succs, num_preds, num_succs);
-
-
- /* If we allocated any variables in temporary storage, clear out the
- pointer to the local storage to avoid dangling pointers. */
- if (clear_local_bb_vars)
- {
- basic_block_drops_in = NULL;
- uid_block_number = NULL;
-
- }
+ for (e = ENTRY_BLOCK_PTR->succ; e ; e = e->succ_next)
+ add_pred_succ (ENTRY_BLOCK, e->dest->index, s_preds, s_succs,
+ num_preds, num_succs);
}
void
-dump_bb_data (file, preds, succs)
+dump_bb_data (file, preds, succs, live_info)
FILE *file;
int_list_ptr *preds;
int_list_ptr *succs;
+ int live_info;
{
int bb;
int_list_ptr p;
@@ -3516,47 +4542,16 @@ dump_bb_data (file, preds, succs)
else
fprintf (file, " %d", succ_bb);
}
- fprintf (file, "\n");
- }
- fprintf (file, "\n");
-}
-
-void
-dump_sbitmap (file, bmap)
- FILE *file;
- sbitmap bmap;
-{
- int i,j,n;
- int set_size = bmap->size;
- int total_bits = bmap->n_bits;
-
- fprintf (file, " ");
- for (i = n = 0; i < set_size && n < total_bits; i++)
- {
- for (j = 0; j < SBITMAP_ELT_BITS && n < total_bits; j++, n++)
+ if (live_info)
{
- if (n != 0 && n % 10 == 0)
- fprintf (file, " ");
- fprintf (file, "%d", (bmap->elms[i] & (1L << j)) != 0);
+ int regno;
+ fprintf (file, "\nRegisters live at start:");
+ for (regno = 0; regno < max_regno; regno++)
+ if (REGNO_REG_SET_P (BASIC_BLOCK (bb)->global_live_at_start, regno))
+ fprintf (file, " %d", regno);
+ fprintf (file, "\n");
}
- }
- fprintf (file, "\n");
-}
-
-void
-dump_sbitmap_vector (file, title, subtitle, bmaps, n_maps)
- FILE *file;
- char *title, *subtitle;
- sbitmap *bmaps;
- int n_maps;
-{
- int bb;
-
- fprintf (file, "%s\n", title);
- for (bb = 0; bb < n_maps; bb++)
- {
- fprintf (file, "%s %d\n", subtitle, bb);
- dump_sbitmap (file, bmaps[bb]);
+ fprintf (file, "\n");
}
fprintf (file, "\n");
}
@@ -3568,462 +4563,6 @@ free_bb_mem ()
{
free_int_list (&pred_int_list_blocks);
}
-
-/* Bitmap manipulation routines. */
-
-/* Allocate a simple bitmap of N_ELMS bits. */
-
-sbitmap
-sbitmap_alloc (n_elms)
- int n_elms;
-{
- int bytes, size, amt;
- sbitmap bmap;
-
- size = SBITMAP_SET_SIZE (n_elms);
- bytes = size * sizeof (SBITMAP_ELT_TYPE);
- amt = (sizeof (struct simple_bitmap_def)
- + bytes - sizeof (SBITMAP_ELT_TYPE));
- bmap = (sbitmap) xmalloc (amt);
- bmap->n_bits = n_elms;
- bmap->size = size;
- bmap->bytes = bytes;
- return bmap;
-}
-
-/* Allocate a vector of N_VECS bitmaps of N_ELMS bits. */
-
-sbitmap *
-sbitmap_vector_alloc (n_vecs, n_elms)
- int n_vecs, n_elms;
-{
- int i, bytes, offset, elm_bytes, size, amt, vector_bytes;
- sbitmap *bitmap_vector;
-
- size = SBITMAP_SET_SIZE (n_elms);
- bytes = size * sizeof (SBITMAP_ELT_TYPE);
- elm_bytes = (sizeof (struct simple_bitmap_def)
- + bytes - sizeof (SBITMAP_ELT_TYPE));
- vector_bytes = n_vecs * sizeof (sbitmap *);
-
- /* Round up `vector_bytes' to account for the alignment requirements
- of an sbitmap. One could allocate the vector-table and set of sbitmaps
- separately, but that requires maintaining two pointers or creating
- a cover struct to hold both pointers (so our result is still just
- one pointer). Neither is a bad idea, but this is simpler for now. */
- {
- /* Based on DEFAULT_ALIGNMENT computation in obstack.c. */
- struct { char x; SBITMAP_ELT_TYPE y; } align;
- int alignment = (char *) & align.y - & align.x;
- vector_bytes = (vector_bytes + alignment - 1) & ~ (alignment - 1);
- }
-
- amt = vector_bytes + (n_vecs * elm_bytes);
- bitmap_vector = (sbitmap *) xmalloc (amt);
-
- for (i = 0, offset = vector_bytes;
- i < n_vecs;
- i++, offset += elm_bytes)
- {
- sbitmap b = (sbitmap) ((char *) bitmap_vector + offset);
- bitmap_vector[i] = b;
- b->n_bits = n_elms;
- b->size = size;
- b->bytes = bytes;
- }
-
- return bitmap_vector;
-}
-
-/* Copy sbitmap SRC to DST. */
-
-void
-sbitmap_copy (dst, src)
- sbitmap dst, src;
-{
- bcopy (src->elms, dst->elms, sizeof (SBITMAP_ELT_TYPE) * dst->size);
-}
-
-/* Zero all elements in a bitmap. */
-
-void
-sbitmap_zero (bmap)
- sbitmap bmap;
-{
- bzero ((char *) bmap->elms, bmap->bytes);
-}
-
-/* Set to ones all elements in a bitmap. */
-
-void
-sbitmap_ones (bmap)
- sbitmap bmap;
-{
- memset (bmap->elms, -1, bmap->bytes);
-}
-
-/* Zero a vector of N_VECS bitmaps. */
-
-void
-sbitmap_vector_zero (bmap, n_vecs)
- sbitmap *bmap;
- int n_vecs;
-{
- int i;
-
- for (i = 0; i < n_vecs; i++)
- sbitmap_zero (bmap[i]);
-}
-
-/* Set to ones a vector of N_VECS bitmaps. */
-
-void
-sbitmap_vector_ones (bmap, n_vecs)
- sbitmap *bmap;
- int n_vecs;
-{
- int i;
-
- for (i = 0; i < n_vecs; i++)
- sbitmap_ones (bmap[i]);
-}
-
-/* Set DST to be A union (B - C).
- DST = A | (B & ~C).
- Return non-zero if any change is made. */
-
-int
-sbitmap_union_of_diff (dst, a, b, c)
- sbitmap dst, a, b, c;
-{
- int i,changed;
- sbitmap_ptr dstp, ap, bp, cp;
-
- changed = 0;
- dstp = dst->elms;
- ap = a->elms;
- bp = b->elms;
- cp = c->elms;
- for (i = 0; i < dst->size; i++)
- {
- SBITMAP_ELT_TYPE tmp = *ap | (*bp & ~*cp);
- if (*dstp != tmp)
- changed = 1;
- *dstp = tmp;
- dstp++; ap++; bp++; cp++;
- }
- return changed;
-}
-
-/* Set bitmap DST to the bitwise negation of the bitmap SRC. */
-
-void
-sbitmap_not (dst, src)
- sbitmap dst, src;
-{
- int i;
- sbitmap_ptr dstp, ap;
-
- dstp = dst->elms;
- ap = src->elms;
- for (i = 0; i < dst->size; i++)
- {
- SBITMAP_ELT_TYPE tmp = ~(*ap);
- *dstp = tmp;
- dstp++; ap++;
- }
-}
-
-/* Set the bits in DST to be the difference between the bits
- in A and the bits in B. i.e. dst = a - b.
- The - operator is implemented as a & (~b). */
-
-void
-sbitmap_difference (dst, a, b)
- sbitmap dst, a, b;
-{
- int i;
- sbitmap_ptr dstp, ap, bp;
-
- dstp = dst->elms;
- ap = a->elms;
- bp = b->elms;
- for (i = 0; i < dst->size; i++)
- *dstp++ = *ap++ & (~*bp++);
-}
-
-/* Set DST to be (A and B)).
- Return non-zero if any change is made. */
-
-int
-sbitmap_a_and_b (dst, a, b)
- sbitmap dst, a, b;
-{
- int i,changed;
- sbitmap_ptr dstp, ap, bp;
-
- changed = 0;
- dstp = dst->elms;
- ap = a->elms;
- bp = b->elms;
- for (i = 0; i < dst->size; i++)
- {
- SBITMAP_ELT_TYPE tmp = *ap & *bp;
- if (*dstp != tmp)
- changed = 1;
- *dstp = tmp;
- dstp++; ap++; bp++;
- }
- return changed;
-}
-/* Set DST to be (A or B)).
- Return non-zero if any change is made. */
-
-int
-sbitmap_a_or_b (dst, a, b)
- sbitmap dst, a, b;
-{
- int i,changed;
- sbitmap_ptr dstp, ap, bp;
-
- changed = 0;
- dstp = dst->elms;
- ap = a->elms;
- bp = b->elms;
- for (i = 0; i < dst->size; i++)
- {
- SBITMAP_ELT_TYPE tmp = *ap | *bp;
- if (*dstp != tmp)
- changed = 1;
- *dstp = tmp;
- dstp++; ap++; bp++;
- }
- return changed;
-}
-
-/* Set DST to be (A or (B and C)).
- Return non-zero if any change is made. */
-
-int
-sbitmap_a_or_b_and_c (dst, a, b, c)
- sbitmap dst, a, b, c;
-{
- int i,changed;
- sbitmap_ptr dstp, ap, bp, cp;
-
- changed = 0;
- dstp = dst->elms;
- ap = a->elms;
- bp = b->elms;
- cp = c->elms;
- for (i = 0; i < dst->size; i++)
- {
- SBITMAP_ELT_TYPE tmp = *ap | (*bp & *cp);
- if (*dstp != tmp)
- changed = 1;
- *dstp = tmp;
- dstp++; ap++; bp++; cp++;
- }
- return changed;
-}
-
-/* Set DST to be (A ann (B or C)).
- Return non-zero if any change is made. */
-
-int
-sbitmap_a_and_b_or_c (dst, a, b, c)
- sbitmap dst, a, b, c;
-{
- int i,changed;
- sbitmap_ptr dstp, ap, bp, cp;
-
- changed = 0;
- dstp = dst->elms;
- ap = a->elms;
- bp = b->elms;
- cp = c->elms;
- for (i = 0; i < dst->size; i++)
- {
- SBITMAP_ELT_TYPE tmp = *ap & (*bp | *cp);
- if (*dstp != tmp)
- changed = 1;
- *dstp = tmp;
- dstp++; ap++; bp++; cp++;
- }
- return changed;
-}
-
-/* Set the bitmap DST to the intersection of SRC of all predecessors or
- successors of block number BB (PRED_SUCC says which). */
-
-void
-sbitmap_intersect_of_predsucc (dst, src, bb, pred_succ)
- sbitmap dst;
- sbitmap *src;
- int bb;
- int_list_ptr *pred_succ;
-{
- int_list_ptr ps;
- int ps_bb;
- int set_size = dst->size;
-
- ps = pred_succ[bb];
-
- /* It is possible that there are no predecessors(/successors).
- This can happen for example in unreachable code. */
-
- if (ps == NULL)
- {
- /* In APL-speak this is the `and' reduction of the empty set and thus
- the result is the identity for `and'. */
- sbitmap_ones (dst);
- return;
- }
-
- /* Set result to first predecessor/successor. */
-
- for ( ; ps != NULL; ps = ps->next)
- {
- ps_bb = INT_LIST_VAL (ps);
- if (ps_bb == ENTRY_BLOCK || ps_bb == EXIT_BLOCK)
- continue;
- sbitmap_copy (dst, src[ps_bb]);
- /* Break out since we're only doing first predecessor. */
- break;
- }
- if (ps == NULL)
- return;
-
- /* Now do the remaining predecessors/successors. */
-
- for (ps = ps->next; ps != NULL; ps = ps->next)
- {
- int i;
- sbitmap_ptr p,r;
-
- ps_bb = INT_LIST_VAL (ps);
- if (ps_bb == ENTRY_BLOCK || ps_bb == EXIT_BLOCK)
- continue;
-
- p = src[ps_bb]->elms;
- r = dst->elms;
-
- for (i = 0; i < set_size; i++)
- *r++ &= *p++;
- }
-}
-
-/* Set the bitmap DST to the intersection of SRC of all predecessors
- of block number BB. */
-
-void
-sbitmap_intersect_of_predecessors (dst, src, bb, s_preds)
- sbitmap dst;
- sbitmap *src;
- int bb;
- int_list_ptr *s_preds;
-{
- sbitmap_intersect_of_predsucc (dst, src, bb, s_preds);
-}
-
-/* Set the bitmap DST to the intersection of SRC of all successors
- of block number BB. */
-
-void
-sbitmap_intersect_of_successors (dst, src, bb, s_succs)
- sbitmap dst;
- sbitmap *src;
- int bb;
- int_list_ptr *s_succs;
-{
- sbitmap_intersect_of_predsucc (dst, src, bb, s_succs);
-}
-
-/* Set the bitmap DST to the union of SRC of all predecessors/successors of
- block number BB. */
-
-void
-sbitmap_union_of_predsucc (dst, src, bb, pred_succ)
- sbitmap dst;
- sbitmap *src;
- int bb;
- int_list_ptr *pred_succ;
-{
- int_list_ptr ps;
- int ps_bb;
- int set_size = dst->size;
-
- ps = pred_succ[bb];
-
- /* It is possible that there are no predecessors(/successors).
- This can happen for example in unreachable code. */
-
- if (ps == NULL)
- {
- /* In APL-speak this is the `or' reduction of the empty set and thus
- the result is the identity for `or'. */
- sbitmap_zero (dst);
- return;
- }
-
- /* Set result to first predecessor/successor. */
-
- for ( ; ps != NULL; ps = ps->next)
- {
- ps_bb = INT_LIST_VAL (ps);
- if (ps_bb == ENTRY_BLOCK || ps_bb == EXIT_BLOCK)
- continue;
- sbitmap_copy (dst, src[ps_bb]);
- /* Break out since we're only doing first predecessor. */
- break;
- }
- if (ps == NULL)
- return;
-
- /* Now do the remaining predecessors/successors. */
-
- for (ps = ps->next; ps != NULL; ps = ps->next)
- {
- int i;
- sbitmap_ptr p,r;
-
- ps_bb = INT_LIST_VAL (ps);
- if (ps_bb == ENTRY_BLOCK || ps_bb == EXIT_BLOCK)
- continue;
-
- p = src[ps_bb]->elms;
- r = dst->elms;
-
- for (i = 0; i < set_size; i++)
- *r++ |= *p++;
- }
-}
-
-/* Set the bitmap DST to the union of SRC of all predecessors of
- block number BB. */
-
-void
-sbitmap_union_of_predecessors (dst, src, bb, s_preds)
- sbitmap dst;
- sbitmap *src;
- int bb;
- int_list_ptr *s_preds;
-{
- sbitmap_union_of_predsucc (dst, src, bb, s_preds);
-}
-
-/* Set the bitmap DST to the union of SRC of all predecessors of
- block number BB. */
-
-void
-sbitmap_union_of_successors (dst, src, bb, s_succ)
- sbitmap dst;
- sbitmap *src;
- int bb;
- int_list_ptr *s_succ;
-{
- sbitmap_union_of_predsucc (dst, src, bb, s_succ);
-}
/* Compute dominator relationships. */
void
@@ -4044,8 +4583,8 @@ compute_dominators (dominators, post_dominators, s_preds, s_succs)
sbitmap_zero (dominators[0]);
SET_BIT (dominators[0], 0);
- sbitmap_zero (post_dominators[n_basic_blocks-1]);
- SET_BIT (post_dominators[n_basic_blocks-1], 0);
+ sbitmap_zero (post_dominators[n_basic_blocks - 1]);
+ SET_BIT (post_dominators[n_basic_blocks - 1], 0);
passes = 0;
changed = 1;
@@ -4073,6 +4612,46 @@ compute_dominators (dominators, post_dominators, s_preds, s_succs)
free (temp_bitmap);
}
+/* Given DOMINATORS, compute the immediate dominators into IDOM. */
+
+void
+compute_immediate_dominators (idom, dominators)
+ int *idom;
+ sbitmap *dominators;
+{
+ sbitmap *tmp;
+ int b;
+
+ tmp = sbitmap_vector_alloc (n_basic_blocks, n_basic_blocks);
+
+ /* Begin with tmp(n) = dom(n) - { n }. */
+ for (b = n_basic_blocks; --b >= 0; )
+ {
+ sbitmap_copy (tmp[b], dominators[b]);
+ RESET_BIT (tmp[b], b);
+ }
+
+ /* Subtract out all of our dominator's dominators. */
+ for (b = n_basic_blocks; --b >= 0; )
+ {
+ sbitmap tmp_b = tmp[b];
+ int s;
+
+ for (s = n_basic_blocks; --s >= 0; )
+ if (TEST_BIT (tmp_b, s))
+ sbitmap_difference (tmp_b, tmp_b, tmp[s]);
+ }
+
+ /* Find the one bit set in the bitmap and put it in the output array. */
+ for (b = n_basic_blocks; --b >= 0; )
+ {
+ int t;
+ EXECUTE_IF_SET_IN_SBITMAP (tmp[b], 0, t, { idom[b] = t; });
+ }
+
+ sbitmap_vector_free (tmp);
+}
+
/* Count for a single SET rtx, X. */
static void
@@ -4283,12 +4862,18 @@ count_reg_references (x)
register allocators to prioritize pseudos for allocation to hard regs.
More accurate reference counts generally lead to better register allocation.
+ F is the first insn to be scanned.
+ LOOP_STEP denotes how much loop_depth should be incremented per
+ loop nesting level in order to increase the ref count more for references
+ in a loop.
+
It might be worthwhile to update REG_LIVE_LENGTH, REG_BASIC_BLOCK and
possibly other information which is used by the register allocators. */
void
-recompute_reg_usage (f)
+recompute_reg_usage (f, loop_step)
rtx f;
+ int loop_step;
{
rtx insn;
int i, max_reg;
@@ -4311,9 +4896,9 @@ recompute_reg_usage (f)
{
/* Look for loop boundaries. */
if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_END)
- loop_depth--;
+ loop_depth -= loop_step;
else if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_BEG)
- loop_depth++;
+ loop_depth += loop_step;
/* If we have LOOP_DEPTH == 0, there has been a bookkeeping error.
Abort now rather than setting register status incorrectly. */
@@ -4359,3 +4944,34 @@ recompute_reg_usage (f)
}
}
}
+
+/* Record INSN's block as BB. */
+
+void
+set_block_for_insn (insn, bb)
+ rtx insn;
+ basic_block bb;
+{
+ size_t uid = INSN_UID (insn);
+ if (uid >= basic_block_for_insn->num_elements)
+ {
+ int new_size;
+
+ /* Add one-eighth the size so we don't keep calling xrealloc. */
+ new_size = uid + (uid + 7) / 8;
+
+ VARRAY_GROW (basic_block_for_insn, new_size);
+ }
+ VARRAY_BB (basic_block_for_insn, uid) = bb;
+}
+
+/* Record INSN's block number as BB. */
+/* ??? This has got to go. */
+
+void
+set_block_num (insn, bb)
+ rtx insn;
+ int bb;
+{
+ set_block_for_insn (insn, BASIC_BLOCK (bb));
+}
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 8ba27d227df..d25ccdc51f9 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -1,5 +1,5 @@
/* Fold a constant sub-tree into a single node for C-compiler
- Copyright (C) 1987, 88, 92-97, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1987, 88, 92-98, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -50,9 +50,6 @@ Boston, MA 02111-1307, USA. */
#include "rtl.h"
#include "toplev.h"
-/* Handle floating overflow for `const_binop'. */
-static jmp_buf float_error;
-
static void encode PROTO((HOST_WIDE_INT *,
HOST_WIDE_INT, HOST_WIDE_INT));
static void decode PROTO((HOST_WIDE_INT *,
@@ -96,6 +93,9 @@ static tree fold_truthop PROTO((enum tree_code, tree, tree, tree));
static tree strip_compound_expr PROTO((tree, tree));
static int multiple_of_p PROTO((tree, tree, tree));
static tree constant_boolean_node PROTO((int, tree));
+static int count_cond PROTO((tree, int));
+static void const_binop_1 PROTO((PTR));
+static void fold_convert_1 PROTO((PTR));
#ifndef BRANCH_COST
#define BRANCH_COST 1
@@ -378,7 +378,7 @@ lshift_double (l1, h1, count, prec, lv, hv, arith)
void
rshift_double (l1, h1, count, prec, lv, hv, arith)
HOST_WIDE_INT l1, h1, count;
- int prec;
+ int prec ATTRIBUTE_UNUSED;
HOST_WIDE_INT *lv, *hv;
int arith;
{
@@ -529,7 +529,7 @@ div_and_round_double (code, uns,
encode (den, lden, hden);
/* Special code for when the divisor < BASE. */
- if (hden == 0 && lden < BASE)
+ if (hden == 0 && lden < (HOST_WIDE_INT) BASE)
{
/* hnum != 0 already checked. */
for (i = 4 - 1; i >= 0; i--)
@@ -885,6 +885,7 @@ exact_real_inverse (mode, r)
enum machine_mode mode;
REAL_VALUE_TYPE *r;
{
+ jmp_buf float_error;
union
{
double d;
@@ -964,6 +965,235 @@ fail:
*r = y.d;
return 1;
}
+
+
+/* Convert C9X hexadecimal floating point string constant S. Return
+ real value type in mode MODE. This function uses the host computer's
+ fp arithmetic when there is no REAL_ARITHMETIC. */
+
+REAL_VALUE_TYPE
+real_hex_to_f (s, mode)
+ char *s;
+ enum machine_mode mode;
+{
+ REAL_VALUE_TYPE ip;
+ char *p = s;
+ unsigned HOST_WIDE_INT low, high;
+ int frexpon, expon, shcount, nrmcount, k;
+ int sign, expsign, decpt, isfloat, isldouble, gotp, lost;
+ char c;
+
+ isldouble = 0;
+ isfloat = 0;
+ frexpon = 0;
+ expon = 0;
+ expsign = 1;
+ ip = 0.0;
+
+ while (*p == ' ' || *p == '\t')
+ ++p;
+
+ /* Sign, if any, comes first. */
+ sign = 1;
+ if (*p == '-')
+ {
+ sign = -1;
+ ++p;
+ }
+
+ /* The string is supposed to start with 0x or 0X . */
+ if (*p == '0')
+ {
+ ++p;
+ if (*p == 'x' || *p == 'X')
+ ++p;
+ else
+ abort ();
+ }
+ else
+ abort ();
+
+ while (*p == '0')
+ ++p;
+
+ high = 0;
+ low = 0;
+ lost = 0; /* Nonzero low order bits shifted out and discarded. */
+ frexpon = 0; /* Bits after the decimal point. */
+ expon = 0; /* Value of exponent. */
+ decpt = 0; /* How many decimal points. */
+ gotp = 0; /* How many P's. */
+ shcount = 0;
+ while ((c = *p) != '\0')
+ {
+ if ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F')
+ || (c >= 'a' && c <= 'f'))
+ {
+ k = c & 0x7f;
+ if (k >= 'a')
+ k = k - 'a' + 10;
+ else if (k >= 'A')
+ k = k - 'A' + 10;
+ else
+ k = k - '0';
+
+ if ((high & 0xf0000000) == 0)
+ {
+ high = (high << 4) + ((low >> 28) & 15);
+ low = (low << 4) + k;
+ shcount += 4;
+ if (decpt)
+ frexpon += 4;
+ }
+ else
+ {
+ /* Record nonzero lost bits. */
+ lost |= k;
+ if (!decpt)
+ frexpon -= 4;
+ }
+ ++p;
+ }
+ else if ( c == '.')
+ {
+ ++decpt;
+ ++p;
+ }
+ else if (c == 'p' || c == 'P')
+ {
+ ++gotp;
+ ++p;
+ /* Sign of exponent. */
+ if (*p == '-')
+ {
+ expsign = -1;
+ ++p;
+ }
+ /* Value of exponent.
+ The exponent field is a decimal integer. */
+ while (isdigit(*p))
+ {
+ k = (*p++ & 0x7f) - '0';
+ expon = 10 * expon + k;
+ }
+ expon *= expsign;
+ /* F suffix is ambiguous in the significand part
+ so it must appear after the decimal exponent field. */
+ if (*p == 'f' || *p == 'F')
+ {
+ isfloat = 1;
+ ++p;
+ break;
+ }
+ }
+ else if (c == 'l' || c == 'L')
+ {
+ isldouble = 1;
+ ++p;
+ break;
+ }
+ else
+ break;
+ }
+ /* Abort if last character read was not legitimate. */
+ c = *p;
+ if ((c != '\0' && c != ' ' && c != '\n' && c != '\r') || (decpt > 1))
+ abort ();
+ /* There must be either one decimal point or one p. */
+ if (decpt == 0 && gotp == 0)
+ abort ();
+ shcount -= 4;
+ if ((high == 0) && (low == 0))
+ {
+ return dconst0;
+ }
+
+ /* Normalize. */
+ nrmcount = 0;
+ if (high == 0)
+ {
+ high = low;
+ low = 0;
+ nrmcount += 32;
+ }
+ /* Leave a high guard bit for carry-out. */
+ if ((high & 0x80000000) != 0)
+ {
+ lost |= low & 1;
+ low = (low >> 1) | (high << 31);
+ high = high >> 1;
+ nrmcount -= 1;
+ }
+ if ((high & 0xffff8000) == 0)
+ {
+ high = (high << 16) + ((low >> 16) & 0xffff);
+ low = low << 16;
+ nrmcount += 16;
+ }
+ while ((high & 0xc0000000) == 0)
+ {
+ high = (high << 1) + ((low >> 31) & 1);
+ low = low << 1;
+ nrmcount += 1;
+ }
+ if (isfloat || GET_MODE_SIZE(mode) == UNITS_PER_WORD)
+ {
+ /* Keep 24 bits precision, bits 0x7fffff80.
+ Rounding bit is 0x40. */
+ lost = lost | low | (high & 0x3f);
+ low = 0;
+ if (high & 0x40)
+ {
+ if ((high & 0x80) || lost)
+ high += 0x40;
+ }
+ high &= 0xffffff80;
+ }
+ else
+ {
+ /* We need real.c to do long double formats, so here default
+ to double precision. */
+#if HOST_FLOAT_FORMAT == IEEE_FLOAT_FORMAT
+ /* IEEE double.
+ Keep 53 bits precision, bits 0x7fffffff fffffc00.
+ Rounding bit is low word 0x200. */
+ lost = lost | (low & 0x1ff);
+ if (low & 0x200)
+ {
+ if ((low & 0x400) || lost)
+ {
+ low = (low + 0x200) & 0xfffffc00;
+ if (low == 0)
+ high += 1;
+ }
+ }
+ low &= 0xfffffc00;
+#else
+ /* Assume it's a VAX with 56-bit significand,
+ bits 0x7fffffff ffffff80. */
+ lost = lost | (low & 0x7f);
+ if (low & 0x40)
+ {
+ if ((low & 0x80) || lost)
+ {
+ low = (low + 0x40) & 0xffffff80;
+ if (low == 0)
+ high += 1;
+ }
+ }
+ low &= 0xffffff80;
+#endif
+ }
+ ip = (double) high;
+ ip = REAL_VALUE_LDEXP (ip, 32) + (double) low;
+ /* Apply shifts and exponent value as power of 2. */
+ ip = REAL_VALUE_LDEXP (ip, expon - (nrmcount + frexpon));
+
+ if (sign < 0)
+ ip = -ip;
+ return ip;
+}
+
#endif /* no REAL_ARITHMETIC */
/* Split a tree IN into a constant and a variable part
@@ -1248,6 +1478,67 @@ int_const_binop (code, arg1, arg2, notrunc, forsize)
return t;
}
+struct cb_args
+{
+ /* Input */
+ tree arg1;
+ REAL_VALUE_TYPE d1, d2;
+ enum tree_code code;
+ /* Output */
+ tree t;
+};
+
+static void
+const_binop_1 (data)
+ PTR data;
+{
+ struct cb_args * args = (struct cb_args *) data;
+ REAL_VALUE_TYPE value;
+
+#ifdef REAL_ARITHMETIC
+ REAL_ARITHMETIC (value, args->code, args->d1, args->d2);
+#else
+ switch (args->code)
+ {
+ case PLUS_EXPR:
+ value = args->d1 + args->d2;
+ break;
+
+ case MINUS_EXPR:
+ value = args->d1 - args->d2;
+ break;
+
+ case MULT_EXPR:
+ value = args->d1 * args->d2;
+ break;
+
+ case RDIV_EXPR:
+#ifndef REAL_INFINITY
+ if (args->d2 == 0)
+ abort ();
+#endif
+
+ value = args->d1 / args->d2;
+ break;
+
+ case MIN_EXPR:
+ value = MIN (args->d1, args->d2);
+ break;
+
+ case MAX_EXPR:
+ value = MAX (args->d1, args->d2);
+ break;
+
+ default:
+ abort ();
+ }
+#endif /* no REAL_ARITHMETIC */
+ args->t =
+ build_real (TREE_TYPE (args->arg1),
+ real_value_truncate (TYPE_MODE (TREE_TYPE (args->arg1)),
+ value));
+}
+
/* Combine two constants ARG1 and ARG2 under operation CODE
to produce a new constant.
We assume ARG1 and ARG2 have the same data type,
@@ -1272,8 +1563,8 @@ const_binop (code, arg1, arg2, notrunc)
REAL_VALUE_TYPE d1;
REAL_VALUE_TYPE d2;
int overflow = 0;
- REAL_VALUE_TYPE value;
tree t;
+ struct cb_args args;
d1 = TREE_REAL_CST (arg1);
d2 = TREE_REAL_CST (arg2);
@@ -1284,57 +1575,24 @@ const_binop (code, arg1, arg2, notrunc)
return arg1;
else if (REAL_VALUE_ISNAN (d2))
return arg2;
- else if (setjmp (float_error))
+
+ /* Setup input for const_binop_1() */
+ args.arg1 = arg1;
+ args.d1 = d1;
+ args.d2 = d2;
+ args.code = code;
+
+ if (do_float_handler (const_binop_1, (PTR) &args))
{
- t = copy_node (arg1);
- overflow = 1;
- goto got_float;
+ /* Receive output from const_binop_1() */
+ t = args.t;
}
-
- set_float_handler (float_error);
-
-#ifdef REAL_ARITHMETIC
- REAL_ARITHMETIC (value, code, d1, d2);
-#else
- switch (code)
+ else
{
- case PLUS_EXPR:
- value = d1 + d2;
- break;
-
- case MINUS_EXPR:
- value = d1 - d2;
- break;
-
- case MULT_EXPR:
- value = d1 * d2;
- break;
-
- case RDIV_EXPR:
-#ifndef REAL_INFINITY
- if (d2 == 0)
- abort ();
-#endif
-
- value = d1 / d2;
- break;
-
- case MIN_EXPR:
- value = MIN (d1, d2);
- break;
-
- case MAX_EXPR:
- value = MAX (d1, d2);
- break;
-
- default:
- abort ();
+ /* We got an exception from const_binop_1() */
+ t = copy_node (arg1);
+ overflow = 1;
}
-#endif /* no REAL_ARITHMETIC */
- t = build_real (TREE_TYPE (arg1),
- real_value_truncate (TYPE_MODE (TREE_TYPE (arg1)), value));
- got_float:
- set_float_handler (NULL_PTR);
TREE_OVERFLOW (t)
= (force_fit_type (t, overflow)
@@ -1508,6 +1766,25 @@ ssize_binop (code, arg0, arg1)
return fold (build (code, ssizetype, arg0, arg1));
}
+struct fc_args
+{
+ /* Input */
+ tree arg1, type;
+ /* Output */
+ tree t;
+};
+
+static void
+fold_convert_1 (data)
+ PTR data;
+{
+ struct fc_args * args = (struct fc_args *) data;
+
+ args->t = build_real (args->type,
+ real_value_truncate (TYPE_MODE (args->type),
+ TREE_REAL_CST (args->arg1)));
+}
+
/* Given T, a tree representing type conversion of ARG1, a constant,
return a constant tree representing the result of conversion. */
@@ -1633,25 +1910,31 @@ fold_convert (t, arg1)
#endif /* not REAL_IS_NOT_DOUBLE, or REAL_ARITHMETIC */
if (TREE_CODE (arg1) == REAL_CST)
{
+ struct fc_args args;
+
if (REAL_VALUE_ISNAN (TREE_REAL_CST (arg1)))
{
t = arg1;
TREE_TYPE (arg1) = type;
return t;
}
- else if (setjmp (float_error))
+
+ /* Setup input for fold_convert_1() */
+ args.arg1 = arg1;
+ args.type = type;
+
+ if (do_float_handler (fold_convert_1, (PTR) &args))
+ {
+ /* Receive output from fold_convert_1() */
+ t = args.t;
+ }
+ else
{
+ /* We got an exception from fold_convert_1() */
overflow = 1;
t = copy_node (arg1);
- goto got_it;
}
- set_float_handler (float_error);
-
- t = build_real (type, real_value_truncate (TYPE_MODE (type),
- TREE_REAL_CST (arg1)));
- set_float_handler (NULL_PTR);
- got_it:
TREE_OVERFLOW (t)
= TREE_OVERFLOW (arg1) | force_fit_type (t, overflow);
TREE_CONSTANT_OVERFLOW (t)
@@ -2128,7 +2411,7 @@ eval_subst (arg, old0, new0, old1, new1)
default:
break;
}
- /* fall through (???) */
+ /* fall through - ??? */
case '<':
{
@@ -2514,8 +2797,8 @@ optimize_bit_field_compare (code, compare_type, lhs, rhs)
convert (unsigned_type, rhs),
size_int (lbitsize), 0)))
{
- warning ("comparison is always %s due to width of bitfield",
- code == NE_EXPR ? "one" : "zero");
+ warning ("comparison is always %d due to width of bitfield",
+ code == NE_EXPR);
return convert (compare_type,
(code == NE_EXPR
? integer_one_node : integer_zero_node));
@@ -2527,8 +2810,8 @@ optimize_bit_field_compare (code, compare_type, lhs, rhs)
size_int (lbitsize - 1), 0);
if (! integer_zerop (tem) && ! integer_all_onesp (tem))
{
- warning ("comparison is always %s due to width of bitfield",
- code == NE_EXPR ? "one" : "zero");
+ warning ("comparison is always %d due to width of bitfield",
+ code == NE_EXPR);
return convert (compare_type,
(code == NE_EXPR
? integer_one_node : integer_zero_node));
@@ -2762,21 +3045,33 @@ range_binop (code, type, arg0, upper0_p, arg1, upper1_p)
return 0;
/* Set SGN[01] to -1 if ARG[01] is a lower bound, 1 for upper, and 0
- for neither. Then compute our result treating them as never equal
- and comparing bounds to non-bounds as above. */
+ for neither. In real maths, we cannot assume open ended ranges are
+ the same. But, this is computer arithmetic, where numbers are finite.
+ We can therefore make the transformation of any unbounded range with
+ the value Z, Z being greater than any representable number. This permits
+ us to treat unbounded ranges as equal. */
sgn0 = arg0 != 0 ? 0 : (upper0_p ? 1 : -1);
sgn1 = arg1 != 0 ? 0 : (upper1_p ? 1 : -1);
switch (code)
{
- case EQ_EXPR: case NE_EXPR:
- result = (code == NE_EXPR);
+ case EQ_EXPR:
+ result = sgn0 == sgn1;
+ break;
+ case NE_EXPR:
+ result = sgn0 != sgn1;
break;
- case LT_EXPR: case LE_EXPR:
+ case LT_EXPR:
result = sgn0 < sgn1;
break;
- case GT_EXPR: case GE_EXPR:
+ case LE_EXPR:
+ result = sgn0 <= sgn1;
+ break;
+ case GT_EXPR:
result = sgn0 > sgn1;
break;
+ case GE_EXPR:
+ result = sgn0 >= sgn1;
+ break;
default:
abort ();
}
@@ -2828,6 +3123,11 @@ make_range (exp, pin_p, plow, phigh)
arg1 = TREE_OPERAND (exp, 1);
}
+ /* Set ORIG_TYPE as soon as TYPE is non-null so that we do not
+ lose a cast by accident. */
+ if (type != NULL_TREE && orig_type == NULL_TREE)
+ orig_type = type;
+
switch (code)
{
case TRUTH_NOT_EXPR:
@@ -2946,8 +3246,6 @@ make_range (exp, pin_p, plow, phigh)
continue;
case NOP_EXPR: case NON_LVALUE_EXPR: case CONVERT_EXPR:
- if (orig_type == NULL_TREE)
- orig_type = type;
if (TYPE_PRECISION (type) > TYPE_PRECISION (orig_type))
break;
@@ -3295,7 +3593,6 @@ fold_range_test (exp)
}
}
-
return 0;
}
@@ -3396,7 +3693,7 @@ fold_truthop (code, truth_type, lhs, rhs)
tree ll_mask, lr_mask, rl_mask, rr_mask;
tree ll_and_mask, lr_and_mask, rl_and_mask, rr_and_mask;
tree l_const, r_const;
- tree type, result;
+ tree lntype, rntype, result;
int first_bit, end_bit;
int volatilep;
@@ -3534,7 +3831,7 @@ fold_truthop (code, truth_type, lhs, rhs)
lnbitsize = GET_MODE_BITSIZE (lnmode);
lnbitpos = first_bit & ~ (lnbitsize - 1);
- type = type_for_size (lnbitsize, 1);
+ lntype = type_for_size (lnbitsize, 1);
xll_bitpos = ll_bitpos - lnbitpos, xrl_bitpos = rl_bitpos - lnbitpos;
if (BYTES_BIG_ENDIAN)
@@ -3543,23 +3840,22 @@ fold_truthop (code, truth_type, lhs, rhs)
xrl_bitpos = lnbitsize - xrl_bitpos - rl_bitsize;
}
- ll_mask = const_binop (LSHIFT_EXPR, convert (type, ll_mask),
+ ll_mask = const_binop (LSHIFT_EXPR, convert (lntype, ll_mask),
size_int (xll_bitpos), 0);
- rl_mask = const_binop (LSHIFT_EXPR, convert (type, rl_mask),
+ rl_mask = const_binop (LSHIFT_EXPR, convert (lntype, rl_mask),
size_int (xrl_bitpos), 0);
if (l_const)
{
- l_const = convert (type, l_const);
+ l_const = convert (lntype, l_const);
l_const = unextend (l_const, ll_bitsize, ll_unsignedp, ll_and_mask);
l_const = const_binop (LSHIFT_EXPR, l_const, size_int (xll_bitpos), 0);
if (! integer_zerop (const_binop (BIT_AND_EXPR, l_const,
fold (build1 (BIT_NOT_EXPR,
- type, ll_mask)),
+ lntype, ll_mask)),
0)))
{
- warning ("comparison is always %s",
- wanted_code == NE_EXPR ? "one" : "zero");
+ warning ("comparison is always %d", wanted_code == NE_EXPR);
return convert (truth_type,
wanted_code == NE_EXPR
@@ -3568,17 +3864,16 @@ fold_truthop (code, truth_type, lhs, rhs)
}
if (r_const)
{
- r_const = convert (type, r_const);
+ r_const = convert (lntype, r_const);
r_const = unextend (r_const, rl_bitsize, rl_unsignedp, rl_and_mask);
r_const = const_binop (LSHIFT_EXPR, r_const, size_int (xrl_bitpos), 0);
if (! integer_zerop (const_binop (BIT_AND_EXPR, r_const,
fold (build1 (BIT_NOT_EXPR,
- type, rl_mask)),
+ lntype, rl_mask)),
0)))
{
- warning ("comparison is always %s",
- wanted_code == NE_EXPR ? "one" : "zero");
-
+ warning ("comparison is always %d", wanted_code == NE_EXPR);
+
return convert (truth_type,
wanted_code == NE_EXPR
? integer_one_node : integer_zero_node);
@@ -3607,6 +3902,7 @@ fold_truthop (code, truth_type, lhs, rhs)
rnbitsize = GET_MODE_BITSIZE (rnmode);
rnbitpos = first_bit & ~ (rnbitsize - 1);
+ rntype = type_for_size (rnbitsize, 1);
xlr_bitpos = lr_bitpos - rnbitpos, xrr_bitpos = rr_bitpos - rnbitpos;
if (BYTES_BIG_ENDIAN)
@@ -3615,47 +3911,83 @@ fold_truthop (code, truth_type, lhs, rhs)
xrr_bitpos = rnbitsize - xrr_bitpos - rr_bitsize;
}
- lr_mask = const_binop (LSHIFT_EXPR, convert (type, lr_mask),
+ lr_mask = const_binop (LSHIFT_EXPR, convert (rntype, lr_mask),
size_int (xlr_bitpos), 0);
- rr_mask = const_binop (LSHIFT_EXPR, convert (type, rr_mask),
+ rr_mask = const_binop (LSHIFT_EXPR, convert (rntype, rr_mask),
size_int (xrr_bitpos), 0);
/* Make a mask that corresponds to both fields being compared.
- Do this for both items being compared. If the masks agree,
- we can do this by masking both and comparing the masked
+ Do this for both items being compared. If the operands are the
+ same size and the bits being compared are in the same position
+ then we can do this by masking both and comparing the masked
results. */
ll_mask = const_binop (BIT_IOR_EXPR, ll_mask, rl_mask, 0);
lr_mask = const_binop (BIT_IOR_EXPR, lr_mask, rr_mask, 0);
- if (operand_equal_p (ll_mask, lr_mask, 0) && lnbitsize == rnbitsize)
+ if (lnbitsize == rnbitsize && xll_bitpos == xlr_bitpos)
{
- lhs = make_bit_field_ref (ll_inner, type, lnbitsize, lnbitpos,
+ lhs = make_bit_field_ref (ll_inner, lntype, lnbitsize, lnbitpos,
ll_unsignedp || rl_unsignedp);
- rhs = make_bit_field_ref (lr_inner, type, rnbitsize, rnbitpos,
- lr_unsignedp || rr_unsignedp);
if (! all_ones_mask_p (ll_mask, lnbitsize))
- {
- lhs = build (BIT_AND_EXPR, type, lhs, ll_mask);
- rhs = build (BIT_AND_EXPR, type, rhs, ll_mask);
- }
+ lhs = build (BIT_AND_EXPR, lntype, lhs, ll_mask);
+
+ rhs = make_bit_field_ref (lr_inner, rntype, rnbitsize, rnbitpos,
+ lr_unsignedp || rr_unsignedp);
+ if (! all_ones_mask_p (lr_mask, rnbitsize))
+ rhs = build (BIT_AND_EXPR, rntype, rhs, lr_mask);
+
return build (wanted_code, truth_type, lhs, rhs);
}
/* There is still another way we can do something: If both pairs of
fields being compared are adjacent, we may be able to make a wider
- field containing them both. */
+ field containing them both.
+
+ Note that we still must mask the lhs/rhs expressions. Furthermore,
+ the mask must be shifted to account for the shift done by
+ make_bit_field_ref. */
if ((ll_bitsize + ll_bitpos == rl_bitpos
&& lr_bitsize + lr_bitpos == rr_bitpos)
|| (ll_bitpos == rl_bitpos + rl_bitsize
&& lr_bitpos == rr_bitpos + rr_bitsize))
- return build (wanted_code, truth_type,
- make_bit_field_ref (ll_inner, type,
- ll_bitsize + rl_bitsize,
- MIN (ll_bitpos, rl_bitpos),
- ll_unsignedp),
- make_bit_field_ref (lr_inner, type,
- lr_bitsize + rr_bitsize,
- MIN (lr_bitpos, rr_bitpos),
- lr_unsignedp));
+ {
+ tree type;
+
+ lhs = make_bit_field_ref (ll_inner, lntype, ll_bitsize + rl_bitsize,
+ MIN (ll_bitpos, rl_bitpos), ll_unsignedp);
+ rhs = make_bit_field_ref (lr_inner, rntype, lr_bitsize + rr_bitsize,
+ MIN (lr_bitpos, rr_bitpos), lr_unsignedp);
+
+ ll_mask = const_binop (RSHIFT_EXPR, ll_mask,
+ size_int (MIN (xll_bitpos, xrl_bitpos)), 0);
+ lr_mask = const_binop (RSHIFT_EXPR, lr_mask,
+ size_int (MIN (xlr_bitpos, xrr_bitpos)), 0);
+
+ /* Convert to the smaller type before masking out unwanted bits. */
+ type = lntype;
+ if (lntype != rntype)
+ {
+ if (lnbitsize > rnbitsize)
+ {
+ lhs = convert (rntype, lhs);
+ ll_mask = convert (rntype, ll_mask);
+ type = rntype;
+ }
+ else if (lnbitsize < rnbitsize)
+ {
+ rhs = convert (lntype, rhs);
+ lr_mask = convert (lntype, lr_mask);
+ type = lntype;
+ }
+ }
+
+ if (! all_ones_mask_p (ll_mask, ll_bitsize + rl_bitsize))
+ lhs = build (BIT_AND_EXPR, type, lhs, ll_mask);
+
+ if (! all_ones_mask_p (lr_mask, lr_bitsize + rr_bitsize))
+ rhs = build (BIT_AND_EXPR, type, rhs, lr_mask);
+
+ return build (wanted_code, truth_type, lhs, rhs);
+ }
return 0;
}
@@ -3676,7 +4008,7 @@ fold_truthop (code, truth_type, lhs, rhs)
}
else
{
- warning ("`and' of mutually exclusive equal-tests is always zero");
+ warning ("`and' of mutually exclusive equal-tests is always 0");
return convert (truth_type, integer_zero_node);
}
}
@@ -3685,12 +4017,12 @@ fold_truthop (code, truth_type, lhs, rhs)
reference we will make. Unless the mask is all ones the width of
that field, perform the mask operation. Then compare with the
merged constant. */
- result = make_bit_field_ref (ll_inner, type, lnbitsize, lnbitpos,
+ result = make_bit_field_ref (ll_inner, lntype, lnbitsize, lnbitpos,
ll_unsignedp || rl_unsignedp);
ll_mask = const_binop (BIT_IOR_EXPR, ll_mask, rl_mask, 0);
if (! all_ones_mask_p (ll_mask, lnbitsize))
- result = build (BIT_AND_EXPR, type, result, ll_mask);
+ result = build (BIT_AND_EXPR, lntype, result, ll_mask);
return build (wanted_code, truth_type, result,
const_binop (BIT_IOR_EXPR, l_const, r_const, 0));
@@ -3753,6 +4085,27 @@ constant_boolean_node (value, type)
}
}
+/* Utility function for the following routine, to see how complex a nesting of
+ COND_EXPRs can be. EXPR is the expression and LIMIT is a count beyond which
+ we don't care (to avoid spending too much time on complex expressions.). */
+
+static int
+count_cond (expr, lim)
+ tree expr;
+ int lim;
+{
+ int true, false;
+
+ if (TREE_CODE (expr) != COND_EXPR)
+ return 0;
+ else if (lim <= 0)
+ return 0;
+
+ true = count_cond (TREE_OPERAND (expr, 1), lim - 1);
+ false = count_cond (TREE_OPERAND (expr, 2), lim - 1 - true);
+ return MIN (lim, 1 + true + false);
+}
+
/* Perform constant folding and related simplification of EXPR.
The related simplifications include x*1 => x, x*0 => 0, etc.,
and application of the associative law.
@@ -3976,6 +4329,8 @@ fold (expr)
else if ((TREE_CODE (arg1) == COND_EXPR
|| (TREE_CODE_CLASS (TREE_CODE (arg1)) == '<'
&& TREE_CODE_CLASS (code) != '<'))
+ && (TREE_CODE (arg0) != COND_EXPR
+ || count_cond (arg0, 25) + count_cond (arg1, 25) <= 25)
&& (! TREE_SIDE_EFFECTS (arg0)
|| (current_function_decl != 0
&& ! contains_placeholder_p (arg0))))
@@ -4049,6 +4404,8 @@ fold (expr)
else if ((TREE_CODE (arg0) == COND_EXPR
|| (TREE_CODE_CLASS (TREE_CODE (arg0)) == '<'
&& TREE_CODE_CLASS (code) != '<'))
+ && (TREE_CODE (arg1) != COND_EXPR
+ || count_cond (arg0, 25) + count_cond (arg1, 25) <= 25)
&& (! TREE_SIDE_EFFECTS (arg1)
|| (current_function_decl != 0
&& ! contains_placeholder_p (arg1))))
@@ -4673,6 +5030,8 @@ fold (expr)
tree01 = TREE_OPERAND (arg0, 1);
tree11 = TREE_OPERAND (arg1, 1);
+ STRIP_NOPS (tree01);
+ STRIP_NOPS (tree11);
code01 = TREE_CODE (tree01);
code11 = TREE_CODE (tree11);
if (code01 == INTEGER_CST
@@ -4683,22 +5042,40 @@ fold (expr)
== TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg0, 0)))))
return build (LROTATE_EXPR, type, TREE_OPERAND (arg0, 0),
code0 == LSHIFT_EXPR ? tree01 : tree11);
- else if (code11 == MINUS_EXPR
- && TREE_CODE (TREE_OPERAND (tree11, 0)) == INTEGER_CST
- && TREE_INT_CST_HIGH (TREE_OPERAND (tree11, 0)) == 0
- && TREE_INT_CST_LOW (TREE_OPERAND (tree11, 0))
- == TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg0, 0)))
- && operand_equal_p (tree01, TREE_OPERAND (tree11, 1), 0))
- return build (code0 == LSHIFT_EXPR ? LROTATE_EXPR : RROTATE_EXPR,
- type, TREE_OPERAND (arg0, 0), tree01);
- else if (code01 == MINUS_EXPR
- && TREE_CODE (TREE_OPERAND (tree01, 0)) == INTEGER_CST
- && TREE_INT_CST_HIGH (TREE_OPERAND (tree01, 0)) == 0
- && TREE_INT_CST_LOW (TREE_OPERAND (tree01, 0))
- == TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg0, 0)))
- && operand_equal_p (tree11, TREE_OPERAND (tree01, 1), 0))
- return build (code0 != LSHIFT_EXPR ? LROTATE_EXPR : RROTATE_EXPR,
- type, TREE_OPERAND (arg0, 0), tree11);
+ else if (code11 == MINUS_EXPR)
+ {
+ tree tree110, tree111;
+ tree110 = TREE_OPERAND (tree11, 0);
+ tree111 = TREE_OPERAND (tree11, 1);
+ STRIP_NOPS (tree110);
+ STRIP_NOPS (tree111);
+ if (TREE_CODE (tree110) == INTEGER_CST
+ && TREE_INT_CST_HIGH (tree110) == 0
+ && (TREE_INT_CST_LOW (tree110)
+ == TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg0, 0))))
+ && operand_equal_p (tree01, tree111, 0))
+ return build ((code0 == LSHIFT_EXPR
+ ? LROTATE_EXPR
+ : RROTATE_EXPR),
+ type, TREE_OPERAND (arg0, 0), tree01);
+ }
+ else if (code01 == MINUS_EXPR)
+ {
+ tree tree010, tree011;
+ tree010 = TREE_OPERAND (tree01, 0);
+ tree011 = TREE_OPERAND (tree01, 1);
+ STRIP_NOPS (tree010);
+ STRIP_NOPS (tree011);
+ if (TREE_CODE (tree010) == INTEGER_CST
+ && TREE_INT_CST_HIGH (tree010) == 0
+ && (TREE_INT_CST_LOW (tree010)
+ == TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg0, 0))))
+ && operand_equal_p (tree11, tree011, 0))
+ return build ((code0 != LSHIFT_EXPR
+ ? LROTATE_EXPR
+ : RROTATE_EXPR),
+ type, TREE_OPERAND (arg0, 0), tree11);
+ }
}
goto associate;
diff --git a/gcc/frame.c b/gcc/frame.c
index b3d30c86f5e..b5f643e7043 100644
--- a/gcc/frame.c
+++ b/gcc/frame.c
@@ -46,7 +46,6 @@ Boston, MA 02111-1307, USA. */
#include "defaults.h"
#ifdef DWARF2_UNWIND_INFO
-#include "gansidecl.h"
#include "dwarf2.h"
#include <stddef.h>
#include "frame.h"
@@ -71,6 +70,25 @@ typedef unsigned int uaddr __attribute__ ((mode (pointer)));
typedef int saddr __attribute__ ((mode (pointer)));
typedef unsigned char ubyte;
+/* Terminology:
+ CIE - Common Information Element
+ FDE - Frame Descriptor Element
+
+ There is one per function, and it describes where the function code
+ is located, and what the register lifetimes and stack layout are
+ within the function.
+
+ The data structures are defined in the DWARF specfication, although
+ not in a very readable way (see LITERATURE).
+
+ Every time an exception is thrown, the code needs to locate the FDE
+ for the current function, and starts to look for exception regions
+ from that FDE. This works in a two-level search:
+ a) in a linear search, find the shared image (i.e. DLL) containing
+ the PC
+ b) using the FDE table for that shared object, locate the FDE using
+ binary search (which requires the sorting). */
+
/* The first few fields of a CIE. The CIE_id field is 0 for a CIE,
to distinguish it from a valid FDE. FDEs are aligned to an addressing
unit boundary, but the fields within are unaligned. */
diff --git a/gcc/frame.h b/gcc/frame.h
index 7493d92f80b..985416cd180 100644
--- a/gcc/frame.h
+++ b/gcc/frame.h
@@ -1,5 +1,25 @@
-/* Copyright (C) 1997 Free Software Foundation, Inc.
- This file is part of GNU CC. */
+/* Header file for unwinding stack frames for exception handling. */
+/* Compile this one with gcc. */
+/* Copyright (C) 1997, 1998 Free Software Foundation, Inc.
+ Contributed by Jason Merrill <jason@cygnus.com>.
+
+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. */
+
typedef struct frame_state
{
@@ -34,6 +54,11 @@ struct object {
struct object *next;
};
+/* Note the following routines are exported interfaces from libgcc; do not
+ change these interfaces. Instead create new interfaces. Also note
+ references to these functions may be made weak in files where they
+ are referenced. */
+
extern void __register_frame (void * );
extern void __register_frame_table (void *);
extern void __deregister_frame (void *);
diff --git a/gcc/function.c b/gcc/function.c
index 77612ca6623..a2645981010 100644
--- a/gcc/function.c
+++ b/gcc/function.c
@@ -1,5 +1,5 @@
/* Expands front end tree to back end RTL for GNU C-Compiler
- Copyright (C) 1987, 88, 89, 91-97, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1987, 88, 89, 91-98, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -56,12 +56,21 @@ Boston, MA 02111-1307, USA. */
#include "basic-block.h"
#include "obstack.h"
#include "toplev.h"
+#include "hash.h"
#include "ggc.h"
+#if !defined PREFERRED_STACK_BOUNDARY && defined STACK_BOUNDARY
+#define PREFERRED_STACK_BOUNDARY STACK_BOUNDARY
+#endif
+
#ifndef TRAMPOLINE_ALIGNMENT
#define TRAMPOLINE_ALIGNMENT FUNCTION_BOUNDARY
#endif
+#ifndef LOCAL_ALIGNMENT
+#define LOCAL_ALIGNMENT(TYPE, ALIGNMENT) ALIGNMENT
+#endif
+
/* Some systems use __main in a way incompatible with its use in gcc, in these
cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
give the same symbol without quotes for an alternative entry point. You
@@ -93,13 +102,6 @@ Boston, MA 02111-1307, USA. */
/* The function structure for the currently being compiled function. */
struct function *current_function;
-/* Nonzero if this function has a computed goto.
-
- It is computed during find_basic_blocks or during stupid life
- analysis. */
-
-int current_function_has_computed_jump;
-
/* The FUNCTION_DECL for an inline function currently being expanded. */
tree inline_function_decl;
@@ -152,9 +154,22 @@ struct temp_slot
/* The rtx used to represent the address if not the address of the
slot above. May be an EXPR_LIST if multiple addresses exist. */
rtx address;
+ /* The alignment (in bits) of the slot. */
+ int align;
/* The size, in units, of the slot. */
HOST_WIDE_INT size;
- /* The value of `seq_rtl_expr' when this temporary is allocated. */
+ /* The alias set for the slot. If the alias set is zero, we don't
+ know anything about the alias set of the slot. We must only
+ reuse a slot if it is assigned an object of the same alias set.
+ Otherwise, the rest of the compiler may assume that the new use
+ of the slot cannot alias the old use of the slot, which is
+ false. If the slot has alias set zero, then we can't reuse the
+ slot at all, since we have no idea what alias set may have been
+ imposed on the memory. For example, if the stack slot is the
+ call frame for an inline functioned, we have no idea what alias
+ sets will be assigned to various pieces of the call frame. */
+ int alias_set;
+ /* The value of `sequence_rtl_expr' when this temporary is allocated. */
tree rtl_expr;
/* Non-zero if this temporary is currently in use. */
char in_use;
@@ -192,19 +207,30 @@ struct var_refs_queue
struct var_refs_queue *next;
};
+struct insns_for_mem_entry {
+ /* The KEY in HE will be a MEM. */
+ struct hash_entry he;
+ /* These are the INSNS which reference the MEM. */
+ rtx insns;
+};
+
/* Forward declarations. */
static rtx assign_outer_stack_local PROTO ((enum machine_mode, HOST_WIDE_INT,
int, struct function *));
+static rtx assign_stack_temp_for_type PROTO ((enum machine_mode, HOST_WIDE_INT,
+ int, tree));
static struct temp_slot *find_temp_slot_from_address PROTO((rtx));
static void put_reg_into_stack PROTO((struct function *, rtx, tree,
enum machine_mode, enum machine_mode,
- int, int, int));
-static void fixup_var_refs PROTO((rtx, enum machine_mode, int));
+ int, int, int,
+ struct hash_table *));
+static void fixup_var_refs PROTO((rtx, enum machine_mode, int,
+ struct hash_table *));
static struct fixup_replacement
*find_fixup_replacement PROTO((struct fixup_replacement **, rtx));
static void fixup_var_refs_insns PROTO((rtx, enum machine_mode, int,
- rtx, int));
+ rtx, int, struct hash_table *));
static void fixup_var_refs_1 PROTO((rtx, enum machine_mode, rtx *, rtx,
struct fixup_replacement **));
static rtx fixup_memory_subreg PROTO((rtx, rtx, int));
@@ -231,8 +257,17 @@ static int all_blocks PROTO((tree, tree *));
static int *record_insns PROTO((rtx));
static int contains PROTO((rtx, int *));
#endif /* HAVE_prologue || HAVE_epilogue */
-static void put_addressof_into_stack PROTO((rtx));
-static void purge_addressof_1 PROTO((rtx *, rtx, int, int));
+static void put_addressof_into_stack PROTO((rtx, struct hash_table *));
+static void purge_addressof_1 PROTO((rtx *, rtx, int, int,
+ struct hash_table *));
+static struct hash_entry *insns_for_mem_newfunc PROTO((struct hash_entry *,
+ struct hash_table *,
+ hash_table_key));
+static unsigned long insns_for_mem_hash PROTO ((hash_table_key));
+static boolean insns_for_mem_comp PROTO ((hash_table_key, hash_table_key));
+static int insns_for_mem_walk PROTO ((rtx *, void *));
+static void compute_insns_for_mem PROTO ((rtx, rtx, struct hash_table *));
+
/* Global list of all compiled functions. */
struct function *all_functions = 0;
@@ -273,6 +308,8 @@ push_function_context_to (context)
save_tree_status (f, context);
if (save_lang_status)
(*save_lang_status) (f);
+ if (save_machine_status)
+ (*save_machine_status) (p);
}
void
@@ -296,7 +333,6 @@ pop_function_context_from (context)
outer_function_chain = f->next;
restore_tree_status (f, context);
- restore_emit_status (f);
if (restore_machine_status)
(*restore_machine_status) (f);
@@ -314,7 +350,8 @@ pop_function_context_from (context)
for (queue = f->saved_fixup_var_refs_queue; queue; queue = next)
{
next = queue->next;
- fixup_var_refs (queue->modified, queue->promoted_mode, queue->unsignedp);
+ fixup_var_refs (queue->modified, queue->promoted_mode,
+ queue->unsignedp, 0);
free (queue);
}
f->saved_fixup_var_refs_queue = 0;
@@ -345,9 +382,9 @@ free_after_compilation (f)
/* Allocate fixed slots in the stack frame of the current function. */
-/* Return size needed for stack frame based on slots so far allocated in
- function F. This size counts from zero. It is not rounded to
- STACK_BOUNDARY; the caller may have to do that. */
+/* Return size needed for stack frame based on slots so far allocated.
+ This size counts from zero. It is not rounded to PREFERRED_STACK_BOUNDARY;
+ the caller may have to do that. */
HOST_WIDE_INT
get_func_frame_size (f)
@@ -390,9 +427,19 @@ assign_stack_local (mode, size, align)
if (align == 0)
{
- alignment = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
+ tree type;
+
+ alignment = GET_MODE_ALIGNMENT (mode);
if (mode == BLKmode)
- alignment = BIGGEST_ALIGNMENT / BITS_PER_UNIT;
+ alignment = BIGGEST_ALIGNMENT;
+
+ /* Allow the target to (possibly) increase the alignment of this
+ stack slot. */
+ type = type_for_mode (mode, 0);
+ if (type)
+ alignment = LOCAL_ALIGNMENT (type, alignment);
+
+ alignment /= BITS_PER_UNIT;
}
else if (align == -1)
{
@@ -460,9 +507,19 @@ assign_outer_stack_local (mode, size, align, f)
if (align == 0)
{
- alignment = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
+ tree type;
+
+ alignment = GET_MODE_ALIGNMENT (mode);
if (mode == BLKmode)
- alignment = BIGGEST_ALIGNMENT / BITS_PER_UNIT;
+ alignment = BIGGEST_ALIGNMENT;
+
+ /* Allow the target to (possibly) increase the alignment of this
+ stack slot. */
+ type = type_for_mode (mode, 0);
+ if (type)
+ alignment = LOCAL_ALIGNMENT (type, alignment);
+
+ alignment /= BITS_PER_UNIT;
}
else if (align == -1)
{
@@ -514,14 +571,19 @@ assign_outer_stack_local (mode, size, align, f)
with this flag. KEEP is 2 if we allocate a longer term temporary,
whose lifetime is controlled by CLEANUP_POINT_EXPRs. KEEP is 3
if we are to allocate something at an inner level to be treated as
- a variable in the block (e.g., a SAVE_EXPR). */
+ a variable in the block (e.g., a SAVE_EXPR).
-rtx
-assign_stack_temp (mode, size, keep)
+ TYPE is the type that will be used for the stack slot. */
+
+static rtx
+assign_stack_temp_for_type (mode, size, keep, type)
enum machine_mode mode;
HOST_WIDE_INT size;
int keep;
+ tree type;
{
+ int align;
+ int alias_set;
struct temp_slot *p, *best_p = 0;
/* If SIZE is -1 it means that somebody tried to allocate a temporary
@@ -529,19 +591,41 @@ assign_stack_temp (mode, size, keep)
if (size == -1)
abort ();
- /* First try to find an available, already-allocated temporary that is the
- exact size we require. */
+ /* If we know the alias set for the memory that will be used, use
+ it. If there's no TYPE, then we don't know anything about the
+ alias set for the memory. */
+ if (type)
+ alias_set = get_alias_set (type);
+ else
+ alias_set = 0;
+
+ align = GET_MODE_ALIGNMENT (mode);
+ if (mode == BLKmode)
+ align = BIGGEST_ALIGNMENT;
+
+ if (! type)
+ type = type_for_mode (mode, 0);
+ if (type)
+ align = LOCAL_ALIGNMENT (type, align);
+
+ /* Try to find an available, already-allocated temporary of the proper
+ mode which meets the size and alignment requirements. Choose the
+ smallest one with the closest alignment. */
for (p = temp_slots; p; p = p->next)
- if (p->size == size && GET_MODE (p->slot) == mode && ! p->in_use)
- break;
-
- /* If we didn't find, one, try one that is larger than what we want. We
- find the smallest such. */
- if (p == 0)
- for (p = temp_slots; p; p = p->next)
- if (p->size > size && GET_MODE (p->slot) == mode && ! p->in_use
- && (best_p == 0 || best_p->size > p->size))
+ if (p->align >= align && p->size >= size && GET_MODE (p->slot) == mode
+ && ! p->in_use
+ && (!flag_strict_aliasing
+ || (alias_set && p->alias_set == alias_set))
+ && (best_p == 0 || best_p->size > p->size
+ || (best_p->size == p->size && best_p->align > p->align)))
+ {
+ if (p->align == align && p->size == size)
+ {
+ best_p = 0;
+ break;
+ }
best_p = p;
+ }
/* Make our best, if any, the one to use. */
if (best_p)
@@ -549,9 +633,13 @@ assign_stack_temp (mode, size, keep)
/* If there are enough aligned bytes left over, make them into a new
temp_slot so that the extra bytes don't get wasted. Do this only
for BLKmode slots, so that we can be sure of the alignment. */
- if (GET_MODE (best_p->slot) == BLKmode)
+ if (GET_MODE (best_p->slot) == BLKmode
+ /* We can't split slots if -fstrict-aliasing because the
+ information about the alias set for the new slot will be
+ lost. */
+ && !flag_strict_aliasing)
{
- int alignment = BIGGEST_ALIGNMENT / BITS_PER_UNIT;
+ int alignment = best_p->align / BITS_PER_UNIT;
HOST_WIDE_INT rounded_size = CEIL_ROUND (size, alignment);
if (best_p->size - rounded_size >= alignment)
@@ -564,6 +652,7 @@ assign_stack_temp (mode, size, keep)
p->slot = gen_rtx_MEM (BLKmode,
plus_constant (XEXP (best_p->slot, 0),
rounded_size));
+ p->align = best_p->align;
p->address = 0;
p->rtl_expr = 0;
p->next = temp_slots;
@@ -587,9 +676,22 @@ assign_stack_temp (mode, size, keep)
p = (struct temp_slot *) oballoc (sizeof (struct temp_slot));
- /* If the temp slot mode doesn't indicate the alignment,
- use the largest possible, so no one will be disappointed. */
- p->slot = assign_stack_local (mode, size, mode == BLKmode ? -1 : 0);
+ /* We are passing an explicit alignment request to assign_stack_local.
+ One side effect of that is assign_stack_local will not round SIZE
+ to ensure the frame offset remains suitably aligned.
+
+ So for requests which depended on the rounding of SIZE, we go ahead
+ and round it now. We also make sure ALIGNMENT is at least
+ BIGGEST_ALIGNMENT. */
+ if (mode == BLKmode && align < (BIGGEST_ALIGNMENT / BITS_PER_UNIT))
+ abort();
+ p->slot = assign_stack_local (mode,
+ mode == BLKmode
+ ? CEIL_ROUND (size, align) : size,
+ align);
+
+ p->align = align;
+ p->alias_set = alias_set;
/* The following slot size computation is necessary because we don't
know the actual size of the temporary slot until assign_stack_local
@@ -641,8 +743,22 @@ assign_stack_temp (mode, size, keep)
set from before. */
RTX_UNCHANGING_P (p->slot) = 0;
MEM_IN_STRUCT_P (p->slot) = 0;
+ MEM_SCALAR_P (p->slot) = 0;
+ MEM_ALIAS_SET (p->slot) = 0;
return p->slot;
}
+
+/* Allocate a temporary stack slot and record it for possible later
+ reuse. First three arguments are same as in preceding function. */
+
+rtx
+assign_stack_temp (mode, size, keep)
+ enum machine_mode mode;
+ HOST_WIDE_INT size;
+ int keep;
+{
+ return assign_stack_temp_for_type (mode, size, keep, NULL_TREE);
+}
/* Assign a temporary of given TYPE.
KEEP is as for assign_stack_temp.
@@ -675,8 +791,8 @@ assign_temp (type, keep, memory_required, dont_promote)
&& TREE_CODE (TYPE_ARRAY_MAX_SIZE (type)) == INTEGER_CST)
size = TREE_INT_CST_LOW (TYPE_ARRAY_MAX_SIZE (type));
- tmp = assign_stack_temp (mode, size, keep);
- MEM_IN_STRUCT_P (tmp) = AGGREGATE_TYPE_P (type);
+ tmp = assign_stack_temp_for_type (mode, size, keep, type);
+ MEM_SET_IN_STRUCT_P (tmp, AGGREGATE_TYPE_P (type));
return tmp;
}
@@ -701,6 +817,11 @@ combine_temp_slots ()
struct temp_slot *prev_p, *prev_q;
int num_slots;
+ /* We can't combine slots, because the information about which slot
+ is in which alias set will be lost. */
+ if (flag_strict_aliasing)
+ return;
+
/* If there are a lot of temp slots, don't do anything unless
high levels of optimizaton. */
if (! flag_expensive_optimizations)
@@ -1133,8 +1254,8 @@ put_var_into_stack (decl)
put_reg_into_stack (function, reg, TREE_TYPE (decl),
promoted_mode, decl_mode,
TREE_SIDE_EFFECTS (decl), 0,
- TREE_USED (decl)
- || DECL_INITIAL (decl) != 0);
+ TREE_USED (decl) || DECL_INITIAL (decl) != 0,
+ 0);
}
else if (GET_CODE (reg) == CONCAT)
{
@@ -1146,17 +1267,21 @@ put_var_into_stack (decl)
/* Since part 0 should have a lower address, do it second. */
put_reg_into_stack (function, XEXP (reg, 1), part_type, part_mode,
part_mode, TREE_SIDE_EFFECTS (decl), 0,
- TREE_USED (decl) || DECL_INITIAL (decl) != 0);
+ TREE_USED (decl) || DECL_INITIAL (decl) != 0,
+ 0);
put_reg_into_stack (function, XEXP (reg, 0), part_type, part_mode,
part_mode, TREE_SIDE_EFFECTS (decl), 0,
- TREE_USED (decl) || DECL_INITIAL (decl) != 0);
+ TREE_USED (decl) || DECL_INITIAL (decl) != 0,
+ 0);
#else
put_reg_into_stack (function, XEXP (reg, 0), part_type, part_mode,
part_mode, TREE_SIDE_EFFECTS (decl), 0,
- TREE_USED (decl) || DECL_INITIAL (decl) != 0);
+ TREE_USED (decl) || DECL_INITIAL (decl) != 0,
+ 0);
put_reg_into_stack (function, XEXP (reg, 1), part_type, part_mode,
part_mode, TREE_SIDE_EFFECTS (decl), 0,
- TREE_USED (decl) || DECL_INITIAL (decl) != 0);
+ TREE_USED (decl) || DECL_INITIAL (decl) != 0,
+ 0);
#endif
/* Change the CONCAT into a combined MEM for both parts. */
@@ -1174,7 +1299,7 @@ put_var_into_stack (decl)
else
return;
- if (flag_check_memory_usage)
+ if (current_function_check_memory_usage)
emit_library_call (chkr_set_right_libfunc, 1, VOIDmode, 3,
XEXP (reg, 0), ptr_mode,
GEN_INT (GET_MODE_SIZE (GET_MODE (reg))),
@@ -1192,7 +1317,7 @@ put_var_into_stack (decl)
static void
put_reg_into_stack (function, reg, type, promoted_mode, decl_mode, volatile_p,
- original_regno, used_p)
+ original_regno, used_p, ht)
struct function *function;
rtx reg;
tree type;
@@ -1200,6 +1325,7 @@ put_reg_into_stack (function, reg, type, promoted_mode, decl_mode, volatile_p,
int volatile_p;
int original_regno;
int used_p;
+ struct hash_table *ht;
{
rtx new = 0;
int regno = original_regno;
@@ -1234,7 +1360,8 @@ put_reg_into_stack (function, reg, type, promoted_mode, decl_mode, volatile_p,
previously generated stack slot, then we need to copy the bit in
case it was set for other reasons. For instance, it is set for
__builtin_va_alist. */
- MEM_IN_STRUCT_P (reg) = AGGREGATE_TYPE_P (type) | MEM_IN_STRUCT_P (new);
+ MEM_SET_IN_STRUCT_P (reg,
+ AGGREGATE_TYPE_P (type) || MEM_IN_STRUCT_P (new));
MEM_ALIAS_SET (reg) = get_alias_set (type);
/* Now make sure that all refs to the variable, previously made
@@ -1253,14 +1380,15 @@ put_reg_into_stack (function, reg, type, promoted_mode, decl_mode, volatile_p,
}
else if (used_p)
/* Variable is local; fix it up now. */
- fixup_var_refs (reg, promoted_mode, TREE_UNSIGNED (type));
+ fixup_var_refs (reg, promoted_mode, TREE_UNSIGNED (type), ht);
}
static void
-fixup_var_refs (var, promoted_mode, unsignedp)
+fixup_var_refs (var, promoted_mode, unsignedp, ht)
rtx var;
enum machine_mode promoted_mode;
int unsignedp;
+ struct hash_table *ht;
{
tree pending;
rtx first = get_insns ();
@@ -1268,14 +1396,18 @@ fixup_var_refs (var, promoted_mode, unsignedp)
tree rtl_exps = rtl_expr_chain;
/* Must scan all insns for stack-refs that exceed the limit. */
- fixup_var_refs_insns (var, promoted_mode, unsignedp, first, stack == 0);
+ fixup_var_refs_insns (var, promoted_mode, unsignedp, first_insn,
+ stack == 0, ht);
+ /* If there's a hash table, it must record all uses of VAR. */
+ if (ht)
+ return;
/* Scan all pending sequences too. */
for (; stack; stack = stack->next)
{
push_to_sequence (stack->first);
fixup_var_refs_insns (var, promoted_mode, unsignedp,
- stack->first, stack->next != 0);
+ stack->first, stack->next != 0, 0);
/* Update remembered end of sequence
in case we added an insn at the end. */
stack->last = get_last_insn ();
@@ -1289,10 +1421,17 @@ fixup_var_refs (var, promoted_mode, unsignedp)
if (seq != const0_rtx && seq != 0)
{
push_to_sequence (seq);
- fixup_var_refs_insns (var, promoted_mode, unsignedp, seq, 0);
+ fixup_var_refs_insns (var, promoted_mode, unsignedp, seq, 0,
+ 0);
end_sequence ();
}
}
+
+ /* Scan the catch clauses for exception handling too. */
+ push_to_sequence (catch_clauses);
+ fixup_var_refs_insns (var, promoted_mode, unsignedp, catch_clauses,
+ 0, 0);
+ end_sequence ();
}
/* REPLACEMENTS is a pointer to a list of the struct fixup_replacement and X is
@@ -1327,14 +1466,26 @@ find_fixup_replacement (replacements, x)
main chain of insns for the current function. */
static void
-fixup_var_refs_insns (var, promoted_mode, unsignedp, insn, toplevel)
+fixup_var_refs_insns (var, promoted_mode, unsignedp, insn, toplevel, ht)
rtx var;
enum machine_mode promoted_mode;
int unsignedp;
rtx insn;
int toplevel;
+ struct hash_table *ht;
{
rtx call_dest = 0;
+ rtx insn_list;
+
+ /* If we already know which INSNs reference VAR there's no need
+ to walk the entire instruction chain. */
+ if (ht)
+ {
+ insn_list = ((struct insns_for_mem_entry *)
+ hash_lookup (ht, var, /*create=*/0, /*copy=*/0))->insns;
+ insn = insn_list ? XEXP (insn_list, 0) : NULL_RTX;
+ insn_list = XEXP (insn_list, 1);
+ }
while (insn)
{
@@ -1507,7 +1658,16 @@ fixup_var_refs_insns (var, promoted_mode, unsignedp, insn, toplevel)
XEXP (note, 0)
= walk_fixup_memory_subreg (XEXP (note, 0), insn, 1);
}
- insn = next;
+
+ if (!ht)
+ insn = next;
+ else if (insn_list)
+ {
+ insn = XEXP (insn_list, 0);
+ insn_list = XEXP (insn_list, 1);
+ }
+ else
+ insn = NULL_RTX;
}
}
@@ -1545,18 +1705,45 @@ fixup_var_refs_1 (var, promoted_mode, loc, insn, replacements)
/* Prevent sharing of rtl that might lose. */
rtx sub = copy_rtx (XEXP (var, 0));
- start_sequence ();
-
if (! validate_change (insn, loc, sub, 0))
{
- rtx y = force_operand (sub, NULL_RTX);
+ rtx y = gen_reg_rtx (GET_MODE (sub));
+ rtx seq, new_insn;
- if (! validate_change (insn, loc, y, 0))
- *loc = copy_to_reg (y);
- }
+ /* We should be able to replace with a register or all is lost.
+ Note that we can't use validate_change to verify this, since
+ we're not caring for replacing all dups simultaneously. */
+ if (! validate_replace_rtx (*loc, y, insn))
+ abort ();
- emit_insn_before (gen_sequence (), insn);
- end_sequence ();
+ /* Careful! First try to recognize a direct move of the
+ value, mimicking how things are done in gen_reload wrt
+ PLUS. Consider what happens when insn is a conditional
+ move instruction and addsi3 clobbers flags. */
+
+ start_sequence ();
+ new_insn = emit_insn (gen_rtx_SET (VOIDmode, y, sub));
+ seq = gen_sequence ();
+ end_sequence ();
+
+ if (recog_memoized (new_insn) < 0)
+ {
+ /* That failed. Fall back on force_operand and hope. */
+
+ start_sequence ();
+ force_operand (sub, y);
+ seq = gen_sequence ();
+ end_sequence ();
+ }
+
+#ifdef HAVE_cc0
+ /* Don't separate setter from user. */
+ if (PREV_INSN (insn) && sets_cc0_p (PREV_INSN (insn)))
+ insn = PREV_INSN (insn);
+#endif
+
+ emit_insn_before (seq, insn);
+ }
}
return;
@@ -1690,8 +1877,7 @@ fixup_var_refs_1 (var, promoted_mode, loc, insn, replacements)
newmem = gen_rtx_MEM (wanted_mode,
plus_constant (XEXP (tem, 0), offset));
RTX_UNCHANGING_P (newmem) = RTX_UNCHANGING_P (tem);
- MEM_VOLATILE_P (newmem) = MEM_VOLATILE_P (tem);
- MEM_IN_STRUCT_P (newmem) = MEM_IN_STRUCT_P (tem);
+ MEM_COPY_ATTRIBUTES (newmem, tem);
/* Make the change and see if the insn remains valid. */
INSN_CODE (insn) = -1;
@@ -1882,8 +2068,7 @@ fixup_var_refs_1 (var, promoted_mode, loc, insn, replacements)
newmem = gen_rtx_MEM (wanted_mode,
plus_constant (XEXP (tem, 0), offset));
RTX_UNCHANGING_P (newmem) = RTX_UNCHANGING_P (tem);
- MEM_VOLATILE_P (newmem) = MEM_VOLATILE_P (tem);
- MEM_IN_STRUCT_P (newmem) = MEM_IN_STRUCT_P (tem);
+ MEM_COPY_ATTRIBUTES (newmem, tem);
/* Make the change and see if the insn remains valid. */
INSN_CODE (insn) = -1;
@@ -2334,7 +2519,9 @@ optimize_bit_field (body, insn, equiv_mem)
while (GET_CODE (dest) == SUBREG
&& SUBREG_WORD (dest) == 0
&& (GET_MODE_CLASS (GET_MODE (dest))
- == GET_MODE_CLASS (GET_MODE (SUBREG_REG (dest)))))
+ == GET_MODE_CLASS (GET_MODE (SUBREG_REG (dest))))
+ && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (dest)))
+ <= UNITS_PER_WORD))
dest = SUBREG_REG (dest);
validate_change (insn, &SET_DEST (body), dest, 1);
@@ -2448,11 +2635,11 @@ gen_mem_addressof (reg, decl)
PUT_CODE (reg, MEM);
PUT_MODE (reg, DECL_MODE (decl));
MEM_VOLATILE_P (reg) = TREE_SIDE_EFFECTS (decl);
- MEM_IN_STRUCT_P (reg) = AGGREGATE_TYPE_P (type);
+ MEM_SET_IN_STRUCT_P (reg, AGGREGATE_TYPE_P (type));
MEM_ALIAS_SET (reg) = get_alias_set (decl);
if (TREE_USED (decl) || DECL_INITIAL (decl) != 0)
- fixup_var_refs (reg, GET_MODE (reg), TREE_UNSIGNED (type));
+ fixup_var_refs (reg, GET_MODE (reg), TREE_UNSIGNED (type), 0);
return reg;
}
@@ -2468,14 +2655,15 @@ flush_addressof (decl)
&& GET_CODE (DECL_RTL (decl)) == MEM
&& GET_CODE (XEXP (DECL_RTL (decl), 0)) == ADDRESSOF
&& GET_CODE (XEXP (XEXP (DECL_RTL (decl), 0), 0)) == REG)
- put_addressof_into_stack (XEXP (DECL_RTL (decl), 0));
+ put_addressof_into_stack (XEXP (DECL_RTL (decl), 0), 0);
}
/* Force the register pointed to by R, an ADDRESSOF rtx, into the stack. */
static void
-put_addressof_into_stack (r)
+put_addressof_into_stack (r, ht)
rtx r;
+ struct hash_table *ht;
{
tree decl = ADDRESSOF_DECL (r);
rtx reg = XEXP (r, 0);
@@ -2486,18 +2674,23 @@ put_addressof_into_stack (r)
put_reg_into_stack (0, reg, TREE_TYPE (decl), GET_MODE (reg),
DECL_MODE (decl), TREE_SIDE_EFFECTS (decl),
ADDRESSOF_REGNO (r),
- TREE_USED (decl) || DECL_INITIAL (decl) != 0);
+ TREE_USED (decl) || DECL_INITIAL (decl) != 0, ht);
}
+/* List of replacements made below in purge_addressof_1 when creating
+ bitfield insertions. */
+static rtx purge_addressof_replacements;
+
/* Helper function for purge_addressof. See if the rtx expression at *LOC
in INSN needs to be changed. If FORCE, always put any ADDRESSOFs into
the stack. */
static void
-purge_addressof_1 (loc, insn, force, store)
+purge_addressof_1 (loc, insn, force, store, ht)
rtx *loc;
rtx insn;
int force, store;
+ struct hash_table *ht;
{
rtx x;
RTX_CODE code;
@@ -2520,115 +2713,214 @@ purge_addressof_1 (loc, insn, force, store)
overwriting a REG rtx which is always shared. */
rtx sub = copy_rtx (XEXP (XEXP (x, 0), 0));
- if (validate_change (insn, loc, sub, 0))
+ if (validate_change (insn, loc, sub, 0)
+ || validate_replace_rtx (x, sub, insn))
return;
-
+
start_sequence ();
- if (! validate_change (insn, loc,
- force_operand (sub, NULL_RTX),
- 0))
+ sub = force_operand (sub, NULL_RTX);
+ if (! validate_change (insn, loc, sub, 0)
+ && ! validate_replace_rtx (x, sub, insn))
abort ();
insns = gen_sequence ();
end_sequence ();
- emit_insns_before (insns, insn);
+ emit_insn_before (insns, insn);
return;
}
else if (code == MEM && GET_CODE (XEXP (x, 0)) == ADDRESSOF && ! force)
{
rtx sub = XEXP (XEXP (x, 0), 0);
+ rtx sub2;
if (GET_CODE (sub) == MEM)
- sub = gen_rtx_MEM (GET_MODE (x), copy_rtx (XEXP (sub, 0)));
+ {
+ sub2 = gen_rtx_MEM (GET_MODE (x), copy_rtx (XEXP (sub, 0)));
+ MEM_COPY_ATTRIBUTES (sub2, sub);
+ RTX_UNCHANGING_P (sub2) = RTX_UNCHANGING_P (sub);
+ sub = sub2;
+ }
if (GET_CODE (sub) == REG
&& (MEM_VOLATILE_P (x) || GET_MODE (x) == BLKmode))
{
- put_addressof_into_stack (XEXP (x, 0));
+ put_addressof_into_stack (XEXP (x, 0), ht);
return;
}
else if (GET_CODE (sub) == REG && GET_MODE (x) != GET_MODE (sub))
{
int size_x, size_sub;
+ if (!insn)
+ {
+ /* When processing REG_NOTES look at the list of
+ replacements done on the insn to find the register that X
+ was replaced by. */
+ rtx tem;
+
+ for (tem = purge_addressof_replacements; tem != NULL_RTX;
+ tem = XEXP (XEXP (tem, 1), 1))
+ {
+ rtx y = XEXP (tem, 0);
+ if (GET_CODE (y) == MEM
+ && rtx_equal_p (XEXP (x, 0), XEXP (y, 0)))
+ {
+ /* It can happen that the note may speak of things in
+ a wider (or just different) mode than the code did.
+ This is especially true of REG_RETVAL. */
+
+ rtx z = XEXP (XEXP (tem, 1), 0);
+ if (GET_MODE (x) != GET_MODE (y))
+ {
+ if (GET_CODE (z) == SUBREG && SUBREG_WORD (z) == 0)
+ z = SUBREG_REG (z);
+
+ /* ??? If we'd gotten into any of the really complex
+ cases below, I'm not sure we can do a proper
+ replacement. Might we be able to delete the
+ note in some cases? */
+ if (GET_MODE_SIZE (GET_MODE (x))
+ < GET_MODE_SIZE (GET_MODE (y)))
+ abort ();
+
+ if (GET_MODE_SIZE (GET_MODE (x)) > UNITS_PER_WORD
+ && (GET_MODE_SIZE (GET_MODE (x))
+ > GET_MODE_SIZE (GET_MODE (z))))
+ {
+ /* This can occur as a result in invalid
+ pointer casts, e.g. float f; ...
+ *(long long int *)&f.
+ ??? We could emit a warning here, but
+ without a line number that wouldn't be
+ very helpful. */
+ z = gen_rtx_SUBREG (GET_MODE (x), z, 0);
+ }
+ else
+ z = gen_lowpart (GET_MODE (x), z);
+ }
+
+ *loc = z;
+ return;
+ }
+ }
+
+ /* There should always be such a replacement. */
+ abort ();
+ }
+
size_x = GET_MODE_BITSIZE (GET_MODE (x));
size_sub = GET_MODE_BITSIZE (GET_MODE (sub));
/* Don't even consider working with paradoxical subregs,
or the moral equivalent seen here. */
- if (size_x < size_sub)
+ if (size_x <= size_sub
+ && int_mode_for_mode (GET_MODE (sub)) != BLKmode)
{
/* Do a bitfield insertion to mirror what would happen
in memory. */
rtx val, seq;
- /* We cannot do this if we are trying to pick out
- an integral piece, smaller than a word, of a
- floating point value. */
- if (INTEGRAL_MODE_P (GET_MODE (x))
- && GET_MODE_SIZE (GET_MODE (x)) < UNITS_PER_WORD
- && FLOAT_MODE_P (GET_MODE (sub)))
- {
- put_addressof_into_stack (XEXP (x, 0));
- return;
- }
-
if (store)
{
- /* If we can't replace with a register, be afraid. */
+ rtx p = PREV_INSN (insn);
start_sequence ();
val = gen_reg_rtx (GET_MODE (x));
if (! validate_change (insn, loc, val, 0))
- abort ();
+ {
+ /* Discard the current sequence and put the
+ ADDRESSOF on stack. */
+ end_sequence ();
+ goto give_up;
+ }
seq = gen_sequence ();
end_sequence ();
emit_insn_before (seq, insn);
+ compute_insns_for_mem (p ? NEXT_INSN (p) : get_insns (),
+ insn, ht);
start_sequence ();
store_bit_field (sub, size_x, 0, GET_MODE (x),
val, GET_MODE_SIZE (GET_MODE (sub)),
GET_MODE_SIZE (GET_MODE (sub)));
+ /* Make sure to unshare any shared rtl that store_bit_field
+ might have created. */
+ for (p = get_insns(); p; p = NEXT_INSN (p))
+ {
+ reset_used_flags (PATTERN (p));
+ reset_used_flags (REG_NOTES (p));
+ reset_used_flags (LOG_LINKS (p));
+ }
+ unshare_all_rtl (get_insns ());
+
seq = gen_sequence ();
end_sequence ();
- emit_insn_after (seq, insn);
+ p = emit_insn_after (seq, insn);
+ if (NEXT_INSN (insn))
+ compute_insns_for_mem (NEXT_INSN (insn),
+ p ? NEXT_INSN (p) : NULL_RTX,
+ ht);
}
else
{
+ rtx p = PREV_INSN (insn);
+
start_sequence ();
val = extract_bit_field (sub, size_x, 0, 1, NULL_RTX,
GET_MODE (x), GET_MODE (x),
GET_MODE_SIZE (GET_MODE (sub)),
GET_MODE_SIZE (GET_MODE (sub)));
- /* If we can't replace with a register, be afraid. */
if (! validate_change (insn, loc, val, 0))
- abort ();
+ {
+ /* Discard the current sequence and put the
+ ADDRESSOF on stack. */
+ end_sequence ();
+ goto give_up;
+ }
seq = gen_sequence ();
end_sequence ();
emit_insn_before (seq, insn);
+ compute_insns_for_mem (p ? NEXT_INSN (p) : get_insns (),
+ insn, ht);
}
+ /* Remember the replacement so that the same one can be done
+ on the REG_NOTES. */
+ purge_addressof_replacements
+ = gen_rtx_EXPR_LIST (VOIDmode, x,
+ gen_rtx_EXPR_LIST (VOIDmode, val,
+ purge_addressof_replacements));
+
/* We replaced with a reg -- all done. */
return;
}
}
else if (validate_change (insn, loc, sub, 0))
- goto restart;
+ {
+ /* Remember the replacement so that the same one can be done
+ on the REG_NOTES. */
+ purge_addressof_replacements
+ = gen_rtx_EXPR_LIST (VOIDmode, x,
+ gen_rtx_EXPR_LIST (VOIDmode, sub,
+ purge_addressof_replacements));
+ goto restart;
+ }
+ give_up:;
/* else give up and put it into the stack */
}
else if (code == ADDRESSOF)
{
- put_addressof_into_stack (x);
+ put_addressof_into_stack (x, ht);
return;
}
else if (code == SET)
{
- purge_addressof_1 (&SET_DEST (x), insn, force, 1);
- purge_addressof_1 (&SET_SRC (x), insn, force, 0);
+ purge_addressof_1 (&SET_DEST (x), insn, force, 1, ht);
+ purge_addressof_1 (&SET_SRC (x), insn, force, 0, ht);
return;
}
@@ -2637,13 +2929,130 @@ purge_addressof_1 (loc, insn, force, store)
for (i = 0; i < GET_RTX_LENGTH (code); i++, fmt++)
{
if (*fmt == 'e')
- purge_addressof_1 (&XEXP (x, i), insn, force, 0);
+ purge_addressof_1 (&XEXP (x, i), insn, force, 0, ht);
else if (*fmt == 'E')
for (j = 0; j < XVECLEN (x, i); j++)
- purge_addressof_1 (&XVECEXP (x, i, j), insn, force, 0);
+ purge_addressof_1 (&XVECEXP (x, i, j), insn, force, 0, ht);
}
}
+/* Return a new hash table entry in HT. */
+
+static struct hash_entry *
+insns_for_mem_newfunc (he, ht, k)
+ struct hash_entry *he;
+ struct hash_table *ht;
+ hash_table_key k ATTRIBUTE_UNUSED;
+{
+ struct insns_for_mem_entry *ifmhe;
+ if (he)
+ return he;
+
+ ifmhe = ((struct insns_for_mem_entry *)
+ hash_allocate (ht, sizeof (struct insns_for_mem_entry)));
+ ifmhe->insns = NULL_RTX;
+
+ return &ifmhe->he;
+}
+
+/* Return a hash value for K, a REG. */
+
+static unsigned long
+insns_for_mem_hash (k)
+ hash_table_key k;
+{
+ /* K is really a RTX. Just use the address as the hash value. */
+ return (unsigned long) k;
+}
+
+/* Return non-zero if K1 and K2 (two REGs) are the same. */
+
+static boolean
+insns_for_mem_comp (k1, k2)
+ hash_table_key k1;
+ hash_table_key k2;
+{
+ return k1 == k2;
+}
+
+struct insns_for_mem_walk_info {
+ /* The hash table that we are using to record which INSNs use which
+ MEMs. */
+ struct hash_table *ht;
+
+ /* The INSN we are currently proessing. */
+ rtx insn;
+
+ /* Zero if we are walking to find ADDRESSOFs, one if we are walking
+ to find the insns that use the REGs in the ADDRESSOFs. */
+ int pass;
+};
+
+/* Called from compute_insns_for_mem via for_each_rtx. If R is a REG
+ that might be used in an ADDRESSOF expression, record this INSN in
+ the hash table given by DATA (which is really a pointer to an
+ insns_for_mem_walk_info structure). */
+
+static int
+insns_for_mem_walk (r, data)
+ rtx *r;
+ void *data;
+{
+ struct insns_for_mem_walk_info *ifmwi
+ = (struct insns_for_mem_walk_info *) data;
+
+ if (ifmwi->pass == 0 && *r && GET_CODE (*r) == ADDRESSOF
+ && GET_CODE (XEXP (*r, 0)) == REG)
+ hash_lookup (ifmwi->ht, XEXP (*r, 0), /*create=*/1, /*copy=*/0);
+ else if (ifmwi->pass == 1 && *r && GET_CODE (*r) == REG)
+ {
+ /* Lookup this MEM in the hashtable, creating it if necessary. */
+ struct insns_for_mem_entry *ifme
+ = (struct insns_for_mem_entry *) hash_lookup (ifmwi->ht,
+ *r,
+ /*create=*/0,
+ /*copy=*/0);
+
+ /* If we have not already recorded this INSN, do so now. Since
+ we process the INSNs in order, we know that if we have
+ recorded it it must be at the front of the list. */
+ if (ifme && (!ifme->insns || XEXP (ifme->insns, 0) != ifmwi->insn))
+ {
+ /* We do the allocation on the same obstack as is used for
+ the hash table since this memory will not be used once
+ the hash table is deallocated. */
+ push_obstacks (&ifmwi->ht->memory, &ifmwi->ht->memory);
+ ifme->insns = gen_rtx_EXPR_LIST (VOIDmode, ifmwi->insn,
+ ifme->insns);
+ pop_obstacks ();
+ }
+ }
+
+ return 0;
+}
+
+/* Walk the INSNS, until we reach LAST_INSN, recording which INSNs use
+ which REGs in HT. */
+
+static void
+compute_insns_for_mem (insns, last_insn, ht)
+ rtx insns;
+ rtx last_insn;
+ struct hash_table *ht;
+{
+ rtx insn;
+ struct insns_for_mem_walk_info ifmwi;
+ ifmwi.ht = ht;
+
+ for (ifmwi.pass = 0; ifmwi.pass < 2; ++ifmwi.pass)
+ for (insn = insns; insn != last_insn; insn = NEXT_INSN (insn))
+ if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
+ {
+ ifmwi.insn = insn;
+ for_each_rtx (&insn, insns_for_mem_walk, &ifmwi);
+ }
+}
+
/* Eliminate all occurrences of ADDRESSOF from INSNS. Elide any remaining
(MEM (ADDRESSOF)) patterns, and force any needed registers into the
stack. */
@@ -2653,14 +3062,33 @@ purge_addressof (insns)
rtx insns;
{
rtx insn;
+ struct hash_table ht;
+
+ /* When we actually purge ADDRESSOFs, we turn REGs into MEMs. That
+ requires a fixup pass over the instruction stream to correct
+ INSNs that depended on the REG being a REG, and not a MEM. But,
+ these fixup passes are slow. Furthermore, more MEMs are not
+ mentioned in very many instructions. So, we speed up the process
+ by pre-calculating which REGs occur in which INSNs; that allows
+ us to perform the fixup passes much more quickly. */
+ hash_table_init (&ht,
+ insns_for_mem_newfunc,
+ insns_for_mem_hash,
+ insns_for_mem_comp);
+ compute_insns_for_mem (insns, NULL_RTX, &ht);
+
for (insn = insns; insn; insn = NEXT_INSN (insn))
if (GET_CODE (insn) == INSN || GET_CODE (insn) == JUMP_INSN
|| GET_CODE (insn) == CALL_INSN)
{
purge_addressof_1 (&PATTERN (insn), insn,
- asm_noperands (PATTERN (insn)) > 0, 0);
- purge_addressof_1 (&REG_NOTES (insn), NULL_RTX, 0, 0);
+ asm_noperands (PATTERN (insn)) > 0, 0, &ht);
+ purge_addressof_1 (&REG_NOTES (insn), NULL_RTX, 0, 0, &ht);
}
+
+ /* Clean up. */
+ hash_table_free (&ht);
+ purge_addressof_replacements = 0;
}
/* Pass through the INSNS of function FNDECL and convert virtual register
@@ -3290,30 +3718,24 @@ delete_handlers ()
TREE_CHAIN (last_t) = TREE_CHAIN (t);
}
}
- if (GET_CODE (insn) == INSN
- && ((nonlocal_goto_handler_slot != 0
- && reg_mentioned_p (nonlocal_goto_handler_slot, PATTERN (insn)))
+ if (GET_CODE (insn) == INSN)
+ {
+ int can_delete = 0;
+ rtx t;
+ for (t = nonlocal_goto_handler_slots; t != 0; t = XEXP (t, 1))
+ if (reg_mentioned_p (t, PATTERN (insn)))
+ {
+ can_delete = 1;
+ break;
+ }
+ if (can_delete
|| (nonlocal_goto_stack_level != 0
&& reg_mentioned_p (nonlocal_goto_stack_level,
- PATTERN (insn)))))
- delete_insn (insn);
+ PATTERN (insn))))
+ delete_insn (insn);
+ }
}
}
-
-/* Return a list (chain of EXPR_LIST nodes) for the nonlocal labels
- of the current function. */
-
-rtx
-nonlocal_label_rtx_list ()
-{
- tree t;
- rtx x = 0;
-
- for (t = nonlocal_labels; t; t = TREE_CHAIN (t))
- x = gen_rtx_EXPR_LIST (VOIDmode, label_rtx (TREE_VALUE (t)), x);
-
- return x;
-}
/* Output a USE for any register use in RTL.
This is used with -noreg to mark the extent of lifespan
@@ -3463,7 +3885,9 @@ assign_parms (fndecl, second_time)
/* This is a dummy PARM_DECL that we used for the function result if
the function returns a structure. */
tree function_result_decl = 0;
+#ifdef SETUP_INCOMING_VARARGS
int varargs_setup = 0;
+#endif
rtx conversion_insns = 0;
/* Nonzero if the last arg is named `__builtin_va_alist',
@@ -3542,6 +3966,7 @@ assign_parms (fndecl, second_time)
int did_conversion = 0;
tree passed_type = DECL_ARG_TYPE (parm);
tree nominal_type = TREE_TYPE (parm);
+ int pretend_named;
/* Set LAST_NAMED if this is last named arg before some
anonymous args. */
@@ -3663,19 +4088,19 @@ assign_parms (fndecl, second_time)
In this case, we call FUNCTION_ARG with NAMED set to 1 instead of
0 as it was the previous time. */
- locate_and_pad_parm (promoted_mode, passed_type,
+ pretend_named = named_arg || PRETEND_OUTGOING_VARARGS_NAMED;
+ locate_and_pad_parm (nominal_mode, passed_type,
#ifdef STACK_PARMS_IN_REG_PARM_AREA
1,
#else
#ifdef FUNCTION_INCOMING_ARG
FUNCTION_INCOMING_ARG (args_so_far, promoted_mode,
passed_type,
- (named_arg
- || varargs_setup)) != 0,
+ pretend_named) != 0,
#else
FUNCTION_ARG (args_so_far, promoted_mode,
passed_type,
- named_arg || varargs_setup) != 0,
+ pretend_named) != 0,
#endif
#endif
fndecl, &stack_args_size, &stack_offset, &arg_size);
@@ -3685,9 +4110,9 @@ assign_parms (fndecl, second_time)
rtx offset_rtx = ARGS_SIZE_RTX (stack_offset);
if (offset_rtx == const0_rtx)
- stack_parm = gen_rtx_MEM (promoted_mode, internal_arg_pointer);
+ stack_parm = gen_rtx_MEM (nominal_mode, internal_arg_pointer);
else
- stack_parm = gen_rtx_MEM (promoted_mode,
+ stack_parm = gen_rtx_MEM (nominal_mode,
gen_rtx_PLUS (Pmode,
internal_arg_pointer,
offset_rtx));
@@ -3695,7 +4120,7 @@ assign_parms (fndecl, second_time)
/* If this is a memory ref that contains aggregate components,
mark it as such for cse and loop optimize. Likewise if it
is readonly. */
- MEM_IN_STRUCT_P (stack_parm) = aggregate;
+ MEM_SET_IN_STRUCT_P (stack_parm, aggregate);
RTX_UNCHANGING_P (stack_parm) = TREE_READONLY (parm);
MEM_ALIAS_SET (stack_parm) = get_alias_set (parm);
}
@@ -3759,6 +4184,8 @@ assign_parms (fndecl, second_time)
to indicate there is no preallocated stack slot for the parm. */
if (entry_parm == stack_parm
+ || (GET_CODE (entry_parm) == PARALLEL
+ && XEXP (XVECEXP (entry_parm, 0, 0), 0) == NULL_RTX)
#if defined (REG_PARM_STACK_SPACE) && ! defined (MAYBE_REG_PARM_STACK_SPACE)
/* On some machines, even if a parm value arrives in a register
there is still an (uninitialized) stack slot allocated for it.
@@ -3835,7 +4262,7 @@ assign_parms (fndecl, second_time)
/* If this is a memory ref that contains aggregate components,
mark it as such for cse and loop optimize. */
- MEM_IN_STRUCT_P (stack_parm) = aggregate;
+ MEM_SET_IN_STRUCT_P (stack_parm, aggregate);
}
#endif /* 0 */
@@ -3892,7 +4319,7 @@ assign_parms (fndecl, second_time)
/* If this is a memory ref that contains aggregate
components, mark it as such for cse and loop optimize. */
- MEM_IN_STRUCT_P (stack_parm) = aggregate;
+ MEM_SET_IN_STRUCT_P (stack_parm, aggregate);
}
else if (PARM_BOUNDARY % BITS_PER_WORD != 0)
@@ -3949,7 +4376,7 @@ assign_parms (fndecl, second_time)
{
DECL_RTL (parm)
= gen_rtx_MEM (TYPE_MODE (TREE_TYPE (passed_type)), parmreg);
- MEM_IN_STRUCT_P (DECL_RTL (parm)) = aggregate;
+ MEM_SET_IN_STRUCT_P (DECL_RTL (parm), aggregate);
}
else
DECL_RTL (parm) = parmreg;
@@ -3958,6 +4385,7 @@ assign_parms (fndecl, second_time)
if (nominal_mode != passed_mode
|| promoted_nominal_mode != promoted_mode)
{
+ int save_tree_used;
/* ENTRY_PARM has been converted to PROMOTED_MODE, its
mode, by the caller. We now have to convert it to
NOMINAL_MODE, if different. However, PARMREG may be in
@@ -3984,8 +4412,11 @@ assign_parms (fndecl, second_time)
push_to_sequence (conversion_insns);
tempreg = convert_to_mode (nominal_mode, tempreg, unsignedp);
+ /* TREE_USED gets set erroneously during expand_assignment. */
+ save_tree_used = TREE_USED (parm);
expand_assignment (parm,
make_tree (nominal_type, tempreg), 0, 0);
+ TREE_USED (parm) = save_tree_used;
conversion_insns = get_insns ();
did_conversion = 1;
end_sequence ();
@@ -4050,12 +4481,12 @@ assign_parms (fndecl, second_time)
else
copy = assign_stack_temp (TYPE_MODE (type),
int_size_in_bytes (type), 1);
- MEM_IN_STRUCT_P (copy) = AGGREGATE_TYPE_P (type);
+ MEM_SET_IN_STRUCT_P (copy, AGGREGATE_TYPE_P (type));
RTX_UNCHANGING_P (copy) = TREE_READONLY (parm);
store_expr (parm, copy, 0);
emit_move_insn (parmreg, XEXP (copy, 0));
- if (flag_check_memory_usage)
+ if (current_function_check_memory_usage)
emit_library_call (chkr_set_right_libfunc, 1, VOIDmode, 3,
XEXP (copy, 0), ptr_mode,
GEN_INT (int_size_in_bytes (type)),
@@ -4204,7 +4635,7 @@ assign_parms (fndecl, second_time)
GET_MODE_SIZE (GET_MODE (entry_parm)), 0);
/* If this is a memory ref that contains aggregate components,
mark it as such for cse and loop optimize. */
- MEM_IN_STRUCT_P (stack_parm) = aggregate;
+ MEM_SET_IN_STRUCT_P (stack_parm, aggregate);
}
if (promoted_mode != nominal_mode)
@@ -4219,7 +4650,7 @@ assign_parms (fndecl, second_time)
emit_move_insn (validize_mem (stack_parm),
validize_mem (entry_parm));
}
- if (flag_check_memory_usage)
+ if (current_function_check_memory_usage)
{
push_to_sequence (conversion_insns);
emit_library_call (chkr_set_right_libfunc, 1, VOIDmode, 3,
@@ -4246,7 +4677,8 @@ assign_parms (fndecl, second_time)
DECL_RTL (result)
= gen_rtx_MEM (DECL_MODE (result), DECL_RTL (parm));
- MEM_IN_STRUCT_P (DECL_RTL (result)) = AGGREGATE_TYPE_P (restype);
+ MEM_SET_IN_STRUCT_P (DECL_RTL (result),
+ AGGREGATE_TYPE_P (restype));
}
if (TREE_THIS_VOLATILE (parm))
@@ -4273,8 +4705,8 @@ assign_parms (fndecl, second_time)
#endif
#endif
-#ifdef STACK_BOUNDARY
-#define STACK_BYTES (STACK_BOUNDARY / BITS_PER_UNIT)
+#ifdef PREFERRED_STACK_BOUNDARY
+#define STACK_BYTES (PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT)
current_function_args_size
= ((current_function_args_size + STACK_BYTES - 1)
@@ -4386,7 +4818,7 @@ locate_and_pad_parm (passed_mode, type, in_regs, fndecl,
enum machine_mode passed_mode;
tree type;
int in_regs;
- tree fndecl;
+ tree fndecl ATTRIBUTE_UNUSED;
struct args_size *initial_offset_ptr;
struct args_size *offset_ptr;
struct args_size *arg_size_ptr;
@@ -4580,6 +5012,14 @@ uninitialized_vars_warning (block)
&& ! AGGREGATE_TYPE_P (TREE_TYPE (decl))
&& DECL_RTL (decl) != 0
&& GET_CODE (DECL_RTL (decl)) == REG
+ /* Global optimizations can make it difficult to determine if a
+ particular variable has been initialized. However, a VAR_DECL
+ with a nonzero DECL_INITIAL had an initializer, so do not
+ claim it is potentially uninitialized.
+
+ We do not care about the actual value in DECL_INITIAL, so we do
+ not worry that it may be a dangling pointer. */
+ && DECL_INITIAL (decl) == NULL_TREE
&& regno_uninitialized (REGNO (DECL_RTL (decl))))
warning_with_decl (decl,
"`%s' might be used uninitialized in this function");
@@ -5054,11 +5494,12 @@ prepare_function_start ()
current_function_has_nonlocal_goto = 0;
/* There is no stack slot for handling nonlocal gotos. */
- nonlocal_goto_handler_slot = 0;
+ nonlocal_goto_handler_slots = 0;
nonlocal_goto_stack_level = 0;
/* No labels have been declared for nonlocal use. */
nonlocal_labels = 0;
+ nonlocal_goto_handler_labels = 0;
/* No function calls so far in this function. */
function_call_count = 0;
@@ -5095,6 +5536,8 @@ prepare_function_start ()
current_function_calls_alloca = 0;
current_function_contains_functions = 0;
+ current_function_sp_is_unchanging = 0;
+ current_function_has_computed_jump = 0;
current_function_is_thunk = 0;
current_function_returns_pcc_struct = 0;
@@ -5261,6 +5704,11 @@ expand_function_start (subr, parms_have_cleanups)
valid operands of arithmetic insns. */
init_recog_no_volatile ();
+ /* Set this before generating any memory accesses. */
+ current_function_check_memory_usage
+ = (flag_check_memory_usage
+ && ! DECL_NO_CHECK_MEMORY_USAGE (current_function_decl));
+
current_function_instrument_entry_exit
= (flag_instrument_function_entry_exit
&& ! DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (subr));
@@ -5333,8 +5781,10 @@ expand_function_start (subr, parms_have_cleanups)
{
DECL_RTL (DECL_RESULT (subr))
= gen_rtx_MEM (DECL_MODE (DECL_RESULT (subr)), value_address);
- MEM_IN_STRUCT_P (DECL_RTL (DECL_RESULT (subr)))
- = AGGREGATE_TYPE_P (TREE_TYPE (DECL_RESULT (subr)));
+ MEM_SET_IN_STRUCT_P (DECL_RTL (DECL_RESULT (subr)),
+ AGGREGATE_TYPE_P (TREE_TYPE
+ (DECL_RESULT
+ (subr))));
}
}
else if (DECL_MODE (DECL_RESULT (subr)) == VOIDmode)
@@ -5538,8 +5988,15 @@ expand_function_end (filename, line, end_bindings)
/* Save the argument pointer if a save area was made for it. */
if (arg_pointer_save_area)
{
- rtx x = gen_move_insn (arg_pointer_save_area, virtual_incoming_args_rtx);
- emit_insn_before (x, tail_recursion_reentry);
+ /* arg_pointer_save_area may not be a valid memory address, so we
+ have to check it and fix it if necessary. */
+ rtx seq;
+ start_sequence ();
+ emit_move_insn (validize_mem (arg_pointer_save_area),
+ virtual_incoming_args_rtx);
+ seq = gen_sequence ();
+ end_sequence ();
+ emit_insn_before (seq, tail_recursion_reentry);
}
/* Initialize any trampolines required by this function. */
@@ -5615,7 +6072,8 @@ expand_function_end (filename, line, end_bindings)
}
/* Delete handlers for nonlocal gotos if nothing uses them. */
- if (nonlocal_goto_handler_slot != 0 && !current_function_has_nonlocal_label)
+ if (nonlocal_goto_handler_slots != 0
+ && ! current_function_has_nonlocal_label)
delete_handlers ();
/* End any sequences that failed to be closed due to syntax errors. */
@@ -5883,100 +6341,172 @@ contains (insn, vec)
void
thread_prologue_and_epilogue_insns (f)
- rtx f;
+ rtx f ATTRIBUTE_UNUSED;
{
+ int insertted = 0;
+
+ prologue = 0;
#ifdef HAVE_prologue
if (HAVE_prologue)
{
- rtx head, seq;
-
- /* The first insn (a NOTE_INSN_DELETED) is followed by zero or more
- prologue insns and a NOTE_INSN_PROLOGUE_END. */
- emit_note_after (NOTE_INSN_PROLOGUE_END, f);
- seq = gen_prologue ();
- head = emit_insn_after (seq, f);
+ rtx seq;
- /* Include the new prologue insns in the first block. Ignore them
- if they form a basic block unto themselves. */
- if (basic_block_head && n_basic_blocks
- && GET_CODE (basic_block_head[0]) != CODE_LABEL)
- basic_block_head[0] = NEXT_INSN (f);
+ start_sequence ();
+ seq = gen_prologue();
+ emit_insn (seq);
/* Retain a map of the prologue insns. */
- prologue = record_insns (GET_CODE (seq) == SEQUENCE ? seq : head);
+ if (GET_CODE (seq) != SEQUENCE)
+ seq = get_insns ();
+ prologue = record_insns (seq);
+
+ emit_note (NULL, NOTE_INSN_PROLOGUE_END);
+ seq = gen_sequence ();
+ end_sequence ();
+
+ /* If optimization is off, and perhaps in an empty function,
+ the entry block will have no successors. */
+ if (ENTRY_BLOCK_PTR->succ)
+ {
+ /* Can't deal with multiple successsors of the entry block. */
+ if (ENTRY_BLOCK_PTR->succ->succ_next)
+ abort ();
+
+ insert_insn_on_edge (seq, ENTRY_BLOCK_PTR->succ);
+ insertted = 1;
+ }
+ else
+ emit_insn_after (seq, f);
}
- else
#endif
- prologue = 0;
+ epilogue = 0;
#ifdef HAVE_epilogue
if (HAVE_epilogue)
{
- rtx insn = get_last_insn ();
- rtx prev = prev_nonnote_insn (insn);
+ edge e;
+ basic_block bb = 0;
+ rtx tail = get_last_insn ();
+
+ /* ??? This is gastly. If function returns were not done via uses,
+ but via mark_regs_live_at_end, we could use insert_insn_on_edge
+ and all of this uglyness would go away. */
- /* If we end with a BARRIER, we don't need an epilogue. */
- if (! (prev && GET_CODE (prev) == BARRIER))
+ switch (optimize)
{
- rtx tail, seq, tem;
- rtx first_use = 0;
- rtx last_use = 0;
-
- /* The last basic block ends with a NOTE_INSN_EPILOGUE_BEG, the
- epilogue insns, the USE insns at the end of a function,
- the jump insn that returns, and then a BARRIER. */
-
- /* Move the USE insns at the end of a function onto a list. */
- while (prev
- && GET_CODE (prev) == INSN
- && GET_CODE (PATTERN (prev)) == USE)
- {
- tem = prev;
+ default:
+ /* If the exit block has no non-fake predecessors, we don't
+ need an epilogue. Furthermore, only pay attention to the
+ fallthru predecessors; if (conditional) return insns were
+ generated, by definition we do not need to emit epilogue
+ insns. */
+
+ for (e = EXIT_BLOCK_PTR->pred; e ; e = e->pred_next)
+ if ((e->flags & EDGE_FAKE) == 0
+ && (e->flags & EDGE_FALLTHRU) != 0)
+ break;
+ if (e == NULL)
+ break;
+
+ /* We can't handle multiple epilogues -- if one is needed,
+ we won't be able to place it multiple times.
+
+ ??? Fix epilogue expanders to not assume they are the
+ last thing done compiling the function. Either that
+ or copy_rtx each insn.
+
+ ??? Blah, it's not a simple expression to assert that
+ we've exactly one fallthru exit edge. */
+
+ bb = e->src;
+ tail = bb->end;
+
+ /* ??? If the last insn of the basic block is a jump, then we
+ are creating a new basic block. Wimp out and leave these
+ insns outside any block. */
+ if (GET_CODE (tail) == JUMP_INSN)
+ bb = 0;
+
+ /* FALLTHRU */
+ case 0:
+ {
+ rtx prev, seq, first_use;
+
+ /* Move the USE insns at the end of a function onto a list. */
+ prev = tail;
+ if (GET_CODE (prev) == BARRIER
+ || GET_CODE (prev) == NOTE)
prev = prev_nonnote_insn (prev);
- NEXT_INSN (PREV_INSN (tem)) = NEXT_INSN (tem);
- PREV_INSN (NEXT_INSN (tem)) = PREV_INSN (tem);
- if (first_use)
- {
- NEXT_INSN (tem) = first_use;
- PREV_INSN (first_use) = tem;
- }
- first_use = tem;
- if (!last_use)
- last_use = tem;
- }
+ first_use = 0;
+ if (prev
+ && GET_CODE (prev) == INSN
+ && GET_CODE (PATTERN (prev)) == USE)
+ {
+ /* If the end of the block is the use, grab hold of something
+ else so that we emit barriers etc in the right place. */
+ if (prev == tail)
+ {
+ do
+ tail = PREV_INSN (tail);
+ while (GET_CODE (tail) == INSN
+ && GET_CODE (PATTERN (tail)) == USE);
+ }
- emit_barrier_after (insn);
+ do
+ {
+ rtx use = prev;
+ prev = prev_nonnote_insn (prev);
+
+ remove_insn (use);
+ if (first_use)
+ {
+ NEXT_INSN (use) = first_use;
+ PREV_INSN (first_use) = use;
+ }
+ else
+ NEXT_INSN (use) = NULL_RTX;
+ first_use = use;
+ }
+ while (prev
+ && GET_CODE (prev) == INSN
+ && GET_CODE (PATTERN (prev)) == USE);
+ }
- seq = gen_epilogue ();
- tail = emit_jump_insn_after (seq, insn);
+ /* The last basic block ends with a NOTE_INSN_EPILOGUE_BEG, the
+ epilogue insns, the USE insns at the end of a function,
+ the jump insn that returns, and then a BARRIER. */
- /* Insert the USE insns immediately before the return insn, which
- must be the first instruction before the final barrier. */
- if (first_use)
- {
- tem = prev_nonnote_insn (get_last_insn ());
- NEXT_INSN (PREV_INSN (tem)) = first_use;
- PREV_INSN (first_use) = PREV_INSN (tem);
- PREV_INSN (tem) = last_use;
- NEXT_INSN (last_use) = tem;
- }
+ if (GET_CODE (tail) != BARRIER)
+ {
+ prev = next_nonnote_insn (tail);
+ if (!prev || GET_CODE (prev) != BARRIER)
+ emit_barrier_after (tail);
+ }
- emit_note_after (NOTE_INSN_EPILOGUE_BEG, insn);
+ seq = gen_epilogue ();
+ prev = tail;
+ tail = emit_jump_insn_after (seq, tail);
- /* Include the new epilogue insns in the last block. Ignore
- them if they form a basic block unto themselves. */
- if (basic_block_end && n_basic_blocks
- && GET_CODE (basic_block_end[n_basic_blocks - 1]) != JUMP_INSN)
- basic_block_end[n_basic_blocks - 1] = tail;
+ /* Insert the USE insns immediately before the return insn, which
+ must be the last instruction emitted in the sequence. */
+ if (first_use)
+ emit_insns_before (first_use, tail);
+ emit_note_after (NOTE_INSN_EPILOGUE_BEG, prev);
- /* Retain a map of the epilogue insns. */
- epilogue = record_insns (GET_CODE (seq) == SEQUENCE ? seq : tail);
- return;
+ /* Update the tail of the basic block. */
+ if (bb)
+ bb->end = tail;
+
+ /* Retain a map of the epilogue insns. */
+ epilogue = record_insns (GET_CODE (seq) == SEQUENCE ? seq : tail);
+ }
}
}
#endif
- epilogue = 0;
+
+ if (insertted)
+ commit_edge_insertions ();
}
/* Reposition the prologue-end and epilogue-begin notes after instruction
@@ -5984,13 +6514,12 @@ thread_prologue_and_epilogue_insns (f)
void
reposition_prologue_and_epilogue_notes (f)
- rtx f;
+ rtx f ATTRIBUTE_UNUSED;
{
#if defined (HAVE_prologue) || defined (HAVE_epilogue)
/* Reposition the prologue and epilogue notes. */
if (n_basic_blocks)
{
- rtx next, prev;
int len;
if (prologue)
@@ -6011,6 +6540,7 @@ reposition_prologue_and_epilogue_notes (f)
}
else if ((len -= contains (insn, prologue)) == 0)
{
+ rtx next;
/* Find the prologue-end note if we haven't already, and
move it to just after the last prologue insn. */
if (note == 0)
@@ -6022,17 +6552,13 @@ reposition_prologue_and_epilogue_notes (f)
}
next = NEXT_INSN (note);
- prev = PREV_INSN (note);
- if (prev)
- NEXT_INSN (prev) = next;
- if (next)
- PREV_INSN (next) = prev;
- /* Whether or not we can depend on basic_block_head,
+ /* Whether or not we can depend on BLOCK_HEAD,
attempt to keep it up-to-date. */
- if (basic_block_head[0] == note)
- basic_block_head[0] = next;
+ if (BLOCK_HEAD (0) == note)
+ BLOCK_HEAD (0) = next;
+ remove_insn (note);
add_insn_after (note, insn);
}
}
@@ -6065,19 +6591,14 @@ reposition_prologue_and_epilogue_notes (f)
&& NOTE_LINE_NUMBER (note) == NOTE_INSN_EPILOGUE_BEG)
break;
}
- next = NEXT_INSN (note);
- prev = PREV_INSN (note);
- if (prev)
- NEXT_INSN (prev) = next;
- if (next)
- PREV_INSN (next) = prev;
- /* Whether or not we can depend on basic_block_head,
+ /* Whether or not we can depend on BLOCK_HEAD,
attempt to keep it up-to-date. */
if (n_basic_blocks
- && basic_block_head[n_basic_blocks-1] == insn)
- basic_block_head[n_basic_blocks-1] = note;
+ && BLOCK_HEAD (n_basic_blocks-1) == insn)
+ BLOCK_HEAD (n_basic_blocks-1) = note;
+ remove_insn (note);
add_insn_before (note, insn);
}
}
diff --git a/gcc/function.h b/gcc/function.h
index c1af7eaf47e..58374ac9de2 100644
--- a/gcc/function.h
+++ b/gcc/function.h
@@ -197,6 +197,9 @@ struct function
/* Nonzero if function being compiled contains nested functions. */
int contains_functions;
+ /* Nonzero if the function being compiled issues a computed jump. */
+ int has_computed_jump;
+
/* Nonzero if the current function is a thunk (a lightweight function that
just adjusts one of its arguments and forwards to another function), so
we should try to cut corners where we can. */
@@ -207,8 +210,9 @@ struct function
May affect compilation of return insn or of function epilogue. */
int args_size;
- /* # bytes the prologue should push and pretend that the caller pushed them.
- The prologue must do this, but only if parms can be passed in registers. */
+ /* # bytes the prologue should push and pretend that the caller pushed
+ them. The prologue must do this, but only if parms can be passed in
+ registers. */
int pretend_args_size;
/* This is the offset from the arg pointer to the place where the first
@@ -226,7 +230,8 @@ struct function
/* The arg pointer hard register, or the pseudo into which it was copied. */
rtx internal_arg_pointer;
- /* Language-specific reason why the current function cannot be made inline. */
+ /* Language-specific reason why the current function cannot be made
+ inline. */
char *cannot_inline;
/* # of bytes of outgoing arguments. If ACCUMULATE_OUTGOING_ARGS is
@@ -319,7 +324,8 @@ struct function
/* List (chain of TREE_LISTs) of trampolines for nested functions.
The trampoline sets up the static chain and jumps to the function.
- We supply the trampoline's address when the function's address is requested.
+ We supply the trampoline's address when the function's address is
+ requested.
Each link has a FUNCTION_DECL in the TREE_PURPOSE and a reg rtx
in an RTL_EXPR in the TREE_VALUE. */
@@ -369,6 +375,11 @@ struct function
function. */
int has_nonlocal_goto;
+ rtx nonlocal_goto_handler_slots;
+ rtx nonlocal_goto_handler_labels;
+ rtx nonlocal_goto_stack_level;
+ tree nonlocal_labels;
+
struct stmt_status *stmt;
struct eh_status *eh;
struct emit_status *emit;
@@ -465,6 +476,7 @@ extern struct function *current_function;
#define nonlocal_labels (current_function->saved_nonlocal_labels)
#define nonlocal_goto_handler_slot (current_function->saved_nonlocal_goto_handler_slot)
#define nonlocal_goto_stack_level (current_function->saved_nonlocal_goto_stack_level)
+#define current_function_has_computed_jump (current_function->has_computed_jump)
/* The FUNCTION_DECL for an inline function currently being expanded. */
extern tree inline_function_decl;
diff --git a/gcc/gansidecl.h b/gcc/gansidecl.h
index f9326403774..cf7762fad6a 100644
--- a/gcc/gansidecl.h
+++ b/gcc/gansidecl.h
@@ -1,5 +1,5 @@
/* ANSI and traditional C compatibility macros.
- Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -22,34 +22,43 @@ Boston, MA 02111-1307, USA. */
in binutils and gdb releases.
??? Over time the two should be merged into one. */
-#ifndef ANSIDECL_H
-#define ANSIDECL_H
-
-/* Add prototype support. */
-#ifndef PROTO
-#if defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__)
-#define PROTO(ARGS) ARGS
-#else
-#define PROTO(ARGS) ()
-#endif
-#endif
-
-#ifndef VPROTO
-#ifdef __STDC__
-#define PVPROTO(ARGS) ARGS
-#define VPROTO(ARGS) ARGS
-#define VA_START(va_list,var) va_start(va_list,var)
-#else
-#define PVPROTO(ARGS) ()
-#define VPROTO(ARGS) (va_alist) va_dcl
-#define VA_START(va_list,var) va_start(va_list)
-#endif
-#endif
+#ifndef __GANSIDECL_H__
+#define __GANSIDECL_H__
+
+#include "ansidecl.h"
+
+/* Undef ansidecl.h's "obsolete" version. */
+#undef PROTO
+/* These macros are deprecated, use ansidecl.h's PARAMS style instead. */
+#define PROTO(ARGS) PARAMS(ARGS)
+#define VPROTO(ARGS) VPARAMS(ARGS)
+#define PVPROTO(ARGS) PARAMS(ARGS)
+
+/* Autoconf will possibly define the `inline' or `const' keywords as
+ macros, however this is only valid for the stage1 compiler. If we
+ detect a modern version of gcc, unconditionally reset the values.
+ This makes sure the right thing happens in stage2 and later. We
+ need to do this very early; i.e. before any systems header files or
+ gcc header files in case they use these keywords. Otherwise
+ conflicts might occur. */
+#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7)
+# undef const
+# undef inline
+# define inline __inline__ /* Modern gcc can use `__inline__' freely. */
+#endif /* GCC >= 2.7 */
#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7)
# define __attribute__(x)
#endif
+#ifndef ATTRIBUTE_UNUSED_LABEL
+# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 93)
+# define ATTRIBUTE_UNUSED_LABEL
+# else
+# define ATTRIBUTE_UNUSED_LABEL ATTRIBUTE_UNUSED
+# endif /* GNUC < 2.93 */
+#endif /* ATTRIBUTE_UNUSED_LABEL */
+
#ifndef ATTRIBUTE_UNUSED
#define ATTRIBUTE_UNUSED __attribute__ ((__unused__))
#endif /* ATTRIBUTE_UNUSED */
@@ -67,29 +76,10 @@ Boston, MA 02111-1307, USA. */
#define ATTRIBUTE_PRINTF_5 ATTRIBUTE_PRINTF(5, 6)
#endif /* ATTRIBUTE_PRINTF */
-#ifndef GENERIC_PTR
-#if defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__)
-#define GENERIC_PTR void *
-#else
-#define GENERIC_PTR char *
-#endif
-#endif
+#define GENERIC_PTR PTR
#ifndef NULL_PTR
-#define NULL_PTR ((GENERIC_PTR) 0)
+#define NULL_PTR ((PTR) 0)
#endif
-#ifdef __STDC__
-
-#define PTR void *
-
-#else
-
-#define PTR char *
-#ifndef const
-#define const
-#endif
-
-#endif /* ! __STDC__ */
-
-#endif /* ANSIDECL_H */
+#endif /* __GANSIDECL_H__ */
diff --git a/gcc/gcc.1 b/gcc/gcc.1
index b6a9d6211df..c5bba78a50d 100644
--- a/gcc/gcc.1
+++ b/gcc/gcc.1
@@ -20,7 +20,7 @@
.if n .sp
.if t .sp 0.4
..
-.Id $Id: gcc.1,v 1.8 1998/08/29 10:37:47 law Exp $
+.Id $Id: gcc.1,v 1.9 1998/12/16 20:55:57 law Exp $
.TH GCC 1 "\*(Dt" "GNU Tools" "GNU Tools"
.SH NAME
gcc, g++ \- GNU project C and C++ Compiler (egcs-1.1)
diff --git a/gcc/gcc.c b/gcc/gcc.c
index 64fa16db3e5..a56cf114505 100644
--- a/gcc/gcc.c
+++ b/gcc/gcc.c
@@ -1,5 +1,5 @@
/* Compiler driver program that can handle many languages.
- Copyright (C) 1987, 89, 92-97, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1987, 89, 92-98, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -34,55 +34,15 @@ compilation is specified by a string called a "spec". */
#include "config.h"
#include "system.h"
#include <signal.h>
-#include <sys/stat.h>
-#include "gansidecl.h"
#include "obstack.h"
-
-
-/* ??? Need to find a GCC header to put these in. */
-extern int pexecute PROTO ((const char *, char * const *, const char *,
- const char *, char **, char **, int));
-extern int pwait PROTO ((int, int *, int));
-extern char *update_path PROTO((char *, char *));
-extern void set_std_prefix PROTO((char *, int));
-/* Flag arguments to pexecute. */
-#define PEXECUTE_FIRST 1
-#define PEXECUTE_LAST 2
-#define PEXECUTE_SEARCH 4
-#define PEXECUTE_VERBOSE 8
-
-#ifndef WIFSIGNALED
-#define WIFSIGNALED(S) (((S) & 0xff) != 0 && ((S) & 0xff) != 0x7f)
-#endif
-#ifndef WTERMSIG
-#define WTERMSIG(S) ((S) & 0x7f)
-#endif
-#ifndef WIFEXITED
-#define WIFEXITED(S) (((S) & 0xff) == 0)
-#endif
-#ifndef WEXITSTATUS
-#define WEXITSTATUS(S) (((S) & 0xff00) >> 8)
-#endif
+#include "intl.h"
+#include "prefix.h"
#ifdef VMS
#define exit __posix_exit
#endif
-#ifdef USG
-#define vfork fork
-#endif /* USG */
-
-/* Test if something is a normal file. */
-#ifndef S_ISREG
-#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
-#endif
-
-/* Test if something is a directory. */
-#ifndef S_ISDIR
-#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
-#endif
-
/* By default there is no special suffix for executables. */
#ifdef EXECUTABLE_SUFFIX
#define HAVE_EXECUTABLE_SUFFIX
@@ -115,8 +75,6 @@ static char dir_separator_str[] = {DIR_SEPARATOR, 0};
#define GET_ENV_PATH_LIST(VAR,NAME) do { (VAR) = getenv (NAME); } while (0)
#endif
-extern char *my_strerror PROTO((int));
-
#ifndef HAVE_KILL
#define kill(p,s) raise(s)
#endif
@@ -134,11 +92,11 @@ static int print_search_dirs;
/* Flag saying to print the full filename of this file
as found through our usual search mechanism. */
-static char *print_file_name = NULL;
+static const char *print_file_name = NULL;
/* As print_file_name, but search for executable file. */
-static char *print_prog_name = NULL;
+static const char *print_prog_name = NULL;
/* Flag saying to print the relative path we'd use to
find libgcc.a given the current compiler flags. */
@@ -174,7 +132,7 @@ static char *spec_version = DEFAULT_TARGET_VERSION;
/* The target machine specified with -b. */
-static char *spec_machine = DEFAULT_TARGET_MACHINE;
+static const char *spec_machine = DEFAULT_TARGET_MACHINE;
/* Nonzero if cross-compiling.
When -b is used, the value comes from the `specs' file. */
@@ -206,56 +164,65 @@ extern char *version_string;
struct path_prefix;
static void init_spec PROTO((void));
-static void read_specs PROTO((char *, int));
-static void set_spec PROTO((char *, char *));
-static struct compiler *lookup_compiler PROTO((char *, size_t, char *));
-static char *build_search_list PROTO((struct path_prefix *, char *, int));
-static void putenv_from_prefixes PROTO((struct path_prefix *, char *));
-static char *find_a_file PROTO((struct path_prefix *, char *, int));
-static void add_prefix PROTO((struct path_prefix *, char *, char *,
- int, int, int *));
+static void read_specs PROTO((const char *, int));
+static void set_spec PROTO((const char *, const char *));
+static struct compiler *lookup_compiler PROTO((const char *, size_t, const char *));
+static char *build_search_list PROTO((struct path_prefix *, const char *, int));
+static void putenv_from_prefixes PROTO((struct path_prefix *, const char *));
+static char *find_a_file PROTO((struct path_prefix *, const char *, int));
+static void add_prefix PROTO((struct path_prefix *, const char *,
+ const char *, int, int, int *));
static char *skip_whitespace PROTO((char *));
-static void record_temp_file PROTO((char *, int, int));
-static void delete_if_ordinary PROTO((char *));
+static void record_temp_file PROTO((const char *, int, int));
+static void delete_if_ordinary PROTO((const char *));
static void delete_temp_files PROTO((void));
static void delete_failure_queue PROTO((void));
static void clear_failure_queue PROTO((void));
static int check_live_switch PROTO((int, int));
-static char *handle_braces PROTO((char *));
-static char *save_string PROTO((char *, int));
-static char *concat PVPROTO((char *, ...));
-extern int do_spec PROTO((char *));
-static int do_spec_1 PROTO((char *, int, char *));
-static char *find_file PROTO((char *));
-static int is_directory PROTO((char *, char *, int));
-static void validate_switches PROTO((char *));
+static const char *handle_braces PROTO((const char *));
+static char *save_string PROTO((const char *, int));
+extern int do_spec PROTO((const char *));
+static int do_spec_1 PROTO((const char *, int, const char *));
+static const char *find_file PROTO((const char *));
+static int is_directory PROTO((const char *, const char *, int));
+static void validate_switches PROTO((const char *));
static void validate_all_switches PROTO((void));
static void give_switch PROTO((int, int, int));
-static int used_arg PROTO((char *, int));
-static int default_arg PROTO((char *, int));
+static int used_arg PROTO((const char *, int));
+static int default_arg PROTO((const char *, int));
static void set_multilib_dir PROTO((void));
static void print_multilib_info PROTO((void));
-static void pfatal_with_name PROTO((char *));
-static void perror_with_name PROTO((char *));
-static void pfatal_pexecute PROTO((char *, char *));
-static void fatal PVPROTO((char *, ...));
-static void error PVPROTO((char *, ...));
+static void pfatal_with_name PROTO((const char *)) ATTRIBUTE_NORETURN;
+static void perror_with_name PROTO((const char *));
+static void pfatal_pexecute PROTO((const char *, const char *))
+ ATTRIBUTE_NORETURN;
+static void fatal PVPROTO((const char *, ...))
+ ATTRIBUTE_NORETURN ATTRIBUTE_PRINTF_1;
+static void error PVPROTO((const char *, ...))
+ ATTRIBUTE_PRINTF_1;
+static void notice PVPROTO((const char *, ...))
+ ATTRIBUTE_PRINTF_1;
static void display_help PROTO((void));
+static void add_preprocessor_option PROTO ((const char *, int));
+static void add_assembler_option PROTO ((const char *, int));
+static void add_linker_option PROTO ((const char *, int));
+static void process_command PROTO ((int, char **));
+static int execute PROTO ((void));
+static void unused_prefix_warnings PROTO ((struct path_prefix *));
+static void clear_args PROTO ((void));
+static void fatal_error PROTO ((int));
-void fancy_abort ();
-char *xmalloc ();
-char *xrealloc ();
+void fancy_abort PROTO((void)) ATTRIBUTE_NORETURN;
-#ifdef LANG_SPECIFIC_DRIVER
/* Called before processing to change/add/remove arguments. */
-extern void lang_specific_driver PROTO ((void (*) PVPROTO((char *, ...)), int *, char ***, int *));
+extern void lang_specific_driver PROTO ((void (*) PVPROTO((const char *, ...)),
+ int *, char ***, int *));
/* Called before linking. Returns 0 on success and -1 on failure. */
extern int lang_specific_pre_link ();
/* Number of extra output files that lang_specific_pre_link may generate. */
extern int lang_specific_extra_outfiles;
-#endif
/* Specs are strings containing lines, each of which (if not blank)
is made up of a program name, and arguments separated by spaces.
@@ -531,7 +498,7 @@ static char *multilib_defaults_raw[] = MULTILIB_DEFAULTS;
struct user_specs {
struct user_specs *next;
- char *filename;
+ const char *filename;
};
static struct user_specs *user_specs_head, *user_specs_tail;
@@ -579,10 +546,10 @@ static struct user_specs *user_specs_head, *user_specs_tail;
struct compiler
{
- char *suffix; /* Use this compiler for input files
+ const char *suffix; /* Use this compiler for input files
whose names end in this suffix. */
- char *spec[4]; /* To use this compiler, concatenate these
+ const char *spec[4]; /* To use this compiler, concatenate these
specs and pass to do_spec. */
};
@@ -609,8 +576,10 @@ static struct compiler default_compilers[] =
were not present when we built the driver, we will hit these copies
and be given a more meaningful error than "file not used since
linking is not done". */
- {".cc", {"#C++"}}, {".cxx", {"#C++"}}, {".cpp", {"#C++"}}, {".c++", {"#C++"}},
- {".C", {"#C++"}}, {".ads", {"#Ada"}}, {".adb", {"#Ada"}}, {".ada", {"#Ada"}},
+ {".m", {"#Objective-C"}},
+ {".cc", {"#C++"}}, {".cxx", {"#C++"}}, {".cpp", {"#C++"}},
+ {".c++", {"#C++"}}, {".C", {"#C++"}},
+ {".ads", {"#Ada"}}, {".adb", {"#Ada"}}, {".ada", {"#Ada"}},
{".f", {"#Fortran"}}, {".for", {"#Fortran"}}, {".F", {"#Fortran"}},
{".fpp", {"#Fortran"}},
{".p", {"#Pascal"}}, {".pas", {"#Pascal"}},
@@ -619,32 +588,36 @@ static struct compiler default_compilers[] =
{"@c",
{
#if USE_CPPLIB
- "%{E|M|MM:cpp -lang-c%{ansi:89} %{nostdinc*} %{C} %{v} %{A*} %{I*} %{P} %I\
+ "%{E|M|MM:cpp -lang-c %{ansi:-std=c89} %{std*} %{nostdinc*}\
+ %{C} %{v} %{A*} %{I*} %{P} %I\
%{C:%{!E:%eGNU C does not support -C without using -E}}\
%{M} %{MM} %{MD:-MD %b.d} %{MMD:-MMD %b.d} %{MG}\
-undef -D__GNUC__=%v1 -D__GNUC_MINOR__=%v2\
- %{ansi:-trigraphs -D__STRICT_ANSI__}\
- %{!undef:%{!ansi:%p} %P} %{trigraphs} \
+ %{ansi|std=*:%{!std=gnu*:-trigraphs -D__STRICT_ANSI__}}\
+ %{!undef:%{!ansi:%{!std=*:%p}%{std=gnu*:%p}} %P} %{trigraphs}\
%c %{Os:-D__OPTIMIZE_SIZE__} %{O*:%{!O0:-D__OPTIMIZE__}}\
+ %{ffast-math:-D__FAST_MATH__}\
%{traditional} %{ftraditional:-traditional}\
%{traditional-cpp:-traditional}\
+ %{fleading-underscore} %{fno-leading-underscore}\
%{g*} %{W*} %{w} %{pedantic*} %{H} %{d*} %C %{D*} %{U*} %{i*} %Z\
%i %{E:%W{o*}}%{M:%W{o*}}%{MM:%W{o*}}\n}\
%{!E:%{!M:%{!MM:cc1 %i %1 \
- -lang-c%{ansi:89} %{nostdinc*} %{A*} %{I*} %I\
+ %{std*} %{nostdinc*} %{A*} %{I*} %I\
%{!Q:-quiet} -dumpbase %b.c %{d*} %{m*} %{a*}\
%{MD:-MD %b.d} %{MMD:-MMD %b.d} %{MG}\
-undef -D__GNUC__=%v1 -D__GNUC_MINOR__=%v2\
- %{ansi:-trigraphs -D__STRICT_ANSI__}\
- %{!undef:%{!ansi:%p} %P} %{trigraphs} \
+ %{ansi|std=*:%{!std=gnu*:-trigraphs -D__STRICT_ANSI__}}\
+ %{!undef:%{!ansi:%{!std=*:%p}%{std=gnu*:%p}} %P} %{trigraphs}\
%c %{Os:-D__OPTIMIZE_SIZE__} %{O*:%{!O0:-D__OPTIMIZE__}}\
+ %{ffast-math:-D__FAST_MATH__}\
%{H} %C %{D*} %{U*} %{i*} %Z\
%{ftraditional:-traditional}\
%{traditional-cpp:-traditional}\
%{traditional} %{v:-version} %{pg:-p} %{p} %{f*}\
- %{aux-info*}\
- %{--help:--help} \
- %{g*} %{O*} %{W*} %{w} %{pedantic*} %{ansi} \
+ %{aux-info*} %{Qn:-fno-ident}\
+ %{--help:--help}\
+ %{g*} %{O*} %{W*} %{w} %{pedantic*}\
%{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\
%{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%g.s}} |\n\
%{!S:as %a %Y\
@@ -652,22 +625,25 @@ static struct compiler default_compilers[] =
%{!pipe:%g.s} %A\n }}}}"
}},
#else /* ! USE_CPPLIB */
- "cpp -lang-c%{ansi:89} %{nostdinc*} %{C} %{v} %{A*} %{I*} %{P} %I\
+ "cpp -lang-c %{ansi:-std=c89} %{std*} %{nostdinc*}\
+ %{C} %{v} %{A*} %{I*} %{P} %I\
%{C:%{!E:%eGNU C does not support -C without using -E}}\
%{M} %{MM} %{MD:-MD %b.d} %{MMD:-MMD %b.d} %{MG}\
-undef -D__GNUC__=%v1 -D__GNUC_MINOR__=%v2\
- %{ansi:-trigraphs -D__STRICT_ANSI__}\
- %{!undef:%{!ansi:%p} %P} %{trigraphs} \
+ %{ansi|std=*:%{!std=gnu*:-trigraphs -D__STRICT_ANSI__}}\
+ %{!undef:%{!ansi:%{!std=*:%p}%{std=gnu*:%p}} %P} %{trigraphs}\
%c %{Os:-D__OPTIMIZE_SIZE__} %{O*:%{!O0:-D__OPTIMIZE__}}\
+ %{ffast-math:-D__FAST_MATH__}\
%{traditional} %{ftraditional:-traditional}\
%{traditional-cpp:-traditional}\
+ %{fleading-underscore} %{fno-leading-underscore}\
%{g*} %{W*} %{w} %{pedantic*} %{H} %{d*} %C %{D*} %{U*} %{i*} %Z\
%i %{!M:%{!MM:%{!E:%{!pipe:%g.i}}}}%{E:%W{o*}}%{M:%W{o*}}%{MM:%W{o*}} |\n",
"%{!M:%{!MM:%{!E:cc1 %{!pipe:%g.i} %1 \
%{!Q:-quiet} -dumpbase %b.c %{d*} %{m*} %{a*}\
- %{g*} %{O*} %{W*} %{w} %{pedantic*} %{ansi} \
+ %{g*} %{O*} %{W*} %{w} %{pedantic*} %{std*}\
%{traditional} %{v:-version} %{pg:-p} %{p} %{f*}\
- %{aux-info*}\
+ %{aux-info*} %{Qn:-fno-ident}\
%{--help:--help} \
%{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\
%{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%g.s}} |\n\
@@ -677,42 +653,21 @@ static struct compiler default_compilers[] =
}},
#endif /* ! USE_CPPLIB */
{"-",
- {"%{E:cpp -lang-c%{ansi:89} %{nostdinc*} %{C} %{v} %{A*} %{I*} %{P} %I\
+ {"%{E:cpp -lang-c %{ansi:-std=c89} %{std*} %{nostdinc*}\
+ %{C} %{v} %{A*} %{I*} %{P} %I\
%{C:%{!E:%eGNU C does not support -C without using -E}}\
%{M} %{MM} %{MD:-MD %b.d} %{MMD:-MMD %b.d} %{MG}\
-undef -D__GNUC__=%v1 -D__GNUC_MINOR__=%v2\
- %{ansi:-trigraphs -D__STRICT_ANSI__}\
- %{!undef:%{!ansi:%p} %P} %{trigraphs}\
+ %{ansi|std=*:%{!std=gnu*:-trigraphs -D__STRICT_ANSI__}}\
+ %{!undef:%{!ansi:%{!std=*:%p}%{std=gnu*:%p}} %P} %{trigraphs}\
%c %{Os:-D__OPTIMIZE_SIZE__} %{O*:%{!O0:-D__OPTIMIZE__}}\
+ %{ffast-math:-D__FAST_MATH__}\
%{traditional} %{ftraditional:-traditional}\
%{traditional-cpp:-traditional}\
+ %{fleading-underscore} %{fno-leading-underscore}\
%{g*} %{W*} %{w} %{pedantic*} %{H} %{d*} %C %{D*} %{U*} %{i*} %Z\
%i %W{o*}}\
%{!E:%e-E required when input is from standard input}"}},
- {".m", {"@objective-c"}},
- {"@objective-c",
- {"cpp -lang-objc %{nostdinc*} %{C} %{v} %{A*} %{I*} %{P} %I\
- %{C:%{!E:%eGNU C does not support -C without using -E}}\
- %{M} %{MM} %{MD:-MD %b.d} %{MMD:-MMD %b.d} %{MG}\
- -undef -D__OBJC__ -D__GNUC__=%v1 -D__GNUC_MINOR__=%v2\
- %{ansi:-trigraphs -D__STRICT_ANSI__}\
- %{!undef:%{!ansi:%p} %P} %{trigraphs}\
- %c %{Os:-D__OPTIMIZE_SIZE__} %{O*:%{!O0:-D__OPTIMIZE__}}\
- %{traditional} %{ftraditional:-traditional}\
- %{traditional-cpp:-traditional}\
- %{g*} %{W*} %{w} %{pedantic*} %{H} %{d*} %C %{D*} %{U*} %{i*} %Z\
- %i %{!M:%{!MM:%{!E:%{!pipe:%g.i}}}}%{E:%W{o*}}%{M:%W{o*}}%{MM:%W{o*}} |\n",
- "%{!M:%{!MM:%{!E:cc1obj %{!pipe:%g.i} %1 \
- %{!Q:-quiet} -dumpbase %b.m %{d*} %{m*} %{a*}\
- %{g*} %{O*} %{W*} %{w} %{pedantic*} %{ansi} \
- %{traditional} %{v:-version} %{pg:-p} %{p} %{f*} \
- -lang-objc %{gen-decls} \
- %{aux-info*}\
- %{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\
- %{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%g.s}} |\n\
- %{!S:as %a %Y\
- %{c:%W{o*}%{!o*:-o %w%b%O}}%{!c:-o %d%w%u%O}\
- %{!pipe:%g.s} %A\n }}}}"}},
{".h", {"@c-header"}},
{"@c-header",
{"%{!E:%eCompilation of header file requested} \
@@ -720,19 +675,21 @@ static struct compiler default_compilers[] =
%{C:%{!E:%eGNU C does not support -C without using -E}}\
%{M} %{MM} %{MD:-MD %b.d} %{MMD:-MMD %b.d} %{MG}\
-undef -D__GNUC__=%v1 -D__GNUC_MINOR__=%v2\
- %{ansi:-trigraphs -D__STRICT_ANSI__}\
- %{!undef:%{!ansi:%p} %P} %{trigraphs}\
+ %{std=*:%{!std=gnu*:-trigraphs -D__STRICT_ANSI__}}\
+ %{!undef:%{!std=*:%p}%{std=gnu*:%p} %P} %{trigraphs}\
%c %{Os:-D__OPTIMIZE_SIZE__} %{O*:%{!O0:-D__OPTIMIZE__}}\
+ %{ffast-math:-D__FAST_MATH__}\
%{traditional} %{ftraditional:-traditional}\
%{traditional-cpp:-traditional}\
+ %{fleading-underscore} %{fno-leading-underscore}\
%{g*} %{W*} %{w} %{pedantic*} %{H} %{d*} %C %{D*} %{U*} %{i*} %Z\
%i %W{o*}"}},
{".i", {"@cpp-output"}},
{"@cpp-output",
{"%{!M:%{!MM:%{!E:cc1 %i %1 %{!Q:-quiet} %{d*} %{m*} %{a*}\
- %{g*} %{O*} %{W*} %{w} %{pedantic*} %{ansi}\
+ %{g*} %{O*} %{W*} %{w} %{pedantic*} %{std*}\
%{traditional} %{v:-version} %{pg:-p} %{p} %{f*}\
- %{aux-info*}\
+ %{aux-info*} %{Qn:-fno-ident}\
%{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\
%{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%g.s}} |\n\
%{!S:as %a %Y\
@@ -750,8 +707,10 @@ static struct compiler default_compilers[] =
%{M} %{MM} %{MD:-MD %b.d} %{MMD:-MMD %b.d} %{MG} %{trigraphs}\
-undef -$ %{!undef:%p %P} -D__ASSEMBLER__ \
%c %{Os:-D__OPTIMIZE_SIZE__} %{O*:%{!O0:-D__OPTIMIZE__}}\
+ %{ffast-math:-D__FAST_MATH__}\
%{traditional} %{ftraditional:-traditional}\
%{traditional-cpp:-traditional}\
+ %{fleading-underscore} %{fno-leading-underscore}\
%{g*} %{W*} %{w} %{pedantic*} %{H} %{d*} %C %{D*} %{U*} %{i*} %Z\
%i %{!M:%{!MM:%{!E:%{!pipe:%g.s}}}}%{E:%W{o*}}%{M:%W{o*}}%{MM:%W{o*}} |\n",
"%{!M:%{!MM:%{!E:%{!S:as %a %Y\
@@ -778,12 +737,12 @@ static int n_default_compilers
#ifdef LINK_COMMAND_SPEC
/* Provide option to override link_command_spec from machine specific
configuration files. */
-static char *link_command_spec =
+static const char *link_command_spec =
LINK_COMMAND_SPEC;
#else
#ifdef LINK_LIBGCC_SPECIAL
/* Don't generate -L options. */
-static char *link_command_spec = "\
+static const char *link_command_spec = "\
%{!fsyntax-only: \
%{!c:%{!M:%{!MM:%{!E:%{!S:%(linker) %l %X %{o*} %{A} %{d} %{e*} %{m} %{N} %{n} \
%{r} %{s} %{t} %{u*} %{x} %{z} %{Z}\
@@ -795,7 +754,7 @@ static char *link_command_spec = "\
\n }}}}}}";
#else
/* Use -L. */
-static char *link_command_spec = "\
+static const char *link_command_spec = "\
%{!fsyntax-only: \
%{!c:%{!M:%{!MM:%{!E:%{!S:%(linker) %l %X %{o*} %{A} %{d} %{e*} %{m} %{N} %{n} \
%{r} %{s} %{t} %{u*} %{x} %{z} %{Z}\
@@ -832,15 +791,15 @@ static char **preprocessor_options;
struct option_map
{
/* The long option's name. */
- char *name;
+ const char *name;
/* The equivalent short option. */
- char *equivalent;
+ const char *equivalent;
/* Argument info. A string of flag chars; NULL equals no options.
a => argument required.
o => argument optional.
j => join argument to equivalent, making one word.
* => require other text after NAME as an argument. */
- char *arg_info;
+ const char *arg_info;
};
/* This is the table of mappings. Mappings are tried sequentially
@@ -852,6 +811,8 @@ struct option_map option_map[] =
{"--ansi", "-ansi", 0},
{"--assemble", "-S", 0},
{"--assert", "-A", "a"},
+ {"--classpath", "-fclasspath=", "aj"},
+ {"--CLASSPATH", "-fCLASSPATH=", "aj"},
{"--comments", "-C", 0},
{"--compile", "-c", 0},
{"--debug", "-g", "oj"},
@@ -884,6 +845,7 @@ struct option_map option_map[] =
{"--no-warnings", "-w", 0},
{"--optimize", "-O", "oj"},
{"--output", "-o", "a"},
+ {"--output-class-directory", "-foutput-class-dir=", "ja"},
{"--pedantic", "-pedantic", 0},
{"--pedantic-errors", "-pedantic-errors", 0},
{"--pipe", "-pipe", 0},
@@ -904,6 +866,7 @@ struct option_map option_map[] =
{"--silent", "-q", 0},
{"--specs", "-specs=", "aj"},
{"--static", "-static", 0},
+ {"--std", "-std=", "aj"},
{"--symbolic", "-symbolic", 0},
{"--target", "-b", "a"},
{"--trace-includes", "-H", 0},
@@ -928,12 +891,13 @@ struct option_map option_map[] =
static void
translate_options (argcp, argvp)
int *argcp;
- char ***argvp;
+ const char ***argvp;
{
- int i, j, k;
+ int i;
int argc = *argcp;
- char **argv = *argvp;
- char **newv = (char **) xmalloc ((argc + 2) * 2 * sizeof (char *));
+ const char **argv = *argvp;
+ const char **newv =
+ (const char **) xmalloc ((argc + 2) * 2 * sizeof (const char *));
int newindex = 0;
i = 0;
@@ -944,23 +908,25 @@ translate_options (argcp, argvp)
/* Translate -- options. */
if (argv[i][0] == '-' && argv[i][1] == '-')
{
+ size_t j;
/* Find a mapping that applies to this option. */
for (j = 0; j < sizeof (option_map) / sizeof (option_map[0]); j++)
{
size_t optlen = strlen (option_map[j].name);
size_t arglen = strlen (argv[i]);
size_t complen = arglen > optlen ? optlen : arglen;
- char *arginfo = option_map[j].arg_info;
+ const char *arginfo = option_map[j].arg_info;
if (arginfo == 0)
arginfo = "";
if (!strncmp (argv[i], option_map[j].name, complen))
{
- char *arg = 0;
+ const char *arg = 0;
if (arglen < optlen)
{
+ size_t k;
for (k = j + 1;
k < sizeof (option_map) / sizeof (option_map[0]);
k++)
@@ -1045,7 +1011,7 @@ translate_options (argcp, argvp)
with their arguments. */
else if (argv[i][0] == '-')
{
- char *p = argv[i] + 1;
+ const char *p = argv[i] + 1;
int c = *p;
int nskip = 1;
@@ -1083,7 +1049,7 @@ translate_options (argcp, argvp)
}
char *
-my_strerror(e)
+xstrerror(e)
int e;
{
#ifdef HAVE_STRERROR
@@ -1092,15 +1058,13 @@ my_strerror(e)
#else
- static char buffer[30];
if (!e)
- return "cannot access";
+ return "errno = 0";
if (e > 0 && e < sys_nerr)
return sys_errlist[e];
- sprintf (buffer, "Unknown error %d", e);
- return buffer;
+ return "errno = ?";
#endif
}
@@ -1175,7 +1139,16 @@ static struct spec_list static_specs[] = {
};
#ifdef EXTRA_SPECS /* additional specs needed */
-static struct spec_list extra_specs[] = { EXTRA_SPECS };
+/* Structure to keep track of just the first two args of a spec_list.
+ That is all that the EXTRA_SPECS macro gives us. */
+struct spec_list_1
+{
+ char *name;
+ char *ptr;
+};
+
+static struct spec_list_1 extra_specs_1[] = { EXTRA_SPECS };
+static struct spec_list * extra_specs = (struct spec_list *)0;
#endif
/* List of dynamically allocates specs that have been defined so far. */
@@ -1196,12 +1169,20 @@ init_spec ()
return; /* already initialized */
if (verbose_flag)
- fprintf (stderr, "Using builtin specs.\n");
+ notice ("Using builtin specs.\n");
#ifdef EXTRA_SPECS
- for (i = (sizeof (extra_specs) / sizeof (extra_specs[0])) - 1; i >= 0; i--)
+ extra_specs = (struct spec_list *)
+ xmalloc (sizeof(struct spec_list) *
+ (sizeof(extra_specs_1)/sizeof(extra_specs_1[0])));
+ bzero ((PTR) extra_specs, sizeof(struct spec_list) *
+ (sizeof(extra_specs_1)/sizeof(extra_specs_1[0])));
+
+ for (i = (sizeof(extra_specs_1) / sizeof(extra_specs_1[0])) - 1; i >= 0; i--)
{
sl = &extra_specs[i];
+ sl->name = extra_specs_1[i].name;
+ sl->ptr = extra_specs_1[i].ptr;
sl->next = next;
sl->name_len = strlen (sl->name);
sl->ptr_spec = &sl->ptr;
@@ -1226,8 +1207,8 @@ init_spec ()
static void
set_spec (name, spec)
- char *name;
- char *spec;
+ const char *name;
+ const char *spec;
{
struct spec_list *sl;
char *old_spec;
@@ -1267,13 +1248,13 @@ set_spec (name, spec)
}
old_spec = *(sl->ptr_spec);
- *(sl->ptr_spec) = ((spec[0] == '+' && ISSPACE (spec[1]))
+ *(sl->ptr_spec) = ((spec[0] == '+' && ISSPACE ((unsigned char)spec[1]))
? concat (old_spec, spec + 1, NULL_PTR)
: save_string (spec, strlen (spec)));
#ifdef DEBUG_SPECS
if (verbose_flag)
- fprintf (stderr, "Setting spec %s to '%s'\n\n", name, *(sl->ptr_spec));
+ notice ("Setting spec %s to '%s'\n\n", name, *(sl->ptr_spec));
#endif
/* Free the old spec */
@@ -1302,21 +1283,19 @@ static int argbuf_index;
#ifdef MKTEMP_EACH_FILE
-extern char *make_temp_file PROTO((char *));
+extern char *make_temp_file PROTO((const char *));
/* This is the list of suffixes and codes (%g/%u/%U) and the associated
temp file. */
static struct temp_name {
- char *suffix; /* suffix associated with the code. */
+ const char *suffix; /* suffix associated with the code. */
int length; /* strlen (suffix). */
int unique; /* Indicates whether %g or %u/%U was used. */
- char *filename; /* associated filename. */
+ const char *filename; /* associated filename. */
int filename_length; /* strlen (filename). */
struct temp_name *next;
} *temp_names;
-#else
-extern char *choose_temp_base PROTO((void));
#endif
@@ -1330,7 +1309,7 @@ static int signal_count;
/* Name with which this program was invoked. */
-static char *programname;
+static const char *programname;
/* Structures to keep track of prefixes to try when looking for files. */
@@ -1347,7 +1326,7 @@ struct path_prefix
{
struct prefix_list *plist; /* List of prefixes to try */
int max_len; /* Max length of a prefix in PLIST */
- char *name; /* Name of this list (used in config stuff) */
+ const char *name; /* Name of this list (used in config stuff) */
};
/* List of prefixes to try when looking for executables. */
@@ -1365,16 +1344,16 @@ static struct path_prefix include_prefixes = { 0, 0, "include" };
/* Suffix to attach to directories searched for commands.
This looks like `MACHINE/VERSION/'. */
-static char *machine_suffix = 0;
+static const char *machine_suffix = 0;
/* Suffix to attach to directories searched for commands.
This is just `MACHINE/'. */
-static char *just_machine_suffix = 0;
+static const char *just_machine_suffix = 0;
/* Adjusted value of GCC_EXEC_PREFIX envvar. */
-static char *gcc_exec_prefix;
+static const char *gcc_exec_prefix;
/* Default prefixes to attach to command names. */
@@ -1388,10 +1367,10 @@ static char *gcc_exec_prefix;
#define STANDARD_EXEC_PREFIX "/usr/local/lib/gcc-lib/"
#endif /* !defined STANDARD_EXEC_PREFIX */
-static char *standard_exec_prefix = STANDARD_EXEC_PREFIX;
-static char *standard_exec_prefix_1 = "/usr/lib/gcc/";
+static const char *standard_exec_prefix = STANDARD_EXEC_PREFIX;
+static const char *standard_exec_prefix_1 = "/usr/lib/gcc/";
#ifdef MD_EXEC_PREFIX
-static char *md_exec_prefix = MD_EXEC_PREFIX;
+static const char *md_exec_prefix = MD_EXEC_PREFIX;
#endif
#ifndef STANDARD_STARTFILE_PREFIX
@@ -1399,25 +1378,25 @@ static char *md_exec_prefix = MD_EXEC_PREFIX;
#endif /* !defined STANDARD_STARTFILE_PREFIX */
#ifdef MD_STARTFILE_PREFIX
-static char *md_startfile_prefix = MD_STARTFILE_PREFIX;
+static const char *md_startfile_prefix = MD_STARTFILE_PREFIX;
#endif
#ifdef MD_STARTFILE_PREFIX_1
-static char *md_startfile_prefix_1 = MD_STARTFILE_PREFIX_1;
+static const char *md_startfile_prefix_1 = MD_STARTFILE_PREFIX_1;
#endif
-static char *standard_startfile_prefix = STANDARD_STARTFILE_PREFIX;
-static char *standard_startfile_prefix_1 = "/lib/";
-static char *standard_startfile_prefix_2 = "/usr/lib/";
+static const char *standard_startfile_prefix = STANDARD_STARTFILE_PREFIX;
+static const char *standard_startfile_prefix_1 = "/lib/";
+static const char *standard_startfile_prefix_2 = "/usr/lib/";
#ifndef TOOLDIR_BASE_PREFIX
#define TOOLDIR_BASE_PREFIX "/usr/local/"
#endif
-static char *tooldir_base_prefix = TOOLDIR_BASE_PREFIX;
-static char *tooldir_prefix;
+static const char *tooldir_base_prefix = TOOLDIR_BASE_PREFIX;
+static const char *tooldir_prefix;
/* Subdirectory to use for locating libraries. Set by
set_multilib_dir based on the compilation options. */
-static char *multilib_dir;
+static const char *multilib_dir;
/* Clear out the vector of arguments (after a command is executed). */
@@ -1463,7 +1442,7 @@ store_arg (arg, delete_always, delete_failure)
static void
read_specs (filename, main_p)
- char *filename;
+ const char *filename;
int main_p;
{
int desc;
@@ -1473,7 +1452,7 @@ read_specs (filename, main_p)
register char *p;
if (verbose_flag)
- fprintf (stderr, "Reading specs from %s\n", filename);
+ notice ("Reading specs from %s\n", filename);
/* Open and stat the file. */
desc = open (filename, O_RDONLY, 0);
@@ -1525,8 +1504,8 @@ read_specs (filename, main_p)
p1++;
if (*p1++ != '<' || p[-2] != '>')
- fatal ("specs %%include syntax malformed after %d characters",
- p1 - buffer + 1);
+ fatal ("specs %%include syntax malformed after %ld characters",
+ (long) (p1 - buffer + 1));
p[-2] = '\0';
new_filename = find_a_file (&startfile_prefixes, p1, R_OK);
@@ -1543,15 +1522,15 @@ read_specs (filename, main_p)
while (*p1 == ' ' || *p1 == '\t') p1++;
if (*p1++ != '<' || p[-2] != '>')
- fatal ("specs %%include syntax malformed after %d characters",
- p1 - buffer + 1);
+ fatal ("specs %%include syntax malformed after %ld characters",
+ (long) (p1 - buffer + 1));
p[-2] = '\0';
new_filename = find_a_file (&startfile_prefixes, p1, R_OK);
if (new_filename)
read_specs (new_filename, FALSE);
else if (verbose_flag)
- fprintf (stderr, "Could not find specs file %s\n", p1);
+ notice ("Could not find specs file %s\n", p1);
continue;
}
else if (!strncmp (p1, "%rename", sizeof "%rename" - 1)
@@ -1566,35 +1545,35 @@ read_specs (filename, main_p)
while (*p1 == ' ' || *p1 == '\t')
p1++;
- if (! ISALPHA (*p1))
- fatal ("specs %%rename syntax malformed after %d characters",
- p1 - buffer);
+ if (! ISALPHA ((unsigned char)*p1))
+ fatal ("specs %%rename syntax malformed after %ld characters",
+ (long) (p1 - buffer));
p2 = p1;
- while (*p2 && !ISSPACE (*p2))
+ while (*p2 && !ISSPACE ((unsigned char)*p2))
p2++;
if (*p2 != ' ' && *p2 != '\t')
- fatal ("specs %%rename syntax malformed after %d characters",
- p2 - buffer);
+ fatal ("specs %%rename syntax malformed after %ld characters",
+ (long) (p2 - buffer));
name_len = p2 - p1;
*p2++ = '\0';
while (*p2 == ' ' || *p2 == '\t')
p2++;
- if (! ISALPHA (*p2))
- fatal ("specs %%rename syntax malformed after %d characters",
- p2 - buffer);
+ if (! ISALPHA ((unsigned char)*p2))
+ fatal ("specs %%rename syntax malformed after %ld characters",
+ (long) (p2 - buffer));
/* Get new spec name */
p3 = p2;
- while (*p3 && !ISSPACE (*p3))
+ while (*p3 && !ISSPACE ((unsigned char)*p3))
p3++;
if (p3 != p-1)
- fatal ("specs %%rename syntax malformed after %d characters",
- p3 - buffer);
+ fatal ("specs %%rename syntax malformed after %ld characters",
+ (long) (p3 - buffer));
*p3 = '\0';
for (sl = specs; sl; sl = sl->next)
@@ -1609,9 +1588,9 @@ read_specs (filename, main_p)
if (verbose_flag)
{
- fprintf (stderr, "rename spec %s to %s\n", p1, p2);
+ notice ("rename spec %s to %s\n", p1, p2);
#ifdef DEBUG_SPECS
- fprintf (stderr, "spec is '%s'\n\n", *(sl->ptr_spec));
+ notice ("spec is '%s'\n\n", *(sl->ptr_spec));
#endif
}
@@ -1624,8 +1603,8 @@ read_specs (filename, main_p)
continue;
}
else
- fatal ("specs unknown %% command after %d characters",
- p1 - buffer);
+ fatal ("specs unknown %% command after %ld characters",
+ (long) (p1 - buffer));
}
/* Find the colon that should end the suffix. */
@@ -1635,7 +1614,8 @@ read_specs (filename, main_p)
/* The colon shouldn't be missing. */
if (*p1 != ':')
- fatal ("specs file malformed after %d characters", p1 - buffer);
+ fatal ("specs file malformed after %ld characters",
+ (long) (p1 - buffer));
/* Skip back over trailing whitespace. */
p2 = p1;
@@ -1647,7 +1627,8 @@ read_specs (filename, main_p)
/* Find the next line. */
p = skip_whitespace (p1 + 1);
if (p[1] == 0)
- fatal ("specs file malformed after %d characters", p - buffer);
+ fatal ("specs file malformed after %ld characters",
+ (long) (p - buffer));
p1 = p;
/* Find next blank line or end of string. */
@@ -1720,7 +1701,7 @@ read_specs (filename, main_p)
otherwise, in /usr/tmp or /tmp;
or finally the current directory if all else fails. */
-static char *temp_filename;
+static const char *temp_filename;
/* Length of the prefix. */
@@ -1730,7 +1711,7 @@ static int temp_filename_length;
struct temp_file
{
- char *name;
+ const char *name;
struct temp_file *next;
};
@@ -1747,7 +1728,7 @@ static struct temp_file *failure_delete_queue;
static void
record_temp_file (filename, always_delete, fail_delete)
- char *filename;
+ const char *filename;
int always_delete;
int fail_delete;
{
@@ -1790,7 +1771,7 @@ record_temp_file (filename, always_delete, fail_delete)
static void
delete_if_ordinary (name)
- char *name;
+ const char *name;
{
struct stat st;
#ifdef DEBUG
@@ -1902,7 +1883,7 @@ putenv (str)
static char *
build_search_list (paths, prefix, check_dir_p)
struct path_prefix *paths;
- char *prefix;
+ const char *prefix;
int check_dir_p;
{
int suffix_len = (machine_suffix) ? strlen (machine_suffix) : 0;
@@ -1963,7 +1944,7 @@ build_search_list (paths, prefix, check_dir_p)
static void
putenv_from_prefixes (paths, env_var)
struct path_prefix *paths;
- char *env_var;
+ const char *env_var;
{
putenv (build_search_list (paths, env_var, 1));
}
@@ -1975,11 +1956,11 @@ putenv_from_prefixes (paths, env_var)
static char *
find_a_file (pprefix, name, mode)
struct path_prefix *pprefix;
- char *name;
+ const char *name;
int mode;
{
char *temp;
- char *file_suffix = ((mode & X_OK) != 0 ? EXECUTABLE_SUFFIX : "");
+ const char *file_suffix = ((mode & X_OK) != 0 ? EXECUTABLE_SUFFIX : "");
struct prefix_list *pl;
int len = pprefix->max_len + strlen (name) + strlen (file_suffix) + 1;
@@ -2135,8 +2116,8 @@ find_a_file (pprefix, name, mode)
static void
add_prefix (pprefix, prefix, component, first, require_machine_suffix, warn)
struct path_prefix *pprefix;
- char *prefix;
- char *component;
+ const char *prefix;
+ const char *component;
int first;
int require_machine_suffix;
int *warn;
@@ -2215,8 +2196,8 @@ execute ()
char *string;
struct command
{
- char *prog; /* program name. */
- char **argv; /* vector of args. */
+ const char *prog; /* program name. */
+ char **argv; /* vector of args. */
int pid; /* pid of process for this command. */
};
@@ -2245,7 +2226,7 @@ execute ()
for (n_commands = 1, i = 0; i < argbuf_index; i++)
if (strcmp (argbuf[i], "|") == 0)
{ /* each command. */
-#if defined (__MSDOS__) || (defined (_WIN32) && defined (__CYGWIN32_)) || defined (OS2) || defined (VMS)
+#if defined (__MSDOS__) || defined (OS2) || defined (VMS)
fatal ("-pipe not supported");
#endif
argbuf[i] = 0; /* termination of command args. */
@@ -2282,7 +2263,7 @@ execute ()
}
fflush (stderr);
#ifdef DEBUG
- fprintf (stderr, "\nGo ahead? (y or n) ");
+ notice ("\nGo ahead? (y or n) ");
fflush (stderr);
i = getchar ();
if (i != '\n')
@@ -2370,15 +2351,15 @@ execute ()
is a null-terminated vector containing the following arguments.
The `live_cond' field is 1 if the switch is true in a conditional spec,
-1 if false (overridden by a later switch), and is initialized to zero.
- The `valid' field is nonzero if any spec has looked at this switch;
+ The `validated' field is nonzero if any spec has looked at this switch;
if it remains zero at the end of the run, it must be meaningless. */
struct switchstr
{
- char *part1;
+ const char *part1;
char **args;
int live_cond;
- int valid;
+ int validated;
};
static struct switchstr *switches;
@@ -2387,8 +2368,8 @@ static int n_switches;
struct infile
{
- char *name;
- char *language;
+ const char *name;
+ const char *language;
};
/* Also a vector of input files specified. */
@@ -2397,14 +2378,14 @@ static struct infile *infiles;
static int n_infiles;
-/* This counts the number of libraries added by LANG_SPECIFIC_DRIVER, so that
+/* This counts the number of libraries added by lang_specific_driver, so that
we can tell if there were any user supplied any files or libraries. */
static int added_libraries;
/* And a vector of corresponding output files is made up later. */
-static char **outfiles;
+static const char **outfiles;
/* Used to track if none of the -B paths are used. */
static int warn_B;
@@ -2427,7 +2408,12 @@ convert_filename (name, do_exe)
int do_exe;
{
int i;
- int len = strlen (name);
+ int len;
+
+ if (name == NULL)
+ return NULL;
+
+ len = strlen (name);
#ifdef HAVE_OBJECT_SUFFIX
/* Convert x.o to x.obj if OBJECT_SUFFIX is ".obj". */
@@ -2491,6 +2477,7 @@ display_help ()
printf (" -save-temps Do not delete intermediate files\n");
printf (" -pipe Use pipes rather than intermediate files\n");
printf (" -specs=<file> Override builtin specs with the contents of <file>\n");
+ printf (" -std=<standard> Assume that the input sources are for <standard>\n");
printf (" -B <directory> Add <directory> to the compiler's search paths\n");
printf (" -b <machine> Run gcc for target <machine>, if installed\n");
printf (" -V <version> Run gcc version number <version>, if installed\n");
@@ -2515,56 +2502,57 @@ display_help ()
static void
add_preprocessor_option (option, len)
- char * option;
- int len;
+ const char * option;
+ int len;
{
- n_preprocessor_options++;
+ n_preprocessor_options++;
- if (! preprocessor_options)
- preprocessor_options
- = (char **) xmalloc (n_preprocessor_options * sizeof (char **));
- else
- preprocessor_options
- = (char **) xrealloc (preprocessor_options,
- n_preprocessor_options * sizeof (char **));
+ if (! preprocessor_options)
+ preprocessor_options
+ = (char **) xmalloc (n_preprocessor_options * sizeof (char *));
+ else
+ preprocessor_options
+ = (char **) xrealloc (preprocessor_options,
+ n_preprocessor_options * sizeof (char *));
- preprocessor_options [n_preprocessor_options - 1] = save_string (option, len);
+ preprocessor_options [n_preprocessor_options - 1] =
+ save_string (option, len);
}
static void
add_assembler_option (option, len)
- char * option;
- int len;
-{
- n_assembler_options++;
-
- if (! assembler_options)
- assembler_options
- = (char **) xmalloc (n_assembler_options * sizeof (char **));
- else
- assembler_options
- = (char **) xrealloc (assembler_options,
- n_assembler_options * sizeof (char **));
-
- assembler_options [n_assembler_options - 1] = save_string (option, len);
+ const char * option;
+ int len;
+{
+ n_assembler_options++;
+
+ if (! assembler_options)
+ assembler_options
+ = (char **) xmalloc (n_assembler_options * sizeof (char *));
+ else
+ assembler_options
+ = (char **) xrealloc (assembler_options,
+ n_assembler_options * sizeof (char *));
+
+ assembler_options [n_assembler_options - 1] = save_string (option, len);
}
static void
add_linker_option (option, len)
- char * option;
- int len;
-{
- n_linker_options++;
-
- if (! linker_options)
- linker_options
- = (char **) xmalloc (n_linker_options * sizeof (char **));
- else
- linker_options
- = (char **) xrealloc (linker_options,
- n_linker_options * sizeof (char **));
-
- linker_options [n_linker_options - 1] = save_string (option, len);
+ const char * option;
+ int len;
+{
+ n_linker_options++;
+
+ if (! linker_options)
+ linker_options
+ = (char **) xmalloc (n_linker_options * sizeof (char *));
+ else
+ linker_options
+ = (char **) xrealloc (linker_options,
+ n_linker_options * sizeof (char *));
+
+ linker_options [n_linker_options - 1] = save_string (option, len);
}
/* Create the vector `switches' and its contents.
@@ -2576,7 +2564,8 @@ process_command (argc, argv)
char **argv;
{
register int i;
- char *temp;
+ const char *temp;
+ char *temp1;
char *spec_lang = 0;
int last_language_n_infiles;
int have_c = 0;
@@ -2591,12 +2580,13 @@ process_command (argc, argv)
/* Figure compiler version from version string. */
- compiler_version = save_string (version_string, strlen (version_string));
- for (temp = compiler_version; *temp; ++temp)
+ compiler_version = temp1 =
+ save_string (version_string, strlen (version_string));
+ for (; *temp1; ++temp1)
{
- if (*temp == ' ')
+ if (*temp1 == ' ')
{
- *temp = '\0';
+ *temp1 = '\0';
break;
}
}
@@ -2606,7 +2596,7 @@ process_command (argc, argv)
if (gcc_exec_prefix)
{
int len = strlen (gcc_exec_prefix);
- if (len > sizeof ("/lib/gcc-lib/")-1
+ if (len > (int) sizeof ("/lib/gcc-lib/")-1
&& (gcc_exec_prefix[len-1] == '/'
|| gcc_exec_prefix[len-1] == DIR_SEPARATOR))
{
@@ -2629,7 +2619,7 @@ process_command (argc, argv)
GET_ENV_PATH_LIST (temp, "COMPILER_PATH");
if (temp)
{
- char *startp, *endp;
+ const char *startp, *endp;
char *nstore = (char *) alloca (strlen (temp) + 3);
startp = endp = temp;
@@ -2663,7 +2653,7 @@ process_command (argc, argv)
GET_ENV_PATH_LIST (temp, "LIBRARY_PATH");
if (temp && *cross_compile == '0')
{
- char *startp, *endp;
+ const char *startp, *endp;
char *nstore = (char *) alloca (strlen (temp) + 3);
startp = endp = temp;
@@ -2696,7 +2686,7 @@ process_command (argc, argv)
GET_ENV_PATH_LIST (temp, "LPATH");
if (temp && *cross_compile == '0')
{
- char *startp, *endp;
+ const char *startp, *endp;
char *nstore = (char *) alloca (strlen (temp) + 3);
startp = endp = temp;
@@ -2728,10 +2718,8 @@ process_command (argc, argv)
/* Convert new-style -- options to old-style. */
translate_options (&argc, &argv);
-#ifdef LANG_SPECIFIC_DRIVER
/* Do language-specific adjustment/addition of flags. */
lang_specific_driver (fatal, &argc, &argv, &added_libraries);
-#endif
/* Scan argv twice. Here, the first time, just count how many switches
there will be in their vector, and how many input files in theirs.
@@ -2745,6 +2733,8 @@ process_command (argc, argv)
init_spec ();
for (sl = specs; sl; sl = sl->next)
printf ("*%s:\n%s\n\n", sl->name, *(sl->ptr_spec));
+ if (link_command_spec)
+ printf ("*link_command:\n%s\n\n", link_command_spec);
exit (0);
}
else if (! strcmp (argv[i], "-dumpversion"))
@@ -2962,7 +2952,7 @@ process_command (argc, argv)
The format of the version string is
([^0-9]*-)?[0-9]+[.][0-9]+([.][0-9]+)?([- ].*)? */
{
- char *v = compiler_version;
+ const char *v = compiler_version;
/* Ignore leading non-digits. i.e. "foo-" in "foo-2.7.2". */
while (! ISDIGIT (*v))
@@ -3164,7 +3154,7 @@ process_command (argc, argv)
switches[n_switches].part1 = "--help";
switches[n_switches].args = 0;
switches[n_switches].live_cond = 0;
- switches[n_switches].valid = 0;
+ switches[n_switches].validated = 0;
n_switches++;
}
@@ -3179,7 +3169,7 @@ process_command (argc, argv)
switches[n_switches].part1 = &argv[i][0];
switches[n_switches].args = 0;
switches[n_switches].live_cond = 0;
- switches[n_switches].valid = 0;
+ switches[n_switches].validated = 0;
n_switches++;
}
else if (strncmp (argv[i], "-Wl,", 4) == 0)
@@ -3278,15 +3268,15 @@ process_command (argc, argv)
switches[n_switches].args = 0;
switches[n_switches].live_cond = 0;
- switches[n_switches].valid = 0;
+ switches[n_switches].validated = 0;
/* This is always valid, since gcc.c itself understands it. */
if (!strcmp (p, "save-temps"))
- switches[n_switches].valid = 1;
+ switches[n_switches].validated = 1;
else
{
char ch = switches[n_switches].part1[0];
if (ch == 'V' || ch == 'b' || ch == 'B')
- switches[n_switches].valid = 1;
+ switches[n_switches].validated = 1;
}
n_switches++;
}
@@ -3325,12 +3315,12 @@ process_command (argc, argv)
sans all directory names, and basename_length is the number
of characters starting there excluding the suffix .c or whatever. */
-char *input_filename;
+const char *input_filename;
static int input_file_number;
size_t input_filename_length;
static int basename_length;
-static char *input_basename;
-static char *input_suffix;
+static const char *input_basename;
+static const char *input_suffix;
/* These are variables used within do_spec and do_spec_1. */
@@ -3359,7 +3349,7 @@ static int input_from_pipe;
int
do_spec (spec)
- char *spec;
+ const char *spec;
{
int value;
@@ -3400,14 +3390,14 @@ do_spec (spec)
static int
do_spec_1 (spec, inswitch, soft_matched_part)
- char *spec;
+ const char *spec;
int inswitch;
- char *soft_matched_part;
+ const char *soft_matched_part;
{
- register char *p = spec;
+ register const char *p = spec;
register int c;
int i;
- char *string;
+ const char *string;
int value;
while ((c = *p++))
@@ -3442,7 +3432,7 @@ do_spec_1 (spec, inswitch, soft_matched_part)
if (i < n_switches)
{
input_from_pipe = 1;
- switches[i].valid = 1;
+ switches[i].validated = 1;
break;
}
else
@@ -3628,16 +3618,16 @@ do_spec_1 (spec, inswitch, soft_matched_part)
break;
case 'e':
- /* {...:%efoo} means report an error with `foo' as error message
+ /* %efoo means report an error with `foo' as error message
and don't execute any more commands for this file. */
{
- char *q = p;
+ const char *q = p;
char *buf;
while (*p != 0 && *p != '\n') p++;
buf = (char *) alloca (p - q + 1);
strncpy (buf, q, p - q);
buf[p - q] = 0;
- error ("%s", buf);
+ error (buf);
return -1;
}
break;
@@ -3659,20 +3649,20 @@ do_spec_1 (spec, inswitch, soft_matched_part)
In 2.4, do something about that. */
struct temp_name *t;
int suffix_length;
- char *suffix = p;
+ const char *suffix = p;
if (p[0] == '%' && p[1] == 'O')
{
+ p += 2;
/* We don't support extra suffix characters after %O. */
- if (*p == '.' || ISALPHA (*p))
+ if (*p == '.' || ISALPHA ((unsigned char)*p))
abort ();
suffix = OBJECT_SUFFIX;
suffix_length = strlen (OBJECT_SUFFIX);
- p += 2;
}
else
{
- while (*p == '.' || ISALPHA (*p))
+ while (*p == '.' || ISALPHA ((unsigned char)*p))
p++;
suffix_length = p - suffix;
}
@@ -3754,9 +3744,8 @@ do_spec_1 (spec, inswitch, soft_matched_part)
case 'o':
{
int max = n_infiles;
-#ifdef LANG_SPECIFIC_DRIVER
max += lang_specific_extra_outfiles;
-#endif
+
for (i = 0; i < max; i++)
if (outfiles[i])
store_arg (outfiles[i], 0, 0);
@@ -3795,7 +3784,7 @@ do_spec_1 (spec, inswitch, soft_matched_part)
/* %x{OPTION} records OPTION for %X to output. */
case 'x':
{
- char *p1 = p;
+ const char *p1 = p;
char *string;
/* Skip past the option value and make a copy. */
@@ -3960,7 +3949,8 @@ do_spec_1 (spec, inswitch, soft_matched_part)
*x++ = *y++;
if (*y != '_'
- || (*(y+1) != '_' && ! ISUPPER (*(y+1))))
+ || (*(y+1) != '_'
+ && ! ISUPPER ((unsigned char)*(y+1))))
{
/* Stick __ at front of macro name. */
*x++ = '_';
@@ -4002,7 +3992,8 @@ do_spec_1 (spec, inswitch, soft_matched_part)
y += 2;
if (*y != '_'
- || (*(y+1) != '_' && ! ISUPPER (*(y+1))))
+ || (*(y+1) != '_'
+ && ! ISUPPER ((unsigned char)*(y+1))))
{
/* Stick -D__ at front of macro name. */
*x++ = '-';
@@ -4090,7 +4081,7 @@ do_spec_1 (spec, inswitch, soft_matched_part)
error ("Warning: use of obsolete %%[ operator in specs");
case '(':
{
- char *name = p;
+ const char *name = p;
struct spec_list *sl;
int len;
@@ -4105,8 +4096,8 @@ do_spec_1 (spec, inswitch, soft_matched_part)
{
name = *(sl->ptr_spec);
#ifdef DEBUG_SPECS
- fprintf (stderr, "Processing spec %c%s%c, which is '%s'\n",
- c, sl->name, (c == '(') ? ')' : ']', name);
+ notice ("Processing spec %c%s%c, which is '%s'\n",
+ c, sl->name, (c == '(') ? ')' : ']', name);
#endif
break;
}
@@ -4123,7 +4114,7 @@ do_spec_1 (spec, inswitch, soft_matched_part)
{
char *x = (char *) alloca (strlen (name) * 2 + 1);
char *buf = x;
- char *y = name;
+ const char *y = name;
int flag = 0;
/* Copy all of NAME into BUF, but put __ after
@@ -4231,11 +4222,11 @@ do_spec_1 (spec, inswitch, soft_matched_part)
/* Return 0 if we call do_spec_1 and that returns -1. */
-static char *
+static const char *
handle_braces (p)
- register char *p;
+ register const char *p;
{
- char *filter, *body = NULL, *endbody;
+ const char *filter, *body = NULL, *endbody = NULL;
int pipe_p = 0;
int negate;
int suffix;
@@ -4280,7 +4271,7 @@ next_member:
if (*p != '}')
{
register int count = 1;
- register char *q = p;
+ register const char *q = p;
while (*q++ != ':') continue;
body = q;
@@ -4304,7 +4295,7 @@ next_member:
if (suffix)
{
int found = (input_suffix != 0
- && strlen (input_suffix) == p - filter
+ && (long) strlen (input_suffix) == (long)(p - filter)
&& strncmp (input_suffix, filter, p - filter) == 0);
if (body[0] == '}')
@@ -4335,7 +4326,7 @@ next_member:
if (p[-1] == '*' && !negate)
{
int substitution;
- char *r = body;
+ const char *r = body;
/* First see whether we have %*. */
substitution = 0;
@@ -4446,7 +4437,7 @@ check_live_switch (switchnum, prefix_length)
int switchnum;
int prefix_length;
{
- char *name = switches[switchnum].part1;
+ const char *name = switches[switchnum].part1;
int i;
/* In the common case of {<at-most-one-letter>*}, a negating
@@ -4467,7 +4458,7 @@ check_live_switch (switchnum, prefix_length)
for (i = switchnum + 1; i < n_switches; i++)
if (switches[i].part1[0] == 'O')
{
- switches[switchnum].valid = 1;
+ switches[switchnum].validated = 1;
switches[switchnum].live_cond = -1;
return 0;
}
@@ -4481,7 +4472,7 @@ check_live_switch (switchnum, prefix_length)
if (switches[i].part1[0] == name[0]
&& ! strcmp (&switches[i].part1[1], &name[4]))
{
- switches[switchnum].valid = 1;
+ switches[switchnum].validated = 1;
switches[switchnum].live_cond = -1;
return 0;
}
@@ -4496,7 +4487,7 @@ check_live_switch (switchnum, prefix_length)
&& switches[i].part1[3] == '-'
&& !strcmp (&switches[i].part1[4], &name[1]))
{
- switches[switchnum].valid = 1;
+ switches[switchnum].validated = 1;
switches[switchnum].live_cond = -1;
return 0;
}
@@ -4544,16 +4535,16 @@ give_switch (switchnum, omit_first_word, include_blanks)
}
do_spec_1 (" ", 0, NULL_PTR);
- switches[switchnum].valid = 1;
+ switches[switchnum].validated = 1;
}
/* Search for a file named NAME trying various prefixes including the
user's -B prefix and some standard ones.
Return the absolute file name found. If nothing is found, return NAME. */
-static char *
+static const char *
find_file (name)
- char *name;
+ const char *name;
{
char *newname;
@@ -4586,8 +4577,8 @@ find_file (name)
static int
is_directory (path1, path2, linker)
- char *path1;
- char *path2;
+ const char *path1;
+ const char *path2;
int linker;
{
int len1 = strlen (path1);
@@ -4651,13 +4642,19 @@ main (argc, argv)
int linker_was_run = 0;
char *explicit_link_files;
char *specs_file;
- char *p;
+ const char *p;
struct user_specs *uptr;
p = argv[0] + strlen (argv[0]);
while (p != argv[0] && p[-1] != '/' && p[-1] != DIR_SEPARATOR) --p;
programname = p;
+#ifdef HAVE_LC_MESSAGES
+ setlocale (LC_MESSAGES, "");
+#endif
+ (void) bindtextdomain (PACKAGE, localedir);
+ (void) textdomain (PACKAGE);
+
if (signal (SIGINT, SIG_IGN) != SIG_IGN)
signal (SIGINT, fatal_error);
#ifdef SIGHUP
@@ -4748,10 +4745,10 @@ main (argc, argv)
sizeof ("COLLECT_GCC_OPTIONS=")-1);
first_time = TRUE;
- for (i = 0; i < n_switches; i++)
+ for (i = 0; (int)i < n_switches; i++)
{
char **args;
- char *p, *q;
+ const char *p, *q;
if (!first_time)
obstack_grow (&collect_obstack, " ", 1);
@@ -4919,8 +4916,8 @@ main (argc, argv)
/* Warn about any switches that no pass was interested in. */
- for (i = 0; i < n_switches; i++)
- if (! switches[i].valid)
+ for (i = 0; (int)i < n_switches; i++)
+ if (! switches[i].validated)
error ("unrecognized option `-%s'", switches[i].part1);
/* Obey some of the options. */
@@ -4967,7 +4964,7 @@ main (argc, argv)
if (! verbose_flag)
{
- printf ("\nReport bugs to egcs-bugs@cygnus.com.\n");
+ printf ("\nReport bugs to egcs-bugs@egcs.cygnus.com.\n");
printf ("Please see the file BUGS (included with the sources) first.\n");
exit (0);
@@ -4991,10 +4988,10 @@ main (argc, argv)
if (! strncmp (version_string, compiler_version, n)
&& compiler_version[n] == 0)
- fprintf (stderr, "gcc version %s\n", version_string);
+ notice ("gcc version %s\n", version_string);
else
- fprintf (stderr, "gcc driver version %s executing gcc version %s\n",
- version_string, compiler_version);
+ notice ("gcc driver version %s executing gcc version %s\n",
+ version_string, compiler_version);
if (n_infiles == 0)
exit (0);
@@ -5007,10 +5004,8 @@ main (argc, argv)
that correspond to the input files. */
i = n_infiles;
-#ifdef LANG_SPECIFIC_DRIVER
i += lang_specific_extra_outfiles;
-#endif
- outfiles = (char **) xmalloc (i * sizeof (char *));
+ outfiles = (const char **) xmalloc (i * sizeof (char *));
bzero ((char *) outfiles, i * sizeof (char *));
/* Record which files were specified explicitly as link input. */
@@ -5018,7 +5013,7 @@ main (argc, argv)
explicit_link_files = xmalloc (n_infiles);
bzero (explicit_link_files, n_infiles);
- for (i = 0; i < n_infiles; i++)
+ for (i = 0; (int)i < n_infiles; i++)
{
register struct compiler *cp = 0;
int this_file_error = 0;
@@ -5042,7 +5037,7 @@ main (argc, argv)
{
/* Ok, we found an applicable compiler. Run its spec. */
/* First say how much of input_filename to substitute for %b */
- register char *p;
+ register const char *p;
int len;
if (cp->spec[0][0] == '#')
@@ -5072,18 +5067,20 @@ main (argc, argv)
if (cp->spec[j])
len += strlen (cp->spec[j]);
- p = (char *) xmalloc (len + 1);
-
- len = 0;
- for (j = 0; j < sizeof cp->spec / sizeof cp->spec[0]; j++)
- if (cp->spec[j])
- {
- strcpy (p + len, cp->spec[j]);
- len += strlen (cp->spec[j]);
- }
-
- value = do_spec (p);
- free (p);
+ {
+ char *p1 = (char *) xmalloc (len + 1);
+
+ len = 0;
+ for (j = 0; j < sizeof cp->spec / sizeof cp->spec[0]; j++)
+ if (cp->spec[j])
+ {
+ strcpy (p1 + len, cp->spec[j]);
+ len += strlen (cp->spec[j]);
+ }
+
+ value = do_spec (p1);
+ free (p1);
+ }
if (value < 0)
this_file_error = 1;
}
@@ -5106,7 +5103,6 @@ main (argc, argv)
clear_failure_queue ();
}
-#ifdef LANG_SPECIFIC_DRIVER
if (error_count == 0)
{
/* Make sure INPUT_FILE_NUMBER points to first available open
@@ -5115,7 +5111,6 @@ main (argc, argv)
if (lang_specific_pre_link ())
error_count++;
}
-#endif
/* Run ld to link all the compiler output files. */
@@ -5149,7 +5144,7 @@ main (argc, argv)
complain about input files to be given to the linker. */
if (! linker_was_run && error_count == 0)
- for (i = 0; i < n_infiles; i++)
+ for (i = 0; (int)i < n_infiles; i++)
if (explicit_link_files[i])
error ("%s: linker input file unused since linking not done",
outfiles[i]);
@@ -5162,7 +5157,7 @@ main (argc, argv)
if (print_help_list)
{
- printf ("\nReport bugs to egcs-bugs@cygnus.com.\n");
+ printf ("\nReport bugs to egcs-bugs@egcs.cygnus.com.\n");
printf ("Please see the file BUGS (included with the sources) first.\n");
}
@@ -5177,9 +5172,9 @@ main (argc, argv)
static struct compiler *
lookup_compiler (name, length, language)
- char *name;
+ const char *name;
size_t length;
- char *language;
+ const char *language;
{
struct compiler *cp;
@@ -5241,85 +5236,35 @@ lookup_compiler (name, length, language)
return 0;
}
-char *
+PTR
xmalloc (size)
- unsigned size;
+ size_t size;
{
- register char *value = (char *) malloc (size);
+ register PTR value = (PTR) malloc (size);
if (value == 0)
fatal ("virtual memory exhausted");
return value;
}
-char *
-xrealloc (ptr, size)
- char *ptr;
- unsigned size;
+PTR
+xrealloc (old, size)
+ PTR old;
+ size_t size;
{
- register char *value = (char *) realloc (ptr, size);
- if (value == 0)
+ register PTR ptr;
+ if (old)
+ ptr = (PTR) realloc (old, size);
+ else
+ ptr = (PTR) malloc (size);
+ if (ptr == 0)
fatal ("virtual memory exhausted");
- return value;
-}
-
-/* This function is based on the one in libiberty. */
-
-static char *
-concat VPROTO((char *first, ...))
-{
- register int length;
- register char *newstr;
- register char *end;
- register char *arg;
- va_list args;
-#ifndef __STDC__
- char *first;
-#endif
-
- /* First compute the size of the result and get sufficient memory. */
-
- VA_START (args, first);
-#ifndef __STDC__
- first = va_arg (args, char *);
-#endif
-
- arg = first;
- length = 0;
-
- while (arg != 0)
- {
- length += strlen (arg);
- arg = va_arg (args, char *);
- }
-
- newstr = (char *) xmalloc (length + 1);
- va_end (args);
-
- /* Now copy the individual pieces to the result string. */
-
- VA_START (args, first);
-#ifndef __STDC__
- first = va_arg (args, char *);
-#endif
-
- end = newstr;
- arg = first;
- while (arg != 0)
- {
- while (*arg)
- *end++ = *arg++;
- arg = va_arg (args, char *);
- }
- *end = '\000';
- va_end (args);
-
- return (newstr);
+ return ptr;
}
static char *
save_string (s, len)
- char *s;
- int len;
+ const char *s;
+ int len;
{
register char *result = xmalloc (len + 1);
@@ -5330,34 +5275,38 @@ save_string (s, len)
static void
pfatal_with_name (name)
- char *name;
+ const char *name;
{
- fatal ("%s: %s", name, my_strerror (errno));
+ perror_with_name (name);
+ delete_temp_files ();
+ exit (1);
}
static void
perror_with_name (name)
- char *name;
+ const char *name;
{
- error ("%s: %s", name, my_strerror (errno));
+ error ("%s: %s", name, xstrerror (errno));
}
static void
pfatal_pexecute (errmsg_fmt, errmsg_arg)
- char *errmsg_fmt;
- char *errmsg_arg;
+ const char *errmsg_fmt;
+ const char *errmsg_arg;
{
- int save_errno = errno;
-
if (errmsg_arg)
{
+ int save_errno = errno;
+
/* Space for trailing '\0' is in %s. */
char *msg = xmalloc (strlen (errmsg_fmt) + strlen (errmsg_arg));
sprintf (msg, errmsg_fmt, errmsg_arg);
errmsg_fmt = msg;
+
+ errno = save_errno;
}
- fatal ("%s: %s", errmsg_fmt, my_strerror (save_errno));
+ pfatal_with_name (errmsg_fmt);
}
/* More 'friendly' abort that prints the line and file.
@@ -5372,21 +5321,21 @@ fancy_abort ()
/* Output an error message and exit */
static void
-fatal VPROTO((char *format, ...))
+fatal VPROTO((const char *msgid, ...))
{
-#ifndef __STDC__
- char *format;
+#ifndef ANSI_PROTOTYPES
+ const char *msgid;
#endif
va_list ap;
- VA_START (ap, format);
+ VA_START (ap, msgid);
-#ifndef __STDC__
- format = va_arg (ap, char *);
+#ifndef ANSI_PROTOTYPES
+ msgid = va_arg (ap, const char *);
#endif
fprintf (stderr, "%s: ", programname);
- vfprintf (stderr, format, ap);
+ vfprintf (stderr, _(msgid), ap);
va_end (ap);
fprintf (stderr, "\n");
delete_temp_files ();
@@ -5394,31 +5343,50 @@ fatal VPROTO((char *format, ...))
}
static void
-error VPROTO((char *format, ...))
+error VPROTO((const char *msgid, ...))
{
-#ifndef __STDC__
- char *format;
+#ifndef ANSI_PROTOTYPES
+ const char *msgid;
#endif
va_list ap;
- VA_START (ap, format);
+ VA_START (ap, msgid);
-#ifndef __STDC__
- format = va_arg (ap, char *);
+#ifndef ANSI_PROTOTYPES
+ msgid = va_arg (ap, const char *);
#endif
fprintf (stderr, "%s: ", programname);
- vfprintf (stderr, format, ap);
+ vfprintf (stderr, _(msgid), ap);
va_end (ap);
fprintf (stderr, "\n");
}
+
+static void
+notice VPROTO((const char *msgid, ...))
+{
+#ifndef ANSI_PROTOTYPES
+ const char *msgid;
+#endif
+ va_list ap;
+
+ VA_START (ap, msgid);
+
+#ifndef ANSI_PROTOTYPES
+ msgid = va_arg (ap, const char *);
+#endif
+
+ vfprintf (stderr, _(msgid), ap);
+ va_end (ap);
+}
+
static void
validate_all_switches ()
{
struct compiler *comp;
- register char *p;
+ register const char *p;
register char c;
struct spec_list *spec;
@@ -5457,10 +5425,10 @@ validate_all_switches ()
static void
validate_switches (start)
- char *start;
+ const char *start;
{
- register char *p = start;
- char *filter;
+ register const char *p = start;
+ const char *filter;
register int i;
int suffix = 0;
@@ -5484,7 +5452,7 @@ validate_switches (start)
--p;
for (i = 0; i < n_switches; i++)
if (!strncmp (switches[i].part1, filter, p - filter))
- switches[i].valid = 1;
+ switches[i].validated = 1;
}
else
{
@@ -5493,7 +5461,7 @@ validate_switches (start)
{
if (!strncmp (switches[i].part1, filter, p - filter)
&& switches[i].part1[p - filter] == 0)
- switches[i].valid = 1;
+ switches[i].validated = 1;
}
}
}
@@ -5503,7 +5471,7 @@ validate_switches (start)
static int
used_arg (p, len)
- char *p;
+ const char *p;
int len;
{
struct mswitchstr {
@@ -5591,7 +5559,7 @@ used_arg (p, len)
static int
default_arg (p, len)
- char *p;
+ const char *p;
int len;
{
char *start, *end;
@@ -5706,9 +5674,10 @@ set_multilib_dir ()
if (this_path_len != 1
|| this_path[0] != '.')
{
- multilib_dir = xmalloc (this_path_len + 1);
- strncpy (multilib_dir, this_path, this_path_len);
- multilib_dir[this_path_len] = '\0';
+ char * new_multilib_dir = xmalloc (this_path_len + 1);
+ strncpy (new_multilib_dir, this_path, this_path_len);
+ new_multilib_dir[this_path_len] = '\0';
+ multilib_dir = new_multilib_dir;
}
break;
}
diff --git a/gcc/gcc.texi b/gcc/gcc.texi
index b0fee64ddcd..4f9ceeb4ea8 100644
--- a/gcc/gcc.texi
+++ b/gcc/gcc.texi
@@ -1643,15 +1643,16 @@ in scope at the time of the call.
@cindex misunderstandings in C++
@cindex surprises in C++
@cindex C++ misunderstandings
-C++ is a complex language and an evolving one, and its standard definition
-(the ANSI C++ draft standard) is also evolving. As a result,
-your C++ compiler may occasionally surprise you, even when its behavior is
-correct. This section discusses some areas that frequently give rise to
-questions of this sort.
+C++ is a complex language and an evolving one, and its standard
+definition (the ISO C++ standard) was only recently completed. As a
+result, your C++ compiler may occasionally surprise you, even when its
+behavior is correct. This section discusses some areas that frequently
+give rise to questions of this sort.
@menu
* Static Definitions:: Static member declarations are not definitions
* Temporaries:: Temporaries may vanish before you expect
+* Copy Assignment:: Copy Assignment operators copy virtual bases twice
@end menu
@node Static Definitions
@@ -1698,52 +1699,109 @@ symbols any static data members that lack definitions.
It is dangerous to use pointers or references to @emph{portions} of a
temporary object. The compiler may very well delete the object before
you expect it to, leaving a pointer to garbage. The most common place
-where this problem crops up is in classes like the libg++
-@code{String} class, that define a conversion function to type
-@code{char *} or @code{const char *}. However, any class that returns
-a pointer to some internal structure is potentially subject to this
-problem.
+where this problem crops up is in classes like string classes,
+especially ones that define a conversion function to type @code{char *}
+or @code{const char *} -- which is one reason why the standard
+@code{string} class requires you to call the @code{c_str} member
+function. However, any class that returns a pointer to some internal
+structure is potentially subject to this problem.
For example, a program may use a function @code{strfunc} that returns
-@code{String} objects, and another function @code{charfunc} that
+@code{string} objects, and another function @code{charfunc} that
operates on pointers to @code{char}:
@example
-String strfunc ();
+string strfunc ();
void charfunc (const char *);
+
+void
+f ()
+@{
+ const char *p = strfunc().c_str();
+ ...
+ charfunc (p);
+ ...
+ charfunc (p);
+@}
@end example
@noindent
-In this situation, it may seem natural to write @w{@samp{charfunc
-(strfunc ());}} based on the knowledge that class @code{String} has an
-explicit conversion to @code{char} pointers. However, what really
-happens is akin to @samp{charfunc (@w{strfunc ()}.@w{convert ()});},
-where the @code{convert} method is a function to do the same data
-conversion normally performed by a cast. Since the last use of the
-temporary @code{String} object is the call to the conversion function,
-the compiler may delete that object before actually calling
-@code{charfunc}. The compiler has no way of knowing that deleting the
-@code{String} object will invalidate the pointer. The pointer then
-points to garbage, so that by the time @code{charfunc} is called, it
-gets an invalid argument.
+In this situation, it may seem reasonable to save a pointer to the C
+string returned by the @code{c_str} member function and use that rather
+than call @code{c_str} repeatedly. However, the temporary string
+created by the call to @code{strfunc} is destroyed after @code{p} is
+initialized, at which point @code{p} is left pointing to freed memory.
Code like this may run successfully under some other compilers,
-especially those that delete temporaries relatively late. However, the
-GNU C++ behavior is also standard-conforming, so if your program depends
-on late destruction of temporaries it is not portable.
+particularly obsolete cfront-based compilers that delete temporaries
+along with normal local variables. However, the GNU C++ behavior is
+standard-conforming, so if your program depends on late destruction of
+temporaries it is not portable.
-If you think this is surprising, you should be aware that the ANSI C++
-committee continues to debate the lifetime-of-temporaries problem.
+The safe way to write such code is to give the temporary a name, which
+forces it to remain until the end of the scope of the name. For
+example:
-For now, at least, the safe way to write such code is to give the
-temporary a name, which forces it to remain until the end of the scope of
-the name. For example:
+@example
+string& tmp = strfunc ();
+charfunc (tmp.c_str ());
+@end example
+
+@node Copy Assignment
+@subsection Implicit Copy-Assignment for Virtual Bases
+
+When a base class is virtual, only one subobject of the base class
+belongs to each full object. Also, the constructors and destructors are
+invoked only once, and called from the most-derived class. However, such
+objects behave unspecified when being assigned. For example:
@example
-String& tmp = strfunc ();
-charfunc (tmp);
+struct Base@{
+ char *name;
+ Base(char *n) : name(strdup(n))@{@}
+ Base& operator= (const Base& other)@{
+ free (name);
+ name = strdup (other.name);
+ @}
+@};
+
+struct A:virtual Base@{
+ int val;
+ A():Base("A")@{@}
+@};
+
+struct B:virtual Base@{
+ int bval;
+ B():Base("B")@{@}
+@};
+
+struct Derived:public A, public B@{
+ Derived():Base("Derived")@{@}
+@};
+
+void func(Derived &d1, Derived &d2)
+@{
+ d1 = d2;
+@}
@end example
+The C++ standard specifies that @samp{Base::Base} is only called once
+when constructing or copy-constructing a Derived object. It is
+unspecified whether @samp{Base::operator=} is called more than once when
+the implicit copy-assignment for Derived objects is invoked (as it is
+inside @samp{func} in the example).
+
+g++ implements the "intuitive" algorithm for copy-assignment: assign all
+direct bases, then assign all members. In that algorithm, the virtual
+base subobject can be encountered many times. In the example, copying
+proceeds in the following order: @samp{val}, @samp{name} (via
+@code{strdup}), @samp{bval}, and @samp{name} again.
+
+If application code relies on copy-assignment, a user-defined
+copy-assignment operator removes any uncertainties. With such an
+operator, the application can define whether and how the virtual base
+subobject is assigned.
+
@node Protoize Caveats
@section Caveats of using @code{protoize}
@@ -2005,12 +2063,18 @@ test explicitly for C++ as well.
@item
Deleting ``empty'' loops.
-GNU CC does not delete ``empty'' loops because the most likely reason
-you would put one in a program is to have a delay. Deleting them will
-not make real programs run any faster, so it would be pointless.
+Historically, GNU CC has not deleted ``empty'' loops under the
+assumption that the most likely reason you would put one in a program is
+to have a delay, so deleting them will not make real programs run any
+faster.
+
+However, the rationale here is that optimization of a nonempty loop
+cannot produce an empty one, which holds for C but is not always the
+case for C++.
-It would be different if optimization of a nonempty loop could produce
-an empty one. But this generally can't happen.
+Moreover, with @samp{-funroll-loops} small ``empty'' loops are already
+removed, so the current behavior is both sub-optimal and inconsistent
+and will change in the future.
@item
Making side effects happen in the same order as in some other compiler.
@@ -2188,13 +2252,13 @@ for improvement of GNU CC or GNU C++ are welcome in any case.
@node Bug Lists
@section Where to Report Bugs
@cindex bug report mailing lists
-@kindex egcs-bugs@@cygnus.com
-Send bug reports for GNU C to @samp{egcs-bugs@@cygnus.com}.
+@kindex egcs-bugs@@egcs.cygnus.com
+Send bug reports for GNU C to @samp{egcs-bugs@@egcs.cygnus.com}.
-@kindex egcs-bugs@@cygnus.com
-@kindex egcs-bugs@@cygnus.com
+@kindex egcs-bugs@@egcs.cygnus.com
+@kindex egcs-bugs@@egcs.cygnus.com
Send bug reports for GNU C++ and the C++ runtime libraries to
-@samp{egcs-bugs@@cygnus.com}.
+@samp{egcs-bugs@@egcs.cygnus.com}.
Often people think of posting bug reports to the newsgroup instead of
mailing them. This appears to work, but it has one problem which can be
@@ -2252,9 +2316,15 @@ If you include source code in your message, you can send it as clear
text if it is small. If the message is larger, you may compress it using
@file{gzip}, @file{bzip2}, or @file{pkzip}. Please be aware that sending
compressed files needs an additional binary-safe mechanism such as
-@code{MIME} or @code{uuencode}. There is a 40k message limit on the
-@samp{egcs-bugs@@cygnus.com} mailing list at the time of this writing
-(August 1998).
+@code{MIME} or @code{uuencode}. There is a 100k message limit on the
+@samp{egcs-bugs@@egcs.cygnus.com} mailing list at the time of this
+writing (March 1999). We're trying to create some mechanism for larger
+bug reports to be submitted; please check the on-line FAQ for more
+up-to-date instructions. Don't think that just posting a URL to the
+code is better, we do want to archive bug reports, and not all
+maintainers have good network connectivity to download large pieces of
+software when they need them; it's much easier for them to have them in
+their mailboxes.
To enable someone to investigate the bug, you should include all these
things:
@@ -2482,7 +2552,7 @@ we should be able to reproduce the crash ourselves.
If you would like to write bug fixes or improvements for the GNU C
compiler, that is very helpful. Send suggested fixes to the bug report
-mailing list, @code{egcs-bugs@@cygnus.com}.
+mailing list, @code{egcs-bugs@@egcs.cygnus.com}.
Please follow these guidelines so we can study your patches efficiently.
If you don't follow these guidelines, your information might still be
@@ -2602,8 +2672,8 @@ ways to find it:
@itemize @bullet
@item
Send a message to a suitable network mailing list. First try
-@code{egcs-bugs@@cygnus.com}, and if that brings no response, try
-@code{egcs@@cygnus.com}.
+@code{egcs-bugs@@egcs.cygnus.com}, and if that brings no response, try
+@code{egcs@@egcs.cygnus.com}.
@item
Look in the service directory for someone who might help you for a fee.
@@ -2616,13 +2686,13 @@ GNU CC distribution.
If you would like to help pretest GNU CC releases to assure they work
well, or if you would like to work on improving GNU CC, please contact
-the maintainers at @code{egcs@@cygnus.com}. A pretester should
+the maintainers at @code{egcs@@egcs.cygnus.com}. A pretester should
be willing to try to investigate bugs as well as report them.
If you'd like to work on improvements, please ask for suggested projects
or suggest your own ideas. If you have already written an improvement,
please tell us about it. If you have not yet started work, it is useful
-to contact @code{egcs@@cygnus.com} before you start; the
+to contact @code{egcs@@egcs.cygnus.com} before you start; the
maintainers may be able to suggest ways to make your extension fit in
better with the rest of GNU CC and with other development plans.
diff --git a/gcc/gcov-io.h b/gcc/gcov-io.h
index c2949a311af..d2605fe2533 100644
--- a/gcc/gcov-io.h
+++ b/gcc/gcov-io.h
@@ -1,5 +1,5 @@
/* Machine-independent I/O routines for gcov.
- Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+ Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
Contributed by Bob Manson <manson@cygnus.com>.
This file is part of GNU CC.
@@ -24,7 +24,7 @@ Boston, MA 02111-1307, USA. */
#include <stdio.h>
#include <sys/types.h>
-static int __fetch_long PROTO ((long *, char *, int));
+static int __fetch_long PROTO ((long *, char *, size_t));
static int __store_long PROTO ((long, char *, size_t));
static int __read_long PROTO ((long *, FILE *, size_t));
static int __write_long PROTO ((long, FILE *, size_t));
@@ -74,17 +74,17 @@ static int
__fetch_long (dest, source, bytes)
long *dest;
char *source;
- int bytes;
+ size_t bytes;
{
long value = 0;
int i;
- for (i = bytes - 1; i > (sizeof (*dest) - 1); i--)
- if (source[i] & (i == (bytes - 1) ? 127 : 255 ))
+ for (i = bytes - 1; (size_t) i > (sizeof (*dest) - 1); i--)
+ if (source[i] & ((size_t) i == (bytes - 1) ? 127 : 255 ))
return 1;
for (; i >= 0; i--)
- value = value * 256 + (source[i] & (i == (bytes - 1) ? 127 : 255));
+ value = value * 256 + (source[i] & ((size_t)i == (bytes - 1) ? 127 : 255));
if ((source[bytes - 1] & 128) && (value > 0))
value = - value;
diff --git a/gcc/gcov.c b/gcc/gcov.c
index eff68f1608a..46df6ede862 100644
--- a/gcc/gcov.c
+++ b/gcc/gcov.c
@@ -1,6 +1,6 @@
/* Gcov.c: prepend line execution counts and branch probabilities to a
source file.
- Copyright (C) 1990, 91, 92, 93, 94, 96, 1997 Free Software Foundation, Inc.
+ Copyright (C) 1990, 91-94, 96, 97, 98, 1999 Free Software Foundation, Inc.
Contributed by James E. Wilson of Cygnus Support.
Mangled by Bob Manson of Cygnus Support.
@@ -16,7 +16,8 @@ GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Gcov; see the file COPYING. If not, write to
-the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
/* ??? The code in final.c that produces the struct bb assumes that there is
no padding between the fields. This is not necessary true. The current
@@ -43,8 +44,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "config.h"
#include "system.h"
-#include <sys/stat.h>
-#include "gansidecl.h"
+#include "intl.h"
#include "gcov-io.h"
@@ -218,14 +218,19 @@ static void open_files PROTO ((void));
static void read_files PROTO ((void));
static void scan_for_source_files PROTO ((void));
static void output_data PROTO ((void));
-static void print_usage PROTO ((void));
-char * xmalloc ();
+static void print_usage PROTO ((void)) ATTRIBUTE_NORETURN;
int
main (argc, argv)
int argc;
char **argv;
{
+#ifdef HAVE_LC_MESSAGES
+ setlocale (LC_MESSAGES, "");
+#endif
+ (void) bindtextdomain (PACKAGE, localedir);
+ (void) textdomain (PACKAGE);
+
process_args (argc, argv);
open_files ();
@@ -239,14 +244,36 @@ main (argc, argv)
return 0;
}
-char *
+static void fnotice PVPROTO ((FILE *, const char *, ...)) ATTRIBUTE_PRINTF_2;
+static void
+fnotice VPROTO ((FILE *file, const char *msgid, ...))
+{
+#ifndef ANSI_PROTOTYPES
+ FILE *file;
+ const char *msgid;
+#endif
+ va_list ap;
+
+ VA_START (ap, msgid);
+
+#ifndef ANSI_PROTOTYPES
+ file = va_arg (ap, FILE *);
+ msgid = va_arg (ap, const char *);
+#endif
+
+ vfprintf (file, _(msgid), ap);
+ va_end (ap);
+}
+
+
+PTR
xmalloc (size)
- unsigned size;
+ size_t size;
{
- register char *value = (char *) malloc (size);
+ register PTR value = (PTR) malloc (size);
if (value == 0)
{
- fprintf (stderr, "error: virtual memory exhausted");
+ fnotice (stderr, "error: virtual memory exhausted");
exit (FATAL_EXIT_CODE);
}
return value;
@@ -258,7 +285,7 @@ xmalloc (size)
void
fancy_abort ()
{
- fprintf (stderr, "Internal gcc abort.\n");
+ fnotice (stderr, "Internal gcc abort.\n");
exit (FATAL_EXIT_CODE);
}
@@ -267,7 +294,7 @@ fancy_abort ()
static void
print_usage ()
{
- fprintf (stderr, "gcov [-b] [-v] [-n] [-l] [-f] [-o OBJDIR] file\n");
+ fnotice (stderr, "gcov [-b] [-v] [-n] [-l] [-f] [-o OBJDIR] file\n");
exit (FATAL_EXIT_CODE);
}
@@ -385,7 +412,7 @@ open_files ()
bb_file = fopen (bb_file_name, "r");
if (bb_file == NULL)
{
- fprintf (stderr, "Could not open basic block file %s.\n", bb_file_name);
+ fnotice (stderr, "Could not open basic block file %s.\n", bb_file_name);
exit (FATAL_EXIT_CODE);
}
@@ -394,14 +421,14 @@ open_files ()
da_file = fopen (da_file_name, "r");
if (da_file == NULL)
{
- fprintf (stderr, "Could not open data file %s.\n", da_file_name);
- fprintf (stderr, "Assuming that all execution counts are zero.\n");
+ fnotice (stderr, "Could not open data file %s.\n", da_file_name);
+ fnotice (stderr, "Assuming that all execution counts are zero.\n");
}
bbg_file = fopen (bbg_file_name, "r");
if (bbg_file == NULL)
{
- fprintf (stderr, "Could not open program flow graph file %s.\n",
+ fnotice (stderr, "Could not open program flow graph file %s.\n",
bbg_file_name);
exit (FATAL_EXIT_CODE);
}
@@ -412,7 +439,7 @@ open_files ()
ungetc (getc (bbg_file), bbg_file);
if (feof (bbg_file))
{
- fprintf (stderr, "No executable code associated with file %s.\n",
+ fnotice (stderr, "No executable code associated with file %s.\n",
input_file_name);
exit (FATAL_EXIT_CODE);
}
@@ -713,10 +740,10 @@ read_files ()
if (da_file)
{
if (feof (da_file))
- fprintf (stderr, ".da file contents exhausted too early\n");
+ fnotice (stderr, ".da file contents exhausted too early\n");
/* Should be at end of file now. */
if (__read_long (&total, da_file, 8) == 0)
- fprintf (stderr, ".da file contents not exhausted\n");
+ fnotice (stderr, ".da file contents not exhausted\n");
}
/* Calculate all of the basic block execution counts and branch
@@ -897,33 +924,33 @@ static void
function_summary ()
{
if (function_source_lines)
- fprintf (stdout, "%6.2f%% of %d source lines executed in function %s\n",
+ fnotice (stdout, "%6.2f%% of %d source lines executed in function %s\n",
(((double) function_source_lines_executed / function_source_lines)
* 100), function_source_lines, function_name);
else
- fprintf (stdout, "No executable source lines in function %s\n",
+ fnotice (stdout, "No executable source lines in function %s\n",
function_name);
if (output_branch_probs)
{
if (function_branches)
{
- fprintf (stdout, "%6.2f%% of %d branches executed in function %s\n",
+ fnotice (stdout, "%6.2f%% of %d branches executed in function %s\n",
(((double) function_branches_executed / function_branches)
* 100), function_branches, function_name);
- fprintf (stdout,
+ fnotice (stdout,
"%6.2f%% of %d branches taken at least once in function %s\n",
(((double) function_branches_taken / function_branches)
* 100), function_branches, function_name);
}
else
- fprintf (stdout, "No branches in function %s\n", function_name);
+ fnotice (stdout, "No branches in function %s\n", function_name);
if (function_calls)
- fprintf (stdout, "%6.2f%% of %d calls executed in function %s\n",
+ fnotice (stdout, "%6.2f%% of %d calls executed in function %s\n",
(((double) function_calls_executed / function_calls)
* 100), function_calls, function_name);
else
- fprintf (stdout, "No calls in function %s\n", function_name);
+ fnotice (stdout, "No calls in function %s\n", function_name);
}
}
@@ -997,10 +1024,10 @@ output_data ()
bzero (line_exists, s_ptr->maxlineno);
if (output_branch_probs)
{
- branch_probs = (struct arcdata **) xmalloc (sizeof (struct arcdata **)
+ branch_probs = (struct arcdata **) xmalloc (sizeof (struct arcdata *)
* s_ptr->maxlineno);
bzero ((char *) branch_probs,
- sizeof (struct arcdata **) * s_ptr->maxlineno);
+ sizeof (struct arcdata *) * s_ptr->maxlineno);
}
/* There will be a zero at the beginning of the bb info, before the
@@ -1054,10 +1081,10 @@ output_data ()
}
else
{
- fprintf (stderr,
+ fnotice (stderr,
"didn't use all bb entries of graph, function %s\n",
function_name);
- fprintf (stderr, "block_num = %ld, num_blocks = %d\n",
+ fnotice (stderr, "block_num = %ld, num_blocks = %d\n",
block_num, current_graph->num_blocks);
}
@@ -1095,7 +1122,7 @@ output_data ()
if (block_num >= current_graph->num_blocks)
{
- fprintf (stderr, "ERROR: too many basic blocks in .bb file %s\n",
+ fnotice (stderr, "ERROR: too many basic blocks in .bb file %s\n",
function_name);
abort ();
}
@@ -1171,34 +1198,34 @@ output_data ()
}
if (total_source_lines)
- fprintf (stdout,
+ fnotice (stdout,
"%6.2f%% of %d source lines executed in file %s\n",
(((double) total_source_lines_executed / total_source_lines)
* 100), total_source_lines, source_file_name);
else
- fprintf (stdout, "No executable source lines in file %s\n",
+ fnotice (stdout, "No executable source lines in file %s\n",
source_file_name);
if (output_branch_probs)
{
if (total_branches)
{
- fprintf (stdout, "%6.2f%% of %d branches executed in file %s\n",
+ fnotice (stdout, "%6.2f%% of %d branches executed in file %s\n",
(((double) total_branches_executed / total_branches)
* 100), total_branches, source_file_name);
- fprintf (stdout,
+ fnotice (stdout,
"%6.2f%% of %d branches taken at least once in file %s\n",
(((double) total_branches_taken / total_branches)
* 100), total_branches, source_file_name);
}
else
- fprintf (stdout, "No branches in file %s\n", source_file_name);
+ fnotice (stdout, "No branches in file %s\n", source_file_name);
if (total_calls)
- fprintf (stdout, "%6.2f%% of %d calls executed in file %s\n",
+ fnotice (stdout, "%6.2f%% of %d calls executed in file %s\n",
(((double) total_calls_executed / total_calls)
* 100), total_calls, source_file_name);
else
- fprintf (stdout, "No calls in file %s\n", source_file_name);
+ fnotice (stdout, "No calls in file %s\n", source_file_name);
}
if (output_gcov_file)
@@ -1210,7 +1237,7 @@ output_data ()
source_file = fopen (source_file_name, "r");
if (source_file == NULL)
{
- fprintf (stderr, "Could not open source file %s.\n",
+ fnotice (stderr, "Could not open source file %s.\n",
source_file_name);
free (line_counts);
free (line_exists);
@@ -1260,7 +1287,7 @@ output_data ()
if (gcov_file == NULL)
{
- fprintf (stderr, "Could not open output file %s.\n",
+ fnotice (stderr, "Could not open output file %s.\n",
gcov_file_name);
fclose (source_file);
free (line_counts);
@@ -1268,7 +1295,7 @@ output_data ()
continue;
}
- fprintf (stdout, "Creating %s.\n", gcov_file_name);
+ fnotice (stdout, "Creating %s.\n", gcov_file_name);
for (count = 1; count < s_ptr->maxlineno; count++)
{
@@ -1312,19 +1339,19 @@ output_data ()
if (a_ptr->call_insn)
{
if (a_ptr->prob == -1)
- fprintf (gcov_file, "call %d never executed\n", i);
+ fnotice (gcov_file, "call %d never executed\n", i);
else
- fprintf (gcov_file,
+ fnotice (gcov_file,
"call %d returns = %d%%\n",
i, 100 - a_ptr->prob);
}
else
{
if (a_ptr->prob == -1)
- fprintf (gcov_file, "branch %d never executed\n",
+ fnotice (gcov_file, "branch %d never executed\n",
i);
else
- fprintf (gcov_file, "branch %d taken = %d%%\n", i,
+ fnotice (gcov_file, "branch %d taken = %d%%\n", i,
a_ptr->prob);
}
}
@@ -1333,7 +1360,7 @@ output_data ()
/* Gracefully handle errors while reading the source file. */
if (retval == NULL)
{
- fprintf (stderr,
+ fnotice (stderr,
"Unexpected EOF while reading source file %s.\n",
source_file_name);
break;
diff --git a/gcc/gcse.c b/gcc/gcse.c
index bf5b66d7735..2d441d1dfe5 100644
--- a/gcc/gcse.c
+++ b/gcc/gcse.c
@@ -1,6 +1,6 @@
-/* Global common subexpression elimination
+/* Global common subexpression elimination/Partial redundancy elimination
and global constant/copy propagation for GNU compiler.
- Copyright (C) 1997 Free Software Foundation, Inc.
+ Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -24,18 +24,17 @@ Boston, MA 02111-1307, USA. */
- do rough calc of how many regs are needed in each block, and a rough
calc of how many regs are available in each class and use that to
throttle back the code in cases where RTX_COST is minimal.
- - memory aliasing support
+ - dead store elimination
+ - a store to the same address as a load does not kill the load if the
+ source of the store is also the destination of the load. Handling this
+ allows more load motion, particularly out of loops.
- ability to realloc sbitmap vectors would allow one initial computation
of reg_set_in_block with only subsequent additions, rather than
recomputing it for each pass
- NOTES
- - the classic gcse implementation is kept in for now for comparison
*/
/* References searched while implementing this.
- This list will eventually be deleted but I wanted to have a record of it
- for now.
Compilers Principles, Techniques and Tools
Aho, Sethi, Ullman
@@ -49,12 +48,6 @@ Boston, MA 02111-1307, USA. */
Frederick Chow
Stanford Ph.D. thesis, Dec. 1983
-xxx
- Elimination Algorithms for Data Flow Analysis
- B.G. Ryder, M.C. Paull
- ACM Computing Surveys, Vol. 18, Num. 3, Sep. 1986
-
-reread
A Fast Algorithm for Code Movement Optimization
D.M. Dhamdhere
SIGPLAN Notices, Vol. 23, Num. 10, Oct. 1988
@@ -74,11 +67,6 @@ reread
R. Cytron, J. Ferrante, B.K. Rosen, M.N. Wegman, and F.K. Zadeck
ACM TOPLAS, Vol. 13, Num. 4, Oct. 1991
-yyy
- How to Analyze Large Programs Efficiently and Informatively
- D.M. Dhamdhere, B.K. Rosen, F.K. Zadeck
- ACM SIGPLAN Notices Vol. 27, Num. 7, Jul. 1992, '92 Conference on PLDI
-
Lazy Code Motion
J. Knoop, O. Ruthing, B. Steffen
ACM SIGPLAN Notices Vol. 27, Num. 7, Jul. 1992, '92 Conference on PLDI
@@ -134,17 +122,27 @@ yyy
Michael Wolfe
Addison-Wesley, 1996
- People wishing to speed up the code here should read xxx, yyy.
+ Advanced Compiler Design and Implementation
+ Steven Muchnick
+ Morgan Kaufmann, 1997
+
+ People wishing to speed up the code here should read:
+ Elimination Algorithms for Data Flow Analysis
+ B.G. Ryder, M.C. Paull
+ ACM Computing Surveys, Vol. 18, Num. 3, Sep. 1986
+
+ How to Analyze Large Programs Efficiently and Informatively
+ D.M. Dhamdhere, B.K. Rosen, F.K. Zadeck
+ ACM SIGPLAN Notices Vol. 27, Num. 7, Jul. 1992, '92 Conference on PLDI
+
People wishing to do something different can find various possibilities
in the above papers and elsewhere.
*/
#include "config.h"
-/* Must precede rtl.h for FFS. */
#include "system.h"
#include "rtl.h"
-#include "function.h"
#include "regs.h"
#include "hard-reg-set.h"
#include "flags.h"
@@ -153,6 +151,7 @@ yyy
#include "recog.h"
#include "basic-block.h"
#include "output.h"
+#include "expr.h"
#include "obstack.h"
#define obstack_chunk_alloc gmalloc
@@ -174,11 +173,10 @@ yyy
heuristics into gcse.c. */
#define FOLLOW_BACK_EDGES 1
-/* We support two GCSE implementations: Classic GCSE (i.e. Dragon Book)
- and PRE (Partial Redundancy Elimination) GCSE (based on Fred Chow's thesis).
- The default is PRE.
+/* We support GCSE via Partial Redundancy Elimination. PRE optimizations
+ are a superset of those done by GCSE.
- In either case we perform the following steps:
+ We perform the following steps:
1) Compute basic block information.
@@ -188,7 +186,7 @@ yyy
4) Perform global cse.
- 5) Perform another pass of copy/constant propagation [only if PRE].
+ 5) Perform another pass of copy/constant propagation.
Two passes of copy/constant propagation are done because the first one
enables more GCSE and the second one helps to clean up the copies that
@@ -202,10 +200,7 @@ yyy
Function want_to_gcse_p says what these are.
PRE handles moving invariant expressions out of loops (by treating them as
- partially redundant). This feature of PRE is disabled here (by not
- propagating dataflow information along back edges) because loop.c has more
- involved (and thus typically better) heuristics for what to move out of
- loops.
+ partially redundant).
Eventually it would be nice to replace cse.c/gcse.c with SSA (static single
assignment) based GVN (global value numbering). L. T. Simpson's paper
@@ -254,7 +249,7 @@ yyy
argue it is not. The number of iterations for the algorithm to converge
is typically 2-4 so I don't view it as that expensive (relatively speaking).
- PRE GCSE depends heavily on the seconds CSE pass to clean up the copies
+ PRE GCSE depends heavily on the second CSE pass to clean up the copies
we create. To make an expression reach the place where it's redundant,
the result of the expression is copied to a new register, and the redundant
expression is deleted by replacing it with this new register. Classic GCSE
@@ -263,35 +258,6 @@ yyy
**********************
- When -fclassic-gcse, we perform a classic global CSE pass.
- It is based on the algorithms in the Dragon book, and is based on code
- written by Devor Tevi at Intel.
-
- The steps for Classic GCSE are:
-
- 1) Build the hash table of expressions we wish to GCSE (expr_hash_table).
- Also recorded are reaching definition "gen" statements (rd_gen)
-
- 2) Compute the reaching definitions (reaching_defs).
- This is a bitmap for each basic block indexed by INSN_CUID that is 1
- for each statement containing a definition that reaches the block.
-
- 3) Compute the available expressions (ae_in).
- This is a bitmap for each basic block indexed by expression number
- that is 1 for each expression that is available at the beginning of
- the block.
-
- 4) Perform GCSE.
- This is done by scanning each instruction looking for sets of the form
- (set (pseudo-reg) (expression)) and checking if `expression' is in the
- hash table. If it is, and if the expression is available, and if only
- one computation of the expression reaches the instruction, we substitute
- the expression for a register containing its value. If there is no
- such register, but the expression is expensive enough we create an
- instruction to copy the result of the expression into and use that.
-
- **********************
-
A fair bit of simplicity is created by creating small functions for simple
tasks, even when the function is only called in one place. This may
measurably slow things down [or may not] by creating more function call
@@ -307,6 +273,23 @@ yyy
/* -dG dump file. */
static FILE *gcse_file;
+/* Note whether or not we should run jump optimization after gcse. We
+ want to do this for two cases.
+
+ * If we changed any jumps via cprop.
+
+ * If we added any labels via edge splitting. */
+
+static int run_jump_opt_after_gcse;
+
+/* Element I is a list of I's predecessors/successors. */
+static int_list_ptr *s_preds;
+static int_list_ptr *s_succs;
+
+/* Element I is the number of predecessors/successors of basic block I. */
+static int *num_preds;
+static int *num_succs;
+
/* Bitmaps are normally not included in debugging dumps.
However it's useful to be able to print them from GDB.
We could create special functions for this, but it's simpler to
@@ -325,14 +308,6 @@ static char can_copy_p[(int) NUM_MACHINE_MODES];
/* Non-zero if can_copy_p has been initialized. */
static int can_copy_init_p;
-/* Element I is a list of I's predecessors/successors. */
-static int_list_ptr *s_preds;
-static int_list_ptr *s_succs;
-
-/* Element I is the number of predecessors/successors of basic block I. */
-static int *num_preds;
-static int *num_succs;
-
/* Hash table of expressions. */
struct expr
@@ -345,8 +320,9 @@ struct expr
struct expr *next_same_hash;
/* List of anticipatable occurrences in basic blocks in the function.
An "anticipatable occurrence" is one that is the first occurrence in the
- basic block and the operands are not modified in the basic block prior
- to the occurrence. */
+ basic block, the operands are not modified in the basic block prior
+ to the occurrence and the output is not used between the start of
+ the block and the occurrence. */
struct occr *antic_occr;
/* List of available occurrence in basic blocks in the function.
An "available occurrence" is one that is the last occurrence in the
@@ -435,11 +411,10 @@ static int n_sets;
For simplicity, GCSE is done on sets of pseudo-regs only. PRE GCSE only
requires knowledge of which blocks kill which regs [and thus could use
- a bitmap instead of the lists `reg_set_table' uses]. The classic GCSE
- uses the information in lists.
+ a bitmap instead of the lists `reg_set_table' uses].
- If the classic GCSE pass is deleted `reg_set_table' and could be turned
- into an array of bitmaps (num-bbs x num-regs)
+ `reg_set_table' and could be turned into an array of bitmaps
+ (num-bbs x num-regs)
[however perhaps it may be useful to keep the data as is].
One advantage of recording things this way is that `reg_set_table' is
fairly sparse with respect to pseudo regs but for hard regs could be
@@ -531,120 +506,114 @@ static sbitmap *rd_kill, *rd_gen, *reaching_defs, *rd_out;
/* for available exprs */
static sbitmap *ae_kill, *ae_gen, *ae_in, *ae_out;
+
-static void compute_can_copy PROTO ((void));
-
-static char *gmalloc PROTO ((unsigned int));
-static char *grealloc PROTO ((char *, unsigned int));
-static char *gcse_alloc PROTO ((unsigned long));
-static void alloc_gcse_mem PROTO ((rtx));
-static void free_gcse_mem PROTO ((void));
-extern void dump_cuid_table PROTO ((FILE *));
-
-static void alloc_reg_set_mem PROTO ((int));
-static void free_reg_set_mem PROTO ((void));
-static void record_one_set PROTO ((int, rtx));
-static void record_set_info PROTO ((rtx, rtx));
-static void compute_sets PROTO ((rtx));
-
-static void hash_scan_insn PROTO ((rtx, int, int));
-static void hash_scan_set PROTO ((rtx, rtx, int));
-static void hash_scan_clobber PROTO ((rtx, rtx));
-static void hash_scan_call PROTO ((rtx, rtx));
-static void maybe_set_rd_gen PROTO ((int, rtx));
-static int want_to_gcse_p PROTO ((rtx));
-static int oprs_unchanged_p PROTO ((rtx, rtx, int));
+static void compute_can_copy PROTO ((void));
+
+static char *gmalloc PROTO ((unsigned int));
+static char *grealloc PROTO ((char *, unsigned int));
+static char *gcse_alloc PROTO ((unsigned long));
+static void alloc_gcse_mem PROTO ((rtx));
+static void free_gcse_mem PROTO ((void));
+static void alloc_reg_set_mem PROTO ((int));
+static void free_reg_set_mem PROTO ((void));
+static void record_one_set PROTO ((int, rtx));
+static void record_set_info PROTO ((rtx, rtx));
+static void compute_sets PROTO ((rtx));
+
+static void hash_scan_insn PROTO ((rtx, int, int));
+static void hash_scan_set PROTO ((rtx, rtx, int));
+static void hash_scan_clobber PROTO ((rtx, rtx));
+static void hash_scan_call PROTO ((rtx, rtx));
+static int want_to_gcse_p PROTO ((rtx));
+static int oprs_unchanged_p PROTO ((rtx, rtx, int));
static int oprs_anticipatable_p PROTO ((rtx, rtx));
-static int oprs_available_p PROTO ((rtx, rtx));
-static void insert_expr_in_table PROTO ((rtx, enum machine_mode, rtx, int, int));
+static int oprs_available_p PROTO ((rtx, rtx));
+static void insert_expr_in_table PROTO ((rtx, enum machine_mode,
+ rtx, int, int));
static void insert_set_in_table PROTO ((rtx, rtx));
-static unsigned int hash_expr PROTO ((rtx, enum machine_mode, int *, int));
+static unsigned int hash_expr PROTO ((rtx, enum machine_mode,
+ int *, int));
static unsigned int hash_expr_1 PROTO ((rtx, enum machine_mode, int *));
-static unsigned int hash_set PROTO ((int, int));
-static int expr_equiv_p PROTO ((rtx, rtx));
+static unsigned int hash_set PROTO ((int, int));
+static int expr_equiv_p PROTO ((rtx, rtx));
static void record_last_reg_set_info PROTO ((rtx, int));
static void record_last_mem_set_info PROTO ((rtx));
static void record_last_set_info PROTO ((rtx, rtx));
-static void compute_hash_table PROTO ((rtx, int));
+static void compute_hash_table PROTO ((int));
static void alloc_set_hash_table PROTO ((int));
static void free_set_hash_table PROTO ((void));
-static void compute_set_hash_table PROTO ((rtx));
+static void compute_set_hash_table PROTO ((void));
static void alloc_expr_hash_table PROTO ((int));
static void free_expr_hash_table PROTO ((void));
-static void compute_expr_hash_table PROTO ((rtx));
-static void dump_hash_table PROTO ((FILE *, char *, struct expr **, int, int));
+static void compute_expr_hash_table PROTO ((void));
+static void dump_hash_table PROTO ((FILE *, const char *, struct expr **,
+ int, int));
static struct expr *lookup_expr PROTO ((rtx));
-static struct expr *lookup_set PROTO ((int, rtx));
-static struct expr *next_set PROTO ((int, struct expr *));
+static struct expr *lookup_set PROTO ((int, rtx));
+static struct expr *next_set PROTO ((int, struct expr *));
static void reset_opr_set_tables PROTO ((void));
-static int oprs_not_set_p PROTO ((rtx, rtx));
-static void mark_call PROTO ((rtx, rtx));
-static void mark_set PROTO ((rtx, rtx));
-static void mark_clobber PROTO ((rtx, rtx));
-static void mark_oprs_set PROTO ((rtx));
-
-static void alloc_rd_mem PROTO ((int, int));
-static void free_rd_mem PROTO ((void));
-static void compute_kill_rd PROTO ((void));
-static void handle_rd_kill_set PROTO ((rtx, int, int));
-static void compute_rd PROTO ((void));
-extern void dump_rd_table PROTO ((FILE *, char *, sbitmap *));
+static int oprs_not_set_p PROTO ((rtx, rtx));
+static void mark_call PROTO ((rtx));
+static void mark_set PROTO ((rtx, rtx));
+static void mark_clobber PROTO ((rtx, rtx));
+static void mark_oprs_set PROTO ((rtx));
+
+static void alloc_cprop_mem PROTO ((int, int));
+static void free_cprop_mem PROTO ((void));
+static void compute_transp PROTO ((rtx, int, sbitmap *, int));
+static void compute_transpout PROTO ((void));
+static void compute_local_properties PROTO ((sbitmap *, sbitmap *,
+ sbitmap *, int));
+static void compute_cprop_avinout PROTO ((void));
+static void compute_cprop_data PROTO ((void));
+static void find_used_regs PROTO ((rtx));
+static int try_replace_reg PROTO ((rtx, rtx, rtx));
+static struct expr *find_avail_set PROTO ((int, rtx));
+static int cprop_insn PROTO ((rtx, int));
+static int cprop PROTO ((int));
+static int one_cprop_pass PROTO ((int, int));
+
+static void alloc_pre_mem PROTO ((int, int));
+static void free_pre_mem PROTO ((void));
+static void compute_pre_data PROTO ((void));
+static int pre_expr_reaches_here_p PROTO ((int, struct expr *,
+ int, int, char *));
+static void insert_insn_end_bb PROTO ((struct expr *, int, int));
+static void pre_insert PROTO ((struct expr **));
+static void pre_insert_copy_insn PROTO ((struct expr *, rtx));
+static void pre_insert_copies PROTO ((void));
+static int pre_delete PROTO ((void));
+static int pre_gcse PROTO ((void));
+static int one_pre_gcse_pass PROTO ((int));
+static void add_label_notes PROTO ((rtx, rtx));
+
+static void alloc_rd_mem PROTO ((int, int));
+static void free_rd_mem PROTO ((void));
+static void handle_rd_kill_set PROTO ((rtx, int, int));
+static void compute_kill_rd PROTO ((void));
+static void compute_rd PROTO ((void));
static void alloc_avail_expr_mem PROTO ((int, int));
static void free_avail_expr_mem PROTO ((void));
-static void compute_ae_gen PROTO ((void));
-static void compute_ae_kill PROTO ((void));
-static int expr_killed_p PROTO ((rtx, int));
-static void compute_available PROTO ((void));
-
-static int expr_reaches_here_p PROTO ((struct occr *, struct expr *,
+static void compute_ae_gen PROTO ((void));
+static int expr_killed_p PROTO ((rtx, int));
+static void compute_ae_kill PROTO ((void));
+static void compute_available PROTO ((void));
+static int expr_reaches_here_p PROTO ((struct occr *, struct expr *,
int, int, char *));
-static rtx computing_insn PROTO ((struct expr *, rtx));
-static int def_reaches_here_p PROTO ((rtx, rtx));
+static rtx computing_insn PROTO ((struct expr *, rtx));
+static int def_reaches_here_p PROTO ((rtx, rtx));
static int can_disregard_other_sets PROTO ((struct reg_set **, rtx, int));
-static int handle_avail_expr PROTO ((rtx, struct expr *));
-static int classic_gcse PROTO ((void));
-static int one_classic_gcse_pass PROTO ((rtx, int));
-
-static void alloc_cprop_mem PROTO ((int, int));
-static void free_cprop_mem PROTO ((void));
-extern void dump_cprop_data PROTO ((FILE *));
-static void compute_transp PROTO ((rtx, int, sbitmap *, int));
-static void compute_cprop_local_properties PROTO ((void));
-static void compute_cprop_avinout PROTO ((void));
-static void compute_cprop_data PROTO ((void));
-static void find_used_regs PROTO ((rtx));
-static int try_replace_reg PROTO ((rtx, rtx, rtx));
-static struct expr *find_avail_set PROTO ((int, rtx));
-static int cprop_insn PROTO ((rtx));
-static int cprop PROTO ((void));
-static int one_cprop_pass PROTO ((rtx, int));
-
-static void alloc_pre_mem PROTO ((int, int));
-static void free_pre_mem PROTO ((void));
-extern void dump_pre_data PROTO ((FILE *));
-static void compute_pre_local_properties PROTO ((void));
-static void compute_pre_avinout PROTO ((void));
-static void compute_pre_antinout PROTO ((void));
-static void compute_pre_pavinout PROTO ((void));
-static void compute_pre_ppinout PROTO ((void));
-static void compute_pre_data PROTO ((void));
-static int pre_expr_reaches_here_p PROTO ((struct occr *, struct expr *,
- int, char *));
-static void pre_insert_insn PROTO ((struct expr *, int));
-static void pre_insert PROTO ((struct expr **));
-static void pre_insert_copy_insn PROTO ((struct expr *, rtx));
-static void pre_insert_copies PROTO ((void));
-static int pre_delete PROTO ((void));
-static int pre_gcse PROTO ((void));
-static int one_pre_gcse_pass PROTO ((rtx, int));
+static int handle_avail_expr PROTO ((rtx, struct expr *));
+static int classic_gcse PROTO ((void));
+static int one_classic_gcse_pass PROTO ((int));
-static void add_label_notes PROTO ((rtx, rtx));
/* Entry point for global common subexpression elimination.
F is the first instruction in the function. */
-void
+int
gcse_main (f, file)
rtx f;
FILE *file;
@@ -657,23 +626,29 @@ gcse_main (f, file)
/* Point to release obstack data from for each pass. */
char *gcse_obstack_bottom;
- /* It's impossible to construct a correct control flow graph in the
- presense of setjmp, so just punt to be safe. */
+ /* We do not construct an accurate cfg in functions which call
+ setjmp, so just punt to be safe. */
if (current_function_calls_setjmp)
- return;
+ return 0;
+ /* Assume that we do not need to run jump optimizations after gcse. */
+ run_jump_opt_after_gcse = 0;
+
/* For calling dump_foo fns from gdb. */
debug_stderr = stderr;
+ gcse_file = file;
+ /* Identify the basic block information for this function, including
+ successors and predecessors. */
max_gcse_regno = max_reg_num ();
- find_basic_blocks (f, max_gcse_regno, file, 0);
+ find_basic_blocks (f, max_gcse_regno, file);
/* Return if there's nothing to do. */
if (n_basic_blocks <= 1)
{
/* Free storage allocated by find_basic_blocks. */
free_basic_block_vars (0);
- return;
+ return 0;
}
/* See what modes support reg/reg copy operations. */
@@ -685,8 +660,6 @@ gcse_main (f, file)
gcc_obstack_init (&gcse_obstack);
- gcse_file = file;
-
/* Allocate and compute predecessors/successors. */
s_preds = (int_list_ptr *) alloca (n_basic_blocks * sizeof (int_list_ptr));
@@ -697,15 +670,17 @@ gcse_main (f, file)
compute_preds_succs (s_preds, s_succs, num_preds, num_succs);
if (file)
- {
- dump_bb_data (file, s_preds, s_succs);
- }
+ dump_bb_data (file, s_preds, s_succs, 0);
/* Record where pseudo-registers are set.
This data is kept accurate during each pass.
- ??? We could also record hard-reg and memory information here
+ ??? We could also record hard-reg information here
[since it's unchanging], however it is currently done during
- hash table computation. */
+ hash table computation.
+
+ It may be tempting to compute MEM set information here too, but MEM
+ sets will be subject to code motion one day and thus we need to compute
+ information about memory sets when we build the hash tables. */
alloc_reg_set_mem (max_gcse_regno);
compute_sets (f);
@@ -730,12 +705,14 @@ gcse_main (f, file)
alloc_gcse_mem (f);
- changed = one_cprop_pass (f, pass + 1);
+ /* Don't allow constant propagation to modify jumps
+ during this pass. */
+ changed = one_cprop_pass (pass + 1, 0);
if (optimize_size)
- changed |= one_classic_gcse_pass (f, pass + 1);
+ changed |= one_classic_gcse_pass (pass + 1);
else
- changed |= one_pre_gcse_pass (f, pass + 1);
+ changed |= one_pre_gcse_pass (pass + 1);
if (max_pass_bytes < bytes_used)
max_pass_bytes = bytes_used;
@@ -751,14 +728,14 @@ gcse_main (f, file)
pass++;
}
- /* If we're doing PRE, do one last pass of copy propagation. */
- if (! optimize_size)
- {
- max_gcse_regno = max_reg_num ();
- alloc_gcse_mem (f);
- one_cprop_pass (f, pass + 1);
- free_gcse_mem ();
- }
+ /* Do one last pass of copy propagation, including cprop into
+ conditional jumps. */
+
+ max_gcse_regno = max_reg_num ();
+ alloc_gcse_mem (f);
+ /* This time, go ahead and allow cprop to alter jumps. */
+ one_cprop_pass (pass + 1, 1);
+ free_gcse_mem ();
if (file)
{
@@ -776,6 +753,7 @@ gcse_main (f, file)
free_bb_mem ();
/* Free storage allocated by find_basic_blocks. */
free_basic_block_vars (0);
+ return run_jump_opt_after_gcse;
}
/* Misc. utilities. */
@@ -920,23 +898,113 @@ free_gcse_mem ()
free (mem_set_in_block);
}
-void
-dump_cuid_table (file)
- FILE *file;
-{
- int i,n;
+
+/* Compute the local properties of each recorded expression.
+ Local properties are those that are defined by the block, irrespective
+ of other blocks.
+
+ An expression is transparent in a block if its operands are not modified
+ in the block.
+
+ An expression is computed (locally available) in a block if it is computed
+ at least once and expression would contain the same value if the
+ computation was moved to the end of the block.
+
+ An expression is locally anticipatable in a block if it is computed at
+ least once and expression would contain the same value if the computation
+ was moved to the beginning of the block.
- fprintf (file, "CUID table\n");
- for (i = n = 0; i < max_cuid; i++)
+ We call this routine for cprop, pre and code hoisting. They all
+ compute basically the same information and thus can easily share
+ this code.
+
+ TRANSP, COMP, and ANTLOC are destination sbitmaps for recording
+ local properties. If NULL, then it is not necessary to compute
+ or record that particular property.
+
+ SETP controls which hash table to look at. If zero, this routine
+ looks at the expr hash table; if nonzero this routine looks at
+ the set hash table. */
+
+static void
+compute_local_properties (transp, comp, antloc, setp)
+ sbitmap *transp;
+ sbitmap *comp;
+ sbitmap *antloc;
+ int setp;
+{
+ int i, hash_table_size;
+ struct expr **hash_table;
+
+ /* Initialize any bitmaps that were passed in. */
+ if (transp)
+ sbitmap_vector_ones (transp, n_basic_blocks);
+ if (comp)
+ sbitmap_vector_zero (comp, n_basic_blocks);
+ if (antloc)
+ sbitmap_vector_zero (antloc, n_basic_blocks);
+
+ /* We use the same code for cprop, pre and hoisting. For cprop
+ we care about the set hash table, for pre and hoisting we
+ care about the expr hash table. */
+ hash_table_size = setp ? set_hash_table_size : expr_hash_table_size;
+ hash_table = setp ? set_hash_table : expr_hash_table;
+
+ for (i = 0; i < hash_table_size; i++)
{
- rtx insn = CUID_INSN (i);
- if (n != 0 && n % 10 == 0)
- fprintf (file, "\n");
- if (insn != NULL)
- fprintf (file, " %d", INSN_UID (insn));
+ struct expr *expr;
+
+ for (expr = hash_table[i]; expr != NULL; expr = expr->next_same_hash)
+ {
+ struct occr *occr;
+ int indx = expr->bitmap_index;
+
+ /* The expression is transparent in this block if it is not killed.
+ We start by assuming all are transparent [none are killed], and
+ then reset the bits for those that are. */
+
+ if (transp)
+ compute_transp (expr->expr, indx, transp, setp);
+
+ /* The occurrences recorded in antic_occr are exactly those that
+ we want to set to non-zero in ANTLOC. */
+
+ if (antloc)
+ {
+ for (occr = expr->antic_occr; occr != NULL; occr = occr->next)
+ {
+ int bb = BLOCK_NUM (occr->insn);
+ SET_BIT (antloc[bb], indx);
+
+ /* While we're scanning the table, this is a good place to
+ initialize this. */
+ occr->deleted_p = 0;
+ }
+ }
+
+ /* The occurrences recorded in avail_occr are exactly those that
+ we want to set to non-zero in COMP. */
+ if (comp)
+ {
+
+ for (occr = expr->avail_occr; occr != NULL; occr = occr->next)
+ {
+ int bb = BLOCK_NUM (occr->insn);
+ SET_BIT (comp[bb], indx);
+
+ /* While we're scanning the table, this is a good place to
+ initialize this. */
+ occr->copied_p = 0;
+ }
+ }
+
+ /* While we're scanning the table, this is a good place to
+ initialize this. */
+ expr->reaching_reg = 0;
+ }
}
- fprintf (file, "\n\n");
}
+
/* Register set information.
@@ -1068,18 +1136,6 @@ static int *reg_last_set;
static int mem_first_set;
static int mem_last_set;
-/* Set the appropriate bit in `rd_gen' [the gen for reaching defs] if the
- register set in this insn is not set after this insn in this block. */
-
-static void
-maybe_set_rd_gen (regno, insn)
- int regno;
- rtx insn;
-{
- if (reg_last_set[regno] <= INSN_CUID (insn))
- SET_BIT (rd_gen[BLOCK_NUM (insn)], INSN_CUID (insn));
-}
-
/* Perform a quick check whether X, the source of a set, is something
we want to consider for GCSE. */
@@ -1798,7 +1854,8 @@ hash_scan_set (pat, insn, set_p)
&& REGNO (src) >= FIRST_PSEUDO_REGISTER
&& can_copy_p [GET_MODE (dest)])
/* ??? CONST_INT:wip */
- || GET_CODE (src) == CONST_INT)
+ || GET_CODE (src) == CONST_INT
+ || GET_CODE (src) == CONST_DOUBLE)
/* A copy is not available if its src or dest is subsequently
modified. Here we want to search from INSN+1 on, but
oprs_available_p searches from INSN on. */
@@ -1807,22 +1864,6 @@ hash_scan_set (pat, insn, set_p)
&& oprs_available_p (pat, tmp))))
insert_set_in_table (pat, insn);
}
-
- /* Check if first/last set in this block for classic gcse,
- but not for copy/constant propagation. */
- if (optimize_size && !set_p)
-
- {
- rtx dest = SET_DEST (pat);
-
- while (GET_CODE (dest) == SUBREG
- || GET_CODE (dest) == ZERO_EXTRACT
- || GET_CODE (dest) == SIGN_EXTRACT
- || GET_CODE (dest) == STRICT_LOW_PART)
- dest = XEXP (dest, 0);
- if (GET_CODE (dest) == REG)
- maybe_set_rd_gen (REGNO (dest), insn);
- }
}
static void
@@ -1877,21 +1918,6 @@ hash_scan_insn (insn, set_p, in_libcall_block)
{
if (GET_CODE (SET_SRC (x)) == CALL)
hash_scan_call (SET_SRC (x), insn);
-
- /* Check if first/last set in this block for classic
- gcse, but not for constant/copy propagation. */
- if (optimize_size && !set_p)
- {
- rtx dest = SET_DEST (x);
-
- while (GET_CODE (dest) == SUBREG
- || GET_CODE (dest) == ZERO_EXTRACT
- || GET_CODE (dest) == SIGN_EXTRACT
- || GET_CODE (dest) == STRICT_LOW_PART)
- dest = XEXP (dest, 0);
- if (GET_CODE (dest) == REG)
- maybe_set_rd_gen (REGNO (dest), insn);
- }
}
else if (GET_CODE (x) == CLOBBER)
hash_scan_clobber (x, insn);
@@ -1908,7 +1934,7 @@ hash_scan_insn (insn, set_p, in_libcall_block)
static void
dump_hash_table (file, name, table, table_size, total_size)
FILE *file;
- char *name;
+ const char *name;
struct expr **table;
int table_size, total_size;
{
@@ -2014,8 +2040,7 @@ record_last_set_info (dest, setter)
SET_P is non-zero for computing the assignment hash table. */
static void
-compute_hash_table (f, set_p)
- rtx f ATTRIBUTE_UNUSED;
+compute_hash_table (set_p)
int set_p;
{
int bb;
@@ -2052,8 +2077,8 @@ compute_hash_table (f, set_p)
mem_first_set = NEVER_SET;
mem_last_set = NEVER_SET;
- for (insn = basic_block_head[bb];
- insn && insn != NEXT_INSN (basic_block_end[bb]);
+ for (insn = BLOCK_HEAD (bb);
+ insn && insn != NEXT_INSN (BLOCK_END (bb));
insn = NEXT_INSN (insn))
{
#ifdef NON_SAVING_SETJMP
@@ -2072,7 +2097,20 @@ compute_hash_table (f, set_p)
if (GET_CODE (insn) == CALL_INSN)
{
for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
- if (call_used_regs[regno])
+ if ((call_used_regs[regno]
+ && regno != STACK_POINTER_REGNUM
+#if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM
+ && regno != HARD_FRAME_POINTER_REGNUM
+#endif
+#if ARG_POINTER_REGNUM != FRAME_POINTER_REGNUM
+ && ! (regno == ARG_POINTER_REGNUM && fixed_regs[regno])
+#endif
+#if defined (PIC_OFFSET_TABLE_REGNUM) && !defined (PIC_OFFSET_TABLE_REG_CALL_CLOBBERED)
+ && ! (regno == PIC_OFFSET_TABLE_REGNUM && flag_pic)
+#endif
+
+ && regno != FRAME_POINTER_REGNUM)
+ || global_regs[regno])
record_last_reg_set_info (insn, regno);
if (! CONST_CALL_P (insn))
record_last_mem_set_info (insn);
@@ -2084,8 +2122,8 @@ compute_hash_table (f, set_p)
/* The next pass builds the hash table. */
- for (insn = basic_block_head[bb], in_libcall_block = 0;
- insn && insn != NEXT_INSN (basic_block_end[bb]);
+ for (insn = BLOCK_HEAD (bb), in_libcall_block = 0;
+ insn && insn != NEXT_INSN (BLOCK_END (bb));
insn = NEXT_INSN (insn))
{
if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
@@ -2137,14 +2175,13 @@ free_set_hash_table ()
/* Compute the hash table for doing copy/const propagation. */
static void
-compute_set_hash_table (f)
- rtx f;
+compute_set_hash_table ()
{
/* Initialize count of number of entries in hash table. */
n_sets = 0;
bzero ((char *) set_hash_table, set_hash_table_size * sizeof (struct expr *));
- compute_hash_table (f, 1);
+ compute_hash_table (1);
}
/* Allocate space for the expression hash table.
@@ -2180,14 +2217,13 @@ free_expr_hash_table ()
/* Compute the hash table for doing GCSE. */
static void
-compute_expr_hash_table (f)
- rtx f;
+compute_expr_hash_table ()
{
/* Initialize count of number of entries in hash table. */
n_exprs = 0;
bzero ((char *) expr_hash_table, expr_hash_table_size * sizeof (struct expr *));
- compute_hash_table (f, 0);
+ compute_hash_table (0);
}
/* Expression tracking support. */
@@ -2352,8 +2388,8 @@ repeat:
/* Mark things set by a CALL. */
static void
-mark_call (pat, insn)
- rtx pat ATTRIBUTE_UNUSED, insn;
+mark_call (insn)
+ rtx insn;
{
mem_last_set = INSN_CUID (insn);
}
@@ -2378,7 +2414,7 @@ mark_set (pat, insn)
mem_last_set = INSN_CUID (insn);
if (GET_CODE (SET_SRC (pat)) == CALL)
- mark_call (SET_SRC (pat), insn);
+ mark_call (insn);
}
/* Record things set by a CLOBBER. */
@@ -2422,14 +2458,15 @@ mark_oprs_set (insn)
else if (GET_CODE (x) == CLOBBER)
mark_clobber (x, insn);
else if (GET_CODE (x) == CALL)
- mark_call (x, insn);
+ mark_call (insn);
}
}
else if (GET_CODE (pat) == CLOBBER)
mark_clobber (pat, insn);
else if (GET_CODE (pat) == CALL)
- mark_call (pat, insn);
+ mark_call (insn);
}
+
/* Classic GCSE reaching definition support. */
@@ -2481,38 +2518,6 @@ handle_rd_kill_set (insn, regno, bb)
}
}
-void
-dump_rd_table (file, title, bmap)
- FILE *file;
- char *title;
- sbitmap *bmap;
-{
- int bb,cuid,i,j,n;
-
- fprintf (file, "%s\n", title);
- for (bb = 0; bb < n_basic_blocks; bb++)
- {
- fprintf (file, "BB %d\n", bb);
- dump_sbitmap (file, bmap[bb]);
- for (i = n = cuid = 0; i < bmap[bb]->size; i++)
- {
- for (j = 0; j < SBITMAP_ELT_BITS; j++, cuid++)
- {
- if ((bmap[bb]->elms[i] & (1 << j)) != 0)
- {
- if (n % 10 == 0)
- fprintf (file, " ");
- fprintf (file, " %d", INSN_UID (CUID_INSN (cuid)));
- n++;
- }
- }
- }
- if (n != 0)
- fprintf (file, "\n");
- }
- fprintf (file, "\n");
-}
-
/* Compute the set of kill's for reaching definitions. */
static void
@@ -2522,12 +2527,12 @@ compute_kill_rd ()
/* For each block
For each set bit in `gen' of the block (i.e each insn which
- generates a definition in the block)
- Call the reg set by the insn corresponding to that bit regx
- Look at the linked list starting at reg_set_table[regx]
- For each setting of regx in the linked list, which is not in
- this block
- Set the bit in `kill' corresponding to that insn
+ generates a definition in the block)
+ Call the reg set by the insn corresponding to that bit regx
+ Look at the linked list starting at reg_set_table[regx]
+ For each setting of regx in the linked list, which is not in
+ this block
+ Set the bit in `kill' corresponding to that insn
*/
for (bb = 0; bb < n_basic_blocks; bb++)
@@ -2535,20 +2540,33 @@ compute_kill_rd ()
for (cuid = 0; cuid < max_cuid; cuid++)
{
if (TEST_BIT (rd_gen[bb], cuid))
- {
+ {
rtx insn = CUID_INSN (cuid);
rtx pat = PATTERN (insn);
if (GET_CODE (insn) == CALL_INSN)
- {
+ {
int regno;
for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
- {
- if (call_used_regs[regno])
+ {
+ if ((call_used_regs[regno]
+ && regno != STACK_POINTER_REGNUM
+#if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM
+ && regno != HARD_FRAME_POINTER_REGNUM
+#endif
+#if ARG_POINTER_REGNUM != FRAME_POINTER_REGNUM
+ && ! (regno == ARG_POINTER_REGNUM
+ && fixed_regs[regno])
+#endif
+#if defined (PIC_OFFSET_TABLE_REGNUM) && !defined (PIC_OFFSET_TABLE_REG_CALL_CLOBBERED)
+ && ! (regno == PIC_OFFSET_TABLE_REGNUM && flag_pic)
+#endif
+ && regno != FRAME_POINTER_REGNUM)
+ || global_regs[regno])
handle_rd_kill_set (insn, regno, bb);
- }
- }
+ }
+ }
if (GET_CODE (pat) == PARALLEL)
{
@@ -2573,9 +2591,9 @@ compute_kill_rd ()
must be marked in the set of kills in this block. */
handle_rd_kill_set (insn, REGNO (SET_DEST (pat)), bb);
}
- }
+ }
/* FIXME: CLOBBER? */
- }
+ }
}
}
}
@@ -2599,12 +2617,12 @@ compute_rd ()
{
changed = 0;
for (bb = 0; bb < n_basic_blocks; bb++)
- {
+ {
sbitmap_union_of_predecessors (reaching_defs[bb], rd_out,
bb, s_preds);
changed |= sbitmap_union_of_diff (rd_out[bb], rd_gen[bb],
reaching_defs[bb], rd_kill[bb]);
- }
+ }
passes++;
}
@@ -2801,8 +2819,7 @@ compute_available ()
changed = 0;
for (bb = 1; bb < n_basic_blocks; bb++)
{
- sbitmap_intersect_of_predecessors (ae_in[bb], ae_out,
- bb, s_preds);
+ sbitmap_intersect_of_predecessors (ae_in[bb], ae_out, bb, s_preds);
changed |= sbitmap_union_of_diff (ae_out[bb], ae_gen[bb],
ae_in[bb], ae_kill[bb]);
}
@@ -2852,20 +2869,20 @@ expr_reaches_here_p (occr, expr, bb, check_self_loop, visited)
int pred_bb = INT_LIST_VAL (pred);
if (visited[pred_bb])
- {
+ {
/* This predecessor has already been visited.
Nothing to do. */
;
}
else if (pred_bb == bb)
- {
+ {
/* BB loops on itself. */
if (check_self_loop
&& TEST_BIT (ae_gen[pred_bb], expr->bitmap_index)
&& BLOCK_NUM (occr->insn) == pred_bb)
return 1;
visited[pred_bb] = 1;
- }
+ }
/* Ignore this predecessor if it kills the expression. */
else if (TEST_BIT (ae_kill[pred_bb], expr->bitmap_index))
visited[pred_bb] = 1;
@@ -2881,11 +2898,11 @@ expr_reaches_here_p (occr, expr, bb, check_self_loop, visited)
}
/* Neither gen nor kill. */
else
- {
+ {
visited[pred_bb] = 1;
if (expr_reaches_here_p (occr, expr, pred_bb, check_self_loop, visited))
return 1;
- }
+ }
}
/* All paths have been checked. */
@@ -2977,7 +2994,7 @@ def_reaches_here_p (insn, def_insn)
if (BLOCK_NUM (insn) == BLOCK_NUM (def_insn))
{
if (INSN_CUID (def_insn) < INSN_CUID (insn))
- {
+ {
if (GET_CODE (PATTERN (def_insn)) == PARALLEL)
return 1;
if (GET_CODE (PATTERN (def_insn)) == CLOBBER)
@@ -3160,13 +3177,13 @@ handle_avail_expr (insn, expr)
gcse_create_count++;
if (gcse_file != NULL)
- {
+ {
fprintf (gcse_file, "GCSE: Creating insn %d to copy value of reg %d, computed in insn %d,\n",
INSN_UID (NEXT_INSN (insn_computes_expr)),
REGNO (SET_SRC (PATTERN (NEXT_INSN (insn_computes_expr)))),
INSN_UID (insn_computes_expr));
fprintf (gcse_file, " into newly allocated reg %d\n", REGNO (to));
- }
+ }
pat = PATTERN (insn);
@@ -3215,8 +3232,8 @@ classic_gcse ()
start of the block]. */
reset_opr_set_tables ();
- for (insn = basic_block_head[bb];
- insn != NULL && insn != NEXT_INSN (basic_block_end[bb]);
+ for (insn = BLOCK_HEAD (bb);
+ insn != NULL && insn != NEXT_INSN (BLOCK_END (bb));
insn = NEXT_INSN (insn))
{
/* Is insn of form (set (pseudo-reg) ...)? */
@@ -3246,7 +3263,7 @@ classic_gcse ()
/* ??? Need to be careful w.r.t. mods done to INSN. */
if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
mark_oprs_set (insn);
- }
+ }
}
return changed;
@@ -3257,8 +3274,7 @@ classic_gcse ()
Return non-zero if a change was made. */
static int
-one_classic_gcse_pass (f, pass)
- rtx f;
+one_classic_gcse_pass (pass)
int pass;
{
int changed = 0;
@@ -3268,7 +3284,7 @@ one_classic_gcse_pass (f, pass)
alloc_expr_hash_table (max_cuid);
alloc_rd_mem (n_basic_blocks, max_cuid);
- compute_expr_hash_table (f);
+ compute_expr_hash_table ();
if (gcse_file)
dump_hash_table (gcse_file, "Expression", expr_hash_table,
expr_hash_table_size, n_exprs);
@@ -3335,23 +3351,6 @@ free_cprop_mem ()
free (cprop_avout);
}
-/* Dump copy/const propagation data. */
-
-void
-dump_cprop_data (file)
- FILE *file;
-{
- dump_sbitmap_vector (file, "CPROP partially locally available sets", "BB",
- cprop_pavloc, n_basic_blocks);
- dump_sbitmap_vector (file, "CPROP absolutely altered sets", "BB",
- cprop_absaltered, n_basic_blocks);
-
- dump_sbitmap_vector (file, "CPROP available incoming sets", "BB",
- cprop_avin, n_basic_blocks);
- dump_sbitmap_vector (file, "CPROP available outgoing sets", "BB",
- cprop_avout, n_basic_blocks);
-}
-
/* For each block, compute whether X is transparent.
X is either an expression or an assignment [though we don't care which,
for this context an assignment is treated as an expression].
@@ -3478,42 +3477,11 @@ compute_transp (x, indx, bmap, set_p)
}
}
-static void
-compute_cprop_local_properties ()
-{
- int i;
-
- sbitmap_vector_zero (cprop_absaltered, n_basic_blocks);
- sbitmap_vector_zero (cprop_pavloc, n_basic_blocks);
-
- for (i = 0; i < set_hash_table_size; i++)
- {
- struct expr *expr;
-
- for (expr = set_hash_table[i]; expr != NULL; expr = expr->next_same_hash)
- {
- struct occr *occr;
- int indx = expr->bitmap_index;
-
- /* The assignment is absolutely altered if any operand is modified
- by this block [excluding the assignment itself].
- We start by assuming all are transparent [none are killed], and
- then setting the bits for those that are. */
-
- compute_transp (expr->expr, indx, cprop_absaltered, 1);
-
- /* The occurrences recorded in avail_occr are exactly those that
- we want to set to non-zero in PAVLOC. */
-
- for (occr = expr->avail_occr; occr != NULL; occr = occr->next)
- {
- int bb = BLOCK_NUM (occr->insn);
- SET_BIT (cprop_pavloc[bb], indx);
- }
- }
- }
-}
-
+/* Compute the available expressions at the start and end of each
+ basic block for cprop. This particular dataflow equation is
+ used often enough that we might want to generalize it and make
+ as a subroutine for other global optimizations that need available
+ in/out information. */
static void
compute_cprop_avinout ()
{
@@ -3528,10 +3496,10 @@ compute_cprop_avinout ()
{
changed = 0;
for (bb = 0; bb < n_basic_blocks; bb++)
- {
+ {
if (bb != 0)
- sbitmap_intersect_of_predecessors (cprop_avin[bb], cprop_avout,
- bb, s_preds);
+ sbitmap_intersect_of_predecessors (cprop_avin[bb],
+ cprop_avout, bb, s_preds);
changed |= sbitmap_union_of_diff (cprop_avout[bb],
cprop_pavloc[bb],
cprop_avin[bb],
@@ -3550,7 +3518,7 @@ compute_cprop_avinout ()
static void
compute_cprop_data ()
{
- compute_cprop_local_properties ();
+ compute_local_properties (cprop_absaltered, cprop_pavloc, NULL, 1);
compute_cprop_avinout ();
}
@@ -3662,6 +3630,11 @@ static int
try_replace_reg (from, to, insn)
rtx from, to, insn;
{
+ /* If this fails we could try to simplify the result of the
+ replacement and attempt to recognize the simplified insn.
+
+ But we need a general simplify_rtx that doesn't have pass
+ specific state variables. I'm not aware of one at the moment. */
return validate_replace_src (from, to, insn);
}
@@ -3689,14 +3662,17 @@ find_avail_set (regno, insn)
The result is non-zero if a change was made. */
static int
-cprop_insn (insn)
+cprop_insn (insn, alter_jumps)
rtx insn;
+ int alter_jumps;
{
struct reg_use *reg_used;
int changed = 0;
- /* ??? For now only propagate into SETs. */
- if (GET_CODE (insn) != INSN
+ /* Only propagate into SETs. Note that a conditional jump is a
+ SET with pc_rtx as the destination. */
+ if ((GET_CODE (insn) != INSN
+ && GET_CODE (insn) != JUMP_INSN)
|| GET_CODE (PATTERN (insn)) != SET)
return 0;
@@ -3732,9 +3708,12 @@ cprop_insn (insn)
abort ();
src = SET_SRC (pat);
- if (GET_CODE (src) == CONST_INT)
+ /* Constant propagation. */
+ if (GET_CODE (src) == CONST_INT || GET_CODE (src) == CONST_DOUBLE)
{
- if (try_replace_reg (reg_used->reg_rtx, src, insn))
+ /* Handle normal insns first. */
+ if (GET_CODE (insn) == INSN
+ && try_replace_reg (reg_used->reg_rtx, src, insn))
{
changed = 1;
const_prop_count++;
@@ -3742,13 +3721,91 @@ cprop_insn (insn)
{
fprintf (gcse_file, "CONST-PROP: Replacing reg %d in insn %d with constant ",
regno, INSN_UID (insn));
- fprintf (gcse_file, HOST_WIDE_INT_PRINT_DEC, INTVAL (src));
+ print_rtl (gcse_file, src);
fprintf (gcse_file, "\n");
}
/* The original insn setting reg_used may or may not now be
deletable. We leave the deletion to flow. */
}
+
+ /* Try to propagate a CONST_INT into a conditional jump.
+ We're pretty specific about what we will handle in this
+ code, we can extend this as necessary over time.
+
+ Right now the insn in question must look like
+
+ (set (pc) (if_then_else ...))
+
+ Note this does not currently handle machines which use cc0. */
+ else if (alter_jumps
+ && GET_CODE (insn) == JUMP_INSN && condjump_p (insn))
+ {
+ /* We want a copy of the JUMP_INSN so we can modify it
+ in-place as needed without effecting the original. */
+ rtx copy = copy_rtx (insn);
+ rtx set = PATTERN (copy);
+ rtx temp;
+
+ /* Replace the register with the appropriate constant. */
+ replace_rtx (SET_SRC (set), reg_used->reg_rtx, src);
+
+ temp = simplify_ternary_operation (GET_CODE (SET_SRC (set)),
+ GET_MODE (SET_SRC (set)),
+ GET_MODE (XEXP (SET_SRC (set), 0)),
+ XEXP (SET_SRC (set), 0),
+ XEXP (SET_SRC (set), 1),
+ XEXP (SET_SRC (set), 2));
+
+ /* If no simplification can be made, then try the next
+ register. */
+ if (temp)
+ SET_SRC (set) = temp;
+ else
+ continue;
+
+ /* That may have changed the structure of TEMP, so
+ force it to be rerecognized if it has not turned
+ into a nop or unconditional jump. */
+
+ INSN_CODE (copy) = -1;
+ if ((SET_DEST (set) == pc_rtx
+ && (SET_SRC (set) == pc_rtx
+ || GET_CODE (SET_SRC (set)) == LABEL_REF))
+ || recog (PATTERN (copy), copy, NULL) >= 0)
+ {
+ /* This has either become an unconditional jump
+ or a nop-jump. We'd like to delete nop jumps
+ here, but doing so confuses gcse. So we just
+ make the replacement and let later passes
+ sort things out. */
+ PATTERN (insn) = set;
+ INSN_CODE (insn) = -1;
+
+ /* One less use of the label this insn used to jump to
+ if we turned this into a NOP jump. */
+ if (SET_SRC (set) == pc_rtx && JUMP_LABEL (insn) != 0)
+ --LABEL_NUSES (JUMP_LABEL (insn));
+
+ /* If this has turned into an unconditional jump,
+ then put a barrier after it so that the unreachable
+ code will be deleted. */
+ if (GET_CODE (SET_SRC (set)) == LABEL_REF)
+ emit_barrier_after (insn);
+
+ run_jump_opt_after_gcse = 1;
+
+ changed = 1;
+ const_prop_count++;
+ if (gcse_file != NULL)
+ {
+ fprintf (gcse_file, "CONST-PROP: Replacing reg %d in insn %d with constant ",
+ regno, INSN_UID (insn));
+ print_rtl (gcse_file, src);
+ fprintf (gcse_file, "\n");
+ }
+ }
+ }
}
else if (GET_CODE (src) == REG
&& REGNO (src) >= FIRST_PSEUDO_REGISTER
@@ -3787,7 +3844,8 @@ cprop_insn (insn)
Return non-zero if a change was made. */
static int
-cprop ()
+cprop (alter_jumps)
+ int alter_jumps;
{
int bb, changed;
rtx insn;
@@ -3801,19 +3859,19 @@ cprop ()
start of the block]. */
reset_opr_set_tables ();
- for (insn = basic_block_head[bb];
- insn != NULL && insn != NEXT_INSN (basic_block_end[bb]);
+ for (insn = BLOCK_HEAD (bb);
+ insn != NULL && insn != NEXT_INSN (BLOCK_END (bb));
insn = NEXT_INSN (insn))
{
if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
{
- changed |= cprop_insn (insn);
+ changed |= cprop_insn (insn, alter_jumps);
/* Keep track of everything modified by this insn. */
/* ??? Need to be careful w.r.t. mods done to INSN. */
mark_oprs_set (insn);
}
- }
+ }
}
if (gcse_file != NULL)
@@ -3827,9 +3885,9 @@ cprop ()
PASS is the pass count. */
static int
-one_cprop_pass (f, pass)
- rtx f;
+one_cprop_pass (pass, alter_jumps)
int pass;
+ int alter_jumps;
{
int changed = 0;
@@ -3837,7 +3895,7 @@ one_cprop_pass (f, pass)
copy_prop_count = 0;
alloc_set_hash_table (max_cuid);
- compute_set_hash_table (f);
+ compute_set_hash_table ();
if (gcse_file)
dump_hash_table (gcse_file, "SET", set_hash_table, set_hash_table_size,
n_sets);
@@ -3845,7 +3903,7 @@ one_cprop_pass (f, pass)
{
alloc_cprop_mem (n_basic_blocks, n_sets);
compute_cprop_data ();
- changed = cprop ();
+ changed = cprop (alter_jumps);
free_cprop_mem ();
}
free_set_hash_table ();
@@ -3861,446 +3919,63 @@ one_cprop_pass (f, pass)
return changed;
}
-/* Compute PRE working variables. */
+/* Compute PRE+LCM working variables. */
/* Local properties of expressions. */
/* Nonzero for expressions that are transparent in the block. */
-static sbitmap *pre_transp;
-/* Nonzero for expressions that are computed (available) in the block. */
-static sbitmap *pre_comp;
-/* Nonzero for expressions that are locally anticipatable in the block. */
-static sbitmap *pre_antloc;
-
-/* Global properties (computed from the expression local properties). */
-/* Nonzero for expressions that are available on block entry/exit. */
-static sbitmap *pre_avin;
-static sbitmap *pre_avout;
-/* Nonzero for expressions that are anticipatable on block entry/exit. */
-static sbitmap *pre_antin;
-static sbitmap *pre_antout;
-/* Nonzero for expressions that are partially available on block entry/exit. */
-static sbitmap *pre_pavin;
-static sbitmap *pre_pavout;
-/* Nonzero for expressions that are "placement possible" on block entry/exit. */
-static sbitmap *pre_ppin;
-static sbitmap *pre_ppout;
+static sbitmap *transp;
/* Nonzero for expressions that are transparent at the end of the block.
This is only zero for expressions killed by abnormal critical edge
created by a calls. */
-static sbitmap *pre_transpout;
-
-/* Used while performing PRE to denote which insns are redundant. */
-static sbitmap pre_redundant;
-
-/* Allocate vars used for PRE analysis. */
-
-static void
-alloc_pre_mem (n_blocks, n_exprs)
- int n_blocks, n_exprs;
-{
- pre_transp = sbitmap_vector_alloc (n_blocks, n_exprs);
- pre_comp = sbitmap_vector_alloc (n_blocks, n_exprs);
- pre_antloc = sbitmap_vector_alloc (n_blocks, n_exprs);
-
- pre_avin = sbitmap_vector_alloc (n_blocks, n_exprs);
- pre_avout = sbitmap_vector_alloc (n_blocks, n_exprs);
- pre_antin = sbitmap_vector_alloc (n_blocks, n_exprs);
- pre_antout = sbitmap_vector_alloc (n_blocks, n_exprs);
-
- pre_pavin = sbitmap_vector_alloc (n_blocks, n_exprs);
- pre_pavout = sbitmap_vector_alloc (n_blocks, n_exprs);
- pre_ppin = sbitmap_vector_alloc (n_blocks, n_exprs);
- pre_ppout = sbitmap_vector_alloc (n_blocks, n_exprs);
-
- pre_transpout = sbitmap_vector_alloc (n_blocks, n_exprs);
-}
-
-/* Free vars used for PRE analysis. */
-
-static void
-free_pre_mem ()
-{
- free (pre_transp);
- free (pre_comp);
- free (pre_antloc);
- free (pre_avin);
- free (pre_avout);
- free (pre_antin);
- free (pre_antout);
-
- free (pre_pavin);
- free (pre_pavout);
- free (pre_ppin);
- free (pre_ppout);
- free (pre_transpout);
-}
-
-/* Dump PRE data. */
-
-void
-dump_pre_data (file)
- FILE *file;
-{
- dump_sbitmap_vector (file, "PRE locally transparent expressions", "BB",
- pre_transp, n_basic_blocks);
- dump_sbitmap_vector (file, "PRE locally available expressions", "BB",
- pre_comp, n_basic_blocks);
- dump_sbitmap_vector (file, "PRE locally anticipatable expressions", "BB",
- pre_antloc, n_basic_blocks);
-
- dump_sbitmap_vector (file, "PRE available incoming expressions", "BB",
- pre_avin, n_basic_blocks);
- dump_sbitmap_vector (file, "PRE available outgoing expressions", "BB",
- pre_avout, n_basic_blocks);
- dump_sbitmap_vector (file, "PRE anticipatable incoming expressions", "BB",
- pre_antin, n_basic_blocks);
- dump_sbitmap_vector (file, "PRE anticipatable outgoing expressions", "BB",
- pre_antout, n_basic_blocks);
-
- dump_sbitmap_vector (file, "PRE partially available incoming expressions", "BB",
- pre_pavin, n_basic_blocks);
- dump_sbitmap_vector (file, "PRE partially available outgoing expressions", "BB",
- pre_pavout, n_basic_blocks);
- dump_sbitmap_vector (file, "PRE placement possible on incoming", "BB",
- pre_ppin, n_basic_blocks);
- dump_sbitmap_vector (file, "PRE placement possible on outgoing", "BB",
- pre_ppout, n_basic_blocks);
-
- dump_sbitmap_vector (file, "PRE transparent on outgoing", "BB",
- pre_transpout, n_basic_blocks);
-}
-
-/* Compute the local properties of each recorded expression.
- Local properties are those that are defined by the block, irrespective
- of other blocks.
-
- An expression is transparent in a block if its operands are not modified
- in the block.
-
- An expression is computed (locally available) in a block if it is computed
- at least once and expression would contain the same value if the
- computation was moved to the end of the block.
-
- An expression is locally anticipatable in a block if it is computed at
- least once and expression would contain the same value if the computation
- was moved to the beginning of the block. */
-
-static void
-compute_pre_local_properties ()
-{
- int i;
-
- sbitmap_vector_ones (pre_transp, n_basic_blocks);
- sbitmap_vector_zero (pre_comp, n_basic_blocks);
- sbitmap_vector_zero (pre_antloc, n_basic_blocks);
-
- for (i = 0; i < expr_hash_table_size; i++)
- {
- struct expr *expr;
-
- for (expr = expr_hash_table[i]; expr != NULL; expr = expr->next_same_hash)
- {
- struct occr *occr;
- int indx = expr->bitmap_index;
+static sbitmap *transpout;
- /* The expression is transparent in this block if it is not killed.
- We start by assuming all are transparent [none are killed], and then
- reset the bits for those that are. */
-
- compute_transp (expr->expr, indx, pre_transp, 0);
-
- /* The occurrences recorded in antic_occr are exactly those that
- we want to set to non-zero in ANTLOC. */
-
- for (occr = expr->antic_occr; occr != NULL; occr = occr->next)
- {
- int bb = BLOCK_NUM (occr->insn);
- SET_BIT (pre_antloc[bb], indx);
-
- /* While we're scanning the table, this is a good place to
- initialize this. */
- occr->deleted_p = 0;
- }
-
- /* The occurrences recorded in avail_occr are exactly those that
- we want to set to non-zero in COMP. */
-
- for (occr = expr->avail_occr; occr != NULL; occr = occr->next)
- {
- int bb = BLOCK_NUM (occr->insn);
- SET_BIT (pre_comp[bb], indx);
-
- /* While we're scanning the table, this is a good place to
- initialize this. */
- occr->copied_p = 0;
- }
-
- /* While we're scanning the table, this is a good place to
- initialize this. */
- expr->reaching_reg = 0;
- }
- }
-}
+/* Nonzero for expressions that are computed (available) in the block. */
+static sbitmap *comp;
-/* Compute expression availability at entrance and exit of each block. */
+/* Nonzero for expressions that are locally anticipatable in the block. */
+static sbitmap *antloc;
-static void
-compute_pre_avinout ()
-{
- int bb, changed, passes;
+/* Nonzero for expressions where this block is an optimal computation
+ point. */
+static sbitmap *pre_optimal;
- sbitmap_zero (pre_avin[0]);
- sbitmap_vector_ones (pre_avout, n_basic_blocks);
+/* Nonzero for expressions which are redundant in a particular block. */
+static sbitmap *pre_redundant;
- passes = 0;
- changed = 1;
- while (changed)
- {
- changed = 0;
- for (bb = 0; bb < n_basic_blocks; bb++)
- {
- if (bb != 0)
- sbitmap_intersect_of_predecessors (pre_avin[bb], pre_avout,
- bb, s_preds);
- changed |= sbitmap_a_or_b_and_c (pre_avout[bb], pre_comp[bb],
- pre_transp[bb], pre_avin[bb]);
- }
- passes++;
- }
+static sbitmap *temp_bitmap;
- if (gcse_file)
- fprintf (gcse_file, "avail expr computation: %d passes\n", passes);
-}
+/* Redundant insns. */
+static sbitmap pre_redundant_insns;
-/* Compute expression anticipatability at entrance and exit of each block. */
+/* Allocate vars used for PRE analysis. */
static void
-compute_pre_antinout ()
+alloc_pre_mem (n_blocks, n_exprs)
+ int n_blocks, n_exprs;
{
- int bb, changed, passes;
-
- sbitmap_zero (pre_antout[n_basic_blocks - 1]);
- sbitmap_vector_ones (pre_antin, n_basic_blocks);
-
- passes = 0;
- changed = 1;
- while (changed)
- {
- changed = 0;
- /* We scan the blocks in the reverse order to speed up
- the convergence. */
- for (bb = n_basic_blocks - 1; bb >= 0; bb--)
- {
- if (bb != n_basic_blocks - 1)
- sbitmap_intersect_of_successors (pre_antout[bb], pre_antin,
- bb, s_succs);
- changed |= sbitmap_a_or_b_and_c (pre_antin[bb], pre_antloc[bb],
- pre_transp[bb], pre_antout[bb]);
- }
- passes++;
- }
-
- if (gcse_file)
- fprintf (gcse_file, "antic expr computation: %d passes\n", passes);
+ transp = sbitmap_vector_alloc (n_blocks, n_exprs);
+ comp = sbitmap_vector_alloc (n_blocks, n_exprs);
+ antloc = sbitmap_vector_alloc (n_blocks, n_exprs);
+
+ temp_bitmap = sbitmap_vector_alloc (n_blocks, n_exprs);
+ pre_optimal = sbitmap_vector_alloc (n_blocks, n_exprs);
+ pre_redundant = sbitmap_vector_alloc (n_blocks, n_exprs);
+ transpout = sbitmap_vector_alloc (n_blocks, n_exprs);
}
-/* Compute expression partial availability at entrance and exit of
- each block. */
-
-static void
-compute_pre_pavinout ()
-{
- int bb, changed, passes;
-
- sbitmap_zero (pre_pavin[0]);
- sbitmap_vector_zero (pre_pavout, n_basic_blocks);
-
- passes = 0;
- changed = 1;
- while (changed)
- {
- changed = 0;
- for (bb = 0; bb < n_basic_blocks; bb++)
- {
- if (bb != 0)
- sbitmap_union_of_predecessors (pre_pavin[bb], pre_pavout,
- bb, s_preds);
- changed |= sbitmap_a_or_b_and_c (pre_pavout[bb], pre_comp[bb],
- pre_transp[bb], pre_pavin[bb]);
- }
- passes++;
- }
-
- if (gcse_file)
- fprintf (gcse_file, "partially avail expr computation: %d passes\n", passes);
-}
-
-/* Compute transparent outgoing information for each block.
-
- An expression is transparent to an edge unless it is killed by
- the edge itself. This can only happen with abnormal control flow,
- when the edge is traversed through a call. This happens with
- non-local labels and exceptions.
-
- This would not be necessary if we split the edge. While this is
- normally impossible for abnormal critical edges, with some effort
- it should be possible with exception handling, since we still have
- control over which handler should be invoked. But due to increased
- EH table sizes, this may not be worthwhile. */
-
-static void
-compute_pre_transpout ()
-{
- int bb;
-
- sbitmap_vector_ones (pre_transpout, n_basic_blocks);
-
- for (bb = 0; bb < n_basic_blocks; ++bb)
- {
- int i;
-
- /* Note that flow inserted a nop a the end of basic blocks that
- end in call instructions for reasons other than abnormal
- control flow. */
- if (GET_CODE (BLOCK_END (bb)) != CALL_INSN)
- continue;
-
- for (i = 0; i < expr_hash_table_size; i++)
- {
- struct expr *expr;
- for (expr = expr_hash_table[i]; expr ; expr = expr->next_same_hash)
- if (GET_CODE (expr->expr) == MEM)
- {
- rtx addr = XEXP (expr->expr, 0);
-
- if (GET_CODE (addr) == SYMBOL_REF
- && CONSTANT_POOL_ADDRESS_P (addr))
- continue;
-
- /* ??? Optimally, we would use interprocedural alias
- analysis to determine if this mem is actually killed
- by this call. */
- RESET_BIT (pre_transpout[bb], expr->bitmap_index);
- }
- }
- }
-}
-
-/* Compute "placement possible" information on entrance and exit of
- each block.
-
- From Fred Chow's Thesis:
- A computation `e' is PP at a point `p' if it is anticipated at `p' and
- all the anticipated e's can be rendered redundant by zero or more
- insertions at that point and some other points in the procedure, and
- these insertions satisfy the conditions that the insertions are always
- at points that `e' is anticipated and the first anticipated e's after the
- insertions are rendered redundant. */
+/* Free vars used for PRE analysis. */
static void
-compute_pre_ppinout ()
+free_pre_mem ()
{
- int bb, i, changed, size, passes;
-
- sbitmap_vector_ones (pre_ppin, n_basic_blocks);
- /* ??? Inefficient as we set pre_ppin[0] twice, but simple. */
- sbitmap_zero (pre_ppin[0]);
-
- sbitmap_vector_ones (pre_ppout, n_basic_blocks);
- /* ??? Inefficient as we set pre_ppout[n_basic_blocks-1] twice, but simple. */
- sbitmap_zero (pre_ppout[n_basic_blocks - 1]);
-
- size = pre_ppin[0]->size;
- passes = 0;
- changed = 1;
- while (changed)
- {
- changed = 0;
- for (bb = 1; bb < n_basic_blocks; bb++)
- {
- sbitmap_ptr antin = pre_antin[bb]->elms;
- sbitmap_ptr pavin = pre_pavin[bb]->elms;
- sbitmap_ptr antloc = pre_antloc[bb]->elms;
- sbitmap_ptr transp = pre_transp[bb]->elms;
- sbitmap_ptr ppout = pre_ppout[bb]->elms;
- sbitmap_ptr ppin = pre_ppin[bb]->elms;
-
- for (i = 0; i < size; i++)
- {
- int_list_ptr pred;
- SBITMAP_ELT_TYPE tmp = *antin & *pavin & (*antloc | (*transp & *ppout));
- SBITMAP_ELT_TYPE pred_val = -1L;
+ free (transp);
+ free (comp);
+ free (antloc);
- for (pred = s_preds[bb]; pred != NULL; pred = pred->next)
- {
- int pred_bb = INT_LIST_VAL (pred);
- sbitmap_ptr ppout_j,avout_j;
-
- if (pred_bb == ENTRY_BLOCK)
- continue;
-
- /* If this is a back edge, propagate info along the back
- edge to allow for loop invariant code motion.
-
- See FOLLOW_BACK_EDGES at the top of this file for a longer
- discussion about loop invariant code motion in pre. */
- if (! FOLLOW_BACK_EDGES
- && (INSN_CUID (BLOCK_HEAD (bb))
- < INSN_CUID (BLOCK_END (pred_bb))))
- {
- pred_val = 0;
- }
- else
- {
- ppout_j = pre_ppout[pred_bb]->elms + i;
- avout_j = pre_avout[pred_bb]->elms + i;
- pred_val &= *ppout_j | *avout_j;
- }
- }
- tmp &= pred_val;
- *ppin = tmp;
- antin++; pavin++; antloc++; transp++; ppout++; ppin++;
- }
- }
-
- for (bb = 0; bb < n_basic_blocks - 1; bb++)
- {
- sbitmap_ptr ppout = pre_ppout[bb]->elms;
- sbitmap_ptr transpout = pre_transpout[bb]->elms;
-
- for (i = 0; i < size; i++)
- {
- int_list_ptr succ;
- SBITMAP_ELT_TYPE tmp = *transpout;
-
- for (succ = s_succs[bb]; succ != NULL; succ = succ->next)
- {
- int succ_bb = INT_LIST_VAL (succ);
- sbitmap_ptr ppin;
-
- if (succ_bb == EXIT_BLOCK)
- continue;
-
- ppin = pre_ppin[succ_bb]->elms + i;
- tmp &= *ppin;
- }
-
- if (*ppout != tmp)
- {
- changed = 1;
- *ppout = tmp;
- }
-
- ppout++; transpout++;
- }
- }
-
- passes++;
- }
-
- if (gcse_file)
- fprintf (gcse_file, "placement possible computation: %d passes\n", passes);
+ free (pre_optimal);
+ free (pre_redundant);
+ free (transpout);
}
/* Top level routine to do the dataflow analysis needed by PRE. */
@@ -4308,23 +3983,24 @@ compute_pre_ppinout ()
static void
compute_pre_data ()
{
- compute_pre_local_properties ();
- compute_pre_avinout ();
- compute_pre_antinout ();
- compute_pre_pavinout ();
- compute_pre_transpout ();
- compute_pre_ppinout ();
- if (gcse_file)
- fprintf (gcse_file, "\n");
+ compute_local_properties (transp, comp, antloc, 0);
+ compute_transpout ();
+ pre_lcm (n_basic_blocks, n_exprs, s_preds, s_succs, transp,
+ antloc, pre_redundant, pre_optimal);
}
+
/* PRE utilities */
-/* Return non-zero if occurrence OCCR of expression EXPR reaches block BB.
+/* Return non-zero if an occurrence of expression EXPR in OCCR_BB would reach
+ block BB.
VISITED is a pointer to a working buffer for tracking which BB's have
been visited. It is NULL for the top-level call.
+ CHECK_PRE_COMP controls whether or not we check for a computation of
+ EXPR in OCCR_BB.
+
We treat reaching expressions that go through blocks containing the same
reaching expression as "not reaching". E.g. if EXPR is generated in blocks
2 and 3, INSN is in block 4, and 2->3->4, we treat the expression in block
@@ -4333,10 +4009,11 @@ compute_pre_data ()
the closest such expression. */
static int
-pre_expr_reaches_here_p (occr, expr, bb, visited)
- struct occr *occr;
+pre_expr_reaches_here_p (occr_bb, expr, bb, check_pre_comp, visited)
+ int occr_bb;
struct expr *expr;
int bb;
+ int check_pre_comp;
char *visited;
{
int_list_ptr pred;
@@ -4354,49 +4031,64 @@ pre_expr_reaches_here_p (occr, expr, bb, visited)
if (pred_bb == ENTRY_BLOCK
/* Has predecessor has already been visited? */
|| visited[pred_bb])
- {
+ {
/* Nothing to do. */
}
/* Does this predecessor generate this expression? */
- else if (TEST_BIT (pre_comp[pred_bb], expr->bitmap_index))
+ else if ((!check_pre_comp && occr_bb == pred_bb)
+ || TEST_BIT (comp[pred_bb], expr->bitmap_index))
{
/* Is this the occurrence we're looking for?
Note that there's only one generating occurrence per block
so we just need to check the block number. */
- if (BLOCK_NUM (occr->insn) == pred_bb)
+ if (occr_bb == pred_bb)
return 1;
visited[pred_bb] = 1;
}
/* Ignore this predecessor if it kills the expression. */
- else if (! TEST_BIT (pre_transp[pred_bb], expr->bitmap_index))
+ else if (! TEST_BIT (transp[pred_bb], expr->bitmap_index))
visited[pred_bb] = 1;
/* Neither gen nor kill. */
else
- {
+ {
visited[pred_bb] = 1;
- if (pre_expr_reaches_here_p (occr, expr, pred_bb, visited))
+ if (pre_expr_reaches_here_p (occr_bb, expr, pred_bb,
+ check_pre_comp, visited))
return 1;
- }
+ }
}
/* All paths have been checked. */
return 0;
}
-/* Add EXPR to the end of basic block BB. */
+/* Add EXPR to the end of basic block BB.
+
+ This is used by both the PRE and code hoisting.
+
+ For PRE, we want to verify that the expr is either transparent
+ or locally anticipatable in the target block. This check makes
+ no sense for code hoisting. */
static void
-pre_insert_insn (expr, bb)
+insert_insn_end_bb (expr, bb, pre)
struct expr *expr;
int bb;
+ int pre;
{
rtx insn = BLOCK_END (bb);
rtx new_insn;
rtx reg = expr->reaching_reg;
int regno = REGNO (reg);
- rtx pat;
+ rtx pat, copied_expr;
+ rtx first_new_insn;
- pat = gen_rtx_SET (VOIDmode, reg, copy_rtx (expr->expr));
+ start_sequence ();
+ copied_expr = copy_rtx (expr->expr);
+ emit_move_insn (reg, copied_expr);
+ first_new_insn = get_insns ();
+ pat = gen_sequence ();
+ end_sequence ();
/* If the last insn is a jump, insert EXPR in front [taking care to
handle cc0, etc. properly]. */
@@ -4431,7 +4123,6 @@ pre_insert_insn (expr, bb)
#endif
/* FIXME: What if something in cc0/jump uses value set in new insn? */
new_insn = emit_insn_before (pat, insn);
- add_label_notes (SET_SRC (pat), new_insn);
if (BLOCK_HEAD (bb) == insn)
BLOCK_HEAD (bb) = new_insn;
}
@@ -4449,11 +4140,11 @@ pre_insert_insn (expr, bb)
presumtion that we'll get better code elsewhere as well. */
/* It should always be the case that we can put these instructions
- anywhere in the basic block. Check this. */
- /* ??? Well, it would be the case if we'd split all critical edges.
- Since we didn't, we may very well abort. */
- if (!TEST_BIT (pre_antloc[bb], expr->bitmap_index)
- && !TEST_BIT (pre_transp[bb], expr->bitmap_index))
+ anywhere in the basic block with performing PRE optimizations.
+ Check this. */
+ if (pre
+ && !TEST_BIT (antloc[bb], expr->bitmap_index)
+ && !TEST_BIT (transp[bb], expr->bitmap_index))
abort ();
/* Since different machines initialize their parameter registers
@@ -4493,62 +4184,101 @@ pre_insert_insn (expr, bb)
else
{
new_insn = emit_insn_after (pat, insn);
- add_label_notes (SET_SRC (pat), new_insn);
BLOCK_END (bb) = new_insn;
}
- /* Keep block number table up to date. */
- set_block_num (new_insn, bb);
- /* Keep register set table up to date. */
- record_one_set (regno, new_insn);
+ /* Keep block number table up to date.
+ Note, PAT could be a multiple insn sequence, we have to make
+ sure that each insn in the sequence is handled. */
+ if (GET_CODE (pat) == SEQUENCE)
+ {
+ int i;
+
+ for (i = 0; i < XVECLEN (pat, 0); i++)
+ {
+ rtx insn = XVECEXP (pat, 0, i);
+ set_block_num (insn, bb);
+ if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
+ add_label_notes (PATTERN (insn), new_insn);
+ record_set_insn = insn;
+ note_stores (PATTERN (insn), record_set_info);
+ }
+ }
+ else
+ {
+ add_label_notes (SET_SRC (pat), new_insn);
+ set_block_num (new_insn, bb);
+ /* Keep register set table up to date. */
+ record_one_set (regno, new_insn);
+ }
gcse_create_count++;
if (gcse_file)
{
- fprintf (gcse_file, "PRE: end of bb %d, insn %d, copying expression %d to reg %d\n",
+ fprintf (gcse_file, "PRE/HOIST: end of bb %d, insn %d, copying expression %d to reg %d\n",
bb, INSN_UID (new_insn), expr->bitmap_index, regno);
}
}
/* Insert partially redundant expressions at the ends of appropriate basic
- blocks making them now redundant. */
+ blocks making them fully redundant. */
static void
pre_insert (index_map)
struct expr **index_map;
{
- int bb, i, size;
+ int bb, i, set_size;
+ sbitmap *inserted;
+
+ /* Compute INSERT = PRE_OPTIMAL & ~PRE_REDUNDANT.
+ Where INSERT is nonzero, we add the expression at the end of the basic
+ block if it reaches any of the deleted expressions. */
- /* Compute INSERT = PPOUT & (~AVOUT) & (~PPIN | ~TRANSP) for each
- expression. Where INSERT == TRUE, add the expression at the end of
- the basic block. */
+ set_size = pre_optimal[0]->size;
+ inserted = sbitmap_vector_alloc (n_basic_blocks, n_exprs);
+ sbitmap_vector_zero (inserted, n_basic_blocks);
- size = pre_ppout[0]->size;
for (bb = 0; bb < n_basic_blocks; bb++)
{
int indx;
- sbitmap_ptr ppout = pre_ppout[bb]->elms;
- sbitmap_ptr avout = pre_avout[bb]->elms;
- sbitmap_ptr ppin = pre_ppin[bb]->elms;
- sbitmap_ptr transp = pre_transp[bb]->elms;
-
- for (i = indx = 0;
- i < size;
- i++, indx += SBITMAP_ELT_BITS, ppout++, avout++, ppin++, transp++)
+
+ /* This computes the number of potential insertions we need. */
+ sbitmap_not (temp_bitmap[bb], pre_redundant[bb]);
+ sbitmap_a_and_b (temp_bitmap[bb], temp_bitmap[bb], pre_optimal[bb]);
+
+ /* TEMP_BITMAP[bb] now contains a bitmap of the expressions that we need
+ to insert at the end of this basic block. */
+ for (i = indx = 0; i < set_size; i++, indx += SBITMAP_ELT_BITS)
{
+ SBITMAP_ELT_TYPE insert = temp_bitmap[bb]->elms[i];
int j;
- SBITMAP_ELT_TYPE insert = *ppout & (~*avout) & (~*ppin | ~*transp);
- for (j = indx; insert != 0 && j < n_exprs; j++, insert >>= 1)
+ for (j = indx; insert && j < n_exprs; j++, insert >>= 1)
{
- if ((insert & 1) != 0
- /* If the basic block isn't reachable, PPOUT will be TRUE.
- However, we don't want to insert a copy here because the
- expression may not really be redundant. So only insert
- an insn if the expression was deleted. */
- && index_map[j]->reaching_reg != NULL)
- pre_insert_insn (index_map[j], bb);
+ if ((insert & 1) != 0 && index_map[j]->reaching_reg != NULL_RTX)
+ {
+ struct expr *expr = index_map[j];
+ struct occr *occr;
+
+ /* Now look at each deleted occurence of this expression. */
+ for (occr = expr->antic_occr; occr != NULL; occr = occr->next)
+ {
+ if (! occr->deleted_p)
+ continue;
+
+ /* Insert this expression at the end of BB if it would
+ reach the deleted occurence. */
+ if (!TEST_BIT (inserted[bb], j)
+ && pre_expr_reaches_here_p (bb, expr,
+ BLOCK_NUM (occr->insn), 0,
+ NULL))
+ {
+ SET_BIT (inserted[bb], j);
+ insert_insn_end_bb (index_map[j], bb, 1);
+ }
+ }
+ }
}
}
}
@@ -4592,7 +4322,12 @@ pre_insert_copy_insn (expr, insn)
static void
pre_insert_copies ()
{
- int i;
+ int i, bb;
+
+ for (bb = 0; bb < n_basic_blocks; bb++)
+ {
+ sbitmap_a_and_b (temp_bitmap[bb], pre_optimal[bb], pre_redundant[bb]);
+ }
/* For each available expression in the table, copy the result to
`reaching_reg' if the expression reaches a deleted one.
@@ -4627,17 +4362,21 @@ pre_insert_copies ()
for (avail = expr->avail_occr; avail != NULL; avail = avail->next)
{
rtx insn = avail->insn;
+ int bb = BLOCK_NUM (insn);
+
+ if (!TEST_BIT (temp_bitmap[bb], expr->bitmap_index))
+ continue;
/* No need to handle this one if handled already. */
if (avail->copied_p)
continue;
/* Don't handle this one if it's a redundant one. */
- if (TEST_BIT (pre_redundant, INSN_CUID (insn)))
+ if (TEST_BIT (pre_redundant_insns, INSN_CUID (insn)))
continue;
/* Or if the expression doesn't reach the deleted one. */
- if (! pre_expr_reaches_here_p (avail, expr,
+ if (! pre_expr_reaches_here_p (BLOCK_NUM (avail->insn), expr,
BLOCK_NUM (occr->insn),
- NULL))
+ 1, NULL))
continue;
/* Copy the result of avail to reaching_reg. */
@@ -4650,7 +4389,6 @@ pre_insert_copies ()
}
/* Delete redundant computations.
- These are ones that satisy ANTLOC & PPIN.
Deletion is done by changing the insn to copy the `reaching_reg' of
the expression into the result of the SET. It is left to later passes
(cprop, cse2, flow, combine, regmove) to propagate the copy or eliminate it.
@@ -4660,7 +4398,15 @@ pre_insert_copies ()
static int
pre_delete ()
{
- int i, changed;
+ int i, bb, changed;
+
+ /* Compute the expressions which are redundant and need to be replaced by
+ copies from the reaching reg to the target reg. */
+ for (bb = 0; bb < n_basic_blocks; bb++)
+ {
+ sbitmap_not (temp_bitmap[bb], pre_optimal[bb]);
+ sbitmap_a_and_b (temp_bitmap[bb], temp_bitmap[bb], pre_redundant[bb]);
+ }
changed = 0;
for (i = 0; i < expr_hash_table_size; i++)
@@ -4680,9 +4426,8 @@ pre_delete ()
rtx insn = occr->insn;
rtx set;
int bb = BLOCK_NUM (insn);
- sbitmap ppin = pre_ppin[bb];
- if (TEST_BIT (ppin, indx))
+ if (TEST_BIT (temp_bitmap[bb], indx))
{
set = single_set (insn);
if (! set)
@@ -4700,20 +4445,21 @@ pre_delete ()
However, on the x86 some of the movXX patterns actually
contain clobbers of scratch regs. This may cause the
- insn created by validate_change to not patch any pattern
+ insn created by validate_change to not match any pattern
and thus cause validate_change to fail. */
if (validate_change (insn, &SET_SRC (set),
expr->reaching_reg, 0))
{
occr->deleted_p = 1;
- SET_BIT (pre_redundant, INSN_CUID (insn));
+ SET_BIT (pre_redundant_insns, INSN_CUID (insn));
changed = 1;
gcse_subst_count++;
}
if (gcse_file)
{
- fprintf (gcse_file, "PRE: redundant insn %d (expression %d) in bb %d, reaching reg is %d\n",
+ fprintf (gcse_file,
+ "PRE: redundant insn %d (expression %d) in bb %d, reaching reg is %d\n",
INSN_UID (insn), indx, bb, REGNO (expr->reaching_reg));
}
}
@@ -4728,10 +4474,9 @@ pre_delete ()
This is called by one_pre_gcse_pass after all the dataflow analysis
has been done.
- This is based on the original Morel-Renvoise paper and Fred Chow's thesis.
-
- The M-R paper uses "TRANSP" to describe an expression as being transparent
- in a block where as Chow's thesis uses "ALTERED". We use TRANSP.
+ This is based on the original Morel-Renvoise paper Fred Chow's thesis,
+ and lazy code motion from Knoop, Ruthing and Steffen as described in
+ Advanced Compiler Design and Implementation.
??? A new pseudo reg is created to hold the reaching expression.
The nice thing about the classical approach is that it would try to
@@ -4766,8 +4511,8 @@ pre_gcse ()
}
/* Reset bitmap used to track which insns are redundant. */
- pre_redundant = sbitmap_alloc (max_cuid);
- sbitmap_zero (pre_redundant);
+ pre_redundant_insns = sbitmap_alloc (max_cuid);
+ sbitmap_zero (pre_redundant_insns);
/* Delete the redundant insns first so that
- we know what register to use for the new insns and for the other
@@ -4783,7 +4528,7 @@ pre_gcse ()
specially allocated pseudo-reg that reaches the redundant expression. */
pre_insert_copies ();
- free (pre_redundant);
+ free (pre_redundant_insns);
return changed;
}
@@ -4793,8 +4538,7 @@ pre_gcse ()
Return non-zero if a change was made. */
static int
-one_pre_gcse_pass (f, pass)
- rtx f;
+one_pre_gcse_pass (pass)
int pass;
{
int changed = 0;
@@ -4803,7 +4547,7 @@ one_pre_gcse_pass (f, pass)
gcse_create_count = 0;
alloc_expr_hash_table (max_cuid);
- compute_expr_hash_table (f);
+ compute_expr_hash_table ();
if (gcse_file)
dump_hash_table (gcse_file, "Expression", expr_hash_table,
expr_hash_table_size, n_exprs);
@@ -4850,10 +4594,10 @@ add_label_notes (x, insn)
if (code == LABEL_REF && !LABEL_REF_NONLOCAL_P (x))
{
/* This code used to ignore labels that referred to dispatch tables to
- avoid flow generating (slighly) worse code.
+ avoid flow generating (slighly) worse code.
- We no longer ignore such label references (see LABEL_REF handling in
- mark_jump_label for additional information). */
+ We no longer ignore such label references (see LABEL_REF handling in
+ mark_jump_label for additional information). */
REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_LABEL, XEXP (x, 0),
REG_NOTES (insn));
return;
@@ -4869,3 +4613,54 @@ add_label_notes (x, insn)
add_label_notes (XVECEXP (x, i, j), insn);
}
}
+
+/* Compute transparent outgoing information for each block.
+
+ An expression is transparent to an edge unless it is killed by
+ the edge itself. This can only happen with abnormal control flow,
+ when the edge is traversed through a call. This happens with
+ non-local labels and exceptions.
+
+ This would not be necessary if we split the edge. While this is
+ normally impossible for abnormal critical edges, with some effort
+ it should be possible with exception handling, since we still have
+ control over which handler should be invoked. But due to increased
+ EH table sizes, this may not be worthwhile. */
+
+static void
+compute_transpout ()
+{
+ int bb;
+
+ sbitmap_vector_ones (transpout, n_basic_blocks);
+
+ for (bb = 0; bb < n_basic_blocks; ++bb)
+ {
+ int i;
+
+ /* Note that flow inserted a nop a the end of basic blocks that
+ end in call instructions for reasons other than abnormal
+ control flow. */
+ if (GET_CODE (BLOCK_END (bb)) != CALL_INSN)
+ continue;
+
+ for (i = 0; i < expr_hash_table_size; i++)
+ {
+ struct expr *expr;
+ for (expr = expr_hash_table[i]; expr ; expr = expr->next_same_hash)
+ if (GET_CODE (expr->expr) == MEM)
+ {
+ rtx addr = XEXP (expr->expr, 0);
+
+ if (GET_CODE (addr) == SYMBOL_REF
+ && CONSTANT_POOL_ADDRESS_P (addr))
+ continue;
+
+ /* ??? Optimally, we would use interprocedural alias
+ analysis to determine if this mem is actually killed
+ by this call. */
+ RESET_BIT (transpout[bb], expr->bitmap_index);
+ }
+ }
+ }
+}
diff --git a/gcc/gen-protos.c b/gcc/gen-protos.c
index f6533e7bed3..08b7ea85ddc 100644
--- a/gcc/gen-protos.c
+++ b/gcc/gen-protos.c
@@ -17,7 +17,6 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "hconfig.h"
#include "system.h"
-#include "gansidecl.h"
#include "scan.h"
#include "cpplib.h"
#include "cpphash.h"
@@ -29,20 +28,6 @@ char *progname;
int hash_tab[HASH_SIZE];
int next_index;
-int
-hashf (name, len, hashsize)
- register const U_CHAR *name;
- register int len;
- int hashsize;
-{
- register int r = 0;
-
- while (len--)
- r = HASHSTEP (r, *name++);
-
- return MAKE_POS (r) % hashsize;
-}
-
static void
add_hash (fname)
char *fname;
diff --git a/gcc/genattr.c b/gcc/genattr.c
index 191e27486c5..1157389fdf0 100644
--- a/gcc/genattr.c
+++ b/gcc/genattr.c
@@ -1,5 +1,5 @@
/* Generate attribute information (insn-attr.h) from machine description.
- Copyright (C) 1991, 1994, 1996, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1991, 1994, 1996, 1998, 1999 Free Software Foundation, Inc.
Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
This file is part of GNU CC.
@@ -31,9 +31,9 @@ struct obstack *rtl_obstack = &obstack;
#define obstack_chunk_alloc xmalloc
#define obstack_chunk_free free
-char *xmalloc PROTO((unsigned));
-static void fatal PVPROTO ((char *, ...)) ATTRIBUTE_PRINTF_1;
-void fancy_abort PROTO((void));
+static void fatal PVPROTO ((const char *, ...))
+ ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN;
+void fancy_abort PROTO((void)) ATTRIBUTE_NORETURN;
/* Define this so we can link with print-rtl.o to get debug_rtx function. */
char **insn_name_ptr = 0;
@@ -198,40 +198,44 @@ write_units (num_units, multiplicity, simultaneity,
printf ("#define INSN_QUEUE_SIZE %d\n", q_size);
}
-char *
+PTR
xmalloc (size)
- unsigned size;
+ size_t size;
{
- register char *val = (char *) malloc (size);
+ register PTR val = (PTR) malloc (size);
if (val == 0)
fatal ("virtual memory exhausted");
return val;
}
-char *
-xrealloc (ptr, size)
- char *ptr;
- unsigned size;
+PTR
+xrealloc (old, size)
+ PTR old;
+ size_t size;
{
- char * result = (char *) realloc (ptr, size);
- if (!result)
+ register PTR ptr;
+ if (old)
+ ptr = (PTR) realloc (old, size);
+ else
+ ptr = (PTR) malloc (size);
+ if (!ptr)
fatal ("virtual memory exhausted");
- return result;
+ return ptr;
}
static void
-fatal VPROTO ((char *format, ...))
+fatal VPROTO ((const char *format, ...))
{
-#ifndef __STDC__
- char *format;
+#ifndef ANSI_PROTOTYPES
+ const char *format;
#endif
va_list ap;
VA_START (ap, format);
-#ifndef __STDC__
- format = va_arg (ap, char *);
+#ifndef ANSI_PROTOTYPES
+ format = va_arg (ap, const char *);
#endif
fprintf (stderr, "genattr: ");
diff --git a/gcc/genattrtab.c b/gcc/genattrtab.c
index d57dd51b72f..c03aa9cca5a 100644
--- a/gcc/genattrtab.c
+++ b/gcc/genattrtab.c
@@ -1,5 +1,5 @@
/* Generate code from machine description to compute values of attributes.
- Copyright (C) 1991, 93, 94, 95, 96, 97, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1991, 93-98, 1999 Free Software Foundation, Inc.
Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
This file is part of GNU CC.
@@ -34,7 +34,7 @@ Boston, MA 02111-1307, USA. */
If the attribute `alternative', or a random C expression is present,
`constrain_operands' is called. If either of these cases of a reference to
- an operand is found, `insn_extract' is called.
+ an operand is found, `extract_insn' is called.
The special attribute `length' is also recognized. For this operand,
expressions involving the address of an operand or the current insn,
@@ -119,8 +119,9 @@ struct obstack *temp_obstack = &obstack2;
/* Define this so we can link with print-rtl.o to get debug_rtx function. */
char **insn_name_ptr = 0;
-static void fatal PVPROTO ((char *, ...)) ATTRIBUTE_PRINTF_1;
-void fancy_abort PROTO((void));
+static void fatal PVPROTO ((const char *, ...))
+ ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN;
+void fancy_abort PROTO((void)) ATTRIBUTE_NORETURN;
/* enough space to reserve for printing out ints */
#define MAX_DIGITS (HOST_BITS_PER_INT * 3 / 10 + 3)
@@ -364,12 +365,13 @@ rtx pic_offset_table_rtx;
static void attr_hash_add_rtx PROTO((int, rtx));
static void attr_hash_add_string PROTO((int, char *));
static rtx attr_rtx PVPROTO((enum rtx_code, ...));
-static char *attr_printf PVPROTO((int, char *, ...));
-static char *attr_string PROTO((char *, int));
+static char *attr_printf PVPROTO((int, const char *, ...))
+ ATTRIBUTE_PRINTF_2;
+static char *attr_string PROTO((const char *, int));
static rtx check_attr_test PROTO((rtx, int));
static rtx check_attr_value PROTO((rtx, struct attr_desc *));
-static rtx convert_set_attr_alternative PROTO((rtx, int, int, int));
-static rtx convert_set_attr PROTO((rtx, int, int, int));
+static rtx convert_set_attr_alternative PROTO((rtx, int, int));
+static rtx convert_set_attr PROTO((rtx, int, int));
static void check_defs PROTO((void));
#if 0
static rtx convert_const_symbol_ref PROTO((rtx, struct attr_desc *));
@@ -424,36 +426,35 @@ static void gen_insn PROTO((rtx));
static void gen_delay PROTO((rtx));
static void gen_unit PROTO((rtx));
static void write_test_expr PROTO((rtx, int));
-static int max_attr_value PROTO((rtx));
-static int or_attr_value PROTO((rtx));
+static int max_attr_value PROTO((rtx, int*));
+static int or_attr_value PROTO((rtx, int*));
static void walk_attr_value PROTO((rtx));
static void write_attr_get PROTO((struct attr_desc *));
static rtx eliminate_known_true PROTO((rtx, rtx, int, int));
-static void write_attr_set PROTO((struct attr_desc *, int, rtx, char *,
- char *, rtx, int, int));
+static void write_attr_set PROTO((struct attr_desc *, int, rtx,
+ const char *, const char *, rtx,
+ int, int));
static void write_attr_case PROTO((struct attr_desc *, struct attr_value *,
- int, char *, char *, int, rtx));
-static void write_unit_name PROTO((char *, int, char *));
+ int, const char *, const char *, int, rtx));
+static void write_unit_name PROTO((const char *, int, const char *));
static void write_attr_valueq PROTO((struct attr_desc *, char *));
static void write_attr_value PROTO((struct attr_desc *, rtx));
static void write_upcase PROTO((char *));
static void write_indent PROTO((int));
-static void write_eligible_delay PROTO((char *));
+static void write_eligible_delay PROTO((const char *));
static void write_function_unit_info PROTO((void));
-static void write_complex_function PROTO((struct function_unit *, char *,
- char *));
+static void write_complex_function PROTO((struct function_unit *, const char *,
+ const char *));
static int write_expr_attr_cache PROTO((rtx, struct attr_desc *));
static void write_toplevel_expr PROTO((rtx));
static int n_comma_elts PROTO((char *));
static char *next_comma_elt PROTO((char **));
-static struct attr_desc *find_attr PROTO((char *, int));
-static void make_internal_attr PROTO((char *, rtx, int));
+static struct attr_desc *find_attr PROTO((const char *, int));
+static void make_internal_attr PROTO((const char *, rtx, int));
static struct attr_value *find_most_used PROTO((struct attr_desc *));
static rtx find_single_value PROTO((struct attr_desc *));
static rtx make_numeric_value PROTO((int));
static void extend_range PROTO((struct range *, int, int));
-char *xrealloc PROTO((char *, unsigned));
-char *xmalloc PROTO((unsigned));
#define oballoc(size) obstack_alloc (hash_obstack, size)
@@ -537,7 +538,7 @@ attr_hash_add_string (hashcode, str)
static rtx
attr_rtx VPROTO((enum rtx_code code, ...))
{
-#ifndef __STDC__
+#ifndef ANSI_PROTOTYPES
enum rtx_code code;
#endif
va_list p;
@@ -550,7 +551,7 @@ attr_rtx VPROTO((enum rtx_code code, ...))
VA_START (p, code);
-#ifndef __STDC__
+#ifndef ANSI_PROTOTYPES
code = va_arg (p, enum rtx_code);
#endif
@@ -732,20 +733,20 @@ attr_rtx VPROTO((enum rtx_code code, ...))
/*VARARGS2*/
static char *
-attr_printf VPROTO((register int len, char *fmt, ...))
+attr_printf VPROTO((register int len, const char *fmt, ...))
{
-#ifndef __STDC__
+#ifndef ANSI_PROTOTYPES
register int len;
- char *fmt;
+ const char *fmt;
#endif
va_list p;
register char *str;
VA_START (p, fmt);
-#ifndef __STDC__
+#ifndef ANSI_PROTOTYPES
len = va_arg (p, int);
- fmt = va_arg (p, char *);
+ fmt = va_arg (p, const char *);
#endif
/* Print the string into a temporary location. */
@@ -776,7 +777,7 @@ attr_numeral (n)
static char *
attr_string (str, len)
- char *str;
+ const char *str;
int len;
{
register struct attr_hash *h;
@@ -1082,7 +1083,7 @@ check_attr_value (exp, attr)
fatal ("CONST_INT not valid for non-numeric `%s' attribute",
attr->name);
- if (INTVAL (exp) < 0)
+ if (INTVAL (exp) < 0 && ! attr->negative_ok)
fatal ("Negative numeric value specified for `%s' attribute",
attr->name);
@@ -1122,6 +1123,16 @@ check_attr_value (exp, attr)
XEXP (exp, 2) = check_attr_value (XEXP (exp, 2), attr);
break;
+ case PLUS:
+ case MINUS:
+ case MULT:
+ case DIV:
+ case MOD:
+ if (attr && !attr->is_numeric)
+ fatal ("Invalid operation `%s' for non-numeric attribute value",
+ GET_RTX_NAME (GET_CODE (exp)));
+ /* FALLTHRU */
+
case IOR:
case AND:
XEXP (exp, 0) = check_attr_value (XEXP (exp, 0), attr);
@@ -1147,12 +1158,27 @@ check_attr_value (exp, attr)
XEXP (exp, 1) = check_attr_value (XEXP (exp, 1), attr);
break;
+ case ATTR:
+ {
+ struct attr_desc *attr2 = find_attr (XSTR (exp, 0), 0);
+ if (attr2 == NULL)
+ fatal ("Unknown attribute `%s' in ATTR", XSTR (exp, 0));
+ else if ((attr && attr->is_const) && ! attr2->is_const)
+ fatal ("Non-constant attribute `%s' referenced from `%s'",
+ XSTR (exp, 0), attr->name);
+ else if (attr
+ && (attr->is_numeric != attr2->is_numeric
+ || (! attr->negative_ok && attr2->negative_ok)))
+ fatal ("Numeric attribute mismatch calling `%s' from `%s'",
+ XSTR (exp, 0), attr->name);
+ }
+ break;
+
case SYMBOL_REF:
- if (attr && attr->is_const)
- /* A constant SYMBOL_REF is valid as a constant attribute test and
- is expanded later by make_canonical into a COND. */
- return attr_rtx (SYMBOL_REF, XSTR (exp, 0));
- /* Otherwise, fall through... */
+ /* A constant SYMBOL_REF is valid as a constant attribute test and
+ is expanded later by make_canonical into a COND. In a non-constant
+ attribute test, it is left be. */
+ return attr_rtx (SYMBOL_REF, XSTR (exp, 0));
default:
fatal ("Invalid operation `%s' for attribute value",
@@ -1166,10 +1192,10 @@ check_attr_value (exp, attr)
It becomes a COND with each test being (eq_attr "alternative "n") */
static rtx
-convert_set_attr_alternative (exp, num_alt, insn_code, insn_index)
+convert_set_attr_alternative (exp, num_alt, insn_index)
rtx exp;
int num_alt;
- int insn_code, insn_index;
+ int insn_index;
{
rtx condexp;
int i;
@@ -1207,10 +1233,10 @@ convert_set_attr_alternative (exp, num_alt, insn_code, insn_index)
list of values is given, convert to SET_ATTR_ALTERNATIVE first. */
static rtx
-convert_set_attr (exp, num_alt, insn_code, insn_index)
+convert_set_attr (exp, num_alt, insn_index)
rtx exp;
int num_alt;
- int insn_code, insn_index;
+ int insn_index;
{
rtx newexp;
char *name_ptr;
@@ -1234,7 +1260,7 @@ convert_set_attr (exp, num_alt, insn_code, insn_index)
while ((p = next_comma_elt (&name_ptr)) != NULL)
XVECEXP (newexp, 1, n++) = attr_rtx (CONST_STRING, p);
- return convert_set_attr_alternative (newexp, num_alt, insn_code, insn_index);
+ return convert_set_attr_alternative (newexp, num_alt, insn_index);
}
/* Scan all definitions, checking for validity. Also, convert any SET_ATTR
@@ -1267,13 +1293,12 @@ check_defs ()
case SET_ATTR_ALTERNATIVE:
value = convert_set_attr_alternative (value,
id->num_alternatives,
- id->insn_code,
id->insn_index);
break;
case SET_ATTR:
value = convert_set_attr (value, id->num_alternatives,
- id->insn_code, id->insn_index);
+ id->insn_index);
break;
default:
@@ -1817,7 +1842,7 @@ expand_units ()
rtx unitsmask;
rtx readycost;
rtx newexp;
- char *str;
+ const char *str;
int i, j, u, num, nvalues;
/* Rebuild the condition for the unit to share the RTL expressions.
@@ -2101,7 +2126,10 @@ expand_units ()
}
/* Record MAX (BLOCKAGE (*,*)). */
- unit->max_blockage = max_attr_value (max_blockage);
+ {
+ int unknown;
+ unit->max_blockage = max_attr_value (max_blockage, &unknown);
+ }
/* See if the upper and lower bounds of BLOCKAGE (E,*) are the
same. If so, the blockage function carries no additional
@@ -2186,9 +2214,14 @@ simplify_knowing (exp, known_true)
{
if (GET_CODE (exp) != CONST_STRING)
{
- exp = attr_rtx (IF_THEN_ELSE, known_true, exp,
- make_numeric_value (max_attr_value (exp)));
- exp = simplify_by_exploding (exp);
+ int unknown = 0, max;
+ max = max_attr_value (exp, &unknown);
+ if (! unknown)
+ {
+ exp = attr_rtx (IF_THEN_ELSE, known_true, exp,
+ make_numeric_value (max));
+ exp = simplify_by_exploding (exp);
+ }
}
return exp;
}
@@ -2386,9 +2419,9 @@ substitute_address (exp, no_address_fn, address_fn)
static void
make_length_attrs ()
{
- static char *new_names[] = {"*insn_default_length",
- "*insn_variable_length_p",
- "*insn_current_length"};
+ static const char *new_names[] = {"*insn_default_length",
+ "*insn_variable_length_p",
+ "*insn_current_length"};
static rtx (*no_address_fn[]) PROTO((rtx)) = {identity_fn, zero_fn, zero_fn};
static rtx (*address_fn[]) PROTO((rtx)) = {max_fn, one_fn, identity_fn};
size_t i;
@@ -2458,7 +2491,8 @@ static rtx
max_fn (exp)
rtx exp;
{
- return make_numeric_value (max_attr_value (exp));
+ int unknown;
+ return make_numeric_value (max_attr_value (exp, &unknown));
}
static void
@@ -2468,16 +2502,23 @@ write_length_unit_log ()
struct attr_value *av;
struct insn_ent *ie;
unsigned int length_unit_log, length_or;
+ int unknown = 0;
if (length_attr == 0)
return;
- length_or = or_attr_value (length_attr->default_val->value);
- for (av = length_attr->first_value; av; av = av->next)
- for (ie = av->first_insn; ie; ie = ie->next)
- length_or |= or_attr_value (av->value);
- length_or = ~length_or;
- for (length_unit_log = 0; length_or & 1; length_or >>= 1)
- length_unit_log++;
+ length_or = or_attr_value (length_attr->default_val->value, &unknown);
+ for (av = length_attr->first_value; av; av = av->next)
+ for (ie = av->first_insn; ie; ie = ie->next)
+ length_or |= or_attr_value (av->value, &unknown);
+
+ if (unknown)
+ length_unit_log = 0;
+ else
+ {
+ length_or = ~length_or;
+ for (length_unit_log = 0; length_or & 1; length_or >>= 1)
+ length_unit_log++;
+ }
printf ("int length_unit_log = %u;\n", length_unit_log);
}
@@ -3703,6 +3744,8 @@ find_and_mark_used_attributes (exp, terms, nterms)
*nterms += 1;
MEM_VOLATILE_P (exp) = 1;
}
+ return 1;
+
case CONST_STRING:
case CONST_INT:
return 1;
@@ -4106,7 +4149,7 @@ gen_attr (exp)
fatal ("Duplicate definition for `%s' attribute", attr->name);
if (*XSTR (exp, 1) == '\0')
- attr->is_numeric = 1;
+ attr->is_numeric = 1;
else
{
name_ptr = XSTR (exp, 1);
@@ -4652,80 +4695,83 @@ write_test_expr (exp, flags)
}
/* Given an attribute value, return the maximum CONST_STRING argument
- encountered. It is assumed that they are all numeric. */
+ encountered. Set *UNKNOWNP and return INT_MAX if the value is unknown. */
static int
-max_attr_value (exp)
+max_attr_value (exp, unknownp)
rtx exp;
+ int *unknownp;
{
- int current_max = 0;
- int n;
- int i;
-
- if (GET_CODE (exp) == CONST_STRING)
- return atoi (XSTR (exp, 0));
+ int current_max;
+ int i, n;
- else if (GET_CODE (exp) == COND)
+ switch (GET_CODE (exp))
{
+ case CONST_STRING:
+ current_max = atoi (XSTR (exp, 0));
+ break;
+
+ case COND:
+ current_max = max_attr_value (XEXP (exp, 1), unknownp);
for (i = 0; i < XVECLEN (exp, 0); i += 2)
{
- n = max_attr_value (XVECEXP (exp, 0, i + 1));
+ n = max_attr_value (XVECEXP (exp, 0, i + 1), unknownp);
if (n > current_max)
current_max = n;
}
+ break;
- n = max_attr_value (XEXP (exp, 1));
+ case IF_THEN_ELSE:
+ current_max = max_attr_value (XEXP (exp, 1), unknownp);
+ n = max_attr_value (XEXP (exp, 2), unknownp);
if (n > current_max)
current_max = n;
- }
+ break;
- else if (GET_CODE (exp) == IF_THEN_ELSE)
- {
- current_max = max_attr_value (XEXP (exp, 1));
- n = max_attr_value (XEXP (exp, 2));
- if (n > current_max)
- current_max = n;
+ default:
+ *unknownp = 1;
+ current_max = INT_MAX;
+ break;
}
- else
- abort ();
-
return current_max;
}
/* Given an attribute value, return the result of ORing together all
- CONST_STRING arguments encountered. It is assumed that they are
- all numeric. */
+ CONST_STRING arguments encountered. Set *UNKNOWNP and return -1
+ if the numeric value is not known. */
static int
-or_attr_value (exp)
+or_attr_value (exp, unknownp)
rtx exp;
+ int *unknownp;
{
- int current_or = 0;
+ int current_or;
int i;
- if (GET_CODE (exp) == CONST_STRING)
- return atoi (XSTR (exp, 0));
-
- else if (GET_CODE (exp) == COND)
+ switch (GET_CODE (exp))
{
+ case CONST_STRING:
+ current_or = atoi (XSTR (exp, 0));
+ break;
+
+ case COND:
+ current_or = or_attr_value (XEXP (exp, 1), unknownp);
for (i = 0; i < XVECLEN (exp, 0); i += 2)
- {
- current_or |= or_attr_value (XVECEXP (exp, 0, i + 1));
- }
+ current_or |= or_attr_value (XVECEXP (exp, 0, i + 1), unknownp);
+ break;
- current_or |= or_attr_value (XEXP (exp, 1));
- }
+ case IF_THEN_ELSE:
+ current_or = or_attr_value (XEXP (exp, 1), unknownp);
+ current_or |= or_attr_value (XEXP (exp, 2), unknownp);
+ break;
- else if (GET_CODE (exp) == IF_THEN_ELSE)
- {
- current_or = or_attr_value (XEXP (exp, 1));
- current_or |= or_attr_value (XEXP (exp, 2));
+ default:
+ *unknownp = 1;
+ current_or = -1;
+ break;
}
- else
- abort ();
-
return current_or;
}
@@ -4923,19 +4969,12 @@ write_attr_set (attr, indent, value, prefix, suffix, known_true,
struct attr_desc *attr;
int indent;
rtx value;
- char *prefix;
- char *suffix;
+ const char *prefix;
+ const char *suffix;
rtx known_true;
int insn_code, insn_index;
{
- if (GET_CODE (value) == CONST_STRING)
- {
- write_indent (indent);
- printf ("%s ", prefix);
- write_attr_value (attr, value);
- printf ("%s\n", suffix);
- }
- else if (GET_CODE (value) == COND)
+ if (GET_CODE (value) == COND)
{
/* Assume the default value will be the default of the COND unless we
find an always true expression. */
@@ -5009,7 +5048,12 @@ write_attr_set (attr, indent, value, prefix, suffix, known_true,
}
}
else
- abort ();
+ {
+ write_indent (indent);
+ printf ("%s ", prefix);
+ write_attr_value (attr, value);
+ printf ("%s\n", suffix);
+ }
}
/* Write out the computation for one attribute value. */
@@ -5020,7 +5064,7 @@ write_attr_case (attr, av, write_case_lines, prefix, suffix, indent,
struct attr_desc *attr;
struct attr_value *av;
int write_case_lines;
- char *prefix, *suffix;
+ const char *prefix, *suffix;
int indent;
rtx known_true;
{
@@ -5063,14 +5107,14 @@ write_attr_case (attr, av, write_case_lines, prefix, suffix, indent,
if (must_extract)
{
write_indent (indent + 2);
- printf ("insn_extract (insn);\n");
+ printf ("extract_insn (insn);\n");
}
if (must_constrain)
{
#ifdef REGISTER_CONSTRAINTS
write_indent (indent + 2);
- printf ("if (! constrain_operands (INSN_CODE (insn), reload_completed))\n");
+ printf ("if (! constrain_operands (reload_completed))\n");
write_indent (indent + 2);
printf (" fatal_insn_not_found (insn);\n");
#endif
@@ -5176,9 +5220,9 @@ write_toplevel_expr (p)
static void
write_unit_name (prefix, num, suffix)
- char *prefix;
+ const char *prefix;
int num;
- char *suffix;
+ const char *suffix;
{
struct function_unit *unit;
@@ -5214,7 +5258,7 @@ write_attr_valueq (attr, s)
else
{
int i;
- char *sep = " /* units: ";
+ const char *sep = " /* units: ";
for (i = 0, num = ~num; num; i++, num >>= 1)
if (num & 1)
{
@@ -5244,10 +5288,53 @@ write_attr_value (attr, value)
struct attr_desc *attr;
rtx value;
{
- if (GET_CODE (value) != CONST_STRING)
- abort ();
+ int op;
+
+ switch (GET_CODE (value))
+ {
+ case CONST_STRING:
+ write_attr_valueq (attr, XSTR (value, 0));
+ break;
+
+ case SYMBOL_REF:
+ fputs (XSTR (value, 0), stdout);
+ break;
- write_attr_valueq (attr, XSTR (value, 0));
+ case ATTR:
+ {
+ struct attr_desc *attr2 = find_attr (XSTR (value, 0), 0);
+ printf ("get_attr_%s (%s)", attr2->name,
+ (attr2->is_const ? "" : "insn"));
+ }
+ break;
+
+ case PLUS:
+ op = '+';
+ goto do_operator;
+ case MINUS:
+ op = '-';
+ goto do_operator;
+ case MULT:
+ op = '*';
+ goto do_operator;
+ case DIV:
+ op = '/';
+ goto do_operator;
+ case MOD:
+ op = '%';
+ goto do_operator;
+
+ do_operator:
+ write_attr_value (attr, XEXP (value, 0));
+ putchar (' ');
+ putchar (op);
+ putchar (' ');
+ write_attr_value (attr, XEXP (value, 1));
+ break;
+
+ default:
+ abort ();
+ }
}
static void
@@ -5286,7 +5373,7 @@ write_indent (indent)
static void
write_eligible_delay (kind)
- char *kind;
+ const char *kind;
{
struct delay_desc *delay;
int max_slots;
@@ -5475,7 +5562,7 @@ write_function_unit_info ()
static void
write_complex_function (unit, name, connection)
struct function_unit *unit;
- char *name, *connection;
+ const char *name, *connection;
{
struct attr_desc *case_attr, *attr;
struct attr_value *av, *common_av;
@@ -5616,7 +5703,7 @@ next_comma_elt (pstr)
static struct attr_desc *
find_attr (name, create)
- char *name;
+ const char *name;
int create;
{
struct attr_desc *attr;
@@ -5654,7 +5741,7 @@ find_attr (name, create)
static void
make_internal_attr (name, value, special)
- char *name;
+ const char *name;
rtx value;
int special;
{
@@ -5752,22 +5839,26 @@ extend_range (range, min, max)
if (range->max < max) range->max = max;
}
-char *
-xrealloc (ptr, size)
- char *ptr;
- unsigned size;
+PTR
+xrealloc (old, size)
+ PTR old;
+ size_t size;
{
- char *result = (char *) realloc (ptr, size);
- if (!result)
+ register PTR ptr;
+ if (old)
+ ptr = (PTR) realloc (old, size);
+ else
+ ptr = (PTR) malloc (size);
+ if (!ptr)
fatal ("virtual memory exhausted");
- return result;
+ return ptr;
}
-char *
+PTR
xmalloc (size)
- unsigned size;
+ size_t size;
{
- register char *val = (char *) malloc (size);
+ register PTR val = (PTR) malloc (size);
if (val == 0)
fatal ("virtual memory exhausted");
@@ -5814,17 +5905,17 @@ copy_rtx_unchanging (orig)
}
static void
-fatal VPROTO ((char *format, ...))
+fatal VPROTO ((const char *format, ...))
{
-#ifndef __STDC__
- char *format;
+#ifndef ANSI_PROTOTYPES
+ const char *format;
#endif
va_list ap;
VA_START (ap, format);
-#ifndef __STDC__
- format = va_arg (ap, char *);
+#ifndef ANSI_PROTOTYPES
+ format = va_arg (ap, const char *);
#endif
fprintf (stderr, "genattrtab: ");
diff --git a/gcc/gencheck.c b/gcc/gencheck.c
index 03a4127be1e..80d7c4f5f2e 100644
--- a/gcc/gencheck.c
+++ b/gcc/gencheck.c
@@ -23,7 +23,7 @@ Boston, MA 02111-1307, USA. */
#define DEFTREECODE(SYM, NAME, TYPE, LEN) STRINGIFY(SYM),
-char *tree_codes[] = {
+const char *tree_codes[] = {
#include "tree.def"
#include "gencheck.h"
(char*)0
@@ -36,7 +36,7 @@ void usage ()
int main (argc, argv)
int argc;
- char *argv[];
+ char *argv[] ATTRIBUTE_UNUSED;
{
int i;
@@ -66,11 +66,11 @@ int main (argc, argv)
/* FIXME: We only need an xmalloc definition because we are forced to
link with alloca.o on some platforms. This should go away if/when
we link against libiberty.a. (ghazi@caip.rutgers.edu 6/3/98) */
-char *
+PTR
xmalloc (nbytes)
- int nbytes;
+ size_t nbytes;
{
- char *tmp = (char *) malloc (nbytes);
+ register PTR tmp = (PTR) malloc (nbytes);
if (!tmp)
{
diff --git a/gcc/gencodes.c b/gcc/gencodes.c
index 725cc651e69..8c043d2848a 100644
--- a/gcc/gencodes.c
+++ b/gcc/gencodes.c
@@ -2,7 +2,7 @@
- some macros CODE_FOR_... giving the insn_code_number value
for each of the defined standard insn names.
- Copyright (C) 1987, 1991, 1995 Free Software Foundation, Inc.
+ Copyright (C) 1987, 1991, 1995, 1998, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -33,9 +33,9 @@ struct obstack *rtl_obstack = &obstack;
#define obstack_chunk_alloc xmalloc
#define obstack_chunk_free free
-char *xmalloc PROTO((unsigned));
-static void fatal PVPROTO ((char *, ...)) ATTRIBUTE_PRINTF_1;
-void fancy_abort PROTO((void));
+static void fatal PVPROTO ((const char *, ...))
+ ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN;
+void fancy_abort PROTO((void)) ATTRIBUTE_NORETURN;
/* Define this so we can link with print-rtl.o to get debug_rtx function. */
char **insn_name_ptr = 0;
@@ -56,40 +56,44 @@ gen_insn (insn)
insn_code_number);
}
-char *
+PTR
xmalloc (size)
- unsigned size;
+ size_t size;
{
- register char *val = (char *) malloc (size);
+ register PTR val = (PTR) malloc (size);
if (val == 0)
fatal ("virtual memory exhausted");
return val;
}
-char *
-xrealloc (ptr, size)
- char *ptr;
- unsigned size;
+PTR
+xrealloc (old, size)
+ PTR old;
+ size_t size;
{
- char *result = (char *) realloc (ptr, size);
- if (!result)
+ register PTR ptr;
+ if (old)
+ ptr = (PTR) realloc (old, size);
+ else
+ ptr = (PTR) malloc (size);
+ if (!ptr)
fatal ("virtual memory exhausted");
- return result;
+ return ptr;
}
static void
-fatal VPROTO ((char *format, ...))
+fatal VPROTO ((const char *format, ...))
{
-#ifndef __STDC__
- char *format;
+#ifndef ANSI_PROTOTYPES
+ const char *format;
#endif
va_list ap;
VA_START (ap, format);
-#ifndef __STDC__
- format = va_arg (ap, char *);
+#ifndef ANSI_PROTOTYPES
+ format = va_arg (ap, const char *);
#endif
fprintf (stderr, "gencodes: ");
diff --git a/gcc/genconfig.c b/gcc/genconfig.c
index 75693c1fb65..9a191e8fd59 100644
--- a/gcc/genconfig.c
+++ b/gcc/genconfig.c
@@ -1,6 +1,6 @@
/* Generate from machine description:
- some #define configuration flags.
- Copyright (C) 1987, 1991, 1997, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1987, 1991, 1997, 1998, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -49,9 +49,9 @@ static int max_insns_per_split = 1;
static int clobbers_seen_this_insn;
static int dup_operands_seen_this_insn;
-char *xmalloc PROTO((unsigned));
-static void fatal PVPROTO ((char *, ...)) ATTRIBUTE_PRINTF_1;
-void fancy_abort PROTO((void));
+static void fatal PVPROTO ((const char *, ...))
+ ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN;
+void fancy_abort PROTO((void)) ATTRIBUTE_NORETURN;
static void walk_insn_part PROTO((rtx, int, int));
static void gen_insn PROTO((rtx));
@@ -244,11 +244,11 @@ gen_peephole (peep)
walk_insn_part (XVECEXP (peep, 0, i), 1, 0);
}
-char *
+PTR
xmalloc (size)
- unsigned size;
+ size_t size;
{
- register char *val = (char *) malloc (size);
+ register PTR val = (PTR) malloc (size);
if (val == 0)
fatal ("virtual memory exhausted");
@@ -256,29 +256,33 @@ xmalloc (size)
return val;
}
-char *
-xrealloc (ptr, size)
- char *ptr;
- unsigned size;
+PTR
+xrealloc (old, size)
+ PTR old;
+ size_t size;
{
- char *result = (char *) realloc (ptr, size);
- if (!result)
+ register PTR ptr;
+ if (old)
+ ptr = (PTR) realloc (old, size);
+ else
+ ptr = (PTR) malloc (size);
+ if (!ptr)
fatal ("virtual memory exhausted");
- return result;
+ return ptr;
}
static void
-fatal VPROTO ((char *format, ...))
+fatal VPROTO ((const char *format, ...))
{
-#ifndef __STDC__
- char *format;
+#ifndef ANSI_PROTOTYPES
+ const char *format;
#endif
va_list ap;
VA_START (ap, format);
-#ifndef __STDC__
- format = va_arg (ap, char *);
+#ifndef ANSI_PROTOTYPES
+ format = va_arg (ap, const char *);
#endif
fprintf (stderr, "genconfig: ");
diff --git a/gcc/genemit.c b/gcc/genemit.c
index 692f02831e4..91bcdd40500 100644
--- a/gcc/genemit.c
+++ b/gcc/genemit.c
@@ -1,5 +1,5 @@
/* Generate code from machine description to emit insns as rtl.
- Copyright (C) 1987, 88, 91, 94, 95, 97, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1987, 88, 91, 94, 95, 97, 98, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -30,9 +30,9 @@ struct obstack *rtl_obstack = &obstack;
#define obstack_chunk_alloc xmalloc
#define obstack_chunk_free free
-char *xmalloc PROTO((unsigned));
-static void fatal PVPROTO ((char *, ...)) ATTRIBUTE_PRINTF_1;
-void fancy_abort PROTO((void));
+static void fatal PVPROTO ((const char *, ...))
+ ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN;
+void fancy_abort PROTO((void)) ATTRIBUTE_NORETURN;
/* Define this so we can link with print-rtl.o to get debug_rtx function. */
char **insn_name_ptr = 0;
@@ -678,11 +678,11 @@ output_init_mov_optab ()
#endif
}
-char *
+PTR
xmalloc (size)
- unsigned size;
+ size_t size;
{
- register char *val = (char *) malloc (size);
+ register PTR val = (PTR) malloc (size);
if (val == 0)
fatal ("virtual memory exhausted");
@@ -690,29 +690,33 @@ xmalloc (size)
return val;
}
-char *
-xrealloc (ptr, size)
- char *ptr;
- unsigned size;
+PTR
+xrealloc (old, size)
+ PTR old;
+ size_t size;
{
- char *result = (char *) realloc (ptr, size);
- if (!result)
+ register PTR ptr;
+ if (old)
+ ptr = (PTR) realloc (old, size);
+ else
+ ptr = (PTR) malloc (size);
+ if (!ptr)
fatal ("virtual memory exhausted");
- return result;
+ return ptr;
}
static void
-fatal VPROTO ((char *format, ...))
+fatal VPROTO ((const char *format, ...))
{
-#ifndef __STDC__
- char *format;
+#ifndef ANSI_PROTOTYPES
+ const char *format;
#endif
va_list ap;
VA_START (ap, format);
-#ifndef __STDC__
- format = va_arg (ap, char *);
+#ifndef ANSI_PROTOTYPES
+ format = va_arg (ap, const char *);
#endif
fprintf (stderr, "genemit: ");
@@ -771,11 +775,11 @@ from the machine description file `md'. */\n\n");
printf ("#include \"real.h\"\n");
printf ("#include \"flags.h\"\n");
printf ("#include \"output.h\"\n");
- printf ("#include \"insn-config.h\"\n\n");
- printf ("#include \"insn-flags.h\"\n\n");
- printf ("#include \"insn-codes.h\"\n\n");
- printf ("#include \"reload.h\"\n");
- printf ("extern char *insn_operand_constraint[][MAX_RECOG_OPERANDS];\n\n");
+ printf ("#include \"insn-config.h\"\n");
+ printf ("#include \"insn-flags.h\"\n");
+ printf ("#include \"insn-codes.h\"\n");
+ printf ("#include \"recog.h\"\n");
+ printf ("#include \"reload.h\"\n\n");
printf ("extern rtx recog_operand[];\n");
printf ("#define operands emit_operand\n\n");
printf ("#define FAIL return (end_sequence (), _val)\n");
diff --git a/gcc/genextract.c b/gcc/genextract.c
index 6b64077c026..dc5cbd36ea5 100644
--- a/gcc/genextract.c
+++ b/gcc/genextract.c
@@ -1,5 +1,5 @@
/* Generate code from machine description to extract operands from insn as rtl.
- Copyright (C) 1987, 91, 92, 93, 97, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1987, 91-93, 97-98, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -96,14 +96,11 @@ static int dupnums[MAX_DUP_OPERANDS];
static struct code_ptr *peepholes;
static void gen_insn PROTO ((rtx));
-static void walk_rtx PROTO ((rtx, char *));
+static void walk_rtx PROTO ((rtx, const char *));
static void print_path PROTO ((char *));
-char *xmalloc PROTO ((unsigned));
-char *xrealloc PROTO ((char *, unsigned));
-static void fatal PVPROTO ((char *, ...)) ATTRIBUTE_PRINTF_1;
-static char *copystr PROTO ((char *));
-static void mybzero ();
-void fancy_abort PROTO ((void));
+static void fatal PVPROTO ((const char *, ...))
+ ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN;
+void fancy_abort PROTO ((void)) ATTRIBUTE_NORETURN;
static void
gen_insn (insn)
@@ -117,7 +114,7 @@ gen_insn (insn)
dup_count = 0;
/* No operands seen so far in this pattern. */
- mybzero (oplocs, sizeof oplocs);
+ memset (oplocs, 0, sizeof oplocs);
/* Walk the insn's pattern, remembering at all times the path
down to the walking point. */
@@ -188,7 +185,7 @@ gen_insn (insn)
static void
walk_rtx (x, path)
rtx x;
- char *path;
+ const char *path;
{
register RTX_CODE code;
register int i;
@@ -212,19 +209,19 @@ walk_rtx (x, path)
case MATCH_OPERAND:
case MATCH_SCRATCH:
- oplocs[XINT (x, 0)] = copystr (path);
+ oplocs[XINT (x, 0)] = xstrdup (path);
op_count = MAX (op_count, XINT (x, 0) + 1);
break;
case MATCH_DUP:
case MATCH_PAR_DUP:
- duplocs[dup_count] = copystr (path);
+ duplocs[dup_count] = xstrdup (path);
dupnums[dup_count] = XINT (x, 0);
dup_count++;
break;
case MATCH_OP_DUP:
- duplocs[dup_count] = copystr (path);
+ duplocs[dup_count] = xstrdup (path);
dupnums[dup_count] = XINT (x, 0);
dup_count++;
@@ -240,7 +237,7 @@ walk_rtx (x, path)
return;
case MATCH_OPERATOR:
- oplocs[XINT (x, 0)] = copystr (path);
+ oplocs[XINT (x, 0)] = xstrdup (path);
op_count = MAX (op_count, XINT (x, 0) + 1);
newpath = (char *) alloca (depth + 2);
@@ -255,7 +252,7 @@ walk_rtx (x, path)
return;
case MATCH_PARALLEL:
- oplocs[XINT (x, 0)] = copystr (path);
+ oplocs[XINT (x, 0)] = xstrdup (path);
op_count = MAX (op_count, XINT (x, 0) + 1);
newpath = (char *) alloca (depth + 2);
@@ -347,40 +344,44 @@ print_path (path)
}
}
-char *
+PTR
xmalloc (size)
- unsigned size;
+ size_t size;
{
- register char *val = (char *) malloc (size);
+ register PTR val = (PTR) malloc (size);
if (val == 0)
fatal ("virtual memory exhausted");
return val;
}
-char *
-xrealloc (ptr, size)
- char *ptr;
- unsigned size;
+PTR
+xrealloc (old, size)
+ PTR old;
+ size_t size;
{
- char *result = (char *) realloc (ptr, size);
- if (!result)
+ register PTR ptr;
+ if (old)
+ ptr = (PTR) realloc (old, size);
+ else
+ ptr = (PTR) malloc (size);
+ if (!ptr)
fatal ("virtual memory exhausted");
- return result;
+ return ptr;
}
static void
-fatal VPROTO ((char *format, ...))
+fatal VPROTO ((const char *format, ...))
{
-#ifndef __STDC__
- char *format;
+#ifndef ANSI_PROTOTYPES
+ const char *format;
#endif
va_list ap;
VA_START (ap, format);
-#ifndef __STDC__
- format = va_arg (ap, char *);
+#ifndef ANSI_PROTOTYPES
+ format = va_arg (ap, const char *);
#endif
fprintf (stderr, "genextract: ");
@@ -399,28 +400,14 @@ fancy_abort ()
fatal ("Internal gcc abort.");
}
-static char *
-copystr (s1)
- char *s1;
-{
- register char *tem;
-
- if (s1 == 0)
- return 0;
-
- tem = (char *) xmalloc (strlen (s1) + 1);
- strcpy (tem, s1);
-
- return tem;
-}
-
-static void
-mybzero (b, length)
- register char *b;
- register unsigned length;
+char *
+xstrdup (input)
+ const char *input;
{
- while (length-- > 0)
- *b++ = 0;
+ register size_t len = strlen (input) + 1;
+ register char *output = xmalloc (len);
+ memcpy (output, input, len);
+ return output;
}
int
@@ -459,17 +446,14 @@ from the machine description file `md'. */\n\n");
printf ("#include \"config.h\"\n");
printf ("#include \"system.h\"\n");
printf ("#include \"rtl.h\"\n");
+ printf ("#include \"insn-config.h\"\n");
+ printf ("#include \"recog.h\"\n");
printf ("#include \"toplev.h\"\n\n");
/* This variable exists only so it can be the "location"
of any missing operand whose numbers are skipped by a given pattern. */
printf ("static rtx junk ATTRIBUTE_UNUSED;\n");
- printf ("extern rtx recog_operand[];\n");
- printf ("extern rtx *recog_operand_loc[];\n");
- printf ("extern rtx *recog_dup_loc[];\n");
- printf ("extern char recog_dup_num[];\n");
-
printf ("void\ninsn_extract (insn)\n");
printf (" rtx insn;\n");
printf ("{\n");
@@ -477,6 +461,8 @@ from the machine description file `md'. */\n\n");
printf (" register rtx **ro_loc = recog_operand_loc;\n");
printf (" rtx pat = PATTERN (insn);\n");
printf (" int i ATTRIBUTE_UNUSED;\n\n");
+ printf (" memset (ro, 0, sizeof (*ro) * MAX_RECOG_OPERANDS);\n");
+ printf (" memset (ro_loc, 0, sizeof (*ro_loc) * MAX_RECOG_OPERANDS);\n");
printf (" switch (INSN_CODE (insn))\n");
printf (" {\n");
printf (" case -1:\n");
diff --git a/gcc/genflags.c b/gcc/genflags.c
index dee8128a9c2..a87b08de287 100644
--- a/gcc/genflags.c
+++ b/gcc/genflags.c
@@ -2,7 +2,7 @@
- some flags HAVE_... saying which simple standard instructions are
available for this machine.
- Copyright (C) 1987, 1991, 1995, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1987, 1991, 1995, 1998, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -33,9 +33,9 @@ struct obstack *rtl_obstack = &obstack;
#define obstack_chunk_alloc xmalloc
#define obstack_chunk_free free
-char *xmalloc PROTO((unsigned));
-static void fatal PVPROTO ((char *, ...)) ATTRIBUTE_PRINTF_1;
-void fancy_abort PROTO((void));
+static void fatal PVPROTO ((const char *, ...))
+ ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN;
+void fancy_abort PROTO((void)) ATTRIBUTE_NORETURN;
/* Names for patterns. Need to allow linking with print-rtl. */
char **insn_name_ptr;
@@ -175,11 +175,11 @@ gen_insn (insn)
obstack_grow (obstack_ptr, &insn, sizeof (rtx));
}
-char *
+PTR
xmalloc (size)
- unsigned size;
+ size_t size;
{
- register char *val = (char *) malloc (size);
+ register PTR val = (PTR) malloc (size);
if (val == 0)
fatal ("virtual memory exhausted");
@@ -187,29 +187,33 @@ xmalloc (size)
return val;
}
-char *
-xrealloc (ptr, size)
- char *ptr;
- unsigned size;
+PTR
+xrealloc (old, size)
+ PTR old;
+ size_t size;
{
- char *result = (char *) realloc (ptr, size);
- if (!result)
+ register PTR ptr;
+ if (old)
+ ptr = (PTR) realloc (old, size);
+ else
+ ptr = (PTR) malloc (size);
+ if (!ptr)
fatal ("virtual memory exhausted");
- return result;
+ return ptr;
}
static void
-fatal VPROTO ((char *format, ...))
+fatal VPROTO ((const char *format, ...))
{
-#ifndef __STDC__
- char *format;
+#ifndef ANSI_PROTOTYPES
+ const char *format;
#endif
va_list ap;
VA_START (ap, format);
-#ifndef __STDC__
- format = va_arg (ap, char *);
+#ifndef ANSI_PROTOTYPES
+ format = va_arg (ap, const char *);
#endif
fprintf (stderr, "genflags: ");
diff --git a/gcc/gengenrtl.c b/gcc/gengenrtl.c
index 865d0aa261e..1949a5f0411 100644
--- a/gcc/gengenrtl.c
+++ b/gcc/gengenrtl.c
@@ -1,5 +1,5 @@
/* Generate code to allocate RTL structures.
- Copyright (C) 1997 Free Software Foundation, Inc.
+ Copyright (C) 1997, 1998 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -276,11 +276,11 @@ gencode (f)
}
#if defined(USE_C_ALLOCA)
-char *
+PTR
xmalloc (nbytes)
- int nbytes;
+ size_t nbytes;
{
- char *tmp = (char *) malloc (nbytes);
+ register PTR tmp = (PTR) malloc (nbytes);
if (!tmp)
{
diff --git a/gcc/genopinit.c b/gcc/genopinit.c
index f0b57bb9be9..37db6b964e3 100644
--- a/gcc/genopinit.c
+++ b/gcc/genopinit.c
@@ -1,5 +1,5 @@
/* Generate code to initialize optabs from machine description.
- Copyright (C) 1993, 94-97, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1993, 94-98, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -30,9 +30,9 @@ struct obstack *rtl_obstack = &obstack;
#define obstack_chunk_alloc xmalloc
#define obstack_chunk_free free
-char *xmalloc PROTO((unsigned));
-static void fatal PVPROTO ((char *, ...)) ATTRIBUTE_PRINTF_1;
-void fancy_abort PROTO((void));
+static void fatal PVPROTO ((const char *, ...))
+ ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN;
+void fancy_abort PROTO((void)) ATTRIBUTE_NORETURN;
/* Many parts of GCC use arrays that are indexed by machine mode and
contain the insn codes for pattern in the MD file that perform a given
@@ -63,7 +63,7 @@ void fancy_abort PROTO((void));
/* The reason we use \% is to avoid sequences of the form %-capletter-%
which SCCS treats as magic. This gets warnings which you should ignore. */
-char *optabs[] =
+const char *optabs[] =
{ "extendtab[(int) %B][(int) %A][0] = CODE_FOR_%(extend%a\%b2%)",
"extendtab[(int) %B][(int) %A][1] = CODE_FOR_%(zero_extend%a\%b2%)",
"fixtab[(int) %A][(int) %B][0] = CODE_FOR_%(fix%F\%a%I\%b2%)",
@@ -134,7 +134,7 @@ gen_insn (insn)
int m1, m2, op;
size_t pindex;
int i;
- char *np, *pp, *p, *q;
+ const char *np, *pp, *p, *q;
/* Don't mention instructions whose names are the null string.
They are in the machine description just to be recognized. */
@@ -201,7 +201,7 @@ gen_insn (insn)
for (i = ((int) MAX_MACHINE_MODE) - 1; i >= 0; i--)
{
for (p = mode_name[i], q = np; *p; p++, q++)
- if (tolower (*p) != *q)
+ if (tolower ((unsigned char)*p) != *q)
break;
if (*p == 0
@@ -255,11 +255,11 @@ gen_insn (insn)
break;
case 'a':
for (np = mode_name[m1]; *np; np++)
- printf ("%c", tolower (*np));
+ printf ("%c", tolower ((unsigned char)*np));
break;
case 'b':
for (np = mode_name[m2]; *np; np++)
- printf ("%c", tolower (*np));
+ printf ("%c", tolower ((unsigned char)*np));
break;
case 'A':
printf ("%smode", mode_name[m1]);
@@ -272,7 +272,7 @@ gen_insn (insn)
break;
case 'C':
for (np = rtx_name[op]; *np; np++)
- printf ("%c", toupper (*np));
+ printf ("%c", toupper ((unsigned char)*np));
break;
}
}
@@ -280,11 +280,11 @@ gen_insn (insn)
printf (";\n");
}
-char *
+PTR
xmalloc (size)
- unsigned size;
+ size_t size;
{
- register char *val = (char *) malloc (size);
+ register PTR val = (PTR) malloc (size);
if (val == 0)
fatal ("virtual memory exhausted");
@@ -292,29 +292,33 @@ xmalloc (size)
return val;
}
-char *
-xrealloc (ptr, size)
- char *ptr;
- unsigned size;
+PTR
+xrealloc (old, size)
+ PTR old;
+ size_t size;
{
- char *result = (char *) realloc (ptr, size);
- if (!result)
+ register PTR ptr;
+ if (old)
+ ptr = (PTR) realloc (old, size);
+ else
+ ptr = (PTR) malloc (size);
+ if (!ptr)
fatal ("virtual memory exhausted");
- return result;
+ return ptr;
}
static void
-fatal VPROTO ((char *format, ...))
+fatal VPROTO ((const char *format, ...))
{
-#ifndef __STDC__
- char *format;
+#ifndef ANSI_PROTOTYPES
+ const char *format;
#endif
va_list ap;
VA_START (ap, format);
-#ifndef __STDC__
- format = va_arg (ap, char *);
+#ifndef ANSI_PROTOTYPES
+ format = va_arg (ap, const char *);
#endif
fprintf (stderr, "genopinit: ");
diff --git a/gcc/genoutput.c b/gcc/genoutput.c
index 400a8be442b..30d1280b76d 100644
--- a/gcc/genoutput.c
+++ b/gcc/genoutput.c
@@ -1,5 +1,5 @@
/* Generate code from to output assembler insns as recognized from rtl.
- Copyright (C) 1987, 88, 92, 94, 95, 97, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1987, 88, 92, 94-95, 97-98, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -107,12 +107,10 @@ struct obstack *rtl_obstack = &obstack;
#define obstack_chunk_alloc xmalloc
#define obstack_chunk_free free
-char *xmalloc PROTO((unsigned));
-static void fatal PVPROTO ((char *, ...)) ATTRIBUTE_PRINTF_1;
-void fancy_abort PROTO((void));
-static void error PVPROTO ((char *, ...)) ATTRIBUTE_PRINTF_1;
-static void mybcopy ();
-static void mybzero ();
+static void fatal PVPROTO ((const char *, ...))
+ ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN;
+void fancy_abort PROTO((void)) ATTRIBUTE_NORETURN;
+static void error PVPROTO ((const char *, ...)) ATTRIBUTE_PRINTF_1;
static int n_occurrences PROTO((int, char *));
/* Define this so we can link with print-rtl.o to get debug_rtx function. */
@@ -172,6 +170,7 @@ int have_constraints;
static int have_error;
+static char * name_for_index PROTO((int));
static void output_prologue PROTO((void));
static void output_epilogue PROTO((void));
static void scan_operands PROTO((rtx, int, int));
@@ -183,6 +182,29 @@ static void gen_expand PROTO((rtx));
static void gen_split PROTO((rtx));
static int n_occurrences PROTO((int, char *));
+static char *
+name_for_index (index)
+ int index;
+{
+ static char buf[100];
+
+ struct data *i, *last_named = NULL;
+ for (i = insn_data; i ; i = i->next)
+ {
+ if (i->index_number == index)
+ return i->name;
+ if (i->name)
+ last_named = i;
+ }
+
+ if (last_named)
+ sprintf(buf, "%s+%d", last_named->name, index - last_named->index_number);
+ else
+ sprintf(buf, "insn %d", index);
+
+ return buf;
+}
+
static void
output_prologue ()
{
@@ -211,7 +233,7 @@ output_epilogue ()
{
register struct data *d;
- printf ("\nchar * const insn_template[] =\n {\n");
+ printf ("\nconst char * const insn_template[] =\n {\n");
for (d = insn_data; d; d = d->next)
{
if (d->template)
@@ -221,7 +243,7 @@ output_epilogue ()
}
printf (" };\n");
- printf ("\nchar *(*const insn_outfun[])() =\n {\n");
+ printf ("\nconst char *(*const insn_outfun[])() =\n {\n");
for (d = insn_data; d; d = d->next)
{
if (d->outfun)
@@ -241,7 +263,7 @@ output_epilogue ()
}
printf (" };\n");
- printf ("\nchar *insn_name[] =\n {\n");
+ printf ("\nconst char *insn_name[] =\n {\n");
{
int offset = 0;
int next;
@@ -282,7 +304,7 @@ output_epilogue ()
}
}
printf (" };\n");
- printf ("char **insn_name_ptr = insn_name;\n");
+ printf ("const char **insn_name_ptr = insn_name;\n");
printf ("\nconst int insn_n_operands[] =\n {\n");
for (d = insn_data; d; d = d->next)
@@ -296,7 +318,7 @@ output_epilogue ()
if (have_constraints)
{
- printf ("\nchar *const insn_operand_constraint[][MAX_RECOG_OPERANDS] =\n {\n");
+ printf ("\nconst char *const insn_operand_constraint[][MAX_RECOG_OPERANDS] =\n {\n");
for (d = insn_data; d; d = d->next)
{
register int i;
@@ -415,7 +437,7 @@ static int max_opno;
static int num_dups;
static char *constraints[MAX_MAX_OPERANDS];
static int op_n_alternatives[MAX_MAX_OPERANDS];
-static char *predicates[MAX_MAX_OPERANDS];
+static const char *predicates[MAX_MAX_OPERANDS];
static char address_p[MAX_MAX_OPERANDS];
static enum machine_mode modes[MAX_MAX_OPERANDS];
static char strict_low[MAX_MAX_OPERANDS];
@@ -442,13 +464,13 @@ scan_operands (part, this_address_p, this_strict_low)
max_opno = opno;
if (max_opno >= MAX_MAX_OPERANDS)
{
- error ("Too many operands (%d) in definition %d.\n",
- max_opno + 1, next_index_number);
+ error ("Too many operands (%d) in definition %s.\n",
+ max_opno + 1, name_for_index (next_index_number));
return;
}
if (seen[opno])
- error ("Definition %d specified operand number %d more than once.\n",
- next_index_number, opno);
+ error ("Definition %s specified operand number %d more than once.\n",
+ name_for_index (next_index_number), opno);
seen[opno] = 1;
modes[opno] = GET_MODE (part);
strict_low[opno] = this_strict_low;
@@ -468,13 +490,13 @@ scan_operands (part, this_address_p, this_strict_low)
max_opno = opno;
if (max_opno >= MAX_MAX_OPERANDS)
{
- error ("Too many operands (%d) in definition %d.\n",
- max_opno + 1, next_index_number);
+ error ("Too many operands (%d) in definition %s.\n",
+ max_opno + 1, name_for_index (next_index_number));
return;
}
if (seen[opno])
- error ("Definition %d specified operand number %d more than once.\n",
- next_index_number, opno);
+ error ("Definition %s specified operand number %d more than once.\n",
+ name_for_index (next_index_number), opno);
seen[opno] = 1;
modes[opno] = GET_MODE (part);
strict_low[opno] = 0;
@@ -495,13 +517,13 @@ scan_operands (part, this_address_p, this_strict_low)
max_opno = opno;
if (max_opno >= MAX_MAX_OPERANDS)
{
- error ("Too many operands (%d) in definition %d.\n",
- max_opno + 1, next_index_number);
+ error ("Too many operands (%d) in definition %s.\n",
+ max_opno + 1, name_for_index (next_index_number));
return;
}
if (seen[opno])
- error ("Definition %d specified operand number %d more than once.\n",
- next_index_number, opno);
+ error ("Definition %s specified operand number %d more than once.\n",
+ name_for_index (next_index_number), opno);
seen[opno] = 1;
modes[opno] = GET_MODE (part);
strict_low[opno] = 0;
@@ -573,7 +595,7 @@ process_template (d, template)
d->template = 0;
d->outfun = 1;
- printf ("\nstatic char *\n");
+ printf ("\nstatic const char *\n");
printf ("output_%d (operands, insn)\n", d->code_number);
printf (" rtx *operands ATTRIBUTE_UNUSED;\n");
printf (" rtx insn ATTRIBUTE_UNUSED;\n");
@@ -586,7 +608,7 @@ process_template (d, template)
if (template[0] == '@')
{
- printf (" static /*const*/ char *const strings_%d[] = {\n",
+ printf (" static const char *const strings_%d[] = {\n",
d->code_number);
for (i = 0, cp = &template[1]; *cp; )
@@ -646,8 +668,8 @@ validate_insn_alternatives (d)
if (n == 0)
n = d->op_n_alternatives[start];
else if (n != d->op_n_alternatives[start])
- error ("wrong number of alternatives in operand %d of insn number %d",
- start, d->index_number);
+ error ("wrong number of alternatives in operand %d of insn %s",
+ start, name_for_index (d->index_number));
}
/* Record the insn's overall number of alternatives. */
d->n_alternatives = n;
@@ -684,13 +706,13 @@ gen_insn (insn)
max_opno = -1;
num_dups = 0;
- mybzero (constraints, sizeof constraints);
- mybzero (op_n_alternatives, sizeof op_n_alternatives);
- mybzero (predicates, sizeof predicates);
- mybzero (address_p, sizeof address_p);
- mybzero (modes, sizeof modes);
- mybzero (strict_low, sizeof strict_low);
- mybzero (seen, sizeof seen);
+ memset (constraints, 0, sizeof constraints);
+ memset (op_n_alternatives, 0, sizeof op_n_alternatives);
+ memset (predicates, 0, sizeof predicates);
+ memset (address_p, 0, sizeof address_p);
+ memset (modes, 0, sizeof modes);
+ memset (strict_low, 0, sizeof strict_low);
+ memset (seen, 0, sizeof seen);
for (i = 0; i < XVECLEN (insn, 1); i++)
scan_operands (XVECEXP (insn, 1, i), 0, 0);
@@ -698,12 +720,12 @@ gen_insn (insn)
d->n_operands = max_opno + 1;
d->n_dups = num_dups;
- mybcopy (constraints, d->constraints, sizeof constraints);
- mybcopy (op_n_alternatives, d->op_n_alternatives, sizeof op_n_alternatives);
- mybcopy (predicates, d->predicates, sizeof predicates);
- mybcopy (address_p, d->address_p, sizeof address_p);
- mybcopy (modes, d->modes, sizeof modes);
- mybcopy (strict_low, d->strict_low, sizeof strict_low);
+ memcpy (d->constraints, constraints, sizeof constraints);
+ memcpy (d->op_n_alternatives, op_n_alternatives, sizeof op_n_alternatives);
+ memcpy (d->predicates, predicates, sizeof predicates);
+ memcpy (d->address_p, address_p, sizeof address_p);
+ memcpy (d->modes, modes, sizeof modes);
+ memcpy (d->strict_low, strict_low, sizeof strict_low);
validate_insn_alternatives (d);
process_template (d, XSTR (insn, 3));
@@ -735,13 +757,13 @@ gen_peephole (peep)
end_of_insn_data = d;
max_opno = -1;
- mybzero (constraints, sizeof constraints);
- mybzero (op_n_alternatives, sizeof op_n_alternatives);
- mybzero (predicates, sizeof predicates);
- mybzero (address_p, sizeof address_p);
- mybzero (modes, sizeof modes);
- mybzero (strict_low, sizeof strict_low);
- mybzero (seen, sizeof seen);
+ memset (constraints, 0, sizeof constraints);
+ memset (op_n_alternatives, 0, sizeof op_n_alternatives);
+ memset (predicates, 0, sizeof predicates);
+ memset (address_p, 0, sizeof address_p);
+ memset (modes, 0, sizeof modes);
+ memset (strict_low, 0, sizeof strict_low);
+ memset (seen, 0, sizeof seen);
/* Get the number of operands by scanning all the
patterns of the peephole optimizer.
@@ -752,12 +774,12 @@ gen_peephole (peep)
d->n_operands = max_opno + 1;
d->n_dups = 0;
- mybcopy (constraints, d->constraints, sizeof constraints);
- mybcopy (op_n_alternatives, d->op_n_alternatives, sizeof op_n_alternatives);
- mybzero (d->predicates, sizeof predicates);
- mybzero (d->address_p, sizeof address_p);
- mybzero (d->modes, sizeof modes);
- mybzero (d->strict_low, sizeof strict_low);
+ memcpy (d->constraints, constraints, sizeof constraints);
+ memcpy (d->op_n_alternatives, op_n_alternatives, sizeof op_n_alternatives);
+ memset (d->predicates, 0, sizeof predicates);
+ memset (d->address_p, 0, sizeof address_p);
+ memset (d->modes, 0, sizeof modes);
+ memset (d->strict_low, 0, sizeof strict_low);
validate_insn_alternatives (d);
process_template (d, XSTR (peep, 2));
@@ -796,13 +818,13 @@ gen_expand (insn)
/* Scan the operands to get the specified predicates and modes,
since expand_binop needs to know them. */
- mybzero (constraints, sizeof constraints);
- mybzero (op_n_alternatives, sizeof op_n_alternatives);
- mybzero (predicates, sizeof predicates);
- mybzero (address_p, sizeof address_p);
- mybzero (modes, sizeof modes);
- mybzero (strict_low, sizeof strict_low);
- mybzero (seen, sizeof seen);
+ memset (constraints, 0, sizeof constraints);
+ memset (op_n_alternatives, 0, sizeof op_n_alternatives);
+ memset (predicates, 0, sizeof predicates);
+ memset (address_p, 0, sizeof address_p);
+ memset (modes, 0, sizeof modes);
+ memset (strict_low, 0, sizeof strict_low);
+ memset (seen, 0, sizeof seen);
if (XVEC (insn, 1))
for (i = 0; i < XVECLEN (insn, 1); i++)
@@ -811,12 +833,12 @@ gen_expand (insn)
d->n_operands = max_opno + 1;
d->n_dups = num_dups;
- mybcopy (constraints, d->constraints, sizeof constraints);
- mybcopy (op_n_alternatives, d->op_n_alternatives, sizeof op_n_alternatives);
- mybcopy (predicates, d->predicates, sizeof predicates);
- mybcopy (address_p, d->address_p, sizeof address_p);
- mybcopy (modes, d->modes, sizeof modes);
- mybcopy (strict_low, d->strict_low, sizeof strict_low);
+ memcpy (d->constraints, constraints, sizeof constraints);
+ memcpy (d->op_n_alternatives, op_n_alternatives, sizeof op_n_alternatives);
+ memcpy (d->predicates, predicates, sizeof predicates);
+ memcpy (d->address_p, address_p, sizeof address_p);
+ memcpy (d->modes, modes, sizeof modes);
+ memcpy (d->strict_low, strict_low, sizeof strict_low);
d->template = 0;
d->outfun = 0;
@@ -851,13 +873,13 @@ gen_split (split)
max_opno = -1;
num_dups = 0;
- mybzero (constraints, sizeof constraints);
- mybzero (op_n_alternatives, sizeof op_n_alternatives);
- mybzero (predicates, sizeof predicates);
- mybzero (address_p, sizeof address_p);
- mybzero (modes, sizeof modes);
- mybzero (strict_low, sizeof strict_low);
- mybzero (seen, sizeof seen);
+ memset (constraints, 0, sizeof constraints);
+ memset (op_n_alternatives, 0, sizeof op_n_alternatives);
+ memset (predicates, 0, sizeof predicates);
+ memset (address_p, 0, sizeof address_p);
+ memset (modes, 0, sizeof modes);
+ memset (strict_low, 0, sizeof strict_low);
+ memset (seen, 0, sizeof seen);
/* Get the number of operands by scanning all the
patterns of the split patterns.
@@ -867,12 +889,12 @@ gen_split (split)
d->n_operands = max_opno + 1;
- mybzero (d->constraints, sizeof constraints);
- mybzero (d->op_n_alternatives, sizeof op_n_alternatives);
- mybzero (d->predicates, sizeof predicates);
- mybzero (d->address_p, sizeof address_p);
- mybzero (d->modes, sizeof modes);
- mybzero (d->strict_low, sizeof strict_low);
+ memset (d->constraints, 0, sizeof constraints);
+ memset (d->op_n_alternatives, 0, sizeof op_n_alternatives);
+ memset (d->predicates, 0, sizeof predicates);
+ memset (d->address_p, 0, sizeof address_p);
+ memset (d->modes, 0, sizeof modes);
+ memset (d->strict_low, 0, sizeof strict_low);
d->n_dups = 0;
d->n_alternatives = 0;
@@ -880,59 +902,44 @@ gen_split (split)
d->outfun = 0;
}
-char *
+PTR
xmalloc (size)
- unsigned size;
+ size_t size;
{
- register char *val = (char *) malloc (size);
+ register PTR val = (PTR) malloc (size);
if (val == 0)
fatal ("virtual memory exhausted");
return val;
}
-char *
-xrealloc (ptr, size)
- char *ptr;
- unsigned size;
+PTR
+xrealloc (old, size)
+ PTR old;
+ size_t size;
{
- char *result = (char *) realloc (ptr, size);
- if (!result)
+ register PTR ptr;
+ if (old)
+ ptr = (PTR) realloc (old, size);
+ else
+ ptr = (PTR) malloc (size);
+ if (!ptr)
fatal ("virtual memory exhausted");
- return result;
-}
-
-static void
-mybzero (b, length)
- register char *b;
- register unsigned length;
-{
- while (length-- > 0)
- *b++ = 0;
-}
-
-static void
-mybcopy (b1, b2, length)
- register char *b1;
- register char *b2;
- register unsigned length;
-{
- while (length-- > 0)
- *b2++ = *b1++;
+ return ptr;
}
static void
-fatal VPROTO ((char *format, ...))
+fatal VPROTO ((const char *format, ...))
{
-#ifndef __STDC__
- char *format;
+#ifndef ANSI_PROTOTYPES
+ const char *format;
#endif
va_list ap;
VA_START (ap, format);
-#ifndef __STDC__
- format = va_arg (ap, char *);
+#ifndef ANSI_PROTOTYPES
+ format = va_arg (ap, const char *);
#endif
fprintf (stderr, "genoutput: ");
@@ -952,17 +959,17 @@ fancy_abort ()
}
static void
-error VPROTO ((char *format, ...))
+error VPROTO ((const char *format, ...))
{
-#ifndef __STDC__
- char *format;
+#ifndef ANSI_PROTOTYPES
+ const char *format;
#endif
va_list ap;
VA_START (ap, format);
-#ifndef __STDC__
- format = va_arg (ap, char *);
+#ifndef ANSI_PROTOTYPES
+ format = va_arg (ap, const char *);
#endif
fprintf (stderr, "genoutput: ");
diff --git a/gcc/genpeep.c b/gcc/genpeep.c
index 99fcec54ce5..dfba042e9b5 100644
--- a/gcc/genpeep.c
+++ b/gcc/genpeep.c
@@ -1,5 +1,5 @@
/* Generate code from machine description to perform peephole optimizations.
- Copyright (C) 1987, 1989, 1992, 1997, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1987, 89, 92, 97, 98, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -46,9 +46,9 @@ struct link
int vecelt;
};
-char *xmalloc PROTO((unsigned));
-static void fatal PVPROTO ((char *, ...)) ATTRIBUTE_PRINTF_1;
-void fancy_abort PROTO((void));
+static void fatal PVPROTO ((const char *, ...))
+ ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN;
+void fancy_abort PROTO((void)) ATTRIBUTE_NORETURN;
static int max_opno;
@@ -384,40 +384,44 @@ print_code (code)
}
}
-char *
+PTR
xmalloc (size)
- unsigned size;
+ size_t size;
{
- register char *val = (char *) malloc (size);
+ register PTR val = (PTR) malloc (size);
if (val == 0)
fatal ("virtual memory exhausted");
return val;
}
-char *
-xrealloc (ptr, size)
- char *ptr;
- unsigned size;
+PTR
+xrealloc (old, size)
+ PTR old;
+ size_t size;
{
- char *result = (char *) realloc (ptr, size);
- if (!result)
+ register PTR ptr;
+ if (old)
+ ptr = (PTR) realloc (old, size);
+ else
+ ptr = (PTR) malloc (size);
+ if (!ptr)
fatal ("virtual memory exhausted");
- return result;
+ return ptr;
}
static void
-fatal VPROTO ((char *format, ...))
+fatal VPROTO ((const char *format, ...))
{
-#ifndef __STDC__
- char *format;
+#ifndef ANSI_PROTOTYPES
+ const char *format;
#endif
va_list ap;
VA_START (ap, format);
-#ifndef __STDC__
- format = va_arg (ap, char *);
+#ifndef ANSI_PROTOTYPES
+ format = va_arg (ap, const char *);
#endif
fprintf (stderr, "genpeep: ");
@@ -466,10 +470,12 @@ from the machine description file `md'. */\n\n");
printf ("#include \"config.h\"\n");
printf ("#include \"system.h\"\n");
+ printf ("#include \"insn-config.h\"\n");
printf ("#include \"rtl.h\"\n");
printf ("#include \"regs.h\"\n");
printf ("#include \"output.h\"\n");
printf ("#include \"real.h\"\n");
+ printf ("#include \"recog.h\"\n");
printf ("#include \"except.h\"\n\n");
printf ("extern rtx peep_operand[];\n\n");
diff --git a/gcc/genrecog.c b/gcc/genrecog.c
index cffa47fd7b9..f1359470b6b 100644
--- a/gcc/genrecog.c
+++ b/gcc/genrecog.c
@@ -1,5 +1,5 @@
/* Generate code from machine description to recognize rtl as insns.
- Copyright (C) 1987, 88, 92, 93, 94, 95, 97, 98 Free Software Foundation, Inc.
+ Copyright (C) 1987, 88, 92-95, 97-98, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -51,14 +51,18 @@ Boston, MA 02111-1307, USA. */
#include "rtl.h"
#include "obstack.h"
+#define OUTPUT_LABEL(INDENT_STRING, LABEL_NUMBER) \
+ printf("%sL%d: ATTRIBUTE_UNUSED_LABEL\n", (INDENT_STRING), (LABEL_NUMBER))
+
static struct obstack obstack;
struct obstack *rtl_obstack = &obstack;
#define obstack_chunk_alloc xmalloc
#define obstack_chunk_free free
-/* Define this so we can link with print-rtl.o to get debug_rtx function. */
+/* Holds an array of names indexed by insn_code_number. */
char **insn_name_ptr = 0;
+int insn_name_ptr_size = 0;
/* Data structure for a listhead of decision trees. The alternatives
to a node are kept in a doublely-linked list so we can easily add nodes
@@ -86,7 +90,7 @@ struct decision
int elt_one_int; /* Required value for XINT (rtl, 1) */
int test_elt_zero_wide; /* Nonzero if should test XWINT (rtl, 0) */
HOST_WIDE_INT elt_zero_wide; /* Required value for XWINT (rtl, 0) */
- char *tests; /* If nonzero predicate to call */
+ const char *tests; /* If nonzero predicate to call */
int pred; /* `preds' index of predicate or -1 */
char *c_test; /* Additional test to perform */
struct decision_head success; /* Nodes to test on success */
@@ -137,7 +141,7 @@ static int max_depth;
static struct pred_table
{
- char *name;
+ const char *name;
RTX_CODE codes[NUM_RTX_CODE];
} preds[]
= {{"general_operand", {CONST_INT, CONST_DOUBLE, CONST, SYMBOL_REF,
@@ -157,6 +161,7 @@ static struct pred_table
{"nonmemory_operand", {CONST_INT, CONST_DOUBLE, CONST, SYMBOL_REF,
LABEL_REF, SUBREG, REG}},
{"push_operand", {MEM}},
+ {"pop_operand", {MEM}},
{"memory_operand", {SUBREG, MEM}},
{"indirect_operand", {SUBREG, MEM}},
{"comparison_operator", {EQ, NE, LE, LT, GE, GT, LEU, LTU, GEU, GTU}},
@@ -167,7 +172,7 @@ static struct pred_table
static struct decision_head make_insn_sequence PROTO((rtx, enum routine_type));
static struct decision *add_to_sequence PROTO((rtx, struct decision_head *,
- char *));
+ const char *));
static int not_both_true PROTO((struct decision *, struct decision *,
int));
static int position_merit PROTO((struct decision *, enum machine_mode,
@@ -177,24 +182,20 @@ static struct decision_head merge_trees PROTO((struct decision_head,
static int break_out_subroutines PROTO((struct decision_head,
enum routine_type, int));
static void write_subroutine PROTO((struct decision *, enum routine_type));
-static void write_tree_1 PROTO((struct decision *, char *,
+static void write_tree_1 PROTO((struct decision *, const char *,
struct decision *, enum routine_type));
static void print_code PROTO((enum rtx_code));
static int same_codes PROTO((struct decision *, enum rtx_code));
static void clear_codes PROTO((struct decision *));
static int same_modes PROTO((struct decision *, enum machine_mode));
static void clear_modes PROTO((struct decision *));
-static void write_tree PROTO((struct decision *, char *,
+static void write_tree PROTO((struct decision *, const char *,
struct decision *, int,
enum routine_type));
-static void change_state PROTO((char *, char *, int));
-static char *copystr PROTO((char *));
-static void mybzero PROTO((char *, unsigned));
-static void mybcopy PROTO((char *, char *, unsigned));
-static void fatal PVPROTO((char *, ...)) ATTRIBUTE_PRINTF_1;
-char *xrealloc PROTO((char *, unsigned));
-char *xmalloc PROTO((unsigned));
-void fancy_abort PROTO((void));
+static void change_state PROTO((const char *, const char *, int));
+static void fatal PVPROTO((const char *, ...))
+ ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN;
+void fancy_abort PROTO((void)) ATTRIBUTE_NORETURN;
/* Construct and return a sequence of decisions
that will recognize INSN.
@@ -211,6 +212,38 @@ make_insn_sequence (insn, type)
struct decision *last;
struct decision_head head;
+ {
+ static char *last_real_name = "insn";
+ static int last_real_code = 0;
+ char *name;
+
+ if (insn_name_ptr_size <= next_insn_code)
+ {
+ int new_size;
+ new_size = (insn_name_ptr_size ? insn_name_ptr_size * 2 : 512);
+ insn_name_ptr =
+ (char **) xrealloc (insn_name_ptr, sizeof(char *) * new_size);
+ bzero ((PTR)(insn_name_ptr + insn_name_ptr_size),
+ sizeof(char *) * (new_size - insn_name_ptr_size));
+ insn_name_ptr_size = new_size;
+ }
+
+ name = XSTR (insn, 0);
+ if (!name || name[0] == '\0')
+ {
+ name = xmalloc (strlen (last_real_name) + 10);
+ sprintf (name, "%s+%d", last_real_name,
+ next_insn_code - last_real_code);
+ }
+ else
+ {
+ last_real_name = name;
+ last_real_code = next_insn_code;
+ }
+
+ insn_name_ptr[next_insn_code] = name;
+ }
+
if (XVECLEN (insn, type == RECOG) == 1)
x = XVECEXP (insn, type == RECOG, 0);
else
@@ -292,7 +325,7 @@ static struct decision *
add_to_sequence (pattern, last, position)
rtx pattern;
struct decision_head *last;
- char *position;
+ const char *position;
{
register RTX_CODE code;
register struct decision *new
@@ -308,7 +341,7 @@ add_to_sequence (pattern, last, position)
max_depth = depth;
new->number = next_number++;
- new->position = copystr (position);
+ new->position = xstrdup (position);
new->ignore_code = 0;
new->ignore_mode = 0;
new->enforce_mode = 1;
@@ -416,7 +449,7 @@ add_to_sequence (pattern, last, position)
if (code == MATCH_OPERATOR || code == MATCH_PARALLEL)
{
- for (i = 0; i < XVECLEN (pattern, 2); i++)
+ for (i = 0; i < (size_t) XVECLEN (pattern, 2); i++)
{
newpos[depth] = i + (code == MATCH_OPERATOR ? '0': 'a');
new = add_to_sequence (XVECEXP (pattern, 2, i),
@@ -431,7 +464,7 @@ add_to_sequence (pattern, last, position)
new->dupno = XINT (pattern, 0);
new->code = UNKNOWN;
new->tests = 0;
- for (i = 0; i < XVECLEN (pattern, 1); i++)
+ for (i = 0; i < (size_t) XVECLEN (pattern, 1); i++)
{
newpos[depth] = i + '0';
new = add_to_sequence (XVECEXP (pattern, 1, i),
@@ -528,7 +561,7 @@ add_to_sequence (pattern, last, position)
fmt = GET_RTX_FORMAT (code);
len = GET_RTX_LENGTH (code);
- for (i = 0; i < len; i++)
+ for (i = 0; i < (size_t) len; i++)
{
newpos[depth] = '0' + i;
if (fmt[i] == 'e' || fmt[i] == 'u')
@@ -831,8 +864,7 @@ merge_trees (oldh, addh)
struct decision *split
= (struct decision *) xmalloc (sizeof (struct decision));
- mybcopy ((char *) old, (char *) split,
- sizeof (struct decision));
+ memcpy (split, old, sizeof (struct decision));
old->success.first = old->success.last = split;
old->c_test = 0;
@@ -858,8 +890,7 @@ merge_trees (oldh, addh)
struct decision *split
= (struct decision *) xmalloc (sizeof (struct decision));
- mybcopy ((char *) add, (char *) split,
- sizeof (struct decision));
+ memcpy (split, add, sizeof (struct decision));
add->success.first = add->success.last = split;
add->c_test = 0;
@@ -899,7 +930,11 @@ merge_trees (oldh, addh)
old->num_clobbers_to_add = 0;
}
else
- fatal ("Two actions at one point in tree");
+ fatal ("Two actions at one point in tree for insns \"%s\" (%d) and \"%s\" (%d)",
+ insn_name_ptr[old->insn_code_number],
+ old->insn_code_number,
+ insn_name_ptr[add->insn_code_number],
+ add->insn_code_number);
}
if (old->insn_code_number == -1)
@@ -1032,7 +1067,7 @@ write_subroutine (tree, type)
conditions or switch statements. We only support small indentations
and always indent at least two spaces. */
-static char *indents[]
+static const char *indents[]
= {" ", " ", " ", " ", " ", " ", " ", " ",
"\t", "\t ", "\t ", "\t ", "\t ", "\t ", "\t ",
"\t\t", "\t\t ", "\t\t ", "\t\t ", "\t\t ", "\t\t "};
@@ -1061,7 +1096,7 @@ static char *indents[]
static void
write_tree_1 (tree, prevpos, afterward, type)
struct decision *tree;
- char *prevpos;
+ const char *prevpos;
struct decision *afterward;
enum routine_type type;
{
@@ -1104,7 +1139,7 @@ write_tree_1 (tree, prevpos, afterward, type)
printf ("\n");
if (tree && tree->subroutine_number == 0)
{
- printf (" L%d:\n", tree->number);
+ OUTPUT_LABEL (" ", tree->number);
tree->label_needed = 0;
}
@@ -1240,7 +1275,7 @@ write_tree_1 (tree, prevpos, afterward, type)
if (p->label_needed && (p->retest_mode || p->retest_code))
{
- printf ("%sL%d:\n", indents[indent - 2], p->number);
+ OUTPUT_LABEL (indents[indent - 2], p->number);
p->label_needed = 0;
}
@@ -1298,7 +1333,7 @@ write_tree_1 (tree, prevpos, afterward, type)
if (switch_mode == VOIDmode && mode != VOIDmode && p->next != 0
&& p->next->enforce_mode && p->next->mode != VOIDmode)
{
- mybzero (modemap, sizeof modemap);
+ memset (modemap, 0, sizeof modemap);
printf ("%sswitch (GET_MODE (x%d))\n", indents[indent], depth);
printf ("%s{\n", indents[indent + 2]);
indent += 4;
@@ -1315,7 +1350,7 @@ write_tree_1 (tree, prevpos, afterward, type)
if (switch_code == UNKNOWN && p->code != UNKNOWN && ! p->ignore_code
&& p->next != 0 && p->next->code != UNKNOWN)
{
- mybzero (codemap, sizeof codemap);
+ memset (codemap, 0, sizeof codemap);
printf ("%sswitch (GET_CODE (x%d))\n", indents[indent], depth);
printf ("%s{\n", indents[indent + 2]);
indent += 4;
@@ -1331,7 +1366,7 @@ write_tree_1 (tree, prevpos, afterward, type)
/* Now that most mode and code tests have been done, we can write out
a label for an inner node, if we haven't already. */
if (p->label_needed)
- printf ("%sL%d:\n", indents[indent - 2], p->number);
+ OUTPUT_LABEL (indents[indent - 2], p->number);
inner_indent = indent;
@@ -1553,18 +1588,18 @@ clear_modes (p)
static void
write_tree (tree, prevpos, afterward, initial, type)
struct decision *tree;
- char *prevpos;
+ const char *prevpos;
struct decision *afterward;
int initial;
enum routine_type type;
{
register struct decision *p;
- char *name_prefix = (type == SPLIT ? "split" : "recog");
- char *call_suffix = (type == SPLIT ? "" : ", pnum_clobbers");
+ const char *name_prefix = (type == SPLIT ? "split" : "recog");
+ const char *call_suffix = (type == SPLIT ? "" : ", pnum_clobbers");
if (! initial && tree->subroutine_number > 0)
{
- printf (" L%d:\n", tree->number);
+ OUTPUT_LABEL (" ", tree->number);
if (afterward)
{
@@ -1599,8 +1634,8 @@ write_tree (tree, prevpos, afterward, initial, type)
static void
change_state (oldpos, newpos, indent)
- char *oldpos;
- char *newpos;
+ const char *oldpos;
+ const char *newpos;
int indent;
{
int odepth = strlen (oldpos);
@@ -1626,55 +1661,36 @@ change_state (oldpos, newpos, indent)
}
}
-static char *
-copystr (s1)
- char *s1;
-{
- register char *tem;
-
- if (s1 == 0)
- return 0;
-
- tem = (char *) xmalloc (strlen (s1) + 1);
- strcpy (tem, s1);
-
- return tem;
-}
-
-static void
-mybzero (b, length)
- register char *b;
- register unsigned length;
-{
- while (length-- > 0)
- *b++ = 0;
-}
-
-static void
-mybcopy (in, out, length)
- register char *in, *out;
- register unsigned length;
+char *
+xstrdup (input)
+ const char *input;
{
- while (length-- > 0)
- *out++ = *in++;
+ register size_t len = strlen (input) + 1;
+ register char *output = xmalloc (len);
+ memcpy (output, input, len);
+ return output;
}
-char *
-xrealloc (ptr, size)
- char *ptr;
- unsigned size;
+PTR
+xrealloc (old, size)
+ PTR old;
+ size_t size;
{
- char *result = (char *) realloc (ptr, size);
- if (!result)
+ register PTR ptr;
+ if (old)
+ ptr = (PTR) realloc (old, size);
+ else
+ ptr = (PTR) malloc (size);
+ if (!ptr)
fatal ("virtual memory exhausted");
- return result;
+ return ptr;
}
-char *
+PTR
xmalloc (size)
- unsigned size;
+ size_t size;
{
- register char *val = (char *) malloc (size);
+ register PTR val = (PTR) malloc (size);
if (val == 0)
fatal ("virtual memory exhausted");
@@ -1682,17 +1698,17 @@ xmalloc (size)
}
static void
-fatal VPROTO ((char *format, ...))
+fatal VPROTO ((const char *format, ...))
{
-#ifndef __STDC__
- char *format;
+#ifndef ANSI_PROTOTYPES
+ const char *format;
#endif
va_list ap;
VA_START (ap, format);
-#ifndef __STDC__
- format = va_arg (ap, char *);
+#ifndef ANSI_PROTOTYPES
+ format = va_arg (ap, const char *);
#endif
fprintf (stderr, "genrecog: ");
@@ -1801,10 +1817,6 @@ from the machine description file `md'. */\n\n");
printf ("*/\n\n");
- printf ("rtx recog_operand[MAX_RECOG_OPERANDS];\n\n");
- printf ("rtx *recog_operand_loc[MAX_RECOG_OPERANDS];\n\n");
- printf ("rtx *recog_dup_loc[MAX_DUP_OPERANDS];\n\n");
- printf ("char recog_dup_num[MAX_DUP_OPERANDS];\n\n");
printf ("#define operands recog_operand\n\n");
next_subroutine_number = 0;
diff --git a/gcc/getpwd.c b/gcc/getpwd.c
index 947383ef9a4..c3d155e5741 100644
--- a/gcc/getpwd.c
+++ b/gcc/getpwd.c
@@ -2,7 +2,6 @@
#include "config.h"
#include "system.h"
-#include <sys/stat.h>
/* Virtually every UN*X system now in common use (except for pre-4.3-tahoe
BSD systems) now provides getcwd as called for by POSIX. Allow for
@@ -20,9 +19,7 @@
#define GUESSPATHLEN 100
#endif /* (defined (USG) || defined (VMS)) */
-char *xmalloc ();
-
-#if !(defined (VMS) || (defined(_WIN32) && !defined(__CYGWIN32__)))
+#if !(defined (VMS) || (defined(_WIN32) && !defined(__CYGWIN__)))
/* Get the working directory. Use the PWD environment variable if it's
set correctly, since this is faster and gives more uniform answers
@@ -70,7 +67,7 @@ getpwd ()
return p;
}
-#else /* VMS || _WIN32 && !__CYGWIN32__ */
+#else /* VMS || _WIN32 && !__CYGWIN__ */
#ifndef MAXPATHLEN
#define MAXPATHLEN 255
@@ -90,4 +87,4 @@ getpwd ()
return pwd;
}
-#endif /* VMS || _WIN32 && !__CYGWIN32__ */
+#endif /* VMS || _WIN32 && !__CYGWIN__ */
diff --git a/gcc/ginclude/math-3300.h b/gcc/ginclude/math-3300.h
index 4e701257995..5d7ba28f67f 100644
--- a/gcc/ginclude/math-3300.h
+++ b/gcc/ginclude/math-3300.h
@@ -278,7 +278,7 @@ __inline static const double pow (const double x, const double y)
{
int i = (int) y;
- if (i & 1 == 0) /* even */
+ if ((i & 1) == 0) /* even */
return exp (y * log (x));
else
return - exp (y * log (x));
diff --git a/gcc/ginclude/va-sh.h b/gcc/ginclude/va-sh.h
index f1671c7b0b6..dc4e3ae8079 100644
--- a/gcc/ginclude/va-sh.h
+++ b/gcc/ginclude/va-sh.h
@@ -1,15 +1,18 @@
-/* This is just like the default gvarargs.h
- except for differences described below. */
+/* The ! __SH3E_VARG case is similar to the default gvarargs.h . */
+
+#if (defined (__SH3E__) || defined (__SH4_SINGLE__) || defined (__SH4__) || defined (__SH4_SINGLE_ONLY__)) && ! defined (__HITACHI__)
+#define __SH3E_VARG
+#endif
/* Define __gnuc_va_list. */
#ifndef __GNUC_VA_LIST
#define __GNUC_VA_LIST
-#ifdef __SH3E__
+#ifdef __SH3E_VARG
typedef long __va_greg;
-typedef double __va_freg;
+typedef float __va_freg;
typedef struct {
__va_greg * __va_next_o; /* next available register */
@@ -33,24 +36,24 @@ typedef void *__gnuc_va_list;
#ifdef _STDARG_H
-#ifdef __SH3E__
+#ifdef __SH3E_VARG
#define va_start(AP, LASTARG) \
__extension__ \
({ \
- AP.__va_next_fp = (__va_freg *) __builtin_saveregs (); \
- AP.__va_next_fp_limit = (AP.__va_next_fp + \
+ (AP).__va_next_fp = (__va_freg *) __builtin_saveregs (); \
+ (AP).__va_next_fp_limit = ((AP).__va_next_fp + \
(__builtin_args_info (1) < 8 ? 8 - __builtin_args_info (1) : 0)); \
- AP.__va_next_o = (__va_greg *) AP.__va_next_fp_limit; \
- AP.__va_next_o_limit = (AP.__va_next_o + \
+ (AP).__va_next_o = (__va_greg *) (AP).__va_next_fp_limit; \
+ (AP).__va_next_o_limit = ((AP).__va_next_o + \
(__builtin_args_info (0) < 4 ? 4 - __builtin_args_info (0) : 0)); \
- AP.__va_next_stack = (__va_greg *) __builtin_next_arg (LASTARG); \
+ (AP).__va_next_stack = (__va_greg *) __builtin_next_arg (LASTARG); \
})
#else /* ! SH3E */
#define va_start(AP, LASTARG) \
- (AP = ((__gnuc_va_list) __builtin_next_arg (LASTARG)))
+ ((AP) = ((__gnuc_va_list) __builtin_next_arg (LASTARG)))
#endif /* ! SH3E */
@@ -59,24 +62,26 @@ __extension__ \
#define va_alist __builtin_va_alist
#define va_dcl int __builtin_va_alist;...
-#ifdef __SH3E__
+#ifdef __SH3E_VARG
#define va_start(AP) \
__extension__ \
({ \
- AP.__va_next_fp = (__va_freg *) __builtin_saveregs (); \
- AP.__va_next_fp_limit = (AP.__va_next_fp + \
+ (AP).__va_next_fp = (__va_freg *) __builtin_saveregs (); \
+ (AP).__va_next_fp_limit = ((AP).__va_next_fp + \
(__builtin_args_info (1) < 8 ? 8 - __builtin_args_info (1) : 0)); \
- AP.__va_next_o = (__va_greg *) AP.__va_next_fp_limit; \
- AP.__va_next_o_limit = (AP.__va_next_o + \
+ (AP).__va_next_o = (__va_greg *) (AP).__va_next_fp_limit; \
+ (AP).__va_next_o_limit = ((AP).__va_next_o + \
(__builtin_args_info (0) < 4 ? 4 - __builtin_args_info (0) : 0)); \
- AP.__va_next_stack = (__va_greg *) __builtin_next_arg (__builtin_va_alist) \
- - (__builtin_args_info (0) >= 4 || __builtin_args_info (1) >= 8 ? 1 : 0); \
+ (AP).__va_next_stack \
+ = ((__va_greg *) __builtin_next_arg (__builtin_va_alist) \
+ - (__builtin_args_info (0) >= 4 || __builtin_args_info (1) >= 8 \
+ ? 1 : 0)); \
})
#else /* ! SH3E */
-#define va_start(AP) AP=(char *) &__builtin_va_alist
+#define va_start(AP) ((AP) = (char *) &__builtin_va_alist)
#endif /* ! SH3E */
@@ -136,53 +141,78 @@ enum __va_type_classes {
We want the MEM_IN_STRUCT_P bit set in the emitted RTL, therefore we
use unions even when it would otherwise be unnecessary. */
+/* gcc has an extension that allows to use a casted lvalue as an lvalue,
+ But it doesn't work in C++ with -pedantic - even in the presence of
+ __extension__ . We work around this problem by using a reference type. */
+#ifdef __cplusplus
+#define __VA_REF &
+#else
+#define __VA_REF
+#endif
+
#define __va_arg_sh1(AP, TYPE) __extension__ \
-__extension__ \
({(sizeof (TYPE) == 1 \
? ({union {TYPE t; char c;} __t; \
- asm("" \
- : "=r" (__t.c) \
- : "0" ((((union { int i, j; } *) (AP))++)->i)); \
+ __asm("" \
+ : "=r" (__t.c) \
+ : "0" ((((union { int i, j; } *__VA_REF) (AP))++)->i)); \
__t.t;}) \
: sizeof (TYPE) == 2 \
? ({union {TYPE t; short s;} __t; \
- asm("" \
- : "=r" (__t.s) \
- : "0" ((((union { int i, j; } *) (AP))++)->i)); \
+ __asm("" \
+ : "=r" (__t.s) \
+ : "0" ((((union { int i, j; } *__VA_REF) (AP))++)->i)); \
__t.t;}) \
: sizeof (TYPE) >= 4 || __LITTLE_ENDIAN_P \
- ? (((union { TYPE t; int i;} *) (AP))++)->t \
- : ((union {TYPE t;TYPE u;}*) ((char *)++(int *)(AP) - sizeof (TYPE)))->t);})
+ ? (((union { TYPE t; int i;} *__VA_REF) (AP))++)->t \
+ : ((union {TYPE t;TYPE u;}*) ((char *)++(int *__VA_REF)(AP) - sizeof (TYPE)))->t);})
-#ifdef __SH3E__
+#ifdef __SH3E_VARG
#define __PASS_AS_FLOAT(TYPE_CLASS,SIZE) \
(TYPE_CLASS == __real_type_class && SIZE == 4)
+#define __TARGET_SH4_P 0
+
+#if defined(__SH4__) || defined(__SH4_SINGLE__)
+#undef __PASS_AS_FLOAT
+#define __PASS_AS_FLOAT(TYPE_CLASS,SIZE) \
+ (TYPE_CLASS == __real_type_class && SIZE <= 8 \
+ || TYPE_CLASS == __complex_type_class && SIZE <= 16)
+#undef __TARGET_SH4_P
+#define __TARGET_SH4_P 1
+#endif
+
#define va_arg(pvar,TYPE) \
__extension__ \
({int __type = __builtin_classify_type (* (TYPE *) 0); \
void * __result_p; \
if (__PASS_AS_FLOAT (__type, sizeof(TYPE))) \
{ \
- if (pvar.__va_next_fp < pvar.__va_next_fp_limit) \
+ if ((pvar).__va_next_fp < (pvar).__va_next_fp_limit) \
{ \
- __result_p = &pvar.__va_next_fp; \
+ if (((__type == __real_type_class && sizeof (TYPE) > 4)\
+ || sizeof (TYPE) > 8) \
+ && (((int) (pvar).__va_next_fp ^ (int) (pvar).__va_next_fp_limit)\
+ & 4)) \
+ (pvar).__va_next_fp++; \
+ __result_p = &(pvar).__va_next_fp; \
} \
else \
- __result_p = &pvar.__va_next_stack; \
+ __result_p = &(pvar).__va_next_stack; \
} \
else \
{ \
- if (pvar.__va_next_o + ((sizeof (TYPE) + 3) / 4) \
- <= pvar.__va_next_o_limit) \
- __result_p = &pvar.__va_next_o; \
+ if ((pvar).__va_next_o + ((sizeof (TYPE) + 3) / 4) \
+ <= (pvar).__va_next_o_limit) \
+ __result_p = &(pvar).__va_next_o; \
else \
{ \
if (sizeof (TYPE) > 4) \
- pvar.__va_next_o = pvar.__va_next_o_limit; \
+ if (! __TARGET_SH4_P) \
+ (pvar).__va_next_o = (pvar).__va_next_o_limit; \
\
- __result_p = &pvar.__va_next_stack; \
+ __result_p = &(pvar).__va_next_stack; \
} \
} \
__va_arg_sh1(*(void **)__result_p, TYPE);})
@@ -194,6 +224,6 @@ __extension__ \
#endif /* SH3E */
/* Copy __gnuc_va_list into another variable of this type. */
-#define __va_copy(dest, src) (dest) = (src)
+#define __va_copy(dest, src) ((dest) = (src))
#endif /* defined (_STDARG_H) || defined (_VARARGS_H) */
diff --git a/gcc/global.c b/gcc/global.c
index af0fb3eb445..72231842706 100644
--- a/gcc/global.c
+++ b/gcc/global.c
@@ -1,5 +1,5 @@
/* Allocate registers for pseudo-registers that span basic blocks.
- Copyright (C) 1987, 88, 91, 94, 96, 1997 Free Software Foundation, Inc.
+ Copyright (C) 1987, 88, 91, 94, 96-98, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -262,7 +262,7 @@ static void expand_preferences PROTO((void));
static void prune_preferences PROTO((void));
static void find_reg PROTO((int, HARD_REG_SET, int, int, int));
static void record_one_conflict PROTO((int));
-static void record_conflicts PROTO((short *, int));
+static void record_conflicts PROTO((int *, int));
static void mark_reg_store PROTO((rtx, rtx));
static void mark_reg_clobber PROTO((rtx, rtx));
static void mark_reg_conflicts PROTO((rtx));
@@ -364,7 +364,7 @@ global_alloc (file)
SET_HARD_REG_BIT (regs_used_so_far, i);
#endif
- for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
+ for (i = FIRST_PSEUDO_REGISTER; i < (size_t) max_regno; i++)
if (reg_renumber[i] >= 0)
SET_HARD_REG_BIT (regs_used_so_far, reg_renumber[i]);
@@ -390,7 +390,7 @@ global_alloc (file)
reg_may_share[r2] = r1;
}
- for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
+ for (i = FIRST_PSEUDO_REGISTER; i < (size_t) max_regno; i++)
/* Note that reg_live_length[i] < 0 indicates a "constant" reg
that we are supposed to refrain from putting in a hard reg.
-2 means do make an allocno but don't allocate it. */
@@ -420,7 +420,7 @@ global_alloc (file)
bzero ((char *) allocno_n_refs, max_allocno * sizeof (int));
bzero ((char *) allocno_live_length, max_allocno * sizeof (int));
- for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
+ for (i = FIRST_PSEUDO_REGISTER; i < (size_t) max_regno; i++)
if (reg_allocno[i] >= 0)
{
int allocno = reg_allocno[i];
@@ -437,7 +437,7 @@ global_alloc (file)
override it. */
bzero ((char *) local_reg_live_length, sizeof local_reg_live_length);
bzero ((char *) local_reg_n_refs, sizeof local_reg_n_refs);
- for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
+ for (i = FIRST_PSEUDO_REGISTER; i < (size_t) max_regno; i++)
if (reg_renumber[i] >= 0)
{
int regno = reg_renumber[i];
@@ -508,7 +508,7 @@ global_alloc (file)
So in either case, we can ignore the conflict. Likewise for
preferences. */
- for (i = 0; i < max_allocno; i++)
+ for (i = 0; i < (size_t) max_allocno; i++)
{
AND_COMPL_HARD_REG_SET (hard_reg_conflicts[i], eliminable_regset);
AND_COMPL_HARD_REG_SET (hard_reg_copy_preferences[i],
@@ -523,7 +523,7 @@ global_alloc (file)
/* Determine the order to allocate the remaining pseudo registers. */
allocno_order = (int *) alloca (max_allocno * sizeof (int));
- for (i = 0; i < max_allocno; i++)
+ for (i = 0; i < (size_t) max_allocno; i++)
allocno_order[i] = i;
/* Default the size to 1, since allocno_compare uses it to divide by.
@@ -533,7 +533,7 @@ global_alloc (file)
allocate it. So avoid the divide-by-zero and set it to a low
priority. */
- for (i = 0; i < max_allocno; i++)
+ for (i = 0; i < (size_t) max_allocno; i++)
{
if (allocno_size[i] == 0)
allocno_size[i] = 1;
@@ -551,7 +551,7 @@ global_alloc (file)
/* Try allocating them, one by one, in that order,
except for parameters marked with reg_live_length[regno] == -2. */
- for (i = 0; i < max_allocno; i++)
+ for (i = 0; i < (size_t) max_allocno; i++)
if (reg_renumber[allocno_reg[allocno_order[i]]] < 0
&& REG_LIVE_LENGTH (allocno_reg[allocno_order[i]]) >= 0)
{
@@ -622,12 +622,12 @@ global_conflicts ()
{
register int b, i;
register rtx insn;
- short *block_start_allocnos;
+ int *block_start_allocnos;
/* Make a vector that mark_reg_{store,clobber} will store in. */
regs_set = (rtx *) alloca (max_parallel * sizeof (rtx) * 2);
- block_start_allocnos = (short *) alloca (max_allocno * sizeof (short));
+ block_start_allocnos = (int *) alloca (max_allocno * sizeof (int));
for (b = 0; b < n_basic_blocks; b++)
{
@@ -647,7 +647,7 @@ global_conflicts ()
are explicitly marked in basic_block_live_at_start. */
{
- register regset old = basic_block_live_at_start[b];
+ register regset old = BASIC_BLOCK (b)->global_live_at_start;
int ax = 0;
REG_SET_TO_HARD_REG_SET (hard_regs_live, old);
@@ -670,16 +670,26 @@ global_conflicts ()
record_conflicts (block_start_allocnos, ax);
#ifdef STACK_REGS
- /* Pseudos can't go in stack regs at the start of a basic block
- that can be reached through a computed goto, since reg-stack
- can't handle computed gotos. */
- if (basic_block_computed_jump_target[b])
- for (ax = FIRST_STACK_REG; ax <= LAST_STACK_REG; ax++)
- record_one_conflict (ax);
+ {
+ /* Pseudos can't go in stack regs at the start of a basic block
+ that can be reached through a computed goto, since reg-stack
+ can't handle computed gotos. */
+ /* ??? Seems more likely that reg-stack can't handle any abnormal
+ edges, critical or not, computed goto or otherwise. */
+
+ edge e;
+ for (e = BASIC_BLOCK (b)->pred; e ; e = e->pred_next)
+ if (e->flags & EDGE_ABNORMAL)
+ break;
+
+ if (e != NULL)
+ for (ax = FIRST_STACK_REG; ax <= LAST_STACK_REG; ax++)
+ record_one_conflict (ax);
+ }
#endif
}
- insn = basic_block_head[b];
+ insn = BLOCK_HEAD (b);
/* Scan the code of this basic block, noting which allocnos
and hard regs are born or die. When one is born,
@@ -738,9 +748,16 @@ global_conflicts ()
/* If INSN has multiple outputs, then any reg that dies here
and is used inside of an output
- must conflict with the other outputs. */
-
- if (GET_CODE (PATTERN (insn)) == PARALLEL && !single_set (insn))
+ must conflict with the other outputs.
+
+ It is unsafe to use !single_set here since it will ignore an
+ unused output. Just because an output is unused does not mean
+ the compiler can assume the side effect will not occur.
+ Consider if REG appears in the address of an output and we
+ reload the output. If we allocate REG to the same hard
+ register as an unused output we could set the hard register
+ before the output reload insn. */
+ if (GET_CODE (PATTERN (insn)) == PARALLEL && multiple_sets (insn))
for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
if (REG_NOTE_KIND (link) == REG_DEAD)
{
@@ -769,7 +786,7 @@ global_conflicts ()
mark_reg_death (regs_set[n_regs_set]);
}
- if (insn == basic_block_end[b])
+ if (insn == BLOCK_END (b))
break;
insn = NEXT_INSN (insn);
}
@@ -1290,7 +1307,7 @@ record_one_conflict (regno)
static void
record_conflicts (allocno_vec, len)
- register short *allocno_vec;
+ register int *allocno_vec;
register int len;
{
register int allocno;
@@ -1590,11 +1607,14 @@ mark_elimination (from, to)
int i;
for (i = 0; i < n_basic_blocks; i++)
- if (REGNO_REG_SET_P (basic_block_live_at_start[i], from))
- {
- CLEAR_REGNO_REG_SET (basic_block_live_at_start[i], from);
- SET_REGNO_REG_SET (basic_block_live_at_start[i], to);
- }
+ {
+ register regset r = BASIC_BLOCK (i)->global_live_at_start;
+ if (REGNO_REG_SET_P (r, from))
+ {
+ CLEAR_REGNO_REG_SET (r, from);
+ SET_REGNO_REG_SET (r, to);
+ }
+ }
}
/* Used for communication between the following functions. Holds the
@@ -1659,18 +1679,18 @@ build_insn_chain (first)
{
struct insn_chain *c;
- if (first == basic_block_head[b])
+ if (first == BLOCK_HEAD (b))
{
int i;
CLEAR_REG_SET (live_relevant_regs);
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
- if (REGNO_REG_SET_P (basic_block_live_at_start[b], i)
+ if (REGNO_REG_SET_P (BASIC_BLOCK (b)->global_live_at_start, i)
&& ! TEST_HARD_REG_BIT (eliminable_regset, i))
SET_REGNO_REG_SET (live_relevant_regs, i);
for (; i < max_regno; i++)
if (reg_renumber[i] >= 0
- && REGNO_REG_SET_P (basic_block_live_at_start[b], i))
+ && REGNO_REG_SET_P (BASIC_BLOCK (b)->global_live_at_start, i))
SET_REGNO_REG_SET (live_relevant_regs, i);
}
@@ -1719,8 +1739,22 @@ build_insn_chain (first)
}
}
- if (first == basic_block_end[b])
+ if (first == BLOCK_END (b))
b++;
+
+ /* Stop after we pass the end of the last basic block. Verify that
+ no real insns are after the end of the last basic block.
+
+ We may want to reorganize the loop somewhat since this test should
+ always be the right exit test. */
+ if (b == n_basic_blocks)
+ {
+ for (first = NEXT_INSN (first) ; first; first = NEXT_INSN (first))
+ if (GET_RTX_CLASS (GET_CODE (first)) == 'i'
+ && GET_CODE (PATTERN (first)) != USE)
+ abort ();
+ break;
+ }
}
FREE_REG_SET (live_relevant_regs);
*p = 0;
diff --git a/gcc/gmon.c b/gcc/gmon.c
index 04fc13adf9f..2bb7366197a 100644
--- a/gcc/gmon.c
+++ b/gcc/gmon.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 1991 The Regents of the University of California.
+ * Copyright (c) 1991, 1998 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/gcc/gthr-vxworks.h b/gcc/gthr-vxworks.h
index 98766467818..6d51ded2cda 100644
--- a/gcc/gthr-vxworks.h
+++ b/gcc/gthr-vxworks.h
@@ -60,11 +60,16 @@ extern __gthread_key_t eh_context_key;
don't map well enough onto VxWorks. */
static void
-__ehdtor ()
+__ehdtor (void *pTcb)
{
- if (eh_context_key)
- free ((void*)eh_context_key);
- eh_context_key = 0;
+ int tid = (int) pTcb;
+ void *p = (void*)taskVarGet(tid, &eh_context_key);
+ if (p != (void*)-1)
+ {
+ if (p)
+ free (p);
+ taskVarSet(tid, &eh_context_key, 0);
+ }
}
/* This only works for the code in libgcc2.c. */
@@ -74,6 +79,11 @@ __gthread_key_create (__gthread_key_t *key, void (*dtor) (void *))
{
*key = 0;
+ /* Do this first so that the task variables are visible during the
+ running of the delete hook. */
+
+ taskVarInit();
+
/* We don't have a way to track dtor here, so instead, we
register a generic routine that can cleanup any task. */
diff --git a/gcc/haifa-sched.c b/gcc/haifa-sched.c
index 8e1538c58e0..0b189e8f39d 100644
--- a/gcc/haifa-sched.c
+++ b/gcc/haifa-sched.c
@@ -1,5 +1,5 @@
/* Instruction scheduling pass.
- Copyright (C) 1992, 93-97, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1992, 93-98, 1999 Free Software Foundation, Inc.
Contributed by Michael Tiemann (tiemann@cygnus.com) Enhanced by,
and currently maintained by, Jim Wilson (wilson@cygnus.com)
@@ -136,8 +136,8 @@
This pass must update information that subsequent passes expect to
be correct. Namely: reg_n_refs, reg_n_sets, reg_n_deaths,
- reg_n_calls_crossed, and reg_live_length. Also, basic_block_head,
- basic_block_end.
+ reg_n_calls_crossed, and reg_live_length. Also, BLOCK_HEAD,
+ BLOCK_END.
The information in the line number notes is carefully retained by
this pass. Notes that refer to the starting and ending of
@@ -167,6 +167,7 @@
#include "insn-attr.h"
#include "except.h"
#include "toplev.h"
+#include "recog.h"
extern char *reg_known_equiv_p;
extern rtx *reg_known_value;
@@ -251,7 +252,9 @@ static int current_block_num;
by splitting insns. */
static rtx *reg_last_uses;
static rtx *reg_last_sets;
+static rtx *reg_last_clobbers;
static regset reg_pending_sets;
+static regset reg_pending_clobbers;
static int reg_pending_sets_all;
/* Vector indexed by INSN_UID giving the original ordering of the insns. */
@@ -294,9 +297,9 @@ static unsigned int *insn_blockage;
#define UNIT_BITS 5
#define BLOCKAGE_MASK ((1 << BLOCKAGE_BITS) - 1)
#define ENCODE_BLOCKAGE(U, R) \
-((((U) << UNIT_BITS) << BLOCKAGE_BITS \
+(((U) << BLOCKAGE_BITS \
| MIN_BLOCKAGE_COST (R)) << BLOCKAGE_BITS \
- | MAX_BLOCKAGE_COST (R))
+ | MAX_BLOCKAGE_COST (R))
#define UNIT_BLOCKED(B) ((B) >> (2 * BLOCKAGE_BITS))
#define BLOCKAGE_RANGE(B) \
(((((B) >> BLOCKAGE_BITS) & BLOCKAGE_MASK) << (HOST_BITS_PER_INT / 2)) \
@@ -448,11 +451,9 @@ static void attach_deaths_insn PROTO ((rtx));
static int new_sometimes_live PROTO ((struct sometimes *, int, int));
static void finish_sometimes_live PROTO ((struct sometimes *, int));
static int schedule_block PROTO ((int, int));
-static rtx regno_use_in PROTO ((int, rtx));
static void split_hard_reg_notes PROTO ((rtx, rtx, rtx));
static void new_insn_dead_notes PROTO ((rtx, rtx, rtx, rtx));
static void update_n_sets PROTO ((rtx, int));
-static void update_flow_info PROTO ((rtx, rtx, rtx, rtx));
static char *safe_concat PROTO ((char *, char *, char *));
static int insn_issue_delay PROTO ((rtx));
static int birthing_insn_p PROTO ((rtx));
@@ -474,8 +475,8 @@ typedef struct
int next_in;
int next_out;
}
-edge;
-static edge *edge_table;
+haifa_edge;
+static haifa_edge *edge_table;
#define NEXT_IN(edge) (edge_table[edge].next_in)
#define NEXT_OUT(edge) (edge_table[edge].next_out)
@@ -760,7 +761,6 @@ static rtx group_leader PROTO ((rtx));
static int set_priorities PROTO ((int));
static void init_rtx_vector PROTO ((rtx **, rtx *, int, int));
static void schedule_region PROTO ((int));
-static void split_block_insns PROTO ((int));
#endif /* INSN_SCHEDULING */
@@ -858,6 +858,12 @@ add_dependence (insn, elem, dep_type)
if (insn == elem)
return;
+ /* We can get a dependency on deleted insns due to optimizations in
+ the register allocation and reloading or due to splitting. Any
+ such dependency is useless and can be ignored. */
+ if (GET_CODE (elem) == NOTE)
+ return;
+
/* If elem is part of a sequence that must be scheduled together, then
make the dependence point to the last insn of the sequence.
When HAVE_cc0, it is possible for NOTEs to exist between users and
@@ -1046,6 +1052,7 @@ static rtx last_scheduled_insn;
static rtx **bb_reg_last_uses;
static rtx **bb_reg_last_sets;
+static rtx **bb_reg_last_clobbers;
static rtx *bb_pending_read_insns;
static rtx *bb_pending_read_mems;
@@ -1074,7 +1081,7 @@ is_cfg_nonregular ()
/* If we have a label that could be the target of a nonlocal goto, then
the cfg is not well structured. */
- if (nonlocal_label_rtx_list () != NULL)
+ if (nonlocal_goto_handler_labels)
return 1;
/* If we have any forced labels, then the cfg is not well structured. */
@@ -1096,7 +1103,7 @@ is_cfg_nonregular ()
the cfg not well structured. */
/* check for labels referred to other thn by jumps */
for (b = 0; b < n_basic_blocks; b++)
- for (insn = basic_block_head[b];; insn = NEXT_INSN (insn))
+ for (insn = BLOCK_HEAD (b);; insn = NEXT_INSN (insn))
{
code = GET_CODE (insn);
if (GET_RTX_CLASS (code) == 'i')
@@ -1108,7 +1115,7 @@ is_cfg_nonregular ()
return 1;
}
- if (insn == basic_block_end[b])
+ if (insn == BLOCK_END (b))
break;
}
@@ -1158,7 +1165,7 @@ build_control_flow (s_preds, s_succs, num_preds, num_succs)
in_edges = (int *) xcalloc (n_basic_blocks, sizeof (int));
out_edges = (int *) xcalloc (n_basic_blocks, sizeof (int));
- edge_table = (edge *) xcalloc (nr_edges, sizeof (edge));
+ edge_table = (haifa_edge *) xcalloc (nr_edges, sizeof (haifa_edge));
nr_edges = 0;
for (i = 0; i < n_basic_blocks; i++)
@@ -1397,8 +1404,8 @@ too_large (block, num_bbs, num_insns)
int block, *num_bbs, *num_insns;
{
(*num_bbs)++;
- (*num_insns) += (INSN_LUID (basic_block_end[block]) -
- INSN_LUID (basic_block_head[block]));
+ (*num_insns) += (INSN_LUID (BLOCK_END (block)) -
+ INSN_LUID (BLOCK_HEAD (block)));
if ((*num_bbs > MAX_RGN_BLOCKS) || (*num_insns > MAX_RGN_INSNS))
return 1;
else
@@ -1674,8 +1681,8 @@ find_rgns (s_preds, s_succs, num_preds, num_succs, dom)
/* Estimate # insns, and count # blocks in the region. */
num_bbs = 1;
- num_insns = (INSN_LUID (basic_block_end[i])
- - INSN_LUID (basic_block_head[i]));
+ num_insns = (INSN_LUID (BLOCK_END (i))
+ - INSN_LUID (BLOCK_HEAD (i)));
/* Find all loop latches (blocks which back edges to the loop
@@ -2141,7 +2148,8 @@ check_live_1 (src, x)
{
int b = candidate_table[src].split_bbs.first_member[i];
- if (REGNO_REG_SET_P (basic_block_live_at_start[b], regno + j))
+ if (REGNO_REG_SET_P (BASIC_BLOCK (b)->global_live_at_start,
+ regno + j))
{
return 0;
}
@@ -2155,7 +2163,7 @@ check_live_1 (src, x)
{
int b = candidate_table[src].split_bbs.first_member[i];
- if (REGNO_REG_SET_P (basic_block_live_at_start[b], regno))
+ if (REGNO_REG_SET_P (BASIC_BLOCK (b)->global_live_at_start, regno))
{
return 0;
}
@@ -2215,7 +2223,8 @@ update_live_1 (src, x)
{
int b = candidate_table[src].update_bbs.first_member[i];
- SET_REGNO_REG_SET (basic_block_live_at_start[b], regno + j);
+ SET_REGNO_REG_SET (BASIC_BLOCK (b)->global_live_at_start,
+ regno + j);
}
}
}
@@ -2225,7 +2234,7 @@ update_live_1 (src, x)
{
int b = candidate_table[src].update_bbs.first_member[i];
- SET_REGNO_REG_SET (basic_block_live_at_start[b], regno);
+ SET_REGNO_REG_SET (BASIC_BLOCK (b)->global_live_at_start, regno);
}
}
}
@@ -2850,7 +2859,7 @@ blockage_range (unit, insn)
unsigned int blockage = INSN_BLOCKAGE (insn);
unsigned int range;
- if (UNIT_BLOCKED (blockage) != unit + 1)
+ if ((int) UNIT_BLOCKED (blockage) != unit + 1)
{
range = function_units[unit].blockage_range_function (insn);
/* We only cache the blockage range for one unit and then only if
@@ -3295,6 +3304,7 @@ sched_analyze_1 (x, insn)
{
register int regno;
register rtx dest = SET_DEST (x);
+ enum rtx_code code = GET_CODE (x);
if (dest == 0)
return;
@@ -3339,15 +3349,25 @@ sched_analyze_1 (x, insn)
for (u = reg_last_uses[regno + i]; u; u = XEXP (u, 1))
add_dependence (insn, XEXP (u, 0), REG_DEP_ANTI);
- reg_last_uses[regno + i] = 0;
for (u = reg_last_sets[regno + i]; u; u = XEXP (u, 1))
add_dependence (insn, XEXP (u, 0), REG_DEP_OUTPUT);
- SET_REGNO_REG_SET (reg_pending_sets, regno + i);
+ /* Clobbers need not be ordered with respect to one another,
+ but sets must be ordered with respect to a pending clobber. */
+ if (code == SET)
+ {
+ reg_last_uses[regno + i] = 0;
+ for (u = reg_last_clobbers[regno + i]; u; u = XEXP (u, 1))
+ add_dependence (insn, XEXP (u, 0), REG_DEP_OUTPUT);
+ SET_REGNO_REG_SET (reg_pending_sets, regno + i);
+ }
+ else
+ SET_REGNO_REG_SET (reg_pending_clobbers, regno + i);
- if ((call_used_regs[regno + i] || global_regs[regno + i]))
- /* Function calls clobber all call_used regs. */
+ /* Function calls clobber all call_used regs. */
+ if (global_regs[regno + i]
+ || (code == SET && call_used_regs[regno + i]))
for (u = last_function_call; u; u = XEXP (u, 1))
add_dependence (insn, XEXP (u, 0), REG_DEP_ANTI);
}
@@ -3358,12 +3378,19 @@ sched_analyze_1 (x, insn)
for (u = reg_last_uses[regno]; u; u = XEXP (u, 1))
add_dependence (insn, XEXP (u, 0), REG_DEP_ANTI);
- reg_last_uses[regno] = 0;
for (u = reg_last_sets[regno]; u; u = XEXP (u, 1))
add_dependence (insn, XEXP (u, 0), REG_DEP_OUTPUT);
- SET_REGNO_REG_SET (reg_pending_sets, regno);
+ if (code == SET)
+ {
+ reg_last_uses[regno] = 0;
+ for (u = reg_last_clobbers[regno]; u; u = XEXP (u, 1))
+ add_dependence (insn, XEXP (u, 0), REG_DEP_OUTPUT);
+ SET_REGNO_REG_SET (reg_pending_sets, regno);
+ }
+ else
+ SET_REGNO_REG_SET (reg_pending_clobbers, regno);
/* Pseudos that are REG_EQUIV to something may be replaced
by that during reloading. We need only add dependencies for
@@ -3514,6 +3541,10 @@ sched_analyze_2 (x, insn)
for (u = reg_last_sets[regno + i]; u; u = XEXP (u, 1))
add_dependence (insn, XEXP (u, 0), 0);
+ /* ??? This should never happen. */
+ for (u = reg_last_clobbers[regno + i]; u; u = XEXP (u, 1))
+ add_dependence (insn, XEXP (u, 0), 0);
+
if ((call_used_regs[regno + i] || global_regs[regno + i]))
/* Function calls clobber all call_used regs. */
for (u = last_function_call; u; u = XEXP (u, 1))
@@ -3527,6 +3558,10 @@ sched_analyze_2 (x, insn)
for (u = reg_last_sets[regno]; u; u = XEXP (u, 1))
add_dependence (insn, XEXP (u, 0), 0);
+ /* ??? This should never happen. */
+ for (u = reg_last_clobbers[regno]; u; u = XEXP (u, 1))
+ add_dependence (insn, XEXP (u, 0), 0);
+
/* Pseudos that are REG_EQUIV to something may be replaced
by that during reloading. We need only add dependencies for
the address in the REG_EQUIV note. */
@@ -3617,9 +3652,11 @@ sched_analyze_2 (x, insn)
add_dependence (insn, XEXP (u, 0), REG_DEP_ANTI);
reg_last_uses[i] = 0;
- /* reg_last_sets[r] is now a list of insns */
for (u = reg_last_sets[i]; u; u = XEXP (u, 1))
add_dependence (insn, XEXP (u, 0), 0);
+
+ for (u = reg_last_clobbers[i]; u; u = XEXP (u, 1))
+ add_dependence (insn, XEXP (u, 0), 0);
}
reg_pending_sets_all = 1;
@@ -3748,9 +3785,11 @@ sched_analyze_insn (x, insn, loop_notes)
add_dependence (insn, XEXP (u, 0), REG_DEP_ANTI);
reg_last_uses[i] = 0;
- /* reg_last_sets[r] is now a list of insns */
for (u = reg_last_sets[i]; u; u = XEXP (u, 1))
add_dependence (insn, XEXP (u, 0), 0);
+
+ for (u = reg_last_clobbers[i]; u; u = XEXP (u, 1))
+ add_dependence (insn, XEXP (u, 0), 0);
}
reg_pending_sets_all = 1;
@@ -3759,41 +3798,29 @@ sched_analyze_insn (x, insn, loop_notes)
}
- /* After reload, it is possible for an instruction to have a REG_DEAD note
- for a register that actually dies a few instructions earlier. For
- example, this can happen with SECONDARY_MEMORY_NEEDED reloads.
- In this case, we must consider the insn to use the register mentioned
- in the REG_DEAD note. Otherwise, we may accidentally move this insn
- after another insn that sets the register, thus getting obviously invalid
- rtl. This confuses reorg which believes that REG_DEAD notes are still
- meaningful.
-
- ??? We would get better code if we fixed reload to put the REG_DEAD
- notes in the right places, but that may not be worth the effort. */
-
- if (reload_completed)
- {
- rtx note;
-
- for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
- if (REG_NOTE_KIND (note) == REG_DEAD)
- sched_analyze_2 (XEXP (note, 0), insn);
- }
-
+ /* Accumulate clobbers until the next set so that it will be output dependant
+ on all of them. At the next set we can clear the clobber list, since
+ subsequent sets will be output dependant on it. */
EXECUTE_IF_SET_IN_REG_SET (reg_pending_sets, 0, i,
{
- /* reg_last_sets[r] is now a list of insns */
free_list (&reg_last_sets[i], &unused_insn_list);
+ free_list (&reg_last_clobbers[i],
+ &unused_insn_list);
reg_last_sets[i]
= alloc_INSN_LIST (insn, NULL_RTX);
});
+ EXECUTE_IF_SET_IN_REG_SET (reg_pending_clobbers, 0, i,
+ {
+ reg_last_clobbers[i]
+ = alloc_INSN_LIST (insn, reg_last_clobbers[i]);
+ });
CLEAR_REG_SET (reg_pending_sets);
+ CLEAR_REG_SET (reg_pending_clobbers);
if (reg_pending_sets_all)
{
for (i = 0; i < maxreg; i++)
{
- /* reg_last_sets[r] is now a list of insns */
free_list (&reg_last_sets[i], &unused_insn_list);
reg_last_sets[i] = alloc_INSN_LIST (insn, NULL_RTX);
}
@@ -3891,9 +3918,11 @@ sched_analyze (head, tail)
reg_last_uses[i] = 0;
- /* reg_last_sets[r] is now a list of insns */
for (u = reg_last_sets[i]; u; u = XEXP (u, 1))
add_dependence (insn, XEXP (u, 0), 0);
+
+ for (u = reg_last_clobbers[i]; u; u = XEXP (u, 1))
+ add_dependence (insn, XEXP (u, 0), 0);
}
reg_pending_sets_all = 1;
@@ -3916,10 +3945,13 @@ sched_analyze (head, tail)
add_dependence (insn, XEXP (u, 0), REG_DEP_ANTI);
reg_last_uses[i] = 0;
- /* reg_last_sets[r] is now a list of insns */
for (u = reg_last_sets[i]; u; u = XEXP (u, 1))
add_dependence (insn, XEXP (u, 0), REG_DEP_ANTI);
+ if (global_regs[i])
+ for (u = reg_last_clobbers[i]; u; u = XEXP (u, 1))
+ add_dependence (insn, XEXP (u, 0), REG_DEP_ANTI);
+
SET_REGNO_REG_SET (reg_pending_sets, i);
}
}
@@ -4852,8 +4884,8 @@ get_block_head_tail (bb, headp, tailp)
b = BB_TO_BLOCK (bb);
/* HEAD and TAIL delimit the basic block being scheduled. */
- head = basic_block_head[b];
- tail = basic_block_end[b];
+ head = BLOCK_HEAD (b);
+ tail = BLOCK_END (b);
/* Don't include any notes or labels at the beginning of the
basic block, or notes at the ends of basic blocks. */
@@ -4934,7 +4966,7 @@ save_line_notes (bb)
get_block_head_tail (bb, &head, &tail);
next_tail = NEXT_INSN (tail);
- for (insn = basic_block_head[BB_TO_BLOCK (bb)];
+ for (insn = BLOCK_HEAD (BB_TO_BLOCK (bb));
insn != next_tail;
insn = NEXT_INSN (insn))
if (GET_CODE (insn) == NOTE && NOTE_LINE_NUMBER (insn) > 0)
@@ -4957,8 +4989,8 @@ restore_line_notes (bb)
b = BB_TO_BLOCK (bb);
- head = basic_block_head[b];
- next_tail = NEXT_INSN (basic_block_end[b]);
+ head = BLOCK_HEAD (b);
+ next_tail = NEXT_INSN (BLOCK_END (b));
/* Determine the current line-number. We want to know the current
line number of the first insn of the block here, in case it is
@@ -5144,7 +5176,7 @@ finish_sometimes_live (regs_sometimes_live, sometimes_max)
/* functions for computation of registers live/usage info */
-/* It is assumed that prior to scheduling basic_block_live_at_start (b)
+/* It is assumed that prior to scheduling BASIC_BLOCK (b)->global_live_at_start
contains the registers that are alive at the entry to b.
Two passes follow: The first pass is performed before the scheduling
@@ -5174,7 +5206,7 @@ find_pre_sched_live (bb)
int b = BB_TO_BLOCK (bb);
get_block_head_tail (bb, &head, &tail);
- COPY_REG_SET (bb_live_regs, basic_block_live_at_start[b]);
+ COPY_REG_SET (bb_live_regs, BASIC_BLOCK (b)->global_live_at_start);
next_tail = NEXT_INSN (tail);
for (insn = head; insn != next_tail; insn = NEXT_INSN (insn))
@@ -5312,7 +5344,8 @@ find_post_sched_live (bb)
int b_succ;
b_succ = TO_BLOCK (e);
- IOR_REG_SET (bb_live_regs, basic_block_live_at_start[b_succ]);
+ IOR_REG_SET (bb_live_regs,
+ BASIC_BLOCK (b_succ)->global_live_at_start);
e = NEXT_OUT (e);
}
while (e != first_edge);
@@ -5334,7 +5367,7 @@ find_post_sched_live (bb)
&& (GET_RTX_CLASS (GET_CODE (tail)) != 'i'))
{
if (current_nr_blocks > 1)
- COPY_REG_SET (basic_block_live_at_start[b], bb_live_regs);
+ COPY_REG_SET (BASIC_BLOCK (b)->global_live_at_start, bb_live_regs);
return;
}
@@ -5457,9 +5490,9 @@ find_post_sched_live (bb)
finish_sometimes_live (regs_sometimes_live, sometimes_max);
- /* In interblock scheduling, basic_block_live_at_start may have changed. */
+ /* In interblock scheduling, global_live_at_start may have changed. */
if (current_nr_blocks > 1)
- COPY_REG_SET (basic_block_live_at_start[b], bb_live_regs);
+ COPY_REG_SET (BASIC_BLOCK (b)->global_live_at_start, bb_live_regs);
FREE_REG_SET (old_live_regs);
@@ -5531,7 +5564,7 @@ update_reg_usage ()
pseudos which are live in more than one block.
This is because combine might have made an optimization which
- invalidated basic_block_live_at_start and reg_n_calls_crossed,
+ invalidated global_live_at_start and reg_n_calls_crossed,
but it does not update them. If we update reg_n_calls_crossed
here, the two variables are now inconsistent, and this might
confuse the caller-save code into saving a register that doesn't
@@ -5795,8 +5828,17 @@ print_exp (buf, x, verbose)
{
case PLUS:
op[0] = XEXP (x, 0);
- st[1] = "+";
- op[1] = XEXP (x, 1);
+ if (GET_CODE (XEXP (x, 1)) == CONST_INT
+ && INTVAL (XEXP (x, 1)) < 0)
+ {
+ st[1] = "-";
+ op[1] = GEN_INT (-INTVAL (XEXP (x, 1)));
+ }
+ else
+ {
+ st[1] = "+";
+ op[1] = XEXP (x, 1);
+ }
break;
case LO_SUM:
op[0] = XEXP (x, 0);
@@ -6122,7 +6164,7 @@ print_value (buf, x, verbose)
switch (GET_CODE (x))
{
case CONST_INT:
- sprintf (t, "0x%lx", (long)INTVAL (x));
+ sprintf (t, HOST_WIDE_INT_PRINT_HEX, INTVAL (x));
cur = safe_concat (buf, cur, t);
break;
case CONST_DOUBLE:
@@ -6695,8 +6737,7 @@ schedule_block (bb, rgn_n_insns)
fprintf (dump, ";; ======================================================\n");
fprintf (dump,
";; -- basic block %d from %d to %d -- %s reload\n",
- b, INSN_UID (basic_block_head[b]),
- INSN_UID (basic_block_end[b]),
+ b, INSN_UID (BLOCK_HEAD (b)), INSN_UID (BLOCK_END (b)),
(reload_completed ? "after" : "before"));
fprintf (dump, ";; ======================================================\n");
fprintf (dump, "\n");
@@ -6833,9 +6874,9 @@ schedule_block (bb, rgn_n_insns)
last = prev_head;
/* Initialize INSN_QUEUE, LIST and NEW_NEEDS. */
- new_needs = (NEXT_INSN (prev_head) == basic_block_head[b]
+ new_needs = (NEXT_INSN (prev_head) == BLOCK_HEAD (b)
? NEED_HEAD : NEED_NOTHING);
- if (PREV_INSN (next_tail) == basic_block_end[b])
+ if (PREV_INSN (next_tail) == BLOCK_END (b))
new_needs |= NEED_TAIL;
/* loop until all the insns in BB are scheduled. */
@@ -6919,29 +6960,29 @@ schedule_block (bb, rgn_n_insns)
/* Update source block boundaries. */
b1 = INSN_BLOCK (temp);
- if (temp == basic_block_head[b1]
- && insn == basic_block_end[b1])
+ if (temp == BLOCK_HEAD (b1)
+ && insn == BLOCK_END (b1))
{
/* We moved all the insns in the basic block.
Emit a note after the last insn and update the
begin/end boundaries to point to the note. */
emit_note_after (NOTE_INSN_DELETED, insn);
- basic_block_end[b1] = NEXT_INSN (insn);
- basic_block_head[b1] = NEXT_INSN (insn);
+ BLOCK_END (b1) = NEXT_INSN (insn);
+ BLOCK_HEAD (b1) = NEXT_INSN (insn);
}
- else if (insn == basic_block_end[b1])
+ else if (insn == BLOCK_END (b1))
{
/* We took insns from the end of the basic block,
so update the end of block boundary so that it
points to the first insn we did not move. */
- basic_block_end[b1] = PREV_INSN (temp);
+ BLOCK_END (b1) = PREV_INSN (temp);
}
- else if (temp == basic_block_head[b1])
+ else if (temp == BLOCK_HEAD (b1))
{
/* We took insns from the start of the basic block,
so update the start of block boundary so that
it points to the first insn we did not move. */
- basic_block_head[b1] = NEXT_INSN (insn);
+ BLOCK_HEAD (b1) = NEXT_INSN (insn);
}
}
else
@@ -7017,18 +7058,18 @@ schedule_block (bb, rgn_n_insns)
/* update target block boundaries. */
if (new_needs & NEED_HEAD)
- basic_block_head[b] = head;
+ BLOCK_HEAD (b) = head;
if (new_needs & NEED_TAIL)
- basic_block_end[b] = tail;
+ BLOCK_END (b) = tail;
/* debugging */
if (sched_verbose)
{
fprintf (dump, ";; total time = %d\n;; new basic block head = %d\n",
- clock_var, INSN_UID (basic_block_head[b]));
+ clock_var, INSN_UID (BLOCK_HEAD (b)));
fprintf (dump, ";; new basic block end = %d\n\n",
- INSN_UID (basic_block_end[b]));
+ INSN_UID (BLOCK_END (b)));
}
return (sched_n_insns);
@@ -7239,9 +7280,11 @@ compute_block_backward_dependences (bb)
{
reg_last_uses = (rtx *) alloca (max_reg * sizeof (rtx));
reg_last_sets = (rtx *) alloca (max_reg * sizeof (rtx));
+ reg_last_clobbers = (rtx *) alloca (max_reg * sizeof (rtx));
bzero ((char *) reg_last_uses, max_reg * sizeof (rtx));
bzero ((char *) reg_last_sets, max_reg * sizeof (rtx));
+ bzero ((char *) reg_last_clobbers, max_reg * sizeof (rtx));
pending_read_insns = 0;
pending_read_mems = 0;
@@ -7259,6 +7302,7 @@ compute_block_backward_dependences (bb)
{
reg_last_uses = bb_reg_last_uses[bb];
reg_last_sets = bb_reg_last_sets[bb];
+ reg_last_clobbers = bb_reg_last_clobbers[bb];
pending_read_insns = bb_pending_read_insns[bb];
pending_read_mems = bb_pending_read_mems[bb];
@@ -7330,6 +7374,16 @@ compute_block_backward_dependences (bb)
= alloc_INSN_LIST (XEXP (u, 0),
(bb_reg_last_sets[bb_succ])[reg]);
}
+
+ for (u = reg_last_clobbers[reg]; u; u = XEXP (u, 1))
+ {
+ if (find_insn_list (XEXP (u, 0), (bb_reg_last_clobbers[bb_succ])[reg]))
+ continue;
+
+ (bb_reg_last_clobbers[bb_succ])[reg]
+ = alloc_INSN_LIST (XEXP (u, 0),
+ (bb_reg_last_clobbers[bb_succ])[reg]);
+ }
}
/* mem read/write lists are inherited by bb_succ */
@@ -7404,6 +7458,8 @@ compute_block_backward_dependences (bb)
3-5% on average. */
for (b = 0; b < max_reg; ++b)
{
+ if (reg_last_clobbers[b])
+ free_list (&reg_last_clobbers[b], &unused_insn_list);
if (reg_last_sets[b])
free_list (&reg_last_sets[b], &unused_insn_list);
if (reg_last_uses[b])
@@ -7415,6 +7471,7 @@ compute_block_backward_dependences (bb)
{
bb_reg_last_uses[bb] = (rtx *) NULL_RTX;
bb_reg_last_sets[bb] = (rtx *) NULL_RTX;
+ bb_reg_last_clobbers[bb] = (rtx *) NULL_RTX;
}
}
@@ -7567,6 +7624,7 @@ schedule_region (rgn)
current_blocks = RGN_BLOCKS (rgn);
reg_pending_sets = ALLOCA_REG_SET ();
+ reg_pending_clobbers = ALLOCA_REG_SET ();
reg_pending_sets_all = 0;
/* initializations for region data dependence analyisis */
@@ -7578,21 +7636,34 @@ schedule_region (rgn)
bb_reg_last_uses = (rtx **) alloca (current_nr_blocks * sizeof (rtx *));
space = (rtx *) alloca (current_nr_blocks * maxreg * sizeof (rtx));
bzero ((char *) space, current_nr_blocks * maxreg * sizeof (rtx));
- init_rtx_vector (bb_reg_last_uses, space, current_nr_blocks, maxreg * sizeof (rtx *));
+ init_rtx_vector (bb_reg_last_uses, space, current_nr_blocks,
+ maxreg * sizeof (rtx *));
bb_reg_last_sets = (rtx **) alloca (current_nr_blocks * sizeof (rtx *));
space = (rtx *) alloca (current_nr_blocks * maxreg * sizeof (rtx));
bzero ((char *) space, current_nr_blocks * maxreg * sizeof (rtx));
- init_rtx_vector (bb_reg_last_sets, space, current_nr_blocks, maxreg * sizeof (rtx *));
+ init_rtx_vector (bb_reg_last_sets, space, current_nr_blocks,
+ maxreg * sizeof (rtx *));
+
+ bb_reg_last_clobbers =
+ (rtx **) alloca (current_nr_blocks * sizeof (rtx *));
+ space = (rtx *) alloca (current_nr_blocks * maxreg * sizeof (rtx));
+ bzero ((char *) space, current_nr_blocks * maxreg * sizeof (rtx));
+ init_rtx_vector (bb_reg_last_clobbers, space, current_nr_blocks,
+ maxreg * sizeof (rtx *));
bb_pending_read_insns = (rtx *) alloca (current_nr_blocks * sizeof (rtx));
bb_pending_read_mems = (rtx *) alloca (current_nr_blocks * sizeof (rtx));
- bb_pending_write_insns = (rtx *) alloca (current_nr_blocks * sizeof (rtx));
+ bb_pending_write_insns =
+ (rtx *) alloca (current_nr_blocks * sizeof (rtx));
bb_pending_write_mems = (rtx *) alloca (current_nr_blocks * sizeof (rtx));
- bb_pending_lists_length = (int *) alloca (current_nr_blocks * sizeof (int));
- bb_last_pending_memory_flush = (rtx *) alloca (current_nr_blocks * sizeof (rtx));
+ bb_pending_lists_length =
+ (int *) alloca (current_nr_blocks * sizeof (int));
+ bb_last_pending_memory_flush =
+ (rtx *) alloca (current_nr_blocks * sizeof (rtx));
bb_last_function_call = (rtx *) alloca (current_nr_blocks * sizeof (rtx));
- bb_sched_before_next_call = (rtx *) alloca (current_nr_blocks * sizeof (rtx));
+ bb_sched_before_next_call =
+ (rtx *) alloca (current_nr_blocks * sizeof (rtx));
init_rgn_data_dependences (current_nr_blocks);
}
@@ -7710,39 +7781,7 @@ schedule_region (rgn)
free_pending_lists ();
FREE_REG_SET (reg_pending_sets);
-}
-
-/* Subroutine of split_hard_reg_notes. Searches X for any reference to
- REGNO, returning the rtx of the reference found if any. Otherwise,
- returns 0. */
-
-static rtx
-regno_use_in (regno, x)
- int regno;
- rtx x;
-{
- register char *fmt;
- int i, j;
- rtx tem;
-
- if (GET_CODE (x) == REG && REGNO (x) == regno)
- return x;
-
- fmt = GET_RTX_FORMAT (GET_CODE (x));
- for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
- {
- if (fmt[i] == 'e')
- {
- if ((tem = regno_use_in (regno, XEXP (x, i))))
- return tem;
- }
- else if (fmt[i] == 'E')
- for (j = XVECLEN (x, i) - 1; j >= 0; j--)
- if ((tem = regno_use_in (regno, XVECEXP (x, i, j))))
- return tem;
- }
-
- return 0;
+ FREE_REG_SET (reg_pending_clobbers);
}
/* Subroutine of update_flow_info. Determines whether any new REG_NOTEs are
@@ -7931,7 +7970,7 @@ update_n_sets (x, inc)
the insns from FIRST to LAST inclusive that were created by splitting
ORIG_INSN. NOTES are the original REG_NOTES. */
-static void
+void
update_flow_info (notes, first, last, orig_insn)
rtx notes;
rtx first, last;
@@ -7999,16 +8038,7 @@ update_flow_info (notes, first, last, orig_insn)
register that was not needed by this instantiation of the
pattern, so we can safely ignore it. */
if (insn == first)
- {
- /* After reload, REG_DEAD notes come sometimes an
- instruction after the register actually dies. */
- if (reload_completed && REG_NOTE_KIND (note) == REG_DEAD)
- {
- XEXP (note, 1) = REG_NOTES (insn);
- REG_NOTES (insn) = note;
- break;
- }
-
+ {
if (REG_NOTE_KIND (note) != REG_UNUSED)
abort ();
@@ -8361,8 +8391,28 @@ update_flow_info (notes, first, last, orig_insn)
}
else if (!found_orig_dest)
{
- /* This should never happen. */
- abort ();
+ int i, regno;
+
+ /* Should never reach here for a pseudo reg. */
+ if (REGNO (orig_dest) >= FIRST_PSEUDO_REGISTER)
+ abort ();
+
+ /* This can happen for a hard register, if the splitter
+ does not bother to emit instructions which would be no-ops.
+ We try to verify that this is the case by checking to see if
+ the original instruction uses all of the registers that it
+ set. This case is OK, because deleting a no-op can not affect
+ REG_DEAD notes on other insns. If this is not the case, then
+ abort. */
+
+ regno = REGNO (orig_dest);
+ for (i = HARD_REGNO_NREGS (regno, GET_MODE (orig_dest)) - 1;
+ i >= 0; i--)
+ if (! refers_to_regno_p (regno + i, regno + i + 1, orig_insn,
+ NULL_PTR))
+ break;
+ if (i >= 0)
+ abort ();
}
}
@@ -8411,79 +8461,6 @@ update_flow_info (notes, first, last, orig_insn)
}
}
-/* Do the splitting of insns in the block b. */
-
-static void
-split_block_insns (b)
- int b;
-{
- rtx insn, next;
-
- for (insn = basic_block_head[b];; insn = next)
- {
- rtx set, last, first, notes;
-
- /* Can't use `next_real_insn' because that
- might go across CODE_LABELS and short-out basic blocks. */
- next = NEXT_INSN (insn);
- if (GET_CODE (insn) != INSN)
- {
- if (insn == basic_block_end[b])
- break;
-
- continue;
- }
-
- /* Don't split no-op move insns. These should silently disappear
- later in final. Splitting such insns would break the code
- that handles REG_NO_CONFLICT blocks. */
- set = single_set (insn);
- if (set && rtx_equal_p (SET_SRC (set), SET_DEST (set)))
- {
- if (insn == basic_block_end[b])
- break;
-
- /* Nops get in the way while scheduling, so delete them now if
- register allocation has already been done. It is too risky
- to try to do this before register allocation, and there are
- unlikely to be very many nops then anyways. */
- if (reload_completed)
- {
- PUT_CODE (insn, NOTE);
- NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
- NOTE_SOURCE_FILE (insn) = 0;
- }
-
- continue;
- }
-
- /* Split insns here to get max fine-grain parallelism. */
- first = PREV_INSN (insn);
- notes = REG_NOTES (insn);
- last = try_split (PATTERN (insn), insn, 1);
- if (last != insn)
- {
- /* try_split returns the NOTE that INSN became. */
- first = NEXT_INSN (first);
- update_flow_info (notes, first, last, insn);
-
- PUT_CODE (insn, NOTE);
- NOTE_SOURCE_FILE (insn) = 0;
- NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
- if (insn == basic_block_head[b])
- basic_block_head[b] = first;
- if (insn == basic_block_end[b])
- {
- basic_block_end[b] = last;
- break;
- }
- }
-
- if (insn == basic_block_end[b])
- break;
- }
-}
-
/* The one entry point in this file. DUMP_FILE is the dump file for
this pass. */
@@ -8537,7 +8514,7 @@ schedule_insns (dump_file)
/* do the splitting first for all blocks */
for (b = 0; b < n_basic_blocks; b++)
- split_block_insns (b);
+ split_block_insns (b, 1);
max_uid = (get_max_uid () + 1);
@@ -8555,12 +8532,12 @@ schedule_insns (dump_file)
luid = 0;
for (b = 0; b < n_basic_blocks; b++)
- for (insn = basic_block_head[b];; insn = NEXT_INSN (insn))
+ for (insn = BLOCK_HEAD (b);; insn = NEXT_INSN (insn))
{
INSN_BLOCK (insn) = b;
INSN_LUID (insn) = luid++;
- if (insn == basic_block_end[b])
+ if (insn == BLOCK_END (b))
break;
}
@@ -8571,7 +8548,7 @@ schedule_insns (dump_file)
rtx insn;
for (b = 0; b < n_basic_blocks; b++)
- for (insn = basic_block_head[b];; insn = NEXT_INSN (insn))
+ for (insn = BLOCK_HEAD (b);; insn = NEXT_INSN (insn))
{
rtx link, prev;
@@ -8593,7 +8570,7 @@ schedule_insns (dump_file)
}
}
- if (insn == basic_block_end[b])
+ if (insn == BLOCK_END (b))
break;
}
}
@@ -8635,7 +8612,7 @@ schedule_insns (dump_file)
/* The scheduler runs after flow; therefore, we can't blindly call
back into find_basic_blocks since doing so could invalidate the
- info in basic_block_live_at_start.
+ info in global_live_at_start.
Consider a block consisting entirely of dead stores; after life
analysis it would be a block of NOTE_INSN_DELETED notes. If
@@ -8726,7 +8703,7 @@ schedule_insns (dump_file)
determine the correct line number for the first insn of the block. */
for (b = 0; b < n_basic_blocks; b++)
- for (line = basic_block_head[b]; line; line = PREV_INSN (line))
+ for (line = BLOCK_HEAD (b); line; line = PREV_INSN (line))
if (GET_CODE (line) == NOTE && NOTE_LINE_NUMBER (line) > 0)
{
line_note_head[b] = line;
@@ -8753,15 +8730,15 @@ schedule_insns (dump_file)
/* ??? Add a NOTE after the last insn of the last basic block. It is not
known why this is done. */
- insn = basic_block_end[n_basic_blocks - 1];
+ insn = BLOCK_END (n_basic_blocks - 1);
if (NEXT_INSN (insn) == 0
|| (GET_CODE (insn) != NOTE
&& GET_CODE (insn) != CODE_LABEL
- /* Don't emit a NOTE if it would end up between an unconditional
- jump and a BARRIER. */
+ /* Don't emit a NOTE if it would end up between an unconditional
+ jump and a BARRIER. */
&& !(GET_CODE (insn) == JUMP_INSN
&& GET_CODE (NEXT_INSN (insn)) == BARRIER)))
- emit_note_after (NOTE_INSN_DELETED, basic_block_end[n_basic_blocks - 1]);
+ emit_note_after (NOTE_INSN_DELETED, BLOCK_END (n_basic_blocks - 1));
/* Schedule every region in the subroutine */
for (rgn = 0; rgn < nr_regions; rgn++)
diff --git a/gcc/halfpic.c b/gcc/halfpic.c
index 2c19c554f63..6233ca9b980 100644
--- a/gcc/halfpic.c
+++ b/gcc/halfpic.c
@@ -1,5 +1,5 @@
/* OSF/rose half-pic support functions.
- Copyright (C) 1992, 1997 Free Software Foundation, Inc.
+ Copyright (C) 1992, 1997, 1998 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -40,7 +40,6 @@ Boston, MA 02111-1307, USA. */
#define obstack_chunk_alloc xmalloc
#define obstack_chunk_free free
-extern char *xmalloc ();
extern rtx eliminate_constant_term ();
extern void assemble_name ();
extern void output_addr_const ();
@@ -217,10 +216,9 @@ half_pic_encode (decl)
#ifdef HALF_PIC_DEBUG
if (HALF_PIC_DEBUG)
{
- if (HALF_PIC_DEBUG)
- fprintf (stderr, "\n========== Half_pic_encode %.*s\n",
- IDENTIFIER_LENGTH (asm_name),
- IDENTIFIER_POINTER (asm_name));
+ fprintf (stderr, "\n========== Half_pic_encode %.*s\n",
+ IDENTIFIER_LENGTH (asm_name),
+ IDENTIFIER_POINTER (asm_name));
debug_tree (decl);
}
#endif
diff --git a/gcc/halfpic.h b/gcc/halfpic.h
index 80e6543de07..562121e191c 100644
--- a/gcc/halfpic.h
+++ b/gcc/halfpic.h
@@ -1,5 +1,5 @@
/* OSF/rose half-pic support definitions.
- Copyright (C) 1992, 1996, 1997 Free Software Foundation, Inc.
+ Copyright (C) 1992, 1996, 1997, 1998 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -20,9 +20,7 @@ Boston, MA 02111-1307, USA. */
#ifndef NO_HALF_PIC
-#include "gansidecl.h"
-
-#if defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__)
+#ifdef ANSI_PROTOTYPES
union tree_node; /* forward reference */
struct rtx_def;
#endif
diff --git a/gcc/hash.c b/gcc/hash.c
index 1428ae1c26b..f333c6c4d70 100644
--- a/gcc/hash.c
+++ b/gcc/hash.c
@@ -1,5 +1,5 @@
/* hash.c -- hash table routines
- Copyright (C) 1993, 94 Free Software Foundation, Inc.
+ Copyright (C) 1993, 1994, 1998 Free Software Foundation, Inc.
Written by Steve Chamberlain <sac@cygnus.com>
This file was lifted from BFD, the Binary File Descriptor library.
@@ -16,32 +16,32 @@ GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
#include "config.h"
#include "system.h"
#include "hash.h"
#include "obstack.h"
-#include "gansidecl.h"
#include "toplev.h"
/* Obstack allocation and deallocation routines. */
#define obstack_chunk_alloc xmalloc
#define obstack_chunk_free free
-extern char * xmalloc ();
-
/* The default number of entries to use when creating a hash table. */
#define DEFAULT_SIZE (1009)
/* Create a new hash table, given a number of entries. */
boolean
-hash_table_init_n (table, newfunc, size)
+hash_table_init_n (table, newfunc, hash, comp, size)
struct hash_table *table;
struct hash_entry *(*newfunc) PARAMS ((struct hash_entry *,
- struct hash_table *,
- const char *));
+ struct hash_table *,
+ hash_table_key));
+ unsigned long (*hash) PARAMS ((hash_table_key));
+ boolean (*comp) PARAMS ((hash_table_key, hash_table_key));
unsigned int size;
{
unsigned int alloc;
@@ -62,19 +62,23 @@ hash_table_init_n (table, newfunc, size)
memset ((PTR) table->table, 0, alloc);
table->size = size;
table->newfunc = newfunc;
+ table->hash = hash;
+ table->comp = comp;
return true;
}
/* Create a new hash table with the default number of entries. */
boolean
-hash_table_init (table, newfunc)
+hash_table_init (table, newfunc, hash, comp)
struct hash_table *table;
struct hash_entry *(*newfunc) PARAMS ((struct hash_entry *,
- struct hash_table *,
- const char *));
+ struct hash_table *,
+ hash_table_key));
+ unsigned long (*hash) PARAMS ((hash_table_key));
+ boolean (*comp) PARAMS ((hash_table_key, hash_table_key));
{
- return hash_table_init_n (table, newfunc, DEFAULT_SIZE);
+ return hash_table_init_n (table, newfunc, hash, comp, DEFAULT_SIZE);
}
/* Free a hash table. */
@@ -86,33 +90,22 @@ hash_table_free (table)
obstack_free (&table->memory, (PTR) NULL);
}
-/* Look up a string in a hash table. */
+/* Look up KEY in TABLE. If CREATE is non-NULL a new entry is
+ created if one does not previously exist. */
struct hash_entry *
-hash_lookup (table, string, create, copy)
+hash_lookup (table, key, create, copy)
struct hash_table *table;
- const char *string;
+ hash_table_key key;
boolean create;
- boolean copy;
+ hash_table_key (*copy) PARAMS ((struct obstack* memory,
+ hash_table_key key));
{
- register const unsigned char *s;
register unsigned long hash;
- register unsigned int c;
struct hash_entry *hashp;
- unsigned int len;
unsigned int index;
- hash = 0;
- len = 0;
- s = (const unsigned char *) string;
- while ((c = *s++) != '\0')
- {
- hash += c + (c << 17);
- hash ^= hash >> 2;
- ++len;
- }
- hash += len + (len << 17);
- hash ^= hash >> 2;
+ hash = (*table->hash)(key);
index = hash % table->size;
for (hashp = table->table[index];
@@ -120,30 +113,19 @@ hash_lookup (table, string, create, copy)
hashp = hashp->next)
{
if (hashp->hash == hash
- && strcmp (hashp->string, string) == 0)
+ && (*table->comp)(hashp->key, key))
return hashp;
}
if (! create)
return (struct hash_entry *) NULL;
- hashp = (*table->newfunc) ((struct hash_entry *) NULL, table, string);
+ hashp = (*table->newfunc) ((struct hash_entry *) NULL, table, key);
if (hashp == (struct hash_entry *) NULL)
return (struct hash_entry *) NULL;
if (copy)
- {
- char *new;
-
- new = (char *) obstack_alloc (&table->memory, len + 1);
- if (!new)
- {
- error ("no memory");
- return (struct hash_entry *) NULL;
- }
- strcpy (new, string);
- string = new;
- }
- hashp->string = string;
+ key = (*copy) (&table->memory, key);
+ hashp->key = key;
hashp->hash = hash;
hashp->next = table->table[index];
table->table[index] = hashp;
@@ -155,10 +137,10 @@ hash_lookup (table, string, create, copy)
/*ARGSUSED*/
struct hash_entry *
-hash_newfunc (entry, table, string)
+hash_newfunc (entry, table, p)
struct hash_entry *entry;
struct hash_table *table;
- const char *string;
+ hash_table_key p;
{
if (entry == (struct hash_entry *) NULL)
entry = ((struct hash_entry *)
@@ -186,7 +168,7 @@ hash_allocate (table, size)
void
hash_traverse (table, func, info)
struct hash_table *table;
- boolean (*func) PARAMS ((struct hash_entry *, PTR));
+ boolean (*func) PARAMS ((struct hash_entry *, hash_table_key));
PTR info;
{
unsigned int i;
@@ -202,3 +184,62 @@ hash_traverse (table, func, info)
}
}
}
+
+/* Hash a string. Return a hash-code for the string. */
+
+unsigned long
+string_hash (k)
+ hash_table_key k;
+{
+ const unsigned char *s;
+ unsigned long hash;
+ unsigned char c;
+ unsigned int len;
+
+ s = (const unsigned char *) k;
+ hash = 0;
+ len = 0;
+
+ while ((c = *s++) != '\0')
+ {
+ hash += c + (c << 17);
+ hash ^= hash >> 2;
+ ++len;
+ }
+ hash += len + (len << 17);
+ hash ^= hash >> 2;
+
+ return hash;
+}
+
+/* Compare two strings. Return non-zero iff the two strings are
+ the same. */
+
+boolean
+string_compare (k1, k2)
+ hash_table_key k1;
+ hash_table_key k2;
+{
+ return (strcmp ((char*) k1, (char*) k2) == 0);
+}
+
+/* Copy K to OBSTACK. */
+
+hash_table_key
+string_copy (memory, k)
+ struct obstack* memory;
+ hash_table_key k;
+{
+ char *new;
+ char *string = (char*) k;
+
+ new = (char *) obstack_alloc (memory, strlen (string) + 1);
+ if (!new)
+ {
+ error ("no memory");
+ return NULL;
+ }
+ strcpy (new, string);
+
+ return new;
+}
diff --git a/gcc/hash.h b/gcc/hash.h
index 5a3838c5ace..ac3b1ede570 100644
--- a/gcc/hash.h
+++ b/gcc/hash.h
@@ -1,5 +1,5 @@
/* Header file for generic hash table support.
- Copyright (C) 1993, 94 Free Software Foundation, Inc.
+ Copyright (C) 1993, 1994, 1997, 1998 Free Software Foundation, Inc.
Written by Steve Chamberlain <sac@cygnus.com>
This file was lifted from BFD, the Binary File Descriptor library.
@@ -16,38 +16,19 @@ GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
-
-#ifdef IN_GCC
-
-/* Add prototype support. */
-#ifndef PROTO
-#if defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__)
-#define PROTO(ARGS) ARGS
-#else
-#define PROTO(ARGS) ()
-#endif
-#endif
-
-#define PARAMS(ARGS) PROTO(ARGS)
-
-#ifdef __STDC__
-#define PTR void *
-#else
-#ifndef const
-#define const
-#endif
-#define PTR char *
-#endif
-
-#else /* ! IN_GCC */
+Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#ifndef IN_GCC
#include <ansidecl.h>
-#endif /* IN_GCC */
+#endif /* ! IN_GCC */
#include "obstack.h"
typedef enum {false, true} boolean;
+typedef PTR hash_table_key;
+
/* Hash table routines. There is no way to free up a hash table. */
/* An element in the hash table. Most uses will actually use a larger
@@ -57,8 +38,8 @@ struct hash_entry
{
/* Next entry for this hash code. */
struct hash_entry *next;
- /* String being hashed. */
- const char *string;
+ /* The thing being hashed. */
+ hash_table_key key;
/* Hash code. This is the full hash code, not the index into the
table. */
unsigned long hash;
@@ -81,7 +62,11 @@ struct hash_table
only if the argument is NULL. */
struct hash_entry *(*newfunc) PARAMS ((struct hash_entry *,
struct hash_table *,
- const char *));
+ hash_table_key));
+ /* A function to compute the hash code for a key in the hash table. */
+ unsigned long (*hash) PARAMS ((hash_table_key));
+ /* A function to compare two keys. */
+ boolean (*comp) PARAMS ((hash_table_key, hash_table_key));
/* An obstack for this hash table. */
struct obstack memory;
};
@@ -91,31 +76,35 @@ extern boolean hash_table_init
PARAMS ((struct hash_table *,
struct hash_entry *(*) (struct hash_entry *,
struct hash_table *,
- const char *)));
+ hash_table_key),
+ unsigned long (*hash) (hash_table_key),
+ boolean (*comp) (hash_table_key, hash_table_key)));
/* Initialize a hash table specifying a size. */
extern boolean hash_table_init_n
PARAMS ((struct hash_table *,
struct hash_entry *(*) (struct hash_entry *,
struct hash_table *,
- const char *),
+ hash_table_key),
+ unsigned long (*hash) (hash_table_key),
+ boolean (*comp) (hash_table_key, hash_table_key),
unsigned int size));
/* Free up a hash table. */
extern void hash_table_free PARAMS ((struct hash_table *));
-/* Look up a string in a hash table. If CREATE is true, a new entry
- will be created for this string if one does not already exist. The
- COPY argument must be true if this routine should copy the string
- into newly allocated memory when adding an entry. */
+/* Look up KEY in a hash table. If CREATE is true, a new entry
+ will be created for this KEY if one does not already exist. If
+ COPY is non-NULL, it is used to copy the KEY before storing it in
+ the hash table. */
extern struct hash_entry *hash_lookup
- PARAMS ((struct hash_table *, const char *, boolean create,
- boolean copy));
+ PARAMS ((struct hash_table *, hash_table_key key, boolean create,
+ hash_table_key (*copy)(struct obstack*, hash_table_key)));
/* Base method for creating a hash table entry. */
extern struct hash_entry *hash_newfunc
- PARAMS ((struct hash_entry *, struct hash_table *,
- const char *));
+ PARAMS ((struct hash_entry *, struct hash_table *,
+ hash_table_key key));
/* Grab some space for a hash table entry. */
extern PTR hash_allocate PARAMS ((struct hash_table *,
@@ -126,5 +115,17 @@ extern PTR hash_allocate PARAMS ((struct hash_table *,
INFO argument is passed to the function. */
extern void hash_traverse PARAMS ((struct hash_table *,
boolean (*) (struct hash_entry *,
- PTR),
- PTR info));
+ hash_table_key),
+ hash_table_key info));
+
+/* Hash a string K, which is really of type `char*'. */
+extern unsigned long string_hash PARAMS ((hash_table_key k));
+
+/* Compare two strings K1, K2 which are really of type `char*'. */
+extern boolean string_compare PARAMS ((hash_table_key k1,
+ hash_table_key k2));
+
+/* Copy a string K, which is really of type `char*'. */
+extern hash_table_key string_copy PARAMS ((struct obstack* memory,
+ hash_table_key k));
+
diff --git a/gcc/input.h b/gcc/input.h
index 7bcde83f975..5de5cdeb0fe 100644
--- a/gcc/input.h
+++ b/gcc/input.h
@@ -1,6 +1,6 @@
/* Declarations for variables relating to reading the source file.
Used by parsers, lexical analyzers, and error message routines.
- Copyright (C) 1993, 1997 Free Software Foundation, Inc.
+ Copyright (C) 1993, 1997, 1998 Free Software Foundation, Inc.
This file is part of GNU CC.
diff --git a/gcc/install.texi b/gcc/install.texi
index 5e3da8e58c1..0e51c5fd2ff 100644
--- a/gcc/install.texi
+++ b/gcc/install.texi
@@ -1,4 +1,4 @@
-@c Copyright (C) 1988,89,92,93,94,95,96,97,1998 Free Software Foundation, Inc.
+@c Copyright (C) 1988, 89, 92-98, 1999 Free Software Foundation, Inc.
@c This is part of the GCC manual.
@c For copying conditions, see the file gcc.texi.
@@ -15,6 +15,7 @@ install procedures. It is provided for historical reference only.
@cindex installing GNU CC
@menu
+* Configuration Files:: Files created by running @code{configure}.
* Configurations:: Configurations Supported by GNU CC.
* Other Dir:: Compiling in a separate directory (not where the source is).
* Cross-Compiler:: Building and installing a cross-compiler.
@@ -24,11 +25,11 @@ install procedures. It is provided for historical reference only.
* Header Dirs:: Understanding the standard header file directories.
@end menu
-Here is the procedure for installing GNU CC on a Unix system. See
-@ref{VMS Install}, for VMS systems. In this section we assume you
+Here is the procedure for installing GNU CC on a GNU or Unix system.
+See @ref{VMS Install}, for VMS systems. In this section we assume you
compile in the same directory that contains the source files; see
-@ref{Other Dir}, to find out how to compile in a separate directory on Unix
-systems.
+@ref{Other Dir}, to find out how to compile in a separate directory on
+Unix systems.
You cannot install GNU C by itself on MSDOS; it will not compile under
any MSDOS compiler except itself. You need to get the complete
@@ -49,9 +50,32 @@ On a System V release 4 system, make sure @file{/usr/bin} precedes
@file{/usr/ucb} in @code{PATH}. The @code{cc} command in
@file{/usr/ucb} uses libraries which have bugs.
+@cindex Bison parser generator
+@cindex parser generator, Bison
+@item
+Make sure the Bison parser generator is installed. (This is
+unnecessary if the Bison output files @file{c-parse.c} and
+@file{cexp.c} are more recent than @file{c-parse.y} and @file{cexp.y}
+and you do not plan to change the @samp{.y} files.)
+
+Bison versions older than Sept 8, 1988 will produce incorrect output
+for @file{c-parse.c}.
+
+@item
+If you have chosen a configuration for GNU CC which requires other GNU
+tools (such as GAS or the GNU linker) instead of the standard system
+tools, install the required tools in the build directory under the names
+@file{as}, @file{ld} or whatever is appropriate. This will enable the
+compiler to find the proper tools for compilation of the program
+@file{enquire}.
+
+Alternatively, you can do subsequent compilation using a value of the
+@code{PATH} environment variable such that the necessary GNU tools come
+before the standard system tools.
+
@item
Specify the host, build and target machine configurations. You do this
-by running the file @file{configure}.
+when you run the @file{configure} script.
The @dfn{build} machine is the system which you are using, the
@dfn{host} machine is the system where you want to run the resulting
@@ -100,10 +124,11 @@ See @ref{Configurations}, for a list of supported configuration names and
notes on many of the configurations. You should check the notes in that
section before proceeding any further with the installation of GNU CC.
-There are four additional options you can specify independently to
-describe variant hardware and software configurations. These are
-@samp{--with-gnu-as}, @samp{--with-gnu-ld}, @samp{--with-stabs} and
-@samp{--nfp}.
+@item
+When running @code{configure}, you may also need to specify certain
+additional options that describe variant hardware and software
+configurations. These are @samp{--with-gnu-as}, @samp{--with-gnu-ld},
+@samp{--with-stabs} and @samp{--nfp}.
@table @samp
@item --with-gnu-as
@@ -207,7 +232,6 @@ of tree node types when referencing fields of that node. This does not
change the generated code, but adds error checking within the compiler.
This will slow down the compiler and may only work properly if you
are building the compiler with GNU C.
-@end table
The @file{configure} script searches subdirectories of the source
directory for other compilers that are to be integrated into GNU CC.
@@ -252,16 +276,42 @@ A file named @file{tm.h} is created which includes the
machine-description macro file for your target machine. It should be in
the subdirectory @file{config} and its name is often
@file{@var{machine}.h}.
+@end itemize
+
+@cindex Native Language Support
+@cindex NLS
+@item --enable-nls
+@itemx --disable-nls
+The @samp{--enable-nls} option enables Native Language Support (NLS),
+which lets GCC output diagnostics in languages other than American
+English. No translations are available yet, so the main users of this
+option now are those translating GCC's diagnostics who want to test
+their work. Once translations become available, Native Language Support
+will become enabled by default. The @samp{--disable-nls} option
+disables NLS.
+
+@cindex @code{gettext}
+@item --with-included-gettext
+If NLS is enabled, the GCC build procedure normally attempts to use the
+host's @code{gettext} libraries, and falls back on GCC's copy of the GNU
+@code{gettext} library only if the host libraries do not suffice. The
+@samp{--with-included-gettext} option causes the build procedure to
+prefer its copy of GNU @code{gettext}.
+
+@cindex @code{catgets}
+@item --with-catgets
+If NLS is enabled, and if the host lacks @code{gettext} but has the
+inferior @code{catgets} interface, the GCC build procedure normally
+ignores @code{catgets} and instead uses GCC's copy of the GNU
+@code{gettext} library. The @samp{--with-catgets} option causes the
+build procedure to use the host's @code{catgets} in this situation.
+@end table
@item
-The command file @file{configure} also constructs the file
-@file{Makefile} by adding some text to the template file
-@file{Makefile.in}. The additional text comes from files in the
-@file{config} directory, named @file{t-@var{target}} and
-@file{x-@var{host}}. If these files do not exist, it means nothing
-needs to be added for a given target or host.
-@end itemize
+In certain cases, you should specify certain other options when you run
+@code{configure}.
+@itemize @bullet
@item
The standard directory for installing GNU CC is @file{/usr/local/lib}.
If you want to install its files somewhere else, specify
@@ -303,29 +353,7 @@ Indications are that people who use this option use it based on
mistaken ideas of what it is for. People use it as if it specified
where to install part of GNU CC. Perhaps they make this assumption
because installing GNU CC creates the directory.
-
-@cindex Bison parser generator
-@cindex parser generator, Bison
-@item
-Make sure the Bison parser generator is installed. (This is
-unnecessary if the Bison output files @file{c-parse.c} and
-@file{cexp.c} are more recent than @file{c-parse.y} and @file{cexp.y}
-and you do not plan to change the @samp{.y} files.)
-
-Bison versions older than Sept 8, 1988 will produce incorrect output
-for @file{c-parse.c}.
-
-@item
-If you have chosen a configuration for GNU CC which requires other GNU
-tools (such as GAS or the GNU linker) instead of the standard system
-tools, install the required tools in the build directory under the names
-@file{as}, @file{ld} or whatever is appropriate. This will enable the
-compiler to find the proper tools for compilation of the program
-@file{enquire}.
-
-Alternatively, you can do subsequent compilation using a value of the
-@code{PATH} environment variable such that the necessary GNU tools come
-before the standard system tools.
+@end itemize
@item
Build the compiler. Just type @samp{make LANGUAGES=c} in the compiler
@@ -360,9 +388,9 @@ should be investigated and reported (@pxref{Bugs}).
should be investigated and reported.
@end ifset
-Some commercial compilers fail to compile GNU CC because they have bugs
-or limitations. For example, the Microsoft compiler is said to run out
-of macro space. Some Ultrix compilers run out of expression space; then
+Some compilers fail to compile GNU CC because they have bugs or
+limitations. For example, the Microsoft compiler is said to run out of
+macro space. Some Ultrix compilers run out of expression space; then
you need to break up the statement where the problem happens.
@item
@@ -457,8 +485,8 @@ instead of making @file{stage1}, @file{stage2}, and performing
the two compiler builds.
@item
-Then compare the latest object files with the stage 2 object
-files---they ought to be identical, aside from time stamps (if any).
+Compare the latest object files with the stage 2 object files---they
+ought to be identical, aside from time stamps (if any).
On some systems, meaningful comparison of object files is impossible;
they always appear ``different.'' This is currently true on Solaris and
@@ -546,11 +574,8 @@ compiler.)
@item
@cindex C++ runtime library
@cindex @code{libstdc++}
-If you're going to use C++, it's likely that you need to also install
-a C++ runtime library. Just as GNU C does not
-distribute a C runtime library, it also does not include a C++ runtime
-library. All I/O functionality, special class libraries, etc., are
-provided by the C++ runtime library.
+If you're going to use C++, you need to install the C++ runtime library.
+This includes all I/O functionality, special class libraries, etc.
The standard C++ runtime library for GNU CC is called @samp{libstdc++}.
An obsolescent library @samp{libg++} may also be available, but it's
@@ -643,6 +668,56 @@ Microsoft Win32 API thread support.
@end itemize
@end enumerate
+@node Configuration Files
+@section Files Created by @code{configure}
+
+Here we spell out what files will be set up by @code{configure}. Normally
+you need not be concerned with these files.
+
+@itemize @bullet
+@item
+@ifset INTERNALS
+A file named @file{config.h} is created that contains a @samp{#include}
+of the top-level config file for the machine you will run the compiler
+on (@pxref{Config}). This file is responsible for defining information
+about the host machine. It includes @file{tm.h}.
+@end ifset
+@ifclear INTERNALS
+A file named @file{config.h} is created that contains a @samp{#include}
+of the top-level config file for the machine you will run the compiler
+on (@pxref{Config,,The Configuration File, gcc.info, Using and Porting
+GCC}). This file is responsible for defining information about the host
+machine. It includes @file{tm.h}.
+@end ifclear
+
+The top-level config file is located in the subdirectory @file{config}.
+Its name is always @file{xm-@var{something}.h}; usually
+@file{xm-@var{machine}.h}, but there are some exceptions.
+
+If your system does not support symbolic links, you might want to
+set up @file{config.h} to contain a @samp{#include} command which
+refers to the appropriate file.
+
+@item
+A file named @file{tconfig.h} is created which includes the top-level config
+file for your target machine. This is used for compiling certain
+programs to run on that machine.
+
+@item
+A file named @file{tm.h} is created which includes the
+machine-description macro file for your target machine. It should be in
+the subdirectory @file{config} and its name is often
+@file{@var{machine}.h}.
+
+@item
+The command file @file{configure} also constructs the file
+@file{Makefile} by adding some text to the template file
+@file{Makefile.in}. The additional text comes from files in the
+@file{config} directory, named @file{t-@var{target}} and
+@file{x-@var{host}}. If these files do not exist, it means nothing
+needs to be added for a given target or host.
+@end itemize
+
@node Configurations
@section Configurations Supported by GNU CC
@cindex configurations supported by GNU CC
diff --git a/gcc/integrate.c b/gcc/integrate.c
index 862a4c3aa60..cde51acf5f7 100644
--- a/gcc/integrate.c
+++ b/gcc/integrate.c
@@ -1,5 +1,5 @@
/* Procedure integration for GNU CC.
- Copyright (C) 1988, 91, 93-97, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1988, 91, 93-98, 1999 Free Software Foundation, Inc.
Contributed by Michael Tiemann (tiemann@cygnus.com)
This file is part of GNU CC.
@@ -37,6 +37,7 @@ Boston, MA 02111-1307, USA. */
#include "except.h"
#include "function.h"
#include "toplev.h"
+#include "intl.h"
#include "obstack.h"
#define obstack_chunk_alloc xmalloc
@@ -93,22 +94,17 @@ get_label_from_map (map, i)
rtx x = map->label_map[i];
if (x == NULL_RTX)
- {
- push_obstacks_nochange ();
- end_temporary_allocation ();
- x = map->label_map[i] = gen_label_rtx();
- pop_obstacks ();
- }
+ x = map->label_map[i] = gen_label_rtx();
return x;
}
/* Zero if the current function (whose FUNCTION_DECL is FNDECL)
is safe and reasonable to integrate into other functions.
- Nonzero means value is a warning message with a single %s
+ Nonzero means value is a warning msgid with a single %s
for the function's name. */
-char *
+const char *
function_cannot_inline_p (fndecl)
register tree fndecl;
{
@@ -122,20 +118,20 @@ function_cannot_inline_p (fndecl)
/* No inlines with varargs. */
if ((last && TREE_VALUE (last) != void_type_node)
|| current_function_varargs)
- return "varargs function cannot be inline";
+ return N_("varargs function cannot be inline");
if (current_function_calls_alloca)
- return "function using alloca cannot be inline";
+ return N_("function using alloca cannot be inline");
if (current_function_contains_functions)
- return "function with nested functions cannot be inline";
+ return N_("function with nested functions cannot be inline");
if (current_function_cannot_inline)
return current_function_cannot_inline;
/* If its not even close, don't even look. */
if (!DECL_INLINE (fndecl) && get_max_uid () > 3 * max_insns)
- return "function too large to be inline";
+ return N_("function too large to be inline");
#if 0
/* Don't inline functions which do not specify a function prototype and
@@ -145,27 +141,27 @@ function_cannot_inline_p (fndecl)
if (TYPE_MODE (TREE_TYPE (parms)) == BLKmode)
TREE_ADDRESSABLE (parms) = 1;
if (last == NULL_TREE && TREE_ADDRESSABLE (parms))
- return "no prototype, and parameter address used; cannot be inline";
+ return N_("no prototype, and parameter address used; cannot be inline");
}
#endif
/* We can't inline functions that return structures
the old-fashioned PCC way, copying into a static block. */
if (current_function_returns_pcc_struct)
- return "inline functions not supported for this return value type";
+ return N_("inline functions not supported for this return value type");
/* We can't inline functions that return structures of varying size. */
if (int_size_in_bytes (TREE_TYPE (TREE_TYPE (fndecl))) < 0)
- return "function with varying-size return value cannot be inline";
+ return N_("function with varying-size return value cannot be inline");
/* Cannot inline a function with a varying size argument or one that
receives a transparent union. */
for (parms = DECL_ARGUMENTS (fndecl); parms; parms = TREE_CHAIN (parms))
{
if (int_size_in_bytes (TREE_TYPE (parms)) < 0)
- return "function with varying-size parameter cannot be inline";
+ return N_("function with varying-size parameter cannot be inline");
else if (TYPE_TRANSPARENT_UNION (TREE_TYPE (parms)))
- return "function with transparent unit parameter cannot be inline";
+ return N_("function with transparent unit parameter cannot be inline");
}
if (!DECL_INLINE (fndecl) && get_max_uid () > max_insns)
@@ -177,22 +173,21 @@ function_cannot_inline_p (fndecl)
ninsns++;
if (ninsns >= max_insns)
- return "function too large to be inline";
+ return N_("function too large to be inline");
}
- /* We cannot inline this function if forced_labels is non-zero. This
- implies that a label in this function was used as an initializer.
- Because labels can not be duplicated, all labels in the function
- will be renamed when it is inlined. However, there is no way to find
- and fix all variables initialized with addresses of labels in this
- function, hence inlining is impossible. */
+ /* We will not inline a function which uses computed goto. The addresses of
+ its local labels, which may be tucked into global storage, are of course
+ not constant across instantiations, which causes unexpected behaviour. */
+ if (current_function_has_computed_jump)
+ return N_("function with computed jump cannot inline");
if (forced_labels)
return "function with label addresses used in initializers cannot inline";
/* We cannot inline a nested function that jumps to a nonlocal label. */
if (current_function_has_nonlocal_goto)
- return "function with nonlocal goto cannot be inline";
+ return N_("function with nonlocal goto cannot be inline");
/* This is a hack, until the inliner is taught about eh regions at
the start of the function. */
@@ -204,13 +199,13 @@ function_cannot_inline_p (fndecl)
{
if (insn && GET_CODE (insn) == NOTE
&& NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_BEG)
- return "function with complex parameters cannot be inline";
+ return N_("function with complex parameters cannot be inline");
}
/* We can't inline functions that return a PARALLEL rtx. */
result = DECL_RTL (DECL_RESULT (fndecl));
if (result && GET_CODE (result) == PARALLEL)
- return "inline functions not supported for this return value type";
+ return N_("inline functions not supported for this return value type");
return 0;
}
@@ -223,6 +218,16 @@ function_cannot_inline_p (fndecl)
static tree *parmdecl_map;
+/* Subroutines passed to duplicate_eh_handlers to map exception labels. */
+
+static rtx
+save_for_inline_eh_labelmap (label)
+ rtx label;
+{
+ int index = CODE_LABEL_NUMBER (label);
+ return label_map[index];
+}
+
/* Subroutine for `save_for_inline_nocopy. Performs initialization
needed to save FNDECL's insns and info for future inline expansion. */
@@ -505,8 +510,7 @@ note_modified_parmregs (reg, x)
with a function called from note_stores. Be *very* careful that this
is used properly in the presence of recursion. */
-rtx *global_const_equiv_map;
-int global_const_equiv_map_size;
+varray_type global_const_equiv_varray;
#define FIXED_BASE_PLUS_P(X) \
(GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 1)) == CONST_INT \
@@ -536,16 +540,24 @@ process_reg_param (map, loc, copy)
{
rtx temp = copy_to_mode_reg (GET_MODE (loc), copy);
REG_USERVAR_P (temp) = REG_USERVAR_P (loc);
- if ((CONSTANT_P (copy) || FIXED_BASE_PLUS_P (copy))
- && REGNO (temp) < map->const_equiv_map_size)
- {
- map->const_equiv_map[REGNO (temp)] = copy;
- map->const_age_map[REGNO (temp)] = CONST_AGE_PARM;
- }
+ if (CONSTANT_P (copy) || FIXED_BASE_PLUS_P (copy))
+ SET_CONST_EQUIV_DATA (map, temp, copy, CONST_AGE_PARM);
copy = temp;
}
map->reg_map[REGNO (loc)] = copy;
}
+
+/* Used by duplicate_eh_handlers to map labels for the exception table */
+static struct inline_remap *eif_eh_map;
+
+static rtx
+expand_inline_function_eh_labelmap (label)
+ rtx label;
+{
+ int index = CODE_LABEL_NUMBER (label);
+ return get_label_from_map (eif_eh_map, index);
+}
+
/* Integrate the procedure defined by FNDECL. Note that this function
may wind up calling itself. Since the static variables are not
reentrant, we do not assign them until after the possibility
@@ -586,7 +598,7 @@ expand_inline_function (fndecl, parms, target, ignore, type,
rtx loc;
rtx stack_save = 0;
rtx temp;
- struct inline_remap *map;
+ struct inline_remap *map = 0;
#ifdef HAVE_cc0
rtx cc0_insn = 0;
#endif
@@ -673,7 +685,8 @@ expand_inline_function (fndecl, parms, target, ignore, type,
rtx stack_slot
= assign_stack_temp (TYPE_MODE (TREE_TYPE (arg)),
int_size_in_bytes (TREE_TYPE (arg)), 1);
- MEM_IN_STRUCT_P (stack_slot) = AGGREGATE_TYPE_P (TREE_TYPE (arg));
+ MEM_SET_IN_STRUCT_P (stack_slot,
+ AGGREGATE_TYPE_P (TREE_TYPE (arg)));
store_expr (arg, stack_slot, 0);
@@ -749,30 +762,25 @@ expand_inline_function (fndecl, parms, target, ignore, type,
map->integrating = 1;
- /* const_equiv_map maps pseudos in our routine to constants, so it needs to
- be large enough for all our pseudos. This is the number we are currently
- using plus the number in the called routine, plus 15 for each arg,
- five to compute the virtual frame pointer, and five for the return value.
- This should be enough for most cases. We do not reference entries
- outside the range of the map.
+ /* const_equiv_varray maps pseudos in our routine to constants, so
+ it needs to be large enough for all our pseudos. This is the
+ number we are currently using plus the number in the called
+ routine, plus 15 for each arg, five to compute the virtual frame
+ pointer, and five for the return value. This should be enough
+ for most cases. We do not reference entries outside the range of
+ the map.
??? These numbers are quite arbitrary and were obtained by
experimentation. At some point, we should try to allocate the
table after all the parameters are set up so we an more accurately
estimate the number of pseudos we will need. */
- map->const_equiv_map_size
- = max_reg_num () + (max_regno - FIRST_PSEUDO_REGISTER) + 15 * nargs + 10;
-
- map->const_equiv_map
- = (rtx *)alloca (map->const_equiv_map_size * sizeof (rtx));
- bzero ((char *) map->const_equiv_map,
- map->const_equiv_map_size * sizeof (rtx));
-
- map->const_age_map
- = (unsigned *)alloca (map->const_equiv_map_size * sizeof (unsigned));
- bzero ((char *) map->const_age_map,
- map->const_equiv_map_size * sizeof (unsigned));
+ VARRAY_CONST_EQUIV_INIT (map->const_equiv_varray,
+ (max_reg_num ()
+ + (max_regno - FIRST_PSEUDO_REGISTER)
+ + 15 * nargs
+ + 10),
+ "expand_inline_function");
map->const_age = 0;
/* Record the current insn in case we have to set up pointers to frame
@@ -841,12 +849,8 @@ expand_inline_function (fndecl, parms, target, ignore, type,
if (GET_CODE (copy) != REG)
{
temp = copy_addr_to_reg (copy);
- if ((CONSTANT_P (copy) || FIXED_BASE_PLUS_P (copy))
- && REGNO (temp) < map->const_equiv_map_size)
- {
- map->const_equiv_map[REGNO (temp)] = copy;
- map->const_age_map[REGNO (temp)] = CONST_AGE_PARM;
- }
+ if (CONSTANT_P (copy) || FIXED_BASE_PLUS_P (copy))
+ SET_CONST_EQUIV_DATA (map, temp, copy, CONST_AGE_PARM);
copy = temp;
}
map->reg_map[REGNO (XEXP (loc, 0))] = copy;
@@ -911,46 +915,60 @@ expand_inline_function (fndecl, parms, target, ignore, type,
map->inline_target = 0;
loc = DECL_RTL (DECL_RESULT (fndecl));
+
if (TYPE_MODE (type) == VOIDmode)
/* There is no return value to worry about. */
;
else if (GET_CODE (loc) == MEM)
{
- if (! structure_value_addr || ! aggregate_value_p (DECL_RESULT (fndecl)))
- abort ();
+ if (GET_CODE (XEXP (loc, 0)) == ADDRESSOF)
+ {
+ temp = copy_rtx_and_substitute (loc, map);
+ subst_constants (&temp, NULL_RTX, map);
+ apply_change_group ();
+ target = temp;
+ }
+ else
+ {
+ if (! structure_value_addr
+ || ! aggregate_value_p (DECL_RESULT (fndecl)))
+ abort ();
- /* Pass the function the address in which to return a structure value.
- Note that a constructor can cause someone to call us with
- STRUCTURE_VALUE_ADDR, but the initialization takes place
- via the first parameter, rather than the struct return address.
+ /* Pass the function the address in which to return a structure
+ value. Note that a constructor can cause someone to call us
+ with STRUCTURE_VALUE_ADDR, but the initialization takes place
+ via the first parameter, rather than the struct return address.
- We have two cases: If the address is a simple register indirect,
- use the mapping mechanism to point that register to our structure
- return address. Otherwise, store the structure return value into
- the place that it will be referenced from. */
+ We have two cases: If the address is a simple register
+ indirect, use the mapping mechanism to point that register to
+ our structure return address. Otherwise, store the structure
+ return value into the place that it will be referenced from. */
- if (GET_CODE (XEXP (loc, 0)) == REG)
- {
- temp = force_reg (Pmode,
- force_operand (structure_value_addr, NULL_RTX));
- map->reg_map[REGNO (XEXP (loc, 0))] = temp;
- if ((CONSTANT_P (structure_value_addr)
- || GET_CODE (structure_value_addr) == ADDRESSOF
- || (GET_CODE (structure_value_addr) == PLUS
- && XEXP (structure_value_addr, 0) == virtual_stack_vars_rtx
- && GET_CODE (XEXP (structure_value_addr, 1)) == CONST_INT))
- && REGNO (temp) < map->const_equiv_map_size)
+ if (GET_CODE (XEXP (loc, 0)) == REG)
{
- map->const_equiv_map[REGNO (temp)] = structure_value_addr;
- map->const_age_map[REGNO (temp)] = CONST_AGE_PARM;
+ temp = force_operand (structure_value_addr, NULL_RTX);
+ temp = force_reg (Pmode, temp);
+ map->reg_map[REGNO (XEXP (loc, 0))] = temp;
+
+ if (CONSTANT_P (structure_value_addr)
+ || GET_CODE (structure_value_addr) == ADDRESSOF
+ || (GET_CODE (structure_value_addr) == PLUS
+ && (XEXP (structure_value_addr, 0)
+ == virtual_stack_vars_rtx)
+ && (GET_CODE (XEXP (structure_value_addr, 1))
+ == CONST_INT)))
+ {
+ SET_CONST_EQUIV_DATA (map, temp, structure_value_addr,
+ CONST_AGE_PARM);
+ }
+ }
+ else
+ {
+ temp = copy_rtx_and_substitute (loc, map);
+ subst_constants (&temp, NULL_RTX, map);
+ apply_change_group ();
+ emit_move_insn (temp, structure_value_addr);
}
- }
- else
- {
- temp = copy_rtx_and_substitute (loc, map);
- subst_constants (&temp, NULL_RTX, map);
- apply_change_group ();
- emit_move_insn (temp, structure_value_addr);
}
}
else if (ignore)
@@ -1044,10 +1062,9 @@ expand_inline_function (fndecl, parms, target, ignore, type,
/* Clean up stack so that variables might have smaller offsets. */
do_pending_stack_adjust ();
- /* Save a copy of the location of const_equiv_map for mark_stores, called
- via note_stores. */
- global_const_equiv_map = map->const_equiv_map;
- global_const_equiv_map_size = map->const_equiv_map_size;
+ /* Save a copy of the location of const_equiv_varray for
+ mark_stores, called via note_stores. */
+ global_const_equiv_varray = map->const_equiv_varray;
/* If the called function does an alloca, save and restore the
stack pointer around the call. This saves stack space, but
@@ -1231,7 +1248,7 @@ expand_inline_function (fndecl, parms, target, ignore, type,
/* Be lazy and assume CALL_INSNs clobber all hard registers. */
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
- map->const_equiv_map[i] = 0;
+ VARRAY_CONST_EQUIV (map->const_equiv_varray, i).rtx = 0;
break;
case CODE_LABEL:
@@ -1267,17 +1284,12 @@ expand_inline_function (fndecl, parms, target, ignore, type,
/* we have to duplicate the handlers for the original */
if (NOTE_LINE_NUMBER (copy) == NOTE_INSN_EH_REGION_BEG)
{
- handler_info *ptr, *temp;
- int nr;
- nr = new_eh_region_entry (CODE_LABEL_NUMBER (label));
- ptr = get_first_handler (NOTE_BLOCK_NUMBER (copy));
- for ( ; ptr; ptr = ptr->next)
- {
- temp = get_new_handler ( get_label_from_map (map,
- CODE_LABEL_NUMBER (ptr->handler_label)),
- ptr->type_info);
- add_new_handler (nr, temp);
- }
+ /* We need to duplicate the handlers for the EH region
+ and we need to indicate where the label map is */
+ eif_eh_map = map;
+ duplicate_eh_handlers (NOTE_BLOCK_NUMBER (copy),
+ CODE_LABEL_NUMBER (label),
+ expand_inline_function_eh_labelmap);
}
/* We have to forward these both to match the new exception
@@ -1365,12 +1377,14 @@ expand_inline_function (fndecl, parms, target, ignore, type,
target = gen_rtx_MEM (TYPE_MODE (type),
memory_address (TYPE_MODE (type),
structure_value_addr));
- MEM_IN_STRUCT_P (target) = 1;
+ MEM_SET_IN_STRUCT_P (target, 1);
}
/* Make sure we free the things we explicitly allocated with xmalloc. */
if (real_label_map)
free (real_label_map);
+ if (map)
+ VARRAY_FREE (map->const_equiv_varray);
return target;
}
@@ -1574,11 +1588,7 @@ copy_rtx_and_substitute (orig, map)
STACK_BOUNDARY / BITS_PER_UNIT);
#endif
- if (REGNO (temp) < map->const_equiv_map_size)
- {
- map->const_equiv_map[REGNO (temp)] = loc;
- map->const_age_map[REGNO (temp)] = CONST_AGE_PARM;
- }
+ SET_CONST_EQUIV_DATA (map, temp, loc, CONST_AGE_PARM);
seq = gen_sequence ();
end_sequence ();
@@ -1609,11 +1619,7 @@ copy_rtx_and_substitute (orig, map)
STACK_BOUNDARY / BITS_PER_UNIT);
#endif
- if (REGNO (temp) < map->const_equiv_map_size)
- {
- map->const_equiv_map[REGNO (temp)] = loc;
- map->const_age_map[REGNO (temp)] = CONST_AGE_PARM;
- }
+ SET_CONST_EQUIV_DATA (map, temp, loc, CONST_AGE_PARM);
seq = gen_sequence ();
end_sequence ();
@@ -1658,7 +1664,17 @@ copy_rtx_and_substitute (orig, map)
return gen_rtx_SUBREG (GET_MODE (orig), SUBREG_REG (copy),
SUBREG_WORD (orig) + SUBREG_WORD (copy));
else if (GET_CODE (copy) == CONCAT)
- return (subreg_realpart_p (orig) ? XEXP (copy, 0) : XEXP (copy, 1));
+ {
+ rtx retval = subreg_realpart_p (orig) ? XEXP (copy, 0) : XEXP (copy, 1);
+
+ if (GET_MODE (retval) == GET_MODE (orig))
+ return retval;
+ else
+ return gen_rtx_SUBREG (GET_MODE (orig), retval,
+ (SUBREG_WORD (orig) %
+ (GET_MODE_UNIT_SIZE (GET_MODE (SUBREG_REG (orig)))
+ / (unsigned) UNITS_PER_WORD)));
+ }
else
return gen_rtx_SUBREG (GET_MODE (orig), copy,
SUBREG_WORD (orig));
@@ -1745,6 +1761,13 @@ copy_rtx_and_substitute (orig, map)
map)),
0);
}
+ else
+ if (SYMBOL_REF_NEED_ADJUST (orig))
+ {
+ eif_eh_map = map;
+ return rethrow_symbol_map (orig,
+ expand_inline_function_eh_labelmap);
+ }
return orig;
@@ -1878,7 +1901,7 @@ copy_rtx_and_substitute (orig, map)
copy_rtx_and_substitute (SET_DEST (orig), map);
equiv_reg = map->reg_map[REGNO (SET_DEST (orig))];
- equiv_loc = map->const_equiv_map[REGNO (equiv_reg)];
+ equiv_loc = VARRAY_CONST_EQUIV (map->const_equiv_varray, REGNO (equiv_reg)).rtx;
loc_offset
= GET_CODE (equiv_loc) == REG ? 0 : INTVAL (XEXP (equiv_loc, 1));
return gen_rtx_SET (VOIDmode, SET_DEST (orig),
@@ -1894,8 +1917,7 @@ copy_rtx_and_substitute (orig, map)
copy = rtx_alloc (MEM);
PUT_MODE (copy, mode);
XEXP (copy, 0) = copy_rtx_and_substitute (XEXP (orig, 0), map);
- MEM_IN_STRUCT_P (copy) = MEM_IN_STRUCT_P (orig);
- MEM_VOLATILE_P (copy) = MEM_VOLATILE_P (orig);
+ MEM_COPY_ATTRIBUTES (copy, orig);
MEM_ALIAS_SET (copy) = MEM_ALIAS_SET (orig);
/* If doing function inlining, this MEM might not be const in the
@@ -2005,16 +2027,15 @@ try_constants (insn, map)
{
int regno = REGNO (map->equiv_sets[i].dest);
- if (regno < map->const_equiv_map_size
- && (map->const_equiv_map[regno] == 0
- /* Following clause is a hack to make case work where GNU C++
- reassigns a variable to make cse work right. */
- || ! rtx_equal_p (map->const_equiv_map[regno],
- map->equiv_sets[i].equiv)))
- {
- map->const_equiv_map[regno] = map->equiv_sets[i].equiv;
- map->const_age_map[regno] = map->const_age;
- }
+ MAYBE_EXTEND_CONST_EQUIV_VARRAY (map, regno);
+ if (VARRAY_CONST_EQUIV (map->const_equiv_varray, regno).rtx == 0
+ /* Following clause is a hack to make case work where GNU C++
+ reassigns a variable to make cse work right. */
+ || ! rtx_equal_p (VARRAY_CONST_EQUIV (map->const_equiv_varray,
+ regno).rtx,
+ map->equiv_sets[i].equiv))
+ SET_CONST_EQUIV_DATA (map, map->equiv_sets[i].dest,
+ map->equiv_sets[i].equiv, map->const_age);
}
else if (map->equiv_sets[i].dest == pc_rtx)
map->last_pc_value = map->equiv_sets[i].equiv;
@@ -2084,12 +2105,14 @@ subst_constants (loc, insn, map)
hard regs used as user variables with constants. */
{
int regno = REGNO (x);
+ struct const_equiv_data *p;
if (! (regno < FIRST_PSEUDO_REGISTER && REG_USERVAR_P (x))
- && regno < map->const_equiv_map_size
- && map->const_equiv_map[regno] != 0
- && map->const_age_map[regno] >= map->const_age)
- validate_change (insn, loc, map->const_equiv_map[regno], 1);
+ && regno < VARRAY_SIZE (map->const_equiv_varray)
+ && (p = &VARRAY_CONST_EQUIV (map->const_equiv_varray, regno),
+ p->rtx != 0)
+ && p->age >= map->const_age)
+ validate_change (insn, loc, p->rtx, 1);
return;
}
@@ -2332,8 +2355,8 @@ mark_stores (dest, x)
if (regno != VIRTUAL_INCOMING_ARGS_REGNUM
&& regno != VIRTUAL_STACK_VARS_REGNUM)
for (i = regno; i <= last_reg; i++)
- if (i < global_const_equiv_map_size)
- global_const_equiv_map[i] = 0;
+ if (i < VARRAY_SIZE (global_const_equiv_varray))
+ VARRAY_CONST_EQUIV (global_const_equiv_varray, i).rtx = 0;
}
}
diff --git a/gcc/integrate.h b/gcc/integrate.h
index ce766e96c77..e486d33df67 100644
--- a/gcc/integrate.h
+++ b/gcc/integrate.h
@@ -18,6 +18,8 @@ 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 "varray.h"
+
/* This structure is used to remap objects in the function being inlined to
those belonging to the calling function. It is passed by
expand_inline_function to its children.
@@ -67,19 +69,15 @@ struct inline_remap
pseudos that contain pointers into the replacement area allocated for
this inline instance. These pseudos are then marked as being equivalent
to the appropriate address and substituted if valid. */
- rtx *const_equiv_map;
- /* Number of entries in const_equiv_map and const_arg_map. */
- int const_equiv_map_size;
+ varray_type const_equiv_varray;
/* This is incremented for each new basic block.
- It is used to store in const_age_map to record the domain of validity
- of each entry in const_equiv_map.
+ It is used to store in the age field to record the domain of validity
+ of each entry in const_equiv_varray.
A value of -1 indicates an entry for a reg which is a parm.
All other values are "positive". */
#define CONST_AGE_PARM (-1)
unsigned int const_age;
- /* In parallel with const_equiv_map, record the valid age for each entry.
- The entry is invalid if its age is less than const_age. */
- unsigned int *const_age_map;
+
/* Target of the inline function being expanded, or NULL if none. */
rtx inline_target;
/* When an insn is being copied by copy_rtx_and_substitute,
@@ -128,9 +126,29 @@ extern rtx get_label_from_map PROTO((struct inline_remap *, int));
/* Set the label indicated. */
#define set_label_in_map(MAP, I, X) ((MAP)->label_map[I] = (X))
-/* Unfortunately, we need a global copy of const_equiv map for communication
- with a function called from note_stores. Be *very* careful that this
- is used properly in the presence of recursion. */
-
-extern rtx *global_const_equiv_map;
-extern int global_const_equiv_map_size;
+/* Unfortunately, we need a global copy of const_equiv varray for
+ communication with a function called from note_stores. Be *very*
+ careful that this is used properly in the presence of recursion. */
+
+extern varray_type global_const_equiv_varray;
+
+#define MAYBE_EXTEND_CONST_EQUIV_VARRAY(MAP,MAX) \
+ { \
+ if ((MAX) >= VARRAY_SIZE ((MAP)->const_equiv_varray)) \
+ { \
+ int is_global = (global_const_equiv_varray \
+ == (MAP)->const_equiv_varray); \
+ VARRAY_GROW ((MAP)->const_equiv_varray, (MAX)+1); \
+ if (is_global) \
+ global_const_equiv_varray = (MAP)->const_equiv_varray; \
+ } \
+ }
+
+#define SET_CONST_EQUIV_DATA(MAP,REG,RTX,AGE) \
+ { \
+ struct const_equiv_data *p; \
+ MAYBE_EXTEND_CONST_EQUIV_VARRAY ((MAP), REGNO (REG)); \
+ p = &VARRAY_CONST_EQUIV ((MAP)->const_equiv_varray, REGNO (REG)); \
+ p->rtx = (RTX); \
+ p->age = (AGE); \
+ }
diff --git a/gcc/invoke.texi b/gcc/invoke.texi
index d0339e47699..ad145dab442 100644
--- a/gcc/invoke.texi
+++ b/gcc/invoke.texi
@@ -1,4 +1,4 @@
-@c Copyright (C) 1988,89,92,93,94,95,96,97,1998 Free Software Foundation, Inc.
+@c Copyright (C) 1988, 89, 92-98, 1999 Free Software Foundation, Inc.
@c This is part of the GCC manual.
@c For copying conditions, see the file gcc.texi.
@@ -87,13 +87,13 @@ in the following sections.
@item Overall Options
@xref{Overall Options,,Options Controlling the Kind of Output}.
@smallexample
--c -S -E -o @var{file} -pipe -v -x @var{language}
+-c -S -E -o @var{file} -pipe -v --help -x @var{language}
@end smallexample
@item C Language Options
@xref{C Dialect Options,,Options Controlling C Dialect}.
@smallexample
--ansi -fallow-single-precision -fcond-mismatch -fno-asm
+-ansi -flang-isoc9x -fallow-single-precision -fcond-mismatch -fno-asm
-fno-builtin -ffreestanding -fhosted -fsigned-bitfields -fsigned-char
-funsigned-bitfields -funsigned-char -fwritable-strings
-traditional -traditional-cpp -trigraphs
@@ -117,13 +117,13 @@ in the following sections.
@smallexample
-fsyntax-only -pedantic -pedantic-errors
-w -W -Wall -Waggregate-return -Wbad-function-cast
--Wcast-align -Wcast-qual -Wchar-subscript -Wcomment
+-Wcast-align -Wcast-qual -Wchar-subscripts -Wcomment
-Wconversion -Werror -Wformat
-Wid-clash-@var{len} -Wimplicit -Wimplicit-int
-Wimplicit-function-declaration -Wimport
-Werror-implicit-function-declaration -Winline
-Wlarger-than-@var{len} -Wlong-long
--Wmain -Wmissing-declarations
+-Wmain -Wmissing-declarations -Wmissing-noreturn
-Wmissing-prototypes -Wmultichar -Wnested-externs -Wno-import
-Wno-non-template-friend -Wold-style-cast -Woverloaded-virtual
-Wparentheses -Wpointer-arith -Wredundant-decls -Wreorder
@@ -170,7 +170,7 @@ in the following sections.
-idirafter @var{dir}
-include @var{file} -imacros @var{file}
-iprefix @var{file} -iwithprefix @var{dir}
--iwithprefixbefore @var{dir} -isystem @var{dir}
+-iwithprefixbefore @var{dir} -isystem @var{dir} -isystem-c++ @var{dir}
-M -MD -MM -MMD -MG -nostdinc -P -trigraphs
-undef -U@var{macro} -Wp,@var{option}
@end smallexample
@@ -259,6 +259,8 @@ in the following sections.
-mcpu= -march= -mfpe=
-mstructure-size-boundary=
-mbsd -mxopen -mno-symrename
+-mabort-on-noreturn
+-mno-sched-prolog
@emph{Thumb Options}
-mtpcs-frame -mno-tpcs-frame
@@ -320,7 +322,7 @@ in the following sections.
-mabicalls -mcpu=@var{cpu type} -membedded-data
-membedded-pic -mfp32 -mfp64 -mgas -mgp32 -mgp64
-mgpopt -mhalf-pic -mhard-float -mint64 -mips1
--mips2 -mips3 -mips4 -mlong64 -mlong-calls -mmemcpy
+-mips2 -mips3 -mips4 -mlong64 -mlong32 -mlong-calls -mmemcpy
-mmips-as -mmips-tfile -mno-abicalls
-mno-embedded-data -mno-embedded-pic
-mno-gpopt -mno-long-calls
@@ -393,6 +395,11 @@ in the following sections.
-mprolog-function -mno-prolog-function -mspace
-mtda=@var{n} -msda=@var{n} -mzda=@var{n}
-mv850 -mbig-switch
+
+@emph{NS32K Options}
+-m32032 -m32332 -m32532 -m32081 -m32381 -mmult-add -mnomult-add
+-msoft-float -mrtd -mnortd -mregparam -mnoregparam -msb -mnosb
+-mbitfield -mnobitfield -mhimem -mnohimem
@end smallexample
@item Code Generation Options
@@ -404,10 +411,11 @@ in the following sections.
-fno-common -fno-ident -fno-gnu-linker
-fpcc-struct-return -fpic -fPIC
-freg-struct-return -fshared-data -fshort-enums
--fshort-double -fvolatile -fvolatile-global
+-fshort-double -fvolatile -fvolatile-global -fvolatile-static
-fverbose-asm -fpack-struct -fstack-check
-fargument-alias -fargument-noalias
-fargument-noalias-global
+-fleading-underscore
@end smallexample
@end table
@@ -558,6 +566,15 @@ Use pipes rather than temporary files for communication between the
various stages of compilation. This fails to work on some systems where
the assembler is unable to read from a pipe; but the GNU assembler has
no trouble.
+
+@item --help
+Print (on the standard output) a description of the command line options
+understood by @code{gcc}. If the @code{-v} option is also specified
+then @code{--help} will also be passed on to the various processes
+invoked by @code{gcc}, so that they can display the command line options
+they accept. If the @code{-W} option is also specified then command
+line options which have no documentation associated with them will also
+be displayed.
@end table
@node Invoking G++
@@ -644,6 +661,15 @@ programs that might use these names for other things.
The functions @code{alloca}, @code{abort}, @code{exit}, and
@code{_exit} are not builtin functions when @samp{-ansi} is used.
+@item -flang-isoc9x
+Enable support for features found in the C9X standard. In particular,
+enable support for the C9X @code{restrict} keyword.
+
+Even when this option is not specified, you can still use some C9X
+features in so far as they do not conflict with previous C standards.
+For example, you may use @code{__restrict__} even when -flang-isoc9x
+is not specified.
+
@item -fno-asm
Do not recognize @code{asm}, @code{inline} or @code{typeof} as a
keyword, so that code can use these words as identifiers. You can use
@@ -672,7 +698,7 @@ other, C++-specific, extension keywords such as @code{headof}.
@findex strcmp
@findex strcpy
@findex strlen
-Don't recognize builtin functions that do not begin with `__builtin_'
+Don't recognize builtin functions that do not begin with @samp{__builtin_}
as prefix. Currently, the functions affected include @code{abort},
@code{abs}, @code{alloca}, @code{cos}, @code{exit}, @code{fabs},
@code{ffs}, @code{labs}, @code{memcmp}, @code{memcpy}, @code{sin},
@@ -1065,11 +1091,24 @@ Disable diagnostics that the standard says a compiler does not need to
issue. Currently, this means the diagnostic for a name having multiple
meanings within a class.
+@item -fpermissive
+Downgrade messages about nonconformant code from errors to warnings. By
+default, g++ effectively sets @samp{-pedantic-errors} without
+@samp{-pedantic}; this option reverses that. This behavior and this
+option are superceded by @samp{-pedantic}, which works as it does for GNU C.
+
@item -frepo
Enable automatic template instantiation. This option also implies
@samp{-fno-implicit-templates}. @xref{Template Instantiation}, for more
information.
+@item -fno-rtti
+Disable generation of the information used by C++ runtime type
+identification features (@samp{dynamic_cast} and @samp{typeid}). If you
+don't use those parts of the language (or exception handling, which uses
+@samp{dynamic_cast} internally), you can save some space by using this
+flag.
+
@item -fstrict-prototype
Within an @samp{extern "C"} linkage specification, treat a function
declaration with no arguments, such as @samp{int foo ();}, as declaring
@@ -1118,6 +1157,11 @@ offsets for adjusting the @samp{this} pointer at the call site. Newer
implementations store a single pointer to a @samp{thunk} function which
does any necessary adjustment and then calls the target function.
+This option also enables a heuristic for controlling emission of
+vtables; if a class has any non-inline virtual functions, the vtable
+will be emitted in the translation unit containing the first one of
+those.
+
Like all options that change the ABI, all C++ code, @emph{including
libgcc.a} must be built with the same setting of this option.
@@ -1201,11 +1245,8 @@ ANSI C @emph{requires} a diagnostic.
A feature to report any failure to conform to ANSI C might be useful in
some instances, but would require considerable additional work and would
-be quite different from @samp{-pedantic}. We recommend, rather, that
-users take advantage of the extensions of GNU C and disregard the
-limitations of other compilers. Aside from certain supercomputers and
-obsolete small machines, there is less and less reason ever to use any
-other C compiler other than for bootstrapping GNU CC.
+be quite different from @samp{-pedantic}. We don't have plans to
+support such a feature in the near future.
@item -pedantic-errors
Like @samp{-pedantic}, except that errors are produced rather than
@@ -1319,7 +1360,7 @@ In order to get a warning about an unused function parameter, you must
specify both @samp{-W} and @samp{-Wunused}.
To suppress this warning for an expression, simply cast it to void. For
-unused variables and parameters, use the @samp{unused} attribute
+unused variables, parameters and labels, use the @samp{unused} attribute
(@pxref{Variable Attributes}).
@item -Wuninitialized
@@ -1527,6 +1568,10 @@ the block.
@item
A @code{switch} statement has an operand of type @code{long}.
+
+@item
+A non-@code{static} function declaration follows a @code{static} one.
+This construct is not accepted by some traditional C compilers.
@end itemize
@item -Wundef
@@ -1617,6 +1662,13 @@ Do so even if the definition itself provides a prototype.
Use this option to detect global functions that are not declared in
header files.
+@item -Wmissing-noreturn
+Warn about functions which might be candidates for attribute @code{noreturn}.
+Note these are only possible candidates, not absolute ones. Care should
+be taken to manually verify functions actually do not ever return before
+adding the @code{noreturn} attribute, otherwise subtle code generation
+bugs could be introduced.
+
@item -Wredundant-decls
Warn if anything is declared more than once in the same scope, even in
cases where multiple declaration is valid and changes nothing.
@@ -2317,7 +2369,7 @@ This pass also performs global constant and copy propagation.
Perform a number of minor optimizations that are relatively expensive.
@item -foptimize-register-moves
-@item -fregmove
+@itemx -fregmove
Attempt to reassign register numbers in move instructions and as
operands of other simple instructions in order to maximize the amount of
register tying. This is especially helpful on machines with two-operand
@@ -2346,7 +2398,7 @@ especially useful on machines with a relatively small number of
registers and where memory load instructions take more than one cycle.
@item -ffunction-sections
-@item -fdata-sections
+@itemx -fdata-sections
Place each function or data item into its own section in the output
file if the target supports arbitrary sections. The name of the
function or the name of the data item determines the section's name
@@ -2407,7 +2459,7 @@ These two options are intended to be removed someday, once
they have helped determine the efficacy of various
approaches to improving loop optimizations.
-Please let us (@code{egcs@@cygnus.com} and @code{fortran@@gnu.org})
+Please let us (@code{egcs@@egcs.cygnus.com} and @code{fortran@@gnu.org})
know how use of these options affects
the performance of your production code.
We're very interested in code that runs @emph{slower}
@@ -3029,6 +3081,7 @@ that macro, which enables you to change the defaults.
* System V Options::
* V850 Options::
* ARC Options::
+* NS32K Options::
@end menu
@node M680x0 Options
@@ -3312,8 +3365,8 @@ They have been replaced with @samp{-mcpu=xxx}.
Set the instruction set, register set, and instruction scheduling parameters
for machine type @var{cpu_type}. Supported values for @var{cpu_type} are
@samp{v7}, @samp{cypress}, @samp{v8}, @samp{supersparc}, @samp{sparclite},
-@samp{f930}, @samp{f934}, @samp{sparclet}, @samp{tsc701}, @samp{v9}, and
-@samp{ultrasparc}.
+@samp{hypersparc}, @samp{sparclite86x}, @samp{f930}, @samp{f934},
+@samp{sparclet}, @samp{tsc701}, @samp{v9}, and @samp{ultrasparc}.
Default instruction scheduling parameters are used for values that select
an architecture and not an implementation. These are @samp{v7}, @samp{v8},
@@ -3324,8 +3377,8 @@ implementations.
@smallexample
v7: cypress
- v8: supersparc
- sparclite: f930, f934
+ v8: supersparc, hypersparc
+ sparclite: f930, f934, sparclite86x
sparclet: tsc701
v9: ultrasparc
@end smallexample
@@ -3338,7 +3391,8 @@ option @samp{-mcpu=}@var{cpu_type} would.
The same values for @samp{-mcpu=}@var{cpu_type} are used for
@samp{-mtune=}@*@var{cpu_type}, though the only useful values are those that
select a particular cpu implementation: @samp{cypress}, @samp{supersparc},
-@samp{f930}, @samp{f934}, @samp{tsc701}, @samp{ultrasparc}.
+@samp{hypersparc}, @samp{f930}, @samp{f934}, @samp{sparclite86x},
+@samp{tsc701}, @samp{ultrasparc}.
@item -malign-loops=@var{num}
Align loops to a 2 raised to a @var{num} byte boundary. If
@@ -3590,6 +3644,11 @@ Normally the facilities of the machine's usual C compiler are used, but
this can't be done directly in cross-compilation. You must make your
own arrangements to provide suitable library functions for
cross-compilation.
+
+@item -mno-multm
+@kindex -mno-multm
+Do not generate multm or multmu instructions. This is useful for some embedded
+systems which do not have trap handlers for these instructions.
@end table
@node ARM Options
@@ -3749,13 +3808,17 @@ suppresses this pass. The post-processor is never run when the
compiler is built for cross-compilation.
@item -mcpu=<name>
+@itemx -mtune=<name>
@kindex -mcpu=
+@kindex -mtune=
This specifies the name of the target ARM processor. GCC uses this name
to determine what kind of instructions it can use when generating
assembly code. Permissable names are: arm2, arm250, arm3, arm6, arm60,
arm600, arm610, arm620, arm7, arm7m, arm7d, arm7dm, arm7di, arm7dmi,
arm70, arm700, arm700i, arm710, arm710c, arm7100, arm7500, arm7500fe,
-arm7tdmi, arm8, strongarm, strongarm110
+arm7tdmi, arm8, strongarm, strongarm110, strongarm1100, arm8, arm810,
+arm9, arm9tdmi. @samp{-mtune=} is a synonym for @samp{-mcpue=} to
+support older versions of GCC.
@item -march=<name>
@kindex -march=
@@ -3766,9 +3829,12 @@ of the @samp{-mcpu=} option. Permissable names are: armv2, armv2a,
armv3, armv3m, armv4, armv4t
@item -mfpe=<number>
+@itemx -mfp=<number>
@kindex -mfpe=
+@kindex -mfp=
This specifes the version of the floating point emulation available on
-the target. Permissable values are 2 and 3.
+the target. Permissable values are 2 and 3. @samp{-mfp=} is a synonym
+for @samp{-mfpe=} to support older versions of GCC.
@item -mstructure-size-boundary=<n>
@kindex -mstructure-size-boundary
@@ -3783,6 +3849,12 @@ libraries compiled with the other value, if they exchange information
using structures or unions. Programmers are encouraged to use the 32
value as future versions of the toolchain may default to this value.
+@item -mabort-on-noreturn
+@kindex -mabort-on-noreturn
+@kindex -mnoabort-on-noreturn
+Generate a call to the function abort at the end of a noreturn function.
+It will be executed if the function tries to return.
+
@end table
@node Thumb Options
@@ -4256,13 +4328,13 @@ Set architecture type, register usage, choice of mnemonics, and
instruction scheduling parameters for machine type @var{cpu_type}.
Supported values for @var{cpu_type} are @samp{rs6000}, @samp{rios1},
@samp{rios2}, @samp{rsc}, @samp{601}, @samp{602}, @samp{603},
-@samp{603e}, @samp{604}, @samp{604e}, @samp{620}, @samp{power},
-@samp{power2}, @samp{powerpc}, @samp{403}, @samp{505}, @samp{801},
-@samp{821}, @samp{823}, and @samp{860} and @samp{common}.
-@samp{-mcpu=power}, @samp{-mcpu=power2}, and @samp{-mcpu=powerpc}
-specify generic POWER, POWER2 and pure PowerPC (i.e., not MPC601)
-architecture machine types, with an appropriate, generic processor model
-assumed for scheduling purposes.@refill
+@samp{603e}, @samp{604}, @samp{604e}, @samp{620}, @samp{740},
+@samp{750}, @samp{power}, @samp{power2}, @samp{powerpc}, @samp{403},
+@samp{505}, @samp{801}, @samp{821}, @samp{823}, and @samp{860} and
+@samp{common}. @samp{-mcpu=power}, @samp{-mcpu=power2}, and
+@samp{-mcpu=powerpc} specify generic POWER, POWER2 and pure PowerPC
+(i.e., not MPC601) architecture machine types, with an appropriate,
+generic processor model assumed for scheduling purposes.@refill
@c overfull hbox here --bob 22 jul96
@c original text between ignore ... end ignore
@@ -4406,17 +4478,20 @@ instructions and the store multiple word instructions. These
instructions are generated by default on POWER systems, and not
generated on PowerPC systems. Do not use @samp{-mmultiple} on little
endian PowerPC systems, since those instructions do not work when the
-processor is in little endian mode.
+processor is in little endian mode. The exceptions are PPC740 and
+PPC750 which permit the instructions usage in little endian mode.
@item -mstring
@itemx -mno-string
@kindex -mstring
-Generate code that uses (does not use) the load string instructions and the
-store string word instructions to save multiple registers and do small block
-moves. These instructions are generated by default on POWER systems, and not
-generated on PowerPC systems. Do not use @samp{-mstring} on little endian
-PowerPC systems, since those instructions do not work when the processor is in
-little endian mode.
+Generate code that uses (does not use) the load string instructions
+and the store string word instructions to save multiple registers and
+do small block moves. These instructions are generated by default on
+POWER systems, and not generated on PowerPC systems. Do not use
+@samp{-mstring} on little endian PowerPC systems, since those
+instructions do not work when the processor is in little endian mode.
+The exceptions are PPC740 and PPC750 which permit the instructions
+usage in little endian mode.
@item -mupdate
@itemx -mno-update
@@ -4616,7 +4691,9 @@ All modules should be compiled with the same @samp{-G @var{num}} value.
@itemx -mno-regnames
On System V.4 and embedded PowerPC systems do (do not) emit register
names in the assembly language output using symbolic forms.
+
@end table
+
@node RT Options
@subsection IBM RT Options
@cindex RT options
@@ -4694,7 +4771,6 @@ ISA level.
@item -mips3
Issue instructions from level 3 of the MIPS ISA (64 bit instructions).
@samp{r4000} is the default @var{cpu type} at this ISA level.
-This option does not change the sizes of any of the C data types.
@item -mips4
Issue instructions from level 4 of the MIPS ISA. @samp{r8000} is the
@@ -4717,12 +4793,25 @@ Assume that 32 64-bit general purpose registers are available. This is
the default when the @samp{-mips3} option is used.
@item -mint64
-Types long, int, and pointer are 64 bits. This works only if @samp{-mips3}
-is also specified.
+Force int and long types to be 64 bits wide. See @samp{-mlong32} for an
+explanation of the default, and the width of pointers.
@item -mlong64
-Types long and pointer are 64 bits, and type int is 32 bits.
-This works only if @samp{-mips3} is also specified.
+Force long types to be 64 bits wide. See @samp{-mlong32} for an
+explanation of the default, and the width of pointers.
+
+@item -mlong32
+Force long, int, and pointer types to be 32 bits wide.
+
+If none of @samp{-mlong32}, @samp{-mlong64}, or @samp{-mint64} are set,
+the size of ints, longs, and pointers depends on the ABI and ISA choosen.
+For @samp{-mabi=32}, and @samp{-mabi=n32}, ints and longs are 32 bits
+wide. For @samp{-mabi=64}, ints are 32 bits, and longs are 64 bits wide.
+For @samp{-mabi=eabi} and either @samp{-mips1} or @samp{-mips2}, ints
+and longs are 32 bits wide. For @samp{-mabi=eabi} and higher ISAs, ints
+are 32 bits, and longs are 64 bits wide. The width of pointer types is
+the smaller of the width of longs or the width of general purpose
+registers (which in turn depends on the ISA).
@itemx -mabi=32
@itemx -mabi=n32
@@ -4986,7 +5075,7 @@ there.
You can specify that an individual function is called with this calling
sequence with the function attribute @samp{stdcall}. You can also
override the @samp{-mrtd} option by using the function attribute
-@samp{cdecl}. @xref{Function Attributes}
+@samp{cdecl}. @xref{Function Attributes}.
@strong{Warning:} this calling convention is incompatible with the one
normally used on Unix, so you cannot use it if you need to call
@@ -5012,7 +5101,8 @@ supported letters are: @code{a} allocate EAX; @code{b} allocate EBX;
Control how many registers are used to pass integer arguments. By
default, no registers are used to pass arguments, and at most 3
registers can be used. You can control this behavior for a specific
-function by using the function attribute @samp{regparm}. @xref{Function Attributes}
+function by using the function attribute @samp{regparm}.
+@xref{Function Attributes}.
@strong{Warning:} if you use this switch, and
@var{num} is nonzero, then you must build all modules with the same
@@ -5104,13 +5194,10 @@ Enable the use of assembler directives only GAS understands.
@item -mschedule=@var{cpu type}
Schedule code according to the constraints for the machine type
-@var{cpu type}. The choices for @var{cpu type} are @samp{700} for
-7@var{n}0 machines, @samp{7100} for 7@var{n}5 machines, and @samp{7100LC}
-for 7@var{n}2 machines. @samp{7100} is the default for @var{cpu type}.
-
-Note the @samp{7100LC} scheduling information is incomplete and using
-@samp{7100LC} often leads to bad schedules. For now it's probably best
-to use @samp{7100} instead of @samp{7100LC} for the 7@var{n}2 machines.
+@var{cpu type}. The choices for @var{cpu type} are @samp{700}
+@samp{7100}, @samp{7100LC}, @samp{7200}, and @samp{8000}. Refer to
+@file{/usr/lib/sched.models} on an HP-UX system to determine the
+proper scheduling option for your machine.
@item -mlinker-opt
Enable the optimization pass in the HPUX linker. Note this makes symbolic
@@ -5206,6 +5293,15 @@ Do not permit (do permit) unaligned accesses.
@item -mold-align
Enable structure-alignment compatibility with Intel's gcc release version
1.3 (based on gcc 1.37). This option implies @samp{-mstrict-align}.
+
+@item -mlong-double-64
+Implement type @samp{long double} as 64-bit floating point numbers.
+Without the option @samp{long double} is implemented by 80-bit
+floating point numbers. The only reason we have it because there is
+no 128-bit @samp{long double} support in @samp{fp-bit.c} yet. So it
+is only useful for people using soft-float targets. Otherwise, we
+should recommend against use of it.
+
@end table
@node DEC Alpha Options
@@ -5643,15 +5739,130 @@ Which variants are supported depend on the configuration.
All variants support @samp{-mcpu=base}, this is the default.
@item -mtext=@var{text section}
-@item -mdata=@var{data section}
-@item -mrodata=@var{readonly data section}
+@itemx -mdata=@var{data section}
+@itemx -mrodata=@var{readonly data section}
Put functions, data, and readonly data in @var{text section},
@var{data section}, and @var{readonly data section} respectively
by default. This can be overridden with the @code{section} attribute.
-@xref{Variable Attributes}
+@xref{Variable Attributes}.
@end table
+@node NS32K Options
+@subsection NS32K Options
+@cindex NS32K options
+
+These are the @samp{-m} options defined for the 32000 series. The default
+values for these options depends on which style of 32000 was selected when
+the compiler was configured; the defaults for the most common choices are
+given below.
+
+@table @code
+@item -m32032
+@itemx -m32032
+Generate output for a 32032. This is the default
+when the compiler is configured for 32032 and 32016 based systems.
+
+@item -m32332
+@itemx -m32332
+Generate output for a 32332. This is the default
+when the compiler is configured for 32332-based systems.
+
+@item -m32532
+@itemx -m32532
+Generate output for a 32532. This is the default
+when the compiler is configured for 32532-based systems.
+
+@item -m32081
+Generate output containing 32081 instructions for floating point.
+This is the default for all systems.
+
+@item -m32381
+Generate output containing 32381 instructions for floating point. This
+also implies @samp{-m32081}. The 32381 is only compatible with the 32332
+and 32532 cpus. This is the default for the pc532-netbsd configuration.
+
+@item -mmulti-add
+Try and generate multiply-add floating point instructions @code{polyF}
+and @code{dotF}. This option is only available if the @samp{-m32381}
+option is in effect. Using these instructions requires changes to to
+register allocation which generally has a negative impact on
+performance. This option should only be enabled when compiling code
+particularly likely to make heavy use of multiply-add instructions.
+
+@item -mnomulti-add
+Do not try and generate multiply-add floating point instructions
+@code{polyF} and @code{dotF}. This is the default on all platforms.
+
+@item -msoft-float
+Generate output containing library calls for floating point.
+@strong{Warning:} the requisite libraries may not be available.
+
+@item -mnobitfield
+Do not use the bit-field instructions. On some machines it is faster to
+use shifting and masking operations. This is the default for the pc532.
+
+@item -mbitfield
+Do use the bit-field instructions. This is the default for all platforms
+except the pc532.
+
+@item -mrtd
+Use a different function-calling convention, in which functions
+that take a fixed number of arguments return pop their
+arguments on return with the @code{ret} instruction.
+
+This calling convention is incompatible with the one normally
+used on Unix, so you cannot use it if you need to call libraries
+compiled with the Unix compiler.
+
+Also, you must provide function prototypes for all functions that
+take variable numbers of arguments (including @code{printf});
+otherwise incorrect code will be generated for calls to those
+functions.
+
+In addition, seriously incorrect code will result if you call a
+function with too many arguments. (Normally, extra arguments are
+harmlessly ignored.)
+
+This option takes its name from the 680x0 @code{rtd} instruction.
+
+
+@item -mregparam
+Use a different function-calling convention where the first two arguments
+are passed in registers.
+
+This calling convention is incompatible with the one normally
+used on Unix, so you cannot use it if you need to call libraries
+compiled with the Unix compiler.
+
+@item -mnoregparam
+Do not pass any arguments in registers. This is the default for all
+targets.
+
+@item -msb
+It is OK to use the sb as an index register which is always loaded with
+zero. This is the default for the pc532-netbsd target.
+
+@item -mnosb
+The sb register is not available for use or has not been initialized to
+zero by the run time system. This is the default for all targets except
+the pc532-netbsd. It is also implied whenever @samp{-mhimem} or
+@samp{-fpic} is set.
+
+@item -mhimem
+Many ns32000 series addressing modes use displacements of up to 512MB.
+If an address is above 512MB then displacements from zero can not be used.
+This option causes code to be generated which can be loaded above 512MB.
+This may be useful for operating systems or ROM code.
+
+@item -mnohimem
+Assume code will be loaded in the first 512MB of virtual address space.
+This is the default for all platforms.
+
+
+@end table
+
+
@node Code Gen Options
@section Options for Code Generation Conventions
@@ -5764,7 +5975,11 @@ Consider all memory references through pointers to be volatile.
@item -fvolatile-global
Consider all memory references to extern and global data items to
-be volatile.
+be volatile. GNU CC does not consider static data items to be volatile
+because of this switch.
+
+@item -fvolatile-static
+Consider all memory references to static data to be volatile.
@item -fpic
@cindex global offset table
@@ -5812,9 +6027,9 @@ clobbered by function calls. It may be allocated for temporaries or
variables that do not live across a call. Functions compiled this way
will not save and restore the register @var{reg}.
-Use of this flag for a register that has a fixed pervasive role in the
-machine's execution model, such as the stack pointer or frame pointer,
-will produce disastrous results.
+It is an error to used this flag with the frame pointer or stack pointer.
+Use of this flag for other registers that have fixed pervasive roles in
+the machine's execution model will produce disastrous results.
This flag does not have a negative form, because it specifies a
three-way choice.
@@ -5825,9 +6040,9 @@ functions. It may be allocated even for temporaries or variables that
live across a call. Functions compiled this way will save and restore
the register @var{reg} if they use it.
-Use of this flag for a register that has a fixed pervasive role in the
-machine's execution model, such as the stack pointer or frame pointer,
-will produce disastrous results.
+It is an error to used this flag with the frame pointer or stack pointer.
+Use of this flag for other registers that have fixed pervasive roles in
+the machine's execution model will produce disastrous results.
A different sort of disaster will result from the use of this flag for
a register in which function values may be returned.
@@ -5843,8 +6058,7 @@ the offsets of structure members won't agree with system libraries.
@item -fcheck-memory-usage
Generate extra code to check each memory access. GNU CC will generate
code that is suitable for a detector of bad memory accesses such as
-@file{Checker}. If you specify this option, you can not use the
-@code{asm} or @code{__asm__} keywords.
+@file{Checker}.
You must also specify this option when you compile functions you call that
have side effects. If you do not, you may get erroneous messages from
@@ -5859,6 +6073,24 @@ which are provided by the detector. If you cannot find or build
stubs for every function you call, you may have to specify
@samp{-fcheck-memory-usage} without @samp{-fprefix-function-name}.
+If you specify this option, you can not use the @code{asm} or
+@code{__asm__} keywords in functions with memory checking enabled. The
+compiler cannot understand what the @code{asm} statement will do, and
+therefore cannot generate the appropriate code, so it is rejected.
+However, the function attribute @code{no_check_memory_usage} will
+disable memory checking within a function, and @code{asm} statements can
+be put inside such functions. Inline expansion of a non-checked
+function within a checked function is permitted; the inline function's
+memory accesses won't be checked, but the rest will.
+
+If you move your @code{asm} statements to non-checked inline functions,
+but they do access memory, you can add calls to the support code in your
+inline function, to indicate any reads, writes, or copies being done.
+These calls would be similar to those done in the stubs described above.
+
+@c FIXME: The support-routine interface is defined by the compiler and
+@c should be documented!
+
@item -fprefix-function-name
Request GNU CC to add a prefix to the symbols generated for function names.
GNU CC adds a prefix to the names of functions defined as well as
@@ -5947,6 +6179,14 @@ alias each other and do not alias global storage.
Each language will automatically use whatever option is required by
the language standard. You should not need to use these options yourself.
+
+@item -fleading-underscore
+This option and its counterpart, -fno-leading-underscore, forcibly
+change the way C symbols are represented in the object file. One use
+is to help link with legacy assembly code.
+
+Be warned that you should know what you are doing when invoking this
+option, and that not all targets provide complete support for it.
@end table
@node Environment Variables
@@ -5974,6 +6214,46 @@ CC. @xref{Driver}.
@end ifset
@table @code
+@item LANG
+@itemx LC_CTYPE
+@c @itemx LC_COLLATE
+@itemx LC_MESSAGES
+@c @itemx LC_MONETARY
+@c @itemx LC_NUMERIC
+@c @itemx LC_TIME
+@itemx LC_ALL
+@findex LANG
+@findex LC_CTYPE
+@c @findex LC_COLLATE
+@findex LC_MESSAGES
+@c @findex LC_MONETARY
+@c @findex LC_NUMERIC
+@c @findex LC_TIME
+@findex LC_ALL
+@cindex locale
+These environment variables control the way that GNU CC uses
+localization information that allow GNU CC to work with different
+national conventions. GNU CC inspects the locale categories
+@code{LC_CTYPE} and @code{LC_MESSAGES} if it has been configured to do
+so. These locale categories can be set to any value supported by your
+installation. A typical value is @samp{en_UK} for English in the United
+Kingdom.
+
+The @code{LC_CTYPE} environment variable specifies character
+classification. GNU CC uses it to determine the character boundaries in
+a string; this is needed for some multibyte encodings that contain quote
+and escape characters that would otherwise be interpreted as a string
+end or escape.
+
+The @code{LC_MESSAGES} environment variable specifies the language to
+use in diagnostic messages.
+
+If the @code{LC_ALL} environment variable is set, it overrides the value
+of @code{LC_CTYPE} and @code{LC_MESSAGES}; otherwise, @code{LC_CTYPE}
+and @code{LC_MESSAGES} default to the value of the @code{LANG}
+environment variable. If none of these variables are set, GNU CC
+defaults to traditional C English behavior.
+
@item TMPDIR
@findex TMPDIR
If @code{TMPDIR} is set, it specifies the directory to use for temporary
diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog
index c38e0adbd3e..487d0bfaa59 100644
--- a/gcc/java/ChangeLog
+++ b/gcc/java/ChangeLog
@@ -1,8 +1,2866 @@
+Sat Mar 27 15:49:18 1999 Per Bothner <bothner@cygnus.com>
+
+ * parse.y (complete_loop_body): Rename to finish_loop_body.
+ (complete_labeled_statement): Rename to finish_labeled_statement.
+ (complete_for_loop): Rename to finish_for_loop.
+ (complete_method_declaration): Rename to finish_method_declaration.
+
+ * java-tree.h (continue_identifier_node): New global node.
+ * decl.c: Define and initialize continue_identifier_node.
+ * parse.y (generate_labeled_block): Remove - no longer needed.
+ (build_loop_body): Use continue_identifier_node for continue block.
+ (finish_labeled_statement): Also do pop_labeled_block actions.
+ (java_complete_lhs): POP_LOOP even if error.
+ (build_labeled_block): Special handling for continue_identifier_node.
+ (patch_loop_statement): Re-organize.
+ (patch_bc_statement): Re-write.
+
+Sat Mar 27 15:13:21 1999 Alexandre Petit-Bianco <apbianco@cygnus.com>
+
+ * parse.h (EXPR_WFL_GET_LINECOL): Set a line and column count
+ using a WFL compound value.
+ * parse.y (xref.h): Include.
+ (maybe_create_class_interface_decl): Set DECL_SOURCE_LINE to the
+ WFL compound value.
+ (register_fields): Set WFL compound value to lineno if doing
+ xrefs.
+ (java_complete_expand_method): Call expand_xref if flag_emit_xref
+ is set.
+ * xref.c (system.h, jcf.h, parse.h, obstack.h): Include.
+ * xref.h (expand_xref): Prototype renamed from xref_generate.
+
+Sat Mar 27 14:16:32 1999 Alexandre Petit-Bianco <apbianco@cygnus.com>
+
+ * parse.h (BLOCK_CHAIN_DECL): New use GET_CURRENT_BLOCK.
+ (GET_CURRENT_BLOCK): New macro.
+ * parse.y (current_static_block): New global variable.
+ (method_body:): Define action.
+ (complete_method_declaration): Set current_function_decl to NULL
+ when work on the current method is done.
+ (declare_local_variables): Use GET_CURRENT_BLOCK.
+ (java_method_add_stmt): Likewise.
+ (java_complete_expand_method): Disable the use of `this' when
+ expanding <clinit>.
+ (enter_a_block): If no current method exist, use
+ current_static_block to link static initializer blocks.
+ (exit_block): Rewritten to use current_static_block when no current
+ method decl exists.
+ (lookup_name_in_blocks): Use GET_CURRENT_BLOCK.
+ (patch_return): Forbid the use of `return' in static initializers.
+ (patch_throw_statement): Fixed indentation. Issue specific error
+ for uncaught thrown checked exception in static initializer
+ blocks. Removed FIXME.
+
+1999-03-25 Zack Weinberg <zack@rabi.columbia.edu>
+
+ * java/Make-lang.in: Remove all references to gcj.o/gcj.c.
+ Link gcj from gcc.o.
+
+Tue Mar 23 10:48:24 1999 Alexandre Petit-Bianco <apbianco@cygnus.com>
+
+ * parse.y (find_applicable_accessible_methods_list): When dealing
+ with interface: ensure that a given interface or java.lang.Object
+ are searched only once.
+
+Tue Mar 23 10:05:27 1999 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * gjavah.c (print_c_decl): Remove unused argument `flags'.
+
+ * jcf-dump.c (print_access_flags): Add braces around if-else.
+
+ * jvspec.c (lang_specific_driver): Wrap variable `len' in macro
+ COMBINE_INPUTS.
+
+ * lex.c (build_wfl_node): Add static prototype.
+
+ * lex.h (build_wfl_node): Remove static prototype.
+
+ * parse.y: Include lex.c early enough to declare everything needed.
+ Ensure calls to `build_wfl_node' pass the proper arguments.
+ (create_class): Remove unused variable `super_decl'.
+ (get_printable_method_name): Initialize variable `name'.
+
+Mon Mar 22 20:14:26 1999 Alexandre Petit-Bianco <apbianco@cygnus.com>
+
+ * Changelog: Fixed 1999-03-22 typos.
+ * lang.c (lang_decode_option): Fixed typo in error string in the
+ XARG section.
+
+1999-03-22 Alexandre Petit-Bianco <apbianco@cygnus.com>
+
+ * Makefile.in (JAVA_OBJS): Added entry xref.o.
+ (xref.o): New rule.
+ * java-tree.h (flag_emit_xref): Declared extern.
+ * lang.c (xref.h): Included.
+ (flag_emit_xref): New global variable.
+ (lang_decode_option): Added support for -fxref.
+ * xref.c: Created.
+ * xref.h: Likewise.
+
+1999-03-21 Manfred Hollstein <manfred@s-direktnet.de>
+
+ * Make-lang.in ($(GCJ)$(exeext)): Add intl.o to list of files to be
+ linked with.
+
+Sun Mar 21 08:30:30 1999 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * Makefile.in (jcf-dump.o): Depend on $(CONFIG_H)
+ $(srcdir)/../system.h and $(JAVA_TREE_H).
+ (jcf-io.o): Depend on $(JAVA_TREE_H).
+ (mangle.o): Likewise.
+
+ * check-init.c (check_cond_init): Add static prototype.
+
+ * class.c (build_java_method_type, hashUtf8String,
+ make_field_value, get_dispatch_vector, get_dispatch_table,
+ append_gpp_mangled_type, mangle_static_field): Likewise.
+ (strLengthUtf8): Hide unused definition.
+ (hashUtf8String): Const-ify.
+ (make_field_value): Un-ANSI-fy.
+
+ * constants.c: Move inclusion of jcf.h above java-tree.h.
+ (set_constant_entry, find_class_or_string_constant,
+ find_name_and_type_constant, get_tag_node,
+ build_constant_data_ref): Add static prototype.
+
+ * decl.c (push_jvm_slot, builtin_function,
+ lookup_name_current_level): Likewise.
+ (builtin_function): Const-ify.
+
+ * except.c (expand_start_java_handler, expand_end_java_handler):
+ Add static prototype.
+
+ * expr.c (flush_quick_stack, push_value, pop_value,
+ java_stack_swap, java_stack_dup, build_java_athrow,
+ build_java_jsr, build_java_ret, expand_java_multianewarray,
+ expand_java_arraystore, expand_java_arrayload,
+ expand_java_array_length, build_java_monitor, expand_java_pushc,
+ expand_java_return, expand_java_NEW, expand_java_INSTANCEOF,
+ expand_java_CHECKCAST, expand_iinc, expand_java_binop, note_label,
+ expand_compare, expand_test, expand_cond, expand_java_goto,
+ expand_java_call, expand_java_ret, pop_arguments, expand_invoke,
+ expand_java_field_op, java_push_constant_from_pool): Likewise.
+
+ (decode_newarray_type, expand_iinc): Un-ANSI-fy.
+ (build_java_arraynull_check): Mark parameters `node' and `type'
+ with ATTRIBUTE_UNUSED.
+ (note_label): Likewise for parameter `current_pc'.
+ (expand_java_call, expand_java_ret): Hide unused definition.
+
+ * java-tree.h (make_class, build_constants_constructor,
+ java_set_exception_lang_code, pop_labeled_block, emit_handlers,
+ init_outgoing_cpool, register_class, emit_register_classes,
+ java_layout_seen_class_methods): Prototype.
+ (unicode_mangling_length): Const-ify.
+ (append_gpp_mangled_name, append_gpp_mangled_classtype,
+ emit_unicode_mangled_name, format_int, format_uint,
+ jcf_trim_old_input, jcf_print_utf8, jcf_print_char,
+ jcf_print_utf8_replace, open_class): Prototype.
+
+ * jcf-dump.c: Include "config.h", not <config.h>. Don't include
+ <stdio.h>. Include tree.h/java-tree.h.
+ (utf8_equal_string usage, process_class): Add static prototype.
+ (open_class): Don't prototype this here.
+ (utf8_equal_string): Match arguments to format specifiers.
+ (HANDLE_CODE_ATTRIBUTE, BRANCH, JSR, RET, LOOKUP_SWITCH,
+ TABLE_SWITCH, disassemble_method): Likewise.
+
+ * jcf-io.c: Include tree.h/java-tree.h.
+ (open_class, find_classfile, jcf_print_utf8,
+ jcf_print_utf8_replace): Const-ify.
+
+ * jcf-parse.c (parse_zip_file_entries, process_zip_dir,
+ parse_class_file): Add static prototype.
+ (find_in_current_zip): Match definition to existing static
+ prototype.
+
+ * jcf-write.c: Include jcf.h before tree.h/java-tree.h.
+ (alloc_chunk, append_chunk, append_chunk_copy, gen_jcf_label,
+ finish_jcf_block, define_jcf_label, get_jcf_label_here,
+ put_linenumber, localvar_alloc, localvar_free, get_access_flags,
+ write_chunks, adjust_typed_op, generate_bytecode_conditional,
+ generate_bytecode_return, perform_relocations, init_jcf_state,
+ init_jcf_method, release_jcf_state, generate_classfile):
+ Add static prototype.
+ (emit_unop): Mark parameter `type' with ATTRIBUTE_UNUSED.
+ (make_class_file_name): Const-ify.
+
+ * jcf.h (find_classfile): Const-ify.
+
+ * jv-scan.c (reset_report): Remove prototype.
+
+ * jvgenmain.c: Include jcf.h/tree.h/java-tree.h.
+ (error): Rewrite to allow varargs.
+
+ * lang.c (lang_f_options): Const-ify.
+
+ * lex.c (java_parse_escape_sequence): Add static prototype.
+ (java_allocate_new_line): Match definition to existing static
+ prototype.
+
+ * mangle.c Include tree.h/java-tree.h.
+ (unicode_mangling_length, emit_unicode_mangled_name,
+ append_gpp_mangled_name, append_gpp_mangled_classtype): Const-ify.
+
+ * parse.h (jdep_code): Remove trailing comma in enumeration.
+ (java_get_line_col): Move prototype outside of !JC1_LITE test.
+ (reset_report): Add prototype.
+
+ * verify.c (push_pending_label, merge_types): Add static
+ prototypes.
+
+ * zipfile.h (opendir_in_zip, open_in_zip): Prototype.
+
+1999-03-19 Alexandre Petit-Bianco <apbianco@cygnus.com>
+
+ * parse.y (find_applicable_accessible_methods_list): Extend the
+ search to superinterfaces when relevant.
+ (search_applicable_methods_list): New function.
+
+1999-03-18 Alexandre Petit-Bianco <apbianco@cygnus.com>
+
+ * class.c (unmangle_classname): Implemented stricter testing
+ before setting the QUALIFIED_P flag on an identifier.
+
+Tue Mar 16 15:15:41 1999 Per Bothner <bothner@cygnus.com>
+
+ * parse.y (java_complete_lhs): Call force_evaluation_order
+ after patch_newarray.
+ (patch_binop): Don't call fold if there are side effects.
+
+1999-03-16 Alexandre Petit-Bianco <apbianco@cygnus.com>
+
+ * parse.y (java_stabilize_reference): Use save_expr instead of
+ building a SAVE_EXPR node.
+ (java_complete_lhs): Patch the resulting string of the `+='
+ operator (if necessary) and complete the RHS after having built
+ the cast.
+
+Mon Mar 15 12:18:29 1999 Per Bothner <bothner@cygnus.com>
+
+ * class.c (make_class): Don't set CLASS_P here (because
+ this function is also called by build_java_array_type).
+ (push_class): Set CLASS_P here instead.
+ * parse.h (TYPE_CLASS_P): Check for TYPE_ARRAY_P is redundant.
+
+ * jcf-dump.c (print_access_flags): Take extra parameter to indicate
+ context. If the context is class, perfer "super" over "synchronized".
+ * jcf-write.c (generate_classfile): Don't add ACC_SUPER if interface.
+
+ * parse.y (create_class): Don't call parser_check_super here;
+ it is not robust. Always wait until later.
+
+ * parse.y (method_header): For interfaces, set ACC_ABSTRACT (to
+ match what JDK 1.2 does), but don't set ACC_PUBLIC.
+
+Sat Mar 13 18:16:34 1999 Per Bothner <bothner@cygnus.com>
+
+ * lex.c (java_read_char): UNGET invalid non-initial utf8 character.
+ * lex.h (UNGETC): Change misleading macro.
+
+1999-03-12 Alexandre Petit-Bianco <apbianco@cygnus.com>
+
+ * parse.y (java_stabilize_reference): Return NODE when patching a
+ COMPOUND_EXPR.
+ (java_complete_lhs): Put parenthesis around truth values.
+
+1999-03-12 Alexandre Petit-Bianco <apbianco@cygnus.com>
+
+ * class.c (layout_class_method): Don't make rtl for interface
+ methods.
+ * parse.h (GET_TYPE_NAME): New macro.
+ * parse.y (if_then_statement:): Fixed indentation.
+ (if_then_else_statement:): Likewise.
+ (for_statement:): Fixed spacing.
+ (try_statement:): Fixed indentation.
+ (create_interface): Don't force interfaces to be abstract.
+ (method_header): Abstract methods are OK in interfaces.
+ (declare_local_variables): Fixed typo in comment.
+ (java_complete_expand_method): Fixed indentation.
+ (resolve_qualified_expression_name): Use GET_TYPE_NAME to report
+ non accessible fields.
+ (java_stabilize_reference): New function.
+ (java_complete_lhs): Fixed indentation. Use
+ java_stabilize_reference in compound assignement. Insert the
+ cast. If not processing `+' fix string constants before processing
+ binop.
+
+Fri Mar 12 19:42:55 1999 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * constants.c (find_class_or_string_constant): Cast variable `j'
+ to a `jword' when comparing against one.
+
+ * expr.c (java_lang_expand_expr): Remove unused variables
+ `has_finally_p' and `op0'.
+
+ * gjavah.c (print_field_info): Cast a value to jint when comparing
+ against one. Likewise for a jlong.
+ (add_namelet): Likewise cast a `sizeof' to an int when comparing
+ against a signed quantity.
+
+ * jcf-dump.c (print_signature_type): Remove unused variable `digit'.
+ (print_signature): Don't needlessly dereference variable `str'
+
+ * jcf-reader.c (get_attribute): Mark variables `max_stack' and
+ `max_locals' with ATTRIBUTE_UNUSED.
+ (jcf_parse_class): Likewise for variable `index'.
+
+ * parse.h (reverse_jdep_list): Remove static prototype.
+
+ * parse.y (build_jump_to_finally): Remove prototype and definition.
+ (reverse_jdep_list): Add static prototype.
+
+ * typeck.c (convert_ieee_real_to_integer): Remove unused variables
+ `assignment' and `expr_decl'.
+
+ * verify.c (verify_jvm_instructions): Remove unused label `bad_ldc'.
+
+1999-03-12 Andrew Haley <aph@cygnus.com>
+
+ * jcf-path.c (add_entry): alloca len+2 rather than len+1 bytes;
+ we'll need a directory separator and a null character.
+
+Wed Mar 10 23:20:11 1999 Per Bothner <bothner@cygnus.com>
+
+ * jcf-write.c (generate_bytecode_insns): Handle __builtin_fmod, for %.
+
+ Tue Mar 9 11:52:08 1999 Alexandre Petit-Bianco <apbianco@cygnus.com>
+
+ * parse.y (method_header): Don't set ACC_ABSTRACT flags on
+ interfaces.
+
+Fri Mar 5 15:17:29 1999 Per Bothner <bothner@cygnus.com>
+
+ * lex.c (java_parse_end_comment): Take extra parameter (next char).
+
+ * class.c (build_utf8_ref): Fix possible name class/ambiguity.
+
+ * class.c (layout_class_method): A static method in a base class
+ is never overridden, so treat it like it doesn't exist.
+ However, do complain about private non-static method overriding
+ public static method.
+
+ * parse.y: Don't set unused INITIALIZED_P flag.
+ * java-tree.h (INITIALIZED_P): Removed no-longer needed flag.
+
+ * parse.y (find_expr_with_wfl): Optimize tail-calls.
+ (build_array_from_name): Re-order &index[string] to &string[index].
+
+ * parse.y (java_complete_lhs): Don't call patch_assignment if rhs is
+ error_mark (it might catch more errors, but it is more likely to lose).
+
+Sat Mar 6 11:17:16 1999 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * Makefile.in (jcf-parse.o): Depend on $(PARSE_H).
+ (parse-scan.o): Depend on toplev.h.
+
+ * class.c (make_method_value): Add prototype. Make it static.
+ Remove unused second argument, caller changed.
+
+ * expr.c (java_lang_expand_expr): Remove unused variable
+ `return_label'.
+
+ * java-tree.h: Don't prototype find_in_current_zip.
+ Add prototypes for verify_constant_pool, start_java_method,
+ end_java_method, give_name_to_locals, expand_byte_code,
+ open_in_zip, set_constant_value, find_constant1, find_constant2,
+ find_utf8_constant, find_string_constant, find_class_constant,
+ find_fieldref_index, find_methodref_index, write_constant_pool,
+ count_constant_pool_bytes and encode_newarray_type.
+
+ * jcf-dump.c: Remove unused variable `LONG_temp'.
+
+ * jcf-parse.c: Include parse.h.
+ (jcf_parse_source): Remove unused parameter, all callers changed.
+ (jcf_figure_file_type): Add static prototype.
+ (find_in_current_zip): Likewise. Also remove unused parameter,
+ all callers changed.
+ (read_class): Initialize variable `saved_pos'.
+
+ * jcf-reader.c (jcf_parse_preamble): Mark variables
+ `minor_version' and `major_version' with ATTRIBUTE_UNUSED.
+
+ * lex.c (java_is_eol): Wrap prototype and definition in !JC1_LITE.
+ (java_init_lex): Wrap variable `java_lang_imported' in !JC1_LITE.
+ (java_parse_doc_section): Initialize variable `seen_star'.
+ (java_lex): Wrap variable `number_beginning' in !JC1_LITE.
+ (java_lex_error): Mark parameters `msg' and `forward' with
+ ATTRIBUTE_UNUSED.
+ (java_get_line_col): Mark parameters `filename' and `line' with
+ ATTRIBUTE_UNUSED.
+
+ * parse-scan.y: Include toplev.h.
+ (yyerror): Mark parameter `msg' with ATTRIBUTE_UNUSED.
+
+ * parse.h: use `struct JCF', not plain `JCF'.
+ (java_parser_context_save_global, java_expand_classes
+ java_parser_context_restore_global, java_parse): Add prototypes.
+
+ * typeck.c (convert_ieee_real_to_integer): Remove unused variable
+ `node'.
+
+Wed Feb 24 16:13:59 1999 Per Bothner <bothner@deneb.cygnus.com>
+
+ * check-init.c (check_init): COPYN takes word count, not bit count.
+
+Fri Feb 26 14:06:21 1999 Per Bothner <bothner@cygnus.com>
+
+ * typeck.c (convert_ieee_real_to_integer): Use save_expr instead of
+ explicit build_decl. (Avoids crash in reload when optimizing.)
+
+Thu Feb 25 21:05:04 1999 Per Bothner <bothner@cygnus.com>
+
+ * decl.c (complete_start_java_method): Handle synchronized method
+ even when compiling from bytecode.
+
+1999-02-26 Tom Tromey <tromey@cygnus.com>
+
+ * gjavah.c (add_class_decl): Only generate `#include' if outer
+ class is not the name of the class we are processing. Correctly
+ append `.h' in #include.
+ (process_file): Clean up newlines around generated `#include's.
+ (decode_signature_piece): Correctly handle inner classes.
+ (struct include): New structure.
+ (all_includes): New global.
+ (print_include): New function.
+ (add_class_decl): Use it.
+ (process_file): Likewise.
+ (add_class_decl): Generate include for java-array.h if array
+ seen.
+ (process_file): Don't generate java-array.h include.
+
+ * gjavah.c (add_namelet): Check for standard package names here.
+ (add_class_decl): Don't check for standard package names here.
+
+1999-02-25 Tom Tromey <tromey@cygnus.com>
+
+ * parse.y (read_import_dir): Use `|=', not `+=', to set `found'.
+ When reading a zip file, only use strncmp if both strings are
+ bigger than the buffer length. Initialize `k' when looping
+ through zip file.
+
+1999-02-24 Tom Tromey <tromey@cygnus.com>
+
+ * gjavah.c (struct namelet): New structure.
+ (add_namelet): New function.
+ (print_namelet): New function.
+ (print_class_decls): Use add_namelet and print_namelet to generate
+ namespaces and not classes.
+ (method_printed): New global.
+ (HANDLE_END_METHOD): Examine method_printed.
+ (print_method_info): Set method_printed when required. Print
+ error if function to be ignored is marked virtual. Handle $finit$
+ method.
+ (METHOD_IS_FINAL): New macro.
+ (print_field_info): Use it.
+ (HANDLE_METHOD): Clear method_printed.
+ (method_pass): New global.
+ (HANDLE_END_FIELD): Call add_class_decl on the first pass.
+ (process_file): Do two passes over both fields and methods.
+ (HANDLE_METHOD): Examine method_pass.
+ (root): New global.
+ (add_class_decl): New function.
+ (print_class_decls): Don't scan over entire constant pool.
+
+1999-02-23 Tom Tromey <tromey@cygnus.com>
+
+ * jvspec.c (lang_specific_driver): Recognize -fsyntax-only and
+ disable linking in that case.
+
+1999-02-20 Tom Tromey <tromey@cygnus.com>
+
+ * jcf.h (UTF8_GET): Mask first byte of 3-byte encoding with 0x0f,
+ not 0x1f.
+
+Sun Feb 21 14:56:11 1999 Per Bothner <bothner@cygnus.com>
+
+ * decl.c (build_result_decl), java-tree.h: New method.
+ (complete_start_java_method): Handle synchronized methods.
+ Don't build DECL_RESULT here. (Ordering dependency problem.)
+ (start_java_method): Call build_result_decl here instead ...
+ * parse.y (java_complete_expand_method): ... and here.
+ (expand_start_java_method): Don't call complete_start_java_method here.
+ (java_complete_expand_method): Call it here instead.
+ * parse.h (BUILD_MONITOR_ENTER, BUILD_MONITOR_EXIT): Moved to ..
+ * java-tree.h: ... here.
+
+ * expr.c (force_evaluation_order): Fix typo, don't handle ARRAY_REF.
+ * parse.y (java_complete_lhs): Don't call force_evaluation_order
+ for ARRAY_REF - it doesn't work when array bounds are checked.
+ (patch_array_ref): Handle it here instead.
+
+ * jcf-write.c (generate_classfile): Emit "Exceptions" attribute.
+
+Fri Feb 19 15:35:01 1999 Per Bothner <bothner@cygnus.com>
+
+ Force left-to-right evaluation of binary operations etc.
+ * expr.c (force_evaluation_order), java-tree.h: New function.
+ * parse.y (java_complete_lhs): Pass binary operations, procedure
+ calls, and ARRAY_REFs to force_evaluation_order.
+ (various): Set TREE_SIDE_EFFECTS more carefully.
+
+ Tolerate random (non-UTF8) encoding in comments without complaining.
+ * lex.c (java_read_char): Return 0xFFFE if bad UTF8 encoding.
+ (java_is_eol): Handle '\r' followed by '\n' instead of vice versa.
+
+ * parse.y (resolve_qualified_expression_name): Handle error_mark.
+ (java_complete_node case EXPR_WITH_FILE_LOCATION): Likewise.
+
+ * parse.y (java_complete_lhs): Ignore an empty statement in a
+ COMPOUND_EXPR. Don't complain about empty statement after return.
+
+Fri Feb 19 13:00:56 1999 Per Bothner <bothner@cygnus.com>
+
+ * parse.y (obtain_incomplete_type): Don't wrap unknown types
+ in TREE_LIST - just chain the POINTER_TYPEs together.
+ (resolve_class): If type already resolved, return decl.
+ After resolving, update TREE_TYPE(class_type), and name (if array).
+ * parse.h (do_resolve_class), parse.y: Make non-static.
+ * class.c (maybe_layout_super_class): Take this_class argument.
+ Do do_resolve_class if necessary.
+ (layout_class, layout_class_methods): Adjust calls appropriately.
+ * parse.h (JDEP_TO_RESOLVE, JDEP_RESOLVED_DECL, JDEP_RESOLVED,
+ JDEP_RESOLVED_P): Redefined for new TREE_LIST-less convention.
+ * typeck.c (build_java_array_type): Don't call layout_class.
+
+Wed Feb 17 15:47:20 1999 Alexandre Petit-Bianco <apbianco@cygnus.com>
+
+ * parse.y (check_pkg_class_access): Allow private class access
+ within the same package.
+ (strip_out_static_field_access_decl): New function.
+ (patch_unaryop): Call strip_out_static_field_access_decl on ++/--
+ operator argument before testing its nature.
+
+Wed Feb 3 12:38:43 1999 Per Bothner <bothner@cygnus.com>
+
+ * java-tree.def (FINALLY_EXPR): Removed. (Now uses TRY_FINALLY_EXPR.)
+ (TRY_EXPR): Simplify - it no longer has a finally clause.
+ * check-init.c (check_init): Handle TRY_FINALLY_EXPR.
+ Simpler handling of TRY_EXPR, which no longer has a finally clause.
+ * expr.c (java_lang_expand_expr): Likewise.
+ * java-tree.h (CATCH_EXPR_GET_EXPR): Removed - no longer needed.
+ * parse.h (java_get_catch_block), parse.y: Removed - no longer needed.
+ * parse.y (java_complete_lhs): Add support for TRY_FIANLLY_EXPR.
+ (build_try_statement): Remove finally parameter and handling.
+ (build_try_finally_statement): New function.
+ (patch_try_statement): No longer need to support finally clause.
+ (try_statement): Update grammar action rules.
+ * jcf-write.c (generate_bytecode_insns): Handle TRY_FINALLY_EXPR.
+ Simpler handling of TRY_EXPR, which no longer has a finally clause.
+
+1998-11-26 Andrew Haley <aph@viagra.cygnus.co.uk>
+
+ * jcf-parse.c (get_constant): Add braces around computation of 'd'
+ when REAL_ARITHMETIC is not defined. [Oct 26 fix got overwritten -PB]
+
+1999-02-17 Andrew Haley <aph@cygnus.com>
+
+ * class.c (build_utf8_ref): Back out broken patch which was
+ intended to to output signatures using '.' as a separator.
+
+ * class.c (make_class_data): Output signatures using '.' as a
+ separator, rather than '/'.
+ (mangled_classname): Likewise.
+ (make_field_value): Likewise.
+ (make_method_value): Likewise.
+ * constants.c (alloc_class_constant): Likewise.
+ * expr.c (build_invokeinterface): Likewise.
+
+Thu Feb 11 21:25:51 1999 Alexandre Petit-Bianco <apbianco@cygnus.com>
+
+ * parse.y (valid_builtin_assignconv_identity_widening_p): Got rid
+ of an ancient workaround.
+
+Wed Feb 10 23:27:33 1999 Jeffrey A Law (law@cygnus.com)
+
+ * jvspec.c (xmalloc): Kill the prototype. It does not belong
+ here anymore.
+
+1999-02-10 Alexandre Petit-Bianco <apbianco@cygnus.com>
+
+ * lex.c (yylex): Encode \0 as UTF8.
+
+1999-02-10 Tom Tromey <tromey@cygnus.com>
+
+ * jvspec.c (lang_specific_driver): Use libgcj, not libjava.
+ * Makefile.in (jcf-path.o): Define LIBGCJ_ZIP_FILE.
+ (libgcj_zip): Renamed.
+ * jcf-path.c (add_entry): Use LIBGCJ_ZIP_FILE, not
+ LIBJAVA_ZIP_FILE.
+ (jcf_path_init): Use LIBGCJ_ZIP_FILE.
+
+ * jvspec.c (THREAD_NAME): Renamed -lqthreads to -lgcjcoop.
+ (GC_NAME): Renamed -lgc to -lgcjgc.
+
+Tue Feb 9 19:31:09 1999 Alexandre Petit-Bianco <apbianco@cygnus.com>
+
+ * lex.c (java_lang_cloneable): Initialize.
+ * parse.y (java_lang_cloneable): New static variable.
+ (qualify_ambiguous_name): Take CONVERT_EXPR into account when
+ doing one more qualification round.
+ (valid_ref_assignconv_cast_p): Reject null source or
+ destination. Allow an array to be cast into java.lang.Cloneable.
+ (patch_cast): Swapped two first arguments to first call to
+ valid_ref_assignconv_cast_p.
+
+Mon Feb 8 11:50:50 1999 Alexandre Petit-Bianco <apbianco@cygnus.com>
+
+ * parse.h: DECL_P renamed JDECL_P.
+ * parse.y: DECL_P replaced by JDECL_P.
+ (build_array_from_name): Always use pointer's type.
+ (patch_bc_statement): Extra code to search continue target in a
+ for loop. Fixed comments. Continue target is current loop when
+ unlabeled.
+
+1999-02-05 Andrew Haley <aph@cygnus.com>
+
+ * class.c (make_class_data): The superclass of an interface should
+ be null, not class Object.
+
+ * lex.c (java_lex): Sign extend hex literals.
+
+1999-02-04 Andrew Haley <aph@cygnus.com>
+
+ * class.c (build_utf8_ref): Output signatures using '.' as a
+ separator, rather than '/'.
+ (make_class_data): Likewise.
+
+Wed Feb 3 22:50:17 1999 Marc Espie <Marc.Espie@liafa.jussieu.fr>
+
+ * Make-lang.in ($(GCJ)(exeext)): Remove choose-temp.o, pexecute.o and
+ mkstemp.o. Get them from libiberty now.
+
+Tue Feb 2 19:49:12 1999 Jeffrey A Law (law@cygnus.com)
+
+ * jcf-io.c: Do not include sys/stat.h or sys/wait.h
+
+Tue Feb 2 20:04:50 1999 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * jvspec.c (xmalloc): Fix the prototype to match the one obtained
+ from libiberty.h
+
+Tue Feb 2 10:39:47 1999 Per Bothner <bothner@cygnus.com>
+
+ Optimize: `return (a ? b : c)' as: `if (a) return b; else return c;'.
+ * jcf-write.c (generate_bytecode_return): New function.
+ (generate_bytecode_insns): Use it, for RETURN_EXPR.
+
+ * jcf-write.c (generate_bytecode_insns): For REAL_CST that is 0 or 1,
+ generate special [fd]const_[01] instructions.
+
+ * jcf-parse.c (yyparse): Don't emit_register_classes if -fsyntax-only.
+
+ * verify.c (verify_jvm_instructions): Do INVALIDATE_PC after
+ handling OPCODE_lookupswitch or OPCODE_tableswitch.
+
+Mon Feb 1 20:44:47 1999 Per Bothner <bothner@cygnus.com>
+
+ * parse.y (patch_method_invocation): Handle calling static methods,
+ even in the form EXPR.METHOD(ARGS), not just TYPE.METHOD(ARGS).
+
+ * parse.y (java_complete_lhs): Don't complain about unreachable
+ exit condition in a do-while statement.
+
+Fri Jan 29 18:19:02 1999 Alexandre Petit-Bianco <apbianco@cygnus.com>
+
+ * lex.c (java_read_char): Fixed utf8 decoding.
+ (java_unicode_2_utf8): Fixed utf8 encoding in the 0x800-0xffff
+ range.
+ * parse.y (valid_builtin_assignconv_identity_widening_p): Fixed
+ comments. Local variable `all_primitive' is gone. Broadened
+ acceptance of `0' to floating point targets. `long' can now be
+ widened to `double' or `float'.
+ (valid_method_invocation_conversion_p): Added leading
+ comment. Fixed tabulation.
+ (build_string_concatenation): Optimize out left or right empty
+ string constants.
+
+Thu Jan 28 18:51:26 1999 Per Bothner <bothner@cygnus.com>
+
+ * jcf-write.c (localvar_alloc): Only emit entry for
+ LocalVariableTable if debug_info_level > DINFO_LEVEL_TERSE.
+ (generate_bytecode_insns): Only call put_linenumber if
+ debug_info_level > DINFO_LEVEL_NONE.
+ * jvspec.c (lang_specific_driver): If no -O* or -g* option
+ is specified, add -g1 (for compatibility wih javac).
+
+Thu Jan 28 09:17:51 1999 Hans-Peter Nilsson <hp@axis.se>
+
+ * java/Makefile.in: Add missing dependencies for jcf-dump.o,
+ gjavah.o, check-init.o, jv-scan.o
+
+Mon Feb 1 09:50:48 1999 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * Makefile.in (gjavah.o): Depend on $(CONFIG_H) and system.h.
+
+ * gjavah.c: Include config.h and system.h.
+
+ * javaop.h (inline): Don't define, its handled by system.h.
+ (WORD_TO_FLOAT, WORDS_TO_LONG, WORDS_TO_DOUBLE): Change these
+ from `inline' to `static inline'.
+
+ * jcf.h (inline): Don't define, its handled by system.h.
+
+ * lex.c (inline): Likewise.
+
+Sun Jan 31 20:34:29 1999 Zack Weinberg <zack@rabi.columbia.edu>
+
+ * lang-specs.h: Map -Qn to -fno-ident.
+
+Fri Jan 29 16:51:56 1999 Richard Henderson <rth@cygnus.com>
+
+ * check-init.c (check_init): Fix CLEANUP_POINT_EXPR typo.
+
+1999-01-29 Tom Tromey <tromey@cygnus.com>
+
+ * parse.h (BUILD_APPEND): If ARG is a non-String object reference,
+ then cast it to Object before calling `append' method.
+
+Thu Jan 28 14:45:39 1999 Per Bothner <bothner@cygnus.com>
+
+ * check-init.c (check_bool2_init, check_bool_init, check_init):
+ Handle TRUTH_AND_EXPR, TRUTH_OR_EXPR, and TRUTH_XOR_EXPR.
+ * jcf-write.c (generate_bytecode_insns): Likewise.
+
+Thu Jan 28 11:50:11 1999 Alexandre Petit-Bianco <apbianco@cygnus.com>
+
+ * jcf-parse.c (jcf_parse): Don't parse the same class file twice.
+ * parse.y (patch_cast): Allow a boolean to be cast into a
+ boolean.
+
+Wed Jan 27 10:19:29 1999 Alexandre Petit-Bianco <apbianco@cygnus.com>
+
+ * parse.y: (class_declaration:): Fixed indentation.
+ (class_member_declaration:): Extra `;' after field declaration now
+ accepted.
+ (interface_declaration:): Removed debug messages in error reports.
+ (patch_binop): Nodes created and returned inherit the orignal
+ node's COMPOUND_ASSIGN_P flag value.
+ (patch_cast): Fix cast from char to floating point.
+
+Mon Jan 25 17:39:19 1999 Andrew Haley <aph@cygnus.com>
+
+ * except.c, java-except.h (expand_resume_after_catch): new
+ function.
+ * expr.c (java_lang_expand_expr): call expand_resume_after_catch
+ to branch back to main flow of control after a catch block.
+
+Sat Jan 23 23:02:43 1999 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * Makefile.in (parse.o): Depend on $(CONFIG_H) and
+ $(srcdir)/../system.h.
+ (class.o): Depend on $(PARSE_H) and $(srcdir)/../output.h.
+ (jcf-parse.o): Depend on $(srcdir)/../toplev.h.
+ (jcf-write.o): Likewise.
+ (jv-scan.o): Depend on $(CONFIG_H) and $(srcdir)/../system.h.
+ (mangle.o): Depend on $(srcdir)/../toplev.h.
+ (parse-scan.o): Depend on $(CONFIG_H) and $(srcdir)/../system.h.
+ (zextract.o): Depend on $(CONFIG_H) and $(srcdir)/../system.h.
+
+ * class.c: Include output.h and parse.h.
+ (mangled_classname): Add the `const' keyword to a char*.
+ (find_named_method): Hide unused function definition.
+ (build_utf8_ref): Change type of variable `c' to unsigned char.
+ Use ISALPHA/ISDIGIT instead of isalpha/isdigit.
+ (build_class_ref): Add the `const' keyword to a char*.
+ (layout_class_method): Remove unused variable `buf'.
+
+ * decl.c (find_local_variable): Remove unused variable `rtl'.
+ (pushdecl): Likewise for variables `different_binding_level' and
+ `oldglobal'.
+ (pushlevel): Mark parameter `unused' with ATTRIBUTE_UNUSED.
+ (maybe_build_cleanup): Likewise for parameter `decl'.
+
+ * except.c (expand_start_java_handler): Mark parameter `range'
+ with ATTRIBUTE_UNUSED.
+
+ * expr.c: Include except.h.
+ (pop_type): Remove unused variable `i'.
+ (pop_value): Likewise for variables `n_words' and `i'.
+ (expand_java_arrayload): Likewise for variable `convert'.
+ (java_lang_expand_expr): Likewise for variables `op0', `type',
+ `mode', `unsignedp', `node' and `elements'.
+ (expand_byte_code): Likewise for variables `prev_eh_ranges' and
+ `eh_ranges'.
+ (process_jvm_instruction): Add a `const' qualifier to a char*.
+
+ * gjavah.c (output_directory): Add the `const' keyword to a char*.
+ (temp_directory): Likewise.
+ (print_c_decl): Likewise.
+ (print_method_info): Likewise.
+ (decode_signature_piece): Likewise.
+ (print_mangled_classname): Likewise.
+
+ * java-except.h: Provide prototypes for maybe_start_try,
+ maybe_end_try and add_handler.
+
+ * java-tree.h (mangled_classname): Add the `const' keyword to a char*.
+ (parse_error_context): Likewise. Also add ATTRIBUTE_PRINTF_2.
+ (pushdecl_top_level, alloc_class_constant, unicode_mangling_length,
+ init_expr_processing, push_super_field, init_class_processing,
+ can_widen_reference_to, class_depth, verify_jvm_instructions,
+ maybe_pushlevels, maybe_poplevels, process_jvm_instruction,
+ set_local_type, merge_type_state, push_type, load_type_state,
+ add_interface, find_in_current_zip, append_gpp_mangled_classtype,
+ emit_unicode_mangled_name): Add prototypes.
+
+ * jcf-dump.c (print_constant): Add the `const' keyword to a char*.
+ (print_signature_type): Use ISDIGIT, not isdigit.
+ (print_signature): Remove unused variable `j'.
+
+ * jcf-io.c (jcf_filbuf_from_stdio): Cast the result of `fread' to
+ int when comparing against one.
+
+ * jcf-parse.c: Include toplev.h.
+
+ * jcf-write.c: Likewise. Don't include <string.h> or <sys/stat.h>.
+ (localvar_free): Remove unused variable `i'.
+ (generate_bytecode_conditional): Likewise for variable `kind'.
+
+ * jv-scan.c: Include config.h and system.h. Remove redundant
+ OS header and gansidecl.h includes.
+ (warning): Add the `const' keyword to a char*. Also add
+ ATTRIBUTE_PRINTF_1 to the prototype. Check ANSI_PROTOTYPES, not
+ __STDC__, when determining whether to use ANSI-isms.
+ (fatal): Likewise. Also add ATTRIBUTE_UNUSED.
+ (xmalloc): Don't redundantly prototype here.
+ (main): Remove unused parameter `envp'. Also fix the arguments
+ passed to function `fatal' to match the format specifier.
+
+ * lang.c (java_tree_code_name): Add the `const' keyword to a char*.
+
+ * mangle.c: Include toplev.h.
+ (emit_unicode_mangled_name): Declare parameter `len'.
+
+ * parse.y (parse_warning_context): Add the `const' keyword to a
+ char*. Also add ATTRIBUTE_PRINTF_2 to the prototype. Check
+ `ANSI_PROTOTYPES' not `__STDC__' for whether to use ANSI-isms.
+ (issue_warning_error_from_context): Add the `const' keyword to
+ a char*.
+ (parse_error_context): Likewise. Also check `ANSI_PROTOTYPES'
+ not `__STDC__' for whether to use ANSI-isms.
+
+ * typeck.c (incomplete_type_error): Mark parameters `value' and
+ `type' with ATTRIBUTE_UNUSED.
+ (parse_signature_type): Use ISDIGIT, not isdigit.
+
+ * verify.c (check_pending_block): Add the `const' keyword to a char*.
+ (verify_jvm_instructions): Likewise. Remove unused variables
+ `field_name' and `default_val'.
+
+ * zextract.c: Include config.h and system.h. Remove redundant
+ OS header includes.
+
+ * zipfile.h: Prototype `read_zip_archive'.
+
+Thu Jan 21 16:00:06 1999 Andrew Haley <aph@cygnus.com>
+
+ * typeck.c (convert): Allow conversions to void type: some
+ optimizations in gcc do this.
+
+Thu Jan 21 15:21:49 1999 Andrew Haley <aph@cygnus.com>
+
+ * typeck.c (convert_ieee_real_to_integer): New function.
+ (convert): When not using fast-math and using hardware fp, convert
+ an IEEE NaN to zero.
+
+1999-01-18 Andrew Haley <aph@cygnus.com>
+
+ * parse.y (patch_binop): Do a type conversion from signed to
+ unsigned and then back to signed when a ">>>" is found.
+
+Sun Jan 17 22:34:22 1999 Alexandre Petit-Bianco <apbianco@cygnus.com>
+
+ * java-tree.h: (check_for_initialization): Added prototype.
+ * lex.c (java_parse_doc_section): `\n' breaks the `*/' string.
+ * parse.y (do_resolve_class): Removed unused locals.
+ (read_import_dir): Likewise.
+ (resolve_qualified_expression_name): Array creation
+ expressions are valid primary expressions.
+ (qualify_ambiguous_name): Likewise.
+ (patch_synchronized_statement): Removed unused local.
+
+Sun Jan 17 21:55:42 1999 Jeffrey A Law (law@cygnus.com)
+
+ * Makefile.in (zextract.o): Add dependencies.
+
+ * Makefile.in: Do not put ^Ls at the start of a line.
+
+Fri Jan 15 20:16:20 1999 Per Bothner <bothner@cygnus.com>
+
+ * expr.c (process_jvm_instruction): Coerce to correct Throwable
+ sub-type the result of the call that gets the exception value.
+
+ * parse.y (java_complete_expand_methods): If flags_syntax_only,
+ don't call finish_class.
+
+ * parse.y (java_check_regular_methods): If METHOD_PRIVATE,
+ clear found before continuing.
+
+ * verify.c (verify_jvm_instructions): On an array load, allow
+ and handle top of stack to be TYPE_NULL.
+
+ * gjavah.c (generate_access): Translate Java package private or
+ protected access to C++ public, but with a comment.
+
+1999-01-13 Andrew Haley <aph@cygnus.com>
+
+ * expr.c (generate_name): Name prefix changed to avoid clashes
+ with assembler temp labels.
+
+ * parse.y (patch_synchronized_statement): Set TREE_SIDE_EFFECTS on
+ MODIFY_EXPR. Without this, code for the assignement may not be
+ generated at all and the synchronized statement will read an
+ uninitialized variable.
+
+Wed Jan 13 01:24:54 1999 Alexandre Petit-Bianco <apbianco@cygnus.com>
+
+ * class.c (maybe_layout_super_class): Fixed returned value.
+ * lex.c: Added 1999 to the copyright.
+ (java_init_lex): Initialize java_lang_imported.
+ * lex.h: Added 1999 to the copyright.
+ * parse.h: Added 1999 to the copyright.
+ (REGISTER_IMPORT): Fixed typo in trailing macro.
+ (CURRENT_OSB): New macro.
+ (struct parser_ctxt): New fields osb_depth, osb_limit.
+ * parse.y (java_lang_id): New global variable.
+ (type_import_on_demand_declaration): Don't import java.lang.* twice.
+ (array_creation_expression:): Use CURRENT_OSB.
+ (dims:): Uses a stack to keep track of array dimensions.
+ (cast_expression:): Use CURRENT_OSB.
+ (find_expr_with_wfl): Return NULL if node found doesn't meet the
+ conditions.
+ (register_fields): Fixed typos in comment.
+ (check_method_redefinition): Fixed comment indentation.
+ (java_check_regular_methods): Set saved found wfl to NULL after
+ having reinstalled it in the previously found DECL_NAME.
+
+Sun Jan 10 13:36:14 1999 Richard Henderson <rth@cygnus.com>
+
+ * gjavah.c (java_float_finite): Use a union to do type punning.
+ (java_double_finite): Likewise.
+
+Sat Jan 9 11:25:00 1999 Per Bothner <bothner@cygnus.com>
+
+ * parse.y (build_new_array_init): Don't set EXPR_WFL_LINECOL
+ on CONSTRUCTOR (since that trashes TREE_CST_RTL).
+ (patch_new_array_init): Clear TREE_CONSTANT also if INDIRECT_REF.
+ (register_fields): Set TREE_STATIC on NEW_ARRAY_INIT, not on
+ CONSTRUCTOR (which causes expand_expr to call output_constant_def).
+ * expr.c (java_lang_expand_expr): Check TREE_STATIC of NEW_ARRAY_INIT.
+
+Fri Jan 8 15:48:03 1999 Per Bothner <bothner@cygnus.com>
+
+ * check-init.c (check_init): If compiling to native, we don't
+ see THROW_EXPR. Instead, look for a call to throw_node (_Jv_Throw).
+
+1999-01-08 Tom Tromey <tromey@cygnus.com>
+
+ * parse-scan.y (variable_declarator_id): Set or increment
+ bracket_count.
+ (bracket_count): New global.
+ (formal_parameter): Handle case where bracket pairs trail variable
+ declarator id.
+
+1999-01-07 Andrew Haley <aph@viagra.cygnus.co.uk>
+
+ * jcf-parse.c (yyparse): variable len changed from a char to an
+ int to prevent overflow.
+
+Wed Jan 6 17:19:46 1999 Per Bothner <bothner@cygnus.com>
+
+ * java-tree.h: Declare read_class.
+ * jcf-parse.c (read_class): New function.
+ (load_class): Now just call read_class.
+
+ * java-tree.h (java_parse_abort_on_error): Only return if new errors.
+ * jcf-parse.c (parse_source_file): Declare save_error_count,
+ which is needed by java_parse_abort_on_error macro,
+ * parse.y (java_layout_classes, java_expand_classes): Likewise.
+
+ * parse.y (register_fields): Set TREE_STATIC flag of NEW_ARRAY_INIT
+ constructor, if initializing a static field.
+ (patch_new_array_init): Set TREE_CONSTANT if it is.
+ * expr.c (java_lang_expand_expr): For a static array constructor
+ of primitive elements, allocate the array itself statically.
+ Disabled until we can set the vtable field statically.
+
+ * check-init.c: New file. Checks for definite assignment.
+ * Makefile.in (JAVA_OBJS): Add check-init.o.
+ * parse.y (java_complete_expand_method): Call check_for_initialization.
+ * parse.h (BLOCK_EXPR_DECLS, BLOCK_EXPR_BODY): Moved to java-tree.h.
+
+Wed Jan 6 14:53:10 1999 Graham <grahams@rcp.co.uk>
+
+ * parse.y : include system.h instead of including
+ standard headers directly with the exception of <dirent.h>.
+
+Wed Jan 6 16:20:06 1999 Per Bothner <bothner@cygnus.com>
+
+ * lex.h: Moved static function declarations to lex.c,
+ to shut up some -Wall warnings.
+ * lex.c: Static function declarations moved here.
+ * jcf-dump.c: Small fixes to shut up -Wall warnings.
+
+Tue Jan 5 22:15:40 1999 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * Make-lang.in ($(GCJ).o): Depend on prefix.h.
+
+Tue Dec 22 11:25:19 1998 Per Bothner <bothner@cygnus.com>
+
+ * expr.c (process_jvm_instruction): Do load_type_state after JSR.
+ * verify.c (verify_jvm_instructions): Fix off-by-one error.
+
+ * jcf-write.c (CHECK_PUT): Add (void) cast to avoid -Wall warnings.
+ (localvar_alloc): Change return type to void,
+ (emit_unop): Remove unused variable size.
+
+ * jcf-write.c (struct jcf_block): Add new union.
+ (PENDING_CLEANUP_PC, PENDING_EXIT_PC, UNDEFINED_PC): New macros.
+ (call_cleanups): New functions.
+ (struct jcf_partial): New fields num_finalizers and return_value_decl.
+ (generate_bytecode_insns): Support CLEANUP_POINT_EXPR and
+ WITH_CLEANUP_EXPR. Handle cleanups in RETURN_EXPR and EXIT_BLOCK_EXPR.
+ * lang.c (lang_init): Call using_eh_for_cleanups.
+ * parse.y (java_complete_lhs): For SYNCHRONIZED_EXPR, defer
+ completing operands to patch_synchronized_statement.
+ Support CLEANUP_POINT_EXPR, WITH_CLEANUP_EXPR.
+ (patch_synchronized_statement): Re-write suing CLEANUP_POINT_EXPR and
+ WITH_CLEANUP_EXPR instead of TRY_EXPR.
+
+Sun Dec 20 16:15:44 1998 John F. Carr <jfc@mit.edu>
+
+ * Make-lang.in: Comment out control-Ls; they upset some makes.
+
+1998-12-18 Tom Tromey <tromey@cygnus.com>
+
+ * parse.y (check_class_interface_creation): Use DIR_SEPARATOR
+ consistently.
+
+1998-12-17 Tom Tromey <tromey@cygnus.com>
+
+ * parse.y (DIR_SEPARATOR): New define.
+ (check_class_interface_creation): Use it.
+
+ * parse-scan.y (report_main_declaration): Recognize
+ `java.lang.String' in argument to main.
+
+Wed Dec 16 16:18:59 1998 Per Bothner <bothner@cygnus.com>
+
+ * parse.y (create_interface): Remove bogus test.
+
+Wed Dec 16 14:42:19 1998 Per Bothner <bothner@cygnus.com>
+
+ * jcf-parse.c (get_constant): Set TREE_TYPE for string constants.
+ (HANDLE_CONSTANTVALUE): If flag_emit_class_files, call get_constant.
+
+1998-12-16 Tom Tromey <tromey@cygnus.com>
+
+ * parse-scan.y (qualified_name): Use correct sprintf format.
+
+1998-12-15 Tom Tromey <tromey@cygnus.com>
+
+ * gjavah.c (print_field_info): Changed how most negative number is
+ printed.
+
+Mon Dec 14 18:49:29 1998 Per Bothner <bothner@cygnus.com>
+
+ * parse.y (fold_constant_for_init): New function.
+ (resolve_expression_name): Don't replace static final
+ constant-initialized fields by its value.
+ (java_complete_lhs): New. Same as java_complete_tree, except does
+ not replace static final constant-initialized fields by their values.
+ (register_fields): If there is an initializer, set DECL_INITIAL and
+ MODIFY_EXPR_FROM_INITIALIZATION_P.
+ (java_complete_tree): For MODIFY_EXPR, use java_complete_lhs for lhs.
+ Only call patch_initialized_static_field if
+ MODIFY_EXPR_FROM_INITIALIZATION_P.
+ (patch_initialized_static_field): If not valid constant, clear
+ DECL_INITIAL.
+
+ * parse.y (lookup_field_wrapper): Fix thinko.
+
+ * parse.y (java_complete_tree): In EXPR_WITH_FILE_LOCATION,
+ set and restore global lineno.
+
+1998-12-14 Tom Tromey <tromey@cygnus.com>
+
+ * gjavah.c (print_field_info): If value to print is the smallest
+ value of its size, then print as hex to avoid later warnings from
+ C++ compiler.
+
+1998-12-14 Tom Tromey <tromey@cygnus.com>
+
+ * gjavah.c (decompile_method): Decompile `return null'.
+ (process_file): Generate `#pragma interface'.
+ (method_declared): New global.
+ (print_method_info): Set it.
+ (HANDLE_CODE_ATTRIBUTE): Only print it method_declared set.
+ (print_method_info): Handle abstract methods.
+
+Sun Dec 13 17:31:40 1998 Per Bothner <bothner@cygnus.com>
+
+ * parse.y (patch_method_invocation): If class_decl is null
+ (e.g. an array type), use original type.
+
+ * parse.y (check_thrown_exceptions): Temporary hack to suppress
+ errors about uncaught exception from clone (of array, specifically).
+
+1998-12-13 Tom Tromey <tromey@cygnus.com>
+
+ * gjavah.c (decompile_method): Handle all types of `return'
+ opcode. Decompile `return this' and `return'.
+ (method_access): New global.
+ (print_method_info): Set it.
+ (decompile_method): Don't decompile a synchronized method.
+
+1998-12-13 Tom Tromey <tromey@cygnus.com>
+
+ * jcf-reader.c (jcf_parse_one_method): Recognize
+ HANDLE_END_METHOD.
+ * gjavah.c (HANDLE_END_METHOD): New macro.
+ (HANDLE_CODE_ATTRIBUTE): New macro.
+ (decompile_method): New function.
+ (print_method_info): Don't print `;\n' at end of function decl.
+ Include java-opcodes.h.
+ (decompiled): New global.
+
+Sat Dec 12 20:13:19 1998 Per Bothner <bothner@cygnus.com>
+
+ * class.c (build_class_ref): Handle PRIMTYPE.class if
+ flag_emit_class_files.
+ * expr.c (expand_java_field_op): Don't optimize java.lang.XXX.TYPE
+ if flag_emit_class_files.
+ * parse.y (java_complete_tree): Pre-liminary support for
+ COMPONENT_REF - only to handle PRIMCLASS.TYPE.
+
+ * parse.y (patch_synchronized_statement): Don't call monitorexit
+ unless block CAN_COMPLETE_NORMALLY. Propagate that flag properly.
+
+ * java-tree.h (DECL_LOCAL_STATIC_VALUE): Removed - no longer used.
+
+ * zipfile.h (opendir_in_zip): New declaration.
+ * jcf-io.c (saw_java_source): Moved to jcf-parse.c.
+ (opendir_in_zip): New function, using code from open_in_zip.
+ (open_in_zip): Call opendir_in_zip.
+ (find_class): Remove no-longer-used do_class_file parameter,
+ but add source_ok parameter. Change logic so if we find a .java file,
+ we don't look for .class in later classpath emtries.
+ * jcf-parse.c (load_class): Pass saw_java_source to find_class.
+ (jcf_figure_file_type): Only call open_in_zip if correct magic number.
+ * gjavah.c: Update call to find_class.
+ * jcf-dump.c: Likewise.
+
+ * jcf-write.c (put_linenumber): Handle duplicate line numbers.
+ (generate_bytecode_insns): For EXPR_WITH_FILE_LOCATION, do
+ nothing if body is empty_stmt_node.
+ Various little fixes so SP gets correctly adjusted.
+ For NEW_ARRAY_INIT, handle IGNORE_TARGET.
+ For CALL_EXPR, test if static first.
+ (generate_classfile): Ignore fields that are DECL_ARTIFICIAL,
+ such as the ones we create for Object and Class.
+ Set and restore current_function_decl.
+ * parse.y: Check/set IS_AN_IMPORT_ON_DEMAND_P in read_import_dir.
+ (note_possible_classname): New function.
+ (read_import_entry): Removed. Merged with read_import_dir.
+ (read_import_dir): Don't call find_class - that only gives us
+ the first classpath entry having the needed package.
+ Use the struct buffer data structure from buffer.h.
+ (read_import_dir, find_in_imports_on_demand): The remembered
+ class names now use '.' (not '/') as package separator.
+
+ * parse.y (java_complete_expand_methods): Call write_classfile
+ here, and not in java_expand_classes (which only gets first class).
+
+Sat Dec 12 19:46:04 1998 Alexandre Petit-Bianco <apbianco@sendai.cygnus.com>
+
+ * parse.y (<type_declaration>): Do maybe_generate_clinit last.
+ (register_fields): If a static fields has an initializer, just
+ chain it on ctxp->static_initialized, and handle later.
+ (java_complete_expand_methods): Force <clinit> first.
+ (resolve_expression_name, resolve_field_access): Just get DECL_INITIAL
+ - it's already been completed.
+ (patch_initialized_static_field): New function.
+ (java_complete_field): Call it.
+
+Sat Dec 12 19:21:11 1998 Per Bothner <bothner@cygnus.com>
+
+ * expr.c (encode_newarray_type, build_new_array): New functions.
+ * java-tree.h: Declare build_new_array.
+ * jcf-write.c (patch_newarray): Use build_new_array.
+
+ * expr.c (java_lang_expand_exp): Support NEW_ARRAY_INIT.
+ * jcf-write.c (generate_bytecode_insns): Support NEW_ARRAY_INIT.
+
+ * parse.y (patch_new_array_init): Re-organize.
+ Now is passed the actual array (pointer) type of the value.
+ Set the type of the CONSTRUCTOR to be an ARRAY_TYPE.
+ (patch_array_constructor): Removed - merged into patch_new_array_init.
+ (java_complete_tree): Update patch_new_array_init.
+
+ * jcf-write.c (find_constant_index): New function.
+ (generate_bytecode_insns): Use find_constant_index.
+ (generate_classfile): Use find_constant_index for ConstantValue.
+
+1998-12-11 Tom Tromey <tromey@cygnus.com>
+
+ * expr.c (invoke_build_dtable): Renamed dtable -> vtable.
+ * decl.c (init_decl_processing): Renamed dtable -> vtable.
+ * class.c (make_class_data): Renamed dtable -> vtable, and
+ dtable_method_count -> vtable_method_count.
+
+Thu Dec 10 20:00:54 1998 Alexandre Petit-Bianco <apbianco@sendai.cygnus.com>
+
+ * decl.c (long_zero_node, float_zero_node, double_zero_node): New
+ global variables, initialized.
+ * java-tree.h (long_zero_node, float_zero_node, double_zero_node):
+ Declared new global variables.
+ * lex.c (java_lex): Return long_zero_node, float_zero_node,
+ double_zero_node, integer_zero_node upon direct matching.
+ * parse.y (purify_type_name): Added function prototype.
+ (duplicate_declaration_error_p): Consider new_type as potentially
+ being a incomplete type. Use purify_type_name on type string.
+ (method_header): saved_type: unused variable removed. Don't figure
+ return type if method name is invalid.
+ (java_complete_tree): Set CAN_COMPLETE_NORMALLY after `node' was
+ processed by patch_unaryop.
+ (patch_unaryop): Fixed typo in comment. Re-convert pre/post
+ increment/decrement node into its original type after binary
+ numeric promotion on its operands.
+
+Thu Dec 10 11:02:49 1998 Alexandre Petit-Bianco <apbianco@cygnus.com>
+
+ * parse.y (array_initializer:): Array init operand is NULL_TREE
+ instead of a TREE_LIST of NULL_TREEs when parsing `{}'. `{,}' is
+ now an error. Fixed indentation problems.
+ (patch_string): Handle error_mark_node as an argument.
+ (patch_new_array_init): Fixed indentation problems.
+ (array_constructor_check_entry): Removed check on null wfl_value.
+ Return an error if wfl_value's walk returns an error.
+
+Wed Dec 9 15:37:05 1998 Alexandre Petit-Bianco <apbianco@cygnus.com>
+
+ * java-tree.def (NEW_ARRAY_INIT): New Java tree code.
+ * lex.c (java_lex): Remember column position before advancing one
+ token. Retain location information on OCB_TK.
+ * lex.h (typedef struct java_lc): Added new field.
+ * parse.h (GET_SKIP_TYPE): New macro.
+ (QUAL_DECL_TYPE): Redefined using GET_SKIP_TYPE.
+ * parse.y (build_new_array_init, patch_new_array_init,
+ patch_array_constructor, maybe_build_array_element_wfl,
+ array_constructor_check_entry): New function prototypes.
+ (switch_block:): Tagged <node>.
+ (OCB_TK): Tagged <operator>.
+ (array_initializer:): Installed actions.
+ (variable_initializer): Build location information on element if
+ necessary.
+ (switch_statement:): Fixed indentation typo.
+ (switch_block:): Redefined default action.
+ (java_complete_tree): Handle NEW_ARRAY_INIT in MODIFY_EXPR:.
+ (patch_assignment): Removed duplicate code.
+ (maybe_build_array_element_wfl, build_new_array_init,
+ patch_new_array_init, patch_array_constructor,
+ array_constructor_check_entry): New functions.
+
+Mon Dec 7 15:13:52 1998 Alexandre Petit-Bianco <apbianco@cygnus.com>
+
+ * parse.y (array_initializer): Tagged <node>.
+ (variable_initializer:): Use default rule.
+ (array_initializer:): Defined actions.
+ (variable_initializers:): Likewise.
+ (resolve_qualified_expression_name): Use DECL_CONTEXT to build
+ non-static field accesses.
+ (patch_invoke): Fixed indentation typo.
+ (java_complete_tree): Likewise.
+ (build_labeled_block): Changed leading comment. Generate an error
+ in case of duplicate loop labels.
+ (patch_conditional_expr): Patch results of string concatenation
+ operations.
+
+Sun Dec 6 13:45:00 1998 Per Bothner <bothner@cygnus.com>
+
+ * constants.c (find_methodref_index): When the class is an interface,
+ generate CONSTANT_InterfaceMethodref instead of a CONSTANT_MethodRef.
+
+ * decl.c (finit_identifier_node): Use "$finit$", rather than
+ "<finit>" (which Sun's verifier rejects).
+ * parse.y (maybe_generate_finit): Leave out meaningless final flag.
+ (generate_field_initialization_code): Removed.
+ (fix_constructors) Don't add call to $finit$ here (wrong order).
+ (patch_method_invocation): Add $finit$ call here.
+
+ * java-tree.h (CALL_USING_SUPER): New macro.
+ * parse.y (patch_invoke): Remove im local variable.
+ (patch_method_invocation, patch_invoke): Don't pass super parameter.
+ (patch_invoke): Use CALL_USING_SUPER instead of from_super parameter.
+ (resolve_qualified_expression_name): Maybe set CALL_USING_SUPER.
+
+ * jcf-write.c (get_access_flags): Fix typo ACC_PUBLIC -> ACC_FINAL.
+
+ * parse.y (java_complete_tree): Don't complain about unreachable
+ statement if it is empty_stmt_node.
+
+ * jcf-write.c (find_constant_wide): New function.
+ (push_long_const): Use find_constant_wide.
+
+ * jcf-write.c (generate_bytecode_insn): Fix bug in switch handling.
+ (generate_bytecode_insn): Use correct dup variant for MODIFY_EXPR.
+ Add "redundant" NOTE_PUSH/NOTE_POP uses so code_SP_max gets set.
+ Emit invokeinterface when calling an interface method.
+ Emit invokespecial also when calling super or private methods.
+
+ * jcf-write.c (generate_classfile): Emit ConstantValue attributes.
+
+Sun Dec 6 13:21:18 1998 Per Bothner <bothner@cygnus.com>
+
+ * jcf-dump.c (INVOKE): If invokeinterface, print number of args.
+
+Thu Dec 3 17:11:12 1998 Alexandre Petit-Bianco <apbianco@cygnus.com>
+
+ * java-tree.h (java_layout_seen_class_methods): New function
+ prototype.
+ (LAYOUT_SEEN_CLASS_METHODS): Macro removed.
+ * jcf-parse.c (parse_class_file): Call java_layout_seen_class_methods.
+ * parse.h (PROMOTE_RECORD_IF_COMPLETE): New macro.
+ * parse.y (method_declarator:): Defined action.
+ (issue_warning_error_from_context): input_filename saved, set to
+ the appropriate value and restored after java_error is called.
+ (build_unresolved_array_type): Fixed comment.
+ (register_fields): Use PROMOTE_RECORD_IF_COMPLETE.
+ (method_header): Deal with return type the same way type are
+ handled for fields and method's parameters and local variables
+ types are handled.
+ (check_method_redefinition): Removed extra CR.
+ (declare_local_variables): Use PROMOTE_RECORD_IF_COMPLETE.
+ (java_layout_seen_class_methods): New function.
+ (java_layout_classes): Call java_layout_seen_class_methods.
+
+Thu Dec 3 15:56:50 1998 Per Bothner <bothner@cygnus.com>
+
+ * parse,y (patch_synchronized_statement): Set CAN_COMPLETE_NORMALLY.
+
+Thu Dec 3 15:08:30 1998 Per Bothner <bothner@cygnus.com>
+
+ * jcf-dump.c (main): Fix error message.
+ * jcf-path.c (add_entry): Style fix.
+
+Wed Dec 2 15:52:25 1998 Alexandre Petit-Bianco <apbianco@cygnus.com>
+
+ * class.c (layout_class_method): Call build_java_argument_signature
+ on constructors too.
+ * parse.y (check_method_redefinition): Use TYPE_ARGUMENT_SIGNATURE.
+ (patch_method_invocation): Define a primary when resolving an
+ expression name. Augmented comment on code checking illegal `this'
+ usage. Loosened it test by accepting NEW_CLASS_EXPR.
+
+Tue Dec 1 13:53:24 1998 Alexandre Petit-Bianco <apbianco@cygnus.com>
+
+ * class.c (layout_class_method): Don't report error on non-static
+ overriding static if the method is private.
+ * java-tree.h (finish_class): Prototype added.
+ * lex.c (java_get_line_col): Handle col argument -2 value.
+ * parse.h: All static method declarations moved to parse.y.
+ * parse.y: Now contains all static method declarations previously
+ found in parse.h.
+ (find_expr_with_wfl, missing_return_error,
+ unreachable_stmt_error): New functions.
+ (java_get_real_method_name): Identify constructors bearing class
+ names in source code compiled classes only.
+ (java_complete_expand_methods): Call missing_return_error.
+ (invocation_mode): Private methods invoked as static methods.
+ (java_complete_tree): Call unreachable_stmt_error.
+
+1998-12-01 Tom Tromey <tromey@cygnus.com>
+
+ * Makefile.in (+target): Removed.
+ (+xmake_file): Likewise.
+ (+tmake_file): Likewise.
+ (.NOEXPORT): Removed duplicate.
+
+Fri Nov 27 13:20:51 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * Makefile.in (jc1, jv-scan): Link with $(SUBDIR_OBSTACK).
+
+ * jv-scan.c: Fix xmalloc prototype. Provide an xmalloc definition.
+
+ * jvgenmain.c: Remove the xmalloc prototype, we get it from
+ libiberty.h. Provide an xmalloc definition.
+
+ * jvspec.c: Remove the xmalloc prototype.
+
+ * parse-scan.y: Include config.h and system.h. Don't include
+ OS headers or gansidecl.h. Don't prototype xmalloc/xstrdup.
+ Provide an xstrdup definition.
+
+Wed Nov 26 22:03:58 1998 Alexandre Oliva <oliva@dcc.unicamp.br>
+
+ * jcf-path.c (add_entry): recognize ".jar" too
+ * lang-specs.h: ditto
+
+Thu Nov 26 12:44:07 1998 Per Bothner <bothner@cygnus.com>
+
+ * jcf-write.c (generate_bytecode_insns): In Call_EXPR, handle
+ soft_monitorenter_node, soft_monitorexit_node, throw_node.
+
+ * jcf-write.c (generate_bytecode_insns):
+ Handle pre/post-increment/decrement of long.
+
+ * jcf-write.c (generate_bytecode_insns):
+ Handle missing exception handler (finally for synchronized).
+
+Wed Nov 25 09:47:15 1998 Per Bothner <bothner@cygnus.com>
+
+ * java-tree.h (end_params_node): Declare global.
+ * decl.c (end_params_node): New global.
+ (init_decl_processing, start_java_method): Use end_params_node for
+ end of list of parameter types. Follows correct gcc conventions.
+ * expr.c (pop_argument_types, pop_arguments): Likewise.
+ * lang.c (put_decl_node): Likewise.
+ * typeck.c (various places): Likewise.
+ * class.y (various places): Likewise.
+ * parse.y (various places): Likewise.
+
+ * parse.y (java_complete_tree): Move CAN_COMPLETE_NORMALLY.
+ (build_jump_to_finally): Add missing CAN_COMPLETE_NORMALLY.
+
+ * class.c: Add #include flags.h, remove no-longer needed declaration.
+
+ * class.c (layout_class_method): Remove commented-out code, re-format.
+ Don't add vtable entry (or index) for private methods.
+ * expr.c (expand_invoke): A private method is implicitly final.
+ * class.c (make_class_data): If inlining or optimizing,
+ skip private methods.
+
+ * class.c (finish_class): New function. Calls existing methods,
+ but alls emits deferred inline functions.
+ * jcf-parse.c (parse_class_file): Call finish_class.
+ * parse.y (java_complete_expand_methods): Likewise.
+
+ * expr.c (build_java_binop): Explicit default, to silence -Wall.
+
+ * expr.c (CHECK_PC_IN_RANGE): Add void cast to kill warnings.
+
+Wed Nov 25 00:50:58 1998 Marc Espie <espie@quatramaran.ens.fr>
+
+ * jcf-write.c (generate_bytecode_conditional): Fix typo.
+
+Tue Nov 24 17:06:38 1998 Per Bothner <bothner@cygnus.com>
+
+ * (generate_classfile): Always write class access flag with
+ ACC_SUPER set.
+
+Tue Nov 24 16:34:33 1998 Alexandre Petit-Bianco <apbianco@cygnus.com>
+
+ * class.c (maybe_layout_super_class): New function.
+ (layout_class): Reorganized. Loop on class methods dispatched into
+ a new function. Call maybe_layout_super_class.
+ (layout_class_methods, layout_class_method): New functions.
+ * expr.c (expand_java_NEW): Call layout_class_methods on loaded
+ class.
+ (expand_invoke): Likewise.
+ * java-tree.h (all_class_list): New global variable declared.
+ (layout_class_methods, layout_class_method): New function
+ prototypes.
+ (LAYOUT_SEEN_CLASS_METHODS): New macro.
+ * jcf-parse.c (all_class_list): New global variable.
+ (load_class): Extended what class_or_name can be. Use parser
+ context mechanism to save globals before calling jcf_parse.
+ (jcf_parse_source): Don't parse twice if HAS_BEEN_ALREADY_PARSED_P
+ is set on the file name.
+ (jcf_parse): Layout class methods when Object is loaded, otherwise
+ record class in all_class_list for delayed method layout.
+ (parse_class_file): Use LAYOUT_SEEN_CLASS_METHODS.
+ * lang.c (put_decl_node): Decode <init> into the decl context
+ class name.
+ * lex.c (java_allocate_new_line): Use xmalloc.
+ * parse.h (INCOMPLETE_TYPE_P): Redefined to work with incomplete
+ pointers, not TREE_LIST elements.
+ (struct parser_ctxt): Fixed comment indentations, added comments
+ and reordered some fields.
+ (java_check_methods): Function prototype removed.
+ * parse.y (java_push_parser_context): Use xmalloc.
+ (java_parser_context_restore_global): Pop extra pushed ctxp only
+ when there's nothing next.
+ (maybe_create_class_interface_decl): Fixed comment, add new
+ created class decl to all_class_list.
+ (method_header): Use GET_REAL_TYPE on argument's types.
+ (method_declarator): Use GET_REAL_TYPE, change type to the real
+ type in TREE_LIST dependency node. Build argument list with the
+ real type.
+ (create_jdep_list): Use xmalloc. Removed allocation error message.
+ (obtain_incomplete_type): Fixed leading comment. Broadened
+ incoming argument meaning.
+ (register_incomplete_type): Use xmalloc. Removed allocation error
+ message.
+ (safe_layout_class): Fixed leading comment.
+ (jdep_resolve_class): Reversed if statement condition and switch
+ if and else bodies.
+ (resolve_and_layout): Fixed leading comment. Broadened incoming
+ argument meaning.
+ (complete_class_report_errors): New local variable name, for
+ clarity. purify_type_name used for all error cases.
+ (java_get_real_method_name): Stricter check on constructors.
+ (java_check_regular_methods): Reverse methods list only if not
+ already laid out. Layout artificial constructor.
+ (java_check_methods): Deleted.
+ (source_start_java_method): Obtain incomplete type for patchable
+ method arguments.
+ (java_layout_classes): Fixed leading comment. Use
+ LAYOUT_SEEN_CLASS_METHODS, use a loop to check methods. Added else
+ statement to layout operation, reuse LAYOUT_SEEN_CLASS_METHODS
+ before returning. Fixed comments.
+ (java_expand_classes): Check for errors up front.
+ (patch_method_invocation): Class to search is resolved and laid
+ out.
+
+Tue Nov 24 12:57:13 1998 Per Bothner <bothner@cygnus.com>
+
+ * expr.c (java_lang_expand_expr): Add missing emit_queue.
+
+ * javaop.h (int8): Removed - not used.
+ (jbyte): Redefine portably with correct signedness.
+
+ * jcf-write.c (generate_bytecode_insns): Don't free sw_state.cases.
+
+ * jcf-write.c (generate_bytecode_insns): Fix typo
+ OPCODE_getstatic to OPCODE_getfield.
+
+ * java-tree.def (CASE_EXPR, DEFAULT_EXPR): Kind is 'x', not '1'.
+ * parse.y (java_complete_tree): For CASE_EXPR and DEFAULT_EXPR,
+ set TREE_SIDE_EFFECTS (otherwise expand_expr may skip them).
+
+Thu Nov 19 11:16:55 1998 Alexandre Petit-Bianco <apbianco@cygnus.com>
+
+ * jcf-parse.c (jcf_parse_source): Function returned type is
+ void. Added prototype.
+ (jcf_parse): Function returned type is void.
+ (yyparse): Remove call to fclose on the last parsed file.
+
+ * java-tree.h (jcf_parse): Changed jcf_parse prototype.
+
+Wed Nov 18 23:54:53 1998 Alexandre Petit-Bianco <apbianco@cygnus.com>
+
+ * class.c (unmangle_classname): Set QUALIFIED_P when appropriate.
+ (layout_class): Cope with methods featuring WFL in decl names.
+ * decl.c (unqualified_object_id_node): New global variable,
+ initialized.
+ (build_decl_no_layout): Removed.
+ * expr.c (build_primtype_type_ref): Handle Double.
+ (java_lang_expand_expr): Fixed indentations.
+ * java-tree.h (CLASS_METHOD_CHECKED_P): Flag deleted.
+ (flag_wall, flag_redundant, flag_not_overriding,
+ flag_static_local_jdk1_1, unqualified_object_id_node): Global
+ variable declarations.
+ (build_decl_no_layout): Removed prototype.
+ (java_get_real_method_name): Added prototype.
+ (IS_UNCHECKED_EXPRESSION_P): Renamed IS_UNCHECKED_EXCEPTION_P.
+ (java_parse_abort_on_error): Macro now just returns.
+ * jcf-parse.c (jcf_parse_source): Check fclose returned
+ value. Call emit_register_classes if java_report_errors returns
+ zero.
+ * lanc.c (flag_wall, flag_redundant, flag_not_overriding,
+ flag_static_local_jdk1_1): New integer flags.
+ (lang_decode_option): New flags set here.
+ * parse.h (GET_REAL_TYPE, GET_METHOD_NAME): New macros.
+ (OBSOLETE_MODIFIER_WARNING): Issue error message conditionally to
+ the flag_redundant variable.
+ (SET_TYPE_FOR_RESOLUTION): Consider Object being java.lang.Object
+ when parsing java.lang.Object class.
+ (BUILD_MONITOR_ENTER, BUILD_MONITOR_EXIT): Added terminal
+ NULL_TREE to build.
+ (resolve_qualified_expression_name): Fixed indentation.
+ (patch_array_ref): Changed prototype.
+ (not_initialized_as_it_should_p): Prototype removed.
+ (java_report_errors): Added function prototype.
+ * parse.y (formal_parameter:): Changed error message for not yet
+ supported final parameters.
+ (class_type_list:): Set both PURPOSE and VALUE of created
+ TREE_LIST to be class_type.
+ (primary_no_new_array:): Handle class literals on primitive types.
+ (parse_warning_context): Reinstalled correct force_error and
+ do_warning flags setups.
+ (java_report_errors): Changed prototype. Return java_error_count
+ value.
+ (variable_redefinition_error): Consider treating variable type as
+ a fake pointer.
+ (create_interface): Warn about redundant abstract modifier if
+ flag_redundant is set. Changed error message.
+ (lookup_field_wrapper): Save/restore globals before/after looking
+ up field.
+ (duplicate_declaration_error_p): Consider treating declaration
+ type as a fake pointer.
+ (register_fields): Extract real type from dependency node. Check
+ for duplicate field declaration after type adjustment. Use
+ DECL_INITIAL to store static final initialized values.
+ (method_header): Extract real function type from dependency node.
+ (check_abstract_method_header): Use GET_METHOD_NAME.
+ (obtain_incomplete_type): Layout fake pointer type.
+ (safe_layout_class): Don't try to check for methods before layout.
+ (java_complete_class): Don't check for correct throws clause
+ elements inheritance here.
+ (resolve_and_layout): Broadened name parameter meaning.
+ (reset_method_name): Use GET_METHOD_NAME.
+ (java_get_real_method_name): New function.
+ (java_check_regular_methods): Don't check methods in
+ java.lang.Object. Verify lineage of throws clause elements. Use
+ flag_no_overriding in warning report.
+ (check_throws_clauses): Don't check if class was from
+ bytecode. Use IS_UNCHECKED_EXCEPTION_P macro.
+ (java_check_methods): Don't set CLASS_METHOD_CHECKED_P flag.
+ (declare_local_variables): Use flag_static_local_jdk1_1 to report
+ warning on unsupported final local variables. Use build_decl
+ instead of build_decl_no_layout. Get real local variable type from
+ dependency node.
+ (source_start_java_method): Get real parameter type from
+ dependency node. Call build_decl instead of build_decl_no_layout.
+ (java_layout_classes): Reverse tree and layout type and class as
+ required. Mark class as loaded when done.
+ (resolve_field_access): Fixed indentation. Restricted condition
+ leading to static field access code generation. Set field_type
+ decl's TREE_TYPE if QUAL_DECL_TYPE not available.
+ (resolve_qualified_expression_name): Initialize type_found to
+ null. Handle static field resolved during qualification. Fixed
+ layout on non primitive field decl types.
+ (not_accessible_p): Fixed typo in comment.
+ (patch_method_invocation): Resolve and layout class to search from
+ type.
+ (lookup_method_invoke): Keep integer constant 0 as is. Resolve and
+ layout non primitive type, if necessary. Make method node only to
+ report errors.
+ (find_applicable_accessible_methods_list): Consider WFL'ed method
+ decl names. Fixed indentation.
+ (argument_types_convertible): Resolve and layout target type if
+ necessary.
+ (java_complete_tree): Fixed indentation problems. Rewrote
+ CALL_EXPR thrown exceptions check. Re-installed further processing
+ of the assignment in certain cases.
+ (patch_assignment): Call maybe_build_primttype_type_ref to perform
+ inlining on class literals.
+ (valid_builtin_assignconv_identity_widening_p): Cope with constant
+ 0 literal.
+ (valid_method_invocation_conversion_p): Likewise.
+ (patch_string): Temporary disable forbidden use of `this' in
+ explicit constructor invocations when doing string concatenation
+ within their scope.
+ (patch_unaryop): Added comment. Reinstalled code to disable
+ further check on assignment operation with cast expression RHS.
+ (patch_switch_statement): Fixed indentation.
+ (build_try_statement): Call build_decl instead of
+ build_decl_no_layout.
+ (patch_synchronized_statement): Likewise.
+ (patch_throw_statement): Use IS_UNCHECKED_EXCEPTION_P instead of
+ IS_UNCHECKED_EXPRESSION_P.
+ (check_thrown_exceptions_do): Changed leading comment. Resolve and
+ layout argument exception type.
+ (purge_unchecked_exceptions): Use IS_UNCHECKED_EXCEPTION_P instead
+ of IS_UNCHECKED_EXPRESSION_P.
+
+Wed Nov 18 14:21:48 1998 Anthony Green <green@cygnus.com>
+
+ * jcf-parse.c (yyparse): Open class file in binary mode.
+
+Sun Nov 15 17:14:17 1998 Per Bothner <bothner@cygnus.com>
+
+ * jvgenmain.c: Need to #include "gansidecl.h" (to get PROTO).
+
+ * jcf-write.c (perform_relocations): Move check out one loop.
+
+Sun Nov 15 15:09:56 1998 Anthony Green <green@hoser.cygnus.com>
+
+ * Make-lang.in: Fix reference to srcdir.
+ * jv-scan.c: Add missing xmalloc prototype.
+ * jvgenmain.c: Ditto.
+
+Sun Nov 15 14:36:29 1998 Per Bothner <bothner@cygnus.com>
+
+ * decl.c (error_mark_node), java-tree.h: New global.
+ * parse.y: Use empty_stmt_node instead of size_zero_node.
+ (build_if_else_statement): If missing else, use empty_stmt_node.
+
+ * parse.y (not_initialized_as_it_should_p): Removed, with its callers.
+ (java_complete_expand_method): Complain if return is missing.
+ (java_check_regular_methods): Comment out incorrect error check.
+ (not_accessible_p): Fix incorrect handling of protected methods.
+ (patch_method_invocation): Pass correct context to not_accessible_p.
+ (find_applicable_accessible_methods_list): Likewise.
+ (qualify_ambiguous_name): If ARRAY_REF, it's an expression name.
+ (java_complete_tree): For CASE_EXPR and DEFAULT_EXPR, set
+ TREE_TYPE (to void_type_node); otherwise expand_expr crashes.
+ (patch_if_else_statement): Fix setting of CAN_COMPLETE_NORMALLY.
+
+ * jcf-write.c (CHECK_OP, CHECK_PUT): Add some error checking.
+ (push_int_const): Remove reundant NOTE_PUSH.
+ (generate_bytecode_insns - case STRING_CST): Do NOTE_PUSH.
+ (- case SWITCH_EXPR): Fix code generation bug.
+ (- case PREDECREMENT_EXPR etc): Remove redundant NOTE_PUSH.
+ (generate_classfile): More robust for abstract methods.
+
+Sun Nov 15 13:52:39 1998 Anthony Green <green@cygnus.com>
+
+ * Makefile.in: jv-scan and jvgenmain all require libiberty.
+ * Make-lang.in: Ditto.
+
+ * jv-scan.c: Remove xmalloc and xstrdup definitions.
+ * jvgenmain: Ditto.
+
+Sun Nov 15 14:10:56 1998 Per Bothner <bothner@cygnus.com>
+
+ * jcf-parse.c (HANDLE_EXCEPTIONS_ATTRIBUTE): New macro.
+
+ * jcf-io.c (find_class): Simpler/cleaner structure fixes a bug.
+
+Sat Nov 14 17:19:18 1998 Per Bothner <bothner@cygnus.com>
+
+ Allow uses of interface types to verify. This is not really
+ type-safe, but it matches what Sun does, and is OK as long as
+ there are appropriate run-time checks.
+ * verify.c (merge_types): If merging two interface types,
+ just set the result to java.lang.Object.
+ * expr.c (pop_type): Any interface is matches by java.lang.Object.
+
+1998-11-13 Tom Tromey <tromey@cygnus.com>
+
+ * gjavah.c (main): Handle --output-class-directory argument.
+ * jvspec.c (lang_specific_driver): Translate `-d' into
+ -foutput-class-dir.
+ * jcf.h (jcf_write_base_directory): Declare.
+ * lang.c (lang_decode_option): Recognize -foutput-class-dir.
+ * lang-options.h: Mention -foutput-class-dir.
+ * jcf-write.c (jcf_write_base_directory): New global.
+ (make_class_file_name): Put generated .class file into `-d'
+ directory, or into source directory if -d not given. Function now
+ static.
+ (write_classfile): Free class file name. Handle case where class
+ file name is NULL.
+ (DIR_SEPARATOR): New macro.
+ Include <sys/stat.h>
+
+ * Makefile.in (prefix): New macro.
+
+Thu Nov 12 14:15:07 1998 Per Bothner <bothner@cygnus.com>
+
+ * parse.y (patch_invoke): Do less if flag_emit_class_files.
+ * expr.c (build_known_method_ref): Don't check flag_emit_class_files
+ here (done in patch_invoke instead).
+ (case_identity): Moved here from parse.y.
+
+ * java-tree.h (CAN_COMPLETE_NORMALLY): New macro.
+ * parse.y (java_complete_tree etc): Maybe set CAN_COMPLETE_NORMALLY.
+ * parse.y (java_complete_tree): Re-order COMPOUND_EXPR in BLOCK
+ so they can be efficiently scanned without recursion.
+ Error it ! CAN_COMPLETE_NORMALLY first part of COMPOUND_EXPR.
+ * expr.c (java_lang_expand_expr): Expand statements of COMPOUND_EXPR
+ in BLOCK iteratively, rather than recursively.
+
+ * parse.y (do_unary_numeric_promotion): New function.
+ (patch_unaryop, patch_binop, patch_array_ref): Use it.
+
+ * parse.y (patch_newarray): Various fixes.
+
+ Re-do handling of switch statements (for proper block scoping).
+ * parse.y: Add just a single block for the enture switch block,
+ but don't create any "case blocks".
+ (group_of_labels): Rmeoved unneeded non-terminal.
+ CASE_EXPR and DEFAULT_EXPR are added to current block.
+ * expr.c (java_lang_expand_expr): Inline SWITCH_EXPR here.
+ Now also need to handle CASE_EXPR and DEFAULT_EXPR.
+ * java-tree.h (SWITCH_HAS_DEFAULT): New macro.
+ * parse.y (wfl_operator, print_int_node): Make non-static.
+ (java_complete_tree): CASE_EXPR and DEFAULT_EXPR are now processed
+ as part of recursive scan of block.
+ (java_expand_switch ): Removed - inlined into java_lang_expand_expr.
+ (patch_switch_statement): Most tests move dinto java_complete_tree.
+
+ * parse.y: Make various production be non-typed (void).
+ * parse.y (parse_error): Merged into issue_warning_error_from_context.
+ * parse.y (add_stmt_to_compound): Don't create/change extra node.
+ (patch_method_invocation_stmt): Renamed to patch_method_invocation.
+
+ * jcf-write.c (struct jcf_handler): New type.
+ (struct jcf_switch_state): New type.
+ (SWITCH_ALIGN_RELOC, BLOCK_START_RELOC): New relocation kinds.
+ (alloc_handler, emit_unop, emit_reloc): New functions.
+ (adjust_typed_op): Add extra parameter ("max type" offset).
+ (emit_switch_reloc, emit_case-reloc): New function.
+ (generate_bytecode_conditional): Handle REAL_TYPE comparisons.
+ (generate_bytecode_insns): Support REAL_CST, switch statements,
+ exception handling, method calls, object/array creation, and more.
+
+ * class.c: Remove some unused variables.
+ * constants.c (find_string_constant): New function.
+ (count_constant_pool_bytes): Fix to correctly handle wide constants.
+ * decl.c (complete_start_java_method): Don't _Jv_InitClass
+ if flag_emit_class_files.
+
+1998-11-12 Tom Tromey <tromey@cygnus.com>
+
+ * jcf-io.c (find_class): Added explanatory comment.
+
+ * jcf-path.c (add_entry): Look for `.zip' at end of filename. Add
+ trailing slash to `.zip' entries.
+
+ * jvspec.c (lang_specific_driver): Correctly handle case where
+ GC_NAME not defined.
+
+1998-11-11 Tom Tromey <tromey@cygnus.com>
+
+ * jvspec.c (GC_NAME): New define.
+ (lang_specific_driver): Use GC_NAME. Add GC_NAME to command line
+ if required.
+ * Make-lang.in (jvspec.o): Define WITH_GC_<name>.
+
+Wed Nov 11 19:08:52 1998 Per Bothner <bothner@cygnus.com>
+
+ * jcf-dump.c (TABLE_SWITCH): Fix typos.
+
+1998-11-11 Tom Tromey <tromey@cygnus.com>
+
+ * jcf-dump.c (main): Correctly recognize `--'-style long options.
+
+Tue Nov 10 12:34:03 1998 Alexandre Petit-Bianco <apbianco@cygnus.com>
+
+ * class.c (is_compiled_class): Call safe_layout_class for class
+ compiled from source.
+ * conver.h (convert_to_integer, convert_to_real,
+ convert_to_pointer): Added prototypes.
+ * decl.c (init_decl_processing): Non longer push the decls of
+ `methodtable', `constants', `Class', `Field', `dispatchTable'
+ `jexception' and `Method'.
+ * expr.c (build_invokeinterface): New function.
+ (expand_invoke): static variable CLASS_IDENT now in
+ build_invokeinterface. Use build_invokeinterface.
+ (expand_java_field_op): Moved code to inline
+ java.lang.PRIMTYPE.TYPE into a function.
+ (build_primtype_type_ref): New function.
+ * java-tree.def (INSTANCEOF_EXPR): New tree code.
+ * java-tree.h (CLASS_METHOD_CHECKED_P, METHOD_DEPRECATED,
+ FIELD_DEPRECATED, CLASS_DEPRECATED): New flag macros.
+ (DECL_CONSTRUCTOR_P): Fixed typo in comment.
+ (DECL_LOCAL_STATIC_VALUE): New macro.
+ (build_invokeinterface, build_primtype_type_ref): New function
+ prototypes.
+ (java_parse_abort_on_error): Macro rewritten.
+ * jcf-parse.c (current_method): Add comment to declaration.
+ (parse_zip_file_entries, process_zip_dir, void parse_source_file):
+ Function prototypes fixed.
+ (jcf_parse_source): push/pop parser context. save/restore global.
+ (parse_source_file): Fixed leading comment. Now take a
+ IDENTIFIER_NODE as an argument. Doesn't check methods, layout
+ classes and pop the parser context anymore.
+ (yyparse): Push parser context, save globals, parse the source
+ file, restore globals and pop the parser context when processing a
+ source file.
+ * jcf.h (VERBOSE_SKELETON): Replaces SOURCE_FRONTEND_DEBUG define.
+ * lex.c (java_parse_doc_section): New function.
+ (java_lex): Call java_parse_doc_section when appropriate. Build an
+ operator around INSTANCEOF_TK.
+ * lex.h (java_lineterminator, java_sprint_unicode,
+ java_unicode_2_utf8, java_lex_error, java_store_unicode):
+ Prototypes rewritten.
+ (java_parse_escape_sequence, java_letter_or_digit_p,
+ java_parse_doc_section, java_parse_end_comment, java_get_unicode,
+ java_read_unicode, java_store_unicode, java_read_char,
+ java_allocate_new_line, java_unget_unicode, java_sneak_unicode):
+ Added function prototypes.
+ * parse.h (VERBOSE_SKELETON): Replaces SOURCE_FRONTEND_DEBUG
+ define.
+ (JNULLP_TYPE_P, CHECK_METHODS, CHECK_DEPRECATED, REGISTER_IMPORT):
+ New macros
+ (struct parser_ctxt): New fields: deprecated,
+ current_parsed_class_un, gclass_list.
+ (fix_method_argument_names, issue_warning_error_from_context,
+ resolve_package, lookup_package_type): New function prototypes.
+ (resolve_expression_name): Fixed function prototype.
+ (find_applicable_accessible_methods_list): Fixed indentation, added
+ extra argument in prototype.
+ (check_final_assignment, build_null_of_type, check_deprecation,
+ check_method_redefinition, reset_method_name,
+ java_check_regular_methods, java_check_abstract_methods,
+ maybe_build_primttype_type_ref): New function prototype.
+ * parse.y (conver.h): Include.
+ (INSTANCEOF_TK): Tagged <operator>.
+ (single_type_import_declaration): Use REGISTER_IMPORT macro.
+ (relational_expression:): Build binop for instanceof.
+ (java_push_parser_context): Remember ctxp->gclass_list across
+ contexts.
+ (java_pop_parser_context): Simply return if no context
+ exists. Remember gclass_list across contexts.
+ (issue_warning_error_from_context): New function.
+ (parse_error_context): Don't setup ctxp->elc here. Call
+ issue_warning_error_from_context instead.
+ (parse_warning_context): Likewise.
+ (maybe_create_class_interface_decl): Removed DECL_ARTIFICIAL
+ setup. Link new class/interface to ctxp->gclass_list.
+ (add_superinterfaces): Register interface as incomplete if not
+ loaded.
+ (create_class): Remember class unqualified name in
+ ctxp->current_parsed_class_un. Check class deprecation.
+ (register_fields): Check field deprecation. Remember static final
+ field value in DECL_LOCAL_STATIC_VALUE. Changed comment in part
+ processing INIT.
+ (method_header): New local variable ORIG_ARG. Use unqualified
+ current class name for check on constructor errors. Promote return
+ type if of record type. Argument list fix moved in
+ fix_method_argument_names, called here. Check method deprecation.
+ (fix_method_argument_names): New function.
+ (method_declarator): Promote record typed arguments.
+ (safe_layout_class): Check class methods before layout.
+ (java_complete_class): Compute field layout when patched.
+ (do_resolve_class): Try to load class after having it renamed
+ after the package name.
+ (get_printable_method_name): Use DECL_CONTEXT.
+ (reset_method_name): New function.
+ (check_method_redefinition): Use reset_method_name.
+ (java_check_regular_methods): New local variable
+ SAVED_FOUND_WFL. Temporarily reinstall overriding/hiding method
+ names for error report. Check for compile-time error when method
+ found has default (package) access.
+ (java_check_abstract_methods): Now takes an interface DECL node as
+ an argument. Also reinstall real name on unchecked
+ overriding/hiding methods for error report.
+ (java_check_methods): Fixed leading comment. Get classes to verify
+ from ctxp->gclass_list. Use CHECK_METHODS macro and set
+ CLASS_METHOD_CHECKED_P on class verification.
+ (lookup_java_method2): Get real method name if necessary.
+ (find_in_imports): Don't check package class access here.
+ (resolve_package, lookup_package_type): New functions.
+ (java_layout_classes): Fixed leading comment. Take classes to be
+ laid out from ctxp->gclass_list.
+ (java_complete_expand_methods): Don't expand native and abstract
+ methods.
+ (java_expand_classes): New function.
+ (resolve_expression_name): Use additional argument ORIG. Retrieve
+ values of static final field of primitive types.
+ (resolve_field_access): Handles static final field of promotive
+ type.
+ (resolve_qualified_expression_name): Handle STRING_CST as
+ primaries and package name resolution. Check deprecation on found
+ decls. Set where_found and type_found on non static field resolved
+ during qualification. Layout non primitive field decl types.
+ (check_deprecation): New function.
+ (maybe_access_field): Simplified.
+ (patch_method_invocation_stmt): Local variable CLASS_TYPE
+ removed. Reverse method's argument when primary is a type. Don't
+ use CLASS_TYPE to report problems, use IDENTIFIER_WFL
+ instead. Include abstract class in the list of class searchable
+ for constructors. Use DECL_CONTEXT of found method for access
+ checks. Check method deprecation.
+ (patch_invoke): Pay extra care to NEW_CLASS_EXPR type call when
+ converting arguments. Handle INVOKE_INTERFACE.
+ (lookup_method_invoke): Search constructor using existing
+ infrastructure (don't rely on lookup_java_constructor anymore).
+ (find_applicable_accessible_methods_list): Extra argument flag
+ LC. Now include constructor in the search.
+ (qualify_ambiguous_name): Conditional expression are primaries.
+ (not_initialized_as_it_should_p): static final are always
+ initialized.
+ (java_complete_tree): Pass extra NULL argument to
+ resolve_expression_name. Stricter test to carry on patching
+ assignments. New case for INSTANCEOF_EXPR.
+ (complete_function_arguments): Inline PRIMTYPE.TYPE read access.
+ (check_final_assignment, maybe_build_primttype_type_ref): New
+ functions.
+ (patch_assignment): Detect resolved static finals and carry normal
+ assignment error check on them. Inline PRIMTYPE.TYPE read access.
+ (try_builtin_assignconv): Access constant 0 on all primitive
+ types.
+ (valid_builtin_assignconv_identity_widening_p): Accept identical
+ types. Accept all promoted type on int type.
+ (valid_ref_assignconv_cast_p): Accept a null pointer to be
+ assigned to a reference.
+ (valid_method_invocation_conversion_p): Accept to check null
+ pointers.
+ (build_binop): Merge declaration and initialization of local
+ variable BINOP.
+ (patch_binop): New case for INSTANCEOF_EXPR. NE_EXPR to accept all
+ numeric types. Improved validity test for qualify operators on
+ references.
+ (patch_unaryop): Broadened rejection test for PREDECREMENT_EXPR
+ and PREINCREMENT_EXPR. Also detect resolved static finals of a
+ primitive type and issue the appropriate error message.
+ (resolve_type_during_patch): Mark class loaded when resolved.
+ (patch_cast): Allow null to be cased to reference types.
+ (build_null_of_type): New function.
+ (patch_array_ref): Handle array on references correctly.
+ (patch_return): Removed unused local variable MODIFY. Force
+ boolean to be returned as integers. Allows null to be returned by
+ a function returning a reference.
+ * typeck.c (convert_to_integer, convert_to_real,
+ convert_to_pointer): Prototypes moved to convert.h
+ (lookup_argument_method): Use method real name, if necessary.
+
+1998-10-30 Tom Tromey <tromey@cygnus.com>
+
+ * class.c (build_class_ref): Changed name of primitive classes to
+ start with `_Jv_'.
+
+ * class.c (make_class_data): Renamed fields: nmethods to
+ method_count, method_count to dtable_method_count. Always set
+ `state' field to 0.
+ * decl.c (init_decl_processing): Likewise.
+
+Wed Oct 28 08:03:31 1998 Alexandre Petit-Bianco <apbianco@cygnus.com>
+
+ * class.c (layout_class): Don't mangle <finit>, produce
+ __finit<class> instead. Don't verify artificial methods.
+ * decl.c (finit_identifier_node): New declared global.
+ (init_decl_processing): finit_identifier_node initialized.
+ * java-tree.def (CONDITIONAL_EXPR): New Java tree code.
+ * java-tree.h (finit_identifier_node): Declared as extern.
+ (struct lang_decl): New field called_constructor.
+ (DECL_CONSTRUCTOR_CALLS): Access macro to called_constructor.
+ (CLASS_HAS_FINIT_P): New macro.
+ (CALL_CONSTRUCTOR_P): Leading comment changed. Macro now checks
+ explicit constructor invocation.
+ (CALL_EXPLICIT_CONSTRUCTOR_P, CALL_THIS_CONSTRUCTOR_P,
+ CALL_SUPER_CONSTRUCTOR_P): New macros.
+ (write_classfile): Added prototype.
+ * jcf-parse.c (jcf_parse_source): Parse and remember for
+ generation if the file was seen on the command line.
+ (parse_source_file): Don't write the class file here.
+ (yyparse): Loop on files rewritten. Set current_jcf.
+ (parse_zip_file_entries): Parse class file only if it was found.
+ * lang.c (init_parse): Don't open command line provided filename
+ here.
+ (lang_parse): Don't set main_jcf anymore.
+ * parse.h (ABSTRAC_CHECK): Capitalized arguments.
+ (JCONSTRUCTOR_CHECK): New macro.
+ (JBSC_TYPE_P): New macro.
+ (IN_TRY_BLOCK_P, EXCEPTIONS_P): Fixed leading comment.
+ (COMPLETE_CHECK_OP_2): New macro.
+ (struct parse_ctxt): New field explicit_constructor_p.
+ (check_class_interface_creation): Fixed prototype indentation.
+ (patch_method_invocation_stmt): Prototype reflects added argument.
+ (patch_invoke): Likewise.
+ (complete_method_declaration, build_super_invocation,
+ verify_constructor_circularity,
+ build_this_super_qualified_invocation, get_printable_method_name,
+ patch_conditional_expr, maybe_generate_finit, fix_constructors,
+ verify_constructor_super, create_artificial_method,
+ start_artificial_method_body, end_artificial_method_body,
+ generate_field_initialization_code): New function prototypes.
+ * parse.y: Fixed leading comment
+ (constructor_header:, constructor_body:, block_end:): Rules tagged
+ <node>.
+ (type_declaration:): Call maybe_generate_finit.
+ (method_declaration:): Action for method_body: placed in new
+ function complete_method_declaration, called here.
+ (constructor_declaration:): Defined actions. Removed leading
+ FIXME.
+ (constructor_header:): New rule with action.
+ (constructor_body:): Rule rewritten using block_begin: and
+ block_end:. Defined actions.
+ (constructor_declarator:, explicit_constructor_invocation:):
+ Defined actions.
+ (block:): Use new rules block_begin: block_end:.
+ (block_begin:, block_end:): New rules and actions.
+ (block_statements:): Fixed error message for explicit
+ constructors.
+ (method_invocation:): Call build_this_super_qualified_invocation
+ if primary is `this' or `super' was seen.
+ (conditional_expression:): Action defined.
+ (extra_ctxp_pushed_p): New static global flag.
+ (java_parser_context_save_global): Create parser context if
+ necessary. Use extra_ctxp_pushed_p to remember it.
+ (java_parser_context_restore_global): Pop extra parser context if
+ one exists.
+ (build_array_from_name): Array on primitive types are marked
+ loaded.
+ (register_fields): Restore new name in field initializer
+ expression if type was altered. Non static fields initialized upon
+ declaration marked initialized.
+ (maybe_generate_finit): New function.
+ (maybe_generate_clinit): Use create_artificial_method,
+ start_artificial_method_body, end_artificial_method_body. Generate
+ debug info for enclosed initialization statements.
+ (method_header): Fixed leading comment. Check constructor
+ flags. Detect constructor declarations and set DECL_CONSTRUCTOR_P
+ accordingly.
+ (complete_method_declaration, constructor_circularity_msg,
+ verify_constructor_circularity): New functions.
+ (get_printable_method_name): New function.
+ (check_method_redefinition): Don't rename <finit> methods. Fix
+ declared constructor names. Error message for
+ constructors modified.
+ (java_check_regular_methods): Local variable seen_constructor
+ renamed saw_constructor. Skip verification on constructors. Create
+ default constructor with create_artificial_method.
+ (java_check_methods): Removed unnecessary empty line.
+ (create_artificial_method, start_artificial_method_body,
+ end_artificial_method_body): New functions.
+ (java_layout_classes): Changed leading comment. Reverse fields
+ list if necessary. Always layout java.lang.Object if being
+ defined.
+ (java_complete_expand_methods): Verify constructor circularity.
+ (java_complete_expand_method): Call fix_constructor on
+ constructors. Local variable no_ac_found removed. Restore
+ bindings if method body expansion failed.
+ (fix_constructors, verify_constructor_super,
+ generate_field_initialization_code): New function.
+ (java_expand_classes): Fixed leading comment. Write class file
+ here.
+ (resolve_expression_name): Check for illegal instance variable
+ usage within the argument scope of an explicit constructor
+ invocation.
+ (resolve_qualified_expression_name): Pass extra from_super flag
+ when invoking patch_method_invocation_stmt. New case for
+ conditional expression when used as a primary. Check for error
+ when acquiring super.
+ (patch_method_invocation_stmt): Added extra argument super. New
+ local variable is_static_flag. Set class_to_search according to
+ the nature of the constructor invocation. Don't add `this'
+ argument when expanding NEW_CLASS_EXPR. Check for illegal method
+ invocation within the argument scope of explicit constructor
+ invocation. Set is_static according to is_static_flag. Provide
+ extra `super' argument to patch_invoke invocation.
+ (patch_invoke): New argument from_super. Loop on arguments
+ indentation fixed. Pass from_super to invocation_mode. New switch
+ case INVOKE_SUPER. Fixed error message in switch default case.
+ Don't use CALL_CONSTRUCTOR_P but rather a test on the tree node
+ value.
+ (invocation_mode): Return INVOKE_SUPER mode when appropriate.
+ (lookup_method_invoke): Fixed prototypes in candidates list. Error
+ message takes constructors into account.
+ (find_applicable_accessible_methods_list): Fixed indentation.
+ (qualify_ambiguous_name): Take explicit constructor invocation
+ into account. Deal with a conditional expression as a primary to
+ a method call.
+ (java_complete_tree): Added local wfl_op3. New CONDITIONAL_EXPR
+ case. Added extra argument to patch_method_invocation_stmt.
+ Register calls made to explicit constructor `this'. Don't call
+ save_expr in ARRAY_REF case when emitting class files. Check for
+ illegal use of this when expanding explicit constructor invocation
+ arguments.
+ (complete_function_arguments): Set and reset parser context
+ explicit_constructor_p field value when appropriate.
+ (build_super_invocation, build_this_super_qualified_invocation):
+ New functions.
+ (patch_assignment): Fixed typo.
+ (patch_unaryop): Check on final fields occurs only when a decl
+ exits.
+ (patch_return): Take constructors into account.
+ (patch_conditional_expr): New function.
+ * typeck.c (build_java_signature): Removed unnecessary empty line.
+
+Wed Oct 28 00:46:15 1998 Jeffrey A Law (law@cygnus.com)
+
+ * Makefile.in (jcf-dump, gcjh): Link in $(LIBS) too.
+
+1998-10-28 Tom Tromey <tromey@cygnus.com>
+
+ * decl.c (init_decl_processing): Renamed fields.
+ * class.c (make_class_data): Renamed bfsize, nfields, nsfields,
+ interface_len, msize fields.
+
+ * class.c (make_class_data): Removed subclass_head and
+ subclass_next fields.
+ * decl.c (init_decl_processing): Removed subclass_head and
+ subclass_next fields.
+
+Wed Oct 28 00:46:15 1998 Jeffrey A Law (law@cygnus.com)
+
+ * jcf-write.c (emit_load_or_store): Avoid implicit int arguments.
+ * mangle.c (emit_unicode_mangled_name): Similarly.
+
+Mon Oct 26 12:17:23 1998 Nick Clifton <nickc@cygnus.com>
+
+ * jcf-parse.c (get_constant): Place braces around code to compute
+ 'd' when REAL_ARITHMETIC is not defined.
+
+Sun Oct 25 14:58:05 1998 H.J. Lu (hjl@gnu.org)
+
+ * Make-lang.in (jv-scan$(exeext)): Add stamp-objlist to
+ dependency.
+
+1998-10-23 Tom Tromey <tromey@cygnus.com>
+
+ * lang-specs.h: `.zip' files are input to jc1.
+
+Thu Oct 22 23:01:54 1998 Per Bothner <bothner@cygnus.com>
+
+ * jvspecs.c: Add (but don't enable) support for combining multiple
+ .class and .java input filenames to a single jc1 invocation.
+ Add support for -C flag (copile to .class files).
+ Translate -classpath and -CLASSPATH arguments.
+ * lang-specs.h: Don't set %2 spec.
+
+1998-10-22 Tom Tromey <tromey@cygnus.com>
+
+ * jcf-path.c (add_entry): Don't add trailing separator if entry is
+ a .zip file.
+ (add_path): Don't add trailing separator to non-empty path
+ elements.
+
+ * lang.c (lang_decode_option): Check for -fclasspath and
+ -fCLASSPATH before examining other `-f' options.
+
+ * java-tree.h (finalize_identifier_node): Don't declare.
+ * class.c (make_class_data): Don't push "final" field.
+ * decl.c (init_decl_processing): Don't push "final" field.
+ (finalize_identifier_node): Removed.
+ (init_decl_processing): Don't set finalize_identifier_node.
+
+ * config-lang.in (stagestuff): Added jcf-dump and jv-scan.
+
+Sun Oct 11 10:31:52 1998 Anthony Green <green@cygnus.com>
+
+ * Make-lang.in (java): Depend on jcf-dump and jv-scan.
+ (JV_SCAN_SOURCES): New macro.
+ (JCF_DUMP_SOURCES): Likewise.
+ (jcf-dump$(exeext)): New target.
+ (jv-scan$(exeext)): New target.
+
+1998-10-22 Tom Tromey <tromey@cygnus.com>
+
+ * Makefile.in (LEX): Removed.
+ (LEXFLAGS): Likewise.
+ (SET_BISON): New macro.
+ (BISON): Removed.
+ ($(PARSE_C)): Use SET_BISON. Run bison from srcdir to avoid
+ spurious diffs in parse.c.
+ ($(PARSE_SCAN_C)): Likewise.
+ (PARSE_DIR): New macro.
+ (PARSE_C): Use it.
+ (PARSE_SCAN_C): Likewise.
+ (PARSE_RELDIR): New macro.
+
+ * jcf-io.c (saw_java_source): Define here, not in jcf-parse.c.
+
+ * jcf-io.c (find_class): Use saw_java_source to determine when to
+ look for `.java' file.
+ * jcf-parse.c (saw_java_source): New global.
+ (yyparse): Set it if `.java' file seen.
+
+ * Make-lang.in (JAVA_SRCS): Added jcf-path.c.
+ (GCJH_SOURCES): Likewise.
+ * Makefile.in (datadir): New macro.
+ (libjava_zip): Likewise.
+ (JAVA_OBJS): Added jcf-path.o.
+ (../jcf-dump$(exeext)): Depend on and link with jcf-depend.o.
+ (../gcjh$(exeext)): Likewise.
+ (jcf-path.o): New target.
+ * java-tree.h (fix_classpath): Removed decl.
+ * jcf-parse.c (fix_classpath): Removed.
+ (load_class): Don't call fix_classpath.
+ * parse.y (read_import_dir): Don't call fix_classpath.
+ * lex.h: Don't mention classpath.
+ * lex.c (java_init_lex): Don't initialize classpath.
+ * jcf-io.c (classpath): Removed global.
+ (find_class): Use jcf_path iteration functions. Correctly search
+ class path for .java file.
+ (open_in_zip): New argument `is_system'.
+ * jcf-dump.c (main): Call jcf_path_init. Recognize all new
+ classpath-related options.
+ * lang.c (lang_decode_option): Handle -fclasspath, -fCLASSPATH,
+ and -I.
+ (lang_init): Call jcf_path_init.
+ * lang-options.h: Mention -I, -fclasspath, and -fCLASSPATH.
+ * lang-specs.h: Handle -I. Minor cleanup to -M options.
+ Correctly put braces around second string in each entry.
+ * gjavah.c (main): Call jcf_path_init. Recognize all the new
+ classpath-related options.
+ (help): Updated for new options.
+ * jcf.h: Declare functions from jcf-path.c. Don't mention
+ `classpath' global.
+ * jcf-path.c: New file.
+
+ * jcf-depend.c: Include jcf.h.
+
+ * jcf-write.c (localvar_alloc): Returns `void'.
+ (localvar_free): Removed unused variable.
+
+ * lang.c (OBJECT_SUFFIX): Define if not already defined.
+ (init_parse): Use OBJECT_SUFFIX, not ".o".
+
+Wed Oct 21 07:54:11 1998 Alexandre Petit-Bianco <apbianco@cygnus.com>
+
+ * class.c (emit_register_classes): Renamed from
+ emit_register_class.
+ * java-tree.h (emit_register_classes): Prototype renamed from
+ emit_register_class.
+ * jcf-parse.c (yyparse): Call emit_register_classes once before
+ returning.
+ * parse.y (java_expand_classes): No longer register classes.
+
+Tue Oct 20 09:15:38 1998 Alexandre Petit-Bianco <apbianco@cygnus.com>
+
+ * class.c (is_compiled_class): New local variable
+ seen_in_zip. Identify classes found in currently compiled source
+ file(s).
+ * decl.c (complete_start_java_method): Fixed typo.
+ * java-tree.h (CLASS_FROM_CURRENTLY_COMPILED_SOURCE_P,
+ HAS_BEEN_ALREADY_PARSED_P, IS_A_COMMAND_LINE_FILENAME_P): New macros.
+ (CLASS_P): Moved around.
+ (java_parse_abort_on_error): Macro moved from jcf-parse.c
+ * jcf-parse.c (java_parse_abort_on_error): Macro moved to
+ java-parse.h
+ (jcf_parse_source): Changed leading comment. Removed unnecessary
+ fclose and CLASS_FROM_SOURCE_P marking.
+ (parse_source_file): New local variables remember_for_generation
+ and filename. Mark parsed file name identifier node. Removed block
+ executed when parse_only was null. Set remember_for_generation.
+ Use it as an argument to java_pop_parser_context.
+ (yyparse): New local variables several_files, list, next node and
+ current_file_list. Split ampersand separated file names into
+ current_file_list. Iterate through the list and parse accordingly.
+ * parse.h (java_pop_parser_context): New function prototype.
+ * parse.y (ctxp_for_generation): New static global variable.
+ (java_pop_parser_context): New argument generate. Link popped ctxp
+ to ctxp_for_generation list accordingly.
+ (java_complete_expand_methods): Fixed indentation.
+ (java_expand_classes): New function.
+
+Sat Oct 17 11:25:21 1998 Per Bothner <bothner@cygnus.com>
+
+ * Makefile.in: Link with libiberty.a instead of memmove.o.
+
+Fri Oct 16 10:59:01 1998 Alexandre Petit-Bianco <apbianco@cygnus.com>
+
+ * lex.c (setjmp.h): No longer included.
+ * lex.h (setjmp.h): Included.
+ * parse.h (SET_TYPE_FOR_RESOLUTION): New macro.
+ (duplicate_declaration_error_p): Renamed from
+ duplicate_declaration_error.
+ (build_array_from_name): New function prototype.
+ * parse.y (setjmp.h): No longer included.
+ (variable_declarator_id): Define action.
+ (build_array_from_name): New function.
+ (duplicate_declaration_error_p): Renamed from
+ duplicate_declaration_error. Fixed leading comment.
+ (register_fields): Main `for' loop reorganized. Uses
+ SET_TYPE_FOR_RESOLUTION and build_array_from_name.
+ (method_declarator): Uses SET_TYPE_FOR_RESOLUTION and call
+ build_array_from_name.
+ (resolve_class): Set CLASS_LOADED_P on newly build array dimension
+ types.
+ (read_import_dir): Don't try to skip `.' and `..'.
+ (declare_local_variables): Uses SET_TYPE_FOR_RESOLUTION and
+ build_array_from_name. Main `for' loop reorganized.
+ (resolve_qualified_expression_name): When building access to a
+ field, use the type where the field was found, not its own type.
+ (maybe_access_field): Use field DECL_CONTEXT if the type where the
+ field was found is null.
+ (qualify_ambiguous_name): Sweep through all successive array
+ dimensions.
+
+Wed Oct 14 18:21:29 1998 Alexandre Petit-Bianco <apbianco@cygnus.com>
+
+ * java-tree.h (pop_labeled_block, lang_printable_name,
+ maybe_add_interface, set_super_info, get_access_flags_from_decl,
+ interface_of_p, inherits_from_p, fix_classpath,
+ complete_start_java_method, emit_handlers, init_outgoing_cpool,
+ make_class_data, register_class, alloc_name_constant): New
+ function prototypes.
+ * lang.c (lang_decode_option): Set argc argument unused. Fixed
+ indentation. Added cast to remove warning.
+ (lang_printable_name): Set v argument unused.
+ (lang_print_error): Added argument to lang_printable_name call.
+ (java_dummy_print, print_lang_decl, print_lang_type,
+ print_lang_identifier, lang_print_xnode): All argument marked
+ unused.
+ * lex.c (java_unget_unicode): Removed unnecessary argument.
+ (java_allocate_new_line): Unused local variable is gone.
+ (java_read_char): Added parenthesis in expressions to remove
+ warnings. Added final return statement.
+ (java_read_unicode): Added parenthesis in expression to remove
+ warning.
+ (java_parse_end_comment): Fixed java_unget_unicode invocation.
+ (java_parse_escape_sequence): Likewise.
+ (java_lex): Unused local variables are gone. Fixed
+ java_unget_unicode invocation.
+ * lex.h (set_float_handler): Prototype added when JC1_LITE not
+ defined.
+ * parse.h (ERROR_CANT_CONVERT_TO_BOOLEAN): Fixed
+ lang_printable_name invocation in macro.
+ (ERROR_CANT_CONVERT_TO_NUMERIC, ERROR_CAST_NEEDED_TO_INTEGRAL):
+ Likewise.
+ (duplicate_declaration_error): Suppressed unused argument in
+ prototype.
+ (identical_subpath_p): Function declaration is gone.
+ (patch_invoke): Suppressed unused argument in prototype.
+ (patch_cast, build_labeled_block, check_thrown_exceptions):
+ Likewise.
+ * parse.y (setjmp.h): Included
+ (toplev.h): Likewise.
+ (field_declaration:): Suppressed unused local
+ (label_decl:): Fixed build_labeled_block invocation.
+ (java_pop_parser_context): Put extra parenthesis around assignment
+ in if.
+ (yyerror): Suppressed unused local variables.
+ (variable_redefinition_error): Fixed lang_printable_name
+ invocation.
+ (create_interface): Suppressed unused local variables.
+ (create_class): Likewise.
+ (duplicate_declaration_error): Suppressed unused argument. Fixed
+ lang_printable_name invocation.
+ (register_fields): Suppressed unused local variable. Fixed
+ duplicate_declaration_error invocation.
+ (method_header): Suppressed unused local variable.
+ (method_declarator, parser_check_super): Likewise.
+ (java_complete_class): Suppressed unused local variable. Fixed
+ fatal error message.
+ (complete_class_report_errors): Added default: in switch.
+ (java_check_regular_methods): Fixed lang_printable_name
+ invocations.
+ (check_throws_clauses): Likewise.
+ (java_check_abstract_methods): Suppressed unused local
+ variable. Fixed lang_printable_name invocation.
+ (read_import_entry): Added supplemental return statement.
+ (read_import_dir): Suppressed unused local variables.
+ (check_pkg_class_access, declare_local_variables): Likewise.
+ (source_start_java_method): Suppressed unused extern variable
+ declarations
+ (expand_start_java_method): Suppressed unused extern and local
+ variable declarations.
+ (java_complete_expand_methods): Likewise.
+ (java_complete_expand_method): Suppressed unused local variables.
+ (make_qualified_name): Likewise.
+ (resolve_qualified_expression_name): Added default: in
+ switch. Fixed lang_printable_name invocation.
+ (class_instance_creation_expression): Added parenthesis around
+ expressions.
+ (patch_method_invocation_stmt): Fixed lang_printable_name and
+ patch_invoke invocations.
+ (check_for_static_method_reference): Fixed lang_printable_name
+ invocation.
+ (patch_invoke): Suppressed unused arguments and local variables.
+ (lookup_method_invoke): Suppressed unused local variables.
+ (qualify_ambiguous_name): Added default: in switch.
+ (identical_subpath_p): Function removed.
+ (patch_assignment): Suppressed unused local variables. Suppressed
+ unnecessary if statement. Fixed lang_printable_name invocations.
+ (try_builtin_assignconv): Fixed lang_printable_name invocations.
+ (valid_ref_assignconv_cast_p): Parenthesis around
+ expression. Suppressed unused local variables.
+ (build_binop): Suppressed unused local variables. fixed
+ lang_printable_name invocations.
+ (string_constant_concatenation): Suppressed unused local
+ variables.
+ (patch_unaryop): Fixed lang_printable_name invocation.
+ (patch_cast): Suppressed unnecessary argument. Fixed
+ lang_printable_name invocation.
+ (patch_array_ref): Fixed lang_printable_name invocation.
+ (patch_newarray, patch_return, patch_if_else_statement): Likewise.
+ (build_labeled_block): Suppressed unused argument.
+ (generate_labeled_block): Fixed build_labeled_block invocation.
+ (build_loop_body): Suppressed unused local variables.
+ (patch_loop_statement): Likewise.
+ (patch_exit): Fixed lang_printable_name invocation.
+ (patch_switch_statement): Likewise.
+ (case_identity): First argument marked unused.
+ (patch_try_statement): Fixed lang_printable_name invocations.
+ (patch_synchronized_statement, patch_throw_statement): Likewise.
+ (check_thrown_exceptions): Fixed check_thrown_exceptions and
+ lang_printable_name invocations.
+ (check_thrown_exceptions_do): Suppressed unused argument.
+
+1998-10-14 Tom Tromey <tromey@cygnus.com>
+
+ * jcf-write.c (write_classfile): Add output class file as target.
+ * lang-options.h: Added -MD, -MMD, -M, and -MM.
+ * jcf.h: Added declarations for dependency-tracking functions.
+ * lang-specs.h: Handle -M, -MM, MD, and -MMD.
+ * lang.c (lang_decode_option): Recognize -MD and -MMD.
+ (finish_parse): Call jcf_dependency_write.
+ (dependency_tracking): New global.
+ (DEPEND_SET_FILE): New define.
+ (DEPEND_ENABLE): New define.
+ (init_parse): Enable dependency tracking if required.
+ Include "flags.h".
+ * Makefile.in (JAVA_OBJS): Added jcf-depend.o.
+ (../jcf-dump$(exeext)): Depend on and link with jcf-depend.o.
+ (../gcjh$(exeext)): Likewise.
+ (jcf-depend.o): New target.
+ * Make-lang.in (JAVA_SRCS): Added jcf-depend.c.
+ (GCJH_SOURCES): Likewise.
+ * jcf-io.c (open_class): Call jcf_dependency_add_file. Added
+ dep_name argument.
+ (find_classfile): Added dep_name argument.
+ (find_class): Compute name of dependency.
+ (open_in_zip): Call jcf_dependency_add_file.
+ * gjavah.c (output_file): No longer global.
+ (usage): Don't mention "gjavah".
+ (help): Likewise.
+ (java_no_argument): Likewise.
+ (version): Likewise.
+ (main): Recognize and handle -M family of options.
+ (print_mangled_classname): Return is void.
+ (process_file): Handle case where output is suppressed.
+ (HANDLE_END_FIELD): Likewise.
+ (HANDLE_METHOD): Likewise.
+ * jcf-depend.c: New file.
+
+Tue Oct 13 23:34:12 1998 Jeffrey A Law (law@cygnus.com)
+
+ * java-tree.def: Add missing newline at EOF.
+
+1998-10-13 Tom Tromey <tromey@cygnus.com>
+
+ * jcf-dump.c (process_class): Use FATAL_EXIT_CODE, not -1.
+ (main): Likewise. Exit with SUCCESS_EXIT_CODE at end of
+ function.
+ Include <config.h> and "system.h".
+ (disassemble_method): Undefine RET to avoid clash with
+ config/i386/i386.h.
+
+Tue Oct 13 03:50:28 1998 Alexandre Petit-Bianco <apbianco@cygnus.com>
+
+ * decl.c (runtime_exception_type_node, error_exception_type_node):
+ New global variables.
+ (init_decl_processing): Initialized.
+ * expr.c (java_lang_expand_expr): Set caught exception type to
+ null if catch handler argument doesn't exit.
+ * java-tree.def (SYNCHRONIZED_EXPR, THROW_EXPR): New Java specific
+ tree codes.
+ * java-tree.h (runtime_exception_type_node,
+ error_exception_type_node): Global variables declared.
+ (DECL_FUNCTION_THROWS): New macro.
+ (DECL_FUNCTION_BODY): Modified comment.
+ (DECL_SPECIFIC_COUNT): Likewise.
+ (struct lang_decl): New field throws_list.
+ (IS_UNCHECKED_EXPRESSION_P): New macro.
+ * lex.c (java_lex): Generate location information for THROW_TK.
+ * parse.h (PUSH_EXCEPTIONS, POP_EXCEPTIONS, IN_TRY_BLOCK_P,
+ EXCEPTIONS_P): New macros.
+ (enum jdep_code): New value JDEP_EXCEPTION.
+ (BUILD_MONITOR_ENTER, BUILD_MONITOR_EXIT,
+ BUILD_ASSIGN_EXCEPTION_INFO, BUILD_THROW, SET_WFL_OPERATOR,
+ PATCH_METHOD_RETURN_ERROR): New macros.
+ (patch_method_invocation_stmt): Added new argument to prototype.
+ (patch_synchronized_statement, patch_throw_statement,
+ check_thrown_exceptions, check_thrown_exceptions_do,
+ purge_unchecked_exceptions, check_throws_clauses): New function
+ prototypes.
+ * parse.y Fixed typo in keyword section.
+ (throw:): Rule tagged <node>.
+ (THROW_TK): Keyword tagged <operator>.
+ (method_header:): Last argument to call to method_header passed
+ from throws: rule.
+ (throws:, class_type_list:, throw_statement:,
+ synchronized_statement:, synchronized:): Defined actions.
+ (method_header): New local variable current. Register exceptions
+ from throws clause.
+ (java_complete_tree): Complete and verify exceptions from throws
+ clause.
+ (complete_class_report_errors): Error message on exceptions not
+ found
+ (java_check_regular_methods): Fixed typo. Shortcut on private
+ overriding methods. Changed error message on method
+ redefinition. Check for throws clause compatibility.
+ (check_throws_clauses): New function.
+ (java_check_abstract_methods): Use DECL_NAME for wfl or current
+ method. Changed error message on method redefinition.
+ (currently_caught_type_list): New static variable.
+ (java_complete_expand_methods): Purge unchecked exceptions from
+ throws clause list. Call PUSH_EXCEPTIONS before walk and
+ POP_EXCEPTIONS after.
+ (resolve_qualified_expression_name): Pass new argument as NULL to
+ patch_method_invocation_stmt.
+ (patch_method_invocation_stmt): New argument ref_decl. Invoke
+ PATCH_METHOD_RETURN_ERROR when returning with error. Reverse
+ argument list when appropriate. Use new argument if non null to
+ store selected method decl.
+ (patch_invoke): Convert if necessary args of builtin types before
+ forming CALL_EXPR. Argument list no longer reversed here.
+ (invocation_mode): Treat final methods as static methods.
+ (java_complete_tree): New cases for THROW_EXPR: and
+ SYNCHRONIZED_EXPR:. Check thrown exceptions when completing
+ function call.
+ (complete_function_arguments): No more RECORD_TYPE
+ conversion. Function parameter nodes no longer saved.
+ (valid_ref_assignconv_cast_p): Avoid handling null type.
+ (patch_binop): Fixed null constant reference handling.
+ (build_try_statement): Use BUILD_ASSIGN_EXCEPTION_INFO and
+ BUILD_THROW macros.
+ (patch_try_statement): Fixed comments. Record caught types in
+ list, push the list, expand try block and pop the list.
+ (patch_synchronized_statement, patch_throw_statement,
+ check_thrown_exceptions, check_thrown_exceptions_do,
+ purge_unchecked_exceptions): New functions.
+ * typeck.c (lookup_argument_method): Allow WFL in place of method
+ DECL_NAME during method definition check
+
+1998-10-09 Tom Tromey <tromey@cygnus.com>
+
+ * gjavah.c (decode_signature_piece): New function.
+ (print_c_decl): Use it. Added `name_override' argument.
+ (print_method_info): Use name_override argument to print_c_decl.
+ (seen_fields): Removed.
+ (print_field_info): Don't update seen_fields.
+ (struct method_name): New structure.
+ (method_name_list): New global.
+ (print_method_info): Add new method to list of methods.
+ (name_is_method_p): New function.
+ (print_field_info): If field name has same name as method, then
+ change field name.
+ (process_file): Parse methods before fields.
+ (field_pass): New global.
+ (HANDLE_END_FIELD): Take field_pass into account.
+
Wed Oct 7 12:10:48 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
* Makefile.in (keyword.h): Add -L KR-C -F ', 0' flags to gperf.
(keyword.h): Regenerate using gperf 2.7.1 (19981006 egcs).
+Sat Oct 3 13:29:46 1998 Anthony Green <green@cygnus.com>
+
+ * jvspec.c: Fix bug in jvgenmain_spec patch.
+
+Fri Oct 2 17:22:52 1998 Alexandre Petit-Bianco <apbianco@cygnus.com>
+
+ * Makefile.in (lang.o:): Install dependency on java-tree.def.
+ * decl.c (soft_exceptioninfo_call_node): New global variable.
+ (init_decl_processing): Fixed indentation. soft_badarrayindex_node
+ takes extra integer argument. soft_exceptioninfo_call_node
+ initialized.
+ * except.c (java_set_exception_lang_code): New function
+ (method_init_exceptions): Called here.
+ (prepare_eh_table_type): New function.
+ (expand_end_java_handler): Called here.
+ * expr.c (build_java_throw_out_of_bounds_exception): Now features
+ one argument. Modified generation of call to
+ soft_badarrayindex_node to use new argument.
+ (build_java_arrayaccess): Pass faulty index value to
+ build_java_throw_out_of_bounds_exception.
+ (generate_name): New function.
+ (java_lang_expand_expr): New local variables node, current,
+ has_finally_p. Expand TRY_EXPR node.
+ (process_jvm_instruction): Replace top of the stack with thrown
+ object reference when entering exception handler.
+ * java-tree.def (TRY_EXPR, CATCH_EXPR, FINALLY_EXPR): New Java
+ specific tree codes.
+ * java-tree.h (soft_exceptioninfo_call_node): Declaration of new
+ global.
+ (DECL_SPECIFIC_COUNT): New macro.
+ (prepare_eh_table_type, java_set_exception_lang_code,
+ generate_name): New function declarations.
+ (match_java_method): Declaration deleted.
+ (FINALLY_EXPR_LABEL, FINALLY_EXPR_BLOCK, CATCH_EXPR_GET_EXPR): New
+ macros.
+ * lex.c (TRY_TK, CATCH_TK): Generate location information.
+ * parse.h (redefinition_error, refine_accessible_methods_list,
+ can_cast_to_p): Function declaration removed.
+ (classitf_redefinition_error, variable_redefinition_error,
+ parse_jdk1_1_error, find_applicable_accessible_methods_list,
+ find_most_specific_methods_list, argument_types_convertible,
+ enter_a_block, valid_builtin_assignconv_identity_widening_p,
+ valid_cast_to_p, valid_method_invocation_conversion_p,
+ try_reference_assignconv, add_stmt_to_compound,
+ build_jump_to_finally, build_tree_list, patch_try_statement,
+ java_get_catch_block): New function declarations.
+ * parse.y (string_buffer_type): Global variable deleted.
+ (group_of_labels, catches, catch_clause, catch_clause_parameter,
+ finally): Rules tagged <node>.
+ (TRY_TK, CATCH_TK): Token tagged <operator>.
+ (class_body_declaration:, class_member_declaration:,
+ formal_parameter:, explicit_constructor_invocation:,
+ interface_member_declaration:, constant_declaration:,
+ primary_no_new_array:, class_instance_creation_expression:,
+ array_creation_expression:): Issue error on unsuported JDK1.1
+ features.
+ (try_statement:, catches:, finally:): Define actions.
+ (catch_clause_parameter): New rule.
+ (catch_clause:): Use new rule catch_clause_parameter.
+ (parse_jdk1_1_error): New function.
+ (redefinition_error): Renamed classitf_redefinition_error.
+ (variable_redefinition_error): New function.
+ (check_class_interface_creation): Call
+ classitf_redefinition_error.
+ (java_complete_tree): Added error message on JDEP_TYPE: case.
+ (complete_class_report_errors): Fixed indentation.
+ (declare_local_variables): Call variable_redefinition_error.
+ (source_end_java_method): Call java_set_exception_lang_code and
+ emit_handlers where appropriate.
+ (java_method_add_stmt): Call add_stmt_to_block.
+ (add_stmt_to_block): New function.
+ (lookup_method_invoke): Fixed outside comment. new local variable
+ candicates. Call find_applicable_accessible_methods_list and
+ find_most_specific_methods_list when searching for a
+ method. Modified error report to list possible candidates when
+ applicable.
+ (find_applicable_accessible_methods_list,
+ find_most_specific_methods_list, argument_types_convertible): New
+ function.
+ (refine_accessible_methods_list): Function deleted.
+ (java_complete_tree): Handle TRY_EXPR. ARRAY_REF handling: save
+ expr (if applicable) before calling patch_array_ref.
+ (build_expr_block): Fixed BLOCK_EXPR_BODY assignment.
+ (enter_block): Fixed comment.
+ (enter_a_block): New function.
+ (patch_assignment): Reorganized. Call try_reference_assignconv for
+ references. Call valid_cast_to_p instead of can_cast_to_p.
+ (try_reference_assignconv,
+ valid_builtin_assignconv_identity_widening_p): New functions.
+ (valid_ref_assignconv_cast_p): Fixed inverted test on CLASS_FINAL.
+ (valid_cast_to_p, valid_method_invocation_conversion_p): New
+ functions.
+ (build_string_concatenation): Don't resolve StringBuffer.
+ (patch_cast): Fixed inverted arguments.
+ (patch_array_ref): Code to save array expr deleted. Call
+ valid_cast_to_p instead of can_cast_to_p.
+ (generate_labeled_block): Call generate_name.
+ (build_jump_to_finally, build_try_statement, java_get_catch_block,
+ patch_try_statement): New functions.
+ * typeck.c (match_java_method): Function deleted.
+
+Fri Oct 2 13:48:36 1998 Anthony Green <green@cygnus.com>
+
+ * jvspec.c: jvgenmain_spec uses different temporary file names.
+
+Fri Oct 2 12:50:19 1998 Anthony Green <green@cygnus.com>
+
+ * jvspec.c (lang_specific_driver): Fail if user specifies
+ --main= when not linking.
+
+Mon Sep 28 13:48:33 1998 Tom Tromey <tromey@cygnus.com>
+
+ * class.c (make_class_data): Push value for `thread' field.
+ * decl.c (init_decl_processing): Added `thread' field to class.
+
+ * class.c (add_field): Always make static fields externally
+ visible.
+
+Sat Sep 26 08:22:47 1998 Anthony Green <green@cygnus.com>
+
+ * expr.c (build_java_athrow,
+ build_java_throw_out_of_bounds_exception, expand_invoke,
+ build_newarray, expand_java_multianewarray, build_java_monitor):
+ Update comments to reflect _Jv_* function names.
+
+Fri Sep 25 16:03:02 1998 Per Bothner <bothner@cygnus.com>
+
+ * decl.c (complete_start_java_method): DECL_RESULT is always promoted.
+ * decl.c (start_java_method): Handle PROMOTE_PROTOTYPES target macro.
+ * parse.y (expand_start_java_method): Likewise.
+
+Thu Sep 24 12:20:35 1998 Per Bothner <bothner@cygnus.com>
+
+ * expr.c (pop_arguments): Handle PROMOTE_PROTOTYPES target macro.
+
+ * class.c (push_class): IDENTIFIER_SIGNATURE_TYPE is now POINTER_TYPE.
+ (add_field): No longer need to convert from RECORD_TYPE to pointer,
+ * expr.c: Remove no-longer-needed calls to promote_type.
+ * decl.c (give_name_to_locals): Liekwise.
+ * jcf-parse.c (get_class_constant): Compensate for new signatures.
+ * parse.y: Add/remove promote_type calls as appropriate.
+ * typeck.c (parse_signature_type): Returns POINTER_TYPE for objects.
+ (parse_signature_string): Likewise.
+ (build_java_array_type): Fix for now signature convenions.
+
+ * lex.c (java_lex): Fix (from Alex) for JC1_LITE problem.
+
+Wed Sep 23 14:49:35 1998 Tom Tromey <tromey@cygnus.com>
+
+ * class.c (init_class_processing): libjava function renamed to
+ _Jv_RegisterClass.
+
+Tue Sep 22 12:00:02 1998 Alexandre Petit-Bianco <apbianco@cygnus.com>
+
+ * expr.c (java_lang_expand_expr): New case for SWITCH_EXPR.
+ * java-tree.def: Fixed DEFTREECODE third argument.
+ (UNARY_PLUS_EXPR, NEW_ARRAY_EXPR, NEW_CLASS_EXPR, THIS_EXPR,
+ CASE_EXPR, DEFAULT_EXPR): New tree codes for Java.
+ * java-tree.h: (IS_CRAFTED_STRING_BUFFER_P): New macro.
+ (JAVA_UNARY_PLUS_EXPR, JAVA_NEW_ARRAY_EXPR, JAVA_NEW_CLASS_EXPR,
+ JAVA_THIS_EXPR): Now replaced by tree code definitions.
+ (CALL_CONSTRUCTOR_P): Now uses NEW_CLASS_EXPR.
+ * lang.c (java_tree_code_type, java_tree_code_length,
+ java_tree_code_name): New arrays.
+ (lang_init): Append Java tree node definitions to Gcc ones.
+ * lex.c (expression_obstack): Declared as extern when JC1_LITE
+ defined.
+ (java_init_lex): Initialize wfl_append, wfl_string_buffer,
+ wfl_to_string.
+ (java_lex): Allow declaration of empty string constants. Retain
+ location information on CASE_TK and DEFAULT_TK.
+ * parse.h (JFLOAT_TYPE_P, JINTEGRAL_TYPE_P, JNUMERIC_TYPE_P,
+ JPRIMITIVE_TYPE_P, JSTRING_TYPE_P, JSTRING_P, JREFERENCE_TYPE_P):
+ Modified to be more robust.
+ (BUILD_APPEND, BUILD_STRING_BUFFER): New macros.
+ (build_new_invocation, try_builtin_assignconv,
+ patch_switch_statement, string_constant_concatenation,
+ build_string_concatenation, patch_string_cst, patch_string,
+ java_expand_switch): New function declarations.
+ * parse.y: Rules related to switch and EH tagged <node>.
+ (label_id): Set to NULL_TREE
+ (wfl_string_buffer, wfl_append, wfl_to_string): New static global
+ tree nodes.
+ (this_or_super:): Fixed indentation.
+ (statement:, statement_nsi:, statement_without_trailing_substatement:,
+ statement_expression:): Removed call to RULE on all sub-rules.
+ (switch_expression:, switch_labels:): New rules.
+ (switch_statement:, switch_block:, switch_block_statement_groups:,
+ switch_block_statement_group:, switch_labels:, switch_label:):
+ Defined actions.
+ (throw_statement:, synchronized_statement:, try_statement:):
+ Defined temporary actions.
+ (class_instance_creation_expression:): Call
+ build_new_invocation. Fixed indentation.
+ (field_access): Fixed indentation.
+ (method_invocation): Likewise.
+ (make_qualified_primary): Use THIS_EXPR.
+ (resolve_qualified_expression_name): Use NEW_CLASS_EXPR. When
+ resolving from SUPER, set *type_found.
+ (qualify_ambiguous_name): Use NEW_CLASS_EXPR.
+ (java_complete_tree): Removed unused local variable `location'. Case
+ for SWITCH_EXPR, sharing code with LOOP_EXPR. Use NEW_ARRAY_EXPR,
+ NEW_CLASS_EXPR, UNARY_PLUS_EXPR and THIS_EXPR. New string handling
+ on MODIFY_EXPR: and all binary operator tree code cases. Removed
+ STRING_CST: case. default: checks for patchable strings.
+ (complete_function_arguments): Transform string constant or
+ crafted StringBuffer if necessary.
+ (build_method_invocation): Fixed comments.
+ (build_new_invocation): New function.
+ (patch_assignment): Call try_builtin_assignconv to figure a valid
+ assignment conversion between builtin types.
+ (try_builtin_assignconv): New function.
+ (build_binop): Use URSHIFT_EXPR directly to call build.
+ (operator_string): Use UNARY_PLUS_EXPR.
+ (patch_binop): Use UNARY_PLUS_EXPR. Handle string concatenation
+ operator.
+ (do_merge_string_cste, merge_string_cste,
+ string_constant_concatenation, build_string_concatenation,
+ patch_string, patch_string_cst): New function.
+ (build_unary_op): Use UNARY_PLUS_EXPR and CONVERT_EXPR.
+ (patch_unaryop): Likewise. New test of valid ++/-- operands.
+ (build_newarray_node): Use NEW_ARRAY_EXPR.
+ (build_this): Use THIS_EXPR.
+ (build_return): Enable debug information on return statement.
+ (build_if_else_statement): Likewise.
+ (complete_labeled_statement): Fixed related comment.
+ (build_loop_body): Fixed comment.
+ (build_bc_statement): Enable debug information on break/continue
+ statements.
+ (patch_bc_statement): Fixed typos. Handle SWITCH statement
+ context.
+ (patch_switch_statement, case_identity, java_expand_switch): New
+ functions.
+
+Mon Sep 21 13:21:35 1998 Per Bothner <bothner@cygnus.com>
+
+ * buffer.h (BUFFER_INIT): New macro.
+ * jcf-write.c (struct jcf_partial): New type. Put global stuff here.
+ Pass (struct jcf_partial *state) to most functions.
+ (jcf_block, jcf_relocation): New types.
+ Support labels, branches, conditionals, loops.
+
+Mon Sep 21 15:08:48 1998 Tom Tromey <tromey@cygnus.com>
+
+ * decl.c (INT_TYPE_SIZE): Define as BITS_PER_WORD if not defined.
+
+Mon Sep 21 13:21:35 1998 Per Bothner <bothner@cygnus.com>
+
+ * decl.c (integer_type_node): Make it have INT_TYPE_SIZE.
+ * verify.c (verify_jvm_instructions): Use int_type_not (32 bits),
+ not integer_type_node (INT_TYPE_SIZ bits).
+
+ * parse.y (patch_if_else_statement): Accept promoted_boolean_type_node.
+
+ * jcf-reader.c (get_attribute): New HANDLE_EXCEPTION_TABLE hook.
+ * jcf-dump.c (print_exception_table): New function.
+ (disassemble_method): Better handling of wide instructions.
+ Make more robust for bad input.
+
Wed Sep 30 20:53:51 1998 Jeffrey A Law (law@cygnus.com)
* jcf-write.c (OP2, OP4): Use "_i", not "_I" to avoid problems on
@@ -21,6 +2879,11 @@ Thu Sep 17 01:57:07 1998 Jeffrey A Law (law@cygnus.com)
* Makefile.in (JAVA_OBJS): Add memmove.o
(memmove.o): New target & rules.
+Tue Sep 15 23:21:55 1998 Tom Tromey <tromey@cygnus.com>
+
+ * expr.c (expand_invoke): Don't generate a call to the class init
+ code.
+
Mon Sep 14 10:14:47 1998 Jeffrey A Law (law@cygnus.com)
* Makefile.in: Add many missing dependencies.
@@ -29,6 +2892,14 @@ Mon Sep 14 10:14:47 1998 Jeffrey A Law (law@cygnus.com)
* except.c, expr.c, jcf-io.c jcf-parse.c, jcf-write.c: Likewise.
* jvgenmain.c lang.c mangle.c typeck.c verify.c: Likewise.
+Fri Sep 11 14:05:21 1998 Per Bothner <bothner@cygnus.com>
+
+ * decl.c (complete_start_java_method): If method is static (and
+ not private) call _Jv_InitClass.
+ * expr.c (expand_invoke): Don't call build_class_init.
+
+ * jvspec.c (jvgenmain_spec): Fix spec for generated .o file.
+
Thu Sep 10 10:33:31 1998 Jeffrey A Law (law@cygnus.com)
* Make-lang.in (GCJ): Define before using.
@@ -53,3 +2924,2809 @@ Mon Sep 7 13:59:49 1998 Jeffrey A Law (law@cygnus.com)
* Makefile.in (INCLUDES): Update for recent toplevel gcc changes.
+Sat Sep 5 16:08:01 1998 Tom Tromey <tromey@cygnus.com>
+
+ * Make-lang.in (java.maintainer-clean): Don't remove parse.h.
+ (java.mostlyclean): Remove parse.c and parse-scan.c, not parse.h.
+ * Makefile.in (PARSE_C): New macro.
+ (PARSE_H): Likewise.
+ (PARSE_SCAN_C): Likewise.
+ ($(PARSE_C)): Target renamed from parse.c.
+ ($(PARSE_SCAN_C)): Target renamed from parse-scan.c.
+ (clean): Remove parse-scan.c as well.
+ (parse.o): Depend on $(PARSE_C).
+
+Sat Sep 5 08:48:40 1998 Anthony Green <green@cygnus.com>
+
+ * README, license.terms: Removed.
+
+ * Make-lang.in, Makefile.in, class.c, config-lang.in, constants.c,
+ decl.c, except.c, expr.c, gjavah.c, java-except.h, java-tree.h,
+ javaop.def, javaop.h, jcf-dump.c, jcf-io.c, jcf-parse.c,
+ jcf-reader.c, jcf-write.c, jcf.h, jvgenmain.c, jvspec.c,
+ keyword.gperf, keyword.h, lang-options.h, lang-specs.h, lang.c,
+ lex.c, lex.h, mangle.c, parse-scan.y, parse.h, parse.y, typeck.c,
+ verify.c, zextract.c, zipfile.h: Fixed copyright assignment,
+ and Java trademark attribution.
+
+Fri Sep 4 10:42:05 1998 Tom Tromey <tromey@cygnus.com>
+
+ * Makefile.in: Use gcjh, not gjavah.
+ * config-lang.in (stagestuff): Use gcjh, not gjavah.
+ * Make-lang.in: Changed gjavah to gcjh everywhere.
+
+Thu Sep 3 18:04:09 1998 Per Bothner <bothner@cygnus.com>
+
+ * gjavah.c: Support new -prepend -add -append flags.
+ (print_method_info): Method is not virtual if class is final.
+
+Thu Sep 3 12:03:53 1998 Alexandre Petit-Bianco <apbianco@sendai.cygnus.com>
+
+ * jv-scan.c: Fixed copyright assignment.
+ * keyword.gperf: Likewise.
+ * keyword.h: Likewise.
+ * lex.c: Fixed copyright assignment.
+ (java_lex): Push unicode back when parsing '<'.
+ * lex.h: Fixed copyright assignment.
+ * parse-scan.y: Likewise.
+ * parse.h: Fixed copyright assignment.
+ (build_debugable_stmt, complete_for_loop): New function prototypes.
+ * parse.y: Fixed copyright assignment.
+ (for_statement:): Call complete_for_loop. Set EXIT_EXPR to be
+ size_zero_node when completing a loop with no exit condition.
+ (for_statement_nsi:): Define action.
+ (for_init:, for_update:): Return size_zero_node when empty.
+ (declare_local_variables): Call build_debugable_stmt.
+ (build_debugable_stmt): New function.
+ (build_loop_body): Build debugable statement around loop
+ condition part.
+ (complete_loop_body): Take into account the debugable statement
+ around the EXIT_EXPR.
+ (complete_loop_body): New function.
+ (patch_exit_expr): Fixed condition inversion.
+
+Wed Sep 2 11:53:58 1998 Tom Tromey <tromey@cygnus.com>
+
+ * Make-lang.in (jvspec.o): Use GCC_THREAD_FILE to compute correct
+ name of thread define.
+ * jvspec.c (THREAD_NAME): New macro.
+ (GCLIB): Likewise.
+ (THREADLIB): Likewise.
+ (lang_specific_driver): Recognize attempt to link with thread
+ library or gc library. Recognize -ljava on command line so it
+ isn't linked against more than once.
+
+Wed Sep 2 11:28:35 1998 Alexandre Petit-Bianco <apbianco@cygnus.com>
+
+ * parse-scan.y (report_main_declaration): Name of the class
+ containing `main' can be a qualified name.
+
+Mon Aug 31 13:25:58 1998 Tom Tromey <tromey@cygnus.com>
+
+ * config-lang.in: Changed gjavac to gjc everywhere.
+ * Make-lang.in: Changed gjavac to gjc everywhere.
+
+Thu Aug 27 02:28:27 1998 Alexandre Petit-Bianco <apbianco@cygnus.com>
+
+ * Make-lang.in (JAVA_TARGET_INDEPENDENT_BIN_TOOLS): New variable.
+ (java.install-common:): Loop over JAVA_TARGET_INDEPENDENT_BIN_TOOLS
+ and install the files.
+ * Makefile.in (JAVA_OBJS_LITE): New variable.
+ (compiler:): Now include jv-scan as a dependency.
+ (../jv-scan$(exeext), parse-scan.c): New targets.
+ (../jcf-dump$(exeext)): Was jcf-dump$(exeext) before.
+ * config-lang.in (compilers): Removed gcj, gjavah from the list.
+ * jcf-parse.c (parse_source_file): Call java_layout_classes and
+ check for errors even if parse_only.
+ * lex.c (java_init_lex): Reorganized and skip parts if JC1_LITE is
+ defined.
+ (yylex): New function. Uses java_lex body.
+ (java_lex): Removed commented out statement. Remove local variable
+ literal. Use SET_LVAL_NODE_TYPE and SET_LVAL_NODE where
+ appropriate. Use macros FLOAT_TYPE_NODE, DOUBLE_TYPE_NODE,
+ DCONST0, SET_FLOAT_HANDLER, SET_REAL_VALUE_ATOF,
+ SET_LVAL_NODE_TYPE and GET_TYPE_PRECISION. Don't create STRING_CST
+ if JC1_LITE is defined. Use BUILD_ID_WFL to build identifiers. Use
+ SET_MODIFIER_CTX, SET_LVAL_NODE, BUILD_ID_WFL and GET_IDENTIFIER
+ where appropriate.
+ (java_lex_error): Empty if JC1_LITE is defined.
+ (java_get_line_col): Return 0 if JC1_LITE is defined.
+ * lex.h (JAVA_FLOAT_RANGE_ERROR, JAVA_INTEGRAL_RANGE_ERROR,
+ SET_MODIFIER_CTX): Moved into the section containing the macros
+ conditionally defined by JC1_LITE.
+ (BUILD_OPERATOR,BUILD_OPERATOR2): Just return the TOKEN
+ argument if JC1_LITE is defined.
+ (HOST_BITS_PER_WIDE_INT, HOST_WIDE_INT, REAL_VALUE_ATOF,
+ REAL_VALUE_ISINF, REAL_VALUE_ISNAN): Preset to values if JC1_LITE
+ is defined.
+ (DCONST0, SET_FLOAT_HANDLER, GET_IDENTIFIER, SET_REAL_VALUE_ATOF,
+ FLOAT_TYPE, DOUBLE_TYPE, SET_MODIFIER_CTX, GET_TYPE_PRECISION,
+ SET_LVAL_NODE, SET_LVAL_NODE_TYPE, BUILD_ID_WFL): New macros, set
+ to different values according to JC1_LITE.
+ * parse.h (int_fits_type_p, stabilize_reference): Prototype not
+ declared if JC1_LITE set.
+ (jdep_code, typedef struct _jdep, typedef struct _jdeplist): Not
+ defined if JC1_LITE not set.
+ (struct parser_ctx): Reorganized and skip the jc1 front end part
+ if JC1_LITE set.
+ (java_layout_classes): New function definition.
+ (java_push_parser_context, java_init_lex, yyparse, yylex,
+ yyerror): Prototype always declared. All other static function
+ prototypes declared only if JC1_LITE is not set.
+ * parse.y (yyparse, yylex, yyerror): No longer declared here. Now
+ declared in parse.h.
+ (java_layout_classes): New function.
+ (java_complete_expand_methods): No longer layout the class here.
+ * parse-scan.y: New file.
+ * jv-scan.c: New file.
+
+Tue Aug 25 10:17:54 1998 Tom Tromey <tromey@cygnus.com>
+
+ * gjavah.c (main): Handle -friend option.
+ (friend_specs): New global.
+ (generate_access): Handle friend_specs.
+ (process_file): Likewise.
+ (MAX_FRIENDS): New macro.
+ (friend_count): New global.
+ (print_cxx_classname): Added `prefix' argument. Ignore arrays.
+ Changed all callers.
+
+Mon Aug 24 20:19:27 1998 Per Bothner <bothner@cygnus.com>
+
+ * jcf-dump.c (process_class): Move JCF_FINISH use to main,
+ (main): Handle processing all the entries of a named .zip archive.
+ * jcf-io.c (jcf_trim_old_input): New function.
+ * jcf.h (GET_u2_le,GET_u4_le,JCF_readu2_le,JCF_readu4_le): New macros.
+
+Mon Aug 24 07:35:13 1998 Per Bothner <bothner@cygnus.com>
+
+ * lang.c (flag_assume_compiled): Make default be on.
+
+Fri Aug 21 17:29:04 1998 Per Bothner <bothner@cygnus.com>
+
+ * jcf-dump.c: Add bunches of flags to control output more.
+ (process_class): New function; support printing more than one class.
+ (main): Support new --print-main and --javap flags.
+ * jcf-reader.c (IGNORE_ATTRIBUTE): New hook.
+ * jcf.h (CPOOL_INDEX_IN_RANGE): New macro.
+
+Thu Aug 20 14:24:47 1998 Per Bothner <bothner@cygnus.com>
+
+ Change mangling of dispatch table to match C++ vtable (w/thunks).
+ * class.c (build_dtable_decl), java-tree.h: New function.
+ (make_class_data): Call it.
+ * decl.c (init_decl_processing): Likewise.
+
+Wed Aug 19 17:57:07 1998 Warren Levy <warrenl@cygnus.com>
+
+ * decl.c (init_decl_processing): Use _Jv_NewObjectArray, not
+ soft_anewarray; adjust args passed.
+ * expr.c (build_anewarray): Adjust args for soft_anewarray_node to
+ match _Jv_NewObjectArray.
+
+Wed Aug 19 09:33:23 1998 Alexandre Petit-Bianco <apbianco@cygnus.com>
+
+ * decl.c (push_labeled_block, pop_labeled_block): New functions.
+ * expr.c (loopup_label): Call create_label_decl.
+ (create_label_decl): New function.
+ (java_lang_expand_expr): Call expand_start_bindings with argument
+ set to zero.
+ * java-tree.h Added space after PROTO in function declarations
+ when necessary.
+ (IS_FOR_LOOP_P, IS_BREAK_STMT_P): New macros.
+ (create_label_decl, push_labeled_block): New function
+ declarations.
+ * lex.c (label_id): Initialize.
+ (SUPER_TK, THIS_TK, RETURN_TK): Merged common actions in final
+ switch.
+ * parse.h Added space after PROTO in function declarations when
+ necessary.
+ (LOOP_EXPR_BODY_MAIN_BLOCK, LOOP_EXPR_BODY_UPDATE_BLOCK,
+ LOOP_EXPR_BODY_CONDITION_EXPR, LOOP_EXPR_BODY_LABELED_BODY,
+ LOOP_EXPR_BODY_BODY_EXPR, LOOP_HAS_LABEL_P, LOOP_HAS_LABEL_SKIP_P,
+ PUSH_LABELED_BLOCK, POP_LABELED_BLOCK, PUSH_LOOP, POP_LOOP): New
+ macros.
+ (struct parser_ctxt): New fields current_loop,
+ current_labeled_block.
+ (build_if_else_statement, patch_if_else_statement,
+ add_stmt_to_compound, patch_exit_expr, build_labeled_block,
+ generate_labeled_block, complete_labeled_statement,
+ build_bc_statement, patch_bc_statement, patch_loop_statement,
+ build_new_loop, build_loop_body, complete_loop_body): New function
+ declarations.
+ * parse.y (java_warning_count): New global variable.
+ (label_id): New static variable.
+ (BREAK_TK, CONTINUE_TK): Token tagged <operator>.
+ (block:): Return size_zero_node when block is empty.
+ (empty_statement:): Return size_zero_node.
+ (statement:): Implement supplemental action when for_statement: is
+ reduced.
+ (label_decl:): New rule.
+ (labeled_statement:): Rewritten using label_decl. Actions
+ implemented.
+ (labeled_statement_nsi:): Likewise.
+ (if_then_statement): Actions implemented.
+ (while_expression): New rule.
+ (while_statement:): Rewritten using while_expression. Actions
+ implemented.
+ (while_statement_nsi:): Likewise.
+ (do_statement_begin:): New rule.
+ (do_statement:): Rewritten using do_statement_begin. Actions
+ implemented.
+ (for_statement:): Rewritten using for_begin. Actions implemented.
+ (for_statement_nsi:): Likewise.
+ (for_header:, for_begin:): New rules.
+ (for_init:): Actions implemented.
+ (statement_expression_list:, break_statement:,
+ continue_statement:): Likewise.
+ (yyerror): Count number of issued warning(s).
+ (java_report_errors): Report error(s) and/or warning(s).
+ (java_complete_class): Use build_java_argument_signature to
+ recompute completed method signature.
+ (java_check_regular_methods): New locals method_wfl and aflags.
+ Use method_wfl instead of lookup_cl during error reports. Fixed
+ indentation and modified some error messages. Use
+ lang_printable_name in method instead of the DECL_NAME. New code
+ to issue warnings on methods not overriding corresponding methods
+ private to a different package.
+ (java_method_add_stmt): Call add_stmt_to_compound.
+ (add_stmt_to_compound): New function.
+ (java_complete_tree): Handle LABELED_BLOCK_EXPR, EXIT_BLOCK_EXPR,
+ LOOP_EXPR, EXIT_EXPR and COND_EXPR.
+ (build_if_else_statement, patch_if_else_statement,
+ build_labeled_block, generate_labeled_block,
+ complete_labeled_statement, build_new_loop, build_loop_body,
+ complete_loop_body, patch_loop_statement, build_bc_statement,
+ patch_bc_statement, patch_exit_expr): New functions.
+ * typeck.c (build_java_signature): Build argument signature before
+ enclosing it in between parenthesis.
+
+Mon Aug 17 17:44:24 1998 Warren Levy <warrenl@cygnus.com>
+
+ * Make-lang.in (JAVA_SRCS): Created for dependencies * Makefile.in
+ (JAVA_OBJS): Added reminder comment
+
+Thu Aug 13 10:01:45 1998 Nick Clifton <nickc@cygnus.com>
+
+ * gjavah.c (D_NAN_MASK): Append LL to the constant to force it to
+ be interpreted as a long long.
+
+Thu Aug 13 14:34:07 1998 Warren Levy <warrenl@cygnus.com>
+
+ * decl.c (init_decl_processing): Use _Jv_InitClass, not
+ soft_initialise_class. Use _Jv_NewMultiArray, not
+ soft_multianewarray. Use _Jv_ThrowBadArrayIndex, not
+ soft_badarrayindex. Use _Jv_CheckCast, not soft_checkcast. Use
+ _Jv_CheckArrayStore, not soft_checkarraystore. Use
+ _Jv_LookupInterfaceMethod, not soft_lookupinterfacemethod.
+
+Wed Aug 12 14:23:13 1998 Per Bothner <bothner@cygnus.com>
+
+ * decl.c, java-tree.h (this_identifier_node, super_identifier_node,
+ length_identifier_node): New global tree node constants.
+ * parse.y (kw_super, kw_this, kw_length): Removed globals.
+ Replace uses by super_identifier_node etc.
+ * lex.c (kw_super, kw_this, kw_length): Don't initialize.
+
+ * parse.y (resolve_field_access): Don't special-case ".length" if
+ flag_emit_class_files.
+ (patch_array_ref): Leave as ARRAY_REF if flag_emit_class_files.
+ * jcf-write.c (generate_bytecode_insns): Handle ARRAY_REF opcode
+ and ARRAY.length.
+
+Tue Aug 11 11:31:55 1998 Per Bothner <bothner@cygnus.com>
+
+ * decl.c (init_decl_processing): Remove unused method_type_node fields.
+ * class.c (make_method_value): Remove init for removed fields.
+
+ * class.c (layout_class): Use build_java_argument_signature.
+ * java-tree.h (TYPE_ARGUMENT_SIGNATURE): New macro.
+
+ * typeck.c (push_java_argument_signature): Removed. Merged into ...
+ (build_java_argument_signature): Use TYPE_ARGUMENT_SIGNATURE cache.
+ (build_java_signature): Don't use push_java_argument_signature.
+
+ * typeck.c (lookup_argument_method): New function.
+ * parse.y (java_check_regular_methods): Use lookup_argument_method
+ instead of lookup_java_method2 followed by lookup_java_method.
+
+ * parse.y (check_method_redefinition): Minor optimization.
+
+ * jcf-write.c (generate_bytecode_insns): Handle RETURN_EXPR,
+ MINUS_EXPR, MULT_EXPR, TRUNC_DIV_EXPR, and RDIV_EXPR.
+
+Mon Aug 10 09:57:15 1998 Tom Tromey <tromey@cygnus.com>
+
+ * Make-lang.in (jc1$(exeext)): Don't depend on c-common.o or
+ c-pragma.o.
+
+ * gjavah.c (java_float_finite): Use K&R-style definition.
+ (java_double_finite): Likewise.
+ (generate_access): Now returns void. Changed all callers.
+ (last_access_generated): Removed.
+ (process_file): Only make a single pass over the .class file.
+
+Wed Jul 29 17:50:23 1998 Per Bothner <bothner@cygnus.com>
+
+ * class.c (get_dispatch_table): Add extra dummy vtable entry,
+ for compatibility for G++ (with -fvtable-thunks).
+ * expr.c (build_invokevirtual): Add one for extra dummy vtable entry.
+
+ * gjavah.c (process_file): Use public inheritance for super-class.
+
+Wed Jul 29 13:19:03 1998 Alexandre Petit-Bianco <apbianco@cygnus.com>
+
+ * lex.c (java_init_lex): Initialize ctxp->package.
+ * parse.h (struct parser_ctxt): package and package_len replaced
+ by tree package, an identifier node. Field method_decl_list is
+ gone. Fixed comments.
+ (lookup_field_wrapper, merge_qualified_name, not_accessible,
+ class_in_current_package): New function prototypes.
+ * parse.y (array_type:): Set class loaded flag on primitive type
+ arrays.
+ (package_declaration:): Assign ctxp->package to the
+ identifier node.
+ (method_invocation:): Handle invocation of method qualified by
+ `super'.
+ (single_type_import_declaration:): Removed ambiguity check.
+ (java_pop_parser_context): New local variable `next'. Reset and
+ set IMPORT_CLASSFILE_NAME flags on current and previous import
+ list.
+ (java_accstring_lookup): Use new local macro COPY_RETURN.
+ (lookup_field_wrapper): New function.
+ (parser_qualified_classname): Use merge_qualified_name.
+ (parser_check_super_interface): Broaden error message.
+ (do_resolve_class): Check for qualified class name in the current
+ compilation unit if appropriate.
+ (process_imports): Check for already defined classes.
+ (check_pkg_class_access): Got rid of call to
+ get_access_flags_from_decl.
+ (java_complete_expand_methods): Call safe_layout_class based on
+ the current class size.
+ (make_qualified_primary): Build a WFL qualification on primary if
+ none exists.
+ (merge_qualified_name): New function.
+ (make_qualified_name): Use merge_qualified_name.
+ (resolve_expression_name): Use safe_lookup_field.
+ (resolve_field_access): Got rid of call to get_access_flags_from_decl.
+ (resolve_qualified_expression_name): Likewise. Check on resolved
+ element accessibility.
+ (not_accessible_p, class_in_current_package): New functions.
+ (maybe_access_field): Got rid of call to get_access_flags_from_decl.
+ (patch_method_invocation_stmt): Merged common pieces. Check
+ accessibility of invoked method.
+ (check_for_static_method_reference): Add returned type in error
+ message.
+ (invocation_mode): Get rid of bogus check on PRIVATE methods.
+ (refine_accessible_methods_list): Merged two conditions in test.
+ (java_complete_class): Sanity check on stabilize_ref gone.
+ * zextract.c (read_zip_archive): Cast lseek second argument to long.
+
+Tue Jul 28 21:39:22 1998 Per Bothner <bothner@cygnus.com>
+
+ * class.c (hashUtf8String): Fix - use new JavaSoft specification.
+
+Fri Jul 24 10:43:25 1998 Tom Tromey <tromey@cygnus.com>
+
+ * gjavah.c (F_NAN): Removed.
+ (F_NAN_MASK): New macro.
+ (F_POSITIVE_INFINITY): Removed.
+ (F_NEGATIVE_INFINITY): Likewise.
+ (java_float_finite): Rewrote.
+ (D_NAN_MASK): Renamed.
+ (java_double_finite): Rewrote.
+ (D_POSITIVE_INFINITY): Removed.
+ (D_NEGATIVE_INFINITY): Likewise.
+
+ * jcf-dump.c (print_constant): [CONSTANT_Double, CONSTANT_Float]
+ If verbose, print underlying representation of value in hex.
+
+Fri Jul 24 14:14:32 1998 Per Bothner <bothner@cygnus.com>
+
+ * buffer.h, buffer.c: New files.
+ * Makefile.in (JAVA_OBJS): Add buffer.o.
+
+ Support locals variables and writing their debug entries to .class.
+ * jcf-write.c: Simplify some by user new buffer type.
+ (vode_buffer_grow): Removed.
+ (struct localvar_info): New type.
+ (localsvars, localvartable): New buffers.
+ (localvar_alloc, localvar_free): New functions.
+ (generate_bytecode_insns): Handle local variables.
+ (generate_classfile): Write LocalVariableTable attribute.
+
+Fri Jul 24 13:46:59 1998 Alexandre Petit-Bianco <apbianco@cygnus.com>
+
+ * jcf-io.c (open_in_zip): Check the zipfile magic number.
+ * zipfile.h (ZIPMAGIC): New macro.
+
+Fri Jul 24 10:43:25 1998 Tom Tromey <tromey@cygnus.com>
+
+ * Makefile.in (gjavah.o): Updated dependencies.
+ (jcf-dump.o): Likewise.
+ (all.indirect): Use ../gjavah.
+ (../gjavah$(exeext)): Likewise.
+ (clean): Don't remove gjavah.
+ (clean): Remove parse.c, not java/parse.c.
+ * Make-lang.in (java): Added gjavah.
+ (gjavah$(exeext)): New target.
+ (GJAVAH_SOURCES): New macro.
+ (java.all.build): Added gjavah.
+ (java.all.cross): Likewise.
+ (java.rest.encap): Likewise.
+ * config-lang.in (compilers, stagestuff): Added gjavah.
+
+Thu Jul 23 18:33:56 1998 Tom Tromey <tromey@cygnus.com>
+
+ * gjavah.c (java_float_finite): New function.
+ (java_double_finite): Likewise.
+ (F_POSITIVE_INFINITY): New macro.
+ (F_NEGATIVE_INFINITY): Likewise.
+ (F_NAN): Likewise.
+ (D_POSITIVE_INFINITY): Likewise.
+ (D_NEGATIVE_INFINITY): Likewise.
+ (D_NAN): Likewise.
+ (print_field_info): Use java_float_finite and java_double_finite.
+
+Thu Jul 23 15:28:24 1998 Per Bothner <bothner@cygnus.com>
+
+ * parse.y (method_header): Name "this" implicit argument.
+
+Wed Jul 22 15:47:30 1998 Per Bothner <bothner@cygnus.com>
+
+ * jcf-write.c: Write out LineNumberTable attribute in .class file.
+ (linenumber_buffer, linenumber_ptr, linenumber_limit): New statics.
+ (put_linenumber): New function.
+ (generate_bytecode_insns, generate_classfile): Write line numbers.
+
+Wed Jul 22 14:39:00 1998 Alexandre Petit-Bianco <apbianco@cygnus.com>
+
+ * java-tree.h (CALL_EXPR_FROM_PRIMARY_P): Changed in PRIMARY_P.
+ (lookup_name, build_known_method_ref, build_class_init,
+ build_invokevirtual, invoke_build_dtable, match_java_method,
+ build_field_ref, pushdecl_force_head, build_java_binop,
+ binary_numeric_promotion, build_decl_no_layout,
+ build_java_arrayaccess, build_newarray, build_anewarray,
+ build_java_array_length_access, build_java_arraynull_check): New
+ extern function prototypes.
+ (JAVA_UNARY_PLUS_EXPR, JAVA_NEW_ARRAY_EXPR, JAVA_NEW_CLASS_EXPR,
+ JAVA_THIS_EXPR, CALL_CONSTRUCTOR_P): Macro definition moved in
+ java-tree.h.
+ * jcf-parse.c (init_outgoing_cpool): Set current_constant_pool_data_ref
+ to NULL
+ * jcf.h (jcf_out_of_synch): New extern function prototype.
+ * parse.h: Static/global function implemented in parse.y
+ prototyped and declarations moved at the end of the file.
+ (DECL_P): Check that the argument isn't null.
+ (JAVA_UNARY_PLUS_EXPR, JAVA_NEW_ARRAY_EXPR, JAVA_NEW_CLASS_EXPR,
+ JAVA_THIS_EXPR): No longer defined here. See java-tree.h
+ (QUAL_DECL_TYPE): New macro.
+ (PARAMS): Macro definition removed.
+ * parse.y: (yyparse, yyerror): Use PROTO instead of PARAMS.
+ (return_statement:): Call build_return.
+ (field_access:): Call make_qualified_primary in sub rule.
+ (method_invocation:): Build method invocation and call
+ make_qualified_primary when processing primaries.
+ (java_complete_class): Set IDENTIFIER_SIGNATURE_TYPE by calling
+ get_type_from_signature.
+ (java_check_regular_method): Extra integer 0 argument when calling
+ lookup_java_method2.
+ (lookup_java_interface_method2): Extra method DECL argument when
+ calling lookup_java_interface_method2.
+ (java_method_add_stmt): Set TREE_SIDE_EFFECTS on newly created
+ COMPOUND_EXPR node.
+ (java_complete_expand_method): Layout current class iff not
+ already done. Don't process interface's methods.
+ (java_complete_expand_method): Use super class only if it
+ exists. Use current class otherwise.
+ (make_qualified_primary): New function.
+ (resolve_expression_name): Process qualified expression or
+ expression from primary the same way.
+ (resolve_expression_name): Two last arguments to
+ resolve_field_access are now NULL_TREEs.
+ (resolve_field_access): New variable is_static. Local field must
+ be DECLs. is_static computed on field DECLs only. Append code in
+ where_found to the field access if necessary. Use QUAL_DECL_TYPE
+ to initialize field_type.
+ (resolve_qualified_expression_name): New local variable,
+ previous_call_static and is_static. Handle primaries with function
+ calls, casts, array references and `this'. `super' now handled as
+ `(super_class)this'. Use is_static to clarify boolean expressions.
+ Added code to handle case where a proper handle is required to
+ access a field. Use QUAL_DECL_TYPE where applicable.
+ (maybe_access_field): New function.
+ (patch_method_invocation_stmt): New arguments primary, where,
+ is_static. Branch of the test on CALL_EXPR_FROM_PRIMARY_P
+ deleted. Use `where' as a type to search from if specified. Check
+ for static method reference where forbidden. Append primary or
+ current_this to the argument list if not calling constructor nor
+ static methods.
+ (check_for_static_method_reference): New function.
+ (patch_invoke): Layout the class on which new is done if
+ necessary.
+ (lookup_method_invoke): Changed format to report errors on
+ methods.
+ (qualify_ambiguous_name): New local variable this_found. Now
+ handle things from primaries. Method call are considered
+ expression names.
+ (identical_subpath_p): NULL_TREE arguments to breakdown_qualified
+ changed into NULLs.
+ (not_initialized_as_it_should_p): Comply with the new DECL_P.
+ (java_complete_tree): New case fo RETURN_EXPR. Process function
+ call arguments in separate function.
+ (complete_function_arguments): New function.
+ (build_method_invocation): Don't use CALL_EXPR_FROM_PRIMARY_P
+ anymore.
+ (patch_assignment): Take the return function slot into account as
+ a RHS. Distinguish assignment from a return.
+ (valid_ref_assignconv_cast_p): Use build_java_argument_signature
+ when checking methods in interfaces.
+ (resolve_type_during_patch): NULL argument to unresolve_type_p
+ instead of NULL_TREE.
+ (patch_newarray): Fixed typo in comment.
+ (buid_this): Build a WFL with `kw_this' instead of a FIELD_DECL.
+ (build_return, patch_return): New functions.
+ * typeck.c (lookup_java_constructor): Fixed typo in comment.
+
+Tue Jul 21 12:10:04 1998 Per Bothner <bothner@cygnus.com>
+
+ * constants.c (find_name_and_type_constant, find_fieldref_index,
+ find_methodref_index): New methods.
+ * expr.c (build_invoke_non_interface): If flag_emit_class_files,
+ just return given method. Also, rename to build_known_method_ref.
+ (expand_invoke): Rename call to build_invoke_non_interface.
+ * java-tree.h, parse.h: Update prototype.
+ * parse.y, decl.c, jcf-parse.c: Suppress calls to back-end functions
+ (such as expand_expr_stmt) if flag_emit_class_files.
+ * jcf-write.c (RESERVE, OP1, OP2, OP4, NOTE_PUSH, NOTE_POP,
+ STACK_TARGET, IGNORE_TARGET): New macros.
+ (code_buffer, code_ptr, code_limit, code_S, code_SP_max): New globals.
+ (generate_bytecode_insn): New function to generate method's bytecode.
+ (generate_classfile): Node generate Code attribute for a method.
+ (code_buffer_grow, push_constant1, push_constant2, push_int_const,
+ push_long_const, field_op, adjust_typed_op, maybe_wide):
+ New functions used by generate_bytecode_insn.
+
+ * typeck.c (signature_include_return): Remove variable.
+ (push_java_argument_signature, build_java_argument_signature): New.
+ (build_java_signature): Use push_java_argument_signature.
+ * parse.y: Use build_java_argument_signature instead of fiddling
+ with signature_include_return.
+
+Fri Jul 17 09:48:51 1998 Tom Tromey <tromey@cygnus.com>
+
+ * gjavah.c (print_c_decl): Always generate JArray<>* for array
+ types.
+
+ * Makefile.in (all.indirect): Added gjavah$(exeext).
+ (gjavah$(exeext)): Added $(exeext).
+ (clean): Likewise.
+
+Thu Jul 16 15:29:20 1998 Alexandre Petit-Bianco <apbianco@cygnus.com>
+
+ * class.c (layout_class): Call to java_layout_parsed_class replace
+ by safe_layout_class.
+ * expr.c (build_java_array_length_access): Removed static storage
+ class in the function definition.
+ (build_java_arraynull_check): Likewise.
+ Also fixed typos in two comments.
+ * lex.c (java_init_lex): Initialize static global kw_length.
+ (java_lex): Use BUILD_OPERATOR on RETURN_TK.
+ * lex.h (JAVA_FLOAT_RANGE_ERROR): Add extra argument to
+ java_lex_error.
+ (JAVA_INTEGRAL_RANGE_ERROR): Likewise.
+ * parse.h (resolve_no_layout): New static function declaration.
+ (get_identifier_in_static): Declaration removed.
+ (java_layout_parsed_class): Function name declaration changed to
+ safe_layout_class.
+ (build_newarray_node, patch_newarray, resolve_type_during_patch,
+ not_initialized_as_it_should_p, build_this): New static function
+ declarations.
+ (pushdecl_force_head, build_java_binop, int_fits_type_p,
+ binary_numeric_promotion, stabilize_reference,
+ build_decl_no_layout, build_java_arrayaccess): Extern function
+ declarations moved into their own section.
+ (build_newarray, build_anewarray, build_java_array_length_access,
+ build_java_arraynull_check): New extern function declarations.
+ (UNARY_PLUS_EXPR): Macro renamed into JAVA_UNARY_PLUS_EXPR.
+ (JAVA_NEW_ARRAY_EXPR, JAVA_NEW_CLASS_EXPR, JAVA_THIS_EXPR): New
+ fake tree codes.
+ (CALL_CONSTRUCTOR_P): New macro.
+ * parse.y (kw_length): New static global tree node.
+ (return_statement): Tagged <node>.
+ (RETURN_TK): Tagged <operator>.
+ (variable_declarator_id:): Build variable declaration with an
+ empty initialization value if a syntax error was found in the
+ initialization part of the variable declaration.
+ (statement_without_trailing_substatement:): return_statement: now
+ uses the default rule.
+ (return_statement:): Temporarily fixed to return NULL_TREE.
+ (primary_no_new_array:): Call build_this when THIS_TK was parsed.
+ (class_instance_creation_expression:): Class creation rules now
+ call build_method_invocation upon reduction.
+ (array_creation_expression:): Rules call build_newarray_node upon
+ reduction.
+ (dim_exprs:): Build a list of dimension expressions.
+ (dim_expr:): Store location of the OSB_TK in the dimension
+ expression node.
+ (method_invocation:): Added a new error rule.
+ (build_unresolved_array_type): WFL argument may also be an array
+ on a primitive type. Name of the argument changed to reflect this.
+ (method_declarator): Insert argument type at the beginning of the
+ argument type list and later reverse the list.
+ (unresolved_type_p): Argument 'returned' may be optionally
+ NULL_TREE.
+ (java_layout_class_from_source): Function renamed
+ safe_layout_class.
+ (resolve_and_layout): Now call resolve_no_layout and
+ safe_layout_class.
+ (resolve_no_layout): New function.
+ (purify_type_name): New function.
+ (complete_class_report_errors): Call purify_type_name during error
+ report on a type not found.
+ (process_imports): error_found local variable doesn't need to be
+ initialized to zero.
+ (declare_local_variables): New local type_wfl. Fixed typo in error
+ message. type_wfl assigned to unresolved type and used to register
+ incomplete type. Build a WFL around the variable initialization
+ statement so that debug info can be generated on it.
+ (source_start_java_method): Reverse argument list after they've
+ been processed.
+ (current_this): New static global variable.
+ (java_complete_expand_methods): Set current_this when appropriate.
+ (resolve_expression_name): Build correct static and non static
+ field access bearing a simple name.
+ (resolve_field_access): Resolve the length field of arrays. Handle
+ f.m() cases.
+ (patch_method_invocation_stmt): Set the type of the method
+ invocation to error_mark_node. This value is later overridden by a
+ valid type, if any. Don't handle qualified constructor invocation
+ as qualified method invocation. Call lookup_method_invoke with its
+ new flag. It's no longer necessary to access the selected method
+ as the value of a tree list. Handle constructor invocation.
+ (patch_invoke): Reverse argument list when invoking non interface
+ methods. Insert call to new as the first argument of the
+ constructor.
+ (invocation_mode): Return a INVOKE_STATIC is the invoked method is
+ defined within a final class. Return INVOKE_STATIC if the invoked
+ method is a constructor.
+ (lookup_method_invoke): New lc argument is a flag to indicate a
+ constructor lookup. Now handle constructor lookup. Choose the most
+ specific method in case several were matching the invocation
+ requirements. Return a method decl instead of a tree list featuring
+ one single method decl element.
+ (refine_accessible_methods_list): New lc flag argument to
+ indicate that a constructor is being looked up.
+ (not_initialized_as_it_should_p): New function.
+ (java_complete_tree): Now process fake tree codes
+ JAVA_NEW_ARRAY_EXPR, JAVA_NEW_CLASS_EXPR and JAVA_THIS_EXPR. Call
+ save_expr on resolved function call arguments. Case on
+ UNARY_PLUS_EXPR changed into a case on JAVA_UNARY_PLUS_EXPR.
+ (patch_assignment): LHS can be a field access expression. When
+ dealing with reference, lhs_type is the promoted type of the
+ rhs_type, not the RHS. Use not_initialized_as_it_should_p where
+ applicable.
+ (operator_string): JAVA_UNARY_PLUS_EXPR replaces UNARY_PLUS_EXPR.
+ (patch_binop): Use not_initialized_as_it_should_p where
+ applicable.
+ (build_unaryop): JAVA_UNARY_PLUS_EXPR replaces UNARY_PLUS_EXPR.
+ (patch_unaryop): Likewise. And use not_initialized_as_it_should_p
+ where applicable.
+ (resolve_type_during_patch): New function.
+ (patch_cast): Call resolve_type_during_patch to resolve type and
+ report error accordingly.
+ (patch_array_ref): Use not_initialized_as_it_should_p where
+ applicable. Array base expression is saved before being
+ used. Promote the type of an array elements if it contains non
+ builtin types.
+ (build_newarray_node, patch_newarray, build_this): New functions.
+
+Thu Jul 16 10:46:47 1998 Tom Tromey <tromey@cygnus.com>
+
+ * gjavah.c (print_c_decl): UTF8_GET increments pointer; don't
+ increment it in `for' statement.
+ (print_field_info): If number is inf or nan, don't print it.
+ (print_method_info): If method name is `delete', just ignore it.
+ (print_c_decl): Special-case jstringArray.
+
+ * gjavah.c (help): New function.
+ (no_argument): New function.
+ (usage): Changed text.
+ (main): Rewrote argument handling. Now handles -v, --help,
+ --version.
+ (version): New function.
+ (found_error): New global.
+ (main): Return found_error.
+ (generate_access): Set found_error.
+ (print_c_decl): Likewise.
+
+Wed Jul 15 10:36:27 1998 Tom Tromey <tromey@cygnus.com>
+
+ * gjavah.c (print_c_decl): Don't print "," when examining field.
+ Skip type name when looking at "[L" types.
+ (process_file): Now static.
+ (generate_access): Now returns int.
+ (last_access_generated): New global.
+ (process_file): Clear last_access_generated; make multiple passes
+ over the class.
+ (print_field_info): Just return if generate_access returns true.
+ (print_method_info): Likewise. Also, allow <init> functions to
+ pass through.
+ (print_c_decl): Added is_init argument. Print constructors
+ properly.
+ (print_cxx_classname): Use UTF8_GET to extract characters from
+ string.
+ (print_base_classname): New function.
+ (print_class_decls): New function.
+ (process_file): Use it.
+ (utf8_cmp): New function.
+
+Mon Jul 13 14:21:47 1998 Nick Clifton <nickc@cygnus.com>
+
+ * lang-options.h: Format changed to match changes in gcc/toplev.c
+ to implement a --help option.
+
+1998-07-10 Brendan Kehoe <brendan@cygnus.com>
+
+ * decl.c (init_decl_processing): Revert change to dtable_type.
+
+Thu Jul 9 18:22:12 1998 Per Bothner <bothner@cygnus.com>
+
+ * java-tree.h (CLASS_P): Changed DECL_LANG_FLAG_7 -> TYPE_LANG_FLAG_4.
+
+1998-07-08 Brendan Kehoe <brendan@cygnus.com>
+
+ * decl.c (init_decl_processing): Set CLASS_LOADED_P on dtable_type.
+
+ * lang.c (lang_init): Default flag_exceptions to 1, without
+ checking to see if it's 2 first.
+
+Wed Jul 8 03:01:32 1998 Jeffrey A Law (law@cygnus.com)
+
+ * constants.c: Include "system.h".
+ * decl.c: Likewise.
+ * lang.c (flag_new_exceptions): Get via extern now.
+ (lang_init_options): New functions. Turn on flag_new_exceptions.
+
+Tue Jul 7 12:56:48 1998 Alexandre Petit-Bianco <apbianco@cygnus.com>
+
+ * lex.c (java_lex): Return 0 when we see an invalid character in
+ the input.
+
+ * lex.c (java_read_char): Specify extra argument when calling
+ java_lex_error.
+ (java_read_unicode, java_parse_end_comment,
+ java_parse_escape_sequence): Likewise,
+ (java_lex): Specify extra argument when calling
+ java_lex_error. Test that IDs are beginning with a legal character
+ for IDs. Handle invalid characters with an error message and a
+ call to java_lex_error.
+ (java_lex_error): Adjust column position by new argument
+ `forward'. Issue an error even if in the middle of reporting an
+ other error.
+
+1998-07-07 Brendan Kehoe <brendan@cygnus.com>
+
+ * jcf-io.c (find_class): Zero out BUFFER before we use it, since
+ we don't explicitly put a null pointer when we're copying it.
+
+Tue Jul 7 09:38:38 1998 Tom Tromey <tromey@cygnus.com>
+
+ * gjavah.c (print_cxx_classname): New function.
+ (super_class_name): Likewise.
+ (print_super_fields): Removed.
+ (in_super): Removed.
+ (print_field_info): Never generate #defines.
+ (print_c_decl): Changed generated types to match JNI. No longer
+ print class name before method name.
+ (print_method_info): Print "static" before static methods.
+ Print "virtual" before non-final methods.
+ (usage): Use exit(1), not exit(-1).
+ (main): Likewise.
+ (print_field_info): Use %.17g to print a double.
+ (last_access): New globals.
+ (process_file): Initialize last_access.
+ (usage): Now static.
+ (ACC_VISIBILITY): New define.
+ (generate_access): New function.
+ (print_field_info): Call it.
+ (print_method_info): Likewise. Also, generate information for all
+ methods, not just native methods. Return void.
+ (print_c_decl): Return void.
+ (print_field_info): Return void.
+
+Thu Jul 2 16:53:16 1998 Alexandre Petit-Bianco <apbianco@cygnus.com>
+
+ * Makefile.in (JAVABISONFLAGS): Specific flag for bison when
+ processing the jc1 grammar file. Prefix bison functions and
+ variables with java_.
+ (parse.c): Dependencies on parse.h and lex.h
+ * expr.c (build_java_arrayaccess): Function now global.
+ * java-tree.h: Comment reorganized to carry on previous
+ classification effort.
+ (RESOLVE_EXPRESSION_NAME_P, RESOLVE_PACKAGE_NAME_P,
+ RESOLVE_TYPE_NAME_P): New flags on WFLs.
+ * jcf-parse.c (parse_source_file): java_parse_source_file renamed
+ java_parse (new prefix java_ generated by bison).
+ (java_layout_parsed_class, java_register_parsed_class): Function
+ call removed.
+ (yyparse): Removed unnecessary call to init_outgoing_cpool.
+ * lex.c (static tree wfl_op): Variable deleted.
+ (java_init_lex): Initialize kw_super and kw_this. Initialize more
+ ctxp fields to NULL_TREE.
+ (java_lex): No longer create WFL for operators. Filename caching
+ mechanism deleted. Call BUILD_OPERATOR for `.', '(', '['. Strings
+ created as STRING_CST and later expanded. Removed extra argument
+ to BUILD_OPERATOR and BUILD_OPERATOR2. Build operators for THIS
+ and SUPER.
+ (build_wfl_node): Removed code in comments.
+ * lex.h (BUILD_OPERATOR, BUILD_OPERATOR2): No longer build a WFL but
+ store token and location data in the current bison token.
+ * parse.h: Removed pre-processor based symbol prefixes hack. Moved
+ static/extern function declaration at the beginning of the file.
+ (struct qualification): Data structure definition deleted.
+ (RESOLVE_CHAIN_REMAINDER): Macro definition deleted.
+ (qualify_ambiguous_name): Function declaration modified. Function
+ now returns nothing.
+ (build_array_ref, patch_array_ref, make_qualified_name,
+ resolve_qualified_expression_name, maybe_generate_clinit,
+ resolve_field_access): New static function declarations.
+ (build_java_arrayaccess): New extern function declaration.
+ (enum { RESOLVE_EXPRESION_NAME...}): Enum deleted.
+ (CALL_EXPR_PRIMARY): Macro deleted.
+ (EXPR_WFL_QUALIFICATION, QUAL_WFL, QUAL_RESOLUTION): New macros.
+ (struct parser_ctxt): Field initialized_final
+ removed. non_static_initialized, static_initialized: New fields.
+ * parse.y (static tree kw_super, static tree kw_this): New global
+ static.
+ (%union): tree wfl field of operator member replaced by int
+ location. WFLs are non longer created for operators.
+ (OSB_TK, DOT_TK, THIS_TK, SUPER_TK): Tagged <operator>.
+ (qualified_name:): Now calls make_qualified_name to build the
+ identifier.
+ (type_declaration:): Consider generating <clinit> when class
+ parsing completed.
+ (variable_declarator:): Directly build an assignment node when the
+ variable is initialized when declared.
+ (this_or_super:): Build a WFL and set current location when THIS
+ or SUPER are parsed.
+ (expression_statement:): Wrap statement around a WFL.
+ (primary_no_new_array:): Fixed typo. Changed value returned by
+ THIS_TK because of its new type (temporary).
+ (dim_exprs:): Temporary fix because of OSB_TK's new type.
+ (field_access:): Build qualified name with SUPER.
+ (method_invocation:): Fixed returned value because of SUPER's new
+ type.
+ (array_access:): Use OSB_TK location information.
+ (post_increment_expression:, post_decrement_expression:,
+ unary_expression:, pre_increment_expression:,
+ pre_decrement_expression:, unary_expression_not_plus_minus:,
+ cast_expression:, multiplicative_expression:,
+ additive_expression:, shift_expression:, relational_expression:,
+ equality_expression:, and_expression:, exclusive_or_expression:,
+ inclusive_or_expression:, conditional_and_expression:,
+ conditional_or_expression:, assignment:): Use new location/token
+ information available on operators.
+ (create_class): Set super_decl_type to NULL_TREE when processing
+ java.lang.Object.
+ (register_fields): Field initialization is now a MODIFY_EXPR
+ node. Chain initialization code to the matching lists (according
+ the the field declaration modifiers).
+ (maybe_generate_clinit): New function.
+ (method_header): Don't set method's DECL_NAME to a WFL when adding
+ methods to java.lang.Object.
+ (resolve_and_layout): Now can return NULL_TREE if the type
+ resolution fails. Otherwise, return the class DECL instead of its
+ TYPE.
+ (check_method_redefinition): Don't patch method DECL_NAME if it
+ belongs to java.lang.Object.
+ (process_imports): Simply assign error_found to the value returned
+ by check_pkg_class_access.
+ (declare_local_variables): Don't use their init statements (if
+ any) when parsing error were previously found. Reuse MODIFY_EXPR
+ build during parsing as an init statement.
+ (java_method_add_stmt): Now return the current method body.
+ (java_layout_parsed_class, java_register_parsed_class): Functions
+ removed.
+ (java_complete_expand_methods): Initialize the constant pool on a
+ per class basis. Layout the classes before expanding their method
+ bodies. Don't try expand artificial constructor code if error were
+ found. Make the classes data and register them if no error were
+ found.
+ (java_complete_expand_method): Retrieve an artificial constructor
+ argument list before entering its body. Assign the top block to
+ the artificial constructor function body and set types of declared
+ blocks and compound statements to void. Walk method body if not an
+ artificial constructor.
+ (make_qualified_name, cut_identifier_in_qualified): New functions.
+ (resolve_expression_name): Fixed comments. Save/restore the
+ current class CLASS_LOADED_P flag value. Build non qualified
+ static field access and handle qualified expression names.
+ (resolve_field_access, resolve_qualified_expression_name): New
+ functions.
+ (patch_method_invocation_stmt): Use the new expression resolution
+ scheme, calling resolve_field_access when the function call is
+ resolved as an expression.
+ (qualify_ambiguous_name): Function rewritten to work on qualified
+ expression produced by make_qualified_name.
+ (java_complete_tree): Promote type when function's argument are
+ RECORD_TYPEs. While processing the MODIFY_EXPR case: don't patch
+ the assignment to discover further errors if RHS is a expression
+ name that fails to evaluate. Declare LHS initialized even though
+ the assignment failed. Don't use the location variable and removed
+ extra argument in patch function calls. Now handle the ARRAY_REF
+ case and build internal string representation when STRING_CSTs are
+ walked.
+ (build_method_invocation): Don't wrap function call around a WFL.
+ (build_assignment): Likewise. Use the operator location
+ information.
+ (patch_assignment): Handle array access LHSs. Handle error
+ provenance, resulting in a better error report.
+ (build_binop): Use op_location from operator as binop location
+ information.
+ (build_unaryop, build_incdec, build_cast): Likewise.
+ (patch_binop): Extract location information from the node. Fixed
+ typo in error message.
+ (patch_unary_op): Extract location information from the node.
+ (build_array_ref, patch_array_ref): New functions.
+
+Wed Jul 1 13:11:36 1998 Tom Tromey <tromey@cygnus.com>
+
+ * expr.c (expand_java_INSTANCEOF): Changed calling convention to
+ match _Jv_IsInstanceOf.
+ * decl.c (init_decl_processing): Use _Jv_NewArray, not
+ soft_newarray. Use _Jv_IsInstanceOf, not soft_instanceof.
+
+Tue Jun 30 14:12:54 1998 Tom Tromey <tromey@cygnus.com>
+
+ * decl.c (init_decl_processing): Functions are now named
+ _Jv_MonitorEnter and _Jv_MonitorExit, and return jint.
+
+Mon Jun 29 14:47:10 1998 Per Bothner <bothner@cygnus.com>
+
+ * java-tree.h (load_class): Add prototype.
+ * class.c (is_compiled_class): Add missing arg to load_class.
+ * expr.c (expand_java_NEW): Call load_class.
+ * parse.y (process_import): Removed bogus use of void return value.
+
+Thu Jun 25 11:50:48 1998 Per Bothner <bothner@cygnus.com>
+
+ * decl.c, java-tree.h (soft_athrow_node): Renamed to soft_node.
+ Function name is "_Jv_Throw" instead of "soft_athrow".
+ * decl.c, java-tree.h (soft_new_node): Renamed to alloc_object_node.
+ Function name is "_Jv_AllocObject" instead of "soft_new".
+ Takes an extra parameter (object size).
+ * expr.c: Update calls.
+
+Wed Jun 24 13:59:02 1998 Per Bothner <bothner@cygnus.com>
+
+ * lex.c (java_get_line_col): Handle end-of-file.
+ * except.c (expand_end_java_handler): Handle null type (i.e. finally).
+
+Wed Jun 24 09:22:34 EDT 1998 Andrew MacLeod <amacleod@cygnus.com>
+
+ * lang.c (lang_init): Make -fexceptions the default.
+ * except.c (maybe_start_try, maybe_end_try): Don't do anything if
+ exception handling is not turned on.
+
+Tue Jun 23 10:17:09 EDT 1998 Andrew MacLeod <amacleod@cygnus.com>
+
+ * lang.c (flag_new_exceptions): Make this this default.
+ * decl.c (end_java_method): Call emit_handlers.
+ * except.c (method_init_exceptions): Set language code and version.
+ (expand_start_java_handler): Enable exception, and call
+ expand_eh_region_start.
+ (expand_end_java_handler): Enable exception, and set up catch blocks.
+ (emit_handlers): New routine to generate the saved handlers.
+ * java-except.h (emit_handlers): Add prototype.
+
+Fri Jun 12 11:31:24 1998 Per Bothner <bothner@cygnus.com>
+
+ We used to have three different representations of the constant pool:
+ the CPool structure, the tree_constant_pool, and the constructures
+ used to build the Class object (which may need class and string
+ constants) in compiled code. None were appropriate for compiling
+ to .class files, so I did a major overhaul.
+
+ First, the tree_constant_pool array was removed. Things were
+ modified to the CPool structure in the JCF could be used.
+ Second, a "capacity" field was added to the CPool, and functions
+ written to search for a matching constant, adding one if not found.
+ The code that generated the Class object was changed to use a CPool.
+ The actual TREE_LISTs used to build the CONSTRUCTORs used for
+ the static Class object are now only in build_constants_constructor.
+ Finally, I wrote code which can generate a .class file (including its
+ constant pool) from the RECORD_TYPE of a class. This is a big step
+ on the way to compiling Java source into .class files.
+
+ * jcf-write.c: New file. Writes out a RECORD_TYPE as a .class file.
+ * Makefile.in (JAVA_OBJS): Added jcf-write.o.
+
+ * java-tree.h (CPOOL_UTF, CONSTANT_ResolvedFlag,
+ CONSTANT_ResolvedString, CONSTANT_ResolvedClass): New macros.
+ (NAME_AND_TYPE_NAME, NAME_AND_TYPE_SIGNATURE, COMPONENT_REF_NAME,
+ COMPONENT_REF_NAME_AND_TYPE, COMPONENT_REF_SIGNATURE): Redefined.
+ (COMPONENT_REF_CLASS): Replaced by COMPONENT_REF_CLASS_INDEX.
+ (lang_type): Removed constant_pool field.
+ * jcf.h (CPool): Renamed size to count. Added field capacity.
+ (CPOO_COUNT, CPOOL_UINT, CPOOL_USHORT1, CPOOL_USHORT2,
+ CPOOL_FINISH, CPOOL_INIT, CPOOL_REINIT): New macros.
+ Rewrite some of the old JCF_XXX in terms of CPOOL_XXX macros.
+
+ * constants.c (current_constant_pool_tags, current_constant_pool_data,
+ current_constant_pool_length), java-tree.h: Replaced by outgoing_cpool.
+ * constants.c (build_constants_constructor): Use new outgoing_cpool.
+ (set_constant_entry, find_constant1, find_constant2,
+ find_class_constant, count_constant_pool_bytes, write_constant_pool,
+ find_utf8_constant, find_class_or_string_constant): New functions.
+
+ * jcf-parse.c (load_class): Don't save/restore tree-constant_pool.
+ (get_constant): Use current_jcf.cpool instead of tree_constant_pool.
+ (give_name_to_class, get_class_constant): Likewise.
+ * jcf-parse.c, java-tree.h (tree_constant_pool): Removed.
+ (get_name_and_type_constant, get_ref_constant): Removed.
+ * parse.h (parser_ctxt): Remove field tree_constant_pool.
+ * parse.y: Don't save/restore tree_constant_pool.
+ * verify.c (verify_jvm_instructions): Update for new approach.
+ * expr.c (expand_invoke, expand_java_field_op): Likewise.
+
+ * lang-options.h: Added -femit-class-file, -femit-class-files.
+ * lang.c (flag_emit_class_files), java-tree.h: New flag.
+ (lang_f_options): Added "emit-class-file(s)".
+
+ * expr.c (build_java_arrayaccess): Generate more efficient array
+ bounds checking, by using unsigned compare.
+
+ * expr.c (expand_invoke): Re-arrange error checks to make more robust.
+
+Wed Jun 10 17:34:42 1998 Alexandre Petit-Bianco <apbianco@cygnus.com>
+
+ * parse.h: New comment on the handling of unresolved type
+ identifiers. JDEPs are now part of the jdep_code enum.
+ (typedef struct jdep): Now use enum jdep_code or int, depending on
+ availability. Both are narrowed down to an 8 bits bitfield.
+ (CALL_EXPR_PRIMARY): Fixed comment.
+
+Wed Jun 10 10:54:39 1998 Tom Tromey <tromey@cygnus.com>
+
+ * Make-lang.in (java): Added gjavac and jvgenmain.
+ (java.start.encap): Depend on gjavac.
+ (java.rest.encap): Depend on jvgenmain.
+
+ * Make-lang.in (JAVA_INSTALL_NAME): Name is gjavac, not c++.
+ (JAVA_CROSS_NAME): Likewise.
+ (java.all.build): Depend on jvgenmain and gjavac.
+ (java.all.cross): Depend on jvgenmain and gjavac-cross.
+ (jvgenmain$(exeext)): New target.
+ (java.install-common): Wrote.
+ * config-lang.in (compilers, stagestuff): Added gjavac and
+ jvgenmain.
+
+Wed Jun 10 12:19:04 1998 Dave Brolley <brolley@cygnus.com>
+
+ * lang.c (lang_decode_option): New argc/argv interface.
+
+Tue Jun 9 18:12:46 1998 Alexandre Petit-Bianco <apbianco@cygnus.com>
+
+ * ChangeLog: Fixed entries not compliant with the Gnu Coding Standard.
+ * decl.c (build_decl_no_layout): New function.
+ * expr.c (java_lang_expand_expr): Layout declarations found in
+ blocks before they're pushed.
+ * jcf-parse.c (load_class): Save current line when parsing class
+ file.
+ (parse_source_file): Register class before expanding their
+ methods.
+ * lang.c (put_decl_node): Produce `null' when `void *' is
+ processed.
+ * lex.c (static tree wfl_op): New static global, for error report
+ on casts.
+ (java_init_lex): wfl_operator and wfl_op initialized
+ here. Filename caching added for wfl_op. Return wfl_op when `(' is
+ parsed.
+ * parse.h (build_unaryop, build_incdec, patch_unaryop, build_cast,
+ patch_cast, valid_ref_assignconv_cast_p, can_cast_to_p,
+ build_unresolved_array_type): New static function definitions.
+ (build_decl_no_layout): New extern function declared.
+ (OBSOLETE_MODIFIER_WARNING): Report error only if the WFL of the
+ faulty modifier exists.
+ (TYPE_INTERFACE_P, TYPE_CLASS_P): New macros.
+ (ERROR_CAST_NEEDED_TO_INTEGRAL): Error message tuned.
+ (UNARY_PLUS_EXPR): New fake operator.
+ (struct parser_ctxt): New field osb_number.
+ * parse.y (static tree wfl_operator): New static WFL for operator
+ bound error messages.
+ (DECR_TK, INCR_TK): Moved.
+ (OP_TK): Tagged <operator>.
+ (array_type:): Now call build_unresolved_array_type.
+ (dim_expr:): Count the number of '[' seen.
+ (post_increment_expression, post_decrement_expression,
+ pre_increment_expression, pre_decrement_expression,
+ unary_expression_not_plus_minus, unary_expression:): Actions are
+ now building the corresponding unary expressions.
+ (cast_expression:): Actions are now building cast expressions.
+ (build_unresolved_array_type): New function.
+ (create_interface): Reset the number of declared interfaces.
+ (create_class): Likewise.
+ (method_header): Methods declared within the scope of an interface
+ are now implicitly set public and abstract.
+ (java_complete_class): Variable's and parameter's type are patched
+ with a promoted type.
+ (declare_local_variables): Resolved non builtin types are promoted
+ before being used to build a variable decl. Removed type patch
+ posted on variable initialization statement.
+ (source_start_java_method): Use build_decl_no_layout to build the
+ decl of a parameter of incomplete type.
+ (java_register_parsed_class): Process interfaces too. Call
+ rest_of_decl_compilation on each processed class declarations.
+ (java_complete_expand_methods): Don't attempt to expand things in
+ interfaces.
+ (java_complete_tree): Process CONVERT_EXPR, even though it always
+ has a type. Propagate error_mark_node to node's type too. Promote
+ method's call argument type and return error_mark_node if
+ argument's completion didn't work. MODIFY_EXPR can have a WFL as a
+ RHS. Fixed bug in the handling of bogus RHS of a fixed type. Now
+ handle unary operator nodes.
+ (build_assignment): Added comment.
+ (print_int_node): New function.
+ (patch_assignment): New second argument. New error handling. Use
+ print_int_node. Handle references. Use can_cast_to_p to issue
+ different error message according to the context and check upon
+ the initialization of the RHS.
+ (can_cast_to_p, valid_ref_assignconv_cast_p): New functions.
+ (operator_string): Handle more operators.
+ (patch_binop): No longer use a function static
+ wfl_operator. Improved error message on shift distance.
+ (build_unaryop, build_incdec, build_cast, patch_unaryop,
+ patch_cast): New functions.
+
+Fri Jun 5 18:03:07 1998 Per Bothner <bothner@cygnus.com>
+
+ * jvspec.c: New file.
+ * Make-lang.in: New rules to build gjavac from jvspec.c and ../gcc.c.
+
+ * java-tree.h (identifier_subst): Add declaration.
+
+Thu Jun 4 13:44:23 1998 Tom Tromey <tromey@cygnus.com>
+
+ * jvgenmain.c (main): Generate call to JvRunMain.
+
+ * class.c (make_class_data): Push value for "sync_info" field.
+ * decl.c (init_decl_processing): Push "sync_info" field.
+
+Wed Jun 3 20:39:14 1998 Per Bothner <bothner@cygnus.com>
+
+ * typeck.c (build_java_array_type): Set TYPE_NAME to actual
+ Java (source) name, not signature.
+ Set TYPE_ALIGN to (at least) that of element_type.
+
+Tue Jun 2 15:19:19 1998 Per Bothner <bothner@cygnus.com>
+
+ * class.c: Moved classname-mangling-rekated code to ...
+ * mangle.c: ... this new file.
+ * jvgenmain.c: New program (needs mangle.c) to generate main program.
+ * Makefile.in: Update for above changes.
+
+Mon Jun 1 09:58:36 1998 Alexandre Petit-Bianco <apbianco@cygnus.com>
+
+ * expr.c (truthvalue_conversion): Convert integer and floating
+ point value to their truth value.
+ * lex.c (java_lex): Handle the `null' literal.
+ * parse.h (JREFERENCE_TYPE_P, DECL_P): New macros.
+ (ERROR_CANT_CONVERT_TO_BOOLEAN, ERROR_CANT_CONVERT_TO_NUMERIC,
+ ERROR_CAST_NEEDED_TO_INTEGRAL, ERROR_VARIABLE_NOT_INITIALIZED):
+ New macros.
+
+ * parse.y: Reorganization/documentation on token declaration.
+ (binop_lookup[]): New added new tree codes.
+ (relational_expression): Build corresponding binary operators.
+ (equality_expression, conditional_and_expression,
+ conditional_or_expression): Likewise.
+ (java_complete_class): Fix crash in debug message.
+ (java_complete_tree): Check initialization of method call
+ arguments. Further bogus node evaluation to detect more error
+ during assignments. Handles more binary operators.
+ (patch_assignment): Use DECL_P.
+ (build_binop): Fix crash when using URSHIFT_EXPR, a Java only tree
+ code.
+ (operator_string): Handle more case. Compacted source.
+ (patch_binop): Changed function comment. Checking for
+ uninitialized first operand takes the compound assignment into
+ account and uses DECL_P. Checking for uninitialized second operand
+ delayed to routine's end. Use macros to issue type bound error
+ messages and issue messages on both operands if their types are
+ different. Force fixed type into node. Handle all binary
+ operators.
+
+Wed May 27 10:30:31 1998 Alexandre Petit-Bianco <apbianco@cygnus.com>
+
+ * java-tree.h (COMPOUND_ASSIGN_P, INITIALIZED_P): New macros.
+ * lex.c (java_lex): Use BUILD_OPERATOR and BUILD_OPERATOR2 to
+ build operator node and return tokens.
+ * lex.h (BUILD_OPERATOR, BUILD_OPERATOR2): New macros.
+ * parse.h (java_complete_tree): Changed returned type in prototype.
+ (build_method_invocation, build_assignment, patch_assignment,
+ patch_binop): New static function declarations.
+ (JFLOAT_TYPE_P, JNUMERIC_TYPE_P, JPRIMITIVE_TYPE_P, JSTRING_P,
+ BUILD_EXPR_WFL): New macros.
+ * parse.y (enum tree_code binop_lookup[]): New static for token to
+ TREE_CODE lookup.
+ (%union): Parser union has new sub-structure `operator'.
+ (ASSIGN_TK, MULT_ASSIGN_TK, DIV_ASSIGN_TK, REM_ASSIGN_TK,
+ PLUS_ASSIGN_TK, MINUS_ASSIGN_TK, LS_ASSIGN_TK, SRS_ASSIGN_TK,
+ ZRS_ASSIGN_TK, AND_ASSIGN_TK, XOR_ASSIGN_TK, OR_ASSIGN_TK,
+ ASSIGN_ANY_TK): Tokens tagged `operator'.
+ (EQ_TK, GTE_TK, ZRS_TK, SRS_TK, GT_TK, LTE_TK, LS_TK, BOOL_AND_TK,
+ AND_TK, BOOL_OR_TK, OR_TK, INCR_TK, PLUS_TK, DECR_TK, MINUS_TK,
+ MULT_TK, DIV_TK, XOR_TK, REM_TK, NEQ_TK, NEG_TK, REL_QM_TK,
+ REL_CL_TK, NOT_TK, LT_TK): Tokens tagged `operator'.
+ (assignment_operator:): Rule tagged `operator'.
+ (expression_statement:): Re-installed default rule.
+ (method_invocation:): Sub rules call build_method_invocation.
+ (postfix_expression:): Don't attempt to resolve name here. Just
+ return an ID.
+ (multiplicative_expression:): Sub-rules build corresponding binop
+ expression node.
+ (additive_expression:, shift_expression:, and_expression:,
+ exclusive_or_expression:, inclusive_or_expression:): Likewise.
+ (assignment:): Sub rule invoke build_assignment.
+ (assignment_operator:): Default rules on sub rules.
+ (force_error): Added documentation on this variable.
+ (declare_local_variables): Build initialization calling
+ build_assignment.
+ (expand_start_java_method): Removed unused rtx declaration. Mark
+ arguments as already initialized.
+ (java_method_add_stmt): Type of built COMPOUND_EXPR set to NULL.
+ (java_complete_expand_methods): Don't process next method if
+ completion of the previous one triggered errors.
+ (java_complete_expand_method): Call source_end_java_method if no
+ error were found during completion.
+ (resolve_expression_name): Use IDENTIFIER_LOCAL_VALUE to retrieve
+ locals declaratilon. Handle names found within a class. Return
+ error_mark_node when things aren't found.
+ (patch_method_invocation_stmt): Return error_mark_node on failures.
+ (patch_invoke): Removed unused local. Return the correct node.
+ (java_complete_tree): Now returns a value. The BLOCK section binds
+ local identifiers and the type of a BLOCK is now void. Assign the
+ result of operand completion on COMPOUND_EXPR. Assign the
+ encapsulated node of a WFL to the result of its completion, except
+ when the node is an identifier. Now handle MODIFY_EXPR and several
+ binary operators. Return error_mark_node on errors.
+ (build_method_invocation, build_assignment, patch_assignment,
+ build_binop, operator_string, patch_binop): New functions.
+ * typeck.c (binary_numeric_promotion): New function.
+
+Thu May 21 12:01:04 1998 Per Bothner <bothner@cygnus.com>
+
+ * class.c (identifier_subst): New convenience wrapper for ident_subst.
+ Replace most uses of ident_subst by identifier_subst.
+
+ * class.c (push_class_static_dummy_field): Removed function.
+ (build_class_ref): Find Class object decl by looking up "CNAME.class",
+ instead of looking got "class" static field. Create that decl here.
+ (class_identifier_node): Removed; no longer needed.
+ (init_class_processing): Don't init class_identifier_node.
+ * jcf-parse.c (jcf_parse): Don't call push_class_static_dummy_field.
+ Do nreverse 0 times (instead of twice) for Object and Class.
+ * parse.y (java_layout_parsed_class): No push_class_static_dummy_field.
+
+Wed May 20 16:35:04 1998 Per Bothner <bothner@cygnus.com>
+
+ * jcf-parse.c (parse_class-file): Set lino to smallest line number,
+ while initializing linenumber_count and linenumber_table.
+ Do it before init_function_start (which calls emit_line_note).
+ * expr.c (expand_byte_code): Don't need to clear lineno here.
+
+Mon May 18 16:23:32 1998 Tom Tromey <tromey@cygnus.com>
+
+ * class.c (append_gpp_mangled_type): If `qualifications' is >=9,
+ then mangle number as _N_.
+
+ * class.c (mangle_class_field): New function.
+ (build_class_ref): Set assembler name of class reference using
+ mangle_class_field.
+ (push_class_static_dummy_field): Likewise.
+
+Sun May 17 12:52:35 1998 Michael Tiemann <tiemann@cygnus.com>
+
+ * parse.y (source_start_java_method): Use TREE_SET_CODE instead
+ of assigning to TREE_CODE. The latter method exploits a feature
+ of GCC that is not ANSI compliant.
+
+Thu May 12 13:44:27 1998 Alexandre Petit-Bianco <apbianco@cygnus.com>
+
+ * decl.c (pushdecl_force_head): New function.
+ (pushlevel): Removed conditional printf.
+ (complete_start_java_method): Don't enter local variable scope if
+ function is compiled from source code.
+ * expr.c: parse.h now included
+ (java_lang_expand_expr): New function.
+ * jcf-io.c (find_class): Use SOURCE_FRONTEND_DEBUG instead of
+ printf. Terminate buffer when doing directories.
+ * jcf-parse.c (parse_source_file): Call lang_init_source before
+ parsing and before code generation.
+ * jcf.h (SOURCE_FRONTEND_DEBUG): Macro redefined to conditionally
+ use printf if the macro is defined.
+ * lang.c (lang_init): Install lang_expand_expr hook on
+ java_lang_expand_expr.
+ (java_dummy_print): New function.
+ (lang_init_source): New function.
+ * lex.c (java_lex): Remember location of an opening brace at the
+ second nesting level.
+ (java_is_eol): Unget character seen after a CR if it is EOF.
+ * parse.h: Now includes lex.h
+ (SOURCE_FRONTEND_DEBUG): Macro redefined to conditionally use
+ printf if the macro is defined.
+ (expand_start_java_method, build_expr_block, enter_block,
+ exit_block, lookup_name_in_blocks, maybe_absorb_scoping_blocks):
+ New static function declarations.
+ (pushdecl_force_head): New extern function declaration.
+ (INCOMPLETE_TYPE_P): New macro.
+ (JDEP_PARM, JDEP_TYPE): New entries in JDEPs enum.
+ (BLOCK_CHAIN_DECL, BLOCK_EXPR_DECLS, BLOCK_EXPR_BODY,
+ BLOCK_EXPR_ORIGIN): New macros.
+ (DECL_SOURCE_LINE_MERGE, DECL_SOURCE_LINE_FIRST,
+ DECL_SOURCE_LINE_LAST): New macros.
+ (struct parser_ctxt): Removed field current_method_decl, redundant
+ with the field current_function_decl. Added fields
+ first_ccb_indent1 and pending_block.
+ * parse.y (method_body, literal, INT_LIT_TK, FP_LIT_TK,
+ BOOL_LIT_TK, CHAR_LIT_TK, STRING_LIT_TK, NULL_TK, VOID_TK): Rules
+ tagged <node>
+ (SOURCE_FRONTEND_DEBUG): Used as macro accepting varargs.
+ (compilation_unit:): Cosmetic on sub rule.
+ (type_declaration:): Cosmetic on sub rules. Added an error rule.
+ (variable_initializer:): Installed default rule on expression:.
+ (method_declaration:): method_header: starts a new
+ method. method_body: installs the function body, absorbs blocks
+ emitted for temporary variable scopings, pops function's body block
+ and merges function's last statement lineno in DECL_SOURCE_LINE.
+ (method_body:): Installed default rules.
+ (block:): Call enter_block when an opening brace is seen. Absorb
+ scoping blocks and call exit_block when a closing brace is seen.
+ (block_statement:): Cosmetic changes.
+ (method_invocation:): Create WFL around CALL_EXPR node.
+ (patch_stage): Added comment around definition.
+ (method_header): Try to use first_ccb_indent1 as the first line of
+ the method, so BP debug info are emitted at the first opening
+ brace of the function. If the function has no body, use the
+ location of the function's name. Override currently defined method
+ name with the matching WFL so we can point redefinition errors
+ using the location where the function's name was declared.
+ (check_abstract_method_header): Interprets DECL_NAME as an
+ identifier or as a WFL, accordingly.
+ (java_complete_class): New cases for JDEP_TYPE and JDEP_PARM.
+ (check_method_redefinition): Use DECL_NAME as a WFL. Extract
+ location and name information out of it and reinstall DECL_NAME to
+ its original identifier node value.
+ (lookup_cl): Use DECL_SOURCE_LINE_FIRST (first line of the
+ function's source code).
+ (read_import_dir): Test the value returned by find_class and issue
+ a fatal accordingly.
+ (declare_local_variables): Push a new block for the scope of the
+ new variable(s) if code has been already generated at that nesting
+ level. Pinpoint redefinition errors using the variable id
+ WFLs. Generate initialization code if necessary. If the variable
+ type is incomplete, register a patch on its decl.
+ (source_start_java_method): Rewritten. Define a new block for the
+ function's parameters. Build parameter decl out of function's
+ arguments and register them for a patch if their types are
+ incomplete.
+ (expand_start_java_method): Includes the part of
+ source_start_java_method that was pushing the parameter decls and
+ completing the method start code.
+ (source_end_java_method): Removed call the expand_end_bindings and
+ poplevel (already taken care of). Reinstall function's arguments
+ and get function's last line of code before calling
+ expand_function_end.
+ (java_method_add_stmt): New comment before the function's
+ code. Complement the second operand of the current COMPOUND_EXPR
+ if necessary.
+ (java_complete_expand_methods): Don't generate debug info on line
+ zero when expanding a generated constructor.
+ (java_complete_expand_method): Set start and end line numbers for
+ a artificially generated constructor to one and manually call
+ enter_block and exit_block when defining it. For all methods:
+ expand function's start calling the new expand_start_java_method
+ and invoke java_complete_tree on the effective method's body, if
+ any.
+ (resolve_expression_name): Now use lookup_name_in_blocks to search
+ local variable decls and print out an error when variables are
+ undefined.
+ (patch_method_invocation_stmt): Inserted comment before the
+ function's code.
+ (lookup_method_invoke): Chain method's arguments using chainon
+ with the current arg list as a second argument. Inserted missing
+ IDENTIFIER_POINTER when reporting an error on methods not found.
+ (refine_accessible_methods_list): Don't retain constructors.
+ (patch_arguments): Function removed.
+ (java_complete_tree): Inserted comment before the function's
+ code. New case for BLOCKs. Moved the WFL case a bit
+ further. Complete function's arguments.
+ (build_expr_block, enter_block, exit_block, lookup_name_in_blocks,
+ maybe_absorb_scoping_blocks): New functions.
+
+Mon Apr 27 10:50:05 1998 Alexandre Petit-Bianco <apbianco@cygnus.com>
+
+ * jcf-io.c (find_class): Reset jcf->java_source after JCF_ZERO, if
+ previously set.
+ * jcf-parse.c (parse_source_file, java_error_count): New forward
+ and extern declarations.
+ (java_parse_abort_on_error): Macro moved.
+ (jcf_parse_source): fatal called if fopen fails. Now calls
+ parse_source_file.
+ (parse_source_file): New parse_only parameter. Reflects the
+ elimination of the second pass.
+ (yyparse): parse_source_file called with argument set to 0.
+ * jcf.h (JCF_ZERO): Sets java_source to zero.
+ * lex.c (java_init_lex): pass argument is gone. Function modified
+ to be called once during the analysis of a file.
+ (java_unget_unicode): Fixed typo in fatal message.
+ (java_get_line_col): Likewise.
+ (java_lval): Likewise. String literals no longer built during
+ second pass.
+ * lex.h (JAVA_COLUMN_DELTA): Take the tabulation character into
+ account.
+ * parse.h (MODIFIER_WFL): New macro.
+ (parse_check_super, parser_check_super_interface): Now return int.
+ (parser_chain_incomplete_item, not_builtin_p,
+ complete_method_decl): Declarations removed.
+ (build_method_invocation_stmt, build_invoke): Renamed using the
+ `patch' instead of `build'
+ (register-incomplete_type, obtain_incomplete_type,
+ java_complete_tree, java_complete_expand_method,
+ unresolved_type_p, create_jdep_list): New function declarations.
+ (IC_TYPE, IC_DEPEND, DEPEND_DECL, DEPEND_WFL, BEGIN_ONLY_PASS,
+ END_ONLY_PASS, ELSE_ONLY_PASS): Macro deleted.
+ (jdep): New typedef on new struct _jdep.
+ (JDEP_DECL, JDEP_DECL_WFL, JDEP_KIND, JDEP_SOLV, JDEP_WFL,
+ JDEP_MISC, JDEP_APPLY_PATCH, JDEP_GET_PATCH, JDEP_CHAIN,
+ JDEP_TO_REVOLVE, JDEP_RESOLVED_DECL, JDEP_RESOLVED,
+ JDEP_RESOLVED_P): New macros.
+ (JDEP_NO_PATCH, JDEP_SUPER, JDEP_FIELD, JDEP_METHOD,
+ JDEP_METHOD_RETURN, JDEP_METHOD_END, JDEP_INTERFACE,
+ JDEP_VARIABLE): New enum values and jdep kinds.
+ (jdeplist): New typedef on struct _jdeplist.
+ (CLASSD_FIRST, CLASSD_LAST, CLASSD_CHAIN, JDEP_INSERT): New
+ macros.
+ (CALL_EXPR_PRIMARY): New macro.
+ (struct parser_ctxt): Fields java_pass, current_method_decl,
+ method_decl_list deleted. New field jdeplist.
+ (INCOMPLETE_P): Macro deleted.
+ * parse.y (single_type_import_declaration:): Removed pass switch.
+ (type_import_on_demand_declaration): Likewise.
+ (field_declaration:): Removed pass switch on all sub rules.
+ (class_declaration:): Call the complete_class_decl removed on
+ class_body rules.
+ (method_declaration:): Removed second pass switch. No longer chain
+ methods decl when method_header reduced.
+ (method_header:): Sub rules no longer depend on pass switch.
+ (method_declarator:): Likewise.
+ (method_body:): Likewise.
+ (abstract_method_declaration:): Likewise.
+ (block_statement:): Likewise.
+ (local_variable_declaration:): Likewise.
+ (argument_list:): Likewise.
+ (method_invocation:): Likewise. Call to build_method_invocation_stmt
+ removed. Partial CLASS_EXPR tree node built instead.
+ (postfix_expression:): Removed pass switch on all sub rules.
+ (java_pop_parser_context): Free classd_list content.
+ (yyerror): Call obstrack_grow0 to finalize error message.
+ (check_class_interface_creation): Comment modified to reflect new
+ returned value meaning. Removed second pass switch. Return 1 if an
+ error was found, 0 otherwise. Adjust pointer on filename if a
+ leading path separator was found.
+ (maybe_create_class_interface_decl): Removed first pass switch
+ when linking the class decl to the class_list. Install a new
+ jdep_list for the class.
+ (add_superinterfaces): List of unresolved interfaces is
+ gone. Unresolved interfaces are directly added to the current
+ dependencies list.
+ (create_interface): Second pass shortcut removed.
+ ctpx->modifier_ctx access through MODIFIER_WFL.
+ (create_class): Second pass shortcut removed. Call to
+ register_incomplete_type replaces the call to
+ parser_chain_incomplete_item.
+ (complete_class_decl): Function removed.
+ (duplicate_declaration_error): New way of retrieving redeclared
+ item type.
+ (register_fields): Call to lookup_modifier_cl replaced by
+ MODIFIER_WFL. New way of handling unresolved type, using
+ unresolved_type_p and obtain_incomplete_type.
+ register_incomplete_type replaces call to parser_chain_incomplete_item.
+ (patch_stage): New static global variable.
+ (method_header): New way of handling unresolved type, using
+ unresolved_type_p and obtain_incomplete_type. patch_stage used to
+ indicates that the method decl needs to be patched.
+ (check_abstract_method_header): Call to lookup_modifier_cl
+ replaced by MODIFIER_WFL.
+ (method_declarator): Incomplete argument type are registered
+ calling register_incomplete_type. Patch on the declared method is
+ issued in that case.
+ (unresolved_type_p): New function.
+ (parser_check_super_interface): New comment to reflect function's
+ modified returned type (int). Function and has a new argument
+ this_wfl. Call to parse_error_context uses this_wfl instead of
+ relying on lookup_cl.
+ (parser_check_super): Comment reflects function's new returned
+ type (int). Function returns non zero value on error.
+ (create_jdep_list, reverse_jdep_list, obtain_incomplete_type,
+ register_incomplete_type, jdep_resolve_class): New functions to
+ handle incomplete types in declarations.
+ (java_complete_class): Rewritten to work with the new incomplete
+ type handling scheme.
+ (complete_class_report_errors): Likewise.
+ (complete_method_decl): Removed: it jobs is now handled by
+ java_complete_class.
+ (do_resolve_class): Class loaded in not already loaded and not
+ found in Java source code.
+ (java_check_regular_methods, java_check_abstract_methods): Don't
+ call complete_method_decl anymore.
+ (lookup_modifier_cl, not_builtin_p): Functions deleted.
+ (read_import_dir): Got rid of the pass number dependency.
+ (declare_local_variables): New handling of unresolved types (patch
+ issued).
+ (source_start_java_method): New parameter level. Function called
+ with level set to 1 when argument types are potentially
+ unresolved. Called to complete the job with level set to 2 once
+ types are complete.
+ (source_end_java_method): Call to permanent_allocation
+ removed. Waiting to be replaced by a more suitable obstack
+ management.
+ (java_complete_expand_methods, java_complete_expand_method,
+ java_expand_finals): New functions.
+ (build_method_invocation_stmt): Renamed
+ patch_method_invocation_stmt. Extracts function call expression
+ (wfl) and arguments (args) from CALL_EXPR tree operands.
+ (build_invoke): Renamed patch_invoke. Fixed typo in fatal
+ call. Patch the function and argument operand of the CALL_EXPR
+ tree argument.
+ (patch_argument, java_complete_tree): New functions.
+
+Mon Apr 20 18:26:57 1998 Per Bothner <bothner@cygnus.com>
+
+ Recover from missing fields and methods (i.e. error instead of fatal).
+ * decl.c, java-tree.h (TYPE_identifier_node): New global constant.
+ * expr.c (expand_invoke): Recover from missing method.
+ (expand_java_field_op): Recover from missing field.
+ Inline references to java.lang.{Integer,Char,...}.TYPE.
+ * typeck.c (get_type_from_signature), java-tree.h: New function.
+ * class.c (add_method): Use get_type_from_signature.
+ (build_class_ref): Handle a class that was not found.
+ * typeck.c (convert): Handle conversion to pointers (for convenience).
+ * verify.c (verify_jvm_instructions): Use get_type_from_signature
+ instead of lookup_field to handle missing fields.
+
+ * jcf-parse.c (process_zip_dir): Set java_source.
+
+1998-04-20 Brendan Kehoe <brendan@cygnus.com>
+
+ * jcf-parse.c (set_source_filename): Use TYPE_NAME, not DECL_NAME.
+
+Tue Apr 14 15:59:54 1998 Alexandre Petit-Bianco <apbianco@cygnus.com>
+
+ * jcf-parse.c (load_class): Don't change input_filename before
+ calling jcf_parse_source (but still do it before calling
+ jcf_parse).
+ (jcf_parse_source): Assign input_filename after having saved the
+ parser context.
+ * lex.c (java_init_lex): Chain a WFL node to the import on demand
+ list. ctxp->modifier_ctx zeroed according to its new
+ definition. ctxp->filename initialized. Removed
+ JAVA_MODIFIER_CTX_UNMARK.
+ (java_unget_unicode): Update the character based column position.
+ (java_allocate_new_line): ref_count not used anymore. Always free
+ ctxp->p_line. Initialize c_line->char_col to 0.
+ (java_get_unicode): Update the character based column position.
+ (java_lex): Use ctxp->elc to store current position in source
+ file, at the beginning of the parsed token. Set modifier_ctx entry
+ corresponding to the parse modifier to a WFL node. Return a WFL
+ node when an identifier is parsed.
+ (java_lex_error): Now uses ctxp->elc to store current position in
+ source.
+ (build_wfl_node, java_is_eol, java_get_line_col): New functions.
+ * lex.h (build_wfl_node): New function definitions.
+ (struct java_line): ref_count and next fields are gone. New field
+ char_col.
+ (JAVA_LINE_CHECK, JAVA_LINE_MARK, JAVA_LINE_CHAIN,
+ JAVA_LINE_UNMARK, ID_NAME, ID_CL): Macro definitions deleted.
+ (JAVA_COLUMN_DELTA): New macro.
+ (java_lc): New typedef on new struct _java_lc.
+ * parse.h (lookup_cl, lookup_modifier_cl): Changed returned types.
+ (parse_error_context, parse_warning_context): Changed prototypes.
+ (java_get_line_col): Added as an available global function.
+ (JAVA_MODIFIER_CTX_UNMARK): Macro removed.
+ (IC_DECL): Replaced by macro IC_TYPE
+ (DEPEND_WFL): New macro.
+ (THIS_MODIFIER_ONLY): Now works with WFL and only remembers the first
+ wrong modifier.
+ (exit_java_complete_class): Removed a commented out statement.
+ (struct parser_ctxt): Added comments on fields. modifier_ctx is
+ now an array of tree nodes. Deleted fields line_list and
+ e_line. New field elc, to replace e_line.
+ * parse.y (array_type:): Build WFL node.
+ (qualified_name:): Build a single WFL node out of two. Retain
+ the location information of the first node in the resulting node.
+ (package_declaration:): Use package name as a WFL node
+ (single_type_import_declaration:): Use imported name as a WFL node.
+ (type_import_on_demand_declaration:): Use root of the imported
+ packages as a WFL node.
+ (field_declaration:): Removed unused local variable cl.
+ (method_declaration:): Don't call JAVA_MODIFIER_CTX_UNMARK.
+ (yyerror): New static elc. Removed static error_line, error_pos.
+ New local code_from_source. Save ctxp->elc into elc at the first
+ pass. Call java_get_line_col to get a string of the line where
+ the error occured.
+ (debug_line): Removed static function.
+ (parse_error_context, parse_warning_context): Parameter cl is now
+ a WFL node. Use its value to initialize ctxp->elc.
+ (redefinition_error): Parameter cl is now a WFL node.
+ (parse_add_interface): New parameter wfl. No longer call
+ lookup_cl, use wfl instead.
+ (check_class_interface_creation): Parameter cl is now a WFL node.
+ (maybe_create_class_interface_decl): Likewise.
+ (add_superinterfaces): New function.
+ (create_interface): Removed local cl, node, super_decl,
+ super_decl_type. Function now uses id as a WFL node. Better
+ warning/error report on obsolete or forbidden mix of
+ modifiers. Now calls add_superinterfaces to register interfaces.
+ (create_class): Removed local cl, node. Local variable id is used
+ as a WFL node. Better error report on forbidden modifier
+ mix. Uses add_superinterfaces to register interfaces.
+ (find_field): Argument cl is now a WFL node. Now store the WFL
+ node of a fields that needs to be checked for their
+ initialization.
+ (method_header): Local variable node non longer used. Local
+ variable id replaces cl.
+ (check_modifiers_consistency): Local variable cl is now a WFL
+ node.
+ (method_declarator): Local variable cl replaced by parameter id.
+ (parser_qualified_name): Now uses parameter name as a WFL node.
+ (parser_check_super_interface): New parameter wfl, for achieve
+ greater accuracy during error reports.
+ (parser_chain_incomplete_item): New parameter named location. Used,
+ along the decl, to construct the incomplete item node.
+ (java_complete_class): resolve_class now uses WFL node extracted
+ from the incomplete item node. Macro IC_TYPE replaces TREE_PURPOSE
+ where appropriate.
+ (complete_method_decl): Unresolved function's argument types are WFL.
+ (resolve_class): Parameter cl is now a WFL node.
+ (resolve_and_layout): Likewise.
+ (do_resolve_class): Likewise. Try first to use cl and then do the
+ lookup on the decl when calling check_pkg_class_access.
+ (complete_class_report_errors): Use IC_TYPE in place of
+ TREE_PURPOSE where appropriate. Use DEPEND_WFL on dependency
+ instead of doing a lookup over the decl.
+ (java_check_final): Use WFL info from field tree list.
+ (lookup_cl): Rewritten and returns a statically defined WFL node.
+ (lookup_modifier_cl): Now uses information from WFL nodes.
+ (process_imports): Likewise.
+ (read_import_dir): name and cl arguments replaced by a single WFL
+ node. Function modified accordingly.
+ (find_in_imports_on_demand): Now uses WFL node.
+ (check_pkg_class_access): cl argument is now a WFL node.
+ (declare_local_variables): Fixed to use WFL nodes.
+ (resolve_expression_name): Likewise.
+ (build_method_invocation_stmt): name_combo argument renamed
+ wfl. Function modified to use WFL nodes.
+ (build_invoke): cl used as a WFL node when calling build_expr_wfl.
+ (lookup_method_invoke): cl is now a WFL node. Added missing
+ IDENTIFIER_POINTER to class type decl name.
+
+Tue Apr 14 15:23:29 1998 Dave Brolley <brolley@cygnus.com>
+
+ * lang.c (init_parse): Now returns char* containing the filename.
+
+Fri Apr 10 11:36:04 1998 Per Bothner <bothner@cygnus.com>
+
+ * class.c (layout_class): Mangle repeated arg types to match cc1plus.
+
+ * decl.c, java-tree.h (integer_four_node): New INTEGER_CST node.
+ * class.c (make_class_data): If flag_assume_compiled, initial class
+ state is CSTATE_PREPARED; make superclass and interfaces direct
+ references, rather than constant pool indexes.
+
+Thu Apr 9 16:10:56 1998 Alexandre Petit-Bianco <apbianco@cygnus.com>
+
+ * parser.y: Include flags.h. Removed debug variable pl.
+ (method_declaration:): Uses ctxp->parser_ccb_indent instead of pl.
+ (block:): Likewise.
+ (labeled_statement_nsi:): Generate debug info when reducing
+ expression_statement:.
+ (check_pkg_class_access): get_access_flags_from_decl invokation
+ fixed for new CLASS_* flags location.
+ (source_end_java_method): Save/restore parser context when
+ entering/leaving this routine. Restore lineno to its right value
+ before calling expand_end_bindings.
+ (build_method_invocation_stmt): build_invoke called with the
+ current line information.
+ (build_invoke): New argument cl. Wrap the function call around a
+ wfl node.
+ (refine_accessible_methods_list): Changed comment, removed
+ unnecessary code.
+ * parse.h: Fixed typo in comments.
+ (CLASS_OR_INTERFACE): Handle the new CLASS_* flags location.
+ (JAVA_MAYBE_GENERATE_DEBUG_INFO): New macro.
+ (struct parser_ctxt): New fields ccb_indent, last_ccb_indent1,
+ parser_ccb_indent.
+ * lex.c (java_lex): Record the last closing curly bracket of a
+ function.
+ * jcf-parse.c (jcf_parse_source): Now calls
+ java_check_methods. Clarified comment, fixed typo.
+
+1998-04-09 Dave Brolley <brolley@cygnus.com>
+
+ * lang.c (init_parse): Expose for non USE_CPPLIB builds.
+ (finish_parse): Expose for non USE_CPPLIB builds.
+
+Wed Apr 8 13:06:23 1998 Jeffrey A Law (law@cygnus.com)
+
+ * lang.c (lang_print_xnode): New function.
+
+Fri Apr 3 13:22:41 1998 Per Bothner <bothner@cygnus.com>
+
+ * decl.c (class_dtable_decl), java-tree.h: New tree node.
+ * class.c (get_dispatch_vector, get_dispatch_table): New functions
+ used to build a class's dispatch table.
+ (make_class_data): Generate dispatch table if flag_assume_compiled.
+ Set dtable of class object to address of class_dtable_decl.
+
+ * decl.c (int_decl_processing): Make soft_badarrayindex_node
+ be volatile and have side effects - generates better code.
+
+ * class.c, expr.c, parse.y: CLASS_INTERFACE, CLASS_FINAL, etc:
+ These flags were defined for TYPE_DECLs, but used on RECORD_TYPEs.
+
+ * expr.c (expand_invoke): If class is final, method is
+ effectively final, so can call it directly.
+
+ * java-tree.h (TYPE_NVIRTUALS, TYPE_VTABLE): New macros.
+
+ * Makefile.in, Make-lang.in: Add missing $(exeext)s.
+
+Thu Mar 19 16:59:16 1998 Alexandre Petit-Bianco <apbianco@cygnus.com>
+
+ * parse.y (build_method_invocation_stmt): Removed extra argument
+ to build_invoke.
+
+Mon Mar 16 17:25:19 1998 Alexandre Petit-Bianco <apbianco@cygnus.com>
+
+ * expr.c (dtable_indent): Now static global.
+ (expand_invoke): Now call invoke_build_dtable and
+ build_invokevirtual.
+ (invoke_build_dtable, build_invokevirtual): New functions.
+ * jcf-io.c (find_class): Defer issuing a warning by setting
+ jcf->outofsynch to 1.
+ * jcf-parse.c (jcf_out_of_synch): New function.
+ (load_class): Test this_jcf.outofsynch flag and call
+ jcf_out_of_synch accordingly.
+ * jcf.h: (typedef struct JCF): New flag outofsynch. Fixed typo in
+ comment indentation.
+ * lex.c (java_get_unicode): Fixed code indentation.
+ (java_lex): Create string literal. Fixed typo. Removed several
+ premature obstack_free.
+ * parse.h: New enums for name resolution and invocation mode.
+ (struct qualification): New data structure.
+ (RESOLVE_CHAIN_REMAINDER, BUILD_PTR_FROM_NAME): New macros.
+ (do_resolve_class, build_method_invocation_stmt,
+ breakdown_qualified, qualify_ambiguous_name, resolve_and_layout,
+ debug_line, identical_subpath_p, invocation_mode,
+ refine_accessible_methods_list, build_invoke,
+ lookup_method_invoke): New functions declared.
+ (build_invokevirtual, invoke_build_dtable, match_java_method,
+ build_field_ref, jcf_out_of_synch): New references to external
+ functions.
+ (struct parse_ctxt): Removed artificial_constructor field.
+ * parse.y: (array_type:): Type defined for this rule.
+ (class_type:): Installed default rule for interface_type:.
+ (array_type:): Now build Java array type.
+ (qualified_name:): Now use obstack_grow0.
+ (method_declaration:): Skip the artificial constructor added to
+ the list, if any.
+ (abstract_method_declaration:): Execute the code only during pass 1.
+ (block:): Installed default rule in block_statements:.
+ (block_statement:): Add the statement to the method during pass 2.
+ (statement_expression): Installed default rule for
+ method_invocation:.
+ (argument_list:): Added code to build the argument list.
+ (method_invocation:): Added call to create the method invocation
+ node.
+ (yyerror): Now use obstack_grow0. Removed bogus obstack_free.
+ (debug_line): New function for debug.
+ (complete_class_decl): No longer do something during pass 1.
+ (method_header): Use BUILD_PTR_FROM_NAME.
+ (parser_qualified_classname): Use obstack_grow0. Removed bogus
+ obstack_free.
+ (parser_chain_incomplete_item): Use BUILD_PTR_FROM_NAME. Modified
+ function's main comment.
+ (java_complete_class): Set CLASS_LOADED_P on all fixed incomplete
+ classes.
+ (complete_method_decl): Use BUILD_PTR_FROM_NAME and promote types.
+ (resolve_class): Now works with arrays.
+ (do_resolve_class, resolve_and_layout): New functions.
+ (java_check_regular_methods): Reverse method list before and after
+ having processed it. No longer set ctxp->artificial_constructor.
+ (read_import_dir): Test jcf->outofsynch and call jcf_out_of_synch
+ accordingly. Fixed typo in issued error message. Now use
+ obstack_grow0.
+ (find_in_imports_on_demand): Now use obstack_grow0.
+ (declare_local_variables): Use BUILD_PTR_FROM_NAME.
+ (source_end_java_method): Call expand_expr_stmt instead of
+ expand_expr. Calls it before calling expand_function_end.
+ (java_method_add_stmt): Do nothing if errors were found during
+ parsing.
+ (java_layout_parsed_class): Set CLASS_LOADED_P and fixed typo.
+ (build_method_invocation_stmt, build_invoke, invocation_mode,
+ lookup_method_invoke, refine_accessible_methods_list,
+ qualify_ambiguous_name, breakdown_qualified, identical_subpath_p):
+ New functions.
+ * typeck.c (build_java_signature): Properly end method signature
+ if return type skipped.
+ (match_java_method): New function.
+
+Mon Mar 16 10:40:47 1998 Per Bothner <bothner@cygnus.com>
+
+ * jcf-io.c (find_classfile): If USE_JCF_STDIO, fopen in binary mode.
+
+Wed Feb 25 08:55:49 1998 Alexandre Petit-Bianco <apbianco@cygnus.com>
+
+ * expr.c (build_invoke_non_interface): New function.
+ (methods_ident, ncode_ident): Now static globals.
+ (expand_invoke): Use build_invoke_non_interface.
+ * java-tree.h (struct lang_decl): New field function_decl_body.
+ (DECL_FUNCTION_BODY): New macro.
+ * jcf-parse.c (jcf_parse_source): Deeper check before setting
+ CLASS_FROM_SOURCE_P.
+ (parse_source_file): Fixed typos. Call java_layout_parsed_class
+ before starting pass 2. Call to java_generate_parsed_class replaced
+ by java_register_parsed_class.
+ * lex.c: Fixed typo in header. Some line width related formating.
+ * lex.h: Some line width related formating.
+ * parse.h (source_end_java_method, resolve_expression_name,
+ complete_class_decl, maybe_create_class_interface_decl,
+ check_class_interface_creation): New static function declarations.
+ (java_layout_parsed_class, java_method_add_stmt): New function
+ declarations.
+ (struct parser_ctxt): Field mark_class_generate removed. New
+ fields class_list and artificial_constructor.
+ * parse.y: Fixed typo in header.
+ (class_declaration:): Call complete_class_decl when class body
+ parsed.
+ (method_declaration:): Call source_end_java_method in pass 2 when
+ the method body is defined.
+ (postfix_expression:): Do expression name resolution on sub-rule
+ name during pass 2.
+ (create_class, create_interface): Merged common pieces.
+ (check_class_interface_creation, maybe_create_class_interface_decl):
+ New functions.
+ (complete_class_decl): New function.
+ (register_fields): Fixed line width related typo.
+ (method_header): Correctly skip first argument when fixing
+ argument line. Changed the loop.
+ (java_check_circular_reference): Now use ctxp->class_list.
+ (java_complete_class): Removed start/stop marking.
+ (java_check_regular_methods): Now takes a class decl as an
+ argument. Add default constructor if none were encountered.
+ (java_check_methods): Now use ctxp->class_list. Changed call to
+ java_check_regular_methods.
+ (source_start_java_method): Set DECL_ARG_TYPE for each function
+ arguments.
+ (source_end_java_method, java_method_add_stmt): New functions.
+ (java_generate_parsed_class): No longer exists.
+ (java_layout_parsed_class, java_register_parsed_class): New functions.
+ (resolve_expression_name): New function.
+
+Thu Feb 12 11:54:28 1998 Alexandre Petit-Bianco <apbianco@cygnus.com>
+
+ * jcf-parse.c: (parse_source_file): Check on errors after init lex.
+ * lex.c: (java_init_lex): Defer ctxp->java_pass initialization
+ until pass initializations are done. Call read_import_dir with
+ pass set to 0.
+ * parse.h: (lookup_modifier_cl): New function declared.
+ (INTERFACE_FIELD_MODIFIERS): New macro.
+ (OBSOLETE_MODIFIER_WARNING): New macro.
+ * parse.y: (register_fields): Class type and current field name in
+ local variables. Check modifier(s) if adding field(s) to an interface.
+ (check_abstract_method_header): Now use OBSOLETE_MODIFIER_WARNING
+ and report errors using the faulty modifier line context.
+ (lookup_modifier_cl): New function.
+ (read_import_dir): Detect and report default import processing
+ failure.
+
+1998-02-11 Brendan Kehoe <brendan@cygnus.com>
+
+ Add a pair of -fassume-compiled/-fno-assume-compiled options.
+ * class.c (is_compiled_class): Return 1 after making sure it
+ qualifies as loaded, if FLAG_ASSUME_COMPILED is set.
+ * lang-options.h: Add -fassume-compiled/-fno-assume-compiled.
+ * java-tree.h (flag_assume_compiled): Add decl.
+ * lang.c (lang_f_options): Add the flag.
+ (flag_assume_compiled): Add decl, default to 0.
+
+Wed Feb 11 11:27:59 1998 Alexandre Petit-Bianco <apbianco@cygnus.com>
+
+ * class.c (class_depth): Call to load_class uses extra VERBOSE arg.
+ (is_compiled_class): Likewise.
+ (layout_class): Likewise.
+ (layout_class): Detect and lay out classes defined in source code.
+ (interface_of_p, add_interface_do, may_add_interface): New
+ function.
+ (add_interface): Now use add_interface_do.
+ (add_method_1): New function.
+ (add_method): Now use add_method_1.
+ (pushlevel): Debug message conditional to SOURCE_FRONTEND_DEBUG.
+ (complete_start_java_method): New function.
+ (start_java_mehod): Now call complete_start_java_method.
+ * expr.c (lookup_field): Call to load_class uses extra VERBOSE arg.
+ (expand_invoke): Likewise and fixed typo.
+ *gjava.c: (print_super_field): Use new argument to find_class
+ DO_CLASS_FILE.
+ (main): Likewise.
+ *java-tree.h: (CLASS_FROM_SOURCE_P): New flag on RECORD_TYPE.
+ (IS_A_SINGLE_IMPORT_CLASSFILE_NAME_P, IS_A_CLASSFILE_NAME,
+ QUALIFIED_P, IS_AN_IMPORT_ON_DEMAND_P): New flags on
+ IDENTIFIER_NODE.
+ (CLASS_COMPLETE_P): New flag on TYPE_DECL.
+ (add_method_1, push_class): New prototypes.
+ *jcf-dump.c: find_class now uses new DO_CLASS_FILE argument.
+ *jcf-io.c: (open_in_zip): jcf now stores a pointer to the Zip
+ directory where the class was found.
+ (find_class): New argument DO_CLASS_FILE. Function find_class
+ modified accordingly.
+ *jcf-parse.c: (fix_class_path): New function.
+ (load_class): Use new VERBOSE argument. load_class now finds and
+ loads/parses .class/.java files. Save read_state of current_jcf
+ if necessary.
+ (java_parser_abort_on_error): New macro.
+ (jcf_parse_source, parse_source_file): New function.
+ (jcf_parse): Fixed typo.
+ (yyparse): Call parse_source_file () only.
+ (process_zip_dir): Fixed typo, fix zdir->filename_length when
+ writing the real class name back in the zip directory entry.
+ (find_in_current_zip): IDENTIFIER_CLASS_VALUE may be null.
+ (jcf_figure_file_type): Fixed bogus alloc and bcopy.
+ *jcf.h: (typedef struct JCF): New fields java_source and zipd.
+ (find_class): Prototype fixed.
+ *lex.c: Added 1998 time stamp.
+ Removed all static global variables, moved into the parser
+ context data structure.. Now include unistd.h if SEEK_SET not
+ defined.
+ (java_init_lex): Rewritten.
+ (java_sneak_unicode): Modified current unicode access in current line.
+ (java_unget_unicode): Likewise.
+ (java_allocate_new_line): New allocation management.
+ (java_read_char): Modified access and storage of unget_utf8_value.
+ New way of processing current unicode.
+ (java_store_unicode, java_read_unicode): Fixed typo in declaration.
+ (java_get_unicode): Now use the parser context.
+ (java_lineterminator): Likewise.
+ (java_lex): Now used java_lval argument (pointer to YYSTYPE), part
+ of the reentrant parser implementation. Function now use the
+ parser context data structure and java_lval. Fixed production of
+ the float and double constant "out of range" error message. Fixed
+ obstack use. Return integer value when hitting a modifier. Now
+ return type for TRUE, FALSE and other predefined types. Return
+ identifier as a TREE_LIST list containing the current line context
+ as the TREE_VALUE sub-node.
+ (java_unicode_2_utf8): Fixed typo in declaration.
+ (java_lex_error): Now use the parser context data structure.
+ *lex.h: Added 1998 time stamp.
+ (struct java_line): New fields ref_count and next.
+ (JAVA_LINE_CHECK, JAVA_LINE_MARK, JAVA_LINE_CHAIN,
+ JAVA_LINE_UNMARK, ID_NAME, ID_CL): New macros.
+ (JAVA_FLOAT_RANGE_ERROR, JAVA_INTEGRAL_RANGE_ERROR, UNGETC): Fixed.
+ *parse.h: Added 1998 time stamp.
+ (java_parse_source_file): Renamed from parse_source_file.
+ (YYERROR_NOW, YYNOT_TWICE): Fixed.
+ (CLASS_MODIFIERS, FIELD_MODIFIERS, METHOD_MODIFIERS,
+ INTERFACE_MODIFIER, INTERFACE_METHOD_MODIFIERS,
+ JAVA_MODIFIER_CTX_UNMARK, IC_DECL, IC_DEPEND, DEPEND_DECL,
+ THIS_MODIFIER_ONLY, ABSTRACT_CHECK, BEGIN_ONLY_PASS,
+ END_ONLY_PASS, ELSE_ONLY_PASS, exit_java_complete_class,
+ CLASS_OR_INTERFACE, INCOMPLETE_P): New macros.
+ (struct parser_ctxt): New data structure to keep the parser context.
+ *parse.y: Added 1998 time stamp, got rid of static global variables.
+ (java_error_count, ctxp): New global variables.
+ (%union): New value field.
+ (numeric_type, integral_type): Rules removed.
+ (primitive_type): Rule defined to handle integral, float, double and
+ boolean types.
+ (qualified_name, package_declaration,
+ single_type_import_declaration, type_import_on_demand_declaration,
+ modifiers, class_declaration, super, interfaces,
+ interface_type_list, class_body, field_declaration,
+ field_declaration, variable_declarators, variable_declarator,
+ variable_declarator_id, method_declaration, method_header,
+ formal_parameter_list, formal_parameter, method_body, block,
+ static, interface_declaration, extends_interfaces,
+ abstract_method_declaration, local_variable_declarators): Rules now
+ define actions.
+ (force_error, do_warning): New global statics.
+ (push_parser_context, parser_context_save_global,
+ parser_context_restore_global, pop_parser_context): New functions.
+ (yyerror): Now uses the global parser context. Fixed use of obstack.
+ (parse_error, parse_error_context, parse_warning_context,
+ java_accstring_lookup, redefinition_error, check_modifiers,
+ parser_add_interface, create_interface, create_class, find_field,
+ duplicate_declaration_error, register_fields, method_header,
+ check_modifiers_consistency, check_abstract_method_header,
+ method_declarator, parser_qualified_classname,
+ parser_check_super_interface, parser_check_super,
+ parser_chain_incomplete_item, java_check_circular_reference,
+ layout_class_from_source, java_complete_class,
+ complete_method_decl, resolve_class, complete_class_report_errors,
+ java_check_final, check_method_redefinition,
+ java_check_regular_methods, java_check_abstract_methods,
+ java_check_methods, lookup_java_interface_method2,
+ lookup_java_method2, lookup_cl, find_name_in_single_imports,
+ process_imports, find_in_imports, read_import_entry,
+ read_import_dir, find_in_imports_on_demand,
+ check_pkg_class_access, not_builtin_p, declare_local_variables,
+ source_start_java_method, java_generate_parsed_class): New
+ functions.
+ *typeck.c: (signature_include_return): New global variable.
+ (build_java_signature): Use SIGNATURE_INCLUDE_RETURN figure whether
+ to add the function returned type in the signature.
+
+1998-02-09 Brendan Kehoe <brendan@cygnus.com>
+
+ * jcf-io.c (open_in_zip): Use strncmp and LEN.
+
+Thu Jan 29 16:12:13 1998 Dave Brolley <brolley@cygnus.com>
+
+ * Make-lang.in (java.info): Added.
+ (java.install-info): Added
+
+1998-01-27 Brendan Kehoe <brendan@cygnus.com>
+
+ * Makefile.in (clean): Also remove java/parse.c.
+
+1998-01-26 Brendan Kehoe <brendan@cygnus.com>
+
+ Add a pair of -fbounds-check/-fno-bounds-check options.
+ * lang.c (lang_decode_option): Add code to grok arguments.
+ (flag_bounds_check): Add decl.
+ (lang_f_options): New array w/ the option in it.
+ * java-tree.h (flag_bounds_check): Add decl.
+ * lang-options.h: New file.
+ * expr.c (build_java_arrayaccess): Use flag_bounds_check instead
+ of a static macro value.
+ (JAVA_ARRAY_EXCEPTION): Delete macro.
+
+Fri Jan 23 14:19:47 1998 Per Bothner <bothner@cygnus.com>
+
+ * typeck.c (build_java_array_type): Fix two bugs in previous change.
+ * expr.c (build_anewarray): Add missing promote_type.
+
+Thu Jan 22 17:43:45 1998 Per Bothner <bothner@cygnus.com>
+
+ Add array types with known length to optimize bounds checking.
+ * typeck.c (build_java_array_type): Take length parameter.
+ (java_array_type_length, build_prim_array_type): New functions.
+ * java-tree.h: Update for new functions.
+ * expr.c, typeck.c, verify.c: Update build_java_array_type calls.
+ * class.c: Use build_prim_array_type.
+ * expr.c (can_widen_reference_to): Handle known-length array types.
+ (verify_jvm_instructions): Keep track of integer push instructions
+ followed by newarray/anewarray, so we can build known-length arrays.
+ (JAVA_ARRAY_DATA_OFFSET): Replace by ...
+ (java_array_data_offset): New function.
+ (build_java_array_length_access): New function. Optimize if constant.
+ (build_java_arrayaccess): Constant fold bounds check.
+ (expand_java_newarray, expand_java_anewarray): Replaced by ...
+ (build_newarray, build_anewarray): New functions.
+ (ARRAY_NEW_NUM, ARRAY_NEW_PTR): Use build_{a,}newarray.
+ * verify.c (merge_types): Handle known-lengh array types.
+
+Mon Jan 19 13:09:25 1998 Per Bothner <bothner@cygnus.com>
+
+ * expr.c (expand_byte_code): Fix performace bug, which caused
+ searching linenumber_table to be linear rather than constant.
+
+Fri Dec 12 19:18:42 1997 Per Bothner <bothner@cygnus.com>
+
+ * Makefile.in (BISON, BISONFLAGS): Add missing macros.
+
+ * decl.c, java-tree.h (soft_fmod_node): New global.
+ * decl.c (init_decl_processing): Define __builtin_fmod.
+ * expr.c (build_java_binop): Implement TRUNC_MOD_EXPR for REAL_TYPE
+ using __builtin_fmod.
+
+Thu Dec 4 13:22:59 1997 Alexandre Petit-Bianco <apbianco@cygnus.com>
+
+ * keyword.h: New file, output of keyword.gperf as processed by
+ gperf.
+ * lex.c (java_lex_init): Initialize java_error_flag.
+ * parse.c (YYERROR_NOW): Uses java_error_flag.
+ * parse.y: New static java_error_flag. Useless definition of
+ buffer_error gone.
+ * parse.y (java_error): Portable error recovery using
+ java_error_flag (not yet completely tuned).
+
+1997-12-04 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * Makefile.in (parse.c): Use $(srcdir) for parse.y.
+
+Wed Dec 3 18:37:42 1997 Alexandre Petit-Bianco <apbianco@cygnus.com>
+
+ * Makefile.in: (JAVA_OBJS): New object jcf-parse.o.
+ (parse.c, lex.c, keyword.h): New rules for Java source code
+ front-end.
+ * parse.c: Renamed into jcf-parse.c.
+ * jcf-parse.c (yyparse): Invoke the parser to process Java source code.
+ * keyword.gperf: New file, Java keywords.
+ * parse.y: New file, Java language grammar.
+ * parse.h: New file, Java language grammar definitions.
+ * lex.c: New file, Java language lexer.
+ * lex.h: New file, Java language lexer definitions.
+
+Wed Dec 3 17:00:17 1997 Per Bothner <bothner@cygnus.com>
+
+ * decl.c (clinit_identifier_node), java-tree.h: New global.
+ * java-tree.h (IS_METHOD_INIT_P, IS_METHOD_CLINIT_P): Removed.
+ * verify.c (verify_jvm_instructions): Inline use of removed macros.
+ * expr.c (expand_java_field_op): Check for invalid assignment
+ to final field.
+
+ * jcf-reader.c (get_attribute): Test for wrong attribute length.
+
+Mon Oct 27 17:46:36 1997 Per Bothner <bothner@cygnus.com>
+
+ * verify.c (verify_jvm_instructions): When processing a handler,
+ attempt to set the current_subr to the right value.
+ (More complicated code combines Sep 17 and Oct 22 versions.)
+
+Fri Oct 24 11:36:54 1997 Per Bothner <bothner@cygnus.com>
+
+ * class.c (push_class): Figure out (guess) name of source file.
+ * parse.c (set_source_filename): Set DECL_SOURCE_FILE of class decl.
+ (give_name_to_class): Don't guess source name; use DECL_SOURCE_FILE.
+ (parse_class_file): Change return type from int to void.
+ Call debug_start_source_file/debug_end_source_file.
+
+ * expr.c (build_java_binop): Fix masking 2nd operand.
+ * decl.c (init_decl_processing): Set sizetype first.
+
+Wed Oct 22 19:39:05 1997 Per Bothner <bothner@cygnus.com>
+
+ * verify.c (verify_jvm_instructions): Don't set current_subr to NULL.
+ (Revert Sep 17 change.)
+
+Tue Oct 21 15:09:02 1997 Alexandre Petit-Bianco <apbianco@cygnus.com>
+
+ * parse.c (process_zip_dir): Skip ZIP entries not bearing the
+ .class extension in their name and fix thing so we don't process
+ them parse_zip_file_entries().
+ (parse_zip_file_entries): Cleaned unused local variables.
+
+Mon Oct 20 14:52:42 1997 Per Bothner <bothner@cygnus.com>
+
+ * expr.c (can_widen_reference_to): Allows equal array element types.
+ (expand_byte_code): PRE_RET must expand OPERAND_VALUE (to get index).
+ * jcf-dump.c (RET): Get (and print) index.
+
+ * verify.c (verify_jvm_instructions case OPCODE_anewarray):
+ Promote element type to POINTER_TYPE.
+
+Mon Oct 20 13:40:41 1997 Alexandre Petit-Bianco <apbianco@cygnus.com>
+
+ * jcf-reader.c, parse.c: (parse_zip_file, process_zip_dir,
+ find_in_current_zip, jcf_figure_file_type): Moved from
+ jcf-reader.c to parse.c.
+ * zextract.c: (read_zip_archive): takes file_comment_length possible
+ field into account.
+
+Mon Oct 20 11:45:06 1997 Per Bothner <bothner@cygnus.com>
+
+ * verify.c (verify_jvm_instructions): Var can also be promoted to int.
+
+ * verify.c (merge_types): Handle array types even better ...
+
+Fri Oct 17 15:56:37 1997 Per Bothner <bothner@cygnus.com>
+
+ * expr.c (java_stack_pop): Fix use of NULL_TREE for TYPE_SECOND.
+
+ * java-tree.h (PUSH_FIELD): Set DECL_ARTIFICIAL.
+ * class.c (make_class_data): Don't build fields_decl if no fields.
+ When building fields_decl, skip if DECL_ARTIFICAL.
+
+ * expr.c (java_stack_swap): Update stack_type_map.
+ * verify.c (merge_types): Handle array types better.
+
+Wed Oct 15 18:09:45 1997 Per Bothner <bothner@cygnus.com>
+
+ * class.c (add_field): Don't promote short integral fields to
+ int any more (unless JAVA_PROMOTE_TO_INT), since Kaffe doesn't.
+ * expr.c (push_value): Promote and convert short integral values.
+
+ * decl.c, java-tree.h (integer_two_node): New constant node.
+ * verify.c (merge_types): Check for TYPE_RETURN_ADDR.
+
+Wed Oct 15 17:04:50 1997 Alexandre Petit-Bianco <apbianco@cygnus.com>
+
+ * class.c (append_gpp_mangled_type): Use function argument
+ unpromoted type to generate mangled name.
+
+Mon Oct 13 16:52:55 1997 Alexandre Petit-Bianco <apbianco@cygnus.com>
+
+ * constants.c (build_constant_data_ref): Now uses current_class
+ instead of main_class.
+ (build_constants_constructor): Now uses current_class instead of
+ main_class.
+ * zipfile.h: (struct ZipFileCache): Now defined here. Declaration
+ of the global variable SeepZipFiles done here.
+ * zextract.c (read_zip_archive): extra_field optional field taken
+ into account while computing the position of the class file in the
+ archive.
+ * verify.c (verify_jvm_instructions): Use current_jcf to search
+ the constant pool.
+ * parse.c (load_class): First search for the class to load in the
+ current zip file. Saves current_jcf (restored before returning
+ from that function). Don't call JCF_FINISH in the class was found
+ in the current ZIP file.
+ (jcf_parse): If the class was found in the current ZIP file, save
+ its tree_constant_pool (for later reuse).
+ (parse_class_file): New function. Process each method defined in
+ the current class and record the class as to be later registered.
+ (yyparse): Rewritten. Figure the type of the current file and switch
+ accordingly.
+ * lang.c: New global variable current_jcf.
+ (lang_init): Removed compiling_from_source test (done later, in
+ yyparse). Removed call the jcf_parse ().
+ * jcf.h (JCF_ZIP, JCF_CLASS, JCF_SOURCE): New defined values.
+ (typedef struct JCF): New fields seen_in_zip (to mark a class found
+ in the current ZIP file) and zip_offset (offset to the class data in
+ the current zip file).
+ * jcf-reader.c: zipfile.h included.
+ localToFile: New ZipFileCache static global variable
+ (parse_zip_file_entries): New function. Browse the current ZIP
+ file directory and process each class found.
+ (process_zip_dir): New function. Register each class found in the
+ ZIP file directory. The class aren't parsed but a valid JCF is
+ link to each of them.
+ (find_in_current_zip): New function. Search for a class in the
+ current ZIP file directory. If found, prepare the class so that it
+ can be loaded.
+ (jcf_figure_file_type): New function. Examine the file structure
+ to figure a class file, a ZIP file. If none of these categories are
+ matched, a source file is assumed.
+ * jcf-io.c: Removed definition of ZipFileCache (moved in zipfile.h).
+ SeenZipFile: New global variable.
+ (open_in_zip): Use zipmember's length to accelerate the search for
+ a member. If zipmember was NULL and zip file successfully read,
+ return 0.
+ * java-tree.h: New global variable current_jcf declared. Added
+ declaration for current_constant_pool_tags, current_constant_pool_data,
+ current_constant_pool_length, current_constant_pool_data_ref.
+ (struct lang_type): Augmented with two fields. struct JCF *jcf (to
+ store the JCF of classes seen in a zip file) and tree *constant_pool
+ (to save a loaded class constant pool). current_class declared here.
+ * expr.c (expand_invoke): Use current_jcf instead of main_jcf to
+ retrieve method_ref_constant.
+ (PUSHC): java_push_constant_from_pool now uses current_jcf.
+ (OBJECT): get_class_constant now uses current_jcf.
+ (ARRAY_NEW_PTR): get_class_constant now uses current_jcf.
+ (ARRAY_NEW_MULTI): get_class_constant now uses current_jcf.
+ (expand_invoke): Now uses current_class instead of main_class
+ (build_class_init): Now uses current_class instead of main_class
+ * class.c: New static global variable registered_class.
+ (register_class): New function.
+ (emit_register_class): Modified to use registered_class instead of
+ main_class
+ (is_compiled_class): Now take into account class seen in the archive.
+
+Mon Oct 6 12:03:23 1997 Per Bothner <bothner@cygnus.com>
+
+ * except.h: Renamed to: java-except.h.
+ * parse.c, except.c, expr.c, verify.c: Update #include accordingly.
+ * except.c: Add semi-working (commented out) implementation.
+
+ * expr.c (expand_iinc): Add needed flush_quick_stack.
+ * parse.c (set_source_filename): New function.
+ (give_name_to_class): Set input_filename from package.classname.java.
+
+ * jcf-io.c (find_class): Don't look first in ".".
+
+Wed Oct 1 11:26:10 1997 Alexandre Petit-Bianco <apbianco@cygnus.com>
+
+ * zextract.c (read_zip_archive): Now takes into account the
+ extra_field field.
+ * expr.c (can_widen_reference_to): Modified to handle sub-interfaces.
+
+Sat Sep 20 12:44:28 1997 Per Bothner <bothner@cygnus.com>
+
+ * constants.c, java-tree.h (build_internal_class_name): New function.
+ (alloc_class_constant): Re-implement using build_internal_class_name.
+ * class.c (make_class_data): Likewise.
+ * class.c (hashUtf8String): Make hash algorithm match String.hashCode.
+
+Wed Sep 17 13:15:23 1997 Per Bothner <bothner@cygnus.com>
+
+ * verify.c (verify_jvm_instructions): Temporarily set current_subr
+ to NULL before pushing an exception handler target.
+
+ * expr.c (flush_quick_stack): Save from low stack indexes to high.
+ (java_stack_swap, java_stack_dup): Re-write to be safe from
+ clobbering registers.
+ (build_class_init): New function.
+
+Wed Sep 17 11:02:41 1997 Alexandre Petit-Bianco <apbianco@cygnus.com>
+
+ * typeck.c (build_java_array_type): Temporary use
+ permanent_obstack to create the array 'length' field.
+ * expr.c (lookup_label): Temporay use permanent_obstack to create
+ label if not found.
+ * class.c (push_super_field): Tempory use permanent_obstack.
+
+Mon Sep 15 11:33:31 1997 Alexandre Petit-Bianco <apbianco@cygnus.com>
+
+ * typeck.c (type_for_mode): Now handles double_type_node and
+ float_type_node.
+ * verify.c (verify_jvm_instructions): The instruction following
+ the wide bytecode is checked. OPCODE_ret added to the list of
+ wide.
+
+Thu Sep 11 19:45:18 1997 Alexandre Petit-Bianco <apbianco@cygnus.com>
+
+ * class.c (make_class): Temporary use permanent_obstack. Set the
+ class CLASS_P field to 1.
+ (push_class): Temporary use permanent_obstack.
+ (set_super_info): Temporary use permanent_obstack.
+ (add_method): Temporary use permanent_obstack, set
+ METHOD_TRANSIENT().
+ (add_field): Temporary use permanent_obstack. Sets
+ FIELD_VOLATILE() and FIELD_TRANSIENT().
+ (build_class_ref): Temporary use permanent_obstack if the class
+ isn't compiled.
+ (build_static_field_ref): Temporary use permanent_obstack when
+ creating field's rtl.
+ (get_access_flags_from_decl): Handle ACC_VOLATILE, ACC_TRANSIENT,
+ ACC_SYNCHRONIZED, ACC_NATIVE, ACC_ABSTRACT flags for methods
+ and fields. Function finalized, as far as flag handling.
+ (push_class_static_dummy_field): Temporary use permanent_obstack.
+ (emit_register_class): Force generation of class registration at
+ -O3 or deeper.
+ * decl.c (end_java_method): Call permanent_allocation() before
+ returning.
+ * expr.c (can_widen_reference_to): Added comment to interface
+ handling, fixed typo.
+ (lookup_field): Now uses CLASS_P() to correct FIXME
+ (expand_invoke): Verification on public && !static &&
+ !abstract moved into soft_lookupinterfacemethod (kaffe).
+ Use Object class dtable if objectref is an array when expanding
+ invokeinterface.
+ (java_push_constant_from_pool): Temporary use permanent_obstack
+ for CONSTANT_string
+ * parse.c (get_ref_constant): Temporary use permanent_obstack to
+ create constant references.
+ (get_constant): Temporary use permanent_obstack to create constant.
+ (load_class): Temporary use permanent_obstack to load class.
+ (jcf_parse): Temporary use permanent_obstack to perform class
+ layout.
+ * typeck.c: (parse_signature_string): Temporary use permanent_obstack.
+ (build_java_signature): Temporary use permanent_obstack.
+ * verify.c: (verify_jvm_instruction): removed unecessary verification
+ on ACC_SUPER flag.
+ * java-tree.h (METHOD_NATIVE, METHOD_TRANSIENT): Defined.
+ (FIELD_VOLATILE, FIELD_TRANSIENT): Defined.
+ (CLASS_P): Defined
+
+Thu Sep 11 11:57:32 1997 Per Bothner <bothner@cygnus.com>
+
+ * class.c (append_gpp_mangled_type): Fix typo.
+ (emit_register_class): Use main_class to get class object, rather
+ than looking for no-longer-existing static decl starting with _CL.
+ * typeck.c (parse_signature_type): Promote array element type
+ if it is a RECORD_TYPE.
+
+Wed Sep 10 16:09:23 1997 Per Bothner <bothner@cygnus.com>
+
+ * class.c (push_class_static_dummy_field): New function.
+ (mangle_static_field): New. Do G++-style mangling of static fields.
+ (layout_class): Mandle static fields here, not in add_field.
+ (build_class_ref): The class object is now a dummy static field.
+ * decl.c (find_local_variable): Look for best, instead of first match.
+ * expr.c (push_type): Always promote_type, not just for RECORD_TYPE.
+ (build_java_athrow): Don't check here if exception is Throwable.
+ * java-tree.h (TYPE_UNSET): Renamed to TYPE_UNKNOWN.
+ (TYPE_USED): Removed. No longer used ...
+ * parse.c (jcf_parse): Call push_class_static_dummy_field.
+ * verify.c (push_pending_label): New function.
+ (push_pending_block): Renamed to check_pending_block.
+ (merge_types): Remove unneeded suuport for TYPE_UNUSED.
+ (verify_jvm_instructions): Only reset prev_eh_ranges (to force
+ re-checking possible handlers) after a store (less wasted work).
+ Check for null handler (finally) before calling add_handler.
+ Various changes to (finally?) correctly handle try/finally.
+
+1997-09-09 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * class.c: Include stdio.h.
+
+Thu Sep 4 21:30:55 1997 Per Bothner <bothner@cygnus.com>
+
+ * expr.c (expand_invoke): Use COMPOUND_EXPR (and TREE_SIDE_EFFECTS)
+ to make sure class is initialized before static/special invoke.
+
+ * verify.c (verify_jvm_instructions): On a store instruction,
+ call find_local_variable to force pre-allocation of decl and rtx.
+ * decl.c (push_jvm_slot): Set DECL_REGISTER on stack slots.
+
+Wed Sep 3 16:13:23 1997 Per Bothner <bothner@cygnus.com>
+
+ * class.c (build_class_ref): Strip off "promoted_" if need be.
+ (make_field_value): Call build_java_signature when needed.
+ (layout_class): Don't make_function_rtl if METHOD_ABSTRACT.
+ * expr.c (build_java_athrow): Don't push_value of exception.
+ (build_java_binop): Implement COMPARE_L_EXPR and COMPARE_G_EXPR to
+ match specification of [fd]cmp[lg] for NaNs.
+ (expand_byte_code): Add support for exception handler ranges.
+ * except.c: Add skeleton for EH code-generation.
+ * verify.c (merge_types): Treat all promoted integral types as equal.
+ * constants.c (build_constants_constructor): To force creation of
+ current_constant_pool_data_ref, call build_constant_data_ref.
+
+ * javaop.def (lload): Fix typo.
+ * jcf-dump.c (main): Clear filename to prevent possibly-bad free.
+
+Tue Sep 2 17:37:25 1997 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * parse.c: Don't include function.h.
+
+Wed Aug 27 18:33:04 1997 Per Bothner <bothner@cygnus.com>
+
+ * except.[ch]: New files.
+ * Makefile.in (JAVA_OBJS): Add except.o
+ * expr.c: Temporary warning about unimplemented exceptions.
+ * verify.c: Verify exception handlers.
+
+ * jcf-dump.c (disassemble_method): Print exception table.
+
+Wed Aug 27 13:26:58 1997 Alexandre Petit-Bianco <apbianco@cygnus.com>
+
+ * expr.c (verify_jvm_instructions): Started a thorough
+ verification of invoke* bytecodes.
+ (expand_byte_code): flush quick stack if PC is the target of a
+ branch. and undef RET (conflicting with config/i386/i386.h).
+ (expand_java_arrayload): Fixed bogus cast, when Boolean type is
+ used.
+ (expand_invoke): Now handles invokeinterface and do more
+ verification according to the bytecode.
+ (lookup_field): Don't try to load the class if processing
+ dtable_type.
+ (can_widen_reference_to): Now handles interfaces.
+ * decl.c (init_decl_processing): New global variable
+ soft_lookupinterfacemethod_node, declared in java-tree.h.
+ Call set_super_info on string_type_node.
+ * java-tree.h (CLASS_INTERFACE, CLASS_ABSTRACT, CLASS_SUPER): Now
+ defined.
+ * class.c (set_super_info): Fills the CLASS_* flags according to
+ access_flags.
+ (get_access_flags_from_decl): Handles all class flags.
+
+Tue Aug 26 18:54:34 1997 Per Bothner <bothner@cygnus.com>
+
+ * class.c (add_method): Zero out newly-allocated DECL_LANG_SPECIFIC.
+ * parse.c (yyparse): Check for abstract method, and missing code.
+ * expr.c (expand_byte_code): Change interface.
+ * lang.c (put_decl_node): Print promoted types prettier.
+ * verify.c (verify_jvm_instruction): Change interface.
+ Partial support for scanning exception table.
+ For load instructions, handle promoted integral types.
+
+Thu Aug 21 13:48:01 1997 Per Bothner <bothner@cygnus.com>
+
+ * verify.c: New file, with contents moved from expr.c.
+ * expr.c: Bunch of stuff (mostly verification) moved to verify.c.
+ * typeck.c (is_array_type_p): Moved here from expr.c.
+ * java-tree.h: Add some now-needed function declarations.
+ * Makefile.in (JAVA_OBJS): Added verify.o.
+
+Wed Aug 20 14:34:34 1997 Alexandre Petit-Bianco <apbianco@cygnus.com>
+
+ * class.c (add_method): Sets the METHOD_SYNCHRONIZED flag, sets the
+ METHOD_ABSTRACT flag.
+
+ * java-tree.h (METHOD_SYNCHRONIZED): Set to DECL_LANG_FLAG_4.
+ (IS_METHOD_CLINIT_P, IS_METHOD_INIT_P): New macros.
+ (METHOD_ABSTRACT): Set to DECL_LANG_FLAG_5
+
+ * decl.c (soft_monitorenter_node, soft_monitorexit_node): New global
+ variables.
+ (start_java_method): Hook for SYNCHRONIZED methods.
+
+ * expr.c (build_java_jsr, build_java_ret): New functions
+ (JSR,PRE): New macros
+ (PRE_TABLE_SWITCH, PRE_LOOKUP_SWITCH): Fixed and secured.
+ (verify_jvm_instructions): tableswitch, lookupswitch,
+ monitorenter, monitorexit, goto_w: verified.
+ (LOOKUP_SWITCH, TABLE_SWITCH): Fixed generation of default: label
+ (build_java_monitor): New function.
+ (MONITOR_OPERATION): Modified to call build_java_monitor()
+ (verify_jvm_instructions): Started a thorough verification of
+ invoke* bytecodes.
+
+Tue Aug 19 13:35:49 1997 Per Bothner <bothner@cygnus.com>
+
+ Support verification of jsr/ret subroutines (used for try/finally).
+ * decl.c (return_address_type_node): New type node.
+ * java-tree.h (LABEL_RETURN_LABEL, LABEL_RETURN_TYPE_STATE,
+ RETURN_MAP_ADJUSTED, LABEL_RETURN_LABELS, LABEL_IN_SUBR,
+ LABEL_SUBR_START, LABEL_SUBR_CONTEXT, BCODE_VERIFIED): New macros.
+ (TYPE_UNSET, TYPE_SECOND, TYPE_NULL, TYPE_RETURN_ADDR, TYPE_UNUSED,
+ TYPE_USED): New macros for special types in type_map.
+
+ * java-tree.h (BCODE_JUMP_TARGET): Renamed to BCODE_TARGET.
+ (BCODE_BACKWARDS_TARGET, CODE_FORWARDS_TARGET): Replaced by
+ BCODE_JUMP_TARGET.
+ * expr.c (expand_byte_code): Fix logic to warn of unused instructions.
+
+ * expr.c (can_widen_reference_to): New function.
+ (pop_type): Use it.
+ (merge_type_state): Support handling start of subroutine.
+ (push_pending_block): Return char* error message, instead of calling
+ fatal on an error. Also handle subroutines.
+ (verify_jvm_instructions): Handle errors from push_poending_block.
+ Support jsr and ret instructions.
+
+Tue Aug 19 13:33:36 1997 Per Bothner <bothner@cygnus.com>
+
+ * jcf-io.c (find_classfile): Fix thinko.
+ * jcf-dump.c: Add CONVERT2 (to match changed javaop.def).
+
+Tue Aug 12 20:14:45 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * Makefile.in (BISON): Remove.
+
+Thu Aug 7 23:08:24 1997 Per Bothner <bothner@cygnus.com>
+
+ * Makefile.in: Convert to autoconf.
+ * config-lang.in (outputs): Added java/Makefile.
+
+ * Make-lang.in, lang-specs.h, config-lang.in, Makefile.in:
+ Rename cc1java to jc1.
+
+ * lang.c (init_parse, finihs_parse): New functions #ifdef USE_CPPLIB.
+ * Makefile.in (INTERNAL_CFLAGS): Add @extra_c_flags.
+
+ * class.c (class_depth): Do load_class if needed.
+
+ Mostly better verification.
+ * decl.c (pushdecl): Set TYPE_STUB_DECL for a type.
+ (init_decl_processing): Change return type of soft_checkcast.
+ * expr.c (expand_java_CHECKCAST): Do push_value of the "casted" value.
+ * lang.c (put_decl_string, put_decl_node, lang_printable_name,
+ lang_print_error): New functions.
+ (lang_init): Set global hook print_error_function to lang_print_error.
+ * expr.c: In the type_map ptr_type_node is only used for null now.
+ (pop_type, merge_types): Hence ptr_type_node matches any reference.
+ (merge_types): Dererence pointer to record types before comparing.
+ (decode_newarray_type, merge_types): On error just return NULL.
+ (build_java_binop): Add preliminary implementation (with warning)
+ for COMPARE_L_EXPR and COMPARE_G_EXPR (i.e. [fd]cmp[lg]).
+ (lookup_label): Set DECL_IGNORED_P (for dwarf2out).
+ (expand_compare, expand_java_goto, expand_java_call): Don't
+ push_pending_block, since that only makes sense when verifying.
+ (merge_type_state): Different return codes.
+ (push_pending_block): A block may need to be verified more than once.
+ (expand_byte_code): Warn about unused code at code generation time.
+ (verify_jvm_instruction): Changed logic, since code may need to be
+ re-verified if type-state has changed. Also, better error handling.
+ Implement acmpeq, acmpne, pop, pop2, swap, checkcast, instanceof.
+ Improve newarray, anewarray, ?aload, athrow,
+ * java-tree.h (LABEL_CHANGED): New macro.
+
+Tue Aug 5 12:21:27 1997 Alexandre Petit-Bianco <apbianco@cygnus.com>
+
+ * decl.c (soft_athrow_node): New global variable initialized.
+ * javaop.def (i2b, i2c, i2s): Invoke CONVERT2
+ * typeck.c (convert): Added support for REAL_TYPE.
+ (convert_to_char): New function.
+ (convert): Handle CHAR_TYPE.
+ * expr.c (expand_java_arraystore): Modified because CHAR/BYTE/BOOLEAN/
+ SHORT now expect INT but store as CHAR/BYTE/BOOLEAN/SHORT.
+ (expand_java_arrayload): CHAR/BYTE/BOOLEAN/SHORT now convert result to
+ promoted type.
+ (verify_jvm_instructions): Added break a the end of bogus unop: label.
+ (OPCODE_<b|c|s>astore): Pop an int operand from the type stack
+ (OPCODE_<b|c|s>astore): Push the promoted type onto the stack
+ (process_jvm_instruction): New macro CONVERT2 for i2c, i2s and i2b.
+ (JAVA_ARRAY_LENGTH_OFFSET, JAVA_ARRAY_DATA_OFFSET): Modified
+ to Use The Right Things.
+ (pop_type): Accept CHAR/BYTE/BOOLEAN/SHORT promoted type as
+ compatible with INT. BOOLEAN is made equivalent to BYTE.
+ (OPCODE_athrow, OPCODE_aconst_null, OPCODE_ifnull,
+ OPCODE_ifnonnull): Now supported.
+ (build_java_athrow): New function.
+
+Mon Aug 4 15:46:45 1997 Per Bothner <bothner@cygnus.com>
+
+ Rename method name <init> to match G++ (and fix mangling).
+ * class.c (layout_class): Replace method name of <init> by class name.
+ (make_method_value): Do inverse renaming of constructor from <init>.
+ * java-tree.h (DECL_CONSTRUCTOR_P): New macro.
+ * typeck.c (lookup_java_constructor): New function.
+ * expr.c (expand_invoke): If method_name is <init>, call
+ lookup_java_constructor to find constructor.
+
+ * parse.c (get_constant): Handle CONSTANT_Float and CONSTANT_Double.
+
+Fri Aug 1 11:37:09 1997 Alexandre Petit-Bianco <apbianco@cygnus.com>
+
+ * parse.c (get_class_constant): Modified to handle array "classes"
+ * typeck.c (set_local_type): Bug fixed when filling type_map[] with
+ wide type.
+ (convert): Modified to handle real type.
+ * java-tree.h (soft_badarrayindex_node, soft_anewarray_node,
+ soft_multianewarray, soft_newarray_node, soft_throw_node): New global
+ variables declared.
+ * decl.c (soft_badarrayindex_node, soft_anewarray_node,
+ soft_multianewarray, soft_newarray_node, soft_throw_node): New
+ global variables initialized.
+ (find_local_variable): Handles the case of a pointer
+ (end_java_method): Restore the use of one more scope
+ * expr.c (build_java_arraynull_check, build_java_arrayaccess,
+ build_java_array_length_access, expand_java_arrayload,
+ expand_java_arraystore, expand_java_array_length,
+ expand_java_multianewarray, expand_java_anewarray,
+ build_java_check_indexed_type, is_array_type_p,
+ build_java_throw_out_of_bound_exception): New functions.
+ (STORE_INTERNAL): Now forces type of the decl to be type of the value.
+ (OPCODE_arraylength, OPCODE_newarray, OPCODE_<t>astore,
+ OPCODE_<t>aload): Implemented code for verification.
+ (ARRAY_STORE, ARRAY_LOAD, ARRAY_LENGTH, ARRAY_NEW_PTR, ARRAY_NEW_NUM
+ ARRAY_NEW_MULTI): Macro defined.
+ (CONVERT): Modified to invoke convert().
+ (case OPCODE_aload2): Fixed index typo from 2 to 1.
+
+Thu Jul 31 12:48:18 1997 Per Bothner <bothner@cygnus.com>
+
+ * class.c (push_class): Set DECL_ARTIFICIAL (for dbxout.c).
+ (build_class_ref, is_compiled_class): Handle pointer-to-record types.
+ (make_class_data): Field name needs '/' as package prefix.
+ * expr.c (type_stack_dup, java_stack_dup): Fix fencepost errors.
+
+Fri Jul 25 11:44:21 1997 Per Bothner <bothner@cygnus.com>
+
+ Implement debug information for local variables.
+ * java-tree.h (DECL_CODE_LENGTH, DECL_ARG_SLOT_COUNT,
+ DECL_LOCAL_SLOT_NUMBER, DECL_LOCAL_START_PC, DECL_LOCAL_END_PC,
+ DECL_LOCAL_SLOT_CHAIN): New macros.
+ (struct lang_decl_var): New type.
+ * parse.c (give_name_to_locals): Move to decl.c.
+ * decl.c (give_name_to_locals): Re-written to Do The Right Thing.
+ (start_java_method): Re-write parameter handling.
+ (pending_local_decls): New global variable.
+ (push_jvm_slot, maybe_pushlevels, maybe_poplevels): New functions.
+ (find_local_variable): Accept pc so we can skips decls not in range.
+ (struct binding_level): Add end_pc field.
+ * expr.c (expand_byte_code): Call maybe_pushlevels and maybe_poplevels.
+ (various): Change so current pc gets passed to find_local_variable.
+
+ * decl.c (init_decl_processing): Re-arrange fields in
+ class_type_node and and method_type_node to match kaffe 0.9.1.
+ * class.c (make_method_value, make_class_data): Update
+ initializations to match.
+
+Wed Jul 16 17:17:50 1997 Per Bothner <bothner@cygnus.com>
+
+ * class.c (unicode_mangling_length, emit_unicode_mangled_name,
+ append_gpp_mangled_name, append_gpp_mangled_type): New functions.
+ (push_super_field): New function.
+ (make_class_data): Handle inheritance of class static initializer.
+ (layout_class): New name mangling.
+ * constants.c (build_constant_data_ref): Init type of data array
+ to a one-element array.
+ (build_constants_constructor): Set DECL_SIZE from complete array type.
+ * decl.c: Rename class_type, object_type etc to class_type_node,
+ object_type_node etc. Make former inherit from latter.
+ * expr.c (expand_invoke): Add cast of function address.
+ * java-tree.h (TYPE_ARRAY_ELEMENT, PUSH_SUPER_VALUE): New.
+ * parse.c (yyparse): Don't call layout_class here.
+ * typeck.c (build_java_array_type): Set TYPE_ARRAY_ELEMENT.
+
+Sat Jun 14 12:06:57 1997 Per Bothner <bothner@cygnus.com>
+
+ * decl.c, class.c: Update method type to match latest Kaffe snapshot.
+ * constants.c (lookup_name_constant): Renamed to alloc_name_constant.
+ (alloc_class_constant): New.
+ * expr.c (expand_invoke): Make sure method's class is initialized.
+ * class.c (interits_from_p, emit_register_class): New functions.
+ * parse.c (yyparse): Call emit_register_class.
+
+Mon Jun 9 18:08:06 1997 Per Bothner <bothner@cygnus.com>
+
+ * constants.c: New file, to handle constant pool.
+ * Makefile.in (JAVA_OBJS): Add constants.o.
+ * decl.c (init_decl_processing): Update, fix, finish various structs.
+ (pushdecl_top_level): New.
+ * parse.c (layout_class): Moved to class.c.
+ * expr.c (java_push_constant_from_pool): New function.
+ * class.c (build_class_ref): Make work fully
+ (make_class_data): Emit super-class, constant pool, interface vector.
+
+Tue Jun 3 10:14:31 1997 Per Bothner <bothner@cygnus.com>
+
+ java-tree.h (DECL_SIGNATURE, BCODE_EMITTED): Remove.
+ (LABEL_VERIFIED, BCODE_EXCEPTION_TARGET, TYPE_ARRAY_P): New.
+ * class.c (class_depth): New function.
+ (lookup_named_class): Replaced by new function lookup_class.
+ * decl.c (object_type_node, string_type_node): New.
+ Remove various types that we no longer need.
+ * expr.c (verify_jvm_instructions): New separate verifier pass.
+ (push_type, pop_type): New functions for verifier.
+ (type_stack_dup, pop_argument_types, merge_types): Likewise.
+ (expand_byte_code): Simplify, since we assume already verified.
+ (expand_invoke): Now mostly works.
+ * javaop.def: Rename ldc1->ldc, ldc2->ldc_w, ldc2w->ldc2_w.
+ * lang.c (main_class): Move to parse.c. Don't make_class yet.
+ * parse.c: Wait to allocate class object until we know its name.
+ (layout_class): Calculate DECL_VINDEX for each virtual method.
+ * typeck.c (get_array_type): Rename to ...
+ (build_java_array_type): ... and provide working implementation.
+ (build_java_signature): New function - build Java signature of type.
+ (set_java_signature): New function - cache signature with type.
+ (lookup_java_method): New function.
+
+Tue May 6 22:08:24 1997 Per Bothner <bothner@deneb.cygnus.com>
+
+ * class.c (ident_subst): Take extra SUFFIX parameter.
+ (add_field): Set DECL_ASSEMBLER_NAME of static fields; more.
+ (set_constant_value, build_static_field_ref, is_compiled_class): New.
+ (build_class_ref): Actually implement.
+ * decl.c, java-tree.h: Renamed some xx_type to xx_type_node.
+ * decl.c (builtin_function): New.
+ (init_decl_processing): Update for current Kaffe. Declare some
+ builtin Kaffe functions.
+ * expr.c (build_address_of): New.
+ (expand_java_NEW, expand_java_INSTANCEOF, expand_java_CHECKCAST):
+ Renamed (from expand_java_new etc), and added working implementations.
+ (build_field_ref): Now also handle static fields.
+ (expand_invoke): Implement invokestatic, and start implement rest.
+ * java-opcodes.h: Use javaop.def to avoid duplicated list.
+ * javaop.def: Rename invokevirt -> invokevirtual.
+ * lang.c (use_handles): Removed.
+ * parse.c: Add support for ConstantValue atribute.
+ Handle nested loading of a class. (JPOOL_UTF): New.
+
+Tue Mar 11 20:11:05 1997 Per Bothner <bothner@deneb.cygnus.com>
+
+ * expr.c (expand_java_pushc): Support #ifndef REAL_ARITHMETIC case.
+
+Thu Feb 27 14:24:29 1997 Per Bothner <bothner@deneb.cygnus.com>
+
+ * Make-lang.in (java.install-man): New empty rule.
+ * typeck.c (set_local_type): New function.
+ * expr.c (STORE_INTERNAL): Call find_local_variable,
+ not find_stack_slot. Call set_local_type.
+
+Wed Feb 12 16:11:05 1997 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * java-tree.h: Various new macros for constructing RECORD_TYPEs,
+ and building RECORD_TYPE CONSTRUCTORs.
+ Also support for creating Utf8Const objects from an INDETIFIER_NODE.
+
+ * lang.c (use_handles): Change the default to 0.
+ * decl.c: Define and build class_type, field_type, utf8const_type.
+ * class.c (make_class_data, make_field_value,
+ get_access_flags_from_decl, build_class_ref, build_utf8_ref,
+ hashUtf8String, strLengthUtf8, mangled_classname:
+ Functions to build reflective data structures.
+ * parse.c (yyparse): Call make_class_data.
+
+ * jcf-io.c (open_class, find_classfile): New functions.
+ * jcf-dump.c: Support reading classfile from explicitly-named
+ class file (without CLASSPATH searching).
+
+Thu Oct 24 14:10:16 1996 Per Bothner <bothner@deneb.cygnus.com>
+
+ * jcf-reader.c: Add parameter list to HANDLE_CONSTANT_Utf8.
+ * parse.c (JPOOL_UTF_LENGTH, JPOOL_UTF_DATA, HANDLE_CONSTANT_Utf8):
+ Override jcf-reader macros so CONSTANT_Utf8 becomes tree node here.
+ (get_constant): Now trivial for CONSTANT_Utf8.
+
+ * jcf.h: Make NEW_CPOOL the default.
+ * jcf.h, jcf-reader.c, parse.c: Remove support for !NEW_CPOOL.
+
+Thu Oct 24 13:52:45 1996 Per Bothner <bothner@deneb.cygnus.com>
+
+ New directory.
diff --git a/gcc/java/Make-lang.in b/gcc/java/Make-lang.in
index 737ba031abb..787319e3c09 100644
--- a/gcc/java/Make-lang.in
+++ b/gcc/java/Make-lang.in
@@ -1,6 +1,6 @@
# Top level makefile fragment for the GNU compiler for the Java(TM)
# language.
-# Copyright (C) 1996, 1998 Free Software Foundation, Inc.
+# Copyright (C) 1996, 1998, 1999 Free Software Foundation, Inc.
#This file is part of GNU CC.
@@ -40,7 +40,7 @@
# - making any compiler driver (eg: g++)
# - the compiler proper (eg: jc1)
# - define the names for selecting the language in LANGUAGES.
-
+#
# Extra flags to pass to recursive makes.
JAVA_FLAGS_TO_PASS = \
"JAVA_FOR_BUILD=$(JAVA_FOR_BUILD)" \
@@ -53,11 +53,11 @@ JAVA_INSTALL_NAME = `t='$(program_transform_name)'; echo gcj | sed $$t`
# Actual names to use when installing a cross-compiler.
JAVA_CROSS_NAME = `t='$(program_transform_cross_name)'; echo gcj | sed $$t`
-
+#
GCJ = gcj
# Define the names for selecting java in LANGUAGES.
-java: jc1$(exeext) $(GCJ)$(exeext) jvgenmain$(exeext) gcjh$(exeext)
+java: jc1$(exeext) $(GCJ)$(exeext) jvgenmain$(exeext) gcjh$(exeext) jv-scan$(exeext) jcf-dump$(exeext)
# Define the name of target independant tools to be installed in $(bindir)
# Names are subject to changes
@@ -73,36 +73,22 @@ JAVA_SRCS = $(srcdir)/java/parse.y $(srcdir)/java/class.c \
$(srcdir)/java/lang.c $(srcdir)/java/typeck.c $(srcdir)/java/except.c \
$(srcdir)/java/verify.c $(srcdir)/java/zextract.c $(srcdir)/java/jcf-io.c \
$(srcdir)/java/jcf-parse.c $(srcdir)/java/mangle.c \
- $(srcdir)/java/jcf-write.c $(srcdir)/java/buffer.c
+ $(srcdir)/java/jcf-write.c $(srcdir)/java/buffer.c \
+ $(srcdir)/java/jcf-depend.c $(srcdir)/java/jcf-path.c
jc1$(exeext): $(P) $(JAVA_SRCS) $(LIBDEPS) stamp-objlist
cd java; $(MAKE) $(FLAGS_TO_PASS) $(JAVA_FLAGS_TO_PASS) ../jc1$(exeext)
-$(GCJ).c: $(srcdir)/gcc.c
- -rm -f $@
- $(LN_S) $(srcdir)/gcc.c $@
-
jvspec.o: $(srcdir)/java/jvspec.c
- $(CC) -c -DWITH_THREAD_$(GCC_THREAD_FILE) \
+ $(CC) -c -DWITH_THREAD_$(GCC_THREAD_FILE) -DWITH_GC_$(JAVAGC) \
$(ALL_CFLAGS) $(ALL_CPPFLAGS) \
$(INCLUDES) $(srcdir)/java/jvspec.c
-# N.B.: This is a copy of the gcc.o rule, with -DLANG_SPECIFIC_DRIVER added.
-# It'd be nice if we could find an easier way to do this---rather than have
-# to track changes to the toplevel gcc Makefile as well.
-# We depend on $(GCJ).c last, to make it obvious where it came from.
-$(GCJ).o: $(CONFIG_H) multilib.h config.status $(lang_specs_files) $(GCJ).c \
- system.h
- $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
- $(DRIVER_DEFINES) \
- -DLANG_SPECIFIC_DRIVER \
- -c $(GCJ).c
-
# Create the compiler driver for $(GCJ).
-$(GCJ)$(exeext): $(GCJ).o jvspec.o version.o choose-temp.o\
- pexecute.o prefix.o mkstemp.o $(LIBDEPS) $(EXTRA_GCC_OBJS)
- $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ $(GCJ).o jvspec.o prefix.o \
- version.o choose-temp.o pexecute.o mkstemp.o $(EXTRA_GCC_OBJS) $(LIBS)
+$(GCJ)$(exeext): gcc.o jvspec.o version.o \
+ prefix.o intl.o $(LIBDEPS) $(EXTRA_GCC_OBJS)
+ $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ gcc.o jvspec.o prefix.o intl.o \
+ version.o $(EXTRA_GCC_OBJS) $(LIBS)
# Create a version of the $(GCJ) driver which calls the cross-compiler.
$(GCJ)-cross$(exeext): $(GCJ)$(exeext)
@@ -111,20 +97,34 @@ $(GCJ)-cross$(exeext): $(GCJ)$(exeext)
# Dependencies here must be kept in sync with dependencies in Makefile.in.
jvgenmain$(exeext): $(srcdir)/java/jvgenmain.c $(srcdir)/java/mangle.c \
- $(OBSTACK)
+ $(OBSTACK) $(LIBDEPS)
cd java && $(MAKE) $(FLAGS_TO_PASS) $(JAVA_FLAGS_TO_PASS) ../jvgenmain$(exeext)
# This must be kept in sync with dependencies in Makefile.in.
GCJH_SOURCES = $(srcdir)/java/gjavah.c $(srcdir)/java/jcf-io.c \
$(srcdir)/java/zextract.c $(srcdir)/java/jcf-reader.c \
$(srcdir)/java/jcf.h $(srcdir)/java/javaop.h \
- $(srcdir)/java/javaop.def
+ $(srcdir)/java/javaop.def $(srcdir)/java/jcf-depend.c \
+ $(srcdir)/java/jcf-path.c
-gcjh$(exeext): $(GCJH_SOURCES)
+gcjh$(exeext): $(GCJH_SOURCES) $(LIBDEPS)
cd java && $(MAKE) $(FLAGS_TO_PASS) $(JAVA_FLAGS_TO_PASS) ../gcjh$(exeext)
+# This must be kept in sync with dependencies in Makefile.in.
+JV_SCAN_SOURCES = $(srcdir)/java/parse-scan.y $(srcdir)/java/lex.c \
+ $(srcdir)/java/parse.h $(srcdir)/java/lex.h $(srcdir)/java/jv-scan.c $(srcdir)/../libiberty/xmalloc.c $(srcdir)/../libiberty/xstrdup.c
+
+jv-scan$(exeext): $(JV_SCAN_SOURCES) stamp-objlist $(LIBDEPS)
+ cd java && $(MAKE) $(FLAGS_TO_PASS) $(JAVA_FLAGS_TO_PASS) ../jv-scan$(exeext)
+
+# This must be kept in sync with dependencies in Makefile.in.
+JCF_DUMP_SOURCES = $(srcdir)/java/jcf-dump.c $(srcdir)/java/jcf-io.c \
+ $(srcdir)/java/zextract.c $(srcdir)/../libiberty/memmove.c
+
+jcf-dump$(exeext): $(JCF_DUMP_SOURCES)
+ cd java && $(MAKE) $(FLAGS_TO_PASS) $(JAVA_FLAGS_TO_PASS) ../jcf-dump$(exeext)
-
+#
# Build hooks:
java.all.build: $(GCJ)$(exeext)
@@ -169,7 +169,7 @@ java.uninstall:
java.install-info:
-
+#
# Clean hooks:
# A lot of the ancillary files are deleted by the main makefile.
# We just have to delete files specific to us.
@@ -182,8 +182,8 @@ java.distclean:
-rm -f java/parse.output
java.extraclean:
java.maintainer-clean:
- -rm -f java/parse.h
-
+ -rm -f java/parse.c java/parse-scan.c java/parse.output java/y.tab.c
+#
# Stage hooks:
# The main makefile has already created stage?/java.
@@ -195,7 +195,7 @@ java.stage3:
-mv java/*$(objext) stage3/java
java.stage4:
-mv java/*$(objext) stage4/java
-
+#
# Maintenance hooks:
# This target creates the files that can be rebuilt, but go in the
diff --git a/gcc/java/Makefile.in b/gcc/java/Makefile.in
index efe7ef1bf00..f7373d6c8d7 100644
--- a/gcc/java/Makefile.in
+++ b/gcc/java/Makefile.in
@@ -1,5 +1,5 @@
# Makefile for GNU compiler for the Java(TM) language.
-# Copyright (C) 1987, 88, 90-4, 1995, 1998 Free Software Foundation, Inc.
+# Copyright (C) 1987, 88, 90-5, 1998, 1999 Free Software Foundation, Inc.
#This file is part of GNU CC.
@@ -59,11 +59,9 @@ X_CPPFLAGS =
T_CPPFLAGS =
CC = @CC@
-BISON = `if [ -f ../../bison/bison ] ; then echo ../../bison/bison -L $(srcdir)/../../bison/ ; else echo bison ; fi`
+SET_BISON = here=`pwd`; sdir=`cd $(srcdir) && pwd`; if test -f ../../bison; then bison="$$here/../../bison/bison -L $$sdir"; else bison=bison; fi
BISONFLAGS =
JAVABISONFLAGS = --name-prefix=java_
-LEX = `if [ -f ../../flex/flex ] ; then echo ../../flex/flex ; else echo flex ; fi`
-LEXFLAGS =
AR = ar
AR_FLAGS = rc
SHELL = /bin/sh
@@ -94,9 +92,6 @@ GCC_CFLAGS=$(INTERNAL_CFLAGS) $(X_CFLAGS) $(T_CFLAGS) $(CFLAGS)
program_transform_name =
objdir = .
-+target=@target@
-+xmake_file=@dep_host_xmake_file@
-+tmake_file=@dep_tmake_file@
#version=`sed -e 's/.*\"\([^ \"]*\)[ \"].*/\1/' < $(srcdir)/version.c`
#mainversion=`sed -e 's/.*\"\([0-9]*\.[0-9]*\).*/\1/' < $(srcdir)/version.c`
@@ -104,6 +99,11 @@ objdir = .
srcdir = @srcdir@
VPATH = @srcdir@
+# Directory holding libgcj.zip.
+prefix = @prefix@
+datadir = @datadir@
+libgcj_zip = $(datadir)/libgcj.zip
+
# Additional system libraries to link with.
CLIB=
@@ -133,7 +133,7 @@ all: all.indirect
####build overrides
@build_overrides@
####site overrides
-
+#
# Now figure out from those variables how to compile and link.
all.indirect: Makefile ../jc1$(exeext) ../jcf-dump$(exeext) \
@@ -148,8 +148,6 @@ ALL_CFLAGS = $(INTERNAL_CFLAGS) $(X_CFLAGS) $(T_CFLAGS) $(CFLAGS) $(XCFLAGS)
# Likewise.
ALL_CPPFLAGS = $(CPPFLAGS) $(X_CPPFLAGS) $(T_CPPFLAGS)
-# Even if ALLOCA is set, don't use it if compiling with GCC.
-
SUBDIR_OBSTACK = `if [ x$(OBSTACK) != x ]; then echo ../$(OBSTACK); else true; fi`
SUBDIR_USE_ALLOCA = `case "${CC}" in "${OLDCC}") if [ x$(ALLOCA) != x ]; then echo ../$(ALLOCA); else true; fi ;; esac`
SUBDIR_MALLOC = `if [ x$(MALLOC) != x ]; then echo ../$(MALLOC); else true; fi`
@@ -168,10 +166,7 @@ INCLUDES = -I. -I.. -I$(srcdir) -I$(srcdir)/.. -I$(srcdir)/../config -I$(srcdir)
.c.o:
$(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $<
-# This tells GNU make version 3 not to export all the variables
-# defined in this file into the environment.
-.NOEXPORT:
-
+#
# Lists of files for various purposes.
# Language-specific object files for Gcc/Java:
@@ -180,10 +175,13 @@ INCLUDES = -I. -I.. -I$(srcdir) -I$(srcdir)/.. -I$(srcdir)/../config -I$(srcdir)
#
JAVA_OBJS = parse.o class.o decl.o expr.o constants.o lang.o typeck.o \
except.o verify.o zextract.o jcf-io.o jcf-parse.o mangle.o jcf-write.o \
- buffer.o memmove.o
+ buffer.o check-init.o jcf-depend.o jcf-path.o xref.o
JAVA_OBJS_LITE = parse-scan.o jv-scan.o
+LIBS = ../../libiberty/libiberty.a
+LIBDEPS = $(LIBS)
+
# Language-independent object files.
OBJS = `cat ../stamp-objlist`
OBJDEPS = ../stamp-objlist
@@ -192,32 +190,31 @@ compiler: ../jc1$(exeext) ../jv-scan$(exeext)
../jc1$(exeext): $(P) $(JAVA_OBJS) $(OBJDEPS) $(LIBDEPS)
rm -f ../jc1$(exeext)
$(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ \
- $(JAVA_OBJS) $(OBJS) $(LIBS)
+ $(JAVA_OBJS) $(OBJS) $(SUBDIR_OBSTACK) $(LIBS)
../jv-scan$(exeext): $(P) $(JAVA_OBJS_LITE) $(OBJDEPS) $(LIBDEPS)
rm -f ../jv-scan$(exeext)
$(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ \
- $(JAVA_OBJS_LITE) $(LIBS)
+ $(JAVA_OBJS_LITE) $(SUBDIR_OBSTACK) $(LIBS)
-../jcf-dump$(exeext): jcf-dump.o jcf-io.o zextract.o memmove.o
- $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ jcf-dump.o jcf-io.o zextract.o memmove.o
+../jcf-dump$(exeext): jcf-dump.o jcf-io.o jcf-depend.o jcf-path.o \
+ zextract.o
+ $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ jcf-dump.o jcf-io.o \
+ jcf-depend.o jcf-path.o zextract.o $(LIBS)
# Dependencies here must be kept in sync with dependencies in Make-lang.in.
-../jvgenmain$(exeext): jvgenmain.o mangle.o
- $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ jvgenmain.o mangle.o ../obstack.o
+../jvgenmain$(exeext): jvgenmain.o mangle.o $(LIBDEPS)
+ $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ jvgenmain.o mangle.o ../obstack.o $(LIBS)
-../gcjh$(exeext): gjavah.o jcf-io.o zextract.o memmove.o
- $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ gjavah.o jcf-io.o zextract.o memmove.o
+../gcjh$(exeext): gjavah.o jcf-io.o jcf-depend.o jcf-path.o \
+ zextract.o $(LIBDEPS)
+ $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ gjavah.o jcf-io.o \
+ jcf-depend.o jcf-path.o zextract.o $(LIBS)
Makefile: $(srcdir)/Makefile.in $(srcdir)/../configure
cd ..; $(SHELL) config.status
-memmove.o: $(srcdir)/../../libiberty/memmove.c
- rm -f memmove.c
- $(LN_S) $(srcdir)/../../libiberty/memmove.c memmove.c
- $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) memmove.c
-
native: config.status ../jc1$(exeext)
-
+#
# Compiling object files from source files.
TREE_H = $(srcdir)/../tree.h $(srcdir)/../real.h $(srcdir)/../tree.def \
$(srcdir)/../machmode.h $(srcdir)/../machmode.def
@@ -226,23 +223,37 @@ RTL_H = $(srcdir)/../rtl.h $(srcdir)/../rtl.def \
$(srcdir)/../machmode.h $(srcdir)/../machmode.def
EXPR_H = $(srcdir)/../expr.h ../insn-codes.h
+# Separating PARSE_DIR from PARSE_RELDIR lets us easily change the
+# code to support building parse.c in the build directory, at some
+# expense in readability.
+PARSE_DIR = $(srcdir)
+PARSE_RELDIR = .
+PARSE_C = $(PARSE_DIR)/parse.c
+PARSE_SCAN_C = $(PARSE_DIR)/parse-scan.c
PARSE_H = $(srcdir)/parse.h
-PARSE_C = $(srcdir)/parse.c
-PARSE_SCAN_C = $(srcdir)/parse-scan.c
$(PARSE_C): $(srcdir)/parse.y $(srcdir)/lex.c $(PARSE_H) $(srcdir)/lex.h
- $(BISON) -t -v $(BISONFLAGS) $(JAVABISONFLAGS) -o $(PARSE_C) \
- $(srcdir)/parse.y
+ $(SET_BISON); \
+ cd $(PARSE_DIR) && $$bison -t -v $(BISONFLAGS) $(JAVABISONFLAGS) \
+ -o parse.c $(PARSE_RELDIR)/parse.y
$(PARSE_SCAN_C): $(srcdir)/parse-scan.y $(srcdir)/lex.c $(PARSE_H) \
- $(srcdir)/lex.h
- $(BISON) -t -v $(BISONFLAGS) -o $(PARSE_SCAN_C) $(srcdir)/parse-scan.y
+ $(srcdir)/lex.h
+ $(SET_BISON); \
+ cd $(PARSE_DIR) && $$bison -t -v $(BISONFLAGS) -o parse-scan.c \
+ $(PARSE_RELDIR)/parse-scan.y
lex.c: keyword.h lex.h
+lang.o: $(srcdir)/java-tree.def
+
keyword.h: keyword.gperf
gperf -L KR-C -F ', 0' -p -t -j1 -i 1 -g -o -N java_keyword -k1,3,$$ \
keyword.gperf > keyword.h
+jcf-path.o : jcf-path.c $(CONFIG_H) $(srcdir)/../system.h jcf.h
+ $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
+ -DLIBGCJ_ZIP_FILE='"$(libgcj_zip)"' $(srcdir)/jcf-path.c
+
# These exist for maintenance purposes.
# Update the tags table.
@@ -259,17 +270,22 @@ mostlyclean:
rm -f *.o
clean: mostlyclean
- rm -f parse.c
force:
-parse.o: $(PARSE_C) jcf-reader.c
-jcf-dump.o: jcf-reader.c jcf.h javaop.h javaop.def
-gjavah.o: jcf-reader.c jcf.h javaop.h
+parse.o : $(PARSE_C) jcf-reader.c $(CONFIG_H) $(srcdir)/../system.h
+jcf-dump.o : $(CONFIG_H) $(srcdir)/../system.h $(JAVA_TREE_H) jcf-dump.c \
+ jcf-reader.c jcf.h javaop.h javaop.def
+gjavah.o : $(CONFIG_H) $(srcdir)/../system.h gjavah.c \
+ jcf-reader.c jcf.h javaop.h
buffer.o : buffer.c $(CONFIG_H) buffer.h $(srcdir)/../gansidecl.h \
$(srcdir)/../system.h $(srcdir)/../toplev.h
-class.o : class.c $(CONFIG_H) $(JAVA_TREE_H) $(RTL_H) jcf.h \
- $(srcdir)/../gansidecl.h $(srcdir)/../toplev.h $(srcdir)/../system.h
+check-init.o : check-init.c $(CONFIG_H) $(srcdir)/../gansidecl.h \
+ $(srcdir)/../../include/libiberty.h $(JAVA_TREE_H) \
+ $(srcdir)/../system.h $(srcdir)/../toplev.h
+class.o : class.c $(CONFIG_H) $(JAVA_TREE_H) $(RTL_H) jcf.h $(PARSE_H) \
+ $(srcdir)/../gansidecl.h $(srcdir)/../toplev.h $(srcdir)/../system.h \
+ $(srcdir)/../output.h
constants.o : constants.c $(CONFIG_H) $(JAVA_TREE_H) jcf.h \
$(srcdir)/../toplev.h $(srcdir)/../system.h
decl.o : decl.c $(CONFIG_H) $(JAVA_TREE_H) jcf.h \
@@ -281,17 +297,25 @@ expr.o : expr.c $(CONFIG_H) $(JAVA_TREE_H) jcf.h $(srcdir)/../real.h \
$(RTL_H) $(EXPR_H) javaop.h java-opcodes.h $(srcdir)/../except.h \
java-except.h java-except.h parse.h $(srcdir)/../toplev.h \
$(srcdir)/../system.h
-jcf-io.o: jcf-io.c $(CONFIG_H) $(srcdir)/../system.h
+jcf-depend.o : jcf-depend.c $(CONFIG_H) $(srcdir)/../system.h jcf.h
+jcf-io.o : jcf-io.c $(CONFIG_H) $(srcdir)/../system.h $(JAVA_TREE_H)
jcf-parse.o : jcf-parse.c $(CONFIG_H) $(JAVA_TREE_H) $(srcdir)/../flags.h \
- $(srcdir)/../input.h java-except.h $(srcdir)/../system.h
+ $(srcdir)/../input.h java-except.h $(srcdir)/../system.h \
+ $(srcdir)/../toplev.h $(PARSE_H)
jcf-write.o : jcf-write.c $(CONFIG_H) $(JAVA_TREE_H) jcf.h $(RTL_H) \
- java-opcodes.h parse.h buffer.h $(srcdir)/../system.h
+ java-opcodes.h parse.h buffer.h $(srcdir)/../system.h $(srcdir)/../toplev.h
+jv-scan.o : jv-scan.c $(CONFIG_H) $(srcdir)/../system.h
jvgenmain.o : jvgenmain.c $(CONFIG_H) $(srcdir)/../system.h
lang.o : lang.c $(CONFIG_H) $(JAVA_TREE_H) jcf.h $(srcdir)/../input.h \
$(srcdir)/../toplev.h $(srcdir)/../system.h
-mangle.o : mangle.c $(CONFIG_H) jcf.h $(srcdir)/../system.h
+mangle.o : mangle.c $(CONFIG_H) jcf.h $(JAVA_TREE_H) $(srcdir)/../system.h \
+ $(srcdir)/../toplev.h
+parse-scan.o : $(CONFIG_H) $(srcdir)/../system.h $(srcdir)/../toplev.h
typeck.o : typeck.c $(CONFIG_H) $(JAVA_TREE_H) jcf.h convert.h \
$(srcdir)/../toplev.h $(srcdir)/../system.h
verify.o : verify.c $(CONFIG_H) $(JAVA_TREE_H) jcf.h javaop.h java-opcodes.h \
java-except.h $(srcdir)/../toplev.h $(srcdir)/../system.h
+xref.o : xref.h $(CONFIG_H) $(JAVA_TREE_H) $(srcdir)/../toplev.h \
+ $(srcdir)/../system.h
+zextract.o : zextract.c $(CONFIG_H) $(srcdir)/../system.h zipfile.h
diff --git a/gcc/java/buffer.h b/gcc/java/buffer.h
index aa63840d759..924f6e0f276 100644
--- a/gcc/java/buffer.h
+++ b/gcc/java/buffer.h
@@ -36,6 +36,9 @@ struct buffer
#define NULL_BUFFER { (void*) 0, (void*) 0, (void*) 0 }
+#define BUFFER_INIT(BUFP) \
+ ((BUFP)->data = NULL, (BUFP)->ptr = NULL, (BUFP)->limit = NULL)
+
#define BUFFER_LENGTH(BUFP) ((BUFP)->ptr - (BUFP)->data)
#define BUFFER_RESET(BUFP) ((BUFP)->ptr = (BUFP)->data)
diff --git a/gcc/java/class.c b/gcc/java/class.c
index 920d50d854e..cb418cd8b3c 100644
--- a/gcc/java/class.c
+++ b/gcc/java/class.c
@@ -1,5 +1,5 @@
/* Functions related to building classes and their related objects.
- Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1996, 97-98, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -28,12 +28,23 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */
#include "system.h"
#include "tree.h"
#include "rtl.h"
+#include "flags.h"
#include "java-tree.h"
#include "jcf.h"
#include "obstack.h"
#include "toplev.h"
+#include "output.h"
+#include "parse.h"
static tree mangle_class_field PROTO ((tree class));
+static tree make_method_value PROTO ((tree));
+static tree build_java_method_type PROTO ((tree, tree, int));
+static int32 hashUtf8String PROTO ((const char *, int));
+static tree make_field_value PROTO ((tree));
+static tree get_dispatch_vector PROTO ((tree));
+static tree get_dispatch_table PROTO ((tree, tree));
+static void append_gpp_mangled_type PROTO ((struct obstack *, tree));
+static tree mangle_static_field PROTO ((tree));
static rtx registerClass_libfunc;
@@ -94,13 +105,13 @@ identifier_subst (old_id, prefix, old_char, new_char, suffix)
tree
mangled_classname (prefix, type)
- char *prefix;
- tree type;
+ const char *prefix;
+ tree type;
{
tree ident = TYPE_NAME (type);
if (TREE_CODE (ident) != IDENTIFIER_NODE)
ident = DECL_NAME (ident);
- return identifier_subst (ident, prefix, '/', '_', "");
+ return identifier_subst (ident, prefix, '.', '_', "");
}
tree
@@ -124,7 +135,6 @@ make_class ()
#else
TYPE_BINFO (type) = make_tree_vec (6);
#endif
- CLASS_P (type) = 1;
pop_obstacks ();
return type;
@@ -138,7 +148,20 @@ tree
unmangle_classname (name, name_length)
const char *name; int name_length;
{
- return ident_subst (name, name_length, "", '/', '.', "");
+ tree to_return = ident_subst (name, name_length, "", '/', '.', "");
+ /* It's not sufficient to compare to_return and get_identifier
+ (name) to determine whether to_return is qualified. There are
+ cases in signature analysis where name will be stripped of a
+ trailing ';'. */
+ name = IDENTIFIER_POINTER (to_return);
+ while (*name)
+ if (*name++ == '.')
+ {
+ QUALIFIED_P (to_return) = 1;
+ break;
+ }
+
+ return to_return;
}
tree
@@ -150,13 +173,14 @@ push_class (class_type, class_name)
int save_lineno = lineno;
tree source_name = identifier_subst (class_name, "", '.', '/', ".java");
push_obstacks (&permanent_obstack, &permanent_obstack);
+ CLASS_P (class_type) = 1;
input_filename = IDENTIFIER_POINTER (source_name);
lineno = 0;
decl = build_decl (TYPE_DECL, class_name, class_type);
input_filename = save_input_filename;
lineno = save_lineno;
signature = identifier_subst (class_name, "L", '.', '/', ";");
- IDENTIFIER_SIGNATURE_TYPE (signature) = class_type;
+ IDENTIFIER_SIGNATURE_TYPE (signature) = build_pointer_type (class_type);
/* Setting DECL_ARTIFICAL forces dbxout.c to specific the type is
both a typedef and in the struct name-space. We may want to re-visit
@@ -350,6 +374,7 @@ add_interface (this_class, interface_class)
add_interface_do (basetype_vec, interface_class, i);
}
+#if 0
/* Return the address of a pointer to the first FUNCTION_DECL
in the list (*LIST) whose DECL_NAME is NAME. */
@@ -362,8 +387,9 @@ find_named_method (list, name)
list = &TREE_CHAIN (*list);
return list;
}
+#endif
-tree
+static tree
build_java_method_type (fntype, this_class, access_flags)
tree fntype;
tree this_class;
@@ -422,7 +448,7 @@ add_method (this_class, access_flags, name, method_sig)
tree method_sig;
{
tree handle_class = CLASS_TO_HANDLE_TYPE (this_class);
- tree function_type, method_type, fndecl;
+ tree function_type, fndecl;
unsigned char *sig = (unsigned char*)IDENTIFIER_POINTER (method_sig);
push_obstacks (&permanent_obstack, &permanent_obstack);
if (sig[0] != '(')
@@ -445,10 +471,6 @@ add_field (class, name, field_type, flags)
tree field;
/* Push the obstack of field_type ? FIXME */
push_obstacks (&permanent_obstack, &permanent_obstack);
-#if ! JAVA_PROMOTE_TO_INT
- if (TREE_CODE (field_type) == RECORD_TYPE)
-#endif
- field_type = promote_type (field_type);
field = build_decl (is_static ? VAR_DECL : FIELD_DECL, name, field_type);
pop_obstacks ();
TREE_CHAIN (field) = TYPE_FIELDS (class);
@@ -464,8 +486,9 @@ add_field (class, name, field_type, flags)
if (is_static)
{
FIELD_STATIC (field) = 1;
- if (! FIELD_PRIVATE (field) || FIELD_PROTECTED (field))
- TREE_PUBLIC (field) = 1;
+ /* Always make field externally visible. This is required so
+ that native methods can always access the field. */
+ TREE_PUBLIC (field) = 1;
}
return field;
}
@@ -487,6 +510,7 @@ set_constant_value (field, constant)
/* Count the number of Unicode chars encoded in a given Ut8 string. */
+#if 0
int
strLengthUtf8 (str, len)
char *str;
@@ -501,19 +525,20 @@ strLengthUtf8 (str, len)
}
return str_length;
}
+#endif
/* Calculate a hash value for a string encoded in Utf8 format.
* This returns the same hash value as specified for java.lang.String.hashCode.
*/
-int32
+static int32
hashUtf8String (str, len)
- char *str;
+ const char *str;
int len;
{
- register unsigned char* ptr = (unsigned char*) str;
- register unsigned char *limit = ptr + len;
+ register const unsigned char* ptr = (const unsigned char*) str;
+ register const unsigned char *limit = ptr + len;
int32 hash = 0;
for (; ptr < limit;)
{
@@ -563,12 +588,14 @@ build_utf8_ref (name)
/* Build a unique identifier based on buf. */
sprintf(buf, "_Utf%d", ++utf8_count);
buf_ptr = &buf[strlen (buf)];
+ if (name_len > 0 && name_ptr[0] >= '0' && name_ptr[0] <= '9')
+ *buf_ptr++ = '_';
while (--name_len >= 0)
{
- char c = *name_ptr++;
+ unsigned char c = *name_ptr++;
if (c & 0x80)
continue;
- if (!isalpha(c) && !isdigit(c))
+ if (!ISALPHA(c) && !ISDIGIT(c))
c = '_';
*buf_ptr++ = c;
if (buf_ptr >= buf + 50)
@@ -635,14 +662,42 @@ build_class_ref (type)
else
{
char *name;
- char buffer[20];
+ char buffer[25];
+ if (flag_emit_class_files)
+ {
+ const char *prim_class_name;
+ tree prim_class;
+ if (type == char_type_node)
+ prim_class_name = "java.lang.Character";
+ else if (type == boolean_type_node)
+ prim_class_name = "java.lang.Boolean";
+ else if (type == byte_type_node)
+ prim_class_name = "java.lang.Byte";
+ else if (type == short_type_node)
+ prim_class_name = "java.lang.Short";
+ else if (type == int_type_node)
+ prim_class_name = "java.lang.Integer";
+ else if (type == long_type_node)
+ prim_class_name = "java.lang.Long";
+ else if (type == float_type_node)
+ prim_class_name = "java.lang.Float";
+ else if (type == double_type_node)
+ prim_class_name = "java.lang.Double";
+ else if (type == void_type_node)
+ prim_class_name = "java.lang.Void";
+ else
+ fatal ("internal error - bad type to build_class_ref");
+ prim_class = lookup_class (get_identifier (prim_class_name));
+ return build (COMPONENT_REF, NULL_TREE,
+ prim_class, TYPE_identifier_node);
+ }
decl_name = TYPE_NAME (type);
if (TREE_CODE (decl_name) == TYPE_DECL)
decl_name = DECL_NAME (decl_name);
name = IDENTIFIER_POINTER (decl_name);
if (strncmp (name, "promoted_", 9) == 0)
name += 9;
- sprintf (buffer, "%sClass", name);
+ sprintf (buffer, "_Jv_%sClass", name);
decl_name = get_identifier (buffer);
decl = IDENTIFIER_GLOBAL_VALUE (decl_name);
if (decl == NULL_TREE)
@@ -795,8 +850,9 @@ get_access_flags_from_decl (decl)
abort ();
}
-tree
-make_field_value (tree fdecl)
+static tree
+make_field_value (fdecl)
+ tree fdecl;
{
tree finit, info;
int bsize, flags;
@@ -807,7 +863,12 @@ make_field_value (tree fdecl)
if (resolved)
type = build_class_ref (type);
else
- type = build_utf8_ref (build_java_signature (type));
+ {
+ tree signature = build_java_signature (type);
+ type = build_utf8_ref (unmangle_classname
+ (IDENTIFIER_POINTER(signature),
+ IDENTIFIER_LENGTH(signature)));
+ }
PUSH_FIELD_VALUE (finit, "type", type);
flags = get_access_flags_from_decl (fdecl);
if (! resolved)
@@ -836,10 +897,9 @@ make_field_value (tree fdecl)
return finit;
}
-tree
-make_method_value (mdecl, this_class_addr)
+static tree
+make_method_value (mdecl)
tree mdecl;
- tree this_class_addr;
{
tree minit;
tree code;
@@ -853,15 +913,21 @@ make_method_value (mdecl, this_class_addr)
build_utf8_ref (DECL_CONSTRUCTOR_P (mdecl) ?
init_identifier_node
: DECL_NAME (mdecl)));
- PUSH_FIELD_VALUE (minit, "signature",
- build_utf8_ref (build_java_signature (TREE_TYPE (mdecl))));
+ {
+ tree signature = build_java_signature (TREE_TYPE (mdecl));
+ PUSH_FIELD_VALUE (minit, "signature",
+ (build_utf8_ref
+ (unmangle_classname
+ (IDENTIFIER_POINTER(signature),
+ IDENTIFIER_LENGTH(signature)))));
+ }
PUSH_FIELD_VALUE (minit, "accflags", build_int_2 (accflags, 0));
PUSH_FIELD_VALUE (minit, "ncode", code);
FINISH_RECORD_CONSTRUCTOR (minit);
return minit;
}
-tree
+static tree
get_dispatch_vector (type)
tree type;
{
@@ -894,7 +960,7 @@ get_dispatch_vector (type)
return vtable;
}
-tree
+static tree
get_dispatch_table (type, this_class_addr)
tree type, this_class_addr;
{
@@ -994,7 +1060,11 @@ make_class_data (type)
for (method = TYPE_METHODS (CLASS_TO_HANDLE_TYPE (type));
method != NULL_TREE; method = TREE_CHAIN (method))
{
- tree init = make_method_value (method, this_class_addr);
+ tree init;
+ if (METHOD_PRIVATE (method)
+ && (flag_inline_functions || optimize))
+ continue;
+ init = make_method_value (method);
method_count++;
methods = tree_cons (NULL_TREE, init, methods);
}
@@ -1073,9 +1143,9 @@ make_class_data (type)
START_RECORD_CONSTRUCTOR (temp, object_type_node);
#if 0
- PUSH_FIELD_VALUE (temp, "dtable", NULL_TREE);
+ PUSH_FIELD_VALUE (temp, "vtable", NULL_TREE);
#else
- PUSH_FIELD_VALUE (temp, "dtable",
+ PUSH_FIELD_VALUE (temp, "vtable",
build1 (ADDR_EXPR, dtable_ptr_type, class_dtable_decl));
#endif
PUSH_FIELD_VALUE (temp, "sync_info", null_pointer_node);
@@ -1083,40 +1153,33 @@ make_class_data (type)
START_RECORD_CONSTRUCTOR (cons, class_type_node);
PUSH_SUPER_VALUE (cons, temp);
PUSH_FIELD_VALUE (cons, "next", null_pointer_node);
- PUSH_FIELD_VALUE (cons, "name",
- build_utf8_ref (build_internal_class_name (type)));
+ PUSH_FIELD_VALUE (cons, "name", build_utf8_ref (DECL_NAME (type_decl)));
PUSH_FIELD_VALUE (cons, "accflags",
build_int_2 (get_access_flags_from_decl (type_decl), 0));
- PUSH_FIELD_VALUE (cons, "superclass", super);
- PUSH_FIELD_VALUE (cons, "subclass_head", null_pointer_node);
- PUSH_FIELD_VALUE (cons, "subclass_next", null_pointer_node);
+ PUSH_FIELD_VALUE (cons, "superclass",
+ CLASS_INTERFACE (type_decl) ? null_pointer_node : super);
PUSH_FIELD_VALUE (cons, "constants", constant_pool_constructor);
PUSH_FIELD_VALUE (cons, "methods",
build1 (ADDR_EXPR, method_ptr_type_node, methods_decl));
- PUSH_FIELD_VALUE (cons, "nmethods", build_int_2 (method_count, 0));
- PUSH_FIELD_VALUE (cons, "msize", TYPE_NVIRTUALS (type));
+ PUSH_FIELD_VALUE (cons, "method_count", build_int_2 (method_count, 0));
+ PUSH_FIELD_VALUE (cons, "vtable_method_count", TYPE_NVIRTUALS (type));
PUSH_FIELD_VALUE (cons, "fields",
fields_decl == NULL_TREE ? null_pointer_node
: build1 (ADDR_EXPR, field_ptr_type_node, fields_decl));
- PUSH_FIELD_VALUE (cons, "bfsize", size_in_bytes (type));
- PUSH_FIELD_VALUE (cons, "nfields", build_int_2 (field_count, 0));
- PUSH_FIELD_VALUE (cons, "nsfields", build_int_2 (static_field_count, 0));
- /* For now, we let Kaffe fill in the dtable. */
- PUSH_FIELD_VALUE (cons, "dtable",
+ PUSH_FIELD_VALUE (cons, "size_in_bytes", size_in_bytes (type));
+ PUSH_FIELD_VALUE (cons, "field_count", build_int_2 (field_count, 0));
+ PUSH_FIELD_VALUE (cons, "static_field_count",
+ build_int_2 (static_field_count, 0));
+ PUSH_FIELD_VALUE (cons, "vtable",
dtable_decl == NULL_TREE ? null_pointer_node
: build1 (ADDR_EXPR, dtable_ptr_type, dtable_decl));
PUSH_FIELD_VALUE (cons, "interfaces", interfaces);
PUSH_FIELD_VALUE (cons, "loader", null_pointer_node);
- PUSH_FIELD_VALUE (cons, "interface_len", build_int_2 (interface_len, 0));
- PUSH_FIELD_VALUE (cons, "state",
- flag_assume_compiled ? integer_four_node
- : integer_two_node);
+ PUSH_FIELD_VALUE (cons, "interface_count", build_int_2 (interface_len, 0));
+ PUSH_FIELD_VALUE (cons, "state", integer_zero_node);
- method = lookup_java_method (type,
- finalize_identifier_node, void_signature_node);
- PUSH_FIELD_VALUE (cons, "final",
- method == NULL ? integer_zero_node : integer_one_node);
+ PUSH_FIELD_VALUE (cons, "thread", null_pointer_node);
FINISH_RECORD_CONSTRUCTOR (cons);
@@ -1124,6 +1187,35 @@ make_class_data (type)
rest_of_decl_compilation (decl, (char*) 0, 1, 0);
}
+void
+finish_class (cl)
+ tree cl;
+{
+ tree method;
+
+ /* Emit deferred inline methods. */
+ for ( method = TYPE_METHODS (CLASS_TO_HANDLE_TYPE (current_class));
+ method != NULL_TREE; method = TREE_CHAIN (method))
+ {
+ if (! TREE_ASM_WRITTEN (method) && DECL_SAVED_INSNS (method) != 0)
+ {
+ /* It's a deferred inline method. Decide if we need to emit it. */
+ if (flag_keep_inline_functions
+ || TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (method))
+ || ! METHOD_PRIVATE (method))
+ {
+ temporary_allocation ();
+ output_inline_function (method);
+ permanent_allocation (1);
+ }
+ }
+ }
+
+ make_class_data (current_class);
+ register_class ();
+ rest_of_decl_compilation (TYPE_NAME (current_class), (char*) 0, 1, 0);
+}
+
/* Return 2 if CLASS is compiled by this compilation job;
return 1 if CLASS can otherwise be assumed to be compiled;
return 0 if we cannot assume that CLASS is compiled.
@@ -1132,6 +1224,7 @@ int
is_compiled_class (class)
tree class;
{
+ int seen_in_zip;
if (TREE_CODE (class) == POINTER_TYPE)
class = TREE_TYPE (class);
if (TREE_CODE (class) != RECORD_TYPE) /* Primitive types are static. */
@@ -1140,25 +1233,33 @@ is_compiled_class (class)
return 0;
if (class == current_class)
return 2;
- if ((TYPE_LANG_SPECIFIC (class) && TYPE_LANG_SPECIFIC (class)->jcf &&
- TYPE_LANG_SPECIFIC (class)->jcf->seen_in_zip))
+
+ seen_in_zip = (TYPE_LANG_SPECIFIC (class) && TYPE_LANG_SPECIFIC (class)->jcf
+ && TYPE_LANG_SPECIFIC (class)->jcf->seen_in_zip);
+ if (CLASS_FROM_CURRENTLY_COMPILED_SOURCE_P (class) || seen_in_zip)
{
/* The class was seen in the current ZIP file and will be
available as a compiled class in the future but may not have
been loaded already. Load it if necessary. This prevent
- build_class_ref () from crashing. This should take into
- consideration class specified in a multiple class file
- command line. FIXME if necessary. */
+ build_class_ref () from crashing. */
- if (!CLASS_LOADED_P (class))
+ if (seen_in_zip && !CLASS_LOADED_P (class))
load_class (class, 1);
+
+ /* We return 2 for class seen in ZIP and class from files
+ belonging to the same compilation unit */
return 2;
}
if (flag_assume_compiled)
{
if (!CLASS_LOADED_P (class))
- load_class (class, 1);
+ {
+ if (CLASS_FROM_SOURCE_P (class))
+ safe_layout_class (class);
+ else
+ load_class (class, 1);
+ }
return 1;
}
@@ -1167,14 +1268,11 @@ is_compiled_class (class)
/* Append the mangled name of TYPE onto OBSTACK. */
-void
+static void
append_gpp_mangled_type (obstack, type)
struct obstack *obstack;
tree type;
{
- char buf[8];
- int len;
- char *ptr;
switch (TREE_CODE (type))
{
char code;
@@ -1245,7 +1343,7 @@ mangle_class_field (class)
/* Build the mangled (assembly-level) name of the static field FIELD. */
-tree
+static tree
mangle_static_field (field)
tree field;
{
@@ -1323,39 +1421,59 @@ push_super_field (this_class, super_class)
DECL_SIZE (base_decl) = TYPE_SIZE (super_class);
}
+/* Handle the different manners we may have to lay out a super class. */
+
+static tree
+maybe_layout_super_class (super_class, this_class)
+ tree super_class;
+ tree this_class;
+{
+ if (TREE_CODE (super_class) == RECORD_TYPE)
+ {
+ if (!CLASS_LOADED_P (super_class)
+ && CLASS_FROM_SOURCE_P (super_class))
+ safe_layout_class (super_class);
+ if (!CLASS_LOADED_P (super_class))
+ load_class (super_class, 1);
+ }
+ /* We might have to layout the class before its dependency on
+ the super class gets resolved by java_complete_class */
+ else if (TREE_CODE (super_class) == POINTER_TYPE)
+ {
+ if (TREE_TYPE (super_class) != NULL_TREE)
+ super_class = TREE_TYPE (super_class);
+ else
+ {
+ super_class = do_resolve_class (super_class, NULL_TREE, this_class);
+ if (!super_class)
+ return NULL_TREE; /* FIXME, NULL_TREE not checked by caller. */
+ super_class = TREE_TYPE (super_class);
+ }
+ }
+ if (!TYPE_SIZE (super_class))
+ safe_layout_class (super_class);
+
+ return super_class;
+}
+
void
layout_class (this_class)
tree this_class;
{
tree super_class = CLASSTYPE_SUPER (this_class);
- tree handle_type = CLASS_TO_HANDLE_TYPE (this_class);
- tree method_decl, field;
- tree dtable_count;
- int i;
+ tree field;
if (super_class)
{
- /* Class seen in source are now complete and can be layed out.
- Once layed out, a class seen in the source has its
- CLASS_LOADED_P flag set */
- if (CLASS_FROM_SOURCE_P (super_class) && !CLASS_LOADED_P (super_class))
- safe_layout_class (super_class);
- if (! CLASS_LOADED_P (super_class))
- load_class (super_class, 1);
+ super_class = maybe_layout_super_class (super_class, this_class);
if (TREE_CODE (TYPE_SIZE (super_class)) == ERROR_MARK)
{
TYPE_SIZE (this_class) = error_mark_node;
return;
}
- dtable_count = TYPE_NVIRTUALS (super_class);
-
if (TYPE_SIZE (this_class) == NULL_TREE)
push_super_field (this_class, super_class);
}
- else
- {
- dtable_count = integer_zero_node;
- }
for (field = TYPE_FIELDS (this_class);
field != NULL_TREE; field = TREE_CHAIN (field))
@@ -1368,168 +1486,197 @@ layout_class (this_class)
}
layout_type (this_class);
+}
+void
+layout_class_methods (this_class)
+ tree this_class;
+{
+ tree method_decl, dtable_count;
+ tree super_class, handle_type;
+
+ if (TYPE_NVIRTUALS (this_class))
+ return;
+
+ push_obstacks (&permanent_obstack, &permanent_obstack);
+ super_class = CLASSTYPE_SUPER (this_class);
+ handle_type = CLASS_TO_HANDLE_TYPE (this_class);
+
+ if (super_class)
+ {
+ super_class = maybe_layout_super_class (super_class, this_class);
+ if (!TYPE_NVIRTUALS (super_class))
+ layout_class_methods (super_class);
+ dtable_count = TYPE_NVIRTUALS (super_class);
+ }
+ else
+ dtable_count = integer_zero_node;
+
TYPE_METHODS (handle_type) = nreverse (TYPE_METHODS (handle_type));
- for (method_decl = TYPE_METHODS (handle_type), i = 0;
- method_decl; method_decl = TREE_CHAIN (method_decl), i++)
+ for (method_decl = TYPE_METHODS (handle_type);
+ method_decl; method_decl = TREE_CHAIN (method_decl))
+ dtable_count = layout_class_method (this_class, super_class,
+ method_decl, dtable_count);
+
+ TYPE_NVIRTUALS (this_class) = dtable_count;
+
+#ifdef JAVA_USE_HANDLES
+ layout_type (handle_type);
+#endif
+ pop_obstacks ();
+}
+
+/* Lay METHOD_DECL out, returning a possibly new value of
+ DTABLE_COUNT. */
+
+tree
+layout_class_method (this_class, super_class, method_decl, dtable_count)
+ tree this_class, super_class, method_decl, dtable_count;
+{
+ char *ptr;
+ char *asm_name;
+ tree arg, arglist, t;
+ int method_name_needs_escapes = 0;
+ tree method_name = DECL_NAME (method_decl);
+ int method_name_is_wfl =
+ (TREE_CODE (method_name) == EXPR_WITH_FILE_LOCATION);
+ if (method_name_is_wfl)
+ method_name = java_get_real_method_name (method_decl);
+
+ if (method_name != init_identifier_node
+ && method_name != finit_identifier_node)
{
- char *ptr;
- char buf[8];
- char *asm_name;
- tree method_name = DECL_NAME (method_decl);
-#if 1
- /* Remove this once we no longer need old (Kaffe / JDK 1.0) mangling. */
- if (! flag_assume_compiled && METHOD_NATIVE (method_decl))
+ int encoded_len
+ = unicode_mangling_length (IDENTIFIER_POINTER (method_name),
+ IDENTIFIER_LENGTH (method_name));
+ if (encoded_len > 0)
{
- for (ptr = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (this_class)));
- *ptr; )
- {
- int ch = *ptr++;
- if (ch == '.')
- ch = '_';
- obstack_1grow (&temporary_obstack, (char) ch);
- }
- obstack_1grow (&temporary_obstack, (char) '_');
- if (method_name == init_identifier_node)
- obstack_grow (&temporary_obstack, "INIT", 4);
- else
- obstack_grow (&temporary_obstack,
- IDENTIFIER_POINTER (method_name),
- IDENTIFIER_LENGTH (method_name));
+ method_name_needs_escapes = 1;
+ emit_unicode_mangled_name (&temporary_obstack,
+ IDENTIFIER_POINTER (method_name),
+ IDENTIFIER_LENGTH (method_name));
}
else
-#endif
{
- int len; tree arg, arglist, t;
- int method_name_needs_escapes = 0;
- if (method_name != init_identifier_node)
+ obstack_grow (&temporary_obstack,
+ IDENTIFIER_POINTER (method_name),
+ IDENTIFIER_LENGTH (method_name));
+ }
+ }
+
+ obstack_grow (&temporary_obstack, "__", 2);
+ if (method_name == finit_identifier_node)
+ obstack_grow (&temporary_obstack, "finit", 5);
+ append_gpp_mangled_type (&temporary_obstack, this_class);
+ TREE_PUBLIC (method_decl) = 1;
+
+ t = TREE_TYPE (method_decl);
+ arglist = TYPE_ARG_TYPES (t);
+ if (TREE_CODE (t) == METHOD_TYPE)
+ arglist = TREE_CHAIN (arglist);
+ for (arg = arglist; arg != end_params_node; )
+ {
+ tree a = arglist;
+ tree argtype = TREE_VALUE (arg);
+ int tindex = 1;
+ if (TREE_CODE (argtype) == POINTER_TYPE)
+ {
+ /* This is O(N**2). Do we care? Cfr gcc/cp/method.c. */
+ while (a != arg && argtype != TREE_VALUE (a))
+ a = TREE_CHAIN (a), tindex++;
+ }
+ else
+ a = arg;
+ if (a != arg)
+ {
+ char buf[12];
+ int nrepeats = 0;
+ do
{
- int encoded_len
- = unicode_mangling_length (IDENTIFIER_POINTER (method_name),
- IDENTIFIER_LENGTH (method_name));
- if (encoded_len > 0)
- {
- method_name_needs_escapes = 1;
- emit_unicode_mangled_name (&temporary_obstack,
- IDENTIFIER_POINTER (method_name),
- IDENTIFIER_LENGTH (method_name));
- }
- else
- {
- obstack_grow (&temporary_obstack,
- IDENTIFIER_POINTER (method_name),
- IDENTIFIER_LENGTH (method_name));
- }
+ arg = TREE_CHAIN (arg); nrepeats++;
}
-
- obstack_grow (&temporary_obstack, "__", 2);
- append_gpp_mangled_type (&temporary_obstack, this_class);
- TREE_PUBLIC (method_decl) = 1;
-
- t = TREE_TYPE (method_decl);
- arglist = TYPE_ARG_TYPES (t);
- if (TREE_CODE (t) == METHOD_TYPE)
- arglist = TREE_CHAIN (arglist);
- for (arg = arglist; arg != NULL_TREE; )
+ while (arg != end_params_node && argtype == TREE_VALUE (arg));
+ if (nrepeats > 1)
{
- tree a = arglist;
- tree argtype = TREE_VALUE (arg);
- int tindex = 1;
- if (TREE_CODE (argtype) == POINTER_TYPE)
- {
- /* This is O(N**2). Do we care? Cfr gcc/cp/method.c. */
- while (a != arg && argtype != TREE_VALUE (a))
- a = TREE_CHAIN (a), tindex++;
- }
- else
- a = arg;
- if (a != arg)
- {
- char buf[12];
- int nrepeats = 0;
- do
- {
- arg = TREE_CHAIN (arg); nrepeats++;
- }
- while (arg != NULL_TREE && argtype == TREE_VALUE (arg));
- if (nrepeats > 1)
- {
- obstack_1grow (&temporary_obstack, 'N');
- sprintf (buf, "%d", nrepeats);
- obstack_grow (&temporary_obstack, buf, strlen (buf));
- if (nrepeats > 9)
- obstack_1grow (&temporary_obstack, '_');
- }
- else
- obstack_1grow (&temporary_obstack, 'T');
- sprintf (buf, "%d", tindex);
- obstack_grow (&temporary_obstack, buf, strlen (buf));
- if (tindex > 9)
- obstack_1grow (&temporary_obstack, '_');
- }
- else
- {
- append_gpp_mangled_type (&temporary_obstack, argtype);
- arg = TREE_CHAIN (arg);
- }
+ obstack_1grow (&temporary_obstack, 'N');
+ sprintf (buf, "%d", nrepeats);
+ obstack_grow (&temporary_obstack, buf, strlen (buf));
+ if (nrepeats > 9)
+ obstack_1grow (&temporary_obstack, '_');
}
- if (method_name_needs_escapes)
- obstack_1grow (&temporary_obstack, 'U');
+ else
+ obstack_1grow (&temporary_obstack, 'T');
+ sprintf (buf, "%d", tindex);
+ obstack_grow (&temporary_obstack, buf, strlen (buf));
+ if (tindex > 9)
+ obstack_1grow (&temporary_obstack, '_');
}
- obstack_1grow (&temporary_obstack, '\0');
- asm_name = obstack_finish (&temporary_obstack);
- DECL_ASSEMBLER_NAME (method_decl) = get_identifier (asm_name);
- if (! METHOD_ABSTRACT (method_decl))
- make_function_rtl (method_decl);
- obstack_free (&temporary_obstack, asm_name);
-
- if (method_name == init_identifier_node)
+ else
{
- char *p = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (this_class)));
- for (ptr = p; *ptr; )
- {
- if (*ptr++ == '.')
- p = ptr;
- }
- DECL_NAME (method_decl) = get_identifier (p);
- DECL_CONSTRUCTOR_P (method_decl) = 1;
+ append_gpp_mangled_type (&temporary_obstack, argtype);
+ arg = TREE_CHAIN (arg);
}
- else if (! METHOD_STATIC (method_decl))
+ }
+ if (method_name_needs_escapes)
+ obstack_1grow (&temporary_obstack, 'U');
+
+ obstack_1grow (&temporary_obstack, '\0');
+ asm_name = obstack_finish (&temporary_obstack);
+ DECL_ASSEMBLER_NAME (method_decl) = get_identifier (asm_name);
+ if (! METHOD_ABSTRACT (method_decl)
+ && ! CLASS_INTERFACE (TYPE_NAME (this_class)))
+ make_function_rtl (method_decl);
+ obstack_free (&temporary_obstack, asm_name);
+
+ if (method_name == init_identifier_node)
+ {
+ char *p = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (this_class)));
+ for (ptr = p; *ptr; )
{
- tree method_sig = build_java_argument_signature (TREE_TYPE (method_decl));
- tree super_method = lookup_argument_method (super_class, method_name,
+ if (*ptr++ == '.')
+ p = ptr;
+ }
+ if (method_name_is_wfl)
+ EXPR_WFL_NODE (DECL_NAME (method_decl)) = get_identifier (p);
+ else
+ DECL_NAME (method_decl) = get_identifier (p);
+ DECL_CONSTRUCTOR_P (method_decl) = 1;
+ build_java_argument_signature (TREE_TYPE (method_decl));
+ }
+ else if (! METHOD_STATIC (method_decl) && !DECL_ARTIFICIAL (method_decl))
+ {
+ tree method_sig =
+ build_java_argument_signature (TREE_TYPE (method_decl));
+ tree super_method = lookup_argument_method (super_class, method_name,
method_sig);
- if (super_method != NULL_TREE)
- {
- DECL_VINDEX (method_decl) = DECL_VINDEX (super_method);
- if (DECL_VINDEX (method_decl) == NULL_TREE)
- error_with_decl (method_decl,
- "non-static method '%s' overrides static method");
+ if (super_method != NULL_TREE && ! METHOD_PRIVATE (super_method))
+ {
+ DECL_VINDEX (method_decl) = DECL_VINDEX (super_method);
+ if (DECL_VINDEX (method_decl) == NULL_TREE)
+ error_with_decl (method_decl,
+ "non-static method '%s' overrides static method");
#if 0
- else if (TREE_TYPE (TREE_TYPE (method_decl))
- != TREE_TYPE (TREE_TYPE (super_method)))
- {
- error_with_decl (method_decl,
- "Method `%s' redefined with different return type");
- error_with_decl (super_method,
- "Overridden decl is here");
- }
-#endif
- }
- else if (! METHOD_FINAL (method_decl)
- && ! CLASS_FINAL (TYPE_NAME (this_class)))
+ else if (TREE_TYPE (TREE_TYPE (method_decl))
+ != TREE_TYPE (TREE_TYPE (super_method)))
{
- DECL_VINDEX (method_decl) = dtable_count;
- dtable_count = build_int_2 (1+TREE_INT_CST_LOW (dtable_count), 0);
+ error_with_decl (method_decl,
+ "Method `%s' redefined with different return type");
+ error_with_decl (super_method,
+ "Overridden decl is here");
}
+#endif
+ }
+ else if (! METHOD_FINAL (method_decl)
+ && ! METHOD_PRIVATE (method_decl)
+ && ! CLASS_FINAL (TYPE_NAME (this_class))
+ && dtable_count)
+ {
+ DECL_VINDEX (method_decl) = dtable_count;
+ dtable_count = build_int_2 (1+TREE_INT_CST_LOW (dtable_count), 0);
}
}
- TYPE_NVIRTUALS (this_class) = dtable_count;
-
-#ifdef JAVA_USE_HANDLES
- layout_type (handle_type);
-#endif
+ return dtable_count;
}
static tree registered_class = NULL_TREE;
@@ -1554,13 +1701,13 @@ register_class ()
which calls registerClass for all the compiled classes. */
void
-emit_register_class ()
+emit_register_classes ()
{
tree decl = getdecls ();
extern tree get_file_function_name PROTO((int));
tree init_name = get_file_function_name ('I');
- tree init_type = build_function_type (void_type_node, NULL_TREE);
+ tree init_type = build_function_type (void_type_node, end_params_node);
tree init_decl;
tree t;
@@ -1585,7 +1732,6 @@ emit_register_class ()
poplevel (1, 0, 1);
{
/* Force generation, even with -O3 or deeper. Gross hack. FIXME */
- extern int flag_inline_functions;
int saved_flag = flag_inline_functions;
flag_inline_functions = 0;
rest_of_compilation (init_decl);
@@ -1598,5 +1744,5 @@ emit_register_class ()
void
init_class_processing ()
{
- registerClass_libfunc = gen_rtx (SYMBOL_REF, Pmode, "registerClass");
+ registerClass_libfunc = gen_rtx (SYMBOL_REF, Pmode, "_Jv_RegisterClass");
}
diff --git a/gcc/java/config-lang.in b/gcc/java/config-lang.in
index 571e65a734b..07f77493037 100644
--- a/gcc/java/config-lang.in
+++ b/gcc/java/config-lang.in
@@ -35,6 +35,6 @@ language="java"
compilers="jc1\$(exeext) jvgenmain\$(exeext)"
-stagestuff="jc1\$(exeext) gcj\$(exeext) jvgenmain\$(exeext) gcjh\$(exeext)"
+stagestuff="jc1\$(exeext) gcj\$(exeext) jvgenmain\$(exeext) gcjh\$(exeext) jv-scan\$(exeext) jcf-dump\$(exeext)"
outputs=java/Makefile
diff --git a/gcc/java/constants.c b/gcc/java/constants.c
index 507d4847387..a1f820e0dd2 100644
--- a/gcc/java/constants.c
+++ b/gcc/java/constants.c
@@ -23,16 +23,22 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */
#include "config.h"
#include "system.h"
+#include "jcf.h"
#include "tree.h"
#include "java-tree.h"
-#include "jcf.h"
#include "toplev.h"
extern struct obstack permanent_obstack;
+static void set_constant_entry PROTO ((CPool *, int, int, jword));
+static int find_class_or_string_constant PROTO ((CPool *, int, tree));
+static int find_name_and_type_constant PROTO ((CPool *, tree, tree));
+static tree get_tag_node PROTO ((int));
+static tree build_constant_data_ref PROTO ((void));
+
/* Set the INDEX'th constant in CPOOL to have the given TAG and VALUE. */
-void
+static void
set_constant_entry (cpool, index, tag, value)
CPool *cpool;
int index;
@@ -113,7 +119,7 @@ find_utf8_constant (cpool, name)
return find_constant1 (cpool, CONSTANT_Utf8, (jword) name);
}
-int
+static int
find_class_or_string_constant (cpool, tag, name)
CPool *cpool;
int tag;
@@ -123,7 +129,7 @@ find_class_or_string_constant (cpool, tag, name)
int i;
for (i = cpool->count; --i > 0; )
{
- if (cpool->tags[i] == tag && cpool->data[i] == j)
+ if (cpool->tags[i] == tag && cpool->data[i] == (jword) j)
return i;
}
i = cpool->count;
@@ -140,10 +146,22 @@ find_class_constant (cpool, type)
build_internal_class_name (type));
}
+/* Allocate a CONSTANT_string entry given a STRING_CST. */
+
+int
+find_string_constant (cpool, string)
+ CPool *cpool;
+ tree string;
+{
+ string = get_identifier (TREE_STRING_POINTER (string));
+ return find_class_or_string_constant (cpool, CONSTANT_String, string);
+
+}
+
/* Find (or create) a CONSTANT_NameAndType matching NAME and TYPE.
Return its index in the constant pool CPOOL. */
-int
+static int
find_name_and_type_constant (cpool, name, type)
CPool *cpool;
tree name;
@@ -178,13 +196,16 @@ find_methodref_index (cpool, decl)
CPool *cpool;
tree decl;
{
- int class_index = find_class_constant (cpool, DECL_CONTEXT (decl));
+ tree mclass = DECL_CONTEXT (decl);
+ int class_index = find_class_constant (cpool, mclass);
tree name = DECL_CONSTRUCTOR_P (decl) ? init_identifier_node
: DECL_NAME (decl);
int name_type_index
= find_name_and_type_constant (cpool, name, TREE_TYPE (decl));
- /* Methodref or INterfacemethodRef - FIXME */
- return find_constant1 (cpool, CONSTANT_Methodref,
+ return find_constant1 (cpool,
+ CLASS_INTERFACE (TYPE_NAME (mclass))
+ ? CONSTANT_InterfaceMethodref
+ : CONSTANT_Methodref,
(class_index << 16) | name_type_index);
}
@@ -202,8 +223,7 @@ count_constant_pool_bytes (cpool)
{
int size = 2;
int i = 1;
- jword *datap = &cpool->data[1];;
- for ( ; i < cpool->count; i++, datap++)
+ for ( ; i < cpool->count; i++)
{
size++;
switch (cpool->tags[i])
@@ -222,15 +242,19 @@ count_constant_pool_bytes (cpool)
break;
case CONSTANT_Long:
case CONSTANT_Double:
- size += 4;
+ size += 8;
+ i++;
break;
case CONSTANT_Utf8:
{
- tree t = (tree) *datap;
+ tree t = (tree) cpool->data[i];
int len = IDENTIFIER_LENGTH (t);
size += len + 2;
}
break;
+ default:
+ /* Second word of CONSTANT_Long and CONSTANT_Double. */
+ size--;
}
}
return size;
@@ -298,7 +322,7 @@ tree current_constant_pool_data_ref;
/* A Cache for build_int_2 (CONSTANT_XXX, 0). */
static tree tag_nodes[13];
-tree
+static tree
get_tag_node (tag)
int tag;
{
@@ -350,14 +374,17 @@ int
alloc_class_constant (clas)
tree clas;
{
-
+ tree class_name = build_internal_class_name (clas);
+
return alloc_name_constant (CONSTANT_Class,
- build_internal_class_name (clas));
+ (unmangle_classname
+ (IDENTIFIER_POINTER(class_name),
+ IDENTIFIER_LENGTH(class_name))));
}
/* Return a reference to the data array of the current constant pool. */
-tree
+static tree
build_constant_data_ref ()
{
if (current_constant_pool_data_ref == NULL_TREE)
diff --git a/gcc/java/convert.h b/gcc/java/convert.h
index 1e1373e5e41..a627bc2aca8 100644
--- a/gcc/java/convert.h
+++ b/gcc/java/convert.h
@@ -1,3 +1,4 @@
+
/* Definition of conversion functions.
Copyright (C) 1993 Free Software Foundation, Inc.
@@ -22,3 +23,6 @@ Boston, MA 02111-1307, USA. */
extern tree convert_to_boolean PROTO ((tree, tree));
extern tree convert_to_char PROTO ((tree, tree));
+extern tree convert_to_integer PROTO ((tree type, tree expr));
+extern tree convert_to_real PROTO ((tree type, tree expr));
+extern tree convert_to_pointer PROTO ((tree type, tree expr));
diff --git a/gcc/java/decl.c b/gcc/java/decl.c
index 1d00ee5f533..e98fb51429a 100644
--- a/gcc/java/decl.c
+++ b/gcc/java/decl.c
@@ -1,7 +1,7 @@
/* Process declarations and variables for the GNU compiler for the
Java(TM) language.
- Copyright (C) 1996, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1996, 97-98, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -33,6 +33,15 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */
#include "jcf.h"
#include "toplev.h"
+static tree push_jvm_slot PROTO ((int, tree));
+static tree builtin_function PROTO ((const char *, tree,
+ enum built_in_function, const char *));
+static tree lookup_name_current_level PROTO ((tree));
+
+#ifndef INT_TYPE_SIZE
+#define INT_TYPE_SIZE BITS_PER_WORD
+#endif
+
/* The DECL_MAP is a mapping from (index, type) to a decl node.
If index < max_locals, it is the index of a local variable.
if index >= max_locals, then index-max_locals is a stack slot.
@@ -51,7 +60,7 @@ tree pending_local_decls = NULL_TREE;
/* Push a local variable or stack slot into the decl_map,
and assign it an rtl. */
-tree
+static tree
push_jvm_slot (index, decl)
int index;
tree decl;
@@ -109,7 +118,6 @@ find_local_variable (index, type, pc)
tree type;
int pc;
{
- struct rtx_def *rtl = NULL;
tree decl = TREE_VEC_ELT (decl_map, index);
tree best = NULL_TREE;
while (decl != NULL_TREE)
@@ -243,9 +251,12 @@ tree current_function_decl;
tree char_type_node;
tree object_type_node;
+tree unqualified_object_id_node;
tree object_ptr_type_node;
tree string_type_node;
tree throwable_type_node;
+tree runtime_exception_type_node;
+tree error_exception_type_node;
tree boolean_type_node;
@@ -309,9 +320,15 @@ tree class_dtable_decl;
tree error_mark_node;
/* Two expressions that are constants with value zero.
- The first is of type `int', the second of type `void *'. */
+ The first is of type `int', the second of type `void *'.
+ Other of type `long', `float' and `double' follow. */
tree integer_zero_node;
tree null_pointer_node;
+tree long_zero_node;
+tree float_zero_node;
+tree double_zero_node;
+
+tree empty_stmt_node;
/* Nodes for boolean constants TRUE and FALSE. */
tree boolean_true_node, boolean_false_node;
@@ -319,11 +336,14 @@ tree boolean_true_node, boolean_false_node;
tree TYPE_identifier_node;
tree init_identifier_node;
tree clinit_identifier_node;
-tree finalize_identifier_node;
+tree finit_identifier_node;
tree void_signature_node;
tree length_identifier_node;
tree this_identifier_node;
tree super_identifier_node;
+tree continue_identifier_node;
+
+tree end_params_node;
/* References to internal libjava functions we use. */
tree alloc_object_node;
@@ -340,6 +360,7 @@ tree soft_monitorenter_node;
tree soft_monitorexit_node;
tree soft_lookupinterfacemethod_node;
tree soft_fmod_node;
+tree soft_exceptioninfo_call_node;
/* Build (and pushdecl) a "promoted type" for all standard
types shorter than int. */
@@ -381,12 +402,12 @@ tree integer_negative_one_node;
If LIBRARY_NAME is nonzero, use that for DECL_ASSEMBLER_NAME,
the name to be called if we can't opencode the function. */
-tree
+static tree
builtin_function (name, type, function_code, library_name)
- char *name;
+ const char *name;
tree type;
enum built_in_function function_code;
- char *library_name;
+ const char *library_name;
{
tree decl = build_decl (FUNCTION_DECL, get_identifier (name), type);
DECL_EXTERNAL (decl) = 1;
@@ -406,6 +427,7 @@ builtin_function (name, type, function_code, library_name)
void
init_decl_processing ()
{
+ register tree endlink;
tree field;
tree t;
@@ -447,7 +469,7 @@ init_decl_processing ()
pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned long"),
unsigned_long_type_node));
- integer_type_node = int_type_node;
+ integer_type_node = type_for_size (INT_TYPE_SIZE, 0);
integer_zero_node = build_int_2 (0, 0);
integer_one_node = build_int_2 (1, 0);
@@ -455,6 +477,9 @@ init_decl_processing ()
integer_four_node = build_int_2 (4, 0);
integer_negative_one_node = build_int_2 (-1, 0);
+ long_zero_node = build_int_2 (0, 0);
+ TREE_TYPE (long_zero_node) = long_type_node;
+
void_type_node = make_node (VOID_TYPE);
pushdecl (build_decl (TYPE_DECL, get_identifier ("void"), void_type_node));
layout_type (void_type_node); /* Uses size_zero_node */
@@ -466,6 +491,10 @@ init_decl_processing ()
null_pointer_node = build_int_2 (0, 0);
TREE_TYPE (null_pointer_node) = ptr_type_node;
+ /* Used by the parser to represent empty statements and blocks. */
+ empty_stmt_node = build1 (NOP_EXPR, void_type_node, size_zero_node);
+ CAN_COMPLETE_NORMALLY (empty_stmt_node) = 1;
+
#if 0
/* Make a type to be the domain of a few array types
whose domains don't really matter.
@@ -508,26 +537,34 @@ init_decl_processing ()
double_type_node));
layout_type (double_type_node);
+ float_zero_node = build_real (float_type_node, dconst0);
+ double_zero_node = build_real (double_type_node, dconst0);
+
+ unqualified_object_id_node = get_identifier ("Object");
object_type_node = lookup_class (get_identifier ("java.lang.Object"));
object_ptr_type_node = promote_type (object_type_node);
string_type_node = lookup_class (get_identifier ("java.lang.String"));
class_type_node = lookup_class (get_identifier ("java.lang.Class"));
throwable_type_node = lookup_class (get_identifier ("java.lang.Throwable"));
+ runtime_exception_type_node =
+ lookup_class (get_identifier ("java.lang.RuntimeException"));
+ error_exception_type_node =
+ lookup_class (get_identifier ("java.lang.Error"));
methodtable_type = make_node (RECORD_TYPE);
layout_type (methodtable_type);
- pushdecl (build_decl (TYPE_DECL, get_identifier ("methodtable"),
- methodtable_type));
+ build_decl (TYPE_DECL, get_identifier ("methodtable"), methodtable_type);
methodtable_ptr_type = build_pointer_type (methodtable_type);
TYPE_identifier_node = get_identifier ("TYPE");
init_identifier_node = get_identifier ("<init>");
clinit_identifier_node = get_identifier ("<clinit>");
- finalize_identifier_node = get_identifier ("finalize");
+ finit_identifier_node = get_identifier ("$finit$");
void_signature_node = get_identifier ("()V");
length_identifier_node = get_identifier ("length");
this_identifier_node = get_identifier ("this");
super_identifier_node = get_identifier ("super");
+ continue_identifier_node = get_identifier ("continue");
/* for lack of a better place to put this stub call */
init_expr_processing();
@@ -543,15 +580,14 @@ init_decl_processing ()
PUSH_FIELD (constants_type_node, field, "tags", ptr_type_node);
PUSH_FIELD (constants_type_node, field, "data", ptr_type_node);
FINISH_RECORD (constants_type_node);
- pushdecl (build_decl (TYPE_DECL, get_identifier ("constants"),
- constants_type_node));
+ build_decl (TYPE_DECL, get_identifier ("constants"), constants_type_node);
access_flags_type_node = unsigned_short_type_node;
dtable_type = make_node (RECORD_TYPE);
dtable_ptr_type = build_pointer_type (dtable_type);
- PUSH_FIELD (object_type_node, field, "dtable", dtable_ptr_type);
+ PUSH_FIELD (object_type_node, field, "vtable", dtable_ptr_type);
PUSH_FIELD (object_type_node, field, "sync_info", ptr_type_node);
for (t = TYPE_FIELDS (object_type_node); t != NULL_TREE; t = TREE_CHAIN (t))
FIELD_PRIVATE (t) = 1;
@@ -576,28 +612,26 @@ init_decl_processing ()
PUSH_FIELD (class_type_node, field, "name", utf8const_ptr_type);
PUSH_FIELD (class_type_node, field, "accflags", access_flags_type_node);
PUSH_FIELD (class_type_node, field, "superclass", class_ptr_type);
- PUSH_FIELD (class_type_node, field, "subclass_head", class_ptr_type);
- PUSH_FIELD (class_type_node, field, "subclass_next", class_ptr_type);
PUSH_FIELD (class_type_node, field, "constants", constants_type_node);
PUSH_FIELD (class_type_node, field, "methods", method_ptr_type_node);
- PUSH_FIELD (class_type_node, field, "nmethods", short_type_node);
- PUSH_FIELD (class_type_node, field, "msize", short_type_node);
+ PUSH_FIELD (class_type_node, field, "method_count", short_type_node);
+ PUSH_FIELD (class_type_node, field, "vtable_method_count", short_type_node);
PUSH_FIELD (class_type_node, field, "fields", field_ptr_type_node);
- PUSH_FIELD (class_type_node, field, "bfsize", int_type_node);
- PUSH_FIELD (class_type_node, field, "nfields", short_type_node);
- PUSH_FIELD (class_type_node, field, "nsfields", short_type_node);
- PUSH_FIELD (class_type_node, field, "dtable", dtable_ptr_type);
+ PUSH_FIELD (class_type_node, field, "size_in_bytes", int_type_node);
+ PUSH_FIELD (class_type_node, field, "field_count", short_type_node);
+ PUSH_FIELD (class_type_node, field, "static_field_count", short_type_node);
+ PUSH_FIELD (class_type_node, field, "vtable", dtable_ptr_type);
PUSH_FIELD (class_type_node, field, "interfaces",
build_pointer_type (class_ptr_type));
PUSH_FIELD (class_type_node, field, "loader", ptr_type_node);
- PUSH_FIELD (class_type_node, field, "interface_len", short_type_node);
+ PUSH_FIELD (class_type_node, field, "interface_count", short_type_node);
PUSH_FIELD (class_type_node, field, "state", byte_type_node);
- PUSH_FIELD (class_type_node, field, "final", byte_type_node);
+ PUSH_FIELD (class_type_node, field, "thread", ptr_type_node);
for (t = TYPE_FIELDS (class_type_node); t != NULL_TREE; t = TREE_CHAIN (t))
FIELD_PRIVATE (t) = 1;
push_super_field (class_type_node, object_type_node);
FINISH_RECORD (class_type_node);
- pushdecl (build_decl (TYPE_DECL, get_identifier ("Class"), class_type_node));
+ build_decl (TYPE_DECL, get_identifier ("Class"), class_type_node);
field_info_union_node = make_node (UNION_TYPE);
PUSH_FIELD (field_info_union_node, field, "boffset", int_type_node);
@@ -614,7 +648,7 @@ init_decl_processing ()
PUSH_FIELD (field_type_node, field, "info", field_info_union_node);
FINISH_RECORD (field_type_node);
CLASS_LOADED_P (field_type_node) = 1;
- pushdecl (build_decl (TYPE_DECL, get_identifier ("Field"), field_type_node));
+ build_decl (TYPE_DECL, get_identifier ("Field"), field_type_node);
one_elt_array_domain_type = build_index_type (integer_one_node);
nativecode_ptr_array_type_node
@@ -623,7 +657,7 @@ init_decl_processing ()
PUSH_FIELD (dtable_type, field, "class", class_ptr_type);
PUSH_FIELD (dtable_type, field, "methods", nativecode_ptr_array_type_node);
FINISH_RECORD (dtable_type);
- pushdecl (build_decl (TYPE_DECL, get_identifier ("dispatchTable"), dtable_type));
+ build_decl (TYPE_DECL, get_identifier ("dispatchTable"), dtable_type);
#define jint_type int_type_node
#define jint_ptr_type ptr_type_node
@@ -634,7 +668,7 @@ init_decl_processing ()
PUSH_FIELD (jexception_type, field, "handler_pc", ptr_type_node);
PUSH_FIELD (jexception_type, field, "catch_type", class_ptr_type);
FINISH_RECORD (jexception_type);
- pushdecl (build_decl (TYPE_DECL, get_identifier ("jexception"), field_type_node));
+ build_decl (TYPE_DECL, get_identifier ("jexception"), field_type_node);
jexception_ptr_type = build_pointer_type (jexception_type);
lineNumberEntry_type = make_node (RECORD_TYPE);
@@ -656,10 +690,12 @@ init_decl_processing ()
PUSH_FIELD (method_type_node, field, "ncode", nativecode_ptr_type_node);
FINISH_RECORD (method_type_node);
CLASS_LOADED_P (method_type_node) = 1;
- pushdecl (build_decl (TYPE_DECL, get_identifier ("Method"), method_type_node));
+ build_decl (TYPE_DECL, get_identifier ("Method"), method_type_node);
+
+ endlink = end_params_node = tree_cons (NULL_TREE, void_type_node, NULL_TREE);
t = tree_cons (NULL_TREE, class_ptr_type,
- build_tree_list (NULL_TREE, int_type_node));
+ tree_cons (NULL_TREE, int_type_node, endlink));
alloc_object_node = builtin_function ("_Jv_AllocObject",
build_function_type (ptr_type_node, t),
NOT_BUILT_IN, NULL_PTR);
@@ -667,21 +703,18 @@ init_decl_processing ()
build_function_type (void_type_node,
t),
NOT_BUILT_IN, NULL_PTR);
- t = build_tree_list (NULL_TREE, void_type_node);
+ t = tree_cons (NULL_TREE, ptr_type_node, endlink);
throw_node = builtin_function ("_Jv_Throw",
build_function_type (ptr_type_node, t),
NOT_BUILT_IN, NULL_PTR);
+ t = build_function_type (int_type_node, endlink);
soft_monitorenter_node
- = builtin_function ("_Jv_MonitorEnter",
- build_function_type (int_type_node, t),
- NOT_BUILT_IN, NULL_PTR);
+ = builtin_function ("_Jv_MonitorEnter", t, NOT_BUILT_IN, NULL_PTR);
soft_monitorexit_node
- = builtin_function ("_Jv_MonitorExit",
- build_function_type (int_type_node, t),
- NOT_BUILT_IN, NULL_PTR);
+ = builtin_function ("_Jv_MonitorExit", t, NOT_BUILT_IN, NULL_PTR);
t = tree_cons (NULL_TREE, int_type_node,
- build_tree_list (NULL_TREE, int_type_node));
+ tree_cons (NULL_TREE, int_type_node, endlink));
soft_newarray_node
= builtin_function ("_Jv_NewArray",
build_function_type(ptr_type_node, t),
@@ -689,59 +722,71 @@ init_decl_processing ()
t = tree_cons (NULL_TREE, int_type_node,
tree_cons (NULL_TREE, class_ptr_type,
- build_tree_list (NULL_TREE, object_ptr_type_node)));
+ tree_cons (NULL_TREE, object_ptr_type_node, endlink)));
soft_anewarray_node
= builtin_function ("_Jv_NewObjectArray",
build_function_type (ptr_type_node, t),
NOT_BUILT_IN, NULL_PTR );
t = tree_cons (NULL_TREE, ptr_type_node,
- build_tree_list (NULL_TREE, int_type_node));
+ tree_cons (NULL_TREE, int_type_node, endlink));
soft_multianewarray_node
= builtin_function ("_Jv_NewMultiArray",
build_function_type (ptr_type_node, t),
NOT_BUILT_IN, NULL_PTR );
- t = build_function_type (void_type_node, NULL_TREE);
+ t = build_function_type (void_type_node,
+ tree_cons (NULL_TREE, int_type_node, endlink));
soft_badarrayindex_node
- = builtin_function ("_Jv_ThrowBadArrayIndex", t, NOT_BUILT_IN, NULL_PTR );
+ = builtin_function ("_Jv_ThrowBadArrayIndex", t,
+ NOT_BUILT_IN, NULL_PTR);
TREE_THIS_VOLATILE (soft_badarrayindex_node) = 1;
TREE_SIDE_EFFECTS (soft_badarrayindex_node) = 1;
t = tree_cons (NULL_TREE, class_ptr_type,
- build_tree_list (NULL_TREE, object_ptr_type_node));
+ tree_cons (NULL_TREE, object_ptr_type_node, endlink));
soft_checkcast_node
= builtin_function ("_Jv_CheckCast",
build_function_type (ptr_type_node, t),
NOT_BUILT_IN, NULL_PTR);
t = tree_cons (NULL_TREE, object_ptr_type_node,
- build_tree_list (NULL_TREE, class_ptr_type));
+ tree_cons (NULL_TREE, class_ptr_type, endlink));
soft_instanceof_node
= builtin_function ("_Jv_IsInstanceOf",
build_function_type (promoted_boolean_type_node, t),
NOT_BUILT_IN, NULL_PTR);
t = tree_cons (NULL_TREE, object_ptr_type_node,
- build_tree_list (NULL_TREE, object_ptr_type_node));
+ tree_cons (NULL_TREE, object_ptr_type_node, endlink));
soft_checkarraystore_node
= builtin_function ("_Jv_CheckArrayStore",
build_function_type (void_type_node, t),
NOT_BUILT_IN, NULL_PTR);
t = tree_cons (NULL_TREE, ptr_type_node,
tree_cons (NULL_TREE, ptr_type_node,
- build_tree_list (NULL_TREE, ptr_type_node)));
+ tree_cons (NULL_TREE, ptr_type_node, endlink)));
soft_lookupinterfacemethod_node
= builtin_function ("_Jv_LookupInterfaceMethod",
- build_function_type(ptr_type_node, t),
+ build_function_type (ptr_type_node, t),
NOT_BUILT_IN, NULL_PTR);
t = tree_cons (NULL_TREE, double_type_node,
- build_tree_list (NULL_TREE, double_type_node));
+ tree_cons (NULL_TREE, double_type_node, endlink));
soft_fmod_node
= builtin_function ("__builtin_fmod",
build_function_type (double_type_node, t),
BUILT_IN_FMOD, "fmod");
+
+ soft_exceptioninfo_call_node
+ = build (CALL_EXPR,
+ ptr_type_node,
+ build_address_of
+ (builtin_function ("_Jv_exception_info",
+ build_function_type (ptr_type_node, endlink),
+ NOT_BUILT_IN, NULL_PTR)),
+ NULL_TREE, NULL_TREE);
+ TREE_SIDE_EFFECTS (soft_exceptioninfo_call_node) = 1;
#if 0
t = tree_cons (NULL_TREE, float_type_node,
- build_tree_list (NULL_TREE, float_type_node));
+ tree_cons (NULL_TREE, float_type_node, endlink));
soft_fmodf_node
= builtin_function ("__builtin_fmodf",
build_function_type (float_type_node, t),
@@ -773,7 +818,7 @@ lookup_name (name)
/* Similar to `lookup_name' but look only at current binding level and
the previous one if its the parameter level. */
-tree
+static tree
lookup_name_current_level (name)
tree name;
{
@@ -849,7 +894,6 @@ pushdecl (x)
{
char *file;
int line;
- int different_binding_level = 0;
t = lookup_name_current_level (name);
if (t != 0 && t == error_mark_node)
@@ -889,7 +933,6 @@ pushdecl (x)
{
/* Here to install a non-global value. */
tree oldlocal = IDENTIFIER_LOCAL_VALUE (name);
- tree oldglobal = IDENTIFIER_GLOBAL_VALUE (name);
IDENTIFIER_LOCAL_VALUE (name) = x;
#if 0
@@ -1008,7 +1051,7 @@ make_binding_level ()
void
pushlevel (unused)
- int unused;
+ int unused ATTRIBUTE_UNUSED;
{
register struct binding_level *newlevel = NULL_BINDING_LEVEL;
@@ -1339,7 +1382,7 @@ copy_lang_decl (node)
tree
maybe_build_cleanup (decl)
- tree decl;
+ tree decl ATTRIBUTE_UNUSED;
{
/* There are no cleanups in Java (I think). */
return NULL_TREE;
@@ -1364,7 +1407,7 @@ give_name_to_locals (jcf)
int signature_index = JCF_readu2 (jcf);
int slot = JCF_readu2 (jcf);
tree name = get_name_constant (jcf, name_index);
- tree type = promote_type (parse_signature (jcf, signature_index));
+ tree type = parse_signature (jcf, signature_index);
if (slot < DECL_ARG_SLOT_COUNT (current_function_decl)
&& start_pc == 0
&& length == DECL_CODE_LENGTH (current_function_decl))
@@ -1429,14 +1472,22 @@ give_name_to_locals (jcf)
}
}
+tree
+build_result_decl (fndecl)
+ tree fndecl;
+{
+ tree restype = TREE_TYPE (TREE_TYPE (fndecl));
+ /* To be compatible with C_PROMOTING_INTEGER_TYPE_P in cc1/cc1plus. */
+ if (INTEGRAL_TYPE_P (restype)
+ && TYPE_PRECISION (restype) < TYPE_PRECISION (integer_type_node))
+ restype = integer_type_node;
+ return (DECL_RESULT (fndecl) = build_decl (RESULT_DECL, NULL_TREE, restype));
+}
+
void
complete_start_java_method (fndecl)
tree fndecl;
{
-
- DECL_RESULT (fndecl) = build_decl (RESULT_DECL, NULL_TREE,
- TREE_TYPE (TREE_TYPE (fndecl)));
-
if (! flag_emit_class_files)
{
/* Initialize the RTL code for the function. */
@@ -1458,21 +1509,57 @@ complete_start_java_method (fndecl)
#endif
- if (METHOD_SYNCHRONIZED (fndecl))
+ if (METHOD_STATIC (fndecl) && ! METHOD_PRIVATE (fndecl)
+ && ! flag_emit_class_files)
{
- /* FIXME: surround the function body by a try/finally set. */
+ tree clas = DECL_CONTEXT (fndecl);
+ tree init = build (CALL_EXPR, void_type_node,
+ build_address_of (soft_initclass_node),
+ build_tree_list (NULL_TREE, build_class_ref (clas)),
+ NULL_TREE);
+ TREE_SIDE_EFFECTS (init) = 1;
+ expand_expr_stmt (init);
}
/* Push local variables. Function compiled from source code are
using a different local variables management, and for them,
pushlevel shouldn't be called from here. */
if (!CLASS_FROM_SOURCE_P (DECL_CONTEXT (fndecl)))
-
{
pushlevel (2);
if (! flag_emit_class_files)
expand_start_bindings (1);
}
+
+ if (METHOD_SYNCHRONIZED (fndecl) && ! flag_emit_class_files)
+ {
+ /* Warp function body with a monitorenter plus monitorexit cleanup. */
+ tree enter, exit, lock;
+ if (METHOD_STATIC (fndecl))
+ lock = build_class_ref (DECL_CONTEXT (fndecl));
+ else
+ lock = DECL_ARGUMENTS (fndecl);
+ BUILD_MONITOR_ENTER (enter, lock);
+ BUILD_MONITOR_EXIT (exit, lock);
+ if (!CLASS_FROM_SOURCE_P (DECL_CONTEXT (fndecl)))
+ {
+ expand_expr_stmt (enter);
+ expand_decl_cleanup (NULL_TREE, exit);
+ }
+ else
+ {
+ tree function_body = DECL_FUNCTION_BODY (fndecl);
+ tree body = BLOCK_EXPR_BODY (function_body);
+ lock = build (WITH_CLEANUP_EXPR, void_type_node,
+ enter, NULL_TREE, exit);
+ TREE_SIDE_EFFECTS (lock) = 1;
+ lock = build (COMPOUND_EXPR, TREE_TYPE (body), lock, body);
+ TREE_SIDE_EFFECTS (lock) = 1;
+ lock = build1 (CLEANUP_POINT_EXPR, TREE_TYPE (body), lock);
+ TREE_SIDE_EFFECTS (lock) = 1;
+ BLOCK_EXPR_BODY (function_body) = lock;
+ }
+ }
}
void
@@ -1493,15 +1580,21 @@ start_java_method (fndecl)
ptr = &DECL_ARGUMENTS (fndecl);
for (tem = TYPE_ARG_TYPES (TREE_TYPE (fndecl)), i = 0;
- tem != NULL_TREE; tem = TREE_CHAIN (tem), i++)
+ tem != end_params_node; tem = TREE_CHAIN (tem), i++)
{
tree parm_name = NULL_TREE, parm_decl;
+ tree parm_type = TREE_VALUE (tem);
if (i >= DECL_MAX_LOCALS(fndecl))
fatal ("function has more parameters than local slots");
- parm_decl = build_decl (PARM_DECL, parm_name, TREE_VALUE (tem));
+ parm_decl = build_decl (PARM_DECL, parm_name, parm_type);
DECL_CONTEXT (parm_decl) = fndecl;
- DECL_ARG_TYPE (parm_decl) = TREE_TYPE (parm_decl);
+#ifdef PROMOTE_PROTOTYPES
+ if (TYPE_PRECISION (parm_type) < TYPE_PRECISION (integer_type_node)
+ && INTEGRAL_TYPE_P (parm_type))
+ parm_type = integer_type_node;
+#endif
+ DECL_ARG_TYPE (parm_decl) = parm_type;
*ptr = parm_decl;
ptr = &TREE_CHAIN (parm_decl);
@@ -1522,6 +1615,7 @@ start_java_method (fndecl)
while (i < DECL_MAX_LOCALS(fndecl))
type_map[i++] = NULL_TREE;
+ build_result_decl (fndecl);
complete_start_java_method (fndecl);
}
@@ -1550,13 +1644,3 @@ end_java_method ()
current_function_decl = NULL_TREE;
permanent_allocation (1);
}
-
-tree
-build_decl_no_layout (code, name, type)
- enum tree_code code;
- tree name, type;
-{
- tree decl = build_decl (TYPE_DECL, name, type);
- TREE_SET_CODE (decl, code);
- return decl;
-}
diff --git a/gcc/java/except.c b/gcc/java/except.c
index cbfeb0a8cc2..8fbf0b60e06 100644
--- a/gcc/java/except.c
+++ b/gcc/java/except.c
@@ -1,5 +1,5 @@
/* Handle exceptions for GNU compiler for the Java(TM) language.
- Copyright (C) 1997 Free Software Foundation, Inc.
+ Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -36,6 +36,9 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */
#include "eh-common.h"
#include "toplev.h"
+static void expand_start_java_handler PROTO ((struct eh_range *));
+static void expand_end_java_handler PROTO ((struct eh_range *));
+
extern struct obstack permanent_obstack;
struct eh_range *current_method_handlers;
@@ -161,6 +164,12 @@ method_init_exceptions ()
whole_range.first_child = NULL;
whole_range.next_sibling = NULL;
cache_range_start = 0xFFFFFF;
+ java_set_exception_lang_code ();
+}
+
+void
+java_set_exception_lang_code ()
+{
set_exception_lang_code (EH_LANG_Java);
set_exception_version_code (1);
}
@@ -176,16 +185,42 @@ add_handler (start_pc, end_pc, handler, type)
/* if there are any handlers for this range, issue start of region */
-void
+static void
expand_start_java_handler (range)
- struct eh_range *range;
+ struct eh_range *range ATTRIBUTE_UNUSED;
{
expand_eh_region_start ();
}
+tree
+prepare_eh_table_type (type)
+ tree type;
+{
+ tree exp;
+
+ /* The "type" (metch_info) in a (Java) exception table is one:
+ * a) NULL - meaning match any type in a try-finally.
+ * b) a pointer to a (ccmpiled) class (low-order bit 0).
+ * c) a pointer to the Utf8Const name of the class, plus one
+ * (which yields a value with low-order bit 1). */
+
+ push_obstacks (&permanent_obstack, &permanent_obstack);
+ if (type == NULL_TREE)
+ exp = null_pointer_node;
+ else if (is_compiled_class (type))
+ exp = build_class_ref (type);
+ else
+ exp = fold (build
+ (PLUS_EXPR, ptr_type_node,
+ build_utf8_ref (build_internal_class_name (type)),
+ size_one_node));
+ pop_obstacks ();
+ return exp;
+}
+
/* if there are any handlers for this range, isssue end of range,
and then all handler blocks */
-void
+static void
expand_end_java_handler (range)
struct eh_range *range;
{
@@ -193,24 +228,8 @@ expand_end_java_handler (range)
expand_start_all_catch ();
for ( ; handler != NULL_TREE; handler = TREE_CHAIN (handler))
{
- tree type = TREE_PURPOSE (handler);
- tree exp;
- /* The "type" (metch_info) in a (Java) exception table is one:
- * a) NULL - meaning match any type in a try-finally.
- * b) a pointer to a (ccmpiled) class (low-order bit 0).
- * c) a pointer to the Utf8Const name of the class, plus one
- * (which yields a value with low-order bit 1). */
- push_obstacks (&permanent_obstack, &permanent_obstack);
- if (type == NULL_TREE)
- exp = null_pointer_node;
- else if (is_compiled_class (type))
- exp = build_class_ref (type);
- else
- exp = fold (build (PLUS_EXPR, ptr_type_node,
- build_utf8_ref (build_internal_class_name (type)),
- size_one_node));
- pop_obstacks ();
- start_catch_handler (exp);
+ start_catch_handler (prepare_eh_table_type (TREE_PURPOSE (handler)));
+ /* Push the thrown object on the top of the stack */
expand_goto (TREE_VALUE (handler));
}
expand_end_all_catch ();
@@ -277,3 +296,12 @@ emit_handlers ()
emit_label (funcend);
}
}
+
+/* Resume executing at the statement immediately after the end of an
+ exception region. */
+
+void
+expand_resume_after_catch ()
+{
+ expand_goto (top_label_entry (&caught_return_label_stack));
+}
diff --git a/gcc/java/expr.c b/gcc/java/expr.c
index 3b8538c60e8..268861d68a4 100644
--- a/gcc/java/expr.c
+++ b/gcc/java/expr.c
@@ -1,5 +1,5 @@
/* Process expressions for the GNU compiler for the Java(TM) language.
- Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -29,6 +29,7 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */
#include "tree.h"
#include "real.h"
#include "rtl.h"
+#include "flags.h"
#include "expr.h"
#include "java-tree.h"
#include "javaop.h"
@@ -37,7 +38,42 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */
#include "java-except.h"
#include "parse.h"
#include "toplev.h"
-
+#include "except.h"
+
+static void flush_quick_stack PROTO ((void));
+static void push_value PROTO ((tree));
+static tree pop_value PROTO ((tree));
+static void java_stack_swap PROTO ((void));
+static void java_stack_dup PROTO ((int, int));
+static tree build_java_athrow PROTO ((tree));
+static void build_java_jsr PROTO ((tree, tree));
+static void build_java_ret PROTO ((tree));
+static void expand_java_multianewarray PROTO ((tree, int));
+static void expand_java_arraystore PROTO ((tree));
+static void expand_java_arrayload PROTO ((tree));
+static void expand_java_array_length PROTO ((void));
+static tree build_java_monitor PROTO ((tree, tree));
+static void expand_java_pushc PROTO ((int, tree));
+static void expand_java_return PROTO ((tree));
+static void expand_java_NEW PROTO ((tree));
+static void expand_java_INSTANCEOF PROTO ((tree));
+static void expand_java_CHECKCAST PROTO ((tree));
+static void expand_iinc PROTO ((unsigned int, int, int));
+static void expand_java_binop PROTO ((tree, enum tree_code));
+static void note_label PROTO ((int, int));
+static void expand_compare PROTO ((enum tree_code, tree, tree, int));
+static void expand_test PROTO ((enum tree_code, tree, int));
+static void expand_cond PROTO ((enum tree_code, tree, int));
+static void expand_java_goto PROTO ((int));
+#if 0
+static void expand_java_call PROTO ((int, int));
+static void expand_java_ret PROTO ((tree));
+#endif
+static tree pop_arguments PROTO ((tree));
+static void expand_invoke PROTO ((int, int, int));
+static void expand_java_field_op PROTO ((int, int, int));
+static void java_push_constant_from_pool PROTO ((struct JCF *, int));
+
static tree operand_type[59];
extern struct obstack permanent_obstack;
@@ -166,7 +202,7 @@ unhand_expr (expr)
that the expression for a slot may contain decls for stack slots with
higher (or the same) index, but not lower. */
-void
+static void
flush_quick_stack ()
{
int stack_index = stack_pointer;
@@ -214,7 +250,7 @@ push_type (type)
stack_type_map[stack_pointer++] = TYPE_SECOND;
}
-void
+static void
push_value (value)
tree value;
{
@@ -242,7 +278,6 @@ pop_type (type)
tree type;
{
int n_words;
- int i;
tree t;
if (TREE_CODE (type) == RECORD_TYPE)
type = promote_type (type);
@@ -268,6 +303,12 @@ pop_type (type)
return type;
else if (can_widen_reference_to (t, type))
return t;
+ /* This is a kludge, but matches what Sun's verifier does.
+ It can be tricked, but is safe as long as type errors
+ (i.e. interface method calls) are caught at run-time. */
+ else if (CLASS_INTERFACE (TYPE_NAME (TREE_TYPE (type)))
+ && t == object_ptr_type_node)
+ return t;
}
error ("unexpected type on stack");
return t;
@@ -346,12 +387,10 @@ can_widen_reference_to (source_type, target_type)
}
}
-tree
+static tree
pop_value (type)
tree type;
{
- int n_words = 1 + TYPE_IS_WIDE (type);
- int i;
type = pop_type (type);
if (quick_stack)
{
@@ -369,7 +408,7 @@ pop_value (type)
/* Pop and discrad the top COUNT stack slots. */
-void
+static void
java_stack_pop (count)
int count;
{
@@ -393,7 +432,7 @@ java_stack_pop (count)
/* Implement the 'swap' operator (to swap two top stack slots). */
-void
+static void
java_stack_swap ()
{
tree type1, type2;
@@ -417,7 +456,7 @@ java_stack_swap ()
stack_type_map[stack_pointer - 2] = type1;
}
-void
+static void
java_stack_dup (size, offset)
int size, offset;
{
@@ -460,9 +499,9 @@ java_stack_dup (size, offset)
}
}
-/* Calls soft_athrow. Discard the contents of the value stack. */
+/* Calls _Jv_Throw. Discard the contents of the value stack. */
-tree
+static tree
build_java_athrow (node)
tree node;
{
@@ -480,7 +519,7 @@ build_java_athrow (node)
/* Implementation for jsr/ret */
-void
+static void
build_java_jsr (where, ret)
tree where;
tree ret;
@@ -492,7 +531,7 @@ build_java_jsr (where, ret)
expand_label (ret);
}
-void
+static void
build_java_ret (location)
tree location;
{
@@ -510,7 +549,8 @@ build_java_ret (location)
size_int (BITS_PER_UNIT))
tree
-decode_newarray_type (int atype)
+decode_newarray_type (atype)
+ int atype;
{
switch (atype)
{
@@ -526,15 +566,42 @@ decode_newarray_type (int atype)
}
}
-/* Build a call to soft_badarrayindex(), the ArrayIndexOfBoundsException
- exception handler. */
+/* Map primitive type to the code used by OPCODE_newarray. */
+
+int
+encode_newarray_type (type)
+ tree type;
+{
+ if (type == boolean_type_node)
+ return 4;
+ else if (type == char_type_node)
+ return 5;
+ else if (type == float_type_node)
+ return 6;
+ else if (type == double_type_node)
+ return 7;
+ else if (type == byte_type_node)
+ return 8;
+ else if (type == short_type_node)
+ return 9;
+ else if (type == int_type_node)
+ return 10;
+ else if (type == long_type_node)
+ return 11;
+ else
+ fatal ("Can't compute type code - patch_newarray");
+}
+
+/* Build a call to _Jv_ThrowBadArrayIndex(), the
+ ArrayIndexOfBoundsException exception handler. */
static tree
-build_java_throw_out_of_bounds_exception ()
+build_java_throw_out_of_bounds_exception (index)
+ tree index;
{
tree node = build (CALL_EXPR, int_type_node,
build_address_of (soft_badarrayindex_node),
- NULL_TREE, NULL_TREE );
+ build_tree_list (NULL_TREE, index), NULL_TREE);
TREE_SIDE_EFFECTS (node) = 1; /* Allows expansion within ANDIF */
return (node);
}
@@ -567,9 +634,9 @@ build_java_array_length_access (node)
tree
build_java_arraynull_check (node, expr, type)
- tree node;
- tree expr;
- tree type;
+ tree node ATTRIBUTE_UNUSED;
+ tree expr;
+ tree type ATTRIBUTE_UNUSED;
{
#if 0
static int java_array_access_throws_null_exception = 0;
@@ -629,7 +696,7 @@ build_java_arrayaccess (array, type, index)
if (! integer_zerop (test))
{
throw = build (TRUTH_ANDIF_EXPR, int_type_node, test,
- build_java_throw_out_of_bounds_exception ());
+ build_java_throw_out_of_bounds_exception (index));
/* allows expansion within COMPOUND */
TREE_SIDE_EFFECTS( throw ) = 1;
}
@@ -677,7 +744,7 @@ build_java_check_indexed_type (array_node, indexed_type)
return indexed_type;
}
-/* newarray triggers a call to soft_newarray. This function should be called
+/* newarray triggers a call to _Jv_NewArray. This function should be called
with an integer code (the type of array to create) and get from the stack
the size of the dimmension. */
@@ -700,13 +767,13 @@ build_newarray (atype_value, length)
/* Generates anewarray from a given CLASS_TYPE. Gets from the stack the size
of the dimension. */
-/* Merge with build_newarray. FIXME. */
+
tree
build_anewarray (class_type, length)
tree class_type;
tree length;
{
- tree type = build_java_array_type (promote_type (class_type),
+ tree type = build_java_array_type (class_type,
TREE_CODE (length) == INTEGER_CST
? TREE_INT_CST_LOW (length)
: -1);
@@ -719,11 +786,24 @@ build_anewarray (class_type, length)
NULL_TREE);
}
-/* Generates a call to multianewarray. multianewarray expects a class pointer,
- a number of dimensions and the matching number of dimensions. The argument
- list is NULL terminated. */
+/* Return a node the evaluates 'new TYPE[LENGTH]'. */
-void
+tree
+build_new_array (type, length)
+ tree type;
+ tree length;
+{
+ if (JPRIMITIVE_TYPE_P (type))
+ return build_newarray (encode_newarray_type (type), length);
+ else
+ return build_anewarray (TREE_TYPE (type), length);
+}
+
+/* Generates a call to _Jv_NewMultiArray. multianewarray expects a
+ class pointer, a number of dimensions and the matching number of
+ dimensions. The argument list is NULL terminated. */
+
+static void
expand_java_multianewarray (class_type, ndim)
tree class_type;
int ndim;
@@ -753,7 +833,7 @@ expand_java_multianewarray (class_type, ndim)
to make sure that the RHS can be assigned to the array element
type. It is not necessary to generate this code if ARRAY is final. */
-void
+static void
expand_java_arraystore (rhs_type_node)
tree rhs_type_node;
{
@@ -795,12 +875,11 @@ expand_java_arraystore (rhs_type_node)
BOOLEAN/SHORT, we push a promoted type back to the stack.
*/
-void
+static void
expand_java_arrayload (lhs_type_node )
tree lhs_type_node;
{
tree load_node;
- int convert;
tree index_node = pop_value (int_type_node);
tree array_node = pop_value (ptr_type_node);
@@ -820,7 +899,7 @@ expand_java_arrayload (lhs_type_node )
/* Expands .length. Makes sure that we deal with and array and may expand
a NULL check on the array object. */
-void
+static void
expand_java_array_length ()
{
tree array = pop_value (ptr_type_node);
@@ -829,10 +908,10 @@ expand_java_array_length ()
push_value (build_java_arraynull_check (array, length, int_type_node));
}
-/* Emit code for the call to soft_monitor{enter,exit}. CALL can be either
- soft_monitorenter_node or soft_monitorexit_node. */
+/* Emit code for the call to _Jv_Monitor{Enter,Exit}. CALL can be
+ either soft_monitorenter_node or soft_monitorexit_node. */
-tree
+static tree
build_java_monitor (call, object)
tree call;
tree object;
@@ -846,7 +925,7 @@ build_java_monitor (call, object)
/* Emit code for one of the PUSHC instructions. */
-void
+static void
expand_java_pushc (ival, type)
int ival;
tree type;
@@ -874,7 +953,7 @@ expand_java_pushc (ival, type)
push_value (value);
}
-void
+static void
expand_java_return (type)
tree type;
{
@@ -897,12 +976,13 @@ build_address_of (value)
return build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (value)), value);
}
-void
+static void
expand_java_NEW (type)
tree type;
{
if (! CLASS_LOADED_P (type))
load_class (type, 1);
+ layout_class_methods (type);
push_value (build (CALL_EXPR, promote_type (type),
build_address_of (alloc_object_node),
tree_cons (NULL_TREE, build_class_ref (type),
@@ -911,7 +991,7 @@ expand_java_NEW (type)
NULL_TREE));
}
-void
+static void
expand_java_INSTANCEOF (type)
tree type;
{
@@ -925,7 +1005,7 @@ expand_java_INSTANCEOF (type)
push_value (value);
}
-void
+static void
expand_java_CHECKCAST (type)
tree type;
{
@@ -938,8 +1018,11 @@ expand_java_CHECKCAST (type)
push_value (value);
}
-void
-expand_iinc (unsigned int local_var_index, int ival, int pc)
+static void
+expand_iinc (local_var_index, ival, pc)
+ unsigned int local_var_index;
+ int ival;
+ int pc;
{
tree local_var, res;
tree constant_value;
@@ -1020,28 +1103,12 @@ build_java_binop (op, type, arg1, arg2)
return call;
}
break;
-
-#if 0 /* not required */
- case PLUS_EXPR:
- case MULT_EXPR:
- case MINUS_EXPR:
- case TRUNC_DIV_EXPR:
- case RDIV_EXPR:
-/* case REM_EXPR: */
- case BIT_AND_EXPR:
- case BIT_IOR_EXPR:
- case BIT_XOR_EXPR:
- break;
- default:
- error ("unknown opcode");
- return error_mark_node;
-#endif
-
+ default: ;
}
return fold (build (op, type, arg1, arg2));
}
-void
+static void
expand_java_binop (type, op)
tree type; enum tree_code op;
{
@@ -1147,6 +1214,18 @@ lookup_label (pc)
}
}
+/* Generate a unique name for the purpose of loops and switches
+ labels, and try-catch-finally blocks label or temporary variables. */
+
+tree
+generate_name ()
+{
+ static int l_number = 0;
+ char buff [20];
+ sprintf (buff, "$LJv%d", l_number++);
+ return get_identifier (buff);
+}
+
tree
create_label_decl (name)
tree name;
@@ -1164,9 +1243,9 @@ create_label_decl (name)
/* This maps a bytecode offset (PC) to various flags. */
char *instruction_bits;
-void
+static void
note_label (current_pc, target_pc)
- int current_pc, target_pc;
+ int current_pc ATTRIBUTE_UNUSED, target_pc;
{
lookup_label (target_pc);
instruction_bits [target_pc] |= BCODE_JUMP_TARGET;
@@ -1175,8 +1254,7 @@ note_label (current_pc, target_pc)
/* Emit code to jump to TARGET_PC if VALUE1 CONDITION VALUE2,
where CONDITION is one of one the compare operators. */
-
-void
+static void
expand_compare (condition, value1, value2, target_pc)
enum tree_code condition;
tree value1, value2;
@@ -1191,7 +1269,7 @@ expand_compare (condition, value1, value2, target_pc)
/* Emit code for a TEST-type opcode. */
-void
+static void
expand_test (condition, type, target_pc)
enum tree_code condition;
tree type;
@@ -1206,7 +1284,7 @@ expand_test (condition, type, target_pc)
/* Emit code for a COND-type opcode. */
-void
+static void
expand_cond (condition, type, target_pc)
enum tree_code condition;
tree type;
@@ -1221,7 +1299,7 @@ expand_cond (condition, type, target_pc)
expand_compare (condition, value1, value2, target_pc);
}
-void
+static void
expand_java_goto (target_pc)
int target_pc;
{
@@ -1230,7 +1308,8 @@ expand_java_goto (target_pc)
expand_goto (target_label);
}
-void
+#if 0
+static void
expand_java_call (target_pc, return_address)
int target_pc, return_address;
{
@@ -1241,9 +1320,9 @@ expand_java_call (target_pc, return_address)
expand_goto (target_label);
}
-void
+static void
expand_java_ret (return_address)
- tree return_address;
+ tree return_address ATTRIBUTE_UNUSED;
{
warning ("ret instruction not implemented");
#if 0
@@ -1252,6 +1331,7 @@ expand_java_ret (return_address)
expand_goto (target_label);
#endif
}
+#endif
/* Recursive helper function to pop argument types during verifiation. */
@@ -1259,7 +1339,7 @@ void
pop_argument_types (arg_types)
tree arg_types;
{
- if (arg_types == NULL_TREE)
+ if (arg_types == end_params_node)
return;
if (TREE_CODE (arg_types) == TREE_LIST)
{
@@ -1270,16 +1350,23 @@ pop_argument_types (arg_types)
abort ();
}
-tree
+static tree
pop_arguments (arg_types)
tree arg_types;
{
- if (arg_types == NULL_TREE)
+ if (arg_types == end_params_node)
return NULL_TREE;
if (TREE_CODE (arg_types) == TREE_LIST)
{
tree tail = pop_arguments (TREE_CHAIN (arg_types));
- return tree_cons (NULL_TREE, pop_value (TREE_VALUE (arg_types)), tail);
+ tree type = TREE_VALUE (arg_types);
+ tree arg = pop_value (type);
+#ifdef PROMOTE_PROTOTYPES
+ if (TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)
+ && INTEGRAL_TYPE_P (type))
+ arg = convert (integer_type_node, arg);
+#endif
+ return tree_cons (NULL_TREE, arg, tail);
}
abort ();
}
@@ -1318,9 +1405,7 @@ build_known_method_ref (method, method_type, self_type, method_signature, arg_li
tree method, method_type, self_type, method_signature, arg_list;
{
tree func;
- if (flag_emit_class_files)
- return method;
- else if (is_compiled_class (self_type))
+ if (is_compiled_class (self_type))
{
make_decl_rtl (method, NULL, 1);
func = build1 (ADDR_EXPR, method_ptr_type_node, method);
@@ -1384,7 +1469,7 @@ invoke_build_dtable (is_invoke_interface, arg_list)
object_type_node : TREE_VALUE (arg_list));
if (dtable_ident == NULL_TREE)
- dtable_ident = get_identifier ("dtable");
+ dtable_ident = get_identifier ("vtable");
dtable = build1 (INDIRECT_REF, object_type_node, objectref );
dtable = build (COMPONENT_REF, dtable_ptr_type, dtable,
lookup_field (&object_type_node, dtable_ident));
@@ -1412,12 +1497,42 @@ build_invokevirtual (dtable, method)
return func;
}
+tree
+build_invokeinterface (dtable, method_name, method_signature)
+ tree dtable, method_name, method_signature;
+{
+ static tree class_ident = NULL_TREE;
+ tree lookup_arg;
+
+ /* We expand invokeinterface here. _Jv_LookupInterfaceMethod() will
+ ensure that the selected method exists, is public and not
+ abstract nor static. */
+
+ if (class_ident == NULL_TREE)
+ class_ident = get_identifier ("class");
+
+ dtable = build1 (INDIRECT_REF, dtable_type, dtable);
+ dtable = build (COMPONENT_REF, class_ptr_type, dtable,
+ lookup_field (&dtable_type, class_ident));
+ lookup_arg = build_tree_list (NULL_TREE,
+ (build_utf8_ref
+ (unmangle_classname
+ (IDENTIFIER_POINTER(method_signature),
+ IDENTIFIER_LENGTH(method_signature)))));
+ lookup_arg = tree_cons (NULL_TREE, dtable,
+ tree_cons (NULL_TREE, build_utf8_ref (method_name),
+ lookup_arg));
+ return build (CALL_EXPR, ptr_type_node,
+ build_address_of (soft_lookupinterfacemethod_node),
+ lookup_arg, NULL_TREE);
+}
+
/* Expand one of the invoke_* opcodes.
OCPODE is the specific opcode.
METHOD_REF_INDEX is an index into the constant pool.
NARGS is the number of arguments, or -1 if not specified. */
-void
+static void
expand_invoke (opcode, method_ref_index, nargs)
int opcode;
int method_ref_index;
@@ -1430,14 +1545,13 @@ expand_invoke (opcode, method_ref_index, nargs)
char *self_name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (self_type)));
tree call, func, method, arg_list, method_type;
- static tree class_ident = NULL_TREE;
-
if (! CLASS_LOADED_P (self_type))
{
load_class (self_type, 1);
if (TREE_CODE (TYPE_SIZE (self_type)) == ERROR_MARK)
fatal ("failed to find class '%s'", self_name);
}
+ layout_class_methods (self_type);
if (method_name == init_identifier_node)
method = lookup_java_constructor (CLASS_TO_HANDLE_TYPE (self_type),
@@ -1490,21 +1604,11 @@ expand_invoke (opcode, method_ref_index, nargs)
arg_list = pop_arguments (TYPE_ARG_TYPES (method_type));
flush_quick_stack ();
- if (opcode == OPCODE_invokestatic || opcode == OPCODE_invokespecial
- && ! inherits_from_p (current_class, self_type))
- { /* FIXME probably not needed for invokespecial if done by NEW. */
- /* Ensure self_type is initialized. */
- func = build (CALL_EXPR, void_type_node, soft_initclass_node,
- build_tree_list (NULL_TREE,
- build_class_ref (self_type)),
- NULL_TREE);
- expand_expr_stmt (func);
- }
-
func = NULL_TREE;
if (opcode == OPCODE_invokestatic || opcode == OPCODE_invokespecial
|| (opcode == OPCODE_invokevirtual
- && (METHOD_FINAL (method) || CLASS_FINAL (TYPE_NAME (self_type)))))
+ && (METHOD_PRIVATE (method)
+ || METHOD_FINAL (method) || CLASS_FINAL (TYPE_NAME (self_type)))))
func = build_known_method_ref (method, method_type, self_type,
method_signature, arg_list);
else
@@ -1514,41 +1618,12 @@ expand_invoke (opcode, method_ref_index, nargs)
if (opcode == OPCODE_invokevirtual)
func = build_invokevirtual (dtable, method);
else
- {
- /* We expand invokeinterface here. soft_lookupinterfacemethod () will
- ensure that the selected method exists, is public and not abstract
- nor static. */
-
- tree lookup_arg;
-
- if (class_ident == NULL_TREE)
- class_ident = get_identifier ("class");
-
- dtable = build1 (INDIRECT_REF, dtable_type, dtable);
- dtable = build (COMPONENT_REF, class_ptr_type, dtable,
- lookup_field (&dtable_type, class_ident));
- lookup_arg = build_tree_list (NULL_TREE,
- build_utf8_ref (method_signature));
- lookup_arg = tree_cons (NULL_TREE, dtable,
- tree_cons (NULL_TREE,
- build_utf8_ref (method_name),
- lookup_arg));
- func = build (CALL_EXPR,
- ptr_type_node,
- build_address_of (soft_lookupinterfacemethod_node),
- lookup_arg, NULL_TREE);
- }
+ func = build_invokeinterface (dtable, method_name, method_signature);
}
func = build1 (NOP_EXPR, build_pointer_type (method_type), func);
call = build (CALL_EXPR, TREE_TYPE (method_type), func, arg_list, NULL_TREE);
TREE_SIDE_EFFECTS (call) = 1;
- if (opcode == OPCODE_invokestatic || opcode == OPCODE_invokespecial)
- { /* FIXME probably not needed for invokespecial if done by NEW. */
- /* Ensure self_type is initialized. */
- call = build_class_init (self_type, call);
- }
-
if (TREE_CODE (TREE_TYPE (method_type)) == VOID_TYPE)
expand_expr_stmt (call);
else
@@ -1564,7 +1639,7 @@ expand_invoke (opcode, method_ref_index, nargs)
IS_PUTTING is 1 for putting into a field; 0 for getting from the field.
FIELD_REF_INDEX is an index into the constant pool. */
-void
+static void
expand_java_field_op (is_static, is_putting, field_ref_index)
int is_static;
int is_putting;
@@ -1600,7 +1675,7 @@ expand_java_field_op (is_static, is_putting, field_ref_index)
if (is_error)
{
if (! is_putting)
- push_value (convert (promote_type (field_type), integer_zero_node));
+ push_value (convert (field_type, integer_zero_node));
flush_quick_stack ();
return;
}
@@ -1610,32 +1685,13 @@ expand_java_field_op (is_static, is_putting, field_ref_index)
this is also needed to avoid circularities in the implementation
of these fields in libjava. */
if (field_name == TYPE_identifier_node && ! is_putting
- && field_type == class_type_node
+ && ! flag_emit_class_files && field_type == class_ptr_type
&& strncmp (self_name, "java.lang.", 10) == 0)
{
- char *class_name = self_name+10;
- tree typ;
- if (strcmp(class_name, "Byte") == 0)
- typ = byte_type_node;
- else if (strcmp(class_name, "Short") == 0)
- typ = short_type_node;
- else if (strcmp(class_name, "Integer") == 0)
- typ = int_type_node;
- else if (strcmp(class_name, "Long") == 0)
- typ = long_type_node;
- else if (strcmp(class_name, "Float") == 0)
- typ = float_type_node;
- else if (strcmp(class_name, "Boolean") == 0)
- typ = boolean_type_node;
- else if (strcmp(class_name, "Char") == 0)
- typ = char_type_node;
- else if (strcmp(class_name, "Void") == 0)
- typ = void_type_node;
- else
- typ = NULL_TREE;
- if (typ != NULL_TREE)
+ tree typ = build_primtype_type_ref (self_name);
+ if (typ)
{
- push_value (build_class_ref (typ));
+ push_value (typ);
return;
}
}
@@ -1670,6 +1726,38 @@ expand_java_field_op (is_static, is_putting, field_ref_index)
push_value (field_ref);
}
+tree
+build_primtype_type_ref (self_name)
+ char *self_name;
+{
+ char *class_name = self_name+10;
+ tree typ;
+ if (strncmp(class_name, "Byte", 4) == 0)
+ typ = byte_type_node;
+ else if (strncmp(class_name, "Short", 5) == 0)
+ typ = short_type_node;
+ else if (strncmp(class_name, "Integer", 7) == 0)
+ typ = int_type_node;
+ else if (strncmp(class_name, "Long", 4) == 0)
+ typ = long_type_node;
+ else if (strncmp(class_name, "Float", 5) == 0)
+ typ = float_type_node;
+ else if (strncmp(class_name, "Double", 6) == 0)
+ typ = double_type_node;
+ else if (strncmp(class_name, "Boolean", 7) == 0)
+ typ = boolean_type_node;
+ else if (strncmp(class_name, "Char", 4) == 0)
+ typ = char_type_node;
+ else if (strncmp(class_name, "Void", 4) == 0)
+ typ = void_type_node;
+ else
+ typ = NULL_TREE;
+ if (typ != NULL_TREE)
+ return build_class_ref (typ);
+ else
+ return NULL_TREE;
+}
+
void
load_type_state (label)
tree label;
@@ -1682,6 +1770,18 @@ load_type_state (label)
type_map [i] = TREE_VEC_ELT (vec, i);
}
+/* Do the expansion of a Java switch. With Gcc, switches are front-end
+ dependant things, but they rely on gcc routines. This function is
+ placed here because it uses things defined locally in parse.y. */
+
+static tree
+case_identity (t, v)
+ tree t __attribute__ ((__unused__));
+ tree v;
+{
+ return v;
+}
+
struct rtx_def *
java_lang_expand_expr (exp, target, tmode, modifier)
register tree exp;
@@ -1689,17 +1789,78 @@ java_lang_expand_expr (exp, target, tmode, modifier)
enum machine_mode tmode;
enum expand_modifier modifier;
{
- register rtx op0;
- tree type = TREE_TYPE (exp);
- register enum machine_mode mode = TYPE_MODE (type);
- int unsignedp = TREE_UNSIGNED (type);
+ tree current;
switch (TREE_CODE (exp))
{
+ case NEW_ARRAY_INIT:
+ {
+ rtx tmp;
+ tree array_type = TREE_TYPE (TREE_TYPE (exp));
+ tree element_type = TYPE_ARRAY_ELEMENT (array_type);
+ tree data_fld = TREE_CHAIN (TREE_CHAIN (TYPE_FIELDS (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 array_decl;
+#if 0
+ /* Enable this once we can set the vtable field statically. FIXME */
+ if (TREE_CONSTANT (init) && TREE_STATIC (exp)
+ && JPRIMITIVE_TYPE_P (element_type))
+ {
+ tree temp, value, init_decl;
+ START_RECORD_CONSTRUCTOR (temp, object_type_node);
+ PUSH_FIELD_VALUE (temp, "vtable",
+ null_pointer_node /* FIXME */
+ );
+ PUSH_FIELD_VALUE (temp, "sync_info", null_pointer_node);
+ FINISH_RECORD_CONSTRUCTOR (temp);
+ START_RECORD_CONSTRUCTOR (value, array_type);
+ PUSH_SUPER_VALUE (value, temp);
+ PUSH_FIELD_VALUE (value, "length", length);
+ PUSH_FIELD_VALUE (value, "data", init);
+ FINISH_RECORD_CONSTRUCTOR (value);
+
+ init_decl = build_decl (VAR_DECL, generate_name (), array_type);
+ pushdecl_top_level (init_decl);
+ TREE_STATIC (init_decl) = 1;
+ DECL_INITIAL (init_decl) = value;
+ DECL_IGNORED_P (init_decl) = 1;
+ TREE_READONLY (init_decl) = 1;
+ make_decl_rtl (init_decl, NULL, 1);
+ init = build1 (ADDR_EXPR, TREE_TYPE (exp), init_decl);
+ return expand_expr (init, target, tmode, modifier);
+ }
+#endif
+ array_decl = build_decl (VAR_DECL, NULL_TREE, TREE_TYPE (exp));
+ expand_decl (array_decl);
+ tmp = expand_assignment (array_decl,
+ build_new_array (element_type, length),
+ 1, 0);
+ if (TREE_CONSTANT (init)
+ && ilength >= 10 && JPRIMITIVE_TYPE_P (element_type))
+ {
+ tree init_decl = build_decl (VAR_DECL, generate_name (),
+ TREE_TYPE (init));
+ pushdecl_top_level (init_decl);
+ TREE_STATIC (init_decl) = 1;
+ DECL_INITIAL (init_decl) = init;
+ DECL_IGNORED_P (init_decl) = 1;
+ TREE_READONLY (init_decl) = 1;
+ make_decl_rtl (init_decl, NULL, 1);
+ init = init_decl;
+ }
+ expand_assignment (build (COMPONENT_REF, TREE_TYPE (data_fld),
+ build1 (INDIRECT_REF, array_type, array_decl),
+ data_fld),
+ init, 0, 0);
+ return tmp;
+ }
case BLOCK:
if (BLOCK_EXPR_BODY (exp))
{
tree local;
+ tree body = BLOCK_EXPR_BODY (exp);
struct rtx_def *to_return;
pushlevel (2); /* 2 and above */
expand_start_bindings (0);
@@ -1711,14 +1872,71 @@ java_lang_expand_expr (exp, target, tmode, modifier)
expand_decl (pushdecl (local));
local = next;
}
- to_return =
- expand_expr (BLOCK_EXPR_BODY (exp), target, tmode, modifier);
+ /* Avoid deep recursion for long block. */
+ while (TREE_CODE (body) == COMPOUND_EXPR)
+ {
+ expand_expr (TREE_OPERAND (body, 0), const0_rtx, VOIDmode, 0);
+ emit_queue ();
+ body = TREE_OPERAND (body, 1);
+ }
+ to_return = expand_expr (body, target, tmode, modifier);
poplevel (1, 1, 0);
expand_end_bindings (getdecls (), 1, 0);
return to_return;
}
break;
+ case CASE_EXPR:
+ {
+ tree duplicate;
+ if (pushcase (TREE_OPERAND (exp, 0), case_identity,
+ build_decl (LABEL_DECL, NULL_TREE, NULL_TREE),
+ &duplicate) == 2)
+ {
+ EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (exp);
+ parse_error_context
+ (wfl_operator, "Duplicate case label: `%s'",
+ print_int_node (TREE_OPERAND (exp, 0)));
+ }
+ return const0_rtx;
+ }
+
+ case DEFAULT_EXPR:
+ pushcase (NULL_TREE, 0,
+ build_decl (LABEL_DECL, NULL_TREE, NULL_TREE), NULL);
+ return const0_rtx;
+
+ case SWITCH_EXPR:
+ expand_start_case (0, TREE_OPERAND (exp, 0), int_type_node, "switch");
+ expand_expr_stmt (TREE_OPERAND (exp, 1));
+ expand_end_case (TREE_OPERAND (exp, 0));
+ return const0_rtx;
+
+ case TRY_EXPR:
+ /* We expand a try[-catch] block */
+
+ /* Expand the try block */
+ expand_eh_region_start ();
+ expand_expr_stmt (TREE_OPERAND (exp, 0));
+ expand_start_all_catch ();
+
+ /* Expand all catch clauses (EH handlers) */
+ for (current = TREE_OPERAND (exp, 1); current;
+ current = TREE_CHAIN (current))
+ {
+ tree type;
+ tree catch = TREE_OPERAND (current, 0);
+ tree decl = BLOCK_EXPR_DECLS (catch);
+ type = (decl ? TREE_TYPE (TREE_TYPE (decl)) : NULL_TREE);
+ start_catch_handler (prepare_eh_table_type (type));
+ expand_expr_stmt (TREE_OPERAND (current, 0));
+
+ expand_resume_after_catch ();
+ end_catch_handler ();
+ }
+ expand_end_all_catch ();
+ break;
+
default:
fatal ("Can't expand '%s' tree - java_lang_expand_expr",
tree_code_name [TREE_CODE (exp)]);
@@ -1734,8 +1952,6 @@ expand_byte_code (jcf, method)
int i;
int saw_index;
unsigned char *linenumber_pointer;
- struct eh_range *prev_eh_ranges = NULL_EH_RANGE;
- struct eh_range *eh_ranges;
#undef RET /* Defined by config/i386/i386.h */
#undef AND /* Causes problems with opcodes for iand and land. */
@@ -1763,7 +1979,7 @@ expand_byte_code (jcf, method)
#define VAR_INDEX_1 (saw_index = 1, IMMEDIATE_u1)
#define VAR_INDEX_2 (saw_index = 1, IMMEDIATE_u2)
-#define CHECK_PC_IN_RANGE(PC) 1 /* Already handled by verifier. */
+#define CHECK_PC_IN_RANGE(PC) ((void)1) /* Already handled by verifier. */
instruction_bits = oballoc (length + 1);
bzero (instruction_bits, length + 1);
@@ -1955,7 +2171,7 @@ expand_byte_code (jcf, method)
} /* for */
}
-void
+static void
java_push_constant_from_pool (jcf, index)
JCF *jcf;
int index;
@@ -1982,8 +2198,17 @@ process_jvm_instruction (PC, byte_ops, length)
unsigned char* byte_ops;
long length;
{
- char *opname; /* Temporary ??? */
+ const char *opname; /* Temporary ??? */
int oldpc = PC; /* PC at instruction start. */
+
+ /* If the instruction is at the beginning of a exception handler,
+ replace the top of the stack with the thrown object reference */
+ if (instruction_bits [PC] & BCODE_EXCEPTION_TARGET)
+ {
+ tree type = pop_type (ptr_type_node);
+ push_value (build1 (NOP_EXPR, type, soft_exceptioninfo_call_node));
+ }
+
switch (byte_ops[PC++])
{
#define JAVAOP(OPNAME, OPCODE, OPKIND, OPERAND_TYPE, OPERAND_VALUE) \
@@ -2004,6 +2229,7 @@ process_jvm_instruction (PC, byte_ops, length)
tree where = lookup_label (oldpc+OPERAND_VALUE); \
tree ret = lookup_label (PC); \
build_java_jsr (where, ret); \
+ load_type_state (ret); \
}
/* Push a constant onto the stack. */
@@ -2282,3 +2508,48 @@ process_jvm_instruction (PC, byte_ops, length)
}
return PC;
}
+
+/* Force the (direct) sub-operands of NODE to be evaluated in left-to-right
+ order, as specified by Java Language Specification.
+
+ The problem is that while expand_expr will evaluate its sub-operands in
+ left-to-right order, for variables it will just return an rtx (i.e.
+ an lvalue) for the variable (rather than an rvalue). So it is possible
+ that a later sub-operand will change the register, and when the
+ actual operation is done, it will use the new value, when it should
+ have used the original value.
+
+ We fix this by using save_expr. This forces the sub-operand to be
+ copied into a fresh virtual register,
+*/
+
+tree
+force_evaluation_order (node)
+ tree node;
+{
+ if (flag_syntax_only)
+ return node;
+ if (TREE_CODE_CLASS (TREE_CODE (node)) == '2')
+ {
+ if (TREE_SIDE_EFFECTS (TREE_OPERAND (node, 1)))
+ TREE_OPERAND (node, 0) = save_expr (TREE_OPERAND (node, 0));
+ }
+ else if (TREE_CODE (node) == CALL_EXPR || TREE_CODE (node) == NEW_CLASS_EXPR)
+ {
+ tree last_side_effecting_arg = NULL_TREE;
+ tree arg = TREE_OPERAND (node, 1);
+ for (; arg != NULL_TREE; arg = TREE_CHAIN (arg))
+ {
+ if (TREE_SIDE_EFFECTS (TREE_VALUE (arg)))
+ last_side_effecting_arg = arg;
+ }
+ arg = TREE_OPERAND (node, 1);
+ for (; arg != NULL_TREE; arg = TREE_CHAIN (arg))
+ {
+ if (arg == last_side_effecting_arg)
+ break;
+ TREE_VALUE (arg) = save_expr (TREE_VALUE (arg));
+ }
+ }
+ return node;
+}
diff --git a/gcc/java/gjavah.c b/gcc/java/gjavah.c
index fd39df6b8fc..0b030f22e72 100644
--- a/gcc/java/gjavah.c
+++ b/gcc/java/gjavah.c
@@ -1,7 +1,7 @@
/* Program to write C++-suitable header files from a Java(TM) .class
file. This is similar to SUN's javah.
-Copyright (C) 1996, 1998 Free Software Foundation, Inc.
+Copyright (C) 1996, 1998, 1999 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
@@ -24,11 +24,10 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */
/* Written by Per Bothner <bothner@cygnus.com>, February 1996. */
-#include <stdio.h>
+#include "config.h"
+#include "system.h"
#include "jcf.h"
-#ifdef __STDC__
-#include <stdlib.h>
-#endif
+#include "java-opcodes.h"
#include <math.h>
/* The output file. */
@@ -38,12 +37,10 @@ FILE *out = NULL;
static int found_error = 0;
/* Directory to place resulting files in. Set by -d option. */
-char *output_directory = "";
-
-char *output_file = NULL;
+const char *output_directory = "";
/* Directory to place temporary file. Set by -td option. Currently unused. */
-char *temp_directory = "/tmp";
+const char *temp_directory = "/tmp";
/* Number of friend functions we have to declare. */
static int friend_count;
@@ -84,11 +81,28 @@ static JCF_u2 last_access;
#define ACC_VISIBILITY (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED)
-int seen_fields = 0;
+/* Pass this macro the flags for a class and for a method. It will
+ return true if the method should be considered `final'. */
+#define METHOD_IS_FINAL(Class, Method) \
+ (((Class) & ACC_FINAL) || ((Method) & (ACC_FINAL | ACC_PRIVATE)))
+
+/* We keep a linked list of all method names we have seen. This lets
+ us determine if a method name and a field name are in conflict. */
+struct method_name
+{
+ unsigned char *name;
+ int length;
+ struct method_name *next;
+};
+
+/* List of method names we've seen. */
+static struct method_name *method_name_list;
static void print_field_info PROTO ((FILE *, JCF*, int, int, JCF_u2));
static void print_method_info PROTO ((FILE *, JCF*, int, int, JCF_u2));
-static void print_c_decl PROTO ((FILE*, JCF*, int, int, JCF_u2, int));
+static void print_c_decl PROTO ((FILE*, JCF*, int, int, int, const char *));
+static void decompile_method PROTO ((FILE *, JCF *, int));
+static void add_class_decl PROTO ((FILE *, JCF *, JCF_u2));
JCF_u2 current_field_name;
JCF_u2 current_field_value;
@@ -99,14 +113,47 @@ JCF_u2 current_field_flags;
( current_field_name = (NAME), current_field_signature = (SIGNATURE), \
current_field_flags = (ACCESS_FLAGS), current_field_value = 0)
-#define HANDLE_END_FIELD() \
- print_field_info (out, jcf, current_field_name, current_field_signature, \
- current_field_flags);
+/* We pass over fields twice. The first time we just note the types
+ of the fields and then the start of the methods. Then we go back
+ and parse the fields for real. This is ugly. */
+static int field_pass;
+/* Likewise we pass over methods twice. The first time we generate
+ class decl information; the second time we generate actual method
+ decls. */
+static int method_pass;
+
+#define HANDLE_END_FIELD() \
+ if (field_pass) \
+ { \
+ if (out) \
+ print_field_info (out, jcf, current_field_name, \
+ current_field_signature, \
+ current_field_flags); \
+ } \
+ else \
+ add_class_decl (out, jcf, current_field_signature);
#define HANDLE_CONSTANTVALUE(VALUEINDEX) current_field_value = (VALUEINDEX)
-#define HANDLE_METHOD(ACCESS_FLAGS, NAME, SIGNATURE, ATTRIBUTE_COUNT) \
- print_method_info (out, jcf, NAME, SIGNATURE, ACCESS_FLAGS)
+static int method_declared = 0;
+static int method_access = 0;
+static int method_printed = 0;
+#define HANDLE_METHOD(ACCESS_FLAGS, NAME, SIGNATURE, ATTRIBUTE_COUNT) \
+ if (method_pass) \
+ { \
+ decompiled = 0; method_printed = 0; \
+ if (out) \
+ print_method_info (out, jcf, NAME, SIGNATURE, ACCESS_FLAGS); \
+ } \
+ else \
+ add_class_decl (out, jcf, SIGNATURE);
+
+#define HANDLE_CODE_ATTRIBUTE(MAX_STACK, MAX_LOCALS, CODE_LENGTH) \
+ if (out && method_declared) decompile_method (out, jcf, CODE_LENGTH);
+
+static int decompiled = 0;
+#define HANDLE_END_METHOD() \
+ if (out && method_printed) fputs (decompiled ? "\n" : ";\n", out);
#include "jcf-reader.c"
@@ -119,12 +166,16 @@ static int
java_float_finite (f)
jfloat f;
{
- int32 *ip = (int32 *) &f;
+ union {
+ jfloat f;
+ int32 i;
+ } u;
+ u.f = f;
/* We happen to know that F_NAN_MASK will match all NaN values, and
also positive and negative infinity. That's why we only need one
test here. See The Java Language Specification, section 20.9. */
- return (*ip & F_NAN_MASK) != F_NAN_MASK;
+ return (u.i & F_NAN_MASK) != F_NAN_MASK;
}
/* Return 1 if D is not Inf or NaN. */
@@ -132,10 +183,14 @@ static int
java_double_finite (d)
jdouble d;
{
- int64 *ip = (int64 *) &d;
+ union {
+ jdouble d;
+ int64 i;
+ } u;
+ u.d = d;
/* Now check for all NaNs. */
- return (*ip & D_NAN_MASK) != D_NAN_MASK;
+ return (u.i & D_NAN_MASK) != D_NAN_MASK;
}
void
@@ -159,7 +214,7 @@ print_base_classname (stream, jcf, index)
int index;
{
int name_index = JPOOL_USHORT1 (jcf, index);
- int i, len;
+ int len;
unsigned char *s, *p, *limit;
s = JPOOL_UTF_DATA (jcf, name_index);
@@ -212,19 +267,15 @@ generate_access (stream, flags)
FILE *stream;
JCF_u2 flags;
{
- /* FIXME: Java's "protected" and "no access specifier" modes don't
- actually map to C++ "protected". That's how we map them for now,
- though. */
-
- if (! (flags & ACC_VISIBILITY))
- flags = ACC_PROTECTED;
-
if ((flags & ACC_VISIBILITY) == last_access)
return;
last_access = (flags & ACC_VISIBILITY);
switch (last_access)
{
+ case 0:
+ fputs ("public: // actually package-private\n", stream);
+ break;
case ACC_PUBLIC:
fputs ("public:\n", stream);
break;
@@ -232,7 +283,7 @@ generate_access (stream, flags)
fputs ("private:\n", stream);
break;
case ACC_PROTECTED:
- fputs ("protected:\n", stream);
+ fputs ("public: // actually protected\n", stream);
break;
default:
found_error = 1;
@@ -242,36 +293,75 @@ generate_access (stream, flags)
}
}
+/* See if NAME is already the name of a method. */
+static int
+name_is_method_p (name, length)
+ unsigned char *name;
+ int length;
+{
+ struct method_name *p;
+
+ for (p = method_name_list; p != NULL; p = p->next)
+ {
+ if (p->length == length && ! memcmp (p->name, name, length))
+ return 1;
+ }
+ return 0;
+}
+
static void
DEFUN(print_field_info, (stream, jcf, name_index, sig_index, flags),
FILE *stream AND JCF* jcf
AND int name_index AND int sig_index AND JCF_u2 flags)
{
+ char *override = NULL;
+
if (flags & ACC_FINAL)
{
if (current_field_value > 0)
{
- jlong num;
char buffer[25];
generate_access (stream, flags);
switch (JPOOL_TAG (jcf, current_field_value))
{
case CONSTANT_Integer:
- fputs (" static const jint ", out);
- print_name (out, jcf, name_index);
- fputs (" = ", out);
- num = JPOOL_INT (jcf, current_field_value);
- format_int (buffer, num, 10);
- fprintf (out, "%sL;\n", buffer);
+ {
+ jint num;
+ int most_negative = 0;
+ fputs (" static const jint ", out);
+ print_name (out, jcf, name_index);
+ fputs (" = ", out);
+ num = JPOOL_INT (jcf, current_field_value);
+ /* We single out the most negative number to print
+ specially. This avoids later warnings from g++. */
+ if (num == (jint) 0x80000000)
+ {
+ most_negative = 1;
+ ++num;
+ }
+ format_int (buffer, (jlong) num, 10);
+ fprintf (out, "%sL%s;\n", buffer, most_negative ? " - 1" : "");
+ }
break;
case CONSTANT_Long:
- fputs (" static const jlong ", out);
- print_name (out, jcf, name_index);
- fputs (" = ", out);
- num = JPOOL_LONG (jcf, current_field_value);
- format_int (buffer, num, 10);
- fprintf (out, "%sLL;\n", buffer);
+ {
+ jlong num;
+ int most_negative = 0;
+ fputs (" static const jlong ", out);
+ print_name (out, jcf, name_index);
+ fputs (" = ", out);
+ num = JPOOL_LONG (jcf, current_field_value);
+ /* We single out the most negative number to print
+ specially.. This avoids later warnings from g++. */
+ if (num == (jlong) 0x8000000000000000LL)
+ {
+ most_negative = 1;
+ ++num;
+ }
+ format_int (buffer, num, 10);
+ fprintf (out, "%sLL%s;\n", buffer, most_negative ? " - 1" :"");
+ }
break;
case CONSTANT_Float:
{
@@ -305,12 +395,42 @@ DEFUN(print_field_info, (stream, jcf, name_index, sig_index, flags),
generate_access (stream, flags);
fputs (" ", out);
- if (flags & ACC_STATIC)
+ if ((flags & ACC_STATIC))
fputs ("static ", out);
- print_c_decl (out, jcf, name_index, sig_index, flags, 0);
+
+ if (JPOOL_TAG (jcf, name_index) != CONSTANT_Utf8)
+ {
+ fprintf (stream, "<not a UTF8 constant>");
+ found_error = 1;
+ }
+ else
+ {
+ unsigned char *name = JPOOL_UTF_DATA (jcf, name_index);
+ int length = JPOOL_UTF_LENGTH (jcf, name_index);
+
+ if (name_is_method_p (name, length))
+ {
+ /* This field name matches a method. So override the name
+ with a dummy name. This is yucky, but it isn't clear
+ what else to do. FIXME: if the field is static, then
+ we'll be in real trouble. */
+ if ((flags & ACC_STATIC))
+ {
+ fprintf (stderr, "static field has same name as method\n");
+ found_error = 1;
+ }
+
+ override = (char *) malloc (length + 3);
+ memcpy (override, name, length);
+ strcpy (override + length, "__");
+ }
+ }
+
+ print_c_decl (out, jcf, name_index, sig_index, 0, override);
fputs (";\n", out);
- if (! (flags & ACC_STATIC))
- seen_fields++;
+
+ if (override)
+ free (override);
}
static void
@@ -320,202 +440,332 @@ DEFUN(print_method_info, (stream, jcf, name_index, sig_index, flags),
{
unsigned char *str;
int length, is_init = 0;
+ const char *override = NULL;
+ method_declared = 0;
+ method_access = flags;
if (JPOOL_TAG (jcf, name_index) != CONSTANT_Utf8)
fprintf (stream, "<not a UTF8 constant>");
str = JPOOL_UTF_DATA (jcf, name_index);
length = JPOOL_UTF_LENGTH (jcf, name_index);
- if (str[0] == '<')
+ if (str[0] == '<' || str[0] == '$')
{
- /* Ignore internally generated methods like <clinit>. However,
- treat <init> as a constructor. */
+ /* Ignore internally generated methods like <clinit> and
+ $finit$. However, treat <init> as a constructor. */
if (! utf8_cmp (str, length, "<init>"))
is_init = 1;
- else
+ else if (! METHOD_IS_FINAL (jcf->access_flags, flags)
+ && ! (flags & ACC_STATIC))
+ {
+ /* FIXME: i18n bug here. Order of prints should not be
+ fixed. */
+ fprintf (stderr, "ignored method `");
+ jcf_print_utf8 (stderr, str, length);
+ fprintf (stderr, "' marked virtual\n");
+ found_error = 1;
+ return;
+ }
+ else
return;
}
+ else
+ {
+ struct method_name *nn;
+
+ nn = (struct method_name *) malloc (sizeof (struct method_name));
+ nn->name = (char *) malloc (length);
+ memcpy (nn->name, str, length);
+ nn->length = length;
+ nn->next = method_name_list;
+ method_name_list = nn;
+ }
/* We can't generate a method whose name is a C++ reserved word.
For now the only problem has been `delete'; add more here as
- required. FIXME: we need a better solution than just ignoring
- the method. */
+ required. We can't just ignore the function, because that will
+ cause incorrect code to be generated if the function is virtual
+ (not only for calls to this function for for other functions
+ after it in the vtbl). So we give it a dummy name instead. */
if (! utf8_cmp (str, length, "delete"))
- return;
+ {
+ /* If the method is static or final, we can safely skip it. If
+ we don't skip it then we'll have problems since the mangling
+ will be wrong. FIXME. */
+ if (METHOD_IS_FINAL (jcf->access_flags, flags)
+ || (flags & ACC_STATIC))
+ return;
+ override = "__dummy_delete";
+ }
+ method_printed = 1;
generate_access (stream, flags);
fputs (" ", out);
if ((flags & ACC_STATIC))
fputs ("static ", out);
- else if (! (flags & ACC_FINAL) && ! (jcf->access_flags & ACC_FINAL))
+ else if (! METHOD_IS_FINAL (jcf->access_flags, flags))
{
/* Don't print `virtual' if we have a constructor. */
if (! is_init)
fputs ("virtual ", out);
}
- print_c_decl (out, jcf, name_index, sig_index, flags, is_init);
+ print_c_decl (out, jcf, name_index, sig_index, is_init, override);
+
+ if ((flags & ACC_ABSTRACT))
+ fputs (" = 0", out);
+ else
+ method_declared = 1;
+}
+
+/* Try to decompile a method body. Right now we just try to handle a
+ simple case that we can do. Expand as desired. */
+static void
+decompile_method (out, jcf, code_len)
+ FILE *out;
+ JCF *jcf;
+ int code_len;
+{
+ unsigned char *codes = jcf->read_ptr;
+ int index;
+ uint16 name_and_type, name;
- /* FIXME: it would be nice to decompile small methods here. That
- would allow for inlining. */
+ /* If the method is synchronized, don't touch it. */
+ if ((method_access & ACC_SYNCHRONIZED))
+ return;
- fprintf(out, ";\n");
+ if (code_len == 5
+ && codes[0] == OPCODE_aload_0
+ && codes[1] == OPCODE_getfield
+ && (codes[4] == OPCODE_areturn
+ || codes[4] == OPCODE_dreturn
+ || codes[4] == OPCODE_freturn
+ || codes[4] == OPCODE_ireturn
+ || codes[4] == OPCODE_lreturn))
+ {
+ /* Found code like `return FIELD'. */
+ fputs (" { return ", out);
+ index = (codes[2] << 8) | codes[3];
+ /* FIXME: ensure that tag is CONSTANT_Fieldref. */
+ /* FIXME: ensure that the field's class is this class. */
+ name_and_type = JPOOL_USHORT2 (jcf, index);
+ /* FIXME: ensure that tag is CONSTANT_NameAndType. */
+ name = JPOOL_USHORT1 (jcf, name_and_type);
+ print_name (out, jcf, name);
+ fputs ("; }", out);
+ decompiled = 1;
+ }
+ else if (code_len == 2
+ && codes[0] == OPCODE_aload_0
+ && codes[1] == OPCODE_areturn)
+ {
+ /* Found `return this'. */
+ fputs (" { return this; }", out);
+ decompiled = 1;
+ }
+ else if (code_len == 1 && codes[0] == OPCODE_return)
+ {
+ /* Found plain `return'. */
+ fputs (" { }", out);
+ decompiled = 1;
+ }
+ else if (code_len == 2
+ && codes[0] == OPCODE_aconst_null
+ && codes[1] == OPCODE_areturn)
+ {
+ /* Found `return null'. We don't want to depend on NULL being
+ defined. */
+ fputs (" { return 0; }", out);
+ decompiled = 1;
+ }
+}
+
+/* Print one piece of a signature. Returns pointer to next parseable
+ character on success, NULL on error. */
+static unsigned char *
+decode_signature_piece (stream, signature, limit, need_space)
+ FILE *stream;
+ unsigned char *signature, *limit;
+ int *need_space;
+{
+ const char *ctype;
+
+ switch (signature[0])
+ {
+ case '[':
+ for (signature++; (signature < limit
+ && *signature >= '0'
+ && *signature <= '9'); signature++)
+ ;
+ switch (*signature)
+ {
+ case 'B': ctype = "jbyteArray"; goto printit;
+ case 'C': ctype = "jcharArray"; goto printit;
+ case 'D': ctype = "jdoubleArray"; goto printit;
+ case 'F': ctype = "jfloatArray"; goto printit;
+ case 'I': ctype = "jintArray"; goto printit;
+ case 'S': ctype = "jshortArray"; goto printit;
+ case 'J': ctype = "jlongArray"; goto printit;
+ case 'Z': ctype = "jbooleanArray"; goto printit;
+ case '[': ctype = "jobjectArray"; goto printit;
+ case 'L':
+ /* We have to generate a reference to JArray here,
+ so that our output matches what the compiler
+ does. */
+ ++signature;
+ fputs ("JArray<", stream);
+ while (signature < limit && *signature != ';')
+ {
+ int ch = UTF8_GET (signature, limit);
+ if (ch == '/')
+ fputs ("::", stream);
+ else
+ jcf_print_char (stream, ch);
+ }
+ fputs (" *> *", stream);
+ *need_space = 0;
+ ++signature;
+ break;
+ default:
+ /* Unparseable signature. */
+ return NULL;
+ }
+ break;
+
+ case '(':
+ case ')':
+ /* This shouldn't happen. */
+ return NULL;
+
+ case 'B': ctype = "jbyte"; goto printit;
+ case 'C': ctype = "jchar"; goto printit;
+ case 'D': ctype = "jdouble"; goto printit;
+ case 'F': ctype = "jfloat"; goto printit;
+ case 'I': ctype = "jint"; goto printit;
+ case 'J': ctype = "jlong"; goto printit;
+ case 'S': ctype = "jshort"; goto printit;
+ case 'Z': ctype = "jboolean"; goto printit;
+ case 'V': ctype = "void"; goto printit;
+ case 'L':
+ ++signature;
+ while (*signature && *signature != ';')
+ {
+ int ch = UTF8_GET (signature, limit);
+ /* `$' is the separator for an inner class. */
+ if (ch == '/' || ch == '$')
+ fputs ("::", stream);
+ else
+ jcf_print_char (stream, ch);
+ }
+ fputs (" *", stream);
+ if (*signature == ';')
+ signature++;
+ *need_space = 0;
+ break;
+ default:
+ *need_space = 1;
+ jcf_print_char (stream, *signature++);
+ break;
+ printit:
+ signature++;
+ *need_space = 1;
+ fputs (ctype, stream);
+ break;
+ }
+
+ return signature;
}
static void
-DEFUN(print_c_decl, (stream, jcf, name_index, signature_index, flags, is_init),
+DEFUN(print_c_decl, (stream, jcf, name_index, signature_index, is_init,
+ name_override),
FILE* stream AND JCF* jcf
- AND int name_index AND int signature_index AND JCF_u2 flags
- AND int is_init)
+ AND int name_index AND int signature_index
+ AND int is_init AND const char *name_override)
{
if (JPOOL_TAG (jcf, signature_index) != CONSTANT_Utf8)
- fprintf (stream, "<not a UTF8 constant>");
+ {
+ fprintf (stream, "<not a UTF8 constant>");
+ found_error = 1;
+ }
else
{
int length = JPOOL_UTF_LENGTH (jcf, signature_index);
unsigned char *str0 = JPOOL_UTF_DATA (jcf, signature_index);
register unsigned char *str = str0;
unsigned char *limit = str + length;
- int j;
- char *ctype;
int need_space = 0;
int is_method = str[0] == '(';
+ unsigned char *next;
- if (is_method)
+ /* If printing a method, skip to the return signature and print
+ that first. However, there is no return value if this is a
+ constructor. */
+ if (is_method && ! is_init)
{
- /* Skip to the return signature, and print that first.
- However, don't do this is we are printing a construtcor.
- */
- if (is_init)
- {
- str = str0 + 1;
- /* FIXME: Most programmers love Celtic knots because
- they see their own code in the interconnected loops.
- That is, this is spaghetti. */
- goto have_constructor;
- }
- else
+ while (str < limit)
{
- while (str < limit)
- {
- int ch = *str++;
- if (ch == ')')
- break;
- }
+ int ch = *str++;
+ if (ch == ')')
+ break;
}
}
- again:
- while (str < limit)
+ /* If printing a field or an ordinary method, then print the
+ "return value" now. */
+ if (! is_method || ! is_init)
{
- switch (str[0])
+ next = decode_signature_piece (stream, str, limit, &need_space);
+ if (! next)
{
- case '[':
- for (str++; str < limit && *str >= '0' && *str <= '9'; str++)
- ;
- switch (*str)
- {
- case 'B': ctype = "jbyteArray"; goto printit;
- case 'C': ctype = "jcharArray"; goto printit;
- case 'D': ctype = "jdoubleArray"; goto printit;
- case 'F': ctype = "jfloatArray"; goto printit;
- case 'I': ctype = "jintArray"; goto printit;
- case 'S': ctype = "jshortArray"; goto printit;
- case 'J': ctype = "jlongArray"; goto printit;
- case 'Z': ctype = "jbooleanArray"; goto printit;
- case '[': ctype = "jobjectArray"; goto printit;
- case 'L':
- /* We have to generate a reference to JArray here,
- so that our output matches what the compiler
- does. */
- ++str;
- fputs ("JArray<", out);
- while (str < limit && *str != ';')
- {
- int ch = UTF8_GET (str, limit);
- if (ch == '/')
- fputs ("::", stream);
- else
- jcf_print_char (stream, ch);
- }
- fputs (" *> *", out);
- need_space = 0;
- ++str;
- break;
- default:
- fprintf (stderr, "unparseable signature `%s'\n", str0);
- found_error = 1;
- ctype = "???"; goto printit;
- }
- break;
- case '(':
- fputc (*str++, stream);
- continue;
- case ')':
- fputc (*str++, stream);
- /* the return signature was printed in the first pass. */
+ fprintf (stderr, "unparseable signature: `%s'\n", str0);
+ found_error = 1;
return;
- case 'B': ctype = "jbyte"; goto printit;
- case 'C': ctype = "jchar"; goto printit;
- case 'D': ctype = "jdouble"; goto printit;
- case 'F': ctype = "jfloat"; goto printit;
- case 'I': ctype = "jint"; goto printit;
- case 'J': ctype = "jlong"; goto printit;
- case 'S': ctype = "jshort"; goto printit;
- case 'Z': ctype = "jboolean"; goto printit;
- case 'V': ctype = "void"; goto printit;
- case 'L':
- ++str;
- while (*str && *str != ';')
- {
- int ch = UTF8_GET (str, limit);
- if (ch == '/')
- fputs ("::", stream);
- else
- jcf_print_char (stream, ch);
- }
- fputs (" *", stream);
- if (*str == ';')
- str++;
- need_space = 0;
- break;
- default:
- need_space = 1;
- jcf_print_char (stream, *str++);
- break;
- printit:
- str++;
- need_space = 1;
- fputs (ctype, stream);
- break;
}
-
- if (is_method && str < limit && *str != ')')
- fputs (", ", stream);
}
- have_constructor:
- if (name_index)
+
+ /* Now print the name of the thing. */
+ if (need_space)
+ fputs (" ", stream);
+ if (name_override)
+ fputs (name_override, stream);
+ else if (name_index)
{
- if (need_space)
- fprintf (stream, " ");
/* Declare constructors specially. */
if (is_init)
print_base_classname (stream, jcf, jcf->this_class);
else
print_name (stream, jcf, name_index);
}
+
if (is_method)
{
+ /* Have a method or a constructor. Print signature pieces
+ until done. */
fputs (" (", stream);
- /* Go to beginning, skipping '('. */
str = str0 + 1;
- goto again; /* To handle argument signatures. */
+ while (str < limit && *str != ')')
+ {
+ next = decode_signature_piece (stream, str, limit, &need_space);
+ if (! next)
+ {
+ fprintf (stderr, "unparseable signature: `%s'\n", str0);
+ found_error = 1;
+ return;
+ }
+
+ if (next < limit && *next != ')')
+ fputs (", ", stream);
+ str = next;
+ }
+
+ fputs (")", stream);
}
}
}
-int
+void
DEFUN(print_mangled_classname, (stream, jcf, prefix, index),
- FILE *stream AND JCF *jcf AND char *prefix AND int index)
+ FILE *stream AND JCF *jcf AND const char *prefix AND int index)
{
int name_index = JPOOL_USHORT1 (jcf, index);
fputs (prefix, stream);
@@ -536,7 +786,7 @@ print_cxx_classname (stream, prefix, jcf, index)
int index;
{
int name_index = JPOOL_USHORT1 (jcf, index);
- int i, len, c;
+ int len, c;
unsigned char *s, *p, *limit;
s = JPOOL_UTF_DATA (jcf, name_index);
@@ -581,42 +831,283 @@ super_class_name (derived_jcf, len)
return supername;
}
-/* Print declarations for all classes required by this class. FIXME:
- the current implementation just prints every class name from the
- constant pool. This is too much. We really only need to print a
- declaration for each class which is the type of a return value, a
- field, or an argument. */
+
+
+/* We keep track of all the `#include's we generate, so we can avoid
+ duplicates. */
+struct include
+{
+ char *name;
+ struct include *next;
+};
+
+/* List of all includes. */
+static struct include *all_includes = NULL;
+
+/* Generate a #include. */
static void
-print_class_decls (out, jcf)
+print_include (out, utf8, len)
+ FILE *out;
+ unsigned char *utf8;
+ int len;
+{
+ struct include *incl;
+
+ if (! out)
+ return;
+
+ if (len == -1)
+ len = strlen (utf8);
+
+ for (incl = all_includes; incl; incl = incl->next)
+ {
+ if (! strncmp (incl->name, utf8, len))
+ return;
+ }
+
+ incl = (struct include *) malloc (sizeof (struct include));
+ incl->name = malloc (len + 1);
+ strncpy (incl->name, utf8, len);
+ incl->name[len] = '\0';
+ incl->next = all_includes;
+ all_includes = incl;
+
+ fputs ("#include <", out);
+ jcf_print_utf8 (out, utf8, len);
+ fputs (".h>\n", out);
+}
+
+
+
+/* This is used to represent part of a package or class name. */
+struct namelet
+{
+ /* The text of this part of the name. */
+ char *name;
+ /* True if this represents a class. */
+ int is_class;
+ /* Linked list of all classes and packages inside this one. */
+ struct namelet *subnamelets;
+ /* Pointer to next sibling. */
+ struct namelet *next;
+};
+
+/* The special root namelet. */
+static struct namelet root =
+{
+ NULL,
+ 0,
+ NULL,
+ NULL
+};
+
+/* This extracts the next name segment from the full UTF-8 encoded
+ package or class name and links it into the tree. It does this
+ recursively. */
+static void
+add_namelet (name, name_limit, parent)
+ unsigned char *name, *name_limit;
+ struct namelet *parent;
+{
+ unsigned char *p;
+ struct namelet *n = NULL, *np;
+
+ /* We want to skip the standard namespaces that we assume the
+ runtime already knows about. We only do this at the top level,
+ though, hence the check for `root'. */
+ if (parent == &root)
+ {
+#define JAVALANG "java/lang/"
+#define JAVAIO "java/io/"
+#define JAVAUTIL "java/util/"
+ if ((name_limit - name >= (int) sizeof (JAVALANG) - 1
+ && ! strncmp (name, JAVALANG, sizeof (JAVALANG) - 1))
+ || (name_limit - name >= (int) sizeof (JAVAUTIL) - 1
+ && ! strncmp (name, JAVAUTIL, sizeof (JAVAUTIL) - 1))
+ || (name_limit - name >= (int) sizeof (JAVAIO) - 1
+ && ! strncmp (name, JAVAIO, sizeof (JAVAIO) - 1)))
+ return;
+ }
+
+ for (p = name; p < name_limit && *p != '/' && *p != '$'; ++p)
+ ;
+
+ /* Search for this name beneath the PARENT node. */
+ for (np = parent->subnamelets; np != NULL; np = np->next)
+ {
+ if (! strncmp (name, np->name, p - name))
+ {
+ n = np;
+ break;
+ }
+ }
+
+ if (n == NULL)
+ {
+ n = (struct namelet *) malloc (sizeof (struct namelet));
+ n->name = malloc (p - name + 1);
+ strncpy (n->name, name, p - name);
+ n->name[p - name] = '\0';
+ n->is_class = (p == name_limit || *p == '$');
+ n->subnamelets = NULL;
+ n->next = parent->subnamelets;
+ parent->subnamelets = n;
+ }
+
+ /* We recurse if there is more text, and if the trailing piece does
+ not represent an inner class. */
+ if (p < name_limit && *p != '$')
+ add_namelet (p + 1, name_limit, n);
+}
+
+/* Print a single namelet. Destroys namelets while printing. */
+static void
+print_namelet (out, name, depth)
+ FILE *out;
+ struct namelet *name;
+ int depth;
+{
+ int i, term = 0;
+ struct namelet *c;
+
+ if (name->name)
+ {
+ for (i = 0; i < depth; ++i)
+ fputc (' ', out);
+ fprintf (out, "%s %s", name->is_class ? "class" : "namespace",
+ name->name);
+ if (name->is_class && name->subnamelets == NULL)
+ fputs (";\n", out);
+ else
+ {
+ term = 1;
+ fputs ("\n", out);
+ for (i = 0; i < depth; ++i)
+ fputc (' ', out);
+ fputs ("{\n", out);
+ }
+ }
+
+ c = name->subnamelets;
+ while (c != NULL)
+ {
+ struct namelet *next = c->next;
+ print_namelet (out, c, depth + 2);
+ c = next;
+ }
+
+ if (name->name)
+ {
+ if (term)
+ {
+ for (i = 0; i < depth; ++i)
+ fputc (' ', out);
+ fputs ("};\n", out);
+ }
+
+ free (name->name);
+ free (name);
+ }
+}
+
+/* This is called to add some classes to the list of classes for which
+ we need decls. The signature argument can be a function
+ signature. */
+static void
+add_class_decl (out, jcf, signature)
FILE *out;
JCF *jcf;
+ JCF_u2 signature;
{
- int i, seen_one = 0;
+ unsigned char *s = JPOOL_UTF_DATA (jcf, signature);
+ int len = JPOOL_UTF_LENGTH (jcf, signature);
+ int i;
+ /* Name of class we are processing. */
+ int name_index = JPOOL_USHORT1 (jcf, jcf->this_class);
+ int tlen = JPOOL_UTF_LENGTH (jcf, name_index);
+ char *tname = JPOOL_UTF_DATA (jcf, name_index);
- for (i = 1; i < JPOOL_SIZE (jcf); ++i)
+ for (i = 0; i < len; ++i)
{
- int kind = JPOOL_TAG (jcf, i);
- if (kind == CONSTANT_Class)
+ int start, saw_dollar;
+
+ /* If we see an array, then we include the array header. */
+ if (s[i] == '[')
{
- if (print_cxx_classname (out, "class ", jcf, i))
- fputs (";\n", out);
- seen_one = 1;
+ print_include (out, "java-array", -1);
+ continue;
+ }
+
+ /* We're looking for `L<stuff>;' -- everything else is
+ ignorable. */
+ if (s[i] != 'L')
+ continue;
+
+ saw_dollar = 0;
+ for (start = ++i; i < len && s[i] != ';'; ++i)
+ {
+ if (! saw_dollar && s[i] == '$' && out)
+ {
+ saw_dollar = 1;
+ /* If this class represents an inner class, then
+ generate a `#include' for the outer class. However,
+ don't generate the include if the outer class is the
+ class we are processing. */
+ if (i - start < tlen || strncmp (&s[start], tname, i - start))
+ print_include (out, &s[start], i - start);
+ break;
+ }
}
+
+ /* If we saw an inner class, then the generated #include will
+ declare the class. So in this case we needn't bother. */
+ if (! saw_dollar)
+ add_namelet (&s[start], &s[i], &root);
}
+}
+
+/* Print declarations for all classes required by this class. Any
+ class or package in the `java' package is assumed to be handled
+ statically in libjava; we don't generate declarations for these.
+ This makes the generated headers a bit easier to read. */
+static void
+print_class_decls (out, jcf, self)
+ FILE *out;
+ JCF *jcf;
+ int self;
+{
+ /* Make sure to always add the current class to the list of things
+ that should be declared. */
+ int name_index = JPOOL_USHORT1 (jcf, self);
+ int len;
+ unsigned char *s;
+
+ s = JPOOL_UTF_DATA (jcf, name_index);
+ len = JPOOL_UTF_LENGTH (jcf, name_index);
+ add_namelet (s, s + len, &root);
- if (seen_one)
- fputs ("\n", out);
+ if (root.subnamelets)
+ {
+ fputs ("extern \"Java\"\n{\n", out);
+ /* We use an initial offset of 0 because the root namelet
+ doesn't cause anything to print. */
+ print_namelet (out, &root, 0);
+ fputs ("};\n\n", out);
+ }
}
+
+
static void
DEFUN(process_file, (jcf, out),
JCF *jcf AND FILE *out)
{
int code, i;
+ uint32 field_start, method_end, method_start;
current_jcf = main_jcf = jcf;
- last_access = 0;
+ last_access = -1;
if (jcf_parse_preamble (jcf) != 0)
{
@@ -643,49 +1134,64 @@ DEFUN(process_file, (jcf, out),
jcf_parse_class (jcf);
- if (written_class_count++ == 0)
+ if (written_class_count++ == 0 && out)
fputs ("// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-\n\n",
out);
- print_mangled_classname (out, jcf, "#ifndef __", jcf->this_class);
- fprintf (out, "__\n");
+ if (out)
+ {
+ print_mangled_classname (out, jcf, "#ifndef __", jcf->this_class);
+ fprintf (out, "__\n");
+
+ print_mangled_classname (out, jcf, "#define __", jcf->this_class);
+ fprintf (out, "__\n\n");
- print_mangled_classname (out, jcf, "#define __", jcf->this_class);
- fprintf (out, "__\n\n");
+ /* We do this to ensure that inline methods won't be `outlined'
+ by g++. This works as long as method and fields are not
+ added by the user. */
+ fprintf (out, "#pragma interface\n");
+ }
- if (jcf->super_class)
+ if (jcf->super_class && out)
{
int super_length;
unsigned char *supername = super_class_name (jcf, &super_length);
- fputs ("#include <", out);
- jcf_print_utf8 (out, supername, super_length);
- fputs (".h>\n", out);
-
- /* FIXME: If our superclass is Object, then we include
- java-array.h. The right thing to do here is look at all the
- methods and fields and see if an array is in use. Only then
- would we need to include java-array.h. */
- if (! utf8_cmp (supername, super_length, "java/lang/Object"))
- fputs ("#include <java-array.h>\n", out);
-
fputs ("\n", out);
+ print_include (out, supername, super_length);
}
- print_class_decls (out, jcf);
+ /* We want to parse the methods first. But we need to find where
+ they start. So first we skip the fields, then parse the methods.
+ Then we parse the fields and skip the methods. This is ugly, but
+ not too bad since we need two full passes to get class decl
+ information anyway. */
+ field_pass = 0;
+ field_start = JCF_TELL (jcf);
+ jcf_parse_fields (jcf);
+
+ method_start = JCF_TELL (jcf);
+ method_pass = 0;
+ jcf_parse_methods (jcf);
+
+ if (out)
+ {
+ fputs ("\n", out);
+ print_class_decls (out, jcf, jcf->this_class);
- for (i = 0; i < prepend_count; ++i)
- fprintf (out, "%s\n", prepend_specs[i]);
- if (prepend_count > 0)
- fputc ('\n', out);
+ for (i = 0; i < prepend_count; ++i)
+ fprintf (out, "%s\n", prepend_specs[i]);
+ if (prepend_count > 0)
+ fputc ('\n', out);
+ }
- if (! print_cxx_classname (out, "class ", jcf, jcf->this_class))
+ if (out && ! print_cxx_classname (out, "class ", jcf, jcf->this_class))
{
fprintf (stderr, "class is of array type\n");
found_error = 1;
return;
}
- if (jcf->super_class)
+ if (out && jcf->super_class)
{
if (! print_cxx_classname (out, " : public ", jcf, jcf->super_class))
{
@@ -694,50 +1200,61 @@ DEFUN(process_file, (jcf, out),
return;
}
}
- fputs ("\n{\n", out);
+ if (out)
+ fputs ("\n{\n", out);
- /* We make a single pass over the file, printing methods and fields
- as we see them. We have to list the methods in the same order
- that they appear in the class file, so that the Java and C++
- vtables have the same layout. */
- jcf_parse_fields (jcf);
+ /* Now go back for second pass over methods and fields. */
+ JCF_SEEK (jcf, method_start);
+ method_pass = 1;
jcf_parse_methods (jcf);
+ method_end = JCF_TELL (jcf);
+
+ field_pass = 1;
+ JCF_SEEK (jcf, field_start);
+ jcf_parse_fields (jcf);
+ JCF_SEEK (jcf, method_end);
+
jcf_parse_final_attributes (jcf);
- /* Generate friend decl if we still must. */
- for (i = 0; i < friend_count; ++i)
- fprintf (out, " friend %s\n", friend_specs[i]);
+ if (out)
+ {
+ /* Generate friend decl if we still must. */
+ for (i = 0; i < friend_count; ++i)
+ fprintf (out, " friend %s\n", friend_specs[i]);
- /* Generate extra declarations. */
- if (add_count > 0)
- fputc ('\n', out);
- for (i = 0; i < add_count; ++i)
- fprintf (out, " %s\n", add_specs[i]);
+ /* Generate extra declarations. */
+ if (add_count > 0)
+ fputc ('\n', out);
+ for (i = 0; i < add_count; ++i)
+ fprintf (out, " %s\n", add_specs[i]);
- fputs ("};\n", out);
+ fputs ("};\n", out);
- if (append_count > 0)
- fputc ('\n', out);
- for (i = 0; i < append_count; ++i)
- fprintf (out, "%s\n", append_specs[i]);
+ if (append_count > 0)
+ fputc ('\n', out);
+ for (i = 0; i < append_count; ++i)
+ fprintf (out, "%s\n", append_specs[i]);
- print_mangled_classname (out, jcf, "\n#endif /* __", jcf->this_class);
- fprintf (out, "__ */\n");
+ print_mangled_classname (out, jcf, "\n#endif /* __", jcf->this_class);
+ fprintf (out, "__ */\n");
+ }
}
static void
usage ()
{
- fprintf (stderr, "gjavah: no classes specified\n");
+ fprintf (stderr, "gcjh: no classes specified\n");
exit (1);
}
static void
help ()
{
- printf ("Usage: gjavah [OPTION]... CLASS...\n\n");
+ printf ("Usage: gcjh [OPTION]... CLASS...\n\n");
printf ("Generate C++ header files from .class files\n\n");
printf (" --classpath PATH Set path to find .class files\n");
+ printf (" --CLASSPATH PATH Set path to find .class files\n");
+ printf (" -IDIR Append directory to class path\n");
printf (" -d DIRECTORY Set output directory name\n");
printf (" --help Print this help, then exit\n");
printf (" -o FILE Set output file name\n");
@@ -752,7 +1269,7 @@ static void
java_no_argument (opt)
char *opt;
{
- fprintf (stderr, "gjavah: no argument given for option `%s'\n", opt);
+ fprintf (stderr, "gcjh: no argument given for option `%s'\n", opt);
exit (1);
}
@@ -760,7 +1277,7 @@ static void
version ()
{
/* FIXME: use version.c? */
- printf ("gjavah (GNU gcc) 0.0\n\n");
+ printf ("gcjh (GNU gcc) 0.0\n\n");
printf ("Copyright (C) 1998 Free Software Foundation, Inc.\n");
printf ("This is free software; see the source for copying conditions. There is NO\n");
printf ("warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n");
@@ -773,10 +1290,14 @@ DEFUN(main, (argc, argv),
{
JCF jcf;
int argi;
+ char *output_file = NULL;
+ int emit_dependencies = 0, suppress_output = 0;
if (argc <= 1)
usage ();
+ jcf_path_init ();
+
for (argi = 1; argi < argc; argi++)
{
char *arg = argv[argi];
@@ -856,10 +1377,19 @@ DEFUN(main, (argc, argv),
else if (strcmp (arg, "-classpath") == 0)
{
if (argi + 1 < argc)
- classpath = argv[++argi];
+ jcf_path_classpath_arg (argv[++argi]);
+ else
+ java_no_argument (argv[argi]);
+ }
+ else if (strcmp (arg, "-CLASSPATH") == 0)
+ {
+ if (argi + 1 < argc)
+ jcf_path_CLASSPATH_arg (argv[++argi]);
else
java_no_argument (argv[argi]);
}
+ else if (strncmp (arg, "-I", 2) == 0)
+ jcf_path_include_arg (arg + 2);
else if (strcmp (arg, "-verbose") == 0 || strcmp (arg, "-v") == 0)
verbose++;
else if (strcmp (arg, "-stubs") == 0)
@@ -868,6 +1398,33 @@ DEFUN(main, (argc, argv),
help ();
else if (strcmp (arg, "-version") == 0)
version ();
+ else if (strcmp (arg, "-M") == 0)
+ {
+ emit_dependencies = 1;
+ suppress_output = 1;
+ jcf_dependency_init (1);
+ }
+ else if (strcmp (arg, "-MM") == 0)
+ {
+ emit_dependencies = 1;
+ suppress_output = 1;
+ jcf_dependency_init (0);
+ }
+ else if (strcmp (arg, "-MG") == 0)
+ {
+ fprintf (stderr, "gcjh: `%s' option is unimplemented\n", argv[argi]);
+ exit (1);
+ }
+ else if (strcmp (arg, "-MD") == 0)
+ {
+ emit_dependencies = 1;
+ jcf_dependency_init (1);
+ }
+ else if (strcmp (arg, "-MMD") == 0)
+ {
+ emit_dependencies = 1;
+ jcf_dependency_init (0);
+ }
else
{
fprintf (stderr, "%s: illegal argument\n", argv[argi]);
@@ -878,11 +1435,12 @@ DEFUN(main, (argc, argv),
if (argi == argc)
usage ();
- if (classpath == NULL)
+ jcf_path_seal ();
+
+ if (output_file && emit_dependencies)
{
- classpath = (char *) getenv ("CLASSPATH");
- if (classpath == NULL)
- classpath = "";
+ fprintf (stderr, "gcjh: can't specify both -o and -MD\n");
+ exit (1);
}
for (; argi < argc; argi++)
@@ -892,7 +1450,9 @@ DEFUN(main, (argc, argv),
if (verbose)
fprintf (stderr, "Processing %s\n", classname);
- classfile_name = find_class (classname, strlen (classname), &jcf, 1);
+ if (! output_file)
+ jcf_dependency_reset ();
+ classfile_name = find_class (classname, strlen (classname), &jcf, 0);
if (classfile_name == NULL)
{
fprintf (stderr, "%s: no such class\n", classname);
@@ -905,7 +1465,9 @@ DEFUN(main, (argc, argv),
if (strcmp (output_file, "-") == 0)
out = stdout;
else if (out == NULL)
- out = fopen (output_file, "w");
+ {
+ out = fopen (output_file, "w");
+ }
if (out == NULL)
{
perror (output_file);
@@ -928,18 +1490,38 @@ DEFUN(main, (argc, argv),
ch = '/';
current_output_file[dir_len++] = ch;
}
- strcpy (current_output_file+dir_len, ".h");
- out = fopen (current_output_file, "w");
- if (out == NULL)
+ if (emit_dependencies)
{
- perror (current_output_file);
- exit (1);
+ if (suppress_output)
+ {
+ jcf_dependency_set_dep_file ("-");
+ out = NULL;
+ }
+ else
+ {
+ /* We use `.hd' and not `.d' to avoid clashes with
+ dependency tracking from straight compilation. */
+ strcpy (current_output_file + dir_len, ".hd");
+ jcf_dependency_set_dep_file (current_output_file);
+ }
+ }
+ strcpy (current_output_file + dir_len, ".h");
+ jcf_dependency_set_target (current_output_file);
+ if (! suppress_output)
+ {
+ out = fopen (current_output_file, "w");
+ if (out == NULL)
+ {
+ perror (current_output_file);
+ exit (1);
+ }
}
}
process_file (&jcf, out);
JCF_FINISH (&jcf);
if (current_output_file != output_file)
free (current_output_file);
+ jcf_dependency_write ();
}
if (out != NULL && out != stdout)
diff --git a/gcc/java/java-except.h b/gcc/java/java-except.h
index 576096f8270..cdc123d744a 100644
--- a/gcc/java/java-except.h
+++ b/gcc/java/java-except.h
@@ -1,6 +1,6 @@
/* Definitions for exception handling for use by the GNU compiler
for the Java(TM) language compiler.
- Copyright (C) 1997 Free Software Foundation, Inc.
+ Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -65,3 +65,10 @@ extern void method_init_exceptions PROTO ((void));
extern void emit_handlers PROTO ((void));
+extern void maybe_start_try PROTO ((int));
+
+extern void maybe_end_try PROTO ((int));
+
+extern int add_handler PROTO ((int, int, tree, tree));
+
+extern void expand_resume_after_catch PROTO ((void));
diff --git a/gcc/java/java-tree.def b/gcc/java/java-tree.def
index a05b92d0aac..ead192476f6 100644
--- a/gcc/java/java-tree.def
+++ b/gcc/java/java-tree.def
@@ -1,12 +1,77 @@
/* Shift right, logical. */
-DEFTREECODE (URSHIFT_EXPR, "urshift_expr", "2", 2)
+DEFTREECODE (URSHIFT_EXPR, "urshift_expr", '2', 2)
/* Return -1, 0, 1 depending on whether the first argument is
less, equal, or greater to the second argument. */
-DEFTREECODE (COMPARE_EXPR, "compare_expr", "2", 2)
+DEFTREECODE (COMPARE_EXPR, "compare_expr", '2', 2)
/* Same as COMPARE_EXPR, but if either value is NaN, the result is -1. */
-DEFTREECODE (COMPARE_L_EXPR, "compare_l_expr", "2", 2)
+DEFTREECODE (COMPARE_L_EXPR, "compare_l_expr", '2', 2)
/* Same as COMPARE_EXPR, but if either value is NaN, the result is 1. */
-DEFTREECODE (COMPARE_G_EXPR, "compare_g_expr", "2", 2)
+DEFTREECODE (COMPARE_G_EXPR, "compare_g_expr", '2', 2)
+
+/* Unary plus. Operand 0 is the expression the unary plus is applied
+ to */
+DEFTREECODE (UNARY_PLUS_EXPR, "unary_plus_expr", '1', 1)
+
+/* New array creation expression.
+ Operand 0 is the array base type.
+ Operand 1 is the list of dimension expressions.
+ Operand 2 is the number of other dimensions of unspecified range.
+ Once patched, the node will bear the type of the created array. */
+DEFTREECODE (NEW_ARRAY_EXPR, "new_array_expr", 'e', 3)
+
+/* New class creation expression.
+ Operand 0 is the name of the class to be created
+ Operand 1 is the argument list used to select a constructor.
+ There is no operand 2. That slot is used for the
+ CALL_EXPR_RTL macro (see preexpand_calls).
+ The type should be the one of the created class. */
+DEFTREECODE (NEW_CLASS_EXPR, "new_class_expr", 'e', 3)
+
+/* Defines `this' as an expression. */
+DEFTREECODE (THIS_EXPR, "this", '1', 0)
+
+/* Case statement expression.
+ Operand 1 is the case value. */
+DEFTREECODE (CASE_EXPR, "case", 'x', 1)
+
+/* Default statement expression. */
+DEFTREECODE (DEFAULT_EXPR, "default", 'x', 0)
+
+/* Try expression
+ Operand 0 is the tried block,
+ Operand 1 contains chained catch nodes. */
+DEFTREECODE (TRY_EXPR, "try-catch-finally", 'e', 2)
+
+/* Catch clause.
+ Operand 0 is the catch clause block, which contains the declaration of
+ the catch clause parameter. */
+DEFTREECODE (CATCH_EXPR, "catch", '1', 1)
+
+/* Synchronized statement.
+ Operand 0 is the expression on which we whish to synchronize,
+ Operand 1 is the synchronized expression block. */
+DEFTREECODE (SYNCHRONIZED_EXPR, "synchronized", 'e', 2)
+
+/* Throw statement.
+ Operand 0 is the throw expresion. */
+DEFTREECODE (THROW_EXPR, "throw", '1', 1)
+
+/* Conditional operator.
+ Operand 0 is the condition expression
+ Operand 1 is the then-value
+ Operand 2 is the else-value. */
+DEFTREECODE (CONDITIONAL_EXPR, "?:", 'e', 3)
+
+/* instanceof operator.
+ Operand 0 is the expression that is getting tested
+ Operand 1 is the class used for the test. */
+DEFTREECODE (INSTANCEOF_EXPR, "instanceof", 'e', 2)
+
+/* Array initializers.
+ Operand 0 is the (sub) array target to initialize, left to NULL_TREE
+ when the node is created.
+ Operand 1 is a CONSTRUCTOR node. */
+DEFTREECODE (NEW_ARRAY_INIT, "new_array_init", '1', 1)
diff --git a/gcc/java/java-tree.h b/gcc/java/java-tree.h
index d8084993bee..2925c043aa9 100644
--- a/gcc/java/java-tree.h
+++ b/gcc/java/java-tree.h
@@ -1,6 +1,6 @@
/* Definitions for parsing and type checking for the GNU compiler for
the Java(TM) language.
- Copyright (C) 1997, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -49,16 +49,27 @@ struct JCF;
MODIFY_EXPR_FROM_INITIALIZATION_P (in MODIFY_EXPR)
3: IS_AN_IMPORT_ON_DEMAND_P (in IDENTIFIER_NODE)
RESOLVE_PACKAGE_NAME_P (in EXPR_WITH_FILE_LOCATION)
- 4: RESOLVE_TYPE_NAME_P (in EXPR_WITH_FILE_LOCATION)
- 5: IS_BREAK_STMT_P (in EXPR_WITH_FILE_LOCATION)
+ SWITCH_HAS_DEFAULT (in SWITCH_EXPR)
+ 4: IS_A_COMMAND_LINE_FILENAME_P (in IDENTIFIER_NODE)
+ RESOLVE_TYPE_NAME_P (in EXPR_WITH_FILE_LOCATION)
+ CALL_USING_SUPER (in CALL_EXPR)
+ 5: HAS_BEEN_ALREADY_PARSED_P (in IDENTIFIER_NODE)
+ IS_BREAK_STMT_P (in EXPR_WITH_FILE_LOCATION)
+ IS_CRAFTED_STRING_BUFFER_P (in CALL_EXPR)
+ 6: CAN_COMPLETE_NORMALLY (in statement nodes).
Usage of TYPE_LANG_FLAG_?:
1: TYPE_ARRAY_P (in RECORD_TYPE).
2: CLASS_LOADED_P (in RECORD_TYPE).
3: CLASS_FROM_SOURCE_P (in RECORD_TYPE).
4: CLASS_P (in RECORD_TYPE).
+ 5: CLASS_FROM_CURRENTLY_COMPILED_SOURCE_P (in RECORD_TYPE)
+ 6: CLASS_HAS_FINIT_P (in RECORD_TYPE)
Usage of DECL_LANG_FLAG_?:
+ 0: METHOD_DEPRECATED (in FUNCTION_DECL).
+ FIELD_DEPRECATED (in FIELD_DECL).
+ CLASS_DEPRECATED (in TYPE_DECL).
1: METHOD_PUBLIC (in FUNCTION_DECL).
FIELD_PUBLIC (in FIELD_DECL).
CLASS_PUBLIC (in TYPE_DECL).
@@ -79,8 +90,7 @@ struct JCF;
6: METHOD_TRANSIENT (in FUNCTION_DECL)
LABEL_CHANGED (in LABEL_DECL)
CLASS_SUPER (in TYPE_DECL, ACC_SUPER flag)
- INITIALIZED_P (in FIELD_DECL, VAR_DECL, PARM_DECL)
- 7: DECL_CONSTRUCTOR_P (in FUNCTION_DECL)
+ 7: DECL_CONSTRUCTOR_P (in FUNCTION_DECL).
*/
/* True if the class whose TYPE_BINFO this is has a superclass.
@@ -102,6 +112,9 @@ extern tree main_class;
/* The class we are currently processing. */
extern tree current_class;
+/* List of all class DECLs seen so far. */
+extern tree all_class_list;
+
/* Nonzero if we want to automatically do array bounds checking;
on by default. Use -fno-bounds-check to disable. */
@@ -114,6 +127,17 @@ extern int flag_assume_compiled;
extern int flag_emit_class_files;
+/* When non zero, we emit xref strings. Values of the flag for xref
+ backends are defined in xref.h. */
+
+extern int flag_emit_xref;
+
+/* Turned to 1 if -Wall was encountered. See lang.c for their meanings. */
+extern int flag_wall;
+extern int flag_redundant;
+extern int flag_not_overriding;
+extern int flag_static_local_jdk1_1;
+
/* The Java .class file that provides main_class; the main input file. */
extern struct JCF main_jcf[1], *current_jcf;
@@ -171,9 +195,12 @@ extern tree float_type_node;
extern tree double_type_node;
extern tree object_type_node;
+extern tree unqualified_object_id_node;
extern tree object_ptr_type_node;
extern tree string_type_node;
extern tree throwable_type_node;
+extern tree runtime_exception_type_node;
+extern tree error_exception_type_node;
extern tree byte_array_type_node;
extern tree short_array_type_node;
@@ -189,11 +216,12 @@ extern tree string_array_type_node;
extern tree TYPE_identifier_node; /* "TYPE" */
extern tree init_identifier_node; /* "<init>" */
extern tree clinit_identifier_node; /* "<clinit>" */
+extern tree finit_identifier_node; /* "$finit$" */
extern tree void_signature_node; /* "()V" */
-extern tree finalize_identifier_node; /* "finalize" */
extern tree length_identifier_node; /* "length" */
extern tree this_identifier_node; /* "this" */
extern tree super_identifier_node; /* "super" */
+extern tree continue_identifier_node; /* "continue" */
extern tree one_elt_array_domain_type;
extern tree void_type_node;
extern tree ptr_type_node;
@@ -204,9 +232,13 @@ extern tree return_address_type_node;
extern tree boolean_true_node, boolean_false_node;
/* Integer constants not declared in tree.h. */
+extern tree long_zero_node;
+extern tree float_zero_node;
+extern tree double_zero_node;
extern tree integer_negative_one_node;
extern tree integer_two_node;
extern tree integer_four_node;
+extern tree empty_stmt_node;
/* The type for struct methodtable. */
extern tree methodtable_type;
@@ -226,6 +258,8 @@ extern tree method_type_node;
extern tree method_ptr_type_node;
#define nativecode_ptr_type_node ptr_type_node
+extern tree end_params_node;
+
/* References to internal libjava functions we use. */
extern tree alloc_object_node;
extern tree soft_instanceof_node;
@@ -241,6 +275,7 @@ extern tree soft_monitorenter_node;
extern tree soft_monitorexit_node;
extern tree soft_lookupinterfacemethod_node;
extern tree soft_fmod_node;
+extern tree soft_exceptioninfo_call_node;
extern tree access_flags_type_node;
@@ -250,6 +285,7 @@ extern tree class_dtable_decl;
extern struct CPool *outgoing_cpool;
extern tree current_constant_pool_data_ref;
+extern tree wfl_operator;
struct lang_identifier
{
@@ -315,8 +351,19 @@ struct lang_identifier
#define DECL_MAX_STACK(DECL) (DECL_LANG_SPECIFIC(DECL)->max_stack)
/* Number of local variable slots needed for the arguments of this function. */
#define DECL_ARG_SLOT_COUNT(DECL) (DECL_LANG_SPECIFIC(DECL)->arg_slot_count)
-/* Pointer to the function's COMPOUND_EXPR tree */
+/* List of checked thrown exceptions, as specified with the `throws'
+ keyword */
+#define DECL_FUNCTION_THROWS(DECL) (DECL_LANG_SPECIFIC(DECL)->throws_list)
+/* List of other constructors of the same class that this constructor
+ calls */
+#define DECL_CONSTRUCTOR_CALLS(DECL) \
+ (DECL_LANG_SPECIFIC(DECL)->called_constructor)
+/* Pointer to the function's current's COMPOUND_EXPR tree (while
+ completing its body) or the function's block */
#define DECL_FUNCTION_BODY(DECL) (DECL_LANG_SPECIFIC(DECL)->function_decl_body)
+/* How specific the function is (for method selection - Java source
+ code front-end */
+#define DECL_SPECIFIC_COUNT(DECL) DECL_ARG_SLOT_COUNT(DECL)
/* In a LABEL_DECL, a TREE_VEC that saves the type_map at that point. */
#define LABEL_TYPE_STATE(NODE) (DECL_INITIAL (NODE))
@@ -388,7 +435,10 @@ struct lang_decl
long localvariables_offset;
int arg_slots;
int max_locals, max_stack, arg_slot_count;
+ tree throws_list; /* Exception specified by `throws' */
tree function_decl_body; /* Hold all function's statements */
+ tree called_constructor; /* When decl is a constructor, the
+ list of other constructor it calls. */
};
/* DECL_LANG_SPECIFIC for VAR_DECL and PARM_DECL. */
@@ -434,21 +484,22 @@ extern tree get_constant PROTO ((struct JCF*, int));
extern tree get_name_constant PROTO ((struct JCF*, int));
extern tree get_class_constant PROTO ((struct JCF*, int));
extern tree parse_signature PROTO ((struct JCF *jcf, int sig_index));
-extern int jcf_parse PROTO ((struct JCF*));
+extern void jcf_parse PROTO ((struct JCF*));
extern tree add_field PROTO ((tree, tree, tree, int));
extern tree add_method PROTO ((tree, int, tree, tree));
extern tree add_method_1 PROTO ((tree, int, tree, tree));
-extern tree make_class ();
+extern tree make_class PROTO ((void));
extern tree push_class PROTO ((tree, tree));
extern tree unmangle_classname PROTO ((const char *name, int name_length));
extern tree parse_signature_string PROTO ((const unsigned char *, int));
extern tree get_type_from_signature PROTO ((tree));
extern void layout_class PROTO ((tree));
-extern tree make_class ();
+extern tree layout_class_method PROTO ((tree, tree, tree, tree));
+extern void layout_class_methods PROTO ((tree));
extern tree build_class_ref PROTO ((tree));
extern tree build_dtable_decl PROTO ((tree));
extern tree build_internal_class_name PROTO ((tree));
-extern tree build_constants_constructor ();
+extern tree build_constants_constructor PROTO ((void));
extern tree build_ref_from_constant_pool PROTO ((int));
extern tree build_utf8_ref PROTO ((tree));
extern tree ident_subst PROTO ((const char*, int,
@@ -465,7 +516,7 @@ extern tree find_stack_slot PROTO ((int index, tree type));
extern tree build_prim_array_type PROTO ((tree, HOST_WIDE_INT));
extern tree build_java_array_type PROTO ((tree, HOST_WIDE_INT));
extern int is_compiled_class PROTO ((tree));
-extern tree mangled_classname PROTO ((char*, tree));
+extern tree mangled_classname PROTO ((const char*, tree));
extern tree lookup_label PROTO ((int));
extern tree pop_type PROTO ((tree));
extern void pop_argument_types PROTO ((tree));
@@ -473,26 +524,112 @@ extern tree decode_newarray_type PROTO ((int));
extern tree lookup_field PROTO ((tree*, tree));
extern int is_array_type_p PROTO ((tree));
extern HOST_WIDE_INT java_array_type_length PROTO ((tree));
+extern int read_class PROTO ((tree));
extern void load_class PROTO ((tree, int));
extern tree lookup_name PROTO ((tree));
extern tree build_known_method_ref PROTO ((tree, tree, tree, tree, tree));
extern tree build_class_init PROTO ((tree, tree));
extern tree build_invokevirtual PROTO ((tree, tree));
+extern tree build_invokeinterface PROTO ((tree, tree, tree));
extern tree invoke_build_dtable PROTO ((int, tree));
-extern tree match_java_method PROTO ((tree, tree, tree));
extern tree build_field_ref PROTO ((tree, tree, tree));
extern void pushdecl_force_head PROTO ((tree));
extern tree build_java_binop PROTO ((enum tree_code, tree, tree, tree));
extern tree binary_numeric_promotion PROTO ((tree, tree, tree *, tree *));
-extern tree build_decl_no_layout PROTO ((enum tree_code, tree, tree));
extern tree build_java_arrayaccess PROTO ((tree, tree, tree));
extern tree build_newarray PROTO ((int, tree));
extern tree build_anewarray PROTO ((tree, tree));
+extern tree build_new_array PROTO ((tree, tree));
extern tree build_java_array_length_access PROTO ((tree));
extern tree build_java_arraynull_check PROTO ((tree, tree, tree));
extern tree create_label_decl PROTO ((tree));
extern void push_labeled_block PROTO ((tree));
+extern tree prepare_eh_table_type PROTO ((tree));
+extern void java_set_exception_lang_code PROTO ((void));
+extern tree generate_name PROTO ((void));
+extern void pop_labeled_block PROTO ((void));
+extern char *lang_printable_name PROTO ((tree, int));
+extern tree maybe_add_interface PROTO ((tree, tree));
+extern void set_super_info PROTO ((int, tree, tree, int));
+extern int get_access_flags_from_decl PROTO ((tree));
+extern int interface_of_p PROTO ((tree, tree));
+extern int inherits_from_p PROTO ((tree, tree));
+extern void complete_start_java_method PROTO ((tree));
+extern tree build_result_decl PROTO ((tree));
+extern void emit_handlers PROTO ((void));
+extern void init_outgoing_cpool PROTO ((void));
+extern void make_class_data PROTO ((tree));
+extern void register_class PROTO ((void));
+extern int alloc_name_constant PROTO ((int, tree));
+extern void emit_register_classes PROTO ((void));
+extern void lang_init_source PROTO ((int));
+extern void write_classfile PROTO ((tree));
+extern char *print_int_node PROTO ((tree));
+extern void parse_error_context PVPROTO ((tree cl, const char *, ...))
+ ATTRIBUTE_PRINTF_2;
+extern tree build_primtype_type_ref PROTO ((char *));
+extern tree java_get_real_method_name PROTO ((tree));
+extern void finish_class PROTO ((tree));
+extern void java_layout_seen_class_methods PROTO ((void));
+extern void check_for_initialization PROTO ((tree));
+
+extern tree pushdecl_top_level PROTO ((tree));
+extern int alloc_class_constant PROTO ((tree));
+extern int unicode_mangling_length PROTO ((const char *, int));
+extern void init_expr_processing PROTO ((void));
+extern void push_super_field PROTO ((tree, tree));
+extern void init_class_processing PROTO ((void));
+extern int can_widen_reference_to PROTO ((tree, tree));
+extern int class_depth PROTO ((tree));
+extern int verify_jvm_instructions PROTO ((struct JCF *, unsigned char *, long));
+extern void maybe_pushlevels PROTO ((int));
+extern void maybe_poplevels PROTO ((int));
+extern int process_jvm_instruction PROTO ((int, unsigned char *, long));
+extern void set_local_type PROTO ((int, tree));
+extern int merge_type_state PROTO ((tree));
+extern void push_type PROTO ((tree));
+extern void load_type_state PROTO ((tree));
+extern void add_interface PROTO ((tree, tree));
+extern void append_gpp_mangled_name PROTO ((struct obstack *, const char *, int));
+extern void append_gpp_mangled_classtype PROTO ((struct obstack *, const char *));
+extern void emit_unicode_mangled_name PROTO ((struct obstack *, const char *, int));
+extern tree force_evaluation_order PROTO ((tree));
+extern int verify_constant_pool PROTO ((struct JCF *));
+extern void start_java_method PROTO ((tree));
+extern void end_java_method PROTO ((void));
+extern void give_name_to_locals PROTO ((struct JCF *));
+extern void expand_byte_code PROTO ((struct JCF *, tree));
+extern int open_in_zip PROTO ((struct JCF *, const char *, const char *, int));
+extern void set_constant_value PROTO ((tree, tree));
+#ifdef jword
+extern int find_constant1 PROTO ((struct CPool *, int, jword));
+extern int find_constant2 PROTO ((struct CPool *, int, jword, jword));
+#endif
+extern int find_utf8_constant PROTO ((struct CPool *, tree));
+extern int find_string_constant PROTO ((struct CPool *, tree));
+extern int find_class_constant PROTO ((struct CPool *, tree));
+extern int find_fieldref_index PROTO ((struct CPool *, tree));
+extern int find_methodref_index PROTO ((struct CPool *, tree));
+extern void write_constant_pool PROTO ((struct CPool *, unsigned char *, int));
+extern int count_constant_pool_bytes PROTO ((struct CPool *));
+extern int encode_newarray_type PROTO ((tree));
+#ifdef uint64
+extern void format_int PROTO ((char *, jlong, int));
+extern void format_uint PROTO ((char *, uint64, int));
+#endif
+extern void jcf_trim_old_input PROTO ((struct JCF *));
+#ifdef BUFSIZ
+extern void jcf_print_utf8 PROTO ((FILE *, const unsigned char *, int));
+extern void jcf_print_char PROTO ((FILE *, int));
+extern void jcf_print_utf8_replace PROTO ((FILE *, const unsigned char *,
+ int, int, int));
+# if JCF_USE_STDIO
+extern char* open_class PROTO ((char *, struct JCF *, FILE *, const char *));
+# else
+extern char* open_class PROTO ((char *, struct JCF *, int, const char *));
+# endif /* JCF_USE_STDIO */
+#endif
/* Access flags etc for a method (a FUNCTION_DECL): */
@@ -518,10 +655,6 @@ extern void push_labeled_block PROTO ((tree));
#define FIELD_VOLATILE(DECL) DECL_LANG_FLAG_4 (DECL)
#define FIELD_TRANSIENT(DECL) DECL_LANG_FLAG_5 (DECL)
-/* Initialized flag on variable/field/parm decl */
-
-#define INITIALIZED_P(DECL) DECL_LANG_FLAG_6 (DECL)
-
/* Access flags etc for a class (a TYPE_DECL): */
#define CLASS_PUBLIC(DECL) DECL_LANG_FLAG_1 (DECL)
@@ -530,6 +663,13 @@ extern void push_labeled_block PROTO ((tree));
#define CLASS_ABSTRACT(DECL) DECL_LANG_FLAG_5 (DECL)
#define CLASS_SUPER(DECL) DECL_LANG_FLAG_6 (DECL)
+/* @deprecated marker flag on methods, fields and classes */
+
+#define METHOD_DEPRECATED(DECL) DECL_LANG_FLAG_0 (DECL)
+#define FIELD_DEPRECATED(DECL) DECL_LANG_FLAG_0 (DECL)
+#define CLASS_DEPRECATED(DECL) DECL_LANG_FLAG_0 (DECL)
+#define DECL_DEPRECATED(DECL) DECL_LANG_FLAG_0 (DECL)
+
/* The number of virtual methods in this class's dispatch table.
Does not include initial two dummy entries (one points to the
Class object, and the other is for G++ -fvtable-thunks compatibility). */
@@ -539,8 +679,6 @@ extern void push_labeled_block PROTO ((tree));
virtual methods. */
#define TYPE_VTABLE(TYPE) TYPE_BINFO_VTABLE(TYPE)
-/* True of a RECORD_TYPE of a class/interface type (not array type) */
-#define CLASS_P(TYPE) TYPE_LANG_FLAG_4 (TYPE)
/* Use CLASS_LOADED_P? FIXME */
#define CLASS_COMPLETE_P(DECL) DECL_LANG_FLAG_2 (DECL)
@@ -625,6 +763,16 @@ extern tree *type_map;
/* True if class TYPE was defined in Java source code. */
#define CLASS_FROM_SOURCE_P(TYPE) TYPE_LANG_FLAG_3 (TYPE)
+/* True of a RECORD_TYPE of a class/interface type (not array type) */
+#define CLASS_P(TYPE) TYPE_LANG_FLAG_4 (TYPE)
+
+/* True if class TYPE was defined in a Java source file compiled. */
+#define CLASS_FROM_CURRENTLY_COMPILED_SOURCE_P(TYPE) \
+ TYPE_LANG_FLAG_5 (TYPE)
+
+/* True if class TYPE has a field initializer $finit$ function */
+#define CLASS_HAS_FINIT_P(TYPE) TYPE_LANG_FLAG_6 (TYPE)
+
/* True if identifier ID was seen while processing a single type import stmt */
#define IS_A_SINGLE_IMPORT_CLASSFILE_NAME_P(ID) TREE_LANG_FLAG_0 (ID)
@@ -637,9 +785,18 @@ extern tree *type_map;
/* True if ID is an already processed import on demand */
#define IS_AN_IMPORT_ON_DEMAND_P(ID) TREE_LANG_FLAG_3 (ID)
+/* True if ID is a command-line specified filename */
+#define IS_A_COMMAND_LINE_FILENAME_P(ID) TREE_LANG_FLAG_4 (ID)
+
+/* True if filename ID has already been parsed */
+#define HAS_BEEN_ALREADY_PARSED_P(ID) TREE_LANG_FLAG_5 (ID)
+
/* True if EXPR is RHS sub-tree of a compound assign expression */
#define COMPOUND_ASSIGN_P(EXPR) TREE_LANG_FLAG_1 (EXPR)
+/* True if a SWITCH_EXPR has a DEFAULT_EXPR. */
+#define SWITCH_HAS_DEFAULT(NODE) TREE_LANG_FLAG_3 (NODE)
+
/* True if EXPR (a WFL in that case) was created after the
reduction of PRIMARY . XXX */
#define PRIMARY_P(EXPR) TREE_LANG_FLAG_2 (EXPR)
@@ -663,6 +820,15 @@ extern tree *type_map;
/* True if STMT (a WFL in that case) holds a BREAK statement */
#define IS_BREAK_STMT_P(WFL) TREE_LANG_FLAG_5 (WFL)
+/* True if EXPR (a CALL_EXPR in that case) is a crafted StringBuffer */
+#define IS_CRAFTED_STRING_BUFFER_P(EXPR) TREE_LANG_FLAG_5 (EXPR)
+
+/* If set in CALL_EXPR, the receiver is 'super'. */
+#define CALL_USING_SUPER(EXPR) TREE_LANG_FLAG_4 (EXPR)
+
+/* True if NODE (a statement) can complete normally. */
+#define CAN_COMPLETE_NORMALLY(NODE) TREE_LANG_FLAG_6(NODE)
+
/* Add a FIELD_DECL to RECORD_TYPE RTYPE.
The field has name NAME (a char*), and type FTYPE.
Unless this is the first field, FIELD most hold the previous field.
@@ -709,12 +875,57 @@ extern tree *type_map;
#define FINISH_RECORD_CONSTRUCTOR(CONS) \
CONSTRUCTOR_ELTS(CONS) = nreverse (CONSTRUCTOR_ELTS(CONS))
-/* New tree code for expression, so we can expand then individually. */
-#define JAVA_UNARY_PLUS_EXPR ((int)LAST_AND_UNUSED_TREE_CODE + 2)
-#define JAVA_NEW_ARRAY_EXPR ((int)LAST_AND_UNUSED_TREE_CODE + 3)
-#define JAVA_NEW_CLASS_EXPR ((int)LAST_AND_UNUSED_TREE_CODE + 4)
-#define JAVA_THIS_EXPR ((int)LAST_AND_UNUSED_TREE_CODE + 5)
-
-/* Macro(s) using the definitions above */
-#define CALL_CONSTRUCTOR_P(NODE) (TREE_CODE (NODE) == JAVA_NEW_CLASS_EXPR)
-
+/* Macros on constructors invocations. */
+#define CALL_CONSTRUCTOR_P(NODE) \
+ (TREE_CODE (NODE) == NEW_CLASS_EXPR || CALL_EXPLICIT_CONSTRUCTOR_P (NODE))
+
+#define CALL_EXPLICIT_CONSTRUCTOR_P(NODE) \
+ (CALL_THIS_CONSTRUCTOR_P (NODE) || CALL_SUPER_CONSTRUCTOR_P (NODE))
+
+#define CALL_THIS_CONSTRUCTOR_P(NODE) \
+ (TREE_CODE (NODE) == CALL_EXPR \
+ && EXPR_WFL_NODE (TREE_OPERAND (NODE, 0)) == this_identifier_node)
+
+#define CALL_SUPER_CONSTRUCTOR_P(NODE) \
+ (TREE_CODE (NODE) == CALL_EXPR \
+ && EXPR_WFL_NODE (TREE_OPERAND (NODE, 0)) == super_identifier_node)
+
+/* Using a FINALLY_EXPR node */
+#define FINALLY_EXPR_LABEL(NODE) TREE_OPERAND ((NODE), 0)
+#define FINALLY_EXPR_BLOCK(NODE) TREE_OPERAND ((NODE), 1)
+
+#define BLOCK_EXPR_DECLS(NODE) BLOCK_VARS(NODE)
+#define BLOCK_EXPR_BODY(NODE) BLOCK_SUBBLOCKS(NODE)
+
+#define BUILD_MONITOR_ENTER(WHERE, ARG) \
+ { \
+ (WHERE) = build (CALL_EXPR, int_type_node, \
+ build_address_of (soft_monitorenter_node), \
+ build_tree_list (NULL_TREE, (ARG)), \
+ NULL_TREE); \
+ TREE_SIDE_EFFECTS (WHERE) = 1; \
+ }
+
+#define BUILD_MONITOR_EXIT(WHERE, ARG) \
+ { \
+ (WHERE) = build (CALL_EXPR, int_type_node, \
+ build_address_of (soft_monitorexit_node), \
+ build_tree_list (NULL_TREE, (ARG)), \
+ NULL_TREE); \
+ TREE_SIDE_EFFECTS (WHERE) = 1; \
+ }
+
+/* Non zero if TYPE is an unchecked exception */
+#define IS_UNCHECKED_EXCEPTION_P(TYPE) \
+ (inherits_from_p ((TYPE), runtime_exception_type_node) \
+ || inherits_from_p ((TYPE), error_exception_type_node))
+
+extern int java_error_count; \
+
+/* Make the current function where this macro is invoked report error
+ messages and and return, if any */
+#define java_parse_abort_on_error() \
+ { \
+ if (java_error_count > save_error_count) \
+ return; \
+ }
diff --git a/gcc/java/javaop.h b/gcc/java/javaop.h
index f4ae05006be..cce0a61ea49 100644
--- a/gcc/java/javaop.h
+++ b/gcc/java/javaop.h
@@ -1,6 +1,6 @@
/* Utility macros to handle Java(TM) byte codes.
- Copyright (C) 1996 Free Software Foundation, Inc.
+ Copyright (C) 1996, 1998, 1999 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
@@ -26,7 +26,6 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */
#ifndef JAVAOP_H
#define JAVAOP_H
-typedef char int8;
typedef unsigned char uint8;
#ifndef int16
#define int16 short
@@ -48,7 +47,11 @@ typedef unsigned int32 uint32;
#endif
typedef uint16 jchar;
-typedef int8 jbyte;
+#ifdef __STDC__
+typedef signed char jbyte;
+#else
+typedef char jbyte;
+#endif
typedef int16 jshort;
typedef int32 jint;
typedef int64 jlong;
@@ -79,10 +82,6 @@ union Word {
#define jword uint32
#endif
-#if !defined(inline) && !defined(__GC__) && !defined(__cplusplus)
-#define inline static
-#endif
-
#ifndef IMMEDIATE_u1
#define IMMEDIATE_u1 (PC++, CHECK_PC_IN_RANGE(PC), BCODE[PC-1])
#endif
@@ -103,14 +102,14 @@ union Word {
| (BCODE[PC-2] << 8) | (BCODE[PC-1]))))
#endif
-inline jfloat
+static inline jfloat
WORD_TO_FLOAT(jword w)
{ union Word wu;
wu.i = w;
return wu.f;
}
-inline jlong
+static inline jlong
WORDS_TO_LONG(jword hi, jword lo)
{
return ((jlong) hi << 32) | ((jlong)lo & (((jlong)1 << 32) -1));
@@ -122,7 +121,7 @@ union DWord {
jword w[2];
};
-inline jdouble
+static inline jdouble
WORDS_TO_DOUBLE(jword hi, jword lo)
{ union DWord wu;
wu.l = WORDS_TO_LONG(hi, lo);
diff --git a/gcc/java/jcf-dump.c b/gcc/java/jcf-dump.c
index 749aa82146f..6d3e37253b3 100644
--- a/gcc/java/jcf-dump.c
+++ b/gcc/java/jcf-dump.c
@@ -1,7 +1,7 @@
/* Program to dump out a Java(TM) .class file.
Functionally similar to Sun's javap.
- Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1996, 1997, 1998, 1999 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
@@ -46,8 +46,12 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */
*/
-#include <stdio.h>
+#include "config.h"
+#include "system.h"
+
#include "jcf.h"
+#include "tree.h"
+#include "java-tree.h"
/* Outout file. */
FILE *out;
@@ -74,22 +78,23 @@ int class_access_flags = 0;
/* Print in format similar to javap. VERY IMCOMPLETE. */
int flag_javap_compatible = 0;
-static int print_access_flags PROTO ((FILE *, uint16));
+static int print_access_flags PROTO ((FILE *, uint16, char));
static void print_constant_terse PROTO ((FILE*, JCF*, int, int));
static void print_constant PROTO ((FILE *, JCF *, int, int));
static void print_constant_ref PROTO ((FILE *, JCF *, int));
static void disassemble_method PROTO ((JCF*, unsigned char *, int));
static void print_name PROTO ((FILE*, JCF*, int));
static void print_signature PROTO ((FILE*, JCF*, int, int));
+static int utf8_equal_string PROTO ((struct JCF*, int, const char *));
+static int usage PROTO ((void));
+static void process_class PROTO ((struct JCF *));
#define PRINT_SIGNATURE_RESULT_ONLY 1
#define PRINT_SIGNATURE_ARGS_ONLY 2
-extern char* open_class();
-
-int
+static int
DEFUN(utf8_equal_string, (jcf, index, value),
- JCF *jcf AND int index AND char * value)
+ JCF *jcf AND int index AND const char * value)
{
if (CPOOL_INDEX_IN_RANGE (&jcf->cpool, index)
&& JPOOL_TAG (jcf, index) == CONSTANT_Utf8)
@@ -106,8 +111,8 @@ DEFUN(utf8_equal_string, (jcf, index, value),
this_class_index = 0; \
if (flag_print_class_info) \
fprintf (out, \
- "Magic number: 0x%0x, minor_version: %d, major_version: %d.\n", \
- MAGIC, MINOR, MAJOR)
+ "Magic number: 0x%0lx, minor_version: %ld, major_version: %ld.\n",\
+ (long) MAGIC, (long) MINOR, (long) MAJOR)
#define HANDLE_START_CONSTANT_POOL(COUNT) \
if (flag_print_constant_pool) \
@@ -116,7 +121,7 @@ DEFUN(utf8_equal_string, (jcf, index, value),
#define HANDLE_SOURCEFILE(INDEX) \
{ fprintf (out, "Attribute "); \
print_constant_terse (out, jcf, attribute_name, CONSTANT_Utf8); \
- fprintf (out, ", length:%d, #%d=", attribute_length, INDEX); \
+ fprintf (out, ", length:%ld, #%d=", (long) attribute_length, INDEX); \
print_constant_terse (out, jcf, INDEX, CONSTANT_Utf8); fputc ('\n', out); }
#define HANDLE_CLASS_INFO(ACCESS_FLAGS, THIS, SUPER, INTERFACES_COUNT) \
@@ -124,7 +129,7 @@ DEFUN(utf8_equal_string, (jcf, index, value),
class_access_flags = ACCESS_FLAGS; \
if (flag_print_class_info) \
{ fprintf (out, "\nAccess flags: 0x%x", ACCESS_FLAGS); \
- print_access_flags (out, ACCESS_FLAGS); \
+ print_access_flags (out, ACCESS_FLAGS, 'c'); \
fputc ('\n', out); \
fprintf (out, "This class: "); \
if (flag_print_constant_pool) \
@@ -160,7 +165,7 @@ DEFUN(utf8_equal_string, (jcf, index, value),
if (flag_print_fields) \
{ fprintf (out, "Field name:"); \
print_constant_terse (out, jcf, NAME, CONSTANT_Utf8); \
- print_access_flags (out, ACCESS_FLAGS); \
+ print_access_flags (out, ACCESS_FLAGS, 'f'); \
fprintf (out, " Signature: "); \
if (flag_print_constant_pool) \
fprintf (out, "%d=", SIGNATURE); \
@@ -191,7 +196,7 @@ DEFUN(utf8_equal_string, (jcf, index, value),
if (flag_javap_compatible) \
{ \
fprintf (out, " "); \
- print_access_flags (out, ACCESS_FLAGS); \
+ print_access_flags (out, ACCESS_FLAGS, 'm'); \
fputc (' ', out); \
print_signature (out, jcf, SIGNATURE, PRINT_SIGNATURE_RESULT_ONLY); \
fputc (' ', out); \
@@ -203,7 +208,7 @@ DEFUN(utf8_equal_string, (jcf, index, value),
{ \
fprintf (out, "\nMethod name:"); \
print_constant_terse (out, jcf, NAME, CONSTANT_Utf8); \
- print_access_flags (out, ACCESS_FLAGS); \
+ print_access_flags (out, ACCESS_FLAGS, 'm'); \
fprintf (out, " Signature: "); \
if (flag_print_constant_pool) \
fprintf (out, "%d=", SIGNATURE); \
@@ -225,7 +230,7 @@ DEFUN(utf8_equal_string, (jcf, index, value),
#define COMMON_HANDLE_ATTRIBUTE(JCF, INDEX, LENGTH) \
( fprintf (out, "Attribute "), \
print_constant_terse (out, jcf, INDEX, CONSTANT_Utf8), \
- fprintf (out, ", length:%d", LENGTH) )
+ fprintf (out, ", length:%ld", (long) LENGTH) )
#define HANDLE_CONSTANTVALUE(VALUE_INDEX) \
( COMMON_HANDLE_ATTRIBUTE(JCF, attribute_name, attribute_length), \
@@ -235,10 +240,13 @@ DEFUN(utf8_equal_string, (jcf, index, value),
#define HANDLE_CODE_ATTRIBUTE(MAX_STACK, MAX_LOCALS, CODE_LENGTH) \
{ COMMON_HANDLE_ATTRIBUTE(JCF, attribute_name, attribute_length); \
- fprintf (out, ", max_stack:%d, max_locals:%d, code_length:%d\n", \
- MAX_STACK, MAX_LOCALS, CODE_LENGTH); \
+ fprintf (out, ", max_stack:%ld, max_locals:%ld, code_length:%ld\n", \
+ (long) MAX_STACK, (long) MAX_LOCALS, (long) CODE_LENGTH); \
disassemble_method (jcf, jcf->read_ptr, CODE_LENGTH); }
+#define HANDLE_EXCEPTION_TABLE(ENTRIES, COUNT) \
+ print_exception_table (jcf, ENTRIES, COUNT)
+
#define HANDLE_EXCEPTIONS_ATTRIBUTE(COUNT) \
{ int n = (COUNT); int i; \
COMMON_HANDLE_ATTRIBUTE(JCF, attribute_name, attribute_length); \
@@ -286,7 +294,6 @@ DEFUN(utf8_equal_string, (jcf, index, value),
fprintf (out, "\nAttributes (count: %d):\n", attributes_count);
#include "javaop.h"
-#include "jcf-reader.c"
static void
DEFUN(print_constant_ref, (stream, jcf, index),
@@ -297,19 +304,29 @@ DEFUN(print_constant_ref, (stream, jcf, index),
fprintf (stream, "out of range");
else
print_constant (stream, jcf, index, 1);
- fprintf (stream, ">", index);
+ fprintf (stream, ">");
}
+/* Print the access flags given by FLAGS.
+ The CONTEXT is one of 'c' (class flags), 'f' (field flags),
+ or 'm' (method flags). */
+
static int
-DEFUN (print_access_flags, (stream, flags),
- FILE *stream AND uint16 flags)
+DEFUN (print_access_flags, (stream, flags, context),
+ FILE *stream AND uint16 flags AND char context)
{
if (flags & ACC_PUBLIC) fprintf (stream, " public");
if (flags & ACC_PRIVATE) fprintf (stream, " private");
if (flags & ACC_PROTECTED) fprintf (stream, " protected");
if (flags & ACC_STATIC) fprintf (stream, " static");
if (flags & ACC_FINAL) fprintf (stream, " final");
- if (flags & ACC_SYNCHRONIZED) fprintf (stream, " synchronized");
+ if (flags & ACC_SYNCHRONIZED)
+ {
+ if (context == 'c')
+ fprintf (stream, " super");
+ else
+ fprintf (stream, " synchronized");
+ }
if (flags & ACC_VOLATILE) fprintf (stream, " volatile");
if (flags & ACC_TRANSIENT) fprintf (stream, " transient");
if (flags & ACC_NATIVE) fprintf (stream, " native");
@@ -332,11 +349,13 @@ DEFUN(print_name, (stream, jcf, name_index),
/* If the type of the constant at INDEX matches EXPECTED,
print it tersely, otherwise more verbosely. */
-void
+static void
DEFUN(print_constant_terse, (out, jcf, index, expected),
FILE *out AND JCF *jcf AND int index AND int expected)
{
- if (JPOOL_TAG (jcf, index) != expected)
+ if (! CPOOL_INDEX_IN_RANGE (&jcf->cpool, index))
+ fprintf (out, "<constant pool index %d not in range>", index);
+ else if (JPOOL_TAG (jcf, index) != expected)
{
fprintf (out, "<Unexpected constant type ");
print_constant (out, jcf, index, 1);
@@ -357,7 +376,7 @@ DEFUN(print_constant, (out, jcf, index, verbosity),
{
int j, n;
jlong num;
- char *str;
+ const char *str;
int kind = JPOOL_TAG (jcf, index);
switch (kind)
{
@@ -511,10 +530,9 @@ DEFUN(print_signature_type, (stream, ptr, limit),
{
case '[':
array_size = -1;
- for ((*ptr)++; (*ptr) < limit && isdigit (**ptr); (*ptr)++)
+ for ((*ptr)++; (*ptr) < limit && ISDIGIT (**ptr); (*ptr)++)
{
- int digit =
- array_size = (array_size < 0 ? 0 : 10 * array_size) + *(*ptr) - '0';
+ array_size = (array_size < 0 ? 0 : 10 * array_size) + *(*ptr) - '0';
}
print_signature_type (stream, ptr, limit);
if (array_size == -1)
@@ -571,7 +589,6 @@ DEFUN(print_signature, (stream, jcf, signature_index, int options),
print_constant_terse (out, jcf, signature_index, CONSTANT_Utf8);
else
{
- int j;
const unsigned char *str = JPOOL_UTF_DATA (jcf, signature_index);
int length = JPOOL_UTF_LENGTH (jcf, signature_index);
const unsigned char *limit;
@@ -586,7 +603,7 @@ DEFUN(print_signature, (stream, jcf, signature_index, int options),
}
if (options & PRINT_SIGNATURE_ARGS_ONLY)
{
- *str++;
+ str++;
fputc ('(', stream);
while (str < limit && *str != ')')
{
@@ -610,14 +627,47 @@ DEFUN(print_signature, (stream, jcf, signature_index, int options),
}
}
-int
+
+static void
+DEFUN(print_exception_table, (jcf, entries, count),
+ JCF *jcf AND unsigned char *entries AND int count)
+{
+ /* Print exception table. */
+ int i = count;
+ if (i > 0)
+ {
+ unsigned char *ptr = entries;
+ fprintf (out, "Exceptions (count: %d):\n", i);
+ for (; --i >= 0; ptr+= 8)
+ {
+ int start_pc = GET_u2 (ptr);
+ int end_pc = GET_u2 (ptr+2);
+ int handler_pc = GET_u2 (ptr+4);
+ int catch_type = GET_u2 (ptr+6);
+ fprintf (out, " start: %d, end: %d, handler: %d, type: %d",
+ start_pc, end_pc, handler_pc, catch_type);
+ if (catch_type == 0)
+ fputs (" /* finally */", out);
+ else
+ {
+ fputc('=', out);
+ print_constant_terse (out, jcf, catch_type, CONSTANT_Class);
+ }
+ fputc ('\n', out);
+ }
+ }
+}
+
+#include "jcf-reader.c"
+
+static int
DEFUN (usage, (), )
{
fprintf (stderr, "Usage: jcf-dump [-o outputfile] [-c] classname\n");
exit(1);
}
-void
+static void
DEFUN(process_class, (jcf),
JCF *jcf)
{
@@ -630,13 +680,13 @@ DEFUN(process_class, (jcf),
if (code != 0)
{
fprintf (stderr, "error while parsing constant pool\n");
- exit (-1);
+ exit (FATAL_EXIT_CODE);
}
code = verify_constant_pool (jcf);
if (code > 0)
{
fprintf (stderr, "error in constant pool entry #%d\n", code);
- exit (-1);
+ exit (FATAL_EXIT_CODE);
}
if (flag_print_constant_pool)
print_constant_pool (jcf);
@@ -646,19 +696,19 @@ DEFUN(process_class, (jcf),
if (code != 0)
{
fprintf (stderr, "error while parsing fields\n");
- exit (-1);
+ exit (FATAL_EXIT_CODE);
}
code = jcf_parse_methods (jcf);
if (code != 0)
{
fprintf (stderr, "error while parsing methods\n");
- exit (-1);
+ exit (FATAL_EXIT_CODE);
}
code = jcf_parse_final_attributes (jcf);
if (code != 0)
{
fprintf (stderr, "error while parsing final attributes\n");
- exit (-1);
+ exit (FATAL_EXIT_CODE);
}
jcf->filename = NULL;
}
@@ -672,55 +722,50 @@ DEFUN(main, (argc, argv),
if (argc <= 1)
usage ();
+ jcf_path_init ();
+
for (argi = 1; argi < argc; argi++)
{
char *arg = argv[argi];
- if (arg[0] == '-')
+
+ if (arg[0] != '-' || ! strcmp (arg, "--"))
+ break;
+
+ /* Just let all arguments be given in either "-" or "--" form. */
+ if (arg[1] == '-')
+ ++arg;
+
+ if (strcmp (arg, "-o") == 0 && argi + 1 < argc)
+ output_file = argv[++argi];
+ else if (strcmp (arg, "-classpath") == 0 && argi + 1 < argc)
+ jcf_path_classpath_arg (argv[++argi]);
+ else if (strcmp (arg, "-CLASSPATH") == 0 && argi + 1 < argc)
+ jcf_path_CLASSPATH_arg (argv[++argi]);
+ else if (strncmp (arg, "-I", 2) == 0)
+ jcf_path_include_arg (arg + 2);
+ else if (strcmp (arg, "-verbose") == 0)
+ verbose++;
+ else if (strcmp (arg, "-print-main") == 0)
+ flag_print_main++;
+ else if (strcmp (arg, "-c") == 0)
+ flag_disassemble_methods++;
+ else if (strcmp (arg, "-javap") == 0)
{
- if (strcmp (arg, "-o") == 0 && argi + 1 < argc)
- output_file = argv[++argi];
- else if (arg[1] == '-')
- {
- arg++;
- if (strcmp (arg, "-classpath") == 0 && argi + 1 < argc)
- classpath = argv[++argi];
- else if (strcmp (arg, "-verbose") == 0)
- verbose++;
- else if (strcmp (arg, "-print-main") == 0)
- flag_print_main++;
- else if (strcmp (arg, "-javap") == 0)
- {
- flag_javap_compatible++;
- flag_print_constant_pool = 0;
- }
- else if (arg[2] == '\0')
- break;
- else
- {
- fprintf (stderr, "%s: illegal argument\n", argv[argi]);
- exit (-1);
- }
-
- }
- else if (strcmp (arg, "-classpath") == 0 && argi + 1 < argc)
- classpath = argv[++argi];
- else if (strcmp (arg, "-verbose") == 0)
- verbose++;
- else if (strcmp (arg, "-print-main") == 0)
- flag_print_main++;
- else if (strcmp (arg, "-c") == 0)
- flag_disassemble_methods++;
- else
- {
- fprintf (stderr, "%s: illegal argument\n", argv[argi]);
- exit (-1);
- }
+ flag_javap_compatible++;
+ flag_print_constant_pool = 0;
}
else
- break;
+ {
+ fprintf (stderr, "%s: illegal argument\n", argv[argi]);
+ exit (FATAL_EXIT_CODE);
+ }
}
+
if (argi == argc)
usage ();
+
+ jcf_path_seal ();
+
if (flag_print_main)
{
flag_print_fields = 0;
@@ -730,20 +775,13 @@ DEFUN(main, (argc, argv),
flag_print_class_info = 0;
}
- if (classpath == NULL)
- {
- classpath = (char *) getenv ("CLASSPATH");
- if (classpath == NULL)
- classpath = "";
- }
-
if (output_file)
{
out = fopen (output_file, "w");
if (out)
{
fprintf (stderr, "Cannot open '%s' for output.\n", output_file);
- exit (-1);
+ exit (FATAL_EXIT_CODE);
}
}
else
@@ -753,9 +791,9 @@ DEFUN(main, (argc, argv),
{
fprintf (out, "Reading .class from <standard input>.\n");
#if JCF_USE_STDIO
- open_class ("<stdio>", jcf, stdin);
+ open_class ("<stdio>", jcf, stdin, NULL);
#else
- open_class ("<stdio>", jcf, 0);
+ open_class ("<stdio>", jcf, 0, NULL);
#endif
process_class (jcf);
}
@@ -764,13 +802,13 @@ DEFUN(main, (argc, argv),
for (; argi < argc; argi++)
{
char *arg = argv[argi];
- char* class_filename = find_class (arg, strlen (arg), jcf, 1);
+ char* class_filename = find_class (arg, strlen (arg), jcf, 0);
if (class_filename == NULL)
- class_filename = find_classfile (arg, jcf);
+ class_filename = find_classfile (arg, jcf, NULL);
if (class_filename == NULL)
{
perror ("Could not find class");
- exit (-1);
+ exit (FATAL_EXIT_CODE);
}
JCF_FILL (jcf, 4);
if (GET_u4 (jcf->read_ptr) == ZIPMAGIC)
@@ -792,8 +830,8 @@ DEFUN(main, (argc, argv),
break; /* got to central directory */
if (magic != 0x04034b50) /* ZIPMAGIC (little-endian) */
{
- fprintf (stderr, "bad format of .zip archine\n");
- exit (-1);
+ fprintf (stderr, "bad format of .zip/.jar archive\n");
+ exit (FATAL_EXIT_CODE);
}
JCF_FILL (jcf, 26);
JCF_SKIP (jcf, 2);
@@ -866,6 +904,8 @@ DEFUN(main, (argc, argv),
JCF_FINISH(jcf);
}
}
+
+ exit (SUCCESS_EXIT_CODE);
}
static void
@@ -876,6 +916,7 @@ DEFUN(disassemble_method, (jcf, byte_ops, len),
#undef PTR
int PC;
int i;
+ int saw_wide = 0;
if (flag_disassemble_methods == 0)
return;
#define BCODE byte_ops
@@ -883,10 +924,7 @@ DEFUN(disassemble_method, (jcf, byte_ops, len),
{
int oldpc = PC;
int saw_index;
- jlong LONG_temp;
jint INT_temp;
- jfloat FLOAT_temp;
- jdouble DOUBLE_temp;
switch (byte_ops[PC++])
{
@@ -915,17 +953,15 @@ DEFUN(disassemble_method, (jcf, byte_ops, len),
/* Print out operand (if not implied by the opcode) for PUSCH opcodes.
These all push a constant onto the opcode stack. */
#define PUSHC(OPERAND_TYPE, OPERAND_VALUE) \
- saw_index = 0, INT_temp = (OPERAND_VALUE); \
+ saw_index = 0, i = (OPERAND_VALUE); \
if (oldpc+1 == PC) /* nothing */; \
- else if (saw_index) fprintf (out, " "), print_constant_ref (out, jcf, INT_temp); \
- else fprintf (out, " %d", INT_temp);
+ else if (saw_index) fprintf (out, " "), print_constant_ref (out, jcf, i); \
+ else fprintf (out, " %d", i);
/* Print out operand (a local variable index) for LOAD opcodes.
These all push local variable onto the opcode stack. */
#define LOAD(OPERAND_TYPE, OPERAND_VALUE) \
- INT_temp = (OPERAND_VALUE); \
- if (oldpc+1 == PC) /* nothing - local index implied by opcode */; \
- else fprintf (out, " %d", INT_temp);
+ INT_temp = saw_wide ? IMMEDIATE_u2 : (OPERAND_VALUE); goto load_store;
/* Handle STORE opcodes same as LOAD opcodes.
These all store a value from the opcode stack in a local variable. */
@@ -947,7 +983,9 @@ DEFUN(disassemble_method, (jcf, byte_ops, len),
/* Print operand for invoke opcodes. */
#define INVOKE(OPERAND_TYPE, OPERAND_VALUE) \
fputc (' ', out); print_constant_ref (out, jcf, IMMEDIATE_u2);\
- PC += 2 * OPERAND_VALUE /* for invokeinterface */;
+ if (OPERAND_VALUE) /* for invokeinterface */ \
+ { int nargs = IMMEDIATE_u1; PC++; \
+ fprintf (out, " nargs:%d", nargs); }
#define OBJECT(OPERAND_TYPE, OPERAND_VALUE) \
fputc (' ', out); print_constant_ref (out, jcf, IMMEDIATE_u2);
@@ -987,22 +1025,24 @@ DEFUN(disassemble_method, (jcf, byte_ops, len),
#define BRANCH(OPERAND_TYPE, OPERAND_VALUE) \
saw_index = 0, INT_temp = (OPERAND_VALUE); \
- fprintf (out, " %d", saw_index ? INT_temp : oldpc + INT_temp)
+ fprintf (out, " %ld", (long) (saw_index ? INT_temp : oldpc + INT_temp))
#define JSR(OPERAND_TYPE, OPERAND_VALUE) \
saw_index = 0, INT_temp = (OPERAND_VALUE); \
- fprintf (out, " %d", saw_index ? INT_temp : oldpc + INT_temp)
+ fprintf (out, " %ld", (long) (saw_index ? INT_temp : oldpc + INT_temp))
+#undef RET /* Defined by config/i386/i386.h */
#define RET(OPERAND_TYPE, OPERAND_VALUE) \
- INT_temp = (OPERAND_VALUE); \
- fprintf (out, " %d", INT_temp);
+ INT_temp = saw_wide ? IMMEDIATE_u2 : (OPERAND_VALUE); \
+ saw_wide = 0; \
+ fprintf (out, " %ld", (long) INT_temp);
#define SWITCH(OPERAND_TYPE, TABLE_OR_LOOKUP) \
PC = (PC + 3) / 4 * 4; TABLE_OR_LOOKUP##_SWITCH
#define LOOKUP_SWITCH \
{ jint default_offset = IMMEDIATE_s4; jint npairs = IMMEDIATE_s4; \
- fprintf (out, " npairs=%d, default=%d", npairs, default_offset+oldpc); \
+ fprintf (out, " npairs=%ld, default=%ld", (long) npairs, (long) default_offset+oldpc); \
while (--npairs >= 0) { \
jint match = IMMEDIATE_s4; jint offset = IMMEDIATE_s4; \
fprintf (out, "\n%10ld: %ld", (long)match, (long)(offset+oldpc)); } \
@@ -1011,8 +1051,8 @@ DEFUN(disassemble_method, (jcf, byte_ops, len),
#define TABLE_SWITCH \
{ jint default_offset = IMMEDIATE_s4; \
jint low = IMMEDIATE_s4; jint high = IMMEDIATE_s4; \
- fprintf (out, " low==%d, high=%ddefault=%d", \
- low, high, default_offset+oldpc); \
+ fprintf (out, " low=%ld, high=%ld, default=%ld", \
+ (long) low, (long) high, (long) default_offset+oldpc); \
for (; low <= high; low++) { \
jint offset = IMMEDIATE_s4; \
fprintf (out, "\n%10ld: %ld", (long)low, (long)(offset+oldpc)); } \
@@ -1022,11 +1062,14 @@ DEFUN(disassemble_method, (jcf, byte_ops, len),
SPECIAL_##OPERAND_VALUE(OPERAND_TYPE)
#define SPECIAL_IINC(OPERAND_TYPE) \
- INT_temp = IMMEDIATE_u1; \
- fprintf (out, "%d %d", INT_temp, IMMEDIATE_s1)
+ i = saw_wide ? IMMEDIATE_u2 : IMMEDIATE_u1; \
+ fprintf (out, " %d", i); \
+ INT_temp = saw_wide ? IMMEDIATE_s2 : IMMEDIATE_s1; \
+ saw_wide = 0; \
+ fprintf (out, " %d", i)
#define SPECIAL_WIDE(OPERAND_TYPE) \
- INT_temp = IMMEDIATE_u1; fprintf (out, "%d", INT_temp)
+ saw_wide = 1;
#define SPECIAL_EXIT(OPERAND_TYPE) /* nothing */
#define SPECIAL_ENTER(OPERAND_TYPE) /* nothing */
@@ -1040,33 +1083,19 @@ DEFUN(disassemble_method, (jcf, byte_ops, len),
TEST(OPERAND_TYPE, OPERAND_VALUE)
#include "javaop.def"
- default:
- fprintf (out, "%3d: unknown(%3d)\n", oldpc, byte_ops[PC]);
- }
- }
- /* Print exception table. */
- i = GET_u2(byte_ops+len);
- if (i > 0)
- {
- unsigned char *ptr = byte_ops+len+2;
- fprintf (out, "Exceptions (count: %d):\n", i);
- for (; --i >= 0; ptr+= 8)
- {
- int start_pc = GET_u2 (ptr);
- int end_pc = GET_u2 (ptr+2);
- int handler_pc = GET_u2 (ptr+4);
- int catch_type = GET_u2 (ptr+6);
- fprintf (out, " start: %d, end: %d, handler: %d, type: %d",
- start_pc, end_pc, handler_pc, catch_type);
- if (catch_type == 0)
- fputs (" /* finally */", out);
+ load_store:
+ if (oldpc+1 == PC) /* nothing - local index implied by opcode */;
else
{
- fputc('=', out);
- print_constant_terse (out, jcf, catch_type, CONSTANT_Class);
+ saw_wide = 0;
+ fprintf (out, " %ld", (long) INT_temp);
}
fputc ('\n', out);
+ break;
+
+ default:
+ fprintf (out, "%3d: unknown(%3d)\n", oldpc, byte_ops[PC]);
}
}
}
diff --git a/gcc/java/jcf-io.c b/gcc/java/jcf-io.c
index e5586326d8d..e4d614d687e 100644
--- a/gcc/java/jcf-io.c
+++ b/gcc/java/jcf-io.c
@@ -1,5 +1,5 @@
/* Utility routines for finding and reading Java(TM) .class files.
- Copyright (C) 1996 Free Software Foundation, Inc.
+ Copyright (C) 1996, 97-98, 1999 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
@@ -25,19 +25,15 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */
#include "config.h"
#include "system.h"
-#define ENABLE_UNZIP 1
-
#include "jcf.h"
-#include <sys/stat.h>
-#include <sys/wait.h>
+#include "tree.h"
+#include "java-tree.h"
/* DOS brain-damage */
#ifndef O_BINARY
#define O_BINARY 0 /* MS-DOS brain-damage */
#endif
-char *classpath;
-
int
DEFUN(jcf_unexpected_eof, (jcf, count),
JCF *jcf AND int count)
@@ -83,66 +79,86 @@ DEFUN(jcf_filbuf_from_stdio, (jcf, count),
count -= jcf->read_end - jcf->read_ptr;
if (count <= 0)
return 0;
- if (fread (jcf->read_end, 1, count, file) != count)
+ if ((int) fread (jcf->read_end, 1, count, file) != count)
jcf_unexpected_eof (jcf, count);
jcf->read_end += count;
return 0;
}
-#if ENABLE_UNZIP
#include "zipfile.h"
struct ZipFileCache *SeenZipFiles = NULL;
-int
-DEFUN(open_in_zip, (jcf,
-zipfile, zipmember),
- JCF *jcf AND const char *zipfile AND const char *zipmember)
+/* Open a zip file with the given name, and cache directory and file
+ descriptor. If the file is missing, treat it as an empty archive.
+ Return NULL if the .zip file is malformed.
+*/
+
+ZipFile *
+DEFUN(opendir_in_zip, (zipfile, is_system),
+ const char *zipfile AND int is_system)
{
struct ZipFileCache* zipf;
- ZipDirectory *zipd;
- int i, len;
- for (zipf = SeenZipFiles; ; zipf = zipf->next)
+ char magic [4];
+ int fd;
+ for (zipf = SeenZipFiles; zipf != NULL; zipf = zipf->next)
{
- if (zipf == NULL)
- {
- char magic [4];
- int fd = open (zipfile, O_RDONLY | O_BINARY);
- if (read (fd, magic, 4) != 4 || GET_u4 (magic) != (JCF_u4)ZIPMAGIC)
- return -1;
- lseek (fd, 0L, SEEK_SET);
- zipf = ALLOC (sizeof (struct ZipFileCache) + strlen (zipfile) + 1);
- zipf->next = SeenZipFiles;
- zipf->name = (char*)(zipf+1);
- strcpy (zipf->name, zipfile);
- SeenZipFiles = zipf;
- zipf->z.fd = fd;
- if (fd == -1)
- {
- /* A missing zip file is not considered an error. */
- zipf->z.count = 0;
- zipf->z.dir_size = 0;
- zipf->z.central_directory = NULL;
- return -1;
- }
- else
- {
- if (read_zip_archive (&zipf->z) != 0)
- return -2; /* This however should be an error - FIXME */
- }
- break;
- }
if (strcmp (zipf->name, zipfile) == 0)
- break;
+ return &zipf->z;
}
+ zipf = ALLOC (sizeof (struct ZipFileCache) + strlen (zipfile) + 1);
+ zipf->next = SeenZipFiles;
+ zipf->name = (char*)(zipf+1);
+ strcpy (zipf->name, zipfile);
+ SeenZipFiles = zipf;
+ fd = open (zipfile, O_RDONLY | O_BINARY);
+ zipf->z.fd = fd;
+ if (fd < 0)
+ {
+ /* A missing zip file is not considered an error.
+ We may want to re-consider that. FIXME. */
+ zipf->z.count = 0;
+ zipf->z.dir_size = 0;
+ zipf->z.central_directory = NULL;
+ }
+ else
+ {
+ jcf_dependency_add_file (zipfile, is_system);
+ if (read (fd, magic, 4) != 4 || GET_u4 (magic) != (JCF_u4)ZIPMAGIC)
+ return NULL;
+ lseek (fd, 0L, SEEK_SET);
+ if (read_zip_archive (&zipf->z) != 0)
+ return NULL;
+ }
+ return &zipf->z;
+}
+
+/* Returns:
+ 0: OK - zipmember found.
+ -1: Not found.
+ -2: Malformed archive.
+*/
+
+int
+DEFUN(open_in_zip, (jcf, zipfile, zipmember, is_system),
+ JCF *jcf AND const char *zipfile AND const char *zipmember
+ AND int is_system)
+{
+ ZipDirectory *zipd;
+ int i, len;
+ ZipFile *zipf = opendir_in_zip (zipfile, is_system);
+
+ if (zipf == NULL)
+ return -2;
+
if (!zipmember)
return 0;
len = strlen (zipmember);
- zipd = (struct ZipDirectory*) zipf->z.central_directory;
- for (i = 0; i < zipf->z.count; i++, zipd = ZIPDIR_NEXT (zipd))
+ zipd = (struct ZipDirectory*) zipf->central_directory;
+ for (i = 0; i < zipf->count; i++, zipd = ZIPDIR_NEXT (zipd))
{
if (len == zipd->filename_length &&
strncmp (ZIPDIR_FILENAME (zipd), zipmember, len) == 0)
@@ -156,23 +172,24 @@ zipfile, zipmember),
jcf->filename = strdup (zipfile);
jcf->classname = strdup (zipmember);
jcf->zipd = (void *)zipd;
- if (lseek (zipf->z.fd, zipd->filestart, 0) < 0
- || read (zipf->z.fd, jcf->buffer, zipd->size) != zipd->size)
+ if (lseek (zipf->fd, zipd->filestart, 0) < 0
+ || read (zipf->fd, jcf->buffer, zipd->size) != zipd->size)
return -2;
return 0;
}
}
return -1;
}
-#endif /* ENABLE_UNZIP */
#if JCF_USE_STDIO
char*
-DEFUN(open_class, (filename, jcf, stream),
- char *filename AND JCF *jcf AND FILE* stream)
+DEFUN(open_class, (filename, jcf, stream, dep_name),
+ char *filename AND JCF *jcf AND FILE* stream AND const char *dep_name)
{
if (jcf)
{
+ if (dep_name != NULL)
+ jcf_dependency_add_file (dep_name, 0);
JCF_ZERO (jcf);
jcf->buffer = NULL;
jcf->buffer_end = NULL;
@@ -187,8 +204,8 @@ DEFUN(open_class, (filename, jcf, stream),
}
#else
char*
-DEFUN(open_class, (filename, jcf, fd),
- char *filename AND JCF *jcf AND int fd)
+DEFUN(open_class, (filename, jcf, fd, dep_name),
+ char *filename AND JCF *jcf AND int fd AND const char *dep_name)
{
if (jcf)
{
@@ -199,6 +216,8 @@ DEFUN(open_class, (filename, jcf, fd),
perror ("Could not figure length of .class file");
return NULL;
}
+ if (dep_name != NULL)
+ jcf_dependency_add_file (dep_name, 0);
JCF_ZERO (jcf);
jcf->buffer = ALLOC (stat_buf.st_size);
jcf->buffer_end = jcf->buffer + stat_buf.st_size;
@@ -222,32 +241,30 @@ DEFUN(open_class, (filename, jcf, fd),
char *
-DEFUN(find_classfile, (filename, jcf),
- char *filename AND JCF *jcf)
+DEFUN(find_classfile, (filename, jcf, dep_name),
+ char *filename AND JCF *jcf AND const char *dep_name)
{
#if JCF_USE_STDIO
FILE *stream = fopen (filename, "rb");
if (stream == NULL)
return NULL;
- return open_class (arg, jcf, stream);
+ return open_class (arg, jcf, stream, dep_name);
#else
int fd = open (filename, O_RDONLY | O_BINARY);
if (fd < 0)
return NULL;
- return open_class (filename, jcf, fd);
+ return open_class (filename, jcf, fd, dep_name);
#endif
}
/* Returns a freshly malloc'd string with the fully qualified pathname
of the .class file for the class CLASSNAME. Returns NULL on
- failure. If JCF != NULL, it is suitably initialized. With
- DO_CLASS_FILE set to 1, search a .class/.java file named after
- CLASSNAME, otherwise, search a ZIP directory entry named after
- CLASSNAME. */
+ failure. If JCF != NULL, it is suitably initialized.
+ SOURCE_OK is true if we should also look for .java file. */
char *
-DEFUN(find_class, (classname, classname_length, jcf, do_class_file),
- const char *classname AND int classname_length AND JCF *jcf AND int do_class_file)
+DEFUN(find_class, (classname, classname_length, jcf, source_ok),
+ const char *classname AND int classname_length AND JCF *jcf AND int source_ok)
{
#if JCF_USE_STDIO
@@ -255,62 +272,61 @@ DEFUN(find_class, (classname, classname_length, jcf, do_class_file),
#else
int fd;
#endif
- int i, j, k, java, class;
+ int i, k, java = -1, class = -1;
struct stat java_buf, class_buf;
+ char *dep_file;
+ void *entry;
+ char *java_buffer;
/* Allocate and zero out the buffer, since we don't explicitly put a
null pointer when we're copying it below. */
- int buflen = strlen (classpath) + classname_length + 10;
+ int buflen = jcf_path_max_len () + classname_length + 10;
char *buffer = (char *) ALLOC (buflen);
bzero (buffer, buflen);
+ java_buffer = (char *) alloca (buflen);
+
jcf->java_source = jcf->outofsynch = 0;
- for (j = 0; classpath[j] != '\0'; )
+
+ for (entry = jcf_path_start (); entry != NULL; entry = jcf_path_next (entry))
{
- for (i = 0; classpath[j] != ':' && classpath[j] != '\0'; i++, j++)
- buffer[i] = classpath[j];
- if (classpath[j] == ':')
- j++;
- if (i > 0) /* Empty directory is redundant */
+ char *path_name = jcf_path_name (entry);
+ if (class != 0)
{
int dir_len;
- if (buffer[i-1] != '/')
- buffer[i++] = '/';
- dir_len = i-1;
+
+ strcpy (buffer, path_name);
+ i = strlen (buffer);
+
+ /* This is right because we know that `.zip' entries will have a
+ trailing slash. See jcf-path.c. */
+ dir_len = i - 1;
+
for (k = 0; k < classname_length; k++, i++)
{
char ch = classname[k];
buffer[i] = ch == '.' ? '/' : ch;
}
- if (do_class_file)
- strcpy (buffer+i, ".class");
-#if ENABLE_UNZIP
- if (dir_len > 4
- && buffer[dir_len-4] == '.' && buffer[dir_len-3] == 'z'
- && buffer[dir_len-2] == 'i' && buffer[dir_len-1] == 'p')
+ strcpy (buffer+i, ".class");
+
+ if (jcf_path_is_zipfile (entry))
{
int err_code;
JCF _jcf;
- if (!do_class_file)
- strcpy (buffer+i, "/");
buffer[dir_len] = '\0';
- if (do_class_file)
- SOURCE_FRONTEND_DEBUG
- (("Trying [...%s]:%s",
- &buffer[dir_len-(dir_len > 15 ? 15 : dir_len)],
- buffer+dir_len+1));
+ SOURCE_FRONTEND_DEBUG
+ (("Trying [...%s]:%s",
+ &buffer[dir_len-(dir_len > 15 ? 15 : dir_len)],
+ buffer+dir_len+1));
if (jcf == NULL)
jcf = &_jcf;
- err_code = open_in_zip (jcf, buffer, buffer+dir_len+1);
+ err_code = open_in_zip (jcf, buffer, buffer+dir_len+1,
+ jcf_path_is_system (entry));
if (err_code == 0)
{
- if (!do_class_file)
- jcf->seen_in_zip = 1;
- else
- {
- buffer[dir_len] = '(';
- strcpy (buffer+i, ".class)");
- }
+ /* Should we check if .zip is out-of-date wrt .java? */
+ buffer[dir_len] = '(';
+ strcpy (buffer+i, ".class)");
if (jcf == &_jcf)
JCF_FINISH (jcf);
return buffer;
@@ -318,72 +334,73 @@ DEFUN(find_class, (classname, classname_length, jcf, do_class_file),
else
continue;
}
-#endif
- /* If we do directories, do them here */
- if (!do_class_file)
- {
- struct stat dir_buff;
- int dir;
- buffer[i] = '\0'; /* Was previously unterminated here. */
- if (!(dir = stat (buffer, &dir_buff)))
- {
- jcf->seen_in_zip = 0;
- goto found;
- }
- }
-
- /* Check for out of synch .class/.java files */
class = stat (buffer, &class_buf);
- strcpy (buffer+i, ".java");
- java = stat (buffer, &java_buf);
- if ((!java && !class) && java_buf.st_mtime >= class_buf.st_mtime)
- jcf->outofsynch = 1;
+ }
+
+ if (source_ok)
+ {
+ /* Compute name of .java file. */
+ int l, m;
+ strcpy (java_buffer, path_name);
+ l = strlen (java_buffer);
+ for (m = 0; m < classname_length; ++m)
+ java_buffer[m + l] = (classname[m] == '.' ? '/' : classname[m]);
+ strcpy (java_buffer + m + l, ".java");
+ java = stat (java_buffer, &java_buf);
+ if (java == 0)
+ break;
+ }
+ }
+
+ if (! java && ! class && java_buf.st_mtime >= class_buf.st_mtime)
+ jcf->outofsynch = 1;
+
+ if (! java)
+ dep_file = java_buffer;
+ else
+ dep_file = buffer;
#if JCF_USE_STDIO
- if (!class)
- {
- strcpy (buffer+i, ".class");
- SOURCE_FRONTEND_DEBUG (("Trying %s", buffer));
- stream = fopen (buffer, "rb");
- if (stream)
- goto found;
- }
- /* Give .java a try, if necessary */
- if (!java)
- {
- strcpy (buffer+i, ".java");
- SOURCE_FRONTEND_DEBUG (("Trying %s", buffer));
- stream = fopen (buffer, "r");
- if (stream)
- {
- jcf->java_source = 1;
- goto found;
- }
- }
+ if (!class)
+ {
+ SOURCE_FRONTEND_DEBUG (("Trying %s", buffer));
+ stream = fopen (buffer, "rb");
+ if (stream)
+ goto found;
+ }
+ /* Give .java a try, if necessary */
+ if (!java)
+ {
+ strcpy (buffer, java_buffer);
+ SOURCE_FRONTEND_DEBUG (("Trying %s", buffer));
+ stream = fopen (buffer, "r");
+ if (stream)
+ {
+ jcf->java_source = 1;
+ goto found;
+ }
+ }
#else
- if (!class)
- {
- strcpy (buffer+i, ".class");
- SOURCE_FRONTEND_DEBUG (("Trying %s", buffer));
- fd = open (buffer, O_RDONLY | O_BINARY);
- if (fd >= 0)
- goto found;
- }
- /* Give .java a try, if necessary */
- if (!java)
- {
- if (do_class_file)
- strcpy (buffer+i, ".java");
- SOURCE_FRONTEND_DEBUG (("Trying %s", buffer));
- fd = open (buffer, O_RDONLY | O_BINARY);
- if (fd >= 0)
- {
- jcf->java_source = 1;
- goto found;
- }
- }
-#endif
+ if (!class)
+ {
+ SOURCE_FRONTEND_DEBUG (("Trying %s", buffer));
+ fd = open (buffer, O_RDONLY | O_BINARY);
+ if (fd >= 0)
+ goto found;
+ }
+ /* Give .java a try, if necessary */
+ if (!java)
+ {
+ strcpy (buffer, java_buffer);
+ SOURCE_FRONTEND_DEBUG (("Trying %s", buffer));
+ fd = open (buffer, O_RDONLY);
+ if (fd >= 0)
+ {
+ jcf->java_source = 1;
+ goto found;
}
}
+#endif
+
free (buffer);
return NULL;
found:
@@ -391,7 +408,7 @@ DEFUN(find_class, (classname, classname_length, jcf, do_class_file),
if (jcf->java_source)
return NULL; /* FIXME */
else
- return open_class (buffer, jcf, stream);
+ return open_class (buffer, jcf, stream, dep_file);
#else
if (jcf->java_source)
{
@@ -400,8 +417,8 @@ DEFUN(find_class, (classname, classname_length, jcf, do_class_file),
jcf->filename = (char *) strdup (buffer);
close (fd); /* We use STDIO for source file */
}
- else if (do_class_file)
- buffer = open_class (buffer, jcf, fd);
+ else
+ buffer = open_class (buffer, jcf, fd, dep_file);
jcf->classname = (char *) ALLOC (classname_length + 1);
strncpy (jcf->classname, classname, classname_length + 1);
jcf->classname = (char *) strdup (classname);
@@ -443,9 +460,9 @@ DEFUN(jcf_print_char, (stream, ch),
void
DEFUN(jcf_print_utf8, (stream, str, length),
- FILE *stream AND register unsigned char *str AND int length)
+ FILE *stream AND register const unsigned char *str AND int length)
{
- unsigned char* limit = str + length;
+ const unsigned char * limit = str + length;
while (str < limit)
{
int ch = UTF8_GET (str, limit);
@@ -462,7 +479,7 @@ DEFUN(jcf_print_utf8, (stream, str, length),
void
DEFUN(jcf_print_utf8_replace, (stream, str, length, in_char, out_char),
- FILE *stream AND unsigned char *str AND int length
+ FILE *stream AND const unsigned char *str AND int length
AND int in_char AND int out_char)
{
diff --git a/gcc/java/jcf-parse.c b/gcc/java/jcf-parse.c
index cdcbcedd8e1..58dd7223fac 100644
--- a/gcc/java/jcf-parse.c
+++ b/gcc/java/jcf-parse.c
@@ -1,5 +1,5 @@
/* Parser for Java(TM) .class files.
- Copyright (C) 1996 Free Software Foundation, Inc.
+ Copyright (C) 1996, 1998, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -32,6 +32,8 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */
#include "java-except.h"
#include "input.h"
#include "java-tree.h"
+#include "toplev.h"
+#include "parse.h"
/* A CONSTANT_Utf8 element is converted to an IDENTIFIER_NODE at parse time. */
#define JPOOL_UTF(JCF, INDEX) CPOOL_UTF(&(JCF)->cpool, INDEX)
@@ -55,34 +57,35 @@ extern struct obstack *saveable_obstack;
extern struct obstack temporary_obstack;
extern struct obstack permanent_obstack;
+/* This is true if the user specified a `.java' file on the command
+ line. Otherwise it is 0. FIXME: this is temporary, until our
+ .java parser is fully working. */
+int saw_java_source = 0;
+
/* The class we are currently processing. */
tree current_class = NULL_TREE;
/* The class we started with. */
tree main_class = NULL_TREE;
-/* The FIELD_DECL for the current field. */
+/* List of all class DECL seen so far. */
+tree all_class_list = NULL_TREE;
+
+/* The FIELD_DECL for the current field. */
static tree current_field = NULL_TREE;
+/* The METHOD_DECL for the current method. */
static tree current_method = NULL_TREE;
+/* Declarations of some functions used here. */
static tree give_name_to_class PROTO ((JCF *jcf, int index));
-
-void parse_zip_file_entries (void);
-void process_zip_dir();
-
-/* Source file compilation declarations */
-static void parse_source_file ();
-extern int java_error_count;
-#define java_parse_abort_on_error() \
- { \
- if (java_error_count) \
- { \
- java_report_errors (); \
- java_pop_parser_context (); \
- return; \
- } \
- }
+static void parse_zip_file_entries PROTO ((void));
+static void process_zip_dir PROTO ((void));
+static void parse_source_file PROTO ((tree));
+static void jcf_parse_source PROTO ((void));
+static int jcf_figure_file_type PROTO ((JCF *));
+static int find_in_current_zip PROTO ((char *, struct JCF **));
+static void parse_class_file PROTO ((void));
/* Handle "SourceFile" attribute. */
@@ -131,7 +134,7 @@ set_source_filename (jcf, index)
#define HANDLE_CONSTANTVALUE(INDEX) \
{ tree constant; int index = INDEX; \
- if (JPOOL_TAG (jcf, index) == CONSTANT_String) { \
+ if (! flag_emit_class_files && JPOOL_TAG (jcf, index) == CONSTANT_String) { \
tree name = get_name_constant (jcf, JPOOL_USHORT1 (jcf, index)); \
constant = build_utf8_ref (name); \
} \
@@ -166,6 +169,18 @@ set_source_filename (jcf, index)
DECL_LINENUMBERS_OFFSET (current_method) = JCF_TELL (jcf) - 2; \
JCF_SKIP (jcf, n * 4); }
+#define HANDLE_EXCEPTIONS_ATTRIBUTE(COUNT) \
+{ \
+ int n = COUNT; \
+ tree list = DECL_FUNCTION_THROWS (current_method); \
+ while (--n >= 0) \
+ { \
+ tree thrown_class = get_class_constant (jcf, JCF_readu2 (jcf)); \
+ list = tree_cons (NULL_TREE, thrown_class, list); \
+ } \
+ DECL_FUNCTION_THROWS (current_method) = nreverse (list); \
+}
+
#include "jcf-reader.c"
static int yydebug;
@@ -270,10 +285,12 @@ get_constant (jcf, index)
#ifdef REAL_ARITHMETIC
d = REAL_VALUE_FROM_TARGET_DOUBLE (num);
#else
- union { double d; jint i[2]; } u;
- u.i[0] = (jint) num[0];
- u.i[1] = (jint) num[1];
- d = u.d;
+ {
+ union { double d; jint i[2]; } u;
+ u.i[0] = (jint) num[0];
+ u.i[1] = (jint) num[1];
+ d = u.d;
+ }
#endif
value = build_real (double_type_node, d);
break;
@@ -302,6 +319,7 @@ get_constant (jcf, index)
}
value = make_node (STRING_CST);
+ TREE_TYPE (value) = build_pointer_type (string_type_node);
TREE_STRING_LENGTH (value) = 2 * str_len;
TREE_STRING_POINTER (value)
= obstack_alloc (expression_obstack, 2 * str_len);
@@ -408,7 +426,7 @@ get_class_constant (JCF *jcf , int i)
char *name = JPOOL_UTF_DATA (jcf, name_index);
int nlength = JPOOL_UTF_LENGTH (jcf, name_index);
if (name[0] == '[') /* Handle array "classes". */
- type = parse_signature_string (name, nlength);
+ type = TREE_TYPE (parse_signature_string (name, nlength));
else
{
tree cname = unmangle_classname (name, nlength);
@@ -423,22 +441,6 @@ get_class_constant (JCF *jcf , int i)
}
void
-fix_classpath ()
-{
- static char default_path[] = DEFAULT_CLASS_PATH;
-
- if (classpath == NULL)
- {
- classpath = (char *) getenv ("CLASSPATH");
- if (classpath == NULL)
- {
- warning ("CLASSPATH not set");
- classpath = default_path;
- }
- }
-}
-
-void
DEFUN(jcf_out_of_synch, (jcf),
JCF *jcf)
{
@@ -454,45 +456,37 @@ DEFUN(jcf_out_of_synch, (jcf),
free (source);
}
-/* Load CLASS_OR_NAME. CLASS_OR_NAME can be a mere identifier if
- called from the parser, otherwise it's a RECORD_TYPE node. If
- VERBOSE is 1, print error message on failure to load a class. */
+/* Read a class with the fully qualified-name NAME.
+ Return 1 iff we read the requested file.
+ (It is still possible we failed if the file did not
+ define the class it is supposed to.) */
-void
-load_class (class_or_name, verbose)
- tree class_or_name;
- int verbose;
+int
+read_class (name)
+ tree name;
{
JCF this_jcf, *jcf;
- tree name = (TREE_CODE (class_or_name) == IDENTIFIER_NODE ?
- class_or_name : DECL_NAME (TYPE_NAME (class_or_name)));
tree save_current_class = current_class;
char *save_input_filename = input_filename;
JCF *save_current_jcf = current_jcf;
- long saved_pos;
+ long saved_pos = 0;
if (current_jcf->read_state)
saved_pos = ftell (current_jcf->read_state);
push_obstacks (&permanent_obstack, &permanent_obstack);
- if (!classpath)
- fix_classpath ();
/* Search in current zip first. */
- if (find_in_current_zip (IDENTIFIER_POINTER (name),
- IDENTIFIER_LENGTH (name), &jcf) == 0)
+ if (find_in_current_zip (IDENTIFIER_POINTER (name), &jcf) == 0)
+ /* FIXME: until the `.java' parser is fully working, we only
+ look for a .java file when one was mentioned on the
+ command line. This lets us test the .java parser fairly
+ easily, without compromising our ability to use the
+ .class parser without fear. */
if (find_class (IDENTIFIER_POINTER (name), IDENTIFIER_LENGTH (name),
- &this_jcf, 1) == 0)
+ &this_jcf, saw_java_source) == 0)
{
- if (verbose)
- {
- error ("Cannot find class file class %s.",
- IDENTIFIER_POINTER (name));
- TYPE_SIZE (class_or_name) = error_mark_node;
- if (!strcmp (classpath, DEFAULT_CLASS_PATH))
- fatal ("giving up");
- pop_obstacks (); /* FIXME: one pop_obstack() per function */
- }
- return;
+ pop_obstacks (); /* FIXME: one pop_obstack() per function */
+ return 0;
}
else
{
@@ -505,17 +499,18 @@ load_class (class_or_name, verbose)
current_jcf = jcf;
if (current_jcf->java_source)
- jcf_parse_source (current_jcf);
+ jcf_parse_source ();
else {
- int saved_lineno = lineno;
+ java_parser_context_save_global ();
+ java_push_parser_context ();
input_filename = current_jcf->filename;
jcf_parse (current_jcf);
- lineno = saved_lineno;
+ java_pop_parser_context (0);
+ java_parser_context_restore_global ();
}
if (!current_jcf->seen_in_zip)
JCF_FINISH (current_jcf);
-/* DECL_IGNORED_P (TYPE_NAME (class_or_name)) = 1;*/
pop_obstacks ();
current_class = save_current_class;
@@ -523,33 +518,77 @@ load_class (class_or_name, verbose)
current_jcf = save_current_jcf;
if (current_jcf->read_state)
fseek (current_jcf->read_state, saved_pos, SEEK_SET);
+ return 1;
}
-/* Parse a source file when JCF refers to a source file. This piece
- needs further work as far as error handling and report. */
+/* Load CLASS_OR_NAME. CLASS_OR_NAME can be a mere identifier if
+ called from the parser, otherwise it's a RECORD_TYPE node. If
+ VERBOSE is 1, print error message on failure to load a class. */
-int
-jcf_parse_source (jcf)
- JCF *jcf;
+/* Replace calls to load_class by having callers call read_class directly
+ - and then perhaps rename read_class to load_class. FIXME */
+
+void
+load_class (class_or_name, verbose)
+ tree class_or_name;
+ int verbose;
{
- java_parser_context_save_global ();
+ tree name;
+
+ /* class_or_name can be the name of the class we want to load */
+ if (TREE_CODE (class_or_name) == IDENTIFIER_NODE)
+ name = class_or_name;
+ /* In some cases, it's a dependency that we process earlier that
+ we though */
+ else if (TREE_CODE (class_or_name) == TREE_LIST)
+ name = TYPE_NAME (TREE_PURPOSE (class_or_name));
+ /* Or it's a type in the making */
+ else
+ name = DECL_NAME (TYPE_NAME (class_or_name));
- input_filename = current_jcf->filename;
- if (!(finput = fopen (input_filename, "r")))
- fatal ("input file `%s' just disappeared - jcf_parse_source",
- input_filename);
+ if (read_class (name) == 0 && verbose)
+ {
+ error ("Cannot find file for class %s.",
+ IDENTIFIER_POINTER (name));
+ if (TREE_CODE (class_or_name) == RECORD_TYPE)
+ TYPE_SIZE (class_or_name) = error_mark_node;
+#if 0
+ /* FIXME: what to do here? */
+ if (!strcmp (classpath, DEFAULT_CLASS_PATH))
+ fatal ("giving up");
+#endif
+ return;
+ }
+}
- parse_source_file (1); /* Parse only */
- if (current_class && TREE_TYPE (current_class))
- CLASS_FROM_SOURCE_P (TREE_TYPE (current_class)) = 1;
+/* Parse a source file when JCF refers to a source file. */
- fclose (finput);
+static void
+jcf_parse_source ()
+{
+ tree file;
+
+ java_parser_context_save_global ();
+ java_push_parser_context ();
+ input_filename = current_jcf->filename;
+ file = get_identifier (input_filename);
+ if (!HAS_BEEN_ALREADY_PARSED_P (file))
+ {
+ if (!(finput = fopen (input_filename, "r")))
+ fatal ("input file `%s' just disappeared - jcf_parse_source",
+ input_filename);
+ parse_source_file (file);
+ if (fclose (finput))
+ fatal ("can't close input file `%s' stream - jcf_parse_source",
+ input_filename);
+ }
+ java_pop_parser_context (IS_A_COMMAND_LINE_FILENAME_P (file));
java_parser_context_restore_global ();
}
/* Parse the .class file JCF. */
-int
+void
jcf_parse (jcf)
JCF* jcf;
{
@@ -570,6 +609,8 @@ jcf_parse (jcf)
if (! quiet_flag && TYPE_NAME (current_class))
fprintf (stderr, " class %s",
IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (current_class))));
+ if (CLASS_LOADED_P (current_class))
+ return;
CLASS_LOADED_P (current_class) = 1;
for (i = 1; i < JPOOL_SIZE(jcf); i++)
@@ -598,6 +639,11 @@ jcf_parse (jcf)
push_obstacks (&permanent_obstack, &permanent_obstack);
layout_class (current_class);
+ if (current_class == object_type_node)
+ layout_class_methods (object_type_node);
+ else
+ all_class_list = tree_cons (NULL_TREE,
+ TYPE_NAME (current_class), all_class_list );
pop_obstacks ();
}
@@ -617,13 +663,15 @@ init_outgoing_cpool ()
}
}
-void
+static void
parse_class_file ()
{
tree method;
char *save_input_filename = input_filename;
int save_lineno = lineno;
+ java_layout_seen_class_methods ();
+
input_filename = DECL_SOURCE_FILE (TYPE_NAME (current_class));
lineno = 0;
debug_start_source_file (input_filename);
@@ -679,83 +727,135 @@ parse_class_file ()
if (flag_emit_class_files)
write_classfile (current_class);
- make_class_data (current_class);
- register_class ();
- rest_of_decl_compilation (TYPE_NAME (current_class), (char*) 0, 1, 0);
+
+ finish_class (current_class);
debug_end_source_file (save_lineno);
input_filename = save_input_filename;
lineno = save_lineno;
}
-/* Parse a source file, as pointed by the current JCF. If PARSE_ONLY
- is non zero, we're not parsing a file found on the command line and
- we skip things related to code generation. */
+/* Parse a source file, as pointed by the current value of INPUT_FILENAME. */
static void
-parse_source_file (parse_only)
- int parse_only;
+parse_source_file (file)
+ tree file;
{
+ int save_error_count = java_error_count;
+ /* Mark the file as parsed */
+ HAS_BEEN_ALREADY_PARSED_P (file) = 1;
+
lang_init_source (1); /* Error msgs have no method prototypes */
- java_push_parser_context ();
+
java_init_lex (); /* Initialize the parser */
java_parse_abort_on_error ();
+
java_parse (); /* Parse and build partial tree nodes. */
java_parse_abort_on_error ();
java_complete_class (); /* Parse unsatisfied class decl. */
java_parse_abort_on_error ();
java_check_circular_reference (); /* Check on circular references */
java_parse_abort_on_error ();
- java_check_methods (); /* Check the methods */
- java_parse_abort_on_error ();
- java_layout_classes ();
- java_parse_abort_on_error ();
- if (!parse_only)
- {
- lang_init_source (2); /* Error msgs have method prototypes */
- java_complete_expand_methods (); /* Complete and expand method bodies */
- java_parse_abort_on_error ();
- java_expand_finals (); /* Expand and check the finals */
- java_parse_abort_on_error ();
- java_check_final (); /* Check unitialized final */
- java_parse_abort_on_error ();
- if (! flag_emit_class_files)
- emit_register_class ();
- java_report_errors (); /* Final step for this file */
- }
- if (flag_emit_class_files)
- write_classfile (current_class);
- java_pop_parser_context ();
}
int
yyparse ()
{
- /* Everything migh be enclosed within a loop processing each file after
- the other one. */
+ int several_files = 0;
+ char *list = strdup (input_filename), *next;
+ tree node, current_file_list = NULL_TREE;
- switch (jcf_figure_file_type (current_jcf))
+ do
{
- case JCF_ZIP:
- parse_zip_file_entries ();
- emit_register_class ();
- break;
- case JCF_CLASS:
- jcf_parse (current_jcf);
- parse_class_file ();
- emit_register_class ();
- break;
- case JCF_SOURCE:
- parse_source_file (0); /* Parse and generate */
- break;
+ next = strchr (list, '&');
+ if (next)
+ {
+ *next++ = '\0';
+ several_files = 1;
+ }
+
+ if (list[0])
+ {
+ char *value;
+
+ int len = strlen (list);
+ /* FIXME: this test is only needed until our .java parser is
+ fully capable. */
+ if (len > 5 && ! strcmp (&list[len - 5], ".java"))
+ saw_java_source = 1;
+
+ if (*list != '/' && several_files)
+ obstack_grow (&temporary_obstack, "./", 2);
+
+ obstack_grow0 (&temporary_obstack, list, len);
+ value = obstack_finish (&temporary_obstack);
+ node = get_identifier (value);
+ IS_A_COMMAND_LINE_FILENAME_P (node) = 1;
+ current_file_list = tree_cons (NULL_TREE, node, current_file_list);
+ }
+ list = next;
}
+ while (next);
+
+ current_jcf = main_jcf;
+ current_file_list = nreverse (current_file_list);
+ for (node = current_file_list; node; node = TREE_CHAIN (node))
+ {
+ tree name = TREE_VALUE (node);
+
+ /* Skip already parsed files */
+ if (HAS_BEEN_ALREADY_PARSED_P (name))
+ continue;
+
+ /* Close previous descriptor, if any */
+ if (main_jcf->read_state && fclose (main_jcf->read_state))
+ fatal ("failed to close input file `%s' - yyparse",
+ (main_jcf->filename ? main_jcf->filename : "<unknown>"));
+
+ /* Set jcf up and open a new file */
+ JCF_ZERO (main_jcf);
+ main_jcf->read_state = fopen (IDENTIFIER_POINTER (name), "rb");
+ if (main_jcf->read_state == NULL)
+ pfatal_with_name (IDENTIFIER_POINTER (name));
+
+ /* Set new input_filename and finput */
+ finput = main_jcf->read_state;
+#ifdef IO_BUFFER_SIZE
+ setvbuf (finput, (char *) xmalloc (IO_BUFFER_SIZE),
+ _IOFBF, IO_BUFFER_SIZE);
+#endif
+ input_filename = IDENTIFIER_POINTER (name);
+ main_jcf->filbuf = jcf_filbuf_from_stdio;
+
+ switch (jcf_figure_file_type (current_jcf))
+ {
+ case JCF_ZIP:
+ parse_zip_file_entries ();
+ break;
+ case JCF_CLASS:
+ jcf_parse (current_jcf);
+ parse_class_file ();
+ break;
+ case JCF_SOURCE:
+ java_push_parser_context ();
+ java_parser_context_save_global ();
+ parse_source_file (name);
+ java_parser_context_restore_global ();
+ java_pop_parser_context (1);
+ break;
+ }
+ }
+
+ java_expand_classes ();
+ if (!java_report_errors () && !flag_syntax_only)
+ emit_register_classes ();
return 0;
}
static struct ZipFileCache *localToFile;
/* Process all class entries found in the zip file. */
-void
+static void
parse_zip_file_entries (void)
{
struct ZipDirectory *zdir;
@@ -780,21 +880,23 @@ parse_zip_file_entries (void)
jcf_parse (current_jcf);
}
- input_filename = current_jcf->filename;
-
- parse_class_file ();
- FREE (current_jcf->buffer); /* No longer necessary */
- /* Note: there is a way to free this buffer right after a class seen
- in a zip file has been parsed. The idea is the set its jcf in such
- a way that buffer will be reallocated the time the code for the class
- will be generated. FIXME. */
+ if (TYPE_SIZE (current_class) != error_mark_node)
+ {
+ input_filename = current_jcf->filename;
+ parse_class_file ();
+ FREE (current_jcf->buffer); /* No longer necessary */
+ /* Note: there is a way to free this buffer right after a
+ class seen in a zip file has been parsed. The idea is the
+ set its jcf in such a way that buffer will be reallocated
+ the time the code for the class will be generated. FIXME. */
+ }
}
}
/* Read all the entries of the zip file, creates a class and a JCF. Sets the
jcf up for further processing and link it to the created class. */
-void process_zip_dir()
+static void process_zip_dir()
{
int i;
ZipDirectory *zdir;
@@ -854,9 +956,9 @@ void process_zip_dir()
/* Lookup class NAME and figure whether is a class already found in the current
zip file. */
-int
+static int
DEFUN(find_in_current_zip, (name, length, jcf),
- char *name AND int length AND JCF **jcf)
+ char *name AND JCF **jcf)
{
JCF *local_jcf;
tree class_name = maybe_get_identifier (name), class, icv;
@@ -879,7 +981,7 @@ DEFUN(find_in_current_zip, (name, length, jcf),
}
/* Figure what kind of file we're dealing with */
-int
+static int
DEFUN(jcf_figure_file_type, (jcf),
JCF *jcf)
{
@@ -895,7 +997,9 @@ DEFUN(jcf_figure_file_type, (jcf),
if (magic == 0xcafebabe)
return JCF_CLASS;
- if (!open_in_zip (jcf, input_filename, NULL))
+ /* FIXME: is it a system file? */
+ if (magic == (JCF_u4)ZIPMAGIC
+ && !open_in_zip (jcf, input_filename, NULL, 0))
{
localToFile = ALLOC (sizeof (struct ZipFileCache));
bcopy (SeenZipFiles, localToFile, sizeof (struct ZipFileCache));
diff --git a/gcc/java/jcf-reader.c b/gcc/java/jcf-reader.c
index cf5c0427789..accb1a11706 100644
--- a/gcc/java/jcf-reader.c
+++ b/gcc/java/jcf-reader.c
@@ -72,8 +72,8 @@ DEFUN(get_attribute, (jcf),
if (name_length == 4 && memcmp (name_data, "Code", 4) == 0)
{
uint16 j;
- uint16 max_stack = JCF_readu2 (jcf);
- uint16 max_locals = JCF_readu2 (jcf);
+ uint16 max_stack ATTRIBUTE_UNUSED = JCF_readu2 (jcf);
+ uint16 max_locals ATTRIBUTE_UNUSED = JCF_readu2 (jcf);
uint32 code_length = JCF_readu4 (jcf);
uint16 exception_table_length, attributes_count;
if (code_length + 12 > attribute_length)
@@ -83,6 +83,9 @@ DEFUN(get_attribute, (jcf),
exception_table_length = JCF_readu2 (jcf);
if (code_length + 8 * exception_table_length + 12 > attribute_length)
return -1;
+#ifdef HANDLE_EXCEPTION_TABLE
+ HANDLE_EXCEPTION_TABLE (jcf->read_ptr, exception_table_length);
+#endif
JCF_SKIP (jcf, 2 * 4 * exception_table_length);
attributes_count = JCF_readu2 (jcf);
for (j = 0; j < attributes_count; j++)
@@ -136,8 +139,8 @@ DEFUN(jcf_parse_preamble, (jcf),
JCF* jcf)
{
uint32 magic = (JCF_FILL (jcf, 8), JCF_readu4 (jcf));
- uint16 minor_version = JCF_readu2 (jcf);
- uint16 major_version = JCF_readu2 (jcf);
+ uint16 minor_version ATTRIBUTE_UNUSED = JCF_readu2 (jcf);
+ uint16 major_version ATTRIBUTE_UNUSED = JCF_readu2 (jcf);
#ifdef HANDLE_MAGIC
HANDLE_MAGIC (magic, minor_version, major_version);
#endif
@@ -239,7 +242,7 @@ DEFUN(jcf_parse_class, (jcf),
/* Read interfaces. */
for (i = 0; i < interfaces_count; i++)
{
- uint16 index = JCF_readu2 (jcf);
+ uint16 index ATTRIBUTE_UNUSED = JCF_readu2 (jcf);
#ifdef HANDLE_CLASS_INTERFACE
HANDLE_CLASS_INTERFACE (index);
#endif
@@ -305,6 +308,9 @@ DEFUN(jcf_parse_one_method, (jcf),
if (code != 0)
return code;
}
+#ifdef HANDLE_END_METHOD
+ HANDLE_END_METHOD ();
+#endif
return 0;
}
diff --git a/gcc/java/jcf-write.c b/gcc/java/jcf-write.c
index af663017bfd..71560e60616 100644
--- a/gcc/java/jcf-write.c
+++ b/gcc/java/jcf-write.c
@@ -1,5 +1,5 @@
/* Write out a Java(TM) class file.
- Copyright (C) 1998 Free Software Foundation, Inc.
+ Copyright (C) 1998, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -23,62 +23,63 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */
#include "config.h"
#include "system.h"
+#include "jcf.h"
#include "tree.h"
#include "java-tree.h"
-#include "jcf.h"
#include "obstack.h"
#undef AND
#include "rtl.h"
+#include "flags.h"
#include "java-opcodes.h"
#include "parse.h" /* for BLOCK_EXPR_BODY */
#include "buffer.h"
+#include "toplev.h"
-extern struct obstack temporary_obstack;
+#ifndef DIR_SEPARATOR
+#define DIR_SEPARATOR '/'
+#endif
-/* The buffer allocated for bytecode for the current method. */
+extern struct obstack temporary_obstack;
-struct buffer bytecode = NULL_BUFFER;
+/* Base directory in which `.class' files should be written.
+ NULL means to put the file into the same directory as the
+ corresponding .java file. */
+char *jcf_write_base_directory = NULL;
/* Make sure bytecode.data is big enough for at least N more bytes. */
#define RESERVE(N) \
- do { if (bytecode.ptr + (N) > bytecode.limit) buffer_grow (&bytecode, N); } while (0)
+ do { CHECK_OP(state); \
+ if (state->bytecode.ptr + (N) > state->bytecode.limit) \
+ buffer_grow (&state->bytecode, N); } while (0)
/* Add a 1-byte instruction/operand I to bytecode.data,
assuming space has already been RESERVE'd. */
-#define OP1(I) (*bytecode.ptr++ = (I))
+#define OP1(I) (*state->bytecode.ptr++ = (I), CHECK_OP(state))
/* Like OP1, but I is a 2-byte big endian integer. */
#define OP2(I) \
- do { int _i = (I); OP1 (_i >> 8); OP1 (_i); } while (0)
+ do { int _i = (I); OP1 (_i >> 8); OP1 (_i); CHECK_OP(state); } while (0)
/* Like OP1, but I is a 4-byte big endian integer. */
#define OP4(I) \
do { int _i = (I); OP1 (_i >> 24); OP1 (_i >> 16); \
- OP1 (_i >> 8); OP1 (_i); } while (0)
-
-/* The current stack size (stack pointer) in the current method. */
-
-int code_SP = 0;
-
-/* The largest extent of stack size (stack pointer) in the current method. */
-
-int code_SP_max = 0;
-
-CPool *code_cpool;
+ OP1 (_i >> 8); OP1 (_i); CHECK_OP(state); } while (0)
/* Macro to call each time we push I words on the JVM stack. */
#define NOTE_PUSH(I) \
- do { code_SP += (I); if (code_SP > code_SP_max) code_SP_max = code_SP; } while (0)
+ do { state->code_SP += (I); \
+ if (state->code_SP > state->code_SP_max) \
+ state->code_SP_max = state->code_SP; } while (0)
/* Macro to call each time we pop I words from the JVM stack. */
#define NOTE_POP(I) \
- do { code_SP -= (I); if (code_SP < 0) abort(); } while (0)
+ do { state->code_SP -= (I); if (state->code_SP < 0) abort(); } while (0)
/* A chunk or segment of a .class file. */
@@ -94,176 +95,510 @@ struct chunk
int size;
};
+#define PENDING_CLEANUP_PC (-3)
+#define PENDING_EXIT_PC (-2)
+#define UNDEFINED_PC (-1)
+
+/* Each "block" represents a label plus the bytecode instructions following.
+ There may be branches out of the block, but no incoming jumps, except
+ to the beginning of the block.
+
+ If (pc < 0), the jcf_block is not an actual block (i.e. it has no
+ assocated code yet), but it is an undefined label.
+*/
+
+struct jcf_block
+{
+ /* For blocks that that are defined, the next block (in pc order).
+ For blocks that are the not-yet-defined end label of a LABELED_BLOCK_EXPR
+ or a cleanup expression (from a WITH_CLEANUP_EXPR),
+ this is the next (outer) such end label, in a stack headed by
+ labeled_blocks in jcf_partial. */
+ struct jcf_block *next;
+
+ /* In the not-yet-defined end label for an unfinished EXIT_BLOCK_EXPR.
+ pc is PENDING_EXIT_PC.
+ In the not-yet-defined end label for pending cleanup subroutine,
+ pc is PENDING_CLEANUP_PC.
+ For other not-yet-defined labels, pc is UNDEFINED_PC.
+
+ If the label has been defined:
+ Until perform_relocations is finished, this is the maximum possible
+ value of the bytecode offset at the begnning of this block.
+ After perform_relocations, it is the actual offset (pc). */
+ int pc;
+
+ int linenumber;
+
+ /* After finish_jcf_block is called, The actual instructions contained in this block.
+ Before than NULL, and the instructions are in state->bytecode. */
+ union {
+ struct chunk *chunk;
+
+ /* If pc==PENDING_CLEANUP_PC, start_label is the start of the region
+ coveed by the cleanup. */
+ struct jcf_block *start_label;
+ } v;
+
+ union {
+ /* Set of relocations (in reverse offset order) for this block. */
+ struct jcf_relocation *relocations;
+
+ /* If this block is that of the not-yet-defined end label of
+ a LABELED_BLOCK_EXPR, where LABELED_BLOCK is that LABELED_BLOCK_EXPR.
+ If pc==PENDING_CLEANUP_PC, the cleanup that needs to be run. */
+ tree labeled_block;
+ } u;
+};
+
+/* A "relocation" type for the 0-3 bytes of padding at the start
+ of a tableswitch or a lookupswitch. */
+#define SWITCH_ALIGN_RELOC 4
+
+/* A relocation type for the labels in a tableswitch or a lookupswitch;
+ these are relative to the start of the instruction, but (due to
+ th 0-3 bytes of padding), we don't know the offset before relocation. */
+#define BLOCK_START_RELOC 1
+
+struct jcf_relocation
+{
+ /* Next relocation for the current jcf_block. */
+ struct jcf_relocation *next;
+
+ /* The (byte) offset within the current block that needs to be relocated. */
+ HOST_WIDE_INT offset;
+
+ /* 0 if offset is a 4-byte relative offset.
+ 4 (SWITCH_ALIGN_RELOC) if offset points to 0-3 padding bytes inserted
+ for proper alignment in tableswitch/lookupswitch instructions.
+ 1 (BLOCK_START_RELOC) if offset points to a 4-byte offset relative
+ to the start of the containing block.
+ -1 if offset is a 2-byte relative offset.
+ < -1 if offset is the address of an instruction with a 2-byte offset
+ that does not have a corresponding 4-byte offset version, in which
+ case the absolute value of kind is the inverted opcode.
+ > 4 if offset is the address of an instruction (such as jsr) with a
+ 2-byte offset that does have a corresponding 4-byte offset version,
+ in which case kind is the opcode of the 4-byte version (such as jsr_w). */
+ int kind;
+
+ /* The label the relocation wants to actually transfer to. */
+ struct jcf_block *label;
+};
+
+/* State for single catch clause. */
+
+struct jcf_handler
+{
+ struct jcf_handler *next;
+
+ struct jcf_block *start_label;
+ struct jcf_block *end_label;
+ struct jcf_block *handler_label;
+
+ /* The sub-class of Throwable handled, or NULL_TREE (for finally). */
+ tree type;
+};
+
+/* State for the current switch statement. */
+
+struct jcf_switch_state
+{
+ struct jcf_switch_state *prev;
+ struct jcf_block *default_label;
+
+ struct jcf_relocation *cases;
+ int num_cases;
+ HOST_WIDE_INT min_case, max_case;
+};
+
+/* This structure is used to contain the various pieces that will
+ become a .class file. */
+
+struct jcf_partial
+{
+ struct chunk *first;
+ struct chunk *chunk;
+ struct obstack *chunk_obstack;
+ tree current_method;
+
+ /* List of basic blocks for the current method. */
+ struct jcf_block *blocks;
+ struct jcf_block *last_block;
+
+ struct localvar_info *first_lvar;
+ struct localvar_info *last_lvar;
+ int lvar_count;
+
+ CPool cpool;
+
+ int linenumber_count;
+
+ /* Until perform_relocations, this is a upper bound on the number
+ of bytes (so far) in the instructions for the current method. */
+ int code_length;
+
+ /* Stack of undefined ending labels for LABELED_BLOCK_EXPR. */
+ struct jcf_block *labeled_blocks;
+
+ /* The current stack size (stack pointer) in the current method. */
+ int code_SP;
+
+ /* The largest extent of stack size (stack pointer) in the current method. */
+ int code_SP_max;
+
+ /* Contains a mapping from local var slot number to localvar_info. */
+ struct buffer localvars;
+
+ /* The buffer allocated for bytecode for the current jcf_block. */
+ struct buffer bytecode;
+
+ /* Chain of exception handlers for the current method. */
+ struct jcf_handler *handlers;
+
+ /* Last element in handlers chain. */
+ struct jcf_handler *last_handler;
+
+ /* Number of exception handlers for the current method. */
+ int num_handlers;
+
+ /* Number of finalizers we are currently nested within. */
+ int num_finalizers;
+
+ /* If non-NULL, use this for the return value. */
+ tree return_value_decl;
+
+ /* Information about the current switch statemenet. */
+ struct jcf_switch_state *sw_state;
+};
+
+static void generate_bytecode_insns PROTO ((tree, int, struct jcf_partial *));
+static struct chunk * alloc_chunk PROTO ((struct chunk *, unsigned char *,
+ int, struct obstack *));
+static unsigned char * append_chunk PROTO ((unsigned char *, int,
+ struct jcf_partial *));
+static void append_chunk_copy PROTO ((unsigned char *, int,
+ struct jcf_partial *));
+static struct jcf_block * gen_jcf_label PROTO ((struct jcf_partial *));
+static void finish_jcf_block PROTO ((struct jcf_partial *));
+static void define_jcf_label PROTO ((struct jcf_block *,
+ struct jcf_partial *));
+static struct jcf_block * get_jcf_label_here PROTO ((struct jcf_partial *));
+static void put_linenumber PROTO ((int, struct jcf_partial *));
+static void localvar_alloc PROTO ((tree, struct jcf_partial *));
+static int localvar_free PROTO ((tree, struct jcf_partial *));
+static int get_access_flags PROTO ((tree));
+static void write_chunks PROTO ((FILE *, struct chunk *));
+static int adjust_typed_op PROTO ((tree, int));
+static void generate_bytecode_conditional PROTO ((tree, struct jcf_block *,
+ struct jcf_block *, int,
+ struct jcf_partial *));
+static void generate_bytecode_return PROTO ((tree, struct jcf_partial *));
+static void perform_relocations PROTO ((struct jcf_partial *));
+static void init_jcf_state PROTO ((struct jcf_partial *, struct obstack *));
+static void init_jcf_method PROTO ((struct jcf_partial *, tree));
+static void release_jcf_state PROTO ((struct jcf_partial *));
+static struct chunk * generate_classfile PROTO ((tree, struct jcf_partial *));
+
+
/* Utility macros for appending (big-endian) data to a buffer.
We assume a local variable 'ptr' points into where we want to
write next, and we assume enoygh space has been allocated. */
-#define PUT1(X) (*ptr++ = (X))
+#ifdef ENABLE_CHECKING
+int
+CHECK_PUT(ptr, state, i)
+ void *ptr;
+ struct jcf_partial *state;
+ int i;
+{
+ if (ptr < state->chunk->data
+ || (char*)ptr + i > state->chunk->data + state->chunk->size)
+ fatal ("internal error - CHECK_PUT failed");
+ return 0;
+}
+#else
+#define CHECK_PUT(PTR, STATE, I) ((void)0)
+#endif
+
+#define PUT1(X) (CHECK_PUT(ptr, state, 1), *ptr++ = (X))
#define PUT2(X) (PUT1((X) >> 8), PUT1((X) & 0xFF))
#define PUT4(X) (PUT2((X) >> 16), PUT2((X) & 0xFFFF))
-#define PUTN(P, N) (bcopy(P, ptr, N), ptr += (N))
+#define PUTN(P, N) (CHECK_PUT(ptr, state, N), memcpy(ptr, P, N), ptr += (N))
-/* A buffer for storing line number entries for the current method. */
-struct buffer linenumbers = NULL_BUFFER;
+/* Allocate a new chunk on obstack WORK, and link it in after LAST.
+ Set the data and size fields to DATA and SIZE, respectively.
+ However, if DATA is NULL and SIZE>0, allocate a buffer as well. */
+
+static struct chunk *
+alloc_chunk (last, data, size, work)
+ struct chunk *last;
+ unsigned char *data;
+ int size;
+ struct obstack *work;
+{
+ struct chunk *chunk = (struct chunk *)
+ obstack_alloc (work, sizeof(struct chunk));
-/* Append a line number entry for the given PC and LINE into
- linenumbers.data. This will later before a LineNumberTable attribute. */
+ if (data == NULL && size > 0)
+ data = obstack_alloc (work, size);
-void
-put_linenumber (pc, line)
- int pc, line;
+ chunk->next = NULL;
+ chunk->data = data;
+ chunk->size = size;
+ if (last != NULL)
+ last->next = chunk;
+ return chunk;
+}
+
+#ifdef ENABLE_CHECKING
+int
+CHECK_OP(struct jcf_partial *state)
{
- register unsigned char *ptr;
- if (linenumbers.ptr == linenumbers.limit)
- buffer_grow (&linenumbers, 4);
- ptr = linenumbers.ptr;
- PUT2 (pc);
- PUT2 (line);
- linenumbers.ptr = ptr;
+ if (state->bytecode.ptr > state->bytecode.limit)
+ {
+ fatal("internal error - CHECK_OP failed");
+ }
+ return 0;
}
+#else
+#define CHECK_OP(STATE) ((void)0)
+#endif
+
+static unsigned char *
+append_chunk (data, size, state)
+ unsigned char *data;
+ int size;
+ struct jcf_partial *state;
+{
+ state->chunk = alloc_chunk (state->chunk, data, size, state->chunk_obstack);
+ if (state->first == NULL)
+ state->first = state->chunk;
+ return state->chunk->data;
+}
+
+static void
+append_chunk_copy (data, size, state)
+ unsigned char *data;
+ int size;
+ struct jcf_partial *state;
+{
+ unsigned char *ptr = append_chunk (NULL, size, state);
+ memcpy (ptr, data, size);
+}
+
+static struct jcf_block *
+gen_jcf_label (state)
+ struct jcf_partial *state;
+{
+ struct jcf_block *block = (struct jcf_block *)
+ obstack_alloc (state->chunk_obstack, sizeof (struct jcf_block));
+ block->next = NULL;
+ block->linenumber = -1;
+ block->pc = UNDEFINED_PC;
+ return block;
+}
+
+static void
+finish_jcf_block (state)
+ struct jcf_partial *state;
+{
+ struct jcf_block *block = state->last_block;
+ struct jcf_relocation *reloc;
+ int code_length = BUFFER_LENGTH (&state->bytecode);
+ int pc = state->code_length;
+ append_chunk_copy (state->bytecode.data, code_length, state);
+ BUFFER_RESET (&state->bytecode);
+ block->v.chunk = state->chunk;
+
+ /* Calculate code_length to the maximum value it can have. */
+ pc += block->v.chunk->size;
+ for (reloc = block->u.relocations; reloc != NULL; reloc = reloc->next)
+ {
+ int kind = reloc->kind;
+ if (kind == SWITCH_ALIGN_RELOC)
+ pc += 3;
+ else if (kind > BLOCK_START_RELOC)
+ pc += 2; /* 2-byte offset may grow to 4-byte offset */
+ else if (kind < -1)
+ pc += 5; /* May need to add a goto_w. */
+ }
+ state->code_length = pc;
+}
+
+static void
+define_jcf_label (label, state)
+ struct jcf_block *label;
+ struct jcf_partial *state;
+{
+ if (state->last_block != NULL)
+ finish_jcf_block (state);
+ label->pc = state->code_length;
+ if (state->blocks == NULL)
+ state->blocks = label;
+ else
+ state->last_block->next = label;
+ state->last_block = label;
+ label->next = NULL;
+ label->u.relocations = NULL;
+}
+
+static struct jcf_block *
+get_jcf_label_here (state)
+ struct jcf_partial *state;
+{
+ if (state->last_block != NULL && BUFFER_LENGTH (&state->bytecode) == 0)
+ return state->last_block;
+ else
+ {
+ struct jcf_block *label = gen_jcf_label (state);
+ define_jcf_label (label, state);
+ return label;
+ }
+}
+
+/* Note a line number entry for the current PC and given LINE. */
+
+static void
+put_linenumber (line, state)
+ int line;
+ struct jcf_partial *state;
+{
+ struct jcf_block *label = get_jcf_label_here (state);
+ if (label->linenumber > 0)
+ {
+ label = gen_jcf_label (state);
+ define_jcf_label (label, state);
+ }
+ label->linenumber = line;
+ state->linenumber_count++;
+}
+
+/* Allocate a new jcf_handler, for a catch clause that catches exceptions
+ in the range (START_LABEL, END_LABEL). */
+
+static struct jcf_handler *
+alloc_handler (start_label, end_label, state)
+ struct jcf_block *start_label;
+ struct jcf_block *end_label;
+ struct jcf_partial *state;
+{
+ struct jcf_handler *handler = (struct jcf_handler *)
+ obstack_alloc (state->chunk_obstack, sizeof (struct jcf_handler));
+ handler->start_label = start_label;
+ handler->end_label = end_label;
+ handler->handler_label = get_jcf_label_here (state);
+ if (state->handlers == NULL)
+ state->handlers = handler;
+ else
+ state->last_handler->next = handler;
+ state->last_handler = handler;
+ handler->next = NULL;
+ state->num_handlers++;
+ return handler;
+}
+
/* The index of jvm local variable allocated for this DECL.
- This is assign when generating .class files;
- contrast DECL_LOCAL_SLOT_NUMBER whcih is set when *reading* a .class file.
+ This is assigned when generating .class files;
+ contrast DECL_LOCAL_SLOT_NUMBER which is set when *reading* a .class file.
(We don't allocate DECL_LANG_SPECIFIC for locals from Java sourc code.) */
#define DECL_LOCAL_INDEX(DECL) DECL_ALIGN(DECL)
struct localvar_info
{
- tree decl;
+ struct localvar_info *next;
- int start_pc;
-
- /* Offset in LocalVariableTable. */
- int debug_offset;
+ tree decl;
+ struct jcf_block *start_label;
+ struct jcf_block *end_label;
};
-struct buffer localvars = NULL_BUFFER;
-
-#define localvar_buffer ((struct localvar_info*) localvars.data)
-#define localvar_max ((struct localvar_info*) localvars.ptr - localvar_buffer)
-
-/* A buffer for storing LocalVariableTable entries entries. */
-
-struct buffer localvartable = NULL_BUFFER;
+#define localvar_buffer ((struct localvar_info**) state->localvars.data)
+#define localvar_max \
+ ((struct localvar_info**) state->localvars.ptr - localvar_buffer)
-int
-localvar_alloc (decl, start_pc)
+static void
+localvar_alloc (decl, state)
tree decl;
- int start_pc;
+ struct jcf_partial *state;
{
+ struct jcf_block *start_label = get_jcf_label_here (state);
int wide = TYPE_IS_WIDE (TREE_TYPE (decl));
int index;
- register struct localvar_info *info = (struct localvar_info*)localvars.data;
- register struct localvar_info *limit = (struct localvar_info*)localvars.ptr;
- for (index = 0; info < limit; index++, info++)
+ register struct localvar_info *info;
+ register struct localvar_info **ptr = localvar_buffer;
+ register struct localvar_info **limit
+ = (struct localvar_info**) state->localvars.ptr;
+ for (index = 0; ptr < limit; index++, ptr++)
{
- if (info->decl == NULL_TREE
- && (! wide || (info+1)->decl == NULL_TREE))
+ if (ptr[0] == NULL
+ && (! wide || ((ptr+1) < limit && ptr[1] == NULL)))
break;
}
- if (info == limit)
+ if (ptr == limit)
{
- buffer_grow (&localvars, sizeof (struct localvar_info));
- info = (struct localvar_info*)localvars.data + index;
- localvars.ptr = (unsigned char *) (info + 1 + wide);
+ buffer_grow (&state->localvars, 2 * sizeof (struct localvar_info*));
+ ptr = (struct localvar_info**) state->localvars.data + index;
+ state->localvars.ptr = (unsigned char *) (ptr + 1 + wide);
}
- info->decl = decl;
+ info = (struct localvar_info *)
+ obstack_alloc (state->chunk_obstack, sizeof (struct localvar_info));
+ ptr[0] = info;
if (wide)
- (info+1)->decl = TYPE_SECOND;
+ ptr[1] = (struct localvar_info *)(~0);
DECL_LOCAL_INDEX (decl) = index;
- info->start_pc = start_pc;
+ info->decl = decl;
+ info->start_label = start_label;
- if (DECL_NAME (decl) != NULL_TREE)
+ if (debug_info_level > DINFO_LEVEL_TERSE
+ && DECL_NAME (decl) != NULL_TREE)
{
/* Generate debugging info. */
- int i;
- register unsigned char *ptr;
- buffer_grow (&localvartable, 10);
- ptr = localvartable.ptr;
- info->debug_offset = ptr - localvartable.data;
- PUT2 (start_pc);
- PUT2 (0); /* length - fill in later */
- i = find_utf8_constant (code_cpool, DECL_NAME (decl));
- PUT2 (i); /* name_index*/
- i = find_utf8_constant (code_cpool,
- build_java_signature (TREE_TYPE (decl)));
- PUT2 (i); /* descriptor_index */
- PUT2 (index);
- localvartable.ptr = ptr;
+ info->next = NULL;
+ if (state->last_lvar != NULL)
+ state->last_lvar->next = info;
+ else
+ state->first_lvar = info;
+ state->last_lvar = info;
+ state->lvar_count++;
}
- else
- info->debug_offset = -1;
}
-int
-localvar_free (decl, end_pc)
- tree decl;
- int end_pc;
+static int
+localvar_free (decl, state)
+ tree decl;
+ struct jcf_partial *state;
{
- register unsigned char *ptr;
+ struct jcf_block *end_label = get_jcf_label_here (state);
int index = DECL_LOCAL_INDEX (decl);
- register struct localvar_info *info = &localvar_buffer [index];
+ register struct localvar_info **ptr = &localvar_buffer [index];
+ register struct localvar_info *info = *ptr;
int wide = TYPE_IS_WIDE (TREE_TYPE (decl));
- int i;
- i = info->debug_offset;
- if (i >= 0)
- {
- register unsigned char *ptr;
- /* Point to length field of local_variable_table. */
- ptr = localvartable.data + i + 2;
- i = end_pc - info->start_pc;
- PUT2 (i);
- }
+ info->end_label = end_label;
if (info->decl != decl)
abort ();
- info->decl = NULL_TREE;
+ ptr[0] = NULL;
if (wide)
{
- info++;
- if (info->decl != TYPE_SECOND)
+ if (ptr[1] != (struct localvar_info *)(~0))
abort ();
- info->decl = NULL_TREE;
+ ptr[1] = NULL;
}
-
}
#define STACK_TARGET 1
#define IGNORE_TARGET 2
-/* Allocate a new chunk on obstack WORK, and link it in after LAST.
- Set the data and size fields to DATA and SIZE, respectively.
- However, if DATA is NULL and SIZE>0, allocate a buffer as well. */
-
-struct chunk *
-alloc_chunk (last, data, size, work)
- struct chunk *last;
- unsigned char *data;
- int size;
- struct obstack *work;
-{
- struct chunk *chunk = (struct chunk *)
- obstack_alloc (work, sizeof(struct chunk));
-
- if (data == NULL && size > 0)
- data = obstack_alloc (work, size);
-
- chunk->next = NULL;
- chunk->data = data;
- chunk->size = size;
- last->next = chunk;
- return chunk;
-}
-
/* Get the access flags of a class (TYPE_DECL), a method (FUNCTION_DECL), or
a field (FIELD_DECL or VAR_DECL, if static), as encoded in a .class file. */
-int
+static int
get_access_flags (decl)
tree decl;
{
@@ -272,7 +607,7 @@ get_access_flags (decl)
if (CLASS_PUBLIC (decl)) /* same as FIELD_PUBLIC and METHOD_PUBLIC */
flags |= ACC_PUBLIC;
if (CLASS_FINAL (decl)) /* same as FIELD_FINAL and METHOD_FINAL */
- flags |= ACC_PUBLIC;
+ flags |= ACC_FINAL;
if (isfield || TREE_CODE (decl) == FUNCTION_DECL)
{
if (TREE_PROTECTED (decl))
@@ -297,8 +632,6 @@ get_access_flags (decl)
flags |= ACC_NATIVE;
if (METHOD_STATIC (decl))
flags |= ACC_STATIC;
- if (METHOD_FINAL (decl))
- flags |= ACC_FINAL;
if (METHOD_SYNCHRONIZED (decl))
flags |= ACC_SYNCHRONIZED;
if (METHOD_ABSTRACT (decl))
@@ -318,7 +651,7 @@ get_access_flags (decl)
/* Write the list of segments starting at CHUNKS to STREAM. */
-void
+static void
write_chunks (stream, chunks)
FILE* stream;
struct chunk *chunks;
@@ -327,10 +660,15 @@ write_chunks (stream, chunks)
fwrite (chunks->data, chunks->size, 1, stream);
}
-void
-push_constant1 (index)
+/* Push a 1-word constant in the constant pool at the given INDEX.
+ (Caller is responsible for doing NOTE_PUSH.) */
+
+static void
+push_constant1 (index, state)
int index;
+ struct jcf_partial *state;
{
+ RESERVE (3);
if (index < 256)
{
OP1 (OPCODE_ldc);
@@ -343,18 +681,26 @@ push_constant1 (index)
}
}
-void
-push_constant2 (index)
+/* Push a 2-word constant in the constant pool at the given INDEX.
+ (Caller is responsible for doing NOTE_PUSH.) */
+
+static void
+push_constant2 (index, state)
int index;
+ struct jcf_partial *state;
{
RESERVE (3);
OP1 (OPCODE_ldc2_w);
OP2 (index);
}
-void
-push_int_const (i)
+/* Push 32-bit integer constant on VM stack.
+ Caller is responsible for doing NOTE_PUSH. */
+
+static void
+push_int_const (i, state)
HOST_WIDE_INT i;
+ struct jcf_partial *state;
{
RESERVE(3);
if (i >= -1 && i <= 5)
@@ -371,44 +717,93 @@ push_int_const (i)
}
else
{
- i = find_constant1 (code_cpool, CONSTANT_Integer, i & 0xFFFFFFFF);
- push_constant1 (i);
+ i = find_constant1 (&state->cpool, CONSTANT_Integer, i & 0xFFFFFFFF);
+ push_constant1 (i, state);
}
}
-void
-push_long_const (lo, hi)
+static int
+find_constant_wide (lo, hi, state)
+ HOST_WIDE_INT lo, hi;
+ struct jcf_partial *state;
+{
+ HOST_WIDE_INT w1, w2;
+ lshift_double (lo, hi, -32, 64, &w1, &w2, 1);
+ return find_constant2 (&state->cpool, CONSTANT_Long,
+ w1 & 0xFFFFFFFF, lo & 0xFFFFFFFF);
+}
+
+/* Find or allocate a constant pool entry for the given VALUE.
+ Return the index in the constant pool. */
+
+static int
+find_constant_index (value, state)
+ tree value;
+ struct jcf_partial *state;
+{
+ if (TREE_CODE (value) == INTEGER_CST)
+ {
+ if (TYPE_PRECISION (TREE_TYPE (value)) <= 32)
+ return find_constant1 (&state->cpool, CONSTANT_Integer,
+ TREE_INT_CST_LOW (value) & 0xFFFFFFFF);
+ else
+ return find_constant_wide (TREE_INT_CST_LOW (value),
+ TREE_INT_CST_HIGH (value), state);
+ }
+ else if (TREE_CODE (value) == REAL_CST)
+ {
+ long words[2];
+ if (TYPE_PRECISION (TREE_TYPE (value)) == 32)
+ {
+ words[0] = etarsingle (TREE_REAL_CST (value)) & 0xFFFFFFFF;
+ return find_constant1 (&state->cpool, CONSTANT_Float, words[0]);
+ }
+ else
+ {
+ etardouble (TREE_REAL_CST (value), words);
+ return find_constant2 (&state->cpool, CONSTANT_Double,
+ words[1-FLOAT_WORDS_BIG_ENDIAN] & 0xFFFFFFFF,
+ words[FLOAT_WORDS_BIG_ENDIAN] & 0xFFFFFFFF);
+ }
+ }
+ else if (TREE_CODE (value) == STRING_CST)
+ {
+ return find_string_constant (&state->cpool, value);
+ }
+ else
+ fatal ("find_constant_index - bad type");
+}
+
+/* Push 64-bit long constant on VM stack.
+ Caller is responsible for doing NOTE_PUSH. */
+
+static void
+push_long_const (lo, hi, state)
HOST_WIDE_INT lo, hi;
+ struct jcf_partial *state;
{
if (hi == 0 && lo >= 0 && lo <= 1)
{
RESERVE(1);
OP1(OPCODE_lconst_0 + lo);
}
-#if 0
- else if ((jlong) (jint) i == i)
+ else if ((hi == 0 && lo < 32768) || (hi == -1 && lo >= -32768))
{
- push_int_const ((jint) i);
+ push_int_const (lo, state);
RESERVE (1);
OP1 (OPCODE_i2l);
}
-#endif
else
- {
- HOST_WIDE_INT w1, w2;
- lshift_double (lo, hi, -32, 64, &w1, &w2, 1);
- hi = find_constant1 (code_cpool, CONSTANT_Long,
- w1 & 0xFFFFFFFF, lo & 0xFFFFFFFF);
- push_constant2 (hi);
- }
+ push_constant2 (find_constant_wide (lo, hi, state), state);
}
-void
-field_op (field, opcode)
+static void
+field_op (field, opcode, state)
tree field;
int opcode;
+ struct jcf_partial *state;
{
- int index = find_fieldref_index (code_cpool, field);
+ int index = find_fieldref_index (&state->cpool, field);
RESERVE (3);
OP1 (opcode);
OP2 (index);
@@ -418,21 +813,24 @@ field_op (field, opcode)
reference) to 7 (for 'short') which matches the pattern of how JVM
opcodes typically depend on the operand type. */
-int
-adjust_typed_op (type)
+static int
+adjust_typed_op (type, max)
tree type;
+ int max;
{
switch (TREE_CODE (type))
{
- case BOOLEAN_TYPE: return 5;
- case CHAR_TYPE: return 6;
case POINTER_TYPE:
case RECORD_TYPE: return 4;
+ case BOOLEAN_TYPE:
+ return TYPE_PRECISION (type) == 32 || max < 5 ? 0 : 5;
+ case CHAR_TYPE:
+ return TYPE_PRECISION (type) == 32 || max < 6 ? 0 : 6;
case INTEGER_TYPE:
switch (TYPE_PRECISION (type))
{
- case 8: return 5;
- case 16: return 7;
+ case 8: return max < 5 ? 0 : 5;
+ case 16: return max < 7 ? 0 : 7;
case 32: return 0;
case 64: return 1;
}
@@ -444,18 +842,21 @@ adjust_typed_op (type)
case 64: return 3;
}
break;
+ default:
+ break;
}
abort ();
}
-void
-maybe_wide (opcode, index)
+static void
+maybe_wide (opcode, index, state)
int opcode, index;
+ struct jcf_partial *state;
{
if (index >= 256)
{
RESERVE (4);
- OP1 (196); /* wide */
+ OP1 (OPCODE_wide);
OP1 (opcode);
OP2 (index);
}
@@ -467,55 +868,566 @@ maybe_wide (opcode, index)
}
}
-#define PC BUFFER_LENGTH(&bytecode)
+/* Compile code to duplicate with offset, where
+ SIZE is the size of the stack item to duplicate (1 or 2), abd
+ OFFSET is where to insert the result (must be 0, 1, or 2).
+ (The new words get inserted at stack[SP-size-offset].) */
+
+static void
+emit_dup (size, offset, state)
+ int size, offset;
+ struct jcf_partial *state;
+{
+ int kind;
+ if (size == 0)
+ return;
+ RESERVE(1);
+ if (offset == 0)
+ kind = size == 1 ? OPCODE_dup : OPCODE_dup2;
+ else if (offset == 1)
+ kind = size == 1 ? OPCODE_dup_x1 : OPCODE_dup2_x1;
+ else if (offset == 2)
+ kind = size == 1 ? OPCODE_dup_x2 : OPCODE_dup2_x2;
+ else
+ abort();
+ OP1 (kind);
+ NOTE_PUSH (size);
+}
+
+static void
+emit_pop (size, state)
+ int size;
+ struct jcf_partial *state;
+{
+ RESERVE (1);
+ OP1 (OPCODE_pop - 1 + size);
+}
+
+static void
+emit_iinc (var, value, state)
+ tree var;
+ int value;
+ struct jcf_partial *state;
+{
+ int slot = DECL_LOCAL_INDEX (var);
+
+ if (value < -128 || value > 127 || slot >= 256)
+ {
+ RESERVE (6);
+ OP1 (OPCODE_wide);
+ OP1 (OPCODE_iinc);
+ OP2 (slot);
+ OP2 (value);
+ }
+ else
+ {
+ RESERVE (3);
+ OP1 (OPCODE_iinc);
+ OP1 (slot);
+ OP1 (value);
+ }
+}
+
+static void
+emit_load_or_store (var, opcode, state)
+ tree var; /* Variable to load from or store into. */
+ int opcode; /* Either OPCODE_iload or OPCODE_istore. */
+ struct jcf_partial *state;
+{
+ tree type = TREE_TYPE (var);
+ int kind = adjust_typed_op (type, 4);
+ int index = DECL_LOCAL_INDEX (var);
+ if (index <= 3)
+ {
+ RESERVE (1);
+ OP1 (opcode + 5 + 4 * kind + index); /* [ilfda]{load,store}_[0123] */
+ }
+ else
+ maybe_wide (opcode + kind, index, state); /* [ilfda]{load,store} */
+}
+
+static void
+emit_load (var, state)
+ tree var;
+ struct jcf_partial *state;
+{
+ emit_load_or_store (var, OPCODE_iload, state);
+ NOTE_PUSH (TYPE_IS_WIDE (TREE_TYPE (var)) ? 2 : 1);
+}
+
+static void
+emit_store (var, state)
+ tree var;
+ struct jcf_partial *state;
+{
+ emit_load_or_store (var, OPCODE_istore, state);
+ NOTE_POP (TYPE_IS_WIDE (TREE_TYPE (var)) ? 2 : 1);
+}
+
+static void
+emit_unop (opcode, type, state)
+ enum java_opcode opcode;
+ tree type ATTRIBUTE_UNUSED;
+ struct jcf_partial *state;
+{
+ RESERVE(1);
+ OP1 (opcode);
+}
+
+static void
+emit_binop (opcode, type, state)
+ enum java_opcode opcode;
+ tree type;
+ struct jcf_partial *state;
+{
+ int size = TYPE_IS_WIDE (type) ? 2 : 1;
+ RESERVE(1);
+ OP1 (opcode);
+ NOTE_POP (size);
+}
+
+static void
+emit_reloc (value, kind, target, state)
+ HOST_WIDE_INT value;
+ int kind;
+ struct jcf_block *target;
+ struct jcf_partial *state;
+{
+ struct jcf_relocation *reloc = (struct jcf_relocation *)
+ obstack_alloc (state->chunk_obstack, sizeof (struct jcf_relocation));
+ struct jcf_block *block = state->last_block;
+ reloc->next = block->u.relocations;
+ block->u.relocations = reloc;
+ reloc->offset = BUFFER_LENGTH (&state->bytecode);
+ reloc->label = target;
+ reloc->kind = kind;
+ if (kind == 0 || kind == BLOCK_START_RELOC)
+ OP4 (value);
+ else if (kind != SWITCH_ALIGN_RELOC)
+ OP2 (value);
+}
+
+static void
+emit_switch_reloc (label, state)
+ struct jcf_block *label;
+ struct jcf_partial *state;
+{
+ emit_reloc (0, BLOCK_START_RELOC, label, state);
+}
+
+/* Similar to emit_switch_reloc,
+ but re-uses an existing case reloc. */
+
+static void
+emit_case_reloc (reloc, state)
+ struct jcf_relocation *reloc;
+ struct jcf_partial *state;
+{
+ struct jcf_block *block = state->last_block;
+ reloc->next = block->u.relocations;
+ block->u.relocations = reloc;
+ reloc->offset = BUFFER_LENGTH (&state->bytecode);
+ reloc->kind = BLOCK_START_RELOC;
+ OP4 (0);
+}
+
+/* Emit a conditional jump to TARGET with a 2-byte relative jump offset
+ The opcode is OPCODE, the inverted opcode is INV_OPCODE. */
-/* Generate byetcode for sub-expression EXP of METHOD.
+static void
+emit_if (target, opcode, inv_opcode, state)
+ struct jcf_block *target;
+ int opcode, inv_opcode;
+ struct jcf_partial *state;
+{
+ OP1 (opcode);
+ // value is 1 byte from reloc back to start of instruction.
+ emit_reloc (1, - inv_opcode, target, state);
+}
+
+static void
+emit_goto (target, state)
+ struct jcf_block *target;
+ struct jcf_partial *state;
+{
+ OP1 (OPCODE_goto);
+ // Value is 1 byte from reloc back to start of instruction.
+ emit_reloc (1, OPCODE_goto_w, target, state);
+}
+
+static void
+emit_jsr (target, state)
+ struct jcf_block *target;
+ struct jcf_partial *state;
+{
+ OP1 (OPCODE_jsr);
+ // Value is 1 byte from reloc back to start of instruction.
+ emit_reloc (1, OPCODE_jsr_w, target, state);
+}
+
+/* Generate code to evaluate EXP. If the result is true,
+ branch to TRUE_LABEL; otherwise, branch to FALSE_LABEL.
+ TRUE_BRANCH_FIRST is a code geneation hint that the
+ TRUE_LABEL may follow right after this. (The idea is that we
+ may be able to optimize away GOTO TRUE_LABEL; TRUE_LABEL:) */
+
+static void
+generate_bytecode_conditional (exp, true_label, false_label,
+ true_branch_first, state)
+ tree exp;
+ struct jcf_block *true_label;
+ struct jcf_block *false_label;
+ int true_branch_first;
+ struct jcf_partial *state;
+{
+ tree exp0, exp1, type;
+ int save_SP = state->code_SP;
+ enum java_opcode op, negop;
+ switch (TREE_CODE (exp))
+ {
+ case INTEGER_CST:
+ emit_goto (integer_zerop (exp) ? false_label : true_label, state);
+ break;
+ case COND_EXPR:
+ {
+ struct jcf_block *then_label = gen_jcf_label (state);
+ struct jcf_block *else_label = gen_jcf_label (state);
+ int save_SP_before, save_SP_after;
+ generate_bytecode_conditional (TREE_OPERAND (exp, 0),
+ then_label, else_label, 1, state);
+ define_jcf_label (then_label, state);
+ save_SP_before = state->code_SP;
+ generate_bytecode_conditional (TREE_OPERAND (exp, 1),
+ true_label, false_label, 1, state);
+ save_SP_after = state->code_SP;
+ state->code_SP = save_SP_before;
+ define_jcf_label (else_label, state);
+ generate_bytecode_conditional (TREE_OPERAND (exp, 2),
+ true_label, false_label,
+ true_branch_first, state);
+ if (state->code_SP != save_SP_after)
+ fatal ("internal error non-matching SP");
+ }
+ break;
+ case TRUTH_NOT_EXPR:
+ generate_bytecode_conditional (TREE_OPERAND (exp, 0), false_label, true_label,
+ ! true_branch_first, state);
+ break;
+ case TRUTH_ANDIF_EXPR:
+ {
+ struct jcf_block *next_label = gen_jcf_label (state);
+ generate_bytecode_conditional (TREE_OPERAND (exp, 0),
+ next_label, false_label, 1, state);
+ define_jcf_label (next_label, state);
+ generate_bytecode_conditional (TREE_OPERAND (exp, 1),
+ true_label, false_label, 1, state);
+ }
+ break;
+ case TRUTH_ORIF_EXPR:
+ {
+ struct jcf_block *next_label = gen_jcf_label (state);
+ generate_bytecode_conditional (TREE_OPERAND (exp, 0),
+ true_label, next_label, 1, state);
+ define_jcf_label (next_label, state);
+ generate_bytecode_conditional (TREE_OPERAND (exp, 1),
+ true_label, false_label, 1, state);
+ }
+ break;
+ compare_1:
+ /* Assuming op is one of the 2-operand if_icmp<COND> instructions,
+ set it to the corresponding 1-operand if<COND> instructions. */
+ op = op - 6;
+ /* FALLTHROUGH */
+ compare_2:
+ /* The opcodes with their inverses are allocated in pairs.
+ E.g. The inverse of if_icmplt (161) is if_icmpge (162). */
+ negop = (op & 1) ? op + 1 : op - 1;
+ compare_2_ptr:
+ if (true_branch_first)
+ {
+ emit_if (false_label, negop, op, state);
+ emit_goto (true_label, state);
+ }
+ else
+ {
+ emit_if (true_label, op, negop, state);
+ emit_goto (false_label, state);
+ }
+ break;
+ case EQ_EXPR:
+ op = OPCODE_if_icmpeq;
+ goto compare;
+ case NE_EXPR:
+ op = OPCODE_if_icmpne;
+ goto compare;
+ case GT_EXPR:
+ op = OPCODE_if_icmpgt;
+ goto compare;
+ case LT_EXPR:
+ op = OPCODE_if_icmplt;
+ goto compare;
+ case GE_EXPR:
+ op = OPCODE_if_icmpge;
+ goto compare;
+ case LE_EXPR:
+ op = OPCODE_if_icmple;
+ goto compare;
+ compare:
+ exp0 = TREE_OPERAND (exp, 0);
+ exp1 = TREE_OPERAND (exp, 1);
+ type = TREE_TYPE (exp0);
+ switch (TREE_CODE (type))
+ {
+ int opf;
+ case POINTER_TYPE: case RECORD_TYPE:
+ switch (TREE_CODE (exp))
+ {
+ case EQ_EXPR: op = OPCODE_if_acmpeq; break;
+ case NE_EXPR: op = OPCODE_if_acmpne; break;
+ default: abort();
+ }
+ if (integer_zerop (exp1) || integer_zerop (exp0))
+ {
+ generate_bytecode_insns (integer_zerop (exp1) ? exp0 : exp0,
+ STACK_TARGET, state);
+ op = op + (OPCODE_ifnull - OPCODE_if_acmpeq);
+ negop = (op & 1) ? op - 1 : op + 1;
+ NOTE_POP (1);
+ goto compare_2_ptr;
+ }
+ generate_bytecode_insns (exp0, STACK_TARGET, state);
+ generate_bytecode_insns (exp1, STACK_TARGET, state);
+ NOTE_POP (2);
+ goto compare_2;
+ case REAL_TYPE:
+ generate_bytecode_insns (exp0, STACK_TARGET, state);
+ generate_bytecode_insns (exp1, STACK_TARGET, state);
+ if (op == OPCODE_if_icmplt || op == OPCODE_if_icmple)
+ opf = OPCODE_fcmpg;
+ else
+ opf = OPCODE_fcmpl;
+ if (TYPE_PRECISION (type) > 32)
+ {
+ opf += 2;
+ NOTE_POP (4);
+ }
+ else
+ NOTE_POP (2);
+ RESERVE (1);
+ OP1 (opf);
+ goto compare_1;
+ case INTEGER_TYPE:
+ if (TYPE_PRECISION (type) > 32)
+ {
+ generate_bytecode_insns (exp0, STACK_TARGET, state);
+ generate_bytecode_insns (exp1, STACK_TARGET, state);
+ NOTE_POP (4);
+ RESERVE (1);
+ OP1 (OPCODE_lcmp);
+ goto compare_1;
+ }
+ /* FALLTHOUGH */
+ default:
+ if (integer_zerop (exp1))
+ {
+ generate_bytecode_insns (exp0, STACK_TARGET, state);
+ NOTE_POP (1);
+ goto compare_1;
+ }
+ if (integer_zerop (exp0))
+ {
+ switch (op)
+ {
+ case OPCODE_if_icmplt:
+ case OPCODE_if_icmpge:
+ op += 2;
+ break;
+ case OPCODE_if_icmpgt:
+ case OPCODE_if_icmple:
+ op -= 2;
+ break;
+ default:
+ break;
+ }
+ generate_bytecode_insns (exp1, STACK_TARGET, state);
+ NOTE_POP (1);
+ goto compare_1;
+ }
+ generate_bytecode_insns (exp0, STACK_TARGET, state);
+ generate_bytecode_insns (exp1, STACK_TARGET, state);
+ NOTE_POP (2);
+ goto compare_2;
+ }
+
+ default:
+ generate_bytecode_insns (exp, STACK_TARGET, state);
+ NOTE_POP (1);
+ if (true_branch_first)
+ {
+ emit_if (false_label, OPCODE_ifeq, OPCODE_ifne, state);
+ emit_goto (true_label, state);
+ }
+ else
+ {
+ emit_if (true_label, OPCODE_ifne, OPCODE_ifeq, state);
+ emit_goto (false_label, state);
+ }
+ break;
+ }
+ if (save_SP != state->code_SP)
+ fatal ("internal error - SP mismatch");
+}
+
+/* Call pending cleanups i.e. those for surrounding CLEANUP_POINT_EXPRs
+ but only as far out as LIMIT (since we are about to jump to the
+ emit label that is LIMIT). */
+
+static void
+call_cleanups (limit, state)
+ struct jcf_block *limit;
+ struct jcf_partial *state;
+{
+ struct jcf_block *block = state->labeled_blocks;
+ for (; block != limit; block = block->next)
+ {
+ if (block->pc == PENDING_CLEANUP_PC)
+ emit_jsr (block, state);
+ }
+}
+
+static void
+generate_bytecode_return (exp, state)
+ tree exp;
+ struct jcf_partial *state;
+{
+ tree return_type = TREE_TYPE (TREE_TYPE (state->current_method));
+ int returns_void = TREE_CODE (return_type) == VOID_TYPE;
+ int op;
+ again:
+ if (exp != NULL)
+ {
+ switch (TREE_CODE (exp))
+ {
+ case COMPOUND_EXPR:
+ generate_bytecode_insns (TREE_OPERAND (exp, 0), IGNORE_TARGET,
+ state);
+ exp = TREE_OPERAND (exp, 1);
+ goto again;
+ case COND_EXPR:
+ {
+ struct jcf_block *then_label = gen_jcf_label (state);
+ struct jcf_block *else_label = gen_jcf_label (state);
+ generate_bytecode_conditional (TREE_OPERAND (exp, 0),
+ then_label, else_label, 1, state);
+ define_jcf_label (then_label, state);
+ generate_bytecode_return (TREE_OPERAND (exp, 1), state);
+ define_jcf_label (else_label, state);
+ generate_bytecode_return (TREE_OPERAND (exp, 2), state);
+ }
+ return;
+ default:
+ generate_bytecode_insns (exp,
+ returns_void ? IGNORE_TARGET
+ : STACK_TARGET, state);
+ }
+ }
+ if (returns_void)
+ {
+ op = OPCODE_return;
+ call_cleanups (NULL_TREE, state);
+ }
+ else
+ {
+ op = OPCODE_ireturn + adjust_typed_op (return_type, 4);
+ if (state->num_finalizers > 0)
+ {
+ if (state->return_value_decl == NULL_TREE)
+ {
+ state->return_value_decl
+ = build_decl (VAR_DECL, NULL_TREE, TREE_TYPE (exp));
+ localvar_alloc (state->return_value_decl, state);
+ }
+ emit_store (state->return_value_decl, state);
+ call_cleanups (NULL_TREE, state);
+ emit_load (state->return_value_decl, state);
+ /* If we call localvar_free (state->return_value_decl, state),
+ then we risk the save decl erroneously re-used in the
+ finalizer. Instead, we keep the state->return_value_decl
+ allocated through the rest of the method. This is not
+ the greatest solution, but it is at least simple and safe. */
+ }
+ }
+ RESERVE (1);
+ OP1 (op);
+}
+
+/* Generate bytecode for sub-expression EXP of METHOD.
TARGET is one of STACK_TARGET or IGNORE_TARGET. */
-void
-generate_bytecode_insns (method, exp, target)
- tree method;
+static void
+generate_bytecode_insns (exp, target, state)
tree exp;
int target;
+ struct jcf_partial *state;
{
- rtx value;
- tree type = TREE_TYPE (exp);
+ tree type;
enum java_opcode jopcode;
int op;
+ HOST_WIDE_INT value;
+ int post_op;
+ int size;
+ int offset;
+
+ if (exp == NULL && target == IGNORE_TARGET)
+ return;
+
+ type = TREE_TYPE (exp);
+
switch (TREE_CODE (exp))
{
case BLOCK:
if (BLOCK_EXPR_BODY (exp))
{
tree local;
+ tree body = BLOCK_EXPR_BODY (exp);
for (local = BLOCK_EXPR_DECLS (exp); local; )
{
tree next = TREE_CHAIN (local);
- localvar_alloc (local, PC);
+ localvar_alloc (local, state);
local = next;
}
- generate_bytecode_insns (method, BLOCK_EXPR_BODY (exp), target);
+ /* Avoid deep recursion for long blocks. */
+ while (TREE_CODE (body) == COMPOUND_EXPR)
+ {
+ generate_bytecode_insns (TREE_OPERAND (body, 0), target, state);
+ body = TREE_OPERAND (body, 1);
+ }
+ generate_bytecode_insns (body, target, state);
for (local = BLOCK_EXPR_DECLS (exp); local; )
{
tree next = TREE_CHAIN (local);
- localvar_free (local, PC);
+ localvar_free (local, state);
local = next;
}
}
break;
case COMPOUND_EXPR:
- generate_bytecode_insns (method, TREE_OPERAND (exp, 0), IGNORE_TARGET);
- generate_bytecode_insns (method, TREE_OPERAND (exp, 1), target);
+ generate_bytecode_insns (TREE_OPERAND (exp, 0), IGNORE_TARGET, state);
+ generate_bytecode_insns (TREE_OPERAND (exp, 1), target, state);
break;
case EXPR_WITH_FILE_LOCATION:
{
char *saved_input_filename = input_filename;
+ tree body = EXPR_WFL_NODE (exp);
int saved_lineno = lineno;
+ if (body == empty_stmt_node)
+ break;
input_filename = EXPR_WFL_FILENAME (exp);
lineno = EXPR_WFL_LINENO (exp);
- if (EXPR_WFL_EMIT_LINE_NOTE (exp))
- put_linenumber (PC, EXPR_WFL_LINENO (exp));
- generate_bytecode_insns (method, EXPR_WFL_NODE (exp), target);
+ if (EXPR_WFL_EMIT_LINE_NOTE (exp) && lineno > 0
+ && debug_info_level > DINFO_LEVEL_NONE)
+ put_linenumber (lineno, state);
+ generate_bytecode_insns (body, target, state);
input_filename = saved_input_filename;
lineno = saved_lineno;
}
@@ -532,46 +1444,67 @@ generate_bytecode_insns (method, exp, target)
}
else if (TYPE_PRECISION (type) <= 32)
{
- push_int_const (TREE_INT_CST_LOW (exp));
+ push_int_const (TREE_INT_CST_LOW (exp), state);
NOTE_PUSH (1);
}
else
{
- push_long_const (TREE_INT_CST_LOW (exp), TREE_INT_CST_HIGH (exp));
+ push_long_const (TREE_INT_CST_LOW (exp), TREE_INT_CST_HIGH (exp),
+ state);
NOTE_PUSH (2);
}
break;
+ case REAL_CST:
+ {
+ int prec = TYPE_PRECISION (type) >> 5;
+ RESERVE(1);
+ if (real_zerop (exp))
+ OP1 (prec == 1 ? OPCODE_fconst_0 : OPCODE_dconst_0);
+ else if (real_onep (exp))
+ OP1 (prec == 1 ? OPCODE_fconst_1 : OPCODE_dconst_1);
+ /* FIXME Should also use fconst_2 for 2.0f.
+ Also, should use iconst_2/ldc followed by i2f/i2d
+ for other float/double when the value is a small integer. */
+ else
+ {
+ offset = find_constant_index (exp, state);
+ if (prec == 1)
+ push_constant1 (offset, state);
+ else
+ push_constant2 (offset, state);
+ }
+ NOTE_PUSH (prec);
+ }
+ break;
+ case STRING_CST:
+ push_constant1 (find_string_constant (&state->cpool, exp), state);
+ NOTE_PUSH (1);
+ break;
case VAR_DECL:
if (TREE_STATIC (exp))
{
- field_op (exp, OPCODE_getstatic);
+ field_op (exp, OPCODE_getstatic, state);
+ NOTE_PUSH (TYPE_IS_WIDE (TREE_TYPE (exp)) ? 2 : 1);
break;
}
/* ... fall through ... */
case PARM_DECL:
- {
- int kind = adjust_typed_op (type);
- int index = DECL_LOCAL_INDEX (exp);
- if (index <= 3)
- {
- RESERVE (1);
- OP1 (26 + 4 * kind + index); /* [ilfda]load_[0123] */
- }
- else
- maybe_wide (21 + kind, index); /* [ilfda]load */
- }
+ emit_load (exp, state);
break;
+ case NON_LVALUE_EXPR:
case INDIRECT_REF:
- generate_bytecode_insns (method, TREE_OPERAND (exp, 0), target);
+ generate_bytecode_insns (TREE_OPERAND (exp, 0), target, state);
break;
case ARRAY_REF:
- generate_bytecode_insns (method, TREE_OPERAND (exp, 0), target);
- generate_bytecode_insns (method, TREE_OPERAND (exp, 1), target);
+ generate_bytecode_insns (TREE_OPERAND (exp, 0), target, state);
+ generate_bytecode_insns (TREE_OPERAND (exp, 1), target, state);
if (target != IGNORE_TARGET)
{
- jopcode = OPCODE_iaload + adjust_typed_op (type);
+ jopcode = OPCODE_iaload + adjust_typed_op (type, 7);
RESERVE(1);
OP1 (jopcode);
+ if (! TYPE_IS_WIDE (type))
+ NOTE_POP (1);
}
break;
case COMPONENT_REF:
@@ -579,8 +1512,8 @@ generate_bytecode_insns (method, exp, target)
tree obj = TREE_OPERAND (exp, 0);
tree field = TREE_OPERAND (exp, 1);
int is_static = FIELD_STATIC (field);
- generate_bytecode_insns (method, obj,
- is_static ? IGNORE_TARGET : target);
+ generate_bytecode_insns (obj,
+ is_static ? IGNORE_TARGET : target, state);
if (target != IGNORE_TARGET)
{
if (DECL_NAME (field) == length_identifier_node && !is_static
@@ -590,198 +1523,1211 @@ generate_bytecode_insns (method, exp, target)
OP1 (OPCODE_arraylength);
}
else
- field_op (field, is_static ? OPCODE_getstatic : OPCODE_getfield);
+ {
+ field_op (field, is_static ? OPCODE_getstatic : OPCODE_getfield,
+ state);
+ if (! is_static)
+ NOTE_POP (1);
+ NOTE_PUSH (TYPE_IS_WIDE (TREE_TYPE (field)) ? 2 : 1);
+ }
}
}
break;
- case RETURN_EXPR:
- if (!TREE_OPERAND (exp, 0))
- op = OPCODE_return;
- else
- {
- exp = TREE_OPERAND (exp, 0);
- if (TREE_CODE (exp) != MODIFY_EXPR)
- abort ();
- exp = TREE_OPERAND (exp, 1);
- op = OPCODE_ireturn + adjust_typed_op (TREE_TYPE (exp));
- generate_bytecode_insns (method, exp, STACK_TARGET);
- }
- RESERVE (1);
- OP1 (op);
+ case TRUTH_ANDIF_EXPR:
+ case TRUTH_ORIF_EXPR:
+ case EQ_EXPR:
+ case NE_EXPR:
+ case GT_EXPR:
+ case LT_EXPR:
+ case GE_EXPR:
+ case LE_EXPR:
+ {
+ struct jcf_block *then_label = gen_jcf_label (state);
+ struct jcf_block *else_label = gen_jcf_label (state);
+ struct jcf_block *end_label = gen_jcf_label (state);
+ generate_bytecode_conditional (exp,
+ then_label, else_label, 1, state);
+ define_jcf_label (then_label, state);
+ push_int_const (1, state);
+ emit_goto (end_label, state);
+ define_jcf_label (else_label, state);
+ push_int_const (0, state);
+ define_jcf_label (end_label, state);
+ NOTE_PUSH (1);
+ }
break;
- case MODIFY_EXPR:
+ case COND_EXPR:
{
- tree lhs = TREE_OPERAND (exp, 0);
- tree rhs = TREE_OPERAND (exp, 1);
- HOST_WIDE_INT value;
-#if 0
- if (TREE_CODE (rhs) == PLUS_EXPR
- && TREE_CODE (lhs) == VAR_DECL
- /* && FIXME lhs is a local variable */
- && TYPE_MODE (TREE)TYPE (lhs) == SImode /* ??? */
- && TREE_OPERAND (rhs, 0) == lhs
- && TREE_CODE (TREE_OPERAND (rhs, 1)) == INTEGER_CST
- /* or vice versa FIXME */
- && (value = TREE_INT_CST_LOW (TREE_OPERAND (rhs, 1)),
- (value >= -32768 && value <= 32767)))
- {
- emit_insn (gen_rtx (SET, SImode,
- DECL_RTL (lhs),
- gen_rtx (PLUS, SImode,
- DECL_RTL (lhs),
- gen_rtx_CONST_INT (SImode, value))));
- return DECL_RTL (lhs);
- }
-#endif
- if (TREE_CODE (lhs) == COMPONENT_REF)
- generate_bytecode_insns (method, TREE_OPERAND (lhs, 0), STACK_TARGET);
- else if (TREE_CODE (lhs) == ARRAY_REF)
+ struct jcf_block *then_label = gen_jcf_label (state);
+ struct jcf_block *else_label = gen_jcf_label (state);
+ struct jcf_block *end_label = gen_jcf_label (state);
+ generate_bytecode_conditional (TREE_OPERAND (exp, 0),
+ then_label, else_label, 1, state);
+ define_jcf_label (then_label, state);
+ generate_bytecode_insns (TREE_OPERAND (exp, 1), target, state);
+ if (CAN_COMPLETE_NORMALLY (TREE_OPERAND (exp, 1))
+ /* Not all expressions have CAN_COMPLETE_NORMALLY set properly. */
+ || TREE_CODE (TREE_TYPE (exp)) != VOID_TYPE)
+ emit_goto (end_label, state);
+ define_jcf_label (else_label, state);
+ generate_bytecode_insns (TREE_OPERAND (exp, 2), target, state);
+ define_jcf_label (end_label, state);
+ }
+ break;
+ case CASE_EXPR:
+ {
+ struct jcf_switch_state *sw_state = state->sw_state;
+ struct jcf_relocation *reloc = (struct jcf_relocation *)
+ obstack_alloc (state->chunk_obstack, sizeof (struct jcf_relocation));
+ HOST_WIDE_INT case_value = TREE_INT_CST_LOW (TREE_OPERAND (exp, 0));
+ reloc->kind = 0;
+ reloc->label = get_jcf_label_here (state);
+ reloc->offset = case_value;
+ reloc->next = sw_state->cases;
+ sw_state->cases = reloc;
+ if (sw_state->num_cases == 0)
{
- generate_bytecode_insns (method,
- TREE_OPERAND (lhs, 0), STACK_TARGET);
- generate_bytecode_insns (method,
- TREE_OPERAND (lhs, 1), STACK_TARGET);
+ sw_state->min_case = case_value;
+ sw_state->max_case = case_value;
}
- generate_bytecode_insns (method, rhs, STACK_TARGET);
- if (target != IGNORE_TARGET)
+ else
{
- RESERVE (1);
- OP1 (TYPE_IS_WIDE (type) ? OPCODE_dup2_x1 : OPCODE_dup_x1);
+ if (case_value < sw_state->min_case)
+ sw_state->min_case = case_value;
+ if (case_value > sw_state->max_case)
+ sw_state->max_case = case_value;
}
- if (TREE_CODE (lhs) == COMPONENT_REF)
+ sw_state->num_cases++;
+ }
+ break;
+ case DEFAULT_EXPR:
+ state->sw_state->default_label = get_jcf_label_here (state);
+ break;
+
+ case SWITCH_EXPR:
+ {
+ /* The SWITCH_EXPR has three parts, generated in the following order:
+ 1. the switch_expression (the value used to select the correct case);
+ 2. the switch_body;
+ 3. the switch_instruction (the tableswitch/loopupswitch instruction.).
+ After code generation, we will re-order then in the order 1, 3, 2.
+ This is to avoid an extra GOTOs. */
+ struct jcf_switch_state sw_state;
+ struct jcf_block *expression_last; /* Last block of the switch_expression. */
+ struct jcf_block *body_last; /* Last block of the switch_body. */
+ struct jcf_block *switch_instruction; /* First block of switch_instruction. */
+ struct jcf_block *instruction_last; /* Last block of the switch_instruction. */
+ struct jcf_block *body_block;
+ int switch_length;
+ sw_state.prev = state->sw_state;
+ state->sw_state = &sw_state;
+ sw_state.cases = NULL;
+ sw_state.num_cases = 0;
+ sw_state.default_label = NULL;
+ generate_bytecode_insns (TREE_OPERAND (exp, 0), STACK_TARGET, state);
+ expression_last = state->last_block;
+ body_block = get_jcf_label_here (state); /* Force a new block here. */
+ generate_bytecode_insns (TREE_OPERAND (exp, 1), IGNORE_TARGET, state);
+ body_last = state->last_block;
+
+ switch_instruction = gen_jcf_label (state);
+ define_jcf_label (switch_instruction, state);
+ if (sw_state.default_label == NULL)
+ sw_state.default_label = gen_jcf_label (state);
+
+ if (sw_state.num_cases <= 1)
{
- tree field = TREE_OPERAND (lhs, 1);
- field_op (field,
- FIELD_STATIC (field) ? OPCODE_putstatic
- : OPCODE_putfield);
+ if (sw_state.num_cases == 0)
+ {
+ emit_pop (1, state);
+ NOTE_POP (1);
+ }
+ else
+ {
+ push_int_const (sw_state.cases->offset, state);
+ emit_if (sw_state.cases->label,
+ OPCODE_ifeq, OPCODE_ifne, state);
+ }
+ emit_goto (sw_state.default_label, state);
}
- else if (TREE_CODE (lhs) == VAR_DECL
- || TREE_CODE (lhs) == PARM_DECL)
+ else
{
- if (FIELD_STATIC (lhs))
+ HOST_WIDE_INT i;
+ /* Copy the chain of relocs into a sorted array. */
+ struct jcf_relocation **relocs = (struct jcf_relocation **)
+ xmalloc (sw_state.num_cases * sizeof (struct jcf_relocation *));
+ /* The relocs arrays is a buffer with a gap.
+ The assumption is that cases will normally come in "runs". */
+ int gap_start = 0;
+ int gap_end = sw_state.num_cases;
+ struct jcf_relocation *reloc;
+ for (reloc = sw_state.cases; reloc != NULL; reloc = reloc->next)
{
- field_op (lhs, OPCODE_putstatic);
+ HOST_WIDE_INT case_value = reloc->offset;
+ while (gap_end < sw_state.num_cases)
+ {
+ struct jcf_relocation *end = relocs[gap_end];
+ if (case_value <= end->offset)
+ break;
+ relocs[gap_start++] = end;
+ gap_end++;
+ }
+ while (gap_start > 0)
+ {
+ struct jcf_relocation *before = relocs[gap_start-1];
+ if (case_value >= before->offset)
+ break;
+ relocs[--gap_end] = before;
+ gap_start--;
+ }
+ relocs[gap_start++] = reloc;
+ /* Note we don't check for duplicates. FIXME! */
+ }
+
+ if (2 * sw_state.num_cases
+ >= sw_state.max_case - sw_state.min_case)
+ { /* Use tableswitch. */
+ int index = 0;
+ RESERVE (13 + 4 * (sw_state.max_case - sw_state.min_case + 1));
+ OP1 (OPCODE_tableswitch);
+ emit_reloc (0, SWITCH_ALIGN_RELOC, NULL, state);
+ emit_switch_reloc (sw_state.default_label, state);
+ OP4 (sw_state.min_case);
+ OP4 (sw_state.max_case);
+ for (i = sw_state.min_case; ; )
+ {
+ reloc = relocs[index];
+ if (i == reloc->offset)
+ {
+ emit_case_reloc (reloc, state);
+ if (i == sw_state.max_case)
+ break;
+ index++;
+ }
+ else
+ emit_switch_reloc (sw_state.default_label, state);
+ i++;
+ }
}
else
- {
- int index = DECL_LOCAL_INDEX (lhs);
- int opcode = adjust_typed_op (TREE_TYPE (lhs));
- if (index <= 3)
+ { /* Use lookupswitch. */
+ RESERVE(9 + 8 * sw_state.num_cases);
+ OP1 (OPCODE_lookupswitch);
+ emit_reloc (0, SWITCH_ALIGN_RELOC, NULL, state);
+ emit_switch_reloc (sw_state.default_label, state);
+ OP4 (sw_state.num_cases);
+ for (i = 0; i < sw_state.num_cases; i++)
{
- RESERVE (1);
- opcode = 59 + 4 * opcode + index;
- OP1 (opcode); /* [ilfda]store_[0123] */
+ struct jcf_relocation *reloc = relocs[i];
+ OP4 (reloc->offset);
+ emit_case_reloc (reloc, state);
}
- else
+ }
+ free (relocs);
+ }
+
+ instruction_last = state->last_block;
+ if (sw_state.default_label->pc < 0)
+ define_jcf_label (sw_state.default_label, state);
+ else /* Force a new block. */
+ sw_state.default_label = get_jcf_label_here (state);
+ /* Now re-arrange the blocks so the switch_instruction
+ comes before the switch_body. */
+ switch_length = state->code_length - switch_instruction->pc;
+ switch_instruction->pc = body_block->pc;
+ instruction_last->next = body_block;
+ instruction_last->v.chunk->next = body_block->v.chunk;
+ expression_last->next = switch_instruction;
+ expression_last->v.chunk->next = switch_instruction->v.chunk;
+ body_last->next = sw_state.default_label;
+ body_last->v.chunk->next = NULL;
+ state->chunk = body_last->v.chunk;
+ for (; body_block != sw_state.default_label; body_block = body_block->next)
+ body_block->pc += switch_length;
+
+ state->sw_state = sw_state.prev;
+ break;
+ }
+
+ case RETURN_EXPR:
+ exp = TREE_OPERAND (exp, 0);
+ if (exp == NULL_TREE)
+ exp = empty_stmt_node;
+ else if (TREE_CODE (exp) != MODIFY_EXPR)
+ abort ();
+ else
+ exp = TREE_OPERAND (exp, 1);
+ generate_bytecode_return (exp, state);
+ break;
+ case LABELED_BLOCK_EXPR:
+ {
+ struct jcf_block *end_label = gen_jcf_label (state);
+ end_label->next = state->labeled_blocks;
+ state->labeled_blocks = end_label;
+ end_label->pc = PENDING_EXIT_PC;
+ end_label->u.labeled_block = exp;
+ if (LABELED_BLOCK_BODY (exp))
+ generate_bytecode_insns (LABELED_BLOCK_BODY (exp), target, state);
+ if (state->labeled_blocks != end_label)
+ abort();
+ state->labeled_blocks = end_label->next;
+ define_jcf_label (end_label, state);
+ }
+ break;
+ case LOOP_EXPR:
+ {
+ tree body = TREE_OPERAND (exp, 0);
+#if 0
+ if (TREE_CODE (body) == COMPOUND_EXPR
+ && TREE_CODE (TREE_OPERAND (body, 0)) == EXIT_EXPR)
+ {
+ /* Optimize: H: if (TEST) GOTO L; BODY; GOTO H; L:
+ to: GOTO L; BODY; L: if (!TEST) GOTO L; */
+ struct jcf_block *head_label;
+ struct jcf_block *body_label;
+ struct jcf_block *end_label = gen_jcf_label (state);
+ struct jcf_block *exit_label = state->labeled_blocks;
+ head_label = gen_jcf_label (state);
+ emit_goto (head_label, state);
+ body_label = get_jcf_label_here (state);
+ generate_bytecode_insns (TREE_OPERAND (body, 1), target, state);
+ define_jcf_label (head_label, state);
+ generate_bytecode_conditional (TREE_OPERAND (body, 0),
+ end_label, body_label, 1, state);
+ define_jcf_label (end_label, state);
+ }
+ else
+#endif
+ {
+ struct jcf_block *head_label = get_jcf_label_here (state);
+ generate_bytecode_insns (body, IGNORE_TARGET, state);
+ emit_goto (head_label, state);
+ }
+ }
+ break;
+ case EXIT_EXPR:
+ {
+ struct jcf_block *label = state->labeled_blocks;
+ struct jcf_block *end_label = gen_jcf_label (state);
+ generate_bytecode_conditional (TREE_OPERAND (exp, 0),
+ label, end_label, 0, state);
+ define_jcf_label (end_label, state);
+ }
+ break;
+ case EXIT_BLOCK_EXPR:
+ {
+ struct jcf_block *label = state->labeled_blocks;
+ if (TREE_OPERAND (exp, 1) != NULL) goto notimpl;
+ while (label->u.labeled_block != TREE_OPERAND (exp, 0))
+ label = label->next;
+ call_cleanups (label, state);
+ emit_goto (label, state);
+ }
+ break;
+
+ case PREDECREMENT_EXPR: value = -1; post_op = 0; goto increment;
+ case PREINCREMENT_EXPR: value = 1; post_op = 0; goto increment;
+ case POSTDECREMENT_EXPR: value = -1; post_op = 1; goto increment;
+ case POSTINCREMENT_EXPR: value = 1; post_op = 1; goto increment;
+ increment:
+
+ exp = TREE_OPERAND (exp, 0);
+ type = TREE_TYPE (exp);
+ size = TYPE_IS_WIDE (type) ? 2 : 1;
+ if ((TREE_CODE (exp) == VAR_DECL || TREE_CODE (exp) == PARM_DECL)
+ && ! TREE_STATIC (exp)
+ && TREE_CODE (type) == INTEGER_TYPE
+ && TYPE_PRECISION (type) == 32)
+ {
+ if (target != IGNORE_TARGET && post_op)
+ emit_load (exp, state);
+ emit_iinc (exp, value, state);
+ if (target != IGNORE_TARGET && ! post_op)
+ emit_load (exp, state);
+ break;
+ }
+ if (TREE_CODE (exp) == COMPONENT_REF)
+ {
+ generate_bytecode_insns (TREE_OPERAND (exp, 0), STACK_TARGET, state);
+ emit_dup (1, 0, state);
+ /* Stack: ..., objectref, objectref. */
+ field_op (TREE_OPERAND (exp, 1), OPCODE_getfield, state);
+ NOTE_PUSH (size-1);
+ /* Stack: ..., objectref, oldvalue. */
+ offset = 1;
+ }
+ else if (TREE_CODE (exp) == ARRAY_REF)
+ {
+ generate_bytecode_insns (TREE_OPERAND (exp, 0), STACK_TARGET, state);
+ generate_bytecode_insns (TREE_OPERAND (exp, 1), STACK_TARGET, state);
+ emit_dup (2, 0, state);
+ /* Stack: ..., array, index, array, index. */
+ jopcode = OPCODE_iaload + adjust_typed_op (TREE_TYPE (exp), 7);
+ RESERVE(1);
+ OP1 (jopcode);
+ NOTE_POP (2-size);
+ /* Stack: ..., array, index, oldvalue. */
+ offset = 2;
+ }
+ else if (TREE_CODE (exp) == VAR_DECL || TREE_CODE (exp) == PARM_DECL)
+ {
+ generate_bytecode_insns (exp, STACK_TARGET, state);
+ /* Stack: ..., oldvalue. */
+ offset = 0;
+ }
+ else
+ abort ();
+
+ if (target != IGNORE_TARGET && post_op)
+ emit_dup (size, offset, state);
+ /* Stack, if ARRAY_REF: ..., [result, ] array, index, oldvalue. */
+ /* Stack, if COMPONENT_REF: ..., [result, ] objectref, oldvalue. */
+ /* Stack, otherwise: ..., [result, ] oldvalue. */
+ if (size == 1)
+ push_int_const (value, state);
+ else
+ push_long_const (value, value >= 0 ? 0 : -1, state);
+ NOTE_PUSH (size);
+ emit_binop (OPCODE_iadd + adjust_typed_op (type, 3), type, state);
+ if (target != IGNORE_TARGET && ! post_op)
+ emit_dup (size, offset, state);
+ /* Stack, if ARRAY_REF: ..., [result, ] array, index, newvalue. */
+ /* Stack, if COMPONENT_REF: ..., [result, ] objectref, newvalue. */
+ /* Stack, otherwise: ..., [result, ] newvalue. */
+ goto finish_assignment;
+
+ case MODIFY_EXPR:
+ {
+ tree lhs = TREE_OPERAND (exp, 0);
+ tree rhs = TREE_OPERAND (exp, 1);
+ int offset = 0;
+
+ /* See if we can use the iinc instruction. */
+ if ((TREE_CODE (lhs) == VAR_DECL || TREE_CODE (lhs) == PARM_DECL)
+ && ! TREE_STATIC (lhs)
+ && TREE_CODE (TREE_TYPE (lhs)) == INTEGER_TYPE
+ && TYPE_PRECISION (TREE_TYPE (lhs)) == 32
+ && (TREE_CODE (rhs) == PLUS_EXPR || TREE_CODE (rhs) == MINUS_EXPR))
+ {
+ tree arg0 = TREE_OPERAND (rhs, 0);
+ tree arg1 = TREE_OPERAND (rhs, 1);
+ HOST_WIDE_INT min_value = -32768;
+ HOST_WIDE_INT max_value = 32767;
+ if (TREE_CODE (rhs) == MINUS_EXPR)
+ {
+ min_value++;
+ max_value++;
+ }
+ else if (arg1 == lhs)
+ {
+ arg0 = arg1;
+ arg1 = TREE_OPERAND (rhs, 0);
+ }
+ if (lhs == arg0 && TREE_CODE (arg1) == INTEGER_CST)
+ {
+ HOST_WIDE_INT hi_value = TREE_INT_CST_HIGH (arg1);
+ value = TREE_INT_CST_LOW (arg1);
+ if ((hi_value == 0 && value <= max_value)
+ || (hi_value == -1 && value >= min_value))
{
- maybe_wide (54 + opcode, index); /* [ilfda]store */
+ if (TREE_CODE (rhs) == MINUS_EXPR)
+ value = -value;
+ emit_iinc (lhs, value, state);
+ break;
}
}
}
+
+ if (TREE_CODE (lhs) == COMPONENT_REF)
+ {
+ generate_bytecode_insns (TREE_OPERAND (lhs, 0),
+ STACK_TARGET, state);
+ offset = 1;
+ }
else if (TREE_CODE (lhs) == ARRAY_REF)
{
- jopcode = OPCODE_iastore + adjust_typed_op (TREE_TYPE (lhs));
- RESERVE(1);
- OP1 (jopcode);
+ generate_bytecode_insns (TREE_OPERAND(lhs, 0),
+ STACK_TARGET, state);
+ generate_bytecode_insns (TREE_OPERAND(lhs, 1),
+ STACK_TARGET, state);
+ offset = 2;
}
else
- fatal ("internal error (bad lhs to MODIFY_EXPR)");
+ offset = 0;
+ generate_bytecode_insns (rhs, STACK_TARGET, state);
+ if (target != IGNORE_TARGET)
+ emit_dup (TYPE_IS_WIDE (type) ? 2 : 1 , offset, state);
+ exp = lhs;
}
+ /* FALLTHOUGH */
+
+ finish_assignment:
+ if (TREE_CODE (exp) == COMPONENT_REF)
+ {
+ tree field = TREE_OPERAND (exp, 1);
+ if (! FIELD_STATIC (field))
+ NOTE_POP (1);
+ field_op (field,
+ FIELD_STATIC (field) ? OPCODE_putstatic : OPCODE_putfield,
+ state);
+
+ NOTE_POP (TYPE_IS_WIDE (TREE_TYPE (field)) ? 2 : 1);
+ }
+ else if (TREE_CODE (exp) == VAR_DECL
+ || TREE_CODE (exp) == PARM_DECL)
+ {
+ if (FIELD_STATIC (exp))
+ {
+ field_op (exp, OPCODE_putstatic, state);
+ NOTE_POP (TYPE_IS_WIDE (TREE_TYPE (exp)) ? 2 : 1);
+ }
+ else
+ emit_store (exp, state);
+ }
+ else if (TREE_CODE (exp) == ARRAY_REF)
+ {
+ jopcode = OPCODE_iastore + adjust_typed_op (TREE_TYPE (exp), 7);
+ RESERVE(1);
+ OP1 (jopcode);
+ NOTE_POP (TYPE_IS_WIDE (TREE_TYPE (exp)) ? 4 : 3);
+ }
+ else
+ fatal ("internal error (bad lhs to MODIFY_EXPR)");
break;
case PLUS_EXPR:
- jopcode = OPCODE_iadd + adjust_typed_op (type);
+ jopcode = OPCODE_iadd;
goto binop;
case MINUS_EXPR:
- jopcode = OPCODE_isub + adjust_typed_op (type);
+ jopcode = OPCODE_isub;
goto binop;
case MULT_EXPR:
- jopcode = OPCODE_imul + adjust_typed_op (type);
+ jopcode = OPCODE_imul;
goto binop;
case TRUNC_DIV_EXPR:
case RDIV_EXPR:
- jopcode = OPCODE_idiv + adjust_typed_op (type);
+ jopcode = OPCODE_idiv;
goto binop;
+ case TRUNC_MOD_EXPR:
+ jopcode = OPCODE_irem;
+ goto binop;
+ case LSHIFT_EXPR: jopcode = OPCODE_ishl; goto binop;
+ case RSHIFT_EXPR: jopcode = OPCODE_ishr; goto binop;
+ case URSHIFT_EXPR: jopcode = OPCODE_iushr; goto binop;
+ case TRUTH_AND_EXPR:
+ case BIT_AND_EXPR: jopcode = OPCODE_iand; goto binop;
+ case TRUTH_OR_EXPR:
+ case BIT_IOR_EXPR: jopcode = OPCODE_ior; goto binop;
+ case TRUTH_XOR_EXPR:
+ case BIT_XOR_EXPR: jopcode = OPCODE_ixor; goto binop;
binop:
- generate_bytecode_insns (method, TREE_OPERAND (exp, 0), target);
- generate_bytecode_insns (method, TREE_OPERAND (exp, 1), target);
+ {
+ tree arg0 = TREE_OPERAND (exp, 0);
+ tree arg1 = TREE_OPERAND (exp, 1);
+ jopcode += adjust_typed_op (type, 3);
+ if (arg0 == arg1 && TREE_CODE (arg0) == SAVE_EXPR)
+ {
+ /* fold may (e.g) convert 2*x to x+x. */
+ generate_bytecode_insns (TREE_OPERAND (arg0, 0), target, state);
+ emit_dup (TYPE_PRECISION (TREE_TYPE (arg0)) > 32 ? 2 : 1, 0, state);
+ }
+ else
+ {
+ generate_bytecode_insns (arg0, target, state);
+ generate_bytecode_insns (arg1, target, state);
+ }
+ /* For most binary operations, both operands and the result have the
+ same type. Shift operations are different. Using arg1's type
+ gets us the correct SP adjustment in all casesd. */
+ if (target == STACK_TARGET)
+ emit_binop (jopcode, TREE_TYPE (arg1), state);
+ break;
+ }
+ case TRUTH_NOT_EXPR:
+ case BIT_NOT_EXPR:
+ generate_bytecode_insns (TREE_OPERAND (exp, 0), target, state);
if (target == STACK_TARGET)
{
- RESERVE(1);
- OP1 (jopcode);
+ int is_long = TYPE_PRECISION (TREE_TYPE (exp)) > 32;
+ push_int_const (TREE_CODE (exp) == BIT_NOT_EXPR ? -1 : 1, state);
+ RESERVE (2);
+ if (is_long)
+ OP1 (OPCODE_i2l);
+ NOTE_PUSH (1 + is_long);
+ OP1 (OPCODE_ixor + is_long);
+ NOTE_POP (1 + is_long);
}
break;
+ case NEGATE_EXPR:
+ jopcode = OPCODE_ineg;
+ jopcode += adjust_typed_op (type, 3);
+ generate_bytecode_insns (TREE_OPERAND (exp, 0), target, state);
+ if (target == STACK_TARGET)
+ emit_unop (jopcode, type, state);
+ break;
+ case INSTANCEOF_EXPR:
+ {
+ int index = find_class_constant (&state->cpool, TREE_OPERAND (exp, 1));
+ generate_bytecode_insns (TREE_OPERAND (exp, 0), target, state);
+ RESERVE (3);
+ OP1 (OPCODE_instanceof);
+ OP2 (index);
+ }
+ break;
+ case CONVERT_EXPR:
+ case NOP_EXPR:
+ case FLOAT_EXPR:
+ case FIX_TRUNC_EXPR:
+ {
+ tree src = TREE_OPERAND (exp, 0);
+ tree src_type = TREE_TYPE (src);
+ tree dst_type = TREE_TYPE (exp);
+ generate_bytecode_insns (TREE_OPERAND (exp, 0), target, state);
+ if (target == IGNORE_TARGET || src_type == dst_type)
+ break;
+ if (TREE_CODE (dst_type) == POINTER_TYPE)
+ {
+ if (TREE_CODE (exp) == CONVERT_EXPR)
+ {
+ int index = find_class_constant (&state->cpool, TREE_TYPE (dst_type));
+ RESERVE (3);
+ OP1 (OPCODE_checkcast);
+ OP2 (index);
+ }
+ }
+ else /* Convert numeric types. */
+ {
+ int wide_src = TYPE_PRECISION (src_type) > 32;
+ int wide_dst = TYPE_PRECISION (dst_type) > 32;
+ NOTE_POP (1 + wide_src);
+ RESERVE (1);
+ if (TREE_CODE (dst_type) == REAL_TYPE)
+ {
+ if (TREE_CODE (src_type) == REAL_TYPE)
+ OP1 (wide_dst ? OPCODE_f2d : OPCODE_d2f);
+ else if (TYPE_PRECISION (src_type) == 64)
+ OP1 (OPCODE_l2f + wide_dst);
+ else
+ OP1 (OPCODE_i2f + wide_dst);
+ }
+ else /* Convert to integral type. */
+ {
+ if (TREE_CODE (src_type) == REAL_TYPE)
+ OP1 (OPCODE_f2i + wide_dst + 3 * wide_src);
+ else if (wide_dst)
+ OP1 (OPCODE_i2l);
+ else if (wide_src)
+ OP1 (OPCODE_l2i);
+ if (TYPE_PRECISION (dst_type) < 32)
+ {
+ RESERVE (1);
+ /* Already converted to int, if needed. */
+ if (TYPE_PRECISION (dst_type) <= 8)
+ OP1 (OPCODE_i2b);
+ else if (TREE_UNSIGNED (dst_type))
+ OP1 (OPCODE_i2c);
+ else
+ OP1 (OPCODE_i2s);
+ }
+ }
+ NOTE_PUSH (1 + wide_dst);
+ }
+ }
+ break;
+
+ case CLEANUP_POINT_EXPR:
+ {
+ struct jcf_block *save_labeled_blocks = state->labeled_blocks;
+ int can_complete = CAN_COMPLETE_NORMALLY (TREE_OPERAND (exp, 0));
+ generate_bytecode_insns (TREE_OPERAND (exp, 0), IGNORE_TARGET, state);
+ if (target != IGNORE_TARGET)
+ abort ();
+ while (state->labeled_blocks != save_labeled_blocks)
+ {
+ struct jcf_block *finished_label = NULL;
+ tree return_link;
+ tree exception_type = build_pointer_type (throwable_type_node);
+ tree exception_decl = build_decl (VAR_DECL, NULL_TREE,
+ exception_type);
+ struct jcf_block *end_label = get_jcf_label_here (state);
+ struct jcf_block *label = state->labeled_blocks;
+ struct jcf_handler *handler;
+ tree cleanup = label->u.labeled_block;
+ state->labeled_blocks = label->next;
+ state->num_finalizers--;
+ if (can_complete)
+ {
+ finished_label = gen_jcf_label (state);
+ emit_jsr (label, state);
+ emit_goto (finished_label, state);
+ if (! CAN_COMPLETE_NORMALLY (cleanup))
+ can_complete = 0;
+ }
+ handler = alloc_handler (label->v.start_label, end_label, state);
+ handler->type = NULL_TREE;
+ localvar_alloc (exception_decl, state);
+ NOTE_PUSH (1);
+ emit_store (exception_decl, state);
+ emit_jsr (label, state);
+ emit_load (exception_decl, state);
+ RESERVE (1);
+ OP1 (OPCODE_athrow);
+ NOTE_POP (1);
+
+ /* The finally block. */
+ return_link = build_decl (VAR_DECL, NULL_TREE,
+ return_address_type_node);
+ define_jcf_label (label, state);
+ NOTE_PUSH (1);
+ localvar_alloc (return_link, state);
+ emit_store (return_link, state);
+ generate_bytecode_insns (cleanup, IGNORE_TARGET, state);
+ maybe_wide (OPCODE_ret, DECL_LOCAL_INDEX (return_link), state);
+ localvar_free (return_link, state);
+ localvar_free (exception_decl, state);
+ if (finished_label != NULL)
+ define_jcf_label (finished_label, state);
+ }
+ }
+ break;
+
+ case WITH_CLEANUP_EXPR:
+ {
+ struct jcf_block *label;
+ generate_bytecode_insns (TREE_OPERAND (exp, 0), IGNORE_TARGET, state);
+ label = gen_jcf_label (state);
+ label->pc = PENDING_CLEANUP_PC;
+ label->next = state->labeled_blocks;
+ state->labeled_blocks = label;
+ state->num_finalizers++;
+ label->u.labeled_block = TREE_OPERAND (exp, 2);
+ label->v.start_label = get_jcf_label_here (state);
+ if (target != IGNORE_TARGET)
+ abort ();
+ }
+ break;
+
+ case TRY_EXPR:
+ {
+ tree try_clause = TREE_OPERAND (exp, 0);
+ struct jcf_block *start_label = get_jcf_label_here (state);
+ struct jcf_block *end_label; /* End of try clause. */
+ struct jcf_block *finished_label = gen_jcf_label (state);
+ tree clause = TREE_OPERAND (exp, 1);
+ if (target != IGNORE_TARGET)
+ abort ();
+ generate_bytecode_insns (try_clause, IGNORE_TARGET, state);
+ end_label = get_jcf_label_here (state);
+ if (CAN_COMPLETE_NORMALLY (try_clause))
+ emit_goto (finished_label, state);
+ while (clause != NULL_TREE)
+ {
+ tree catch_clause = TREE_OPERAND (clause, 0);
+ tree exception_decl = BLOCK_EXPR_DECLS (catch_clause);
+ struct jcf_handler *handler = alloc_handler (start_label, end_label, state);
+ if (exception_decl == NULL_TREE)
+ handler->type = NULL_TREE;
+ else
+ handler->type = TREE_TYPE (TREE_TYPE (exception_decl));
+ generate_bytecode_insns (catch_clause, IGNORE_TARGET, state);
+ clause = TREE_CHAIN (clause);
+ if (CAN_COMPLETE_NORMALLY (catch_clause) && clause != NULL_TREE)
+ emit_goto (finished_label, state);
+ }
+ define_jcf_label (finished_label, state);
+ }
+ break;
+ case TRY_FINALLY_EXPR:
+ {
+ tree try_block = TREE_OPERAND (exp, 0);
+ tree finally = TREE_OPERAND (exp, 1);
+ struct jcf_block *finished_label = gen_jcf_label (state);
+ struct jcf_block *finally_label = gen_jcf_label (state);
+ struct jcf_block *start_label = get_jcf_label_here (state);
+ tree return_link = build_decl (VAR_DECL, NULL_TREE,
+ return_address_type_node);
+ tree exception_type = build_pointer_type (throwable_type_node);
+ tree exception_decl = build_decl (VAR_DECL, NULL_TREE, exception_type);
+ struct jcf_handler *handler;
+
+ finally_label->pc = PENDING_CLEANUP_PC;
+ finally_label->next = state->labeled_blocks;
+ state->labeled_blocks = finally_label;
+ state->num_finalizers++;
+
+ generate_bytecode_insns (try_block, target, state);
+ if (state->labeled_blocks != finally_label)
+ abort();
+ state->labeled_blocks = finally_label->next;
+ emit_jsr (finally_label, state);
+ if (CAN_COMPLETE_NORMALLY (try_block))
+ emit_goto (finished_label, state);
+
+ /* Handle exceptions. */
+ localvar_alloc (return_link, state);
+ handler = alloc_handler (start_label, NULL_TREE, state);
+ handler->end_label = handler->handler_label;
+ handler->type = NULL_TREE;
+ localvar_alloc (exception_decl, state);
+ NOTE_PUSH (1);
+ emit_store (exception_decl, state);
+ emit_jsr (finally_label, state);
+ emit_load (exception_decl, state);
+ RESERVE (1);
+ OP1 (OPCODE_athrow);
+ NOTE_POP (1);
+ localvar_free (exception_decl, state);
+
+ /* The finally block. First save return PC into return_link. */
+ define_jcf_label (finally_label, state);
+ NOTE_PUSH (1);
+ emit_store (return_link, state);
+
+ generate_bytecode_insns (finally, IGNORE_TARGET, state);
+ maybe_wide (OPCODE_ret, DECL_LOCAL_INDEX (return_link), state);
+ localvar_free (return_link, state);
+ define_jcf_label (finished_label, state);
+ }
+ break;
+ case THROW_EXPR:
+ generate_bytecode_insns (TREE_OPERAND (exp, 0), STACK_TARGET, state);
+ RESERVE (1);
+ OP1 (OPCODE_athrow);
+ break;
+ case NEW_ARRAY_INIT:
+ {
+ tree values = CONSTRUCTOR_ELTS (TREE_OPERAND (exp, 0));
+ tree array_type = TREE_TYPE (TREE_TYPE (exp));
+ tree element_type = TYPE_ARRAY_ELEMENT (array_type);
+ HOST_WIDE_INT length = java_array_type_length (array_type);
+ if (target == IGNORE_TARGET)
+ {
+ for ( ; values != NULL_TREE; values = TREE_CHAIN (values))
+ generate_bytecode_insns (TREE_VALUE (values), target, state);
+ break;
+ }
+ push_int_const (length, state);
+ NOTE_PUSH (1);
+ RESERVE (3);
+ if (JPRIMITIVE_TYPE_P (element_type))
+ {
+ int atype = encode_newarray_type (element_type);
+ OP1 (OPCODE_newarray);
+ OP1 (atype);
+ }
+ else
+ {
+ int index = find_class_constant (&state->cpool,
+ TREE_TYPE (element_type));
+ OP1 (OPCODE_anewarray);
+ OP2 (index);
+ }
+ offset = 0;
+ jopcode = OPCODE_iastore + adjust_typed_op (element_type, 7);
+ for ( ; values != NULL_TREE; values = TREE_CHAIN (values), offset++)
+ {
+ int save_SP = state->code_SP;
+ emit_dup (1, 0, state);
+ push_int_const (offset, state);
+ NOTE_PUSH (1);
+ generate_bytecode_insns (TREE_VALUE (values), STACK_TARGET, state);
+ RESERVE (1);
+ OP1 (jopcode);
+ state->code_SP = save_SP;
+ }
+ }
+ break;
+ case NEW_CLASS_EXPR:
+ {
+ tree class = TREE_TYPE (TREE_TYPE (exp));
+ int need_result = target != IGNORE_TARGET;
+ int index = find_class_constant (&state->cpool, class);
+ RESERVE (4);
+ OP1 (OPCODE_new);
+ OP2 (index);
+ if (need_result)
+ OP1 (OPCODE_dup);
+ NOTE_PUSH (1 + need_result);
+ }
+ /* ... fall though ... */
case CALL_EXPR:
{
- tree t;
- for (t = TREE_OPERAND (exp, 1); t != NULL_TREE; t = TREE_CHAIN (t))
+ tree f = TREE_OPERAND (exp, 0);
+ tree x = TREE_OPERAND (exp, 1);
+ int save_SP = state->code_SP;
+ int nargs;
+ if (TREE_CODE (f) == ADDR_EXPR)
+ f = TREE_OPERAND (f, 0);
+ if (f == soft_newarray_node)
{
- generate_bytecode_insns (method, TREE_VALUE (t), STACK_TARGET);
+ int type_code = TREE_INT_CST_LOW (TREE_VALUE (x));
+ generate_bytecode_insns (TREE_VALUE (TREE_CHAIN (x)),
+ STACK_TARGET, state);
+ RESERVE (2);
+ OP1 (OPCODE_newarray);
+ OP1 (type_code);
+ break;
}
- t = TREE_OPERAND (exp, 0);
- if (TREE_CODE (t) == FUNCTION_DECL)
+ else if (f == soft_multianewarray_node)
{
- int index = find_methodref_index (code_cpool, t);
+ int ndims;
+ int idim;
+ int index = find_class_constant (&state->cpool,
+ TREE_TYPE (TREE_TYPE (exp)));
+ x = TREE_CHAIN (x); /* Skip class argument. */
+ ndims = TREE_INT_CST_LOW (TREE_VALUE (x));
+ for (idim = ndims; --idim >= 0; )
+ {
+ x = TREE_CHAIN (x);
+ generate_bytecode_insns (TREE_VALUE (x), STACK_TARGET, state);
+ }
+ RESERVE (4);
+ OP1 (OPCODE_multianewarray);
+ OP2 (index);
+ OP1 (ndims);
+ break;
+ }
+ else if (f == soft_anewarray_node)
+ {
+ tree cl = TYPE_ARRAY_ELEMENT (TREE_TYPE (TREE_TYPE (exp)));
+ int index = find_class_constant (&state->cpool, TREE_TYPE (cl));
+ generate_bytecode_insns (TREE_VALUE (x), STACK_TARGET, state);
RESERVE (3);
- if (DECL_CONSTRUCTOR_P (t))
- OP1 (OPCODE_invokespecial);
- else if (METHOD_STATIC (t))
+ OP1 (OPCODE_anewarray);
+ OP2 (index);
+ break;
+ }
+ else if (f == soft_monitorenter_node
+ || f == soft_monitorexit_node
+ || f == throw_node)
+ {
+ if (f == soft_monitorenter_node)
+ op = OPCODE_monitorenter;
+ else if (f == soft_monitorexit_node)
+ op = OPCODE_monitorexit;
+ else
+ op = OPCODE_athrow;
+ generate_bytecode_insns (TREE_VALUE (x), STACK_TARGET, state);
+ RESERVE (1);
+ OP1 (op);
+ NOTE_POP (1);
+ break;
+ }
+ else if (exp == soft_exceptioninfo_call_node)
+ {
+ NOTE_PUSH (1); /* Pushed by exception system. */
+ break;
+ }
+ for ( ; x != NULL_TREE; x = TREE_CHAIN (x))
+ {
+ generate_bytecode_insns (TREE_VALUE (x), STACK_TARGET, state);
+ }
+ nargs = state->code_SP - save_SP;
+ state->code_SP = save_SP;
+ if (f == soft_fmod_node)
+ {
+ RESERVE (1);
+ OP1 (OPCODE_drem);
+ NOTE_PUSH (2);
+ break;
+ }
+ if (TREE_CODE (exp) == NEW_CLASS_EXPR)
+ NOTE_POP (1); /* Pop implicit this. */
+ if (TREE_CODE (f) == FUNCTION_DECL && DECL_CONTEXT (f) != NULL_TREE)
+ {
+ int index = find_methodref_index (&state->cpool, f);
+ int interface = 0;
+ RESERVE (5);
+ if (METHOD_STATIC (f))
OP1 (OPCODE_invokestatic);
+ else if (DECL_CONSTRUCTOR_P (f) || CALL_USING_SUPER (exp)
+ || METHOD_PRIVATE (f))
+ OP1 (OPCODE_invokespecial);
+ else if (CLASS_INTERFACE (TYPE_NAME (DECL_CONTEXT (f))))
+ {
+ OP1 (OPCODE_invokeinterface);
+ interface = 1;
+ }
else
OP1 (OPCODE_invokevirtual);
OP2 (index);
+ f = TREE_TYPE (TREE_TYPE (f));
+ if (TREE_CODE (f) != VOID_TYPE)
+ {
+ int size = TYPE_IS_WIDE (f) ? 2 : 1;
+ if (target == IGNORE_TARGET)
+ emit_pop (size, state);
+ else
+ NOTE_PUSH (size);
+ }
+ if (interface)
+ {
+ OP1 (nargs);
+ OP1 (0);
+ }
break;
}
}
/* fall through */
+ notimpl:
default:
- error("internal error - tree code not implemented: ", TREE_CODE (exp));
+ error("internal error - tree code not implemented: %s",
+ tree_code_name [(int) TREE_CODE (exp)]);
}
}
+static void
+perform_relocations (state)
+ struct jcf_partial *state;
+{
+ struct jcf_block *block;
+ struct jcf_relocation *reloc;
+ int pc;
+ int shrink;
+
+ /* Before we start, the pc field of each block is an upper bound on
+ the block's start pc (it may be less, if previous blocks need less
+ than their maximum).
+
+ The minimum size of each block is in the block's chunk->size. */
+
+ /* First, figure out the actual locations of each block. */
+ pc = 0;
+ shrink = 0;
+ for (block = state->blocks; block != NULL; block = block->next)
+ {
+ int block_size = block->v.chunk->size;
+
+ block->pc = pc;
+
+ /* Optimize GOTO L; L: by getting rid of the redundant goto.
+ Assumes relocations are in reverse order. */
+ reloc = block->u.relocations;
+ while (reloc != NULL
+ && reloc->kind == OPCODE_goto_w
+ && reloc->label->pc == block->next->pc
+ && reloc->offset + 2 == block_size)
+ {
+ reloc = reloc->next;
+ block->u.relocations = reloc;
+ block->v.chunk->size -= 3;
+ block_size -= 3;
+ shrink += 3;
+ }
+
+ for (reloc = block->u.relocations; reloc != NULL; reloc = reloc->next)
+ {
+ if (reloc->kind == SWITCH_ALIGN_RELOC)
+ {
+ /* We assume this is the first relocation in this block,
+ so we know its final pc. */
+ int where = pc + reloc->offset;
+ int pad = ((where + 3) & ~3) - where;
+ block_size += pad;
+ }
+ else if (reloc->kind < -1 || reloc->kind > BLOCK_START_RELOC)
+ {
+ int delta = reloc->label->pc - (pc + reloc->offset - 1);
+ int expand = reloc->kind > 0 ? 2 : 5;
+
+ if (delta > 0)
+ delta -= shrink;
+ if (delta >= -32768 && delta <= 32767)
+ {
+ shrink += expand;
+ reloc->kind = -1;
+ }
+ else
+ block_size += expand;
+ }
+ }
+ pc += block_size;
+ }
+
+ for (block = state->blocks; block != NULL; block = block->next)
+ {
+ struct chunk *chunk = block->v.chunk;
+ int old_size = chunk->size;
+ int next_pc = block->next == NULL ? pc : block->next->pc;
+ int new_size = next_pc - block->pc;
+ unsigned char *new_ptr;
+ unsigned char *old_buffer = chunk->data;
+ unsigned char *old_ptr = old_buffer + old_size;
+ if (new_size != old_size)
+ {
+ chunk->data = (unsigned char *)
+ obstack_alloc (state->chunk_obstack, new_size);
+ chunk->size = new_size;
+ }
+ new_ptr = chunk->data + new_size;
+
+ /* We do the relocations from back to front, because
+ the relocations are in reverse order. */
+ for (reloc = block->u.relocations; ; reloc = reloc->next)
+ {
+ /* new_ptr and old_ptr point into the old and new buffers,
+ respectively. (If no relocations cause the buffer to
+ grow, the buffer will be the same buffer, and new_ptr==old_ptr.)
+ The bytes at higher adress have been copied and relocations
+ handled; those at lower addresses remain to process. */
+
+ /* Lower old index of piece to be copied with no relocation.
+ I.e. high index of the first piece that does need relocation. */
+ int start = reloc == NULL ? 0
+ : reloc->kind == SWITCH_ALIGN_RELOC ? reloc->offset
+ : (reloc->kind == 0 || reloc->kind == BLOCK_START_RELOC)
+ ? reloc->offset + 4
+ : reloc->offset + 2;
+ int32 value;
+ int new_offset;
+ int n = (old_ptr - old_buffer) - start;
+ new_ptr -= n;
+ old_ptr -= n;
+ if (n > 0)
+ memcpy (new_ptr, old_ptr, n);
+ if (old_ptr == old_buffer)
+ break;
+
+ new_offset = new_ptr - chunk->data;
+ new_offset -= (reloc->kind == -1 ? 2 : 4);
+ if (reloc->kind == 0)
+ {
+ old_ptr -= 4;
+ value = GET_u4 (old_ptr);
+ }
+ else if (reloc->kind == BLOCK_START_RELOC)
+ {
+ old_ptr -= 4;
+ value = 0;
+ new_offset = 0;
+ }
+ else if (reloc->kind == SWITCH_ALIGN_RELOC)
+ {
+ int where = block->pc + reloc->offset;
+ int pad = ((where + 3) & ~3) - where;
+ while (--pad >= 0)
+ *--new_ptr = 0;
+ continue;
+ }
+ else
+ {
+ old_ptr -= 2;
+ value = GET_u2 (old_ptr);
+ }
+ value += reloc->label->pc - (block->pc + new_offset);
+ *--new_ptr = (unsigned char) value; value >>= 8;
+ *--new_ptr = (unsigned char) value; value >>= 8;
+ if (reloc->kind != -1)
+ {
+ *--new_ptr = (unsigned char) value; value >>= 8;
+ *--new_ptr = (unsigned char) value;
+ }
+ if (reloc->kind > BLOCK_START_RELOC)
+ {
+ /* Convert: OP TARGET to: OP_w TARGET; (OP is goto or jsr). */
+ --old_ptr;
+ *--new_ptr = reloc->kind;
+ }
+ else if (reloc->kind < -1)
+ {
+ /* Convert: ifCOND TARGET to: ifNCOND T; goto_w TARGET; T: */
+ --old_ptr;
+ *--new_ptr = OPCODE_goto_w;
+ *--new_ptr = 3;
+ *--new_ptr = 0;
+ *--new_ptr = - reloc->kind;
+ }
+ }
+ if (new_ptr != chunk->data)
+ fatal ("internal error - perform_relocations");
+ }
+ state->code_length = pc;
+}
+
+static void
+init_jcf_state (state, work)
+ struct jcf_partial *state;
+ struct obstack *work;
+{
+ state->chunk_obstack = work;
+ state->first = state->chunk = NULL;
+ CPOOL_INIT (&state->cpool);
+ BUFFER_INIT (&state->localvars);
+ BUFFER_INIT (&state->bytecode);
+}
+
+static void
+init_jcf_method (state, method)
+ struct jcf_partial *state;
+ tree method;
+{
+ state->current_method = method;
+ state->blocks = state->last_block = NULL;
+ state->linenumber_count = 0;
+ state->first_lvar = state->last_lvar = NULL;
+ state->lvar_count = 0;
+ state->labeled_blocks = NULL;
+ state->code_length = 0;
+ BUFFER_RESET (&state->bytecode);
+ BUFFER_RESET (&state->localvars);
+ state->code_SP = 0;
+ state->code_SP_max = 0;
+ state->handlers = NULL;
+ state->last_handler = NULL;
+ state->num_handlers = 0;
+ state->num_finalizers = 0;
+ state->return_value_decl = NULL_TREE;
+}
+
+static void
+release_jcf_state (state)
+ struct jcf_partial *state;
+{
+ CPOOL_FINISH (&state->cpool);
+ obstack_free (state->chunk_obstack, state->first);
+}
+
/* Generate and return a list of chunks containing the class CLAS
in the .class file representation. The list can be written to a
.class file using write_chunks. Allocate chunks from obstack WORK. */
-/* Currently does not write any attributes i.e. no code. */
-
-struct chunk *
-generate_classfile (clas, work)
+static struct chunk *
+generate_classfile (clas, state)
tree clas;
- struct obstack *work;
+ struct jcf_partial *state;
{
- CPool cpool;
- struct chunk head;
- struct chunk *chunk;
struct chunk *cpool_chunk;
+ char *source_file;
char *ptr;
int i;
char *fields_count_ptr;
int fields_count = 0;
char *methods_count_ptr;
int methods_count = 0;
+ static tree SourceFile_node = NULL_TREE;
tree part;
int total_supers
= clas == object_type_node ? 0
: TREE_VEC_LENGTH (TYPE_BINFO_BASETYPES (clas));
-
- chunk = alloc_chunk (&head, NULL, 8, work);
- ptr = chunk->data;
+
+ ptr = append_chunk (NULL, 8, state);
PUT4 (0xCafeBabe); /* Magic number */
PUT2 (3); /* Minor version */
PUT2 (45); /* Major version */
- CPOOL_INIT(&cpool);
- cpool_chunk = chunk = alloc_chunk (chunk, NULL, 0, work);
+ append_chunk (NULL, 0, state);
+ cpool_chunk = state->chunk;
/* Next allocate the chunk containing acces_flags through fields_counr. */
if (clas == object_type_node)
i = 10;
else
i = 8 + 2 * total_supers;
- chunk = alloc_chunk (chunk, NULL, i, work);
- ptr = chunk->data;
- i = get_access_flags (TYPE_NAME (clas)); PUT2 (i); /* acces_flags */
- i = find_class_constant (&cpool, clas); PUT2 (i); /* this_class */
+ ptr = append_chunk (NULL, i, state);
+ i = get_access_flags (TYPE_NAME (clas));
+ if (! (i & ACC_INTERFACE))
+ i |= ACC_SUPER;
+ PUT2 (i); /* acces_flags */
+ i = find_class_constant (&state->cpool, clas); PUT2 (i); /* this_class */
if (clas == object_type_node)
{
PUT2(0); /* super_class */
@@ -791,12 +2737,13 @@ generate_classfile (clas, work)
{
tree basetypes = TYPE_BINFO_BASETYPES (clas);
tree base = BINFO_TYPE (TREE_VEC_ELT (basetypes, 0));
- int j = find_class_constant (&cpool, base); PUT2 (j); /* super_class */
+ int j = find_class_constant (&state->cpool, base);
+ PUT2 (j); /* super_class */
PUT2 (total_supers - 1); /* interfaces_count */
for (i = 1; i < total_supers; i++)
{
base = BINFO_TYPE (TREE_VEC_ELT (basetypes, i));
- j = find_class_constant (&cpool, base);
+ j = find_class_constant (&state->cpool, base);
PUT2 (j);
}
}
@@ -804,143 +2751,289 @@ generate_classfile (clas, work)
for (part = TYPE_FIELDS (clas); part; part = TREE_CHAIN (part))
{
- if (DECL_NAME (part) == NULL_TREE)
+ int have_value;
+ if (DECL_NAME (part) == NULL_TREE || DECL_ARTIFICIAL (part))
continue;
- chunk = alloc_chunk (chunk, NULL, 8, work);
- ptr = chunk->data;
+ ptr = append_chunk (NULL, 8, state);
i = get_access_flags (part); PUT2 (i);
- i = find_utf8_constant (&cpool, DECL_NAME (part)); PUT2 (i);
- i = find_utf8_constant (&cpool, build_java_signature (TREE_TYPE (part)));
+ i = find_utf8_constant (&state->cpool, DECL_NAME (part)); PUT2 (i);
+ i = find_utf8_constant (&state->cpool, build_java_signature (TREE_TYPE (part)));
PUT2(i);
- PUT2 (0); /* attributes_count */
- /* FIXME - emit ConstantValue attribute when appropriate */
+ have_value = DECL_INITIAL (part) != NULL_TREE && FIELD_STATIC (part);
+ PUT2 (have_value); /* attributes_count */
+ if (have_value)
+ {
+ tree init = DECL_INITIAL (part);
+ static tree ConstantValue_node = NULL_TREE;
+ ptr = append_chunk (NULL, 8, state);
+ if (ConstantValue_node == NULL_TREE)
+ ConstantValue_node = get_identifier ("ConstantValue");
+ i = find_utf8_constant (&state->cpool, ConstantValue_node);
+ PUT2 (i); /* attribute_name_index */
+ PUT4 (2); /* attribute_length */
+ i = find_constant_index (init, state); PUT2 (i);
+ }
fields_count++;
}
ptr = fields_count_ptr; PUT2 (fields_count);
- chunk = alloc_chunk (chunk, NULL, 2, work);
- ptr = methods_count_ptr = chunk->data;
+ ptr = methods_count_ptr = append_chunk (NULL, 2, state);
PUT2 (0);
for (part = TYPE_METHODS (clas); part; part = TREE_CHAIN (part))
{
- tree body = BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (part));
- int linenumber_size; /* 4 * number of line number entries */
- chunk = alloc_chunk (chunk, NULL, 8, work);
- ptr = chunk->data;
+ struct jcf_block *block;
+ tree function_body = DECL_FUNCTION_BODY (part);
+ tree body = function_body == NULL_TREE ? NULL_TREE
+ : BLOCK_EXPR_BODY (function_body);
+ tree name = DECL_CONSTRUCTOR_P (part) ? init_identifier_node
+ : DECL_NAME (part);
+ tree type = TREE_TYPE (part);
+ tree save_function = current_function_decl;
+ current_function_decl = part;
+ ptr = append_chunk (NULL, 8, state);
i = get_access_flags (part); PUT2 (i);
- i = find_utf8_constant (&cpool, DECL_NAME (part)); PUT2 (i);
- i = find_utf8_constant (&cpool, build_java_signature (TREE_TYPE (part)));
+ i = find_utf8_constant (&state->cpool, name); PUT2 (i);
+ i = find_utf8_constant (&state->cpool, build_java_signature (type));
PUT2 (i);
- PUT2 (body != NULL_TREE ? 1 : 0); /* attributes_count */
+ i = (body != NULL_TREE) + (DECL_FUNCTION_THROWS (part) != NULL_TREE);
+ PUT2 (i); /* attributes_count */
if (body != NULL_TREE)
{
int code_attributes_count = 0;
- int linenumber_size; /* 4 * number of line number entries */
- int localvartable_size; /* 10 * number of local variable entries */
static tree Code_node = NULL_TREE;
tree t;
char *attr_len_ptr;
- int code_length;
+ struct jcf_handler *handler;
if (Code_node == NULL_TREE)
Code_node = get_identifier ("Code");
- chunk = alloc_chunk (chunk, NULL, 14, work);
- ptr = chunk->data;
- i = find_utf8_constant (&cpool, Code_node); PUT2 (i);
+ ptr = append_chunk (NULL, 14, state);
+ i = find_utf8_constant (&state->cpool, Code_node); PUT2 (i);
attr_len_ptr = ptr;
- BUFFER_RESET (&bytecode);
- BUFFER_RESET (&localvartable);
- BUFFER_RESET (&linenumbers);
- BUFFER_RESET (&localvars);
- code_SP = 0;
- code_SP_max = 0;
- code_cpool = &cpool;
+ init_jcf_method (state, part);
+ get_jcf_label_here (state); /* Force a first block. */
for (t = DECL_ARGUMENTS (part); t != NULL_TREE; t = TREE_CHAIN (t))
- localvar_alloc (t, 0);
- generate_bytecode_insns (part, body, IGNORE_TARGET);
- code_length = PC;
+ localvar_alloc (t, state);
+ generate_bytecode_insns (body, IGNORE_TARGET, state);
+ if (CAN_COMPLETE_NORMALLY (body))
+ {
+ if (TREE_CODE (TREE_TYPE (type)) != VOID_TYPE)
+ abort();
+ RESERVE (1);
+ OP1 (OPCODE_return);
+ }
for (t = DECL_ARGUMENTS (part); t != NULL_TREE; t = TREE_CHAIN (t))
- localvar_free (t, code_length);
- linenumber_size = BUFFER_LENGTH (&linenumbers);
- localvartable_size = BUFFER_LENGTH (&localvartable);
- chunk = alloc_chunk (chunk, NULL, code_length, work);
- bcopy (bytecode.data, chunk->data, code_length);
+ localvar_free (t, state);
+ if (state->return_value_decl != NULL_TREE)
+ localvar_free (state->return_value_decl, state);
+ finish_jcf_block (state);
+ perform_relocations (state);
+
ptr = attr_len_ptr;
- i = 8 + code_length + 4;
- if (linenumber_size > 0)
+ i = 8 + state->code_length + 4 + 8 * state->num_handlers;
+ if (state->linenumber_count > 0)
{
code_attributes_count++;
- i += 8 + linenumber_size;
+ i += 8 + 4 * state->linenumber_count;
}
- if (localvartable_size > 0)
+ if (state->lvar_count > 0)
{
code_attributes_count++;
- i += 8 + localvartable_size;
+ i += 8 + 10 * state->lvar_count;
}
PUT4 (i); /* attribute_length */
- PUT2 (code_SP_max); /* max_stack */
+ PUT2 (state->code_SP_max); /* max_stack */
PUT2 (localvar_max); /* max_locals */
- PUT4 (code_length);
- chunk = alloc_chunk (chunk, NULL, 4, work);
- ptr = chunk->data;
- PUT2 (0); /* exception_table_length */
+ PUT4 (state->code_length);
+
+ /* Emit the exception table. */
+ ptr = append_chunk (NULL, 2 + 8 * state->num_handlers, state);
+ PUT2 (state->num_handlers); /* exception_table_length */
+ handler = state->handlers;
+ for (; handler != NULL; handler = handler->next)
+ {
+ int type_index;
+ PUT2 (handler->start_label->pc);
+ PUT2 (handler->end_label->pc);
+ PUT2 (handler->handler_label->pc);
+ if (handler->type == NULL_TREE)
+ type_index = 0;
+ else
+ type_index = find_class_constant (&state->cpool,
+ handler->type);
+ PUT2 (type_index);
+ }
+
+ ptr = append_chunk (NULL, 2, state);
PUT2 (code_attributes_count);
/* Write the LineNumberTable attribute. */
- if (linenumber_size > 0)
+ if (state->linenumber_count > 0)
{
static tree LineNumberTable_node = NULL_TREE;
- chunk = alloc_chunk (chunk, NULL, 8 + linenumber_size, work);
- ptr = chunk->data;
+ ptr = append_chunk (NULL, 8 + 4 * state->linenumber_count, state);
if (LineNumberTable_node == NULL_TREE)
LineNumberTable_node = get_identifier ("LineNumberTable");
- i = find_utf8_constant (&cpool, LineNumberTable_node);
+ i = find_utf8_constant (&state->cpool, LineNumberTable_node);
PUT2 (i); /* attribute_name_index */
- i = 2 + linenumber_size; PUT4 (i); /* attribute_length */
- i = linenumber_size >> 2; PUT2 (i);
- PUTN (linenumbers.data, linenumber_size);
+ i = 2+4*state->linenumber_count; PUT4(i); /* attribute_length */
+ i = state->linenumber_count; PUT2 (i);
+ for (block = state->blocks; block != NULL; block = block->next)
+ {
+ int line = block->linenumber;
+ if (line > 0)
+ {
+ PUT2 (block->pc);
+ PUT2 (line);
+ }
+ }
}
/* Write the LocalVariableTable attribute. */
- if (localvartable_size > 0)
+ if (state->lvar_count > 0)
{
static tree LocalVariableTable_node = NULL_TREE;
- chunk = alloc_chunk (chunk, NULL, 8 + localvartable_size, work);
- ptr = chunk->data;
+ struct localvar_info *lvar = state->first_lvar;
+ ptr = append_chunk (NULL, 8 + 10 * state->lvar_count, state);
if (LocalVariableTable_node == NULL_TREE)
LocalVariableTable_node = get_identifier("LocalVariableTable");
- i = find_utf8_constant (&cpool, LocalVariableTable_node);
+ i = find_utf8_constant (&state->cpool, LocalVariableTable_node);
PUT2 (i); /* attribute_name_index */
- i = 2 + localvartable_size; PUT4 (i); /* attribute_length */
- i = localvartable_size / 10; PUT2 (i);
- PUTN (localvartable.data, localvartable_size);
+ i = 2 + 10 * state->lvar_count; PUT4 (i); /* attribute_length */
+ i = state->lvar_count; PUT2 (i);
+ for ( ; lvar != NULL; lvar = lvar->next)
+ {
+ tree name = DECL_NAME (lvar->decl);
+ tree sig = build_java_signature (TREE_TYPE (lvar->decl));
+ i = lvar->start_label->pc; PUT2 (i);
+ i = lvar->end_label->pc - i; PUT2 (i);
+ i = find_utf8_constant (&state->cpool, name); PUT2 (i);
+ i = find_utf8_constant (&state->cpool, sig); PUT2 (i);
+ i = DECL_LOCAL_INDEX (lvar->decl); PUT2 (i);
+ }
+ }
+ }
+ if (DECL_FUNCTION_THROWS (part) != NULL_TREE)
+ {
+ tree t = DECL_FUNCTION_THROWS (part);
+ int throws_count = list_length (t);
+ static tree Exceptions_node = NULL_TREE;
+ if (Exceptions_node == NULL_TREE)
+ Exceptions_node = get_identifier ("Exceptions");
+ ptr = append_chunk (NULL, 8 + 2 * throws_count, state);
+ i = find_utf8_constant (&state->cpool, Exceptions_node);
+ PUT2 (i); /* attribute_name_index */
+ i = 2 + 2 * throws_count; PUT4(i); /* attribute_length */
+ i = throws_count; PUT2 (i);
+ for (; t != NULL_TREE; t = TREE_CHAIN (t))
+ {
+ i = find_class_constant (&state->cpool, TREE_VALUE (t));
+ PUT2 (i);
}
}
methods_count++;
+ current_function_decl = save_function;
}
ptr = methods_count_ptr; PUT2 (methods_count);
- chunk = alloc_chunk (chunk, NULL, 2, work);
- ptr = chunk->data;
- PUT2 (0); /* attributes_count */
+ source_file = DECL_SOURCE_FILE (TYPE_NAME (clas));
+ for (ptr = source_file; ; ptr++)
+ {
+ char ch = *ptr;
+ if (ch == '\0')
+ break;
+ if (ch == '/' || ch == '\\')
+ source_file = ptr+1;
+ }
+ ptr = append_chunk (NULL, 10, state);
+ PUT2 (1); /* attributes_count */
+
+ /* generate the SourceFile attribute. */
+ if (SourceFile_node == NULL_TREE)
+ SourceFile_node = get_identifier ("SourceFile");
+ i = find_utf8_constant (&state->cpool, SourceFile_node);
+ PUT2 (i); /* attribute_name_index */
+ PUT4 (2);
+ i = find_utf8_constant (&state->cpool, get_identifier (source_file));
+ PUT2 (i);
/* New finally generate the contents of the constant pool chunk. */
- i = count_constant_pool_bytes (&cpool);
- ptr = obstack_alloc (work, i);
+ i = count_constant_pool_bytes (&state->cpool);
+ ptr = obstack_alloc (state->chunk_obstack, i);
cpool_chunk->data = ptr;
cpool_chunk->size = i;
- write_constant_pool (&cpool, ptr, i);
- CPOOL_FINISH (&cpool);
- return head.next;
+ write_constant_pool (&state->cpool, ptr, i);
+ return state->first;
}
-char*
+static char *
make_class_file_name (clas)
tree clas;
{
- /* Should prepend an output directly, but need an option to specify it. */
- return IDENTIFIER_POINTER (identifier_subst (DECL_NAME (TYPE_NAME (clas)),
- "", '.', '/', ".class"));
+ const char *dname, *slash;
+ char *cname, *r;
+ struct stat sb;
+
+ cname = IDENTIFIER_POINTER (identifier_subst (DECL_NAME (TYPE_NAME (clas)),
+ "", '.', DIR_SEPARATOR,
+ ".class"));
+ if (jcf_write_base_directory == NULL)
+ {
+ /* Make sure we put the class file into the .java file's
+ directory, and not into some subdirectory thereof. */
+ char *t;
+ dname = DECL_SOURCE_FILE (TYPE_NAME (clas));
+ slash = strrchr (dname, DIR_SEPARATOR);
+ if (! slash)
+ {
+ dname = ".";
+ slash = dname + 1;
+ }
+ t = strrchr (cname, DIR_SEPARATOR);
+ if (t)
+ cname = t + 1;
+ }
+ else
+ {
+ dname = jcf_write_base_directory;
+ slash = dname + strlen (dname);
+ }
+
+ r = xmalloc (slash - dname + strlen (cname) + 2);
+ strncpy (r, dname, slash - dname);
+ r[slash - dname] = DIR_SEPARATOR;
+ strcpy (&r[slash - dname + 1], cname);
+
+ /* We try to make new directories when we need them. We only do
+ this for directories which "might not" exist. For instance, we
+ assume the `-d' directory exists, but we don't assume that any
+ subdirectory below it exists. It might be worthwhile to keep
+ track of which directories we've created to avoid gratuitous
+ stat()s. */
+ dname = r + (slash - dname) + 1;
+ while (1)
+ {
+ cname = strchr (dname, DIR_SEPARATOR);
+ if (cname == NULL)
+ break;
+ *cname = '\0';
+ if (stat (r, &sb) == -1)
+ {
+ /* Try to make it. */
+ if (mkdir (r, 0755) == -1)
+ {
+ fatal ("failed to create directory `%s'", r);
+ free (r);
+ return NULL;
+ }
+ }
+ *cname = DIR_SEPARATOR;
+ /* Skip consecutive separators. */
+ for (dname = cname + 1; *dname && *dname == DIR_SEPARATOR; ++dname)
+ ;
+ }
+
+ return r;
}
/* Write out the contens of a class (RECORD_TYPE) CLAS, as a .class file.
@@ -951,14 +3044,27 @@ write_classfile (clas)
tree clas;
{
struct obstack *work = &temporary_obstack;
+ struct jcf_partial state[1];
char *class_file_name = make_class_file_name (clas);
struct chunk *chunks;
- FILE* stream = fopen (class_file_name, "wb");
- if (stream == NULL)
- fatal ("failed to open `%s' for writing", class_file_name);
- chunks = generate_classfile (clas, work);
- write_chunks (stream, chunks);
- if (fclose (stream))
- fatal ("failed to close after writing `%s'", class_file_name);
- obstack_free (work, chunks);
+
+ if (class_file_name != NULL)
+ {
+ FILE* stream = fopen (class_file_name, "wb");
+ if (stream == NULL)
+ fatal ("failed to open `%s' for writing", class_file_name);
+ jcf_dependency_add_target (class_file_name);
+ init_jcf_state (state, work);
+ chunks = generate_classfile (clas, state);
+ write_chunks (stream, chunks);
+ if (fclose (stream))
+ fatal ("failed to close after writing `%s'", class_file_name);
+ free (class_file_name);
+ }
+ release_jcf_state (state);
}
+
+/* TODO:
+ string concatenation
+ synchronized statement
+ */
diff --git a/gcc/java/jcf.h b/gcc/java/jcf.h
index 5e82387ca15..c8ab62b2596 100644
--- a/gcc/java/jcf.h
+++ b/gcc/java/jcf.h
@@ -1,6 +1,6 @@
/* Utility macros to read Java(TM) .class files and byte codes.
- Copyright (C) 1996 Free Software Foundation, Inc.
+ Copyright (C) 1996, 97-98, 1999 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
@@ -35,7 +35,6 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */
#define PTR char *
#define AND ;
#define DEFUN(name, arglist, args) name arglist args;
-#define inline static
#endif
#endif /* !DEFUN */
@@ -222,11 +221,10 @@ typedef struct JCF {
#define CONSTANT_Utf8 1
#define CONSTANT_Unicode 2
-extern char *classpath;
#define DEFAULT_CLASS_PATH "."
extern char *find_class PROTO ((const char *, int, JCF*, int));
-extern char *find_classfile PROTO ((char *, JCF*));
+extern char *find_classfile PROTO ((char *, JCF*, const char *));
extern int jcf_filbuf_from_stdio PROTO ((JCF *jcf, int count));
extern void jcf_out_of_synch PROTO((JCF *));
extern int jcf_unexpected_eof PROTO ((JCF*, int));
@@ -243,13 +241,15 @@ extern int jcf_unexpected_eof PROTO ((JCF*, int));
? (((PTR)[-2] & 0x1F) << 6) + ((PTR)[-1] & 0x3F) \
: (*(PTR) & 0xF0) == 0xE0 && ((PTR) += 3) <= (LIMIT) \
&& ((PTR)[-2] & 0xC0) == 0x80 && ((PTR)[-1] & 0xC0) == 0x80 \
- ? (((PTR)[-3]&0x1F) << 12) + (((PTR)[-2]&0x3F) << 6) + ((PTR)[-1]&0x3F) \
+ ? (((PTR)[-3]&0x0F) << 12) + (((PTR)[-2]&0x3F) << 6) + ((PTR)[-1]&0x3F) \
: ((PTR)++, -1))
+extern char *jcf_write_base_directory;
+
/* Debug macros, for the front end */
extern int quiet_flag;
-#ifdef SOURCE_FRONTEND_DEBUG
+#ifdef VERBOSE_SKELETON
#undef SOURCE_FRONTEND_DEBUG
#define SOURCE_FRONTEND_DEBUG(X) \
{if (!quiet_flag) {printf ("* "); printf X; putchar ('\n');} }
@@ -257,4 +257,26 @@ extern int quiet_flag;
#define SOURCE_FRONTEND_DEBUG(X)
#endif
+/* Declarations for dependency code. */
+extern void jcf_dependency_reset PROTO ((void));
+extern void jcf_dependency_set_target PROTO ((char *));
+extern void jcf_dependency_add_target PROTO ((char *));
+extern void jcf_dependency_set_dep_file PROTO ((const char *));
+extern void jcf_dependency_add_file PROTO ((const char *, int));
+extern void jcf_dependency_write PROTO ((void));
+extern void jcf_dependency_init PROTO ((int));
+
+/* Declarations for path handling code. */
+extern void jcf_path_init PROTO ((void));
+extern void jcf_path_classpath_arg PROTO ((char *));
+extern void jcf_path_CLASSPATH_arg PROTO ((char *));
+extern void jcf_path_include_arg PROTO ((char *));
+extern void jcf_path_seal PROTO ((void));
+extern void *jcf_path_start PROTO ((void));
+extern void *jcf_path_next PROTO ((void *));
+extern char *jcf_path_name PROTO ((void *));
+extern int jcf_path_is_zipfile PROTO ((void *));
+extern int jcf_path_is_system PROTO ((void *));
+extern int jcf_path_max_len PROTO ((void));
+
#endif
diff --git a/gcc/java/jv-scan.c b/gcc/java/jv-scan.c
index 99065927756..26fc662ed5e 100644
--- a/gcc/java/jv-scan.c
+++ b/gcc/java/jv-scan.c
@@ -1,5 +1,5 @@
/* Main for jv-scan
- Copyright (C) 1998 Free Software Foundation, Inc.
+ Copyright (C) 1998, 1999 Free Software Foundation, Inc.
Contributed by Alexandre Petit-Bianco (apbianco@cygnus.com)
This file is part of GNU CC.
@@ -19,21 +19,14 @@ 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 <stdio.h>
-#include <stdlib.h>
-#ifdef __STDC__
-#include <stdarg.h>
-#else
-#include <varargs.h>
-#endif
+#include "config.h"
+#include "system.h"
-#include "gansidecl.h" /* Definitions of PROTO and VPROTO */
#include "obstack.h" /* We use obstacks in lex.c */
-void fatal VPROTO((char *s, ...));
-void warning VPROTO((char *s, ...));
+void fatal VPROTO((const char *s, ...)) ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN;
+void warning VPROTO((const char *s, ...)) ATTRIBUTE_PRINTF_1;
void gcc_obstack_init PROTO ((struct obstack *obstack));
-extern void reset_report PROTO ((void));
#define JC1_LITE
#include "parse.h"
@@ -54,10 +47,9 @@ int flag_list_filename = 0;
/* jc1-lite main entry point */
int
-main (argc, argv, envp)
- int argc;
- char **argv;
- char **envp;
+main (argc, argv)
+ int argc;
+ char **argv;
{
int i = 1;
char *output_file = NULL;
@@ -108,10 +100,10 @@ main (argc, argv, envp)
/* Check on bad usage */
if (flag_find_main && flag_dump_class)
fatal ("Options `--print-main' and `--list-class' can't be turned on "
- "at the same time", argv [0]);
+ "at the same time");
if (output_file && !(out = fopen (output_file, "w")))
- fatal ("Can't open output file `%s'", argv [0], output_file);
+ fatal ("Can't open output file `%s'", output_file);
ft = ftell (out);
@@ -133,7 +125,7 @@ main (argc, argv, envp)
reset_report ();
}
else
- fatal ("File not found `%s'", argv [0], argv [i]);
+ fatal ("File not found `%s'", argv [i]);
}
/* Flush and close */
@@ -149,17 +141,17 @@ main (argc, argv, envp)
functions */
void
-fatal VPROTO((char *s, ...))
+fatal VPROTO((const char *s, ...))
{
-#ifndef __STDC__
- char *s;
+#ifndef ANSI_PROTOTYPES
+ const char *s;
#endif
va_list ap;
VA_START (ap, s);
-#ifndef __STDC__
- s = va_arg (ap, char *);
+#ifndef ANSI_PROTOTYPES
+ s = va_arg (ap, const char *);
#endif
fprintf (stderr, "%s: error: ", exec_name);
@@ -169,43 +161,18 @@ fatal VPROTO((char *s, ...))
exit (1);
}
-char *
-xmalloc (size)
- unsigned size;
-{
- register char *value;
-
- if (size == 0)
- size = 1;
-
- value = (char *) malloc (size);
- if (value == 0)
- fatal ("virtual memory exhausted");
- return value;
-}
-
-char *
-xstrdup (string)
- char *string;
-{
- int length = strlen (string)+1;
- char *to_return = xmalloc (length);
- strcpy (to_return, string);
- return to_return;
-}
-
void
-warning VPROTO((char *s, ...))
+warning VPROTO((const char *s, ...))
{
-#ifndef __STDC__
- char *s;
+#ifndef ANSI_PROTOTYPES
+ const char *s;
#endif
va_list ap;
VA_START (ap, s);
-#ifndef __STDC__
- s = va_arg (ap, char *);
+#ifndef ANSI_PROTOTYPES
+ s = va_arg (ap, const char *);
#endif
fprintf (stderr, "%s: warning: ", exec_name);
@@ -233,3 +200,14 @@ gcc_obstack_init (obstack)
(void *(*) ()) OBSTACK_CHUNK_ALLOC,
(void (*) ()) OBSTACK_CHUNK_FREE);
}
+
+PTR
+xmalloc (size)
+ size_t size;
+{
+ register PTR val = (PTR) malloc (size);
+
+ if (val == 0)
+ fatal ("virtual memory exhausted");
+ return val;
+}
diff --git a/gcc/java/jvgenmain.c b/gcc/java/jvgenmain.c
index 5e767afffe6..0f9e6287827 100644
--- a/gcc/java/jvgenmain.c
+++ b/gcc/java/jvgenmain.c
@@ -27,6 +27,10 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */
#include "config.h"
#include "system.h"
#include "obstack.h"
+#include "gansidecl.h"
+#include "jcf.h"
+#include "tree.h"
+#include "java-tree.h"
const char main_method_prefix[] = "main__";
const char main_method_suffix[] = "Pt6JArray1ZPQ34java4lang6String";
@@ -34,24 +38,25 @@ const char class_mangling_prefix[] = "_CL_";
struct obstack name_obstack;
-void
-error (const char *str)
-{
- fprintf (stderr, "%s\n", str);
- exit (-1);
-}
+extern void error PVPROTO ((const char *, ...))
+ ATTRIBUTE_PRINTF_1;
-void *
-xmalloc (size)
- size_t size;
+void
+error VPROTO((const char *msgid, ...))
{
- void *ptr = malloc (size);
- if (ptr == NULL)
- {
- fprintf (stderr, "Not enough memory!\n");
- exit (-1);
- }
- return ptr;
+#ifndef ANSI_PROTOTYPES
+ const char *msgid;
+#endif
+ va_list ap;
+
+ VA_START (ap, msgid);
+
+#ifndef ANSI_PROTOTYPES
+ msgid = va_arg (ap, const char *);
+#endif
+
+ vfprintf (stderr, msgid, ap);
+ va_end (ap);
}
void
@@ -121,3 +126,17 @@ main (int argc, const char **argv)
}
return 0;
}
+
+PTR
+xmalloc (size)
+ size_t size;
+{
+ register PTR val = (PTR) malloc (size);
+
+ if (val == 0)
+ {
+ fprintf(stderr, "jvgenmain: virtual memory exhausted");
+ exit(FATAL_EXIT_CODE);
+ }
+ return val;
+}
diff --git a/gcc/java/jvspec.c b/gcc/java/jvspec.c
index 5f9381167d8..fee65b87db3 100644
--- a/gcc/java/jvspec.c
+++ b/gcc/java/jvspec.c
@@ -1,6 +1,6 @@
-/* Specific flags and argument handling of the front-end of the
+ /* Specific flags and argument handling of the front-end of the
GNU compiler for the Java(TM) language.
- Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -32,7 +32,11 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */
#if defined (WITH_THREAD_posix) || defined (WITH_THREAD_pthreads)
#define THREAD_NAME "-lpthread"
#elif defined (WITH_THREAD_qt)
-#define THREAD_NAME "-lqthreads"
+#define THREAD_NAME "-lgcjcoop"
+#endif
+
+#if defined (WITH_GC_boehm)
+#define GC_NAME "-lgcjgc"
#endif
/* This bit is set if we saw a `-xfoo' language specification. */
@@ -41,17 +45,22 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */
#define MATHLIB (1<<2)
/* This bit is set if they did `-lc'. */
#define WITHLIBC (1<<3)
-/* This bit is set if they did `-lgc'. */
+/* This bit is set if they did `-lgcjgc'. */
#define GCLIB (1<<4)
/* This bit is set if they did `-lpthread' (or added some other thread
library). */
#define THREADLIB (1<<5)
+/* True if this arg is a parameter to the previous option-taking arg. */
+#define PARAM_ARG (1<<6)
+/* True if this arg is a .java input file name. */
+#define JAVA_FILE_ARG (1<<7)
+/* True if this arg is a .class input file name. */
+#define CLASS_FILE_ARG (1<<8)
#ifndef MATH_LIBRARY
#define MATH_LIBRARY "-lm"
#endif
-extern char *xmalloc PROTO((size_t));
extern int do_spec PROTO((char *));
extern char *input_filename;
extern size_t input_filename_length;
@@ -59,16 +68,21 @@ extern size_t input_filename_length;
char *main_class_name = NULL;
int lang_specific_extra_outfiles = 0;
+/* Once we have the proper support in jc1 (and gcc.c) working,
+ set COMBINE_INPUTS to one. This enables combining multiple *.java
+ and *.class input files to be passed to a single jc1 invocation. */
+#define COMBINE_INPUTS 0
+
char jvgenmain_spec[] =
- "jvgenmain %i %{!pipe:%g.i} |\n\
- cc1 %{!pipe:%g.i} %1 \
+ "jvgenmain %i %{!pipe:%u.i} |\n\
+ cc1 %{!pipe:%U.i} %1 \
%{!Q:-quiet} -dumpbase %b.c %{d*} %{m*} %{a*}\
%{g*} %{O*} \
%{v:-version} %{pg:-p} %{p} %{f*}\
%{aux-info*}\
%{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\
- %{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%g.s}} |\n\
- %{!S:as %a %Y -o %w%b%O %{!pipe:%g.s} %A\n }";
+ %{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%U.s}} |\n\
+ %{!S:as %a %Y -o %d%w%u%O %{!pipe:%U.s} %A\n }";
void
lang_specific_driver (fn, in_argc, in_argv, in_added_libraries)
@@ -83,9 +97,33 @@ lang_specific_driver (fn, in_argc, in_argv, in_added_libraries)
int saw_verbose_flag = 0;
/* This will be 0 if we encounter a situation where we should not
- link in libjava. */
+ link in libgcj. */
int library = 1;
+#if COMBINE_INPUTS
+ /* This will be 1 if multiple input files (.class and/or .java)
+ should be passed to a single jc1 invocation. */
+ int combine_inputs = 0;
+
+ /* Index of last .java or .class argument. */
+ int last_input_index;
+
+ /* A buffer containing the concatenation of the inputs files
+ (e.g. "foo.java&bar.class&baz.class"). if combine_inputs. */
+ char* combined_inputs_buffer;
+
+ /* Next available location in combined_inputs_buffer. */
+ int combined_inputs_pos;
+
+ /* Number of .java and .class source file arguments seen. */
+ int java_files_count = 0;
+ int class_files_count = 0;
+
+ /* Cumulative length of the .java and .class source file names. */
+ int java_files_length = 0;
+ int class_files_length = 0;
+#endif
+
/* The number of arguments being added to what's in argv, other than
libraries. We use this to track the number of times we've inserted
-xc++/-xnone. */
@@ -109,14 +147,22 @@ lang_specific_driver (fn, in_argc, in_argv, in_added_libraries)
/* "-lc" if it appears on the command line. */
char *saw_libc = 0;
- /* "-lgc" if it appears on the command line. */
+ /* "-lgcjgc" if it appears on the command line. */
char *saw_gc = 0;
/* Saw `-l' option for the thread library. */
char *saw_threadlib = 0;
- /* Saw `-ljava' on command line. */
- int saw_libjava = 0;
+ /* Saw `-lgcj' on command line. */
+ int saw_libgcj = 0;
+
+ /* Saw -C or -o option, respectively. */
+ int saw_C = 0;
+ int saw_o = 0;
+
+ /* Saw some -O* or -g* option, respectively. */
+ int saw_O = 0;
+ int saw_g = 0;
/* An array used to flag each argument that needs a bit set for
LANGSPEC, MATHLIB, WITHLIBC, or GCLIB. */
@@ -129,6 +175,9 @@ lang_specific_driver (fn, in_argc, in_argv, in_added_libraries)
*/
int need_thread = 1;
+ /* By default, we throw in the gc library (if one is required). */
+ int need_gc = 1;
+
/* The total number of arguments with the new stuff. */
int argc;
@@ -141,6 +190,9 @@ lang_specific_driver (fn, in_argc, in_argv, in_added_libraries)
/* The total number of arguments with the new stuff. */
int num_args = 1;
+ /* Non-zero if linking is supposed to happen. */
+ int will_link = 1;
+
argc = *in_argc;
argv = *in_argv;
added_libraries = *in_added_libraries;
@@ -154,6 +206,7 @@ lang_specific_driver (fn, in_argc, in_argv, in_added_libraries)
if (quote)
{
quote = NULL;
+ args[i] |= PARAM_ARG;
continue;
}
@@ -180,13 +233,21 @@ lang_specific_driver (fn, in_argc, in_argv, in_added_libraries)
need_math = 0;
}
else if (strncmp (argv[i], "-fmain=", 7) == 0)
- main_class_name = argv[i] + 7;
- else if (strcmp (argv[i], "-ljava") == 0)
- saw_libjava = 1;
+ {
+ main_class_name = argv[i] + 7;
+ added--;
+ }
+ else if (strcmp (argv[i], "-lgcj") == 0)
+ saw_libgcj = 1;
else if (strcmp (argv[i], "-lc") == 0)
args[i] |= WITHLIBC;
- else if (strcmp (argv[i], "-lgc") == 0)
- args[i] |= GCLIB;
+#ifdef GC_NAME
+ else if (strcmp (argv[i], GC_NAME) == 0)
+ {
+ args[i] |= GCLIB;
+ need_gc = 0;
+ }
+#endif
#ifdef THREAD_NAME
else if (strcmp (argv[i], THREAD_NAME) == 0)
{
@@ -200,24 +261,66 @@ lang_specific_driver (fn, in_argc, in_argv, in_added_libraries)
if (argc == 2)
{
/* If they only gave us `-v', don't try to link
- in libjava. */
+ in libgcj. */
library = 0;
}
}
else if (strncmp (argv[i], "-x", 2) == 0)
saw_speclang = 1;
+ else if (strcmp (argv[i], "-C") == 0)
+ {
+ saw_C = 1;
+#if COMBINE_INPUTS
+ combine_inputs = 1;
+#endif
+ if (library != 0)
+ added -= 2;
+ library = 0;
+ will_link = 0;
+ }
+ else if (argv[i][1] == 'g')
+ saw_g = 1;
+ else if (argv[i][1] == 'O')
+ saw_O = 1;
else if (((argv[i][2] == '\0'
&& (char *)strchr ("bBVDUoeTuIYmLiA", argv[i][1]) != NULL)
|| strcmp (argv[i], "-Tdata") == 0))
- quote = argv[i];
- else if (library != 0 && ((argv[i][2] == '\0'
- && (char *) strchr ("cSEM", argv[i][1]) != NULL)
- || strcmp (argv[i], "-MM") == 0))
+ {
+ if (strcmp (argv[i], "-o") == 0)
+ saw_o = 1;
+ quote = argv[i];
+ }
+ else if (strcmp(argv[i], "-classpath") == 0
+ || strcmp(argv[i], "-CLASSPATH") == 0)
+ {
+ quote = argv[i];
+ added -= 1;
+ }
+ else if (library != 0
+ && ((argv[i][2] == '\0'
+ && (char *) strchr ("cSEM", argv[i][1]) != NULL)
+ || strcmp (argv[i], "-MM") == 0))
{
/* Don't specify libraries if we won't link, since that would
cause a warning. */
library = 0;
added -= 2;
+
+ /* Remember this so we can confirm -fmain option. */
+ will_link = 0;
+ }
+ else if (strcmp (argv[i], "-d") == 0)
+ {
+ /* `-d' option is for javac compatibility. */
+ quote = argv[i];
+ added -= 1;
+ }
+ else if (strcmp (argv[i], "-fsyntax-only") == 0
+ || strcmp (argv[i], "--syntax-only") == 0)
+ {
+ library = 0;
+ will_link = 0;
+ continue;
}
else
/* Pass other options through. */
@@ -225,7 +328,9 @@ lang_specific_driver (fn, in_argc, in_argv, in_added_libraries)
}
else
{
+#if COMBINE_INPUTS
int len;
+#endif
if (saw_speclang)
{
@@ -233,48 +338,115 @@ lang_specific_driver (fn, in_argc, in_argv, in_added_libraries)
continue;
}
- /* If the filename ends in .c or .i, put options around it.
- But not if a specified -x option is currently active. */
+#if COMBINE_INPUTS
len = strlen (argv[i]);
- if (len > 2
- && (argv[i][len - 1] == 'c' || argv[i][len - 1] == 'i')
- && argv[i][len - 2] == '.')
+ if (len > 5 && strcmp (argv[i] + len - 5, ".java") == 0)
+ {
+ args[i] |= JAVA_FILE_ARG;
+ java_files_count++;
+ java_files_length += len;
+ last_input_index = i;
+ }
+ if (len > 6 && strcmp (argv[i] + len - 6, ".class") == 0)
{
- args[i] |= LANGSPEC;
- added += 2;
+ args[i] |= CLASS_FILE_ARG;
+ class_files_count++;
+ class_files_length += len;
+ last_input_index = i;
}
+#endif
}
}
if (quote)
(*fn) ("argument to `%s' missing\n", quote);
+ num_args = argc + added;
+ if (will_link)
+ num_args += need_math + need_thread + need_gc;
+ if (saw_C)
+ {
+ num_args += 3;
+#if COMBINE_INPUTS
+ class_files_length = 0;
+ num_args -= class_files_count;
+ num_args += 2; /* For -o NONE. */
+#endif
+ if (saw_o)
+ (*fn) ("cannot specify both -C and -o");
+ }
+#if COMBINE_INPUTS
+ if (saw_o && java_files_count + (saw_C ? 0 : class_files_count) > 1)
+ combine_inputs = 1;
+
+ if (combine_inputs)
+ {
+ int len = java_files_length + java_files_count - 1;
+ num_args -= java_files_count;
+ num_args++; /* Add one for the combined arg. */
+ if (class_files_length > 0)
+ {
+ len += class_files_length + class_files_count - 1;
+ num_args -= class_files_count;
+ }
+ combined_inputs_buffer = (char*) xmalloc (len);
+ combined_inputs_pos = 0;
+ }
/* If we know we don't have to do anything, bail now. */
- if (! added && ! library && main_class_name == NULL)
+#endif
+#if 0
+ if (! added && ! library && main_class_name == NULL && ! saw_C)
{
free (args);
return;
}
+#endif
- num_args = argc + added + need_math + need_thread;
if (main_class_name)
{
lang_specific_extra_outfiles++;
}
- arglist = (char **) xmalloc (num_args * sizeof (char *));
+ if (saw_g + saw_O == 0)
+ num_args++;
+ arglist = (char **) xmalloc ((num_args + 1) * sizeof (char *));
- /* NOTE: We start at 1 now, not 0. */
for (i = 0, j = 0; i < argc; i++, j++)
{
arglist[j] = argv[i];
+ if ((args[i] & PARAM_ARG) || i == 0)
+ continue;
+
+ if (strcmp (argv[i], "-classpath") == 0
+ || strcmp (argv[i], "-CLASSPATH") == 0)
+ {
+ char* patharg
+ = (char*) xmalloc (strlen (argv[i]) + strlen (argv[i+1]) + 3);
+ sprintf (patharg, "-f%s=%s", argv[i]+1, argv[i+1]);
+ arglist[j] = patharg;
+ i++;
+ continue;
+ }
+
+ if (strcmp (argv[i], "-d") == 0)
+ {
+ char *patharg = (char *) xmalloc (sizeof ("-foutput-class-dir=")
+ + strlen (argv[i + 1]) + 1);
+ sprintf (patharg, "-foutput-class-dir=%s", argv[i + 1]);
+ arglist[j] = patharg;
+ ++i;
+ continue;
+ }
+
if (strncmp (argv[i], "-fmain=", 7) == 0)
{
+ if (! will_link)
+ (*fn) ("cannot specify `main' class when not linking");
--j;
continue;
}
- /* Make sure -ljava is before the math library, since libjava
+ /* Make sure -lgcj is before the math library, since libgcj
itself uses those math routines. */
if (!saw_math && (args[i] & MATHLIB) && library)
{
@@ -282,32 +454,65 @@ lang_specific_driver (fn, in_argc, in_argv, in_added_libraries)
saw_math = argv[i];
}
- /* Likewise -ljava must come before -lc. */
+ /* Likewise -lgcj must come before -lc. */
if (!saw_libc && (args[i] & WITHLIBC) && library)
{
--j;
saw_libc = argv[i];
}
- /* And -ljava must come before -lgc. */
+ /* And -lgcj must come before -lgcjgc. */
if (!saw_gc && (args[i] & GCLIB) && library)
{
--j;
saw_gc = argv[i];
}
- /* And -ljava must come before thread library. */
+ /* And -lgcj must come before thread library. */
if (!saw_threadlib && (args[i] & THREADLIB) && library)
{
--j;
saw_threadlib = argv[i];
}
+
+ if ((args[i] & CLASS_FILE_ARG) && saw_C)
+ {
+ --j;
+ continue;
+ }
+
+#if COMBINE_INPUTS
+ if (combine_inputs && (args[i] & (CLASS_FILE_ARG|JAVA_FILE_ARG)) != 0)
+ {
+ if (combined_inputs_pos > 0)
+ combined_inputs_buffer[combined_inputs_pos++] = '&';
+ strcpy (&combined_inputs_buffer[combined_inputs_pos], argv[i]);
+ combined_inputs_pos += strlen (argv[i]);
+ --j;
+ continue;
+ }
+#endif
}
- /* Add `-ljava' if we haven't already done so. */
- if (library && ! saw_libjava)
+#if COMBINE_INPUTS
+ if (combine_inputs)
{
- arglist[j++] = "-ljava";
+ combined_inputs_buffer[combined_inputs_pos] = '\0';
+#if 0
+ if (! saw_C)
+#endif
+ arglist[j++] = combined_inputs_buffer;
+ }
+#endif
+
+ /* If we saw no -O or -g option, default to -g1, for javac compatibility. */
+ if (saw_g + saw_O == 0)
+ arglist[j++] = "-g1";
+
+ /* Add `-lgcj' if we haven't already done so. */
+ if (library && ! saw_libgcj)
+ {
+ arglist[j++] = "-lgcj";
added_libraries++;
}
@@ -319,13 +524,18 @@ lang_specific_driver (fn, in_argc, in_argv, in_added_libraries)
added_libraries++;
}
- /* FIXME: we need a way to know when the GC library should be
- added. Then we can add it if the user hasn't already. */
if (saw_gc)
arglist[j++] = saw_gc;
+#ifdef GC_NAME
+ else if (library)
+ {
+ arglist[j++] = GC_NAME;
+ added_libraries++;
+ }
+#endif
/* Thread library must come after GC library as well as after
- -ljava. */
+ -lgcj. */
if (saw_threadlib)
arglist[j++] = saw_threadlib;
#ifdef THREAD_NAME
@@ -339,6 +549,17 @@ lang_specific_driver (fn, in_argc, in_argv, in_added_libraries)
if (saw_libc)
arglist[j++] = saw_libc;
+ if (saw_C)
+ {
+ arglist[j++] = "-fsyntax-only";
+ arglist[j++] = "-femit-class-files";
+ arglist[j++] = "-S";
+#if COMBINE_INPUTS
+ arglist[j++] = "-o";
+ arglist[j++] = "NONE";
+#endif
+ }
+
arglist[j] = NULL;
*in_argc = j;
diff --git a/gcc/java/lang-options.h b/gcc/java/lang-options.h
index f421e6a16c7..56d023cdd93 100644
--- a/gcc/java/lang-options.h
+++ b/gcc/java/lang-options.h
@@ -26,10 +26,18 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */
java. */
DEFINE_LANG_NAME ("Java")
-
+
{ "-fbounds-check", "" },
{ "-fno-bounds-check", "Disable automatic array bounds checking" },
{ "-fassume-compiled", "Make is_compiled_class return 1"},
{ "-fno-assume-compiled", "" },
{ "-femit-class-file", "" },
{ "-femit-class-files", "Dump class files to <name>.class" },
+ { "-MD", "Print dependencies to FILE.d" },
+ { "-MMD", "Print dependencies to FILE.d" },
+ { "-M", "Print dependencies to stdout" },
+ { "-MM", "Print dependencies to stdout" },
+ { "-fclasspath", "Set class path and suppress system path" },
+ { "-fCLASSPATH", "Set class path" },
+ { "-I", "Add directory to class path" },
+ { "-foutput-class-dir", "Directory where class files should be written" },
diff --git a/gcc/java/lang-specs.h b/gcc/java/lang-specs.h
index f86c327d0c0..93d18859310 100644
--- a/gcc/java/lang-specs.h
+++ b/gcc/java/lang-specs.h
@@ -1,5 +1,5 @@
/* Definitions for specs for the GNU compiler for the Java(TM) language.
- Copyright (C) 1996 Free Software Foundation, Inc.
+ Copyright (C) 1996, 1998, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -15,7 +15,8 @@ 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, 675 Mass Ave, Cambridge, MA 02139, USA.
+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.
@@ -24,15 +25,19 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */
/* This is the contribution to the `default_compilers' array in gcc.c for
Java. */
- {".java", "@java" },
- {".class", "@java" },
+ {".java", {"@java"} },
+ {".class", {"@java"} },
+ {".zip", {"@java"} },
+ {".jar", {"@java"} },
{"@java",
- "%{!M:%{!MM:%{!E:jc1 %i %1 %2 %{!Q:-quiet} %{d*} %{m*} %{a}\
- %{g*} %{O*} %{W*} %{w} %{pedantic*} %{ansi}\
- %{traditional} %{v:-version} %{pg:-p} %{p}\
- %{f*} %{+e*} %{aux-info*}\
- %{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\
- %{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%g.s}} |\n\
- %{!S:as %a %Y\
- %{c:%W{o*}%{!o*:-o %w%b%O}}%{!c:-o %d%w%u%O}\
- %{!pipe:%g.s} %A\n }}}}"},
+ {"%{!E:jc1 %i %1 %{!Q:-quiet} %{d*} %{m*} %{a}\
+ %{g*} %{O*} %{W*} %{w} %{pedantic*} %{ansi}\
+ %{traditional} %{v:-version} %{pg:-p} %{p}\
+ %{f*} %{+e*} %{aux-info*} %{Qn:-fno-ident}\
+ %{I*}\
+ %{MD} %{MMD} %{M} %{MM}\
+ %{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\
+ %{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%g.s}} |\n\
+ %{!S:as %a %Y\
+ %{c:%W{o*}%{!o*:-o %w%b%O}}%{!c:-o %d%w%u%O}\
+ %{!pipe:%g.s} %A\n }}"}},
diff --git a/gcc/java/lang.c b/gcc/java/lang.c
index 7d46f50eb5d..9fc7c1ed1c9 100644
--- a/gcc/java/lang.c
+++ b/gcc/java/lang.c
@@ -1,5 +1,5 @@
/* Java(TM) language-specific utility routines.
- Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1996, 97-98, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -31,6 +31,46 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */
#include "java-tree.h"
#include "jcf.h"
#include "toplev.h"
+#include "flags.h"
+#include "xref.h"
+
+#ifndef OBJECT_SUFFIX
+# define OBJECT_SUFFIX ".o"
+#endif
+
+/* Table indexed by tree code giving a string containing a character
+ classifying the tree code. Possibilities are
+ t, d, s, c, r, <, 1 and 2. See java/java-tree.def for details. */
+
+#define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE,
+
+char java_tree_code_type[] = {
+ 'x',
+#include "java-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,
+
+int java_tree_code_length[] = {
+ 0,
+#include "java-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 *java_tree_code_name[] = {
+ "@@dummy",
+#include "java-tree.def"
+};
+#undef DEFTREECODE
int compiling_from_source;
@@ -48,7 +88,24 @@ int flag_assume_compiled = 1;
int flag_emit_class_files = 0;
-/* From gcc/flags.h, and idicates if exceptions are turned on or not. */
+/* When non zero, we emit xref strings. Values of the flag for xref
+ backends are defined in xref_flag_table, xref.c. */
+
+int flag_emit_xref = 0;
+
+/* When non zero, -Wall was turned on. */
+int flag_wall = 0;
+
+/* When non zero, check for redundant modifier uses. */
+int flag_redundant = 0;
+
+/* When non zero, warns about overridings that don't occur. */
+int flag_not_overriding = 0;
+
+/* When non zero, warns that final local are treated as non final. */
+int flag_static_local_jdk1_1 = 0;
+
+/* From gcc/flags.h, and indicates if exceptions are turned on or not. */
extern int flag_new_exceptions;
extern int flag_exceptions;
@@ -59,7 +116,8 @@ extern int flag_exceptions;
if `-fSTRING' is seen as an option.
(If `-fno-STRING' is seen as an option, the opposite value is stored.) */
-static struct { char *string; int *variable; int on_value;} lang_f_options[] =
+static struct { const char *string; int *variable; int on_value;}
+lang_f_options[] =
{
{"bounds-check", &flag_bounds_check, 1},
{"assume-compiled", &flag_assume_compiled, 1},
@@ -70,15 +128,62 @@ static struct { char *string; int *variable; int on_value;} lang_f_options[] =
JCF main_jcf[1];
JCF *current_jcf;
+/* Variable controlling how dependency tracking is enabled in
+ init_parse. */
+static int dependency_tracking = 0;
+
+/* Flag values for DEPENDENCY_TRACKING. */
+#define DEPEND_SET_FILE 1
+#define DEPEND_ENABLE 2
+
/*
* process java-specific compiler command-line options
*/
int
lang_decode_option (argc, argv)
- int argc;
+ int argc __attribute__ ((__unused__));
char **argv;
{
char *p = argv[0];
+
+#define CLARG "-fclasspath="
+ if (strncmp (p, CLARG, sizeof (CLARG) - 1) == 0)
+ {
+ jcf_path_classpath_arg (p + sizeof (CLARG) - 1);
+ return 1;
+ }
+#undef CLARG
+#define CLARG "-fCLASSPATH="
+ else if (strncmp (p, CLARG, sizeof (CLARG) - 1) == 0)
+ {
+ jcf_path_CLASSPATH_arg (p + sizeof (CLARG) - 1);
+ return 1;
+ }
+#undef CLARG
+ else if (strncmp (p, "-I", 2) == 0)
+ {
+ jcf_path_include_arg (p + 2);
+ return 1;
+ }
+
+#define ARG "-foutput-class-dir="
+ if (strncmp (p, ARG, sizeof (ARG) - 1) == 0)
+ {
+ jcf_write_base_directory = p + sizeof (ARG) - 1;
+ return 1;
+ }
+#undef ARG
+
+#define XARG "-fxref="
+ if (strncmp (p, XARG, sizeof (XARG) - 1) == 0)
+ {
+ if (!(flag_emit_xref = xref_flag_value (p + sizeof (XARG) - 1)))
+ {
+ error ("Unkown xref format `%s'", p + sizeof (XARG) - 1);
+ }
+ }
+#undef XARG
+
if (p[0] == '-' && p[1] == 'f')
{
/* Some kind of -f option.
@@ -89,8 +194,9 @@ lang_decode_option (argc, argv)
p += 2;
for (j = 0;
- !found && j < sizeof (lang_f_options) / sizeof (lang_f_options[0]);
- j++)
+ !found
+ && j < (int)(sizeof (lang_f_options) / sizeof (lang_f_options[0]));
+ j++)
{
if (!strcmp (p, lang_f_options[j].string))
{
@@ -106,9 +212,43 @@ lang_decode_option (argc, argv)
found = 1;
}
}
+
return found;
}
+ if (strcmp (p, "-Wall") == 0)
+ {
+ flag_wall = 1;
+ flag_redundant = 1;
+ flag_not_overriding = 1;
+ flag_static_local_jdk1_1 = 1;
+ }
+
+ if (strcmp (p, "-MD") == 0)
+ {
+ jcf_dependency_init (1);
+ dependency_tracking |= DEPEND_SET_FILE | DEPEND_ENABLE;
+ return 1;
+ }
+ else if (strcmp (p, "-MMD") == 0)
+ {
+ jcf_dependency_init (0);
+ dependency_tracking |= DEPEND_SET_FILE | DEPEND_ENABLE;
+ return 1;
+ }
+ else if (strcmp (p, "-M") == 0)
+ {
+ jcf_dependency_init (1);
+ dependency_tracking |= DEPEND_ENABLE;
+ return 1;
+ }
+ else if (strcmp (p, "-MM") == 0)
+ {
+ jcf_dependency_init (0);
+ dependency_tracking |= DEPEND_ENABLE;
+ return 1;
+ }
+
return 0;
}
@@ -123,15 +263,48 @@ init_parse (filename)
{
finput = stdin;
filename = "stdin";
+
+ if (dependency_tracking)
+ error ("can't do dependency tracking with input from stdin");
}
else
- finput = fopen (filename, "r");
- if (finput == 0)
- pfatal_with_name (filename);
-
-#ifdef IO_BUFFER_SIZE
- setvbuf (finput, (char *) xmalloc (IO_BUFFER_SIZE), _IOFBF, IO_BUFFER_SIZE);
-#endif
+ {
+ if (dependency_tracking)
+ {
+ char *dot;
+ dot = strrchr (filename, '.');
+ if (dot == NULL)
+ error ("couldn't determine target name for dependency tracking");
+ else
+ {
+ char *buf = (char *) xmalloc (dot - filename +
+ 3 + sizeof (OBJECT_SUFFIX));
+ strncpy (buf, filename, dot - filename);
+
+ /* If emitting class files, we might have multiple
+ targets. The class generation code takes care of
+ registering them. Otherwise we compute the target
+ name here. */
+ if (flag_emit_class_files)
+ jcf_dependency_set_target (NULL);
+ else
+ {
+ strcpy (buf + (dot - filename), OBJECT_SUFFIX);
+ jcf_dependency_set_target (buf);
+ }
+
+ if ((dependency_tracking & DEPEND_SET_FILE))
+ {
+ strcpy (buf + (dot - filename), ".d");
+ jcf_dependency_set_dep_file (buf);
+ }
+ else
+ jcf_dependency_set_dep_file ("-");
+
+ free (buf);
+ }
+ }
+ }
init_lex ();
return filename;
@@ -141,6 +314,7 @@ void
finish_parse ()
{
fclose (finput);
+ jcf_dependency_write ();
}
/* Buffer used by lang_printable_name. */
@@ -201,7 +375,12 @@ put_decl_node (node)
put_decl_string (".", 1);
}
#endif
- put_decl_node (DECL_NAME (node));
+ if (TREE_CODE (node) == FUNCTION_DECL
+ && DECL_NAME (node) == init_identifier_node
+ && !DECL_ARTIFICIAL (node) && current_class)
+ put_decl_node (TYPE_NAME (current_class));
+ else
+ put_decl_node (DECL_NAME (node));
if (TREE_CODE (node) == FUNCTION_DECL && TREE_TYPE (node) != NULL_TREE)
{
int i = 0;
@@ -209,7 +388,7 @@ put_decl_node (node)
if (TREE_CODE (TREE_TYPE (node)) == METHOD_TYPE)
args = TREE_CHAIN (args);
put_decl_string ("(", 1);
- for ( ; args != NULL_TREE; args = TREE_CHAIN (args), i++)
+ for ( ; args != end_params_node; args = TREE_CHAIN (args), i++)
{
if (i > 0)
put_decl_string (",", 1);
@@ -253,7 +432,7 @@ put_decl_node (node)
char *
lang_printable_name (decl, v)
tree decl;
- int v;
+ int v __attribute__ ((__unused__));
{
decl_bufpos = 0;
put_decl_node (decl);
@@ -279,7 +458,7 @@ lang_print_error (file)
last_error_function_context = DECL_CONTEXT (current_function_decl);
fprintf (stderr, "In class `%s':\n",
- lang_printable_name (last_error_function_context));
+ lang_printable_name (last_error_function_context, 0));
}
if (last_error_function != current_function_decl)
{
@@ -310,16 +489,30 @@ lang_init ()
flag_minimal_debug = 0;
#endif
+ jcf_path_init ();
+ jcf_path_seal ();
+
decl_printable_name = lang_printable_name;
print_error_function = lang_print_error;
lang_expand_expr = java_lang_expand_expr;
- JCF_ZERO (main_jcf);
- main_jcf->read_state = finput;
- main_jcf->filbuf = jcf_filbuf_from_stdio;
- current_jcf = main_jcf;
-
flag_exceptions = 1;
+
+ /* Append to Gcc tree node definition arrays */
+
+ bcopy (java_tree_code_type,
+ tree_code_type + (int) LAST_AND_UNUSED_TREE_CODE,
+ (int)LAST_JAVA_TREE_CODE - (int)LAST_AND_UNUSED_TREE_CODE);
+ bcopy ((char *)java_tree_code_length,
+ (char *)(tree_code_length + (int) LAST_AND_UNUSED_TREE_CODE),
+ (LAST_JAVA_TREE_CODE -
+ (int)LAST_AND_UNUSED_TREE_CODE) * sizeof (int));
+ bcopy ((char *)java_tree_code_name,
+ (char *)(tree_code_name + (int) LAST_AND_UNUSED_TREE_CODE),
+ (LAST_JAVA_TREE_CODE -
+ (int)LAST_AND_UNUSED_TREE_CODE) * sizeof (char *));
+
+ using_eh_for_cleanups ();
}
/* This doesn't do anything on purpose. It's used to satisfy the
@@ -327,7 +520,7 @@ lang_init ()
function prototypes. */
void java_dummy_print (s)
- char *s;
+ char *s __attribute__ ((__unused__));
{
}
@@ -369,25 +562,25 @@ lang_identify ()
void
print_lang_decl (file, node, indent)
- FILE *file;
- tree node;
- int indent;
+ FILE *file __attribute ((__unused__));
+ tree node __attribute ((__unused__));
+ int indent __attribute ((__unused__));
{
}
void
print_lang_type (file, node, indent)
- FILE *file;
- tree node;
- int indent;
+ FILE *file __attribute ((__unused__));
+ tree node __attribute ((__unused__));
+ int indent __attribute ((__unused__));
{
}
void
print_lang_identifier (file, node, indent)
- FILE *file;
- tree node;
- int indent;
+ FILE *file __attribute ((__unused__));
+ tree node __attribute ((__unused__));
+ int indent __attribute ((__unused__));
{
}
@@ -400,8 +593,8 @@ print_lang_statistics ()
void
lang_print_xnode (file, node, indent)
- FILE *file;
- tree node;
- int indent;
+ FILE *file __attribute ((__unused__));
+ tree node __attribute ((__unused__));
+ int indent __attribute ((__unused__));
{
}
diff --git a/gcc/java/lex.c b/gcc/java/lex.c
index 50999654766..df15a8f2ecc 100644
--- a/gcc/java/lex.c
+++ b/gcc/java/lex.c
@@ -1,5 +1,5 @@
/* Language lexer for the GNU compiler for the Java(TM) language.
- Copyright (C) 1997, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc.
Contributed by Alexandre Petit-Bianco (apbianco@cygnus.com)
This file is part of GNU CC.
@@ -36,31 +36,59 @@ Addison Wesley 1996" (http://java.sun.com/docs/books/jls/html/3.doc.html) */
#include <stdio.h>
#include <string.h>
-#include <setjmp.h>
+#include <strings.h>
#ifdef JAVA_LEX_DEBUG
#include <ctype.h>
#endif
-#ifdef inline /* javaop.h redefines inline as static */
-#undef inline
-#endif
#include "keyword.h"
#ifndef SEEK_SET
#include <unistd.h>
#endif
+#ifndef JC1_LITE
+extern struct obstack *expression_obstack;
+#endif
+
+/* Function declaration */
+static int java_lineterminator PROTO ((unicode_t));
+static char *java_sprint_unicode PROTO ((struct java_line *, int));
+static void java_unicode_2_utf8 PROTO ((unicode_t));
+static void java_lex_error PROTO ((char *, int));
+#ifndef JC1_LITE
+static int java_is_eol PROTO ((FILE *, int));
+static tree build_wfl_node PROTO ((tree));
+#endif
+static void java_store_unicode PROTO ((struct java_line *, unicode_t, int));
+static unicode_t java_parse_escape_sequence PROTO ((void));
+static int java_letter_or_digit_p PROTO ((unicode_t));
+static int java_parse_doc_section PROTO ((unicode_t));
+static void java_parse_end_comment PROTO ((unicode_t));
+static unicode_t java_get_unicode PROTO (());
+static unicode_t java_read_unicode PROTO ((int, int *));
+static void java_store_unicode PROTO ((struct java_line *, unicode_t, int));
+static unicode_t java_read_char PROTO (());
+static void java_allocate_new_line PROTO (());
+static void java_unget_unicode PROTO (());
+static unicode_t java_sneak_unicode PROTO (());
+
void
java_init_lex ()
{
+#ifndef JC1_LITE
int java_lang_imported = 0;
-#ifndef JC1_LITE
+ if (!java_lang_id)
+ java_lang_id = get_identifier ("java.lang");
+ if (!java_lang_cloneable)
+ java_lang_cloneable = get_identifier ("java.lang.Cloneable");
+
if (!java_lang_imported)
{
tree node = build_tree_list
- (build_expr_wfl (get_identifier ("java.lang"), NULL, 0, 0), NULL_TREE);
+ (build_expr_wfl (java_lang_id, NULL, 0, 0), NULL_TREE);
read_import_dir (TREE_PURPOSE (node));
TREE_CHAIN (node) = ctxp->import_demand_list;
ctxp->import_demand_list = node;
@@ -71,12 +99,18 @@ java_init_lex ()
wfl_operator = build_expr_wfl (NULL_TREE, ctxp->filename, 0, 0);
if (!label_id)
label_id = get_identifier ("$L");
+ if (!wfl_append)
+ wfl_append = build_expr_wfl (get_identifier ("append"), NULL, 0, 0);
+ if (!wfl_string_buffer)
+ wfl_string_buffer =
+ build_expr_wfl (get_identifier ("java.lang.StringBuffer"), NULL, 0, 0);
+ if (!wfl_to_string)
+ wfl_to_string = build_expr_wfl (get_identifier ("toString"), NULL, 0, 0);
ctxp->static_initialized = ctxp->non_static_initialized =
ctxp->incomplete_class = NULL_TREE;
bzero (ctxp->modifier_ctx, 11*sizeof (ctxp->modifier_ctx[0]));
- classpath = NULL;
bzero (current_jcf, sizeof (JCF));
ctxp->current_parsed_class = NULL;
ctxp->package = NULL_TREE;
@@ -114,8 +148,7 @@ java_sneak_unicode ()
}
static void
-java_unget_unicode (c)
- unicode_t c;
+java_unget_unicode ()
{
if (!ctxp->c_line->current)
fatal ("can't unget unicode - java_unget_unicode");
@@ -123,10 +156,9 @@ java_unget_unicode (c)
ctxp->c_line->char_col -= JAVA_COLUMN_DELTA (0);
}
-void
+static void
java_allocate_new_line ()
{
- int i;
unicode_t ahead = (ctxp->c_line ? ctxp->c_line->ahead[0] : '\0');
char ahead_escape_p = (ctxp->c_line ?
ctxp->c_line->unicode_escape_ahead_p : 0);
@@ -145,12 +177,12 @@ java_allocate_new_line ()
if (!ctxp->c_line)
{
- ctxp->c_line = (struct java_line *)malloc (sizeof (struct java_line));
+ ctxp->c_line = (struct java_line *)xmalloc (sizeof (struct java_line));
ctxp->c_line->max = JAVA_LINE_MAX;
- ctxp->c_line->line = (unicode_t *)malloc
- (sizeof (unicode_t)*ctxp->c_line->max);
+ ctxp->c_line->line = (unicode_t *)xmalloc
+ (sizeof (unicode_t)*ctxp->c_line->max);
ctxp->c_line->unicode_escape_p =
- (char *)malloc (sizeof (char)*ctxp->c_line->max);
+ (char *)xmalloc (sizeof (char)*ctxp->c_line->max);
ctxp->c_line->white_space_only = 0;
}
@@ -168,6 +200,8 @@ java_allocate_new_line ()
ctxp->c_line->white_space_only = 1;
}
+#define BAD_UTF8_VALUE 0xFFFE
+
static unicode_t
java_read_char ()
{
@@ -189,24 +223,35 @@ java_read_char ()
return UEOF;
else
{
- if (c & 0xe0 == 0xc0)
+ if ((c & 0xe0) == 0xc0)
{
c1 = GETC ();
- if (c1 & 0xc0 == 0x80)
+ if ((c1 & 0xc0) == 0x80)
return (unicode_t)(((c &0x1f) << 6) + (c1 & 0x3f));
+ c = c1;
}
- else if (c & 0xf0 == 0xe0)
+ else if ((c & 0xf0) == 0xe0)
{
c1 = GETC ();
- if (c1 & 0xc0 == 0x80)
+ if ((c1 & 0xc0) == 0x80)
{
c2 = GETC ();
- if (c2 & 0xc0 == 0x80)
+ if ((c2 & 0xc0) == 0x80)
return (unicode_t)(((c & 0xf) << 12) +
(( c1 & 0x3f) << 6) + (c2 & 0x3f));
+ else
+ c = c2;
}
+ else
+ c = c1;
}
- java_lex_error ("Bad utf8 encoding", 0);
+ /* We looked for a UTF8 multi-byte sequence (since we saw an initial
+ byte with the high bit set), but found invalid bytes instead.
+ If the most recent byte was Ascii (and not EOF), we should
+ unget it, in case it was a comment terminator or other delimitor. */
+ if ((c & 0x80) == 0)
+ UNGETC (c);
+ return BAD_UTF8_VALUE;
}
}
@@ -266,7 +311,7 @@ java_read_unicode (term_context, unicode_escape_p)
if (c >= '0' && c <= '9')
unicode |= (unicode_t)((c-'0') << shift);
else if ((c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'))
- unicode |= (unicode_t)(10+(c | 0x20)-'a' << shift);
+ unicode |= (unicode_t)((10+(c | 0x20)-'a') << shift);
else
java_lex_error
("Non hex digit in Unicode escape sequence", 0);
@@ -275,7 +320,7 @@ java_read_unicode (term_context, unicode_escape_p)
return (term_context ? unicode :
(java_lineterminator (c) ? '\n' : unicode));
}
- UNGETC (c);
+ ctxp->unget_utf8_value = c;
}
return (unicode_t)'\\';
}
@@ -333,13 +378,14 @@ java_lineterminator (c)
return 0;
}
-/* Parse the end of a C style comment */
+/* Parse the end of a C style comment.
+ * C is the first character after the '/*'. */
static void
-java_parse_end_comment ()
+java_parse_end_comment (c)
+ unicode_t c;
{
- unicode_t c;
- for (c = java_get_unicode ();; c = java_get_unicode ())
+ for ( ;; c = java_get_unicode ())
{
switch (c)
{
@@ -353,12 +399,67 @@ java_parse_end_comment ()
case '/':
return;
case '*': /* reparse only '*' */
- java_unget_unicode (c);
+ java_unget_unicode ();
}
}
}
}
+/* Parse the documentation section. Keywords must be at the beginning
+ of a documentation comment line (ignoring white space and any `*'
+ character). Parsed keyword(s): @DEPRECATED. */
+
+static int
+java_parse_doc_section (c)
+ unicode_t c;
+{
+ int valid_tag = 0, seen_star = 0;
+
+ while (JAVA_WHITE_SPACE_P (c) || (c == '*') || c == '\n')
+ {
+ switch (c)
+ {
+ case '*':
+ seen_star = 1;
+ break;
+ case '\n': /* ULT */
+ valid_tag = 1;
+ default:
+ seen_star = 0;
+ }
+ c = java_get_unicode();
+ }
+
+ if (c == UEOF)
+ java_lex_error ("Comment not terminated at end of input", 0);
+
+ if (seen_star && (c == '/'))
+ return 1; /* Goto step1 in caller */
+
+ /* We're parsing @deprecated */
+ if (valid_tag && (c == '@'))
+ {
+ char tag [10];
+ int tag_index = 0;
+
+ while (tag_index < 10 && c != UEOF && c != ' ' && c != '\n')
+ {
+ c = java_get_unicode ();
+ tag [tag_index++] = c;
+ }
+
+ if (c == UEOF)
+ java_lex_error ("Comment not terminated at end of input", 0);
+
+ java_unget_unicode ();
+ tag [tag_index] = '\0';
+
+ if (!strcmp (tag, "deprecated"))
+ ctxp->deprecated = 1;
+ }
+ return 0;
+}
+
/* This function to be used only by JAVA_ID_CHAR_P (), otherwise it
will return a wrong result. */
static int
@@ -402,7 +503,7 @@ java_parse_escape_sequence ()
c = java_get_unicode ())
octal_escape [octal_escape_index++] = c;
- java_unget_unicode (c);
+ java_unget_unicode ();
if ((octal_escape_index == 3) && (octal_escape [0] > '3'))
{
@@ -437,7 +538,6 @@ java_lex (java_lval)
YYSTYPE *java_lval;
{
unicode_t c, first_unicode;
- int line_terminator;
int ascii_index, all_ascii;
char *string;
@@ -460,7 +560,7 @@ java_lex (java_lval)
if ((c = java_get_unicode ()) == UEOF)
return 0; /* Ok here */
else
- java_unget_unicode (c); /* Caught latter at the end the function */
+ java_unget_unicode (); /* Caught latter at the end the function */
}
/* Handle EOF here */
if (c == UEOF) /* Should probably do something here... */
@@ -472,8 +572,9 @@ java_lex (java_lval)
switch (c = java_get_unicode ())
{
case '/':
- for (c = java_get_unicode ();;c = java_get_unicode ())
+ for (;;)
{
+ c = java_get_unicode ();
if (c == UEOF)
java_lex_error ("Comment not terminated at end of input", 0);
if (c == '\n') /* ULT */
@@ -486,77 +587,22 @@ java_lex (java_lval)
{
if ((c = java_get_unicode ()) == '/')
goto step1; /* Empy documentation comment */
-
- else
- /* Parsing the documentation section. We're looking
- for the @depracated pseudo keyword. the @deprecated
- tag must be at the beginning of a doc comment line
- (ignoring white space and any * character) */
-
- {
- int valid_tag = 0, seen_star;
-
- while (JAVA_WHITE_SPACE_P (c) || (c == '*') || c == '\n')
- {
- switch (c)
- {
- case '*':
- seen_star = 1;
- break;
- case '\n': /* ULT */
- valid_tag = 1;
- break;
- default:
- seen_star = 0;
- }
- c = java_get_unicode();
- }
-
- if (c == UEOF)
- java_lex_error
- ("Comment not terminated at end of input", 0);
-
- if (seen_star && (c == '/'))
- goto step1; /* End of documentation */
-
- if (valid_tag && (c == '@'))
- {
- char deprecated [10];
- int deprecated_index = 0;
-
- for (deprecated_index = 0, c = java_get_unicode ();
- deprecated_index < 10 && c != UEOF;
- c = java_get_unicode ())
- deprecated [deprecated_index++] = c;
-
- if (c == UEOF)
- java_lex_error
- ("Comment not terminated at end of input", 0);
-
- java_unget_unicode (c);
- deprecated [deprecated_index] = '\0';
- if (!strcmp (deprecated, "deprecated"))
- {
- /* Set global flag to be checked by class. FIXME */
- warning ("deprecated implementation found");
- }
- }
- }
+ else if (java_parse_doc_section (c))
+ goto step1;
}
- else
- java_unget_unicode (c);
- java_parse_end_comment ();
+ java_parse_end_comment (c);
goto step1;
break;
default:
- java_unget_unicode (c);
+ java_unget_unicode ();
c = '/';
break;
}
}
ctxp->elc.line = ctxp->c_line->lineno;
+ ctxp->elc.prev_col = ctxp->elc.col;
ctxp->elc.col = ctxp->c_line->char_col - JAVA_COLUMN_DELTA (-1);
if (ctxp->elc.col < 0)
fatal ("ctxp->elc.col < 0 - java_lex");
@@ -564,7 +610,6 @@ java_lex (java_lval)
/* Numeric literals */
if (JAVA_ASCII_DIGIT (c) || (c == '.'))
{
- unicode_t peep;
/* This section of code is borrowed from gcc/c-lex.c */
#define TOTAL_PARTS ((HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR) * 2 + 2)
int parts[TOTAL_PARTS];
@@ -573,7 +618,9 @@ java_lex (java_lval)
char literal_token [256];
int literal_index = 0, radix = 10, long_suffix = 0, overflow = 0, bytes;
int i;
+#ifndef JC1_LITE
int number_beginning = ctxp->c_line->current;
+#endif
/* We might have a . separator instead of a FP like .[0-9]* */
if (c == '.')
@@ -603,7 +650,7 @@ java_lex (java_lval)
else if (c == '.')
{
/* Push the '.' back and prepare for a FP parsing... */
- java_unget_unicode (c);
+ java_unget_unicode ();
c = '0';
}
else
@@ -613,19 +660,17 @@ java_lex (java_lval)
switch (c)
{
case 'L': case 'l':
- SET_LVAL_NODE_TYPE (integer_zero_node, long_type_node);
+ SET_LVAL_NODE (long_zero_node);
return (INT_LIT_TK);
case 'f': case 'F':
- SET_LVAL_NODE_TYPE (build_real (float_type_node, dconst0),
- float_type_node);
+ SET_LVAL_NODE (float_zero_node);
return (FP_LIT_TK);
case 'd': case 'D':
- SET_LVAL_NODE_TYPE (build_real (double_type_node, dconst0),
- double_type_node);
+ SET_LVAL_NODE (double_zero_node);
return (FP_LIT_TK);
default:
- java_unget_unicode (c);
- SET_LVAL_NODE_TYPE (integer_zero_node, int_type_node);
+ java_unget_unicode ();
+ SET_LVAL_NODE (integer_zero_node);
return (INT_LIT_TK);
}
}
@@ -734,7 +779,7 @@ java_lex (java_lval)
#endif
if (stage != 4) /* Don't push back fF/dD */
- java_unget_unicode (c);
+ java_unget_unicode ();
/* An exponent (if any) must have seen a digit. */
if (seen_exponent && !seen_digit)
@@ -779,7 +824,7 @@ java_lex (java_lval)
else if (radix == 16 && !literal_index)
java_lex_error ("No digit specified for hexadecimal literal", 0);
else
- java_unget_unicode (c);
+ java_unget_unicode ();
#ifdef JAVA_LEX_DEBUG
literal_token [literal_index] = '\0'; /* So JAVA_LEX_LIT is safe. */
@@ -824,11 +869,13 @@ java_lex (java_lval)
/* 2147483648 is valid if operand of a '-'. Otherwise,
2147483647 is the biggest `int' literal that can be
expressed using a 10 radix. For other radixes, everything
- that fits within 32 bits is OK. */
+ that fits within 32 bits is OK. As all literals are
+ signed, we sign extend here. */
int hb = (low >> 31) & 0x1;
if (overflow || high || (hb && low & 0x7fffffff && radix == 10) ||
(hb && !(low & 0x7fffffff) && !ctxp->minus_seen && radix == 10))
JAVA_INTEGRAL_RANGE_ERROR ("Numeric overflow for `int' literal");
+ high = -hb;
}
ctxp->minus_seen = 0;
SET_LVAL_NODE_TYPE (build_int_2 (low, high),
@@ -873,8 +920,7 @@ java_lex (java_lval)
if (c == '\\')
c = java_parse_escape_sequence ();
no_error &= (c != JAVA_CHAR_ERROR ? 1 : 0);
- if (c)
- java_unicode_2_utf8 (c);
+ java_unicode_2_utf8 (c);
}
if (c == '\n' || c == UEOF) /* ULT */
{
@@ -885,27 +931,20 @@ java_lex (java_lval)
obstack_1grow (&temporary_obstack, '\0');
string = obstack_finish (&temporary_obstack);
- if (!no_error || (c != '"'))
- *string = '\0'; /* Silently turns the string to an empty one */
-
- JAVA_LEX_STR_LIT (string)
-
#ifndef JC1_LITE
- if (*string)
+ if (!no_error || (c != '"'))
+ java_lval->node = error_mark_node; /* Requires futher testing FIXME */
+ else
{
- extern struct obstack *expression_obstack;
tree s = make_node (STRING_CST);
TREE_STRING_LENGTH (s) = strlen (string);
TREE_STRING_POINTER (s) =
- obstack_alloc (expression_obstack, strlen (string));
+ obstack_alloc (expression_obstack, TREE_STRING_LENGTH (s)+1);
strcpy (TREE_STRING_POINTER (s), string);
java_lval->node = s;
}
- else
- java_lval->node = error_mark_node;
#endif
return STRING_LIT_TK;
-
}
/* Separator */
@@ -922,7 +961,7 @@ java_lex (java_lval)
if (ctxp->ccb_indent == 1)
ctxp->first_ccb_indent1 = lineno;
ctxp->ccb_indent++;
- return OCB_TK;
+ BUILD_OPERATOR (OCB_TK);
case '}':
JAVA_LEX_SEP (c);
ctxp->ccb_indent--;
@@ -961,7 +1000,7 @@ java_lex (java_lval)
variable_declarator: rule, it has to be seen as '=' as opposed
to being seen as an ordinary assignment operator in
assignment_operators: rule. */
- java_unget_unicode (c);
+ java_unget_unicode ();
BUILD_OPERATOR (ASSIGN_TK);
}
@@ -980,17 +1019,17 @@ java_lex (java_lval)
}
else
{
- java_unget_unicode (c);
+ java_unget_unicode ();
BUILD_OPERATOR (ZRS_TK);
}
case '=':
BUILD_OPERATOR2 (SRS_ASSIGN_TK);
default:
- java_unget_unicode (c);
+ java_unget_unicode ();
BUILD_OPERATOR (SRS_TK);
}
default:
- java_unget_unicode (c);
+ java_unget_unicode ();
BUILD_OPERATOR (GT_TK);
}
@@ -1006,11 +1045,11 @@ java_lex (java_lval)
}
else
{
- java_unget_unicode (c);
+ java_unget_unicode ();
BUILD_OPERATOR (LS_TK);
}
default:
- java_unget_unicode (c);
+ java_unget_unicode ();
BUILD_OPERATOR (LT_TK);
}
@@ -1022,7 +1061,7 @@ java_lex (java_lval)
case '=':
BUILD_OPERATOR2 (AND_ASSIGN_TK);
default:
- java_unget_unicode (c);
+ java_unget_unicode ();
BUILD_OPERATOR (AND_TK);
}
@@ -1034,7 +1073,7 @@ java_lex (java_lval)
case '=':
BUILD_OPERATOR2 (OR_ASSIGN_TK);
default:
- java_unget_unicode (c);
+ java_unget_unicode ();
BUILD_OPERATOR (OR_TK);
}
@@ -1046,7 +1085,7 @@ java_lex (java_lval)
case '=':
BUILD_OPERATOR2 (PLUS_ASSIGN_TK);
default:
- java_unget_unicode (c);
+ java_unget_unicode ();
BUILD_OPERATOR (PLUS_TK);
}
@@ -1058,7 +1097,7 @@ java_lex (java_lval)
case '=':
BUILD_OPERATOR2 (MINUS_ASSIGN_TK);
default:
- java_unget_unicode (c);
+ java_unget_unicode ();
ctxp->minus_seen = 1;
BUILD_OPERATOR (MINUS_TK);
}
@@ -1070,7 +1109,7 @@ java_lex (java_lval)
}
else
{
- java_unget_unicode (c);
+ java_unget_unicode ();
BUILD_OPERATOR (MULT_TK);
}
@@ -1081,7 +1120,7 @@ java_lex (java_lval)
}
else
{
- java_unget_unicode (c);
+ java_unget_unicode ();
BUILD_OPERATOR (DIV_TK);
}
@@ -1092,7 +1131,7 @@ java_lex (java_lval)
}
else
{
- java_unget_unicode (c);
+ java_unget_unicode ();
BUILD_OPERATOR (XOR_TK);
}
@@ -1103,7 +1142,7 @@ java_lex (java_lval)
}
else
{
- java_unget_unicode (c);
+ java_unget_unicode ();
BUILD_OPERATOR (REM_TK);
}
@@ -1114,7 +1153,7 @@ java_lex (java_lval)
}
else
{
- java_unget_unicode (c);
+ java_unget_unicode ();
BUILD_OPERATOR (NEG_TK);
}
@@ -1140,7 +1179,7 @@ java_lex (java_lval)
obstack_1grow (&temporary_obstack, '\0');
string = obstack_finish (&temporary_obstack);
- java_unget_unicode (c);
+ java_unget_unicode ();
/* If we have something all ascii, we consider a keyword, a boolean
literal, a null literal or an all ASCII identifier. Otherwise,
@@ -1194,12 +1233,19 @@ java_lex (java_lval)
SET_LVAL_NODE (null_pointer_node);
return NULL_TK;
- /* We build an operator for SUPER, so we can keep its position */
+ /* Some keyword we want to retain information on the location
+ they where found */
+ case CASE_TK:
+ case DEFAULT_TK:
case SUPER_TK:
case THIS_TK:
case RETURN_TK:
case BREAK_TK:
case CONTINUE_TK:
+ case TRY_TK:
+ case CATCH_TK:
+ case THROW_TK:
+ case INSTANCEOF_TK:
BUILD_OPERATOR (kw->token);
default:
@@ -1246,7 +1292,7 @@ java_unicode_2_utf8 (unicode)
obstack_1grow (&temporary_obstack,
(unsigned char)(0x80 | (unicode & 0x0fc0) >> 6));
obstack_1grow (&temporary_obstack,
- (unsigned char)(0x80 | (unicode & 0x003f) >> 12));
+ (unsigned char)(0x80 | (unicode & 0x003f)));
}
}
@@ -1261,8 +1307,8 @@ build_wfl_node (node)
static void
java_lex_error (msg, forward)
- char *msg;
- int forward;
+ char *msg ATTRIBUTE_UNUSED;
+ int forward ATTRIBUTE_UNUSED;
{
#ifndef JC1_LITE
ctxp->elc.line = ctxp->c_line->lineno;
@@ -1275,6 +1321,7 @@ java_lex_error (msg, forward)
#endif
}
+#ifndef JC1_LITE
static int
java_is_eol (fp, c)
FILE *fp;
@@ -1283,22 +1330,23 @@ java_is_eol (fp, c)
int next;
switch (c)
{
- case '\n':
+ case '\r':
next = getc (fp);
- if (next != '\r' && next != EOF)
+ if (next != '\n' && next != EOF)
ungetc (next, fp);
return 1;
- case '\r':
+ case '\n':
return 1;
default:
return 0;
}
}
+#endif
char *
java_get_line_col (filename, line, col)
- char *filename;
- int line, col;
+ char *filename ATTRIBUTE_UNUSED;
+ int line ATTRIBUTE_UNUSED, col ATTRIBUTE_UNUSED;
{
#ifdef JC1_LITE
return 0;
@@ -1306,11 +1354,14 @@ java_get_line_col (filename, line, col)
/* Dumb implementation. Doesn't try to cache or optimize things. */
/* First line of the file is line 1, first column is 1 */
- /* COL <= 0 means, at the CR/LF in LINE */
+ /* COL == -1 means, at the CR/LF in LINE */
+ /* COL == -2 means, at the first non space char in LINE */
FILE *fp;
int c, ccol, cline = 1;
int current_line_col = 0;
+ int first_non_space = 0;
+ char *base;
if (!(fp = fopen (filename, "r")))
fatal ("Can't open file - java_display_line_col");
@@ -1334,6 +1385,8 @@ java_get_line_col (filename, line, col)
c = getc (fp);
if (c < 0 || java_is_eol (fp, c))
break;
+ if (!first_non_space && !JAVA_WHITE_SPACE_P (c))
+ first_non_space = current_line_col;
obstack_1grow (&temporary_obstack, c);
current_line_col++;
}
@@ -1341,12 +1394,25 @@ java_get_line_col (filename, line, col)
obstack_1grow (&temporary_obstack, '\n');
- if (col < 0)
- col = current_line_col;
+ if (col == -1)
+ {
+ col = current_line_col;
+ first_non_space = 0;
+ }
+ else if (col == -2)
+ col = first_non_space;
+ else
+ first_non_space = 0;
/* Place the '^' a the right position */
+ base = obstack_base (&temporary_obstack);
for (ccol = 1; ccol <= col; ccol++)
- obstack_1grow (&temporary_obstack, ' ');
+ {
+ /* Compute \t when reaching first_non_space */
+ char c = (first_non_space ?
+ (base [ccol-1] == '\t' ? '\t' : ' ') : ' ');
+ obstack_1grow (&temporary_obstack, c);
+ }
obstack_grow0 (&temporary_obstack, "^", 1);
fclose (fp);
diff --git a/gcc/java/lex.h b/gcc/java/lex.h
index 9116e42fbe0..97c0c613ae3 100644
--- a/gcc/java/lex.h
+++ b/gcc/java/lex.h
@@ -1,5 +1,5 @@
/* Language lexer definitions for the GNU compiler for the Java(TM) language.
- Copyright (C) 1997, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc.
Contributed by Alexandre Petit-Bianco (apbianco@cygnus.com)
This file is part of GNU CC.
@@ -26,21 +26,15 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */
#ifndef JV_LEX_H
#define JV_LEX_H
+#include <setjmp.h> /* set_float_handler argument uses it */
+
/* Extern global variables declarations */
extern FILE *finput;
extern int lineno;
-extern char *classpath;
/* A Unicode character, as read from the input file */
typedef unsigned short unicode_t;
-/* Function declaration */
-static int java_lineterminator ();
-static char *java_sprint_unicode ();
-static void java_unicode_2_utf8 ();
-static void java_lex_error ();
-static void java_store_unicode ();
-
/* Debug macro to print-out what we match */
#ifdef JAVA_LEX_DEBUG
#ifdef JAVA_LEX_DEBUG_CHAR
@@ -98,14 +92,15 @@ struct java_error {
typedef struct _java_lc {
int line;
+ int prev_col;
int col;
} java_lc;
#define JAVA_LINE_MAX 80
-/* Macro to read and unread chars */
-#define UNGETC(c) ctxp->unget_utf8_value = (c);
+/* Macro to read and unread bytes */
+#define UNGETC(c) ungetc(c, finput)
#define GETC() getc(finput)
/* Build a location compound integer */
@@ -140,7 +135,7 @@ typedef struct _java_lc {
#else
-static tree build_wfl_node ();
+extern void set_float_handler PROTO((jmp_buf));
#define SET_FLOAT_HANDLER(H) set_float_handler ((H))
#define DCONST0 dconst0
#define GET_IDENTIFIER(S) get_identifier ((S))
diff --git a/gcc/java/mangle.c b/gcc/java/mangle.c
index 08f587a6c96..ebe680eb2e9 100644
--- a/gcc/java/mangle.c
+++ b/gcc/java/mangle.c
@@ -1,6 +1,6 @@
/* Functions related to mangling class names for the GNU compiler
for the Java(TM) language.
- Copyright (C) 1998 Free Software Foundation, Inc.
+ Copyright (C) 1998, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -28,7 +28,10 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */
#include "config.h"
#include "system.h"
#include "jcf.h"
+#include "tree.h"
+#include "java-tree.h"
#include "obstack.h"
+#include "toplev.h"
/* Assuming (NAME, LEN) is a Utf8-encoding string, calculate
the length of the string as mangled (a la g++) including Unicode escapes.
@@ -36,15 +39,15 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */
int
unicode_mangling_length (name, len)
- char *name;
+ const char *name;
int len;
{
- unsigned char *ptr;
- unsigned char *limit = (unsigned char *)name + len;
+ const unsigned char *ptr;
+ const unsigned char *limit = (const unsigned char *)name + len;
int need_escapes = 0;
int num_chars = 0;
int underscores = 0;
- for (ptr = (unsigned char *) name; ptr < limit; )
+ for (ptr = (const unsigned char *) name; ptr < limit; )
{
int ch = UTF8_GET(ptr, limit);
if (ch < 0)
@@ -69,11 +72,12 @@ unicode_mangling_length (name, len)
void
emit_unicode_mangled_name (obstack, name, len)
struct obstack *obstack;
- char *name;
+ const char *name;
+ int len;
{
- unsigned char *ptr;
- unsigned char *limit = (unsigned char *)name + len;
- for (ptr = (unsigned char *) name; ptr < limit; )
+ const unsigned char *ptr;
+ const unsigned char *limit = (const unsigned char *)name + len;
+ for (ptr = (const unsigned char *) name; ptr < limit; )
{
int ch = UTF8_GET(ptr, limit);
int emit_escape;
@@ -105,7 +109,7 @@ emit_unicode_mangled_name (obstack, name, len)
void
append_gpp_mangled_name (obstack, name, len)
struct obstack *obstack;
- char *name;
+ const char *name;
int len;
{
int encoded_len = unicode_mangling_length (name, len);
@@ -130,9 +134,9 @@ append_gpp_mangled_name (obstack, name, len)
void
append_gpp_mangled_classtype (obstack, class_name)
struct obstack *obstack;
- char *class_name;
+ const char *class_name;
{
- char *ptr;
+ const char *ptr;
int qualifications = 0;
for (ptr = class_name; *ptr != '\0'; ptr++)
diff --git a/gcc/java/parse-scan.y b/gcc/java/parse-scan.y
index 11c9978c67e..a8f6df645a9 100644
--- a/gcc/java/parse-scan.y
+++ b/gcc/java/parse-scan.y
@@ -1,5 +1,5 @@
/* Parser grammar for quick source code scan of Java(TM) language programs.
- Copyright (C) 1998 Free Software Foundation, Inc.
+ Copyright (C) 1998, 1999 Free Software Foundation, Inc.
Contributed by Alexandre Petit-Bianco (apbianco@cygnus.com)
This file is part of GNU CC.
@@ -37,13 +37,11 @@ definitions and other extensions. */
%{
#define JC1_LITE
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
+#include "config.h"
+#include "system.h"
-/* Definitions for PROTO and VPROTO macros */
-#include "gansidecl.h"
#include "obstack.h"
+#include "toplev.h"
extern char *input_filename;
extern FILE *finput, *out;
@@ -74,6 +72,10 @@ static int previous_output;
/* Record modifier uses */
static int modifier_value;
+/* Keep track of number of bracket pairs after a variable declarator
+ id. */
+static int bracket_count;
+
/* Record a method declaration */
struct method_declarator {
char *method_name;
@@ -91,10 +93,6 @@ struct method_declarator {
static void report_class_declaration PROTO ((char *));
static void report_main_declaration PROTO ((struct method_declarator *));
-/* Other extern functions */
-char *xmalloc PROTO ((unsigned));
-char *xstrdup PROTO ((char *));
-
#include "lex.h"
#include "parse.h"
%}
@@ -257,7 +255,7 @@ qualified_name:
name DOT_TK identifier
{
char *n = xmalloc (strlen ($1)+strlen ($3)+2);
- sprintf (n, "%s.s", $1, $3);
+ sprintf (n, "%s.%s", $1, $3);
$$ = n;
}
;
@@ -406,8 +404,9 @@ variable_declarator:
variable_declarator_id:
identifier
- { USE_ABSORBER; }
+ { bracket_count = 0; USE_ABSORBER; }
| variable_declarator_id OSB_TK CSB_TK
+ { ++bracket_count; }
;
variable_initializer:
@@ -463,10 +462,32 @@ formal_parameter:
type variable_declarator_id
{
USE_ABSORBER;
- $$ = $1;
+ if (bracket_count)
+ {
+ int i;
+ char *n = xmalloc (bracket_count + 1 + strlen ($$));
+ for (i = 0; i < bracket_count; ++i)
+ n[i] = '[';
+ strcpy (n + bracket_count, $$);
+ $$ = n;
+ }
+ else
+ $$ = $1;
}
| modifiers type variable_declarator_id /* Added, JDK1.1 final locals */
- { $$ = $2; }
+ {
+ if (bracket_count)
+ {
+ int i;
+ char *n = xmalloc (bracket_count + 1 + strlen ($$));
+ for (i = 0; i < bracket_count; ++i)
+ n[i] = '[';
+ strcpy (n + bracket_count, $$);
+ $$ = n;
+ }
+ else
+ $$ = $2;
+ }
;
throws:
@@ -1133,7 +1154,8 @@ report_main_declaration (declarator)
&& !strcmp (declarator->method_name, "main")
&& declarator->args
&& declarator->args [0] == '['
- && !strcmp( declarator->args+1, "String")
+ && (! strcmp (declarator->args+1, "String")
+ || ! strcmp (declarator->args + 1, "java.lang.String"))
&& current_class)
{
if (!previous_output)
@@ -1157,6 +1179,17 @@ void reset_report ()
void
yyerror (msg)
- char *msg;
+ char *msg ATTRIBUTE_UNUSED;
{
}
+
+char *
+xstrdup (s)
+ const char *s;
+{
+ char *ret;
+
+ ret = xmalloc (strlen (s) + 1);
+ strcpy (ret, s);
+ return ret;
+}
diff --git a/gcc/java/parse.c b/gcc/java/parse.c
index 224ae38c7f6..bdce35974c0 100644
--- a/gcc/java/parse.c
+++ b/gcc/java/parse.c
@@ -1,5 +1,5 @@
-/* A Bison parser, made from /nfs/hoser/beer/java/egcs/gcc/java/parse.y
+/* A Bison parser, made from ./parse.y
by GNU Bison version 1.25
*/
@@ -120,28 +120,203 @@
#define BOOL_LIT_TK 363
#define NULL_TK 364
-#line 49 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <dirent.h>
-#ifdef __STDC__
-#include <stdarg.h>
-#else
-#include <varargs.h>
-#endif
+#line 48 "./parse.y"
#include "config.h"
+#include "system.h"
+#include <dirent.h>
#include "tree.h"
#include "rtl.h"
#include "obstack.h"
+#include "toplev.h"
#include "flags.h"
#include "java-tree.h"
#include "jcf.h"
#include "lex.h"
#include "parse.h"
#include "zipfile.h"
+#include "convert.h"
+#include "buffer.h"
+#include "xref.h"
+
+#ifndef DIR_SEPARATOR
+#define DIR_SEPARATOR '/'
+#endif
+
+/* Local function prototypes */
+static char *java_accstring_lookup PROTO ((int));
+static void classitf_redefinition_error PROTO ((char *,tree, tree, tree));
+static void variable_redefinition_error PROTO ((tree, tree, tree, int));
+static void check_modifiers PROTO ((char *, int, int));
+static tree create_class PROTO ((int, tree, tree, tree));
+static tree create_interface PROTO ((int, tree, tree));
+static tree find_field PROTO ((tree, tree));
+static tree lookup_field_wrapper PROTO ((tree, tree));
+static int duplicate_declaration_error_p PROTO ((tree, tree, tree));
+static void register_fields PROTO ((int, tree, tree));
+static tree parser_qualified_classname PROTO ((tree));
+static int parser_check_super PROTO ((tree, tree, tree));
+static int parser_check_super_interface PROTO ((tree, tree, tree));
+static void check_modifiers_consistency PROTO ((int));
+static tree lookup_cl PROTO ((tree));
+static tree lookup_java_method2 PROTO ((tree, tree, int));
+static tree method_header PROTO ((int, tree, tree, tree));
+static void fix_method_argument_names PROTO ((tree ,tree));
+static tree method_declarator PROTO ((tree, tree));
+static void parse_warning_context PVPROTO ((tree cl, const char *msg, ...))
+ ATTRIBUTE_PRINTF_2;
+static void issue_warning_error_from_context PROTO ((tree, const char *msg, va_list));
+static tree parse_jdk1_1_error PROTO ((char *));
+static void complete_class_report_errors PROTO ((jdep *));
+static int process_imports PROTO ((void));
+static void read_import_dir PROTO ((tree));
+static int find_in_imports_on_demand PROTO ((tree));
+static int find_in_imports PROTO ((tree));
+static int check_pkg_class_access PROTO ((tree, tree));
+static tree resolve_package PROTO ((tree, tree *));
+static tree lookup_package_type PROTO ((char *, int));
+static tree resolve_class PROTO ((tree, tree, tree));
+static void declare_local_variables PROTO ((int, tree, tree));
+static void source_start_java_method PROTO ((tree));
+static void source_end_java_method PROTO ((void));
+static void expand_start_java_method PROTO ((tree));
+static tree find_name_in_single_imports PROTO ((tree));
+static void check_abstract_method_header PROTO ((tree));
+static tree lookup_java_interface_method2 PROTO ((tree, tree));
+static tree resolve_expression_name PROTO ((tree, tree *));
+static tree maybe_create_class_interface_decl PROTO ((tree, tree, tree));
+static int check_class_interface_creation PROTO ((int, int, tree,
+ tree, tree, tree));
+static tree patch_method_invocation PROTO ((tree, tree, tree,
+ int *, tree *));
+static int breakdown_qualified PROTO ((tree *, tree *, tree));
+static tree resolve_and_layout PROTO ((tree, tree));
+static tree resolve_no_layout PROTO ((tree, tree));
+static int invocation_mode PROTO ((tree, int));
+static tree find_applicable_accessible_methods_list PROTO ((int, tree,
+ tree, tree));
+static void search_applicable_methods_list PROTO ((int, tree, tree, tree,
+ tree *, tree *));
+static tree find_most_specific_methods_list PROTO ((tree));
+static int argument_types_convertible PROTO ((tree, tree));
+static tree patch_invoke PROTO ((tree, tree, tree));
+static tree lookup_method_invoke PROTO ((int, tree, tree, tree, tree));
+static tree register_incomplete_type PROTO ((int, tree, tree, tree));
+static tree obtain_incomplete_type PROTO ((tree));
+static tree java_complete_lhs PROTO ((tree));
+static tree java_complete_tree PROTO ((tree));
+static void java_complete_expand_method PROTO ((tree));
+static int unresolved_type_p PROTO ((tree, tree *));
+static void create_jdep_list PROTO ((struct parser_ctxt *));
+static tree build_expr_block PROTO ((tree, tree));
+static tree enter_block PROTO ((void));
+static tree enter_a_block PROTO ((tree));
+static tree exit_block PROTO ((void));
+static tree lookup_name_in_blocks PROTO ((tree));
+static void maybe_absorb_scoping_blocks PROTO ((void));
+static tree build_method_invocation PROTO ((tree, tree));
+static tree build_new_invocation PROTO ((tree, tree));
+static tree build_assignment PROTO ((int, int, tree, tree));
+static tree build_binop PROTO ((enum tree_code, int, tree, tree));
+static int check_final_assignment PROTO ((tree ,tree));
+static tree patch_assignment PROTO ((tree, tree, tree ));
+static tree patch_binop PROTO ((tree, tree, tree));
+static tree build_unaryop PROTO ((int, int, tree));
+static tree build_incdec PROTO ((int, int, tree, int));
+static tree patch_unaryop PROTO ((tree, tree));
+static tree build_cast PROTO ((int, tree, tree));
+static tree build_null_of_type PROTO ((tree));
+static tree patch_cast PROTO ((tree, tree));
+static int valid_ref_assignconv_cast_p PROTO ((tree, tree, int));
+static int valid_builtin_assignconv_identity_widening_p PROTO ((tree, tree));
+static int valid_cast_to_p PROTO ((tree, tree));
+static int valid_method_invocation_conversion_p PROTO ((tree, tree));
+static tree try_builtin_assignconv PROTO ((tree, tree, tree));
+static tree try_reference_assignconv PROTO ((tree, tree));
+static tree build_unresolved_array_type PROTO ((tree));
+static tree build_array_from_name PROTO ((tree, tree, tree, tree *));
+static tree build_array_ref PROTO ((int, tree, tree));
+static tree patch_array_ref PROTO ((tree));
+static tree make_qualified_name PROTO ((tree, tree, int));
+static tree merge_qualified_name PROTO ((tree, tree));
+static tree make_qualified_primary PROTO ((tree, tree, int));
+static int resolve_qualified_expression_name PROTO ((tree, tree *,
+ tree *, tree *));
+static void qualify_ambiguous_name PROTO ((tree));
+static void maybe_generate_clinit PROTO ((void));
+static tree resolve_field_access PROTO ((tree, tree *, tree *));
+static tree build_newarray_node PROTO ((tree, tree, int));
+static tree patch_newarray PROTO ((tree));
+static tree resolve_type_during_patch PROTO ((tree));
+static tree build_this PROTO ((int));
+static tree build_return PROTO ((int, tree));
+static tree patch_return PROTO ((tree));
+static tree maybe_access_field PROTO ((tree, tree, tree));
+static int complete_function_arguments PROTO ((tree));
+static int check_for_static_method_reference PROTO ((tree, tree, tree, tree, tree));
+static int not_accessible_p PROTO ((tree, tree, int));
+static void check_deprecation PROTO ((tree, tree));
+static int class_in_current_package PROTO ((tree));
+static tree build_if_else_statement PROTO ((int, tree, tree, tree));
+static tree patch_if_else_statement PROTO ((tree));
+static tree add_stmt_to_compound PROTO ((tree, tree, tree));
+static tree add_stmt_to_block PROTO ((tree, tree, tree));
+static tree patch_exit_expr PROTO ((tree));
+static tree build_labeled_block PROTO ((int, tree));
+static tree finish_labeled_statement PROTO ((tree, tree));
+static tree build_bc_statement PROTO ((int, int, tree));
+static tree patch_bc_statement PROTO ((tree));
+static tree patch_loop_statement PROTO ((tree));
+static tree build_new_loop PROTO ((tree));
+static tree build_loop_body PROTO ((int, tree, int));
+static tree finish_loop_body PROTO ((int, tree, tree, int));
+static tree build_debugable_stmt PROTO ((int, tree));
+static tree finish_for_loop PROTO ((int, tree, tree, tree));
+static tree patch_switch_statement PROTO ((tree));
+static tree string_constant_concatenation PROTO ((tree, tree));
+static tree build_string_concatenation PROTO ((tree, tree));
+static tree patch_string_cst PROTO ((tree));
+static tree patch_string PROTO ((tree));
+static tree build_try_statement PROTO ((int, tree, tree));
+static tree build_try_finally_statement PROTO ((int, tree, tree));
+static tree patch_try_statement PROTO ((tree));
+static tree patch_synchronized_statement PROTO ((tree, tree));
+static tree patch_throw_statement PROTO ((tree, tree));
+static void check_thrown_exceptions PROTO ((int, tree));
+static int check_thrown_exceptions_do PROTO ((tree));
+static void purge_unchecked_exceptions PROTO ((tree));
+static void check_throws_clauses PROTO ((tree, tree, tree));
+static void finish_method_declaration PROTO ((tree));
+static tree build_super_invocation PROTO (());
+static int verify_constructor_circularity PROTO ((tree, tree));
+static char *constructor_circularity_msg PROTO ((tree, tree));
+static tree build_this_super_qualified_invocation PROTO ((int, tree, tree,
+ int, int));
+static char *get_printable_method_name PROTO ((tree));
+static tree patch_conditional_expr PROTO ((tree, tree, tree));
+static void maybe_generate_finit PROTO (());
+static void fix_constructors PROTO ((tree));
+static int verify_constructor_super PROTO (());
+static tree create_artificial_method PROTO ((tree, int, tree, tree, tree));
+static void start_artificial_method_body PROTO ((tree));
+static void end_artificial_method_body PROTO ((tree));
+static int check_method_redefinition PROTO ((tree, tree));
+static int reset_method_name PROTO ((tree));
+static void java_check_regular_methods PROTO ((tree));
+static void java_check_abstract_methods PROTO ((tree));
+static tree maybe_build_primttype_type_ref PROTO ((tree, tree));
+static void unreachable_stmt_error PROTO ((tree));
+static tree find_expr_with_wfl PROTO ((tree));
+static void missing_return_error PROTO ((tree));
+static tree build_new_array_init PROTO ((int, tree));
+static tree patch_new_array_init PROTO ((tree, tree));
+static tree maybe_build_array_element_wfl PROTO ((tree));
+static int array_constructor_check_entry PROTO ((tree, tree));
+static char *purify_type_name PROTO ((char *));
+static tree patch_initialized_static_field PROTO ((tree));
+static tree fold_constant_for_init PROTO ((tree, tree));
+static tree strip_out_static_field_access_decl PROTO ((tree));
+static jdeplist *reverse_jdep_list PROTO ((struct parser_ctxt *));
/* Number of error found so far. */
int java_error_count;
@@ -151,6 +326,9 @@ int java_warning_count;
/* The current parser context */
static struct parser_ctxt *ctxp;
+/* List of things that were anlyzed for which code will be generated */
+static struct parser_ctxt *ctxp_for_generation = NULL;
+
/* binop_lookup maps token to tree_code. It is used where binary
operations are involved and required by the parser. RDIV_EXPR
covers both integral/floating point division. The code is changed
@@ -170,12 +348,31 @@ static enum tree_code binop_lookup[19] =
/* Fake WFL used to report error message. It is initialized once if
needed and reused with it's location information is overriden. */
-static tree wfl_operator = NULL_TREE;
+tree wfl_operator = NULL_TREE;
/* The "$L" identifier we use to create labels. */
-static tree label_id;
+static tree label_id = NULL_TREE;
+
+/* The "StringBuffer" identifier used for the String `+' operator. */
+static tree wfl_string_buffer = NULL_TREE;
-#line 104 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+/* The "append" identifier used for String `+' operator. */
+static tree wfl_append = NULL_TREE;
+
+/* The "toString" identifier used for String `+' operator. */
+static tree wfl_to_string = NULL_TREE;
+
+/* The "java.lang" import qualified name. */
+static tree java_lang_id = NULL_TREE;
+
+/* The "java.lang.Cloneable" qualified name. */
+static tree java_lang_cloneable = NULL_TREE;
+
+/* Context and flag for static blocks */
+static tree current_static_block = NULL_TREE;
+
+
+#line 300 "./parse.y"
typedef union {
tree node;
int sub_token;
@@ -185,6 +382,9 @@ typedef union {
} operator;
int value;
} YYSTYPE;
+#line 310 "./parse.y"
+
+#include "lex.c"
#ifndef YYDEBUG
#define YYDEBUG 1
#endif
@@ -199,11 +399,11 @@ typedef union {
-#define YYFINAL 772
+#define YYFINAL 775
#define YYFLAG -32768
#define YYNTBASE 110
-#define YYTRANSLATE(x) ((unsigned)(x) <= 364 ? yytranslate[x] : 259)
+#define YYTRANSLATE(x) ((unsigned)(x) <= 364 ? yytranslate[x] : 265)
static const char yytranslate[] = { 0,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
@@ -255,48 +455,48 @@ static const short yyprhs[] = { 0,
139, 141, 143, 145, 147, 149, 152, 153, 161, 162,
169, 173, 176, 180, 185, 186, 189, 193, 196, 197,
200, 203, 205, 209, 213, 216, 220, 222, 225, 227,
- 229, 231, 233, 235, 237, 239, 241, 245, 250, 252,
- 256, 260, 262, 266, 270, 275, 277, 281, 284, 288,
- 292, 294, 296, 297, 301, 304, 308, 312, 317, 322,
- 325, 329, 332, 336, 339, 343, 348, 352, 356, 360,
- 362, 366, 370, 373, 377, 380, 384, 385, 388, 391,
- 393, 397, 401, 403, 406, 408, 411, 415, 417, 421,
- 426, 431, 437, 441, 446, 449, 453, 457, 462, 467,
- 473, 481, 488, 490, 492, 493, 498, 499, 505, 506,
- 512, 513, 520, 524, 529, 532, 536, 539, 543, 546,
- 550, 552, 555, 557, 559, 561, 563, 565, 568, 571,
- 574, 578, 582, 587, 589, 593, 597, 600, 601, 606,
- 608, 611, 613, 615, 617, 620, 623, 627, 629, 631,
- 633, 635, 637, 639, 641, 643, 645, 647, 649, 651,
- 653, 655, 657, 659, 661, 663, 665, 667, 669, 671,
- 673, 676, 679, 682, 685, 688, 691, 694, 697, 701,
- 706, 711, 717, 722, 728, 735, 743, 750, 752, 754,
- 756, 758, 760, 762, 764, 770, 773, 777, 782, 790,
- 798, 804, 807, 811, 817, 820, 824, 828, 833, 835,
- 838, 841, 843, 846, 850, 853, 856, 860, 863, 868,
- 871, 874, 878, 883, 886, 888, 896, 904, 911, 915,
- 921, 926, 934, 941, 944, 947, 951, 954, 955, 957,
- 959, 962, 963, 965, 967, 971, 975, 978, 982, 985,
- 989, 992, 996, 999, 1003, 1006, 1010, 1013, 1017, 1021,
- 1024, 1028, 1034, 1040, 1043, 1048, 1052, 1054, 1058, 1062,
- 1067, 1070, 1072, 1075, 1081, 1084, 1089, 1093, 1096, 1099,
- 1101, 1103, 1105, 1107, 1111, 1113, 1115, 1117, 1119, 1123,
- 1127, 1131, 1135, 1139, 1143, 1147, 1151, 1157, 1162, 1169,
- 1175, 1180, 1186, 1192, 1199, 1203, 1207, 1212, 1218, 1221,
- 1225, 1229, 1233, 1235, 1239, 1243, 1247, 1251, 1256, 1261,
- 1266, 1271, 1275, 1279, 1281, 1284, 1288, 1292, 1295, 1298,
- 1302, 1306, 1310, 1314, 1317, 1321, 1326, 1332, 1339, 1345,
- 1352, 1357, 1362, 1367, 1372, 1376, 1381, 1385, 1390, 1392,
- 1394, 1396, 1398, 1401, 1404, 1406, 1408, 1411, 1414, 1416,
- 1419, 1422, 1425, 1428, 1431, 1434, 1436, 1439, 1442, 1444,
- 1447, 1450, 1456, 1461, 1466, 1472, 1477, 1480, 1486, 1491,
- 1497, 1499, 1503, 1507, 1511, 1515, 1519, 1523, 1525, 1529,
- 1533, 1537, 1541, 1543, 1547, 1551, 1555, 1559, 1563, 1567,
- 1569, 1573, 1577, 1581, 1585, 1589, 1593, 1597, 1601, 1605,
- 1609, 1611, 1615, 1619, 1623, 1627, 1629, 1633, 1637, 1639,
- 1643, 1647, 1649, 1653, 1657, 1659, 1663, 1667, 1669, 1673,
- 1677, 1679, 1685, 1690, 1694, 1700, 1702, 1704, 1708, 1712,
- 1714, 1716, 1718, 1720, 1722, 1724
+ 229, 231, 233, 235, 238, 240, 242, 244, 248, 253,
+ 255, 259, 263, 265, 269, 273, 278, 280, 284, 287,
+ 291, 295, 297, 299, 300, 304, 307, 311, 315, 320,
+ 325, 328, 332, 335, 339, 342, 346, 351, 355, 359,
+ 363, 365, 369, 373, 376, 380, 383, 387, 388, 391,
+ 394, 396, 400, 404, 406, 409, 411, 414, 418, 420,
+ 421, 425, 428, 432, 436, 441, 444, 448, 452, 457,
+ 462, 468, 476, 483, 485, 487, 488, 493, 494, 500,
+ 501, 507, 508, 515, 519, 524, 527, 531, 534, 538,
+ 541, 545, 547, 550, 552, 554, 556, 558, 560, 563,
+ 566, 569, 573, 578, 580, 584, 588, 591, 595, 597,
+ 599, 601, 604, 606, 608, 610, 613, 616, 620, 622,
+ 624, 626, 628, 630, 632, 634, 636, 638, 640, 642,
+ 644, 646, 648, 650, 652, 654, 656, 658, 660, 662,
+ 664, 666, 669, 672, 675, 678, 681, 684, 687, 690,
+ 694, 699, 704, 710, 715, 721, 728, 736, 743, 745,
+ 747, 749, 751, 753, 755, 757, 763, 766, 770, 775,
+ 783, 791, 792, 796, 801, 804, 808, 814, 817, 821,
+ 825, 830, 832, 835, 838, 840, 843, 847, 850, 853,
+ 857, 860, 865, 868, 871, 875, 880, 883, 885, 893,
+ 901, 908, 912, 918, 923, 931, 938, 941, 944, 948,
+ 951, 952, 954, 956, 959, 960, 962, 964, 968, 972,
+ 975, 979, 982, 986, 989, 993, 996, 1000, 1003, 1007,
+ 1010, 1014, 1018, 1021, 1025, 1031, 1037, 1040, 1045, 1049,
+ 1051, 1055, 1059, 1064, 1067, 1069, 1072, 1075, 1080, 1083,
+ 1087, 1092, 1095, 1098, 1100, 1102, 1104, 1106, 1110, 1112,
+ 1114, 1116, 1118, 1122, 1126, 1130, 1134, 1138, 1142, 1146,
+ 1150, 1156, 1161, 1168, 1174, 1179, 1185, 1191, 1198, 1202,
+ 1206, 1211, 1217, 1220, 1224, 1228, 1232, 1234, 1238, 1242,
+ 1246, 1250, 1255, 1260, 1265, 1270, 1274, 1278, 1280, 1283,
+ 1287, 1291, 1294, 1297, 1301, 1305, 1309, 1313, 1316, 1320,
+ 1325, 1331, 1338, 1344, 1351, 1356, 1361, 1366, 1371, 1375,
+ 1380, 1384, 1389, 1391, 1393, 1395, 1397, 1400, 1403, 1405,
+ 1407, 1410, 1413, 1415, 1418, 1421, 1424, 1427, 1430, 1433,
+ 1435, 1438, 1441, 1443, 1446, 1449, 1455, 1460, 1465, 1471,
+ 1476, 1479, 1485, 1490, 1496, 1498, 1502, 1506, 1510, 1514,
+ 1518, 1522, 1524, 1528, 1532, 1536, 1540, 1542, 1546, 1550,
+ 1554, 1558, 1562, 1566, 1568, 1572, 1576, 1580, 1584, 1588,
+ 1592, 1596, 1600, 1604, 1608, 1610, 1614, 1618, 1622, 1626,
+ 1628, 1632, 1636, 1638, 1642, 1646, 1648, 1652, 1656, 1658,
+ 1662, 1666, 1668, 1672, 1676, 1678, 1684, 1689, 1693, 1699,
+ 1701, 1703, 1707, 1711, 1713, 1715, 1717, 1719, 1721, 1723
};
static const short yyrhs[] = { 123,
@@ -314,7 +514,7 @@ static const short yyrhs[] = { 123,
55, 119, 99, 0, 55, 1, 0, 55, 119, 1,
0, 55, 119, 101, 5, 99, 0, 55, 119, 101,
1, 0, 55, 119, 101, 5, 1, 0, 132, 0,
- 163, 0, 99, 0, 1, 0, 44, 0, 131, 44,
+ 165, 0, 99, 0, 1, 0, 44, 0, 131, 44,
0, 0, 131, 67, 122, 135, 136, 133, 138, 0,
0, 67, 122, 135, 136, 134, 138, 0, 131, 67,
1, 0, 67, 1, 0, 67, 122, 1, 0, 131,
@@ -323,212 +523,212 @@ static const short yyrhs[] = { 123,
1, 0, 117, 0, 137, 100, 117, 0, 137, 100,
1, 0, 95, 96, 0, 95, 139, 96, 0, 140,
0, 139, 140, 0, 141, 0, 156, 0, 158, 0,
- 176, 0, 142, 0, 147, 0, 132, 0, 163, 0,
- 112, 143, 99, 0, 131, 112, 143, 99, 0, 144,
- 0, 143, 100, 144, 0, 143, 100, 1, 0, 145,
- 0, 145, 92, 146, 0, 145, 92, 1, 0, 145,
- 92, 146, 1, 0, 122, 0, 145, 97, 98, 0,
- 122, 1, 0, 145, 97, 1, 0, 145, 98, 1,
- 0, 257, 0, 174, 0, 0, 149, 148, 155, 0,
- 149, 1, 0, 112, 150, 153, 0, 59, 150, 153,
- 0, 131, 112, 150, 153, 0, 131, 59, 150, 153,
- 0, 112, 1, 0, 131, 112, 1, 0, 59, 1,
- 0, 131, 59, 1, 0, 131, 1, 0, 122, 93,
- 94, 0, 122, 93, 151, 94, 0, 150, 97, 98,
- 0, 122, 93, 1, 0, 150, 97, 1, 0, 152,
- 0, 151, 100, 152, 0, 151, 100, 1, 0, 112,
- 145, 0, 131, 112, 145, 0, 112, 1, 0, 131,
- 112, 1, 0, 0, 53, 154, 0, 53, 1, 0,
- 116, 0, 154, 100, 116, 0, 154, 100, 1, 0,
- 176, 0, 176, 99, 0, 99, 0, 157, 176, 0,
- 157, 176, 99, 0, 44, 0, 159, 153, 160, 0,
- 131, 159, 153, 160, 0, 159, 153, 160, 99, 0,
- 131, 159, 153, 160, 99, 0, 120, 93, 94, 0,
- 120, 93, 151, 94, 0, 95, 96, 0, 95, 161,
- 96, 0, 95, 178, 96, 0, 95, 161, 178, 96,
- 0, 162, 93, 94, 99, 0, 162, 93, 226, 94,
- 99, 0, 119, 101, 65, 93, 226, 94, 99, 0,
- 119, 101, 65, 93, 94, 99, 0, 76, 0, 65,
- 0, 0, 61, 122, 164, 169, 0, 0, 131, 61,
- 122, 165, 169, 0, 0, 61, 122, 168, 166, 169,
- 0, 0, 131, 61, 122, 168, 167, 169, 0, 61,
- 122, 1, 0, 131, 61, 122, 1, 0, 63, 117,
- 0, 168, 100, 117, 0, 63, 1, 0, 168, 100,
- 1, 0, 95, 96, 0, 95, 170, 96, 0, 171,
- 0, 170, 171, 0, 172, 0, 173, 0, 132, 0,
- 163, 0, 142, 0, 149, 99, 0, 149, 1, 0,
- 95, 96, 0, 95, 175, 96, 0, 95, 100, 96,
- 0, 95, 175, 100, 96, 0, 146, 0, 175, 100,
- 146, 0, 175, 100, 1, 0, 95, 96, 0, 0,
- 95, 177, 178, 96, 0, 179, 0, 178, 179, 0,
- 180, 0, 182, 0, 132, 0, 181, 99, 0, 112,
- 143, 0, 131, 112, 143, 0, 184, 0, 187, 0,
- 191, 0, 192, 0, 201, 0, 205, 0, 184, 0,
- 188, 0, 193, 0, 202, 0, 206, 0, 176, 0,
- 185, 0, 189, 0, 194, 0, 204, 0, 212, 0,
- 213, 0, 214, 0, 216, 0, 215, 0, 218, 0,
- 99, 0, 122, 88, 0, 186, 182, 0, 122, 1,
- 0, 186, 183, 0, 190, 99, 0, 1, 99, 0,
- 1, 95, 0, 1, 96, 0, 162, 93, 1, 0,
- 162, 93, 94, 1, 0, 162, 93, 226, 1, 0,
- 162, 93, 226, 94, 1, 0, 119, 101, 65, 1,
- 0, 119, 101, 65, 93, 1, 0, 119, 101, 65,
- 93, 226, 1, 0, 119, 101, 65, 93, 226, 94,
- 1, 0, 119, 101, 65, 93, 94, 1, 0, 254,
- 0, 238, 0, 239, 0, 235, 0, 236, 0, 232,
- 0, 224, 0, 48, 93, 257, 94, 182, 0, 48,
- 1, 0, 48, 93, 1, 0, 48, 93, 257, 1,
- 0, 48, 93, 257, 94, 183, 56, 182, 0, 48,
- 93, 257, 94, 183, 56, 183, 0, 68, 93, 257,
- 94, 195, 0, 68, 1, 0, 68, 93, 1, 0,
- 68, 93, 257, 94, 1, 0, 95, 96, 0, 95,
- 198, 96, 0, 95, 196, 96, 0, 95, 196, 198,
- 96, 0, 197, 0, 196, 197, 0, 198, 178, 0,
- 199, 0, 198, 199, 0, 62, 258, 88, 0, 47,
- 88, 0, 62, 1, 0, 62, 258, 1, 0, 47,
- 1, 0, 66, 93, 257, 94, 0, 200, 182, 0,
- 66, 1, 0, 66, 93, 1, 0, 66, 93, 257,
- 1, 0, 200, 183, 0, 51, 0, 203, 182, 66,
- 93, 257, 94, 99, 0, 208, 99, 257, 99, 210,
- 94, 182, 0, 208, 99, 99, 210, 94, 182, 0,
- 208, 99, 1, 0, 208, 99, 257, 99, 1, 0,
- 208, 99, 99, 1, 0, 208, 99, 257, 99, 210,
- 94, 183, 0, 208, 99, 99, 210, 94, 183, 0,
- 71, 93, 0, 71, 1, 0, 71, 93, 1, 0,
- 207, 209, 0, 0, 211, 0, 181, 0, 211, 1,
- 0, 0, 211, 0, 190, 0, 211, 100, 190, 0,
- 211, 100, 1, 0, 54, 99, 0, 54, 122, 99,
- 0, 54, 1, 0, 54, 122, 1, 0, 73, 99,
- 0, 73, 122, 99, 0, 73, 1, 0, 73, 122,
- 1, 0, 58, 99, 0, 58, 257, 99, 0, 58,
- 1, 0, 58, 257, 1, 0, 49, 257, 99, 0,
- 49, 1, 0, 49, 257, 1, 0, 217, 93, 257,
- 94, 176, 0, 217, 93, 257, 94, 1, 0, 217,
- 1, 0, 217, 93, 1, 94, 0, 217, 93, 1,
- 0, 44, 0, 70, 176, 219, 0, 70, 176, 221,
- 0, 70, 176, 219, 221, 0, 70, 1, 0, 220,
- 0, 219, 220, 0, 60, 93, 152, 94, 176, 0,
- 60, 1, 0, 60, 93, 1, 94, 0, 60, 93,
- 1, 0, 64, 176, 0, 64, 1, 0, 223, 0,
- 227, 0, 111, 0, 76, 0, 93, 257, 94, 0,
- 224, 0, 231, 0, 232, 0, 233, 0, 119, 101,
- 67, 0, 113, 101, 67, 0, 59, 101, 67, 0,
- 119, 101, 76, 0, 93, 257, 1, 0, 119, 101,
- 1, 0, 113, 101, 1, 0, 59, 101, 1, 0,
- 72, 116, 93, 226, 94, 0, 72, 116, 93, 94,
- 0, 72, 116, 93, 226, 94, 138, 0, 72, 116,
- 93, 94, 138, 0, 225, 122, 93, 94, 0, 225,
- 122, 93, 94, 138, 0, 225, 122, 93, 226, 94,
- 0, 225, 122, 93, 226, 94, 138, 0, 72, 1,
- 99, 0, 72, 116, 1, 0, 72, 116, 93, 1,
- 0, 72, 116, 93, 226, 1, 0, 225, 1, 0,
- 225, 122, 1, 0, 119, 101, 72, 0, 222, 101,
- 72, 0, 257, 0, 226, 100, 257, 0, 226, 100,
- 1, 0, 72, 113, 228, 0, 72, 115, 228, 0,
- 72, 113, 228, 230, 0, 72, 115, 228, 230, 0,
- 72, 115, 230, 174, 0, 72, 113, 230, 174, 0,
- 72, 1, 98, 0, 72, 1, 97, 0, 229, 0,
- 228, 229, 0, 97, 257, 98, 0, 97, 257, 1,
- 0, 97, 1, 0, 97, 98, 0, 230, 97, 98,
- 0, 230, 97, 1, 0, 222, 101, 122, 0, 65,
- 101, 122, 0, 65, 1, 0, 119, 93, 94, 0,
- 119, 93, 226, 94, 0, 222, 101, 122, 93, 94,
- 0, 222, 101, 122, 93, 226, 94, 0, 65, 101,
- 122, 93, 94, 0, 65, 101, 122, 93, 226, 94,
- 0, 65, 101, 1, 94, 0, 65, 101, 1, 101,
- 0, 119, 97, 257, 98, 0, 223, 97, 257, 98,
- 0, 119, 97, 1, 0, 119, 97, 257, 1, 0,
- 223, 97, 1, 0, 223, 97, 257, 1, 0, 222,
- 0, 119, 0, 235, 0, 236, 0, 234, 46, 0,
- 234, 45, 0, 238, 0, 239, 0, 3, 237, 0,
- 4, 237, 0, 240, 0, 3, 1, 0, 4, 1,
- 0, 46, 237, 0, 46, 1, 0, 45, 237, 0,
- 45, 1, 0, 234, 0, 89, 237, 0, 90, 237,
- 0, 241, 0, 89, 1, 0, 90, 1, 0, 93,
- 113, 230, 94, 237, 0, 93, 113, 94, 237, 0,
- 93, 257, 94, 240, 0, 93, 119, 230, 94, 240,
- 0, 93, 113, 97, 1, 0, 93, 1, 0, 93,
- 113, 230, 94, 1, 0, 93, 113, 94, 1, 0,
- 93, 119, 230, 94, 1, 0, 237, 0, 242, 5,
- 237, 0, 242, 6, 237, 0, 242, 7, 237, 0,
- 242, 5, 1, 0, 242, 6, 1, 0, 242, 7,
- 1, 0, 242, 0, 243, 3, 242, 0, 243, 4,
- 242, 0, 243, 3, 1, 0, 243, 4, 1, 0,
- 243, 0, 244, 8, 243, 0, 244, 9, 243, 0,
- 244, 10, 243, 0, 244, 8, 1, 0, 244, 9,
- 1, 0, 244, 10, 1, 0, 244, 0, 245, 20,
- 244, 0, 245, 18, 244, 0, 245, 21, 244, 0,
- 245, 19, 244, 0, 245, 57, 114, 0, 245, 20,
- 1, 0, 245, 18, 1, 0, 245, 21, 1, 0,
- 245, 19, 1, 0, 245, 57, 1, 0, 245, 0,
- 246, 16, 245, 0, 246, 17, 245, 0, 246, 16,
- 1, 0, 246, 17, 1, 0, 246, 0, 247, 11,
- 246, 0, 247, 11, 1, 0, 247, 0, 248, 12,
- 247, 0, 248, 12, 1, 0, 248, 0, 249, 13,
- 248, 0, 249, 13, 1, 0, 249, 0, 250, 14,
- 249, 0, 250, 14, 1, 0, 250, 0, 251, 15,
- 250, 0, 251, 15, 1, 0, 251, 0, 251, 87,
- 257, 88, 252, 0, 251, 87, 88, 1, 0, 251,
- 87, 1, 0, 251, 87, 257, 88, 1, 0, 252,
- 0, 254, 0, 255, 256, 253, 0, 255, 256, 1,
- 0, 119, 0, 231, 0, 233, 0, 91, 0, 92,
- 0, 253, 0, 257, 0
+ 178, 0, 142, 0, 142, 99, 0, 147, 0, 132,
+ 0, 165, 0, 112, 143, 99, 0, 131, 112, 143,
+ 99, 0, 144, 0, 143, 100, 144, 0, 143, 100,
+ 1, 0, 145, 0, 145, 92, 146, 0, 145, 92,
+ 1, 0, 145, 92, 146, 1, 0, 122, 0, 145,
+ 97, 98, 0, 122, 1, 0, 145, 97, 1, 0,
+ 145, 98, 1, 0, 263, 0, 176, 0, 0, 149,
+ 148, 155, 0, 149, 1, 0, 112, 150, 153, 0,
+ 59, 150, 153, 0, 131, 112, 150, 153, 0, 131,
+ 59, 150, 153, 0, 112, 1, 0, 131, 112, 1,
+ 0, 59, 1, 0, 131, 59, 1, 0, 131, 1,
+ 0, 122, 93, 94, 0, 122, 93, 151, 94, 0,
+ 150, 97, 98, 0, 122, 93, 1, 0, 150, 97,
+ 1, 0, 152, 0, 151, 100, 152, 0, 151, 100,
+ 1, 0, 112, 145, 0, 131, 112, 145, 0, 112,
+ 1, 0, 131, 112, 1, 0, 0, 53, 154, 0,
+ 53, 1, 0, 116, 0, 154, 100, 116, 0, 154,
+ 100, 1, 0, 178, 0, 178, 99, 0, 99, 0,
+ 157, 178, 0, 157, 178, 99, 0, 44, 0, 0,
+ 160, 159, 162, 0, 161, 153, 0, 131, 161, 153,
+ 0, 120, 93, 94, 0, 120, 93, 151, 94, 0,
+ 179, 180, 0, 179, 163, 180, 0, 179, 181, 180,
+ 0, 179, 163, 181, 180, 0, 164, 93, 94, 99,
+ 0, 164, 93, 232, 94, 99, 0, 119, 101, 65,
+ 93, 232, 94, 99, 0, 119, 101, 65, 93, 94,
+ 99, 0, 76, 0, 65, 0, 0, 61, 122, 166,
+ 171, 0, 0, 131, 61, 122, 167, 171, 0, 0,
+ 61, 122, 170, 168, 171, 0, 0, 131, 61, 122,
+ 170, 169, 171, 0, 61, 122, 1, 0, 131, 61,
+ 122, 1, 0, 63, 117, 0, 170, 100, 117, 0,
+ 63, 1, 0, 170, 100, 1, 0, 95, 96, 0,
+ 95, 172, 96, 0, 173, 0, 172, 173, 0, 174,
+ 0, 175, 0, 132, 0, 165, 0, 142, 0, 149,
+ 99, 0, 149, 1, 0, 95, 96, 0, 95, 177,
+ 96, 0, 95, 177, 100, 96, 0, 146, 0, 177,
+ 100, 146, 0, 177, 100, 1, 0, 95, 96, 0,
+ 179, 181, 180, 0, 95, 0, 96, 0, 182, 0,
+ 181, 182, 0, 183, 0, 185, 0, 132, 0, 184,
+ 99, 0, 112, 143, 0, 131, 112, 143, 0, 187,
+ 0, 190, 0, 194, 0, 195, 0, 206, 0, 210,
+ 0, 187, 0, 191, 0, 196, 0, 207, 0, 211,
+ 0, 178, 0, 188, 0, 192, 0, 197, 0, 209,
+ 0, 217, 0, 218, 0, 219, 0, 221, 0, 220,
+ 0, 223, 0, 99, 0, 122, 88, 0, 189, 185,
+ 0, 122, 1, 0, 189, 186, 0, 193, 99, 0,
+ 1, 99, 0, 1, 95, 0, 1, 96, 0, 164,
+ 93, 1, 0, 164, 93, 94, 1, 0, 164, 93,
+ 232, 1, 0, 164, 93, 232, 94, 1, 0, 119,
+ 101, 65, 1, 0, 119, 101, 65, 93, 1, 0,
+ 119, 101, 65, 93, 232, 1, 0, 119, 101, 65,
+ 93, 232, 94, 1, 0, 119, 101, 65, 93, 94,
+ 1, 0, 260, 0, 244, 0, 245, 0, 241, 0,
+ 242, 0, 238, 0, 230, 0, 48, 93, 263, 94,
+ 185, 0, 48, 1, 0, 48, 93, 1, 0, 48,
+ 93, 263, 1, 0, 48, 93, 263, 94, 186, 56,
+ 185, 0, 48, 93, 263, 94, 186, 56, 186, 0,
+ 0, 199, 198, 200, 0, 68, 93, 263, 94, 0,
+ 68, 1, 0, 68, 93, 1, 0, 68, 93, 263,
+ 94, 1, 0, 95, 96, 0, 95, 203, 96, 0,
+ 95, 201, 96, 0, 95, 201, 203, 96, 0, 202,
+ 0, 201, 202, 0, 203, 181, 0, 204, 0, 203,
+ 204, 0, 62, 264, 88, 0, 47, 88, 0, 62,
+ 1, 0, 62, 264, 1, 0, 47, 1, 0, 66,
+ 93, 263, 94, 0, 205, 185, 0, 66, 1, 0,
+ 66, 93, 1, 0, 66, 93, 263, 1, 0, 205,
+ 186, 0, 51, 0, 208, 185, 66, 93, 263, 94,
+ 99, 0, 213, 99, 263, 99, 215, 94, 185, 0,
+ 213, 99, 99, 215, 94, 185, 0, 213, 99, 1,
+ 0, 213, 99, 263, 99, 1, 0, 213, 99, 99,
+ 1, 0, 213, 99, 263, 99, 215, 94, 186, 0,
+ 213, 99, 99, 215, 94, 186, 0, 71, 93, 0,
+ 71, 1, 0, 71, 93, 1, 0, 212, 214, 0,
+ 0, 216, 0, 184, 0, 216, 1, 0, 0, 216,
+ 0, 193, 0, 216, 100, 193, 0, 216, 100, 1,
+ 0, 54, 99, 0, 54, 122, 99, 0, 54, 1,
+ 0, 54, 122, 1, 0, 73, 99, 0, 73, 122,
+ 99, 0, 73, 1, 0, 73, 122, 1, 0, 58,
+ 99, 0, 58, 263, 99, 0, 58, 1, 0, 58,
+ 263, 1, 0, 49, 263, 99, 0, 49, 1, 0,
+ 49, 263, 1, 0, 222, 93, 263, 94, 178, 0,
+ 222, 93, 263, 94, 1, 0, 222, 1, 0, 222,
+ 93, 1, 94, 0, 222, 93, 1, 0, 44, 0,
+ 70, 178, 224, 0, 70, 178, 227, 0, 70, 178,
+ 224, 227, 0, 70, 1, 0, 225, 0, 224, 225,
+ 0, 226, 178, 0, 60, 93, 152, 94, 0, 60,
+ 1, 0, 60, 93, 1, 0, 60, 93, 1, 94,
+ 0, 64, 178, 0, 64, 1, 0, 229, 0, 233,
+ 0, 111, 0, 76, 0, 93, 263, 94, 0, 230,
+ 0, 237, 0, 238, 0, 239, 0, 119, 101, 67,
+ 0, 113, 101, 67, 0, 59, 101, 67, 0, 119,
+ 101, 76, 0, 93, 263, 1, 0, 119, 101, 1,
+ 0, 113, 101, 1, 0, 59, 101, 1, 0, 72,
+ 116, 93, 232, 94, 0, 72, 116, 93, 94, 0,
+ 72, 116, 93, 232, 94, 138, 0, 72, 116, 93,
+ 94, 138, 0, 231, 122, 93, 94, 0, 231, 122,
+ 93, 94, 138, 0, 231, 122, 93, 232, 94, 0,
+ 231, 122, 93, 232, 94, 138, 0, 72, 1, 99,
+ 0, 72, 116, 1, 0, 72, 116, 93, 1, 0,
+ 72, 116, 93, 232, 1, 0, 231, 1, 0, 231,
+ 122, 1, 0, 119, 101, 72, 0, 228, 101, 72,
+ 0, 263, 0, 232, 100, 263, 0, 232, 100, 1,
+ 0, 72, 113, 234, 0, 72, 115, 234, 0, 72,
+ 113, 234, 236, 0, 72, 115, 234, 236, 0, 72,
+ 115, 236, 176, 0, 72, 113, 236, 176, 0, 72,
+ 1, 98, 0, 72, 1, 97, 0, 235, 0, 234,
+ 235, 0, 97, 263, 98, 0, 97, 263, 1, 0,
+ 97, 1, 0, 97, 98, 0, 236, 97, 98, 0,
+ 236, 97, 1, 0, 228, 101, 122, 0, 65, 101,
+ 122, 0, 65, 1, 0, 119, 93, 94, 0, 119,
+ 93, 232, 94, 0, 228, 101, 122, 93, 94, 0,
+ 228, 101, 122, 93, 232, 94, 0, 65, 101, 122,
+ 93, 94, 0, 65, 101, 122, 93, 232, 94, 0,
+ 65, 101, 1, 94, 0, 65, 101, 1, 101, 0,
+ 119, 97, 263, 98, 0, 229, 97, 263, 98, 0,
+ 119, 97, 1, 0, 119, 97, 263, 1, 0, 229,
+ 97, 1, 0, 229, 97, 263, 1, 0, 228, 0,
+ 119, 0, 241, 0, 242, 0, 240, 46, 0, 240,
+ 45, 0, 244, 0, 245, 0, 3, 243, 0, 4,
+ 243, 0, 246, 0, 3, 1, 0, 4, 1, 0,
+ 46, 243, 0, 46, 1, 0, 45, 243, 0, 45,
+ 1, 0, 240, 0, 89, 243, 0, 90, 243, 0,
+ 247, 0, 89, 1, 0, 90, 1, 0, 93, 113,
+ 236, 94, 243, 0, 93, 113, 94, 243, 0, 93,
+ 263, 94, 246, 0, 93, 119, 236, 94, 246, 0,
+ 93, 113, 97, 1, 0, 93, 1, 0, 93, 113,
+ 236, 94, 1, 0, 93, 113, 94, 1, 0, 93,
+ 119, 236, 94, 1, 0, 243, 0, 248, 5, 243,
+ 0, 248, 6, 243, 0, 248, 7, 243, 0, 248,
+ 5, 1, 0, 248, 6, 1, 0, 248, 7, 1,
+ 0, 248, 0, 249, 3, 248, 0, 249, 4, 248,
+ 0, 249, 3, 1, 0, 249, 4, 1, 0, 249,
+ 0, 250, 8, 249, 0, 250, 9, 249, 0, 250,
+ 10, 249, 0, 250, 8, 1, 0, 250, 9, 1,
+ 0, 250, 10, 1, 0, 250, 0, 251, 20, 250,
+ 0, 251, 18, 250, 0, 251, 21, 250, 0, 251,
+ 19, 250, 0, 251, 57, 114, 0, 251, 20, 1,
+ 0, 251, 18, 1, 0, 251, 21, 1, 0, 251,
+ 19, 1, 0, 251, 57, 1, 0, 251, 0, 252,
+ 16, 251, 0, 252, 17, 251, 0, 252, 16, 1,
+ 0, 252, 17, 1, 0, 252, 0, 253, 11, 252,
+ 0, 253, 11, 1, 0, 253, 0, 254, 12, 253,
+ 0, 254, 12, 1, 0, 254, 0, 255, 13, 254,
+ 0, 255, 13, 1, 0, 255, 0, 256, 14, 255,
+ 0, 256, 14, 1, 0, 256, 0, 257, 15, 256,
+ 0, 257, 15, 1, 0, 257, 0, 257, 87, 263,
+ 88, 258, 0, 257, 87, 88, 1, 0, 257, 87,
+ 1, 0, 257, 87, 263, 88, 1, 0, 258, 0,
+ 260, 0, 261, 262, 259, 0, 261, 262, 1, 0,
+ 119, 0, 237, 0, 239, 0, 91, 0, 92, 0,
+ 259, 0, 263, 0
};
#endif
#if YYDEBUG != 0
static const short yyrline[] = { 0,
- 251, 257, 259, 260, 261, 262, 263, 267, 269, 272,
- 274, 275, 278, 280, 283, 287, 291, 295, 301, 303,
- 305, 307, 312, 314, 317, 321, 326, 331, 333, 334,
- 335, 336, 337, 338, 339, 342, 347, 353, 355, 358,
- 361, 363, 367, 369, 372, 402, 404, 408, 421, 423,
- 427, 433, 434, 436, 446, 451, 466, 470, 473, 476,
- 479, 481, 483, 485, 489, 491, 493, 495, 499, 501,
- 503, 510, 516, 521, 525, 528, 532, 534, 537, 539,
- 540, 541, 544, 546, 547, 548, 552, 555, 567, 570,
- 572, 576, 579, 586, 592, 600, 602, 606, 608, 610,
- 614, 616, 621, 628, 640, 644, 647, 649, 651, 653,
- 655, 657, 659, 661, 668, 671, 673, 678, 680, 684,
- 689, 694, 698, 703, 708, 710, 717, 718, 719, 723,
- 725, 726, 730, 732, 733, 738, 743, 749, 761, 766,
- 772, 777, 786, 788, 791, 793, 794, 795, 799, 801,
- 804, 805, 809, 816, 826, 830, 833, 836, 839, 842,
- 845, 848, 851, 853, 857, 863, 868, 870, 874, 877,
- 881, 883, 886, 888, 889, 890, 893, 897, 903, 908,
- 913, 917, 921, 927, 929, 930, 935, 938, 941, 948,
- 950, 953, 955, 957, 960, 964, 967, 971, 973, 975,
- 977, 979, 981, 991, 993, 995, 997, 999, 1003, 1006,
- 1008, 1010, 1012, 1014, 1016, 1018, 1019, 1021, 1023, 1027,
- 1032, 1043, 1050, 1054, 1065, 1075, 1081, 1087, 1093, 1095,
- 1097, 1099, 1101, 1103, 1105, 1107, 1109, 1113, 1115, 1119,
- 1123, 1127, 1131, 1132, 1138, 1141, 1143, 1145, 1149, 1154,
- 1159, 1161, 1163, 1165, 1169, 1171, 1172, 1173, 1176, 1178,
- 1181, 1186, 1188, 1191, 1193, 1194, 1196, 1198, 1202, 1210,
- 1213, 1215, 1217, 1221, 1226, 1235, 1240, 1243, 1250, 1252,
- 1254, 1258, 1261, 1270, 1277, 1279, 1283, 1296, 1298, 1304,
- 1310, 1314, 1316, 1320, 1323, 1325, 1329, 1332, 1334, 1336,
- 1340, 1343, 1345, 1347, 1351, 1354, 1356, 1358, 1362, 1364,
- 1366, 1370, 1372, 1374, 1376, 1378, 1382, 1389, 1391, 1392,
- 1393, 1397, 1399, 1402, 1404, 1406, 1408, 1412, 1414, 1419,
- 1421, 1424, 1426, 1428, 1430, 1431, 1432, 1433, 1437, 1438,
- 1439, 1443, 1444, 1446, 1448, 1450, 1454, 1460, 1468, 1470,
- 1475, 1476, 1477, 1478, 1479, 1481, 1483, 1485, 1487, 1489,
- 1493, 1495, 1498, 1504, 1509, 1513, 1516, 1518, 1520, 1524,
- 1526, 1528, 1530, 1534, 1537, 1541, 1547, 1549, 1557, 1560,
- 1562, 1566, 1569, 1576, 1580, 1583, 1585, 1590, 1595, 1603,
- 1615, 1617, 1621, 1624, 1626, 1631, 1636, 1641, 1648, 1650,
- 1651, 1652, 1655, 1660, 1665, 1667, 1668, 1670, 1672, 1673,
- 1675, 1679, 1682, 1686, 1689, 1693, 1695, 1697, 1699, 1700,
- 1702, 1706, 1714, 1716, 1718, 1730, 1732, 1738, 1740, 1742,
- 1746, 1748, 1753, 1758, 1763, 1765, 1767, 1771, 1773, 1778,
- 1783, 1785, 1789, 1791, 1796, 1801, 1806, 1808, 1810, 1814,
- 1816, 1821, 1826, 1831, 1836, 1837, 1839, 1841, 1843, 1845,
- 1849, 1851, 1856, 1861, 1863, 1867, 1869, 1874, 1878, 1880,
- 1885, 1889, 1891, 1896, 1900, 1902, 1907, 1911, 1913, 1918,
- 1922, 1924, 1925, 1931, 1933, 1937, 1939, 1942, 1945, 1953,
- 1955, 1956, 1959, 1961, 1964, 1968
+ 454, 460, 462, 463, 464, 465, 466, 470, 472, 475,
+ 477, 478, 481, 483, 486, 490, 494, 498, 504, 506,
+ 508, 510, 515, 517, 520, 524, 529, 534, 536, 537,
+ 538, 539, 540, 541, 542, 545, 550, 556, 558, 561,
+ 564, 566, 570, 572, 575, 602, 604, 608, 621, 623,
+ 627, 634, 635, 637, 647, 652, 667, 671, 674, 677,
+ 680, 682, 684, 689, 693, 695, 697, 699, 703, 705,
+ 707, 714, 720, 725, 729, 732, 736, 738, 741, 743,
+ 744, 745, 749, 751, 753, 754, 756, 761, 764, 774,
+ 777, 779, 783, 786, 793, 799, 807, 809, 811, 813,
+ 815, 819, 821, 825, 832, 833, 837, 840, 842, 844,
+ 846, 848, 850, 852, 854, 861, 864, 866, 875, 877,
+ 881, 886, 891, 895, 900, 902, 904, 911, 913, 915,
+ 919, 922, 924, 928, 930, 931, 936, 942, 949, 957,
+ 964, 967, 970, 974, 977, 981, 990, 992, 994, 999,
+ 1006, 1014, 1016, 1020, 1027, 1037, 1041, 1044, 1047, 1050,
+ 1053, 1056, 1059, 1062, 1064, 1068, 1074, 1079, 1081, 1085,
+ 1088, 1092, 1094, 1097, 1099, 1100, 1102, 1106, 1110, 1116,
+ 1121, 1124, 1126, 1130, 1136, 1140, 1145, 1148, 1152, 1157,
+ 1165, 1167, 1170, 1172, 1174, 1178, 1182, 1185, 1189, 1191,
+ 1192, 1193, 1194, 1195, 1205, 1207, 1208, 1209, 1210, 1213,
+ 1215, 1216, 1217, 1218, 1219, 1220, 1221, 1222, 1223, 1224,
+ 1227, 1232, 1243, 1246, 1250, 1257, 1267, 1273, 1279, 1285,
+ 1287, 1293, 1295, 1301, 1303, 1305, 1307, 1309, 1313, 1315,
+ 1316, 1317, 1318, 1319, 1320, 1323, 1329, 1331, 1333, 1337,
+ 1342, 1347, 1353, 1363, 1369, 1371, 1373, 1380, 1383, 1385,
+ 1387, 1391, 1393, 1396, 1400, 1402, 1405, 1412, 1418, 1420,
+ 1422, 1426, 1434, 1437, 1439, 1441, 1445, 1450, 1459, 1464,
+ 1467, 1474, 1476, 1478, 1482, 1485, 1494, 1501, 1503, 1507,
+ 1520, 1522, 1528, 1534, 1538, 1540, 1544, 1547, 1549, 1553,
+ 1556, 1558, 1560, 1564, 1567, 1569, 1571, 1575, 1578, 1580,
+ 1582, 1586, 1592, 1594, 1598, 1605, 1607, 1609, 1611, 1615,
+ 1623, 1626, 1628, 1633, 1637, 1639, 1646, 1654, 1671, 1673,
+ 1675, 1679, 1682, 1687, 1689, 1692, 1694, 1696, 1698, 1699,
+ 1700, 1701, 1705, 1707, 1709, 1714, 1716, 1718, 1720, 1722,
+ 1726, 1729, 1734, 1736, 1741, 1742, 1743, 1744, 1745, 1747,
+ 1749, 1751, 1753, 1755, 1759, 1761, 1764, 1770, 1775, 1779,
+ 1782, 1784, 1786, 1790, 1792, 1794, 1796, 1800, 1803, 1807,
+ 1813, 1815, 1823, 1850, 1852, 1856, 1861, 1868, 1872, 1875,
+ 1877, 1888, 1899, 1904, 1913, 1915, 1919, 1922, 1924, 1929,
+ 1934, 1939, 1946, 1948, 1949, 1950, 1953, 1958, 1963, 1965,
+ 1966, 1968, 1970, 1971, 1973, 1977, 1980, 1984, 1987, 1991,
+ 1993, 1995, 1997, 1998, 2000, 2004, 2013, 2015, 2017, 2030,
+ 2032, 2038, 2040, 2042, 2046, 2048, 2053, 2058, 2063, 2065,
+ 2067, 2071, 2073, 2078, 2083, 2085, 2089, 2091, 2096, 2101,
+ 2106, 2108, 2110, 2114, 2116, 2121, 2126, 2131, 2136, 2138,
+ 2140, 2142, 2144, 2146, 2150, 2152, 2157, 2162, 2164, 2168,
+ 2170, 2175, 2179, 2181, 2186, 2190, 2192, 2197, 2201, 2203,
+ 2208, 2212, 2214, 2219, 2223, 2225, 2230, 2236, 2238, 2242,
+ 2244, 2247, 2250, 2258, 2260, 2261, 2264, 2266, 2269, 2273
};
#endif
@@ -560,30 +760,31 @@ static const char * const yytname[] = { "$","error","$undefined.","PLUS_TK",
"class_member_declaration","field_declaration","variable_declarators","variable_declarator",
"variable_declarator_id","variable_initializer","method_declaration","@3","method_header",
"method_declarator","formal_parameter_list","formal_parameter","throws","class_type_list",
-"method_body","static_initializer","static","constructor_declaration","constructor_declarator",
-"constructor_body","explicit_constructor_invocation","this_or_super","interface_declaration",
-"@4","@5","@6","@7","extends_interfaces","interface_body","interface_member_declarations",
-"interface_member_declaration","constant_declaration","abstract_method_declaration",
-"array_initializer","variable_initializers","block","@8","block_statements",
-"block_statement","local_variable_declaration_statement","local_variable_declaration",
-"statement","statement_nsi","statement_without_trailing_substatement","empty_statement",
-"label_decl","labeled_statement","labeled_statement_nsi","expression_statement",
+"method_body","static_initializer","static","constructor_declaration","@4","constructor_header",
+"constructor_declarator","constructor_body","explicit_constructor_invocation",
+"this_or_super","interface_declaration","@5","@6","@7","@8","extends_interfaces",
+"interface_body","interface_member_declarations","interface_member_declaration",
+"constant_declaration","abstract_method_declaration","array_initializer","variable_initializers",
+"block","block_begin","block_end","block_statements","block_statement","local_variable_declaration_statement",
+"local_variable_declaration","statement","statement_nsi","statement_without_trailing_substatement",
+"empty_statement","label_decl","labeled_statement","labeled_statement_nsi","expression_statement",
"statement_expression","if_then_statement","if_then_else_statement","if_then_else_statement_nsi",
-"switch_statement","switch_block","switch_block_statement_groups","switch_block_statement_group",
-"switch_labels","switch_label","while_expression","while_statement","while_statement_nsi",
-"do_statement_begin","do_statement","for_statement","for_statement_nsi","for_header",
-"for_begin","for_init","for_update","statement_expression_list","break_statement",
-"continue_statement","return_statement","throw_statement","synchronized_statement",
-"synchronized","try_statement","catches","catch_clause","finally","primary",
-"primary_no_new_array","class_instance_creation_expression","something_dot_new",
-"argument_list","array_creation_expression","dim_exprs","dim_expr","dims","field_access",
-"method_invocation","array_access","postfix_expression","post_increment_expression",
-"post_decrement_expression","unary_expression","pre_increment_expression","pre_decrement_expression",
-"unary_expression_not_plus_minus","cast_expression","multiplicative_expression",
-"additive_expression","shift_expression","relational_expression","equality_expression",
-"and_expression","exclusive_or_expression","inclusive_or_expression","conditional_and_expression",
-"conditional_or_expression","conditional_expression","assignment_expression",
-"assignment","left_hand_side","assignment_operator","expression","constant_expression", NULL
+"switch_statement","@9","switch_expression","switch_block","switch_block_statement_groups",
+"switch_block_statement_group","switch_labels","switch_label","while_expression",
+"while_statement","while_statement_nsi","do_statement_begin","do_statement",
+"for_statement","for_statement_nsi","for_header","for_begin","for_init","for_update",
+"statement_expression_list","break_statement","continue_statement","return_statement",
+"throw_statement","synchronized_statement","synchronized","try_statement","catches",
+"catch_clause","catch_clause_parameter","finally","primary","primary_no_new_array",
+"class_instance_creation_expression","something_dot_new","argument_list","array_creation_expression",
+"dim_exprs","dim_expr","dims","field_access","method_invocation","array_access",
+"postfix_expression","post_increment_expression","post_decrement_expression",
+"unary_expression","pre_increment_expression","pre_decrement_expression","unary_expression_not_plus_minus",
+"cast_expression","multiplicative_expression","additive_expression","shift_expression",
+"relational_expression","equality_expression","and_expression","exclusive_or_expression",
+"inclusive_or_expression","conditional_and_expression","conditional_or_expression",
+"conditional_expression","assignment_expression","assignment","left_hand_side",
+"assignment_operator","expression","constant_expression", NULL
};
#endif
@@ -596,48 +797,48 @@ static const short yyr1[] = { 0,
130, 130, 130, 130, 131, 131, 133, 132, 134, 132,
132, 132, 132, 132, 135, 135, 135, 135, 136, 136,
136, 137, 137, 137, 138, 138, 139, 139, 140, 140,
- 140, 140, 141, 141, 141, 141, 142, 142, 143, 143,
- 143, 144, 144, 144, 144, 145, 145, 145, 145, 145,
- 146, 146, 148, 147, 147, 149, 149, 149, 149, 149,
- 149, 149, 149, 149, 150, 150, 150, 150, 150, 151,
- 151, 151, 152, 152, 152, 152, 153, 153, 153, 154,
- 154, 154, 155, 155, 155, 156, 156, 157, 158, 158,
- 158, 158, 159, 159, 160, 160, 160, 160, 161, 161,
- 161, 161, 162, 162, 164, 163, 165, 163, 166, 163,
- 167, 163, 163, 163, 168, 168, 168, 168, 169, 169,
- 170, 170, 171, 171, 171, 171, 172, 173, 173, 174,
- 174, 174, 174, 175, 175, 175, 176, 177, 176, 178,
- 178, 179, 179, 179, 180, 181, 181, 182, 182, 182,
- 182, 182, 182, 183, 183, 183, 183, 183, 184, 184,
- 184, 184, 184, 184, 184, 184, 184, 184, 184, 185,
- 186, 187, 187, 188, 189, 189, 189, 189, 189, 189,
- 189, 189, 189, 189, 189, 189, 189, 190, 190, 190,
- 190, 190, 190, 190, 191, 191, 191, 191, 192, 193,
- 194, 194, 194, 194, 195, 195, 195, 195, 196, 196,
- 197, 198, 198, 199, 199, 199, 199, 199, 200, 201,
- 201, 201, 201, 202, 203, 204, 205, 205, 205, 205,
- 205, 206, 206, 207, 207, 207, 208, 209, 209, 209,
- 209, 210, 210, 211, 211, 211, 212, 212, 212, 212,
- 213, 213, 213, 213, 214, 214, 214, 214, 215, 215,
- 215, 216, 216, 216, 216, 216, 217, 218, 218, 218,
- 218, 219, 219, 220, 220, 220, 220, 221, 221, 222,
- 222, 223, 223, 223, 223, 223, 223, 223, 223, 223,
- 223, 223, 223, 223, 223, 223, 224, 224, 224, 224,
- 224, 224, 224, 224, 224, 224, 224, 224, 224, 224,
- 225, 225, 226, 226, 226, 227, 227, 227, 227, 227,
- 227, 227, 227, 228, 228, 229, 229, 229, 230, 230,
- 230, 231, 231, 231, 232, 232, 232, 232, 232, 232,
- 232, 232, 233, 233, 233, 233, 233, 233, 234, 234,
- 234, 234, 235, 236, 237, 237, 237, 237, 237, 237,
- 237, 238, 238, 239, 239, 240, 240, 240, 240, 240,
- 240, 241, 241, 241, 241, 241, 241, 241, 241, 241,
- 242, 242, 242, 242, 242, 242, 242, 243, 243, 243,
- 243, 243, 244, 244, 244, 244, 244, 244, 244, 245,
- 245, 245, 245, 245, 245, 245, 245, 245, 245, 245,
- 246, 246, 246, 246, 246, 247, 247, 247, 248, 248,
- 248, 249, 249, 249, 250, 250, 250, 251, 251, 251,
- 252, 252, 252, 252, 252, 253, 253, 254, 254, 255,
- 255, 255, 256, 256, 257, 258
+ 140, 140, 141, 141, 141, 141, 141, 142, 142, 143,
+ 143, 143, 144, 144, 144, 144, 145, 145, 145, 145,
+ 145, 146, 146, 148, 147, 147, 149, 149, 149, 149,
+ 149, 149, 149, 149, 149, 150, 150, 150, 150, 150,
+ 151, 151, 151, 152, 152, 152, 152, 153, 153, 153,
+ 154, 154, 154, 155, 155, 155, 156, 156, 157, 159,
+ 158, 160, 160, 161, 161, 162, 162, 162, 162, 163,
+ 163, 163, 163, 164, 164, 166, 165, 167, 165, 168,
+ 165, 169, 165, 165, 165, 170, 170, 170, 170, 171,
+ 171, 172, 172, 173, 173, 173, 173, 174, 175, 175,
+ 176, 176, 176, 177, 177, 177, 178, 178, 179, 180,
+ 181, 181, 182, 182, 182, 183, 184, 184, 185, 185,
+ 185, 185, 185, 185, 186, 186, 186, 186, 186, 187,
+ 187, 187, 187, 187, 187, 187, 187, 187, 187, 187,
+ 188, 189, 190, 190, 191, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192, 193, 193,
+ 193, 193, 193, 193, 193, 194, 194, 194, 194, 195,
+ 196, 198, 197, 199, 199, 199, 199, 200, 200, 200,
+ 200, 201, 201, 202, 203, 203, 204, 204, 204, 204,
+ 204, 205, 206, 206, 206, 206, 207, 208, 209, 210,
+ 210, 210, 210, 210, 211, 211, 212, 212, 212, 213,
+ 214, 214, 214, 214, 215, 215, 216, 216, 216, 217,
+ 217, 217, 217, 218, 218, 218, 218, 219, 219, 219,
+ 219, 220, 220, 220, 221, 221, 221, 221, 221, 222,
+ 223, 223, 223, 223, 224, 224, 225, 226, 226, 226,
+ 226, 227, 227, 228, 228, 229, 229, 229, 229, 229,
+ 229, 229, 229, 229, 229, 229, 229, 229, 229, 229,
+ 230, 230, 230, 230, 230, 230, 230, 230, 230, 230,
+ 230, 230, 230, 230, 231, 231, 232, 232, 232, 233,
+ 233, 233, 233, 233, 233, 233, 233, 234, 234, 235,
+ 235, 235, 236, 236, 236, 237, 237, 237, 238, 238,
+ 238, 238, 238, 238, 238, 238, 239, 239, 239, 239,
+ 239, 239, 240, 240, 240, 240, 241, 242, 243, 243,
+ 243, 243, 243, 243, 243, 244, 244, 245, 245, 246,
+ 246, 246, 246, 246, 246, 247, 247, 247, 247, 247,
+ 247, 247, 247, 247, 248, 248, 248, 248, 248, 248,
+ 248, 249, 249, 249, 249, 249, 250, 250, 250, 250,
+ 250, 250, 250, 251, 251, 251, 251, 251, 251, 251,
+ 251, 251, 251, 251, 252, 252, 252, 252, 252, 253,
+ 253, 253, 254, 254, 254, 255, 255, 255, 256, 256,
+ 256, 257, 257, 257, 258, 258, 258, 258, 258, 259,
+ 259, 260, 260, 261, 261, 261, 262, 262, 263, 264
};
static const short yyr2[] = { 0,
@@ -649,48 +850,48 @@ static const short yyr2[] = { 0,
1, 1, 1, 1, 1, 2, 0, 7, 0, 6,
3, 2, 3, 4, 0, 2, 3, 2, 0, 2,
2, 1, 3, 3, 2, 3, 1, 2, 1, 1,
- 1, 1, 1, 1, 1, 1, 3, 4, 1, 3,
- 3, 1, 3, 3, 4, 1, 3, 2, 3, 3,
- 1, 1, 0, 3, 2, 3, 3, 4, 4, 2,
- 3, 2, 3, 2, 3, 4, 3, 3, 3, 1,
- 3, 3, 2, 3, 2, 3, 0, 2, 2, 1,
- 3, 3, 1, 2, 1, 2, 3, 1, 3, 4,
- 4, 5, 3, 4, 2, 3, 3, 4, 4, 5,
- 7, 6, 1, 1, 0, 4, 0, 5, 0, 5,
- 0, 6, 3, 4, 2, 3, 2, 3, 2, 3,
- 1, 2, 1, 1, 1, 1, 1, 2, 2, 2,
- 3, 3, 4, 1, 3, 3, 2, 0, 4, 1,
- 2, 1, 1, 1, 2, 2, 3, 1, 1, 1,
+ 1, 1, 1, 2, 1, 1, 1, 3, 4, 1,
+ 3, 3, 1, 3, 3, 4, 1, 3, 2, 3,
+ 3, 1, 1, 0, 3, 2, 3, 3, 4, 4,
+ 2, 3, 2, 3, 2, 3, 4, 3, 3, 3,
+ 1, 3, 3, 2, 3, 2, 3, 0, 2, 2,
+ 1, 3, 3, 1, 2, 1, 2, 3, 1, 0,
+ 3, 2, 3, 3, 4, 2, 3, 3, 4, 4,
+ 5, 7, 6, 1, 1, 0, 4, 0, 5, 0,
+ 5, 0, 6, 3, 4, 2, 3, 2, 3, 2,
+ 3, 1, 2, 1, 1, 1, 1, 1, 2, 2,
+ 2, 3, 4, 1, 3, 3, 2, 3, 1, 1,
+ 1, 2, 1, 1, 1, 2, 2, 3, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 2, 2, 2, 2, 2, 2, 2, 2, 3, 4,
- 4, 5, 4, 5, 6, 7, 6, 1, 1, 1,
- 1, 1, 1, 1, 5, 2, 3, 4, 7, 7,
- 5, 2, 3, 5, 2, 3, 3, 4, 1, 2,
- 2, 1, 2, 3, 2, 2, 3, 2, 4, 2,
- 2, 3, 4, 2, 1, 7, 7, 6, 3, 5,
- 4, 7, 6, 2, 2, 3, 2, 0, 1, 1,
- 2, 0, 1, 1, 3, 3, 2, 3, 2, 3,
- 2, 3, 2, 3, 2, 3, 2, 3, 3, 2,
- 3, 5, 5, 2, 4, 3, 1, 3, 3, 4,
- 2, 1, 2, 5, 2, 4, 3, 2, 2, 1,
- 1, 1, 1, 3, 1, 1, 1, 1, 3, 3,
- 3, 3, 3, 3, 3, 3, 5, 4, 6, 5,
- 4, 5, 5, 6, 3, 3, 4, 5, 2, 3,
- 3, 3, 1, 3, 3, 3, 3, 4, 4, 4,
- 4, 3, 3, 1, 2, 3, 3, 2, 2, 3,
- 3, 3, 3, 2, 3, 4, 5, 6, 5, 6,
- 4, 4, 4, 4, 3, 4, 3, 4, 1, 1,
- 1, 1, 2, 2, 1, 1, 2, 2, 1, 2,
- 2, 2, 2, 2, 2, 1, 2, 2, 1, 2,
- 2, 5, 4, 4, 5, 4, 2, 5, 4, 5,
- 1, 3, 3, 3, 3, 3, 3, 1, 3, 3,
- 3, 3, 1, 3, 3, 3, 3, 3, 3, 1,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 1, 3, 3, 3, 3, 1, 3, 3, 1, 3,
- 3, 1, 3, 3, 1, 3, 3, 1, 3, 3,
- 1, 5, 4, 3, 5, 1, 1, 3, 3, 1,
- 1, 1, 1, 1, 1, 1
+ 1, 2, 2, 2, 2, 2, 2, 2, 2, 3,
+ 4, 4, 5, 4, 5, 6, 7, 6, 1, 1,
+ 1, 1, 1, 1, 1, 5, 2, 3, 4, 7,
+ 7, 0, 3, 4, 2, 3, 5, 2, 3, 3,
+ 4, 1, 2, 2, 1, 2, 3, 2, 2, 3,
+ 2, 4, 2, 2, 3, 4, 2, 1, 7, 7,
+ 6, 3, 5, 4, 7, 6, 2, 2, 3, 2,
+ 0, 1, 1, 2, 0, 1, 1, 3, 3, 2,
+ 3, 2, 3, 2, 3, 2, 3, 2, 3, 2,
+ 3, 3, 2, 3, 5, 5, 2, 4, 3, 1,
+ 3, 3, 4, 2, 1, 2, 2, 4, 2, 3,
+ 4, 2, 2, 1, 1, 1, 1, 3, 1, 1,
+ 1, 1, 3, 3, 3, 3, 3, 3, 3, 3,
+ 5, 4, 6, 5, 4, 5, 5, 6, 3, 3,
+ 4, 5, 2, 3, 3, 3, 1, 3, 3, 3,
+ 3, 4, 4, 4, 4, 3, 3, 1, 2, 3,
+ 3, 2, 2, 3, 3, 3, 3, 2, 3, 4,
+ 5, 6, 5, 6, 4, 4, 4, 4, 3, 4,
+ 3, 4, 1, 1, 1, 1, 2, 2, 1, 1,
+ 2, 2, 1, 2, 2, 2, 2, 2, 2, 1,
+ 2, 2, 1, 2, 2, 5, 4, 4, 5, 4,
+ 2, 5, 4, 5, 1, 3, 3, 3, 3, 3,
+ 3, 1, 3, 3, 3, 3, 1, 3, 3, 3,
+ 3, 3, 3, 1, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 1, 3, 3, 3, 3, 1,
+ 3, 3, 1, 3, 3, 1, 3, 3, 1, 3,
+ 3, 1, 3, 3, 1, 5, 4, 3, 5, 1,
+ 1, 3, 3, 1, 1, 1, 1, 1, 1, 1
};
static const short yydefact[] = { 0,
@@ -698,1053 +899,1023 @@ static const short yydefact[] = { 0,
0, 36, 43, 44, 38, 0, 51, 52, 46, 27,
0, 23, 24, 25, 0, 62, 0, 41, 0, 0,
37, 39, 0, 0, 56, 0, 0, 47, 45, 0,
- 163, 0, 0, 159, 63, 0, 69, 42, 40, 0,
- 0, 0, 61, 0, 49, 0, 26, 167, 17, 165,
- 15, 0, 156, 0, 0, 68, 16, 0, 0, 59,
- 164, 0, 161, 64, 69, 50, 48, 12, 0, 10,
- 11, 169, 0, 8, 9, 13, 14, 15, 0, 175,
- 177, 0, 176, 0, 171, 173, 174, 168, 166, 160,
- 67, 71, 72, 70, 0, 158, 0, 57, 112, 0,
- 127, 110, 0, 0, 89, 92, 127, 0, 0, 0,
- 114, 0, 0, 179, 178, 170, 172, 0, 0, 60,
- 162, 0, 0, 0, 0, 107, 98, 87, 0, 0,
- 0, 0, 106, 21, 18, 22, 20, 19, 113, 127,
- 111, 0, 127, 74, 73, 55, 188, 75, 23, 0,
- 85, 0, 77, 79, 83, 84, 0, 80, 0, 81,
- 127, 86, 82, 58, 118, 115, 0, 0, 0, 120,
- 129, 130, 128, 119, 117, 91, 0, 90, 94, 0,
- 0, 0, 0, 0, 0, 0, 333, 0, 0, 0,
- 0, 6, 5, 2, 3, 4, 7, 332, 0, 400,
- 0, 102, 399, 330, 335, 0, 331, 336, 337, 338,
- 416, 401, 402, 431, 405, 406, 409, 419, 438, 443,
- 450, 461, 466, 469, 472, 475, 478, 481, 486, 495,
- 487, 0, 101, 99, 97, 100, 109, 88, 108, 187,
- 0, 0, 127, 76, 78, 105, 0, 136, 0, 125,
- 123, 0, 116, 0, 0, 410, 400, 336, 338, 407,
- 411, 408, 415, 414, 413, 412, 0, 384, 0, 0,
- 0, 16, 0, 420, 417, 421, 418, 427, 0, 400,
- 0, 180, 0, 184, 0, 0, 0, 0, 0, 95,
- 0, 0, 359, 0, 404, 403, 0, 0, 0, 0,
+ 164, 0, 0, 160, 63, 0, 69, 42, 40, 0,
+ 0, 0, 61, 0, 49, 0, 26, 168, 17, 166,
+ 15, 0, 157, 0, 0, 68, 16, 0, 0, 59,
+ 165, 0, 162, 64, 69, 50, 48, 12, 0, 10,
+ 11, 170, 0, 8, 9, 13, 14, 15, 0, 176,
+ 178, 0, 177, 0, 172, 174, 175, 169, 167, 161,
+ 67, 71, 72, 70, 0, 159, 0, 57, 113, 0,
+ 128, 111, 0, 0, 90, 93, 128, 0, 0, 0,
+ 115, 0, 0, 180, 179, 171, 173, 0, 0, 60,
+ 163, 0, 0, 0, 0, 108, 99, 88, 0, 0,
+ 0, 0, 107, 21, 18, 22, 20, 19, 114, 128,
+ 112, 0, 128, 74, 73, 55, 189, 75, 23, 0,
+ 86, 0, 77, 79, 83, 85, 0, 80, 0, 81,
+ 140, 128, 87, 82, 0, 58, 119, 116, 0, 0,
+ 0, 121, 130, 131, 129, 120, 118, 92, 0, 91,
+ 95, 0, 0, 0, 0, 0, 0, 0, 337, 0,
+ 0, 0, 0, 6, 5, 2, 3, 4, 7, 336,
+ 0, 404, 0, 103, 403, 334, 339, 0, 335, 340,
+ 341, 342, 420, 405, 406, 435, 409, 410, 413, 423,
+ 442, 447, 454, 465, 470, 473, 476, 479, 482, 485,
+ 490, 499, 491, 0, 102, 100, 98, 101, 110, 89,
+ 109, 187, 0, 128, 76, 78, 84, 106, 0, 137,
+ 0, 142, 0, 55, 0, 0, 278, 0, 0, 0,
+ 0, 0, 0, 0, 0, 337, 0, 221, 0, 8,
+ 404, 0, 0, 195, 0, 210, 0, 191, 193, 0,
+ 194, 199, 211, 0, 200, 212, 0, 201, 202, 213,
+ 252, 0, 203, 0, 214, 204, 291, 0, 215, 216,
+ 217, 219, 218, 0, 220, 245, 244, 0, 242, 243,
+ 240, 241, 239, 126, 124, 0, 117, 0, 0, 414,
+ 404, 340, 342, 411, 415, 412, 419, 418, 417, 416,
+ 0, 388, 0, 0, 0, 16, 0, 424, 421, 425,
+ 422, 431, 0, 404, 0, 181, 184, 0, 0, 0,
+ 0, 0, 96, 0, 0, 363, 0, 408, 407, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 493, 494, 0,
- 0, 55, 0, 0, 275, 0, 0, 0, 0, 0,
- 0, 0, 0, 333, 0, 220, 0, 8, 400, 0,
- 0, 194, 0, 209, 0, 190, 192, 0, 193, 198,
- 210, 0, 199, 211, 0, 200, 201, 212, 0, 202,
- 0, 213, 203, 288, 0, 214, 215, 216, 218, 217,
- 0, 219, 244, 243, 0, 241, 242, 239, 240, 238,
- 143, 0, 0, 135, 104, 133, 137, 0, 139, 126,
- 124, 122, 121, 132, 131, 346, 341, 0, 383, 373,
- 372, 355, 0, 366, 374, 0, 367, 0, 356, 0,
- 0, 0, 0, 0, 0, 343, 334, 182, 181, 0,
- 345, 340, 385, 0, 363, 395, 0, 344, 339, 361,
- 342, 362, 382, 397, 0, 360, 0, 435, 432, 436,
- 433, 437, 434, 441, 439, 442, 440, 447, 444, 448,
- 445, 449, 446, 457, 452, 459, 454, 456, 451, 458,
- 453, 460, 0, 455, 464, 462, 465, 463, 468, 467,
- 471, 470, 474, 473, 477, 476, 480, 479, 484, 0,
- 0, 489, 488, 227, 228, 226, 246, 0, 310, 0,
- 299, 297, 0, 307, 305, 0, 271, 0, 252, 0,
- 321, 0, 285, 0, 303, 301, 0, 0, 196, 0,
- 0, 223, 221, 0, 0, 189, 191, 195, 317, 400,
- 222, 225, 270, 0, 400, 0, 290, 294, 287, 0,
- 0, 314, 0, 144, 140, 134, 145, 400, 0, 0,
- 0, 141, 391, 392, 0, 378, 379, 0, 375, 368,
- 0, 371, 369, 370, 357, 348, 0, 429, 423, 426,
- 0, 0, 424, 186, 183, 185, 386, 0, 396, 393,
- 0, 398, 394, 351, 0, 483, 0, 247, 0, 311,
- 309, 300, 298, 308, 306, 272, 0, 253, 0, 0,
- 0, 318, 322, 319, 286, 304, 302, 334, 0, 197,
- 229, 0, 0, 0, 291, 0, 279, 0, 0, 316,
- 0, 142, 0, 146, 0, 0, 147, 389, 0, 377,
- 376, 381, 380, 350, 358, 347, 428, 422, 430, 425,
- 365, 364, 387, 0, 352, 353, 485, 482, 248, 0,
- 273, 269, 0, 325, 0, 329, 328, 323, 320, 233,
- 0, 230, 231, 0, 0, 296, 295, 281, 0, 293,
- 0, 315, 0, 0, 148, 0, 0, 390, 349, 388,
- 354, 0, 245, 0, 198, 0, 205, 206, 0, 207,
- 208, 0, 254, 0, 251, 327, 0, 234, 0, 0,
- 232, 0, 0, 280, 0, 313, 312, 0, 149, 0,
- 0, 0, 224, 274, 0, 0, 0, 255, 0, 259,
- 0, 262, 326, 0, 237, 235, 0, 0, 278, 0,
- 0, 0, 150, 0, 249, 0, 0, 268, 265, 266,
- 496, 0, 257, 260, 0, 256, 0, 263, 324, 236,
- 276, 277, 152, 0, 0, 0, 0, 267, 264, 258,
- 151, 0, 0, 0, 0, 283, 0, 250, 282, 0,
- 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 497, 498, 0, 144, 0, 143, 136, 105, 134, 138,
+ 189, 141, 0, 228, 229, 227, 247, 0, 313, 0,
+ 302, 300, 0, 310, 308, 0, 274, 0, 255, 0,
+ 324, 0, 288, 0, 306, 304, 0, 0, 197, 0,
+ 0, 224, 222, 0, 0, 190, 188, 192, 196, 320,
+ 404, 223, 226, 0, 273, 0, 404, 0, 293, 297,
+ 290, 0, 0, 317, 0, 127, 125, 123, 122, 133,
+ 132, 350, 345, 0, 387, 377, 376, 359, 0, 370,
+ 378, 0, 371, 0, 360, 0, 0, 0, 0, 0,
+ 0, 347, 338, 182, 0, 349, 344, 389, 0, 367,
+ 399, 0, 348, 343, 365, 346, 366, 386, 401, 0,
+ 364, 0, 439, 436, 440, 437, 441, 438, 445, 443,
+ 446, 444, 451, 448, 452, 449, 453, 450, 461, 456,
+ 463, 458, 460, 455, 462, 457, 464, 0, 459, 468,
+ 466, 469, 467, 472, 471, 475, 474, 478, 477, 481,
+ 480, 484, 483, 488, 0, 0, 493, 492, 145, 135,
+ 404, 0, 0, 146, 0, 248, 0, 314, 312, 303,
+ 301, 311, 309, 275, 0, 256, 0, 0, 0, 321,
+ 325, 0, 322, 289, 307, 305, 338, 0, 198, 230,
+ 0, 0, 0, 253, 0, 294, 0, 282, 0, 0,
+ 319, 0, 395, 396, 0, 382, 383, 0, 379, 372,
+ 0, 375, 373, 374, 361, 352, 0, 433, 427, 430,
+ 0, 0, 428, 186, 183, 185, 390, 0, 400, 397,
+ 0, 402, 398, 355, 0, 487, 0, 0, 147, 0,
+ 0, 148, 249, 0, 276, 272, 0, 329, 0, 333,
+ 332, 326, 323, 327, 234, 0, 231, 232, 0, 0,
+ 0, 258, 0, 262, 0, 265, 0, 299, 298, 284,
+ 0, 296, 0, 318, 0, 393, 0, 381, 380, 385,
+ 384, 354, 362, 351, 432, 426, 434, 429, 369, 368,
+ 391, 0, 356, 357, 489, 486, 0, 149, 0, 0,
+ 0, 246, 0, 199, 0, 206, 207, 0, 208, 209,
+ 0, 257, 330, 0, 235, 0, 0, 233, 271, 268,
+ 269, 500, 0, 260, 263, 0, 259, 0, 266, 0,
+ 0, 283, 0, 316, 315, 394, 353, 392, 358, 0,
+ 150, 0, 0, 0, 225, 277, 0, 331, 328, 238,
+ 236, 0, 270, 267, 261, 0, 281, 0, 0, 0,
+ 151, 0, 250, 0, 0, 237, 279, 280, 153, 0,
+ 0, 0, 0, 152, 0, 0, 0, 0, 286, 0,
+ 251, 285, 0, 0, 0
};
-static const short yydefgoto[] = { 770,
- 208, 347, 209, 85, 86, 68, 60, 87, 210, 22,
+static const short yydefgoto[] = { 773,
+ 210, 279, 211, 85, 86, 68, 60, 87, 212, 22,
23, 24, 8, 9, 10, 11, 12, 13, 14, 15,
- 351, 352, 132, 105, 47, 70, 104, 130, 162, 163,
- 164, 91, 114, 115, 116, 211, 166, 257, 92, 111,
- 179, 180, 136, 183, 395, 168, 169, 170, 171, 399,
- 549, 353, 18, 43, 72, 65, 107, 44, 63, 94,
- 95, 96, 97, 212, 295, 354, 251, 747, 356, 357,
- 358, 359, 684, 360, 361, 362, 363, 687, 364, 365,
- 366, 367, 688, 368, 695, 719, 720, 721, 722, 369,
- 370, 690, 371, 372, 373, 691, 374, 375, 539, 669,
- 670, 376, 377, 378, 379, 380, 381, 382, 602, 603,
- 604, 213, 214, 215, 216, 434, 217, 414, 415, 416,
- 218, 219, 220, 221, 222, 223, 224, 225, 226, 227,
- 228, 229, 230, 231, 232, 233, 234, 235, 236, 237,
- 238, 239, 240, 241, 242, 330, 435, 742
+ 283, 284, 132, 105, 47, 70, 104, 130, 162, 163,
+ 164, 91, 114, 115, 116, 213, 166, 259, 92, 111,
+ 181, 182, 136, 185, 398, 168, 169, 170, 261, 171,
+ 172, 402, 552, 285, 18, 43, 72, 65, 107, 44,
+ 63, 94, 95, 96, 97, 214, 358, 286, 175, 437,
+ 718, 288, 289, 290, 291, 693, 292, 293, 294, 295,
+ 696, 296, 297, 298, 299, 697, 300, 444, 301, 584,
+ 653, 654, 655, 656, 302, 303, 699, 304, 305, 306,
+ 700, 307, 308, 451, 661, 662, 309, 310, 311, 312,
+ 313, 314, 315, 570, 571, 572, 573, 215, 216, 217,
+ 218, 489, 219, 470, 471, 472, 220, 221, 222, 223,
+ 224, 225, 226, 227, 228, 229, 230, 231, 232, 233,
+ 234, 235, 236, 237, 238, 239, 240, 241, 242, 243,
+ 244, 393, 490, 713
};
-static const short yypact[] = { 353,
--32768,-32768, 325, -41, 376, 398,-32768,-32768, 164, 528,
- 436,-32768,-32768,-32768,-32768, 494,-32768,-32768,-32768,-32768,
- 10,-32768,-32768,-32768, 18,-32768, 297,-32768, 11, 576,
--32768,-32768, 445, 598,-32768, -41, 428,-32768,-32768, 690,
--32768, 470, -13, -46,-32768, 495, 82,-32768,-32768, -41,
- 612, 328,-32768, 381,-32768, 28,-32768,-32768,-32768,-32768,
- -36, 1021,-32768, 531, -13,-32768,-32768, 232, 577,-32768,
--32768, -13, -46,-32768, 82,-32768,-32768,-32768, 590,-32768,
--32768,-32768, 592, 2,-32768,-32768, 170, -7, 916,-32768,
--32768, 92,-32768, 1055,-32768,-32768,-32768,-32768,-32768,-32768,
--32768,-32768,-32768, 172, 202,-32768, -13,-32768,-32768, 262,
- -1,-32768, 424, -75,-32768, 504, -1, 9, 86, 278,
--32768, 615, 617,-32768,-32768,-32768,-32768, 637, 936,-32768,
--32768, 202, 729, 653, 117,-32768,-32768,-32768, 660, 2333,
- 132, 384,-32768,-32768,-32768,-32768,-32768,-32768,-32768, -1,
--32768, 655, -1,-32768,-32768, 337, 377,-32768, 417, 916,
--32768, 1001,-32768,-32768,-32768,-32768, 47,-32768, 406,-32768,
- 472,-32768,-32768,-32768,-32768,-32768, 667, 903, 551,-32768,
--32768,-32768, 442,-32768,-32768,-32768, 460,-32768,-32768, 3080,
- 3145, 3196, 3261, 466, 21, 497,-32768, 3312, 3377, 3428,
- 5442,-32768,-32768,-32768,-32768,-32768,-32768,-32768, 543, 915,
- 99,-32768, 548, 560,-32768, 712,-32768, 770,-32768, 836,
- 888,-32768,-32768,-32768,-32768,-32768,-32768,-32768, 619, 945,
- 1019, 937, 935, 669, 676, 694, 714, 258,-32768,-32768,
--32768, 872,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
- 2125, 731, 472,-32768,-32768,-32768, 128, 634, 668,-32768,
- 873, 719,-32768, 585, 721,-32768, 673,-32768,-32768,-32768,
--32768,-32768,-32768,-32768,-32768,-32768, 25,-32768, 724, 992,
- 643, 643, 290,-32768,-32768,-32768,-32768,-32768, 746, 962,
- 208,-32768, 654,-32768, 358, 331, 5509, 3493, 622,-32768,
- 427, 3544,-32768, 393,-32768,-32768, 3609, 3660, 3725, 3776,
- 3841, 3892, 3957, 4008, 4073, 4124, 4189, 4240, 525, 4305,
- 4356, 4421, 4472, 4537, 4588, 4653, 2384,-32768,-32768, 4704,
- 510, 415, 416, 4769,-32768, 182, 2449, 13, 418, 426,
- 26, 450, 204, 679, 5741,-32768, -41, 618, 844, 448,
- 827,-32768, 684,-32768, 1785,-32768,-32768, 685,-32768,-32768,
--32768, 2193,-32768,-32768, 689,-32768,-32768,-32768, 2193,-32768,
- 2193,-32768,-32768, 5792, 697,-32768,-32768,-32768,-32768,-32768,
- 469,-32768, 702, 711, 888, 947, 965,-32768,-32768,-32768,
--32768, 759, 668,-32768,-32768, 728,-32768, 1853, 732,-32768,
- 873,-32768,-32768,-32768,-32768,-32768,-32768, 123, 740,-32768,
--32768,-32768, 2500, 643,-32768, 493, 643, 493,-32768, 2565,
- 4820, 166, -30, 2616, 308,-32768, 1180,-32768,-32768, 1645,
--32768,-32768,-32768, 781,-32768,-32768, 239,-32768,-32768,-32768,
--32768,-32768, 772,-32768, 244,-32768, 5560,-32768,-32768,-32768,
--32768,-32768,-32768,-32768, 619,-32768, 619,-32768, 945,-32768,
- 945,-32768, 945,-32768, 1019,-32768, 1019,-32768, 1019,-32768,
- 1019,-32768, 2,-32768,-32768, 937,-32768, 937,-32768, 935,
--32768, 669,-32768, 676,-32768, 694,-32768, 714,-32768, 766,
- 784,-32768,-32768,-32768,-32768,-32768,-32768, 4885,-32768, 143,
--32768,-32768, 153,-32768,-32768, 180,-32768, 4936,-32768, 5001,
--32768, 681,-32768, 5350,-32768,-32768, 235, 242, 783, 2681,
- 620,-32768,-32768, -41, 2732,-32768,-32768,-32768,-32768, 1070,
--32768,-32768,-32768, 821, 984, 903,-32768,-32768,-32768, 104,
- 2797,-32768, 5052,-32768, 802,-32768,-32768, 1037, 1921, 812,
- 1989,-32768,-32768,-32768, 5625,-32768,-32768, 259,-32768, 826,
- 295,-32768, 826,-32768,-32768, 202, 61,-32768,-32768,-32768,
- 5117, 817,-32768,-32768,-32768,-32768,-32768, 5168,-32768,-32768,
- 5676,-32768,-32768, 202, 785,-32768, 5233,-32768, 252,-32768,
--32768,-32768,-32768,-32768,-32768,-32768, 253,-32768, 845, 471,
- 46, 681,-32768,-32768,-32768,-32768,-32768,-32768, 473, 783,
--32768, 941, 122, 851,-32768, 5484,-32768, 5375, 855, 865,
- 867,-32768, 645,-32768, 2057, 2848,-32768,-32768, 792,-32768,
--32768,-32768,-32768,-32768,-32768, 202,-32768,-32768,-32768,-32768,
--32768,-32768,-32768, 814,-32768, 202,-32768,-32768,-32768, 2259,
--32768,-32768, 87,-32768, 788,-32768,-32768,-32768,-32768,-32768,
- 2913,-32768,-32768, 972, 5741,-32768,-32768,-32768, 885, 884,
- 5417,-32768, 206, 478,-32768, 245, 134,-32768,-32768,-32768,
--32768, 481,-32768, 931, 934, 2259,-32768,-32768, 2259,-32768,
--32768, 897,-32768, 733,-32768, 905, 910,-32768, 1016, 138,
--32768, 929, 2193,-32768, 939,-32768,-32768, 2964,-32768, 257,
- 4885, 2193,-32768,-32768, 3029, 167, 5284,-32768, 739,-32768,
- 1484,-32768,-32768, 406,-32768,-32768, 1024, 944,-32768, 2193,
- 273, 150,-32768, 269,-32768, 5375, 948,-32768,-32768,-32768,
--32768, 212,-32768,-32768, 1571,-32768, 1717,-32768,-32768,-32768,
--32768,-32768,-32768, 276, 2259, 946, 5417,-32768,-32768,-32768,
--32768, 974, 2259, 955, 2259,-32768, 2259,-32768,-32768, 1038,
- 1052,-32768
+static const short yypact[] = { 538,
+-32768,-32768, 61, -61, 310, 456,-32768,-32768, 245, 513,
+ 578,-32768,-32768,-32768,-32768, 567,-32768,-32768,-32768,-32768,
+ 19,-32768,-32768,-32768, 160,-32768, 296,-32768, 33, 603,
+-32768,-32768, 680, 629,-32768, -61, 486,-32768,-32768, 503,
+-32768, 504, -50, -27,-32768, 510, 130,-32768,-32768, -61,
+ 693, 338,-32768, 356,-32768, 37,-32768,-32768,-32768,-32768,
+ -2, 830,-32768, 520, -50,-32768,-32768, 342, 521,-32768,
+-32768, -50, -27,-32768, 130,-32768,-32768,-32768, 530,-32768,
+-32768,-32768, 539, 156,-32768,-32768, 197, -55, 787,-32768,
+-32768, 53,-32768, 988,-32768,-32768,-32768,-32768,-32768,-32768,
+-32768,-32768,-32768, 236, 132,-32768, -50,-32768,-32768, 371,
+ 379,-32768, 122, 550,-32768, 716, 379, 43, 77, 260,
+-32768, 562, 565,-32768,-32768,-32768,-32768, 568, 869,-32768,
+-32768, 132, 421, 574, 95,-32768,-32768,-32768, 580, 1258,
+ 113, 478,-32768,-32768,-32768,-32768,-32768,-32768,-32768, 379,
+-32768, 759, 379,-32768,-32768, 523, 519,-32768, 548, 787,
+-32768, 1021,-32768,-32768, 576,-32768, 203,-32768, 602,-32768,
+-32768, 625,-32768,-32768, 1818,-32768,-32768,-32768, 582, 948,
+ -29,-32768,-32768,-32768, 588,-32768,-32768,-32768, 350,-32768,
+-32768, 2787, 2838, 2903, 2954, 609, 28, 700,-32768, 3019,
+ 3070, 3135, 5134,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
+ 632, 949, 66,-32768, 642, 656,-32768, 583,-32768, 437,
+-32768, 771, 831,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
+ 887, 895, 950, 1007, 889, 745, 762, 758, 777, 268,
+-32768,-32768,-32768, 819,-32768,-32768,-32768,-32768,-32768,-32768,
+-32768,-32768, 896, 625,-32768,-32768,-32768,-32768, 671, 712,
+ 704,-32768, 502, 114, 306, 3186,-32768, 263, 2091, 47,
+ 391, 416, 232, 423, 307, 723, 5433,-32768, -61, 733,
+ 1018, 319, 918,-32768, 728,-32768, 1750,-32768,-32768, 725,
+-32768,-32768,-32768, 1886,-32768,-32768, 788,-32768,-32768,-32768,
+-32768, 1886,-32768, 1886,-32768,-32768, 5484, 791,-32768,-32768,
+-32768,-32768,-32768, 426,-32768, 706, 782, 831, 892, 897,
+-32768,-32768,-32768,-32768, 850, 590,-32768, 711, 593,-32768,
+ 545,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
+ 31,-32768, 622, 908, 739, 739, 430,-32768,-32768,-32768,
+-32768,-32768, 683, 998, 86,-32768,-32768, 694, 468, 5201,
+ 3251, 30,-32768, 474, 3302,-32768, 458,-32768,-32768, 3367,
+ 3418, 3483, 3534, 3599, 3650, 3715, 3766, 3831, 3882, 3947,
+ 3998, 719, 4063, 4114, 4179, 4230, 4295, 4346, 4411, 2142,
+-32768,-32768, 4462,-32768, 188,-32768,-32768,-32768, 797,-32768,
+-32768,-32768, 1750,-32768,-32768,-32768,-32768, 4527,-32768, 59,
+-32768,-32768, 74,-32768,-32768, 127,-32768, 4578,-32768, 4643,
+-32768, 796,-32768, 5042,-32768,-32768, 217, 295, 744, 2207,
+ 775,-32768,-32768, -61, 2258,-32768,-32768,-32768,-32768,-32768,
+ 1087,-32768,-32768, 754,-32768, 804, 1038, 948,-32768,-32768,
+-32768, 69, 2323,-32768, 4694,-32768, 850,-32768,-32768,-32768,
+-32768,-32768,-32768, 494, 808,-32768,-32768,-32768, 2374, 739,
+-32768, 490, 739, 490,-32768, 2439, 4759, 224, 359, 2490,
+ 450,-32768, 1509,-32768, 2026,-32768,-32768,-32768, 617,-32768,
+-32768, 234,-32768,-32768,-32768,-32768,-32768, 810,-32768, 248,
+-32768, 5252,-32768,-32768,-32768,-32768,-32768,-32768,-32768, 887,
+-32768, 887,-32768, 895,-32768, 895,-32768, 895,-32768, 950,
+-32768, 950,-32768, 950,-32768, 950,-32768, 156,-32768,-32768,
+ 1007,-32768, 1007,-32768, 889,-32768, 745,-32768, 762,-32768,
+ 758,-32768, 777,-32768, 880, 820,-32768,-32768,-32768,-32768,
+ 1076, 1750, 827,-32768, 1750,-32768, 352,-32768,-32768,-32768,
+-32768,-32768,-32768,-32768, 438,-32768, 829, 461, 309, 796,
+-32768, 602,-32768,-32768,-32768,-32768,-32768, 469, 744,-32768,
+ 928, 94, 185,-32768, 838,-32768, 5176,-32768, 5067, 834,
+ 851, 856,-32768,-32768, 5317,-32768,-32768, 262,-32768, 859,
+ 265,-32768, 859,-32768,-32768, 132, 102,-32768,-32768,-32768,
+ 4810, 1388,-32768,-32768,-32768,-32768,-32768, 4875,-32768,-32768,
+ 5368,-32768,-32768, 132, 627,-32768, 4926, 799,-32768, 1750,
+ 2555,-32768,-32768, 1952,-32768,-32768, 396,-32768, 737,-32768,
+-32768,-32768,-32768,-32768,-32768, 2606,-32768,-32768, 952, 355,
+ 4991,-32768, 190,-32768, 1484,-32768, 5433,-32768,-32768,-32768,
+ 867, 863, 5109,-32768, 402,-32768, 648,-32768,-32768,-32768,
+-32768,-32768,-32768, 132,-32768,-32768,-32768,-32768,-32768,-32768,
+-32768, 726,-32768, 132,-32768,-32768, 471,-32768, 239, 116,
+ 477,-32768, 910, 920, 1952,-32768,-32768, 1952,-32768,-32768,
+ 884,-32768, 893, 901,-32768, 995, 142,-32768,-32768,-32768,
+-32768,-32768, 424,-32768,-32768, 1614,-32768, 1682,-32768, 905,
+ 1886,-32768, 907,-32768,-32768,-32768,-32768,-32768,-32768, 2671,
+-32768, 242, 4527, 1886,-32768,-32768, 2722,-32768,-32768,-32768,
+-32768, 1008,-32768,-32768,-32768, 917,-32768, 1886, 289, 177,
+-32768, 439,-32768, 5067, 919,-32768,-32768,-32768,-32768, 291,
+ 1952, 925, 5109,-32768, 965, 1952, 942, 1952,-32768, 1952,
+-32768,-32768, 1039, 1045,-32768
};
static const short yypgoto[] = {-32768,
--32768, -58, 14, 737, 4, -99, 674,-32768, -3, 677,
--32768, 79,-32768, 1047, 760,-32768, 266,-32768,-32768, 881,
- 7, 23,-32768,-32768, 1007, 997,-32768, -131,-32768, 912,
--32768, 281, -121, 928, 431, -195,-32768,-32768, 408, 509,
- 832, -259, -73,-32768,-32768,-32768,-32768,-32768, 918, 686,
--32768, 700, -34,-32768,-32768,-32768,-32768, 1040, 508,-32768,
- 1006,-32768,-32768, 500,-32768, -120,-32768, -221, -340,-32768,
- 727, -299, 101, -526,-32768, -325,-32768,-32768,-32768, -336,
--32768,-32768,-32768,-32768,-32768,-32768, 389, 391, -666, -300,
--32768,-32768,-32768,-32768,-32768,-32768,-32768, -280,-32768, -297,
- 741,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, 511,
- 517,-32768,-32768, -31,-32768, -369,-32768, 813, 219, -269,
- 1157, 133, 1187, 279, 423, 486, -20, 569, 607, -419,
--32768, 703, 819, 534, 699, 799, 801, 803, 800, 816,
--32768, 552, 815, 695,-32768,-32768, -51,-32768
+-32768, -25, -53, 666, -34, -121, 645,-32768, -3, 597,
+-32768, 134,-32768, 1040, 806,-32768, 449,-32768,-32768, 689,
+ 17, 610,-32768,-32768, 999, 981,-32768, -131,-32768, 904,
+-32768, -57, -117, 924, -163, -192,-32768,-32768, 305, -65,
+ 805, -321, -98,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
+ 909,-32768,-32768, 664, -41,-32768,-32768,-32768,-32768, 1016,
+ 429,-32768, 983,-32768,-32768, 393,-32768, -106, 818, -401,
+ -165, -283,-32768, 774, -280, -36, -585,-32768, -492,-32768,
+-32768,-32768, -302,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
+-32768, 432, 434, -615, -447,-32768,-32768,-32768,-32768,-32768,
+-32768,-32768, -433,-32768, -630, 785,-32768,-32768,-32768,-32768,
+-32768,-32768,-32768,-32768, 524,-32768, 532,-32768,-32768, -63,
+-32768, -316,-32768, 747, 103, -261, 1023, 223, 1044, 254,
+ 380, 442, -111, 531, 620, -468,-32768, 600, 636, 681,
+ 596, 715, 722, 734, 724, 736,-32768, 495, 720, 750,
+-32768,-32768, 65,-32768
};
-#define YYLAST 5901
+#define YYLAST 5593
static const short yytable[] = { 21,
- 174, 152, 29, 83, 403, 294, 16, 573, 173, 144,
- 38, 48, 418, 278, 527, 16, 16, 16, 41, 423,
- 425, 278, 17, 138, 139, 406, 511, 93, 76, 355,
- 123, 17, 17, 17, 182, 83, 16, 538, 61, 16,
- 16, 173, 61, 143, 20, 59, 656, 256, 258, 67,
- 567, 134, 17, 64, 748, 17, 17, 16, 88, 93,
- 61, 635, 531, 571, 50, 61, 561, 59, 89, 533,
- 83, 534, 59, 17, 177, 84, 247, 585, 748, 249,
- 42, 62, 25, 27, 90, 88, 146, 693, 243, 120,
- 88, 407, 124, 50, 172, 135, 283, 259, 118, 300,
- 89, 123, 84, 83, 615, -154, 145, 84, 39, 49,
- 40, 50, -155, 279, 52, 54, 90, 184, 57, 262,
- 157, 279, 663, 685, 61, 88, 77, 172, 57, 88,
- 61, 59, 244, 69, 663, 160, 396, 67, 726, 178,
- 157, -103, 84, 590, 560, -103, 84, 563, 291, 243,
- 726, 161, 640, 592, 636, 613, 88, 110, 88, 685,
- 578, 113, 685, -30, 1, 405, 570, 738, 160, 270,
- 272, 274, 276, 84, 88, 84, 551, 285, 287, 393,
- 594, 694, 501, 147, 161, 629, 267, 267, 267, 267,
- 125, 84, 61, 177, 267, 267, 290, -93, -93, 282,
- 110, 113, -289, 616, 515, 177, 706, 2, 426, 281,
- 527, 644, 758, 289, 185, 664, 553, 187, 3, 383,
- 512, 578, 157, 554, 4, 519, 394, 710, 685, 245,
- 5, 727, 101, 578, 576, 606, 685, 578, 685, 579,
- 685, 591, 426, 754, 582, 662, 437, 349, 88, 578,
- 445, 593, 649, 651, 739, 187, 677, 701, 178, 630,
- 88, 61, 7, 557, 348, 84, 119, 20, 67, 649,
- 178, 128, 326, 725, 31, 491, 750, 84, 595, 667,
- 502, 538, 500, -66, 527, 506, 449, 451, 453, 20,
- 419, 700, 524, 518, 304, 632, 129, 45, 31, 759,
- 157, 427, 516, 267, 267, 267, 267, 267, 267, 267,
- 267, 267, 267, 267, 267, 88, 267, 267, 267, 267,
- 267, 267, 267, 383, 686, 19, -66, 625, 71, 350,
- 383, 431, 473, 607, 538, 608, 580, 383, 732, 383,
- 187, 583, 383, 709, 327, 650, 652, 88, -65, 689,
- 683, 349, -28, 1, 133, 733, 631, 409, 530, 46,
- 686, 558, 755, 686, 84, 530, 383, 530, 348, 692,
- 535, 753, 437, 705, 761, 148, 26, 57, 243, 443,
- 536, 74, 420, 384, 246, 689, 531, 348, 689, 533,
- 42, -65, 633, 446, 548, 697, 2, 432, 28, 538,
- 569, 572, 610, 729, 561, 692, 527, 3, 692, 165,
- 20, 348, 735, 4, 503, -317, 497, 267, 507, 5,
- 538, 517, -157, 267, 137, 187, 509, 6, 53, 686,
- 752, -138, -65, 350, 634, -29, 1, 686, 756, 686,
- 350, 686, 165, 46, -32, 1, 589, 350, 522, 350,
- 513, 7, 645, 429, 689, 683, 597, 430, 599, 764,
- 137, 20, 689, 729, 689, 735, 689, 752, 437, 542,
- 58, 654, 250, 660, 692, -65, 350, 524, 660, 2,
- 657, 497, 692, 20, 692, 447, 692, 384, 2, 619,
- 3, 621, -25, -25, 384, 66, 4, 280, 442, 3,
- 157, 384, 5, 384, 679, 4, 384, -317, 498, 252,
- 508, 5, 20, 20, 681, -96, 133, 383, 510, 383,
- -96, -96, -96, -96, 134, 472, 642, -31, 1, 385,
- 384, 98, 88, -25, 7, 523, 167, 35, -25, -25,
- -25, 265, 514, 7, -25, 349, 78, 349, -25, 84,
- 638, -96, 707, -96, 36, 20, -96, -96, -96, -96,
- 37, 543, 348, 655, 348, 661, 277, 267, 267, 167,
- 708, 2, 100, 711, 78, -34, 1, 102, 80, 106,
- 20, 81, 20, 267, 383, 402, 383, 201, 4, 561,
- 109, 117, 112, 383, 5, 140, 177, -33, 1, 57,
- 141, 142, 187, 749, 494, 495, 80, 261, 496, 81,
- 20, -35, 1, 702, 131, 149, 20, 151, 383, 2,
- 438, 349, 438, 307, 308, 309, 7, 350, 2, 350,
- 150, 153, 559, 385, 78, 559, 4, 154, 348, 383,
- 385, 2, 5, 296, 263, 438, 530, 385, 301, 385,
- 264, 88, 385, 181, 383, 2, 302, 383, 4, 734,
- 186, 178, 20, 737, 5, 741, 80, 260, 84, 81,
- 20, 383, 4, 386, 7, 20, 385, 20, 5, 322,
- 383, 384, 530, 384, 609, 530, 439, 323, 439, 383,
- 55, 440, 401, 440, 56, 441, 7, 441, 383, 530,
- 20, 57, 20, 350, 383, 20, 324, 20, 530, 674,
- 7, 439, 303, 383, 118, 383, 440, 349, 296, 400,
- 441, 404, 20, 383, 408, 383, 530, 325, 350, 175,
- 20, 383, 397, 383, 348, 383, 387, 99, 20, 413,
- 600, 349, 103, 349, 601, 20, -335, -335, 384, 428,
- 384, 530, 20, 248, 139, -337, -337, 384, 348, 530,
- 348, 530, 398, 530, 350, 297, 586, 350, 30, 298,
- 34, -153, 2, 299, 2, 20, 525, 386, 78, 716,
- 78, 350, 384, 528, 386, 716, 713, 532, 696, 714,
- 350, 386, 51, 386, 717, 541, 386, 20, -335, 350,
- 717, 155, -335, 384, 20, 159, 20, -337, 350, 20,
- 80, -337, 80, 81, 20, 81, 20, 639, 384, 388,
- 386, 384, 176, 350, 391, 350, 546, 385, 718, 385,
- 552, 2, 555, 350, 743, 384, 159, 78, 159, 421,
- 387, 350, 422, 350, 384, 350, 296, 387, 465, 467,
- 469, 471, 544, 384, 387, 762, 387, 389, 264, 387,
- -491, -491, 384, 766, 581, 768, 78, 769, 384, 80,
- 35, 587, 81, 20, 577, 194, 78, 384, 646, 384,
- 578, 195, 139, 387, 578, 678, 614, 384, 196, 384,
- 32, 578, 197, 37, 385, 384, 385, 384, 80, 384,
- 622, 81, 20, 385, 626, 198, 199, 680, 80, 200,
- 32, 81, 20, 578, 32, 562, 121, 564, 202, 203,
- 204, 205, 561, 388, 206, 207, -492, -492, 385, -15,
- 388, 32, 305, 306, -490, -490, 297, 388, 653, 388,
- 520, 662, 388, 665, 521, 390, 35, 310, 311, 385,
- 320, 321, 78, 671, 315, 316, 317, 318, 672, 35,
- 673, 389, 328, 329, 385, 78, 388, 385, 389, 141,
- 142, 386, 701, 386, 122, 389, 36, 389, 703, 156,
- 389, 385, 37, 616, 80, 78, 712, 81, 20, -204,
- 385, -401, -401, 319, 79, 715, 4, 80, 723, 385,
- 81, 20, 5, 724, 389, -490, -490, 297, 385, -402,
- -402, 298, 455, 457, 385, 299, 725, 80, 476, 478,
- 81, 20, 728, 385, 750, 385, 312, 313, 314, 765,
- 157, 158, 730, 385, 387, 385, 387, 771, 386, 763,
- 386, 385, 751, 385, 156, 385, 757, 386, 767, 390,
- 78, 772, -490, -490, 297, 474, 390, 33, 424, 79,
- 75, 4, 299, 390, 2, 390, 188, 5, 390, -15,
- 78, 108, 386, 255, -490, -490, 297, 253, 545, 79,
- 520, 4, 80, 392, 299, 81, 20, 5, 410, 411,
- 412, 73, 390, 386, 417, 157, 254, 550, 2, 127,
- 537, 387, 80, 387, 78, 81, 20, 744, 386, 745,
- 387, 386, 658, 79, 540, 4, 82, 388, 659, 388,
- 480, 5, -15, 482, 486, 386, 484, -490, -490, 297,
- 459, 461, 463, 520, 386, 387, 80, 623, 648, 81,
- 20, 488, 0, 386, 493, 0, 0, 0, 0, 0,
- 126, 0, 386, 0, 0, 389, 387, 389, 386, 0,
- -490, -490, 297, 0, 0, 0, 298, 386, 0, 386,
- 521, 387, 0, 0, 387, 0, 0, 386, 0, 386,
- 0, 0, 0, 0, 388, 386, 388, 386, 387, 386,
- 0, 0, 0, 388, 0, 0, 0, 387, 0, 0,
- 0, 0, 0, 0, 0, 0, 387, 0, 0, 0,
- 0, 0, 0, 0, 0, 387, 0, 0, 388, 0,
- 0, 387, 389, 0, 389, 0, 0, 0, 0, 78,
- 387, 389, 387, 0, 0, 0, 0, 0, 194, 388,
- 387, 0, 387, 390, 195, 390, 0, 0, 387, 0,
- 387, 196, 387, 0, 388, 197, 389, 388, 0, 0,
- 0, 80, 0, 0, 81, 20, 0, 0, 198, 199,
- 0, 388, 200, 0, 0, 0, 0, 389, 0, 0,
- 388, 202, 203, 204, 205, 0, 0, 206, 207, 388,
- 0, 0, 389, 0, 0, 389, 0, 0, 388, 0,
- 0, 0, 0, 0, 388, 0, 0, 0, 0, 389,
- 390, 0, 390, 388, 0, 388, 0, 0, 389, 390,
- 0, 0, 0, 388, 0, 388, 0, 389, 0, 0,
- 0, 388, 0, 388, 0, 388, 389, 0, 0, 0,
- 0, 0, 389, 0, 390, 0, 268, 268, 268, 268,
- 0, 389, 0, 389, 268, 268, 0, 0, 0, 0,
- 0, 389, 0, 389, 0, 390, 0, 0, 0, 389,
- 0, 389, 0, 389, 0, 0, 269, 269, 269, 269,
- 390, 0, 0, 390, 269, 269, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 390, 0, 0,
- 0, 0, 0, 0, 0, 0, 390, 0, 0, 0,
- 0, 0, 0, 0, 0, 390, 0, 0, 0, 0,
- 0, 0, 0, 0, 390, 0, 0, 0, 0, 0,
- 390, 0, 0, 0, 0, 0, 0, 0, 0, 390,
- 0, 390, 0, 0, 0, 0, 0, 0, 0, 390,
- 0, 390, 0, 0, 0, 0, 0, 390, 0, 390,
- 0, 390, 0, 268, 268, 268, 268, 268, 268, 268,
- 268, 268, 268, 268, 268, 0, 268, 268, 268, 268,
- 268, 268, 268, 0, 331, 0, 0, 0, 0, 0,
- 0, 0, 0, 269, 269, 269, 269, 269, 269, 269,
- 269, 269, 269, 269, 269, 0, 269, 269, 269, 269,
- 269, 269, 269, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 332, 192, 193,
- 716, 333, 334, 78, 335, 0, 0, 336, 0, 0,
- 0, 337, 194, 0, 0, 717, 0, 0, 338, 339,
- 5, 340, 0, 341, 342, 196, 343, 0, 0, 344,
+ 176, 554, 29, 438, 450, 152, 459, 59, 84, 287,
+ 357, 67, 184, 442, 613, 325, 16, 117, 143, 38,
+ 93, 445, 174, 446, 20, 16, 16, 16, 342, 59,
+ 493, 462, 723, 48, 59, 84, 83, 76, 61, 719,
+ 84, 120, 61, 144, 62, 50, 16, 342, 694, 16,
+ 16, 249, 93, 124, 251, 174, 150, 153, 88, 558,
+ 61, 19, 260, 123, 327, 61, 363, 16, 83, 586,
+ 328, 165, 64, 262, 560, 84, 347, 146, 89, 84,
+ 334, 336, 338, 340, 474, 88, 482, 173, 349, 351,
+ 88, 479, 481, 59, 648, 186, 494, 463, 50, 67,
+ 719, 495, 673, 83, 165, 496, 84, 179, 84, 694,
+ 89, 316, 694, 246, -320, 20, 648, 39, 582, 40,
+ 173, 280, 137, 762, 61, 88, 84, 562, 343, 88,
+ 61, 49, 767, 50, 123, 77, 83, 25, 27, -155,
+ 145, 695, 741, 678, 345, 160, 20, 343, 353, 180,
+ 629, 125, 399, 632, 326, 396, 88, 559, 88, 607,
+ 41, 429, 457, 346, -94, -94, 422, -292, 587, 52,
+ 54, 281, 561, 57, 147, 694, 88, 741, 160, 483,
+ 694, 69, 694, 57, 694, 625, 698, 649, 331, 331,
+ 331, 331, 187, 618, 61, 674, 331, 331, 354, 84,
+ 701, 618, 695, 258, 245, 695, -320, 461, 600, 732,
+ 247, 603, 110, -97, 133, 618, 113, 575, -97, -97,
+ -97, -97, 42, 316, 610, 563, 129, 179, 688, 84,
+ 316, 650, 421, 280, 619, 742, 650, 555, 316, 647,
+ 316, 618, 708, 316, -30, 1, 651, 698, 622, 88,
+ 698, 651, 118, 280, -156, 110, 113, 434, 504, 506,
+ 508, 701, 668, 411, 701, 670, 355, 245, 695, 180,
+ 760, 438, 189, 695, 84, 695, 618, 695, 667, 88,
+ 652, 549, 389, 281, 659, 714, 450, 328, 2, 740,
+ 441, 756, 616, 119, 67, 482, 45, -104, 441, 3,
+ 441, -104, 179, 447, 682, 4, 407, 425, 282, 640,
+ 26, 5, 189, 698, 690, 576, 579, 704, 698, 432,
+ 698, 597, 698, 448, 88, 61, 157, 701, 528, 707,
+ 410, 620, 701, 416, 701, 128, 701, 731, 71, 316,
+ 751, 428, 101, 7, 180, 623, 438, -65, 20, 280,
+ 137, 367, 633, 692, 390, 709, 74, 148, 46, 669,
+ 450, 412, 671, -25, -25, 609, 331, 331, 331, 331,
+ 331, 331, 331, 331, 331, 331, 331, 331, 88, 331,
+ 331, 331, 331, 331, 331, 331, 630, 759, 577, 764,
+ -65, 417, 20, -66, 84, 20, 702, 317, 408, 551,
+ 42, 413, 724, 157, -25, 426, 433, -65, 427, -25,
+ -25, -25, 189, 750, 442, -25, 419, 445, 46, -25,
+ 282, 177, 434, 423, 743, 492, 454, 282, 318, 500,
+ 475, 134, -158, 167, 438, 282, -66, 282, 635, 633,
+ 747, -97, 710, -97, 88, 634, -97, -97, -97, -97,
+ -65, 450, 611, 753, 546, 601, 28, 31, 501, 189,
+ 450, 638, 641, 133, 2, 644, 167, 758, 486, 645,
+ 78, 645, 557, 331, 672, 135, 465, 407, 248, 331,
+ 692, 31, 565, 418, 567, 747, 53, 753, 316, 758,
+ -254, 316, 683, 100, 492, 57, 157, 498, 280, 676,
+ 106, 280, 80, 55, 58, 81, 20, 56, 420, 317,
+ 66, 744, -31, 1, 178, 424, 317, 590, 455, 592,
+ 98, 102, 476, 316, 317, 316, 317, -495, -495, 317,
+ 109, 636, 761, 598, 487, 131, 282, -28, 1, 112,
+ 318, 20, 727, 612, 492, 497, 601, 318, 281, 245,
+ 502, 281, 729, 639, 319, 318, 2, 318, 725, 20,
+ 318, 646, 149, 730, 57, 151, 316, 189, 154, 733,
+ 316, 20, 599, 4, 183, 599, 280, -29, 1, 5,
+ 188, 2, 324, 366, 203, 84, 601, 593, 20, 20,
+ 456, 316, 3, 460, 594, 20, 404, 405, 4, 316,
+ 406, 280, -34, 1, 5, 20, 20, 331, 331, 17,
+ 35, 7, 6, 179, 252, 20, 320, -139, 17, 17,
+ 17, 2, 464, 331, 20, 317, 281, 36, -33, 1,
+ 441, 316, 3, 37, 316, 88, 7, 360, 4, 17,
+ 253, 361, 17, 17, 5, 362, 2, 20, 138, 139,
+ 20, 281, 316, 20, 316, 180, 318, 316, 735, 20,
+ 17, 736, 280, 4, 280, 20, 319, 20, 20, 5,
+ 316, 90, 2, 319, 257, 20, 7, 134, 20, -32,
+ 1, 319, 680, 319, 316, 282, 319, 329, 282, 4,
+ 316, 441, -35, 1, 441, 5, 157, 316, 32, 316,
+ 344, 7, 316, 90, 316, 321, 316, 20, 99, 341,
+ 617, 458, 281, 103, 281, 712, 618, 441, 32, 527,
+ 684, 720, 32, 2, 765, 159, 618, 7, 320, 769,
+ 441, 771, 359, 772, 3, 320, 2, 703, 161, 32,
+ 4, 726, 364, 320, 441, 320, 5, 618, 320, 78,
+ -339, -339, 365, 4, 2, 385, 159, 441, 159, 5,
+ 78, 57, 441, 282, 441, 157, 441, 282, 78, 397,
+ 387, 161, 155, 386, 317, 493, 477, 317, 7, 478,
+ 2, 80, 319, 359, 81, 20, 78, 121, 282, 484,
+ 388, 7, 80, 485, 322, 81, 20, 752, 401, 493,
+ 80, 755, -339, 81, 20, 318, -339, 140, 318, 317,
+ 400, 317, 141, 142, 30, -154, 34, 321, 80, 728,
+ 435, 81, 20, 439, 321, 618, -341, -341, 282, 118,
+ 35, 282, 321, 359, 321, 469, 78, 321, 51, 578,
+ 318, 494, 318, 139, 320, 122, 495, 36, 583, 282,
+ 496, 282, 317, 37, 282, 568, 317, 250, 139, 569,
+ 20, -496, -496, 687, 602, 494, 604, 282, 80, 585,
+ 495, 81, 20, 2, 496, 368, 369, 317, -341, 78,
+ 626, 282, -341, 318, 20, 317, 443, 318, 79, 453,
+ 4, 370, 371, 372, 282, 550, 5, 373, 374, 282,
+ 595, 282, 621, 282, 383, 384, 322, 627, 318, 391,
+ 392, 80, 156, 322, 81, 20, 318, 317, 78, 631,
+ 317, 322, 637, 322, 323, 82, 322, 79, 647, 4,
+ 657, 319, 663, 321, 319, 5, -405, -405, 317, 2,
+ 317, -406, -406, 317, 664, 78, 141, 142, 318, 665,
+ 80, 318, 708, 81, 20, 601, 317, 375, 376, 377,
+ 721, 35, 587, 157, 158, 734, 319, 78, 319, 318,
+ 317, 318, 510, 512, 318, -205, 317, 80, 531, 533,
+ 81, 20, 737, 317, 37, 317, 738, 318, 317, 394,
+ 317, 35, 317, 320, 739, 740, 320, 78, 746, 80,
+ 748, 318, 81, 20, 466, 467, 468, 318, 756, 319,
+ 514, 516, 518, 319, 318, 757, 318, 763, 766, 318,
+ 768, 318, 322, 318, 378, 379, 380, 381, 320, 80,
+ 320, 2, 81, 20, 319, 770, 323, 78, 774, -494,
+ -494, 360, 319, 323, 775, 361, 79, 529, 4, 362,
+ 33, 323, 75, 323, 5, 108, 323, 395, 520, 522,
+ 524, 526, 190, 382, 156, 256, 553, 73, 254, 80,
+ 78, 320, 81, 20, 319, 320, 127, 319, 403, 79,
+ 449, 4, 321, 126, 715, 321, 716, 5, -494, -494,
+ 360, 452, 473, 642, 480, 319, 320, 319, 362, 535,
+ 319, 643, 80, -15, 320, 81, 20, 537, -494, -494,
+ 360, 541, 548, 319, 430, 157, 255, 321, 431, 321,
+ 539, 686, 0, -15, 543, 0, 0, 319, -494, -494,
+ 360, 0, 0, 319, 430, 0, 320, 0, 362, 320,
+ 319, 0, 319, 0, 0, 319, 0, 319, 0, 319,
+ 0, 0, 323, 0, 0, 0, 0, 320, 0, 320,
+ 321, -15, 320, 0, 321, 0, -494, -494, 360, 0,
+ 0, 322, 430, 0, 322, 320, 628, -494, -494, 360,
+ 0, 0, 0, 361, 0, 321, 0, 431, 0, 320,
+ 0, 0, 0, 321, 0, 320, 0, 0, 0, 0,
+ 0, 0, 320, 0, 320, 0, 322, 320, 322, 320,
+ 0, 320, 0, 0, 332, 332, 332, 332, 0, 0,
+ 0, 0, 332, 332, 0, 321, 0, 0, 321, 0,
+ 0, 0, 0, 0, 0, 333, 333, 333, 333, 0,
+ 0, 0, 0, 333, 333, 0, 321, 0, 321, 322,
+ 0, 321, 0, 322, 0, 0, 0, 0, 191, 0,
+ 192, 193, 0, 0, 321, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 322, 0, 0, 0, 321, 0,
+ 0, 0, 322, 0, 321, 0, 0, 0, 0, 0,
+ 0, 321, 0, 321, 0, 0, 321, 0, 321, 0,
+ 321, 323, 194, 195, 323, 0, 0, 78, 0, 0,
+ 0, 0, 0, 0, 322, 0, 196, 322, 0, 0,
+ 0, 0, 197, 0, 0, 0, 0, 0, 0, 198,
+ 0, 0, 0, 199, 0, 322, 323, 322, 323, 80,
+ 322, 0, 81, 20, 0, 0, 200, 201, 0, 0,
+ 202, 0, 203, 322, 0, 0, 0, 0, 0, 204,
+ 205, 206, 207, 0, 0, 208, 209, 322, 0, 0,
+ 0, 0, 0, 322, 0, 0, 0, 0, 0, 323,
+ 322, 0, 322, 323, 0, 322, 0, 322, 677, 322,
+ 0, 0, 332, 332, 332, 332, 332, 332, 332, 332,
+ 332, 332, 332, 332, 323, 332, 332, 332, 332, 332,
+ 332, 332, 323, 333, 333, 333, 333, 333, 333, 333,
+ 333, 333, 333, 333, 333, 0, 333, 333, 333, 333,
+ 333, 333, 333, 0, 0, 0, 0, 78, 0, 0,
+ 0, 0, 0, 0, 323, 0, 196, 323, 0, 0,
+ 0, 0, 197, 0, 0, 0, 0, 0, 0, 198,
+ 0, 0, 0, 199, 0, 323, 0, 323, 0, 80,
+ 323, 0, 81, 20, 0, 0, 200, 201, 0, 0,
+ 202, 0, 0, 323, 263, 0, 0, 0, 0, 204,
+ 205, 206, 207, 0, 0, 208, 209, 323, 0, 332,
+ 0, 0, 0, 323, 0, 332, 0, 0, 0, 0,
+ 323, 0, 323, 0, 0, 323, 0, 323, 0, 323,
+ 333, 0, 0, 0, 0, 0, 333, 264, 194, 195,
+ 650, 265, 266, 78, 267, 0, 0, 268, 0, 0,
+ 0, 269, 196, 0, 0, 651, 0, 0, 270, 271,
+ 5, 272, 0, 273, 274, 198, 275, 0, 78, 276,
+ 0, 0, 0, 0, 0, 80, 0, 196, 81, 20,
+ 0, 0, 0, 197, 0, 0, 277, 0, 157, 717,
+ 198, 0, 278, 0, 199, 204, 205, 206, 207, 0,
+ 80, 208, 209, 81, 20, 0, 0, 200, 201, 0,
+ 0, 202, 0, 0, 0, 0, 0, 0, 0, 0,
+ 204, 205, 206, 207, 263, 0, 208, 209, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 332, 332, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 332,
+ 0, 0, 0, 0, 333, 333, 0, 264, 194, 195,
+ 650, 265, 266, 78, 267, 0, 0, 268, 0, 0,
+ 333, 269, 196, 0, 0, 651, 0, 0, 270, 271,
+ 5, 272, 263, 273, 274, 198, 275, 0, 0, 276,
0, 0, 0, 0, 0, 80, 0, 0, 81, 20,
- 0, 331, 0, 0, 0, 0, 345, 268, 157, 746,
- 0, 0, 346, 268, 0, 202, 203, 204, 205, 0,
- 0, 206, 207, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 269, 0, 0,
- 0, 0, 0, 269, 332, 192, 193, 716, 333, 334,
- 78, 335, 0, 0, 336, 0, 0, 0, 337, 194,
- 0, 0, 717, 0, 0, 338, 339, 5, 340, 0,
- 341, 342, 196, 343, 0, 574, 344, 190, 191, 0,
- 0, 0, 80, 0, 0, 81, 20, 0, 0, 0,
- 0, 0, 0, 345, 0, 157, 760, 0, 0, 346,
- 0, 0, 202, 203, 204, 205, 0, 0, 206, 207,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 192,
- 193, 0, 0, 0, 78, 0, 0, 0, 0, 0,
- 0, 0, 0, 194, 0, 0, 0, 0, 0, 195,
- 0, 0, 0, 0, 0, 0, 196, 331, 0, 0,
- 197, 0, 0, 0, 0, 0, 80, 268, 268, 81,
- 20, 0, 0, 198, 199, 0, 0, 200, 0, 201,
- 575, 0, 0, 268, 0, 0, 202, 203, 204, 205,
- 0, 0, 206, 207, 0, 0, 0, 269, 269, 0,
- 332, 192, 193, -261, 333, 334, 78, 335, 0, 0,
- 336, 0, 0, 269, 337, 194, 0, 0, -261, 0,
- 0, 338, 339, 5, 340, 331, 341, 342, 196, 343,
- 0, 0, 344, 0, 0, 0, 0, 0, 80, 0,
- 0, 81, 20, 0, 0, 0, 0, 0, 0, 345,
- 0, 157, -261, 0, 0, 346, 0, 0, 202, 203,
- 204, 205, 0, 0, 206, 207, 0, 0, 332, 192,
- 193, 0, 333, 334, 78, 335, 0, 0, 336, 0,
- 0, 0, 337, 194, 0, 0, 0, 0, 0, 338,
- 339, 5, 340, 331, 341, 342, 196, 343, 0, 0,
- 344, 0, 0, 0, 0, 0, 80, 0, 0, 81,
- 20, 0, 0, 0, 0, 0, 0, 345, 0, 157,
- 526, 0, 0, 346, 0, 0, 202, 203, 204, 205,
- 0, 0, 206, 207, 0, 0, 332, 192, 193, 0,
- 333, 334, 78, 335, 0, 0, 336, 0, 0, 0,
- 337, 194, 0, 0, 0, 0, 0, 338, 339, 5,
- 340, 331, 341, 342, 196, 343, 0, 0, 344, 0,
- 0, 0, 0, 0, 80, 0, 0, 81, 20, 0,
- 0, 0, 0, 0, 0, 345, 0, 157, 547, 0,
- 0, 346, 0, 0, 202, 203, 204, 205, 0, 0,
- 206, 207, 0, 0, 332, 192, 193, 0, 333, 334,
- 78, 335, 0, 0, 336, 0, 0, 0, 337, 194,
- 0, 0, 0, 0, 0, 338, 339, 5, 340, 331,
- 341, 342, 196, 343, 0, 0, 344, 0, 0, 0,
- 0, 0, 80, 0, 0, 81, 20, 0, 0, 0,
- 0, 0, 0, 345, 0, 157, 624, 0, 0, 346,
- 0, 0, 202, 203, 204, 205, 0, 0, 206, 207,
- 0, 0, 332, 192, 193, 0, 333, 334, 78, 335,
- 0, 0, 336, 0, 0, 0, 337, 194, 0, 0,
- 0, 0, 0, 338, 339, 5, 340, 331, 341, 342,
- 196, 343, 0, 0, 344, 0, 0, 0, 0, 0,
- 80, 0, 0, 81, 20, 0, 0, 0, 0, 0,
- 0, 345, 0, 157, 627, 0, 0, 346, 0, 0,
- 202, 203, 204, 205, 0, 0, 206, 207, 0, 0,
- 332, 192, 193, 0, 333, 334, 78, 335, 0, 0,
- 336, 0, 0, 0, 337, 194, 0, 0, 0, 0,
- 0, 338, 339, 5, 340, 331, 341, 342, 196, 343,
- 0, 0, 344, 0, 0, 0, 0, 0, 80, 0,
- 0, 81, 20, 0, 0, 0, 0, 0, 0, 345,
- 0, 157, 675, 0, 0, 346, 0, 0, 202, 203,
- 204, 205, 0, 0, 206, 207, 0, 0, 332, 192,
- 193, 0, 333, 334, 78, 335, 0, 0, 336, 0,
- 0, 0, 337, 194, 0, 0, 0, 0, 0, 338,
- 339, 5, 340, 331, 341, 342, 196, 343, 0, 0,
- 344, 0, 0, 0, 0, 0, 80, 0, 0, 81,
- 20, 0, 0, 0, 0, 0, 0, 345, 0, 157,
- 0, 0, 0, 346, 0, 0, 202, 203, 204, 205,
- 0, 0, 206, 207, 0, 0, 529, 192, 193, 0,
- 333, 334, 78, 335, 0, 0, 336, 0, 0, 0,
- 337, 194, 0, 0, 0, 0, 0, 338, 339, 331,
- 340, 0, 341, 342, 196, 343, 0, 0, 344, 0,
- 0, 0, 0, 0, 80, 0, 0, 81, 20, 0,
- 0, 0, 0, 0, 0, 345, 0, 157, 0, 0,
- 0, 346, 0, 0, 202, 203, 204, 205, 0, 0,
- 206, 207, 529, 192, 193, 0, 682, 334, 78, 335,
- 0, 0, 336, 0, 0, 0, 337, 194, 0, 0,
- 0, 0, 0, 338, 339, 0, 340, 0, 341, 342,
- 196, 343, 0, 189, 344, 190, 191, 0, 0, 0,
- 80, 0, 0, 81, 20, 0, 0, 0, 0, 0,
- 0, 345, 0, 157, 0, 0, 0, 346, 0, 0,
- 202, 203, 204, 205, 0, 0, 206, 207, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 192, 193, 0,
- 0, 0, 78, 0, 489, 0, 190, 191, 0, 0,
- 0, 194, 0, 0, 0, 0, 0, 195, 0, 0,
- 0, 0, 0, 0, 196, 0, 0, 0, 197, 0,
+ 0, 0, 0, 0, 0, 0, 277, 0, 157, 745,
+ 0, 0, 278, 0, 0, 204, 205, 206, 207, 0,
+ 0, 208, 209, 0, 0, 264, 194, 195, -264, 265,
+ 266, 78, 267, 0, 0, 268, 0, 0, 0, 269,
+ 196, 0, 0, -264, 0, 0, 270, 271, 5, 272,
+ 263, 273, 274, 198, 275, 0, 0, 276, 0, 0,
+ 0, 0, 0, 80, 0, 0, 81, 20, 0, 0,
+ 0, 0, 0, 0, 277, 0, 157, -264, 0, 0,
+ 278, 0, 0, 204, 205, 206, 207, 0, 0, 208,
+ 209, 0, 0, 264, 194, 195, 0, 265, 266, 78,
+ 267, 0, 0, 268, 0, 0, 0, 269, 196, 0,
+ 0, 0, 0, 0, 270, 271, 5, 272, 263, 273,
+ 274, 198, 275, 0, 0, 276, 0, 0, 0, 0,
+ 0, 80, 0, 0, 81, 20, 0, 0, 0, 0,
+ 0, 0, 277, 0, 157, 436, 0, 0, 278, 0,
+ 0, 204, 205, 206, 207, 0, 0, 208, 209, 0,
+ 0, 264, 194, 195, 0, 265, 266, 78, 267, 0,
+ 0, 268, 0, 0, 0, 269, 196, 0, 0, 0,
+ 0, 0, 270, 271, 5, 272, 263, 273, 274, 198,
+ 275, 0, 0, 276, 0, 0, 0, 0, 0, 80,
+ 0, 0, 81, 20, 0, 0, 0, 0, 0, 0,
+ 277, 0, 157, 0, 0, 0, 278, 0, 0, 204,
+ 205, 206, 207, 0, 0, 208, 209, 0, 0, 440,
+ 194, 195, 0, 265, 266, 78, 267, 0, 0, 268,
+ 0, 0, 0, 269, 196, 0, 0, 0, 0, 0,
+ 270, 271, 263, 272, 0, 273, 274, 198, 275, 0,
+ 0, 276, 0, 0, 0, 0, 0, 80, 0, 0,
+ 81, 20, 0, 0, 0, 0, 0, 0, 277, 0,
+ 157, 0, 0, 0, 278, 0, 0, 204, 205, 206,
+ 207, 0, 0, 208, 209, 440, 194, 195, 0, 691,
+ 266, 78, 267, 0, 0, 268, 0, 0, 0, 269,
+ 196, 0, 0, 0, 0, 0, 270, 271, 0, 272,
+ 0, 273, 274, 198, 275, 0, 614, 276, 192, 193,
+ 0, 0, 0, 80, 0, 0, 81, 20, 0, 0,
+ 0, 0, 0, 0, 277, 0, 157, 0, 0, 0,
+ 278, 0, 0, 204, 205, 206, 207, 0, 0, 208,
+ 209, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 194, 195, 0, 0, 0, 78, 0, 0, 0, 0,
+ 0, 0, 0, 0, 196, 0, 0, 0, 0, 0,
+ 197, 414, 0, 192, 193, 0, 0, 198, 0, 0,
+ 0, 199, 0, 0, 0, 0, 0, 80, 0, 0,
+ 81, 20, 0, 0, 200, 201, 0, 0, 202, 0,
+ 203, 615, 0, 0, 0, 0, 0, 204, 205, 206,
+ 207, 0, 0, 208, 209, 194, 195, 0, 0, 0,
+ 78, 0, 544, 0, 192, 193, 0, 0, 0, 196,
+ 0, 0, 0, 0, 0, 197, 0, 0, 0, 0,
+ 0, 0, 198, 0, 0, 0, 199, 0, 0, 0,
+ 0, 0, 80, 0, 0, 81, 20, 0, 0, 200,
+ 201, 0, 0, 202, 0, 0, 194, 195, 0, 415,
+ 0, 78, 204, 205, 206, 207, 0, 0, 208, 209,
+ 196, 0, 0, 0, 0, 0, 197, 491, 0, 192,
+ 193, 0, 0, 198, 0, 0, 0, 199, 0, 0,
+ 0, 0, 0, 80, 0, 0, 81, 20, 0, 545,
+ 200, 201, 0, 0, 202, 0, 0, 0, 0, 0,
+ 0, 0, 0, 204, 205, 206, 207, 0, 0, 208,
+ 209, 194, 195, 0, 0, 0, 78, 0, 580, 0,
+ 192, 193, 0, 0, 0, 196, 0, 0, 0, 0,
+ 0, 197, 0, 0, 0, 0, 0, 0, 198, 0,
+ 0, 0, 199, 0, 0, 0, 0, 0, 80, 0,
+ 0, 81, 20, 0, 0, 200, 201, 0, 0, 202,
+ 0, 0, 194, 195, 148, 0, 0, 78, 204, 205,
+ 206, 207, 0, 0, 208, 209, 196, 0, 0, 0,
+ 0, 0, 197, 588, 0, 192, 193, 0, 0, 198,
+ 0, 0, 0, 199, 0, 0, 0, 0, 0, 80,
+ 0, 0, 81, 20, 0, 0, 200, 201, 0, 0,
+ 202, 581, 0, 0, 0, 0, 0, 0, 0, 204,
+ 205, 206, 207, 0, 0, 208, 209, 194, 195, 0,
+ 0, 0, 78, 0, 596, 0, 192, 193, 0, 0,
+ 0, 196, 0, 0, 0, 0, 0, 197, 0, 0,
+ 0, 0, 0, 0, 198, 0, 0, 0, 199, 0,
0, 0, 0, 0, 80, 0, 0, 81, 20, 0,
- 0, 198, 199, 0, 0, 200, 0, 201, 192, 193,
- 0, 0, 0, 78, 202, 203, 204, 205, 0, 0,
- 206, 207, 194, 0, 0, 0, 0, 0, 195, 504,
- 0, 190, 191, 0, 0, 196, 0, 0, 0, 197,
+ 0, 200, 201, 0, 0, 202, 0, 0, 194, 195,
+ 0, 589, 0, 78, 204, 205, 206, 207, 0, 0,
+ 208, 209, 196, 0, 0, 0, 0, 0, 197, 605,
+ 0, 192, 193, 0, 0, 198, 0, 0, 0, 199,
0, 0, 0, 0, 0, 80, 0, 0, 81, 20,
- 0, 490, 198, 199, 0, 0, 200, 0, 0, 0,
- 0, 0, 0, 0, 0, 202, 203, 204, 205, 0,
- 0, 206, 207, 192, 193, 0, 0, 0, 78, 0,
- 556, 0, 190, 191, 0, 0, 0, 194, 0, 0,
- 0, 0, 0, 195, 0, 0, 0, 0, 0, 0,
- 196, 0, 0, 0, 197, 0, 0, 0, 0, 0,
- 80, 0, 0, 81, 20, 0, 0, 198, 199, 0,
- 0, 200, 0, 0, 192, 193, 0, 505, 0, 78,
- 202, 203, 204, 205, 0, 0, 206, 207, 194, 0,
- 0, 0, 0, 0, 195, 565, 0, 190, 191, 0,
- 0, 196, 0, 0, 0, 197, 0, 0, 0, 0,
- 0, 80, 0, 0, 81, 20, 0, 0, 198, 199,
- 0, 0, 200, 0, 0, 0, 0, 557, 0, 0,
- 0, 202, 203, 204, 205, 0, 0, 206, 207, 192,
- 193, 0, 0, 0, 78, 0, 436, 0, 190, 191,
- 0, 0, 0, 194, 0, 0, 0, 0, 0, 195,
- 0, 0, 0, 0, 0, 0, 196, 0, 0, 0,
- 197, 0, 0, 0, 0, 0, 80, 0, 0, 81,
- 20, 0, 0, 198, 199, 0, 0, 200, 566, 0,
- 192, 193, 0, 0, 0, 78, 202, 203, 204, 205,
- 0, 0, 206, 207, 194, 0, 0, 0, 0, 0,
- 195, 436, 0, 190, 191, 0, 0, 196, 0, 0,
- 0, 197, 0, 0, 0, 0, 0, 80, 0, 0,
- 81, 20, 0, 0, 198, 199, 0, 0, 200, 0,
- 0, 0, 0, 557, 0, 0, 0, 202, 203, 204,
- 205, 0, 0, 206, 207, 192, 193, 0, 0, 0,
- 78, 0, 611, 0, 190, 191, 0, 0, 0, 194,
- 0, 0, 0, 0, 0, 195, 0, 0, 0, 0,
- 0, 0, 196, 0, 0, 0, 197, 0, 0, 0,
- 0, 0, 80, 0, 0, 81, 20, 0, 0, 198,
- 199, 0, 0, 200, 0, 0, 192, 193, 148, 0,
- 0, 78, 202, 203, 204, 205, 0, 0, 206, 207,
- 194, 0, 0, 0, 0, 0, 195, 617, 0, 190,
- 191, 0, 0, 196, 0, 0, 0, 197, 0, 0,
+ 0, 0, 200, 201, 0, 0, 202, 0, 0, 0,
+ 0, 597, 0, 0, 0, 204, 205, 206, 207, 0,
+ 0, 208, 209, 194, 195, 0, 0, 0, 78, 0,
+ 491, 0, 192, 193, 0, 0, 0, 196, 0, 0,
+ 0, 0, 0, 197, 0, 0, 0, 0, 0, 0,
+ 198, 0, 0, 0, 199, 0, 0, 0, 0, 0,
+ 80, 0, 0, 81, 20, 0, 0, 200, 201, 0,
+ 0, 202, 606, 0, 194, 195, 0, 0, 0, 78,
+ 204, 205, 206, 207, 0, 0, 208, 209, 196, 0,
+ 0, 0, 0, 0, 197, 580, 0, 192, 193, 0,
+ 0, 198, 0, 0, 0, 199, 0, 0, 0, 0,
+ 0, 80, 0, 0, 81, 20, 0, 0, 200, 201,
+ 0, 0, 202, 0, 0, 0, 0, 597, 0, 0,
+ 0, 204, 205, 206, 207, 0, 0, 208, 209, 194,
+ 195, 0, 0, 0, 78, 0, 705, 0, 192, 193,
+ 0, 0, 0, 196, 0, 0, 0, 0, 0, 197,
+ 0, 0, 0, 0, 0, 0, 198, 0, 0, 0,
+ 199, 0, 0, 0, 0, 0, 80, 0, 0, 81,
+ 20, 0, 0, 200, 201, 0, 0, 202, 689, 0,
+ 194, 195, 0, 0, 0, 78, 204, 205, 206, 207,
+ 0, 0, 208, 209, 196, 0, 0, 0, 0, 0,
+ 197, 705, 0, 192, 193, 0, 0, 198, 0, 0,
+ 0, 199, 0, 0, 0, 0, 0, 80, 0, 0,
+ 81, 20, 0, 0, 200, 201, 0, 0, 202, 706,
+ 0, 0, 0, 0, 0, 0, 0, 204, 205, 206,
+ 207, 0, 0, 208, 209, 194, 195, 0, 0, 0,
+ 78, 0, 588, 0, 192, 193, 0, 0, 0, 196,
+ 0, 0, 0, 0, 0, 197, 0, 0, 0, 0,
+ 0, 0, 198, 0, 0, 0, 199, 0, 0, 0,
+ 0, 0, 80, 0, 0, 81, 20, 0, 0, 200,
+ 201, 0, 0, 202, 749, 0, 194, 195, 0, 0,
+ 0, 78, 204, 205, 206, 207, 0, 0, 208, 209,
+ 196, 0, 0, 0, 0, 0, 197, 330, 0, 192,
+ 193, 0, 0, 198, 0, 0, 0, 199, 0, 0,
0, 0, 0, 80, 0, 0, 81, 20, 0, 0,
- 198, 199, 0, 0, 200, 612, 0, 0, 0, 0,
- 0, 0, 0, 202, 203, 204, 205, 0, 0, 206,
- 207, 192, 193, 0, 0, 0, 78, 0, 611, 0,
- 190, 191, 0, 0, 0, 194, 0, 0, 0, 0,
- 0, 195, 0, 0, 0, 0, 0, 0, 196, 0,
- 0, 0, 197, 0, 0, 0, 0, 0, 80, 0,
- 0, 81, 20, 0, 0, 198, 199, 0, 0, 200,
- 0, 0, 192, 193, 0, 618, 0, 78, 202, 203,
- 204, 205, 0, 0, 206, 207, 194, 0, 0, 0,
- 0, 0, 195, 698, 0, 190, 191, 0, 0, 196,
- 0, 0, 0, 197, 0, 0, 0, 0, 0, 80,
- 0, 0, 81, 20, 0, 0, 198, 199, 0, 0,
- 200, 676, 0, 0, 0, 0, 0, 0, 0, 202,
- 203, 204, 205, 0, 0, 206, 207, 192, 193, 0,
- 0, 0, 78, 0, 698, 0, 190, 191, 0, 0,
- 0, 194, 0, 0, 0, 0, 0, 195, 0, 0,
- 0, 0, 0, 0, 196, 0, 0, 0, 197, 0,
+ 200, 201, 0, 0, 202, 0, 0, 0, 0, 0,
+ 754, 0, 0, 204, 205, 206, 207, 0, 0, 208,
+ 209, 194, 195, 0, 0, 0, 78, 0, 335, 0,
+ 192, 193, 0, 0, 0, 196, 0, 0, 0, 0,
+ 0, 197, 0, 0, 0, 0, 0, 0, 198, 0,
+ 0, 0, 199, 0, 0, 0, 0, 0, 80, 0,
+ 0, 81, 20, 0, 0, 200, 201, 0, 0, 202,
+ 0, 0, 194, 195, 0, 0, 0, 78, 204, 205,
+ 206, 207, 0, 0, 208, 209, 196, 0, 0, 0,
+ 0, 0, 197, 337, 0, 192, 193, 0, 0, 198,
+ 0, 0, 0, 199, 0, 0, 0, 0, 0, 80,
+ 0, 0, 81, 20, 0, 0, 200, 201, 0, 0,
+ 202, 0, 0, 0, 0, 0, 0, 0, 0, 204,
+ 205, 206, 207, 0, 0, 208, 209, 194, 195, 0,
+ 0, 0, 78, 0, 339, 0, 192, 193, 0, 0,
+ 0, 196, 0, 0, 0, 0, 0, 197, 0, 0,
+ 0, 0, 0, 0, 198, 0, 0, 0, 199, 0,
0, 0, 0, 0, 80, 0, 0, 81, 20, 0,
- 0, 198, 199, 0, 0, 200, 699, 0, 192, 193,
- 0, 0, 0, 78, 202, 203, 204, 205, 0, 0,
- 206, 207, 194, 0, 0, 0, 0, 0, 195, 617,
- 0, 190, 191, 0, 0, 196, 0, 0, 0, 197,
+ 0, 200, 201, 0, 0, 202, 0, 0, 194, 195,
+ 0, 0, 0, 78, 204, 205, 206, 207, 0, 0,
+ 208, 209, 196, 0, 0, 0, 0, 0, 197, 348,
+ 0, 192, 193, 0, 0, 198, 0, 0, 0, 199,
0, 0, 0, 0, 0, 80, 0, 0, 81, 20,
- 0, 0, 198, 199, 0, 0, 200, 731, 0, 0,
- 0, 0, 0, 0, 0, 202, 203, 204, 205, 0,
- 0, 206, 207, 192, 193, 0, 0, 0, 78, 0,
- 266, 0, 190, 191, 0, 0, 0, 194, 0, 0,
- 0, 0, 0, 195, 0, 0, 0, 0, 0, 0,
- 196, 0, 0, 0, 197, 0, 0, 0, 0, 0,
- 80, 0, 0, 81, 20, 0, 0, 198, 199, 0,
- 0, 200, 0, 0, 192, 193, 0, 736, 0, 78,
- 202, 203, 204, 205, 0, 0, 206, 207, 194, 0,
- 0, 0, 0, 0, 195, 271, 0, 190, 191, 0,
- 0, 196, 0, 0, 0, 197, 0, 0, 0, 0,
- 0, 80, 0, 0, 81, 20, 0, 0, 198, 199,
- 0, 0, 200, 0, 0, 0, 0, 0, 0, 0,
- 0, 202, 203, 204, 205, 0, 0, 206, 207, 192,
- 193, 0, 0, 0, 78, 0, 273, 0, 190, 191,
- 0, 0, 0, 194, 0, 0, 0, 0, 0, 195,
- 0, 0, 0, 0, 0, 0, 196, 0, 0, 0,
- 197, 0, 0, 0, 0, 0, 80, 0, 0, 81,
- 20, 0, 0, 198, 199, 0, 0, 200, 0, 0,
- 192, 193, 0, 0, 0, 78, 202, 203, 204, 205,
- 0, 0, 206, 207, 194, 0, 0, 0, 0, 0,
- 195, 275, 0, 190, 191, 0, 0, 196, 0, 0,
- 0, 197, 0, 0, 0, 0, 0, 80, 0, 0,
- 81, 20, 0, 0, 198, 199, 0, 0, 200, 0,
- 0, 0, 0, 0, 0, 0, 0, 202, 203, 204,
- 205, 0, 0, 206, 207, 192, 193, 0, 0, 0,
- 78, 0, 284, 0, 190, 191, 0, 0, 0, 194,
- 0, 0, 0, 0, 0, 195, 0, 0, 0, 0,
- 0, 0, 196, 0, 0, 0, 197, 0, 0, 0,
- 0, 0, 80, 0, 0, 81, 20, 0, 0, 198,
- 199, 0, 0, 200, 0, 0, 192, 193, 0, 0,
- 0, 78, 202, 203, 204, 205, 0, 0, 206, 207,
- 194, 0, 0, 0, 0, 0, 195, 286, 0, 190,
- 191, 0, 0, 196, 0, 0, 0, 197, 0, 0,
+ 0, 0, 200, 201, 0, 0, 202, 0, 0, 0,
+ 0, 0, 0, 0, 0, 204, 205, 206, 207, 0,
+ 0, 208, 209, 194, 195, 0, 0, 0, 78, 0,
+ 350, 0, 192, 193, 0, 0, 0, 196, 0, 0,
+ 0, 0, 0, 197, 0, 0, 0, 0, 0, 0,
+ 198, 0, 0, 0, 199, 0, 0, 0, 0, 0,
+ 80, 0, 0, 81, 20, 0, 0, 200, 201, 0,
+ 0, 202, 0, 0, 194, 195, 0, 0, 0, 78,
+ 204, 205, 206, 207, 0, 0, 208, 209, 196, 0,
+ 0, 0, 0, 0, 197, 352, 0, 192, 193, 0,
+ 0, 198, 0, 0, 0, 199, 0, 0, 0, 0,
+ 0, 80, 0, 0, 81, 20, 0, 0, 200, 201,
+ 0, 0, 202, 0, 0, 0, 0, 0, 0, 0,
+ 0, 204, 205, 206, 207, 0, 0, 208, 209, 194,
+ 195, 0, 0, 0, 78, 0, 409, 0, 192, 193,
+ 0, 0, 0, 196, 0, 0, 0, 0, 0, 197,
+ 0, 0, 0, 0, 0, 0, 198, 0, 0, 0,
+ 199, 0, 0, 0, 0, 0, 80, 0, 0, 81,
+ 20, 0, 0, 200, 201, 0, 0, 202, 0, 0,
+ 194, 195, 0, 0, 0, 78, 204, 205, 206, 207,
+ 0, 0, 208, 209, 196, 0, 0, 0, 0, 0,
+ 197, 491, 0, 192, 193, 0, 0, 198, 0, 0,
+ 0, 199, 0, 0, 0, 0, 0, 80, 0, 0,
+ 81, 20, 0, 0, 200, 201, 0, 0, 202, 0,
+ 0, 0, 0, 0, 0, 0, 0, 204, 205, 206,
+ 207, 0, 0, 208, 209, 194, 195, 0, 0, 0,
+ 78, 0, 499, 0, 192, 193, 0, 0, 0, 196,
+ 0, 0, 0, 0, 0, 197, 0, 0, 0, 0,
+ 0, 0, 198, 0, 0, 0, 199, 0, 0, 0,
+ 0, 0, 80, 0, 0, 81, 20, 0, 0, 200,
+ 201, 0, 0, 202, 0, 0, 194, 195, 0, 0,
+ 0, 78, 204, 205, 206, 207, 0, 0, 208, 209,
+ 196, 0, 0, 0, 0, 0, 197, 503, 0, 192,
+ 193, 0, 0, 198, 0, 0, 0, 199, 0, 0,
0, 0, 0, 80, 0, 0, 81, 20, 0, 0,
- 198, 199, 0, 0, 200, 0, 0, 0, 0, 0,
- 0, 0, 0, 202, 203, 204, 205, 0, 0, 206,
- 207, 192, 193, 0, 0, 0, 78, 0, 288, 0,
- 190, 191, 0, 0, 0, 194, 0, 0, 0, 0,
- 0, 195, 0, 0, 0, 0, 0, 0, 196, 0,
- 0, 0, 197, 0, 0, 0, 0, 0, 80, 0,
- 0, 81, 20, 0, 0, 198, 199, 0, 0, 200,
- 0, 0, 192, 193, 0, 0, 0, 78, 202, 203,
- 204, 205, 0, 0, 206, 207, 194, 0, 0, 0,
- 0, 0, 195, 436, 0, 190, 191, 0, 0, 196,
- 0, 0, 0, 197, 0, 0, 0, 0, 0, 80,
- 0, 0, 81, 20, 0, 0, 198, 199, 0, 0,
- 200, 0, 0, 0, 0, 0, 0, 0, 0, 202,
- 203, 204, 205, 0, 0, 206, 207, 192, 193, 0,
- 0, 0, 78, 0, 444, 0, 190, 191, 0, 0,
- 0, 194, 0, 0, 0, 0, 0, 195, 0, 0,
- 0, 0, 0, 0, 196, 0, 0, 0, 197, 0,
+ 200, 201, 0, 0, 202, 0, 0, 0, 0, 0,
+ 0, 0, 0, 204, 205, 206, 207, 0, 0, 208,
+ 209, 194, 195, 0, 0, 0, 78, 0, 505, 0,
+ 192, 193, 0, 0, 0, 196, 0, 0, 0, 0,
+ 0, 197, 0, 0, 0, 0, 0, 0, 198, 0,
+ 0, 0, 199, 0, 0, 0, 0, 0, 80, 0,
+ 0, 81, 20, 0, 0, 200, 201, 0, 0, 202,
+ 0, 0, 194, 195, 0, 0, 0, 78, 204, 205,
+ 206, 207, 0, 0, 208, 209, 196, 0, 0, 0,
+ 0, 0, 197, 507, 0, 192, 193, 0, 0, 198,
+ 0, 0, 0, 199, 0, 0, 0, 0, 0, 80,
+ 0, 0, 81, 20, 0, 0, 200, 201, 0, 0,
+ 202, 0, 0, 0, 0, 0, 0, 0, 0, 204,
+ 205, 206, 207, 0, 0, 208, 209, 194, 195, 0,
+ 0, 0, 78, 0, 509, 0, 192, 193, 0, 0,
+ 0, 196, 0, 0, 0, 0, 0, 197, 0, 0,
+ 0, 0, 0, 0, 198, 0, 0, 0, 199, 0,
0, 0, 0, 0, 80, 0, 0, 81, 20, 0,
- 0, 198, 199, 0, 0, 200, 0, 0, 192, 193,
- 0, 0, 0, 78, 202, 203, 204, 205, 0, 0,
- 206, 207, 194, 0, 0, 0, 0, 0, 195, 448,
- 0, 190, 191, 0, 0, 196, 0, 0, 0, 197,
+ 0, 200, 201, 0, 0, 202, 0, 0, 194, 195,
+ 0, 0, 0, 78, 204, 205, 206, 207, 0, 0,
+ 208, 209, 196, 0, 0, 0, 0, 0, 197, 511,
+ 0, 192, 193, 0, 0, 198, 0, 0, 0, 199,
0, 0, 0, 0, 0, 80, 0, 0, 81, 20,
- 0, 0, 198, 199, 0, 0, 200, 0, 0, 0,
- 0, 0, 0, 0, 0, 202, 203, 204, 205, 0,
- 0, 206, 207, 192, 193, 0, 0, 0, 78, 0,
- 450, 0, 190, 191, 0, 0, 0, 194, 0, 0,
- 0, 0, 0, 195, 0, 0, 0, 0, 0, 0,
- 196, 0, 0, 0, 197, 0, 0, 0, 0, 0,
- 80, 0, 0, 81, 20, 0, 0, 198, 199, 0,
- 0, 200, 0, 0, 192, 193, 0, 0, 0, 78,
- 202, 203, 204, 205, 0, 0, 206, 207, 194, 0,
- 0, 0, 0, 0, 195, 452, 0, 190, 191, 0,
- 0, 196, 0, 0, 0, 197, 0, 0, 0, 0,
- 0, 80, 0, 0, 81, 20, 0, 0, 198, 199,
- 0, 0, 200, 0, 0, 0, 0, 0, 0, 0,
- 0, 202, 203, 204, 205, 0, 0, 206, 207, 192,
- 193, 0, 0, 0, 78, 0, 454, 0, 190, 191,
- 0, 0, 0, 194, 0, 0, 0, 0, 0, 195,
- 0, 0, 0, 0, 0, 0, 196, 0, 0, 0,
- 197, 0, 0, 0, 0, 0, 80, 0, 0, 81,
- 20, 0, 0, 198, 199, 0, 0, 200, 0, 0,
- 192, 193, 0, 0, 0, 78, 202, 203, 204, 205,
- 0, 0, 206, 207, 194, 0, 0, 0, 0, 0,
- 195, 456, 0, 190, 191, 0, 0, 196, 0, 0,
- 0, 197, 0, 0, 0, 0, 0, 80, 0, 0,
- 81, 20, 0, 0, 198, 199, 0, 0, 200, 0,
- 0, 0, 0, 0, 0, 0, 0, 202, 203, 204,
- 205, 0, 0, 206, 207, 192, 193, 0, 0, 0,
- 78, 0, 458, 0, 190, 191, 0, 0, 0, 194,
- 0, 0, 0, 0, 0, 195, 0, 0, 0, 0,
- 0, 0, 196, 0, 0, 0, 197, 0, 0, 0,
- 0, 0, 80, 0, 0, 81, 20, 0, 0, 198,
- 199, 0, 0, 200, 0, 0, 192, 193, 0, 0,
- 0, 78, 202, 203, 204, 205, 0, 0, 206, 207,
- 194, 0, 0, 0, 0, 0, 195, 460, 0, 190,
- 191, 0, 0, 196, 0, 0, 0, 197, 0, 0,
+ 0, 0, 200, 201, 0, 0, 202, 0, 0, 0,
+ 0, 0, 0, 0, 0, 204, 205, 206, 207, 0,
+ 0, 208, 209, 194, 195, 0, 0, 0, 78, 0,
+ 513, 0, 192, 193, 0, 0, 0, 196, 0, 0,
+ 0, 0, 0, 197, 0, 0, 0, 0, 0, 0,
+ 198, 0, 0, 0, 199, 0, 0, 0, 0, 0,
+ 80, 0, 0, 81, 20, 0, 0, 200, 201, 0,
+ 0, 202, 0, 0, 194, 195, 0, 0, 0, 78,
+ 204, 205, 206, 207, 0, 0, 208, 209, 196, 0,
+ 0, 0, 0, 0, 197, 515, 0, 192, 193, 0,
+ 0, 198, 0, 0, 0, 199, 0, 0, 0, 0,
+ 0, 80, 0, 0, 81, 20, 0, 0, 200, 201,
+ 0, 0, 202, 0, 0, 0, 0, 0, 0, 0,
+ 0, 204, 205, 206, 207, 0, 0, 208, 209, 194,
+ 195, 0, 0, 0, 78, 0, 517, 0, 192, 193,
+ 0, 0, 0, 196, 0, 0, 0, 0, 0, 197,
+ 0, 0, 0, 0, 0, 0, 198, 0, 0, 0,
+ 199, 0, 0, 0, 0, 0, 80, 0, 0, 81,
+ 20, 0, 0, 200, 201, 0, 0, 202, 0, 0,
+ 194, 195, 0, 0, 0, 78, 204, 205, 206, 207,
+ 0, 0, 208, 209, 196, 0, 0, 0, 0, 0,
+ 197, 519, 0, 192, 193, 0, 0, 198, 0, 0,
+ 0, 199, 0, 0, 0, 0, 0, 80, 0, 0,
+ 81, 20, 0, 0, 200, 201, 0, 0, 202, 0,
+ 0, 0, 0, 0, 0, 0, 0, 204, 205, 206,
+ 207, 0, 0, 208, 209, 194, 195, 0, 0, 0,
+ 78, 0, 521, 0, 192, 193, 0, 0, 0, 196,
+ 0, 0, 0, 0, 0, 197, 0, 0, 0, 0,
+ 0, 0, 198, 0, 0, 0, 199, 0, 0, 0,
+ 0, 0, 80, 0, 0, 81, 20, 0, 0, 200,
+ 201, 0, 0, 202, 0, 0, 194, 195, 0, 0,
+ 0, 78, 204, 205, 206, 207, 0, 0, 208, 209,
+ 196, 0, 0, 0, 0, 0, 197, 523, 0, 192,
+ 193, 0, 0, 198, 0, 0, 0, 199, 0, 0,
0, 0, 0, 80, 0, 0, 81, 20, 0, 0,
- 198, 199, 0, 0, 200, 0, 0, 0, 0, 0,
- 0, 0, 0, 202, 203, 204, 205, 0, 0, 206,
- 207, 192, 193, 0, 0, 0, 78, 0, 462, 0,
- 190, 191, 0, 0, 0, 194, 0, 0, 0, 0,
- 0, 195, 0, 0, 0, 0, 0, 0, 196, 0,
- 0, 0, 197, 0, 0, 0, 0, 0, 80, 0,
- 0, 81, 20, 0, 0, 198, 199, 0, 0, 200,
- 0, 0, 192, 193, 0, 0, 0, 78, 202, 203,
- 204, 205, 0, 0, 206, 207, 194, 0, 0, 0,
- 0, 0, 195, 464, 0, 190, 191, 0, 0, 196,
- 0, 0, 0, 197, 0, 0, 0, 0, 0, 80,
- 0, 0, 81, 20, 0, 0, 198, 199, 0, 0,
- 200, 0, 0, 0, 0, 0, 0, 0, 0, 202,
- 203, 204, 205, 0, 0, 206, 207, 192, 193, 0,
- 0, 0, 78, 0, 466, 0, 190, 191, 0, 0,
- 0, 194, 0, 0, 0, 0, 0, 195, 0, 0,
- 0, 0, 0, 0, 196, 0, 0, 0, 197, 0,
+ 200, 201, 0, 0, 202, 0, 0, 0, 0, 0,
+ 0, 0, 0, 204, 205, 206, 207, 0, 0, 208,
+ 209, 194, 195, 0, 0, 0, 78, 0, 525, 0,
+ 192, 193, 0, 0, 0, 196, 0, 0, 0, 0,
+ 0, 197, 0, 0, 0, 0, 0, 0, 198, 0,
+ 0, 0, 199, 0, 0, 0, 0, 0, 80, 0,
+ 0, 81, 20, 0, 0, 200, 201, 0, 0, 202,
+ 0, 0, 194, 195, 0, 0, 0, 78, 204, 205,
+ 206, 207, 0, 0, 208, 209, 196, 0, 0, 0,
+ 0, 0, 197, 530, 0, 192, 193, 0, 0, 198,
+ 0, 0, 0, 199, 0, 0, 0, 0, 0, 80,
+ 0, 0, 81, 20, 0, 0, 200, 201, 0, 0,
+ 202, 0, 0, 0, 0, 0, 0, 0, 0, 204,
+ 205, 206, 207, 0, 0, 208, 209, 194, 195, 0,
+ 0, 0, 78, 0, 532, 0, 192, 193, 0, 0,
+ 0, 196, 0, 0, 0, 0, 0, 197, 0, 0,
+ 0, 0, 0, 0, 198, 0, 0, 0, 199, 0,
0, 0, 0, 0, 80, 0, 0, 81, 20, 0,
- 0, 198, 199, 0, 0, 200, 0, 0, 192, 193,
- 0, 0, 0, 78, 202, 203, 204, 205, 0, 0,
- 206, 207, 194, 0, 0, 0, 0, 0, 195, 468,
- 0, 190, 191, 0, 0, 196, 0, 0, 0, 197,
+ 0, 200, 201, 0, 0, 202, 0, 0, 194, 195,
+ 0, 0, 0, 78, 204, 205, 206, 207, 0, 0,
+ 208, 209, 196, 0, 0, 0, 0, 0, 197, 534,
+ 0, 192, 193, 0, 0, 198, 0, 0, 0, 199,
0, 0, 0, 0, 0, 80, 0, 0, 81, 20,
- 0, 0, 198, 199, 0, 0, 200, 0, 0, 0,
- 0, 0, 0, 0, 0, 202, 203, 204, 205, 0,
- 0, 206, 207, 192, 193, 0, 0, 0, 78, 0,
- 470, 0, 190, 191, 0, 0, 0, 194, 0, 0,
- 0, 0, 0, 195, 0, 0, 0, 0, 0, 0,
- 196, 0, 0, 0, 197, 0, 0, 0, 0, 0,
- 80, 0, 0, 81, 20, 0, 0, 198, 199, 0,
- 0, 200, 0, 0, 192, 193, 0, 0, 0, 78,
- 202, 203, 204, 205, 0, 0, 206, 207, 194, 0,
- 0, 0, 0, 0, 195, 475, 0, 190, 191, 0,
- 0, 196, 0, 0, 0, 197, 0, 0, 0, 0,
- 0, 80, 0, 0, 81, 20, 0, 0, 198, 199,
- 0, 0, 200, 0, 0, 0, 0, 0, 0, 0,
- 0, 202, 203, 204, 205, 0, 0, 206, 207, 192,
- 193, 0, 0, 0, 78, 0, 477, 0, 190, 191,
- 0, 0, 0, 194, 0, 0, 0, 0, 0, 195,
- 0, 0, 0, 0, 0, 0, 196, 0, 0, 0,
- 197, 0, 0, 0, 0, 0, 80, 0, 0, 81,
- 20, 0, 0, 198, 199, 0, 0, 200, 0, 0,
- 192, 193, 0, 0, 0, 78, 202, 203, 204, 205,
- 0, 0, 206, 207, 194, 0, 0, 0, 0, 0,
- 195, 479, 0, 190, 191, 0, 0, 196, 0, 0,
- 0, 197, 0, 0, 0, 0, 0, 80, 0, 0,
- 81, 20, 0, 0, 198, 199, 0, 0, 200, 0,
- 0, 0, 0, 0, 0, 0, 0, 202, 203, 204,
- 205, 0, 0, 206, 207, 192, 193, 0, 0, 0,
- 78, 0, 481, 0, 190, 191, 0, 0, 0, 194,
- 0, 0, 0, 0, 0, 195, 0, 0, 0, 0,
- 0, 0, 196, 0, 0, 0, 197, 0, 0, 0,
- 0, 0, 80, 0, 0, 81, 20, 0, 0, 198,
- 199, 0, 0, 200, 0, 0, 192, 193, 0, 0,
- 0, 78, 202, 203, 204, 205, 0, 0, 206, 207,
- 194, 0, 0, 0, 0, 0, 195, 483, 0, 190,
- 191, 0, 0, 196, 0, 0, 0, 197, 0, 0,
+ 0, 0, 200, 201, 0, 0, 202, 0, 0, 0,
+ 0, 0, 0, 0, 0, 204, 205, 206, 207, 0,
+ 0, 208, 209, 194, 195, 0, 0, 0, 78, 0,
+ 536, 0, 192, 193, 0, 0, 0, 196, 0, 0,
+ 0, 0, 0, 197, 0, 0, 0, 0, 0, 0,
+ 198, 0, 0, 0, 199, 0, 0, 0, 0, 0,
+ 80, 0, 0, 81, 20, 0, 0, 200, 201, 0,
+ 0, 202, 0, 0, 194, 195, 0, 0, 0, 78,
+ 204, 205, 206, 207, 0, 0, 208, 209, 196, 0,
+ 0, 0, 0, 0, 197, 538, 0, 192, 193, 0,
+ 0, 198, 0, 0, 0, 199, 0, 0, 0, 0,
+ 0, 80, 0, 0, 81, 20, 0, 0, 200, 201,
+ 0, 0, 202, 0, 0, 0, 0, 0, 0, 0,
+ 0, 204, 205, 206, 207, 0, 0, 208, 209, 194,
+ 195, 0, 0, 0, 78, 0, 540, 0, 192, 193,
+ 0, 0, 0, 196, 0, 0, 0, 0, 0, 197,
+ 0, 0, 0, 0, 0, 0, 198, 0, 0, 0,
+ 199, 0, 0, 0, 0, 0, 80, 0, 0, 81,
+ 20, 0, 0, 200, 201, 0, 0, 202, 0, 0,
+ 194, 195, 0, 0, 0, 78, 204, 205, 206, 207,
+ 0, 0, 208, 209, 196, 0, 0, 0, 0, 0,
+ 197, 542, 0, 192, 193, 0, 0, 198, 0, 0,
+ 0, 199, 0, 0, 0, 0, 0, 80, 0, 0,
+ 81, 20, 0, 0, 200, 201, 0, 0, 202, 0,
+ 0, 0, 0, 0, 0, 0, 0, 204, 205, 206,
+ 207, 0, 0, 208, 209, 194, 195, 0, 0, 0,
+ 78, 0, 547, 0, 192, 193, 0, 0, 0, 196,
+ 0, 0, 0, 0, 0, 197, 0, 0, 0, 0,
+ 0, 0, 198, 0, 0, 0, 199, 0, 0, 0,
+ 0, 0, 80, 0, 0, 81, 20, 0, 0, 200,
+ 201, 0, 0, 202, 0, 0, 194, 195, 0, 0,
+ 0, 78, 204, 205, 206, 207, 0, 0, 208, 209,
+ 196, 0, 0, 0, 0, 0, 197, 556, 0, 192,
+ 193, 0, 0, 198, 0, 0, 0, 199, 0, 0,
0, 0, 0, 80, 0, 0, 81, 20, 0, 0,
- 198, 199, 0, 0, 200, 0, 0, 0, 0, 0,
- 0, 0, 0, 202, 203, 204, 205, 0, 0, 206,
- 207, 192, 193, 0, 0, 0, 78, 0, 485, 0,
- 190, 191, 0, 0, 0, 194, 0, 0, 0, 0,
- 0, 195, 0, 0, 0, 0, 0, 0, 196, 0,
- 0, 0, 197, 0, 0, 0, 0, 0, 80, 0,
- 0, 81, 20, 0, 0, 198, 199, 0, 0, 200,
- 0, 0, 192, 193, 0, 0, 0, 78, 202, 203,
- 204, 205, 0, 0, 206, 207, 194, 0, 0, 0,
- 0, 0, 195, 487, 0, 190, 191, 0, 0, 196,
- 0, 0, 0, 197, 0, 0, 0, 0, 0, 80,
- 0, 0, 81, 20, 0, 0, 198, 199, 0, 0,
- 200, 0, 0, 0, 0, 0, 0, 0, 0, 202,
- 203, 204, 205, 0, 0, 206, 207, 192, 193, 0,
- 0, 0, 78, 0, 492, 0, 190, 191, 0, 0,
- 0, 194, 0, 0, 0, 0, 0, 195, 0, 0,
- 0, 0, 0, 0, 196, 0, 0, 0, 197, 0,
+ 200, 201, 0, 0, 202, 0, 0, 0, 0, 0,
+ 0, 0, 0, 204, 205, 206, 207, 0, 0, 208,
+ 209, 194, 195, 0, 0, 0, 78, 0, 564, 0,
+ 192, 193, 0, 0, 0, 196, 0, 0, 0, 0,
+ 0, 197, 0, 0, 0, 0, 0, 0, 198, 0,
+ 0, 0, 199, 0, 0, 0, 0, 0, 80, 0,
+ 0, 81, 20, 0, 0, 200, 201, 0, 0, 202,
+ 0, 0, 194, 195, 0, 0, 0, 78, 204, 205,
+ 206, 207, 0, 0, 208, 209, 196, 0, 0, 0,
+ 0, 0, 197, 566, 0, 192, 193, 0, 0, 198,
+ 0, 0, 0, 199, 0, 0, 0, 0, 0, 80,
+ 0, 0, 81, 20, 0, 0, 200, 201, 0, 0,
+ 202, 0, 0, 0, 0, 0, 0, 0, 0, 204,
+ 205, 206, 207, 0, 0, 208, 209, 194, 195, 0,
+ 0, 0, 78, 0, 591, 0, 192, 193, 0, 0,
+ 0, 196, 0, 0, 0, 0, 0, 197, 0, 0,
+ 0, 0, 0, 0, 198, 0, 0, 0, 199, 0,
0, 0, 0, 0, 80, 0, 0, 81, 20, 0,
- 0, 198, 199, 0, 0, 200, 0, 0, 192, 193,
- 0, 0, 0, 78, 202, 203, 204, 205, 0, 0,
- 206, 207, 194, 0, 0, 0, 0, 0, 195, 499,
- 0, 190, 191, 0, 0, 196, 0, 0, 0, 197,
+ 0, 200, 201, 0, 0, 202, 0, 0, 194, 195,
+ 0, 0, 0, 78, 204, 205, 206, 207, 0, 0,
+ 208, 209, 196, 0, 0, 0, 0, 0, 197, 608,
+ 0, 192, 193, 0, 0, 198, 0, 0, 0, 199,
0, 0, 0, 0, 0, 80, 0, 0, 81, 20,
- 0, 0, 198, 199, 0, 0, 200, 0, 0, 0,
- 0, 0, 0, 0, 0, 202, 203, 204, 205, 0,
- 0, 206, 207, 192, 193, 0, 0, 0, 78, 0,
- 568, 0, 190, 191, 0, 0, 0, 194, 0, 0,
- 0, 0, 0, 195, 0, 0, 0, 0, 0, 0,
- 196, 0, 0, 0, 197, 0, 0, 0, 0, 0,
- 80, 0, 0, 81, 20, 0, 0, 198, 199, 0,
- 0, 200, 0, 0, 192, 193, 0, 0, 0, 78,
- 202, 203, 204, 205, 0, 0, 206, 207, 194, 0,
- 0, 0, 0, 0, 195, 588, 0, 190, 191, 0,
- 0, 196, 0, 0, 0, 197, 0, 0, 0, 0,
- 0, 80, 0, 0, 81, 20, 0, 0, 198, 199,
- 0, 0, 200, 0, 0, 0, 0, 0, 0, 0,
- 0, 202, 203, 204, 205, 0, 0, 206, 207, 192,
- 193, 0, 0, 0, 78, 0, 596, 0, 190, 191,
- 0, 0, 0, 194, 0, 0, 0, 0, 0, 195,
- 0, 0, 0, 0, 0, 0, 196, 0, 0, 0,
- 197, 0, 0, 0, 0, 0, 80, 0, 0, 81,
- 20, 0, 0, 198, 199, 0, 0, 200, 0, 0,
- 192, 193, 0, 0, 0, 78, 202, 203, 204, 205,
- 0, 0, 206, 207, 194, 0, 0, 0, 0, 0,
- 195, 598, 0, 190, 191, 0, 0, 196, 0, 0,
- 0, 197, 0, 0, 0, 0, 0, 80, 0, 0,
- 81, 20, 0, 0, 198, 199, 0, 0, 200, 0,
- 0, 0, 0, 0, 0, 0, 0, 202, 203, 204,
- 205, 0, 0, 206, 207, 192, 193, 0, 0, 0,
- 78, 0, 620, 0, 190, 191, 0, 0, 0, 194,
- 0, 0, 0, 0, 0, 195, 0, 0, 0, 0,
- 0, 0, 196, 0, 0, 0, 197, 0, 0, 0,
- 0, 0, 80, 0, 0, 81, 20, 0, 0, 198,
- 199, 0, 0, 200, 0, 0, 192, 193, 0, 0,
- 0, 78, 202, 203, 204, 205, 0, 0, 206, 207,
- 194, 0, 0, 0, 0, 0, 195, 637, 0, 190,
- 191, 0, 0, 196, 0, 0, 0, 197, 0, 0,
+ 0, 0, 200, 201, 0, 0, 202, 0, 0, 0,
+ 0, 0, 0, 0, 0, 204, 205, 206, 207, 0,
+ 0, 208, 209, 194, 195, 0, 0, 0, 78, 0,
+ 675, 0, 192, 193, 0, 0, 0, 196, 0, 0,
+ 0, 0, 0, 197, 0, 0, 0, 0, 0, 0,
+ 198, 0, 0, 0, 199, 0, 0, 0, 0, 0,
+ 80, 0, 0, 81, 20, 0, 0, 200, 201, 0,
+ 0, 202, 0, 0, 194, 195, 0, 0, 0, 78,
+ 204, 205, 206, 207, 0, 0, 208, 209, 196, 0,
+ 0, 0, 0, 0, 197, 679, 0, 192, 193, 0,
+ 0, 198, 0, 0, 0, 199, 0, 0, 0, 0,
+ 0, 80, 0, 0, 81, 20, 0, 0, 200, 201,
+ 0, 0, 202, 0, 0, 0, 0, 0, 0, 0,
+ 0, 204, 205, 206, 207, 0, 0, 208, 209, 194,
+ 195, 0, 0, 0, 78, 0, 685, 0, 192, 193,
+ 0, 0, 0, 196, 0, 0, 0, 0, 0, 197,
+ 0, 0, 0, 0, 0, 0, 198, 0, 0, 0,
+ 199, 0, 0, 0, 0, 0, 80, 0, 0, 81,
+ 20, 0, 0, 200, 201, 0, 0, 202, 0, 0,
+ 194, 195, 0, 0, 0, 78, 204, 205, 206, 207,
+ 0, 0, 208, 209, 196, 0, 0, 0, 0, 0,
+ 197, 711, 0, 192, 193, 0, 0, 198, 0, 0,
+ 0, 199, 0, 0, 0, 0, 0, 80, 0, 0,
+ 81, 20, 0, 0, 200, 201, 0, 0, 202, 0,
+ 0, 0, 0, 0, 0, 0, 0, 204, 205, 206,
+ 207, 0, 0, 208, 209, 194, 195, 0, 0, 0,
+ 78, 0, 574, 0, 0, 0, 0, 0, 0, 196,
+ 0, 0, 0, 0, 0, 197, 0, 0, 0, 0,
+ 0, 0, 198, 0, 0, 0, 199, 660, 0, 0,
+ 0, 0, 80, 0, 0, 81, 20, 0, 0, 200,
+ 201, 0, 0, 202, 0, -287, -287, -287, 0, 0,
+ 0, -287, 204, 205, 206, 207, 0, 0, 208, 209,
+ -287, 0, 0, 0, 0, 0, -287, 0, 0, 722,
+ 0, 194, 195, -287, 0, 0, 78, -287, 0, 0,
+ 0, 0, 0, -287, 0, 196, -287, -287, 0, 0,
+ 0, 197, 0, 0, -287, 0, 192, 193, 198, 0,
+ -287, 0, 199, -287, -287, -287, -287, 0, 80, -287,
+ -287, 81, 20, 194, 195, 0, 0, 0, 78, 277,
+ -295, 0, 0, 0, 0, 0, 0, 196, 204, 205,
+ 206, 207, 0, 197, 208, 209, 658, 0, 194, 195,
+ 198, 0, 0, 78, 199, 0, 0, 0, 0, 0,
+ 80, 0, 196, 81, 20, 0, 0, 0, 197, 0,
+ 0, 277, -295, 192, 193, 198, 0, 0, 0, 199,
+ 204, 205, 206, 207, 0, 80, 208, 209, 81, 20,
+ 194, 195, 200, 201, 0, 78, 202, 0, 203, 356,
+ 0, 0, 0, 0, 196, 204, 205, 206, 207, 0,
+ 197, 208, 209, 0, 0, 194, 195, 198, 0, 0,
+ 78, 199, 0, 0, 192, 193, 0, 80, 0, 196,
+ 81, 20, 0, 0, 0, 197, 0, 0, 277, 0,
+ 0, 0, 198, 0, 0, 0, 199, 204, 205, 206,
+ 207, 0, 80, 208, 209, 81, 20, 0, 0, 200,
+ 201, 0, 0, 202, 488, 0, 194, 195, 0, 0,
+ 0, 78, 204, 205, 206, 207, 0, 0, 208, 209,
+ 196, 0, 0, 0, 0, 0, 197, 0, 0, 192,
+ 193, 0, 0, 198, 0, 0, 0, 199, 0, 0,
0, 0, 0, 80, 0, 0, 81, 20, 0, 0,
- 198, 199, 0, 0, 200, 0, 0, 0, 0, 0,
- 0, 0, 0, 202, 203, 204, 205, 0, 0, 206,
- 207, 192, 193, 0, 0, 0, 78, 0, 641, 0,
- 190, 191, 0, 0, 0, 194, 0, 0, 0, 0,
- 0, 195, 0, 0, 0, 0, 0, 0, 196, 0,
- 0, 0, 197, 0, 0, 0, 0, 0, 80, 0,
- 0, 81, 20, 0, 0, 198, 199, 0, 0, 200,
- 0, 0, 192, 193, 0, 0, 0, 78, 202, 203,
- 204, 205, 0, 0, 206, 207, 194, 0, 0, 0,
- 0, 0, 195, 647, 0, 190, 191, 0, 0, 196,
- 0, 0, 0, 197, 0, 0, 0, 0, 0, 80,
- 0, 0, 81, 20, 0, 0, 198, 199, 0, 0,
- 200, 0, 0, 0, 0, 0, 0, 0, 0, 202,
- 203, 204, 205, 0, 0, 206, 207, 192, 193, 0,
- 0, 0, 78, 0, 740, 0, 190, 191, 0, 0,
- 0, 194, 0, 0, 0, 0, 0, 195, 0, 0,
- 0, 0, 0, 0, 196, 0, 0, 0, 197, 0,
+ 200, 201, 0, 0, 202, 624, 0, 0, 0, 0,
+ 0, 0, 0, 204, 205, 206, 207, 0, 0, 208,
+ 209, 194, 195, 0, 0, 0, 78, 0, 0, 0,
+ 192, 193, 0, 0, 0, 196, 0, 0, 0, 0,
+ 0, 197, 0, 0, 0, 0, 0, 0, 198, 0,
+ 0, 0, 199, 0, 0, 0, 0, 0, 80, 0,
+ 0, 81, 20, 0, 0, 200, 201, 0, 0, 202,
+ 666, 0, 194, 195, 0, 0, 0, 78, 204, 205,
+ 206, 207, 0, 0, 208, 209, 196, 0, 0, 0,
+ 0, 0, 197, 0, 0, 192, 193, 0, 0, 198,
+ 0, 0, 0, 199, 0, 0, 0, 0, 0, 80,
+ 0, 0, 81, 20, 0, 0, 200, 201, 0, 0,
+ 202, 681, 0, 0, 0, 0, 0, 0, 0, 204,
+ 205, 206, 207, 0, 0, 208, 209, 194, 195, 0,
+ 0, 0, 78, 0, 0, 0, 0, 0, 0, 0,
+ 0, 196, 0, 0, 0, 0, 0, 197, 0, 0,
+ 0, 0, 0, 0, 198, 0, 0, 0, 199, 0,
0, 0, 0, 0, 80, 0, 0, 81, 20, 0,
- 0, 198, 199, 0, 0, 200, 0, 0, 192, 193,
- 0, 0, 0, 78, 202, 203, 204, 205, 0, 0,
- 206, 207, 194, 0, 0, 0, 0, 0, 195, 0,
- 605, 0, 0, 0, 0, 196, 0, 0, 0, 197,
+ 0, 200, 201, 0, 0, 202, 0, 2, 194, 195,
+ 0, 0, 0, 78, 204, 205, 206, 207, 0, 0,
+ 208, 209, 196, 0, 0, 0, 0, 0, 197, 0,
+ 0, 0, 0, 0, 0, 198, 0, 0, 0, 199,
0, 0, 0, 0, 0, 80, 0, 0, 81, 20,
- 0, 0, 198, 199, 0, 668, 200, 0, 0, 0,
- 0, 0, 0, 0, 0, 202, 203, 204, 205, 0,
- 0, 206, 207, -284, -284, -284, 0, 0, 0, -284,
- 0, 0, 0, 0, 0, 0, 0, 0, -284, 0,
- 0, 0, 0, 0, -284, 0, 0, 704, 0, 192,
- 193, -284, 0, 0, 78, -284, 0, 0, 0, 0,
- 0, -284, 0, 194, -284, -284, 0, 0, 0, 195,
- 0, 0, -284, 0, 190, 191, 196, 0, -284, 0,
- 197, -284, -284, -284, -284, 0, 80, -284, -284, 81,
- 20, 192, 193, 0, 0, 0, 78, 345, -292, 0,
- 0, 0, 0, 0, 0, 194, 202, 203, 204, 205,
- 0, 195, 206, 207, 666, 0, 192, 193, 196, 0,
- 0, 78, 197, 0, 0, 0, 0, 0, 80, 0,
- 194, 81, 20, 0, 0, 0, 195, 0, 0, 345,
- -292, 190, 191, 196, 0, 0, 0, 197, 202, 203,
- 204, 205, 0, 80, 206, 207, 81, 20, 192, 193,
- 198, 199, 0, 78, 200, 0, 201, 292, 0, 0,
- 0, 293, 194, 202, 203, 204, 205, 0, 195, 206,
- 207, 0, 0, 192, 193, 196, 0, 0, 78, 197,
- 0, 0, 190, 191, 0, 80, 0, 194, 81, 20,
- 0, 0, 0, 195, 0, 0, 345, 0, 0, 0,
- 196, 0, 0, 0, 197, 202, 203, 204, 205, 0,
- 80, 206, 207, 81, 20, 0, 0, 198, 199, 0,
- 0, 200, 433, 0, 192, 193, 0, 0, 0, 78,
- 202, 203, 204, 205, 0, 0, 206, 207, 194, 0,
- 0, 0, 0, 0, 195, 0, 0, 190, 191, 0,
- 0, 196, 0, 0, 0, 197, 0, 0, 0, 0,
- 0, 80, 0, 0, 81, 20, 0, 0, 198, 199,
- 0, 0, 200, 584, 0, 0, 0, 0, 0, 0,
- 0, 202, 203, 204, 205, 0, 0, 206, 207, 192,
- 193, 0, 0, 0, 78, 0, 0, 0, 190, 191,
- 0, 0, 0, 194, 0, 0, 0, 0, 0, 195,
- 0, 0, 0, 0, 0, 0, 196, 0, 0, 0,
- 197, 0, 0, 0, 0, 0, 80, 0, 0, 81,
- 20, 0, 0, 198, 199, 0, 0, 200, 628, 0,
- 192, 193, 0, 0, 0, 78, 202, 203, 204, 205,
- 0, 0, 206, 207, 194, 0, 0, 0, 0, 0,
- 195, 0, 0, 190, 191, 0, 0, 196, 0, 0,
- 0, 197, 0, 0, 0, 0, 0, 80, 0, 0,
- 81, 20, 0, 0, 198, 199, 0, 0, 200, 643,
- 0, 0, 0, 0, 0, 0, 0, 202, 203, 204,
- 205, 0, 0, 206, 207, 192, 193, 0, 0, 0,
- 78, 0, 0, 0, 0, 0, 0, 0, 0, 194,
- 0, 0, 0, 0, 0, 195, 0, 0, 0, 0,
- 0, 0, 196, 0, 0, 0, 197, 0, 0, 0,
- 0, 0, 80, 0, 0, 81, 20, 0, 0, 198,
- 199, 0, 0, 200, 0, 2, 192, 193, 0, 0,
- 0, 78, 202, 203, 204, 205, 0, 0, 206, 207,
- 194, 0, 0, 0, 0, 0, 195, 0, 0, 0,
- 0, 0, 0, 196, 0, 0, 0, 197, 0, 0,
- 0, 0, 0, 80, 0, 0, 81, 20, 0, 0,
- 0, 0, 0, 0, 345, 0, 0, 0, 0, 0,
- 0, 0, 0, 202, 203, 204, 205, 0, 0, 206,
- 207
+ 0, 0, 0, 0, 0, 0, 277, 0, 0, 0,
+ 0, 0, 0, 0, 0, 204, 205, 206, 207, 0,
+ 0, 208, 209
};
static const short yycheck[] = { 3,
- 132, 123, 6, 62, 264, 201, 0, 427, 129, 1,
- 1, 1, 282, 1, 355, 9, 10, 11, 1, 289,
- 290, 1, 0, 99, 100, 1, 1, 62, 1, 251,
- 89, 9, 10, 11, 134, 94, 30, 374, 42, 33,
- 34, 162, 46, 117, 86, 42, 1, 1, 169, 46,
- 420, 53, 30, 100, 721, 33, 34, 51, 62, 94,
- 64, 1, 362, 94, 101, 69, 97, 64, 62, 369,
- 129, 371, 69, 51, 133, 62, 150, 447, 745, 153,
- 63, 95, 4, 5, 62, 89, 1, 1, 140, 97,
- 94, 67, 1, 101, 129, 97, 196, 171, 97, 1,
- 94, 160, 89, 162, 1, 93, 98, 94, 99, 99,
- 101, 101, 95, 101, 36, 37, 94, 1, 40, 178,
- 95, 101, 1, 650, 128, 129, 99, 162, 50, 133,
- 134, 128, 1, 52, 1, 129, 257, 134, 1, 133,
- 95, 95, 129, 1, 414, 99, 133, 417, 200, 201,
- 1, 129, 572, 1, 94, 525, 160, 79, 162, 686,
- 100, 83, 689, 0, 1, 265, 1, 1, 162, 190,
- 191, 192, 193, 160, 178, 162, 398, 198, 199, 253,
- 1, 95, 1, 98, 162, 555, 190, 191, 192, 193,
- 99, 178, 196, 252, 198, 199, 200, 99, 100, 196,
- 122, 123, 99, 100, 1, 264, 1, 44, 1, 196,
- 551, 581, 1, 200, 98, 94, 94, 139, 55, 251,
- 341, 100, 95, 101, 61, 347, 99, 94, 755, 98,
- 67, 94, 1, 100, 430, 1, 763, 100, 765, 1,
- 767, 99, 1, 94, 1, 1, 298, 251, 252, 100,
- 302, 99, 1, 1, 88, 177, 626, 1, 252, 1,
- 264, 265, 99, 98, 251, 252, 97, 86, 265, 1,
- 264, 100, 15, 1, 9, 327, 1, 264, 99, 616,
- 99, 618, 334, 52, 625, 337, 307, 308, 309, 86,
- 1, 661, 351, 345, 216, 1, 95, 1, 33, 88,
- 95, 94, 99, 307, 308, 309, 310, 311, 312, 313,
- 314, 315, 316, 317, 318, 319, 320, 321, 322, 323,
- 324, 325, 326, 355, 650, 1, 95, 549, 1, 251,
- 362, 1, 319, 99, 671, 94, 98, 369, 708, 371,
- 262, 98, 374, 99, 87, 94, 94, 351, 52, 650,
- 650, 355, 0, 1, 93, 99, 98, 279, 362, 63,
- 686, 413, 94, 689, 351, 369, 398, 371, 355, 650,
- 374, 99, 424, 671, 99, 98, 1, 299, 430, 301,
- 374, 1, 93, 251, 1, 686, 686, 374, 689, 689,
- 63, 95, 98, 1, 398, 655, 44, 67, 1, 736,
- 421, 94, 524, 703, 97, 686, 747, 55, 689, 129,
- 86, 398, 712, 61, 336, 1, 1, 421, 1, 67,
- 757, 343, 95, 427, 1, 347, 1, 75, 1, 755,
- 730, 95, 52, 355, 566, 0, 1, 763, 736, 765,
- 362, 767, 162, 63, 0, 1, 498, 369, 1, 371,
- 1, 99, 584, 96, 755, 755, 508, 100, 510, 757,
- 1, 86, 763, 763, 765, 765, 767, 767, 520, 1,
- 1, 1, 96, 1, 755, 95, 398, 536, 1, 44,
- 601, 1, 763, 86, 765, 93, 767, 355, 44, 541,
- 55, 543, 45, 46, 362, 1, 61, 1, 72, 55,
- 95, 369, 67, 371, 636, 61, 374, 93, 93, 93,
- 93, 67, 86, 86, 646, 92, 93, 549, 93, 551,
- 97, 98, 99, 100, 53, 1, 578, 0, 1, 251,
- 398, 1, 536, 86, 99, 88, 129, 44, 91, 92,
- 93, 100, 93, 99, 97, 549, 50, 551, 101, 536,
- 571, 92, 673, 94, 61, 86, 97, 98, 99, 100,
- 67, 93, 549, 93, 551, 93, 101, 571, 572, 162,
- 93, 44, 65, 93, 50, 0, 1, 1, 82, 72,
- 86, 85, 86, 587, 616, 1, 618, 95, 61, 97,
- 1, 83, 1, 625, 67, 92, 655, 0, 1, 521,
- 97, 98, 524, 724, 95, 96, 82, 177, 99, 85,
- 86, 0, 1, 665, 107, 1, 86, 1, 650, 44,
- 1, 625, 1, 5, 6, 7, 99, 549, 44, 551,
- 122, 123, 414, 355, 50, 417, 61, 1, 625, 671,
- 362, 44, 67, 101, 94, 1, 650, 369, 101, 371,
- 100, 655, 374, 1, 686, 44, 97, 689, 61, 711,
- 1, 655, 86, 715, 67, 717, 82, 1, 655, 85,
- 86, 703, 61, 251, 99, 86, 398, 86, 67, 11,
- 712, 549, 686, 551, 65, 689, 67, 12, 67, 721,
- 1, 72, 262, 72, 5, 76, 99, 76, 730, 703,
- 86, 623, 86, 625, 736, 86, 13, 86, 712, 65,
- 99, 67, 1, 745, 97, 747, 72, 721, 101, 1,
- 76, 1, 86, 755, 1, 757, 730, 14, 650, 1,
- 86, 763, 99, 765, 721, 767, 251, 64, 86, 97,
- 60, 745, 69, 747, 64, 86, 45, 46, 616, 96,
- 618, 755, 86, 99, 100, 45, 46, 625, 745, 763,
- 747, 765, 95, 767, 686, 93, 1, 689, 9, 97,
- 11, 93, 44, 101, 44, 86, 93, 355, 50, 47,
- 50, 703, 650, 99, 362, 47, 686, 99, 1, 689,
- 712, 369, 33, 371, 62, 99, 374, 86, 97, 721,
- 62, 128, 101, 671, 86, 129, 86, 97, 730, 86,
- 82, 101, 82, 85, 86, 85, 86, 1, 686, 251,
- 398, 689, 94, 745, 94, 747, 99, 549, 96, 551,
- 99, 44, 93, 755, 96, 703, 160, 50, 162, 94,
- 355, 763, 97, 765, 712, 767, 101, 362, 315, 316,
- 317, 318, 94, 721, 369, 755, 371, 251, 100, 374,
- 91, 92, 730, 763, 93, 765, 50, 767, 736, 82,
- 44, 88, 85, 86, 94, 59, 50, 745, 94, 747,
- 100, 65, 100, 398, 100, 94, 66, 755, 72, 757,
- 10, 100, 76, 67, 616, 763, 618, 765, 82, 767,
- 99, 85, 86, 625, 93, 89, 90, 94, 82, 93,
- 30, 85, 86, 100, 34, 416, 1, 418, 102, 103,
- 104, 105, 97, 355, 108, 109, 91, 92, 650, 86,
- 362, 51, 45, 46, 91, 92, 93, 369, 94, 371,
- 97, 1, 374, 93, 101, 251, 44, 3, 4, 671,
- 16, 17, 50, 99, 18, 19, 20, 21, 94, 44,
- 94, 355, 91, 92, 686, 50, 398, 689, 362, 97,
- 98, 549, 1, 551, 59, 369, 61, 371, 94, 44,
- 374, 703, 67, 100, 82, 50, 56, 85, 86, 56,
- 712, 45, 46, 57, 59, 99, 61, 82, 94, 721,
- 85, 86, 67, 94, 398, 91, 92, 93, 730, 45,
- 46, 97, 310, 311, 736, 101, 1, 82, 320, 321,
- 85, 86, 94, 745, 1, 747, 8, 9, 10, 56,
- 95, 96, 94, 755, 549, 757, 551, 0, 616, 94,
- 618, 763, 99, 765, 44, 767, 99, 625, 94, 355,
- 50, 0, 91, 92, 93, 319, 362, 11, 97, 59,
- 54, 61, 101, 369, 44, 371, 139, 67, 374, 86,
- 50, 75, 650, 162, 91, 92, 93, 160, 393, 59,
- 97, 61, 82, 252, 101, 85, 86, 67, 97, 98,
- 99, 52, 398, 671, 282, 95, 96, 398, 44, 94,
- 374, 616, 82, 618, 50, 85, 86, 719, 686, 719,
- 625, 689, 602, 59, 374, 61, 96, 549, 602, 551,
- 322, 67, 86, 323, 325, 703, 324, 91, 92, 93,
- 312, 313, 314, 97, 712, 650, 82, 101, 587, 85,
- 86, 326, -1, 721, 330, -1, -1, -1, -1, -1,
- 96, -1, 730, -1, -1, 549, 671, 551, 736, -1,
- 91, 92, 93, -1, -1, -1, 97, 745, -1, 747,
- 101, 686, -1, -1, 689, -1, -1, 755, -1, 757,
- -1, -1, -1, -1, 616, 763, 618, 765, 703, 767,
- -1, -1, -1, 625, -1, -1, -1, 712, -1, -1,
- -1, -1, -1, -1, -1, -1, 721, -1, -1, -1,
- -1, -1, -1, -1, -1, 730, -1, -1, 650, -1,
- -1, 736, 616, -1, 618, -1, -1, -1, -1, 50,
- 745, 625, 747, -1, -1, -1, -1, -1, 59, 671,
- 755, -1, 757, 549, 65, 551, -1, -1, 763, -1,
- 765, 72, 767, -1, 686, 76, 650, 689, -1, -1,
- -1, 82, -1, -1, 85, 86, -1, -1, 89, 90,
- -1, 703, 93, -1, -1, -1, -1, 671, -1, -1,
- 712, 102, 103, 104, 105, -1, -1, 108, 109, 721,
- -1, -1, 686, -1, -1, 689, -1, -1, 730, -1,
- -1, -1, -1, -1, 736, -1, -1, -1, -1, 703,
- 616, -1, 618, 745, -1, 747, -1, -1, 712, 625,
- -1, -1, -1, 755, -1, 757, -1, 721, -1, -1,
- -1, 763, -1, 765, -1, 767, 730, -1, -1, -1,
- -1, -1, 736, -1, 650, -1, 190, 191, 192, 193,
- -1, 745, -1, 747, 198, 199, -1, -1, -1, -1,
- -1, 755, -1, 757, -1, 671, -1, -1, -1, 763,
- -1, 765, -1, 767, -1, -1, 190, 191, 192, 193,
- 686, -1, -1, 689, 198, 199, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, 703, -1, -1,
- -1, -1, -1, -1, -1, -1, 712, -1, -1, -1,
- -1, -1, -1, -1, -1, 721, -1, -1, -1, -1,
- -1, -1, -1, -1, 730, -1, -1, -1, -1, -1,
- 736, -1, -1, -1, -1, -1, -1, -1, -1, 745,
- -1, 747, -1, -1, -1, -1, -1, -1, -1, 755,
- -1, 757, -1, -1, -1, -1, -1, 763, -1, 765,
- -1, 767, -1, 307, 308, 309, 310, 311, 312, 313,
- 314, 315, 316, 317, 318, -1, 320, 321, 322, 323,
- 324, 325, 326, -1, 1, -1, -1, -1, -1, -1,
- -1, -1, -1, 307, 308, 309, 310, 311, 312, 313,
- 314, 315, 316, 317, 318, -1, 320, 321, 322, 323,
- 324, 325, 326, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, 44, 45, 46,
+ 132, 403, 6, 287, 307, 123, 328, 42, 62, 175,
+ 203, 46, 134, 294, 483, 179, 0, 83, 117, 1,
+ 62, 302, 129, 304, 86, 9, 10, 11, 1, 64,
+ 1, 1, 663, 1, 69, 89, 62, 1, 42, 655,
+ 94, 97, 46, 1, 95, 101, 30, 1, 634, 33,
+ 34, 150, 94, 1, 153, 162, 122, 123, 62, 1,
+ 64, 1, 169, 89, 94, 69, 1, 51, 94, 1,
+ 100, 129, 100, 172, 1, 129, 198, 1, 62, 133,
+ 192, 193, 194, 195, 346, 89, 1, 129, 200, 201,
+ 94, 353, 354, 128, 1, 1, 67, 67, 101, 134,
+ 716, 72, 1, 129, 162, 76, 160, 133, 162, 695,
+ 94, 175, 698, 1, 1, 86, 1, 99, 435, 101,
+ 162, 175, 1, 754, 128, 129, 180, 1, 101, 133,
+ 134, 99, 763, 101, 160, 99, 162, 4, 5, 93,
+ 98, 634, 1, 612, 198, 129, 86, 101, 202, 133,
+ 552, 99, 259, 555, 180, 254, 160, 99, 162, 476,
+ 1, 279, 326, 198, 99, 100, 273, 99, 100, 36,
+ 37, 175, 99, 40, 98, 761, 180, 1, 162, 94,
+ 766, 52, 768, 50, 770, 502, 634, 94, 192, 193,
+ 194, 195, 98, 100, 198, 94, 200, 201, 202, 253,
+ 634, 100, 695, 1, 140, 698, 93, 329, 470, 94,
+ 98, 473, 79, 92, 93, 100, 83, 1, 97, 98,
+ 99, 100, 63, 287, 1, 99, 95, 253, 630, 283,
+ 294, 47, 1, 287, 1, 94, 47, 403, 302, 1,
+ 304, 100, 1, 307, 0, 1, 62, 695, 1, 253,
+ 698, 62, 97, 307, 95, 122, 123, 283, 370, 371,
+ 372, 695, 1, 1, 698, 1, 202, 203, 761, 253,
+ 94, 555, 139, 766, 328, 768, 100, 770, 595, 283,
+ 96, 94, 15, 287, 587, 96, 589, 100, 44, 1,
+ 294, 1, 485, 97, 329, 1, 1, 95, 302, 55,
+ 304, 99, 328, 307, 621, 61, 1, 1, 175, 1,
+ 1, 67, 179, 761, 631, 99, 434, 639, 766, 1,
+ 768, 98, 770, 307, 328, 329, 95, 761, 382, 646,
+ 266, 98, 766, 269, 768, 100, 770, 99, 1, 403,
+ 99, 277, 1, 99, 328, 98, 630, 52, 86, 403,
+ 1, 218, 1, 634, 87, 1, 1, 98, 63, 98,
+ 663, 99, 98, 45, 46, 477, 370, 371, 372, 373,
+ 374, 375, 376, 377, 378, 379, 380, 381, 382, 383,
+ 384, 385, 386, 387, 388, 389, 552, 99, 94, 99,
+ 95, 1, 86, 52, 448, 86, 1, 175, 93, 403,
+ 63, 268, 1, 95, 86, 99, 88, 52, 275, 91,
+ 92, 93, 279, 730, 695, 97, 1, 698, 63, 101,
+ 287, 1, 448, 1, 1, 361, 1, 294, 175, 365,
+ 1, 53, 95, 129, 718, 302, 95, 304, 1, 1,
+ 721, 92, 88, 94, 448, 94, 97, 98, 99, 100,
+ 95, 754, 94, 734, 390, 97, 1, 9, 1, 326,
+ 763, 1, 569, 93, 44, 572, 162, 748, 1, 1,
+ 50, 1, 408, 477, 606, 97, 343, 1, 1, 483,
+ 761, 33, 418, 93, 420, 766, 1, 768, 552, 770,
+ 95, 555, 624, 65, 430, 362, 95, 364, 552, 611,
+ 72, 555, 82, 1, 1, 85, 86, 5, 93, 287,
+ 1, 88, 0, 1, 94, 93, 294, 453, 93, 455,
+ 1, 1, 93, 587, 302, 589, 304, 91, 92, 307,
+ 1, 94, 94, 469, 67, 107, 403, 0, 1, 1,
+ 287, 86, 674, 94, 480, 72, 97, 294, 552, 485,
+ 93, 555, 684, 93, 175, 302, 44, 304, 665, 86,
+ 307, 93, 1, 93, 431, 1, 630, 434, 1, 93,
+ 634, 86, 470, 61, 1, 473, 630, 0, 1, 67,
+ 1, 44, 1, 1, 95, 639, 97, 94, 86, 86,
+ 1, 655, 55, 1, 101, 86, 95, 96, 61, 663,
+ 99, 655, 0, 1, 67, 86, 86, 611, 612, 0,
+ 44, 99, 75, 639, 96, 86, 175, 95, 9, 10,
+ 11, 44, 1, 627, 86, 403, 630, 61, 0, 1,
+ 634, 695, 55, 67, 698, 639, 99, 93, 61, 30,
+ 93, 97, 33, 34, 67, 101, 44, 86, 99, 100,
+ 86, 655, 716, 86, 718, 639, 403, 721, 695, 86,
+ 51, 698, 716, 61, 718, 86, 287, 86, 86, 67,
+ 734, 62, 44, 294, 99, 86, 99, 53, 86, 0,
+ 1, 302, 618, 304, 748, 552, 307, 100, 555, 61,
+ 754, 695, 0, 1, 698, 67, 95, 761, 10, 763,
+ 1, 99, 766, 94, 768, 175, 770, 86, 64, 101,
+ 94, 1, 716, 69, 718, 651, 100, 721, 30, 1,
+ 94, 657, 34, 44, 761, 129, 100, 99, 287, 766,
+ 734, 768, 101, 770, 55, 294, 44, 1, 129, 51,
+ 61, 94, 101, 302, 748, 304, 67, 100, 307, 50,
+ 45, 46, 97, 61, 44, 11, 160, 761, 162, 67,
+ 50, 628, 766, 630, 768, 95, 770, 634, 50, 99,
+ 13, 162, 128, 12, 552, 1, 94, 555, 99, 97,
+ 44, 82, 403, 101, 85, 86, 50, 1, 655, 96,
+ 14, 99, 82, 100, 175, 85, 86, 733, 95, 1,
+ 82, 737, 97, 85, 86, 552, 101, 92, 555, 587,
+ 99, 589, 97, 98, 9, 93, 11, 287, 82, 94,
+ 93, 85, 86, 99, 294, 100, 45, 46, 695, 97,
+ 44, 698, 302, 101, 304, 97, 50, 307, 33, 65,
+ 587, 67, 589, 100, 403, 59, 72, 61, 95, 716,
+ 76, 718, 630, 67, 721, 60, 634, 99, 100, 64,
+ 86, 91, 92, 65, 472, 67, 474, 734, 82, 66,
+ 72, 85, 86, 44, 76, 45, 46, 655, 97, 50,
+ 1, 748, 101, 630, 86, 663, 99, 634, 59, 99,
+ 61, 5, 6, 7, 761, 99, 67, 3, 4, 766,
+ 93, 768, 93, 770, 16, 17, 287, 88, 655, 91,
+ 92, 82, 44, 294, 85, 86, 663, 695, 50, 93,
+ 698, 302, 94, 304, 175, 96, 307, 59, 1, 61,
+ 93, 552, 99, 403, 555, 67, 45, 46, 716, 44,
+ 718, 45, 46, 721, 94, 50, 97, 98, 695, 94,
+ 82, 698, 1, 85, 86, 97, 734, 8, 9, 10,
+ 94, 44, 100, 95, 96, 56, 587, 50, 589, 716,
+ 748, 718, 373, 374, 721, 56, 754, 82, 383, 384,
+ 85, 86, 99, 761, 67, 763, 94, 734, 766, 94,
+ 768, 44, 770, 552, 94, 1, 555, 50, 94, 82,
+ 94, 748, 85, 86, 97, 98, 99, 754, 1, 630,
+ 375, 376, 377, 634, 761, 99, 763, 99, 94, 766,
+ 56, 768, 403, 770, 18, 19, 20, 21, 587, 82,
+ 589, 44, 85, 86, 655, 94, 287, 50, 0, 91,
+ 92, 93, 663, 294, 0, 97, 59, 382, 61, 101,
+ 11, 302, 54, 304, 67, 75, 307, 253, 378, 379,
+ 380, 381, 139, 57, 44, 162, 403, 52, 160, 82,
+ 50, 630, 85, 86, 695, 634, 94, 698, 261, 59,
+ 307, 61, 552, 96, 653, 555, 653, 67, 91, 92,
+ 93, 307, 346, 570, 97, 716, 655, 718, 101, 385,
+ 721, 570, 82, 86, 663, 85, 86, 386, 91, 92,
+ 93, 388, 393, 734, 97, 95, 96, 587, 101, 589,
+ 387, 627, -1, 86, 389, -1, -1, 748, 91, 92,
+ 93, -1, -1, 754, 97, -1, 695, -1, 101, 698,
+ 761, -1, 763, -1, -1, 766, -1, 768, -1, 770,
+ -1, -1, 403, -1, -1, -1, -1, 716, -1, 718,
+ 630, 86, 721, -1, 634, -1, 91, 92, 93, -1,
+ -1, 552, 97, -1, 555, 734, 101, 91, 92, 93,
+ -1, -1, -1, 97, -1, 655, -1, 101, -1, 748,
+ -1, -1, -1, 663, -1, 754, -1, -1, -1, -1,
+ -1, -1, 761, -1, 763, -1, 587, 766, 589, 768,
+ -1, 770, -1, -1, 192, 193, 194, 195, -1, -1,
+ -1, -1, 200, 201, -1, 695, -1, -1, 698, -1,
+ -1, -1, -1, -1, -1, 192, 193, 194, 195, -1,
+ -1, -1, -1, 200, 201, -1, 716, -1, 718, 630,
+ -1, 721, -1, 634, -1, -1, -1, -1, 1, -1,
+ 3, 4, -1, -1, 734, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 655, -1, -1, -1, 748, -1,
+ -1, -1, 663, -1, 754, -1, -1, -1, -1, -1,
+ -1, 761, -1, 763, -1, -1, 766, -1, 768, -1,
+ 770, 552, 45, 46, 555, -1, -1, 50, -1, -1,
+ -1, -1, -1, -1, 695, -1, 59, 698, -1, -1,
+ -1, -1, 65, -1, -1, -1, -1, -1, -1, 72,
+ -1, -1, -1, 76, -1, 716, 587, 718, 589, 82,
+ 721, -1, 85, 86, -1, -1, 89, 90, -1, -1,
+ 93, -1, 95, 734, -1, -1, -1, -1, -1, 102,
+ 103, 104, 105, -1, -1, 108, 109, 748, -1, -1,
+ -1, -1, -1, 754, -1, -1, -1, -1, -1, 630,
+ 761, -1, 763, 634, -1, 766, -1, 768, 1, 770,
+ -1, -1, 370, 371, 372, 373, 374, 375, 376, 377,
+ 378, 379, 380, 381, 655, 383, 384, 385, 386, 387,
+ 388, 389, 663, 370, 371, 372, 373, 374, 375, 376,
+ 377, 378, 379, 380, 381, -1, 383, 384, 385, 386,
+ 387, 388, 389, -1, -1, -1, -1, 50, -1, -1,
+ -1, -1, -1, -1, 695, -1, 59, 698, -1, -1,
+ -1, -1, 65, -1, -1, -1, -1, -1, -1, 72,
+ -1, -1, -1, 76, -1, 716, -1, 718, -1, 82,
+ 721, -1, 85, 86, -1, -1, 89, 90, -1, -1,
+ 93, -1, -1, 734, 1, -1, -1, -1, -1, 102,
+ 103, 104, 105, -1, -1, 108, 109, 748, -1, 477,
+ -1, -1, -1, 754, -1, 483, -1, -1, -1, -1,
+ 761, -1, 763, -1, -1, 766, -1, 768, -1, 770,
+ 477, -1, -1, -1, -1, -1, 483, 44, 45, 46,
47, 48, 49, 50, 51, -1, -1, 54, -1, -1,
-1, 58, 59, -1, -1, 62, -1, -1, 65, 66,
- 67, 68, -1, 70, 71, 72, 73, -1, -1, 76,
+ 67, 68, -1, 70, 71, 72, 73, -1, 50, 76,
+ -1, -1, -1, -1, -1, 82, -1, 59, 85, 86,
+ -1, -1, -1, 65, -1, -1, 93, -1, 95, 96,
+ 72, -1, 99, -1, 76, 102, 103, 104, 105, -1,
+ 82, 108, 109, 85, 86, -1, -1, 89, 90, -1,
+ -1, 93, -1, -1, -1, -1, -1, -1, -1, -1,
+ 102, 103, 104, 105, 1, -1, 108, 109, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 611, 612, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, 627,
+ -1, -1, -1, -1, 611, 612, -1, 44, 45, 46,
+ 47, 48, 49, 50, 51, -1, -1, 54, -1, -1,
+ 627, 58, 59, -1, -1, 62, -1, -1, 65, 66,
+ 67, 68, 1, 70, 71, 72, 73, -1, -1, 76,
-1, -1, -1, -1, -1, 82, -1, -1, 85, 86,
- -1, 1, -1, -1, -1, -1, 93, 421, 95, 96,
- -1, -1, 99, 427, -1, 102, 103, 104, 105, -1,
- -1, 108, 109, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, 421, -1, -1,
- -1, -1, -1, 427, 44, 45, 46, 47, 48, 49,
- 50, 51, -1, -1, 54, -1, -1, -1, 58, 59,
- -1, -1, 62, -1, -1, 65, 66, 67, 68, -1,
- 70, 71, 72, 73, -1, 1, 76, 3, 4, -1,
- -1, -1, 82, -1, -1, 85, 86, -1, -1, -1,
- -1, -1, -1, 93, -1, 95, 96, -1, -1, 99,
- -1, -1, 102, 103, 104, 105, -1, -1, 108, 109,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, 45,
- 46, -1, -1, -1, 50, -1, -1, -1, -1, -1,
- -1, -1, -1, 59, -1, -1, -1, -1, -1, 65,
- -1, -1, -1, -1, -1, -1, 72, 1, -1, -1,
- 76, -1, -1, -1, -1, -1, 82, 571, 572, 85,
- 86, -1, -1, 89, 90, -1, -1, 93, -1, 95,
- 96, -1, -1, 587, -1, -1, 102, 103, 104, 105,
- -1, -1, 108, 109, -1, -1, -1, 571, 572, -1,
- 44, 45, 46, 47, 48, 49, 50, 51, -1, -1,
- 54, -1, -1, 587, 58, 59, -1, -1, 62, -1,
- -1, 65, 66, 67, 68, 1, 70, 71, 72, 73,
- -1, -1, 76, -1, -1, -1, -1, -1, 82, -1,
- -1, 85, 86, -1, -1, -1, -1, -1, -1, 93,
- -1, 95, 96, -1, -1, 99, -1, -1, 102, 103,
- 104, 105, -1, -1, 108, 109, -1, -1, 44, 45,
- 46, -1, 48, 49, 50, 51, -1, -1, 54, -1,
- -1, -1, 58, 59, -1, -1, -1, -1, -1, 65,
- 66, 67, 68, 1, 70, 71, 72, 73, -1, -1,
- 76, -1, -1, -1, -1, -1, 82, -1, -1, 85,
- 86, -1, -1, -1, -1, -1, -1, 93, -1, 95,
- 96, -1, -1, 99, -1, -1, 102, 103, 104, 105,
- -1, -1, 108, 109, -1, -1, 44, 45, 46, -1,
- 48, 49, 50, 51, -1, -1, 54, -1, -1, -1,
- 58, 59, -1, -1, -1, -1, -1, 65, 66, 67,
- 68, 1, 70, 71, 72, 73, -1, -1, 76, -1,
- -1, -1, -1, -1, 82, -1, -1, 85, 86, -1,
- -1, -1, -1, -1, -1, 93, -1, 95, 96, -1,
- -1, 99, -1, -1, 102, 103, 104, 105, -1, -1,
- 108, 109, -1, -1, 44, 45, 46, -1, 48, 49,
- 50, 51, -1, -1, 54, -1, -1, -1, 58, 59,
- -1, -1, -1, -1, -1, 65, 66, 67, 68, 1,
- 70, 71, 72, 73, -1, -1, 76, -1, -1, -1,
- -1, -1, 82, -1, -1, 85, 86, -1, -1, -1,
- -1, -1, -1, 93, -1, 95, 96, -1, -1, 99,
- -1, -1, 102, 103, 104, 105, -1, -1, 108, 109,
- -1, -1, 44, 45, 46, -1, 48, 49, 50, 51,
- -1, -1, 54, -1, -1, -1, 58, 59, -1, -1,
- -1, -1, -1, 65, 66, 67, 68, 1, 70, 71,
- 72, 73, -1, -1, 76, -1, -1, -1, -1, -1,
- 82, -1, -1, 85, 86, -1, -1, -1, -1, -1,
- -1, 93, -1, 95, 96, -1, -1, 99, -1, -1,
- 102, 103, 104, 105, -1, -1, 108, 109, -1, -1,
- 44, 45, 46, -1, 48, 49, 50, 51, -1, -1,
- 54, -1, -1, -1, 58, 59, -1, -1, -1, -1,
- -1, 65, 66, 67, 68, 1, 70, 71, 72, 73,
+ -1, -1, -1, -1, -1, -1, 93, -1, 95, 96,
+ -1, -1, 99, -1, -1, 102, 103, 104, 105, -1,
+ -1, 108, 109, -1, -1, 44, 45, 46, 47, 48,
+ 49, 50, 51, -1, -1, 54, -1, -1, -1, 58,
+ 59, -1, -1, 62, -1, -1, 65, 66, 67, 68,
+ 1, 70, 71, 72, 73, -1, -1, 76, -1, -1,
+ -1, -1, -1, 82, -1, -1, 85, 86, -1, -1,
+ -1, -1, -1, -1, 93, -1, 95, 96, -1, -1,
+ 99, -1, -1, 102, 103, 104, 105, -1, -1, 108,
+ 109, -1, -1, 44, 45, 46, -1, 48, 49, 50,
+ 51, -1, -1, 54, -1, -1, -1, 58, 59, -1,
+ -1, -1, -1, -1, 65, 66, 67, 68, 1, 70,
+ 71, 72, 73, -1, -1, 76, -1, -1, -1, -1,
+ -1, 82, -1, -1, 85, 86, -1, -1, -1, -1,
+ -1, -1, 93, -1, 95, 96, -1, -1, 99, -1,
+ -1, 102, 103, 104, 105, -1, -1, 108, 109, -1,
+ -1, 44, 45, 46, -1, 48, 49, 50, 51, -1,
+ -1, 54, -1, -1, -1, 58, 59, -1, -1, -1,
+ -1, -1, 65, 66, 67, 68, 1, 70, 71, 72,
+ 73, -1, -1, 76, -1, -1, -1, -1, -1, 82,
+ -1, -1, 85, 86, -1, -1, -1, -1, -1, -1,
+ 93, -1, 95, -1, -1, -1, 99, -1, -1, 102,
+ 103, 104, 105, -1, -1, 108, 109, -1, -1, 44,
+ 45, 46, -1, 48, 49, 50, 51, -1, -1, 54,
+ -1, -1, -1, 58, 59, -1, -1, -1, -1, -1,
+ 65, 66, 1, 68, -1, 70, 71, 72, 73, -1,
+ -1, 76, -1, -1, -1, -1, -1, 82, -1, -1,
+ 85, 86, -1, -1, -1, -1, -1, -1, 93, -1,
+ 95, -1, -1, -1, 99, -1, -1, 102, 103, 104,
+ 105, -1, -1, 108, 109, 44, 45, 46, -1, 48,
+ 49, 50, 51, -1, -1, 54, -1, -1, -1, 58,
+ 59, -1, -1, -1, -1, -1, 65, 66, -1, 68,
+ -1, 70, 71, 72, 73, -1, 1, 76, 3, 4,
+ -1, -1, -1, 82, -1, -1, 85, 86, -1, -1,
+ -1, -1, -1, -1, 93, -1, 95, -1, -1, -1,
+ 99, -1, -1, 102, 103, 104, 105, -1, -1, 108,
+ 109, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 45, 46, -1, -1, -1, 50, -1, -1, -1, -1,
+ -1, -1, -1, -1, 59, -1, -1, -1, -1, -1,
+ 65, 1, -1, 3, 4, -1, -1, 72, -1, -1,
+ -1, 76, -1, -1, -1, -1, -1, 82, -1, -1,
+ 85, 86, -1, -1, 89, 90, -1, -1, 93, -1,
+ 95, 96, -1, -1, -1, -1, -1, 102, 103, 104,
+ 105, -1, -1, 108, 109, 45, 46, -1, -1, -1,
+ 50, -1, 1, -1, 3, 4, -1, -1, -1, 59,
+ -1, -1, -1, -1, -1, 65, -1, -1, -1, -1,
+ -1, -1, 72, -1, -1, -1, 76, -1, -1, -1,
+ -1, -1, 82, -1, -1, 85, 86, -1, -1, 89,
+ 90, -1, -1, 93, -1, -1, 45, 46, -1, 99,
+ -1, 50, 102, 103, 104, 105, -1, -1, 108, 109,
+ 59, -1, -1, -1, -1, -1, 65, 1, -1, 3,
+ 4, -1, -1, 72, -1, -1, -1, 76, -1, -1,
+ -1, -1, -1, 82, -1, -1, 85, 86, -1, 88,
+ 89, 90, -1, -1, 93, -1, -1, -1, -1, -1,
+ -1, -1, -1, 102, 103, 104, 105, -1, -1, 108,
+ 109, 45, 46, -1, -1, -1, 50, -1, 1, -1,
+ 3, 4, -1, -1, -1, 59, -1, -1, -1, -1,
+ -1, 65, -1, -1, -1, -1, -1, -1, 72, -1,
-1, -1, 76, -1, -1, -1, -1, -1, 82, -1,
- -1, 85, 86, -1, -1, -1, -1, -1, -1, 93,
- -1, 95, 96, -1, -1, 99, -1, -1, 102, 103,
- 104, 105, -1, -1, 108, 109, -1, -1, 44, 45,
- 46, -1, 48, 49, 50, 51, -1, -1, 54, -1,
- -1, -1, 58, 59, -1, -1, -1, -1, -1, 65,
- 66, 67, 68, 1, 70, 71, 72, 73, -1, -1,
- 76, -1, -1, -1, -1, -1, 82, -1, -1, 85,
- 86, -1, -1, -1, -1, -1, -1, 93, -1, 95,
- -1, -1, -1, 99, -1, -1, 102, 103, 104, 105,
- -1, -1, 108, 109, -1, -1, 44, 45, 46, -1,
- 48, 49, 50, 51, -1, -1, 54, -1, -1, -1,
- 58, 59, -1, -1, -1, -1, -1, 65, 66, 1,
- 68, -1, 70, 71, 72, 73, -1, -1, 76, -1,
- -1, -1, -1, -1, 82, -1, -1, 85, 86, -1,
- -1, -1, -1, -1, -1, 93, -1, 95, -1, -1,
- -1, 99, -1, -1, 102, 103, 104, 105, -1, -1,
- 108, 109, 44, 45, 46, -1, 48, 49, 50, 51,
- -1, -1, 54, -1, -1, -1, 58, 59, -1, -1,
- -1, -1, -1, 65, 66, -1, 68, -1, 70, 71,
- 72, 73, -1, 1, 76, 3, 4, -1, -1, -1,
- 82, -1, -1, 85, 86, -1, -1, -1, -1, -1,
- -1, 93, -1, 95, -1, -1, -1, 99, -1, -1,
- 102, 103, 104, 105, -1, -1, 108, 109, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, 45, 46, -1,
+ -1, 85, 86, -1, -1, 89, 90, -1, -1, 93,
+ -1, -1, 45, 46, 98, -1, -1, 50, 102, 103,
+ 104, 105, -1, -1, 108, 109, 59, -1, -1, -1,
+ -1, -1, 65, 1, -1, 3, 4, -1, -1, 72,
+ -1, -1, -1, 76, -1, -1, -1, -1, -1, 82,
+ -1, -1, 85, 86, -1, -1, 89, 90, -1, -1,
+ 93, 94, -1, -1, -1, -1, -1, -1, -1, 102,
+ 103, 104, 105, -1, -1, 108, 109, 45, 46, -1,
-1, -1, 50, -1, 1, -1, 3, 4, -1, -1,
-1, 59, -1, -1, -1, -1, -1, 65, -1, -1,
-1, -1, -1, -1, 72, -1, -1, -1, 76, -1,
-1, -1, -1, -1, 82, -1, -1, 85, 86, -1,
- -1, 89, 90, -1, -1, 93, -1, 95, 45, 46,
- -1, -1, -1, 50, 102, 103, 104, 105, -1, -1,
+ -1, 89, 90, -1, -1, 93, -1, -1, 45, 46,
+ -1, 99, -1, 50, 102, 103, 104, 105, -1, -1,
108, 109, 59, -1, -1, -1, -1, -1, 65, 1,
-1, 3, 4, -1, -1, 72, -1, -1, -1, 76,
-1, -1, -1, -1, -1, 82, -1, -1, 85, 86,
- -1, 88, 89, 90, -1, -1, 93, -1, -1, -1,
- -1, -1, -1, -1, -1, 102, 103, 104, 105, -1,
+ -1, -1, 89, 90, -1, -1, 93, -1, -1, -1,
+ -1, 98, -1, -1, -1, 102, 103, 104, 105, -1,
-1, 108, 109, 45, 46, -1, -1, -1, 50, -1,
1, -1, 3, 4, -1, -1, -1, 59, -1, -1,
-1, -1, -1, 65, -1, -1, -1, -1, -1, -1,
72, -1, -1, -1, 76, -1, -1, -1, -1, -1,
82, -1, -1, 85, 86, -1, -1, 89, 90, -1,
- -1, 93, -1, -1, 45, 46, -1, 99, -1, 50,
+ -1, 93, 94, -1, 45, 46, -1, -1, -1, 50,
102, 103, 104, 105, -1, -1, 108, 109, 59, -1,
-1, -1, -1, -1, 65, 1, -1, 3, 4, -1,
-1, 72, -1, -1, -1, 76, -1, -1, -1, -1,
@@ -1760,49 +1931,49 @@ static const short yycheck[] = { 3,
-1, -1, 108, 109, 59, -1, -1, -1, -1, -1,
65, 1, -1, 3, 4, -1, -1, 72, -1, -1,
-1, 76, -1, -1, -1, -1, -1, 82, -1, -1,
- 85, 86, -1, -1, 89, 90, -1, -1, 93, -1,
- -1, -1, -1, 98, -1, -1, -1, 102, 103, 104,
+ 85, 86, -1, -1, 89, 90, -1, -1, 93, 94,
+ -1, -1, -1, -1, -1, -1, -1, 102, 103, 104,
105, -1, -1, 108, 109, 45, 46, -1, -1, -1,
50, -1, 1, -1, 3, 4, -1, -1, -1, 59,
-1, -1, -1, -1, -1, 65, -1, -1, -1, -1,
-1, -1, 72, -1, -1, -1, 76, -1, -1, -1,
-1, -1, 82, -1, -1, 85, 86, -1, -1, 89,
- 90, -1, -1, 93, -1, -1, 45, 46, 98, -1,
+ 90, -1, -1, 93, 94, -1, 45, 46, -1, -1,
-1, 50, 102, 103, 104, 105, -1, -1, 108, 109,
59, -1, -1, -1, -1, -1, 65, 1, -1, 3,
4, -1, -1, 72, -1, -1, -1, 76, -1, -1,
-1, -1, -1, 82, -1, -1, 85, 86, -1, -1,
- 89, 90, -1, -1, 93, 94, -1, -1, -1, -1,
- -1, -1, -1, 102, 103, 104, 105, -1, -1, 108,
+ 89, 90, -1, -1, 93, -1, -1, -1, -1, -1,
+ 99, -1, -1, 102, 103, 104, 105, -1, -1, 108,
109, 45, 46, -1, -1, -1, 50, -1, 1, -1,
3, 4, -1, -1, -1, 59, -1, -1, -1, -1,
-1, 65, -1, -1, -1, -1, -1, -1, 72, -1,
-1, -1, 76, -1, -1, -1, -1, -1, 82, -1,
-1, 85, 86, -1, -1, 89, 90, -1, -1, 93,
- -1, -1, 45, 46, -1, 99, -1, 50, 102, 103,
+ -1, -1, 45, 46, -1, -1, -1, 50, 102, 103,
104, 105, -1, -1, 108, 109, 59, -1, -1, -1,
-1, -1, 65, 1, -1, 3, 4, -1, -1, 72,
-1, -1, -1, 76, -1, -1, -1, -1, -1, 82,
-1, -1, 85, 86, -1, -1, 89, 90, -1, -1,
- 93, 94, -1, -1, -1, -1, -1, -1, -1, 102,
+ 93, -1, -1, -1, -1, -1, -1, -1, -1, 102,
103, 104, 105, -1, -1, 108, 109, 45, 46, -1,
-1, -1, 50, -1, 1, -1, 3, 4, -1, -1,
-1, 59, -1, -1, -1, -1, -1, 65, -1, -1,
-1, -1, -1, -1, 72, -1, -1, -1, 76, -1,
-1, -1, -1, -1, 82, -1, -1, 85, 86, -1,
- -1, 89, 90, -1, -1, 93, 94, -1, 45, 46,
+ -1, 89, 90, -1, -1, 93, -1, -1, 45, 46,
-1, -1, -1, 50, 102, 103, 104, 105, -1, -1,
108, 109, 59, -1, -1, -1, -1, -1, 65, 1,
-1, 3, 4, -1, -1, 72, -1, -1, -1, 76,
-1, -1, -1, -1, -1, 82, -1, -1, 85, 86,
- -1, -1, 89, 90, -1, -1, 93, 94, -1, -1,
+ -1, -1, 89, 90, -1, -1, 93, -1, -1, -1,
-1, -1, -1, -1, -1, 102, 103, 104, 105, -1,
-1, 108, 109, 45, 46, -1, -1, -1, 50, -1,
1, -1, 3, 4, -1, -1, -1, 59, -1, -1,
-1, -1, -1, 65, -1, -1, -1, -1, -1, -1,
72, -1, -1, -1, 76, -1, -1, -1, -1, -1,
82, -1, -1, 85, 86, -1, -1, 89, 90, -1,
- -1, 93, -1, -1, 45, 46, -1, 99, -1, 50,
+ -1, 93, -1, -1, 45, 46, -1, -1, -1, 50,
102, 103, 104, 105, -1, -1, 108, 109, 59, -1,
-1, -1, -1, -1, 65, 1, -1, 3, 4, -1,
-1, 72, -1, -1, -1, 76, -1, -1, -1, -1,
@@ -1995,97 +2166,67 @@ static const short yycheck[] = { 3,
85, 86, -1, -1, 89, 90, -1, -1, 93, -1,
-1, -1, -1, -1, -1, -1, -1, 102, 103, 104,
105, -1, -1, 108, 109, 45, 46, -1, -1, -1,
- 50, -1, 1, -1, 3, 4, -1, -1, -1, 59,
+ 50, -1, 1, -1, -1, -1, -1, -1, -1, 59,
-1, -1, -1, -1, -1, 65, -1, -1, -1, -1,
- -1, -1, 72, -1, -1, -1, 76, -1, -1, -1,
+ -1, -1, 72, -1, -1, -1, 76, 1, -1, -1,
-1, -1, 82, -1, -1, 85, 86, -1, -1, 89,
- 90, -1, -1, 93, -1, -1, 45, 46, -1, -1,
+ 90, -1, -1, 93, -1, 44, 45, 46, -1, -1,
-1, 50, 102, 103, 104, 105, -1, -1, 108, 109,
- 59, -1, -1, -1, -1, -1, 65, 1, -1, 3,
+ 59, -1, -1, -1, -1, -1, 65, -1, -1, 1,
+ -1, 45, 46, 72, -1, -1, 50, 76, -1, -1,
+ -1, -1, -1, 82, -1, 59, 85, 86, -1, -1,
+ -1, 65, -1, -1, 93, -1, 3, 4, 72, -1,
+ 99, -1, 76, 102, 103, 104, 105, -1, 82, 108,
+ 109, 85, 86, 45, 46, -1, -1, -1, 50, 93,
+ 94, -1, -1, -1, -1, -1, -1, 59, 102, 103,
+ 104, 105, -1, 65, 108, 109, 1, -1, 45, 46,
+ 72, -1, -1, 50, 76, -1, -1, -1, -1, -1,
+ 82, -1, 59, 85, 86, -1, -1, -1, 65, -1,
+ -1, 93, 94, 3, 4, 72, -1, -1, -1, 76,
+ 102, 103, 104, 105, -1, 82, 108, 109, 85, 86,
+ 45, 46, 89, 90, -1, 50, 93, -1, 95, 96,
+ -1, -1, -1, -1, 59, 102, 103, 104, 105, -1,
+ 65, 108, 109, -1, -1, 45, 46, 72, -1, -1,
+ 50, 76, -1, -1, 3, 4, -1, 82, -1, 59,
+ 85, 86, -1, -1, -1, 65, -1, -1, 93, -1,
+ -1, -1, 72, -1, -1, -1, 76, 102, 103, 104,
+ 105, -1, 82, 108, 109, 85, 86, -1, -1, 89,
+ 90, -1, -1, 93, 94, -1, 45, 46, -1, -1,
+ -1, 50, 102, 103, 104, 105, -1, -1, 108, 109,
+ 59, -1, -1, -1, -1, -1, 65, -1, -1, 3,
4, -1, -1, 72, -1, -1, -1, 76, -1, -1,
-1, -1, -1, 82, -1, -1, 85, 86, -1, -1,
- 89, 90, -1, -1, 93, -1, -1, -1, -1, -1,
+ 89, 90, -1, -1, 93, 94, -1, -1, -1, -1,
-1, -1, -1, 102, 103, 104, 105, -1, -1, 108,
- 109, 45, 46, -1, -1, -1, 50, -1, 1, -1,
+ 109, 45, 46, -1, -1, -1, 50, -1, -1, -1,
3, 4, -1, -1, -1, 59, -1, -1, -1, -1,
-1, 65, -1, -1, -1, -1, -1, -1, 72, -1,
-1, -1, 76, -1, -1, -1, -1, -1, 82, -1,
-1, 85, 86, -1, -1, 89, 90, -1, -1, 93,
- -1, -1, 45, 46, -1, -1, -1, 50, 102, 103,
+ 94, -1, 45, 46, -1, -1, -1, 50, 102, 103,
104, 105, -1, -1, 108, 109, 59, -1, -1, -1,
- -1, -1, 65, 1, -1, 3, 4, -1, -1, 72,
+ -1, -1, 65, -1, -1, 3, 4, -1, -1, 72,
-1, -1, -1, 76, -1, -1, -1, -1, -1, 82,
-1, -1, 85, 86, -1, -1, 89, 90, -1, -1,
- 93, -1, -1, -1, -1, -1, -1, -1, -1, 102,
+ 93, 94, -1, -1, -1, -1, -1, -1, -1, 102,
103, 104, 105, -1, -1, 108, 109, 45, 46, -1,
- -1, -1, 50, -1, 1, -1, 3, 4, -1, -1,
+ -1, -1, 50, -1, -1, -1, -1, -1, -1, -1,
-1, 59, -1, -1, -1, -1, -1, 65, -1, -1,
-1, -1, -1, -1, 72, -1, -1, -1, 76, -1,
-1, -1, -1, -1, 82, -1, -1, 85, 86, -1,
- -1, 89, 90, -1, -1, 93, -1, -1, 45, 46,
+ -1, 89, 90, -1, -1, 93, -1, 44, 45, 46,
-1, -1, -1, 50, 102, 103, 104, 105, -1, -1,
108, 109, 59, -1, -1, -1, -1, -1, 65, -1,
- 1, -1, -1, -1, -1, 72, -1, -1, -1, 76,
+ -1, -1, -1, -1, -1, 72, -1, -1, -1, 76,
-1, -1, -1, -1, -1, 82, -1, -1, 85, 86,
- -1, -1, 89, 90, -1, 1, 93, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 93, -1, -1, -1,
-1, -1, -1, -1, -1, 102, 103, 104, 105, -1,
- -1, 108, 109, 44, 45, 46, -1, -1, -1, 50,
- -1, -1, -1, -1, -1, -1, -1, -1, 59, -1,
- -1, -1, -1, -1, 65, -1, -1, 1, -1, 45,
- 46, 72, -1, -1, 50, 76, -1, -1, -1, -1,
- -1, 82, -1, 59, 85, 86, -1, -1, -1, 65,
- -1, -1, 93, -1, 3, 4, 72, -1, 99, -1,
- 76, 102, 103, 104, 105, -1, 82, 108, 109, 85,
- 86, 45, 46, -1, -1, -1, 50, 93, 94, -1,
- -1, -1, -1, -1, -1, 59, 102, 103, 104, 105,
- -1, 65, 108, 109, 1, -1, 45, 46, 72, -1,
- -1, 50, 76, -1, -1, -1, -1, -1, 82, -1,
- 59, 85, 86, -1, -1, -1, 65, -1, -1, 93,
- 94, 3, 4, 72, -1, -1, -1, 76, 102, 103,
- 104, 105, -1, 82, 108, 109, 85, 86, 45, 46,
- 89, 90, -1, 50, 93, -1, 95, 96, -1, -1,
- -1, 100, 59, 102, 103, 104, 105, -1, 65, 108,
- 109, -1, -1, 45, 46, 72, -1, -1, 50, 76,
- -1, -1, 3, 4, -1, 82, -1, 59, 85, 86,
- -1, -1, -1, 65, -1, -1, 93, -1, -1, -1,
- 72, -1, -1, -1, 76, 102, 103, 104, 105, -1,
- 82, 108, 109, 85, 86, -1, -1, 89, 90, -1,
- -1, 93, 94, -1, 45, 46, -1, -1, -1, 50,
- 102, 103, 104, 105, -1, -1, 108, 109, 59, -1,
- -1, -1, -1, -1, 65, -1, -1, 3, 4, -1,
- -1, 72, -1, -1, -1, 76, -1, -1, -1, -1,
- -1, 82, -1, -1, 85, 86, -1, -1, 89, 90,
- -1, -1, 93, 94, -1, -1, -1, -1, -1, -1,
- -1, 102, 103, 104, 105, -1, -1, 108, 109, 45,
- 46, -1, -1, -1, 50, -1, -1, -1, 3, 4,
- -1, -1, -1, 59, -1, -1, -1, -1, -1, 65,
- -1, -1, -1, -1, -1, -1, 72, -1, -1, -1,
- 76, -1, -1, -1, -1, -1, 82, -1, -1, 85,
- 86, -1, -1, 89, 90, -1, -1, 93, 94, -1,
- 45, 46, -1, -1, -1, 50, 102, 103, 104, 105,
- -1, -1, 108, 109, 59, -1, -1, -1, -1, -1,
- 65, -1, -1, 3, 4, -1, -1, 72, -1, -1,
- -1, 76, -1, -1, -1, -1, -1, 82, -1, -1,
- 85, 86, -1, -1, 89, 90, -1, -1, 93, 94,
- -1, -1, -1, -1, -1, -1, -1, 102, 103, 104,
- 105, -1, -1, 108, 109, 45, 46, -1, -1, -1,
- 50, -1, -1, -1, -1, -1, -1, -1, -1, 59,
- -1, -1, -1, -1, -1, 65, -1, -1, -1, -1,
- -1, -1, 72, -1, -1, -1, 76, -1, -1, -1,
- -1, -1, 82, -1, -1, 85, 86, -1, -1, 89,
- 90, -1, -1, 93, -1, 44, 45, 46, -1, -1,
- -1, 50, 102, 103, 104, 105, -1, -1, 108, 109,
- 59, -1, -1, -1, -1, -1, 65, -1, -1, -1,
- -1, -1, -1, 72, -1, -1, -1, 76, -1, -1,
- -1, -1, -1, 82, -1, -1, 85, 86, -1, -1,
- -1, -1, -1, -1, 93, -1, -1, -1, -1, -1,
- -1, -1, -1, 102, 103, 104, 105, -1, -1, 108,
- 109
+ -1, 108, 109
};
#define YYPURE 1
/* -*-C-*- Note some compilers choke on comments on `#line' lines. */
-#line 3 "/usr/cygnus/gnupro-98r1/share/bison.simple"
+#line 3 "/usr/lib/bison.simple"
/* Skeleton output parser for bison,
Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc.
@@ -2278,7 +2419,7 @@ __yy_memcpy (char *to, char *from, int count)
#endif
#endif
-#line 196 "/usr/cygnus/gnupro-98r1/share/bison.simple"
+#line 196 "/usr/lib/bison.simple"
/* The user can define YYPARSE_PARAM as the name of an argument to be passed
into yyparse. The argument should have type void *.
@@ -2583,66 +2724,66 @@ yyreduce:
switch (yyn) {
case 1:
-#line 253 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+#line 456 "./parse.y"
{;
break;}
case 18:
-#line 297 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+#line 500 "./parse.y"
{
yyval.node = build_java_array_type (yyvsp[-2].node, -1);
CLASS_LOADED_P (yyval.node) = 1;
;
break;}
case 19:
-#line 302 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+#line 505 "./parse.y"
{ yyval.node = build_unresolved_array_type (yyvsp[-2].node); ;
break;}
case 20:
-#line 304 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+#line 507 "./parse.y"
{ yyval.node = build_unresolved_array_type (yyvsp[-2].node); ;
break;}
case 21:
-#line 306 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+#line 509 "./parse.y"
{RULE ("']' expected"); RECOVER;;
break;}
case 22:
-#line 308 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+#line 511 "./parse.y"
{RULE ("']' expected"); RECOVER;;
break;}
case 26:
-#line 323 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+#line 526 "./parse.y"
{ yyval.node = make_qualified_name (yyvsp[-2].node, yyvsp[0].node, yyvsp[-1].operator.location); ;
break;}
case 28:
-#line 332 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+#line 535 "./parse.y"
{yyval.node = NULL;;
break;}
case 36:
-#line 344 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+#line 547 "./parse.y"
{
yyval.node = NULL;
;
break;}
case 37:
-#line 348 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+#line 551 "./parse.y"
{
yyval.node = NULL;
;
break;}
case 40:
-#line 360 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+#line 563 "./parse.y"
{ ctxp->package = EXPR_WFL_NODE (yyvsp[-1].node); ;
break;}
case 41:
-#line 362 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+#line 565 "./parse.y"
{yyerror ("Missing name"); RECOVER;;
break;}
case 42:
-#line 364 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+#line 567 "./parse.y"
{yyerror ("';' expected"); RECOVER;;
break;}
case 45:
-#line 374 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+#line 577 "./parse.y"
{
tree name = EXPR_WFL_NODE (yyvsp[-1].node), node, last_name;
int i = IDENTIFIER_LENGTH (name)-1;
@@ -2662,72 +2803,70 @@ case 45:
(yyvsp[-1].node, "Ambiguous class: `%s' and `%s'",
IDENTIFIER_POINTER (name),
IDENTIFIER_POINTER (err));
+ else
+ REGISTER_IMPORT (yyvsp[-1].node, last_name)
}
else
- {
- IS_A_SINGLE_IMPORT_CLASSFILE_NAME_P (last_name) = 1;
- node = build_tree_list (yyvsp[-1].node, last_name);
- TREE_CHAIN (node) = ctxp->import_list;
- ctxp->import_list = node;
- }
+ REGISTER_IMPORT (yyvsp[-1].node, last_name);
;
break;}
case 46:
-#line 403 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+#line 603 "./parse.y"
{yyerror ("Missing name"); RECOVER;;
break;}
case 47:
-#line 405 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+#line 605 "./parse.y"
{yyerror ("';' expected"); RECOVER;;
break;}
case 48:
-#line 410 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+#line 610 "./parse.y"
{
tree name = EXPR_WFL_NODE (yyvsp[-3].node);
- tree node = build_tree_list (yyvsp[-3].node, NULL_TREE);
- if (!IS_AN_IMPORT_ON_DEMAND_P (name))
+ /* Don't import java.lang.* twice. */
+ if (name != java_lang_id)
{
+ tree node = build_tree_list (yyvsp[-3].node, NULL_TREE);
read_import_dir (yyvsp[-3].node);
- IS_AN_IMPORT_ON_DEMAND_P (name) = 1;
+ TREE_CHAIN (node) = ctxp->import_demand_list;
+ ctxp->import_demand_list = node;
}
- TREE_CHAIN (node) = ctxp->import_demand_list;
- ctxp->import_demand_list = node;
;
break;}
case 49:
-#line 422 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+#line 622 "./parse.y"
{yyerror ("'*' expected"); RECOVER;;
break;}
case 50:
-#line 424 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+#line 624 "./parse.y"
{yyerror ("';' expected"); RECOVER;;
break;}
case 51:
-#line 429 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+#line 629 "./parse.y"
{
+ maybe_generate_finit ();
maybe_generate_clinit ();
yyval.node = yyvsp[0].node;
;
break;}
case 53:
-#line 435 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+#line 636 "./parse.y"
{ yyval.node = NULL; ;
break;}
case 54:
-#line 437 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+#line 638 "./parse.y"
{
YYERROR_NOW;
yyerror ("Class or interface declaration expected");
;
break;}
case 55:
-#line 448 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+#line 649 "./parse.y"
{
yyval.value = (1 << yyvsp[0].value);
;
break;}
case 56:
-#line 452 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+#line 653 "./parse.y"
{
int acc = (1 << yyvsp[0].value);
if (yyval.value & acc)
@@ -2741,107 +2880,124 @@ case 56:
;
break;}
case 57:
-#line 468 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+#line 669 "./parse.y"
{ create_class (yyvsp[-4].value, yyvsp[-2].node, yyvsp[-1].node, yyvsp[0].node); ;
break;}
case 58:
-#line 470 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+#line 671 "./parse.y"
{
yyval.node = yyvsp[0].node;
;
break;}
case 59:
-#line 474 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+#line 675 "./parse.y"
{ create_class (0, yyvsp[-2].node, yyvsp[-1].node, yyvsp[0].node); ;
break;}
case 60:
-#line 476 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+#line 677 "./parse.y"
{
yyval.node = yyvsp[0].node;
;
break;}
case 61:
-#line 480 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+#line 681 "./parse.y"
{yyerror ("Missing class name"); RECOVER;;
break;}
case 62:
-#line 482 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+#line 683 "./parse.y"
{yyerror ("Missing class name"); RECOVER;;
break;}
case 63:
-#line 484 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{if (!ctxp->class_err) yyerror ("'{' expected"); DRECOVER(class1);;
+#line 685 "./parse.y"
+{
+ if (!ctxp->class_err) yyerror ("'{' expected");
+ DRECOVER(class1);
+ ;
break;}
case 64:
-#line 486 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+#line 690 "./parse.y"
{if (!ctxp->class_err) yyerror ("'{' expected"); RECOVER;;
break;}
case 65:
-#line 490 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+#line 694 "./parse.y"
{ yyval.node = NULL; ;
break;}
case 66:
-#line 492 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+#line 696 "./parse.y"
{ yyval.node = yyvsp[0].node; ;
break;}
case 67:
-#line 494 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+#line 698 "./parse.y"
{yyerror ("'{' expected"); ctxp->class_err=1;;
break;}
case 68:
-#line 496 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+#line 700 "./parse.y"
{yyerror ("Missing super class name"); ctxp->class_err=1;;
break;}
case 69:
-#line 500 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+#line 704 "./parse.y"
{ yyval.node = NULL_TREE; ;
break;}
case 70:
-#line 502 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+#line 706 "./parse.y"
{ yyval.node = yyvsp[0].node; ;
break;}
case 71:
-#line 504 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+#line 708 "./parse.y"
{
ctxp->class_err=1;
yyerror ("Missing interface name");
;
break;}
case 72:
-#line 512 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+#line 716 "./parse.y"
{
ctxp->interface_number = 1;
yyval.node = build_tree_list (yyvsp[0].node, NULL_TREE);
;
break;}
case 73:
-#line 517 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+#line 721 "./parse.y"
{
ctxp->interface_number++;
yyval.node = chainon (yyvsp[-2].node, build_tree_list (yyvsp[0].node, NULL_TREE));
;
break;}
case 74:
-#line 522 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+#line 726 "./parse.y"
{yyerror ("Missing interface name"); RECOVER;;
break;}
case 75:
-#line 527 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+#line 731 "./parse.y"
{ yyval.node = ctxp->current_parsed_class; ;
break;}
case 76:
-#line 529 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+#line 733 "./parse.y"
{ yyval.node = ctxp->current_parsed_class; ;
break;}
+case 82:
+#line 746 "./parse.y"
+{ yyval.node = parse_jdk1_1_error ("instance initializer"); ;
+ break;}
+case 84:
+#line 752 "./parse.y"
+{ yyval.node = yyvsp[-1].node; ;
+ break;}
+case 86:
+#line 755 "./parse.y"
+{ yyval.node = parse_jdk1_1_error ("inner classe declaration"); ;
+ break;}
case 87:
-#line 554 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{ register_fields (0, yyvsp[-2].node, yyvsp[-1].node); ;
+#line 757 "./parse.y"
+{ yyval.node = parse_jdk1_1_error ("inner interface declaration"); ;
break;}
case 88:
-#line 556 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+#line 763 "./parse.y"
+{ register_fields (0, yyvsp[-2].node, yyvsp[-1].node); ;
+ break;}
+case 89:
+#line 765 "./parse.y"
{
- int acc_count = 0;
-
check_modifiers
("Illegal modifier `%s' for field declaration",
yyvsp[-3].value, FIELD_MODIFIERS);
@@ -2849,20 +3005,20 @@ case 88:
register_fields (yyvsp[-3].value, yyvsp[-2].node, yyvsp[-1].node);
;
break;}
-case 90:
-#line 571 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 91:
+#line 778 "./parse.y"
{ yyval.node = chainon (yyvsp[-2].node, yyvsp[0].node); ;
break;}
-case 91:
-#line 573 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 92:
+#line 780 "./parse.y"
{yyerror ("Missing term"); RECOVER;;
break;}
-case 92:
-#line 578 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 93:
+#line 785 "./parse.y"
{ yyval.node = build_tree_list (yyvsp[0].node, NULL_TREE); ;
break;}
-case 93:
-#line 580 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 94:
+#line 787 "./parse.y"
{
if (java_error_count)
yyvsp[0].node = NULL_TREE;
@@ -2870,411 +3026,454 @@ case 93:
(yyvsp[-2].node, build_assignment (yyvsp[-1].operator.token, yyvsp[-1].operator.location, yyvsp[-2].node, yyvsp[0].node));
;
break;}
-case 94:
-#line 587 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 95:
+#line 794 "./parse.y"
{
yyerror ("Missing variable initializer");
yyval.node = build_tree_list (yyvsp[-2].node, NULL_TREE);
RECOVER;
;
break;}
-case 95:
-#line 593 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 96:
+#line 800 "./parse.y"
{
yyerror ("';' expected");
yyval.node = build_tree_list (yyvsp[-3].node, NULL_TREE);
RECOVER;
;
break;}
-case 97:
-#line 603 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{
- yyval.node = NULL; /* FIXME */
- ;
- break;}
case 98:
-#line 607 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{yyerror ("Invalid declaration"); DRECOVER(vdi);;
+#line 810 "./parse.y"
+{ yyval.node = build_unresolved_array_type (yyvsp[-2].node); ;
break;}
case 99:
-#line 609 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{yyerror ("']' expected"); DRECOVER(vdi);;
+#line 812 "./parse.y"
+{yyerror ("Invalid declaration"); DRECOVER(vdi);;
break;}
case 100:
-#line 611 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{yyerror ("Unbalanced ']'"); DRECOVER(vdi);;
+#line 814 "./parse.y"
+{yyerror ("']' expected"); DRECOVER(vdi);;
break;}
-case 102:
-#line 617 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{ yyval.node = NULL; ;
+case 101:
+#line 816 "./parse.y"
+{yyerror ("Unbalanced ']'"); DRECOVER(vdi);;
break;}
-case 103:
-#line 623 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 104:
+#line 827 "./parse.y"
{
current_function_decl = yyvsp[0].node;
source_start_java_method (current_function_decl);
;
break;}
-case 104:
-#line 628 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{
- BLOCK_EXPR_BODY
- (DECL_FUNCTION_BODY (current_function_decl)) = yyvsp[0].node;
- maybe_absorb_scoping_blocks ();
- exit_block (); /* Exit function's body. */
-
- /* Merge last line of the function with first line,
- directly in the function decl. It will be used to
- emit correct debug info. */
- DECL_SOURCE_LINE_MERGE (current_function_decl,
- ctxp->last_ccb_indent1);
- ;
- break;}
case 105:
-#line 641 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{YYNOT_TWICE yyerror ("'{' expected"); RECOVER;;
+#line 832 "./parse.y"
+{ finish_method_declaration (yyvsp[0].node); ;
break;}
case 106:
-#line 646 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{ yyval.node = method_header (0, yyvsp[-2].node, yyvsp[-1].node, NULL); ;
+#line 834 "./parse.y"
+{YYNOT_TWICE yyerror ("'{' expected"); RECOVER;;
break;}
case 107:
-#line 648 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{ yyval.node = method_header (0, void_type_node, yyvsp[-1].node, NULL); ;
+#line 839 "./parse.y"
+{ yyval.node = method_header (0, yyvsp[-2].node, yyvsp[-1].node, yyvsp[0].node); ;
break;}
case 108:
-#line 650 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{ yyval.node = method_header (yyvsp[-3].value, yyvsp[-2].node, yyvsp[-1].node, NULL); ;
+#line 841 "./parse.y"
+{ yyval.node = method_header (0, void_type_node, yyvsp[-1].node, yyvsp[0].node); ;
break;}
case 109:
-#line 652 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{ yyval.node = method_header (yyvsp[-3].value, void_type_node, yyvsp[-1].node, NULL); ;
+#line 843 "./parse.y"
+{ yyval.node = method_header (yyvsp[-3].value, yyvsp[-2].node, yyvsp[-1].node, yyvsp[0].node); ;
break;}
case 110:
-#line 654 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{RECOVER;;
+#line 845 "./parse.y"
+{ yyval.node = method_header (yyvsp[-3].value, void_type_node, yyvsp[-1].node, yyvsp[0].node); ;
break;}
case 111:
-#line 656 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+#line 847 "./parse.y"
{RECOVER;;
break;}
case 112:
-#line 658 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{yyerror ("Identifier expected"); RECOVER;;
+#line 849 "./parse.y"
+{RECOVER;;
break;}
case 113:
-#line 660 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+#line 851 "./parse.y"
{yyerror ("Identifier expected"); RECOVER;;
break;}
case 114:
-#line 662 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+#line 853 "./parse.y"
+{yyerror ("Identifier expected"); RECOVER;;
+ break;}
+case 115:
+#line 855 "./parse.y"
{
yyerror ("Invalid method declaration, return type required");
RECOVER;
;
break;}
-case 115:
-#line 670 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 116:
+#line 863 "./parse.y"
{ yyval.node = method_declarator (yyvsp[-2].node, NULL_TREE); ;
break;}
-case 116:
-#line 672 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 117:
+#line 865 "./parse.y"
{ yyval.node = method_declarator (yyvsp[-3].node, yyvsp[-1].node); ;
break;}
-case 117:
-#line 674 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{
- /* Issue a warning here: obsolete declaration. FIXME */
- yyval.node = NULL; /* FIXME */
+case 118:
+#line 867 "./parse.y"
+{
+ EXPR_WFL_LINECOL (wfl_operator) = yyvsp[-1].operator.location;
+ TREE_PURPOSE (yyvsp[-2].node) =
+ build_unresolved_array_type (TREE_PURPOSE (yyvsp[-2].node));
+ parse_warning_context
+ (wfl_operator,
+ "Discouraged form of returned type specification");
;
break;}
-case 118:
-#line 679 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 119:
+#line 876 "./parse.y"
{yyerror ("')' expected"); DRECOVER(method_declarator);;
break;}
-case 119:
-#line 681 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 120:
+#line 878 "./parse.y"
{yyerror ("']' expected"); RECOVER;;
break;}
-case 120:
-#line 686 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 121:
+#line 883 "./parse.y"
{
ctxp->formal_parameter_number = 1;
;
break;}
-case 121:
-#line 690 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 122:
+#line 887 "./parse.y"
{
ctxp->formal_parameter_number += 1;
yyval.node = chainon (yyvsp[-2].node, yyvsp[0].node);
;
break;}
-case 122:
-#line 695 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{yyerror ("Missing formal parameter term"); RECOVER;;
- break;}
case 123:
-#line 700 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{
- yyval.node = build_tree_list (yyvsp[0].node, yyvsp[-1].node);
- ;
+#line 892 "./parse.y"
+{yyerror ("Missing formal parameter term"); RECOVER;;
break;}
case 124:
-#line 704 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+#line 897 "./parse.y"
{
- SOURCE_FRONTEND_DEBUG (("Modifiers: %d", yyvsp[-2].value));
- yyval.node = NULL; /* FIXME */
+ yyval.node = build_tree_list (yyvsp[0].node, yyvsp[-1].node);
;
break;}
case 125:
-#line 709 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{yyerror ("Missing identifier"); RECOVER;;
+#line 901 "./parse.y"
+{ yyval.node = parse_jdk1_1_error ("final parameters"); ;
break;}
case 126:
-#line 711 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+#line 903 "./parse.y"
+{yyerror ("Missing identifier"); RECOVER;;
+ break;}
+case 127:
+#line 905 "./parse.y"
{
SOURCE_FRONTEND_DEBUG (("Modifiers: %d", yyvsp[-2].value));
yyerror ("Missing identifier"); RECOVER;
;
break;}
+case 128:
+#line 912 "./parse.y"
+{ yyval.node = NULL_TREE; ;
+ break;}
case 129:
-#line 720 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+#line 914 "./parse.y"
+{ yyval.node = yyvsp[0].node; ;
+ break;}
+case 130:
+#line 916 "./parse.y"
{yyerror ("Missing class type term"); RECOVER;;
break;}
+case 131:
+#line 921 "./parse.y"
+{ yyval.node = build_tree_list (yyvsp[0].node, yyvsp[0].node); ;
+ break;}
case 132:
-#line 727 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{yyerror ("Missing class type term"); RECOVER;;
+#line 923 "./parse.y"
+{ yyval.node = tree_cons (yyvsp[0].node, yyvsp[0].node, yyvsp[-2].node); ;
break;}
-case 135:
-#line 734 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{ yyval.node = NULL_TREE; ;
+case 133:
+#line 925 "./parse.y"
+{yyerror ("Missing class type term"); RECOVER;;
break;}
case 136:
-#line 740 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{
- RULE ("STATIC_INITIALIZER");
- ;
+#line 932 "./parse.y"
+{ yyval.node = NULL_TREE; ;
break;}
case 137:
-#line 744 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+#line 938 "./parse.y"
{
- RULE ("STATIC_INITIALIZER");
+ TREE_CHAIN (yyvsp[0].node) = ctxp->static_initialized;
+ ctxp->static_initialized = yyvsp[0].node;
;
break;}
case 138:
-#line 751 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+#line 943 "./parse.y"
{
- SOURCE_FRONTEND_DEBUG (("Modifiers: %d", yyvsp[0].value));
+ TREE_CHAIN (yyvsp[-1].node) = ctxp->static_initialized;
+ ctxp->static_initialized = yyvsp[-1].node;
;
break;}
case 139:
-#line 763 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+#line 951 "./parse.y"
{
- RULE ("CONSTRUCTOR_DECLARATION");
+ SOURCE_FRONTEND_DEBUG (("Modifiers: %d", yyvsp[0].value));
;
break;}
case 140:
-#line 767 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+#line 959 "./parse.y"
{
- SOURCE_FRONTEND_DEBUG (("Modifiers: %d", yyvsp[-3].value));
- RULE ("CONSTRUCTOR_DECLARATION (modifier)");
+ current_function_decl = yyvsp[0].node;
+ source_start_java_method (current_function_decl);
;
break;}
case 141:
-#line 773 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{
- RULE ("CONSTRUCTOR_DECLARATION");
- ;
+#line 964 "./parse.y"
+{ finish_method_declaration (yyvsp[0].node); ;
break;}
case 142:
-#line 778 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{
- SOURCE_FRONTEND_DEBUG (("Modifiers: %d", yyvsp[-4].value));
- RULE ("CONSTRUCTOR_DECLARATION (modifier)");
+#line 969 "./parse.y"
+{ yyval.node = method_header (0, NULL_TREE, yyvsp[-1].node, yyvsp[0].node); ;
+ break;}
+case 143:
+#line 971 "./parse.y"
+{ yyval.node = method_header (yyvsp[-2].value, NULL_TREE, yyvsp[-1].node, yyvsp[0].node); ;
+ break;}
+case 144:
+#line 976 "./parse.y"
+{ yyval.node = method_declarator (yyvsp[-2].node, NULL_TREE); ;
+ break;}
+case 145:
+#line 978 "./parse.y"
+{ yyval.node = method_declarator (yyvsp[-3].node, yyvsp[-1].node); ;
+ break;}
+case 146:
+#line 986 "./parse.y"
+{
+ BLOCK_EXPR_BODY (yyvsp[0].node) = empty_stmt_node;
+ yyval.node = yyvsp[0].node;
+ ;
+ break;}
+case 147:
+#line 991 "./parse.y"
+{ yyval.node = yyvsp[0].node; ;
+ break;}
+case 148:
+#line 993 "./parse.y"
+{ yyval.node = yyvsp[0].node; ;
+ break;}
+case 149:
+#line 995 "./parse.y"
+{ yyval.node = yyvsp[0].node; ;
+ break;}
+case 150:
+#line 1001 "./parse.y"
+{
+ yyval.node = build_method_invocation (yyvsp[-3].node, NULL_TREE);
+ yyval.node = build_debugable_stmt (EXPR_WFL_LINECOL (yyvsp[-3].node), yyval.node);
+ yyval.node = java_method_add_stmt (current_function_decl, yyval.node);
+ ;
+ break;}
+case 151:
+#line 1007 "./parse.y"
+{
+ yyval.node = build_method_invocation (yyvsp[-4].node, yyvsp[-2].node);
+ yyval.node = build_debugable_stmt (EXPR_WFL_LINECOL (yyvsp[-4].node), yyval.node);
+ yyval.node = java_method_add_stmt (current_function_decl, yyval.node);
;
break;}
case 152:
-#line 806 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{RULE ("explicit_constructor_invocation (X.super)");;
+#line 1015 "./parse.y"
+{yyval.node = parse_jdk1_1_error ("explicit constructor invocation"); ;
break;}
case 153:
-#line 811 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+#line 1017 "./parse.y"
+{yyval.node = parse_jdk1_1_error ("explicit constructor invocation"); ;
+ break;}
+case 154:
+#line 1022 "./parse.y"
{
- tree wfl = build_wfl_node (this_identifier_node, input_filename, 0, 0);
+ tree wfl = build_wfl_node (this_identifier_node);
EXPR_WFL_LINECOL (wfl) = yyvsp[0].operator.location;
yyval.node = wfl;
;
break;}
-case 154:
-#line 817 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 155:
+#line 1028 "./parse.y"
{
- tree wfl = build_wfl_node (super_identifier_node, input_filename, 0, 0);
+ tree wfl = build_wfl_node (super_identifier_node);
EXPR_WFL_LINECOL (wfl) = yyvsp[0].operator.location;
yyval.node = wfl;
;
break;}
-case 155:
-#line 828 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 156:
+#line 1039 "./parse.y"
{ create_interface (0, yyvsp[0].node, NULL_TREE); ;
break;}
-case 156:
-#line 830 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 157:
+#line 1041 "./parse.y"
{
yyval.node = yyvsp[0].node;
;
break;}
-case 157:
-#line 834 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 158:
+#line 1045 "./parse.y"
{ create_interface (yyvsp[-2].value, yyvsp[0].node, NULL_TREE); ;
break;}
-case 158:
-#line 836 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 159:
+#line 1047 "./parse.y"
{
yyval.node = yyvsp[0].node;
;
break;}
-case 159:
-#line 840 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 160:
+#line 1051 "./parse.y"
{ create_interface (0, yyvsp[-1].node, yyvsp[0].node); ;
break;}
-case 160:
-#line 842 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 161:
+#line 1053 "./parse.y"
{
yyval.node = yyvsp[0].node;
;
break;}
-case 161:
-#line 846 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 162:
+#line 1057 "./parse.y"
{ create_interface (yyvsp[-3].value, yyvsp[-1].node, yyvsp[0].node); ;
break;}
-case 162:
-#line 848 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 163:
+#line 1059 "./parse.y"
{
yyval.node = yyvsp[0].node;
;
break;}
-case 163:
-#line 852 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{yyerror ("(here)'{' expected"); RECOVER;;
- break;}
case 164:
-#line 854 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{yyerror ("(there)'{' expected"); RECOVER;;
+#line 1063 "./parse.y"
+{yyerror ("'{' expected"); RECOVER;;
break;}
case 165:
-#line 859 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+#line 1065 "./parse.y"
+{yyerror ("'{' expected"); RECOVER;;
+ break;}
+case 166:
+#line 1070 "./parse.y"
{
ctxp->interface_number = 1;
yyval.node = build_tree_list (yyvsp[0].node, NULL_TREE);
;
break;}
-case 166:
-#line 864 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 167:
+#line 1075 "./parse.y"
{
ctxp->interface_number++;
yyval.node = chainon (yyvsp[-2].node, build_tree_list (yyvsp[0].node, NULL_TREE));
;
break;}
-case 167:
-#line 869 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 168:
+#line 1080 "./parse.y"
{yyerror ("Invalid interface type"); RECOVER;;
break;}
-case 168:
-#line 871 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 169:
+#line 1082 "./parse.y"
{yyerror ("Missing term"); RECOVER;;
break;}
-case 169:
-#line 876 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 170:
+#line 1087 "./parse.y"
{ yyval.node = NULL_TREE; ;
break;}
-case 170:
-#line 878 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 171:
+#line 1089 "./parse.y"
{ yyval.node = NULL_TREE; ;
break;}
-case 178:
-#line 899 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 176:
+#line 1101 "./parse.y"
+{ yyval.node = parse_jdk1_1_error ("inner class declaration"); ;
+ break;}
+case 177:
+#line 1103 "./parse.y"
+{ yyval.node = parse_jdk1_1_error ("inner interface declaration"); ;
+ break;}
+case 179:
+#line 1112 "./parse.y"
{
check_abstract_method_header (yyvsp[-1].node);
current_function_decl = NULL_TREE; /* FIXME ? */
;
break;}
-case 179:
-#line 904 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{yyerror ("';' expected"); RECOVER;;
- break;}
case 180:
-#line 910 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{
- RULE ("ARRAY_INITIALIZER (empty)");
- ;
+#line 1117 "./parse.y"
+{yyerror ("';' expected"); RECOVER;;
break;}
case 181:
-#line 914 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{
- RULE ("ARRAY_INITIALIZER (variable)");
- ;
+#line 1123 "./parse.y"
+{ yyval.node = build_new_array_init (yyvsp[-1].operator.location, NULL_TREE); ;
break;}
case 182:
-#line 918 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{
- RULE ("ARRAY_INITIALIZER (,)");
- ;
+#line 1125 "./parse.y"
+{ yyval.node = build_new_array_init (yyvsp[-2].operator.location, yyvsp[-1].node); ;
break;}
case 183:
-#line 922 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+#line 1127 "./parse.y"
+{ yyval.node = build_new_array_init (yyvsp[-3].operator.location, yyvsp[-2].node); ;
+ break;}
+case 184:
+#line 1132 "./parse.y"
+{
+ yyval.node = tree_cons (maybe_build_array_element_wfl (yyvsp[0].node),
+ yyvsp[0].node, NULL_TREE);
+ ;
+ break;}
+case 185:
+#line 1137 "./parse.y"
{
- RULE ("ARRAY_INITIALIZER (variable, ,)");
+ yyval.node = tree_cons (maybe_build_array_element_wfl (yyvsp[0].node), yyvsp[0].node, yyvsp[-2].node);
;
break;}
case 186:
-#line 931 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+#line 1141 "./parse.y"
{yyerror ("Missing term"); RECOVER;;
break;}
case 187:
-#line 937 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{ yyval.node = size_zero_node; ;
+#line 1147 "./parse.y"
+{ yyval.node = empty_stmt_node; ;
break;}
case 188:
-#line 939 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{ enter_block (); ;
+#line 1149 "./parse.y"
+{ yyval.node = yyvsp[0].node; ;
break;}
case 189:
-#line 942 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+#line 1154 "./parse.y"
+{ enter_block (); ;
+ break;}
+case 190:
+#line 1159 "./parse.y"
{
maybe_absorb_scoping_blocks ();
yyval.node = exit_block ();
;
break;}
-case 193:
-#line 956 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{ yyval.node = java_method_add_stmt (current_function_decl, yyvsp[0].node); ;
+case 194:
+#line 1173 "./parse.y"
+{ java_method_add_stmt (current_function_decl, yyvsp[0].node); ;
break;}
-case 196:
-#line 966 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{ declare_local_variables (0, yyvsp[-1].node, yyvsp[0].node); ;
+case 195:
+#line 1175 "./parse.y"
+{ parse_jdk1_1_error ("inner class declaration"); ;
break;}
case 197:
-#line 968 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{ declare_local_variables (yyvsp[-2].value, yyvsp[-1].node, yyvsp[0].node); ;
- break;}
-case 199:
-#line 974 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{ RULE ("STATEMENT (labeled)"); ;
- break;}
-case 200:
-#line 976 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{ RULE ("STATEMENT (if-then)"); ;
- break;}
-case 201:
-#line 978 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{ RULE ("STATEMENT (if-then-else)"); ;
+#line 1184 "./parse.y"
+{ declare_local_variables (0, yyvsp[-1].node, yyvsp[0].node); ;
break;}
-case 202:
-#line 980 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{ RULE ("STATEMENT (while)"); ;
+case 198:
+#line 1186 "./parse.y"
+{ declare_local_variables (yyvsp[-2].value, yyvsp[-1].node, yyvsp[0].node); ;
break;}
-case 203:
-#line 982 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 204:
+#line 1196 "./parse.y"
{
/* If the for loop is unlabeled, we must return the
block it was defined it. It our last chance to
@@ -3283,98 +3482,34 @@ case 203:
yyval.node = exit_block ();
;
break;}
-case 205:
-#line 994 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{ RULE ("NSI STATEMENT (labeled)"); ;
- break;}
-case 206:
-#line 996 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{ RULE ("NSI STATEMENT (if-then-else)"); ;
- break;}
-case 207:
-#line 998 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{ RULE ("NSI STATEMENT (while)"); ;
- break;}
-case 208:
-#line 1000 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{ RULE ("NSI STATEMENT (for)"); ;
- break;}
-case 209:
-#line 1005 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{ RULE ("STATEMENT (block)"); ;
- break;}
-case 210:
-#line 1007 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{ RULE ("STATEMENT (empty)"); ;
- break;}
-case 211:
-#line 1009 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{ RULE ("STATEMENT (expression)"); ;
- break;}
-case 212:
-#line 1011 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{ RULE ("STATEMENT (switch)"); ;
- break;}
-case 213:
-#line 1013 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{ RULE ("STATEMENT (do)"); ;
- break;}
-case 214:
-#line 1015 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{ RULE ("STATEMENT (break)"); ;
- break;}
-case 215:
-#line 1017 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{ RULE ("STATEMENT (continue)"); ;
- break;}
-case 217:
-#line 1020 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{ RULE ("STATEMENT (synchronized)"); ;
- break;}
-case 218:
-#line 1022 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{ RULE ("STATEMENT (throw)"); ;
- break;}
-case 219:
-#line 1024 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{ RULE ("STATEMENT (try)"); ;
- break;}
-case 220:
-#line 1029 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{ yyval.node = size_zero_node; ;
- break;}
case 221:
-#line 1034 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+#line 1229 "./parse.y"
+{ yyval.node = empty_stmt_node; ;
+ break;}
+case 222:
+#line 1234 "./parse.y"
{
yyval.node = build_labeled_block (EXPR_WFL_LINECOL (yyvsp[-1].node),
- EXPR_WFL_NODE (yyvsp[-1].node), yyvsp[-1].node);
+ EXPR_WFL_NODE (yyvsp[-1].node));
pushlevel (2);
push_labeled_block (yyval.node);
PUSH_LABELED_BLOCK (yyval.node);
;
break;}
-case 222:
-#line 1045 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{
- yyval.node = complete_labeled_statement (yyvsp[-1].node, yyvsp[0].node);
- pop_labeled_block ();
- POP_LABELED_BLOCK ();
- ;
- break;}
case 223:
-#line 1051 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{yyerror ("':' expected"); RECOVER;;
+#line 1245 "./parse.y"
+{ yyval.node = finish_labeled_statement (yyvsp[-1].node, yyvsp[0].node); ;
break;}
case 224:
-#line 1056 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{
- yyval.node = complete_labeled_statement (yyvsp[-1].node, yyvsp[0].node);
- pop_labeled_block ();
- POP_LABELED_BLOCK ();
- ;
+#line 1247 "./parse.y"
+{yyerror ("':' expected"); RECOVER;;
break;}
case 225:
-#line 1067 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+#line 1252 "./parse.y"
+{ yyval.node = finish_labeled_statement (yyvsp[-1].node, yyvsp[0].node); ;
+ break;}
+case 226:
+#line 1259 "./parse.y"
{
/* We have a statement. Generate a WFL around it so
we can debug it */
@@ -3384,238 +3519,275 @@ case 225:
yyval.node = JAVA_MAYBE_GENERATE_DEBUG_INFO (yyval.node);
;
break;}
-case 226:
-#line 1076 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 227:
+#line 1268 "./parse.y"
{
if (ctxp->prevent_ese != lineno)
yyerror ("Invalid expression statement");
DRECOVER (expr_stmt);
;
break;}
-case 227:
-#line 1082 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 228:
+#line 1274 "./parse.y"
{
if (ctxp->prevent_ese != lineno)
yyerror ("Invalid expression statement");
DRECOVER (expr_stmt);
;
break;}
-case 228:
-#line 1088 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 229:
+#line 1280 "./parse.y"
{
if (ctxp->prevent_ese != lineno)
yyerror ("Invalid expression statement");
DRECOVER (expr_stmt);
;
break;}
-case 229:
-#line 1094 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{yyerror ("')' expected"); RECOVER;;
- break;}
case 230:
-#line 1096 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{yyerror ("';' expected"); RECOVER;;
+#line 1286 "./parse.y"
+{yyerror ("')' expected"); RECOVER;;
break;}
case 231:
-#line 1098 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{yyerror ("')' expected"); RECOVER;;
+#line 1288 "./parse.y"
+{
+ yyerror ("Constructor invocation must be first "
+ "thing in a constructor");
+ RECOVER;
+ ;
break;}
case 232:
-#line 1100 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{yyerror ("';' expected"); RECOVER;;
+#line 1294 "./parse.y"
+{yyerror ("')' expected"); RECOVER;;
break;}
case 233:
-#line 1102 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{yyerror ("'(' expected"); RECOVER;;
+#line 1296 "./parse.y"
+{
+ yyerror ("Constructor invocation must be first "
+ "thing in a constructor");
+ RECOVER;
+ ;
break;}
case 234:
-#line 1104 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{yyerror ("')' expected"); RECOVER;;
+#line 1302 "./parse.y"
+{yyerror ("'(' expected"); RECOVER;;
break;}
case 235:
-#line 1106 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+#line 1304 "./parse.y"
{yyerror ("')' expected"); RECOVER;;
break;}
case 236:
-#line 1108 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{yyerror ("';' expected"); RECOVER;;
+#line 1306 "./parse.y"
+{yyerror ("')' expected"); RECOVER;;
break;}
case 237:
-#line 1110 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+#line 1308 "./parse.y"
{yyerror ("';' expected"); RECOVER;;
break;}
-case 239:
-#line 1116 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{
- RULE ("++INCREMENT");
- ;
- break;}
-case 240:
-#line 1120 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{
- RULE ("--DECREMENT");
- ;
- break;}
-case 241:
-#line 1124 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{
- RULE ("INCREMENT++");
- ;
- break;}
-case 242:
-#line 1128 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{
- RULE ("DECREMENT--");
- ;
+case 238:
+#line 1310 "./parse.y"
+{yyerror ("';' expected"); RECOVER;;
break;}
-case 244:
-#line 1133 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{
- RULE ("INSTANCE CREATION");
+case 246:
+#line 1325 "./parse.y"
+{
+ yyval.node = build_if_else_statement (yyvsp[-3].operator.location, yyvsp[-2].node,
+ yyvsp[0].node, NULL_TREE);
;
break;}
-case 245:
-#line 1140 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{ yyval.node = build_if_else_statement (yyvsp[-3].operator.location, yyvsp[-2].node, yyvsp[0].node, NULL_TREE); ;
- break;}
-case 246:
-#line 1142 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 247:
+#line 1330 "./parse.y"
{yyerror ("'(' expected"); RECOVER;;
break;}
-case 247:
-#line 1144 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 248:
+#line 1332 "./parse.y"
{yyerror ("Missing term"); RECOVER;;
break;}
-case 248:
-#line 1146 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 249:
+#line 1334 "./parse.y"
{yyerror ("')' expected"); RECOVER;;
break;}
-case 249:
-#line 1151 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 250:
+#line 1339 "./parse.y"
{ yyval.node = build_if_else_statement (yyvsp[-5].operator.location, yyvsp[-4].node, yyvsp[-2].node, yyvsp[0].node); ;
break;}
-case 250:
-#line 1156 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 251:
+#line 1344 "./parse.y"
{ yyval.node = build_if_else_statement (yyvsp[-5].operator.location, yyvsp[-4].node, yyvsp[-2].node, yyvsp[0].node); ;
break;}
case 252:
-#line 1162 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{yyerror ("'(' expected"); RECOVER;;
+#line 1349 "./parse.y"
+{
+ enter_block ();
+ ;
break;}
case 253:
-#line 1164 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{yyerror ("Missing term or ')'"); DRECOVER(switch_statement);;
+#line 1353 "./parse.y"
+{
+ /* Make into "proper list" of COMPOUND_EXPRs.
+ I.e. make the last statment also have its own
+ COMPOUND_EXPR. */
+ maybe_absorb_scoping_blocks ();
+ TREE_OPERAND (yyvsp[-2].node, 1) = exit_block ();
+ yyval.node = build_debugable_stmt (EXPR_WFL_LINECOL (yyvsp[-2].node), yyvsp[-2].node);
+ ;
break;}
case 254:
-#line 1166 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+#line 1365 "./parse.y"
+{
+ yyval.node = build (SWITCH_EXPR, NULL_TREE, yyvsp[-1].node, NULL_TREE);
+ EXPR_WFL_LINECOL (yyval.node) = yyvsp[-2].operator.location;
+ ;
+ break;}
+case 255:
+#line 1370 "./parse.y"
+{yyerror ("'(' expected"); RECOVER;;
+ break;}
+case 256:
+#line 1372 "./parse.y"
+{yyerror ("Missing term or ')'"); DRECOVER(switch_statement);;
+ break;}
+case 257:
+#line 1374 "./parse.y"
{yyerror ("'{' expected"); RECOVER;;
break;}
-case 266:
-#line 1195 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{yyerror ("Missing or invalid constant expression"); RECOVER;;
+case 258:
+#line 1382 "./parse.y"
+{ yyval.node = NULL_TREE; ;
+ break;}
+case 259:
+#line 1384 "./parse.y"
+{ yyval.node = NULL_TREE; ;
+ break;}
+case 260:
+#line 1386 "./parse.y"
+{ yyval.node = NULL_TREE; ;
+ break;}
+case 261:
+#line 1388 "./parse.y"
+{ yyval.node = NULL_TREE; ;
break;}
case 267:
-#line 1197 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{yyerror ("':' expected"); RECOVER;;
+#line 1407 "./parse.y"
+{
+ tree lab = build1 (CASE_EXPR, NULL_TREE, yyvsp[-1].node);
+ EXPR_WFL_LINECOL (lab) = yyvsp[-2].operator.location;
+ java_method_add_stmt (current_function_decl, lab);
+ ;
break;}
case 268:
-#line 1199 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{yyerror ("':' expected"); RECOVER;;
+#line 1413 "./parse.y"
+{
+ tree lab = build1 (DEFAULT_EXPR, NULL_TREE, NULL_TREE);
+ EXPR_WFL_LINECOL (lab) = yyvsp[-1].operator.location;
+ java_method_add_stmt (current_function_decl, lab);
+ ;
break;}
case 269:
-#line 1204 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+#line 1419 "./parse.y"
+{yyerror ("Missing or invalid constant expression"); RECOVER;;
+ break;}
+case 270:
+#line 1421 "./parse.y"
+{yyerror ("':' expected"); RECOVER;;
+ break;}
+case 271:
+#line 1423 "./parse.y"
+{yyerror ("':' expected"); RECOVER;;
+ break;}
+case 272:
+#line 1428 "./parse.y"
{
tree body = build_loop_body (yyvsp[-2].operator.location, yyvsp[-1].node, 0);
yyval.node = build_new_loop (body);
;
break;}
-case 270:
-#line 1212 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{ yyval.node = complete_loop_body (0, NULL_TREE, yyvsp[0].node, 0); ;
+case 273:
+#line 1436 "./parse.y"
+{ yyval.node = finish_loop_body (0, NULL_TREE, yyvsp[0].node, 0); ;
break;}
-case 271:
-#line 1214 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 274:
+#line 1438 "./parse.y"
{YYERROR_NOW; yyerror ("'(' expected"); RECOVER;;
break;}
-case 272:
-#line 1216 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 275:
+#line 1440 "./parse.y"
{yyerror ("Missing term and ')' expected"); RECOVER;;
break;}
-case 273:
-#line 1218 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 276:
+#line 1442 "./parse.y"
{yyerror ("')' expected"); RECOVER;;
break;}
-case 274:
-#line 1223 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{ yyval.node = complete_loop_body (0, NULL_TREE, yyvsp[0].node, 0); ;
+case 277:
+#line 1447 "./parse.y"
+{ yyval.node = finish_loop_body (0, NULL_TREE, yyvsp[0].node, 0); ;
break;}
-case 275:
-#line 1228 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 278:
+#line 1452 "./parse.y"
{
tree body = build_loop_body (0, NULL_TREE, 1);
yyval.node = build_new_loop (body);
;
break;}
-case 276:
-#line 1237 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{ yyval.node = complete_loop_body (yyvsp[-3].operator.location, yyvsp[-2].node, yyvsp[-5].node, 1); ;
+case 279:
+#line 1461 "./parse.y"
+{ yyval.node = finish_loop_body (yyvsp[-3].operator.location, yyvsp[-2].node, yyvsp[-5].node, 1); ;
break;}
-case 277:
-#line 1242 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{ yyval.node = complete_for_loop (EXPR_WFL_LINECOL (yyvsp[-4].node), yyvsp[-4].node, yyvsp[-2].node, yyvsp[0].node);;
+case 280:
+#line 1466 "./parse.y"
+{ yyval.node = finish_for_loop (EXPR_WFL_LINECOL (yyvsp[-4].node), yyvsp[-4].node, yyvsp[-2].node, yyvsp[0].node); ;
break;}
-case 278:
-#line 1244 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 281:
+#line 1468 "./parse.y"
{
- yyval.node = complete_for_loop (0, NULL_TREE, yyvsp[-2].node, yyvsp[0].node);
+ yyval.node = finish_for_loop (0, NULL_TREE, yyvsp[-2].node, yyvsp[0].node);
/* We have not condition, so we get rid of the EXIT_EXPR */
LOOP_EXPR_BODY_CONDITION_EXPR (LOOP_EXPR_BODY (yyval.node), 0) =
- size_zero_node;
+ empty_stmt_node;
;
break;}
-case 279:
-#line 1251 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 282:
+#line 1475 "./parse.y"
{yyerror ("Invalid control expression"); RECOVER;;
break;}
-case 280:
-#line 1253 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 283:
+#line 1477 "./parse.y"
{yyerror ("Invalid update expression"); RECOVER;;
break;}
-case 281:
-#line 1255 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 284:
+#line 1479 "./parse.y"
{yyerror ("Invalid update expression"); RECOVER;;
break;}
-case 282:
-#line 1260 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{ yyval.node = complete_for_loop (EXPR_WFL_LINECOL (yyvsp[-4].node), yyvsp[-4].node, yyvsp[-2].node, yyvsp[0].node);;
+case 285:
+#line 1484 "./parse.y"
+{ yyval.node = finish_for_loop (EXPR_WFL_LINECOL (yyvsp[-4].node), yyvsp[-4].node, yyvsp[-2].node, yyvsp[0].node);;
break;}
-case 283:
-#line 1262 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 286:
+#line 1486 "./parse.y"
{
- yyval.node = complete_for_loop (0, NULL_TREE, yyvsp[-2].node, yyvsp[0].node);
+ yyval.node = finish_for_loop (0, NULL_TREE, yyvsp[-2].node, yyvsp[0].node);
/* We have not condition, so we get rid of the EXIT_EXPR */
LOOP_EXPR_BODY_CONDITION_EXPR (LOOP_EXPR_BODY (yyval.node), 0) =
- size_zero_node;
+ empty_stmt_node;
;
break;}
-case 284:
-#line 1272 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 287:
+#line 1496 "./parse.y"
{
/* This scope defined for local variable that may be
defined within the scope of the for loop */
enter_block ();
;
break;}
-case 285:
-#line 1278 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 288:
+#line 1502 "./parse.y"
{yyerror ("'(' expected"); DRECOVER(for_1);;
break;}
-case 286:
-#line 1280 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 289:
+#line 1504 "./parse.y"
{yyerror ("Invalid init statement"); RECOVER;;
break;}
-case 287:
-#line 1285 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 290:
+#line 1509 "./parse.y"
{
/* We now declare the loop body. The loop is
declared as a for loop. */
@@ -3627,489 +3799,599 @@ case 287:
java_method_add_stmt (current_function_decl, yyval.node);
;
break;}
-case 288:
-#line 1297 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{ yyval.node = size_zero_node; ;
+case 291:
+#line 1521 "./parse.y"
+{ yyval.node = empty_stmt_node; ;
break;}
-case 289:
-#line 1299 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 292:
+#line 1523 "./parse.y"
{
/* Init statement recorded within the previously
defined block scope */
yyval.node = java_method_add_stmt (current_function_decl, yyvsp[0].node);
;
break;}
-case 290:
-#line 1305 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 293:
+#line 1529 "./parse.y"
{
/* Local variable are recorded within the previously
defined block scope */
yyval.node = NULL_TREE;
;
break;}
-case 291:
-#line 1311 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 294:
+#line 1535 "./parse.y"
{yyerror ("';' expected"); DRECOVER(for_init_1);;
break;}
-case 292:
-#line 1315 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{yyval.node = size_zero_node;;
+case 295:
+#line 1539 "./parse.y"
+{yyval.node = empty_stmt_node;;
break;}
-case 293:
-#line 1317 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 296:
+#line 1541 "./parse.y"
{ yyval.node = build_debugable_stmt (BUILD_LOCATION (), yyvsp[0].node); ;
break;}
-case 294:
-#line 1322 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 297:
+#line 1546 "./parse.y"
{ yyval.node = add_stmt_to_compound (NULL_TREE, NULL_TREE, yyvsp[0].node); ;
break;}
-case 295:
-#line 1324 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 298:
+#line 1548 "./parse.y"
{ yyval.node = add_stmt_to_compound (yyvsp[-2].node, NULL_TREE, yyvsp[0].node); ;
break;}
-case 296:
-#line 1326 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 299:
+#line 1550 "./parse.y"
{yyerror ("Missing term"); RECOVER;;
break;}
-case 297:
-#line 1331 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 300:
+#line 1555 "./parse.y"
{ yyval.node = build_bc_statement (yyvsp[-1].operator.location, 1, NULL_TREE); ;
break;}
-case 298:
-#line 1333 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 301:
+#line 1557 "./parse.y"
{ yyval.node = build_bc_statement (yyvsp[-2].operator.location, 1, yyvsp[-1].node); ;
break;}
-case 299:
-#line 1335 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 302:
+#line 1559 "./parse.y"
{yyerror ("Missing term"); RECOVER;;
break;}
-case 300:
-#line 1337 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 303:
+#line 1561 "./parse.y"
{yyerror ("';' expected"); RECOVER;;
break;}
-case 301:
-#line 1342 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 304:
+#line 1566 "./parse.y"
{ yyval.node = build_bc_statement (yyvsp[-1].operator.location, 0, NULL_TREE); ;
break;}
-case 302:
-#line 1344 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 305:
+#line 1568 "./parse.y"
{ yyval.node = build_bc_statement (yyvsp[-2].operator.location, 0, yyvsp[-1].node); ;
break;}
-case 303:
-#line 1346 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 306:
+#line 1570 "./parse.y"
{yyerror ("Missing term"); RECOVER;;
break;}
-case 304:
-#line 1348 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 307:
+#line 1572 "./parse.y"
{yyerror ("';' expected"); RECOVER;;
break;}
-case 305:
-#line 1353 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 308:
+#line 1577 "./parse.y"
{ yyval.node = build_return (yyvsp[-1].operator.location, NULL_TREE); ;
break;}
-case 306:
-#line 1355 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 309:
+#line 1579 "./parse.y"
{ yyval.node = build_return (yyvsp[-2].operator.location, yyvsp[-1].node); ;
break;}
-case 307:
-#line 1357 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 310:
+#line 1581 "./parse.y"
{yyerror ("Missing term"); RECOVER;;
break;}
-case 308:
-#line 1359 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 311:
+#line 1583 "./parse.y"
{yyerror ("';' expected"); RECOVER;;
break;}
-case 310:
-#line 1365 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 312:
+#line 1588 "./parse.y"
+{
+ yyval.node = build1 (THROW_EXPR, NULL_TREE, yyvsp[-1].node);
+ EXPR_WFL_LINECOL (yyval.node) = yyvsp[-2].operator.location;
+ ;
+ break;}
+case 313:
+#line 1593 "./parse.y"
{yyerror ("Missing term"); RECOVER;;
break;}
-case 311:
-#line 1367 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 314:
+#line 1595 "./parse.y"
{yyerror ("';' expected"); RECOVER;;
break;}
-case 313:
-#line 1373 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 315:
+#line 1600 "./parse.y"
+{
+ yyval.node = build (SYNCHRONIZED_EXPR, NULL_TREE, yyvsp[-2].node, yyvsp[0].node);
+ EXPR_WFL_LINECOL (yyval.node) =
+ EXPR_WFL_LINECOL (MODIFIER_WFL (SYNCHRONIZED_TK));
+ ;
+ break;}
+case 316:
+#line 1606 "./parse.y"
{yyerror ("'{' expected"); RECOVER;;
break;}
-case 314:
-#line 1375 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 317:
+#line 1608 "./parse.y"
{yyerror ("'(' expected"); RECOVER;;
break;}
-case 315:
-#line 1377 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 318:
+#line 1610 "./parse.y"
{yyerror ("Missing term"); RECOVER;;
break;}
-case 316:
-#line 1379 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 319:
+#line 1612 "./parse.y"
{yyerror ("Missing term"); RECOVER;;
break;}
-case 317:
-#line 1384 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 320:
+#line 1617 "./parse.y"
{
- SOURCE_FRONTEND_DEBUG (("Modifiers: %d", yyvsp[0].value));
+ if ((1 << yyvsp[0].value) != ACC_SYNCHRONIZED)
+ fatal ("synchronized was '%d' - yyparse", (1 << yyvsp[0].value));
;
break;}
case 321:
-#line 1394 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{yyerror ("'{' expected"); DRECOVER (try_statement);;
+#line 1625 "./parse.y"
+{ yyval.node = build_try_statement (yyvsp[-2].operator.location, yyvsp[-1].node, yyvsp[0].node); ;
+ break;}
+case 322:
+#line 1627 "./parse.y"
+{ yyval.node = build_try_finally_statement (yyvsp[-2].operator.location, yyvsp[-1].node, yyvsp[0].node); ;
+ break;}
+case 323:
+#line 1629 "./parse.y"
+{ yyval.node = build_try_finally_statement
+ (yyvsp[-3].operator.location, build_try_statement (yyvsp[-3].operator.location,
+ yyvsp[-2].node, yyvsp[-1].node), yyvsp[0].node);
+ ;
break;}
-case 325:
-#line 1405 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{yyerror ("'(' expected"); RECOVER;;
+case 324:
+#line 1634 "./parse.y"
+{yyerror ("'{' expected"); DRECOVER (try_statement);;
break;}
case 326:
-#line 1407 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{yyerror ("Missing term"); DRECOVER (1);;
+#line 1640 "./parse.y"
+{
+ TREE_CHAIN (yyvsp[0].node) = yyvsp[-1].node;
+ yyval.node = yyvsp[0].node;
+ ;
break;}
case 327:
-#line 1409 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{yyerror ("Missing term"); DRECOVER (2);;
+#line 1648 "./parse.y"
+{
+ java_method_add_stmt (current_function_decl, yyvsp[0].node);
+ exit_block ();
+ yyval.node = yyvsp[-1].node;
+ ;
+ break;}
+case 328:
+#line 1656 "./parse.y"
+{
+ /* We add a block to define a scope for
+ formal_parameter (CCBP). The formal parameter is
+ declared initialized by the appropriate function
+ call */
+ tree ccpb = enter_block ();
+ tree init = build_assignment (ASSIGN_TK, yyvsp[-2].operator.location,
+ TREE_PURPOSE (yyvsp[-1].node),
+ soft_exceptioninfo_call_node);
+ declare_local_variables (0, TREE_VALUE (yyvsp[-1].node),
+ build_tree_list (TREE_PURPOSE (yyvsp[-1].node),
+ init));
+ yyval.node = build1 (CATCH_EXPR, NULL_TREE, ccpb);
+ EXPR_WFL_LINECOL (yyval.node) = yyvsp[-3].operator.location;
+ ;
break;}
case 329:
-#line 1415 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{yyerror ("'{' expected"); RECOVER; ;
+#line 1672 "./parse.y"
+{yyerror ("'(' expected"); RECOVER;;
+ break;}
+case 330:
+#line 1674 "./parse.y"
+{yyerror ("Missing term or ')' expected"); DRECOVER (2);;
+ break;}
+case 331:
+#line 1676 "./parse.y"
+{yyerror ("')' expected"); DRECOVER (1);;
+ break;}
+case 332:
+#line 1681 "./parse.y"
+{ yyval.node = yyvsp[0].node; ;
break;}
case 333:
-#line 1427 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+#line 1683 "./parse.y"
+{yyerror ("'{' expected"); RECOVER; ;
+ break;}
+case 337:
+#line 1695 "./parse.y"
{ yyval.node = build_this (yyvsp[0].operator.location); ;
break;}
-case 334:
-#line 1429 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 338:
+#line 1697 "./parse.y"
{yyval.node = yyvsp[-1].node;;
break;}
case 343:
-#line 1445 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{yyerror ("')' expected"); RECOVER;;
+#line 1706 "./parse.y"
+{ yyval.node = parse_jdk1_1_error ("named class literals"); ;
break;}
case 344:
-#line 1447 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{yyerror ("'class' or 'this' expected" ); RECOVER;;
+#line 1708 "./parse.y"
+{ yyval.node = build_class_ref (yyvsp[-2].node); ;
break;}
case 345:
-#line 1449 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{yyerror ("'class' expected" ); RECOVER;;
+#line 1710 "./parse.y"
+{ yyval.node = build_class_ref (void_type_node); ;
break;}
case 346:
-#line 1451 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{yyerror ("'class' expected" ); RECOVER;;
+#line 1715 "./parse.y"
+{ yyval.node = parse_jdk1_1_error ("class literals"); ;
break;}
case 347:
-#line 1456 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{
- yyval.node = build_method_invocation (yyvsp[-3].node, yyvsp[-1].node);
- TREE_SET_CODE (yyval.node, JAVA_NEW_CLASS_EXPR);
- ;
+#line 1717 "./parse.y"
+{yyerror ("')' expected"); RECOVER;;
break;}
case 348:
-#line 1461 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{
- yyval.node = build_method_invocation (yyvsp[-2].node, NULL_TREE);
- TREE_SET_CODE (yyval.node, JAVA_NEW_CLASS_EXPR);
- ;
+#line 1719 "./parse.y"
+{yyerror ("'class' or 'this' expected" ); RECOVER;;
break;}
case 349:
-#line 1469 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{yyval.node = yyvsp[-4].node;;
+#line 1721 "./parse.y"
+{yyerror ("'class' expected" ); RECOVER;;
break;}
case 350:
-#line 1471 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{yyval.node = yyvsp[-3].node;;
+#line 1723 "./parse.y"
+{yyerror ("'class' expected" ); RECOVER;;
+ break;}
+case 351:
+#line 1728 "./parse.y"
+{ yyval.node = build_new_invocation (yyvsp[-3].node, yyvsp[-1].node); ;
break;}
-case 355:
-#line 1480 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 352:
+#line 1730 "./parse.y"
+{ yyval.node = build_new_invocation (yyvsp[-2].node, NULL_TREE); ;
+ break;}
+case 353:
+#line 1735 "./parse.y"
+{ yyval.node = parse_jdk1_1_error ("inner class instance creation"); ;
+ break;}
+case 354:
+#line 1737 "./parse.y"
+{ yyval.node = parse_jdk1_1_error ("inner class instance creation"); ;
+ break;}
+case 359:
+#line 1746 "./parse.y"
{yyerror ("'(' expected"); DRECOVER(new_1);;
break;}
-case 356:
-#line 1482 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 360:
+#line 1748 "./parse.y"
{yyerror ("'(' expected"); RECOVER;;
break;}
-case 357:
-#line 1484 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 361:
+#line 1750 "./parse.y"
{yyerror ("')' or term expected"); RECOVER;;
break;}
-case 358:
-#line 1486 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 362:
+#line 1752 "./parse.y"
{yyerror ("')' expected"); RECOVER;;
break;}
-case 359:
-#line 1488 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 363:
+#line 1754 "./parse.y"
{YYERROR_NOW; yyerror ("Identifier expected"); RECOVER;;
break;}
-case 360:
-#line 1490 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 364:
+#line 1756 "./parse.y"
{yyerror ("'(' expected"); RECOVER;;
break;}
-case 363:
-#line 1500 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 367:
+#line 1766 "./parse.y"
{
yyval.node = tree_cons (NULL_TREE, yyvsp[0].node, NULL_TREE);
ctxp->formal_parameter_number = 1;
;
break;}
-case 364:
-#line 1505 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 368:
+#line 1771 "./parse.y"
{
ctxp->formal_parameter_number += 1;
yyval.node = tree_cons (NULL_TREE, yyvsp[0].node, yyvsp[-2].node);
;
break;}
-case 365:
-#line 1510 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 369:
+#line 1776 "./parse.y"
{yyerror ("Missing term"); RECOVER;;
break;}
-case 366:
-#line 1515 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 370:
+#line 1781 "./parse.y"
{ yyval.node = build_newarray_node (yyvsp[-1].node, yyvsp[0].node, 0); ;
break;}
-case 367:
-#line 1517 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 371:
+#line 1783 "./parse.y"
{ yyval.node = build_newarray_node (yyvsp[-1].node, yyvsp[0].node, 0); ;
break;}
-case 368:
-#line 1519 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{ yyval.node = build_newarray_node (yyvsp[-2].node, yyvsp[-1].node, ctxp->osb_number); ;
+case 372:
+#line 1785 "./parse.y"
+{ yyval.node = build_newarray_node (yyvsp[-2].node, yyvsp[-1].node, CURRENT_OSB (ctxp));;
break;}
-case 369:
-#line 1521 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{ yyval.node = build_newarray_node (yyvsp[-2].node, yyvsp[-1].node, ctxp->osb_number); ;
+case 373:
+#line 1787 "./parse.y"
+{ yyval.node = build_newarray_node (yyvsp[-2].node, yyvsp[-1].node, CURRENT_OSB (ctxp));;
break;}
-case 370:
-#line 1525 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{yyval.node = yyvsp[-2].node;;
+case 374:
+#line 1791 "./parse.y"
+{ yyval.node = parse_jdk1_1_error ("anonymous array"); ;
break;}
-case 371:
-#line 1527 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{yyval.node = yyvsp[-2].node;;
+case 375:
+#line 1793 "./parse.y"
+{ yyval.node = parse_jdk1_1_error ("anonymous array"); ;
break;}
-case 372:
-#line 1529 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 376:
+#line 1795 "./parse.y"
{yyerror ("'[' expected"); DRECOVER ("]");;
break;}
-case 373:
-#line 1531 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 377:
+#line 1797 "./parse.y"
{yyerror ("']' expected"); RECOVER;;
break;}
-case 374:
-#line 1536 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 378:
+#line 1802 "./parse.y"
{ yyval.node = build_tree_list (NULL_TREE, yyvsp[0].node); ;
break;}
-case 375:
-#line 1538 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 379:
+#line 1804 "./parse.y"
{ yyval.node = tree_cons (NULL_TREE, yyvsp[0].node, yyval.node); ;
break;}
-case 376:
-#line 1543 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 380:
+#line 1809 "./parse.y"
{
EXPR_WFL_LINECOL (yyvsp[-1].node) = yyvsp[-2].operator.location;
yyval.node = yyvsp[-1].node;
;
break;}
-case 377:
-#line 1548 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 381:
+#line 1814 "./parse.y"
{yyerror ("']' expected"); RECOVER;;
break;}
-case 378:
-#line 1550 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 382:
+#line 1816 "./parse.y"
{
yyerror ("Missing term");
yyerror ("']' expected");
RECOVER;
;
break;}
-case 379:
-#line 1559 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{ ctxp->osb_number = 1; ;
+case 383:
+#line 1825 "./parse.y"
+{
+ int allocate = 0;
+ /* If not initialized, allocate memory for the osb
+ numbers stack */
+ if (!ctxp->osb_limit)
+ {
+ allocate = ctxp->osb_limit = 32;
+ ctxp->osb_depth = -1;
+ }
+ /* If capacity overflown, reallocate a bigger chuck */
+ else if (ctxp->osb_depth+1 == ctxp->osb_limit)
+ allocate = ctxp->osb_limit << 1;
+
+ if (allocate)
+ {
+ allocate *= sizeof (int);
+ if (ctxp->osb_number)
+ ctxp->osb_number = (int *)xrealloc (ctxp->osb_number,
+ allocate);
+ else
+ ctxp->osb_number = (int *)xmalloc (allocate);
+ }
+ ctxp->osb_depth++;
+ CURRENT_OSB (ctxp) = 1;
+ ;
break;}
-case 380:
-#line 1561 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{ ctxp->osb_number++; ;
+case 384:
+#line 1851 "./parse.y"
+{ CURRENT_OSB (ctxp)++; ;
break;}
-case 381:
-#line 1563 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 385:
+#line 1853 "./parse.y"
{ yyerror ("']' expected"); RECOVER;;
break;}
-case 382:
-#line 1568 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 386:
+#line 1858 "./parse.y"
{ yyval.node = make_qualified_primary (yyvsp[-2].node, yyvsp[0].node, yyvsp[-1].operator.location); ;
break;}
-case 383:
-#line 1570 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 387:
+#line 1862 "./parse.y"
{
tree super_wfl =
- build_wfl_node (super_identifier_node, input_filename, 0, 0);
+ build_wfl_node (super_identifier_node);
EXPR_WFL_LINECOL (super_wfl) = yyvsp[-2].operator.location;
yyval.node = make_qualified_name (super_wfl, yyvsp[0].node, yyvsp[-1].operator.location);
;
break;}
-case 384:
-#line 1577 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 388:
+#line 1869 "./parse.y"
{yyerror ("Field expected"); DRECOVER (super_field_acces);;
break;}
-case 385:
-#line 1582 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 389:
+#line 1874 "./parse.y"
{ yyval.node = build_method_invocation (yyvsp[-2].node, NULL_TREE); ;
break;}
-case 386:
-#line 1584 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 390:
+#line 1876 "./parse.y"
{ yyval.node = build_method_invocation (yyvsp[-3].node, yyvsp[-1].node); ;
break;}
-case 387:
-#line 1586 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 391:
+#line 1878 "./parse.y"
{
- tree invok = build_method_invocation (yyvsp[-2].node, NULL_TREE);
- yyval.node = make_qualified_primary (yyvsp[-4].node, invok, yyvsp[-3].operator.location);
+ if (TREE_CODE (yyvsp[-4].node) == THIS_EXPR)
+ yyval.node = build_this_super_qualified_invocation
+ (1, yyvsp[-2].node, NULL_TREE, 0, yyvsp[-3].operator.location);
+ else
+ {
+ tree invok = build_method_invocation (yyvsp[-2].node, NULL_TREE);
+ yyval.node = make_qualified_primary (yyvsp[-4].node, invok, yyvsp[-3].operator.location);
+ }
;
break;}
-case 388:
-#line 1591 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 392:
+#line 1889 "./parse.y"
{
- tree invok = build_method_invocation (yyvsp[-3].node, yyvsp[-1].node);
- yyval.node = make_qualified_primary (yyvsp[-5].node, invok, yyvsp[-4].operator.location);
+ if (TREE_CODE (yyvsp[-5].node) == THIS_EXPR)
+ yyval.node = build_this_super_qualified_invocation
+ (1, yyvsp[-3].node, yyvsp[-1].node, 0, yyvsp[-4].operator.location);
+ else
+ {
+ tree invok = build_method_invocation (yyvsp[-3].node, yyvsp[-1].node);
+ yyval.node = make_qualified_primary (yyvsp[-5].node, invok, yyvsp[-4].operator.location);
+ }
;
break;}
-case 389:
-#line 1596 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
-{
- tree invok;
- tree wfl = build_wfl_node (super_identifier_node, input_filename, 0, 0);
- EXPR_WFL_LINECOL (wfl) = yyvsp[-4].operator.location;
- invok = build_method_invocation (yyvsp[-2].node, NULL_TREE);
- yyval.node = make_qualified_primary (wfl, invok, yyvsp[-3].operator.location);
+case 393:
+#line 1900 "./parse.y"
+{
+ yyval.node = build_this_super_qualified_invocation
+ (0, yyvsp[-2].node, NULL_TREE, yyvsp[-4].operator.location, yyvsp[-3].operator.location);
;
break;}
-case 390:
-#line 1604 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 394:
+#line 1905 "./parse.y"
{
- tree invok;
- tree wfl = build_wfl_node (super_identifier_node, input_filename, 0, 0);
- EXPR_WFL_LINECOL (wfl) = yyvsp[-5].operator.location;
- invok = build_method_invocation (yyvsp[-3].node, yyvsp[-1].node);
- yyval.node = make_qualified_primary (wfl, invok, yyvsp[-4].operator.location);
+ yyval.node = build_this_super_qualified_invocation
+ (0, yyvsp[-3].node, yyvsp[-1].node, yyvsp[-5].operator.location, yyvsp[-4].operator.location);
;
break;}
-case 391:
-#line 1616 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 395:
+#line 1914 "./parse.y"
{ yyerror ("'(' expected"); DRECOVER (method_invocation); ;
break;}
-case 392:
-#line 1618 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 396:
+#line 1916 "./parse.y"
{ yyerror ("'(' expected"); DRECOVER (method_invocation); ;
break;}
-case 393:
-#line 1623 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 397:
+#line 1921 "./parse.y"
{ yyval.node = build_array_ref (yyvsp[-2].operator.location, yyvsp[-3].node, yyvsp[-1].node); ;
break;}
-case 394:
-#line 1625 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 398:
+#line 1923 "./parse.y"
{ yyval.node = build_array_ref (yyvsp[-2].operator.location, yyvsp[-3].node, yyvsp[-1].node); ;
break;}
-case 395:
-#line 1627 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 399:
+#line 1925 "./parse.y"
{
yyerror ("Missing term and ']' expected");
DRECOVER(array_access);
;
break;}
-case 396:
-#line 1632 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 400:
+#line 1930 "./parse.y"
{
yyerror ("']' expected");
DRECOVER(array_access);
;
break;}
-case 397:
-#line 1637 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 401:
+#line 1935 "./parse.y"
{
yyerror ("Missing term and ']' expected");
DRECOVER(array_access);
;
break;}
-case 398:
-#line 1642 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 402:
+#line 1940 "./parse.y"
{
yyerror ("']' expected");
DRECOVER(array_access);
;
break;}
-case 403:
-#line 1657 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 407:
+#line 1955 "./parse.y"
{ yyval.node = build_incdec (yyvsp[0].operator.token, yyvsp[0].operator.location, yyvsp[-1].node, 1); ;
break;}
-case 404:
-#line 1662 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 408:
+#line 1960 "./parse.y"
{ yyval.node = build_incdec (yyvsp[0].operator.token, yyvsp[0].operator.location, yyvsp[-1].node, 1); ;
break;}
-case 407:
-#line 1669 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 411:
+#line 1967 "./parse.y"
{yyval.node = build_unaryop (yyvsp[-1].operator.token, yyvsp[-1].operator.location, yyvsp[0].node); ;
break;}
-case 408:
-#line 1671 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 412:
+#line 1969 "./parse.y"
{yyval.node = build_unaryop (yyvsp[-1].operator.token, yyvsp[-1].operator.location, yyvsp[0].node); ;
break;}
-case 410:
-#line 1674 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 414:
+#line 1972 "./parse.y"
{yyerror ("Missing term"); RECOVER;
break;}
-case 411:
-#line 1676 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 415:
+#line 1974 "./parse.y"
{yyerror ("Missing term"); RECOVER;
break;}
-case 412:
-#line 1681 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 416:
+#line 1979 "./parse.y"
{yyval.node = build_incdec (yyvsp[-1].operator.token, yyvsp[-1].operator.location, yyvsp[0].node, 0); ;
break;}
-case 413:
-#line 1683 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 417:
+#line 1981 "./parse.y"
{yyerror ("Missing term"); RECOVER;
break;}
-case 414:
-#line 1688 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 418:
+#line 1986 "./parse.y"
{yyval.node = build_incdec (yyvsp[-1].operator.token, yyvsp[-1].operator.location, yyvsp[0].node, 0); ;
break;}
-case 415:
-#line 1690 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 419:
+#line 1988 "./parse.y"
{yyerror ("Missing term"); RECOVER;
break;}
-case 417:
-#line 1696 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 421:
+#line 1994 "./parse.y"
{yyval.node = build_unaryop (yyvsp[-1].operator.token, yyvsp[-1].operator.location, yyvsp[0].node); ;
break;}
-case 418:
-#line 1698 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 422:
+#line 1996 "./parse.y"
{yyval.node = build_unaryop (yyvsp[-1].operator.token, yyvsp[-1].operator.location, yyvsp[0].node); ;
break;}
-case 420:
-#line 1701 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 424:
+#line 1999 "./parse.y"
{yyerror ("Missing term"); RECOVER;
break;}
-case 421:
-#line 1703 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 425:
+#line 2001 "./parse.y"
{yyerror ("Missing term"); RECOVER;
break;}
-case 422:
-#line 1708 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 426:
+#line 2006 "./parse.y"
{
tree type = yyvsp[-3].node;
- while (ctxp->osb_number--)
+ while (CURRENT_OSB (ctxp)--)
type = build_java_array_type (type, -1);
+ ctxp->osb_depth--;
yyval.node = build_cast (yyvsp[-4].operator.location, type, yyvsp[0].node);
;
break;}
-case 423:
-#line 1715 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 427:
+#line 2014 "./parse.y"
{ yyval.node = build_cast (yyvsp[-3].operator.location, yyvsp[-2].node, yyvsp[0].node); ;
break;}
-case 424:
-#line 1717 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 428:
+#line 2016 "./parse.y"
{ yyval.node = build_cast (yyvsp[-3].operator.location, yyvsp[-2].node, yyvsp[0].node); ;
break;}
-case 425:
-#line 1719 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 429:
+#line 2018 "./parse.y"
{
char *ptr;
- while (ctxp->osb_number--)
+ while (CURRENT_OSB (ctxp)--)
obstack_1grow (&temporary_obstack, '[');
+ ctxp->osb_depth--;
obstack_grow0 (&temporary_obstack,
IDENTIFIER_POINTER (EXPR_WFL_NODE (yyvsp[-3].node)),
IDENTIFIER_LENGTH (EXPR_WFL_NODE (yyvsp[-3].node)));
@@ -4118,265 +4400,276 @@ case 425:
yyval.node = build_cast (yyvsp[-4].operator.location, yyvsp[-3].node, yyvsp[0].node);
;
break;}
-case 426:
-#line 1731 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 430:
+#line 2031 "./parse.y"
{yyerror ("']' expected, invalid type expression");;
break;}
-case 427:
-#line 1733 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 431:
+#line 2033 "./parse.y"
{
if (ctxp->prevent_ese != lineno)
yyerror ("Invalid type expression"); RECOVER;
RECOVER;
;
break;}
-case 428:
-#line 1739 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 432:
+#line 2039 "./parse.y"
{yyerror ("Missing term"); RECOVER;;
break;}
-case 429:
-#line 1741 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 433:
+#line 2041 "./parse.y"
{yyerror ("Missing term"); RECOVER;;
break;}
-case 430:
-#line 1743 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 434:
+#line 2043 "./parse.y"
{yyerror ("Missing term"); RECOVER;;
break;}
-case 432:
-#line 1749 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 436:
+#line 2049 "./parse.y"
{
yyval.node = build_binop (BINOP_LOOKUP (yyvsp[-1].operator.token),
yyvsp[-1].operator.location, yyvsp[-2].node, yyvsp[0].node);
;
break;}
-case 433:
-#line 1754 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 437:
+#line 2054 "./parse.y"
{
yyval.node = build_binop (BINOP_LOOKUP (yyvsp[-1].operator.token), yyvsp[-1].operator.location,
yyvsp[-2].node, yyvsp[0].node);
;
break;}
-case 434:
-#line 1759 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 438:
+#line 2059 "./parse.y"
{
yyval.node = build_binop (BINOP_LOOKUP (yyvsp[-1].operator.token), yyvsp[-1].operator.location,
yyvsp[-2].node, yyvsp[0].node);
;
break;}
-case 435:
-#line 1764 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 439:
+#line 2064 "./parse.y"
{yyerror ("Missing term"); RECOVER;;
break;}
-case 436:
-#line 1766 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 440:
+#line 2066 "./parse.y"
{yyerror ("Missing term"); RECOVER;;
break;}
-case 437:
-#line 1768 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 441:
+#line 2068 "./parse.y"
{yyerror ("Missing term"); RECOVER;;
break;}
-case 439:
-#line 1774 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 443:
+#line 2074 "./parse.y"
{
yyval.node = build_binop (BINOP_LOOKUP (yyvsp[-1].operator.token), yyvsp[-1].operator.location,
yyvsp[-2].node, yyvsp[0].node);
;
break;}
-case 440:
-#line 1779 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 444:
+#line 2079 "./parse.y"
{
yyval.node = build_binop (BINOP_LOOKUP (yyvsp[-1].operator.token), yyvsp[-1].operator.location,
yyvsp[-2].node, yyvsp[0].node);
;
break;}
-case 441:
-#line 1784 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 445:
+#line 2084 "./parse.y"
{yyerror ("Missing term"); RECOVER;;
break;}
-case 442:
-#line 1786 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 446:
+#line 2086 "./parse.y"
{yyerror ("Missing term"); RECOVER;;
break;}
-case 444:
-#line 1792 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 448:
+#line 2092 "./parse.y"
{
yyval.node = build_binop (BINOP_LOOKUP (yyvsp[-1].operator.token), yyvsp[-1].operator.location,
yyvsp[-2].node, yyvsp[0].node);
;
break;}
-case 445:
-#line 1797 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 449:
+#line 2097 "./parse.y"
{
yyval.node = build_binop (BINOP_LOOKUP (yyvsp[-1].operator.token), yyvsp[-1].operator.location,
yyvsp[-2].node, yyvsp[0].node);
;
break;}
-case 446:
-#line 1802 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 450:
+#line 2102 "./parse.y"
{
yyval.node = build_binop (BINOP_LOOKUP (yyvsp[-1].operator.token), yyvsp[-1].operator.location,
yyvsp[-2].node, yyvsp[0].node);
;
break;}
-case 447:
-#line 1807 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 451:
+#line 2107 "./parse.y"
{yyerror ("Missing term"); RECOVER;;
break;}
-case 448:
-#line 1809 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 452:
+#line 2109 "./parse.y"
{yyerror ("Missing term"); RECOVER;;
break;}
-case 449:
-#line 1811 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 453:
+#line 2111 "./parse.y"
{yyerror ("Missing term"); RECOVER;;
break;}
-case 451:
-#line 1817 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 455:
+#line 2117 "./parse.y"
{
yyval.node = build_binop (BINOP_LOOKUP (yyvsp[-1].operator.token), yyvsp[-1].operator.location,
yyvsp[-2].node, yyvsp[0].node);
;
break;}
-case 452:
-#line 1822 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 456:
+#line 2122 "./parse.y"
{
yyval.node = build_binop (BINOP_LOOKUP (yyvsp[-1].operator.token), yyvsp[-1].operator.location,
yyvsp[-2].node, yyvsp[0].node);
;
break;}
-case 453:
-#line 1827 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 457:
+#line 2127 "./parse.y"
{
yyval.node = build_binop (BINOP_LOOKUP (yyvsp[-1].operator.token), yyvsp[-1].operator.location,
yyvsp[-2].node, yyvsp[0].node);
;
break;}
-case 454:
-#line 1832 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 458:
+#line 2132 "./parse.y"
{
yyval.node = build_binop (BINOP_LOOKUP (yyvsp[-1].operator.token), yyvsp[-1].operator.location,
yyvsp[-2].node, yyvsp[0].node);
;
break;}
-case 456:
-#line 1838 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 459:
+#line 2137 "./parse.y"
+{ yyval.node = build_binop (INSTANCEOF_EXPR, yyvsp[-1].operator.location, yyvsp[-2].node, yyvsp[0].node); ;
+ break;}
+case 460:
+#line 2139 "./parse.y"
{yyerror ("Missing term"); RECOVER;;
break;}
-case 457:
-#line 1840 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 461:
+#line 2141 "./parse.y"
{yyerror ("Missing term"); RECOVER;;
break;}
-case 458:
-#line 1842 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 462:
+#line 2143 "./parse.y"
{yyerror ("Missing term"); RECOVER;;
break;}
-case 459:
-#line 1844 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 463:
+#line 2145 "./parse.y"
{yyerror ("Missing term"); RECOVER;;
break;}
-case 460:
-#line 1846 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 464:
+#line 2147 "./parse.y"
{yyerror ("Invalid reference type"); RECOVER;;
break;}
-case 462:
-#line 1852 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 466:
+#line 2153 "./parse.y"
{
yyval.node = build_binop (BINOP_LOOKUP (yyvsp[-1].operator.token), yyvsp[-1].operator.location,
yyvsp[-2].node, yyvsp[0].node);
;
break;}
-case 463:
-#line 1857 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 467:
+#line 2158 "./parse.y"
{
yyval.node = build_binop (BINOP_LOOKUP (yyvsp[-1].operator.token), yyvsp[-1].operator.location,
yyvsp[-2].node, yyvsp[0].node);
;
break;}
-case 464:
-#line 1862 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 468:
+#line 2163 "./parse.y"
{yyerror ("Missing term"); RECOVER;;
break;}
-case 465:
-#line 1864 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 469:
+#line 2165 "./parse.y"
{yyerror ("Missing term"); RECOVER;;
break;}
-case 467:
-#line 1870 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 471:
+#line 2171 "./parse.y"
{
yyval.node = build_binop (BINOP_LOOKUP (yyvsp[-1].operator.token), yyvsp[-1].operator.location,
yyvsp[-2].node, yyvsp[0].node);
;
break;}
-case 468:
-#line 1875 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 472:
+#line 2176 "./parse.y"
{yyerror ("Missing term"); RECOVER;;
break;}
-case 470:
-#line 1881 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 474:
+#line 2182 "./parse.y"
{
yyval.node = build_binop (BINOP_LOOKUP (yyvsp[-1].operator.token), yyvsp[-1].operator.location,
yyvsp[-2].node, yyvsp[0].node);
;
break;}
-case 471:
-#line 1886 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 475:
+#line 2187 "./parse.y"
{yyerror ("Missing term"); RECOVER;;
break;}
-case 473:
-#line 1892 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 477:
+#line 2193 "./parse.y"
{
yyval.node = build_binop (BINOP_LOOKUP (yyvsp[-1].operator.token), yyvsp[-1].operator.location,
yyvsp[-2].node, yyvsp[0].node);
;
break;}
-case 474:
-#line 1897 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 478:
+#line 2198 "./parse.y"
{yyerror ("Missing term"); RECOVER;;
break;}
-case 476:
-#line 1903 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 480:
+#line 2204 "./parse.y"
{
yyval.node = build_binop (BINOP_LOOKUP (yyvsp[-1].operator.token), yyvsp[-1].operator.location,
yyvsp[-2].node, yyvsp[0].node);
;
break;}
-case 477:
-#line 1908 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 481:
+#line 2209 "./parse.y"
{yyerror ("Missing term"); RECOVER;;
break;}
-case 479:
-#line 1914 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 483:
+#line 2215 "./parse.y"
{
yyval.node = build_binop (BINOP_LOOKUP (yyvsp[-1].operator.token), yyvsp[-1].operator.location,
yyvsp[-2].node, yyvsp[0].node);
;
break;}
-case 480:
-#line 1919 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 484:
+#line 2220 "./parse.y"
{yyerror ("Missing term"); RECOVER;;
break;}
-case 483:
-#line 1926 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 486:
+#line 2226 "./parse.y"
+{
+ yyval.node = build (CONDITIONAL_EXPR, NULL_TREE, yyvsp[-4].node, yyvsp[-2].node, yyvsp[0].node);
+ EXPR_WFL_LINECOL (yyval.node) = yyvsp[-3].operator.location;
+ ;
+ break;}
+case 487:
+#line 2231 "./parse.y"
{
YYERROR_NOW;
yyerror ("Missing term");
DRECOVER (1);
;
break;}
-case 484:
-#line 1932 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 488:
+#line 2237 "./parse.y"
{yyerror ("Missing term"); DRECOVER (2);;
break;}
-case 485:
-#line 1934 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 489:
+#line 2239 "./parse.y"
{yyerror ("Missing term"); DRECOVER (3);;
break;}
-case 488:
-#line 1944 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 492:
+#line 2249 "./parse.y"
{ yyval.node = build_assignment (yyvsp[-1].operator.token, yyvsp[-1].operator.location, yyvsp[-2].node, yyvsp[0].node); ;
break;}
-case 489:
-#line 1946 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+case 493:
+#line 2251 "./parse.y"
{
if (ctxp->prevent_ese != lineno)
yyerror ("Missing term");
@@ -4385,7 +4678,7 @@ case 489:
break;}
}
/* the action file gets copied in in place of this dollarsign */
-#line 498 "/usr/cygnus/gnupro-98r1/share/bison.simple"
+#line 498 "/usr/lib/bison.simple"
yyvsp -= yylen;
yyssp -= yylen;
@@ -4581,12 +4874,10 @@ yyerrhandle:
yystate = yyn;
goto yynewstate;
}
-#line 1972 "/nfs/hoser/beer/java/egcs/gcc/java/parse.y"
+#line 2277 "./parse.y"
-#include "lex.c"
-
/* Flag for the error report routine to issue the error the first time
it's called (overriding the default behavior which is to drop the
first invocation and honor the second one, taking advantage of a
@@ -4599,18 +4890,32 @@ void
java_push_parser_context ()
{
struct parser_ctxt *new =
- (struct parser_ctxt *)malloc(sizeof (struct parser_ctxt));
+ (struct parser_ctxt *)xmalloc(sizeof (struct parser_ctxt));
bzero (new, sizeof (struct parser_ctxt));
new->next = ctxp;
ctxp = new;
if (ctxp->next)
- ctxp->incomplete_class = ctxp->next->incomplete_class;
+ {
+ ctxp->incomplete_class = ctxp->next->incomplete_class;
+ ctxp->gclass_list = ctxp->next->gclass_list;
+ }
}
+/* If the first file of a file list was a class file, no context
+ exists for a source file to be parsed. This boolean remembers that
+ java_parser_context_save_global might have created a dummy one, so
+ that java_parser_context_restore_global can pop it. */
+static int extra_ctxp_pushed_p = 0;
+
void
java_parser_context_save_global ()
{
+ if (!ctxp)
+ {
+ java_push_parser_context ();
+ extra_ctxp_pushed_p = 1;
+ }
ctxp->finput = finput;
ctxp->lineno = lineno;
ctxp->current_class = current_class;
@@ -4626,18 +4931,29 @@ java_parser_context_restore_global ()
current_class = ctxp->current_class;
input_filename = ctxp->filename;
current_function_decl = ctxp->current_function_decl;
+ if (!ctxp->next && extra_ctxp_pushed_p)
+ {
+ java_pop_parser_context (0);
+ extra_ctxp_pushed_p = 0;
+ }
}
void
-java_pop_parser_context ()
+java_pop_parser_context (generate)
+ int generate;
{
tree current;
- struct parser_ctxt *toFree = ctxp;
- struct parser_ctxt *next = ctxp->next;
+ struct parser_ctxt *toFree, *next;
+
+ if (!ctxp)
+ return;
+ toFree = ctxp;
+ next = ctxp->next;
if (next)
{
next->incomplete_class = ctxp->incomplete_class;
+ next->gclass_list = ctxp->gclass_list;
lineno = ctxp->lineno;
finput = ctxp->finput;
current_class = ctxp->current_class;
@@ -4649,11 +4965,28 @@ java_pop_parser_context ()
IS_A_SINGLE_IMPORT_CLASSFILE_NAME_P (TREE_PURPOSE (current)) = 0;
/* And restore those of the previous context */
- if (ctxp = next)
+ if ((ctxp = next)) /* Assignment is really meant here */
for (current = ctxp->import_list; current; current = TREE_CHAIN (current))
IS_A_SINGLE_IMPORT_CLASSFILE_NAME_P (TREE_PURPOSE (current)) = 1;
- free (toFree);
+ if (generate)
+ {
+ toFree->next = ctxp_for_generation;
+ ctxp_for_generation = toFree;
+ }
+ else
+ free (toFree);
+}
+
+/* Reporting JDK1.1 features not implemented */
+
+static tree
+parse_jdk1_1_error (msg)
+ char *msg;
+{
+ sorry (": `%s' JDK1.1(TM) feature", msg);
+ java_error_count++;
+ return empty_stmt_node;
}
static int do_warning = 0;
@@ -4666,7 +4999,7 @@ yyerror (msg)
static int prev_lineno;
static char *prev_msg;
- int i, save_lineno;
+ int save_lineno;
char *remainder, *code_from_source;
extern struct obstack temporary_obstack;
@@ -4725,68 +5058,151 @@ yyerror (msg)
}
static void
-parse_error (msg)
- char *msg;
+issue_warning_error_from_context (cl, msg, ap)
+ tree cl;
+ const char *msg;
+ va_list ap;
{
+ char *saved, *saved_input_filename;
+ char buffer [4096];
+ vsprintf (buffer, msg, ap);
+ force_error = 1;
+
+ ctxp->elc.line = EXPR_WFL_LINENO (cl);
+ ctxp->elc.col = (EXPR_WFL_COLNO (cl) == 0xfff ? -1 :
+ (EXPR_WFL_COLNO (cl) == 0xffe ? -2 : EXPR_WFL_COLNO (cl)));
+
+ /* We have a CL, that's a good reason for using it if it contains data */
+ saved = ctxp->filename;
+ if (TREE_CODE (cl) == EXPR_WITH_FILE_LOCATION && EXPR_WFL_FILENAME_NODE (cl))
+ ctxp->filename = EXPR_WFL_FILENAME (cl);
+ saved_input_filename = input_filename;
+ input_filename = ctxp->filename;
java_error (NULL);
- java_error (msg);
+ java_error (buffer);
+ ctxp->filename = saved;
+ input_filename = saved_input_filename;
+ force_error = 0;
}
/* Issue an error message at a current source line CL */
-static void
-parse_error_context VPROTO ((tree cl, char *msg, ...))
+void
+parse_error_context VPROTO ((tree cl, const char *msg, ...))
{
-#ifndef __STDC__
+#ifndef ANSI_PROTOTYPES
tree cl;
- char *msg;
+ const char *msg;
#endif
- char buffer [4096];
va_list ap;
VA_START (ap, msg);
-#ifndef __STDC__
+#ifndef ANSI_PROTOTYPES
cl = va_arg (ap, tree);
- msg = va_arg (ap, char *);
+ msg = va_arg (ap, const char *);
#endif
- vsprintf (buffer, msg, ap);
-
- force_error = 1;
- ctxp->elc.line = EXPR_WFL_LINENO (cl);
- ctxp->elc.col = (EXPR_WFL_COLNO (cl) == 0xfff ? -1 : EXPR_WFL_COLNO (cl));
-
- parse_error (buffer);
- force_error = 0;
+ issue_warning_error_from_context (cl, msg, ap);
+ va_end (ap);
}
/* Issue a warning at a current source line CL */
static void
-parse_warning_context VPROTO ((tree cl, char *msg, ...))
+parse_warning_context VPROTO ((tree cl, const char *msg, ...))
{
-#ifndef __STDC__
+#ifndef ANSI_PROTOTYPES
tree cl;
- char *msg;
+ const char *msg;
#endif
- char buffer [4096];
va_list ap;
VA_START (ap, msg);
-#ifndef __STDC__
+#ifndef ANSI_PROTOTYPES
cl = va_arg (ap, tree);
- msg = va_arg (ap, char *);
+ msg = va_arg (ap, const char *);
#endif
- vsprintf (buffer, msg, ap);
force_error = do_warning = 1;
- ctxp->elc.line = EXPR_WFL_LINENO (cl);
- ctxp->elc.col = (EXPR_WFL_COLNO (cl) == 0xfff ? -1 : EXPR_WFL_COLNO (cl));
-
- parse_error (buffer);
+ issue_warning_error_from_context (cl, msg, ap);
do_warning = force_error = 0;
+ va_end (ap);
}
-void
+static tree
+find_expr_with_wfl (node)
+ tree node;
+{
+ while (node)
+ {
+ char code;
+ tree to_return;
+
+ switch (TREE_CODE (node))
+ {
+ case BLOCK:
+ node = BLOCK_EXPR_BODY (node);
+ continue;
+
+ case COMPOUND_EXPR:
+ to_return = find_expr_with_wfl (TREE_OPERAND (node, 0));
+ if (to_return)
+ return to_return;
+ node = TREE_OPERAND (node, 1);
+ continue;
+
+ case LOOP_EXPR:
+ node = TREE_OPERAND (node, 0);
+ continue;
+
+ case LABELED_BLOCK_EXPR:
+ node = TREE_OPERAND (node, 1);
+ continue;
+
+ default:
+ code = TREE_CODE_CLASS (TREE_CODE (node));
+ if (((code == '1') || (code == '2') || (code == 'e'))
+ && EXPR_WFL_LINECOL (node))
+ return node;
+ return NULL_TREE;
+ }
+ }
+ return NULL_TREE;
+}
+
+/* Issue a missing return statement error. Uses METHOD to figure the
+ last line of the method the error occurs in. */
+
+static void
+missing_return_error (method)
+ tree method;
+{
+ EXPR_WFL_SET_LINECOL (wfl_operator, DECL_SOURCE_LINE_LAST (method), -2);
+ parse_error_context (wfl_operator, "Missing return statement");
+}
+
+/* Issue an unreachable statement error. From NODE, find the next
+ statement to report appropriately. */
+static void
+unreachable_stmt_error (node)
+ tree node;
+{
+ /* Browse node to find the next expression node that has a WFL. Use
+ the location to report the error */
+ if (TREE_CODE (node) == COMPOUND_EXPR)
+ node = find_expr_with_wfl (TREE_OPERAND (node, 1));
+ else
+ node = find_expr_with_wfl (node);
+
+ if (node)
+ {
+ EXPR_WFL_SET_LINECOL (wfl_operator, EXPR_WFL_LINENO (node), -2);
+ parse_error_context (wfl_operator, "Unreachable statement");
+ }
+ else
+ fatal ("Can't get valid statement - unreachable_stmt_error");
+}
+
+int
java_report_errors ()
{
if (java_error_count)
@@ -4797,6 +5213,7 @@ java_report_errors ()
java_warning_count, (java_warning_count == 1 ? "" : "s"));
if (java_error_count || java_warning_count)
putc ('\n', stderr);
+ return java_error_count;
}
static char *
@@ -4825,8 +5242,11 @@ java_accstring_lookup (flags)
#undef COPY_RETURN
}
+/* Issuing error messages upon redefinition of classes, interfaces or
+ variables. */
+
static void
-redefinition_error (context, id, decl, cl)
+classitf_redefinition_error (context, id, decl, cl)
char *context;
tree id, decl, cl;
{
@@ -4836,6 +5256,74 @@ redefinition_error (context, id, decl, cl)
/* Here we should point out where its redefined. It's a unicode. FIXME */
}
+static void
+variable_redefinition_error (context, name, type, line)
+ tree context, name, type;
+ int line;
+{
+ char *type_name;
+
+ /* Figure a proper name for type. We might haven't resolved it */
+ if (TREE_CODE (type) == POINTER_TYPE && !TREE_TYPE (type))
+ type_name = IDENTIFIER_POINTER (TYPE_NAME (type));
+ else
+ type_name = lang_printable_name (type, 0);
+
+ parse_error_context (context,
+ "Variable `%s' is already defined in this method and "
+ "was declared `%s %s' at line %d",
+ IDENTIFIER_POINTER (name),
+ type_name, IDENTIFIER_POINTER (name), line);
+}
+
+static tree
+build_array_from_name (type, type_wfl, name, ret_name)
+ tree type, type_wfl, name, *ret_name;
+{
+ int more_dims = 0;
+ char *string;
+
+ /* Eventually get more dims */
+ string = IDENTIFIER_POINTER (name);
+ while (string [more_dims] == '[')
+ more_dims++;
+
+ /* If we have, then craft a new type for this variable */
+ if (more_dims)
+ {
+ name = get_identifier (&string [more_dims]);
+
+ /* If we have a pointer, use its type */
+ if (TREE_CODE (type) == POINTER_TYPE)
+ type = TREE_TYPE (type);
+
+ /* Building the first dimension of a primitive type uses this
+ function */
+ if (JPRIMITIVE_TYPE_P (type))
+ {
+ type = build_java_array_type (type, -1);
+ CLASS_LOADED_P (type) = 1;
+ more_dims--;
+ }
+ /* Otherwise, if we have a WFL for this type, use it (the type
+ is already an array on an unresolved type, and we just keep
+ on adding dimensions) */
+ else if (type_wfl)
+ type = type_wfl;
+
+ /* Add all the dimensions */
+ while (more_dims--)
+ type = build_unresolved_array_type (type);
+
+ /* The type may have been incomplete in the first place */
+ if (type_wfl)
+ type = obtain_incomplete_type (type);
+ }
+
+ *ret_name = name;
+ return type;
+}
+
/* Build something that the type identifier resolver will identify as
being an array to an unresolved type. TYPE_WFL is a WFL on a
identifier. */
@@ -4846,7 +5334,7 @@ build_unresolved_array_type (type_or_wfl)
{
char *ptr;
- /* TYPE_OR_WFL might be an array on a primitive type. In this case,
+ /* TYPE_OR_WFL might be an array on a resolved type. In this case,
just create a array type */
if (TREE_CODE (type_or_wfl) == RECORD_TYPE)
{
@@ -4924,8 +5412,8 @@ check_class_interface_creation (is_interface, flags, raw_name, qualified_name, d
}
if (decl && CLASS_COMPLETE_P (decl))
{
- redefinition_error ((is_interface ? "Interface" : "Class"),
- qualified_name, decl, cl);
+ classitf_redefinition_error ((is_interface ? "Interface" : "Class"),
+ qualified_name, decl, cl);
return 1;
}
@@ -4936,8 +5424,10 @@ check_class_interface_creation (is_interface, flags, raw_name, qualified_name, d
/* Contains OS dependent assumption on path separator. FIXME */
for (f = &input_filename [strlen (input_filename)];
- f != input_filename && f[0] != '/'; f--);
- if (f[0] == '/')
+ f != input_filename && f[0] != '/' && f[0] != DIR_SEPARATOR;
+ f--)
+ ;
+ if (f[0] == '/' || f[0] == DIR_SEPARATOR)
f++;
if (strncmp (IDENTIFIER_POINTER (raw_name),
f , IDENTIFIER_LENGTH (raw_name)) ||
@@ -4963,21 +5453,30 @@ static tree
maybe_create_class_interface_decl (decl, qualified_name, cl)
tree decl, qualified_name, cl;
{
- if (decl)
- DECL_ARTIFICIAL (decl) = 1; /* FIXME */
- else
+ if (!decl)
decl = push_class (make_class (), qualified_name);
/* Take care of the file and line business */
DECL_SOURCE_FILE (decl) = EXPR_WFL_FILENAME (cl);
- DECL_SOURCE_LINE (decl) = EXPR_WFL_LINENO (cl);
+ /* If we're emiting xrefs, store the line/col number information */
+ if (flag_emit_xref)
+ DECL_SOURCE_LINE (decl) = EXPR_WFL_LINECOL (cl);
+ else
+ DECL_SOURCE_LINE (decl) = EXPR_WFL_LINENO (cl);
CLASS_FROM_SOURCE_P (TREE_TYPE (decl)) = 1;
+ CLASS_FROM_CURRENTLY_COMPILED_SOURCE_P (TREE_TYPE (decl)) =
+ IS_A_COMMAND_LINE_FILENAME_P (EXPR_WFL_FILENAME_NODE (cl));
ctxp->current_parsed_class = decl;
/* Link the declaration to the already seen ones */
TREE_CHAIN (decl) = ctxp->class_list;
ctxp->class_list = decl;
+
+ /* Create a new nodes in the global lists */
+ ctxp->gclass_list = tree_cons (NULL_TREE, decl, ctxp->gclass_list);
+ all_class_list = tree_cons (NULL_TREE, decl, all_class_list);
+
/* Install a new dependency list element */
create_jdep_list (ctxp);
@@ -5000,11 +5499,12 @@ add_superinterfaces (decl, interface_list)
defined. */
for (node = interface_list; node; node = TREE_CHAIN (node))
{
- tree current = TREE_PURPOSE (node), interface_decl;
- if ((interface_decl = IDENTIFIER_CLASS_VALUE (EXPR_WFL_NODE (current))))
+ tree current = TREE_PURPOSE (node);
+ tree idecl = IDENTIFIER_CLASS_VALUE (EXPR_WFL_NODE (current));
+ if (idecl && CLASS_LOADED_P (TREE_TYPE (idecl)))
{
- if (!parser_check_super_interface (interface_decl, decl, current))
- parser_add_interface (decl, interface_decl, current);
+ if (!parser_check_super_interface (idecl, decl, current))
+ parser_add_interface (decl, idecl, current);
}
else
register_incomplete_type (JDEP_INTERFACE,
@@ -5020,7 +5520,6 @@ create_interface (flags, id, super)
int flags;
tree id, super;
{
- int chk;
tree raw_name = EXPR_WFL_NODE (id);
tree q_name = parser_qualified_classname (id);
tree decl = IDENTIFIER_CLASS_VALUE (q_name);
@@ -5035,22 +5534,17 @@ create_interface (flags, id, super)
- public/abstract allowed (already done at that point)
- abstract is obsolete (comes first, it's a warning, or should be)
- Can't use twice the same (checked in the modifier rule) */
- if (flags & ACC_ABSTRACT)
+ if ((flags & ACC_ABSTRACT) && flag_redundant)
parse_warning_context
(MODIFIER_WFL (ABSTRACT_TK),
- "Obsolete use of `abstract' modifier. Interface `%s' is implicitely "
+ "Redundant use of `abstract' modifier. Interface `%s' is implicitely "
"abstract", IDENTIFIER_POINTER (raw_name));
- if (flags & ACC_PUBLIC && flags & ACC_ABSTRACT)
- parse_error_context
- (MODIFIER_WFL (ABSTRACT_TK),
- "Can't specify both `public' and `abstract' modifiers in the "
- "definition of interface `%s'", IDENTIFIER_POINTER (raw_name));
/* Create a new decl if DECL is NULL, otherwise fix it */
decl = maybe_create_class_interface_decl (decl, q_name, id);
/* Set super info and mark the class a complete */
- set_super_info (ACC_ABSTRACT | ACC_INTERFACE | flags, TREE_TYPE (decl),
+ set_super_info (ACC_INTERFACE | flags, TREE_TYPE (decl),
object_type_node, ctxp->interface_number);
ctxp->interface_number = 0;
CLASS_COMPLETE_P (decl) = 1;
@@ -5067,13 +5561,13 @@ create_class (flags, id, super, interfaces)
int flags;
tree id, super, interfaces;
{
- int chk;
tree raw_name = EXPR_WFL_NODE (id);
tree class_id, decl;
- tree super_decl = NULL, super_decl_type;
+ tree super_decl_type;
class_id = parser_qualified_classname (id);
decl = IDENTIFIER_CLASS_VALUE (class_id);
+ ctxp->current_parsed_class_un = EXPR_WFL_NODE (id);
EXPR_WFL_NODE (id) = class_id;
/* Basic check: scope, redefinition, modifiers */
@@ -5101,17 +5595,8 @@ create_class (flags, id, super, interfaces)
return NULL_TREE;
}
- /* The class is known and exists if there is a decl. Otherwise,
- postpone the operation and do it later. */
- super_decl = IDENTIFIER_CLASS_VALUE (EXPR_WFL_NODE (super));
- if (super_decl)
- {
- parser_check_super (super_decl, decl, id);
- super_decl_type = TREE_TYPE (super_decl);
- }
- else
- super_decl_type =
- register_incomplete_type (JDEP_SUPER, super, decl, NULL_TREE);
+ super_decl_type =
+ register_incomplete_type (JDEP_SUPER, super, decl, NULL_TREE);
}
else if (TREE_TYPE (decl) != object_type_node)
super_decl_type = object_type_node;
@@ -5126,6 +5611,9 @@ create_class (flags, id, super, interfaces)
CLASS_COMPLETE_P (decl) = 1;
add_superinterfaces (decl, interfaces);
+ /* Eventually sets the @deprecated tag flag */
+ CHECK_DEPRECATED (decl);
+
return decl;
}
@@ -5154,27 +5642,38 @@ lookup_field_wrapper (class, name)
tree class, name;
{
tree type = class;
- return lookup_field (&type, name);
+ tree decl;
+ java_parser_context_save_global ();
+ decl = lookup_field (&type, name);
+ java_parser_context_restore_global ();
+ return decl;
}
/* Find duplicate field within the same class declarations and report
- the error */
+ the error. Returns 1 if a duplicated field was found, 0
+ otherwise. */
static int
-duplicate_declaration_error (class, new_field_name, new_type, cl)
- tree class, new_field_name, new_type, cl;
+duplicate_declaration_error_p (new_field_name, new_type, cl)
+ tree new_field_name, new_type, cl;
{
/* This might be modified to work with method decl as well */
tree decl = find_field (TREE_TYPE (ctxp->current_parsed_class),
new_field_name);
if (decl)
{
- char *t1 = strdup ((char *)lang_printable_name (new_type, 1));
- char *t2 =
- strdup ((TREE_CODE (TREE_TYPE (decl)) == TREE_LIST ?
- IDENTIFIER_POINTER (TYPE_NAME
- (TREE_PURPOSE (TREE_TYPE (decl)))) :
- (char *)lang_printable_name (TREE_TYPE (decl), 1)));
+ char *t1 = strdup (purify_type_name
+ ((TREE_CODE (new_type) == POINTER_TYPE
+ && TREE_TYPE (new_type) == NULL_TREE) ?
+ IDENTIFIER_POINTER (TYPE_NAME (new_type)) :
+ lang_printable_name (new_type, 1)));
+ /* The type may not have been completed by the time we report
+ the error */
+ char *t2 = strdup (purify_type_name
+ ((TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
+ && TREE_TYPE (TREE_TYPE (decl)) == NULL_TREE) ?
+ IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE (decl))) :
+ lang_printable_name (TREE_TYPE (decl), 1)));
parse_error_context
(cl , "Duplicate variable declaration: `%s %s' was `%s %s' (%s:%d)",
t1, IDENTIFIER_POINTER (new_field_name),
@@ -5182,9 +5681,9 @@ duplicate_declaration_error (class, new_field_name, new_type, cl)
DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl));
free (t1);
free (t2);
- return 0;
+ return 1;
}
- return 1;
+ return 0;
}
/* Field registration routine. If TYPE doesn't exist, field
@@ -5196,7 +5695,7 @@ register_fields (flags, type, variable_list)
int flags;
tree type, variable_list;
{
- tree current, type_decl, returned_type;
+ tree current, saved_type;
tree class_type = TREE_TYPE (ctxp->current_parsed_class);
int saved_lineno = lineno;
int must_chain = 0;
@@ -5219,103 +5718,128 @@ register_fields (flags, type, variable_list)
flags |= (ACC_PUBLIC | ACC_STATIC | ACC_FINAL);
}
- if (unresolved_type_p (type, &returned_type))
- {
- if (returned_type)
- type = returned_type;
- else
- {
- wfl = type;
- type = obtain_incomplete_type (type);
- must_chain = 1;
- }
- }
+ /* Obtain a suitable type for resolution, if necessary */
+ SET_TYPE_FOR_RESOLUTION (type, wfl, must_chain);
+
+ /* If TYPE is fully resolved and we don't have a reference, make one */
+ PROMOTE_RECORD_IF_COMPLETE (type, must_chain);
- for (current = variable_list; current; current = TREE_CHAIN (current))
+ for (current = variable_list, saved_type = type; current;
+ current = TREE_CHAIN (current), type = saved_type)
{
+ tree real_type;
+ tree field_decl;
tree cl = TREE_PURPOSE (current);
tree init = TREE_VALUE (current);
tree current_name = EXPR_WFL_NODE (cl);
- if (duplicate_declaration_error (class_type, current_name, type, cl))
- {
- tree field_decl;
- lineno = EXPR_WFL_LINENO (cl);
- field_decl = add_field (class_type, current_name, type, flags);
+ /* Process NAME, as it may specify extra dimension(s) for it */
+ type = build_array_from_name (type, wfl, current_name, &current_name);
+
+ /* Type adjustment. We may have just readjusted TYPE because
+ the variable specified more dimensions. Make sure we have
+ a reference if we can and don't have one already. Also
+ change the name if we have an init. */
+ if (type != saved_type)
+ {
+ PROMOTE_RECORD_IF_COMPLETE (type, must_chain);
+ if (init)
+ EXPR_WFL_NODE (TREE_OPERAND (init, 0)) = current_name;
+ }
+
+ real_type = GET_REAL_TYPE (type);
+ /* Check for redeclarations */
+ if (duplicate_declaration_error_p (current_name, real_type, cl))
+ continue;
- /* Check if we must chain. */
- if (must_chain)
- register_incomplete_type (JDEP_FIELD, wfl, field_decl, type);
+ /* Set lineno to the line the field was found and create a
+ declaration for it. Eventually sets the @deprecated tag flag. */
+ if (flag_emit_xref)
+ lineno = EXPR_WFL_LINECOL (cl);
+ else
+ lineno = EXPR_WFL_LINENO (cl);
+ field_decl = add_field (class_type, current_name, real_type, flags);
+ CHECK_DEPRECATED (field_decl);
+
+ /* Check if we must chain. */
+ if (must_chain)
+ register_incomplete_type (JDEP_FIELD, wfl, field_decl, type);
- /* Default value of a static field is 0 and it is considered
- initialized. */
+ /* If we have an initialization value tied to the field */
+ if (init)
+ {
+ /* The field is declared static */
if (flags & ACC_STATIC)
- INITIALIZED_P (field_decl) = 1;
-
- /* If we have an initialization value tied to the field */
- if (init)
{
- /* The field is declared static */
- if (flags & ACC_STATIC)
- {
- /* FIXME */
- if (flags & ACC_FINAL)
- ;
- /* Otherwise, the field should be initialized in
- <clinit>. This field is remembered so we can
- generate <clinit> later. */
- else
- {
- INITIALIZED_P (field_decl) = 1;
- TREE_CHAIN (init) = ctxp->static_initialized;
- ctxp->static_initialized = init;
- }
- }
- /* A non-static field declared with an immediate
- initialization is to be initialized in <init>, if
- any. This field is remembered to be processed at the
- time of the generation of <init>. */
- else
- {
- TREE_CHAIN (init) = ctxp->non_static_initialized;
- ctxp->non_static_initialized = init;
- }
+ /* We include the field and its initialization part into
+ a list used to generate <clinit>. After <clinit> is
+ walked, field initializations will be processed and
+ fields initialized with known constants will be taken
+ out of <clinit> and have their DECL_INITIAL set
+ appropriately. */
+ TREE_CHAIN (init) = ctxp->static_initialized;
+ ctxp->static_initialized = init;
+ DECL_INITIAL (field_decl) = TREE_OPERAND (init, 1);
+ if (TREE_CODE (TREE_OPERAND (init, 1)) == NEW_ARRAY_INIT)
+ TREE_STATIC (TREE_OPERAND (init, 1)) = 1;
}
+ /* A non-static field declared with an immediate initialization is
+ to be initialized in <init>, if any. This field is remembered
+ to be processed at the time of the generation of <init>. */
+ else
+ {
+ TREE_CHAIN (init) = ctxp->non_static_initialized;
+ ctxp->non_static_initialized = init;
+ }
+ MODIFY_EXPR_FROM_INITIALIZATION_P (init) = 1;
}
}
lineno = saved_lineno;
}
+/* Generate the method $finit$ that initializes fields initialized
+ upon declaration. */
+
+static void
+maybe_generate_finit ()
+{
+ tree mdecl, current;
+
+ if (!ctxp->non_static_initialized || java_error_count)
+ return;
+
+ mdecl = create_artificial_method (TREE_TYPE (ctxp->current_parsed_class),
+ ACC_PRIVATE, void_type_node,
+ finit_identifier_node, end_params_node);
+ start_artificial_method_body (mdecl);
+
+ ctxp->non_static_initialized = nreverse (ctxp->non_static_initialized);
+ for (current = ctxp->non_static_initialized; current;
+ current = TREE_CHAIN (current))
+ java_method_add_stmt (mdecl,
+ build_debugable_stmt (EXPR_WFL_LINECOL (current),
+ current));
+
+ end_artificial_method_body (mdecl);
+ CLASS_HAS_FINIT_P (TREE_TYPE (ctxp->current_parsed_class)) = 1;
+ ctxp->non_static_initialized = NULL_TREE;
+}
+
/* Check whether it is necessary to generate a <clinit> for the class
we just parsed. */
static void
maybe_generate_clinit ()
{
- int saved_lineno;
- tree meth, mdecl, c;
- tree cclass, class_wfl;
+ tree mdecl, c;
if (!ctxp->static_initialized || java_error_count)
return;
- cclass = TREE_TYPE (ctxp->current_parsed_class);
- class_wfl = build_expr_wfl (DECL_NAME (TYPE_NAME (cclass)),
- input_filename, 0, 0);
-
- saved_lineno = lineno;
- lineno = 0;
- meth = make_node (FUNCTION_TYPE);
- TREE_TYPE (meth) = void_type_node;
- TYPE_ARG_TYPES (meth) = NULL_TREE;
- mdecl = add_method (cclass, ACC_STATIC, clinit_identifier_node,
- build_java_signature (meth));
- lineno = saved_lineno;
-
- DECL_SOURCE_LINE (mdecl) = 1;
- DECL_SOURCE_LINE_MERGE (mdecl, 1);
- source_start_java_method (mdecl);
- enter_block ();
+ mdecl = create_artificial_method (TREE_TYPE (ctxp->current_parsed_class),
+ ACC_STATIC, void_type_node,
+ clinit_identifier_node, end_params_node);
+ start_artificial_method_body (mdecl);
/* Keep initialization in order to enforce 8.5 */
ctxp->static_initialized = nreverse (ctxp->static_initialized);
@@ -5328,11 +5852,11 @@ maybe_generate_clinit ()
/* We build the assignment expression that will initialize the
field to its value. There are strict rules on static
initializers (8.5). FIXME */
- java_method_add_stmt (mdecl, c);
+ java_method_add_stmt (mdecl,
+ build_debugable_stmt (EXPR_WFL_LINECOL (c), c));
}
- BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (mdecl)) = exit_block ();
- exit_block ();
+ end_artificial_method_body (mdecl);
ctxp->static_initialized = NULL_TREE;
}
@@ -5347,7 +5871,8 @@ static int patch_stage;
/* Check the method declaration and add the method to its current
class. If the argument list is known to contain incomplete types,
the method is partially added and the registration will be resume
- once the method arguments resolved */
+ once the method arguments resolved. If TYPE is NULL, we're dealing
+ with a constructor. */
static tree
method_header (flags, type, mdecl, throws)
@@ -5357,33 +5882,58 @@ method_header (flags, type, mdecl, throws)
tree meth = TREE_VALUE (mdecl);
tree id = TREE_PURPOSE (mdecl);
tree this_class = TREE_TYPE (ctxp->current_parsed_class);
- tree handle_class = CLASS_TO_HANDLE_TYPE (this_class);
- tree meth_name, returned_type;
+ tree type_wfl = NULL_TREE;
+ tree meth_name = NULL_TREE, current, orig_arg;
int saved_lineno;
+ int constructor_ok = 0, must_chain;
check_modifiers_consistency (flags);
/* There are some forbidden modifiers for an abstract method and its
class must be abstract as well. */
- if (flags & ACC_ABSTRACT)
+ if (type && (flags & ACC_ABSTRACT))
{
ABSTRACT_CHECK (flags, ACC_PRIVATE, id, "Private");
ABSTRACT_CHECK (flags, ACC_STATIC, id, "Static");
ABSTRACT_CHECK (flags, ACC_FINAL, id, "Final");
ABSTRACT_CHECK (flags, ACC_NATIVE, id, "Native");
ABSTRACT_CHECK (flags, ACC_SYNCHRONIZED,id, "Synchronized");
- if (!CLASS_ABSTRACT (TYPE_NAME (this_class)))
+ if (!CLASS_ABSTRACT (TYPE_NAME (this_class))
+ && !CLASS_INTERFACE (TYPE_NAME (this_class)))
parse_error_context
(id, "Class `%s' must be declared abstract to define abstract "
"method `%s'",
IDENTIFIER_POINTER (DECL_NAME (ctxp->current_parsed_class)),
IDENTIFIER_POINTER (EXPR_WFL_NODE (id)));
}
-
+ /* Things to be checked when declaring a constructor */
+ if (!type)
+ {
+ int ec = java_error_count;
+ /* 8.6: Constructor declarations: we might be trying to define a
+ method without specifying a return type. */
+ if (EXPR_WFL_NODE (id) != ctxp->current_parsed_class_un)
+ parse_error_context
+ (id, "Invalid method declaration, return type required");
+ /* 8.6.3: Constructor modifiers */
+ else
+ {
+ JCONSTRUCTOR_CHECK (flags, ACC_ABSTRACT, id, "abstract");
+ JCONSTRUCTOR_CHECK (flags, ACC_STATIC, id, "static");
+ JCONSTRUCTOR_CHECK (flags, ACC_FINAL, id, "final");
+ JCONSTRUCTOR_CHECK (flags, ACC_NATIVE, id, "native");
+ JCONSTRUCTOR_CHECK (flags, ACC_SYNCHRONIZED, id, "synchronized");
+ }
+ /* If we found error here, we don't consider it's OK to tread
+ the method definition as a constructor, for the rest of this
+ function */
+ if (ec == java_error_count)
+ constructor_ok = 1;
+ }
/* Method declared within the scope of an interface are implicitly
abstract and public. Conflicts with other erroneously provided
- modifiers are check right after. */
+ modifiers are checked right after. */
if (CLASS_INTERFACE (TYPE_NAME (this_class)))
{
@@ -5401,18 +5951,31 @@ method_header (flags, type, mdecl, throws)
/* Modifiers context reset moved up, so abstract method declaration
modifiers can be later checked. */
- meth_name = EXPR_WFL_NODE (id);
+ /* Set constructor returned type to void and method name to <init>,
+ unless we found an error identifier the constructor (in which
+ case we retain the original name) */
+ if (!type)
+ {
+ type = void_type_node;
+ if (constructor_ok)
+ meth_name = init_identifier_node;
+ }
+ else
+ meth_name = EXPR_WFL_NODE (id);
+
+ /* Do the returned type resolution and registration if necessary */
+ SET_TYPE_FOR_RESOLUTION (type, type_wfl, must_chain);
- if (unresolved_type_p (type, &returned_type))
+ if (meth_name)
+ type = build_array_from_name (type, type_wfl, meth_name, &meth_name);
+ EXPR_WFL_NODE (id) = meth_name;
+ PROMOTE_RECORD_IF_COMPLETE (type, must_chain);
+
+ if (must_chain)
{
- if (returned_type)
- TREE_TYPE (meth) = returned_type;
- else
- {
- patch_stage = JDEP_METHOD_RETURN;
- TREE_TYPE (meth) =
- register_incomplete_type (patch_stage, type, id, NULL_TREE);
- }
+ patch_stage = JDEP_METHOD_RETURN;
+ register_incomplete_type (patch_stage, type_wfl, id, type);
+ TREE_TYPE (meth) = GET_REAL_TYPE (type);
}
else
TREE_TYPE (meth) = type;
@@ -5424,6 +5987,9 @@ method_header (flags, type, mdecl, throws)
lineno = (ctxp->first_ccb_indent1 ? ctxp->first_ccb_indent1 :
EXPR_WFL_LINENO (id));
+ /* Remember the original argument list */
+ orig_arg = TYPE_ARG_TYPES (meth);
+
if (patch_stage) /* includes ret type and/or all args */
{
jdep *jdep;
@@ -5439,41 +6005,150 @@ method_header (flags, type, mdecl, throws)
register_incomplete_type (JDEP_METHOD_END, NULL_TREE, meth, NULL_TREE);
}
else
+ meth = add_method (this_class, flags, meth_name,
+ build_java_signature (meth));
+
+ /* Fix the method argument list so we have the argument name
+ information */
+ fix_method_argument_names (orig_arg, meth);
+
+ /* Register the parameter number and re-install the current line
+ number */
+ DECL_MAX_LOCALS (meth) = ctxp->formal_parameter_number+1;
+ lineno = saved_lineno;
+
+ /* Register exception specified by the `throws' keyword for
+ resolution and set the method decl appropriate field to the list.
+ Note: the grammar ensures that what we get here are class
+ types. */
+ if (throws)
{
- tree signature = build_java_signature (meth);
- tree arg, orig_arg;
- /* Save original argument list, including argument's names */
- orig_arg = TYPE_ARG_TYPES (meth);
- /* Add the method to its class */
- meth = add_method (this_class, flags, meth_name, signature);
- /* Fix the method argument list so we have the argument name
- information */
- arg = TYPE_ARG_TYPES (TREE_TYPE (meth));
- if (TREE_CODE (TREE_TYPE (meth)) == METHOD_TYPE)
- {
- TREE_PURPOSE (arg) = this_identifier_node;
- arg = TREE_CHAIN (arg);
- }
- while (orig_arg)
- {
- TREE_PURPOSE (arg) = TREE_PURPOSE (orig_arg);
- orig_arg = TREE_CHAIN (orig_arg);
- arg = TREE_CHAIN (arg);
+ throws = nreverse (throws);
+ for (current = throws; current; current = TREE_CHAIN (current))
+ {
+ register_incomplete_type (JDEP_EXCEPTION, TREE_VALUE (current),
+ NULL_TREE, NULL_TREE);
+ JDEP_GET_PATCH (CLASSD_LAST (ctxp->classd_list)) =
+ &TREE_VALUE (current);
}
+ DECL_FUNCTION_THROWS (meth) = throws;
}
- DECL_MAX_LOCALS (meth) = ctxp->formal_parameter_number+1;
- lineno = saved_lineno;
+
/* We set the DECL_NAME to ID so we can track the location where
the function was declared. This allow us to report
redefinition error accurately. When method are verified,
DECL_NAME is reinstalled properly (using the content of the
WFL node ID) (see check_method_redefinition). We don't do that
- when Object is being defined. */
+ when Object is being defined. Constructor <init> names will be
+ reinstalled the same way. */
if (TREE_TYPE (ctxp->current_parsed_class) != object_type_node)
DECL_NAME (meth) = id;
+
+ /* Set the flag if we correctly processed a constructor */
+ if (constructor_ok)
+ DECL_CONSTRUCTOR_P (meth) = 1;
+
+ /* Eventually set the @deprecated tag flag */
+ CHECK_DEPRECATED (meth);
+
return meth;
}
+static void
+fix_method_argument_names (orig_arg, meth)
+ tree orig_arg, meth;
+{
+ tree arg = TYPE_ARG_TYPES (TREE_TYPE (meth));
+ if (TREE_CODE (TREE_TYPE (meth)) == METHOD_TYPE)
+ {
+ TREE_PURPOSE (arg) = this_identifier_node;
+ arg = TREE_CHAIN (arg);
+ }
+ while (orig_arg != end_params_node)
+ {
+ TREE_PURPOSE (arg) = TREE_PURPOSE (orig_arg);
+ orig_arg = TREE_CHAIN (orig_arg);
+ arg = TREE_CHAIN (arg);
+ }
+}
+
+/* Complete the method declaration with METHOD_BODY. */
+
+static void
+finish_method_declaration (method_body)
+ tree method_body;
+{
+ BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (current_function_decl)) = method_body;
+ maybe_absorb_scoping_blocks ();
+ /* Exit function's body */
+ exit_block ();
+ /* Merge last line of the function with first line, directly in the
+ function decl. It will be used to emit correct debug info. */
+ DECL_SOURCE_LINE_MERGE (current_function_decl, ctxp->last_ccb_indent1);
+ /* So we don't have an irrelevant function declaration context for
+ the next static block we'll see. */
+ current_function_decl = NULL_TREE;
+}
+
+/* Build a an error message for constructor circularity errors. */
+
+static char *
+constructor_circularity_msg (from, to)
+ tree from, to;
+{
+ static char string [4096];
+ char *t = strdup (lang_printable_name (from, 0));
+ sprintf (string, "`%s' invokes `%s'", t, lang_printable_name (to, 0));
+ free (t);
+ return string;
+}
+
+/* Verify a circular call to METH. Return 1 if an error is found, 0
+ otherwise. */
+
+static int
+verify_constructor_circularity (meth, current)
+ tree meth, current;
+{
+ static tree list = NULL_TREE;
+ tree c;
+ for (c = DECL_CONSTRUCTOR_CALLS (current); c; c = TREE_CHAIN (c))
+ {
+ if (TREE_VALUE (c) == meth)
+ {
+ char *t;
+ if (list)
+ {
+ tree liste;
+ list = nreverse (list);
+ for (liste = list; liste; liste = TREE_CHAIN (liste))
+ {
+ parse_error_context
+ (TREE_PURPOSE (TREE_PURPOSE (liste)),
+ constructor_circularity_msg
+ (TREE_VALUE (liste), TREE_VALUE (TREE_PURPOSE (liste))));
+ java_error_count--;
+ }
+ }
+ t = strdup (lang_printable_name (meth, 0));
+ parse_error_context (TREE_PURPOSE (c),
+ "%s: recursive invocation of constructor `%s'",
+ constructor_circularity_msg (current, meth), t);
+ free (t);
+ list = NULL_TREE;
+ return 1;
+ }
+ }
+ for (c = DECL_CONSTRUCTOR_CALLS (current); c; c = TREE_CHAIN (c))
+ {
+ list = tree_cons (c, current, list);
+ if (verify_constructor_circularity (meth, TREE_VALUE (c)))
+ return 1;
+ list = TREE_CHAIN (list);
+ }
+ return 0;
+}
+
/* Check modifiers that can be declared but exclusively */
static void
@@ -5500,8 +6175,7 @@ check_abstract_method_header (meth)
{
int flags = get_access_flags_from_decl (meth);
/* DECL_NAME might still be a WFL node */
- tree name = (TREE_CODE (DECL_NAME (meth)) == EXPR_WITH_FILE_LOCATION ?
- EXPR_WFL_NODE (DECL_NAME (meth)) : DECL_NAME (meth));
+ tree name = GET_METHOD_NAME (meth);
OBSOLETE_MODIFIER_WARNING (MODIFIER_WFL (ABSTRACT_TK), flags,
ACC_ABSTRACT, "abstract method `%s'",
@@ -5526,17 +6200,33 @@ method_declarator (id, list)
tree arg_types = NULL_TREE, current, node;
tree meth = make_node (FUNCTION_TYPE);
jdep *jdep;
- int incomplete = 0;
patch_stage = JDEP_NO_PATCH;
for (current = list; current; current = TREE_CHAIN (current))
{
+ int must_chain = 0;
tree wfl_name = TREE_PURPOSE (current);
tree type = TREE_VALUE (current);
tree name = EXPR_WFL_NODE (wfl_name);
- tree patchable_type = NULL_TREE, already;
- tree arg_node, returned_type;
+ tree already, arg_node;
+ tree type_wfl = NULL_TREE;
+ tree real_type;
+
+ /* Obtain a suitable type for resolution, if necessary */
+ SET_TYPE_FOR_RESOLUTION (type, type_wfl, must_chain);
+
+ /* Process NAME, as it may specify extra dimension(s) for it */
+ type = build_array_from_name (type, type_wfl, name, &name);
+ EXPR_WFL_NODE (wfl_name) = name;
+
+ real_type = GET_REAL_TYPE (type);
+ if (TREE_CODE (real_type) == RECORD_TYPE)
+ {
+ real_type = promote_type (real_type);
+ if (TREE_CODE (type) == TREE_LIST)
+ TREE_PURPOSE (type) = real_type;
+ }
/* Check redefinition */
for (already = arg_types; already; already = TREE_CHAIN (already))
@@ -5552,27 +6242,23 @@ method_declarator (id, list)
/* If we've an incomplete argument type, we know there is a location
to patch when the type get resolved, later. */
jdep = NULL;
- if (unresolved_type_p (type, &returned_type))
+ if (must_chain)
{
- if (returned_type)
- type = returned_type;
- else
- {
- patch_stage = JDEP_METHOD;
- type = register_incomplete_type (patch_stage, type,
- wfl_name, NULL_TREE);
- jdep = CLASSD_LAST (ctxp->classd_list);
- JDEP_MISC (jdep) = id;
- }
+ patch_stage = JDEP_METHOD;
+ type = register_incomplete_type (patch_stage,
+ type_wfl, wfl_name, type);
+ jdep = CLASSD_LAST (ctxp->classd_list);
+ JDEP_MISC (jdep) = id;
}
+
/* The argument node: a name and a (possibly) incomplete type */
- arg_node = build_tree_list (name, type);
+ arg_node = build_tree_list (name, real_type);
if (jdep)
JDEP_GET_PATCH (jdep) = &TREE_VALUE (arg_node);
TREE_CHAIN (arg_node) = arg_types;
arg_types = arg_node;
}
- TYPE_ARG_TYPES (meth) = nreverse (arg_types);
+ TYPE_ARG_TYPES (meth) = chainon (nreverse (arg_types), end_params_node);
node = build_tree_list (id, meth);
return node;
}
@@ -5647,7 +6333,6 @@ static int
parser_check_super (super_decl, this_decl, wfl)
tree super_decl, this_decl, wfl;
{
- tree this_type = TREE_TYPE (this_decl);
tree super_type = TREE_TYPE (super_decl);
/* SUPER should be a CLASS (neither an array nor an interface) */
@@ -5685,11 +6370,7 @@ static void
create_jdep_list (ctxp)
struct parser_ctxt *ctxp;
{
- jdeplist *new = malloc (sizeof (jdeplist));
-
- if (!new)
- fatal ("Can't alloc jdeplist - create_jdep_list");
-
+ jdeplist *new = (jdeplist *)xmalloc (sizeof (jdeplist));
new->first = new->last = NULL;
new->next = ctxp->classd_list;
ctxp->classd_list = new;
@@ -5709,25 +6390,32 @@ reverse_jdep_list (ctxp)
return prev;
}
-/* Create a fake pointer based on the ID stored in the WFL */
+/* Create a fake pointer based on the ID stored in
+ TYPE_NAME. TYPE_NAME can be a WFL or a incomplete type asking to be
+ registered again. */
static tree
-obtain_incomplete_type (wfl)
- tree wfl;
+obtain_incomplete_type (type_name)
+ tree type_name;
{
- tree ptr;
- tree name = EXPR_WFL_NODE (wfl);
+ tree ptr, name;
+
+ if (TREE_CODE (type_name) == EXPR_WITH_FILE_LOCATION)
+ name = EXPR_WFL_NODE (type_name);
+ else if (INCOMPLETE_TYPE_P (type_name))
+ name = TYPE_NAME (type_name);
+ else
+ fatal ("invalid type name - obtain_incomplete_type");
for (ptr = ctxp->incomplete_class; ptr; ptr = TREE_CHAIN (ptr))
- if (TYPE_NAME (TREE_PURPOSE (ptr)) == name)
+ if (TYPE_NAME (ptr) == name)
break;
if (!ptr)
{
- tree core;
push_obstacks (&permanent_obstack, &permanent_obstack);
- BUILD_PTR_FROM_NAME (core, name);
- ptr = build_tree_list (core, NULL_TREE);
+ BUILD_PTR_FROM_NAME (ptr, name);
+ layout_type (ptr);
pop_obstacks ();
TREE_CHAIN (ptr) = ctxp->incomplete_class;
ctxp->incomplete_class = ptr;
@@ -5746,10 +6434,8 @@ register_incomplete_type (kind, wfl, decl, ptr)
int kind;
tree wfl, decl, ptr;
{
- jdep *new = malloc (sizeof (jdep));
+ jdep *new = (jdep *)xmalloc (sizeof (jdep));
- if (!new)
- fatal ("Can't allocate new jdep - register_incomplete_type");
if (!ptr && kind != JDEP_METHOD_END) /* JDEP_METHOD_END is a mere marker */
ptr = obtain_incomplete_type (wfl);
@@ -5798,6 +6484,10 @@ java_check_circular_reference ()
}
}
+/* safe_layout_class just makes sure that we can load a class without
+ disrupting the current_class, input_file, lineno, etc, information
+ about the class processed currently. */
+
void
safe_layout_class (class)
tree class;
@@ -5805,11 +6495,12 @@ safe_layout_class (class)
tree save_current_class = current_class;
char *save_input_filename = input_filename;
int save_lineno = lineno;
-
+
push_obstacks (&permanent_obstack, &permanent_obstack);
+
layout_class (class);
pop_obstacks ();
-
+
current_class = save_current_class;
input_filename = save_input_filename;
lineno = save_lineno;
@@ -5822,20 +6513,18 @@ jdep_resolve_class (dep)
{
tree decl;
- if (!JDEP_RESOLVED_P (dep))
+ if (JDEP_RESOLVED_P (dep))
+ decl = JDEP_RESOLVED_DECL (dep);
+ else
{
- decl =
- resolve_class (JDEP_TO_RESOLVE (dep), JDEP_DECL (dep), JDEP_WFL (dep));
+ decl = resolve_class (JDEP_TO_RESOLVE (dep),
+ JDEP_DECL (dep), JDEP_WFL (dep));
JDEP_RESOLVED (dep, decl);
}
- else
- decl = JDEP_RESOLVED_DECL (dep);
-
+
if (!decl)
- {
- complete_class_report_errors (dep);
- return NULL_TREE;
- }
+ complete_class_report_errors (dep);
+
return decl;
}
@@ -5844,10 +6533,10 @@ jdep_resolve_class (dep)
void
java_complete_class ()
{
- tree current;
tree cclass;
jdeplist *cclassd;
int error_found;
+ tree type;
push_obstacks (&permanent_obstack, &permanent_obstack);
@@ -5859,7 +6548,7 @@ java_complete_class ()
/* Rever things so we have the right order */
ctxp->class_list = nreverse (ctxp->class_list);
ctxp->classd_list = reverse_jdep_list (ctxp);
-
+
for (cclassd = ctxp->classd_list, cclass = ctxp->class_list;
cclass && cclassd;
cclass = TREE_CHAIN (cclass), cclassd = CLASSD_CHAIN (cclassd))
@@ -5868,7 +6557,6 @@ java_complete_class ()
for (dep = CLASSD_FIRST (cclassd); dep; dep = JDEP_CHAIN (dep))
{
tree decl;
-
if (!(decl = jdep_resolve_class (dep)))
continue;
@@ -5889,12 +6577,12 @@ java_complete_class ()
tree field_decl = JDEP_DECL (dep);
tree field_type = TREE_TYPE (decl);
push_obstacks (&permanent_obstack, &permanent_obstack);
-#if ! JAVA_PROMOTE_TO_INT
if (TREE_CODE (field_type) == RECORD_TYPE)
-#endif
field_type = promote_type (field_type);
pop_obstacks ();
TREE_TYPE (field_decl) = field_type;
+ DECL_ALIGN (field_decl) = 0;
+ layout_decl (field_decl, 0);
SOURCE_FRONTEND_DEBUG
(("Completed field/var decl `%s' with `%s'",
IDENTIFIER_POINTER (DECL_NAME (field_decl)),
@@ -5908,7 +6596,9 @@ java_complete_class ()
{
if (decl)
{
- tree type = promote_type (TREE_TYPE(decl));
+ type = TREE_TYPE(decl);
+ if (TREE_CODE (type) == RECORD_TYPE)
+ type = promote_type (type);
JDEP_APPLY_PATCH (dep, type);
SOURCE_FRONTEND_DEBUG
(((JDEP_KIND (dep) == JDEP_METHOD_RETURN ?
@@ -5946,14 +6636,12 @@ java_complete_class ()
parser_add_interface (JDEP_DECL (dep), decl, JDEP_WFL (dep));
break;
+ case JDEP_PARM:
case JDEP_VARIABLE:
- JDEP_APPLY_PATCH (dep, promote_type (TREE_TYPE (decl)));
- SOURCE_FRONTEND_DEBUG
- (("Completing variable `%s' with type `%s'",
- (TREE_CODE (JDEP_DECL_WFL (dep)) == EXPR_WITH_FILE_LOCATION ?
- IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_DECL_WFL (dep))) :
- IDENTIFIER_POINTER (DECL_NAME (JDEP_DECL_WFL (dep)))),
- IDENTIFIER_POINTER (DECL_NAME (decl))));
+ type = TREE_TYPE(decl);
+ if (TREE_CODE (type) == RECORD_TYPE)
+ type = promote_type (type);
+ JDEP_APPLY_PATCH (dep, type);
break;
case JDEP_TYPE:
@@ -5963,16 +6651,16 @@ java_complete_class ()
tree_code_name [TREE_CODE (JDEP_DECL (dep))]));
break;
- case JDEP_PARM:
- JDEP_APPLY_PATCH (dep, promote_type (TREE_TYPE (decl)));
+ case JDEP_EXCEPTION:
+ JDEP_APPLY_PATCH (dep, TREE_TYPE (decl));
SOURCE_FRONTEND_DEBUG
- (("Completing parameter `%s' with type `%s'",
- IDENTIFIER_POINTER (JDEP_MISC (dep)),
- IDENTIFIER_POINTER (DECL_NAME (decl))));
+ (("Completing `%s' `throws' argument node",
+ IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_WFL (dep)))));
break;
default:
- fatal ("incomplete switch - java_complete_class");
+ fatal ("Can't handle patch code %d - java_complete_class",
+ JDEP_KIND (dep));
}
}
}
@@ -5989,8 +6677,22 @@ resolve_class (class_type, decl, cl)
{
char *name = IDENTIFIER_POINTER (TYPE_NAME (class_type));
char *base = name;
- tree resolved_type, resolved_type_decl;
+ tree resolved_type = TREE_TYPE (class_type);
+ tree resolved_type_decl;
+ if (resolved_type != NULL_TREE)
+ {
+ tree resolved_type_decl = TYPE_NAME (resolved_type);
+ if (resolved_type_decl == NULL_TREE
+ || TREE_CODE (resolved_type_decl) == IDENTIFIER_NODE)
+ {
+ resolved_type_decl = build_decl (TYPE_DECL,
+ TYPE_NAME (class_type),
+ resolved_type);
+ }
+ return resolved_type_decl;
+ }
+
/* 1- Check to see if we have an array. If true, find what we really
want to resolve */
while (name[0] == '[')
@@ -6011,6 +6713,7 @@ resolve_class (class_type, decl, cl)
if (TREE_CODE (resolved_type) == RECORD_TYPE)
resolved_type = promote_type (resolved_type);
resolved_type = build_java_array_type (resolved_type, -1);
+ CLASS_LOADED_P (resolved_type) = 1;
name--;
}
/* Build a fake decl for this, since this is what is expected to
@@ -6020,14 +6723,16 @@ resolve_class (class_type, decl, cl)
/* Figure how those two things are important for error report. FIXME */
DECL_SOURCE_LINE (resolved_type_decl) = 0;
DECL_SOURCE_FILE (resolved_type_decl) = input_filename;
+ TYPE_NAME (class_type) = TYPE_NAME (resolved_type);
}
+ TREE_TYPE (class_type) = resolved_type;
return resolved_type_decl;
}
/* Effectively perform the resolution of class CLASS_TYPE. DECL or CL
are used to report error messages. */
-static tree
+tree
do_resolve_class (class_type, decl, cl)
tree class_type;
tree decl;
@@ -6045,7 +6750,6 @@ do_resolve_class (class_type, decl, cl)
/* 2- And check for the type in the current compilation unit. If it fails,
try with a name qualified with the package name if appropriate. */
-
if ((new_class_decl = IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type))))
{
if (!CLASS_LOADED_P (TREE_TYPE (new_class_decl)) &&
@@ -6058,6 +6762,9 @@ do_resolve_class (class_type, decl, cl)
if (!QUALIFIED_P (TYPE_NAME (class_type)) && ctxp->package)
TYPE_NAME (class_type) = merge_qualified_name (ctxp->package,
TYPE_NAME (class_type));
+#if 1
+ if (!(new_class_decl = IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type))))
+ load_class (TYPE_NAME (class_type), 0);
if ((new_class_decl = IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type))))
{
if (!CLASS_LOADED_P (TREE_TYPE (new_class_decl)) &&
@@ -6065,6 +6772,27 @@ do_resolve_class (class_type, decl, cl)
load_class (TYPE_NAME (class_type), 0);
return IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type));
}
+#else
+ new_name = TYPE_NAME (class_type);
+ if ((new_class_decl = IDENTIFIER_CLASS_VALUE (new_name)) != NULL_TREE)
+ {
+ if (!CLASS_LOADED_P (TREE_TYPE (new_class_decl)) &&
+ !CLASS_FROM_SOURCE_P (TREE_TYPE (new_class_decl)))
+ load_class (new_name, 0);
+ return IDENTIFIER_CLASS_VALUE (new_name);
+ }
+ else
+ {
+ tree class = read_class (new_name);
+ if (class != NULL_TREE)
+ {
+ tree decl = IDENTIFIER_CLASS_VALUE (new_name);
+ if (decl == NULL_TREE)
+ decl = push_class (class, new_name);
+ return decl;
+ }
+ }
+#endif
TYPE_NAME (class_type) = original_name;
/* 3- Check an other compilation unit that bears the name of type */
@@ -6087,17 +6815,59 @@ do_resolve_class (class_type, decl, cl)
}
/* Resolve NAME and lay it out (if not done and if not the current
- parsed class). Return a decl node. */
+ parsed class). Return a decl node. This function is meant to be
+ called when type resolution is necessary during the walk pass. */
static tree
-resolve_and_layout (name, cl)
- tree name;
+resolve_and_layout (something, cl)
+ tree something;
tree cl;
{
- tree decl = resolve_no_layout (name, cl);
- if (decl && TREE_TYPE (decl) != current_class
- && !CLASS_LOADED_P (TREE_TYPE (decl)))
+ tree decl;
+
+ /* Don't do that on the current class */
+ if (something == current_class)
+ return TYPE_NAME (current_class);
+
+ /* Don't do anything for void and other primitive types */
+ if (JPRIMITIVE_TYPE_P (something) || something == void_type_node)
+ return NULL_TREE;
+
+ /* Pointer types can be reall pointer types or fake pointers. When
+ finding a real pointer, recheck for primitive types */
+ if (TREE_CODE (something) == POINTER_TYPE)
+ {
+ if (TREE_TYPE (something))
+ {
+ something = TREE_TYPE (something);
+ if (JPRIMITIVE_TYPE_P (something) || something == void_type_node)
+ return NULL_TREE;
+ }
+ else
+ something = TYPE_NAME (something);
+ }
+
+ /* Don't do anything for arrays of primitive types */
+ if (TREE_CODE (something) == RECORD_TYPE && TYPE_ARRAY_P (something)
+ && JPRIMITIVE_TYPE_P (TYPE_ARRAY_ELEMENT (something)))
+ return NULL_TREE;
+
+ /* If something is not and IDENTIFIER_NODE, it can be a a TYPE_DECL
+ or a real TYPE */
+ if (TREE_CODE (something) != IDENTIFIER_NODE)
+ something = (TREE_CODE (TYPE_NAME (something)) == TYPE_DECL ?
+ DECL_NAME (TYPE_NAME (something)) : TYPE_NAME (something));
+
+ if (!(decl = resolve_no_layout (something, cl)))
+ return NULL_TREE;
+
+ /* Resolve and layout if necessary */
+ layout_class_methods (TREE_TYPE (decl));
+ if (CLASS_FROM_SOURCE_P (TREE_TYPE (decl)))
+ CHECK_METHODS (decl);
+ if (TREE_TYPE (decl) != current_class && !CLASS_LOADED_P (TREE_TYPE (decl)))
safe_layout_class (TREE_TYPE (decl));
+
return decl;
}
@@ -6117,8 +6887,8 @@ resolve_no_layout (name, cl)
return decl;
}
-/* Called to report errors. Skip leader '[' in a complex array type
- description that failed to be resolved. */
+/* Called when reporting errors. Skip leader '[' in a complex array
+ type description that failed to be resolved. */
static char *
purify_type_name (name)
@@ -6135,25 +6905,31 @@ static void
complete_class_report_errors (dep)
jdep *dep;
{
+ char *name;
+
+ if (!JDEP_WFL (dep))
+ return;
+
+ name = IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_WFL (dep)));
switch (JDEP_KIND (dep))
{
case JDEP_SUPER:
parse_error_context
(JDEP_WFL (dep), "Superclass `%s' of class `%s' not found",
- IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_WFL (dep))),
+ purify_type_name (name),
IDENTIFIER_POINTER (DECL_NAME (JDEP_DECL (dep))));
break;
case JDEP_FIELD:
parse_error_context
(JDEP_WFL (dep), "Type `%s' not found in declaration of field `%s'",
- IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_WFL (dep))),
+ purify_type_name (name),
IDENTIFIER_POINTER (DECL_NAME (JDEP_DECL (dep))));
break;
case JDEP_METHOD: /* Covers arguments */
parse_error_context
(JDEP_WFL (dep), "Type `%s' not found in the declaration of the "
"argument `%s' of method `%s'",
- IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_WFL (dep))),
+ purify_type_name (name),
IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_DECL_WFL (dep))),
IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_MISC (dep))));
break;
@@ -6161,7 +6937,7 @@ complete_class_report_errors (dep)
parse_error_context
(JDEP_WFL (dep), "Type `%s' not found in the declaration of the "
"return type of method `%s'",
- IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_WFL (dep))),
+ purify_type_name (name),
IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_DECL_WFL (dep))));
break;
case JDEP_INTERFACE:
@@ -6175,9 +6951,19 @@ complete_class_report_errors (dep)
parse_error_context
(JDEP_WFL (dep), "Type `%s' not found in the declaration of the "
"local variable `%s'",
- purify_type_name (IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_WFL (dep)))),
+ purify_type_name (IDENTIFIER_POINTER
+ (EXPR_WFL_NODE (JDEP_WFL (dep)))),
IDENTIFIER_POINTER (DECL_NAME (JDEP_DECL (dep))));
break;
+ case JDEP_EXCEPTION: /* As specified by `throws' */
+ parse_error_context
+ (JDEP_WFL (dep), "Class `%s' not found in `throws'",
+ IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_WFL (dep))));
+ break;
+ default:
+ /* Fix for -Wall. Just break doing nothing. The error will be
+ caught later */
+ break;
}
}
@@ -6188,35 +6974,107 @@ java_check_final ()
{
}
+/* Return a static string containing the DECL prototype string. If
+ DECL is a constructor, use the class name instead of the form
+ <init> */
+
+static char *
+get_printable_method_name (decl)
+ tree decl;
+{
+ char *to_return;
+ tree name = NULL_TREE;
+
+ if (DECL_CONSTRUCTOR_P (decl))
+ {
+ name = DECL_NAME (decl);
+ DECL_NAME (decl) = DECL_NAME (TYPE_NAME (DECL_CONTEXT (decl)));
+ }
+
+ to_return = lang_printable_name (decl, 0);
+ if (DECL_CONSTRUCTOR_P (decl))
+ DECL_NAME (decl) = name;
+
+ return to_return;
+}
+
+/* Reinstall the proper DECL_NAME on METHOD. Return 0 if the method
+ nevertheless needs to be verfied, 1 otherwise. */
+
static int
-check_method_redefinition (class, method)
- tree class, method;
+reset_method_name (method)
+ tree method;
{
- tree redef, name;
- tree cl = DECL_NAME (method);
- tree sig = TYPE_LANG_SPECIFIC (TREE_TYPE (method))->signature;
- /* decl name of generated <clinit> doesn't need to be fixed and
- checked */
- if (DECL_NAME (method) != clinit_identifier_node)
+ if (DECL_NAME (method) != clinit_identifier_node
+ && DECL_NAME (method) != finit_identifier_node)
{
/* NAME is just the plain name when Object is being defined */
- if (class != object_type_node)
- name = DECL_NAME (method) = EXPR_WFL_NODE (DECL_NAME (method));
- else
- name = DECL_NAME (method);
+ if (DECL_CONTEXT (method) != object_type_node)
+ DECL_NAME (method) = (DECL_CONSTRUCTOR_P (method) ?
+ init_identifier_node : GET_METHOD_NAME (method));
+ return 0;
}
else
+ return 1;
+}
+
+/* Return the name of METHOD_DECL, when DECL_NAME is a WFL */
+
+tree
+java_get_real_method_name (method_decl)
+ tree method_decl;
+{
+ tree method_name = DECL_NAME (method_decl);
+ if (DECL_CONSTRUCTOR_P (method_decl))
+ return init_identifier_node;
+
+ /* Explain here why METHOD_DECL doesn't have the DECL_CONSTRUCTUR_P
+ and still can be a constructor. FIXME */
+
+ /* Don't confuse method only bearing the name of their class as
+ constructors */
+ else if (!CLASS_FROM_SOURCE_P (DECL_CONTEXT (method_decl))
+ && ctxp
+ && ctxp->current_parsed_class_un == EXPR_WFL_NODE (method_name)
+ && get_access_flags_from_decl (method_decl) <= ACC_PROTECTED
+ && TREE_TYPE (TREE_TYPE (method_decl)) == void_type_node)
+ return init_identifier_node;
+ else
+ return EXPR_WFL_NODE (method_name);
+}
+
+/* Track method being redefined inside the same class. As a side
+ effect, set DECL_NAME to an IDENTIFIER (prior entering this
+ function it's a FWL, so we can track errors more accurately */
+
+static int
+check_method_redefinition (class, method)
+ tree class, method;
+{
+ tree redef, name;
+ tree cl = DECL_NAME (method);
+ tree sig = TYPE_ARGUMENT_SIGNATURE (TREE_TYPE (method));
+ /* decl name of artificial <clinit> and $finit$ doesn't need to be
+ fixed and checked */
+
+ /* Reset the method name before running the check. If it returns 1,
+ the method doesn't need to be verified with respect to method
+ redeclaration and we return 0 */
+ if (reset_method_name (method))
return 0;
-
+
+ name = DECL_NAME (method);
for (redef = TYPE_METHODS (class); redef; redef = TREE_CHAIN (redef))
{
- struct lang_type *t = TYPE_LANG_SPECIFIC (TREE_TYPE (redef));
-
- if (! t || (redef == method))
+ if (redef == method)
break;
- if (DECL_NAME (redef) == name && sig == t->signature)
+ if (DECL_NAME (redef) == name
+ && sig == TYPE_ARGUMENT_SIGNATURE (TREE_TYPE (redef)))
{
- parse_error_context (cl, "Duplicate method declaration");
+ parse_error_context
+ (cl, "Duplicate %s declaration `%s'",
+ (DECL_CONSTRUCTOR_P (redef) ? "constructor" : "method"),
+ get_printable_method_name (redef));
return 1;
}
}
@@ -6231,40 +7089,92 @@ static void
java_check_regular_methods (class_decl)
tree class_decl;
{
+ int saw_constructor = 0;
tree method;
tree class = CLASS_TO_HANDLE_TYPE (TREE_TYPE (class_decl));
tree super_class = CLASSTYPE_SUPER (class);
- int seen_constructor = 0;
+ tree saved_found_wfl = NULL_TREE, found = NULL_TREE;
+ tree mthrows;
+
+ /* It is not necessary to check methods defined in java.lang.Object */
+ if (class == object_type_node)
+ return;
- TYPE_METHODS (class) = nreverse (TYPE_METHODS (class));
+ if (!TYPE_NVIRTUALS (class))
+ TYPE_METHODS (class) = nreverse (TYPE_METHODS (class));
/* Should take interfaces into account. FIXME */
for (method = TYPE_METHODS (class); method; method = TREE_CHAIN (method))
{
- tree found, sig;
+ tree sig;
tree method_wfl = DECL_NAME (method);
int aflags;
- if (DECL_CONSTRUCTOR_P (method))
- seen_constructor = 1;
+ /* If we previously found something and its name was saved,
+ reinstall it now */
+ if (found && saved_found_wfl)
+ {
+ DECL_NAME (found) = saved_found_wfl;
+ saved_found_wfl = NULL_TREE;
+ }
/* Check for redefinitions */
if (check_method_redefinition (class, method))
continue;
- sig = build_java_argument_signature (TREE_TYPE (method));
+ /* If we see one constructor a mark so we don't generate the
+ default one. Also skip other verifications: constructors
+ can't be inherited hence hiden or overriden */
+ if (DECL_CONSTRUCTOR_P (method))
+ {
+ saw_constructor = 1;
+ continue;
+ }
+
+ /* We verify things thrown by the method. They must inherits from
+ java.lang.Throwable */
+ for (mthrows = DECL_FUNCTION_THROWS (method);
+ mthrows; mthrows = TREE_CHAIN (mthrows))
+ {
+ if (!inherits_from_p (TREE_VALUE (mthrows), throwable_type_node))
+ parse_error_context
+ (TREE_PURPOSE (mthrows), "Class `%s' in `throws' clause must be "
+ "a subclass of class `java.lang.Throwable'",
+ IDENTIFIER_POINTER
+ (DECL_NAME (TYPE_NAME (TREE_VALUE (mthrows)))));
+ }
+ sig = build_java_argument_signature (TREE_TYPE (method));
found = lookup_argument_method (super_class, DECL_NAME (method), sig);
- if (! found)
- continue;
+
+ /* Nothing overrides or it's a private method. */
+ if (!found)
+ continue;
+ if (METHOD_PRIVATE (found))
+ {
+ found = NULL_TREE;
+ continue;
+ }
+
+ /* If found wasn't verified, it's DECL_NAME won't be set properly.
+ We set it temporarily for the sake of the error report. */
+ saved_found_wfl = DECL_NAME (found);
+ reset_method_name (found);
+
/* Can't override a method with the same name and different return
types. */
if (TREE_TYPE (TREE_TYPE (found)) != TREE_TYPE (TREE_TYPE (method)))
- parse_warning_context
- (method_wfl,
- "Method `%s' redefined with different return type in class `%s'",
- lang_printable_name (found),
- IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
+ {
+ char *t = strdup (lang_printable_name (TREE_TYPE (TREE_TYPE (found)),
+ 0));
+ parse_error_context
+ (method_wfl,
+ "Method `%s' was defined with return type `%s' in class `%s'",
+ lang_printable_name (found, 0), t,
+ IDENTIFIER_POINTER
+ (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
+ free (t);
+ }
/* Can't override final. Can't override static. */
if (METHOD_FINAL (found) || METHOD_STATIC (found))
@@ -6276,7 +7186,7 @@ java_check_regular_methods (class_decl)
(method_wfl,
"%s methods can't be overriden. Method `%s' is %s in class `%s'",
(METHOD_FINAL (found) ? "Final" : "Static"),
- lang_printable_name (found),
+ lang_printable_name (found, 0),
(METHOD_FINAL (found) ? "final" : "static"),
IDENTIFIER_POINTER
(DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
@@ -6289,94 +7199,164 @@ java_check_regular_methods (class_decl)
(method_wfl,
"Instance methods can't be overriden by a static method. Method "
"`%s' is an instance method in class `%s'",
- lang_printable_name (found),
+ lang_printable_name (found, 0),
IDENTIFIER_POINTER
(DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
continue;
}
- /* Overriding/hiding public must be public or
- overriding/hiding protected must be protected or public */
- if ((METHOD_PUBLIC (found) && !METHOD_PUBLIC (method)) ||
- (METHOD_PROTECTED (found)
- && !(METHOD_PUBLIC (method) || METHOD_PROTECTED (method))))
+
+ aflags = get_access_flags_from_decl (found);
+ /* - Overriding/hiding public must be public
+ - Overriding/hiding protected must be protected or public
+ - If the overriden or hidden method has default (package)
+ access, then the overriding or hiding method must not be
+ private; otherwise, a compile-time error occurs */
+ if ((METHOD_PUBLIC (found) && !METHOD_PUBLIC (method))
+ || (METHOD_PROTECTED (found)
+ && !(METHOD_PUBLIC (method) || METHOD_PROTECTED (method)))
+ || (!(aflags & (ACC_PUBLIC | ACC_PRIVATE | ACC_STATIC))
+ && METHOD_PRIVATE (method)))
{
parse_error_context
(method_wfl,
"Methods can't be overridden to be more private. Method `%s' is "
- "%s in class `%s'", lang_printable_name (found),
- (METHOD_PUBLIC (found) ? "public" : "protected"),
- IDENTIFIER_POINTER
- (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
+ "not %s in class `%s'", lang_printable_name (method, 0),
+ (METHOD_PUBLIC (method) ? "public" :
+ (METHOD_PRIVATE (method) ? "private" : "protected")),
+ IDENTIFIER_POINTER (DECL_NAME
+ (TYPE_NAME (DECL_CONTEXT (found)))));
continue;
}
+ /* Overriding methods must have compatible `throws' clauses on checked
+ exceptions, if any */
+ check_throws_clauses (method, method_wfl, found);
+
/* If the method has default access in an other package, then
- issue a warning that the current method doesn't override the one
- that was found elsewhere */
- aflags = get_access_flags_from_decl (found);
- if ((!aflags || (aflags > ACC_PROTECTED))
- && !class_in_current_package (DECL_CONTEXT (found)))
+ issue a warning that the current method doesn't override the
+ one that was found elsewhere. Do not issue this warning when
+ the match was found in java.lang.Object. */
+ if (DECL_CONTEXT (found) != object_type_node
+ && (!aflags || (aflags > ACC_PROTECTED))
+ && !class_in_current_package (DECL_CONTEXT (found))
+ && flag_not_overriding)
parse_warning_context
(method_wfl, "Method `%s' in class `%s' does not "
"override the corresponding method in class `%s', which is "
"private to a different package",
- lang_printable_name (found),
+ lang_printable_name (found, 0),
IDENTIFIER_POINTER (DECL_NAME (class_decl)),
IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
- /* Check on (default) package access. FIXME. */
/* Inheriting multiple methods with the same signature. FIXME */
}
- TYPE_METHODS (class) = nreverse (TYPE_METHODS (class));
+ /* Don't forget eventual pending found and saved_found_wfl. Take
+ into account that we might have exited because we saw an
+ aritifical method as the last entry. */
+
+ if (found && !DECL_ARTIFICIAL (found) && saved_found_wfl)
+ DECL_NAME (found) = saved_found_wfl;
+
+ if (!TYPE_NVIRTUALS (class))
+ TYPE_METHODS (class) = nreverse (TYPE_METHODS (class));
- if (!seen_constructor)
+ if (!saw_constructor)
{
- /* No constructor seen, we craft one, at line 0 */
- int saved_lineno = lineno;
- tree meth, decl;
- lineno = 0;
- meth = make_node (FUNCTION_TYPE);
- TREE_TYPE (meth) = void_type_node;
- TYPE_ARG_TYPES (meth) = NULL_TREE;
- decl = add_method (class, 0, init_identifier_node,
- build_java_signature (meth));
+ /* No constructor seen, we craft one, at line 0. Since this
+ operation takes place after we laid methods out
+ (layout_class_methods), we prepare the its DECL
+ appropriately. */
+ int flags;
+ tree decl;
+
+ /* If the class is declared PUBLIC, the default constructor is
+ PUBLIC otherwise it has default access implied by no access
+ modifiers. */
+ flags = (get_access_flags_from_decl (class_decl) & ACC_PUBLIC ?
+ ACC_PUBLIC : 0);
+ decl = create_artificial_method (class, flags, void_type_node,
+ init_identifier_node, end_params_node);
DECL_CONSTRUCTOR_P (decl) = 1;
- lineno = saved_lineno;
+ layout_class_method (TREE_TYPE (class_decl), NULL_TREE, decl, NULL_TREE);
+ }
+}
+
+/* Return a non zero value if the `throws' clause of METHOD (if any)
+ is incompatible with the `throws' clause of FOUND (if any). */
+
+static void
+check_throws_clauses (method, method_wfl, found)
+ tree method, method_wfl, found;
+{
+ tree mthrows, fthrows;
+
+ /* Can't check these things with class loaded from bytecode. FIXME */
+ if (!CLASS_FROM_SOURCE_P (DECL_CONTEXT (found)))
+ return;
+
+ for (mthrows = DECL_FUNCTION_THROWS (method);
+ mthrows; mthrows = TREE_CHAIN (mthrows))
+ {
+ /* We don't verify unchecked expressions */
+ if (IS_UNCHECKED_EXCEPTION_P (TREE_VALUE (mthrows)))
+ continue;
+ /* Checked expression must be compatible */
+ for (fthrows = DECL_FUNCTION_THROWS (found);
+ fthrows; fthrows = TREE_CHAIN (fthrows))
+ if (inherits_from_p (TREE_VALUE (mthrows), TREE_VALUE (fthrows)))
+ break;
+ if (!fthrows)
+ {
+ parse_error_context
+ (method_wfl, "Invalid checked exception class `%s' in "
+ "`throws' clause. The exception must be a subclass of an "
+ "exception thrown by `%s' from class `%s'",
+ IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (TREE_VALUE (mthrows)))),
+ lang_printable_name (found, 0),
+ IDENTIFIER_POINTER
+ (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
+ }
}
}
/* Check abstract method of interface INTERFACE */
static void
-java_check_abstract_methods (interface)
- tree interface;
+java_check_abstract_methods (interface_decl)
+ tree interface_decl;
{
int i, n;
tree method, basetype_vec, found;
+ tree interface = TREE_TYPE (interface_decl);
for (method = TYPE_METHODS (interface); method; method = TREE_CHAIN (method))
{
- char *csig;
- tree name = DECL_NAME (method);
+ tree method_wfl = DECL_NAME (method);
/* 2- Check for double definition inside the defining interface */
if (check_method_redefinition (interface, method))
continue;
/* 3- Overriding is OK as far as we preserve the return type and
- the thrown exceptions */
+ the thrown exceptions (FIXME) */
found = lookup_java_interface_method2 (interface, method);
if (found)
{
+ char *t;
+ tree saved_found_wfl = DECL_NAME (found);
+ reset_method_name (found);
+ t = strdup (lang_printable_name (TREE_TYPE (TREE_TYPE (found)), 0));
parse_error_context
- (lookup_cl (method),
- "Method `%s' previously defined in interface `%s' is "
- "redefined with different return type in interface `%s'",
- lang_printable_name (found),
- IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))),
- IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (interface))));
+ (method_wfl,
+ "Method `%s' was defined with return type `%s' in class `%s'",
+ lang_printable_name (found, 0), t,
+ IDENTIFIER_POINTER
+ (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
+ free (t);
continue;
+
+ DECL_NAME (found) = saved_found_wfl;
}
}
@@ -6398,41 +7378,27 @@ java_check_abstract_methods (interface)
found = lookup_java_interface_method2 (interface,
sub_interface_method);
if (found && (found != sub_interface_method))
- parse_error_context
- (lookup_cl (sub_interface_method),
- "Interface `%s' inherits method `%s' from interface `%s'. This "
- "method is redefined with a different return "
- "type in interface `%s'",
- IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (interface))),
- lang_printable_name (found),
- IDENTIFIER_POINTER
- (DECL_NAME (TYPE_NAME (DECL_CONTEXT (sub_interface_method)))),
- IDENTIFIER_POINTER
- (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
+ {
+ tree saved_found_wfl = DECL_NAME (found);
+ reset_method_name (found);
+ parse_error_context
+ (lookup_cl (sub_interface_method),
+ "Interface `%s' inherits method `%s' from interface `%s'. "
+ "This method is redefined with a different return type in "
+ "interface `%s'",
+ IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (interface))),
+ lang_printable_name (found, 0),
+ IDENTIFIER_POINTER
+ (DECL_NAME (TYPE_NAME
+ (DECL_CONTEXT (sub_interface_method)))),
+ IDENTIFIER_POINTER
+ (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
+ DECL_NAME (found) = saved_found_wfl;
+ }
}
}
}
-/* Check the method on all the defined classes. Should be done to the
- classes declared in the compilation unit only. FIXME */
-
-void
-java_check_methods ()
-{
-
- tree current;
- for (current = ctxp->class_list; current; current = TREE_CHAIN (current))
- if (CLASS_FROM_SOURCE_P (TREE_TYPE (current)))
- {
- tree class = CLASS_TO_HANDLE_TYPE (TREE_TYPE (current));
-
- if (CLASS_INTERFACE (TYPE_NAME (class)))
- java_check_abstract_methods (class);
- else
- java_check_regular_methods (current);
- }
-}
-
/* Lookup methods in interfaces using their name and partial
signature. Return a matching method only if their types differ. */
@@ -6474,9 +7440,12 @@ lookup_java_method2 (clas, method_decl, do_interface)
tree clas, method_decl;
int do_interface;
{
- tree method, method_signature, method_name, method_type;
+ tree method, method_signature, method_name, method_type, name;
+
method_signature = build_java_argument_signature (TREE_TYPE (method_decl));
- method_name = DECL_NAME (method_decl);
+ name = DECL_NAME (method_decl);
+ method_name = (TREE_CODE (name) == EXPR_WITH_FILE_LOCATION ?
+ EXPR_WFL_NODE (name) : name);
method_type = TREE_TYPE (TREE_TYPE (method_decl));
while (clas != NULL_TREE)
@@ -6485,12 +7454,12 @@ lookup_java_method2 (clas, method_decl, do_interface)
method != NULL_TREE; method = TREE_CHAIN (method))
{
tree method_sig = build_java_argument_signature (TREE_TYPE (method));
- if (DECL_NAME (method) == method_name
+ tree name = DECL_NAME (method);
+ if ((TREE_CODE (name) == EXPR_WITH_FILE_LOCATION ?
+ EXPR_WFL_NODE (name) : name) == method_name
&& method_sig == method_signature
&& TREE_TYPE (TREE_TYPE (method)) != method_type)
- {
- return method;
- }
+ return method;
}
clas = (do_interface ? NULL_TREE : CLASSTYPE_SUPER (clas));
}
@@ -6579,74 +7548,26 @@ find_in_imports (class_type)
{
TYPE_NAME (class_type) = EXPR_WFL_NODE (TREE_PURPOSE (import));
QUALIFIED_P (TYPE_NAME (class_type)) = 1;
- return check_pkg_class_access (TYPE_NAME (class_type),
- TREE_PURPOSE (import));
}
return 0;
}
-/* Process a import on demand statement (lazy) */
-
static int
-read_import_entry (jcf, dirp, returned_name)
- JCF *jcf;
- DIR *dirp;
- char **returned_name;
+note_possible_classname (name, len)
+ char *name;
+ int len;
{
- if (dirp)
- {
- struct dirent *direntp = readdir (dirp);
- if (!direntp)
- {
- *returned_name = NULL;
- return 0;
- }
- else
- {
- *returned_name = direntp->d_name;
- return (strlen (direntp->d_name));
- }
- }
+ tree node;
+ if (len > 5 && strncmp (&name [len-5], ".java", 5) == 0)
+ len = len - 5;
+ else if (len > 6 && strncmp (&name [len-6], ".class", 6) == 0)
+ len = len - 6;
else
- {
- int current_dir_len = strlen (jcf->classname);
- char *current_entry;
- int current_entry_len;
-
- /* Here we read a zip directory as a file directory. The files
- we're selecting must have the same root than the directory
- we're examining. */
-
- ZipDirectory *zipd = (ZipDirectory *)jcf->zipd;
-
- while (zipd)
- {
- current_entry = ZIPDIR_FILENAME (zipd);
- current_entry_len = zipd->filename_length;
- while (current_entry_len && current_entry [current_entry_len] != '/')
- current_entry_len--;
- /* If the path of the current file doesn't match the directory we're
- scanning, that the end of the search */
- current_entry_len++;
- if (strncmp (jcf->classname, current_entry, current_dir_len))
- {
- *returned_name = NULL;
- return 0;
- }
- /* Ok, we have at least the same path. The position of the last '/'
- of the current file we're examining should match the size of
- name of the directory we're browsing, otherwise that an entry
- belonging to a sub directory, we want to skip it. */
- if (current_entry_len != current_dir_len)
- zipd = ZIPDIR_NEXT (zipd);
- else
- {
- jcf->zipd = ZIPDIR_NEXT (zipd); /* Prepare next read */
- *returned_name = &current_entry [current_entry_len];
- return (zipd->filename_length - current_entry_len);
- }
- }
- }
+ return 0;
+ node = ident_subst (name, len, "", '/', '.', "");
+ IS_A_CLASSFILE_NAME (node) = 1; /* Or soon to be */
+ QUALIFIED_P (node) = 1; /* As soon as we turn / into . */
+ return 1;
}
/* Read a import directory, gathering potential match for further type
@@ -6657,30 +7578,104 @@ static void
read_import_dir (wfl)
tree wfl;
{
- char *name = IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl));
- int name_len = IDENTIFIER_LENGTH (EXPR_WFL_NODE (wfl)), reclen;
+ tree package_id = EXPR_WFL_NODE (wfl);
+ char *package_name = IDENTIFIER_POINTER (package_id);
+ int package_length = IDENTIFIER_LENGTH (package_id);
DIR *dirp = NULL;
- tree dirname = ident_subst (name, name_len, "", '.', '/', "");
- JCF jcfr, *jcf, *saved_jcf = current_jcf;
- char *founddirname, *d_name;
- struct ZipFileCache zip_cache;
+ JCF *saved_jcf = current_jcf;
+
+ int found = 0;
+ int k;
+ void *entry;
+ struct buffer filename[1];
+
+
+ if (IS_AN_IMPORT_ON_DEMAND_P (package_id))
+ return;
+ IS_AN_IMPORT_ON_DEMAND_P (package_id) = 1;
- jcf = &jcfr;
- if (!classpath)
- fix_classpath ();
- if (!(founddirname = find_class (name, name_len, jcf, 0)))
- fatal ("Can't import `%s'", name);
- if (jcf->outofsynch)
- jcf_out_of_synch (jcf);
- if (jcf->seen_in_zip)
- jcf->zipd = ZIPDIR_NEXT ((ZipDirectory *)jcf->zipd);
+ BUFFER_INIT (filename);
+ buffer_grow (filename, package_length + 100);
- else if (founddirname && (dirp = opendir (founddirname)))
+ for (entry = jcf_path_start (); entry != NULL; entry = jcf_path_next (entry))
{
- readdir (dirp); readdir (dirp);
+ char *entry_name = jcf_path_name (entry);
+ int entry_length = strlen (entry_name);
+ if (jcf_path_is_zipfile (entry))
+ {
+ ZipFile *zipf;
+ buffer_grow (filename, entry_length);
+ memcpy (filename->data, entry_name, entry_length - 1);
+ filename->data[entry_length-1] = '\0';
+ zipf = opendir_in_zip (filename->data, jcf_path_is_system (entry));
+ if (zipf == NULL)
+ error ("malformed .zip archive in CLASSPATH: %s", entry_name);
+ else
+ {
+ ZipDirectory *zipd = (ZipDirectory *) zipf->central_directory;
+ BUFFER_RESET (filename);
+ for (k = 0; k < package_length; k++)
+ {
+ char ch = package_name[k];
+ *filename->ptr++ = ch == '.' ? '/' : ch;
+ }
+ *filename->ptr++ = '/';
+
+ for (k = 0; k < zipf->count; k++, zipd = ZIPDIR_NEXT (zipd))
+ {
+ char *current_entry = ZIPDIR_FILENAME (zipd);
+ int current_entry_len = zipd->filename_length;
+
+ if (current_entry_len >= BUFFER_LENGTH (filename)
+ && strncmp (filename->data, current_entry,
+ BUFFER_LENGTH (filename)) != 0)
+ continue;
+ found |= note_possible_classname (current_entry,
+ current_entry_len);
+ }
+ }
+ }
+ else
+ {
+ BUFFER_RESET (filename);
+ buffer_grow (filename, entry_length + package_length + 4);
+ strcpy (filename->data, entry_name);
+ filename->ptr = filename->data + entry_length;
+ for (k = 0; k < package_length; k++)
+ {
+ char ch = package_name[k];
+ *filename->ptr++ = ch == '.' ? '/' : ch;
+ }
+ *filename->ptr = '\0';
+
+ dirp = opendir (filename->data);
+ if (dirp == NULL)
+ continue;
+ *filename->ptr++ = '/';
+ for (;;)
+ {
+ int len;
+ char *d_name;
+ struct dirent *direntp = readdir (dirp);
+ if (!direntp)
+ break;
+ d_name = direntp->d_name;
+ len = strlen (direntp->d_name);
+ buffer_grow (filename, len+1);
+ strcpy (filename->ptr, d_name);
+ found |= note_possible_classname (filename->data + entry_length,
+ package_length+len+1);
+ }
+ if (dirp)
+ closedir (dirp);
+ }
}
- if (!founddirname && !dirp)
+ free (filename->data);
+
+ /* Here we should have a unified way of retrieving an entry, to be
+ indexed. */
+ if (!found)
{
static int first = 1;
if (first)
@@ -6688,55 +7683,17 @@ read_import_dir (wfl)
char buffer [256];
sprintf (buffer, "Can't find default package `%s'. Check "
"the CLASSPATH environment variable and the access to the "
- "archives.", name);
+ "archives.", package_name);
error (buffer);
java_error_count++;
first = 0;
}
else
- parse_error_context (wfl, "Package `%s' not found in import", name);
+ parse_error_context (wfl, "Package `%s' not found in import",
+ package_name);
current_jcf = saved_jcf;
return;
}
-
- /* Here we should have a unified way of retrieving an entry, to be
- indexed. */
- while ((reclen = read_import_entry (jcf, dirp, &d_name)))
- {
- int java_or_class = 0;
- int len;
- if ((reclen > 5)
- && !strcmp (&d_name [reclen-5], ".java"))
- {
- java_or_class = 1;
- len = reclen - 5;
- }
-
- if (!java_or_class && (reclen > 6) &&
- !strcmp (&d_name [reclen-6], ".class"))
- {
- java_or_class = 2;
- len = reclen - 6;
- }
-
- if (java_or_class)
- {
- char *id_name;
- tree node, old;
-
- obstack_grow (&temporary_obstack, name, name_len);
- obstack_1grow (&temporary_obstack, '/');
- obstack_grow0 (&temporary_obstack, d_name, len);
- id_name = obstack_finish (&temporary_obstack);
-
- node = get_identifier (id_name);
- IS_A_CLASSFILE_NAME (node) = 1; /* Or soon to be */
- QUALIFIED_P (node) = 1; /* As soon as we turn / into . */
- }
- }
- if (dirp)
- closedir (dirp);
-
current_jcf = saved_jcf;
}
@@ -6755,11 +7712,10 @@ find_in_imports_on_demand (class_type)
for (import = ctxp->import_demand_list; import; import = TREE_CHAIN (import))
{
char *id_name;
- tree found;
obstack_grow (&temporary_obstack,
IDENTIFIER_POINTER (EXPR_WFL_NODE (TREE_PURPOSE (import))),
IDENTIFIER_LENGTH (EXPR_WFL_NODE (TREE_PURPOSE (import))));
- obstack_1grow (&temporary_obstack, '/');
+ obstack_1grow (&temporary_obstack, '.');
obstack_grow0 (&temporary_obstack,
IDENTIFIER_POINTER (TYPE_NAME (class_type)),
IDENTIFIER_LENGTH (TYPE_NAME (class_type)));
@@ -6792,9 +7748,7 @@ find_in_imports_on_demand (class_type)
tree decl;
int saved_lineno = lineno;
lineno = EXPR_WFL_LINENO (cl);
- TYPE_NAME (class_type) = ident_subst (IDENTIFIER_POINTER (node_to_use),
- IDENTIFIER_LENGTH (node_to_use),
- "", '/', '.', "");
+ TYPE_NAME (class_type) = node_to_use;
QUALIFIED_P (TYPE_NAME (class_type)) = 1;
decl = IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type));
/* If there is no DECL set for the class or if the class isn't
@@ -6809,6 +7763,49 @@ find_in_imports_on_demand (class_type)
return (seen_once < 0 ? 0 : seen_once); /* It's ok not to have found */
}
+static tree
+resolve_package (pkg, next)
+ tree pkg, *next;
+{
+ tree type_name = NULL_TREE;
+ char *name = IDENTIFIER_POINTER (EXPR_WFL_NODE (pkg));
+
+ /* The trick is to determine when the package name stops and were
+ the name of something contained in the package starts. Then we
+ return a fully qualified name of what we want to get. */
+
+ /* Do a quick search on well known package names */
+ if (!strncmp (name, "java.lang.reflect", 17))
+ {
+ *next =
+ TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (EXPR_WFL_QUALIFICATION (pkg))));
+ type_name = lookup_package_type (name, 17);
+ }
+ else if (!strncmp (name, "java.lang", 9))
+ {
+ *next = TREE_CHAIN (TREE_CHAIN (EXPR_WFL_QUALIFICATION (pkg)));
+ type_name = lookup_package_type (name, 9);
+ }
+ else
+ return NULL_TREE; /* FIXME, search all imported packages. */
+
+ return type_name;
+}
+
+static tree
+lookup_package_type (name, from)
+ char *name;
+ int from;
+{
+ char subname [128];
+ char *sub = &name[from+1];
+ while (*sub != '.' && *sub)
+ sub++;
+ strncpy (subname, name, sub-name);
+ subname [sub-name] = '\0';
+ return get_identifier (subname);
+}
+
/* Check that CLASS_NAME refers to a PUBLIC class. Return 0 if no
access violations were found, 1 otherwise. */
@@ -6818,7 +7815,6 @@ check_pkg_class_access (class_name, cl)
tree cl;
{
tree type;
- int access;
if (!QUALIFIED_P (class_name) || !IDENTIFIER_CLASS_VALUE (class_name))
return 0;
@@ -6828,6 +7824,13 @@ check_pkg_class_access (class_name, cl)
if (!CLASS_PUBLIC (TYPE_NAME (type)))
{
+ /* Access to a private class within the same package is
+ allowed. */
+ tree l, r;
+ breakdown_qualified (&l, &r, class_name);
+ if (l == ctxp->package)
+ return 0;
+
parse_error_context
(cl, "Can't access %s `%s'. Only public classes and interfaces in "
"other packages can be accessed",
@@ -6846,85 +7849,100 @@ declare_local_variables (modifier, type, vlist)
tree type;
tree vlist;
{
- tree decl, current, returned_type, type_wfl, init_stmt = NULL_TREE;
+ tree decl, current, saved_type;
+ tree type_wfl = NULL_TREE;
int must_chain = 0;
- /* Push a new block if statement were seen between the last time we
+ /* Push a new block if statements were seen between the last time we
pushed a block and now. Keep a cound of block to close */
- if (BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (current_function_decl)))
+ if (BLOCK_EXPR_BODY (GET_CURRENT_BLOCK (current_function_decl)))
{
- tree body = DECL_FUNCTION_BODY (current_function_decl);
+ tree body = GET_CURRENT_BLOCK (current_function_decl);
tree b = enter_block ();
- BLOCK_EXPR_ORIGIN(b) = body;
+ BLOCK_EXPR_ORIGIN (b) = body;
}
if (modifier)
{
int i;
for (i = 0; i <= 10; i++) if (1 << i & modifier) break;
- parse_error_context
- (ctxp->modifier_ctx [i],
- (modifier == ACC_FINAL ?
- "Unsupported JDK1.1 `final' locals" :
- "Only `final' is allowed as a local variables modifier"));
- return;
- }
-
- if (unresolved_type_p (type, &returned_type))
- {
- if (returned_type)
- type = returned_type;
+ if (modifier == ACC_FINAL)
+ {
+ if (flag_static_local_jdk1_1)
+ parse_warning_context (ctxp->modifier_ctx [i],
+ "Unsupported JDK1.1 `final' local variable "
+ "(treated as non final)");
+ }
else
{
- type_wfl = type;
- type = obtain_incomplete_type (type);
- must_chain = 1;
+ parse_error_context
+ (ctxp->modifier_ctx [i],
+ "Only `final' is allowed as a local variables modifier");
+ return;
}
}
-
- for (current = vlist; current; current = TREE_CHAIN (current))
+
+ /* Obtain an incomplete type if TYPE is not complete. TYPE_WFL will
+ hold the TYPE value if a new incomplete has to be created (as
+ opposed to being found already existing and reused). */
+ SET_TYPE_FOR_RESOLUTION (type, type_wfl, must_chain);
+
+ /* If TYPE is fully resolved and we don't have a reference, make one */
+ PROMOTE_RECORD_IF_COMPLETE (type, must_chain);
+
+ /* Go through all the declared variables */
+ for (current = vlist, saved_type = type; current;
+ current = TREE_CHAIN (current), type = saved_type)
{
+ tree other, real_type;
tree wfl = TREE_PURPOSE (current);
tree name = EXPR_WFL_NODE (wfl);
tree init = TREE_VALUE (current);
- tree other = lookup_name_in_blocks (name);
- /* Don't try to use an INIT statement when an error was found */
- if (init && java_error_count)
- init = NULL_TREE;
+ /* Process NAME, as it may specify extra dimension(s) for it */
+ type = build_array_from_name (type, type_wfl, name, &name);
- if (other)
- parse_error_context
- (wfl, "Variable `%s' is already defined in this method and was "
- "declared `%s %s' in line %d",
- IDENTIFIER_POINTER (name), lang_printable_name (TREE_TYPE (other)),
- IDENTIFIER_POINTER (name), DECL_SOURCE_LINE (other));
- else
+ /* Variable redefinition check */
+ if ((other = lookup_name_in_blocks (name)))
{
- if (!must_chain && TREE_CODE (type) == RECORD_TYPE)
- type = promote_type (type);
- /* Never layout this decl. This will be done when its scope
- will be entered */
- decl = build_decl_no_layout (VAR_DECL, name, type);
- BLOCK_CHAIN_DECL (decl);
+ variable_redefinition_error (wfl, name, TREE_TYPE (other),
+ DECL_SOURCE_LINE (other));
+ continue;
+ }
- /* Add the initialization function to the current function's code */
- if (init)
- {
- tree wfl;
- MODIFY_EXPR_FROM_INITIALIZATION_P (init) = 1;
- java_method_add_stmt
- (current_function_decl,
- build_debugable_stmt (EXPR_WFL_LINECOL (init), init));
- }
+ /* Type adjustment. We may have just readjusted TYPE because
+ the variable specified more dimensions. Make sure we have
+ a reference if we can and don't have one already. */
+ PROMOTE_RECORD_IF_COMPLETE (type, must_chain);
- if (must_chain)
- {
- jdep *dep;
- register_incomplete_type (JDEP_VARIABLE, type_wfl, decl, type);
- dep = CLASSD_LAST (ctxp->classd_list);
- JDEP_GET_PATCH (dep) = &TREE_TYPE (decl);
- }
+ real_type = GET_REAL_TYPE (type);
+ /* Never layout this decl. This will be done when its scope
+ will be entered */
+ decl = build_decl (VAR_DECL, name, real_type);
+ BLOCK_CHAIN_DECL (decl);
+
+ /* Don't try to use an INIT statement when an error was found */
+ if (init && java_error_count)
+ init = NULL_TREE;
+
+ /* Add the initialization function to the current function's code */
+ if (init)
+ {
+ /* Name might have been readjusted */
+ EXPR_WFL_NODE (TREE_OPERAND (init, 0)) = name;
+ MODIFY_EXPR_FROM_INITIALIZATION_P (init) = 1;
+ java_method_add_stmt (current_function_decl,
+ build_debugable_stmt (EXPR_WFL_LINECOL (init),
+ init));
+ }
+
+ /* Setup dependency the type of the decl */
+ if (must_chain)
+ {
+ jdep *dep;
+ register_incomplete_type (JDEP_VARIABLE, type_wfl, decl, type);
+ dep = CLASSD_LAST (ctxp->classd_list);
+ JDEP_GET_PATCH (dep) = &TREE_TYPE (decl);
}
}
SOURCE_FRONTEND_DEBUG (("Defined locals"));
@@ -6940,25 +7958,24 @@ source_start_java_method (fndecl)
tree parm_decl;
int i;
- extern tree current_binding_level;
current_function_decl = fndecl;
/* New scope for the function */
enter_block ();
for (tem = TYPE_ARG_TYPES (TREE_TYPE (fndecl)), i = 0;
- tem != NULL_TREE; tem = TREE_CHAIN (tem), i++)
+ tem != end_params_node; tem = TREE_CHAIN (tem), i++)
{
tree type = TREE_VALUE (tem);
tree name = TREE_PURPOSE (tem);
- /* If type is incomplete. Layout can't take place
- now. Create an incomplete decl and ask for the decl to be
- patched later */
+ /* If type is incomplete. Create an incomplete decl and ask for
+ the decl to be patched later */
if (INCOMPLETE_TYPE_P (type))
{
jdep *jdep;
- parm_decl = build_decl_no_layout (PARM_DECL, name, type);
-
+ tree real_type = GET_REAL_TYPE (type);
+ parm_decl = build_decl (PARM_DECL, name, real_type);
+ type = obtain_incomplete_type (type);
register_incomplete_type (JDEP_PARM, NULL_TREE, NULL_TREE, type);
jdep = CLASSD_LAST (ctxp->classd_list);
JDEP_MISC (jdep) = name;
@@ -6975,6 +7992,47 @@ source_start_java_method (fndecl)
DECL_ARG_SLOT_COUNT (current_function_decl) = i;
}
+/* Called during parsing. Creates an artificial method declaration. */
+
+static tree
+create_artificial_method (class, flags, type, name, args)
+ tree class;
+ int flags;
+ tree type, name, args;
+{
+ int saved_lineno = lineno;
+ tree mdecl;
+
+ lineno = 0;
+ mdecl = make_node (FUNCTION_TYPE);
+ TREE_TYPE (mdecl) = type;
+ TYPE_ARG_TYPES (mdecl) = args;
+ mdecl = add_method (class, flags, name, build_java_signature (mdecl));
+ lineno = saved_lineno;
+ DECL_ARTIFICIAL (mdecl) = 1;
+ return mdecl;
+}
+
+/* Starts the body if an artifical method. */
+
+static void
+start_artificial_method_body (mdecl)
+ tree mdecl;
+{
+ DECL_SOURCE_LINE (mdecl) = 1;
+ DECL_SOURCE_LINE_MERGE (mdecl, 1);
+ source_start_java_method (mdecl);
+ enter_block ();
+}
+
+static void
+end_artificial_method_body (mdecl)
+ tree mdecl;
+{
+ BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (mdecl)) = exit_block ();
+ exit_block ();
+}
+
/* Called during expansion. Push decls formerly built from argument
list so they're usable during expansion. */
@@ -6983,9 +8041,7 @@ expand_start_java_method (fndecl)
tree fndecl;
{
tree tem, *ptr;
- tree parm_decl;
- extern tree current_binding_level;
current_function_decl = fndecl;
announce_function (fndecl);
@@ -6995,10 +8051,15 @@ expand_start_java_method (fndecl)
while (tem)
{
tree next = TREE_CHAIN (tem);
- DECL_ARG_TYPE (tem) = TREE_TYPE (tem);
+ tree type = TREE_TYPE (tem);
+#ifdef PROMOTE_PROTOTYPES
+ if (TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)
+ && INTEGRAL_TYPE_P (type))
+ type = integer_type_node;
+#endif
+ DECL_ARG_TYPE (tem) = type;
layout_decl (tem, 0);
pushdecl (tem);
- INITIALIZED_P (tem) = 1; /* Parms are initialized */
*ptr = tem;
ptr = &TREE_CHAIN (tem);
tem = next;
@@ -7006,7 +8067,6 @@ expand_start_java_method (fndecl)
*ptr = NULL_TREE;
pushdecl_force_head (DECL_ARGUMENTS (fndecl));
lineno = DECL_SOURCE_LINE_FIRST (fndecl);
- complete_start_java_method (fndecl);
}
/* Terminate a function and expand its body. */
@@ -7019,6 +8079,9 @@ source_end_java_method ()
java_parser_context_save_global ();
lineno = ctxp->last_ccb_indent1;
+ /* Set EH language codes */
+ java_set_exception_lang_code ();
+
/* Generate function's code */
if (BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (fndecl))
&& ! flag_emit_class_files)
@@ -7033,6 +8096,8 @@ source_end_java_method ()
if (! flag_emit_class_files)
{
lineno = DECL_SOURCE_LINE_LAST (fndecl);
+ /* Emit catch-finally clauses */
+ emit_handlers ();
expand_function_end (input_filename, lineno, 0);
/* Run the optimizers and output assembler code for this function. */
@@ -7051,17 +8116,24 @@ tree
java_method_add_stmt (fndecl, expr)
tree fndecl, expr;
{
- tree body = BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (fndecl));
- tree node;
+ return add_stmt_to_block (GET_CURRENT_BLOCK (fndecl), NULL_TREE, expr);
+}
+static tree
+add_stmt_to_block (b, type, stmt)
+ tree b, type, stmt;
+{
+ tree body = BLOCK_EXPR_BODY (b), c;
+
if (java_error_count)
return body;
- if ((node = add_stmt_to_compound (body, NULL_TREE, expr)) == body)
+
+ if ((c = add_stmt_to_compound (body, type, stmt)) == body)
return body;
- BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (fndecl)) = node;
- TREE_SIDE_EFFECTS (node) = 1;
- return node;
+ BLOCK_EXPR_BODY (b) = c;
+ TREE_SIDE_EFFECTS (c) = 1;
+ return c;
}
/* Add STMT to EXISTING if possible, otherwise create a new
@@ -7071,39 +8143,103 @@ static tree
add_stmt_to_compound (existing, type, stmt)
tree existing, type, stmt;
{
- tree node;
-
- if (existing && (TREE_CODE (existing) == COMPOUND_EXPR)
- && TREE_OPERAND (existing, 1) == size_zero_node)
- {
- TREE_OPERAND (existing, 1) = stmt;
- TREE_TYPE (existing) = type;
- return existing;
- }
- else if (existing)
- node = build (COMPOUND_EXPR, type, existing, stmt);
+ if (existing)
+ return build (COMPOUND_EXPR, type, existing, stmt);
else
- node = build (COMPOUND_EXPR, type, stmt, size_zero_node);
-
- return node;
+ return stmt;
}
/* Hold THIS for the scope of the current public method decl. */
static tree current_this;
-/* Layout all class found during parsing */
+void java_layout_seen_class_methods ()
+{
+ tree previous_list = all_class_list;
+ tree end = NULL_TREE;
+ tree current;
+
+ while (1)
+ {
+ for (current = previous_list;
+ current != end; current = TREE_CHAIN (current))
+ layout_class_methods (TREE_TYPE (TREE_VALUE (current)));
+
+ if (previous_list != all_class_list)
+ {
+ end = previous_list;
+ previous_list = all_class_list;
+ }
+ else
+ break;
+ }
+}
+
+/* Layout the methods of all classes loaded in one way on an
+ other. Check methods of source parsed classes. Then reorder the
+ fields and layout the classes or the type of all source parsed
+ classes */
void
java_layout_classes ()
{
tree current;
- for (current = ctxp->class_list; current; current = TREE_CHAIN (current))
+ int save_error_count = java_error_count;
+
+ /* Layout the methods of all classes seen so far */
+ java_layout_seen_class_methods ();
+ java_parse_abort_on_error ();
+ all_class_list = NULL_TREE;
+
+ /* Then check the methods of all parsed classes */
+ for (current = ctxp->gclass_list; current; current = TREE_CHAIN (current))
+ if (CLASS_FROM_SOURCE_P (TREE_TYPE (TREE_VALUE (current))))
+ CHECK_METHODS (TREE_VALUE (current));
+ java_parse_abort_on_error ();
+
+ for (current = ctxp->gclass_list; current; current = TREE_CHAIN (current))
{
- current_class = TREE_TYPE (current);
- TYPE_FIELDS (current_class) = nreverse (TYPE_FIELDS (current_class));
- if (!TYPE_SIZE (current_class))
- safe_layout_class (current_class);
+ current_class = TREE_TYPE (TREE_VALUE (current));
+
+ /* Reverse the fields, but leave the dummy field in front.
+ Fields are already ordered for Object and Class */
+ if (TYPE_FIELDS (current_class) && current_class != object_type_node
+ && current_class != class_type_node)
+ {
+ /* If the dummy field is there, reverse the right fields and
+ just layout the type for proper fields offset */
+ if (!DECL_NAME (TYPE_FIELDS (current_class)))
+ {
+ tree fields = TYPE_FIELDS (current_class);
+ TREE_CHAIN (fields) = nreverse (TREE_CHAIN (fields));
+ TYPE_SIZE (current_class) = NULL_TREE;
+ layout_type (current_class);
+ }
+ /* We don't have a dummy field, we need to layout the class,
+ after having reversed the fields */
+ else
+ {
+ TYPE_FIELDS (current_class) =
+ nreverse (TYPE_FIELDS (current_class));
+ TYPE_SIZE (current_class) = NULL_TREE;
+ layout_class (current_class);
+ }
+ }
+ else
+ layout_class (current_class);
+
+ /* From now on, the class is considered completely loaded */
+ CLASS_LOADED_P (current_class) = 1;
+
+ /* Error reported by the caller */
+ if (java_error_count)
+ return;
}
+
+ /* We might have reloaded classes durign the process of laying out
+ classes for code generation. We must layout the methods of those
+ late additions, as constructor checks might use them */
+ java_layout_seen_class_methods ();
+ java_parse_abort_on_error ();
}
/* Expand all methods in all registered classes. */
@@ -7115,16 +8251,24 @@ java_complete_expand_methods ()
for (current = ctxp->class_list; current; current = TREE_CHAIN (current))
{
- extern tree current_constant_pool_data_ref;
tree class_type = CLASS_TO_HANDLE_TYPE (TREE_TYPE (current));
tree decl;
- int saved_lineno;
current_class = TREE_TYPE (current);
/* Initialize a new constant pool */
init_outgoing_cpool ();
+ /* We want <clinit> (if any) to be processed first. */
+ decl = tree_last (TYPE_METHODS (class_type));
+ if (decl && DECL_NAME (decl) == clinit_identifier_node)
+ {
+ tree list = nreverse (TYPE_METHODS (class_type));
+ list = TREE_CHAIN (list);
+ TREE_CHAIN (decl) = NULL_TREE;
+ TYPE_METHODS (class_type) = chainon (decl, nreverse (list));
+ }
+
/* Don't process function bodies in interfaces */
if (!CLASS_INTERFACE (TYPE_NAME (current_class)))
for (decl = TYPE_METHODS (class_type); decl; decl = TREE_CHAIN (decl))
@@ -7143,91 +8287,204 @@ java_complete_expand_methods ()
restore_line_number_status (0);
}
}
- else
+ else if (METHOD_ABSTRACT (decl) || METHOD_NATIVE (decl))
+ continue;
+ else
java_complete_expand_method (decl);
}
+ /* Now verify constructor circularity (stop after the first one
+ we find) */
+ if (!CLASS_INTERFACE (TYPE_NAME (current_class)))
+ for (decl = TYPE_METHODS (class_type); decl; decl = TREE_CHAIN (decl))
+ if (DECL_CONSTRUCTOR_P (decl) &&
+ verify_constructor_circularity (decl, decl))
+ break;
+
/* Make the class data, register it and run the rest of decl
compilation on it */
- if (!java_error_count && ! flag_emit_class_files)
+ if (!java_error_count)
{
- make_class_data (current_class);
- register_class ();
- rest_of_decl_compilation (TYPE_NAME (current_class), (char*) 0, 1, 0);
+ if (flag_emit_class_files)
+ write_classfile (current_class);
+ if (flag_emit_xref)
+ expand_xref (current_class);
+ else if (! flag_syntax_only)
+ finish_class (current_class);
}
}
}
+/* Hold a list of catch clauses list. The first element of this list is
+ the list of the catch clauses of the currently analysed try block. */
+static tree currently_caught_type_list;
+
/* Complete and expand a method. */
static void
java_complete_expand_method (mdecl)
tree mdecl;
{
- tree node;
- jdep *current;
- int no_ac_found = 1;
-
- /* We generate some code for an empty constructor */
- if (DECL_CONSTRUCTOR_P (mdecl) && !DECL_FUNCTION_BODY (mdecl))
- {
- tree arg_list, func, call;
- tree method_type = TREE_TYPE (mdecl);
- tree class_type = CLASS_TO_HANDLE_TYPE (current_class);
- tree self_type = (CLASSTYPE_SUPER (class_type) ?
- CLASSTYPE_SUPER (class_type) : class_type);
- tree method_signature =
- TYPE_LANG_SPECIFIC (method_type)->signature;
- tree method =
- lookup_java_constructor (CLASS_TO_HANDLE_TYPE (self_type),
- method_signature);
- tree block, compound;
-
- /* Fixe the begining/ending lines of the method so that with
- no_line_numbers set to 1 it doesn't generate debug info at
- line 1 for this artificial constructor. */
- DECL_SOURCE_LINE (mdecl) = 1;
- DECL_SOURCE_LINE_MERGE (mdecl, 1);
- source_start_java_method (mdecl);
- arg_list = BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (mdecl));
- enter_block ();
- func = build_known_method_ref (method, method_type, self_type,
- method_signature, arg_list);
-
- if (! flag_emit_class_files)
- func = build1 (NOP_EXPR, build_pointer_type (method_type), func);
- call = build (CALL_EXPR, TREE_TYPE (method_type), func,
- build_tree_list (NULL_TREE, arg_list), NULL_TREE);
- TREE_SIDE_EFFECTS (call) = 1;
- call = build_class_init (self_type, call);
- compound = java_method_add_stmt (mdecl, call);
- block = exit_block ();
- BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (mdecl)) = block;
- /* The function decl, its block and the compound statement
- within this block are all of void type. */
- TREE_TYPE (block) = TREE_TYPE (compound) =
- TREE_TYPE (DECL_FUNCTION_BODY (mdecl)) = void_type_node;
- exit_block ();
- no_ac_found = 0;
- }
+ /* Fix constructors before expanding them */
+ if (DECL_CONSTRUCTOR_P (mdecl))
+ fix_constructors (mdecl);
+ /* Expand functions that have a body */
if (DECL_FUNCTION_BODY (mdecl))
{
+ tree fbody = DECL_FUNCTION_BODY (mdecl);
+ tree block_body = BLOCK_EXPR_BODY (fbody);
expand_start_java_method (mdecl);
+ build_result_decl (mdecl);
current_this
= (!METHOD_STATIC (mdecl) ?
BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (mdecl)) : NULL_TREE);
- if (BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (mdecl)) && no_ac_found)
- java_complete_tree (BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (mdecl)));
+ /* Purge the `throws' list of unchecked exceptions */
+ purge_unchecked_exceptions (mdecl);
+
+ /* Install exceptions thrown with `throws' */
+ PUSH_EXCEPTIONS (DECL_FUNCTION_THROWS (mdecl));
+
+ if (block_body != NULL_TREE)
+ {
+ /* Prevent the use of `this' inside <clinit> */
+ if (DECL_NAME (current_function_decl) == clinit_identifier_node)
+ ctxp->explicit_constructor_p = 1;
+
+ block_body = java_complete_tree (block_body);
+ check_for_initialization (block_body);
+ ctxp->explicit_constructor_p = 0;
+ }
+ BLOCK_EXPR_BODY (fbody) = block_body;
+
+ if ((block_body == NULL_TREE || CAN_COMPLETE_NORMALLY (block_body))
+ && TREE_CODE (TREE_TYPE (TREE_TYPE (mdecl))) != VOID_TYPE)
+ missing_return_error (current_function_decl);
+
+ complete_start_java_method (mdecl);
+
/* Don't go any further if we've found error(s) during the
expansion */
if (!java_error_count)
source_end_java_method ();
+ else
+ {
+ pushdecl_force_head (DECL_ARGUMENTS (mdecl));
+ poplevel (1, 0, 1);
+ }
+
+ /* Pop the exceptions and sanity check */
+ POP_EXCEPTIONS();
+ if (currently_caught_type_list)
+ fatal ("Exception list non empty - java_complete_expand_method");
}
}
+/* Craft a body for default constructor. Patch existing constructor
+ bodies with call to super() and field initialization statements if
+ necessary. */
+
+static void
+fix_constructors (mdecl)
+ tree mdecl;
+{
+ tree body = DECL_FUNCTION_BODY (mdecl);
+
+ if (!body)
+ {
+ /* The constructor body must be crafted by hand. It's the
+ constructor we defined when we realize we didn't have the
+ CLASSNAME() constructor */
+
+ tree compound;
+
+ /* It is an error for the compiler to generate a default
+ constructor if the superclass doesn't have a constructor that
+ takes no argument */
+ if (verify_constructor_super ())
+ {
+ tree sclass_decl = TYPE_NAME (CLASSTYPE_SUPER (current_class));
+ char *n = IDENTIFIER_POINTER (DECL_NAME (sclass_decl));
+ parse_error_context (lookup_cl (TYPE_NAME (current_class)),
+ "No constructor matching `%s()' found in "
+ "class `%s'", n, n);
+ }
+
+ start_artificial_method_body (mdecl);
+
+ /* We don't generate a super constructor invocation if we're
+ compiling java.lang.Object. build_super_invocation takes care
+ of that. */
+ compound = java_method_add_stmt (mdecl, build_super_invocation ());
+
+ end_artificial_method_body (mdecl);
+ }
+ /* Search for an explicit constructor invocation */
+ else
+ {
+ int found = 0;
+ tree main_block = BLOCK_EXPR_BODY (body);
+ tree compound = NULL_TREE;
+
+ while (body)
+ switch (TREE_CODE (body))
+ {
+ case CALL_EXPR:
+ found = CALL_EXPLICIT_CONSTRUCTOR_P (body);
+ body = NULL_TREE;
+ break;
+ case COMPOUND_EXPR:
+ case EXPR_WITH_FILE_LOCATION:
+ body = TREE_OPERAND (body, 0);
+ break;
+ case BLOCK:
+ body = BLOCK_EXPR_BODY (body);
+ break;
+ default:
+ found = 0;
+ body = NULL_TREE;
+ }
+ /* The constructor is missing an invocation of super() */
+ if (!found)
+ compound = add_stmt_to_compound (compound, NULL_TREE,
+ build_super_invocation ());
+
+ /* Fix the constructor main block if we're adding extra stmts */
+ if (compound)
+ {
+ compound = add_stmt_to_compound (compound, NULL_TREE,
+ BLOCK_EXPR_BODY (main_block));
+ BLOCK_EXPR_BODY (main_block) = compound;
+ }
+ }
+}
+
+/* Browse constructors in the super class, searching for a constructor
+ that doesn't take any argument. Return 0 if one is found, 1
+ otherwise. */
+
+static int
+verify_constructor_super ()
+{
+ tree class = CLASSTYPE_SUPER (current_class);
+ if (!class)
+ return 0;
+
+ if (class)
+ {
+ tree mdecl;
+ for (mdecl = TYPE_METHODS (class); mdecl; mdecl = TREE_CHAIN (mdecl))
+ {
+ if (DECL_CONSTRUCTOR_P (mdecl)
+ && TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (mdecl))) == end_params_node)
+ return 0;
+ }
+ }
+ return 1;
+}
+
/* Expand finals. */
void
@@ -7235,6 +8492,31 @@ java_expand_finals ()
{
}
+/* Generate code for all context remembered for code generation. */
+
+void
+java_expand_classes ()
+{
+ int save_error_count = java_error_count;
+ java_parse_abort_on_error ();
+ if (!(ctxp = ctxp_for_generation))
+ return;
+ java_layout_classes ();
+ java_parse_abort_on_error ();
+
+ for (; ctxp_for_generation; ctxp_for_generation = ctxp_for_generation->next)
+ {
+ ctxp = ctxp_for_generation;
+ lang_init_source (2); /* Error msgs have method prototypes */
+ java_complete_expand_methods (); /* Complete and expand method bodies */
+ java_parse_abort_on_error ();
+ java_expand_finals (); /* Expand and check the finals */
+ java_parse_abort_on_error ();
+ java_check_final (); /* Check unitialized final */
+ java_parse_abort_on_error ();
+ }
+}
+
/* Wrap non WFL PRIMARY around a WFL and set EXPR_WFL_QUALIFICATION to
a tree list node containing RIGHT. Fore coming RIGHTs will be
chained to this hook. LOCATION contains the location of the
@@ -7250,9 +8532,9 @@ make_qualified_primary (primary, right, location)
/* We want to process THIS . xxx symbolicaly, to keep it consistent
with the way we're processing SUPER. A THIS from a primary as a
different form than a SUPER. Turn THIS into something symbolic */
- if (TREE_CODE (primary) == JAVA_THIS_EXPR)
+ if (TREE_CODE (primary) == THIS_EXPR)
{
- wfl = build_wfl_node (this_identifier_node, input_filename, 0, 0);
+ wfl = build_wfl_node (this_identifier_node);
EXPR_WFL_LINECOL (wfl) = EXPR_WFL_LINECOL (primary);
wfl = make_qualified_name (wfl, right, location);
PRIMARY_P (wfl) = 1;
@@ -7306,7 +8588,11 @@ make_qualified_name (left, right, location)
tree left, right;
int location;
{
- int qualified;
+#ifdef USE_COMPONENT_REF
+ tree node = build (COMPONENT_REF, NULL_TREE, left, right);
+ EXPR_WFL_LINECOL (node) = location;
+ return node;
+#else
tree left_id = EXPR_WFL_NODE (left);
tree right_id = EXPR_WFL_NODE (right);
tree wfl, merge;
@@ -7327,6 +8613,7 @@ make_qualified_name (left, right, location)
EXPR_WFL_NODE (left) = merge;
return left;
+#endif
}
/* Extract the last identifier component of the qualified in WFL. The
@@ -7352,8 +8639,9 @@ cut_identifier_in_qualified (wfl)
/* Resolve the expression name NAME. Return its decl. */
static tree
-resolve_expression_name (id)
+resolve_expression_name (id, orig)
tree id;
+ tree *orig;
{
tree name = EXPR_WFL_NODE (id);
tree decl;
@@ -7386,9 +8674,26 @@ resolve_expression_name (id)
(TYPE_NAME (current_class))));
return error_mark_node;
}
+ /* Instance variables can't appear as an argument of
+ an explicit constructor invocation */
+ if (!fs && ctxp->explicit_constructor_p)
+ {
+ parse_error_context
+ (id, "Can't reference `%s' before the superclass "
+ "constructor has been called", IDENTIFIER_POINTER (name));
+ return error_mark_node;
+ }
+
+ /* Otherwise build what it takes to access the field */
decl = build_field_ref ((fs ? NULL_TREE : current_this),
current_class, name);
- return (fs ? build_class_init (current_class, decl) : decl);
+ if (fs && !flag_emit_class_files)
+ decl = build_class_init (current_class, decl);
+ /* We may be asked to save the real field access node */
+ if (orig)
+ *orig = decl;
+ /* And we return what we got */
+ return decl;
}
/* Fall down to error report on undefined variable */
}
@@ -7396,6 +8701,8 @@ resolve_expression_name (id)
/* 6.5.5.2 Qualified Expression Names */
else
{
+ if (orig)
+ *orig = NULL_TREE;
qualify_ambiguous_name (id);
/* 15.10.1 Field Access Using a Primary and/or Expression Name */
/* 15.10.2: Accessing Superclass Members using super */
@@ -7437,23 +8744,36 @@ resolve_field_access (qual_wfl, field_decl, field_type)
}
/* We might have been trying to resolve field.method(). In which
case, the resolution is over and decl is the answer */
- else if (DECL_P (decl) && IDENTIFIER_LOCAL_VALUE (DECL_NAME (decl)) == decl)
+ else if (JDECL_P (decl) && IDENTIFIER_LOCAL_VALUE (DECL_NAME (decl)) == decl)
field_ref = decl;
- else if (DECL_P (decl))
- {
- is_static = DECL_P (decl) && FIELD_STATIC (decl);
- field_ref = build_field_ref ((is_static ? NULL_TREE : where_found),
- type_found, DECL_NAME (decl));
+ else if (JDECL_P (decl))
+ {
+ int static_final_found = 0;
+ if (!type_found)
+ type_found = DECL_CONTEXT (decl);
+ is_static = JDECL_P (decl) && FIELD_STATIC (decl);
+ if (FIELD_FINAL (decl)
+ && JPRIMITIVE_TYPE_P (TREE_TYPE (decl))
+ && DECL_LANG_SPECIFIC (decl)
+ && DECL_INITIAL (decl))
+ {
+ field_ref = DECL_INITIAL (decl);
+ static_final_found = 1;
+ }
+ else
+ field_ref = build_field_ref ((is_static ? NULL_TREE : where_found),
+ type_found, DECL_NAME (decl));
if (field_ref == error_mark_node)
return error_mark_node;
- if (is_static)
+ if (is_static && !static_final_found && !flag_emit_class_files)
{
field_ref = build_class_init (type_found, field_ref);
/* If the static field was identified by an expression that
needs to be generated, make the field access a compound
expression whose first part of the evaluation of the
field selector part. */
- if (where_found && TREE_CODE (where_found) != TYPE_DECL)
+ if (where_found && TREE_CODE (where_found) != TYPE_DECL
+ && TREE_CODE (where_found) != RECORD_TYPE)
{
tree type = QUAL_DECL_TYPE (field_ref);
field_ref = build (COMPOUND_EXPR, type, where_found, field_ref);
@@ -7466,10 +8786,35 @@ resolve_field_access (qual_wfl, field_decl, field_type)
if (field_decl)
*field_decl = decl;
if (field_type)
- *field_type = QUAL_DECL_TYPE (decl);
+ *field_type = (QUAL_DECL_TYPE (decl) ?
+ QUAL_DECL_TYPE (decl) : TREE_TYPE (decl));
return field_ref;
}
+/* If NODE is an access to f static field, strip out the class
+ initialization part and return the field decl, otherwise, return
+ NODE. */
+
+static tree
+strip_out_static_field_access_decl (node)
+ tree node;
+{
+ if (TREE_CODE (node) == COMPOUND_EXPR)
+ {
+ tree op1 = TREE_OPERAND (node, 1);
+ if (TREE_CODE (op1) == COMPOUND_EXPR)
+ {
+ tree call = TREE_OPERAND (op1, 0);
+ if (TREE_CODE (call) == CALL_EXPR
+ && TREE_CODE (TREE_OPERAND (call, 0)) == ADDR_EXPR
+ && TREE_OPERAND (TREE_OPERAND (call, 0), 0)
+ == soft_initclass_node)
+ return TREE_OPERAND (op1, 1);
+ }
+ }
+ return node;
+}
+
/* 6.5.5.2: Qualified Expression Names */
static int
@@ -7482,31 +8827,33 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
int previous_call_static = 0;
int is_static;
tree decl = NULL_TREE, type = NULL_TREE, q;
- *where_found = NULL_TREE;
+ *type_found = *where_found = NULL_TREE;
for (q = EXPR_WFL_QUALIFICATION (wfl); q; q = TREE_CHAIN (q))
{
tree qual_wfl = QUAL_WFL (q);
/* 15.10.1 Field Access Using a Primary */
-
switch (TREE_CODE (qual_wfl))
{
case CALL_EXPR:
- case JAVA_NEW_CLASS_EXPR:
+ case NEW_CLASS_EXPR:
/* If the access to the function call is a non static field,
build the code to access it. */
- if (DECL_P (decl) && !FIELD_STATIC (decl))
+ if (JDECL_P (decl) && !FIELD_STATIC (decl))
{
- decl = maybe_access_field (decl, *where_found, type);
+ decl = maybe_access_field (decl, *where_found,
+ DECL_CONTEXT (decl));
if (decl == error_mark_node)
return 1;
}
/* And code for the function call */
if (complete_function_arguments (qual_wfl))
return 1;
+ if (from_super && TREE_CODE (qual_wfl) == CALL_EXPR)
+ CALL_USING_SUPER (qual_wfl) = 1;
*where_found =
- patch_method_invocation_stmt (qual_wfl, decl, type, &is_static);
+ patch_method_invocation (qual_wfl, decl, type, &is_static, NULL);
if (*where_found == error_mark_node)
return 1;
*type_found = type = QUAL_DECL_TYPE (*where_found);
@@ -7527,6 +8874,14 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
}
continue;
+ case NEW_ARRAY_EXPR:
+ *where_found = decl = java_complete_tree (qual_wfl);
+ if (decl == error_mark_node)
+ return 1;
+ *type_found = type = QUAL_DECL_TYPE (decl);
+ CLASS_LOADED_P (type) = 1;
+ continue;
+
case CONVERT_EXPR:
*where_found = decl = java_complete_tree (qual_wfl);
if (decl == error_mark_node)
@@ -7535,10 +8890,18 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
from_cast = 1;
continue;
+ case CONDITIONAL_EXPR:
+ case STRING_CST:
+ *where_found = decl = java_complete_tree (qual_wfl);
+ if (decl == error_mark_node)
+ return 1;
+ *type_found = type = QUAL_DECL_TYPE (decl);
+ continue;
+
case ARRAY_REF:
/* If the access to the function call is a non static field,
build the code to access it. */
- if (DECL_P (decl) && !FIELD_STATIC (decl))
+ if (JDECL_P (decl) && !FIELD_STATIC (decl))
{
decl = maybe_access_field (decl, *where_found, type);
if (decl == error_mark_node)
@@ -7550,6 +8913,10 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
return 1;
type = QUAL_DECL_TYPE (decl);
continue;
+
+ default:
+ /* Fix for -Wall Just go to the next statement. Don't
+ continue */
}
/* If we fall here, we weren't processing a (static) function call. */
@@ -7566,7 +8933,7 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
}
/* We have to generate code for intermediate acess */
*where_found = decl = current_this;
- type = QUAL_DECL_TYPE (decl);
+ *type_found = type = QUAL_DECL_TYPE (decl);
continue;
}
@@ -7587,6 +8954,8 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
CLASSTYPE_SUPER (current_class),
build_this (EXPR_WFL_LINECOL (qual_wfl)));
*where_found = decl = java_complete_tree (node);
+ if (decl == error_mark_node)
+ return 1;
*type_found = type = QUAL_DECL_TYPE (decl);
from_super = from_type = 1;
continue;
@@ -7596,17 +8965,33 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
assume a variable/class name was meant. */
if (RESOLVE_PACKAGE_NAME_P (qual_wfl))
{
- if (from_super || from_cast)
- parse_error_context
- ((from_cast ? qual_wfl : wfl),
- "No variable `%s' defined in class `%s'",
- IDENTIFIER_POINTER (EXPR_WFL_NODE (qual_wfl)),
- lang_printable_name (type));
+ tree name = resolve_package (wfl, &q);
+ if (name)
+ {
+ *where_found = decl = resolve_no_layout (name, qual_wfl);
+ /* We wan't to be absolutely that the class is laid
+ out. We're going to search something inside it. */
+ *type_found = type = TREE_TYPE (decl);
+ layout_class (type);
+ from_type = 1;
+ /* Should be a list, really. FIXME */
+ RESOLVE_EXPRESSION_NAME_P (QUAL_WFL (TREE_CHAIN (q))) = 1;
+ RESOLVE_PACKAGE_NAME_P (QUAL_WFL (TREE_CHAIN (q))) = 0;
+ }
else
- parse_error_context
- (qual_wfl, "Undefined variable or class name: `%s'",
- IDENTIFIER_POINTER (EXPR_WFL_NODE (qual_wfl)));
- return 1;
+ {
+ if (from_super || from_cast)
+ parse_error_context
+ ((from_cast ? qual_wfl : wfl),
+ "No variable `%s' defined in class `%s'",
+ IDENTIFIER_POINTER (EXPR_WFL_NODE (qual_wfl)),
+ lang_printable_name (type, 0));
+ else
+ parse_error_context
+ (qual_wfl, "Undefined variable or class name: `%s'",
+ IDENTIFIER_POINTER (EXPR_WFL_NODE (qual_wfl)));
+ return 1;
+ }
}
/* We have a type name. It's been already resolved when the
@@ -7621,11 +9006,12 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
parse_error_context
(qual_wfl, "Can't access %s field `%s.%s' from `%s'",
java_accstring_lookup (get_access_flags_from_decl (decl)),
- IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))),
+ GET_TYPE_NAME (type),
IDENTIFIER_POINTER (DECL_NAME (decl)),
IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (current_class))));
return 1;
}
+ check_deprecation (qual_wfl, decl);
type = TREE_TYPE (decl);
from_type = 1;
@@ -7640,36 +9026,69 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
come. Don't do that when processing something after SUPER
(we need more thing to be put in place below */
if (!from_super && QUAL_RESOLUTION (q))
- decl = QUAL_RESOLUTION (q);
+ {
+ decl = QUAL_RESOLUTION (q);
+ if (!type)
+ {
+ if (!FIELD_STATIC (decl))
+ *where_found = current_this;
+ else
+ {
+ *where_found = TREE_TYPE (decl);
+ if (TREE_CODE (*where_found) == POINTER_TYPE)
+ *where_found = TREE_TYPE (*where_found);
+ }
+ }
+ }
/* We have to search for a field, knowing the type of its
container. The flag FROM_TYPE indicates that we resolved
the last member of the expression as a type name, which
- means that for the resolution of this field, will check
- on other errors than if the it was resolved as a member
- of an other field. */
+ means that for the resolution of this field, we'll look
+ for other errors than if it was resolved as a member of
+ an other field. */
else
{
int is_static;
+ tree field_decl_type; /* For layout */
+
if (!from_type && !JREFERENCE_TYPE_P (type))
{
parse_error_context
(qual_wfl, "Attempt to reference field `%s' in `%s %s'",
IDENTIFIER_POINTER (EXPR_WFL_NODE (qual_wfl)),
- lang_printable_name (type),
+ lang_printable_name (type, 0),
IDENTIFIER_POINTER (DECL_NAME (field_decl)));
return 1;
}
- if (!(field_decl =
- lookup_field_wrapper (type, EXPR_WFL_NODE (qual_wfl))))
+ field_decl = lookup_field_wrapper (type,
+ EXPR_WFL_NODE (qual_wfl));
+ if (field_decl == NULL_TREE)
{
parse_error_context
- (qual_wfl, "No variable `%s' defined in class `%s'",
+ (qual_wfl, "No variable `%s' defined in type `%s'",
IDENTIFIER_POINTER (EXPR_WFL_NODE (qual_wfl)),
- IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))));
+ GET_TYPE_NAME (type));
return 1;
}
+ if (field_decl == error_mark_node)
+ return 1;
+
+ /* Layout the type of field_decl, since we may need
+ it. Don't do primitive types or loaded classes. The
+ situation of non primitive arrays may not handled
+ properly here. FIXME */
+ if (TREE_CODE (TREE_TYPE (field_decl)) == POINTER_TYPE)
+ field_decl_type = TREE_TYPE (TREE_TYPE (field_decl));
+ else
+ field_decl_type = TREE_TYPE (field_decl);
+ if (!JPRIMITIVE_TYPE_P (field_decl_type)
+ && !CLASS_LOADED_P (field_decl_type)
+ && !TYPE_ARRAY_P (field_decl_type))
+ resolve_and_layout (field_decl_type, NULL_TREE);
+ if (TYPE_ARRAY_P (field_decl_type))
+ CLASS_LOADED_P (field_decl_type) = 1;
/* Check on accessibility here */
if (not_accessible_p (type, field_decl, from_super))
@@ -7679,12 +9098,13 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
"Can't access %s field `%s.%s' from `%s'",
java_accstring_lookup
(get_access_flags_from_decl (field_decl)),
- IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))),
+ GET_TYPE_NAME (type),
IDENTIFIER_POINTER (DECL_NAME (field_decl)),
IDENTIFIER_POINTER
(DECL_NAME (TYPE_NAME (current_class))));
return 1;
}
+ check_deprecation (qual_wfl, field_decl);
/* There are things to check when fields are accessed
from type. There are no restrictions on a static
@@ -7703,11 +9123,12 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
}
from_cast = from_super = 0;
- /* If we need to generate something to get a proper handle
- on what this field is accessed from, do it now. */
+ /* If we need to generate something to get a proper
+ handle on what this field is accessed from, do it
+ now. */
if (!is_static)
{
- decl = maybe_access_field (decl, *where_found, type);
+ decl = maybe_access_field (decl, *where_found, *type_found);
if (decl == error_mark_node)
return 1;
}
@@ -7721,7 +9142,6 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
search from */
decl = field_decl;
}
-
from_type = 0;
type = QUAL_DECL_TYPE (decl);
}
@@ -7752,32 +9172,19 @@ int not_accessible_p (reference, member, from_super)
if (class_in_current_package (DECL_CONTEXT (member)))
return 0;
- if (TREE_CODE (member) == FUNCTION_DECL && DECL_CONSTRUCTOR_P (member))
- {
- /* Access from SUPER is granted */
- if (from_super)
- return 0;
- /* Otherwise, access isn't granted */
- return 1;
- }
- else
- {
- /* If accessed with the form `super.member', then access is
- granted */
- if (from_super)
- return 0;
+ /* If accessed with the form `super.member', then access is granted */
+ if (from_super)
+ return 0;
- /* Otherwise, access is granted if occuring from the class where
- member is declared or a subclass of it */
- if (inherits_from_p (reference, current_class))
- return 0;
- }
+ /* Otherwise, access is granted if occuring from the class where
+ member is declared or a subclass of it */
+ if (inherits_from_p (reference, current_class))
+ return 0;
return 1;
}
/* Check access on private members. Access is granted only if it
- occurs from within the class in witch it is declared*/
-
+ occurs from within the class in witch it is declared */
if (access_flag & ACC_PRIVATE)
return (current_class == DECL_CONTEXT (member) ? 0 : 1);
@@ -7791,6 +9198,40 @@ int not_accessible_p (reference, member, from_super)
return 0;
}
+/* Test deprecated decl access. */
+static void
+check_deprecation (wfl, decl)
+ tree wfl, decl;
+{
+ char *file = DECL_SOURCE_FILE (decl);
+ /* Complain if the field is deprecated and the file it was defined
+ in isn't compiled at the same time the file which contains its
+ use is */
+ if (DECL_DEPRECATED (decl)
+ && !IS_A_COMMAND_LINE_FILENAME_P (get_identifier (file)))
+ {
+ char the [20];
+ switch (TREE_CODE (decl))
+ {
+ case FUNCTION_DECL:
+ strcpy (the, "method");
+ break;
+ case FIELD_DECL:
+ strcpy (the, "field");
+ break;
+ case TYPE_DECL:
+ strcpy (the, "class");
+ break;
+ default:
+ fatal ("unexpected DECL code - check_deprecation");
+ }
+ parse_warning_context
+ (wfl, "The %s `%s' in class `%s' has been deprecated",
+ the, lang_printable_name (decl, 0),
+ IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (DECL_CONTEXT (decl)))));
+ }
+}
+
/* Returns 1 if class was declared in the current package, 0 otherwise */
static int
@@ -7810,7 +9251,7 @@ class_in_current_package (class)
qualified, class isn't in the current package. If there is a
current package and the name of the CLASS is not qualified, class
isn't in the current package */
- if (!ctxp->package && qualified_flag || ctxp->package && !qualified_flag)
+ if ((!ctxp->package && qualified_flag) || (ctxp->package && !qualified_flag))
return 0;
/* If there is not package and the name of CLASS isn't qualified,
@@ -7835,28 +9276,31 @@ static tree
maybe_access_field (decl, where, type)
tree decl, where, type;
{
- if (DECL_P (decl) && decl != current_this
- && (!(TREE_CODE (decl) != PARM_DECL
- && FIELD_STATIC (decl)))
- && !IDENTIFIER_LOCAL_VALUE (DECL_NAME (decl)))
+ if (TREE_CODE (decl) == FIELD_DECL && decl != current_this
+ && !FIELD_STATIC (decl))
decl = build_field_ref (where ? where : current_this,
- type, DECL_NAME (decl));
+ (type ? type : DECL_CONTEXT (decl)),
+ DECL_NAME (decl));
return decl;
}
-/* Build a method invocation statement, by patching PATCH. If non NULL
+/* Build a method invocation, by patching PATCH. If non NULL
and according to the situation, PRIMARY and WHERE may be
used. IS_STATIC is set to 1 if the invoked function is static. */
static tree
-patch_method_invocation_stmt (patch, primary, where, is_static)
+patch_method_invocation (patch, primary, where, is_static, ret_decl)
tree patch, primary, where;
int *is_static;
+ tree *ret_decl;
{
tree wfl = TREE_OPERAND (patch, 0);
tree args = TREE_OPERAND (patch, 1);
tree name = EXPR_WFL_NODE (wfl);
- tree list, class_type;
+ tree list;
+ int is_static_flag = 0;
+ int is_super_init = 0;
+ tree this_arg = NULL_TREE;
/* Should be overriden if everything goes well. Otherwise, if
something fails, it should keep this value. It stop the
@@ -7893,7 +9337,7 @@ patch_method_invocation_stmt (patch, primary, where, is_static)
parse_error_context (wfl, "Can't search method `%s' in package "
"`%s'",IDENTIFIER_POINTER (identifier),
IDENTIFIER_POINTER (remainder));
- return error_mark_node;
+ PATCH_METHOD_RETURN_ERROR ();
}
/* We're resolving a call from a type */
else if (RESOLVE_TYPE_NAME_P (wfl))
@@ -7909,7 +9353,7 @@ patch_method_invocation_stmt (patch, primary, where, is_static)
(identifier_wfl, "Can't make static reference to method "
"`%s' in interface `%s'", IDENTIFIER_POINTER (identifier),
IDENTIFIER_POINTER (name));
- return error_mark_node;
+ PATCH_METHOD_RETURN_ERROR ();
}
/* Look the method up in the type selector. The method ought
to be static. */
@@ -7917,15 +9361,16 @@ patch_method_invocation_stmt (patch, primary, where, is_static)
list = lookup_method_invoke (0, wfl, type, identifier, args);
if (list && !METHOD_STATIC (list))
{
- char *fct_name = strdup ((char *)lang_printable_name (list));
+ char *fct_name = strdup (lang_printable_name (list, 0));
parse_error_context
(identifier_wfl,
"Can't make static reference to method `%s %s' in class `%s'",
- lang_printable_name (TREE_TYPE (TREE_TYPE (list))), fct_name,
- IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))));
+ lang_printable_name (TREE_TYPE (TREE_TYPE (list)), 0),
+ fct_name, IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))));
free (fct_name);
- return error_mark_node;
+ PATCH_METHOD_RETURN_ERROR ();
}
+ args = nreverse (args);
}
/* We're resolving an expression name */
else
@@ -7935,25 +9380,29 @@ patch_method_invocation_stmt (patch, primary, where, is_static)
/* 1- Find the field to which the call applies */
field = resolve_field_access (wfl, NULL, &type);
if (field == error_mark_node)
- return error_mark_node;
+ PATCH_METHOD_RETURN_ERROR ();
+ /* field is used in lieu of a primary. It alows us not to
+ report errors on erroneous use of `this' in
+ constructors. */
+ primary = field;
/* 2- Do the layout of the class where the last field
was found, so we can search it. */
- class_decl =
- resolve_and_layout (DECL_NAME (TYPE_NAME (type)), NULL_TREE);
-
+ class_decl = resolve_and_layout (type, NULL_TREE);
+ if (class_decl != NULL_TREE)
+ type = TREE_TYPE (class_decl);
+
/* 3- Retrieve a filtered list of method matches, Refine
if necessary. In any cases, point out errors. */
list = lookup_method_invoke (0, identifier_wfl, type,
identifier, args);
/* 4- Add the field as an argument */
- args = tree_cons (NULL_TREE, field, args);
+ args = nreverse (args);
+ this_arg = field;
}
- /* CLASS_TYPE is used during the call to not_accessible_p and
- IDENTIFIER_WFL will be used to report any problem further */
- class_type = TREE_TYPE (class_decl);
+ /* IDENTIFIER_WFL will be used to report any problem further */
wfl = identifier_wfl;
}
/* Resolution of simple names, names generated after a primary: or
@@ -7966,24 +9415,54 @@ patch_method_invocation_stmt (patch, primary, where, is_static)
/* We search constructor in their target class */
if (CALL_CONSTRUCTOR_P (patch))
{
- class_to_search = resolve_no_layout (EXPR_WFL_NODE (wfl), NULL_TREE);
- if (!class_to_search)
+ if (TREE_CODE (patch) == NEW_CLASS_EXPR)
+ class_to_search = EXPR_WFL_NODE (wfl);
+ else if (EXPR_WFL_NODE (TREE_OPERAND (patch, 0)) ==
+ this_identifier_node)
+ class_to_search = NULL_TREE;
+ else if (EXPR_WFL_NODE (TREE_OPERAND (patch, 0)) ==
+ super_identifier_node)
{
- parse_error_context
- (wfl, "Class `%s' not found in type declaration",
- IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl)));
- return error_mark_node;
+ is_super_init = 1;
+ if (CLASSTYPE_SUPER (current_class))
+ class_to_search =
+ DECL_NAME (TYPE_NAME (CLASSTYPE_SUPER (current_class)));
+ else
+ {
+ parse_error_context (wfl, "Can't invoke super constructor "
+ "on java.lang.Object");
+ PATCH_METHOD_RETURN_ERROR ();
+ }
}
-
- /* Can't instantiate an abstract class */
- if (CLASS_ABSTRACT (class_to_search))
+
+ /* Class to search is NULL if we're searching the current one */
+ if (class_to_search)
{
- parse_error_context
- (wfl, "Class `%s' is an abstract class. It can't be "
- "instantiated", IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl)));
- return error_mark_node;
+ class_to_search = resolve_and_layout (class_to_search,
+ NULL_TREE);
+ if (!class_to_search)
+ {
+ parse_error_context
+ (wfl, "Class `%s' not found in type declaration",
+ IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl)));
+ PATCH_METHOD_RETURN_ERROR ();
+ }
+
+ /* Can't instantiate an abstract class, but we can
+ invoke it's constructor. It's use within the `new'
+ context is denied here. */
+ if (CLASS_ABSTRACT (class_to_search)
+ && TREE_CODE (patch) == NEW_CLASS_EXPR)
+ {
+ parse_error_context
+ (wfl, "Class `%s' is an abstract class. It can't be "
+ "instantiated", IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl)));
+ PATCH_METHOD_RETURN_ERROR ();
+ }
+ class_to_search = TREE_TYPE (class_to_search);
}
- class_to_search = TREE_TYPE (class_to_search);
+ else
+ class_to_search = current_class;
lc = 1;
}
/* This is a regular search in the local class, unless an
@@ -7997,49 +9476,90 @@ patch_method_invocation_stmt (patch, primary, where, is_static)
/* NAME is a simple identifier or comes from a primary. Search
in the class whose declaration contain the method being
invoked. */
+ resolve_and_layout (class_to_search, NULL_TREE);
list = lookup_method_invoke (lc, wfl, class_to_search, name, args);
/* Don't continue if no method were found, as the next statement
can't be executed then. */
- if (!list) return error_mark_node;
+ if (!list)
+ PATCH_METHOD_RETURN_ERROR ();
/* Check for static reference if non static methods */
if (check_for_static_method_reference (wfl, patch, list,
class_to_search, primary))
- return error_mark_node;
-
- /* Non static/constructor methods are called with the current
- object extra argument. If method is resolved as a primary,
- use the primary otherwise use the current THIS. */
- if (!CALL_CONSTRUCTOR_P (patch) && !METHOD_STATIC (list))
- args = tree_cons (NULL_TREE, primary ? primary : current_this, args);
+ PATCH_METHOD_RETURN_ERROR ();
- class_type = class_to_search;
+ /* Non static methods are called with the current object extra
+ argument. If patch a `new TYPE()', the argument is the value
+ returned by the object allocator. If method is resolved as a
+ primary, use the primary otherwise use the current THIS. */
+ args = nreverse (args);
+ if (TREE_CODE (patch) != NEW_CLASS_EXPR)
+ this_arg = primary ? primary : current_this;
}
-
+
/* Merge point of all resolution schemes. If we have nothing, this
is an error, already signaled */
- if (!list) return error_mark_node;
-
+ if (!list)
+ PATCH_METHOD_RETURN_ERROR ();
+
/* Check accessibility, position the is_static flag, build and
return the call */
- if (not_accessible_p (class_type, list, 0))
+ if (not_accessible_p (DECL_CONTEXT (current_function_decl), list, 0))
{
- char *fct_name = strdup ((char *)lang_printable_name (list));
+ char *fct_name = strdup (lang_printable_name (list, 0));
parse_error_context
(wfl, "Can't access %s method `%s %s.%s' from `%s'",
java_accstring_lookup (get_access_flags_from_decl (list)),
- lang_printable_name (TREE_TYPE (TREE_TYPE (list))),
- IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (class_type))), fct_name,
- IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (current_class))));
+ lang_printable_name (TREE_TYPE (TREE_TYPE (list)), 0),
+ IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (DECL_CONTEXT (list)))),
+ fct_name, IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (current_class))));
free (fct_name);
- return error_mark_node;
+ PATCH_METHOD_RETURN_ERROR ();
+ }
+ check_deprecation (wfl, list);
+
+ is_static_flag = METHOD_STATIC (list);
+ if (! METHOD_STATIC (list) && this_arg != NULL_TREE)
+ args = tree_cons (NULL_TREE, this_arg, args);
+
+ /* In the context of an explicit constructor invocation, we can't
+ invoke any method relying on `this'. Exceptions are: we're
+ invoking a static function, primary exists and is not the current
+ this, we're creating a new object. */
+ if (ctxp->explicit_constructor_p
+ && !is_static_flag
+ && (!primary || primary == current_this)
+ && (TREE_CODE (patch) != NEW_CLASS_EXPR))
+ {
+ parse_error_context
+ (wfl, "Can't reference `this' before the superclass constructor has "
+ "been called");
+ PATCH_METHOD_RETURN_ERROR ();
}
-
- if (is_static)
- *is_static = METHOD_STATIC (list);
java_parser_context_restore_global ();
- return patch_invoke (patch, list, args, wfl);
+ if (is_static)
+ *is_static = is_static_flag;
+ /* Sometimes, we want the decl of the selected method. Such as for
+ EH checking */
+ if (ret_decl)
+ *ret_decl = list;
+ patch = patch_invoke (patch, list, args);
+ if (is_super_init && CLASS_HAS_FINIT_P (current_class))
+ {
+ /* Generate the code used to initialize fields declared with an
+ initialization statement. For now, it returns a call the the
+ artificial function $finit$, if required. */
+
+ tree finit_call =
+ build_method_invocation (build_expr_wfl (finit_identifier_node,
+ input_filename, 0, 0),
+ NULL_TREE);
+ patch = build (COMPOUND_EXPR, void_type_node, patch,
+ java_complete_tree (finit_call));
+ CAN_COMPLETE_NORMALLY (patch) = 1;
+ }
+ return patch;
}
/* Check that we're not trying to do a static reference to a method in
@@ -8052,10 +9572,10 @@ check_for_static_method_reference (wfl, node, method, where, primary)
if (METHOD_STATIC (current_function_decl)
&& !METHOD_STATIC (method) && !primary && !CALL_CONSTRUCTOR_P (node))
{
- char *fct_name = strdup ((char *)lang_printable_name (method));
+ char *fct_name = strdup (lang_printable_name (method, 0));
parse_error_context
(wfl, "Can't make static reference to method `%s %s' in class `%s'",
- lang_printable_name (TREE_TYPE (TREE_TYPE (method))), fct_name,
+ lang_printable_name (TREE_TYPE (TREE_TYPE (method)), 0), fct_name,
IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (where))));
free (fct_name);
return 1;
@@ -8067,48 +9587,76 @@ check_for_static_method_reference (wfl, node, method, where, primary)
mode. */
static tree
-patch_invoke (patch, method, args, cl)
+patch_invoke (patch, method, args)
tree patch, method, args;
- tree cl;
{
tree dtable, func;
- tree signature = build_java_signature (TREE_TYPE (method));
- tree original_call;
-
- switch (invocation_mode (method, 0))
+ tree original_call, t, ta;
+
+ /* Last step for args: convert build-in types. If we're dealing with
+ a new TYPE() type call, the first argument to the constructor
+ isn't found in the incomming argument list, but delivered by
+ `new' */
+ t = TYPE_ARG_TYPES (TREE_TYPE (method));
+ if (TREE_CODE (patch) == NEW_CLASS_EXPR)
+ t = TREE_CHAIN (t);
+ for (ta = args; t != end_params_node && ta;
+ t = TREE_CHAIN (t), ta = TREE_CHAIN (ta))
+ if (JPRIMITIVE_TYPE_P (TREE_TYPE (TREE_VALUE (ta))) &&
+ TREE_TYPE (TREE_VALUE (ta)) != TREE_VALUE (t))
+ TREE_VALUE (ta) = convert (TREE_VALUE (t), TREE_VALUE (ta));
+
+ if (flag_emit_class_files)
+ func = method;
+ else
{
- case INVOKE_VIRTUAL:
- dtable = invoke_build_dtable (0, args);
- func = build_invokevirtual (dtable, method);
- break;
- case INVOKE_STATIC:
- func = build_known_method_ref (method, TREE_TYPE (method),
- DECL_CONTEXT (method),
- signature, args);
- args = nreverse (args);
- break;
+ tree signature = build_java_signature (TREE_TYPE (method));
+ switch (invocation_mode (method, CALL_USING_SUPER (patch)))
+ {
+ case INVOKE_VIRTUAL:
+ dtable = invoke_build_dtable (0, args);
+ func = build_invokevirtual (dtable, method);
+ break;
- default:
- fatal ("Unknown invocation mode - build_invoke");
- return NULL_TREE;
- }
+ case INVOKE_SUPER:
+ case INVOKE_STATIC:
+ func = build_known_method_ref (method, TREE_TYPE (method),
+ DECL_CONTEXT (method),
+ signature, args);
+ break;
+
+ case INVOKE_INTERFACE:
+ dtable = invoke_build_dtable (1, args);
+ func = build_invokeinterface (dtable, DECL_NAME (method), signature);
+ break;
+ default:
+ fatal ("internal error - unknown invocation_mode result");
+ }
+
+ /* Ensure self_type is initialized, (invokestatic). FIXME */
+ func = build1 (NOP_EXPR, build_pointer_type (TREE_TYPE (method)), func);
+ }
- /* Ensure self_type is initialized, (invokestatic). FIXME */
- func = build1 (NOP_EXPR, build_pointer_type (TREE_TYPE (method)), func);
TREE_TYPE (patch) = TREE_TYPE (TREE_TYPE (method));
TREE_OPERAND (patch, 0) = func;
TREE_OPERAND (patch, 1) = args;
original_call = patch;
- /* We're calling a constructor. New is called an its returned value
- is an argument to the constructor. We build a COMPOUND_EXPR and
- use saved expression so that the overall NEW expression value is
- a pointer to a newly created and initialized class. */
- if (CALL_CONSTRUCTOR_P (original_call))
+ /* We're processing a `new TYPE ()' form. New is called an its
+ returned value is the first argument to the constructor. We build
+ a COMPOUND_EXPR and use saved expression so that the overall NEW
+ expression value is a pointer to a newly created and initialized
+ class. */
+ if (TREE_CODE (original_call) == NEW_CLASS_EXPR)
{
tree class = DECL_CONTEXT (method);
tree c1, saved_new, size, new;
+ if (flag_emit_class_files)
+ {
+ TREE_TYPE (patch) = build_pointer_type (class);
+ return patch;
+ }
if (!TYPE_SIZE (class))
safe_layout_class (class);
size = size_in_bytes (class);
@@ -8135,25 +9683,26 @@ invocation_mode (method, super)
{
int access = get_access_flags_from_decl (method);
- if (access & ACC_STATIC)
+ if (super)
+ return INVOKE_SUPER;
+
+ if (access & ACC_STATIC || access & ACC_FINAL || access & ACC_PRIVATE)
return INVOKE_STATIC;
if (CLASS_FINAL (TYPE_NAME (DECL_CONTEXT (method))))
return INVOKE_STATIC;
- if (super)
- return INVOKE_SUPER;
-
if (CLASS_INTERFACE (TYPE_NAME (DECL_CONTEXT (method))))
return INVOKE_INTERFACE;
if (DECL_CONSTRUCTOR_P (method))
return INVOKE_STATIC;
-
+
return INVOKE_VIRTUAL;
}
-/* Retrieve a refined list of matching methods. */
+/* Retrieve a refined list of matching methods. It covers the step
+ 15.11.2 (Compile-Time Step 2) */
static tree
lookup_method_invoke (lc, cl, class, name, arg_list)
@@ -8161,159 +9710,271 @@ lookup_method_invoke (lc, cl, class, name, arg_list)
tree cl;
tree class, name, arg_list;
{
- tree method = make_node (FUNCTION_TYPE);
- tree arg_type_list = NULL_TREE;
- tree signature, list, node, scratch;
+ tree atl = end_params_node; /* Arg Type List */
+ tree method, signature, list, node;
+ char *candidates; /* Used for error report */
+ /* Fix the arguments */
for (node = arg_list; node; node = TREE_CHAIN (node))
{
- tree current_arg;
- current_arg =
- build_tree_list (NULL_TREE,
- promote_type (TREE_TYPE (TREE_VALUE (node))));
- arg_type_list = chainon (current_arg, arg_type_list);
- }
- TYPE_ARG_TYPES (method) = arg_type_list;
+ tree current_arg = TREE_TYPE (TREE_VALUE (node));
+ /* Non primitive type may have to be resolved */
+ if (!JPRIMITIVE_TYPE_P (current_arg))
+ resolve_and_layout (current_arg, NULL_TREE);
+ /* And promoted */
+ if (TREE_CODE (current_arg) == RECORD_TYPE)
+ current_arg = promote_type (current_arg);
+ atl = tree_cons (NULL_TREE, current_arg, atl);
+ }
+
+ /* Find all candidates and then refine the list, searching for the
+ most specific method. */
+ list = find_applicable_accessible_methods_list (lc, class, name, atl);
+ list = find_most_specific_methods_list (list);
+ if (list && !TREE_CHAIN (list))
+ return TREE_VALUE (list);
- if (!lc)
+ /* Issue an error. List candidates if any. Candidates are listed
+ only if accessible (non accessible methods may end-up here for
+ the sake of a better error report). */
+ candidates = NULL;
+ if (list)
{
- signature = build_java_argument_signature (method);
- list = match_java_method (class, name, signature);
- list = refine_accessible_methods_list (lc, list);
+ tree current;
+ obstack_grow (&temporary_obstack, ". Candidates are:\n", 18);
+ for (current = list; current; current = TREE_CHAIN (current))
+ {
+ tree cm = TREE_VALUE (current);
+ char string [4096];
+ if (!cm || not_accessible_p (class, cm, 0))
+ continue;
+ sprintf
+ (string, " `%s' in `%s'%s",
+ get_printable_method_name (cm),
+ IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (DECL_CONTEXT (cm)))),
+ (TREE_CHAIN (current) ? "\n" : ""));
+ obstack_grow (&temporary_obstack, string, strlen (string));
+ }
+ obstack_1grow (&temporary_obstack, '\0');
+ candidates = obstack_finish (&temporary_obstack);
+ }
+ /* Issue the error message */
+ method = make_node (FUNCTION_TYPE);
+ TYPE_ARG_TYPES (method) = atl;
+ signature = build_java_argument_signature (method);
+ parse_error_context (cl, "Can't find %s `%s(%s)' in class `%s'%s",
+ (lc ? "constructor" : "method"),
+ (lc ?
+ IDENTIFIER_POINTER(DECL_NAME (TYPE_NAME (class))) :
+ IDENTIFIER_POINTER (name)),
+ IDENTIFIER_POINTER (signature),
+ IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (class))),
+ (candidates ? candidates : ""));
+ return NULL_TREE;
+}
+
+/* 15.11.2.1: Find Methods that are Applicable and Accessible. LC is 1
+ when we're looking for a constructor. */
+
+static tree
+find_applicable_accessible_methods_list (lc, class, name, arglist)
+ int lc;
+ tree class, name, arglist;
+{
+ tree list = NULL_TREE, all_list = NULL_TREE;
+
+ /* Search interfaces */
+ if (CLASS_INTERFACE (TYPE_NAME (class)))
+ {
+ static tree searched_interfaces = NULL_TREE;
+ static int search_not_done = 0;
+ int i, n;
+ tree basetype_vec = TYPE_BINFO_BASETYPES (class);
+
+ /* Have we searched this interface already? */
+ if (searched_interfaces)
+ {
+ tree current;
+ for (current = searched_interfaces;
+ current; current = TREE_CHAIN (current))
+ if (TREE_VALUE (current) == class)
+ return NULL;
+ }
+ searched_interfaces = tree_cons (NULL_TREE, class, searched_interfaces);
+
+ search_applicable_methods_list
+ (lc, TYPE_METHODS (class), name, arglist, &list, &all_list);
+
+ n = TREE_VEC_LENGTH (basetype_vec);
+ for (i = 0; i < n; i++)
+ {
+ tree t = BINFO_TYPE (TREE_VEC_ELT (basetype_vec, i));
+ tree rlist;
+
+ /* Skip java.lang.Object (we'll search it once later.) */
+ if (t == object_type_node)
+ continue;
+
+ search_not_done++;
+ rlist = find_applicable_accessible_methods_list (lc, t, name,
+ arglist);
+ all_list = chainon (rlist, (list ? list : all_list));
+ search_not_done--;
+ }
+
+ /* We're done. Reset the searched interfaces list and finally search
+ java.lang.Object */
+ if (!search_not_done)
+ {
+ searched_interfaces = NULL_TREE;
+ search_applicable_methods_list (lc, TYPE_METHODS (object_type_node),
+ name, arglist, &list, &all_list);
+ }
}
+ /* Search classes */
else
- {
- TREE_TYPE (method) = void_type_node;
- signature = build_java_signature (method);
- list = lookup_java_constructor (class, signature);
- }
+ while (class != NULL_TREE)
+ {
+ search_applicable_methods_list
+ (lc, TYPE_METHODS (class), name, arglist, &list, &all_list);
+ class = (lc ? NULL_TREE : CLASSTYPE_SUPER (class));
+ }
- if (!list)
+ /* Either return the list obtained or all selected (but
+ inaccessible) methods for better error report. */
+ return (!list ? all_list : list);
+}
+
+/* Effectively search for the approriate method in method */
+
+static void
+search_applicable_methods_list(lc, method, name, arglist, list, all_list)
+ int lc;
+ tree method, name, arglist;
+ tree *list, *all_list;
+{
+ for (; method; method = TREE_CHAIN (method))
{
- parse_error_context (cl, "Can't find method `%s(%s)' in class `%s'",
- IDENTIFIER_POINTER (name),
- IDENTIFIER_POINTER (signature),
- IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (class))));
- return NULL_TREE;
+ /* When dealing with constructor, stop here, otherwise search
+ other classes */
+ if (lc && !DECL_CONSTRUCTOR_P (method))
+ continue;
+ else if (!lc && (DECL_CONSTRUCTOR_P (method)
+ || (GET_METHOD_NAME (method) != name)))
+ continue;
+
+ if (argument_types_convertible (method, arglist))
+ {
+ /* Retain accessible methods only */
+ if (!not_accessible_p (DECL_CONTEXT (current_function_decl),
+ method, 0))
+ *list = tree_cons (NULL_TREE, method, *list);
+ else
+ /* Also retain all selected method here */
+ *all_list = tree_cons (NULL_TREE, method, *list);
+ }
}
+}
- if (lc)
- return list;
+/* 15.11.2.2 Choose the Most Specific Method */
- if (TREE_CHAIN (list))
+static tree
+find_most_specific_methods_list (list)
+ tree list;
+{
+ int max = 0;
+ tree current, new_list = NULL_TREE;
+ for (current = list; current; current = TREE_CHAIN (current))
{
- tree most_specific_list = NULL_TREE;
- tree current;
- /* 15.11.2.2 Choose the Most Specific Method */
- for (current = list; current; current = TREE_CHAIN (current))
+ tree method;
+ DECL_SPECIFIC_COUNT (TREE_VALUE (current)) = 0;
+
+ for (method = list; method; method = TREE_CHAIN (method))
{
- tree rest;
- tree method = TREE_VALUE (list);
- tree class_from = DECL_CONTEXT (method);
- for (rest = TREE_CHAIN (current); rest; rest = TREE_CHAIN (rest))
+ /* Don't test a method against itself */
+ if (method == current)
+ continue;
+
+ /* Compare arguments and location where method where declared */
+ if (argument_types_convertible (TREE_VALUE (method),
+ TREE_VALUE (current))
+ && valid_method_invocation_conversion_p
+ (DECL_CONTEXT (TREE_VALUE (method)),
+ DECL_CONTEXT (TREE_VALUE (current))))
{
- tree other = TREE_VALUE (rest);
-
- /* METHOD can be declared more specific with regard to OTHER iif:
-
- - The class METHOD belongs can be converted to the
- class OTHER belongs by method invocation conversion
- (5.3). Since we're dealing with classes here, it is
- covered by the identity conversion or the windening
- primitive conversion.
-
- - The types of the arguments of METHOD can be
- converted to the types of the arguments of OTHER by
- method invocation conversion (5.3). */
-
- if (valid_ref_assignconv_cast_p (class_from,
- DECL_CONTEXT (other), 0)
- && 1) /* Test on args non implemented */
- most_specific_list = tree_cons (NULL_TREE, method,
- most_specific_list);
+ int v = ++DECL_SPECIFIC_COUNT (TREE_VALUE (current));
+ max = (v > max ? v : max);
}
}
- list = most_specific_list;
}
- if (!list || TREE_CHAIN (list))
+ /* Review the list and select the maximally specific methods */
+ for (current = list; current; current = TREE_CHAIN (current))
+ if (DECL_SPECIFIC_COUNT (TREE_VALUE (current)) == max)
+ new_list = tree_cons (NULL_TREE, TREE_VALUE (current), new_list);
+
+ /* If we can't find one, lower expectations and try to gather multiple
+ maximally specific methods */
+ while (!new_list)
{
- parse_error_context (cl, "Can't find method `%s(%s)' in class `%s'",
- IDENTIFIER_POINTER (name),
- IDENTIFIER_POINTER (signature),
- IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (class))));
- return NULL_TREE;
+ while (--max > 0)
+ {
+ if (DECL_SPECIFIC_COUNT (TREE_VALUE (current)) == max)
+ new_list = tree_cons (NULL_TREE, TREE_VALUE (current), new_list);
+ }
+ return new_list;
}
- /* 15.11.3 Is the Chosen Method Appropriate ? */
- else
- return TREE_VALUE (list);
+ return new_list;
}
-/* Refine accessible methods from the raw matching method list, as
- specified in 15.11.4.3. Return a (possibly empty) new method
- list. */
+/* Make sure that the type of each M2_OR_ARGLIST arguments can be
+ converted by method invocation conversion (5.3) to the type of the
+ corresponding parameter of M1. Implementation expects M2_OR_ARGLIST
+ to change less often than M1. */
-static tree
-refine_accessible_methods_list (lc, list)
- int lc; /* Looking for Constructor */
- tree list;
+static int
+argument_types_convertible (m1, m2_or_arglist)
+ tree m1, m2_or_arglist;
{
-#define ADD_TO_LIST_AND_CONTINUE \
- { \
- refined_list = tree_cons (NULL_TREE, method, refined_list); \
- continue; \
- }
- tree node, refined_list = NULL_TREE;
- tree current_class_name = DECL_NAME (TYPE_NAME (current_class));
-
- for (node = list; node; node = TREE_CHAIN (node))
- {
- int access, identical;
- tree class_from, method, class_from_name;
-
- method = TREE_VALUE (node);
+ static tree m2_arg_value = NULL_TREE;
+ static tree m2_arg_cache = NULL_TREE;
- /* Constructor not retained here, unless were specifically
- looking for them. */
- if (lc && DECL_CONSTRUCTOR_P (method))
- ADD_TO_LIST_AND_CONTINUE;
+ register tree m1_arg, m2_arg;
- access = get_access_flags_from_decl (method);
- class_from = DECL_CONTEXT (method);
- class_from_name = DECL_NAME (TYPE_NAME (class_from));
-
- identical = identical_subpath_p (current_class_name, class_from_name);
+ m1_arg = TYPE_ARG_TYPES (TREE_TYPE (m1));
+ if (!METHOD_STATIC (m1))
+ m1_arg = TREE_CHAIN (m1_arg);
- /* Check accessibility of class_from from the current one: This
- test has been already carried out when qualify_ambiguous_name
- tried to resolve a type found in an other package. It is not
- necessary to retest things here, the error has been already
- reported. */
-
- /* Public method are always OK */
- if (access & ACC_PUBLIC)
- ADD_TO_LIST_AND_CONTINUE;
-
- /* Protected method access is OK if classes are from the
- same package or part of the same inheritance lineage */
- if ((access & ACC_PROTECTED)
- && (inherits_from_p (current_class, class_from) || identical))
- ADD_TO_LIST_AND_CONTINUE;
+ if (m2_arg_value == m2_or_arglist)
+ m2_arg = m2_arg_cache;
+ else
+ {
+ /* M2_OR_ARGLIST can be a function DECL or a raw list of
+ argument types */
+ if (m2_or_arglist && TREE_CODE (m2_or_arglist) == FUNCTION_DECL)
+ {
+ m2_arg = TYPE_ARG_TYPES (TREE_TYPE (m2_or_arglist));
+ if (!METHOD_STATIC (m2_or_arglist))
+ m2_arg = TREE_CHAIN (m2_arg);
+ }
+ else
+ m2_arg = m2_or_arglist;
- /* Methods with default (package) access are OK if classes are
- from the same default package. */
- if (identical ||
- (!QUALIFIED_P (class_from_name) && !QUALIFIED_P (current_class_name)))
- ADD_TO_LIST_AND_CONTINUE;
+ m2_arg_value = m2_or_arglist;
+ m2_arg_cache = m2_arg;
+ }
- /* Private method accessible iff current class is the node where
- the method is defined */
- if ((access & ACC_PRIVATE) && (class_from == current_class))
- ADD_TO_LIST_AND_CONTINUE;
+ while (m1_arg != end_params_node && m2_arg != end_params_node)
+ {
+ resolve_and_layout (TREE_VALUE (m1_arg), NULL_TREE);
+ if (!valid_method_invocation_conversion_p (TREE_VALUE (m1_arg),
+ TREE_VALUE (m2_arg)))
+ break;
+ m1_arg = TREE_CHAIN (m1_arg);
+ m2_arg = TREE_CHAIN (m2_arg);
}
-#undef ADD_TO_LIST_AND_CONTINUE
- return refined_list;
+ return m1_arg == end_params_node && m2_arg == end_params_node;
}
/* Qualification routines */
@@ -8323,7 +9984,7 @@ qualify_ambiguous_name (id)
tree id;
{
tree qual, qual_wfl, name, decl, ptr_type, saved_current_class;
- int again, super_found = 0, this_found = 0;
+ int again, super_found = 0, this_found = 0, new_array_found = 0;
/* We first qualify the first element, then derive qualification of
others based on the first one. If the first element is qualified
@@ -8351,11 +10012,21 @@ qualify_ambiguous_name (id)
qual_wfl = QUAL_WFL (qual);
}
break;
- case JAVA_NEW_CLASS_EXPR:
+ case NEW_ARRAY_EXPR:
+ qual = TREE_CHAIN (qual);
+ new_array_found = again = 1;
+ continue;
+ case NEW_CLASS_EXPR:
case CONVERT_EXPR:
- case ARRAY_REF:
qual_wfl = TREE_OPERAND (qual_wfl, 0);
break;
+ case ARRAY_REF:
+ while (TREE_CODE (qual_wfl) == ARRAY_REF)
+ qual_wfl = TREE_OPERAND (qual_wfl, 0);
+ break;
+ default:
+ /* Fix for -Wall. Just break doing nothing */
+ break;
}
name = EXPR_WFL_NODE (qual_wfl);
ptr_type = current_class;
@@ -8365,7 +10036,10 @@ qualify_ambiguous_name (id)
{
qual = TREE_CHAIN (qual);
qual_wfl = QUAL_WFL (qual);
- name = EXPR_WFL_NODE (qual_wfl);
+ if (TREE_CODE (qual_wfl) == CALL_EXPR)
+ again = 1;
+ else
+ name = EXPR_WFL_NODE (qual_wfl);
this_found = 1;
}
/* If we have a SUPER, we set the context accordingly */
@@ -8384,13 +10058,22 @@ qualify_ambiguous_name (id)
/* Do one more interation to set things up */
super_found = again = 1;
}
+ /* Loop one more time if we're dealing with ?: or a string
+ constant, or a convert expression */
+ if (TREE_CODE (qual_wfl) == CONDITIONAL_EXPR
+ || TREE_CODE (qual_wfl) == STRING_CST
+ || TREE_CODE (qual_wfl) == CONVERT_EXPR)
+ {
+ qual = TREE_CHAIN (qual);
+ qual_wfl = QUAL_WFL (qual);
+ again = 1;
+ }
} while (again);
/* If name appears within the scope of a location variable
declaration or parameter declaration, then it is an expression
name. We don't carry this test out if we're in the context of the
use of SUPER or THIS */
-
if (!this_found && !super_found && (decl = IDENTIFIER_LOCAL_VALUE (name)))
{
RESOLVE_EXPRESSION_NAME_P (qual_wfl) = 1;
@@ -8399,11 +10082,13 @@ qualify_ambiguous_name (id)
/* If within the class/interface NAME was found to be used there
exists a (possibly inherited) field named NAME, then this is an
- expression name. */
- else if ((decl = lookup_field_wrapper (ptr_type, name)))
+ expression name. If we saw a NEW_ARRAY_EXPR before and want to
+ address length, it is OK. */
+ else if ((decl = lookup_field_wrapper (ptr_type, name))
+ || (new_array_found && name == length_identifier_node))
{
RESOLVE_EXPRESSION_NAME_P (qual_wfl) = 1;
- QUAL_RESOLUTION (qual) = decl;
+ QUAL_RESOLUTION (qual) = (new_array_found ? NULL_TREE : decl);
}
/* We reclassify NAME as a type name if:
@@ -8421,7 +10106,8 @@ qualify_ambiguous_name (id)
}
/* Method call are expression name */
- else if (TREE_CODE (QUAL_WFL (qual)) == CALL_EXPR)
+ else if (TREE_CODE (QUAL_WFL (qual)) == CALL_EXPR
+ || TREE_CODE (QUAL_WFL (qual)) == ARRAY_REF)
RESOLVE_EXPRESSION_NAME_P (qual_wfl) = 1;
/* Check here that NAME isn't declared by more than one
@@ -8482,49 +10168,57 @@ breakdown_qualified (left, right, source)
return 0;
}
-/* Return 1 if N1 and N2 have identical sub-path. */
+/* Patch tree nodes in a function body. When a BLOCK is found, push
+ local variable decls if present.
+ Same as java_complete_lhs, but does resolve static finals to values. */
-static int
-identical_subpath_p (n1, n2)
- tree n1, n2;
+static tree
+java_complete_tree (node)
+ tree node;
{
- tree left1, left2;
-
- if (!QUALIFIED_P (n1) || !QUALIFIED_P (n2))
- return n1 == n2;
-
- breakdown_qualified (&left1, NULL, n1);
- breakdown_qualified (&left2, NULL, n2);
-
- return left1 == left2;
+ node = java_complete_lhs (node);
+ if (TREE_CODE (node) == VAR_DECL && FIELD_STATIC (node)
+ && FIELD_FINAL (node) && DECL_INITIAL (node) != NULL_TREE)
+ {
+ tree value = DECL_INITIAL (node);
+ DECL_INITIAL (node) = NULL_TREE;
+ value = fold_constant_for_init (value, node);
+ DECL_INITIAL (node) = value;
+ if (value != NULL_TREE)
+ return value;
+ }
+ return node;
}
-static int
-not_initialized_as_it_should_p (decl)
- tree decl;
+static tree
+java_stabilize_reference (node)
+ tree node;
{
- if (DECL_P (decl))
+ if (TREE_CODE (node) == COMPOUND_EXPR)
{
- if (TREE_CODE (decl) == FIELD_DECL
- && METHOD_STATIC (current_function_decl))
- return 0;
- return DECL_P (decl) && !INITIALIZED_P (decl);
+ tree op0 = TREE_OPERAND (node, 0);
+ tree op1 = TREE_OPERAND (node, 1);
+ TREE_OPERAND (node, 0) = save_expr (op0);
+ TREE_OPERAND (node, 1) = java_stabilize_reference (op1);
+ return node;
}
- return 0;
+ else
+ return stabilize_reference (node);
}
/* Patch tree nodes in a function body. When a BLOCK is found, push
- local variable decls if present. */
+ local variable decls if present.
+ Same as java_complete_tree, but does not resolve static finals to values. */
static tree
-java_complete_tree (node)
+java_complete_lhs (node)
tree node;
{
- tree nn, cn, wfl_op1, wfl_op2;
- int flag, location;
+ tree nn, cn, wfl_op1, wfl_op2, wfl_op3;
+ int flag;
/* CONVERT_EXPR always has its type set, even though it needs to be
- worked out */
+ worked out. */
if (TREE_TYPE (node) && TREE_CODE (node) != CONVERT_EXPR)
return node;
@@ -8543,13 +10237,67 @@ java_complete_tree (node)
{
DECL_CONTEXT (cn) = current_function_decl;
IDENTIFIER_LOCAL_VALUE (DECL_NAME (cn)) = cn;
- INITIALIZED_P (cn) = 0;
}
- if (BLOCK_EXPR_BODY (node))
+ if (BLOCK_EXPR_BODY (node) == NULL_TREE)
+ CAN_COMPLETE_NORMALLY (node) = 1;
+ else
{
- BLOCK_EXPR_BODY (node) = java_complete_tree (BLOCK_EXPR_BODY (node));
- if (BLOCK_EXPR_BODY (node) == error_mark_node)
+ tree stmt = BLOCK_EXPR_BODY (node);
+ tree *ptr;
+ int error_seen = 0;
+ if (TREE_CODE (stmt) == COMPOUND_EXPR)
+ {
+ /* Re-order from (((A; B); C); ...; Z) to
+ (A; (B; (C ; (...; Z)))).
+ This makes it easier to scan the statements left-to-right
+ without using recursion (which might overflow the stack
+ if the block has many statements. */
+ for (;;)
+ {
+ tree left = TREE_OPERAND (stmt, 0);
+ if (TREE_CODE (left) != COMPOUND_EXPR)
+ break;
+ TREE_OPERAND (stmt, 0) = TREE_OPERAND (left, 1);
+ TREE_OPERAND (left, 1) = stmt;
+ stmt = left;
+ }
+ BLOCK_EXPR_BODY (node) = stmt;
+ }
+
+ /* Now do the actual complete, without deep recursion for
+ long blocks. */
+ ptr = &BLOCK_EXPR_BODY (node);
+ while (TREE_CODE (*ptr) == COMPOUND_EXPR
+ && TREE_OPERAND (*ptr, 1) != empty_stmt_node)
+ {
+ tree cur = java_complete_tree (TREE_OPERAND (*ptr, 0));
+ tree *next = &TREE_OPERAND (*ptr, 1);
+ TREE_OPERAND (*ptr, 0) = cur;
+ if (TREE_CODE (cur) == ERROR_MARK)
+ error_seen++;
+ else if (! CAN_COMPLETE_NORMALLY (cur))
+ {
+ wfl_op2 = *next;
+ for (;;)
+ {
+ if (TREE_CODE (wfl_op2) == BLOCK)
+ wfl_op2 = BLOCK_EXPR_BODY (wfl_op2);
+ else if (TREE_CODE (wfl_op2) == COMPOUND_EXPR)
+ wfl_op2 = TREE_OPERAND (wfl_op2, 0);
+ else
+ break;
+ }
+ if (TREE_CODE (wfl_op2) != CASE_EXPR
+ && TREE_CODE (wfl_op2) != DEFAULT_EXPR)
+ unreachable_stmt_error (*ptr);
+ }
+ ptr = next;
+ }
+ *ptr = java_complete_tree (*ptr);
+
+ if (TREE_CODE (*ptr) == ERROR_MARK || error_seen > 0)
return error_mark_node;
+ CAN_COMPLETE_NORMALLY (node) = CAN_COMPLETE_NORMALLY (*ptr);
}
/* Turn local bindings to null */
for (cn = BLOCK_EXPR_DECLS (node); cn; cn = TREE_CHAIN (cn))
@@ -8559,12 +10307,52 @@ java_complete_tree (node)
break;
/* 2- They are expressions but ultimately deal with statements */
+
+ case THROW_EXPR:
+ wfl_op1 = TREE_OPERAND (node, 0);
+ COMPLETE_CHECK_OP_0 (node);
+ /* CAN_COMPLETE_NORMALLY (node) = 0; */
+ return patch_throw_statement (node, wfl_op1);
+
+ case SYNCHRONIZED_EXPR:
+ wfl_op1 = TREE_OPERAND (node, 0);
+ return patch_synchronized_statement (node, wfl_op1);
+
+ case TRY_EXPR:
+ return patch_try_statement (node);
+
+ case TRY_FINALLY_EXPR:
+ COMPLETE_CHECK_OP_0 (node);
+ COMPLETE_CHECK_OP_1 (node);
+ CAN_COMPLETE_NORMALLY (node)
+ = (CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 0))
+ && CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 1)));
+ TREE_TYPE (node) = TREE_TYPE (TREE_OPERAND (node, 0));
+ return node;
+
+ case CLEANUP_POINT_EXPR:
+ COMPLETE_CHECK_OP_0 (node);
+ TREE_TYPE (node) = void_type_node;
+ CAN_COMPLETE_NORMALLY (node) =
+ CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 0));
+ return node;
+
+ case WITH_CLEANUP_EXPR:
+ COMPLETE_CHECK_OP_0 (node);
+ COMPLETE_CHECK_OP_2 (node);
+ CAN_COMPLETE_NORMALLY (node) =
+ CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 0));
+ TREE_TYPE (node) = void_type_node;
+ return node;
+
case LABELED_BLOCK_EXPR:
PUSH_LABELED_BLOCK (node);
if (LABELED_BLOCK_BODY (node))
COMPLETE_CHECK_OP_1 (node);
TREE_TYPE (node) = void_type_node;
POP_LABELED_BLOCK ();
+ if (CAN_COMPLETE_NORMALLY (LABELED_BLOCK_BODY (node)))
+ CAN_COMPLETE_NORMALLY (node) = 1;
return node;
case EXIT_BLOCK_EXPR:
@@ -8572,21 +10360,92 @@ java_complete_tree (node)
the EXIT_BLOCK_EXPR which doesn't exist it Java */
return patch_bc_statement (node);
+ case CASE_EXPR:
+ cn = java_complete_tree (TREE_OPERAND (node, 0));
+ if (cn == error_mark_node)
+ return cn;
+
+ /* First, the case expression must be constant */
+ cn = fold (cn);
+
+ if (!TREE_CONSTANT (cn))
+ {
+ EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
+ parse_error_context (node, "Constant expression required");
+ return error_mark_node;
+ }
+
+ nn = ctxp->current_loop;
+
+ /* It must be assignable to the type of the switch expression. */
+ if (!try_builtin_assignconv (NULL_TREE,
+ TREE_TYPE (TREE_OPERAND (nn, 0)), cn))
+ {
+ EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
+ parse_error_context
+ (wfl_operator,
+ "Incompatible type for case. Can't convert `%s' to `int'",
+ lang_printable_name (TREE_TYPE (cn), 0));
+ return error_mark_node;
+ }
+
+ cn = fold (convert (int_type_node, cn));
+
+ /* Multiple instance of a case label bearing the same
+ value is checked during code generation. The case
+ expression is allright so far. */
+ TREE_OPERAND (node, 0) = cn;
+ TREE_TYPE (node) = void_type_node;
+ CAN_COMPLETE_NORMALLY (node) = 1;
+ TREE_SIDE_EFFECTS (node) = 1;
+ break;
+
+ case DEFAULT_EXPR:
+ nn = ctxp->current_loop;
+ /* Only one default label is allowed per switch statement */
+ if (SWITCH_HAS_DEFAULT (nn))
+ {
+ EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
+ parse_error_context (wfl_operator,
+ "Duplicate case label: `default'");
+ return error_mark_node;
+ }
+ else
+ SWITCH_HAS_DEFAULT (nn) = 1;
+ TREE_TYPE (node) = void_type_node;
+ TREE_SIDE_EFFECTS (node) = 1;
+ CAN_COMPLETE_NORMALLY (node) = 1;
+ break;
+
+ case SWITCH_EXPR:
case LOOP_EXPR:
PUSH_LOOP (node);
/* Check whether the loop was enclosed in a labeled
statement. If not, create one, insert the loop in it and
return the node */
nn = patch_loop_statement (node);
+
/* Anyways, walk the body of the loop */
- TREE_OPERAND (node, 0) = java_complete_tree (TREE_OPERAND (node, 0));
+ if (TREE_CODE (node) == LOOP_EXPR)
+ TREE_OPERAND (node, 0) = java_complete_tree (TREE_OPERAND (node, 0));
+ /* Switch statement: walk the switch expression and the cases */
+ else
+ node = patch_switch_statement (node);
+
if (TREE_OPERAND (node, 0) == error_mark_node)
- return error_mark_node;
- TREE_TYPE (nn) = TREE_TYPE (node) = void_type_node;
- /* If we returned something different, that's because we
- inserted a label. Pop the label too. */
- if (nn != node)
- POP_LABELED_BLOCK ();
+ nn = error_mark_node;
+ else
+ {
+ TREE_TYPE (nn) = TREE_TYPE (node) = void_type_node;
+ /* If we returned something different, that's because we
+ inserted a label. Pop the label too. */
+ if (nn != node)
+ {
+ if (CAN_COMPLETE_NORMALLY (node))
+ CAN_COMPLETE_NORMALLY (nn) = 1;
+ POP_LABELED_BLOCK ();
+ }
+ }
POP_LOOP ();
return nn;
@@ -8609,27 +10468,71 @@ java_complete_tree (node)
return patch_if_else_statement (node);
break;
+ case CONDITIONAL_EXPR:
+ /* Condition */
+ wfl_op1 = TREE_OPERAND (node, 0);
+ COMPLETE_CHECK_OP_0 (node);
+ wfl_op2 = TREE_OPERAND (node, 1);
+ COMPLETE_CHECK_OP_1 (node);
+ wfl_op3 = TREE_OPERAND (node, 2);
+ COMPLETE_CHECK_OP_2 (node);
+ return patch_conditional_expr (node, wfl_op1, wfl_op2);
+
/* 3- Expression section */
case COMPOUND_EXPR:
- TREE_OPERAND (node, 0) = java_complete_tree (TREE_OPERAND (node, 0));
- TREE_OPERAND (node, 1) = java_complete_tree (TREE_OPERAND (node, 1));
- if (TREE_OPERAND (node, 1) == error_mark_node)
- return error_mark_node;
+ wfl_op2 = TREE_OPERAND (node, 1);
+ TREE_OPERAND (node, 0) = nn =
+ java_complete_tree (TREE_OPERAND (node, 0));
+ if (wfl_op2 == empty_stmt_node)
+ CAN_COMPLETE_NORMALLY (node) = CAN_COMPLETE_NORMALLY (nn);
+ else
+ {
+ if (! CAN_COMPLETE_NORMALLY (nn) && TREE_CODE (nn) != ERROR_MARK)
+ {
+ /* An unreachable condition in a do-while statement
+ is *not* (technically) an unreachable statement. */
+ nn = wfl_op2;
+ if (TREE_CODE (nn) == EXPR_WITH_FILE_LOCATION)
+ nn = EXPR_WFL_NODE (nn);
+ if (TREE_CODE (nn) != EXIT_EXPR)
+ {
+ SET_WFL_OPERATOR (wfl_operator, node, wfl_op2);
+ parse_error_context (wfl_operator, "Unreachable statement");
+ }
+ }
+ TREE_OPERAND (node, 1) = java_complete_tree (TREE_OPERAND (node, 1));
+ if (TREE_OPERAND (node, 1) == error_mark_node)
+ return error_mark_node;
+ CAN_COMPLETE_NORMALLY (node)
+ = CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 1));
+ }
TREE_TYPE (node) = TREE_TYPE (TREE_OPERAND (node, 1));
break;
case RETURN_EXPR:
+ /* CAN_COMPLETE_NORMALLY (node) = 0; */
return patch_return (node);
case EXPR_WITH_FILE_LOCATION:
if (!EXPR_WFL_NODE (node) /* Or a PRIMARY flag ? */
|| TREE_CODE (EXPR_WFL_NODE (node)) == IDENTIFIER_NODE)
- return resolve_expression_name (node);
+ {
+ node = resolve_expression_name (node, NULL);
+ if (node == error_mark_node)
+ return node;
+ CAN_COMPLETE_NORMALLY (node) = 1;
+ }
else
{
- EXPR_WFL_NODE (node) = java_complete_tree (EXPR_WFL_NODE (node));
- TREE_SIDE_EFFECTS (node) = 1;
- if (EXPR_WFL_NODE (node) == error_mark_node)
+ tree body;
+ int save_lineno = lineno;
+ lineno = EXPR_WFL_LINENO (node);
+ body = java_complete_tree (EXPR_WFL_NODE (node));
+ lineno = save_lineno;
+ EXPR_WFL_NODE (node) = body;
+ TREE_SIDE_EFFECTS (node) = TREE_SIDE_EFFECTS (body);
+ CAN_COMPLETE_NORMALLY (node) = CAN_COMPLETE_NORMALLY (body);
+ if (body == error_mark_node)
{
/* Its important for the evaluation of assignment that
this mark on the TREE_TYPE is propagated. */
@@ -8638,10 +10541,11 @@ java_complete_tree (node)
}
else
TREE_TYPE (node) = TREE_TYPE (EXPR_WFL_NODE (node));
+
}
break;
- case JAVA_NEW_ARRAY_EXPR:
+ case NEW_ARRAY_EXPR:
/* Patch all the dimensions */
flag = 0;
for (cn = TREE_OPERAND (node, 1); cn; cn = TREE_CHAIN (cn))
@@ -8655,7 +10559,7 @@ java_complete_tree (node)
}
else
{
- TREE_VALUE (cn) = save_expr (dim);
+ TREE_VALUE (cn) = dim;
/* Setup the location of the current dimension, for
later error report. */
TREE_PURPOSE (cn) =
@@ -8665,57 +10569,96 @@ java_complete_tree (node)
}
/* They complete the array creation expression, if no errors
were found. */
- return (flag ? error_mark_node : patch_newarray (node));
+ CAN_COMPLETE_NORMALLY (node) = 1;
+ return (flag ? error_mark_node
+ : force_evaluation_order (patch_newarray (node)));
- case JAVA_NEW_CLASS_EXPR:
+ case NEW_CLASS_EXPR:
case CALL_EXPR:
- /* Complete function's argument first */
+ /* Complete function's argument(s) first */
if (complete_function_arguments (node))
return error_mark_node;
else
- return patch_method_invocation_stmt (node, NULL_TREE, NULL_TREE, NULL);
+ {
+ tree decl, wfl = TREE_OPERAND (node, 0);
+ int in_this = CALL_THIS_CONSTRUCTOR_P (node);
+
+ node = patch_method_invocation (node, NULL_TREE,
+ NULL_TREE, 0, &decl);
+ if (node == error_mark_node)
+ return error_mark_node;
+
+ check_thrown_exceptions (EXPR_WFL_LINECOL (node), decl);
+ /* If we call this(...), register signature and positions */
+ if (in_this)
+ DECL_CONSTRUCTOR_CALLS (current_function_decl) =
+ tree_cons (wfl, decl,
+ DECL_CONSTRUCTOR_CALLS (current_function_decl));
+ CAN_COMPLETE_NORMALLY (node) = 1;
+ return force_evaluation_order (node);
+ }
case MODIFY_EXPR:
/* Save potential wfls */
wfl_op1 = TREE_OPERAND (node, 0);
wfl_op2 = TREE_OPERAND (node, 1);
- TREE_OPERAND (node, 0) = java_complete_tree (wfl_op1);
+ TREE_OPERAND (node, 0) = java_complete_lhs (wfl_op1);
if (TREE_OPERAND (node, 0) == error_mark_node)
return error_mark_node;
if (COMPOUND_ASSIGN_P (wfl_op2))
{
- tree lvalue;
- tree other =
- java_complete_tree (TREE_OPERAND (wfl_op2, 0));
+ tree lvalue = java_stabilize_reference (TREE_OPERAND (node, 0));
/* Hand stablize the lhs on both places */
- lvalue = stabilize_reference (other);
TREE_OPERAND (node, 0) = lvalue;
TREE_OPERAND (TREE_OPERAND (node, 1), 0) = lvalue;
- }
- /* There are cases where the type of RHS is fixed. In those
- cases, if the evaluation of the RHS fails, we further the
- evaluation of the assignment to detect more errors. */
- nn = java_complete_tree (TREE_OPERAND (node, 1));
- if (nn == error_mark_node)
- {
- /* It's hopeless, but we can further things on to discover
- an error during the assignment. In any cases, the
- assignment operation fails. */
- if (TREE_CODE (TREE_OPERAND (node, 1)) != EXPR_WITH_FILE_LOCATION
- && TREE_TYPE (TREE_OPERAND (node, 1)) != error_mark_node)
- patch_assignment (node, wfl_op1, wfl_op2);
+ /* Now complete the RHS. We write it back later on. */
+ nn = java_complete_tree (TREE_OPERAND (node, 1));
- /* Now, we still mark the lhs as initialized */
- if (DECL_P (TREE_OPERAND (node, 0)))
- INITIALIZED_P (TREE_OPERAND (node, 0)) = 1;
+ if ((cn = patch_string (nn)))
+ nn = cn;
- return error_mark_node;
+ /* The last part of the rewrite for E1 op= E2 is to have
+ E1 = (T)(E1 op E2), with T being the type of E1. */
+ nn = java_complete_tree (build_cast (EXPR_WFL_LINECOL (wfl_op2),
+ TREE_TYPE (lvalue), nn));
}
+
+ /* If we're about to patch a NEW_ARRAY_INIT, we call a special
+ function to complete this RHS */
+ else if (TREE_CODE (wfl_op2) == NEW_ARRAY_INIT)
+ nn = patch_new_array_init (TREE_TYPE (TREE_OPERAND (node, 0)),
+ TREE_OPERAND (node, 1));
+ /* Otherwise we simply complete the RHS */
+ else
+ nn = java_complete_tree (TREE_OPERAND (node, 1));
+
+ if (nn == error_mark_node)
+ return error_mark_node;
+
+ /* Write back the RHS as we evaluated it. */
TREE_OPERAND (node, 1) = nn;
- return patch_assignment (node, wfl_op1, wfl_op2);
+
+ /* In case we're handling = with a String as a RHS, we need to
+ produce a String out of the RHS (it might still be a
+ STRING_CST or a StringBuffer at this stage */
+ if ((nn = patch_string (TREE_OPERAND (node, 1))))
+ TREE_OPERAND (node, 1) = nn;
+ node = patch_assignment (node, wfl_op1, wfl_op2);
+ CAN_COMPLETE_NORMALLY (node) = 1;
+
+ /* Before returning the node, in the context of a static field
+ assignment in <clinit>, we may want to carray further
+ optimizations. (VAR_DECL means it's a static field. See
+ add_field. */
+ if (DECL_NAME (current_function_decl) == clinit_identifier_node
+ && MODIFY_EXPR_FROM_INITIALIZATION_P (node)
+ && TREE_CODE (TREE_OPERAND (node, 0)) == VAR_DECL)
+ node = patch_initialized_static_field (node);
+
+ return node;
case MULT_EXPR:
case PLUS_EXPR:
@@ -8740,15 +10683,35 @@ java_complete_tree (node)
knows how to handle those cases. */
wfl_op1 = TREE_OPERAND (node, 0);
wfl_op2 = TREE_OPERAND (node, 1);
- TREE_OPERAND (node, 0) = java_complete_tree (wfl_op1);
- if (TREE_OPERAND (node, 0) == error_mark_node)
- return error_mark_node;
- TREE_OPERAND (node, 1) = java_complete_tree (wfl_op2);
- if (TREE_OPERAND (node, 1) == error_mark_node)
- return error_mark_node;
- return patch_binop (node, wfl_op1, wfl_op2);
- case JAVA_UNARY_PLUS_EXPR:
+ CAN_COMPLETE_NORMALLY (node) = 1;
+ /* Don't complete string nodes if dealing with the PLUS operand. */
+ if (TREE_CODE (node) != PLUS_EXPR || !JSTRING_P (wfl_op1))
+ {
+ nn = java_complete_tree (wfl_op1);
+ if (nn == error_mark_node)
+ return error_mark_node;
+ if ((cn = patch_string (nn)))
+ nn = cn;
+ TREE_OPERAND (node, 0) = nn;
+ }
+ if (TREE_CODE (node) != PLUS_EXPR || !JSTRING_P (wfl_op2))
+ {
+ nn = java_complete_tree (wfl_op2);
+ if (nn == error_mark_node)
+ return error_mark_node;
+ if ((cn = patch_string (nn)))
+ nn = cn;
+ TREE_OPERAND (node, 1) = nn;
+ }
+ return force_evaluation_order (patch_binop (node, wfl_op1, wfl_op2));
+
+ case INSTANCEOF_EXPR:
+ wfl_op1 = TREE_OPERAND (node, 0);
+ COMPLETE_CHECK_OP_0 (node);
+ return patch_binop (node, wfl_op1, TREE_OPERAND (node, 1));
+
+ case UNARY_PLUS_EXPR:
case NEGATE_EXPR:
case TRUTH_NOT_EXPR:
case BIT_NOT_EXPR:
@@ -8760,10 +10723,13 @@ java_complete_tree (node)
/* There are cases were wfl_op1 is a WFL. patch_unaryop knows
how to handle those cases. */
wfl_op1 = TREE_OPERAND (node, 0);
+ CAN_COMPLETE_NORMALLY (node) = 1;
TREE_OPERAND (node, 0) = java_complete_tree (wfl_op1);
if (TREE_OPERAND (node, 0) == error_mark_node)
return error_mark_node;
- return patch_unaryop (node, wfl_op1);
+ node = patch_unaryop (node, wfl_op1);
+ CAN_COMPLETE_NORMALLY (node) = 1;
+ break;
case ARRAY_REF:
/* There are cases were wfl_op1 is a WFL. patch_array_ref knows
@@ -8772,14 +10738,45 @@ java_complete_tree (node)
TREE_OPERAND (node, 0) = java_complete_tree (wfl_op1);
if (TREE_OPERAND (node, 0) == error_mark_node)
return error_mark_node;
+ if (!flag_emit_class_files)
+ TREE_OPERAND (node, 0) = save_expr (TREE_OPERAND (node, 0));
/* The same applies to wfl_op2 */
wfl_op2 = TREE_OPERAND (node, 1);
TREE_OPERAND (node, 1) = java_complete_tree (wfl_op2);
if (TREE_OPERAND (node, 1) == error_mark_node)
return error_mark_node;
- return patch_array_ref (node, wfl_op1, wfl_op2);
+ if (!flag_emit_class_files)
+ TREE_OPERAND (node, 1) = save_expr (TREE_OPERAND (node, 1));
+ return patch_array_ref (node);
- case JAVA_THIS_EXPR:
+ case RECORD_TYPE:
+ return node;;
+
+ case COMPONENT_REF:
+ /* The first step in the re-write of qualified name handling. FIXME.
+ So far, this is only to support PRIMTYPE.class -> PRIMCLASS.TYPE. */
+ TREE_OPERAND (node, 0) = java_complete_tree (TREE_OPERAND (node, 0));
+ if (TREE_CODE (TREE_OPERAND (node, 0)) == RECORD_TYPE)
+ {
+ tree name = TREE_OPERAND (node, 1);
+ tree field = lookup_field_wrapper (TREE_OPERAND (node, 0), name);
+ if (field == NULL_TREE)
+ {
+ error ("missing static field `%s'", IDENTIFIER_POINTER (name));
+ return error_mark_node;
+ }
+ if (! FIELD_STATIC (field))
+ {
+ error ("not a static field `%s'", IDENTIFIER_POINTER (name));
+ return error_mark_node;
+ }
+ return field;
+ }
+ else
+ fatal ("unimplemented java_complete_tree for COMPONENT_REF");
+ break;
+
+ case THIS_EXPR:
/* Can't use THIS in a static environment */
if (!current_this)
{
@@ -8789,18 +10786,24 @@ java_complete_tree (node)
TREE_TYPE (node) = error_mark_node;
return error_mark_node;
}
+ if (ctxp->explicit_constructor_p)
+ {
+ EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
+ parse_error_context
+ (wfl_operator, "Can't reference `this' or `super' before the "
+ "superclass constructor has been called");
+ TREE_TYPE (node) = error_mark_node;
+ return error_mark_node;
+ }
return current_this;
- case STRING_CST:
- /* Build the internal string representation */
- push_obstacks (&permanent_obstack, &permanent_obstack);
- node = get_identifier (TREE_STRING_POINTER (node));
- location = alloc_name_constant (CONSTANT_String, node);
- node = build_ref_from_constant_pool (location);
- TREE_TYPE (node) = promote_type (string_type_node);
- return node;
-
default:
+ CAN_COMPLETE_NORMALLY (node) = 1;
+ /* Ok: may be we have a STRING_CST or a crafted `StringBuffer'
+ and it's time to turn it into the appropriate String object
+ */
+ if ((node = patch_string (node)))
+ return node;
fatal ("No case for tree code `%s' - java_complete_tree\n",
tree_code_name [TREE_CODE (node)]);
}
@@ -8817,25 +10820,27 @@ complete_function_arguments (node)
int flag = 0;
tree cn;
+ ctxp->explicit_constructor_p += (CALL_THIS_CONSTRUCTOR_P (node) ? 1 : 0);
for (cn = TREE_OPERAND (node, 1); cn; cn = TREE_CHAIN (cn))
{
- tree wfl = TREE_VALUE (cn), parm;
+ tree wfl = TREE_VALUE (cn), parm, temp;
parm = java_complete_tree (wfl);
if (parm == error_mark_node)
{
flag = 1;
continue;
}
- if (TREE_CODE (TREE_TYPE (parm)) == RECORD_TYPE)
- TREE_VALUE (cn) = convert (promote_type (TREE_TYPE (parm)), parm);
- else
- TREE_VALUE (cn) = save_expr (parm);
- if (not_initialized_as_it_should_p (parm))
- {
- ERROR_VARIABLE_NOT_INITIALIZED (wfl, EXPR_WFL_NODE (wfl));
- INITIALIZED_P (parm) = 1;
- }
+ /* If have a string literal that we haven't transformed yet or a
+ crafted string buffer, as a result of use of the the String
+ `+' operator. Build `parm.toString()' and expand it. */
+ if ((temp = patch_string (parm)))
+ parm = temp;
+ /* Inline PRIMTYPE.TYPE read access */
+ parm = maybe_build_primttype_type_ref (parm, wfl);
+
+ TREE_VALUE (cn) = parm;
}
+ ctxp->explicit_constructor_p -= (CALL_THIS_CONSTRUCTOR_P (node) ? 1 : 0);
return flag;
}
@@ -8863,28 +10868,39 @@ build_expr_block (body, decls)
{
tree node = make_node (BLOCK);
BLOCK_EXPR_DECLS (node) = decls;
- BLOCK_EXPR_BODY (body);
+ BLOCK_EXPR_BODY (node) = body;
if (body)
TREE_TYPE (node) = TREE_TYPE (body);
TREE_SIDE_EFFECTS (node) = 1;
return node;
}
-/* Create a new function block and link its supercontext to the
- previous block. The current function DECL is used as supercontext
- when enter_block is called for the first time for a given
- function. The current function body (DECL_FUNCTION_BODY) is set to
- the newly created block. */
-
-static block_level = 0;
+/* Create a new function block and link it approriately to current
+ function block chain */
static tree
enter_block ()
{
- tree b = build_expr_block (NULL_TREE, NULL_TREE);
+ return (enter_a_block (build_expr_block (NULL_TREE, NULL_TREE)));
+}
+
+/* Link block B supercontext to the previous block. The current
+ function DECL is used as supercontext when enter_a_block is called
+ for the first time for a given function. The current function body
+ (DECL_FUNCTION_BODY) is set to be block B. */
+
+static tree
+enter_a_block (b)
+ tree b;
+{
tree fndecl = current_function_decl;
- if (!DECL_FUNCTION_BODY (fndecl))
+ if (!fndecl) {
+ BLOCK_SUPERCONTEXT (b) = current_static_block;
+ current_static_block = b;
+ }
+
+ else if (!DECL_FUNCTION_BODY (fndecl))
{
BLOCK_SUPERCONTEXT (b) = fndecl;
DECL_FUNCTION_BODY (fndecl) = b;
@@ -8904,11 +10920,20 @@ enter_block ()
static tree
exit_block ()
{
- tree b = DECL_FUNCTION_BODY (current_function_decl);
-
- if (BLOCK_SUPERCONTEXT (b) != current_function_decl)
- DECL_FUNCTION_BODY (current_function_decl) = BLOCK_SUPERCONTEXT (b);
+ tree b;
+ if (current_function_decl)
+ {
+ b = DECL_FUNCTION_BODY (current_function_decl);
+ if (BLOCK_SUPERCONTEXT (b) != current_function_decl)
+ DECL_FUNCTION_BODY (current_function_decl) = BLOCK_SUPERCONTEXT (b);
+ }
+ else
+ {
+ b = current_static_block;
+ if (BLOCK_SUPERCONTEXT (b))
+ current_static_block = BLOCK_SUPERCONTEXT (b);
+ }
return b;
}
@@ -8920,7 +10945,7 @@ static tree
lookup_name_in_blocks (name)
tree name;
{
- tree b = DECL_FUNCTION_BODY (current_function_decl);
+ tree b = GET_CURRENT_BLOCK (current_function_decl);
while (b != current_function_decl)
{
@@ -8942,7 +10967,7 @@ lookup_name_in_blocks (name)
static void
maybe_absorb_scoping_blocks ()
{
- while (BLOCK_EXPR_ORIGIN (DECL_FUNCTION_BODY (current_function_decl)))
+ while (BLOCK_EXPR_ORIGIN (GET_CURRENT_BLOCK (current_function_decl)))
{
tree b = exit_block ();
java_method_add_stmt (current_function_decl, b);
@@ -8955,7 +10980,39 @@ maybe_absorb_scoping_blocks ()
are building incomplete tree nodes and the patch_* functions that
are completing them. */
-/* Build an incomplete CALL_EXPR node. Encapsulate it within a WFL */
+/* Build a super() constructor invocation. Returns empty_stmt_node if
+ we're currently dealing with the class java.lang.Object. */
+
+static tree
+build_super_invocation ()
+{
+ if (current_class == object_type_node)
+ return empty_stmt_node;
+ else
+ {
+ tree super_wfl = build_wfl_node (super_identifier_node);
+ return build_method_invocation (super_wfl, NULL_TREE);
+ }
+}
+
+/* Build a SUPER/THIS qualified method invocation. */
+
+static tree
+build_this_super_qualified_invocation (use_this, name, args, lloc, rloc)
+ int use_this;
+ tree name, args;
+ int lloc, rloc;
+
+{
+ tree invok;
+ tree wfl =
+ build_wfl_node (use_this ? this_identifier_node : super_identifier_node);
+ EXPR_WFL_LINECOL (wfl) = lloc;
+ invok = build_method_invocation (name, args);
+ return make_qualified_primary (wfl, invok, rloc);
+}
+
+/* Build an incomplete CALL_EXPR node. */
static tree
build_method_invocation (name, args)
@@ -8964,7 +11021,18 @@ build_method_invocation (name, args)
{
tree call = build (CALL_EXPR, NULL_TREE, name, args, NULL_TREE);
TREE_SIDE_EFFECTS (call) = 1;
- /* Check on cases where NAME isn't a WFL. FIXME */
+ EXPR_WFL_LINECOL (call) = EXPR_WFL_LINECOL (name);
+ return call;
+}
+
+/* Build an incomplete new xxx(...) node. */
+
+static tree
+build_new_invocation (name, args)
+ tree name, args;
+{
+ tree call = build (NEW_CLASS_EXPR, NULL_TREE, name, args, NULL_TREE);
+ TREE_SIDE_EFFECTS (call) = 1;
EXPR_WFL_LINECOL (call) = EXPR_WFL_LINECOL (name);
return call;
}
@@ -8993,7 +11061,7 @@ build_assignment (op, op_location, lhs, rhs)
/* Print an INTEGER_CST node in a static buffer, and return the buffer. */
-static char *
+char *
print_int_node (node)
tree node;
{
@@ -9018,6 +11086,48 @@ print_int_node (node)
return buffer;
}
+/* Return 1 if you an assignment of a FINAL is attempted */
+
+static int
+check_final_assignment (lvalue, wfl)
+ tree lvalue, wfl;
+{
+ if (JDECL_P (lvalue) && FIELD_FINAL (lvalue) &&
+ DECL_NAME (current_function_decl) != clinit_identifier_node)
+ {
+ parse_error_context
+ (wfl, "Can't assign a value to the final variable `%s'",
+ IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl)));
+ return 1;
+ }
+ return 0;
+}
+
+/* Inline references to java.lang.PRIMTYPE.TYPE when accessed in
+ read. This is needed to avoid circularities in the implementation
+ of these fields in libjava. */
+
+static tree
+maybe_build_primttype_type_ref (rhs, wfl)
+ tree rhs, wfl;
+{
+ tree to_return = NULL_TREE;
+ tree rhs_type = TREE_TYPE (rhs);
+ if (TREE_CODE (rhs) == COMPOUND_EXPR)
+ {
+ tree n = TREE_OPERAND (rhs, 1);
+ if (TREE_CODE (n) == VAR_DECL
+ && DECL_NAME (n) == TYPE_identifier_node
+ && rhs_type == class_ptr_type)
+ {
+ char *self_name = IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl));
+ if (!strncmp (self_name, "java.lang.", 10))
+ to_return = build_primtype_type_ref (self_name);
+ }
+ }
+ return (to_return ? to_return : rhs );
+}
+
/* 15.25 Assignment operators. */
static tree
@@ -9027,27 +11137,20 @@ patch_assignment (node, wfl_op1, wfl_op2)
tree wfl_op2;
{
tree rhs = TREE_OPERAND (node, 1);
- tree lvalue = TREE_OPERAND (node, 0);
+ tree lvalue = TREE_OPERAND (node, 0), llvalue;
tree lhs_type, rhs_type, new_rhs = NULL_TREE;
- int all_primitive;
int error_found = 0;
int lvalue_from_array = 0;
/* Can't assign to a final. */
- if (DECL_P (lvalue) && FIELD_FINAL (lvalue))
- {
- parse_error_context
- (wfl_op1, "Can't assign a value to the final variable `%s'",
- IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl_op1)));
- error_found = 1;
- }
+ if (check_final_assignment (lvalue, wfl_op1))
+ error_found = 1;
EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
/* Lhs can be a named variable */
- if (DECL_P (lvalue))
+ if (JDECL_P (lvalue))
{
- INITIALIZED_P (lvalue) = 1;
lhs_type = TREE_TYPE (lvalue);
}
/* Or Lhs can be a array acccess. Should that be lvalue ? FIXME +
@@ -9063,64 +11166,30 @@ patch_assignment (node, wfl_op1, wfl_op2)
/* Or a function return slot */
else if (TREE_CODE (lvalue) == RESULT_DECL)
lhs_type = TREE_TYPE (lvalue);
- /* Otherwise, this is an error */
- else
+ /* Otherwise, we might want to try to write into an optimized static
+ final, this is an of a different nature, reported further on. */
+ else if (TREE_CODE (wfl_op1) == EXPR_WITH_FILE_LOCATION
+ && resolve_expression_name (wfl_op1, &llvalue)
+ && check_final_assignment (llvalue, wfl_op1))
+ {
+ error_found = 1;
+ /* What we should do instead is resetting the all the flags
+ previously set, exchange lvalue for llvalue and continue. */
+ return error_mark_node;
+ }
+ else
{
parse_error_context (wfl_op1, "Invalid left hand side of assignment");
error_found = 1;
}
rhs_type = TREE_TYPE (rhs);
+ /* 5.1 Try the assignment conversion for builtin type. */
+ new_rhs = try_builtin_assignconv (wfl_op1, lhs_type, rhs);
- /* 5.2 Begin Assignment conversion */
-
- /* 5.1.1 Try Identity Conversion */
- if (lhs_type == rhs_type)
- new_rhs = rhs;
-
- /* 5.1.2 Try Widening Primitive Conversion */
- all_primitive = JPRIMITIVE_TYPE_P (lhs_type) && JPRIMITIVE_TYPE_P (rhs_type);
- if (all_primitive && JINTEGRAL_TYPE_P (rhs_type)
- && ((TYPE_PRECISION (rhs_type) < TYPE_PRECISION (lhs_type))
- || (JFLOAT_TYPE_P (lhs_type) &&
- TYPE_PRECISION (rhs_type) == TYPE_PRECISION (lhs_type))))
- new_rhs = convert (lhs_type, rhs);
- else if (all_primitive && JFLOAT_TYPE_P (rhs_type)
- && (TYPE_PRECISION (rhs_type) < TYPE_PRECISION (lhs_type)))
- new_rhs = convert (lhs_type, rhs);
-
- /* Try a narrowing primitive conversion:
- - expression is a constant expression of type int AND
- - variable is byte, short or char AND
- - The value of the expression is representable in the type of the
- variable */
- else if (rhs_type == int_type_node && TREE_CONSTANT (rhs)
- && (lhs_type == byte_type_node || lhs_type == char_type_node
- || lhs_type == short_type_node))
- {
- if (int_fits_type_p (rhs, lhs_type))
- new_rhs = convert (lhs_type, rhs);
- else
- parse_warning_context
- (wfl_op1, "Constant expression `%s' to wide for narrowing "
- "primitive conversion to `%s'",
- print_int_node (rhs), lang_printable_name (lhs_type));
- /* Reported a warning that will turn into an error further
- down, so we don't return */
- }
-
- /* 5.2 Try a reference conversion */
- else if (!JPRIMITIVE_TYPE_P (rhs_type) && JREFERENCE_TYPE_P (lhs_type))
- {
- /* `null' may be assigned to any reference type */
- if (rhs == null_pointer_node)
- new_rhs = null_pointer_node;
- /* Try the reference assignment conversion */
- else if (valid_ref_assignconv_cast_p (rhs_type, lhs_type, 0))
- new_rhs = rhs;
- if (new_rhs)
- lhs_type = promote_type (rhs_type);
- }
+ /* 5.2 If it failed, try a reference conversion */
+ if (!new_rhs && (new_rhs = try_reference_assignconv (lhs_type, rhs)))
+ lhs_type = promote_type (rhs_type);
/* 15.25.2 If we have a compound assignment, convert RHS into the
type of the LHS */
@@ -9130,8 +11199,8 @@ patch_assignment (node, wfl_op1, wfl_op2)
/* Explicit cast required. This is an error */
if (!new_rhs)
{
- char *t1 = strdup ((char *)lang_printable_name (TREE_TYPE (rhs)));
- char *t2 = strdup ((char *)lang_printable_name (lhs_type));
+ char *t1 = strdup (lang_printable_name (TREE_TYPE (rhs), 0));
+ char *t2 = strdup (lang_printable_name (lhs_type, 0));
tree wfl;
char operation [32]; /* Max size known */
@@ -9159,7 +11228,7 @@ patch_assignment (node, wfl_op1, wfl_op2)
}
parse_error_context
- (wfl, (!can_cast_to_p (rhs_type, lhs_type) ?
+ (wfl, (!valid_cast_to_p (rhs_type, lhs_type) ?
"Incompatible type for %s. Can't convert `%s' to `%s'" :
"Incompatible type for %s. Explicit cast "
"needed to convert `%s' to `%s'"), operation, t1, t2);
@@ -9167,13 +11236,9 @@ patch_assignment (node, wfl_op1, wfl_op2)
error_found = 1;
}
- /* Before reporting type incompatibility errors, check that the rhs
- is initialized, if a variable */
- if (not_initialized_as_it_should_p (rhs))
- {
- ERROR_VARIABLE_NOT_INITIALIZED (wfl_op2, DECL_NAME (rhs));
- INITIALIZED_P (rhs) = 1;
- }
+ /* Inline read access to java.lang.PRIMTYPE.TYPE */
+ if (new_rhs)
+ new_rhs = maybe_build_primttype_type_ref (new_rhs, wfl_op2);
if (error_found)
return error_mark_node;
@@ -9182,32 +11247,155 @@ patch_assignment (node, wfl_op1, wfl_op2)
assignment into an array element, return it here. */
if (TREE_CODE (node) == COMPOUND_EXPR)
return node;
-
+
TREE_OPERAND (node, 0) = lvalue;
TREE_OPERAND (node, 1) = new_rhs;
TREE_TYPE (node) = lhs_type;
return node;
}
-/* Check that SOURCE can be converted into DEST, at least with a
- cast. If the convertion can't occur at all, return 0 otherwise
- 1. This function is used to produce accurate error messages on the
- reasons why an assignment failed. */
+/* Optimize static (final) field initialized upon declaration.
+ - If the field is static final and is assigned to a primitive
+ constant type, then set its DECL_INITIAL to the value.
+ - More to come. */
+
+static tree
+patch_initialized_static_field (node)
+ tree node;
+{
+ tree field = TREE_OPERAND (node, 0);
+ tree value = TREE_OPERAND (node, 1);
+
+ if (DECL_INITIAL (field) != NULL_TREE)
+ {
+ tree type = TREE_TYPE (value);
+ if (FIELD_FINAL (field) && TREE_CONSTANT (value)
+ && (JPRIMITIVE_TYPE_P (type)
+ || (flag_emit_class_files
+ && TREE_CODE (type) == POINTER_TYPE
+ && TREE_TYPE (type) == string_type_node)))
+ {
+ DECL_INITIAL (field) = value;
+ return empty_stmt_node;
+ }
+ DECL_INITIAL (field) = NULL_TREE;
+ }
+ return node;
+}
+
+/* Check that type SOURCE can be cast into type DEST. If the cast
+ can't occur at all, return 0 otherwise 1. This function is used to
+ produce accurate error messages on the reasons why an assignment
+ failed. */
+
+static tree
+try_reference_assignconv (lhs_type, rhs)
+ tree lhs_type, rhs;
+{
+ tree new_rhs = NULL_TREE;
+ tree rhs_type = TREE_TYPE (rhs);
+
+ if (!JPRIMITIVE_TYPE_P (rhs_type) && JREFERENCE_TYPE_P (lhs_type))
+ {
+ /* `null' may be assigned to any reference type */
+ if (rhs == null_pointer_node)
+ new_rhs = null_pointer_node;
+ /* Try the reference assignment conversion */
+ else if (valid_ref_assignconv_cast_p (rhs_type, lhs_type, 0))
+ new_rhs = rhs;
+ /* This is a magic assignment that we process differently */
+ else if (rhs == soft_exceptioninfo_call_node)
+ new_rhs = rhs;
+ }
+ return new_rhs;
+}
+
+/* Check that RHS can be converted into LHS_TYPE by the assignment
+ conversion (5.2), for the cases of RHS being a builtin type. Return
+ NULL_TREE if the conversion fails or if because RHS isn't of a
+ builtin type. Return a converted RHS if the conversion is possible. */
+
+static tree
+try_builtin_assignconv (wfl_op1, lhs_type, rhs)
+ tree wfl_op1, lhs_type, rhs;
+{
+ tree new_rhs = NULL_TREE;
+ tree rhs_type = TREE_TYPE (rhs);
+
+ /* Zero accepted everywhere */
+ if (TREE_CODE (rhs) == INTEGER_CST
+ && TREE_INT_CST_HIGH (rhs) == 0 && TREE_INT_CST_LOW (rhs) == 0
+ && JPRIMITIVE_TYPE_P (rhs_type))
+ new_rhs = convert (lhs_type, rhs);
+
+ /* 5.1.1 Try Identity Conversion,
+ 5.1.2 Try Widening Primitive Conversion */
+ else if (valid_builtin_assignconv_identity_widening_p (lhs_type, rhs_type))
+ new_rhs = convert (lhs_type, rhs);
+
+ /* Try a narrowing primitive conversion (5.1.3):
+ - expression is a constant expression of type int AND
+ - variable is byte, short or char AND
+ - The value of the expression is representable in the type of the
+ variable */
+ else if (rhs_type == int_type_node && TREE_CONSTANT (rhs)
+ && (lhs_type == byte_type_node || lhs_type == char_type_node
+ || lhs_type == short_type_node))
+ {
+ if (int_fits_type_p (rhs, lhs_type))
+ new_rhs = convert (lhs_type, rhs);
+ else if (wfl_op1) /* Might be called with a NULL */
+ parse_warning_context
+ (wfl_op1, "Constant expression `%s' to wide for narrowing "
+ "primitive conversion to `%s'",
+ print_int_node (rhs), lang_printable_name (lhs_type, 0));
+ /* Reported a warning that will turn into an error further
+ down, so we don't return */
+ }
+
+ return new_rhs;
+}
+
+/* Return 1 if RHS_TYPE can be converted to LHS_TYPE by identity
+ conversion (5.1.1) or widening primitve conversion (5.1.2). Return
+ 0 is the conversion test fails. This implements parts the method
+ invocation convertion (5.3). */
static int
-can_cast_to_p (source, dest)
- tree source;
- tree dest;
+valid_builtin_assignconv_identity_widening_p (lhs_type, rhs_type)
+ tree lhs_type, rhs_type;
{
- if (TREE_CODE (source) == POINTER_TYPE)
- source = TREE_TYPE (source);
- if (TREE_CODE (dest) == POINTER_TYPE)
- dest = TREE_TYPE (dest);
+ /* 5.1.1: This is the identity conversion part. */
+ if (lhs_type == rhs_type)
+ return 1;
- if (TREE_CODE (source) == RECORD_TYPE && TREE_CODE (dest) == RECORD_TYPE)
- return valid_ref_assignconv_cast_p (source, dest, 1);
+ /* Reject non primitive types */
+ if (!JPRIMITIVE_TYPE_P (lhs_type) || !JPRIMITIVE_TYPE_P (rhs_type))
+ return 0;
- else if (JNUMERIC_TYPE_P (source) && JNUMERIC_TYPE_P (dest))
+ /* 5.1.2: widening primitive conversion. byte, even if it's smaller
+ than a char can't be converted into a char. Short can't too, but
+ the < test below takes care of that */
+ if (lhs_type == char_type_node && rhs_type == byte_type_node)
+ return 0;
+
+ /* Accept all promoted type here. Note, we can't use <= in the test
+ below, because we still need to bounce out assignments of short
+ to char and the likes */
+ if (lhs_type == int_type_node
+ && (rhs_type == promoted_byte_type_node
+ || rhs_type == promoted_short_type_node
+ || rhs_type == promoted_char_type_node
+ || rhs_type == promoted_boolean_type_node))
+ return 1;
+
+ /* From here, an integral is widened if its precision is smaller
+ than the precision of the LHS or if the LHS is a floating point
+ type, or the RHS is a float and the RHS a double. */
+ if ((JINTEGRAL_TYPE_P (rhs_type) && JINTEGRAL_TYPE_P (lhs_type)
+ && (TYPE_PRECISION (rhs_type) < TYPE_PRECISION (lhs_type)))
+ || (JINTEGRAL_TYPE_P (rhs_type) && JFLOAT_TYPE_P (lhs_type))
+ || (rhs_type == float_type_node && lhs_type == double_type_node))
return 1;
return 0;
@@ -9225,6 +11413,11 @@ valid_ref_assignconv_cast_p (source, dest, cast)
tree dest;
int cast;
{
+ /* SOURCE or DEST might be null if not from a declared entity. */
+ if (!source || !dest)
+ return 0;
+ if (JNULLP_TYPE_P (source))
+ return 1;
if (TREE_CODE (source) == POINTER_TYPE)
source = TREE_TYPE (source);
if (TREE_CODE (dest) == POINTER_TYPE)
@@ -9234,7 +11427,7 @@ valid_ref_assignconv_cast_p (source, dest, cast)
{
if (TYPE_CLASS_P (dest))
return source == dest || inherits_from_p (source, dest)
- || cast && inherits_from_p (dest, source);
+ || (cast && inherits_from_p (dest, source));
if (TYPE_INTERFACE_P (dest))
{
/* If doing a cast and SOURCE is final, the operation is
@@ -9257,7 +11450,7 @@ valid_ref_assignconv_cast_p (source, dest, cast)
return dest == object_type_node;
/* We're doing a cast. The cast is always valid is class
DEST is not final, otherwise, DEST must implement SOURCE */
- else if (!CLASS_FINAL (TYPE_NAME (source)))
+ else if (!CLASS_FINAL (TYPE_NAME (dest)))
return 1;
else
return interface_of_p (source, dest);
@@ -9271,7 +11464,7 @@ valid_ref_assignconv_cast_p (source, dest, cast)
{
tree method_source, method_dest;
tree source_type;
- tree source_sig, dest_sig;
+ tree source_sig;
tree source_name;
for (method_source = TYPE_METHODS (source); method_source;
method_source = TREE_CHAIN (method_source))
@@ -9300,13 +11493,18 @@ valid_ref_assignconv_cast_p (source, dest, cast)
{
if (TYPE_CLASS_P (dest))
return dest == object_type_node;
+ /* Can't cast an array to an interface unless the interface is
+ java.lang.Cloneable */
if (TYPE_INTERFACE_P (dest))
- return 0; /* Install test on Clonable. FIXME */
+ return (DECL_NAME (TYPE_NAME (dest)) == java_lang_cloneable ? 1 : 0);
else /* Arrays */
{
tree source_element_type = TYPE_ARRAY_ELEMENT (source);
tree dest_element_type = TYPE_ARRAY_ELEMENT (dest);
+ /* In case of severe errors, they turn out null */
+ if (!dest_element_type || !source_element_type)
+ return 0;
if (source_element_type == dest_element_type)
return 1;
return valid_ref_assignconv_cast_p (source_element_type,
@@ -9317,6 +11515,53 @@ valid_ref_assignconv_cast_p (source, dest, cast)
return 0;
}
+static int
+valid_cast_to_p (source, dest)
+ tree source;
+ tree dest;
+{
+ if (TREE_CODE (source) == POINTER_TYPE)
+ source = TREE_TYPE (source);
+ if (TREE_CODE (dest) == POINTER_TYPE)
+ dest = TREE_TYPE (dest);
+
+ if (TREE_CODE (source) == RECORD_TYPE && TREE_CODE (dest) == RECORD_TYPE)
+ return valid_ref_assignconv_cast_p (source, dest, 1);
+
+ else if (JNUMERIC_TYPE_P (source) && JNUMERIC_TYPE_P (dest))
+ return 1;
+
+ return 0;
+}
+
+/* Method invocation conversion test. Return 1 if type SOURCE can be
+ converted to type DEST through the methond invocation conversion
+ process (5.3) */
+
+static tree
+do_unary_numeric_promotion (arg)
+ tree arg;
+{
+ tree type = TREE_TYPE (arg);
+ if (TREE_CODE (type) == INTEGER_TYPE ? TYPE_PRECISION (type) < 32
+ : TREE_CODE (type) == CHAR_TYPE)
+ arg = convert (int_type_node, arg);
+ return arg;
+}
+
+/* Return a non zero value if SOURCE can be converted into DEST using
+ the method invocation conversion rule (5.3). */
+static int
+valid_method_invocation_conversion_p (dest, source)
+ tree dest, source;
+{
+ return ((JPRIMITIVE_TYPE_P (source) && JPRIMITIVE_TYPE_P (dest)
+ && valid_builtin_assignconv_identity_widening_p (dest, source))
+ || ((JREFERENCE_TYPE_P (source) || JNULLP_TYPE_P (source))
+ && (JREFERENCE_TYPE_P (dest) || JNULLP_TYPE_P (dest))
+ && valid_ref_assignconv_cast_p (source, dest, 0)));
+}
+
/* Build an incomplete binop expression. */
static tree
@@ -9325,15 +11570,7 @@ build_binop (op, op_location, op1, op2)
int op_location;
tree op1, op2;
{
- tree wfl;
-
- /* URSHIFT_EXPR is not part of what GCC understands, we can't directly build
- a node with it */
- tree binop =
- build ((op == URSHIFT_EXPR ? RSHIFT_EXPR : op), NULL_TREE, op1, op2);
- if (op == URSHIFT_EXPR)
- TREE_SET_CODE (binop, op);
-
+ tree binop = build (op, NULL_TREE, op1, op2);
TREE_SIDE_EFFECTS (binop) = 1;
/* Store the location of the operator, for better error report. The
string of the operator will be rebuild based on the OP value. */
@@ -9379,7 +11616,7 @@ operator_string (node)
case GE_EXPR: BUILD_OPERATOR_STRING (">=");
case LT_EXPR: BUILD_OPERATOR_STRING ("<");
case LE_EXPR: BUILD_OPERATOR_STRING ("<=");
- case JAVA_UNARY_PLUS_EXPR: BUILD_OPERATOR_STRING ("+");
+ case UNARY_PLUS_EXPR: BUILD_OPERATOR_STRING ("+");
case NEGATE_EXPR: BUILD_OPERATOR_STRING ("-");
case TRUTH_NOT_EXPR: BUILD_OPERATOR_STRING ("!");
case BIT_NOT_EXPR: BUILD_OPERATOR_STRING ("~");
@@ -9413,28 +11650,13 @@ patch_binop (node, wfl_op1, wfl_op2)
tree op2_type = TREE_TYPE (op2);
tree prom_type;
int code = TREE_CODE (node);
+
/* If 1, tell the routine that we have to return error_mark_node
after checking for the initialization of the RHS */
int error_found = 0;
- /* Figure what is going to be checked first for initialization prior
- its use. If NODE is part of a compound assignment, we check the
- second operand first, otherwise the first one first. We also
- initialize the matching WFL for the error report. `cfi' stands
- for Check For Initialization */
- tree cfi = (COMPOUND_ASSIGN_P (node) ? op2 : op1);
- tree cfi_wfl = (COMPOUND_ASSIGN_P (node) ? wfl_op2 : wfl_op1);
-
EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
- /* Check initialization of LHS first. We then silence further error
- message if the variable wasn't initialized */
- if (not_initialized_as_it_should_p (cfi))
- {
- ERROR_VARIABLE_NOT_INITIALIZED (cfi_wfl, DECL_NAME (cfi));
- INITIALIZED_P (op1) = 1;
- }
-
switch (code)
{
/* 15.16 Multiplicative operators */
@@ -9455,16 +11677,36 @@ patch_binop (node, wfl_op1, wfl_op2)
/* Change the division operator if necessary */
if (code == RDIV_EXPR && TREE_CODE (prom_type) == INTEGER_TYPE)
TREE_SET_CODE (node, TRUNC_DIV_EXPR);
- /* This one is more complicated. FLOATs are processed by a function
- call to soft_fmod. */
+
+ /* This one is more complicated. FLOATs are processed by a
+ function call to soft_fmod. Duplicate the value of the
+ COMPOUND_ASSIGN_P flag. */
if (code == TRUNC_MOD_EXPR)
- return build_java_binop (TRUNC_MOD_EXPR, prom_type, op1, op2);
+ {
+ tree mod = build_java_binop (TRUNC_MOD_EXPR, prom_type, op1, op2);
+ COMPOUND_ASSIGN_P (mod) = COMPOUND_ASSIGN_P (node);
+ TREE_SIDE_EFFECTS (mod)
+ = TREE_SIDE_EFFECTS (op1) | TREE_SIDE_EFFECTS (op2);
+ return mod;
+ }
break;
/* 15.17 Additive Operators */
case PLUS_EXPR: /* 15.17.1 String Concatenation Operator + */
- if (JSTRING_TYPE_P (op1_type) || JSTRING_TYPE_P (op2_type))
- fatal ("operator `+' non implemented on String - patch_binop");
+
+ /* Operation is valid if either one argument is a string
+ constant, a String object or a StringBuffer crafted for the
+ purpose of the a previous usage of the String concatenation
+ operator */
+
+ if (TREE_CODE (op1) == STRING_CST
+ || TREE_CODE (op2) == STRING_CST
+ || JSTRING_TYPE_P (op1_type)
+ || JSTRING_TYPE_P (op2_type)
+ || IS_CRAFTED_STRING_BUFFER_P (op1)
+ || IS_CRAFTED_STRING_BUFFER_P (op2))
+ return build_string_concatenation (op1, op2);
+
case MINUS_EXPR: /* 15.17.2 Additive Operators (+ and -) for
Numeric Types */
if (!JPRIMITIVE_TYPE_P (op1_type) || !JPRIMITIVE_TYPE_P (op2_type))
@@ -9495,7 +11737,7 @@ patch_binop (node, wfl_op1, wfl_op2)
"shift distance from `%s' to integral" :
"Incompatible type for `%s'. Can't convert shift distance from "
"`%s' to integral"),
- operator_string (node), lang_printable_name (op2_type));
+ operator_string (node), lang_printable_name (op2_type, 0));
TREE_TYPE (node) = error_mark_node;
error_found = 1;
break;
@@ -9503,8 +11745,8 @@ patch_binop (node, wfl_op1, wfl_op2)
/* Unary numeric promotion (5.6.1) is performed on each operand
separatly */
- op1 = convert (promote_type (op1_type), op1);
- op2 = convert (promote_type (op2_type), op2);
+ op1 = do_unary_numeric_promotion (op1);
+ op2 = do_unary_numeric_promotion (op2);
/* The type of the shift expression is the type of the promoted
type of the left-hand operand */
@@ -9519,13 +11761,86 @@ patch_binop (node, wfl_op1, wfl_op2)
build_int_2 (0x3f, 0)));
/* The >>> operator is a >> operating on unsigned quantities */
- if (code == URSHIFT_EXPR)
+ if (code == URSHIFT_EXPR && ! flag_emit_class_files)
{
- op1 = convert (unsigned_type (prom_type), op1);
+ tree to_return;
+ tree utype = unsigned_type (prom_type);
+ op1 = convert (utype, op1);
TREE_SET_CODE (node, RSHIFT_EXPR);
+ TREE_OPERAND (node, 0) = op1;
+ TREE_OPERAND (node, 1) = op2;
+ TREE_TYPE (node) = utype;
+ to_return = convert (prom_type, node);
+ /* Copy the original value of the COMPOUND_ASSIGN_P flag */
+ COMPOUND_ASSIGN_P (to_return) = COMPOUND_ASSIGN_P (node);
+ TREE_SIDE_EFFECTS (to_return)
+ = TREE_SIDE_EFFECTS (op1) | TREE_SIDE_EFFECTS (op2);
+ return to_return;
}
break;
+
+ /* 15.19.1 Type Comparison Operator instaceof */
+ case INSTANCEOF_EXPR:
+
+ TREE_TYPE (node) = boolean_type_node;
+
+ if (!(op2_type = resolve_type_during_patch (op2)))
+ return error_mark_node;
+
+ /* The first operand must be a reference type or the null type */
+ if (!JREFERENCE_TYPE_P (op1_type) && op1 != null_pointer_node)
+ error_found = 1; /* Error reported further below */
+
+ /* The second operand must be a reference type */
+ if (!JREFERENCE_TYPE_P (op2_type))
+ {
+ SET_WFL_OPERATOR (wfl_operator, node, wfl_op2);
+ parse_error_context
+ (wfl_operator, "Invalid argument `%s' for `instanceof'",
+ lang_printable_name (op2_type, 0));
+ error_found = 1;
+ }
+
+ if (!error_found && valid_ref_assignconv_cast_p (op1_type, op2_type, 1))
+ {
+ /* If the first operand is null, the result is always false */
+ if (op1 == null_pointer_node)
+ return boolean_false_node;
+ else if (flag_emit_class_files)
+ {
+ TREE_OPERAND (node, 1) = op2_type;
+ TREE_SIDE_EFFECTS (node) = TREE_SIDE_EFFECTS (op1);
+ return node;
+ }
+ /* Otherwise we have to invoke instance of to figure it out */
+ else
+ {
+ tree call =
+ build (CALL_EXPR, boolean_type_node,
+ build_address_of (soft_instanceof_node),
+ tree_cons
+ (NULL_TREE, op1,
+ build_tree_list (NULL_TREE,
+ build_class_ref (op2_type))),
+ NULL_TREE);
+ TREE_SIDE_EFFECTS (call) = TREE_SIDE_EFFECTS (op1);
+ return call;
+ }
+ }
+ /* There is no way the expression operand can be an instance of
+ the type operand. This is a compile time error. */
+ else
+ {
+ char *t1 = strdup (lang_printable_name (op1_type, 0));
+ SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
+ parse_error_context
+ (wfl_operator, "Impossible for `%s' to be instance of `%s'",
+ t1, lang_printable_name (op2_type, 0));
+ free (t1);
+ error_found = 1;
+ }
+ break;
/* 15.21 Bitwise and Logical Operators */
case BIT_AND_EXPR:
@@ -9601,7 +11916,7 @@ patch_binop (node, wfl_op1, wfl_op2)
case NE_EXPR:
/* 15.20.1 Numerical Equality Operators == and != */
/* Binary numeric promotion is performed on the operands */
- if (JPRIMITIVE_TYPE_P (op1_type) && JPRIMITIVE_TYPE_P (op2_type))
+ if (JNUMERIC_TYPE_P (op1_type) && JNUMERIC_TYPE_P (op2_type))
binary_numeric_promotion (op1_type, op2_type, &op1, &op2);
/* 15.20.2 Boolean Equality Operators == and != */
@@ -9610,13 +11925,14 @@ patch_binop (node, wfl_op1, wfl_op2)
; /* Nothing to do here */
/* 15.20.3 Reference Equality Operators == and != */
- /* Types have to be either references or the null type */
- else if ((op1 == null_pointer_node || op2 == null_pointer_node
- || JREFERENCE_TYPE_P (op1_type)
- || JREFERENCE_TYPE_P (op2_type))
- && ((op1_type == op2_type)
- /* The should use a can_cast_to_p() */
- ))
+ /* Types have to be either references or the null type. If
+ they're references, it must be possible to convert either
+ type to the other by casting conversion. */
+ else if (op1 == null_pointer_node || op2 == null_pointer_node
+ || (JREFERENCE_TYPE_P (op1_type) && JREFERENCE_TYPE_P (op2_type)
+ && (valid_ref_assignconv_cast_p (op1_type, op2_type, 1)
+ || valid_ref_assignconv_cast_p (op2_type,
+ op1_type, 1))))
; /* Nothing to do here */
/* Else we have an error figure what can't be converted into
@@ -9624,11 +11940,11 @@ patch_binop (node, wfl_op1, wfl_op2)
else
{
char *t1;
- t1 = strdup ((char *)lang_printable_name (op1_type));
+ t1 = strdup (lang_printable_name (op1_type, 0));
parse_error_context
(wfl_operator, "Incompatible type for `%s'. Can't convert `%s' "
"to `%s'", operator_string (node), t1,
- lang_printable_name (op2_type));
+ lang_printable_name (op2_type, 0));
free (t1);
TREE_TYPE (node) = boolean_type_node;
error_found = 1;
@@ -9638,29 +11954,241 @@ patch_binop (node, wfl_op1, wfl_op2)
break;
}
- /* Then check the initialization of the RHS. We don't do that if
- we're dealing with a node that is part of a compound
- assignment. We then silence further error message if the variable
- wasn't initialized */
- if (not_initialized_as_it_should_p (op2) && !COMPOUND_ASSIGN_P (node))
- {
- ERROR_VARIABLE_NOT_INITIALIZED (wfl_op2, DECL_NAME (op2));
- INITIALIZED_P (op2) = 1;
- }
-
if (error_found)
return error_mark_node;
TREE_OPERAND (node, 0) = op1;
TREE_OPERAND (node, 1) = op2;
TREE_TYPE (node) = prom_type;
- return fold (node);
+ TREE_SIDE_EFFECTS (node) = TREE_SIDE_EFFECTS (op1) | TREE_SIDE_EFFECTS (op2);
+
+ /* fold does not respect side-effect order as required for Java but not C. */
+ if (! TREE_SIDE_EFFECTS (node))
+ node = fold (node);
+ return node;
+}
+
+/* Concatenate the STRING_CST CSTE and STRING. When AFTER is a non
+ zero value, the value of CSTE comes after the valude of STRING */
+
+static tree
+do_merge_string_cste (cste, string, string_len, after)
+ tree cste;
+ char *string;
+ int string_len, after;
+{
+ int len = TREE_STRING_LENGTH (cste) + string_len;
+ char *old = TREE_STRING_POINTER (cste);
+ TREE_STRING_LENGTH (cste) = len;
+ TREE_STRING_POINTER (cste) = obstack_alloc (expression_obstack, len+1);
+ if (after)
+ {
+ strcpy (TREE_STRING_POINTER (cste), string);
+ strcat (TREE_STRING_POINTER (cste), old);
+ }
+ else
+ {
+ strcpy (TREE_STRING_POINTER (cste), old);
+ strcat (TREE_STRING_POINTER (cste), string);
+ }
+ return cste;
+}
+
+/* Tries to merge OP1 (a STRING_CST) and OP2 (if suitable). Return a
+ new STRING_CST on success, NULL_TREE on failure */
+
+static tree
+merge_string_cste (op1, op2, after)
+ tree op1, op2;
+ int after;
+{
+ /* Handle two string constants right away */
+ if (TREE_CODE (op2) == STRING_CST)
+ return do_merge_string_cste (op1, TREE_STRING_POINTER (op2),
+ TREE_STRING_LENGTH (op2), after);
+
+ /* Reasonable integer constant can be treated right away */
+ if (TREE_CODE (op2) == INTEGER_CST && !TREE_CONSTANT_OVERFLOW (op2))
+ {
+ static char *boolean_true = "true";
+ static char *boolean_false = "false";
+ static char *null_pointer = "null";
+ char ch[3];
+ char *string;
+
+ if (op2 == boolean_true_node)
+ string = boolean_true;
+ else if (op2 == boolean_false_node)
+ string = boolean_false;
+ else if (op2 == null_pointer_node)
+ string = null_pointer;
+ else if (TREE_TYPE (op2) == char_type_node)
+ {
+ ch[0] = (char )TREE_INT_CST_LOW (op2);
+ ch[1] = '\0';
+ string = ch;
+ }
+ else
+ string = print_int_node (op2);
+
+ return do_merge_string_cste (op1, string, strlen (string), after);
+ }
+ return NULL_TREE;
+}
+
+/* Tries to statically concatenate OP1 and OP2 if possible. Either one
+ has to be a STRING_CST and the other part must be a STRING_CST or a
+ INTEGRAL constant. Return a new STRING_CST if the operation
+ succeed, NULL_TREE otherwise.
+
+ If the case we want to optimize for space, we might want to return
+ NULL_TREE for each invocation of this routine. FIXME */
+
+static tree
+string_constant_concatenation (op1, op2)
+ tree op1, op2;
+{
+ if (TREE_CODE (op1) == STRING_CST || (TREE_CODE (op2) == STRING_CST))
+ {
+ tree string, rest;
+ int invert;
+
+ string = (TREE_CODE (op1) == STRING_CST ? op1 : op2);
+ rest = (string == op1 ? op2 : op1);
+ invert = (string == op1 ? 0 : 1 );
+
+ /* Walk REST, only if it looks reasonable */
+ if (TREE_CODE (rest) != STRING_CST
+ && !IS_CRAFTED_STRING_BUFFER_P (rest)
+ && !JSTRING_TYPE_P (TREE_TYPE (rest))
+ && TREE_CODE (rest) == EXPR_WITH_FILE_LOCATION)
+ {
+ rest = java_complete_tree (rest);
+ if (rest == error_mark_node)
+ return error_mark_node;
+ rest = fold (rest);
+ }
+ return merge_string_cste (string, rest, invert);
+ }
+ return NULL_TREE;
+}
+
+/* Implement the `+' operator. Does static optimization if possible,
+ otherwise create (if necessary) and append elements to a
+ StringBuffer. The StringBuffer will be carried around until it is
+ used for a function call or an assignment. Then toString() will be
+ called on it to turn it into a String object. */
+
+static tree
+build_string_concatenation (op1, op2)
+ tree op1, op2;
+{
+ tree result;
+ int side_effects = TREE_SIDE_EFFECTS (op1) | TREE_SIDE_EFFECTS (op2);
+
+ /* Try to do some static optimization */
+ if ((result = string_constant_concatenation (op1, op2)))
+ return result;
+
+ /* Discard empty strings on either side of the expression */
+ if (TREE_CODE (op1) == STRING_CST && TREE_STRING_LENGTH (op1) == 0)
+ {
+ op1 = op2;
+ op2 = NULL_TREE;
+ }
+ else if (TREE_CODE (op2) == STRING_CST && TREE_STRING_LENGTH (op2) == 0)
+ op2 = NULL_TREE;
+
+ /* If operands are string constant, turn then into object references */
+ if (TREE_CODE (op1) == STRING_CST)
+ op1 = patch_string_cst (op1);
+ if (op2 && TREE_CODE (op2) == STRING_CST)
+ op2 = patch_string_cst (op2);
+
+ /* If either one of the constant is null and the other non null
+ operand is a String object, return it. */
+ if (JSTRING_TYPE_P (TREE_TYPE (op1)) && !op2)
+ return op1;
+
+ /* If OP1 isn't already a StringBuffer, create and
+ initialize a new one */
+ if (!IS_CRAFTED_STRING_BUFFER_P (op1))
+ {
+ /* Two solutions here:
+ 1) OP1 is a string reference, we call new StringBuffer(OP1)
+ 2) OP1 is something else, we call new StringBuffer().append(OP1). */
+ if (JSTRING_TYPE_P (TREE_TYPE (op1)))
+ op1 = BUILD_STRING_BUFFER (op1);
+ else
+ {
+ tree aNew = BUILD_STRING_BUFFER (NULL_TREE);
+ op1 = make_qualified_primary (aNew, BUILD_APPEND (op1), 0);
+ }
+ }
+
+ if (op2)
+ {
+ /* OP1 is no longer the last node holding a crafted StringBuffer */
+ IS_CRAFTED_STRING_BUFFER_P (op1) = 0;
+ /* Create a node for `{new...,xxx}.append (op2)' */
+ if (op2)
+ op1 = make_qualified_primary (op1, BUILD_APPEND (op2), 0);
+ }
+
+ /* Mark the last node holding a crafted StringBuffer */
+ IS_CRAFTED_STRING_BUFFER_P (op1) = 1;
+
+ TREE_SIDE_EFFECTS (op1) = side_effects;
+ return op1;
}
-/* Build an incomplete unary operator expression. Unary `+' node is
- build as a CONV_EXPR, even though its tree code is overridden by a
- JAVA_UNARY_PLUS_EXPR that isn't a tree code, to differentiate it during
- the walk. */
+/* Patch the string node NODE. NODE can be a STRING_CST of a crafted
+ StringBuffer. If no string were found to be patched, return
+ NULL. */
+
+static tree
+patch_string (node)
+ tree node;
+{
+ if (node == error_mark_node)
+ return error_mark_node;
+ if (TREE_CODE (node) == STRING_CST)
+ return patch_string_cst (node);
+ else if (IS_CRAFTED_STRING_BUFFER_P (node))
+ {
+ int saved = ctxp->explicit_constructor_p;
+ tree invoke = build_method_invocation (wfl_to_string, NULL_TREE);
+ tree ret;
+ /* Temporary disable forbid the use of `this'. */
+ ctxp->explicit_constructor_p = 0;
+ ret = java_complete_tree (make_qualified_primary (node, invoke, 0));
+ /* Restore it at its previous value */
+ ctxp->explicit_constructor_p = saved;
+ return ret;
+ }
+ return NULL_TREE;
+}
+
+/* Build the internal representation of a string constant. */
+
+static tree
+patch_string_cst (node)
+ tree node;
+{
+ int location;
+ if (! flag_emit_class_files)
+ {
+ push_obstacks (&permanent_obstack, &permanent_obstack);
+ node = get_identifier (TREE_STRING_POINTER (node));
+ location = alloc_name_constant (CONSTANT_String, node);
+ node = build_ref_from_constant_pool (location);
+ }
+ TREE_TYPE (node) = promote_type (string_type_node);
+ TREE_CONSTANT (node) = 1;
+ return node;
+}
+
+/* Build an incomplete unary operator expression. */
static tree
build_unaryop (op_token, op_location, op1)
@@ -9671,7 +12199,7 @@ build_unaryop (op_token, op_location, op1)
tree unaryop;
switch (op_token)
{
- case PLUS_TK: op = CONVERT_EXPR; break;
+ case PLUS_TK: op = UNARY_PLUS_EXPR; break;
case MINUS_TK: op = NEGATE_EXPR; break;
case NEG_TK: op = TRUTH_NOT_EXPR; break;
case NOT_TK: op = BIT_NOT_EXPR; break;
@@ -9680,9 +12208,6 @@ build_unaryop (op_token, op_location, op1)
}
unaryop = build1 (op, NULL_TREE, op1);
- if (op_token == PLUS_TK)
- TREE_SET_CODE (unaryop, JAVA_UNARY_PLUS_EXPR);
-
TREE_SIDE_EFFECTS (unaryop) = 1;
/* Store the location of the operator, for better error report. The
string of the operator will be rebuild based on the OP value. */
@@ -9739,7 +12264,7 @@ patch_unaryop (node, wfl_op)
{
tree op = TREE_OPERAND (node, 0);
tree op_type = TREE_TYPE (op);
- tree prom_type, value;
+ tree prom_type, value, decl;
int code = TREE_CODE (node);
int error_found = 0;
@@ -9755,21 +12280,27 @@ patch_unaryop (node, wfl_op)
case PREINCREMENT_EXPR:
/* 15.14.2 Prefix Decrement Operator -- */
case PREDECREMENT_EXPR:
- if (!DECL_P (op))
- {
- parse_error_context (wfl_operator, "Invalid argument to `%s'",
- operator_string (node));
- TREE_TYPE (node) = error_mark_node;
- error_found = 1;
- }
- else if (FIELD_FINAL (op))
+ decl = strip_out_static_field_access_decl (op);
+ if (!JDECL_P (decl)
+ && !((TREE_CODE (decl) == INDIRECT_REF
+ || TREE_CODE (decl) == COMPONENT_REF)
+ && JPRIMITIVE_TYPE_P (TREE_TYPE (decl))))
{
- parse_error_context
- (wfl_op, "Can't assign a value to the final variable `%s'",
- IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl_op)));
+ tree lvalue;
+ /* Before screaming, check that we're not in fact trying to
+ increment a optimized static final access, in which case
+ we issue an different error message. */
+ if (!(TREE_CODE (wfl_op) == EXPR_WITH_FILE_LOCATION
+ && resolve_expression_name (wfl_op, &lvalue)
+ && check_final_assignment (lvalue, wfl_op)))
+ parse_error_context (wfl_operator, "Invalid argument to `%s'",
+ operator_string (node));
TREE_TYPE (node) = error_mark_node;
error_found = 1;
}
+ else if (check_final_assignment (op, wfl_op))
+ error_found = 1;
+
/* From now on, we know that op if a variable and that it has a
valid wfl. We use wfl_op to locate errors related to the
++/-- operand. */
@@ -9777,24 +12308,27 @@ patch_unaryop (node, wfl_op)
{
parse_error_context
(wfl_op, "Invalid argument type `%s' to `%s'",
- lang_printable_name (op_type), operator_string (node));
+ lang_printable_name (op_type, 0), operator_string (node));
TREE_TYPE (node) = error_mark_node;
error_found = 1;
}
else
{
- /* Before the addition, binary numeric promotion if performed on
+ /* Before the addition, binary numeric promotion is performed on
both operands */
- value = integer_one_node;
- prom_type = binary_numeric_promotion (op_type, TREE_TYPE (value),
- &op, &value);
- /* And write the promoted increment back */
+ value = build_int_2 (1, 0);
+ TREE_TYPE (node) =
+ binary_numeric_promotion (op_type, TREE_TYPE (value), &op, &value);
+ /* And write the promoted incremented and increment */
+ TREE_OPERAND (node, 0) = op;
TREE_OPERAND (node, 1) = value;
+ /* Convert the overall back into its original type. */
+ return fold (convert (op_type, node));
}
break;
/* 15.14.3 Unary Plus Operator + */
- case JAVA_UNARY_PLUS_EXPR:
+ case UNARY_PLUS_EXPR:
/* 15.14.4 Unary Minus Operator - */
case NEGATE_EXPR:
if (!JNUMERIC_TYPE_P (op_type))
@@ -9806,10 +12340,10 @@ patch_unaryop (node, wfl_op)
/* Unary numeric promotion is performed on operand */
else
{
- prom_type = promote_type (op_type);
- op = convert (prom_type, op);
- if (code == JAVA_UNARY_PLUS_EXPR)
- node = op;
+ op = do_unary_numeric_promotion (op);
+ prom_type = TREE_TYPE (op);
+ if (code == UNARY_PLUS_EXPR)
+ return fold (op);
}
break;
@@ -9823,8 +12357,8 @@ patch_unaryop (node, wfl_op)
}
else
{
- prom_type = promote_type (op_type);
- op = convert (prom_type, op);
+ op = do_unary_numeric_promotion (op);
+ prom_type = TREE_TYPE (op);
}
break;
@@ -9833,6 +12367,8 @@ patch_unaryop (node, wfl_op)
if (TREE_CODE (op_type) != BOOLEAN_TYPE)
{
ERROR_CANT_CONVERT_TO_BOOLEAN (wfl_operator, node, op_type);
+ /* But the type is known. We will report an error if further
+ attempt of a assignment is made with this rhs */
TREE_TYPE (node) = boolean_type_node;
error_found = 1;
}
@@ -9842,32 +12378,33 @@ patch_unaryop (node, wfl_op)
/* 15.15 Cast Expression */
case CONVERT_EXPR:
- value = patch_cast (node, wfl_op, wfl_operator);
+ value = patch_cast (node, wfl_operator);
if (value == error_mark_node)
{
+ /* If this cast is part of an assignment, we tell the code
+ that deals with it not to complain about a mismatch,
+ because things have been cast, anyways */
TREE_TYPE (node) = error_mark_node;
error_found = 1;
}
else
- node = value;
+ {
+ value = fold (value);
+ TREE_SIDE_EFFECTS (value) = TREE_SIDE_EFFECTS (op);
+ return value;
+ }
break;
}
- /* Check variable initialization */
- if (not_initialized_as_it_should_p (op))
- {
- ERROR_VARIABLE_NOT_INITIALIZED (wfl_op, DECL_NAME (op));
- INITIALIZED_P (op) = 1;
- }
-
if (error_found)
return error_mark_node;
- /* In the case of JAVA_UNARY_PLUS_EXPR, we replaced NODE by a new one */
- else if (code != JAVA_UNARY_PLUS_EXPR && code != CONVERT_EXPR)
- {
- TREE_OPERAND (node, 0) = op;
- TREE_TYPE (node) = prom_type;
- }
+
+ /* There are cases where node has been replaced by something else
+ and we don't end up returning here: UNARY_PLUS_EXPR,
+ CONVERT_EXPR, {POST,PRE}{INCR,DECR}EMENT_EXPR. */
+ TREE_OPERAND (node, 0) = fold (op);
+ TREE_TYPE (node) = prom_type;
+ TREE_SIDE_EFFECTS (node) = TREE_SIDE_EFFECTS (op);
return fold (node);
}
@@ -9890,7 +12427,10 @@ resolve_type_during_patch (type)
return NULL_TREE;
}
else
- return TREE_TYPE (type_decl);
+ {
+ CLASS_LOADED_P (TREE_TYPE (type_decl)) = 1;
+ return TREE_TYPE (type_decl);
+ }
}
return type;
}
@@ -9898,9 +12438,8 @@ resolve_type_during_patch (type)
found. Otherwise NODE or something meant to replace it is returned. */
static tree
-patch_cast (node, wfl_op, wfl_operator)
+patch_cast (node, wfl_operator)
tree node;
- tree wfl_op;
tree wfl_operator;
{
tree op = TREE_OPERAND (node, 0);
@@ -9920,12 +12459,25 @@ patch_cast (node, wfl_op, wfl_operator)
if (cast_type == op_type)
return node;
+ /* float and double type are converted to the original type main
+ variant and then to the target type. */
+ if (JFLOAT_TYPE_P (op_type) && TREE_CODE (cast_type) == CHAR_TYPE)
+ op = convert (integer_type_node, op);
+
/* Try widening/narowwing convertion. Potentially, things need
to be worked out in gcc so we implement the extreme cases
correctly. fold_convert() needs to be fixed. */
return convert (cast_type, op);
}
+ /* It's also valid to cast a boolean into a boolean */
+ if (op_type == boolean_type_node && cast_type == boolean_type_node)
+ return node;
+
+ /* null can be casted to references */
+ if (op == null_pointer_node && JREFERENCE_TYPE_P (cast_type))
+ return build_null_of_type (cast_type);
+
/* The remaining legal casts involve conversion between reference
types. Check for their compile time correctness. */
if (JREFERENCE_TYPE_P (op_type) && JREFERENCE_TYPE_P (cast_type)
@@ -9937,7 +12489,16 @@ patch_cast (node, wfl_op, wfl_operator)
conversion (5.2) */
if (valid_ref_assignconv_cast_p (op_type, cast_type, 0))
- return node;
+ {
+ TREE_SET_CODE (node, NOP_EXPR);
+ return node;
+ }
+
+ if (flag_emit_class_files)
+ {
+ TREE_SET_CODE (node, CONVERT_EXPR);
+ return node;
+ }
/* The cast requires a run-time check */
return build (CALL_EXPR, promote_type (cast_type),
@@ -9948,13 +12509,24 @@ patch_cast (node, wfl_op, wfl_operator)
}
/* Any other casts are proven incorrect at compile time */
- t1 = strdup ((char *)lang_printable_name (op_type));
+ t1 = strdup (lang_printable_name (op_type, 0));
parse_error_context (wfl_operator, "Invalid cast from `%s' to `%s'",
- t1, lang_printable_name (cast_type));
+ t1, lang_printable_name (cast_type, 0));
free (t1);
return error_mark_node;
}
+/* Build a null constant and give it the type TYPE. */
+
+static tree
+build_null_of_type (type)
+ tree type;
+{
+ tree node = build_int_2 (0, 0);
+ TREE_TYPE (node) = promote_type (type);
+ return node;
+}
+
/* Build an ARRAY_REF incomplete tree node. Note that operand 1 isn't
a list of indices. */
static tree
@@ -9970,26 +12542,17 @@ build_array_ref (location, array, index)
/* 15.12 Array Access Expression */
static tree
-patch_array_ref (node, wfl_array, wfl_index)
- tree node, wfl_array, wfl_index;
+patch_array_ref (node)
+ tree node;
{
tree array = TREE_OPERAND (node, 0);
tree array_type = TREE_TYPE (array);
tree index = TREE_OPERAND (node, 1);
tree index_type = TREE_TYPE (index);
- tree promoted_index_type;
int error_found = 0;
EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
- if (not_initialized_as_it_should_p (array))
- {
- ERROR_VARIABLE_NOT_INITIALIZED (wfl_array, DECL_NAME (array));
- INITIALIZED_P (array) = 1;
- }
- if (! flag_emit_class_files)
- array = save_expr (array);
-
if (TREE_CODE (array_type) == POINTER_TYPE)
array_type = TREE_TYPE (array_type);
@@ -9998,47 +12561,48 @@ patch_array_ref (node, wfl_array, wfl_index)
{
parse_error_context
(wfl_operator, "`[]' can only be applied to arrays. It can't be "
- "applied to `%s'", lang_printable_name (array_type));
+ "applied to `%s'", lang_printable_name (array_type, 0));
TREE_TYPE (node) = error_mark_node;
error_found = 1;
}
/* The array index underdoes unary numeric promotion. The promoted
type must be int */
- promoted_index_type = promote_type (index_type);
- if (promoted_index_type != int_type_node)
+ index = do_unary_numeric_promotion (index);
+ if (TREE_TYPE (index) != int_type_node)
{
- int could_cast = can_cast_to_p (index_type, int_type_node);
+ int could_cast = valid_cast_to_p (index_type, int_type_node);
parse_error_context
(wfl_operator,
(could_cast ? "Incompatible type for `[]'. Explicit cast needed to "
"convert `%s' to `int'" : "Incompatible type for `[]'. "
"Can't convert `%s' to `int'"),
- lang_printable_name (index_type));
+ lang_printable_name (index_type, 0));
TREE_TYPE (node) = error_mark_node;
error_found = 1;
}
- /* Now if the index is a var/parm decl, check on its initialization */
- if (not_initialized_as_it_should_p (index))
- {
- ERROR_VARIABLE_NOT_INITIALIZED (wfl_index, DECL_NAME (index));
- INITIALIZED_P (index) = 1;
- }
-
if (error_found)
return error_mark_node;
- index = convert (promoted_index_type, index);
- if (TREE_CODE (array_type) == RECORD_TYPE)
- array_type = promote_type (TYPE_ARRAY_ELEMENT (array_type));
+ array_type = TYPE_ARRAY_ELEMENT (array_type);
+
if (flag_emit_class_files)
{
- TREE_OPERAND (node, 0)= array;
- TREE_OPERAND (node, 1)= index;
+ TREE_OPERAND (node, 0) = array;
+ TREE_OPERAND (node, 1) = index;
}
else
- node = build_java_arrayaccess (array, array_type, index);
+ {
+ /* The save_expr is for correct evaluation order. It would be cleaner
+ to use force_evaluation_order (see comment there), but that is
+ difficult when we also have to deal with bounds checking. */
+ if (TREE_SIDE_EFFECTS (index))
+ array = save_expr (array);
+ node = build_java_arrayaccess (array, array_type, index);
+ if (TREE_SIDE_EFFECTS (index))
+ node = build (COMPOUND_EXPR, array_type, array, node);
+ }
TREE_TYPE (node) = array_type;
return node;
}
@@ -10052,9 +12616,8 @@ build_newarray_node (type, dims, extra_dims)
int extra_dims;
{
tree node =
- build (CALL_EXPR, NULL_TREE, type, nreverse (dims),
+ build (NEW_ARRAY_EXPR, NULL_TREE, type, nreverse (dims),
build_int_2 (extra_dims, 0));
- TREE_SET_CODE (node, JAVA_NEW_ARRAY_EXPR);
return node;
}
@@ -10068,7 +12631,6 @@ patch_newarray (node)
int error_found = 0;
int ndims = 0;
int xdims = TREE_INT_CST_LOW (TREE_OPERAND (node, 2));
- int total_dims;
/* Dimension types are verified. It's better for the types to be
verified in order. */
@@ -10088,7 +12650,7 @@ patch_newarray (node)
promoted type must be int. */
else
{
- dim = convert (promote_type (TREE_TYPE (dim)), dim);
+ dim = do_unary_numeric_promotion (dim);
if (TREE_TYPE (dim) != int_type_node)
dim_error = 1;
}
@@ -10100,18 +12662,9 @@ patch_newarray (node)
(TREE_PURPOSE (cdim),
"Incompatible type for dimension in array creation expression. "
"%s convert `%s' to `int'",
- (can_cast_to_p (TREE_TYPE (dim), int_type_node) ?
+ (valid_cast_to_p (TREE_TYPE (dim), int_type_node) ?
"Explicit cast needed to" : "Can't"),
- lang_printable_name (TREE_TYPE (dim)));
- error_found = 1;
- }
-
- /* Check for uninitialized variables */
- if (not_initialized_as_it_should_p (dim))
- {
- ERROR_VARIABLE_NOT_INITIALIZED (TREE_PURPOSE (cdim),
- DECL_NAME (dim));
- INITIALIZED_P (dim) = 1;
+ lang_printable_name (TREE_TYPE (dim), 0));
error_found = 1;
}
@@ -10130,68 +12683,199 @@ patch_newarray (node)
return error_mark_node;
}
+ /* Set array_type to the actual (promoted) array type of the result. */
+ if (TREE_CODE (type) == RECORD_TYPE)
+ type = build_pointer_type (type);
+ while (--xdims >= 0)
+ {
+ type = promote_type (build_java_array_type (type, -1));
+ }
+ dims = nreverse (dims);
+ array_type = type;
+ for (cdim = dims; cdim; cdim = TREE_CHAIN (cdim))
+ {
+ type = array_type;
+ array_type = build_java_array_type (type,
+ TREE_CODE (cdim) == INTEGER_CST ?
+ TREE_INT_CST_LOW (cdim) : -1);
+ array_type = promote_type (array_type);
+ }
+ dims = nreverse (dims);
+
/* The node is transformed into a function call. Things are done
differently according to the number of dimensions. If the number
of dimension is equal to 1, then the nature of the base type
(primitive or not) matters. */
- total_dims = xdims + ndims;
- if (total_dims == 1)
+ if (ndims == 1)
+ return build_new_array (type, TREE_VALUE (dims));
+
+ /* Can't reuse what's already written in expr.c because it uses the
+ JVM stack representation. Provide a build_multianewarray. FIXME */
+ return build (CALL_EXPR, array_type,
+ build_address_of (soft_multianewarray_node),
+ tree_cons (NULL_TREE, build_class_ref (TREE_TYPE (array_type)),
+ tree_cons (NULL_TREE,
+ build_int_2 (ndims, 0), dims )),
+ NULL_TREE);
+}
+
+/* 10.6 Array initializer. */
+
+/* Build a wfl for array element that don't have one, so we can
+ pin-point errors. */
+
+static tree
+maybe_build_array_element_wfl (node)
+ tree node;
+{
+ if (TREE_CODE (node) != EXPR_WITH_FILE_LOCATION)
+ return build_expr_wfl (NULL_TREE, ctxp->filename,
+ ctxp->elc.line, ctxp->elc.prev_col);
+ else
+ return NULL_TREE;
+}
+
+/* Build a NEW_ARRAY_INIT that features a CONSTRUCTOR node. This makes
+ identification of initialized arrays easier to detect during walk
+ and expansion. */
+
+static tree
+build_new_array_init (location, values)
+ int location;
+ tree values;
+{
+ tree constructor = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, values);
+ tree to_return = build1 (NEW_ARRAY_INIT, NULL_TREE, constructor);
+ EXPR_WFL_LINECOL (to_return) = location;
+ return to_return;
+}
+
+/* Expand a NEW_ARRAY_INIT node. Return error_mark_node if an error
+ occurred. Otherwise return NODE after having set its type
+ appropriately. */
+
+static tree
+patch_new_array_init (type, node)
+ tree type, node;
+{
+ int error_seen = 0;
+ tree current, element_type;
+ HOST_WIDE_INT length;
+ int all_constant = 1;
+ tree init = TREE_OPERAND (node, 0);
+
+ if (TREE_CODE (type) != POINTER_TYPE || ! TYPE_ARRAY_P (TREE_TYPE (type)))
{
- if (JPRIMITIVE_TYPE_P (type))
+ parse_error_context (node,
+ "Invalid array initializer for non-array type `%s'",
+ lang_printable_name (type, 1));
+ return error_mark_node;
+ }
+ type = TREE_TYPE (type);
+ element_type = TYPE_ARRAY_ELEMENT (type);
+
+ CONSTRUCTOR_ELTS (init) = nreverse (CONSTRUCTOR_ELTS (init));
+
+ for (length = 0, current = CONSTRUCTOR_ELTS (init);
+ current; length++, current = TREE_CHAIN (current))
+ {
+ tree elt = TREE_VALUE (current);
+ if (elt == NULL_TREE || TREE_CODE (elt) != NEW_ARRAY_INIT)
{
- int type_code;
- if (type == boolean_type_node)
- type_code = 4;
- else if (type == char_type_node)
- type_code = 5;
- else if (type == float_type_node)
- type_code = 6;
- else if (type == double_type_node)
- type_code = 7;
- else if (type == byte_type_node)
- type_code = 8;
- else if (type == short_type_node)
- type_code = 9;
- else if (type == int_type_node)
- type_code = 10;
- else if (type == long_type_node)
- type_code = 11;
- else
- fatal ("Can't compute type code - patch_newarray");
- return build_newarray (type_code, TREE_VALUE (dims));
+ error_seen |= array_constructor_check_entry (element_type, current);
+ elt = TREE_VALUE (current);
+ /* When compiling to native code, STRING_CST is converted to
+ INDIRECT_REF, but still with a TREE_CONSTANT flag. */
+ if (! TREE_CONSTANT (elt) || TREE_CODE (elt) == INDIRECT_REF)
+ all_constant = 0;
}
else
- return build_anewarray (type, TREE_VALUE (dims));
+ {
+ TREE_VALUE (current) = patch_new_array_init (element_type, elt);
+ TREE_PURPOSE (current) = NULL_TREE;
+ all_constant = 0;
+ }
+ if (elt && TREE_VALUE (elt) == error_mark_node)
+ error_seen = 1;
+ }
+
+ if (error_seen)
+ return error_mark_node;
+
+ /* Create a new type. We can't reuse the one we have here by
+ patching its dimension because it originally is of dimension -1
+ hence reused by gcc. This would prevent triangular arrays. */
+ type = build_java_array_type (element_type, length);
+ TREE_TYPE (init) = TREE_TYPE (TREE_CHAIN (TREE_CHAIN (TYPE_FIELDS (type))));
+ TREE_TYPE (node) = promote_type (type);
+ TREE_CONSTANT (init) = all_constant;
+ TREE_CONSTANT (node) = all_constant;
+ return node;
+}
+
+/* Verify that one entry of the initializer element list can be
+ assigned to the array base type. Report 1 if an error occurred, 0
+ otherwise. */
+
+static int
+array_constructor_check_entry (type, entry)
+ tree type, entry;
+{
+ char *array_type_string = NULL; /* For error reports */
+ tree value, type_value, new_value, wfl_value, patched;
+ int error_seen = 0;
+
+ new_value = NULL_TREE;
+ wfl_value = TREE_VALUE (entry);
+
+ value = java_complete_tree (TREE_VALUE (entry));
+ /* patch_string return error_mark_node if arg is error_mark_node */
+ if ((patched = patch_string (value)))
+ value = patched;
+ if (value == error_mark_node)
+ return 1;
+
+ type_value = TREE_TYPE (value);
+
+ /* At anytime, try_builtin_assignconv can report a warning on
+ constant overflow during narrowing. */
+ SET_WFL_OPERATOR (wfl_operator, TREE_PURPOSE (entry), wfl_value);
+ new_value = try_builtin_assignconv (wfl_operator, type, value);
+ if (!new_value && (new_value = try_reference_assignconv (type, value)))
+ type_value = promote_type (type);
+
+ /* Check and report errors */
+ if (!new_value)
+ {
+ char *msg = (!valid_cast_to_p (type_value, type) ?
+ "Can't" : "Explicit cast needed to");
+ if (!array_type_string)
+ array_type_string = strdup (lang_printable_name (type, 1));
+ parse_error_context
+ (wfl_operator, "Incompatible type for array. %s convert `%s' to `%s'",
+ msg, lang_printable_name (type_value, 1), array_type_string);
+ error_seen = 1;
}
- /* Add extra dimensions as unknown dimensions */
- while (xdims--)
- dims =
- chainon (dims, build_tree_list (NULL_TREE, integer_negative_one_node));
- dims = chainon (dims, build_tree_list (NULL_TREE, integer_zero_node));
+ if (new_value)
+ {
+ new_value = maybe_build_primttype_type_ref (new_value, wfl_operator);
+ TREE_VALUE (entry) = new_value;
+ }
- /* Can't reuse what's already written in expr.c because it uses the
- JVM stack representation. Provide a build_multianewarray. FIXME */
- array_type = type;
- for (cdim = TREE_CHAIN (dims); cdim; cdim = TREE_CHAIN (cdim))
- array_type = build_java_array_type (promote_type (array_type),
- TREE_CODE (cdim) == INTEGER_CST ?
- TREE_INT_CST_LOW (cdim) : -1);
- return build (CALL_EXPR,
- promote_type (array_type),
- build_address_of (soft_multianewarray_node),
- tree_cons (NULL_TREE, build_class_ref (array_type),
- tree_cons (NULL_TREE,
- build_int_2 (total_dims, 0), dims )),
- NULL_TREE);
+ if (array_type_string)
+ free (array_type_string);
+
+ TREE_PURPOSE (entry) = NULL_TREE;
+ return error_seen;
}
static tree
build_this (location)
int location;
{
- tree node = build_wfl_node (this_identifier_node, input_filename, 0, 0);
- TREE_SET_CODE (node, JAVA_THIS_EXPR);
+ tree node = build_wfl_node (this_identifier_node);
+ TREE_SET_CODE (node, THIS_EXPR);
EXPR_WFL_LINECOL (node) = location;
return node;
}
@@ -10207,6 +12891,7 @@ build_return (location, op)
{
tree node = build1 (RETURN_EXPR, NULL_TREE, op);
EXPR_WFL_LINECOL (node) = location;
+ node = build_debugable_stmt (location, node);
return node;
}
@@ -10217,7 +12902,6 @@ patch_return (node)
tree return_exp = TREE_OPERAND (node, 0);
tree meth = current_function_decl;
tree mtype = TREE_TYPE (TREE_TYPE (current_function_decl));
- tree modify;
int error_found = 0;
TREE_TYPE (node) = error_mark_node;
@@ -10228,6 +12912,10 @@ patch_return (node)
if (return_exp && (mtype == void_type_node || DECL_CONSTRUCTOR_P (meth)))
error_found = 1;
+ /* It's invalid to use a return statement in a static block */
+ if (DECL_NAME (current_function_decl) == clinit_identifier_node)
+ error_found = 1;
+
/* It's invalid to have a no return value within a function that
isn't declared with the keyword `void' */
if (!return_exp && (mtype != void_type_node && !DECL_CONSTRUCTOR_P (meth)))
@@ -10235,20 +12923,53 @@ patch_return (node)
if (error_found)
{
- char *t = strdup ((char *)lang_printable_name (mtype));
- parse_error_context (wfl_operator, "`return' with%s value from `%s %s'",
- (error_found == 1 ? "" : "out"), t,
- lang_printable_name (meth));
- free (t);
+ if (DECL_NAME (current_function_decl) == clinit_identifier_node)
+ parse_error_context (wfl_operator,
+ "`return' inside static initializer.");
+
+ else if (!DECL_CONSTRUCTOR_P (meth))
+ {
+ char *t = strdup (lang_printable_name (mtype, 0));
+ parse_error_context (wfl_operator,
+ "`return' with%s value from `%s %s'",
+ (error_found == 1 ? "" : "out"),
+ t, lang_printable_name (meth, 0));
+ free (t);
+ }
+ else
+ parse_error_context (wfl_operator,
+ "`return' with value from constructor `%s'",
+ lang_printable_name (meth, 0));
return error_mark_node;
}
- /* If we have a return_exp, build a modify expression and expand it */
+ /* If we have a return_exp, build a modify expression and expand
+ it. Note: at that point, the assignment is declared valid, but we
+ may want to carry some more hacks */
if (return_exp)
{
- modify = build (MODIFY_EXPR, NULL_TREE, DECL_RESULT (meth), return_exp);
+ tree exp = java_complete_tree (return_exp);
+ tree modify, patched;
+
+ /* If the function returned value and EXP are booleans, EXP has
+ to be converted into the type of DECL_RESULT, which is integer
+ (see complete_start_java_method) */
+ if (TREE_TYPE (exp) == boolean_type_node &&
+ TREE_TYPE (TREE_TYPE (meth)) == boolean_type_node)
+ exp = convert_to_integer (TREE_TYPE (DECL_RESULT (meth)), exp);
+
+ /* `null' can be assigned to a function returning a reference */
+ if (JREFERENCE_TYPE_P (TREE_TYPE (TREE_TYPE (meth))) &&
+ exp == null_pointer_node)
+ exp = build_null_of_type (TREE_TYPE (TREE_TYPE (meth)));
+
+ if ((patched = patch_string (exp)))
+ exp = patched;
+
+ modify = build (MODIFY_EXPR, NULL_TREE, DECL_RESULT (meth), exp);
EXPR_WFL_LINECOL (modify) = EXPR_WFL_LINECOL (node);
modify = java_complete_tree (modify);
+
if (modify != error_mark_node)
{
TREE_SIDE_EFFECTS (modify) = 1;
@@ -10270,12 +12991,11 @@ build_if_else_statement (location, expression, if_body, else_body)
tree expression, if_body, else_body;
{
tree node;
- /* FIXME: make else body be a void node, where this function is
- called */
if (!else_body)
- else_body = build (COMPOUND_EXPR, void_type_node, NULL_TREE, NULL_TREE);
+ else_body = empty_stmt_node;
node = build (COND_EXPR, NULL_TREE, expression, if_body, else_body);
EXPR_WFL_LINECOL (node) = location;
+ node = build_debugable_stmt (location, node);
return node;
}
@@ -10289,17 +13009,21 @@ patch_if_else_statement (node)
EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
/* The type of expression must be boolean */
- if (TREE_TYPE (expression) != boolean_type_node)
+ if (TREE_TYPE (expression) != boolean_type_node
+ && TREE_TYPE (expression) != promoted_boolean_type_node)
{
parse_error_context
(wfl_operator,
"Incompatible type for `if'. Can't convert `%s' to `boolean'",
- lang_printable_name (TREE_TYPE (expression)));
+ lang_printable_name (TREE_TYPE (expression), 0));
return error_mark_node;
}
TREE_TYPE (node) = void_type_node;
TREE_SIDE_EFFECTS (node) = 1;
+ CAN_COMPLETE_NORMALLY (node)
+ = CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 1))
+ | CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 2));
return node;
}
@@ -10307,30 +13031,35 @@ patch_if_else_statement (node)
/* Action taken when a lableled statement is parsed. a new
LABELED_BLOCK_EXPR is created. No statement is attached to the
- label, yet. */
+ label, yet. LABEL can be NULL_TREE for artificially-generated blocks. */
static tree
-build_labeled_block (location, label, wfl)
+build_labeled_block (location, label)
int location;
- tree label, wfl;
+ tree label;
{
- tree label_name = merge_qualified_name (label_id, label);
+ tree label_name ;
tree label_decl, node;
-
- /* Issue a warning if we try to reuse a label that was previously
- declared */
- if (IDENTIFIER_LOCAL_VALUE (label_name))
+ if (label == NULL_TREE || label == continue_identifier_node)
+ label_name = label;
+ else
{
- EXPR_WFL_LINECOL (wfl_operator) = location;
- parse_warning_context (wfl_operator, "Declaration of `%s' shadows "
- "a previous declaration",
- IDENTIFIER_POINTER (label));
- EXPR_WFL_LINECOL (wfl_operator) =
- EXPR_WFL_LINECOL (IDENTIFIER_LOCAL_VALUE (label_name));
- parse_warning_context (wfl_operator, "This is the location of the "
- "previous declaration of label `%s'",
- IDENTIFIER_POINTER (label));
- java_warning_count--;
+ label_name = merge_qualified_name (label_id, label);
+ /* Issue an error if we try to reuse a label that was previously
+ declared */
+ if (IDENTIFIER_LOCAL_VALUE (label_name))
+ {
+ EXPR_WFL_LINECOL (wfl_operator) = location;
+ parse_error_context (wfl_operator, "Declaration of `%s' shadows "
+ "a previous label declaration",
+ IDENTIFIER_POINTER (label));
+ EXPR_WFL_LINECOL (wfl_operator) =
+ EXPR_WFL_LINECOL (IDENTIFIER_LOCAL_VALUE (label_name));
+ parse_error_context (wfl_operator, "This is the location of the "
+ "previous declaration of label `%s'",
+ IDENTIFIER_POINTER (label));
+ java_error_count--;
+ }
}
label_decl = create_label_decl (label_name);
@@ -10340,27 +13069,10 @@ build_labeled_block (location, label, wfl)
return node;
}
-/* Generate a label crafting a unique name for it. This is used to
- implicitely label loops that aren't the body part of labeled
- statement. */
-
-static tree
-generate_labeled_block ()
-{
- static int l_number = 0;
- char buf [20];
- tree label_name;
-
- sprintf (buf, "$a%d", l_number++);
- return build_labeled_block (0, get_identifier (buf), NULL_TREE);
-}
-
-/* A labeled statement LBE is attached a statement. If the statement
- happens to be a loop, a link from the loop back to the label is
- installed. */
+/* A labeled statement LBE is attached a statement. */
static tree
-complete_labeled_statement (lbe, statement)
+finish_labeled_statement (lbe, statement)
tree lbe; /* Labeled block expr */
tree statement;
{
@@ -10373,9 +13085,10 @@ complete_labeled_statement (lbe, statement)
if (TREE_CODE (statement) == LOOP_EXPR && IS_FOR_LOOP_P (statement))
{
java_method_add_stmt (current_function_decl, lbe);
- return exit_block ();
+ lbe = exit_block ();
}
-
+ pop_labeled_block ();
+ POP_LABELED_BLOCK ();
return lbe;
}
@@ -10399,12 +13112,20 @@ build_new_loop (loop_body)
COMPOUND_EXPR (loop main body)
EXIT_EXPR (this order is for while/for loops.
LABELED_BLOCK_EXPR the order is reversed for do loops)
- LABEL_DECL (continue occurding here branche at the
+ LABEL_DECL (a continue occuring here branches at the
BODY end of this labeled block)
INCREMENT (if any)
REVERSED, if non zero, tells that the loop condition expr comes
- after the body, like in the do-while loop. */
+ after the body, like in the do-while loop.
+
+ To obtain a loop, the loop body structure described above is
+ encapsulated within a LOOP_EXPR surrounded by a LABELED_BLOCK_EXPR:
+
+ LABELED_BLOCK_EXPR
+ LABEL_DECL (use this label to exit the loop)
+ LOOP_EXPR
+ <structure described above> */
static tree
build_loop_body (location, condition, reversed)
@@ -10412,19 +13133,19 @@ build_loop_body (location, condition, reversed)
tree condition;
int reversed;
{
- tree first, second, label, body;
+ tree first, second, body;
condition = build (EXIT_EXPR, NULL_TREE, condition); /* Force walk */
EXPR_WFL_LINECOL (condition) = location; /* For accurate error report */
condition = build_debugable_stmt (location, condition);
TREE_SIDE_EFFECTS (condition) = 1;
- body = generate_labeled_block ();
+ body = build_labeled_block (0, continue_identifier_node);
first = (reversed ? body : condition);
second = (reversed ? condition : body);
return
build (COMPOUND_EXPR, NULL_TREE,
- build (COMPOUND_EXPR, NULL_TREE, first, second), size_zero_node);
+ build (COMPOUND_EXPR, NULL_TREE, first, second), empty_stmt_node);
}
/* Install CONDITION (if any) and loop BODY (using REVERSED to tell
@@ -10432,7 +13153,7 @@ build_loop_body (location, condition, reversed)
loop list. */
static tree
-complete_loop_body (location, condition, body, reversed)
+finish_loop_body (location, condition, body, reversed)
int location;
tree condition, body;
int reversed;
@@ -10454,16 +13175,16 @@ complete_loop_body (location, condition, body, reversed)
return to_return;
}
-/* Tailored version of complete_loop_body for FOR loops, when FOR
+/* Tailored version of finish_loop_body for FOR loops, when FOR
loops feature the condition part */
static tree
-complete_for_loop (location, condition, update, body)
+finish_for_loop (location, condition, update, body)
int location;
tree condition, update, body;
{
/* Put the condition and the loop body in place */
- tree loop = complete_loop_body (location, condition, body, 0);
+ tree loop = finish_loop_body (location, condition, body, 0);
/* LOOP is the current loop which has been now popped of the loop
stack. Install the update block */
LOOP_EXPR_BODY_UPDATE_BLOCK (LOOP_EXPR_BODY (loop)) = update;
@@ -10471,28 +13192,21 @@ complete_for_loop (location, condition, update, body)
}
/* If the loop isn't surrounded by a labeled statement, create one and
- insert LOOP as it's body. */
+ insert LOOP as its body. */
static tree
patch_loop_statement (loop)
tree loop;
{
- tree cbl, loop_label, to_return_as_loop;
-
- if (LOOP_HAS_LABEL_P (loop))
- {
- loop_label = ctxp->current_labeled_block;
- to_return_as_loop = loop;
- }
- else
+ if (! LOOP_HAS_LABEL_P (loop))
{
- loop_label = generate_labeled_block ();
+ tree loop_label = build_labeled_block (0, NULL_TREE);
LABELED_BLOCK_BODY (loop_label) = loop;
PUSH_LABELED_BLOCK (loop_label);
- to_return_as_loop = loop_label;
+ loop = loop_label;
}
- TREE_TYPE (to_return_as_loop) = void_type_node;
- return to_return_as_loop;
+ TREE_TYPE (loop) = void_type_node;
+ return loop;
}
/* 14.13, 14.14: break and continue Statements */
@@ -10525,6 +13239,7 @@ build_bc_statement (location, is_break, name)
IS_BREAK_STMT_P (break_continue) = is_break;
TREE_SIDE_EFFECTS (break_continue) = 1;
EXPR_WFL_LINECOL (break_continue) = location;
+ break_continue = build_debugable_stmt (location, break_continue);
return break_continue;
}
@@ -10535,79 +13250,65 @@ patch_bc_statement (node)
tree node;
{
tree bc_label = EXIT_BLOCK_LABELED_BLOCK (node), target_stmt;
- int is_unlabeled = 0;
- EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
+ tree labeled_block = ctxp->current_labeled_block;
+ EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
- /* Not having a target means that the break/continue statement is
- unlabeled. We try to find a descent label for it */
- if (!bc_label)
- {
- is_unlabeled = 1;
- /* There should be a loop to branch to */
- if (ctxp->current_loop)
- {
- /* At that stage, we're in the loop body, which is
- encapsulated around a LABELED_BLOCK_EXPR. So searching
- the current loop label requires us to consider the
- labeled block before the current one. */
- if (!LOOP_HAS_LABEL_SKIP_P (ctxp->current_loop))
- fatal ("unlabeled loop has not installed label -- "
- "patch_bc_statement");
- bc_label = TREE_CHAIN (ctxp->current_labeled_block);
- }
- /* Not having a loop to break/continue to is an error */
- else
- {
- parse_error_context (wfl_operator, "`%s' must be in loop%s",
- (IS_BREAK_STMT_P (node) ? "break" : "continue"),
- (IS_BREAK_STMT_P (node) ? " or switch" : ""));
- return error_mark_node;
- }
- }
/* Having an identifier here means that the target is unknown. */
- else if (TREE_CODE (bc_label) == IDENTIFIER_NODE)
+ if (bc_label != NULL_TREE && TREE_CODE (bc_label) == IDENTIFIER_NODE)
{
parse_error_context (wfl_operator, "No label definition found for `%s'",
IDENTIFIER_POINTER (bc_label));
return error_mark_node;
}
-
- /* Find the statement we're targeting. */
- target_stmt = LABELED_BLOCK_BODY (bc_label);
-
- /* 14.13 The break Statement */
- if (IS_BREAK_STMT_P (node))
+ if (! IS_BREAK_STMT_P (node))
{
- /* Named break are always fine, as far as they have a target
- (already verified). Anonymous break need to target
- while/do/for/switch */
- if (is_unlabeled &&
- !(TREE_CODE (target_stmt) == LOOP_EXPR /* do/while/for */
- || 0)) /* switch FIXME */
+ /* It's a continue statement. */
+ for (;; labeled_block = TREE_CHAIN (labeled_block))
{
- parse_error_context (wfl_operator,
- "`break' must be in loop or switch");
- return error_mark_node;
+ if (labeled_block == NULL_TREE)
+ {
+ if (bc_label == NULL_TREE)
+ parse_error_context (wfl_operator,
+ "`continue' must be in loop");
+ else
+ parse_error_context (wfl_operator,
+ "continue label `%d' does not name a loop",
+ IDENTIFIER_POINTER (bc_label));
+ return error_mark_node;
+ }
+ if ((DECL_NAME (LABELED_BLOCK_LABEL (labeled_block))
+ == continue_identifier_node)
+ && (bc_label == NULL_TREE
+ || TREE_CHAIN (labeled_block) == bc_label))
+ {
+ bc_label = labeled_block;
+ break;
+ }
}
- /* If previously unlabeled, install the new found label */
- if (is_unlabeled)
- EXIT_BLOCK_LABELED_BLOCK (node) = bc_label;
}
- /* 14.14 The continue Statement */
- /* The continue statement must always target a loop */
- else
- {
- if (TREE_CODE (target_stmt) != LOOP_EXPR) /* do/while/for */
+ else if (!bc_label)
+ {
+ for (;; labeled_block = TREE_CHAIN (labeled_block))
{
- parse_error_context (wfl_operator, "`continue' must be in loop");
- return error_mark_node;
+ if (labeled_block == NULL_TREE)
+ {
+ parse_error_context (wfl_operator,
+ "`break' must be in loop or switch");
+ return error_mark_node;
+ }
+ target_stmt = LABELED_BLOCK_BODY (labeled_block);
+ if (TREE_CODE (target_stmt) == SWITCH_EXPR
+ || TREE_CODE (target_stmt) == LOOP_EXPR)
+ {
+ bc_label = labeled_block;
+ break;
+ }
}
- /* Everything looks good. We can fix the `continue' jump to go
- at the place in the loop were the continue is. The continue
- is the current labeled block, by construction. */
- EXIT_BLOCK_LABELED_BLOCK (node) = ctxp->current_labeled_block;
}
+ EXIT_BLOCK_LABELED_BLOCK (node) = bc_label;
+ CAN_COMPLETE_NORMALLY (bc_label) = 1;
+
/* Our break/continue don't return values. */
TREE_TYPE (node) = void_type_node;
/* Encapsulate the break within a compound statement so that it's
@@ -10636,13 +13337,686 @@ patch_exit_expr (node)
(wfl_operator,
"Incompatible type for loop conditional. Can't convert `%s' to "
"`boolean'",
- lang_printable_name (TREE_TYPE (expression)));
+ lang_printable_name (TREE_TYPE (expression), 0));
return error_mark_node;
}
/* Now we know things are allright, invert the condition, fold and
return */
TREE_OPERAND (node, 0) =
fold (build1 (TRUTH_NOT_EXPR, boolean_type_node, expression));
+
+ if (! integer_zerop (TREE_OPERAND (node, 0))
+ && ctxp->current_loop != NULL_TREE
+ && TREE_CODE (ctxp->current_loop) == LOOP_EXPR)
+ CAN_COMPLETE_NORMALLY (ctxp->current_loop) = 1;
+ if (! integer_onep (TREE_OPERAND (node, 0)))
+ CAN_COMPLETE_NORMALLY (node) = 1;
+
+
TREE_TYPE (node) = void_type_node;
return node;
}
+
+/* 14.9 Switch statement */
+
+static tree
+patch_switch_statement (node)
+ tree node;
+{
+ tree se = TREE_OPERAND (node, 0), se_type;
+
+ /* Complete the switch expression */
+ se = TREE_OPERAND (node, 0) = java_complete_tree (se);
+ se_type = TREE_TYPE (se);
+ /* The type of the switch expression must be char, byte, short or
+ int */
+ if (!JINTEGRAL_TYPE_P (se_type))
+ {
+ EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
+ parse_error_context (wfl_operator, "Incompatible type for `switch'. "
+ "Can't convert `%s' to `int'",
+ lang_printable_name (se_type, 0));
+ /* This is what java_complete_tree will check */
+ TREE_OPERAND (node, 0) = error_mark_node;
+ return error_mark_node;
+ }
+
+ TREE_OPERAND (node, 1) = java_complete_tree (TREE_OPERAND (node, 1));
+
+ /* Ready to return */
+ if (TREE_CODE (TREE_OPERAND (node, 1)) == ERROR_MARK)
+ {
+ TREE_TYPE (node) = error_mark_node;
+ return error_mark_node;
+ }
+ TREE_TYPE (node) = void_type_node;
+ TREE_SIDE_EFFECTS (node) = 1;
+ CAN_COMPLETE_NORMALLY (node)
+ = CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 1))
+ || ! SWITCH_HAS_DEFAULT (node);
+ return node;
+}
+
+/* 14.18 The try statement */
+
+static tree
+build_try_statement (location, try_block, catches)
+ int location;
+ tree try_block, catches;
+{
+ tree node = build (TRY_EXPR, NULL_TREE, try_block, catches);
+ EXPR_WFL_LINECOL (node) = location;
+ return node;
+}
+
+static tree
+build_try_finally_statement (location, try_block, finally)
+ int location;
+ tree try_block, finally;
+{
+ tree node = build (TRY_FINALLY_EXPR, NULL_TREE, try_block, finally);
+ EXPR_WFL_LINECOL (node) = location;
+ return node;
+}
+
+static tree
+patch_try_statement (node)
+ tree node;
+{
+ int error_found = 0;
+ tree try = TREE_OPERAND (node, 0);
+ /* Exception handlers are considered in left to right order */
+ tree catch = nreverse (TREE_OPERAND (node, 1));
+ tree current, caught_type_list = NULL_TREE;
+
+ /* Check catch clauses, if any. Every time we find an error, we try
+ to process the next catch clause. We process the catch clause before
+ the try block so that when processing the try block we can check thrown
+ exceptions againts the caught type list. */
+ for (current = catch; current; current = TREE_CHAIN (current))
+ {
+ tree carg_decl, carg_type;
+ tree sub_current, catch_block, catch_clause;
+ int unreachable;
+
+ /* At this point, the structure of the catch clause is
+ CATCH_EXPR (catch node)
+ BLOCK (with the decl of the parameter)
+ COMPOUND_EXPR
+ MODIFY_EXPR (assignment of the catch parameter)
+ BLOCK (catch clause block)
+ */
+ catch_clause = TREE_OPERAND (current, 0);
+ carg_decl = BLOCK_EXPR_DECLS (catch_clause);
+ carg_type = TREE_TYPE (TREE_TYPE (carg_decl));
+
+ /* Catch clauses can't have more than one parameter declared,
+ but it's already enforced by the grammar. Make sure that the
+ only parameter of the clause statement in of class Throwable
+ or a subclass of Throwable, but that was done earlier. The
+ catch clause parameter type has also been resolved. */
+
+ /* Just make sure that the catch clause parameter type inherits
+ from java.lang.Throwable */
+ if (!inherits_from_p (carg_type, throwable_type_node))
+ {
+ EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (current);
+ parse_error_context (wfl_operator,
+ "Can't catch class `%s'. Catch clause "
+ "parameter type must be a subclass of "
+ "class `java.lang.Throwable'",
+ lang_printable_name (carg_type, 0));
+ error_found = 1;
+ continue;
+ }
+
+ /* Partial check for unreachable catch statement: The catch
+ clause is reachable iff is no earlier catch block A in
+ the try statement such that the type of the catch
+ clause's parameter is the same as or a subclass of the
+ type of A's parameter */
+ unreachable = 0;
+ for (sub_current = catch;
+ sub_current != current; sub_current = TREE_CHAIN (sub_current))
+ {
+ tree sub_catch_clause, decl;
+ sub_catch_clause = TREE_OPERAND (sub_current, 0);
+ decl = BLOCK_EXPR_DECLS (sub_catch_clause);
+
+ if (inherits_from_p (carg_type, TREE_TYPE (TREE_TYPE (decl))))
+ {
+ EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (current);
+ parse_error_context
+ (wfl_operator, "`catch' not reached because of the catch "
+ "clause at line %d", EXPR_WFL_LINENO (sub_current));
+ unreachable = error_found = 1;
+ break;
+ }
+ }
+ /* Complete the catch clause block */
+ catch_block = java_complete_tree (TREE_OPERAND (current, 0));
+ if (catch_block == error_mark_node)
+ {
+ error_found = 1;
+ continue;
+ }
+ if (CAN_COMPLETE_NORMALLY (catch_block))
+ CAN_COMPLETE_NORMALLY (node) = 1;
+ TREE_OPERAND (current, 0) = catch_block;
+
+ if (unreachable)
+ continue;
+
+ /* Things to do here: the exception must be thrown */
+
+ /* Link this type to the caught type list */
+ caught_type_list = tree_cons (NULL_TREE, carg_type, caught_type_list);
+ }
+
+ PUSH_EXCEPTIONS (caught_type_list);
+ if ((try = java_complete_tree (try)) == error_mark_node)
+ error_found = 1;
+ if (CAN_COMPLETE_NORMALLY (try))
+ CAN_COMPLETE_NORMALLY (node) = 1;
+ POP_EXCEPTIONS ();
+
+ /* Verification ends here */
+ if (error_found)
+ return error_mark_node;
+
+ TREE_OPERAND (node, 0) = try;
+ TREE_OPERAND (node, 1) = catch;
+ TREE_TYPE (node) = void_type_node;
+ return node;
+}
+
+/* 14.17 The synchronized Statement */
+
+static tree
+patch_synchronized_statement (node, wfl_op1)
+ tree node, wfl_op1;
+{
+ tree expr = java_complete_tree (TREE_OPERAND (node, 0));
+ tree block = TREE_OPERAND (node, 1);
+
+ tree enter, exit, expr_decl, assignment;
+
+ if (expr == error_mark_node)
+ {
+ block = java_complete_tree (block);
+ return expr;
+ }
+
+ /* The TYPE of expr must be a reference type */
+ if (!JREFERENCE_TYPE_P (TREE_TYPE (expr)))
+ {
+ SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
+ parse_error_context (wfl_operator, "Incompatible type for `synchronized'"
+ ". Can't convert `%s' to `java.lang.Object'",
+ lang_printable_name (TREE_TYPE (expr), 0));
+ return error_mark_node;
+ }
+
+ /* Generate a try-finally for the synchronized statement, except
+ that the handler that catches all throw exception calls
+ _Jv_MonitorExit and then rethrow the exception.
+ The synchronized statement is then implemented as:
+ TRY
+ {
+ _Jv_MonitorEnter (expression)
+ synchronized_block
+ _Jv_MonitorExit (expression)
+ }
+ CATCH_ALL
+ {
+ e = _Jv_exception_info ();
+ _Jv_MonitorExit (expression)
+ Throw (e);
+ } */
+
+ expr_decl = build_decl (VAR_DECL, generate_name (), TREE_TYPE (expr));
+ BUILD_MONITOR_ENTER (enter, expr_decl);
+ BUILD_MONITOR_EXIT (exit, expr_decl);
+ CAN_COMPLETE_NORMALLY (enter) = 1;
+ CAN_COMPLETE_NORMALLY (exit) = 1;
+ assignment = build (MODIFY_EXPR, NULL_TREE, expr_decl, expr);
+ TREE_SIDE_EFFECTS (assignment) = 1;
+ node = build1 (CLEANUP_POINT_EXPR, NULL_TREE,
+ build (COMPOUND_EXPR, NULL_TREE,
+ build (WITH_CLEANUP_EXPR, NULL_TREE,
+ build (COMPOUND_EXPR, NULL_TREE,
+ assignment, enter),
+ NULL_TREE, exit),
+ block));
+ node = build_expr_block (node, expr_decl);
+
+ return java_complete_tree (node);
+}
+
+/* 14.16 The throw Statement */
+
+static tree
+patch_throw_statement (node, wfl_op1)
+ tree node, wfl_op1;
+{
+ tree expr = TREE_OPERAND (node, 0);
+ tree type = TREE_TYPE (expr);
+ int unchecked_ok = 0, tryblock_throws_ok = 0;
+
+ /* Thrown expression must be assignable to java.lang.Throwable */
+ if (!try_reference_assignconv (throwable_type_node, expr))
+ {
+ SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
+ parse_error_context (wfl_operator, "Can't throw `%s'; it must be a "
+ "subclass of class `java.lang.Throwable'",
+ lang_printable_name (type, 0));
+ /* If the thrown expression was a reference, we further the
+ compile-time check. */
+ if (!JREFERENCE_TYPE_P (type))
+ return error_mark_node;
+ }
+
+ /* At least one of the following must be true */
+
+ /* The type of the throw expression is a not checked exception,
+ i.e. is a unchecked expression. */
+ unchecked_ok = IS_UNCHECKED_EXCEPTION_P (TREE_TYPE (type));
+
+ /* Throw is contained in a try statement and at least one catch
+ clause can receive the thrown expression or the current method is
+ declared to throw such an exception. Or, the throw statement is
+ contained in a method or constructor declaration and the type of
+ the Expression is assignable to at least one type listed in the
+ throws clause the declaration. */
+ SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
+ if (!unchecked_ok)
+ tryblock_throws_ok = check_thrown_exceptions_do (TREE_TYPE (expr));
+ if (!(unchecked_ok || tryblock_throws_ok))
+ {
+ /* If there is a surrounding try block that has no matching
+ clatch clause, report it first. A surrounding try block exits
+ only if there is something after the list of checked
+ exception thrown by the current function (if any). */
+ if (IN_TRY_BLOCK_P ())
+ parse_error_context (wfl_operator, "Checked exception `%s' can't be "
+ "caught by any of the catch clause(s) "
+ "of the surrounding `try' block",
+ lang_printable_name (type, 0));
+ /* If we have no surrounding try statement and the method doesn't have
+ any throws, report it now. FIXME */
+
+ /* We report that the exception can't be throw from a try block
+ in all circumstances but when the `throw' is inside a static
+ block. */
+ else if (!EXCEPTIONS_P (currently_caught_type_list)
+ && !tryblock_throws_ok)
+ {
+ if (DECL_NAME (current_function_decl) == clinit_identifier_node)
+ parse_error_context (wfl_operator, "Checked exception `%s' can't "
+ "be thrown in initializer",
+ lang_printable_name (type, 0));
+ else
+ parse_error_context (wfl_operator, "Checked exception `%s' isn't "
+ "thrown from a `try' block",
+ lang_printable_name (type, 0));
+ }
+ /* Otherwise, the current method doesn't have the appropriate
+ throws declaration */
+ else
+ parse_error_context (wfl_operator, "Checked exception `%s' doesn't "
+ "match any of current method's `throws' "
+ "declaration(s)",
+ lang_printable_name (type, 0));
+ return error_mark_node;
+ }
+
+ if (! flag_emit_class_files)
+ BUILD_THROW (node, expr);
+ return node;
+}
+
+/* Check that exception said to be thrown by method DECL can be
+ effectively caught from where DECL is invoked. */
+
+static void
+check_thrown_exceptions (location, decl)
+ int location;
+ tree decl;
+{
+ tree throws;
+ /* For all the unchecked exceptions thrown by DECL */
+ for (throws = DECL_FUNCTION_THROWS (decl); throws;
+ throws = TREE_CHAIN (throws))
+ if (!check_thrown_exceptions_do (TREE_VALUE (throws)))
+ {
+#if 1
+ /* Temporary hack to suppresses errors about cloning arrays. FIXME */
+ if (DECL_NAME (decl) == get_identifier ("clone"))
+ continue;
+#endif
+ EXPR_WFL_LINECOL (wfl_operator) = location;
+ parse_error_context
+ (wfl_operator, "Exception `%s' must be caught, or it must be "
+ "declared in the `throws' clause of `%s'",
+ lang_printable_name (TREE_VALUE (throws), 0),
+ IDENTIFIER_POINTER (DECL_NAME (current_function_decl)));
+ }
+}
+
+/* Return 1 if checked EXCEPTION is caught at the current nesting level of
+ try-catch blocks, OR is listed in the `throws' clause of the
+ current method. */
+
+static int
+check_thrown_exceptions_do (exception)
+ tree exception;
+{
+ tree list = currently_caught_type_list;
+ resolve_and_layout (exception, NULL_TREE);
+ /* First, all the nested try-catch-finally at that stage. The
+ last element contains `throws' clause exceptions, if any. */
+ if (IS_UNCHECKED_EXCEPTION_P (exception))
+ return 1;
+ while (list)
+ {
+ tree caught;
+ for (caught = TREE_VALUE (list); caught; caught = TREE_CHAIN (caught))
+ if (valid_ref_assignconv_cast_p (exception, TREE_VALUE (caught), 0))
+ return 1;
+ list = TREE_CHAIN (list);
+ }
+ return 0;
+}
+
+static void
+purge_unchecked_exceptions (mdecl)
+ tree mdecl;
+{
+ tree throws = DECL_FUNCTION_THROWS (mdecl);
+ tree new = NULL_TREE;
+
+ while (throws)
+ {
+ tree next = TREE_CHAIN (throws);
+ if (!IS_UNCHECKED_EXCEPTION_P (TREE_VALUE (throws)))
+ {
+ TREE_CHAIN (throws) = new;
+ new = throws;
+ }
+ throws = next;
+ }
+ /* List is inverted here, but it doesn't matter */
+ DECL_FUNCTION_THROWS (mdecl) = new;
+}
+
+/* 15.24 Conditional Operator ?: */
+
+static tree
+patch_conditional_expr (node, wfl_cond, wfl_op1)
+ tree node, wfl_cond, wfl_op1;
+{
+ tree cond = TREE_OPERAND (node, 0);
+ tree op1 = TREE_OPERAND (node, 1);
+ tree op2 = TREE_OPERAND (node, 2);
+ tree resulting_type = NULL_TREE;
+ tree t1, t2, patched;
+ int error_found = 0;
+
+ /* Operands of ?: might be StringBuffers crafted as a result of a
+ string concatenation. Obtain a descent operand here. */
+ if ((patched = patch_string (op1)))
+ TREE_OPERAND (node, 1) = op1 = patched;
+ if ((patched = patch_string (op2)))
+ TREE_OPERAND (node, 2) = op2 = patched;
+
+ t1 = TREE_TYPE (op1);
+ t2 = TREE_TYPE (op2);
+
+ /* The first expression must be a boolean */
+ if (TREE_TYPE (cond) != boolean_type_node)
+ {
+ SET_WFL_OPERATOR (wfl_operator, node, wfl_cond);
+ parse_error_context (wfl_operator, "Incompatible type for `?:'. Can't "
+ "convert `%s' to `boolean'",
+ lang_printable_name (TREE_TYPE (cond), 0));
+ error_found = 1;
+ }
+
+ /* Second and third can be numeric, boolean (i.e. primitive),
+ references or null. Anything else results in an error */
+ if (!((JNUMERIC_TYPE_P (t1) && JNUMERIC_TYPE_P (t2))
+ || ((JREFERENCE_TYPE_P (t1) || op1 == null_pointer_node)
+ && (JREFERENCE_TYPE_P (t2) || op2 == null_pointer_node))
+ || (t1 == boolean_type_node && t2 == boolean_type_node)))
+ error_found = 1;
+
+ /* Determine the type of the conditional expression. Same types are
+ easy to deal with */
+ else if (t1 == t2)
+ resulting_type = t1;
+
+ /* There are different rules for numeric types */
+ else if (JNUMERIC_TYPE_P (t1))
+ {
+ /* if byte/short found, the resulting type is short */
+ if ((t1 == byte_type_node && t2 == short_type_node)
+ || (t1 == short_type_node && t2 == byte_type_node))
+ resulting_type = short_type_node;
+
+ /* If t1 is a constant int and t2 is of type byte, short or char
+ and t1's value fits in t2, then the resulting type is t2 */
+ else if ((t1 == int_type_node && TREE_CONSTANT (TREE_OPERAND (node, 1)))
+ && JBSC_TYPE_P (t2) && int_fits_type_p (TREE_OPERAND (node, 1), t2))
+ resulting_type = t2;
+
+ /* If t2 is a constant int and t1 is of type byte, short or char
+ and t2's value fits in t1, then the resulting type is t1 */
+ else if ((t2 == int_type_node && TREE_CONSTANT (TREE_OPERAND (node, 2)))
+ && JBSC_TYPE_P (t1) && int_fits_type_p (TREE_OPERAND (node, 2), t1))
+ resulting_type = t1;
+
+ /* Otherwise, binary numeric promotion is applied and the
+ resulting type is the promoted type of operand 1 and 2 */
+ else
+ resulting_type = binary_numeric_promotion (t2, t2,
+ &TREE_OPERAND (node, 1),
+ &TREE_OPERAND (node, 2));
+ }
+
+ /* Cases of a reference and a null type */
+ else if (JREFERENCE_TYPE_P (t1) && op2 == null_pointer_node)
+ resulting_type = t1;
+
+ else if (JREFERENCE_TYPE_P (t2) && op1 == null_pointer_node)
+ resulting_type = t2;
+
+ /* Last case: different reference types. If a type can be converted
+ into the other one by assignment conversion, the latter
+ determines the type of the expression */
+ else if ((resulting_type = try_reference_assignconv (t1, op2)))
+ resulting_type = promote_type (t1);
+
+ else if ((resulting_type = try_reference_assignconv (t2, op1)))
+ resulting_type = promote_type (t2);
+
+ /* If we don't have any resulting type, we're in trouble */
+ if (!resulting_type)
+ {
+ char *t = strdup (lang_printable_name (t1, 0));
+ SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
+ parse_error_context (wfl_operator, "Incompatible type for `?:'. Can't "
+ "convert `%s' to `%s'", t,
+ lang_printable_name (t2, 0));
+ free (t);
+ error_found = 1;
+ }
+
+ if (error_found)
+ {
+ TREE_TYPE (node) = error_mark_node;
+ return error_mark_node;
+ }
+
+ TREE_TYPE (node) = resulting_type;
+ TREE_SET_CODE (node, COND_EXPR);
+ CAN_COMPLETE_NORMALLY (node) = 1;
+ return node;
+}
+
+/* Try to constant fold NODE.
+ If NODE is not a constant expression, return NULL_EXPR.
+ CONTEXT is a static final VAR_DECL whose initializer we are folding. */
+
+static tree
+fold_constant_for_init (node, context)
+ tree node;
+ tree context;
+{
+ tree op0, op1, val;
+ enum tree_code code = TREE_CODE (node);
+
+ if (code == INTEGER_CST || code == REAL_CST || code == STRING_CST)
+ return node;
+ if (TREE_TYPE (node) != NULL_TREE)
+ return NULL_TREE;
+
+ switch (code)
+ {
+ case PLUS_EXPR:
+ case MINUS_EXPR:
+ case MULT_EXPR:
+ case TRUNC_MOD_EXPR:
+ case RDIV_EXPR:
+ case LSHIFT_EXPR:
+ case RSHIFT_EXPR:
+ case URSHIFT_EXPR:
+ case BIT_AND_EXPR:
+ case BIT_XOR_EXPR:
+ case BIT_IOR_EXPR:
+ case TRUTH_ANDIF_EXPR:
+ case TRUTH_ORIF_EXPR:
+ case EQ_EXPR:
+ case NE_EXPR:
+ case GT_EXPR:
+ case GE_EXPR:
+ case LT_EXPR:
+ case LE_EXPR:
+ op0 = TREE_OPERAND (node, 0);
+ op1 = TREE_OPERAND (node, 1);
+ val = fold_constant_for_init (op0, context);
+ if (val == NULL_TREE || ! TREE_CONSTANT (val))
+ return NULL_TREE;
+ TREE_OPERAND (node, 0) = val;
+ val = fold_constant_for_init (op1, context);
+ if (val == NULL_TREE || ! TREE_CONSTANT (val))
+ return NULL_TREE;
+ TREE_OPERAND (node, 1) = val;
+ return patch_binop (node, op0, op1);
+
+ case UNARY_PLUS_EXPR:
+ case NEGATE_EXPR:
+ case TRUTH_NOT_EXPR:
+ case BIT_NOT_EXPR:
+ case CONVERT_EXPR:
+ op0 = TREE_OPERAND (node, 0);
+ val = fold_constant_for_init (op0, context);
+ if (val == NULL_TREE || ! TREE_CONSTANT (val))
+ return NULL_TREE;
+ TREE_OPERAND (node, 0) = val;
+ return patch_unaryop (node, op0);
+ break;
+
+ case COND_EXPR:
+ val = fold_constant_for_init (TREE_OPERAND (node, 0), context);
+ if (val == NULL_TREE || ! TREE_CONSTANT (val))
+ return NULL_TREE;
+ TREE_OPERAND (node, 0) = val;
+ val = fold_constant_for_init (TREE_OPERAND (node, 1), context);
+ if (val == NULL_TREE || ! TREE_CONSTANT (val))
+ return NULL_TREE;
+ TREE_OPERAND (node, 1) = val;
+ val = fold_constant_for_init (TREE_OPERAND (node, 2), context);
+ if (val == NULL_TREE || ! TREE_CONSTANT (val))
+ return NULL_TREE;
+ TREE_OPERAND (node, 2) = val;
+ return integer_zerop (TREE_OPERAND (node, 0)) ? TREE_OPERAND (node, 1)
+ : TREE_OPERAND (node, 2);
+
+ case VAR_DECL:
+ if (! FIELD_STATIC (node) || ! FIELD_FINAL (node)
+ || DECL_INITIAL (node) == NULL_TREE)
+ return NULL_TREE;
+ val = DECL_INITIAL (node);
+ /* Guard against infinite recursion. */
+ DECL_INITIAL (node) = NULL_TREE;
+ val = fold_constant_for_init (val, DECL_CONTEXT (node));
+ DECL_INITIAL (node) = val;
+ return val;
+
+ case EXPR_WITH_FILE_LOCATION:
+ /* Compare java_complete_tree and resolve_expression_name. */
+ if (!EXPR_WFL_NODE (node) /* Or a PRIMARY flag ? */
+ || TREE_CODE (EXPR_WFL_NODE (node)) == IDENTIFIER_NODE)
+ {
+ tree name = EXPR_WFL_NODE (node);
+ tree decl;
+ if (PRIMARY_P (node))
+ return NULL_TREE;
+ else if (! QUALIFIED_P (name))
+ {
+ decl = lookup_field_wrapper (DECL_CONTEXT (context), name);
+ if (! FIELD_STATIC (decl))
+ return NULL_TREE;
+ return fold_constant_for_init (decl, decl);
+ }
+ else
+ {
+#if 0
+ /* Wait until the USE_COMPONENT_REF re-write. FIXME. */
+ qualify_ambiguous_name (node);
+ if (resolve_field_access (node, &decl, NULL)
+ && decl != NULL_TREE)
+ return fold_constant_for_init (decl, decl);
+#endif
+ return NULL_TREE;
+ }
+ }
+ else
+ {
+ op0 = TREE_OPERAND (node, 0);
+ val = fold_constant_for_init (op0, context);
+ if (val == NULL_TREE || ! TREE_CONSTANT (val))
+ return NULL_TREE;
+ TREE_OPERAND (node, 0) = val;
+ return val;
+ }
+
+#ifdef USE_COMPONENT_REF
+ case IDENTIFIER:
+ case COMPONENT_REF:
+ ?;
+#endif
+
+ default:
+ return NULL_TREE;
+ }
+}
+
+#ifdef USE_COMPONENT_REF
+/* Context is 'T' for TypeName, 'P' for PackageName,
+ 'M' for MethodName, 'E' for ExpressionName, and 'A' for AmbiguousName. */
+
+tree
+resolve_simple_name (name, context)
+ tree name;
+ int context;
+{
+}
+
+tree
+resolve_qualified_name (name, context)
+ tree name;
+ int context;
+{
+}
+#endif
diff --git a/gcc/java/parse.h b/gcc/java/parse.h
index 50d51401149..52d9917df87 100644
--- a/gcc/java/parse.h
+++ b/gcc/java/parse.h
@@ -1,5 +1,5 @@
/* Language parser definitions for the GNU compiler for the Java(TM) language.
- Copyright (C) 1997, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc.
Contributed by Alexandre Petit-Bianco (apbianco@cygnus.com)
This file is part of GNU CC.
@@ -47,7 +47,7 @@ extern tree stabilize_reference PROTO ((tree));
#define RULE( rule )
#endif
-#ifdef SOURCE_FRONTEND_DEBUG
+#ifdef VERBOSE_SKELETON
#undef SOURCE_FRONTEND_DEBUG
#define SOURCE_FRONTEND_DEBUG(X) \
{if (!quiet_flag) {printf ("* "); printf X; putchar ('\n');} }
@@ -99,10 +99,14 @@ extern tree stabilize_reference PROTO ((tree));
count++; \
}
-#define ABSTRACT_CHECK(flag, v, cl, s) \
- if ((flag) & (v)) \
- parse_error_context (cl, s " method can't be abstract");
+#define ABSTRACT_CHECK(FLAG, V, CL, S) \
+ if ((FLAG) & (V)) \
+ parse_error_context ((CL), S " method can't be abstract");
+#define JCONSTRUCTOR_CHECK(FLAG, V, CL, S) \
+ if ((FLAG) & (V)) \
+ parse_error_context ((CL), "Constructor can't be %s", (S)); \
+
/* Misc. */
#define exit_java_complete_class() \
{ \
@@ -118,11 +122,25 @@ extern tree stabilize_reference PROTO ((tree));
(s1 [0]=='S' ? "Supertype" : "supertype") : \
(s1 [0] > 'A' ? "Type" : "type")))
+#define GET_REAL_TYPE(TYPE) \
+ (TREE_CODE (TYPE) == TREE_LIST ? TREE_PURPOSE (TYPE) : TYPE)
+
+#define GET_METHOD_NAME(METHOD) \
+ (TREE_CODE (DECL_NAME (METHOD)) == EXPR_WITH_FILE_LOCATION ? \
+ EXPR_WFL_NODE (DECL_NAME (METHOD)) : DECL_NAME (METHOD))
+
+/* Get TYPE name string, regardless whether TYPE is a class or an
+ array. */
+#define GET_TYPE_NAME(TYPE) \
+ (TREE_CODE (TYPE_NAME (TYPE)) == IDENTIFIER_NODE ? \
+ IDENTIFIER_POINTER (TYPE_NAME (TYPE)) : \
+ IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (TYPE))))
+
/* Pedantic warning on obsolete modifiers. Note: when cl is NULL,
flags was set artificially, such as for a interface method */
#define OBSOLETE_MODIFIER_WARNING(cl, flags, modifier, format, arg) \
{ \
- if ((cl) && ((flags) & (modifier))) \
+ if (flag_redundant && (cl) && ((flags) & (modifier))) \
parse_warning_context (cl, \
"Discouraged redundant use of `%s' modifier " \
"in declaration of " format, \
@@ -136,10 +154,10 @@ extern tree stabilize_reference PROTO ((tree));
TYPE_NAME (ptr) = name; \
}
-#define INCOMPLETE_TYPE_P(NODE) \
- ((TREE_CODE (NODE) == TREE_LIST) \
- && (TREE_CODE (TREE_PURPOSE (NODE)) == POINTER_TYPE) \
- && (TREE_TYPE (TREE_PURPOSE (NODE)) == NULL_TREE))
+#define INCOMPLETE_TYPE_P(NODE) \
+ ((TREE_CODE (NODE) == POINTER_TYPE) \
+ && !TREE_TYPE (NODE) \
+ && TREE_CODE (TYPE_NAME (NODE)) == IDENTIFIER_NODE)
/* Set the EMIT_LINE_NOTE flag of a EXPR_WLF to 1 if debug information
are requested. Works in the context of a parser rule. */
@@ -148,45 +166,60 @@ extern tree stabilize_reference PROTO ((tree));
EXPR_WFL_EMIT_LINE_NOTE (node) = 1, node : node)
/* Types classification, according to the JLS, section 4.2 */
-#define JFLOAT_TYPE_P(TYPE) (TREE_CODE ((TYPE)) == REAL_TYPE)
-#define JINTEGRAL_TYPE_P(TYPE) ((TREE_CODE ((TYPE)) == INTEGER_TYPE) \
- || (TREE_CODE ((TYPE)) == CHAR_TYPE))
-#define JNUMERIC_TYPE_P(TYPE) (JFLOAT_TYPE_P ((TYPE)) \
- || JINTEGRAL_TYPE_P ((TYPE)))
-#define JPRIMITIVE_TYPE_P(TYPE) (JNUMERIC_TYPE_P ((TYPE)) \
- || (TREE_CODE ((TYPE)) == BOOLEAN_TYPE))
+#define JFLOAT_TYPE_P(TYPE) (TYPE && TREE_CODE ((TYPE)) == REAL_TYPE)
+#define JINTEGRAL_TYPE_P(TYPE) ((TYPE) \
+ && (TREE_CODE ((TYPE)) == INTEGER_TYPE \
+ || TREE_CODE ((TYPE)) == CHAR_TYPE))
+#define JNUMERIC_TYPE_P(TYPE) ((TYPE) \
+ && (JFLOAT_TYPE_P ((TYPE)) \
+ || JINTEGRAL_TYPE_P ((TYPE))))
+#define JPRIMITIVE_TYPE_P(TYPE) ((TYPE) \
+ && (JNUMERIC_TYPE_P ((TYPE)) \
+ || TREE_CODE ((TYPE)) == BOOLEAN_TYPE))
+
+#define JBSC_TYPE_P(TYPE) ((TYPE) && (((TYPE) == byte_type_node) \
+ || ((TYPE) == short_type_node) \
+ || ((TYPE) == char_type_node)))
/* Not defined in the LRM */
-#define JSTRING_TYPE_P(TYPE) ((TYPE) == string_type_node || \
- (TREE_CODE (TYPE) == POINTER_TYPE && \
- TREE_TYPE (op1_type) == string_type_node))
-
-#define JREFERENCE_TYPE_P(TYPE) (TREE_CODE (TYPE) == RECORD_TYPE || \
- (TREE_CODE (TYPE) == POINTER_TYPE && \
- TREE_CODE (TREE_TYPE (TYPE)) == RECORD_TYPE))
+#define JSTRING_TYPE_P(TYPE) ((TYPE) \
+ && ((TYPE) == string_type_node || \
+ (TREE_CODE (TYPE) == POINTER_TYPE && \
+ TREE_TYPE (TYPE) == string_type_node)))
+#define JSTRING_P(NODE) ((NODE) \
+ && (TREE_CODE (NODE) == STRING_CST \
+ || IS_CRAFTED_STRING_BUFFER_P (NODE) \
+ || JSTRING_TYPE_P (TREE_TYPE (NODE))))
+
+#define JREFERENCE_TYPE_P(TYPE) ((TYPE) \
+ && (TREE_CODE (TYPE) == RECORD_TYPE \
+ || (TREE_CODE (TYPE) == POINTER_TYPE \
+ && TREE_CODE (TREE_TYPE (TYPE)) == \
+ RECORD_TYPE)))
+#define JNULLP_TYPE_P(TYPE) ((TYPE) && (TREE_CODE (TYPE) == POINTER_TYPE) \
+ && (TYPE) == TREE_TYPE (null_pointer_node))
/* Other predicate */
-#define DECL_P(NODE) (NODE && (TREE_CODE (NODE) == PARM_DECL \
- || TREE_CODE (NODE) == VAR_DECL \
- || TREE_CODE (NODE) == FIELD_DECL))
+#define JDECL_P(NODE) (NODE && (TREE_CODE (NODE) == PARM_DECL \
+ || TREE_CODE (NODE) == VAR_DECL \
+ || TREE_CODE (NODE) == FIELD_DECL))
#define TYPE_INTERFACE_P(TYPE) \
(CLASS_P (TYPE) && CLASS_INTERFACE (TYPE_NAME (TYPE)))
#define TYPE_CLASS_P(TYPE) (CLASS_P (TYPE) \
- && !CLASS_INTERFACE (TYPE_NAME (TYPE)) \
- && !TYPE_ARRAY_P (TYPE))
+ && !CLASS_INTERFACE (TYPE_NAME (TYPE)))
/* Standard error messages */
#define ERROR_CANT_CONVERT_TO_BOOLEAN(OPERATOR, NODE, TYPE) \
parse_error_context \
((OPERATOR), "Incompatible type for `%s'. Can't convert `%s' to " \
- "boolean", operator_string ((NODE)), lang_printable_name ((TYPE)))
+ "boolean", operator_string ((NODE)), lang_printable_name ((TYPE),0))
#define ERROR_CANT_CONVERT_TO_NUMERIC(OPERATOR, NODE, TYPE) \
parse_error_context \
((OPERATOR), "Incompatible type for `%s'. Can't convert `%s' to " \
- "numeric type", operator_string ((NODE)), lang_printable_name ((TYPE)))
+ "numeric type", operator_string ((NODE)), lang_printable_name ((TYPE), 0))
#define ERROR_CAST_NEEDED_TO_INTEGRAL(OPERATOR, NODE, TYPE) \
parse_error_context \
@@ -194,16 +227,16 @@ extern tree stabilize_reference PROTO ((tree));
"Incompatible type for `%s'. Explicit cast needed to convert " \
"`%s' to integral" : "Incompatible type for `%s'. Can't convert " \
"`%s' to integral"), operator_string ((NODE)), \
- lang_printable_name ((TYPE)))
+ lang_printable_name ((TYPE), 0))
#define ERROR_VARIABLE_NOT_INITIALIZED(WFL, V) \
parse_error_context \
- ((WFL), "Variable `%s' may not have been initialized", \
+ ((WFL), "Variable `%s' may not have been initialized", \
IDENTIFIER_POINTER (V))
-/* Definition for loop handling. This Java's own definition of a loop
- body. See parse.y for documentation. It's valid once you hold a
- loop's body (LOOP_EXPR_BODY) */
+/* Definition for loop handling. This is Java's own definition of a
+ loop body. See parse.y for documentation. It's valid once you hold
+ a loop's body (LOOP_EXPR_BODY) */
/* The loop main block is the one hold the condition and the loop body */
#define LOOP_EXPR_BODY_MAIN_BLOCK(NODE) TREE_OPERAND (NODE, 0)
@@ -252,6 +285,22 @@ extern tree stabilize_reference PROTO ((tree));
}
#define POP_LOOP() ctxp->current_loop = TREE_CHAIN (ctxp->current_loop)
+#define PUSH_EXCEPTIONS(E) \
+ currently_caught_type_list = \
+ tree_cons (NULL_TREE, (E), currently_caught_type_list);
+
+#define POP_EXCEPTIONS() \
+ currently_caught_type_list = TREE_CHAIN (currently_caught_type_list)
+
+/* Check that we're inside a try block. */
+#define IN_TRY_BLOCK_P() \
+ (currently_caught_type_list \
+ && ((TREE_VALUE (currently_caught_type_list) != \
+ DECL_FUNCTION_THROWS (current_function_decl)) \
+ || TREE_CHAIN (currently_caught_type_list)))
+
+/* Check that we have exceptions in E. */
+#define EXCEPTIONS_P(E) ((E) ? TREE_VALUE (E) : NULL_TREE)
/* Invocation modes, as returned by invocation_mode (). */
enum {
@@ -259,7 +308,7 @@ enum {
INVOKE_NONVIRTUAL,
INVOKE_SUPER,
INVOKE_INTERFACE,
- INVOKE_VIRTUAL,
+ INVOKE_VIRTUAL
};
/* We need the resolution stuff only if we compile jc1 */
@@ -308,6 +357,7 @@ enum jdep_code {
JDEP_TYPE, /* Patch a random tree node type,
without the need for any specific
actions */
+ JDEP_EXCEPTION /* Patch exceptions specified by `throws' */
};
typedef struct _jdep {
@@ -337,22 +387,17 @@ typedef struct _jdep {
#define JDEP_APPLY_PATCH(J,P) (*(J)->patch = (P))
#define JDEP_GET_PATCH(J) ((J)->patch)
#define JDEP_CHAIN(J) ((J)->next)
-#define JDEP_TO_RESOLVE(J) (TREE_PURPOSE ((J)->solv))
-#define JDEP_RESOLVED_DECL(J) ((J)->solv ? TREE_PURPOSE ((J)->solv):NULL_TREE)
-#define JDEP_RESOLVED(J, D) \
- { \
- TREE_PURPOSE ((J)->solv) = D; \
- TREE_VALUE ((J)->solv) = (J)->solv; \
- }
-#define JDEP_RESOLVED_P(J) (!(J)->solv || \
- TREE_VALUE ((J)->solv) == (J)->solv)
+#define JDEP_TO_RESOLVE(J) ((J)->solv)
+#define JDEP_RESOLVED_DECL(J) ((J)->solv)
+#define JDEP_RESOLVED(J, D) ((J)->solv = D)
+#define JDEP_RESOLVED_P(J) \
+ (!(J)->solv || TREE_CODE ((J)->solv) != POINTER_TYPE)
typedef struct _jdeplist {
jdep *first;
jdep *last;
struct _jdeplist *next;
} jdeplist;
-static jdeplist *reverse_jdep_list ();
#endif /* JC1_LITE */
@@ -371,16 +416,57 @@ static jdeplist *reverse_jdep_list ();
} \
}
+/* if TYPE can't be resolved, obtain something suitable for its
+ resolution (TYPE is saved in SAVE before being changed). and set
+ CHAIN to 1. Otherwise, type is set to something usable. CHAIN is
+ usually used to determine that a new DEP must be installed on TYPE.
+ Note that when compiling java.lang.Object, references to Object are
+ java.lang.Object. */
+#define SET_TYPE_FOR_RESOLUTION(TYPE, SAVE, CHAIN) \
+ { \
+ tree returned_type; \
+ (CHAIN) = 0; \
+ if (TREE_TYPE (ctxp->current_parsed_class) == object_type_node \
+ && TREE_CODE (TYPE) == EXPR_WITH_FILE_LOCATION \
+ && EXPR_WFL_NODE (TYPE) == unqualified_object_id_node) \
+ (TYPE) = object_type_node; \
+ else \
+ { \
+ if (unresolved_type_p (type, &returned_type)) \
+ { \
+ if (returned_type) \
+ (TYPE) = returned_type; \
+ else \
+ { \
+ (SAVE) = (TYPE); \
+ (TYPE) = obtain_incomplete_type (TYPE); \
+ CHAIN = 1; \
+ } \
+ } \
+ } \
+ }
+/* Promote a type if it won't be registered as a patch */
+#define PROMOTE_RECORD_IF_COMPLETE(TYPE, IS_INCOMPLETE) \
+ { \
+ if (!(IS_INCOMPLETE) && TREE_CODE (TYPE) == RECORD_TYPE) \
+ (TYPE) = promote_type (TYPE); \
+ }
+
/* Insert a DECL in the current block */
#define BLOCK_CHAIN_DECL(NODE) \
{ \
TREE_CHAIN ((NODE)) = \
- BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (current_function_decl)); \
- BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (current_function_decl)) = (NODE); \
+ BLOCK_EXPR_DECLS (GET_CURRENT_BLOCK (current_function_decl)); \
+ BLOCK_EXPR_DECLS (GET_CURRENT_BLOCK (current_function_decl)) = (NODE); \
}
-#define BLOCK_EXPR_DECLS(NODE) BLOCK_VARS(NODE)
-#define BLOCK_EXPR_BODY(NODE) BLOCK_SUBBLOCKS(NODE)
+/* Return the current block, either found in the body of the currently
+ declared function or in the current static block being defined. */
+#define GET_CURRENT_BLOCK(F) ((F) ? DECL_FUNCTION_BODY ((F)) : \
+ current_static_block)
+
+/* For an artificial BLOCK (created to house a local variable declaration not
+ at the start of an existing block), the parent block; otherwise NULL. */
#define BLOCK_EXPR_ORIGIN(NODE) BLOCK_ABSTRACT_ORIGIN(NODE)
/* Merge an other line to the source line number of a decl. Used to
@@ -391,6 +477,13 @@ static jdeplist *reverse_jdep_list ();
#define DECL_SOURCE_LINE_FIRST(DECL) (DECL_SOURCE_LINE(DECL) & 0x0000ffff)
#define DECL_SOURCE_LINE_LAST(DECL) (DECL_SOURCE_LINE(DECL) >> 16)
+/* Retrieve line/column from a WFL. */
+#define EXPR_WFL_GET_LINECOL(V,LINE,COL) \
+ { \
+ (LINE) = (V) >> 12; \
+ (COL) = (V) & 0xfff; \
+ }
+
/* Build a WFL for expression nodes */
#define BUILD_EXPR_WFL(NODE, WFL) \
build_expr_wfl ((NODE), input_filename, EXPR_WFL_LINENO ((WFL)), \
@@ -399,9 +492,11 @@ static jdeplist *reverse_jdep_list ();
#define EXPR_WFL_QUALIFICATION(WFL) TREE_OPERAND ((WFL), 1)
#define QUAL_WFL(NODE) TREE_PURPOSE (NODE)
#define QUAL_RESOLUTION(NODE) TREE_VALUE (NODE)
-#define QUAL_DECL_TYPE(NODE) \
+#define QUAL_DECL_TYPE(NODE) GET_SKIP_TYPE (NODE)
+
+#define GET_SKIP_TYPE(NODE) \
(TREE_CODE (TREE_TYPE (NODE)) == POINTER_TYPE ? \
- TREE_TYPE (TREE_TYPE (NODE)) : TREE_TYPE (NODE))
+ TREE_TYPE (TREE_TYPE (NODE)): TREE_TYPE (NODE))
/* Handy macros for the walk operation */
#define COMPLETE_CHECK_OP(NODE, N) \
@@ -413,7 +508,81 @@ static jdeplist *reverse_jdep_list ();
}
#define COMPLETE_CHECK_OP_0(NODE) COMPLETE_CHECK_OP(NODE, 0)
#define COMPLETE_CHECK_OP_1(NODE) COMPLETE_CHECK_OP(NODE, 1)
+#define COMPLETE_CHECK_OP_2(NODE) COMPLETE_CHECK_OP(NODE, 2)
+
+/* Building invocations: append(ARG) and StringBuffer(ARG) */
+#define BUILD_APPEND(ARG) \
+ ((JSTRING_TYPE_P (TREE_TYPE (ARG)) || JPRIMITIVE_TYPE_P (TREE_TYPE (ARG))) \
+ ? build_method_invocation (wfl_append, \
+ ARG ? build_tree_list (NULL, (ARG)) : NULL_TREE)\
+ : build_method_invocation (wfl_append, \
+ ARG ? build_tree_list (NULL, \
+ build1 (CONVERT_EXPR, \
+ object_type_node,\
+ (ARG))) \
+ : NULL_TREE))
+#define BUILD_STRING_BUFFER(ARG) \
+ build_new_invocation (wfl_string_buffer, \
+ (ARG ? build_tree_list (NULL, (ARG)) : NULL_TREE))
+
+/* For exception handling, build diverse function calls */
+#define BUILD_ASSIGN_EXCEPTION_INFO(WHERE, TO) \
+ { \
+ (WHERE) = build (MODIFY_EXPR, void_type_node, (TO), \
+ soft_exceptioninfo_call_node); \
+ TREE_SIDE_EFFECTS (WHERE) = 1; \
+ }
+
+#define BUILD_THROW(WHERE, WHAT) \
+ { \
+ (WHERE) = build (CALL_EXPR, void_type_node, \
+ build_address_of (throw_node), \
+ build_tree_list (NULL_TREE, (WHAT)), NULL_TREE); \
+ TREE_SIDE_EFFECTS ((WHERE)) = 1; \
+ }
+
+/* Set wfl_operator for the most accurate error location */
+#define SET_WFL_OPERATOR(WHICH, NODE, WFL) \
+ EXPR_WFL_LINECOL (WHICH) = \
+ (TREE_CODE (WFL) == EXPR_WITH_FILE_LOCATION ? \
+ EXPR_WFL_LINECOL (WFL) : EXPR_WFL_LINECOL (NODE))
+
+#define PATCH_METHOD_RETURN_ERROR() \
+ { \
+ if (ret_decl) \
+ *ret_decl = NULL_TREE; \
+ return error_mark_node; \
+ }
+
+/* Convenient macro to check. Assumes that CLASS is a CLASS_DECL. */
+#define CHECK_METHODS(CLASS) \
+ { \
+ if (CLASS_INTERFACE ((CLASS))) \
+ java_check_abstract_methods ((CLASS)); \
+ else \
+ java_check_regular_methods ((CLASS)); \
+ }
+
+/* Using and reseting the @deprecated tag flag */
+#define CHECK_DEPRECATED(DECL) \
+ { \
+ if (ctxp->deprecated) \
+ DECL_DEPRECATED (DECL) = 1; \
+ ctxp->deprecated = 0; \
+ }
+
+/* Register an import */
+#define REGISTER_IMPORT(WHOLE, NAME) \
+{ \
+ IS_A_SINGLE_IMPORT_CLASSFILE_NAME_P ((NAME)) = 1; \
+ node = build_tree_list ((WHOLE), (NAME)); \
+ TREE_CHAIN (node) = ctxp->import_list; \
+ ctxp->import_list = node; \
+}
+/* Macro to access the osb (opening square bracket) count */
+#define CURRENT_OSB(C) (C)->osb_number [(C)->osb_depth]
+
/* Parser context data structure. */
struct parser_ctxt {
@@ -428,18 +597,21 @@ struct parser_ctxt {
int first_ccb_indent1; /* First { at ident level 1 */
int last_ccb_indent1; /* Last } at ident level 1 */
int parser_ccb_indent; /* Keep track of {} indent, parser */
- int osb_number; /* Keep track of ['s */
+ int osb_depth; /* Current depth of [ in an expression */
+ int osb_limit; /* Limit of this depth */
+ int *osb_number; /* Keep track of ['s */
int minus_seen; /* Integral literal overflow */
- int lineno; /* Current lineno */
- int java_error_flag; /* Report error when true */
+ int lineno; /* Current lineno */
+ int java_error_flag; /* Report error when true */
+ int deprecated; /* @deprecated tag seen */
/* This section is defined only if we compile jc1 */
#ifndef JC1_LITE
- tree modifier_ctx [11]; /* WFL of modifiers */
+ tree modifier_ctx [11]; /* WFL of modifiers */
tree current_class; /* Current class */
tree current_function_decl; /* Current function decl, save/restore */
- JCF *current_jcf; /* CU jcf */
+ struct JCF *current_jcf; /* CU jcf */
int prevent_ese; /* Prevent expression statement error */
int class_err; /* Flag to report certain errors */
@@ -449,151 +621,60 @@ struct parser_ctxt {
tree package; /* Defined package ID */
+ /* Those tow list are saved accross file traversal */
tree incomplete_class; /* List of non-complete classes */
- tree current_parsed_class; /* Class currently parsed */
+ tree gclass_list; /* All classes seen from source code */
+
+ /* These two lists won't survive file traversal */
tree class_list; /* List of classes in a CU */
jdeplist *classd_list; /* Classe dependencies in a CU */
+ tree current_parsed_class; /* Class currently parsed */
+ tree current_parsed_class_un; /* Curr. parsed class unqualified name */
+
tree non_static_initialized; /* List of non static initialized fields */
tree static_initialized; /* List of static non final initialized */
tree import_list; /* List of import */
tree import_demand_list; /* List of import on demand */
- tree current_loop; /* List of the currently nested loops */
- tree current_labeled_block; /* List of currently nested
- labeled blocks. */
+ tree current_loop; /* List of the currently nested
+ loops/switches */
+ tree current_labeled_block; /* List of currently nested
+ labeled blocks. */
+
+ int pending_block; /* Pending block to close */
- int pending_block; /* Pending block to close */
+ int explicit_constructor_p; /* True when processing an explicit
+ constructor. This flag is used to trap
+ illegal argument usage during an
+ explicit constructor invocation. */
#endif /* JC1_LITE */
};
-/* Functions declarations */
#ifndef JC1_LITE
-static char *java_accstring_lookup PROTO ((int));
-static void parse_error PROTO ((char *));
-static void redefinition_error PROTO ((char *,tree, tree, tree));
-static void check_modifiers PROTO ((char *, int, int));
-static tree create_class PROTO ((int, tree, tree, tree));
-static tree create_interface PROTO ((int, tree, tree));
-static tree find_field PROTO ((tree, tree));
-static tree lookup_field_wrapper PROTO ((tree, tree));
-static int duplicate_declaration_error PROTO ((tree, tree, tree, tree));
-static void register_fields PROTO ((int, tree, tree));
-static tree parser_qualified_classname PROTO ((tree));
-static int parser_check_super PROTO ((tree, tree, tree));
-static int parser_check_super_interface PROTO ((tree, tree, tree));
-static void check_modifiers_consistency PROTO ((int));
-static tree lookup_cl PROTO ((tree));
-static tree lookup_java_method2 PROTO ((tree, tree, int));
-static tree method_header PROTO ((int, tree, tree, tree));
-static tree method_declarator PROTO ((tree, tree));
-static void parse_error_context VPROTO ((tree cl, char *msg, ...));
-static void parse_warning_context VPROTO ((tree cl, char *msg, ...));
-static void complete_class_report_errors PROTO ((jdep *));
-static int process_imports PROTO ((void));
-static void read_import_dir PROTO ((tree));
-static int find_in_imports_on_demand PROTO ((tree));
-static int find_in_imports PROTO ((tree));
-static int check_pkg_class_access PROTO ((tree, tree));
-static tree resolve_class PROTO ((tree, tree, tree));
-static tree do_resolve_class PROTO ((tree, tree, tree));
-static void declare_local_variables PROTO ((int, tree, tree));
-static void source_start_java_method PROTO ((tree));
-static void source_end_java_method PROTO ((void));
-static void expand_start_java_method PROTO ((tree));
-static tree find_name_in_single_imports PROTO ((tree));
-static void check_abstract_method_header PROTO ((tree));
-static tree lookup_java_interface_method2 PROTO ((tree, tree));
-static tree resolve_expression_name PROTO ((tree));
-static tree maybe_create_class_interface_decl PROTO ((tree, tree, tree));
-static int check_class_interface_creation PROTO ((int, int, tree, tree, tree, tree));
-static tree patch_method_invocation_stmt PROTO ((tree, tree, tree, int *));
-static int breakdown_qualified PROTO ((tree *, tree *, tree));
-static tree resolve_and_layout PROTO ((tree, tree));
-static tree resolve_no_layout PROTO ((tree, tree));
-static int identical_subpath_p PROTO ((tree, tree));
-static int invocation_mode PROTO ((tree, int));
-static tree refine_accessible_methods_list PROTO ((int, tree));
-static tree patch_invoke PROTO ((tree, tree, tree, tree));
-static tree lookup_method_invoke PROTO ((int, tree, tree, tree, tree));
-static tree register_incomplete_type PROTO ((int, tree, tree, tree));
-static tree obtain_incomplete_type PROTO ((tree));
-static tree java_complete_tree PROTO ((tree));
-static void java_complete_expand_method PROTO ((tree));
-static int unresolved_type_p PROTO ((tree, tree *));
-static void create_jdep_list PROTO ((struct parser_ctxt *));
-static tree build_expr_block PROTO ((tree, tree));
-static tree enter_block PROTO ((void));
-static tree exit_block PROTO ((void));
-static tree lookup_name_in_blocks PROTO ((tree));
-static void maybe_absorb_scoping_blocks PROTO ((void));
-static tree build_method_invocation PROTO ((tree, tree));
-static tree build_assignment PROTO ((int, int, tree, tree));
-static tree build_binop PROTO ((enum tree_code, int, tree, tree));
-static tree patch_assignment PROTO ((tree, tree, tree ));
-static tree patch_binop PROTO ((tree, tree, tree));
-static tree build_unaryop PROTO ((int, int, tree));
-static tree build_incdec PROTO ((int, int, tree, int));
-static tree patch_unaryop PROTO ((tree, tree));
-static tree build_cast PROTO ((int, tree, tree));
-static tree patch_cast PROTO ((tree, tree, tree));
-static int valid_ref_assignconv_cast_p PROTO ((tree, tree, int));
-static int can_cast_to_p PROTO ((tree, tree));
-static tree build_unresolved_array_type PROTO ((tree));
-static tree build_array_ref PROTO ((int, tree, tree));
-static tree patch_array_ref PROTO ((tree, tree, tree));
-static tree make_qualified_name PROTO ((tree, tree, int));
-static tree merge_qualified_name PROTO ((tree, tree));
-static tree make_qualified_primary PROTO ((tree, tree, int));
-static int resolve_qualified_expression_name PROTO ((tree, tree *, tree *, tree *));
-static void qualify_ambiguous_name PROTO ((tree));
-static void maybe_generate_clinit PROTO ((void));
-static tree resolve_field_access PROTO ((tree, tree *, tree *));
-static tree build_newarray_node PROTO ((tree, tree, int));
-static tree patch_newarray PROTO ((tree));
-static tree resolve_type_during_patch PROTO ((tree));
-static int not_initialized_as_it_should_p PROTO ((tree));
-static tree build_this PROTO ((int));
-static tree build_return PROTO ((int, tree));
-static tree patch_return PROTO ((tree));
-static tree maybe_access_field PROTO ((tree, tree, tree));
-static int complete_function_arguments PROTO ((tree));
-static int check_for_static_method_reference PROTO ((tree, tree, tree, tree, tree));
-static int not_accessible_p PROTO ((tree, tree, int));
-static int class_in_current_package PROTO ((tree));
-static tree build_if_else_statement PROTO ((int, tree, tree, tree));
-static tree patch_if_else_statement PROTO ((tree));
-static tree add_stmt_to_compound PROTO ((tree, tree, tree));
-static tree patch_exit_expr PROTO ((tree));
-static tree build_labeled_block PROTO ((int, tree, tree));
-static tree generate_labeled_block PROTO (());
-static tree complete_labeled_statement PROTO ((tree, tree));
-static tree build_bc_statement PROTO ((int, int, tree));
-static tree patch_bc_statement PROTO ((tree));
-static tree patch_loop_statement PROTO ((tree));
-static tree build_new_loop PROTO ((tree));
-static tree build_loop_body PROTO ((int, tree, int));
-static tree complete_loop_body PROTO ((int, tree, tree, int));
-static tree build_debugable_stmt PROTO ((int, tree));
-static tree complete_for_loop PROTO ((int, tree, tree, tree));
-
void safe_layout_class PROTO ((tree));
void java_complete_class PROTO ((void));
void java_check_circular_reference PROTO ((void));
void java_check_final PROTO ((void));
-void java_check_methods PROTO ((void));
void java_layout_classes PROTO ((void));
tree java_method_add_stmt PROTO ((tree, tree));
+void java_expand_switch PROTO ((tree));
+int java_report_errors PROTO (());
+extern tree do_resolve_class PROTO ((tree, tree, tree));
+#endif
char *java_get_line_col PROTO ((char *, int, int));
-#endif /* JC1_LITE */
+extern void reset_report PROTO ((void));
/* Always in use, no matter what you compile */
-
void java_push_parser_context PROTO ((void));
+void java_pop_parser_context PROTO ((int));
void java_init_lex PROTO ((void));
+extern void java_parser_context_save_global PROTO ((void));
+extern void java_parser_context_restore_global PROTO ((void));
int yyparse PROTO ((void));
+extern int java_parse PROTO ((void));
int yylex ();
void yyerror PROTO ((char *));
-
+extern void java_expand_classes PROTO ((void));
#endif
diff --git a/gcc/java/parse.y b/gcc/java/parse.y
index 50a467962fc..3792cba9691 100644
--- a/gcc/java/parse.y
+++ b/gcc/java/parse.y
@@ -1,6 +1,6 @@
/* Source code parsing and tree node generation for the GNU compiler
for the Java(TM) language.
- Copyright (C) 1997, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc.
Contributed by Alexandre Petit-Bianco (apbianco@cygnus.com)
This file is part of GNU CC.
@@ -35,7 +35,6 @@ Language Specification. J. Gosling, B. Joy, G. Steele. Addison Wesley
The following modifications were brought to the original grammar:
method_body: added the rule '| block SC_TK'
-constructor_declaration: added two rules to accept SC_TK.
static_initializer: added the rule 'static block SC_TK'.
Note: All the extra rules described above should go away when the
@@ -47,26 +46,201 @@ Some rules have been modified to support JDK1.1 inner classes
definitions and other extensions. */
%{
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <dirent.h>
-#ifdef __STDC__
-#include <stdarg.h>
-#else
-#include <varargs.h>
-#endif
-
#include "config.h"
+#include "system.h"
+#include <dirent.h>
#include "tree.h"
#include "rtl.h"
#include "obstack.h"
+#include "toplev.h"
#include "flags.h"
#include "java-tree.h"
#include "jcf.h"
#include "lex.h"
#include "parse.h"
#include "zipfile.h"
+#include "convert.h"
+#include "buffer.h"
+#include "xref.h"
+
+#ifndef DIR_SEPARATOR
+#define DIR_SEPARATOR '/'
+#endif
+
+/* Local function prototypes */
+static char *java_accstring_lookup PROTO ((int));
+static void classitf_redefinition_error PROTO ((char *,tree, tree, tree));
+static void variable_redefinition_error PROTO ((tree, tree, tree, int));
+static void check_modifiers PROTO ((char *, int, int));
+static tree create_class PROTO ((int, tree, tree, tree));
+static tree create_interface PROTO ((int, tree, tree));
+static tree find_field PROTO ((tree, tree));
+static tree lookup_field_wrapper PROTO ((tree, tree));
+static int duplicate_declaration_error_p PROTO ((tree, tree, tree));
+static void register_fields PROTO ((int, tree, tree));
+static tree parser_qualified_classname PROTO ((tree));
+static int parser_check_super PROTO ((tree, tree, tree));
+static int parser_check_super_interface PROTO ((tree, tree, tree));
+static void check_modifiers_consistency PROTO ((int));
+static tree lookup_cl PROTO ((tree));
+static tree lookup_java_method2 PROTO ((tree, tree, int));
+static tree method_header PROTO ((int, tree, tree, tree));
+static void fix_method_argument_names PROTO ((tree ,tree));
+static tree method_declarator PROTO ((tree, tree));
+static void parse_warning_context PVPROTO ((tree cl, const char *msg, ...))
+ ATTRIBUTE_PRINTF_2;
+static void issue_warning_error_from_context PROTO ((tree, const char *msg, va_list));
+static tree parse_jdk1_1_error PROTO ((char *));
+static void complete_class_report_errors PROTO ((jdep *));
+static int process_imports PROTO ((void));
+static void read_import_dir PROTO ((tree));
+static int find_in_imports_on_demand PROTO ((tree));
+static int find_in_imports PROTO ((tree));
+static int check_pkg_class_access PROTO ((tree, tree));
+static tree resolve_package PROTO ((tree, tree *));
+static tree lookup_package_type PROTO ((char *, int));
+static tree resolve_class PROTO ((tree, tree, tree));
+static void declare_local_variables PROTO ((int, tree, tree));
+static void source_start_java_method PROTO ((tree));
+static void source_end_java_method PROTO ((void));
+static void expand_start_java_method PROTO ((tree));
+static tree find_name_in_single_imports PROTO ((tree));
+static void check_abstract_method_header PROTO ((tree));
+static tree lookup_java_interface_method2 PROTO ((tree, tree));
+static tree resolve_expression_name PROTO ((tree, tree *));
+static tree maybe_create_class_interface_decl PROTO ((tree, tree, tree));
+static int check_class_interface_creation PROTO ((int, int, tree,
+ tree, tree, tree));
+static tree patch_method_invocation PROTO ((tree, tree, tree,
+ int *, tree *));
+static int breakdown_qualified PROTO ((tree *, tree *, tree));
+static tree resolve_and_layout PROTO ((tree, tree));
+static tree resolve_no_layout PROTO ((tree, tree));
+static int invocation_mode PROTO ((tree, int));
+static tree find_applicable_accessible_methods_list PROTO ((int, tree,
+ tree, tree));
+static void search_applicable_methods_list PROTO ((int, tree, tree, tree,
+ tree *, tree *));
+static tree find_most_specific_methods_list PROTO ((tree));
+static int argument_types_convertible PROTO ((tree, tree));
+static tree patch_invoke PROTO ((tree, tree, tree));
+static tree lookup_method_invoke PROTO ((int, tree, tree, tree, tree));
+static tree register_incomplete_type PROTO ((int, tree, tree, tree));
+static tree obtain_incomplete_type PROTO ((tree));
+static tree java_complete_lhs PROTO ((tree));
+static tree java_complete_tree PROTO ((tree));
+static void java_complete_expand_method PROTO ((tree));
+static int unresolved_type_p PROTO ((tree, tree *));
+static void create_jdep_list PROTO ((struct parser_ctxt *));
+static tree build_expr_block PROTO ((tree, tree));
+static tree enter_block PROTO ((void));
+static tree enter_a_block PROTO ((tree));
+static tree exit_block PROTO ((void));
+static tree lookup_name_in_blocks PROTO ((tree));
+static void maybe_absorb_scoping_blocks PROTO ((void));
+static tree build_method_invocation PROTO ((tree, tree));
+static tree build_new_invocation PROTO ((tree, tree));
+static tree build_assignment PROTO ((int, int, tree, tree));
+static tree build_binop PROTO ((enum tree_code, int, tree, tree));
+static int check_final_assignment PROTO ((tree ,tree));
+static tree patch_assignment PROTO ((tree, tree, tree ));
+static tree patch_binop PROTO ((tree, tree, tree));
+static tree build_unaryop PROTO ((int, int, tree));
+static tree build_incdec PROTO ((int, int, tree, int));
+static tree patch_unaryop PROTO ((tree, tree));
+static tree build_cast PROTO ((int, tree, tree));
+static tree build_null_of_type PROTO ((tree));
+static tree patch_cast PROTO ((tree, tree));
+static int valid_ref_assignconv_cast_p PROTO ((tree, tree, int));
+static int valid_builtin_assignconv_identity_widening_p PROTO ((tree, tree));
+static int valid_cast_to_p PROTO ((tree, tree));
+static int valid_method_invocation_conversion_p PROTO ((tree, tree));
+static tree try_builtin_assignconv PROTO ((tree, tree, tree));
+static tree try_reference_assignconv PROTO ((tree, tree));
+static tree build_unresolved_array_type PROTO ((tree));
+static tree build_array_from_name PROTO ((tree, tree, tree, tree *));
+static tree build_array_ref PROTO ((int, tree, tree));
+static tree patch_array_ref PROTO ((tree));
+static tree make_qualified_name PROTO ((tree, tree, int));
+static tree merge_qualified_name PROTO ((tree, tree));
+static tree make_qualified_primary PROTO ((tree, tree, int));
+static int resolve_qualified_expression_name PROTO ((tree, tree *,
+ tree *, tree *));
+static void qualify_ambiguous_name PROTO ((tree));
+static void maybe_generate_clinit PROTO ((void));
+static tree resolve_field_access PROTO ((tree, tree *, tree *));
+static tree build_newarray_node PROTO ((tree, tree, int));
+static tree patch_newarray PROTO ((tree));
+static tree resolve_type_during_patch PROTO ((tree));
+static tree build_this PROTO ((int));
+static tree build_return PROTO ((int, tree));
+static tree patch_return PROTO ((tree));
+static tree maybe_access_field PROTO ((tree, tree, tree));
+static int complete_function_arguments PROTO ((tree));
+static int check_for_static_method_reference PROTO ((tree, tree, tree, tree, tree));
+static int not_accessible_p PROTO ((tree, tree, int));
+static void check_deprecation PROTO ((tree, tree));
+static int class_in_current_package PROTO ((tree));
+static tree build_if_else_statement PROTO ((int, tree, tree, tree));
+static tree patch_if_else_statement PROTO ((tree));
+static tree add_stmt_to_compound PROTO ((tree, tree, tree));
+static tree add_stmt_to_block PROTO ((tree, tree, tree));
+static tree patch_exit_expr PROTO ((tree));
+static tree build_labeled_block PROTO ((int, tree));
+static tree finish_labeled_statement PROTO ((tree, tree));
+static tree build_bc_statement PROTO ((int, int, tree));
+static tree patch_bc_statement PROTO ((tree));
+static tree patch_loop_statement PROTO ((tree));
+static tree build_new_loop PROTO ((tree));
+static tree build_loop_body PROTO ((int, tree, int));
+static tree finish_loop_body PROTO ((int, tree, tree, int));
+static tree build_debugable_stmt PROTO ((int, tree));
+static tree finish_for_loop PROTO ((int, tree, tree, tree));
+static tree patch_switch_statement PROTO ((tree));
+static tree string_constant_concatenation PROTO ((tree, tree));
+static tree build_string_concatenation PROTO ((tree, tree));
+static tree patch_string_cst PROTO ((tree));
+static tree patch_string PROTO ((tree));
+static tree build_try_statement PROTO ((int, tree, tree));
+static tree build_try_finally_statement PROTO ((int, tree, tree));
+static tree patch_try_statement PROTO ((tree));
+static tree patch_synchronized_statement PROTO ((tree, tree));
+static tree patch_throw_statement PROTO ((tree, tree));
+static void check_thrown_exceptions PROTO ((int, tree));
+static int check_thrown_exceptions_do PROTO ((tree));
+static void purge_unchecked_exceptions PROTO ((tree));
+static void check_throws_clauses PROTO ((tree, tree, tree));
+static void finish_method_declaration PROTO ((tree));
+static tree build_super_invocation PROTO (());
+static int verify_constructor_circularity PROTO ((tree, tree));
+static char *constructor_circularity_msg PROTO ((tree, tree));
+static tree build_this_super_qualified_invocation PROTO ((int, tree, tree,
+ int, int));
+static char *get_printable_method_name PROTO ((tree));
+static tree patch_conditional_expr PROTO ((tree, tree, tree));
+static void maybe_generate_finit PROTO (());
+static void fix_constructors PROTO ((tree));
+static int verify_constructor_super PROTO (());
+static tree create_artificial_method PROTO ((tree, int, tree, tree, tree));
+static void start_artificial_method_body PROTO ((tree));
+static void end_artificial_method_body PROTO ((tree));
+static int check_method_redefinition PROTO ((tree, tree));
+static int reset_method_name PROTO ((tree));
+static void java_check_regular_methods PROTO ((tree));
+static void java_check_abstract_methods PROTO ((tree));
+static tree maybe_build_primttype_type_ref PROTO ((tree, tree));
+static void unreachable_stmt_error PROTO ((tree));
+static tree find_expr_with_wfl PROTO ((tree));
+static void missing_return_error PROTO ((tree));
+static tree build_new_array_init PROTO ((int, tree));
+static tree patch_new_array_init PROTO ((tree, tree));
+static tree maybe_build_array_element_wfl PROTO ((tree));
+static int array_constructor_check_entry PROTO ((tree, tree));
+static char *purify_type_name PROTO ((char *));
+static tree patch_initialized_static_field PROTO ((tree));
+static tree fold_constant_for_init PROTO ((tree, tree));
+static tree strip_out_static_field_access_decl PROTO ((tree));
+static jdeplist *reverse_jdep_list PROTO ((struct parser_ctxt *));
/* Number of error found so far. */
int java_error_count;
@@ -76,6 +250,9 @@ int java_warning_count;
/* The current parser context */
static struct parser_ctxt *ctxp;
+/* List of things that were anlyzed for which code will be generated */
+static struct parser_ctxt *ctxp_for_generation = NULL;
+
/* binop_lookup maps token to tree_code. It is used where binary
operations are involved and required by the parser. RDIV_EXPR
covers both integral/floating point division. The code is changed
@@ -95,10 +272,29 @@ static enum tree_code binop_lookup[19] =
/* Fake WFL used to report error message. It is initialized once if
needed and reused with it's location information is overriden. */
-static tree wfl_operator = NULL_TREE;
+tree wfl_operator = NULL_TREE;
/* The "$L" identifier we use to create labels. */
-static tree label_id;
+static tree label_id = NULL_TREE;
+
+/* The "StringBuffer" identifier used for the String `+' operator. */
+static tree wfl_string_buffer = NULL_TREE;
+
+/* The "append" identifier used for String `+' operator. */
+static tree wfl_append = NULL_TREE;
+
+/* The "toString" identifier used for String `+' operator. */
+static tree wfl_to_string = NULL_TREE;
+
+/* The "java.lang" import qualified name. */
+static tree java_lang_id = NULL_TREE;
+
+/* The "java.lang.Cloneable" qualified name. */
+static tree java_lang_cloneable = NULL_TREE;
+
+/* Context and flag for static blocks */
+static tree current_static_block = NULL_TREE;
+
%}
%union {
@@ -111,6 +307,10 @@ static tree label_id;
int value;
}
+%{
+#include "lex.c"
+%}
+
%pure_parser
/* Things defined here have to match the order of what's in the
@@ -183,18 +383,17 @@ static tree label_id;
abstract_method_declaration interface_type_list
%type <node> class_body_declaration class_member_declaration
static_initializer constructor_declaration block
-%type <node> class_body_declarations
+%type <node> class_body_declarations constructor_header
%type <node> class_or_interface_type class_type class_type_list
constructor_declarator explicit_constructor_invocation
-%type <node> dim_expr dim_exprs this_or_super
+%type <node> dim_expr dim_exprs this_or_super throws
%type <node> variable_declarator_id variable_declarator
variable_declarators variable_initializer
- variable_initializers
+ variable_initializers constructor_body
+ array_initializer
-%type <node> class_body
-%type <node> block_statement local_variable_declaration_statement
- block_statements local_variable_declaration
+%type <node> class_body block_end
%type <node> statement statement_without_trailing_substatement
labeled_statement if_then_statement label_decl
if_then_else_statement while_statement for_statement
@@ -219,6 +418,9 @@ static tree label_id;
conditional_expression assignment_expression
left_hand_side assignment for_header for_begin
constant_expression do_statement_begin empty_statement
+ switch_statement synchronized_statement throw_statement
+ try_statement switch_expression switch_block
+ catches catch_clause catch_clause_parameter finally
%type <node> return_statement break_statement continue_statement
%type <operator> ASSIGN_TK MULT_ASSIGN_TK DIV_ASSIGN_TK
@@ -229,9 +431,10 @@ static tree label_id;
%token <operator> EQ_TK GTE_TK ZRS_TK SRS_TK GT_TK LTE_TK LS_TK
%token <operator> BOOL_AND_TK AND_TK BOOL_OR_TK OR_TK INCR_TK PLUS_TK
%token <operator> DECR_TK MINUS_TK MULT_TK DIV_TK XOR_TK REM_TK NEQ_TK
-%token <operator> NEG_TK REL_QM_TK REL_CL_TK NOT_TK LT_TK
-%token <operator> OP_TK OSB_TK DOT_TK
-%type <operator> THIS_TK SUPER_TK RETURN_TK BREAK_TK CONTINUE_TK
+%token <operator> NEG_TK REL_QM_TK REL_CL_TK NOT_TK LT_TK OCB_TK
+%token <operator> OP_TK OSB_TK DOT_TK THROW_TK INSTANCEOF_TK
+%type <operator> THIS_TK SUPER_TK RETURN_TK BREAK_TK CONTINUE_TK
+%type <operator> CASE_TK DEFAULT_TK TRY_TK CATCH_TK SYNCHRONIZED_TK
%type <node> method_body
@@ -390,14 +593,11 @@ single_type_import_declaration:
($2, "Ambiguous class: `%s' and `%s'",
IDENTIFIER_POINTER (name),
IDENTIFIER_POINTER (err));
+ else
+ REGISTER_IMPORT ($2, last_name)
}
else
- {
- IS_A_SINGLE_IMPORT_CLASSFILE_NAME_P (last_name) = 1;
- node = build_tree_list ($2, last_name);
- TREE_CHAIN (node) = ctxp->import_list;
- ctxp->import_list = node;
- }
+ REGISTER_IMPORT ($2, last_name);
}
| IMPORT_TK error
{yyerror ("Missing name"); RECOVER;}
@@ -409,14 +609,14 @@ type_import_on_demand_declaration:
IMPORT_TK name DOT_TK MULT_TK SC_TK
{
tree name = EXPR_WFL_NODE ($2);
- tree node = build_tree_list ($2, NULL_TREE);
- if (!IS_AN_IMPORT_ON_DEMAND_P (name))
+ /* Don't import java.lang.* twice. */
+ if (name != java_lang_id)
{
+ tree node = build_tree_list ($2, NULL_TREE);
read_import_dir ($2);
- IS_AN_IMPORT_ON_DEMAND_P (name) = 1;
+ TREE_CHAIN (node) = ctxp->import_demand_list;
+ ctxp->import_demand_list = node;
}
- TREE_CHAIN (node) = ctxp->import_demand_list;
- ctxp->import_demand_list = node;
}
| IMPORT_TK name DOT_TK error
{yyerror ("'*' expected"); RECOVER;}
@@ -427,6 +627,7 @@ type_import_on_demand_declaration:
type_declaration:
class_declaration
{
+ maybe_generate_finit ();
maybe_generate_clinit ();
$$ = $1;
}
@@ -481,7 +682,10 @@ class_declaration:
| CLASS_TK error
{yyerror ("Missing class name"); RECOVER;}
| CLASS_TK identifier error
- {if (!ctxp->class_err) yyerror ("'{' expected"); DRECOVER(class1);}
+ {
+ if (!ctxp->class_err) yyerror ("'{' expected");
+ DRECOVER(class1);
+ }
| modifiers CLASS_TK identifier error
{if (!ctxp->class_err) yyerror ("'{' expected"); RECOVER;}
;
@@ -539,13 +743,18 @@ class_body_declaration:
| static_initializer
| constructor_declaration
| block /* Added, JDK1.1, instance initializer */
+ { $$ = parse_jdk1_1_error ("instance initializer"); }
;
class_member_declaration:
field_declaration
+| field_declaration SC_TK
+ { $$ = $1; }
| method_declaration
| class_declaration /* Added, JDK1.1 inner classes */
+ { $$ = parse_jdk1_1_error ("inner classe declaration"); }
| interface_declaration /* Added, JDK1.1 inner classes */
+ { $$ = parse_jdk1_1_error ("inner interface declaration"); }
;
/* 19.8.2 Productions from 8.3: Field Declarations */
@@ -554,8 +763,6 @@ field_declaration:
{ register_fields (0, $1, $2); }
| modifiers type variable_declarators SC_TK
{
- int acc_count = 0;
-
check_modifiers
("Illegal modifier `%s' for field declaration",
$1, FIELD_MODIFIERS);
@@ -600,9 +807,7 @@ variable_declarator:
variable_declarator_id:
identifier
| variable_declarator_id OSB_TK CSB_TK
- {
- $$ = NULL; /* FIXME */
- }
+ { $$ = build_unresolved_array_type ($1); }
| identifier error
{yyerror ("Invalid declaration"); DRECOVER(vdi);}
| variable_declarator_id OSB_TK error
@@ -614,7 +819,6 @@ variable_declarator_id:
variable_initializer:
expression
| array_initializer
- { $$ = NULL; }
;
/* 19.8.3 Productions from 8.4: Method Declarations */
@@ -625,31 +829,20 @@ method_declaration:
source_start_java_method (current_function_decl);
}
method_body
- {
- BLOCK_EXPR_BODY
- (DECL_FUNCTION_BODY (current_function_decl)) = $3;
- maybe_absorb_scoping_blocks ();
- exit_block (); /* Exit function's body. */
-
- /* Merge last line of the function with first line,
- directly in the function decl. It will be used to
- emit correct debug info. */
- DECL_SOURCE_LINE_MERGE (current_function_decl,
- ctxp->last_ccb_indent1);
- }
+ { finish_method_declaration ($3); }
| method_header error
{YYNOT_TWICE yyerror ("'{' expected"); RECOVER;}
;
method_header:
type method_declarator throws
- { $$ = method_header (0, $1, $2, NULL); }
+ { $$ = method_header (0, $1, $2, $3); }
| VOID_TK method_declarator throws
- { $$ = method_header (0, void_type_node, $2, NULL); }
+ { $$ = method_header (0, void_type_node, $2, $3); }
| modifiers type method_declarator throws
- { $$ = method_header ($1, $2, $3, NULL); }
+ { $$ = method_header ($1, $2, $3, $4); }
| modifiers VOID_TK method_declarator throws
- { $$ = method_header ($1, void_type_node, $3, NULL); }
+ { $$ = method_header ($1, void_type_node, $3, $4); }
| type error
{RECOVER;}
| modifiers type error
@@ -672,8 +865,12 @@ method_declarator:
{ $$ = method_declarator ($1, $3); }
| method_declarator OSB_TK CSB_TK
{
- /* Issue a warning here: obsolete declaration. FIXME */
- $$ = NULL; /* FIXME */
+ EXPR_WFL_LINECOL (wfl_operator) = $2.location;
+ TREE_PURPOSE ($1) =
+ build_unresolved_array_type (TREE_PURPOSE ($1));
+ parse_warning_context
+ (wfl_operator,
+ "Discouraged form of returned type specification");
}
| identifier OP_TK error
{yyerror ("')' expected"); DRECOVER(method_declarator);}
@@ -700,11 +897,8 @@ formal_parameter:
{
$$ = build_tree_list ($2, $1);
}
-| modifiers type variable_declarator_id /* Added, JDK1.1 final locals */
- {
- SOURCE_FRONTEND_DEBUG (("Modifiers: %d", $1));
- $$ = NULL; /* FIXME */
- }
+| modifiers type variable_declarator_id /* Added, JDK1.1 final parms */
+ { $$ = parse_jdk1_1_error ("final parameters"); }
| type error
{yyerror ("Missing identifier"); RECOVER;}
| modifiers type error
@@ -715,14 +909,18 @@ formal_parameter:
;
throws:
+ { $$ = NULL_TREE; }
| THROWS_TK class_type_list
+ { $$ = $2; }
| THROWS_TK error
{yyerror ("Missing class type term"); RECOVER;}
;
class_type_list:
class_type
+ { $$ = build_tree_list ($1, $1); }
| class_type_list C_TK class_type
+ { $$ = tree_cons ($3, $3, $1); }
| class_type_list C_TK error
{yyerror ("Missing class type term"); RECOVER;}
;
@@ -738,11 +936,13 @@ method_body:
static_initializer:
static block
{
- RULE ("STATIC_INITIALIZER");
+ TREE_CHAIN ($2) = ctxp->static_initialized;
+ ctxp->static_initialized = $2;
}
| static block SC_TK /* Shouldn't be here. FIXME */
{
- RULE ("STATIC_INITIALIZER");
+ TREE_CHAIN ($2) = ctxp->static_initialized;
+ ctxp->static_initialized = $2;
}
;
@@ -754,68 +954,79 @@ static: /* Test lval.sub_token here */
;
/* 19.8.5 Productions from 8.6: Constructor Declarations */
-/* NOTE FOR FURTHER WORK ON CONSTRUCTORS:
- - If a forbidded modifier is found, the the error is either the use of
- a forbidded modifier for a constructor OR bogus attempt to declare a
- method without having specified the return type. FIXME */
constructor_declaration:
- constructor_declarator throws constructor_body
- {
- RULE ("CONSTRUCTOR_DECLARATION");
- }
-| modifiers constructor_declarator throws constructor_body
+ constructor_header
{
- SOURCE_FRONTEND_DEBUG (("Modifiers: %d", $1));
- RULE ("CONSTRUCTOR_DECLARATION (modifier)");
- }
-/* extra SC_TK, FIXME */
-| constructor_declarator throws constructor_body SC_TK
- {
- RULE ("CONSTRUCTOR_DECLARATION");
- }
-/* extra SC_TK, FIXME */
-| modifiers constructor_declarator throws constructor_body SC_TK
- {
- SOURCE_FRONTEND_DEBUG (("Modifiers: %d", $1));
- RULE ("CONSTRUCTOR_DECLARATION (modifier)");
+ current_function_decl = $1;
+ source_start_java_method (current_function_decl);
}
-/* I'm not happy with the SC_TK addition. It isn't in the grammer and should
- probably be matched by and empty statement. But it doesn't work. FIXME */
+ constructor_body
+ { finish_method_declaration ($3); }
+;
+
+constructor_header:
+ constructor_declarator throws
+ { $$ = method_header (0, NULL_TREE, $1, $2); }
+| modifiers constructor_declarator throws
+ { $$ = method_header ($1, NULL_TREE, $2, $3); }
;
constructor_declarator:
simple_name OP_TK CP_TK
+ { $$ = method_declarator ($1, NULL_TREE); }
| simple_name OP_TK formal_parameter_list CP_TK
+ { $$ = method_declarator ($1, $3); }
;
constructor_body:
- OCB_TK CCB_TK
-| OCB_TK explicit_constructor_invocation CCB_TK
-| OCB_TK block_statements CCB_TK
-| OCB_TK explicit_constructor_invocation block_statements CCB_TK
+ /* Unlike regular method, we always need a complete (empty)
+ body so we can safely perform all the required code
+ addition (super invocation and field initialization) */
+ block_begin block_end
+ {
+ BLOCK_EXPR_BODY ($2) = empty_stmt_node;
+ $$ = $2;
+ }
+| block_begin explicit_constructor_invocation block_end
+ { $$ = $3; }
+| block_begin block_statements block_end
+ { $$ = $3; }
+| block_begin explicit_constructor_invocation block_statements block_end
+ { $$ = $4; }
;
/* Error recovery for that rule moved down expression_statement: rule. */
explicit_constructor_invocation:
this_or_super OP_TK CP_TK SC_TK
+ {
+ $$ = build_method_invocation ($1, NULL_TREE);
+ $$ = build_debugable_stmt (EXPR_WFL_LINECOL ($1), $$);
+ $$ = java_method_add_stmt (current_function_decl, $$);
+ }
| this_or_super OP_TK argument_list CP_TK SC_TK
+ {
+ $$ = build_method_invocation ($1, $3);
+ $$ = build_debugable_stmt (EXPR_WFL_LINECOL ($1), $$);
+ $$ = java_method_add_stmt (current_function_decl, $$);
+ }
/* Added, JDK1.1 inner classes. Modified because the rule
'primary' couldn't work. */
| name DOT_TK SUPER_TK OP_TK argument_list CP_TK SC_TK
+ {$$ = parse_jdk1_1_error ("explicit constructor invocation"); }
| name DOT_TK SUPER_TK OP_TK CP_TK SC_TK
- {RULE ("explicit_constructor_invocation (X.super)");}
+ {$$ = parse_jdk1_1_error ("explicit constructor invocation"); }
;
this_or_super: /* Added, simplifies error diagnostics */
THIS_TK
{
- tree wfl = build_wfl_node (this_identifier_node, input_filename, 0, 0);
+ tree wfl = build_wfl_node (this_identifier_node);
EXPR_WFL_LINECOL (wfl) = $1.location;
$$ = wfl;
}
| SUPER_TK
{
- tree wfl = build_wfl_node (super_identifier_node, input_filename, 0, 0);
+ tree wfl = build_wfl_node (super_identifier_node);
EXPR_WFL_LINECOL (wfl) = $1.location;
$$ = wfl;
}
@@ -849,9 +1060,9 @@ interface_declaration:
$$ = $6;
}
| INTERFACE_TK identifier error
- {yyerror ("(here)'{' expected"); RECOVER;}
+ {yyerror ("'{' expected"); RECOVER;}
| modifiers INTERFACE_TK identifier error
- {yyerror ("(there)'{' expected"); RECOVER;}
+ {yyerror ("'{' expected"); RECOVER;}
;
extends_interfaces:
@@ -887,7 +1098,9 @@ interface_member_declaration:
constant_declaration
| abstract_method_declaration
| class_declaration /* Added, JDK1.1 inner classes */
+ { $$ = parse_jdk1_1_error ("inner class declaration"); }
| interface_declaration /* Added, JDK1.1 inner classes */
+ { $$ = parse_jdk1_1_error ("inner interface declaration"); }
;
constant_declaration:
@@ -907,26 +1120,23 @@ abstract_method_declaration:
/* 19.10 Productions from 10: Arrays */
array_initializer:
OCB_TK CCB_TK
- {
- RULE ("ARRAY_INITIALIZER (empty)");
- }
+ { $$ = build_new_array_init ($1.location, NULL_TREE); }
| OCB_TK variable_initializers CCB_TK
- {
- RULE ("ARRAY_INITIALIZER (variable)");
- }
-| OCB_TK C_TK CCB_TK
- {
- RULE ("ARRAY_INITIALIZER (,)");
- }
+ { $$ = build_new_array_init ($1.location, $2); }
| OCB_TK variable_initializers C_TK CCB_TK
- {
- RULE ("ARRAY_INITIALIZER (variable, ,)");
- }
+ { $$ = build_new_array_init ($1.location, $2); }
;
variable_initializers:
variable_initializer
+ {
+ $$ = tree_cons (maybe_build_array_element_wfl ($1),
+ $1, NULL_TREE);
+ }
| variable_initializers C_TK variable_initializer
+ {
+ $$ = tree_cons (maybe_build_array_element_wfl ($3), $3, $1);
+ }
| variable_initializers C_TK error
{yyerror ("Missing term"); RECOVER;}
;
@@ -934,10 +1144,17 @@ variable_initializers:
/* 19.11 Production from 14: Blocks and Statements */
block:
OCB_TK CCB_TK
- { $$ = size_zero_node; }
-| OCB_TK
+ { $$ = empty_stmt_node; }
+| block_begin block_statements block_end
+ { $$ = $3; }
+;
+
+block_begin:
+ OCB_TK
{ enter_block (); }
- block_statements
+;
+
+block_end:
CCB_TK
{
maybe_absorb_scoping_blocks ();
@@ -953,8 +1170,9 @@ block_statements:
block_statement:
local_variable_declaration_statement
| statement
- { $$ = java_method_add_stmt (current_function_decl, $1); }
+ { java_method_add_stmt (current_function_decl, $1); }
| class_declaration /* Added, JDK1.1 inner classes */
+ { parse_jdk1_1_error ("inner class declaration"); }
;
local_variable_declaration_statement:
@@ -971,13 +1189,9 @@ local_variable_declaration:
statement:
statement_without_trailing_substatement
| labeled_statement
- { RULE ("STATEMENT (labeled)"); }
| if_then_statement
- { RULE ("STATEMENT (if-then)"); }
| if_then_else_statement
- { RULE ("STATEMENT (if-then-else)"); }
| while_statement
- { RULE ("STATEMENT (while)"); }
| for_statement
{
/* If the for loop is unlabeled, we must return the
@@ -991,49 +1205,35 @@ statement:
statement_nsi:
statement_without_trailing_substatement
| labeled_statement_nsi
- { RULE ("NSI STATEMENT (labeled)"); }
| if_then_else_statement_nsi
- { RULE ("NSI STATEMENT (if-then-else)"); }
| while_statement_nsi
- { RULE ("NSI STATEMENT (while)"); }
| for_statement_nsi
- { RULE ("NSI STATEMENT (for)"); }
;
statement_without_trailing_substatement:
block
- { RULE ("STATEMENT (block)"); }
| empty_statement
- { RULE ("STATEMENT (empty)"); }
| expression_statement
- { RULE ("STATEMENT (expression)"); }
| switch_statement
- { RULE ("STATEMENT (switch)"); }
| do_statement
- { RULE ("STATEMENT (do)"); }
| break_statement
- { RULE ("STATEMENT (break)"); }
| continue_statement
- { RULE ("STATEMENT (continue)"); }
| return_statement
| synchronized_statement
- { RULE ("STATEMENT (synchronized)"); }
| throw_statement
- { RULE ("STATEMENT (throw)"); }
| try_statement
- { RULE ("STATEMENT (try)"); }
;
empty_statement:
SC_TK
- { $$ = size_zero_node; }
+ { $$ = empty_stmt_node; }
;
label_decl:
identifier REL_CL_TK
{
$$ = build_labeled_block (EXPR_WFL_LINECOL ($1),
- EXPR_WFL_NODE ($1), $1);
+ EXPR_WFL_NODE ($1));
pushlevel (2);
push_labeled_block ($$);
PUSH_LABELED_BLOCK ($$);
@@ -1042,22 +1242,14 @@ label_decl:
labeled_statement:
label_decl statement
- {
- $$ = complete_labeled_statement ($1, $2);
- pop_labeled_block ();
- POP_LABELED_BLOCK ();
- }
+ { $$ = finish_labeled_statement ($1, $2); }
| identifier error
{yyerror ("':' expected"); RECOVER;}
;
labeled_statement_nsi:
label_decl statement_nsi
- {
- $$ = complete_labeled_statement ($1, $2);
- pop_labeled_block ();
- POP_LABELED_BLOCK ();
- }
+ { $$ = finish_labeled_statement ($1, $2); }
;
/* We concentrate here a bunch of error handling rules that we couldn't write
@@ -1093,11 +1285,19 @@ expression_statement:
| this_or_super OP_TK error
{yyerror ("')' expected"); RECOVER;}
| this_or_super OP_TK CP_TK error
- {yyerror ("';' expected"); RECOVER;}
+ {
+ yyerror ("Constructor invocation must be first "
+ "thing in a constructor");
+ RECOVER;
+ }
| this_or_super OP_TK argument_list error
{yyerror ("')' expected"); RECOVER;}
| this_or_super OP_TK argument_list CP_TK error
- {yyerror ("';' expected"); RECOVER;}
+ {
+ yyerror ("Constructor invocation must be first "
+ "thing in a constructor");
+ RECOVER;
+ }
| name DOT_TK SUPER_TK error
{yyerror ("'(' expected"); RECOVER;}
| name DOT_TK SUPER_TK OP_TK error
@@ -1113,31 +1313,19 @@ expression_statement:
statement_expression:
assignment
| pre_increment_expression
- {
- RULE ("++INCREMENT");
- }
| pre_decrement_expression
- {
- RULE ("--DECREMENT");
- }
| post_increment_expression
- {
- RULE ("INCREMENT++");
- }
| post_decrement_expression
- {
- RULE ("DECREMENT--");
- }
| method_invocation
| class_instance_creation_expression
- {
- RULE ("INSTANCE CREATION");
- }
;
if_then_statement:
IF_TK OP_TK expression CP_TK statement
- { $$ = build_if_else_statement ($2.location, $3, $5, NULL_TREE); }
+ {
+ $$ = build_if_else_statement ($2.location, $3,
+ $5, NULL_TREE);
+ }
| IF_TK error
{yyerror ("'(' expected"); RECOVER;}
| IF_TK OP_TK error
@@ -1148,16 +1336,36 @@ if_then_statement:
if_then_else_statement:
IF_TK OP_TK expression CP_TK statement_nsi ELSE_TK statement
- { $$ = build_if_else_statement ($2.location, $3, $5, $7); }
+ { $$ = build_if_else_statement ($2.location, $3, $5, $7); }
;
if_then_else_statement_nsi:
IF_TK OP_TK expression CP_TK statement_nsi ELSE_TK statement_nsi
- { $$ = build_if_else_statement ($2.location, $3, $5, $7); }
+ { $$ = build_if_else_statement ($2.location, $3, $5, $7); }
;
switch_statement:
- SWITCH_TK OP_TK expression CP_TK switch_block
+ switch_expression
+ {
+ enter_block ();
+ }
+ switch_block
+ {
+ /* Make into "proper list" of COMPOUND_EXPRs.
+ I.e. make the last statment also have its own
+ COMPOUND_EXPR. */
+ maybe_absorb_scoping_blocks ();
+ TREE_OPERAND ($1, 1) = exit_block ();
+ $$ = build_debugable_stmt (EXPR_WFL_LINECOL ($1), $1);
+ }
+;
+
+switch_expression:
+ SWITCH_TK OP_TK expression CP_TK
+ {
+ $$ = build (SWITCH_EXPR, NULL_TREE, $3, NULL_TREE);
+ EXPR_WFL_LINECOL ($$) = $2.location;
+ }
| SWITCH_TK error
{yyerror ("'(' expected"); RECOVER;}
| SWITCH_TK OP_TK error
@@ -1166,11 +1374,18 @@ switch_statement:
{yyerror ("'{' expected"); RECOVER;}
;
+/* Default assignment is there to avoid type node on switch_block
+ node. */
+
switch_block:
OCB_TK CCB_TK
+ { $$ = NULL_TREE; }
| OCB_TK switch_labels CCB_TK
+ { $$ = NULL_TREE; }
| OCB_TK switch_block_statement_groups CCB_TK
+ { $$ = NULL_TREE; }
| OCB_TK switch_block_statement_groups switch_labels CCB_TK
+ { $$ = NULL_TREE; }
;
switch_block_statement_groups:
@@ -1182,7 +1397,6 @@ switch_block_statement_group:
switch_labels block_statements
;
-
switch_labels:
switch_label
| switch_labels switch_label
@@ -1190,7 +1404,17 @@ switch_labels:
switch_label:
CASE_TK constant_expression REL_CL_TK
+ {
+ tree lab = build1 (CASE_EXPR, NULL_TREE, $2);
+ EXPR_WFL_LINECOL (lab) = $1.location;
+ java_method_add_stmt (current_function_decl, lab);
+ }
| DEFAULT_TK REL_CL_TK
+ {
+ tree lab = build1 (DEFAULT_EXPR, NULL_TREE, NULL_TREE);
+ EXPR_WFL_LINECOL (lab) = $1.location;
+ java_method_add_stmt (current_function_decl, lab);
+ }
| CASE_TK error
{yyerror ("Missing or invalid constant expression"); RECOVER;}
| CASE_TK constant_expression error
@@ -1209,7 +1433,7 @@ while_expression:
while_statement:
while_expression statement
- { $$ = complete_loop_body (0, NULL_TREE, $2, 0); }
+ { $$ = finish_loop_body (0, NULL_TREE, $2, 0); }
| WHILE_TK error
{YYERROR_NOW; yyerror ("'(' expected"); RECOVER;}
| WHILE_TK OP_TK error
@@ -1220,7 +1444,7 @@ while_statement:
while_statement_nsi:
while_expression statement_nsi
- { $$ = complete_loop_body (0, NULL_TREE, $2, 0); }
+ { $$ = finish_loop_body (0, NULL_TREE, $2, 0); }
;
do_statement_begin:
@@ -1234,18 +1458,18 @@ do_statement_begin:
do_statement:
do_statement_begin statement WHILE_TK OP_TK expression CP_TK SC_TK
- { $$ = complete_loop_body ($4.location, $5, $2, 1); }
+ { $$ = finish_loop_body ($4.location, $5, $2, 1); }
;
for_statement:
for_begin SC_TK expression SC_TK for_update CP_TK statement
- { $$ = complete_for_loop (EXPR_WFL_LINECOL ($3), $3, $5, $7);}
+ { $$ = finish_for_loop (EXPR_WFL_LINECOL ($3), $3, $5, $7); }
| for_begin SC_TK SC_TK for_update CP_TK statement
{
- $$ = complete_for_loop (0, NULL_TREE, $4, $6);
+ $$ = finish_for_loop (0, NULL_TREE, $4, $6);
/* We have not condition, so we get rid of the EXIT_EXPR */
LOOP_EXPR_BODY_CONDITION_EXPR (LOOP_EXPR_BODY ($$), 0) =
- size_zero_node;
+ empty_stmt_node;
}
| for_begin SC_TK error
{yyerror ("Invalid control expression"); RECOVER;}
@@ -1257,13 +1481,13 @@ for_statement:
for_statement_nsi:
for_begin SC_TK expression SC_TK for_update CP_TK statement_nsi
- { $$ = complete_for_loop (EXPR_WFL_LINECOL ($3), $3, $5, $7);}
+ { $$ = finish_for_loop (EXPR_WFL_LINECOL ($3), $3, $5, $7);}
| for_begin SC_TK SC_TK for_update CP_TK statement_nsi
{
- $$ = complete_for_loop (0, NULL_TREE, $4, $6);
+ $$ = finish_for_loop (0, NULL_TREE, $4, $6);
/* We have not condition, so we get rid of the EXIT_EXPR */
LOOP_EXPR_BODY_CONDITION_EXPR (LOOP_EXPR_BODY ($$), 0) =
- size_zero_node;
+ empty_stmt_node;
}
;
@@ -1294,7 +1518,7 @@ for_begin:
}
;
for_init: /* Can be empty */
- { $$ = size_zero_node; }
+ { $$ = empty_stmt_node; }
| statement_expression_list
{
/* Init statement recorded within the previously
@@ -1312,7 +1536,7 @@ for_init: /* Can be empty */
;
for_update: /* Can be empty */
- {$$ = size_zero_node;}
+ {$$ = empty_stmt_node;}
| statement_expression_list
{ $$ = build_debugable_stmt (BUILD_LOCATION (), $1); }
;
@@ -1361,6 +1585,10 @@ return_statement:
throw_statement:
THROW_TK expression SC_TK
+ {
+ $$ = build1 (THROW_EXPR, NULL_TREE, $2);
+ EXPR_WFL_LINECOL ($$) = $1.location;
+ }
| THROW_TK error
{yyerror ("Missing term"); RECOVER;}
| THROW_TK expression error
@@ -1369,6 +1597,11 @@ throw_statement:
synchronized_statement:
synchronized OP_TK expression CP_TK block
+ {
+ $$ = build (SYNCHRONIZED_EXPR, NULL_TREE, $3, $5);
+ EXPR_WFL_LINECOL ($$) =
+ EXPR_WFL_LINECOL (MODIFIER_WFL (SYNCHRONIZED_TK));
+ }
| synchronized OP_TK expression CP_TK error
{yyerror ("'{' expected"); RECOVER;}
| synchronized error
@@ -1379,17 +1612,24 @@ synchronized_statement:
{yyerror ("Missing term"); RECOVER;}
;
-synchronized: /* Test lval.sub_token here */
+synchronized:
MODIFIER_TK
{
- SOURCE_FRONTEND_DEBUG (("Modifiers: %d", $1));
+ if ((1 << $1) != ACC_SYNCHRONIZED)
+ fatal ("synchronized was '%d' - yyparse", (1 << $1));
}
;
try_statement:
TRY_TK block catches
+ { $$ = build_try_statement ($1.location, $2, $3); }
| TRY_TK block finally
+ { $$ = build_try_finally_statement ($1.location, $2, $3); }
| TRY_TK block catches finally
+ { $$ = build_try_finally_statement
+ ($1.location, build_try_statement ($1.location,
+ $2, $3), $4);
+ }
| TRY_TK error
{yyerror ("'{' expected"); DRECOVER (try_statement);}
;
@@ -1397,20 +1637,48 @@ try_statement:
catches:
catch_clause
| catches catch_clause
+ {
+ TREE_CHAIN ($2) = $1;
+ $$ = $2;
+ }
;
catch_clause:
- CATCH_TK OP_TK formal_parameter CP_TK block
+ catch_clause_parameter block
+ {
+ java_method_add_stmt (current_function_decl, $2);
+ exit_block ();
+ $$ = $1;
+ }
+
+catch_clause_parameter:
+ CATCH_TK OP_TK formal_parameter CP_TK
+ {
+ /* We add a block to define a scope for
+ formal_parameter (CCBP). The formal parameter is
+ declared initialized by the appropriate function
+ call */
+ tree ccpb = enter_block ();
+ tree init = build_assignment (ASSIGN_TK, $2.location,
+ TREE_PURPOSE ($3),
+ soft_exceptioninfo_call_node);
+ declare_local_variables (0, TREE_VALUE ($3),
+ build_tree_list (TREE_PURPOSE ($3),
+ init));
+ $$ = build1 (CATCH_EXPR, NULL_TREE, ccpb);
+ EXPR_WFL_LINECOL ($$) = $1.location;
+ }
| CATCH_TK error
{yyerror ("'(' expected"); RECOVER;}
-| CATCH_TK OP_TK error CP_TK /* That's for () */
- {yyerror ("Missing term"); DRECOVER (1);}
| CATCH_TK OP_TK error
- {yyerror ("Missing term"); DRECOVER (2);}
+ {yyerror ("Missing term or ')' expected"); DRECOVER (2);}
+| CATCH_TK OP_TK error CP_TK /* That's for () */
+ {yyerror ("')' expected"); DRECOVER (1);}
;
finally:
FINALLY_TK block
+ { $$ = $2; }
| FINALLY_TK error
{yyerror ("'{' expected"); RECOVER; }
;
@@ -1435,12 +1703,16 @@ primary_no_new_array:
'type' into its components. Missing is something for array,
which will complete the reference_type part. FIXME */
| name DOT_TK CLASS_TK /* Added, JDK1.1 class literals */
+ { $$ = parse_jdk1_1_error ("named class literals"); }
| primitive_type DOT_TK CLASS_TK /* Added, JDK1.1 class literals */
+ { $$ = build_class_ref ($1); }
| VOID_TK DOT_TK CLASS_TK /* Added, JDK1.1 class literals */
+ { $$ = build_class_ref (void_type_node); }
/* Added, JDK1.1 inner classes. Documentation is wrong
refering to a 'ClassName' (class_name) rule that doesn't
exist. Used name instead. */
| name DOT_TK THIS_TK
+ { $$ = parse_jdk1_1_error ("class literals"); }
| OP_TK expression error
{yyerror ("')' expected"); RECOVER;}
| name DOT_TK error
@@ -1453,22 +1725,16 @@ primary_no_new_array:
class_instance_creation_expression:
NEW_TK class_type OP_TK argument_list CP_TK
- {
- $$ = build_method_invocation ($2, $4);
- TREE_SET_CODE ($$, JAVA_NEW_CLASS_EXPR);
- }
+ { $$ = build_new_invocation ($2, $4); }
| NEW_TK class_type OP_TK CP_TK
- {
- $$ = build_method_invocation ($2, NULL_TREE);
- TREE_SET_CODE ($$, JAVA_NEW_CLASS_EXPR);
- }
+ { $$ = build_new_invocation ($2, NULL_TREE); }
/* Added, JDK1.1 inner classes but modified to use
'class_type' instead of 'TypeName' (type_name) mentionned
in the documentation but doesn't exist. */
| NEW_TK class_type OP_TK argument_list CP_TK class_body
-{$$ = $2;}
+ { $$ = parse_jdk1_1_error ("inner class instance creation"); }
| NEW_TK class_type OP_TK CP_TK class_body
-{$$ = $2;}
+ { $$ = parse_jdk1_1_error ("inner class instance creation"); }
/* Added, JDK1.1 inner classes, modified to use name or
primary instead of primary solely which couldn't work in
all situations. */
@@ -1516,15 +1782,15 @@ array_creation_expression:
| NEW_TK class_or_interface_type dim_exprs
{ $$ = build_newarray_node ($2, $3, 0); }
| NEW_TK primitive_type dim_exprs dims
- { $$ = build_newarray_node ($2, $3, ctxp->osb_number); }
+ { $$ = build_newarray_node ($2, $3, CURRENT_OSB (ctxp));}
| NEW_TK class_or_interface_type dim_exprs dims
- { $$ = build_newarray_node ($2, $3, ctxp->osb_number); }
+ { $$ = build_newarray_node ($2, $3, CURRENT_OSB (ctxp));}
/* Added, JDK1.1 anonymous array. Initial documentation rule
modified */
| NEW_TK class_or_interface_type dims array_initializer
-{$$ = $2;}
+ { $$ = parse_jdk1_1_error ("anonymous array"); }
| NEW_TK primitive_type dims array_initializer
-{$$ = $2;}
+ { $$ = parse_jdk1_1_error ("anonymous array"); }
| NEW_TK error CSB_TK
{yyerror ("'[' expected"); DRECOVER ("]");}
| NEW_TK error OSB_TK
@@ -1556,9 +1822,33 @@ dim_expr:
dims:
OSB_TK CSB_TK
- { ctxp->osb_number = 1; }
+ {
+ int allocate = 0;
+ /* If not initialized, allocate memory for the osb
+ numbers stack */
+ if (!ctxp->osb_limit)
+ {
+ allocate = ctxp->osb_limit = 32;
+ ctxp->osb_depth = -1;
+ }
+ /* If capacity overflown, reallocate a bigger chuck */
+ else if (ctxp->osb_depth+1 == ctxp->osb_limit)
+ allocate = ctxp->osb_limit << 1;
+
+ if (allocate)
+ {
+ allocate *= sizeof (int);
+ if (ctxp->osb_number)
+ ctxp->osb_number = (int *)xrealloc (ctxp->osb_number,
+ allocate);
+ else
+ ctxp->osb_number = (int *)xmalloc (allocate);
+ }
+ ctxp->osb_depth++;
+ CURRENT_OSB (ctxp) = 1;
+ }
| dims OSB_TK CSB_TK
- { ctxp->osb_number++; }
+ { CURRENT_OSB (ctxp)++; }
| dims OSB_TK error
{ yyerror ("']' expected"); RECOVER;}
;
@@ -1566,10 +1856,12 @@ dims:
field_access:
primary DOT_TK identifier
{ $$ = make_qualified_primary ($1, $3, $2.location); }
+ /* FIXME - REWRITE TO:
+ { $$ = build_binop (COMPONENT_REF, $2.location, $1, $3); } */
| SUPER_TK DOT_TK identifier
{
tree super_wfl =
- build_wfl_node (super_identifier_node, input_filename, 0, 0);
+ build_wfl_node (super_identifier_node);
EXPR_WFL_LINECOL (super_wfl) = $1.location;
$$ = make_qualified_name (super_wfl, $3, $2.location);
}
@@ -1584,29 +1876,35 @@ method_invocation:
{ $$ = build_method_invocation ($1, $3); }
| primary DOT_TK identifier OP_TK CP_TK
{
- tree invok = build_method_invocation ($3, NULL_TREE);
- $$ = make_qualified_primary ($1, invok, $2.location);
+ if (TREE_CODE ($1) == THIS_EXPR)
+ $$ = build_this_super_qualified_invocation
+ (1, $3, NULL_TREE, 0, $2.location);
+ else
+ {
+ tree invok = build_method_invocation ($3, NULL_TREE);
+ $$ = make_qualified_primary ($1, invok, $2.location);
+ }
}
| primary DOT_TK identifier OP_TK argument_list CP_TK
{
- tree invok = build_method_invocation ($3, $5);
- $$ = make_qualified_primary ($1, invok, $2.location);
+ if (TREE_CODE ($1) == THIS_EXPR)
+ $$ = build_this_super_qualified_invocation
+ (1, $3, $5, 0, $2.location);
+ else
+ {
+ tree invok = build_method_invocation ($3, $5);
+ $$ = make_qualified_primary ($1, invok, $2.location);
+ }
}
| SUPER_TK DOT_TK identifier OP_TK CP_TK
- {
- tree invok;
- tree wfl = build_wfl_node (super_identifier_node, input_filename, 0, 0);
- EXPR_WFL_LINECOL (wfl) = $1.location;
- invok = build_method_invocation ($3, NULL_TREE);
- $$ = make_qualified_primary (wfl, invok, $2.location);
+ {
+ $$ = build_this_super_qualified_invocation
+ (0, $3, NULL_TREE, $1.location, $2.location);
}
| SUPER_TK DOT_TK identifier OP_TK argument_list CP_TK
{
- tree invok;
- tree wfl = build_wfl_node (super_identifier_node, input_filename, 0, 0);
- EXPR_WFL_LINECOL (wfl) = $1.location;
- invok = build_method_invocation ($3, $5);
- $$ = make_qualified_primary (wfl, invok, $2.location);
+ $$ = build_this_super_qualified_invocation
+ (0, $3, $5, $1.location, $2.location);
}
/* Screws up thing. I let it here until I'm convinced it can
be removed. FIXME
@@ -1707,8 +2005,9 @@ cast_expression: /* Error handling here is potentially weak */
OP_TK primitive_type dims CP_TK unary_expression
{
tree type = $2;
- while (ctxp->osb_number--)
+ while (CURRENT_OSB (ctxp)--)
type = build_java_array_type (type, -1);
+ ctxp->osb_depth--;
$$ = build_cast ($1.location, type, $5);
}
| OP_TK primitive_type CP_TK unary_expression
@@ -1718,8 +2017,9 @@ cast_expression: /* Error handling here is potentially weak */
| OP_TK name dims CP_TK unary_expression_not_plus_minus
{
char *ptr;
- while (ctxp->osb_number--)
+ while (CURRENT_OSB (ctxp)--)
obstack_1grow (&temporary_obstack, '[');
+ ctxp->osb_depth--;
obstack_grow0 (&temporary_obstack,
IDENTIFIER_POINTER (EXPR_WFL_NODE ($2)),
IDENTIFIER_LENGTH (EXPR_WFL_NODE ($2)));
@@ -1834,6 +2134,7 @@ relational_expression:
$1, $3);
}
| relational_expression INSTANCEOF_TK reference_type
+ { $$ = build_binop (INSTANCEOF_EXPR, $2.location, $1, $3); }
| relational_expression LT_TK error
{yyerror ("Missing term"); RECOVER;}
| relational_expression GT_TK error
@@ -1922,6 +2223,10 @@ conditional_or_expression:
conditional_expression: /* Error handling here is weak */
conditional_or_expression
| conditional_or_expression REL_QM_TK expression REL_CL_TK conditional_expression
+ {
+ $$ = build (CONDITIONAL_EXPR, NULL_TREE, $1, $3, $5);
+ EXPR_WFL_LINECOL ($$) = $2.location;
+ }
| conditional_or_expression REL_QM_TK REL_CL_TK error
{
YYERROR_NOW;
@@ -1972,8 +2277,6 @@ constant_expression:
%%
-#include "lex.c"
-
/* Flag for the error report routine to issue the error the first time
it's called (overriding the default behavior which is to drop the
first invocation and honor the second one, taking advantage of a
@@ -1986,18 +2289,32 @@ void
java_push_parser_context ()
{
struct parser_ctxt *new =
- (struct parser_ctxt *)malloc(sizeof (struct parser_ctxt));
+ (struct parser_ctxt *)xmalloc(sizeof (struct parser_ctxt));
bzero (new, sizeof (struct parser_ctxt));
new->next = ctxp;
ctxp = new;
if (ctxp->next)
- ctxp->incomplete_class = ctxp->next->incomplete_class;
+ {
+ ctxp->incomplete_class = ctxp->next->incomplete_class;
+ ctxp->gclass_list = ctxp->next->gclass_list;
+ }
}
+/* If the first file of a file list was a class file, no context
+ exists for a source file to be parsed. This boolean remembers that
+ java_parser_context_save_global might have created a dummy one, so
+ that java_parser_context_restore_global can pop it. */
+static int extra_ctxp_pushed_p = 0;
+
void
java_parser_context_save_global ()
{
+ if (!ctxp)
+ {
+ java_push_parser_context ();
+ extra_ctxp_pushed_p = 1;
+ }
ctxp->finput = finput;
ctxp->lineno = lineno;
ctxp->current_class = current_class;
@@ -2013,18 +2330,29 @@ java_parser_context_restore_global ()
current_class = ctxp->current_class;
input_filename = ctxp->filename;
current_function_decl = ctxp->current_function_decl;
+ if (!ctxp->next && extra_ctxp_pushed_p)
+ {
+ java_pop_parser_context (0);
+ extra_ctxp_pushed_p = 0;
+ }
}
void
-java_pop_parser_context ()
+java_pop_parser_context (generate)
+ int generate;
{
tree current;
- struct parser_ctxt *toFree = ctxp;
- struct parser_ctxt *next = ctxp->next;
+ struct parser_ctxt *toFree, *next;
+ if (!ctxp)
+ return;
+
+ toFree = ctxp;
+ next = ctxp->next;
if (next)
{
next->incomplete_class = ctxp->incomplete_class;
+ next->gclass_list = ctxp->gclass_list;
lineno = ctxp->lineno;
finput = ctxp->finput;
current_class = ctxp->current_class;
@@ -2036,11 +2364,28 @@ java_pop_parser_context ()
IS_A_SINGLE_IMPORT_CLASSFILE_NAME_P (TREE_PURPOSE (current)) = 0;
/* And restore those of the previous context */
- if (ctxp = next)
+ if ((ctxp = next)) /* Assignment is really meant here */
for (current = ctxp->import_list; current; current = TREE_CHAIN (current))
IS_A_SINGLE_IMPORT_CLASSFILE_NAME_P (TREE_PURPOSE (current)) = 1;
- free (toFree);
+ if (generate)
+ {
+ toFree->next = ctxp_for_generation;
+ ctxp_for_generation = toFree;
+ }
+ else
+ free (toFree);
+}
+
+/* Reporting JDK1.1 features not implemented */
+
+static tree
+parse_jdk1_1_error (msg)
+ char *msg;
+{
+ sorry (": `%s' JDK1.1(TM) feature", msg);
+ java_error_count++;
+ return empty_stmt_node;
}
static int do_warning = 0;
@@ -2053,7 +2398,7 @@ yyerror (msg)
static int prev_lineno;
static char *prev_msg;
- int i, save_lineno;
+ int save_lineno;
char *remainder, *code_from_source;
extern struct obstack temporary_obstack;
@@ -2112,68 +2457,151 @@ yyerror (msg)
}
static void
-parse_error (msg)
- char *msg;
+issue_warning_error_from_context (cl, msg, ap)
+ tree cl;
+ const char *msg;
+ va_list ap;
{
+ char *saved, *saved_input_filename;
+ char buffer [4096];
+ vsprintf (buffer, msg, ap);
+ force_error = 1;
+
+ ctxp->elc.line = EXPR_WFL_LINENO (cl);
+ ctxp->elc.col = (EXPR_WFL_COLNO (cl) == 0xfff ? -1 :
+ (EXPR_WFL_COLNO (cl) == 0xffe ? -2 : EXPR_WFL_COLNO (cl)));
+
+ /* We have a CL, that's a good reason for using it if it contains data */
+ saved = ctxp->filename;
+ if (TREE_CODE (cl) == EXPR_WITH_FILE_LOCATION && EXPR_WFL_FILENAME_NODE (cl))
+ ctxp->filename = EXPR_WFL_FILENAME (cl);
+ saved_input_filename = input_filename;
+ input_filename = ctxp->filename;
java_error (NULL);
- java_error (msg);
+ java_error (buffer);
+ ctxp->filename = saved;
+ input_filename = saved_input_filename;
+ force_error = 0;
}
/* Issue an error message at a current source line CL */
-static void
-parse_error_context VPROTO ((tree cl, char *msg, ...))
+void
+parse_error_context VPROTO ((tree cl, const char *msg, ...))
{
-#ifndef __STDC__
+#ifndef ANSI_PROTOTYPES
tree cl;
- char *msg;
+ const char *msg;
#endif
- char buffer [4096];
va_list ap;
VA_START (ap, msg);
-#ifndef __STDC__
+#ifndef ANSI_PROTOTYPES
cl = va_arg (ap, tree);
- msg = va_arg (ap, char *);
+ msg = va_arg (ap, const char *);
#endif
- vsprintf (buffer, msg, ap);
-
- force_error = 1;
- ctxp->elc.line = EXPR_WFL_LINENO (cl);
- ctxp->elc.col = (EXPR_WFL_COLNO (cl) == 0xfff ? -1 : EXPR_WFL_COLNO (cl));
-
- parse_error (buffer);
- force_error = 0;
+ issue_warning_error_from_context (cl, msg, ap);
+ va_end (ap);
}
/* Issue a warning at a current source line CL */
static void
-parse_warning_context VPROTO ((tree cl, char *msg, ...))
+parse_warning_context VPROTO ((tree cl, const char *msg, ...))
{
-#ifndef __STDC__
+#ifndef ANSI_PROTOTYPES
tree cl;
- char *msg;
+ const char *msg;
#endif
- char buffer [4096];
va_list ap;
VA_START (ap, msg);
-#ifndef __STDC__
+#ifndef ANSI_PROTOTYPES
cl = va_arg (ap, tree);
- msg = va_arg (ap, char *);
+ msg = va_arg (ap, const char *);
#endif
- vsprintf (buffer, msg, ap);
force_error = do_warning = 1;
- ctxp->elc.line = EXPR_WFL_LINENO (cl);
- ctxp->elc.col = (EXPR_WFL_COLNO (cl) == 0xfff ? -1 : EXPR_WFL_COLNO (cl));
-
- parse_error (buffer);
+ issue_warning_error_from_context (cl, msg, ap);
do_warning = force_error = 0;
+ va_end (ap);
}
-void
+static tree
+find_expr_with_wfl (node)
+ tree node;
+{
+ while (node)
+ {
+ char code;
+ tree to_return;
+
+ switch (TREE_CODE (node))
+ {
+ case BLOCK:
+ node = BLOCK_EXPR_BODY (node);
+ continue;
+
+ case COMPOUND_EXPR:
+ to_return = find_expr_with_wfl (TREE_OPERAND (node, 0));
+ if (to_return)
+ return to_return;
+ node = TREE_OPERAND (node, 1);
+ continue;
+
+ case LOOP_EXPR:
+ node = TREE_OPERAND (node, 0);
+ continue;
+
+ case LABELED_BLOCK_EXPR:
+ node = TREE_OPERAND (node, 1);
+ continue;
+
+ default:
+ code = TREE_CODE_CLASS (TREE_CODE (node));
+ if (((code == '1') || (code == '2') || (code == 'e'))
+ && EXPR_WFL_LINECOL (node))
+ return node;
+ return NULL_TREE;
+ }
+ }
+ return NULL_TREE;
+}
+
+/* Issue a missing return statement error. Uses METHOD to figure the
+ last line of the method the error occurs in. */
+
+static void
+missing_return_error (method)
+ tree method;
+{
+ EXPR_WFL_SET_LINECOL (wfl_operator, DECL_SOURCE_LINE_LAST (method), -2);
+ parse_error_context (wfl_operator, "Missing return statement");
+}
+
+/* Issue an unreachable statement error. From NODE, find the next
+ statement to report appropriately. */
+static void
+unreachable_stmt_error (node)
+ tree node;
+{
+ /* Browse node to find the next expression node that has a WFL. Use
+ the location to report the error */
+ if (TREE_CODE (node) == COMPOUND_EXPR)
+ node = find_expr_with_wfl (TREE_OPERAND (node, 1));
+ else
+ node = find_expr_with_wfl (node);
+
+ if (node)
+ {
+ EXPR_WFL_SET_LINECOL (wfl_operator, EXPR_WFL_LINENO (node), -2);
+ parse_error_context (wfl_operator, "Unreachable statement");
+ }
+ else
+ fatal ("Can't get valid statement - unreachable_stmt_error");
+}
+
+int
java_report_errors ()
{
if (java_error_count)
@@ -2184,6 +2612,7 @@ java_report_errors ()
java_warning_count, (java_warning_count == 1 ? "" : "s"));
if (java_error_count || java_warning_count)
putc ('\n', stderr);
+ return java_error_count;
}
static char *
@@ -2212,8 +2641,11 @@ java_accstring_lookup (flags)
#undef COPY_RETURN
}
+/* Issuing error messages upon redefinition of classes, interfaces or
+ variables. */
+
static void
-redefinition_error (context, id, decl, cl)
+classitf_redefinition_error (context, id, decl, cl)
char *context;
tree id, decl, cl;
{
@@ -2223,6 +2655,74 @@ redefinition_error (context, id, decl, cl)
/* Here we should point out where its redefined. It's a unicode. FIXME */
}
+static void
+variable_redefinition_error (context, name, type, line)
+ tree context, name, type;
+ int line;
+{
+ char *type_name;
+
+ /* Figure a proper name for type. We might haven't resolved it */
+ if (TREE_CODE (type) == POINTER_TYPE && !TREE_TYPE (type))
+ type_name = IDENTIFIER_POINTER (TYPE_NAME (type));
+ else
+ type_name = lang_printable_name (type, 0);
+
+ parse_error_context (context,
+ "Variable `%s' is already defined in this method and "
+ "was declared `%s %s' at line %d",
+ IDENTIFIER_POINTER (name),
+ type_name, IDENTIFIER_POINTER (name), line);
+}
+
+static tree
+build_array_from_name (type, type_wfl, name, ret_name)
+ tree type, type_wfl, name, *ret_name;
+{
+ int more_dims = 0;
+ char *string;
+
+ /* Eventually get more dims */
+ string = IDENTIFIER_POINTER (name);
+ while (string [more_dims] == '[')
+ more_dims++;
+
+ /* If we have, then craft a new type for this variable */
+ if (more_dims)
+ {
+ name = get_identifier (&string [more_dims]);
+
+ /* If we have a pointer, use its type */
+ if (TREE_CODE (type) == POINTER_TYPE)
+ type = TREE_TYPE (type);
+
+ /* Building the first dimension of a primitive type uses this
+ function */
+ if (JPRIMITIVE_TYPE_P (type))
+ {
+ type = build_java_array_type (type, -1);
+ CLASS_LOADED_P (type) = 1;
+ more_dims--;
+ }
+ /* Otherwise, if we have a WFL for this type, use it (the type
+ is already an array on an unresolved type, and we just keep
+ on adding dimensions) */
+ else if (type_wfl)
+ type = type_wfl;
+
+ /* Add all the dimensions */
+ while (more_dims--)
+ type = build_unresolved_array_type (type);
+
+ /* The type may have been incomplete in the first place */
+ if (type_wfl)
+ type = obtain_incomplete_type (type);
+ }
+
+ *ret_name = name;
+ return type;
+}
+
/* Build something that the type identifier resolver will identify as
being an array to an unresolved type. TYPE_WFL is a WFL on a
identifier. */
@@ -2233,7 +2733,7 @@ build_unresolved_array_type (type_or_wfl)
{
char *ptr;
- /* TYPE_OR_WFL might be an array on a primitive type. In this case,
+ /* TYPE_OR_WFL might be an array on a resolved type. In this case,
just create a array type */
if (TREE_CODE (type_or_wfl) == RECORD_TYPE)
{
@@ -2311,8 +2811,8 @@ check_class_interface_creation (is_interface, flags, raw_name, qualified_name, d
}
if (decl && CLASS_COMPLETE_P (decl))
{
- redefinition_error ((is_interface ? "Interface" : "Class"),
- qualified_name, decl, cl);
+ classitf_redefinition_error ((is_interface ? "Interface" : "Class"),
+ qualified_name, decl, cl);
return 1;
}
@@ -2323,8 +2823,10 @@ check_class_interface_creation (is_interface, flags, raw_name, qualified_name, d
/* Contains OS dependent assumption on path separator. FIXME */
for (f = &input_filename [strlen (input_filename)];
- f != input_filename && f[0] != '/'; f--);
- if (f[0] == '/')
+ f != input_filename && f[0] != '/' && f[0] != DIR_SEPARATOR;
+ f--)
+ ;
+ if (f[0] == '/' || f[0] == DIR_SEPARATOR)
f++;
if (strncmp (IDENTIFIER_POINTER (raw_name),
f , IDENTIFIER_LENGTH (raw_name)) ||
@@ -2350,21 +2852,30 @@ static tree
maybe_create_class_interface_decl (decl, qualified_name, cl)
tree decl, qualified_name, cl;
{
- if (decl)
- DECL_ARTIFICIAL (decl) = 1; /* FIXME */
- else
+ if (!decl)
decl = push_class (make_class (), qualified_name);
/* Take care of the file and line business */
DECL_SOURCE_FILE (decl) = EXPR_WFL_FILENAME (cl);
- DECL_SOURCE_LINE (decl) = EXPR_WFL_LINENO (cl);
+ /* If we're emiting xrefs, store the line/col number information */
+ if (flag_emit_xref)
+ DECL_SOURCE_LINE (decl) = EXPR_WFL_LINECOL (cl);
+ else
+ DECL_SOURCE_LINE (decl) = EXPR_WFL_LINENO (cl);
CLASS_FROM_SOURCE_P (TREE_TYPE (decl)) = 1;
+ CLASS_FROM_CURRENTLY_COMPILED_SOURCE_P (TREE_TYPE (decl)) =
+ IS_A_COMMAND_LINE_FILENAME_P (EXPR_WFL_FILENAME_NODE (cl));
ctxp->current_parsed_class = decl;
/* Link the declaration to the already seen ones */
TREE_CHAIN (decl) = ctxp->class_list;
ctxp->class_list = decl;
+
+ /* Create a new nodes in the global lists */
+ ctxp->gclass_list = tree_cons (NULL_TREE, decl, ctxp->gclass_list);
+ all_class_list = tree_cons (NULL_TREE, decl, all_class_list);
+
/* Install a new dependency list element */
create_jdep_list (ctxp);
@@ -2387,11 +2898,12 @@ add_superinterfaces (decl, interface_list)
defined. */
for (node = interface_list; node; node = TREE_CHAIN (node))
{
- tree current = TREE_PURPOSE (node), interface_decl;
- if ((interface_decl = IDENTIFIER_CLASS_VALUE (EXPR_WFL_NODE (current))))
+ tree current = TREE_PURPOSE (node);
+ tree idecl = IDENTIFIER_CLASS_VALUE (EXPR_WFL_NODE (current));
+ if (idecl && CLASS_LOADED_P (TREE_TYPE (idecl)))
{
- if (!parser_check_super_interface (interface_decl, decl, current))
- parser_add_interface (decl, interface_decl, current);
+ if (!parser_check_super_interface (idecl, decl, current))
+ parser_add_interface (decl, idecl, current);
}
else
register_incomplete_type (JDEP_INTERFACE,
@@ -2407,7 +2919,6 @@ create_interface (flags, id, super)
int flags;
tree id, super;
{
- int chk;
tree raw_name = EXPR_WFL_NODE (id);
tree q_name = parser_qualified_classname (id);
tree decl = IDENTIFIER_CLASS_VALUE (q_name);
@@ -2422,22 +2933,17 @@ create_interface (flags, id, super)
- public/abstract allowed (already done at that point)
- abstract is obsolete (comes first, it's a warning, or should be)
- Can't use twice the same (checked in the modifier rule) */
- if (flags & ACC_ABSTRACT)
+ if ((flags & ACC_ABSTRACT) && flag_redundant)
parse_warning_context
(MODIFIER_WFL (ABSTRACT_TK),
- "Obsolete use of `abstract' modifier. Interface `%s' is implicitely "
+ "Redundant use of `abstract' modifier. Interface `%s' is implicitely "
"abstract", IDENTIFIER_POINTER (raw_name));
- if (flags & ACC_PUBLIC && flags & ACC_ABSTRACT)
- parse_error_context
- (MODIFIER_WFL (ABSTRACT_TK),
- "Can't specify both `public' and `abstract' modifiers in the "
- "definition of interface `%s'", IDENTIFIER_POINTER (raw_name));
/* Create a new decl if DECL is NULL, otherwise fix it */
decl = maybe_create_class_interface_decl (decl, q_name, id);
/* Set super info and mark the class a complete */
- set_super_info (ACC_ABSTRACT | ACC_INTERFACE | flags, TREE_TYPE (decl),
+ set_super_info (ACC_INTERFACE | flags, TREE_TYPE (decl),
object_type_node, ctxp->interface_number);
ctxp->interface_number = 0;
CLASS_COMPLETE_P (decl) = 1;
@@ -2454,13 +2960,13 @@ create_class (flags, id, super, interfaces)
int flags;
tree id, super, interfaces;
{
- int chk;
tree raw_name = EXPR_WFL_NODE (id);
tree class_id, decl;
- tree super_decl = NULL, super_decl_type;
+ tree super_decl_type;
class_id = parser_qualified_classname (id);
decl = IDENTIFIER_CLASS_VALUE (class_id);
+ ctxp->current_parsed_class_un = EXPR_WFL_NODE (id);
EXPR_WFL_NODE (id) = class_id;
/* Basic check: scope, redefinition, modifiers */
@@ -2488,17 +2994,8 @@ create_class (flags, id, super, interfaces)
return NULL_TREE;
}
- /* The class is known and exists if there is a decl. Otherwise,
- postpone the operation and do it later. */
- super_decl = IDENTIFIER_CLASS_VALUE (EXPR_WFL_NODE (super));
- if (super_decl)
- {
- parser_check_super (super_decl, decl, id);
- super_decl_type = TREE_TYPE (super_decl);
- }
- else
- super_decl_type =
- register_incomplete_type (JDEP_SUPER, super, decl, NULL_TREE);
+ super_decl_type =
+ register_incomplete_type (JDEP_SUPER, super, decl, NULL_TREE);
}
else if (TREE_TYPE (decl) != object_type_node)
super_decl_type = object_type_node;
@@ -2513,6 +3010,9 @@ create_class (flags, id, super, interfaces)
CLASS_COMPLETE_P (decl) = 1;
add_superinterfaces (decl, interfaces);
+ /* Eventually sets the @deprecated tag flag */
+ CHECK_DEPRECATED (decl);
+
return decl;
}
@@ -2541,27 +3041,38 @@ lookup_field_wrapper (class, name)
tree class, name;
{
tree type = class;
- return lookup_field (&type, name);
+ tree decl;
+ java_parser_context_save_global ();
+ decl = lookup_field (&type, name);
+ java_parser_context_restore_global ();
+ return decl;
}
/* Find duplicate field within the same class declarations and report
- the error */
+ the error. Returns 1 if a duplicated field was found, 0
+ otherwise. */
static int
-duplicate_declaration_error (class, new_field_name, new_type, cl)
- tree class, new_field_name, new_type, cl;
+duplicate_declaration_error_p (new_field_name, new_type, cl)
+ tree new_field_name, new_type, cl;
{
/* This might be modified to work with method decl as well */
tree decl = find_field (TREE_TYPE (ctxp->current_parsed_class),
new_field_name);
if (decl)
{
- char *t1 = strdup ((char *)lang_printable_name (new_type, 1));
- char *t2 =
- strdup ((TREE_CODE (TREE_TYPE (decl)) == TREE_LIST ?
- IDENTIFIER_POINTER (TYPE_NAME
- (TREE_PURPOSE (TREE_TYPE (decl)))) :
- (char *)lang_printable_name (TREE_TYPE (decl), 1)));
+ char *t1 = strdup (purify_type_name
+ ((TREE_CODE (new_type) == POINTER_TYPE
+ && TREE_TYPE (new_type) == NULL_TREE) ?
+ IDENTIFIER_POINTER (TYPE_NAME (new_type)) :
+ lang_printable_name (new_type, 1)));
+ /* The type may not have been completed by the time we report
+ the error */
+ char *t2 = strdup (purify_type_name
+ ((TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
+ && TREE_TYPE (TREE_TYPE (decl)) == NULL_TREE) ?
+ IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE (decl))) :
+ lang_printable_name (TREE_TYPE (decl), 1)));
parse_error_context
(cl , "Duplicate variable declaration: `%s %s' was `%s %s' (%s:%d)",
t1, IDENTIFIER_POINTER (new_field_name),
@@ -2569,9 +3080,9 @@ duplicate_declaration_error (class, new_field_name, new_type, cl)
DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl));
free (t1);
free (t2);
- return 0;
+ return 1;
}
- return 1;
+ return 0;
}
/* Field registration routine. If TYPE doesn't exist, field
@@ -2583,7 +3094,7 @@ register_fields (flags, type, variable_list)
int flags;
tree type, variable_list;
{
- tree current, type_decl, returned_type;
+ tree current, saved_type;
tree class_type = TREE_TYPE (ctxp->current_parsed_class);
int saved_lineno = lineno;
int must_chain = 0;
@@ -2606,103 +3117,128 @@ register_fields (flags, type, variable_list)
flags |= (ACC_PUBLIC | ACC_STATIC | ACC_FINAL);
}
- if (unresolved_type_p (type, &returned_type))
- {
- if (returned_type)
- type = returned_type;
- else
- {
- wfl = type;
- type = obtain_incomplete_type (type);
- must_chain = 1;
- }
- }
+ /* Obtain a suitable type for resolution, if necessary */
+ SET_TYPE_FOR_RESOLUTION (type, wfl, must_chain);
+
+ /* If TYPE is fully resolved and we don't have a reference, make one */
+ PROMOTE_RECORD_IF_COMPLETE (type, must_chain);
- for (current = variable_list; current; current = TREE_CHAIN (current))
+ for (current = variable_list, saved_type = type; current;
+ current = TREE_CHAIN (current), type = saved_type)
{
+ tree real_type;
+ tree field_decl;
tree cl = TREE_PURPOSE (current);
tree init = TREE_VALUE (current);
tree current_name = EXPR_WFL_NODE (cl);
- if (duplicate_declaration_error (class_type, current_name, type, cl))
- {
- tree field_decl;
- lineno = EXPR_WFL_LINENO (cl);
- field_decl = add_field (class_type, current_name, type, flags);
+ /* Process NAME, as it may specify extra dimension(s) for it */
+ type = build_array_from_name (type, wfl, current_name, &current_name);
- /* Check if we must chain. */
- if (must_chain)
- register_incomplete_type (JDEP_FIELD, wfl, field_decl, type);
+ /* Type adjustment. We may have just readjusted TYPE because
+ the variable specified more dimensions. Make sure we have
+ a reference if we can and don't have one already. Also
+ change the name if we have an init. */
+ if (type != saved_type)
+ {
+ PROMOTE_RECORD_IF_COMPLETE (type, must_chain);
+ if (init)
+ EXPR_WFL_NODE (TREE_OPERAND (init, 0)) = current_name;
+ }
+
+ real_type = GET_REAL_TYPE (type);
+ /* Check for redeclarations */
+ if (duplicate_declaration_error_p (current_name, real_type, cl))
+ continue;
+
+ /* Set lineno to the line the field was found and create a
+ declaration for it. Eventually sets the @deprecated tag flag. */
+ if (flag_emit_xref)
+ lineno = EXPR_WFL_LINECOL (cl);
+ else
+ lineno = EXPR_WFL_LINENO (cl);
+ field_decl = add_field (class_type, current_name, real_type, flags);
+ CHECK_DEPRECATED (field_decl);
+
+ /* Check if we must chain. */
+ if (must_chain)
+ register_incomplete_type (JDEP_FIELD, wfl, field_decl, type);
- /* Default value of a static field is 0 and it is considered
- initialized. */
+ /* If we have an initialization value tied to the field */
+ if (init)
+ {
+ /* The field is declared static */
if (flags & ACC_STATIC)
- INITIALIZED_P (field_decl) = 1;
-
- /* If we have an initialization value tied to the field */
- if (init)
{
- /* The field is declared static */
- if (flags & ACC_STATIC)
- {
- /* FIXME */
- if (flags & ACC_FINAL)
- ;
- /* Otherwise, the field should be initialized in
- <clinit>. This field is remembered so we can
- generate <clinit> later. */
- else
- {
- INITIALIZED_P (field_decl) = 1;
- TREE_CHAIN (init) = ctxp->static_initialized;
- ctxp->static_initialized = init;
- }
- }
- /* A non-static field declared with an immediate
- initialization is to be initialized in <init>, if
- any. This field is remembered to be processed at the
- time of the generation of <init>. */
- else
- {
- TREE_CHAIN (init) = ctxp->non_static_initialized;
- ctxp->non_static_initialized = init;
- }
+ /* We include the field and its initialization part into
+ a list used to generate <clinit>. After <clinit> is
+ walked, field initializations will be processed and
+ fields initialized with known constants will be taken
+ out of <clinit> and have their DECL_INITIAL set
+ appropriately. */
+ TREE_CHAIN (init) = ctxp->static_initialized;
+ ctxp->static_initialized = init;
+ DECL_INITIAL (field_decl) = TREE_OPERAND (init, 1);
+ if (TREE_CODE (TREE_OPERAND (init, 1)) == NEW_ARRAY_INIT)
+ TREE_STATIC (TREE_OPERAND (init, 1)) = 1;
+ }
+ /* A non-static field declared with an immediate initialization is
+ to be initialized in <init>, if any. This field is remembered
+ to be processed at the time of the generation of <init>. */
+ else
+ {
+ TREE_CHAIN (init) = ctxp->non_static_initialized;
+ ctxp->non_static_initialized = init;
}
+ MODIFY_EXPR_FROM_INITIALIZATION_P (init) = 1;
}
}
lineno = saved_lineno;
}
+/* Generate the method $finit$ that initializes fields initialized
+ upon declaration. */
+
+static void
+maybe_generate_finit ()
+{
+ tree mdecl, current;
+
+ if (!ctxp->non_static_initialized || java_error_count)
+ return;
+
+ mdecl = create_artificial_method (TREE_TYPE (ctxp->current_parsed_class),
+ ACC_PRIVATE, void_type_node,
+ finit_identifier_node, end_params_node);
+ start_artificial_method_body (mdecl);
+
+ ctxp->non_static_initialized = nreverse (ctxp->non_static_initialized);
+ for (current = ctxp->non_static_initialized; current;
+ current = TREE_CHAIN (current))
+ java_method_add_stmt (mdecl,
+ build_debugable_stmt (EXPR_WFL_LINECOL (current),
+ current));
+
+ end_artificial_method_body (mdecl);
+ CLASS_HAS_FINIT_P (TREE_TYPE (ctxp->current_parsed_class)) = 1;
+ ctxp->non_static_initialized = NULL_TREE;
+}
+
/* Check whether it is necessary to generate a <clinit> for the class
we just parsed. */
static void
maybe_generate_clinit ()
{
- int saved_lineno;
- tree meth, mdecl, c;
- tree cclass, class_wfl;
+ tree mdecl, c;
if (!ctxp->static_initialized || java_error_count)
return;
- cclass = TREE_TYPE (ctxp->current_parsed_class);
- class_wfl = build_expr_wfl (DECL_NAME (TYPE_NAME (cclass)),
- input_filename, 0, 0);
-
- saved_lineno = lineno;
- lineno = 0;
- meth = make_node (FUNCTION_TYPE);
- TREE_TYPE (meth) = void_type_node;
- TYPE_ARG_TYPES (meth) = NULL_TREE;
- mdecl = add_method (cclass, ACC_STATIC, clinit_identifier_node,
- build_java_signature (meth));
- lineno = saved_lineno;
-
- DECL_SOURCE_LINE (mdecl) = 1;
- DECL_SOURCE_LINE_MERGE (mdecl, 1);
- source_start_java_method (mdecl);
- enter_block ();
+ mdecl = create_artificial_method (TREE_TYPE (ctxp->current_parsed_class),
+ ACC_STATIC, void_type_node,
+ clinit_identifier_node, end_params_node);
+ start_artificial_method_body (mdecl);
/* Keep initialization in order to enforce 8.5 */
ctxp->static_initialized = nreverse (ctxp->static_initialized);
@@ -2715,11 +3251,11 @@ maybe_generate_clinit ()
/* We build the assignment expression that will initialize the
field to its value. There are strict rules on static
initializers (8.5). FIXME */
- java_method_add_stmt (mdecl, c);
+ java_method_add_stmt (mdecl,
+ build_debugable_stmt (EXPR_WFL_LINECOL (c), c));
}
- BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (mdecl)) = exit_block ();
- exit_block ();
+ end_artificial_method_body (mdecl);
ctxp->static_initialized = NULL_TREE;
}
@@ -2734,7 +3270,8 @@ static int patch_stage;
/* Check the method declaration and add the method to its current
class. If the argument list is known to contain incomplete types,
the method is partially added and the registration will be resume
- once the method arguments resolved */
+ once the method arguments resolved. If TYPE is NULL, we're dealing
+ with a constructor. */
static tree
method_header (flags, type, mdecl, throws)
@@ -2744,33 +3281,58 @@ method_header (flags, type, mdecl, throws)
tree meth = TREE_VALUE (mdecl);
tree id = TREE_PURPOSE (mdecl);
tree this_class = TREE_TYPE (ctxp->current_parsed_class);
- tree handle_class = CLASS_TO_HANDLE_TYPE (this_class);
- tree meth_name, returned_type;
+ tree type_wfl = NULL_TREE;
+ tree meth_name = NULL_TREE, current, orig_arg;
int saved_lineno;
+ int constructor_ok = 0, must_chain;
check_modifiers_consistency (flags);
/* There are some forbidden modifiers for an abstract method and its
class must be abstract as well. */
- if (flags & ACC_ABSTRACT)
+ if (type && (flags & ACC_ABSTRACT))
{
ABSTRACT_CHECK (flags, ACC_PRIVATE, id, "Private");
ABSTRACT_CHECK (flags, ACC_STATIC, id, "Static");
ABSTRACT_CHECK (flags, ACC_FINAL, id, "Final");
ABSTRACT_CHECK (flags, ACC_NATIVE, id, "Native");
ABSTRACT_CHECK (flags, ACC_SYNCHRONIZED,id, "Synchronized");
- if (!CLASS_ABSTRACT (TYPE_NAME (this_class)))
+ if (!CLASS_ABSTRACT (TYPE_NAME (this_class))
+ && !CLASS_INTERFACE (TYPE_NAME (this_class)))
parse_error_context
(id, "Class `%s' must be declared abstract to define abstract "
"method `%s'",
IDENTIFIER_POINTER (DECL_NAME (ctxp->current_parsed_class)),
IDENTIFIER_POINTER (EXPR_WFL_NODE (id)));
}
-
+ /* Things to be checked when declaring a constructor */
+ if (!type)
+ {
+ int ec = java_error_count;
+ /* 8.6: Constructor declarations: we might be trying to define a
+ method without specifying a return type. */
+ if (EXPR_WFL_NODE (id) != ctxp->current_parsed_class_un)
+ parse_error_context
+ (id, "Invalid method declaration, return type required");
+ /* 8.6.3: Constructor modifiers */
+ else
+ {
+ JCONSTRUCTOR_CHECK (flags, ACC_ABSTRACT, id, "abstract");
+ JCONSTRUCTOR_CHECK (flags, ACC_STATIC, id, "static");
+ JCONSTRUCTOR_CHECK (flags, ACC_FINAL, id, "final");
+ JCONSTRUCTOR_CHECK (flags, ACC_NATIVE, id, "native");
+ JCONSTRUCTOR_CHECK (flags, ACC_SYNCHRONIZED, id, "synchronized");
+ }
+ /* If we found error here, we don't consider it's OK to tread
+ the method definition as a constructor, for the rest of this
+ function */
+ if (ec == java_error_count)
+ constructor_ok = 1;
+ }
/* Method declared within the scope of an interface are implicitly
abstract and public. Conflicts with other erroneously provided
- modifiers are check right after. */
+ modifiers are checked right after. */
if (CLASS_INTERFACE (TYPE_NAME (this_class)))
{
@@ -2788,18 +3350,31 @@ method_header (flags, type, mdecl, throws)
/* Modifiers context reset moved up, so abstract method declaration
modifiers can be later checked. */
- meth_name = EXPR_WFL_NODE (id);
+ /* Set constructor returned type to void and method name to <init>,
+ unless we found an error identifier the constructor (in which
+ case we retain the original name) */
+ if (!type)
+ {
+ type = void_type_node;
+ if (constructor_ok)
+ meth_name = init_identifier_node;
+ }
+ else
+ meth_name = EXPR_WFL_NODE (id);
+
+ /* Do the returned type resolution and registration if necessary */
+ SET_TYPE_FOR_RESOLUTION (type, type_wfl, must_chain);
- if (unresolved_type_p (type, &returned_type))
+ if (meth_name)
+ type = build_array_from_name (type, type_wfl, meth_name, &meth_name);
+ EXPR_WFL_NODE (id) = meth_name;
+ PROMOTE_RECORD_IF_COMPLETE (type, must_chain);
+
+ if (must_chain)
{
- if (returned_type)
- TREE_TYPE (meth) = returned_type;
- else
- {
- patch_stage = JDEP_METHOD_RETURN;
- TREE_TYPE (meth) =
- register_incomplete_type (patch_stage, type, id, NULL_TREE);
- }
+ patch_stage = JDEP_METHOD_RETURN;
+ register_incomplete_type (patch_stage, type_wfl, id, type);
+ TREE_TYPE (meth) = GET_REAL_TYPE (type);
}
else
TREE_TYPE (meth) = type;
@@ -2811,6 +3386,9 @@ method_header (flags, type, mdecl, throws)
lineno = (ctxp->first_ccb_indent1 ? ctxp->first_ccb_indent1 :
EXPR_WFL_LINENO (id));
+ /* Remember the original argument list */
+ orig_arg = TYPE_ARG_TYPES (meth);
+
if (patch_stage) /* includes ret type and/or all args */
{
jdep *jdep;
@@ -2826,41 +3404,150 @@ method_header (flags, type, mdecl, throws)
register_incomplete_type (JDEP_METHOD_END, NULL_TREE, meth, NULL_TREE);
}
else
+ meth = add_method (this_class, flags, meth_name,
+ build_java_signature (meth));
+
+ /* Fix the method argument list so we have the argument name
+ information */
+ fix_method_argument_names (orig_arg, meth);
+
+ /* Register the parameter number and re-install the current line
+ number */
+ DECL_MAX_LOCALS (meth) = ctxp->formal_parameter_number+1;
+ lineno = saved_lineno;
+
+ /* Register exception specified by the `throws' keyword for
+ resolution and set the method decl appropriate field to the list.
+ Note: the grammar ensures that what we get here are class
+ types. */
+ if (throws)
{
- tree signature = build_java_signature (meth);
- tree arg, orig_arg;
- /* Save original argument list, including argument's names */
- orig_arg = TYPE_ARG_TYPES (meth);
- /* Add the method to its class */
- meth = add_method (this_class, flags, meth_name, signature);
- /* Fix the method argument list so we have the argument name
- information */
- arg = TYPE_ARG_TYPES (TREE_TYPE (meth));
- if (TREE_CODE (TREE_TYPE (meth)) == METHOD_TYPE)
- {
- TREE_PURPOSE (arg) = this_identifier_node;
- arg = TREE_CHAIN (arg);
- }
- while (orig_arg)
- {
- TREE_PURPOSE (arg) = TREE_PURPOSE (orig_arg);
- orig_arg = TREE_CHAIN (orig_arg);
- arg = TREE_CHAIN (arg);
+ throws = nreverse (throws);
+ for (current = throws; current; current = TREE_CHAIN (current))
+ {
+ register_incomplete_type (JDEP_EXCEPTION, TREE_VALUE (current),
+ NULL_TREE, NULL_TREE);
+ JDEP_GET_PATCH (CLASSD_LAST (ctxp->classd_list)) =
+ &TREE_VALUE (current);
}
+ DECL_FUNCTION_THROWS (meth) = throws;
}
- DECL_MAX_LOCALS (meth) = ctxp->formal_parameter_number+1;
- lineno = saved_lineno;
+
/* We set the DECL_NAME to ID so we can track the location where
the function was declared. This allow us to report
redefinition error accurately. When method are verified,
DECL_NAME is reinstalled properly (using the content of the
WFL node ID) (see check_method_redefinition). We don't do that
- when Object is being defined. */
+ when Object is being defined. Constructor <init> names will be
+ reinstalled the same way. */
if (TREE_TYPE (ctxp->current_parsed_class) != object_type_node)
DECL_NAME (meth) = id;
+
+ /* Set the flag if we correctly processed a constructor */
+ if (constructor_ok)
+ DECL_CONSTRUCTOR_P (meth) = 1;
+
+ /* Eventually set the @deprecated tag flag */
+ CHECK_DEPRECATED (meth);
+
return meth;
}
+static void
+fix_method_argument_names (orig_arg, meth)
+ tree orig_arg, meth;
+{
+ tree arg = TYPE_ARG_TYPES (TREE_TYPE (meth));
+ if (TREE_CODE (TREE_TYPE (meth)) == METHOD_TYPE)
+ {
+ TREE_PURPOSE (arg) = this_identifier_node;
+ arg = TREE_CHAIN (arg);
+ }
+ while (orig_arg != end_params_node)
+ {
+ TREE_PURPOSE (arg) = TREE_PURPOSE (orig_arg);
+ orig_arg = TREE_CHAIN (orig_arg);
+ arg = TREE_CHAIN (arg);
+ }
+}
+
+/* Complete the method declaration with METHOD_BODY. */
+
+static void
+finish_method_declaration (method_body)
+ tree method_body;
+{
+ BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (current_function_decl)) = method_body;
+ maybe_absorb_scoping_blocks ();
+ /* Exit function's body */
+ exit_block ();
+ /* Merge last line of the function with first line, directly in the
+ function decl. It will be used to emit correct debug info. */
+ DECL_SOURCE_LINE_MERGE (current_function_decl, ctxp->last_ccb_indent1);
+ /* So we don't have an irrelevant function declaration context for
+ the next static block we'll see. */
+ current_function_decl = NULL_TREE;
+}
+
+/* Build a an error message for constructor circularity errors. */
+
+static char *
+constructor_circularity_msg (from, to)
+ tree from, to;
+{
+ static char string [4096];
+ char *t = strdup (lang_printable_name (from, 0));
+ sprintf (string, "`%s' invokes `%s'", t, lang_printable_name (to, 0));
+ free (t);
+ return string;
+}
+
+/* Verify a circular call to METH. Return 1 if an error is found, 0
+ otherwise. */
+
+static int
+verify_constructor_circularity (meth, current)
+ tree meth, current;
+{
+ static tree list = NULL_TREE;
+ tree c;
+ for (c = DECL_CONSTRUCTOR_CALLS (current); c; c = TREE_CHAIN (c))
+ {
+ if (TREE_VALUE (c) == meth)
+ {
+ char *t;
+ if (list)
+ {
+ tree liste;
+ list = nreverse (list);
+ for (liste = list; liste; liste = TREE_CHAIN (liste))
+ {
+ parse_error_context
+ (TREE_PURPOSE (TREE_PURPOSE (liste)),
+ constructor_circularity_msg
+ (TREE_VALUE (liste), TREE_VALUE (TREE_PURPOSE (liste))));
+ java_error_count--;
+ }
+ }
+ t = strdup (lang_printable_name (meth, 0));
+ parse_error_context (TREE_PURPOSE (c),
+ "%s: recursive invocation of constructor `%s'",
+ constructor_circularity_msg (current, meth), t);
+ free (t);
+ list = NULL_TREE;
+ return 1;
+ }
+ }
+ for (c = DECL_CONSTRUCTOR_CALLS (current); c; c = TREE_CHAIN (c))
+ {
+ list = tree_cons (c, current, list);
+ if (verify_constructor_circularity (meth, TREE_VALUE (c)))
+ return 1;
+ list = TREE_CHAIN (list);
+ }
+ return 0;
+}
+
/* Check modifiers that can be declared but exclusively */
static void
@@ -2887,8 +3574,7 @@ check_abstract_method_header (meth)
{
int flags = get_access_flags_from_decl (meth);
/* DECL_NAME might still be a WFL node */
- tree name = (TREE_CODE (DECL_NAME (meth)) == EXPR_WITH_FILE_LOCATION ?
- EXPR_WFL_NODE (DECL_NAME (meth)) : DECL_NAME (meth));
+ tree name = GET_METHOD_NAME (meth);
OBSOLETE_MODIFIER_WARNING (MODIFIER_WFL (ABSTRACT_TK), flags,
ACC_ABSTRACT, "abstract method `%s'",
@@ -2913,17 +3599,33 @@ method_declarator (id, list)
tree arg_types = NULL_TREE, current, node;
tree meth = make_node (FUNCTION_TYPE);
jdep *jdep;
- int incomplete = 0;
patch_stage = JDEP_NO_PATCH;
for (current = list; current; current = TREE_CHAIN (current))
{
+ int must_chain = 0;
tree wfl_name = TREE_PURPOSE (current);
tree type = TREE_VALUE (current);
tree name = EXPR_WFL_NODE (wfl_name);
- tree patchable_type = NULL_TREE, already;
- tree arg_node, returned_type;
+ tree already, arg_node;
+ tree type_wfl = NULL_TREE;
+ tree real_type;
+
+ /* Obtain a suitable type for resolution, if necessary */
+ SET_TYPE_FOR_RESOLUTION (type, type_wfl, must_chain);
+
+ /* Process NAME, as it may specify extra dimension(s) for it */
+ type = build_array_from_name (type, type_wfl, name, &name);
+ EXPR_WFL_NODE (wfl_name) = name;
+
+ real_type = GET_REAL_TYPE (type);
+ if (TREE_CODE (real_type) == RECORD_TYPE)
+ {
+ real_type = promote_type (real_type);
+ if (TREE_CODE (type) == TREE_LIST)
+ TREE_PURPOSE (type) = real_type;
+ }
/* Check redefinition */
for (already = arg_types; already; already = TREE_CHAIN (already))
@@ -2939,27 +3641,23 @@ method_declarator (id, list)
/* If we've an incomplete argument type, we know there is a location
to patch when the type get resolved, later. */
jdep = NULL;
- if (unresolved_type_p (type, &returned_type))
+ if (must_chain)
{
- if (returned_type)
- type = returned_type;
- else
- {
- patch_stage = JDEP_METHOD;
- type = register_incomplete_type (patch_stage, type,
- wfl_name, NULL_TREE);
- jdep = CLASSD_LAST (ctxp->classd_list);
- JDEP_MISC (jdep) = id;
- }
+ patch_stage = JDEP_METHOD;
+ type = register_incomplete_type (patch_stage,
+ type_wfl, wfl_name, type);
+ jdep = CLASSD_LAST (ctxp->classd_list);
+ JDEP_MISC (jdep) = id;
}
+
/* The argument node: a name and a (possibly) incomplete type */
- arg_node = build_tree_list (name, type);
+ arg_node = build_tree_list (name, real_type);
if (jdep)
JDEP_GET_PATCH (jdep) = &TREE_VALUE (arg_node);
TREE_CHAIN (arg_node) = arg_types;
arg_types = arg_node;
}
- TYPE_ARG_TYPES (meth) = nreverse (arg_types);
+ TYPE_ARG_TYPES (meth) = chainon (nreverse (arg_types), end_params_node);
node = build_tree_list (id, meth);
return node;
}
@@ -3034,7 +3732,6 @@ static int
parser_check_super (super_decl, this_decl, wfl)
tree super_decl, this_decl, wfl;
{
- tree this_type = TREE_TYPE (this_decl);
tree super_type = TREE_TYPE (super_decl);
/* SUPER should be a CLASS (neither an array nor an interface) */
@@ -3072,11 +3769,7 @@ static void
create_jdep_list (ctxp)
struct parser_ctxt *ctxp;
{
- jdeplist *new = malloc (sizeof (jdeplist));
-
- if (!new)
- fatal ("Can't alloc jdeplist - create_jdep_list");
-
+ jdeplist *new = (jdeplist *)xmalloc (sizeof (jdeplist));
new->first = new->last = NULL;
new->next = ctxp->classd_list;
ctxp->classd_list = new;
@@ -3096,25 +3789,32 @@ reverse_jdep_list (ctxp)
return prev;
}
-/* Create a fake pointer based on the ID stored in the WFL */
+/* Create a fake pointer based on the ID stored in
+ TYPE_NAME. TYPE_NAME can be a WFL or a incomplete type asking to be
+ registered again. */
static tree
-obtain_incomplete_type (wfl)
- tree wfl;
+obtain_incomplete_type (type_name)
+ tree type_name;
{
- tree ptr;
- tree name = EXPR_WFL_NODE (wfl);
+ tree ptr, name;
+
+ if (TREE_CODE (type_name) == EXPR_WITH_FILE_LOCATION)
+ name = EXPR_WFL_NODE (type_name);
+ else if (INCOMPLETE_TYPE_P (type_name))
+ name = TYPE_NAME (type_name);
+ else
+ fatal ("invalid type name - obtain_incomplete_type");
for (ptr = ctxp->incomplete_class; ptr; ptr = TREE_CHAIN (ptr))
- if (TYPE_NAME (TREE_PURPOSE (ptr)) == name)
+ if (TYPE_NAME (ptr) == name)
break;
if (!ptr)
{
- tree core;
push_obstacks (&permanent_obstack, &permanent_obstack);
- BUILD_PTR_FROM_NAME (core, name);
- ptr = build_tree_list (core, NULL_TREE);
+ BUILD_PTR_FROM_NAME (ptr, name);
+ layout_type (ptr);
pop_obstacks ();
TREE_CHAIN (ptr) = ctxp->incomplete_class;
ctxp->incomplete_class = ptr;
@@ -3133,10 +3833,8 @@ register_incomplete_type (kind, wfl, decl, ptr)
int kind;
tree wfl, decl, ptr;
{
- jdep *new = malloc (sizeof (jdep));
+ jdep *new = (jdep *)xmalloc (sizeof (jdep));
- if (!new)
- fatal ("Can't allocate new jdep - register_incomplete_type");
if (!ptr && kind != JDEP_METHOD_END) /* JDEP_METHOD_END is a mere marker */
ptr = obtain_incomplete_type (wfl);
@@ -3185,6 +3883,10 @@ java_check_circular_reference ()
}
}
+/* safe_layout_class just makes sure that we can load a class without
+ disrupting the current_class, input_file, lineno, etc, information
+ about the class processed currently. */
+
void
safe_layout_class (class)
tree class;
@@ -3192,11 +3894,12 @@ safe_layout_class (class)
tree save_current_class = current_class;
char *save_input_filename = input_filename;
int save_lineno = lineno;
-
+
push_obstacks (&permanent_obstack, &permanent_obstack);
+
layout_class (class);
pop_obstacks ();
-
+
current_class = save_current_class;
input_filename = save_input_filename;
lineno = save_lineno;
@@ -3209,20 +3912,18 @@ jdep_resolve_class (dep)
{
tree decl;
- if (!JDEP_RESOLVED_P (dep))
+ if (JDEP_RESOLVED_P (dep))
+ decl = JDEP_RESOLVED_DECL (dep);
+ else
{
- decl =
- resolve_class (JDEP_TO_RESOLVE (dep), JDEP_DECL (dep), JDEP_WFL (dep));
+ decl = resolve_class (JDEP_TO_RESOLVE (dep),
+ JDEP_DECL (dep), JDEP_WFL (dep));
JDEP_RESOLVED (dep, decl);
}
- else
- decl = JDEP_RESOLVED_DECL (dep);
-
+
if (!decl)
- {
- complete_class_report_errors (dep);
- return NULL_TREE;
- }
+ complete_class_report_errors (dep);
+
return decl;
}
@@ -3231,10 +3932,10 @@ jdep_resolve_class (dep)
void
java_complete_class ()
{
- tree current;
tree cclass;
jdeplist *cclassd;
int error_found;
+ tree type;
push_obstacks (&permanent_obstack, &permanent_obstack);
@@ -3246,7 +3947,7 @@ java_complete_class ()
/* Rever things so we have the right order */
ctxp->class_list = nreverse (ctxp->class_list);
ctxp->classd_list = reverse_jdep_list (ctxp);
-
+
for (cclassd = ctxp->classd_list, cclass = ctxp->class_list;
cclass && cclassd;
cclass = TREE_CHAIN (cclass), cclassd = CLASSD_CHAIN (cclassd))
@@ -3255,7 +3956,6 @@ java_complete_class ()
for (dep = CLASSD_FIRST (cclassd); dep; dep = JDEP_CHAIN (dep))
{
tree decl;
-
if (!(decl = jdep_resolve_class (dep)))
continue;
@@ -3276,12 +3976,12 @@ java_complete_class ()
tree field_decl = JDEP_DECL (dep);
tree field_type = TREE_TYPE (decl);
push_obstacks (&permanent_obstack, &permanent_obstack);
-#if ! JAVA_PROMOTE_TO_INT
if (TREE_CODE (field_type) == RECORD_TYPE)
-#endif
field_type = promote_type (field_type);
pop_obstacks ();
TREE_TYPE (field_decl) = field_type;
+ DECL_ALIGN (field_decl) = 0;
+ layout_decl (field_decl, 0);
SOURCE_FRONTEND_DEBUG
(("Completed field/var decl `%s' with `%s'",
IDENTIFIER_POINTER (DECL_NAME (field_decl)),
@@ -3295,7 +3995,9 @@ java_complete_class ()
{
if (decl)
{
- tree type = promote_type (TREE_TYPE(decl));
+ type = TREE_TYPE(decl);
+ if (TREE_CODE (type) == RECORD_TYPE)
+ type = promote_type (type);
JDEP_APPLY_PATCH (dep, type);
SOURCE_FRONTEND_DEBUG
(((JDEP_KIND (dep) == JDEP_METHOD_RETURN ?
@@ -3333,14 +4035,12 @@ java_complete_class ()
parser_add_interface (JDEP_DECL (dep), decl, JDEP_WFL (dep));
break;
+ case JDEP_PARM:
case JDEP_VARIABLE:
- JDEP_APPLY_PATCH (dep, promote_type (TREE_TYPE (decl)));
- SOURCE_FRONTEND_DEBUG
- (("Completing variable `%s' with type `%s'",
- (TREE_CODE (JDEP_DECL_WFL (dep)) == EXPR_WITH_FILE_LOCATION ?
- IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_DECL_WFL (dep))) :
- IDENTIFIER_POINTER (DECL_NAME (JDEP_DECL_WFL (dep)))),
- IDENTIFIER_POINTER (DECL_NAME (decl))));
+ type = TREE_TYPE(decl);
+ if (TREE_CODE (type) == RECORD_TYPE)
+ type = promote_type (type);
+ JDEP_APPLY_PATCH (dep, type);
break;
case JDEP_TYPE:
@@ -3350,16 +4050,16 @@ java_complete_class ()
tree_code_name [TREE_CODE (JDEP_DECL (dep))]));
break;
- case JDEP_PARM:
- JDEP_APPLY_PATCH (dep, promote_type (TREE_TYPE (decl)));
+ case JDEP_EXCEPTION:
+ JDEP_APPLY_PATCH (dep, TREE_TYPE (decl));
SOURCE_FRONTEND_DEBUG
- (("Completing parameter `%s' with type `%s'",
- IDENTIFIER_POINTER (JDEP_MISC (dep)),
- IDENTIFIER_POINTER (DECL_NAME (decl))));
+ (("Completing `%s' `throws' argument node",
+ IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_WFL (dep)))));
break;
default:
- fatal ("incomplete switch - java_complete_class");
+ fatal ("Can't handle patch code %d - java_complete_class",
+ JDEP_KIND (dep));
}
}
}
@@ -3376,8 +4076,22 @@ resolve_class (class_type, decl, cl)
{
char *name = IDENTIFIER_POINTER (TYPE_NAME (class_type));
char *base = name;
- tree resolved_type, resolved_type_decl;
+ tree resolved_type = TREE_TYPE (class_type);
+ tree resolved_type_decl;
+ if (resolved_type != NULL_TREE)
+ {
+ tree resolved_type_decl = TYPE_NAME (resolved_type);
+ if (resolved_type_decl == NULL_TREE
+ || TREE_CODE (resolved_type_decl) == IDENTIFIER_NODE)
+ {
+ resolved_type_decl = build_decl (TYPE_DECL,
+ TYPE_NAME (class_type),
+ resolved_type);
+ }
+ return resolved_type_decl;
+ }
+
/* 1- Check to see if we have an array. If true, find what we really
want to resolve */
while (name[0] == '[')
@@ -3398,6 +4112,7 @@ resolve_class (class_type, decl, cl)
if (TREE_CODE (resolved_type) == RECORD_TYPE)
resolved_type = promote_type (resolved_type);
resolved_type = build_java_array_type (resolved_type, -1);
+ CLASS_LOADED_P (resolved_type) = 1;
name--;
}
/* Build a fake decl for this, since this is what is expected to
@@ -3407,14 +4122,16 @@ resolve_class (class_type, decl, cl)
/* Figure how those two things are important for error report. FIXME */
DECL_SOURCE_LINE (resolved_type_decl) = 0;
DECL_SOURCE_FILE (resolved_type_decl) = input_filename;
+ TYPE_NAME (class_type) = TYPE_NAME (resolved_type);
}
+ TREE_TYPE (class_type) = resolved_type;
return resolved_type_decl;
}
/* Effectively perform the resolution of class CLASS_TYPE. DECL or CL
are used to report error messages. */
-static tree
+tree
do_resolve_class (class_type, decl, cl)
tree class_type;
tree decl;
@@ -3432,7 +4149,6 @@ do_resolve_class (class_type, decl, cl)
/* 2- And check for the type in the current compilation unit. If it fails,
try with a name qualified with the package name if appropriate. */
-
if ((new_class_decl = IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type))))
{
if (!CLASS_LOADED_P (TREE_TYPE (new_class_decl)) &&
@@ -3445,6 +4161,9 @@ do_resolve_class (class_type, decl, cl)
if (!QUALIFIED_P (TYPE_NAME (class_type)) && ctxp->package)
TYPE_NAME (class_type) = merge_qualified_name (ctxp->package,
TYPE_NAME (class_type));
+#if 1
+ if (!(new_class_decl = IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type))))
+ load_class (TYPE_NAME (class_type), 0);
if ((new_class_decl = IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type))))
{
if (!CLASS_LOADED_P (TREE_TYPE (new_class_decl)) &&
@@ -3452,6 +4171,27 @@ do_resolve_class (class_type, decl, cl)
load_class (TYPE_NAME (class_type), 0);
return IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type));
}
+#else
+ new_name = TYPE_NAME (class_type);
+ if ((new_class_decl = IDENTIFIER_CLASS_VALUE (new_name)) != NULL_TREE)
+ {
+ if (!CLASS_LOADED_P (TREE_TYPE (new_class_decl)) &&
+ !CLASS_FROM_SOURCE_P (TREE_TYPE (new_class_decl)))
+ load_class (new_name, 0);
+ return IDENTIFIER_CLASS_VALUE (new_name);
+ }
+ else
+ {
+ tree class = read_class (new_name);
+ if (class != NULL_TREE)
+ {
+ tree decl = IDENTIFIER_CLASS_VALUE (new_name);
+ if (decl == NULL_TREE)
+ decl = push_class (class, new_name);
+ return decl;
+ }
+ }
+#endif
TYPE_NAME (class_type) = original_name;
/* 3- Check an other compilation unit that bears the name of type */
@@ -3474,17 +4214,59 @@ do_resolve_class (class_type, decl, cl)
}
/* Resolve NAME and lay it out (if not done and if not the current
- parsed class). Return a decl node. */
+ parsed class). Return a decl node. This function is meant to be
+ called when type resolution is necessary during the walk pass. */
static tree
-resolve_and_layout (name, cl)
- tree name;
+resolve_and_layout (something, cl)
+ tree something;
tree cl;
{
- tree decl = resolve_no_layout (name, cl);
- if (decl && TREE_TYPE (decl) != current_class
- && !CLASS_LOADED_P (TREE_TYPE (decl)))
+ tree decl;
+
+ /* Don't do that on the current class */
+ if (something == current_class)
+ return TYPE_NAME (current_class);
+
+ /* Don't do anything for void and other primitive types */
+ if (JPRIMITIVE_TYPE_P (something) || something == void_type_node)
+ return NULL_TREE;
+
+ /* Pointer types can be reall pointer types or fake pointers. When
+ finding a real pointer, recheck for primitive types */
+ if (TREE_CODE (something) == POINTER_TYPE)
+ {
+ if (TREE_TYPE (something))
+ {
+ something = TREE_TYPE (something);
+ if (JPRIMITIVE_TYPE_P (something) || something == void_type_node)
+ return NULL_TREE;
+ }
+ else
+ something = TYPE_NAME (something);
+ }
+
+ /* Don't do anything for arrays of primitive types */
+ if (TREE_CODE (something) == RECORD_TYPE && TYPE_ARRAY_P (something)
+ && JPRIMITIVE_TYPE_P (TYPE_ARRAY_ELEMENT (something)))
+ return NULL_TREE;
+
+ /* If something is not and IDENTIFIER_NODE, it can be a a TYPE_DECL
+ or a real TYPE */
+ if (TREE_CODE (something) != IDENTIFIER_NODE)
+ something = (TREE_CODE (TYPE_NAME (something)) == TYPE_DECL ?
+ DECL_NAME (TYPE_NAME (something)) : TYPE_NAME (something));
+
+ if (!(decl = resolve_no_layout (something, cl)))
+ return NULL_TREE;
+
+ /* Resolve and layout if necessary */
+ layout_class_methods (TREE_TYPE (decl));
+ if (CLASS_FROM_SOURCE_P (TREE_TYPE (decl)))
+ CHECK_METHODS (decl);
+ if (TREE_TYPE (decl) != current_class && !CLASS_LOADED_P (TREE_TYPE (decl)))
safe_layout_class (TREE_TYPE (decl));
+
return decl;
}
@@ -3504,8 +4286,8 @@ resolve_no_layout (name, cl)
return decl;
}
-/* Called to report errors. Skip leader '[' in a complex array type
- description that failed to be resolved. */
+/* Called when reporting errors. Skip leader '[' in a complex array
+ type description that failed to be resolved. */
static char *
purify_type_name (name)
@@ -3522,25 +4304,31 @@ static void
complete_class_report_errors (dep)
jdep *dep;
{
+ char *name;
+
+ if (!JDEP_WFL (dep))
+ return;
+
+ name = IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_WFL (dep)));
switch (JDEP_KIND (dep))
{
case JDEP_SUPER:
parse_error_context
(JDEP_WFL (dep), "Superclass `%s' of class `%s' not found",
- IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_WFL (dep))),
+ purify_type_name (name),
IDENTIFIER_POINTER (DECL_NAME (JDEP_DECL (dep))));
break;
case JDEP_FIELD:
parse_error_context
(JDEP_WFL (dep), "Type `%s' not found in declaration of field `%s'",
- IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_WFL (dep))),
+ purify_type_name (name),
IDENTIFIER_POINTER (DECL_NAME (JDEP_DECL (dep))));
break;
case JDEP_METHOD: /* Covers arguments */
parse_error_context
(JDEP_WFL (dep), "Type `%s' not found in the declaration of the "
"argument `%s' of method `%s'",
- IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_WFL (dep))),
+ purify_type_name (name),
IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_DECL_WFL (dep))),
IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_MISC (dep))));
break;
@@ -3548,7 +4336,7 @@ complete_class_report_errors (dep)
parse_error_context
(JDEP_WFL (dep), "Type `%s' not found in the declaration of the "
"return type of method `%s'",
- IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_WFL (dep))),
+ purify_type_name (name),
IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_DECL_WFL (dep))));
break;
case JDEP_INTERFACE:
@@ -3562,9 +4350,19 @@ complete_class_report_errors (dep)
parse_error_context
(JDEP_WFL (dep), "Type `%s' not found in the declaration of the "
"local variable `%s'",
- purify_type_name (IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_WFL (dep)))),
+ purify_type_name (IDENTIFIER_POINTER
+ (EXPR_WFL_NODE (JDEP_WFL (dep)))),
IDENTIFIER_POINTER (DECL_NAME (JDEP_DECL (dep))));
break;
+ case JDEP_EXCEPTION: /* As specified by `throws' */
+ parse_error_context
+ (JDEP_WFL (dep), "Class `%s' not found in `throws'",
+ IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_WFL (dep))));
+ break;
+ default:
+ /* Fix for -Wall. Just break doing nothing. The error will be
+ caught later */
+ break;
}
}
@@ -3575,35 +4373,107 @@ java_check_final ()
{
}
+/* Return a static string containing the DECL prototype string. If
+ DECL is a constructor, use the class name instead of the form
+ <init> */
+
+static char *
+get_printable_method_name (decl)
+ tree decl;
+{
+ char *to_return;
+ tree name = NULL_TREE;
+
+ if (DECL_CONSTRUCTOR_P (decl))
+ {
+ name = DECL_NAME (decl);
+ DECL_NAME (decl) = DECL_NAME (TYPE_NAME (DECL_CONTEXT (decl)));
+ }
+
+ to_return = lang_printable_name (decl, 0);
+ if (DECL_CONSTRUCTOR_P (decl))
+ DECL_NAME (decl) = name;
+
+ return to_return;
+}
+
+/* Reinstall the proper DECL_NAME on METHOD. Return 0 if the method
+ nevertheless needs to be verfied, 1 otherwise. */
+
static int
-check_method_redefinition (class, method)
- tree class, method;
+reset_method_name (method)
+ tree method;
{
- tree redef, name;
- tree cl = DECL_NAME (method);
- tree sig = TYPE_LANG_SPECIFIC (TREE_TYPE (method))->signature;
- /* decl name of generated <clinit> doesn't need to be fixed and
- checked */
- if (DECL_NAME (method) != clinit_identifier_node)
+ if (DECL_NAME (method) != clinit_identifier_node
+ && DECL_NAME (method) != finit_identifier_node)
{
/* NAME is just the plain name when Object is being defined */
- if (class != object_type_node)
- name = DECL_NAME (method) = EXPR_WFL_NODE (DECL_NAME (method));
- else
- name = DECL_NAME (method);
+ if (DECL_CONTEXT (method) != object_type_node)
+ DECL_NAME (method) = (DECL_CONSTRUCTOR_P (method) ?
+ init_identifier_node : GET_METHOD_NAME (method));
+ return 0;
}
else
+ return 1;
+}
+
+/* Return the name of METHOD_DECL, when DECL_NAME is a WFL */
+
+tree
+java_get_real_method_name (method_decl)
+ tree method_decl;
+{
+ tree method_name = DECL_NAME (method_decl);
+ if (DECL_CONSTRUCTOR_P (method_decl))
+ return init_identifier_node;
+
+ /* Explain here why METHOD_DECL doesn't have the DECL_CONSTRUCTUR_P
+ and still can be a constructor. FIXME */
+
+ /* Don't confuse method only bearing the name of their class as
+ constructors */
+ else if (!CLASS_FROM_SOURCE_P (DECL_CONTEXT (method_decl))
+ && ctxp
+ && ctxp->current_parsed_class_un == EXPR_WFL_NODE (method_name)
+ && get_access_flags_from_decl (method_decl) <= ACC_PROTECTED
+ && TREE_TYPE (TREE_TYPE (method_decl)) == void_type_node)
+ return init_identifier_node;
+ else
+ return EXPR_WFL_NODE (method_name);
+}
+
+/* Track method being redefined inside the same class. As a side
+ effect, set DECL_NAME to an IDENTIFIER (prior entering this
+ function it's a FWL, so we can track errors more accurately */
+
+static int
+check_method_redefinition (class, method)
+ tree class, method;
+{
+ tree redef, name;
+ tree cl = DECL_NAME (method);
+ tree sig = TYPE_ARGUMENT_SIGNATURE (TREE_TYPE (method));
+ /* decl name of artificial <clinit> and $finit$ doesn't need to be
+ fixed and checked */
+
+ /* Reset the method name before running the check. If it returns 1,
+ the method doesn't need to be verified with respect to method
+ redeclaration and we return 0 */
+ if (reset_method_name (method))
return 0;
-
+
+ name = DECL_NAME (method);
for (redef = TYPE_METHODS (class); redef; redef = TREE_CHAIN (redef))
{
- struct lang_type *t = TYPE_LANG_SPECIFIC (TREE_TYPE (redef));
-
- if (! t || (redef == method))
+ if (redef == method)
break;
- if (DECL_NAME (redef) == name && sig == t->signature)
+ if (DECL_NAME (redef) == name
+ && sig == TYPE_ARGUMENT_SIGNATURE (TREE_TYPE (redef)))
{
- parse_error_context (cl, "Duplicate method declaration");
+ parse_error_context
+ (cl, "Duplicate %s declaration `%s'",
+ (DECL_CONSTRUCTOR_P (redef) ? "constructor" : "method"),
+ get_printable_method_name (redef));
return 1;
}
}
@@ -3618,40 +4488,92 @@ static void
java_check_regular_methods (class_decl)
tree class_decl;
{
+ int saw_constructor = 0;
tree method;
tree class = CLASS_TO_HANDLE_TYPE (TREE_TYPE (class_decl));
tree super_class = CLASSTYPE_SUPER (class);
- int seen_constructor = 0;
+ tree saved_found_wfl = NULL_TREE, found = NULL_TREE;
+ tree mthrows;
+
+ /* It is not necessary to check methods defined in java.lang.Object */
+ if (class == object_type_node)
+ return;
- TYPE_METHODS (class) = nreverse (TYPE_METHODS (class));
+ if (!TYPE_NVIRTUALS (class))
+ TYPE_METHODS (class) = nreverse (TYPE_METHODS (class));
/* Should take interfaces into account. FIXME */
for (method = TYPE_METHODS (class); method; method = TREE_CHAIN (method))
{
- tree found, sig;
+ tree sig;
tree method_wfl = DECL_NAME (method);
int aflags;
- if (DECL_CONSTRUCTOR_P (method))
- seen_constructor = 1;
+ /* If we previously found something and its name was saved,
+ reinstall it now */
+ if (found && saved_found_wfl)
+ {
+ DECL_NAME (found) = saved_found_wfl;
+ saved_found_wfl = NULL_TREE;
+ }
/* Check for redefinitions */
if (check_method_redefinition (class, method))
continue;
- sig = build_java_argument_signature (TREE_TYPE (method));
+ /* If we see one constructor a mark so we don't generate the
+ default one. Also skip other verifications: constructors
+ can't be inherited hence hiden or overriden */
+ if (DECL_CONSTRUCTOR_P (method))
+ {
+ saw_constructor = 1;
+ continue;
+ }
+
+ /* We verify things thrown by the method. They must inherits from
+ java.lang.Throwable */
+ for (mthrows = DECL_FUNCTION_THROWS (method);
+ mthrows; mthrows = TREE_CHAIN (mthrows))
+ {
+ if (!inherits_from_p (TREE_VALUE (mthrows), throwable_type_node))
+ parse_error_context
+ (TREE_PURPOSE (mthrows), "Class `%s' in `throws' clause must be "
+ "a subclass of class `java.lang.Throwable'",
+ IDENTIFIER_POINTER
+ (DECL_NAME (TYPE_NAME (TREE_VALUE (mthrows)))));
+ }
+ sig = build_java_argument_signature (TREE_TYPE (method));
found = lookup_argument_method (super_class, DECL_NAME (method), sig);
- if (! found)
- continue;
+
+ /* Nothing overrides or it's a private method. */
+ if (!found)
+ continue;
+ if (METHOD_PRIVATE (found))
+ {
+ found = NULL_TREE;
+ continue;
+ }
+
+ /* If found wasn't verified, it's DECL_NAME won't be set properly.
+ We set it temporarily for the sake of the error report. */
+ saved_found_wfl = DECL_NAME (found);
+ reset_method_name (found);
+
/* Can't override a method with the same name and different return
types. */
if (TREE_TYPE (TREE_TYPE (found)) != TREE_TYPE (TREE_TYPE (method)))
- parse_warning_context
- (method_wfl,
- "Method `%s' redefined with different return type in class `%s'",
- lang_printable_name (found),
- IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
+ {
+ char *t = strdup (lang_printable_name (TREE_TYPE (TREE_TYPE (found)),
+ 0));
+ parse_error_context
+ (method_wfl,
+ "Method `%s' was defined with return type `%s' in class `%s'",
+ lang_printable_name (found, 0), t,
+ IDENTIFIER_POINTER
+ (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
+ free (t);
+ }
/* Can't override final. Can't override static. */
if (METHOD_FINAL (found) || METHOD_STATIC (found))
@@ -3663,7 +4585,7 @@ java_check_regular_methods (class_decl)
(method_wfl,
"%s methods can't be overriden. Method `%s' is %s in class `%s'",
(METHOD_FINAL (found) ? "Final" : "Static"),
- lang_printable_name (found),
+ lang_printable_name (found, 0),
(METHOD_FINAL (found) ? "final" : "static"),
IDENTIFIER_POINTER
(DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
@@ -3676,94 +4598,164 @@ java_check_regular_methods (class_decl)
(method_wfl,
"Instance methods can't be overriden by a static method. Method "
"`%s' is an instance method in class `%s'",
- lang_printable_name (found),
+ lang_printable_name (found, 0),
IDENTIFIER_POINTER
(DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
continue;
}
- /* Overriding/hiding public must be public or
- overriding/hiding protected must be protected or public */
- if ((METHOD_PUBLIC (found) && !METHOD_PUBLIC (method)) ||
- (METHOD_PROTECTED (found)
- && !(METHOD_PUBLIC (method) || METHOD_PROTECTED (method))))
+
+ aflags = get_access_flags_from_decl (found);
+ /* - Overriding/hiding public must be public
+ - Overriding/hiding protected must be protected or public
+ - If the overriden or hidden method has default (package)
+ access, then the overriding or hiding method must not be
+ private; otherwise, a compile-time error occurs */
+ if ((METHOD_PUBLIC (found) && !METHOD_PUBLIC (method))
+ || (METHOD_PROTECTED (found)
+ && !(METHOD_PUBLIC (method) || METHOD_PROTECTED (method)))
+ || (!(aflags & (ACC_PUBLIC | ACC_PRIVATE | ACC_STATIC))
+ && METHOD_PRIVATE (method)))
{
parse_error_context
(method_wfl,
"Methods can't be overridden to be more private. Method `%s' is "
- "%s in class `%s'", lang_printable_name (found),
- (METHOD_PUBLIC (found) ? "public" : "protected"),
- IDENTIFIER_POINTER
- (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
+ "not %s in class `%s'", lang_printable_name (method, 0),
+ (METHOD_PUBLIC (method) ? "public" :
+ (METHOD_PRIVATE (method) ? "private" : "protected")),
+ IDENTIFIER_POINTER (DECL_NAME
+ (TYPE_NAME (DECL_CONTEXT (found)))));
continue;
}
+ /* Overriding methods must have compatible `throws' clauses on checked
+ exceptions, if any */
+ check_throws_clauses (method, method_wfl, found);
+
/* If the method has default access in an other package, then
- issue a warning that the current method doesn't override the one
- that was found elsewhere */
- aflags = get_access_flags_from_decl (found);
- if ((!aflags || (aflags > ACC_PROTECTED))
- && !class_in_current_package (DECL_CONTEXT (found)))
+ issue a warning that the current method doesn't override the
+ one that was found elsewhere. Do not issue this warning when
+ the match was found in java.lang.Object. */
+ if (DECL_CONTEXT (found) != object_type_node
+ && (!aflags || (aflags > ACC_PROTECTED))
+ && !class_in_current_package (DECL_CONTEXT (found))
+ && flag_not_overriding)
parse_warning_context
(method_wfl, "Method `%s' in class `%s' does not "
"override the corresponding method in class `%s', which is "
"private to a different package",
- lang_printable_name (found),
+ lang_printable_name (found, 0),
IDENTIFIER_POINTER (DECL_NAME (class_decl)),
IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
- /* Check on (default) package access. FIXME. */
/* Inheriting multiple methods with the same signature. FIXME */
}
- TYPE_METHODS (class) = nreverse (TYPE_METHODS (class));
+ /* Don't forget eventual pending found and saved_found_wfl. Take
+ into account that we might have exited because we saw an
+ aritifical method as the last entry. */
+
+ if (found && !DECL_ARTIFICIAL (found) && saved_found_wfl)
+ DECL_NAME (found) = saved_found_wfl;
- if (!seen_constructor)
+ if (!TYPE_NVIRTUALS (class))
+ TYPE_METHODS (class) = nreverse (TYPE_METHODS (class));
+
+ if (!saw_constructor)
{
- /* No constructor seen, we craft one, at line 0 */
- int saved_lineno = lineno;
- tree meth, decl;
- lineno = 0;
- meth = make_node (FUNCTION_TYPE);
- TREE_TYPE (meth) = void_type_node;
- TYPE_ARG_TYPES (meth) = NULL_TREE;
- decl = add_method (class, 0, init_identifier_node,
- build_java_signature (meth));
+ /* No constructor seen, we craft one, at line 0. Since this
+ operation takes place after we laid methods out
+ (layout_class_methods), we prepare the its DECL
+ appropriately. */
+ int flags;
+ tree decl;
+
+ /* If the class is declared PUBLIC, the default constructor is
+ PUBLIC otherwise it has default access implied by no access
+ modifiers. */
+ flags = (get_access_flags_from_decl (class_decl) & ACC_PUBLIC ?
+ ACC_PUBLIC : 0);
+ decl = create_artificial_method (class, flags, void_type_node,
+ init_identifier_node, end_params_node);
DECL_CONSTRUCTOR_P (decl) = 1;
- lineno = saved_lineno;
+ layout_class_method (TREE_TYPE (class_decl), NULL_TREE, decl, NULL_TREE);
+ }
+}
+
+/* Return a non zero value if the `throws' clause of METHOD (if any)
+ is incompatible with the `throws' clause of FOUND (if any). */
+
+static void
+check_throws_clauses (method, method_wfl, found)
+ tree method, method_wfl, found;
+{
+ tree mthrows, fthrows;
+
+ /* Can't check these things with class loaded from bytecode. FIXME */
+ if (!CLASS_FROM_SOURCE_P (DECL_CONTEXT (found)))
+ return;
+
+ for (mthrows = DECL_FUNCTION_THROWS (method);
+ mthrows; mthrows = TREE_CHAIN (mthrows))
+ {
+ /* We don't verify unchecked expressions */
+ if (IS_UNCHECKED_EXCEPTION_P (TREE_VALUE (mthrows)))
+ continue;
+ /* Checked expression must be compatible */
+ for (fthrows = DECL_FUNCTION_THROWS (found);
+ fthrows; fthrows = TREE_CHAIN (fthrows))
+ if (inherits_from_p (TREE_VALUE (mthrows), TREE_VALUE (fthrows)))
+ break;
+ if (!fthrows)
+ {
+ parse_error_context
+ (method_wfl, "Invalid checked exception class `%s' in "
+ "`throws' clause. The exception must be a subclass of an "
+ "exception thrown by `%s' from class `%s'",
+ IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (TREE_VALUE (mthrows)))),
+ lang_printable_name (found, 0),
+ IDENTIFIER_POINTER
+ (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
+ }
}
}
/* Check abstract method of interface INTERFACE */
static void
-java_check_abstract_methods (interface)
- tree interface;
+java_check_abstract_methods (interface_decl)
+ tree interface_decl;
{
int i, n;
tree method, basetype_vec, found;
+ tree interface = TREE_TYPE (interface_decl);
for (method = TYPE_METHODS (interface); method; method = TREE_CHAIN (method))
{
- char *csig;
- tree name = DECL_NAME (method);
+ tree method_wfl = DECL_NAME (method);
/* 2- Check for double definition inside the defining interface */
if (check_method_redefinition (interface, method))
continue;
/* 3- Overriding is OK as far as we preserve the return type and
- the thrown exceptions */
+ the thrown exceptions (FIXME) */
found = lookup_java_interface_method2 (interface, method);
if (found)
{
+ char *t;
+ tree saved_found_wfl = DECL_NAME (found);
+ reset_method_name (found);
+ t = strdup (lang_printable_name (TREE_TYPE (TREE_TYPE (found)), 0));
parse_error_context
- (lookup_cl (method),
- "Method `%s' previously defined in interface `%s' is "
- "redefined with different return type in interface `%s'",
- lang_printable_name (found),
- IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))),
- IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (interface))));
+ (method_wfl,
+ "Method `%s' was defined with return type `%s' in class `%s'",
+ lang_printable_name (found, 0), t,
+ IDENTIFIER_POINTER
+ (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
+ free (t);
continue;
+
+ DECL_NAME (found) = saved_found_wfl;
}
}
@@ -3785,41 +4777,27 @@ java_check_abstract_methods (interface)
found = lookup_java_interface_method2 (interface,
sub_interface_method);
if (found && (found != sub_interface_method))
- parse_error_context
- (lookup_cl (sub_interface_method),
- "Interface `%s' inherits method `%s' from interface `%s'. This "
- "method is redefined with a different return "
- "type in interface `%s'",
- IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (interface))),
- lang_printable_name (found),
- IDENTIFIER_POINTER
- (DECL_NAME (TYPE_NAME (DECL_CONTEXT (sub_interface_method)))),
- IDENTIFIER_POINTER
- (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
+ {
+ tree saved_found_wfl = DECL_NAME (found);
+ reset_method_name (found);
+ parse_error_context
+ (lookup_cl (sub_interface_method),
+ "Interface `%s' inherits method `%s' from interface `%s'. "
+ "This method is redefined with a different return type in "
+ "interface `%s'",
+ IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (interface))),
+ lang_printable_name (found, 0),
+ IDENTIFIER_POINTER
+ (DECL_NAME (TYPE_NAME
+ (DECL_CONTEXT (sub_interface_method)))),
+ IDENTIFIER_POINTER
+ (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
+ DECL_NAME (found) = saved_found_wfl;
+ }
}
}
}
-/* Check the method on all the defined classes. Should be done to the
- classes declared in the compilation unit only. FIXME */
-
-void
-java_check_methods ()
-{
-
- tree current;
- for (current = ctxp->class_list; current; current = TREE_CHAIN (current))
- if (CLASS_FROM_SOURCE_P (TREE_TYPE (current)))
- {
- tree class = CLASS_TO_HANDLE_TYPE (TREE_TYPE (current));
-
- if (CLASS_INTERFACE (TYPE_NAME (class)))
- java_check_abstract_methods (class);
- else
- java_check_regular_methods (current);
- }
-}
-
/* Lookup methods in interfaces using their name and partial
signature. Return a matching method only if their types differ. */
@@ -3861,9 +4839,12 @@ lookup_java_method2 (clas, method_decl, do_interface)
tree clas, method_decl;
int do_interface;
{
- tree method, method_signature, method_name, method_type;
+ tree method, method_signature, method_name, method_type, name;
+
method_signature = build_java_argument_signature (TREE_TYPE (method_decl));
- method_name = DECL_NAME (method_decl);
+ name = DECL_NAME (method_decl);
+ method_name = (TREE_CODE (name) == EXPR_WITH_FILE_LOCATION ?
+ EXPR_WFL_NODE (name) : name);
method_type = TREE_TYPE (TREE_TYPE (method_decl));
while (clas != NULL_TREE)
@@ -3872,12 +4853,12 @@ lookup_java_method2 (clas, method_decl, do_interface)
method != NULL_TREE; method = TREE_CHAIN (method))
{
tree method_sig = build_java_argument_signature (TREE_TYPE (method));
- if (DECL_NAME (method) == method_name
+ tree name = DECL_NAME (method);
+ if ((TREE_CODE (name) == EXPR_WITH_FILE_LOCATION ?
+ EXPR_WFL_NODE (name) : name) == method_name
&& method_sig == method_signature
&& TREE_TYPE (TREE_TYPE (method)) != method_type)
- {
- return method;
- }
+ return method;
}
clas = (do_interface ? NULL_TREE : CLASSTYPE_SUPER (clas));
}
@@ -3966,74 +4947,26 @@ find_in_imports (class_type)
{
TYPE_NAME (class_type) = EXPR_WFL_NODE (TREE_PURPOSE (import));
QUALIFIED_P (TYPE_NAME (class_type)) = 1;
- return check_pkg_class_access (TYPE_NAME (class_type),
- TREE_PURPOSE (import));
}
return 0;
}
-/* Process a import on demand statement (lazy) */
-
static int
-read_import_entry (jcf, dirp, returned_name)
- JCF *jcf;
- DIR *dirp;
- char **returned_name;
+note_possible_classname (name, len)
+ char *name;
+ int len;
{
- if (dirp)
- {
- struct dirent *direntp = readdir (dirp);
- if (!direntp)
- {
- *returned_name = NULL;
- return 0;
- }
- else
- {
- *returned_name = direntp->d_name;
- return (strlen (direntp->d_name));
- }
- }
+ tree node;
+ if (len > 5 && strncmp (&name [len-5], ".java", 5) == 0)
+ len = len - 5;
+ else if (len > 6 && strncmp (&name [len-6], ".class", 6) == 0)
+ len = len - 6;
else
- {
- int current_dir_len = strlen (jcf->classname);
- char *current_entry;
- int current_entry_len;
-
- /* Here we read a zip directory as a file directory. The files
- we're selecting must have the same root than the directory
- we're examining. */
-
- ZipDirectory *zipd = (ZipDirectory *)jcf->zipd;
-
- while (zipd)
- {
- current_entry = ZIPDIR_FILENAME (zipd);
- current_entry_len = zipd->filename_length;
- while (current_entry_len && current_entry [current_entry_len] != '/')
- current_entry_len--;
- /* If the path of the current file doesn't match the directory we're
- scanning, that the end of the search */
- current_entry_len++;
- if (strncmp (jcf->classname, current_entry, current_dir_len))
- {
- *returned_name = NULL;
- return 0;
- }
- /* Ok, we have at least the same path. The position of the last '/'
- of the current file we're examining should match the size of
- name of the directory we're browsing, otherwise that an entry
- belonging to a sub directory, we want to skip it. */
- if (current_entry_len != current_dir_len)
- zipd = ZIPDIR_NEXT (zipd);
- else
- {
- jcf->zipd = ZIPDIR_NEXT (zipd); /* Prepare next read */
- *returned_name = &current_entry [current_entry_len];
- return (zipd->filename_length - current_entry_len);
- }
- }
- }
+ return 0;
+ node = ident_subst (name, len, "", '/', '.', "");
+ IS_A_CLASSFILE_NAME (node) = 1; /* Or soon to be */
+ QUALIFIED_P (node) = 1; /* As soon as we turn / into . */
+ return 1;
}
/* Read a import directory, gathering potential match for further type
@@ -4044,30 +4977,104 @@ static void
read_import_dir (wfl)
tree wfl;
{
- char *name = IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl));
- int name_len = IDENTIFIER_LENGTH (EXPR_WFL_NODE (wfl)), reclen;
+ tree package_id = EXPR_WFL_NODE (wfl);
+ char *package_name = IDENTIFIER_POINTER (package_id);
+ int package_length = IDENTIFIER_LENGTH (package_id);
DIR *dirp = NULL;
- tree dirname = ident_subst (name, name_len, "", '.', '/', "");
- JCF jcfr, *jcf, *saved_jcf = current_jcf;
- char *founddirname, *d_name;
- struct ZipFileCache zip_cache;
+ JCF *saved_jcf = current_jcf;
+
+ int found = 0;
+ int k;
+ void *entry;
+ struct buffer filename[1];
+
+
+ if (IS_AN_IMPORT_ON_DEMAND_P (package_id))
+ return;
+ IS_AN_IMPORT_ON_DEMAND_P (package_id) = 1;
- jcf = &jcfr;
- if (!classpath)
- fix_classpath ();
- if (!(founddirname = find_class (name, name_len, jcf, 0)))
- fatal ("Can't import `%s'", name);
- if (jcf->outofsynch)
- jcf_out_of_synch (jcf);
- if (jcf->seen_in_zip)
- jcf->zipd = ZIPDIR_NEXT ((ZipDirectory *)jcf->zipd);
+ BUFFER_INIT (filename);
+ buffer_grow (filename, package_length + 100);
- else if (founddirname && (dirp = opendir (founddirname)))
+ for (entry = jcf_path_start (); entry != NULL; entry = jcf_path_next (entry))
{
- readdir (dirp); readdir (dirp);
+ char *entry_name = jcf_path_name (entry);
+ int entry_length = strlen (entry_name);
+ if (jcf_path_is_zipfile (entry))
+ {
+ ZipFile *zipf;
+ buffer_grow (filename, entry_length);
+ memcpy (filename->data, entry_name, entry_length - 1);
+ filename->data[entry_length-1] = '\0';
+ zipf = opendir_in_zip (filename->data, jcf_path_is_system (entry));
+ if (zipf == NULL)
+ error ("malformed .zip archive in CLASSPATH: %s", entry_name);
+ else
+ {
+ ZipDirectory *zipd = (ZipDirectory *) zipf->central_directory;
+ BUFFER_RESET (filename);
+ for (k = 0; k < package_length; k++)
+ {
+ char ch = package_name[k];
+ *filename->ptr++ = ch == '.' ? '/' : ch;
+ }
+ *filename->ptr++ = '/';
+
+ for (k = 0; k < zipf->count; k++, zipd = ZIPDIR_NEXT (zipd))
+ {
+ char *current_entry = ZIPDIR_FILENAME (zipd);
+ int current_entry_len = zipd->filename_length;
+
+ if (current_entry_len >= BUFFER_LENGTH (filename)
+ && strncmp (filename->data, current_entry,
+ BUFFER_LENGTH (filename)) != 0)
+ continue;
+ found |= note_possible_classname (current_entry,
+ current_entry_len);
+ }
+ }
+ }
+ else
+ {
+ BUFFER_RESET (filename);
+ buffer_grow (filename, entry_length + package_length + 4);
+ strcpy (filename->data, entry_name);
+ filename->ptr = filename->data + entry_length;
+ for (k = 0; k < package_length; k++)
+ {
+ char ch = package_name[k];
+ *filename->ptr++ = ch == '.' ? '/' : ch;
+ }
+ *filename->ptr = '\0';
+
+ dirp = opendir (filename->data);
+ if (dirp == NULL)
+ continue;
+ *filename->ptr++ = '/';
+ for (;;)
+ {
+ int len;
+ char *d_name;
+ struct dirent *direntp = readdir (dirp);
+ if (!direntp)
+ break;
+ d_name = direntp->d_name;
+ len = strlen (direntp->d_name);
+ buffer_grow (filename, len+1);
+ strcpy (filename->ptr, d_name);
+ found |= note_possible_classname (filename->data + entry_length,
+ package_length+len+1);
+ }
+ if (dirp)
+ closedir (dirp);
+ }
}
- if (!founddirname && !dirp)
+ free (filename->data);
+
+ /* Here we should have a unified way of retrieving an entry, to be
+ indexed. */
+ if (!found)
{
static int first = 1;
if (first)
@@ -4075,55 +5082,17 @@ read_import_dir (wfl)
char buffer [256];
sprintf (buffer, "Can't find default package `%s'. Check "
"the CLASSPATH environment variable and the access to the "
- "archives.", name);
+ "archives.", package_name);
error (buffer);
java_error_count++;
first = 0;
}
else
- parse_error_context (wfl, "Package `%s' not found in import", name);
+ parse_error_context (wfl, "Package `%s' not found in import",
+ package_name);
current_jcf = saved_jcf;
return;
}
-
- /* Here we should have a unified way of retrieving an entry, to be
- indexed. */
- while ((reclen = read_import_entry (jcf, dirp, &d_name)))
- {
- int java_or_class = 0;
- int len;
- if ((reclen > 5)
- && !strcmp (&d_name [reclen-5], ".java"))
- {
- java_or_class = 1;
- len = reclen - 5;
- }
-
- if (!java_or_class && (reclen > 6) &&
- !strcmp (&d_name [reclen-6], ".class"))
- {
- java_or_class = 2;
- len = reclen - 6;
- }
-
- if (java_or_class)
- {
- char *id_name;
- tree node, old;
-
- obstack_grow (&temporary_obstack, name, name_len);
- obstack_1grow (&temporary_obstack, '/');
- obstack_grow0 (&temporary_obstack, d_name, len);
- id_name = obstack_finish (&temporary_obstack);
-
- node = get_identifier (id_name);
- IS_A_CLASSFILE_NAME (node) = 1; /* Or soon to be */
- QUALIFIED_P (node) = 1; /* As soon as we turn / into . */
- }
- }
- if (dirp)
- closedir (dirp);
-
current_jcf = saved_jcf;
}
@@ -4142,11 +5111,10 @@ find_in_imports_on_demand (class_type)
for (import = ctxp->import_demand_list; import; import = TREE_CHAIN (import))
{
char *id_name;
- tree found;
obstack_grow (&temporary_obstack,
IDENTIFIER_POINTER (EXPR_WFL_NODE (TREE_PURPOSE (import))),
IDENTIFIER_LENGTH (EXPR_WFL_NODE (TREE_PURPOSE (import))));
- obstack_1grow (&temporary_obstack, '/');
+ obstack_1grow (&temporary_obstack, '.');
obstack_grow0 (&temporary_obstack,
IDENTIFIER_POINTER (TYPE_NAME (class_type)),
IDENTIFIER_LENGTH (TYPE_NAME (class_type)));
@@ -4179,9 +5147,7 @@ find_in_imports_on_demand (class_type)
tree decl;
int saved_lineno = lineno;
lineno = EXPR_WFL_LINENO (cl);
- TYPE_NAME (class_type) = ident_subst (IDENTIFIER_POINTER (node_to_use),
- IDENTIFIER_LENGTH (node_to_use),
- "", '/', '.', "");
+ TYPE_NAME (class_type) = node_to_use;
QUALIFIED_P (TYPE_NAME (class_type)) = 1;
decl = IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type));
/* If there is no DECL set for the class or if the class isn't
@@ -4196,6 +5162,49 @@ find_in_imports_on_demand (class_type)
return (seen_once < 0 ? 0 : seen_once); /* It's ok not to have found */
}
+static tree
+resolve_package (pkg, next)
+ tree pkg, *next;
+{
+ tree type_name = NULL_TREE;
+ char *name = IDENTIFIER_POINTER (EXPR_WFL_NODE (pkg));
+
+ /* The trick is to determine when the package name stops and were
+ the name of something contained in the package starts. Then we
+ return a fully qualified name of what we want to get. */
+
+ /* Do a quick search on well known package names */
+ if (!strncmp (name, "java.lang.reflect", 17))
+ {
+ *next =
+ TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (EXPR_WFL_QUALIFICATION (pkg))));
+ type_name = lookup_package_type (name, 17);
+ }
+ else if (!strncmp (name, "java.lang", 9))
+ {
+ *next = TREE_CHAIN (TREE_CHAIN (EXPR_WFL_QUALIFICATION (pkg)));
+ type_name = lookup_package_type (name, 9);
+ }
+ else
+ return NULL_TREE; /* FIXME, search all imported packages. */
+
+ return type_name;
+}
+
+static tree
+lookup_package_type (name, from)
+ char *name;
+ int from;
+{
+ char subname [128];
+ char *sub = &name[from+1];
+ while (*sub != '.' && *sub)
+ sub++;
+ strncpy (subname, name, sub-name);
+ subname [sub-name] = '\0';
+ return get_identifier (subname);
+}
+
/* Check that CLASS_NAME refers to a PUBLIC class. Return 0 if no
access violations were found, 1 otherwise. */
@@ -4205,7 +5214,6 @@ check_pkg_class_access (class_name, cl)
tree cl;
{
tree type;
- int access;
if (!QUALIFIED_P (class_name) || !IDENTIFIER_CLASS_VALUE (class_name))
return 0;
@@ -4215,6 +5223,13 @@ check_pkg_class_access (class_name, cl)
if (!CLASS_PUBLIC (TYPE_NAME (type)))
{
+ /* Access to a private class within the same package is
+ allowed. */
+ tree l, r;
+ breakdown_qualified (&l, &r, class_name);
+ if (l == ctxp->package)
+ return 0;
+
parse_error_context
(cl, "Can't access %s `%s'. Only public classes and interfaces in "
"other packages can be accessed",
@@ -4233,85 +5248,100 @@ declare_local_variables (modifier, type, vlist)
tree type;
tree vlist;
{
- tree decl, current, returned_type, type_wfl, init_stmt = NULL_TREE;
+ tree decl, current, saved_type;
+ tree type_wfl = NULL_TREE;
int must_chain = 0;
- /* Push a new block if statement were seen between the last time we
+ /* Push a new block if statements were seen between the last time we
pushed a block and now. Keep a cound of block to close */
- if (BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (current_function_decl)))
+ if (BLOCK_EXPR_BODY (GET_CURRENT_BLOCK (current_function_decl)))
{
- tree body = DECL_FUNCTION_BODY (current_function_decl);
+ tree body = GET_CURRENT_BLOCK (current_function_decl);
tree b = enter_block ();
- BLOCK_EXPR_ORIGIN(b) = body;
+ BLOCK_EXPR_ORIGIN (b) = body;
}
if (modifier)
{
int i;
for (i = 0; i <= 10; i++) if (1 << i & modifier) break;
- parse_error_context
- (ctxp->modifier_ctx [i],
- (modifier == ACC_FINAL ?
- "Unsupported JDK1.1 `final' locals" :
- "Only `final' is allowed as a local variables modifier"));
- return;
- }
-
- if (unresolved_type_p (type, &returned_type))
- {
- if (returned_type)
- type = returned_type;
+ if (modifier == ACC_FINAL)
+ {
+ if (flag_static_local_jdk1_1)
+ parse_warning_context (ctxp->modifier_ctx [i],
+ "Unsupported JDK1.1 `final' local variable "
+ "(treated as non final)");
+ }
else
{
- type_wfl = type;
- type = obtain_incomplete_type (type);
- must_chain = 1;
+ parse_error_context
+ (ctxp->modifier_ctx [i],
+ "Only `final' is allowed as a local variables modifier");
+ return;
}
}
-
- for (current = vlist; current; current = TREE_CHAIN (current))
+
+ /* Obtain an incomplete type if TYPE is not complete. TYPE_WFL will
+ hold the TYPE value if a new incomplete has to be created (as
+ opposed to being found already existing and reused). */
+ SET_TYPE_FOR_RESOLUTION (type, type_wfl, must_chain);
+
+ /* If TYPE is fully resolved and we don't have a reference, make one */
+ PROMOTE_RECORD_IF_COMPLETE (type, must_chain);
+
+ /* Go through all the declared variables */
+ for (current = vlist, saved_type = type; current;
+ current = TREE_CHAIN (current), type = saved_type)
{
+ tree other, real_type;
tree wfl = TREE_PURPOSE (current);
tree name = EXPR_WFL_NODE (wfl);
tree init = TREE_VALUE (current);
- tree other = lookup_name_in_blocks (name);
- /* Don't try to use an INIT statement when an error was found */
- if (init && java_error_count)
- init = NULL_TREE;
+ /* Process NAME, as it may specify extra dimension(s) for it */
+ type = build_array_from_name (type, type_wfl, name, &name);
- if (other)
- parse_error_context
- (wfl, "Variable `%s' is already defined in this method and was "
- "declared `%s %s' in line %d",
- IDENTIFIER_POINTER (name), lang_printable_name (TREE_TYPE (other)),
- IDENTIFIER_POINTER (name), DECL_SOURCE_LINE (other));
- else
+ /* Variable redefinition check */
+ if ((other = lookup_name_in_blocks (name)))
{
- if (!must_chain && TREE_CODE (type) == RECORD_TYPE)
- type = promote_type (type);
- /* Never layout this decl. This will be done when its scope
- will be entered */
- decl = build_decl_no_layout (VAR_DECL, name, type);
- BLOCK_CHAIN_DECL (decl);
+ variable_redefinition_error (wfl, name, TREE_TYPE (other),
+ DECL_SOURCE_LINE (other));
+ continue;
+ }
- /* Add the initialization function to the current function's code */
- if (init)
- {
- tree wfl;
- MODIFY_EXPR_FROM_INITIALIZATION_P (init) = 1;
- java_method_add_stmt
- (current_function_decl,
- build_debugable_stmt (EXPR_WFL_LINECOL (init), init));
- }
+ /* Type adjustment. We may have just readjusted TYPE because
+ the variable specified more dimensions. Make sure we have
+ a reference if we can and don't have one already. */
+ PROMOTE_RECORD_IF_COMPLETE (type, must_chain);
- if (must_chain)
- {
- jdep *dep;
- register_incomplete_type (JDEP_VARIABLE, type_wfl, decl, type);
- dep = CLASSD_LAST (ctxp->classd_list);
- JDEP_GET_PATCH (dep) = &TREE_TYPE (decl);
- }
+ real_type = GET_REAL_TYPE (type);
+ /* Never layout this decl. This will be done when its scope
+ will be entered */
+ decl = build_decl (VAR_DECL, name, real_type);
+ BLOCK_CHAIN_DECL (decl);
+
+ /* Don't try to use an INIT statement when an error was found */
+ if (init && java_error_count)
+ init = NULL_TREE;
+
+ /* Add the initialization function to the current function's code */
+ if (init)
+ {
+ /* Name might have been readjusted */
+ EXPR_WFL_NODE (TREE_OPERAND (init, 0)) = name;
+ MODIFY_EXPR_FROM_INITIALIZATION_P (init) = 1;
+ java_method_add_stmt (current_function_decl,
+ build_debugable_stmt (EXPR_WFL_LINECOL (init),
+ init));
+ }
+
+ /* Setup dependency the type of the decl */
+ if (must_chain)
+ {
+ jdep *dep;
+ register_incomplete_type (JDEP_VARIABLE, type_wfl, decl, type);
+ dep = CLASSD_LAST (ctxp->classd_list);
+ JDEP_GET_PATCH (dep) = &TREE_TYPE (decl);
}
}
SOURCE_FRONTEND_DEBUG (("Defined locals"));
@@ -4327,25 +5357,24 @@ source_start_java_method (fndecl)
tree parm_decl;
int i;
- extern tree current_binding_level;
current_function_decl = fndecl;
/* New scope for the function */
enter_block ();
for (tem = TYPE_ARG_TYPES (TREE_TYPE (fndecl)), i = 0;
- tem != NULL_TREE; tem = TREE_CHAIN (tem), i++)
+ tem != end_params_node; tem = TREE_CHAIN (tem), i++)
{
tree type = TREE_VALUE (tem);
tree name = TREE_PURPOSE (tem);
- /* If type is incomplete. Layout can't take place
- now. Create an incomplete decl and ask for the decl to be
- patched later */
+ /* If type is incomplete. Create an incomplete decl and ask for
+ the decl to be patched later */
if (INCOMPLETE_TYPE_P (type))
{
jdep *jdep;
- parm_decl = build_decl_no_layout (PARM_DECL, name, type);
-
+ tree real_type = GET_REAL_TYPE (type);
+ parm_decl = build_decl (PARM_DECL, name, real_type);
+ type = obtain_incomplete_type (type);
register_incomplete_type (JDEP_PARM, NULL_TREE, NULL_TREE, type);
jdep = CLASSD_LAST (ctxp->classd_list);
JDEP_MISC (jdep) = name;
@@ -4362,6 +5391,47 @@ source_start_java_method (fndecl)
DECL_ARG_SLOT_COUNT (current_function_decl) = i;
}
+/* Called during parsing. Creates an artificial method declaration. */
+
+static tree
+create_artificial_method (class, flags, type, name, args)
+ tree class;
+ int flags;
+ tree type, name, args;
+{
+ int saved_lineno = lineno;
+ tree mdecl;
+
+ lineno = 0;
+ mdecl = make_node (FUNCTION_TYPE);
+ TREE_TYPE (mdecl) = type;
+ TYPE_ARG_TYPES (mdecl) = args;
+ mdecl = add_method (class, flags, name, build_java_signature (mdecl));
+ lineno = saved_lineno;
+ DECL_ARTIFICIAL (mdecl) = 1;
+ return mdecl;
+}
+
+/* Starts the body if an artifical method. */
+
+static void
+start_artificial_method_body (mdecl)
+ tree mdecl;
+{
+ DECL_SOURCE_LINE (mdecl) = 1;
+ DECL_SOURCE_LINE_MERGE (mdecl, 1);
+ source_start_java_method (mdecl);
+ enter_block ();
+}
+
+static void
+end_artificial_method_body (mdecl)
+ tree mdecl;
+{
+ BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (mdecl)) = exit_block ();
+ exit_block ();
+}
+
/* Called during expansion. Push decls formerly built from argument
list so they're usable during expansion. */
@@ -4370,9 +5440,7 @@ expand_start_java_method (fndecl)
tree fndecl;
{
tree tem, *ptr;
- tree parm_decl;
- extern tree current_binding_level;
current_function_decl = fndecl;
announce_function (fndecl);
@@ -4382,10 +5450,15 @@ expand_start_java_method (fndecl)
while (tem)
{
tree next = TREE_CHAIN (tem);
- DECL_ARG_TYPE (tem) = TREE_TYPE (tem);
+ tree type = TREE_TYPE (tem);
+#ifdef PROMOTE_PROTOTYPES
+ if (TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)
+ && INTEGRAL_TYPE_P (type))
+ type = integer_type_node;
+#endif
+ DECL_ARG_TYPE (tem) = type;
layout_decl (tem, 0);
pushdecl (tem);
- INITIALIZED_P (tem) = 1; /* Parms are initialized */
*ptr = tem;
ptr = &TREE_CHAIN (tem);
tem = next;
@@ -4393,7 +5466,6 @@ expand_start_java_method (fndecl)
*ptr = NULL_TREE;
pushdecl_force_head (DECL_ARGUMENTS (fndecl));
lineno = DECL_SOURCE_LINE_FIRST (fndecl);
- complete_start_java_method (fndecl);
}
/* Terminate a function and expand its body. */
@@ -4406,6 +5478,9 @@ source_end_java_method ()
java_parser_context_save_global ();
lineno = ctxp->last_ccb_indent1;
+ /* Set EH language codes */
+ java_set_exception_lang_code ();
+
/* Generate function's code */
if (BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (fndecl))
&& ! flag_emit_class_files)
@@ -4420,6 +5495,8 @@ source_end_java_method ()
if (! flag_emit_class_files)
{
lineno = DECL_SOURCE_LINE_LAST (fndecl);
+ /* Emit catch-finally clauses */
+ emit_handlers ();
expand_function_end (input_filename, lineno, 0);
/* Run the optimizers and output assembler code for this function. */
@@ -4438,17 +5515,24 @@ tree
java_method_add_stmt (fndecl, expr)
tree fndecl, expr;
{
- tree body = BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (fndecl));
- tree node;
+ return add_stmt_to_block (GET_CURRENT_BLOCK (fndecl), NULL_TREE, expr);
+}
+static tree
+add_stmt_to_block (b, type, stmt)
+ tree b, type, stmt;
+{
+ tree body = BLOCK_EXPR_BODY (b), c;
+
if (java_error_count)
return body;
- if ((node = add_stmt_to_compound (body, NULL_TREE, expr)) == body)
+
+ if ((c = add_stmt_to_compound (body, type, stmt)) == body)
return body;
- BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (fndecl)) = node;
- TREE_SIDE_EFFECTS (node) = 1;
- return node;
+ BLOCK_EXPR_BODY (b) = c;
+ TREE_SIDE_EFFECTS (c) = 1;
+ return c;
}
/* Add STMT to EXISTING if possible, otherwise create a new
@@ -4458,39 +5542,103 @@ static tree
add_stmt_to_compound (existing, type, stmt)
tree existing, type, stmt;
{
- tree node;
-
- if (existing && (TREE_CODE (existing) == COMPOUND_EXPR)
- && TREE_OPERAND (existing, 1) == size_zero_node)
- {
- TREE_OPERAND (existing, 1) = stmt;
- TREE_TYPE (existing) = type;
- return existing;
- }
- else if (existing)
- node = build (COMPOUND_EXPR, type, existing, stmt);
+ if (existing)
+ return build (COMPOUND_EXPR, type, existing, stmt);
else
- node = build (COMPOUND_EXPR, type, stmt, size_zero_node);
-
- return node;
+ return stmt;
}
/* Hold THIS for the scope of the current public method decl. */
static tree current_this;
-/* Layout all class found during parsing */
+void java_layout_seen_class_methods ()
+{
+ tree previous_list = all_class_list;
+ tree end = NULL_TREE;
+ tree current;
+
+ while (1)
+ {
+ for (current = previous_list;
+ current != end; current = TREE_CHAIN (current))
+ layout_class_methods (TREE_TYPE (TREE_VALUE (current)));
+
+ if (previous_list != all_class_list)
+ {
+ end = previous_list;
+ previous_list = all_class_list;
+ }
+ else
+ break;
+ }
+}
+
+/* Layout the methods of all classes loaded in one way on an
+ other. Check methods of source parsed classes. Then reorder the
+ fields and layout the classes or the type of all source parsed
+ classes */
void
java_layout_classes ()
{
tree current;
- for (current = ctxp->class_list; current; current = TREE_CHAIN (current))
+ int save_error_count = java_error_count;
+
+ /* Layout the methods of all classes seen so far */
+ java_layout_seen_class_methods ();
+ java_parse_abort_on_error ();
+ all_class_list = NULL_TREE;
+
+ /* Then check the methods of all parsed classes */
+ for (current = ctxp->gclass_list; current; current = TREE_CHAIN (current))
+ if (CLASS_FROM_SOURCE_P (TREE_TYPE (TREE_VALUE (current))))
+ CHECK_METHODS (TREE_VALUE (current));
+ java_parse_abort_on_error ();
+
+ for (current = ctxp->gclass_list; current; current = TREE_CHAIN (current))
{
- current_class = TREE_TYPE (current);
- TYPE_FIELDS (current_class) = nreverse (TYPE_FIELDS (current_class));
- if (!TYPE_SIZE (current_class))
- safe_layout_class (current_class);
+ current_class = TREE_TYPE (TREE_VALUE (current));
+
+ /* Reverse the fields, but leave the dummy field in front.
+ Fields are already ordered for Object and Class */
+ if (TYPE_FIELDS (current_class) && current_class != object_type_node
+ && current_class != class_type_node)
+ {
+ /* If the dummy field is there, reverse the right fields and
+ just layout the type for proper fields offset */
+ if (!DECL_NAME (TYPE_FIELDS (current_class)))
+ {
+ tree fields = TYPE_FIELDS (current_class);
+ TREE_CHAIN (fields) = nreverse (TREE_CHAIN (fields));
+ TYPE_SIZE (current_class) = NULL_TREE;
+ layout_type (current_class);
+ }
+ /* We don't have a dummy field, we need to layout the class,
+ after having reversed the fields */
+ else
+ {
+ TYPE_FIELDS (current_class) =
+ nreverse (TYPE_FIELDS (current_class));
+ TYPE_SIZE (current_class) = NULL_TREE;
+ layout_class (current_class);
+ }
+ }
+ else
+ layout_class (current_class);
+
+ /* From now on, the class is considered completely loaded */
+ CLASS_LOADED_P (current_class) = 1;
+
+ /* Error reported by the caller */
+ if (java_error_count)
+ return;
}
+
+ /* We might have reloaded classes durign the process of laying out
+ classes for code generation. We must layout the methods of those
+ late additions, as constructor checks might use them */
+ java_layout_seen_class_methods ();
+ java_parse_abort_on_error ();
}
/* Expand all methods in all registered classes. */
@@ -4502,16 +5650,24 @@ java_complete_expand_methods ()
for (current = ctxp->class_list; current; current = TREE_CHAIN (current))
{
- extern tree current_constant_pool_data_ref;
tree class_type = CLASS_TO_HANDLE_TYPE (TREE_TYPE (current));
tree decl;
- int saved_lineno;
current_class = TREE_TYPE (current);
/* Initialize a new constant pool */
init_outgoing_cpool ();
+ /* We want <clinit> (if any) to be processed first. */
+ decl = tree_last (TYPE_METHODS (class_type));
+ if (decl && DECL_NAME (decl) == clinit_identifier_node)
+ {
+ tree list = nreverse (TYPE_METHODS (class_type));
+ list = TREE_CHAIN (list);
+ TREE_CHAIN (decl) = NULL_TREE;
+ TYPE_METHODS (class_type) = chainon (decl, nreverse (list));
+ }
+
/* Don't process function bodies in interfaces */
if (!CLASS_INTERFACE (TYPE_NAME (current_class)))
for (decl = TYPE_METHODS (class_type); decl; decl = TREE_CHAIN (decl))
@@ -4530,91 +5686,204 @@ java_complete_expand_methods ()
restore_line_number_status (0);
}
}
- else
+ else if (METHOD_ABSTRACT (decl) || METHOD_NATIVE (decl))
+ continue;
+ else
java_complete_expand_method (decl);
}
+ /* Now verify constructor circularity (stop after the first one
+ we find) */
+ if (!CLASS_INTERFACE (TYPE_NAME (current_class)))
+ for (decl = TYPE_METHODS (class_type); decl; decl = TREE_CHAIN (decl))
+ if (DECL_CONSTRUCTOR_P (decl) &&
+ verify_constructor_circularity (decl, decl))
+ break;
+
/* Make the class data, register it and run the rest of decl
compilation on it */
- if (!java_error_count && ! flag_emit_class_files)
+ if (!java_error_count)
{
- make_class_data (current_class);
- register_class ();
- rest_of_decl_compilation (TYPE_NAME (current_class), (char*) 0, 1, 0);
+ if (flag_emit_class_files)
+ write_classfile (current_class);
+ if (flag_emit_xref)
+ expand_xref (current_class);
+ else if (! flag_syntax_only)
+ finish_class (current_class);
}
}
}
+/* Hold a list of catch clauses list. The first element of this list is
+ the list of the catch clauses of the currently analysed try block. */
+static tree currently_caught_type_list;
+
/* Complete and expand a method. */
static void
java_complete_expand_method (mdecl)
tree mdecl;
{
- tree node;
- jdep *current;
- int no_ac_found = 1;
-
- /* We generate some code for an empty constructor */
- if (DECL_CONSTRUCTOR_P (mdecl) && !DECL_FUNCTION_BODY (mdecl))
- {
- tree arg_list, func, call;
- tree method_type = TREE_TYPE (mdecl);
- tree class_type = CLASS_TO_HANDLE_TYPE (current_class);
- tree self_type = (CLASSTYPE_SUPER (class_type) ?
- CLASSTYPE_SUPER (class_type) : class_type);
- tree method_signature =
- TYPE_LANG_SPECIFIC (method_type)->signature;
- tree method =
- lookup_java_constructor (CLASS_TO_HANDLE_TYPE (self_type),
- method_signature);
- tree block, compound;
-
- /* Fixe the begining/ending lines of the method so that with
- no_line_numbers set to 1 it doesn't generate debug info at
- line 1 for this artificial constructor. */
- DECL_SOURCE_LINE (mdecl) = 1;
- DECL_SOURCE_LINE_MERGE (mdecl, 1);
- source_start_java_method (mdecl);
- arg_list = BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (mdecl));
- enter_block ();
- func = build_known_method_ref (method, method_type, self_type,
- method_signature, arg_list);
-
- if (! flag_emit_class_files)
- func = build1 (NOP_EXPR, build_pointer_type (method_type), func);
- call = build (CALL_EXPR, TREE_TYPE (method_type), func,
- build_tree_list (NULL_TREE, arg_list), NULL_TREE);
- TREE_SIDE_EFFECTS (call) = 1;
- call = build_class_init (self_type, call);
- compound = java_method_add_stmt (mdecl, call);
- block = exit_block ();
- BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (mdecl)) = block;
- /* The function decl, its block and the compound statement
- within this block are all of void type. */
- TREE_TYPE (block) = TREE_TYPE (compound) =
- TREE_TYPE (DECL_FUNCTION_BODY (mdecl)) = void_type_node;
- exit_block ();
- no_ac_found = 0;
- }
+ /* Fix constructors before expanding them */
+ if (DECL_CONSTRUCTOR_P (mdecl))
+ fix_constructors (mdecl);
+ /* Expand functions that have a body */
if (DECL_FUNCTION_BODY (mdecl))
{
+ tree fbody = DECL_FUNCTION_BODY (mdecl);
+ tree block_body = BLOCK_EXPR_BODY (fbody);
expand_start_java_method (mdecl);
+ build_result_decl (mdecl);
current_this
= (!METHOD_STATIC (mdecl) ?
BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (mdecl)) : NULL_TREE);
- if (BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (mdecl)) && no_ac_found)
- java_complete_tree (BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (mdecl)));
+ /* Purge the `throws' list of unchecked exceptions */
+ purge_unchecked_exceptions (mdecl);
+
+ /* Install exceptions thrown with `throws' */
+ PUSH_EXCEPTIONS (DECL_FUNCTION_THROWS (mdecl));
+
+ if (block_body != NULL_TREE)
+ {
+ /* Prevent the use of `this' inside <clinit> */
+ if (DECL_NAME (current_function_decl) == clinit_identifier_node)
+ ctxp->explicit_constructor_p = 1;
+
+ block_body = java_complete_tree (block_body);
+ check_for_initialization (block_body);
+ ctxp->explicit_constructor_p = 0;
+ }
+ BLOCK_EXPR_BODY (fbody) = block_body;
+
+ if ((block_body == NULL_TREE || CAN_COMPLETE_NORMALLY (block_body))
+ && TREE_CODE (TREE_TYPE (TREE_TYPE (mdecl))) != VOID_TYPE)
+ missing_return_error (current_function_decl);
+
+ complete_start_java_method (mdecl);
+
/* Don't go any further if we've found error(s) during the
expansion */
if (!java_error_count)
source_end_java_method ();
+ else
+ {
+ pushdecl_force_head (DECL_ARGUMENTS (mdecl));
+ poplevel (1, 0, 1);
+ }
+
+ /* Pop the exceptions and sanity check */
+ POP_EXCEPTIONS();
+ if (currently_caught_type_list)
+ fatal ("Exception list non empty - java_complete_expand_method");
}
}
+/* Craft a body for default constructor. Patch existing constructor
+ bodies with call to super() and field initialization statements if
+ necessary. */
+
+static void
+fix_constructors (mdecl)
+ tree mdecl;
+{
+ tree body = DECL_FUNCTION_BODY (mdecl);
+
+ if (!body)
+ {
+ /* The constructor body must be crafted by hand. It's the
+ constructor we defined when we realize we didn't have the
+ CLASSNAME() constructor */
+
+ tree compound;
+
+ /* It is an error for the compiler to generate a default
+ constructor if the superclass doesn't have a constructor that
+ takes no argument */
+ if (verify_constructor_super ())
+ {
+ tree sclass_decl = TYPE_NAME (CLASSTYPE_SUPER (current_class));
+ char *n = IDENTIFIER_POINTER (DECL_NAME (sclass_decl));
+ parse_error_context (lookup_cl (TYPE_NAME (current_class)),
+ "No constructor matching `%s()' found in "
+ "class `%s'", n, n);
+ }
+
+ start_artificial_method_body (mdecl);
+
+ /* We don't generate a super constructor invocation if we're
+ compiling java.lang.Object. build_super_invocation takes care
+ of that. */
+ compound = java_method_add_stmt (mdecl, build_super_invocation ());
+
+ end_artificial_method_body (mdecl);
+ }
+ /* Search for an explicit constructor invocation */
+ else
+ {
+ int found = 0;
+ tree main_block = BLOCK_EXPR_BODY (body);
+ tree compound = NULL_TREE;
+
+ while (body)
+ switch (TREE_CODE (body))
+ {
+ case CALL_EXPR:
+ found = CALL_EXPLICIT_CONSTRUCTOR_P (body);
+ body = NULL_TREE;
+ break;
+ case COMPOUND_EXPR:
+ case EXPR_WITH_FILE_LOCATION:
+ body = TREE_OPERAND (body, 0);
+ break;
+ case BLOCK:
+ body = BLOCK_EXPR_BODY (body);
+ break;
+ default:
+ found = 0;
+ body = NULL_TREE;
+ }
+ /* The constructor is missing an invocation of super() */
+ if (!found)
+ compound = add_stmt_to_compound (compound, NULL_TREE,
+ build_super_invocation ());
+
+ /* Fix the constructor main block if we're adding extra stmts */
+ if (compound)
+ {
+ compound = add_stmt_to_compound (compound, NULL_TREE,
+ BLOCK_EXPR_BODY (main_block));
+ BLOCK_EXPR_BODY (main_block) = compound;
+ }
+ }
+}
+
+/* Browse constructors in the super class, searching for a constructor
+ that doesn't take any argument. Return 0 if one is found, 1
+ otherwise. */
+
+static int
+verify_constructor_super ()
+{
+ tree class = CLASSTYPE_SUPER (current_class);
+ if (!class)
+ return 0;
+
+ if (class)
+ {
+ tree mdecl;
+ for (mdecl = TYPE_METHODS (class); mdecl; mdecl = TREE_CHAIN (mdecl))
+ {
+ if (DECL_CONSTRUCTOR_P (mdecl)
+ && TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (mdecl))) == end_params_node)
+ return 0;
+ }
+ }
+ return 1;
+}
+
/* Expand finals. */
void
@@ -4622,6 +5891,31 @@ java_expand_finals ()
{
}
+/* Generate code for all context remembered for code generation. */
+
+void
+java_expand_classes ()
+{
+ int save_error_count = java_error_count;
+ java_parse_abort_on_error ();
+ if (!(ctxp = ctxp_for_generation))
+ return;
+ java_layout_classes ();
+ java_parse_abort_on_error ();
+
+ for (; ctxp_for_generation; ctxp_for_generation = ctxp_for_generation->next)
+ {
+ ctxp = ctxp_for_generation;
+ lang_init_source (2); /* Error msgs have method prototypes */
+ java_complete_expand_methods (); /* Complete and expand method bodies */
+ java_parse_abort_on_error ();
+ java_expand_finals (); /* Expand and check the finals */
+ java_parse_abort_on_error ();
+ java_check_final (); /* Check unitialized final */
+ java_parse_abort_on_error ();
+ }
+}
+
/* Wrap non WFL PRIMARY around a WFL and set EXPR_WFL_QUALIFICATION to
a tree list node containing RIGHT. Fore coming RIGHTs will be
chained to this hook. LOCATION contains the location of the
@@ -4637,9 +5931,9 @@ make_qualified_primary (primary, right, location)
/* We want to process THIS . xxx symbolicaly, to keep it consistent
with the way we're processing SUPER. A THIS from a primary as a
different form than a SUPER. Turn THIS into something symbolic */
- if (TREE_CODE (primary) == JAVA_THIS_EXPR)
+ if (TREE_CODE (primary) == THIS_EXPR)
{
- wfl = build_wfl_node (this_identifier_node, input_filename, 0, 0);
+ wfl = build_wfl_node (this_identifier_node);
EXPR_WFL_LINECOL (wfl) = EXPR_WFL_LINECOL (primary);
wfl = make_qualified_name (wfl, right, location);
PRIMARY_P (wfl) = 1;
@@ -4693,7 +5987,11 @@ make_qualified_name (left, right, location)
tree left, right;
int location;
{
- int qualified;
+#ifdef USE_COMPONENT_REF
+ tree node = build (COMPONENT_REF, NULL_TREE, left, right);
+ EXPR_WFL_LINECOL (node) = location;
+ return node;
+#else
tree left_id = EXPR_WFL_NODE (left);
tree right_id = EXPR_WFL_NODE (right);
tree wfl, merge;
@@ -4714,6 +6012,7 @@ make_qualified_name (left, right, location)
EXPR_WFL_NODE (left) = merge;
return left;
+#endif
}
/* Extract the last identifier component of the qualified in WFL. The
@@ -4739,8 +6038,9 @@ cut_identifier_in_qualified (wfl)
/* Resolve the expression name NAME. Return its decl. */
static tree
-resolve_expression_name (id)
+resolve_expression_name (id, orig)
tree id;
+ tree *orig;
{
tree name = EXPR_WFL_NODE (id);
tree decl;
@@ -4773,9 +6073,26 @@ resolve_expression_name (id)
(TYPE_NAME (current_class))));
return error_mark_node;
}
+ /* Instance variables can't appear as an argument of
+ an explicit constructor invocation */
+ if (!fs && ctxp->explicit_constructor_p)
+ {
+ parse_error_context
+ (id, "Can't reference `%s' before the superclass "
+ "constructor has been called", IDENTIFIER_POINTER (name));
+ return error_mark_node;
+ }
+
+ /* Otherwise build what it takes to access the field */
decl = build_field_ref ((fs ? NULL_TREE : current_this),
current_class, name);
- return (fs ? build_class_init (current_class, decl) : decl);
+ if (fs && !flag_emit_class_files)
+ decl = build_class_init (current_class, decl);
+ /* We may be asked to save the real field access node */
+ if (orig)
+ *orig = decl;
+ /* And we return what we got */
+ return decl;
}
/* Fall down to error report on undefined variable */
}
@@ -4783,6 +6100,8 @@ resolve_expression_name (id)
/* 6.5.5.2 Qualified Expression Names */
else
{
+ if (orig)
+ *orig = NULL_TREE;
qualify_ambiguous_name (id);
/* 15.10.1 Field Access Using a Primary and/or Expression Name */
/* 15.10.2: Accessing Superclass Members using super */
@@ -4824,23 +6143,36 @@ resolve_field_access (qual_wfl, field_decl, field_type)
}
/* We might have been trying to resolve field.method(). In which
case, the resolution is over and decl is the answer */
- else if (DECL_P (decl) && IDENTIFIER_LOCAL_VALUE (DECL_NAME (decl)) == decl)
+ else if (JDECL_P (decl) && IDENTIFIER_LOCAL_VALUE (DECL_NAME (decl)) == decl)
field_ref = decl;
- else if (DECL_P (decl))
- {
- is_static = DECL_P (decl) && FIELD_STATIC (decl);
- field_ref = build_field_ref ((is_static ? NULL_TREE : where_found),
- type_found, DECL_NAME (decl));
+ else if (JDECL_P (decl))
+ {
+ int static_final_found = 0;
+ if (!type_found)
+ type_found = DECL_CONTEXT (decl);
+ is_static = JDECL_P (decl) && FIELD_STATIC (decl);
+ if (FIELD_FINAL (decl)
+ && JPRIMITIVE_TYPE_P (TREE_TYPE (decl))
+ && DECL_LANG_SPECIFIC (decl)
+ && DECL_INITIAL (decl))
+ {
+ field_ref = DECL_INITIAL (decl);
+ static_final_found = 1;
+ }
+ else
+ field_ref = build_field_ref ((is_static ? NULL_TREE : where_found),
+ type_found, DECL_NAME (decl));
if (field_ref == error_mark_node)
return error_mark_node;
- if (is_static)
+ if (is_static && !static_final_found && !flag_emit_class_files)
{
field_ref = build_class_init (type_found, field_ref);
/* If the static field was identified by an expression that
needs to be generated, make the field access a compound
expression whose first part of the evaluation of the
field selector part. */
- if (where_found && TREE_CODE (where_found) != TYPE_DECL)
+ if (where_found && TREE_CODE (where_found) != TYPE_DECL
+ && TREE_CODE (where_found) != RECORD_TYPE)
{
tree type = QUAL_DECL_TYPE (field_ref);
field_ref = build (COMPOUND_EXPR, type, where_found, field_ref);
@@ -4853,10 +6185,35 @@ resolve_field_access (qual_wfl, field_decl, field_type)
if (field_decl)
*field_decl = decl;
if (field_type)
- *field_type = QUAL_DECL_TYPE (decl);
+ *field_type = (QUAL_DECL_TYPE (decl) ?
+ QUAL_DECL_TYPE (decl) : TREE_TYPE (decl));
return field_ref;
}
+/* If NODE is an access to f static field, strip out the class
+ initialization part and return the field decl, otherwise, return
+ NODE. */
+
+static tree
+strip_out_static_field_access_decl (node)
+ tree node;
+{
+ if (TREE_CODE (node) == COMPOUND_EXPR)
+ {
+ tree op1 = TREE_OPERAND (node, 1);
+ if (TREE_CODE (op1) == COMPOUND_EXPR)
+ {
+ tree call = TREE_OPERAND (op1, 0);
+ if (TREE_CODE (call) == CALL_EXPR
+ && TREE_CODE (TREE_OPERAND (call, 0)) == ADDR_EXPR
+ && TREE_OPERAND (TREE_OPERAND (call, 0), 0)
+ == soft_initclass_node)
+ return TREE_OPERAND (op1, 1);
+ }
+ }
+ return node;
+}
+
/* 6.5.5.2: Qualified Expression Names */
static int
@@ -4869,31 +6226,33 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
int previous_call_static = 0;
int is_static;
tree decl = NULL_TREE, type = NULL_TREE, q;
- *where_found = NULL_TREE;
+ *type_found = *where_found = NULL_TREE;
for (q = EXPR_WFL_QUALIFICATION (wfl); q; q = TREE_CHAIN (q))
{
tree qual_wfl = QUAL_WFL (q);
/* 15.10.1 Field Access Using a Primary */
-
switch (TREE_CODE (qual_wfl))
{
case CALL_EXPR:
- case JAVA_NEW_CLASS_EXPR:
+ case NEW_CLASS_EXPR:
/* If the access to the function call is a non static field,
build the code to access it. */
- if (DECL_P (decl) && !FIELD_STATIC (decl))
+ if (JDECL_P (decl) && !FIELD_STATIC (decl))
{
- decl = maybe_access_field (decl, *where_found, type);
+ decl = maybe_access_field (decl, *where_found,
+ DECL_CONTEXT (decl));
if (decl == error_mark_node)
return 1;
}
/* And code for the function call */
if (complete_function_arguments (qual_wfl))
return 1;
+ if (from_super && TREE_CODE (qual_wfl) == CALL_EXPR)
+ CALL_USING_SUPER (qual_wfl) = 1;
*where_found =
- patch_method_invocation_stmt (qual_wfl, decl, type, &is_static);
+ patch_method_invocation (qual_wfl, decl, type, &is_static, NULL);
if (*where_found == error_mark_node)
return 1;
*type_found = type = QUAL_DECL_TYPE (*where_found);
@@ -4914,6 +6273,14 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
}
continue;
+ case NEW_ARRAY_EXPR:
+ *where_found = decl = java_complete_tree (qual_wfl);
+ if (decl == error_mark_node)
+ return 1;
+ *type_found = type = QUAL_DECL_TYPE (decl);
+ CLASS_LOADED_P (type) = 1;
+ continue;
+
case CONVERT_EXPR:
*where_found = decl = java_complete_tree (qual_wfl);
if (decl == error_mark_node)
@@ -4922,10 +6289,18 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
from_cast = 1;
continue;
+ case CONDITIONAL_EXPR:
+ case STRING_CST:
+ *where_found = decl = java_complete_tree (qual_wfl);
+ if (decl == error_mark_node)
+ return 1;
+ *type_found = type = QUAL_DECL_TYPE (decl);
+ continue;
+
case ARRAY_REF:
/* If the access to the function call is a non static field,
build the code to access it. */
- if (DECL_P (decl) && !FIELD_STATIC (decl))
+ if (JDECL_P (decl) && !FIELD_STATIC (decl))
{
decl = maybe_access_field (decl, *where_found, type);
if (decl == error_mark_node)
@@ -4937,6 +6312,10 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
return 1;
type = QUAL_DECL_TYPE (decl);
continue;
+
+ default:
+ /* Fix for -Wall Just go to the next statement. Don't
+ continue */
}
/* If we fall here, we weren't processing a (static) function call. */
@@ -4953,7 +6332,7 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
}
/* We have to generate code for intermediate acess */
*where_found = decl = current_this;
- type = QUAL_DECL_TYPE (decl);
+ *type_found = type = QUAL_DECL_TYPE (decl);
continue;
}
@@ -4974,6 +6353,8 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
CLASSTYPE_SUPER (current_class),
build_this (EXPR_WFL_LINECOL (qual_wfl)));
*where_found = decl = java_complete_tree (node);
+ if (decl == error_mark_node)
+ return 1;
*type_found = type = QUAL_DECL_TYPE (decl);
from_super = from_type = 1;
continue;
@@ -4983,17 +6364,33 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
assume a variable/class name was meant. */
if (RESOLVE_PACKAGE_NAME_P (qual_wfl))
{
- if (from_super || from_cast)
- parse_error_context
- ((from_cast ? qual_wfl : wfl),
- "No variable `%s' defined in class `%s'",
- IDENTIFIER_POINTER (EXPR_WFL_NODE (qual_wfl)),
- lang_printable_name (type));
+ tree name = resolve_package (wfl, &q);
+ if (name)
+ {
+ *where_found = decl = resolve_no_layout (name, qual_wfl);
+ /* We wan't to be absolutely that the class is laid
+ out. We're going to search something inside it. */
+ *type_found = type = TREE_TYPE (decl);
+ layout_class (type);
+ from_type = 1;
+ /* Should be a list, really. FIXME */
+ RESOLVE_EXPRESSION_NAME_P (QUAL_WFL (TREE_CHAIN (q))) = 1;
+ RESOLVE_PACKAGE_NAME_P (QUAL_WFL (TREE_CHAIN (q))) = 0;
+ }
else
- parse_error_context
- (qual_wfl, "Undefined variable or class name: `%s'",
- IDENTIFIER_POINTER (EXPR_WFL_NODE (qual_wfl)));
- return 1;
+ {
+ if (from_super || from_cast)
+ parse_error_context
+ ((from_cast ? qual_wfl : wfl),
+ "No variable `%s' defined in class `%s'",
+ IDENTIFIER_POINTER (EXPR_WFL_NODE (qual_wfl)),
+ lang_printable_name (type, 0));
+ else
+ parse_error_context
+ (qual_wfl, "Undefined variable or class name: `%s'",
+ IDENTIFIER_POINTER (EXPR_WFL_NODE (qual_wfl)));
+ return 1;
+ }
}
/* We have a type name. It's been already resolved when the
@@ -5008,11 +6405,12 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
parse_error_context
(qual_wfl, "Can't access %s field `%s.%s' from `%s'",
java_accstring_lookup (get_access_flags_from_decl (decl)),
- IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))),
+ GET_TYPE_NAME (type),
IDENTIFIER_POINTER (DECL_NAME (decl)),
IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (current_class))));
return 1;
}
+ check_deprecation (qual_wfl, decl);
type = TREE_TYPE (decl);
from_type = 1;
@@ -5027,36 +6425,69 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
come. Don't do that when processing something after SUPER
(we need more thing to be put in place below */
if (!from_super && QUAL_RESOLUTION (q))
- decl = QUAL_RESOLUTION (q);
+ {
+ decl = QUAL_RESOLUTION (q);
+ if (!type)
+ {
+ if (!FIELD_STATIC (decl))
+ *where_found = current_this;
+ else
+ {
+ *where_found = TREE_TYPE (decl);
+ if (TREE_CODE (*where_found) == POINTER_TYPE)
+ *where_found = TREE_TYPE (*where_found);
+ }
+ }
+ }
/* We have to search for a field, knowing the type of its
container. The flag FROM_TYPE indicates that we resolved
the last member of the expression as a type name, which
- means that for the resolution of this field, will check
- on other errors than if the it was resolved as a member
- of an other field. */
+ means that for the resolution of this field, we'll look
+ for other errors than if it was resolved as a member of
+ an other field. */
else
{
int is_static;
+ tree field_decl_type; /* For layout */
+
if (!from_type && !JREFERENCE_TYPE_P (type))
{
parse_error_context
(qual_wfl, "Attempt to reference field `%s' in `%s %s'",
IDENTIFIER_POINTER (EXPR_WFL_NODE (qual_wfl)),
- lang_printable_name (type),
+ lang_printable_name (type, 0),
IDENTIFIER_POINTER (DECL_NAME (field_decl)));
return 1;
}
- if (!(field_decl =
- lookup_field_wrapper (type, EXPR_WFL_NODE (qual_wfl))))
+ field_decl = lookup_field_wrapper (type,
+ EXPR_WFL_NODE (qual_wfl));
+ if (field_decl == NULL_TREE)
{
parse_error_context
- (qual_wfl, "No variable `%s' defined in class `%s'",
+ (qual_wfl, "No variable `%s' defined in type `%s'",
IDENTIFIER_POINTER (EXPR_WFL_NODE (qual_wfl)),
- IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))));
+ GET_TYPE_NAME (type));
return 1;
}
+ if (field_decl == error_mark_node)
+ return 1;
+
+ /* Layout the type of field_decl, since we may need
+ it. Don't do primitive types or loaded classes. The
+ situation of non primitive arrays may not handled
+ properly here. FIXME */
+ if (TREE_CODE (TREE_TYPE (field_decl)) == POINTER_TYPE)
+ field_decl_type = TREE_TYPE (TREE_TYPE (field_decl));
+ else
+ field_decl_type = TREE_TYPE (field_decl);
+ if (!JPRIMITIVE_TYPE_P (field_decl_type)
+ && !CLASS_LOADED_P (field_decl_type)
+ && !TYPE_ARRAY_P (field_decl_type))
+ resolve_and_layout (field_decl_type, NULL_TREE);
+ if (TYPE_ARRAY_P (field_decl_type))
+ CLASS_LOADED_P (field_decl_type) = 1;
/* Check on accessibility here */
if (not_accessible_p (type, field_decl, from_super))
@@ -5066,12 +6497,13 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
"Can't access %s field `%s.%s' from `%s'",
java_accstring_lookup
(get_access_flags_from_decl (field_decl)),
- IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))),
+ GET_TYPE_NAME (type),
IDENTIFIER_POINTER (DECL_NAME (field_decl)),
IDENTIFIER_POINTER
(DECL_NAME (TYPE_NAME (current_class))));
return 1;
}
+ check_deprecation (qual_wfl, field_decl);
/* There are things to check when fields are accessed
from type. There are no restrictions on a static
@@ -5090,11 +6522,12 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
}
from_cast = from_super = 0;
- /* If we need to generate something to get a proper handle
- on what this field is accessed from, do it now. */
+ /* If we need to generate something to get a proper
+ handle on what this field is accessed from, do it
+ now. */
if (!is_static)
{
- decl = maybe_access_field (decl, *where_found, type);
+ decl = maybe_access_field (decl, *where_found, *type_found);
if (decl == error_mark_node)
return 1;
}
@@ -5108,7 +6541,6 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
search from */
decl = field_decl;
}
-
from_type = 0;
type = QUAL_DECL_TYPE (decl);
}
@@ -5139,32 +6571,19 @@ int not_accessible_p (reference, member, from_super)
if (class_in_current_package (DECL_CONTEXT (member)))
return 0;
- if (TREE_CODE (member) == FUNCTION_DECL && DECL_CONSTRUCTOR_P (member))
- {
- /* Access from SUPER is granted */
- if (from_super)
- return 0;
- /* Otherwise, access isn't granted */
- return 1;
- }
- else
- {
- /* If accessed with the form `super.member', then access is
- granted */
- if (from_super)
- return 0;
+ /* If accessed with the form `super.member', then access is granted */
+ if (from_super)
+ return 0;
- /* Otherwise, access is granted if occuring from the class where
- member is declared or a subclass of it */
- if (inherits_from_p (reference, current_class))
- return 0;
- }
+ /* Otherwise, access is granted if occuring from the class where
+ member is declared or a subclass of it */
+ if (inherits_from_p (reference, current_class))
+ return 0;
return 1;
}
/* Check access on private members. Access is granted only if it
- occurs from within the class in witch it is declared*/
-
+ occurs from within the class in witch it is declared */
if (access_flag & ACC_PRIVATE)
return (current_class == DECL_CONTEXT (member) ? 0 : 1);
@@ -5178,6 +6597,40 @@ int not_accessible_p (reference, member, from_super)
return 0;
}
+/* Test deprecated decl access. */
+static void
+check_deprecation (wfl, decl)
+ tree wfl, decl;
+{
+ char *file = DECL_SOURCE_FILE (decl);
+ /* Complain if the field is deprecated and the file it was defined
+ in isn't compiled at the same time the file which contains its
+ use is */
+ if (DECL_DEPRECATED (decl)
+ && !IS_A_COMMAND_LINE_FILENAME_P (get_identifier (file)))
+ {
+ char the [20];
+ switch (TREE_CODE (decl))
+ {
+ case FUNCTION_DECL:
+ strcpy (the, "method");
+ break;
+ case FIELD_DECL:
+ strcpy (the, "field");
+ break;
+ case TYPE_DECL:
+ strcpy (the, "class");
+ break;
+ default:
+ fatal ("unexpected DECL code - check_deprecation");
+ }
+ parse_warning_context
+ (wfl, "The %s `%s' in class `%s' has been deprecated",
+ the, lang_printable_name (decl, 0),
+ IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (DECL_CONTEXT (decl)))));
+ }
+}
+
/* Returns 1 if class was declared in the current package, 0 otherwise */
static int
@@ -5197,7 +6650,7 @@ class_in_current_package (class)
qualified, class isn't in the current package. If there is a
current package and the name of the CLASS is not qualified, class
isn't in the current package */
- if (!ctxp->package && qualified_flag || ctxp->package && !qualified_flag)
+ if ((!ctxp->package && qualified_flag) || (ctxp->package && !qualified_flag))
return 0;
/* If there is not package and the name of CLASS isn't qualified,
@@ -5222,28 +6675,31 @@ static tree
maybe_access_field (decl, where, type)
tree decl, where, type;
{
- if (DECL_P (decl) && decl != current_this
- && (!(TREE_CODE (decl) != PARM_DECL
- && FIELD_STATIC (decl)))
- && !IDENTIFIER_LOCAL_VALUE (DECL_NAME (decl)))
+ if (TREE_CODE (decl) == FIELD_DECL && decl != current_this
+ && !FIELD_STATIC (decl))
decl = build_field_ref (where ? where : current_this,
- type, DECL_NAME (decl));
+ (type ? type : DECL_CONTEXT (decl)),
+ DECL_NAME (decl));
return decl;
}
-/* Build a method invocation statement, by patching PATCH. If non NULL
+/* Build a method invocation, by patching PATCH. If non NULL
and according to the situation, PRIMARY and WHERE may be
used. IS_STATIC is set to 1 if the invoked function is static. */
static tree
-patch_method_invocation_stmt (patch, primary, where, is_static)
+patch_method_invocation (patch, primary, where, is_static, ret_decl)
tree patch, primary, where;
int *is_static;
+ tree *ret_decl;
{
tree wfl = TREE_OPERAND (patch, 0);
tree args = TREE_OPERAND (patch, 1);
tree name = EXPR_WFL_NODE (wfl);
- tree list, class_type;
+ tree list;
+ int is_static_flag = 0;
+ int is_super_init = 0;
+ tree this_arg = NULL_TREE;
/* Should be overriden if everything goes well. Otherwise, if
something fails, it should keep this value. It stop the
@@ -5280,7 +6736,7 @@ patch_method_invocation_stmt (patch, primary, where, is_static)
parse_error_context (wfl, "Can't search method `%s' in package "
"`%s'",IDENTIFIER_POINTER (identifier),
IDENTIFIER_POINTER (remainder));
- return error_mark_node;
+ PATCH_METHOD_RETURN_ERROR ();
}
/* We're resolving a call from a type */
else if (RESOLVE_TYPE_NAME_P (wfl))
@@ -5296,7 +6752,7 @@ patch_method_invocation_stmt (patch, primary, where, is_static)
(identifier_wfl, "Can't make static reference to method "
"`%s' in interface `%s'", IDENTIFIER_POINTER (identifier),
IDENTIFIER_POINTER (name));
- return error_mark_node;
+ PATCH_METHOD_RETURN_ERROR ();
}
/* Look the method up in the type selector. The method ought
to be static. */
@@ -5304,15 +6760,16 @@ patch_method_invocation_stmt (patch, primary, where, is_static)
list = lookup_method_invoke (0, wfl, type, identifier, args);
if (list && !METHOD_STATIC (list))
{
- char *fct_name = strdup ((char *)lang_printable_name (list));
+ char *fct_name = strdup (lang_printable_name (list, 0));
parse_error_context
(identifier_wfl,
"Can't make static reference to method `%s %s' in class `%s'",
- lang_printable_name (TREE_TYPE (TREE_TYPE (list))), fct_name,
- IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))));
+ lang_printable_name (TREE_TYPE (TREE_TYPE (list)), 0),
+ fct_name, IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))));
free (fct_name);
- return error_mark_node;
+ PATCH_METHOD_RETURN_ERROR ();
}
+ args = nreverse (args);
}
/* We're resolving an expression name */
else
@@ -5322,25 +6779,29 @@ patch_method_invocation_stmt (patch, primary, where, is_static)
/* 1- Find the field to which the call applies */
field = resolve_field_access (wfl, NULL, &type);
if (field == error_mark_node)
- return error_mark_node;
+ PATCH_METHOD_RETURN_ERROR ();
+ /* field is used in lieu of a primary. It alows us not to
+ report errors on erroneous use of `this' in
+ constructors. */
+ primary = field;
/* 2- Do the layout of the class where the last field
was found, so we can search it. */
- class_decl =
- resolve_and_layout (DECL_NAME (TYPE_NAME (type)), NULL_TREE);
-
+ class_decl = resolve_and_layout (type, NULL_TREE);
+ if (class_decl != NULL_TREE)
+ type = TREE_TYPE (class_decl);
+
/* 3- Retrieve a filtered list of method matches, Refine
if necessary. In any cases, point out errors. */
list = lookup_method_invoke (0, identifier_wfl, type,
identifier, args);
/* 4- Add the field as an argument */
- args = tree_cons (NULL_TREE, field, args);
+ args = nreverse (args);
+ this_arg = field;
}
- /* CLASS_TYPE is used during the call to not_accessible_p and
- IDENTIFIER_WFL will be used to report any problem further */
- class_type = TREE_TYPE (class_decl);
+ /* IDENTIFIER_WFL will be used to report any problem further */
wfl = identifier_wfl;
}
/* Resolution of simple names, names generated after a primary: or
@@ -5353,24 +6814,54 @@ patch_method_invocation_stmt (patch, primary, where, is_static)
/* We search constructor in their target class */
if (CALL_CONSTRUCTOR_P (patch))
{
- class_to_search = resolve_no_layout (EXPR_WFL_NODE (wfl), NULL_TREE);
- if (!class_to_search)
+ if (TREE_CODE (patch) == NEW_CLASS_EXPR)
+ class_to_search = EXPR_WFL_NODE (wfl);
+ else if (EXPR_WFL_NODE (TREE_OPERAND (patch, 0)) ==
+ this_identifier_node)
+ class_to_search = NULL_TREE;
+ else if (EXPR_WFL_NODE (TREE_OPERAND (patch, 0)) ==
+ super_identifier_node)
{
- parse_error_context
- (wfl, "Class `%s' not found in type declaration",
- IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl)));
- return error_mark_node;
+ is_super_init = 1;
+ if (CLASSTYPE_SUPER (current_class))
+ class_to_search =
+ DECL_NAME (TYPE_NAME (CLASSTYPE_SUPER (current_class)));
+ else
+ {
+ parse_error_context (wfl, "Can't invoke super constructor "
+ "on java.lang.Object");
+ PATCH_METHOD_RETURN_ERROR ();
+ }
}
-
- /* Can't instantiate an abstract class */
- if (CLASS_ABSTRACT (class_to_search))
+
+ /* Class to search is NULL if we're searching the current one */
+ if (class_to_search)
{
- parse_error_context
- (wfl, "Class `%s' is an abstract class. It can't be "
- "instantiated", IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl)));
- return error_mark_node;
+ class_to_search = resolve_and_layout (class_to_search,
+ NULL_TREE);
+ if (!class_to_search)
+ {
+ parse_error_context
+ (wfl, "Class `%s' not found in type declaration",
+ IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl)));
+ PATCH_METHOD_RETURN_ERROR ();
+ }
+
+ /* Can't instantiate an abstract class, but we can
+ invoke it's constructor. It's use within the `new'
+ context is denied here. */
+ if (CLASS_ABSTRACT (class_to_search)
+ && TREE_CODE (patch) == NEW_CLASS_EXPR)
+ {
+ parse_error_context
+ (wfl, "Class `%s' is an abstract class. It can't be "
+ "instantiated", IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl)));
+ PATCH_METHOD_RETURN_ERROR ();
+ }
+ class_to_search = TREE_TYPE (class_to_search);
}
- class_to_search = TREE_TYPE (class_to_search);
+ else
+ class_to_search = current_class;
lc = 1;
}
/* This is a regular search in the local class, unless an
@@ -5384,49 +6875,90 @@ patch_method_invocation_stmt (patch, primary, where, is_static)
/* NAME is a simple identifier or comes from a primary. Search
in the class whose declaration contain the method being
invoked. */
+ resolve_and_layout (class_to_search, NULL_TREE);
list = lookup_method_invoke (lc, wfl, class_to_search, name, args);
/* Don't continue if no method were found, as the next statement
can't be executed then. */
- if (!list) return error_mark_node;
+ if (!list)
+ PATCH_METHOD_RETURN_ERROR ();
/* Check for static reference if non static methods */
if (check_for_static_method_reference (wfl, patch, list,
class_to_search, primary))
- return error_mark_node;
-
- /* Non static/constructor methods are called with the current
- object extra argument. If method is resolved as a primary,
- use the primary otherwise use the current THIS. */
- if (!CALL_CONSTRUCTOR_P (patch) && !METHOD_STATIC (list))
- args = tree_cons (NULL_TREE, primary ? primary : current_this, args);
+ PATCH_METHOD_RETURN_ERROR ();
- class_type = class_to_search;
+ /* Non static methods are called with the current object extra
+ argument. If patch a `new TYPE()', the argument is the value
+ returned by the object allocator. If method is resolved as a
+ primary, use the primary otherwise use the current THIS. */
+ args = nreverse (args);
+ if (TREE_CODE (patch) != NEW_CLASS_EXPR)
+ this_arg = primary ? primary : current_this;
}
-
+
/* Merge point of all resolution schemes. If we have nothing, this
is an error, already signaled */
- if (!list) return error_mark_node;
-
+ if (!list)
+ PATCH_METHOD_RETURN_ERROR ();
+
/* Check accessibility, position the is_static flag, build and
return the call */
- if (not_accessible_p (class_type, list, 0))
+ if (not_accessible_p (DECL_CONTEXT (current_function_decl), list, 0))
{
- char *fct_name = strdup ((char *)lang_printable_name (list));
+ char *fct_name = strdup (lang_printable_name (list, 0));
parse_error_context
(wfl, "Can't access %s method `%s %s.%s' from `%s'",
java_accstring_lookup (get_access_flags_from_decl (list)),
- lang_printable_name (TREE_TYPE (TREE_TYPE (list))),
- IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (class_type))), fct_name,
- IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (current_class))));
+ lang_printable_name (TREE_TYPE (TREE_TYPE (list)), 0),
+ IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (DECL_CONTEXT (list)))),
+ fct_name, IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (current_class))));
free (fct_name);
- return error_mark_node;
+ PATCH_METHOD_RETURN_ERROR ();
+ }
+ check_deprecation (wfl, list);
+
+ is_static_flag = METHOD_STATIC (list);
+ if (! METHOD_STATIC (list) && this_arg != NULL_TREE)
+ args = tree_cons (NULL_TREE, this_arg, args);
+
+ /* In the context of an explicit constructor invocation, we can't
+ invoke any method relying on `this'. Exceptions are: we're
+ invoking a static function, primary exists and is not the current
+ this, we're creating a new object. */
+ if (ctxp->explicit_constructor_p
+ && !is_static_flag
+ && (!primary || primary == current_this)
+ && (TREE_CODE (patch) != NEW_CLASS_EXPR))
+ {
+ parse_error_context
+ (wfl, "Can't reference `this' before the superclass constructor has "
+ "been called");
+ PATCH_METHOD_RETURN_ERROR ();
}
-
- if (is_static)
- *is_static = METHOD_STATIC (list);
java_parser_context_restore_global ();
- return patch_invoke (patch, list, args, wfl);
+ if (is_static)
+ *is_static = is_static_flag;
+ /* Sometimes, we want the decl of the selected method. Such as for
+ EH checking */
+ if (ret_decl)
+ *ret_decl = list;
+ patch = patch_invoke (patch, list, args);
+ if (is_super_init && CLASS_HAS_FINIT_P (current_class))
+ {
+ /* Generate the code used to initialize fields declared with an
+ initialization statement. For now, it returns a call the the
+ artificial function $finit$, if required. */
+
+ tree finit_call =
+ build_method_invocation (build_expr_wfl (finit_identifier_node,
+ input_filename, 0, 0),
+ NULL_TREE);
+ patch = build (COMPOUND_EXPR, void_type_node, patch,
+ java_complete_tree (finit_call));
+ CAN_COMPLETE_NORMALLY (patch) = 1;
+ }
+ return patch;
}
/* Check that we're not trying to do a static reference to a method in
@@ -5439,10 +6971,10 @@ check_for_static_method_reference (wfl, node, method, where, primary)
if (METHOD_STATIC (current_function_decl)
&& !METHOD_STATIC (method) && !primary && !CALL_CONSTRUCTOR_P (node))
{
- char *fct_name = strdup ((char *)lang_printable_name (method));
+ char *fct_name = strdup (lang_printable_name (method, 0));
parse_error_context
(wfl, "Can't make static reference to method `%s %s' in class `%s'",
- lang_printable_name (TREE_TYPE (TREE_TYPE (method))), fct_name,
+ lang_printable_name (TREE_TYPE (TREE_TYPE (method)), 0), fct_name,
IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (where))));
free (fct_name);
return 1;
@@ -5454,48 +6986,76 @@ check_for_static_method_reference (wfl, node, method, where, primary)
mode. */
static tree
-patch_invoke (patch, method, args, cl)
+patch_invoke (patch, method, args)
tree patch, method, args;
- tree cl;
{
tree dtable, func;
- tree signature = build_java_signature (TREE_TYPE (method));
- tree original_call;
-
- switch (invocation_mode (method, 0))
+ tree original_call, t, ta;
+
+ /* Last step for args: convert build-in types. If we're dealing with
+ a new TYPE() type call, the first argument to the constructor
+ isn't found in the incomming argument list, but delivered by
+ `new' */
+ t = TYPE_ARG_TYPES (TREE_TYPE (method));
+ if (TREE_CODE (patch) == NEW_CLASS_EXPR)
+ t = TREE_CHAIN (t);
+ for (ta = args; t != end_params_node && ta;
+ t = TREE_CHAIN (t), ta = TREE_CHAIN (ta))
+ if (JPRIMITIVE_TYPE_P (TREE_TYPE (TREE_VALUE (ta))) &&
+ TREE_TYPE (TREE_VALUE (ta)) != TREE_VALUE (t))
+ TREE_VALUE (ta) = convert (TREE_VALUE (t), TREE_VALUE (ta));
+
+ if (flag_emit_class_files)
+ func = method;
+ else
{
- case INVOKE_VIRTUAL:
- dtable = invoke_build_dtable (0, args);
- func = build_invokevirtual (dtable, method);
- break;
- case INVOKE_STATIC:
- func = build_known_method_ref (method, TREE_TYPE (method),
- DECL_CONTEXT (method),
- signature, args);
- args = nreverse (args);
- break;
+ tree signature = build_java_signature (TREE_TYPE (method));
+ switch (invocation_mode (method, CALL_USING_SUPER (patch)))
+ {
+ case INVOKE_VIRTUAL:
+ dtable = invoke_build_dtable (0, args);
+ func = build_invokevirtual (dtable, method);
+ break;
- default:
- fatal ("Unknown invocation mode - build_invoke");
- return NULL_TREE;
- }
+ case INVOKE_SUPER:
+ case INVOKE_STATIC:
+ func = build_known_method_ref (method, TREE_TYPE (method),
+ DECL_CONTEXT (method),
+ signature, args);
+ break;
+
+ case INVOKE_INTERFACE:
+ dtable = invoke_build_dtable (1, args);
+ func = build_invokeinterface (dtable, DECL_NAME (method), signature);
+ break;
+
+ default:
+ fatal ("internal error - unknown invocation_mode result");
+ }
+ /* Ensure self_type is initialized, (invokestatic). FIXME */
+ func = build1 (NOP_EXPR, build_pointer_type (TREE_TYPE (method)), func);
+ }
- /* Ensure self_type is initialized, (invokestatic). FIXME */
- func = build1 (NOP_EXPR, build_pointer_type (TREE_TYPE (method)), func);
TREE_TYPE (patch) = TREE_TYPE (TREE_TYPE (method));
TREE_OPERAND (patch, 0) = func;
TREE_OPERAND (patch, 1) = args;
original_call = patch;
- /* We're calling a constructor. New is called an its returned value
- is an argument to the constructor. We build a COMPOUND_EXPR and
- use saved expression so that the overall NEW expression value is
- a pointer to a newly created and initialized class. */
- if (CALL_CONSTRUCTOR_P (original_call))
+ /* We're processing a `new TYPE ()' form. New is called an its
+ returned value is the first argument to the constructor. We build
+ a COMPOUND_EXPR and use saved expression so that the overall NEW
+ expression value is a pointer to a newly created and initialized
+ class. */
+ if (TREE_CODE (original_call) == NEW_CLASS_EXPR)
{
tree class = DECL_CONTEXT (method);
tree c1, saved_new, size, new;
+ if (flag_emit_class_files)
+ {
+ TREE_TYPE (patch) = build_pointer_type (class);
+ return patch;
+ }
if (!TYPE_SIZE (class))
safe_layout_class (class);
size = size_in_bytes (class);
@@ -5522,25 +7082,26 @@ invocation_mode (method, super)
{
int access = get_access_flags_from_decl (method);
- if (access & ACC_STATIC)
+ if (super)
+ return INVOKE_SUPER;
+
+ if (access & ACC_STATIC || access & ACC_FINAL || access & ACC_PRIVATE)
return INVOKE_STATIC;
if (CLASS_FINAL (TYPE_NAME (DECL_CONTEXT (method))))
return INVOKE_STATIC;
- if (super)
- return INVOKE_SUPER;
-
if (CLASS_INTERFACE (TYPE_NAME (DECL_CONTEXT (method))))
return INVOKE_INTERFACE;
if (DECL_CONSTRUCTOR_P (method))
return INVOKE_STATIC;
-
+
return INVOKE_VIRTUAL;
}
-/* Retrieve a refined list of matching methods. */
+/* Retrieve a refined list of matching methods. It covers the step
+ 15.11.2 (Compile-Time Step 2) */
static tree
lookup_method_invoke (lc, cl, class, name, arg_list)
@@ -5548,159 +7109,271 @@ lookup_method_invoke (lc, cl, class, name, arg_list)
tree cl;
tree class, name, arg_list;
{
- tree method = make_node (FUNCTION_TYPE);
- tree arg_type_list = NULL_TREE;
- tree signature, list, node, scratch;
+ tree atl = end_params_node; /* Arg Type List */
+ tree method, signature, list, node;
+ char *candidates; /* Used for error report */
+ /* Fix the arguments */
for (node = arg_list; node; node = TREE_CHAIN (node))
{
- tree current_arg;
- current_arg =
- build_tree_list (NULL_TREE,
- promote_type (TREE_TYPE (TREE_VALUE (node))));
- arg_type_list = chainon (current_arg, arg_type_list);
- }
- TYPE_ARG_TYPES (method) = arg_type_list;
+ tree current_arg = TREE_TYPE (TREE_VALUE (node));
+ /* Non primitive type may have to be resolved */
+ if (!JPRIMITIVE_TYPE_P (current_arg))
+ resolve_and_layout (current_arg, NULL_TREE);
+ /* And promoted */
+ if (TREE_CODE (current_arg) == RECORD_TYPE)
+ current_arg = promote_type (current_arg);
+ atl = tree_cons (NULL_TREE, current_arg, atl);
+ }
+
+ /* Find all candidates and then refine the list, searching for the
+ most specific method. */
+ list = find_applicable_accessible_methods_list (lc, class, name, atl);
+ list = find_most_specific_methods_list (list);
+ if (list && !TREE_CHAIN (list))
+ return TREE_VALUE (list);
- if (!lc)
+ /* Issue an error. List candidates if any. Candidates are listed
+ only if accessible (non accessible methods may end-up here for
+ the sake of a better error report). */
+ candidates = NULL;
+ if (list)
{
- signature = build_java_argument_signature (method);
- list = match_java_method (class, name, signature);
- list = refine_accessible_methods_list (lc, list);
+ tree current;
+ obstack_grow (&temporary_obstack, ". Candidates are:\n", 18);
+ for (current = list; current; current = TREE_CHAIN (current))
+ {
+ tree cm = TREE_VALUE (current);
+ char string [4096];
+ if (!cm || not_accessible_p (class, cm, 0))
+ continue;
+ sprintf
+ (string, " `%s' in `%s'%s",
+ get_printable_method_name (cm),
+ IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (DECL_CONTEXT (cm)))),
+ (TREE_CHAIN (current) ? "\n" : ""));
+ obstack_grow (&temporary_obstack, string, strlen (string));
+ }
+ obstack_1grow (&temporary_obstack, '\0');
+ candidates = obstack_finish (&temporary_obstack);
+ }
+ /* Issue the error message */
+ method = make_node (FUNCTION_TYPE);
+ TYPE_ARG_TYPES (method) = atl;
+ signature = build_java_argument_signature (method);
+ parse_error_context (cl, "Can't find %s `%s(%s)' in class `%s'%s",
+ (lc ? "constructor" : "method"),
+ (lc ?
+ IDENTIFIER_POINTER(DECL_NAME (TYPE_NAME (class))) :
+ IDENTIFIER_POINTER (name)),
+ IDENTIFIER_POINTER (signature),
+ IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (class))),
+ (candidates ? candidates : ""));
+ return NULL_TREE;
+}
+
+/* 15.11.2.1: Find Methods that are Applicable and Accessible. LC is 1
+ when we're looking for a constructor. */
+
+static tree
+find_applicable_accessible_methods_list (lc, class, name, arglist)
+ int lc;
+ tree class, name, arglist;
+{
+ tree list = NULL_TREE, all_list = NULL_TREE;
+
+ /* Search interfaces */
+ if (CLASS_INTERFACE (TYPE_NAME (class)))
+ {
+ static tree searched_interfaces = NULL_TREE;
+ static int search_not_done = 0;
+ int i, n;
+ tree basetype_vec = TYPE_BINFO_BASETYPES (class);
+
+ /* Have we searched this interface already? */
+ if (searched_interfaces)
+ {
+ tree current;
+ for (current = searched_interfaces;
+ current; current = TREE_CHAIN (current))
+ if (TREE_VALUE (current) == class)
+ return NULL;
+ }
+ searched_interfaces = tree_cons (NULL_TREE, class, searched_interfaces);
+
+ search_applicable_methods_list
+ (lc, TYPE_METHODS (class), name, arglist, &list, &all_list);
+
+ n = TREE_VEC_LENGTH (basetype_vec);
+ for (i = 0; i < n; i++)
+ {
+ tree t = BINFO_TYPE (TREE_VEC_ELT (basetype_vec, i));
+ tree rlist;
+
+ /* Skip java.lang.Object (we'll search it once later.) */
+ if (t == object_type_node)
+ continue;
+
+ search_not_done++;
+ rlist = find_applicable_accessible_methods_list (lc, t, name,
+ arglist);
+ all_list = chainon (rlist, (list ? list : all_list));
+ search_not_done--;
+ }
+
+ /* We're done. Reset the searched interfaces list and finally search
+ java.lang.Object */
+ if (!search_not_done)
+ {
+ searched_interfaces = NULL_TREE;
+ search_applicable_methods_list (lc, TYPE_METHODS (object_type_node),
+ name, arglist, &list, &all_list);
+ }
}
+ /* Search classes */
else
- {
- TREE_TYPE (method) = void_type_node;
- signature = build_java_signature (method);
- list = lookup_java_constructor (class, signature);
- }
+ while (class != NULL_TREE)
+ {
+ search_applicable_methods_list
+ (lc, TYPE_METHODS (class), name, arglist, &list, &all_list);
+ class = (lc ? NULL_TREE : CLASSTYPE_SUPER (class));
+ }
+
+ /* Either return the list obtained or all selected (but
+ inaccessible) methods for better error report. */
+ return (!list ? all_list : list);
+}
+
+/* Effectively search for the approriate method in method */
- if (!list)
+static void
+search_applicable_methods_list(lc, method, name, arglist, list, all_list)
+ int lc;
+ tree method, name, arglist;
+ tree *list, *all_list;
+{
+ for (; method; method = TREE_CHAIN (method))
{
- parse_error_context (cl, "Can't find method `%s(%s)' in class `%s'",
- IDENTIFIER_POINTER (name),
- IDENTIFIER_POINTER (signature),
- IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (class))));
- return NULL_TREE;
+ /* When dealing with constructor, stop here, otherwise search
+ other classes */
+ if (lc && !DECL_CONSTRUCTOR_P (method))
+ continue;
+ else if (!lc && (DECL_CONSTRUCTOR_P (method)
+ || (GET_METHOD_NAME (method) != name)))
+ continue;
+
+ if (argument_types_convertible (method, arglist))
+ {
+ /* Retain accessible methods only */
+ if (!not_accessible_p (DECL_CONTEXT (current_function_decl),
+ method, 0))
+ *list = tree_cons (NULL_TREE, method, *list);
+ else
+ /* Also retain all selected method here */
+ *all_list = tree_cons (NULL_TREE, method, *list);
+ }
}
+}
- if (lc)
- return list;
+/* 15.11.2.2 Choose the Most Specific Method */
- if (TREE_CHAIN (list))
+static tree
+find_most_specific_methods_list (list)
+ tree list;
+{
+ int max = 0;
+ tree current, new_list = NULL_TREE;
+ for (current = list; current; current = TREE_CHAIN (current))
{
- tree most_specific_list = NULL_TREE;
- tree current;
- /* 15.11.2.2 Choose the Most Specific Method */
- for (current = list; current; current = TREE_CHAIN (current))
+ tree method;
+ DECL_SPECIFIC_COUNT (TREE_VALUE (current)) = 0;
+
+ for (method = list; method; method = TREE_CHAIN (method))
{
- tree rest;
- tree method = TREE_VALUE (list);
- tree class_from = DECL_CONTEXT (method);
- for (rest = TREE_CHAIN (current); rest; rest = TREE_CHAIN (rest))
+ /* Don't test a method against itself */
+ if (method == current)
+ continue;
+
+ /* Compare arguments and location where method where declared */
+ if (argument_types_convertible (TREE_VALUE (method),
+ TREE_VALUE (current))
+ && valid_method_invocation_conversion_p
+ (DECL_CONTEXT (TREE_VALUE (method)),
+ DECL_CONTEXT (TREE_VALUE (current))))
{
- tree other = TREE_VALUE (rest);
-
- /* METHOD can be declared more specific with regard to OTHER iif:
-
- - The class METHOD belongs can be converted to the
- class OTHER belongs by method invocation conversion
- (5.3). Since we're dealing with classes here, it is
- covered by the identity conversion or the windening
- primitive conversion.
-
- - The types of the arguments of METHOD can be
- converted to the types of the arguments of OTHER by
- method invocation conversion (5.3). */
-
- if (valid_ref_assignconv_cast_p (class_from,
- DECL_CONTEXT (other), 0)
- && 1) /* Test on args non implemented */
- most_specific_list = tree_cons (NULL_TREE, method,
- most_specific_list);
+ int v = ++DECL_SPECIFIC_COUNT (TREE_VALUE (current));
+ max = (v > max ? v : max);
}
}
- list = most_specific_list;
}
- if (!list || TREE_CHAIN (list))
+ /* Review the list and select the maximally specific methods */
+ for (current = list; current; current = TREE_CHAIN (current))
+ if (DECL_SPECIFIC_COUNT (TREE_VALUE (current)) == max)
+ new_list = tree_cons (NULL_TREE, TREE_VALUE (current), new_list);
+
+ /* If we can't find one, lower expectations and try to gather multiple
+ maximally specific methods */
+ while (!new_list)
{
- parse_error_context (cl, "Can't find method `%s(%s)' in class `%s'",
- IDENTIFIER_POINTER (name),
- IDENTIFIER_POINTER (signature),
- IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (class))));
- return NULL_TREE;
+ while (--max > 0)
+ {
+ if (DECL_SPECIFIC_COUNT (TREE_VALUE (current)) == max)
+ new_list = tree_cons (NULL_TREE, TREE_VALUE (current), new_list);
+ }
+ return new_list;
}
- /* 15.11.3 Is the Chosen Method Appropriate ? */
- else
- return TREE_VALUE (list);
+ return new_list;
}
-/* Refine accessible methods from the raw matching method list, as
- specified in 15.11.4.3. Return a (possibly empty) new method
- list. */
+/* Make sure that the type of each M2_OR_ARGLIST arguments can be
+ converted by method invocation conversion (5.3) to the type of the
+ corresponding parameter of M1. Implementation expects M2_OR_ARGLIST
+ to change less often than M1. */
-static tree
-refine_accessible_methods_list (lc, list)
- int lc; /* Looking for Constructor */
- tree list;
+static int
+argument_types_convertible (m1, m2_or_arglist)
+ tree m1, m2_or_arglist;
{
-#define ADD_TO_LIST_AND_CONTINUE \
- { \
- refined_list = tree_cons (NULL_TREE, method, refined_list); \
- continue; \
- }
- tree node, refined_list = NULL_TREE;
- tree current_class_name = DECL_NAME (TYPE_NAME (current_class));
-
- for (node = list; node; node = TREE_CHAIN (node))
- {
- int access, identical;
- tree class_from, method, class_from_name;
-
- method = TREE_VALUE (node);
+ static tree m2_arg_value = NULL_TREE;
+ static tree m2_arg_cache = NULL_TREE;
- /* Constructor not retained here, unless were specifically
- looking for them. */
- if (lc && DECL_CONSTRUCTOR_P (method))
- ADD_TO_LIST_AND_CONTINUE;
+ register tree m1_arg, m2_arg;
- access = get_access_flags_from_decl (method);
- class_from = DECL_CONTEXT (method);
- class_from_name = DECL_NAME (TYPE_NAME (class_from));
-
- identical = identical_subpath_p (current_class_name, class_from_name);
+ m1_arg = TYPE_ARG_TYPES (TREE_TYPE (m1));
+ if (!METHOD_STATIC (m1))
+ m1_arg = TREE_CHAIN (m1_arg);
- /* Check accessibility of class_from from the current one: This
- test has been already carried out when qualify_ambiguous_name
- tried to resolve a type found in an other package. It is not
- necessary to retest things here, the error has been already
- reported. */
-
- /* Public method are always OK */
- if (access & ACC_PUBLIC)
- ADD_TO_LIST_AND_CONTINUE;
-
- /* Protected method access is OK if classes are from the
- same package or part of the same inheritance lineage */
- if ((access & ACC_PROTECTED)
- && (inherits_from_p (current_class, class_from) || identical))
- ADD_TO_LIST_AND_CONTINUE;
+ if (m2_arg_value == m2_or_arglist)
+ m2_arg = m2_arg_cache;
+ else
+ {
+ /* M2_OR_ARGLIST can be a function DECL or a raw list of
+ argument types */
+ if (m2_or_arglist && TREE_CODE (m2_or_arglist) == FUNCTION_DECL)
+ {
+ m2_arg = TYPE_ARG_TYPES (TREE_TYPE (m2_or_arglist));
+ if (!METHOD_STATIC (m2_or_arglist))
+ m2_arg = TREE_CHAIN (m2_arg);
+ }
+ else
+ m2_arg = m2_or_arglist;
- /* Methods with default (package) access are OK if classes are
- from the same default package. */
- if (identical ||
- (!QUALIFIED_P (class_from_name) && !QUALIFIED_P (current_class_name)))
- ADD_TO_LIST_AND_CONTINUE;
+ m2_arg_value = m2_or_arglist;
+ m2_arg_cache = m2_arg;
+ }
- /* Private method accessible iff current class is the node where
- the method is defined */
- if ((access & ACC_PRIVATE) && (class_from == current_class))
- ADD_TO_LIST_AND_CONTINUE;
+ while (m1_arg != end_params_node && m2_arg != end_params_node)
+ {
+ resolve_and_layout (TREE_VALUE (m1_arg), NULL_TREE);
+ if (!valid_method_invocation_conversion_p (TREE_VALUE (m1_arg),
+ TREE_VALUE (m2_arg)))
+ break;
+ m1_arg = TREE_CHAIN (m1_arg);
+ m2_arg = TREE_CHAIN (m2_arg);
}
-#undef ADD_TO_LIST_AND_CONTINUE
- return refined_list;
+ return m1_arg == end_params_node && m2_arg == end_params_node;
}
/* Qualification routines */
@@ -5710,7 +7383,7 @@ qualify_ambiguous_name (id)
tree id;
{
tree qual, qual_wfl, name, decl, ptr_type, saved_current_class;
- int again, super_found = 0, this_found = 0;
+ int again, super_found = 0, this_found = 0, new_array_found = 0;
/* We first qualify the first element, then derive qualification of
others based on the first one. If the first element is qualified
@@ -5738,11 +7411,21 @@ qualify_ambiguous_name (id)
qual_wfl = QUAL_WFL (qual);
}
break;
- case JAVA_NEW_CLASS_EXPR:
+ case NEW_ARRAY_EXPR:
+ qual = TREE_CHAIN (qual);
+ new_array_found = again = 1;
+ continue;
+ case NEW_CLASS_EXPR:
case CONVERT_EXPR:
- case ARRAY_REF:
qual_wfl = TREE_OPERAND (qual_wfl, 0);
break;
+ case ARRAY_REF:
+ while (TREE_CODE (qual_wfl) == ARRAY_REF)
+ qual_wfl = TREE_OPERAND (qual_wfl, 0);
+ break;
+ default:
+ /* Fix for -Wall. Just break doing nothing */
+ break;
}
name = EXPR_WFL_NODE (qual_wfl);
ptr_type = current_class;
@@ -5752,7 +7435,10 @@ qualify_ambiguous_name (id)
{
qual = TREE_CHAIN (qual);
qual_wfl = QUAL_WFL (qual);
- name = EXPR_WFL_NODE (qual_wfl);
+ if (TREE_CODE (qual_wfl) == CALL_EXPR)
+ again = 1;
+ else
+ name = EXPR_WFL_NODE (qual_wfl);
this_found = 1;
}
/* If we have a SUPER, we set the context accordingly */
@@ -5771,13 +7457,22 @@ qualify_ambiguous_name (id)
/* Do one more interation to set things up */
super_found = again = 1;
}
+ /* Loop one more time if we're dealing with ?: or a string
+ constant, or a convert expression */
+ if (TREE_CODE (qual_wfl) == CONDITIONAL_EXPR
+ || TREE_CODE (qual_wfl) == STRING_CST
+ || TREE_CODE (qual_wfl) == CONVERT_EXPR)
+ {
+ qual = TREE_CHAIN (qual);
+ qual_wfl = QUAL_WFL (qual);
+ again = 1;
+ }
} while (again);
/* If name appears within the scope of a location variable
declaration or parameter declaration, then it is an expression
name. We don't carry this test out if we're in the context of the
use of SUPER or THIS */
-
if (!this_found && !super_found && (decl = IDENTIFIER_LOCAL_VALUE (name)))
{
RESOLVE_EXPRESSION_NAME_P (qual_wfl) = 1;
@@ -5786,11 +7481,13 @@ qualify_ambiguous_name (id)
/* If within the class/interface NAME was found to be used there
exists a (possibly inherited) field named NAME, then this is an
- expression name. */
- else if ((decl = lookup_field_wrapper (ptr_type, name)))
+ expression name. If we saw a NEW_ARRAY_EXPR before and want to
+ address length, it is OK. */
+ else if ((decl = lookup_field_wrapper (ptr_type, name))
+ || (new_array_found && name == length_identifier_node))
{
RESOLVE_EXPRESSION_NAME_P (qual_wfl) = 1;
- QUAL_RESOLUTION (qual) = decl;
+ QUAL_RESOLUTION (qual) = (new_array_found ? NULL_TREE : decl);
}
/* We reclassify NAME as a type name if:
@@ -5808,7 +7505,8 @@ qualify_ambiguous_name (id)
}
/* Method call are expression name */
- else if (TREE_CODE (QUAL_WFL (qual)) == CALL_EXPR)
+ else if (TREE_CODE (QUAL_WFL (qual)) == CALL_EXPR
+ || TREE_CODE (QUAL_WFL (qual)) == ARRAY_REF)
RESOLVE_EXPRESSION_NAME_P (qual_wfl) = 1;
/* Check here that NAME isn't declared by more than one
@@ -5869,49 +7567,57 @@ breakdown_qualified (left, right, source)
return 0;
}
-/* Return 1 if N1 and N2 have identical sub-path. */
+/* Patch tree nodes in a function body. When a BLOCK is found, push
+ local variable decls if present.
+ Same as java_complete_lhs, but does resolve static finals to values. */
-static int
-identical_subpath_p (n1, n2)
- tree n1, n2;
+static tree
+java_complete_tree (node)
+ tree node;
{
- tree left1, left2;
-
- if (!QUALIFIED_P (n1) || !QUALIFIED_P (n2))
- return n1 == n2;
-
- breakdown_qualified (&left1, NULL, n1);
- breakdown_qualified (&left2, NULL, n2);
-
- return left1 == left2;
+ node = java_complete_lhs (node);
+ if (TREE_CODE (node) == VAR_DECL && FIELD_STATIC (node)
+ && FIELD_FINAL (node) && DECL_INITIAL (node) != NULL_TREE)
+ {
+ tree value = DECL_INITIAL (node);
+ DECL_INITIAL (node) = NULL_TREE;
+ value = fold_constant_for_init (value, node);
+ DECL_INITIAL (node) = value;
+ if (value != NULL_TREE)
+ return value;
+ }
+ return node;
}
-static int
-not_initialized_as_it_should_p (decl)
- tree decl;
+static tree
+java_stabilize_reference (node)
+ tree node;
{
- if (DECL_P (decl))
+ if (TREE_CODE (node) == COMPOUND_EXPR)
{
- if (TREE_CODE (decl) == FIELD_DECL
- && METHOD_STATIC (current_function_decl))
- return 0;
- return DECL_P (decl) && !INITIALIZED_P (decl);
+ tree op0 = TREE_OPERAND (node, 0);
+ tree op1 = TREE_OPERAND (node, 1);
+ TREE_OPERAND (node, 0) = save_expr (op0);
+ TREE_OPERAND (node, 1) = java_stabilize_reference (op1);
+ return node;
}
- return 0;
+ else
+ return stabilize_reference (node);
}
/* Patch tree nodes in a function body. When a BLOCK is found, push
- local variable decls if present. */
+ local variable decls if present.
+ Same as java_complete_tree, but does not resolve static finals to values. */
static tree
-java_complete_tree (node)
+java_complete_lhs (node)
tree node;
{
- tree nn, cn, wfl_op1, wfl_op2;
- int flag, location;
+ tree nn, cn, wfl_op1, wfl_op2, wfl_op3;
+ int flag;
/* CONVERT_EXPR always has its type set, even though it needs to be
- worked out */
+ worked out. */
if (TREE_TYPE (node) && TREE_CODE (node) != CONVERT_EXPR)
return node;
@@ -5930,13 +7636,67 @@ java_complete_tree (node)
{
DECL_CONTEXT (cn) = current_function_decl;
IDENTIFIER_LOCAL_VALUE (DECL_NAME (cn)) = cn;
- INITIALIZED_P (cn) = 0;
}
- if (BLOCK_EXPR_BODY (node))
+ if (BLOCK_EXPR_BODY (node) == NULL_TREE)
+ CAN_COMPLETE_NORMALLY (node) = 1;
+ else
{
- BLOCK_EXPR_BODY (node) = java_complete_tree (BLOCK_EXPR_BODY (node));
- if (BLOCK_EXPR_BODY (node) == error_mark_node)
+ tree stmt = BLOCK_EXPR_BODY (node);
+ tree *ptr;
+ int error_seen = 0;
+ if (TREE_CODE (stmt) == COMPOUND_EXPR)
+ {
+ /* Re-order from (((A; B); C); ...; Z) to
+ (A; (B; (C ; (...; Z)))).
+ This makes it easier to scan the statements left-to-right
+ without using recursion (which might overflow the stack
+ if the block has many statements. */
+ for (;;)
+ {
+ tree left = TREE_OPERAND (stmt, 0);
+ if (TREE_CODE (left) != COMPOUND_EXPR)
+ break;
+ TREE_OPERAND (stmt, 0) = TREE_OPERAND (left, 1);
+ TREE_OPERAND (left, 1) = stmt;
+ stmt = left;
+ }
+ BLOCK_EXPR_BODY (node) = stmt;
+ }
+
+ /* Now do the actual complete, without deep recursion for
+ long blocks. */
+ ptr = &BLOCK_EXPR_BODY (node);
+ while (TREE_CODE (*ptr) == COMPOUND_EXPR
+ && TREE_OPERAND (*ptr, 1) != empty_stmt_node)
+ {
+ tree cur = java_complete_tree (TREE_OPERAND (*ptr, 0));
+ tree *next = &TREE_OPERAND (*ptr, 1);
+ TREE_OPERAND (*ptr, 0) = cur;
+ if (TREE_CODE (cur) == ERROR_MARK)
+ error_seen++;
+ else if (! CAN_COMPLETE_NORMALLY (cur))
+ {
+ wfl_op2 = *next;
+ for (;;)
+ {
+ if (TREE_CODE (wfl_op2) == BLOCK)
+ wfl_op2 = BLOCK_EXPR_BODY (wfl_op2);
+ else if (TREE_CODE (wfl_op2) == COMPOUND_EXPR)
+ wfl_op2 = TREE_OPERAND (wfl_op2, 0);
+ else
+ break;
+ }
+ if (TREE_CODE (wfl_op2) != CASE_EXPR
+ && TREE_CODE (wfl_op2) != DEFAULT_EXPR)
+ unreachable_stmt_error (*ptr);
+ }
+ ptr = next;
+ }
+ *ptr = java_complete_tree (*ptr);
+
+ if (TREE_CODE (*ptr) == ERROR_MARK || error_seen > 0)
return error_mark_node;
+ CAN_COMPLETE_NORMALLY (node) = CAN_COMPLETE_NORMALLY (*ptr);
}
/* Turn local bindings to null */
for (cn = BLOCK_EXPR_DECLS (node); cn; cn = TREE_CHAIN (cn))
@@ -5946,12 +7706,52 @@ java_complete_tree (node)
break;
/* 2- They are expressions but ultimately deal with statements */
+
+ case THROW_EXPR:
+ wfl_op1 = TREE_OPERAND (node, 0);
+ COMPLETE_CHECK_OP_0 (node);
+ /* CAN_COMPLETE_NORMALLY (node) = 0; */
+ return patch_throw_statement (node, wfl_op1);
+
+ case SYNCHRONIZED_EXPR:
+ wfl_op1 = TREE_OPERAND (node, 0);
+ return patch_synchronized_statement (node, wfl_op1);
+
+ case TRY_EXPR:
+ return patch_try_statement (node);
+
+ case TRY_FINALLY_EXPR:
+ COMPLETE_CHECK_OP_0 (node);
+ COMPLETE_CHECK_OP_1 (node);
+ CAN_COMPLETE_NORMALLY (node)
+ = (CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 0))
+ && CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 1)));
+ TREE_TYPE (node) = TREE_TYPE (TREE_OPERAND (node, 0));
+ return node;
+
+ case CLEANUP_POINT_EXPR:
+ COMPLETE_CHECK_OP_0 (node);
+ TREE_TYPE (node) = void_type_node;
+ CAN_COMPLETE_NORMALLY (node) =
+ CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 0));
+ return node;
+
+ case WITH_CLEANUP_EXPR:
+ COMPLETE_CHECK_OP_0 (node);
+ COMPLETE_CHECK_OP_2 (node);
+ CAN_COMPLETE_NORMALLY (node) =
+ CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 0));
+ TREE_TYPE (node) = void_type_node;
+ return node;
+
case LABELED_BLOCK_EXPR:
PUSH_LABELED_BLOCK (node);
if (LABELED_BLOCK_BODY (node))
COMPLETE_CHECK_OP_1 (node);
TREE_TYPE (node) = void_type_node;
POP_LABELED_BLOCK ();
+ if (CAN_COMPLETE_NORMALLY (LABELED_BLOCK_BODY (node)))
+ CAN_COMPLETE_NORMALLY (node) = 1;
return node;
case EXIT_BLOCK_EXPR:
@@ -5959,21 +7759,92 @@ java_complete_tree (node)
the EXIT_BLOCK_EXPR which doesn't exist it Java */
return patch_bc_statement (node);
+ case CASE_EXPR:
+ cn = java_complete_tree (TREE_OPERAND (node, 0));
+ if (cn == error_mark_node)
+ return cn;
+
+ /* First, the case expression must be constant */
+ cn = fold (cn);
+
+ if (!TREE_CONSTANT (cn))
+ {
+ EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
+ parse_error_context (node, "Constant expression required");
+ return error_mark_node;
+ }
+
+ nn = ctxp->current_loop;
+
+ /* It must be assignable to the type of the switch expression. */
+ if (!try_builtin_assignconv (NULL_TREE,
+ TREE_TYPE (TREE_OPERAND (nn, 0)), cn))
+ {
+ EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
+ parse_error_context
+ (wfl_operator,
+ "Incompatible type for case. Can't convert `%s' to `int'",
+ lang_printable_name (TREE_TYPE (cn), 0));
+ return error_mark_node;
+ }
+
+ cn = fold (convert (int_type_node, cn));
+
+ /* Multiple instance of a case label bearing the same
+ value is checked during code generation. The case
+ expression is allright so far. */
+ TREE_OPERAND (node, 0) = cn;
+ TREE_TYPE (node) = void_type_node;
+ CAN_COMPLETE_NORMALLY (node) = 1;
+ TREE_SIDE_EFFECTS (node) = 1;
+ break;
+
+ case DEFAULT_EXPR:
+ nn = ctxp->current_loop;
+ /* Only one default label is allowed per switch statement */
+ if (SWITCH_HAS_DEFAULT (nn))
+ {
+ EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
+ parse_error_context (wfl_operator,
+ "Duplicate case label: `default'");
+ return error_mark_node;
+ }
+ else
+ SWITCH_HAS_DEFAULT (nn) = 1;
+ TREE_TYPE (node) = void_type_node;
+ TREE_SIDE_EFFECTS (node) = 1;
+ CAN_COMPLETE_NORMALLY (node) = 1;
+ break;
+
+ case SWITCH_EXPR:
case LOOP_EXPR:
PUSH_LOOP (node);
/* Check whether the loop was enclosed in a labeled
statement. If not, create one, insert the loop in it and
return the node */
nn = patch_loop_statement (node);
+
/* Anyways, walk the body of the loop */
- TREE_OPERAND (node, 0) = java_complete_tree (TREE_OPERAND (node, 0));
+ if (TREE_CODE (node) == LOOP_EXPR)
+ TREE_OPERAND (node, 0) = java_complete_tree (TREE_OPERAND (node, 0));
+ /* Switch statement: walk the switch expression and the cases */
+ else
+ node = patch_switch_statement (node);
+
if (TREE_OPERAND (node, 0) == error_mark_node)
- return error_mark_node;
- TREE_TYPE (nn) = TREE_TYPE (node) = void_type_node;
- /* If we returned something different, that's because we
- inserted a label. Pop the label too. */
- if (nn != node)
- POP_LABELED_BLOCK ();
+ nn = error_mark_node;
+ else
+ {
+ TREE_TYPE (nn) = TREE_TYPE (node) = void_type_node;
+ /* If we returned something different, that's because we
+ inserted a label. Pop the label too. */
+ if (nn != node)
+ {
+ if (CAN_COMPLETE_NORMALLY (node))
+ CAN_COMPLETE_NORMALLY (nn) = 1;
+ POP_LABELED_BLOCK ();
+ }
+ }
POP_LOOP ();
return nn;
@@ -5996,27 +7867,71 @@ java_complete_tree (node)
return patch_if_else_statement (node);
break;
+ case CONDITIONAL_EXPR:
+ /* Condition */
+ wfl_op1 = TREE_OPERAND (node, 0);
+ COMPLETE_CHECK_OP_0 (node);
+ wfl_op2 = TREE_OPERAND (node, 1);
+ COMPLETE_CHECK_OP_1 (node);
+ wfl_op3 = TREE_OPERAND (node, 2);
+ COMPLETE_CHECK_OP_2 (node);
+ return patch_conditional_expr (node, wfl_op1, wfl_op2);
+
/* 3- Expression section */
case COMPOUND_EXPR:
- TREE_OPERAND (node, 0) = java_complete_tree (TREE_OPERAND (node, 0));
- TREE_OPERAND (node, 1) = java_complete_tree (TREE_OPERAND (node, 1));
- if (TREE_OPERAND (node, 1) == error_mark_node)
- return error_mark_node;
+ wfl_op2 = TREE_OPERAND (node, 1);
+ TREE_OPERAND (node, 0) = nn =
+ java_complete_tree (TREE_OPERAND (node, 0));
+ if (wfl_op2 == empty_stmt_node)
+ CAN_COMPLETE_NORMALLY (node) = CAN_COMPLETE_NORMALLY (nn);
+ else
+ {
+ if (! CAN_COMPLETE_NORMALLY (nn) && TREE_CODE (nn) != ERROR_MARK)
+ {
+ /* An unreachable condition in a do-while statement
+ is *not* (technically) an unreachable statement. */
+ nn = wfl_op2;
+ if (TREE_CODE (nn) == EXPR_WITH_FILE_LOCATION)
+ nn = EXPR_WFL_NODE (nn);
+ if (TREE_CODE (nn) != EXIT_EXPR)
+ {
+ SET_WFL_OPERATOR (wfl_operator, node, wfl_op2);
+ parse_error_context (wfl_operator, "Unreachable statement");
+ }
+ }
+ TREE_OPERAND (node, 1) = java_complete_tree (TREE_OPERAND (node, 1));
+ if (TREE_OPERAND (node, 1) == error_mark_node)
+ return error_mark_node;
+ CAN_COMPLETE_NORMALLY (node)
+ = CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 1));
+ }
TREE_TYPE (node) = TREE_TYPE (TREE_OPERAND (node, 1));
break;
case RETURN_EXPR:
+ /* CAN_COMPLETE_NORMALLY (node) = 0; */
return patch_return (node);
case EXPR_WITH_FILE_LOCATION:
if (!EXPR_WFL_NODE (node) /* Or a PRIMARY flag ? */
|| TREE_CODE (EXPR_WFL_NODE (node)) == IDENTIFIER_NODE)
- return resolve_expression_name (node);
+ {
+ node = resolve_expression_name (node, NULL);
+ if (node == error_mark_node)
+ return node;
+ CAN_COMPLETE_NORMALLY (node) = 1;
+ }
else
{
- EXPR_WFL_NODE (node) = java_complete_tree (EXPR_WFL_NODE (node));
- TREE_SIDE_EFFECTS (node) = 1;
- if (EXPR_WFL_NODE (node) == error_mark_node)
+ tree body;
+ int save_lineno = lineno;
+ lineno = EXPR_WFL_LINENO (node);
+ body = java_complete_tree (EXPR_WFL_NODE (node));
+ lineno = save_lineno;
+ EXPR_WFL_NODE (node) = body;
+ TREE_SIDE_EFFECTS (node) = TREE_SIDE_EFFECTS (body);
+ CAN_COMPLETE_NORMALLY (node) = CAN_COMPLETE_NORMALLY (body);
+ if (body == error_mark_node)
{
/* Its important for the evaluation of assignment that
this mark on the TREE_TYPE is propagated. */
@@ -6025,10 +7940,11 @@ java_complete_tree (node)
}
else
TREE_TYPE (node) = TREE_TYPE (EXPR_WFL_NODE (node));
+
}
break;
- case JAVA_NEW_ARRAY_EXPR:
+ case NEW_ARRAY_EXPR:
/* Patch all the dimensions */
flag = 0;
for (cn = TREE_OPERAND (node, 1); cn; cn = TREE_CHAIN (cn))
@@ -6042,7 +7958,7 @@ java_complete_tree (node)
}
else
{
- TREE_VALUE (cn) = save_expr (dim);
+ TREE_VALUE (cn) = dim;
/* Setup the location of the current dimension, for
later error report. */
TREE_PURPOSE (cn) =
@@ -6052,57 +7968,96 @@ java_complete_tree (node)
}
/* They complete the array creation expression, if no errors
were found. */
- return (flag ? error_mark_node : patch_newarray (node));
+ CAN_COMPLETE_NORMALLY (node) = 1;
+ return (flag ? error_mark_node
+ : force_evaluation_order (patch_newarray (node)));
- case JAVA_NEW_CLASS_EXPR:
+ case NEW_CLASS_EXPR:
case CALL_EXPR:
- /* Complete function's argument first */
+ /* Complete function's argument(s) first */
if (complete_function_arguments (node))
return error_mark_node;
else
- return patch_method_invocation_stmt (node, NULL_TREE, NULL_TREE, NULL);
+ {
+ tree decl, wfl = TREE_OPERAND (node, 0);
+ int in_this = CALL_THIS_CONSTRUCTOR_P (node);
+
+ node = patch_method_invocation (node, NULL_TREE,
+ NULL_TREE, 0, &decl);
+ if (node == error_mark_node)
+ return error_mark_node;
+
+ check_thrown_exceptions (EXPR_WFL_LINECOL (node), decl);
+ /* If we call this(...), register signature and positions */
+ if (in_this)
+ DECL_CONSTRUCTOR_CALLS (current_function_decl) =
+ tree_cons (wfl, decl,
+ DECL_CONSTRUCTOR_CALLS (current_function_decl));
+ CAN_COMPLETE_NORMALLY (node) = 1;
+ return force_evaluation_order (node);
+ }
case MODIFY_EXPR:
/* Save potential wfls */
wfl_op1 = TREE_OPERAND (node, 0);
wfl_op2 = TREE_OPERAND (node, 1);
- TREE_OPERAND (node, 0) = java_complete_tree (wfl_op1);
+ TREE_OPERAND (node, 0) = java_complete_lhs (wfl_op1);
if (TREE_OPERAND (node, 0) == error_mark_node)
return error_mark_node;
if (COMPOUND_ASSIGN_P (wfl_op2))
{
- tree lvalue;
- tree other =
- java_complete_tree (TREE_OPERAND (wfl_op2, 0));
+ tree lvalue = java_stabilize_reference (TREE_OPERAND (node, 0));
/* Hand stablize the lhs on both places */
- lvalue = stabilize_reference (other);
TREE_OPERAND (node, 0) = lvalue;
TREE_OPERAND (TREE_OPERAND (node, 1), 0) = lvalue;
- }
- /* There are cases where the type of RHS is fixed. In those
- cases, if the evaluation of the RHS fails, we further the
- evaluation of the assignment to detect more errors. */
- nn = java_complete_tree (TREE_OPERAND (node, 1));
- if (nn == error_mark_node)
- {
- /* It's hopeless, but we can further things on to discover
- an error during the assignment. In any cases, the
- assignment operation fails. */
- if (TREE_CODE (TREE_OPERAND (node, 1)) != EXPR_WITH_FILE_LOCATION
- && TREE_TYPE (TREE_OPERAND (node, 1)) != error_mark_node)
- patch_assignment (node, wfl_op1, wfl_op2);
+ /* Now complete the RHS. We write it back later on. */
+ nn = java_complete_tree (TREE_OPERAND (node, 1));
- /* Now, we still mark the lhs as initialized */
- if (DECL_P (TREE_OPERAND (node, 0)))
- INITIALIZED_P (TREE_OPERAND (node, 0)) = 1;
+ if ((cn = patch_string (nn)))
+ nn = cn;
- return error_mark_node;
+ /* The last part of the rewrite for E1 op= E2 is to have
+ E1 = (T)(E1 op E2), with T being the type of E1. */
+ nn = java_complete_tree (build_cast (EXPR_WFL_LINECOL (wfl_op2),
+ TREE_TYPE (lvalue), nn));
}
+
+ /* If we're about to patch a NEW_ARRAY_INIT, we call a special
+ function to complete this RHS */
+ else if (TREE_CODE (wfl_op2) == NEW_ARRAY_INIT)
+ nn = patch_new_array_init (TREE_TYPE (TREE_OPERAND (node, 0)),
+ TREE_OPERAND (node, 1));
+ /* Otherwise we simply complete the RHS */
+ else
+ nn = java_complete_tree (TREE_OPERAND (node, 1));
+
+ if (nn == error_mark_node)
+ return error_mark_node;
+
+ /* Write back the RHS as we evaluated it. */
TREE_OPERAND (node, 1) = nn;
- return patch_assignment (node, wfl_op1, wfl_op2);
+
+ /* In case we're handling = with a String as a RHS, we need to
+ produce a String out of the RHS (it might still be a
+ STRING_CST or a StringBuffer at this stage */
+ if ((nn = patch_string (TREE_OPERAND (node, 1))))
+ TREE_OPERAND (node, 1) = nn;
+ node = patch_assignment (node, wfl_op1, wfl_op2);
+ CAN_COMPLETE_NORMALLY (node) = 1;
+
+ /* Before returning the node, in the context of a static field
+ assignment in <clinit>, we may want to carray further
+ optimizations. (VAR_DECL means it's a static field. See
+ add_field. */
+ if (DECL_NAME (current_function_decl) == clinit_identifier_node
+ && MODIFY_EXPR_FROM_INITIALIZATION_P (node)
+ && TREE_CODE (TREE_OPERAND (node, 0)) == VAR_DECL)
+ node = patch_initialized_static_field (node);
+
+ return node;
case MULT_EXPR:
case PLUS_EXPR:
@@ -6127,15 +8082,35 @@ java_complete_tree (node)
knows how to handle those cases. */
wfl_op1 = TREE_OPERAND (node, 0);
wfl_op2 = TREE_OPERAND (node, 1);
- TREE_OPERAND (node, 0) = java_complete_tree (wfl_op1);
- if (TREE_OPERAND (node, 0) == error_mark_node)
- return error_mark_node;
- TREE_OPERAND (node, 1) = java_complete_tree (wfl_op2);
- if (TREE_OPERAND (node, 1) == error_mark_node)
- return error_mark_node;
- return patch_binop (node, wfl_op1, wfl_op2);
- case JAVA_UNARY_PLUS_EXPR:
+ CAN_COMPLETE_NORMALLY (node) = 1;
+ /* Don't complete string nodes if dealing with the PLUS operand. */
+ if (TREE_CODE (node) != PLUS_EXPR || !JSTRING_P (wfl_op1))
+ {
+ nn = java_complete_tree (wfl_op1);
+ if (nn == error_mark_node)
+ return error_mark_node;
+ if ((cn = patch_string (nn)))
+ nn = cn;
+ TREE_OPERAND (node, 0) = nn;
+ }
+ if (TREE_CODE (node) != PLUS_EXPR || !JSTRING_P (wfl_op2))
+ {
+ nn = java_complete_tree (wfl_op2);
+ if (nn == error_mark_node)
+ return error_mark_node;
+ if ((cn = patch_string (nn)))
+ nn = cn;
+ TREE_OPERAND (node, 1) = nn;
+ }
+ return force_evaluation_order (patch_binop (node, wfl_op1, wfl_op2));
+
+ case INSTANCEOF_EXPR:
+ wfl_op1 = TREE_OPERAND (node, 0);
+ COMPLETE_CHECK_OP_0 (node);
+ return patch_binop (node, wfl_op1, TREE_OPERAND (node, 1));
+
+ case UNARY_PLUS_EXPR:
case NEGATE_EXPR:
case TRUTH_NOT_EXPR:
case BIT_NOT_EXPR:
@@ -6147,10 +8122,13 @@ java_complete_tree (node)
/* There are cases were wfl_op1 is a WFL. patch_unaryop knows
how to handle those cases. */
wfl_op1 = TREE_OPERAND (node, 0);
+ CAN_COMPLETE_NORMALLY (node) = 1;
TREE_OPERAND (node, 0) = java_complete_tree (wfl_op1);
if (TREE_OPERAND (node, 0) == error_mark_node)
return error_mark_node;
- return patch_unaryop (node, wfl_op1);
+ node = patch_unaryop (node, wfl_op1);
+ CAN_COMPLETE_NORMALLY (node) = 1;
+ break;
case ARRAY_REF:
/* There are cases were wfl_op1 is a WFL. patch_array_ref knows
@@ -6159,14 +8137,45 @@ java_complete_tree (node)
TREE_OPERAND (node, 0) = java_complete_tree (wfl_op1);
if (TREE_OPERAND (node, 0) == error_mark_node)
return error_mark_node;
+ if (!flag_emit_class_files)
+ TREE_OPERAND (node, 0) = save_expr (TREE_OPERAND (node, 0));
/* The same applies to wfl_op2 */
wfl_op2 = TREE_OPERAND (node, 1);
TREE_OPERAND (node, 1) = java_complete_tree (wfl_op2);
if (TREE_OPERAND (node, 1) == error_mark_node)
return error_mark_node;
- return patch_array_ref (node, wfl_op1, wfl_op2);
+ if (!flag_emit_class_files)
+ TREE_OPERAND (node, 1) = save_expr (TREE_OPERAND (node, 1));
+ return patch_array_ref (node);
+
+ case RECORD_TYPE:
+ return node;;
+
+ case COMPONENT_REF:
+ /* The first step in the re-write of qualified name handling. FIXME.
+ So far, this is only to support PRIMTYPE.class -> PRIMCLASS.TYPE. */
+ TREE_OPERAND (node, 0) = java_complete_tree (TREE_OPERAND (node, 0));
+ if (TREE_CODE (TREE_OPERAND (node, 0)) == RECORD_TYPE)
+ {
+ tree name = TREE_OPERAND (node, 1);
+ tree field = lookup_field_wrapper (TREE_OPERAND (node, 0), name);
+ if (field == NULL_TREE)
+ {
+ error ("missing static field `%s'", IDENTIFIER_POINTER (name));
+ return error_mark_node;
+ }
+ if (! FIELD_STATIC (field))
+ {
+ error ("not a static field `%s'", IDENTIFIER_POINTER (name));
+ return error_mark_node;
+ }
+ return field;
+ }
+ else
+ fatal ("unimplemented java_complete_tree for COMPONENT_REF");
+ break;
- case JAVA_THIS_EXPR:
+ case THIS_EXPR:
/* Can't use THIS in a static environment */
if (!current_this)
{
@@ -6176,18 +8185,24 @@ java_complete_tree (node)
TREE_TYPE (node) = error_mark_node;
return error_mark_node;
}
+ if (ctxp->explicit_constructor_p)
+ {
+ EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
+ parse_error_context
+ (wfl_operator, "Can't reference `this' or `super' before the "
+ "superclass constructor has been called");
+ TREE_TYPE (node) = error_mark_node;
+ return error_mark_node;
+ }
return current_this;
- case STRING_CST:
- /* Build the internal string representation */
- push_obstacks (&permanent_obstack, &permanent_obstack);
- node = get_identifier (TREE_STRING_POINTER (node));
- location = alloc_name_constant (CONSTANT_String, node);
- node = build_ref_from_constant_pool (location);
- TREE_TYPE (node) = promote_type (string_type_node);
- return node;
-
default:
+ CAN_COMPLETE_NORMALLY (node) = 1;
+ /* Ok: may be we have a STRING_CST or a crafted `StringBuffer'
+ and it's time to turn it into the appropriate String object
+ */
+ if ((node = patch_string (node)))
+ return node;
fatal ("No case for tree code `%s' - java_complete_tree\n",
tree_code_name [TREE_CODE (node)]);
}
@@ -6204,25 +8219,27 @@ complete_function_arguments (node)
int flag = 0;
tree cn;
+ ctxp->explicit_constructor_p += (CALL_THIS_CONSTRUCTOR_P (node) ? 1 : 0);
for (cn = TREE_OPERAND (node, 1); cn; cn = TREE_CHAIN (cn))
{
- tree wfl = TREE_VALUE (cn), parm;
+ tree wfl = TREE_VALUE (cn), parm, temp;
parm = java_complete_tree (wfl);
if (parm == error_mark_node)
{
flag = 1;
continue;
}
- if (TREE_CODE (TREE_TYPE (parm)) == RECORD_TYPE)
- TREE_VALUE (cn) = convert (promote_type (TREE_TYPE (parm)), parm);
- else
- TREE_VALUE (cn) = save_expr (parm);
- if (not_initialized_as_it_should_p (parm))
- {
- ERROR_VARIABLE_NOT_INITIALIZED (wfl, EXPR_WFL_NODE (wfl));
- INITIALIZED_P (parm) = 1;
- }
+ /* If have a string literal that we haven't transformed yet or a
+ crafted string buffer, as a result of use of the the String
+ `+' operator. Build `parm.toString()' and expand it. */
+ if ((temp = patch_string (parm)))
+ parm = temp;
+ /* Inline PRIMTYPE.TYPE read access */
+ parm = maybe_build_primttype_type_ref (parm, wfl);
+
+ TREE_VALUE (cn) = parm;
}
+ ctxp->explicit_constructor_p -= (CALL_THIS_CONSTRUCTOR_P (node) ? 1 : 0);
return flag;
}
@@ -6250,28 +8267,39 @@ build_expr_block (body, decls)
{
tree node = make_node (BLOCK);
BLOCK_EXPR_DECLS (node) = decls;
- BLOCK_EXPR_BODY (body);
+ BLOCK_EXPR_BODY (node) = body;
if (body)
TREE_TYPE (node) = TREE_TYPE (body);
TREE_SIDE_EFFECTS (node) = 1;
return node;
}
-/* Create a new function block and link its supercontext to the
- previous block. The current function DECL is used as supercontext
- when enter_block is called for the first time for a given
- function. The current function body (DECL_FUNCTION_BODY) is set to
- the newly created block. */
-
-static block_level = 0;
+/* Create a new function block and link it approriately to current
+ function block chain */
static tree
enter_block ()
{
- tree b = build_expr_block (NULL_TREE, NULL_TREE);
+ return (enter_a_block (build_expr_block (NULL_TREE, NULL_TREE)));
+}
+
+/* Link block B supercontext to the previous block. The current
+ function DECL is used as supercontext when enter_a_block is called
+ for the first time for a given function. The current function body
+ (DECL_FUNCTION_BODY) is set to be block B. */
+
+static tree
+enter_a_block (b)
+ tree b;
+{
tree fndecl = current_function_decl;
- if (!DECL_FUNCTION_BODY (fndecl))
+ if (!fndecl) {
+ BLOCK_SUPERCONTEXT (b) = current_static_block;
+ current_static_block = b;
+ }
+
+ else if (!DECL_FUNCTION_BODY (fndecl))
{
BLOCK_SUPERCONTEXT (b) = fndecl;
DECL_FUNCTION_BODY (fndecl) = b;
@@ -6291,11 +8319,20 @@ enter_block ()
static tree
exit_block ()
{
- tree b = DECL_FUNCTION_BODY (current_function_decl);
-
- if (BLOCK_SUPERCONTEXT (b) != current_function_decl)
- DECL_FUNCTION_BODY (current_function_decl) = BLOCK_SUPERCONTEXT (b);
+ tree b;
+ if (current_function_decl)
+ {
+ b = DECL_FUNCTION_BODY (current_function_decl);
+ if (BLOCK_SUPERCONTEXT (b) != current_function_decl)
+ DECL_FUNCTION_BODY (current_function_decl) = BLOCK_SUPERCONTEXT (b);
+ }
+ else
+ {
+ b = current_static_block;
+ if (BLOCK_SUPERCONTEXT (b))
+ current_static_block = BLOCK_SUPERCONTEXT (b);
+ }
return b;
}
@@ -6307,7 +8344,7 @@ static tree
lookup_name_in_blocks (name)
tree name;
{
- tree b = DECL_FUNCTION_BODY (current_function_decl);
+ tree b = GET_CURRENT_BLOCK (current_function_decl);
while (b != current_function_decl)
{
@@ -6329,7 +8366,7 @@ lookup_name_in_blocks (name)
static void
maybe_absorb_scoping_blocks ()
{
- while (BLOCK_EXPR_ORIGIN (DECL_FUNCTION_BODY (current_function_decl)))
+ while (BLOCK_EXPR_ORIGIN (GET_CURRENT_BLOCK (current_function_decl)))
{
tree b = exit_block ();
java_method_add_stmt (current_function_decl, b);
@@ -6342,7 +8379,39 @@ maybe_absorb_scoping_blocks ()
are building incomplete tree nodes and the patch_* functions that
are completing them. */
-/* Build an incomplete CALL_EXPR node. Encapsulate it within a WFL */
+/* Build a super() constructor invocation. Returns empty_stmt_node if
+ we're currently dealing with the class java.lang.Object. */
+
+static tree
+build_super_invocation ()
+{
+ if (current_class == object_type_node)
+ return empty_stmt_node;
+ else
+ {
+ tree super_wfl = build_wfl_node (super_identifier_node);
+ return build_method_invocation (super_wfl, NULL_TREE);
+ }
+}
+
+/* Build a SUPER/THIS qualified method invocation. */
+
+static tree
+build_this_super_qualified_invocation (use_this, name, args, lloc, rloc)
+ int use_this;
+ tree name, args;
+ int lloc, rloc;
+
+{
+ tree invok;
+ tree wfl =
+ build_wfl_node (use_this ? this_identifier_node : super_identifier_node);
+ EXPR_WFL_LINECOL (wfl) = lloc;
+ invok = build_method_invocation (name, args);
+ return make_qualified_primary (wfl, invok, rloc);
+}
+
+/* Build an incomplete CALL_EXPR node. */
static tree
build_method_invocation (name, args)
@@ -6351,7 +8420,18 @@ build_method_invocation (name, args)
{
tree call = build (CALL_EXPR, NULL_TREE, name, args, NULL_TREE);
TREE_SIDE_EFFECTS (call) = 1;
- /* Check on cases where NAME isn't a WFL. FIXME */
+ EXPR_WFL_LINECOL (call) = EXPR_WFL_LINECOL (name);
+ return call;
+}
+
+/* Build an incomplete new xxx(...) node. */
+
+static tree
+build_new_invocation (name, args)
+ tree name, args;
+{
+ tree call = build (NEW_CLASS_EXPR, NULL_TREE, name, args, NULL_TREE);
+ TREE_SIDE_EFFECTS (call) = 1;
EXPR_WFL_LINECOL (call) = EXPR_WFL_LINECOL (name);
return call;
}
@@ -6380,7 +8460,7 @@ build_assignment (op, op_location, lhs, rhs)
/* Print an INTEGER_CST node in a static buffer, and return the buffer. */
-static char *
+char *
print_int_node (node)
tree node;
{
@@ -6405,6 +8485,48 @@ print_int_node (node)
return buffer;
}
+/* Return 1 if you an assignment of a FINAL is attempted */
+
+static int
+check_final_assignment (lvalue, wfl)
+ tree lvalue, wfl;
+{
+ if (JDECL_P (lvalue) && FIELD_FINAL (lvalue) &&
+ DECL_NAME (current_function_decl) != clinit_identifier_node)
+ {
+ parse_error_context
+ (wfl, "Can't assign a value to the final variable `%s'",
+ IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl)));
+ return 1;
+ }
+ return 0;
+}
+
+/* Inline references to java.lang.PRIMTYPE.TYPE when accessed in
+ read. This is needed to avoid circularities in the implementation
+ of these fields in libjava. */
+
+static tree
+maybe_build_primttype_type_ref (rhs, wfl)
+ tree rhs, wfl;
+{
+ tree to_return = NULL_TREE;
+ tree rhs_type = TREE_TYPE (rhs);
+ if (TREE_CODE (rhs) == COMPOUND_EXPR)
+ {
+ tree n = TREE_OPERAND (rhs, 1);
+ if (TREE_CODE (n) == VAR_DECL
+ && DECL_NAME (n) == TYPE_identifier_node
+ && rhs_type == class_ptr_type)
+ {
+ char *self_name = IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl));
+ if (!strncmp (self_name, "java.lang.", 10))
+ to_return = build_primtype_type_ref (self_name);
+ }
+ }
+ return (to_return ? to_return : rhs );
+}
+
/* 15.25 Assignment operators. */
static tree
@@ -6414,27 +8536,20 @@ patch_assignment (node, wfl_op1, wfl_op2)
tree wfl_op2;
{
tree rhs = TREE_OPERAND (node, 1);
- tree lvalue = TREE_OPERAND (node, 0);
+ tree lvalue = TREE_OPERAND (node, 0), llvalue;
tree lhs_type, rhs_type, new_rhs = NULL_TREE;
- int all_primitive;
int error_found = 0;
int lvalue_from_array = 0;
/* Can't assign to a final. */
- if (DECL_P (lvalue) && FIELD_FINAL (lvalue))
- {
- parse_error_context
- (wfl_op1, "Can't assign a value to the final variable `%s'",
- IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl_op1)));
- error_found = 1;
- }
+ if (check_final_assignment (lvalue, wfl_op1))
+ error_found = 1;
EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
/* Lhs can be a named variable */
- if (DECL_P (lvalue))
+ if (JDECL_P (lvalue))
{
- INITIALIZED_P (lvalue) = 1;
lhs_type = TREE_TYPE (lvalue);
}
/* Or Lhs can be a array acccess. Should that be lvalue ? FIXME +
@@ -6450,64 +8565,30 @@ patch_assignment (node, wfl_op1, wfl_op2)
/* Or a function return slot */
else if (TREE_CODE (lvalue) == RESULT_DECL)
lhs_type = TREE_TYPE (lvalue);
- /* Otherwise, this is an error */
- else
+ /* Otherwise, we might want to try to write into an optimized static
+ final, this is an of a different nature, reported further on. */
+ else if (TREE_CODE (wfl_op1) == EXPR_WITH_FILE_LOCATION
+ && resolve_expression_name (wfl_op1, &llvalue)
+ && check_final_assignment (llvalue, wfl_op1))
+ {
+ error_found = 1;
+ /* What we should do instead is resetting the all the flags
+ previously set, exchange lvalue for llvalue and continue. */
+ return error_mark_node;
+ }
+ else
{
parse_error_context (wfl_op1, "Invalid left hand side of assignment");
error_found = 1;
}
rhs_type = TREE_TYPE (rhs);
+ /* 5.1 Try the assignment conversion for builtin type. */
+ new_rhs = try_builtin_assignconv (wfl_op1, lhs_type, rhs);
- /* 5.2 Begin Assignment conversion */
-
- /* 5.1.1 Try Identity Conversion */
- if (lhs_type == rhs_type)
- new_rhs = rhs;
-
- /* 5.1.2 Try Widening Primitive Conversion */
- all_primitive = JPRIMITIVE_TYPE_P (lhs_type) && JPRIMITIVE_TYPE_P (rhs_type);
- if (all_primitive && JINTEGRAL_TYPE_P (rhs_type)
- && ((TYPE_PRECISION (rhs_type) < TYPE_PRECISION (lhs_type))
- || (JFLOAT_TYPE_P (lhs_type) &&
- TYPE_PRECISION (rhs_type) == TYPE_PRECISION (lhs_type))))
- new_rhs = convert (lhs_type, rhs);
- else if (all_primitive && JFLOAT_TYPE_P (rhs_type)
- && (TYPE_PRECISION (rhs_type) < TYPE_PRECISION (lhs_type)))
- new_rhs = convert (lhs_type, rhs);
-
- /* Try a narrowing primitive conversion:
- - expression is a constant expression of type int AND
- - variable is byte, short or char AND
- - The value of the expression is representable in the type of the
- variable */
- else if (rhs_type == int_type_node && TREE_CONSTANT (rhs)
- && (lhs_type == byte_type_node || lhs_type == char_type_node
- || lhs_type == short_type_node))
- {
- if (int_fits_type_p (rhs, lhs_type))
- new_rhs = convert (lhs_type, rhs);
- else
- parse_warning_context
- (wfl_op1, "Constant expression `%s' to wide for narrowing "
- "primitive conversion to `%s'",
- print_int_node (rhs), lang_printable_name (lhs_type));
- /* Reported a warning that will turn into an error further
- down, so we don't return */
- }
-
- /* 5.2 Try a reference conversion */
- else if (!JPRIMITIVE_TYPE_P (rhs_type) && JREFERENCE_TYPE_P (lhs_type))
- {
- /* `null' may be assigned to any reference type */
- if (rhs == null_pointer_node)
- new_rhs = null_pointer_node;
- /* Try the reference assignment conversion */
- else if (valid_ref_assignconv_cast_p (rhs_type, lhs_type, 0))
- new_rhs = rhs;
- if (new_rhs)
- lhs_type = promote_type (rhs_type);
- }
+ /* 5.2 If it failed, try a reference conversion */
+ if (!new_rhs && (new_rhs = try_reference_assignconv (lhs_type, rhs)))
+ lhs_type = promote_type (rhs_type);
/* 15.25.2 If we have a compound assignment, convert RHS into the
type of the LHS */
@@ -6517,8 +8598,8 @@ patch_assignment (node, wfl_op1, wfl_op2)
/* Explicit cast required. This is an error */
if (!new_rhs)
{
- char *t1 = strdup ((char *)lang_printable_name (TREE_TYPE (rhs)));
- char *t2 = strdup ((char *)lang_printable_name (lhs_type));
+ char *t1 = strdup (lang_printable_name (TREE_TYPE (rhs), 0));
+ char *t2 = strdup (lang_printable_name (lhs_type, 0));
tree wfl;
char operation [32]; /* Max size known */
@@ -6546,7 +8627,7 @@ patch_assignment (node, wfl_op1, wfl_op2)
}
parse_error_context
- (wfl, (!can_cast_to_p (rhs_type, lhs_type) ?
+ (wfl, (!valid_cast_to_p (rhs_type, lhs_type) ?
"Incompatible type for %s. Can't convert `%s' to `%s'" :
"Incompatible type for %s. Explicit cast "
"needed to convert `%s' to `%s'"), operation, t1, t2);
@@ -6554,13 +8635,9 @@ patch_assignment (node, wfl_op1, wfl_op2)
error_found = 1;
}
- /* Before reporting type incompatibility errors, check that the rhs
- is initialized, if a variable */
- if (not_initialized_as_it_should_p (rhs))
- {
- ERROR_VARIABLE_NOT_INITIALIZED (wfl_op2, DECL_NAME (rhs));
- INITIALIZED_P (rhs) = 1;
- }
+ /* Inline read access to java.lang.PRIMTYPE.TYPE */
+ if (new_rhs)
+ new_rhs = maybe_build_primttype_type_ref (new_rhs, wfl_op2);
if (error_found)
return error_mark_node;
@@ -6569,32 +8646,155 @@ patch_assignment (node, wfl_op1, wfl_op2)
assignment into an array element, return it here. */
if (TREE_CODE (node) == COMPOUND_EXPR)
return node;
-
+
TREE_OPERAND (node, 0) = lvalue;
TREE_OPERAND (node, 1) = new_rhs;
TREE_TYPE (node) = lhs_type;
return node;
}
-/* Check that SOURCE can be converted into DEST, at least with a
- cast. If the convertion can't occur at all, return 0 otherwise
- 1. This function is used to produce accurate error messages on the
- reasons why an assignment failed. */
+/* Optimize static (final) field initialized upon declaration.
+ - If the field is static final and is assigned to a primitive
+ constant type, then set its DECL_INITIAL to the value.
+ - More to come. */
+
+static tree
+patch_initialized_static_field (node)
+ tree node;
+{
+ tree field = TREE_OPERAND (node, 0);
+ tree value = TREE_OPERAND (node, 1);
+
+ if (DECL_INITIAL (field) != NULL_TREE)
+ {
+ tree type = TREE_TYPE (value);
+ if (FIELD_FINAL (field) && TREE_CONSTANT (value)
+ && (JPRIMITIVE_TYPE_P (type)
+ || (flag_emit_class_files
+ && TREE_CODE (type) == POINTER_TYPE
+ && TREE_TYPE (type) == string_type_node)))
+ {
+ DECL_INITIAL (field) = value;
+ return empty_stmt_node;
+ }
+ DECL_INITIAL (field) = NULL_TREE;
+ }
+ return node;
+}
+
+/* Check that type SOURCE can be cast into type DEST. If the cast
+ can't occur at all, return 0 otherwise 1. This function is used to
+ produce accurate error messages on the reasons why an assignment
+ failed. */
+
+static tree
+try_reference_assignconv (lhs_type, rhs)
+ tree lhs_type, rhs;
+{
+ tree new_rhs = NULL_TREE;
+ tree rhs_type = TREE_TYPE (rhs);
+
+ if (!JPRIMITIVE_TYPE_P (rhs_type) && JREFERENCE_TYPE_P (lhs_type))
+ {
+ /* `null' may be assigned to any reference type */
+ if (rhs == null_pointer_node)
+ new_rhs = null_pointer_node;
+ /* Try the reference assignment conversion */
+ else if (valid_ref_assignconv_cast_p (rhs_type, lhs_type, 0))
+ new_rhs = rhs;
+ /* This is a magic assignment that we process differently */
+ else if (rhs == soft_exceptioninfo_call_node)
+ new_rhs = rhs;
+ }
+ return new_rhs;
+}
+
+/* Check that RHS can be converted into LHS_TYPE by the assignment
+ conversion (5.2), for the cases of RHS being a builtin type. Return
+ NULL_TREE if the conversion fails or if because RHS isn't of a
+ builtin type. Return a converted RHS if the conversion is possible. */
+
+static tree
+try_builtin_assignconv (wfl_op1, lhs_type, rhs)
+ tree wfl_op1, lhs_type, rhs;
+{
+ tree new_rhs = NULL_TREE;
+ tree rhs_type = TREE_TYPE (rhs);
+
+ /* Zero accepted everywhere */
+ if (TREE_CODE (rhs) == INTEGER_CST
+ && TREE_INT_CST_HIGH (rhs) == 0 && TREE_INT_CST_LOW (rhs) == 0
+ && JPRIMITIVE_TYPE_P (rhs_type))
+ new_rhs = convert (lhs_type, rhs);
+
+ /* 5.1.1 Try Identity Conversion,
+ 5.1.2 Try Widening Primitive Conversion */
+ else if (valid_builtin_assignconv_identity_widening_p (lhs_type, rhs_type))
+ new_rhs = convert (lhs_type, rhs);
+
+ /* Try a narrowing primitive conversion (5.1.3):
+ - expression is a constant expression of type int AND
+ - variable is byte, short or char AND
+ - The value of the expression is representable in the type of the
+ variable */
+ else if (rhs_type == int_type_node && TREE_CONSTANT (rhs)
+ && (lhs_type == byte_type_node || lhs_type == char_type_node
+ || lhs_type == short_type_node))
+ {
+ if (int_fits_type_p (rhs, lhs_type))
+ new_rhs = convert (lhs_type, rhs);
+ else if (wfl_op1) /* Might be called with a NULL */
+ parse_warning_context
+ (wfl_op1, "Constant expression `%s' to wide for narrowing "
+ "primitive conversion to `%s'",
+ print_int_node (rhs), lang_printable_name (lhs_type, 0));
+ /* Reported a warning that will turn into an error further
+ down, so we don't return */
+ }
+
+ return new_rhs;
+}
+
+/* Return 1 if RHS_TYPE can be converted to LHS_TYPE by identity
+ conversion (5.1.1) or widening primitve conversion (5.1.2). Return
+ 0 is the conversion test fails. This implements parts the method
+ invocation convertion (5.3). */
static int
-can_cast_to_p (source, dest)
- tree source;
- tree dest;
+valid_builtin_assignconv_identity_widening_p (lhs_type, rhs_type)
+ tree lhs_type, rhs_type;
{
- if (TREE_CODE (source) == POINTER_TYPE)
- source = TREE_TYPE (source);
- if (TREE_CODE (dest) == POINTER_TYPE)
- dest = TREE_TYPE (dest);
+ /* 5.1.1: This is the identity conversion part. */
+ if (lhs_type == rhs_type)
+ return 1;
- if (TREE_CODE (source) == RECORD_TYPE && TREE_CODE (dest) == RECORD_TYPE)
- return valid_ref_assignconv_cast_p (source, dest, 1);
+ /* Reject non primitive types */
+ if (!JPRIMITIVE_TYPE_P (lhs_type) || !JPRIMITIVE_TYPE_P (rhs_type))
+ return 0;
- else if (JNUMERIC_TYPE_P (source) && JNUMERIC_TYPE_P (dest))
+ /* 5.1.2: widening primitive conversion. byte, even if it's smaller
+ than a char can't be converted into a char. Short can't too, but
+ the < test below takes care of that */
+ if (lhs_type == char_type_node && rhs_type == byte_type_node)
+ return 0;
+
+ /* Accept all promoted type here. Note, we can't use <= in the test
+ below, because we still need to bounce out assignments of short
+ to char and the likes */
+ if (lhs_type == int_type_node
+ && (rhs_type == promoted_byte_type_node
+ || rhs_type == promoted_short_type_node
+ || rhs_type == promoted_char_type_node
+ || rhs_type == promoted_boolean_type_node))
+ return 1;
+
+ /* From here, an integral is widened if its precision is smaller
+ than the precision of the LHS or if the LHS is a floating point
+ type, or the RHS is a float and the RHS a double. */
+ if ((JINTEGRAL_TYPE_P (rhs_type) && JINTEGRAL_TYPE_P (lhs_type)
+ && (TYPE_PRECISION (rhs_type) < TYPE_PRECISION (lhs_type)))
+ || (JINTEGRAL_TYPE_P (rhs_type) && JFLOAT_TYPE_P (lhs_type))
+ || (rhs_type == float_type_node && lhs_type == double_type_node))
return 1;
return 0;
@@ -6612,6 +8812,11 @@ valid_ref_assignconv_cast_p (source, dest, cast)
tree dest;
int cast;
{
+ /* SOURCE or DEST might be null if not from a declared entity. */
+ if (!source || !dest)
+ return 0;
+ if (JNULLP_TYPE_P (source))
+ return 1;
if (TREE_CODE (source) == POINTER_TYPE)
source = TREE_TYPE (source);
if (TREE_CODE (dest) == POINTER_TYPE)
@@ -6621,7 +8826,7 @@ valid_ref_assignconv_cast_p (source, dest, cast)
{
if (TYPE_CLASS_P (dest))
return source == dest || inherits_from_p (source, dest)
- || cast && inherits_from_p (dest, source);
+ || (cast && inherits_from_p (dest, source));
if (TYPE_INTERFACE_P (dest))
{
/* If doing a cast and SOURCE is final, the operation is
@@ -6644,7 +8849,7 @@ valid_ref_assignconv_cast_p (source, dest, cast)
return dest == object_type_node;
/* We're doing a cast. The cast is always valid is class
DEST is not final, otherwise, DEST must implement SOURCE */
- else if (!CLASS_FINAL (TYPE_NAME (source)))
+ else if (!CLASS_FINAL (TYPE_NAME (dest)))
return 1;
else
return interface_of_p (source, dest);
@@ -6658,7 +8863,7 @@ valid_ref_assignconv_cast_p (source, dest, cast)
{
tree method_source, method_dest;
tree source_type;
- tree source_sig, dest_sig;
+ tree source_sig;
tree source_name;
for (method_source = TYPE_METHODS (source); method_source;
method_source = TREE_CHAIN (method_source))
@@ -6687,13 +8892,18 @@ valid_ref_assignconv_cast_p (source, dest, cast)
{
if (TYPE_CLASS_P (dest))
return dest == object_type_node;
+ /* Can't cast an array to an interface unless the interface is
+ java.lang.Cloneable */
if (TYPE_INTERFACE_P (dest))
- return 0; /* Install test on Clonable. FIXME */
+ return (DECL_NAME (TYPE_NAME (dest)) == java_lang_cloneable ? 1 : 0);
else /* Arrays */
{
tree source_element_type = TYPE_ARRAY_ELEMENT (source);
tree dest_element_type = TYPE_ARRAY_ELEMENT (dest);
+ /* In case of severe errors, they turn out null */
+ if (!dest_element_type || !source_element_type)
+ return 0;
if (source_element_type == dest_element_type)
return 1;
return valid_ref_assignconv_cast_p (source_element_type,
@@ -6704,6 +8914,53 @@ valid_ref_assignconv_cast_p (source, dest, cast)
return 0;
}
+static int
+valid_cast_to_p (source, dest)
+ tree source;
+ tree dest;
+{
+ if (TREE_CODE (source) == POINTER_TYPE)
+ source = TREE_TYPE (source);
+ if (TREE_CODE (dest) == POINTER_TYPE)
+ dest = TREE_TYPE (dest);
+
+ if (TREE_CODE (source) == RECORD_TYPE && TREE_CODE (dest) == RECORD_TYPE)
+ return valid_ref_assignconv_cast_p (source, dest, 1);
+
+ else if (JNUMERIC_TYPE_P (source) && JNUMERIC_TYPE_P (dest))
+ return 1;
+
+ return 0;
+}
+
+/* Method invocation conversion test. Return 1 if type SOURCE can be
+ converted to type DEST through the methond invocation conversion
+ process (5.3) */
+
+static tree
+do_unary_numeric_promotion (arg)
+ tree arg;
+{
+ tree type = TREE_TYPE (arg);
+ if (TREE_CODE (type) == INTEGER_TYPE ? TYPE_PRECISION (type) < 32
+ : TREE_CODE (type) == CHAR_TYPE)
+ arg = convert (int_type_node, arg);
+ return arg;
+}
+
+/* Return a non zero value if SOURCE can be converted into DEST using
+ the method invocation conversion rule (5.3). */
+static int
+valid_method_invocation_conversion_p (dest, source)
+ tree dest, source;
+{
+ return ((JPRIMITIVE_TYPE_P (source) && JPRIMITIVE_TYPE_P (dest)
+ && valid_builtin_assignconv_identity_widening_p (dest, source))
+ || ((JREFERENCE_TYPE_P (source) || JNULLP_TYPE_P (source))
+ && (JREFERENCE_TYPE_P (dest) || JNULLP_TYPE_P (dest))
+ && valid_ref_assignconv_cast_p (source, dest, 0)));
+}
+
/* Build an incomplete binop expression. */
static tree
@@ -6712,15 +8969,7 @@ build_binop (op, op_location, op1, op2)
int op_location;
tree op1, op2;
{
- tree wfl;
-
- /* URSHIFT_EXPR is not part of what GCC understands, we can't directly build
- a node with it */
- tree binop =
- build ((op == URSHIFT_EXPR ? RSHIFT_EXPR : op), NULL_TREE, op1, op2);
- if (op == URSHIFT_EXPR)
- TREE_SET_CODE (binop, op);
-
+ tree binop = build (op, NULL_TREE, op1, op2);
TREE_SIDE_EFFECTS (binop) = 1;
/* Store the location of the operator, for better error report. The
string of the operator will be rebuild based on the OP value. */
@@ -6766,7 +9015,7 @@ operator_string (node)
case GE_EXPR: BUILD_OPERATOR_STRING (">=");
case LT_EXPR: BUILD_OPERATOR_STRING ("<");
case LE_EXPR: BUILD_OPERATOR_STRING ("<=");
- case JAVA_UNARY_PLUS_EXPR: BUILD_OPERATOR_STRING ("+");
+ case UNARY_PLUS_EXPR: BUILD_OPERATOR_STRING ("+");
case NEGATE_EXPR: BUILD_OPERATOR_STRING ("-");
case TRUTH_NOT_EXPR: BUILD_OPERATOR_STRING ("!");
case BIT_NOT_EXPR: BUILD_OPERATOR_STRING ("~");
@@ -6800,28 +9049,13 @@ patch_binop (node, wfl_op1, wfl_op2)
tree op2_type = TREE_TYPE (op2);
tree prom_type;
int code = TREE_CODE (node);
+
/* If 1, tell the routine that we have to return error_mark_node
after checking for the initialization of the RHS */
int error_found = 0;
- /* Figure what is going to be checked first for initialization prior
- its use. If NODE is part of a compound assignment, we check the
- second operand first, otherwise the first one first. We also
- initialize the matching WFL for the error report. `cfi' stands
- for Check For Initialization */
- tree cfi = (COMPOUND_ASSIGN_P (node) ? op2 : op1);
- tree cfi_wfl = (COMPOUND_ASSIGN_P (node) ? wfl_op2 : wfl_op1);
-
EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
- /* Check initialization of LHS first. We then silence further error
- message if the variable wasn't initialized */
- if (not_initialized_as_it_should_p (cfi))
- {
- ERROR_VARIABLE_NOT_INITIALIZED (cfi_wfl, DECL_NAME (cfi));
- INITIALIZED_P (op1) = 1;
- }
-
switch (code)
{
/* 15.16 Multiplicative operators */
@@ -6842,16 +9076,36 @@ patch_binop (node, wfl_op1, wfl_op2)
/* Change the division operator if necessary */
if (code == RDIV_EXPR && TREE_CODE (prom_type) == INTEGER_TYPE)
TREE_SET_CODE (node, TRUNC_DIV_EXPR);
- /* This one is more complicated. FLOATs are processed by a function
- call to soft_fmod. */
+
+ /* This one is more complicated. FLOATs are processed by a
+ function call to soft_fmod. Duplicate the value of the
+ COMPOUND_ASSIGN_P flag. */
if (code == TRUNC_MOD_EXPR)
- return build_java_binop (TRUNC_MOD_EXPR, prom_type, op1, op2);
+ {
+ tree mod = build_java_binop (TRUNC_MOD_EXPR, prom_type, op1, op2);
+ COMPOUND_ASSIGN_P (mod) = COMPOUND_ASSIGN_P (node);
+ TREE_SIDE_EFFECTS (mod)
+ = TREE_SIDE_EFFECTS (op1) | TREE_SIDE_EFFECTS (op2);
+ return mod;
+ }
break;
/* 15.17 Additive Operators */
case PLUS_EXPR: /* 15.17.1 String Concatenation Operator + */
- if (JSTRING_TYPE_P (op1_type) || JSTRING_TYPE_P (op2_type))
- fatal ("operator `+' non implemented on String - patch_binop");
+
+ /* Operation is valid if either one argument is a string
+ constant, a String object or a StringBuffer crafted for the
+ purpose of the a previous usage of the String concatenation
+ operator */
+
+ if (TREE_CODE (op1) == STRING_CST
+ || TREE_CODE (op2) == STRING_CST
+ || JSTRING_TYPE_P (op1_type)
+ || JSTRING_TYPE_P (op2_type)
+ || IS_CRAFTED_STRING_BUFFER_P (op1)
+ || IS_CRAFTED_STRING_BUFFER_P (op2))
+ return build_string_concatenation (op1, op2);
+
case MINUS_EXPR: /* 15.17.2 Additive Operators (+ and -) for
Numeric Types */
if (!JPRIMITIVE_TYPE_P (op1_type) || !JPRIMITIVE_TYPE_P (op2_type))
@@ -6882,7 +9136,7 @@ patch_binop (node, wfl_op1, wfl_op2)
"shift distance from `%s' to integral" :
"Incompatible type for `%s'. Can't convert shift distance from "
"`%s' to integral"),
- operator_string (node), lang_printable_name (op2_type));
+ operator_string (node), lang_printable_name (op2_type, 0));
TREE_TYPE (node) = error_mark_node;
error_found = 1;
break;
@@ -6890,8 +9144,8 @@ patch_binop (node, wfl_op1, wfl_op2)
/* Unary numeric promotion (5.6.1) is performed on each operand
separatly */
- op1 = convert (promote_type (op1_type), op1);
- op2 = convert (promote_type (op2_type), op2);
+ op1 = do_unary_numeric_promotion (op1);
+ op2 = do_unary_numeric_promotion (op2);
/* The type of the shift expression is the type of the promoted
type of the left-hand operand */
@@ -6906,13 +9160,86 @@ patch_binop (node, wfl_op1, wfl_op2)
build_int_2 (0x3f, 0)));
/* The >>> operator is a >> operating on unsigned quantities */
- if (code == URSHIFT_EXPR)
+ if (code == URSHIFT_EXPR && ! flag_emit_class_files)
{
- op1 = convert (unsigned_type (prom_type), op1);
+ tree to_return;
+ tree utype = unsigned_type (prom_type);
+ op1 = convert (utype, op1);
TREE_SET_CODE (node, RSHIFT_EXPR);
+ TREE_OPERAND (node, 0) = op1;
+ TREE_OPERAND (node, 1) = op2;
+ TREE_TYPE (node) = utype;
+ to_return = convert (prom_type, node);
+ /* Copy the original value of the COMPOUND_ASSIGN_P flag */
+ COMPOUND_ASSIGN_P (to_return) = COMPOUND_ASSIGN_P (node);
+ TREE_SIDE_EFFECTS (to_return)
+ = TREE_SIDE_EFFECTS (op1) | TREE_SIDE_EFFECTS (op2);
+ return to_return;
}
break;
+
+ /* 15.19.1 Type Comparison Operator instaceof */
+ case INSTANCEOF_EXPR:
+
+ TREE_TYPE (node) = boolean_type_node;
+
+ if (!(op2_type = resolve_type_during_patch (op2)))
+ return error_mark_node;
+
+ /* The first operand must be a reference type or the null type */
+ if (!JREFERENCE_TYPE_P (op1_type) && op1 != null_pointer_node)
+ error_found = 1; /* Error reported further below */
+
+ /* The second operand must be a reference type */
+ if (!JREFERENCE_TYPE_P (op2_type))
+ {
+ SET_WFL_OPERATOR (wfl_operator, node, wfl_op2);
+ parse_error_context
+ (wfl_operator, "Invalid argument `%s' for `instanceof'",
+ lang_printable_name (op2_type, 0));
+ error_found = 1;
+ }
+
+ if (!error_found && valid_ref_assignconv_cast_p (op1_type, op2_type, 1))
+ {
+ /* If the first operand is null, the result is always false */
+ if (op1 == null_pointer_node)
+ return boolean_false_node;
+ else if (flag_emit_class_files)
+ {
+ TREE_OPERAND (node, 1) = op2_type;
+ TREE_SIDE_EFFECTS (node) = TREE_SIDE_EFFECTS (op1);
+ return node;
+ }
+ /* Otherwise we have to invoke instance of to figure it out */
+ else
+ {
+ tree call =
+ build (CALL_EXPR, boolean_type_node,
+ build_address_of (soft_instanceof_node),
+ tree_cons
+ (NULL_TREE, op1,
+ build_tree_list (NULL_TREE,
+ build_class_ref (op2_type))),
+ NULL_TREE);
+ TREE_SIDE_EFFECTS (call) = TREE_SIDE_EFFECTS (op1);
+ return call;
+ }
+ }
+ /* There is no way the expression operand can be an instance of
+ the type operand. This is a compile time error. */
+ else
+ {
+ char *t1 = strdup (lang_printable_name (op1_type, 0));
+ SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
+ parse_error_context
+ (wfl_operator, "Impossible for `%s' to be instance of `%s'",
+ t1, lang_printable_name (op2_type, 0));
+ free (t1);
+ error_found = 1;
+ }
+ break;
/* 15.21 Bitwise and Logical Operators */
case BIT_AND_EXPR:
@@ -6988,7 +9315,7 @@ patch_binop (node, wfl_op1, wfl_op2)
case NE_EXPR:
/* 15.20.1 Numerical Equality Operators == and != */
/* Binary numeric promotion is performed on the operands */
- if (JPRIMITIVE_TYPE_P (op1_type) && JPRIMITIVE_TYPE_P (op2_type))
+ if (JNUMERIC_TYPE_P (op1_type) && JNUMERIC_TYPE_P (op2_type))
binary_numeric_promotion (op1_type, op2_type, &op1, &op2);
/* 15.20.2 Boolean Equality Operators == and != */
@@ -6997,13 +9324,14 @@ patch_binop (node, wfl_op1, wfl_op2)
; /* Nothing to do here */
/* 15.20.3 Reference Equality Operators == and != */
- /* Types have to be either references or the null type */
- else if ((op1 == null_pointer_node || op2 == null_pointer_node
- || JREFERENCE_TYPE_P (op1_type)
- || JREFERENCE_TYPE_P (op2_type))
- && ((op1_type == op2_type)
- /* The should use a can_cast_to_p() */
- ))
+ /* Types have to be either references or the null type. If
+ they're references, it must be possible to convert either
+ type to the other by casting conversion. */
+ else if (op1 == null_pointer_node || op2 == null_pointer_node
+ || (JREFERENCE_TYPE_P (op1_type) && JREFERENCE_TYPE_P (op2_type)
+ && (valid_ref_assignconv_cast_p (op1_type, op2_type, 1)
+ || valid_ref_assignconv_cast_p (op2_type,
+ op1_type, 1))))
; /* Nothing to do here */
/* Else we have an error figure what can't be converted into
@@ -7011,11 +9339,11 @@ patch_binop (node, wfl_op1, wfl_op2)
else
{
char *t1;
- t1 = strdup ((char *)lang_printable_name (op1_type));
+ t1 = strdup (lang_printable_name (op1_type, 0));
parse_error_context
(wfl_operator, "Incompatible type for `%s'. Can't convert `%s' "
"to `%s'", operator_string (node), t1,
- lang_printable_name (op2_type));
+ lang_printable_name (op2_type, 0));
free (t1);
TREE_TYPE (node) = boolean_type_node;
error_found = 1;
@@ -7025,29 +9353,241 @@ patch_binop (node, wfl_op1, wfl_op2)
break;
}
- /* Then check the initialization of the RHS. We don't do that if
- we're dealing with a node that is part of a compound
- assignment. We then silence further error message if the variable
- wasn't initialized */
- if (not_initialized_as_it_should_p (op2) && !COMPOUND_ASSIGN_P (node))
- {
- ERROR_VARIABLE_NOT_INITIALIZED (wfl_op2, DECL_NAME (op2));
- INITIALIZED_P (op2) = 1;
- }
-
if (error_found)
return error_mark_node;
TREE_OPERAND (node, 0) = op1;
TREE_OPERAND (node, 1) = op2;
TREE_TYPE (node) = prom_type;
- return fold (node);
+ TREE_SIDE_EFFECTS (node) = TREE_SIDE_EFFECTS (op1) | TREE_SIDE_EFFECTS (op2);
+
+ /* fold does not respect side-effect order as required for Java but not C. */
+ if (! TREE_SIDE_EFFECTS (node))
+ node = fold (node);
+ return node;
+}
+
+/* Concatenate the STRING_CST CSTE and STRING. When AFTER is a non
+ zero value, the value of CSTE comes after the valude of STRING */
+
+static tree
+do_merge_string_cste (cste, string, string_len, after)
+ tree cste;
+ char *string;
+ int string_len, after;
+{
+ int len = TREE_STRING_LENGTH (cste) + string_len;
+ char *old = TREE_STRING_POINTER (cste);
+ TREE_STRING_LENGTH (cste) = len;
+ TREE_STRING_POINTER (cste) = obstack_alloc (expression_obstack, len+1);
+ if (after)
+ {
+ strcpy (TREE_STRING_POINTER (cste), string);
+ strcat (TREE_STRING_POINTER (cste), old);
+ }
+ else
+ {
+ strcpy (TREE_STRING_POINTER (cste), old);
+ strcat (TREE_STRING_POINTER (cste), string);
+ }
+ return cste;
+}
+
+/* Tries to merge OP1 (a STRING_CST) and OP2 (if suitable). Return a
+ new STRING_CST on success, NULL_TREE on failure */
+
+static tree
+merge_string_cste (op1, op2, after)
+ tree op1, op2;
+ int after;
+{
+ /* Handle two string constants right away */
+ if (TREE_CODE (op2) == STRING_CST)
+ return do_merge_string_cste (op1, TREE_STRING_POINTER (op2),
+ TREE_STRING_LENGTH (op2), after);
+
+ /* Reasonable integer constant can be treated right away */
+ if (TREE_CODE (op2) == INTEGER_CST && !TREE_CONSTANT_OVERFLOW (op2))
+ {
+ static char *boolean_true = "true";
+ static char *boolean_false = "false";
+ static char *null_pointer = "null";
+ char ch[3];
+ char *string;
+
+ if (op2 == boolean_true_node)
+ string = boolean_true;
+ else if (op2 == boolean_false_node)
+ string = boolean_false;
+ else if (op2 == null_pointer_node)
+ string = null_pointer;
+ else if (TREE_TYPE (op2) == char_type_node)
+ {
+ ch[0] = (char )TREE_INT_CST_LOW (op2);
+ ch[1] = '\0';
+ string = ch;
+ }
+ else
+ string = print_int_node (op2);
+
+ return do_merge_string_cste (op1, string, strlen (string), after);
+ }
+ return NULL_TREE;
+}
+
+/* Tries to statically concatenate OP1 and OP2 if possible. Either one
+ has to be a STRING_CST and the other part must be a STRING_CST or a
+ INTEGRAL constant. Return a new STRING_CST if the operation
+ succeed, NULL_TREE otherwise.
+
+ If the case we want to optimize for space, we might want to return
+ NULL_TREE for each invocation of this routine. FIXME */
+
+static tree
+string_constant_concatenation (op1, op2)
+ tree op1, op2;
+{
+ if (TREE_CODE (op1) == STRING_CST || (TREE_CODE (op2) == STRING_CST))
+ {
+ tree string, rest;
+ int invert;
+
+ string = (TREE_CODE (op1) == STRING_CST ? op1 : op2);
+ rest = (string == op1 ? op2 : op1);
+ invert = (string == op1 ? 0 : 1 );
+
+ /* Walk REST, only if it looks reasonable */
+ if (TREE_CODE (rest) != STRING_CST
+ && !IS_CRAFTED_STRING_BUFFER_P (rest)
+ && !JSTRING_TYPE_P (TREE_TYPE (rest))
+ && TREE_CODE (rest) == EXPR_WITH_FILE_LOCATION)
+ {
+ rest = java_complete_tree (rest);
+ if (rest == error_mark_node)
+ return error_mark_node;
+ rest = fold (rest);
+ }
+ return merge_string_cste (string, rest, invert);
+ }
+ return NULL_TREE;
}
-/* Build an incomplete unary operator expression. Unary `+' node is
- build as a CONV_EXPR, even though its tree code is overridden by a
- JAVA_UNARY_PLUS_EXPR that isn't a tree code, to differentiate it during
- the walk. */
+/* Implement the `+' operator. Does static optimization if possible,
+ otherwise create (if necessary) and append elements to a
+ StringBuffer. The StringBuffer will be carried around until it is
+ used for a function call or an assignment. Then toString() will be
+ called on it to turn it into a String object. */
+
+static tree
+build_string_concatenation (op1, op2)
+ tree op1, op2;
+{
+ tree result;
+ int side_effects = TREE_SIDE_EFFECTS (op1) | TREE_SIDE_EFFECTS (op2);
+
+ /* Try to do some static optimization */
+ if ((result = string_constant_concatenation (op1, op2)))
+ return result;
+
+ /* Discard empty strings on either side of the expression */
+ if (TREE_CODE (op1) == STRING_CST && TREE_STRING_LENGTH (op1) == 0)
+ {
+ op1 = op2;
+ op2 = NULL_TREE;
+ }
+ else if (TREE_CODE (op2) == STRING_CST && TREE_STRING_LENGTH (op2) == 0)
+ op2 = NULL_TREE;
+
+ /* If operands are string constant, turn then into object references */
+ if (TREE_CODE (op1) == STRING_CST)
+ op1 = patch_string_cst (op1);
+ if (op2 && TREE_CODE (op2) == STRING_CST)
+ op2 = patch_string_cst (op2);
+
+ /* If either one of the constant is null and the other non null
+ operand is a String object, return it. */
+ if (JSTRING_TYPE_P (TREE_TYPE (op1)) && !op2)
+ return op1;
+
+ /* If OP1 isn't already a StringBuffer, create and
+ initialize a new one */
+ if (!IS_CRAFTED_STRING_BUFFER_P (op1))
+ {
+ /* Two solutions here:
+ 1) OP1 is a string reference, we call new StringBuffer(OP1)
+ 2) OP1 is something else, we call new StringBuffer().append(OP1). */
+ if (JSTRING_TYPE_P (TREE_TYPE (op1)))
+ op1 = BUILD_STRING_BUFFER (op1);
+ else
+ {
+ tree aNew = BUILD_STRING_BUFFER (NULL_TREE);
+ op1 = make_qualified_primary (aNew, BUILD_APPEND (op1), 0);
+ }
+ }
+
+ if (op2)
+ {
+ /* OP1 is no longer the last node holding a crafted StringBuffer */
+ IS_CRAFTED_STRING_BUFFER_P (op1) = 0;
+ /* Create a node for `{new...,xxx}.append (op2)' */
+ if (op2)
+ op1 = make_qualified_primary (op1, BUILD_APPEND (op2), 0);
+ }
+
+ /* Mark the last node holding a crafted StringBuffer */
+ IS_CRAFTED_STRING_BUFFER_P (op1) = 1;
+
+ TREE_SIDE_EFFECTS (op1) = side_effects;
+ return op1;
+}
+
+/* Patch the string node NODE. NODE can be a STRING_CST of a crafted
+ StringBuffer. If no string were found to be patched, return
+ NULL. */
+
+static tree
+patch_string (node)
+ tree node;
+{
+ if (node == error_mark_node)
+ return error_mark_node;
+ if (TREE_CODE (node) == STRING_CST)
+ return patch_string_cst (node);
+ else if (IS_CRAFTED_STRING_BUFFER_P (node))
+ {
+ int saved = ctxp->explicit_constructor_p;
+ tree invoke = build_method_invocation (wfl_to_string, NULL_TREE);
+ tree ret;
+ /* Temporary disable forbid the use of `this'. */
+ ctxp->explicit_constructor_p = 0;
+ ret = java_complete_tree (make_qualified_primary (node, invoke, 0));
+ /* Restore it at its previous value */
+ ctxp->explicit_constructor_p = saved;
+ return ret;
+ }
+ return NULL_TREE;
+}
+
+/* Build the internal representation of a string constant. */
+
+static tree
+patch_string_cst (node)
+ tree node;
+{
+ int location;
+ if (! flag_emit_class_files)
+ {
+ push_obstacks (&permanent_obstack, &permanent_obstack);
+ node = get_identifier (TREE_STRING_POINTER (node));
+ location = alloc_name_constant (CONSTANT_String, node);
+ node = build_ref_from_constant_pool (location);
+ }
+ TREE_TYPE (node) = promote_type (string_type_node);
+ TREE_CONSTANT (node) = 1;
+ return node;
+}
+
+/* Build an incomplete unary operator expression. */
static tree
build_unaryop (op_token, op_location, op1)
@@ -7058,7 +9598,7 @@ build_unaryop (op_token, op_location, op1)
tree unaryop;
switch (op_token)
{
- case PLUS_TK: op = CONVERT_EXPR; break;
+ case PLUS_TK: op = UNARY_PLUS_EXPR; break;
case MINUS_TK: op = NEGATE_EXPR; break;
case NEG_TK: op = TRUTH_NOT_EXPR; break;
case NOT_TK: op = BIT_NOT_EXPR; break;
@@ -7067,9 +9607,6 @@ build_unaryop (op_token, op_location, op1)
}
unaryop = build1 (op, NULL_TREE, op1);
- if (op_token == PLUS_TK)
- TREE_SET_CODE (unaryop, JAVA_UNARY_PLUS_EXPR);
-
TREE_SIDE_EFFECTS (unaryop) = 1;
/* Store the location of the operator, for better error report. The
string of the operator will be rebuild based on the OP value. */
@@ -7126,7 +9663,7 @@ patch_unaryop (node, wfl_op)
{
tree op = TREE_OPERAND (node, 0);
tree op_type = TREE_TYPE (op);
- tree prom_type, value;
+ tree prom_type, value, decl;
int code = TREE_CODE (node);
int error_found = 0;
@@ -7142,21 +9679,27 @@ patch_unaryop (node, wfl_op)
case PREINCREMENT_EXPR:
/* 15.14.2 Prefix Decrement Operator -- */
case PREDECREMENT_EXPR:
- if (!DECL_P (op))
- {
- parse_error_context (wfl_operator, "Invalid argument to `%s'",
- operator_string (node));
- TREE_TYPE (node) = error_mark_node;
- error_found = 1;
- }
- else if (FIELD_FINAL (op))
+ decl = strip_out_static_field_access_decl (op);
+ if (!JDECL_P (decl)
+ && !((TREE_CODE (decl) == INDIRECT_REF
+ || TREE_CODE (decl) == COMPONENT_REF)
+ && JPRIMITIVE_TYPE_P (TREE_TYPE (decl))))
{
- parse_error_context
- (wfl_op, "Can't assign a value to the final variable `%s'",
- IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl_op)));
+ tree lvalue;
+ /* Before screaming, check that we're not in fact trying to
+ increment a optimized static final access, in which case
+ we issue an different error message. */
+ if (!(TREE_CODE (wfl_op) == EXPR_WITH_FILE_LOCATION
+ && resolve_expression_name (wfl_op, &lvalue)
+ && check_final_assignment (lvalue, wfl_op)))
+ parse_error_context (wfl_operator, "Invalid argument to `%s'",
+ operator_string (node));
TREE_TYPE (node) = error_mark_node;
error_found = 1;
}
+ else if (check_final_assignment (op, wfl_op))
+ error_found = 1;
+
/* From now on, we know that op if a variable and that it has a
valid wfl. We use wfl_op to locate errors related to the
++/-- operand. */
@@ -7164,24 +9707,27 @@ patch_unaryop (node, wfl_op)
{
parse_error_context
(wfl_op, "Invalid argument type `%s' to `%s'",
- lang_printable_name (op_type), operator_string (node));
+ lang_printable_name (op_type, 0), operator_string (node));
TREE_TYPE (node) = error_mark_node;
error_found = 1;
}
else
{
- /* Before the addition, binary numeric promotion if performed on
+ /* Before the addition, binary numeric promotion is performed on
both operands */
- value = integer_one_node;
- prom_type = binary_numeric_promotion (op_type, TREE_TYPE (value),
- &op, &value);
- /* And write the promoted increment back */
+ value = build_int_2 (1, 0);
+ TREE_TYPE (node) =
+ binary_numeric_promotion (op_type, TREE_TYPE (value), &op, &value);
+ /* And write the promoted incremented and increment */
+ TREE_OPERAND (node, 0) = op;
TREE_OPERAND (node, 1) = value;
+ /* Convert the overall back into its original type. */
+ return fold (convert (op_type, node));
}
break;
/* 15.14.3 Unary Plus Operator + */
- case JAVA_UNARY_PLUS_EXPR:
+ case UNARY_PLUS_EXPR:
/* 15.14.4 Unary Minus Operator - */
case NEGATE_EXPR:
if (!JNUMERIC_TYPE_P (op_type))
@@ -7193,10 +9739,10 @@ patch_unaryop (node, wfl_op)
/* Unary numeric promotion is performed on operand */
else
{
- prom_type = promote_type (op_type);
- op = convert (prom_type, op);
- if (code == JAVA_UNARY_PLUS_EXPR)
- node = op;
+ op = do_unary_numeric_promotion (op);
+ prom_type = TREE_TYPE (op);
+ if (code == UNARY_PLUS_EXPR)
+ return fold (op);
}
break;
@@ -7210,8 +9756,8 @@ patch_unaryop (node, wfl_op)
}
else
{
- prom_type = promote_type (op_type);
- op = convert (prom_type, op);
+ op = do_unary_numeric_promotion (op);
+ prom_type = TREE_TYPE (op);
}
break;
@@ -7220,6 +9766,8 @@ patch_unaryop (node, wfl_op)
if (TREE_CODE (op_type) != BOOLEAN_TYPE)
{
ERROR_CANT_CONVERT_TO_BOOLEAN (wfl_operator, node, op_type);
+ /* But the type is known. We will report an error if further
+ attempt of a assignment is made with this rhs */
TREE_TYPE (node) = boolean_type_node;
error_found = 1;
}
@@ -7229,32 +9777,33 @@ patch_unaryop (node, wfl_op)
/* 15.15 Cast Expression */
case CONVERT_EXPR:
- value = patch_cast (node, wfl_op, wfl_operator);
+ value = patch_cast (node, wfl_operator);
if (value == error_mark_node)
{
+ /* If this cast is part of an assignment, we tell the code
+ that deals with it not to complain about a mismatch,
+ because things have been cast, anyways */
TREE_TYPE (node) = error_mark_node;
error_found = 1;
}
else
- node = value;
+ {
+ value = fold (value);
+ TREE_SIDE_EFFECTS (value) = TREE_SIDE_EFFECTS (op);
+ return value;
+ }
break;
}
- /* Check variable initialization */
- if (not_initialized_as_it_should_p (op))
- {
- ERROR_VARIABLE_NOT_INITIALIZED (wfl_op, DECL_NAME (op));
- INITIALIZED_P (op) = 1;
- }
-
if (error_found)
return error_mark_node;
- /* In the case of JAVA_UNARY_PLUS_EXPR, we replaced NODE by a new one */
- else if (code != JAVA_UNARY_PLUS_EXPR && code != CONVERT_EXPR)
- {
- TREE_OPERAND (node, 0) = op;
- TREE_TYPE (node) = prom_type;
- }
+
+ /* There are cases where node has been replaced by something else
+ and we don't end up returning here: UNARY_PLUS_EXPR,
+ CONVERT_EXPR, {POST,PRE}{INCR,DECR}EMENT_EXPR. */
+ TREE_OPERAND (node, 0) = fold (op);
+ TREE_TYPE (node) = prom_type;
+ TREE_SIDE_EFFECTS (node) = TREE_SIDE_EFFECTS (op);
return fold (node);
}
@@ -7277,7 +9826,10 @@ resolve_type_during_patch (type)
return NULL_TREE;
}
else
- return TREE_TYPE (type_decl);
+ {
+ CLASS_LOADED_P (TREE_TYPE (type_decl)) = 1;
+ return TREE_TYPE (type_decl);
+ }
}
return type;
}
@@ -7285,9 +9837,8 @@ resolve_type_during_patch (type)
found. Otherwise NODE or something meant to replace it is returned. */
static tree
-patch_cast (node, wfl_op, wfl_operator)
+patch_cast (node, wfl_operator)
tree node;
- tree wfl_op;
tree wfl_operator;
{
tree op = TREE_OPERAND (node, 0);
@@ -7307,12 +9858,25 @@ patch_cast (node, wfl_op, wfl_operator)
if (cast_type == op_type)
return node;
+ /* float and double type are converted to the original type main
+ variant and then to the target type. */
+ if (JFLOAT_TYPE_P (op_type) && TREE_CODE (cast_type) == CHAR_TYPE)
+ op = convert (integer_type_node, op);
+
/* Try widening/narowwing convertion. Potentially, things need
to be worked out in gcc so we implement the extreme cases
correctly. fold_convert() needs to be fixed. */
return convert (cast_type, op);
}
+ /* It's also valid to cast a boolean into a boolean */
+ if (op_type == boolean_type_node && cast_type == boolean_type_node)
+ return node;
+
+ /* null can be casted to references */
+ if (op == null_pointer_node && JREFERENCE_TYPE_P (cast_type))
+ return build_null_of_type (cast_type);
+
/* The remaining legal casts involve conversion between reference
types. Check for their compile time correctness. */
if (JREFERENCE_TYPE_P (op_type) && JREFERENCE_TYPE_P (cast_type)
@@ -7324,7 +9888,16 @@ patch_cast (node, wfl_op, wfl_operator)
conversion (5.2) */
if (valid_ref_assignconv_cast_p (op_type, cast_type, 0))
- return node;
+ {
+ TREE_SET_CODE (node, NOP_EXPR);
+ return node;
+ }
+
+ if (flag_emit_class_files)
+ {
+ TREE_SET_CODE (node, CONVERT_EXPR);
+ return node;
+ }
/* The cast requires a run-time check */
return build (CALL_EXPR, promote_type (cast_type),
@@ -7335,13 +9908,24 @@ patch_cast (node, wfl_op, wfl_operator)
}
/* Any other casts are proven incorrect at compile time */
- t1 = strdup ((char *)lang_printable_name (op_type));
+ t1 = strdup (lang_printable_name (op_type, 0));
parse_error_context (wfl_operator, "Invalid cast from `%s' to `%s'",
- t1, lang_printable_name (cast_type));
+ t1, lang_printable_name (cast_type, 0));
free (t1);
return error_mark_node;
}
+/* Build a null constant and give it the type TYPE. */
+
+static tree
+build_null_of_type (type)
+ tree type;
+{
+ tree node = build_int_2 (0, 0);
+ TREE_TYPE (node) = promote_type (type);
+ return node;
+}
+
/* Build an ARRAY_REF incomplete tree node. Note that operand 1 isn't
a list of indices. */
static tree
@@ -7357,26 +9941,17 @@ build_array_ref (location, array, index)
/* 15.12 Array Access Expression */
static tree
-patch_array_ref (node, wfl_array, wfl_index)
- tree node, wfl_array, wfl_index;
+patch_array_ref (node)
+ tree node;
{
tree array = TREE_OPERAND (node, 0);
tree array_type = TREE_TYPE (array);
tree index = TREE_OPERAND (node, 1);
tree index_type = TREE_TYPE (index);
- tree promoted_index_type;
int error_found = 0;
EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
- if (not_initialized_as_it_should_p (array))
- {
- ERROR_VARIABLE_NOT_INITIALIZED (wfl_array, DECL_NAME (array));
- INITIALIZED_P (array) = 1;
- }
- if (! flag_emit_class_files)
- array = save_expr (array);
-
if (TREE_CODE (array_type) == POINTER_TYPE)
array_type = TREE_TYPE (array_type);
@@ -7385,47 +9960,48 @@ patch_array_ref (node, wfl_array, wfl_index)
{
parse_error_context
(wfl_operator, "`[]' can only be applied to arrays. It can't be "
- "applied to `%s'", lang_printable_name (array_type));
+ "applied to `%s'", lang_printable_name (array_type, 0));
TREE_TYPE (node) = error_mark_node;
error_found = 1;
}
/* The array index underdoes unary numeric promotion. The promoted
type must be int */
- promoted_index_type = promote_type (index_type);
- if (promoted_index_type != int_type_node)
+ index = do_unary_numeric_promotion (index);
+ if (TREE_TYPE (index) != int_type_node)
{
- int could_cast = can_cast_to_p (index_type, int_type_node);
+ int could_cast = valid_cast_to_p (index_type, int_type_node);
parse_error_context
(wfl_operator,
(could_cast ? "Incompatible type for `[]'. Explicit cast needed to "
"convert `%s' to `int'" : "Incompatible type for `[]'. "
"Can't convert `%s' to `int'"),
- lang_printable_name (index_type));
+ lang_printable_name (index_type, 0));
TREE_TYPE (node) = error_mark_node;
error_found = 1;
}
- /* Now if the index is a var/parm decl, check on its initialization */
- if (not_initialized_as_it_should_p (index))
- {
- ERROR_VARIABLE_NOT_INITIALIZED (wfl_index, DECL_NAME (index));
- INITIALIZED_P (index) = 1;
- }
-
if (error_found)
return error_mark_node;
- index = convert (promoted_index_type, index);
- if (TREE_CODE (array_type) == RECORD_TYPE)
- array_type = promote_type (TYPE_ARRAY_ELEMENT (array_type));
+ array_type = TYPE_ARRAY_ELEMENT (array_type);
+
if (flag_emit_class_files)
{
- TREE_OPERAND (node, 0)= array;
- TREE_OPERAND (node, 1)= index;
+ TREE_OPERAND (node, 0) = array;
+ TREE_OPERAND (node, 1) = index;
}
else
- node = build_java_arrayaccess (array, array_type, index);
+ {
+ /* The save_expr is for correct evaluation order. It would be cleaner
+ to use force_evaluation_order (see comment there), but that is
+ difficult when we also have to deal with bounds checking. */
+ if (TREE_SIDE_EFFECTS (index))
+ array = save_expr (array);
+ node = build_java_arrayaccess (array, array_type, index);
+ if (TREE_SIDE_EFFECTS (index))
+ node = build (COMPOUND_EXPR, array_type, array, node);
+ }
TREE_TYPE (node) = array_type;
return node;
}
@@ -7439,9 +10015,8 @@ build_newarray_node (type, dims, extra_dims)
int extra_dims;
{
tree node =
- build (CALL_EXPR, NULL_TREE, type, nreverse (dims),
+ build (NEW_ARRAY_EXPR, NULL_TREE, type, nreverse (dims),
build_int_2 (extra_dims, 0));
- TREE_SET_CODE (node, JAVA_NEW_ARRAY_EXPR);
return node;
}
@@ -7455,7 +10030,6 @@ patch_newarray (node)
int error_found = 0;
int ndims = 0;
int xdims = TREE_INT_CST_LOW (TREE_OPERAND (node, 2));
- int total_dims;
/* Dimension types are verified. It's better for the types to be
verified in order. */
@@ -7475,7 +10049,7 @@ patch_newarray (node)
promoted type must be int. */
else
{
- dim = convert (promote_type (TREE_TYPE (dim)), dim);
+ dim = do_unary_numeric_promotion (dim);
if (TREE_TYPE (dim) != int_type_node)
dim_error = 1;
}
@@ -7487,18 +10061,9 @@ patch_newarray (node)
(TREE_PURPOSE (cdim),
"Incompatible type for dimension in array creation expression. "
"%s convert `%s' to `int'",
- (can_cast_to_p (TREE_TYPE (dim), int_type_node) ?
+ (valid_cast_to_p (TREE_TYPE (dim), int_type_node) ?
"Explicit cast needed to" : "Can't"),
- lang_printable_name (TREE_TYPE (dim)));
- error_found = 1;
- }
-
- /* Check for uninitialized variables */
- if (not_initialized_as_it_should_p (dim))
- {
- ERROR_VARIABLE_NOT_INITIALIZED (TREE_PURPOSE (cdim),
- DECL_NAME (dim));
- INITIALIZED_P (dim) = 1;
+ lang_printable_name (TREE_TYPE (dim), 0));
error_found = 1;
}
@@ -7517,68 +10082,199 @@ patch_newarray (node)
return error_mark_node;
}
+ /* Set array_type to the actual (promoted) array type of the result. */
+ if (TREE_CODE (type) == RECORD_TYPE)
+ type = build_pointer_type (type);
+ while (--xdims >= 0)
+ {
+ type = promote_type (build_java_array_type (type, -1));
+ }
+ dims = nreverse (dims);
+ array_type = type;
+ for (cdim = dims; cdim; cdim = TREE_CHAIN (cdim))
+ {
+ type = array_type;
+ array_type = build_java_array_type (type,
+ TREE_CODE (cdim) == INTEGER_CST ?
+ TREE_INT_CST_LOW (cdim) : -1);
+ array_type = promote_type (array_type);
+ }
+ dims = nreverse (dims);
+
/* The node is transformed into a function call. Things are done
differently according to the number of dimensions. If the number
of dimension is equal to 1, then the nature of the base type
(primitive or not) matters. */
- total_dims = xdims + ndims;
- if (total_dims == 1)
+ if (ndims == 1)
+ return build_new_array (type, TREE_VALUE (dims));
+
+ /* Can't reuse what's already written in expr.c because it uses the
+ JVM stack representation. Provide a build_multianewarray. FIXME */
+ return build (CALL_EXPR, array_type,
+ build_address_of (soft_multianewarray_node),
+ tree_cons (NULL_TREE, build_class_ref (TREE_TYPE (array_type)),
+ tree_cons (NULL_TREE,
+ build_int_2 (ndims, 0), dims )),
+ NULL_TREE);
+}
+
+/* 10.6 Array initializer. */
+
+/* Build a wfl for array element that don't have one, so we can
+ pin-point errors. */
+
+static tree
+maybe_build_array_element_wfl (node)
+ tree node;
+{
+ if (TREE_CODE (node) != EXPR_WITH_FILE_LOCATION)
+ return build_expr_wfl (NULL_TREE, ctxp->filename,
+ ctxp->elc.line, ctxp->elc.prev_col);
+ else
+ return NULL_TREE;
+}
+
+/* Build a NEW_ARRAY_INIT that features a CONSTRUCTOR node. This makes
+ identification of initialized arrays easier to detect during walk
+ and expansion. */
+
+static tree
+build_new_array_init (location, values)
+ int location;
+ tree values;
+{
+ tree constructor = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, values);
+ tree to_return = build1 (NEW_ARRAY_INIT, NULL_TREE, constructor);
+ EXPR_WFL_LINECOL (to_return) = location;
+ return to_return;
+}
+
+/* Expand a NEW_ARRAY_INIT node. Return error_mark_node if an error
+ occurred. Otherwise return NODE after having set its type
+ appropriately. */
+
+static tree
+patch_new_array_init (type, node)
+ tree type, node;
+{
+ int error_seen = 0;
+ tree current, element_type;
+ HOST_WIDE_INT length;
+ int all_constant = 1;
+ tree init = TREE_OPERAND (node, 0);
+
+ if (TREE_CODE (type) != POINTER_TYPE || ! TYPE_ARRAY_P (TREE_TYPE (type)))
{
- if (JPRIMITIVE_TYPE_P (type))
+ parse_error_context (node,
+ "Invalid array initializer for non-array type `%s'",
+ lang_printable_name (type, 1));
+ return error_mark_node;
+ }
+ type = TREE_TYPE (type);
+ element_type = TYPE_ARRAY_ELEMENT (type);
+
+ CONSTRUCTOR_ELTS (init) = nreverse (CONSTRUCTOR_ELTS (init));
+
+ for (length = 0, current = CONSTRUCTOR_ELTS (init);
+ current; length++, current = TREE_CHAIN (current))
+ {
+ tree elt = TREE_VALUE (current);
+ if (elt == NULL_TREE || TREE_CODE (elt) != NEW_ARRAY_INIT)
{
- int type_code;
- if (type == boolean_type_node)
- type_code = 4;
- else if (type == char_type_node)
- type_code = 5;
- else if (type == float_type_node)
- type_code = 6;
- else if (type == double_type_node)
- type_code = 7;
- else if (type == byte_type_node)
- type_code = 8;
- else if (type == short_type_node)
- type_code = 9;
- else if (type == int_type_node)
- type_code = 10;
- else if (type == long_type_node)
- type_code = 11;
- else
- fatal ("Can't compute type code - patch_newarray");
- return build_newarray (type_code, TREE_VALUE (dims));
+ error_seen |= array_constructor_check_entry (element_type, current);
+ elt = TREE_VALUE (current);
+ /* When compiling to native code, STRING_CST is converted to
+ INDIRECT_REF, but still with a TREE_CONSTANT flag. */
+ if (! TREE_CONSTANT (elt) || TREE_CODE (elt) == INDIRECT_REF)
+ all_constant = 0;
}
else
- return build_anewarray (type, TREE_VALUE (dims));
+ {
+ TREE_VALUE (current) = patch_new_array_init (element_type, elt);
+ TREE_PURPOSE (current) = NULL_TREE;
+ all_constant = 0;
+ }
+ if (elt && TREE_VALUE (elt) == error_mark_node)
+ error_seen = 1;
+ }
+
+ if (error_seen)
+ return error_mark_node;
+
+ /* Create a new type. We can't reuse the one we have here by
+ patching its dimension because it originally is of dimension -1
+ hence reused by gcc. This would prevent triangular arrays. */
+ type = build_java_array_type (element_type, length);
+ TREE_TYPE (init) = TREE_TYPE (TREE_CHAIN (TREE_CHAIN (TYPE_FIELDS (type))));
+ TREE_TYPE (node) = promote_type (type);
+ TREE_CONSTANT (init) = all_constant;
+ TREE_CONSTANT (node) = all_constant;
+ return node;
+}
+
+/* Verify that one entry of the initializer element list can be
+ assigned to the array base type. Report 1 if an error occurred, 0
+ otherwise. */
+
+static int
+array_constructor_check_entry (type, entry)
+ tree type, entry;
+{
+ char *array_type_string = NULL; /* For error reports */
+ tree value, type_value, new_value, wfl_value, patched;
+ int error_seen = 0;
+
+ new_value = NULL_TREE;
+ wfl_value = TREE_VALUE (entry);
+
+ value = java_complete_tree (TREE_VALUE (entry));
+ /* patch_string return error_mark_node if arg is error_mark_node */
+ if ((patched = patch_string (value)))
+ value = patched;
+ if (value == error_mark_node)
+ return 1;
+
+ type_value = TREE_TYPE (value);
+
+ /* At anytime, try_builtin_assignconv can report a warning on
+ constant overflow during narrowing. */
+ SET_WFL_OPERATOR (wfl_operator, TREE_PURPOSE (entry), wfl_value);
+ new_value = try_builtin_assignconv (wfl_operator, type, value);
+ if (!new_value && (new_value = try_reference_assignconv (type, value)))
+ type_value = promote_type (type);
+
+ /* Check and report errors */
+ if (!new_value)
+ {
+ char *msg = (!valid_cast_to_p (type_value, type) ?
+ "Can't" : "Explicit cast needed to");
+ if (!array_type_string)
+ array_type_string = strdup (lang_printable_name (type, 1));
+ parse_error_context
+ (wfl_operator, "Incompatible type for array. %s convert `%s' to `%s'",
+ msg, lang_printable_name (type_value, 1), array_type_string);
+ error_seen = 1;
}
- /* Add extra dimensions as unknown dimensions */
- while (xdims--)
- dims =
- chainon (dims, build_tree_list (NULL_TREE, integer_negative_one_node));
- dims = chainon (dims, build_tree_list (NULL_TREE, integer_zero_node));
+ if (new_value)
+ {
+ new_value = maybe_build_primttype_type_ref (new_value, wfl_operator);
+ TREE_VALUE (entry) = new_value;
+ }
- /* Can't reuse what's already written in expr.c because it uses the
- JVM stack representation. Provide a build_multianewarray. FIXME */
- array_type = type;
- for (cdim = TREE_CHAIN (dims); cdim; cdim = TREE_CHAIN (cdim))
- array_type = build_java_array_type (promote_type (array_type),
- TREE_CODE (cdim) == INTEGER_CST ?
- TREE_INT_CST_LOW (cdim) : -1);
- return build (CALL_EXPR,
- promote_type (array_type),
- build_address_of (soft_multianewarray_node),
- tree_cons (NULL_TREE, build_class_ref (array_type),
- tree_cons (NULL_TREE,
- build_int_2 (total_dims, 0), dims )),
- NULL_TREE);
+ if (array_type_string)
+ free (array_type_string);
+
+ TREE_PURPOSE (entry) = NULL_TREE;
+ return error_seen;
}
static tree
build_this (location)
int location;
{
- tree node = build_wfl_node (this_identifier_node, input_filename, 0, 0);
- TREE_SET_CODE (node, JAVA_THIS_EXPR);
+ tree node = build_wfl_node (this_identifier_node);
+ TREE_SET_CODE (node, THIS_EXPR);
EXPR_WFL_LINECOL (node) = location;
return node;
}
@@ -7594,6 +10290,7 @@ build_return (location, op)
{
tree node = build1 (RETURN_EXPR, NULL_TREE, op);
EXPR_WFL_LINECOL (node) = location;
+ node = build_debugable_stmt (location, node);
return node;
}
@@ -7604,7 +10301,6 @@ patch_return (node)
tree return_exp = TREE_OPERAND (node, 0);
tree meth = current_function_decl;
tree mtype = TREE_TYPE (TREE_TYPE (current_function_decl));
- tree modify;
int error_found = 0;
TREE_TYPE (node) = error_mark_node;
@@ -7615,6 +10311,10 @@ patch_return (node)
if (return_exp && (mtype == void_type_node || DECL_CONSTRUCTOR_P (meth)))
error_found = 1;
+ /* It's invalid to use a return statement in a static block */
+ if (DECL_NAME (current_function_decl) == clinit_identifier_node)
+ error_found = 1;
+
/* It's invalid to have a no return value within a function that
isn't declared with the keyword `void' */
if (!return_exp && (mtype != void_type_node && !DECL_CONSTRUCTOR_P (meth)))
@@ -7622,20 +10322,53 @@ patch_return (node)
if (error_found)
{
- char *t = strdup ((char *)lang_printable_name (mtype));
- parse_error_context (wfl_operator, "`return' with%s value from `%s %s'",
- (error_found == 1 ? "" : "out"), t,
- lang_printable_name (meth));
- free (t);
+ if (DECL_NAME (current_function_decl) == clinit_identifier_node)
+ parse_error_context (wfl_operator,
+ "`return' inside static initializer.");
+
+ else if (!DECL_CONSTRUCTOR_P (meth))
+ {
+ char *t = strdup (lang_printable_name (mtype, 0));
+ parse_error_context (wfl_operator,
+ "`return' with%s value from `%s %s'",
+ (error_found == 1 ? "" : "out"),
+ t, lang_printable_name (meth, 0));
+ free (t);
+ }
+ else
+ parse_error_context (wfl_operator,
+ "`return' with value from constructor `%s'",
+ lang_printable_name (meth, 0));
return error_mark_node;
}
- /* If we have a return_exp, build a modify expression and expand it */
+ /* If we have a return_exp, build a modify expression and expand
+ it. Note: at that point, the assignment is declared valid, but we
+ may want to carry some more hacks */
if (return_exp)
{
- modify = build (MODIFY_EXPR, NULL_TREE, DECL_RESULT (meth), return_exp);
+ tree exp = java_complete_tree (return_exp);
+ tree modify, patched;
+
+ /* If the function returned value and EXP are booleans, EXP has
+ to be converted into the type of DECL_RESULT, which is integer
+ (see complete_start_java_method) */
+ if (TREE_TYPE (exp) == boolean_type_node &&
+ TREE_TYPE (TREE_TYPE (meth)) == boolean_type_node)
+ exp = convert_to_integer (TREE_TYPE (DECL_RESULT (meth)), exp);
+
+ /* `null' can be assigned to a function returning a reference */
+ if (JREFERENCE_TYPE_P (TREE_TYPE (TREE_TYPE (meth))) &&
+ exp == null_pointer_node)
+ exp = build_null_of_type (TREE_TYPE (TREE_TYPE (meth)));
+
+ if ((patched = patch_string (exp)))
+ exp = patched;
+
+ modify = build (MODIFY_EXPR, NULL_TREE, DECL_RESULT (meth), exp);
EXPR_WFL_LINECOL (modify) = EXPR_WFL_LINECOL (node);
modify = java_complete_tree (modify);
+
if (modify != error_mark_node)
{
TREE_SIDE_EFFECTS (modify) = 1;
@@ -7657,12 +10390,11 @@ build_if_else_statement (location, expression, if_body, else_body)
tree expression, if_body, else_body;
{
tree node;
- /* FIXME: make else body be a void node, where this function is
- called */
if (!else_body)
- else_body = build (COMPOUND_EXPR, void_type_node, NULL_TREE, NULL_TREE);
+ else_body = empty_stmt_node;
node = build (COND_EXPR, NULL_TREE, expression, if_body, else_body);
EXPR_WFL_LINECOL (node) = location;
+ node = build_debugable_stmt (location, node);
return node;
}
@@ -7676,17 +10408,21 @@ patch_if_else_statement (node)
EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
/* The type of expression must be boolean */
- if (TREE_TYPE (expression) != boolean_type_node)
+ if (TREE_TYPE (expression) != boolean_type_node
+ && TREE_TYPE (expression) != promoted_boolean_type_node)
{
parse_error_context
(wfl_operator,
"Incompatible type for `if'. Can't convert `%s' to `boolean'",
- lang_printable_name (TREE_TYPE (expression)));
+ lang_printable_name (TREE_TYPE (expression), 0));
return error_mark_node;
}
TREE_TYPE (node) = void_type_node;
TREE_SIDE_EFFECTS (node) = 1;
+ CAN_COMPLETE_NORMALLY (node)
+ = CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 1))
+ | CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 2));
return node;
}
@@ -7694,30 +10430,35 @@ patch_if_else_statement (node)
/* Action taken when a lableled statement is parsed. a new
LABELED_BLOCK_EXPR is created. No statement is attached to the
- label, yet. */
+ label, yet. LABEL can be NULL_TREE for artificially-generated blocks. */
static tree
-build_labeled_block (location, label, wfl)
+build_labeled_block (location, label)
int location;
- tree label, wfl;
+ tree label;
{
- tree label_name = merge_qualified_name (label_id, label);
+ tree label_name ;
tree label_decl, node;
-
- /* Issue a warning if we try to reuse a label that was previously
- declared */
- if (IDENTIFIER_LOCAL_VALUE (label_name))
+ if (label == NULL_TREE || label == continue_identifier_node)
+ label_name = label;
+ else
{
- EXPR_WFL_LINECOL (wfl_operator) = location;
- parse_warning_context (wfl_operator, "Declaration of `%s' shadows "
- "a previous declaration",
- IDENTIFIER_POINTER (label));
- EXPR_WFL_LINECOL (wfl_operator) =
- EXPR_WFL_LINECOL (IDENTIFIER_LOCAL_VALUE (label_name));
- parse_warning_context (wfl_operator, "This is the location of the "
- "previous declaration of label `%s'",
- IDENTIFIER_POINTER (label));
- java_warning_count--;
+ label_name = merge_qualified_name (label_id, label);
+ /* Issue an error if we try to reuse a label that was previously
+ declared */
+ if (IDENTIFIER_LOCAL_VALUE (label_name))
+ {
+ EXPR_WFL_LINECOL (wfl_operator) = location;
+ parse_error_context (wfl_operator, "Declaration of `%s' shadows "
+ "a previous label declaration",
+ IDENTIFIER_POINTER (label));
+ EXPR_WFL_LINECOL (wfl_operator) =
+ EXPR_WFL_LINECOL (IDENTIFIER_LOCAL_VALUE (label_name));
+ parse_error_context (wfl_operator, "This is the location of the "
+ "previous declaration of label `%s'",
+ IDENTIFIER_POINTER (label));
+ java_error_count--;
+ }
}
label_decl = create_label_decl (label_name);
@@ -7727,27 +10468,10 @@ build_labeled_block (location, label, wfl)
return node;
}
-/* Generate a label crafting a unique name for it. This is used to
- implicitely label loops that aren't the body part of labeled
- statement. */
-
-static tree
-generate_labeled_block ()
-{
- static int l_number = 0;
- char buf [20];
- tree label_name;
-
- sprintf (buf, "$a%d", l_number++);
- return build_labeled_block (0, get_identifier (buf), NULL_TREE);
-}
-
-/* A labeled statement LBE is attached a statement. If the statement
- happens to be a loop, a link from the loop back to the label is
- installed. */
+/* A labeled statement LBE is attached a statement. */
static tree
-complete_labeled_statement (lbe, statement)
+finish_labeled_statement (lbe, statement)
tree lbe; /* Labeled block expr */
tree statement;
{
@@ -7760,9 +10484,10 @@ complete_labeled_statement (lbe, statement)
if (TREE_CODE (statement) == LOOP_EXPR && IS_FOR_LOOP_P (statement))
{
java_method_add_stmt (current_function_decl, lbe);
- return exit_block ();
+ lbe = exit_block ();
}
-
+ pop_labeled_block ();
+ POP_LABELED_BLOCK ();
return lbe;
}
@@ -7786,12 +10511,20 @@ build_new_loop (loop_body)
COMPOUND_EXPR (loop main body)
EXIT_EXPR (this order is for while/for loops.
LABELED_BLOCK_EXPR the order is reversed for do loops)
- LABEL_DECL (continue occurding here branche at the
+ LABEL_DECL (a continue occuring here branches at the
BODY end of this labeled block)
INCREMENT (if any)
REVERSED, if non zero, tells that the loop condition expr comes
- after the body, like in the do-while loop. */
+ after the body, like in the do-while loop.
+
+ To obtain a loop, the loop body structure described above is
+ encapsulated within a LOOP_EXPR surrounded by a LABELED_BLOCK_EXPR:
+
+ LABELED_BLOCK_EXPR
+ LABEL_DECL (use this label to exit the loop)
+ LOOP_EXPR
+ <structure described above> */
static tree
build_loop_body (location, condition, reversed)
@@ -7799,19 +10532,19 @@ build_loop_body (location, condition, reversed)
tree condition;
int reversed;
{
- tree first, second, label, body;
+ tree first, second, body;
condition = build (EXIT_EXPR, NULL_TREE, condition); /* Force walk */
EXPR_WFL_LINECOL (condition) = location; /* For accurate error report */
condition = build_debugable_stmt (location, condition);
TREE_SIDE_EFFECTS (condition) = 1;
- body = generate_labeled_block ();
+ body = build_labeled_block (0, continue_identifier_node);
first = (reversed ? body : condition);
second = (reversed ? condition : body);
return
build (COMPOUND_EXPR, NULL_TREE,
- build (COMPOUND_EXPR, NULL_TREE, first, second), size_zero_node);
+ build (COMPOUND_EXPR, NULL_TREE, first, second), empty_stmt_node);
}
/* Install CONDITION (if any) and loop BODY (using REVERSED to tell
@@ -7819,7 +10552,7 @@ build_loop_body (location, condition, reversed)
loop list. */
static tree
-complete_loop_body (location, condition, body, reversed)
+finish_loop_body (location, condition, body, reversed)
int location;
tree condition, body;
int reversed;
@@ -7841,16 +10574,16 @@ complete_loop_body (location, condition, body, reversed)
return to_return;
}
-/* Tailored version of complete_loop_body for FOR loops, when FOR
+/* Tailored version of finish_loop_body for FOR loops, when FOR
loops feature the condition part */
static tree
-complete_for_loop (location, condition, update, body)
+finish_for_loop (location, condition, update, body)
int location;
tree condition, update, body;
{
/* Put the condition and the loop body in place */
- tree loop = complete_loop_body (location, condition, body, 0);
+ tree loop = finish_loop_body (location, condition, body, 0);
/* LOOP is the current loop which has been now popped of the loop
stack. Install the update block */
LOOP_EXPR_BODY_UPDATE_BLOCK (LOOP_EXPR_BODY (loop)) = update;
@@ -7858,28 +10591,21 @@ complete_for_loop (location, condition, update, body)
}
/* If the loop isn't surrounded by a labeled statement, create one and
- insert LOOP as it's body. */
+ insert LOOP as its body. */
static tree
patch_loop_statement (loop)
tree loop;
{
- tree cbl, loop_label, to_return_as_loop;
-
- if (LOOP_HAS_LABEL_P (loop))
+ if (! LOOP_HAS_LABEL_P (loop))
{
- loop_label = ctxp->current_labeled_block;
- to_return_as_loop = loop;
- }
- else
- {
- loop_label = generate_labeled_block ();
+ tree loop_label = build_labeled_block (0, NULL_TREE);
LABELED_BLOCK_BODY (loop_label) = loop;
PUSH_LABELED_BLOCK (loop_label);
- to_return_as_loop = loop_label;
+ loop = loop_label;
}
- TREE_TYPE (to_return_as_loop) = void_type_node;
- return to_return_as_loop;
+ TREE_TYPE (loop) = void_type_node;
+ return loop;
}
/* 14.13, 14.14: break and continue Statements */
@@ -7912,6 +10638,7 @@ build_bc_statement (location, is_break, name)
IS_BREAK_STMT_P (break_continue) = is_break;
TREE_SIDE_EFFECTS (break_continue) = 1;
EXPR_WFL_LINECOL (break_continue) = location;
+ break_continue = build_debugable_stmt (location, break_continue);
return break_continue;
}
@@ -7922,79 +10649,65 @@ patch_bc_statement (node)
tree node;
{
tree bc_label = EXIT_BLOCK_LABELED_BLOCK (node), target_stmt;
- int is_unlabeled = 0;
- EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
+ tree labeled_block = ctxp->current_labeled_block;
+ EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
- /* Not having a target means that the break/continue statement is
- unlabeled. We try to find a descent label for it */
- if (!bc_label)
- {
- is_unlabeled = 1;
- /* There should be a loop to branch to */
- if (ctxp->current_loop)
- {
- /* At that stage, we're in the loop body, which is
- encapsulated around a LABELED_BLOCK_EXPR. So searching
- the current loop label requires us to consider the
- labeled block before the current one. */
- if (!LOOP_HAS_LABEL_SKIP_P (ctxp->current_loop))
- fatal ("unlabeled loop has not installed label -- "
- "patch_bc_statement");
- bc_label = TREE_CHAIN (ctxp->current_labeled_block);
- }
- /* Not having a loop to break/continue to is an error */
- else
- {
- parse_error_context (wfl_operator, "`%s' must be in loop%s",
- (IS_BREAK_STMT_P (node) ? "break" : "continue"),
- (IS_BREAK_STMT_P (node) ? " or switch" : ""));
- return error_mark_node;
- }
- }
/* Having an identifier here means that the target is unknown. */
- else if (TREE_CODE (bc_label) == IDENTIFIER_NODE)
+ if (bc_label != NULL_TREE && TREE_CODE (bc_label) == IDENTIFIER_NODE)
{
parse_error_context (wfl_operator, "No label definition found for `%s'",
IDENTIFIER_POINTER (bc_label));
return error_mark_node;
}
-
- /* Find the statement we're targeting. */
- target_stmt = LABELED_BLOCK_BODY (bc_label);
-
- /* 14.13 The break Statement */
- if (IS_BREAK_STMT_P (node))
+ if (! IS_BREAK_STMT_P (node))
{
- /* Named break are always fine, as far as they have a target
- (already verified). Anonymous break need to target
- while/do/for/switch */
- if (is_unlabeled &&
- !(TREE_CODE (target_stmt) == LOOP_EXPR /* do/while/for */
- || 0)) /* switch FIXME */
+ /* It's a continue statement. */
+ for (;; labeled_block = TREE_CHAIN (labeled_block))
{
- parse_error_context (wfl_operator,
- "`break' must be in loop or switch");
- return error_mark_node;
+ if (labeled_block == NULL_TREE)
+ {
+ if (bc_label == NULL_TREE)
+ parse_error_context (wfl_operator,
+ "`continue' must be in loop");
+ else
+ parse_error_context (wfl_operator,
+ "continue label `%d' does not name a loop",
+ IDENTIFIER_POINTER (bc_label));
+ return error_mark_node;
+ }
+ if ((DECL_NAME (LABELED_BLOCK_LABEL (labeled_block))
+ == continue_identifier_node)
+ && (bc_label == NULL_TREE
+ || TREE_CHAIN (labeled_block) == bc_label))
+ {
+ bc_label = labeled_block;
+ break;
+ }
}
- /* If previously unlabeled, install the new found label */
- if (is_unlabeled)
- EXIT_BLOCK_LABELED_BLOCK (node) = bc_label;
}
- /* 14.14 The continue Statement */
- /* The continue statement must always target a loop */
- else
- {
- if (TREE_CODE (target_stmt) != LOOP_EXPR) /* do/while/for */
+ else if (!bc_label)
+ {
+ for (;; labeled_block = TREE_CHAIN (labeled_block))
{
- parse_error_context (wfl_operator, "`continue' must be in loop");
- return error_mark_node;
+ if (labeled_block == NULL_TREE)
+ {
+ parse_error_context (wfl_operator,
+ "`break' must be in loop or switch");
+ return error_mark_node;
+ }
+ target_stmt = LABELED_BLOCK_BODY (labeled_block);
+ if (TREE_CODE (target_stmt) == SWITCH_EXPR
+ || TREE_CODE (target_stmt) == LOOP_EXPR)
+ {
+ bc_label = labeled_block;
+ break;
+ }
}
- /* Everything looks good. We can fix the `continue' jump to go
- at the place in the loop were the continue is. The continue
- is the current labeled block, by construction. */
- EXIT_BLOCK_LABELED_BLOCK (node) = ctxp->current_labeled_block;
}
+ EXIT_BLOCK_LABELED_BLOCK (node) = bc_label;
+ CAN_COMPLETE_NORMALLY (bc_label) = 1;
+
/* Our break/continue don't return values. */
TREE_TYPE (node) = void_type_node;
/* Encapsulate the break within a compound statement so that it's
@@ -8023,13 +10736,686 @@ patch_exit_expr (node)
(wfl_operator,
"Incompatible type for loop conditional. Can't convert `%s' to "
"`boolean'",
- lang_printable_name (TREE_TYPE (expression)));
+ lang_printable_name (TREE_TYPE (expression), 0));
return error_mark_node;
}
/* Now we know things are allright, invert the condition, fold and
return */
TREE_OPERAND (node, 0) =
fold (build1 (TRUTH_NOT_EXPR, boolean_type_node, expression));
+
+ if (! integer_zerop (TREE_OPERAND (node, 0))
+ && ctxp->current_loop != NULL_TREE
+ && TREE_CODE (ctxp->current_loop) == LOOP_EXPR)
+ CAN_COMPLETE_NORMALLY (ctxp->current_loop) = 1;
+ if (! integer_onep (TREE_OPERAND (node, 0)))
+ CAN_COMPLETE_NORMALLY (node) = 1;
+
+
+ TREE_TYPE (node) = void_type_node;
+ return node;
+}
+
+/* 14.9 Switch statement */
+
+static tree
+patch_switch_statement (node)
+ tree node;
+{
+ tree se = TREE_OPERAND (node, 0), se_type;
+
+ /* Complete the switch expression */
+ se = TREE_OPERAND (node, 0) = java_complete_tree (se);
+ se_type = TREE_TYPE (se);
+ /* The type of the switch expression must be char, byte, short or
+ int */
+ if (!JINTEGRAL_TYPE_P (se_type))
+ {
+ EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
+ parse_error_context (wfl_operator, "Incompatible type for `switch'. "
+ "Can't convert `%s' to `int'",
+ lang_printable_name (se_type, 0));
+ /* This is what java_complete_tree will check */
+ TREE_OPERAND (node, 0) = error_mark_node;
+ return error_mark_node;
+ }
+
+ TREE_OPERAND (node, 1) = java_complete_tree (TREE_OPERAND (node, 1));
+
+ /* Ready to return */
+ if (TREE_CODE (TREE_OPERAND (node, 1)) == ERROR_MARK)
+ {
+ TREE_TYPE (node) = error_mark_node;
+ return error_mark_node;
+ }
TREE_TYPE (node) = void_type_node;
+ TREE_SIDE_EFFECTS (node) = 1;
+ CAN_COMPLETE_NORMALLY (node)
+ = CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 1))
+ || ! SWITCH_HAS_DEFAULT (node);
+ return node;
+}
+
+/* 14.18 The try statement */
+
+static tree
+build_try_statement (location, try_block, catches)
+ int location;
+ tree try_block, catches;
+{
+ tree node = build (TRY_EXPR, NULL_TREE, try_block, catches);
+ EXPR_WFL_LINECOL (node) = location;
+ return node;
+}
+
+static tree
+build_try_finally_statement (location, try_block, finally)
+ int location;
+ tree try_block, finally;
+{
+ tree node = build (TRY_FINALLY_EXPR, NULL_TREE, try_block, finally);
+ EXPR_WFL_LINECOL (node) = location;
+ return node;
+}
+
+static tree
+patch_try_statement (node)
+ tree node;
+{
+ int error_found = 0;
+ tree try = TREE_OPERAND (node, 0);
+ /* Exception handlers are considered in left to right order */
+ tree catch = nreverse (TREE_OPERAND (node, 1));
+ tree current, caught_type_list = NULL_TREE;
+
+ /* Check catch clauses, if any. Every time we find an error, we try
+ to process the next catch clause. We process the catch clause before
+ the try block so that when processing the try block we can check thrown
+ exceptions againts the caught type list. */
+ for (current = catch; current; current = TREE_CHAIN (current))
+ {
+ tree carg_decl, carg_type;
+ tree sub_current, catch_block, catch_clause;
+ int unreachable;
+
+ /* At this point, the structure of the catch clause is
+ CATCH_EXPR (catch node)
+ BLOCK (with the decl of the parameter)
+ COMPOUND_EXPR
+ MODIFY_EXPR (assignment of the catch parameter)
+ BLOCK (catch clause block)
+ */
+ catch_clause = TREE_OPERAND (current, 0);
+ carg_decl = BLOCK_EXPR_DECLS (catch_clause);
+ carg_type = TREE_TYPE (TREE_TYPE (carg_decl));
+
+ /* Catch clauses can't have more than one parameter declared,
+ but it's already enforced by the grammar. Make sure that the
+ only parameter of the clause statement in of class Throwable
+ or a subclass of Throwable, but that was done earlier. The
+ catch clause parameter type has also been resolved. */
+
+ /* Just make sure that the catch clause parameter type inherits
+ from java.lang.Throwable */
+ if (!inherits_from_p (carg_type, throwable_type_node))
+ {
+ EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (current);
+ parse_error_context (wfl_operator,
+ "Can't catch class `%s'. Catch clause "
+ "parameter type must be a subclass of "
+ "class `java.lang.Throwable'",
+ lang_printable_name (carg_type, 0));
+ error_found = 1;
+ continue;
+ }
+
+ /* Partial check for unreachable catch statement: The catch
+ clause is reachable iff is no earlier catch block A in
+ the try statement such that the type of the catch
+ clause's parameter is the same as or a subclass of the
+ type of A's parameter */
+ unreachable = 0;
+ for (sub_current = catch;
+ sub_current != current; sub_current = TREE_CHAIN (sub_current))
+ {
+ tree sub_catch_clause, decl;
+ sub_catch_clause = TREE_OPERAND (sub_current, 0);
+ decl = BLOCK_EXPR_DECLS (sub_catch_clause);
+
+ if (inherits_from_p (carg_type, TREE_TYPE (TREE_TYPE (decl))))
+ {
+ EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (current);
+ parse_error_context
+ (wfl_operator, "`catch' not reached because of the catch "
+ "clause at line %d", EXPR_WFL_LINENO (sub_current));
+ unreachable = error_found = 1;
+ break;
+ }
+ }
+ /* Complete the catch clause block */
+ catch_block = java_complete_tree (TREE_OPERAND (current, 0));
+ if (catch_block == error_mark_node)
+ {
+ error_found = 1;
+ continue;
+ }
+ if (CAN_COMPLETE_NORMALLY (catch_block))
+ CAN_COMPLETE_NORMALLY (node) = 1;
+ TREE_OPERAND (current, 0) = catch_block;
+
+ if (unreachable)
+ continue;
+
+ /* Things to do here: the exception must be thrown */
+
+ /* Link this type to the caught type list */
+ caught_type_list = tree_cons (NULL_TREE, carg_type, caught_type_list);
+ }
+
+ PUSH_EXCEPTIONS (caught_type_list);
+ if ((try = java_complete_tree (try)) == error_mark_node)
+ error_found = 1;
+ if (CAN_COMPLETE_NORMALLY (try))
+ CAN_COMPLETE_NORMALLY (node) = 1;
+ POP_EXCEPTIONS ();
+
+ /* Verification ends here */
+ if (error_found)
+ return error_mark_node;
+
+ TREE_OPERAND (node, 0) = try;
+ TREE_OPERAND (node, 1) = catch;
+ TREE_TYPE (node) = void_type_node;
+ return node;
+}
+
+/* 14.17 The synchronized Statement */
+
+static tree
+patch_synchronized_statement (node, wfl_op1)
+ tree node, wfl_op1;
+{
+ tree expr = java_complete_tree (TREE_OPERAND (node, 0));
+ tree block = TREE_OPERAND (node, 1);
+
+ tree enter, exit, expr_decl, assignment;
+
+ if (expr == error_mark_node)
+ {
+ block = java_complete_tree (block);
+ return expr;
+ }
+
+ /* The TYPE of expr must be a reference type */
+ if (!JREFERENCE_TYPE_P (TREE_TYPE (expr)))
+ {
+ SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
+ parse_error_context (wfl_operator, "Incompatible type for `synchronized'"
+ ". Can't convert `%s' to `java.lang.Object'",
+ lang_printable_name (TREE_TYPE (expr), 0));
+ return error_mark_node;
+ }
+
+ /* Generate a try-finally for the synchronized statement, except
+ that the handler that catches all throw exception calls
+ _Jv_MonitorExit and then rethrow the exception.
+ The synchronized statement is then implemented as:
+ TRY
+ {
+ _Jv_MonitorEnter (expression)
+ synchronized_block
+ _Jv_MonitorExit (expression)
+ }
+ CATCH_ALL
+ {
+ e = _Jv_exception_info ();
+ _Jv_MonitorExit (expression)
+ Throw (e);
+ } */
+
+ expr_decl = build_decl (VAR_DECL, generate_name (), TREE_TYPE (expr));
+ BUILD_MONITOR_ENTER (enter, expr_decl);
+ BUILD_MONITOR_EXIT (exit, expr_decl);
+ CAN_COMPLETE_NORMALLY (enter) = 1;
+ CAN_COMPLETE_NORMALLY (exit) = 1;
+ assignment = build (MODIFY_EXPR, NULL_TREE, expr_decl, expr);
+ TREE_SIDE_EFFECTS (assignment) = 1;
+ node = build1 (CLEANUP_POINT_EXPR, NULL_TREE,
+ build (COMPOUND_EXPR, NULL_TREE,
+ build (WITH_CLEANUP_EXPR, NULL_TREE,
+ build (COMPOUND_EXPR, NULL_TREE,
+ assignment, enter),
+ NULL_TREE, exit),
+ block));
+ node = build_expr_block (node, expr_decl);
+
+ return java_complete_tree (node);
+}
+
+/* 14.16 The throw Statement */
+
+static tree
+patch_throw_statement (node, wfl_op1)
+ tree node, wfl_op1;
+{
+ tree expr = TREE_OPERAND (node, 0);
+ tree type = TREE_TYPE (expr);
+ int unchecked_ok = 0, tryblock_throws_ok = 0;
+
+ /* Thrown expression must be assignable to java.lang.Throwable */
+ if (!try_reference_assignconv (throwable_type_node, expr))
+ {
+ SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
+ parse_error_context (wfl_operator, "Can't throw `%s'; it must be a "
+ "subclass of class `java.lang.Throwable'",
+ lang_printable_name (type, 0));
+ /* If the thrown expression was a reference, we further the
+ compile-time check. */
+ if (!JREFERENCE_TYPE_P (type))
+ return error_mark_node;
+ }
+
+ /* At least one of the following must be true */
+
+ /* The type of the throw expression is a not checked exception,
+ i.e. is a unchecked expression. */
+ unchecked_ok = IS_UNCHECKED_EXCEPTION_P (TREE_TYPE (type));
+
+ /* Throw is contained in a try statement and at least one catch
+ clause can receive the thrown expression or the current method is
+ declared to throw such an exception. Or, the throw statement is
+ contained in a method or constructor declaration and the type of
+ the Expression is assignable to at least one type listed in the
+ throws clause the declaration. */
+ SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
+ if (!unchecked_ok)
+ tryblock_throws_ok = check_thrown_exceptions_do (TREE_TYPE (expr));
+ if (!(unchecked_ok || tryblock_throws_ok))
+ {
+ /* If there is a surrounding try block that has no matching
+ clatch clause, report it first. A surrounding try block exits
+ only if there is something after the list of checked
+ exception thrown by the current function (if any). */
+ if (IN_TRY_BLOCK_P ())
+ parse_error_context (wfl_operator, "Checked exception `%s' can't be "
+ "caught by any of the catch clause(s) "
+ "of the surrounding `try' block",
+ lang_printable_name (type, 0));
+ /* If we have no surrounding try statement and the method doesn't have
+ any throws, report it now. FIXME */
+
+ /* We report that the exception can't be throw from a try block
+ in all circumstances but when the `throw' is inside a static
+ block. */
+ else if (!EXCEPTIONS_P (currently_caught_type_list)
+ && !tryblock_throws_ok)
+ {
+ if (DECL_NAME (current_function_decl) == clinit_identifier_node)
+ parse_error_context (wfl_operator, "Checked exception `%s' can't "
+ "be thrown in initializer",
+ lang_printable_name (type, 0));
+ else
+ parse_error_context (wfl_operator, "Checked exception `%s' isn't "
+ "thrown from a `try' block",
+ lang_printable_name (type, 0));
+ }
+ /* Otherwise, the current method doesn't have the appropriate
+ throws declaration */
+ else
+ parse_error_context (wfl_operator, "Checked exception `%s' doesn't "
+ "match any of current method's `throws' "
+ "declaration(s)",
+ lang_printable_name (type, 0));
+ return error_mark_node;
+ }
+
+ if (! flag_emit_class_files)
+ BUILD_THROW (node, expr);
+ return node;
+}
+
+/* Check that exception said to be thrown by method DECL can be
+ effectively caught from where DECL is invoked. */
+
+static void
+check_thrown_exceptions (location, decl)
+ int location;
+ tree decl;
+{
+ tree throws;
+ /* For all the unchecked exceptions thrown by DECL */
+ for (throws = DECL_FUNCTION_THROWS (decl); throws;
+ throws = TREE_CHAIN (throws))
+ if (!check_thrown_exceptions_do (TREE_VALUE (throws)))
+ {
+#if 1
+ /* Temporary hack to suppresses errors about cloning arrays. FIXME */
+ if (DECL_NAME (decl) == get_identifier ("clone"))
+ continue;
+#endif
+ EXPR_WFL_LINECOL (wfl_operator) = location;
+ parse_error_context
+ (wfl_operator, "Exception `%s' must be caught, or it must be "
+ "declared in the `throws' clause of `%s'",
+ lang_printable_name (TREE_VALUE (throws), 0),
+ IDENTIFIER_POINTER (DECL_NAME (current_function_decl)));
+ }
+}
+
+/* Return 1 if checked EXCEPTION is caught at the current nesting level of
+ try-catch blocks, OR is listed in the `throws' clause of the
+ current method. */
+
+static int
+check_thrown_exceptions_do (exception)
+ tree exception;
+{
+ tree list = currently_caught_type_list;
+ resolve_and_layout (exception, NULL_TREE);
+ /* First, all the nested try-catch-finally at that stage. The
+ last element contains `throws' clause exceptions, if any. */
+ if (IS_UNCHECKED_EXCEPTION_P (exception))
+ return 1;
+ while (list)
+ {
+ tree caught;
+ for (caught = TREE_VALUE (list); caught; caught = TREE_CHAIN (caught))
+ if (valid_ref_assignconv_cast_p (exception, TREE_VALUE (caught), 0))
+ return 1;
+ list = TREE_CHAIN (list);
+ }
+ return 0;
+}
+
+static void
+purge_unchecked_exceptions (mdecl)
+ tree mdecl;
+{
+ tree throws = DECL_FUNCTION_THROWS (mdecl);
+ tree new = NULL_TREE;
+
+ while (throws)
+ {
+ tree next = TREE_CHAIN (throws);
+ if (!IS_UNCHECKED_EXCEPTION_P (TREE_VALUE (throws)))
+ {
+ TREE_CHAIN (throws) = new;
+ new = throws;
+ }
+ throws = next;
+ }
+ /* List is inverted here, but it doesn't matter */
+ DECL_FUNCTION_THROWS (mdecl) = new;
+}
+
+/* 15.24 Conditional Operator ?: */
+
+static tree
+patch_conditional_expr (node, wfl_cond, wfl_op1)
+ tree node, wfl_cond, wfl_op1;
+{
+ tree cond = TREE_OPERAND (node, 0);
+ tree op1 = TREE_OPERAND (node, 1);
+ tree op2 = TREE_OPERAND (node, 2);
+ tree resulting_type = NULL_TREE;
+ tree t1, t2, patched;
+ int error_found = 0;
+
+ /* Operands of ?: might be StringBuffers crafted as a result of a
+ string concatenation. Obtain a descent operand here. */
+ if ((patched = patch_string (op1)))
+ TREE_OPERAND (node, 1) = op1 = patched;
+ if ((patched = patch_string (op2)))
+ TREE_OPERAND (node, 2) = op2 = patched;
+
+ t1 = TREE_TYPE (op1);
+ t2 = TREE_TYPE (op2);
+
+ /* The first expression must be a boolean */
+ if (TREE_TYPE (cond) != boolean_type_node)
+ {
+ SET_WFL_OPERATOR (wfl_operator, node, wfl_cond);
+ parse_error_context (wfl_operator, "Incompatible type for `?:'. Can't "
+ "convert `%s' to `boolean'",
+ lang_printable_name (TREE_TYPE (cond), 0));
+ error_found = 1;
+ }
+
+ /* Second and third can be numeric, boolean (i.e. primitive),
+ references or null. Anything else results in an error */
+ if (!((JNUMERIC_TYPE_P (t1) && JNUMERIC_TYPE_P (t2))
+ || ((JREFERENCE_TYPE_P (t1) || op1 == null_pointer_node)
+ && (JREFERENCE_TYPE_P (t2) || op2 == null_pointer_node))
+ || (t1 == boolean_type_node && t2 == boolean_type_node)))
+ error_found = 1;
+
+ /* Determine the type of the conditional expression. Same types are
+ easy to deal with */
+ else if (t1 == t2)
+ resulting_type = t1;
+
+ /* There are different rules for numeric types */
+ else if (JNUMERIC_TYPE_P (t1))
+ {
+ /* if byte/short found, the resulting type is short */
+ if ((t1 == byte_type_node && t2 == short_type_node)
+ || (t1 == short_type_node && t2 == byte_type_node))
+ resulting_type = short_type_node;
+
+ /* If t1 is a constant int and t2 is of type byte, short or char
+ and t1's value fits in t2, then the resulting type is t2 */
+ else if ((t1 == int_type_node && TREE_CONSTANT (TREE_OPERAND (node, 1)))
+ && JBSC_TYPE_P (t2) && int_fits_type_p (TREE_OPERAND (node, 1), t2))
+ resulting_type = t2;
+
+ /* If t2 is a constant int and t1 is of type byte, short or char
+ and t2's value fits in t1, then the resulting type is t1 */
+ else if ((t2 == int_type_node && TREE_CONSTANT (TREE_OPERAND (node, 2)))
+ && JBSC_TYPE_P (t1) && int_fits_type_p (TREE_OPERAND (node, 2), t1))
+ resulting_type = t1;
+
+ /* Otherwise, binary numeric promotion is applied and the
+ resulting type is the promoted type of operand 1 and 2 */
+ else
+ resulting_type = binary_numeric_promotion (t2, t2,
+ &TREE_OPERAND (node, 1),
+ &TREE_OPERAND (node, 2));
+ }
+
+ /* Cases of a reference and a null type */
+ else if (JREFERENCE_TYPE_P (t1) && op2 == null_pointer_node)
+ resulting_type = t1;
+
+ else if (JREFERENCE_TYPE_P (t2) && op1 == null_pointer_node)
+ resulting_type = t2;
+
+ /* Last case: different reference types. If a type can be converted
+ into the other one by assignment conversion, the latter
+ determines the type of the expression */
+ else if ((resulting_type = try_reference_assignconv (t1, op2)))
+ resulting_type = promote_type (t1);
+
+ else if ((resulting_type = try_reference_assignconv (t2, op1)))
+ resulting_type = promote_type (t2);
+
+ /* If we don't have any resulting type, we're in trouble */
+ if (!resulting_type)
+ {
+ char *t = strdup (lang_printable_name (t1, 0));
+ SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
+ parse_error_context (wfl_operator, "Incompatible type for `?:'. Can't "
+ "convert `%s' to `%s'", t,
+ lang_printable_name (t2, 0));
+ free (t);
+ error_found = 1;
+ }
+
+ if (error_found)
+ {
+ TREE_TYPE (node) = error_mark_node;
+ return error_mark_node;
+ }
+
+ TREE_TYPE (node) = resulting_type;
+ TREE_SET_CODE (node, COND_EXPR);
+ CAN_COMPLETE_NORMALLY (node) = 1;
return node;
}
+
+/* Try to constant fold NODE.
+ If NODE is not a constant expression, return NULL_EXPR.
+ CONTEXT is a static final VAR_DECL whose initializer we are folding. */
+
+static tree
+fold_constant_for_init (node, context)
+ tree node;
+ tree context;
+{
+ tree op0, op1, val;
+ enum tree_code code = TREE_CODE (node);
+
+ if (code == INTEGER_CST || code == REAL_CST || code == STRING_CST)
+ return node;
+ if (TREE_TYPE (node) != NULL_TREE)
+ return NULL_TREE;
+
+ switch (code)
+ {
+ case PLUS_EXPR:
+ case MINUS_EXPR:
+ case MULT_EXPR:
+ case TRUNC_MOD_EXPR:
+ case RDIV_EXPR:
+ case LSHIFT_EXPR:
+ case RSHIFT_EXPR:
+ case URSHIFT_EXPR:
+ case BIT_AND_EXPR:
+ case BIT_XOR_EXPR:
+ case BIT_IOR_EXPR:
+ case TRUTH_ANDIF_EXPR:
+ case TRUTH_ORIF_EXPR:
+ case EQ_EXPR:
+ case NE_EXPR:
+ case GT_EXPR:
+ case GE_EXPR:
+ case LT_EXPR:
+ case LE_EXPR:
+ op0 = TREE_OPERAND (node, 0);
+ op1 = TREE_OPERAND (node, 1);
+ val = fold_constant_for_init (op0, context);
+ if (val == NULL_TREE || ! TREE_CONSTANT (val))
+ return NULL_TREE;
+ TREE_OPERAND (node, 0) = val;
+ val = fold_constant_for_init (op1, context);
+ if (val == NULL_TREE || ! TREE_CONSTANT (val))
+ return NULL_TREE;
+ TREE_OPERAND (node, 1) = val;
+ return patch_binop (node, op0, op1);
+
+ case UNARY_PLUS_EXPR:
+ case NEGATE_EXPR:
+ case TRUTH_NOT_EXPR:
+ case BIT_NOT_EXPR:
+ case CONVERT_EXPR:
+ op0 = TREE_OPERAND (node, 0);
+ val = fold_constant_for_init (op0, context);
+ if (val == NULL_TREE || ! TREE_CONSTANT (val))
+ return NULL_TREE;
+ TREE_OPERAND (node, 0) = val;
+ return patch_unaryop (node, op0);
+ break;
+
+ case COND_EXPR:
+ val = fold_constant_for_init (TREE_OPERAND (node, 0), context);
+ if (val == NULL_TREE || ! TREE_CONSTANT (val))
+ return NULL_TREE;
+ TREE_OPERAND (node, 0) = val;
+ val = fold_constant_for_init (TREE_OPERAND (node, 1), context);
+ if (val == NULL_TREE || ! TREE_CONSTANT (val))
+ return NULL_TREE;
+ TREE_OPERAND (node, 1) = val;
+ val = fold_constant_for_init (TREE_OPERAND (node, 2), context);
+ if (val == NULL_TREE || ! TREE_CONSTANT (val))
+ return NULL_TREE;
+ TREE_OPERAND (node, 2) = val;
+ return integer_zerop (TREE_OPERAND (node, 0)) ? TREE_OPERAND (node, 1)
+ : TREE_OPERAND (node, 2);
+
+ case VAR_DECL:
+ if (! FIELD_STATIC (node) || ! FIELD_FINAL (node)
+ || DECL_INITIAL (node) == NULL_TREE)
+ return NULL_TREE;
+ val = DECL_INITIAL (node);
+ /* Guard against infinite recursion. */
+ DECL_INITIAL (node) = NULL_TREE;
+ val = fold_constant_for_init (val, DECL_CONTEXT (node));
+ DECL_INITIAL (node) = val;
+ return val;
+
+ case EXPR_WITH_FILE_LOCATION:
+ /* Compare java_complete_tree and resolve_expression_name. */
+ if (!EXPR_WFL_NODE (node) /* Or a PRIMARY flag ? */
+ || TREE_CODE (EXPR_WFL_NODE (node)) == IDENTIFIER_NODE)
+ {
+ tree name = EXPR_WFL_NODE (node);
+ tree decl;
+ if (PRIMARY_P (node))
+ return NULL_TREE;
+ else if (! QUALIFIED_P (name))
+ {
+ decl = lookup_field_wrapper (DECL_CONTEXT (context), name);
+ if (! FIELD_STATIC (decl))
+ return NULL_TREE;
+ return fold_constant_for_init (decl, decl);
+ }
+ else
+ {
+#if 0
+ /* Wait until the USE_COMPONENT_REF re-write. FIXME. */
+ qualify_ambiguous_name (node);
+ if (resolve_field_access (node, &decl, NULL)
+ && decl != NULL_TREE)
+ return fold_constant_for_init (decl, decl);
+#endif
+ return NULL_TREE;
+ }
+ }
+ else
+ {
+ op0 = TREE_OPERAND (node, 0);
+ val = fold_constant_for_init (op0, context);
+ if (val == NULL_TREE || ! TREE_CONSTANT (val))
+ return NULL_TREE;
+ TREE_OPERAND (node, 0) = val;
+ return val;
+ }
+
+#ifdef USE_COMPONENT_REF
+ case IDENTIFIER:
+ case COMPONENT_REF:
+ ?;
+#endif
+
+ default:
+ return NULL_TREE;
+ }
+}
+
+#ifdef USE_COMPONENT_REF
+/* Context is 'T' for TypeName, 'P' for PackageName,
+ 'M' for MethodName, 'E' for ExpressionName, and 'A' for AmbiguousName. */
+
+tree
+resolve_simple_name (name, context)
+ tree name;
+ int context;
+{
+}
+
+tree
+resolve_qualified_name (name, context)
+ tree name;
+ int context;
+{
+}
+#endif
diff --git a/gcc/java/typeck.c b/gcc/java/typeck.c
index b388ff7b44d..ad0ba4cda87 100644
--- a/gcc/java/typeck.c
+++ b/gcc/java/typeck.c
@@ -1,5 +1,5 @@
/* Handle types for the GNU compiler for the Java(TM) language.
- Copyright (C) 1996 Free Software Foundation, Inc.
+ Copyright (C) 1996, 97-98, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -28,6 +28,7 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */
#include "system.h"
#include "tree.h"
#include "obstack.h"
+#include "flags.h"
#include "java-tree.h"
#include "jcf.h"
#include "convert.h"
@@ -52,9 +53,26 @@ set_local_type (slot, type)
type_map[++slot] = void_type_node;
}
-extern tree convert_to_integer (tree type, tree expr);
-extern tree convert_to_real (tree type, tree expr);
-extern tree convert_to_pointer (tree type, tree expr);
+/* Convert an IEEE real to an integer type. The result of such a
+ conversion when the source operand is a NaN isn't defined by
+ IEEE754, but by the Java language standard: it must be zero. This
+ conversion produces something like:
+
+ ({ double tmp = expr; (tmp != tmp) ? 0 : (int)tmp; })
+
+ */
+
+static tree
+convert_ieee_real_to_integer (type, expr)
+ tree type, expr;
+{
+ expr = save_expr (expr);
+
+ return build (COND_EXPR, type,
+ build (NE_EXPR, boolean_type_node, expr, expr),
+ convert (type, integer_zero_node),
+ convert_to_integer (type, expr));
+}
/* Create an expression whose value is that of EXPR,
converted to type TYPE. The TREE_TYPE of the value
@@ -73,10 +91,23 @@ convert (type, expr)
return expr;
if (TREE_CODE (TREE_TYPE (expr)) == ERROR_MARK)
return error_mark_node;
+ if (code == VOID_TYPE)
+ return build1 (CONVERT_EXPR, type, expr);
if (code == BOOLEAN_TYPE)
return fold (convert_to_boolean (type, expr));
if (code == INTEGER_TYPE)
- return fold (convert_to_integer (type, expr));
+ {
+ if (TREE_CODE (TREE_TYPE (expr)) == REAL_TYPE
+#ifdef TARGET_SOFT_FLOAT
+ && !TARGET_SOFT_FLOAT
+#endif
+ && !flag_emit_class_files
+ && !flag_fast_math
+ && TARGET_FLOAT_FORMAT == IEEE_FLOAT_FORMAT)
+ return fold (convert_ieee_real_to_integer (type, expr));
+ else
+ return fold (convert_to_integer (type, expr));
+ }
if (code == REAL_TYPE)
return fold (convert_to_real (type, expr));
if (code == CHAR_TYPE)
@@ -87,6 +118,7 @@ convert (type, expr)
return error_mark_node;
}
+
tree
convert_to_char (type, expr)
tree type, expr;
@@ -107,8 +139,8 @@ convert_to_boolean (type, expr)
void
incomplete_type_error (value, type)
- tree value;
- tree type;
+ tree value ATTRIBUTE_UNUSED;
+ tree type ATTRIBUTE_UNUSED;
{
error ("internal error - use of undefined type");
}
@@ -135,14 +167,6 @@ type_for_mode (mode, unsignedp)
if (mode == TYPE_MODE (double_type_node))
return double_type_node;
-#if 0
- 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);
-#endif
-
return 0;
}
@@ -331,9 +355,9 @@ build_java_array_type (element_type, length)
buf, 0, 0, "");
t = IDENTIFIER_SIGNATURE_TYPE (sig);
if (t != NULL_TREE)
- return t;
+ return TREE_TYPE (t);
t = make_class ();
- IDENTIFIER_SIGNATURE_TYPE (sig) = t;
+ IDENTIFIER_SIGNATURE_TYPE (sig) = build_pointer_type (t);
TYPE_ARRAY_P (t) = 1;
if (TREE_CODE (el_name) == POINTER_TYPE)
@@ -345,6 +369,8 @@ build_java_array_type (element_type, length)
set_java_signature (t, sig);
set_super_info (0, t, object_type_node, 0);
+ if (TREE_CODE (element_type) == RECORD_TYPE)
+ element_type = promote_type (element_type);
TYPE_ARRAY_ELEMENT (t) = element_type;
/* Add length pseudo-field. */
@@ -366,7 +392,12 @@ build_java_array_type (element_type, length)
TYPE_ALIGN (t) = TYPE_ALIGN (element_type);
pop_obstacks ();
- layout_class (t);
+ /* We could layout_class, but that loads java.lang.Object prematurely.
+ * This is called by the parser, and it is a bad idea to do load_class
+ * in the middle of parsing, because of possible circularity problems. */
+ push_super_field (t, object_type_node);
+ layout_type (t);
+
return t;
}
@@ -411,6 +442,7 @@ static tree
parse_signature_type (ptr, limit)
const unsigned char **ptr, *limit;
{
+ tree type;
if ((*ptr) >= limit)
fatal ("bad signature string");
switch (*(*ptr))
@@ -425,13 +457,10 @@ parse_signature_type (ptr, limit)
case 'Z': (*ptr)++; return boolean_type_node;
case 'V': (*ptr)++; return void_type_node;
case '[':
- for ((*ptr)++; (*ptr) < limit && isdigit (**ptr); ) (*ptr)++;
- {
- tree element_type = parse_signature_type (ptr, limit);
- if (TREE_CODE (element_type) == RECORD_TYPE)
- element_type = promote_type (element_type);
- return build_java_array_type (element_type, -1);
- }
+ for ((*ptr)++; (*ptr) < limit && ISDIGIT (**ptr); ) (*ptr)++;
+ type = parse_signature_type (ptr, limit);
+ type = build_java_array_type (type, -1);
+ break;
case 'L':
{
const unsigned char *start = ++(*ptr);
@@ -444,11 +473,13 @@ parse_signature_type (ptr, limit)
break;
}
*ptr = str+1;
- return lookup_class (unmangle_classname (start, str - start));
+ type = lookup_class (unmangle_classname (start, str - start));
+ break;
}
default:
fatal ("unrecognized signature string");
}
+ return promote_type (type);
}
/* Parse a Java "mangled" signature string, starting at SIG_STRING,
@@ -471,14 +502,14 @@ parse_signature_string (sig_string, sig_length)
str++;
while (str < limit && str[0] != ')')
{
- tree argtype = promote_type (parse_signature_type (&str, limit));
+ tree argtype = parse_signature_type (&str, limit);
argtype_list = tree_cons (NULL_TREE, argtype, argtype_list);
}
if (str++, str >= limit)
fatal ("bad signature string");
- result_type = promote_type (parse_signature_type (&str, limit));
- result_type = build_function_type (result_type,
- nreverse (argtype_list));
+ result_type = parse_signature_type (&str, limit);
+ argtype_list = chainon (nreverse (argtype_list), end_params_node);
+ result_type = build_function_type (result_type, argtype_list);
}
else
result_type = parse_signature_type (&str, limit);
@@ -523,7 +554,7 @@ build_java_argument_signature (type)
tree args = TYPE_ARG_TYPES (type);
if (TREE_CODE (type) == METHOD_TYPE)
args = TREE_CHAIN (args); /* Skip "this" argument. */
- for (; args != NULL_TREE; args = TREE_CHAIN (args))
+ for (; args != end_params_node; args = TREE_CHAIN (args))
{
tree t = build_java_signature (TREE_VALUE (args));
obstack_grow (&temporary_obstack,
@@ -552,7 +583,6 @@ build_java_signature (type)
{
TYPE_LANG_SPECIFIC (type) = (struct lang_type *)
perm_calloc (1, sizeof (struct lang_type));
-
}
sig = TYPE_LANG_SPECIFIC (type)->signature;
if (sig == NULL_TREE)
@@ -606,7 +636,7 @@ build_java_signature (type)
obstack_grow (&temporary_obstack,
IDENTIFIER_POINTER (sig), IDENTIFIER_LENGTH (sig));
obstack_1grow (&temporary_obstack, ')');
-
+
t = build_java_signature (TREE_TYPE (type));
obstack_grow0 (&temporary_obstack,
IDENTIFIER_POINTER (t), IDENTIFIER_LENGTH (t));
@@ -668,7 +698,10 @@ lookup_argument_method (clas, method_name, method_signature)
method != NULL_TREE; method = TREE_CHAIN (method))
{
tree method_sig = build_java_argument_signature (TREE_TYPE (method));
- if (DECL_NAME (method) == method_name && method_sig == method_signature)
+ tree name = DECL_NAME (method);
+ if ((TREE_CODE (name) == EXPR_WITH_FILE_LOCATION ?
+ EXPR_WFL_NODE (name) : name) == method_name
+ && method_sig == method_signature)
return method;
}
clas = CLASSTYPE_SUPER (clas);
@@ -692,38 +725,13 @@ lookup_java_method (clas, method_name, method_signature)
method != NULL_TREE; method = TREE_CHAIN (method))
{
tree method_sig = build_java_signature (TREE_TYPE (method));
- if (DECL_NAME (method) == method_name && method_sig == method_signature)
- return method;
- }
- clas = CLASSTYPE_SUPER (clas);
- }
- return NULL_TREE;
-}
-
-/* Search in class CLAS (and its superclasses) for methods matching
- METHOD_NAME and METHOD_SIGNATURE. Return a list of FUNCTION_DECLs.
- When called from here, build_java_signature doesn't take the
- returned type into account. */
-
-tree
-match_java_method (clas, method_name, method_signature)
- tree clas, method_name, method_signature;
-{
- tree method;
- tree list = NULL_TREE;
- while (clas != NULL_TREE)
- {
- for (method = TYPE_METHODS (clas);
- method != NULL_TREE; method = TREE_CHAIN (method))
- {
- tree method_sig = build_java_argument_signature (TREE_TYPE (method));
if (DECL_NAME (method) == method_name
&& method_sig == method_signature)
- list = tree_cons (NULL_TREE, method, list);
+ return method;
}
clas = CLASSTYPE_SUPER (clas);
}
- return list;
+ return NULL_TREE;
}
/* Search in class CLAS for a constructor matching METHOD_SIGNATURE.
diff --git a/gcc/java/verify.c b/gcc/java/verify.c
index e0d4e097773..fd0550e87db 100644
--- a/gcc/java/verify.c
+++ b/gcc/java/verify.c
@@ -1,6 +1,6 @@
/* Handle verification of bytecoded methods for the GNU compiler for
the Java(TM) language.
- Copyright (C) 1997 Free Software Foundation, Inc.
+ Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -33,6 +33,9 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */
#include "java-except.h"
#include "toplev.h"
+static void push_pending_label PROTO ((tree));
+static tree merge_types PROTO ((tree, tree));
+
extern int stack_pointer;
/* During verification, start of the current subroutine (jsr target). */
@@ -45,7 +48,7 @@ tree pending_blocks;
/* Append TARGET_LABEL to the pending_block stack unless already in it. */
-void
+static void
push_pending_label (target_label)
tree target_label;
{
@@ -61,7 +64,7 @@ push_pending_label (target_label)
Merge the type state etc.
Return NULL on sucess, or an error message on failure. */
-static char *
+static const char *
check_pending_block (target_label)
tree target_label;
{
@@ -102,7 +105,7 @@ check_pending_block (target_label)
For reference types, return the common super-class.
Return TYPE_UNKNOWN if the types cannot be merged. */
-tree
+static tree
merge_types (type1, type2)
tree type1, type2;
{
@@ -150,6 +153,32 @@ merge_types (type1, type2)
}
return object_ptr_type_node;
}
+
+ if (CLASS_INTERFACE (TYPE_NAME (tt1)))
+ {
+ if (CLASS_INTERFACE (TYPE_NAME (tt2)))
+ {
+ /* This is a kludge, but matches what Sun's verifier does.
+ It can be tricked, but is safe as long as type errors
+ (i.e. interface method calls) are caught at run-time. */
+ return object_ptr_type_node;
+ }
+ else
+ {
+ if (can_widen_reference_to (tt2, tt1))
+ return type1;
+ else
+ return TYPE_UNKNOWN;
+ }
+ }
+ else if (CLASS_INTERFACE (TYPE_NAME (tt2)))
+ {
+ if (can_widen_reference_to (tt1, tt2))
+ return type2;
+ else
+ return TYPE_UNKNOWN;
+ }
+
type1 = tt1;
type2 = tt2;
@@ -306,7 +335,7 @@ verify_jvm_instructions (jcf, byte_ops, length)
int PC;
int oldpc; /* PC of start of instruction. */
int prevpc; /* If >= 0, PC of previous instruction. */
- char *message;
+ const char *message;
int i;
register unsigned char *p;
struct eh_range *prev_eh_ranges = NULL_EH_RANGE;
@@ -698,7 +727,6 @@ verify_jvm_instructions (jcf, byte_ops, length)
int index = IMMEDIATE_u2;
tree self_type = get_class_constant
(jcf, COMPONENT_REF_CLASS_INDEX (&current_jcf->cpool, index));
- tree field_name = COMPONENT_REF_NAME (&current_jcf->cpool, index);
tree field_signature = COMPONENT_REF_SIGNATURE (&current_jcf->cpool, index);
tree field_type = get_type_from_signature (field_signature);
if (is_putting)
@@ -761,7 +789,6 @@ verify_jvm_instructions (jcf, byte_ops, length)
break;
/* ... else fall through ... */
default:
- bad_ldc:
VERIFICATION_ERROR ("bad constant pool tag in ldc");
}
if (type == int_type_node)
@@ -856,10 +883,12 @@ verify_jvm_instructions (jcf, byte_ops, length)
case OPCODE_saload: type = promote_type (short_type_node); goto aload;
aload:
pop_type (int_type_node);
- type = pop_type (ptr_type_node);
- if (! is_array_type_p (type))
+ tmp = pop_type (ptr_type_node);
+ if (is_array_type_p (tmp))
+ type = TYPE_ARRAY_ELEMENT (TREE_TYPE (tmp));
+ else if (tmp != TYPE_NULL)
VERIFICATION_ERROR ("array load from non-array type");
- push_type (TYPE_ARRAY_ELEMENT (TREE_TYPE (type)));
+ push_type (type);
break;
case OPCODE_anewarray:
@@ -930,14 +959,14 @@ verify_jvm_instructions (jcf, byte_ops, length)
case OPCODE_instanceof:
pop_type (ptr_type_node);
get_class_constant (current_jcf, IMMEDIATE_u2);
- push_type (integer_type_node);
+ push_type (int_type_node);
break;
case OPCODE_tableswitch:
{
- jint default_val, low, high;
+ jint low, high;
- pop_type (integer_type_node);
+ pop_type (int_type_node);
while (PC%4)
{
if (byte_ops[PC++])
@@ -952,6 +981,7 @@ verify_jvm_instructions (jcf, byte_ops, length)
while (low++ <= high)
PUSH_PENDING (lookup_label (oldpc + IMMEDIATE_s4));
+ INVALIDATE_PC;
break;
}
@@ -959,7 +989,7 @@ verify_jvm_instructions (jcf, byte_ops, length)
{
jint npairs, last, not_registered = 1;
- pop_type (integer_type_node);
+ pop_type (int_type_node);
while (PC%4)
{
if (byte_ops[PC++])
@@ -983,6 +1013,7 @@ verify_jvm_instructions (jcf, byte_ops, length)
last = match;
PUSH_PENDING (lookup_label (oldpc + IMMEDIATE_s4));
}
+ INVALIDATE_PC;
break;
}
@@ -1009,10 +1040,10 @@ verify_jvm_instructions (jcf, byte_ops, length)
int nlocals = DECL_MAX_LOCALS (current_function_decl);
index = nlocals + DECL_MAX_STACK (current_function_decl);
return_type_map = make_tree_vec (index);
- while (--index >= nlocals)
- TREE_VEC_ELT (return_type_map, index) = TYPE_UNKNOWN;
- while (--index >= 0)
- TREE_VEC_ELT (return_type_map, index) = TYPE_UNUSED;
+ while (index > nlocals)
+ TREE_VEC_ELT (return_type_map, --index) = TYPE_UNKNOWN;
+ while (index > 0)
+ TREE_VEC_ELT (return_type_map, --index) = TYPE_UNUSED;
LABEL_RETURN_LABEL (target)
= build_decl (LABEL_DECL, NULL_TREE, TREE_TYPE (target));
LABEL_PC (LABEL_RETURN_LABEL (target)) = -1;
diff --git a/gcc/java/zextract.c b/gcc/java/zextract.c
index 39bb06c1251..5e170b3a7bb 100644
--- a/gcc/java/zextract.c
+++ b/gcc/java/zextract.c
@@ -2,7 +2,7 @@
This extracts a member from a .zip file, but does not handle
uncompression (since that is not needed for classes.zip).
- Copyright (C) 1996 Free Software Foundation, Inc.
+ Copyright (C) 1996, 97-98, 1999 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
@@ -25,19 +25,14 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */
/* Written by Per Bothner <bothner@cygnus.com>, February 1996. */
+#include "config.h"
+#include "system.h"
#include "zipfile.h"
-
/* This stuff is partly based on the 28 August 1994 public release of the
Info-ZIP group's portable UnZip zipfile-extraction program (and related
utilities). */
-#include <stdio.h>
-#ifdef __STDC__
-#include <stdlib.h>
-#endif
-#include <errno.h> /* used in mapname() */
-
/*************/
/* Defines */
/*************/
diff --git a/gcc/java/zipfile.h b/gcc/java/zipfile.h
index 5d71184139b..98a698ff821 100644
--- a/gcc/java/zipfile.h
+++ b/gcc/java/zipfile.h
@@ -1,6 +1,6 @@
/* Definitions for using a zipped' archive.
- Copyright (C) 1996 Free Software Foundation, Inc.
+ Copyright (C) 1996, 97-98, 1999 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
@@ -56,3 +56,10 @@ extern struct ZipFileCache *SeenZipFiles;
#define ZIPDIR_NEXT(ZIPD) \
((ZipDirectory*)((char*)(ZIPD)+(ZIPD)->direntry_size))
#define ZIPMAGIC 0x504b0304
+
+extern ZipFile * opendir_in_zip PROTO ((const char *, int));
+extern int read_zip_archive PROTO ((ZipFile *));
+#ifdef JCF_ZIP
+extern int open_in_zip PROTO ((struct JCF *, const char *,
+ const char *, int));
+#endif
diff --git a/gcc/jump.c b/gcc/jump.c
index 5eebbac2452..1070005c8ac 100644
--- a/gcc/jump.c
+++ b/gcc/jump.c
@@ -1,5 +1,5 @@
/* Optimize jump instructions, for GNU compiler.
- Copyright (C) 1987, 88, 89, 91-97, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1987, 88, 89, 91-98, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -60,6 +60,7 @@ Boston, MA 02111-1307, USA. */
#include "regs.h"
#include "insn-config.h"
#include "insn-flags.h"
+#include "insn-attr.h"
#include "recog.h"
#include "expr.h"
#include "real.h"
@@ -105,6 +106,12 @@ int can_reach_end;
static int cross_jump_death_matters = 0;
+static int init_label_info PROTO((rtx));
+static void delete_barrier_successors PROTO((rtx));
+static void mark_all_labels PROTO((rtx, int));
+static rtx delete_unreferenced_labels PROTO((rtx));
+static void delete_noop_moves PROTO((rtx));
+static int calculate_can_reach_end PROTO((rtx, int, int));
static int duplicate_loop_exit_test PROTO((rtx));
static void find_cross_jump PROTO((rtx, rtx, int, rtx *, rtx *));
static void do_cross_jump PROTO((rtx, rtx, rtx));
@@ -146,7 +153,7 @@ jump_optimize (f, cross_jump, noop_moves, after_regscan)
int noop_moves;
int after_regscan;
{
- register rtx insn, next, note;
+ register rtx insn, next;
int changed;
int old_max_reg;
int first = 1;
@@ -154,51 +161,15 @@ jump_optimize (f, cross_jump, noop_moves, after_regscan)
rtx last_insn;
cross_jump_death_matters = (cross_jump == 2);
+ max_uid = init_label_info (f) + 1;
- /* Initialize LABEL_NUSES and JUMP_LABEL fields. Delete any REG_LABEL
- notes whose labels don't occur in the insn any more. */
+ /* If we are performing cross jump optimizations, then initialize
+ tables mapping UIDs to EH regions to avoid incorrect movement
+ of insns from one EH region to another. */
+ if (flag_exceptions && cross_jump)
+ init_insn_eh_region (f, max_uid);
- for (insn = f; insn; insn = NEXT_INSN (insn))
- {
- if (GET_CODE (insn) == CODE_LABEL)
- LABEL_NUSES (insn) = (LABEL_PRESERVE_P (insn) != 0);
- else if (GET_CODE (insn) == JUMP_INSN)
- JUMP_LABEL (insn) = 0;
- else if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN)
- for (note = REG_NOTES (insn); note; note = next)
- {
- next = XEXP (note, 1);
- if (REG_NOTE_KIND (note) == REG_LABEL
- && ! reg_mentioned_p (XEXP (note, 0), PATTERN (insn)))
- remove_note (insn, note);
- }
-
- if (INSN_UID (insn) > max_uid)
- max_uid = INSN_UID (insn);
- }
-
- max_uid++;
-
- /* Delete insns following barriers, up to next label. */
-
- for (insn = f; insn;)
- {
- if (GET_CODE (insn) == BARRIER)
- {
- insn = NEXT_INSN (insn);
- while (insn != 0 && GET_CODE (insn) != CODE_LABEL)
- {
- if (GET_CODE (insn) == NOTE
- && NOTE_LINE_NUMBER (insn) != NOTE_INSN_FUNCTION_END)
- insn = NEXT_INSN (insn);
- else
- insn = delete_insn (insn);
- }
- /* INSN is now the code_label. */
- }
- else
- insn = NEXT_INSN (insn);
- }
+ delete_barrier_successors (f);
/* Leave some extra room for labels and duplicate exit test insns
we make. */
@@ -206,32 +177,7 @@ jump_optimize (f, cross_jump, noop_moves, after_regscan)
jump_chain = (rtx *) alloca (max_jump_chain * sizeof (rtx));
bzero ((char *) jump_chain, max_jump_chain * sizeof (rtx));
- /* Mark the label each jump jumps to.
- Combine consecutive labels, and count uses of labels.
-
- For each label, make a chain (using `jump_chain')
- of all the *unconditional* jumps that jump to it;
- also make a chain of all returns. */
-
- for (insn = f; insn; insn = NEXT_INSN (insn))
- if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
- {
- mark_jump_label (PATTERN (insn), insn, cross_jump);
- if (! INSN_DELETED_P (insn) && GET_CODE (insn) == JUMP_INSN)
- {
- if (JUMP_LABEL (insn) != 0 && simplejump_p (insn))
- {
- jump_chain[INSN_UID (insn)]
- = jump_chain[INSN_UID (JUMP_LABEL (insn))];
- jump_chain[INSN_UID (JUMP_LABEL (insn))] = insn;
- }
- if (GET_CODE (PATTERN (insn)) == RETURN)
- {
- jump_chain[INSN_UID (insn)] = jump_chain[0];
- jump_chain[0] = insn;
- }
- }
- }
+ mark_all_labels (f, cross_jump);
/* Keep track of labels used from static data;
they cannot ever be deleted. */
@@ -249,51 +195,11 @@ jump_optimize (f, cross_jump, noop_moves, after_regscan)
exception_optimize ();
- /* Delete all labels already not referenced.
- Also find the last insn. */
-
- last_insn = 0;
- for (insn = f; insn; )
- {
- if (GET_CODE (insn) == CODE_LABEL && LABEL_NUSES (insn) == 0)
- insn = delete_insn (insn);
- else
- {
- last_insn = insn;
- insn = NEXT_INSN (insn);
- }
- }
+ last_insn = delete_unreferenced_labels (f);
if (!optimize)
{
- /* See if there is still a NOTE_INSN_FUNCTION_END in this function.
- If so record that this function can drop off the end. */
-
- insn = last_insn;
- {
- int n_labels = 1;
- while (insn
- /* One label can follow the end-note: the return label. */
- && ((GET_CODE (insn) == CODE_LABEL && n_labels-- > 0)
- /* Ordinary insns can follow it if returning a structure. */
- || GET_CODE (insn) == INSN
- /* If machine uses explicit RETURN insns, no epilogue,
- then one of them follows the note. */
- || (GET_CODE (insn) == JUMP_INSN
- && GET_CODE (PATTERN (insn)) == RETURN)
- /* A barrier can follow the return insn. */
- || GET_CODE (insn) == BARRIER
- /* Other kinds of notes can follow also. */
- || (GET_CODE (insn) == NOTE
- && NOTE_LINE_NUMBER (insn) != NOTE_INSN_FUNCTION_END)))
- insn = PREV_INSN (insn);
- }
-
- /* Report if control can fall through at the end of the function. */
- if (insn && GET_CODE (insn) == NOTE
- && NOTE_LINE_NUMBER (insn) == NOTE_INSN_FUNCTION_END
- && ! INSN_DELETED_P (insn))
- can_reach_end = 1;
+ can_reach_end = calculate_can_reach_end (last_insn, 1, 0);
/* Zero the "deleted" flag of all the "deleted" insns. */
for (insn = f; insn; insn = NEXT_INSN (insn))
@@ -324,245 +230,7 @@ jump_optimize (f, cross_jump, noop_moves, after_regscan)
#endif
if (noop_moves)
- for (insn = f; insn; )
- {
- next = NEXT_INSN (insn);
-
- if (GET_CODE (insn) == INSN)
- {
- register rtx body = PATTERN (insn);
-
-/* Combine stack_adjusts with following push_insns. */
-#ifdef PUSH_ROUNDING
- if (GET_CODE (body) == SET
- && SET_DEST (body) == stack_pointer_rtx
- && GET_CODE (SET_SRC (body)) == PLUS
- && XEXP (SET_SRC (body), 0) == stack_pointer_rtx
- && GET_CODE (XEXP (SET_SRC (body), 1)) == CONST_INT
- && INTVAL (XEXP (SET_SRC (body), 1)) > 0)
- {
- rtx p;
- rtx stack_adjust_insn = insn;
- int stack_adjust_amount = INTVAL (XEXP (SET_SRC (body), 1));
- int total_pushed = 0;
- int pushes = 0;
-
- /* Find all successive push insns. */
- p = insn;
- /* Don't convert more than three pushes;
- that starts adding too many displaced addresses
- and the whole thing starts becoming a losing
- proposition. */
- while (pushes < 3)
- {
- rtx pbody, dest;
- p = next_nonnote_insn (p);
- if (p == 0 || GET_CODE (p) != INSN)
- break;
- pbody = PATTERN (p);
- if (GET_CODE (pbody) != SET)
- break;
- dest = SET_DEST (pbody);
- /* Allow a no-op move between the adjust and the push. */
- if (GET_CODE (dest) == REG
- && GET_CODE (SET_SRC (pbody)) == REG
- && REGNO (dest) == REGNO (SET_SRC (pbody)))
- continue;
- if (! (GET_CODE (dest) == MEM
- && GET_CODE (XEXP (dest, 0)) == POST_INC
- && XEXP (XEXP (dest, 0), 0) == stack_pointer_rtx))
- break;
- pushes++;
- if (total_pushed + GET_MODE_SIZE (GET_MODE (SET_DEST (pbody)))
- > stack_adjust_amount)
- break;
- total_pushed += GET_MODE_SIZE (GET_MODE (SET_DEST (pbody)));
- }
-
- /* Discard the amount pushed from the stack adjust;
- maybe eliminate it entirely. */
- if (total_pushed >= stack_adjust_amount)
- {
- delete_computation (stack_adjust_insn);
- total_pushed = stack_adjust_amount;
- }
- else
- XEXP (SET_SRC (PATTERN (stack_adjust_insn)), 1)
- = GEN_INT (stack_adjust_amount - total_pushed);
-
- /* Change the appropriate push insns to ordinary stores. */
- p = insn;
- while (total_pushed > 0)
- {
- rtx pbody, dest;
- p = next_nonnote_insn (p);
- if (GET_CODE (p) != INSN)
- break;
- pbody = PATTERN (p);
- if (GET_CODE (pbody) != SET)
- break;
- dest = SET_DEST (pbody);
- /* Allow a no-op move between the adjust and the push. */
- if (GET_CODE (dest) == REG
- && GET_CODE (SET_SRC (pbody)) == REG
- && REGNO (dest) == REGNO (SET_SRC (pbody)))
- continue;
- if (! (GET_CODE (dest) == MEM
- && GET_CODE (XEXP (dest, 0)) == POST_INC
- && XEXP (XEXP (dest, 0), 0) == stack_pointer_rtx))
- break;
- total_pushed -= GET_MODE_SIZE (GET_MODE (SET_DEST (pbody)));
- /* If this push doesn't fully fit in the space
- of the stack adjust that we deleted,
- make another stack adjust here for what we
- didn't use up. There should be peepholes
- to recognize the resulting sequence of insns. */
- if (total_pushed < 0)
- {
- emit_insn_before (gen_add2_insn (stack_pointer_rtx,
- GEN_INT (- total_pushed)),
- p);
- break;
- }
- XEXP (dest, 0)
- = plus_constant (stack_pointer_rtx, total_pushed);
- }
- }
-#endif
-
- /* Detect and delete no-op move instructions
- resulting from not allocating a parameter in a register. */
-
- if (GET_CODE (body) == SET
- && (SET_DEST (body) == SET_SRC (body)
- || (GET_CODE (SET_DEST (body)) == MEM
- && GET_CODE (SET_SRC (body)) == MEM
- && rtx_equal_p (SET_SRC (body), SET_DEST (body))))
- && ! (GET_CODE (SET_DEST (body)) == MEM
- && MEM_VOLATILE_P (SET_DEST (body)))
- && ! (GET_CODE (SET_SRC (body)) == MEM
- && MEM_VOLATILE_P (SET_SRC (body))))
- delete_computation (insn);
-
- /* Detect and ignore no-op move instructions
- resulting from smart or fortuitous register allocation. */
-
- else if (GET_CODE (body) == SET)
- {
- int sreg = true_regnum (SET_SRC (body));
- int dreg = true_regnum (SET_DEST (body));
-
- if (sreg == dreg && sreg >= 0)
- delete_insn (insn);
- else if (sreg >= 0 && dreg >= 0)
- {
- rtx trial;
- rtx tem = find_equiv_reg (NULL_RTX, insn, 0,
- sreg, NULL_PTR, dreg,
- GET_MODE (SET_SRC (body)));
-
- if (tem != 0
- && GET_MODE (tem) == GET_MODE (SET_DEST (body)))
- {
- /* DREG may have been the target of a REG_DEAD note in
- the insn which makes INSN redundant. If so, reorg
- would still think it is dead. So search for such a
- note and delete it if we find it. */
- if (! find_regno_note (insn, REG_UNUSED, dreg))
- for (trial = prev_nonnote_insn (insn);
- trial && GET_CODE (trial) != CODE_LABEL;
- trial = prev_nonnote_insn (trial))
- if (find_regno_note (trial, REG_DEAD, dreg))
- {
- remove_death (dreg, trial);
- break;
- }
-
- /* Deleting insn could lose a death-note for SREG. */
- if ((trial = find_regno_note (insn, REG_DEAD, sreg)))
- {
- /* Change this into a USE so that we won't emit
- code for it, but still can keep the note. */
- PATTERN (insn)
- = gen_rtx_USE (VOIDmode, XEXP (trial, 0));
- INSN_CODE (insn) = -1;
- /* Remove all reg notes but the REG_DEAD one. */
- REG_NOTES (insn) = trial;
- XEXP (trial, 1) = NULL_RTX;
- }
- else
- delete_insn (insn);
- }
- }
- else if (dreg >= 0 && CONSTANT_P (SET_SRC (body))
- && find_equiv_reg (SET_SRC (body), insn, 0, dreg,
- NULL_PTR, 0,
- GET_MODE (SET_DEST (body))))
- {
- /* This handles the case where we have two consecutive
- assignments of the same constant to pseudos that didn't
- get a hard reg. Each SET from the constant will be
- converted into a SET of the spill register and an
- output reload will be made following it. This produces
- two loads of the same constant into the same spill
- register. */
-
- rtx in_insn = insn;
-
- /* Look back for a death note for the first reg.
- If there is one, it is no longer accurate. */
- while (in_insn && GET_CODE (in_insn) != CODE_LABEL)
- {
- if ((GET_CODE (in_insn) == INSN
- || GET_CODE (in_insn) == JUMP_INSN)
- && find_regno_note (in_insn, REG_DEAD, dreg))
- {
- remove_death (dreg, in_insn);
- break;
- }
- in_insn = PREV_INSN (in_insn);
- }
-
- /* Delete the second load of the value. */
- delete_insn (insn);
- }
- }
- else if (GET_CODE (body) == PARALLEL)
- {
- /* If each part is a set between two identical registers or
- a USE or CLOBBER, delete the insn. */
- int i, sreg, dreg;
- rtx tem;
-
- for (i = XVECLEN (body, 0) - 1; i >= 0; i--)
- {
- tem = XVECEXP (body, 0, i);
- if (GET_CODE (tem) == USE || GET_CODE (tem) == CLOBBER)
- continue;
-
- if (GET_CODE (tem) != SET
- || (sreg = true_regnum (SET_SRC (tem))) < 0
- || (dreg = true_regnum (SET_DEST (tem))) < 0
- || dreg != sreg)
- break;
- }
-
- if (i < 0)
- delete_insn (insn);
- }
- /* Also delete insns to store bit fields if they are no-ops. */
- /* Not worth the hair to detect this in the big-endian case. */
- else if (! BYTES_BIG_ENDIAN
- && GET_CODE (body) == SET
- && GET_CODE (SET_DEST (body)) == ZERO_EXTRACT
- && XEXP (SET_DEST (body), 2) == const0_rtx
- && XEXP (SET_DEST (body), 0) == SET_SRC (body)
- && ! (GET_CODE (SET_SRC (body)) == MEM
- && MEM_VOLATILE_P (SET_SRC (body))))
- delete_insn (insn);
- }
- insn = next;
- }
+ delete_noop_moves (f);
/* If we haven't yet gotten to reload and we have just run regscan,
delete any insn that sets a register that isn't used elsewhere.
@@ -851,7 +519,8 @@ jump_optimize (f, cross_jump, noop_moves, after_regscan)
|| ! modified_between_p (SET_SRC (temp4), p, temp2))
/* Verify that registers used by the jump are not clobbered
by the instruction being moved. */
- && ! modified_between_p (PATTERN (temp), temp2,
+ && ! regs_set_between_p (PATTERN (temp),
+ PREV_INSN (temp2),
NEXT_INSN (temp2)))
{
emit_insn_after_with_line_notes (PATTERN (temp2), p, temp2);
@@ -952,7 +621,8 @@ jump_optimize (f, cross_jump, noop_moves, after_regscan)
&& ! modified_between_p (SET_SRC (temp4), insert_after, temp)
/* Verify that registers used by the jump are not clobbered
by the instruction being moved. */
- && ! modified_between_p (PATTERN (temp), temp3,
+ && ! regs_set_between_p (PATTERN (temp),
+ PREV_INSN (temp3),
NEXT_INSN (temp3))
&& invert_jump (temp, JUMP_LABEL (insn)))
{
@@ -2362,41 +2032,460 @@ jump_optimize (f, cross_jump, noop_moves, after_regscan)
}
#endif
- /* See if there is still a NOTE_INSN_FUNCTION_END in this function.
- If so, delete it, and record that this function can drop off the end. */
+ can_reach_end = calculate_can_reach_end (last_insn, 0, 1);
+
+ /* Show JUMP_CHAIN no longer valid. */
+ jump_chain = 0;
+}
+
+/* Initialize LABEL_NUSES and JUMP_LABEL fields. Delete any REG_LABEL
+ notes whose labels don't occur in the insn any more. Returns the
+ largest INSN_UID found. */
+static int
+init_label_info (f)
+ rtx f;
+{
+ int largest_uid = 0;
+ rtx insn;
+
+ for (insn = f; insn; insn = NEXT_INSN (insn))
+ {
+ if (GET_CODE (insn) == CODE_LABEL)
+ LABEL_NUSES (insn) = (LABEL_PRESERVE_P (insn) != 0);
+ else if (GET_CODE (insn) == JUMP_INSN)
+ JUMP_LABEL (insn) = 0;
+ else if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN)
+ {
+ rtx note, next;
+
+ for (note = REG_NOTES (insn); note; note = next)
+ {
+ next = XEXP (note, 1);
+ if (REG_NOTE_KIND (note) == REG_LABEL
+ && ! reg_mentioned_p (XEXP (note, 0), PATTERN (insn)))
+ remove_note (insn, note);
+ }
+ }
+ if (INSN_UID (insn) > largest_uid)
+ largest_uid = INSN_UID (insn);
+ }
+
+ return largest_uid;
+}
+
+/* Delete insns following barriers, up to next label.
+
+ Also delete no-op jumps created by gcse. */
+static void
+delete_barrier_successors (f)
+ rtx f;
+{
+ rtx insn;
+
+ for (insn = f; insn;)
+ {
+ if (GET_CODE (insn) == BARRIER)
+ {
+ insn = NEXT_INSN (insn);
+ while (insn != 0 && GET_CODE (insn) != CODE_LABEL)
+ {
+ if (GET_CODE (insn) == NOTE
+ && NOTE_LINE_NUMBER (insn) != NOTE_INSN_FUNCTION_END)
+ insn = NEXT_INSN (insn);
+ else
+ insn = delete_insn (insn);
+ }
+ /* INSN is now the code_label. */
+ }
+ /* Also remove (set (pc) (pc)) insns which can be created by
+ gcse. We eliminate such insns now to avoid having them
+ cause problems later. */
+ else if (GET_CODE (insn) == JUMP_INSN
+ && SET_SRC (PATTERN (insn)) == pc_rtx
+ && SET_DEST (PATTERN (insn)) == pc_rtx)
+ insn = delete_insn (insn);
+
+ else
+ insn = NEXT_INSN (insn);
+ }
+}
+
+/* Mark the label each jump jumps to.
+ Combine consecutive labels, and count uses of labels.
+
+ For each label, make a chain (using `jump_chain')
+ of all the *unconditional* jumps that jump to it;
+ also make a chain of all returns.
+
+ CROSS_JUMP indicates whether we are doing cross jumping
+ and if we are whether we will be paying attention to
+ death notes or not. */
+
+static void
+mark_all_labels (f, cross_jump)
+ rtx f;
+ int cross_jump;
+{
+ rtx insn;
+
+ for (insn = f; insn; insn = NEXT_INSN (insn))
+ if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
+ {
+ mark_jump_label (PATTERN (insn), insn, cross_jump);
+ if (! INSN_DELETED_P (insn) && GET_CODE (insn) == JUMP_INSN)
+ {
+ if (JUMP_LABEL (insn) != 0 && simplejump_p (insn))
+ {
+ jump_chain[INSN_UID (insn)]
+ = jump_chain[INSN_UID (JUMP_LABEL (insn))];
+ jump_chain[INSN_UID (JUMP_LABEL (insn))] = insn;
+ }
+ if (GET_CODE (PATTERN (insn)) == RETURN)
+ {
+ jump_chain[INSN_UID (insn)] = jump_chain[0];
+ jump_chain[0] = insn;
+ }
+ }
+ }
+}
+
+/* Delete all labels already not referenced.
+ Also find and return the last insn. */
+
+static rtx
+delete_unreferenced_labels (f)
+ rtx f;
+{
+ rtx final = NULL_RTX;
+ rtx insn;
+
+ for (insn = f; insn; )
+ {
+ if (GET_CODE (insn) == CODE_LABEL && LABEL_NUSES (insn) == 0)
+ insn = delete_insn (insn);
+ else
+ {
+ final = insn;
+ insn = NEXT_INSN (insn);
+ }
+ }
+
+ return final;
+}
+
+/* Delete various simple forms of moves which have no necessary
+ side effect. */
+
+static void
+delete_noop_moves (f)
+ rtx f;
+{
+ rtx insn, next;
+
+ for (insn = f; insn; )
+ {
+ next = NEXT_INSN (insn);
+
+ if (GET_CODE (insn) == INSN)
+ {
+ register rtx body = PATTERN (insn);
+
+/* Combine stack_adjusts with following push_insns. */
+#ifdef PUSH_ROUNDING
+ if (GET_CODE (body) == SET
+ && SET_DEST (body) == stack_pointer_rtx
+ && GET_CODE (SET_SRC (body)) == PLUS
+ && XEXP (SET_SRC (body), 0) == stack_pointer_rtx
+ && GET_CODE (XEXP (SET_SRC (body), 1)) == CONST_INT
+ && INTVAL (XEXP (SET_SRC (body), 1)) > 0)
+ {
+ rtx p;
+ rtx stack_adjust_insn = insn;
+ int stack_adjust_amount = INTVAL (XEXP (SET_SRC (body), 1));
+ int total_pushed = 0;
+ int pushes = 0;
+
+ /* Find all successive push insns. */
+ p = insn;
+ /* Don't convert more than three pushes;
+ that starts adding too many displaced addresses
+ and the whole thing starts becoming a losing
+ proposition. */
+ while (pushes < 3)
+ {
+ rtx pbody, dest;
+ p = next_nonnote_insn (p);
+ if (p == 0 || GET_CODE (p) != INSN)
+ break;
+ pbody = PATTERN (p);
+ if (GET_CODE (pbody) != SET)
+ break;
+ dest = SET_DEST (pbody);
+ /* Allow a no-op move between the adjust and the push. */
+ if (GET_CODE (dest) == REG
+ && GET_CODE (SET_SRC (pbody)) == REG
+ && REGNO (dest) == REGNO (SET_SRC (pbody)))
+ continue;
+ if (! (GET_CODE (dest) == MEM
+ && GET_CODE (XEXP (dest, 0)) == POST_INC
+ && XEXP (XEXP (dest, 0), 0) == stack_pointer_rtx))
+ break;
+ pushes++;
+ if (total_pushed + GET_MODE_SIZE (GET_MODE (SET_DEST (pbody)))
+ > stack_adjust_amount)
+ break;
+ total_pushed += GET_MODE_SIZE (GET_MODE (SET_DEST (pbody)));
+ }
+
+ /* Discard the amount pushed from the stack adjust;
+ maybe eliminate it entirely. */
+ if (total_pushed >= stack_adjust_amount)
+ {
+ delete_computation (stack_adjust_insn);
+ total_pushed = stack_adjust_amount;
+ }
+ else
+ XEXP (SET_SRC (PATTERN (stack_adjust_insn)), 1)
+ = GEN_INT (stack_adjust_amount - total_pushed);
+
+ /* Change the appropriate push insns to ordinary stores. */
+ p = insn;
+ while (total_pushed > 0)
+ {
+ rtx pbody, dest;
+ p = next_nonnote_insn (p);
+ if (GET_CODE (p) != INSN)
+ break;
+ pbody = PATTERN (p);
+ if (GET_CODE (pbody) != SET)
+ break;
+ dest = SET_DEST (pbody);
+ /* Allow a no-op move between the adjust and the push. */
+ if (GET_CODE (dest) == REG
+ && GET_CODE (SET_SRC (pbody)) == REG
+ && REGNO (dest) == REGNO (SET_SRC (pbody)))
+ continue;
+ if (! (GET_CODE (dest) == MEM
+ && GET_CODE (XEXP (dest, 0)) == POST_INC
+ && XEXP (XEXP (dest, 0), 0) == stack_pointer_rtx))
+ break;
+ total_pushed -= GET_MODE_SIZE (GET_MODE (SET_DEST (pbody)));
+ /* If this push doesn't fully fit in the space
+ of the stack adjust that we deleted,
+ make another stack adjust here for what we
+ didn't use up. There should be peepholes
+ to recognize the resulting sequence of insns. */
+ if (total_pushed < 0)
+ {
+ emit_insn_before (gen_add2_insn (stack_pointer_rtx,
+ GEN_INT (- total_pushed)),
+ p);
+ break;
+ }
+ XEXP (dest, 0)
+ = plus_constant (stack_pointer_rtx, total_pushed);
+ }
+ }
+#endif
+
+ /* Detect and delete no-op move instructions
+ resulting from not allocating a parameter in a register. */
+
+ if (GET_CODE (body) == SET
+ && (SET_DEST (body) == SET_SRC (body)
+ || (GET_CODE (SET_DEST (body)) == MEM
+ && GET_CODE (SET_SRC (body)) == MEM
+ && rtx_equal_p (SET_SRC (body), SET_DEST (body))))
+ && ! (GET_CODE (SET_DEST (body)) == MEM
+ && MEM_VOLATILE_P (SET_DEST (body)))
+ && ! (GET_CODE (SET_SRC (body)) == MEM
+ && MEM_VOLATILE_P (SET_SRC (body))))
+ delete_computation (insn);
+
+ /* Detect and ignore no-op move instructions
+ resulting from smart or fortuitous register allocation. */
+
+ else if (GET_CODE (body) == SET)
+ {
+ int sreg = true_regnum (SET_SRC (body));
+ int dreg = true_regnum (SET_DEST (body));
+
+ if (sreg == dreg && sreg >= 0)
+ delete_insn (insn);
+ else if (sreg >= 0 && dreg >= 0)
+ {
+ rtx trial;
+ rtx tem = find_equiv_reg (NULL_RTX, insn, 0,
+ sreg, NULL_PTR, dreg,
+ GET_MODE (SET_SRC (body)));
+
+ if (tem != 0
+ && GET_MODE (tem) == GET_MODE (SET_DEST (body)))
+ {
+ /* DREG may have been the target of a REG_DEAD note in
+ the insn which makes INSN redundant. If so, reorg
+ would still think it is dead. So search for such a
+ note and delete it if we find it. */
+ if (! find_regno_note (insn, REG_UNUSED, dreg))
+ for (trial = prev_nonnote_insn (insn);
+ trial && GET_CODE (trial) != CODE_LABEL;
+ trial = prev_nonnote_insn (trial))
+ if (find_regno_note (trial, REG_DEAD, dreg))
+ {
+ remove_death (dreg, trial);
+ break;
+ }
+
+ /* Deleting insn could lose a death-note for SREG. */
+ if ((trial = find_regno_note (insn, REG_DEAD, sreg)))
+ {
+ /* Change this into a USE so that we won't emit
+ code for it, but still can keep the note. */
+ PATTERN (insn)
+ = gen_rtx_USE (VOIDmode, XEXP (trial, 0));
+ INSN_CODE (insn) = -1;
+ /* Remove all reg notes but the REG_DEAD one. */
+ REG_NOTES (insn) = trial;
+ XEXP (trial, 1) = NULL_RTX;
+ }
+ else
+ delete_insn (insn);
+ }
+ }
+ else if (dreg >= 0 && CONSTANT_P (SET_SRC (body))
+ && find_equiv_reg (SET_SRC (body), insn, 0, dreg,
+ NULL_PTR, 0,
+ GET_MODE (SET_DEST (body))))
+ {
+ /* This handles the case where we have two consecutive
+ assignments of the same constant to pseudos that didn't
+ get a hard reg. Each SET from the constant will be
+ converted into a SET of the spill register and an
+ output reload will be made following it. This produces
+ two loads of the same constant into the same spill
+ register. */
+
+ rtx in_insn = insn;
+
+ /* Look back for a death note for the first reg.
+ If there is one, it is no longer accurate. */
+ while (in_insn && GET_CODE (in_insn) != CODE_LABEL)
+ {
+ if ((GET_CODE (in_insn) == INSN
+ || GET_CODE (in_insn) == JUMP_INSN)
+ && find_regno_note (in_insn, REG_DEAD, dreg))
+ {
+ remove_death (dreg, in_insn);
+ break;
+ }
+ in_insn = PREV_INSN (in_insn);
+ }
+
+ /* Delete the second load of the value. */
+ delete_insn (insn);
+ }
+ }
+ else if (GET_CODE (body) == PARALLEL)
+ {
+ /* If each part is a set between two identical registers or
+ a USE or CLOBBER, delete the insn. */
+ int i, sreg, dreg;
+ rtx tem;
+
+ for (i = XVECLEN (body, 0) - 1; i >= 0; i--)
+ {
+ tem = XVECEXP (body, 0, i);
+ if (GET_CODE (tem) == USE || GET_CODE (tem) == CLOBBER)
+ continue;
+
+ if (GET_CODE (tem) != SET
+ || (sreg = true_regnum (SET_SRC (tem))) < 0
+ || (dreg = true_regnum (SET_DEST (tem))) < 0
+ || dreg != sreg)
+ break;
+ }
+
+ if (i < 0)
+ delete_insn (insn);
+ }
+ /* Also delete insns to store bit fields if they are no-ops. */
+ /* Not worth the hair to detect this in the big-endian case. */
+ else if (! BYTES_BIG_ENDIAN
+ && GET_CODE (body) == SET
+ && GET_CODE (SET_DEST (body)) == ZERO_EXTRACT
+ && XEXP (SET_DEST (body), 2) == const0_rtx
+ && XEXP (SET_DEST (body), 0) == SET_SRC (body)
+ && ! (GET_CODE (SET_SRC (body)) == MEM
+ && MEM_VOLATILE_P (SET_SRC (body))))
+ delete_insn (insn);
+ }
+ insn = next;
+ }
+}
+
+/* See if there is still a NOTE_INSN_FUNCTION_END in this function.
+ If so indicate that this function can drop off the end by returning
+ 1, else return 0.
+
+ CHECK_DELETED indicates whether we must check if the note being
+ searched for has the deleted flag set.
+
+ DELETE_FINAL_NOTE indicates whether we should delete the note
+ if we find it. */
+
+static int
+calculate_can_reach_end (last, check_deleted, delete_final_note)
+ rtx last;
+ int check_deleted;
+ int delete_final_note;
+{
+ rtx insn = last;
+ int n_labels = 1;
+
+ while (insn != NULL_RTX)
+ {
+ int ok = 0;
+
+ /* One label can follow the end-note: the return label. */
+ if (GET_CODE (insn) == CODE_LABEL && n_labels-- > 0)
+ ok = 1;
+ /* Ordinary insns can follow it if returning a structure. */
+ else if (GET_CODE (insn) == INSN)
+ ok = 1;
+ /* If machine uses explicit RETURN insns, no epilogue,
+ then one of them follows the note. */
+ else if (GET_CODE (insn) == JUMP_INSN
+ && GET_CODE (PATTERN (insn)) == RETURN)
+ ok = 1;
+ /* A barrier can follow the return insn. */
+ else if (GET_CODE (insn) == BARRIER)
+ ok = 1;
+ /* Other kinds of notes can follow also. */
+ else if (GET_CODE (insn) == NOTE
+ && NOTE_LINE_NUMBER (insn) != NOTE_INSN_FUNCTION_END)
+ ok = 1;
+
+ if (ok != 1)
+ break;
- insn = last_insn;
- {
- int n_labels = 1;
- while (insn
- /* One label can follow the end-note: the return label. */
- && ((GET_CODE (insn) == CODE_LABEL && n_labels-- > 0)
- /* Ordinary insns can follow it if returning a structure. */
- || GET_CODE (insn) == INSN
- /* If machine uses explicit RETURN insns, no epilogue,
- then one of them follows the note. */
- || (GET_CODE (insn) == JUMP_INSN
- && GET_CODE (PATTERN (insn)) == RETURN)
- /* A barrier can follow the return insn. */
- || GET_CODE (insn) == BARRIER
- /* Other kinds of notes can follow also. */
- || (GET_CODE (insn) == NOTE
- && NOTE_LINE_NUMBER (insn) != NOTE_INSN_FUNCTION_END)))
insn = PREV_INSN (insn);
- }
+ }
- /* Report if control can fall through at the end of the function. */
- if (insn && GET_CODE (insn) == NOTE
- && NOTE_LINE_NUMBER (insn) == NOTE_INSN_FUNCTION_END)
+ /* See if we backed up to the appropriate type of note. */
+ if (insn != NULL_RTX
+ && GET_CODE (insn) == NOTE
+ && NOTE_LINE_NUMBER (insn) == NOTE_INSN_FUNCTION_END
+ && (check_deleted == 0
+ || ! INSN_DELETED_P (insn)))
{
- can_reach_end = 1;
- delete_insn (insn);
+ if (delete_final_note)
+ delete_insn (insn);
+ return 1;
}
- /* Show JUMP_CHAIN no longer valid. */
- jump_chain = 0;
+ return 0;
}
-
+
/* LOOP_START is a NOTE_INSN_LOOP_BEG note that is followed by an unconditional
jump. Assume that this unconditional jump is to the exit test code. If
the code is sufficiently simple, make a copy of it before INSN,
@@ -2712,6 +2801,13 @@ find_cross_jump (e1, e2, minimum, f1, f2)
if (i2 == 0 || GET_CODE (i1) != GET_CODE (i2))
break;
+ /* Avoid moving insns across EH regions if either of the insns
+ can throw. */
+ if (flag_exceptions
+ && (asynchronous_exceptions || GET_CODE (i1) == CALL_INSN)
+ && !in_same_eh_region (i1, i2))
+ break;
+
p1 = PATTERN (i1);
p2 = PATTERN (i2);
@@ -3314,6 +3410,52 @@ condjump_in_parallel_p (insn)
return 0;
}
+/* Return the label of a conditional jump. */
+
+rtx
+condjump_label (insn)
+ rtx insn;
+{
+ register rtx x = PATTERN (insn);
+
+ if (GET_CODE (x) == PARALLEL)
+ x = XVECEXP (x, 0, 0);
+ if (GET_CODE (x) != SET)
+ return NULL_RTX;
+ if (GET_CODE (SET_DEST (x)) != PC)
+ return NULL_RTX;
+ x = SET_SRC (x);
+ if (GET_CODE (x) == LABEL_REF)
+ return x;
+ if (GET_CODE (x) != IF_THEN_ELSE)
+ return NULL_RTX;
+ if (XEXP (x, 2) == pc_rtx && GET_CODE (XEXP (x, 1)) == LABEL_REF)
+ return XEXP (x, 1);
+ if (XEXP (x, 1) == pc_rtx && GET_CODE (XEXP (x, 2)) == LABEL_REF)
+ return XEXP (x, 2);
+ return NULL_RTX;
+}
+
+/* Return true if INSN is a (possibly conditional) return insn. */
+
+static int
+returnjump_p_1 (loc, data)
+ rtx *loc;
+ void *data ATTRIBUTE_UNUSED;
+{
+ rtx x = *loc;
+ return GET_CODE (x) == RETURN;
+}
+
+int
+returnjump_p (insn)
+ rtx insn;
+{
+ return for_each_rtx (&PATTERN (insn), returnjump_p_1, NULL);
+}
+
+#ifdef HAVE_cc0
+
/* Return 1 if X is an RTX that does nothing but set the condition codes
and CLOBBER or USE registers.
Return -1 if X does explicitly set the condition codes,
@@ -3321,9 +3463,8 @@ condjump_in_parallel_p (insn)
int
sets_cc0_p (x)
- rtx x;
+ rtx x ATTRIBUTE_UNUSED;
{
-#ifdef HAVE_cc0
if (GET_CODE (x) == SET && SET_DEST (x) == cc0_rtx)
return 1;
if (GET_CODE (x) == PARALLEL)
@@ -3342,10 +3483,8 @@ sets_cc0_p (x)
return ! sets_cc0 ? 0 : other_things ? -1 : 1;
}
return 0;
-#else
- abort ();
-#endif
}
+#endif
/* Follow any unconditional jump at LABEL;
return the ultimate label reached by any such chain of jumps.
@@ -3641,6 +3780,17 @@ delete_computation (insn)
}
#endif
+#ifdef INSN_SCHEDULING
+ /* ?!? The schedulers do not keep REG_DEAD notes accurate after
+ reload has completed. The schedulers need to be fixed. Until
+ they are, we must not rely on the death notes here. */
+ if (reload_completed && flag_schedule_insns_after_reload)
+ {
+ delete_insn (insn);
+ return;
+ }
+#endif
+
for (note = REG_NOTES (insn); note; note = next)
{
rtx our_prev;
@@ -4344,6 +4494,10 @@ rtx_renumbered_equal_p (x, y)
case SYMBOL_REF:
return XSTR (x, 0) == XSTR (y, 0);
+ case CODE_LABEL:
+ /* If we didn't match EQ equality above, they aren't the same. */
+ return 0;
+
default:
break;
}
diff --git a/gcc/just-fixinc b/gcc/just-fixinc
index a7d1968ae5a..fb6137866e8 100755
--- a/gcc/just-fixinc
+++ b/gcc/just-fixinc
@@ -1,5 +1,5 @@
#!/bin/sh
-# $Id: just-fixinc,v 1.2 1998/04/03 16:35:58 law Exp $
+# $Id: just-fixinc,v 1.3 1998/12/16 20:57:01 law Exp $
# This script exists for use after installing
# the GCC binaries from a distribution tape/CD-ROM.
# Use it *after* copying the directory of binaries
diff --git a/gcc/libgcc2.c b/gcc/libgcc2.c
index 586aa2c7a6d..53dfdbf4f38 100644
--- a/gcc/libgcc2.c
+++ b/gcc/libgcc2.c
@@ -1,6 +1,6 @@
/* More subroutines needed by GCC output code on some machines. */
/* Compile this one with gcc. */
-/* Copyright (C) 1989, 92-97, 1998 Free Software Foundation, Inc.
+/* Copyright (C) 1989, 92-98, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -72,6 +72,10 @@ Boston, MA 02111-1307, USA. */
#define LIBGCC2_WORDS_BIG_ENDIAN WORDS_BIG_ENDIAN
#endif
+#ifndef LIBGCC2_LONG_DOUBLE_TYPE_SIZE
+#define LIBGCC2_LONG_DOUBLE_TYPE_SIZE LONG_DOUBLE_TYPE_SIZE
+#endif
+
/* In the first part of this file, we are interfacing to calls generated
by the compiler itself. These calls pass values into these routines
which have very specific modes (rather than very specific types), and
@@ -90,10 +94,10 @@ typedef unsigned int UDItype __attribute__ ((mode (DI)));
typedef float SFtype __attribute__ ((mode (SF)));
typedef float DFtype __attribute__ ((mode (DF)));
-#if LONG_DOUBLE_TYPE_SIZE == 96
+#if LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96
typedef float XFtype __attribute__ ((mode (XF)));
#endif
-#if LONG_DOUBLE_TYPE_SIZE == 128
+#if LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128
typedef float TFtype __attribute__ ((mode (TF)));
#endif
@@ -144,10 +148,10 @@ typedef union
extern DItype __fixunssfdi (SFtype a);
extern DItype __fixunsdfdi (DFtype a);
-#if LONG_DOUBLE_TYPE_SIZE == 96
+#if LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96
extern DItype __fixunsxfdi (XFtype a);
#endif
-#if LONG_DOUBLE_TYPE_SIZE == 128
+#if LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128
extern DItype __fixunstfdi (TFtype a);
#endif
@@ -768,7 +772,7 @@ __ucmpdi2 (DItype a, DItype b)
}
#endif
-#if defined(L_fixunstfdi) && (LONG_DOUBLE_TYPE_SIZE == 128)
+#if defined(L_fixunstfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128)
#define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
#define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
@@ -800,7 +804,7 @@ __fixunstfdi (TFtype a)
}
#endif
-#if defined(L_fixtfdi) && (LONG_DOUBLE_TYPE_SIZE == 128)
+#if defined(L_fixtfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128)
DItype
__fixtfdi (TFtype a)
{
@@ -810,7 +814,7 @@ __fixtfdi (TFtype a)
}
#endif
-#if defined(L_fixunsxfdi) && (LONG_DOUBLE_TYPE_SIZE == 96)
+#if defined(L_fixunsxfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96)
#define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
#define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
@@ -842,7 +846,7 @@ __fixunsxfdi (XFtype a)
}
#endif
-#if defined(L_fixxfdi) && (LONG_DOUBLE_TYPE_SIZE == 96)
+#if defined(L_fixxfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96)
DItype
__fixxfdi (XFtype a)
{
@@ -940,7 +944,7 @@ __fixsfdi (SFtype a)
}
#endif
-#if defined(L_floatdixf) && (LONG_DOUBLE_TYPE_SIZE == 96)
+#if defined(L_floatdixf) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96)
#define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
#define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
#define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
@@ -959,7 +963,7 @@ __floatdixf (DItype u)
}
#endif
-#if defined(L_floatditf) && (LONG_DOUBLE_TYPE_SIZE == 128)
+#if defined(L_floatditf) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128)
#define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
#define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
#define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
@@ -1065,7 +1069,7 @@ __floatdisf (DItype u)
}
#endif
-#if defined(L_fixunsxfsi) && LONG_DOUBLE_TYPE_SIZE == 96
+#if defined(L_fixunsxfsi) && LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96
/* Reenable the normal types, in case limits.h needs them. */
#undef char
#undef short
@@ -1403,6 +1407,9 @@ __builtin_saveregs ()
#undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
#include <stdio.h>
/* This is used by the `assert' macro. */
+extern void __eprintf (const char *, const char *, unsigned int, const char *)
+ __attribute__ ((__noreturn__));
+
void
__eprintf (const char *string, const char *expression,
unsigned int line, const char *filename)
@@ -2569,7 +2576,7 @@ __clear_cache (char *beg, char *end)
/* Jump to a trampoline, loading the static chain address. */
-#if defined(WINNT) && ! defined(__CYGWIN32__)
+#if defined(WINNT) && ! defined(__CYGWIN__) && ! defined (_UWIN)
long getpagesize()
{
@@ -2608,7 +2615,7 @@ mprotect (char *addr, int len, int prot)
return -1;
}
-#endif
+#endif /* WINNT && ! __CYGWIN__ && ! _UWIN */
#ifdef TRANSFER_FROM_TRAMPOLINE
TRANSFER_FROM_TRAMPOLINE
@@ -2807,7 +2814,7 @@ cacheflush (char *beg, int size, int flag)
#endif /* sony_news */
#endif /* L_trampoline */
-#ifndef __CYGWIN32__
+#ifndef __CYGWIN__
#ifdef L__main
#include "gbl-ctors.h"
@@ -2889,28 +2896,24 @@ SYMBOL__MAIN ()
#endif /* no HAS_INIT_SECTION or INVOKE__main */
#endif /* L__main */
-#endif /* __CYGWIN32__ */
+#endif /* __CYGWIN__ */
#ifdef L_ctors
#include "gbl-ctors.h"
/* Provide default definitions for the lists of constructors and
- destructors, so that we don't get linker errors. These symbols are
- intentionally bss symbols, so that gld and/or collect will provide
- the right values. */
+ destructors, so that we don't get linker errors.
+
+ The old code sometimes put these into the data segment and sometimes
+ into the bss segment. Putting these into the data segment should always
+ work and avoids a little bit of complexity. */
/* We declare the lists here with two elements each,
so that they are valid empty lists if no other definition is loaded. */
#if !defined(INIT_SECTION_ASM_OP) && !defined(CTOR_LISTS_DEFINED_EXTERNALLY)
-#if defined(__NeXT__) || defined(_AIX)
-/* After 2.3, try this definition on all systems. */
func_ptr __CTOR_LIST__[2] = {0, 0};
func_ptr __DTOR_LIST__[2] = {0, 0};
-#else
-func_ptr __CTOR_LIST__[2];
-func_ptr __DTOR_LIST__[2];
-#endif
#endif /* no INIT_SECTION_ASM_OP and not CTOR_LISTS_DEFINED_EXTERNALLY */
#endif /* L_ctors */
@@ -3023,6 +3026,8 @@ int atexit (func_ptr func)
/* Shared exception handling support routines. */
+extern void __default_terminate (void) __attribute__ ((__noreturn__));
+
void
__default_terminate ()
{
@@ -3062,10 +3067,6 @@ __empty ()
#include <stdio.h>
#endif
-/* This is a safeguard for dynamic handler chain. */
-
-static void *top_elt[2];
-
/* Allocate and return a new EH context structure. */
extern void __throw ();
@@ -3073,15 +3074,26 @@ extern void __throw ();
static void *
new_eh_context ()
{
- struct eh_context *eh = (struct eh_context *) malloc (sizeof *eh);
- if (! eh)
+ struct eh_full_context {
+ struct eh_context c;
+ void *top_elt[2];
+ } *ehfc = (struct eh_full_context *) malloc (sizeof *ehfc);
+
+ if (! ehfc)
__terminate ();
- memset (eh, 0, sizeof *eh);
+ memset (ehfc, 0, sizeof *ehfc);
- eh->dynamic_handler_chain = top_elt;
+ ehfc->c.dynamic_handler_chain = (void **) ehfc->top_elt;
- return eh;
+ /* This should optimize out entirely. This should always be true,
+ but just in case it ever isn't, don't allow bogus code to be
+ generated. */
+
+ if ((void*)(&ehfc->c) != (void*)ehfc)
+ __terminate ();
+
+ return &ehfc->c;
}
#if __GTHREADS
@@ -3173,10 +3185,17 @@ eh_context_initialize ()
static struct eh_context *
eh_context_static ()
{
- static struct eh_context *eh;
- if (! eh)
- eh = new_eh_context ();
- return eh;
+ static struct eh_context eh;
+ static int initialized;
+ static void *top_elt[2];
+
+ if (! initialized)
+ {
+ initialized = 1;
+ memset (&eh, 0, sizeof eh);
+ eh.dynamic_handler_chain = top_elt;
+ }
+ return &eh;
}
#if __GTHREADS
@@ -3226,6 +3245,8 @@ __get_dynamic_handler_chain ()
dynamic handler chain, and use longjmp to transfer back to the associated
handler. */
+extern void __sjthrow (void) __attribute__ ((__noreturn__));
+
void
__sjthrow ()
{
@@ -3278,7 +3299,7 @@ __sjthrow ()
/* We must call terminate if we try and rethrow an exception, when
there is no exception currently active and when there are no
handlers left. */
- if (! eh->info || (*dhc) == top_elt)
+ if (! eh->info || (*dhc)[0] == 0)
__terminate ();
/* Find the jmpbuf associated with the top element of the dynamic
@@ -3302,6 +3323,8 @@ __sjthrow ()
then throw. This is used to skip the first handler, and transfer
control to the next handler in the dynamic handler stack. */
+extern void __sjpopnthrow (void) __attribute__ ((__noreturn__));
+
void
__sjpopnthrow ()
{
@@ -3445,45 +3468,82 @@ old_find_exception_handler (void *pc, old_exception_table *table)
return (void *) 0;
}
+/* find_exception_handler finds the correct handler, if there is one, to
+ handle an exception.
+ returns a pointer to the handler which controlled should be transferred
+ to, or NULL if there is nothing left.
+ Parameters:
+ PC - pc where the exception originates. If this is a rethrow,
+ then this starts out as a pointer to the exception table
+ entry we wish to rethrow out of.
+ TABLE - exception table for the current module.
+ EH_INFO - eh info pointer for this exception.
+ RETHROW - 1 if this is a rethrow. (see incoming value of PC).
+ CLEANUP - returned flag indicating whether this is a cleanup handler.
+*/
static void *
-find_exception_handler (void *pc, exception_descriptor *table, void *eh_info)
+find_exception_handler (void *pc, exception_descriptor *table,
+ __eh_info *eh_info, int rethrow, int *cleanup)
{
+
+ void *retval = NULL;
+ *cleanup = 1;
if (table)
{
+ int pos = 0;
/* The new model assumed the table is sorted inner-most out so the
first region we find which matches is the correct one */
- int pos;
- void *ret;
exception_table *tab = &(table->table[0]);
/* Subtract 1 from the PC to avoid hitting the next region */
- pc--;
+ if (rethrow)
+ {
+ /* pc is actually the region table entry to rethrow out of */
+ pos = ((exception_table *) pc) - tab;
+ pc = ((exception_table *) pc)->end_region - 1;
+
+ /* The label is always on the LAST handler entry for a region,
+ so we know the next entry is a different region, even if the
+ addresses are the same. Make sure its not end of table tho. */
+ if (tab[pos].start_region != (void *) -1)
+ pos++;
+ }
+ else
+ pc--;
/* We can't do a binary search because the table is in inner-most
to outermost address ranges within functions */
- for (pos = 0; tab[pos].start_region != (void *) -1; pos++)
+ for ( ; tab[pos].start_region != (void *) -1; pos++)
{
if (tab[pos].start_region <= pc && tab[pos].end_region > pc)
{
if (tab[pos].match_info)
{
- __eh_matcher matcher = ((__eh_info *)eh_info)->match_function;
+ __eh_matcher matcher = eh_info->match_function;
/* match info but no matcher is NOT a match */
if (matcher)
{
- ret = (*matcher)(eh_info, tab[pos].match_info, table);
- if (ret)
- return tab[pos].exception_handler;
+ void *ret = (*matcher)((void *) eh_info,
+ tab[pos].match_info, table);
+ if (ret)
+ {
+ if (retval == NULL)
+ retval = tab[pos].exception_handler;
+ *cleanup = 0;
+ break;
+ }
}
}
else
- return tab[pos].exception_handler;
+ {
+ if (retval == NULL)
+ retval = tab[pos].exception_handler;
+ }
}
}
}
-
- return (void *) 0;
+ return retval;
}
#endif /* DWARF2_UNWIND_INFO */
#endif /* EH_TABLE_LOOKUP */
@@ -3620,52 +3680,47 @@ next_stack_level (void *pc, frame_state *udata, frame_state *caller_udata)
return caller_udata;
}
-/* We first search for an exception handler, and if we don't find
- it, we call __terminate on the current stack frame so that we may
- use the debugger to walk the stack and understand why no handler
- was found.
-
- If we find one, then we unwind the frames down to the one that
- has the handler and transfer control into the handler. */
-
-void
-__throw ()
+/* Hook to call before __terminate if only cleanup handlers remain. */
+void
+__unwinding_cleanup ()
{
- struct eh_context *eh = (*get_eh_context) ();
- void *saved_pc, *pc, *handler;
- frame_state ustruct, ustruct2;
- frame_state *udata = &ustruct;
- frame_state *sub_udata = &ustruct2;
- frame_state my_ustruct, *my_udata = &my_ustruct;
- long args_size;
- int new_exception_model;
-
- /* This is required for C++ semantics. We must call terminate if we
- try and rethrow an exception, when there is no exception currently
- active. */
- if (! eh->info)
- __terminate ();
-
- /* Start at our stack frame. */
-label:
- udata = __frame_state_for (&&label, udata);
- if (! udata)
- __terminate ();
-
- /* We need to get the value from the CFA register. */
- udata->cfa = __builtin_dwarf_cfa ();
-
- memcpy (my_udata, udata, sizeof (*udata));
-
- /* Do any necessary initialization to access arbitrary stack frames.
- On the SPARC, this means flushing the register windows. */
- __builtin_unwind_init ();
+}
- /* Now reset pc to the right throw point. */
- pc = __builtin_extract_return_addr (__builtin_return_address (0)) - 1;
- saved_pc = pc;
+/* throw_helper performs some of the common grunt work for a throw. This
+ routine is called by throw and rethrows. This is pretty much split
+ out from the old __throw routine. An addition has been added which allows
+ for a dummy call to a routine __unwinding_cleanup() when there are nothing
+ but cleanups remaining. This allows a debugger to examine the state
+ at which the throw was executed, before any cleanups, rather than
+ at the terminate point after the stack has been unwound. */
- handler = 0;
+static void *
+throw_helper (eh, pc, my_udata, udata_p)
+ struct eh_context *eh;
+ void *pc;
+ frame_state *my_udata;
+ frame_state **udata_p;
+{
+ frame_state *udata = *udata_p;
+ frame_state ustruct;
+ frame_state *sub_udata = &ustruct;
+ void *saved_pc = pc;
+ void *handler;
+ void *handler_p;
+ void *pc_p;
+ frame_state saved_ustruct;
+ int new_eh_model;
+ int cleanup = 0;
+ int only_cleanup = 0;
+ int rethrow = 0;
+ int saved_state = 0;
+ __eh_info *eh_info = (__eh_info *)eh->info;
+
+ /* Do we find a handler based on a re-throw PC? */
+ if (eh->table_index != (void *) 0)
+ rethrow = 1;
+
+ handler = (void *) 0;
for (;;)
{
frame_state *p = udata;
@@ -3677,21 +3732,46 @@ label:
break;
if (udata->eh_ptr == NULL)
- new_exception_model = 0;
+ new_eh_model = 0;
else
- new_exception_model = (((exception_descriptor *)(udata->eh_ptr))->
+ new_eh_model = (((exception_descriptor *)(udata->eh_ptr))->
runtime_id_field == NEW_EH_RUNTIME);
- if (new_exception_model)
- handler = find_exception_handler (pc, udata->eh_ptr, eh->info);
+ if (rethrow)
+ {
+ rethrow = 0;
+ handler = find_exception_handler (eh->table_index, udata->eh_ptr,
+ eh_info, 1, &cleanup);
+ eh->table_index = (void *)0;
+ }
else
- handler = old_find_exception_handler (pc, udata->eh_ptr);
-
- /* If we found one, we can stop searching. */
+ if (new_eh_model)
+ handler = find_exception_handler (pc, udata->eh_ptr, eh_info,
+ 0, &cleanup);
+ else
+ handler = old_find_exception_handler (pc, udata->eh_ptr);
+
+ /* If we found one, we can stop searching, if its not a cleanup.
+ for cleanups, we save the state, and keep looking. This allows
+ us to call a debug hook if there are nothing but cleanups left. */
if (handler)
{
- args_size = udata->args_size;
- break;
+ if (cleanup)
+ {
+ if (!saved_state)
+ {
+ saved_ustruct = *udata;
+ handler_p = handler;
+ pc_p = pc;
+ saved_state = 1;
+ only_cleanup = 1;
+ }
+ }
+ else
+ {
+ only_cleanup = 0;
+ break;
+ }
}
/* Otherwise, we continue searching. We subtract 1 from PC to avoid
@@ -3699,10 +3779,19 @@ label:
pc = get_return_addr (udata, sub_udata) - 1;
}
+ if (saved_state)
+ {
+ udata = &saved_ustruct;
+ handler = handler_p;
+ pc = pc_p;
+ if (only_cleanup)
+ __unwinding_cleanup ();
+ }
+
/* If we haven't found a handler by now, this is an unhandled
exception. */
- if (! handler)
- __terminate ();
+ if (! handler)
+ __terminate();
eh->handler_label = handler;
@@ -3756,6 +3845,114 @@ label:
copy_reg (i, udata, my_udata);
}
}
+ /* udata now refers to the frame called by the handler frame. */
+
+ *udata_p = udata;
+ return handler;
+}
+
+
+/* We first search for an exception handler, and if we don't find
+ it, we call __terminate on the current stack frame so that we may
+ use the debugger to walk the stack and understand why no handler
+ was found.
+
+ If we find one, then we unwind the frames down to the one that
+ has the handler and transfer control into the handler. */
+
+/*extern void __throw(void) __attribute__ ((__noreturn__));*/
+
+void
+__throw ()
+{
+ struct eh_context *eh = (*get_eh_context) ();
+ void *pc, *handler;
+ frame_state ustruct;
+ frame_state *udata = &ustruct;
+ frame_state my_ustruct, *my_udata = &my_ustruct;
+
+ /* This is required for C++ semantics. We must call terminate if we
+ try and rethrow an exception, when there is no exception currently
+ active. */
+ if (! eh->info)
+ __terminate ();
+
+ /* Start at our stack frame. */
+label:
+ udata = __frame_state_for (&&label, udata);
+ if (! udata)
+ __terminate ();
+
+ /* We need to get the value from the CFA register. */
+ udata->cfa = __builtin_dwarf_cfa ();
+
+ memcpy (my_udata, udata, sizeof (*udata));
+
+ /* Do any necessary initialization to access arbitrary stack frames.
+ On the SPARC, this means flushing the register windows. */
+ __builtin_unwind_init ();
+
+ /* Now reset pc to the right throw point. */
+ pc = __builtin_extract_return_addr (__builtin_return_address (0)) - 1;
+
+ handler = throw_helper (eh, pc, my_udata, &udata);
+
+ /* Now go! */
+
+ __builtin_eh_return ((void *)eh,
+#ifdef STACK_GROWS_DOWNWARD
+ udata->cfa - my_udata->cfa,
+#else
+ my_udata->cfa - udata->cfa,
+#endif
+ handler);
+
+ /* Epilogue: restore the handler frame's register values and return
+ to the stub. */
+}
+
+/*extern void __rethrow(void *) __attribute__ ((__noreturn__));*/
+
+void
+__rethrow (index)
+ void *index;
+{
+ struct eh_context *eh = (*get_eh_context) ();
+ void *pc, *handler;
+ frame_state ustruct;
+ frame_state *udata = &ustruct;
+ frame_state my_ustruct, *my_udata = &my_ustruct;
+
+ /* This is required for C++ semantics. We must call terminate if we
+ try and rethrow an exception, when there is no exception currently
+ active. */
+ if (! eh->info)
+ __terminate ();
+
+ /* This is the table index we want to rethrow from. The value of
+ the END_REGION label is used for the PC of the throw, and the
+ search begins with the next table entry. */
+ eh->table_index = index;
+
+ /* Start at our stack frame. */
+label:
+ udata = __frame_state_for (&&label, udata);
+ if (! udata)
+ __terminate ();
+
+ /* We need to get the value from the CFA register. */
+ udata->cfa = __builtin_dwarf_cfa ();
+
+ memcpy (my_udata, udata, sizeof (*udata));
+
+ /* Do any necessary initialization to access arbitrary stack frames.
+ On the SPARC, this means flushing the register windows. */
+ __builtin_unwind_init ();
+
+ /* Now reset pc to the right throw point. */
+ pc = __builtin_extract_return_addr (__builtin_return_address (0)) - 1;
+
+ handler = throw_helper (eh, pc, my_udata, &udata);
/* Now go! */
@@ -3795,6 +3992,6 @@ __pure_virtual ()
#ifndef inhibit_libc
write (2, MESSAGE, sizeof (MESSAGE) - 1);
#endif
- _exit (-1);
+ __terminate ();
}
#endif
diff --git a/gcc/local-alloc.c b/gcc/local-alloc.c
index e3b1667b403..f91988591ae 100644
--- a/gcc/local-alloc.c
+++ b/gcc/local-alloc.c
@@ -1,5 +1,5 @@
/* Allocate registers within a basic block, for GNU compiler.
- Copyright (C) 1987, 88, 91, 93-97, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1987, 88, 91, 93-98, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -235,6 +235,9 @@ static rtx this_insn;
static rtx *reg_equiv_replacement;
+/* Used for communication between update_equiv_regs and no_equiv. */
+static rtx *reg_equiv_init_insns;
+
static void alloc_qty PROTO((int, enum machine_mode, int, int));
static void validate_equiv_mem_from_store PROTO((rtx, rtx));
static int validate_equiv_mem PROTO((rtx, rtx, rtx));
@@ -242,6 +245,7 @@ static int contains_replace_regs PROTO((rtx, char *));
static int memref_referenced_p PROTO((rtx, rtx));
static int memref_used_between_p PROTO((rtx, rtx, rtx));
static void update_equiv_regs PROTO((void));
+static void no_equiv PROTO((rtx, rtx));
static void block_alloc PROTO((int));
static int qty_sugg_compare PROTO((int, int));
static int qty_sugg_compare_1 PROTO((const GENERIC_PTR, const GENERIC_PTR));
@@ -258,7 +262,7 @@ static int find_free_reg PROTO((enum reg_class, enum machine_mode,
static void mark_life PROTO((int, enum machine_mode, int));
static void post_mark_life PROTO((int, enum machine_mode, int, int, int));
static int no_conflict_p PROTO((rtx, rtx, rtx));
-static int requires_inout PROTO((char *));
+static int requires_inout PROTO((const char *));
/* Allocate a new quantity (new within current basic block)
for register number REGNO which is born at index BIRTH
@@ -334,9 +338,9 @@ local_alloc ()
qty_n_refs = (int *) alloca (max_qty * sizeof (int));
qty_changes_size = (char *) alloca (max_qty * sizeof (char));
- reg_qty = (int *) alloca (max_regno * sizeof (int));
- reg_offset = (char *) alloca (max_regno * sizeof (char));
- reg_next_in_qty = (int *) alloca (max_regno * sizeof (int));
+ reg_qty = (int *) xmalloc (max_regno * sizeof (int));
+ reg_offset = (char *) xmalloc (max_regno * sizeof (char));
+ reg_next_in_qty = (int *) xmalloc(max_regno * sizeof (int));
/* Allocate the reg_renumber array */
allocate_reg_info (max_regno, FALSE, TRUE);
@@ -403,6 +407,10 @@ local_alloc ()
alloca (0);
#endif
}
+
+ free (reg_qty);
+ free (reg_offset);
+ free (reg_next_in_qty);
}
/* Depth of loops we are in while in update_equiv_regs. */
@@ -421,7 +429,7 @@ static int equiv_mem_modified;
static void
validate_equiv_mem_from_store (dest, set)
rtx dest;
- rtx set;
+ rtx set ATTRIBUTE_UNUSED;
{
if ((GET_CODE (dest) == REG
&& reg_overlap_mentioned_p (dest, equiv_mem))
@@ -623,6 +631,22 @@ memref_used_between_p (memref, start, end)
return 0;
}
+/* Return nonzero if the rtx X is invariant over the current function. */
+int
+function_invariant_p (x)
+ rtx x;
+{
+ if (CONSTANT_P (x))
+ return 1;
+ if (x == frame_pointer_rtx || x == arg_pointer_rtx)
+ return 1;
+ if (GET_CODE (x) == PLUS
+ && (XEXP (x, 0) == frame_pointer_rtx || XEXP (x, 0) == arg_pointer_rtx)
+ && CONSTANT_P (XEXP (x, 1)))
+ return 1;
+ return 0;
+}
+
/* Find registers that are equivalent to a single value throughout the
compilation (either because they can be referenced in memory or are set once
from a single constant). Lower their priority for a register.
@@ -634,7 +658,6 @@ memref_used_between_p (memref, start, end)
static void
update_equiv_regs ()
{
- rtx *reg_equiv_init_insn = (rtx *) alloca (max_regno * sizeof (rtx *));
/* Set when an attempt should be made to replace a register with the
associated reg_equiv_replacement entry at the end of this function. */
char *reg_equiv_replace
@@ -642,10 +665,11 @@ update_equiv_regs ()
rtx insn;
int block, depth;
- reg_equiv_replacement = (rtx *) alloca (max_regno * sizeof (rtx *));
+ reg_equiv_init_insns = (rtx *) alloca (max_regno * sizeof (rtx));
+ reg_equiv_replacement = (rtx *) alloca (max_regno * sizeof (rtx));
- bzero ((char *) reg_equiv_init_insn, max_regno * sizeof (rtx *));
- bzero ((char *) reg_equiv_replacement, max_regno * sizeof (rtx *));
+ bzero ((char *) reg_equiv_init_insns, max_regno * sizeof (rtx));
+ bzero ((char *) reg_equiv_replacement, max_regno * sizeof (rtx));
bzero ((char *) reg_equiv_replace, max_regno * sizeof *reg_equiv_replace);
init_alias_analysis ();
@@ -658,7 +682,7 @@ update_equiv_regs ()
for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
{
rtx note;
- rtx set = single_set (insn);
+ rtx set;
rtx dest, src;
int regno;
@@ -670,10 +694,34 @@ update_equiv_regs ()
loop_depth--;
}
- /* If this insn contains more (or less) than a single SET, ignore it. */
- if (set == 0)
+ if (GET_RTX_CLASS (GET_CODE (insn)) != 'i')
continue;
+ for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
+ if (REG_NOTE_KIND (note) == REG_INC)
+ no_equiv (XEXP (note, 0), note);
+
+ set = single_set (insn);
+
+ /* If this insn contains more (or less) than a single SET,
+ only mark all destinations as having no known equivalence. */
+ if (set == 0)
+ {
+ note_stores (PATTERN (insn), no_equiv);
+ continue;
+ }
+ else if (GET_CODE (PATTERN (insn)) == PARALLEL)
+ {
+ int i;
+
+ for (i = XVECLEN (PATTERN (insn), 0) - 1; i >= 0; i--)
+ {
+ rtx part = XVECEXP (PATTERN (insn), 0, i);
+ if (part != set)
+ note_stores (part, no_equiv);
+ }
+ }
+
dest = SET_DEST (set);
src = SET_SRC (set);
@@ -689,60 +737,83 @@ update_equiv_regs ()
If one of the regs in the address is marked as reg_equiv_replace,
then we can't add this REG_EQUIV note. The reg_equiv_replace
optimization may move the set of this register immediately before
- insn, which puts it after reg_equiv_init_insn[regno], and hence
+ insn, which puts it after reg_equiv_init_insns[regno], and hence
the mention in the REG_EQUIV note would be to an uninitialized
pseudo. */
-
- if (GET_CODE (dest) == MEM && GET_CODE (SET_SRC (set)) == REG
- && (regno = REGNO (SET_SRC (set))) >= FIRST_PSEUDO_REGISTER
+ /* ????? This test isn't good enough; we might see a MEM with a use of
+ a pseudo register before we see its setting insn that will cause
+ reg_equiv_replace for that pseudo to be set.
+ Equivalences to MEMs should be made in another pass, after the
+ reg_equiv_replace information has been gathered. */
+
+ if (GET_CODE (dest) == MEM && GET_CODE (src) == REG
+ && (regno = REGNO (src)) >= FIRST_PSEUDO_REGISTER
&& REG_BASIC_BLOCK (regno) >= 0
- && reg_equiv_init_insn[regno] != 0
+ && REG_N_SETS (regno) == 1
+ && reg_equiv_init_insns[regno] != 0
+ && reg_equiv_init_insns[regno] != const0_rtx
&& ! find_reg_note (insn, REG_EQUIV, NULL_RTX)
- && ! contains_replace_regs (XEXP (dest, 0), reg_equiv_replace)
- && validate_equiv_mem (reg_equiv_init_insn[regno], SET_SRC (set),
- dest)
- && ! memref_used_between_p (SET_DEST (set),
- reg_equiv_init_insn[regno], insn))
- REG_NOTES (reg_equiv_init_insn[regno])
- = gen_rtx_EXPR_LIST (REG_EQUIV, dest,
- REG_NOTES (reg_equiv_init_insn[regno]));
+ && ! contains_replace_regs (XEXP (dest, 0), reg_equiv_replace))
+ {
+ rtx init_insn = XEXP (reg_equiv_init_insns[regno], 0);
+ if (validate_equiv_mem (init_insn, src, dest)
+ && ! memref_used_between_p (dest, init_insn, insn))
+ REG_NOTES (init_insn)
+ = gen_rtx_EXPR_LIST (REG_EQUIV, dest, REG_NOTES (init_insn));
+ }
/* We only handle the case of a pseudo register being set
- once and only if neither the source nor the destination are
- in a register class that's likely to be spilled. */
+ once, or always to the same value. */
+ /* ??? The mn10200 port breaks if we add equivalences for
+ values that need an ADDRESS_REGS register and set them equivalent
+ to a MEM of a pseudo. The actual problem is in the over-conservative
+ handling of INPADDR_ADDRESS / INPUT_ADDRESS / INPUT triples in
+ calculate_needs, but we traditionally work around this problem
+ here by rejecting equivalences when the destination is in a register
+ that's likely spilled. This is fragile, of course, since the
+ preferred class of a pseudo depends on all instructions that set
+ or use it. */
+
if (GET_CODE (dest) != REG
|| (regno = REGNO (dest)) < FIRST_PSEUDO_REGISTER
- || REG_N_SETS (regno) != 1
- || CLASS_LIKELY_SPILLED_P (reg_preferred_class (REGNO (dest)))
- || (GET_CODE (src) == REG
- && REGNO (src) >= FIRST_PSEUDO_REGISTER
- && CLASS_LIKELY_SPILLED_P (reg_preferred_class (REGNO (src)))))
- continue;
+ || reg_equiv_init_insns[regno] == const0_rtx
+ || (CLASS_LIKELY_SPILLED_P (reg_preferred_class (regno))
+ && GET_CODE (src) == MEM))
+ {
+ /* This might be seting a SUBREG of a pseudo, a pseudo that is
+ also set somewhere else to a constant. */
+ note_stores (set, no_equiv);
+ continue;
+ }
+ /* Don't handle the equivalence if the source is in a register
+ class that's likely to be spilled. */
+ if (GET_CODE (src) == REG
+ && REGNO (src) >= FIRST_PSEUDO_REGISTER
+ && CLASS_LIKELY_SPILLED_P (reg_preferred_class (REGNO (src))))
+ {
+ no_equiv (dest, set);
+ continue;
+ }
note = find_reg_note (insn, REG_EQUAL, NULL_RTX);
-#ifdef DONT_RECORD_EQUIVALENCE
- /* Allow the target to reject promotions of some REG_EQUAL notes to
- REG_EQUIV notes.
-
- In some cases this can improve register allocation if the existence
- of the REG_EQUIV note is likely to increase the lifetime of a register
- that is likely to be spilled.
-
- It may also be necessary if the target can't handle certain constant
- expressions appearing randomly in insns, but for whatever reason
- those expressions must be considered legitimate constant expressions
- to prevent them from being forced into memory. */
- if (note && DONT_RECORD_EQUIVALENCE (note))
- note = NULL;
-#endif
-
+ if (REG_N_SETS (regno) != 1
+ && (! note
+ || ! function_invariant_p (XEXP (note, 0))
+ || (reg_equiv_replacement[regno]
+ && ! rtx_equal_p (XEXP (note, 0),
+ reg_equiv_replacement[regno]))))
+ {
+ no_equiv (dest, set);
+ continue;
+ }
/* Record this insn as initializing this register. */
- reg_equiv_init_insn[regno] = insn;
+ reg_equiv_init_insns[regno]
+ = gen_rtx_INSN_LIST (VOIDmode, insn, reg_equiv_init_insns[regno]);
/* If this register is known to be equal to a constant, record that
it is always equivalent to the constant. */
- if (note && CONSTANT_P (XEXP (note, 0)))
+ if (note && function_invariant_p (XEXP (note, 0)))
PUT_MODE (note, (enum machine_mode) REG_EQUIV);
/* If this insn introduces a "constant" register, decrease the priority
@@ -818,7 +889,7 @@ update_equiv_regs ()
/* Keep track of which basic block we are in. */
if (block + 1 < n_basic_blocks
- && basic_block_head[block + 1] == insn)
+ && BLOCK_HEAD (block + 1) == insn)
++block;
if (GET_RTX_CLASS (GET_CODE (insn)) != 'i')
@@ -850,7 +921,12 @@ update_equiv_regs ()
if (! reg_equiv_replace[regno])
continue;
- equiv_insn = reg_equiv_init_insn[regno];
+ /* reg_equiv_replace[REGNO] gets set only when
+ REG_N_REFS[REGNO] is 2, i.e. the register is set
+ once and used once. (If it were only set, but not used,
+ flow would have deleted the setting insns.) Hence
+ there can only be one insn in reg_equiv_init_insns. */
+ equiv_insn = XEXP (reg_equiv_init_insns[regno], 0);
if (validate_replace_rtx (regno_reg_rtx[regno],
reg_equiv_replacement[regno], insn))
@@ -887,16 +963,46 @@ update_equiv_regs ()
REG_N_CALLS_CROSSED (regno) = 0;
REG_LIVE_LENGTH (regno) = 2;
- if (block >= 0 && insn == basic_block_head[block])
- basic_block_head[block] = PREV_INSN (insn);
+ if (block >= 0 && insn == BLOCK_HEAD (block))
+ BLOCK_HEAD (block) = PREV_INSN (insn);
for (l = 0; l < n_basic_blocks; l++)
- CLEAR_REGNO_REG_SET (basic_block_live_at_start[l], regno);
+ CLEAR_REGNO_REG_SET (BASIC_BLOCK (l)->global_live_at_start,
+ regno);
}
}
}
}
}
+
+/* Mark REG as having no known equivalence.
+ Some instructions might have been proceessed before and furnished
+ with REG_EQUIV notes for this register; these notes will have to be
+ removed.
+ STORE is the piece of RTL that does the non-constant / conflicting
+ assignment - a SET, CLOBBER or REG_INC note. It is currently not used,
+ but needs to be there because this function is called from note_stores. */
+static void
+no_equiv (reg, store)
+ rtx reg, store ATTRIBUTE_UNUSED;
+{
+ int regno;
+ rtx list;
+
+ if (GET_CODE (reg) != REG)
+ return;
+ regno = REGNO (reg);
+ list = reg_equiv_init_insns[regno];
+ if (list == const0_rtx)
+ return;
+ for (; list; list = XEXP (list, 1))
+ {
+ rtx insn = XEXP (list, 0);
+ remove_note (insn, find_reg_note (insn, REG_EQUIV, NULL_RTX));
+ }
+ reg_equiv_init_insns[regno] = const0_rtx;
+ reg_equiv_replacement[regno] = NULL_RTX;
+}
/* Allocate hard regs to the pseudo regs used only within block number B.
Only the pseudos that die but once can be handled. */
@@ -916,13 +1022,13 @@ block_alloc (b)
/* Count the instructions in the basic block. */
- insn = basic_block_end[b];
+ insn = BLOCK_END (b);
while (1)
{
if (GET_CODE (insn) != NOTE)
if (++insn_count > max_uid)
abort ();
- if (insn == basic_block_head[b])
+ if (insn == BLOCK_HEAD (b))
break;
insn = PREV_INSN (insn);
}
@@ -935,13 +1041,13 @@ block_alloc (b)
/* Initialize table of hardware registers currently live. */
- REG_SET_TO_HARD_REG_SET (regs_live, basic_block_live_at_start[b]);
+ REG_SET_TO_HARD_REG_SET (regs_live, BASIC_BLOCK (b)->global_live_at_start);
/* This loop scans the instructions of the basic block
and assigns quantities to registers.
It computes which registers to tie. */
- insn = basic_block_head[b];
+ insn = BLOCK_HEAD (b);
while (1)
{
register rtx body = PATTERN (insn);
@@ -956,13 +1062,11 @@ block_alloc (b)
register rtx r0, r1;
int combined_regno = -1;
int i;
- int insn_code_number = recog_memoized (insn);
this_insn_number = insn_number;
this_insn = insn;
- if (insn_code_number >= 0)
- insn_extract (insn);
+ extract_insn (insn);
which_alternative = -1;
/* Is this insn suitable for tying two registers?
@@ -983,11 +1087,11 @@ block_alloc (b)
If tying is done, WIN is set nonzero. */
- if (insn_code_number >= 0
+ if (1
#ifdef REGISTER_CONSTRAINTS
- && insn_n_operands[insn_code_number] > 1
- && insn_operand_constraint[insn_code_number][0][0] == '='
- && insn_operand_constraint[insn_code_number][0][1] != '&'
+ && recog_n_operands > 1
+ && recog_constraints[0][0] == '='
+ && recog_constraints[0][1] != '&'
#else
&& GET_CODE (PATTERN (insn)) == SET
&& rtx_equal_p (SET_DEST (PATTERN (insn)), recog_operand[0])
@@ -1001,19 +1105,19 @@ block_alloc (b)
operand 0. */
int n_matching_alts = 0;
- for (i = 1; i < insn_n_operands[insn_code_number]; i++)
+ for (i = 1; i < recog_n_operands; i++)
{
- char *p = insn_operand_constraint[insn_code_number][i];
+ const char *p = recog_constraints[i];
int this_match = (requires_inout (p));
n_matching_alts += this_match;
- if (this_match == insn_n_alternatives[insn_code_number])
+ if (this_match == recog_n_alternatives)
must_match_0 = i;
}
#endif
r0 = recog_operand[0];
- for (i = 1; i < insn_n_operands[insn_code_number]; i++)
+ for (i = 1; i < recog_n_operands; i++)
{
#ifdef REGISTER_CONSTRAINTS
/* Skip this operand if we found an operand that
@@ -1022,9 +1126,9 @@ block_alloc (b)
if (must_match_0 >= 0 && i != must_match_0
&& ! (i == must_match_0 + 1
- && insn_operand_constraint[insn_code_number][i-1][0] == '%')
+ && recog_constraints[i-1][0] == '%')
&& ! (i == must_match_0 - 1
- && insn_operand_constraint[insn_code_number][i][0] == '%'))
+ && recog_constraints[i][0] == '%'))
continue;
/* Likewise if each alternative has some operand that
@@ -1032,9 +1136,8 @@ block_alloc (b)
operand that doesn't list operand 0 since we know that
the operand always conflicts with operand 0. We
ignore commutatity in this case to keep things simple. */
- if (n_matching_alts == insn_n_alternatives[insn_code_number]
- && (0 == requires_inout
- (insn_operand_constraint[insn_code_number][i])))
+ if (n_matching_alts == recog_n_alternatives
+ && 0 == requires_inout (recog_constraints[i]))
continue;
#endif
@@ -1045,9 +1148,9 @@ block_alloc (b)
of them. */
if (
#ifdef REGISTER_CONSTRAINTS
- insn_operand_constraint[insn_code_number][i][0] == 'p'
+ recog_constraints[i][0] == 'p'
#else
- insn_operand_address_p[insn_code_number][i]
+ recog_operand_address_p[i]
#endif
)
while (GET_CODE (r1) == PLUS || GET_CODE (r1) == MULT)
@@ -1182,7 +1285,7 @@ block_alloc (b)
IOR_HARD_REG_SET (regs_live_at[2 * insn_number], regs_live);
IOR_HARD_REG_SET (regs_live_at[2 * insn_number + 1], regs_live);
- if (insn == basic_block_end[b])
+ if (insn == BLOCK_END (b))
break;
insn = NEXT_INSN (insn);
@@ -1297,8 +1400,8 @@ block_alloc (b)
discourage the register allocator from creating false
dependencies.
- The adjustment by the value +-3 indicates precisely that
- this qty conflicts with qtys in the instructions immediately
+ The adjustment value is choosen to indicate that this qty
+ conflicts with all the qtys in the instructions immediately
before and after the lifetime of this qty.
Experiments have shown that higher values tend to hurt
@@ -1306,8 +1409,9 @@ block_alloc (b)
If allocation using the extended lifetime fails we will try
again with the qty's unadjusted lifetime. */
- int fake_birth = MAX (0, qty_birth[q] - 3);
- int fake_death = MIN (insn_number * 2 + 1, qty_death[q] + 3);
+ int fake_birth = MAX (0, qty_birth[q] - 2 + qty_birth[q] % 2);
+ int fake_death = MIN (insn_number * 2 + 1,
+ qty_death[q] + 2 - qty_death[q] % 2);
#endif
if (N_REG_CLASSES > 1)
@@ -1545,6 +1649,11 @@ combine_regs (usedreg, setreg, may_save_copy, insn_number, insn, already_dead)
|| ureg == sreg
/* Don't try to connect two different hardware registers. */
|| (ureg < FIRST_PSEUDO_REGISTER && sreg < FIRST_PSEUDO_REGISTER)
+ /* Don't use a hard reg that might be spilled. */
+ || (ureg < FIRST_PSEUDO_REGISTER
+ && CLASS_LIKELY_SPILLED_P (REGNO_REG_CLASS (ureg)))
+ || (sreg < FIRST_PSEUDO_REGISTER
+ && CLASS_LIKELY_SPILLED_P (REGNO_REG_CLASS (sreg)))
/* Don't connect two different machine modes if they have different
implications as to which registers may be used. */
|| !MODES_TIEABLE_P (GET_MODE (usedreg), GET_MODE (setreg)))
@@ -1758,9 +1867,16 @@ wipe_dead_reg (reg, output_p)
/* If this insn has multiple results,
and the dead reg is used in one of the results,
extend its life to after this insn,
- so it won't get allocated together with any other result of this insn. */
+ so it won't get allocated together with any other result of this insn.
+
+ It is unsafe to use !single_set here since it will ignore an unused
+ output. Just because an output is unused does not mean the compiler
+ can assume the side effect will not occur. Consider if REG appears
+ in the address of an output and we reload the output. If we allocate
+ REG to the same hard register as an unused output we could set the hard
+ register before the output reload insn. */
if (GET_CODE (PATTERN (this_insn)) == PARALLEL
- && !single_set (this_insn))
+ && multiple_sets (this_insn))
{
int i;
for (i = XVECLEN (PATTERN (this_insn), 0) - 1; i >= 0; i--)
@@ -1859,7 +1975,7 @@ find_free_reg (class, mode, qty, accept_call_clobbered, just_try_suggested,
This is true of any register that can be eliminated. */
#ifdef ELIMINABLE_REGS
- for (i = 0; i < sizeof eliminables / sizeof eliminables[0]; i++)
+ for (i = 0; i < (int)(sizeof eliminables / sizeof eliminables[0]); i++)
SET_HARD_REG_BIT (used, eliminables[i].from);
#if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
/* If FRAME_POINTER_REGNUM is not a real register, then protect the one
@@ -2068,7 +2184,7 @@ no_conflict_p (insn, r0, r1)
static int
requires_inout (p)
- char *p;
+ const char *p;
{
char c;
int found_zero = 0;
diff --git a/gcc/longlong.h b/gcc/longlong.h
index 2c047117d44..d1859ef58ff 100644
--- a/gcc/longlong.h
+++ b/gcc/longlong.h
@@ -1,5 +1,5 @@
/* longlong.h -- definitions for mixed size 32/64 bit arithmetic.
- Copyright (C) 1991, 92, 94, 95, 96, 1997 Free Software Foundation, Inc.
+ Copyright (C) 1991, 92, 94, 95, 96, 1997, 1998 Free Software Foundation, Inc.
This definition file is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public
diff --git a/gcc/loop.c b/gcc/loop.c
index fdf6d28723a..5cb883e5b6f 100644
--- a/gcc/loop.c
+++ b/gcc/loop.c
@@ -1,5 +1,5 @@
/* Perform various loop optimizations, including strength reduction.
- Copyright (C) 1987, 88, 89, 91-97, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1987, 88, 89, 91-98, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -79,6 +79,16 @@ static int max_loop_num;
static rtx *loop_number_loop_starts, *loop_number_loop_ends;
+/* Likewise for the continue insn */
+static rtx *loop_number_loop_cont;
+
+/* The first code_label that is reached in every loop iteration.
+ 0 when not computed yet, initially const0_rtx if a jump couldn't be
+ followed.
+ Also set to 0 when there is no such label before the NOTE_INSN_LOOP_CONT
+ of this loop, or in verify_dominator, if a jump couldn't be followed. */
+static rtx *loop_number_cont_dominator;
+
/* For each loop, gives the containing loop number, -1 if none. */
int *loop_outer_loop;
@@ -89,14 +99,6 @@ int *loop_outer_loop;
int *loop_used_count_register;
#endif /* HAVE_decrement_and_branch_on_count */
-/* For each loop, keep track of its unrolling factor.
- Potential values:
- 0: unrolled
- 1: not unrolled.
- -1: completely unrolled
- >0: holds the unroll exact factor. */
-int *loop_unroll_factor;
-
/* Indexed by loop number, contains a nonzero value if the "loop" isn't
really a loop (an insn outside the loop branches into it). */
@@ -119,14 +121,6 @@ rtx *loop_number_exit_labels;
int *loop_number_exit_count;
-/* Holds the number of loop iterations. It is zero if the number could not be
- calculated. Must be unsigned since the number of iterations can
- be as high as 2^wordsize-1. For loops with a wider iterator, this number
- will be zero if the number of loop iterations is too large for an
- unsigned integer to hold. */
-
-unsigned HOST_WIDE_INT loop_n_iterations;
-
/* Nonzero if there is a subroutine call in the current loop. */
static int loop_has_call;
@@ -136,6 +130,10 @@ static int loop_has_call;
static int loop_has_volatile;
+/* Nonzero if there is a tablejump in the current loop. */
+
+static int loop_has_tablejump;
+
/* Added loop_continue which is the NOTE_INSN_LOOP_CONT of the
current loop. A continue statement will generate a branch to
NEXT_INSN (loop_continue). */
@@ -154,32 +152,35 @@ static rtx loop_continue;
Therefore, at all times, == 0 indicates an invariant register;
< 0 a conditionally invariant one. */
-static varray_type n_times_set;
+static varray_type set_in_loop;
-/* Original value of n_times_set; same except that this value
+/* Original value of set_in_loop; same except that this value
is not set negative for a reg whose sets have been made candidates
and not set to 0 for a reg that is moved. */
-static varray_type n_times_used;
+static varray_type n_times_set;
/* Index by register number, 1 indicates that the register
cannot be moved or strength reduced. */
static varray_type may_not_optimize;
+/* Contains the insn in which a register was used if it was used
+ exactly once; contains const0_rtx if it was used more than once. */
+
+static varray_type reg_single_usage;
+
/* Nonzero means reg N has already been moved out of one loop.
This reduces the desire to move it out of another. */
static char *moved_once;
-/* Array of MEMs that are stored in this loop. If there are too many to fit
- here, we just turn on unknown_address_altered. */
+/* List of MEMs that are stored in this loop. */
-#define NUM_STORES 30
-static rtx loop_store_mems[NUM_STORES];
+static rtx loop_store_mems;
-/* Index of first available slot in above array. */
-static int loop_store_mems_idx;
+/* The insn where the first of these was found. */
+static rtx first_loop_store_insn;
typedef struct loop_mem_info {
rtx mem; /* The MEM itself. */
@@ -285,12 +286,12 @@ FILE *loop_dump_stream;
/* Forward declarations. */
+static void verify_dominator PROTO((int));
static void find_and_verify_loops PROTO((rtx));
static void mark_loop_jump PROTO((rtx, int));
static void prescan_loop PROTO((rtx, rtx));
static int reg_in_basic_block_p PROTO((rtx, rtx));
static int consec_sets_invariant_p PROTO((rtx, int, rtx));
-static rtx libcall_other_reg PROTO((rtx, rtx));
static int labels_in_range_p PROTO((rtx, int));
static void count_one_set PROTO((rtx, rtx, varray_type, rtx *));
@@ -298,7 +299,7 @@ static void count_loop_regs_set PROTO((rtx, rtx, varray_type, varray_type,
int *, int));
static void note_addr_stored PROTO((rtx, rtx));
static int loop_reg_used_before_p PROTO((rtx, rtx, rtx, rtx, rtx));
-static void scan_loop PROTO((rtx, rtx, int, int));
+static void scan_loop PROTO((rtx, rtx, rtx, int, int));
#if 0
static void replace_call_address PROTO((rtx, rtx, rtx));
#endif
@@ -312,23 +313,26 @@ static int rtx_equal_for_loop_p PROTO((rtx, rtx, struct movable *));
static void add_label_notes PROTO((rtx, rtx));
static void move_movables PROTO((struct movable *, int, int, rtx, rtx, int));
static int count_nonfixed_reads PROTO((rtx));
-static void strength_reduce PROTO((rtx, rtx, rtx, int, rtx, rtx, int, int));
+static void strength_reduce PROTO((rtx, rtx, rtx, int, rtx, rtx, rtx, int, int));
static void find_single_use_in_loop PROTO((rtx, rtx, varray_type));
static int valid_initial_value_p PROTO((rtx, rtx, int, rtx));
static void find_mem_givs PROTO((rtx, rtx, int, rtx, rtx));
-static void record_biv PROTO((struct induction *, rtx, rtx, rtx, rtx, int, int));
-static void check_final_value PROTO((struct induction *, rtx, rtx));
+static void record_biv PROTO((struct induction *, rtx, rtx, rtx, rtx, rtx *, int, int));
+static void check_final_value PROTO((struct induction *, rtx, rtx,
+ unsigned HOST_WIDE_INT));
static void record_giv PROTO((struct induction *, rtx, rtx, rtx, rtx, rtx, int, enum g_types, int, rtx *, rtx, rtx));
static void update_giv_derive PROTO((rtx));
-static int basic_induction_var PROTO((rtx, enum machine_mode, rtx, rtx, rtx *, rtx *));
+static int basic_induction_var PROTO((rtx, enum machine_mode, rtx, rtx, rtx *, rtx *, rtx **));
static rtx simplify_giv_expr PROTO((rtx, int *));
static int general_induction_var PROTO((rtx, rtx *, rtx *, rtx *, int, int *));
-static int consec_sets_giv PROTO((int, rtx, rtx, rtx, rtx *, rtx *));
-static int check_dbra_loop PROTO((rtx, int, rtx));
+static int consec_sets_giv PROTO((int, rtx, rtx, rtx, rtx *, rtx *, rtx *));
+static int check_dbra_loop PROTO((rtx, int, rtx, struct loop_info *));
static rtx express_from_1 PROTO((rtx, rtx, rtx));
-static rtx express_from PROTO((struct induction *, struct induction *));
static rtx combine_givs_p PROTO((struct induction *, struct induction *));
static void combine_givs PROTO((struct iv_class *));
+struct recombine_givs_stats;
+static int find_life_end PROTO((rtx, struct recombine_givs_stats *, rtx, rtx));
+static void recombine_givs PROTO((struct iv_class *, rtx, rtx, int));
static int product_cheap_p PROTO((rtx, rtx));
static int maybe_eliminate_biv PROTO((struct iv_class *, rtx, rtx, int, int, int));
static int maybe_eliminate_biv_1 PROTO((rtx, rtx, struct iv_class *, int, rtx));
@@ -337,8 +341,7 @@ static void record_initial PROTO((rtx, rtx));
static void update_reg_last_use PROTO((rtx, rtx));
static rtx next_insn_in_loop PROTO((rtx, rtx, rtx, rtx));
static void load_mems_and_recount_loop_regs_set PROTO((rtx, rtx, rtx,
- rtx, varray_type,
- int *));
+ rtx, int *));
static void load_mems PROTO((rtx, rtx, rtx, rtx));
static int insert_loop_mem PROTO((rtx *, void *));
static int replace_loop_mem PROTO((rtx *, void *));
@@ -362,7 +365,7 @@ typedef struct rtx_pair {
#ifdef HAVE_decrement_and_branch_on_count
/* Test whether BCT applicable and safe. */
-static void insert_bct PROTO((rtx, rtx));
+static void insert_bct PROTO((rtx, rtx, struct loop_info *));
/* Auxiliary function that inserts the BCT pattern into the loop. */
static void instrument_loop_bct PROTO((rtx, rtx, rtx));
@@ -372,6 +375,10 @@ static void instrument_loop_bct PROTO((rtx, rtx, rtx));
int indirect_jump_in_function = 0;
static int indirect_jump_in_function_p PROTO((rtx));
+static int compute_luids PROTO((rtx, rtx, int));
+
+static int biv_elimination_giv_has_0_offset PROTO((struct induction *,
+ struct induction *, rtx));
/* Relative gain of eliminating various kinds of operations. */
static int add_cost;
@@ -415,6 +422,35 @@ init_loop ()
gcc_obstack_init (&temp_obstack);
}
+/* Compute the mapping from uids to luids.
+ LUIDs are numbers assigned to insns, like uids,
+ except that luids increase monotonically through the code.
+ Start at insn START and stop just before END. Assign LUIDs
+ starting with PREV_LUID + 1. Return the last assigned LUID + 1. */
+static int
+compute_luids (start, end, prev_luid)
+ rtx start, end;
+ int prev_luid;
+{
+ int i;
+ rtx insn;
+
+ for (insn = start, i = prev_luid; insn != end; insn = NEXT_INSN (insn))
+ {
+ if (INSN_UID (insn) >= max_uid_for_loop)
+ continue;
+ /* Don't assign luids to line-number NOTEs, so that the distance in
+ luids between two insns is not affected by -g. */
+ if (GET_CODE (insn) != NOTE
+ || NOTE_LINE_NUMBER (insn) <= 0)
+ uid_luid[INSN_UID (insn)] = ++i;
+ else
+ /* Give a line number note the same luid as preceding insn. */
+ uid_luid[INSN_UID (insn)] = i;
+ }
+ return i + 1;
+}
+
/* Entry point of this file. Perform loop optimization
on the current function. F is the first insn of the function
and DUMPFILE is a stream for output of a trace of actions taken
@@ -429,7 +465,6 @@ loop_optimize (f, dumpfile, unroll_p, bct_p)
{
register rtx insn;
register int i;
- rtx last_insn;
loop_dump_stream = dumpfile;
@@ -470,17 +505,13 @@ loop_optimize (f, dumpfile, unroll_p, bct_p)
not be zeroed. */
loop_number_loop_starts = (rtx *) alloca (max_loop_num * sizeof (rtx));
loop_number_loop_ends = (rtx *) alloca (max_loop_num * sizeof (rtx));
+ loop_number_loop_cont = (rtx *) alloca (max_loop_num * sizeof (rtx));
+ loop_number_cont_dominator = (rtx *) alloca (max_loop_num * sizeof (rtx));
loop_outer_loop = (int *) alloca (max_loop_num * sizeof (int));
loop_invalid = (char *) alloca (max_loop_num * sizeof (char));
loop_number_exit_labels = (rtx *) alloca (max_loop_num * sizeof (rtx));
loop_number_exit_count = (int *) alloca (max_loop_num * sizeof (int));
- /* This is initialized by the unrolling code, so we go ahead
- and clear them just in case we are not performing loop
- unrolling. */
- loop_unroll_factor = (int *) alloca (max_loop_num *sizeof (int));
- bzero ((char *) loop_unroll_factor, max_loop_num * sizeof (int));
-
#ifdef HAVE_decrement_and_branch_on_count
/* Allocate for BCT optimization */
loop_used_count_register = (int *) alloca (max_loop_num * sizeof (int));
@@ -503,30 +534,16 @@ loop_optimize (f, dumpfile, unroll_p, bct_p)
but moving this call to init_alias_analysis is more efficient. */
init_alias_analysis ();
- /* See if we went too far. */
+ /* See if we went too far. Note that get_max_uid already returns
+ one more that the maximum uid of all insn. */
if (get_max_uid () > max_uid_for_loop)
abort ();
/* Now reset it to the actual size we need. See above. */
- max_uid_for_loop = get_max_uid () + 1;
+ max_uid_for_loop = get_max_uid ();
- /* Compute the mapping from uids to luids.
- LUIDs are numbers assigned to insns, like uids,
- except that luids increase monotonically through the code.
- Don't assign luids to line-number NOTEs, so that the distance in luids
- between two insns is not affected by -g. */
-
- for (insn = f, i = 0; insn; insn = NEXT_INSN (insn))
- {
- last_insn = insn;
- if (GET_CODE (insn) != NOTE
- || NOTE_LINE_NUMBER (insn) <= 0)
- uid_luid[INSN_UID (insn)] = ++i;
- else
- /* Give a line number note the same luid as preceding insn. */
- uid_luid[INSN_UID (insn)] = i;
- }
-
- max_luid = i + 1;
+ /* find_and_verify_loops has already called compute_luids, but it might
+ have rearranged code afterwards, so we need to recompute the luids now. */
+ max_luid = compute_luids (f, NULL_RTX, 0);
/* Don't leave gaps in uid_luid for insns that have been
deleted. It is possible that the first or last insn
@@ -556,7 +573,7 @@ loop_optimize (f, dumpfile, unroll_p, bct_p)
for (i = max_loop_num-1; i >= 0; i--)
if (! loop_invalid[i] && loop_number_loop_ends[i])
scan_loop (loop_number_loop_starts[i], loop_number_loop_ends[i],
- unroll_p, bct_p);
+ loop_number_loop_cont[i], unroll_p, bct_p);
/* If debugging and unrolling loops, we must replicate the tree nodes
corresponding to the blocks inside the loop, so that the original one
@@ -601,7 +618,8 @@ next_insn_in_loop (insn, start, end, loop_top)
/* Optimize one loop whose start is LOOP_START and end is END.
LOOP_START is the NOTE_INSN_LOOP_BEG and END is the matching
- NOTE_INSN_LOOP_END. */
+ NOTE_INSN_LOOP_END.
+ LOOP_CONT is the NOTE_INSN_LOOP_CONT. */
/* ??? Could also move memory writes out of loops if the destination address
is invariant, the source is invariant, the memory write is not volatile,
@@ -610,8 +628,8 @@ next_insn_in_loop (insn, start, end, loop_top)
write, then we can also mark the memory read as invariant. */
static void
-scan_loop (loop_start, end, unroll_p, bct_p)
- rtx loop_start, end;
+scan_loop (loop_start, end, loop_cont, unroll_p, bct_p)
+ rtx loop_start, end, loop_cont;
int unroll_p, bct_p;
{
register int i;
@@ -644,10 +662,6 @@ scan_loop (loop_start, end, unroll_p, bct_p)
since in that case saving an insn makes more difference
and more registers are available. */
int threshold;
- /* If we have calls, contains the insn in which a register was used
- if it was used exactly once; contains const0_rtx if it was used more
- than once. */
- varray_type reg_single_usage = 0;
/* Nonzero if we are scanning instructions in a sub-loop. */
int loop_depth = 0;
int nregs;
@@ -727,8 +741,7 @@ scan_loop (loop_start, end, unroll_p, bct_p)
/* Count number of times each reg is set during this loop.
Set VARRAY_CHAR (may_not_optimize, I) if it is not safe to move out
- the setting of register I. If this loop has calls, set
- VARRAY_RTX (reg_single_usage, I). */
+ the setting of register I. Set VARRAY_RTX (reg_single_usage, I). */
/* Allocate extra space for REGS that might be created by
load_mems. We allocate a little extra slop as well, in the hopes
@@ -736,12 +749,10 @@ scan_loop (loop_start, end, unroll_p, bct_p)
we won't have to reallocate these arrays. However, we do grow
the arrays, if necessary, in load_mems_recount_loop_regs_set. */
nregs = max_reg_num () + loop_mems_idx + 16;
+ VARRAY_INT_INIT (set_in_loop, nregs, "set_in_loop");
VARRAY_INT_INIT (n_times_set, nregs, "n_times_set");
- VARRAY_INT_INIT (n_times_used, nregs, "n_times_used");
VARRAY_CHAR_INIT (may_not_optimize, nregs, "may_not_optimize");
-
- if (loop_has_call)
- VARRAY_RTX_INIT (reg_single_usage, nregs, "reg_single_usage");
+ VARRAY_RTX_INIT (reg_single_usage, nregs, "reg_single_usage");
count_loop_regs_set (loop_top ? loop_top : loop_start, end,
may_not_optimize, reg_single_usage, &insn_count, nregs);
@@ -749,7 +760,7 @@ scan_loop (loop_start, end, unroll_p, bct_p)
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
{
VARRAY_CHAR (may_not_optimize, i) = 1;
- VARRAY_INT (n_times_set, i) = 1;
+ VARRAY_INT (set_in_loop, i) = 1;
}
#ifdef AVOID_CCMODE_COPIES
@@ -760,8 +771,8 @@ scan_loop (loop_start, end, unroll_p, bct_p)
VARRAY_CHAR (may_not_optimize, i) = 1;
#endif
- bcopy ((char *) &n_times_set->data,
- (char *) &n_times_used->data, nregs * sizeof (int));
+ bcopy ((char *) &set_in_loop->data,
+ (char *) &n_times_set->data, nregs * sizeof (int));
if (loop_dump_stream)
{
@@ -773,7 +784,7 @@ scan_loop (loop_start, end, unroll_p, bct_p)
}
/* Scan through the loop finding insns that are safe to move.
- Set n_times_set negative for the reg being set, so that
+ Set set_in_loop negative for the reg being set, so that
this reg will be considered invariant for subsequent insns.
We consider whether subsequent insns use the reg
in deciding whether it is worth actually moving.
@@ -838,41 +849,38 @@ scan_loop (loop_start, end, unroll_p, bct_p)
We don't know its life-span, so we can't compute the benefit. */
if (REGNO (SET_DEST (set)) >= max_reg_before_loop)
;
- else if (/* The set is a user-variable or it is used in
- the exit test (this can cause the variable to be
- used before it is set just like a
- user-variable)... */
- (REG_USERVAR_P (SET_DEST (set))
- || REG_LOOP_TEST_P (SET_DEST (set)))
+ else if (/* The register is used in basic blocks other
+ than the one where it is set (meaning that
+ something after this point in the loop might
+ depend on its value before the set). */
+ ! reg_in_basic_block_p (p, SET_DEST (set))
/* And the set is not guaranteed to be executed one
the loop starts, or the value before the set is
- needed before the set occurs... */
+ needed before the set occurs...
+
+ ??? Note we have quadratic behaviour here, mitigated
+ by the fact that the previous test will often fail for
+ large loops. Rather than re-scanning the entire loop
+ each time for register usage, we should build tables
+ of the register usage and use them here instead. */
&& (maybe_never
|| loop_reg_used_before_p (set, p, loop_start,
- scan_start, end))
- /* And the register is used in basic blocks other
- than the one where it is set (meaning that
- something after this point in the loop might
- depend on its value before the set). */
- && !reg_in_basic_block_p (p, SET_DEST (set)))
- /* It is unsafe to move the set. The fact that these
- three conditions are considered in conjunction means
- that we are assuming various conditions, such as:
-
- o It's OK to move a set of a variable which was not
- created by the user and is not used in an exit test
- even if that point in the set would not be reached
- during execution of the loop. */
+ scan_start, end)))
+ /* It is unsafe to move the set.
+
+ This code used to consider it OK to move a set of a variable
+ which was not created by the user and not used in an exit test.
+ That behavior is incorrect and was removed. */
;
else if ((tem = invariant_p (src))
&& (dependencies == 0
|| (tem2 = invariant_p (dependencies)) != 0)
- && (VARRAY_INT (n_times_set,
+ && (VARRAY_INT (set_in_loop,
REGNO (SET_DEST (set))) == 1
|| (tem1
= consec_sets_invariant_p
(SET_DEST (set),
- VARRAY_INT (n_times_set, REGNO (SET_DEST (set))),
+ VARRAY_INT (set_in_loop, REGNO (SET_DEST (set))),
p)))
/* If the insn can cause a trap (such as divide by zero),
can't move it unless it's guaranteed to be executed
@@ -899,12 +907,13 @@ scan_loop (loop_start, end, unroll_p, bct_p)
Don't do this if P has a REG_RETVAL note or if we have
SMALL_REGISTER_CLASSES and SET_SRC is a hard register. */
- if (reg_single_usage && VARRAY_RTX (reg_single_usage, regno) != 0
+ if (loop_has_call
+ && VARRAY_RTX (reg_single_usage, regno) != 0
&& VARRAY_RTX (reg_single_usage, regno) != const0_rtx
&& REGNO_FIRST_UID (regno) == INSN_UID (p)
&& (REGNO_LAST_UID (regno)
== INSN_UID (VARRAY_RTX (reg_single_usage, regno)))
- && VARRAY_INT (n_times_set, regno) == 1
+ && VARRAY_INT (set_in_loop, regno) == 1
&& ! side_effects_p (SET_SRC (set))
&& ! find_reg_note (p, REG_RETVAL, NULL_RTX)
&& (! SMALL_REGISTER_CLASSES
@@ -932,7 +941,7 @@ scan_loop (loop_start, end, unroll_p, bct_p)
PUT_CODE (p, NOTE);
NOTE_LINE_NUMBER (p) = NOTE_INSN_DELETED;
NOTE_SOURCE_FILE (p) = 0;
- VARRAY_INT (n_times_set, regno) = 0;
+ VARRAY_INT (set_in_loop, regno) = 0;
continue;
}
@@ -943,7 +952,7 @@ scan_loop (loop_start, end, unroll_p, bct_p)
m->dependencies = dependencies;
m->set_dest = SET_DEST (set);
m->force = 0;
- m->consec = VARRAY_INT (n_times_set,
+ m->consec = VARRAY_INT (set_in_loop,
REGNO (SET_DEST (set))) - 1;
m->done = 0;
m->forces = 0;
@@ -961,10 +970,10 @@ scan_loop (loop_start, end, unroll_p, bct_p)
m->match = 0;
m->lifetime = (uid_luid[REGNO_LAST_UID (regno)]
- uid_luid[REGNO_FIRST_UID (regno)]);
- m->savings = VARRAY_INT (n_times_used, regno);
+ m->savings = VARRAY_INT (n_times_set, regno);
if (find_reg_note (p, REG_RETVAL, NULL_RTX))
m->savings += libcall_benefit (p);
- VARRAY_INT (n_times_set, regno) = move_insn ? -2 : -1;
+ VARRAY_INT (set_in_loop, regno) = move_insn ? -2 : -1;
/* Add M to the end of the chain MOVABLES. */
if (movables == 0)
movables = m;
@@ -1023,7 +1032,7 @@ scan_loop (loop_start, end, unroll_p, bct_p)
&& !reg_mentioned_p (SET_DEST (set), SET_SRC (set1)))
{
register int regno = REGNO (SET_DEST (set));
- if (VARRAY_INT (n_times_set, regno) == 2)
+ if (VARRAY_INT (set_in_loop, regno) == 2)
{
register struct movable *m;
m = (struct movable *) alloca (sizeof (struct movable));
@@ -1073,7 +1082,7 @@ scan_loop (loop_start, end, unroll_p, bct_p)
m->lifetime = (uid_luid[REGNO_LAST_UID (regno)]
- uid_luid[REGNO_FIRST_UID (regno)]);
m->savings = 1;
- VARRAY_INT (n_times_set, regno) = -1;
+ VARRAY_INT (set_in_loop, regno) = -1;
/* Add M to the end of the chain MOVABLES. */
if (movables == 0)
movables = m;
@@ -1138,7 +1147,7 @@ scan_loop (loop_start, end, unroll_p, bct_p)
combine_movables (movables, nregs);
/* Now consider each movable insn to decide whether it is worth moving.
- Store 0 in n_times_set for each reg that is moved.
+ Store 0 in set_in_loop for each reg that is moved.
Generally this increases code size, so do not move moveables when
optimizing for code size. */
@@ -1148,29 +1157,27 @@ scan_loop (loop_start, end, unroll_p, bct_p)
insn_count, loop_start, end, nregs);
/* Now candidates that still are negative are those not moved.
- Change n_times_set to indicate that those are not actually invariant. */
+ Change set_in_loop to indicate that those are not actually invariant. */
for (i = 0; i < nregs; i++)
- if (VARRAY_INT (n_times_set, i) < 0)
- VARRAY_INT (n_times_set, i) = VARRAY_INT (n_times_used, i);
+ if (VARRAY_INT (set_in_loop, i) < 0)
+ VARRAY_INT (set_in_loop, i) = VARRAY_INT (n_times_set, i);
- /* Now that we've moved some things out of the loop, we able to
- hoist even more memory references. There's no need to pass
- reg_single_usage this time, since we're done with it. */
+ /* Now that we've moved some things out of the loop, we might be able to
+ hoist even more memory references. */
load_mems_and_recount_loop_regs_set (scan_start, end, loop_top,
- loop_start, 0,
- &insn_count);
+ loop_start, &insn_count);
if (flag_strength_reduce)
{
the_movables = movables;
strength_reduce (scan_start, end, loop_top,
- insn_count, loop_start, end, unroll_p, bct_p);
+ insn_count, loop_start, end, loop_cont, unroll_p, bct_p);
}
+ VARRAY_FREE (reg_single_usage);
+ VARRAY_FREE (set_in_loop);
VARRAY_FREE (n_times_set);
- VARRAY_FREE (n_times_used);
VARRAY_FREE (may_not_optimize);
- VARRAY_FREE (reg_single_usage);
}
/* Add elements to *OUTPUT to record all the pseudo-regs
@@ -1232,7 +1239,7 @@ record_excess_regs (in_this, not_in_this, output)
If there are none, return 0.
If there are one or more, return an EXPR_LIST containing all of them. */
-static rtx
+rtx
libcall_other_reg (insn, equiv)
rtx insn, equiv;
{
@@ -1444,7 +1451,7 @@ combine_movables (movables, nregs)
/* Perhaps testing m->consec_sets would be more appropriate here? */
for (m = movables; m; m = m->next)
- if (m->match == 0 && VARRAY_INT (n_times_used, m->regno) == 1 && !m->partial)
+ if (m->match == 0 && VARRAY_INT (n_times_set, m->regno) == 1 && !m->partial)
{
register struct movable *m1;
int regno = m->regno;
@@ -1455,7 +1462,7 @@ combine_movables (movables, nregs)
/* We want later insns to match the first one. Don't make the first
one match any later ones. So start this loop at m->next. */
for (m1 = m->next; m1; m1 = m1->next)
- if (m != m1 && m1->match == 0 && VARRAY_INT (n_times_used, m1->regno) == 1
+ if (m != m1 && m1->match == 0 && VARRAY_INT (n_times_set, m1->regno) == 1
/* A reg used outside the loop mustn't be eliminated. */
&& !m1->global
/* A reg used for zero-extending mustn't be eliminated. */
@@ -1592,7 +1599,7 @@ rtx_equal_for_loop_p (x, y, movables)
/* If we have a register and a constant, they may sometimes be
equal. */
- if (GET_CODE (x) == REG && VARRAY_INT (n_times_set, REGNO (x)) == -2
+ if (GET_CODE (x) == REG && VARRAY_INT (set_in_loop, REGNO (x)) == -2
&& CONSTANT_P (y))
{
for (m = movables; m; m = m->next)
@@ -1600,7 +1607,7 @@ rtx_equal_for_loop_p (x, y, movables)
&& rtx_equal_p (m->set_src, y))
return 1;
}
- else if (GET_CODE (y) == REG && VARRAY_INT (n_times_set, REGNO (y)) == -2
+ else if (GET_CODE (y) == REG && VARRAY_INT (set_in_loop, REGNO (y)) == -2
&& CONSTANT_P (x))
{
for (m = movables; m; m = m->next)
@@ -1827,7 +1834,7 @@ move_movables (movables, threshold, insn_count, loop_start, end, nregs)
|| (threshold * savings * m->lifetime) >=
(moved_once[regno] ? insn_count * 2 : insn_count)
|| (m->forces && m->forces->done
- && VARRAY_INT (n_times_used, m->forces->regno) == 1))
+ && VARRAY_INT (n_times_set, m->forces->regno) == 1))
{
int count;
register struct movable *m1;
@@ -2020,6 +2027,8 @@ move_movables (movables, threshold, insn_count, loop_start, end, nregs)
REG_NOTES (i1) = REG_NOTES (temp);
delete_insn (temp);
}
+ if (new_start == 0)
+ new_start = first;
}
if (m->savemode != VOIDmode)
{
@@ -2135,7 +2144,7 @@ move_movables (movables, threshold, insn_count, loop_start, end, nregs)
/* The reg set here is now invariant. */
if (! m->partial)
- VARRAY_INT (n_times_set, regno) = 0;
+ VARRAY_INT (set_in_loop, regno) = 0;
m->done = 1;
@@ -2192,7 +2201,7 @@ move_movables (movables, threshold, insn_count, loop_start, end, nregs)
/* The reg merged here is now invariant,
if the reg it matches is invariant. */
if (! m->partial)
- VARRAY_INT (n_times_set, m1->regno) = 0;
+ VARRAY_INT (set_in_loop, m1->regno) = 0;
}
}
else if (loop_dump_stream)
@@ -2377,9 +2386,9 @@ constant_high_bytes (p, loop_start)
#endif
/* Scan a loop setting the variables `unknown_address_altered',
- `num_mem_sets', `loop_continue', loops_enclosed', `loop_has_call',
- and `loop_has_volatile'. Also, fill in the arrays `loop_mems' and
- `loop_store_mems'. */
+ `num_mem_sets', `loop_continue', `loops_enclosed', `loop_has_call',
+ `loop_has_volatile', and `loop_has_tablejump'.
+ Also, fill in the array `loop_mems' and the list `loop_store_mems'. */
static void
prescan_loop (start, end)
@@ -2399,7 +2408,9 @@ prescan_loop (start, end)
unknown_address_altered = 0;
loop_has_call = 0;
loop_has_volatile = 0;
- loop_store_mems_idx = 0;
+ loop_has_tablejump = 0;
+ loop_store_mems = NULL_RTX;
+ first_loop_store_insn = NULL_RTX;
loop_mems_idx = 0;
num_mem_sets = 0;
@@ -2445,10 +2456,17 @@ prescan_loop (start, end)
if (volatile_refs_p (PATTERN (insn)))
loop_has_volatile = 1;
+
+ if (GET_CODE (insn) == JUMP_INSN
+ && (GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC
+ || GET_CODE (PATTERN (insn)) == ADDR_VEC))
+ loop_has_tablejump = 1;
note_stores (PATTERN (insn), note_addr_stored);
+ if (! first_loop_store_insn && loop_store_mems)
+ first_loop_store_insn = insn;
- if (!loop_has_multiple_exit_targets
+ if (! loop_has_multiple_exit_targets
&& GET_CODE (insn) == JUMP_INSN
&& GET_CODE (PATTERN (insn)) == SET
&& SET_DEST (PATTERN (insn)) == pc_rtx)
@@ -2509,6 +2527,53 @@ prescan_loop (start, end)
for_each_rtx (&insn, insert_loop_mem, 0);
}
+/* LOOP_NUMBER_CONT_DOMINATOR is now the last label between the loop start
+ and the continue note that is a the destination of a (cond)jump after
+ the continue note. If there is any (cond)jump between the loop start
+ and what we have so far as LOOP_NUMBER_CONT_DOMINATOR that has a
+ target between LOOP_DOMINATOR and the continue note, move
+ LOOP_NUMBER_CONT_DOMINATOR forward to that label; if a jump's
+ destination cannot be determined, clear LOOP_NUMBER_CONT_DOMINATOR. */
+
+static void
+verify_dominator (loop_number)
+ int loop_number;
+{
+ rtx insn;
+
+ if (! loop_number_cont_dominator[loop_number])
+ /* This can happen for an empty loop, e.g. in
+ gcc.c-torture/compile/920410-2.c */
+ return;
+ if (loop_number_cont_dominator[loop_number] == const0_rtx)
+ {
+ loop_number_cont_dominator[loop_number] = 0;
+ return;
+ }
+ for (insn = loop_number_loop_starts[loop_number];
+ insn != loop_number_cont_dominator[loop_number];
+ insn = NEXT_INSN (insn))
+ {
+ if (GET_CODE (insn) == JUMP_INSN
+ && GET_CODE (PATTERN (insn)) != RETURN)
+ {
+ rtx label = JUMP_LABEL (insn);
+ int label_luid = INSN_LUID (label);
+
+ if (! condjump_p (insn)
+ && ! condjump_in_parallel_p (insn))
+ {
+ loop_number_cont_dominator[loop_number] = NULL_RTX;
+ return;
+ }
+ if (label_luid < INSN_LUID (loop_number_loop_cont[loop_number])
+ && (label_luid
+ > INSN_LUID (loop_number_cont_dominator[loop_number])))
+ loop_number_cont_dominator[loop_number] = label;
+ }
+ }
+}
+
/* Scan the function looking for loops. Record the start and end of each loop.
Also mark as invalid loops any loops that contain a setjmp or are branched
to from outside the loop. */
@@ -2522,6 +2587,8 @@ find_and_verify_loops (f)
int next_loop = -1;
int loop;
+ compute_luids (f, NULL_RTX, 0);
+
/* If there are jumps to undefined labels,
treat them as jumps out of any/all loops.
This also avoids writing past end of tables when there are no loops. */
@@ -2538,6 +2605,8 @@ find_and_verify_loops (f)
case NOTE_INSN_LOOP_BEG:
loop_number_loop_starts[++next_loop] = insn;
loop_number_loop_ends[next_loop] = 0;
+ loop_number_loop_cont[next_loop] = 0;
+ loop_number_cont_dominator[next_loop] = 0;
loop_outer_loop[next_loop] = current_loop;
loop_invalid[next_loop] = 0;
loop_number_exit_labels[next_loop] = 0;
@@ -2558,17 +2627,63 @@ find_and_verify_loops (f)
}
break;
+ case NOTE_INSN_LOOP_CONT:
+ loop_number_loop_cont[current_loop] = insn;
+ break;
case NOTE_INSN_LOOP_END:
if (current_loop == -1)
abort ();
loop_number_loop_ends[current_loop] = insn;
+ verify_dominator (current_loop);
current_loop = loop_outer_loop[current_loop];
break;
default:
break;
}
+ /* If for any loop, this is a jump insn between the NOTE_INSN_LOOP_CONT
+ and NOTE_INSN_LOOP_END notes, update loop_number_loop_dominator. */
+ else if (GET_CODE (insn) == JUMP_INSN
+ && GET_CODE (PATTERN (insn)) != RETURN
+ && current_loop >= 0)
+ {
+ int this_loop;
+ rtx label = JUMP_LABEL (insn);
+
+ if (! condjump_p (insn) && ! condjump_in_parallel_p (insn))
+ label = NULL_RTX;
+
+ this_loop = current_loop;
+ do
+ {
+ /* First see if we care about this loop. */
+ if (loop_number_loop_cont[this_loop]
+ && loop_number_cont_dominator[this_loop] != const0_rtx)
+ {
+ /* If the jump destination is not known, invalidate
+ loop_number_const_dominator. */
+ if (! label)
+ loop_number_cont_dominator[this_loop] = const0_rtx;
+ else
+ /* Check if the destination is between loop start and
+ cont. */
+ if ((INSN_LUID (label)
+ < INSN_LUID (loop_number_loop_cont[this_loop]))
+ && (INSN_LUID (label)
+ > INSN_LUID (loop_number_loop_starts[this_loop]))
+ /* And if there is no later destination already
+ recorded. */
+ && (! loop_number_cont_dominator[this_loop]
+ || (INSN_LUID (label)
+ > INSN_LUID (loop_number_cont_dominator
+ [this_loop]))))
+ loop_number_cont_dominator[this_loop] = label;
+ }
+ this_loop = loop_outer_loop[this_loop];
+ }
+ while (this_loop >= 0);
+ }
/* Note that this will mark the NOTE_INSN_LOOP_END note as being in the
enclosing loop, but this doesn't matter. */
@@ -2864,6 +2979,11 @@ mark_loop_jump (x, loop_num)
mark_loop_jump (XEXP (x, 1), loop_num);
return;
+ case LO_SUM:
+ /* This may refer to a LABEL_REF or SYMBOL_REF. */
+ mark_loop_jump (XEXP (x, 1), loop_num);
+ return;
+
case SIGN_EXTEND:
case ZERO_EXTEND:
mark_loop_jump (XEXP (x, 0), loop_num);
@@ -2951,21 +3071,21 @@ mark_loop_jump (x, loop_num)
return;
default:
- /* Treat anything else (such as a symbol_ref)
- as a branch out of this loop, but not into any loop. */
-
+ /* Strictly speaking this is not a jump into the loop, only a possible
+ jump out of the loop. However, we have no way to link the destination
+ of this jump onto the list of exit labels. To be safe we mark this
+ loop and any containing loops as invalid. */
if (loop_num != -1)
{
-#ifdef HAVE_decrement_and_branch_on_count
- LABEL_OUTSIDE_LOOP_P (x) = 1;
- LABEL_NEXTREF (x) = loop_number_exit_labels[loop_num];
-#endif /* HAVE_decrement_and_branch_on_count */
-
- loop_number_exit_labels[loop_num] = x;
-
for (outer_loop = loop_num; outer_loop != -1;
outer_loop = loop_outer_loop[outer_loop])
- loop_number_exit_count[outer_loop]++;
+ {
+ if (loop_dump_stream && ! loop_invalid[outer_loop])
+ fprintf (loop_dump_stream,
+ "\nLoop at %d ignored due to unknown exit jump.\n",
+ INSN_UID (loop_number_loop_starts[outer_loop]));
+ loop_invalid[outer_loop] = 1;
+ }
}
return;
}
@@ -2998,8 +3118,6 @@ note_addr_stored (x, y)
rtx x;
rtx y ATTRIBUTE_UNUSED;
{
- register int i;
-
if (x == 0 || GET_CODE (x) != MEM)
return;
@@ -3014,23 +3132,7 @@ note_addr_stored (x, y)
if (unknown_address_altered)
return;
- for (i = 0; i < loop_store_mems_idx; i++)
- if (rtx_equal_p (XEXP (loop_store_mems[i], 0), XEXP (x, 0))
- && MEM_IN_STRUCT_P (x) == MEM_IN_STRUCT_P (loop_store_mems[i]))
- {
- /* We are storing at the same address as previously noted. Save the
- wider reference. */
- if (GET_MODE_SIZE (GET_MODE (x))
- > GET_MODE_SIZE (GET_MODE (loop_store_mems[i])))
- loop_store_mems[i] = x;
- break;
- }
-
- if (i == NUM_STORES)
- unknown_address_altered = 1;
-
- else if (i == loop_store_mems_idx)
- loop_store_mems[loop_store_mems_idx++] = x;
+ loop_store_mems = gen_rtx_EXPR_LIST (VOIDmode, x, loop_store_mems);
}
/* Return nonzero if the rtx X is invariant over the current loop.
@@ -3049,6 +3151,7 @@ invariant_p (x)
register enum rtx_code code;
register char *fmt;
int conditional = 0;
+ rtx mem_list_entry;
if (x == 0)
return 1;
@@ -3094,10 +3197,10 @@ invariant_p (x)
&& REGNO (x) < FIRST_PSEUDO_REGISTER && call_used_regs[REGNO (x)])
return 0;
- if (VARRAY_INT (n_times_set, REGNO (x)) < 0)
+ if (VARRAY_INT (set_in_loop, REGNO (x)) < 0)
return 2;
- return VARRAY_INT (n_times_set, REGNO (x)) == 0;
+ return VARRAY_INT (set_in_loop, REGNO (x)) == 0;
case MEM:
/* Volatile memory references must be rejected. Do this before
@@ -3111,15 +3214,20 @@ invariant_p (x)
if (RTX_UNCHANGING_P (x))
break;
- /* If we filled the table (or had a subroutine call), any location
- in memory could have been clobbered. */
+ /* If we had a subroutine call, any location in memory could have been
+ clobbered. */
if (unknown_address_altered)
return 0;
/* See if there is any dependence between a store and this load. */
- for (i = loop_store_mems_idx - 1; i >= 0; i--)
- if (true_dependence (loop_store_mems[i], VOIDmode, x, rtx_varies_p))
- return 0;
+ mem_list_entry = loop_store_mems;
+ while (mem_list_entry)
+ {
+ if (true_dependence (XEXP (mem_list_entry, 0), VOIDmode,
+ x, rtx_varies_p))
+ return 0;
+ mem_list_entry = XEXP (mem_list_entry, 1);
+ }
/* It's not invalidated by a store in memory
but we must still verify the address is invariant. */
@@ -3185,7 +3293,7 @@ consec_sets_invariant_p (reg, n_sets, insn)
rtx temp;
/* Number of sets we have to insist on finding after INSN. */
int count = n_sets - 1;
- int old = VARRAY_INT (n_times_set, regno);
+ int old = VARRAY_INT (set_in_loop, regno);
int value = 0;
int this;
@@ -3193,7 +3301,7 @@ consec_sets_invariant_p (reg, n_sets, insn)
if (n_sets == 127)
return 0;
- VARRAY_INT (n_times_set, regno) = 0;
+ VARRAY_INT (set_in_loop, regno) = 0;
while (count > 0)
{
@@ -3232,12 +3340,12 @@ consec_sets_invariant_p (reg, n_sets, insn)
count--;
else if (code != NOTE)
{
- VARRAY_INT (n_times_set, regno) = old;
+ VARRAY_INT (set_in_loop, regno) = old;
return 0;
}
}
- VARRAY_INT (n_times_set, regno) = old;
+ VARRAY_INT (set_in_loop, regno) = old;
/* If invariant_p ever returned 2, we return 2. */
return 1 + (value & 2);
}
@@ -3345,7 +3453,7 @@ count_one_set (insn, x, may_not_move, last_set)
in current basic block, and it was set before,
it must be set in two basic blocks, so it cannot
be moved out of the loop. */
- if (VARRAY_INT (n_times_set, regno) > 0
+ if (VARRAY_INT (set_in_loop, regno) > 0
&& last_set[regno] == 0)
VARRAY_CHAR (may_not_move, regno) = 1;
/* If this is not first setting in current basic block,
@@ -3354,16 +3462,16 @@ count_one_set (insn, x, may_not_move, last_set)
if (last_set[regno] != 0
&& reg_used_between_p (dest, last_set[regno], insn))
VARRAY_CHAR (may_not_move, regno) = 1;
- if (VARRAY_INT (n_times_set, regno) < 127)
- ++VARRAY_INT (n_times_set, regno);
+ if (VARRAY_INT (set_in_loop, regno) < 127)
+ ++VARRAY_INT (set_in_loop, regno);
last_set[regno] = insn;
}
}
}
-/* Increment N_TIMES_SET at the index of each register
+/* Increment SET_IN_LOOP at the index of each register
that is modified by an insn between FROM and TO.
- If the value of an element of N_TIMES_SET becomes 127 or more,
+ If the value of an element of SET_IN_LOOP becomes 127 or more,
stop incrementing it, to avoid overflow.
Store in SINGLE_USAGE[I] the single insn in which register I is
@@ -3388,7 +3496,6 @@ count_loop_regs_set (from, to, may_not_move, single_usage, count_ptr, nregs)
register rtx *last_set = (rtx *) alloca (nregs * sizeof (rtx));
register rtx insn;
register int count = 0;
- register rtx dest;
bzero ((char *) last_set, nregs * sizeof (rtx));
for (insn = from; insn != to; insn = NEXT_INSN (insn))
@@ -3397,15 +3504,12 @@ count_loop_regs_set (from, to, may_not_move, single_usage, count_ptr, nregs)
{
++count;
- /* If requested, record registers that have exactly one use. */
- if (single_usage)
- {
- find_single_use_in_loop (insn, PATTERN (insn), single_usage);
+ /* Record registers that have exactly one use. */
+ find_single_use_in_loop (insn, PATTERN (insn), single_usage);
- /* Include uses in REG_EQUAL notes. */
- if (REG_NOTES (insn))
- find_single_use_in_loop (insn, REG_NOTES (insn), single_usage);
- }
+ /* Include uses in REG_EQUAL notes. */
+ if (REG_NOTES (insn))
+ find_single_use_in_loop (insn, REG_NOTES (insn), single_usage);
if (GET_CODE (PATTERN (insn)) == SET
|| GET_CODE (PATTERN (insn)) == CLOBBER)
@@ -3468,13 +3572,13 @@ loop_reg_used_before_p (set, insn, loop_start, scan_start, loop_end)
/* Indexed by register number, indicates whether or not register is an
induction variable, and if so what type. */
-enum iv_mode *reg_iv_type;
+varray_type reg_iv_type;
/* Indexed by register number, contains pointer to `struct induction'
if register is an induction variable. This holds general info for
all induction variables. */
-struct induction **reg_iv_info;
+varray_type reg_iv_info;
/* Indexed by register number, contains pointer to `struct iv_class'
if register is a basic induction variable. This holds info describing
@@ -3488,6 +3592,11 @@ struct iv_class **reg_biv_class;
struct iv_class *loop_iv_list;
+/* Givs made from biv increments are always splittable for loop unrolling.
+ Since there is no regscan info for them, we have to keep track of them
+ separately. */
+int first_increment_giv, last_increment_giv;
+
/* Communication with routines called via `note_stores'. */
static rtx note_insn;
@@ -3534,24 +3643,27 @@ static rtx addr_placeholder;
SCAN_START is the first instruction in the loop, as the loop would
actually be executed. END is the NOTE_INSN_LOOP_END. LOOP_TOP is
the first instruction in the loop, as it is layed out in the
- instruction stream. LOOP_START is the NOTE_INSN_LOOP_BEG. */
+ instruction stream. LOOP_START is the NOTE_INSN_LOOP_BEG.
+ LOOP_CONT is the NOTE_INSN_LOOP_CONT. */
static void
strength_reduce (scan_start, end, loop_top, insn_count,
- loop_start, loop_end, unroll_p, bct_p)
+ loop_start, loop_end, loop_cont, unroll_p, bct_p)
rtx scan_start;
rtx end;
rtx loop_top;
int insn_count;
rtx loop_start;
rtx loop_end;
- int unroll_p, bct_p;
+ rtx loop_cont;
+ int unroll_p, bct_p ATTRIBUTE_UNUSED;
{
rtx p;
rtx set;
rtx inc_val;
rtx mult_val;
rtx dest_reg;
+ rtx *location;
/* This is 1 if current insn is not executed at least once for every loop
iteration. */
int not_every_iteration = 0;
@@ -3568,18 +3680,22 @@ strength_reduce (scan_start, end, loop_top, insn_count,
int threshold = (loop_has_call ? 1 : 2) * (3 + n_non_fixed_regs);
/* Map of pseudo-register replacements. */
rtx *reg_map;
+ int reg_map_size;
int call_seen;
rtx test;
rtx end_insert_before;
int loop_depth = 0;
+ int n_extra_increment;
+ struct loop_info loop_iteration_info;
+ struct loop_info *loop_info = &loop_iteration_info;
+
+ /* If scan_start points to the loop exit test, we have to be wary of
+ subversive use of gotos inside expression statements. */
+ if (prev_nonnote_insn (scan_start) != prev_nonnote_insn (loop_start))
+ maybe_multiple = back_branch_in_range_p (scan_start, loop_start, loop_end);
- reg_iv_type = (enum iv_mode *) alloca (max_reg_before_loop
- * sizeof (enum iv_mode *));
- bzero ((char *) reg_iv_type, max_reg_before_loop * sizeof (enum iv_mode *));
- reg_iv_info = (struct induction **)
- alloca (max_reg_before_loop * sizeof (struct induction *));
- bzero ((char *) reg_iv_info, (max_reg_before_loop
- * sizeof (struct induction *)));
+ VARRAY_INT_INIT (reg_iv_type, max_reg_before_loop, "reg_iv_type");
+ VARRAY_GENERIC_PTR_INIT (reg_iv_info, max_reg_before_loop, "reg_iv_info");
reg_biv_class = (struct iv_class **)
alloca (max_reg_before_loop * sizeof (struct iv_class *));
bzero ((char *) reg_biv_class, (max_reg_before_loop
@@ -3613,10 +3729,11 @@ strength_reduce (scan_start, end, loop_top, insn_count,
dest_reg = SET_DEST (set);
if (REGNO (dest_reg) < max_reg_before_loop
&& REGNO (dest_reg) >= FIRST_PSEUDO_REGISTER
- && reg_iv_type[REGNO (dest_reg)] != NOT_BASIC_INDUCT)
+ && REG_IV_TYPE (REGNO (dest_reg)) != NOT_BASIC_INDUCT)
{
if (basic_induction_var (SET_SRC (set), GET_MODE (SET_SRC (set)),
- dest_reg, p, &inc_val, &mult_val))
+ dest_reg, p, &inc_val, &mult_val,
+ &location))
{
/* It is a possible basic induction variable.
Create and initialize an induction structure for it. */
@@ -3624,20 +3741,20 @@ strength_reduce (scan_start, end, loop_top, insn_count,
struct induction *v
= (struct induction *) alloca (sizeof (struct induction));
- record_biv (v, p, dest_reg, inc_val, mult_val,
+ record_biv (v, p, dest_reg, inc_val, mult_val, location,
not_every_iteration, maybe_multiple);
- reg_iv_type[REGNO (dest_reg)] = BASIC_INDUCT;
+ REG_IV_TYPE (REGNO (dest_reg)) = BASIC_INDUCT;
}
else if (REGNO (dest_reg) < max_reg_before_loop)
- reg_iv_type[REGNO (dest_reg)] = NOT_BASIC_INDUCT;
+ REG_IV_TYPE (REGNO (dest_reg)) = NOT_BASIC_INDUCT;
}
}
/* Past CODE_LABEL, we get to insns that may be executed multiple
times. The only way we can be sure that they can't is if every
jump insn between here and the end of the loop either
- returns, exits the loop, is a forward jump, or is a jump
- to the loop start. */
+ returns, exits the loop, is a jump to a location that is still
+ behind the label, or is a jump to the loop start. */
if (GET_CODE (p) == CODE_LABEL)
{
@@ -3665,10 +3782,7 @@ strength_reduce (scan_start, end, loop_top, insn_count,
&& (! condjump_p (insn)
|| (JUMP_LABEL (insn) != 0
&& JUMP_LABEL (insn) != scan_start
- && (INSN_UID (JUMP_LABEL (insn)) >= max_uid_for_loop
- || INSN_UID (insn) >= max_uid_for_loop
- || (INSN_LUID (JUMP_LABEL (insn))
- < INSN_LUID (insn))))))
+ && ! loop_insn_first_p (p, JUMP_LABEL (insn)))))
{
maybe_multiple = 1;
break;
@@ -3709,8 +3823,13 @@ strength_reduce (scan_start, end, loop_top, insn_count,
{
/* At the virtual top of a converted loop, insns are again known to
be executed each iteration: logically, the loop begins here
- even though the exit code has been duplicated. */
- if (NOTE_LINE_NUMBER (p) == NOTE_INSN_LOOP_VTOP && loop_depth == 0)
+ even though the exit code has been duplicated.
+
+ Insns are also again known to be executed each iteration at
+ the LOOP_CONT note. */
+ if ((NOTE_LINE_NUMBER (p) == NOTE_INSN_LOOP_VTOP
+ || NOTE_LINE_NUMBER (p) == NOTE_INSN_LOOP_CONT)
+ && loop_depth == 0)
not_every_iteration = 0;
else if (NOTE_LINE_NUMBER (p) == NOTE_INSN_LOOP_BEG)
loop_depth++;
@@ -3728,7 +3847,8 @@ strength_reduce (scan_start, end, loop_top, insn_count,
will be executed each iteration. */
if (not_every_iteration && GET_CODE (p) == CODE_LABEL
- && no_labels_between_p (p, loop_end))
+ && no_labels_between_p (p, loop_end)
+ && loop_insn_first_p (p, loop_cont))
not_every_iteration = 0;
}
@@ -3736,7 +3856,7 @@ strength_reduce (scan_start, end, loop_top, insn_count,
Make a sanity check against n_times_set. */
for (backbl = &loop_iv_list, bl = *backbl; bl; bl = bl->next)
{
- if (reg_iv_type[bl->regno] != BASIC_INDUCT
+ if (REG_IV_TYPE (bl->regno) != BASIC_INDUCT
/* Above happens if register modified by subreg, etc. */
/* Make sure it is not recognized as a basic induction var: */
|| VARRAY_INT (n_times_set, bl->regno) != bl->biv_count
@@ -3747,12 +3867,12 @@ strength_reduce (scan_start, end, loop_top, insn_count,
if (loop_dump_stream)
fprintf (loop_dump_stream, "Reg %d: biv discarded, %s\n",
bl->regno,
- (reg_iv_type[bl->regno] != BASIC_INDUCT
+ (REG_IV_TYPE (bl->regno) != BASIC_INDUCT
? "not induction variable"
: (! bl->incremented ? "never incremented"
: "count error")));
- reg_iv_type[bl->regno] = NOT_BASIC_INDUCT;
+ REG_IV_TYPE (bl->regno) = NOT_BASIC_INDUCT;
*backbl = bl->next;
}
else
@@ -3770,7 +3890,8 @@ strength_reduce (scan_start, end, loop_top, insn_count,
/* Can still unroll the loop anyways, but indicate that there is no
strength reduction info available. */
if (unroll_p)
- unroll_loop (loop_end, insn_count, loop_start, end_insert_before, 0);
+ unroll_loop (loop_end, insn_count, loop_start, end_insert_before,
+ loop_info, 0);
return;
}
@@ -3818,7 +3939,7 @@ strength_reduce (scan_start, end, loop_top, insn_count,
/* Look at the each biv and see if we can say anything better about its
initial value from any initializing insns set up above. (This is done
in two passes to avoid missing SETs in a PARALLEL.) */
- for (bl = loop_iv_list; bl; bl = bl->next)
+ for (backbl = &loop_iv_list; (bl = *backbl); backbl = &bl->next)
{
rtx src;
rtx note;
@@ -3863,14 +3984,347 @@ strength_reduce (scan_start, end, loop_top, insn_count,
}
else
{
- /* Biv initial value is not simple move,
- so let it keep initial value of "itself". */
+ struct iv_class *bl2 = 0;
+ rtx increment;
+
+ /* Biv initial value is not a simple move. If it is the sum of
+ another biv and a constant, check if both bivs are incremented
+ in lockstep. Then we are actually looking at a giv.
+ For simplicity, we only handle the case where there is but a
+ single increment, and the register is not used elsewhere. */
+ if (bl->biv_count == 1
+ && bl->regno < max_reg_before_loop
+ && uid_luid[REGNO_LAST_UID (bl->regno)] < INSN_LUID (loop_end)
+ && GET_CODE (src) == PLUS
+ && GET_CODE (XEXP (src, 0)) == REG
+ && CONSTANT_P (XEXP (src, 1))
+ && ((increment = biv_total_increment (bl, loop_start, loop_end))
+ != NULL_RTX))
+ {
+ int regno = REGNO (XEXP (src, 0));
- if (loop_dump_stream)
+ for (bl2 = loop_iv_list; bl2; bl2 = bl2->next)
+ if (bl2->regno == regno)
+ break;
+ }
+
+ /* Now, can we transform this biv into a giv? */
+ if (bl2
+ && bl2->biv_count == 1
+ && rtx_equal_p (increment,
+ biv_total_increment (bl2, loop_start, loop_end))
+ /* init_insn is only set to insns that are before loop_start
+ without any intervening labels. */
+ && ! reg_set_between_p (bl2->biv->src_reg,
+ PREV_INSN (bl->init_insn), loop_start)
+ /* The register from BL2 must be set before the register from
+ BL is set, or we must be able to move the latter set after
+ the former set. Currently there can't be any labels
+ in-between when biv_toal_increment returns nonzero both times
+ but we test it here in case some day some real cfg analysis
+ gets used to set always_computable. */
+ && ((loop_insn_first_p (bl2->biv->insn, bl->biv->insn)
+ && no_labels_between_p (bl2->biv->insn, bl->biv->insn))
+ || (! reg_used_between_p (bl->biv->src_reg, bl->biv->insn,
+ bl2->biv->insn)
+ && no_jumps_between_p (bl->biv->insn, bl2->biv->insn)))
+ && validate_change (bl->biv->insn,
+ &SET_SRC (single_set (bl->biv->insn)),
+ copy_rtx (src), 0))
+ {
+ int loop_num = uid_loop_num[INSN_UID (loop_start)];
+ rtx dominator = loop_number_cont_dominator[loop_num];
+ rtx giv = bl->biv->src_reg;
+ rtx giv_insn = bl->biv->insn;
+ rtx after_giv = NEXT_INSN (giv_insn);
+
+ if (loop_dump_stream)
+ fprintf (loop_dump_stream, "is giv of biv %d\n", bl2->regno);
+ /* Let this giv be discovered by the generic code. */
+ REG_IV_TYPE (bl->regno) = UNKNOWN_INDUCT;
+ /* We can get better optimization if we can move the giv setting
+ before the first giv use. */
+ if (dominator
+ && ! loop_insn_first_p (dominator, scan_start)
+ && ! reg_set_between_p (bl2->biv->src_reg, loop_start,
+ dominator)
+ && ! reg_used_between_p (giv, loop_start, dominator)
+ && ! reg_used_between_p (giv, giv_insn, loop_end))
+ {
+ rtx p;
+ rtx next;
+
+ for (next = NEXT_INSN (dominator); ; next = NEXT_INSN (next))
+ {
+ if ((GET_RTX_CLASS (GET_CODE (next)) == 'i'
+ && (reg_mentioned_p (giv, PATTERN (next))
+ || reg_set_p (bl2->biv->src_reg, next)))
+ || GET_CODE (next) == JUMP_INSN)
+ break;
+#ifdef HAVE_cc0
+ if (GET_RTX_CLASS (GET_CODE (next)) != 'i'
+ || ! sets_cc0_p (PATTERN (next)))
+#endif
+ dominator = next;
+ }
+ if (loop_dump_stream)
+ fprintf (loop_dump_stream, "move after insn %d\n",
+ INSN_UID (dominator));
+ /* Avoid problems with luids by actually moving the insn
+ and adjusting all luids in the range. */
+ reorder_insns (giv_insn, giv_insn, dominator);
+ for (p = dominator; INSN_UID (p) >= max_uid_for_loop; )
+ p = PREV_INSN (p);
+ compute_luids (giv_insn, after_giv, INSN_LUID (p));
+ /* If the only purpose of the init insn is to initialize
+ this giv, delete it. */
+ if (single_set (bl->init_insn)
+ && ! reg_used_between_p (giv, bl->init_insn, loop_start))
+ delete_insn (bl->init_insn);
+ }
+ else if (! loop_insn_first_p (bl2->biv->insn, bl->biv->insn))
+ {
+ rtx p = PREV_INSN (giv_insn);
+ while (INSN_UID (p) >= max_uid_for_loop)
+ p = PREV_INSN (p);
+ reorder_insns (giv_insn, giv_insn, bl2->biv->insn);
+ compute_luids (after_giv, NEXT_INSN (giv_insn),
+ INSN_LUID (p));
+ }
+ /* Remove this biv from the chain. */
+ if (bl->next)
+ *bl = *bl->next;
+ else
+ {
+ *backbl = 0;
+ break;
+ }
+ }
+
+ /* If we can't make it a giv,
+ let biv keep initial value of "itself". */
+ else if (loop_dump_stream)
fprintf (loop_dump_stream, "is complex\n");
}
}
+ /* If a biv is unconditionally incremented several times in a row, convert
+ all but the last increment into a giv. */
+
+ /* Get an upper bound for the number of registers
+ we might have after all bivs have been processed. */
+ first_increment_giv = max_reg_num ();
+ for (n_extra_increment = 0, bl = loop_iv_list; bl; bl = bl->next)
+ n_extra_increment += bl->biv_count - 1;
+
+ /* If the loop contains volatile memory references do not allow any
+ replacements to take place, since this could loose the volatile markers. */
+ /* XXX Temporary. */
+ if (0 && n_extra_increment && ! loop_has_volatile)
+ {
+ int nregs = first_increment_giv + n_extra_increment;
+
+ /* Reallocate reg_iv_type and reg_iv_info. */
+ VARRAY_GROW (reg_iv_type, nregs);
+ VARRAY_GROW (reg_iv_info, nregs);
+
+ for (bl = loop_iv_list; bl; bl = bl->next)
+ {
+ struct induction **vp, *v, *next;
+ int biv_dead_after_loop = 0;
+
+ /* The biv increments lists are in reverse order. Fix this first. */
+ for (v = bl->biv, bl->biv = 0; v; v = next)
+ {
+ next = v->next_iv;
+ v->next_iv = bl->biv;
+ bl->biv = v;
+ }
+
+ /* We must guard against the case that an early exit between v->insn
+ and next->insn leaves the biv live after the loop, since that
+ would mean that we'd be missing an increment for the final
+ value. The following test to set biv_dead_after_loop is like
+ the first part of the test to set bl->eliminable.
+ We don't check here if we can calculate the final value, since
+ this can't succeed if we already know that there is a jump
+ between v->insn and next->insn, yet next->always_executed is
+ set and next->maybe_multiple is cleared. Such a combination
+ implies that the jump destination is outside the loop.
+ If we want to make this check more sophisticated, we should
+ check each branch between v->insn and next->insn individually
+ to see if the biv is dead at its destination. */
+
+ if (uid_luid[REGNO_LAST_UID (bl->regno)] < INSN_LUID (loop_end)
+ && bl->init_insn
+ && INSN_UID (bl->init_insn) < max_uid_for_loop
+ && (uid_luid[REGNO_FIRST_UID (bl->regno)]
+ >= INSN_LUID (bl->init_insn))
+#ifdef HAVE_decrement_and_branch_until_zero
+ && ! bl->nonneg
+#endif
+ && ! reg_mentioned_p (bl->biv->dest_reg, SET_SRC (bl->init_set)))
+ biv_dead_after_loop = 1;
+
+ for (vp = &bl->biv, next = *vp; v = next, next = v->next_iv;)
+ {
+ HOST_WIDE_INT offset;
+ rtx set, add_val, old_reg, dest_reg, last_use_insn;
+ int old_regno, new_regno;
+
+ if (! v->always_executed
+ || v->maybe_multiple
+ || GET_CODE (v->add_val) != CONST_INT
+ || ! next->always_executed
+ || next->maybe_multiple
+ || ! CONSTANT_P (next->add_val)
+ || ! (biv_dead_after_loop
+ || no_jumps_between_p (v->insn, next->insn)))
+ {
+ vp = &v->next_iv;
+ continue;
+ }
+ offset = INTVAL (v->add_val);
+ set = single_set (v->insn);
+ add_val = plus_constant (next->add_val, offset);
+ old_reg = v->dest_reg;
+ dest_reg = gen_reg_rtx (v->mode);
+
+ /* Unlike reg_iv_type / reg_iv_info, the other three arrays
+ have been allocated with some slop space, so we may not
+ actually need to reallocate them. If we do, the following
+ if statement will be executed just once in this loop. */
+ if ((unsigned) max_reg_num () > n_times_set->num_elements)
+ {
+ /* Grow all the remaining arrays. */
+ VARRAY_GROW (set_in_loop, nregs);
+ VARRAY_GROW (n_times_set, nregs);
+ VARRAY_GROW (may_not_optimize, nregs);
+ }
+
+ if (! validate_change (next->insn, next->location, add_val, 0))
+ {
+ vp = &v->next_iv;
+ continue;
+ }
+
+ /* Here we can try to eliminate the increment by combining
+ it into the uses. */
+
+ /* Set last_use_insn so that we can check against it. */
+
+ for (last_use_insn = v->insn, p = NEXT_INSN (v->insn);
+ p != next->insn;
+ p = next_insn_in_loop (p, scan_start, end, loop_top))
+ {
+ if (GET_RTX_CLASS (GET_CODE (p)) != 'i')
+ continue;
+ if (reg_mentioned_p (old_reg, PATTERN (p)))
+ {
+ last_use_insn = p;
+ }
+ }
+
+ /* If we can't get the LUIDs for the insns, we can't
+ calculate the lifetime. This is likely from unrolling
+ of an inner loop, so there is little point in making this
+ a DEST_REG giv anyways. */
+ if (INSN_UID (v->insn) >= max_uid_for_loop
+ || INSN_UID (last_use_insn) >= max_uid_for_loop
+ || ! validate_change (v->insn, &SET_DEST (set), dest_reg, 0))
+ {
+ /* Change the increment at NEXT back to what it was. */
+ if (! validate_change (next->insn, next->location,
+ next->add_val, 0))
+ abort ();
+ vp = &v->next_iv;
+ continue;
+ }
+ next->add_val = add_val;
+ v->dest_reg = dest_reg;
+ v->giv_type = DEST_REG;
+ v->location = &SET_SRC (set);
+ v->cant_derive = 0;
+ v->combined_with = 0;
+ v->maybe_dead = 0;
+ v->derive_adjustment = 0;
+ v->same = 0;
+ v->ignore = 0;
+ v->new_reg = 0;
+ v->final_value = 0;
+ v->same_insn = 0;
+ v->auto_inc_opt = 0;
+ v->unrolled = 0;
+ v->shared = 0;
+ v->derived_from = 0;
+ v->always_computable = 1;
+ v->always_executed = 1;
+ v->replaceable = 1;
+ v->no_const_addval = 0;
+
+ old_regno = REGNO (old_reg);
+ new_regno = REGNO (dest_reg);
+ VARRAY_INT (set_in_loop, old_regno)--;
+ VARRAY_INT (set_in_loop, new_regno) = 1;
+ VARRAY_INT (n_times_set, old_regno)--;
+ VARRAY_INT (n_times_set, new_regno) = 1;
+ VARRAY_CHAR (may_not_optimize, new_regno) = 0;
+
+ REG_IV_TYPE (new_regno) = GENERAL_INDUCT;
+ REG_IV_INFO (new_regno) = v;
+
+ /* Remove the increment from the list of biv increments,
+ and record it as a giv. */
+ *vp = next;
+ bl->biv_count--;
+ v->next_iv = bl->giv;
+ bl->giv = v;
+ bl->giv_count++;
+ v->benefit = rtx_cost (SET_SRC (set), SET);
+ bl->total_benefit += v->benefit;
+
+ /* Now replace the biv with DEST_REG in all insns between
+ the replaced increment and the next increment, and
+ remember the last insn that needed a replacement. */
+ for (last_use_insn = v->insn, p = NEXT_INSN (v->insn);
+ p != next->insn;
+ p = next_insn_in_loop (p, scan_start, end, loop_top))
+ {
+ rtx note;
+
+ if (GET_RTX_CLASS (GET_CODE (p)) != 'i')
+ continue;
+ if (reg_mentioned_p (old_reg, PATTERN (p)))
+ {
+ last_use_insn = p;
+ if (! validate_replace_rtx (old_reg, dest_reg, p))
+ abort ();
+ }
+ for (note = REG_NOTES (p); note; note = XEXP (note, 1))
+ {
+ if (GET_CODE (note) == EXPR_LIST)
+ XEXP (note, 0)
+ = replace_rtx (XEXP (note, 0), old_reg, dest_reg);
+ }
+ }
+
+ v->last_use = last_use_insn;
+ v->lifetime = INSN_LUID (v->insn) - INSN_LUID (last_use_insn);
+ /* If the lifetime is zero, it means that this register is really
+ a dead store. So mark this as a giv that can be ignored.
+ This will not prevent the biv from being eliminated. */
+ if (v->lifetime == 0)
+ v->ignore = 1;
+
+ if (loop_dump_stream)
+ fprintf (loop_dump_stream,
+ "Increment %d of biv %d converted to giv %d.\n\n",
+ INSN_UID (v->insn), old_regno, new_regno);
+ }
+ }
+ }
+ last_increment_giv = max_reg_num () - 1;
+
/* Search the loop for general induction variables. */
/* A register is a giv if: it is only set once, it is a function of a
@@ -3907,6 +4361,7 @@ strength_reduce (scan_start, end, loop_top, insn_count,
rtx mult_val;
int benefit;
rtx regnote = 0;
+ rtx last_consec_insn;
dest_reg = SET_DEST (set);
if (REGNO (dest_reg) < FIRST_PSEUDO_REGISTER)
@@ -3930,31 +4385,19 @@ strength_reduce (scan_start, end, loop_top, insn_count,
/* or all sets must be consecutive and make a giv. */
|| (benefit = consec_sets_giv (benefit, p,
src_reg, dest_reg,
- &add_val, &mult_val))))
+ &add_val, &mult_val,
+ &last_consec_insn))))
{
- int count;
struct induction *v
= (struct induction *) alloca (sizeof (struct induction));
- rtx temp;
/* If this is a library call, increase benefit. */
if (find_reg_note (p, REG_RETVAL, NULL_RTX))
benefit += libcall_benefit (p);
/* Skip the consecutive insns, if there are any. */
- for (count = VARRAY_INT (n_times_set, REGNO (dest_reg)) - 1;
- count > 0; count--)
- {
- /* If first insn of libcall sequence, skip to end.
- Do this at start of loop, since INSN is guaranteed to
- be an insn here. */
- if (GET_CODE (p) != NOTE
- && (temp = find_reg_note (p, REG_LIBCALL, NULL_RTX)))
- p = XEXP (temp, 0);
-
- do p = NEXT_INSN (p);
- while (GET_CODE (p) == NOTE);
- }
+ if (VARRAY_INT (n_times_set, REGNO (dest_reg)) != 1)
+ p = last_consec_insn;
record_giv (v, p, src_reg, dest_reg, mult_val, add_val, benefit,
DEST_REG, not_every_iteration, NULL_PTR, loop_start,
@@ -4011,8 +4454,13 @@ strength_reduce (scan_start, end, loop_top, insn_count,
{
/* At the virtual top of a converted loop, insns are again known to
be executed each iteration: logically, the loop begins here
- even though the exit code has been duplicated. */
- if (NOTE_LINE_NUMBER (p) == NOTE_INSN_LOOP_VTOP && loop_depth == 0)
+ even though the exit code has been duplicated.
+
+ Insns are also again known to be executed each iteration at
+ the LOOP_CONT note. */
+ if ((NOTE_LINE_NUMBER (p) == NOTE_INSN_LOOP_VTOP
+ || NOTE_LINE_NUMBER (p) == NOTE_INSN_LOOP_CONT)
+ && loop_depth == 0)
not_every_iteration = 0;
else if (NOTE_LINE_NUMBER (p) == NOTE_INSN_LOOP_BEG)
loop_depth++;
@@ -4030,7 +4478,8 @@ strength_reduce (scan_start, end, loop_top, insn_count,
will be executed each iteration. */
if (not_every_iteration && GET_CODE (p) == CODE_LABEL
- && no_labels_between_p (p, loop_end))
+ && no_labels_between_p (p, loop_end)
+ && loop_insn_first_p (p, loop_cont))
not_every_iteration = 0;
}
@@ -4039,7 +4488,7 @@ strength_reduce (scan_start, end, loop_top, insn_count,
be called after all giv's have been identified, since otherwise it may
fail if the iteration variable is a giv. */
- loop_n_iterations = loop_iterations (loop_start, loop_end);
+ loop_iterations (loop_start, loop_end, loop_info);
/* Now for each giv for which we still don't know whether or not it is
replaceable, check to see if it is replaceable because its final value
@@ -4052,17 +4501,20 @@ strength_reduce (scan_start, end, loop_top, insn_count,
for (v = bl->giv; v; v = v->next_iv)
if (! v->replaceable && ! v->not_replaceable)
- check_final_value (v, loop_start, loop_end);
+ check_final_value (v, loop_start, loop_end, loop_info->n_iterations);
}
/* Try to prove that the loop counter variable (if any) is always
nonnegative; if so, record that fact with a REG_NONNEG note
so that "decrement and branch until zero" insn can be used. */
- check_dbra_loop (loop_end, insn_count, loop_start);
+ check_dbra_loop (loop_end, insn_count, loop_start, loop_info);
- /* Create reg_map to hold substitutions for replaceable giv regs. */
- reg_map = (rtx *) alloca (max_reg_before_loop * sizeof (rtx));
- bzero ((char *) reg_map, max_reg_before_loop * sizeof (rtx));
+ /* Create reg_map to hold substitutions for replaceable giv regs.
+ Some givs might have been made from biv increments, so look at
+ reg_iv_type for a suitable size. */
+ reg_map_size = reg_iv_type->num_elements;
+ reg_map = (rtx *) alloca (reg_map_size * sizeof (rtx));
+ bzero ((char *) reg_map, reg_map_size * sizeof (rtx));
/* Examine each iv class for feasibility of strength reduction/induction
variable elimination. */
@@ -4073,6 +4525,7 @@ strength_reduce (scan_start, end, loop_top, insn_count,
int benefit;
int all_reduced;
rtx final_value = 0;
+ unsigned nregs;
/* Test whether it will be possible to eliminate this biv
provided all givs are reduced. This is possible if either
@@ -4098,7 +4551,8 @@ strength_reduce (scan_start, end, loop_top, insn_count,
&& ! bl->nonneg
#endif
&& ! reg_mentioned_p (bl->biv->dest_reg, SET_SRC (bl->init_set)))
- || ((final_value = final_biv_value (bl, loop_start, loop_end))
+ || ((final_value = final_biv_value (bl, loop_start, loop_end,
+ loop_info->n_iterations))
#ifdef HAVE_decrement_and_branch_until_zero
&& ! bl->nonneg
#endif
@@ -4167,14 +4621,18 @@ strength_reduce (scan_start, end, loop_top, insn_count,
if (v->giv_type == DEST_ADDR
&& GET_CODE (v->mult_val) == CONST_INT)
{
-#if defined (HAVE_POST_INCREMENT) || defined (HAVE_PRE_INCREMENT)
- if (INTVAL (v->mult_val) == GET_MODE_SIZE (v->mem_mode))
+ if (HAVE_POST_INCREMENT
+ && INTVAL (v->mult_val) == GET_MODE_SIZE (v->mem_mode))
benefit += add_cost * bl->biv_count;
-#endif
-#if defined (HAVE_POST_DECREMENT) || defined (HAVE_PRE_DECREMENT)
- if (-INTVAL (v->mult_val) == GET_MODE_SIZE (v->mem_mode))
+ else if (HAVE_PRE_INCREMENT
+ && INTVAL (v->mult_val) == GET_MODE_SIZE (v->mem_mode))
+ benefit += add_cost * bl->biv_count;
+ else if (HAVE_POST_DECREMENT
+ && -INTVAL (v->mult_val) == GET_MODE_SIZE (v->mem_mode))
+ benefit += add_cost * bl->biv_count;
+ else if (HAVE_PRE_DECREMENT
+ && -INTVAL (v->mult_val) == GET_MODE_SIZE (v->mem_mode))
benefit += add_cost * bl->biv_count;
-#endif
}
#endif
@@ -4218,6 +4676,57 @@ strength_reduce (scan_start, end, loop_top, insn_count,
}
}
+ /* Check for givs whose first use is their definition and whose
+ last use is the definition of another giv. If so, it is likely
+ dead and should not be used to derive another giv nor to
+ eliminate a biv. */
+ for (v = bl->giv; v; v = v->next_iv)
+ {
+ if (v->ignore
+ || (v->same && v->same->ignore))
+ continue;
+
+ if (v->last_use)
+ {
+ struct induction *v1;
+
+ for (v1 = bl->giv; v1; v1 = v1->next_iv)
+ if (v->last_use == v1->insn)
+ v->maybe_dead = 1;
+ }
+ else if (v->giv_type == DEST_REG
+ && REGNO_FIRST_UID (REGNO (v->dest_reg)) == INSN_UID (v->insn))
+ {
+ struct induction *v1;
+
+ for (v1 = bl->giv; v1; v1 = v1->next_iv)
+ if (REGNO_LAST_UID (REGNO (v->dest_reg)) == INSN_UID (v1->insn))
+ v->maybe_dead = 1;
+ }
+ }
+
+#if 0
+ /* XXX Temporary. */
+ /* Now that we know which givs will be reduced, try to rearrange the
+ combinations to reduce register pressure.
+ recombine_givs calls find_life_end, which needs reg_iv_type and
+ reg_iv_info to be valid for all pseudos. We do the necessary
+ reallocation here since it allows to check if there are still
+ more bivs to process. */
+ nregs = max_reg_num ();
+ if (nregs > reg_iv_type->num_elements)
+ {
+ /* If there are still more bivs to process, allocate some slack
+ space so that we're not constantly reallocating these arrays. */
+ if (bl->next)
+ nregs += nregs / 4;
+ /* Reallocate reg_iv_type and reg_iv_info. */
+ VARRAY_GROW (reg_iv_type, nregs);
+ VARRAY_GROW (reg_iv_info, nregs);
+ }
+ recombine_givs (bl, loop_start, loop_end, unroll_p);
+#endif
+
/* Reduce each giv that we decided to reduce. */
for (v = bl->giv; v; v = v->next_iv)
@@ -4227,7 +4736,41 @@ strength_reduce (scan_start, end, loop_top, insn_count,
{
int auto_inc_opt = 0;
- v->new_reg = gen_reg_rtx (v->mode);
+ /* If the code for derived givs immediately below has already
+ allocated a new_reg, we must keep it. */
+ if (! v->new_reg)
+ v->new_reg = gen_reg_rtx (v->mode);
+
+ if (v->derived_from)
+ {
+ struct induction *d = v->derived_from;
+
+ /* In case d->dest_reg is not replaceable, we have
+ to replace it in v->insn now. */
+ if (! d->new_reg)
+ d->new_reg = gen_reg_rtx (d->mode);
+ PATTERN (v->insn)
+ = replace_rtx (PATTERN (v->insn), d->dest_reg, d->new_reg);
+ PATTERN (v->insn)
+ = replace_rtx (PATTERN (v->insn), v->dest_reg, v->new_reg);
+ if (bl->biv_count != 1)
+ {
+ /* For each place where the biv is incremented, add an
+ insn to set the new, reduced reg for the giv. */
+ for (tv = bl->biv; tv; tv = tv->next_iv)
+ {
+ /* We always emit reduced giv increments before the
+ biv increment when bl->biv_count != 1. So by
+ emitting the add insns for derived givs after the
+ biv increment, they pick up the updated value of
+ the reduced giv. */
+ emit_insn_after (copy_rtx (PATTERN (v->insn)),
+ tv->insn);
+
+ }
+ }
+ continue;
+ }
#ifdef AUTO_INC_DEC
/* If the target has auto-increment addressing modes, and
@@ -4341,11 +4884,8 @@ strength_reduce (scan_start, end, loop_top, insn_count,
For each giv register that can be reduced now: if replaceable,
substitute reduced reg wherever the old giv occurs;
- else add new move insn "giv_reg = reduced_reg".
+ else add new move insn "giv_reg = reduced_reg". */
- Also check for givs whose first use is their definition and whose
- last use is the definition of another giv. If so, it is likely
- dead and should not be used to eliminate a biv. */
for (v = bl->giv; v; v = v->next_iv)
{
if (v->same && v->same->ignore)
@@ -4354,16 +4894,6 @@ strength_reduce (scan_start, end, loop_top, insn_count,
if (v->ignore)
continue;
- if (v->giv_type == DEST_REG
- && REGNO_FIRST_UID (REGNO (v->dest_reg)) == INSN_UID (v->insn))
- {
- struct induction *v1;
-
- for (v1 = bl->giv; v1; v1 = v1->next_iv)
- if (REGNO_LAST_UID (REGNO (v->dest_reg)) == INSN_UID (v1->insn))
- v->maybe_dead = 1;
- }
-
/* Update expression if this was combined, in case other giv was
replaced. */
if (v->same)
@@ -4547,8 +5077,8 @@ strength_reduce (scan_start, end, loop_top, insn_count,
if (GET_CODE (p) == INSN || GET_CODE (p) == JUMP_INSN
|| GET_CODE (p) == CALL_INSN)
{
- replace_regs (PATTERN (p), reg_map, max_reg_before_loop, 0);
- replace_regs (REG_NOTES (p), reg_map, max_reg_before_loop, 0);
+ replace_regs (PATTERN (p), reg_map, reg_map_size, 0);
+ replace_regs (REG_NOTES (p), reg_map, reg_map_size, 0);
INSN_CODE (p) = -1;
}
@@ -4557,17 +5087,20 @@ strength_reduce (scan_start, end, loop_top, insn_count,
collected. */
if (unroll_p)
- unroll_loop (loop_end, insn_count, loop_start, end_insert_before, 1);
+ unroll_loop (loop_end, insn_count, loop_start, end_insert_before,
+ loop_info, 1);
#ifdef HAVE_decrement_and_branch_on_count
/* Instrument the loop with BCT insn. */
if (HAVE_decrement_and_branch_on_count && bct_p
&& flag_branch_on_count_reg)
- insert_bct (loop_start, loop_end);
+ insert_bct (loop_start, loop_end, loop_info);
#endif /* HAVE_decrement_and_branch_on_count */
if (loop_dump_stream)
fprintf (loop_dump_stream, "\n");
+ VARRAY_FREE (reg_iv_type);
+ VARRAY_FREE (reg_iv_info);
}
/* Return 1 if X is a valid source for an initial value (or as value being
@@ -4707,13 +5240,14 @@ find_mem_givs (x, insn, not_every_iteration, loop_start, loop_end)
executed exactly once per iteration. */
static void
-record_biv (v, insn, dest_reg, inc_val, mult_val,
+record_biv (v, insn, dest_reg, inc_val, mult_val, location,
not_every_iteration, maybe_multiple)
struct induction *v;
rtx insn;
rtx dest_reg;
rtx inc_val;
rtx mult_val;
+ rtx *location;
int not_every_iteration;
int maybe_multiple;
{
@@ -4724,6 +5258,7 @@ record_biv (v, insn, dest_reg, inc_val, mult_val,
v->dest_reg = dest_reg;
v->mult_val = mult_val;
v->add_val = inc_val;
+ v->location = location;
v->mode = GET_MODE (dest_reg);
v->always_computable = ! not_every_iteration;
v->always_executed = ! not_every_iteration;
@@ -4844,6 +5379,8 @@ record_giv (v, insn, src_reg, dest_reg, mult_val, add_val, benefit,
v->auto_inc_opt = 0;
v->unrolled = 0;
v->shared = 0;
+ v->derived_from = 0;
+ v->last_use = 0;
/* The v->always_computable field is used in update_giv_derive, to
determine whether a giv can be used to derive another giv. For a
@@ -4864,7 +5401,6 @@ record_giv (v, insn, src_reg, dest_reg, mult_val, add_val, benefit,
{
v->mode = GET_MODE (*location);
v->lifetime = 1;
- v->times_used = 1;
}
else /* type == DEST_REG */
{
@@ -4873,16 +5409,14 @@ record_giv (v, insn, src_reg, dest_reg, mult_val, add_val, benefit,
v->lifetime = (uid_luid[REGNO_LAST_UID (REGNO (dest_reg))]
- uid_luid[REGNO_FIRST_UID (REGNO (dest_reg))]);
- v->times_used = VARRAY_INT (n_times_used, REGNO (dest_reg));
-
/* If the lifetime is zero, it means that this register is
really a dead store. So mark this as a giv that can be
ignored. This will not prevent the biv from being eliminated. */
if (v->lifetime == 0)
v->ignore = 1;
- reg_iv_type[REGNO (dest_reg)] = GENERAL_INDUCT;
- reg_iv_info[REGNO (dest_reg)] = v;
+ REG_IV_TYPE (REGNO (dest_reg)) = GENERAL_INDUCT;
+ REG_IV_INFO (REGNO (dest_reg)) = v;
}
/* Add the giv to the class of givs computed from one biv. */
@@ -5008,8 +5542,8 @@ record_giv (v, insn, src_reg, dest_reg, mult_val, add_val, benefit,
fprintf (loop_dump_stream, " src reg %d benefit %d",
REGNO (src_reg), v->benefit);
- fprintf (loop_dump_stream, " used %d lifetime %d",
- v->times_used, v->lifetime);
+ fprintf (loop_dump_stream, " lifetime %d",
+ v->lifetime);
if (v->replaceable)
fprintf (loop_dump_stream, " replaceable");
@@ -5053,9 +5587,10 @@ record_giv (v, insn, src_reg, dest_reg, mult_val, add_val, benefit,
have been identified. */
static void
-check_final_value (v, loop_start, loop_end)
+check_final_value (v, loop_start, loop_end, n_iterations)
struct induction *v;
rtx loop_start, loop_end;
+ unsigned HOST_WIDE_INT n_iterations;
{
struct iv_class *bl;
rtx final_value = 0;
@@ -5082,7 +5617,7 @@ check_final_value (v, loop_start, loop_end)
v->replaceable = 0;
#endif
- if ((final_value = final_giv_value (v, loop_start, loop_end))
+ if ((final_value = final_giv_value (v, loop_start, loop_end, n_iterations))
&& (v->always_computable || last_use_this_basic_block (v->dest_reg, v->insn)))
{
int biv_increment_seen = 0;
@@ -5155,13 +5690,10 @@ check_final_value (v, loop_start, loop_end)
if (GET_CODE (p) == JUMP_INSN && JUMP_LABEL (p)
&& LABEL_NAME (JUMP_LABEL (p))
- && ((INSN_UID (JUMP_LABEL (p)) >= max_uid_for_loop)
- || (INSN_UID (v->insn) >= max_uid_for_loop)
- || (INSN_UID (last_giv_use) >= max_uid_for_loop)
- || (INSN_LUID (JUMP_LABEL (p)) < INSN_LUID (v->insn)
- && INSN_LUID (JUMP_LABEL (p)) > INSN_LUID (loop_start))
- || (INSN_LUID (JUMP_LABEL (p)) > INSN_LUID (last_giv_use)
- && INSN_LUID (JUMP_LABEL (p)) < INSN_LUID (loop_end))))
+ && ((loop_insn_first_p (JUMP_LABEL (p), v->insn)
+ && loop_insn_first_p (loop_start, JUMP_LABEL (p)))
+ || (loop_insn_first_p (last_giv_use, JUMP_LABEL (p))
+ && loop_insn_first_p (JUMP_LABEL (p), loop_end))))
{
v->replaceable = 0;
v->not_replaceable = 1;
@@ -5296,7 +5828,8 @@ update_giv_derive (p)
REG = INVARIANT + REG
If X is suitable, we return 1, set *MULT_VAL to CONST1_RTX,
- and store the additive term into *INC_VAL.
+ store the additive term into *INC_VAL, and store the place where
+ we found the additive term into *LOCATION.
If X is an assignment of an invariant into DEST_REG, we set
*MULT_VAL to CONST0_RTX, and store the invariant into *INC_VAL.
@@ -5323,16 +5856,17 @@ update_giv_derive (p)
If we cannot find a biv, we return 0. */
static int
-basic_induction_var (x, mode, dest_reg, p, inc_val, mult_val)
+basic_induction_var (x, mode, dest_reg, p, inc_val, mult_val, location)
register rtx x;
enum machine_mode mode;
rtx p;
rtx dest_reg;
rtx *inc_val;
rtx *mult_val;
+ rtx **location;
{
register enum rtx_code code;
- rtx arg;
+ rtx *argp, arg;
rtx insn, set = 0;
code = GET_CODE (x);
@@ -5343,20 +5877,26 @@ basic_induction_var (x, mode, dest_reg, p, inc_val, mult_val)
|| (GET_CODE (XEXP (x, 0)) == SUBREG
&& SUBREG_PROMOTED_VAR_P (XEXP (x, 0))
&& SUBREG_REG (XEXP (x, 0)) == dest_reg))
- arg = XEXP (x, 1);
+ {
+ argp = &XEXP (x, 1);
+ }
else if (rtx_equal_p (XEXP (x, 1), dest_reg)
|| (GET_CODE (XEXP (x, 1)) == SUBREG
&& SUBREG_PROMOTED_VAR_P (XEXP (x, 1))
&& SUBREG_REG (XEXP (x, 1)) == dest_reg))
- arg = XEXP (x, 0);
+ {
+ argp = &XEXP (x, 0);
+ }
else
return 0;
+ arg = *argp;
if (invariant_p (arg) != 1)
return 0;
*inc_val = convert_modes (GET_MODE (dest_reg), GET_MODE (x), arg, 0);
*mult_val = const1_rtx;
+ *location = argp;
return 1;
case SUBREG:
@@ -5364,7 +5904,7 @@ basic_induction_var (x, mode, dest_reg, p, inc_val, mult_val)
value. */
if (SUBREG_PROMOTED_VAR_P (x))
return basic_induction_var (SUBREG_REG (x), GET_MODE (SUBREG_REG (x)),
- dest_reg, p, inc_val, mult_val);
+ dest_reg, p, inc_val, mult_val, location);
return 0;
case REG:
@@ -5395,7 +5935,7 @@ basic_induction_var (x, mode, dest_reg, p, inc_val, mult_val)
? GET_MODE (x)
: GET_MODE (SET_SRC (set))),
dest_reg, insn,
- inc_val, mult_val))
+ inc_val, mult_val, location))
return 1;
}
/* ... fall through ... */
@@ -5427,7 +5967,7 @@ basic_induction_var (x, mode, dest_reg, p, inc_val, mult_val)
case SIGN_EXTEND:
return basic_induction_var (XEXP (x, 0), GET_MODE (XEXP (x, 0)),
- dest_reg, p, inc_val, mult_val);
+ dest_reg, p, inc_val, mult_val, location);
case ASHIFTRT:
/* Similar, since this can be a sign extension. */
@@ -5447,7 +5987,8 @@ basic_induction_var (x, mode, dest_reg, p, inc_val, mult_val)
&& XEXP (x, 1) == XEXP (SET_SRC (set), 1))
return basic_induction_var (XEXP (SET_SRC (set), 0),
GET_MODE (XEXP (x, 0)),
- dest_reg, insn, inc_val, mult_val);
+ dest_reg, insn, inc_val, mult_val,
+ location);
return 0;
default:
@@ -5814,13 +6355,13 @@ simplify_giv_expr (x, benefit)
return 0;
/* Check for biv or giv. */
- switch (reg_iv_type[REGNO (x)])
+ switch (REG_IV_TYPE (REGNO (x)))
{
case BASIC_INDUCT:
return x;
case GENERAL_INDUCT:
{
- struct induction *v = reg_iv_info[REGNO (x)];
+ struct induction *v = REG_IV_INFO (REGNO (x));
/* Form expression from giv and add benefit. Ensure this giv
can derive another and subtract any needed adjustment if so. */
@@ -6000,13 +6541,14 @@ sge_plus (mode, x, y)
static int
consec_sets_giv (first_benefit, p, src_reg, dest_reg,
- add_val, mult_val)
+ add_val, mult_val, last_consec_insn)
int first_benefit;
rtx p;
rtx src_reg;
rtx dest_reg;
rtx *add_val;
rtx *mult_val;
+ rtx *last_consec_insn;
{
int count;
enum rtx_code code;
@@ -6030,8 +6572,8 @@ consec_sets_giv (first_benefit, p, src_reg, dest_reg,
v->cant_derive = 0;
v->derive_adjustment = 0;
- reg_iv_type[REGNO (dest_reg)] = GENERAL_INDUCT;
- reg_iv_info[REGNO (dest_reg)] = v;
+ REG_IV_TYPE (REGNO (dest_reg)) = GENERAL_INDUCT;
+ REG_IV_INFO (REGNO (dest_reg)) = v;
count = VARRAY_INT (n_times_set, REGNO (dest_reg)) - 1;
@@ -6075,11 +6617,12 @@ consec_sets_giv (first_benefit, p, src_reg, dest_reg,
&& CONSTANT_P (SET_SRC (set)))
continue;
- reg_iv_type[REGNO (dest_reg)] = UNKNOWN_INDUCT;
+ REG_IV_TYPE (REGNO (dest_reg)) = UNKNOWN_INDUCT;
return 0;
}
}
+ *last_consec_insn = p;
return v->benefit;
}
@@ -6192,7 +6735,7 @@ express_from_1 (a, b, mult)
return NULL_RTX;
}
-static rtx
+rtx
express_from (g1, g2)
struct induction *g1, *g2;
{
@@ -6232,7 +6775,18 @@ express_from (g1, g2)
if (add == const0_rtx)
return mult;
else
- return gen_rtx_PLUS (g2->mode, mult, add);
+ {
+ if (GET_CODE (add) == PLUS
+ && CONSTANT_P (XEXP (add, 1)))
+ {
+ rtx tem = XEXP (add, 1);
+ mult = gen_rtx_PLUS (g2->mode, mult, XEXP (add, 0));
+ add = tem;
+ }
+
+ return gen_rtx_PLUS (g2->mode, mult, add);
+ }
+
}
/* Return an rtx, if any, that expresses giv G2 as a function of the register
@@ -6249,7 +6803,10 @@ combine_givs_p (g1, g2)
/* If these givs are identical, they can be combined. We use the results
of express_from because the addends are not in a canonical form, so
rtx_equal_p is a weaker test. */
- if (tem == g1->dest_reg)
+ /* But don't combine a DEST_REG giv with a DEST_ADDR giv; we want the
+ combination to be the other way round. */
+ if (tem == g1->dest_reg
+ && (g1->giv_type == DEST_REG || g2->giv_type == DEST_ADDR))
{
return g1->dest_reg;
}
@@ -6296,40 +6853,6 @@ cmp_combine_givs_stats (x, y)
return d;
}
-/* If one of these givs is a DEST_REG that was only used once, by the
- other giv, this is actually a single use. Return 0 if this is not
- the case, -1 if g1 is the DEST_REG involved, and 1 if it was g2. */
-
-static int
-combine_givs_used_once (g1, g2)
- struct induction *g1, *g2;
-{
- if (g1->giv_type == DEST_REG
- && VARRAY_INT (n_times_used, REGNO (g1->dest_reg)) == 1
- && reg_mentioned_p (g1->dest_reg, PATTERN (g2->insn)))
- return -1;
-
- if (g2->giv_type == DEST_REG
- && VARRAY_INT (n_times_used, REGNO (g2->dest_reg)) == 1
- && reg_mentioned_p (g2->dest_reg, PATTERN (g1->insn)))
- return 1;
-
- return 0;
-}
-
-static int
-combine_givs_benefit_from (g1, g2)
- struct induction *g1, *g2;
-{
- int tmp = combine_givs_used_once (g1, g2);
- if (tmp < 0)
- return 0;
- else if (tmp > 0)
- return g2->benefit - g1->benefit;
- else
- return g2->benefit;
-}
-
/* Check all pairs of givs for iv_class BL and see if any can be combined with
any other. If so, point SAME to the giv combined with and set NEW_REG to
be an expression (in terms of the other giv's DEST_REG) equivalent to the
@@ -6339,6 +6862,9 @@ static void
combine_givs (bl)
struct iv_class *bl;
{
+ /* Additional benefit to add for being combined multiple times. */
+ const int extra_benefit = 3;
+
struct induction *g1, *g2, **giv_array;
int i, j, k, giv_count;
struct combine_givs_stats *stats;
@@ -6366,13 +6892,27 @@ combine_givs (bl)
for (i = 0; i < giv_count; i++)
{
int this_benefit;
+ rtx single_use;
g1 = giv_array[i];
+ stats[i].giv_number = i;
+
+ /* If a DEST_REG GIV is used only once, do not allow it to combine
+ with anything, for in doing so we will gain nothing that cannot
+ be had by simply letting the GIV with which we would have combined
+ to be reduced on its own. The losage shows up in particular with
+ DEST_ADDR targets on hosts with reg+reg addressing, though it can
+ be seen elsewhere as well. */
+ if (g1->giv_type == DEST_REG
+ && (single_use = VARRAY_RTX (reg_single_usage, REGNO (g1->dest_reg)))
+ && single_use != const0_rtx)
+ continue;
this_benefit = g1->benefit;
/* Add an additional weight for zero addends. */
if (g1->no_const_addval)
this_benefit += 1;
+
for (j = 0; j < giv_count; j++)
{
rtx this_combine;
@@ -6382,12 +6922,9 @@ combine_givs (bl)
&& (this_combine = combine_givs_p (g1, g2)) != NULL_RTX)
{
can_combine[i*giv_count + j] = this_combine;
- this_benefit += combine_givs_benefit_from (g1, g2);
- /* Add an additional weight for being reused more times. */
- this_benefit += 3;
+ this_benefit += g2->benefit + extra_benefit;
}
}
- stats[i].giv_number = i;
stats[i].total_benefit = this_benefit;
}
@@ -6431,12 +6968,10 @@ restart:
g2->new_reg = can_combine[i*giv_count + j];
g2->same = g1;
- g1->combined_with = 1;
- if (!combine_givs_used_once (g1, g2))
- g1->times_used += 1;
+ g1->combined_with++;
g1->lifetime += g2->lifetime;
- g1_add_benefit += combine_givs_benefit_from (g1, g2);
+ g1_add_benefit += g2->benefit;
/* ??? The new final_[bg]iv_value code does a much better job
of finding replaceable giv's, and hence this code may no
@@ -6450,11 +6985,7 @@ restart:
{
int m = stats[l].giv_number;
if (can_combine[m*giv_count + j])
- {
- /* Remove additional weight for being reused. */
- stats[l].total_benefit -= 3 +
- combine_givs_benefit_from (giv_array[m], g2);
- }
+ stats[l].total_benefit -= g2->benefit + extra_benefit;
}
if (loop_dump_stream)
@@ -6471,12 +7002,8 @@ restart:
for (j = 0; j < giv_count; ++j)
{
int m = stats[j].giv_number;
- if (can_combine[m*giv_count + j])
- {
- /* Remove additional weight for being reused. */
- stats[j].total_benefit -= 3 +
- combine_givs_benefit_from (giv_array[m], g1);
- }
+ if (can_combine[m*giv_count + i])
+ stats[j].total_benefit -= g1->benefit + extra_benefit;
}
g1->benefit += g1_add_benefit;
@@ -6492,6 +7019,428 @@ restart:
}
}
+struct recombine_givs_stats
+{
+ int giv_number;
+ int start_luid, end_luid;
+};
+
+/* Used below as comparison function for qsort. We want a ascending luid
+ when scanning the array starting at the end, thus the arguments are
+ used in reverse. */
+static int
+cmp_recombine_givs_stats (x, y)
+ struct recombine_givs_stats *x, *y;
+{
+ int d;
+ d = y->start_luid - x->start_luid;
+ /* Stabilize the sort. */
+ if (!d)
+ d = y->giv_number - x->giv_number;
+ return d;
+}
+
+/* Scan X, which is a part of INSN, for the end of life of a giv. Also
+ look for the start of life of a giv where the start has not been seen
+ yet to unlock the search for the end of its life.
+ Only consider givs that belong to BIV.
+ Return the total number of lifetime ends that have been found. */
+static int
+find_life_end (x, stats, insn, biv)
+ rtx x, insn, biv;
+ struct recombine_givs_stats *stats;
+{
+ enum rtx_code code;
+ char *fmt;
+ int i, j;
+ int retval;
+
+ code = GET_CODE (x);
+ switch (code)
+ {
+ case SET:
+ {
+ rtx reg = SET_DEST (x);
+ if (GET_CODE (reg) == REG)
+ {
+ int regno = REGNO (reg);
+ struct induction *v = REG_IV_INFO (regno);
+
+ if (REG_IV_TYPE (regno) == GENERAL_INDUCT
+ && ! v->ignore
+ && v->src_reg == biv
+ && stats[v->ix].end_luid <= 0)
+ {
+ /* If we see a 0 here for end_luid, it means that we have
+ scanned the entire loop without finding any use at all.
+ We must not predicate this code on a start_luid match
+ since that would make the test fail for givs that have
+ been hoisted out of inner loops. */
+ if (stats[v->ix].end_luid == 0)
+ {
+ stats[v->ix].end_luid = stats[v->ix].start_luid;
+ return 1 + find_life_end (SET_SRC (x), stats, insn, biv);
+ }
+ else if (stats[v->ix].start_luid == INSN_LUID (insn))
+ stats[v->ix].end_luid = 0;
+ }
+ return find_life_end (SET_SRC (x), stats, insn, biv);
+ }
+ break;
+ }
+ case REG:
+ {
+ int regno = REGNO (x);
+ struct induction *v = REG_IV_INFO (regno);
+
+ if (REG_IV_TYPE (regno) == GENERAL_INDUCT
+ && ! v->ignore
+ && v->src_reg == biv
+ && stats[v->ix].end_luid == 0)
+ {
+ while (INSN_UID (insn) >= max_uid_for_loop)
+ insn = NEXT_INSN (insn);
+ stats[v->ix].end_luid = INSN_LUID (insn);
+ return 1;
+ }
+ return 0;
+ }
+ case LABEL_REF:
+ case CONST_DOUBLE:
+ case CONST_INT:
+ case CONST:
+ return 0;
+ default:
+ break;
+ }
+ fmt = GET_RTX_FORMAT (code);
+ retval = 0;
+ for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
+ {
+ if (fmt[i] == 'e')
+ retval += find_life_end (XEXP (x, i), stats, insn, biv);
+
+ else if (fmt[i] == 'E')
+ for (j = XVECLEN (x, i) - 1; j >= 0; j--)
+ retval += find_life_end (XVECEXP (x, i, j), stats, insn, biv);
+ }
+ return retval;
+}
+
+/* For each giv that has been combined with another, look if
+ we can combine it with the most recently used one instead.
+ This tends to shorten giv lifetimes, and helps the next step:
+ try to derive givs from other givs. */
+static void
+recombine_givs (bl, loop_start, loop_end, unroll_p)
+ struct iv_class *bl;
+ rtx loop_start, loop_end;
+ int unroll_p;
+{
+ struct induction *v, **giv_array, *last_giv;
+ struct recombine_givs_stats *stats;
+ int giv_count;
+ int i, rescan;
+ int ends_need_computing;
+
+ for (giv_count = 0, v = bl->giv; v; v = v->next_iv)
+ {
+ if (! v->ignore)
+ giv_count++;
+ }
+ giv_array
+ = (struct induction **) alloca (giv_count * sizeof (struct induction *));
+ stats = (struct recombine_givs_stats *) alloca (giv_count * sizeof *stats);
+
+ /* Initialize stats and set up the ix field for each giv in stats to name
+ the corresponding index into stats. */
+ for (i = 0, v = bl->giv; v; v = v->next_iv)
+ {
+ rtx p;
+
+ if (v->ignore)
+ continue;
+ giv_array[i] = v;
+ stats[i].giv_number = i;
+ /* If this giv has been hoisted out of an inner loop, use the luid of
+ the previous insn. */
+ for (p = v->insn; INSN_UID (p) >= max_uid_for_loop; )
+ p = PREV_INSN (p);
+ stats[i].start_luid = INSN_LUID (p);
+ v->ix = i;
+ i++;
+ }
+
+ qsort (stats, giv_count, sizeof(*stats), cmp_recombine_givs_stats);
+
+ /* Do the actual most-recently-used recombination. */
+ for (last_giv = 0, i = giv_count - 1; i >= 0; i--)
+ {
+ v = giv_array[stats[i].giv_number];
+ if (v->same)
+ {
+ struct induction *old_same = v->same;
+ rtx new_combine;
+
+ /* combine_givs_p actually says if we can make this transformation.
+ The other tests are here only to avoid keeping a giv alive
+ that could otherwise be eliminated. */
+ if (last_giv
+ && ((old_same->maybe_dead && ! old_same->combined_with)
+ || ! last_giv->maybe_dead
+ || last_giv->combined_with)
+ && (new_combine = combine_givs_p (last_giv, v)))
+ {
+ old_same->combined_with--;
+ v->new_reg = new_combine;
+ v->same = last_giv;
+ last_giv->combined_with++;
+ /* No need to update lifetimes / benefits here since we have
+ already decided what to reduce. */
+
+ if (loop_dump_stream)
+ {
+ fprintf (loop_dump_stream,
+ "giv at %d recombined with giv at %d as ",
+ INSN_UID (v->insn), INSN_UID (last_giv->insn));
+ print_rtl (loop_dump_stream, v->new_reg);
+ putc ('\n', loop_dump_stream);
+ }
+ continue;
+ }
+ v = v->same;
+ }
+ else if (v->giv_type != DEST_REG)
+ continue;
+ if (! last_giv
+ || (last_giv->maybe_dead && ! last_giv->combined_with)
+ || ! v->maybe_dead
+ || v->combined_with)
+ last_giv = v;
+ }
+
+ ends_need_computing = 0;
+ /* For each DEST_REG giv, compute lifetime starts, and try to compute
+ lifetime ends from regscan info. */
+ for (i = 0, v = bl->giv; v; v = v->next_iv)
+ {
+ if (v->ignore)
+ continue;
+ if (v->giv_type == DEST_ADDR)
+ {
+ /* Loop unrolling of an inner loop can even create new DEST_REG
+ givs. */
+ rtx p;
+ for (p = v->insn; INSN_UID (p) >= max_uid_for_loop; )
+ p = PREV_INSN (p);
+ stats[i].start_luid = stats[i].end_luid = INSN_LUID (p);
+ if (p != v->insn)
+ stats[i].end_luid++;
+ }
+ else /* v->giv_type == DEST_REG */
+ {
+ if (v->last_use)
+ {
+ stats[i].start_luid = INSN_LUID (v->insn);
+ stats[i].end_luid = INSN_LUID (v->last_use);
+ }
+ else if (INSN_UID (v->insn) >= max_uid_for_loop)
+ {
+ rtx p;
+ /* This insn has been created by loop optimization on an inner
+ loop. We don't have a proper start_luid that will match
+ when we see the first set. But we do know that there will
+ be no use before the set, so we can set end_luid to 0 so that
+ we'll start looking for the last use right away. */
+ for (p = PREV_INSN (v->insn); INSN_UID (p) >= max_uid_for_loop; )
+ p = PREV_INSN (p);
+ stats[i].start_luid = INSN_LUID (p);
+ stats[i].end_luid = 0;
+ ends_need_computing++;
+ }
+ else
+ {
+ int regno = REGNO (v->dest_reg);
+ int count = VARRAY_INT (n_times_set, regno) - 1;
+ rtx p = v->insn;
+
+ /* Find the first insn that sets the giv, so that we can verify
+ if this giv's lifetime wraps around the loop. We also need
+ the luid of the first setting insn in order to detect the
+ last use properly. */
+ while (count)
+ {
+ p = prev_nonnote_insn (p);
+ if (reg_set_p (v->dest_reg, p))
+ count--;
+ }
+
+ stats[i].start_luid = INSN_LUID (p);
+ if (stats[i].start_luid > uid_luid[REGNO_FIRST_UID (regno)])
+ {
+ stats[i].end_luid = -1;
+ ends_need_computing++;
+ }
+ else
+ {
+ stats[i].end_luid = uid_luid[REGNO_LAST_UID (regno)];
+ if (stats[i].end_luid > INSN_LUID (loop_end))
+ {
+ stats[i].end_luid = -1;
+ ends_need_computing++;
+ }
+ }
+ }
+ }
+ i++;
+ }
+
+ /* If the regscan information was unconclusive for one or more DEST_REG
+ givs, scan the all insn in the loop to find out lifetime ends. */
+ if (ends_need_computing)
+ {
+ rtx biv = bl->biv->src_reg;
+ rtx p = loop_end;
+
+ do
+ {
+ if (p == loop_start)
+ p = loop_end;
+ p = PREV_INSN (p);
+ if (GET_RTX_CLASS (GET_CODE (p)) != 'i')
+ continue;
+ ends_need_computing -= find_life_end (PATTERN (p), stats, p, biv);
+ }
+ while (ends_need_computing);
+ }
+
+ /* Set start_luid back to the last insn that sets the giv. This allows
+ more combinations. */
+ for (i = 0, v = bl->giv; v; v = v->next_iv)
+ {
+ if (v->ignore)
+ continue;
+ if (INSN_UID (v->insn) < max_uid_for_loop)
+ stats[i].start_luid = INSN_LUID (v->insn);
+ i++;
+ }
+
+ /* Now adjust lifetime ends by taking combined givs into account. */
+ for (i = 0, v = bl->giv; v; v = v->next_iv)
+ {
+ unsigned luid;
+ int j;
+
+ if (v->ignore)
+ continue;
+ if (v->same && ! v->same->ignore)
+ {
+ j = v->same->ix;
+ luid = stats[i].start_luid;
+ /* Use unsigned arithmetic to model loop wrap-around. */
+ if (luid - stats[j].start_luid
+ > (unsigned) stats[j].end_luid - stats[j].start_luid)
+ stats[j].end_luid = luid;
+ }
+ i++;
+ }
+
+ qsort (stats, giv_count, sizeof(*stats), cmp_recombine_givs_stats);
+
+ /* Try to derive DEST_REG givs from previous DEST_REG givs with the
+ same mult_val and non-overlapping lifetime. This reduces register
+ pressure.
+ Once we find a DEST_REG giv that is suitable to derive others from,
+ we set last_giv to this giv, and try to derive as many other DEST_REG
+ givs from it without joining overlapping lifetimes. If we then
+ encounter a DEST_REG giv that we can't derive, we set rescan to the
+ index for this giv (unless rescan is already set).
+ When we are finished with the current LAST_GIV (i.e. the inner loop
+ terminates), we start again with rescan, which then becomes the new
+ LAST_GIV. */
+ for (i = giv_count - 1; i >= 0; i = rescan)
+ {
+ int life_start, life_end;
+
+ for (last_giv = 0, rescan = -1; i >= 0; i--)
+ {
+ rtx sum;
+
+ v = giv_array[stats[i].giv_number];
+ if (v->giv_type != DEST_REG || v->derived_from || v->same)
+ continue;
+ if (! last_giv)
+ {
+ /* Don't use a giv that's likely to be dead to derive
+ others - that would be likely to keep that giv alive. */
+ if (! v->maybe_dead || v->combined_with)
+ {
+ last_giv = v;
+ life_start = stats[i].start_luid;
+ life_end = stats[i].end_luid;
+ }
+ continue;
+ }
+ /* Use unsigned arithmetic to model loop wrap around. */
+ if (((unsigned) stats[i].start_luid - life_start
+ >= (unsigned) life_end - life_start)
+ && ((unsigned) stats[i].end_luid - life_start
+ > (unsigned) life_end - life_start)
+ /* Check that the giv insn we're about to use for deriving
+ precedes all uses of that giv. Note that initializing the
+ derived giv would defeat the purpose of reducing register
+ pressure.
+ ??? We could arrange to move the insn. */
+ && ((unsigned) stats[i].end_luid - INSN_LUID (loop_start)
+ > (unsigned) stats[i].start_luid - INSN_LUID (loop_start))
+ && rtx_equal_p (last_giv->mult_val, v->mult_val)
+ /* ??? Could handle libcalls, but would need more logic. */
+ && ! find_reg_note (v->insn, REG_RETVAL, NULL_RTX)
+ /* We would really like to know if for any giv that v
+ is combined with, v->insn or any intervening biv increment
+ dominates that combined giv. However, we
+ don't have this detailed control flow information.
+ N.B. since last_giv will be reduced, it is valid
+ anywhere in the loop, so we don't need to check the
+ validity of last_giv.
+ We rely here on the fact that v->always_executed implies that
+ there is no jump to someplace else in the loop before the
+ giv insn, and hence any insn that is executed before the
+ giv insn in the loop will have a lower luid. */
+ && (v->always_executed || ! v->combined_with)
+ && (sum = express_from (last_giv, v))
+ /* Make sure we don't make the add more expensive. ADD_COST
+ doesn't take different costs of registers and constants into
+ account, so compare the cost of the actual SET_SRCs. */
+ && (rtx_cost (sum, SET)
+ <= rtx_cost (SET_SRC (single_set (v->insn)), SET))
+ /* ??? unroll can't understand anything but reg + const_int
+ sums. It would be cleaner to fix unroll. */
+ && ((GET_CODE (sum) == PLUS
+ && GET_CODE (XEXP (sum, 0)) == REG
+ && GET_CODE (XEXP (sum, 1)) == CONST_INT)
+ || ! unroll_p)
+ && validate_change (v->insn, &PATTERN (v->insn),
+ gen_rtx_SET (VOIDmode, v->dest_reg, sum), 0))
+ {
+ v->derived_from = last_giv;
+ life_end = stats[i].end_luid;
+
+ if (loop_dump_stream)
+ {
+ fprintf (loop_dump_stream,
+ "giv at %d derived from %d as ",
+ INSN_UID (v->insn), INSN_UID (last_giv->insn));
+ print_rtl (loop_dump_stream, sum);
+ putc ('\n', loop_dump_stream);
+ }
+ }
+ else if (rescan < 0)
+ rescan = i;
+ }
+ }
+}
+
/* EMIT code before INSERT_BEFORE to set REG = B * M + A. */
void
@@ -6633,10 +7582,11 @@ product_cheap_p (a, b)
final_[bg]iv_value. */
static int
-check_dbra_loop (loop_end, insn_count, loop_start)
+check_dbra_loop (loop_end, insn_count, loop_start, loop_info)
rtx loop_end;
int insn_count;
rtx loop_start;
+ struct loop_info *loop_info;
{
struct iv_class *bl;
rtx reg;
@@ -6807,9 +7757,25 @@ check_dbra_loop (loop_end, insn_count, loop_start)
case, the insn should have been moved out of the loop. */
if (num_mem_sets == 1)
- reversible_mem_store
- = (! unknown_address_altered
- && ! invariant_p (XEXP (loop_store_mems[0], 0)));
+ {
+ struct induction *v;
+
+ reversible_mem_store
+ = (! unknown_address_altered
+ && ! invariant_p (XEXP (loop_store_mems, 0)));
+
+ /* If the store depends on a register that is set after the
+ store, it depends on the initial value, and is thus not
+ reversible. */
+ for (v = bl->giv; reversible_mem_store && v; v = v->next_iv)
+ {
+ if (v->giv_type == DEST_REG
+ && reg_mentioned_p (v->dest_reg,
+ XEXP (loop_store_mems, 0))
+ && loop_insn_first_p (first_loop_store_insn, v->insn))
+ reversible_mem_store = 0;
+ }
+ }
}
else
return 0;
@@ -6858,12 +7824,15 @@ check_dbra_loop (loop_end, insn_count, loop_start)
enum rtx_code cmp_code;
int comparison_const_width;
unsigned HOST_WIDE_INT comparison_sign_mask;
- rtx vtop;
add_val = INTVAL (bl->biv->add_val);
comparison_value = XEXP (comparison, 1);
- comparison_const_width
- = GET_MODE_BITSIZE (GET_MODE (XEXP (comparison, 1)));
+ if (GET_MODE (comparison_value) == VOIDmode)
+ comparison_const_width
+ = GET_MODE_BITSIZE (GET_MODE (XEXP (comparison, 0)));
+ else
+ comparison_const_width
+ = GET_MODE_BITSIZE (GET_MODE (comparison_value));
if (comparison_const_width > HOST_BITS_PER_WIDE_INT)
comparison_const_width = HOST_BITS_PER_WIDE_INT;
comparison_sign_mask
@@ -6905,25 +7874,6 @@ check_dbra_loop (loop_end, insn_count, loop_start)
initial_value = const0_rtx;
}
- /* Check if there is a NOTE_INSN_LOOP_VTOP note. If there is,
- that means that this is a for or while style loop, with
- a loop exit test at the start. Thus, we can assume that
- the loop condition was true when the loop was entered.
- This allows us to change the loop exit condition to an
- equality test.
- We start at the end and search backwards for the previous
- NOTE. If there is no NOTE_INSN_LOOP_VTOP for this loop,
- the search will stop at the NOTE_INSN_LOOP_CONT. */
- vtop = loop_end;
- do
- vtop = PREV_INSN (vtop);
- while (GET_CODE (vtop) != NOTE
- || NOTE_LINE_NUMBER (vtop) > 0
- || NOTE_LINE_NUMBER (vtop) == NOTE_REPEATED_LINE_NUMBER
- || NOTE_LINE_NUMBER (vtop) == NOTE_INSN_DELETED);
- if (NOTE_LINE_NUMBER (vtop) != NOTE_INSN_LOOP_VTOP)
- vtop = NULL_RTX;
-
/* First check if we can do a vanilla loop reversal. */
if (initial_value == const0_rtx
/* If we have a decrement_and_branch_on_count, prefer
@@ -6932,7 +7882,7 @@ check_dbra_loop (loop_end, insn_count, loop_start)
reversal if the biv is used to calculate a giv or has
a non-counting use. */
#if ! defined (HAVE_decrement_and_branch_until_zero) && defined (HAVE_decrement_and_branch_on_count)
- && (! (add_val == 1 && vtop
+ && (! (add_val == 1 && loop_info->vtop
&& (bl->biv_count == 0
|| no_use_except_counting)))
#endif
@@ -6947,7 +7897,7 @@ check_dbra_loop (loop_end, insn_count, loop_start)
nonneg = 1;
cmp_code = GE;
}
- else if (add_val == 1 && vtop
+ else if (add_val == 1 && loop_info->vtop
&& (bl->biv_count == 0
|| no_use_except_counting))
{
@@ -7049,10 +7999,14 @@ check_dbra_loop (loop_end, insn_count, loop_start)
better to have a testcase first. */
return 0;
- /* Add insn to decrement register, and delete insn
- that incremented the register. */
- p = emit_insn_before (gen_add2_insn (reg, new_add_val),
- bl->biv->insn);
+ /* We may not have a single insn which can increment a reg, so
+ create a sequence to hold all the insns from expand_inc. */
+ start_sequence ();
+ expand_inc (reg, new_add_val);
+ tem = gen_sequence ();
+ end_sequence ();
+
+ p = emit_insn_before (tem, bl->biv->insn);
delete_insn (bl->biv->insn);
/* Update biv info to reflect its new status. */
@@ -7060,6 +8014,15 @@ check_dbra_loop (loop_end, insn_count, loop_start)
bl->initial_value = start_value;
bl->biv->add_val = new_add_val;
+ /* Update loop info. */
+ loop_info->initial_value = reg;
+ loop_info->initial_equiv_value = reg;
+ loop_info->final_value = const0_rtx;
+ loop_info->final_equiv_value = const0_rtx;
+ loop_info->comparison_value = const0_rtx;
+ loop_info->comparison_code = cmp_code;
+ loop_info->increment = new_add_val;
+
/* Inc LABEL_NUSES so that delete_insn will
not delete the label. */
LABEL_NUSES (XEXP (jump_label, 0)) ++;
@@ -7079,24 +8042,25 @@ check_dbra_loop (loop_end, insn_count, loop_start)
/* Add new compare/branch insn at end of loop. */
start_sequence ();
- emit_cmp_insn (reg, const0_rtx, cmp_code, NULL_RTX,
- GET_MODE (reg), 0, 0);
- emit_jump_insn ((*bcc_gen_fctn[(int) cmp_code])
- (XEXP (jump_label, 0)));
+ emit_cmp_and_jump_insns (reg, const0_rtx, cmp_code, NULL_RTX,
+ GET_MODE (reg), 0, 0,
+ XEXP (jump_label, 0));
tem = gen_sequence ();
end_sequence ();
emit_jump_insn_before (tem, loop_end);
+ for (tem = PREV_INSN (loop_end);
+ tem && GET_CODE (tem) != JUMP_INSN;
+ tem = PREV_INSN (tem))
+ ;
+
+ if (tem)
+ JUMP_LABEL (tem) = XEXP (jump_label, 0);
+
if (nonneg)
{
- for (tem = PREV_INSN (loop_end);
- tem && GET_CODE (tem) != JUMP_INSN;
- tem = PREV_INSN (tem))
- ;
if (tem)
{
- JUMP_LABEL (tem) = XEXP (jump_label, 0);
-
/* Increment of LABEL_NUSES done above. */
/* Register is now always nonnegative,
so add REG_NONNEG note to the branch. */
@@ -7113,8 +8077,13 @@ check_dbra_loop (loop_end, insn_count, loop_start)
bl->reversed = 1;
if (loop_dump_stream)
- fprintf (loop_dump_stream,
- "Reversed loop and added reg_nonneg\n");
+ {
+ fprintf (loop_dump_stream, "Reversed loop");
+ if (bl->nonneg)
+ fprintf (loop_dump_stream, " and added reg_nonneg\n");
+ else
+ fprintf (loop_dump_stream, "\n");
+ }
return 1;
}
@@ -7176,6 +8145,73 @@ maybe_eliminate_biv (bl, loop_start, end, eliminate_p, threshold, insn_count)
return 0;
}
+/* INSN and REFERENCE are instructions in the same insn chain.
+ Return non-zero if INSN is first. */
+
+int
+loop_insn_first_p (insn, reference)
+ rtx insn, reference;
+{
+ rtx p, q;
+
+ for (p = insn, q = reference; ;)
+ {
+ /* Start with test for not first so that INSN == REFERENCE yields not
+ first. */
+ if (q == insn || ! p)
+ return 0;
+ if (p == reference || ! q)
+ return 1;
+
+ if (INSN_UID (p) < max_uid_for_loop
+ && INSN_UID (q) < max_uid_for_loop)
+ return INSN_LUID (p) < INSN_LUID (q);
+
+ if (INSN_UID (p) >= max_uid_for_loop)
+ p = NEXT_INSN (p);
+ if (INSN_UID (q) >= max_uid_for_loop)
+ q = NEXT_INSN (q);
+ }
+}
+
+/* We are trying to eliminate BIV in INSN using GIV. Return non-zero if
+ the offset that we have to take into account due to auto-increment /
+ div derivation is zero. */
+static int
+biv_elimination_giv_has_0_offset (biv, giv, insn)
+ struct induction *biv, *giv;
+ rtx insn;
+{
+ /* If the giv V had the auto-inc address optimization applied
+ to it, and INSN occurs between the giv insn and the biv
+ insn, then we'd have to adjust the value used here.
+ This is rare, so we don't bother to make this possible. */
+ if (giv->auto_inc_opt
+ && ((loop_insn_first_p (giv->insn, insn)
+ && loop_insn_first_p (insn, biv->insn))
+ || (loop_insn_first_p (biv->insn, insn)
+ && loop_insn_first_p (insn, giv->insn))))
+ return 0;
+
+ /* If the giv V was derived from another giv, and INSN does
+ not occur between the giv insn and the biv insn, then we'd
+ have to adjust the value used here. This is rare, so we don't
+ bother to make this possible. */
+ if (giv->derived_from
+ && ! (giv->always_executed
+ && loop_insn_first_p (giv->insn, insn)
+ && loop_insn_first_p (insn, biv->insn)))
+ return 0;
+ if (giv->same
+ && giv->same->derived_from
+ && ! (giv->same->always_executed
+ && loop_insn_first_p (giv->same->insn, insn)
+ && loop_insn_first_p (insn, biv->insn)))
+ return 0;
+
+ return 1;
+}
+
/* If BL appears in X (part of the pattern of INSN), see if we can
eliminate its use. If so, return 1. If not, return 0.
@@ -7241,15 +8277,7 @@ maybe_eliminate_biv_1 (x, insn, bl, eliminate_p, where)
&& v->mode == mode
&& 0)
{
- /* If the giv V had the auto-inc address optimization applied
- to it, and INSN occurs between the giv insn and the biv
- insn, then we must adjust the value used here.
- This is rare, so we don't bother to do so. */
- if (v->auto_inc_opt
- && ((INSN_LUID (v->insn) < INSN_LUID (insn)
- && INSN_LUID (insn) < INSN_LUID (bl->biv->insn))
- || (INSN_LUID (v->insn) > INSN_LUID (insn)
- && INSN_LUID (insn) > INSN_LUID (bl->biv->insn))))
+ if (! biv_elimination_giv_has_0_offset (bl->biv, v, insn))
continue;
if (! eliminate_p)
@@ -7284,15 +8312,7 @@ maybe_eliminate_biv_1 (x, insn, bl, eliminate_p, where)
|| (GET_CODE (v->add_val) == REG
&& REGNO_POINTER_FLAG (REGNO (v->add_val)))))
{
- /* If the giv V had the auto-inc address optimization applied
- to it, and INSN occurs between the giv insn and the biv
- insn, then we must adjust the value used here.
- This is rare, so we don't bother to do so. */
- if (v->auto_inc_opt
- && ((INSN_LUID (v->insn) < INSN_LUID (insn)
- && INSN_LUID (insn) < INSN_LUID (bl->biv->insn))
- || (INSN_LUID (v->insn) > INSN_LUID (insn)
- && INSN_LUID (insn) > INSN_LUID (bl->biv->insn))))
+ if (! biv_elimination_giv_has_0_offset (bl->biv, v, insn))
continue;
if (! eliminate_p)
@@ -7357,15 +8377,7 @@ maybe_eliminate_biv_1 (x, insn, bl, eliminate_p, where)
&& ! v->ignore && ! v->maybe_dead && v->always_computable
&& v->mode == mode)
{
- /* If the giv V had the auto-inc address optimization applied
- to it, and INSN occurs between the giv insn and the biv
- insn, then we must adjust the value used here.
- This is rare, so we don't bother to do so. */
- if (v->auto_inc_opt
- && ((INSN_LUID (v->insn) < INSN_LUID (insn)
- && INSN_LUID (insn) < INSN_LUID (bl->biv->insn))
- || (INSN_LUID (v->insn) > INSN_LUID (insn)
- && INSN_LUID (insn) > INSN_LUID (bl->biv->insn))))
+ if (! biv_elimination_giv_has_0_offset (bl->biv, v, insn))
continue;
if (! eliminate_p)
@@ -7408,15 +8420,7 @@ maybe_eliminate_biv_1 (x, insn, bl, eliminate_p, where)
{
rtx tem;
- /* If the giv V had the auto-inc address optimization applied
- to it, and INSN occurs between the giv insn and the biv
- insn, then we must adjust the value used here.
- This is rare, so we don't bother to do so. */
- if (v->auto_inc_opt
- && ((INSN_LUID (v->insn) < INSN_LUID (insn)
- && INSN_LUID (insn) < INSN_LUID (bl->biv->insn))
- || (INSN_LUID (v->insn) > INSN_LUID (insn)
- && INSN_LUID (insn) > INSN_LUID (bl->biv->insn))))
+ if (! biv_elimination_giv_has_0_offset (bl->biv, v, insn))
continue;
if (! eliminate_p)
@@ -7452,15 +8456,7 @@ maybe_eliminate_biv_1 (x, insn, bl, eliminate_p, where)
{
rtx tem;
- /* If the giv V had the auto-inc address optimization applied
- to it, and INSN occurs between the giv insn and the biv
- insn, then we must adjust the value used here.
- This is rare, so we don't bother to do so. */
- if (v->auto_inc_opt
- && ((INSN_LUID (v->insn) < INSN_LUID (insn)
- && INSN_LUID (insn) < INSN_LUID (bl->biv->insn))
- || (INSN_LUID (v->insn) > INSN_LUID (insn)
- && INSN_LUID (insn) > INSN_LUID (bl->biv->insn))))
+ if (! biv_elimination_giv_has_0_offset (bl->biv, v, insn))
continue;
if (! eliminate_p)
@@ -7496,7 +8492,7 @@ maybe_eliminate_biv_1 (x, insn, bl, eliminate_p, where)
#if 0
/* Otherwise the reg compared with had better be a biv. */
if (GET_CODE (arg) != REG
- || reg_iv_type[REGNO (arg)] != BASIC_INDUCT)
+ || REG_IV_TYPE (REGNO (arg)) != BASIC_INDUCT)
return 0;
/* Look for a pair of givs, one for each biv,
@@ -7514,15 +8510,7 @@ maybe_eliminate_biv_1 (x, insn, bl, eliminate_p, where)
&& rtx_equal_p (tv->add_val, v->add_val)
&& tv->mode == mode)
{
- /* If the giv V had the auto-inc address optimization applied
- to it, and INSN occurs between the giv insn and the biv
- insn, then we must adjust the value used here.
- This is rare, so we don't bother to do so. */
- if (v->auto_inc_opt
- && ((INSN_LUID (v->insn) < INSN_LUID (insn)
- && INSN_LUID (insn) < INSN_LUID (bl->biv->insn))
- || (INSN_LUID (v->insn) > INSN_LUID (insn)
- && INSN_LUID (insn) > INSN_LUID (bl->biv->insn))))
+ if (! biv_elimination_giv_has_0_offset (bl->biv, v, insn))
continue;
if (! eliminate_p)
@@ -7609,7 +8597,7 @@ record_initial (dest, set)
if (GET_CODE (dest) != REG
|| REGNO (dest) >= max_reg_before_loop
- || reg_iv_type[REGNO (dest)] != BASIC_INDUCT)
+ || REG_IV_TYPE (REGNO (dest)) != BASIC_INDUCT)
return;
bl = reg_biv_class[REGNO (dest)];
@@ -7766,7 +8754,14 @@ get_condition (jump, earliest)
like Alpha that have an IEEE compliant EQ instruction, and
a non-IEEE compliant BEQ instruction. The use of CCmode is
actually artificial, simply to prevent the combination, but
- should not affect other platforms. */
+ should not affect other platforms.
+
+ However, we must allow VOIDmode comparisons to match either
+ CCmode or non-CCmode comparison, because some ports have
+ modeless comparisons inside branch patterns.
+
+ ??? This mode check should perhaps look more like the mode check
+ in simplify_comparison in combine. */
if ((GET_CODE (SET_SRC (set)) == COMPARE
|| (((code == NE
@@ -7784,8 +8779,9 @@ get_condition (jump, earliest)
#endif
))
&& GET_RTX_CLASS (GET_CODE (SET_SRC (set))) == '<'))
- && ((GET_MODE_CLASS (mode) == MODE_CC)
- == (GET_MODE_CLASS (inner_mode) == MODE_CC)))
+ && (((GET_MODE_CLASS (mode) == MODE_CC)
+ == (GET_MODE_CLASS (inner_mode) == MODE_CC))
+ || mode == VOIDmode || inner_mode == VOIDmode))
x = SET_SRC (set);
else if (((code == EQ
|| (code == GE
@@ -7802,8 +8798,10 @@ get_condition (jump, earliest)
#endif
))
&& GET_RTX_CLASS (GET_CODE (SET_SRC (set))) == '<'
- && ((GET_MODE_CLASS (mode) == MODE_CC)
- == (GET_MODE_CLASS (inner_mode) == MODE_CC)))
+ && (((GET_MODE_CLASS (mode) == MODE_CC)
+ == (GET_MODE_CLASS (inner_mode) == MODE_CC))
+ || mode == VOIDmode || inner_mode == VOIDmode))
+
{
/* We might have reversed a LT to get a GE here. But this wasn't
actually the comparison of data, so we don't flag that we
@@ -7862,14 +8860,14 @@ get_condition (jump, earliest)
switch (code)
{
case LE:
- if (const_val != max_val >> 1)
+ if ((unsigned HOST_WIDE_INT) const_val != max_val >> 1)
code = LT, op1 = GEN_INT (const_val + 1);
break;
/* When cross-compiling, const_val might be sign-extended from
BITS_PER_WORD to HOST_BITS_PER_WIDE_INT */
case GE:
- if ((const_val & max_val)
+ if ((HOST_WIDE_INT) (const_val & max_val)
!= (((HOST_WIDE_INT) 1
<< (GET_MODE_BITSIZE (GET_MODE (op0)) - 1))))
code = GT, op1 = GEN_INT (const_val - 1);
@@ -7933,12 +8931,12 @@ get_condition_for_loop (x)
*/
static void
-insert_bct (loop_start, loop_end)
+insert_bct (loop_start, loop_end, loop_info)
rtx loop_start, loop_end;
+ struct loop_info *loop_info;
{
int i;
unsigned HOST_WIDE_INT n_iterations;
- rtx insn;
int increment_direction, compare_direction;
@@ -7951,7 +8949,7 @@ insert_bct (loop_start, loop_end)
int loop_num = uid_loop_num [INSN_UID (loop_start)];
/* It's impossible to instrument a competely unrolled loop. */
- if (loop_unroll_factor [loop_num] == -1)
+ if (loop_info->unroll_number == -1)
return;
/* Make sure that the count register is not in use. */
@@ -7999,25 +8997,20 @@ insert_bct (loop_start, loop_end)
/* Make sure that the loop does not jump via a table.
(the count register might be used to perform the branch on table). */
- for (insn = loop_start; insn && insn != loop_end; insn = NEXT_INSN (insn))
+ if (loop_has_tablejump)
{
- if (GET_CODE (insn) == JUMP_INSN
- && (GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC
- || GET_CODE (PATTERN (insn)) == ADDR_VEC))
- {
- if (loop_dump_stream)
- fprintf (loop_dump_stream,
- "insert_bct %d: BCT instrumentation failed: computed branch in the loop\n",
- loop_num);
- return;
- }
+ if (loop_dump_stream)
+ fprintf (loop_dump_stream,
+ "insert_bct %d: BCT instrumentation failed: computed branch in the loop\n",
+ loop_num);
+ return;
}
/* Account for loop unrolling in instrumented iteration count. */
- if (loop_unroll_factor [loop_num] > 1)
- n_iterations = loop_n_iterations / loop_unroll_factor [loop_num];
+ if (loop_info->unroll_number > 1)
+ n_iterations = loop_info->n_iterations / loop_info->unroll_number;
else
- n_iterations = loop_n_iterations;
+ n_iterations = loop_info->n_iterations;
if (n_iterations != 0 && n_iterations < 3)
{
@@ -8035,7 +9028,7 @@ insert_bct (loop_start, loop_end)
if (n_iterations > 0)
{
/* Mark all enclosing loops that they cannot use count register. */
- for (i=loop_num; i != -1; i = loop_outer_loop[i])
+ for (i = loop_num; i != -1; i = loop_outer_loop[i])
loop_used_count_register[i] = 1;
instrument_loop_bct (loop_start, loop_end, GEN_INT (n_iterations));
return;
@@ -8045,22 +9038,31 @@ insert_bct (loop_start, loop_end)
at compile time. In this case we generate run_time calculation
of the number of iterations. */
- if (GET_MODE_CLASS (GET_MODE (loop_iteration_var)) != MODE_INT
- || GET_MODE_SIZE (GET_MODE (loop_iteration_var)) != UNITS_PER_WORD)
+ if (loop_info->iteration_var == 0)
{
if (loop_dump_stream)
fprintf (loop_dump_stream,
- "insert_bct %d: BCT Instrumentation failed: loop variable not integer\n",
+ "insert_bct %d: BCT Runtime Instrumentation failed: no loop iteration variable found\n",
+ loop_num);
+ return;
+ }
+
+ if (GET_MODE_CLASS (GET_MODE (loop_info->iteration_var)) != MODE_INT
+ || GET_MODE_SIZE (GET_MODE (loop_info->iteration_var)) != UNITS_PER_WORD)
+ {
+ if (loop_dump_stream)
+ fprintf (loop_dump_stream,
+ "insert_bct %d: BCT Runtime Instrumentation failed: loop variable not integer\n",
loop_num);
return;
}
/* With runtime bounds, if the compare is of the form '!=' we give up */
- if (loop_comparison_code == NE)
+ if (loop_info->comparison_code == NE)
{
if (loop_dump_stream)
fprintf (loop_dump_stream,
- "insert_bct %d: runtime bounds with != comparison\n",
+ "insert_bct %d: BCT Runtime Instrumentation failed: runtime bounds with != comparison\n",
loop_num);
return;
}
@@ -8231,7 +9233,7 @@ indirect_jump_in_function_p (start)
static int
insert_loop_mem (mem, data)
rtx *mem;
- void *data;
+ void *data ATTRIBUTE_UNUSED;
{
int i;
rtx m = *mem;
@@ -8293,25 +9295,24 @@ insert_loop_mem (mem, data)
return 0;
}
-/* Like load_mems, but also ensures that N_TIMES_SET,
+/* Like load_mems, but also ensures that SET_IN_LOOP,
MAY_NOT_OPTIMIZE, REG_SINGLE_USAGE, and INSN_COUNT have the correct
values after load_mems. */
static void
load_mems_and_recount_loop_regs_set (scan_start, end, loop_top, start,
- reg_single_usage, insn_count)
+ insn_count)
rtx scan_start;
rtx end;
rtx loop_top;
rtx start;
- varray_type reg_single_usage;
int *insn_count;
{
int nregs = max_reg_num ();
load_mems (scan_start, end, loop_top, start);
- /* Recalculate n_times_set and friends since load_mems may have
+ /* Recalculate set_in_loop and friends since load_mems may have
created new registers. */
if (max_reg_num () > nregs)
{
@@ -8321,20 +9322,18 @@ load_mems_and_recount_loop_regs_set (scan_start, end, loop_top, start,
old_nregs = nregs;
nregs = max_reg_num ();
- if (nregs > n_times_set->num_elements)
+ if ((unsigned) nregs > set_in_loop->num_elements)
{
/* Grow all the arrays. */
+ VARRAY_GROW (set_in_loop, nregs);
VARRAY_GROW (n_times_set, nregs);
- VARRAY_GROW (n_times_used, nregs);
VARRAY_GROW (may_not_optimize, nregs);
- if (reg_single_usage)
- VARRAY_GROW (reg_single_usage, nregs);
+ VARRAY_GROW (reg_single_usage, nregs);
}
/* Clear the arrays */
- bzero ((char *) &n_times_set->data, nregs * sizeof (int));
+ bzero ((char *) &set_in_loop->data, nregs * sizeof (int));
bzero ((char *) &may_not_optimize->data, nregs * sizeof (char));
- if (reg_single_usage)
- bzero ((char *) &reg_single_usage->data, nregs * sizeof (rtx));
+ bzero ((char *) &reg_single_usage->data, nregs * sizeof (rtx));
count_loop_regs_set (loop_top ? loop_top : start, end,
may_not_optimize, reg_single_usage,
@@ -8343,7 +9342,7 @@ load_mems_and_recount_loop_regs_set (scan_start, end, loop_top, start,
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
{
VARRAY_CHAR (may_not_optimize, i) = 1;
- VARRAY_INT (n_times_set, i) = 1;
+ VARRAY_INT (set_in_loop, i) = 1;
}
#ifdef AVOID_CCMODE_COPIES
@@ -8354,9 +9353,9 @@ load_mems_and_recount_loop_regs_set (scan_start, end, loop_top, start,
VARRAY_CHAR (may_not_optimize, i) = 1;
#endif
- /* Set n_times_used for the new registers. */
- bcopy ((char *) (&n_times_set->data.i[0] + old_nregs),
- (char *) (&n_times_used->data.i[0] + old_nregs),
+ /* Set n_times_set for the new registers. */
+ bcopy ((char *) (&set_in_loop->data.i[0] + old_nregs),
+ (char *) (&n_times_set->data.i[0] + old_nregs),
(nregs - old_nregs) * sizeof (int));
}
}
@@ -8418,10 +9417,10 @@ load_mems (scan_start, end, loop_top, start)
/* Actually move the MEMs. */
for (i = 0; i < loop_mems_idx; ++i)
{
- int j;
int written = 0;
rtx reg;
rtx mem = loop_mems[i].mem;
+ rtx mem_list_entry;
if (MEM_VOLATILE_P (mem)
|| invariant_p (XEXP (mem, 0)) != 1)
@@ -8430,17 +9429,19 @@ load_mems (scan_start, end, loop_top, start)
/* Go through the MEMs written to in the loop to see if this
one is aliased by one of them. */
- for (j = 0; j < loop_store_mems_idx; ++j)
+ mem_list_entry = loop_store_mems;
+ while (mem_list_entry)
{
- if (rtx_equal_p (mem, loop_store_mems[j]))
+ if (rtx_equal_p (mem, XEXP (mem_list_entry, 0)))
written = 1;
- else if (true_dependence (loop_store_mems[j], VOIDmode,
+ else if (true_dependence (XEXP (mem_list_entry, 0), VOIDmode,
mem, rtx_varies_p))
{
/* MEM is indeed aliased by this store. */
loop_mems[i].optimize = 0;
break;
}
+ mem_list_entry = XEXP (mem_list_entry, 1);
}
/* If this MEM is written to, we must be sure that there
@@ -8506,7 +9507,7 @@ load_mems (scan_start, end, loop_top, start)
/* Load the memory immediately before START, which is
the NOTE_LOOP_BEG. */
- set = gen_rtx_SET (GET_MODE (reg), reg, mem);
+ set = gen_move_insn (reg, mem);
emit_insn_before (set, start);
if (written)
@@ -8523,7 +9524,7 @@ load_mems (scan_start, end, loop_top, start)
/* Store the memory immediately after END, which is
the NOTE_LOOP_END. */
- set = gen_rtx_SET (GET_MODE (reg), copy_rtx (mem), reg);
+ set = gen_move_insn (copy_rtx (mem), reg);
emit_insn_after (set, label);
}
diff --git a/gcc/loop.h b/gcc/loop.h
index d0ae25f4d45..e164428d861 100644
--- a/gcc/loop.h
+++ b/gcc/loop.h
@@ -1,5 +1,5 @@
/* Loop optimization definitions for GNU C-Compiler
- Copyright (C) 1991, 1995, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1991, 1995, 1998, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -18,6 +18,8 @@ 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 "varray.h"
+
/* Get the luid of an insn. Catch the error of trying to reference the LUID
of an insn added during loop, since these don't have LUIDs. */
@@ -54,6 +56,8 @@ struct induction
For a DEST_ADDR type giv, this is 0. */
rtx *location; /* Place in the insn where this giv occurs.
If GIV_TYPE is DEST_REG, this is 0. */
+ /* For a biv, this is the place where add_val
+ was found. */
enum machine_mode mode; /* The mode of this biv or giv */
enum machine_mode mem_mode; /* For DEST_ADDR, mode of the memory object. */
rtx mult_val; /* Multiplicative factor for src_reg. */
@@ -63,6 +67,9 @@ struct induction
final value could be calculated, it is put
here, and the giv is made replaceable. Set
the giv to this value before the loop. */
+ unsigned combined_with; /* The number of givs this giv has been
+ combined with. If nonzero, this giv
+ cannot combine with any other giv. */
unsigned replaceable : 1; /* 1 if we can substitute the strength-reduced
variable for the original variable.
0 means they must be kept separate and the
@@ -85,8 +92,6 @@ struct induction
another giv. This occurs in many cases
where a giv's lifetime spans an update to
a biv. */
- unsigned combined_with : 1; /* 1 if this giv has been combined with. It
- then cannot combine with any other giv. */
unsigned maybe_dead : 1; /* 1 if this giv might be dead. In that case,
we won't use it to eliminate a biv, it
would probably lose. */
@@ -97,7 +102,6 @@ struct induction
unsigned shared : 1;
unsigned no_const_addval : 1; /* 1 if add_val does not contain a const. */
int lifetime; /* Length of life of this giv */
- int times_used; /* # times this giv is used. */
rtx derive_adjustment; /* If nonzero, is an adjustment to be
subtracted from add_val when this giv
derives another. This occurs when the
@@ -109,14 +113,20 @@ struct induction
struct induction *same; /* If this giv has been combined with another
giv, this points to the base giv. The base
giv will have COMBINED_WITH non-zero. */
+ struct induction *derived_from;/* For a giv, if we decided to derive this
+ giv from another one. */
HOST_WIDE_INT const_adjust; /* Used by loop unrolling, when an address giv
is split, and a constant is eliminated from
the address, the -constant is stored here
for later use. */
+ int ix; /* Used by recombine_givs, as n index into
+ the stats array. */
struct induction *same_insn; /* If there are multiple identical givs in
the same insn, then all but one have this
field set, and they all point to the giv
that doesn't have this field set. */
+ rtx last_use; /* For a giv made from a biv increment, this is
+ a substitute for the lifetime information. */
};
/* A `struct iv_class' is created for each biv. */
@@ -143,6 +153,45 @@ struct iv_class {
biv controls. */
};
+/* Information required to calculate the number of loop iterations.
+ This is set by loop_iterations. */
+
+struct loop_info
+{
+ /* Register or constant initial loop value. */
+ rtx initial_value;
+ /* Register or constant value used for comparison test. */
+ rtx comparison_value;
+ /* Register or constant approximate final value. */
+ rtx final_value;
+ /* Register or constant initial loop value with term common to
+ final_value removed. */
+ rtx initial_equiv_value;
+ /* Register or constant final loop value with term common to
+ initial_value removed. */
+ rtx final_equiv_value;
+ /* Register corresponding to iteration variable. */
+ rtx iteration_var;
+ /* Constant loop increment. */
+ rtx increment;
+ enum rtx_code comparison_code;
+ /* Holds the number of loop iterations. It is zero if the number
+ could not be calculated. Must be unsigned since the number of
+ iterations can be as high as 2^wordsize - 1. For loops with a
+ wider iterator, this number will be zero if the number of loop
+ iterations is too large for an unsigned integer to hold. */
+ unsigned HOST_WIDE_INT n_iterations;
+ /* The loop unrolling factor.
+ Potential values:
+ 0: unrolled
+ 1: not unrolled.
+ -1: completely unrolled
+ >0: holds the unroll exact factor. */
+ unsigned int unroll_number;
+ /* Non-zero if the loop has a NOTE_INSN_LOOP_VTOP. */
+ rtx vtop;
+};
+
/* Definitions used by the basic induction variable discovery code. */
enum iv_mode { UNKNOWN_INDUCT, BASIC_INDUCT, NOT_BASIC_INDUCT,
GENERAL_INDUCT };
@@ -155,41 +204,46 @@ extern int *uid_loop_num;
extern int *loop_outer_loop;
extern rtx *loop_number_exit_labels;
extern int *loop_number_exit_count;
-extern unsigned HOST_WIDE_INT loop_n_iterations;
extern int max_reg_before_loop;
extern FILE *loop_dump_stream;
-extern enum iv_mode *reg_iv_type;
-extern struct induction **reg_iv_info;
+extern varray_type reg_iv_type;
+extern varray_type reg_iv_info;
+
+#define REG_IV_TYPE(n) \
+ (*(enum iv_mode *) &VARRAY_INT(reg_iv_type, (n)))
+#define REG_IV_INFO(n) \
+ (*(struct induction **) &VARRAY_GENERIC_PTR(reg_iv_info, (n)))
+
extern struct iv_class **reg_biv_class;
extern struct iv_class *loop_iv_list;
+extern int first_increment_giv, last_increment_giv;
+
/* Forward declarations for non-static functions declared in loop.c and
unroll.c. */
int invariant_p PROTO((rtx));
rtx get_condition_for_loop PROTO((rtx));
void emit_iv_add_mult PROTO((rtx, rtx, rtx, rtx, rtx));
+rtx express_from PROTO((struct induction *, struct induction *));
-/* Forward declarations for non-static functions declared in stmt.c. */
-void find_loop_tree_blocks PROTO((void));
-void unroll_block_trees PROTO((void));
-
-void unroll_loop PROTO((rtx, int, rtx, rtx, int));
+void unroll_loop PROTO((rtx, int, rtx, rtx, struct loop_info *, int));
rtx biv_total_increment PROTO((struct iv_class *, rtx, rtx));
-unsigned HOST_WIDE_INT loop_iterations PROTO((rtx, rtx));
-rtx final_biv_value PROTO((struct iv_class *, rtx, rtx));
-rtx final_giv_value PROTO((struct induction *, rtx, rtx));
+unsigned HOST_WIDE_INT loop_iterations PROTO((rtx, rtx, struct loop_info *));
+int precondition_loop_p PROTO((rtx, struct loop_info *,
+ rtx *, rtx *, rtx *,
+ enum machine_mode *mode));
+rtx final_biv_value PROTO((struct iv_class *, rtx, rtx,
+ unsigned HOST_WIDE_INT));
+rtx final_giv_value PROTO((struct induction *, rtx, rtx,
+ unsigned HOST_WIDE_INT));
void emit_unrolled_add PROTO((rtx, rtx, rtx));
int back_branch_in_range_p PROTO((rtx, rtx, rtx));
+int loop_insn_first_p PROTO((rtx, rtx));
-extern int *loop_unroll_factor;
-
-#ifdef HAVE_decrement_and_branch_on_count
-extern rtx loop_iteration_var;
-extern rtx loop_initial_value;
-extern rtx loop_increment;
-extern rtx loop_final_value;
-extern enum rtx_code loop_comparison_code;
-#endif /* HAVE_decrement_and_branch_on_count */
+extern int *loop_unroll_number;
+/* Forward declarations for non-static functions declared in stmt.c. */
+void find_loop_tree_blocks PROTO((void));
+void unroll_block_trees PROTO((void));
diff --git a/gcc/machmode.h b/gcc/machmode.h
index 119950c4348..595d8bd6187 100644
--- a/gcc/machmode.h
+++ b/gcc/machmode.h
@@ -1,5 +1,5 @@
/* Machine mode definitions for GNU C-Compiler; included by rtl.h and tree.h.
- Copyright (C) 1991, 1993, 1994, 1996 Free Software Foundation, Inc.
+ Copyright (C) 1991, 1993, 1994, 1996, 1998 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -21,20 +21,8 @@ Boston, MA 02111-1307, USA. */
#ifndef HAVE_MACHINE_MODES
#define HAVE_MACHINE_MODES
-#include "gansidecl.h"
-
/* Strictly speaking, this isn't the proper place to include these definitions,
- but this file is included by every GCC file.
-
- Some systems define these in, e.g., param.h. We undefine these names
- here to avoid the warnings. We prefer to use our definitions since we
- know they are correct. */
-
-#undef MIN
-#undef MAX
-
-#define MIN(X,Y) ((X) < (Y) ? (X) : (Y))
-#define MAX(X,Y) ((X) > (Y) ? (X) : (Y))
+ but this file is included by every GCC file. */
/* Find the largest host integer type and set its size and type. */
@@ -196,7 +184,7 @@ extern int mode_unit_size[];
/* Get a bitmask containing 1 for all bits in a word
that fit within mode MODE. */
-extern const unsigned HOST_WIDE_INT mode_mask_array[];
+extern unsigned HOST_WIDE_INT mode_mask_array[];
#define GET_MODE_MASK(MODE) mode_mask_array[(int) (MODE)]
@@ -211,6 +199,17 @@ extern unsigned char mode_wider_mode[];
extern enum machine_mode mode_for_size PROTO((unsigned int, enum mode_class, int));
+/* Similar, but find the smallest mode for a given width. */
+
+extern enum machine_mode smallest_mode_for_size PROTO((unsigned int,
+ enum mode_class));
+
+
+/* Return an integer mode of the exact same size as the input mode,
+ or BLKmode on failure. */
+
+extern enum machine_mode int_mode_for_mode PROTO((enum machine_mode));
+
/* Find the best mode to use to access a bit field. */
extern enum machine_mode get_best_mode PROTO((int, int, int, enum machine_mode, int));
diff --git a/gcc/mbchar.c b/gcc/mbchar.c
index d54a49749ce..a22e52b56b3 100644
--- a/gcc/mbchar.c
+++ b/gcc/mbchar.c
@@ -34,7 +34,6 @@ Boston, MA 02111-1307, USA. */
#ifdef MULTIBYTE_CHARS
#include "config.h"
#include "system.h"
-#include "gansidecl.h"
#include "mbchar.h"
#include <locale.h>
@@ -282,7 +281,10 @@ local_mb_cur_max ()
#ifdef CROSS_COMPILE
return 1;
#else
- return MB_CUR_MAX;
+ if (MB_CUR_MAX > 0)
+ return MB_CUR_MAX;
+
+ return 1; /* default */
#endif
}
#endif /* MULTIBYTE_CHARS */
diff --git a/gcc/mbchar.h b/gcc/mbchar.h
index a4b82c0558d..65f281a5482 100644
--- a/gcc/mbchar.h
+++ b/gcc/mbchar.h
@@ -1,6 +1,22 @@
/* mbchar.h - Various declarations for functions found in mbchar.c
Copyright (C) 1998 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. */
#ifndef __GCC_MBCHAR_H__
#define __GCC_MBCHAR_H__
diff --git a/gcc/md.texi b/gcc/md.texi
index e9892593ab3..907df37080e 100644
--- a/gcc/md.texi
+++ b/gcc/md.texi
@@ -1746,14 +1746,20 @@ pseudo registers that did not get hard registers, while on other
machines explicit memory references will get optional reloads.
If a scratch register is required to move an object to or from memory,
-it can be allocated using @code{gen_reg_rtx} prior to reload. But this
-is impossible during and after reload. If there are cases needing
+it can be allocated using @code{gen_reg_rtx} prior to life analysis.
+
+If there are cases needing
scratch registers after reload, you must define
@code{SECONDARY_INPUT_RELOAD_CLASS} and perhaps also
@code{SECONDARY_OUTPUT_RELOAD_CLASS} to detect them, and provide
patterns @samp{reload_in@var{m}} or @samp{reload_out@var{m}} to handle
them. @xref{Register Classes}.
+@findex no_new_pseudos
+The global variable @code{no_new_pseudos} can be used to determine if it
+is unsafe to create new pseudo registers. If this variable is nonzero, then
+it is unsafe to call @code{gen_reg_rtx} to allocate a new pseudo.
+
The constraints on a @samp{mov@var{m}} must permit moving any hard
register to any other hard register provided that
@code{HARD_REGNO_MODE_OK} permits mode @var{m} in both registers and
@@ -2175,7 +2181,7 @@ pattern or a @samp{tst@var{m}} pattern.
Machines that use a pseudo register for the condition code value, or
where the mode used for the comparison depends on the condition being
-tested, should also use the above mechanism. @xref{Jump Patterns}
+tested, should also use the above mechanism. @xref{Jump Patterns}.
The above discussion also applies to the @samp{mov@var{mode}cc} and
@samp{s@var{cond}} patterns.
@@ -2531,6 +2537,61 @@ This pattern, if defined, performs the entire action of the longjmp.
You will not normally need to define this pattern unless you also define
@code{builtin_setjmp_setup}. The single argument is a pointer to the
@code{jmp_buf}.
+
+@cindex @code{eh_epilogue} instruction pattern
+@item @samp{eh_epilogue}
+This pattern, if defined, affects the way @code{__builtin_eh_return},
+and thence @code{__throw} are built. It is intended to allow communication
+between the exception handling machinery and the normal epilogue code
+for the target.
+
+The pattern takes three arguments. The first is the exception context
+pointer. This will have already been copied to the function return
+register appropriate for a pointer; normally this can be ignored. The
+second argument is an offset to be added to the stack pointer. It will
+have been copied to some arbitrary call-clobbered hard reg so that it
+will survive until after reload to when the normal epilogue is generated.
+The final argument is the address of the exception handler to which
+the function should return. This will normally need to copied by the
+pattern to some special register.
+
+This pattern must be defined if @code{RETURN_ADDR_RTX} does not yield
+something that can be reliably and permanently modified, i.e. a fixed
+hard register or a stack memory reference.
+
+@cindex @code{prologue} instruction pattern
+@item @samp{prologue}
+This pattern, if defined, emits RTL for entry to a function. The function
+entry is resposible for setting up the stack frame, initializing the frame
+pointer register, saving callee saved registers, etc.
+
+Using a prologue pattern is generally preferred over defining
+@code{FUNCTION_PROLOGUE} to emit assembly code for the prologue.
+
+The @code{prologue} pattern is particularly useful for targets which perform
+instruction scheduling.
+
+@cindex @code{epilogue} instruction pattern
+@item @samp{epilogue}
+This pattern, if defined, emits RTL for exit from a function. The function
+exit is resposible for deallocating the stack frame, restoring callee saved
+registers and emitting the return instruction.
+
+Using an epilogue pattern is generally preferred over defining
+@code{FUNCTION_EPILOGUE} to emit assembly code for the prologue.
+
+The @code{epilogue} pattern is particularly useful for targets which perform
+instruction scheduling or which have delay slots for their return instruction.
+
+@cindex @code{sibcall_epilogue} instruction pattern
+@item @samp{sibcall_epilogue}
+This pattern, if defined, emits RTL for exit from a function without the final
+branch back to the calling function. This pattern will be emitted before any
+sibling call (aka tail call) sites.
+
+The @code{sibcall_epilogue} pattern must not clobber any arguments used for
+parameter passing or any stack slots for arguments passed to the current
+function.
@end table
@node Pattern Ordering
@@ -3528,9 +3589,10 @@ The integer @var{i} specifies the value of a numeric attribute. @var{i}
must be non-negative.
The value of a numeric attribute can be specified either with a
-@code{const_int} or as an integer represented as a string in
-@code{const_string}, @code{eq_attr} (see below), and @code{set_attr}
-(@pxref{Tagging Insns}) expressions.
+@code{const_int}, or as an integer represented as a string in
+@code{const_string}, @code{eq_attr} (see below), @code{attr},
+@code{symbol_ref}, simple arithmetic expressions, and @code{set_attr}
+overrides on specific instructions (@pxref{Tagging Insns}).
@cindex @code{const_string} and attributes
@item (const_string @var{value})
@@ -3713,6 +3775,12 @@ The @code{very_unlikely} and @code{unlikely} flags are false if the
@code{attr_flag} is only used during delay slot scheduling and has no
meaning to other passes of the compiler.
+
+@findex attr
+@item (attr @var{name})
+The value of another attribute is returned. This is most useful
+for numeric attributes, as @code{eq_attr} and @code{attr_flag}
+produce more efficient code for non-numeric attributes.
@end table
@node Tagging Insns
diff --git a/gcc/mips-tdump.c b/gcc/mips-tdump.c
index 558e090a64d..9d3143d1028 100644
--- a/gcc/mips-tdump.c
+++ b/gcc/mips-tdump.c
@@ -1,5 +1,5 @@
/* Read and manage MIPS symbol tables from object modules.
- Copyright (C) 1991, 1994, 1995, 1997 Free Software Foundation, Inc.
+ Copyright (C) 1991, 1994, 1995, 1997, 1998, 1999 Free Software Foundation, Inc.
Contributed by hartzell@boulder.colorado.edu,
Rewritten by meissner@osf.org.
@@ -47,24 +47,9 @@ Boston, MA 02111-1307, USA. */
#define MIPS_UNMARK_STAB(code) ((code)-CODE_MASK)
#endif
-#ifdef __STDC__
-typedef void *PTR_T;
-typedef const void *CPTR_T;
-#define __proto(x) x
-#else
-
-#if defined(_STDIO_H_) || defined(__STDIO_H__) /* Ultrix 4.0, SGI */
-typedef void *PTR_T;
-typedef void *CPTR_T;
-
-#else
-typedef char *PTR_T; /* Ultrix 3.1 */
-typedef char *CPTR_T;
-#endif
-
-#define __proto(x) ()
-#define const
-#endif
+#define __proto(x) PARAMS(x)
+typedef PTR PTR_T;
+typedef const PTR_T CPTR_T;
#define uchar unsigned char
#define ushort unsigned short
@@ -72,7 +57,28 @@ typedef char *CPTR_T;
#define ulong unsigned long
-/* Do to size_t being defined in sys/types.h and different
+static void
+fatal(s)
+ const char *s;
+{
+ fprintf(stderr, "%s\n", s);
+ exit(FATAL_EXIT_CODE);
+}
+
+/* Same as `malloc' but report error if no memory available. */
+/* Do this before size_t is fiddled with so it matches the prototype
+ in libiberty.h . */
+PTR
+xmalloc (size)
+ size_t size;
+{
+ register PTR value = (PTR) malloc (size);
+ if (value == 0)
+ fatal ("Virtual memory exhausted.");
+ return value;
+}
+
+/* Due to size_t being defined in sys/types.h and different
in stddef.h, we have to do this by hand..... Note, these
types are correct for MIPS based systems, and may not be
correct for other systems. */
@@ -263,17 +269,22 @@ void print_file_desc __proto((FDR *, int));
void print_symbol __proto((SYMR *, int, char *, AUXU *, int, FDR *));
void print_aux __proto((AUXU, int, int));
void emit_aggregate __proto((char *, AUXU, AUXU, const char *, FDR *));
-char *st_to_string __proto((st_t));
-char *sc_to_string __proto((sc_t));
-char *glevel_to_string __proto((glevel_t));
-char *lang_to_string __proto((lang_t));
-char *type_to_string __proto((AUXU *, int, FDR *));
+const char *st_to_string __proto((st_t));
+const char *sc_to_string __proto((sc_t));
+const char *glevel_to_string __proto((glevel_t));
+const char *lang_to_string __proto((lang_t));
+const char *type_to_string __proto((AUXU *, int, FDR *));
#ifndef __alpha
+# ifdef NEED_DECLARATION_MALLOC
extern PTR_T malloc __proto((size_t));
+# endif
+# ifdef NEED_DECLARATION_CALLOC
extern PTR_T calloc __proto((size_t, size_t));
+# endif
+# ifdef NEED_DECLARATION_REALLOC
extern PTR_T realloc __proto((PTR_T, size_t));
-extern void free __proto((PTR_T));
+# endif
#endif
extern char *optarg;
@@ -325,7 +336,7 @@ read_seek (ptr, size, offset, context)
/* Convert language code to string format. */
-char *
+const char *
lang_to_string (lang)
lang_t lang;
{
@@ -348,7 +359,7 @@ lang_to_string (lang)
/* Convert storage class to string. */
-char *
+const char *
sc_to_string(storage_class)
sc_t storage_class;
{
@@ -386,7 +397,7 @@ sc_to_string(storage_class)
/* Convert symbol type to string. */
-char *
+const char *
st_to_string(symbol_type)
st_t symbol_type;
{
@@ -427,7 +438,7 @@ st_to_string(symbol_type)
/* Convert debug level to string. */
-char *
+const char *
glevel_to_string (g_level)
glevel_t g_level;
{
@@ -445,7 +456,7 @@ glevel_to_string (g_level)
/* Convert the type information to string format. */
-char *
+const char *
type_to_string (aux_ptr, index, fdp)
AUXU *aux_ptr;
int index;
@@ -1014,7 +1025,7 @@ print_symbol (sym_ptr, number, strbase, aux_base, ifd, fdp)
scope_ptr != (scope_t *) 0;
scope_ptr = scope_ptr->prev)
{
- char *class;
+ const char *class;
if (scope_ptr->st == st_Proc || scope_ptr->st == st_StaticProc)
class = "func.";
else if (scope_ptr->st == st_File)
@@ -1046,7 +1057,7 @@ print_symbol (sym_ptr, number, strbase, aux_base, ifd, fdp)
if (MIPS_IS_STAB(sym_ptr))
{
register int i = sizeof(stab_names) / sizeof(stab_names[0]);
- char *stab_name = "stab";
+ const char *stab_name = "stab";
short code = MIPS_UNMARK_STAB(sym_ptr->index);
while (--i >= 0)
if (stab_names[i].code == code)
@@ -1147,8 +1158,10 @@ print_file_desc (fdp, number)
aux_base = aux_symbols + fdp->iauxBase;
used_base = aux_used + (aux_base - aux_symbols);
- printf ("\nFile #%d, \"%s\"\n\n", number, str_base + fdp->rss);
-
+ printf ("\nFile #%d, \"%s\"\n\n",
+ number,
+ fdp->rss != issNil ? str_base + fdp->rss : "<unknown>");
+
printf (" Name index = %-10ld Readin = %s\n",
(long) fdp->rss, (fdp->fReadin) ? "Yes" : "No");
@@ -1264,7 +1277,7 @@ print_file_desc (fdp, number)
(ulong) fdp->rfdBase);
rfd_ptr = rfile_desc + fdp->rfdBase;
- for (i = 0; i < fdp->crfd; i++)
+ for (i = 0; i < (ulong) fdp->crfd; i++)
{
printf ("\t#%-5ld %11ld, 0x%08lx\n", i, *rfd_ptr, *rfd_ptr);
rfd_ptr++;
@@ -1282,9 +1295,10 @@ print_file_desc (fdp, number)
PDR *proc_ptr = &proc_desc[pdi];
printf ("\n\tProcedure descriptor %d:\n", (pdi - fdp->ipdFirst));
- printf ("\t Name index = %-11ld Name = \"%s\"\n",
- (long) l_symbols[proc_ptr->isym + fdp->isymBase].iss,
- l_symbols[proc_ptr->isym + fdp->isymBase].iss + str_base);
+ if (l_symbols != 0)
+ printf ("\t Name index = %-11ld Name = \"%s\"\n",
+ (long) l_symbols[proc_ptr->isym + fdp->isymBase].iss,
+ l_symbols[proc_ptr->isym + fdp->isymBase].iss + str_base);
printf ("\t .mask 0x%08lx,%-9ld .fmask 0x%08lx,%ld\n",
(long) proc_ptr->regmask,
@@ -1590,23 +1604,3 @@ fancy_abort ()
fprintf (stderr, "mips-tdump internal error");
exit (1);
}
-
-void
-fatal(s)
-char *s;
-{
- fprintf(stderr, "%s\n", s);
- exit(1);
-}
-
-/* Same as `malloc' but report error if no memory available. */
-
-PTR_T
-xmalloc (size)
- unsigned size;
-{
- register PTR_T value = malloc (size);
- if (value == 0)
- fatal ("Virtual memory exhausted.");
- return value;
-}
diff --git a/gcc/mips-tfile.c b/gcc/mips-tfile.c
index 0922bf1ad14..588f4efedc3 100644
--- a/gcc/mips-tfile.c
+++ b/gcc/mips-tfile.c
@@ -2,7 +2,7 @@
contain debugging information specified by the GNU compiler
in the form of comments (the mips assembler does not support
assembly access to debug information).
- Copyright (C) 1991, 93, 94, 95, 97, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1991, 93-95, 97, 98, 1999 Free Software Foundation, Inc.
Contributed by Michael Meissner (meissner@cygnus.com).
This file is part of GNU CC.
@@ -610,36 +610,11 @@ Boston, MA 02111-1307, USA. */
#define __LINE__ 0
#endif
-#ifdef __STDC__
-typedef void *PTR_T;
-typedef const void *CPTR_T;
-#define __proto(x) x
-#ifndef VPROTO
-#define PVPROTO(ARGS) ARGS
-#define VPROTO(ARGS) ARGS
-#define VA_START(va_list,var) va_start(va_list,var)
-#endif
-#else
-
-#if defined(_STDIO_H_) || defined(__STDIO_H__) /* Ultrix 4.0, SGI */
-typedef void *PTR_T;
-typedef void *CPTR_T;
-
-#else
-typedef char *PTR_T; /* Ultrix 3.1 */
-typedef char *CPTR_T;
-#endif
+#define __proto(x) PARAMS(x)
+typedef PTR PTR_T;
+typedef const PTR_T CPTR_T;
-#define __proto(x) ()
-#define const
-#ifndef VPROTO
-#define PVPROTO(ARGS) ()
-#define VPROTO(ARGS) (va_alist) va_dcl
-#define VA_START(va_list,var) va_start(va_list)
-#endif
-#endif
-
-/* Do to size_t being defined in sys/types.h and different
+/* Due to size_t being defined in sys/types.h and different
in stddef.h, we have to do this by hand..... Note, these
types are correct for MIPS based systems, and may not be
correct for other systems. Ultrix 4.0 and Silicon Graphics
@@ -658,16 +633,13 @@ typedef char *CPTR_T;
so they can't be static. */
extern void pfatal_with_name
- __proto((char *));
+ __proto((const char *));
extern void fancy_abort __proto((void));
void botch __proto((const char *));
-extern PTR_T xmalloc __proto((Size_t));
-extern PTR_T xcalloc __proto((Size_t, Size_t));
-extern PTR_T xrealloc __proto((PTR_T, Size_t));
-extern void xfree __proto((PTR_T));
+extern void xfree __proto((PTR));
-extern void fatal PVPROTO((const char *format, ...));
-extern void error PVPROTO((const char *format, ...));
+extern void fatal PVPROTO((const char *format, ...)) ATTRIBUTE_PRINTF_1;
+extern void error PVPROTO((const char *format, ...)) ATTRIBUTE_PRINTF_1;
#ifndef MIPS_DEBUGGING_INFO
@@ -675,8 +647,8 @@ static int line_number;
static int cur_line_start;
static int debug;
static int had_errors;
-static char *progname;
-static char *input_name;
+static const char *progname;
+static const char *input_name;
int
main ()
@@ -694,7 +666,6 @@ main ()
#undef index
#include <signal.h>
-#include <sys/stat.h>
#ifndef CROSS_COMPILE
#include <a.out.h>
@@ -1186,7 +1157,7 @@ typedef union page {
/* Structure holding allocation information for small sized structures. */
typedef struct alloc_info {
- char *alloc_name; /* name of this allocation type (must be first) */
+ const char *alloc_name; /* name of this allocation type (must be first) */
page_t *cur_page; /* current page being allocated from */
small_free_t free_list; /* current free list if any */
int unallocated; /* number of elements unallocated on page */
@@ -1583,7 +1554,7 @@ static long max_file_offset = 0; /* maximum file offset */
static FILE *object_stream = (FILE *) 0; /* file desc. to output .o */
static FILE *obj_in_stream = (FILE *) 0; /* file desc. to input .o */
static char *progname = (char *) 0; /* program name for errors */
-static char *input_name = "stdin"; /* name of input file */
+static const char *input_name = "stdin"; /* name of input file */
static char *object_name = (char *) 0; /* tmp. name of object file */
static char *obj_in_name = (char *) 0; /* name of input object file */
static char *cur_line_start = (char *) 0; /* current line read in */
@@ -1675,8 +1646,8 @@ STATIC void update_headers __proto((void));
STATIC void write_varray __proto((varray_t *, off_t, const char *));
STATIC void write_object __proto((void));
-STATIC char *st_to_string __proto((st_t));
-STATIC char *sc_to_string __proto((sc_t));
+STATIC const char *st_to_string __proto((st_t));
+STATIC const char *sc_to_string __proto((sc_t));
STATIC char *read_line __proto((void));
STATIC void parse_input __proto((void));
STATIC void mark_stabs __proto((const char *));
@@ -1817,7 +1788,7 @@ hash_string (text, hash_len, hash_tbl, ret_hash_index)
*ret_hash_index = hi;
for (ptr = hash_tbl[hi]; ptr != (shash_t *) 0; ptr = ptr->next)
- if (hash_len == ptr->len
+ if ((symint_t) hash_len == ptr->len
&& first_ch == ptr->string[0]
&& memcmp ((CPTR_T) text, (CPTR_T) ptr->string, hash_len) == 0)
break;
@@ -1842,7 +1813,7 @@ add_string (vp, hash_tbl, start, end_p1, ret_hash)
register shash_t *hash_ptr;
symint_t hi;
- if (len >= PAGE_USIZE)
+ if (len >= (Ptrdiff_t) PAGE_USIZE)
fatal ("String too big (%ld bytes)", (long) len);
hash_ptr = hash_string (start, len, hash_tbl, &hi);
@@ -1850,7 +1821,7 @@ add_string (vp, hash_tbl, start, end_p1, ret_hash)
{
register char *p;
- if (vp->objects_last_page + len >= PAGE_USIZE)
+ if (vp->objects_last_page + len >= (long) PAGE_USIZE)
{
vp->num_allocated
= ((vp->num_allocated + PAGE_USIZE - 1) / PAGE_USIZE) * PAGE_USIZE;
@@ -2037,8 +2008,8 @@ add_local_symbol (str_start, str_end_p1, type, storage, value, indx)
&& (debug > 2 || type == st_Block || type == st_End
|| type == st_Proc || type == st_StaticProc))
{
- char *sc_str = sc_to_string (storage);
- char *st_str = st_to_string (type);
+ const char *sc_str = sc_to_string (storage);
+ const char *st_str = st_to_string (type);
int depth = cur_file_ptr->nested_scopes + (scope_delta < 0);
fprintf (stderr,
@@ -2077,8 +2048,8 @@ add_ext_symbol (str_start, str_end_p1, type, storage, value, indx, ifd)
if (debug > 1)
{
- char *sc_str = sc_to_string (storage);
- char *st_str = st_to_string (type);
+ const char *sc_str = sc_to_string (storage);
+ const char *st_str = st_to_string (type);
fprintf (stderr,
"\tesym\tv= %10ld, ifd= %2d, sc= %-12s",
@@ -2386,7 +2357,7 @@ add_unknown_tag (ptag)
if (debug > 1)
{
- char *agg_type = "{unknown aggregate type}";
+ const char *agg_type = "{unknown aggregate type}";
switch (ptag->basic_type)
{
case bt_Struct: agg_type = "struct"; break;
@@ -2480,7 +2451,8 @@ add_procedure (func_start, func_end_p1)
}
if (cur_oproc_ptr == (PDR *) 0)
- error ("Did not find a PDR block for %.*s", func_end_p1 - func_start, func_start);
+ error ("Did not find a PDR block for %.*s",
+ (int) (func_end_p1 - func_start), func_start);
/* Determine the start of symbols. */
new_proc_ptr->isym = file_ptr->symbols.num_allocated;
@@ -2547,7 +2519,7 @@ add_file (file_start, file_end_p1)
&zero_bytes[0],
(shash_t **) 0);
- if (file_end_p1 - file_start > PAGE_USIZE-2)
+ if (file_end_p1 - file_start > (long) PAGE_USIZE-2)
fatal ("Filename goes over one page boundary.");
/* Push the start of the filename. We assume that the filename
@@ -2616,7 +2588,7 @@ add_bytes (vp, input_ptr, nitems)
/* Convert storage class to string. */
-STATIC char *
+STATIC const char *
sc_to_string(storage_class)
sc_t storage_class;
{
@@ -2654,7 +2626,7 @@ sc_to_string(storage_class)
/* Convert symbol type to string. */
-STATIC char *
+STATIC const char *
st_to_string(symbol_type)
st_t symbol_type;
{
@@ -2797,13 +2769,15 @@ parse_begin (start)
if (hash_ptr == (shash_t *) 0)
{
- error ("Label %.*s not found for #.begin", end_p1 - start, start);
+ error ("Label %.*s not found for #.begin",
+ (int) (end_p1 - start), start);
return;
}
if (cur_oproc_begin == (SYMR *) 0)
{
- error ("Procedure table %.*s not found for #.begin", end_p1 - start, start);
+ error ("Procedure table %.*s not found for #.begin",
+ (int) (end_p1 - start), start);
return;
}
@@ -2847,13 +2821,14 @@ parse_bend (start)
if (hash_ptr == (shash_t *) 0)
{
- error ("Label %.*s not found for #.bend", end_p1 - start, start);
+ error ("Label %.*s not found for #.bend", (int) (end_p1 - start), start);
return;
}
if (cur_oproc_begin == (SYMR *) 0)
{
- error ("Procedure table %.*s not found for #.bend", end_p1 - start, start);
+ error ("Procedure table %.*s not found for #.bend",
+ (int) (end_p1 - start), start);
return;
}
@@ -3309,7 +3284,7 @@ parse_def (name_start)
if (tag_start == (char *) 0)
{
error ("No tag specified for %.*s",
- name_end_p1 - name_start,
+ (int) (name_end_p1 - name_start),
name_start);
return;
}
@@ -3472,7 +3447,7 @@ parse_end (start)
}
/* Get the function name, skipping whitespace. */
- for (start_func = start; ISSPACE (*start_func); start_func++)
+ for (start_func = start; ISSPACE ((unsigned char)*start_func); start_func++)
;
ch = *start_func;
@@ -3499,7 +3474,8 @@ parse_end (start)
value = cur_oproc_end->value;
else
- error ("Cannot find .end block for %.*s", end_func_p1 - start_func, start_func);
+ error ("Cannot find .end block for %.*s",
+ (int) (end_func_p1 - start_func), start_func);
(void) add_local_symbol (start_func, end_func_p1,
st_End, sc_Text,
@@ -3531,7 +3507,7 @@ parse_ent (start)
return;
}
- for (start_func = start; ISSPACE (*start_func); start_func++)
+ for (start_func = start; ISSPACE ((unsigned char)*start_func); start_func++)
;
ch = *start_func;
@@ -3580,7 +3556,7 @@ parse_file (start)
static void
mark_stabs (start)
- const char *start; /* Start of directive (ignored) */
+ const char *start ATTRIBUTE_UNUSED; /* Start of directive (ignored) */
{
if (!stabs_seen)
{
@@ -3678,7 +3654,7 @@ parse_stabs_common (string_start, string_end, rest)
dummy_symr.index = code;
if (dummy_symr.index != code)
{
- error ("Line number (%d) for .stabs/.stabn directive cannot fit in index field (20 bits)",
+ error ("Line number (%lu) for .stabs/.stabn directive cannot fit in index field (20 bits)",
code);
return;
@@ -3853,7 +3829,7 @@ STATIC void
parse_input __proto((void))
{
register char *p;
- register int i;
+ register Size_t i;
register thead_t *ptag_head;
register tag_t *ptag;
register tag_t *ptag_next;
@@ -3871,16 +3847,16 @@ parse_input __proto((void))
while ((p = read_line ()) != (char *) 0)
{
/* Skip leading blanks */
- while (ISSPACE (*p))
+ while (ISSPACE ((unsigned char)*p))
p++;
/* See if it's a directive we handle. If so, dispatch handler. */
for (i = 0; i < sizeof (pseudo_ops) / sizeof (pseudo_ops[0]); i++)
if (memcmp (p, pseudo_ops[i].name, pseudo_ops[i].len) == 0
- && ISSPACE (p[pseudo_ops[i].len]))
+ && ISSPACE ((unsigned char)(p[pseudo_ops[i].len])))
{
p += pseudo_ops[i].len; /* skip to first argument */
- while (ISSPACE (*p))
+ while (ISSPACE ((unsigned char)*p))
p++;
(*pseudo_ops[i].func)( p );
@@ -4170,7 +4146,7 @@ write_object __proto((void))
else if (sys_write != sizeof (symbolic_header))
fatal ("Wrote %d bytes to %s, system returned %d",
- sizeof (symbolic_header),
+ (int) sizeof (symbolic_header),
object_name,
sys_write);
@@ -4203,8 +4179,8 @@ write_object __proto((void))
pfatal_with_name (object_name);
else if (sys_write != symbolic_header.cbLine)
- fatal ("Wrote %d bytes to %s, system returned %d",
- symbolic_header.cbLine,
+ fatal ("Wrote %ld bytes to %s, system returned %ld",
+ (long) symbolic_header.cbLine,
object_name,
sys_write);
@@ -4238,7 +4214,7 @@ write_object __proto((void))
pfatal_with_name (object_name);
else if (sys_write != num_write)
- fatal ("Wrote %d bytes to %s, system returned %d",
+ fatal ("Wrote %ld bytes to %s, system returned %ld",
num_write,
object_name,
sys_write);
@@ -4331,7 +4307,7 @@ write_object __proto((void))
else if (sys_write != sizeof (FDR))
fatal ("Wrote %d bytes to %s, system returned %d",
- sizeof (FDR),
+ (int) sizeof (FDR),
object_name,
sys_write);
@@ -4365,8 +4341,8 @@ write_object __proto((void))
if (sys_write <= 0)
pfatal_with_name (object_name);
- else if (sys_write != num_write)
- fatal ("Wrote %d bytes to %s, system returned %d",
+ else if (sys_write != (long)num_write)
+ fatal ("Wrote %lu bytes to %s, system returned %ld",
num_write,
object_name,
sys_write);
@@ -4421,9 +4397,9 @@ read_seek (size, offset, str)
if (sys_read <= 0)
pfatal_with_name (obj_in_name);
- if (sys_read != difference)
- fatal ("Wanted to read %d bytes from %s, system returned %d",
- size,
+ if ((symint_t)sys_read != difference)
+ fatal ("Wanted to read %lu bytes from %s, system returned %ld",
+ (unsigned long) size,
obj_in_name,
sys_read);
}
@@ -4435,9 +4411,9 @@ read_seek (size, offset, str)
if (sys_read <= 0)
pfatal_with_name (obj_in_name);
- if (sys_read != size)
- fatal ("Wanted to read %d bytes from %s, system returned %d",
- size,
+ if (sys_read != (long) size)
+ fatal ("Wanted to read %lu bytes from %s, system returned %ld",
+ (unsigned long) size,
obj_in_name,
sys_read);
@@ -4485,16 +4461,16 @@ copy_object __proto((void))
else if (sys_read == 0 && feof (obj_in_stream))
return; /* create a .T file sans file header */
- else if (sys_read < sizeof (struct filehdr))
+ else if (sys_read < (int) sizeof (struct filehdr))
fatal ("Wanted to read %d bytes from %s, system returned %d",
- sizeof (struct filehdr),
+ (int) sizeof (struct filehdr),
obj_in_name,
sys_read);
if (orig_file_header.f_nsyms != sizeof (HDRR))
fatal ("%s symbolic header wrong size (%d bytes, should be %d)",
- input_name, orig_file_header.f_nsyms, sizeof (HDRR));
+ input_name, orig_file_header.f_nsyms, (int) sizeof (HDRR));
/* Read in the current symbolic header. */
@@ -4509,9 +4485,9 @@ copy_object __proto((void))
if (sys_read < 0)
pfatal_with_name (object_name);
- else if (sys_read < sizeof (struct filehdr))
+ else if (sys_read < (int) sizeof (struct filehdr))
fatal ("Wanted to read %d bytes from %s, system returned %d",
- sizeof (struct filehdr),
+ (int) sizeof (struct filehdr),
obj_in_name,
sys_read);
@@ -4650,7 +4626,7 @@ copy_object __proto((void))
(sc_t) eptr->asym.sc,
eptr->asym.value,
(symint_t) ((eptr->asym.index == indexNil) ? indexNil : 0),
- (ifd < orig_sym_hdr.ifdMax) ? remap_file_number[ ifd ] : ifd);
+ ((long) ifd < orig_sym_hdr.ifdMax) ? remap_file_number[ ifd ] : ifd);
}
@@ -4802,7 +4778,8 @@ copy_object __proto((void))
remaining > 0;
remaining -= num_write)
{
- num_write = (remaining <= sizeof (buffer)) ? remaining : sizeof (buffer);
+ num_write =
+ (remaining <= (int) sizeof (buffer)) ? remaining : sizeof (buffer);
sys_read = fread ((PTR_T) buffer, 1, num_write, obj_in_stream);
if (sys_read <= 0)
pfatal_with_name (obj_in_name);
@@ -4848,13 +4825,13 @@ main (argc, argv)
#if !defined(__SABER__) && !defined(lint)
if (sizeof (efdr_t) > PAGE_USIZE)
fatal ("Efdr_t has a sizeof %d bytes, when it should be less than %d",
- sizeof (efdr_t),
- PAGE_USIZE);
+ (int) sizeof (efdr_t),
+ (int) PAGE_USIZE);
if (sizeof (page_t) != PAGE_USIZE)
fatal ("Page_t has a sizeof %d bytes, when it should be %d",
- sizeof (page_t),
- PAGE_USIZE);
+ (int) sizeof (page_t),
+ (int) PAGE_USIZE);
#endif
@@ -5083,7 +5060,7 @@ catch_signal (signum)
void
pfatal_with_name (msg)
- char *msg;
+ const char *msg;
{
int save_errno = errno; /* just in case.... */
if (line_number > 0)
@@ -5607,15 +5584,15 @@ free_thead (ptr)
void
fatal VPROTO((const char *format, ...))
{
-#ifndef __STDC__
- char *format;
+#ifndef ANSI_PROTOTYPES
+ const char *format;
#endif
va_list ap;
VA_START (ap, format);
-#ifndef __STDC__
- format = va_arg (ap, char *);
+#ifndef ANSI_PROTOTYPES
+ format = va_arg (ap, const char *);
#endif
if (line_number > 0)
@@ -5637,14 +5614,14 @@ fatal VPROTO((const char *format, ...))
void
error VPROTO((const char *format, ...))
{
-#ifndef __STDC__
+#ifndef ANSI_PROTOTYPES
char *format;
#endif
va_list ap;
VA_START (ap, format);
-#ifndef __STDC__
+#ifndef ANSI_PROTOTYPES
format = va_arg (ap, char *);
#endif
@@ -5686,11 +5663,11 @@ botch (s)
/* Same as `malloc' but report error if no memory available. */
-PTR_T
+PTR
xmalloc (size)
- Size_t size;
+ size_t size;
{
- register PTR_T value = malloc (size);
+ register PTR value = (PTR) malloc (size);
if (value == 0)
fatal ("Virtual memory exhausted.");
@@ -5706,11 +5683,11 @@ xmalloc (size)
/* Same as `calloc' but report error if no memory available. */
-PTR_T
+PTR
xcalloc (size1, size2)
- Size_t size1, size2;
+ size_t size1, size2;
{
- register PTR_T value = calloc (size1, size2);
+ register PTR value = (PTR) calloc (size1, size2);
if (value == 0)
fatal ("Virtual memory exhausted.");
@@ -5728,12 +5705,16 @@ xcalloc (size1, size2)
/* Same as `realloc' but report error if no memory available. */
-PTR_T
+PTR
xrealloc (ptr, size)
- PTR_T ptr;
- Size_t size;
+ PTR ptr;
+ size_t size;
{
- register PTR_T result = realloc (ptr, size);
+ register PTR result;
+ if (ptr)
+ result = (PTR) realloc (ptr, size);
+ else
+ result = (PTR) malloc (size);
if (!result)
fatal ("Virtual memory exhausted.");
@@ -5751,7 +5732,7 @@ xrealloc (ptr, size)
void
xfree (ptr)
- PTR_T ptr;
+ PTR ptr;
{
if (debug > 3)
{
diff --git a/gcc/mkinstalldirs b/gcc/mkinstalldirs
index f427ab4a24b..283836fd861 100644
--- a/gcc/mkinstalldirs
+++ b/gcc/mkinstalldirs
@@ -4,7 +4,7 @@
# Created: 1993-05-16
# Public domain
-# $Id: mkinstalldirs,v 1.1 1998/05/19 07:09:56 drepper Exp $
+# $Id: mkinstalldirs,v 1.1.1.1 1998/12/17 06:43:04 law Exp $
errstatus=0
diff --git a/gcc/objc/Make-lang.in b/gcc/objc/Make-lang.in
index bc47fc2e143..ca6e4607eba 100644
--- a/gcc/objc/Make-lang.in
+++ b/gcc/objc/Make-lang.in
@@ -59,9 +59,8 @@ OBJECTIVE-C objective-c: cc1obj$(exeext)
# Language-specific object files for Objective C.
OBJC_OBJS = objc-parse.o objc-act.o $(C_AND_OBJC_OBJS)
-cc1obj$(exeext): $(P) $(OBJC_OBJS) $(OBJS) $(LIBDEPS)
- $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ $(OBJC_OBJS) $(OBJS) \
- $(LIBS)
+cc1obj$(exeext): $(P) $(OBJS) $(OBJC_OBJS) $(LIBDEPS)
+ $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ $(OBJS) $(OBJC_OBJS) $(LIBS)
# Objective C language specific files.
@@ -72,6 +71,7 @@ objc-parse.o : $(srcdir)/objc/objc-parse.c \
$(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) -I$(srcdir)/objc \
-c $(srcdir)/objc/objc-parse.c
+$(INTL_TARGETS): $(srcdir)/objc/objc-parse.c
$(srcdir)/objc/objc-parse.c : $(srcdir)/objc/objc-parse.y
cd $(srcdir)/objc; \
$(BISON) $(BISONFLAGS) objc-parse.y -o objc-parse.c
diff --git a/gcc/objc/Makefile.in b/gcc/objc/Makefile.in
index 0bc92122e5d..71c564c6c59 100644
--- a/gcc/objc/Makefile.in
+++ b/gcc/objc/Makefile.in
@@ -1,5 +1,5 @@
# GNU Objective C frontend Makefile
-# Copyright (C) 1993, 1995, 1996, 1997 Free Software Foundation, Inc.
+# Copyright (C) 1993, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
#
# This file is part of GNU CC.
#
diff --git a/gcc/objc/objc-act.c b/gcc/objc/objc-act.c
index 0dc5ef05398..374e35b84c4 100644
--- a/gcc/objc/objc-act.c
+++ b/gcc/objc/objc-act.c
@@ -55,7 +55,6 @@ Boston, MA 02111-1307, USA. */
#include "cpplib.h"
extern cpp_reader parse_in;
extern cpp_options parse_options;
-static int cpp_initialized;
#endif
/* This is the default way of generating a method name. */
@@ -284,7 +283,8 @@ static void dump_interface PROTO((FILE *, tree));
/* Everything else. */
-static void objc_fatal PROTO((void));
+static void objc_fatal PROTO((void))
+ ATTRIBUTE_NORETURN;
static tree define_decl PROTO((tree, tree));
static tree lookup_method_in_protocol_list PROTO((tree, tree, int));
static tree lookup_protocol_in_reflist PROTO((tree, tree));
@@ -591,9 +591,18 @@ generate_struct_by_value_array ()
exit (0);
}
+#if USE_CPPLIB
+extern char *yy_cur;
+#endif
+
void
lang_init_options ()
{
+#if USE_CPPLIB
+ cpp_reader_init (&parse_in);
+ parse_in.opts = &parse_options;
+ cpp_options_init (&parse_options);
+#endif
}
void
@@ -604,7 +613,10 @@ lang_init ()
With luck, we discover the real source file's name from that
and put it in input_filename. */
ungetc (check_newline (), finput);
-#endif
+#else
+ check_newline ();
+ yy_cur--;
+#endif
/* The line number can be -1 if we had -g3 and the input file
had a directive specifying line 0. But we want predefined
@@ -682,15 +694,6 @@ lang_decode_option (argc, argv)
char **argv;
{
char *p = argv[0];
-#if USE_CPPLIB
- if (! cpp_initialized)
- {
- cpp_reader_init (&parse_in);
- parse_in.data = &parse_options;
- cpp_options_init (&parse_options);
- cpp_initialized = 1;
- }
-#endif
if (!strcmp (p, "-lang-objc"))
doing_objc_thang = 1;
else if (!strcmp (p, "-gen-decls"))
@@ -1317,7 +1320,7 @@ my_build_string (len, str)
tree
build_objc_string (len, str)
int len;
- char *str;
+ const char *str;
{
tree s = build_string (len, str);
@@ -4610,6 +4613,7 @@ is_objc_type_qualifier (node)
|| node == ridpointers [(int) RID_OUT]
|| node == ridpointers [(int) RID_INOUT]
|| node == ridpointers [(int) RID_BYCOPY]
+ || node == ridpointers [(int) RID_BYREF]
|| node == ridpointers [(int) RID_ONEWAY]));
}
@@ -6495,6 +6499,8 @@ encode_type_qualifiers (declspecs)
obstack_1grow (&util_obstack, 'o');
else if (ridpointers[(int) RID_BYCOPY] == TREE_VALUE (spec))
obstack_1grow (&util_obstack, 'O');
+ else if (ridpointers[(int) RID_BYREF] == TREE_VALUE (spec))
+ obstack_1grow (&util_obstack, 'R');
else if (ridpointers[(int) RID_ONEWAY] == TREE_VALUE (spec))
obstack_1grow (&util_obstack, 'V');
}
diff --git a/gcc/objc/objc-parse.c b/gcc/objc/objc-parse.c
index 81daef3b8f7..b2f37427964 100644
--- a/gcc/objc/objc-parse.c
+++ b/gcc/objc/objc-parse.c
@@ -146,11 +146,11 @@ extern void yyprint PROTO ((FILE *, int, YYSTYPE));
-#define YYFINAL 947
+#define YYFINAL 952
#define YYFLAG -32768
#define YYNTBASE 84
-#define YYTRANSLATE(x) ((unsigned)(x) <= 316 ? yytranslate[x] : 309)
+#define YYTRANSLATE(x) ((unsigned)(x) <= 316 ? yytranslate[x] : 311)
static const char yytranslate[] = { 0,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
@@ -209,64 +209,64 @@ static const short yyprhs[] = { 0,
509, 511, 515, 517, 521, 522, 527, 528, 535, 539,
540, 547, 551, 552, 554, 556, 559, 566, 568, 572,
573, 575, 580, 587, 592, 594, 596, 598, 600, 602,
- 603, 608, 610, 611, 614, 616, 620, 622, 623, 628,
- 630, 631, 636, 637, 643, 644, 645, 651, 652, 653,
- 659, 661, 663, 667, 671, 676, 680, 684, 688, 690,
- 692, 696, 701, 705, 709, 713, 715, 719, 723, 727,
- 732, 736, 740, 742, 744, 747, 749, 752, 754, 757,
- 758, 766, 772, 775, 776, 784, 790, 793, 794, 803,
- 804, 812, 815, 816, 818, 819, 821, 823, 826, 827,
- 831, 834, 839, 843, 845, 849, 851, 853, 856, 858,
- 862, 867, 874, 880, 882, 886, 888, 890, 894, 897,
- 900, 901, 903, 905, 908, 909, 912, 916, 920, 923,
- 927, 932, 936, 939, 943, 946, 948, 950, 953, 956,
- 957, 959, 962, 963, 964, 966, 968, 971, 975, 977,
- 980, 982, 985, 992, 998, 1004, 1007, 1010, 1015, 1016,
- 1021, 1022, 1023, 1027, 1032, 1036, 1038, 1040, 1042, 1044,
- 1047, 1048, 1053, 1055, 1059, 1060, 1061, 1069, 1075, 1078,
- 1079, 1080, 1081, 1094, 1095, 1102, 1105, 1108, 1111, 1115,
- 1122, 1131, 1142, 1155, 1159, 1164, 1166, 1168, 1169, 1176,
- 1180, 1186, 1189, 1192, 1193, 1195, 1196, 1198, 1199, 1201,
- 1203, 1207, 1212, 1214, 1218, 1219, 1222, 1225, 1226, 1231,
- 1234, 1235, 1237, 1239, 1243, 1245, 1249, 1254, 1259, 1264,
- 1269, 1274, 1275, 1278, 1280, 1283, 1285, 1289, 1291, 1295,
- 1297, 1299, 1301, 1303, 1305, 1307, 1309, 1311, 1315, 1319,
- 1324, 1325, 1326, 1337, 1338, 1345, 1346, 1347, 1360, 1361,
- 1370, 1371, 1378, 1381, 1382, 1391, 1396, 1397, 1407, 1413,
- 1414, 1421, 1422, 1424, 1428, 1432, 1434, 1436, 1438, 1440,
- 1441, 1445, 1448, 1452, 1456, 1458, 1459, 1461, 1465, 1467,
- 1471, 1474, 1475, 1476, 1477, 1485, 1486, 1487, 1488, 1496,
- 1497, 1498, 1501, 1503, 1505, 1508, 1509, 1513, 1515, 1517,
- 1518, 1519, 1525, 1526, 1527, 1533, 1538, 1540, 1546, 1549,
- 1550, 1553, 1554, 1556, 1558, 1560, 1563, 1566, 1571, 1574,
- 1577, 1579, 1583, 1586, 1589, 1592, 1593, 1596, 1597, 1601,
- 1603, 1605, 1608, 1610, 1612, 1614, 1616, 1618, 1620, 1622,
- 1624, 1626, 1628, 1630, 1632, 1634, 1636, 1638, 1640, 1642,
- 1644, 1646, 1648, 1650, 1652, 1654, 1656, 1658, 1665, 1669,
- 1675, 1678, 1680, 1682, 1684, 1687, 1689, 1693, 1696, 1698,
- 1700, 1701, 1702, 1709, 1711, 1713, 1715, 1718, 1721, 1723,
- 1728, 1733
+ 603, 608, 610, 611, 614, 616, 620, 624, 627, 628,
+ 633, 635, 636, 641, 643, 645, 647, 650, 653, 654,
+ 655, 661, 662, 663, 669, 671, 673, 677, 681, 686,
+ 690, 694, 698, 700, 702, 706, 711, 715, 719, 723,
+ 725, 729, 733, 737, 742, 746, 750, 752, 754, 757,
+ 759, 762, 764, 767, 768, 776, 782, 785, 786, 794,
+ 800, 803, 804, 813, 814, 822, 825, 826, 828, 829,
+ 831, 833, 836, 837, 841, 844, 849, 853, 855, 859,
+ 861, 863, 866, 868, 872, 877, 884, 890, 892, 896,
+ 898, 900, 904, 907, 910, 911, 913, 915, 918, 919,
+ 922, 926, 930, 933, 937, 942, 946, 949, 953, 956,
+ 958, 960, 963, 966, 967, 969, 972, 973, 974, 976,
+ 978, 981, 985, 987, 990, 992, 995, 1002, 1008, 1014,
+ 1017, 1020, 1025, 1026, 1031, 1032, 1033, 1037, 1042, 1046,
+ 1048, 1050, 1052, 1054, 1057, 1058, 1063, 1065, 1069, 1070,
+ 1071, 1079, 1085, 1088, 1089, 1090, 1091, 1104, 1105, 1112,
+ 1115, 1118, 1121, 1125, 1132, 1141, 1152, 1165, 1169, 1174,
+ 1176, 1178, 1179, 1186, 1190, 1196, 1199, 1203, 1204, 1206,
+ 1207, 1209, 1210, 1212, 1214, 1218, 1223, 1225, 1229, 1230,
+ 1233, 1236, 1237, 1242, 1245, 1246, 1248, 1250, 1254, 1256,
+ 1260, 1265, 1270, 1275, 1280, 1285, 1286, 1289, 1291, 1294,
+ 1296, 1300, 1302, 1306, 1308, 1310, 1312, 1314, 1316, 1318,
+ 1320, 1322, 1326, 1330, 1335, 1336, 1337, 1348, 1349, 1356,
+ 1357, 1358, 1371, 1372, 1381, 1382, 1389, 1392, 1393, 1402,
+ 1407, 1408, 1418, 1424, 1425, 1432, 1433, 1435, 1439, 1443,
+ 1445, 1447, 1449, 1451, 1452, 1456, 1459, 1463, 1467, 1469,
+ 1470, 1472, 1476, 1478, 1482, 1485, 1486, 1487, 1488, 1496,
+ 1497, 1498, 1499, 1507, 1508, 1509, 1512, 1514, 1516, 1519,
+ 1520, 1524, 1526, 1528, 1529, 1530, 1536, 1537, 1538, 1544,
+ 1549, 1551, 1557, 1560, 1561, 1564, 1565, 1567, 1569, 1571,
+ 1574, 1577, 1582, 1585, 1588, 1590, 1594, 1597, 1600, 1603,
+ 1604, 1607, 1608, 1612, 1614, 1616, 1619, 1621, 1623, 1625,
+ 1627, 1629, 1631, 1633, 1635, 1637, 1639, 1641, 1643, 1645,
+ 1647, 1649, 1651, 1653, 1655, 1657, 1659, 1661, 1663, 1665,
+ 1667, 1669, 1676, 1680, 1686, 1689, 1691, 1693, 1695, 1698,
+ 1700, 1704, 1707, 1709, 1711, 1712, 1713, 1720, 1722, 1724,
+ 1726, 1729, 1732, 1734, 1739, 1744
};
static const short yyrhs[] = { -1,
85, 0, 0, 86, 88, 0, 0, 85, 87, 88,
- 0, 90, 0, 89, 0, 240, 0, 27, 59, 99,
- 76, 77, 0, 239, 88, 0, 123, 137, 77, 0,
+ 0, 90, 0, 89, 0, 242, 0, 27, 59, 99,
+ 76, 77, 0, 241, 88, 0, 123, 137, 77, 0,
130, 123, 137, 77, 0, 126, 123, 136, 77, 0,
130, 77, 0, 126, 77, 0, 1, 77, 0, 1,
- 78, 0, 77, 0, 0, 0, 126, 123, 163, 91,
- 117, 92, 197, 0, 126, 123, 163, 1, 0, 0,
- 0, 130, 123, 166, 93, 117, 94, 197, 0, 130,
- 123, 166, 1, 0, 0, 0, 123, 166, 95, 117,
- 96, 197, 0, 123, 166, 1, 0, 3, 0, 4,
+ 78, 0, 77, 0, 0, 0, 126, 123, 165, 91,
+ 117, 92, 199, 0, 126, 123, 165, 1, 0, 0,
+ 0, 130, 123, 168, 93, 117, 94, 199, 0, 130,
+ 123, 168, 1, 0, 0, 0, 123, 168, 95, 117,
+ 96, 199, 0, 123, 168, 1, 0, 3, 0, 4,
0, 72, 0, 67, 0, 43, 0, 49, 0, 48,
0, 54, 0, 55, 0, 79, 0, 80, 0, 101,
0, 0, 101, 0, 107, 0, 101, 81, 107, 0,
- 113, 0, 50, 105, 0, 239, 105, 0, 98, 105,
- 0, 40, 97, 0, 103, 102, 0, 103, 59, 184,
- 76, 0, 104, 102, 0, 104, 59, 184, 76, 0,
+ 113, 0, 50, 105, 0, 241, 105, 0, 98, 105,
+ 0, 40, 97, 0, 103, 102, 0, 103, 59, 186,
+ 76, 0, 104, 102, 0, 104, 59, 186, 76, 0,
33, 105, 0, 34, 105, 0, 11, 0, 29, 0,
- 102, 0, 59, 184, 76, 105, 0, 0, 59, 184,
+ 102, 0, 59, 186, 76, 105, 0, 0, 59, 186,
76, 82, 106, 151, 78, 0, 105, 0, 107, 48,
107, 0, 107, 49, 107, 0, 107, 50, 107, 0,
107, 51, 107, 0, 107, 52, 107, 0, 107, 46,
@@ -278,151 +278,152 @@ static const short yyrhs[] = { -1,
37, 112, 38, 107, 0, 107, 36, 107, 0, 107,
35, 107, 0, 3, 0, 8, 0, 115, 0, 59,
99, 76, 0, 59, 1, 76, 0, 0, 59, 114,
- 199, 76, 0, 113, 59, 100, 76, 0, 113, 60,
+ 201, 76, 0, 113, 59, 100, 76, 0, 113, 60,
99, 83, 0, 113, 58, 97, 0, 113, 57, 97,
- 0, 113, 54, 0, 113, 55, 0, 300, 0, 306,
- 0, 307, 0, 308, 0, 116, 0, 9, 0, 115,
+ 0, 113, 54, 0, 113, 55, 0, 302, 0, 308,
+ 0, 309, 0, 310, 0, 116, 0, 9, 0, 115,
9, 0, 75, 0, 116, 75, 0, 0, 119, 0,
- 119, 10, 0, 204, 205, 120, 0, 118, 0, 192,
- 0, 119, 118, 0, 118, 192, 0, 128, 123, 136,
+ 119, 10, 0, 206, 207, 120, 0, 118, 0, 194,
+ 0, 119, 118, 0, 118, 194, 0, 128, 123, 136,
77, 0, 131, 123, 137, 77, 0, 128, 77, 0,
- 131, 77, 0, 204, 205, 125, 0, 121, 0, 192,
- 0, 122, 121, 0, 121, 192, 0, 0, 0, 126,
+ 131, 77, 0, 206, 207, 125, 0, 121, 0, 194,
+ 0, 122, 121, 0, 121, 194, 0, 0, 0, 126,
123, 136, 77, 0, 130, 123, 137, 77, 0, 126,
- 123, 157, 0, 130, 123, 160, 0, 126, 77, 0,
- 130, 77, 0, 239, 125, 0, 134, 127, 0, 130,
+ 123, 159, 0, 130, 123, 162, 0, 126, 77, 0,
+ 130, 77, 0, 241, 125, 0, 134, 127, 0, 130,
134, 127, 0, 0, 127, 135, 0, 127, 5, 0,
127, 144, 0, 134, 129, 0, 131, 134, 129, 0,
0, 129, 135, 0, 129, 5, 0, 131, 0, 144,
0, 130, 131, 0, 130, 144, 0, 7, 0, 5,
0, 131, 7, 0, 131, 5, 0, 134, 133, 0,
- 186, 134, 133, 0, 0, 133, 135, 0, 6, 0,
- 170, 0, 4, 0, 67, 256, 0, 72, 256, 0,
- 257, 0, 28, 59, 99, 76, 0, 28, 59, 184,
- 76, 0, 6, 0, 7, 0, 170, 0, 139, 0,
+ 188, 134, 133, 0, 0, 133, 135, 0, 6, 0,
+ 172, 0, 4, 0, 67, 258, 0, 72, 258, 0,
+ 259, 0, 28, 59, 99, 76, 0, 28, 59, 186,
+ 76, 0, 6, 0, 7, 0, 172, 0, 139, 0,
136, 81, 139, 0, 141, 0, 137, 81, 139, 0,
- 0, 27, 59, 115, 76, 0, 0, 163, 138, 143,
- 36, 140, 149, 0, 163, 138, 143, 0, 0, 166,
- 138, 143, 36, 142, 149, 0, 166, 138, 143, 0,
+ 0, 27, 59, 115, 76, 0, 0, 165, 138, 143,
+ 36, 140, 149, 0, 165, 138, 143, 0, 0, 168,
+ 138, 143, 36, 142, 149, 0, 168, 138, 143, 0,
0, 144, 0, 145, 0, 144, 145, 0, 30, 59,
59, 146, 76, 76, 0, 147, 0, 146, 81, 147,
0, 0, 148, 0, 148, 59, 3, 76, 0, 148,
59, 3, 81, 101, 76, 0, 148, 59, 100, 76,
0, 97, 0, 5, 0, 6, 0, 7, 0, 107,
0, 0, 82, 150, 151, 78, 0, 1, 0, 0,
- 152, 175, 0, 153, 0, 152, 81, 153, 0, 107,
- 0, 0, 82, 154, 151, 78, 0, 1, 0, 0,
- 97, 38, 155, 153, 0, 0, 58, 97, 36, 156,
- 153, 0, 0, 0, 163, 158, 117, 159, 199, 0,
- 0, 0, 166, 161, 117, 162, 199, 0, 164, 0,
- 166, 0, 59, 164, 76, 0, 164, 59, 234, 0,
- 164, 60, 99, 83, 0, 164, 60, 83, 0, 50,
- 187, 164, 0, 144, 124, 164, 0, 4, 0, 72,
- 0, 165, 59, 234, 0, 165, 60, 99, 83, 0,
- 165, 60, 83, 0, 50, 187, 165, 0, 144, 124,
- 165, 0, 4, 0, 166, 59, 234, 0, 59, 166,
- 76, 0, 50, 187, 166, 0, 166, 60, 99, 83,
- 0, 166, 60, 83, 0, 144, 124, 166, 0, 3,
+ 152, 177, 0, 153, 0, 152, 81, 153, 0, 157,
+ 36, 155, 0, 158, 155, 0, 0, 97, 38, 154,
+ 155, 0, 155, 0, 0, 82, 156, 151, 78, 0,
+ 107, 0, 1, 0, 158, 0, 157, 158, 0, 58,
+ 97, 0, 0, 0, 165, 160, 117, 161, 201, 0,
+ 0, 0, 168, 163, 117, 164, 201, 0, 166, 0,
+ 168, 0, 59, 166, 76, 0, 166, 59, 236, 0,
+ 166, 60, 99, 83, 0, 166, 60, 83, 0, 50,
+ 189, 166, 0, 144, 124, 166, 0, 4, 0, 72,
+ 0, 167, 59, 236, 0, 167, 60, 99, 83, 0,
+ 167, 60, 83, 0, 50, 189, 167, 0, 144, 124,
+ 167, 0, 4, 0, 168, 59, 236, 0, 59, 168,
+ 76, 0, 50, 189, 168, 0, 168, 60, 99, 83,
+ 0, 168, 60, 83, 0, 144, 124, 168, 0, 3,
0, 13, 0, 13, 144, 0, 14, 0, 14, 144,
- 0, 12, 0, 12, 144, 0, 0, 167, 97, 82,
- 171, 177, 78, 143, 0, 167, 82, 177, 78, 143,
- 0, 167, 97, 0, 0, 168, 97, 82, 172, 177,
- 78, 143, 0, 168, 82, 177, 78, 143, 0, 168,
- 97, 0, 0, 169, 97, 82, 173, 182, 176, 78,
- 143, 0, 0, 169, 82, 174, 182, 176, 78, 143,
- 0, 169, 97, 0, 0, 81, 0, 0, 81, 0,
- 178, 0, 178, 179, 0, 0, 178, 179, 77, 0,
- 178, 77, 0, 65, 59, 67, 76, 0, 132, 123,
- 180, 0, 132, 0, 186, 123, 180, 0, 186, 0,
- 1, 0, 239, 179, 0, 181, 0, 180, 81, 181,
- 0, 204, 205, 163, 143, 0, 204, 205, 163, 38,
- 107, 143, 0, 204, 205, 38, 107, 143, 0, 183,
- 0, 182, 81, 183, 0, 1, 0, 97, 0, 97,
- 36, 107, 0, 132, 185, 0, 186, 185, 0, 0,
- 188, 0, 7, 0, 186, 7, 0, 0, 187, 7,
- 0, 59, 188, 76, 0, 50, 187, 188, 0, 50,
- 187, 0, 188, 59, 227, 0, 188, 60, 99, 83,
- 0, 188, 60, 83, 0, 59, 227, 0, 60, 99,
- 83, 0, 60, 83, 0, 190, 0, 207, 0, 190,
- 207, 0, 190, 192, 0, 0, 189, 0, 1, 77,
- 0, 0, 0, 195, 0, 196, 0, 195, 196, 0,
- 32, 238, 77, 0, 199, 0, 1, 199, 0, 82,
- 0, 198, 78, 0, 198, 193, 194, 122, 191, 78,
- 0, 198, 193, 194, 1, 78, 0, 198, 193, 194,
- 189, 78, 0, 201, 206, 0, 201, 1, 0, 15,
- 59, 99, 76, 0, 0, 18, 203, 206, 17, 0,
- 0, 0, 204, 205, 209, 0, 204, 205, 220, 206,
- 0, 204, 205, 208, 0, 209, 0, 220, 0, 199,
- 0, 217, 0, 99, 77, 0, 0, 200, 16, 210,
- 206, 0, 200, 0, 200, 16, 1, 0, 0, 0,
- 17, 211, 59, 99, 76, 212, 206, 0, 202, 59,
- 99, 76, 77, 0, 202, 1, 0, 0, 0, 0,
- 19, 59, 222, 77, 213, 222, 77, 214, 222, 76,
- 215, 206, 0, 0, 20, 59, 99, 76, 216, 206,
+ 0, 12, 0, 12, 144, 0, 0, 169, 97, 82,
+ 173, 179, 78, 143, 0, 169, 82, 179, 78, 143,
+ 0, 169, 97, 0, 0, 170, 97, 82, 174, 179,
+ 78, 143, 0, 170, 82, 179, 78, 143, 0, 170,
+ 97, 0, 0, 171, 97, 82, 175, 184, 178, 78,
+ 143, 0, 0, 171, 82, 176, 184, 178, 78, 143,
+ 0, 171, 97, 0, 0, 81, 0, 0, 81, 0,
+ 180, 0, 180, 181, 0, 0, 180, 181, 77, 0,
+ 180, 77, 0, 65, 59, 67, 76, 0, 132, 123,
+ 182, 0, 132, 0, 188, 123, 182, 0, 188, 0,
+ 1, 0, 241, 181, 0, 183, 0, 182, 81, 183,
+ 0, 206, 207, 165, 143, 0, 206, 207, 165, 38,
+ 107, 143, 0, 206, 207, 38, 107, 143, 0, 185,
+ 0, 184, 81, 185, 0, 1, 0, 97, 0, 97,
+ 36, 107, 0, 132, 187, 0, 188, 187, 0, 0,
+ 190, 0, 7, 0, 188, 7, 0, 0, 189, 7,
+ 0, 59, 190, 76, 0, 50, 189, 190, 0, 50,
+ 189, 0, 190, 59, 229, 0, 190, 60, 99, 83,
+ 0, 190, 60, 83, 0, 59, 229, 0, 60, 99,
+ 83, 0, 60, 83, 0, 192, 0, 209, 0, 192,
+ 209, 0, 192, 194, 0, 0, 191, 0, 1, 77,
+ 0, 0, 0, 197, 0, 198, 0, 197, 198, 0,
+ 32, 240, 77, 0, 201, 0, 1, 201, 0, 82,
+ 0, 200, 78, 0, 200, 195, 196, 122, 193, 78,
+ 0, 200, 195, 196, 1, 78, 0, 200, 195, 196,
+ 191, 78, 0, 203, 208, 0, 203, 1, 0, 15,
+ 59, 99, 76, 0, 0, 18, 205, 208, 17, 0,
+ 0, 0, 206, 207, 211, 0, 206, 207, 222, 208,
+ 0, 206, 207, 210, 0, 211, 0, 222, 0, 201,
+ 0, 219, 0, 99, 77, 0, 0, 202, 16, 212,
+ 208, 0, 202, 0, 202, 16, 1, 0, 0, 0,
+ 17, 213, 59, 99, 76, 214, 208, 0, 204, 59,
+ 99, 76, 77, 0, 204, 1, 0, 0, 0, 0,
+ 19, 59, 224, 77, 215, 224, 77, 216, 224, 76,
+ 217, 208, 0, 0, 20, 59, 99, 76, 218, 208,
0, 23, 77, 0, 24, 77, 0, 25, 77, 0,
- 25, 99, 77, 0, 27, 221, 59, 99, 76, 77,
- 0, 27, 221, 59, 99, 38, 223, 76, 77, 0,
- 27, 221, 59, 99, 38, 223, 38, 223, 76, 77,
- 0, 27, 221, 59, 99, 38, 223, 38, 223, 38,
- 226, 76, 77, 0, 26, 97, 77, 0, 26, 50,
- 99, 77, 0, 77, 0, 218, 0, 0, 19, 59,
- 113, 76, 219, 206, 0, 21, 107, 38, 0, 21,
+ 25, 99, 77, 0, 27, 223, 59, 99, 76, 77,
+ 0, 27, 223, 59, 99, 38, 225, 76, 77, 0,
+ 27, 223, 59, 99, 38, 225, 38, 225, 76, 77,
+ 0, 27, 223, 59, 99, 38, 225, 38, 225, 38,
+ 228, 76, 77, 0, 26, 97, 77, 0, 26, 50,
+ 99, 77, 0, 77, 0, 220, 0, 0, 19, 59,
+ 113, 76, 221, 208, 0, 21, 107, 38, 0, 21,
107, 10, 107, 38, 0, 22, 38, 0, 97, 38,
- 0, 0, 7, 0, 0, 99, 0, 0, 224, 0,
- 225, 0, 224, 81, 225, 0, 9, 59, 99, 76,
- 0, 115, 0, 226, 81, 115, 0, 0, 228, 229,
- 0, 231, 76, 0, 0, 232, 77, 230, 229, 0,
- 1, 76, 0, 0, 10, 0, 232, 0, 232, 81,
- 10, 0, 233, 0, 232, 81, 233, 0, 126, 123,
- 165, 143, 0, 126, 123, 166, 143, 0, 126, 123,
- 185, 143, 0, 130, 123, 166, 143, 0, 130, 123,
- 185, 143, 0, 0, 235, 236, 0, 229, 0, 237,
- 76, 0, 3, 0, 237, 81, 3, 0, 97, 0,
- 238, 81, 97, 0, 31, 0, 244, 0, 242, 0,
- 243, 0, 254, 0, 264, 0, 63, 0, 97, 0,
- 241, 81, 97, 0, 73, 241, 77, 0, 74, 97,
- 97, 77, 0, 0, 0, 61, 97, 256, 82, 245,
- 258, 78, 246, 271, 63, 0, 0, 61, 97, 256,
- 247, 271, 63, 0, 0, 0, 61, 97, 38, 97,
- 256, 82, 248, 258, 78, 249, 271, 63, 0, 0,
- 61, 97, 38, 97, 256, 250, 271, 63, 0, 0,
- 62, 97, 82, 251, 258, 78, 0, 62, 97, 0,
- 0, 62, 97, 38, 97, 82, 252, 258, 78, 0,
- 62, 97, 38, 97, 0, 0, 61, 97, 59, 97,
- 76, 256, 253, 271, 63, 0, 62, 97, 59, 97,
- 76, 0, 0, 71, 97, 256, 255, 271, 63, 0,
- 0, 257, 0, 45, 241, 45, 0, 258, 259, 260,
- 0, 260, 0, 69, 0, 70, 0, 68, 0, 0,
- 260, 261, 77, 0, 260, 77, 0, 132, 123, 262,
- 0, 186, 123, 262, 0, 1, 0, 0, 263, 0,
- 262, 81, 263, 0, 163, 0, 163, 38, 107, 0,
- 38, 107, 0, 0, 0, 0, 48, 265, 281, 266,
- 282, 267, 197, 0, 0, 0, 0, 49, 268, 281,
- 269, 282, 270, 197, 0, 0, 0, 272, 273, 0,
- 276, 0, 89, 0, 273, 276, 0, 0, 273, 274,
- 89, 0, 77, 0, 1, 0, 0, 0, 48, 277,
- 281, 278, 275, 0, 0, 0, 49, 279, 281, 280,
- 275, 0, 59, 184, 76, 290, 0, 290, 0, 59,
- 184, 76, 291, 288, 0, 291, 288, 0, 0, 77,
- 283, 0, 0, 284, 0, 285, 0, 192, 0, 284,
- 285, 0, 285, 192, 0, 126, 123, 286, 77, 0,
- 126, 77, 0, 130, 77, 0, 287, 0, 286, 81,
- 287, 0, 165, 143, 0, 166, 143, 0, 185, 143,
- 0, 0, 81, 10, 0, 0, 81, 289, 231, 0,
- 292, 0, 294, 0, 291, 294, 0, 3, 0, 4,
- 0, 72, 0, 293, 0, 12, 0, 13, 0, 14,
- 0, 15, 0, 16, 0, 17, 0, 18, 0, 19,
- 0, 20, 0, 21, 0, 22, 0, 23, 0, 24,
- 0, 25, 0, 26, 0, 27, 0, 11, 0, 28,
- 0, 29, 0, 6, 0, 7, 0, 292, 38, 59,
- 184, 76, 97, 0, 292, 38, 97, 0, 38, 59,
- 184, 76, 97, 0, 38, 97, 0, 292, 0, 296,
- 0, 298, 0, 296, 298, 0, 101, 0, 292, 38,
- 297, 0, 38, 297, 0, 99, 0, 67, 0, 0,
- 0, 60, 301, 299, 302, 295, 83, 0, 292, 0,
- 304, 0, 305, 0, 304, 305, 0, 292, 38, 0,
- 38, 0, 64, 59, 303, 76, 0, 71, 59, 97,
- 76, 0, 66, 59, 184, 76, 0
+ 143, 0, 0, 7, 0, 0, 99, 0, 0, 226,
+ 0, 227, 0, 226, 81, 227, 0, 9, 59, 99,
+ 76, 0, 115, 0, 228, 81, 115, 0, 0, 230,
+ 231, 0, 233, 76, 0, 0, 234, 77, 232, 231,
+ 0, 1, 76, 0, 0, 10, 0, 234, 0, 234,
+ 81, 10, 0, 235, 0, 234, 81, 235, 0, 126,
+ 123, 167, 143, 0, 126, 123, 168, 143, 0, 126,
+ 123, 187, 143, 0, 130, 123, 168, 143, 0, 130,
+ 123, 187, 143, 0, 0, 237, 238, 0, 231, 0,
+ 239, 76, 0, 3, 0, 239, 81, 3, 0, 97,
+ 0, 240, 81, 97, 0, 31, 0, 246, 0, 244,
+ 0, 245, 0, 256, 0, 266, 0, 63, 0, 97,
+ 0, 243, 81, 97, 0, 73, 243, 77, 0, 74,
+ 97, 97, 77, 0, 0, 0, 61, 97, 258, 82,
+ 247, 260, 78, 248, 273, 63, 0, 0, 61, 97,
+ 258, 249, 273, 63, 0, 0, 0, 61, 97, 38,
+ 97, 258, 82, 250, 260, 78, 251, 273, 63, 0,
+ 0, 61, 97, 38, 97, 258, 252, 273, 63, 0,
+ 0, 62, 97, 82, 253, 260, 78, 0, 62, 97,
+ 0, 0, 62, 97, 38, 97, 82, 254, 260, 78,
+ 0, 62, 97, 38, 97, 0, 0, 61, 97, 59,
+ 97, 76, 258, 255, 273, 63, 0, 62, 97, 59,
+ 97, 76, 0, 0, 71, 97, 258, 257, 273, 63,
+ 0, 0, 259, 0, 45, 243, 45, 0, 260, 261,
+ 262, 0, 262, 0, 69, 0, 70, 0, 68, 0,
+ 0, 262, 263, 77, 0, 262, 77, 0, 132, 123,
+ 264, 0, 188, 123, 264, 0, 1, 0, 0, 265,
+ 0, 264, 81, 265, 0, 165, 0, 165, 38, 107,
+ 0, 38, 107, 0, 0, 0, 0, 48, 267, 283,
+ 268, 284, 269, 199, 0, 0, 0, 0, 49, 270,
+ 283, 271, 284, 272, 199, 0, 0, 0, 274, 275,
+ 0, 278, 0, 89, 0, 275, 278, 0, 0, 275,
+ 276, 89, 0, 77, 0, 1, 0, 0, 0, 48,
+ 279, 283, 280, 277, 0, 0, 0, 49, 281, 283,
+ 282, 277, 0, 59, 186, 76, 292, 0, 292, 0,
+ 59, 186, 76, 293, 290, 0, 293, 290, 0, 0,
+ 77, 285, 0, 0, 286, 0, 287, 0, 194, 0,
+ 286, 287, 0, 287, 194, 0, 126, 123, 288, 77,
+ 0, 126, 77, 0, 130, 77, 0, 289, 0, 288,
+ 81, 289, 0, 167, 143, 0, 168, 143, 0, 187,
+ 143, 0, 0, 81, 10, 0, 0, 81, 291, 233,
+ 0, 294, 0, 296, 0, 293, 296, 0, 3, 0,
+ 4, 0, 72, 0, 295, 0, 12, 0, 13, 0,
+ 14, 0, 15, 0, 16, 0, 17, 0, 18, 0,
+ 19, 0, 20, 0, 21, 0, 22, 0, 23, 0,
+ 24, 0, 25, 0, 26, 0, 27, 0, 11, 0,
+ 28, 0, 29, 0, 6, 0, 7, 0, 294, 38,
+ 59, 186, 76, 97, 0, 294, 38, 97, 0, 38,
+ 59, 186, 76, 97, 0, 38, 97, 0, 294, 0,
+ 298, 0, 300, 0, 298, 300, 0, 101, 0, 294,
+ 38, 299, 0, 38, 299, 0, 99, 0, 67, 0,
+ 0, 0, 60, 303, 301, 304, 297, 83, 0, 294,
+ 0, 306, 0, 307, 0, 306, 307, 0, 294, 38,
+ 0, 38, 0, 64, 59, 305, 76, 0, 71, 59,
+ 97, 76, 0, 66, 59, 186, 76, 0
};
#endif
@@ -449,43 +450,43 @@ static const short yyrline[] = { 0,
1080, 1082, 1085, 1087, 1090, 1093, 1099, 1106, 1108, 1115,
1122, 1125, 1132, 1135, 1139, 1142, 1146, 1151, 1154, 1158,
1161, 1163, 1165, 1167, 1174, 1176, 1177, 1178, 1183, 1185,
- 1190, 1198, 1203, 1207, 1210, 1212, 1217, 1220, 1222, 1224,
- 1228, 1231, 1231, 1234, 1236, 1247, 1255, 1259, 1270, 1278,
- 1285, 1287, 1292, 1295, 1300, 1302, 1304, 1311, 1313, 1314,
- 1322, 1328, 1330, 1332, 1339, 1341, 1347, 1353, 1355, 1357,
- 1359, 1366, 1368, 1371, 1374, 1378, 1381, 1385, 1388, 1392,
- 1397, 1399, 1403, 1405, 1407, 1409, 1413, 1415, 1418, 1421,
- 1424, 1427, 1431, 1433, 1436, 1438, 1442, 1445, 1450, 1452,
- 1454, 1458, 1482, 1489, 1494, 1500, 1505, 1507, 1512, 1514,
- 1518, 1522, 1526, 1536, 1538, 1543, 1548, 1551, 1555, 1558,
- 1562, 1565, 1568, 1571, 1575, 1578, 1582, 1586, 1588, 1590,
- 1592, 1594, 1596, 1598, 1600, 1610, 1618, 1620, 1622, 1626,
- 1628, 1631, 1634, 1647, 1649, 1654, 1656, 1659, 1673, 1676,
- 1679, 1681, 1683, 1691, 1699, 1710, 1715, 1718, 1732, 1741,
- 1745, 1749, 1753, 1759, 1763, 1768, 1771, 1776, 1779, 1780,
- 1797, 1802, 1805, 1817, 1819, 1829, 1839, 1840, 1848, 1851,
- 1863, 1867, 1884, 1894, 1903, 1908, 1913, 1918, 1922, 1926,
- 1937, 1944, 1951, 1958, 1969, 1975, 1978, 1983, 2006, 2040,
- 2071, 2102, 2117, 2128, 2132, 2136, 2139, 2144, 2146, 2149,
- 2151, 2155, 2160, 2163, 2169, 2174, 2179, 2181, 2190, 2191,
- 2197, 2199, 2209, 2211, 2215, 2218, 2224, 2234, 2243, 2252,
- 2262, 2276, 2281, 2286, 2288, 2297, 2300, 2305, 2308, 2312,
- 2320, 2322, 2323, 2324, 2325, 2326, 2340, 2343, 2347, 2353,
- 2359, 2366, 2371, 2377, 2384, 2390, 2396, 2401, 2407, 2414,
- 2420, 2426, 2432, 2440, 2446, 2452, 2460, 2467, 2473, 2482,
- 2489, 2497, 2502, 2505, 2515, 2517, 2520, 2522, 2523, 2526,
- 2531, 2532, 2549, 2556, 2562, 2566, 2569, 2570, 2573, 2581,
- 2587, 2596, 2606, 2613, 2617, 2622, 2631, 2638, 2642, 2652,
- 2654, 2655, 2657, 2659, 2660, 2661, 2662, 2664, 2666, 2669,
- 2677, 2684, 2684, 2691, 2697, 2699, 2705, 2710, 2715, 2724,
- 2726, 2732, 2734, 2737, 2739, 2740, 2741, 2744, 2750, 2752,
- 2756, 2759, 2766, 2772, 2777, 2784, 2789, 2794, 2799, 2806,
- 2810, 2813, 2819, 2821, 2822, 2823, 2826, 2828, 2829, 2830,
- 2831, 2832, 2833, 2834, 2835, 2836, 2837, 2838, 2839, 2840,
- 2841, 2842, 2843, 2844, 2845, 2846, 2846, 2849, 2855, 2860,
- 2865, 2871, 2873, 2876, 2878, 2885, 2897, 2902, 2908, 2910,
- 2916, 2920, 2921, 2927, 2929, 2932, 2934, 2940, 2945, 2951,
- 2958, 2967
+ 1190, 1198, 1203, 1207, 1210, 1212, 1217, 1219, 1220, 1223,
+ 1223, 1226, 1229, 1231, 1233, 1236, 1238, 1241, 1249, 1260,
+ 1268, 1272, 1283, 1291, 1298, 1300, 1305, 1308, 1313, 1315,
+ 1317, 1324, 1326, 1327, 1335, 1341, 1343, 1345, 1352, 1354,
+ 1360, 1366, 1368, 1370, 1372, 1379, 1381, 1384, 1387, 1391,
+ 1394, 1398, 1401, 1405, 1410, 1412, 1416, 1418, 1420, 1422,
+ 1426, 1428, 1431, 1434, 1437, 1440, 1444, 1446, 1449, 1451,
+ 1456, 1459, 1464, 1466, 1468, 1472, 1496, 1503, 1508, 1514,
+ 1519, 1521, 1526, 1528, 1532, 1536, 1540, 1550, 1552, 1557,
+ 1562, 1565, 1569, 1572, 1576, 1579, 1582, 1585, 1589, 1592,
+ 1596, 1600, 1602, 1604, 1606, 1608, 1610, 1612, 1614, 1624,
+ 1632, 1634, 1636, 1640, 1642, 1645, 1648, 1661, 1663, 1668,
+ 1670, 1673, 1687, 1690, 1693, 1695, 1697, 1705, 1713, 1724,
+ 1729, 1732, 1746, 1755, 1759, 1763, 1767, 1773, 1777, 1782,
+ 1785, 1790, 1793, 1794, 1811, 1816, 1819, 1831, 1833, 1843,
+ 1853, 1854, 1862, 1865, 1877, 1881, 1898, 1908, 1917, 1922,
+ 1927, 1932, 1936, 1940, 1951, 1958, 1965, 1972, 1983, 1989,
+ 1992, 1997, 2020, 2054, 2085, 2116, 2131, 2145, 2149, 2153,
+ 2156, 2161, 2163, 2166, 2168, 2172, 2177, 2180, 2186, 2191,
+ 2196, 2198, 2207, 2208, 2214, 2216, 2226, 2228, 2232, 2235,
+ 2241, 2251, 2260, 2269, 2279, 2293, 2298, 2303, 2305, 2314,
+ 2317, 2322, 2325, 2329, 2337, 2339, 2340, 2341, 2342, 2343,
+ 2357, 2360, 2364, 2370, 2376, 2383, 2388, 2394, 2401, 2407,
+ 2413, 2418, 2424, 2431, 2437, 2443, 2449, 2457, 2463, 2469,
+ 2477, 2484, 2490, 2499, 2506, 2514, 2519, 2522, 2532, 2534,
+ 2537, 2539, 2540, 2543, 2548, 2549, 2566, 2573, 2579, 2583,
+ 2586, 2587, 2590, 2598, 2604, 2613, 2623, 2630, 2634, 2639,
+ 2648, 2655, 2659, 2669, 2671, 2672, 2674, 2676, 2677, 2678,
+ 2679, 2681, 2683, 2686, 2694, 2701, 2701, 2708, 2714, 2716,
+ 2722, 2727, 2732, 2741, 2743, 2749, 2751, 2754, 2756, 2757,
+ 2758, 2761, 2767, 2769, 2773, 2776, 2783, 2789, 2794, 2801,
+ 2806, 2811, 2816, 2823, 2827, 2830, 2836, 2838, 2839, 2840,
+ 2843, 2845, 2846, 2847, 2848, 2849, 2850, 2851, 2852, 2853,
+ 2854, 2855, 2856, 2857, 2858, 2859, 2860, 2861, 2862, 2863,
+ 2863, 2866, 2872, 2877, 2882, 2888, 2890, 2893, 2895, 2902,
+ 2914, 2919, 2925, 2927, 2933, 2937, 2938, 2944, 2946, 2949,
+ 2951, 2957, 2962, 2968, 2975, 2984
};
#endif
@@ -512,28 +513,28 @@ static const char * const yytname[] = { "$","error","$undefined.","IDENTIFIER"
"typespec","typespecqual_reserved","initdecls","notype_initdecls","maybeasm",
"initdcl","@16","notype_initdcl","@17","maybe_attribute","attributes","attribute",
"attribute_list","attrib","any_word","init","@18","initlist_maybe_comma","initlist1",
-"initelt","@19","@20","@21","nested_function","@22","@23","notype_nested_function",
-"@24","@25","declarator","after_type_declarator","parm_declarator","notype_declarator",
-"struct_head","union_head","enum_head","structsp","@26","@27","@28","@29","maybecomma",
-"maybecomma_warn","component_decl_list","component_decl_list2","component_decl",
-"components","component_declarator","enumlist","enumerator","typename","absdcl",
-"nonempty_type_quals","type_quals","absdcl1","stmts","lineno_stmt_or_labels",
-"xstmts","errstmt","pushlevel","maybe_label_decls","label_decls","label_decl",
-"compstmt_or_error","compstmt_start","compstmt","simple_if","if_prefix","do_stmt_start",
-"@30","save_filename","save_lineno","lineno_labeled_stmt","lineno_stmt_or_label",
-"stmt_or_label","stmt","@31","@32","@33","@34","@35","@36","@37","all_iter_stmt",
-"all_iter_stmt_simple","@38","label","maybe_type_qual","xexpr","asm_operands",
-"nonnull_asm_operands","asm_operand","asm_clobbers","parmlist","@39","parmlist_1",
-"@40","parmlist_2","parms","parm","parmlist_or_identifiers","@41","parmlist_or_identifiers_1",
-"identifiers","identifiers_or_typenames","extension","objcdef","identifier_list",
-"classdecl","aliasdecl","classdef","@42","@43","@44","@45","@46","@47","@48",
-"@49","@50","protocoldef","@51","protocolrefs","non_empty_protocolrefs","ivar_decl_list",
-"visibility_spec","ivar_decls","ivar_decl","ivars","ivar_declarator","methoddef",
-"@52","@53","@54","@55","@56","@57","methodprotolist","@58","methodprotolist2",
-"@59","semi_or_error","methodproto","@60","@61","@62","@63","methoddecl","optarglist",
-"myxdecls","mydecls","mydecl","myparms","myparm","optparmlist","@64","unaryselector",
+"initelt","@19","initval","@20","designator_list","designator","nested_function",
+"@21","@22","notype_nested_function","@23","@24","declarator","after_type_declarator",
+"parm_declarator","notype_declarator","struct_head","union_head","enum_head",
+"structsp","@25","@26","@27","@28","maybecomma","maybecomma_warn","component_decl_list",
+"component_decl_list2","component_decl","components","component_declarator",
+"enumlist","enumerator","typename","absdcl","nonempty_type_quals","type_quals",
+"absdcl1","stmts","lineno_stmt_or_labels","xstmts","errstmt","pushlevel","maybe_label_decls",
+"label_decls","label_decl","compstmt_or_error","compstmt_start","compstmt","simple_if",
+"if_prefix","do_stmt_start","@29","save_filename","save_lineno","lineno_labeled_stmt",
+"lineno_stmt_or_label","stmt_or_label","stmt","@30","@31","@32","@33","@34",
+"@35","@36","all_iter_stmt","all_iter_stmt_simple","@37","label","maybe_type_qual",
+"xexpr","asm_operands","nonnull_asm_operands","asm_operand","asm_clobbers","parmlist",
+"@38","parmlist_1","@39","parmlist_2","parms","parm","parmlist_or_identifiers",
+"@40","parmlist_or_identifiers_1","identifiers","identifiers_or_typenames","extension",
+"objcdef","identifier_list","classdecl","aliasdecl","classdef","@41","@42","@43",
+"@44","@45","@46","@47","@48","@49","protocoldef","@50","protocolrefs","non_empty_protocolrefs",
+"ivar_decl_list","visibility_spec","ivar_decls","ivar_decl","ivars","ivar_declarator",
+"methoddef","@51","@52","@53","@54","@55","@56","methodprotolist","@57","methodprotolist2",
+"@58","semi_or_error","methodproto","@59","@60","@61","@62","methoddecl","optarglist",
+"myxdecls","mydecls","mydecl","myparms","myparm","optparmlist","@63","unaryselector",
"keywordselector","selector","reservedwords","keyworddecl","messageargs","keywordarglist",
-"keywordexpr","keywordarg","receiver","objcmessageexpr","@65","@66","selectorarg",
+"keywordexpr","keywordarg","receiver","objcmessageexpr","@64","@65","selectorarg",
"keywordnamelist","keywordname","objcselectorexpr","objcprotocolexpr","objcencodeexpr", NULL
};
#endif
@@ -559,43 +560,43 @@ static const short yyr1[] = { 0,
136, 136, 137, 137, 138, 138, 140, 139, 139, 142,
141, 141, 143, 143, 144, 144, 145, 146, 146, 147,
147, 147, 147, 147, 148, 148, 148, 148, 149, 150,
- 149, 149, 151, 151, 152, 152, 153, 154, 153, 153,
- 155, 153, 156, 153, 158, 159, 157, 161, 162, 160,
- 163, 163, 164, 164, 164, 164, 164, 164, 164, 164,
- 165, 165, 165, 165, 165, 165, 166, 166, 166, 166,
- 166, 166, 166, 167, 167, 168, 168, 169, 169, 171,
- 170, 170, 170, 172, 170, 170, 170, 173, 170, 174,
- 170, 170, 175, 175, 176, 176, 177, 177, 178, 178,
- 178, 178, 179, 179, 179, 179, 179, 179, 180, 180,
- 181, 181, 181, 182, 182, 182, 183, 183, 184, 184,
- 185, 185, 186, 186, 187, 187, 188, 188, 188, 188,
- 188, 188, 188, 188, 188, 189, 190, 190, 190, 191,
- 191, 192, 193, 194, 194, 195, 195, 196, 197, 197,
- 198, 199, 199, 199, 199, 200, 200, 201, 203, 202,
- 204, 205, 206, 206, 207, 208, 208, 209, 209, 209,
- 210, 209, 209, 209, 211, 212, 209, 209, 209, 213,
- 214, 215, 209, 216, 209, 209, 209, 209, 209, 209,
- 209, 209, 209, 209, 209, 209, 217, 219, 218, 220,
- 220, 220, 220, 221, 221, 222, 222, 223, 223, 224,
- 224, 225, 226, 226, 228, 227, 229, 230, 229, 229,
- 231, 231, 231, 231, 232, 232, 233, 233, 233, 233,
- 233, 235, 234, 236, 236, 237, 237, 238, 238, 239,
- 240, 240, 240, 240, 240, 240, 241, 241, 242, 243,
- 245, 246, 244, 247, 244, 248, 249, 244, 250, 244,
- 251, 244, 244, 252, 244, 244, 253, 244, 244, 255,
- 254, 256, 256, 257, 258, 258, 259, 259, 259, 260,
- 260, 260, 261, 261, 261, 262, 262, 262, 263, 263,
- 263, 265, 266, 267, 264, 268, 269, 270, 264, 271,
- 272, 271, 273, 273, 273, 274, 273, 275, 275, 277,
- 278, 276, 279, 280, 276, 281, 281, 281, 281, 282,
- 282, 283, 283, 284, 284, 284, 284, 285, 285, 285,
- 286, 286, 287, 287, 287, 288, 288, 289, 288, 290,
- 291, 291, 292, 292, 292, 292, 293, 293, 293, 293,
- 293, 293, 293, 293, 293, 293, 293, 293, 293, 293,
- 293, 293, 293, 293, 293, 293, 293, 294, 294, 294,
- 294, 295, 295, 296, 296, 297, 298, 298, 299, 299,
- 301, 302, 300, 303, 303, 304, 304, 305, 305, 306,
- 307, 308
+ 149, 149, 151, 151, 152, 152, 153, 153, 154, 153,
+ 153, 156, 155, 155, 155, 157, 157, 158, 160, 161,
+ 159, 163, 164, 162, 165, 165, 166, 166, 166, 166,
+ 166, 166, 166, 166, 167, 167, 167, 167, 167, 167,
+ 168, 168, 168, 168, 168, 168, 168, 169, 169, 170,
+ 170, 171, 171, 173, 172, 172, 172, 174, 172, 172,
+ 172, 175, 172, 176, 172, 172, 177, 177, 178, 178,
+ 179, 179, 180, 180, 180, 180, 181, 181, 181, 181,
+ 181, 181, 182, 182, 183, 183, 183, 184, 184, 184,
+ 185, 185, 186, 186, 187, 187, 188, 188, 189, 189,
+ 190, 190, 190, 190, 190, 190, 190, 190, 190, 191,
+ 192, 192, 192, 193, 193, 194, 195, 196, 196, 197,
+ 197, 198, 199, 199, 200, 201, 201, 201, 201, 202,
+ 202, 203, 205, 204, 206, 207, 208, 208, 209, 210,
+ 210, 211, 211, 211, 212, 211, 211, 211, 213, 214,
+ 211, 211, 211, 215, 216, 217, 211, 218, 211, 211,
+ 211, 211, 211, 211, 211, 211, 211, 211, 211, 211,
+ 219, 221, 220, 222, 222, 222, 222, 223, 223, 224,
+ 224, 225, 225, 226, 226, 227, 228, 228, 230, 229,
+ 231, 232, 231, 231, 233, 233, 233, 233, 234, 234,
+ 235, 235, 235, 235, 235, 237, 236, 238, 238, 239,
+ 239, 240, 240, 241, 242, 242, 242, 242, 242, 242,
+ 243, 243, 244, 245, 247, 248, 246, 249, 246, 250,
+ 251, 246, 252, 246, 253, 246, 246, 254, 246, 246,
+ 255, 246, 246, 257, 256, 258, 258, 259, 260, 260,
+ 261, 261, 261, 262, 262, 262, 263, 263, 263, 264,
+ 264, 264, 265, 265, 265, 267, 268, 269, 266, 270,
+ 271, 272, 266, 273, 274, 273, 275, 275, 275, 276,
+ 275, 277, 277, 279, 280, 278, 281, 282, 278, 283,
+ 283, 283, 283, 284, 284, 285, 285, 286, 286, 286,
+ 286, 287, 287, 287, 288, 288, 289, 289, 289, 290,
+ 290, 291, 290, 292, 293, 293, 294, 294, 294, 294,
+ 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
+ 295, 295, 295, 295, 295, 295, 295, 295, 295, 295,
+ 295, 296, 296, 296, 296, 297, 297, 298, 298, 299,
+ 300, 300, 301, 301, 303, 304, 302, 305, 305, 306,
+ 306, 307, 307, 308, 309, 310
};
static const short yyr2[] = { 0,
@@ -619,1044 +620,1044 @@ static const short yyr2[] = { 0,
1, 3, 1, 3, 0, 4, 0, 6, 3, 0,
6, 3, 0, 1, 1, 2, 6, 1, 3, 0,
1, 4, 6, 4, 1, 1, 1, 1, 1, 0,
- 4, 1, 0, 2, 1, 3, 1, 0, 4, 1,
- 0, 4, 0, 5, 0, 0, 5, 0, 0, 5,
- 1, 1, 3, 3, 4, 3, 3, 3, 1, 1,
- 3, 4, 3, 3, 3, 1, 3, 3, 3, 4,
- 3, 3, 1, 1, 2, 1, 2, 1, 2, 0,
- 7, 5, 2, 0, 7, 5, 2, 0, 8, 0,
- 7, 2, 0, 1, 0, 1, 1, 2, 0, 3,
- 2, 4, 3, 1, 3, 1, 1, 2, 1, 3,
- 4, 6, 5, 1, 3, 1, 1, 3, 2, 2,
- 0, 1, 1, 2, 0, 2, 3, 3, 2, 3,
- 4, 3, 2, 3, 2, 1, 1, 2, 2, 0,
- 1, 2, 0, 0, 1, 1, 2, 3, 1, 2,
- 1, 2, 6, 5, 5, 2, 2, 4, 0, 4,
- 0, 0, 3, 4, 3, 1, 1, 1, 1, 2,
- 0, 4, 1, 3, 0, 0, 7, 5, 2, 0,
- 0, 0, 12, 0, 6, 2, 2, 2, 3, 6,
- 8, 10, 12, 3, 4, 1, 1, 0, 6, 3,
- 5, 2, 2, 0, 1, 0, 1, 0, 1, 1,
- 3, 4, 1, 3, 0, 2, 2, 0, 4, 2,
- 0, 1, 1, 3, 1, 3, 4, 4, 4, 4,
- 4, 0, 2, 1, 2, 1, 3, 1, 3, 1,
- 1, 1, 1, 1, 1, 1, 1, 3, 3, 4,
- 0, 0, 10, 0, 6, 0, 0, 12, 0, 8,
- 0, 6, 2, 0, 8, 4, 0, 9, 5, 0,
- 6, 0, 1, 3, 3, 1, 1, 1, 1, 0,
- 3, 2, 3, 3, 1, 0, 1, 3, 1, 3,
- 2, 0, 0, 0, 7, 0, 0, 0, 7, 0,
- 0, 2, 1, 1, 2, 0, 3, 1, 1, 0,
- 0, 5, 0, 0, 5, 4, 1, 5, 2, 0,
- 2, 0, 1, 1, 1, 2, 2, 4, 2, 2,
- 1, 3, 2, 2, 2, 0, 2, 0, 3, 1,
- 1, 2, 1, 1, 1, 1, 1, 1, 1, 1,
+ 4, 1, 0, 2, 1, 3, 3, 2, 0, 4,
+ 1, 0, 4, 1, 1, 1, 2, 2, 0, 0,
+ 5, 0, 0, 5, 1, 1, 3, 3, 4, 3,
+ 3, 3, 1, 1, 3, 4, 3, 3, 3, 1,
+ 3, 3, 3, 4, 3, 3, 1, 1, 2, 1,
+ 2, 1, 2, 0, 7, 5, 2, 0, 7, 5,
+ 2, 0, 8, 0, 7, 2, 0, 1, 0, 1,
+ 1, 2, 0, 3, 2, 4, 3, 1, 3, 1,
+ 1, 2, 1, 3, 4, 6, 5, 1, 3, 1,
+ 1, 3, 2, 2, 0, 1, 1, 2, 0, 2,
+ 3, 3, 2, 3, 4, 3, 2, 3, 2, 1,
+ 1, 2, 2, 0, 1, 2, 0, 0, 1, 1,
+ 2, 3, 1, 2, 1, 2, 6, 5, 5, 2,
+ 2, 4, 0, 4, 0, 0, 3, 4, 3, 1,
+ 1, 1, 1, 2, 0, 4, 1, 3, 0, 0,
+ 7, 5, 2, 0, 0, 0, 12, 0, 6, 2,
+ 2, 2, 3, 6, 8, 10, 12, 3, 4, 1,
+ 1, 0, 6, 3, 5, 2, 3, 0, 1, 0,
+ 1, 0, 1, 1, 3, 4, 1, 3, 0, 2,
+ 2, 0, 4, 2, 0, 1, 1, 3, 1, 3,
+ 4, 4, 4, 4, 4, 0, 2, 1, 2, 1,
+ 3, 1, 3, 1, 1, 1, 1, 1, 1, 1,
+ 1, 3, 3, 4, 0, 0, 10, 0, 6, 0,
+ 0, 12, 0, 8, 0, 6, 2, 0, 8, 4,
+ 0, 9, 5, 0, 6, 0, 1, 3, 3, 1,
+ 1, 1, 1, 0, 3, 2, 3, 3, 1, 0,
+ 1, 3, 1, 3, 2, 0, 0, 0, 7, 0,
+ 0, 0, 7, 0, 0, 2, 1, 1, 2, 0,
+ 3, 1, 1, 0, 0, 5, 0, 0, 5, 4,
+ 1, 5, 2, 0, 2, 0, 1, 1, 1, 2,
+ 2, 4, 2, 2, 1, 3, 2, 2, 2, 0,
+ 2, 0, 3, 1, 1, 2, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 6, 3, 5,
- 2, 1, 1, 1, 2, 1, 3, 2, 1, 1,
- 0, 0, 6, 1, 1, 1, 2, 2, 1, 4,
- 4, 4
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 6, 3, 5, 2, 1, 1, 1, 2, 1,
+ 3, 2, 1, 1, 0, 0, 6, 1, 1, 1,
+ 2, 2, 1, 4, 4, 4
};
static const short yydefact[] = { 3,
- 5, 0, 0, 0, 162, 153, 160, 152, 248, 244,
- 246, 0, 0, 0, 410, 0, 462, 466, 0, 0,
- 416, 442, 0, 442, 0, 0, 19, 4, 8, 7,
+ 5, 0, 0, 0, 162, 153, 160, 152, 252, 248,
+ 250, 0, 0, 0, 414, 0, 466, 470, 0, 0,
+ 420, 446, 0, 446, 0, 0, 19, 4, 8, 7,
0, 128, 128, 148, 139, 149, 185, 0, 0, 0,
- 161, 0, 9, 412, 413, 411, 414, 165, 415, 6,
- 17, 18, 249, 245, 247, 0, 0, 0, 32, 33,
- 35, 34, 417, 0, 0, 0, 442, 433, 163, 443,
- 442, 164, 0, 0, 243, 295, 0, 0, 173, 129,
+ 161, 0, 9, 416, 417, 415, 418, 165, 419, 6,
+ 17, 18, 253, 249, 251, 0, 0, 0, 32, 33,
+ 35, 34, 421, 0, 0, 0, 446, 437, 163, 447,
+ 446, 164, 0, 0, 247, 299, 0, 0, 173, 129,
0, 16, 0, 15, 0, 150, 139, 151, 155, 154,
- 137, 186, 269, 253, 269, 257, 260, 262, 11, 89,
+ 137, 186, 273, 257, 273, 261, 264, 266, 11, 89,
90, 107, 59, 60, 0, 0, 0, 36, 38, 37,
- 0, 39, 40, 0, 551, 0, 0, 0, 109, 41,
+ 0, 39, 40, 0, 555, 0, 0, 0, 109, 41,
42, 0, 0, 43, 61, 0, 0, 65, 46, 48,
- 91, 106, 0, 102, 103, 104, 105, 293, 0, 291,
- 158, 0, 291, 190, 444, 0, 513, 514, 536, 537,
- 533, 517, 518, 519, 520, 521, 522, 523, 524, 525,
- 526, 527, 528, 529, 530, 531, 532, 534, 535, 0,
- 0, 515, 463, 487, 506, 510, 516, 511, 467, 0,
- 0, 424, 0, 0, 431, 440, 419, 0, 0, 0,
- 12, 0, 0, 31, 0, 402, 0, 0, 183, 229,
- 295, 0, 230, 0, 171, 129, 0, 221, 222, 0,
+ 91, 106, 0, 102, 103, 104, 105, 297, 0, 295,
+ 158, 0, 295, 190, 448, 0, 517, 518, 540, 541,
+ 537, 521, 522, 523, 524, 525, 526, 527, 528, 529,
+ 530, 531, 532, 533, 534, 535, 536, 538, 539, 0,
+ 0, 519, 467, 491, 510, 514, 520, 515, 471, 0,
+ 0, 428, 0, 0, 435, 444, 423, 0, 0, 0,
+ 12, 0, 0, 31, 0, 406, 0, 0, 183, 233,
+ 299, 0, 234, 0, 171, 129, 0, 225, 226, 0,
0, 138, 141, 168, 169, 140, 142, 170, 0, 0,
- 0, 250, 0, 254, 0, 258, 57, 58, 52, 49,
+ 0, 254, 0, 258, 0, 262, 57, 58, 52, 49,
0, 0, 0, 0, 0, 0, 0, 0, 51, 0,
0, 0, 53, 0, 55, 0, 0, 82, 80, 78,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 100, 101, 0, 0, 44, 0, 108, 110,
- 50, 166, 295, 385, 0, 289, 292, 156, 167, 294,
- 158, 290, 196, 197, 198, 195, 0, 188, 191, 418,
- 0, 541, 0, 490, 508, 489, 0, 512, 0, 490,
- 442, 0, 421, 471, 436, 0, 450, 471, 420, 296,
- 239, 238, 174, 175, 242, 0, 237, 0, 241, 0,
- 0, 29, 0, 331, 116, 332, 182, 184, 0, 0,
- 14, 0, 0, 23, 0, 183, 402, 0, 13, 27,
- 0, 0, 183, 277, 271, 128, 268, 128, 0, 269,
- 183, 269, 286, 287, 265, 284, 0, 93, 92, 321,
- 313, 0, 0, 550, 549, 552, 559, 554, 0, 555,
- 556, 0, 0, 10, 47, 0, 0, 88, 87, 0,
+ 50, 166, 299, 389, 0, 293, 296, 156, 167, 298,
+ 158, 294, 196, 197, 198, 195, 0, 188, 191, 422,
+ 0, 545, 0, 494, 512, 493, 0, 516, 0, 494,
+ 446, 0, 425, 475, 440, 0, 454, 475, 424, 300,
+ 243, 242, 174, 175, 246, 0, 241, 0, 245, 0,
+ 0, 29, 0, 335, 116, 336, 182, 184, 0, 0,
+ 14, 0, 0, 23, 0, 183, 406, 0, 13, 27,
+ 0, 0, 183, 281, 275, 128, 272, 128, 0, 273,
+ 183, 273, 290, 291, 269, 288, 0, 93, 92, 325,
+ 317, 0, 0, 554, 553, 556, 563, 558, 0, 559,
+ 560, 0, 0, 10, 47, 0, 0, 88, 87, 0,
0, 0, 0, 76, 77, 75, 74, 73, 71, 72,
66, 67, 68, 69, 70, 99, 98, 0, 45, 0,
- 299, 0, 303, 0, 305, 0, 385, 0, 159, 157,
- 0, 190, 44, 0, 0, 0, 464, 507, 391, 0,
- 539, 468, 429, 442, 450, 0, 0, 434, 439, 0,
- 0, 0, 0, 0, 406, 392, 128, 128, 404, 0,
- 393, 395, 403, 0, 240, 312, 0, 118, 113, 117,
- 0, 180, 227, 223, 172, 228, 21, 179, 224, 226,
- 0, 25, 0, 252, 331, 270, 331, 278, 0, 256,
- 0, 0, 266, 0, 265, 322, 314, 95, 63, 62,
- 0, 558, 560, 0, 557, 562, 561, 54, 56, 0,
- 0, 81, 79, 96, 97, 298, 297, 386, 304, 300,
- 302, 0, 187, 189, 89, 0, 0, 486, 506, 128,
- 0, 495, 491, 493, 0, 0, 509, 393, 0, 0,
- 426, 471, 437, 0, 425, 480, 483, 474, 0, 128,
- 128, 476, 473, 450, 449, 447, 448, 432, 450, 455,
- 452, 128, 128, 0, 441, 176, 390, 291, 291, 387,
- 388, 0, 405, 0, 0, 30, 319, 114, 128, 128,
- 145, 0, 0, 177, 225, 0, 272, 273, 279, 332,
- 275, 183, 183, 288, 285, 183, 0, 0, 0, 315,
- 316, 0, 0, 542, 0, 543, 544, 83, 86, 301,
- 192, 0, 194, 540, 488, 499, 291, 500, 496, 497,
- 465, 0, 469, 450, 0, 471, 422, 0, 0, 175,
- 0, 0, 0, 475, 0, 0, 456, 456, 451, 236,
- 295, 385, 129, 183, 183, 183, 295, 183, 183, 0,
- 394, 396, 407, 320, 121, 0, 122, 0, 145, 143,
- 202, 200, 199, 181, 22, 0, 26, 331, 0, 251,
- 255, 261, 183, 408, 0, 0, 0, 331, 0, 0,
- 125, 332, 307, 317, 210, 89, 0, 208, 0, 207,
- 0, 263, 205, 546, 548, 0, 553, 0, 545, 0,
- 0, 183, 183, 183, 0, 501, 538, 0, 430, 0,
- 471, 481, 484, 477, 435, 0, 459, 453, 457, 454,
- 299, 0, 402, 0, 397, 398, 399, 299, 400, 401,
- 389, 0, 0, 144, 147, 146, 0, 178, 280, 0,
- 183, 259, 318, 0, 324, 127, 126, 311, 0, 325,
- 309, 332, 308, 0, 0, 0, 211, 64, 0, 204,
- 547, 84, 193, 503, 504, 505, 498, 291, 427, 438,
- 0, 0, 0, 461, 0, 0, 234, 295, 235, 231,
- 233, 0, 119, 120, 0, 183, 0, 281, 409, 323,
- 0, 162, 0, 345, 329, 0, 0, 0, 0, 0,
- 0, 0, 0, 374, 442, 442, 366, 0, 0, 123,
- 128, 128, 338, 343, 0, 0, 335, 336, 339, 367,
- 337, 0, 213, 0, 0, 206, 502, 471, 423, 479,
- 478, 482, 485, 460, 458, 0, 232, 201, 283, 183,
- 0, 0, 331, 376, 0, 0, 372, 356, 357, 358,
- 0, 0, 0, 375, 0, 373, 340, 134, 0, 135,
- 0, 0, 327, 332, 326, 349, 0, 136, 0, 209,
- 212, 0, 282, 0, 0, 0, 377, 48, 0, 0,
- 0, 370, 359, 0, 364, 0, 0, 132, 215, 0,
- 133, 218, 344, 331, 0, 0, 214, 428, 328, 0,
- 330, 368, 350, 354, 0, 365, 0, 130, 0, 131,
- 0, 342, 333, 331, 0, 346, 331, 376, 331, 371,
- 378, 0, 216, 219, 334, 348, 331, 369, 0, 355,
- 0, 0, 379, 380, 360, 0, 0, 347, 351, 0,
- 378, 0, 0, 217, 220, 376, 0, 0, 361, 381,
- 0, 382, 0, 0, 352, 383, 0, 362, 331, 0,
- 0, 353, 363, 384, 0, 0, 0
+ 303, 0, 307, 0, 309, 0, 389, 0, 159, 157,
+ 0, 190, 44, 0, 0, 0, 468, 511, 395, 0,
+ 543, 472, 433, 446, 454, 0, 0, 438, 443, 0,
+ 0, 0, 0, 0, 410, 396, 128, 128, 408, 0,
+ 397, 399, 407, 0, 244, 316, 0, 118, 113, 117,
+ 0, 180, 231, 227, 172, 232, 21, 179, 228, 230,
+ 0, 25, 0, 256, 335, 274, 335, 282, 0, 260,
+ 0, 0, 270, 0, 269, 326, 318, 95, 63, 62,
+ 0, 562, 564, 0, 561, 566, 565, 54, 56, 0,
+ 0, 81, 79, 96, 97, 302, 301, 390, 308, 304,
+ 306, 0, 187, 189, 89, 0, 0, 490, 510, 128,
+ 0, 499, 495, 497, 0, 0, 513, 397, 0, 0,
+ 430, 475, 441, 0, 429, 484, 487, 478, 0, 128,
+ 128, 480, 477, 454, 453, 451, 452, 436, 454, 459,
+ 456, 128, 128, 0, 445, 176, 394, 295, 295, 391,
+ 392, 0, 409, 0, 0, 30, 323, 114, 128, 128,
+ 145, 0, 0, 177, 229, 0, 276, 277, 283, 336,
+ 279, 183, 183, 292, 289, 183, 0, 0, 0, 319,
+ 320, 0, 0, 546, 0, 547, 548, 83, 86, 305,
+ 192, 0, 194, 544, 492, 503, 295, 504, 500, 501,
+ 469, 0, 473, 454, 0, 475, 426, 0, 0, 175,
+ 0, 0, 0, 479, 0, 0, 460, 460, 455, 240,
+ 299, 389, 129, 183, 183, 183, 299, 183, 183, 0,
+ 398, 400, 411, 324, 121, 0, 122, 0, 145, 143,
+ 202, 200, 199, 181, 22, 0, 26, 335, 0, 255,
+ 259, 265, 183, 412, 0, 0, 0, 335, 0, 0,
+ 125, 336, 311, 321, 215, 89, 0, 212, 0, 214,
+ 0, 267, 205, 211, 0, 0, 550, 552, 0, 557,
+ 0, 549, 0, 0, 183, 183, 183, 0, 505, 542,
+ 0, 434, 0, 475, 485, 488, 481, 439, 0, 463,
+ 457, 461, 458, 303, 0, 406, 0, 401, 402, 403,
+ 303, 404, 405, 393, 0, 0, 144, 147, 146, 0,
+ 178, 284, 0, 183, 263, 322, 0, 328, 127, 126,
+ 315, 0, 329, 313, 336, 312, 0, 218, 0, 209,
+ 64, 0, 204, 0, 217, 208, 551, 84, 193, 507,
+ 508, 509, 502, 295, 431, 442, 0, 0, 0, 465,
+ 0, 0, 238, 299, 239, 235, 237, 0, 119, 120,
+ 0, 183, 0, 285, 413, 327, 0, 162, 0, 349,
+ 333, 0, 0, 0, 0, 0, 0, 0, 0, 378,
+ 446, 446, 370, 0, 0, 123, 128, 128, 342, 347,
+ 0, 0, 339, 340, 343, 371, 341, 0, 0, 0,
+ 206, 207, 506, 475, 427, 483, 482, 486, 489, 464,
+ 462, 0, 236, 201, 287, 183, 0, 0, 335, 380,
+ 0, 0, 376, 360, 361, 362, 0, 0, 0, 379,
+ 0, 183, 344, 134, 0, 135, 0, 0, 331, 336,
+ 330, 353, 0, 136, 213, 210, 0, 286, 0, 0,
+ 0, 381, 48, 0, 0, 0, 374, 363, 0, 368,
+ 0, 377, 0, 132, 219, 0, 133, 222, 348, 335,
+ 0, 0, 432, 332, 0, 334, 372, 354, 358, 0,
+ 369, 0, 130, 0, 131, 0, 346, 337, 335, 0,
+ 350, 335, 380, 335, 375, 382, 0, 220, 223, 338,
+ 352, 335, 373, 0, 359, 0, 0, 383, 384, 364,
+ 0, 0, 351, 355, 0, 382, 0, 0, 221, 224,
+ 380, 0, 0, 365, 385, 0, 386, 0, 0, 356,
+ 387, 0, 366, 335, 0, 0, 357, 367, 388, 0,
+ 0, 0
};
-static const short yydefgoto[] = { 945,
+static const short yydefgoto[] = { 950,
1, 2, 3, 28, 29, 30, 335, 563, 341, 566,
198, 447, 669, 122, 232, 398, 124, 125, 126, 127,
- 128, 582, 129, 383, 382, 380, 680, 381, 130, 233,
+ 128, 582, 129, 383, 382, 380, 683, 381, 130, 233,
131, 132, 322, 323, 324, 558, 657, 658, 31, 193,
- 790, 437, 91, 559, 640, 438, 34, 140, 278, 35,
+ 796, 437, 91, 559, 640, 438, 34, 140, 278, 35,
216, 204, 78, 199, 205, 646, 79, 562, 327, 328,
- 37, 287, 288, 289, 644, 717, 671, 672, 673, 736,
- 805, 849, 868, 889, 916, 871, 891, 917, 314, 208,
- 682, 209, 38, 39, 40, 41, 350, 352, 357, 225,
- 740, 474, 220, 221, 347, 568, 569, 355, 356, 142,
- 684, 143, 189, 277, 659, 660, 729, 325, 477, 579,
- 580, 581, 556, 361, 557, 794, 795, 796, 823, 844,
- 451, 845, 663, 797, 798, 874, 822, 907, 898, 926,
- 939, 899, 799, 800, 897, 801, 835, 859, 912, 913,
- 914, 937, 403, 404, 439, 630, 440, 441, 442, 317,
- 318, 443, 444, 655, 133, 43, 64, 44, 45, 46,
- 425, 691, 304, 604, 808, 522, 307, 534, 606, 47,
- 308, 69, 48, 430, 539, 431, 544, 698, 699, 49,
- 65, 294, 516, 66, 300, 520, 426, 427, 532, 613,
- 812, 533, 608, 752, 609, 753, 173, 417, 513, 514,
- 515, 685, 686, 296, 419, 174, 175, 176, 177, 178,
- 585, 586, 675, 587, 366, 134, 235, 481, 369, 370,
- 371, 135, 136, 137
+ 37, 287, 288, 289, 644, 720, 671, 672, 673, 810,
+ 674, 739, 675, 676, 874, 894, 921, 877, 896, 922,
+ 314, 208, 685, 209, 38, 39, 40, 41, 350, 352,
+ 357, 225, 743, 474, 220, 221, 347, 568, 569, 355,
+ 356, 142, 687, 143, 189, 277, 659, 660, 732, 325,
+ 477, 579, 580, 581, 556, 361, 557, 800, 801, 802,
+ 829, 850, 451, 851, 663, 803, 804, 880, 828, 912,
+ 903, 931, 944, 904, 805, 806, 902, 807, 841, 864,
+ 917, 918, 919, 942, 403, 404, 439, 630, 440, 441,
+ 442, 317, 318, 443, 444, 655, 133, 43, 64, 44,
+ 45, 46, 425, 694, 304, 604, 814, 522, 307, 534,
+ 606, 47, 308, 69, 48, 430, 539, 431, 544, 701,
+ 702, 49, 65, 294, 516, 66, 300, 520, 426, 427,
+ 532, 613, 818, 533, 608, 758, 609, 759, 173, 417,
+ 513, 514, 515, 688, 689, 296, 419, 174, 175, 176,
+ 177, 178, 585, 586, 678, 587, 366, 134, 235, 481,
+ 369, 370, 371, 135, 136, 137
};
-static const short yypact[] = { 146,
- 163, 3062, 3062, 133,-32768,-32768,-32768,-32768, 205, 205,
- 205, 182, 209, 215,-32768, 282,-32768,-32768, 282, 282,
--32768, 235, 282, 235, 282, 282,-32768,-32768,-32768,-32768,
- 77, 206, 2542, 195,-32768, 205,-32768, 95, 125, 150,
--32768, 3062,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
--32768,-32768, 205, 205, 205, 2771, 2609, 246,-32768,-32768,
--32768,-32768,-32768, 105, 3331, 3331, 211, 49,-32768,-32768,
- 235,-32768, 23, 282,-32768,-32768, 77, 25,-32768, 205,
- 1765,-32768, 464,-32768, 77, 195,-32768, 205,-32768,-32768,
- 593,-32768, 248, 247, 248, 265,-32768, 274,-32768,-32768,
--32768,-32768,-32768,-32768, 2771, 2771, 282,-32768,-32768,-32768,
- 2771,-32768,-32768, 1370,-32768, 257, 279, 307,-32768,-32768,
--32768, 2771, 301, 302,-32768, 2825, 2879,-32768, 3643, 773,
- 371, 336, 2771,-32768,-32768,-32768,-32768,-32768, 362, 322,
--32768, 387, 3451, 259,-32768, 282,-32768,-32768,-32768,-32768,
+static const short yypact[] = { 171,
+ 186, 3077, 3077, 193,-32768,-32768,-32768,-32768, 172, 172,
+ 172, 145, 174, 199,-32768, 85,-32768,-32768, 85, 85,
+-32768, 249, 85, 249, 85, 85,-32768,-32768,-32768,-32768,
+ 363, 242, 2557, 237,-32768, 172,-32768, 94, 117, 256,
+-32768, 3077,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
+-32768,-32768, 172, 172, 172, 2786, 2624, 266,-32768,-32768,
+-32768,-32768,-32768, 143, 3367, 3367, 72, 54,-32768,-32768,
+ 249,-32768, 42, 85,-32768,-32768, 363, 48,-32768, 172,
+ 1802,-32768, 283,-32768, 363, 237,-32768, 172,-32768,-32768,
+ 859,-32768, 243, 265, 243, 279,-32768, 289,-32768,-32768,
+-32768,-32768,-32768,-32768, 2786, 2786, 85,-32768,-32768,-32768,
+ 2786,-32768,-32768, 1407,-32768, 268, 315, 337,-32768,-32768,
+-32768, 2786, 326, 323,-32768, 2840, 2894,-32768, 3634, 1152,
+ 412, 364, 2786,-32768,-32768,-32768,-32768,-32768, 365, 445,
+-32768, 368, 635, 139,-32768, 85,-32768,-32768,-32768,-32768,
-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
--32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, 225,
- 837,-32768,-32768,-32768, 2503, 409,-32768,-32768,-32768, 282,
- 282, 391, 282, 282,-32768,-32768,-32768, 388, 292, 144,
--32768, 464, 77,-32768, 416,-32768, 1972, 1176, 205,-32768,
--32768, 464,-32768, 39,-32768, 205, 1863, 234, 299, 263,
- 1784, 593,-32768,-32768,-32768,-32768, 205,-32768, 426, 419,
- 1696,-32768, 437,-32768, 239,-32768,-32768,-32768,-32768,-32768,
- 449, 469, 465, 477, 2663, 3359, 837, 282,-32768, 450,
- 2771, 1370,-32768, 1370,-32768, 2771, 2771, 518,-32768,-32768,
- 2771, 2771, 2771, 2771, 2771, 2771, 2771, 2771, 2771, 2771,
- 2771, 2771,-32768,-32768, 282, 282, 2771, 2771,-32768,-32768,
--32768,-32768,-32768, 322, 2031,-32768, 337, 670,-32768,-32768,
--32768,-32768,-32768,-32768,-32768,-32768, 157,-32768, 498,-32768,
- 837,-32768, 484, 485, 554,-32768, 409,-32768, 256, 485,
- 235, 493,-32768, 509, 491, 502,-32768, 509,-32768,-32768,
- 299,-32768,-32768, 558, 299, 582,-32768, 3215,-32768, 511,
- 515,-32768, 879, 84,-32768,-32768, 561, 205, 372, 155,
--32768, 464, 464,-32768, 1176, 205,-32768, 2090,-32768,-32768,
- 1176, 534, 205,-32768,-32768, 326, 525, 1910, 717, 248,
- 205, 248,-32768, 572, 529,-32768, 239,-32768,-32768,-32768,
- 536, 552, 2423,-32768,-32768,-32768,-32768, 595, 560, 3359,
--32768, 564, 570,-32768, 3643, 577, 580, 3643, 3643, 2771,
- 620, 2771, 2771, 1580, 959, 1151, 1757, 1854, 658, 658,
- 489, 489,-32768,-32768,-32768,-32768,-32768, 583, 302, 584,
- 177, 213,-32768, 3234,-32768, 588,-32768, 2149,-32768, 670,
- 587, 259, 2933, 590, 3395, 1882,-32768,-32768, 3464, 837,
--32768,-32768, 578, 235,-32768, 611, 3137,-32768,-32768, 421,
- 3010, 624, 75, 612,-32768,-32768,-32768, 3521,-32768, 626,
- 360,-32768,-32768, 254,-32768,-32768, 92,-32768,-32768,-32768,
- 3533,-32768, 234,-32768,-32768, 234,-32768, 668,-32768,-32768,
- 628,-32768, 638,-32768,-32768,-32768,-32768,-32768, 647,-32768,
- 650, 2771, 282, 654, 529,-32768, 703,-32768,-32768,-32768,
- 3423,-32768,-32768, 595,-32768,-32768,-32768,-32768,-32768, 698,
- 2771, 1345, 1501,-32768,-32768, 337,-32768,-32768,-32768,-32768,
--32768, 655,-32768,-32768, 287, 663, 282,-32768, 2503, 665,
- 3245,-32768,-32768, 3521, 1946, 92,-32768, 662, 671, 92,
--32768, 509,-32768, 543,-32768,-32768,-32768,-32768, 77, 206,
- 2542, 228,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
--32768,-32768, 3546, 667,-32768,-32768,-32768, 592, 357,-32768,
--32768, 3476,-32768, 743, 465,-32768,-32768,-32768, 672, 833,
--32768, 1685, 92,-32768,-32768, 92,-32768, 674,-32768,-32768,
- 674, 205, 205, 3643,-32768, 205, 673, 282, 1011, 703,
--32768, 1450, 2771, 715, 675, 3423,-32768,-32768, 1423,-32768,
--32768, 2771,-32768,-32768,-32768,-32768, 592,-32768,-32768,-32768,
--32768, 282,-32768,-32768, 693, 509,-32768, 3331, 3331, 62,
- 464, 77, 3165,-32768, 549, 3028, 405, 405,-32768,-32768,
--32768, 357, 205, 260, 273, 205,-32768, 273, 205, 3234,
--32768,-32768,-32768,-32768,-32768, 464,-32768, 77,-32768, 625,
--32768,-32768, 3643,-32768,-32768, 1685,-32768,-32768, 446,-32768,
--32768,-32768, 205,-32768, 411, 348, 914, 679, 682, 1091,
--32768,-32768,-32768,-32768,-32768, 723, 282,-32768, 725, 3643,
- 686, 689,-32768, 302,-32768, 2771,-32768, 715,-32768, 2771,
- 318, 260, 273, 205, 427,-32768,-32768, 556,-32768, 704,
- 509,-32768,-32768,-32768,-32768, 2771, 737, 697,-32768, 697,
- 499, 410,-32768, 2208,-32768,-32768,-32768, 747,-32768,-32768,
--32768, 435, 445, 625,-32768,-32768, 1450,-32768,-32768, 2771,
- 73,-32768,-32768, 282,-32768,-32768,-32768,-32768, 701,-32768,
--32768,-32768,-32768, 2289, 745, 1450,-32768,-32768, 1530,-32768,
--32768, 1423,-32768,-32768,-32768,-32768,-32768, 592,-32768,-32768,
- 719, 65, 65, 3643, 2771, 405, 398,-32768, 398,-32768,
--32768, 700,-32768,-32768, 712, 3607, 2771,-32768,-32768,-32768,
- 2369, 754, 734,-32768,-32768, 736, 739, 2771, 758, 724,
- 726, 2717, 109, 793, 178, 289,-32768, 764, 727,-32768,
- 731, 3264,-32768, 795, 1207, 89,-32768,-32768,-32768,-32768,
--32768, 2531,-32768, 735, 1610,-32768,-32768, 509,-32768,-32768,
--32768,-32768,-32768, 3643,-32768, 822,-32768,-32768,-32768, 3607,
- 2771, 755,-32768, 2771, 2771, 3584,-32768,-32768,-32768,-32768,
- 738, 2771, 740,-32768, 757,-32768,-32768,-32768, 464,-32768,
- 77, 1290,-32768,-32768,-32768,-32768, 2771,-32768, 1610,-32768,
--32768, 760,-32768, 742, 2771, 838,-32768, 799, 783, 786,
- 2771,-32768,-32768, 789,-32768, 2771, 451,-32768, 221, 456,
--32768, 471,-32768,-32768, 2369, 791,-32768,-32768,-32768, 792,
--32768,-32768,-32768,-32768, 3625,-32768, 54,-32768, 1176,-32768,
- 1176,-32768,-32768,-32768, 797,-32768,-32768, 2771,-32768,-32768,
- 860, 800,-32768,-32768,-32768,-32768,-32768,-32768, 802,-32768,
- 817, 80, 806,-32768,-32768, 465, 465,-32768,-32768, 2771,
- 860, 811, 860,-32768,-32768, 2771, 814, 81,-32768,-32768,
- 818,-32768, 582, 820,-32768, 371, 334,-32768,-32768, 821,
- 582,-32768,-32768, 371, 895, 899,-32768
+-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, 434,
+ 716,-32768,-32768,-32768, 2518, 409,-32768,-32768,-32768, 85,
+ 85, 386, 85, 85,-32768,-32768,-32768, 375, 286, 149,
+-32768, 283, 363,-32768, 414,-32768, 1987, 1947, 172,-32768,
+-32768, 283,-32768, 115,-32768, 172, 1900, 224, 370, 159,
+ 1821, 859,-32768,-32768,-32768,-32768, 172,-32768, 425, 408,
+ 1733,-32768, 411,-32768, 123,-32768,-32768,-32768,-32768,-32768,
+ 418, 421, 417, 469, 2678, 3395, 716, 85,-32768, 433,
+ 2786, 1407,-32768, 1407,-32768, 2786, 2786, 482,-32768,-32768,
+ 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786,
+ 2786, 2786,-32768,-32768, 85, 85, 2786, 2786,-32768,-32768,
+-32768,-32768,-32768, 445, 2046,-32768, 419, 898,-32768,-32768,
+-32768,-32768,-32768,-32768,-32768,-32768, 147,-32768, 489,-32768,
+ 716,-32768, 479, 484, 556,-32768, 409,-32768, 477, 484,
+ 249, 492,-32768, 514, 497, 508,-32768, 514,-32768,-32768,
+ 370,-32768,-32768, 561, 370, 581,-32768, 878,-32768, 509,
+ 523,-32768, 378, 101,-32768,-32768, 568, 172, 262, 239,
+-32768, 283, 283,-32768, 1947, 172,-32768, 2105,-32768,-32768,
+ 1947, 541, 172,-32768,-32768, 535, 529, 463, 3305, 243,
+ 172, 243,-32768, 579, 537,-32768, 123,-32768,-32768,-32768,
+ 544, 558, 2438,-32768,-32768,-32768,-32768, 594, 564, 3395,
+-32768, 569, 574,-32768, 3634, 588, 592, 3634, 3634, 2786,
+ 617, 2786, 2786, 1617, 1959, 2595, 1794, 1891, 522, 522,
+ 602, 602,-32768,-32768,-32768,-32768,-32768, 593, 323, 554,
+ 272, 299,-32768, 3208,-32768, 589,-32768, 2164,-32768, 898,
+ 603, 139, 2948, 610, 3431, 670,-32768,-32768, 3488, 716,
+-32768,-32768, 596, 249,-32768, 624, 3152,-32768,-32768, 525,
+ 3025, 634, 74, 627,-32768,-32768,-32768, 3534,-32768, 628,
+ 258,-32768,-32768, 197,-32768,-32768, 86,-32768,-32768,-32768,
+ 3530,-32768, 224,-32768,-32768, 224,-32768, 663,-32768,-32768,
+ 622,-32768, 638,-32768,-32768,-32768,-32768,-32768, 632,-32768,
+ 633, 2786, 85, 646, 537,-32768, 693,-32768,-32768,-32768,
+ 3459,-32768,-32768, 594,-32768,-32768,-32768,-32768,-32768, 689,
+ 2786, 1382, 1538,-32768,-32768, 419,-32768,-32768,-32768,-32768,
+-32768, 648,-32768,-32768, 225, 657, 85,-32768, 2518, 666,
+ 3228,-32768,-32768, 3534, 1919, 86,-32768, 654, 664, 86,
+-32768, 514,-32768, 623,-32768,-32768,-32768,-32768, 363, 242,
+ 2557, 362,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
+-32768,-32768, 3564, 672,-32768,-32768,-32768, 539, 551,-32768,
+-32768, 3500,-32768, 747, 417,-32768,-32768,-32768, 676, 3285,
+-32768, 1647, 86,-32768,-32768, 86,-32768, 675,-32768,-32768,
+ 675, 172, 172, 3634,-32768, 172, 687, 85, 1083, 693,
+-32768, 1487, 2786, 731, 694, 3459,-32768,-32768, 1460,-32768,
+-32768, 2786,-32768,-32768,-32768,-32768, 539,-32768,-32768,-32768,
+-32768, 85,-32768,-32768, 709, 514,-32768, 3367, 3367, 327,
+ 283, 363, 3180,-32768, 690, 3043, 213, 213,-32768,-32768,
+-32768, 551, 172, 290, 340, 172,-32768, 340, 172, 3208,
+-32768,-32768,-32768,-32768,-32768, 283,-32768, 363,-32768, 402,
+-32768,-32768, 3634,-32768,-32768, 1647,-32768,-32768, 452,-32768,
+-32768,-32768, 172,-32768, 296, 550, 1003, 695, 698, 913,
+-32768,-32768,-32768,-32768,-32768, 741, 85,-32768, 746, 3634,
+ 707, 705,-32768,-32768, 70, 1240, 323,-32768, 2786,-32768,
+ 731,-32768, 2786, 275, 290, 340, 172, 406,-32768,-32768,
+ 825,-32768, 726, 514,-32768,-32768,-32768,-32768, 2786, 753,
+ 714,-32768, 714, 658, 245,-32768, 2223,-32768,-32768,-32768,
+ 231,-32768,-32768,-32768, 435, 444, 402,-32768,-32768, 1487,
+-32768,-32768, 2786, 78,-32768,-32768, 85,-32768,-32768,-32768,
+-32768, 722,-32768,-32768,-32768,-32768, 2304,-32768, 1487,-32768,
+-32768, 1567,-32768, 1722,-32768,-32768,-32768, 1460,-32768,-32768,
+-32768,-32768,-32768, 539,-32768,-32768, 736, 100, 100, 3634,
+ 2786, 213, 599,-32768, 599,-32768,-32768, 720,-32768,-32768,
+ 727, 3598, 2786,-32768,-32768,-32768, 2384, 770, 752,-32768,
+-32768, 758, 761, 2786, 783, 745, 750, 2732, 293, 817,
+ 69, 113,-32768, 793, 771,-32768, 773, 3257,-32768, 835,
+ 1165, 89,-32768,-32768,-32768,-32768,-32768, 2546, 774, 1722,
+-32768,-32768,-32768, 514,-32768,-32768,-32768,-32768,-32768, 3634,
+-32768, 760,-32768,-32768,-32768, 3598, 2786, 795,-32768, 2786,
+ 2786, 3575,-32768,-32768,-32768,-32768, 781, 2786, 786,-32768,
+ 808, 172,-32768,-32768, 283,-32768, 363, 1327,-32768,-32768,
+-32768,-32768, 2786,-32768,-32768,-32768, 805,-32768, 798, 2786,
+ 860,-32768, 802, 799, 804, 2786,-32768,-32768, 809,-32768,
+ 2786,-32768, 446,-32768, 436, 451,-32768, 721,-32768,-32768,
+ 2384, 811,-32768,-32768, 820,-32768,-32768,-32768,-32768, 3616,
+-32768, 77,-32768, 1947,-32768, 1947,-32768,-32768,-32768, 823,
+-32768,-32768, 2786,-32768,-32768, 900, 830,-32768,-32768,-32768,
+-32768,-32768,-32768, 836,-32768, 856, 84, 837,-32768,-32768,
+ 417, 417,-32768,-32768, 2786, 900, 842, 900,-32768,-32768,
+ 2786, 844, 109,-32768,-32768, 849,-32768, 581, 850,-32768,
+ 412, 313,-32768,-32768, 852, 581,-32768,-32768, 412, 941,
+ 943,-32768
};
static const short yypgoto[] = {-32768,
--32768,-32768,-32768, 98, -363,-32768,-32768,-32768,-32768,-32768,
--32768,-32768, -12,-32768, -56, 488, -230, 383,-32768,-32768,
- -75,-32768, 439,-32768,-32768,-32768,-32768,-32768, 78,-32768,
- -272,-32768, -312, 579,-32768,-32768, 250,-32768, 44, -181,
- 110, 3, 819,-32768, 275, 7, -18, -162, 632, 104,
- -228, -581, -68, -204, -123,-32768,-32768,-32768, -255, 32,
- 90,-32768, 504,-32768, 303,-32768, -612,-32768, -653,-32768,
--32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, -67, -134,
- -508, -29,-32768,-32768,-32768, -73,-32768,-32768,-32768,-32768,
--32768, 475, -38,-32768, 603, 486, 308, 598, 487, -36,
- -70, -160, -182, -221, 300,-32768,-32768, -269,-32768,-32768,
--32768, 385, -177,-32768, -200,-32768,-32768,-32768,-32768, -186,
- -487, -709, 306,-32768, 96,-32768,-32768,-32768,-32768,-32768,
--32768,-32768,-32768,-32768,-32768, 97,-32768, -801, 46,-32768,
- 47,-32768, 568,-32768, -352,-32768, 557, 563, 425, -298,
--32768,-32768,-32768,-32768, 18,-32768, 954,-32768,-32768,-32768,
+-32768,-32768,-32768, 97, -345,-32768,-32768,-32768,-32768,-32768,
+-32768,-32768, -11,-32768, -56, 536, -220, 540,-32768,-32768,
+ -54,-32768, 582,-32768,-32768,-32768,-32768,-32768, 118,-32768,
+ -303,-32768, -263, 631,-32768,-32768, 294,-32768, 16, -166,
+ 158, 1, 864,-32768, 318, 4, -2, -184, 688, 20,
+ -243, -571, -60, -205, -125,-32768,-32768,-32768, 273, 8,
+ 50,-32768, 559,-32768, 324,-32768, -602,-32768, 232,-32768,
+ -595,-32768,-32768, 300,-32768,-32768,-32768,-32768,-32768,-32768,
+ -53, -107, -474, -15,-32768,-32768,-32768, -57,-32768,-32768,
+-32768,-32768,-32768, 501, -50,-32768, 629, 515, 333, 626,
+ 513, -39, -84, -155, -179, -219, 329,-32768,-32768, -262,
+-32768,-32768,-32768, 416, -13,-32768, -175,-32768,-32768,-32768,
+-32768, -160, -506, -667, 334,-32768, 108,-32768,-32768,-32768,
+-32768,-32768,-32768,-32768,-32768,-32768,-32768, 119,-32768, -791,
+ 73,-32768, 75,-32768, 591,-32768, -350,-32768, 583, 586,
+ 449, -301,-32768,-32768,-32768,-32768, 18,-32768, 988,-32768,
-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
--32768, 8, 0, -343,-32768, 444,-32768, 366, 231,-32768,
--32768,-32768,-32768,-32768,-32768,-32768, -270,-32768,-32768,-32768,
- 237, 463,-32768,-32768,-32768,-32768, -20, 688,-32768,-32768,
- 483,-32768, 251, 537,-32768, 585, 633, -103,-32768, -124,
--32768,-32768, 351, 412,-32768,-32768,-32768,-32768,-32768,-32768,
- 643,-32768,-32768,-32768
+-32768,-32768,-32768, 9, 2, -354,-32768, 480,-32768, 420,
+ 277,-32768,-32768,-32768,-32768,-32768,-32768,-32768, -276,-32768,
+-32768,-32768, 276, 510,-32768,-32768,-32768,-32768, -22, 740,
+-32768,-32768, 527,-32768, 295, 538,-32768, 640, 641, -152,
+-32768, -133,-32768,-32768, 371, 458,-32768,-32768,-32768,-32768,
+-32768,-32768, 691,-32768,-32768,-32768
};
-#define YYLAST 3695
+#define YYLAST 3686
static const short yytable[] = { 123,
- 139, 81, 336, 63, 32, 32, 67, 68, 33, 33,
- 71, 326, 63, 74, 86, 207, 210, 218, 329, 42,
- 42, 70, 457, 70, 333, 94, 96, 98, 462, 227,
- 228, 72, 362, 36, 36, 230, 399, 432, 459, 624,
- 53, 54, 55, 433, 32, 179, 239, 190, 33, 409,
- 298, 498, 402, 448, 712, 211, 223, 271, 346, 42,
- 348, 188, 80, 528, 88, 810, 70, 330, 313, 276,
- 70, 297, 282, 36, 182, 83, 85, 234, 186, 75,
- 458, 524, 649, 269, -112, 806, 183, 464, 195, 846,
- 401, 901, 555, 449, 229, 470, 909, 59, 60, 187,
- 50, 191, 14, 146, 765, 192, 14, 184, 80, 336,
- 767, 59, 60, 856, 206, 331, 80, 921, 933, 332,
- 196, 197, 217, 804, 931, 92, 76, 59, 60, 902,
- 185, 286, 368, 290, 293, 77, 87, 326, 218, 99,
- 320, 811, 92, 92, 92, -1, 512, 847, 326, 145,
- 546, 851, 59, 60, 326, 922, 934, 292, 832, 311,
- 141, 61, -2, 315, 892, -112, 62, 301, 302, 92,
- 305, 306, 190, 360, 734, 61, 93, 92, 365, 496,
- 62, 409, 399, 310, 905, 146, 346, 908, 348, 910,
- 615, 61, 757, 759, 453, 877, 62, 918, 456, 89,
- 372, 90, 196, 197, 218, 376, 95, 377, 455, 51,
- 52, 400, 354, 337, 338, -35, 61, 141, 406, 312,
- 80, 62, 16, 206, 80, 373, 273, 59, 60, 942,
- 454, 97, 411, 206, 14, 274, 275, 412, 349, 353,
- 56, 59, 60, 217, 771, 600, 281, 195, 180, 694,
- -175, 605, 396, 397, 414, 16, -175, 867, 59, 60,
- 688, 59, 60, 283, 284, 285, 484, 57, 542, 181,
- 543, 407, 408, 58, 141, 526, 527, 711, 570, 16,
- 570, 461, 82, 291, 59, 60, 421, 480, 497, 14,
- -472, 61, 337, 338, 75, 92, 62, -175, 310, 311,
- 70, -175, 14, 315, 144, 61, 92, 757, 423, 661,
- 62, 469, 219, 471, 420, 236, 650, 651, 703, 704,
- 652, 14, 61, 490, 141, 61, -34, 62, 222, 553,
- 62, 196, 197, 16, 554, 690, 218, 237, 601, 339,
- 141, 76, 603, 192, 354, 141, 224, 141, 61, 36,
- 77, 502, 674, 62, 634, 226, 875, 196, 197, 75,
- 206, 681, 591, 206, 206, 238, 349, 592, 705, 706,
- 707, 273, 709, 710, 75, 200, 240, 584, 310, 269,
- 274, 275, 241, 519, 298, 645, 14, 726, 647, 465,
- 731, 467, 662, 743, 141, 407, 408, 722, 241, 286,
- 402, 14, -274, -274, 760, 297, 627, 75, 200, 940,
- 270, 716, 75, 620, 941, 622, 275, 92, 510, 86,
- 751, 201, 511, 70, 446, 725, 744, 745, 746, 530,
- 202, 523, 560, 531, 14, 36, 551, 272, 701, 14,
- 552, 702, 696, 203, 708, 674, 299, 36, 75, 200,
- 36, 281, 141, 542, 201, 543, 703, 704, 36, 758,
- 354, 570, 279, 202, 309, 768, 75, 200, 77, 88,
- 529, 662, 303, 732, 316, 14, 203, 626, 629, 496,
- 548, 549, 678, 720, 342, 716, 496, 723, 535, 536,
- 537, 724, 86, 14, 594, 201, 343, 195, 538, 610,
- -175, 75, 620, 747, 202, 310, -175, 748, 243, 245,
- 819, 763, 86, 201, 351, 332, 510, 203, 625, 628,
- 511, 764, 202, 141, 358, 192, 374, 888, 14, 196,
- 197, 332, 890, 793, 141, 203, 192, 852, 260, 261,
- 262, 87, 88, 210, 359, 36, 360, -175, 621, 697,
- 697, -175, 363, 597, 561, -85, 413, 622, 275, 415,
- 80, 416, 88, 418, 853, 654, 218, 683, 424, 713,
- 793, -470, 428, 611, 612, 816, 903, 429, 904, 623,
- 80, 721, 610, 36, 195, 617, 618, 692, 693, 687,
- 102, 446, 190, 445, 75, 620, 452, 213, 214, 215,
- 463, 466, 636, 638, 9, 10, 11, 472, 610, 473,
- 535, 536, 537, 476, 87, 530, 535, 536, 537, 531,
- 607, 14, 14, 535, 536, 537, 695, 478, 623, 715,
- 214, 215, 482, 749, 87, 483, 9, 10, 11, 486,
- 218, 621, 206, 80, 36, 487, 281, 762, 206, 206,
- 622, 275, 488, 80, 735, 489, 529, 491, 494, 521,
- 936, 36, 503, 639, 336, 507, 495, 206, 944, 80,
- 499, 311, 315, 525, 793, 214, 215, 789, 311, 375,
- 206, 9, 10, 11, 378, 379, 545, 547, 697, 384,
- 385, 386, 387, 388, 389, 390, 391, 392, 393, 394,
- 395, 550, 326, 564, 326, 258, 259, 260, 261, 262,
- 565, 769, 92, 567, 789, 924, 925, 344, 683, 141,
- 5, 788, 7, 138, 572, 831, 271, 573, 9, 10,
- 11, 576, 623, 623, 578, 588, 791, 590, 593, 80,
- 792, 596, 552, 619, 13, 633, 602, 15, 635, 75,
- 653, 802, 676, 310, 648, 689, -310, 677, 788, 730,
- -32, 16, 737, 738, 854, 36, 750, 857, 860, 739,
- 833, 869, 870, 86, 755, 864, 14, 756, 770, 623,
- 803, 809, 817, 22, 70, 70, 311, 206, 24, 818,
- 876, -33, 821, 72, 824, 827, 627, 825, 880, 834,
- 828, 836, 829, 837, 791, 622, 275, 838, 792, 887,
- 842, 872, 850, 855, 863, 866, 865, 879, 789, 802,
- 492, 493, 878, 88, 75, 620, 263, 264, 310, 265,
- 266, 267, 268, 36, 839, 841, 5, 89, 7, 90,
- 5, 857, 7, 138, 9, 10, 11, 623, 9, 10,
- 11, 14, 263, 264, 881, 265, 266, 267, 268, 883,
- 13, 884, 788, 927, 13, 886, 895, 896, 911, 857,
- 206, 758, 80, 906, 882, 920, 915, 16, 919, 321,
- 77, 16, -115, -115, -115, -115, 923, 929, -115, 932,
- -115, -115, -115, 935, 946, 87, 938, 943, 947, 22,
- 506, 858, 450, 22, 24, 212, -115, 727, 24, 637,
- 574, 848, 410, 714, 321, 504, -124, -124, -124, -124,
- -124, -124, -124, -115, -124, -124, -124, -124, -124, 589,
+ 139, 336, 32, 32, 63, 33, 33, 67, 68, 36,
+ 36, 71, 433, 63, 74, 81, 53, 54, 55, 42,
+ 42, 329, 297, 70, 210, 70, 94, 96, 98, 207,
+ 86, 432, 72, 218, 409, 459, 346, 326, 80, 333,
+ 88, 298, 32, 179, 223, 33, 399, 83, 85, 36,
+ 227, 228, 87, 498, 402, 276, 230, 362, 282, 42,
+ 448, 190, 188, 649, 715, 348, 313, 239, 70, 211,
+ 524, 457, 70, 624, 234, 182, 141, 462, 271, 186,
+ 746, 528, 269, 368, 80, 92, 555, 59, 60, 852,
+ 206, 183, 80, 401, 330, 229, 59, 60, 217, 50,
+ 816, -112, 92, 92, 92, 744, -35, 14, 336, 180,
+ 449, 914, 184, 16, 906, 773, 16, 771, 187, 59,
+ 60, 926, 146, 353, 191, 59, 60, 667, 192, 92,
+ 181, 293, 286, 141, 290, 185, 809, 92, 99, 936,
+ 320, 59, 60, 283, 284, 285, 938, 853, 812, 546,
+ -34, 61, 907, 512, 218, 737, 62, 16, 292, 927,
+ 61, 861, 281, 326, 346, 62, 409, 360, 301, 302,
+ -1, 305, 306, 311, 326, 93, 817, 315, 365, 615,
+ 326, 496, -112, 61, 939, -2, 190, 145, 62, 61,
+ 141, 331, 399, 348, 62, 332, 80, 372, 95, 206,
+ 80, 14, 376, 56, 377, 61, 455, 196, 197, 206,
+ 62, 400, 897, 354, 856, 75, 200, 484, 406, 217,
+ 218, 453, 411, 146, 312, 456, 373, 412, 777, 763,
+ 765, 910, 57, 75, 913, 339, 915, 310, 349, 192,
+ 141, 89, 14, 90, 923, 605, 542, 75, 620, 691,
+ 699, 414, 600, 396, 397, 92, 141, 58, 59, 60,
+ 14, 141, 201, 141, 75, 200, 92, 697, 310, 51,
+ 52, 202, 553, 873, 14, 543, 947, 554, 310, 714,
+ 627, 461, 337, 338, 203, 75, 200, 421, 75, 622,
+ 275, 14, 310, 16, 764, 59, 60, 337, 338, 469,
+ 591, 471, 70, 77, 570, 592, 570, 219, 480, 423,
+ 141, 201, 14, 311, 454, 14, 661, 315, 82, 14,
+ 202, 273, 61, 490, 144, 36, 236, 62, 584, 693,
+ 274, 275, 201, 203, 551, 76, 206, 97, 552, 206,
+ 206, 202, 838, 881, 77, 354, 222, 763, 706, 707,
+ 749, 502, 218, 195, 203, 241, 297, 407, 408, 61,
+ 224, 465, 677, 467, 62, 75, 349, 281, 141, 14,
+ 226, 684, 726, 237, 497, 298, 727, 92, 321, 634,
+ 519, -115, -115, -115, -115, 196, 197, -115, 945, -115,
+ -115, -115, 14, 946, 729, 238, 719, 734, 196, 197,
+ 286, 240, 402, 241, 766, -115, 718, 214, 215, 526,
+ 527, 36, 76, 9, 10, 11, 510, 757, 662, 511,
+ 269, 77, -115, 36, -476, 70, 36, 530, 196, 197,
+ 531, 542, 523, 681, 36, 86, 59, 60, 270, 141,
+ 272, 704, 529, 279, -115, 88, 299, 711, 560, -115,
+ 141, 309, 548, 549, 75, 200, 705, 87, 677, -115,
+ 543, 354, 195, 626, 629, -175, 5, 303, 7, 280,
+ 561, -175, 316, 719, 9, 10, 11, 407, 408, 59,
+ 60, 14, 753, 342, 496, 343, 754, 570, 351, 723,
+ 13, 496, 291, 358, 273, 594, 359, 662, 360, 735,
+ 61, 201, 601, 274, 275, 62, 603, 16, 86, 374,
+ 202, 769, -175, 610, 510, 332, -175, 511, 88, -85,
+ 770, 36, 893, 203, 192, 597, 332, 895, 86, 22,
+ 87, 192, 625, 628, 24, 420, 80, 857, 88, -280,
+ -280, 75, 620, 61, 363, 611, 612, 413, 62, 645,
+ 87, 210, 647, 75, 415, 623, 80, 617, 618, 36,
+ 416, 799, 281, 700, 700, 418, 654, 424, 14, 258,
+ 259, 260, 261, 262, 636, 638, -474, 716, 428, 639,
+ 14, 686, 218, 429, 822, 695, 696, 195, 621, 102,
+ 690, 445, 535, 536, 537, 724, 610, 622, 275, 446,
+ 627, 799, 538, 452, 623, 466, 190, 463, 458, 622,
+ 275, -278, -278, 530, 472, 464, 531, 473, 206, 80,
+ 36, 476, 610, 470, 206, 206, 446, 728, 529, 80,
+ 908, 482, 909, 478, 941, 141, 495, 36, 5, 483,
+ 7, 280, 949, 206, 486, 80, 9, 10, 11, 487,
+ 768, 260, 261, 262, 491, 738, 206, 706, 707, 218,
+ 75, 620, 13, 488, 310, 243, 245, 489, 494, 336,
+ 321, 499, 92, 5, 6, 7, 8, 521, 503, 16,
+ 795, 9, 10, 11, 273, 507, 525, 14, 311, 315,
+ 535, 536, 537, 274, 275, 311, 545, 13, 564, 14,
+ 607, 22, 547, 550, 565, 799, 24, 621, 700, 572,
+ 573, 623, 623, 567, 16, 775, 622, 275, 80, 5,
+ 795, 7, 138, 576, 578, 794, 588, 9, 10, 11,
+ 590, 837, 593, 326, 552, 326, 22, 797, 686, 602,
+ 798, 24, 596, 13, 36, 929, 930, 195, 619, 633,
+ -175, -496, 635, 271, 808, 648, -175, 535, 536, 537,
+ 16, 623, 75, 620, 653, 794, 310, 698, 679, 206,
+ 859, 692, -314, 862, 865, 733, 680, 839, -32, 196,
+ 197, 869, 22, 740, 741, 742, 876, 24, 756, 14,
+ 761, 875, 70, 70, 762, 86, 882, -175, 815, 776,
+ 72, -175, 823, 885, 824, 88, 311, -33, 797, 764,
+ 827, 798, 845, 847, 892, 36, 830, 87, 77, 831,
+ 833, 834, 375, 840, 795, 808, 835, 378, 379, 623,
+ 842, 878, 384, 385, 386, 387, 388, 389, 390, 391,
+ 392, 393, 394, 395, 650, 651, 862, 843, 652, 844,
+ 848, 855, 206, 860, 80, 263, 264, 868, 265, 266,
+ 267, 268, 870, 213, 214, 215, 871, 883, 932, 794,
+ 9, 10, 11, 884, 862, 888, 886, 887, 434, 889,
+ 435, 5, 6, 7, 8, 891, 900, 436, 14, 9,
+ 10, 11, 535, 536, 537, 901, 708, 709, 710, 911,
+ 712, 713, 755, 214, 215, 13, 920, 14, 916, 9,
+ 10, 11, 924, 321, 925, -335, -335, 928, 934, 937,
+ -335, -335, 16, -335, 940, 725, 943, -335, 948, -335,
+ -335, -335, -335, -335, -335, -335, -335, -335, -335, -335,
+ 951, -335, 952, -335, 22, -335, -335, 863, 506, 24,
+ 212, 730, -335, -395, 450, -335, 717, 750, 751, 752,
+ -335, -335, -335, 492, 493, 854, -335, -335, 410, 721,
+ 504, -335, -335, 811, 745, 577, -335, 468, -335, -335,
+ 722, 571, 475, -335, -335, 575, 731, -335, 898, -335,
+ -310, -335, -335, 736, -335, 664, 774, 500, 933, 899,
+ 632, 517, 935, 321, 518, -124, -124, -124, -124, -124,
+ -124, -124, 73, -124, -124, -124, -124, -124, 616, -124,
-124, -124, -124, -124, -124, -124, -124, -124, -124, -124,
- -124, -124, -124, -124, -124, -115, -124, -124, 718, 577,
- -115, 468, 571, -124, 475, 719, -124, 728, -124, 575,
- -115, -124, -124, -124, 664, 733, 928, -124, -124, 930,
- 893, 894, -124, -124, 500, 517, 632, -124, 73, -124,
- -124, 518, 616, 700, -124, -124, 815, 422, -124, 813,
- -124, -124, -124, -124, 614, -124, 599, 679, 807, 508,
- 643, 253, 254, 255, 256, 257, 258, 259, 260, 261,
- 262, 656, 485, -331, -331, -331, -331, -331, -331, -331,
- 670, -331, -331, -331, -331, -331, 741, -331, -331, -331,
- -331, -331, -331, -331, -331, -331, -331, -331, -331, -331,
- -331, -331, 0, -331, -331, 595, 0, 509, 0, 0,
- -331, 0, 0, -331, 0, -331, 0, 0, -331, -331,
- -331, 0, 0, 0, -331, -331, 0, 0, 0, -331,
- -331, 0, 0, 0, -331, 0, -331, -331, 0, 0,
- 0, -331, -331, 0, 643, -331, 0, -331, 0, -331,
- -331, 321, -331, -331, -331, 0, 0, 0, -331, -331,
- 0, -331, 0, 0, 0, -331, 0, -331, -331, -331,
- -331, -331, -331, -331, -331, -331, -331, -331, 742, -331,
- 0, -331, 0, -331, -331, 0, 0, 0, 0, 0,
- -331, 0, 0, -331, 754, 0, 0, 0, -331, -331,
- -331, 0, 0, 0, -331, -331, 0, 0, 0, -331,
- -331, 0, 0, 0, -331, 670, -331, -331, 766, 0,
- 0, -331, -331, 0, 0, -331, 0, -331, -306, -331,
- -331, 0, -331, 0, 670, 0, 321, 670, 0, -331,
- -331, -331, -331, 0, 0, 0, 0, -331, -331, -331,
- 0, 0, 0, 814, 254, 255, 256, 257, 258, 259,
- 260, 261, 262, -331, 0, 820, 0, 843, 0, -331,
- -331, 0, 0, 0, -331, -331, 826, -331, 0, 0,
- -331, -331, 0, -331, -331, -331, -331, -331, -331, -331,
- -331, -331, -331, -331, 0, -331, 0, -331, 0, -331,
- -331, 0, -331, 670, 0, 0, -331, -331, 0, -331,
- 0, 0, 0, 0, -331, -331, -331, -111, 0, 0,
- -331, -331, 0, 0, 0, -331, -331, 0, 0, 0,
- -331, 0, -331, -331, 0, 0, 0, -331, -331, 0,
- 0, -331, 0, -331, 0, -331, -331, 670, -331, 0,
- 873, 0, -341, -341, 0, 0, 0, -341, -341, 885,
- -341, 0, 0, 0, -341, 0, -341, -341, -341, -341,
- -341, -341, -341, -341, -341, -341, -341, 0, -341, 0,
- -341, 0, -341, -341, 0, 0, 0, 0, 0, -341,
- 0, 0, -341, 0, 0, 0, 0, -341, -341, -341,
- 0, 0, 0, -341, -341, 0, 0, 0, -341, -341,
- 0, 0, 0, -341, 0, -341, -341, 0, 0, 0,
- -341, -341, 0, 0, -341, 0, -341, 0, -341, -341,
- 231, -341, 100, 5, 0, 7, 138, 101, 102, 0,
- 103, 9, 10, 11, 250, 251, 252, 253, 254, 255,
- 256, 257, 258, 259, 260, 261, 262, 13, 104, 0,
- 15, 0, 105, 106, 0, 0, 0, 0, 0, 107,
- 0, 0, 108, 0, 16, 0, 0, 109, 110, 111,
- 0, 0, 0, 112, 113, 0, 0, 0, 114, 115,
- 0, 0, 0, 116, 0, 117, 22, 0, 0, 0,
- 118, 24, 0, 0, 119, 0, 0, 0, 120, 121,
- 665, -94, 666, 60, 0, 0, 0, 101, 102, 248,
- 103, 249, 250, 251, 252, 253, 254, 255, 256, 257,
- 258, 259, 260, 261, 262, 0, 0, 0, 104, 0,
- 15, 0, 105, 106, 0, 0, 0, 0, 0, 107,
- 0, 0, 108, 0, 0, 0, 0, 109, 110, 111,
- 0, 0, 0, 112, 113, 0, 0, 667, 114, 115,
- 0, 0, 0, 116, 0, 117, 61, 0, 0, 0,
- 118, 62, 0, 0, 119, 0, 0, -203, 120, 121,
- 665, 668, 666, 60, 0, 0, 0, 101, 102, 0,
- 103, 251, 252, 253, 254, 255, 256, 257, 258, 259,
- 260, 261, 262, 0, 0, 0, 0, 0, 104, 0,
- 15, 0, 105, 106, 0, 0, 0, 0, 0, 107,
- 0, 0, 108, 0, 0, 0, 0, 109, 110, 111,
- 0, 0, 0, 112, 113, 0, 0, 667, 114, 115,
- 0, 0, 0, 116, 0, 117, 61, 0, 0, 0,
- 118, 62, 0, 0, 119, 0, 0, -264, 120, 121,
- 665, 668, 666, 60, 0, 0, 0, 101, 102, 0,
- 103, 252, 253, 254, 255, 256, 257, 258, 259, 260,
- 261, 262, 0, 0, 0, 0, 0, 0, 104, 0,
- 15, 0, 105, 106, 0, 0, 0, 0, 0, 107,
- 0, 0, 108, 0, 0, 0, 0, 109, 110, 111,
- 0, 0, 0, 112, 113, 0, 0, 667, 114, 115,
- 0, 0, 0, 116, 0, 117, 61, 0, 0, 0,
- 118, 62, 0, 0, 119, 641, 0, 100, 120, 121,
- 0, 668, 101, 102, 0, 103, 344, 0, 0, 5,
- 0, 7, 138, 0, 0, 0, 0, 9, 10, 11,
- 0, 0, 0, 104, 0, 15, 0, 105, 106, 0,
- 0, 0, 0, 13, 107, 0, 15, 108, 0, 0,
- 0, 0, 109, 110, 111, 0, 0, 0, 112, 113,
- 16, 0, 0, 114, 115, 0, 0, 0, 116, 0,
- 117, 0, 0, 0, 0, 118, 0, 0, 0, 119,
- 0, 0, 22, 120, 121, 194, 642, 24, -28, -28,
- -28, -28, 345, -267, 0, 0, -28, -28, -28, 0,
- 0, 0, 0, 0, 340, 0, 0, -24, -24, -24,
- -24, 195, -28, 0, -175, -24, -24, -24, 0, 0,
- -175, 255, 256, 257, 258, 259, 260, 261, 262, -28,
- 195, -24, 0, -175, 0, 0, 0, 0, 0, -175,
- 0, 0, 0, 196, 197, 0, 0, 0, -24, 0,
- 0, -28, 0, 0, 0, 0, -28, 0, 0, 0,
- 0, -175, 196, 197, 0, -175, -28, 0, 0, 0,
- -24, 0, 0, 0, 0, -24, 0, 0, 0, 0,
- -175, 0, 0, 334, -175, -24, -20, -20, -20, -20,
- 0, 0, 0, 0, -20, -20, -20, 0, 0, 0,
- 0, 0, 321, 0, 0, 5, 6, 7, 8, 195,
- -20, 0, -175, 9, 10, 11, 0, 0, -175, 256,
- 257, 258, 259, 260, 261, 262, 0, -20, 0, 13,
- 0, 14, 0, 5, 0, 7, 280, 0, 0, 0,
- 0, 9, 10, 11, 0, 0, 16, 0, 0, -20,
- 0, 0, 0, 0, -20, 0, 0, 13, 0, -175,
- 0, 0, 0, -175, -20, 0, 321, 0, 22, -494,
- -494, -494, -494, 24, 16, 0, 0, -494, -494, -494,
- 0, 0, 0, -492, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, -494, 100, -494, 22, 0, 0, 101,
- 102, 24, 103, 0, 0, 0, -276, -276, 0, 0,
- -494, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 104, 0, 15, 0, 105, 106, 0, 0, 0, 0,
- 0, 107, -494, 0, 108, 0, 0, -494, 0, 109,
- 110, 111, 0, 0, 0, 112, 113, -494, 0, 0,
- 114, 115, 0, 100, 0, 116, 0, 117, 101, 102,
- 0, 103, 118, 0, 0, 0, 119, 0, 0, 0,
- 120, 121, 0, 0, 319, 0, 0, 0, 0, 104,
- 0, 15, 0, 105, 106, 0, 0, 0, 0, 0,
- 107, 0, 0, 108, 0, 0, 0, 0, 109, 110,
- 111, 0, 0, 0, 112, 113, 0, 0, 0, 114,
- 115, 0, 100, 0, 116, 0, 117, 101, 102, 0,
- 103, 118, 0, 0, 0, 119, 0, 0, 0, 120,
- 121, 0, 0, 405, 0, 0, 0, 0, 104, 0,
- 15, 0, 105, 106, 0, 0, 0, 0, 0, 107,
- 0, 0, 108, 0, 0, 0, 0, 109, 110, 111,
- 0, 0, 0, 112, 113, 0, 0, 0, 114, 115,
- 0, 100, 0, 116, 0, 117, 101, 102, 0, 103,
+ -124, -124, -124, -124, 819, -124, -124, 703, 821, 422,
+ 599, 614, -124, 682, 825, -124, 595, -124, 813, 747,
+ -124, -124, -124, 574, 508, 509, -124, -124, 0, 0,
+ 485, -124, -124, 0, 0, 0, -124, 0, -124, -124,
+ 0, 0, 589, -124, -124, 0, 0, -124, 0, -124,
+ -124, -124, -124, 656, -124, -335, -335, -335, -335, -335,
+ -335, -335, 0, -335, -335, -335, -335, -335, 858, -335,
+ -335, -335, -335, -335, -335, -335, -335, -335, -335, -335,
+ -335, -335, -335, -335, 872, -335, -335, 0, 0, 0,
+ 0, 0, -335, 0, 0, -335, 0, -335, 0, 0,
+ -335, -335, -335, 0, 0, 0, -335, -335, 0, 0,
+ 0, -335, -335, 643, 0, 0, -335, 0, -335, -335,
+ 0, 0, 0, -335, -335, 0, 0, -335, 0, -335,
+ 0, -335, -335, 670, -335, 849, 0, -335, -335, 0,
+ 0, 0, -335, -335, 0, -335, 0, 0, 0, -335,
+ 0, -335, -335, -335, -335, -335, -335, -335, -335, -335,
+ -335, -335, 0, -335, 0, -335, 0, -335, -335, 0,
+ 0, 0, 0, 0, -335, 263, 264, -335, 265, 266,
+ 267, 268, -335, -335, -335, 0, 0, 0, -335, -335,
+ 0, 0, 0, -335, -335, 0, 0, 643, -335, 0,
+ -335, -335, 0, 0, 0, -335, -335, 0, 0, -335,
+ 665, -335, 100, -335, -335, 0, -335, 101, 102, 0,
+ 103, 0, 0, 0, 0, 0, 0, 670, 0, 0,
+ 0, 0, 0, 0, 748, 0, 0, 0, 104, 0,
+ 15, 0, 105, 106, 0, -216, 0, 0, 0, 107,
+ 760, 0, 108, 0, 0, 0, 0, 109, 110, 111,
+ 0, 0, 0, 112, 113, 0, 0, -216, 114, 115,
+ 0, 670, 0, 116, 772, 117, 0, 0, 0, 0,
118, 0, 0, 0, 119, 0, 0, 0, 120, 121,
- 0, 0, 460, 0, 0, 0, 0, 104, 0, 15,
- 0, 105, 106, 0, 0, 0, 0, 0, 107, 0,
- 0, 108, 0, 0, 0, 0, 109, 110, 111, 0,
- 0, 0, 112, 113, 0, 0, 0, 114, 115, 0,
- 100, 0, 116, 0, 117, 101, 102, 0, 103, 118,
- 0, 0, 0, 119, 0, 0, 0, 120, 121, 0,
- 0, 501, 0, 0, 0, 0, 104, 0, 15, 0,
- 105, 106, 0, 0, 0, 0, 0, 107, 0, 0,
- 108, 0, 0, 0, 0, 109, 110, 111, 0, 0,
- 0, 112, 113, 0, 0, 0, 114, 115, 0, 0,
- 0, 116, 0, 117, 0, 0, 0, 0, 118, 0,
- 0, 0, 119, 0, 0, 0, 120, 121, 0, 0,
- 761, 666, 772, 6, 7, 8, 101, 102, 0, 103,
- 9, 10, 11, 773, 0, 774, 775, 776, 777, 778,
- 779, 780, 781, 782, 783, 784, 13, 104, 14, 15,
- 0, 105, 106, 0, 0, 0, 0, 0, 107, 0,
- 0, 108, 0, 16, 0, 0, 109, 110, 111, 0,
- 0, 0, 112, 113, 0, 0, 0, 114, 115, 0,
- 0, 0, 116, 0, 117, 785, 0, 0, 0, 118,
- 786, 0, 0, 119, 0, 787, 0, 120, 121, 0,
- 360, 666, 60, 0, 0, 0, 101, 102, 0, 103,
- 0, 0, 0, 773, 0, 774, 775, 776, 777, 778,
- 779, 780, 781, 782, 783, 784, 0, 104, 0, 15,
- 0, 105, 106, 0, 0, 0, 0, 0, 107, 0,
- 0, 108, 0, 0, 0, 0, 109, 110, 111, 0,
- 0, 0, 112, 113, 0, 100, 0, 114, 115, 0,
- 101, 102, 116, 103, 117, 61, 0, 0, 0, 118,
- 62, 0, 0, 119, 0, 787, 0, 120, 121, 0,
- 360, 104, 0, 15, 0, 105, 106, 0, 0, 0,
- 0, 0, 107, 0, 0, 108, 0, 0, 0, 0,
- 109, 110, 111, 0, 0, 0, 112, 113, 0, 0,
- 0, 114, 115, 0, 0, 0, 116, 0, 117, 0,
- 0, 0, 0, 118, 0, 0, 0, 119, 0, 0,
- 0, 120, 121, 0, 479, 147, 148, 0, 149, 150,
- 0, 0, 0, 151, 152, 153, 154, 155, 156, 157,
- 158, 159, 160, 161, 162, 163, 164, 165, 166, 167,
- 168, 169, 0, 100, 5, 6, 7, 8, 101, 102,
- 170, 103, 9, 10, 11, 5, 6, 7, 8, 0,
- 0, 0, 0, 9, 10, 11, 0, 0, 13, 104,
- 14, 15, 0, 105, 106, 0, 0, 0, 0, 13,
- 107, 14, 0, 108, 172, 16, 0, 0, 109, 110,
- 111, 0, 0, 295, 112, 113, 16, 0, 0, 114,
- 115, 0, 0, 0, 116, 0, 117, 22, 0, 0,
- 0, 118, 24, 0, 0, 119, 0, 0, 22, 120,
- 121, 100, 5, 24, 7, 138, 101, 102, 84, 103,
- 9, 10, 11, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 13, 104, 0, 15,
- 0, 105, 106, 0, 0, 0, 0, 0, 107, 0,
- 0, 108, 0, 16, 0, 0, 109, 110, 111, 0,
- 0, 0, 112, 113, 0, 100, 0, 114, 115, 0,
- 101, 102, 116, 103, 117, 22, 0, 0, 0, 118,
- 24, 0, 0, 119, 0, 0, 0, 120, 121, 0,
- 0, 104, 0, 15, 0, 105, 106, 0, 0, 0,
- 0, 0, 107, 0, 0, 108, 0, 0, 0, 0,
- 109, 110, 111, 0, 0, 0, 112, 113, 0, 100,
- 0, 114, 115, 0, 101, 102, 116, 103, 117, 364,
- 0, 0, 0, 118, 0, 0, 0, 119, 0, 0,
- 0, 120, 121, 0, 0, 104, 0, 15, 0, 105,
+ 670, 668, 0, 670, 0, 670, 0, 879, 0, -345,
+ -345, 0, 0, 0, -345, -345, 0, -345, 0, 0,
+ 0, -345, 820, -345, -345, -345, -345, -345, -345, -345,
+ -345, -345, -345, -345, 826, -345, 0, -345, 0, -345,
+ -345, 0, 0, 0, 0, 832, -345, 0, 0, -345,
+ 0, 0, 0, 0, -345, -345, -345, 0, 0, 0,
+ -345, -345, 0, 0, 0, -345, -345, 0, 0, 0,
+ -345, 670, -345, -345, 0, 0, 0, -345, -345, 0,
+ 0, -345, 0, -345, 0, -345, -345, 231, -345, 100,
+ 5, 0, 7, 138, 101, 102, 0, 103, 9, 10,
+ 11, 250, 251, 252, 253, 254, 255, 256, 257, 258,
+ 259, 260, 261, 262, 13, 104, 0, 15, 0, 105,
+ 106, 0, 0, 0, 0, 0, 107, 890, 0, 108,
+ 0, 16, 0, 0, 109, 110, 111, 0, 0, 0,
+ 112, 113, 0, 0, 0, 114, 115, 0, 0, 0,
+ 116, 0, 117, 22, 0, 0, 0, 118, 24, 0,
+ 0, 119, 0, 0, 0, 120, 121, 665, -94, 666,
+ 60, 0, 0, 0, 101, 102, 248, 103, 249, 250,
+ 251, 252, 253, 254, 255, 256, 257, 258, 259, 260,
+ 261, 262, 0, 0, 0, 104, 0, 15, 0, 105,
+ 106, 0, 0, 0, 0, 0, 107, 0, 0, 108,
+ 0, 0, 0, 0, 109, 110, 111, 0, 0, 0,
+ 112, 113, 0, 0, 667, 114, 115, 0, 0, 0,
+ 116, 0, 117, 61, 0, 0, 0, 118, 62, 0,
+ 0, 119, 0, 0, -203, 120, 121, 665, 668, 666,
+ 60, 0, 0, 0, 101, 102, 0, 103, 251, 252,
+ 253, 254, 255, 256, 257, 258, 259, 260, 261, 262,
+ 0, 0, 0, 0, 0, 104, 0, 15, 0, 105,
+ 106, 0, 0, 0, 0, 0, 107, 0, 0, 108,
+ 0, 0, 0, 0, 109, 110, 111, 0, 0, 0,
+ 112, 113, 0, 0, 667, 114, 115, 0, 0, 0,
+ 116, 0, 117, 61, 0, 0, 0, 118, 62, 0,
+ 0, 119, 0, 0, -268, 120, 121, 641, 668, 100,
+ 0, 0, 0, 0, 101, 102, 0, 103, 252, 253,
+ 254, 255, 256, 257, 258, 259, 260, 261, 262, 0,
+ 0, 0, 0, 0, 0, 104, 0, 15, 0, 105,
106, 0, 0, 0, 0, 0, 107, 0, 0, 108,
0, 0, 0, 0, 109, 110, 111, 0, 0, 0,
- 112, 113, 0, 100, 0, 114, 115, 0, 101, 102,
- 116, 103, 117, 0, 0, 0, 0, 118, 0, 0,
- 0, 119, 0, 830, 0, 120, 121, 0, 0, 104,
- 0, 15, 0, 105, 106, 0, 0, 0, 0, 0,
- 107, 0, 0, 108, 0, 0, 0, 0, 109, 110,
- 111, 0, 0, 0, 112, 113, 0, 100, 0, 114,
- 115, 0, 101, 102, 116, 103, 117, 0, 0, 0,
- 0, 118, 0, 0, 0, 119, 0, 0, 0, 120,
- 121, 0, 0, 104, 0, 15, 0, 105, 106, 0,
+ 112, 113, 0, 0, 0, 114, 115, 0, 0, 0,
+ 116, 0, 117, 0, 0, 0, 0, 118, 0, 0,
+ 0, 119, 665, 0, 100, 120, 121, 0, 642, 101,
+ 102, 0, 103, 344, 0, 0, 5, 0, 7, 138,
+ 0, 0, 0, 0, 9, 10, 11, 0, 0, 0,
+ 104, 0, 15, 0, 105, 106, 0, 0, 0, 0,
+ 13, 107, 0, 15, 108, 0, 0, 0, 0, 109,
+ 110, 111, 0, 0, 0, 112, 113, 16, 0, 0,
+ 114, 115, 0, 0, 0, 116, 0, 117, 0, 0,
+ 0, 0, 118, 0, 0, 0, 119, 0, 0, 22,
+ 120, 121, 194, 668, 24, -28, -28, -28, -28, 345,
+ -271, 0, 0, -28, -28, -28, 0, 0, 0, 0,
+ 0, 340, 0, 0, -24, -24, -24, -24, 195, -28,
+ 0, -175, -24, -24, -24, 0, 0, -175, 255, 256,
+ 257, 258, 259, 260, 261, 262, -28, 195, -24, 0,
+ -175, 0, 0, 0, 0, 0, -175, 0, 0, 0,
+ 196, 197, 0, 0, 0, -24, 0, 0, -28, 0,
+ 0, 0, 0, -28, 0, 0, 0, 0, -175, 196,
+ 197, 0, -175, -28, 0, 0, 0, -24, 0, 0,
+ 0, 0, -24, 0, 0, 0, 0, -175, 0, 0,
+ 334, -175, -24, -20, -20, -20, -20, 0, 0, 0,
+ 0, -20, -20, -20, 0, 0, 0, 0, 0, 321,
+ 0, 0, -498, -498, -498, -498, 195, -20, 0, -175,
+ -498, -498, -498, 0, 0, -175, 256, 257, 258, 259,
+ 260, 261, 262, 0, -20, 0, -498, 321, -498, 0,
+ -335, -335, -335, -335, 0, 0, 0, 0, -335, -335,
+ -335, 0, 0, -498, 0, 0, -20, 0, 0, 0,
+ 0, -20, 0, 0, -335, 0, -175, 0, 0, 0,
+ -175, -20, 0, 0, 0, -498, 0, 0, 0, 100,
+ -498, -335, 0, 0, 101, 102, 0, 103, 0, 0,
+ -498, 253, 254, 255, 256, 257, 258, 259, 260, 261,
+ 262, 0, 0, -335, 0, 104, 0, 15, -335, 105,
+ 106, 0, 0, 0, 0, 0, 107, 0, -111, 108,
+ 0, 0, 0, 0, 109, 110, 111, 0, 0, 0,
+ 112, 113, 0, 0, 0, 114, 115, 0, 100, 0,
+ 116, 0, 117, 101, 102, 0, 103, 118, 0, 0,
+ 0, 119, 0, 0, 0, 120, 121, 0, 0, 319,
+ 0, 0, 0, 0, 104, 0, 15, 0, 105, 106,
+ 0, 0, 0, 0, 0, 107, 0, 0, 108, 0,
+ 0, 0, 0, 109, 110, 111, 0, 0, 0, 112,
+ 113, 0, 0, 0, 114, 115, 0, 100, 0, 116,
+ 0, 117, 101, 102, 0, 103, 118, 0, 0, 0,
+ 119, 0, 0, 0, 120, 121, 0, 0, 405, 0,
+ 0, 0, 0, 104, 0, 15, 0, 105, 106, 0,
0, 0, 0, 0, 107, 0, 0, 108, 0, 0,
0, 0, 109, 110, 111, 0, 0, 0, 112, 113,
- 0, 100, 0, 242, 115, 0, 101, 102, 116, 103,
- 117, 0, 0, 0, 0, 118, 0, 0, 0, 119,
- 0, 0, 0, 120, 121, 0, 0, 104, 0, 15,
- 0, 105, 106, 0, 0, 0, 0, 0, 107, 0,
- 0, 108, 0, 0, 0, 0, 109, 110, 111, 0,
- 0, 0, 112, 113, 0, 505, 0, 244, 115, 0,
- 101, 102, 116, 103, 117, 0, 0, 0, 0, 118,
- 0, 0, 0, 119, 0, 0, 0, 120, 121, 0,
+ 0, 0, 0, 114, 115, 0, 100, 0, 116, 0,
+ 117, 101, 102, 0, 103, 118, 0, 0, 0, 119,
+ 0, 0, 0, 120, 121, 0, 0, 460, 0, 0,
+ 0, 0, 104, 0, 15, 0, 105, 106, 0, 0,
+ 0, 0, 0, 107, 0, 0, 108, 0, 0, 0,
+ 0, 109, 110, 111, 0, 0, 0, 112, 113, 0,
+ 0, 0, 114, 115, 0, 100, 0, 116, 0, 117,
+ 101, 102, 0, 103, 118, 0, 0, 0, 119, 0,
+ 0, 0, 120, 121, 0, 0, 501, 0, 0, 0,
0, 104, 0, 15, 0, 105, 106, 0, 0, 0,
0, 0, 107, 0, 0, 108, 0, 0, 0, 0,
109, 110, 111, 0, 0, 0, 112, 113, 0, 0,
0, 114, 115, 0, 0, 0, 116, 0, 117, 0,
0, 0, 0, 118, 0, 0, 0, 119, 0, 0,
- 540, 120, 121, 5, 0, 7, 138, 0, 0, 0,
- 0, 9, 10, 11, 0, 0, 0, 0, 540, 0,
- 0, 5, 0, 7, 138, 0, 0, 13, 0, 9,
- 10, 11, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 16, 13, 0, 0, 0, 0,
- 0, 0, 4, 0, -128, 5, 6, 7, 8, 0,
- 0, 0, 16, 9, 10, 11, 22, -446, -446, -446,
- 0, 24, 0, 0, 0, 0, 541, -446, 12, 13,
- 0, 14, 15, 0, 22, -445, -445, -445, 0, 24,
- 0, 0, 0, 0, 541, -445, 16, 0, 0, 17,
- 18, -128, 0, 0, 0, 0, 0, 0, 0, 0,
- -128, 0, 19, 20, 21, 0, 0, 0, 22, 0,
- 0, 0, 23, 24, 25, 26, 0, 4, 27, -128,
+ 0, 120, 121, 0, 0, 767, 666, 778, 6, 7,
+ 8, 101, 102, 0, 103, 9, 10, 11, 779, 0,
+ 780, 781, 782, 783, 784, 785, 786, 787, 788, 789,
+ 790, 13, 104, 14, 15, 0, 105, 106, 0, 0,
+ 0, 0, 0, 107, 0, 0, 108, 0, 16, 0,
+ 0, 109, 110, 111, 0, 0, 0, 112, 113, 0,
+ 0, 0, 114, 115, 0, 0, 0, 116, 0, 117,
+ 791, 0, 0, 0, 118, 792, 0, 0, 119, 0,
+ 793, 0, 120, 121, 0, 360, 666, 60, 0, 0,
+ 0, 101, 102, 0, 103, 0, 0, 0, 779, 0,
+ 780, 781, 782, 783, 784, 785, 786, 787, 788, 789,
+ 790, 0, 104, 0, 15, 0, 105, 106, 0, 0,
+ 0, 0, 0, 107, 0, 0, 108, 0, 0, 0,
+ 0, 109, 110, 111, 0, 0, 0, 112, 113, 0,
+ 100, 0, 114, 115, 0, 101, 102, 116, 103, 117,
+ 61, 0, 0, 0, 118, 62, 0, 0, 119, 0,
+ 793, 0, 120, 121, 0, 360, 104, 0, 15, 0,
+ 105, 106, 0, 0, 0, 0, 0, 107, 0, 0,
+ 108, 0, 0, 0, 0, 109, 110, 111, 0, 0,
+ 0, 112, 113, 0, 0, 0, 114, 115, 0, 0,
+ 0, 116, 0, 117, 0, 0, 0, 0, 118, 0,
+ 0, 0, 119, 0, 0, 0, 120, 121, 0, 479,
+ 147, 148, 0, 149, 150, 0, 0, 0, 151, 152,
+ 153, 154, 155, 156, 157, 158, 159, 160, 161, 162,
+ 163, 164, 165, 166, 167, 168, 169, 0, 100, 5,
+ 6, 7, 8, 101, 102, 170, 103, 9, 10, 11,
5, 6, 7, 8, 0, 0, 0, 0, 9, 10,
- 11, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 13, 4, 14, -128, 5, 6,
- 7, 8, 0, 0, 0, 0, 9, 10, 11, 0,
- 0, 16, 0, 0, 526, 527, -128, 0, 0, 0,
- 0, 0, 13, 0, 14, -128, 0, 0, 0, 0,
+ 11, 0, 0, 13, 104, 14, 15, 0, 105, 106,
+ 0, 0, 0, 0, 13, 107, 14, 0, 108, 172,
+ 16, 0, 0, 109, 110, 111, 0, 0, 295, 112,
+ 113, 16, 0, 0, 114, 115, 0, 0, 0, 116,
+ 0, 117, 22, 0, 0, 0, 118, 24, 0, 0,
+ 119, 0, 0, 22, 120, 121, 100, 5, 24, 7,
+ 138, 101, 102, 84, 103, 9, 10, 11, 254, 255,
+ 256, 257, 258, 259, 260, 261, 262, 0, 0, 0,
+ 0, 13, 104, 0, 15, 0, 105, 106, 0, 0,
+ 0, 0, 0, 107, 0, 0, 108, 0, 16, 0,
+ 0, 109, 110, 111, 0, 0, 0, 112, 113, 0,
+ 100, 0, 114, 115, 0, 101, 102, 116, 103, 117,
+ 22, 0, 0, 0, 118, 24, 0, 0, 119, 0,
+ 0, 0, 120, 121, 0, 0, 104, 0, 15, 0,
+ 105, 106, 0, 0, 0, 0, 0, 107, 0, 0,
+ 108, 0, 0, 0, 0, 109, 110, 111, 0, 0,
+ 0, 112, 113, 0, 100, 0, 114, 115, 0, 101,
+ 102, 116, 103, 117, 364, 0, 0, 0, 118, 0,
+ 0, 0, 119, 0, 0, 0, 120, 121, 0, 0,
+ 104, 0, 15, 0, 105, 106, 0, 0, 0, 0,
+ 0, 107, 0, 0, 108, 0, 0, 0, 0, 109,
+ 110, 111, 0, 0, 0, 112, 113, 0, 100, 0,
+ 114, 115, 0, 101, 102, 116, 103, 117, 0, 0,
+ 0, 0, 118, 0, 0, 0, 119, 0, 836, 0,
+ 120, 121, 0, 0, 104, 0, 15, 0, 105, 106,
+ 0, 0, 0, 0, 0, 107, 0, 0, 108, 0,
+ 0, 0, 0, 109, 110, 111, 0, 0, 0, 112,
+ 113, 0, 100, 0, 114, 115, 0, 101, 102, 116,
+ 103, 117, 0, 0, 0, 0, 118, 0, 0, 0,
+ 119, 0, 0, 0, 120, 121, 0, 0, 104, 0,
+ 15, 0, 105, 106, 0, 0, 0, 0, 0, 107,
+ 0, 0, 108, 0, 0, 0, 0, 109, 110, 111,
+ 0, 0, 0, 112, 113, 0, 100, 0, 242, 115,
+ 0, 101, 102, 116, 103, 117, 0, 0, 0, 0,
+ 118, 0, 0, 0, 119, 0, 0, 0, 120, 121,
+ 0, 0, 104, 0, 15, 0, 105, 106, 0, 0,
+ 0, 0, 0, 107, 0, 0, 108, 0, 0, 0,
+ 0, 109, 110, 111, 0, 0, 0, 112, 113, 0,
+ 505, 0, 244, 115, 0, 101, 102, 116, 103, 117,
+ 0, 0, 0, 0, 118, 0, 0, 0, 119, 0,
+ 0, 0, 120, 121, 0, 0, 104, 0, 15, 0,
+ 105, 106, 0, 0, 0, 0, 0, 107, 0, 0,
+ 108, 0, 0, 0, 0, 109, 110, 111, 0, 0,
+ 0, 112, 113, 0, 0, 0, 114, 115, 0, 0,
+ 0, 116, 0, 117, 0, 0, 0, 0, 118, 0,
+ 0, 0, 119, 0, 0, 540, 120, 121, 5, 0,
+ 7, 138, 0, 0, 0, 0, 9, 10, 11, 0,
+ 0, 0, 0, 540, 0, 0, 5, 0, 7, 138,
+ 0, 0, 13, 0, 9, 10, 11, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 16,
+ 13, 0, 0, 0, 0, 0, 0, 4, 0, -128,
+ 5, 6, 7, 8, 0, 0, 0, 16, 9, 10,
+ 11, 22, -450, -450, -450, 0, 24, 0, 0, 0,
+ 0, 541, -450, 12, 13, 0, 14, 15, 0, 22,
+ -449, -449, -449, 0, 24, 0, 0, 0, 0, 541,
+ -449, 16, 0, 0, 17, 18, -128, 0, 0, 0,
+ 0, 0, 0, 0, 0, -128, 0, 19, 20, 21,
+ 0, 0, 0, 22, 0, 0, 0, 23, 24, 25,
+ 26, 0, 4, 27, -128, 5, 6, 7, 8, 0,
+ 0, 0, 0, 9, 10, 11, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 13,
+ 4, 14, -128, 5, 6, 7, 8, 0, 0, 0,
+ 0, 9, 10, 11, 0, 0, 16, 0, 0, 526,
+ 527, -128, 0, 0, 0, 0, 0, 13, 434, 14,
+ -128, 5, 6, 7, 8, 0, 0, 436, 22, 9,
+ 10, 11, 0, 24, 16, 0, 0, 0, 27, -128,
+ 0, 5, 6, 7, 8, 13, 0, 14, -128, 9,
+ 10, 11, 0, 0, 0, 0, 22, 0, 0, 0,
+ 0, 24, 16, 0, 0, 13, 27, 14, 0, 0,
+ 5, 6, 7, 8, 0, 0, 0, 0, 9, 10,
+ 11, 0, 16, 0, 22, 0, 0, 0, 0, 24,
+ 0, 0, 0, -395, 13, 0, 14, 0, 5, 89,
+ 7, 90, 0, 0, 22, 0, 9, 10, 11, 24,
+ 0, 16, 0, 0, 598, 344, 0, 0, 5, 0,
+ 7, 138, 13, 0, 0, 0, 9, 10, 11, 0,
0, 0, 0, 22, 0, 0, 0, 0, 24, 16,
- 0, 0, 0, 27, -128, 434, 0, 435, 5, 6,
- 7, 8, 0, -128, 436, 0, 9, 10, 11, 0,
- 0, 22, 0, 0, 434, 0, 24, 5, 6, 7,
- 8, 27, 13, 436, 14, 9, 10, 11, 5, 6,
- 7, 8, 0, 0, 0, 0, 9, 10, 11, 16,
- 0, 13, 0, 14, 0, 0, 0, 5, 6, 7,
- 8, 0, 13, 0, 14, 9, 10, 11, 16, 0,
- 0, 22, 0, 0, 0, 0, 24, 0, 0, 16,
- -391, 13, 0, 14, 0, 0, 0, 0, 0, 0,
- 22, 0, 0, 0, 0, 24, 0, 0, 16, -391,
+ 0, 0, 13, 846, 0, 15, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 16,
0, 22, 0, 0, 0, 0, 24, 0, 0, 0,
- 0, 598, 0, 0, 0, 0, 0, 0, 0, 0,
- 22, 0, 0, 147, 148, 24, 149, 150, 0, 0,
- 840, 151, 152, 153, 154, 155, 156, 157, 158, 159,
+ 0, 637, 0, 0, 0, 0, 0, 0, 0, 147,
+ 148, 22, 149, 150, 0, 0, 24, 151, 152, 153,
+ 154, 155, 156, 157, 158, 159, 160, 161, 162, 163,
+ 164, 165, 166, 167, 168, 169, 0, 147, 148, 0,
+ 149, 150, 0, 0, 170, 151, 152, 153, 154, 155,
+ 156, 157, 158, 159, 160, 161, 162, 163, 164, 165,
+ 166, 167, 168, 169, 0, 171, 0, 0, 0, 0,
+ 0, 0, 367, 147, 148, 0, 149, 150, 172, 0,
+ 0, 151, 152, 153, 154, 155, 156, 157, 158, 159,
160, 161, 162, 163, 164, 165, 166, 167, 168, 169,
- 0, 147, 148, 0, 149, 150, 0, 0, 170, 151,
+ 0, 147, 148, 0, 149, 150, 172, 0, 170, 151,
152, 153, 154, 155, 156, 157, 158, 159, 160, 161,
- 162, 163, 164, 165, 166, 167, 168, 169, 0, 171,
- 0, 0, 0, 0, 0, 0, 367, 147, 148, 0,
- 149, 150, 172, 0, 0, 151, 152, 153, 154, 155,
- 156, 157, 158, 159, 160, 161, 162, 163, 164, 165,
- 166, 167, 168, 169, 0, 147, 148, 0, 149, 150,
- 172, 0, 170, 151, 152, 153, 154, 155, 156, 157,
- 158, 159, 160, 161, 162, 163, 164, 165, 166, 167,
- 168, 169, 0, 0, 5, 0, 7, 280, 0, 0,
- 583, 0, 9, 10, 11, 0, 172, 5, 6, 7,
- 8, 0, 0, 436, 0, 9, 10, 11, 13, 5,
- 6, 7, 8, 0, 0, 631, 0, 9, 10, 11,
- 0, 13, 0, 14, 172, 16, 0, 0, 0, 0,
- 273, 0, 0, 13, 0, 14, 0, 0, 16, 274,
- 275, 0, 0, 0, 0, 0, 0, 22, 0, 0,
- 16, 0, 24, 0, 5, 6, 7, 8, 0, 0,
- 22, 0, 9, 10, 11, 24, 5, 6, 7, 8,
- 0, 0, 22, 0, 9, 10, 11, 24, 13, 5,
- 14, 7, 280, 0, 0, 0, 0, 9, 10, 11,
- 13, 0, 0, 0, 0, 16, 0, 0, 0, 0,
- 0, 0, 0, 13, 0, 0, 0, 16, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 22, 0, 0,
- 16, 0, 24, 861, 0, 0, 0, 0, 0, 22,
- 0, 0, 0, 0, 24, 0, 0, 0, 0, 0,
- 0, 0, 22, 0, 0, 0, 0, 24, 246, 247,
- 248, 862, 249, 250, 251, 252, 253, 254, 255, 256,
- 257, 258, 259, 260, 261, 262, 14, 0, 0, 0,
- 0, 246, 247, 248, 0, 249, 250, 251, 252, 253,
- 254, 255, 256, 257, 258, 259, 260, 261, 262, 246,
- 247, 248, 900, 249, 250, 251, 252, 253, 254, 255,
- 256, 257, 258, 259, 260, 261, 262, 246, 247, 248,
- 0, 249, 250, 251, 252, 253, 254, 255, 256, 257,
- 258, 259, 260, 261, 262
+ 162, 163, 164, 165, 166, 167, 168, 169, 0, 0,
+ 0, 5, 6, 7, 8, 0, 583, 436, 0, 9,
+ 10, 11, 172, 5, 6, 7, 8, 0, 0, 631,
+ 0, 9, 10, 11, 0, 13, 0, 14, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 13, 0, 14,
+ 172, 0, 16, 5, 6, 7, 8, 5, 6, 7,
+ 8, 9, 10, 11, 16, 9, 10, 11, 0, 0,
+ 0, 0, 0, 0, 22, 0, 0, 13, 0, 24,
+ 0, 13, 0, 14, 0, 0, 22, 5, 0, 7,
+ 280, 24, 0, 0, 16, 9, 10, 11, 16, 0,
+ 0, 0, 0, 0, 866, 0, 0, 0, 0, 0,
+ 0, 13, 0, 0, 0, 0, 22, 0, 0, 0,
+ 22, 24, 0, 0, 0, 24, 0, 0, 16, 246,
+ 247, 248, 867, 249, 250, 251, 252, 253, 254, 255,
+ 256, 257, 258, 259, 260, 261, 262, 14, 0, 0,
+ 22, 0, 246, 247, 248, 24, 249, 250, 251, 252,
+ 253, 254, 255, 256, 257, 258, 259, 260, 261, 262,
+ 246, 247, 248, 905, 249, 250, 251, 252, 253, 254,
+ 255, 256, 257, 258, 259, 260, 261, 262, 246, 247,
+ 248, 0, 249, 250, 251, 252, 253, 254, 255, 256,
+ 257, 258, 259, 260, 261, 262
};
static const short yycheck[] = { 56,
- 57, 31, 207, 16, 2, 3, 19, 20, 2, 3,
- 23, 198, 25, 26, 33, 83, 85, 91, 201, 2,
- 3, 22, 335, 24, 206, 38, 39, 40, 341, 105,
- 106, 24, 233, 2, 3, 111, 267, 308, 337, 548,
- 9, 10, 11, 316, 42, 66, 122, 77, 42, 278,
- 175, 404, 274, 323, 636, 85, 95, 133, 221, 42,
- 221, 74, 31, 427, 33, 1, 67, 202, 192, 140,
- 71, 175, 143, 42, 67, 32, 33, 114, 71, 3,
- 336, 425, 570, 9, 1, 739, 38, 343, 27, 1,
- 273, 38, 1, 10, 107, 351, 898, 3, 4, 77,
- 3, 77, 30, 81, 717, 81, 30, 59, 77, 314,
- 38, 3, 4, 823, 83, 77, 85, 38, 38, 81,
- 59, 60, 91, 736, 926, 36, 50, 3, 4, 76,
- 82, 144, 236, 146, 171, 59, 33, 324, 212, 42,
- 197, 77, 53, 54, 55, 0, 416, 59, 335, 45,
- 76, 805, 3, 4, 341, 76, 76, 170, 50, 189,
- 57, 67, 0, 193, 874, 82, 72, 180, 181, 80,
- 183, 184, 202, 82, 662, 67, 82, 88, 235, 401,
- 72, 410, 413, 7, 894, 81, 349, 897, 349, 899,
- 534, 67, 701, 702, 329, 849, 72, 907, 333, 5,
- 237, 7, 59, 60, 278, 242, 82, 244, 332, 77,
- 78, 268, 225, 59, 60, 38, 67, 114, 275, 76,
- 189, 72, 45, 192, 193, 238, 50, 3, 4, 939,
- 76, 82, 76, 202, 30, 59, 60, 81, 221, 1,
- 59, 3, 4, 212, 732, 515, 143, 27, 38, 613,
- 30, 522, 265, 266, 291, 45, 36, 839, 3, 4,
- 604, 3, 4, 5, 6, 7, 370, 59, 431, 59,
- 431, 59, 60, 59, 171, 48, 49, 630, 465, 45,
- 467, 338, 77, 59, 3, 4, 299, 363, 76, 30,
- 63, 67, 59, 60, 3, 206, 72, 77, 7, 329,
- 301, 81, 30, 333, 59, 67, 217, 816, 301, 579,
- 72, 350, 65, 352, 59, 59, 572, 573, 59, 60,
- 576, 30, 67, 380, 221, 67, 38, 72, 82, 76,
- 72, 59, 60, 45, 81, 606, 410, 59, 516, 77,
- 237, 50, 520, 81, 357, 242, 82, 244, 67, 318,
- 59, 408, 583, 72, 555, 82, 844, 59, 60, 3,
- 329, 592, 76, 332, 333, 59, 349, 81, 624, 625,
- 626, 50, 628, 629, 3, 4, 76, 481, 7, 9,
- 59, 60, 81, 420, 509, 563, 30, 657, 566, 346,
- 660, 348, 579, 76, 291, 59, 60, 653, 81, 412,
- 622, 30, 77, 78, 703, 509, 50, 3, 4, 76,
- 75, 640, 3, 4, 81, 59, 60, 328, 416, 438,
- 691, 50, 416, 424, 77, 78, 682, 683, 684, 427,
- 59, 424, 451, 427, 30, 404, 77, 76, 621, 30,
- 81, 623, 38, 72, 627, 676, 38, 416, 3, 4,
- 419, 348, 349, 616, 50, 616, 59, 60, 427, 50,
- 473, 648, 76, 59, 77, 721, 3, 4, 59, 438,
- 427, 658, 82, 660, 59, 30, 72, 548, 549, 701,
- 437, 438, 586, 38, 59, 714, 708, 77, 68, 69,
- 70, 81, 511, 30, 507, 50, 78, 27, 78, 529,
- 30, 3, 4, 77, 59, 7, 36, 81, 126, 127,
- 766, 77, 531, 50, 78, 81, 514, 72, 548, 549,
- 514, 77, 59, 420, 76, 81, 77, 77, 30, 59,
- 60, 81, 77, 734, 431, 72, 81, 808, 50, 51,
- 52, 438, 511, 612, 76, 514, 82, 77, 50, 617,
- 618, 81, 76, 510, 451, 38, 59, 59, 60, 76,
- 529, 77, 531, 10, 820, 578, 640, 597, 76, 638,
- 771, 63, 82, 530, 531, 758, 889, 76, 891, 548,
- 549, 649, 612, 552, 27, 542, 543, 608, 609, 602,
- 9, 77, 622, 83, 3, 4, 36, 5, 6, 7,
- 67, 77, 559, 560, 12, 13, 14, 36, 638, 81,
- 68, 69, 70, 78, 511, 613, 68, 69, 70, 613,
- 78, 30, 30, 68, 69, 70, 78, 76, 597, 5,
- 6, 7, 38, 78, 531, 76, 12, 13, 14, 76,
- 714, 50, 611, 612, 613, 76, 543, 704, 617, 618,
- 59, 60, 76, 622, 667, 76, 613, 38, 76, 82,
- 933, 630, 76, 560, 869, 76, 83, 636, 941, 638,
- 83, 701, 702, 63, 875, 6, 7, 734, 708, 241,
- 649, 12, 13, 14, 246, 247, 63, 76, 756, 251,
- 252, 253, 254, 255, 256, 257, 258, 259, 260, 261,
- 262, 76, 889, 36, 891, 48, 49, 50, 51, 52,
- 83, 724, 623, 76, 771, 916, 917, 1, 748, 616,
- 4, 734, 6, 7, 78, 782, 802, 78, 12, 13,
- 14, 78, 701, 702, 32, 38, 734, 83, 76, 708,
- 734, 77, 81, 77, 28, 3, 76, 31, 77, 3,
- 78, 734, 38, 7, 81, 63, 78, 83, 771, 78,
- 38, 45, 38, 78, 821, 734, 63, 824, 825, 81,
- 783, 839, 841, 792, 38, 832, 30, 81, 78, 748,
- 36, 63, 83, 67, 785, 786, 816, 756, 72, 78,
- 847, 38, 59, 786, 59, 38, 50, 59, 855, 7,
- 77, 38, 77, 77, 802, 59, 60, 77, 802, 866,
- 16, 841, 78, 59, 77, 59, 77, 76, 875, 802,
- 382, 383, 63, 792, 3, 4, 54, 55, 7, 57,
- 58, 59, 60, 802, 791, 792, 4, 5, 6, 7,
- 4, 898, 6, 7, 12, 13, 14, 816, 12, 13,
- 14, 30, 54, 55, 17, 57, 58, 59, 60, 77,
- 28, 76, 875, 920, 28, 77, 76, 76, 9, 926,
- 839, 50, 841, 77, 76, 59, 77, 45, 77, 1,
- 59, 45, 4, 5, 6, 7, 81, 77, 10, 76,
- 12, 13, 14, 76, 0, 792, 77, 77, 0, 67,
- 413, 824, 324, 67, 72, 87, 28, 658, 72, 77,
- 472, 802, 281, 639, 1, 412, 3, 4, 5, 6,
- 7, 8, 9, 45, 11, 12, 13, 14, 15, 491,
- 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
- 27, 28, 29, 30, 31, 67, 33, 34, 646, 475,
- 72, 349, 467, 40, 357, 648, 43, 658, 45, 473,
- 82, 48, 49, 50, 580, 660, 921, 54, 55, 923,
- 875, 875, 59, 60, 407, 419, 552, 64, 25, 66,
- 67, 419, 539, 618, 71, 72, 756, 300, 75, 753,
- 77, 78, 79, 80, 532, 82, 514, 586, 748, 415,
- 562, 43, 44, 45, 46, 47, 48, 49, 50, 51,
- 52, 1, 370, 3, 4, 5, 6, 7, 8, 9,
- 582, 11, 12, 13, 14, 15, 676, 17, 18, 19,
- 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
- 30, 31, -1, 33, 34, 509, -1, 415, -1, -1,
- 40, -1, -1, 43, -1, 45, -1, -1, 48, 49,
- 50, -1, -1, -1, 54, 55, -1, -1, -1, 59,
- 60, -1, -1, -1, 64, -1, 66, 67, -1, -1,
- -1, 71, 72, -1, 646, 75, -1, 77, -1, 79,
- 80, 1, 82, 3, 4, -1, -1, -1, 8, 9,
- -1, 11, -1, -1, -1, 15, -1, 17, 18, 19,
- 20, 21, 22, 23, 24, 25, 26, 27, 680, 29,
- -1, 31, -1, 33, 34, -1, -1, -1, -1, -1,
- 40, -1, -1, 43, 696, -1, -1, -1, 48, 49,
- 50, -1, -1, -1, 54, 55, -1, -1, -1, 59,
- 60, -1, -1, -1, 64, 717, 66, 67, 720, -1,
- -1, 71, 72, -1, -1, 75, -1, 77, 78, 79,
- 80, -1, 82, -1, 736, -1, 1, 739, -1, 4,
- 5, 6, 7, -1, -1, -1, -1, 12, 13, 14,
- -1, -1, -1, 755, 44, 45, 46, 47, 48, 49,
- 50, 51, 52, 28, -1, 767, -1, 1, -1, 3,
- 4, -1, -1, -1, 8, 9, 778, 11, -1, -1,
- 45, 15, -1, 17, 18, 19, 20, 21, 22, 23,
- 24, 25, 26, 27, -1, 29, -1, 31, -1, 33,
- 34, -1, 67, 805, -1, -1, 40, 72, -1, 43,
- -1, -1, -1, -1, 48, 49, 50, 82, -1, -1,
+ 57, 207, 2, 3, 16, 2, 3, 19, 20, 2,
+ 3, 23, 316, 25, 26, 31, 9, 10, 11, 2,
+ 3, 201, 175, 22, 85, 24, 38, 39, 40, 83,
+ 33, 308, 24, 91, 278, 337, 221, 198, 31, 206,
+ 33, 175, 42, 66, 95, 42, 267, 32, 33, 42,
+ 105, 106, 33, 404, 274, 140, 111, 233, 143, 42,
+ 323, 77, 74, 570, 636, 221, 192, 122, 67, 85,
+ 425, 335, 71, 548, 114, 67, 57, 341, 133, 71,
+ 676, 427, 9, 236, 77, 36, 1, 3, 4, 1,
+ 83, 38, 85, 273, 202, 107, 3, 4, 91, 3,
+ 1, 1, 53, 54, 55, 36, 38, 30, 314, 38,
+ 10, 903, 59, 45, 38, 38, 45, 720, 77, 3,
+ 4, 38, 81, 1, 77, 3, 4, 58, 81, 80,
+ 59, 171, 144, 114, 146, 82, 739, 88, 42, 931,
+ 197, 3, 4, 5, 6, 7, 38, 59, 744, 76,
+ 38, 67, 76, 416, 212, 662, 72, 45, 170, 76,
+ 67, 829, 143, 324, 349, 72, 410, 82, 180, 181,
+ 0, 183, 184, 189, 335, 82, 77, 193, 235, 534,
+ 341, 401, 82, 67, 76, 0, 202, 45, 72, 67,
+ 171, 77, 413, 349, 72, 81, 189, 237, 82, 192,
+ 193, 30, 242, 59, 244, 67, 332, 59, 60, 202,
+ 72, 268, 880, 225, 810, 3, 4, 370, 275, 212,
+ 278, 329, 76, 81, 76, 333, 238, 81, 735, 704,
+ 705, 899, 59, 3, 902, 77, 904, 7, 221, 81,
+ 221, 5, 30, 7, 912, 522, 431, 3, 4, 604,
+ 38, 291, 515, 265, 266, 206, 237, 59, 3, 4,
+ 30, 242, 50, 244, 3, 4, 217, 613, 7, 77,
+ 78, 59, 76, 845, 30, 431, 944, 81, 7, 630,
+ 50, 338, 59, 60, 72, 3, 4, 299, 3, 59,
+ 60, 30, 7, 45, 50, 3, 4, 59, 60, 350,
+ 76, 352, 301, 59, 465, 81, 467, 65, 363, 301,
+ 291, 50, 30, 329, 76, 30, 579, 333, 77, 30,
+ 59, 50, 67, 380, 59, 318, 59, 72, 481, 606,
+ 59, 60, 50, 72, 77, 50, 329, 82, 81, 332,
+ 333, 59, 50, 850, 59, 357, 82, 822, 59, 60,
+ 76, 408, 410, 27, 72, 81, 509, 59, 60, 67,
+ 82, 346, 583, 348, 72, 3, 349, 348, 349, 30,
+ 82, 592, 77, 59, 76, 509, 81, 328, 1, 555,
+ 420, 4, 5, 6, 7, 59, 60, 10, 76, 12,
+ 13, 14, 30, 81, 657, 59, 640, 660, 59, 60,
+ 412, 76, 622, 81, 706, 28, 5, 6, 7, 48,
+ 49, 404, 50, 12, 13, 14, 416, 694, 579, 416,
+ 9, 59, 45, 416, 63, 424, 419, 427, 59, 60,
+ 427, 616, 424, 586, 427, 438, 3, 4, 75, 420,
+ 76, 621, 427, 76, 67, 438, 38, 627, 451, 72,
+ 431, 77, 437, 438, 3, 4, 623, 438, 679, 82,
+ 616, 473, 27, 548, 549, 30, 4, 82, 6, 7,
+ 451, 36, 59, 717, 12, 13, 14, 59, 60, 3,
+ 4, 30, 77, 59, 704, 78, 81, 648, 78, 38,
+ 28, 711, 59, 76, 50, 507, 76, 658, 82, 660,
+ 67, 50, 516, 59, 60, 72, 520, 45, 511, 77,
+ 59, 77, 77, 529, 514, 81, 81, 514, 511, 38,
+ 77, 514, 77, 72, 81, 510, 81, 77, 531, 67,
+ 511, 81, 548, 549, 72, 59, 529, 814, 531, 77,
+ 78, 3, 4, 67, 76, 530, 531, 59, 72, 563,
+ 531, 612, 566, 3, 76, 548, 549, 542, 543, 552,
+ 77, 737, 543, 617, 618, 10, 578, 76, 30, 48,
+ 49, 50, 51, 52, 559, 560, 63, 638, 82, 560,
+ 30, 597, 640, 76, 764, 608, 609, 27, 50, 9,
+ 602, 83, 68, 69, 70, 649, 612, 59, 60, 77,
+ 50, 777, 78, 36, 597, 77, 622, 67, 336, 59,
+ 60, 77, 78, 613, 36, 343, 613, 81, 611, 612,
+ 613, 78, 638, 351, 617, 618, 77, 78, 613, 622,
+ 894, 38, 896, 76, 938, 616, 83, 630, 4, 76,
+ 6, 7, 946, 636, 76, 638, 12, 13, 14, 76,
+ 707, 50, 51, 52, 38, 667, 649, 59, 60, 717,
+ 3, 4, 28, 76, 7, 126, 127, 76, 76, 875,
+ 1, 83, 623, 4, 5, 6, 7, 82, 76, 45,
+ 737, 12, 13, 14, 50, 76, 63, 30, 704, 705,
+ 68, 69, 70, 59, 60, 711, 63, 28, 36, 30,
+ 78, 67, 76, 76, 83, 881, 72, 50, 762, 78,
+ 78, 704, 705, 76, 45, 727, 59, 60, 711, 4,
+ 777, 6, 7, 78, 32, 737, 38, 12, 13, 14,
+ 83, 788, 76, 894, 81, 896, 67, 737, 754, 76,
+ 737, 72, 77, 28, 737, 921, 922, 27, 77, 3,
+ 30, 82, 77, 808, 737, 81, 36, 68, 69, 70,
+ 45, 754, 3, 4, 78, 777, 7, 78, 38, 762,
+ 827, 63, 78, 830, 831, 78, 83, 789, 38, 59,
+ 60, 838, 67, 38, 78, 81, 847, 72, 63, 30,
+ 38, 845, 791, 792, 81, 798, 853, 77, 63, 78,
+ 792, 81, 83, 860, 78, 798, 822, 38, 808, 50,
+ 59, 808, 797, 798, 871, 808, 59, 798, 59, 59,
+ 38, 77, 241, 7, 881, 808, 77, 246, 247, 822,
+ 38, 847, 251, 252, 253, 254, 255, 256, 257, 258,
+ 259, 260, 261, 262, 572, 573, 903, 77, 576, 77,
+ 16, 78, 845, 59, 847, 54, 55, 77, 57, 58,
+ 59, 60, 77, 5, 6, 7, 59, 63, 925, 881,
+ 12, 13, 14, 76, 931, 77, 17, 76, 1, 76,
+ 3, 4, 5, 6, 7, 77, 76, 10, 30, 12,
+ 13, 14, 68, 69, 70, 76, 624, 625, 626, 77,
+ 628, 629, 78, 6, 7, 28, 77, 30, 9, 12,
+ 13, 14, 77, 1, 59, 3, 4, 81, 77, 76,
+ 8, 9, 45, 11, 76, 653, 77, 15, 77, 17,
+ 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
+ 0, 29, 0, 31, 67, 33, 34, 830, 413, 72,
+ 87, 658, 40, 76, 324, 43, 639, 685, 686, 687,
+ 48, 49, 50, 382, 383, 808, 54, 55, 281, 646,
+ 412, 59, 60, 742, 675, 475, 64, 349, 66, 67,
+ 648, 467, 357, 71, 72, 473, 658, 75, 881, 77,
+ 78, 79, 80, 660, 82, 580, 724, 407, 926, 881,
+ 552, 419, 928, 1, 419, 3, 4, 5, 6, 7,
+ 8, 9, 25, 11, 12, 13, 14, 15, 539, 17,
+ 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
+ 28, 29, 30, 31, 759, 33, 34, 618, 762, 300,
+ 514, 532, 40, 586, 772, 43, 509, 45, 754, 679,
+ 48, 49, 50, 472, 415, 415, 54, 55, -1, -1,
+ 370, 59, 60, -1, -1, -1, 64, -1, 66, 67,
+ -1, -1, 491, 71, 72, -1, -1, 75, -1, 77,
+ 78, 79, 80, 1, 82, 3, 4, 5, 6, 7,
+ 8, 9, -1, 11, 12, 13, 14, 15, 826, 17,
+ 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
+ 28, 29, 30, 31, 842, 33, 34, -1, -1, -1,
+ -1, -1, 40, -1, -1, 43, -1, 45, -1, -1,
+ 48, 49, 50, -1, -1, -1, 54, 55, -1, -1,
+ -1, 59, 60, 562, -1, -1, 64, -1, 66, 67,
+ -1, -1, -1, 71, 72, -1, -1, 75, -1, 77,
+ -1, 79, 80, 582, 82, 1, -1, 3, 4, -1,
+ -1, -1, 8, 9, -1, 11, -1, -1, -1, 15,
+ -1, 17, 18, 19, 20, 21, 22, 23, 24, 25,
+ 26, 27, -1, 29, -1, 31, -1, 33, 34, -1,
+ -1, -1, -1, -1, 40, 54, 55, 43, 57, 58,
+ 59, 60, 48, 49, 50, -1, -1, -1, 54, 55,
+ -1, -1, -1, 59, 60, -1, -1, 646, 64, -1,
+ 66, 67, -1, -1, -1, 71, 72, -1, -1, 75,
+ 1, 77, 3, 79, 80, -1, 82, 8, 9, -1,
+ 11, -1, -1, -1, -1, -1, -1, 676, -1, -1,
+ -1, -1, -1, -1, 683, -1, -1, -1, 29, -1,
+ 31, -1, 33, 34, -1, 36, -1, -1, -1, 40,
+ 699, -1, 43, -1, -1, -1, -1, 48, 49, 50,
+ -1, -1, -1, 54, 55, -1, -1, 58, 59, 60,
+ -1, 720, -1, 64, 723, 66, -1, -1, -1, -1,
+ 71, -1, -1, -1, 75, -1, -1, -1, 79, 80,
+ 739, 82, -1, 742, -1, 744, -1, 1, -1, 3,
+ 4, -1, -1, -1, 8, 9, -1, 11, -1, -1,
+ -1, 15, 761, 17, 18, 19, 20, 21, 22, 23,
+ 24, 25, 26, 27, 773, 29, -1, 31, -1, 33,
+ 34, -1, -1, -1, -1, 784, 40, -1, -1, 43,
+ -1, -1, -1, -1, 48, 49, 50, -1, -1, -1,
+ 54, 55, -1, -1, -1, 59, 60, -1, -1, -1,
+ 64, 810, 66, 67, -1, -1, -1, 71, 72, -1,
+ -1, 75, -1, 77, -1, 79, 80, 1, 82, 3,
+ 4, -1, 6, 7, 8, 9, -1, 11, 12, 13,
+ 14, 40, 41, 42, 43, 44, 45, 46, 47, 48,
+ 49, 50, 51, 52, 28, 29, -1, 31, -1, 33,
+ 34, -1, -1, -1, -1, -1, 40, 866, -1, 43,
+ -1, 45, -1, -1, 48, 49, 50, -1, -1, -1,
54, 55, -1, -1, -1, 59, 60, -1, -1, -1,
64, -1, 66, 67, -1, -1, -1, 71, 72, -1,
- -1, 75, -1, 77, -1, 79, 80, 849, 82, -1,
- 1, -1, 3, 4, -1, -1, -1, 8, 9, 861,
- 11, -1, -1, -1, 15, -1, 17, 18, 19, 20,
- 21, 22, 23, 24, 25, 26, 27, -1, 29, -1,
- 31, -1, 33, 34, -1, -1, -1, -1, -1, 40,
- -1, -1, 43, -1, -1, -1, -1, 48, 49, 50,
- -1, -1, -1, 54, 55, -1, -1, -1, 59, 60,
- -1, -1, -1, 64, -1, 66, 67, -1, -1, -1,
- 71, 72, -1, -1, 75, -1, 77, -1, 79, 80,
- 1, 82, 3, 4, -1, 6, 7, 8, 9, -1,
- 11, 12, 13, 14, 40, 41, 42, 43, 44, 45,
- 46, 47, 48, 49, 50, 51, 52, 28, 29, -1,
- 31, -1, 33, 34, -1, -1, -1, -1, -1, 40,
- -1, -1, 43, -1, 45, -1, -1, 48, 49, 50,
- -1, -1, -1, 54, 55, -1, -1, -1, 59, 60,
- -1, -1, -1, 64, -1, 66, 67, -1, -1, -1,
- 71, 72, -1, -1, 75, -1, -1, -1, 79, 80,
- 1, 82, 3, 4, -1, -1, -1, 8, 9, 37,
- 11, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, -1, -1, -1, 29, -1,
- 31, -1, 33, 34, -1, -1, -1, -1, -1, 40,
- -1, -1, 43, -1, -1, -1, -1, 48, 49, 50,
- -1, -1, -1, 54, 55, -1, -1, 58, 59, 60,
- -1, -1, -1, 64, -1, 66, 67, -1, -1, -1,
- 71, 72, -1, -1, 75, -1, -1, 78, 79, 80,
- 1, 82, 3, 4, -1, -1, -1, 8, 9, -1,
- 11, 41, 42, 43, 44, 45, 46, 47, 48, 49,
- 50, 51, 52, -1, -1, -1, -1, -1, 29, -1,
- 31, -1, 33, 34, -1, -1, -1, -1, -1, 40,
- -1, -1, 43, -1, -1, -1, -1, 48, 49, 50,
- -1, -1, -1, 54, 55, -1, -1, 58, 59, 60,
- -1, -1, -1, 64, -1, 66, 67, -1, -1, -1,
- 71, 72, -1, -1, 75, -1, -1, 78, 79, 80,
- 1, 82, 3, 4, -1, -1, -1, 8, 9, -1,
- 11, 42, 43, 44, 45, 46, 47, 48, 49, 50,
- 51, 52, -1, -1, -1, -1, -1, -1, 29, -1,
- 31, -1, 33, 34, -1, -1, -1, -1, -1, 40,
- -1, -1, 43, -1, -1, -1, -1, 48, 49, 50,
- -1, -1, -1, 54, 55, -1, -1, 58, 59, 60,
- -1, -1, -1, 64, -1, 66, 67, -1, -1, -1,
- 71, 72, -1, -1, 75, 1, -1, 3, 79, 80,
- -1, 82, 8, 9, -1, 11, 1, -1, -1, 4,
- -1, 6, 7, -1, -1, -1, -1, 12, 13, 14,
- -1, -1, -1, 29, -1, 31, -1, 33, 34, -1,
- -1, -1, -1, 28, 40, -1, 31, 43, -1, -1,
- -1, -1, 48, 49, 50, -1, -1, -1, 54, 55,
- 45, -1, -1, 59, 60, -1, -1, -1, 64, -1,
- 66, -1, -1, -1, -1, 71, -1, -1, -1, 75,
- -1, -1, 67, 79, 80, 1, 82, 72, 4, 5,
- 6, 7, 77, 78, -1, -1, 12, 13, 14, -1,
- -1, -1, -1, -1, 1, -1, -1, 4, 5, 6,
- 7, 27, 28, -1, 30, 12, 13, 14, -1, -1,
- 36, 45, 46, 47, 48, 49, 50, 51, 52, 45,
- 27, 28, -1, 30, -1, -1, -1, -1, -1, 36,
- -1, -1, -1, 59, 60, -1, -1, -1, 45, -1,
- -1, 67, -1, -1, -1, -1, 72, -1, -1, -1,
- -1, 77, 59, 60, -1, 81, 82, -1, -1, -1,
- 67, -1, -1, -1, -1, 72, -1, -1, -1, -1,
- 77, -1, -1, 1, 81, 82, 4, 5, 6, 7,
+ -1, 75, -1, -1, -1, 79, 80, 1, 82, 3,
+ 4, -1, -1, -1, 8, 9, 37, 11, 39, 40,
+ 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
+ 51, 52, -1, -1, -1, 29, -1, 31, -1, 33,
+ 34, -1, -1, -1, -1, -1, 40, -1, -1, 43,
+ -1, -1, -1, -1, 48, 49, 50, -1, -1, -1,
+ 54, 55, -1, -1, 58, 59, 60, -1, -1, -1,
+ 64, -1, 66, 67, -1, -1, -1, 71, 72, -1,
+ -1, 75, -1, -1, 78, 79, 80, 1, 82, 3,
+ 4, -1, -1, -1, 8, 9, -1, 11, 41, 42,
+ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
+ -1, -1, -1, -1, -1, 29, -1, 31, -1, 33,
+ 34, -1, -1, -1, -1, -1, 40, -1, -1, 43,
+ -1, -1, -1, -1, 48, 49, 50, -1, -1, -1,
+ 54, 55, -1, -1, 58, 59, 60, -1, -1, -1,
+ 64, -1, 66, 67, -1, -1, -1, 71, 72, -1,
+ -1, 75, -1, -1, 78, 79, 80, 1, 82, 3,
+ -1, -1, -1, -1, 8, 9, -1, 11, 42, 43,
+ 44, 45, 46, 47, 48, 49, 50, 51, 52, -1,
+ -1, -1, -1, -1, -1, 29, -1, 31, -1, 33,
+ 34, -1, -1, -1, -1, -1, 40, -1, -1, 43,
+ -1, -1, -1, -1, 48, 49, 50, -1, -1, -1,
+ 54, 55, -1, -1, -1, 59, 60, -1, -1, -1,
+ 64, -1, 66, -1, -1, -1, -1, 71, -1, -1,
+ -1, 75, 1, -1, 3, 79, 80, -1, 82, 8,
+ 9, -1, 11, 1, -1, -1, 4, -1, 6, 7,
-1, -1, -1, -1, 12, 13, 14, -1, -1, -1,
- -1, -1, 1, -1, -1, 4, 5, 6, 7, 27,
- 28, -1, 30, 12, 13, 14, -1, -1, 36, 46,
- 47, 48, 49, 50, 51, 52, -1, 45, -1, 28,
- -1, 30, -1, 4, -1, 6, 7, -1, -1, -1,
- -1, 12, 13, 14, -1, -1, 45, -1, -1, 67,
- -1, -1, -1, -1, 72, -1, -1, 28, -1, 77,
- -1, -1, -1, 81, 82, -1, 1, -1, 67, 4,
- 5, 6, 7, 72, 45, -1, -1, 12, 13, 14,
- -1, -1, -1, 82, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 28, 3, 30, 67, -1, -1, 8,
- 9, 72, 11, -1, -1, -1, 77, 78, -1, -1,
- 45, -1, -1, -1, -1, -1, -1, -1, -1, -1,
29, -1, 31, -1, 33, 34, -1, -1, -1, -1,
- -1, 40, 67, -1, 43, -1, -1, 72, -1, 48,
- 49, 50, -1, -1, -1, 54, 55, 82, -1, -1,
- 59, 60, -1, 3, -1, 64, -1, 66, 8, 9,
- -1, 11, 71, -1, -1, -1, 75, -1, -1, -1,
- 79, 80, -1, -1, 83, -1, -1, -1, -1, 29,
- -1, 31, -1, 33, 34, -1, -1, -1, -1, -1,
- 40, -1, -1, 43, -1, -1, -1, -1, 48, 49,
- 50, -1, -1, -1, 54, 55, -1, -1, -1, 59,
- 60, -1, 3, -1, 64, -1, 66, 8, 9, -1,
- 11, 71, -1, -1, -1, 75, -1, -1, -1, 79,
- 80, -1, -1, 83, -1, -1, -1, -1, 29, -1,
- 31, -1, 33, 34, -1, -1, -1, -1, -1, 40,
- -1, -1, 43, -1, -1, -1, -1, 48, 49, 50,
- -1, -1, -1, 54, 55, -1, -1, -1, 59, 60,
- -1, 3, -1, 64, -1, 66, 8, 9, -1, 11,
- 71, -1, -1, -1, 75, -1, -1, -1, 79, 80,
- -1, -1, 83, -1, -1, -1, -1, 29, -1, 31,
- -1, 33, 34, -1, -1, -1, -1, -1, 40, -1,
- -1, 43, -1, -1, -1, -1, 48, 49, 50, -1,
- -1, -1, 54, 55, -1, -1, -1, 59, 60, -1,
- 3, -1, 64, -1, 66, 8, 9, -1, 11, 71,
- -1, -1, -1, 75, -1, -1, -1, 79, 80, -1,
- -1, 83, -1, -1, -1, -1, 29, -1, 31, -1,
- 33, 34, -1, -1, -1, -1, -1, 40, -1, -1,
- 43, -1, -1, -1, -1, 48, 49, 50, -1, -1,
- -1, 54, 55, -1, -1, -1, 59, 60, -1, -1,
- -1, 64, -1, 66, -1, -1, -1, -1, 71, -1,
- -1, -1, 75, -1, -1, -1, 79, 80, -1, -1,
- 83, 3, 4, 5, 6, 7, 8, 9, -1, 11,
- 12, 13, 14, 15, -1, 17, 18, 19, 20, 21,
- 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- -1, 33, 34, -1, -1, -1, -1, -1, 40, -1,
- -1, 43, -1, 45, -1, -1, 48, 49, 50, -1,
- -1, -1, 54, 55, -1, -1, -1, 59, 60, -1,
- -1, -1, 64, -1, 66, 67, -1, -1, -1, 71,
- 72, -1, -1, 75, -1, 77, -1, 79, 80, -1,
- 82, 3, 4, -1, -1, -1, 8, 9, -1, 11,
- -1, -1, -1, 15, -1, 17, 18, 19, 20, 21,
- 22, 23, 24, 25, 26, 27, -1, 29, -1, 31,
- -1, 33, 34, -1, -1, -1, -1, -1, 40, -1,
- -1, 43, -1, -1, -1, -1, 48, 49, 50, -1,
- -1, -1, 54, 55, -1, 3, -1, 59, 60, -1,
- 8, 9, 64, 11, 66, 67, -1, -1, -1, 71,
- 72, -1, -1, 75, -1, 77, -1, 79, 80, -1,
- 82, 29, -1, 31, -1, 33, 34, -1, -1, -1,
- -1, -1, 40, -1, -1, 43, -1, -1, -1, -1,
- 48, 49, 50, -1, -1, -1, 54, 55, -1, -1,
- -1, 59, 60, -1, -1, -1, 64, -1, 66, -1,
- -1, -1, -1, 71, -1, -1, -1, 75, -1, -1,
- -1, 79, 80, -1, 82, 3, 4, -1, 6, 7,
- -1, -1, -1, 11, 12, 13, 14, 15, 16, 17,
- 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
- 28, 29, -1, 3, 4, 5, 6, 7, 8, 9,
- 38, 11, 12, 13, 14, 4, 5, 6, 7, -1,
- -1, -1, -1, 12, 13, 14, -1, -1, 28, 29,
- 30, 31, -1, 33, 34, -1, -1, -1, -1, 28,
- 40, 30, -1, 43, 72, 45, -1, -1, 48, 49,
- 50, -1, -1, 81, 54, 55, 45, -1, -1, 59,
- 60, -1, -1, -1, 64, -1, 66, 67, -1, -1,
- -1, 71, 72, -1, -1, 75, -1, -1, 67, 79,
- 80, 3, 4, 72, 6, 7, 8, 9, 77, 11,
- 12, 13, 14, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, 28, 29, -1, 31,
- -1, 33, 34, -1, -1, -1, -1, -1, 40, -1,
- -1, 43, -1, 45, -1, -1, 48, 49, 50, -1,
- -1, -1, 54, 55, -1, 3, -1, 59, 60, -1,
- 8, 9, 64, 11, 66, 67, -1, -1, -1, 71,
- 72, -1, -1, 75, -1, -1, -1, 79, 80, -1,
- -1, 29, -1, 31, -1, 33, 34, -1, -1, -1,
- -1, -1, 40, -1, -1, 43, -1, -1, -1, -1,
- 48, 49, 50, -1, -1, -1, 54, 55, -1, 3,
- -1, 59, 60, -1, 8, 9, 64, 11, 66, 67,
- -1, -1, -1, 71, -1, -1, -1, 75, -1, -1,
- -1, 79, 80, -1, -1, 29, -1, 31, -1, 33,
- 34, -1, -1, -1, -1, -1, 40, -1, -1, 43,
+ 28, 40, -1, 31, 43, -1, -1, -1, -1, 48,
+ 49, 50, -1, -1, -1, 54, 55, 45, -1, -1,
+ 59, 60, -1, -1, -1, 64, -1, 66, -1, -1,
+ -1, -1, 71, -1, -1, -1, 75, -1, -1, 67,
+ 79, 80, 1, 82, 72, 4, 5, 6, 7, 77,
+ 78, -1, -1, 12, 13, 14, -1, -1, -1, -1,
+ -1, 1, -1, -1, 4, 5, 6, 7, 27, 28,
+ -1, 30, 12, 13, 14, -1, -1, 36, 45, 46,
+ 47, 48, 49, 50, 51, 52, 45, 27, 28, -1,
+ 30, -1, -1, -1, -1, -1, 36, -1, -1, -1,
+ 59, 60, -1, -1, -1, 45, -1, -1, 67, -1,
+ -1, -1, -1, 72, -1, -1, -1, -1, 77, 59,
+ 60, -1, 81, 82, -1, -1, -1, 67, -1, -1,
+ -1, -1, 72, -1, -1, -1, -1, 77, -1, -1,
+ 1, 81, 82, 4, 5, 6, 7, -1, -1, -1,
+ -1, 12, 13, 14, -1, -1, -1, -1, -1, 1,
+ -1, -1, 4, 5, 6, 7, 27, 28, -1, 30,
+ 12, 13, 14, -1, -1, 36, 46, 47, 48, 49,
+ 50, 51, 52, -1, 45, -1, 28, 1, 30, -1,
+ 4, 5, 6, 7, -1, -1, -1, -1, 12, 13,
+ 14, -1, -1, 45, -1, -1, 67, -1, -1, -1,
+ -1, 72, -1, -1, 28, -1, 77, -1, -1, -1,
+ 81, 82, -1, -1, -1, 67, -1, -1, -1, 3,
+ 72, 45, -1, -1, 8, 9, -1, 11, -1, -1,
+ 82, 43, 44, 45, 46, 47, 48, 49, 50, 51,
+ 52, -1, -1, 67, -1, 29, -1, 31, 72, 33,
+ 34, -1, -1, -1, -1, -1, 40, -1, 82, 43,
-1, -1, -1, -1, 48, 49, 50, -1, -1, -1,
- 54, 55, -1, 3, -1, 59, 60, -1, 8, 9,
- 64, 11, 66, -1, -1, -1, -1, 71, -1, -1,
- -1, 75, -1, 77, -1, 79, 80, -1, -1, 29,
- -1, 31, -1, 33, 34, -1, -1, -1, -1, -1,
- 40, -1, -1, 43, -1, -1, -1, -1, 48, 49,
- 50, -1, -1, -1, 54, 55, -1, 3, -1, 59,
- 60, -1, 8, 9, 64, 11, 66, -1, -1, -1,
- -1, 71, -1, -1, -1, 75, -1, -1, -1, 79,
- 80, -1, -1, 29, -1, 31, -1, 33, 34, -1,
+ 54, 55, -1, -1, -1, 59, 60, -1, 3, -1,
+ 64, -1, 66, 8, 9, -1, 11, 71, -1, -1,
+ -1, 75, -1, -1, -1, 79, 80, -1, -1, 83,
+ -1, -1, -1, -1, 29, -1, 31, -1, 33, 34,
+ -1, -1, -1, -1, -1, 40, -1, -1, 43, -1,
+ -1, -1, -1, 48, 49, 50, -1, -1, -1, 54,
+ 55, -1, -1, -1, 59, 60, -1, 3, -1, 64,
+ -1, 66, 8, 9, -1, 11, 71, -1, -1, -1,
+ 75, -1, -1, -1, 79, 80, -1, -1, 83, -1,
+ -1, -1, -1, 29, -1, 31, -1, 33, 34, -1,
-1, -1, -1, -1, 40, -1, -1, 43, -1, -1,
-1, -1, 48, 49, 50, -1, -1, -1, 54, 55,
- -1, 3, -1, 59, 60, -1, 8, 9, 64, 11,
- 66, -1, -1, -1, -1, 71, -1, -1, -1, 75,
- -1, -1, -1, 79, 80, -1, -1, 29, -1, 31,
- -1, 33, 34, -1, -1, -1, -1, -1, 40, -1,
- -1, 43, -1, -1, -1, -1, 48, 49, 50, -1,
- -1, -1, 54, 55, -1, 3, -1, 59, 60, -1,
- 8, 9, 64, 11, 66, -1, -1, -1, -1, 71,
- -1, -1, -1, 75, -1, -1, -1, 79, 80, -1,
+ -1, -1, -1, 59, 60, -1, 3, -1, 64, -1,
+ 66, 8, 9, -1, 11, 71, -1, -1, -1, 75,
+ -1, -1, -1, 79, 80, -1, -1, 83, -1, -1,
+ -1, -1, 29, -1, 31, -1, 33, 34, -1, -1,
+ -1, -1, -1, 40, -1, -1, 43, -1, -1, -1,
+ -1, 48, 49, 50, -1, -1, -1, 54, 55, -1,
+ -1, -1, 59, 60, -1, 3, -1, 64, -1, 66,
+ 8, 9, -1, 11, 71, -1, -1, -1, 75, -1,
+ -1, -1, 79, 80, -1, -1, 83, -1, -1, -1,
-1, 29, -1, 31, -1, 33, 34, -1, -1, -1,
-1, -1, 40, -1, -1, 43, -1, -1, -1, -1,
48, 49, 50, -1, -1, -1, 54, 55, -1, -1,
-1, 59, 60, -1, -1, -1, 64, -1, 66, -1,
-1, -1, -1, 71, -1, -1, -1, 75, -1, -1,
- 1, 79, 80, 4, -1, 6, 7, -1, -1, -1,
- -1, 12, 13, 14, -1, -1, -1, -1, 1, -1,
- -1, 4, -1, 6, 7, -1, -1, 28, -1, 12,
- 13, 14, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, 45, 28, -1, -1, -1, -1,
- -1, -1, 1, -1, 3, 4, 5, 6, 7, -1,
- -1, -1, 45, 12, 13, 14, 67, 68, 69, 70,
- -1, 72, -1, -1, -1, -1, 77, 78, 27, 28,
- -1, 30, 31, -1, 67, 68, 69, 70, -1, 72,
- -1, -1, -1, -1, 77, 78, 45, -1, -1, 48,
- 49, 50, -1, -1, -1, -1, -1, -1, -1, -1,
- 59, -1, 61, 62, 63, -1, -1, -1, 67, -1,
- -1, -1, 71, 72, 73, 74, -1, 1, 77, 3,
+ -1, 79, 80, -1, -1, 83, 3, 4, 5, 6,
+ 7, 8, 9, -1, 11, 12, 13, 14, 15, -1,
+ 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
+ 27, 28, 29, 30, 31, -1, 33, 34, -1, -1,
+ -1, -1, -1, 40, -1, -1, 43, -1, 45, -1,
+ -1, 48, 49, 50, -1, -1, -1, 54, 55, -1,
+ -1, -1, 59, 60, -1, -1, -1, 64, -1, 66,
+ 67, -1, -1, -1, 71, 72, -1, -1, 75, -1,
+ 77, -1, 79, 80, -1, 82, 3, 4, -1, -1,
+ -1, 8, 9, -1, 11, -1, -1, -1, 15, -1,
+ 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
+ 27, -1, 29, -1, 31, -1, 33, 34, -1, -1,
+ -1, -1, -1, 40, -1, -1, 43, -1, -1, -1,
+ -1, 48, 49, 50, -1, -1, -1, 54, 55, -1,
+ 3, -1, 59, 60, -1, 8, 9, 64, 11, 66,
+ 67, -1, -1, -1, 71, 72, -1, -1, 75, -1,
+ 77, -1, 79, 80, -1, 82, 29, -1, 31, -1,
+ 33, 34, -1, -1, -1, -1, -1, 40, -1, -1,
+ 43, -1, -1, -1, -1, 48, 49, 50, -1, -1,
+ -1, 54, 55, -1, -1, -1, 59, 60, -1, -1,
+ -1, 64, -1, 66, -1, -1, -1, -1, 71, -1,
+ -1, -1, 75, -1, -1, -1, 79, 80, -1, 82,
+ 3, 4, -1, 6, 7, -1, -1, -1, 11, 12,
+ 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
+ 23, 24, 25, 26, 27, 28, 29, -1, 3, 4,
+ 5, 6, 7, 8, 9, 38, 11, 12, 13, 14,
4, 5, 6, 7, -1, -1, -1, -1, 12, 13,
- 14, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, 28, 1, 30, 3, 4, 5,
+ 14, -1, -1, 28, 29, 30, 31, -1, 33, 34,
+ -1, -1, -1, -1, 28, 40, 30, -1, 43, 72,
+ 45, -1, -1, 48, 49, 50, -1, -1, 81, 54,
+ 55, 45, -1, -1, 59, 60, -1, -1, -1, 64,
+ -1, 66, 67, -1, -1, -1, 71, 72, -1, -1,
+ 75, -1, -1, 67, 79, 80, 3, 4, 72, 6,
+ 7, 8, 9, 77, 11, 12, 13, 14, 44, 45,
+ 46, 47, 48, 49, 50, 51, 52, -1, -1, -1,
+ -1, 28, 29, -1, 31, -1, 33, 34, -1, -1,
+ -1, -1, -1, 40, -1, -1, 43, -1, 45, -1,
+ -1, 48, 49, 50, -1, -1, -1, 54, 55, -1,
+ 3, -1, 59, 60, -1, 8, 9, 64, 11, 66,
+ 67, -1, -1, -1, 71, 72, -1, -1, 75, -1,
+ -1, -1, 79, 80, -1, -1, 29, -1, 31, -1,
+ 33, 34, -1, -1, -1, -1, -1, 40, -1, -1,
+ 43, -1, -1, -1, -1, 48, 49, 50, -1, -1,
+ -1, 54, 55, -1, 3, -1, 59, 60, -1, 8,
+ 9, 64, 11, 66, 67, -1, -1, -1, 71, -1,
+ -1, -1, 75, -1, -1, -1, 79, 80, -1, -1,
+ 29, -1, 31, -1, 33, 34, -1, -1, -1, -1,
+ -1, 40, -1, -1, 43, -1, -1, -1, -1, 48,
+ 49, 50, -1, -1, -1, 54, 55, -1, 3, -1,
+ 59, 60, -1, 8, 9, 64, 11, 66, -1, -1,
+ -1, -1, 71, -1, -1, -1, 75, -1, 77, -1,
+ 79, 80, -1, -1, 29, -1, 31, -1, 33, 34,
+ -1, -1, -1, -1, -1, 40, -1, -1, 43, -1,
+ -1, -1, -1, 48, 49, 50, -1, -1, -1, 54,
+ 55, -1, 3, -1, 59, 60, -1, 8, 9, 64,
+ 11, 66, -1, -1, -1, -1, 71, -1, -1, -1,
+ 75, -1, -1, -1, 79, 80, -1, -1, 29, -1,
+ 31, -1, 33, 34, -1, -1, -1, -1, -1, 40,
+ -1, -1, 43, -1, -1, -1, -1, 48, 49, 50,
+ -1, -1, -1, 54, 55, -1, 3, -1, 59, 60,
+ -1, 8, 9, 64, 11, 66, -1, -1, -1, -1,
+ 71, -1, -1, -1, 75, -1, -1, -1, 79, 80,
+ -1, -1, 29, -1, 31, -1, 33, 34, -1, -1,
+ -1, -1, -1, 40, -1, -1, 43, -1, -1, -1,
+ -1, 48, 49, 50, -1, -1, -1, 54, 55, -1,
+ 3, -1, 59, 60, -1, 8, 9, 64, 11, 66,
+ -1, -1, -1, -1, 71, -1, -1, -1, 75, -1,
+ -1, -1, 79, 80, -1, -1, 29, -1, 31, -1,
+ 33, 34, -1, -1, -1, -1, -1, 40, -1, -1,
+ 43, -1, -1, -1, -1, 48, 49, 50, -1, -1,
+ -1, 54, 55, -1, -1, -1, 59, 60, -1, -1,
+ -1, 64, -1, 66, -1, -1, -1, -1, 71, -1,
+ -1, -1, 75, -1, -1, 1, 79, 80, 4, -1,
6, 7, -1, -1, -1, -1, 12, 13, 14, -1,
- -1, 45, -1, -1, 48, 49, 50, -1, -1, -1,
- -1, -1, 28, -1, 30, 59, -1, -1, -1, -1,
+ -1, -1, -1, 1, -1, -1, 4, -1, 6, 7,
+ -1, -1, 28, -1, 12, 13, 14, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, 45,
+ 28, -1, -1, -1, -1, -1, -1, 1, -1, 3,
+ 4, 5, 6, 7, -1, -1, -1, 45, 12, 13,
+ 14, 67, 68, 69, 70, -1, 72, -1, -1, -1,
+ -1, 77, 78, 27, 28, -1, 30, 31, -1, 67,
+ 68, 69, 70, -1, 72, -1, -1, -1, -1, 77,
+ 78, 45, -1, -1, 48, 49, 50, -1, -1, -1,
+ -1, -1, -1, -1, -1, 59, -1, 61, 62, 63,
+ -1, -1, -1, 67, -1, -1, -1, 71, 72, 73,
+ 74, -1, 1, 77, 3, 4, 5, 6, 7, -1,
+ -1, -1, -1, 12, 13, 14, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, 28,
+ 1, 30, 3, 4, 5, 6, 7, -1, -1, -1,
+ -1, 12, 13, 14, -1, -1, 45, -1, -1, 48,
+ 49, 50, -1, -1, -1, -1, -1, 28, 1, 30,
+ 59, 4, 5, 6, 7, -1, -1, 10, 67, 12,
+ 13, 14, -1, 72, 45, -1, -1, -1, 77, 50,
+ -1, 4, 5, 6, 7, 28, -1, 30, 59, 12,
+ 13, 14, -1, -1, -1, -1, 67, -1, -1, -1,
+ -1, 72, 45, -1, -1, 28, 77, 30, -1, -1,
+ 4, 5, 6, 7, -1, -1, -1, -1, 12, 13,
+ 14, -1, 45, -1, 67, -1, -1, -1, -1, 72,
+ -1, -1, -1, 76, 28, -1, 30, -1, 4, 5,
+ 6, 7, -1, -1, 67, -1, 12, 13, 14, 72,
+ -1, 45, -1, -1, 77, 1, -1, -1, 4, -1,
+ 6, 7, 28, -1, -1, -1, 12, 13, 14, -1,
-1, -1, -1, 67, -1, -1, -1, -1, 72, 45,
- -1, -1, -1, 77, 50, 1, -1, 3, 4, 5,
- 6, 7, -1, 59, 10, -1, 12, 13, 14, -1,
- -1, 67, -1, -1, 1, -1, 72, 4, 5, 6,
- 7, 77, 28, 10, 30, 12, 13, 14, 4, 5,
- 6, 7, -1, -1, -1, -1, 12, 13, 14, 45,
- -1, 28, -1, 30, -1, -1, -1, 4, 5, 6,
- 7, -1, 28, -1, 30, 12, 13, 14, 45, -1,
- -1, 67, -1, -1, -1, -1, 72, -1, -1, 45,
- 76, 28, -1, 30, -1, -1, -1, -1, -1, -1,
- 67, -1, -1, -1, -1, 72, -1, -1, 45, 76,
+ -1, -1, 28, 77, -1, 31, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, 45,
-1, 67, -1, -1, -1, -1, 72, -1, -1, -1,
- -1, 77, -1, -1, -1, -1, -1, -1, -1, -1,
- 67, -1, -1, 3, 4, 72, 6, 7, -1, -1,
- 77, 11, 12, 13, 14, 15, 16, 17, 18, 19,
+ -1, 77, -1, -1, -1, -1, -1, -1, -1, 3,
+ 4, 67, 6, 7, -1, -1, 72, 11, 12, 13,
+ 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
+ 24, 25, 26, 27, 28, 29, -1, 3, 4, -1,
+ 6, 7, -1, -1, 38, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
+ 26, 27, 28, 29, -1, 59, -1, -1, -1, -1,
+ -1, -1, 38, 3, 4, -1, 6, 7, 72, -1,
+ -1, 11, 12, 13, 14, 15, 16, 17, 18, 19,
20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
- -1, 3, 4, -1, 6, 7, -1, -1, 38, 11,
+ -1, 3, 4, -1, 6, 7, 72, -1, 38, 11,
12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
- 22, 23, 24, 25, 26, 27, 28, 29, -1, 59,
- -1, -1, -1, -1, -1, -1, 38, 3, 4, -1,
- 6, 7, 72, -1, -1, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
- 26, 27, 28, 29, -1, 3, 4, -1, 6, 7,
- 72, -1, 38, 11, 12, 13, 14, 15, 16, 17,
- 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
- 28, 29, -1, -1, 4, -1, 6, 7, -1, -1,
- 38, -1, 12, 13, 14, -1, 72, 4, 5, 6,
- 7, -1, -1, 10, -1, 12, 13, 14, 28, 4,
- 5, 6, 7, -1, -1, 10, -1, 12, 13, 14,
- -1, 28, -1, 30, 72, 45, -1, -1, -1, -1,
- 50, -1, -1, 28, -1, 30, -1, -1, 45, 59,
- 60, -1, -1, -1, -1, -1, -1, 67, -1, -1,
- 45, -1, 72, -1, 4, 5, 6, 7, -1, -1,
- 67, -1, 12, 13, 14, 72, 4, 5, 6, 7,
- -1, -1, 67, -1, 12, 13, 14, 72, 28, 4,
- 30, 6, 7, -1, -1, -1, -1, 12, 13, 14,
- 28, -1, -1, -1, -1, 45, -1, -1, -1, -1,
- -1, -1, -1, 28, -1, -1, -1, 45, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, 67, -1, -1,
- 45, -1, 72, 10, -1, -1, -1, -1, -1, 67,
- -1, -1, -1, -1, 72, -1, -1, -1, -1, -1,
- -1, -1, 67, -1, -1, -1, -1, 72, 35, 36,
- 37, 38, 39, 40, 41, 42, 43, 44, 45, 46,
- 47, 48, 49, 50, 51, 52, 30, -1, -1, -1,
- -1, 35, 36, 37, -1, 39, 40, 41, 42, 43,
- 44, 45, 46, 47, 48, 49, 50, 51, 52, 35,
+ 22, 23, 24, 25, 26, 27, 28, 29, -1, -1,
+ -1, 4, 5, 6, 7, -1, 38, 10, -1, 12,
+ 13, 14, 72, 4, 5, 6, 7, -1, -1, 10,
+ -1, 12, 13, 14, -1, 28, -1, 30, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 28, -1, 30,
+ 72, -1, 45, 4, 5, 6, 7, 4, 5, 6,
+ 7, 12, 13, 14, 45, 12, 13, 14, -1, -1,
+ -1, -1, -1, -1, 67, -1, -1, 28, -1, 72,
+ -1, 28, -1, 30, -1, -1, 67, 4, -1, 6,
+ 7, 72, -1, -1, 45, 12, 13, 14, 45, -1,
+ -1, -1, -1, -1, 10, -1, -1, -1, -1, -1,
+ -1, 28, -1, -1, -1, -1, 67, -1, -1, -1,
+ 67, 72, -1, -1, -1, 72, -1, -1, 45, 35,
36, 37, 38, 39, 40, 41, 42, 43, 44, 45,
- 46, 47, 48, 49, 50, 51, 52, 35, 36, 37,
- -1, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52
+ 46, 47, 48, 49, 50, 51, 52, 30, -1, -1,
+ 67, -1, 35, 36, 37, 72, 39, 40, 41, 42,
+ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
+ 35, 36, 37, 38, 39, 40, 41, 42, 43, 44,
+ 45, 46, 47, 48, 49, 50, 51, 52, 35, 36,
+ 37, -1, 39, 40, 41, 42, 43, 44, 45, 46,
+ 47, 48, 49, 50, 51, 52
};
/* -*-C-*- Note some compilers choke on comments on `#line' lines. */
-#line 3 "/usr/cygnus/progressive-98r1/share/bison.simple"
+#line 3 "/usr/lib/bison.simple"
/* Skeleton output parser for bison,
Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc.
@@ -1849,7 +1850,7 @@ __yy_memcpy (char *to, char *from, int count)
#endif
#endif
-#line 196 "/usr/cygnus/progressive-98r1/share/bison.simple"
+#line 196 "/usr/lib/bison.simple"
/* The user can define YYPARSE_PARAM as the name of an argument to be passed
into yyparse. The argument should have type void *.
@@ -2439,7 +2440,7 @@ case 64:
tree type = yyvsp[-5].ttype;
finish_init ();
- if (pedantic)
+ if (pedantic && ! flag_isoc9x)
pedwarn ("ANSI C forbids constructor expressions");
if (TYPE_NAME (type) != 0)
{
@@ -3199,28 +3200,28 @@ case 203:
{ if (pedantic)
pedwarn ("ANSI C forbids empty initializer braces"); ;
break;}
-case 207:
-#line 1219 "objc-parse.y"
-{ process_init_element (yyvsp[0].ttype); ;
- break;}
-case 208:
+case 209:
#line 1221 "objc-parse.y"
+{ set_init_label (yyvsp[-1].ttype); ;
+ break;}
+case 212:
+#line 1228 "objc-parse.y"
{ push_init_level (0); ;
break;}
-case 209:
-#line 1223 "objc-parse.y"
+case 213:
+#line 1230 "objc-parse.y"
{ process_init_element (pop_init_level (0)); ;
break;}
-case 211:
-#line 1229 "objc-parse.y"
-{ set_init_label (yyvsp[-1].ttype); ;
- break;}
-case 213:
+case 214:
#line 1232 "objc-parse.y"
-{ set_init_label (yyvsp[-1].ttype); ;
+{ process_init_element (yyvsp[0].ttype); ;
+ break;}
+case 218:
+#line 1243 "objc-parse.y"
+{ set_init_label (yyvsp[0].ttype); ;
break;}
-case 215:
-#line 1238 "objc-parse.y"
+case 219:
+#line 1251 "objc-parse.y"
{ push_c_function_context ();
if (! start_function (current_declspecs, yyvsp[0].ttype,
prefix_attributes, NULL_TREE, 1))
@@ -3230,17 +3231,17 @@ case 215:
}
reinit_parse_for_function (); ;
break;}
-case 216:
-#line 1247 "objc-parse.y"
+case 220:
+#line 1260 "objc-parse.y"
{ store_parm_decls (); ;
break;}
-case 217:
-#line 1255 "objc-parse.y"
+case 221:
+#line 1268 "objc-parse.y"
{ finish_function (1);
pop_c_function_context (); ;
break;}
-case 218:
-#line 1261 "objc-parse.y"
+case 222:
+#line 1274 "objc-parse.y"
{ push_c_function_context ();
if (! start_function (current_declspecs, yyvsp[0].ttype,
prefix_attributes, NULL_TREE, 1))
@@ -3250,197 +3251,198 @@ case 218:
}
reinit_parse_for_function (); ;
break;}
-case 219:
-#line 1270 "objc-parse.y"
+case 223:
+#line 1283 "objc-parse.y"
{ store_parm_decls (); ;
break;}
-case 220:
-#line 1278 "objc-parse.y"
+case 224:
+#line 1291 "objc-parse.y"
{ finish_function (1);
pop_c_function_context (); ;
break;}
-case 223:
-#line 1294 "objc-parse.y"
+case 227:
+#line 1307 "objc-parse.y"
{ yyval.ttype = yyvsp[-1].ttype; ;
break;}
-case 224:
-#line 1296 "objc-parse.y"
+case 228:
+#line 1309 "objc-parse.y"
{ yyval.ttype = build_nt (CALL_EXPR, yyvsp[-2].ttype, yyvsp[0].ttype, NULL_TREE); ;
break;}
-case 225:
-#line 1301 "objc-parse.y"
+case 229:
+#line 1314 "objc-parse.y"
{ yyval.ttype = build_nt (ARRAY_REF, yyvsp[-3].ttype, yyvsp[-1].ttype); ;
break;}
-case 226:
-#line 1303 "objc-parse.y"
+case 230:
+#line 1316 "objc-parse.y"
{ yyval.ttype = build_nt (ARRAY_REF, yyvsp[-2].ttype, NULL_TREE); ;
break;}
-case 227:
-#line 1305 "objc-parse.y"
+case 231:
+#line 1318 "objc-parse.y"
{ yyval.ttype = make_pointer_declarator (yyvsp[-1].ttype, yyvsp[0].ttype); ;
break;}
-case 228:
-#line 1312 "objc-parse.y"
+case 232:
+#line 1325 "objc-parse.y"
{ yyval.ttype = yyvsp[0].ttype; ;
break;}
-case 231:
-#line 1324 "objc-parse.y"
+case 235:
+#line 1337 "objc-parse.y"
{ yyval.ttype = build_nt (CALL_EXPR, yyvsp[-2].ttype, yyvsp[0].ttype, NULL_TREE); ;
break;}
-case 232:
-#line 1329 "objc-parse.y"
+case 236:
+#line 1342 "objc-parse.y"
{ yyval.ttype = build_nt (ARRAY_REF, yyvsp[-3].ttype, yyvsp[-1].ttype); ;
break;}
-case 233:
-#line 1331 "objc-parse.y"
+case 237:
+#line 1344 "objc-parse.y"
{ yyval.ttype = build_nt (ARRAY_REF, yyvsp[-2].ttype, NULL_TREE); ;
break;}
-case 234:
-#line 1333 "objc-parse.y"
+case 238:
+#line 1346 "objc-parse.y"
{ yyval.ttype = make_pointer_declarator (yyvsp[-1].ttype, yyvsp[0].ttype); ;
break;}
-case 235:
-#line 1340 "objc-parse.y"
+case 239:
+#line 1353 "objc-parse.y"
{ yyval.ttype = yyvsp[0].ttype; ;
break;}
-case 237:
-#line 1349 "objc-parse.y"
+case 241:
+#line 1362 "objc-parse.y"
{ yyval.ttype = build_nt (CALL_EXPR, yyvsp[-2].ttype, yyvsp[0].ttype, NULL_TREE); ;
break;}
-case 238:
-#line 1354 "objc-parse.y"
+case 242:
+#line 1367 "objc-parse.y"
{ yyval.ttype = yyvsp[-1].ttype; ;
break;}
-case 239:
-#line 1356 "objc-parse.y"
+case 243:
+#line 1369 "objc-parse.y"
{ yyval.ttype = make_pointer_declarator (yyvsp[-1].ttype, yyvsp[0].ttype); ;
break;}
-case 240:
-#line 1358 "objc-parse.y"
+case 244:
+#line 1371 "objc-parse.y"
{ yyval.ttype = build_nt (ARRAY_REF, yyvsp[-3].ttype, yyvsp[-1].ttype); ;
break;}
-case 241:
-#line 1360 "objc-parse.y"
+case 245:
+#line 1373 "objc-parse.y"
{ yyval.ttype = build_nt (ARRAY_REF, yyvsp[-2].ttype, NULL_TREE); ;
break;}
-case 242:
-#line 1367 "objc-parse.y"
+case 246:
+#line 1380 "objc-parse.y"
{ yyval.ttype = yyvsp[0].ttype; ;
break;}
-case 244:
-#line 1373 "objc-parse.y"
+case 248:
+#line 1386 "objc-parse.y"
{ yyval.ttype = NULL_TREE; ;
break;}
-case 245:
-#line 1375 "objc-parse.y"
+case 249:
+#line 1388 "objc-parse.y"
{ yyval.ttype = yyvsp[0].ttype; ;
break;}
-case 246:
-#line 1380 "objc-parse.y"
+case 250:
+#line 1393 "objc-parse.y"
{ yyval.ttype = NULL_TREE; ;
break;}
-case 247:
-#line 1382 "objc-parse.y"
+case 251:
+#line 1395 "objc-parse.y"
{ yyval.ttype = yyvsp[0].ttype; ;
break;}
-case 248:
-#line 1387 "objc-parse.y"
+case 252:
+#line 1400 "objc-parse.y"
{ yyval.ttype = NULL_TREE; ;
break;}
-case 249:
-#line 1389 "objc-parse.y"
+case 253:
+#line 1402 "objc-parse.y"
{ yyval.ttype = yyvsp[0].ttype; ;
break;}
-case 250:
-#line 1394 "objc-parse.y"
+case 254:
+#line 1407 "objc-parse.y"
{ yyval.ttype = start_struct (RECORD_TYPE, yyvsp[-1].ttype);
/* Start scope of tag before parsing components. */
;
break;}
-case 251:
-#line 1398 "objc-parse.y"
+case 255:
+#line 1411 "objc-parse.y"
{ yyval.ttype = finish_struct (yyvsp[-3].ttype, yyvsp[-2].ttype, chainon (yyvsp[-6].ttype, yyvsp[0].ttype)); ;
break;}
-case 252:
-#line 1400 "objc-parse.y"
+case 256:
+#line 1413 "objc-parse.y"
{ yyval.ttype = finish_struct (start_struct (RECORD_TYPE, NULL_TREE),
yyvsp[-2].ttype, chainon (yyvsp[-4].ttype, yyvsp[0].ttype));
;
break;}
-case 253:
-#line 1404 "objc-parse.y"
+case 257:
+#line 1417 "objc-parse.y"
{ yyval.ttype = xref_tag (RECORD_TYPE, yyvsp[0].ttype); ;
break;}
-case 254:
-#line 1406 "objc-parse.y"
+case 258:
+#line 1419 "objc-parse.y"
{ yyval.ttype = start_struct (UNION_TYPE, yyvsp[-1].ttype); ;
break;}
-case 255:
-#line 1408 "objc-parse.y"
+case 259:
+#line 1421 "objc-parse.y"
{ yyval.ttype = finish_struct (yyvsp[-3].ttype, yyvsp[-2].ttype, chainon (yyvsp[-6].ttype, yyvsp[0].ttype)); ;
break;}
-case 256:
-#line 1410 "objc-parse.y"
+case 260:
+#line 1423 "objc-parse.y"
{ yyval.ttype = finish_struct (start_struct (UNION_TYPE, NULL_TREE),
yyvsp[-2].ttype, chainon (yyvsp[-4].ttype, yyvsp[0].ttype));
;
break;}
-case 257:
-#line 1414 "objc-parse.y"
+case 261:
+#line 1427 "objc-parse.y"
{ yyval.ttype = xref_tag (UNION_TYPE, yyvsp[0].ttype); ;
break;}
-case 258:
-#line 1416 "objc-parse.y"
+case 262:
+#line 1429 "objc-parse.y"
{ yyvsp[0].itype = suspend_momentary ();
yyval.ttype = start_enum (yyvsp[-1].ttype); ;
break;}
-case 259:
-#line 1419 "objc-parse.y"
+case 263:
+#line 1432 "objc-parse.y"
{ yyval.ttype= finish_enum (yyvsp[-4].ttype, nreverse (yyvsp[-3].ttype), chainon (yyvsp[-7].ttype, yyvsp[0].ttype));
resume_momentary (yyvsp[-5].itype); ;
break;}
-case 260:
-#line 1422 "objc-parse.y"
+case 264:
+#line 1435 "objc-parse.y"
{ yyvsp[0].itype = suspend_momentary ();
yyval.ttype = start_enum (NULL_TREE); ;
break;}
-case 261:
-#line 1425 "objc-parse.y"
+case 265:
+#line 1438 "objc-parse.y"
{ yyval.ttype= finish_enum (yyvsp[-4].ttype, nreverse (yyvsp[-3].ttype), chainon (yyvsp[-6].ttype, yyvsp[0].ttype));
resume_momentary (yyvsp[-5].itype); ;
break;}
-case 262:
-#line 1428 "objc-parse.y"
+case 266:
+#line 1441 "objc-parse.y"
{ yyval.ttype = xref_tag (ENUMERAL_TYPE, yyvsp[0].ttype); ;
break;}
-case 266:
-#line 1439 "objc-parse.y"
-{ if (pedantic) pedwarn ("comma at end of enumerator list"); ;
+case 270:
+#line 1452 "objc-parse.y"
+{ if (pedantic && ! flag_isoc9x)
+ pedwarn ("comma at end of enumerator list"); ;
break;}
-case 267:
-#line 1444 "objc-parse.y"
+case 271:
+#line 1458 "objc-parse.y"
{ yyval.ttype = yyvsp[0].ttype; ;
break;}
-case 268:
-#line 1446 "objc-parse.y"
+case 272:
+#line 1460 "objc-parse.y"
{ yyval.ttype = chainon (yyvsp[-1].ttype, yyvsp[0].ttype);
pedwarn ("no semicolon at end of struct or union"); ;
break;}
-case 269:
-#line 1451 "objc-parse.y"
+case 273:
+#line 1465 "objc-parse.y"
{ yyval.ttype = NULL_TREE; ;
break;}
-case 270:
-#line 1453 "objc-parse.y"
+case 274:
+#line 1467 "objc-parse.y"
{ yyval.ttype = chainon (yyvsp[-2].ttype, yyvsp[-1].ttype); ;
break;}
-case 271:
-#line 1455 "objc-parse.y"
+case 275:
+#line 1469 "objc-parse.y"
{ if (pedantic)
pedwarn ("extra semicolon in struct or union specified"); ;
break;}
-case 272:
-#line 1459 "objc-parse.y"
+case 276:
+#line 1473 "objc-parse.y"
{
tree interface = lookup_interface (yyvsp[-1].ttype);
@@ -3454,164 +3456,164 @@ case 272:
}
;
break;}
-case 273:
-#line 1484 "objc-parse.y"
+case 277:
+#line 1498 "objc-parse.y"
{ yyval.ttype = yyvsp[0].ttype;
current_declspecs = TREE_VALUE (declspec_stack);
prefix_attributes = TREE_PURPOSE (declspec_stack);
declspec_stack = TREE_CHAIN (declspec_stack);
resume_momentary (yyvsp[-1].itype); ;
break;}
-case 274:
-#line 1490 "objc-parse.y"
+case 278:
+#line 1504 "objc-parse.y"
{ if (pedantic)
pedwarn ("ANSI C forbids member declarations with no members");
shadow_tag(yyvsp[0].ttype);
yyval.ttype = NULL_TREE; ;
break;}
-case 275:
-#line 1495 "objc-parse.y"
+case 279:
+#line 1509 "objc-parse.y"
{ yyval.ttype = yyvsp[0].ttype;
current_declspecs = TREE_VALUE (declspec_stack);
prefix_attributes = TREE_PURPOSE (declspec_stack);
declspec_stack = TREE_CHAIN (declspec_stack);
resume_momentary (yyvsp[-1].itype); ;
break;}
-case 276:
-#line 1501 "objc-parse.y"
+case 280:
+#line 1515 "objc-parse.y"
{ if (pedantic)
pedwarn ("ANSI C forbids member declarations with no members");
shadow_tag(yyvsp[0].ttype);
yyval.ttype = NULL_TREE; ;
break;}
-case 277:
-#line 1506 "objc-parse.y"
+case 281:
+#line 1520 "objc-parse.y"
{ yyval.ttype = NULL_TREE; ;
break;}
-case 278:
-#line 1508 "objc-parse.y"
+case 282:
+#line 1522 "objc-parse.y"
{ yyval.ttype = yyvsp[0].ttype;
pedantic = yyvsp[-1].itype; ;
break;}
-case 280:
-#line 1515 "objc-parse.y"
+case 284:
+#line 1529 "objc-parse.y"
{ yyval.ttype = chainon (yyvsp[-2].ttype, yyvsp[0].ttype); ;
break;}
-case 281:
-#line 1520 "objc-parse.y"
+case 285:
+#line 1534 "objc-parse.y"
{ yyval.ttype = grokfield (yyvsp[-3].filename, yyvsp[-2].lineno, yyvsp[-1].ttype, current_declspecs, NULL_TREE);
decl_attributes (yyval.ttype, yyvsp[0].ttype, prefix_attributes); ;
break;}
-case 282:
-#line 1524 "objc-parse.y"
+case 286:
+#line 1538 "objc-parse.y"
{ yyval.ttype = grokfield (yyvsp[-5].filename, yyvsp[-4].lineno, yyvsp[-3].ttype, current_declspecs, yyvsp[-1].ttype);
decl_attributes (yyval.ttype, yyvsp[0].ttype, prefix_attributes); ;
break;}
-case 283:
-#line 1527 "objc-parse.y"
+case 287:
+#line 1541 "objc-parse.y"
{ yyval.ttype = grokfield (yyvsp[-4].filename, yyvsp[-3].lineno, NULL_TREE, current_declspecs, yyvsp[-1].ttype);
decl_attributes (yyval.ttype, yyvsp[0].ttype, prefix_attributes); ;
break;}
-case 285:
-#line 1539 "objc-parse.y"
+case 289:
+#line 1553 "objc-parse.y"
{ if (yyvsp[-2].ttype == error_mark_node)
yyval.ttype = yyvsp[-2].ttype;
else
yyval.ttype = chainon (yyvsp[0].ttype, yyvsp[-2].ttype); ;
break;}
-case 286:
-#line 1544 "objc-parse.y"
+case 290:
+#line 1558 "objc-parse.y"
{ yyval.ttype = error_mark_node; ;
break;}
-case 287:
-#line 1550 "objc-parse.y"
+case 291:
+#line 1564 "objc-parse.y"
{ yyval.ttype = build_enumerator (yyvsp[0].ttype, NULL_TREE); ;
break;}
-case 288:
-#line 1552 "objc-parse.y"
+case 292:
+#line 1566 "objc-parse.y"
{ yyval.ttype = build_enumerator (yyvsp[-2].ttype, yyvsp[0].ttype); ;
break;}
-case 289:
-#line 1557 "objc-parse.y"
+case 293:
+#line 1571 "objc-parse.y"
{ yyval.ttype = build_tree_list (yyvsp[-1].ttype, yyvsp[0].ttype); ;
break;}
-case 290:
-#line 1559 "objc-parse.y"
+case 294:
+#line 1573 "objc-parse.y"
{ yyval.ttype = build_tree_list (yyvsp[-1].ttype, yyvsp[0].ttype); ;
break;}
-case 291:
-#line 1564 "objc-parse.y"
+case 295:
+#line 1578 "objc-parse.y"
{ yyval.ttype = NULL_TREE; ;
break;}
-case 293:
-#line 1570 "objc-parse.y"
+case 297:
+#line 1584 "objc-parse.y"
{ yyval.ttype = tree_cons (NULL_TREE, yyvsp[0].ttype, NULL_TREE); ;
break;}
-case 294:
-#line 1572 "objc-parse.y"
+case 298:
+#line 1586 "objc-parse.y"
{ yyval.ttype = tree_cons (NULL_TREE, yyvsp[0].ttype, yyvsp[-1].ttype); ;
break;}
-case 295:
-#line 1577 "objc-parse.y"
+case 299:
+#line 1591 "objc-parse.y"
{ yyval.ttype = NULL_TREE; ;
break;}
-case 296:
-#line 1579 "objc-parse.y"
+case 300:
+#line 1593 "objc-parse.y"
{ yyval.ttype = tree_cons (NULL_TREE, yyvsp[0].ttype, yyvsp[-1].ttype); ;
break;}
-case 297:
-#line 1584 "objc-parse.y"
+case 301:
+#line 1598 "objc-parse.y"
{ yyval.ttype = yyvsp[-1].ttype; ;
break;}
-case 298:
-#line 1587 "objc-parse.y"
+case 302:
+#line 1601 "objc-parse.y"
{ yyval.ttype = make_pointer_declarator (yyvsp[-1].ttype, yyvsp[0].ttype); ;
break;}
-case 299:
-#line 1589 "objc-parse.y"
+case 303:
+#line 1603 "objc-parse.y"
{ yyval.ttype = make_pointer_declarator (yyvsp[0].ttype, NULL_TREE); ;
break;}
-case 300:
-#line 1591 "objc-parse.y"
+case 304:
+#line 1605 "objc-parse.y"
{ yyval.ttype = build_nt (CALL_EXPR, yyvsp[-2].ttype, yyvsp[0].ttype, NULL_TREE); ;
break;}
-case 301:
-#line 1593 "objc-parse.y"
+case 305:
+#line 1607 "objc-parse.y"
{ yyval.ttype = build_nt (ARRAY_REF, yyvsp[-3].ttype, yyvsp[-1].ttype); ;
break;}
-case 302:
-#line 1595 "objc-parse.y"
+case 306:
+#line 1609 "objc-parse.y"
{ yyval.ttype = build_nt (ARRAY_REF, yyvsp[-2].ttype, NULL_TREE); ;
break;}
-case 303:
-#line 1597 "objc-parse.y"
+case 307:
+#line 1611 "objc-parse.y"
{ yyval.ttype = build_nt (CALL_EXPR, NULL_TREE, yyvsp[0].ttype, NULL_TREE); ;
break;}
-case 304:
-#line 1599 "objc-parse.y"
+case 308:
+#line 1613 "objc-parse.y"
{ yyval.ttype = build_nt (ARRAY_REF, NULL_TREE, yyvsp[-1].ttype); ;
break;}
-case 305:
-#line 1601 "objc-parse.y"
+case 309:
+#line 1615 "objc-parse.y"
{ yyval.ttype = build_nt (ARRAY_REF, NULL_TREE, NULL_TREE); ;
break;}
-case 306:
-#line 1612 "objc-parse.y"
+case 310:
+#line 1626 "objc-parse.y"
{
if (pedantic && yyvsp[0].ends_in_label)
pedwarn ("ANSI C forbids label at end of compound statement");
;
break;}
-case 308:
-#line 1621 "objc-parse.y"
+case 312:
+#line 1635 "objc-parse.y"
{ yyval.ends_in_label = yyvsp[0].ends_in_label; ;
break;}
-case 309:
-#line 1623 "objc-parse.y"
+case 313:
+#line 1637 "objc-parse.y"
{ yyval.ends_in_label = 0; ;
break;}
-case 313:
-#line 1635 "objc-parse.y"
+case 317:
+#line 1649 "objc-parse.y"
{ emit_line_note (input_filename, lineno);
pushlevel (0);
clear_last_expr ();
@@ -3621,13 +3623,13 @@ case 313:
add_objc_decls ();
;
break;}
-case 315:
-#line 1650 "objc-parse.y"
+case 319:
+#line 1664 "objc-parse.y"
{ if (pedantic)
pedwarn ("ANSI C forbids label declarations"); ;
break;}
-case 318:
-#line 1661 "objc-parse.y"
+case 322:
+#line 1675 "objc-parse.y"
{ tree link;
for (link = yyvsp[-1].ttype; link; link = TREE_CHAIN (link))
{
@@ -3637,20 +3639,20 @@ case 318:
}
;
break;}
-case 319:
-#line 1675 "objc-parse.y"
+case 323:
+#line 1689 "objc-parse.y"
{;
break;}
-case 321:
-#line 1679 "objc-parse.y"
+case 325:
+#line 1693 "objc-parse.y"
{ compstmt_count++; ;
break;}
-case 322:
-#line 1682 "objc-parse.y"
+case 326:
+#line 1696 "objc-parse.y"
{ yyval.ttype = convert (void_type_node, integer_zero_node); ;
break;}
-case 323:
-#line 1684 "objc-parse.y"
+case 327:
+#line 1698 "objc-parse.y"
{ emit_line_note (input_filename, lineno);
expand_end_bindings (getdecls (), 1, 0);
yyval.ttype = poplevel (1, 1, 0);
@@ -3659,8 +3661,8 @@ case 323:
else
pop_momentary (); ;
break;}
-case 324:
-#line 1692 "objc-parse.y"
+case 328:
+#line 1706 "objc-parse.y"
{ emit_line_note (input_filename, lineno);
expand_end_bindings (getdecls (), kept_level_p (), 0);
yyval.ttype = poplevel (kept_level_p (), 0, 0);
@@ -3669,8 +3671,8 @@ case 324:
else
pop_momentary (); ;
break;}
-case 325:
-#line 1700 "objc-parse.y"
+case 329:
+#line 1714 "objc-parse.y"
{ emit_line_note (input_filename, lineno);
expand_end_bindings (getdecls (), kept_level_p (), 0);
yyval.ttype = poplevel (kept_level_p (), 0, 0);
@@ -3679,8 +3681,8 @@ case 325:
else
pop_momentary (); ;
break;}
-case 328:
-#line 1720 "objc-parse.y"
+case 332:
+#line 1734 "objc-parse.y"
{ emit_line_note (yyvsp[-5].filename, yyvsp[-4].lineno);
c_expand_start_cond (truthvalue_conversion (yyvsp[-1].ttype), 0,
compstmt_count);
@@ -3689,8 +3691,8 @@ case 328:
if_stmt_line = yyvsp[-4].lineno;
position_after_white_space (); ;
break;}
-case 329:
-#line 1734 "objc-parse.y"
+case 333:
+#line 1748 "objc-parse.y"
{ stmt_count++;
compstmt_count++;
emit_line_note (yyvsp[-2].filename, yyvsp[-1].lineno);
@@ -3699,44 +3701,44 @@ case 329:
expand_start_loop_continue_elsewhere (1);
position_after_white_space (); ;
break;}
-case 330:
-#line 1742 "objc-parse.y"
+case 334:
+#line 1756 "objc-parse.y"
{ expand_loop_continue_here (); ;
break;}
-case 331:
-#line 1746 "objc-parse.y"
+case 335:
+#line 1760 "objc-parse.y"
{ yyval.filename = input_filename; ;
break;}
-case 332:
-#line 1750 "objc-parse.y"
+case 336:
+#line 1764 "objc-parse.y"
{ yyval.lineno = lineno; ;
break;}
-case 333:
-#line 1755 "objc-parse.y"
+case 337:
+#line 1769 "objc-parse.y"
{ ;
break;}
-case 334:
-#line 1760 "objc-parse.y"
+case 338:
+#line 1774 "objc-parse.y"
{ ;
break;}
-case 335:
-#line 1765 "objc-parse.y"
+case 339:
+#line 1779 "objc-parse.y"
{ yyval.ends_in_label = yyvsp[0].ends_in_label; ;
break;}
-case 336:
-#line 1770 "objc-parse.y"
+case 340:
+#line 1784 "objc-parse.y"
{ yyval.ends_in_label = 0; ;
break;}
-case 337:
-#line 1772 "objc-parse.y"
+case 341:
+#line 1786 "objc-parse.y"
{ yyval.ends_in_label = 1; ;
break;}
-case 338:
-#line 1778 "objc-parse.y"
+case 342:
+#line 1792 "objc-parse.y"
{ stmt_count++; ;
break;}
-case 340:
-#line 1781 "objc-parse.y"
+case 344:
+#line 1795 "objc-parse.y"
{ stmt_count++;
emit_line_note (yyvsp[-3].filename, yyvsp[-2].lineno);
/* It appears that this should not be done--that a non-lvalue array
@@ -3754,20 +3756,20 @@ case 340:
iterator_expand (yyvsp[-1].ttype);
clear_momentary (); ;
break;}
-case 341:
-#line 1798 "objc-parse.y"
+case 345:
+#line 1812 "objc-parse.y"
{ c_expand_start_else ();
yyvsp[-1].itype = stmt_count;
position_after_white_space (); ;
break;}
-case 342:
-#line 1802 "objc-parse.y"
+case 346:
+#line 1816 "objc-parse.y"
{ c_expand_end_cond ();
if (extra_warnings && stmt_count == yyvsp[-3].itype)
warning ("empty body in an else-statement"); ;
break;}
-case 343:
-#line 1806 "objc-parse.y"
+case 347:
+#line 1820 "objc-parse.y"
{ c_expand_end_cond ();
/* This warning is here instead of in simple_if, because we
do not want a warning if an empty if is followed by an
@@ -3777,12 +3779,12 @@ case 343:
warning_with_file_and_line (if_stmt_file, if_stmt_line,
"empty body in an if-statement"); ;
break;}
-case 344:
-#line 1818 "objc-parse.y"
+case 348:
+#line 1832 "objc-parse.y"
{ c_expand_end_cond (); ;
break;}
-case 345:
-#line 1820 "objc-parse.y"
+case 349:
+#line 1834 "objc-parse.y"
{ stmt_count++;
emit_line_note (yyvsp[-2].filename, yyvsp[-1].lineno);
/* The emit_nop used to come before emit_line_note,
@@ -3793,8 +3795,8 @@ case 345:
We will see. --rms, July 15, 1991. */
emit_nop (); ;
break;}
-case 346:
-#line 1830 "objc-parse.y"
+case 350:
+#line 1844 "objc-parse.y"
{ /* Don't start the loop till we have succeeded
in parsing the end test. This is to make sure
that we end every loop we start. */
@@ -3804,25 +3806,25 @@ case 346:
truthvalue_conversion (yyvsp[-1].ttype));
position_after_white_space (); ;
break;}
-case 347:
-#line 1839 "objc-parse.y"
+case 351:
+#line 1853 "objc-parse.y"
{ expand_end_loop (); ;
break;}
-case 348:
-#line 1842 "objc-parse.y"
+case 352:
+#line 1856 "objc-parse.y"
{ emit_line_note (input_filename, lineno);
expand_exit_loop_if_false (NULL_PTR,
truthvalue_conversion (yyvsp[-2].ttype));
expand_end_loop ();
clear_momentary (); ;
break;}
-case 349:
-#line 1849 "objc-parse.y"
+case 353:
+#line 1863 "objc-parse.y"
{ expand_end_loop ();
clear_momentary (); ;
break;}
-case 350:
-#line 1853 "objc-parse.y"
+case 354:
+#line 1867 "objc-parse.y"
{ stmt_count++;
emit_line_note (yyvsp[-5].filename, yyvsp[-4].lineno);
/* See comment in `while' alternative, above. */
@@ -3834,13 +3836,13 @@ case 350:
fn without calling expand_end_loop. */
;
break;}
-case 351:
-#line 1865 "objc-parse.y"
+case 355:
+#line 1879 "objc-parse.y"
{ yyvsp[0].lineno = lineno;
yyval.filename = input_filename; ;
break;}
-case 352:
-#line 1868 "objc-parse.y"
+case 356:
+#line 1882 "objc-parse.y"
{
/* Start the loop. Doing this after parsing
all the expressions ensures we will end the loop. */
@@ -3857,8 +3859,8 @@ case 352:
yyvsp[-2].filename = input_filename;
position_after_white_space (); ;
break;}
-case 353:
-#line 1884 "objc-parse.y"
+case 357:
+#line 1898 "objc-parse.y"
{ /* Emit the increment expression, with a line number. */
emit_line_note (yyvsp[-4].filename, yyvsp[-5].lineno);
expand_loop_continue_here ();
@@ -3870,8 +3872,8 @@ case 353:
pop_momentary ();
expand_end_loop (); ;
break;}
-case 354:
-#line 1895 "objc-parse.y"
+case 358:
+#line 1909 "objc-parse.y"
{ stmt_count++;
emit_line_note (yyvsp[-5].filename, yyvsp[-4].lineno);
c_expand_start_case (yyvsp[-1].ttype);
@@ -3880,42 +3882,42 @@ case 354:
push_momentary ();
position_after_white_space (); ;
break;}
-case 355:
-#line 1903 "objc-parse.y"
+case 359:
+#line 1917 "objc-parse.y"
{ expand_end_case (yyvsp[-3].ttype);
if (yychar == CONSTANT || yychar == STRING)
pop_momentary_nofree ();
else
pop_momentary (); ;
break;}
-case 356:
-#line 1909 "objc-parse.y"
+case 360:
+#line 1923 "objc-parse.y"
{ stmt_count++;
emit_line_note (yyvsp[-3].filename, yyvsp[-2].lineno);
if ( ! expand_exit_something ())
error ("break statement not within loop or switch"); ;
break;}
-case 357:
-#line 1914 "objc-parse.y"
+case 361:
+#line 1928 "objc-parse.y"
{ stmt_count++;
emit_line_note (yyvsp[-3].filename, yyvsp[-2].lineno);
if (! expand_continue_loop (NULL_PTR))
error ("continue statement not within a loop"); ;
break;}
-case 358:
-#line 1919 "objc-parse.y"
+case 362:
+#line 1933 "objc-parse.y"
{ stmt_count++;
emit_line_note (yyvsp[-3].filename, yyvsp[-2].lineno);
c_expand_return (NULL_TREE); ;
break;}
-case 359:
-#line 1923 "objc-parse.y"
+case 363:
+#line 1937 "objc-parse.y"
{ stmt_count++;
emit_line_note (yyvsp[-4].filename, yyvsp[-3].lineno);
c_expand_return (yyvsp[-1].ttype); ;
break;}
-case 360:
-#line 1927 "objc-parse.y"
+case 364:
+#line 1941 "objc-parse.y"
{ stmt_count++;
emit_line_note (yyvsp[-7].filename, yyvsp[-6].lineno);
STRIP_NOPS (yyvsp[-2].ttype);
@@ -3926,32 +3928,32 @@ case 360:
else
error ("argument of `asm' is not a constant string"); ;
break;}
-case 361:
-#line 1938 "objc-parse.y"
+case 365:
+#line 1952 "objc-parse.y"
{ stmt_count++;
emit_line_note (yyvsp[-9].filename, yyvsp[-8].lineno);
c_expand_asm_operands (yyvsp[-4].ttype, yyvsp[-2].ttype, NULL_TREE, NULL_TREE,
yyvsp[-6].ttype == ridpointers[(int)RID_VOLATILE],
input_filename, lineno); ;
break;}
-case 362:
-#line 1945 "objc-parse.y"
+case 366:
+#line 1959 "objc-parse.y"
{ stmt_count++;
emit_line_note (yyvsp[-11].filename, yyvsp[-10].lineno);
c_expand_asm_operands (yyvsp[-6].ttype, yyvsp[-4].ttype, yyvsp[-2].ttype, NULL_TREE,
yyvsp[-8].ttype == ridpointers[(int)RID_VOLATILE],
input_filename, lineno); ;
break;}
-case 363:
-#line 1953 "objc-parse.y"
+case 367:
+#line 1967 "objc-parse.y"
{ stmt_count++;
emit_line_note (yyvsp[-13].filename, yyvsp[-12].lineno);
c_expand_asm_operands (yyvsp[-8].ttype, yyvsp[-6].ttype, yyvsp[-4].ttype, yyvsp[-2].ttype,
yyvsp[-10].ttype == ridpointers[(int)RID_VOLATILE],
input_filename, lineno); ;
break;}
-case 364:
-#line 1959 "objc-parse.y"
+case 368:
+#line 1973 "objc-parse.y"
{ tree decl;
stmt_count++;
emit_line_note (yyvsp[-4].filename, yyvsp[-3].lineno);
@@ -3963,16 +3965,16 @@ case 364:
}
;
break;}
-case 365:
-#line 1970 "objc-parse.y"
+case 369:
+#line 1984 "objc-parse.y"
{ if (pedantic)
pedwarn ("ANSI C forbids `goto *expr;'");
stmt_count++;
emit_line_note (yyvsp[-5].filename, yyvsp[-4].lineno);
expand_computed_goto (convert (ptr_type_node, yyvsp[-1].ttype)); ;
break;}
-case 368:
-#line 1985 "objc-parse.y"
+case 372:
+#line 1999 "objc-parse.y"
{
/* The value returned by this action is */
/* 1 if everything is OK */
@@ -3994,15 +3996,15 @@ case 368:
}
;
break;}
-case 369:
-#line 2006 "objc-parse.y"
+case 373:
+#line 2020 "objc-parse.y"
{
if (yyvsp[-1].itype)
iterator_for_loop_end (yyvsp[-3].ttype);
;
break;}
-case 370:
-#line 2041 "objc-parse.y"
+case 374:
+#line 2055 "objc-parse.y"
{ register tree value = check_case_value (yyvsp[-1].ttype);
register tree label
= build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
@@ -4034,8 +4036,8 @@ case 370:
}
position_after_white_space (); ;
break;}
-case 371:
-#line 2072 "objc-parse.y"
+case 375:
+#line 2086 "objc-parse.y"
{ register tree value1 = check_case_value (yyvsp[-3].ttype);
register tree value2 = check_case_value (yyvsp[-1].ttype);
register tree label
@@ -4067,8 +4069,8 @@ case 371:
}
position_after_white_space (); ;
break;}
-case 372:
-#line 2103 "objc-parse.y"
+case 376:
+#line 2117 "objc-parse.y"
{
tree duplicate;
register tree label
@@ -4084,62 +4086,65 @@ case 372:
}
position_after_white_space (); ;
break;}
-case 373:
-#line 2118 "objc-parse.y"
-{ tree label = define_label (input_filename, lineno, yyvsp[-1].ttype);
+case 377:
+#line 2132 "objc-parse.y"
+{ tree label = define_label (input_filename, lineno, yyvsp[-2].ttype);
stmt_count++;
emit_nop ();
if (label)
- expand_label (label);
+ {
+ expand_label (label);
+ decl_attributes (label, yyvsp[0].ttype, NULL_TREE);
+ }
position_after_white_space (); ;
break;}
-case 374:
-#line 2130 "objc-parse.y"
+case 378:
+#line 2147 "objc-parse.y"
{ emit_line_note (input_filename, lineno);
yyval.ttype = NULL_TREE; ;
break;}
-case 375:
-#line 2133 "objc-parse.y"
+case 379:
+#line 2150 "objc-parse.y"
{ emit_line_note (input_filename, lineno); ;
break;}
-case 376:
-#line 2138 "objc-parse.y"
+case 380:
+#line 2155 "objc-parse.y"
{ yyval.ttype = NULL_TREE; ;
break;}
-case 378:
-#line 2145 "objc-parse.y"
+case 382:
+#line 2162 "objc-parse.y"
{ yyval.ttype = NULL_TREE; ;
break;}
-case 381:
-#line 2152 "objc-parse.y"
+case 385:
+#line 2169 "objc-parse.y"
{ yyval.ttype = chainon (yyvsp[-2].ttype, yyvsp[0].ttype); ;
break;}
-case 382:
-#line 2157 "objc-parse.y"
+case 386:
+#line 2174 "objc-parse.y"
{ yyval.ttype = build_tree_list (yyvsp[-3].ttype, yyvsp[-1].ttype); ;
break;}
-case 383:
-#line 2162 "objc-parse.y"
+case 387:
+#line 2179 "objc-parse.y"
{ yyval.ttype = tree_cons (NULL_TREE, combine_strings (yyvsp[0].ttype), NULL_TREE); ;
break;}
-case 384:
-#line 2164 "objc-parse.y"
+case 388:
+#line 2181 "objc-parse.y"
{ yyval.ttype = tree_cons (NULL_TREE, combine_strings (yyvsp[0].ttype), yyvsp[-2].ttype); ;
break;}
-case 385:
-#line 2170 "objc-parse.y"
+case 389:
+#line 2187 "objc-parse.y"
{ pushlevel (0);
clear_parm_order ();
declare_parm_level (0); ;
break;}
-case 386:
-#line 2174 "objc-parse.y"
+case 390:
+#line 2191 "objc-parse.y"
{ yyval.ttype = yyvsp[0].ttype;
parmlist_tags_warning ();
poplevel (0, 0, 0); ;
break;}
-case 388:
-#line 2182 "objc-parse.y"
+case 392:
+#line 2199 "objc-parse.y"
{ tree parm;
if (pedantic)
pedwarn ("ANSI C forbids forward parameter declarations");
@@ -4148,20 +4153,20 @@ case 388:
TREE_ASM_WRITTEN (parm) = 1;
clear_parm_order (); ;
break;}
-case 389:
-#line 2190 "objc-parse.y"
+case 393:
+#line 2207 "objc-parse.y"
{ yyval.ttype = yyvsp[0].ttype; ;
break;}
-case 390:
-#line 2192 "objc-parse.y"
+case 394:
+#line 2209 "objc-parse.y"
{ yyval.ttype = tree_cons (NULL_TREE, NULL_TREE, NULL_TREE); ;
break;}
-case 391:
-#line 2198 "objc-parse.y"
+case 395:
+#line 2215 "objc-parse.y"
{ yyval.ttype = get_parm_info (0); ;
break;}
-case 392:
-#line 2200 "objc-parse.y"
+case 396:
+#line 2217 "objc-parse.y"
{ yyval.ttype = get_parm_info (0);
/* Gcc used to allow this as an extension. However, it does
not work for all targets, and thus has been disabled.
@@ -4172,24 +4177,24 @@ case 392:
error ("ANSI C requires a named argument before `...'");
;
break;}
-case 393:
-#line 2210 "objc-parse.y"
+case 397:
+#line 2227 "objc-parse.y"
{ yyval.ttype = get_parm_info (1); ;
break;}
-case 394:
-#line 2212 "objc-parse.y"
+case 398:
+#line 2229 "objc-parse.y"
{ yyval.ttype = get_parm_info (0); ;
break;}
-case 395:
-#line 2217 "objc-parse.y"
+case 399:
+#line 2234 "objc-parse.y"
{ push_parm_decl (yyvsp[0].ttype); ;
break;}
-case 396:
-#line 2219 "objc-parse.y"
+case 400:
+#line 2236 "objc-parse.y"
{ push_parm_decl (yyvsp[0].ttype); ;
break;}
-case 397:
-#line 2226 "objc-parse.y"
+case 401:
+#line 2243 "objc-parse.y"
{ yyval.ttype = build_tree_list (build_tree_list (current_declspecs,
yyvsp[-1].ttype),
build_tree_list (prefix_attributes,
@@ -4199,8 +4204,8 @@ case 397:
declspec_stack = TREE_CHAIN (declspec_stack);
resume_momentary (yyvsp[-2].itype); ;
break;}
-case 398:
-#line 2235 "objc-parse.y"
+case 402:
+#line 2252 "objc-parse.y"
{ yyval.ttype = build_tree_list (build_tree_list (current_declspecs,
yyvsp[-1].ttype),
build_tree_list (prefix_attributes,
@@ -4210,8 +4215,8 @@ case 398:
declspec_stack = TREE_CHAIN (declspec_stack);
resume_momentary (yyvsp[-2].itype); ;
break;}
-case 399:
-#line 2244 "objc-parse.y"
+case 403:
+#line 2261 "objc-parse.y"
{ yyval.ttype = build_tree_list (build_tree_list (current_declspecs,
yyvsp[-1].ttype),
build_tree_list (prefix_attributes,
@@ -4221,8 +4226,8 @@ case 399:
declspec_stack = TREE_CHAIN (declspec_stack);
resume_momentary (yyvsp[-2].itype); ;
break;}
-case 400:
-#line 2253 "objc-parse.y"
+case 404:
+#line 2270 "objc-parse.y"
{ yyval.ttype = build_tree_list (build_tree_list (current_declspecs,
yyvsp[-1].ttype),
build_tree_list (prefix_attributes,
@@ -4232,8 +4237,8 @@ case 400:
declspec_stack = TREE_CHAIN (declspec_stack);
resume_momentary (yyvsp[-2].itype); ;
break;}
-case 401:
-#line 2263 "objc-parse.y"
+case 405:
+#line 2280 "objc-parse.y"
{ yyval.ttype = build_tree_list (build_tree_list (current_declspecs,
yyvsp[-1].ttype),
build_tree_list (prefix_attributes,
@@ -4243,49 +4248,49 @@ case 401:
declspec_stack = TREE_CHAIN (declspec_stack);
resume_momentary (yyvsp[-2].itype); ;
break;}
-case 402:
-#line 2277 "objc-parse.y"
+case 406:
+#line 2294 "objc-parse.y"
{ pushlevel (0);
clear_parm_order ();
declare_parm_level (1); ;
break;}
-case 403:
-#line 2281 "objc-parse.y"
+case 407:
+#line 2298 "objc-parse.y"
{ yyval.ttype = yyvsp[0].ttype;
parmlist_tags_warning ();
poplevel (0, 0, 0); ;
break;}
-case 405:
-#line 2289 "objc-parse.y"
+case 409:
+#line 2306 "objc-parse.y"
{ tree t;
for (t = yyvsp[-1].ttype; t; t = TREE_CHAIN (t))
if (TREE_VALUE (t) == NULL_TREE)
error ("`...' in old-style identifier list");
yyval.ttype = tree_cons (NULL_TREE, NULL_TREE, yyvsp[-1].ttype); ;
break;}
-case 406:
-#line 2299 "objc-parse.y"
+case 410:
+#line 2316 "objc-parse.y"
{ yyval.ttype = build_tree_list (NULL_TREE, yyvsp[0].ttype); ;
break;}
-case 407:
-#line 2301 "objc-parse.y"
+case 411:
+#line 2318 "objc-parse.y"
{ yyval.ttype = chainon (yyvsp[-2].ttype, build_tree_list (NULL_TREE, yyvsp[0].ttype)); ;
break;}
-case 408:
-#line 2307 "objc-parse.y"
+case 412:
+#line 2324 "objc-parse.y"
{ yyval.ttype = build_tree_list (NULL_TREE, yyvsp[0].ttype); ;
break;}
-case 409:
-#line 2309 "objc-parse.y"
+case 413:
+#line 2326 "objc-parse.y"
{ yyval.ttype = chainon (yyvsp[-2].ttype, build_tree_list (NULL_TREE, yyvsp[0].ttype)); ;
break;}
-case 410:
-#line 2314 "objc-parse.y"
+case 414:
+#line 2331 "objc-parse.y"
{ yyval.itype = pedantic;
pedantic = 0; ;
break;}
-case 416:
-#line 2327 "objc-parse.y"
+case 420:
+#line 2344 "objc-parse.y"
{
if (objc_implementation_context)
{
@@ -4297,115 +4302,115 @@ case 416:
warning ("`@end' must appear in an implementation context");
;
break;}
-case 417:
-#line 2342 "objc-parse.y"
+case 421:
+#line 2359 "objc-parse.y"
{ yyval.ttype = build_tree_list (NULL_TREE, yyvsp[0].ttype); ;
break;}
-case 418:
-#line 2344 "objc-parse.y"
+case 422:
+#line 2361 "objc-parse.y"
{ yyval.ttype = chainon (yyvsp[-2].ttype, build_tree_list (NULL_TREE, yyvsp[0].ttype)); ;
break;}
-case 419:
-#line 2349 "objc-parse.y"
+case 423:
+#line 2366 "objc-parse.y"
{
objc_declare_class (yyvsp[-1].ttype);
;
break;}
-case 420:
-#line 2355 "objc-parse.y"
+case 424:
+#line 2372 "objc-parse.y"
{
objc_declare_alias (yyvsp[-2].ttype, yyvsp[-1].ttype);
;
break;}
-case 421:
-#line 2361 "objc-parse.y"
+case 425:
+#line 2378 "objc-parse.y"
{
objc_interface_context = objc_ivar_context
= start_class (CLASS_INTERFACE_TYPE, yyvsp[-2].ttype, NULL_TREE, yyvsp[-1].ttype);
objc_public_flag = 0;
;
break;}
-case 422:
-#line 2367 "objc-parse.y"
+case 426:
+#line 2384 "objc-parse.y"
{
continue_class (objc_interface_context);
;
break;}
-case 423:
-#line 2372 "objc-parse.y"
+case 427:
+#line 2389 "objc-parse.y"
{
finish_class (objc_interface_context);
objc_interface_context = NULL_TREE;
;
break;}
-case 424:
-#line 2378 "objc-parse.y"
+case 428:
+#line 2395 "objc-parse.y"
{
objc_interface_context
= start_class (CLASS_INTERFACE_TYPE, yyvsp[-1].ttype, NULL_TREE, yyvsp[0].ttype);
continue_class (objc_interface_context);
;
break;}
-case 425:
-#line 2385 "objc-parse.y"
+case 429:
+#line 2402 "objc-parse.y"
{
finish_class (objc_interface_context);
objc_interface_context = NULL_TREE;
;
break;}
-case 426:
-#line 2391 "objc-parse.y"
+case 430:
+#line 2408 "objc-parse.y"
{
objc_interface_context = objc_ivar_context
= start_class (CLASS_INTERFACE_TYPE, yyvsp[-4].ttype, yyvsp[-2].ttype, yyvsp[-1].ttype);
objc_public_flag = 0;
;
break;}
-case 427:
-#line 2397 "objc-parse.y"
+case 431:
+#line 2414 "objc-parse.y"
{
continue_class (objc_interface_context);
;
break;}
-case 428:
-#line 2402 "objc-parse.y"
+case 432:
+#line 2419 "objc-parse.y"
{
finish_class (objc_interface_context);
objc_interface_context = NULL_TREE;
;
break;}
-case 429:
-#line 2408 "objc-parse.y"
+case 433:
+#line 2425 "objc-parse.y"
{
objc_interface_context
= start_class (CLASS_INTERFACE_TYPE, yyvsp[-3].ttype, yyvsp[-1].ttype, yyvsp[0].ttype);
continue_class (objc_interface_context);
;
break;}
-case 430:
-#line 2415 "objc-parse.y"
+case 434:
+#line 2432 "objc-parse.y"
{
finish_class (objc_interface_context);
objc_interface_context = NULL_TREE;
;
break;}
-case 431:
-#line 2421 "objc-parse.y"
+case 435:
+#line 2438 "objc-parse.y"
{
objc_implementation_context = objc_ivar_context
= start_class (CLASS_IMPLEMENTATION_TYPE, yyvsp[-1].ttype, NULL_TREE, NULL_TREE);
objc_public_flag = 0;
;
break;}
-case 432:
-#line 2427 "objc-parse.y"
+case 436:
+#line 2444 "objc-parse.y"
{
objc_ivar_chain
= continue_class (objc_implementation_context);
;
break;}
-case 433:
-#line 2433 "objc-parse.y"
+case 437:
+#line 2450 "objc-parse.y"
{
objc_implementation_context
= start_class (CLASS_IMPLEMENTATION_TYPE, yyvsp[0].ttype, NULL_TREE, NULL_TREE);
@@ -4413,23 +4418,23 @@ case 433:
= continue_class (objc_implementation_context);
;
break;}
-case 434:
-#line 2441 "objc-parse.y"
+case 438:
+#line 2458 "objc-parse.y"
{
objc_implementation_context = objc_ivar_context
= start_class (CLASS_IMPLEMENTATION_TYPE, yyvsp[-3].ttype, yyvsp[-1].ttype, NULL_TREE);
objc_public_flag = 0;
;
break;}
-case 435:
-#line 2447 "objc-parse.y"
+case 439:
+#line 2464 "objc-parse.y"
{
objc_ivar_chain
= continue_class (objc_implementation_context);
;
break;}
-case 436:
-#line 2453 "objc-parse.y"
+case 440:
+#line 2470 "objc-parse.y"
{
objc_implementation_context
= start_class (CLASS_IMPLEMENTATION_TYPE, yyvsp[-2].ttype, yyvsp[0].ttype, NULL_TREE);
@@ -4437,23 +4442,23 @@ case 436:
= continue_class (objc_implementation_context);
;
break;}
-case 437:
-#line 2461 "objc-parse.y"
+case 441:
+#line 2478 "objc-parse.y"
{
objc_interface_context
= start_class (CATEGORY_INTERFACE_TYPE, yyvsp[-4].ttype, yyvsp[-2].ttype, yyvsp[0].ttype);
continue_class (objc_interface_context);
;
break;}
-case 438:
-#line 2468 "objc-parse.y"
+case 442:
+#line 2485 "objc-parse.y"
{
finish_class (objc_interface_context);
objc_interface_context = NULL_TREE;
;
break;}
-case 439:
-#line 2474 "objc-parse.y"
+case 443:
+#line 2491 "objc-parse.y"
{
objc_implementation_context
= start_class (CATEGORY_IMPLEMENTATION_TYPE, yyvsp[-3].ttype, yyvsp[-1].ttype, NULL_TREE);
@@ -4461,30 +4466,30 @@ case 439:
= continue_class (objc_implementation_context);
;
break;}
-case 440:
-#line 2484 "objc-parse.y"
+case 444:
+#line 2501 "objc-parse.y"
{
remember_protocol_qualifiers ();
objc_interface_context
= start_protocol(PROTOCOL_INTERFACE_TYPE, yyvsp[-1].ttype, yyvsp[0].ttype);
;
break;}
-case 441:
-#line 2490 "objc-parse.y"
+case 445:
+#line 2507 "objc-parse.y"
{
forget_protocol_qualifiers();
finish_protocol(objc_interface_context);
objc_interface_context = NULL_TREE;
;
break;}
-case 442:
-#line 2499 "objc-parse.y"
+case 446:
+#line 2516 "objc-parse.y"
{
yyval.ttype = NULL_TREE;
;
break;}
-case 444:
-#line 2507 "objc-parse.y"
+case 448:
+#line 2524 "objc-parse.y"
{
if (yyvsp[-2].code == LT_EXPR && yyvsp[0].code == GT_EXPR)
yyval.ttype = yyvsp[-1].ttype;
@@ -4492,57 +4497,57 @@ case 444:
YYERROR1;
;
break;}
-case 447:
-#line 2521 "objc-parse.y"
+case 451:
+#line 2538 "objc-parse.y"
{ objc_public_flag = 2; ;
break;}
-case 448:
-#line 2522 "objc-parse.y"
+case 452:
+#line 2539 "objc-parse.y"
{ objc_public_flag = 0; ;
break;}
-case 449:
-#line 2523 "objc-parse.y"
+case 453:
+#line 2540 "objc-parse.y"
{ objc_public_flag = 1; ;
break;}
-case 450:
-#line 2528 "objc-parse.y"
+case 454:
+#line 2545 "objc-parse.y"
{
yyval.ttype = NULL_TREE;
;
break;}
-case 452:
-#line 2533 "objc-parse.y"
+case 456:
+#line 2550 "objc-parse.y"
{
if (pedantic)
pedwarn ("extra semicolon in struct or union specified");
;
break;}
-case 453:
-#line 2551 "objc-parse.y"
+case 457:
+#line 2568 "objc-parse.y"
{ yyval.ttype = yyvsp[0].ttype;
current_declspecs = TREE_VALUE (declspec_stack);
prefix_attributes = TREE_PURPOSE (declspec_stack);
declspec_stack = TREE_CHAIN (declspec_stack);
resume_momentary (yyvsp[-1].itype); ;
break;}
-case 454:
-#line 2557 "objc-parse.y"
+case 458:
+#line 2574 "objc-parse.y"
{ yyval.ttype = yyvsp[0].ttype;
current_declspecs = TREE_VALUE (declspec_stack);
prefix_attributes = TREE_PURPOSE (declspec_stack);
declspec_stack = TREE_CHAIN (declspec_stack);
resume_momentary (yyvsp[-1].itype); ;
break;}
-case 455:
-#line 2563 "objc-parse.y"
+case 459:
+#line 2580 "objc-parse.y"
{ yyval.ttype = NULL_TREE; ;
break;}
-case 456:
-#line 2568 "objc-parse.y"
+case 460:
+#line 2585 "objc-parse.y"
{ yyval.ttype = NULL_TREE; ;
break;}
-case 459:
-#line 2575 "objc-parse.y"
+case 463:
+#line 2592 "objc-parse.y"
{
yyval.ttype = add_instance_variable (objc_ivar_context,
objc_public_flag,
@@ -4550,16 +4555,16 @@ case 459:
NULL_TREE);
;
break;}
-case 460:
-#line 2582 "objc-parse.y"
+case 464:
+#line 2599 "objc-parse.y"
{
yyval.ttype = add_instance_variable (objc_ivar_context,
objc_public_flag,
yyvsp[-2].ttype, current_declspecs, yyvsp[0].ttype);
;
break;}
-case 461:
-#line 2588 "objc-parse.y"
+case 465:
+#line 2605 "objc-parse.y"
{
yyval.ttype = add_instance_variable (objc_ivar_context,
objc_public_flag,
@@ -4567,8 +4572,8 @@ case 461:
current_declspecs, yyvsp[0].ttype);
;
break;}
-case 462:
-#line 2598 "objc-parse.y"
+case 466:
+#line 2615 "objc-parse.y"
{
remember_protocol_qualifiers ();
if (objc_implementation_context)
@@ -4577,8 +4582,8 @@ case 462:
fatal ("method definition not in class context");
;
break;}
-case 463:
-#line 2606 "objc-parse.y"
+case 467:
+#line 2623 "objc-parse.y"
{
forget_protocol_qualifiers ();
add_class_method (objc_implementation_context, yyvsp[0].ttype);
@@ -4586,21 +4591,21 @@ case 463:
objc_method_context = yyvsp[0].ttype;
;
break;}
-case 464:
-#line 2613 "objc-parse.y"
+case 468:
+#line 2630 "objc-parse.y"
{
continue_method_def ();
;
break;}
-case 465:
-#line 2617 "objc-parse.y"
+case 469:
+#line 2634 "objc-parse.y"
{
finish_method_def ();
objc_method_context = NULL_TREE;
;
break;}
-case 466:
-#line 2623 "objc-parse.y"
+case 470:
+#line 2640 "objc-parse.y"
{
remember_protocol_qualifiers ();
if (objc_implementation_context)
@@ -4609,8 +4614,8 @@ case 466:
fatal ("method definition not in class context");
;
break;}
-case 467:
-#line 2631 "objc-parse.y"
+case 471:
+#line 2648 "objc-parse.y"
{
forget_protocol_qualifiers ();
add_instance_method (objc_implementation_context, yyvsp[0].ttype);
@@ -4618,268 +4623,268 @@ case 467:
objc_method_context = yyvsp[0].ttype;
;
break;}
-case 468:
-#line 2638 "objc-parse.y"
+case 472:
+#line 2655 "objc-parse.y"
{
continue_method_def ();
;
break;}
-case 469:
-#line 2642 "objc-parse.y"
+case 473:
+#line 2659 "objc-parse.y"
{
finish_method_def ();
objc_method_context = NULL_TREE;
;
break;}
-case 471:
-#line 2654 "objc-parse.y"
+case 475:
+#line 2671 "objc-parse.y"
{yyval.ttype = NULL_TREE; ;
break;}
-case 476:
-#line 2661 "objc-parse.y"
+case 480:
+#line 2678 "objc-parse.y"
{yyval.ttype = NULL_TREE; ;
break;}
-case 480:
-#line 2671 "objc-parse.y"
+case 484:
+#line 2688 "objc-parse.y"
{
/* Remember protocol qualifiers in prototypes. */
remember_protocol_qualifiers ();
objc_inherit_code = CLASS_METHOD_DECL;
;
break;}
-case 481:
-#line 2677 "objc-parse.y"
+case 485:
+#line 2694 "objc-parse.y"
{
/* Forget protocol qualifiers here. */
forget_protocol_qualifiers ();
add_class_method (objc_interface_context, yyvsp[0].ttype);
;
break;}
-case 483:
-#line 2685 "objc-parse.y"
+case 487:
+#line 2702 "objc-parse.y"
{
/* Remember protocol qualifiers in prototypes. */
remember_protocol_qualifiers ();
objc_inherit_code = INSTANCE_METHOD_DECL;
;
break;}
-case 484:
-#line 2691 "objc-parse.y"
+case 488:
+#line 2708 "objc-parse.y"
{
/* Forget protocol qualifiers here. */
forget_protocol_qualifiers ();
add_instance_method (objc_interface_context, yyvsp[0].ttype);
;
break;}
-case 486:
-#line 2701 "objc-parse.y"
+case 490:
+#line 2718 "objc-parse.y"
{
yyval.ttype = build_method_decl (objc_inherit_code, yyvsp[-2].ttype, yyvsp[0].ttype, NULL_TREE);
;
break;}
-case 487:
-#line 2706 "objc-parse.y"
+case 491:
+#line 2723 "objc-parse.y"
{
yyval.ttype = build_method_decl (objc_inherit_code, NULL_TREE, yyvsp[0].ttype, NULL_TREE);
;
break;}
-case 488:
-#line 2711 "objc-parse.y"
+case 492:
+#line 2728 "objc-parse.y"
{
yyval.ttype = build_method_decl (objc_inherit_code, yyvsp[-3].ttype, yyvsp[-1].ttype, yyvsp[0].ttype);
;
break;}
-case 489:
-#line 2716 "objc-parse.y"
+case 493:
+#line 2733 "objc-parse.y"
{
yyval.ttype = build_method_decl (objc_inherit_code, NULL_TREE, yyvsp[-1].ttype, yyvsp[0].ttype);
;
break;}
-case 498:
-#line 2746 "objc-parse.y"
+case 502:
+#line 2763 "objc-parse.y"
{ current_declspecs = TREE_VALUE (declspec_stack);
prefix_attributes = TREE_PURPOSE (declspec_stack);
declspec_stack = TREE_CHAIN (declspec_stack);
resume_momentary (yyvsp[-2].itype); ;
break;}
-case 499:
-#line 2751 "objc-parse.y"
+case 503:
+#line 2768 "objc-parse.y"
{ shadow_tag (yyvsp[-1].ttype); ;
break;}
-case 500:
-#line 2753 "objc-parse.y"
+case 504:
+#line 2770 "objc-parse.y"
{ pedwarn ("empty declaration"); ;
break;}
-case 501:
-#line 2758 "objc-parse.y"
+case 505:
+#line 2775 "objc-parse.y"
{ push_parm_decl (yyvsp[0].ttype); ;
break;}
-case 502:
-#line 2760 "objc-parse.y"
+case 506:
+#line 2777 "objc-parse.y"
{ push_parm_decl (yyvsp[0].ttype); ;
break;}
-case 503:
-#line 2768 "objc-parse.y"
+case 507:
+#line 2785 "objc-parse.y"
{ yyval.ttype = build_tree_list (build_tree_list (current_declspecs,
yyvsp[-1].ttype),
build_tree_list (prefix_attributes,
yyvsp[0].ttype)); ;
break;}
-case 504:
-#line 2773 "objc-parse.y"
+case 508:
+#line 2790 "objc-parse.y"
{ yyval.ttype = build_tree_list (build_tree_list (current_declspecs,
yyvsp[-1].ttype),
build_tree_list (prefix_attributes,
yyvsp[0].ttype)); ;
break;}
-case 505:
-#line 2778 "objc-parse.y"
+case 509:
+#line 2795 "objc-parse.y"
{ yyval.ttype = build_tree_list (build_tree_list (current_declspecs,
yyvsp[-1].ttype),
build_tree_list (prefix_attributes,
yyvsp[0].ttype)); ;
break;}
-case 506:
-#line 2786 "objc-parse.y"
+case 510:
+#line 2803 "objc-parse.y"
{
yyval.ttype = NULL_TREE;
;
break;}
-case 507:
-#line 2790 "objc-parse.y"
+case 511:
+#line 2807 "objc-parse.y"
{
/* oh what a kludge! */
yyval.ttype = (tree)1;
;
break;}
-case 508:
-#line 2795 "objc-parse.y"
+case 512:
+#line 2812 "objc-parse.y"
{
pushlevel (0);
;
break;}
-case 509:
-#line 2799 "objc-parse.y"
+case 513:
+#line 2816 "objc-parse.y"
{
/* returns a tree list node generated by get_parm_info */
yyval.ttype = yyvsp[0].ttype;
poplevel (0, 0, 0);
;
break;}
-case 512:
-#line 2814 "objc-parse.y"
+case 516:
+#line 2831 "objc-parse.y"
{
yyval.ttype = chainon (yyvsp[-1].ttype, yyvsp[0].ttype);
;
break;}
-case 517:
-#line 2827 "objc-parse.y"
-{ yyval.ttype = get_identifier (token_buffer); ;
- break;}
-case 518:
-#line 2828 "objc-parse.y"
-{ yyval.ttype = get_identifier (token_buffer); ;
- break;}
-case 519:
-#line 2829 "objc-parse.y"
-{ yyval.ttype = get_identifier (token_buffer); ;
- break;}
-case 520:
-#line 2830 "objc-parse.y"
-{ yyval.ttype = get_identifier (token_buffer); ;
- break;}
case 521:
-#line 2831 "objc-parse.y"
+#line 2844 "objc-parse.y"
{ yyval.ttype = get_identifier (token_buffer); ;
break;}
case 522:
-#line 2832 "objc-parse.y"
+#line 2845 "objc-parse.y"
{ yyval.ttype = get_identifier (token_buffer); ;
break;}
case 523:
-#line 2833 "objc-parse.y"
+#line 2846 "objc-parse.y"
{ yyval.ttype = get_identifier (token_buffer); ;
break;}
case 524:
-#line 2834 "objc-parse.y"
+#line 2847 "objc-parse.y"
{ yyval.ttype = get_identifier (token_buffer); ;
break;}
case 525:
-#line 2835 "objc-parse.y"
+#line 2848 "objc-parse.y"
{ yyval.ttype = get_identifier (token_buffer); ;
break;}
case 526:
-#line 2836 "objc-parse.y"
+#line 2849 "objc-parse.y"
{ yyval.ttype = get_identifier (token_buffer); ;
break;}
case 527:
-#line 2837 "objc-parse.y"
+#line 2850 "objc-parse.y"
{ yyval.ttype = get_identifier (token_buffer); ;
break;}
case 528:
-#line 2838 "objc-parse.y"
+#line 2851 "objc-parse.y"
{ yyval.ttype = get_identifier (token_buffer); ;
break;}
case 529:
-#line 2839 "objc-parse.y"
+#line 2852 "objc-parse.y"
{ yyval.ttype = get_identifier (token_buffer); ;
break;}
case 530:
-#line 2840 "objc-parse.y"
+#line 2853 "objc-parse.y"
{ yyval.ttype = get_identifier (token_buffer); ;
break;}
case 531:
-#line 2841 "objc-parse.y"
+#line 2854 "objc-parse.y"
{ yyval.ttype = get_identifier (token_buffer); ;
break;}
case 532:
-#line 2842 "objc-parse.y"
+#line 2855 "objc-parse.y"
{ yyval.ttype = get_identifier (token_buffer); ;
break;}
case 533:
-#line 2843 "objc-parse.y"
+#line 2856 "objc-parse.y"
{ yyval.ttype = get_identifier (token_buffer); ;
break;}
case 534:
-#line 2844 "objc-parse.y"
+#line 2857 "objc-parse.y"
{ yyval.ttype = get_identifier (token_buffer); ;
break;}
case 535:
-#line 2845 "objc-parse.y"
+#line 2858 "objc-parse.y"
+{ yyval.ttype = get_identifier (token_buffer); ;
+ break;}
+case 536:
+#line 2859 "objc-parse.y"
+{ yyval.ttype = get_identifier (token_buffer); ;
+ break;}
+case 537:
+#line 2860 "objc-parse.y"
{ yyval.ttype = get_identifier (token_buffer); ;
break;}
case 538:
-#line 2851 "objc-parse.y"
+#line 2861 "objc-parse.y"
+{ yyval.ttype = get_identifier (token_buffer); ;
+ break;}
+case 539:
+#line 2862 "objc-parse.y"
+{ yyval.ttype = get_identifier (token_buffer); ;
+ break;}
+case 542:
+#line 2868 "objc-parse.y"
{
yyval.ttype = build_keyword_decl (yyvsp[-5].ttype, yyvsp[-2].ttype, yyvsp[0].ttype);
;
break;}
-case 539:
-#line 2856 "objc-parse.y"
+case 543:
+#line 2873 "objc-parse.y"
{
yyval.ttype = build_keyword_decl (yyvsp[-2].ttype, NULL_TREE, yyvsp[0].ttype);
;
break;}
-case 540:
-#line 2861 "objc-parse.y"
+case 544:
+#line 2878 "objc-parse.y"
{
yyval.ttype = build_keyword_decl (NULL_TREE, yyvsp[-2].ttype, yyvsp[0].ttype);
;
break;}
-case 541:
-#line 2866 "objc-parse.y"
+case 545:
+#line 2883 "objc-parse.y"
{
yyval.ttype = build_keyword_decl (NULL_TREE, NULL_TREE, yyvsp[0].ttype);
;
break;}
-case 545:
-#line 2879 "objc-parse.y"
+case 549:
+#line 2896 "objc-parse.y"
{
yyval.ttype = chainon (yyvsp[-1].ttype, yyvsp[0].ttype);
;
break;}
-case 546:
-#line 2887 "objc-parse.y"
+case 550:
+#line 2904 "objc-parse.y"
{
if (TREE_CHAIN (yyvsp[0].ttype) == NULL_TREE)
/* just return the expr., remove a level of indirection */
@@ -4889,77 +4894,77 @@ case 546:
yyval.ttype = yyvsp[0].ttype;
;
break;}
-case 547:
-#line 2899 "objc-parse.y"
+case 551:
+#line 2916 "objc-parse.y"
{
yyval.ttype = build_tree_list (yyvsp[-2].ttype, yyvsp[0].ttype);
;
break;}
-case 548:
-#line 2903 "objc-parse.y"
+case 552:
+#line 2920 "objc-parse.y"
{
yyval.ttype = build_tree_list (NULL_TREE, yyvsp[0].ttype);
;
break;}
-case 550:
-#line 2911 "objc-parse.y"
+case 554:
+#line 2928 "objc-parse.y"
{
yyval.ttype = get_class_reference (yyvsp[0].ttype);
;
break;}
-case 551:
-#line 2918 "objc-parse.y"
+case 555:
+#line 2935 "objc-parse.y"
{ objc_receiver_context = 1; ;
break;}
-case 552:
-#line 2920 "objc-parse.y"
+case 556:
+#line 2937 "objc-parse.y"
{ objc_receiver_context = 0; ;
break;}
-case 553:
-#line 2922 "objc-parse.y"
+case 557:
+#line 2939 "objc-parse.y"
{
yyval.ttype = build_tree_list (yyvsp[-3].ttype, yyvsp[-1].ttype);
;
break;}
-case 557:
-#line 2935 "objc-parse.y"
+case 561:
+#line 2952 "objc-parse.y"
{
yyval.ttype = chainon (yyvsp[-1].ttype, yyvsp[0].ttype);
;
break;}
-case 558:
-#line 2942 "objc-parse.y"
+case 562:
+#line 2959 "objc-parse.y"
{
yyval.ttype = build_tree_list (yyvsp[-1].ttype, NULL_TREE);
;
break;}
-case 559:
-#line 2946 "objc-parse.y"
+case 563:
+#line 2963 "objc-parse.y"
{
yyval.ttype = build_tree_list (NULL_TREE, NULL_TREE);
;
break;}
-case 560:
-#line 2953 "objc-parse.y"
+case 564:
+#line 2970 "objc-parse.y"
{
yyval.ttype = yyvsp[-1].ttype;
;
break;}
-case 561:
-#line 2960 "objc-parse.y"
+case 565:
+#line 2977 "objc-parse.y"
{
yyval.ttype = yyvsp[-1].ttype;
;
break;}
-case 562:
-#line 2969 "objc-parse.y"
+case 566:
+#line 2986 "objc-parse.y"
{
yyval.ttype = groktypename (yyvsp[-1].ttype);
;
break;}
}
/* the action file gets copied in in place of this dollarsign */
-#line 498 "/usr/cygnus/progressive-98r1/share/bison.simple"
+#line 498 "/usr/lib/bison.simple"
yyvsp -= yylen;
yyssp -= yylen;
@@ -5155,5 +5160,5 @@ yyerrhandle:
yystate = yyn;
goto yynewstate;
}
-#line 2974 "objc-parse.y"
+#line 2991 "objc-parse.y"
diff --git a/gcc/objc/objc-parse.y b/gcc/objc/objc-parse.y
index bc98ff23489..c5cc9ce3d86 100644
--- a/gcc/objc/objc-parse.y
+++ b/gcc/objc/objc-parse.y
@@ -82,7 +82,7 @@ char *language_string = "GNU Obj-C";
yylval contains an IDENTIFIER_NODE which indicates which one. */
%token TYPESPEC
-/* Reserved words that qualify type: "const" or "volatile".
+/* Reserved words that qualify type: "const", "volatile", or "restrict".
yylval contains an IDENTIFIER_NODE which indicates which one. */
%token TYPE_QUAL
@@ -483,7 +483,7 @@ cast_expr:
tree type = $2;
finish_init ();
- if (pedantic)
+ if (pedantic && ! flag_isoc9x)
pedwarn ("ANSI C forbids constructor expressions");
if (TYPE_NAME (type) != 0)
{
@@ -1215,22 +1215,35 @@ initlist1:
/* `initelt' is a single element of an initializer.
It may use braces. */
initelt:
- expr_no_commas
- { process_init_element ($1); }
- | '{'
+ designator_list '=' initval
+ | designator initval
+ | identifier ':'
+ { set_init_label ($1); }
+ initval
+ | initval
+ ;
+
+initval:
+ '{'
{ push_init_level (0); }
initlist_maybe_comma '}'
{ process_init_element (pop_init_level (0)); }
+ | expr_no_commas
+ { process_init_element ($1); }
| error
+ ;
+
+designator_list:
+ designator
+ | designator_list designator
+ ;
+
+designator:
+ '.' identifier
+ { set_init_label ($2); }
/* These are for labeled elements. The syntax for an array element
initializer conflicts with the syntax for an Objective-C message,
so don't include these productions in the Objective-C grammar. */
- | identifier ':'
- { set_init_label ($1); }
- initelt
- | '.' identifier '='
- { set_init_label ($2); }
- initelt
;
nested_function:
@@ -1436,7 +1449,8 @@ maybecomma:
maybecomma_warn:
/* empty */
| ','
- { if (pedantic) pedwarn ("comma at end of enumerator list"); }
+ { if (pedantic && ! flag_isoc9x)
+ pedwarn ("comma at end of enumerator list"); }
;
component_decl_list:
@@ -2114,12 +2128,15 @@ label: CASE expr_no_commas ':'
error_with_decl (duplicate, "this is the first default label");
}
position_after_white_space (); }
- | identifier ':'
+ | identifier ':' maybe_attribute
{ tree label = define_label (input_filename, lineno, $1);
stmt_count++;
emit_nop ();
if (label)
- expand_label (label);
+ {
+ expand_label (label);
+ decl_attributes (label, $3, NULL_TREE);
+ }
position_after_white_space (); }
;
diff --git a/gcc/objc/objc-tree.def b/gcc/objc/objc-tree.def
index 9d6765b295e..a6616243d10 100644
--- a/gcc/objc/objc-tree.def
+++ b/gcc/objc/objc-tree.def
@@ -1,7 +1,7 @@
/* This file contains the definitions and documentation for the
additional tree codes used in the Objective C front end (see tree.def
for the standard codes).
- Copyright (C) 1990 Free Software Foundation, Inc.
+ Copyright (C) 1990, 1997 Free Software Foundation, Inc.
This file is part of GNU CC.
diff --git a/gcc/optabs.c b/gcc/optabs.c
index c11a16dff25..3bff75ae1be 100644
--- a/gcc/optabs.c
+++ b/gcc/optabs.c
@@ -1,5 +1,5 @@
/* Expand the basic unary and binary arithmetic operations, for GNU compiler.
- Copyright (C) 1987, 88, 92-97, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1987, 88, 92-98, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -21,6 +21,10 @@ Boston, MA 02111-1307, USA. */
#include "config.h"
#include "system.h"
+
+/* Include insn-config.h before expr.h so that HAVE_conditional_move
+ is properly defined. */
+#include "insn-config.h"
#include "rtl.h"
#include "tree.h"
#include "function.h"
@@ -28,7 +32,6 @@ Boston, MA 02111-1307, USA. */
#include "insn-flags.h"
#include "insn-codes.h"
#include "expr.h"
-#include "insn-config.h"
#include "recog.h"
#include "reload.h"
#include "ggc.h"
@@ -89,9 +92,9 @@ static enum insn_code can_float_p PROTO((enum machine_mode, enum machine_mode,
int));
static rtx ftruncify PROTO((rtx));
static optab init_optab PROTO((enum rtx_code));
-static void init_libfuncs PROTO((optab, int, int, char *, int));
-static void init_integral_libfuncs PROTO((optab, char *, int));
-static void init_floating_libfuncs PROTO((optab, char *, int));
+static void init_libfuncs PROTO((optab, int, int, const char *, int));
+static void init_integral_libfuncs PROTO((optab, const char *, int));
+static void init_floating_libfuncs PROTO((optab, const char *, int));
#ifdef HAVE_conditional_trap
static void init_traps PROTO((void));
#endif
@@ -143,9 +146,7 @@ add_equal_note (seq, target, code, op0, op1)
else
note = gen_rtx_fmt_ee (code, GET_MODE (target), copy_rtx (op0), copy_rtx (op1));
- REG_NOTES (XVECEXP (seq, 0, XVECLEN (seq, 0) - 1))
- = gen_rtx_EXPR_LIST (REG_EQUAL, note,
- REG_NOTES (XVECEXP (seq, 0, XVECLEN (seq, 0) - 1)));
+ set_unique_reg_note (XVECEXP (seq, 0, XVECLEN (seq, 0) - 1), REG_EQUAL, note);
return 1;
}
@@ -828,12 +829,11 @@ expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods)
{
rtx temp = emit_move_insn (target, target);
- REG_NOTES (temp)
- = gen_rtx_EXPR_LIST (REG_EQUAL,
- gen_rtx_fmt_ee (binoptab->code, mode,
- copy_rtx (xop0),
- copy_rtx (xop1)),
- REG_NOTES (temp));
+ set_unique_reg_note (temp,
+ REG_EQUAL,
+ gen_rtx_fmt_ee (binoptab->code, mode,
+ copy_rtx (xop0),
+ copy_rtx (xop1)));
}
return target;
}
@@ -1011,12 +1011,11 @@ expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods)
if (mov_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
{
temp = emit_move_insn (product, product);
- REG_NOTES (temp)
- = gen_rtx_EXPR_LIST (REG_EQUAL,
- gen_rtx_fmt_ee (MULT, mode,
- copy_rtx (op0),
- copy_rtx (op1)),
- REG_NOTES (temp));
+ set_unique_reg_note (temp,
+ REG_EQUAL,
+ gen_rtx_fmt_ee (MULT, mode,
+ copy_rtx (op0),
+ copy_rtx (op1)));
}
return product;
}
@@ -1947,14 +1946,13 @@ expand_unop (mode, unoptab, op0, target, unsignedp)
MODE is the mode of the operand; the mode of the result is
different but can be deduced from MODE.
- UNSIGNEDP is relevant if extension is needed. */
+ */
rtx
-expand_abs (mode, op0, target, unsignedp, safe)
+expand_abs (mode, op0, target, safe)
enum machine_mode mode;
rtx op0;
rtx target;
- int unsignedp;
int safe;
{
rtx temp, op1;
@@ -2384,8 +2382,7 @@ emit_no_conflict_block (insns, target, op0, op1, equiv)
{
last = emit_move_insn (target, target);
if (equiv)
- REG_NOTES (last)
- = gen_rtx_EXPR_LIST (REG_EQUAL, equiv, REG_NOTES (last));
+ set_unique_reg_note (last, REG_EQUAL, equiv);
}
else
last = get_last_insn ();
@@ -2437,6 +2434,21 @@ emit_libcall_block (insns, target, result, equiv)
{
rtx prev, next, first, last, insn;
+ /* look for any CALL_INSNs in this sequence, and attach a REG_EH_REGION
+ reg note to indicate that this call cannot throw. (Unless there is
+ already a REG_EH_REGION note.) */
+
+ for (insn = insns; insn; insn = NEXT_INSN (insn))
+ {
+ if (GET_CODE (insn) == CALL_INSN)
+ {
+ rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
+ if (note == NULL_RTX)
+ REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EH_REGION, GEN_INT (0),
+ REG_NOTES (insn));
+ }
+ }
+
/* First emit all insns that set pseudos. Remove them from the list as
we go. Avoid insns that set pseudos which were referenced in previous
insns. These can be generated by move_by_pieces, for example,
@@ -2483,8 +2495,7 @@ emit_libcall_block (insns, target, result, equiv)
last = emit_move_insn (target, result);
if (mov_optab->handlers[(int) GET_MODE (target)].insn_code
!= CODE_FOR_nothing)
- REG_NOTES (last) = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (equiv),
- REG_NOTES (last));
+ set_unique_reg_note (last, REG_EQUAL, copy_rtx (equiv));
if (prev == 0)
first = get_insns ();
@@ -2563,6 +2574,14 @@ emit_cmp_insn (x, y, comparison, size, mode, unsignedp, align)
if (CONSTANT_P (y) && preserve_subexpressions_p () && rtx_cost (y, COMPARE) > 2)
y = force_reg (mode, y);
+#ifdef HAVE_cc0
+ /* Abort if we have a non-canonical comparison. The RTL documentation
+ states that canonical comparisons are required only for targets which
+ have cc0. */
+ if (CONSTANT_P (x) && ! CONSTANT_P (y))
+ abort();
+#endif
+
/* Don't let both operands fail to indicate the mode. */
if (GET_MODE (x) == VOIDmode && GET_MODE (y) == VOIDmode)
x = force_reg (mode, x);
@@ -2754,6 +2773,57 @@ emit_cmp_insn (x, y, comparison, size, mode, unsignedp, align)
abort ();
}
+/* Generate code to compare X with Y so that the condition codes are
+ set and to jump to LABEL if the condition is true. If X is a
+ constant and Y is not a constant, then the comparison is swapped to
+ ensure that the comparison RTL has the canonical form.
+
+ UNSIGNEDP nonzero says that X and Y are unsigned; this matters if they
+ need to be widened by emit_cmp_insn. UNSIGNEDP is also used to select
+ the proper branch condition code.
+
+ If X and Y have mode BLKmode, then SIZE specifies the size of both X and Y,
+ and ALIGN specifies the known shared alignment of X and Y.
+
+ MODE is the mode of the inputs (in case they are const_int).
+
+ COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). It will
+ be passed unchanged to emit_cmp_insn, then potentially converted into an
+ unsigned variant based on UNSIGNEDP to select a proper jump instruction. */
+
+void
+emit_cmp_and_jump_insns (x, y, comparison, size, mode, unsignedp, align, label)
+ rtx x, y;
+ enum rtx_code comparison;
+ rtx size;
+ enum machine_mode mode;
+ int unsignedp;
+ int align;
+ rtx label;
+{
+ rtx op0;
+ rtx op1;
+
+ if (CONSTANT_P (x))
+ {
+ /* Swap operands and condition to ensure canonical RTL. */
+ op0 = y;
+ op1 = x;
+ comparison = swap_condition (comparison);
+ }
+ else
+ {
+ op0 = x;
+ op1 = y;
+ }
+ emit_cmp_insn (op0, op1, comparison, size, mode, unsignedp, align);
+
+ if (unsignedp)
+ comparison = unsigned_condition (comparison);
+ emit_jump_insn ((*bcc_gen_fctn[(int) comparison]) (label));
+}
+
+
/* Nonzero if a compare of mode MODE can be done straightforwardly
(without splitting it into pieces). */
@@ -3230,8 +3300,7 @@ gen_move_insn (x, y)
{
x = gen_rtx_MEM (tmode, XEXP (x1, 0));
RTX_UNCHANGING_P (x) = RTX_UNCHANGING_P (x1);
- MEM_IN_STRUCT_P (x) = MEM_IN_STRUCT_P (x1);
- MEM_VOLATILE_P (x) = MEM_VOLATILE_P (x1);
+ MEM_COPY_ATTRIBUTES (x, x1);
copy_replacements (x1, x);
}
@@ -3240,8 +3309,7 @@ gen_move_insn (x, y)
{
y = gen_rtx_MEM (tmode, XEXP (y1, 0));
RTX_UNCHANGING_P (y) = RTX_UNCHANGING_P (y1);
- MEM_IN_STRUCT_P (y) = MEM_IN_STRUCT_P (y1);
- MEM_VOLATILE_P (y) = MEM_VOLATILE_P (y1);
+ MEM_COPY_ATTRIBUTES (y, y1);
copy_replacements (y1, y);
}
}
@@ -3475,8 +3543,8 @@ expand_float (to, from, unsignedp)
correct its value by 2**bitwidth. */
do_pending_stack_adjust ();
- emit_cmp_insn (from, const0_rtx, GE, NULL_RTX, GET_MODE (from), 0, 0);
- emit_jump_insn (gen_bge (label));
+ emit_cmp_and_jump_insns (from, const0_rtx, GE, NULL_RTX, GET_MODE (from),
+ 0, 0, label);
/* On SCO 3.2.1, ldexp rejects values outside [0.5, 1).
Rather than setting up a dconst_dot_5, let's hope SCO
@@ -3683,8 +3751,8 @@ expand_fix (to, from, unsignedp)
/* See if we need to do the subtraction. */
do_pending_stack_adjust ();
- emit_cmp_insn (from, limit, GE, NULL_RTX, GET_MODE (from), 0, 0);
- emit_jump_insn (gen_bge (lab1));
+ emit_cmp_and_jump_insns (from, limit, GE, NULL_RTX, GET_MODE (from),
+ 0, 0, lab1);
/* If not, do the signed "fix" and branch around fixup code. */
expand_fix (to, from, 0);
@@ -3712,12 +3780,11 @@ expand_fix (to, from, unsignedp)
{
/* Make a place for a REG_NOTE and add it. */
insn = emit_move_insn (to, to);
- REG_NOTES (insn)
- = gen_rtx_EXPR_LIST (REG_EQUAL,
- gen_rtx_fmt_e (UNSIGNED_FIX,
- GET_MODE (to),
- copy_rtx (from)),
- REG_NOTES (insn));
+ set_unique_reg_note (insn,
+ REG_EQUAL,
+ gen_rtx_fmt_e (UNSIGNED_FIX,
+ GET_MODE (to),
+ copy_rtx (from)));
}
return;
}
@@ -3854,7 +3921,7 @@ init_libfuncs (optable, first_mode, last_mode, opname, suffix)
register optab optable;
register int first_mode;
register int last_mode;
- register char *opname;
+ register const char *opname;
register int suffix;
{
register int mode;
@@ -3868,7 +3935,7 @@ init_libfuncs (optable, first_mode, last_mode, opname, suffix)
register char *libfunc_name
= (char *) xmalloc (2 + opname_len + mname_len + 1 + 1);
register char *p;
- register char *q;
+ register const char *q;
p = libfunc_name;
*p++ = '_';
@@ -3876,7 +3943,7 @@ init_libfuncs (optable, first_mode, last_mode, opname, suffix)
for (q = opname; *q; )
*p++ = *q++;
for (q = mname; *q; q++)
- *p++ = tolower (*q);
+ *p++ = tolower ((unsigned char)*q);
*p++ = suffix;
*p++ = '\0';
optable->handlers[(int) mode].libfunc
@@ -3892,7 +3959,7 @@ init_libfuncs (optable, first_mode, last_mode, opname, suffix)
static void
init_integral_libfuncs (optable, opname, suffix)
register optab optable;
- register char *opname;
+ register const char *opname;
register int suffix;
{
init_libfuncs (optable, SImode, TImode, opname, suffix);
@@ -3906,7 +3973,7 @@ init_integral_libfuncs (optable, opname, suffix)
static void
init_floating_libfuncs (optable, opname, suffix)
register optab optable;
- register char *opname;
+ register const char *opname;
register int suffix;
{
init_libfuncs (optable, SFmode, TFmode, opname, suffix);
@@ -4146,6 +4213,7 @@ init_optabs ()
bzero_libfunc = gen_rtx_SYMBOL_REF (Pmode, "bzero");
throw_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__throw");
+ rethrow_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__rethrow");
sjthrow_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__sjthrow");
sjpopnthrow_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__sjpopnthrow");
terminate_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__terminate");
@@ -4242,17 +4310,17 @@ init_optabs ()
fixunstfti_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixunstfti");
/* For check-memory-usage. */
- chkr_check_addr_libfunc = gen_rtx_SYMBOL_REF (VOIDmode, "chkr_check_addr");
- chkr_set_right_libfunc = gen_rtx_SYMBOL_REF (VOIDmode, "chkr_set_right");
- chkr_copy_bitmap_libfunc = gen_rtx_SYMBOL_REF (VOIDmode, "chkr_copy_bitmap");
- chkr_check_exec_libfunc = gen_rtx_SYMBOL_REF (VOIDmode, "chkr_check_exec");
- chkr_check_str_libfunc = gen_rtx_SYMBOL_REF (VOIDmode, "chkr_check_str");
+ chkr_check_addr_libfunc = gen_rtx_SYMBOL_REF (Pmode, "chkr_check_addr");
+ chkr_set_right_libfunc = gen_rtx_SYMBOL_REF (Pmode, "chkr_set_right");
+ chkr_copy_bitmap_libfunc = gen_rtx_SYMBOL_REF (Pmode, "chkr_copy_bitmap");
+ chkr_check_exec_libfunc = gen_rtx_SYMBOL_REF (Pmode, "chkr_check_exec");
+ chkr_check_str_libfunc = gen_rtx_SYMBOL_REF (Pmode, "chkr_check_str");
/* For function entry/exit instrumentation. */
profile_function_entry_libfunc
- = gen_rtx_SYMBOL_REF (VOIDmode, "__cyg_profile_func_enter");
+ = gen_rtx_SYMBOL_REF (Pmode, "__cyg_profile_func_enter");
profile_function_exit_libfunc
- = gen_rtx_SYMBOL_REF (VOIDmode, "__cyg_profile_func_exit");
+ = gen_rtx_SYMBOL_REF (Pmode, "__cyg_profile_func_exit");
#ifdef HAVE_conditional_trap
init_traps ();
@@ -4308,8 +4376,8 @@ init_traps ()
rtx
gen_cond_trap (code, op1, op2, tcode)
- enum rtx_code code;
- rtx op1, op2, tcode;
+ enum rtx_code code ATTRIBUTE_UNUSED;
+ rtx op1, op2 ATTRIBUTE_UNUSED, tcode ATTRIBUTE_UNUSED;
{
enum machine_mode mode = GET_MODE (op1);
diff --git a/gcc/output.h b/gcc/output.h
index d086aa859a1..9e88000d9d6 100644
--- a/gcc/output.h
+++ b/gcc/output.h
@@ -1,6 +1,6 @@
/* Declarations for insn-output.c. These functions are defined in recog.c,
final.c, and varasm.c.
- Copyright (C) 1987, 1991, 1994, 1997 Free Software Foundation, Inc.
+ Copyright (C) 1987, 1991, 1994, 97-98, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -24,7 +24,7 @@ extern void init_final PROTO((char *));
/* Called at end of source file,
to output the block-profiling table for this entire compilation. */
-extern void end_final PROTO((char *));
+extern void end_final PROTO((const char *));
/* Enable APP processing of subsequent output.
Used before the output from an `asm' statement. */
@@ -77,11 +77,11 @@ extern rtx alter_subreg PROTO((rtx));
/* Report inconsistency between the assembler template and the operands.
In an `asm', it's the user's fault; otherwise, the compiler's fault. */
-extern void output_operand_lossage PROTO((char *));
+extern void output_operand_lossage PROTO((const char *));
/* Output a string of assembler code, substituting insn operands.
Defined in final.c. */
-extern void output_asm_insn PROTO((char *, rtx *));
+extern void output_asm_insn PROTO((const char *, rtx *));
/* Compute a worst-case reference address of a branch so that it
can be safely used in the presence of aligned labels.
@@ -106,7 +106,7 @@ extern void output_addr_const PROTO((FILE *, rtx));
/* Output a string of assembler code, substituting numbers, strings
and fixed syntactic prefixes. */
-extern void asm_fprintf PROTO(PVPROTO((FILE *file, char *p, ...)));
+extern void asm_fprintf PVPROTO((FILE *file, const char *p, ...));
/* Split up a CONST_DOUBLE or integer constant rtx into two rtx's for single
words. */
@@ -128,7 +128,7 @@ extern void allocate_for_life_analysis PROTO((void));
extern int regno_uninitialized PROTO((int));
extern int regno_clobbered_at_setjmp PROTO((int));
extern void dump_flow_info PROTO((FILE *));
-extern void find_basic_blocks PROTO((rtx, int, FILE *, int));
+extern void find_basic_blocks PROTO((rtx, int, FILE *));
extern void free_basic_block_vars PROTO((int));
extern void set_block_num PROTO((rtx, int));
extern void life_analysis PROTO((rtx, int, FILE *));
@@ -142,6 +142,9 @@ extern void text_section PROTO((void));
/* Tell assembler to switch to data section. */
extern void data_section PROTO((void));
+/* Tell assembler to make sure its in the data section. */
+extern void force_data_section PROTO((void));
+
/* Tell assembler to switch to read-only data section. This is normally
the text section. */
extern void readonly_data_section PROTO((void));
@@ -158,7 +161,7 @@ extern void eh_frame_section PROTO ((void));
If DECL is NULL, just switch to section NAME.
If NAME is NULL, get the name from DECL.
If RELOC is 1, the initializer for DECL contains relocs. */
-extern void named_section PROTO((tree, char *, int));
+extern void named_section PROTO((tree, const char *, int));
/* Tell assembler to switch to the section for function DECL. */
extern void function_section PROTO((tree));
@@ -185,7 +188,7 @@ extern void weak_finish PROTO ((void));
or -4 if ASMSPEC is `memory' and is not recognized.
Accept an exact spelling or a decimal number.
Prefixes such as % are optional. */
-extern int decode_reg_name PROTO((char *));
+extern int decode_reg_name PROTO((const char *));
#ifdef TREE_CODE
/* Create the DECL_RTL for a declaration for a static or external variable
@@ -195,7 +198,7 @@ extern int decode_reg_name PROTO((char *));
TOP_LEVEL is nonzero if this is a file-scope variable.
This is never called for PARM_DECL nodes. */
-extern void make_decl_rtl PROTO((tree, char *, int));
+extern void make_decl_rtl PROTO((tree, const char *, int));
/* Make the rtl for variable VAR be volatile.
Use this only for static variables. */
@@ -242,7 +245,7 @@ extern void assemble_zeros PROTO((int));
extern void assemble_align PROTO((int));
/* Assemble a string constant with the specified C string as contents. */
-extern void assemble_string PROTO((char *, int));
+extern void assemble_string PROTO((const char *, int));
/* Assemble everything that is needed for a variable or function declaration.
Not used for automatic variables, and not used for function definitions.
Should not be called for variables of incomplete structure type.
@@ -351,6 +354,12 @@ extern int sdb_begin_function_line;
extern FILE *asm_out_file;
#endif
+/* Default file in which to dump debug output. */
+
+#ifdef BUFSIZ
+extern FILE *rtl_dump_file;
+#endif
+
/* Decide whether DECL needs to be in a writable section. RELOC is the same
as for SELECT_SECTION. */
@@ -361,3 +370,6 @@ extern FILE *asm_out_file;
&& (DECL_INITIAL (DECL) == error_mark_node \
|| TREE_CONSTANT (DECL_INITIAL (DECL))) \
&& ! (RELOC && (flag_pic || DECL_ONE_ONLY (DECL))))
+
+/* User label prefix in effect for this compilation. */
+extern const char *user_label_prefix;
diff --git a/gcc/prefix.c b/gcc/prefix.c
index 778600bff8d..e5ca9239410 100644
--- a/gcc/prefix.c
+++ b/gcc/prefix.c
@@ -1,5 +1,5 @@
/* Utility to update paths from internal to external forms.
- Copyright (C) 1997, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -68,15 +68,13 @@ Boston, MA 02111-1307, USA. */
#ifdef _WIN32
#include <windows.h>
#endif
+#include "prefix.h"
-#include "gansidecl.h"
+static const char *std_prefix = PREFIX;
-static char *std_prefix = PREFIX;
-
-static char *get_key_value PROTO((char *));
-static char *translate_name PROTO((char *));
-static char *concat PVPROTO((char *, ...));
-static char *save_string PROTO((char *, int));
+static const char *get_key_value PROTO((char *));
+static const char *translate_name PROTO((const char *));
+static char *save_string PROTO((const char *, int));
#ifdef _WIN32
static char *lookup_key PROTO((char *));
@@ -85,11 +83,11 @@ static HKEY reg_key = (HKEY) INVALID_HANDLE_VALUE;
/* Given KEY, as above, return its value. */
-static char *
+static const char *
get_key_value (key)
char *key;
{
- char *prefix = 0;
+ const char *prefix = 0;
char *temp = 0;
#ifdef _WIN32
@@ -112,23 +110,23 @@ get_key_value (key)
This function is based on the one in libiberty. */
-static char *
-concat VPROTO((char *first, ...))
+char *
+concat VPROTO((const char *first, ...))
{
register int length;
register char *newstr;
register char *end;
- register char *arg;
+ register const char *arg;
va_list args;
-#ifndef __STDC__
- char *first;
+#ifndef ANSI_PROTOTYPES
+ const char *first;
#endif
/* First compute the size of the result and get sufficient memory. */
VA_START (args, first);
-#ifndef __STDC__
- first = va_arg (args, char *);
+#ifndef ANSI_PROTOTYPES
+ first = va_arg (args, const char *);
#endif
arg = first;
@@ -137,7 +135,7 @@ concat VPROTO((char *first, ...))
while (arg != 0)
{
length += strlen (arg);
- arg = va_arg (args, char *);
+ arg = va_arg (args, const char *);
}
newstr = (char *) malloc (length + 1);
@@ -146,7 +144,7 @@ concat VPROTO((char *first, ...))
/* Now copy the individual pieces to the result string. */
VA_START (args, first);
-#ifndef __STDC__
+#ifndef ANSI_PROTOTYPES
first = va_arg (args, char *);
#endif
@@ -156,7 +154,7 @@ concat VPROTO((char *first, ...))
{
while (*arg)
*end++ = *arg++;
- arg = va_arg (args, char *);
+ arg = va_arg (args, const char *);
}
*end = '\000';
va_end (args);
@@ -168,10 +166,10 @@ concat VPROTO((char *first, ...))
static char *
save_string (s, len)
- char *s;
- int len;
+ const char *s;
+ int len;
{
- register char *result = (char *) malloc (len + 1);
+ register char *result = xmalloc (len + 1);
bcopy (s, result, len);
result[len] = 0;
@@ -230,12 +228,13 @@ lookup_key (key)
/* If NAME starts with a '@' or '$', apply the translation rules above
and return a new name. Otherwise, return the given name. */
-static char *
+static const char *
translate_name (name)
- char *name;
+ const char *name;
{
char code = name[0];
- char *key, *prefix = 0;
+ char *key;
+ const char *prefix = 0;
int keylen;
if (code != '@' && code != '$')
@@ -275,8 +274,9 @@ translate_name (name)
#endif
)
{
- prefix = save_string (prefix, strlen (prefix));
- prefix[strlen (prefix) - 1] = 0;
+ char * temp = save_string (prefix, strlen (prefix));
+ temp[strlen (temp) - 1] = 0;
+ prefix = temp;
}
return concat (prefix, name, NULL_PTR);
@@ -284,10 +284,10 @@ translate_name (name)
/* Update PATH using KEY if PATH starts with PREFIX. */
-char *
+const char *
update_path (path, key)
- char *path;
- char *key;
+ const char *path;
+ const char *key;
{
if (! strncmp (path, std_prefix, strlen (std_prefix)) && key != 0)
{
@@ -319,8 +319,8 @@ update_path (path, key)
/* Reset the standard prefix */
void
set_std_prefix (prefix, len)
- char *prefix;
- int len;
+ const char *prefix;
+ int len;
{
std_prefix = save_string (prefix, len);
}
diff --git a/gcc/print-rtl.c b/gcc/print-rtl.c
index e3b36fe0a26..e72a77bf5e9 100644
--- a/gcc/print-rtl.c
+++ b/gcc/print-rtl.c
@@ -1,5 +1,5 @@
/* Print RTL for GNU C Compiler.
- Copyright (C) 1987, 1988, 1992, 1997 Free Software Foundation, Inc.
+ Copyright (C) 1987, 1988, 1992, 1997, 1998 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -22,9 +22,9 @@ Boston, MA 02111-1307, USA. */
#include "config.h"
#include "system.h"
#include "rtl.h"
-#include "bitmap.h"
#include "real.h"
#include "flags.h"
+#include "basic-block.h"
/* How to print out a register name.
@@ -45,7 +45,7 @@ static char *reg_names[] = REGISTER_NAMES;
static FILE *outfile;
-char spaces[] = " ";
+static const char xspaces[] = " ";
static int sawclose = 0;
@@ -55,63 +55,93 @@ static int indent;
extern char **insn_name_ptr;
+static void print_rtx PROTO ((rtx));
+
/* Nonzero means suppress output of instruction numbers and line number
notes in debugging dumps.
This must be defined here so that programs like gencodes can be linked. */
int flag_dump_unnumbered = 0;
+/* Nonzero if we are dumping graphical description. */
+int dump_for_graph;
+
/* Print IN_RTX onto OUTFILE. This is the recursive part of printing. */
static void
print_rtx (in_rtx)
register rtx in_rtx;
{
- register int i, j;
+ register int i = 0;
+ register int j;
register char *format_ptr;
register int is_insn;
if (sawclose)
{
fprintf (outfile, "\n%s",
- (spaces + (sizeof spaces - 1 - indent * 2)));
+ (xspaces + (sizeof xspaces - 1 - indent * 2)));
sawclose = 0;
}
if (in_rtx == 0)
{
- fprintf (outfile, "(nil)");
+ fputs ("(nil)", outfile);
sawclose = 1;
return;
}
- /* print name of expression code */
- fprintf (outfile, "(%s", GET_RTX_NAME (GET_CODE (in_rtx)));
+ is_insn = (GET_RTX_CLASS (GET_CODE (in_rtx)) == 'i');
- if (in_rtx->in_struct)
- fprintf (outfile, "/s");
+ /* When printing in VCG format we write INSNs, NOTE, LABEL, and BARRIER
+ in separate nodes and therefore have to handle them special here. */
+ if (dump_for_graph &&
+ (is_insn || GET_CODE (in_rtx) == NOTE || GET_CODE (in_rtx) == CODE_LABEL
+ || GET_CODE (in_rtx) == BARRIER))
+ {
+ i = 3;
+ indent = 0;
+ }
+ else
+ {
+ /* print name of expression code */
+ fprintf (outfile, "(%s", GET_RTX_NAME (GET_CODE (in_rtx)));
- if (in_rtx->volatil)
- fprintf (outfile, "/v");
+ if (in_rtx->in_struct)
+ fputs ("/s", outfile);
- if (in_rtx->unchanging)
- fprintf (outfile, "/u");
+ if (in_rtx->volatil)
+ fputs ("/v", outfile);
- if (in_rtx->integrated)
- fprintf (outfile, "/i");
+ if (in_rtx->unchanging)
+ fputs ("/u", outfile);
- if (GET_MODE (in_rtx) != VOIDmode)
- {
- /* Print REG_NOTE names for EXPR_LIST and INSN_LIST. */
- if (GET_CODE (in_rtx) == EXPR_LIST || GET_CODE (in_rtx) == INSN_LIST)
- fprintf (outfile, ":%s", GET_REG_NOTE_NAME (GET_MODE (in_rtx)));
- else
- fprintf (outfile, ":%s", GET_MODE_NAME (GET_MODE (in_rtx)));
+ if (in_rtx->integrated)
+ fputs ("/i", outfile);
+
+ if (in_rtx->frame_related)
+ fputs ("/f", outfile);
+
+ if (in_rtx->jump)
+ fputs ("/j", outfile);
+
+ if (in_rtx->call)
+ fputs ("/c", outfile);
+
+ if (GET_MODE (in_rtx) != VOIDmode)
+ {
+ /* Print REG_NOTE names for EXPR_LIST and INSN_LIST. */
+ if (GET_CODE (in_rtx) == EXPR_LIST || GET_CODE (in_rtx) == INSN_LIST)
+ fprintf (outfile, ":%s", GET_REG_NOTE_NAME (GET_MODE (in_rtx)));
+ else
+ fprintf (outfile, ":%s", GET_MODE_NAME (GET_MODE (in_rtx)));
+ }
}
- is_insn = (GET_RTX_CLASS (GET_CODE (in_rtx)) == 'i');
- format_ptr = GET_RTX_FORMAT (GET_CODE (in_rtx));
+ /* Get the format string and skip the first elements if we have handled
+ them already. */
+ format_ptr = GET_RTX_FORMAT (GET_CODE (in_rtx)) + i;
- for (i = 0; i < GET_RTX_LENGTH (GET_CODE (in_rtx)); i++)
+ for (; i < GET_RTX_LENGTH (GET_CODE (in_rtx)); i++)
switch (*format_ptr++)
{
case 'S':
@@ -140,10 +170,19 @@ print_rtx (in_rtx)
break;
}
+ if (i == 3 && GET_CODE (in_rtx) == NOTE
+ && NOTE_LINE_NUMBER (in_rtx) == NOTE_INSN_BASIC_BLOCK)
+ {
+ basic_block bb = NOTE_BASIC_BLOCK (in_rtx);
+ fprintf (outfile, " [bb %d]", bb->index);
+ break;
+ }
+
if (XSTR (in_rtx, i) == 0)
- fprintf (outfile, " \"\"");
+ fputs (dump_for_graph ? " \\\"\\\"" : " \"\"", outfile);
else
- fprintf (outfile, " (\"%s\")", XSTR (in_rtx, i));
+ fprintf (outfile, dump_for_graph ? " (\\\"%s\\\")" : " (\"%s\")",
+ XSTR (in_rtx, i));
sawclose = 1;
break;
@@ -165,10 +204,10 @@ print_rtx (in_rtx)
if (sawclose)
{
fprintf (outfile, "\n%s",
- (spaces + (sizeof spaces - 1 - indent * 2)));
+ (xspaces + (sizeof xspaces - 1 - indent * 2)));
sawclose = 0;
}
- fprintf (outfile, "[ ");
+ fputs ("[ ", outfile);
if (NULL != XVEC (in_rtx, i))
{
indent += 2;
@@ -182,9 +221,9 @@ print_rtx (in_rtx)
}
if (sawclose)
fprintf (outfile, "\n%s",
- (spaces + (sizeof spaces - 1 - indent * 2)));
+ (xspaces + (sizeof xspaces - 1 - indent * 2)));
- fprintf (outfile, "] ");
+ fputs ("] ", outfile);
sawclose = 1;
indent -= 2;
break;
@@ -205,7 +244,7 @@ print_rtx (in_rtx)
}
else if (flag_dump_unnumbered
&& (is_insn || GET_CODE (in_rtx) == NOTE))
- fprintf (outfile, "#");
+ fputc ('#', outfile);
else
fprintf (outfile, " %d", value);
}
@@ -230,18 +269,18 @@ print_rtx (in_rtx)
if (XEXP (in_rtx, i) != NULL)
{
if (flag_dump_unnumbered)
- fprintf (outfile, "#");
+ fputc ('#', outfile);
else
fprintf (outfile, " %d", INSN_UID (XEXP (in_rtx, i)));
}
else
- fprintf (outfile, " 0");
+ fputs (" 0", outfile);
sawclose = 0;
break;
case 'b':
if (XBITMAP (in_rtx, i) == NULL)
- fprintf (outfile, " {null}");
+ fputs (" {null}", outfile);
else
bitmap_print (outfile, XBITMAP (in_rtx, i), " {", "}");
sawclose = 0;
@@ -253,7 +292,7 @@ print_rtx (in_rtx)
break;
case '*':
- fprintf (outfile, " Unknown");
+ fputs (" Unknown", outfile);
sawclose = 0;
break;
@@ -276,8 +315,15 @@ print_rtx (in_rtx)
}
#endif
- fprintf (outfile, ")");
- sawclose = 1;
+ if (dump_for_graph
+ && (is_insn || GET_CODE (in_rtx) == NOTE
+ || GET_CODE (in_rtx) == CODE_LABEL || GET_CODE (in_rtx) == BARRIER))
+ sawclose = 0;
+ else
+ {
+ fputc (')', outfile);
+ sawclose = 1;
+ }
}
/* Print an rtx on the current line of FILE. Initially indent IND
@@ -386,7 +432,7 @@ print_rtl (outf, rtx_first)
sawclose = 0;
if (rtx_first == 0)
- fprintf (outf, "(nil)\n");
+ fputs ("(nil)\n", outf);
else
switch (GET_CODE (rtx_first))
{
diff --git a/gcc/print-tree.c b/gcc/print-tree.c
index 851b06636e7..b4cc87913e0 100644
--- a/gcc/print-tree.c
+++ b/gcc/print-tree.c
@@ -1,5 +1,5 @@
/* Prints out tree in human readable form - GNU C-compiler
- Copyright (C) 1990, 91, 93, 94, 95, 96, 1997 Free Software Foundation, Inc.
+ Copyright (C) 1990, 91, 93-97, 1998 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -64,7 +64,7 @@ debug_tree (node)
void
print_node_brief (file, prefix, node, indent)
FILE *file;
- char *prefix;
+ const char *prefix;
tree node;
int indent;
{
@@ -176,7 +176,7 @@ indent_to (file, column)
void
print_node (file, prefix, node, indent)
FILE *file;
- char *prefix;
+ const char *prefix;
tree node;
int indent;
{
@@ -408,6 +408,8 @@ print_node (file, prefix, node, indent)
fprintf (file, " built-in code %d", DECL_FUNCTION_CODE (node));
if (TREE_CODE (node) == FIELD_DECL)
print_node (file, "bitpos", DECL_FIELD_BITPOS (node), indent + 4);
+ if (DECL_POINTER_ALIAS_SET_KNOWN_P (node))
+ fprintf (file, " alias set %d", DECL_POINTER_ALIAS_SET (node));
print_node_brief (file, "context", DECL_CONTEXT (node), indent + 4);
print_node_brief (file, "machine_attributes", DECL_MACHINE_ATTRIBUTES (node), indent + 4);
print_node_brief (file, "abstract_origin",
@@ -536,7 +538,7 @@ print_node (file, prefix, node, indent)
print_node (file, "chain", BLOCK_CHAIN (node), indent + 4);
print_node (file, "abstract_origin",
BLOCK_ABSTRACT_ORIGIN (node), indent + 4);
- return;
+ break;
case 'e':
case '<':
@@ -549,7 +551,7 @@ print_node (file, prefix, node, indent)
print_node (file, "vars", TREE_OPERAND (node, 0), indent + 4);
print_node (file, "body", TREE_OPERAND (node, 1), indent + 4);
print_node (file, "block", TREE_OPERAND (node, 2), indent + 4);
- return;
+ break;
}
len = tree_code_length[(int) TREE_CODE (node)];
diff --git a/gcc/profile.c b/gcc/profile.c
index 460c0cf9c6b..d454b453966 100644
--- a/gcc/profile.c
+++ b/gcc/profile.c
@@ -1,5 +1,5 @@
/* Calculate branch probabilities, and basic block execution counts.
- Copyright (C) 1990, 91-94, 96, 97, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1990, 91-94, 96-98, 1999 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.
@@ -18,7 +18,8 @@ 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
/* ??? Really should not put insns inside of LIBCALL sequences, when putting
insns after a call, should look for the insn setting the retval, and
@@ -1410,7 +1411,7 @@ expand_spanning_tree (block)
void
init_branch_prob (filename)
- char *filename;
+ const char *filename;
{
long len;
int i;
@@ -1667,7 +1668,13 @@ output_func_start_profiler ()
TREE_PUBLIC (fndecl) = 1;
DECL_ASSEMBLER_NAME (fndecl) = fnname;
DECL_RESULT (fndecl) = build_decl (RESULT_DECL, NULL_TREE, void_type_node);
+
+ fndecl = pushdecl (fndecl);
+ rest_of_decl_compilation (fndecl, 0, 1, 0);
+ announce_function (fndecl);
current_function_decl = fndecl;
+ DECL_INITIAL (fndecl) = error_mark_node;
+ temporary_allocation ();
pushlevel (0);
make_function_rtl (fndecl);
init_function_start (fndecl, input_filename, lineno);
diff --git a/gcc/protoize.c b/gcc/protoize.c
index a7a5ae92e2b..3c5ee622f51 100644
--- a/gcc/protoize.c
+++ b/gcc/protoize.c
@@ -1,5 +1,5 @@
/* Protoize program - Original version by Ron Guilmette (rfg@segfault.us.com).
- Copyright (C) 1989, 92-97, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1989, 92-98, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -58,8 +58,9 @@ Boston, MA 02111-1307, USA. */
#endif
#include "system.h"
-#include <sys/stat.h>
-#if ! defined (_WIN32) || defined (__CYGWIN32__)
+#include "intl.h"
+
+#if ! defined (_WIN32) || defined (__CYGWIN__) || defined (_UWIN)
#if defined(POSIX) || defined(CONCURRENT)
#include <dirent.h>
#else
@@ -67,7 +68,6 @@ Boston, MA 02111-1307, USA. */
#endif
#endif
#include <setjmp.h>
-#include "gansidecl.h"
/* Some systems like Linux don't declare rindex if _POSIX_SOURCE is declared,
but it normally does declare it. This means that configure thinks we don't
@@ -110,49 +110,23 @@ extern char *version_string;
extern char *getpwd ();
-extern char *choose_temp_base PROTO ((void));
-extern char * my_strerror PROTO ((int));
-
-extern int pexecute PROTO ((const char *, char * const *, const char *,
- const char *, char **, char **, int));
-extern int pwait PROTO ((int, int *, int));
-/* Flag arguments to pexecute. */
-#define PEXECUTE_FIRST 1
-#define PEXECUTE_LAST 2
-#define PEXECUTE_SEARCH 4
+static void usage PROTO ((void)) ATTRIBUTE_NORETURN;
+static void aux_info_corrupted PROTO ((void)) ATTRIBUTE_NORETURN;
+static void declare_source_confusing PROTO ((const char *)) ATTRIBUTE_NORETURN;
/* Aliases for pointers to void.
These were made to facilitate compilation with old brain-dead DEC C
compilers which didn't properly grok `void*' types. */
-#ifdef __STDC__
-typedef void * pointer_type;
-typedef const void * const_pointer_type;
-#else
-typedef char * pointer_type;
-typedef char * const_pointer_type;
-#endif
+typedef PTR pointer_type;
+typedef const PTR const_pointer_type;
#if defined(POSIX)
#include <signal.h>
-#include <sys/wait.h>
#else /* !defined(POSIX) */
-#ifndef WIFSIGNALED
-#define WIFSIGNALED(S) (((S) & 0xff) != 0 && ((S) & 0xff) != 0x7f)
-#endif
-#ifndef WTERMSIG
-#define WTERMSIG(S) ((S) & 0x7f)
-#endif
-#ifndef WIFEXITED
-#define WIFEXITED(S) (((S) & 0xff) == 0)
-#endif
-#ifndef WEXITSTATUS
-#define WEXITSTATUS(S) (((S) & 0xff00) >> 8)
-#endif
-
/* Declaring stat or __flsbuf with a prototype
causes conflicts with system headers on some systems. */
@@ -168,8 +142,12 @@ extern int close ();
extern int fflush ();
extern int atoi ();
extern int puts ();
+#ifndef fputs /* This may have been #defined by "system.h". */
extern int fputs ();
+#endif
+#ifndef fputc /* some systems define this as a macro. */
extern int fputc ();
+#endif
extern int unlink ();
extern int access ();
@@ -178,12 +156,6 @@ extern int access ();
extern size_t strlen ()
#endif
-/* Fork is not declared because the declaration caused a conflict
- on the HPPA. */
-#if !(defined (USG) || defined (VMS))
-#define fork vfork
-#endif /* (defined (USG) || defined (VMS)) */
-
#endif /* !defined (POSIX) */
/* Look for these where the `const' qualifier is intentionally cast aside. */
@@ -595,25 +567,44 @@ static char * saved_repl_write_ptr;
static const char *shortpath ();
+/* Translate and output an error message. */
+static void notice PVPROTO ((const char *, ...))
+ ATTRIBUTE_PRINTF_1;
+static void
+notice VPROTO ((const char *msgid, ...))
+{
+#ifndef ANSI_PROTOTYPES
+ const char *msgid;
+#endif
+ va_list ap;
+
+ VA_START (ap, msgid);
+
+#ifndef ANSI_PROTOTYPES
+ msgid = va_arg (ap, const char *);
+#endif
+
+ vfprintf (stderr, _(msgid), ap);
+ va_end (ap);
+}
+
+
char *
-my_strerror(e)
- int e;
+xstrerror(e)
+ int e;
{
#ifdef HAVE_STRERROR
return strerror(e);
#else
-
- static char buffer[30];
if (!e)
return "";
if (e > 0 && e < sys_nerr)
return sys_errlist[e];
- sprintf (buffer, "Unknown error %d", e);
- return buffer;
+ return "errno = ?";
#endif
}
@@ -622,19 +613,15 @@ my_strerror(e)
pointer_type
xmalloc (byte_count)
- size_t byte_count;
+ size_t byte_count;
{
- pointer_type rv;
-
- rv = (pointer_type) malloc (byte_count);
+ register pointer_type rv = (pointer_type) malloc (byte_count);
if (rv == NULL)
{
- fprintf (stderr, "\n%s: virtual memory exceeded\n", pname);
+ notice ("\n%s: virtual memory exceeded\n", pname);
exit (FATAL_EXIT_CODE);
- return 0; /* avoid warnings */
}
- else
- return rv;
+ return rv;
}
/* Reallocate some space, but check that the reallocation was successful. */
@@ -644,17 +631,17 @@ xrealloc (old_space, byte_count)
pointer_type old_space;
size_t byte_count;
{
- pointer_type rv;
-
- rv = (pointer_type) realloc (old_space, byte_count);
+ register pointer_type rv;
+ if (old_space)
+ rv = (pointer_type) realloc (old_space, byte_count);
+ else
+ rv = (pointer_type) malloc (byte_count);
if (rv == NULL)
{
- fprintf (stderr, "\n%s: virtual memory exceeded\n", pname);
+ notice ("\n%s: virtual memory exceeded\n", pname);
exit (FATAL_EXIT_CODE);
- return 0; /* avoid warnings */
}
- else
- return rv;
+ return rv;
}
/* Deallocate the area pointed to by an arbitrary pointer, but first, strip
@@ -702,7 +689,7 @@ savestring2 (input1, size1, input2, size2)
void
fancy_abort ()
{
- fprintf (stderr, "%s: internal abort\n", pname);
+ notice ("%s: internal abort\n", pname);
exit (FATAL_EXIT_CODE);
}
@@ -792,8 +779,8 @@ safe_write (desc, ptr, len, out_fname)
if (errno_val == EINTR)
continue;
#endif
- fprintf (stderr, "%s: error writing file `%s': %s\n",
- pname, shortpath (NULL, out_fname), my_strerror (errno_val));
+ notice ("%s: error writing file `%s': %s\n",
+ pname, shortpath (NULL, out_fname), xstrerror (errno_val));
return;
}
ptr += written;
@@ -824,7 +811,7 @@ restore_pointers ()
static int
is_id_char (ch)
- char ch;
+ unsigned char ch;
{
return (ISALNUM (ch) || (ch == '_') || (ch == '$'));
}
@@ -836,11 +823,11 @@ static void
usage ()
{
#ifdef UNPROTOIZE
- fprintf (stderr, "%s: usage '%s [ -VqfnkN ] [ -i <istring> ] [ filename ... ]'\n",
- pname, pname);
+ notice ("%s: usage '%s [ -VqfnkN ] [ -i <istring> ] [ filename ... ]'\n",
+ pname, pname);
#else /* !defined (UNPROTOIZE) */
- fprintf (stderr, "%s: usage '%s [ -VqfnkNlgC ] [ -B <dirname> ] [ filename ... ]'\n",
- pname, pname);
+ notice ("%s: usage '%s [ -VqfnkNlgC ] [ -B <dirname> ] [ filename ... ]'\n",
+ pname, pname);
#endif /* !defined (UNPROTOIZE) */
exit (FATAL_EXIT_CODE);
}
@@ -926,24 +913,24 @@ file_normally_convertible (const char *path)
if (my_access (path, R_OK))
{
if (!quiet_flag)
- fprintf (stderr, "%s: warning: no read access for file `%s'\n",
- pname, shortpath (NULL, path));
+ notice ("%s: warning: no read access for file `%s'\n",
+ pname, shortpath (NULL, path));
return 0;
}
if (my_access (path, W_OK))
{
if (!quiet_flag)
- fprintf (stderr, "%s: warning: no write access for file `%s'\n",
- pname, shortpath (NULL, path));
+ notice ("%s: warning: no write access for file `%s'\n",
+ pname, shortpath (NULL, path));
return 0;
}
if (my_access (dir_name, W_OK))
{
if (!quiet_flag)
- fprintf (stderr, "%s: warning: no write access for dir containing `%s'\n",
- pname, shortpath (NULL, path));
+ notice ("%s: warning: no write access for dir containing `%s'\n",
+ pname, shortpath (NULL, path));
return 0;
}
@@ -1300,7 +1287,7 @@ abspath (cwd, rel_filename)
outp = inp = abs_buffer;
*outp++ = *inp++; /* copy first slash */
-#ifdef apollo
+#if defined (apollo) || defined (_WIN32) || defined (__INTERIX)
if (inp[0] == '/')
*outp++ = *inp++; /* copy second slash */
#endif
@@ -1334,8 +1321,8 @@ abspath (cwd, rel_filename)
point above the absolute root of the logical file
system. */
- fprintf (stderr, "%s: invalid file name: %s\n",
- pname, rel_filename);
+ notice ("%s: invalid file name: %s\n",
+ pname, rel_filename);
exit (FATAL_EXIT_CODE);
}
*++outp = '\0';
@@ -1485,9 +1472,9 @@ find_file (filename, do_not_stat)
if (my_stat (filename, &stat_buf) == -1)
{
int errno_val = errno;
- fprintf (stderr, "%s: %s: can't get status: %s\n",
- pname, shortpath (NULL, filename),
- my_strerror (errno_val));
+ notice ("%s: %s: can't get status: %s\n",
+ pname, shortpath (NULL, filename),
+ xstrerror (errno_val));
stat_buf.st_mtime = (time_t) -1;
}
}
@@ -1506,8 +1493,8 @@ find_file (filename, do_not_stat)
static void
aux_info_corrupted ()
{
- fprintf (stderr, "\n%s: fatal error: aux info file corrupted at line %d\n",
- pname, current_aux_info_lineno);
+ notice ("\n%s: fatal error: aux info file corrupted at line %d\n",
+ pname, current_aux_info_lineno);
exit (FATAL_EXIT_CODE);
}
@@ -1830,10 +1817,10 @@ save_def_or_dec (l, is_syscalls)
{
if (strcmp (def_dec_p->ansi_decl, other->ansi_decl))
{
- fprintf (stderr, "%s:%d: declaration of function `%s' takes different forms\n",
- def_dec_p->file->hash_entry->symbol,
- def_dec_p->line,
- def_dec_p->hash_entry->symbol);
+ notice ("%s:%d: declaration of function `%s' takes different forms\n",
+ def_dec_p->file->hash_entry->symbol,
+ def_dec_p->line,
+ def_dec_p->hash_entry->symbol);
exit (FATAL_EXIT_CODE);
}
free_def_dec (def_dec_p);
@@ -2002,12 +1989,12 @@ munge_compile_params (params_list)
temp_params[param_count++] = compiler_file_name;
for (;;)
{
- while (ISSPACE (*params_list))
+ while (ISSPACE ((const unsigned char)*params_list))
params_list++;
if (!*params_list)
break;
param = params_list;
- while (*params_list && !ISSPACE (*params_list))
+ while (*params_list && !ISSPACE ((const unsigned char)*params_list))
params_list++;
if (param[0] != '-')
temp_params[param_count++]
@@ -2022,9 +2009,10 @@ munge_compile_params (params_list)
case 'c':
break; /* Don't copy these. */
case 'o':
- while (ISSPACE (*params_list))
+ while (ISSPACE ((const unsigned char)*params_list))
params_list++;
- while (*params_list && !ISSPACE (*params_list))
+ while (*params_list
+ && !ISSPACE ((const unsigned char)*params_list))
params_list++;
break;
default:
@@ -2080,8 +2068,8 @@ gen_aux_info_file (base_filename)
2);
if (!quiet_flag)
- fprintf (stderr, "%s: compiling `%s'\n",
- pname, compile_params[input_file_name_index]);
+ notice ("%s: compiling `%s'\n",
+ pname, compile_params[input_file_name_index]);
{
char *errmsg_fmt, *errmsg_arg;
@@ -2097,28 +2085,28 @@ gen_aux_info_file (base_filename)
int errno_val = errno;
fprintf (stderr, "%s: ", pname);
fprintf (stderr, errmsg_fmt, errmsg_arg);
- fprintf (stderr, ": %s\n", my_strerror (errno_val));
+ fprintf (stderr, ": %s\n", xstrerror (errno_val));
return 0;
}
pid = pwait (pid, &wait_status, 0);
if (pid == -1)
{
- fprintf (stderr, "%s: wait: %s\n", pname, my_strerror (errno));
+ notice ("%s: wait: %s\n", pname, xstrerror (errno));
return 0;
}
if (WIFSIGNALED (wait_status))
{
- fprintf (stderr, "%s: subprocess got fatal signal %d\n",
- pname, WTERMSIG (wait_status));
+ notice ("%s: subprocess got fatal signal %d\n",
+ pname, WTERMSIG (wait_status));
return 0;
}
if (WIFEXITED (wait_status))
{
if (WEXITSTATUS (wait_status) != 0)
{
- fprintf (stderr, "%s: %s exited with status %d\n",
- pname, compile_params[0], WEXITSTATUS (wait_status));
+ notice ("%s: %s exited with status %d\n",
+ pname, compile_params[0], WEXITSTATUS (wait_status));
return 0;
}
return 1;
@@ -2169,8 +2157,8 @@ start_over: ;
{
if (is_syscalls)
{
- fprintf (stderr, "%s: warning: missing SYSCALLS file `%s'\n",
- pname, aux_info_filename);
+ notice ("%s: warning: missing SYSCALLS file `%s'\n",
+ pname, aux_info_filename);
return;
}
must_create = 1;
@@ -2178,9 +2166,9 @@ start_over: ;
else
{
int errno_val = errno;
- fprintf (stderr, "%s: can't read aux info file `%s': %s\n",
- pname, shortpath (NULL, aux_info_filename),
- my_strerror (errno_val));
+ notice ("%s: can't read aux info file `%s': %s\n",
+ pname, shortpath (NULL, aux_info_filename),
+ xstrerror (errno_val));
errors++;
return;
}
@@ -2207,9 +2195,9 @@ start_over: ;
if (my_access (aux_info_filename, R_OK) == -1)
{
int errno_val = errno;
- fprintf (stderr, "%s: can't read aux info file `%s': %s\n",
- pname, shortpath (NULL, aux_info_filename),
- my_strerror (errno_val));
+ notice ("%s: can't read aux info file `%s': %s\n",
+ pname, shortpath (NULL, aux_info_filename),
+ xstrerror (errno_val));
errors++;
return;
}
@@ -2223,9 +2211,9 @@ start_over: ;
if (my_stat (aux_info_filename, &stat_buf) == -1)
{
int errno_val = errno;
- fprintf (stderr, "%s: can't get status of aux info file `%s': %s\n",
- pname, shortpath (NULL, aux_info_filename),
- my_strerror (errno_val));
+ notice ("%s: can't get status of aux info file `%s': %s\n",
+ pname, shortpath (NULL, aux_info_filename),
+ xstrerror (errno_val));
errors++;
return;
}
@@ -2251,9 +2239,9 @@ start_over: ;
if (my_stat (base_source_filename, &stat_buf) == -1)
{
int errno_val = errno;
- fprintf (stderr, "%s: can't get status of aux info file `%s': %s\n",
- pname, shortpath (NULL, base_source_filename),
- my_strerror (errno_val));
+ notice ("%s: can't get status of aux info file `%s': %s\n",
+ pname, shortpath (NULL, base_source_filename),
+ xstrerror (errno_val));
errors++;
return;
}
@@ -2273,9 +2261,9 @@ start_over: ;
if ((aux_info_file = my_open (aux_info_filename, O_RDONLY, 0444 )) == -1)
{
int errno_val = errno;
- fprintf (stderr, "%s: can't open aux info file `%s' for reading: %s\n",
- pname, shortpath (NULL, aux_info_filename),
- my_strerror (errno_val));
+ notice ("%s: can't open aux info file `%s' for reading: %s\n",
+ pname, shortpath (NULL, aux_info_filename),
+ xstrerror (errno_val));
return;
}
@@ -2287,12 +2275,13 @@ start_over: ;
/* Read the aux_info file into memory. */
- if (safe_read (aux_info_file, aux_info_base, aux_info_size) != aux_info_size)
+ if (safe_read (aux_info_file, aux_info_base, aux_info_size) !=
+ (int) aux_info_size)
{
int errno_val = errno;
- fprintf (stderr, "%s: error reading aux info file `%s': %s\n",
- pname, shortpath (NULL, aux_info_filename),
- my_strerror (errno_val));
+ notice ("%s: error reading aux info file `%s': %s\n",
+ pname, shortpath (NULL, aux_info_filename),
+ xstrerror (errno_val));
free (aux_info_base);
close (aux_info_file);
return;
@@ -2303,9 +2292,9 @@ start_over: ;
if (close (aux_info_file))
{
int errno_val = errno;
- fprintf (stderr, "%s: error closing aux info file `%s': %s\n",
- pname, shortpath (NULL, aux_info_filename),
- my_strerror (errno_val));
+ notice ("%s: error closing aux info file `%s': %s\n",
+ pname, shortpath (NULL, aux_info_filename),
+ xstrerror (errno_val));
free (aux_info_base);
close (aux_info_file);
return;
@@ -2319,9 +2308,9 @@ start_over: ;
if (my_unlink (aux_info_filename) == -1)
{
int errno_val = errno;
- fprintf (stderr, "%s: can't delete aux info file `%s': %s\n",
- pname, shortpath (NULL, aux_info_filename),
- my_strerror (errno_val));
+ notice ("%s: can't delete aux info file `%s': %s\n",
+ pname, shortpath (NULL, aux_info_filename),
+ xstrerror (errno_val));
}
/* Save a pointer into the first line of the aux_info file which
@@ -2387,9 +2376,9 @@ start_over: ;
if (keep_it && my_unlink (aux_info_filename) == -1)
{
int errno_val = errno;
- fprintf (stderr, "%s: can't delete file `%s': %s\n",
- pname, shortpath (NULL, aux_info_filename),
- my_strerror (errno_val));
+ notice ("%s: can't delete file `%s': %s\n",
+ pname, shortpath (NULL, aux_info_filename),
+ xstrerror (errno_val));
return;
}
must_create = 1;
@@ -2464,9 +2453,9 @@ rename_c_file (hp)
if (my_link (filename, new_filename) == -1)
{
int errno_val = errno;
- fprintf (stderr, "%s: warning: can't link file `%s' to `%s': %s\n",
- pname, shortpath (NULL, filename),
- shortpath (NULL, new_filename), my_strerror (errno_val));
+ notice ("%s: warning: can't link file `%s' to `%s': %s\n",
+ pname, shortpath (NULL, filename),
+ shortpath (NULL, new_filename), xstrerror (errno_val));
errors++;
return;
}
@@ -2474,8 +2463,8 @@ rename_c_file (hp)
if (my_unlink (filename) == -1)
{
int errno_val = errno;
- fprintf (stderr, "%s: warning: can't delete file `%s': %s\n",
- pname, shortpath (NULL, filename), my_strerror (errno_val));
+ notice ("%s: warning: can't delete file `%s': %s\n",
+ pname, shortpath (NULL, filename), xstrerror (errno_val));
errors++;
return;
}
@@ -2598,14 +2587,14 @@ find_extern_def (head, user)
if (!conflict_noted) /* first time we noticed? */
{
conflict_noted = 1;
- fprintf (stderr, "%s: conflicting extern definitions of '%s'\n",
- pname, head->hash_entry->symbol);
+ notice ("%s: conflicting extern definitions of '%s'\n",
+ pname, head->hash_entry->symbol);
if (!quiet_flag)
{
- fprintf (stderr, "%s: declarations of '%s' will not be converted\n",
- pname, head->hash_entry->symbol);
- fprintf (stderr, "%s: conflict list for '%s' follows:\n",
- pname, head->hash_entry->symbol);
+ notice ("%s: declarations of '%s' will not be converted\n",
+ pname, head->hash_entry->symbol);
+ notice ("%s: conflict list for '%s' follows:\n",
+ pname, head->hash_entry->symbol);
fprintf (stderr, "%s: %s(%d): %s\n",
pname,
shortpath (NULL, extern_def_p->file->hash_entry->symbol),
@@ -2637,10 +2626,10 @@ find_extern_def (head, user)
{
extern_def_p = dd_p; /* save a pointer to the definition */
if (!quiet_flag)
- fprintf (stderr, "%s: warning: using formals list from %s(%d) for function `%s'\n",
- pname,
- shortpath (NULL, dd_p->file->hash_entry->symbol),
- dd_p->line, dd_p->hash_entry->symbol);
+ notice ("%s: warning: using formals list from %s(%d) for function `%s'\n",
+ pname,
+ shortpath (NULL, dd_p->file->hash_entry->symbol),
+ dd_p->line, dd_p->hash_entry->symbol);
break;
}
@@ -2677,15 +2666,15 @@ find_extern_def (head, user)
*p++ = '?';
strcpy (p, ");");
- fprintf (stderr, "%s: %d: `%s' used but missing from SYSCALLS\n",
- shortpath (NULL, file), user->line,
- needed+7); /* Don't print "extern " */
+ notice ("%s: %d: `%s' used but missing from SYSCALLS\n",
+ shortpath (NULL, file), user->line,
+ needed+7); /* Don't print "extern " */
}
#if 0
else
- fprintf (stderr, "%s: %d: warning: no extern definition for `%s'\n",
- shortpath (NULL, file), user->line,
- user->hash_entry->symbol);
+ notice ("%s: %d: warning: no extern definition for `%s'\n",
+ shortpath (NULL, file), user->line,
+ user->hash_entry->symbol);
#endif
}
}
@@ -2714,15 +2703,15 @@ find_static_definition (user)
if (num_static_defs == 0)
{
if (!quiet_flag)
- fprintf (stderr, "%s: warning: no static definition for `%s' in file `%s'\n",
- pname, head->hash_entry->symbol,
- shortpath (NULL, user->file->hash_entry->symbol));
+ notice ("%s: warning: no static definition for `%s' in file `%s'\n",
+ pname, head->hash_entry->symbol,
+ shortpath (NULL, user->file->hash_entry->symbol));
}
else if (num_static_defs > 1)
{
- fprintf (stderr, "%s: multiple static defs of `%s' in file `%s'\n",
- pname, head->hash_entry->symbol,
- shortpath (NULL, user->file->hash_entry->symbol));
+ notice ("%s: multiple static defs of `%s' in file `%s'\n",
+ pname, head->hash_entry->symbol,
+ shortpath (NULL, user->file->hash_entry->symbol));
return NULL;
}
return static_def_p;
@@ -2893,12 +2882,12 @@ declare_source_confusing (clean_p)
if (!quiet_flag)
{
if (clean_p == 0)
- fprintf (stderr, "%s: %d: warning: source too confusing\n",
- shortpath (NULL, convert_filename), last_known_line_number);
+ notice ("%s: %d: warning: source too confusing\n",
+ shortpath (NULL, convert_filename), last_known_line_number);
else
- fprintf (stderr, "%s: %d: warning: source too confusing\n",
- shortpath (NULL, convert_filename),
- identify_lineno (clean_p));
+ notice ("%s: %d: warning: source too confusing\n",
+ shortpath (NULL, convert_filename),
+ identify_lineno (clean_p));
}
longjmp (source_confusion_recovery, 1);
}
@@ -2955,7 +2944,8 @@ static const char *
forward_to_next_token_char (ptr)
const char *ptr;
{
- for (++ptr; ISSPACE (*ptr); check_source (++ptr < clean_text_limit, 0))
+ for (++ptr; ISSPACE ((const unsigned char)*ptr);
+ check_source (++ptr < clean_text_limit, 0))
continue;
return ptr;
}
@@ -3101,9 +3091,9 @@ edit_fn_declaration (def_dec_p, clean_text_p)
if (other_variable_style_function (definition->ansi_decl))
{
if (!quiet_flag)
- fprintf (stderr, "%s: %d: warning: varargs function declaration not converted\n",
- shortpath (NULL, def_dec_p->file->hash_entry->symbol),
- def_dec_p->line);
+ notice ("%s: %d: warning: varargs function declaration not converted\n",
+ shortpath (NULL, def_dec_p->file->hash_entry->symbol),
+ def_dec_p->line);
return;
}
@@ -3116,8 +3106,8 @@ edit_fn_declaration (def_dec_p, clean_text_p)
if (setjmp (source_confusion_recovery))
{
restore_pointers ();
- fprintf (stderr, "%s: declaration of function `%s' not converted\n",
- pname, function_to_edit);
+ notice ("%s: declaration of function `%s' not converted\n",
+ pname, function_to_edit);
return;
}
@@ -3239,8 +3229,8 @@ edit_fn_declaration (def_dec_p, clean_text_p)
else
{
if (!quiet_flag)
- fprintf (stderr, "%s: warning: too many parameter lists in declaration of `%s'\n",
- pname, def_dec_p->hash_entry->symbol);
+ notice ("%s: warning: too many parameter lists in declaration of `%s'\n",
+ pname, def_dec_p->hash_entry->symbol);
check_source (0, end_formals); /* leave the declaration intact */
}
#endif /* !defined (UNPROTOIZE) */
@@ -3260,8 +3250,8 @@ edit_fn_declaration (def_dec_p, clean_text_p)
if (this_f_list_chain_item)
{
if (!quiet_flag)
- fprintf (stderr, "\n%s: warning: too few parameter lists in declaration of `%s'\n",
- pname, def_dec_p->hash_entry->symbol);
+ notice ("\n%s: warning: too few parameter lists in declaration of `%s'\n",
+ pname, def_dec_p->hash_entry->symbol);
check_source (0, start_formals); /* leave the decl intact */
}
#endif /* !defined (UNPROTOIZE) */
@@ -3323,7 +3313,7 @@ edit_formals_lists (end_formals, f_list_count, def_dec_p)
next_end = start_formals - 1;
check_source (next_end > clean_read_ptr, 0);
- while (ISSPACE (*next_end))
+ while (ISSPACE ((const unsigned char)*next_end))
check_source (--next_end > clean_read_ptr, 0);
check_source (*next_end == ')', next_end);
check_source (--next_end > clean_read_ptr, 0);
@@ -3343,7 +3333,8 @@ edit_formals_lists (end_formals, f_list_count, def_dec_p)
const char *func_name_limit;
size_t func_name_len;
- for (func_name_limit = start_formals-1; ISSPACE (*func_name_limit); )
+ for (func_name_limit = start_formals-1;
+ ISSPACE ((const unsigned char)*func_name_limit); )
check_source (--func_name_limit > clean_read_ptr, 0);
for (func_name_start = func_name_limit++;
@@ -3357,11 +3348,11 @@ edit_formals_lists (end_formals, f_list_count, def_dec_p)
if (func_name_len != strlen (expected)
|| strncmp (func_name_start, expected, func_name_len))
{
- fprintf (stderr, "%s: %d: warning: found `%s' but expected `%s'\n",
- shortpath (NULL, def_dec_p->file->hash_entry->symbol),
- identify_lineno (func_name_start),
- dupnstr (func_name_start, func_name_len),
- expected);
+ notice ("%s: %d: warning: found `%s' but expected `%s'\n",
+ shortpath (NULL, def_dec_p->file->hash_entry->symbol),
+ identify_lineno (func_name_start),
+ dupnstr (func_name_start, func_name_len),
+ expected);
return 1;
}
}
@@ -3439,8 +3430,8 @@ find_rightmost_formals_list (clean_text_p)
while (*end_formals != ')')
{
- if (ISSPACE (*end_formals))
- while (ISSPACE (*end_formals))
+ if (ISSPACE ((unsigned char)*end_formals))
+ while (ISSPACE ((unsigned char)*end_formals))
check_source (--end_formals > clean_read_ptr, 0);
else
check_source (--end_formals > clean_read_ptr, 0);
@@ -3469,8 +3460,8 @@ find_rightmost_formals_list (clean_text_p)
while (*end_formals != ')')
{
- if (ISSPACE (*end_formals))
- while (ISSPACE (*end_formals))
+ if (ISSPACE ((const unsigned char)*end_formals))
+ while (ISSPACE ((const unsigned char)*end_formals))
check_source (--end_formals > clean_read_ptr, 0);
else
check_source (--end_formals > clean_read_ptr, 0);
@@ -3488,7 +3479,7 @@ find_rightmost_formals_list (clean_text_p)
by an alphabetic character, while others *cannot* validly be followed
by such characters. */
- if ((ch == '{') || ISALPHA (ch))
+ if ((ch == '{') || ISALPHA ((unsigned char)ch))
break;
/* At this point, we have found a right paren, but we know that it is
@@ -3535,8 +3526,8 @@ add_local_decl (def_dec_p, clean_text_p)
if (setjmp (source_confusion_recovery))
{
restore_pointers ();
- fprintf (stderr, "%s: local declaration for function `%s' not inserted\n",
- pname, function_to_edit);
+ notice ("%s: local declaration for function `%s' not inserted\n",
+ pname, function_to_edit);
return;
}
@@ -3562,8 +3553,7 @@ add_local_decl (def_dec_p, clean_text_p)
if (*start_of_block != '{')
{
if (!quiet_flag)
- fprintf (stderr,
- "\n%s: %d: warning: can't add declaration of `%s' into macro call\n",
+ notice ("\n%s: %d: warning: can't add declaration of `%s' into macro call\n",
def_dec_p->file->hash_entry->symbol, def_dec_p->line,
def_dec_p->hash_entry->symbol);
return;
@@ -3584,7 +3574,7 @@ add_local_decl (def_dec_p, clean_text_p)
We can now just scan backwards and find the left end of the existing
indentation string, and then copy it to the output buffer. */
- for (sp = ep; ISSPACE (*sp) && *sp != '\n'; sp--)
+ for (sp = ep; ISSPACE ((const unsigned char)*sp) && *sp != '\n'; sp--)
continue;
/* Now write out the open { which began this block, and any following
@@ -3637,8 +3627,8 @@ add_global_decls (file_p, clean_text_p)
if (setjmp (source_confusion_recovery))
{
restore_pointers ();
- fprintf (stderr, "%s: global declarations for file `%s' not inserted\n",
- pname, shortpath (NULL, file_p->hash_entry->symbol));
+ notice ("%s: global declarations for file `%s' not inserted\n",
+ pname, shortpath (NULL, file_p->hash_entry->symbol));
return;
}
@@ -3665,7 +3655,7 @@ add_global_decls (file_p, clean_text_p)
header. We will put in the added declarations just prior to that. */
scan_p++;
- while (ISSPACE (*scan_p))
+ while (ISSPACE ((const unsigned char)*scan_p))
scan_p++;
scan_p--;
@@ -3728,8 +3718,8 @@ edit_fn_definition (def_dec_p, clean_text_p)
if (setjmp (source_confusion_recovery))
{
restore_pointers ();
- fprintf (stderr, "%s: definition of function `%s' not converted\n",
- pname, function_to_edit);
+ notice ("%s: definition of function `%s' not converted\n",
+ pname, function_to_edit);
return;
}
@@ -3747,10 +3737,10 @@ edit_fn_definition (def_dec_p, clean_text_p)
if (other_variable_style_function (def_dec_p->ansi_decl))
{
if (!quiet_flag)
- fprintf (stderr, "%s: %d: warning: definition of %s not converted\n",
- shortpath (NULL, def_dec_p->file->hash_entry->symbol),
- identify_lineno (end_formals),
- other_var_style);
+ notice ("%s: %d: warning: definition of %s not converted\n",
+ shortpath (NULL, def_dec_p->file->hash_entry->symbol),
+ identify_lineno (end_formals),
+ other_var_style);
output_up_to (end_formals);
return;
}
@@ -3758,8 +3748,8 @@ edit_fn_definition (def_dec_p, clean_text_p)
if (edit_formals_lists (end_formals, def_dec_p->f_list_count, def_dec_p))
{
restore_pointers ();
- fprintf (stderr, "%s: definition of function `%s' not converted\n",
- pname, function_to_edit);
+ notice ("%s: definition of function `%s' not converted\n",
+ pname, function_to_edit);
return;
}
@@ -3834,7 +3824,7 @@ edit_fn_definition (def_dec_p, clean_text_p)
{
have_newlines |= (*scan_orig == '\n');
/* Leave identical whitespace alone. */
- if (!ISSPACE (*scan_orig))
+ if (!ISSPACE ((const unsigned char)*scan_orig))
*((NONCONST char *)scan_orig) = ' '; /* identical - so whiteout */
}
else
@@ -3878,7 +3868,7 @@ do_cleaning (new_clean_text_base, new_clean_text_limit)
scan_p += 2;
while (scan_p[1] != '/' || scan_p[0] != '*')
{
- if (!ISSPACE (*scan_p))
+ if (!ISSPACE ((const unsigned char)*scan_p))
*scan_p = ' ';
if (++scan_p >= new_clean_text_limit)
abort ();
@@ -3893,7 +3883,7 @@ do_cleaning (new_clean_text_base, new_clean_text_limit)
*scan_p = ' ';
while (scan_p[1] != '\n' || scan_p[0] == '\\')
{
- if (!ISSPACE (*scan_p))
+ if (!ISSPACE ((const unsigned char)*scan_p))
*scan_p = ' ';
if (++scan_p >= new_clean_text_limit)
abort ();
@@ -3905,9 +3895,10 @@ do_cleaning (new_clean_text_base, new_clean_text_limit)
non_whitespace_since_newline = 1;
while (scan_p[1] != '\'' || scan_p[0] == '\\')
{
- if (scan_p[0] == '\\' && !ISSPACE (scan_p[1]))
+ if (scan_p[0] == '\\'
+ && !ISSPACE ((const unsigned char)scan_p[1]))
scan_p[1] = ' ';
- if (!ISSPACE (*scan_p))
+ if (!ISSPACE ((const unsigned char)*scan_p))
*scan_p = ' ';
if (++scan_p >= new_clean_text_limit)
abort ();
@@ -3919,14 +3910,15 @@ do_cleaning (new_clean_text_base, new_clean_text_limit)
non_whitespace_since_newline = 1;
while (scan_p[1] != '"' || scan_p[0] == '\\')
{
- if (scan_p[0] == '\\' && !ISSPACE (scan_p[1]))
+ if (scan_p[0] == '\\'
+ && !ISSPACE ((const unsigned char)scan_p[1]))
scan_p[1] = ' ';
- if (!ISSPACE (*scan_p))
+ if (!ISSPACE ((const unsigned char)*scan_p))
*scan_p = ' ';
if (++scan_p >= new_clean_text_limit)
abort ();
}
- if (!ISSPACE (*scan_p))
+ if (!ISSPACE ((const unsigned char)*scan_p))
*scan_p = ' ';
scan_p++;
break;
@@ -4019,12 +4011,12 @@ scan_for_missed_items (file_p)
last_r_paren = scan_p;
- for (ahead_p = scan_p + 1; ISSPACE (*ahead_p); )
+ for (ahead_p = scan_p + 1; ISSPACE ((const unsigned char)*ahead_p); )
check_source (++ahead_p < limit, limit);
scan_p = ahead_p - 1;
- if (ISALPHA (*ahead_p) || *ahead_p == '{')
+ if (ISALPHA ((const unsigned char)*ahead_p) || *ahead_p == '{')
{
const char *last_l_paren;
const int lineno = identify_lineno (ahead_p);
@@ -4038,7 +4030,8 @@ scan_for_missed_items (file_p)
do
{
last_l_paren = careful_find_l_paren (last_r_paren);
- for (last_r_paren = last_l_paren-1; ISSPACE (*last_r_paren); )
+ for (last_r_paren = last_l_paren-1;
+ ISSPACE ((const unsigned char)*last_r_paren); )
check_source (--last_r_paren >= backup_limit, backup_limit);
}
while (*last_r_paren == ')');
@@ -4074,11 +4067,11 @@ scan_for_missed_items (file_p)
goto not_missed;
#if 0
- fprintf (stderr, "%s: found definition of `%s' at %s(%d)\n",
- pname,
- func_name,
- shortpath (NULL, file_p->hash_entry->symbol),
- identify_lineno (id_start));
+ notice ("%s: found definition of `%s' at %s(%d)\n",
+ pname,
+ func_name,
+ shortpath (NULL, file_p->hash_entry->symbol),
+ identify_lineno (id_start));
#endif /* 0 */
/* We really should check for a match of the function name
here also, but why bother. */
@@ -4090,11 +4083,11 @@ scan_for_missed_items (file_p)
/* If we make it here, then we did not know about this
function definition. */
- fprintf (stderr, "%s: %d: warning: `%s' excluded by preprocessing\n",
- shortpath (NULL, file_p->hash_entry->symbol),
- identify_lineno (id_start), func_name);
- fprintf (stderr, "%s: function definition not converted\n",
- pname);
+ notice ("%s: %d: warning: `%s' excluded by preprocessing\n",
+ shortpath (NULL, file_p->hash_entry->symbol),
+ identify_lineno (id_start), func_name);
+ notice ("%s: function definition not converted\n",
+ pname);
}
not_missed: ;
}
@@ -4152,19 +4145,19 @@ edit_file (hp)
&& !in_system_include_dir (convert_filename)
#endif /* defined (UNPROTOIZE) */
)
- fprintf (stderr, "%s: `%s' not converted\n",
- pname, shortpath (NULL, convert_filename));
+ notice ("%s: `%s' not converted\n",
+ pname, shortpath (NULL, convert_filename));
return;
}
/* Let the user know what we are up to. */
if (nochange_flag)
- fprintf (stderr, "%s: would convert file `%s'\n",
- pname, shortpath (NULL, convert_filename));
+ notice ("%s: would convert file `%s'\n",
+ pname, shortpath (NULL, convert_filename));
else
- fprintf (stderr, "%s: converting file `%s'\n",
- pname, shortpath (NULL, convert_filename));
+ notice ("%s: converting file `%s'\n",
+ pname, shortpath (NULL, convert_filename));
fflush (stderr);
/* Find out the size (in bytes) of the original file. */
@@ -4173,9 +4166,9 @@ edit_file (hp)
if (my_stat ((char *)convert_filename, &stat_buf) == -1)
{
int errno_val = errno;
- fprintf (stderr, "%s: can't get status for file `%s': %s\n",
- pname, shortpath (NULL, convert_filename),
- my_strerror (errno_val));
+ notice ("%s: can't get status for file `%s': %s\n",
+ pname, shortpath (NULL, convert_filename),
+ xstrerror (errno_val));
return;
}
orig_size = stat_buf.st_size;
@@ -4209,9 +4202,9 @@ edit_file (hp)
if ((input_file = my_open (convert_filename, O_RDONLY, 0444)) == -1)
{
int errno_val = errno;
- fprintf (stderr, "%s: can't open file `%s' for reading: %s\n",
- pname, shortpath (NULL, convert_filename),
- my_strerror (errno_val));
+ notice ("%s: can't open file `%s' for reading: %s\n",
+ pname, shortpath (NULL, convert_filename),
+ xstrerror (errno_val));
return;
}
@@ -4219,13 +4212,14 @@ edit_file (hp)
in one swell fwoop. Then figure out where the end of the text is and
make sure that it ends with a newline followed by a null. */
- if (safe_read (input_file, new_orig_text_base, orig_size) != orig_size)
+ if (safe_read (input_file, new_orig_text_base, orig_size) !=
+ (int) orig_size)
{
int errno_val = errno;
close (input_file);
- fprintf (stderr, "\n%s: error reading input file `%s': %s\n",
- pname, shortpath (NULL, convert_filename),
- my_strerror (errno_val));
+ notice ("\n%s: error reading input file `%s': %s\n",
+ pname, shortpath (NULL, convert_filename),
+ xstrerror (errno_val));
return;
}
@@ -4257,9 +4251,9 @@ edit_file (hp)
if ((clean_file = creat (clean_filename, 0666)) == -1)
{
int errno_val = errno;
- fprintf (stderr, "%s: can't create/open clean file `%s': %s\n",
- pname, shortpath (NULL, clean_filename),
- my_strerror (errno_val));
+ notice ("%s: can't create/open clean file `%s': %s\n",
+ pname, shortpath (NULL, clean_filename),
+ xstrerror (errno_val));
return;
}
@@ -4358,18 +4352,18 @@ edit_file (hp)
if (errno_val == EEXIST)
{
if (!quiet_flag)
- fprintf (stderr, "%s: warning: file `%s' already saved in `%s'\n",
- pname,
- shortpath (NULL, convert_filename),
- shortpath (NULL, new_filename));
+ notice ("%s: warning: file `%s' already saved in `%s'\n",
+ pname,
+ shortpath (NULL, convert_filename),
+ shortpath (NULL, new_filename));
}
else
{
- fprintf (stderr, "%s: can't link file `%s' to `%s': %s\n",
- pname,
- shortpath (NULL, convert_filename),
- shortpath (NULL, new_filename),
- my_strerror (errno_val));
+ notice ("%s: can't link file `%s' to `%s': %s\n",
+ pname,
+ shortpath (NULL, convert_filename),
+ shortpath (NULL, new_filename),
+ xstrerror (errno_val));
return;
}
}
@@ -4378,9 +4372,9 @@ edit_file (hp)
if (my_unlink (convert_filename) == -1)
{
int errno_val = errno;
- fprintf (stderr, "%s: can't delete file `%s': %s\n",
- pname, shortpath (NULL, convert_filename),
- my_strerror (errno_val));
+ notice ("%s: can't delete file `%s': %s\n",
+ pname, shortpath (NULL, convert_filename),
+ xstrerror (errno_val));
return;
}
@@ -4392,9 +4386,9 @@ edit_file (hp)
if ((output_file = creat (convert_filename, 0666)) == -1)
{
int errno_val = errno;
- fprintf (stderr, "%s: can't create/open output file `%s': %s\n",
- pname, shortpath (NULL, convert_filename),
- my_strerror (errno_val));
+ notice ("%s: can't create/open output file `%s': %s\n",
+ pname, shortpath (NULL, convert_filename),
+ xstrerror (errno_val));
return;
}
@@ -4421,9 +4415,9 @@ edit_file (hp)
if (my_chmod ((char *)convert_filename, stat_buf.st_mode) == -1)
{
int errno_val = errno;
- fprintf (stderr, "%s: can't change mode of file `%s': %s\n",
- pname, shortpath (NULL, convert_filename),
- my_strerror (errno_val));
+ notice ("%s: can't change mode of file `%s': %s\n",
+ pname, shortpath (NULL, convert_filename),
+ xstrerror (errno_val));
}
/* Note: We would try to change the owner and group of the output file
@@ -4563,11 +4557,17 @@ main (argc, argv)
pname = strrchr (argv[0], '/');
pname = pname ? pname+1 : argv[0];
+#ifdef HAVE_LC_MESSAGES
+ setlocale (LC_MESSAGES, "");
+#endif
+ (void) bindtextdomain (PACKAGE, localedir);
+ (void) textdomain (PACKAGE);
+
cwd_buffer = getpwd ();
if (!cwd_buffer)
{
- fprintf (stderr, "%s: cannot get working directory: %s\n",
- pname, my_strerror(errno));
+ notice ("%s: cannot get working directory: %s\n",
+ pname, xstrerror(errno));
exit (FATAL_EXIT_CODE);
}
@@ -4664,8 +4664,8 @@ main (argc, argv)
base_source_filenames[n_base_source_files++] = path;
else
{
- fprintf (stderr, "%s: input file names must have .c suffixes: %s\n",
- pname, shortpath (NULL, path));
+ notice ("%s: input file names must have .c suffixes: %s\n",
+ pname, shortpath (NULL, path));
errors++;
}
}
@@ -4677,7 +4677,8 @@ main (argc, argv)
{
const char *cp;
- for (cp = varargs_style_indicator; ISALNUM (*cp) || *cp == '_'; cp++)
+ for (cp = varargs_style_indicator;
+ ISALNUM ((const unsigned char)*cp) || *cp == '_'; cp++)
continue;
if (*cp != 0)
varargs_style_indicator = savestring (varargs_style_indicator,
diff --git a/gcc/real.c b/gcc/real.c
index ed854e02625..e6a15fed515 100644
--- a/gcc/real.c
+++ b/gcc/real.c
@@ -1,6 +1,6 @@
/* real.c - implementation of REAL_ARITHMETIC, REAL_VALUE_ATOF,
and support for XFmode IEEE extended real floating point arithmetic.
- Copyright (C) 1993, 94, 95, 96, 97, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1993, 94-98, 1999 Free Software Foundation, Inc.
Contributed by Stephen L. Moshier (moshier@world.std.com).
This file is part of GNU CC.
@@ -79,14 +79,17 @@ netlib.att.com: netlib/cephes. */
`C4X' refers specifically to the floating point format used on
Texas Instruments TMS320C3x and TMS320C4x digital signal
processors. This supports QFmode (32-bit float, double) and HFmode
- (40-bit long double) where BITS_PER_BYTE is 32.
+ (40-bit long double) where BITS_PER_BYTE is 32. Unlike IEEE
+ floats, C4x floats are not rounded to be even. The C4x conversions
+ were contributed by m.hayes@elec.canterbury.ac.nz (Michael Hayes) and
+ Haj.Ten.Brugge@net.HCC.nl (Herman ten Brugge).
If LONG_DOUBLE_TYPE_SIZE = 64 (the default, unless tm.h defines it)
then `long double' and `double' are both implemented, but they
both mean DFmode. In this case, the software floating-point
support available here is activated by writing
#define REAL_ARITHMETIC
- in tm.h.
+ in tm.h.
The case LONG_DOUBLE_TYPE_SIZE = 128 activates TFmode support
and may deactivate XFmode since `long double' is used to refer
@@ -245,7 +248,12 @@ unknown arithmetic type
#define MAXDECEXP 4932
#define MINDECEXP -4956
#define GET_REAL(r,e) bcopy ((char *) r, (char *) e, 2*NE)
-#define PUT_REAL(e,r) bcopy ((char *) e, (char *) r, 2*NE)
+#define PUT_REAL(e,r) \
+do { \
+ if (2*NE < sizeof(*r)) \
+ bzero((char *)r, sizeof(*r)); \
+ bcopy ((char *) e, (char *) r, 2*NE); \
+} while (0)
#else /* no XFmode */
#if LONG_DOUBLE_TYPE_SIZE == 128
#define NE 10
@@ -406,12 +414,12 @@ static void e64toasc PROTO((unsigned EMUSHORT *, char *, int));
static void e113toasc PROTO((unsigned EMUSHORT *, char *, int));
#endif /* 0 */
static void etoasc PROTO((unsigned EMUSHORT *, char *, int));
-static void asctoe24 PROTO((char *, unsigned EMUSHORT *));
-static void asctoe53 PROTO((char *, unsigned EMUSHORT *));
-static void asctoe64 PROTO((char *, unsigned EMUSHORT *));
-static void asctoe113 PROTO((char *, unsigned EMUSHORT *));
-static void asctoe PROTO((char *, unsigned EMUSHORT *));
-static void asctoeg PROTO((char *, unsigned EMUSHORT *, int));
+static void asctoe24 PROTO((const char *, unsigned EMUSHORT *));
+static void asctoe53 PROTO((const char *, unsigned EMUSHORT *));
+static void asctoe64 PROTO((const char *, unsigned EMUSHORT *));
+static void asctoe113 PROTO((const char *, unsigned EMUSHORT *));
+static void asctoe PROTO((const char *, unsigned EMUSHORT *));
+static void asctoeg PROTO((const char *, unsigned EMUSHORT *, int));
static void efloor PROTO((unsigned EMUSHORT *, unsigned EMUSHORT *));
#if 0
static void efrexp PROTO((unsigned EMUSHORT *, int *,
@@ -423,7 +431,7 @@ static void eremain PROTO((unsigned EMUSHORT *, unsigned EMUSHORT *,
unsigned EMUSHORT *));
#endif
static void eiremain PROTO((unsigned EMUSHORT *, unsigned EMUSHORT *));
-static void mtherr PROTO((char *, int));
+static void mtherr PROTO((const char *, int));
#ifdef DEC
static void dectoe PROTO((unsigned EMUSHORT *, unsigned EMUSHORT *));
static void etodec PROTO((unsigned EMUSHORT *, unsigned EMUSHORT *));
@@ -458,7 +466,7 @@ static void esqrt PROTO((unsigned EMUSHORT *, unsigned EMUSHORT *));
swapping ends if required, into output array of longs. The
result is normally passed to fprintf by the ASM_OUTPUT_ macros. */
-static void
+static void
endian (e, x, mode)
unsigned EMUSHORT e[];
long x[];
@@ -555,7 +563,7 @@ endian (e, x, mode)
/* This is the implementation of the REAL_ARITHMETIC macro. */
-void
+void
earith (value, icode, r1, r2)
REAL_VALUE_TYPE *value;
int icode;
@@ -634,7 +642,7 @@ PUT_REAL (v, value);
/* Truncate REAL_VALUE_TYPE toward zero to signed HOST_WIDE_INT.
implements REAL_VALUE_RNDZINT (x) (etrunci (x)). */
-REAL_VALUE_TYPE
+REAL_VALUE_TYPE
etrunci (x)
REAL_VALUE_TYPE x;
{
@@ -657,7 +665,7 @@ etrunci (x)
/* Truncate REAL_VALUE_TYPE toward zero to unsigned HOST_WIDE_INT;
implements REAL_VALUE_UNSIGNED_RNDZINT (x) (etruncui (x)). */
-REAL_VALUE_TYPE
+REAL_VALUE_TYPE
etruncui (x)
REAL_VALUE_TYPE x;
{
@@ -677,13 +685,13 @@ etruncui (x)
}
-/* This is the REAL_VALUE_ATOF function. It converts a decimal string to
- binary, rounding off as indicated by the machine_mode argument. Then it
- promotes the rounded value to REAL_VALUE_TYPE. */
+/* This is the REAL_VALUE_ATOF function. It converts a decimal or hexadecimal
+ string to binary, rounding off as indicated by the machine_mode argument.
+ Then it promotes the rounded value to REAL_VALUE_TYPE. */
-REAL_VALUE_TYPE
+REAL_VALUE_TYPE
ereal_atof (s, t)
- char *s;
+ const char *s;
enum machine_mode t;
{
unsigned EMUSHORT tem[NE], e[NE];
@@ -731,7 +739,7 @@ ereal_atof (s, t)
/* Expansion of REAL_NEGATE. */
-REAL_VALUE_TYPE
+REAL_VALUE_TYPE
ereal_negate (x)
REAL_VALUE_TYPE x;
{
@@ -793,7 +801,7 @@ efixui (x)
/* REAL_VALUE_FROM_INT macro. */
-void
+void
ereal_from_int (d, i, j, mode)
REAL_VALUE_TYPE *d;
HOST_WIDE_INT i, j;
@@ -860,7 +868,7 @@ ereal_from_int (d, i, j, mode)
/* REAL_VALUE_FROM_UNSIGNED_INT macro. */
-void
+void
ereal_from_uint (d, i, j, mode)
REAL_VALUE_TYPE *d;
unsigned HOST_WIDE_INT i, j;
@@ -914,7 +922,7 @@ ereal_from_uint (d, i, j, mode)
/* REAL_VALUE_TO_INT macro. */
-void
+void
ereal_to_int (low, high, rr)
HOST_WIDE_INT *low, *high;
REAL_VALUE_TYPE rr;
@@ -1164,15 +1172,15 @@ debug_real (r)
REAL_VALUE_TO_DECIMAL (r, "%.20g", dstr);
fprintf (stderr, "%s", dstr);
-}
+}
/* The following routines convert REAL_VALUE_TYPE to the various floating
point formats that are meaningful to supported computers.
- The results are returned in 32-bit pieces, each piece stored in a `long'.
+ The results are returned in 32-bit pieces, each piece stored in a `long'.
This is so they can be printed by statements like
-
+
fprintf (file, "%lx, %lx", L[0], L[1]);
that will work on both narrow- and wide-word host computers. */
@@ -1181,7 +1189,7 @@ debug_real (r)
contains four 32-bit pieces of the result, in the order they would appear
in memory. */
-void
+void
etartdouble (r, l)
REAL_VALUE_TYPE r;
long l[];
@@ -1197,7 +1205,7 @@ etartdouble (r, l)
contains three 32-bit pieces of the result, in the order they would
appear in memory. */
-void
+void
etarldouble (r, l)
REAL_VALUE_TYPE r;
long l[];
@@ -1212,7 +1220,7 @@ etarldouble (r, l)
/* Convert R to a double precision value. The output array L contains two
32-bit pieces of the result, in the order they would appear in memory. */
-void
+void
etardouble (r, l)
REAL_VALUE_TYPE r;
long l[];
@@ -1310,11 +1318,11 @@ ereal_isneg (x)
most significant word first,
most significant bit is set)
ei[NI-1] low guard word (0x8000 bit is rounding place)
-
-
-
+
+
+
Routines for external format e-type numbers
-
+
asctoe (string, e) ASCII string to extended double e type
asctoe64 (string, &d) ASCII string to long double
asctoe53 (string, &d) ASCII string to double
@@ -1361,10 +1369,10 @@ ereal_isneg (x)
eisinf (e) 1 if e has maximum exponent (non-IEEE)
or is infinite (IEEE)
eisnan (e) 1 if e is a NaN
-
+
Routines for internal format exploded e-type numbers
-
+
eaddm (ai, bi) add significands, bi = bi + ai
ecleaz (ei) ei = 0
ecleazs (ei) set ei = 0 but leave its sign alone
@@ -1396,13 +1404,13 @@ ereal_isneg (x)
after each arithmetic operation.
Exception flags are NOT fully supported.
-
+
Signaling NaN's are NOT supported; they are treated the same
as quiet NaN's.
-
+
Define INFINITY for support of infinity; otherwise a
saturation arithmetic is implemented.
-
+
Define NANS for support of Not-a-Number items; otherwise the
arithmetic will never produce a NaN output, and might be confused
by a NaN input.
@@ -1410,7 +1418,7 @@ ereal_isneg (x)
either a or b is a NaN. This means asking `if (ecmp (a,b) < 0)'
may not be legitimate. Use `if (ecmp (a,b) == -1)' for `less than'
if in doubt.
-
+
Denormals are always supported here where appropriate (e.g., not
for conversion to DEC numbers). */
@@ -1423,7 +1431,7 @@ ereal_isneg (x)
mode, most floating point constants are given as arrays
of octal integers to eliminate decimal to binary conversion
errors that might be introduced by the compiler.
-
+
For computers, such as IBM PC, that follow the IEEE
Standard for Binary Floating Point Arithmetic (ANSI/IEEE
Std 754-1985), the symbol IEEE should be defined.
@@ -1431,20 +1439,20 @@ ereal_isneg (x)
are provided as arrays of hexadecimal 16 bit integers.
The endian-ness of generated values is controlled by
REAL_WORDS_BIG_ENDIAN.
-
+
To accommodate other types of computer arithmetic, all
constants are also provided in a normal decimal radix
which one can hope are correctly converted to a suitable
format by the available C language compiler. To invoke
this mode, the symbol UNK is defined.
-
+
An important difference among these modes is a predefined
set of machine arithmetic constants for each. The numbers
MACHEP (the machine roundoff error), MAXNUM (largest number
represented), and several other parameters are preset by
the configuration symbol. Check the file const.c to
ensure that these values are correct for your computer.
-
+
For ANSI C compatibility, define ANSIC equal to 1. Currently
this affects only the atan2 function and others that use it. */
@@ -1537,7 +1545,7 @@ extern int rndprc;
/* Clear out entire e-type number X. */
-static void
+static void
eclear (x)
register unsigned EMUSHORT *x;
{
@@ -1549,7 +1557,7 @@ eclear (x)
/* Move e-type number from A to B. */
-static void
+static void
emov (a, b)
register unsigned EMUSHORT *a, *b;
{
@@ -1563,18 +1571,18 @@ emov (a, b)
#if 0
/* Absolute value of e-type X. */
-static void
+static void
eabs (x)
unsigned EMUSHORT x[];
{
/* sign is top bit of last word of external format */
- x[NE - 1] &= 0x7fff;
+ x[NE - 1] &= 0x7fff;
}
#endif /* 0 */
/* Negate the e-type number X. */
-static void
+static void
eneg (x)
unsigned EMUSHORT x[];
{
@@ -1584,7 +1592,7 @@ eneg (x)
/* Return 1 if sign bit of e-type number X is nonzero, else zero. */
-static int
+static int
eisneg (x)
unsigned EMUSHORT x[];
{
@@ -1597,7 +1605,7 @@ eisneg (x)
/* Return 1 if e-type number X is infinity, else return zero. */
-static int
+static int
eisinf (x)
unsigned EMUSHORT x[];
{
@@ -1615,7 +1623,7 @@ eisinf (x)
/* Check if e-type number is not a number. The bit pattern is one that we
defined, so we know for sure how to detect it. */
-static int
+static int
eisnan (x)
unsigned EMUSHORT x[];
{
@@ -1639,7 +1647,7 @@ eisnan (x)
/* Fill e-type number X with infinity pattern (IEEE)
or largest possible number (non-IEEE). */
-static void
+static void
einfin (x)
register unsigned EMUSHORT *x;
{
@@ -1682,7 +1690,7 @@ einfin (x)
This generates Intel's quiet NaN pattern for extended real.
The exponent is 7fff, the leading mantissa word is c000. */
-static void
+static void
enan (x, sign)
register unsigned EMUSHORT *x;
int sign;
@@ -1697,7 +1705,7 @@ enan (x, sign)
/* Move in an e-type number A, converting it to exploded e-type B. */
-static void
+static void
emovi (a, b)
unsigned EMUSHORT *a, *b;
{
@@ -1744,7 +1752,7 @@ emovi (a, b)
/* Move out exploded e-type number A, converting it to e type B. */
-static void
+static void
emovo (a, b)
unsigned EMUSHORT *a, *b;
{
@@ -1783,7 +1791,7 @@ emovo (a, b)
/* Clear out exploded e-type number XI. */
-static void
+static void
ecleaz (xi)
register unsigned EMUSHORT *xi;
{
@@ -1795,7 +1803,7 @@ ecleaz (xi)
/* Clear out exploded e-type XI, but don't touch the sign. */
-static void
+static void
ecleazs (xi)
register unsigned EMUSHORT *xi;
{
@@ -1808,7 +1816,7 @@ ecleazs (xi)
/* Move exploded e-type number from A to B. */
-static void
+static void
emovz (a, b)
register unsigned EMUSHORT *a, *b;
{
@@ -1836,7 +1844,7 @@ einan (x)
/* Return nonzero if exploded e-type X is a NaN. */
-static int
+static int
eiisnan (x)
unsigned EMUSHORT x[];
{
@@ -1855,7 +1863,7 @@ eiisnan (x)
/* Return nonzero if sign of exploded e-type X is nonzero. */
-static int
+static int
eiisneg (x)
unsigned EMUSHORT x[];
{
@@ -1879,7 +1887,7 @@ eiinfin (x)
/* Return nonzero if exploded e-type X is infinite. */
-static int
+static int
eiisinf (x)
unsigned EMUSHORT x[];
{
@@ -1925,7 +1933,7 @@ ecmpm (a, b)
/* Shift significand of exploded e-type X down by 1 bit. */
-static void
+static void
eshdn1 (x)
register unsigned EMUSHORT *x;
{
@@ -1949,7 +1957,7 @@ eshdn1 (x)
/* Shift significand of exploded e-type X up by 1 bit. */
-static void
+static void
eshup1 (x)
register unsigned EMUSHORT *x;
{
@@ -1974,7 +1982,7 @@ eshup1 (x)
/* Shift significand of exploded e-type X down by 8 bits. */
-static void
+static void
eshdn8 (x)
register unsigned EMUSHORT *x;
{
@@ -1995,7 +2003,7 @@ eshdn8 (x)
/* Shift significand of exploded e-type X up by 8 bits. */
-static void
+static void
eshup8 (x)
register unsigned EMUSHORT *x;
{
@@ -2017,7 +2025,7 @@ eshup8 (x)
/* Shift significand of exploded e-type X up by 16 bits. */
-static void
+static void
eshup6 (x)
register unsigned EMUSHORT *x;
{
@@ -2035,7 +2043,7 @@ eshup6 (x)
/* Shift significand of exploded e-type X down by 16 bits. */
-static void
+static void
eshdn6 (x)
register unsigned EMUSHORT *x;
{
@@ -2053,7 +2061,7 @@ eshdn6 (x)
/* Add significands of exploded e-type X and Y. X + Y replaces Y. */
-static void
+static void
eaddm (x, y)
unsigned EMUSHORT *x, *y;
{
@@ -2079,7 +2087,7 @@ eaddm (x, y)
/* Subtract significands of exploded e-type X and Y. Y - X replaces Y. */
-static void
+static void
esubm (x, y)
unsigned EMUSHORT *x, *y;
{
@@ -2113,7 +2121,7 @@ static unsigned EMUSHORT equot[NI];
/* Divide significands */
-int
+int
edivm (den, num)
unsigned EMUSHORT den[], num[];
{
@@ -2211,7 +2219,7 @@ edivm (den, num)
/* Multiply significands */
-int
+int
emulm (a, b)
unsigned EMUSHORT a[], b[];
{
@@ -2333,7 +2341,7 @@ edivm (den, num)
tnum = (((unsigned EMULONG) num[M]) << 16) + num[M+1];
/* Do not execute the divide instruction if it will overflow. */
- if ((tdenm * 0xffffL) < tnum)
+ if ((tdenm * (unsigned long)0xffff) < tnum)
tquot = 0xffff;
else
tquot = tnum / tdenm;
@@ -2417,15 +2425,15 @@ emulm (a, b)
The internal format number to be rounded is S.
Input LOST is 0 if the value is exact. This is the so-called sticky bit.
-
+
Input SUBFLG indicates whether the number was obtained
by a subtraction operation. In that case if LOST is nonzero
then the number is slightly smaller than indicated.
-
+
Input EXP is the biased exponent, which may be negative.
the exponent field of S is ignored but is replaced by
EXP as adjusted by normalization and rounding.
-
+
Input RCNTRL is the rounding control. If it is nonzero, the
returned value will be rounded to RNDPRC bits.
@@ -2434,7 +2442,7 @@ emulm (a, b)
adjusted to be the actual value it would have after conversion to
the final floating point type. This adjustment has been
implemented for all type conversions (etoe53, etc.) and decimal
- conversions, but not for the arithmetic functions (eadd, etc.).
+ conversions, but not for the arithmetic functions (eadd, etc.).
Data types having standard 15-bit exponents are not affected by
this, but SFmode and DFmode are affected. For example, ediv with
rndprc = 24 will not round correctly to 24-bit precision if the
@@ -2448,7 +2456,7 @@ static unsigned EMUSHORT rebit = 0;
static int re = 0;
static unsigned EMUSHORT rbit[NI];
-static void
+static void
emdnorm (s, lost, subflg, exp, rcntrl)
unsigned EMUSHORT s[];
int lost;
@@ -2594,6 +2602,7 @@ emdnorm (s, lost, subflg, exp, rcntrl)
s[rw] &= ~rmsk;
if ((r & rmbit) != 0)
{
+#ifndef C4X
if (r == rmbit)
{
if (lost == 0)
@@ -2607,6 +2616,7 @@ emdnorm (s, lost, subflg, exp, rcntrl)
goto mddone;
}
}
+#endif
eaddm (rbit, s);
}
mddone:
@@ -2662,7 +2672,7 @@ emdnorm (s, lost, subflg, exp, rcntrl)
static int subflg = 0;
-static void
+static void
esub (a, b, c)
unsigned EMUSHORT *a, *b, *c;
{
@@ -2694,7 +2704,7 @@ esub (a, b, c)
/* Add. C = A + B, all e type. */
-static void
+static void
eadd (a, b, c)
unsigned EMUSHORT *a, *b, *c;
{
@@ -2727,7 +2737,7 @@ eadd (a, b, c)
/* Arithmetic common to both addition and subtraction. */
-static void
+static void
eadd1 (a, b, c)
unsigned EMUSHORT *a, *b, *c;
{
@@ -2838,7 +2848,7 @@ eadd1 (a, b, c)
/* Divide: C = B/A, all e type. */
-static void
+static void
ediv (a, b, c)
unsigned EMUSHORT *a, *b, *c;
{
@@ -2942,7 +2952,7 @@ ediv (a, b, c)
/* Multiply e-types A and B, return e-type product C. */
-static void
+static void
emul (a, b, c)
unsigned EMUSHORT *a, *b, *c;
{
@@ -3132,7 +3142,7 @@ e53toe (pe, y)
#endif
eshift (yy, -5);
if (denorm)
- {
+ {
/* If zero exponent, then normalize the significand. */
if ((k = enormlz (yy)) > NBITS)
ecleazs (yy);
@@ -3147,7 +3157,7 @@ e53toe (pe, y)
/* Convert double extended precision float PE to e type Y. */
-static void
+static void
e64toe (pe, y)
unsigned EMUSHORT *pe, *y;
{
@@ -3269,7 +3279,7 @@ bigend_nan:
/* Convert 128-bit long double precision float PE to e type Y. */
-static void
+static void
e113toe (pe, y)
unsigned EMUSHORT *pe, *y;
{
@@ -3354,7 +3364,7 @@ e113toe (pe, y)
/* Convert single precision float PE to e type Y. */
-static void
+static void
e24toe (pe, y)
unsigned EMUSHORT *pe, *y;
{
@@ -3457,7 +3467,7 @@ e24toe (pe, y)
/* Convert e-type X to IEEE 128-bit long double format E. */
-static void
+static void
etoe113 (x, e)
unsigned EMUSHORT *x, *e;
{
@@ -3490,7 +3500,7 @@ etoe113 (x, e)
/* Convert exploded e-type X, that has already been rounded to
113-bit precision, to IEEE 128-bit long double format Y. */
-static void
+static void
toe113 (a, b)
unsigned EMUSHORT *a, *b;
{
@@ -3548,7 +3558,7 @@ toe113 (a, b)
/* Convert e-type X to IEEE double extended format E. */
-static void
+static void
etoe64 (x, e)
unsigned EMUSHORT *x, *e;
{
@@ -3582,7 +3592,7 @@ etoe64 (x, e)
/* Convert exploded e-type X, that has already been rounded to
64-bit precision, to IEEE double extended format Y. */
-static void
+static void
toe64 (a, b)
unsigned EMUSHORT *a, *b;
{
@@ -3698,7 +3708,7 @@ toe64 (a, b)
#ifdef DEC
/* Convert e-type X to DEC-format double E. */
-static void
+static void
etoe53 (x, e)
unsigned EMUSHORT *x, *e;
{
@@ -3708,7 +3718,7 @@ etoe53 (x, e)
/* Convert exploded e-type X, that has already been rounded to
56-bit double precision, to DEC double Y. */
-static void
+static void
toe53 (x, y)
unsigned EMUSHORT *x, *y;
{
@@ -3719,7 +3729,7 @@ toe53 (x, y)
#ifdef IBM
/* Convert e-type X to IBM 370-format double E. */
-static void
+static void
etoe53 (x, e)
unsigned EMUSHORT *x, *e;
{
@@ -3729,7 +3739,7 @@ etoe53 (x, e)
/* Convert exploded e-type X, that has already been rounded to
56-bit precision, to IBM 370 double Y. */
-static void
+static void
toe53 (x, y)
unsigned EMUSHORT *x, *y;
{
@@ -3740,7 +3750,7 @@ toe53 (x, y)
#ifdef C4X
/* Convert e-type X to C4X-format long double E. */
-static void
+static void
etoe53 (x, e)
unsigned EMUSHORT *x, *e;
{
@@ -3750,7 +3760,7 @@ etoe53 (x, e)
/* Convert exploded e-type X, that has already been rounded to
56-bit precision, to IBM 370 double Y. */
-static void
+static void
toe53 (x, y)
unsigned EMUSHORT *x, *y;
{
@@ -3761,7 +3771,7 @@ toe53 (x, y)
/* Convert e-type X to IEEE double E. */
-static void
+static void
etoe53 (x, e)
unsigned EMUSHORT *x, *e;
{
@@ -3795,7 +3805,7 @@ etoe53 (x, e)
/* Convert exploded e-type X, that has already been rounded to
53-bit precision, to IEEE double Y. */
-static void
+static void
toe53 (x, y)
unsigned EMUSHORT *x, *y;
{
@@ -3892,7 +3902,7 @@ toe53 (x, y)
#ifdef IBM
/* Convert e-type X to IBM 370 float E. */
-static void
+static void
etoe24 (x, e)
unsigned EMUSHORT *x, *e;
{
@@ -3902,7 +3912,7 @@ etoe24 (x, e)
/* Convert exploded e-type X, that has already been rounded to
float precision, to IBM 370 float Y. */
-static void
+static void
toe24 (x, y)
unsigned EMUSHORT *x, *y;
{
@@ -3914,7 +3924,7 @@ toe24 (x, y)
#ifdef C4X
/* Convert e-type X to C4X float E. */
-static void
+static void
etoe24 (x, e)
unsigned EMUSHORT *x, *e;
{
@@ -3924,7 +3934,7 @@ etoe24 (x, e)
/* Convert exploded e-type X, that has already been rounded to
float precision, to IBM 370 float Y. */
-static void
+static void
toe24 (x, y)
unsigned EMUSHORT *x, *y;
{
@@ -3935,7 +3945,7 @@ toe24 (x, y)
/* Convert e-type X to IEEE float E. DEC float is the same as IEEE float. */
-static void
+static void
etoe24 (x, e)
unsigned EMUSHORT *x, *e;
{
@@ -3969,7 +3979,7 @@ etoe24 (x, e)
/* Convert exploded e-type X, that has already been rounded to
float precision, to IEEE float Y. */
-static void
+static void
toe24 (x, y)
unsigned EMUSHORT *x, *y;
{
@@ -4061,13 +4071,13 @@ toe24 (x, y)
#endif /* not C4X */
#endif /* not IBM */
-/* Compare two e type numbers.
+/* Compare two e type numbers.
Return +1 if a > b
0 if a == b
-1 if a < b
-2 if either a or b is a NaN. */
-static int
+static int
ecmp (a, b)
unsigned EMUSHORT *a, *b;
{
@@ -4130,7 +4140,7 @@ ecmp (a, b)
#if 0
/* Find e-type nearest integer to X, as floor (X + 0.5). */
-static void
+static void
eround (x, y)
unsigned EMUSHORT *x, *y;
{
@@ -4141,7 +4151,7 @@ eround (x, y)
/* Convert HOST_WIDE_INT LP to e type Y. */
-static void
+static void
ltoe (lp, y)
HOST_WIDE_INT *lp;
unsigned EMUSHORT *y;
@@ -4183,7 +4193,7 @@ ltoe (lp, y)
/* Convert unsigned HOST_WIDE_INT LP to e type Y. */
-static void
+static void
ultoe (lp, y)
unsigned HOST_WIDE_INT *lp;
unsigned EMUSHORT *y;
@@ -4223,7 +4233,7 @@ ultoe (lp, y)
The output e-type fraction FRAC is the positive fractional
part of abs (X). */
-static void
+static void
eifrac (x, i, frac)
unsigned EMUSHORT *x;
HOST_WIDE_INT *i;
@@ -4306,7 +4316,7 @@ eifrac (x, i, frac)
FRAC of e-type X. A negative input yields integer output = 0 but
correct fraction. */
-static void
+static void
euifrac (x, i, frac)
unsigned EMUSHORT *x;
unsigned HOST_WIDE_INT *i;
@@ -4375,7 +4385,7 @@ euifrac (x, i, frac)
/* Shift the significand of exploded e-type X up or down by SC bits. */
-static int
+static int
eshift (x, sc)
unsigned EMUSHORT *x;
int sc;
@@ -4441,7 +4451,7 @@ eshift (x, sc)
/* Shift normalize the significand area of exploded e-type X.
Return the shift count (up = positive). */
-static int
+static int
enormlz (x)
unsigned EMUSHORT x[];
{
@@ -4613,7 +4623,7 @@ static unsigned EMUSHORT emtens[NTEN + 1][NE] =
/* Convert float value X to ASCII string STRING with NDIG digits after
the decimal point. */
-static void
+static void
e24toasc (x, string, ndigs)
unsigned EMUSHORT x[];
char *string;
@@ -4628,7 +4638,7 @@ e24toasc (x, string, ndigs)
/* Convert double value X to ASCII string STRING with NDIG digits after
the decimal point. */
-static void
+static void
e53toasc (x, string, ndigs)
unsigned EMUSHORT x[];
char *string;
@@ -4643,7 +4653,7 @@ e53toasc (x, string, ndigs)
/* Convert double extended value X to ASCII string STRING with NDIG digits
after the decimal point. */
-static void
+static void
e64toasc (x, string, ndigs)
unsigned EMUSHORT x[];
char *string;
@@ -4658,7 +4668,7 @@ e64toasc (x, string, ndigs)
/* Convert 128-bit long double value X to ASCII string STRING with NDIG digits
after the decimal point. */
-static void
+static void
e113toasc (x, string, ndigs)
unsigned EMUSHORT x[];
char *string;
@@ -4676,7 +4686,7 @@ e113toasc (x, string, ndigs)
static char wstring[80]; /* working storage for ASCII output */
-static void
+static void
etoasc (x, string, ndigs)
unsigned EMUSHORT x[];
char *string;
@@ -4932,8 +4942,10 @@ etoasc (x, string, ndigs)
emovo (y, t);
if (ecmp (t, ezero) != 0)
goto roun; /* round to nearest */
+#ifndef C4X
if ((*(s - 1) & 1) == 0)
goto doexp; /* round to even */
+#endif
}
/* Round up and propagate carry-outs */
roun:
@@ -4992,9 +5004,9 @@ etoasc (x, string, ndigs)
/* Convert ASCII string S to single precision float value Y. */
-static void
+static void
asctoe24 (s, y)
- char *s;
+ const char *s;
unsigned EMUSHORT *y;
{
asctoeg (s, y, 24);
@@ -5003,9 +5015,9 @@ asctoe24 (s, y)
/* Convert ASCII string S to double precision value Y. */
-static void
+static void
asctoe53 (s, y)
- char *s;
+ const char *s;
unsigned EMUSHORT *y;
{
#if defined(DEC) || defined(IBM)
@@ -5022,9 +5034,9 @@ asctoe53 (s, y)
/* Convert ASCII string S to double extended value Y. */
-static void
+static void
asctoe64 (s, y)
- char *s;
+ const char *s;
unsigned EMUSHORT *y;
{
asctoeg (s, y, 64);
@@ -5032,9 +5044,9 @@ asctoe64 (s, y)
/* Convert ASCII string S to 128-bit long double Y. */
-static void
+static void
asctoe113 (s, y)
- char *s;
+ const char *s;
unsigned EMUSHORT *y;
{
asctoeg (s, y, 113);
@@ -5042,20 +5054,20 @@ asctoe113 (s, y)
/* Convert ASCII string S to e type Y. */
-static void
+static void
asctoe (s, y)
- char *s;
+ const char *s;
unsigned EMUSHORT *y;
{
asctoeg (s, y, NBITS);
}
/* Convert ASCII string SS to e type Y, with a specified rounding precision
- of OPREC bits. */
+ of OPREC bits. BASE is 16 for C9X hexadecimal floating constants. */
-static void
+static void
asctoeg (ss, y, oprec)
- char *ss;
+ const char *ss;
unsigned EMUSHORT *y;
int oprec;
{
@@ -5065,17 +5077,25 @@ asctoeg (ss, y, oprec)
EMULONG lexp;
unsigned EMUSHORT nsign, *p;
char *sp, *s, *lstr;
+ int base = 10;
/* Copy the input string. */
lstr = (char *) alloca (strlen (ss) + 1);
- s = ss;
- while (*s == ' ') /* skip leading spaces */
- ++s;
+
+ while (*ss == ' ') /* skip leading spaces */
+ ++ss;
+
sp = lstr;
- while ((*sp++ = *s++) != '\0')
+ while ((*sp++ = *ss++) != '\0')
;
s = lstr;
+ if (s[0] == '0' && (s[1] == 'x' || s[1] == 'X'))
+ {
+ base = 16;
+ s += 2;
+ }
+
rndsav = rndprc;
rndprc = NBITS; /* Set to full precision */
lost = 0;
@@ -5089,8 +5109,13 @@ asctoeg (ss, y, oprec)
trail = 0;
nxtcom:
- k = *s - '0';
- if ((k >= 0) && (k <= 9))
+ if (*s >= '0' && *s <= '9')
+ k = *s - '0';
+ else if (*s >= 'a')
+ k = 10 + *s - 'a';
+ else
+ k = 10 + *s - 'A';
+ if ((k >= 0) && (k < base))
{
/* Ignore leading zeros */
if ((prec == 0) && (decflg == 0) && (k == 0))
@@ -5099,11 +5124,15 @@ asctoeg (ss, y, oprec)
if ((trail == 0) && (decflg != 0))
{
sp = s;
- while ((*sp >= '0') && (*sp <= '9'))
+ while ((*sp >= '0' && *sp <= '9')
+ || (base == 16 && ((*sp >= 'a' && *sp <= 'f')
+ || (*sp >= 'A' && *sp <= 'F'))))
++sp;
/* Check for syntax error */
c = *sp & 0x7f;
- if ((c != 'e') && (c != 'E') && (c != '\0')
+ if ((base != 10 || ((c != 'e') && (c != 'E')))
+ && (base != 16 || ((c != 'p') && (c != 'P')))
+ && (c != '\0')
&& (c != '\n') && (c != '\r') && (c != ' ')
&& (c != ','))
goto error;
@@ -5122,13 +5151,28 @@ asctoeg (ss, y, oprec)
if (yy[2] == 0)
{
- if (decflg)
- nexp += 1; /* count digits after decimal point */
- eshup1 (yy); /* multiply current number by 10 */
- emovz (yy, xt);
- eshup1 (xt);
- eshup1 (xt);
- eaddm (xt, yy);
+ if (base == 16)
+ {
+ if (decflg)
+ nexp += 4; /* count digits after decimal point */
+
+ eshup1 (yy); /* multiply current number by 16 */
+ eshup1 (yy);
+ eshup1 (yy);
+ eshup1 (yy);
+ }
+ else
+ {
+ if (decflg)
+ nexp += 1; /* count digits after decimal point */
+
+ eshup1 (yy); /* multiply current number by 10 */
+ emovz (yy, xt);
+ eshup1 (xt);
+ eshup1 (xt);
+ eaddm (xt, yy);
+ }
+ /* Insert the current digit. */
ecleaz (xt);
xt[NI - 2] = (unsigned EMUSHORT) k;
eaddm (xt, yy);
@@ -5139,7 +5183,12 @@ asctoeg (ss, y, oprec)
lost |= k;
/* Count lost digits before the decimal point. */
if (decflg == 0)
- nexp -= 1;
+ {
+ if (base == 10)
+ nexp -= 1;
+ else
+ nexp -= 4;
+ }
}
prec += 1;
goto donchr;
@@ -5151,6 +5200,8 @@ asctoeg (ss, y, oprec)
break;
case 'E':
case 'e':
+ case 'P':
+ case 'p':
goto expnt;
case '.': /* decimal point */
if (decflg)
@@ -5217,24 +5268,19 @@ read_expnt:
{
exp *= 10;
exp += *s++ - '0';
- if (exp > -(MINDECEXP))
- {
- if (esign < 0)
- goto zero;
- else
- goto infinite;
- }
+ if (exp > 999999)
+ break;
}
if (esign < 0)
exp = -exp;
- if (exp > MAXDECEXP)
+ if ((exp > MAXDECEXP) && (base == 10))
{
infinite:
ecleaz (yy);
yy[E] = 0x7fff; /* infinity */
goto aexit;
}
- if (exp < MINDECEXP)
+ if ((exp < MINDECEXP) && (base == 10))
{
zero:
ecleaz (yy);
@@ -5242,6 +5288,25 @@ read_expnt:
}
daldone:
+ if (base == 16)
+ {
+ /* Base 16 hexadecimal floating constant. */
+ if ((k = enormlz (yy)) > NBITS)
+ {
+ ecleaz (yy);
+ goto aexit;
+ }
+ /* Adjust the exponent. NEXP is the number of hex digits,
+ EXP is a power of 2. */
+ lexp = (EXONE - 1 + NBITS) - k + yy[E] + exp - nexp;
+ if (lexp > 0x7fff)
+ goto infinite;
+ if (lexp < 0)
+ goto zero;
+ yy[E] = lexp;
+ goto expdon;
+ }
+
nexp = exp - nexp;
/* Pad trailing zeros to minimize power of 10, per IEEE spec. */
while ((nexp > 0) && (yy[2] == 0))
@@ -5263,6 +5328,7 @@ read_expnt:
}
lexp = (EXONE - 1 + NBITS) - k;
emdnorm (yy, lost, 0, lexp, 64);
+ lost = 0;
/* Convert to external format:
@@ -5318,6 +5384,7 @@ read_expnt:
k = emulm (tt, yy);
lexp -= EXONE - 1;
}
+ lost = k;
expdon:
@@ -5341,7 +5408,7 @@ read_expnt:
lexp -= EXONE - 0201;
#endif
rndprc = oprec;
- emdnorm (yy, k, 0, lexp, 64);
+ emdnorm (yy, lost, 0, lexp, 64);
aexit:
@@ -5409,7 +5476,7 @@ static unsigned EMUSHORT bmask[] =
0x0000,
};
-static void
+static void
efloor (x, y)
unsigned EMUSHORT x[], y[];
{
@@ -5460,7 +5527,7 @@ efloor (x, y)
/* Return S and EXP such that S * 2^EXP = X and .5 <= S < 1.
For example, 1.1 = 0.55 * 2^1. */
-static void
+static void
efrexp (x, exp, s)
unsigned EMUSHORT x[];
int *exp;
@@ -5485,7 +5552,7 @@ efrexp (x, exp, s)
/* Return e type Y = X * 2^PWR2. */
-static void
+static void
eldexp (x, pwr2, y)
unsigned EMUSHORT x[];
int pwr2;
@@ -5508,7 +5575,7 @@ eldexp (x, pwr2, y)
/* C = remainder after dividing B by A, all e type values.
Least significant integer quotient bits left in EQUOT. */
-static void
+static void
eremain (a, b, c)
unsigned EMUSHORT a[], b[], c[];
{
@@ -5545,7 +5612,7 @@ eremain (a, b, c)
/* Return quotient of exploded e-types NUM / DEN in EQUOT,
remainder in NUM. */
-static void
+static void
eiremain (den, num)
unsigned EMUSHORT den[], num[];
{
@@ -5575,10 +5642,9 @@ eiremain (den, num)
}
/* Report an error condition CODE encountered in function NAME.
- CODE is one of the following:
Mnemonic Value Significance
-
+
DOMAIN 1 argument domain error
SING 2 function singularity
OVERFLOW 3 overflow range error
@@ -5588,42 +5654,53 @@ eiremain (den, num)
INVALID 7 NaN - producing operation
EDOM 33 Unix domain error code
ERANGE 34 Unix range error code
-
+
The order of appearance of the following messages is bound to the
error codes defined above. */
-#define NMSGS 8
-static char *ermsg[NMSGS] =
-{
- "unknown", /* error code 0 */
- "domain", /* error code 1 */
- "singularity", /* et seq. */
- "overflow",
- "underflow",
- "total loss of precision",
- "partial loss of precision",
- "invalid operation"
-};
-
int merror = 0;
extern int merror;
-static void
+static void
mtherr (name, code)
- char *name;
+ const char *name;
int code;
{
- char errstr[80];
-
/* The string passed by the calling program is supposed to be the
name of the function in which the error occurred.
The code argument selects which error message string will be printed. */
- if ((code <= 0) || (code >= NMSGS))
- code = 0;
- sprintf (errstr, " %s %s error", name, ermsg[code]);
+ if (strcmp (name, "esub") == 0)
+ name = "subtraction";
+ else if (strcmp (name, "ediv") == 0)
+ name = "division";
+ else if (strcmp (name, "emul") == 0)
+ name = "multiplication";
+ else if (strcmp (name, "enormlz") == 0)
+ name = "normalization";
+ else if (strcmp (name, "etoasc") == 0)
+ name = "conversion to text";
+ else if (strcmp (name, "asctoe") == 0)
+ name = "parsing";
+ else if (strcmp (name, "eremain") == 0)
+ name = "modulus";
+ else if (strcmp (name, "esqrt") == 0)
+ name = "square root";
if (extra_warnings)
- warning (errstr);
+ {
+ switch (code)
+ {
+ case DOMAIN: warning ("%s: argument domain error" , name); break;
+ case SING: warning ("%s: function singularity" , name); break;
+ case OVERFLOW: warning ("%s: overflow range error" , name); break;
+ case UNDERFLOW: warning ("%s: underflow range error" , name); break;
+ case TLOSS: warning ("%s: total loss of precision" , name); break;
+ case PLOSS: warning ("%s: partial loss of precision", name); break;
+ case INVALID: warning ("%s: NaN - producing operation", name); break;
+ default: abort ();
+ }
+ }
+
/* Set global error message word */
merror = code + 1;
}
@@ -5631,7 +5708,7 @@ mtherr (name, code)
#ifdef DEC
/* Convert DEC double precision D to e type E. */
-static void
+static void
dectoe (d, e)
unsigned EMUSHORT *d;
unsigned EMUSHORT *e;
@@ -5671,7 +5748,7 @@ dectoe (d, e)
/* Convert e type X to DEC double precision D. */
-static void
+static void
etodec (x, d)
unsigned EMUSHORT *x, *d;
{
@@ -5693,7 +5770,7 @@ etodec (x, d)
/* Convert exploded e-type X, that has already been rounded to
56-bit precision, to DEC format double Y. */
-static void
+static void
todec (x, y)
unsigned EMUSHORT *x, *y;
{
@@ -5739,7 +5816,7 @@ todec (x, y)
#ifdef IBM
/* Convert IBM single/double precision to e type. */
-static void
+static void
ibmtoe (d, e, mode)
unsigned EMUSHORT *d;
unsigned EMUSHORT *e;
@@ -5783,7 +5860,7 @@ ibmtoe (d, e, mode)
/* Convert e type to IBM single/double precision. */
-static void
+static void
etoibm (x, d, mode)
unsigned EMUSHORT *x, *d;
enum machine_mode mode;
@@ -5802,7 +5879,7 @@ etoibm (x, d, mode)
toibm (xi, d, mode);
}
-static void
+static void
toibm (x, y, mode)
unsigned EMUSHORT *x, *y;
enum machine_mode mode;
@@ -5860,7 +5937,7 @@ toibm (x, y, mode)
#ifdef C4X
/* Convert C4X single/double precision to e type. */
-static void
+static void
c4xtoe (d, e, mode)
unsigned EMUSHORT *d;
unsigned EMUSHORT *e;
@@ -5868,7 +5945,6 @@ c4xtoe (d, e, mode)
{
unsigned EMUSHORT y[NI];
int r;
- int rndsav;
int isnegative;
int size;
int i;
@@ -5899,7 +5975,7 @@ c4xtoe (d, e, mode)
{
isnegative = FALSE;
}
-
+
r >>= 8; /* Shift exponent word down 8 bits. */
if (r & 0x80) /* Make the exponent negative if it is. */
{
@@ -5911,7 +5987,7 @@ c4xtoe (d, e, mode)
/* Now do the high order mantissa. We don't "or" on the high bit
because it is 2 (not 1) and is handled a little differently
below. */
- y[M] = d[0] & 0x7f;
+ y[M] = d[0] & 0x7f;
y[M+1] = d[1];
if (mode != QFmode) /* There are only 2 words in QFmode. */
@@ -5956,11 +6032,11 @@ c4xtoe (d, e, mode)
{
/* Add our e type exponent offset to form our exponent. */
r += EXONE;
- y[1] = r;
+ y[1] = r;
/* Now do the high order mantissa strip off the exponent and sign
bits and add the high 1 bit. */
- y[M] = d[0] & 0x7f | 0x80;
+ y[M] = (d[0] & 0x7f) | 0x80;
y[M+1] = d[1];
if (mode != QFmode) /* There are only 2 words in QFmode. */
@@ -5977,7 +6053,7 @@ c4xtoe (d, e, mode)
/* Convert e type to C4X single/double precision. */
-static void
+static void
etoc4x (x, d, mode)
unsigned EMUSHORT *x, *d;
enum machine_mode mode;
@@ -5999,16 +6075,15 @@ etoc4x (x, d, mode)
toc4x (xi, d, mode);
}
-static void
+static void
toc4x (x, y, mode)
unsigned EMUSHORT *x, *y;
enum machine_mode mode;
{
int i;
- int r;
int v;
int carry;
-
+
/* Short-circuit the zero case */
if ((x[0] == 0) /* Zero exponent and sign */
&& (x[1] == 0)
@@ -6027,17 +6102,17 @@ toc4x (x, y, mode)
}
return;
}
-
+
*y = 0;
-
+
/* Negative number require a two's complement conversion of the
mantissa. */
if (x[0])
{
*y = 0x0080;
-
+
i = ((int) x[1]) - 0x7f;
-
+
/* Now add 1 to the inverted data to do the two's complement. */
if (mode != QFmode)
v = 4 + M;
@@ -6057,7 +6132,7 @@ toc4x (x, y, mode)
}
v--;
}
-
+
/* The following is a special case. The C4X negative float requires
a zero in the high bit (because the format is (2 - x) x 2^m), so
if a one is in that bit, we have to shift left one to get rid
@@ -6089,11 +6164,11 @@ toc4x (x, y, mode)
#endif
return;
}
-
+
y[0] |= ((i & 0xff) << 8);
-
+
eshift (x, 8);
-
+
y[0] |= x[M] & 0x7f;
y[1] = x[M + 1];
if (mode != QFmode)
@@ -6200,11 +6275,11 @@ make_nan (nan, sign, mode)
abort ();
}
if (REAL_WORDS_BIG_ENDIAN)
- *nan++ = (sign << 15) | *p++;
+ *nan++ = (sign << 15) | (*p++ & 0x7fff);
while (--n != 0)
*nan++ = *p++;
if (! REAL_WORDS_BIG_ENDIAN)
- *nan = (sign << 15) | *p;
+ *nan = (sign << 15) | (*p & 0x7fff);
}
/* This is the inverse of the function `etarsingle' invoked by
@@ -6442,7 +6517,7 @@ ditoe (di, e)
/* Convert e-type to unsigned 64-bit int. */
-static void
+static void
etoudi (x, i)
unsigned EMUSHORT *x;
unsigned EMUSHORT *i;
@@ -6525,7 +6600,7 @@ noshift:
/* Convert e-type to signed 64-bit int. */
-static void
+static void
etodi (x, i)
unsigned EMUSHORT *x;
unsigned EMUSHORT *i;
@@ -6627,7 +6702,7 @@ etodi (x, i)
static int esqinited = 0;
static unsigned short sqrndbit[NI];
-static void
+static void
esqrt (x, y)
unsigned EMUSHORT *x, *y;
{
@@ -6748,7 +6823,7 @@ significand_size (mode)
switch (GET_MODE_BITSIZE (mode))
{
case 32:
-
+
#if TARGET_FLOAT_FORMAT == C4X_FLOAT_FORMAT
return 56;
#endif
diff --git a/gcc/real.h b/gcc/real.h
index 0719c26654d..f289379efd8 100644
--- a/gcc/real.h
+++ b/gcc/real.h
@@ -1,5 +1,5 @@
/* Definitions of floating-point access for GNU compiler.
- Copyright (C) 1989, 1991, 1994, 1996, 1997 Free Software Foundation, Inc.
+ Copyright (C) 1989, 91, 94, 96-98, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -132,7 +132,7 @@ extern void earith PROTO((REAL_VALUE_TYPE *, int,
REAL_VALUE_TYPE *, REAL_VALUE_TYPE *));
extern REAL_VALUE_TYPE etrunci PROTO((REAL_VALUE_TYPE));
extern REAL_VALUE_TYPE etruncui PROTO((REAL_VALUE_TYPE));
-extern REAL_VALUE_TYPE ereal_atof PROTO((char *, enum machine_mode));
+extern REAL_VALUE_TYPE ereal_atof PROTO((const char *, enum machine_mode));
extern REAL_VALUE_TYPE ereal_negate PROTO((REAL_VALUE_TYPE));
extern HOST_WIDE_INT efixi PROTO((REAL_VALUE_TYPE));
extern unsigned HOST_WIDE_INT efixui PROTO((REAL_VALUE_TYPE));
@@ -178,7 +178,11 @@ extern REAL_VALUE_TYPE real_value_truncate PROTO ((enum machine_mode,
toward zero. */
#define REAL_VALUE_UNSIGNED_FIX(x) (efixui (x))
+/* Convert ASCII string S to floating point in mode M.
+ Decimal input uses ATOF. Hexadecimal uses HTOF. */
#define REAL_VALUE_ATOF ereal_atof
+#define REAL_VALUE_HTOF ereal_atof
+
#define REAL_VALUE_NEGATE ereal_negate
#define REAL_VALUE_MINUS_ZERO(x) \
@@ -355,6 +359,9 @@ extern double ldexp ();
/* Use real.c to convert decimal numbers to binary, ... */
REAL_VALUE_TYPE ereal_atof ();
#define REAL_VALUE_ATOF(x, s) ereal_atof (x, s)
+/* Could use ereal_atof here for hexadecimal floats too, but real_hex_to_f
+ is OK and it uses faster native fp arithmetic. */
+/* #define REAL_VALUE_HTOF(x, s) ereal_atof (x, s) */
#else
/* ... or, if you like the host computer's atof, go ahead and use it: */
#define REAL_VALUE_ATOF(x, s) atof (x)
@@ -369,6 +376,13 @@ extern double (atof) ();
#endif
#endif
+/* Hexadecimal floating constant input for use with host computer's
+ fp arithmetic. */
+#ifndef REAL_VALUE_HTOF
+extern REAL_VALUE_TYPE real_hex_to_f PROTO((char *, enum machine_mode));
+#define REAL_VALUE_HTOF(s,m) real_hex_to_f(s,m)
+#endif
+
/* Negate the floating-point value X. */
#ifndef REAL_VALUE_NEGATE
#define REAL_VALUE_NEGATE(x) (- (x))
diff --git a/gcc/recog.c b/gcc/recog.c
index 1127cb801e3..e344b27e97e 100644
--- a/gcc/recog.c
+++ b/gcc/recog.c
@@ -1,5 +1,5 @@
/* Subroutines used by or related to instruction recognition.
- Copyright (C) 1987, 1988, 91-97, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1987, 1988, 91-98, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -31,6 +31,8 @@ Boston, MA 02111-1307, USA. */
#include "hard-reg-set.h"
#include "flags.h"
#include "real.h"
+#include "toplev.h"
+#include "basic-block.h"
#ifndef STACK_PUSH_CODE
#ifdef STACK_GROWS_DOWNWARD
@@ -40,9 +42,18 @@ Boston, MA 02111-1307, USA. */
#endif
#endif
-static void validate_replace_rtx_1 PROTO((rtx *, rtx, rtx, rtx));
-static rtx *find_single_use_1 PROTO((rtx, rtx *));
-static rtx *find_constant_term_loc PROTO((rtx *));
+#ifndef STACK_POP_CODE
+#ifdef STACK_GROWS_DOWNWARD
+#define STACK_POP_CODE POST_INC
+#else
+#define STACK_POP_CODE POST_DEC
+#endif
+#endif
+
+static void validate_replace_rtx_1 PROTO((rtx *, rtx, rtx, rtx));
+static rtx *find_single_use_1 PROTO((rtx, rtx *));
+static rtx *find_constant_term_loc PROTO((rtx *));
+static int insn_invalid_p PROTO((rtx));
/* Nonzero means allow operands to be volatile.
This should be 0 if you are generating rtl, such as if you are calling
@@ -54,6 +65,50 @@ static rtx *find_constant_term_loc PROTO((rtx *));
int volatile_ok;
+/* The next variables are set up by extract_insn. The first four of them
+ are also set up during insn_extract. */
+
+/* Indexed by N, gives value of operand N. */
+rtx recog_operand[MAX_RECOG_OPERANDS];
+
+/* Indexed by N, gives location where operand N was found. */
+rtx *recog_operand_loc[MAX_RECOG_OPERANDS];
+
+/* Indexed by N, gives location where the Nth duplicate-appearance of
+ an operand was found. This is something that matched MATCH_DUP. */
+rtx *recog_dup_loc[MAX_RECOG_OPERANDS];
+
+/* Indexed by N, gives the operand number that was duplicated in the
+ Nth duplicate-appearance of an operand. */
+char recog_dup_num[MAX_RECOG_OPERANDS];
+
+/* The number of operands of the insn. */
+int recog_n_operands;
+
+/* The number of MATCH_DUPs in the insn. */
+int recog_n_dups;
+
+/* The number of alternatives in the constraints for the insn. */
+int recog_n_alternatives;
+
+/* Indexed by N, gives the mode of operand N. */
+enum machine_mode recog_operand_mode[MAX_RECOG_OPERANDS];
+
+/* Indexed by N, gives the constraint string for operand N. */
+const char *recog_constraints[MAX_RECOG_OPERANDS];
+
+/* Indexed by N, gives the type (in, out, inout) for operand N. */
+enum op_type recog_op_type[MAX_RECOG_OPERANDS];
+
+#ifndef REGISTER_CONSTRAINTS
+/* Indexed by N, nonzero if operand N should be an address. */
+char recog_operand_address_p[MAX_RECOG_OPERANDS];
+#endif
+
+/* Contains a vector of operand_alternative structures for every operand.
+ Set up by preprocess_constraints. */
+struct operand_alternative recog_op_alt[MAX_RECOG_OPERANDS][MAX_RECOG_ALTERNATIVES];
+
/* On return from `constrain_operands', indicate which alternative
was satisfied. */
@@ -106,21 +161,42 @@ int
check_asm_operands (x)
rtx x;
{
- int noperands = asm_noperands (x);
+ int noperands;
rtx *operands;
+ const char **constraints;
int i;
+ /* Post-reload, be more strict with things. */
+ if (reload_completed)
+ {
+ /* ??? Doh! We've not got the wrapping insn. Cook one up. */
+ extract_insn (make_insn_raw (x));
+ constrain_operands (1);
+ return which_alternative >= 0;
+ }
+
+ noperands = asm_noperands (x);
if (noperands < 0)
return 0;
if (noperands == 0)
return 1;
operands = (rtx *) alloca (noperands * sizeof (rtx));
- decode_asm_operands (x, operands, NULL_PTR, NULL_PTR, NULL_PTR);
+ constraints = (const char **) alloca (noperands * sizeof (char *));
+
+ decode_asm_operands (x, operands, NULL_PTR, constraints, NULL_PTR);
for (i = 0; i < noperands; i++)
- if (!general_operand (operands[i], VOIDmode))
- return 0;
+ {
+ const char *c = constraints[i];
+ if (c[0] == '%')
+ c++;
+ if (ISDIGIT ((unsigned char)c[0]) && c[1] == '\0')
+ c = constraints[c[0] - '0'];
+
+ if (! asm_operand_ok (operands[i], c))
+ return 0;
+ }
return 1;
}
@@ -213,6 +289,33 @@ validate_change (object, loc, new, in_group)
return apply_change_group ();
}
+/* This subroutine of apply_change_group verifies whether the changes to INSN
+ were valid; i.e. whether INSN can still be recognized. */
+
+static int
+insn_invalid_p (insn)
+ rtx insn;
+{
+ int icode = recog_memoized (insn);
+ int is_asm = icode < 0 && asm_noperands (PATTERN (insn)) >= 0;
+
+ if (is_asm && ! check_asm_operands (PATTERN (insn)))
+ return 1;
+ if (! is_asm && icode < 0)
+ return 1;
+
+ /* After reload, verify that all constraints are satisfied. */
+ if (reload_completed)
+ {
+ extract_insn (insn);
+
+ if (! constrain_operands (1))
+ return 1;
+ }
+
+ return 0;
+}
+
/* Apply a group of changes previously issued with `validate_change'.
Return 1 if all changes are valid, zero otherwise. */
@@ -228,8 +331,7 @@ apply_change_group ()
given a MEM and it still is a valid address, or if this is in insn
and it is recognized. In the latter case, if reload has completed,
we also require that the operands meet the constraints for
- the insn. We do not allow modifying an ASM_OPERANDS after reload
- has completed because verifying the constraints is too difficult. */
+ the insn. */
for (i = 0; i < num_changes; i++)
{
@@ -243,13 +345,7 @@ apply_change_group ()
if (! memory_address_p (GET_MODE (object), XEXP (object, 0)))
break;
}
- else if ((recog_memoized (object) < 0
- && (asm_noperands (PATTERN (object)) < 0
- || ! check_asm_operands (PATTERN (object))
- || reload_completed))
- || (reload_completed
- && (insn_extract (object),
- ! constrain_operands (INSN_CODE (object), 1))))
+ else if (insn_invalid_p (object))
{
rtx pat = PATTERN (object);
@@ -454,9 +550,8 @@ validate_replace_rtx_1 (loc, from, to, object)
- MIN (UNITS_PER_WORD, GET_MODE_SIZE (mode)));
new = gen_rtx_MEM (mode, plus_constant (XEXP (to, 0), offset));
- MEM_VOLATILE_P (new) = MEM_VOLATILE_P (to);
RTX_UNCHANGING_P (new) = RTX_UNCHANGING_P (to);
- MEM_IN_STRUCT_P (new) = MEM_IN_STRUCT_P (to);
+ MEM_COPY_ATTRIBUTES (new, to);
validate_change (object, loc, new, 1);
return;
}
@@ -514,8 +609,7 @@ validate_replace_rtx_1 (loc, from, to, object)
newmem = gen_rtx_MEM (wanted_mode,
plus_constant (XEXP (to, 0), offset));
RTX_UNCHANGING_P (newmem) = RTX_UNCHANGING_P (to);
- MEM_VOLATILE_P (newmem) = MEM_VOLATILE_P (to);
- MEM_IN_STRUCT_P (newmem) = MEM_IN_STRUCT_P (to);
+ MEM_COPY_ATTRIBUTES (newmem, to);
validate_change (object, &XEXP (x, 2), GEN_INT (pos), 1);
validate_change (object, &XEXP (x, 0), newmem, 1);
@@ -997,6 +1091,12 @@ immediate_operand (op, mode)
&& GET_MODE_CLASS (mode) != MODE_PARTIAL_INT)
return 0;
+ /* Accept CONSTANT_P_RTX, since it will be gone by CSE1 and
+ result in 0/1. It seems a safe assumption that this is
+ in range for everyone. */
+ if (GET_CODE (op) == CONSTANT_P_RTX)
+ return 1;
+
return (CONSTANT_P (op)
&& (GET_MODE (op) == mode || mode == VOIDmode
|| GET_MODE (op) == VOIDmode)
@@ -1011,7 +1111,7 @@ immediate_operand (op, mode)
int
const_int_operand (op, mode)
register rtx op;
- enum machine_mode mode;
+ enum machine_mode mode ATTRIBUTE_UNUSED;
{
return GET_CODE (op) == CONST_INT;
}
@@ -1106,7 +1206,7 @@ push_operand (op, mode)
if (GET_CODE (op) != MEM)
return 0;
- if (GET_MODE (op) != mode)
+ if (mode != VOIDmode && GET_MODE (op) != mode)
return 0;
op = XEXP (op, 0);
@@ -1117,6 +1217,31 @@ push_operand (op, mode)
return XEXP (op, 0) == stack_pointer_rtx;
}
+/* Return 1 if OP is a valid operand that stands for popping a
+ value of mode MODE off the stack.
+
+ The main use of this function is as a predicate in match_operand
+ expressions in the machine description. */
+
+int
+pop_operand (op, mode)
+ rtx op;
+ enum machine_mode mode;
+{
+ if (GET_CODE (op) != MEM)
+ return 0;
+
+ if (mode != VOIDmode && GET_MODE (op) != mode)
+ return 0;
+
+ op = XEXP (op, 0);
+
+ if (GET_CODE (op) != STACK_POP_CODE)
+ return 0;
+
+ return XEXP (op, 0) == stack_pointer_rtx;
+}
+
/* Return 1 if ADDR is a valid memory address for mode MODE. */
int
@@ -1300,7 +1425,7 @@ decode_asm_operands (body, operands, operand_locs, constraints, modes)
rtx body;
rtx *operands;
rtx **operand_locs;
- char **constraints;
+ const char **constraints;
enum machine_mode *modes;
{
register int i;
@@ -1427,6 +1552,218 @@ decode_asm_operands (body, operands, operand_locs, constraints, modes)
return template;
}
+
+/* Check if an asm_operand matches it's constraints.
+ Return > 0 if ok, = 0 if bad, < 0 if inconclusive. */
+
+int
+asm_operand_ok (op, constraint)
+ rtx op;
+ const char *constraint;
+{
+ int result = 0;
+
+ /* Use constrain_operands after reload. */
+ if (reload_completed)
+ abort ();
+
+ while (*constraint)
+ {
+ switch (*constraint++)
+ {
+ case '=':
+ case '+':
+ case '*':
+ case '%':
+ case '?':
+ case '!':
+ case '#':
+ case '&':
+ case ',':
+ break;
+
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ /* For best results, our caller should have given us the
+ proper matching constraint, but we can't actually fail
+ the check if they didn't. Indicate that results are
+ inconclusive. */
+ result = -1;
+ break;
+
+ case 'p':
+ if (address_operand (op, VOIDmode))
+ return 1;
+ break;
+
+ case 'm':
+ case 'V': /* non-offsettable */
+ if (memory_operand (op, VOIDmode))
+ return 1;
+ break;
+
+ case 'o': /* offsettable */
+ if (offsettable_nonstrict_memref_p (op))
+ return 1;
+ break;
+
+ case '<':
+ /* ??? Before flow, auto inc/dec insns are not supposed to exist,
+ excepting those that expand_call created. Further, on some
+ machines which do not have generalized auto inc/dec, an inc/dec
+ is not a memory_operand.
+
+ Match any memory and hope things are resolved after reload. */
+
+ if (GET_CODE (op) == MEM
+ && (1
+ || GET_CODE (XEXP (op, 0)) == PRE_DEC
+ || GET_CODE (XEXP (op, 0)) == POST_DEC))
+ return 1;
+ break;
+
+ case '>':
+ if (GET_CODE (op) == MEM
+ && (1
+ || GET_CODE (XEXP (op, 0)) == PRE_INC
+ || GET_CODE (XEXP (op, 0)) == POST_INC))
+ return 1;
+ break;
+
+ case 'E':
+#ifndef REAL_ARITHMETIC
+ /* Match any floating double constant, but only if
+ we can examine the bits of it reliably. */
+ if ((HOST_FLOAT_FORMAT != TARGET_FLOAT_FORMAT
+ || HOST_BITS_PER_WIDE_INT != BITS_PER_WORD)
+ && GET_MODE (op) != VOIDmode && ! flag_pretend_float)
+ break;
+#endif
+ /* FALLTHRU */
+
+ case 'F':
+ if (GET_CODE (op) == CONST_DOUBLE)
+ return 1;
+ break;
+
+ case 'G':
+ if (GET_CODE (op) == CONST_DOUBLE
+ && CONST_DOUBLE_OK_FOR_LETTER_P (op, 'G'))
+ return 1;
+ break;
+ case 'H':
+ if (GET_CODE (op) == CONST_DOUBLE
+ && CONST_DOUBLE_OK_FOR_LETTER_P (op, 'H'))
+ return 1;
+ break;
+
+ case 's':
+ if (GET_CODE (op) == CONST_INT
+ || (GET_CODE (op) == CONST_DOUBLE
+ && GET_MODE (op) == VOIDmode))
+ break;
+ /* FALLTHRU */
+
+ case 'i':
+ if (CONSTANT_P (op)
+#ifdef LEGITIMATE_PIC_OPERAND_P
+ && (! flag_pic || LEGITIMATE_PIC_OPERAND_P (op))
+#endif
+ )
+ return 1;
+ break;
+
+ case 'n':
+ if (GET_CODE (op) == CONST_INT
+ || (GET_CODE (op) == CONST_DOUBLE
+ && GET_MODE (op) == VOIDmode))
+ return 1;
+ break;
+
+ case 'I':
+ if (GET_CODE (op) == CONST_INT
+ && CONST_OK_FOR_LETTER_P (INTVAL (op), 'I'))
+ return 1;
+ break;
+ case 'J':
+ if (GET_CODE (op) == CONST_INT
+ && CONST_OK_FOR_LETTER_P (INTVAL (op), 'J'))
+ return 1;
+ break;
+ case 'K':
+ if (GET_CODE (op) == CONST_INT
+ && CONST_OK_FOR_LETTER_P (INTVAL (op), 'K'))
+ return 1;
+ break;
+ case 'L':
+ if (GET_CODE (op) == CONST_INT
+ && CONST_OK_FOR_LETTER_P (INTVAL (op), 'L'))
+ return 1;
+ break;
+ case 'M':
+ if (GET_CODE (op) == CONST_INT
+ && CONST_OK_FOR_LETTER_P (INTVAL (op), 'M'))
+ return 1;
+ break;
+ case 'N':
+ if (GET_CODE (op) == CONST_INT
+ && CONST_OK_FOR_LETTER_P (INTVAL (op), 'N'))
+ return 1;
+ break;
+ case 'O':
+ if (GET_CODE (op) == CONST_INT
+ && CONST_OK_FOR_LETTER_P (INTVAL (op), 'O'))
+ return 1;
+ break;
+ case 'P':
+ if (GET_CODE (op) == CONST_INT
+ && CONST_OK_FOR_LETTER_P (INTVAL (op), 'P'))
+ return 1;
+ break;
+
+ case 'X':
+ return 1;
+
+ case 'g':
+ if (general_operand (op, VOIDmode))
+ return 1;
+ break;
+
+#ifdef EXTRA_CONSTRAINT
+ case 'Q':
+ if (EXTRA_CONSTRAINT (op, 'Q'))
+ return 1;
+ break;
+ case 'R':
+ if (EXTRA_CONSTRAINT (op, 'R'))
+ return 1;
+ break;
+ case 'S':
+ if (EXTRA_CONSTRAINT (op, 'S'))
+ return 1;
+ break;
+ case 'T':
+ if (EXTRA_CONSTRAINT (op, 'T'))
+ return 1;
+ break;
+ case 'U':
+ if (EXTRA_CONSTRAINT (op, 'U'))
+ return 1;
+ break;
+#endif
+
+ case 'r':
+ default:
+ if (GET_MODE (op) == BLKmode)
+ break;
+ if (register_operand (op, VOIDmode))
+ return 1;
+ break;
+ }
+ }
+
+ return result;
+}
/* Given an rtx *P, if it is a sum containing an integer constant term,
return the location (type rtx *) of the pointer to that constant term.
@@ -1578,11 +1915,12 @@ offsettable_address_p (strictp, mode, y)
int
mode_dependent_address_p (addr)
- rtx addr;
+ rtx addr ATTRIBUTE_UNUSED; /* Maybe used in GO_IF_MODE_DEPENDENT_ADDRESS. */
{
GO_IF_MODE_DEPENDENT_ADDRESS (addr, win);
return 0;
- win:
+ /* Label `win' might (not) be used via GO_IF_MODE_DEPENDENT_ADDRESS. */
+ win: ATTRIBUTE_UNUSED_LABEL
return 1;
}
@@ -1605,7 +1943,8 @@ mode_independent_operand (op, mode)
addr = XEXP (op, 0);
GO_IF_MODE_DEPENDENT_ADDRESS (addr, lose);
return 1;
- lose:
+ /* Label `lose' might (not) be used via GO_IF_MODE_DEPENDENT_ADDRESS. */
+ lose: ATTRIBUTE_UNUSED_LABEL
return 0;
}
@@ -1656,11 +1995,206 @@ adj_offsettable_operand (op, offset)
abort ();
}
+/* Analyze INSN and compute the variables recog_n_operands, recog_n_dups,
+ recog_n_alternatives, recog_operand, recog_operand_loc, recog_constraints,
+ recog_operand_mode, recog_dup_loc and recog_dup_num.
+ If REGISTER_CONSTRAINTS is not defined, also compute
+ recog_operand_address_p. */
+void
+extract_insn (insn)
+ rtx insn;
+{
+ int i;
+ int icode;
+ int noperands;
+ rtx body = PATTERN (insn);
+
+ recog_n_operands = 0;
+ recog_n_alternatives = 0;
+ recog_n_dups = 0;
+
+ switch (GET_CODE (body))
+ {
+ case USE:
+ case CLOBBER:
+ case ASM_INPUT:
+ case ADDR_VEC:
+ case ADDR_DIFF_VEC:
+ return;
+
+ case SET:
+ case PARALLEL:
+ case ASM_OPERANDS:
+ recog_n_operands = noperands = asm_noperands (body);
+ if (noperands >= 0)
+ {
+ /* This insn is an `asm' with operands. */
+
+ /* expand_asm_operands makes sure there aren't too many operands. */
+ if (noperands > MAX_RECOG_OPERANDS)
+ abort ();
+
+ /* Now get the operand values and constraints out of the insn. */
+ decode_asm_operands (body, recog_operand, recog_operand_loc,
+ recog_constraints, recog_operand_mode);
+ if (noperands > 0)
+ {
+ const char *p = recog_constraints[0];
+ recog_n_alternatives = 1;
+ while (*p)
+ recog_n_alternatives += (*p++ == ',');
+ }
+#ifndef REGISTER_CONSTRAINTS
+ bzero (recog_operand_address_p, sizeof recog_operand_address_p);
+#endif
+ break;
+ }
+
+ /* FALLTHROUGH */
+
+ default:
+ /* Ordinary insn: recognize it, get the operands via insn_extract
+ and get the constraints. */
+
+ icode = recog_memoized (insn);
+ if (icode < 0)
+ fatal_insn_not_found (insn);
+
+ recog_n_operands = noperands = insn_n_operands[icode];
+ recog_n_alternatives = insn_n_alternatives[icode];
+ recog_n_dups = insn_n_dups[icode];
+
+ insn_extract (insn);
+
+ for (i = 0; i < noperands; i++)
+ {
#ifdef REGISTER_CONSTRAINTS
+ recog_constraints[i] = insn_operand_constraint[icode][i];
+#else
+ recog_operand_address_p[i] = insn_operand_address_p[icode][i];
+#endif
+ recog_operand_mode[i] = insn_operand_mode[icode][i];
+ }
+ }
+ for (i = 0; i < noperands; i++)
+ recog_op_type[i] = (recog_constraints[i][0] == '=' ? OP_OUT
+ : recog_constraints[i][0] == '+' ? OP_INOUT
+ : OP_IN);
-/* Check the operands of an insn (found in recog_operands)
- against the insn's operand constraints (found via INSN_CODE_NUM)
+ if (recog_n_alternatives > MAX_RECOG_ALTERNATIVES)
+ abort ();
+}
+
+/* After calling extract_insn, you can use this function to extract some
+ information from the constraint strings into a more usable form.
+ The collected data is stored in recog_op_alt. */
+void
+preprocess_constraints ()
+{
+ int i;
+
+ for (i = 0; i < recog_n_operands; i++)
+ {
+ int j;
+ struct operand_alternative *op_alt;
+ const char *p = recog_constraints[i];
+
+ op_alt = recog_op_alt[i];
+
+ for (j = 0; j < recog_n_alternatives; j++)
+ {
+ op_alt[j].class = NO_REGS;
+ op_alt[j].constraint = p;
+ op_alt[j].matches = -1;
+ op_alt[j].matched = -1;
+
+ if (*p == '\0' || *p == ',')
+ {
+ op_alt[j].anything_ok = 1;
+ continue;
+ }
+
+ for (;;)
+ {
+ char c = *p++;
+ if (c == '#')
+ do
+ c = *p++;
+ while (c != ',' && c != '\0');
+ if (c == ',' || c == '\0')
+ break;
+
+ switch (c)
+ {
+ case '=': case '+': case '*': case '%':
+ case 'E': case 'F': case 'G': case 'H':
+ case 's': case 'i': case 'n':
+ case 'I': case 'J': case 'K': case 'L':
+ case 'M': case 'N': case 'O': case 'P':
+#ifdef EXTRA_CONSTRAINT
+ case 'Q': case 'R': case 'S': case 'T': case 'U':
+#endif
+ /* These don't say anything we care about. */
+ break;
+
+ case '?':
+ op_alt[j].reject += 6;
+ break;
+ case '!':
+ op_alt[j].reject += 600;
+ break;
+ case '&':
+ op_alt[j].earlyclobber = 1;
+ break;
+
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ op_alt[j].matches = c - '0';
+ op_alt[op_alt[j].matches].matched = i;
+ break;
+
+ case 'm':
+ op_alt[j].memory_ok = 1;
+ break;
+ case '<':
+ op_alt[j].decmem_ok = 1;
+ break;
+ case '>':
+ op_alt[j].incmem_ok = 1;
+ break;
+ case 'V':
+ op_alt[j].nonoffmem_ok = 1;
+ break;
+ case 'o':
+ op_alt[j].offmem_ok = 1;
+ break;
+ case 'X':
+ op_alt[j].anything_ok = 1;
+ break;
+
+ case 'p':
+ op_alt[j].class = reg_class_subunion[(int) op_alt[j].class][(int) BASE_REG_CLASS];
+ break;
+
+ case 'g': case 'r':
+ op_alt[j].class = reg_class_subunion[(int) op_alt[j].class][(int) GENERAL_REGS];
+ break;
+
+ default:
+ op_alt[j].class = reg_class_subunion[(int) op_alt[j].class][(int) REG_CLASS_FROM_LETTER ((unsigned char)c)];
+ break;
+ }
+ }
+ }
+ }
+}
+
+#ifdef REGISTER_CONSTRAINTS
+
+/* Check the operands of an insn against the insn's operand constraints
and return 1 if they are valid.
+ The information about the insn's operands, constraints, operand modes
+ etc. is obtained from the global variables set up by extract_insn.
WHICH_ALTERNATIVE is set to a number which indicates which
alternative of constraints was matched: 0 for the first alternative,
@@ -1690,44 +2224,39 @@ struct funny_match
};
int
-constrain_operands (insn_code_num, strict)
- int insn_code_num;
+constrain_operands (strict)
int strict;
{
- char *constraints[MAX_RECOG_OPERANDS];
+ const char *constraints[MAX_RECOG_OPERANDS];
int matching_operands[MAX_RECOG_OPERANDS];
- enum op_type {OP_IN, OP_OUT, OP_INOUT} op_types[MAX_RECOG_OPERANDS];
int earlyclobber[MAX_RECOG_OPERANDS];
register int c;
- int noperands = insn_n_operands[insn_code_num];
struct funny_match funny_match[MAX_RECOG_OPERANDS];
int funny_match_index;
- int nalternatives = insn_n_alternatives[insn_code_num];
- if (noperands == 0 || nalternatives == 0)
+ if (recog_n_operands == 0 || recog_n_alternatives == 0)
return 1;
- for (c = 0; c < noperands; c++)
+ for (c = 0; c < recog_n_operands; c++)
{
- constraints[c] = insn_operand_constraint[insn_code_num][c];
+ constraints[c] = recog_constraints[c];
matching_operands[c] = -1;
- op_types[c] = OP_IN;
}
which_alternative = 0;
- while (which_alternative < nalternatives)
+ while (which_alternative < recog_n_alternatives)
{
register int opno;
int lose = 0;
funny_match_index = 0;
- for (opno = 0; opno < noperands; opno++)
+ for (opno = 0; opno < recog_n_operands; opno++)
{
register rtx op = recog_operand[opno];
enum machine_mode mode = GET_MODE (op);
- register char *p = constraints[opno];
+ register const char *p = constraints[opno];
int offset = 0;
int win = 0;
int val;
@@ -1759,6 +2288,8 @@ constrain_operands (insn_code_num, strict)
case '!':
case '*':
case '%':
+ case '=':
+ case '+':
break;
case '#':
@@ -1768,14 +2299,6 @@ constrain_operands (insn_code_num, strict)
p++;
break;
- case '=':
- op_types[opno] = OP_OUT;
- break;
-
- case '+':
- op_types[opno] = OP_INOUT;
- break;
-
case '&':
earlyclobber[opno] = 1;
break;
@@ -1820,8 +2343,8 @@ constrain_operands (insn_code_num, strict)
strictly valid, i.e., that all pseudos requiring hard regs
have gotten them. */
if (strict <= 0
- || (strict_memory_address_p
- (insn_operand_mode[insn_code_num][opno], op)))
+ || (strict_memory_address_p (recog_operand_mode[opno],
+ op)))
win = 1;
break;
@@ -2001,18 +2524,18 @@ constrain_operands (insn_code_num, strict)
operand. */
if (strict > 0)
- for (eopno = 0; eopno < noperands; eopno++)
+ for (eopno = 0; eopno < recog_n_operands; eopno++)
/* Ignore earlyclobber operands now in memory,
because we would often report failure when we have
two memory operands, one of which was formerly a REG. */
if (earlyclobber[eopno]
&& GET_CODE (recog_operand[eopno]) == REG)
- for (opno = 0; opno < noperands; opno++)
+ for (opno = 0; opno < recog_n_operands; opno++)
if ((GET_CODE (recog_operand[opno]) == MEM
- || op_types[opno] != OP_OUT)
+ || recog_op_type[opno] != OP_OUT)
&& opno != eopno
/* Ignore things like match_operator operands. */
- && *insn_operand_constraint[insn_code_num][opno] != 0
+ && *recog_constraints[opno] != 0
&& ! (matching_operands[opno] == eopno
&& operands_match_p (recog_operand[opno],
recog_operand[eopno]))
@@ -2038,7 +2561,7 @@ constrain_operands (insn_code_num, strict)
/* If we are about to reject this, but we are not to test strictly,
try a very loose test. Only return failure if it fails also. */
if (strict == 0)
- return constrain_operands (insn_code_num, -1);
+ return constrain_operands (-1);
else
return 0;
}
@@ -2074,3 +2597,84 @@ reg_fits_class_p (operand, class, offset, mode)
}
#endif /* REGISTER_CONSTRAINTS */
+
+/* Do the splitting of insns in the block B. Only try to actually split if
+ DO_SPLIT is true; otherwise, just remove nops. */
+
+void
+split_block_insns (b, do_split)
+ int b;
+ int do_split;
+{
+ rtx insn, next;
+
+ for (insn = BLOCK_HEAD (b);; insn = next)
+ {
+ rtx set;
+
+ /* Can't use `next_real_insn' because that
+ might go across CODE_LABELS and short-out basic blocks. */
+ next = NEXT_INSN (insn);
+ if (GET_CODE (insn) != INSN)
+ {
+ if (insn == BLOCK_END (b))
+ break;
+
+ continue;
+ }
+
+ /* Don't split no-op move insns. These should silently disappear
+ later in final. Splitting such insns would break the code
+ that handles REG_NO_CONFLICT blocks. */
+ set = single_set (insn);
+ if (set && rtx_equal_p (SET_SRC (set), SET_DEST (set)))
+ {
+ if (insn == BLOCK_END (b))
+ break;
+
+ /* Nops get in the way while scheduling, so delete them now if
+ register allocation has already been done. It is too risky
+ to try to do this before register allocation, and there are
+ unlikely to be very many nops then anyways. */
+ if (reload_completed)
+ {
+
+ PUT_CODE (insn, NOTE);
+ NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
+ NOTE_SOURCE_FILE (insn) = 0;
+ }
+
+ continue;
+ }
+
+ if (do_split)
+ {
+ /* Split insns here to get max fine-grain parallelism. */
+ rtx first = PREV_INSN (insn);
+ rtx notes = REG_NOTES (insn);
+ rtx last = try_split (PATTERN (insn), insn, 1);
+
+ if (last != insn)
+ {
+ /* try_split returns the NOTE that INSN became. */
+ first = NEXT_INSN (first);
+#ifdef INSN_SCHEDULING
+ update_flow_info (notes, first, last, insn);
+#endif
+ PUT_CODE (insn, NOTE);
+ NOTE_SOURCE_FILE (insn) = 0;
+ NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
+ if (insn == BLOCK_HEAD (b))
+ BLOCK_HEAD (b) = first;
+ if (insn == BLOCK_END (b))
+ {
+ BLOCK_END (b) = last;
+ break;
+ }
+ }
+ }
+
+ if (insn == BLOCK_END (b))
+ break;
+ }
+}
diff --git a/gcc/recog.h b/gcc/recog.h
index 980b76f70d7..79f22f9135a 100644
--- a/gcc/recog.h
+++ b/gcc/recog.h
@@ -1,5 +1,5 @@
/* Declarations for interface to insn recognizer and insn-output.c.
- Copyright (C) 1987, 1996, 1997 Free Software Foundation, Inc.
+ Copyright (C) 1987, 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -18,22 +18,72 @@ 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 "gansidecl.h"
+/* Random number that should be large enough for all purposes. */
+#define MAX_RECOG_ALTERNATIVES 30
+
+/* Types of operands. */
+enum op_type {
+ OP_IN,
+ OP_OUT,
+ OP_INOUT
+};
+
+struct operand_alternative
+{
+ /* Pointer to the beginning of the constraint string for this alternative,
+ for easier access by alternative number. */
+ const char *constraint;
+
+ /* The register class valid for this alternative (possibly NO_REGS). */
+ enum reg_class class;
+
+ /* "Badness" of this alternative, computed from number of '?' and '!'
+ characters in the constraint string. */
+ unsigned int reject;
+
+ /* -1 if no matching constraint was found, or an operand number. */
+ int matches;
+ /* The same information, but reversed: -1 if this operand is not
+ matched by any other, or the operand number of the operand that
+ matches this one. */
+ int matched;
+
+ /* Nonzero if '&' was found in the constraint string. */
+ unsigned int earlyclobber:1;
+ /* Nonzero if 'm' was found in the constraint string. */
+ unsigned int memory_ok:1;
+ /* Nonzero if 'o' was found in the constraint string. */
+ unsigned int offmem_ok:1;
+ /* Nonzero if 'V' was found in the constraint string. */
+ unsigned int nonoffmem_ok:1;
+ /* Nonzero if '<' was found in the constraint string. */
+ unsigned int decmem_ok:1;
+ /* Nonzero if '>' was found in the constraint string. */
+ unsigned int incmem_ok:1;
+ /* Nonzero if 'X' was found in the constraint string, or if the constraint
+ string for this alternative was empty. */
+ unsigned int anything_ok:1;
+};
+
extern void init_recog PROTO((void));
extern void init_recog_no_volatile PROTO((void));
extern int recog_memoized PROTO((rtx));
extern int check_asm_operands PROTO((rtx));
+extern int asm_operand_ok PROTO((rtx, const char *));
extern int validate_change PROTO((rtx, rtx *, rtx, int));
extern int apply_change_group PROTO((void));
extern int num_validated_changes PROTO((void));
extern void cancel_changes PROTO((int));
-extern int constrain_operands PROTO((int, int));
+extern int constrain_operands PROTO((int));
extern int memory_address_p PROTO((enum machine_mode, rtx));
extern int strict_memory_address_p PROTO((enum machine_mode, rtx));
extern int validate_replace_rtx PROTO((rtx, rtx, rtx));
extern void validate_replace_rtx_group PROTO((rtx, rtx, rtx));
extern int validate_replace_src PROTO((rtx, rtx, rtx));
+#ifdef HAVE_cc0
+extern int next_insn_tests_no_inequality PROTO ((rtx));
+#endif
extern int reg_fits_class_p PROTO((rtx, enum reg_class, int,
enum machine_mode));
extern rtx *find_single_use PROTO((rtx, rtx, rtx *));
@@ -44,10 +94,11 @@ extern int register_operand PROTO((rtx, enum machine_mode));
extern int scratch_operand PROTO((rtx, enum machine_mode));
extern int immediate_operand PROTO((rtx, enum machine_mode));
extern int const_int_operand PROTO((rtx, enum machine_mode));
-extern int cosnt_double_operand PROTO((rtx, enum machine_mode));
+extern int const_double_operand PROTO((rtx, enum machine_mode));
extern int nonimmediate_operand PROTO((rtx, enum machine_mode));
extern int nonmemory_operand PROTO((rtx, enum machine_mode));
extern int push_operand PROTO((rtx, enum machine_mode));
+extern int pop_operand PROTO((rtx, enum machine_mode));
extern int memory_operand PROTO((rtx, enum machine_mode));
extern int indirect_operand PROTO((rtx, enum machine_mode));
extern int mode_independent_operand PROTO((rtx, enum machine_mode));
@@ -61,10 +112,16 @@ extern int mode_dependent_address_p PROTO((rtx));
extern int recog PROTO((rtx, rtx, int *));
extern void add_clobbers PROTO((rtx, int));
extern void insn_extract PROTO((rtx));
+extern void extract_insn PROTO((rtx));
+extern void preprocess_constraints PROTO((void));
/* Nonzero means volatile operands are recognized. */
extern int volatile_ok;
+/* Set by constrain_operands to the number of the alternative that
+ matched. */
+extern int which_alternative;
+
/* The following vectors hold the results from insn_extract. */
/* Indexed by N, gives value of operand N. */
@@ -81,6 +138,35 @@ extern rtx *recog_dup_loc[];
Nth duplicate-appearance of an operand. */
extern char recog_dup_num[];
+/* The next variables are set up by extract_insn. */
+
+/* The number of operands of the insn. */
+extern int recog_n_operands;
+
+/* The number of MATCH_DUPs in the insn. */
+extern int recog_n_dups;
+
+/* The number of alternatives in the constraints for the insn. */
+extern int recog_n_alternatives;
+
+/* Indexed by N, gives the mode of operand N. */
+extern enum machine_mode recog_operand_mode[];
+
+/* Indexed by N, gives the constraint string for operand N. */
+extern const char *recog_constraints[];
+
+/* Indexed by N, gives the type (in, out, inout) for operand N. */
+extern enum op_type recog_op_type[];
+
+#ifndef REGISTER_CONSTRAINTS
+/* Indexed by N, nonzero if operand N should be an address. */
+extern char recog_operand_address_p[];
+#endif
+
+/* Contains a vector of operand_alternative structures for every operand.
+ Set up by preprocess_constraints. */
+extern struct operand_alternative recog_op_alt[MAX_RECOG_OPERANDS][MAX_RECOG_ALTERNATIVES];
+
/* Access the output function for CODE. */
#define OUT_FCN(CODE) (*insn_outfun[(int) (CODE)])
@@ -90,9 +176,9 @@ extern char recog_dup_num[];
/* These are vectors indexed by insn-code. Details in genoutput.c. */
-extern char *const insn_template[];
+extern const char *const insn_template[];
-extern char *(*const insn_outfun[]) ();
+extern const char *(*const insn_outfun[]) ();
extern const int insn_n_operands[];
@@ -106,7 +192,7 @@ extern const int insn_n_alternatives[];
and second by the operand number. Details in genoutput.c. */
#ifdef REGISTER_CONSTRAINTS /* Avoid undef sym in certain broken linkers. */
-extern char *const insn_operand_constraint[][MAX_RECOG_OPERANDS];
+extern const char *const insn_operand_constraint[][MAX_RECOG_OPERANDS];
#endif
#ifndef REGISTER_CONSTRAINTS /* Avoid undef sym in certain broken linkers. */
@@ -119,4 +205,4 @@ extern const char insn_operand_strict_low[][MAX_RECOG_OPERANDS];
extern int (*const insn_operand_predicate[][MAX_RECOG_OPERANDS]) ();
-extern char * insn_name[];
+extern const char * insn_name[];
diff --git a/gcc/reg-stack.c b/gcc/reg-stack.c
index 387ae8c6829..11a4f358209 100644
--- a/gcc/reg-stack.c
+++ b/gcc/reg-stack.c
@@ -1,5 +1,5 @@
/* Register to Stack convert for GNU compiler.
- Copyright (C) 1992, 93, 94, 95, 96, 97, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1992, 93-98, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -167,6 +167,7 @@ Boston, MA 02111-1307, USA. */
#include "hard-reg-set.h"
#include "flags.h"
#include "insn-flags.h"
+#include "recog.h"
#include "toplev.h"
#ifdef STACK_REGS
@@ -229,9 +230,23 @@ static rtx
/* Get the basic block number of an insn. See note at block_number
definition are validity of this information. */
-#define BLOCK_NUM(INSN) \
- ((INSN_UID (INSN) > max_uid) \
- ? (abort() , -1) : block_number[INSN_UID (INSN)])
+static int BLOCK_NUM PROTO((rtx));
+
+#ifdef __GNUC__
+__inline__
+#endif
+static int
+BLOCK_NUM(insn)
+ rtx insn;
+{
+ int tmp = INSN_UID (insn);
+ if (tmp > max_uid)
+ abort ();
+ tmp = block_number[tmp];
+ if (tmp < 0)
+ abort ();
+ return tmp;
+}
/* Forward declarations */
@@ -240,14 +255,11 @@ static void straighten_stack PROTO((rtx, stack));
static void pop_stack PROTO((stack, int));
static void record_label_references PROTO((rtx, rtx));
static rtx *get_true_reg PROTO((rtx *));
-static int constrain_asm_operands PROTO((int, rtx *, char **, int *,
- enum reg_class *));
-static void record_asm_reg_life PROTO((rtx,stack, rtx *, char **,
- int, int));
+static void record_asm_reg_life PROTO((rtx, stack));
static void record_reg_life_pat PROTO((rtx, HARD_REG_SET *,
HARD_REG_SET *, int));
-static void get_asm_operand_lengths PROTO((rtx, int, int *, int *));
+static int get_asm_operand_n_inputs PROTO((rtx));
static void record_reg_life PROTO((rtx, int, stack));
static void find_blocks PROTO((rtx));
static rtx stack_result PROTO((tree));
@@ -262,8 +274,7 @@ static void move_for_stack_reg PROTO((rtx, stack, rtx));
static void swap_rtx_condition PROTO((rtx));
static void compare_for_stack_reg PROTO((rtx, stack, rtx));
static void subst_stack_regs_pat PROTO((rtx, stack, rtx));
-static void subst_asm_stack_regs PROTO((rtx, stack, rtx *, rtx **,
- char **, int, int));
+static void subst_asm_stack_regs PROTO((rtx, stack));
static void subst_stack_regs PROTO((rtx, stack));
static void change_stack PROTO((rtx, stack, stack, rtx (*) ()));
@@ -504,6 +515,7 @@ reg_to_stack (first, file)
bzero ((char *) block_out_reg_set, blocks * sizeof (HARD_REG_SET));
block_number = (int *) alloca ((max_uid + 1) * sizeof (int));
+ memset (block_number, -1, (max_uid + 1) * sizeof (int));
find_blocks (first);
stack_reg_life_analysis (first, &stackentry);
@@ -606,297 +618,8 @@ get_true_reg (pat)
}
}
-/* Scan the OPERANDS and OPERAND_CONSTRAINTS of an asm_operands.
- N_OPERANDS is the total number of operands. Return which alternative
- matched, or -1 is no alternative matches.
-
- OPERAND_MATCHES is an array which indicates which operand this
- operand matches due to the constraints, or -1 if no match is required.
- If two operands match by coincidence, but are not required to match by
- the constraints, -1 is returned.
-
- OPERAND_CLASS is an array which indicates the smallest class
- required by the constraints. If the alternative that matches calls
- for some class `class', and the operand matches a subclass of `class',
- OPERAND_CLASS is set to `class' as required by the constraints, not to
- the subclass. If an alternative allows more than one class,
- OPERAND_CLASS is set to the smallest class that is a union of the
- allowed classes. */
-
-static int
-constrain_asm_operands (n_operands, operands, operand_constraints,
- operand_matches, operand_class)
- int n_operands;
- rtx *operands;
- char **operand_constraints;
- int *operand_matches;
- enum reg_class *operand_class;
-{
- char **constraints = (char **) alloca (n_operands * sizeof (char *));
- char *q;
- int this_alternative, this_operand;
- int n_alternatives;
- int j;
-
- for (j = 0; j < n_operands; j++)
- constraints[j] = operand_constraints[j];
-
- /* Compute the number of alternatives in the operands. reload has
- already guaranteed that all operands have the same number of
- alternatives. */
-
- if (n_operands == 0)
- n_alternatives = 0;
- else
- {
- n_alternatives = 1;
- for (q = constraints[0]; *q; q++)
- n_alternatives += (*q == ',');
- }
-
- this_alternative = 0;
- while (this_alternative < n_alternatives)
- {
- int lose = 0;
- int i;
-
- /* No operands match, no narrow class requirements yet. */
- for (i = 0; i < n_operands; i++)
- {
- operand_matches[i] = -1;
- operand_class[i] = NO_REGS;
- }
-
- for (this_operand = 0; this_operand < n_operands; this_operand++)
- {
- rtx op = operands[this_operand];
- enum machine_mode mode = GET_MODE (op);
- char *p = constraints[this_operand];
- int offset = 0;
- int win = 0;
- int c;
-
- if (GET_CODE (op) == SUBREG)
- {
- if (GET_CODE (SUBREG_REG (op)) == REG
- && REGNO (SUBREG_REG (op)) < FIRST_PSEUDO_REGISTER)
- offset = SUBREG_WORD (op);
- op = SUBREG_REG (op);
- }
-
- /* An empty constraint or empty alternative
- allows anything which matched the pattern. */
- if (*p == 0 || *p == ',')
- win = 1;
-
- while (*p && (c = *p++) != ',')
- switch (c)
- {
- case '=':
- case '+':
- case '?':
- case '&':
- case '!':
- case '*':
- case '%':
- /* Ignore these. */
- break;
-
- case '#':
- /* Ignore rest of this alternative. */
- while (*p && *p != ',') p++;
- break;
-
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- /* This operand must be the same as a previous one.
- This kind of constraint is used for instructions such
- as add when they take only two operands.
-
- Note that the lower-numbered operand is passed first. */
-
- if (operands_match_p (operands[c - '0'],
- operands[this_operand]))
- {
- operand_matches[this_operand] = c - '0';
- win = 1;
- }
- break;
-
- case 'p':
- /* p is used for address_operands. Since this is an asm,
- just to make sure that the operand is valid for Pmode. */
-
- if (strict_memory_address_p (Pmode, op))
- win = 1;
- break;
-
- case 'g':
- /* Anything goes unless it is a REG and really has a hard reg
- but the hard reg is not in the class GENERAL_REGS. */
- if (GENERAL_REGS == ALL_REGS
- || GET_CODE (op) != REG
- || reg_fits_class_p (op, GENERAL_REGS, offset, mode))
- {
- if (GET_CODE (op) == REG)
- operand_class[this_operand]
- = reg_class_subunion[(int) operand_class[this_operand]][(int) GENERAL_REGS];
- win = 1;
- }
- break;
-
- case 'r':
- if (GET_CODE (op) == REG
- && (GENERAL_REGS == ALL_REGS
- || reg_fits_class_p (op, GENERAL_REGS, offset, mode)))
- {
- operand_class[this_operand]
- = reg_class_subunion[(int) operand_class[this_operand]][(int) GENERAL_REGS];
- win = 1;
- }
- break;
-
- case 'X':
- /* This is used for a MATCH_SCRATCH in the cases when we
- don't actually need anything. So anything goes any time. */
- win = 1;
- break;
-
- case 'm':
- if (GET_CODE (op) == MEM)
- win = 1;
- break;
-
- case '<':
- if (GET_CODE (op) == MEM
- && (GET_CODE (XEXP (op, 0)) == PRE_DEC
- || GET_CODE (XEXP (op, 0)) == POST_DEC))
- win = 1;
- break;
-
- case '>':
- if (GET_CODE (op) == MEM
- && (GET_CODE (XEXP (op, 0)) == PRE_INC
- || GET_CODE (XEXP (op, 0)) == POST_INC))
- win = 1;
- break;
-
- case 'E':
- /* Match any CONST_DOUBLE, but only if
- we can examine the bits of it reliably. */
- if ((HOST_FLOAT_FORMAT != TARGET_FLOAT_FORMAT
- || HOST_BITS_PER_WIDE_INT != BITS_PER_WORD)
- && GET_CODE (op) != VOIDmode && ! flag_pretend_float)
- break;
- if (GET_CODE (op) == CONST_DOUBLE)
- win = 1;
- break;
-
- case 'F':
- if (GET_CODE (op) == CONST_DOUBLE)
- win = 1;
- break;
-
- case 'G':
- case 'H':
- if (GET_CODE (op) == CONST_DOUBLE
- && CONST_DOUBLE_OK_FOR_LETTER_P (op, c))
- win = 1;
- break;
-
- case 's':
- if (GET_CODE (op) == CONST_INT
- || (GET_CODE (op) == CONST_DOUBLE
- && GET_MODE (op) == VOIDmode))
- break;
- /* Fall through */
- case 'i':
- if (CONSTANT_P (op))
- win = 1;
- break;
-
- case 'n':
- if (GET_CODE (op) == CONST_INT
- || (GET_CODE (op) == CONST_DOUBLE
- && GET_MODE (op) == VOIDmode))
- win = 1;
- break;
-
- case 'I':
- case 'J':
- case 'K':
- case 'L':
- case 'M':
- case 'N':
- case 'O':
- case 'P':
- if (GET_CODE (op) == CONST_INT
- && CONST_OK_FOR_LETTER_P (INTVAL (op), c))
- win = 1;
- break;
-
-#ifdef EXTRA_CONSTRAINT
- case 'Q':
- case 'R':
- case 'S':
- case 'T':
- case 'U':
- if (EXTRA_CONSTRAINT (op, c))
- win = 1;
- break;
-#endif
-
- case 'V':
- if (GET_CODE (op) == MEM && ! offsettable_memref_p (op))
- win = 1;
- break;
-
- case 'o':
- if (offsettable_memref_p (op))
- win = 1;
- break;
-
- default:
- if (GET_CODE (op) == REG
- && reg_fits_class_p (op, REG_CLASS_FROM_LETTER (c),
- offset, mode))
- {
- operand_class[this_operand]
- = reg_class_subunion[(int)operand_class[this_operand]][(int) REG_CLASS_FROM_LETTER (c)];
- win = 1;
- }
- }
-
- constraints[this_operand] = p;
- /* If this operand did not win somehow,
- this alternative loses. */
- if (! win)
- lose = 1;
- }
- /* This alternative won; the operands are ok.
- Change whichever operands this alternative says to change. */
- if (! lose)
- break;
-
- this_alternative++;
- }
-
- /* For operands constrained to match another operand, copy the other
- operand's class to this operand's class. */
- for (j = 0; j < n_operands; j++)
- if (operand_matches[j] >= 0)
- operand_class[j] = operand_class[operand_matches[j]];
-
- return this_alternative == n_alternatives ? -1 : this_alternative;
-}
-
/* Record the life info of each stack reg in INSN, updating REGSTACK.
- N_INPUTS is the number of inputs; N_OUTPUTS the outputs. CONSTRAINTS
- is an array of the constraint strings used in the asm statement.
+ N_INPUTS is the number of inputs; N_OUTPUTS the outputs.
OPERANDS is an array of all operands for the insn, and is assumed to
contain all output operands, then all inputs operands.
@@ -905,43 +628,47 @@ constrain_asm_operands (n_operands, operands, operand_constraints,
numbers below refer to that explanation. */
static void
-record_asm_reg_life (insn, regstack, operands, constraints,
- n_inputs, n_outputs)
+record_asm_reg_life (insn, regstack)
rtx insn;
stack regstack;
- rtx *operands;
- char **constraints;
- int n_inputs, n_outputs;
{
int i;
- int n_operands = n_inputs + n_outputs;
- int first_input = n_outputs;
int n_clobbers;
int malformed_asm = 0;
rtx body = PATTERN (insn);
- int *operand_matches = (int *) alloca (n_operands * sizeof (int *));
-
- enum reg_class *operand_class
- = (enum reg_class *) alloca (n_operands * sizeof (enum reg_class *));
-
int reg_used_as_output[FIRST_PSEUDO_REGISTER];
int implicitly_dies[FIRST_PSEUDO_REGISTER];
+ int alt;
rtx *clobber_reg;
+ int n_inputs, n_outputs;
/* Find out what the constraints require. If no constraint
alternative matches, this asm is malformed. */
- i = constrain_asm_operands (n_operands, operands, constraints,
- operand_matches, operand_class);
- if (i < 0)
- malformed_asm = 1;
+ extract_insn (insn);
+ constrain_operands (1);
+ alt = which_alternative;
+
+ preprocess_constraints ();
+
+ n_inputs = get_asm_operand_n_inputs (body);
+ n_outputs = recog_n_operands - n_inputs;
+
+ if (alt < 0)
+ {
+ malformed_asm = 1;
+ /* Avoid further trouble with this insn. */
+ PATTERN (insn) = gen_rtx_USE (VOIDmode, const0_rtx);
+ PUT_MODE (insn, VOIDmode);
+ return;
+ }
/* Strip SUBREGs here to make the following code simpler. */
- for (i = 0; i < n_operands; i++)
- if (GET_CODE (operands[i]) == SUBREG
- && GET_CODE (SUBREG_REG (operands[i])) == REG)
- operands[i] = SUBREG_REG (operands[i]);
+ for (i = 0; i < recog_n_operands; i++)
+ if (GET_CODE (recog_operand[i]) == SUBREG
+ && GET_CODE (SUBREG_REG (recog_operand[i])) == REG)
+ recog_operand[i] = SUBREG_REG (recog_operand[i]);
/* Set up CLOBBER_REG. */
@@ -949,7 +676,7 @@ record_asm_reg_life (insn, regstack, operands, constraints,
if (GET_CODE (body) == PARALLEL)
{
- clobber_reg = (rtx *) alloca (XVECLEN (body, 0) * sizeof (rtx *));
+ clobber_reg = (rtx *) alloca (XVECLEN (body, 0) * sizeof (rtx));
for (i = 0; i < XVECLEN (body, 0); i++)
if (GET_CODE (XVECEXP (body, 0, i)) == CLOBBER)
@@ -977,15 +704,15 @@ record_asm_reg_life (insn, regstack, operands, constraints,
bzero ((char *) reg_used_as_output, sizeof (reg_used_as_output));
for (i = 0; i < n_outputs; i++)
- if (STACK_REG_P (operands[i]))
+ if (STACK_REG_P (recog_operand[i]))
{
- if (reg_class_size[(int) operand_class[i]] != 1)
+ if (reg_class_size[(int) recog_op_alt[i][alt].class] != 1)
{
error_for_asm (insn, "Output constraint %d must specify a single register", i);
malformed_asm = 1;
}
else
- reg_used_as_output[REGNO (operands[i])] = 1;
+ reg_used_as_output[REGNO (recog_operand[i])] = 1;
}
@@ -1010,19 +737,19 @@ record_asm_reg_life (insn, regstack, operands, constraints,
popped. */
bzero ((char *) implicitly_dies, sizeof (implicitly_dies));
- for (i = first_input; i < first_input + n_inputs; i++)
- if (STACK_REG_P (operands[i]))
+ for (i = n_outputs; i < n_outputs + n_inputs; i++)
+ if (STACK_REG_P (recog_operand[i]))
{
/* An input reg is implicitly popped if it is tied to an
output, or if there is a CLOBBER for it. */
int j;
for (j = 0; j < n_clobbers; j++)
- if (operands_match_p (clobber_reg[j], operands[i]))
+ if (operands_match_p (clobber_reg[j], recog_operand[i]))
break;
- if (j < n_clobbers || operand_matches[i] >= 0)
- implicitly_dies[REGNO (operands[i])] = 1;
+ if (j < n_clobbers || recog_op_alt[i][alt].matches >= 0)
+ implicitly_dies[REGNO (recog_operand[i])] = 1;
}
/* Search for first non-popped reg. */
@@ -1048,13 +775,13 @@ record_asm_reg_life (insn, regstack, operands, constraints,
??? Detect this more deterministically by having constraint_asm_operands
record any earlyclobber. */
- for (i = first_input; i < first_input + n_inputs; i++)
- if (operand_matches[i] == -1)
+ for (i = n_outputs; i < n_outputs + n_inputs; i++)
+ if (recog_op_alt[i][alt].matches == -1)
{
int j;
for (j = 0; j < n_outputs; j++)
- if (operands_match_p (operands[j], operands[i]))
+ if (operands_match_p (recog_operand[j], recog_operand[i]))
{
error_for_asm (insn,
"Output operand %d must use `&' constraint", j);
@@ -1073,7 +800,7 @@ record_asm_reg_life (insn, regstack, operands, constraints,
/* Process all outputs */
for (i = 0; i < n_outputs; i++)
{
- rtx op = operands[i];
+ rtx op = recog_operand[i];
if (! STACK_REG_P (op))
{
@@ -1095,11 +822,12 @@ record_asm_reg_life (insn, regstack, operands, constraints,
}
/* Process all inputs */
- for (i = first_input; i < first_input + n_inputs; i++)
+ for (i = n_outputs; i < n_outputs + n_inputs; i++)
{
- if (! STACK_REG_P (operands[i]))
+ rtx op = recog_operand[i];
+ if (! STACK_REG_P (op))
{
- if (stack_regs_mentioned_p (operands[i]))
+ if (stack_regs_mentioned_p (op))
abort ();
else
continue;
@@ -1109,13 +837,12 @@ record_asm_reg_life (insn, regstack, operands, constraints,
But don't record a death note if there is already a death note,
or if the input is also an output. */
- if (! TEST_HARD_REG_BIT (regstack->reg_set, REGNO (operands[i]))
- && operand_matches[i] == -1
- && find_regno_note (insn, REG_DEAD, REGNO (operands[i])) == NULL_RTX)
- REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_DEAD, operands[i],
- REG_NOTES (insn));
+ if (! TEST_HARD_REG_BIT (regstack->reg_set, REGNO (op))
+ && recog_op_alt[i][alt].matches == -1
+ && find_regno_note (insn, REG_DEAD, REGNO (op)) == NULL_RTX)
+ REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_DEAD, op, REG_NOTES (insn));
- SET_HARD_REG_BIT (regstack->reg_set, REGNO (operands[i]));
+ SET_HARD_REG_BIT (regstack->reg_set, REGNO (op));
}
}
@@ -1177,29 +904,25 @@ record_reg_life_pat (pat, src, dest, douse)
N_INPUTS and N_OUTPUTS are pointers to ints into which the results are
placed. */
-static void
-get_asm_operand_lengths (body, n_operands, n_inputs, n_outputs)
+static int
+get_asm_operand_n_inputs (body)
rtx body;
- int n_operands;
- int *n_inputs, *n_outputs;
{
if (GET_CODE (body) == SET && GET_CODE (SET_SRC (body)) == ASM_OPERANDS)
- *n_inputs = ASM_OPERANDS_INPUT_LENGTH (SET_SRC (body));
+ return ASM_OPERANDS_INPUT_LENGTH (SET_SRC (body));
else if (GET_CODE (body) == ASM_OPERANDS)
- *n_inputs = ASM_OPERANDS_INPUT_LENGTH (body);
+ return ASM_OPERANDS_INPUT_LENGTH (body);
else if (GET_CODE (body) == PARALLEL
&& GET_CODE (XVECEXP (body, 0, 0)) == SET)
- *n_inputs = ASM_OPERANDS_INPUT_LENGTH (SET_SRC (XVECEXP (body, 0, 0)));
+ return ASM_OPERANDS_INPUT_LENGTH (SET_SRC (XVECEXP (body, 0, 0)));
else if (GET_CODE (body) == PARALLEL
&& GET_CODE (XVECEXP (body, 0, 0)) == ASM_OPERANDS)
- *n_inputs = ASM_OPERANDS_INPUT_LENGTH (XVECEXP (body, 0, 0));
- else
- abort ();
+ return ASM_OPERANDS_INPUT_LENGTH (XVECEXP (body, 0, 0));
- *n_outputs = n_operands - *n_inputs;
+ abort ();
}
/* Scan INSN, which is in BLOCK, and record the life & death of stack
@@ -1243,18 +966,7 @@ record_reg_life (insn, block, regstack)
n_operands = asm_noperands (PATTERN (insn));
if (n_operands >= 0)
{
- /* This insn is an `asm' with operands. Decode the operands,
- decide how many are inputs, and record the life information. */
-
- rtx operands[MAX_RECOG_OPERANDS];
- rtx body = PATTERN (insn);
- int n_inputs, n_outputs;
- char **constraints = (char **) alloca (n_operands * sizeof (char *));
-
- decode_asm_operands (body, operands, NULL_PTR, constraints, NULL_PTR);
- get_asm_operand_lengths (body, n_operands, &n_inputs, &n_outputs);
- record_asm_reg_life (insn, regstack, operands, constraints,
- n_inputs, n_outputs);
+ record_asm_reg_life (insn, regstack);
return;
}
@@ -1486,7 +1198,7 @@ stack_reg_life_analysis (first, stackentry)
for (block = blocks - 1; --block >= 0;)
if (GET_CODE (block_end[block]) == JUMP_INSN
- && GET_CODE (PATTERN (block_end[block])) == RETURN)
+ && returnjump_p (block_end[block]))
mark_regs_pat (retvalue, block_out_reg_set+block);
/* Mark off the end of last block if we "fall off" the end of the
@@ -2348,6 +2060,10 @@ subst_stack_regs_pat (insn, regstack, pat)
break;
case IF_THEN_ELSE:
+ /* dest has to be on stack. */
+ if (get_hard_regnum (regstack, *dest) < FIRST_STACK_REG)
+ abort ();
+
/* This insn requires the top of stack to be the destination. */
/* If the comparison operator is an FP comparison operator,
@@ -2401,9 +2117,7 @@ subst_stack_regs_pat (insn, regstack, pat)
}
}
- /* Make dest the top of stack. Add dest to regstack if not present. */
- if (get_hard_regnum (regstack, *dest) < FIRST_STACK_REG)
- regstack->reg[++regstack->top] = REGNO (*dest);
+ /* Make dest the top of stack. */
SET_HARD_REG_BIT (regstack->reg_set, REGNO (*dest));
replace_reg (dest, FIRST_STACK_REG);
@@ -2416,12 +2130,7 @@ subst_stack_regs_pat (insn, regstack, pat)
/* Substitute hard regnums for any stack regs in INSN, which has
N_INPUTS inputs and N_OUTPUTS outputs. REGSTACK is the stack info
- before the insn, and is updated with changes made here. CONSTRAINTS is
- an array of the constraint strings used in the asm statement.
-
- OPERANDS is an array of the operands, and OPERANDS_LOC is a
- parallel array of where the operands were found. The output operands
- all precede the input operands.
+ before the insn, and is updated with changes made here.
There are several requirements and assumptions about the use of
stack-like regs in asm statements. These rules are enforced by
@@ -2430,21 +2139,12 @@ subst_stack_regs_pat (insn, regstack, pat)
requirements, since record_asm_stack_regs removes any problem asm. */
static void
-subst_asm_stack_regs (insn, regstack, operands, operands_loc, constraints,
- n_inputs, n_outputs)
+subst_asm_stack_regs (insn, regstack)
rtx insn;
stack regstack;
- rtx *operands, **operands_loc;
- char **constraints;
- int n_inputs, n_outputs;
{
- int n_operands = n_inputs + n_outputs;
- int first_input = n_outputs;
rtx body = PATTERN (insn);
-
- int *operand_matches = (int *) alloca (n_operands * sizeof (int *));
- enum reg_class *operand_class
- = (enum reg_class *) alloca (n_operands * sizeof (enum reg_class *));
+ int alt;
rtx *note_reg; /* Array of note contents */
rtx **note_loc; /* Address of REG field of each note */
@@ -2458,24 +2158,31 @@ subst_asm_stack_regs (insn, regstack, operands, operands_loc, constraints,
int n_clobbers;
rtx note;
int i;
+ int n_inputs, n_outputs;
/* Find out what the constraints required. If no constraint
alternative matches, that is a compiler bug: we should have caught
such an insn during the life analysis pass (and reload should have
caught it regardless). */
+ extract_insn (insn);
+ constrain_operands (1);
+ alt = which_alternative;
- i = constrain_asm_operands (n_operands, operands, constraints,
- operand_matches, operand_class);
- if (i < 0)
+ preprocess_constraints ();
+
+ n_inputs = get_asm_operand_n_inputs (body);
+ n_outputs = recog_n_operands - n_inputs;
+
+ if (alt < 0)
abort ();
/* Strip SUBREGs here to make the following code simpler. */
- for (i = 0; i < n_operands; i++)
- if (GET_CODE (operands[i]) == SUBREG
- && GET_CODE (SUBREG_REG (operands[i])) == REG)
+ for (i = 0; i < recog_n_operands; i++)
+ if (GET_CODE (recog_operand[i]) == SUBREG
+ && GET_CODE (SUBREG_REG (recog_operand[i])) == REG)
{
- operands_loc[i] = & SUBREG_REG (operands[i]);
- operands[i] = SUBREG_REG (operands[i]);
+ recog_operand_loc[i] = & SUBREG_REG (recog_operand[i]);
+ recog_operand[i] = SUBREG_REG (recog_operand[i]);
}
/* Set up NOTE_REG, NOTE_LOC and NOTE_KIND. */
@@ -2516,8 +2223,8 @@ subst_asm_stack_regs (insn, regstack, operands, operands_loc, constraints,
if (GET_CODE (body) == PARALLEL)
{
- clobber_reg = (rtx *) alloca (XVECLEN (body, 0) * sizeof (rtx *));
- clobber_loc = (rtx **) alloca (XVECLEN (body, 0) * sizeof (rtx **));
+ clobber_reg = (rtx *) alloca (XVECLEN (body, 0) * sizeof (rtx));
+ clobber_loc = (rtx **) alloca (XVECLEN (body, 0) * sizeof (rtx *));
for (i = 0; i < XVECLEN (body, 0); i++)
if (GET_CODE (XVECEXP (body, 0, i)) == CLOBBER)
@@ -2545,34 +2252,35 @@ subst_asm_stack_regs (insn, regstack, operands, operands_loc, constraints,
/* Put the input regs into the desired place in TEMP_STACK. */
- for (i = first_input; i < first_input + n_inputs; i++)
- if (STACK_REG_P (operands[i])
- && reg_class_subset_p (operand_class[i], FLOAT_REGS)
- && operand_class[i] != FLOAT_REGS)
+ for (i = n_outputs; i < n_outputs + n_inputs; i++)
+ if (STACK_REG_P (recog_operand[i])
+ && reg_class_subset_p (recog_op_alt[i][alt].class,
+ FLOAT_REGS)
+ && recog_op_alt[i][alt].class != FLOAT_REGS)
{
/* If an operand needs to be in a particular reg in
FLOAT_REGS, the constraint was either 't' or 'u'. Since
these constraints are for single register classes, and reload
guaranteed that operand[i] is already in that class, we can
- just use REGNO (operands[i]) to know which actual reg this
+ just use REGNO (recog_operand[i]) to know which actual reg this
operand needs to be in. */
- int regno = get_hard_regnum (&temp_stack, operands[i]);
+ int regno = get_hard_regnum (&temp_stack, recog_operand[i]);
if (regno < 0)
abort ();
- if (regno != REGNO (operands[i]))
+ if (regno != REGNO (recog_operand[i]))
{
- /* operands[i] is not in the right place. Find it
+ /* recog_operand[i] is not in the right place. Find it
and swap it with whatever is already in I's place.
- K is where operands[i] is now. J is where it should
+ K is where recog_operand[i] is now. J is where it should
be. */
int j, k, temp;
k = temp_stack.top - (regno - FIRST_STACK_REG);
j = (temp_stack.top
- - (REGNO (operands[i]) - FIRST_STACK_REG));
+ - (REGNO (recog_operand[i]) - FIRST_STACK_REG));
temp = temp_stack.reg[k];
temp_stack.reg[k] = temp_stack.reg[j];
@@ -2588,15 +2296,15 @@ subst_asm_stack_regs (insn, regstack, operands, operands_loc, constraints,
/* Make the needed input register substitutions. Do death notes and
clobbers too, because these are for inputs, not outputs. */
- for (i = first_input; i < first_input + n_inputs; i++)
- if (STACK_REG_P (operands[i]))
+ for (i = n_outputs; i < n_outputs + n_inputs; i++)
+ if (STACK_REG_P (recog_operand[i]))
{
- int regnum = get_hard_regnum (regstack, operands[i]);
+ int regnum = get_hard_regnum (regstack, recog_operand[i]);
if (regnum < 0)
abort ();
- replace_reg (operands_loc[i], regnum);
+ replace_reg (recog_operand_loc[i], regnum);
}
for (i = 0; i < n_notes; i++)
@@ -2628,21 +2336,21 @@ subst_asm_stack_regs (insn, regstack, operands, operands_loc, constraints,
/* Now remove from REGSTACK any inputs that the asm implicitly popped. */
- for (i = first_input; i < first_input + n_inputs; i++)
- if (STACK_REG_P (operands[i]))
+ for (i = n_outputs; i < n_outputs + n_inputs; i++)
+ if (STACK_REG_P (recog_operand[i]))
{
/* An input reg is implicitly popped if it is tied to an
output, or if there is a CLOBBER for it. */
int j;
for (j = 0; j < n_clobbers; j++)
- if (operands_match_p (clobber_reg[j], operands[i]))
+ if (operands_match_p (clobber_reg[j], recog_operand[i]))
break;
- if (j < n_clobbers || operand_matches[i] >= 0)
+ if (j < n_clobbers || recog_op_alt[i][alt].matches >= 0)
{
- /* operands[i] might not be at the top of stack. But that's OK,
- because all we need to do is pop the right number of regs
+ /* recog_operand[i] might not be at the top of stack. But that's
+ OK, because all we need to do is pop the right number of regs
off of the top of the reg-stack. record_asm_stack_regs
guaranteed that all implicitly popped regs were grouped
at the top of the reg-stack. */
@@ -2663,7 +2371,7 @@ subst_asm_stack_regs (insn, regstack, operands, operands_loc, constraints,
int j;
for (j = 0; j < n_outputs; j++)
- if (STACK_REG_P (operands[j]) && REGNO (operands[j]) == i)
+ if (STACK_REG_P (recog_operand[j]) && REGNO (recog_operand[j]) == i)
{
regstack->reg[++regstack->top] = i;
SET_HARD_REG_BIT (regstack->reg_set, i);
@@ -2679,31 +2387,32 @@ subst_asm_stack_regs (insn, regstack, operands, operands_loc, constraints,
in the death notes have already been substituted. */
for (i = 0; i < n_outputs; i++)
- if (STACK_REG_P (operands[i]))
+ if (STACK_REG_P (recog_operand[i]))
{
int j;
for (j = 0; j < n_notes; j++)
- if (REGNO (operands[i]) == REGNO (note_reg[j])
+ if (REGNO (recog_operand[i]) == REGNO (note_reg[j])
&& note_kind[j] == REG_UNUSED)
{
- insn = emit_pop_insn (insn, regstack, operands[i],
+ insn = emit_pop_insn (insn, regstack, recog_operand[i],
emit_insn_after);
break;
}
}
- for (i = first_input; i < first_input + n_inputs; i++)
- if (STACK_REG_P (operands[i]))
+ for (i = n_outputs; i < n_outputs + n_inputs; i++)
+ if (STACK_REG_P (recog_operand[i]))
{
int j;
for (j = 0; j < n_notes; j++)
- if (REGNO (operands[i]) == REGNO (note_reg[j])
+ if (REGNO (recog_operand[i]) == REGNO (note_reg[j])
&& note_kind[j] == REG_DEAD
- && TEST_HARD_REG_BIT (regstack->reg_set, REGNO (operands[i])))
+ && TEST_HARD_REG_BIT (regstack->reg_set,
+ REGNO (recog_operand[i])))
{
- insn = emit_pop_insn (insn, regstack, operands[i],
+ insn = emit_pop_insn (insn, regstack, recog_operand[i],
emit_insn_after);
break;
}
@@ -2722,7 +2431,6 @@ subst_stack_regs (insn, regstack)
{
register rtx *note_link, note;
register int i;
- int n_operands;
if (GET_CODE (insn) == CALL_INSN)
{
@@ -2754,25 +2462,14 @@ subst_stack_regs (insn, regstack)
if (GET_MODE (insn) == QImode)
{
- n_operands = asm_noperands (PATTERN (insn));
+ int n_operands = asm_noperands (PATTERN (insn));
if (n_operands >= 0)
{
/* This insn is an `asm' with operands. Decode the operands,
decide how many are inputs, and do register substitution.
Any REG_UNUSED notes will be handled by subst_asm_stack_regs. */
- rtx operands[MAX_RECOG_OPERANDS];
- rtx *operands_loc[MAX_RECOG_OPERANDS];
- rtx body = PATTERN (insn);
- int n_inputs, n_outputs;
- char **constraints
- = (char **) alloca (n_operands * sizeof (char *));
-
- decode_asm_operands (body, operands, operands_loc,
- constraints, NULL_PTR);
- get_asm_operand_lengths (body, n_operands, &n_inputs, &n_outputs);
- subst_asm_stack_regs (insn, regstack, operands, operands_loc,
- constraints, n_inputs, n_outputs);
+ subst_asm_stack_regs (insn, regstack);
return;
}
diff --git a/gcc/regclass.c b/gcc/regclass.c
index 03872ac4dba..d43fe5057c9 100644
--- a/gcc/regclass.c
+++ b/gcc/regclass.c
@@ -1,5 +1,5 @@
/* Compute register class preferences for pseudo-registers.
- Copyright (C) 1987, 88, 91-97, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1987, 88, 91-98, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -42,6 +42,9 @@ Boston, MA 02111-1307, USA. */
#define REGISTER_MOVE_COST(x, y) 2
#endif
+static void init_reg_sets_1 PROTO((void));
+static void init_reg_modes PROTO((void));
+
/* If we have auto-increment or auto-decrement and we can have secondary
reloads, we are not allowed to use classes requiring secondary
reloads for pseudos auto-incremented since reload can't handle it. */
@@ -234,6 +237,25 @@ init_reg_sets ()
bcopy (initial_call_used_regs, call_used_regs, sizeof call_used_regs);
bzero (global_regs, sizeof global_regs);
+ /* Do any additional initialization regsets may need */
+ INIT_ONCE_REG_SET ();
+}
+
+/* After switches have been processed, which perhaps alter
+ `fixed_regs' and `call_used_regs', convert them to HARD_REG_SETs. */
+
+static void
+init_reg_sets_1 ()
+{
+ register unsigned int i, j;
+
+ /* This macro allows the fixed or call-used registers
+ and the register classes to depend on target flags. */
+
+#ifdef CONDITIONAL_REGISTER_USAGE
+ CONDITIONAL_REGISTER_USAGE;
+#endif
+
/* Compute number of hard regs in each class. */
bzero ((char *) reg_class_size, sizeof reg_class_size);
@@ -337,25 +359,6 @@ init_reg_sets ()
}
}
- /* Do any additional initialization regsets may need */
- INIT_ONCE_REG_SET ();
-}
-
-/* After switches have been processed, which perhaps alter
- `fixed_regs' and `call_used_regs', convert them to HARD_REG_SETs. */
-
-static void
-init_reg_sets_1 ()
-{
- register unsigned int i, j;
-
- /* This macro allows the fixed or call-used registers
- to depend on target flags. */
-
-#ifdef CONDITIONAL_REGISTER_USAGE
- CONDITIONAL_REGISTER_USAGE;
-#endif
-
/* Initialize "constant" tables. */
CLEAR_HARD_REG_SET (fixed_reg_set);
@@ -575,8 +578,27 @@ fix_register (name, fixed, call_used)
if ((i = decode_reg_name (name)) >= 0)
{
- fixed_regs[i] = fixed;
- call_used_regs[i] = call_used;
+ if ((i == STACK_POINTER_REGNUM
+#ifdef HARD_FRAME_POINTER_REGNUM
+ || i == HARD_FRAME_POINTER_REGNUM
+#else
+ || i == FRAME_POINTER_REGNUM
+#endif
+ )
+ && (fixed == 0 || call_used == 0))
+ {
+ static char* what_option[2][2] = {
+ { "call-saved", "call-used" },
+ { "no-such-option", "fixed" }};
+
+ error ("can't use '%s' as a %s register", name,
+ what_option[fixed][call_used]);
+ }
+ else
+ {
+ fixed_regs[i] = fixed;
+ call_used_regs[i] = call_used;
+ }
}
else
{
@@ -630,6 +652,10 @@ struct costs
static struct costs *costs;
+/* Initialized once, and used to initialize cost values for each insn. */
+
+static struct costs init_cost;
+
/* Record the same data by operand number, accumulated for each alternative
in an insn. The contribution to a pseudo is that of the minimum-cost
alternative. */
@@ -666,8 +692,9 @@ static int loop_depth;
static int loop_cost;
+static rtx scan_one_insn PROTO((rtx, int));
static void record_reg_classes PROTO((int, int, rtx *, enum machine_mode *,
- char **, rtx));
+ const char **, rtx));
static int copy_cost PROTO((rtx, enum machine_mode,
enum reg_class, int));
static void record_address_regs PROTO((rtx, enum reg_class, int));
@@ -699,15 +726,216 @@ reg_alternate_class (regno)
return (enum reg_class) altclass[regno];
}
-/* This prevents dump_flow_info from losing if called
- before regclass is run. */
+/* Initialize some global data for this pass. */
void
regclass_init ()
{
+ int i;
+
+ init_cost.mem_cost = 10000;
+ for (i = 0; i < N_REG_CLASSES; i++)
+ init_cost.cost[i] = 10000;
+
+ /* This prevents dump_flow_info from losing if called
+ before regclass is run. */
prefclass = 0;
}
+/* Subroutine of regclass, processes one insn INSN. Scan it and record each
+ time it would save code to put a certain register in a certain class.
+ PASS, when nonzero, inhibits some optimizations which need only be done
+ once.
+ Return the last insn processed, so that the scan can be continued from
+ there. */
+
+static rtx
+scan_one_insn (insn, pass)
+ rtx insn;
+ int pass;
+{
+ enum rtx_code code = GET_CODE (insn);
+ enum rtx_code pat_code;
+ const char *constraints[MAX_RECOG_OPERANDS];
+ enum machine_mode modes[MAX_RECOG_OPERANDS];
+ rtx set, note;
+ int i, j;
+
+ /* Show that an insn inside a loop is likely to be executed three
+ times more than insns outside a loop. This is much more aggressive
+ than the assumptions made elsewhere and is being tried as an
+ experiment. */
+
+ if (code == NOTE)
+ {
+ if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_BEG)
+ loop_depth++, loop_cost = 1 << (2 * MIN (loop_depth, 5));
+ else if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_END)
+ loop_depth--, loop_cost = 1 << (2 * MIN (loop_depth, 5));
+
+ return insn;
+ }
+
+ if (GET_RTX_CLASS (code) != 'i')
+ return insn;
+
+ pat_code = GET_CODE (PATTERN (insn));
+ if (pat_code == USE
+ || pat_code == CLOBBER
+ || pat_code == ASM_INPUT
+ || pat_code == ADDR_VEC
+ || pat_code == ADDR_DIFF_VEC)
+ return insn;
+
+ set = single_set (insn);
+ extract_insn (insn);
+
+ for (i = 0; i < recog_n_operands; i++)
+ {
+ constraints[i] = recog_constraints[i];
+ modes[i] = recog_operand_mode[i];
+ }
+
+ /* If this insn loads a parameter from its stack slot, then
+ it represents a savings, rather than a cost, if the
+ parameter is stored in memory. Record this fact. */
+
+ if (set != 0 && GET_CODE (SET_DEST (set)) == REG
+ && GET_CODE (SET_SRC (set)) == MEM
+ && (note = find_reg_note (insn, REG_EQUIV,
+ NULL_RTX)) != 0
+ && GET_CODE (XEXP (note, 0)) == MEM)
+ {
+ costs[REGNO (SET_DEST (set))].mem_cost
+ -= (MEMORY_MOVE_COST (GET_MODE (SET_DEST (set)),
+ GENERAL_REGS, 1)
+ * loop_cost);
+ record_address_regs (XEXP (SET_SRC (set), 0),
+ BASE_REG_CLASS, loop_cost * 2);
+ return insn;
+ }
+
+ /* Improve handling of two-address insns such as
+ (set X (ashift CONST Y)) where CONST must be made to
+ match X. Change it into two insns: (set X CONST)
+ (set X (ashift X Y)). If we left this for reloading, it
+ would probably get three insns because X and Y might go
+ in the same place. This prevents X and Y from receiving
+ the same hard reg.
+
+ We can only do this if the modes of operands 0 and 1
+ (which might not be the same) are tieable and we only need
+ do this during our first pass. */
+
+ if (pass == 0 && optimize
+ && recog_n_operands >= 3
+ && recog_constraints[1][0] == '0'
+ && recog_constraints[1][1] == 0
+ && CONSTANT_P (recog_operand[1])
+ && ! rtx_equal_p (recog_operand[0], recog_operand[1])
+ && ! rtx_equal_p (recog_operand[0], recog_operand[2])
+ && GET_CODE (recog_operand[0]) == REG
+ && MODES_TIEABLE_P (GET_MODE (recog_operand[0]),
+ recog_operand_mode[1]))
+ {
+ rtx previnsn = prev_real_insn (insn);
+ rtx dest
+ = gen_lowpart (recog_operand_mode[1],
+ recog_operand[0]);
+ rtx newinsn
+ = emit_insn_before (gen_move_insn (dest,
+ recog_operand[1]),
+ insn);
+
+ /* If this insn was the start of a basic block,
+ include the new insn in that block.
+ We need not check for code_label here;
+ while a basic block can start with a code_label,
+ INSN could not be at the beginning of that block. */
+ if (previnsn == 0 || GET_CODE (previnsn) == JUMP_INSN)
+ {
+ int b;
+ for (b = 0; b < n_basic_blocks; b++)
+ if (insn == BLOCK_HEAD (b))
+ BLOCK_HEAD (b) = newinsn;
+ }
+
+ /* This makes one more setting of new insns's dest. */
+ REG_N_SETS (REGNO (recog_operand[0]))++;
+
+ *recog_operand_loc[1] = recog_operand[0];
+ for (i = recog_n_dups - 1; i >= 0; i--)
+ if (recog_dup_num[i] == 1)
+ *recog_dup_loc[i] = recog_operand[0];
+
+ return PREV_INSN (newinsn);
+ }
+
+ /* If we get here, we are set up to record the costs of all the
+ operands for this insn. Start by initializing the costs.
+ Then handle any address registers. Finally record the desired
+ classes for any pseudos, doing it twice if some pair of
+ operands are commutative. */
+
+ for (i = 0; i < recog_n_operands; i++)
+ {
+ op_costs[i] = init_cost;
+
+ if (GET_CODE (recog_operand[i]) == SUBREG)
+ recog_operand[i] = SUBREG_REG (recog_operand[i]);
+
+ if (GET_CODE (recog_operand[i]) == MEM)
+ record_address_regs (XEXP (recog_operand[i], 0),
+ BASE_REG_CLASS, loop_cost * 2);
+ else if (constraints[i][0] == 'p')
+ record_address_regs (recog_operand[i],
+ BASE_REG_CLASS, loop_cost * 2);
+ }
+
+ /* Check for commutative in a separate loop so everything will
+ have been initialized. We must do this even if one operand
+ is a constant--see addsi3 in m68k.md. */
+
+ for (i = 0; i < recog_n_operands - 1; i++)
+ if (constraints[i][0] == '%')
+ {
+ const char *xconstraints[MAX_RECOG_OPERANDS];
+ int j;
+
+ /* Handle commutative operands by swapping the constraints.
+ We assume the modes are the same. */
+
+ for (j = 0; j < recog_n_operands; j++)
+ xconstraints[j] = constraints[j];
+
+ xconstraints[i] = constraints[i+1];
+ xconstraints[i+1] = constraints[i];
+ record_reg_classes (recog_n_alternatives, recog_n_operands,
+ recog_operand, modes, xconstraints,
+ insn);
+ }
+
+ record_reg_classes (recog_n_alternatives, recog_n_operands, recog_operand,
+ modes, constraints, insn);
+
+ /* Now add the cost for each operand to the total costs for
+ its register. */
+
+ for (i = 0; i < recog_n_operands; i++)
+ if (GET_CODE (recog_operand[i]) == REG
+ && REGNO (recog_operand[i]) >= FIRST_PSEUDO_REGISTER)
+ {
+ int regno = REGNO (recog_operand[i]);
+ struct costs *p = &costs[regno], *q = &op_costs[i];
+
+ p->mem_cost += q->mem_cost * loop_cost;
+ for (j = 0; j < N_REG_CLASSES; j++)
+ p->cost[j] += q->cost[j] * loop_cost;
+ }
+
+ return insn;
+}
+
/* This is a pass of the compiler that scans all instructions
and calculates the preferred class for each pseudo-register.
This information can be accessed later by calling `reg_preferred_class'.
@@ -720,9 +948,7 @@ regclass (f, nregs)
{
#ifdef REGISTER_CONSTRAINTS
register rtx insn;
- register int i, j;
- struct costs init_cost;
- rtx set;
+ register int i;
int pass;
init_recog ();
@@ -742,6 +968,7 @@ regclass (f, nregs)
{
rtx r = gen_rtx_REG (VOIDmode, 0);
enum machine_mode m;
+ register int j;
for (j = 0; j < FIRST_PSEUDO_REGISTER; j++)
if (TEST_HARD_REG_BIT (reg_class_contents[i], j))
@@ -781,10 +1008,6 @@ regclass (f, nregs)
}
#endif /* FORBIDDEN_INC_DEC_CLASSES */
- init_cost.mem_cost = 10000;
- for (i = 0; i < N_REG_CLASSES; i++)
- init_cost.cost[i] = 10000;
-
/* Normally we scan the insns once and determine the best class to use for
each register. However, if -fexpensive_optimizations are on, we do so
twice, the second time using the tentative best classes to guide the
@@ -807,199 +1030,9 @@ regclass (f, nregs)
for (insn = f; insn; insn = NEXT_INSN (insn))
{
- char *constraints[MAX_RECOG_OPERANDS];
- enum machine_mode modes[MAX_RECOG_OPERANDS];
- int nalternatives;
- int noperands;
-
- /* Show that an insn inside a loop is likely to be executed three
- times more than insns outside a loop. This is much more aggressive
- than the assumptions made elsewhere and is being tried as an
- experiment. */
-
- if (GET_CODE (insn) == NOTE
- && NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_BEG)
- loop_depth++, loop_cost = 1 << (2 * MIN (loop_depth, 5));
- else if (GET_CODE (insn) == NOTE
- && NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_END)
- loop_depth--, loop_cost = 1 << (2 * MIN (loop_depth, 5));
-
- else if ((GET_CODE (insn) == INSN
- && GET_CODE (PATTERN (insn)) != USE
- && GET_CODE (PATTERN (insn)) != CLOBBER
- && GET_CODE (PATTERN (insn)) != ASM_INPUT)
- || (GET_CODE (insn) == JUMP_INSN
- && GET_CODE (PATTERN (insn)) != ADDR_VEC
- && GET_CODE (PATTERN (insn)) != ADDR_DIFF_VEC)
- || GET_CODE (insn) == CALL_INSN)
- {
- if (GET_CODE (insn) == INSN
- && (noperands = asm_noperands (PATTERN (insn))) >= 0)
- {
- decode_asm_operands (PATTERN (insn), recog_operand, NULL_PTR,
- constraints, modes);
- nalternatives = (noperands == 0 ? 0
- : n_occurrences (',', constraints[0]) + 1);
- }
- else
- {
- int insn_code_number = recog_memoized (insn);
- rtx note;
-
- set = single_set (insn);
- insn_extract (insn);
-
- nalternatives = insn_n_alternatives[insn_code_number];
- noperands = insn_n_operands[insn_code_number];
-
- /* If this insn loads a parameter from its stack slot, then
- it represents a savings, rather than a cost, if the
- parameter is stored in memory. Record this fact. */
-
- if (set != 0 && GET_CODE (SET_DEST (set)) == REG
- && GET_CODE (SET_SRC (set)) == MEM
- && (note = find_reg_note (insn, REG_EQUIV,
- NULL_RTX)) != 0
- && GET_CODE (XEXP (note, 0)) == MEM)
- {
- costs[REGNO (SET_DEST (set))].mem_cost
- -= (MEMORY_MOVE_COST (GET_MODE (SET_DEST (set)),
- GENERAL_REGS, 1)
- * loop_cost);
- record_address_regs (XEXP (SET_SRC (set), 0),
- BASE_REG_CLASS, loop_cost * 2);
- continue;
- }
-
- /* Improve handling of two-address insns such as
- (set X (ashift CONST Y)) where CONST must be made to
- match X. Change it into two insns: (set X CONST)
- (set X (ashift X Y)). If we left this for reloading, it
- would probably get three insns because X and Y might go
- in the same place. This prevents X and Y from receiving
- the same hard reg.
-
- We can only do this if the modes of operands 0 and 1
- (which might not be the same) are tieable and we only need
- do this during our first pass. */
-
- if (pass == 0 && optimize
- && noperands >= 3
- && insn_operand_constraint[insn_code_number][1][0] == '0'
- && insn_operand_constraint[insn_code_number][1][1] == 0
- && CONSTANT_P (recog_operand[1])
- && ! rtx_equal_p (recog_operand[0], recog_operand[1])
- && ! rtx_equal_p (recog_operand[0], recog_operand[2])
- && GET_CODE (recog_operand[0]) == REG
- && MODES_TIEABLE_P (GET_MODE (recog_operand[0]),
- insn_operand_mode[insn_code_number][1]))
- {
- rtx previnsn = prev_real_insn (insn);
- rtx dest
- = gen_lowpart (insn_operand_mode[insn_code_number][1],
- recog_operand[0]);
- rtx newinsn
- = emit_insn_before (gen_move_insn (dest,
- recog_operand[1]),
- insn);
-
- /* If this insn was the start of a basic block,
- include the new insn in that block.
- We need not check for code_label here;
- while a basic block can start with a code_label,
- INSN could not be at the beginning of that block. */
- if (previnsn == 0 || GET_CODE (previnsn) == JUMP_INSN)
- {
- int b;
- for (b = 0; b < n_basic_blocks; b++)
- if (insn == basic_block_head[b])
- basic_block_head[b] = newinsn;
- }
-
- /* This makes one more setting of new insns's dest. */
- REG_N_SETS (REGNO (recog_operand[0]))++;
-
- *recog_operand_loc[1] = recog_operand[0];
- for (i = insn_n_dups[insn_code_number] - 1; i >= 0; i--)
- if (recog_dup_num[i] == 1)
- *recog_dup_loc[i] = recog_operand[0];
-
- insn = PREV_INSN (newinsn);
- continue;
- }
-
- for (i = 0; i < noperands; i++)
- {
- constraints[i]
- = insn_operand_constraint[insn_code_number][i];
- modes[i] = insn_operand_mode[insn_code_number][i];
- }
- }
-
- /* If we get here, we are set up to record the costs of all the
- operands for this insn. Start by initializing the costs.
- Then handle any address registers. Finally record the desired
- classes for any pseudos, doing it twice if some pair of
- operands are commutative. */
-
- for (i = 0; i < noperands; i++)
- {
- op_costs[i] = init_cost;
-
- if (GET_CODE (recog_operand[i]) == SUBREG)
- recog_operand[i] = SUBREG_REG (recog_operand[i]);
-
- if (GET_CODE (recog_operand[i]) == MEM)
- record_address_regs (XEXP (recog_operand[i], 0),
- BASE_REG_CLASS, loop_cost * 2);
- else if (constraints[i][0] == 'p')
- record_address_regs (recog_operand[i],
- BASE_REG_CLASS, loop_cost * 2);
- }
-
- /* Check for commutative in a separate loop so everything will
- have been initialized. We must do this even if one operand
- is a constant--see addsi3 in m68k.md. */
-
- for (i = 0; i < noperands - 1; i++)
- if (constraints[i][0] == '%')
- {
- char *xconstraints[MAX_RECOG_OPERANDS];
- int j;
-
- /* Handle commutative operands by swapping the constraints.
- We assume the modes are the same. */
-
- for (j = 0; j < noperands; j++)
- xconstraints[j] = constraints[j];
-
- xconstraints[i] = constraints[i+1];
- xconstraints[i+1] = constraints[i];
- record_reg_classes (nalternatives, noperands,
- recog_operand, modes, xconstraints,
- insn);
- }
-
- record_reg_classes (nalternatives, noperands, recog_operand,
- modes, constraints, insn);
-
- /* Now add the cost for each operand to the total costs for
- its register. */
-
- for (i = 0; i < noperands; i++)
- if (GET_CODE (recog_operand[i]) == REG
- && REGNO (recog_operand[i]) >= FIRST_PSEUDO_REGISTER)
- {
- int regno = REGNO (recog_operand[i]);
- struct costs *p = &costs[regno], *q = &op_costs[i];
-
- p->mem_cost += q->mem_cost * loop_cost;
- for (j = 0; j < N_REG_CLASSES; j++)
- p->cost[j] += q->cost[j] * loop_cost;
- }
- }
+ insn = scan_one_insn (insn, pass);
}
-
+
/* Now for each register look at how desirable each class is
and find which class is preferred. Store that in
`prefclass[REGNO]'. Record in `altclass[REGNO]' the largest register
@@ -1104,19 +1137,13 @@ record_reg_classes (n_alts, n_ops, ops, modes, constraints, insn)
int n_ops;
rtx *ops;
enum machine_mode *modes;
- char **constraints;
+ const char **constraints;
rtx insn;
{
int alt;
- enum op_type {OP_READ, OP_WRITE, OP_READ_WRITE} op_types[MAX_RECOG_OPERANDS];
int i, j;
rtx set;
- /* By default, each operand is an input operand. */
-
- for (i = 0; i < n_ops; i++)
- op_types[i] = OP_READ;
-
/* Process each alternative, each time minimizing an operand's cost with
the cost for each operand in that alternative. */
@@ -1130,12 +1157,16 @@ record_reg_classes (n_alts, n_ops, ops, modes, constraints, insn)
for (i = 0; i < n_ops; i++)
{
- char *p = constraints[i];
+ const char *p = constraints[i];
rtx op = ops[i];
enum machine_mode mode = modes[i];
+ int allows_addr = 0;
int allows_mem = 0;
int win = 0;
- char c;
+ unsigned char c;
+
+ /* Initially show we know nothing about the register class. */
+ classes[i] = NO_REGS;
/* If this operand has no constraints at all, we can conclude
nothing about it since anything is valid. */
@@ -1148,12 +1179,13 @@ record_reg_classes (n_alts, n_ops, ops, modes, constraints, insn)
continue;
}
- if (*p == '%')
- p++;
-
/* If this alternative is only relevant when this operand
matches a previous operand, we do different things depending
- on whether this operand is a pseudo-reg or not. */
+ on whether this operand is a pseudo-reg or not. We must process
+ any modifiers for the operand before we can make this test. */
+
+ while (*p == '%' || *p == '=' || *p == '+' || *p == '&')
+ p++;
if (p[0] >= '0' && p[0] <= '0' + i && (p[1] == ',' || p[1] == 0))
{
@@ -1219,18 +1251,9 @@ record_reg_classes (n_alts, n_ops, ops, modes, constraints, insn)
any of the constraints. Collect the valid register classes
and see if this operand accepts memory. */
- classes[i] = NO_REGS;
while (*p && (c = *p++) != ',')
switch (c)
{
- case '=':
- op_types[i] = OP_WRITE;
- break;
-
- case '+':
- op_types[i] = OP_READ_WRITE;
- break;
-
case '*':
/* Ignore the next letter for this pass. */
p++;
@@ -1238,11 +1261,20 @@ record_reg_classes (n_alts, n_ops, ops, modes, constraints, insn)
case '?':
alt_cost += 2;
- case '%':
- case '!': case '#':
- case '&':
+ case '!': case '#': case '&':
case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ break;
+
case 'p':
+ allows_addr = 1;
+ win = address_operand (op, GET_MODE (op));
+ /* We know this operand is an address, so we want it to be
+ allocated to a register that can be the base of an
+ address, ie BASE_REG_CLASS. */
+ classes[i]
+ = reg_class_subunion[(int) classes[i]]
+ [(int) BASE_REG_CLASS];
break;
case 'm': case 'o': case 'V':
@@ -1373,7 +1405,15 @@ record_reg_classes (n_alts, n_ops, ops, modes, constraints, insn)
if (GET_CODE (op) == REG && REGNO (op) >= FIRST_PSEUDO_REGISTER)
{
if (classes[i] == NO_REGS)
- alt_fail = 1;
+ {
+ /* We must always fail if the operand is a REG, but
+ we did not find a suitable class.
+
+ Otherwise we may perform an uninitialized read
+ from this_op_costs after the `continue' statement
+ below. */
+ alt_fail = 1;
+ }
else
{
struct costs *pp = &this_op_costs[i];
@@ -1395,7 +1435,7 @@ record_reg_classes (n_alts, n_ops, ops, modes, constraints, insn)
if (prefclass)
alt_cost
- += may_move_cost[prefclass[REGNO (op)]][(int) classes[i]];
+ += may_move_cost[(unsigned char)prefclass[REGNO (op)]][(int) classes[i]];
}
}
@@ -1413,17 +1453,17 @@ record_reg_classes (n_alts, n_ops, ops, modes, constraints, insn)
else if (classes[i] != NO_REGS)
{
- if (op_types[i] != OP_WRITE)
+ if (recog_op_type[i] != OP_OUT)
alt_cost += copy_cost (op, mode, classes[i], 1);
- if (op_types[i] != OP_READ)
+ if (recog_op_type[i] != OP_IN)
alt_cost += copy_cost (op, mode, classes[i], 0);
}
/* The only other way this alternative can be used is if this is a
constant that could be placed into memory. */
- else if (CONSTANT_P (op) && allows_mem)
+ else if (CONSTANT_P (op) && (allows_addr || allows_mem))
alt_cost += MEMORY_MOVE_COST (mode, classes[i], 1);
else
alt_fail = 1;
@@ -1440,7 +1480,7 @@ record_reg_classes (n_alts, n_ops, ops, modes, constraints, insn)
&& REGNO (ops[i]) >= FIRST_PSEUDO_REGISTER)
{
struct costs *pp = &op_costs[i], *qq = &this_op_costs[i];
- int scale = 1 + (op_types[i] == OP_READ_WRITE);
+ int scale = 1 + (recog_op_type[i] == OP_INOUT);
pp->mem_cost = MIN (pp->mem_cost,
(qq->mem_cost + alt_cost) * scale);
@@ -1467,9 +1507,9 @@ record_reg_classes (n_alts, n_ops, ops, modes, constraints, insn)
int nr;
if (regno >= FIRST_PSEUDO_REGISTER && prefclass != 0
- && (reg_class_size[prefclass[regno]]
+ && (reg_class_size[(unsigned char)prefclass[regno]]
== CLASS_MAX_NREGS (prefclass[regno], mode)))
- op_costs[i].cost[prefclass[regno]] = -1;
+ op_costs[i].cost[(unsigned char)prefclass[regno]] = -1;
else if (regno < FIRST_PSEUDO_REGISTER)
for (class = 0; class < N_REG_CLASSES; class++)
if (TEST_HARD_REG_BIT (reg_class_contents[class], regno)
@@ -1737,25 +1777,21 @@ auto_inc_dec_reg_p (reg, mode)
rtx reg;
enum machine_mode mode;
{
-#ifdef HAVE_POST_INCREMENT
- if (memory_address_p (mode, gen_rtx_POST_INC (Pmode, reg)))
+ if (HAVE_POST_INCREMENT
+ && memory_address_p (mode, gen_rtx_POST_INC (Pmode, reg)))
return 1;
-#endif
-#ifdef HAVE_POST_DECREMENT
- if (memory_address_p (mode, gen_rtx_POST_DEC (Pmode, reg)))
+ if (HAVE_POST_DECREMENT
+ && memory_address_p (mode, gen_rtx_POST_DEC (Pmode, reg)))
return 1;
-#endif
-#ifdef HAVE_PRE_INCREMENT
- if (memory_address_p (mode, gen_rtx_PRE_INC (Pmode, reg)))
+ if (HAVE_PRE_INCREMENT
+ && memory_address_p (mode, gen_rtx_PRE_INC (Pmode, reg)))
return 1;
-#endif
-#ifdef HAVE_PRE_DECREMENT
- if (memory_address_p (mode, gen_rtx_PRE_DEC (Pmode, reg)))
+ if (HAVE_PRE_DECREMENT
+ && memory_address_p (mode, gen_rtx_PRE_DEC (Pmode, reg)))
return 1;
-#endif
return 0;
}
@@ -1763,6 +1799,9 @@ auto_inc_dec_reg_p (reg, mode)
#endif /* REGISTER_CONSTRAINTS */
+static short *renumber = (short *)0;
+static size_t regno_allocated = 0;
+
/* Allocate enough space to hold NUM_REGS registers for the tables used for
reg_scan and flow_analysis that are indexed by the register number. If
NEW_P is non zero, initialize all of the registers, otherwise only
@@ -1776,39 +1815,12 @@ allocate_reg_info (num_regs, new_p, renumber_p)
int new_p;
int renumber_p;
{
- static size_t regno_allocated = 0;
- static short *renumber = (short *)0;
- int i;
size_t size_info;
size_t size_renumber;
size_t min = (new_p) ? 0 : reg_n_max;
struct reg_info_data *reg_data;
struct reg_info_data *reg_next;
- /* Free up all storage allocated */
- if (num_regs < 0)
- {
- if (reg_n_info)
- {
- VARRAY_FREE (reg_n_info);
- for (reg_data = reg_info_head; reg_data; reg_data = reg_next)
- {
- reg_next = reg_data->next;
- free ((char *)reg_data);
- }
-
- free (prefclass_buffer);
- free (altclass_buffer);
- prefclass_buffer = (char *)0;
- altclass_buffer = (char *)0;
- reg_info_head = (struct reg_info_data *)0;
- renumber = (short *)0;
- }
- regno_allocated = 0;
- reg_n_max = 0;
- return;
- }
-
if (num_regs > regno_allocated)
{
size_t old_allocated = regno_allocated;
@@ -1873,6 +1885,8 @@ allocate_reg_info (num_regs, new_p, renumber_p)
{
size_t max = max_index;
size_t local_min = min - min_index;
+ size_t i;
+
if (min < min_index)
local_min = 0;
if (!reg_data->used_p) /* page just allocated with calloc */
@@ -1908,6 +1922,32 @@ allocate_reg_info (num_regs, new_p, renumber_p)
MAX_REGNO_REG_SET (num_regs, new_p, renumber_p);
}
+/* Free up the space allocated by allocate_reg_info. */
+void
+free_reg_info ()
+{
+ if (reg_n_info)
+ {
+ struct reg_info_data *reg_data;
+ struct reg_info_data *reg_next;
+
+ VARRAY_FREE (reg_n_info);
+ for (reg_data = reg_info_head; reg_data; reg_data = reg_next)
+ {
+ reg_next = reg_data->next;
+ free ((char *)reg_data);
+ }
+
+ free (prefclass_buffer);
+ free (altclass_buffer);
+ prefclass_buffer = (char *)0;
+ altclass_buffer = (char *)0;
+ reg_info_head = (struct reg_info_data *)0;
+ renumber = (short *)0;
+ }
+ regno_allocated = 0;
+ reg_n_max = 0;
+}
/* This is the `regscan' pass of the compiler, run just before cse
and again just before loop.
@@ -1999,8 +2039,8 @@ reg_scan_mark_refs (x, insn, note_flag, min_regno)
code = GET_CODE (x);
switch (code)
{
- case CONST_INT:
case CONST:
+ case CONST_INT:
case CONST_DOUBLE:
case CC0:
case PC:
@@ -2169,12 +2209,5 @@ reg_classes_intersect_p (c1, c2)
void
regset_release_memory ()
{
- if (basic_block_live_at_start)
- {
- free_regset_vector (basic_block_live_at_start, n_basic_blocks);
- basic_block_live_at_start = 0;
- }
-
- FREE_REG_SET (regs_live_at_setjmp);
bitmap_release_memory ();
}
diff --git a/gcc/regmove.c b/gcc/regmove.c
index e0af189e422..3b65fc90e90 100644
--- a/gcc/regmove.c
+++ b/gcc/regmove.c
@@ -1,5 +1,5 @@
/* Move registers around to reduce number of move instructions needed.
- Copyright (C) 1987, 88, 89, 92-97, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1987, 88, 89, 92-98, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -15,7 +15,8 @@ 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
/* This module looks for cases where matching constraints would force
@@ -43,7 +44,7 @@ static int optimize_reg_copy_1 PROTO((rtx, rtx, rtx));
static void optimize_reg_copy_2 PROTO((rtx, rtx, rtx));
static void optimize_reg_copy_3 PROTO((rtx, rtx, rtx));
static rtx gen_add3_insn PROTO((rtx, rtx, rtx));
-static void copy_src_to_dest PROTO((rtx, rtx, rtx, int));
+static void copy_src_to_dest PROTO((rtx, rtx, rtx, int, int));
static int *regmove_bb_head;
struct match {
@@ -53,9 +54,11 @@ struct match {
int early_clobber[MAX_RECOG_OPERANDS];
};
-#ifdef AUTO_INC_DEC
+static rtx discover_flags_reg PROTO((void));
+static void mark_flags_life_zones PROTO((rtx));
+static void flags_set_1 PROTO((rtx, rtx));
+
static int try_auto_increment PROTO((rtx, rtx, rtx, rtx, HOST_WIDE_INT, int));
-#endif
static int find_matches PROTO((rtx, struct match *));
static int fixup_match_1 PROTO((rtx, rtx, rtx, rtx, rtx, int, int, int, FILE *))
;
@@ -94,7 +97,6 @@ gen_add3_insn (r0, r1, c)
return (GEN_FCN (icode) (r0, r1, c));
}
-#ifdef AUTO_INC_DEC
/* INC_INSN is an instruction that adds INCREMENT to REG.
Try to fold INC_INSN as a post/pre in/decrement into INSN.
@@ -118,18 +120,14 @@ try_auto_increment (insn, inc_insn, inc_insn_set, reg, increment, pre)
{
int size = GET_MODE_SIZE (GET_MODE (use));
if (0
-#ifdef HAVE_POST_INCREMENT
- || (pre == 0 && (inc_code = POST_INC, increment == size))
-#endif
-#ifdef HAVE_PRE_INCREMENT
- || (pre == 1 && (inc_code = PRE_INC, increment == size))
-#endif
-#ifdef HAVE_POST_DECREMENT
- || (pre == 0 && (inc_code = POST_DEC, increment == -size))
-#endif
-#ifdef HAVE_PRE_DECREMENT
- || (pre == 1 && (inc_code = PRE_DEC, increment == -size))
-#endif
+ || (HAVE_POST_INCREMENT
+ && pre == 0 && (inc_code = POST_INC, increment == size))
+ || (HAVE_PRE_INCREMENT
+ && pre == 1 && (inc_code = PRE_INC, increment == size))
+ || (HAVE_POST_DECREMENT
+ && pre == 0 && (inc_code = POST_DEC, increment == -size))
+ || (HAVE_PRE_DECREMENT
+ && pre == 1 && (inc_code = PRE_DEC, increment == -size))
)
{
if (inc_insn_set)
@@ -157,8 +155,175 @@ try_auto_increment (insn, inc_insn, inc_insn_set, reg, increment, pre)
}
return 0;
}
-#endif /* AUTO_INC_DEC */
+
+/* Determine if the pattern generated by add_optab has a clobber,
+ such as might be issued for a flags hard register. To make the
+ code elsewhere simpler, we handle cc0 in this same framework.
+
+ Return the register if one was discovered. Return NULL_RTX if
+ if no flags were found. Return pc_rtx if we got confused. */
+
+static rtx
+discover_flags_reg ()
+{
+ rtx tmp;
+ tmp = gen_rtx_REG (word_mode, 10000);
+ tmp = gen_add3_insn (tmp, tmp, GEN_INT (2));
+
+ /* If we get something that isn't a simple set, or a
+ [(set ..) (clobber ..)], this whole function will go wrong. */
+ if (GET_CODE (tmp) == SET)
+ return NULL_RTX;
+ else if (GET_CODE (tmp) == PARALLEL)
+ {
+ int found;
+
+ if (XVECLEN (tmp, 0) != 2)
+ return pc_rtx;
+ tmp = XVECEXP (tmp, 0, 1);
+ if (GET_CODE (tmp) != CLOBBER)
+ return pc_rtx;
+ tmp = XEXP (tmp, 0);
+
+ /* Don't do anything foolish if the md wanted to clobber a
+ scratch or something. We only care about hard regs.
+ Moreover we don't like the notion of subregs of hard regs. */
+ if (GET_CODE (tmp) == SUBREG
+ && GET_CODE (SUBREG_REG (tmp)) == REG
+ && REGNO (SUBREG_REG (tmp)) < FIRST_PSEUDO_REGISTER)
+ return pc_rtx;
+ found = (GET_CODE (tmp) == REG && REGNO (tmp) < FIRST_PSEUDO_REGISTER);
+
+ return (found ? tmp : NULL_RTX);
+ }
+
+ return pc_rtx;
+}
+
+/* It is a tedious task identifying when the flags register is live and
+ when it is safe to optimize. Since we process the instruction stream
+ multiple times, locate and record these live zones by marking the
+ mode of the instructions --
+
+ QImode is used on the instruction at which the flags becomes live.
+
+ HImode is used within the range (exclusive) that the flags are
+ live. Thus the user of the flags is not marked.
+
+ All other instructions are cleared to VOIDmode. */
+
+/* Used to communicate with flags_set_1. */
+static rtx flags_set_1_rtx;
+static int flags_set_1_set;
+
+static void
+mark_flags_life_zones (flags)
+ rtx flags;
+{
+ int flags_regno;
+ int flags_nregs;
+ int block;
+
+#ifdef HAVE_cc0
+ /* If we found a flags register on a cc0 host, bail. */
+ if (flags == NULL_RTX)
+ flags = cc0_rtx;
+ else if (flags != cc0_rtx)
+ flags = pc_rtx;
+#endif
+
+ /* Simple cases first: if no flags, clear all modes. If confusing,
+ mark the entire function as being in a flags shadow. */
+ if (flags == NULL_RTX || flags == pc_rtx)
+ {
+ enum machine_mode mode = (flags ? HImode : VOIDmode);
+ rtx insn;
+ for (insn = get_insns(); insn; insn = NEXT_INSN (insn))
+ PUT_MODE (insn, mode);
+ return;
+ }
+
+#ifdef HAVE_cc0
+ flags_regno = -1;
+ flags_nregs = 1;
+#else
+ flags_regno = REGNO (flags);
+ flags_nregs = HARD_REGNO_NREGS (flags_regno, GET_MODE (flags));
+#endif
+ flags_set_1_rtx = flags;
+
+ /* Process each basic block. */
+ for (block = n_basic_blocks - 1; block >= 0; block--)
+ {
+ rtx insn, end;
+ int live;
+
+ insn = BLOCK_HEAD (block);
+ end = BLOCK_END (block);
+
+ /* Look out for the (unlikely) case of flags being live across
+ basic block boundaries. */
+ live = 0;
+#ifndef HAVE_cc0
+ {
+ int i;
+ for (i = 0; i < flags_nregs; ++i)
+ live |= REGNO_REG_SET_P (BASIC_BLOCK (block)->global_live_at_start,
+ flags_regno + i);
+ }
+#endif
+ while (1)
+ {
+ /* Process liveness in reverse order of importance --
+ alive, death, birth. This lets more important info
+ overwrite the mode of lesser info. */
+
+ if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
+ {
+#ifdef HAVE_cc0
+ /* In the cc0 case, death is not marked in reg notes,
+ but is instead the mere use of cc0 when it is alive. */
+ if (live && reg_mentioned_p (cc0_rtx, PATTERN (insn)))
+ live = 0;
+#else
+ /* In the hard reg case, we watch death notes. */
+ if (live && find_regno_note (insn, REG_DEAD, flags_regno))
+ live = 0;
+#endif
+ PUT_MODE (insn, (live ? HImode : VOIDmode));
+
+ /* In either case, birth is denoted simply by it's presence
+ as the destination of a set. */
+ flags_set_1_set = 0;
+ note_stores (PATTERN (insn), flags_set_1);
+ if (flags_set_1_set)
+ {
+ live = 1;
+ PUT_MODE (insn, QImode);
+ }
+ }
+ else
+ PUT_MODE (insn, (live ? HImode : VOIDmode));
+
+ if (insn == end)
+ break;
+ insn = NEXT_INSN (insn);
+ }
+ }
+}
+
+/* A subroutine of mark_flags_life_zones, called through note_stores. */
+
+static void
+flags_set_1 (x, pat)
+ rtx x, pat;
+{
+ if (GET_CODE (pat) == SET
+ && reg_overlap_mentioned_p (x, flags_set_1_rtx))
+ flags_set_1_set = 1;
+}
+
static int *regno_src_regno;
/* Indicate how good a choice REG (which appears as a source) is to replace
@@ -261,10 +426,10 @@ optimize_reg_copy_1 (insn, dest, src)
&& GET_MODE (XEXP (note, 0)) == GET_MODE (src))
{
int failed = 0;
- int length = 0;
int d_length = 0;
- int n_calls = 0;
+ int s_length = 0;
int d_n_calls = 0;
+ int s_n_calls = 0;
/* We can do the optimization. Scan forward from INSN again,
replacing regs as we go. Set FAILED if a replacement can't
@@ -298,42 +463,14 @@ optimize_reg_copy_1 (insn, dest, src)
insn in the REG_N_REFS updates below. If this is not
correct, no great harm is done.
-
- We do not undo this substitution if something later
- fails. Therefore, we must update the other REG_N_*
- counters now to keep them accurate. */
+ Since we do not know if we will change the lifetime of
+ SREGNO or DREGNO, we must not update REG_LIVE_LENGTH
+ or REG_N_CALLS_CROSSED at this time. */
if (sregno >= FIRST_PSEUDO_REGISTER)
- {
- REG_N_REFS (sregno) -= loop_depth;
-
- if (REG_LIVE_LENGTH (sregno) >= 0)
- {
- REG_LIVE_LENGTH (sregno) -= length;
- /* REG_LIVE_LENGTH is only an approximation after
- combine if sched is not run, so make sure that
- we still have a reasonable value. */
- if (REG_LIVE_LENGTH (sregno) < 2)
- REG_LIVE_LENGTH (sregno) = 2;
- }
-
- REG_N_CALLS_CROSSED (sregno) -= n_calls;
- }
+ REG_N_REFS (sregno) -= loop_depth;
if (dregno >= FIRST_PSEUDO_REGISTER)
- {
- REG_N_REFS (dregno) += loop_depth;
-
- if (REG_LIVE_LENGTH (dregno) >= 0)
- REG_LIVE_LENGTH (dregno) += d_length;
-
- REG_N_CALLS_CROSSED (dregno) += d_n_calls;
- }
-
- /* We've done a substitution, clear the counters. */
- length = 0;
- d_length = 0;
- n_calls = 0;
- d_n_calls = 0;
+ REG_N_REFS (dregno) += loop_depth;
}
else
{
@@ -342,9 +479,10 @@ optimize_reg_copy_1 (insn, dest, src)
}
}
- /* Count the insns and CALL_INSNs passed. If we passed the
- death note of DEST, show increased live length. */
- length++;
+ /* For SREGNO, count the total number of insns scanned.
+ For DREGNO, count the total number of insns scanned after
+ passing the death note for DREGNO. */
+ s_length++;
if (dest_death)
d_length++;
@@ -352,7 +490,9 @@ optimize_reg_copy_1 (insn, dest, src)
as a call that has been crossed. Otherwise, count it. */
if (q != p && GET_CODE (q) == CALL_INSN)
{
- n_calls++;
+ /* Similarly, total calls for SREGNO, total calls beyond
+ the death note for DREGNO. */
+ s_n_calls++;
if (dest_death)
d_n_calls++;
}
@@ -372,11 +512,13 @@ optimize_reg_copy_1 (insn, dest, src)
if (! failed)
{
+ /* These counters need to be updated if and only if we are
+ going to move the REG_DEAD note. */
if (sregno >= FIRST_PSEUDO_REGISTER)
{
if (REG_LIVE_LENGTH (sregno) >= 0)
{
- REG_LIVE_LENGTH (sregno) -= length;
+ REG_LIVE_LENGTH (sregno) -= s_length;
/* REG_LIVE_LENGTH is only an approximation after
combine if sched is not run, so make sure that we
still have a reasonable value. */
@@ -384,15 +526,7 @@ optimize_reg_copy_1 (insn, dest, src)
REG_LIVE_LENGTH (sregno) = 2;
}
- REG_N_CALLS_CROSSED (sregno) -= n_calls;
- }
-
- if (dregno >= FIRST_PSEUDO_REGISTER)
- {
- if (REG_LIVE_LENGTH (dregno) >= 0)
- REG_LIVE_LENGTH (dregno) += d_length;
-
- REG_N_CALLS_CROSSED (dregno) += d_n_calls;
+ REG_N_CALLS_CROSSED (sregno) -= s_n_calls;
}
/* Move death note of SRC from P to INSN. */
@@ -406,6 +540,15 @@ optimize_reg_copy_1 (insn, dest, src)
{
XEXP (dest_death, 1) = REG_NOTES (p);
REG_NOTES (p) = dest_death;
+
+ if (dregno >= FIRST_PSEUDO_REGISTER)
+ {
+ /* If and only if we are moving the death note for DREGNO,
+ then we need to update its counters. */
+ if (REG_LIVE_LENGTH (dregno) >= 0)
+ REG_LIVE_LENGTH (dregno) += d_length;
+ REG_N_CALLS_CROSSED (dregno) += d_n_calls;
+ }
}
return ! failed;
@@ -553,6 +696,19 @@ optimize_reg_copy_3 (insn, dest, src)
|| GET_CODE (SET_SRC (set)) != MEM
|| SET_DEST (set) != src_reg)
return;
+
+ /* Be conserative: although this optimization is also valid for
+ volatile memory references, that could cause trouble in later passes. */
+ if (MEM_VOLATILE_P (SET_SRC (set)))
+ return;
+
+ /* Do not use a SUBREG to truncate from one mode to another if truncation
+ is not a nop. */
+ if (GET_MODE_BITSIZE (GET_MODE (src_reg)) <= GET_MODE_BITSIZE (GET_MODE (src))
+ && !TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (GET_MODE (src)),
+ GET_MODE_BITSIZE (GET_MODE (src_reg))))
+ return;
+
old_mode = GET_MODE (src_reg);
PUT_MODE (src_reg, GET_MODE (src));
XEXP (src, 0) = SET_SRC (set);
@@ -589,11 +745,12 @@ optimize_reg_copy_3 (insn, dest, src)
instead moving the value to dest directly before the operation. */
static void
-copy_src_to_dest (insn, src, dest, loop_depth)
+copy_src_to_dest (insn, src, dest, loop_depth, old_max_uid)
rtx insn;
rtx src;
rtx dest;
int loop_depth;
+ int old_max_uid;
{
rtx seq;
rtx link;
@@ -665,11 +822,14 @@ copy_src_to_dest (insn, src, dest, loop_depth)
/* Is the insn the head of a basic block? If so extend it */
insn_uid = INSN_UID (insn);
move_uid = INSN_UID (move_insn);
- bb = regmove_bb_head[insn_uid];
- if (bb >= 0)
+ if (insn_uid < old_max_uid)
{
- basic_block_head[bb] = move_insn;
- regmove_bb_head[insn_uid] = -1;
+ bb = regmove_bb_head[insn_uid];
+ if (bb >= 0)
+ {
+ BLOCK_HEAD (bb) = move_insn;
+ regmove_bb_head[insn_uid] = -1;
+ }
}
/* Update the various register tables. */
@@ -925,13 +1085,17 @@ regmove_optimize (f, nregs, regmove_dump_file)
int i;
rtx copy_src, copy_dst;
+ /* Find out where a potential flags register is live, and so that we
+ can supress some optimizations in those zones. */
+ mark_flags_life_zones (discover_flags_reg ());
+
regno_src_regno = (int *)alloca (sizeof *regno_src_regno * nregs);
for (i = nregs; --i >= 0; ) regno_src_regno[i] = -1;
regmove_bb_head = (int *)alloca (sizeof (int) * (old_max_uid + 1));
for (i = old_max_uid; i >= 0; i--) regmove_bb_head[i] = -1;
for (i = 0; i < n_basic_blocks; i++)
- regmove_bb_head[INSN_UID (basic_block_head[i])] = i;
+ regmove_bb_head[INSN_UID (BLOCK_HEAD (i))] = i;
/* A forward/backward pass. Replace output operands with input operands. */
@@ -950,8 +1114,7 @@ regmove_optimize (f, nregs, regmove_dump_file)
insn = pass ? PREV_INSN (insn) : NEXT_INSN (insn))
{
rtx set;
- int insn_code_number;
- int operand_number, match_number;
+ int op_no, match_no;
if (GET_CODE (insn) == NOTE)
{
@@ -996,11 +1159,11 @@ regmove_optimize (f, nregs, regmove_dump_file)
}
}
}
-#ifdef REGISTER_CONSTRAINTS
- insn_code_number
- = find_matches (insn, &match);
+ if (! flag_regmove)
+ continue;
- if (insn_code_number < 0)
+#ifdef REGISTER_CONSTRAINTS
+ if (! find_matches (insn, &match))
continue;
/* Now scan through the operands looking for a source operand
@@ -1010,21 +1173,19 @@ regmove_optimize (f, nregs, regmove_dump_file)
If it dies there, then replace the dest in both operands with
the source operand. */
- for (operand_number = 0;
- operand_number < insn_n_operands[insn_code_number];
- operand_number++)
+ for (op_no = 0; op_no < recog_n_operands; op_no++)
{
rtx src, dst, src_subreg;
enum reg_class src_class, dst_class;
- match_number = match.with[operand_number];
+ match_no = match.with[op_no];
/* Nothing to do if the two operands aren't supposed to match. */
- if (match_number < 0)
+ if (match_no < 0)
continue;
- src = recog_operand[operand_number];
- dst = recog_operand[match_number];
+ src = recog_operand[op_no];
+ dst = recog_operand[match_no];
if (GET_CODE (src) != REG)
continue;
@@ -1045,7 +1206,7 @@ regmove_optimize (f, nregs, regmove_dump_file)
if (REGNO (src) < FIRST_PSEUDO_REGISTER)
{
- if (match.commutative[operand_number] < operand_number)
+ if (match.commutative[op_no] < op_no)
regno_src_regno[REGNO (dst)] = REGNO (src);
continue;
}
@@ -1053,28 +1214,28 @@ regmove_optimize (f, nregs, regmove_dump_file)
if (REG_LIVE_LENGTH (REGNO (src)) < 0)
continue;
- /* operand_number/src must be a read-only operand, and
+ /* op_no/src must be a read-only operand, and
match_operand/dst must be a write-only operand. */
- if (match.use[operand_number] != READ
- || match.use[match_number] != WRITE)
+ if (match.use[op_no] != READ
+ || match.use[match_no] != WRITE)
continue;
- if (match.early_clobber[match_number]
+ if (match.early_clobber[match_no]
&& count_occurrences (PATTERN (insn), src) > 1)
continue;
/* Make sure match_operand is the destination. */
- if (recog_operand[match_number] != SET_DEST (set))
+ if (recog_operand[match_no] != SET_DEST (set))
continue;
/* If the operands already match, then there is nothing to do. */
/* But in the commutative case, we might find a better match. */
if (operands_match_p (src, dst)
- || (match.commutative[operand_number] >= 0
+ || (match.commutative[op_no] >= 0
&& operands_match_p (recog_operand[match.commutative
- [operand_number]], dst)
+ [op_no]], dst)
&& (replacement_quality (recog_operand[match.commutative
- [operand_number]])
+ [op_no]])
>= replacement_quality (src))))
continue;
@@ -1084,7 +1245,7 @@ regmove_optimize (f, nregs, regmove_dump_file)
continue;
if (fixup_match_1 (insn, set, src, src_subreg, dst, pass,
- operand_number, match_number,
+ op_no, match_no,
regmove_dump_file))
break;
}
@@ -1109,11 +1270,10 @@ regmove_optimize (f, nregs, regmove_dump_file)
}
if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
{
- int insn_code_number = find_matches (insn, &match);
- int operand_number, match_number;
+ int op_no, match_no;
int success = 0;
-
- if (insn_code_number < 0)
+
+ if (! find_matches (insn, &match))
continue;
/* Now scan through the operands looking for a destination operand
@@ -1124,9 +1284,7 @@ regmove_optimize (f, nregs, regmove_dump_file)
copy_src = NULL_RTX;
copy_dst = NULL_RTX;
- for (operand_number = 0;
- operand_number < insn_n_operands[insn_code_number];
- operand_number++)
+ for (op_no = 0; op_no < recog_n_operands; op_no++)
{
rtx set, p, src, dst;
rtx src_note, dst_note;
@@ -1134,14 +1292,14 @@ regmove_optimize (f, nregs, regmove_dump_file)
enum reg_class src_class, dst_class;
int length;
- match_number = match.with[operand_number];
+ match_no = match.with[op_no];
/* Nothing to do if the two operands aren't supposed to match. */
- if (match_number < 0)
+ if (match_no < 0)
continue;
- dst = recog_operand[match_number];
- src = recog_operand[operand_number];
+ dst = recog_operand[match_no];
+ src = recog_operand[op_no];
if (GET_CODE (src) != REG)
continue;
@@ -1153,26 +1311,26 @@ regmove_optimize (f, nregs, regmove_dump_file)
/* If the operands already match, then there is nothing to do. */
if (operands_match_p (src, dst)
- || (match.commutative[operand_number] >= 0
- && operands_match_p (recog_operand[match.commutative[operand_number]], dst)))
+ || (match.commutative[op_no] >= 0
+ && operands_match_p (recog_operand[match.commutative[op_no]], dst)))
continue;
set = single_set (insn);
if (! set)
continue;
- /* match_number/dst must be a write-only operand, and
+ /* match_no/dst must be a write-only operand, and
operand_operand/src must be a read-only operand. */
- if (match.use[operand_number] != READ
- || match.use[match_number] != WRITE)
+ if (match.use[op_no] != READ
+ || match.use[match_no] != WRITE)
continue;
- if (match.early_clobber[match_number]
+ if (match.early_clobber[match_no]
&& count_occurrences (PATTERN (insn), src) > 1)
continue;
- /* Make sure match_number is the destination. */
- if (recog_operand[match_number] != SET_DEST (set))
+ /* Make sure match_no is the destination. */
+ if (recog_operand[match_no] != SET_DEST (set))
continue;
if (REGNO (src) < FIRST_PSEUDO_REGISTER)
@@ -1240,11 +1398,11 @@ regmove_optimize (f, nregs, regmove_dump_file)
if (regmove_dump_file)
fprintf (regmove_dump_file,
"Could fix operand %d of insn %d matching operand %d.\n",
- operand_number, INSN_UID (insn), match_number);
+ op_no, INSN_UID (insn), match_no);
/* Scan backward to find the first instruction that uses
the input operand. If the operand is set here, then
- replace it in both instructions with match_number. */
+ replace it in both instructions with match_no. */
for (length = 0, p = PREV_INSN (insn); p; p = PREV_INSN (p))
{
@@ -1292,7 +1450,7 @@ regmove_optimize (f, nregs, regmove_dump_file)
validate_replace_rtx (dst, src, insn);
/* Now make sure the dst is right. */
validate_change (insn,
- recog_operand_loc[match_number],
+ recog_operand_loc[match_no],
dst, 0);
}
}
@@ -1372,7 +1530,7 @@ regmove_optimize (f, nregs, regmove_dump_file)
if (regmove_dump_file)
fprintf (regmove_dump_file,
"Fixed operand %d of insn %d matching operand %d.\n",
- operand_number, INSN_UID (insn), match_number);
+ op_no, INSN_UID (insn), match_no);
break;
}
@@ -1381,7 +1539,8 @@ regmove_optimize (f, nregs, regmove_dump_file)
/* If we weren't able to replace any of the alternatives, try an
alternative appoach of copying the source to the destination. */
if (!success && copy_src != NULL_RTX)
- copy_src_to_dest (insn, copy_src, copy_dst, loop_depth);
+ copy_src_to_dest (insn, copy_src, copy_dst, loop_depth,
+ old_max_uid);
}
}
@@ -1391,19 +1550,19 @@ regmove_optimize (f, nregs, regmove_dump_file)
ends. Fix that here. */
for (i = 0; i < n_basic_blocks; i++)
{
- rtx end = basic_block_end[i];
+ rtx end = BLOCK_END (i);
rtx new = end;
rtx next = NEXT_INSN (new);
while (next != 0 && INSN_UID (next) >= old_max_uid
- && (i == n_basic_blocks - 1 || basic_block_head[i + 1] != next))
+ && (i == n_basic_blocks - 1 || BLOCK_HEAD (i + 1) != next))
new = next, next = NEXT_INSN (new);
- basic_block_end[i] = new;
+ BLOCK_END (i) = new;
}
}
-/* Returns the INSN_CODE for INSN if its pattern has matching constraints for
- any operand. Returns -1 if INSN can't be recognized, or if the alternative
- can't be determined.
+/* Returns nonzero if INSN's pattern has matching constraints for any operand.
+ Returns 0 if INSN can't be recognized, or if the alternative can't be
+ determined.
Initialize the info in MATCHP based on the constraints. */
@@ -1413,39 +1572,34 @@ find_matches (insn, matchp)
struct match *matchp;
{
int likely_spilled[MAX_RECOG_OPERANDS];
- int operand_number;
- int insn_code_number = recog_memoized (insn);
+ int op_no;
int any_matches = 0;
- if (insn_code_number < 0)
- return -1;
-
- insn_extract (insn);
- if (! constrain_operands (insn_code_number, 0))
- return -1;
+ extract_insn (insn);
+ if (! constrain_operands (0))
+ return 0;
/* Must initialize this before main loop, because the code for
the commutative case may set matches for operands other than
the current one. */
- for (operand_number = insn_n_operands[insn_code_number];
- --operand_number >= 0; )
- matchp->with[operand_number] = matchp->commutative[operand_number] = -1;
+ for (op_no = recog_n_operands; --op_no >= 0; )
+ matchp->with[op_no] = matchp->commutative[op_no] = -1;
- for (operand_number = 0; operand_number < insn_n_operands[insn_code_number];
- operand_number++)
+ for (op_no = 0; op_no < recog_n_operands; op_no++)
{
- char *p, c;
+ const char *p;
+ char c;
int i = 0;
- p = insn_operand_constraint[insn_code_number][operand_number];
+ p = recog_constraints[op_no];
- likely_spilled[operand_number] = 0;
- matchp->use[operand_number] = READ;
- matchp->early_clobber[operand_number] = 0;
+ likely_spilled[op_no] = 0;
+ matchp->use[op_no] = READ;
+ matchp->early_clobber[op_no] = 0;
if (*p == '=')
- matchp->use[operand_number] = WRITE;
+ matchp->use[op_no] = WRITE;
else if (*p == '+')
- matchp->use[operand_number] = READWRITE;
+ matchp->use[op_no] = READWRITE;
for (;*p && i < which_alternative; p++)
if (*p == ',')
@@ -1459,32 +1613,32 @@ find_matches (insn, matchp)
case '+':
break;
case '&':
- matchp->early_clobber[operand_number] = 1;
+ matchp->early_clobber[op_no] = 1;
break;
case '%':
- matchp->commutative[operand_number] = operand_number + 1;
- matchp->commutative[operand_number + 1] = operand_number;
+ matchp->commutative[op_no] = op_no + 1;
+ matchp->commutative[op_no + 1] = op_no;
break;
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
c -= '0';
- if (c < operand_number && likely_spilled[(unsigned char) c])
+ if (c < op_no && likely_spilled[(unsigned char) c])
break;
- matchp->with[operand_number] = c;
+ matchp->with[op_no] = c;
any_matches = 1;
- if (matchp->commutative[operand_number] >= 0)
- matchp->with[matchp->commutative[operand_number]] = c;
+ if (matchp->commutative[op_no] >= 0)
+ matchp->with[matchp->commutative[op_no]] = c;
break;
case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'h':
case 'j': case 'k': case 'l': case 'p': case 'q': case 't': case 'u':
case 'v': case 'w': case 'x': case 'y': case 'z': case 'A': case 'B':
case 'C': case 'D': case 'W': case 'Y': case 'Z':
- if (CLASS_LIKELY_SPILLED_P (REG_CLASS_FROM_LETTER (c)))
- likely_spilled[operand_number] = 1;
+ if (CLASS_LIKELY_SPILLED_P (REG_CLASS_FROM_LETTER ((unsigned char)c)))
+ likely_spilled[op_no] = 1;
break;
}
}
- return any_matches ? insn_code_number : -1;
+ return any_matches;
}
/* Try to replace output operand DST in SET, with input operand SRC. SET is
@@ -1645,13 +1799,9 @@ fixup_match_1 (insn, set, src, src_subreg, dst, backward, operand_number,
&& GET_CODE (SET_DEST (single_set (p))) == REG
&& (REGNO (SET_DEST (single_set (p)))
< FIRST_PSEUDO_REGISTER))
-#ifdef HAVE_cc0
- /* We may not emit an insn directly
- after P if the latter sets CC0. */
- && ! sets_cc0_p (PATTERN (p))
-#endif
- )
-
+ /* We may only emit an insn directly after P if we
+ are not in the shadow of a live flags register. */
+ && GET_MODE (p) == VOIDmode)
{
search_end = q;
q = insn;
@@ -1725,11 +1875,10 @@ fixup_match_1 (insn, set, src, src_subreg, dst, backward, operand_number,
if (code == MINUS)
{
post_inc = emit_insn_after (copy_rtx (PATTERN (insn)), p);
-#if defined (HAVE_PRE_INCREMENT) || defined (HAVE_PRE_DECREMENT)
- if (search_end
+ if ((HAVE_PRE_INCREMENT || HAVE_PRE_DECREMENT)
+ && search_end
&& try_auto_increment (search_end, post_inc, 0, src, newconst, 1))
post_inc = 0;
-#endif
validate_change (insn, &XEXP (SET_SRC (set), 1), GEN_INT (insn_const), 0);
REG_N_SETS (REGNO (src))++;
REG_N_REFS (REGNO (src)) += true_loop_depth;
@@ -1834,31 +1983,23 @@ fixup_match_1 (insn, set, src, src_subreg, dst, backward, operand_number,
else in the next two conditionally included code blocks. */
if (0)
{;}
-#if defined (HAVE_PRE_INCREMENT) || defined (HAVE_PRE_DECREMENT)
- else if ((code == PLUS || code == MINUS) && insn_const
+ else if ((HAVE_PRE_INCREMENT || HAVE_PRE_DECREMENT)
+ && (code == PLUS || code == MINUS) && insn_const
&& try_auto_increment (p, insn, 0, src, insn_const, 1))
insn = p;
-#endif
-#if defined (HAVE_POST_INCREMENT) || defined (HAVE_POST_DECREMENT)
- else if (post_inc
+ else if ((HAVE_POST_INCREMENT || HAVE_POST_DECREMENT)
+ && post_inc
&& try_auto_increment (p, post_inc, post_inc_set, src, newconst, 0))
post_inc = 0;
-#endif
-#if defined (HAVE_PRE_INCREMENT) || defined (HAVE_PRE_DECREMENT)
/* If post_inc still prevails, try to find an
insn where it can be used as a pre-in/decrement.
If code is MINUS, this was already tried. */
if (post_inc && code == PLUS
/* Check that newconst is likely to be usable
in a pre-in/decrement before starting the search. */
- && (0
-#if defined (HAVE_PRE_INCREMENT)
- || (newconst > 0 && newconst <= MOVE_MAX)
-#endif
-#if defined (HAVE_PRE_DECREMENT)
- || (newconst < 0 && newconst >= -MOVE_MAX)
-#endif
- ) && exact_log2 (newconst))
+ && ((HAVE_PRE_INCREMENT && newconst > 0 && newconst <= MOVE_MAX)
+ || (HAVE_PRE_DECREMENT && newconst < 0 && newconst >= -MOVE_MAX))
+ && exact_log2 (newconst))
{
rtx q, inc_dest;
@@ -1895,7 +2036,6 @@ fixup_match_1 (insn, set, src, src_subreg, dst, backward, operand_number,
}
}
}
-#endif /* defined (HAVE_PRE_INCREMENT) || defined (HAVE_PRE_DECREMENT) */
/* Move the death note for DST to INSN if it is used
there. */
if (reg_overlap_mentioned_p (dst, PATTERN (insn)))
@@ -2028,7 +2168,7 @@ regmove_profitable_p ()
we find a machine where this occurs and regmove should
be enabled. */
break;
- if (find_matches (pat, &match) >= 0)
+ if (find_matches (pat, &match))
return 1;
break;
}
diff --git a/gcc/regs.h b/gcc/regs.h
index c12f7f996fc..e551dae8cbd 100644
--- a/gcc/regs.h
+++ b/gcc/regs.h
@@ -38,10 +38,6 @@ Boston, MA 02111-1307, USA. */
extern int max_regno;
-/* Maximum number of SCRATCH rtx's in each block of this function. */
-
-extern int max_scratch;
-
/* Register information indexed by register number */
typedef struct reg_info_def {
/* fields set by reg_scan */
diff --git a/gcc/reload.c b/gcc/reload.c
index eea1a0b9f3b..33ce853ff84 100644
--- a/gcc/reload.c
+++ b/gcc/reload.c
@@ -1,5 +1,5 @@
/* Search an insn for pseudo regs that must be in hard regs and are not.
- Copyright (C) 1987, 88, 89, 92-97, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1987, 88, 89, 92-98, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -182,6 +182,7 @@ char reload_optional[MAX_RELOADS];
char reload_nongroup[MAX_RELOADS];
int reload_inc[MAX_RELOADS];
rtx reload_in_reg[MAX_RELOADS];
+rtx reload_out_reg[MAX_RELOADS];
char reload_nocombine[MAX_RELOADS];
int reload_opnum[MAX_RELOADS];
enum reload_type reload_when_needed[MAX_RELOADS];
@@ -233,11 +234,6 @@ struct decomposition
HOST_WIDE_INT end; /* Ending offset or register number. */
};
-/* MEM-rtx's created for pseudo-regs in stack slots not directly addressable;
- (see reg_equiv_address). */
-static rtx memlocs[MAX_RECOG_OPERANDS * ((MAX_REGS_PER_ADDRESS * 2) + 1)];
-static int n_memlocs;
-
#ifdef SECONDARY_MEMORY_NEEDED
/* Save MEMs needed to copy from one class of registers to another. One MEM
@@ -322,6 +318,8 @@ static int push_reload PROTO((rtx, rtx, rtx *, rtx *, enum reg_class,
int, int, int, enum reload_type));
static void push_replacement PROTO((rtx *, int, enum machine_mode));
static void combine_reloads PROTO((void));
+static int find_reusable_reload PROTO((rtx *, rtx, enum reg_class,
+ enum reload_type, int, int));
static rtx find_dummy_reload PROTO((rtx, rtx, rtx *, rtx *,
enum machine_mode, enum machine_mode,
enum reg_class, int, int));
@@ -329,19 +327,22 @@ static int earlyclobber_operand_p PROTO((rtx));
static int hard_reg_set_here_p PROTO((int, int, rtx));
static struct decomposition decompose PROTO((rtx));
static int immune_p PROTO((rtx, rtx, struct decomposition));
-static int alternative_allows_memconst PROTO((char *, int));
-static rtx find_reloads_toplev PROTO((rtx, int, enum reload_type, int, int));
+static int alternative_allows_memconst PROTO((const char *, int));
+static rtx find_reloads_toplev PROTO((rtx, int, enum reload_type, int, int, rtx));
static rtx make_memloc PROTO((rtx, int));
static int find_reloads_address PROTO((enum machine_mode, rtx *, rtx, rtx *,
int, enum reload_type, int, rtx));
-static rtx subst_reg_equivs PROTO((rtx));
+static rtx subst_reg_equivs PROTO((rtx, rtx));
static rtx subst_indexed_address PROTO((rtx));
static int find_reloads_address_1 PROTO((enum machine_mode, rtx, int, rtx *,
int, enum reload_type,int, rtx));
static void find_reloads_address_part PROTO((rtx, rtx *, enum reg_class,
enum machine_mode, int,
enum reload_type, int));
+static rtx find_reloads_subreg_address PROTO((rtx, int, int, enum reload_type,
+ int, rtx));
static int find_inc_amount PROTO((rtx, rtx));
+static int loc_mentioned_in_p PROTO((rtx *, rtx));
#ifdef HAVE_SECONDARY_RELOADS
@@ -446,7 +447,7 @@ push_secondary_reload (in_p, x, opnum, optional, reload_class, reload_mode,
char insn_letter = insn_operand_constraint[(int) icode][!in_p][in_p];
enum reg_class insn_class
= (insn_letter == 'r' ? GENERAL_REGS
- : REG_CLASS_FROM_LETTER (insn_letter));
+ : REG_CLASS_FROM_LETTER ((unsigned char) insn_letter));
if (insn_class == NO_REGS
|| (in_p && insn_operand_constraint[(int) icode][!in_p][0] != '=')
@@ -463,7 +464,7 @@ push_secondary_reload (in_p, x, opnum, optional, reload_class, reload_mode,
class = insn_class;
t_mode = insn_operand_mode[(int) icode][2];
t_class = (t_letter == 'r' ? GENERAL_REGS
- : REG_CLASS_FROM_LETTER (t_letter));
+ : REG_CLASS_FROM_LETTER ((unsigned char) t_letter));
t_icode = icode;
icode = CODE_FOR_nothing;
}
@@ -537,6 +538,7 @@ push_secondary_reload (in_p, x, opnum, optional, reload_class, reload_mode,
/* Maybe we could combine these, but it seems too tricky. */
reload_nocombine[t_reload] = 1;
reload_in_reg[t_reload] = 0;
+ reload_out_reg[t_reload] = 0;
reload_opnum[t_reload] = opnum;
reload_when_needed[t_reload] = secondary_type;
reload_secondary_in_reload[t_reload] = -1;
@@ -606,6 +608,7 @@ push_secondary_reload (in_p, x, opnum, optional, reload_class, reload_mode,
/* Maybe we could combine these, but it seems too tricky. */
reload_nocombine[s_reload] = 1;
reload_in_reg[s_reload] = 0;
+ reload_out_reg[s_reload] = 0;
reload_opnum[s_reload] = opnum;
reload_when_needed[s_reload] = secondary_type;
reload_secondary_in_reload[s_reload] = in_p ? t_reload : -1;
@@ -746,6 +749,96 @@ find_valid_class (m1, n)
return best_class;
}
+/* Return the number of a previously made reload that can be combined with
+ a new one, or n_reloads if none of the existing reloads can be used.
+ OUT, CLASS, TYPE and OPNUM are the same arguments as passed to
+ push_reload, they determine the kind of the new reload that we try to
+ combine. P_IN points to the corresponding value of IN, which can be
+ modified by this function.
+ DONT_SHARE is nonzero if we can't share any input-only reload for IN. */
+static int
+find_reusable_reload (p_in, out, class, type, opnum, dont_share)
+ rtx *p_in, out;
+ enum reg_class class;
+ enum reload_type type;
+ int opnum, dont_share;
+{
+ rtx in = *p_in;
+ int i;
+ /* We can't merge two reloads if the output of either one is
+ earlyclobbered. */
+
+ if (earlyclobber_operand_p (out))
+ return n_reloads;
+
+ /* We can use an existing reload if the class is right
+ and at least one of IN and OUT is a match
+ and the other is at worst neutral.
+ (A zero compared against anything is neutral.)
+
+ If SMALL_REGISTER_CLASSES, don't use existing reloads unless they are
+ for the same thing since that can cause us to need more reload registers
+ than we otherwise would. */
+
+ for (i = 0; i < n_reloads; i++)
+ if ((reg_class_subset_p (class, reload_reg_class[i])
+ || reg_class_subset_p (reload_reg_class[i], class))
+ /* If the existing reload has a register, it must fit our class. */
+ && (reload_reg_rtx[i] == 0
+ || TEST_HARD_REG_BIT (reg_class_contents[(int) class],
+ true_regnum (reload_reg_rtx[i])))
+ && ((in != 0 && MATCHES (reload_in[i], in) && ! dont_share
+ && (out == 0 || reload_out[i] == 0 || MATCHES (reload_out[i], out)))
+ ||
+ (out != 0 && MATCHES (reload_out[i], out)
+ && (in == 0 || reload_in[i] == 0 || MATCHES (reload_in[i], in))))
+ && (reload_out[i] == 0 || ! earlyclobber_operand_p (reload_out[i]))
+ && (reg_class_size[(int) class] == 1 || SMALL_REGISTER_CLASSES)
+ && MERGABLE_RELOADS (type, reload_when_needed[i],
+ opnum, reload_opnum[i]))
+ return i;
+
+ /* Reloading a plain reg for input can match a reload to postincrement
+ that reg, since the postincrement's value is the right value.
+ Likewise, it can match a preincrement reload, since we regard
+ the preincrementation as happening before any ref in this insn
+ to that register. */
+ for (i = 0; i < n_reloads; i++)
+ if ((reg_class_subset_p (class, reload_reg_class[i])
+ || reg_class_subset_p (reload_reg_class[i], class))
+ /* If the existing reload has a register, it must fit our
+ class. */
+ && (reload_reg_rtx[i] == 0
+ || TEST_HARD_REG_BIT (reg_class_contents[(int) class],
+ true_regnum (reload_reg_rtx[i])))
+ && out == 0 && reload_out[i] == 0 && reload_in[i] != 0
+ && ((GET_CODE (in) == REG
+ && (GET_CODE (reload_in[i]) == POST_INC
+ || GET_CODE (reload_in[i]) == POST_DEC
+ || GET_CODE (reload_in[i]) == PRE_INC
+ || GET_CODE (reload_in[i]) == PRE_DEC)
+ && MATCHES (XEXP (reload_in[i], 0), in))
+ ||
+ (GET_CODE (reload_in[i]) == REG
+ && (GET_CODE (in) == POST_INC
+ || GET_CODE (in) == POST_DEC
+ || GET_CODE (in) == PRE_INC
+ || GET_CODE (in) == PRE_DEC)
+ && MATCHES (XEXP (in, 0), reload_in[i])))
+ && (reload_out[i] == 0 || ! earlyclobber_operand_p (reload_out[i]))
+ && (reg_class_size[(int) class] == 1 || SMALL_REGISTER_CLASSES)
+ && MERGABLE_RELOADS (type, reload_when_needed[i],
+ opnum, reload_opnum[i]))
+ {
+ /* Make sure reload_in ultimately has the increment,
+ not the plain register. */
+ if (GET_CODE (in) == REG)
+ *p_in = reload_in[i];
+ return i;
+ }
+ return n_reloads;
+}
+
/* Record one reload that needs to be performed.
IN is an rtx saying where the data are to be found before this instruction.
OUT says where they must be stored after the instruction.
@@ -782,7 +875,7 @@ find_valid_class (m1, n)
static int
push_reload (in, out, inloc, outloc, class,
inmode, outmode, strict_low, optional, opnum, type)
- register rtx in, out;
+ rtx in, out;
rtx *inloc, *outloc;
enum reg_class class;
enum machine_mode inmode, outmode;
@@ -871,9 +964,11 @@ push_reload (in, out, inloc, outloc, class,
the class whose registers cannot be referenced in a different size
and M1 is not the same size as M2. If SUBREG_WORD is nonzero, we
cannot reload just the inside since we might end up with the wrong
- register class. */
+ register class. But if it is inside a STRICT_LOW_PART, we have
+ no choice, so we hope we do get the right register class there. */
- if (in != 0 && GET_CODE (in) == SUBREG && SUBREG_WORD (in) == 0
+ if (in != 0 && GET_CODE (in) == SUBREG
+ && (SUBREG_WORD (in) == 0 || strict_low)
#ifdef CLASS_CANNOT_CHANGE_SIZE
&& class != CLASS_CANNOT_CHANGE_SIZE
#endif
@@ -990,7 +1085,8 @@ push_reload (in, out, inloc, outloc, class,
storing in a subreg is entitled to clobber it all
(except in the case of STRICT_LOW_PART,
and in that case the constraint should label it input-output.) */
- if (out != 0 && GET_CODE (out) == SUBREG && SUBREG_WORD (out) == 0
+ if (out != 0 && GET_CODE (out) == SUBREG
+ && (SUBREG_WORD (out) == 0 || strict_low)
#ifdef CLASS_CANNOT_CHANGE_SIZE
&& class != CLASS_CANNOT_CHANGE_SIZE
#endif
@@ -1171,72 +1267,14 @@ push_reload (in, out, inloc, outloc, class,
}
}
- if (class == NO_REGS)
+ /* Optional output reloads are always OK even if we have no register class,
+ since the function of these reloads is only to have spill_reg_store etc.
+ set, so that the storing insn can be deleted later. */
+ if (class == NO_REGS
+ && (optional == 0 || type != RELOAD_FOR_OUTPUT))
abort ();
- /* We can use an existing reload if the class is right
- and at least one of IN and OUT is a match
- and the other is at worst neutral.
- (A zero compared against anything is neutral.)
-
- If SMALL_REGISTER_CLASSES, don't use existing reloads unless they are
- for the same thing since that can cause us to need more reload registers
- than we otherwise would. */
-
- for (i = 0; i < n_reloads; i++)
- if ((reg_class_subset_p (class, reload_reg_class[i])
- || reg_class_subset_p (reload_reg_class[i], class))
- /* If the existing reload has a register, it must fit our class. */
- && (reload_reg_rtx[i] == 0
- || TEST_HARD_REG_BIT (reg_class_contents[(int) class],
- true_regnum (reload_reg_rtx[i])))
- && ((in != 0 && MATCHES (reload_in[i], in) && ! dont_share
- && (out == 0 || reload_out[i] == 0 || MATCHES (reload_out[i], out)))
- ||
- (out != 0 && MATCHES (reload_out[i], out)
- && (in == 0 || reload_in[i] == 0 || MATCHES (reload_in[i], in))))
- && (reg_class_size[(int) class] == 1 || SMALL_REGISTER_CLASSES)
- && MERGABLE_RELOADS (type, reload_when_needed[i],
- opnum, reload_opnum[i]))
- break;
-
- /* Reloading a plain reg for input can match a reload to postincrement
- that reg, since the postincrement's value is the right value.
- Likewise, it can match a preincrement reload, since we regard
- the preincrementation as happening before any ref in this insn
- to that register. */
- if (i == n_reloads)
- for (i = 0; i < n_reloads; i++)
- if ((reg_class_subset_p (class, reload_reg_class[i])
- || reg_class_subset_p (reload_reg_class[i], class))
- /* If the existing reload has a register, it must fit our class. */
- && (reload_reg_rtx[i] == 0
- || TEST_HARD_REG_BIT (reg_class_contents[(int) class],
- true_regnum (reload_reg_rtx[i])))
- && out == 0 && reload_out[i] == 0 && reload_in[i] != 0
- && ((GET_CODE (in) == REG
- && (GET_CODE (reload_in[i]) == POST_INC
- || GET_CODE (reload_in[i]) == POST_DEC
- || GET_CODE (reload_in[i]) == PRE_INC
- || GET_CODE (reload_in[i]) == PRE_DEC)
- && MATCHES (XEXP (reload_in[i], 0), in))
- ||
- (GET_CODE (reload_in[i]) == REG
- && (GET_CODE (in) == POST_INC
- || GET_CODE (in) == POST_DEC
- || GET_CODE (in) == PRE_INC
- || GET_CODE (in) == PRE_DEC)
- && MATCHES (XEXP (in, 0), reload_in[i])))
- && (reg_class_size[(int) class] == 1 || SMALL_REGISTER_CLASSES)
- && MERGABLE_RELOADS (type, reload_when_needed[i],
- opnum, reload_opnum[i]))
- {
- /* Make sure reload_in ultimately has the increment,
- not the plain register. */
- if (GET_CODE (in) == REG)
- in = reload_in[i];
- break;
- }
+ i = find_reusable_reload (&in, out, class, type, opnum, dont_share);
if (i == n_reloads)
{
@@ -1282,6 +1320,7 @@ push_reload (in, out, inloc, outloc, class,
reload_inc[i] = 0;
reload_nocombine[i] = 0;
reload_in_reg[i] = inloc ? *inloc : 0;
+ reload_out_reg[i] = outloc ? *outloc : 0;
reload_opnum[i] = opnum;
reload_when_needed[i] = type;
reload_secondary_in_reload[i] = secondary_in_reload;
@@ -1316,9 +1355,34 @@ push_reload (in, out, inloc, outloc, class,
&& GET_MODE_SIZE (outmode) > GET_MODE_SIZE (reload_outmode[i]))
reload_outmode[i] = outmode;
if (in != 0)
- reload_in[i] = in;
+ {
+ rtx in_reg = inloc ? *inloc : 0;
+ /* If we merge reloads for two distinct rtl expressions that
+ are identical in content, there might be duplicate address
+ reloads. Remove the extra set now, so that if we later find
+ that we can inherit this reload, we can get rid of the
+ address reloads altogether. */
+ if (reload_in[i] != in && rtx_equal_p (in, reload_in[i]))
+ {
+ /* We must keep the address reload with the lower operand
+ number alive. */
+ if (opnum > reload_opnum[i])
+ {
+ remove_address_replacements (in);
+ in = reload_in[i];
+ in_reg = reload_in_reg[i];
+ }
+ else
+ remove_address_replacements (reload_in[i]);
+ }
+ reload_in[i] = in;
+ reload_in_reg[i] = in_reg;
+ }
if (out != 0)
- reload_out[i] = out;
+ {
+ reload_out[i] = out;
+ reload_out_reg[i] = outloc ? *outloc : 0;
+ }
if (reg_class_subset_p (class, reload_reg_class[i]))
reload_reg_class[i] = class;
reload_optional[i] &= optional;
@@ -1507,19 +1571,69 @@ transfer_replacements (to, from)
replacements[i].what = to;
}
-/* Remove all replacements in reload FROM. */
-void
-remove_replacements (from)
- int from;
+/* IN_RTX is the value loaded by a reload that we now decided to inherit,
+ or a subpart of it. If we have any replacements registered for IN_RTX,
+ cancel the reloads that were supposed to load them.
+ Return non-zero if we canceled any reloads. */
+int
+remove_address_replacements (in_rtx)
+ rtx in_rtx;
{
int i, j;
+ char reload_flags[MAX_RELOADS];
+ int something_changed = 0;
+ bzero (reload_flags, sizeof reload_flags);
for (i = 0, j = 0; i < n_replacements; i++)
{
- if (replacements[i].what == from)
- continue;
- replacements[j++] = replacements[i];
+ if (loc_mentioned_in_p (replacements[i].where, in_rtx))
+ reload_flags[replacements[i].what] |= 1;
+ else
+ {
+ replacements[j++] = replacements[i];
+ reload_flags[replacements[i].what] |= 2;
+ }
+ }
+ /* Note that the following store must be done before the recursive calls. */
+ n_replacements = j;
+
+ for (i = n_reloads - 1; i >= 0; i--)
+ {
+ if (reload_flags[i] == 1)
+ {
+ deallocate_reload_reg (i);
+ remove_address_replacements (reload_in[i]);
+ reload_in[i] = 0;
+ something_changed = 1;
+ }
}
+ return something_changed;
+}
+
+/* Return non-zero if IN contains a piece of rtl that has the address LOC */
+static int
+loc_mentioned_in_p (loc, in)
+ rtx *loc, in;
+{
+ enum rtx_code code = GET_CODE (in);
+ char *fmt = GET_RTX_FORMAT (code);
+ int i, j;
+
+ for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
+ {
+ if (loc == &XEXP (in, i))
+ return 1;
+ if (fmt[i] == 'e')
+ {
+ if (loc_mentioned_in_p (loc, XEXP (in, i)))
+ return 1;
+ }
+ else if (fmt[i] == 'E')
+ for (j = XVECLEN (in, i) - 1; i >= 0; i--)
+ if (loc_mentioned_in_p (loc, XVECEXP (in, i, j)))
+ return 1;
+ }
+ return 0;
}
/* If there is only one output reload, and it is not for an earlyclobber
@@ -1618,6 +1732,7 @@ combine_reloads ()
/* We have found a reload to combine with! */
reload_out[i] = reload_out[output_reload];
+ reload_out_reg[i] = reload_out_reg[output_reload];
reload_outmode[i] = reload_outmode[output_reload];
/* Mark the old output reload as inoperative. */
reload_out[output_reload] = 0;
@@ -2081,19 +2196,6 @@ operands_match_p (x, y)
return 1 + success_2;
}
-/* Return the number of times character C occurs in string S. */
-
-int
-n_occurrences (c, s)
- int c;
- char *s;
-{
- int n = 0;
- while (*s)
- n += (*s++ == c);
- return n;
-}
-
/* Describe the range of registers or memory referenced by X.
If X is a register, set REG_FLAG and put the first register
number into START and the last plus one into END.
@@ -2300,9 +2402,12 @@ safe_from_earlyclobber (op, clobber)
RELOAD_REG_P if nonzero is a vector indexed by hard reg number
which is nonnegative if the reg has been commandeered for reloading into.
It is copied into STATIC_RELOAD_REG_P and referenced from there
- by various subroutines. */
+ by various subroutines.
-void
+ Return TRUE if some operands need to be changed, because of swapping
+ commutative operands, reg_equiv_address substitution, or whatever. */
+
+int
find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
rtx insn;
int replace, ind_levels;
@@ -2314,8 +2419,6 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
register int insn_code_number;
register int i, j;
int noperands;
- /* These are the constraints for the insn. We don't change them. */
- char *constraints1[MAX_RECOG_OPERANDS];
/* These start out as the constraints for the insn
and they are chewed up as we consider alternatives. */
char *constraints[MAX_RECOG_OPERANDS];
@@ -2358,15 +2461,14 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
rtx set = single_set (insn);
int goal_earlyclobber, this_earlyclobber;
enum machine_mode operand_mode[MAX_RECOG_OPERANDS];
+ int retval = 0;
/* Cache the last regno for the last pseudo we did an output reload
for in case the next insn uses it. */
static int last_output_reload_regno = -1;
this_insn = insn;
- this_insn_is_asm = 0; /* Tentative. */
n_reloads = 0;
n_replacements = 0;
- n_memlocs = 0;
n_earlyclobbers = 0;
replace_reloads = replace;
hard_regs_live_known = live_known;
@@ -2392,94 +2494,34 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
bzero ((char *) secondary_memlocs_elim, sizeof secondary_memlocs_elim);
#endif
- /* Find what kind of insn this is. NOPERANDS gets number of operands.
- Make OPERANDS point to a vector of operand values.
- Make OPERAND_LOCS point to a vector of pointers to
- where the operands were found.
- Fill CONSTRAINTS and CONSTRAINTS1 with pointers to the
- constraint-strings for this insn.
- Return if the insn needs no reload processing. */
-
- switch (GET_CODE (body))
- {
- case USE:
- case CLOBBER:
- case ASM_INPUT:
- case ADDR_VEC:
- case ADDR_DIFF_VEC:
- return;
-
- case SET:
- /* Dispose quickly of (set (reg..) (reg..)) if both have hard regs and it
- is cheap to move between them. If it is not, there may not be an insn
- to do the copy, so we may need a reload. */
- if (GET_CODE (SET_DEST (body)) == REG
- && REGNO (SET_DEST (body)) < FIRST_PSEUDO_REGISTER
- && GET_CODE (SET_SRC (body)) == REG
- && REGNO (SET_SRC (body)) < FIRST_PSEUDO_REGISTER
- && REGISTER_MOVE_COST (REGNO_REG_CLASS (REGNO (SET_SRC (body))),
- REGNO_REG_CLASS (REGNO (SET_DEST (body)))) == 2)
- return;
- case PARALLEL:
- case ASM_OPERANDS:
- reload_n_operands = noperands = asm_noperands (body);
- if (noperands >= 0)
- {
- /* This insn is an `asm' with operands. */
-
- insn_code_number = -1;
- this_insn_is_asm = 1;
+ /* Dispose quickly of (set (reg..) (reg..)) if both have hard regs and it
+ is cheap to move between them. If it is not, there may not be an insn
+ to do the copy, so we may need a reload. */
+ if (GET_CODE (body) == SET
+ && GET_CODE (SET_DEST (body)) == REG
+ && REGNO (SET_DEST (body)) < FIRST_PSEUDO_REGISTER
+ && GET_CODE (SET_SRC (body)) == REG
+ && REGNO (SET_SRC (body)) < FIRST_PSEUDO_REGISTER
+ && REGISTER_MOVE_COST (REGNO_REG_CLASS (REGNO (SET_SRC (body))),
+ REGNO_REG_CLASS (REGNO (SET_DEST (body)))) == 2)
+ return 0;
- /* expand_asm_operands makes sure there aren't too many operands. */
- if (noperands > MAX_RECOG_OPERANDS)
- abort ();
+ extract_insn (insn);
- /* Now get the operand values and constraints out of the insn. */
+ noperands = reload_n_operands = recog_n_operands;
+ n_alternatives = recog_n_alternatives;
- decode_asm_operands (body, recog_operand, recog_operand_loc,
- constraints, operand_mode);
- if (noperands > 0)
- {
- bcopy ((char *) constraints, (char *) constraints1,
- noperands * sizeof (char *));
- n_alternatives = n_occurrences (',', constraints[0]) + 1;
- for (i = 1; i < noperands; i++)
- if (n_alternatives != n_occurrences (',', constraints[i]) + 1)
- {
- error_for_asm (insn, "operand constraints differ in number of alternatives");
- /* Avoid further trouble with this insn. */
- PATTERN (insn) = gen_rtx_USE (VOIDmode, const0_rtx);
- n_reloads = 0;
- return;
- }
- }
- break;
- }
-
- default:
- /* Ordinary insn: recognize it, get the operands via insn_extract
- and get the constraints. */
+ /* Just return "no reloads" if insn has no operands with constraints. */
+ if (noperands == 0 || n_alternatives == 0)
+ return 0;
- insn_code_number = recog_memoized (insn);
- if (insn_code_number < 0)
- fatal_insn_not_found (insn);
+ insn_code_number = INSN_CODE (insn);
+ this_insn_is_asm = insn_code_number < 0;
- reload_n_operands = noperands = insn_n_operands[insn_code_number];
- n_alternatives = insn_n_alternatives[insn_code_number];
- /* Just return "no reloads" if insn has no operands with constraints. */
- if (n_alternatives == 0)
- return;
- insn_extract (insn);
- for (i = 0; i < noperands; i++)
- {
- constraints[i] = constraints1[i]
- = insn_operand_constraint[insn_code_number][i];
- operand_mode[i] = insn_operand_mode[insn_code_number][i];
- }
- }
-
- if (noperands == 0)
- return;
+ bcopy ((char *) recog_operand_mode, (char *) operand_mode,
+ noperands * sizeof (enum machine_mode));
+ bcopy ((char *) recog_constraints, (char *) constraints,
+ noperands * sizeof (char *));
commutative = -1;
@@ -2511,15 +2553,9 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
{
/* The last operand should not be marked commutative. */
if (i == noperands - 1)
- {
- if (this_insn_is_asm)
- warning_for_asm (this_insn,
- "`%%' constraint used with last operand");
- else
- abort ();
- }
- else
- commutative = i;
+ abort ();
+
+ commutative = i;
}
else if (c >= '0' && c <= '9')
{
@@ -2529,13 +2565,7 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
/* An operand may not match itself. */
if (c == i)
- {
- if (this_insn_is_asm)
- warning_for_asm (this_insn,
- "operand %d has constraint %d", i, c);
- else
- abort ();
- }
+ abort ();
/* If C can be commuted with C+1, and C might need to match I,
then C+1 might also need to match I. */
@@ -2599,21 +2629,21 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
|| GET_CODE (recog_operand[i]) == PLUS))
{
INSN_CODE (insn) = -1;
- find_reloads (insn, replace, ind_levels, live_known,
- reload_reg_p);
- return;
+ retval = find_reloads (insn, replace, ind_levels, live_known,
+ reload_reg_p);
+ return retval;
}
substed_operand[i] = recog_operand[i] = *recog_operand_loc[i];
}
else if (code == MEM)
{
- if (find_reloads_address (GET_MODE (recog_operand[i]),
+ address_reloaded[i]
+ = find_reloads_address (GET_MODE (recog_operand[i]),
recog_operand_loc[i],
XEXP (recog_operand[i], 0),
&XEXP (recog_operand[i], 0),
- i, address_type[i], ind_levels, insn))
- address_reloaded[i] = 1;
+ i, address_type[i], ind_levels, insn);
substed_operand[i] = recog_operand[i] = *recog_operand_loc[i];
}
else if (code == SUBREG)
@@ -2623,14 +2653,16 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
= find_reloads_toplev (recog_operand[i], i, address_type[i],
ind_levels,
set != 0
- && &SET_DEST (set) == recog_operand_loc[i]);
+ && &SET_DEST (set) == recog_operand_loc[i],
+ insn);
/* If we made a MEM to load (a part of) the stackslot of a pseudo
that didn't get a hard register, emit a USE with a REG_EQUAL
note in front so that we might inherit a previous, possibly
wider reload. */
- if (GET_CODE (op) == MEM
+ if (replace
+ && GET_CODE (op) == MEM
&& GET_CODE (reg) == REG
&& (GET_MODE_SIZE (GET_MODE (reg))
>= GET_MODE_SIZE (GET_MODE (op))))
@@ -2638,15 +2670,15 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
= gen_rtx_EXPR_LIST (REG_EQUAL,
reg_equiv_memory_loc[REGNO (reg)], NULL_RTX);
- substed_operand[i] = recog_operand[i] = *recog_operand_loc[i] = op;
+ substed_operand[i] = recog_operand[i] = op;
}
else if (code == PLUS || GET_RTX_CLASS (code) == '1')
/* We can get a PLUS as an "operand" as a result of register
elimination. See eliminate_regs and gen_reload. We handle
a unary operator by reloading the operand. */
- substed_operand[i] = recog_operand[i] = *recog_operand_loc[i]
+ substed_operand[i] = recog_operand[i]
= find_reloads_toplev (recog_operand[i], i, address_type[i],
- ind_levels, 0);
+ ind_levels, 0, insn);
else if (code == REG)
{
/* This is equivalent to calling find_reloads_toplev.
@@ -2668,44 +2700,13 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
substed_operand[i] = recog_operand[i]
= reg_equiv_constant[regno];
}
-#if 0 /* This might screw code in reload1.c to delete prior output-reload
- that feeds this insn. */
- if (reg_equiv_mem[regno] != 0)
+ if (reg_equiv_memory_loc[regno] != 0
+ && (reg_equiv_address[regno] != 0 || num_not_at_initial_offset))
+ /* We need not give a valid is_set_dest argument since the case
+ of a constant equivalence was checked above. */
substed_operand[i] = recog_operand[i]
- = reg_equiv_mem[regno];
-#endif
- if (reg_equiv_address[regno] != 0)
- {
- /* If reg_equiv_address is not a constant address, copy it,
- since it may be shared. */
- /* We must rerun eliminate_regs, in case the elimination
- offsets have changed. */
- rtx address = XEXP (eliminate_regs (reg_equiv_memory_loc[regno],
- 0, NULL_RTX),
- 0);
-
- if (rtx_varies_p (address))
- address = copy_rtx (address);
-
- /* Emit a USE that shows what register is being used/modified. */
- REG_NOTES (emit_insn_before (gen_rtx_USE (VOIDmode,
- recog_operand[i]),
- insn))
- = gen_rtx_EXPR_LIST (REG_EQUAL,
- reg_equiv_memory_loc[regno],
- NULL_RTX);
-
- *recog_operand_loc[i] = recog_operand[i]
- = gen_rtx_MEM (GET_MODE (recog_operand[i]), address);
- RTX_UNCHANGING_P (recog_operand[i])
- = RTX_UNCHANGING_P (regno_reg_rtx[regno]);
- find_reloads_address (GET_MODE (recog_operand[i]),
- recog_operand_loc[i],
- XEXP (recog_operand[i], 0),
- &XEXP (recog_operand[i], 0),
- i, address_type[i], ind_levels, insn);
- substed_operand[i] = recog_operand[i] = *recog_operand_loc[i];
- }
+ = find_reloads_toplev (recog_operand[i], i, address_type[i],
+ ind_levels, 0, insn);
}
/* If the operand is still a register (we didn't replace it with an
equivalent), get the preferred class to reload it into. */
@@ -2718,6 +2719,15 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
&& reg_alternate_class (REGNO (recog_operand[i])) == NO_REGS);
}
+#ifdef HAVE_cc0
+ /* If we made any reloads for addresses, see if they violate a
+ "no input reloads" requirement for this insn. */
+ if (no_input_reloads)
+ for (i = 0; i < n_reloads; i++)
+ if (reload_in[i] != 0)
+ abort ();
+#endif
+
/* If this is simply a copy from operand 1 to operand 0, merge the
preferred classes for the operands. */
if (set != 0 && noperands >= 2 && recog_operand[0] == SET_DEST (set)
@@ -3055,24 +3065,11 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
/* If IND_LEVELS, find_reloads_address won't reload a
pseudo that didn't get a hard reg, so we have to
reject that case. */
- && (ind_levels ? offsettable_memref_p (operand)
- : offsettable_nonstrict_memref_p (operand)))
- /* A reloaded auto-increment address is offsettable,
- because it is now just a simple register indirect. */
- || (GET_CODE (operand) == MEM
- && address_reloaded[i]
- && (GET_CODE (XEXP (operand, 0)) == PRE_INC
- || GET_CODE (XEXP (operand, 0)) == PRE_DEC
- || GET_CODE (XEXP (operand, 0)) == POST_INC
- || GET_CODE (XEXP (operand, 0)) == POST_DEC))
- /* Certain mem addresses will become offsettable
- after they themselves are reloaded. This is important;
- we don't want our own handling of unoffsettables
- to override the handling of reg_equiv_address. */
- || (GET_CODE (operand) == MEM
- && GET_CODE (XEXP (operand, 0)) == REG
- && (ind_levels == 0
- || reg_equiv_address[REGNO (XEXP (operand, 0))] != 0))
+ && ((ind_levels ? offsettable_memref_p (operand)
+ : offsettable_nonstrict_memref_p (operand))
+ /* A reloaded address is offsettable because it is now
+ just a simple register indirect. */
+ || address_reloaded[i]))
|| (GET_CODE (operand) == REG
&& REGNO (operand) >= FIRST_PSEUDO_REGISTER
&& reg_renumber[REGNO (operand)] < 0
@@ -3373,14 +3370,7 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
early_data = decompose (recog_operand[i]);
if (modified[i] == RELOAD_READ)
- {
- if (this_insn_is_asm)
- warning_for_asm (this_insn,
- "`&' constraint used with input operand");
- else
- abort ();
- continue;
- }
+ abort ();
if (this_alternative[i] == NO_REGS)
{
@@ -3398,7 +3388,7 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
|| modified[j] != RELOAD_WRITE)
&& j != i
/* Ignore things like match_operator operands. */
- && *constraints1[j] != 0
+ && *recog_constraints[j] != 0
/* Don't count an input operand that is constrained to match
the early clobber operand. */
&& ! (this_alternative_matches[j] == i
@@ -3515,7 +3505,7 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
pref_or_nothing[commutative] = pref_or_nothing[commutative + 1];
pref_or_nothing[commutative + 1] = t;
- bcopy ((char *) constraints1, (char *) constraints,
+ bcopy ((char *) recog_constraints, (char *) constraints,
noperands * sizeof (char *));
goto try_swapped;
}
@@ -3535,12 +3525,12 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
{
/* No alternative works with reloads?? */
if (insn_code_number >= 0)
- abort ();
+ fatal_insn ("Unable to generate reloads for:", insn);
error_for_asm (insn, "inconsistent operand constraints in an `asm'");
/* Avoid further trouble with this insn. */
PATTERN (insn) = gen_rtx_USE (VOIDmode, const0_rtx);
n_reloads = 0;
- return;
+ return 0;
}
/* Jump to `finish' from above if all operands are valid already.
@@ -3575,6 +3565,9 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
tem = recog_operand[commutative];
recog_operand[commutative] = recog_operand[commutative + 1];
recog_operand[commutative + 1] = tem;
+ tem = *recog_operand_loc[commutative];
+ *recog_operand_loc[commutative] = *recog_operand_loc[commutative+1];
+ *recog_operand_loc[commutative+1] = tem;
for (i = 0; i < n_reloads; i++)
{
@@ -3585,14 +3578,8 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
}
}
- /* Perform whatever substitutions on the operands we are supposed
- to make due to commutativity or replacement of registers
- with equivalent constants or memory slots. */
-
for (i = 0; i < noperands; i++)
{
- *recog_operand_loc[i] = substed_operand[i];
- /* While we are looping on operands, initialize this. */
operand_reloadnum[i] = -1;
/* If this is an earlyclobber operand, we need to widen the scope.
@@ -3631,11 +3618,11 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
|| no_input_reloads)
&& operand_mode[i] != VOIDmode)
{
- *recog_operand_loc[i] = recog_operand[i]
+ substed_operand[i] = recog_operand[i]
= find_reloads_toplev (force_const_mem (operand_mode[i],
recog_operand[i]),
- i, address_type[i], ind_levels, 0);
- if (alternative_allows_memconst (constraints1[i],
+ i, address_type[i], ind_levels, 0, insn);
+ if (alternative_allows_memconst (recog_constraints[i],
goal_alternative_number))
goal_alternative_win[i] = 1;
}
@@ -3759,7 +3746,7 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
/* Avoid further trouble with this insn. */
PATTERN (insn) = gen_rtx_USE (VOIDmode, const0_rtx);
n_reloads = 0;
- return;
+ return 0;
}
}
else if (goal_alternative_matched[i] < 0
@@ -3777,13 +3764,21 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
if ((GET_CODE (operand) == MEM
|| (GET_CODE (operand) == REG
&& REGNO (operand) >= FIRST_PSEUDO_REGISTER))
- && (enum reg_class) goal_alternative[i] != NO_REGS
+ /* If this is only for an output, the optional reload would not
+ actually cause us to use a register now, just note that
+ something is stored here. */
+ && ((enum reg_class) goal_alternative[i] != NO_REGS
+ || modified[i] == RELOAD_WRITE)
&& ! no_input_reloads
- /* Optional output reloads don't do anything and we mustn't
- make in-out reloads on insns that are not permitted output
- reloads. */
+ /* An optional output reload might allow to delete INSN later.
+ We mustn't make in-out reloads on insns that are not permitted
+ output reloads.
+ If this is an asm, we can't delete it; we must not even call
+ push_reload for an optional output reload in this case,
+ because we can't be sure that the constraint allows a register,
+ and push_reload verifies the constraints for asms. */
&& (modified[i] == RELOAD_READ
- || (modified[i] == RELOAD_READ_WRITE && ! no_output_reloads)))
+ || (! no_output_reloads && ! this_insn_is_asm)))
operand_reloadnum[i]
= push_reload (modified[i] != RELOAD_WRITE ? recog_operand[i] : 0,
modified[i] != RELOAD_READ ? recog_operand[i] : 0,
@@ -3799,6 +3794,24 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
(insn_code_number < 0 ? 0
: insn_operand_strict_low[insn_code_number][i]),
1, i, operand_type[i]);
+ /* If a memory reference remains, yet we can't make an optional
+ reload, check if this is actually a pseudo register reference;
+ we then need to emit a USE and/or a CLOBBER so that reload
+ inheritance will do the right thing. */
+ else if (replace && GET_CODE (operand) == MEM)
+ {
+ operand = *recog_operand_loc[i];
+
+ while (GET_CODE (operand) == SUBREG)
+ operand = XEXP (operand, 0);
+ if (GET_CODE (operand) == REG)
+ {
+ if (modified[i] != RELOAD_WRITE)
+ emit_insn_before (gen_rtx_USE (VOIDmode, operand), insn);
+ if (modified[i] != RELOAD_READ)
+ emit_insn_after (gen_rtx_CLOBBER (VOIDmode, operand), insn);
+ }
+ }
}
else if (goal_alternative_matches[i] >= 0
&& goal_alternative_win[goal_alternative_matches[i]]
@@ -3830,6 +3843,37 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
0, 1, goal_alternative_matches[i], RELOAD_OTHER);
}
+ /* Perform whatever substitutions on the operands we are supposed
+ to make due to commutativity or replacement of registers
+ with equivalent constants or memory slots. */
+
+ for (i = 0; i < noperands; i++)
+ {
+ /* We only do this on the last pass through reload, because it is
+ possible for some data (like reg_equiv_address) to be changed during
+ later passes. Moreover, we loose the opportunity to get a useful
+ reload_{in,out}_reg when we do these replacements. */
+
+ if (replace)
+ {
+ rtx substitution = substed_operand[i];
+
+ *recog_operand_loc[i] = substitution;
+
+ /* If we're replacing an operand with a LABEL_REF, we need
+ to make sure that there's a REG_LABEL note attached to
+ this instruction. */
+ if (GET_CODE (insn) != JUMP_INSN
+ && GET_CODE (substitution) == LABEL_REF
+ && !find_reg_note (insn, REG_LABEL, XEXP (substitution, 0)))
+ REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_LABEL,
+ XEXP (substitution, 0),
+ REG_NOTES (insn));
+ }
+ else
+ retval |= (substed_operand[i] != *recog_operand_loc[i]);
+ }
+
/* If this insn pattern contains any MATCH_DUP's, make sure that
they will be substituted if the operands they match are substituted.
Also do now any substitutions we already did on the operands.
@@ -3984,7 +4028,11 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
= RELOAD_FOR_OPADDR_ADDR;
}
- reload_when_needed[i] = RELOAD_FOR_OPERAND_ADDRESS;
+ if (reload_when_needed[i] == RELOAD_FOR_INPADDR_ADDRESS
+ || reload_when_needed[i] == RELOAD_FOR_OUTADDR_ADDRESS)
+ reload_when_needed[i] = RELOAD_FOR_OPADDR_ADDR;
+ else
+ reload_when_needed[i] = RELOAD_FOR_OPERAND_ADDRESS;
}
if ((reload_when_needed[i] == RELOAD_FOR_INPUT_ADDRESS
@@ -4098,7 +4146,9 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
for (j = n_reloads - 1; j > first_num; j--)
{
if (reload_when_needed[j] == type
- && reg_mentioned_p (reload_in[i], reload_in[j]))
+ && (reload_secondary_p[i]
+ ? reload_secondary_in_reload[j] == i
+ : reg_mentioned_p (reload_in[i], reload_in[j])))
{
reload_when_needed[i] = type;
break;
@@ -4199,6 +4249,7 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
int goal_earlyclobber = 0; /* Always 0, to make combine_reloads happen. */
register int i;
rtx body = PATTERN (insn);
+ int retval = 0;
n_reloads = 0;
n_replacements = 0;
@@ -4206,50 +4257,11 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
replace_reloads = replace;
this_insn = insn;
- /* Find what kind of insn this is. NOPERANDS gets number of operands.
- Store the operand values in RECOG_OPERAND and the locations
- of the words in the insn that point to them in RECOG_OPERAND_LOC.
- Return if the insn needs no reload processing. */
-
- switch (GET_CODE (body))
- {
- case USE:
- case CLOBBER:
- case ASM_INPUT:
- case ADDR_VEC:
- case ADDR_DIFF_VEC:
- return;
-
- case PARALLEL:
- case SET:
- noperands = asm_noperands (body);
- if (noperands >= 0)
- {
- /* This insn is an `asm' with operands.
- First, find out how many operands, and allocate space. */
-
- insn_code_number = -1;
- /* ??? This is a bug! ???
- Give up and delete this insn if it has too many operands. */
- if (noperands > MAX_RECOG_OPERANDS)
- abort ();
+ extract_insn (insn);
- /* Now get the operand values out of the insn. */
-
- decode_asm_operands (body, recog_operand, recog_operand_loc,
- NULL_PTR, NULL_PTR);
- break;
- }
-
- default:
- /* Ordinary insn: recognize it, allocate space for operands and
- constraints, and get them out via insn_extract. */
-
- insn_code_number = recog_memoized (insn);
- noperands = insn_n_operands[insn_code_number];
- insn_extract (insn);
- }
+ noperands = reload_n_operands = recog_n_operands;
+ /* Return if the insn needs no reload processing. */
if (noperands == 0)
return;
@@ -4298,6 +4310,7 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
if (!goal_earlyclobber)
combine_reloads ();
#endif /* no REGISTER_CONSTRAINTS */
+ return retval;
}
/* Return 1 if alternative number ALTNUM in constraint-string CONSTRAINT
@@ -4305,7 +4318,7 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
static int
alternative_allows_memconst (constraint, altnum)
- char *constraint;
+ const char *constraint;
int altnum;
{
register int c;
@@ -4336,20 +4349,26 @@ alternative_allows_memconst (constraint, altnum)
OPNUM and TYPE identify the purpose of the reload.
IS_SET_DEST is true if X is the destination of a SET, which is not
- appropriate to be replaced by a constant. */
+ appropriate to be replaced by a constant.
+
+ INSN, if nonzero, is the insn in which we do the reload. It is used
+ to determine if we may generate output reloads, and where to put USEs
+ for pseudos that we have to replace with stack slots. */
static rtx
-find_reloads_toplev (x, opnum, type, ind_levels, is_set_dest)
+find_reloads_toplev (x, opnum, type, ind_levels, is_set_dest, insn)
rtx x;
int opnum;
enum reload_type type;
int ind_levels;
int is_set_dest;
+ rtx insn;
{
register RTX_CODE code = GET_CODE (x);
register char *fmt = GET_RTX_FORMAT (code);
register int i;
+ int copied;
if (code == REG)
{
@@ -4363,23 +4382,22 @@ find_reloads_toplev (x, opnum, type, ind_levels, is_set_dest)
else if (reg_equiv_mem[regno] != 0)
x = reg_equiv_mem[regno];
#endif
- else if (reg_equiv_address[regno] != 0)
+ else if (reg_equiv_memory_loc[regno]
+ && (reg_equiv_address[regno] != 0 || num_not_at_initial_offset))
{
- /* If reg_equiv_address varies, it may be shared, so copy it. */
- /* We must rerun eliminate_regs, in case the elimination
- offsets have changed. */
- rtx addr = XEXP (eliminate_regs (reg_equiv_memory_loc[regno], 0,
- NULL_RTX),
- 0);
-
- if (rtx_varies_p (addr))
- addr = copy_rtx (addr);
-
- x = gen_rtx_MEM (GET_MODE (x), addr);
- RTX_UNCHANGING_P (x) = RTX_UNCHANGING_P (regno_reg_rtx[regno]);
- find_reloads_address (GET_MODE (x), NULL_PTR,
- XEXP (x, 0),
- &XEXP (x, 0), opnum, type, ind_levels, 0);
+ rtx mem = make_memloc (x, regno);
+ if (reg_equiv_address[regno]
+ || ! rtx_equal_p (mem, reg_equiv_mem[regno]))
+ {
+ /* If this is not a toplevel operand, find_reloads doesn't see
+ this substitution. We have to emit a USE of the pseudo so
+ that delete_output_reload can see it. */
+ if (replace_reloads && recog_operand[opnum] != x)
+ emit_insn_before (gen_rtx_USE (VOIDmode, x), insn);
+ x = mem;
+ find_reloads_address (GET_MODE (x), &x, XEXP (x, 0), &XEXP (x, 0),
+ opnum, type, ind_levels, insn);
+ }
}
return x;
}
@@ -4387,7 +4405,7 @@ find_reloads_toplev (x, opnum, type, ind_levels, is_set_dest)
{
rtx tem = x;
find_reloads_address (GET_MODE (x), &tem, XEXP (x, 0), &XEXP (x, 0),
- opnum, type, ind_levels, 0);
+ opnum, type, ind_levels, insn);
return tem;
}
@@ -4481,37 +4499,30 @@ find_reloads_toplev (x, opnum, type, ind_levels, is_set_dest)
|| (reg_equiv_mem[regno] != 0
&& (! strict_memory_address_p (GET_MODE (x),
XEXP (reg_equiv_mem[regno], 0))
- || ! offsettable_memref_p (reg_equiv_mem[regno])))))
- {
- int offset = SUBREG_WORD (x) * UNITS_PER_WORD;
- /* We must rerun eliminate_regs, in case the elimination
- offsets have changed. */
- rtx addr = XEXP (eliminate_regs (reg_equiv_memory_loc[regno], 0,
- NULL_RTX),
- 0);
- if (BYTES_BIG_ENDIAN)
- {
- int size;
- size = GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)));
- offset += MIN (size, UNITS_PER_WORD);
- size = GET_MODE_SIZE (GET_MODE (x));
- offset -= MIN (size, UNITS_PER_WORD);
- }
- addr = plus_constant (addr, offset);
- x = gen_rtx_MEM (GET_MODE (x), addr);
- RTX_UNCHANGING_P (x) = RTX_UNCHANGING_P (regno_reg_rtx[regno]);
- find_reloads_address (GET_MODE (x), NULL_PTR,
- XEXP (x, 0),
- &XEXP (x, 0), opnum, type, ind_levels, 0);
- }
-
+ || ! offsettable_memref_p (reg_equiv_mem[regno])
+ || num_not_at_initial_offset))))
+ x = find_reloads_subreg_address (x, 1, opnum, type, ind_levels,
+ insn);
}
- for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
+ for (copied = 0, i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
{
if (fmt[i] == 'e')
- XEXP (x, i) = find_reloads_toplev (XEXP (x, i), opnum, type,
- ind_levels, is_set_dest);
+ {
+ rtx new_part = find_reloads_toplev (XEXP (x, i), opnum, type,
+ ind_levels, is_set_dest, insn);
+ /* If we have replaced a reg with it's equivalent memory loc -
+ that can still be handled here e.g. if it's in a paradoxical
+ subreg - we must make the change in a copy, rather than using
+ a destructive change. This way, find_reloads can still elect
+ not to do the change. */
+ if (new_part != XEXP (x, i) && ! CONSTANT_P (new_part) && ! copied)
+ {
+ x = shallow_copy_rtx (x);
+ copied = 1;
+ }
+ XEXP (x, i) = new_part;
+ }
}
return x;
}
@@ -4524,22 +4535,10 @@ make_memloc (ad, regno)
rtx ad;
int regno;
{
-#if 0
- register int i;
-#endif
/* We must rerun eliminate_regs, in case the elimination
offsets have changed. */
- rtx tem = XEXP (eliminate_regs (reg_equiv_memory_loc[regno], 0, NULL_RTX), 0);
-
-#if 0 /* We cannot safely reuse a memloc made here;
- if the pseudo appears twice, and its mem needs a reload,
- it gets two separate reloads assigned, but it only
- gets substituted with the second of them;
- then it can get used before that reload reg gets loaded up. */
- for (i = 0; i < n_memlocs; i++)
- if (rtx_equal_p (tem, XEXP (memlocs[i], 0)))
- return memlocs[i];
-#endif
+ rtx tem
+ = XEXP (eliminate_regs (reg_equiv_memory_loc[regno], 0, NULL_RTX), 0);
/* If TEM might contain a pseudo, we must copy it to avoid
modifying it when we do the substitution for the reload. */
@@ -4548,7 +4547,6 @@ make_memloc (ad, regno)
tem = gen_rtx_MEM (GET_MODE (ad), tem);
RTX_UNCHANGING_P (tem) = RTX_UNCHANGING_P (regno_reg_rtx[regno]);
- memlocs[n_memlocs++] = tem;
return tem;
}
@@ -4564,7 +4562,8 @@ make_memloc (ad, regno)
supports.
INSN, if nonzero, is the insn in which we do the reload. It is used
- to determine if we may generate output reloads.
+ to determine if we may generate output reloads, and where to put USEs
+ for pseudos that we have to replace with stack slots.
Value is nonzero if this address is reloaded or replaced as a whole.
This is interesting to the caller if the address is an autoincrement.
@@ -4587,6 +4586,7 @@ find_reloads_address (mode, memrefloc, ad, loc, opnum, type, ind_levels, insn)
rtx insn;
{
register int regno;
+ int removed_and = 0;
rtx tem;
/* If the address is a register, see if it is a legitimate address and
@@ -4601,35 +4601,51 @@ find_reloads_address (mode, memrefloc, ad, loc, opnum, type, ind_levels, insn)
&& strict_memory_address_p (mode, reg_equiv_constant[regno]))
{
*loc = ad = reg_equiv_constant[regno];
- return 1;
+ return 0;
}
- else if (reg_equiv_address[regno] != 0)
+ tem = reg_equiv_memory_loc[regno];
+ if (tem != 0)
{
- tem = make_memloc (ad, regno);
- find_reloads_address (GET_MODE (tem), NULL_PTR, XEXP (tem, 0),
- &XEXP (tem, 0), opnum, ADDR_TYPE (type),
- ind_levels, insn);
- push_reload (tem, NULL_RTX, loc, NULL_PTR,
- reload_address_base_reg_class,
- GET_MODE (ad), VOIDmode, 0, 0,
- opnum, type);
- return 1;
+ if (reg_equiv_address[regno] != 0 || num_not_at_initial_offset)
+ {
+ tem = make_memloc (ad, regno);
+ if (! strict_memory_address_p (GET_MODE (tem), XEXP (tem, 0)))
+ {
+ find_reloads_address (GET_MODE (tem), NULL_PTR, XEXP (tem, 0),
+ &XEXP (tem, 0), opnum, ADDR_TYPE (type),
+ ind_levels, insn);
+ }
+ /* We can avoid a reload if the register's equivalent memory
+ expression is valid as an indirect memory address.
+ But not all addresses are valid in a mem used as an indirect
+ address: only reg or reg+constant. */
+
+ if (ind_levels > 0
+ && strict_memory_address_p (mode, tem)
+ && (GET_CODE (XEXP (tem, 0)) == REG
+ || (GET_CODE (XEXP (tem, 0)) == PLUS
+ && GET_CODE (XEXP (XEXP (tem, 0), 0)) == REG
+ && CONSTANT_P (XEXP (XEXP (tem, 0), 1)))))
+ {
+ /* TEM is not the same as what we'll be replacing the
+ pseudo with after reload, put a USE in front of INSN
+ in the final reload pass. */
+ if (replace_reloads
+ && num_not_at_initial_offset
+ && ! rtx_equal_p (tem, reg_equiv_mem[regno]))
+ {
+ *loc = tem;
+ emit_insn_before (gen_rtx_USE (VOIDmode, ad), insn);
+ /* This doesn't really count as replacing the address
+ as a whole, since it is still a memory access. */
+ }
+ return 0;
+ }
+ ad = tem;
+ }
}
- /* We can avoid a reload if the register's equivalent memory expression
- is valid as an indirect memory address.
- But not all addresses are valid in a mem used as an indirect address:
- only reg or reg+constant. */
-
- else if (reg_equiv_mem[regno] != 0 && ind_levels > 0
- && strict_memory_address_p (mode, reg_equiv_mem[regno])
- && (GET_CODE (XEXP (reg_equiv_mem[regno], 0)) == REG
- || (GET_CODE (XEXP (reg_equiv_mem[regno], 0)) == PLUS
- && GET_CODE (XEXP (XEXP (reg_equiv_mem[regno], 0), 0)) == REG
- && CONSTANT_P (XEXP (XEXP (reg_equiv_mem[regno], 0), 1)))))
- return 0;
-
/* The only remaining case where we can avoid a reload is if this is a
hard register that is valid as a base register and which is not the
subject of a CLOBBER in this insn. */
@@ -4640,7 +4656,7 @@ find_reloads_address (mode, memrefloc, ad, loc, opnum, type, ind_levels, insn)
return 0;
/* If we do not have one of the cases above, we must do the reload. */
- push_reload (ad, NULL_RTX, loc, NULL_PTR, reload_address_base_reg_class,
+ push_reload (ad, NULL_RTX, loc, NULL_PTR, BASE_REG_CLASS,
GET_MODE (ad), VOIDmode, 0, 0, opnum, type);
return 1;
}
@@ -4662,7 +4678,7 @@ find_reloads_address (mode, memrefloc, ad, loc, opnum, type, ind_levels, insn)
return 0;
subst_reg_equivs_changed = 0;
- *loc = subst_reg_equivs (ad);
+ *loc = subst_reg_equivs (ad, insn);
if (! subst_reg_equivs_changed)
return 0;
@@ -4690,12 +4706,22 @@ find_reloads_address (mode, memrefloc, ad, loc, opnum, type, ind_levels, insn)
while (0);
#endif
- /* The address is not valid. We have to figure out why. One possibility
- is that it is itself a MEM. This can happen when the frame pointer is
- being eliminated, a pseudo is not allocated to a hard register, and the
- offset between the frame and stack pointers is not its initial value.
- In that case the pseudo will have been replaced by a MEM referring to
- the stack pointer. */
+ /* The address is not valid. We have to figure out why. First see if
+ we have an outer AND and remove it if so. Then analyze what's inside. */
+
+ if (GET_CODE (ad) == AND)
+ {
+ removed_and = 1;
+ loc = &XEXP (ad, 0);
+ ad = *loc;
+ }
+
+ /* One possibility for why the address is invalid is that it is itself
+ a MEM. This can happen when the frame pointer is being eliminated, a
+ pseudo is not allocated to a hard register, and the offset between the
+ frame and stack pointers is not its initial value. In that case the
+ pseudo will have been replaced by a MEM referring to the
+ stack pointer. */
if (GET_CODE (ad) == MEM)
{
/* First ensure that the address in this MEM is valid. Then, unless
@@ -4712,6 +4738,8 @@ find_reloads_address (mode, memrefloc, ad, loc, opnum, type, ind_levels, insn)
*memrefloc = copy_rtx (*memrefloc);
copy_replacements (tem, XEXP (*memrefloc, 0));
loc = &XEXP (*memrefloc, 0);
+ if (removed_and)
+ loc = &XEXP (*loc, 0);
}
/* Check similar cases as for indirect addresses as above except
@@ -4729,10 +4757,10 @@ find_reloads_address (mode, memrefloc, ad, loc, opnum, type, ind_levels, insn)
/* Must use TEM here, not AD, since it is the one that will
have any subexpressions reloaded, if needed. */
push_reload (tem, NULL_RTX, loc, NULL_PTR,
- reload_address_base_reg_class, GET_MODE (tem),
+ BASE_REG_CLASS, GET_MODE (tem),
VOIDmode, 0,
0, opnum, type);
- return 1;
+ return ! removed_and;
}
else
return 0;
@@ -4754,26 +4782,31 @@ find_reloads_address (mode, memrefloc, ad, loc, opnum, type, ind_levels, insn)
{
*memrefloc = copy_rtx (*memrefloc);
loc = &XEXP (*memrefloc, 0);
+ if (removed_and)
+ loc = &XEXP (*loc, 0);
}
+
if (double_reg_address_ok)
{
/* Unshare the sum as well. */
*loc = ad = copy_rtx (ad);
+
/* Reload the displacement into an index reg.
We assume the frame pointer or arg pointer is a base reg. */
find_reloads_address_part (XEXP (ad, 1), &XEXP (ad, 1),
- reload_address_index_reg_class,
- GET_MODE (ad), opnum, type, ind_levels);
+ INDEX_REG_CLASS, GET_MODE (ad), opnum,
+ type, ind_levels);
+ return 0;
}
else
{
/* If the sum of two regs is not necessarily valid,
reload the sum into a base reg.
That will at least work. */
- find_reloads_address_part (ad, loc, reload_address_base_reg_class,
+ find_reloads_address_part (ad, loc, BASE_REG_CLASS,
Pmode, opnum, type, ind_levels);
}
- return 1;
+ return ! removed_and;
}
/* If we have an indexed stack slot, there are three possible reasons why
@@ -4821,13 +4854,12 @@ find_reloads_address (mode, memrefloc, ad, loc, opnum, type, ind_levels, insn)
plus_constant (XEXP (XEXP (ad, 0), 0),
INTVAL (XEXP (ad, 1))),
XEXP (XEXP (ad, 0), 1));
- find_reloads_address_part (XEXP (ad, 0), &XEXP (ad, 0),
- reload_address_base_reg_class,
+ find_reloads_address_part (XEXP (ad, 0), &XEXP (ad, 0), BASE_REG_CLASS,
GET_MODE (ad), opnum, type, ind_levels);
find_reloads_address_1 (mode, XEXP (ad, 1), 1, &XEXP (ad, 1), opnum,
type, 0, insn);
- return 1;
+ return 0;
}
else if (GET_CODE (ad) == PLUS && GET_CODE (XEXP (ad, 1)) == CONST_INT
@@ -4846,13 +4878,12 @@ find_reloads_address (mode, memrefloc, ad, loc, opnum, type, ind_levels, insn)
XEXP (XEXP (ad, 0), 0),
plus_constant (XEXP (XEXP (ad, 0), 1),
INTVAL (XEXP (ad, 1))));
- find_reloads_address_part (XEXP (ad, 1), &XEXP (ad, 1),
- reload_address_base_reg_class,
+ find_reloads_address_part (XEXP (ad, 1), &XEXP (ad, 1), BASE_REG_CLASS,
GET_MODE (ad), opnum, type, ind_levels);
find_reloads_address_1 (mode, XEXP (ad, 0), 1, &XEXP (ad, 0), opnum,
type, 0, insn);
- return 1;
+ return 0;
}
/* See if address becomes valid when an eliminable register
@@ -4867,7 +4898,7 @@ find_reloads_address (mode, memrefloc, ad, loc, opnum, type, ind_levels, insn)
registers. */
subst_reg_equivs_changed = 0;
- tem = subst_reg_equivs (tem);
+ tem = subst_reg_equivs (tem, insn);
/* Make sure that didn't make the address invalid again. */
@@ -4889,12 +4920,13 @@ find_reloads_address (mode, memrefloc, ad, loc, opnum, type, ind_levels, insn)
{
*memrefloc = copy_rtx (*memrefloc);
loc = &XEXP (*memrefloc, 0);
+ if (removed_and)
+ loc = &XEXP (*loc, 0);
}
- find_reloads_address_part (ad, loc, reload_address_base_reg_class,
- Pmode, opnum, type,
+ find_reloads_address_part (ad, loc, BASE_REG_CLASS, Pmode, opnum, type,
ind_levels);
- return 1;
+ return ! removed_and;
}
return find_reloads_address_1 (mode, ad, 0, loc, opnum, type, ind_levels,
@@ -4903,11 +4935,14 @@ find_reloads_address (mode, memrefloc, ad, loc, opnum, type, ind_levels, insn)
/* Find all pseudo regs appearing in AD
that are eliminable in favor of equivalent values
- and do not have hard regs; replace them by their equivalents. */
+ and do not have hard regs; replace them by their equivalents.
+ INSN, if nonzero, is the insn in which we do the reload. We put USEs in
+ front of it for pseudos that we have to replace with stack slots. */
static rtx
-subst_reg_equivs (ad)
+subst_reg_equivs (ad, insn)
rtx ad;
+ rtx insn;
{
register RTX_CODE code = GET_CODE (ad);
register int i;
@@ -4934,6 +4969,16 @@ subst_reg_equivs (ad)
subst_reg_equivs_changed = 1;
return reg_equiv_constant[regno];
}
+ if (reg_equiv_memory_loc[regno] && num_not_at_initial_offset)
+ {
+ rtx mem = make_memloc (ad, regno);
+ if (! rtx_equal_p (mem, reg_equiv_mem[regno]))
+ {
+ subst_reg_equivs_changed = 1;
+ emit_insn_before (gen_rtx_USE (VOIDmode, ad), insn);
+ return mem;
+ }
+ }
}
return ad;
@@ -4951,7 +4996,7 @@ subst_reg_equivs (ad)
fmt = GET_RTX_FORMAT (code);
for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
if (fmt[i] == 'e')
- XEXP (ad, i) = subst_reg_equivs (XEXP (ad, i));
+ XEXP (ad, i) = subst_reg_equivs (XEXP (ad, i), insn);
return ad;
}
@@ -5224,19 +5269,24 @@ find_reloads_address_1 (mode, x, context, loc, opnum, type, ind_levels, insn)
/* Handle a register that is equivalent to a memory location
which cannot be addressed directly. */
- if (reg_equiv_address[regno] != 0)
+ if (reg_equiv_memory_loc[regno] != 0
+ && (reg_equiv_address[regno] != 0 || num_not_at_initial_offset))
{
rtx tem = make_memloc (XEXP (x, 0), regno);
- /* First reload the memory location's address.
- We can't use ADDR_TYPE (type) here, because we need to
- write back the value after reading it, hence we actually
- need two registers. */
- find_reloads_address (GET_MODE (tem), 0, XEXP (tem, 0),
- &XEXP (tem, 0), opnum, type,
- ind_levels, insn);
- /* Put this inside a new increment-expression. */
- x = gen_rtx_fmt_e (GET_CODE (x), GET_MODE (x), tem);
- /* Proceed to reload that, as if it contained a register. */
+ if (reg_equiv_address[regno]
+ || ! rtx_equal_p (tem, reg_equiv_mem[regno]))
+ {
+ /* First reload the memory location's address.
+ We can't use ADDR_TYPE (type) here, because we need to
+ write back the value after reading it, hence we actually
+ need two registers. */
+ find_reloads_address (GET_MODE (tem), &tem, XEXP (tem, 0),
+ &XEXP (tem, 0), opnum, type,
+ ind_levels, insn);
+ /* Put this inside a new increment-expression. */
+ x = gen_rtx_fmt_e (GET_CODE (x), GET_MODE (x), tem);
+ /* Proceed to reload that, as if it contained a register. */
+ }
}
/* If we have a hard register that is ok as an index,
@@ -5269,9 +5319,12 @@ find_reloads_address_1 (mode, x, context, loc, opnum, type, ind_levels, insn)
memory location, since this will make it harder to
reuse address reloads, and increases register pressure.
Also don't do this if we can probably update x directly. */
- rtx equiv = reg_equiv_mem[regno];
+ rtx equiv = (GET_CODE (XEXP (x, 0)) == MEM
+ ? XEXP (x, 0)
+ : reg_equiv_mem[regno]);
int icode = (int) add_optab->handlers[(int) Pmode].insn_code;
if (insn && GET_CODE (insn) == INSN && equiv
+ && memory_operand (equiv, GET_MODE (equiv))
#ifdef HAVE_cc0
&& ! sets_cc0_p (PATTERN (insn))
#endif
@@ -5283,19 +5336,23 @@ find_reloads_address_1 (mode, x, context, loc, opnum, type, ind_levels, insn)
x = XEXP (x, 0);
reloadnum
= push_reload (x, x, loc, loc,
- (context
- ? reload_address_index_reg_class
- : reload_address_base_reg_class),
+ (context ? INDEX_REG_CLASS : BASE_REG_CLASS),
GET_MODE (x), GET_MODE (x), 0, 0,
opnum, RELOAD_OTHER);
+
+ /* If we created a new MEM based on reg_equiv_mem[REGNO], then
+ LOC above is part of the new MEM, not the MEM in INSN.
+
+ We must also replace the address of the MEM in INSN. */
+ if (&XEXP (x_orig, 0) != loc)
+ push_replacement (&XEXP (x_orig, 0), reloadnum, VOIDmode);
+
}
else
{
reloadnum
= push_reload (x, NULL_RTX, loc, NULL_PTR,
- (context
- ? reload_address_index_reg_class
- : reload_address_base_reg_class),
+ (context ? INDEX_REG_CLASS : BASE_REG_CLASS),
GET_MODE (x), GET_MODE (x), 0, 0,
opnum, type);
reload_inc[reloadnum]
@@ -5323,7 +5380,8 @@ find_reloads_address_1 (mode, x, context, loc, opnum, type, ind_levels, insn)
of an equivalent address for a pseudo that was not allocated to a
hard register. Verify that the specified address is valid and
reload it into a register. */
- rtx tem = XEXP (x, 0);
+ /* Variable `tem' might or might not be used in FIND_REG_INC_NOTE. */
+ rtx tem ATTRIBUTE_UNUSED = XEXP (x, 0);
register rtx link;
int reloadnum;
@@ -5341,9 +5399,7 @@ find_reloads_address_1 (mode, x, context, loc, opnum, type, ind_levels, insn)
opnum, type, ind_levels, insn);
reloadnum = push_reload (x, NULL_RTX, loc, NULL_PTR,
- (context
- ? reload_address_index_reg_class
- : reload_address_base_reg_class),
+ (context ? INDEX_REG_CLASS : BASE_REG_CLASS),
GET_MODE (x), VOIDmode, 0, 0, opnum, type);
reload_inc[reloadnum]
= find_inc_amount (PATTERN (this_insn), XEXP (x, 0));
@@ -5372,8 +5428,7 @@ find_reloads_address_1 (mode, x, context, loc, opnum, type, ind_levels, insn)
find_reloads_address (GET_MODE (x), loc, XEXP (x, 0), &XEXP (x, 0),
opnum, ADDR_TYPE (type), ind_levels, insn);
push_reload (*loc, NULL_RTX, loc, NULL_PTR,
- (context ? reload_address_index_reg_class
- : reload_address_base_reg_class),
+ (context ? INDEX_REG_CLASS : BASE_REG_CLASS),
GET_MODE (x), VOIDmode, 0, 0, opnum, type);
return 1;
@@ -5383,10 +5438,8 @@ find_reloads_address_1 (mode, x, context, loc, opnum, type, ind_levels, insn)
if (reg_equiv_constant[regno] != 0)
{
- find_reloads_address_part (reg_equiv_constant[regno], loc,
- (context
- ? reload_address_index_reg_class
- : reload_address_base_reg_class),
+ find_reloads_address_part (reg_equiv_constant[regno], loc,
+ (context ? INDEX_REG_CLASS : BASE_REG_CLASS),
GET_MODE (x), opnum, type, ind_levels);
return 1;
}
@@ -5396,19 +5449,24 @@ find_reloads_address_1 (mode, x, context, loc, opnum, type, ind_levels, insn)
if (reg_equiv_mem[regno] != 0)
{
push_reload (reg_equiv_mem[regno], NULL_RTX, loc, NULL_PTR,
- (context
- ? reload_address_index_reg_class
- : reload_address_base_reg_class),
+ (context ? INDEX_REG_CLASS : BASE_REG_CLASS),
GET_MODE (x), VOIDmode, 0, 0, opnum, type);
return 1;
}
#endif
- if (reg_equiv_address[regno] != 0)
+ if (reg_equiv_memory_loc[regno]
+ && (reg_equiv_address[regno] != 0 || num_not_at_initial_offset))
{
- x = make_memloc (x, regno);
- find_reloads_address (GET_MODE (x), 0, XEXP (x, 0), &XEXP (x, 0),
- opnum, ADDR_TYPE (type), ind_levels, insn);
+ rtx tem = make_memloc (x, regno);
+ if (reg_equiv_address[regno] != 0
+ || ! rtx_equal_p (tem, reg_equiv_mem[regno]))
+ {
+ x = tem;
+ find_reloads_address (GET_MODE (x), &x, XEXP (x, 0),
+ &XEXP (x, 0), opnum, ADDR_TYPE (type),
+ ind_levels, insn);
+ }
}
if (reg_renumber[regno] >= 0)
@@ -5419,9 +5477,7 @@ find_reloads_address_1 (mode, x, context, loc, opnum, type, ind_levels, insn)
: REGNO_MODE_OK_FOR_BASE_P (regno, mode))))
{
push_reload (x, NULL_RTX, loc, NULL_PTR,
- (context
- ? reload_address_index_reg_class
- : reload_address_base_reg_class),
+ (context ? INDEX_REG_CLASS : BASE_REG_CLASS),
GET_MODE (x), VOIDmode, 0, 0, opnum, type);
return 1;
}
@@ -5433,9 +5489,7 @@ find_reloads_address_1 (mode, x, context, loc, opnum, type, ind_levels, insn)
if (regno_clobbered_p (regno, this_insn))
{
push_reload (x, NULL_RTX, loc, NULL_PTR,
- (context
- ? reload_address_index_reg_class
- : reload_address_base_reg_class),
+ (context ? INDEX_REG_CLASS : BASE_REG_CLASS),
GET_MODE (x), VOIDmode, 0, 0, opnum, type);
return 1;
}
@@ -5456,9 +5510,7 @@ find_reloads_address_1 (mode, x, context, loc, opnum, type, ind_levels, insn)
: REGNO_MODE_OK_FOR_BASE_P (regno, mode)))
{
push_reload (x, NULL_RTX, loc, NULL_PTR,
- (context
- ? reload_address_index_reg_class
- : reload_address_base_reg_class),
+ (context ? INDEX_REG_CLASS : BASE_REG_CLASS),
GET_MODE (x), VOIDmode, 0, 0, opnum, type);
return 1;
}
@@ -5467,12 +5519,13 @@ find_reloads_address_1 (mode, x, context, loc, opnum, type, ind_levels, insn)
is larger than the class size, then reload the whole SUBREG. */
else
{
- enum reg_class class = (context
- ? reload_address_index_reg_class
- : reload_address_base_reg_class);
+ enum reg_class class = (context ? INDEX_REG_CLASS
+ : BASE_REG_CLASS);
if (CLASS_MAX_NREGS (class, GET_MODE (SUBREG_REG (x)))
> reg_class_size[class])
{
+ x = find_reloads_subreg_address (x, 0, opnum, type,
+ ind_levels, insn);
push_reload (x, NULL_RTX, loc, NULL_PTR, class,
GET_MODE (x), VOIDmode, 0, 0, opnum, type);
return 1;
@@ -5529,7 +5582,20 @@ find_reloads_address_part (x, loc, class, mode, opnum, type, ind_levels)
&& (! LEGITIMATE_CONSTANT_P (x)
|| PREFERRED_RELOAD_CLASS (x, class) == NO_REGS))
{
- rtx tem = x = force_const_mem (mode, x);
+ rtx tem;
+
+ /* If this is a CONST_INT, it could have been created by a
+ plus_constant call in eliminate_regs, which means it may be
+ on the reload_obstack. reload_obstack will be freed later, so
+ we can't allow such RTL to be put in the constant pool. There
+ is code in force_const_mem to check for this case, but it doesn't
+ work because we have already popped off the reload_obstack, so
+ rtl_obstack == saveable_obstack is true at this point. */
+ if (GET_CODE (x) == CONST_INT)
+ tem = x = force_const_mem (mode, GEN_INT (INTVAL (x)));
+ else
+ tem = x = force_const_mem (mode, x);
+
find_reloads_address (mode, &tem, XEXP (tem, 0), &XEXP (tem, 0),
opnum, type, ind_levels, 0);
}
@@ -5539,7 +5605,13 @@ find_reloads_address_part (x, loc, class, mode, opnum, type, ind_levels)
&& (! LEGITIMATE_CONSTANT_P (XEXP (x, 1))
|| PREFERRED_RELOAD_CLASS (XEXP (x, 1), class) == NO_REGS))
{
- rtx tem = force_const_mem (GET_MODE (x), XEXP (x, 1));
+ rtx tem;
+
+ /* See comment above. */
+ if (GET_CODE (XEXP (x, 1)) == CONST_INT)
+ tem = force_const_mem (GET_MODE (x), GEN_INT (INTVAL (XEXP (x, 1))));
+ else
+ tem = force_const_mem (GET_MODE (x), XEXP (x, 1));
x = gen_rtx_PLUS (GET_MODE (x), XEXP (x, 0), tem);
find_reloads_address (mode, &tem, XEXP (tem, 0), &XEXP (tem, 0),
@@ -5550,6 +5622,86 @@ find_reloads_address_part (x, loc, class, mode, opnum, type, ind_levels)
mode, VOIDmode, 0, 0, opnum, type);
}
+/* X, a subreg of a pseudo, is a part of an address that needs to be
+ reloaded.
+
+ If the pseudo is equivalent to a memory location that cannot be directly
+ addressed, make the necessary address reloads.
+
+ If address reloads have been necessary, or if the address is changed
+ by register elimination, return the rtx of the memory location;
+ otherwise, return X.
+
+ If FORCE_REPLACE is nonzero, unconditionally replace the subreg with the
+ memory location.
+
+ OPNUM and TYPE identify the purpose of the reload.
+
+ IND_LEVELS says how many levels of indirect addressing are
+ supported at this point in the address.
+
+ INSN, if nonzero, is the insn in which we do the reload. It is used
+ to determine where to put USEs for pseudos that we have to replace with
+ stack slots. */
+
+static rtx
+find_reloads_subreg_address (x, force_replace, opnum, type,
+ ind_levels, insn)
+ rtx x;
+ int force_replace;
+ int opnum;
+ enum reload_type type;
+ int ind_levels;
+ rtx insn;
+{
+ int regno = REGNO (SUBREG_REG (x));
+
+ if (reg_equiv_memory_loc[regno])
+ {
+ /* If the address is not directly addressable, or if the address is not
+ offsettable, then it must be replaced. */
+ if (! force_replace
+ && (reg_equiv_address[regno]
+ || ! offsettable_memref_p (reg_equiv_mem[regno])))
+ force_replace = 1;
+
+ if (force_replace || num_not_at_initial_offset)
+ {
+ rtx tem = make_memloc (SUBREG_REG (x), regno);
+
+ /* If the address changes because of register elimination, then
+ it must be replaced. */
+ if (force_replace
+ || ! rtx_equal_p (tem, reg_equiv_mem[regno]))
+ {
+ int offset = SUBREG_WORD (x) * UNITS_PER_WORD;
+
+ if (BYTES_BIG_ENDIAN)
+ {
+ int size;
+
+ size = GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)));
+ offset += MIN (size, UNITS_PER_WORD);
+ size = GET_MODE_SIZE (GET_MODE (x));
+ offset -= MIN (size, UNITS_PER_WORD);
+ }
+ XEXP (tem, 0) = plus_constant (XEXP (tem, 0), offset);
+ PUT_MODE (tem, GET_MODE (x));
+ find_reloads_address (GET_MODE (tem), &tem, XEXP (tem, 0),
+ &XEXP (tem, 0), opnum, ADDR_TYPE (type),
+ ind_levels, insn);
+ /* If this is not a toplevel operand, find_reloads doesn't see
+ this substitution. We have to emit a USE of the pseudo so
+ that delete_output_reload can see it. */
+ if (replace_reloads && recog_operand[opnum] != x)
+ emit_insn_before (gen_rtx_USE (VOIDmode, SUBREG_REG (x)), insn);
+ x = tem;
+ }
+ }
+ }
+ return x;
+}
+
/* Substitute into the current INSN the registers into which we have reloaded
the things that need reloading. The array `replacements'
says contains the locations of all pointers that must be changed
@@ -6546,6 +6698,12 @@ debug_reload_to_stream (f)
print_inline_rtx (f, reload_in_reg[r], 24);
}
+ if (reload_out_reg[r] != 0)
+ {
+ fprintf (f, "\n\treload_out_reg: ");
+ print_inline_rtx (f, reload_out_reg[r], 24);
+ }
+
if (reload_reg_rtx[r] != 0)
{
fprintf (f, "\n\treload_reg_rtx: ");
diff --git a/gcc/reload.h b/gcc/reload.h
index e86296cb87c..968d3124af4 100644
--- a/gcc/reload.h
+++ b/gcc/reload.h
@@ -50,11 +50,10 @@ extern int memory_move_secondary_cost PROTO ((enum machine_mode, enum reg_class,
/* Maximum number of reloads we can need. */
#define MAX_RELOADS (2 * MAX_RECOG_OPERANDS * (MAX_REGS_PER_ADDRESS + 1))
-extern enum reg_class reload_address_base_reg_class;
-extern enum reg_class reload_address_index_reg_class;
extern rtx reload_in[MAX_RELOADS];
extern rtx reload_out[MAX_RELOADS];
extern rtx reload_in_reg[MAX_RELOADS];
+extern rtx reload_out_reg[MAX_RELOADS];
extern enum reg_class reload_reg_class[MAX_RELOADS];
extern enum machine_mode reload_inmode[MAX_RELOADS];
extern enum machine_mode reload_outmode[MAX_RELOADS];
@@ -134,6 +133,8 @@ extern char indirect_symref_ok;
/* Nonzero if an address (plus (reg frame_pointer) (reg ...)) is valid. */
extern char double_reg_address_ok;
+extern int num_not_at_initial_offset;
+
#ifdef MAX_INSN_CODE
/* These arrays record the insn_code of insns that may be needed to
perform input and output reloads of special objects. They provide a
@@ -202,6 +203,9 @@ struct insn_chain
/* Nonzero if find_reloads said the insn requires reloading. */
unsigned int need_reload:1;
+ /* Nonzero if find_reloads needs to be run during reload_as_needed to
+ perform modifications on any operands. */
+ unsigned int need_operand_change:1;
/* Nonzero if eliminate_regs_in_insn said it requires eliminations. */
unsigned int need_elim:1;
/* Nonzero if this insn was inserted by perform_caller_saves. */
@@ -215,6 +219,7 @@ extern struct insn_chain *reload_insn_chain;
/* Allocate a new insn_chain structure. */
extern struct insn_chain *new_insn_chain PROTO((void));
+extern void compute_use_by_pseudos PROTO((HARD_REG_SET *, regset));
#endif
/* Functions from reload.c: */
@@ -232,24 +237,24 @@ extern void clear_secondary_mem PROTO((void));
reload TO. */
extern void transfer_replacements PROTO((int, int));
-/* Remove all replacements in reload FROM. */
-extern void remove_replacements PROTO((int));
+/* IN_RTX is the value loaded by a reload that we now decided to inherit,
+ or a subpart of it. If we have any replacements registered for IN_RTX,
+ chancel the reloads that were supposed to load them.
+ Return non-zero if we chanceled any reloads. */
+extern int remove_address_replacements PROTO((rtx in_rtx));
/* Like rtx_equal_p except that it allows a REG and a SUBREG to match
if they are the same hard reg, and has special hacks for
autoincrement and autodecrement. */
extern int operands_match_p PROTO((rtx, rtx));
-/* Return the number of times character C occurs in string S. */
-extern int n_occurrences PROTO((int, char *));
-
/* Return 1 if altering OP will not modify the value of CLOBBER. */
extern int safe_from_earlyclobber PROTO((rtx, rtx));
/* Search the body of INSN for values that need reloading and record them
with push_reload. REPLACE nonzero means record also where the values occur
so that subst_reloads can be used. */
-extern void find_reloads PROTO((rtx, int, int, int, short *));
+extern int find_reloads PROTO((rtx, int, int, int, short *));
/* Compute the sum of X and Y, making canonicalizations assumed in an
address, namely: sum constant integers, surround the sum of two
@@ -318,6 +323,9 @@ extern rtx eliminate_regs PROTO((rtx, enum machine_mode, rtx));
OPNUM with reload type TYPE. */
extern rtx gen_reload PROTO((rtx, rtx, int, enum reload_type));
+/* Deallocate the reload register used by reload number R. */
+extern void deallocate_reload_reg PROTO((int r));
+
/* Functions in caller-save.c: */
/* Initialize for caller-save. */
@@ -331,3 +339,6 @@ extern void setup_save_areas PROTO((void));
/* Find the places where hard regs are live across calls and save them. */
extern void save_call_clobbered_regs PROTO((void));
+
+/* Replace (subreg (reg)) with the appropriate (reg) for any operands. */
+extern void cleanup_subreg_operands PROTO ((rtx));
diff --git a/gcc/reload1.c b/gcc/reload1.c
index 7caa58f6e85..2bcba8e1760 100644
--- a/gcc/reload1.c
+++ b/gcc/reload1.c
@@ -1,5 +1,5 @@
/* Reload pseudo regs into hard regs for insns that require hard regs.
- Copyright (C) 1987, 88, 89, 92-97, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1987, 88, 89, 92-98, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -25,7 +25,6 @@ Boston, MA 02111-1307, USA. */
#include "machmode.h"
#include "hard-reg-set.h"
#include "rtl.h"
-#include "function.h"
#include "obstack.h"
#include "insn-config.h"
#include "insn-flags.h"
@@ -40,6 +39,10 @@ Boston, MA 02111-1307, USA. */
#include "real.h"
#include "toplev.h"
+#if !defined PREFERRED_STACK_BOUNDARY && defined STACK_BOUNDARY
+#define PREFERRED_STACK_BOUNDARY STACK_BOUNDARY
+#endif
+
/* This file contains the reload pass of the compiler, which is
run after register allocation has been done. It checks that
each insn is valid (operands required to be in registers really
@@ -55,9 +58,10 @@ Boston, MA 02111-1307, USA. */
called ``reload regs'', and for each place where a pseudo reg
must be in a hard reg, copy it temporarily into one of the reload regs.
- All the pseudos that were formerly allocated to the hard regs that
- are now in use as reload regs must be ``spilled''. This means
- that they go to other hard regs, or to stack slots if no other
+ Reload regs are allocated locally for every instruction that needs
+ reloads. When there are pseudos which are allocated to a register that
+ has been chosen as a reload reg, such pseudos must be ``spilled''.
+ This means that they go to other hard regs, or to stack slots if no other
available hard regs can be found. Spilling can invalidate more
insns, requiring additional need for reloads, so we must keep checking
until the process stabilizes.
@@ -114,12 +118,15 @@ rtx *reg_equiv_mem;
/* Widest width in which each pseudo reg is referred to (via subreg). */
static int *reg_max_ref_width;
-/* Element N is the insn that initialized reg N from its equivalent
+/* Element N is the list of insns that initialized reg N from its equivalent
constant or memory slot. */
static rtx *reg_equiv_init;
+/* Vector to remember old contents of reg_renumber before spilling. */
+static short *reg_old_renumber;
+
/* During reload_as_needed, element N contains the last pseudo regno reloaded
- into hard register N. If that pseudo reg occupied more than one register,
+ into hard register N. If that pseudo reg occupied more than one register,
reg_reloaded_contents points to that pseudo for each spill register in
use; all of these must remain set for an inheritance to occur. */
static int reg_reloaded_contents[FIRST_PSEUDO_REGISTER];
@@ -149,41 +156,61 @@ static rtx spill_reg_rtx[FIRST_PSEUDO_REGISTER];
The precise value is the insn generated to do the store. */
static rtx spill_reg_store[FIRST_PSEUDO_REGISTER];
+/* This is the register that was stored with spill_reg_store. This is a
+ copy of reload_out / reload_out_reg when the value was stored; if
+ reload_out is a MEM, spill_reg_stored_to will be set to reload_out_reg. */
+static rtx spill_reg_stored_to[FIRST_PSEUDO_REGISTER];
+
/* This table is the inverse mapping of spill_regs:
indexed by hard reg number,
it contains the position of that reg in spill_regs,
- or -1 for something that is not in spill_regs. */
-static short spill_reg_order[FIRST_PSEUDO_REGISTER];
+ or -1 for something that is not in spill_regs.
-/* This reg set indicates registers that may not be used for retrying global
- allocation. The registers that may not be used include all spill registers
- and the frame pointer (if we are using one). */
-HARD_REG_SET forbidden_regs;
-
-/* This reg set indicates registers that are not good for spill registers.
- They will not be used to complete groups of spill registers. This includes
- all fixed registers, registers that may be eliminated, and, if
- SMALL_REGISTER_CLASSES is zero, registers explicitly used in the rtl.
+ ?!? This is no longer accurate. */
+static short spill_reg_order[FIRST_PSEUDO_REGISTER];
- (spill_reg_order prevents these registers from being used to start a
- group.) */
+/* This reg set indicates registers that can't be used as spill registers for
+ the currently processed insn. These are the hard registers which are live
+ during the insn, but not allocated to pseudos, as well as fixed
+ registers. */
static HARD_REG_SET bad_spill_regs;
+/* These are the hard registers that can't be used as spill register for any
+ insn. This includes registers used for user variables and registers that
+ we can't eliminate. A register that appears in this set also can't be used
+ to retry register allocation. */
+static HARD_REG_SET bad_spill_regs_global;
+
/* Describes order of use of registers for reloading
- of spilled pseudo-registers. `spills' is the number of
- elements that are actually valid; new ones are added at the end. */
+ of spilled pseudo-registers. `n_spills' is the number of
+ elements that are actually valid; new ones are added at the end.
+
+ Both spill_regs and spill_reg_order are used on two occasions:
+ once during find_reload_regs, where they keep track of the spill registers
+ for a single insn, but also during reload_as_needed where they show all
+ the registers ever used by reload. For the latter case, the information
+ is calculated during finish_spills. */
static short spill_regs[FIRST_PSEUDO_REGISTER];
-/* This reg set indicates those registers that have been used a spill
- registers. This information is used in reorg.c, to help figure out
- what registers are live at any point. It is assumed that all spill_regs
- are dead at every CODE_LABEL. */
+/* This vector of reg sets indicates, for each pseudo, which hard registers
+ may not be used for retrying global allocation because the register was
+ formerly spilled from one of them. If we allowed reallocating a pseudo to
+ a register that it was already allocated to, reload might not
+ terminate. */
+static HARD_REG_SET *pseudo_previous_regs;
+
+/* This vector of reg sets indicates, for each pseudo, which hard
+ registers may not be used for retrying global allocation because they
+ are used as spill registers during one of the insns in which the
+ pseudo is live. */
+static HARD_REG_SET *pseudo_forbidden_regs;
-HARD_REG_SET used_spill_regs;
+/* All hard regs that have been used as spill registers for any insn are
+ marked in this set. */
+static HARD_REG_SET used_spill_regs;
/* Index of last register assigned as a spill register. We allocate in
a round-robin fashion. */
-
static int last_spill_reg;
/* Describes order of preference for putting regs into spill_regs.
@@ -193,54 +220,30 @@ static int last_spill_reg;
Empty elements at the end contain -1. */
static short potential_reload_regs[FIRST_PSEUDO_REGISTER];
-/* 1 for a hard register that appears explicitly in the rtl
- (for example, function value registers, special registers
- used by insns, structure value pointer registers). */
-static char regs_explicitly_used[FIRST_PSEUDO_REGISTER];
-
-/* Indicates if a register was counted against the need for
- groups. 0 means it can count against max_nongroup instead. */
-static HARD_REG_SET counted_for_groups;
-
-/* Indicates if a register was counted against the need for
- non-groups. 0 means it can become part of a new group.
- During choose_reload_regs, 1 here means don't use this reg
- as part of a group, even if it seems to be otherwise ok. */
-static HARD_REG_SET counted_for_nongroups;
-
/* Nonzero if indirect addressing is supported on the machine; this means
that spilling (REG n) does not require reloading it into a register in
order to do (MEM (REG n)) or (MEM (PLUS (REG n) (CONST_INT c))). The
value indicates the level of indirect addressing supported, e.g., two
means that (MEM (MEM (REG n))) is also valid if (REG n) does not get
a hard register. */
-
static char spill_indirect_levels;
/* Nonzero if indirect addressing is supported when the innermost MEM is
of the form (MEM (SYMBOL_REF sym)). It is assumed that the level to
which these are valid is the same as spill_indirect_levels, above. */
-
char indirect_symref_ok;
/* Nonzero if an address (plus (reg frame_pointer) (reg ...)) is valid. */
-
char double_reg_address_ok;
/* Record the stack slot for each spilled hard register. */
-
static rtx spill_stack_slot[FIRST_PSEUDO_REGISTER];
/* Width allocated so far for that stack slot. */
-
static int spill_stack_slot_width[FIRST_PSEUDO_REGISTER];
-/* Indexed by register class and basic block number, nonzero if there is
- any need for a spill register of that class in that basic block.
- The pointer is 0 if we did stupid allocation and don't know
- the structure of basic blocks. */
-
-char *basic_block_needs[N_REG_CLASSES];
+/* Record which pseudos needed to be spilled. */
+static regset spilled_pseudos;
/* First uid used by insns created by reload in this function.
Used in find_equiv_reg. */
@@ -248,37 +251,21 @@ int reload_first_uid;
/* Flag set by local-alloc or global-alloc if anything is live in
a call-clobbered reg across calls. */
-
int caller_save_needed;
-/* The register class to use for a base register when reloading an
- address. This is normally BASE_REG_CLASS, but it may be different
- when using SMALL_REGISTER_CLASSES and passing parameters in
- registers. */
-enum reg_class reload_address_base_reg_class;
-
-/* The register class to use for an index register when reloading an
- address. This is normally INDEX_REG_CLASS, but it may be different
- when using SMALL_REGISTER_CLASSES and passing parameters in
- registers. */
-enum reg_class reload_address_index_reg_class;
-
/* Set to 1 while reload_as_needed is operating.
Required by some machines to handle any generated moves differently. */
-
int reload_in_progress = 0;
/* These arrays record the insn_code of insns that may be needed to
perform input and output reloads of special objects. They provide a
place to pass a scratch register. */
-
enum insn_code reload_in_optab[NUM_MACHINE_MODES];
enum insn_code reload_out_optab[NUM_MACHINE_MODES];
/* This obstack is used for allocation of rtl during register elimination.
The allocated storage can be freed once find_reloads has processed the
insn. */
-
struct obstack reload_obstack;
/* Points to the beginning of the reload_obstack. All insn_chain structures
@@ -295,13 +282,22 @@ char *reload_firstobj;
/* List of insn_chain instructions, one for every insn that reload needs to
examine. */
struct insn_chain *reload_insn_chain;
+
+#ifdef TREE_CODE
+extern tree current_function_decl;
+#else
+extern union tree_node *current_function_decl;
+#endif
+
+/* List of all insns needing reloads. */
+static struct insn_chain *insns_need_reload;
/* This structure is used to record information about register eliminations.
Each array entry describes one possible way of eliminating a register
in favor of another. If there is more than one way of eliminating a
particular register, the most preferred should be specified first. */
-static struct elim_table
+struct elim_table
{
int from; /* Register number to be eliminated. */
int to; /* Register number used as replacement. */
@@ -310,7 +306,6 @@ static struct elim_table
int can_eliminate_previous; /* Value of CAN_ELIMINATE in previous scan over
insns made by reload. */
int offset; /* Current offset between the two regs. */
- int max_offset; /* Maximum 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.
@@ -319,7 +314,17 @@ static struct elim_table
register corresponding to a pseudo
assigned to the reg to be eliminated. */
rtx to_rtx; /* REG rtx for the replacement. */
-} reg_eliminate[] =
+};
+
+static struct elim_table * reg_eliminate = 0;
+
+/* This is an intermediate structure to initialize the table. It has
+ exactly the members provided by ELIMINABLE_REGS. */
+static struct elim_table_1
+{
+ int from;
+ int to;
+} reg_eliminate_1[] =
/* If a set of eliminable registers was specified, define the table from it.
Otherwise, default to the normal case of the frame pointer being
@@ -331,15 +336,18 @@ static struct elim_table
{{ FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}};
#endif
-#define NUM_ELIMINABLE_REGS (sizeof reg_eliminate / sizeof reg_eliminate[0])
+#define NUM_ELIMINABLE_REGS (sizeof reg_eliminate_1/sizeof reg_eliminate_1[0])
/* Record the number of pending eliminations that have an offset not equal
to their initial offset. If non-zero, we use a new copy of each
replacement result in any insns encountered. */
-static int num_not_at_initial_offset;
+int num_not_at_initial_offset;
/* Count the number of registers that we may be able to eliminate. */
static int num_eliminable;
+/* And the number of registers that are equivalent to a constant that
+ can be eliminated to frame_pointer / arg_pointer + constant. */
+static int num_eliminable_invariants;
/* For each label, we record the offset of each elimination. If we reach
a label by more than one path and an offset differs, we cannot do the
@@ -355,38 +363,52 @@ static int (*offsets_at)[NUM_ELIMINABLE_REGS];
static int num_labels;
-struct hard_reg_n_uses { int regno; int uses; };
+struct hard_reg_n_uses
+{
+ int regno;
+ unsigned int uses;
+};
-static void dump_needs PROTO((FILE *));
-static int calculate_needs_all_insns PROTO((rtx, int));
-static int calculate_needs PROTO((int, rtx, rtx, int));
-static int find_reload_regs PROTO((int, FILE *));
-static int find_tworeg_group PROTO((int, int, FILE *));
-static int find_group PROTO((int, int, FILE *));
-static int possible_group_p PROTO((int, int *));
-static void count_possible_groups PROTO((int *, enum machine_mode *,
- int *, int));
+static void maybe_fix_stack_asms PROTO((void));
+static void calculate_needs_all_insns PROTO((int));
+static void calculate_needs PROTO((struct insn_chain *));
+static void find_reload_regs PROTO((struct insn_chain *chain,
+ FILE *));
+static void find_tworeg_group PROTO((struct insn_chain *, int,
+ FILE *));
+static void find_group PROTO((struct insn_chain *, int,
+ FILE *));
+static int possible_group_p PROTO((struct insn_chain *, int));
+static void count_possible_groups PROTO((struct insn_chain *, int));
static int modes_equiv_for_class_p PROTO((enum machine_mode,
enum machine_mode,
enum reg_class));
-static void delete_caller_save_insns PROTO((rtx));
+static void delete_caller_save_insns PROTO((void));
+
static void spill_failure PROTO((rtx));
-static int new_spill_reg PROTO((int, int, int *, int *, int,
- FILE *));
+static void new_spill_reg PROTO((struct insn_chain *, int, int,
+ int, FILE *));
+static void maybe_mark_pseudo_spilled PROTO((int));
static void delete_dead_insn PROTO((rtx));
static void alter_reg PROTO((int, int));
static void set_label_offsets PROTO((rtx, rtx, int));
static int eliminate_regs_in_insn PROTO((rtx, int));
+static void update_eliminable_offsets PROTO((void));
static void mark_not_eliminable PROTO((rtx, rtx));
static void set_initial_elim_offsets PROTO((void));
+static void verify_initial_elim_offsets PROTO((void));
+static void set_initial_label_offsets PROTO((void));
+static void set_offsets_for_label PROTO((rtx));
static void init_elim_table PROTO((void));
static void update_eliminables PROTO((HARD_REG_SET *));
-static int spill_hard_reg PROTO((int, int, FILE *, int));
+static void spill_hard_reg PROTO((int, FILE *, int));
+static int finish_spills PROTO((int, FILE *));
+static void ior_hard_reg_set PROTO((HARD_REG_SET *, HARD_REG_SET *));
static void scan_paradoxical_subregs PROTO((rtx));
static int hard_reg_use_compare PROTO((const GENERIC_PTR, const GENERIC_PTR));
-static void order_regs_for_reload PROTO((void));
-static int compare_spill_regs PROTO((const GENERIC_PTR, const GENERIC_PTR));
-static void reload_as_needed PROTO((rtx, int));
+static void count_pseudo PROTO((struct hard_reg_n_uses *, int));
+static void order_regs_for_reload PROTO((struct insn_chain *));
+static void reload_as_needed PROTO((int));
static void forget_old_reloads_1 PROTO((rtx, rtx));
static int reload_reg_class_lower PROTO((const GENERIC_PTR, const GENERIC_PTR));
static void mark_reload_reg_in_use PROTO((int, int, enum reload_type,
@@ -394,19 +416,18 @@ static void mark_reload_reg_in_use PROTO((int, int, enum reload_type,
static void clear_reload_reg_in_use PROTO((int, int, enum reload_type,
enum machine_mode));
static int reload_reg_free_p PROTO((int, int, enum reload_type));
-static int reload_reg_free_before_p PROTO((int, int, enum reload_type, int));
-static int reload_reg_free_for_value_p PROTO((int, int, enum reload_type, rtx, rtx, int));
+static int reload_reg_free_for_value_p PROTO((int, int, enum reload_type, rtx, rtx, int, int));
static int reload_reg_reaches_end_p PROTO((int, int, enum reload_type));
-static int allocate_reload_reg PROTO((int, rtx, int, int));
-static void choose_reload_regs PROTO((rtx, rtx));
+static int allocate_reload_reg PROTO((struct insn_chain *, int, int,
+ int));
+static void choose_reload_regs PROTO((struct insn_chain *));
static void merge_assigned_reloads PROTO((rtx));
-static void emit_reload_insns PROTO((rtx, int));
-static void delete_output_reload PROTO((rtx, int, rtx));
-static void inc_for_reload PROTO((rtx, rtx, int));
-static int constraint_accepts_reg_p PROTO((char *, rtx));
-static void find_set_and_used_regs PROTO((rtx, int, int));
-static void calc_reg_usage PROTO((rtx, int));
-
+static void emit_reload_insns PROTO((struct insn_chain *));
+static void delete_output_reload PROTO((rtx, int, int));
+static void delete_address_reloads PROTO((rtx, rtx));
+static void delete_address_reloads_1 PROTO((rtx, rtx, rtx));
+static rtx inc_for_reload PROTO((rtx, rtx, rtx, int));
+static int constraint_accepts_reg_p PROTO((const char *, rtx));
static void reload_cse_regs_1 PROTO((rtx));
static void reload_cse_invalidate_regno PROTO((int, enum machine_mode, int));
static int reload_cse_mem_conflict_p PROTO((rtx, rtx));
@@ -423,6 +444,9 @@ static void reload_combine_note_use PROTO((rtx *, rtx));
static void reload_combine_note_store PROTO((rtx, rtx));
static void reload_cse_move2add PROTO((rtx));
static void move2add_note_store PROTO((rtx, rtx));
+#ifdef AUTO_INC_DEC
+static void add_auto_inc_notes PROTO((rtx, rtx));
+#endif
/* Initialize the reload pass once per compilation. */
@@ -473,64 +497,6 @@ init_reload ()
/* Initialize obstack for our rtl allocation. */
gcc_obstack_init (&reload_obstack);
reload_startobj = (char *) obstack_alloc (&reload_obstack, 0);
-
- /* Decide which register class should be used when reloading
- addresses. If we are using SMALL_REGISTER_CLASSES, and any
- parameters are passed in registers, then we do not want to use
- those registers when reloading an address. Otherwise, if a
- function argument needs a reload, we may wind up clobbering
- another argument to the function which was already computed. If
- we find a subset class which simply avoids those registers, we
- use it instead. ??? It would be better to only use the
- restricted class when we actually are loading function arguments,
- but that is hard to determine. */
- reload_address_base_reg_class = BASE_REG_CLASS;
- reload_address_index_reg_class = INDEX_REG_CLASS;
- if (SMALL_REGISTER_CLASSES)
- {
- int regno;
- HARD_REG_SET base, index;
- enum reg_class *p;
-
- COPY_HARD_REG_SET (base, reg_class_contents[BASE_REG_CLASS]);
- COPY_HARD_REG_SET (index, reg_class_contents[INDEX_REG_CLASS]);
- for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
- {
- if (FUNCTION_ARG_REGNO_P (regno))
- {
- CLEAR_HARD_REG_BIT (base, regno);
- CLEAR_HARD_REG_BIT (index, regno);
- }
- }
-
- GO_IF_HARD_REG_EQUAL (base, reg_class_contents[BASE_REG_CLASS],
- baseok);
- for (p = reg_class_subclasses[BASE_REG_CLASS];
- *p != LIM_REG_CLASSES;
- p++)
- {
- GO_IF_HARD_REG_EQUAL (base, reg_class_contents[*p], usebase);
- continue;
- usebase:
- reload_address_base_reg_class = *p;
- break;
- }
- baseok:;
-
- GO_IF_HARD_REG_EQUAL (index, reg_class_contents[INDEX_REG_CLASS],
- indexok);
- for (p = reg_class_subclasses[INDEX_REG_CLASS];
- *p != LIM_REG_CLASSES;
- p++)
- {
- GO_IF_HARD_REG_EQUAL (index, reg_class_contents[*p], useindex);
- continue;
- useindex:
- reload_address_index_reg_class = *p;
- break;
- }
- indexok:;
- }
}
/* List of insn chains that are currently unused. */
@@ -544,7 +510,8 @@ new_insn_chain ()
if (unused_insn_chains == 0)
{
- c = obstack_alloc (&reload_obstack, sizeof (struct insn_chain));
+ c = (struct insn_chain *)
+ obstack_alloc (&reload_obstack, sizeof (struct insn_chain));
c->live_before = OBSTACK_ALLOC_REG_SET (&reload_obstack);
c->live_after = OBSTACK_ALLOC_REG_SET (&reload_obstack);
}
@@ -554,46 +521,49 @@ new_insn_chain ()
unused_insn_chains = c->next;
}
c->is_caller_save_insn = 0;
+ c->need_operand_change = 0;
c->need_reload = 0;
c->need_elim = 0;
return c;
}
+/* Small utility function to set all regs in hard reg set TO which are
+ allocated to pseudos in regset FROM. */
+void
+compute_use_by_pseudos (to, from)
+ HARD_REG_SET *to;
+ regset from;
+{
+ int regno;
+ EXECUTE_IF_SET_IN_REG_SET
+ (from, FIRST_PSEUDO_REGISTER, regno,
+ {
+ int r = reg_renumber[regno];
+ int nregs;
+ if (r < 0)
+ {
+ /* reload_combine uses the information from
+ BASIC_BLOCK->global_live_at_start, which might still
+ contain registers that have not actually been allocated
+ since they have an equivalence. */
+ if (! reload_completed)
+ abort ();
+ }
+ else
+ {
+ nregs = HARD_REGNO_NREGS (r, PSEUDO_REGNO_MODE (regno));
+ while (nregs-- > 0)
+ SET_HARD_REG_BIT (*to, r + nregs);
+ }
+ });
+}
+
/* Global variables used by reload and its subroutines. */
-/* Set during calculate_needs if an insn needs reloading. */
-static int something_needs_reloads;
/* Set during calculate_needs if an insn needs register elimination. */
static int something_needs_elimination;
-
-/* For each class, number of reload regs needed in that class.
- This is the maximum over all insns of the needs in that class
- of the individual insn. */
-static int max_needs[N_REG_CLASSES];
-
-/* For each class, size of group of consecutive regs
- that is needed for the reloads of this class. */
-static int group_size[N_REG_CLASSES];
-
-/* For each class, max number of consecutive groups needed.
- (Each group contains group_size[CLASS] consecutive registers.) */
-static int max_groups[N_REG_CLASSES];
-
-/* For each class, max number needed of regs that don't belong
- to any of the groups. */
-static int max_nongroups[N_REG_CLASSES];
-
-/* For each class, the machine mode which requires consecutive
- groups of regs of that class.
- If two different modes ever require groups of one class,
- they must be the same size and equally restrictive for that class,
- otherwise we can't handle the complexity. */
-static enum machine_mode group_mode[N_REG_CLASSES];
-
-/* Record the insn where each maximum need is first found. */
-static rtx max_needs_insn[N_REG_CLASSES];
-static rtx max_groups_insn[N_REG_CLASSES];
-static rtx max_nongroups_insn[N_REG_CLASSES];
+/* Set during calculate_needs if an insn needs an operand changed. */
+int something_needs_operands_changed;
/* Nonzero means we couldn't get enough spill regs. */
static int failure;
@@ -622,7 +592,7 @@ reload (first, global, dumpfile)
int global;
FILE *dumpfile;
{
- register int i, j;
+ register int i;
register rtx insn;
register struct elim_table *ep;
@@ -631,8 +601,6 @@ reload (first, global, dumpfile)
char *real_known_ptr = NULL_PTR;
int (*real_at_ptr)[NUM_ELIMINABLE_REGS];
- int something_changed;
-
/* Make sure even insns with volatile mem refs are recognizable. */
init_recog ();
@@ -647,19 +615,11 @@ reload (first, global, dumpfile)
/* Enable find_equiv_reg to distinguish insns made by reload. */
reload_first_uid = get_max_uid ();
- for (i = 0; i < N_REG_CLASSES; i++)
- basic_block_needs[i] = 0;
-
#ifdef SECONDARY_MEMORY_NEEDED
/* Initialize the secondary memory table. */
clear_secondary_mem ();
#endif
- /* Remember which hard regs appear explicitly
- before we merge into `regs_ever_live' the ones in which
- pseudo regs have been allocated. */
- bcopy (regs_ever_live, regs_explicitly_used, sizeof regs_ever_live);
-
/* We don't have a stack slot for any spill reg yet. */
bzero ((char *) spill_stack_slot, sizeof spill_stack_slot);
bzero ((char *) spill_stack_slot_width, sizeof spill_stack_slot_width);
@@ -706,9 +666,15 @@ reload (first, global, dumpfile)
bzero ((char *) reg_equiv_address, max_regno * sizeof (rtx));
reg_max_ref_width = (int *) xmalloc (max_regno * sizeof (int));
bzero ((char *) reg_max_ref_width, max_regno * sizeof (int));
+ reg_old_renumber = (short *) xmalloc (max_regno * sizeof (short));
+ bcopy ((PTR) reg_renumber, (PTR) reg_old_renumber, max_regno * sizeof (short));
+ pseudo_forbidden_regs
+ = (HARD_REG_SET *) xmalloc (max_regno * sizeof (HARD_REG_SET));
+ pseudo_previous_regs
+ = (HARD_REG_SET *) xmalloc (max_regno * sizeof (HARD_REG_SET));
- if (SMALL_REGISTER_CLASSES)
- CLEAR_HARD_REG_SET (forbidden_regs);
+ CLEAR_HARD_REG_SET (bad_spill_regs_global);
+ bzero ((char *) pseudo_previous_regs, max_regno * sizeof (HARD_REG_SET));
/* Look for REG_EQUIV notes; record what each pseudo is equivalent to.
Also find all paradoxical subregs and find largest such for each pseudo.
@@ -717,6 +683,7 @@ reload (first, global, dumpfile)
Also look for a "constant" NOTE_INSN_SETJMP. This means that all
caller-saved registers must be marked live. */
+ num_eliminable_invariants = 0;
for (insn = first; insn; insn = NEXT_INSN (insn))
{
rtx set = single_set (insn);
@@ -732,7 +699,8 @@ reload (first, global, dumpfile)
rtx note = find_reg_note (insn, REG_EQUIV, NULL_RTX);
if (note
#ifdef LEGITIMATE_PIC_OPERAND_P
- && (! CONSTANT_P (XEXP (note, 0)) || ! flag_pic
+ && (! function_invariant_p (XEXP (note, 0))
+ || ! flag_pic
|| LEGITIMATE_PIC_OPERAND_P (XEXP (note, 0)))
#endif
)
@@ -750,9 +718,22 @@ reload (first, global, dumpfile)
reg_equiv_memory_loc[i] = x;
}
- else if (CONSTANT_P (x))
+ else if (function_invariant_p (x))
{
- if (LEGITIMATE_CONSTANT_P (x))
+ if (GET_CODE (x) == PLUS)
+ {
+ /* This is PLUS of frame pointer and a constant,
+ and might be shared. Unshare it. */
+ reg_equiv_constant[i] = copy_rtx (x);
+ num_eliminable_invariants++;
+ }
+ else if (x == frame_pointer_rtx
+ || x == arg_pointer_rtx)
+ {
+ reg_equiv_constant[i] = x;
+ num_eliminable_invariants++;
+ }
+ else if (LEGITIMATE_CONSTANT_P (x))
reg_equiv_constant[i] = x;
else
reg_equiv_memory_loc[i]
@@ -767,7 +748,8 @@ reload (first, global, dumpfile)
So don't mark this insn now. */
if (GET_CODE (x) != MEM
|| rtx_equal_p (SET_SRC (set), x))
- reg_equiv_init[i] = insn;
+ reg_equiv_init[i]
+ = gen_rtx_INSN_LIST (VOIDmode, insn, reg_equiv_init[i]);
}
}
}
@@ -779,7 +761,9 @@ reload (first, global, dumpfile)
&& reg_equiv_memory_loc[REGNO (SET_SRC (set))]
&& rtx_equal_p (SET_DEST (set),
reg_equiv_memory_loc[REGNO (SET_SRC (set))]))
- reg_equiv_init[REGNO (SET_SRC (set))] = insn;
+ reg_equiv_init[REGNO (SET_SRC (set))]
+ = gen_rtx_INSN_LIST (VOIDmode, insn,
+ reg_equiv_init[REGNO (SET_SRC (set))]);
if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
scan_paradoxical_subregs (PATTERN (insn));
@@ -841,77 +825,49 @@ reload (first, global, dumpfile)
free (reg_equiv_init);
free (reg_equiv_address);
free (reg_max_ref_width);
+ free (reg_old_renumber);
+ free (pseudo_previous_regs);
+ free (pseudo_forbidden_regs);
return 0;
}
#endif
- /* Compute the order of preference for hard registers to spill.
- Store them by decreasing preference in potential_reload_regs. */
-
- order_regs_for_reload ();
-
- /* So far, no hard regs have been spilled. */
- n_spills = 0;
- for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
- spill_reg_order[i] = -1;
+ maybe_fix_stack_asms ();
+ insns_need_reload = 0;
+ something_needs_elimination = 0;
+
/* Initialize to -1, which means take the first spill register. */
last_spill_reg = -1;
- /* On most machines, we can't use any register explicitly used in the
- rtl as a spill register. But on some, we have to. Those will have
- taken care to keep the life of hard regs as short as possible. */
-
- if (! SMALL_REGISTER_CLASSES)
- COPY_HARD_REG_SET (forbidden_regs, bad_spill_regs);
+ spilled_pseudos = ALLOCA_REG_SET ();
/* Spill any hard regs that we know we can't eliminate. */
+ CLEAR_HARD_REG_SET (used_spill_regs);
for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; ep++)
if (! ep->can_eliminate)
- spill_hard_reg (ep->from, global, dumpfile, 1);
+ spill_hard_reg (ep->from, dumpfile, 1);
#if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM
if (frame_pointer_needed)
- spill_hard_reg (HARD_FRAME_POINTER_REGNUM, global, dumpfile, 1);
+ spill_hard_reg (HARD_FRAME_POINTER_REGNUM, dumpfile, 1);
#endif
+ finish_spills (global, dumpfile);
- if (global)
- for (i = 0; i < N_REG_CLASSES; i++)
- {
- basic_block_needs[i] = (char *) alloca (n_basic_blocks);
- bzero (basic_block_needs[i], n_basic_blocks);
- }
-
- /* From now on, we need to emit any moves without making new pseudos. */
+ /* From now on, we may need to generate moves differently. We may also
+ allow modifications of insns which cause them to not be recognized.
+ Any such modifications will be cleaned up during reload itself. */
reload_in_progress = 1;
/* This loop scans the entire function each go-round
and repeats until one repetition spills no additional hard regs. */
-
- /* This flag is set when a pseudo reg is spilled,
- to require another pass. Note that getting an additional reload
- reg does not necessarily imply any pseudo reg was spilled;
- sometimes we find a reload reg that no pseudo reg was allocated in. */
- something_changed = 1;
- /* This flag is set if there are any insns that require reloading. */
- something_needs_reloads = 0;
- /* This flag is set if there are any insns that require register
- eliminations. */
- something_needs_elimination = 0;
- while (something_changed)
+ for (;;)
{
- HOST_WIDE_INT starting_frame_size;
+ int something_changed;
+ int did_spill;
+ struct insn_chain *chain;
- something_changed = 0;
- bzero ((char *) max_needs, sizeof max_needs);
- bzero ((char *) max_groups, sizeof max_groups);
- bzero ((char *) max_nongroups, sizeof max_nongroups);
- bzero ((char *) max_needs_insn, sizeof max_needs_insn);
- bzero ((char *) max_groups_insn, sizeof max_groups_insn);
- bzero ((char *) max_nongroups_insn, sizeof max_nongroups_insn);
- bzero ((char *) group_size, sizeof group_size);
- for (i = 0; i < N_REG_CLASSES; i++)
- group_mode[i] = VOIDmode;
+ HOST_WIDE_INT starting_frame_size;
/* Round size of stack frame to BIGGEST_ALIGNMENT. This must be done
here because the stack size may be a part of the offset computation
@@ -922,7 +878,8 @@ reload (first, global, dumpfile)
starting_frame_size = get_frame_size ();
set_initial_elim_offsets ();
-
+ set_initial_label_offsets ();
+
/* For each pseudo register that has an equivalent location defined,
try to eliminate any eliminable registers (such as the frame pointer)
assuming initial offsets for the replacement register, which
@@ -975,23 +932,14 @@ reload (first, global, dumpfile)
reg_equiv_memory_loc[i] = 0;
reg_equiv_init[i] = 0;
alter_reg (i, -1);
- something_changed = 1;
}
}
- /* Insert code to save and restore call-clobbered hard regs
- around calls. Tell if what mode to use so that we will process
- those insns in reload_as_needed if we have to. */
-
if (caller_save_needed)
setup_save_areas ();
+ /* If we allocated another stack slot, redo elimination bookkeeping. */
if (starting_frame_size != get_frame_size ())
- something_changed = 1;
-
- /* If we allocated another pseudo to the stack, redo elimination
- bookkeeping. */
- if (something_changed)
continue;
if (caller_save_needed)
@@ -1001,16 +949,18 @@ reload (first, global, dumpfile)
reload_firstobj = (char *) obstack_alloc (&reload_obstack, 0);
}
- something_changed |= calculate_needs_all_insns (first, global);
+ calculate_needs_all_insns (global);
+
+ CLEAR_REG_SET (spilled_pseudos);
+ did_spill = 0;
+
+ something_changed = 0;
/* If we allocated any new memory locations, make another pass
since it might have changed elimination offsets. */
if (starting_frame_size != get_frame_size ())
something_changed = 1;
- if (dumpfile)
- dump_needs (dumpfile);
-
{
HARD_REG_SET to_spill;
CLEAR_HARD_REG_SET (to_spill);
@@ -1018,64 +968,39 @@ reload (first, global, dumpfile)
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
if (TEST_HARD_REG_BIT (to_spill, i))
{
- spill_hard_reg (i, global, dumpfile, 1);
+ spill_hard_reg (i, dumpfile, 1);
+ did_spill = 1;
+
+ /* Regardless of the state of spills, if we previously had
+ a register that we thought we could eliminate, but no can
+ not eliminate, we must run another pass.
+
+ Consider pseudos which have an entry in reg_equiv_* which
+ reference an eliminable register. We must make another pass
+ to update reg_equiv_* so that we do not substitute in the
+ old value from when we thought the elimination could be
+ performed. */
something_changed = 1;
}
}
- /* If all needs are met, we win. */
+ CLEAR_HARD_REG_SET (used_spill_regs);
+ /* Try to satisfy the needs for each insn. */
+ for (chain = insns_need_reload; chain != 0;
+ chain = chain->next_need_reload)
+ find_reload_regs (chain, dumpfile);
- for (i = 0; i < N_REG_CLASSES; i++)
- if (max_needs[i] > 0 || max_groups[i] > 0 || max_nongroups[i] > 0)
- break;
- if (i == N_REG_CLASSES && ! something_changed)
- break;
-
- /* Not all needs are met; must spill some hard regs. */
-
- /* Put all registers spilled so far back in potential_reload_regs, but
- put them at the front, since we've already spilled most of the
- pseudos in them (we might have left some pseudos unspilled if they
- were in a block that didn't need any spill registers of a conflicting
- class. We used to try to mark off the need for those registers,
- but doing so properly is very complex and reallocating them is the
- simpler approach. First, "pack" potential_reload_regs by pushing
- any nonnegative entries towards the end. That will leave room
- for the registers we already spilled.
-
- Also, undo the marking of the spill registers from the last time
- around in FORBIDDEN_REGS since we will be probably be allocating
- them again below.
-
- ??? It is theoretically possible that we might end up not using one
- of our previously-spilled registers in this allocation, even though
- they are at the head of the list. It's not clear what to do about
- this, but it was no better before, when we marked off the needs met
- by the previously-spilled registers. With the current code, globals
- can be allocated into these registers, but locals cannot. */
-
- if (n_spills)
- {
- for (i = j = FIRST_PSEUDO_REGISTER - 1; i >= 0; i--)
- if (potential_reload_regs[i] != -1)
- potential_reload_regs[j--] = potential_reload_regs[i];
-
- for (i = 0; i < n_spills; i++)
- {
- potential_reload_regs[i] = spill_regs[i];
- spill_reg_order[spill_regs[i]] = -1;
- CLEAR_HARD_REG_BIT (forbidden_regs, spill_regs[i]);
- }
-
- n_spills = 0;
- }
-
- something_changed |= find_reload_regs (global, dumpfile);
if (failure)
goto failed;
- if (something_changed)
- delete_caller_save_insns (first);
+ if (insns_need_reload != 0 || did_spill)
+ something_changed |= finish_spills (global, dumpfile);
+
+ if (! something_changed)
+ break;
+
+ if (caller_save_needed)
+ delete_caller_save_insns ();
}
/* If global-alloc was run, notify it of any register eliminations we have
@@ -1089,29 +1014,48 @@ reload (first, global, dumpfile)
If that insn didn't set the register (i.e., it copied the register to
memory), just delete that insn instead of the equivalencing insn plus
anything now dead. If we call delete_dead_insn on that insn, we may
- delete the insn that actually sets the register if the register die
+ delete the insn that actually sets the register if the register dies
there and that is incorrect. */
for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
- if (reg_renumber[i] < 0 && reg_equiv_init[i] != 0
- && GET_CODE (reg_equiv_init[i]) != NOTE)
- {
- if (reg_set_p (regno_reg_rtx[i], PATTERN (reg_equiv_init[i])))
- delete_dead_insn (reg_equiv_init[i]);
- else
- {
- PUT_CODE (reg_equiv_init[i], NOTE);
- NOTE_SOURCE_FILE (reg_equiv_init[i]) = 0;
- NOTE_LINE_NUMBER (reg_equiv_init[i]) = NOTE_INSN_DELETED;
- }
- }
+ {
+ if (reg_renumber[i] < 0 && reg_equiv_init[i] != 0)
+ {
+ rtx list;
+ for (list = reg_equiv_init[i]; list; list = XEXP (list, 1))
+ {
+ rtx equiv_insn = XEXP (list, 0);
+ if (GET_CODE (equiv_insn) == NOTE)
+ continue;
+ if (reg_set_p (regno_reg_rtx[i], PATTERN (equiv_insn)))
+ delete_dead_insn (equiv_insn);
+ else
+ {
+ PUT_CODE (equiv_insn, NOTE);
+ NOTE_SOURCE_FILE (equiv_insn) = 0;
+ NOTE_LINE_NUMBER (equiv_insn) = NOTE_INSN_DELETED;
+ }
+ }
+ }
+ }
/* Use the reload registers where necessary
by generating move instructions to move the must-be-register
values into or out of the reload registers. */
- if (something_needs_reloads || something_needs_elimination)
- reload_as_needed (first, global);
+ if (insns_need_reload != 0 || something_needs_elimination
+ || something_needs_operands_changed)
+ {
+ int old_frame_size = get_frame_size ();
+
+ reload_as_needed (global);
+
+ if (old_frame_size != get_frame_size ())
+ abort ();
+
+ if (num_eliminable)
+ verify_initial_elim_offsets ();
+ }
/* If we were able to eliminate the frame pointer, show that it is no
longer live at the start of any basic block. If it ls live by
@@ -1121,7 +1065,7 @@ reload (first, global, dumpfile)
if (! frame_pointer_needed)
for (i = 0; i < n_basic_blocks; i++)
- CLEAR_REGNO_REG_SET (basic_block_live_at_start[i],
+ CLEAR_REGNO_REG_SET (BASIC_BLOCK (i)->global_live_at_start,
HARD_FRAME_POINTER_REGNUM);
/* Come here (with failure set nonzero) if we can't get enough spill regs
@@ -1144,11 +1088,13 @@ reload (first, global, dumpfile)
{
rtx addr = 0;
int in_struct = 0;
+ int is_scalar;
int is_readonly = 0;
if (reg_equiv_memory_loc[i])
{
in_struct = MEM_IN_STRUCT_P (reg_equiv_memory_loc[i]);
+ is_scalar = MEM_SCALAR_P (reg_equiv_memory_loc[i]);
is_readonly = RTX_UNCHANGING_P (reg_equiv_memory_loc[i]);
}
@@ -1167,6 +1113,7 @@ reload (first, global, dumpfile)
REG_USERVAR_P (reg) = 0;
RTX_UNCHANGING_P (reg) = is_readonly;
MEM_IN_STRUCT_P (reg) = in_struct;
+ MEM_SCALAR_P (reg) = is_scalar;
/* We have no alias information about this newly created
MEM. */
MEM_ALIAS_SET (reg) = 0;
@@ -1177,17 +1124,27 @@ reload (first, global, dumpfile)
}
}
- /* Make a pass over all the insns and delete all USEs which we inserted
- only to tag a REG_EQUAL note on them. Also remove all REG_DEAD and
- REG_UNUSED notes. */
+ /* We must set reload_completed now since the cleanup_subreg_operands call
+ below will re-recognize each insn and reload may have generated insns
+ which are only valid during and after reload. */
+ reload_completed = 1;
+
+ /* Make a pass over all the insns and delete all USEs which we
+ inserted only to tag a REG_EQUAL note on them. Remove all
+ REG_DEAD and REG_UNUSED notes. Delete all CLOBBER insns and
+ simplify (subreg (reg)) operands. Also remove all REG_RETVAL and
+ REG_LIBCALL notes since they are no longer useful or accurate.
+ Strip and regenerate REG_INC notes that may have been moved
+ around. */
for (insn = first; insn; insn = NEXT_INSN (insn))
if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
{
rtx *pnote;
- if (GET_CODE (PATTERN (insn)) == USE
- && find_reg_note (insn, REG_EQUAL, NULL_RTX))
+ if ((GET_CODE (PATTERN (insn)) == USE
+ && find_reg_note (insn, REG_EQUAL, NULL_RTX))
+ || GET_CODE (PATTERN (insn)) == CLOBBER)
{
PUT_CODE (insn, NOTE);
NOTE_SOURCE_FILE (insn) = 0;
@@ -1199,11 +1156,21 @@ reload (first, global, dumpfile)
while (*pnote != 0)
{
if (REG_NOTE_KIND (*pnote) == REG_DEAD
- || REG_NOTE_KIND (*pnote) == REG_UNUSED)
+ || REG_NOTE_KIND (*pnote) == REG_UNUSED
+ || REG_NOTE_KIND (*pnote) == REG_INC
+ || REG_NOTE_KIND (*pnote) == REG_RETVAL
+ || REG_NOTE_KIND (*pnote) == REG_LIBCALL)
*pnote = XEXP (*pnote, 1);
else
pnote = &XEXP (*pnote, 1);
}
+
+#ifdef AUTO_INC_DEC
+ add_auto_inc_notes (insn, PATTERN (insn));
+#endif
+
+ /* And simplify (subreg (reg)) if it appears as an operand. */
+ cleanup_subreg_operands (insn);
}
/* If we are doing stack checking, give a warning if this function's
@@ -1220,10 +1187,34 @@ reload (first, global, dumpfile)
warning ("frame size too large for reliable stack checking");
}
- obstack_free (&reload_obstack, reload_startobj);
+ /* If we are doing stack checking, give a warning if this function's
+ frame size is larger than we expect. */
+ if (flag_stack_check && ! STACK_CHECK_BUILTIN)
+ {
+ HOST_WIDE_INT size = get_frame_size () + STACK_CHECK_FIXED_FRAME_SIZE;
+ static int verbose_warned = 0;
+
+ for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+ if (regs_ever_live[i] && ! fixed_regs[i] && call_used_regs[i])
+ size += UNITS_PER_WORD;
+
+ if (size > STACK_CHECK_MAX_FRAME_SIZE)
+ {
+ warning ("frame size too large for reliable stack checking");
+ if (! verbose_warned)
+ {
+ warning ("try reducing the number of local variables");
+ verbose_warned = 1;
+ }
+ }
+ }
/* Indicate that we no longer have known memory locations or constants. */
+ if (reg_equiv_constant)
+ free (reg_equiv_constant);
reg_equiv_constant = 0;
+ if (reg_equiv_memory_loc)
+ free (reg_equiv_memory_loc);
reg_equiv_memory_loc = 0;
if (real_known_ptr)
@@ -1231,46 +1222,164 @@ reload (first, global, dumpfile)
if (real_at_ptr)
free (real_at_ptr);
- free (reg_equiv_constant);
- free (reg_equiv_memory_loc);
free (reg_equiv_mem);
free (reg_equiv_init);
free (reg_equiv_address);
free (reg_max_ref_width);
+ free (reg_old_renumber);
+ free (pseudo_previous_regs);
+ free (pseudo_forbidden_regs);
+
+ FREE_REG_SET (spilled_pseudos);
CLEAR_HARD_REG_SET (used_spill_regs);
for (i = 0; i < n_spills; i++)
SET_HARD_REG_BIT (used_spill_regs, spill_regs[i]);
+ /* Free all the insn_chain structures at once. */
+ obstack_free (&reload_obstack, reload_startobj);
+ unused_insn_chains = 0;
+
return failure;
}
-/* Walk the insns of the current function, starting with FIRST, and collect
- information about the need to do register elimination and the need to
- perform reloads. */
-static int
-calculate_needs_all_insns (first, global)
- rtx first;
+/* Yet another special case. Unfortunately, reg-stack forces people to
+ write incorrect clobbers in asm statements. These clobbers must not
+ cause the register to appear in bad_spill_regs, otherwise we'll call
+ fatal_insn later. We clear the corresponding regnos in the live
+ register sets to avoid this.
+ The whole thing is rather sick, I'm afraid. */
+static void
+maybe_fix_stack_asms ()
+{
+#ifdef STACK_REGS
+ char *constraints[MAX_RECOG_OPERANDS];
+ enum machine_mode operand_mode[MAX_RECOG_OPERANDS];
+ struct insn_chain *chain;
+
+ for (chain = reload_insn_chain; chain != 0; chain = chain->next)
+ {
+ int i, noperands;
+ HARD_REG_SET clobbered, allowed;
+ rtx pat;
+
+ if (GET_RTX_CLASS (GET_CODE (chain->insn)) != 'i'
+ || (noperands = asm_noperands (PATTERN (chain->insn))) < 0)
+ continue;
+ pat = PATTERN (chain->insn);
+ if (GET_CODE (pat) != PARALLEL)
+ continue;
+
+ CLEAR_HARD_REG_SET (clobbered);
+ CLEAR_HARD_REG_SET (allowed);
+
+ /* First, make a mask of all stack regs that are clobbered. */
+ for (i = 0; i < XVECLEN (pat, 0); i++)
+ {
+ rtx t = XVECEXP (pat, 0, i);
+ if (GET_CODE (t) == CLOBBER && STACK_REG_P (XEXP (t, 0)))
+ SET_HARD_REG_BIT (clobbered, REGNO (XEXP (t, 0)));
+ }
+
+ /* Get the operand values and constraints out of the insn. */
+ decode_asm_operands (pat, recog_operand, recog_operand_loc,
+ constraints, operand_mode);
+
+ /* For every operand, see what registers are allowed. */
+ for (i = 0; i < noperands; i++)
+ {
+ char *p = constraints[i];
+ /* For every alternative, we compute the class of registers allowed
+ for reloading in CLS, and merge its contents into the reg set
+ ALLOWED. */
+ int cls = (int) NO_REGS;
+
+ for (;;)
+ {
+ char c = *p++;
+
+ if (c == '\0' || c == ',' || c == '#')
+ {
+ /* End of one alternative - mark the regs in the current
+ class, and reset the class. */
+ IOR_HARD_REG_SET (allowed, reg_class_contents[cls]);
+ cls = NO_REGS;
+ if (c == '#')
+ do {
+ c = *p++;
+ } while (c != '\0' && c != ',');
+ if (c == '\0')
+ break;
+ continue;
+ }
+
+ switch (c)
+ {
+ case '=': case '+': case '*': case '%': case '?': case '!':
+ case '0': case '1': case '2': case '3': case '4': case 'm':
+ case '<': case '>': case 'V': case 'o': case '&': case 'E':
+ case 'F': case 's': case 'i': case 'n': case 'X': case 'I':
+ case 'J': case 'K': case 'L': case 'M': case 'N': case 'O':
+ case 'P':
+#ifdef EXTRA_CONSTRAINT
+ case 'Q': case 'R': case 'S': case 'T': case 'U':
+#endif
+ break;
+
+ case 'p':
+ cls = (int) reg_class_subunion[cls][(int) BASE_REG_CLASS];
+ break;
+
+ case 'g':
+ case 'r':
+ cls = (int) reg_class_subunion[cls][(int) GENERAL_REGS];
+ break;
+
+ default:
+ cls = (int) reg_class_subunion[cls][(int) REG_CLASS_FROM_LETTER (c)];
+
+ }
+ }
+ }
+ /* Those of the registers which are clobbered, but allowed by the
+ constraints, must be usable as reload registers. So clear them
+ out of the life information. */
+ AND_HARD_REG_SET (allowed, clobbered);
+ for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+ if (TEST_HARD_REG_BIT (allowed, i))
+ {
+ CLEAR_REGNO_REG_SET (chain->live_before, i);
+ CLEAR_REGNO_REG_SET (chain->live_after, i);
+ }
+ }
+
+#endif
+}
+
+
+/* Walk the chain of insns, and determine for each whether it needs reloads
+ and/or eliminations. Build the corresponding insns_need_reload list, and
+ set something_needs_elimination as appropriate. */
+static void
+calculate_needs_all_insns (global)
int global;
{
- rtx insn;
- int something_changed = 0;
- rtx after_call = 0;
- /* Keep track of which basic blocks are needing the reloads. */
- int this_block = 0;
+ struct insn_chain **pprev_reload = &insns_need_reload;
+ struct insn_chain **pchain;
- /* Compute the most additional registers needed by any instruction.
- Collect information separately for each class of regs. */
+ something_needs_elimination = 0;
- for (insn = first; insn; insn = NEXT_INSN (insn))
+ for (pchain = &reload_insn_chain; *pchain != 0; pchain = &(*pchain)->next)
{
- if (global && this_block + 1 < n_basic_blocks
- && insn == basic_block_head[this_block+1])
- ++this_block;
+ rtx insn;
+ struct insn_chain *chain;
+
+ chain = *pchain;
+ insn = chain->insn;
- /* If this is a label, a JUMP_INSN, or has REG_NOTES (which
- might include REG_LABEL), we need to see what effects this
- has on the known offsets at labels. */
+ /* If this is a label, a JUMP_INSN, or has REG_NOTES (which might
+ include REG_LABEL), we need to see what effects this has on the
+ known offsets at labels. */
if (GET_CODE (insn) == CODE_LABEL || GET_CODE (insn) == JUMP_INSN
|| (GET_RTX_CLASS (GET_CODE (insn)) == 'i'
@@ -1283,59 +1392,59 @@ calculate_needs_all_insns (first, global)
int old_code = INSN_CODE (insn);
rtx old_notes = REG_NOTES (insn);
int did_elimination = 0;
+ int operands_changed = 0;
+ rtx set = single_set (insn);
- /* Nonzero means don't use a reload reg that overlaps
- the place where a function value can be returned. */
- rtx avoid_return_reg = 0;
-
- /* Set avoid_return_reg if this is an insn
- that might use the value of a function call. */
- if (SMALL_REGISTER_CLASSES && GET_CODE (insn) == CALL_INSN)
- {
- if (GET_CODE (PATTERN (insn)) == SET)
- after_call = SET_DEST (PATTERN (insn));
- else if (GET_CODE (PATTERN (insn)) == PARALLEL
- && GET_CODE (XVECEXP (PATTERN (insn), 0, 0)) == SET)
- after_call = SET_DEST (XVECEXP (PATTERN (insn), 0, 0));
- else
- after_call = 0;
- }
- else if (SMALL_REGISTER_CLASSES && after_call != 0
- && !(GET_CODE (PATTERN (insn)) == SET
- && SET_DEST (PATTERN (insn)) == stack_pointer_rtx)
- && GET_CODE (PATTERN (insn)) != USE)
+ /* Skip insns that only set an equivalence. */
+ if (set && GET_CODE (SET_DEST (set)) == REG
+ && reg_renumber[REGNO (SET_DEST (set))] < 0
+ && reg_equiv_constant[REGNO (SET_DEST (set))])
{
- if (reg_referenced_p (after_call, PATTERN (insn)))
- avoid_return_reg = after_call;
- after_call = 0;
+ /* Must clear out the shortcuts, in case they were set last
+ time through. */
+ chain->need_elim = 0;
+ chain->need_reload = 0;
+ chain->need_operand_change = 0;
+ continue;
}
/* If needed, eliminate any eliminable registers. */
- if (num_eliminable)
+ if (num_eliminable || num_eliminable_invariants)
did_elimination = eliminate_regs_in_insn (insn, 0);
/* Analyze the instruction. */
- find_reloads (insn, 0, spill_indirect_levels, global,
- spill_reg_order);
+ operands_changed = find_reloads (insn, 0, spill_indirect_levels,
+ global, spill_reg_order);
+
+ /* If a no-op set needs more than one reload, this is likely
+ to be something that needs input address reloads. We
+ can't get rid of this cleanly later, and it is of no use
+ anyway, so discard it now.
+ We only do this when expensive_optimizations is enabled,
+ since this complements reload inheritance / output
+ reload deletion, and it can make debugging harder. */
+ if (flag_expensive_optimizations && n_reloads > 1)
+ {
+ rtx set = single_set (insn);
+ if (set
+ && SET_SRC (set) == SET_DEST (set)
+ && GET_CODE (SET_SRC (set)) == REG
+ && REGNO (SET_SRC (set)) >= FIRST_PSEUDO_REGISTER)
+ {
+ PUT_CODE (insn, NOTE);
+ NOTE_SOURCE_FILE (insn) = 0;
+ NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
+ continue;
+ }
+ }
+ if (num_eliminable)
+ update_eliminable_offsets ();
/* Remember for later shortcuts which insns had any reloads or
- register eliminations.
-
- One might think that it would be worthwhile to mark insns
- that need register replacements but not reloads, but this is
- not safe because find_reloads may do some manipulation of
- the insn (such as swapping commutative operands), which would
- be lost when we restore the old pattern after register
- replacement. So the actions of find_reloads must be redone in
- subsequent passes or in reload_as_needed.
-
- However, it is safe to mark insns that need reloads
- but not register replacement. */
-
- PUT_MODE (insn, (did_elimination ? QImode
- : n_reloads ? HImode
- : GET_MODE (insn) == DImode ? DImode
- : VOIDmode));
+ register eliminations. */
+ chain->need_elim = did_elimination;
+ chain->need_reload = n_reloads > 0;
+ chain->need_operand_change = operands_changed;
/* Discard any register replacements done. */
if (did_elimination)
@@ -1347,50 +1456,44 @@ calculate_needs_all_insns (first, global)
something_needs_elimination = 1;
}
+ something_needs_operands_changed |= operands_changed;
+
if (n_reloads != 0)
- something_changed |= calculate_needs (this_block, insn,
- avoid_return_reg, global);
- }
+ {
+ *pprev_reload = chain;
+ pprev_reload = &chain->next_need_reload;
- /* Note that there is a continue statement above. */
+ calculate_needs (chain);
+ }
+ }
}
- return something_changed;
+ *pprev_reload = 0;
}
-/* To compute the number of reload registers of each class
- needed for an insn, we must simulate what choose_reload_regs
- can do. We do this by splitting an insn into an "input" and
- an "output" part. RELOAD_OTHER reloads are used in both.
- The input part uses those reloads, RELOAD_FOR_INPUT reloads,
- which must be live over the entire input section of reloads,
- and the maximum of all the RELOAD_FOR_INPUT_ADDRESS and
- RELOAD_FOR_OPERAND_ADDRESS reloads, which conflict with the
- inputs.
-
- The registers needed for output are RELOAD_OTHER and
- RELOAD_FOR_OUTPUT, which are live for the entire output
- portion, and the maximum of all the RELOAD_FOR_OUTPUT_ADDRESS
- reloads for each operand.
+/* Compute the most additional registers needed by one instruction,
+ given by CHAIN. Collect information separately for each class of regs.
+
+ To compute the number of reload registers of each class needed for an
+ insn, we must simulate what choose_reload_regs can do. We do this by
+ splitting an insn into an "input" and an "output" part. RELOAD_OTHER
+ reloads are used in both. The input part uses those reloads,
+ RELOAD_FOR_INPUT reloads, which must be live over the entire input section
+ of reloads, and the maximum of all the RELOAD_FOR_INPUT_ADDRESS and
+ RELOAD_FOR_OPERAND_ADDRESS reloads, which conflict with the inputs.
+
+ The registers needed for output are RELOAD_OTHER and RELOAD_FOR_OUTPUT,
+ which are live for the entire output portion, and the maximum of all the
+ RELOAD_FOR_OUTPUT_ADDRESS reloads for each operand.
The total number of registers needed is the maximum of the
inputs and outputs. */
-static int
-calculate_needs (this_block, insn, avoid_return_reg, global)
- int this_block;
- rtx insn, avoid_return_reg;
- int global;
+static void
+calculate_needs (chain)
+ struct insn_chain *chain;
{
- int something_changed = 0;
int i;
- struct needs
- {
- /* [0] is normal, [1] is nongroup. */
- int regs[2][N_REG_CLASSES];
- int groups[N_REG_CLASSES];
- };
-
/* Each `struct needs' corresponds to one RELOAD_... type. */
struct {
struct needs other;
@@ -1406,7 +1509,9 @@ calculate_needs (this_block, insn, avoid_return_reg, global)
struct needs out_addr_addr[MAX_RECOG_OPERANDS];
} insn_needs;
- something_needs_reloads = 1;
+ bzero ((char *) chain->group_size, sizeof chain->group_size);
+ for (i = 0; i < N_REG_CLASSES; i++)
+ chain->group_mode[i] = VOIDmode;
bzero ((char *) &insn_needs, sizeof insn_needs);
/* Count each reload once in every class
@@ -1430,16 +1535,6 @@ calculate_needs (this_block, insn, avoid_return_reg, global)
&& ! reload_secondary_p[i]))
continue;
- /* Show that a reload register of this class is needed
- in this basic block. We do not use insn_needs and
- insn_groups because they are overly conservative for
- this purpose. */
- if (global && ! basic_block_needs[(int) class][this_block])
- {
- basic_block_needs[(int) class][this_block] = 1;
- something_changed = 1;
- }
-
mode = reload_inmode[i];
if (GET_MODE_SIZE (reload_outmode[i]) > GET_MODE_SIZE (mode))
mode = reload_outmode[i];
@@ -1481,6 +1576,8 @@ calculate_needs (this_block, insn, avoid_return_reg, global)
case RELOAD_FOR_OPADDR_ADDR:
this_needs = &insn_needs.op_addr_reload;
break;
+ default:
+ abort();
}
if (size > 1)
@@ -1497,18 +1594,18 @@ calculate_needs (this_block, insn, avoid_return_reg, global)
/* Record size and mode of a group of this class. */
/* If more than one size group is needed,
make all groups the largest needed size. */
- if (group_size[(int) class] < size)
+ if (chain->group_size[(int) class] < size)
{
- other_mode = group_mode[(int) class];
+ other_mode = chain->group_mode[(int) class];
allocate_mode = mode;
- group_size[(int) class] = size;
- group_mode[(int) class] = mode;
+ chain->group_size[(int) class] = size;
+ chain->group_mode[(int) class] = mode;
}
else
{
other_mode = mode;
- allocate_mode = group_mode[(int) class];
+ allocate_mode = chain->group_mode[(int) class];
}
/* Crash if two dissimilar machine modes both need
@@ -1518,14 +1615,14 @@ calculate_needs (this_block, insn, avoid_return_reg, global)
&& ! modes_equiv_for_class_p (allocate_mode,
other_mode, class))
fatal_insn ("Two dissimilar machine modes both need groups of consecutive regs of the same class",
- insn);
+ chain->insn);
}
else if (size == 1)
{
- this_needs->regs[reload_nongroup[i]][(int) class] += 1;
+ this_needs->regs[(unsigned char)reload_nongroup[i]][(int) class] += 1;
p = reg_class_superclasses[(int) class];
while (*p != LIM_REG_CLASSES)
- this_needs->regs[reload_nongroup[i]][(int) *p++] += 1;
+ this_needs->regs[(unsigned char)reload_nongroup[i]][(int) *p++] += 1;
}
else
abort ();
@@ -1607,98 +1704,10 @@ calculate_needs (this_block, insn, avoid_return_reg, global)
insn_needs.other_addr.groups[i]);
}
- /* If this insn stores the value of a function call,
- and that value is in a register that has been spilled,
- and if the insn needs a reload in a class
- that might use that register as the reload register,
- then add an extra need in that class.
- This makes sure we have a register available that does
- not overlap the return value. */
-
- if (SMALL_REGISTER_CLASSES && avoid_return_reg)
- {
- int regno = REGNO (avoid_return_reg);
- int nregs
- = HARD_REGNO_NREGS (regno, GET_MODE (avoid_return_reg));
- int r;
- int basic_needs[N_REG_CLASSES], basic_groups[N_REG_CLASSES];
-
- /* First compute the "basic needs", which counts a
- need only in the smallest class in which it
- is required. */
-
- bcopy ((char *) insn_needs.other.regs[0],
- (char *) basic_needs, sizeof basic_needs);
- bcopy ((char *) insn_needs.other.groups,
- (char *) basic_groups, sizeof basic_groups);
-
- for (i = 0; i < N_REG_CLASSES; i++)
- {
- enum reg_class *p;
-
- if (basic_needs[i] >= 0)
- for (p = reg_class_superclasses[i];
- *p != LIM_REG_CLASSES; p++)
- basic_needs[(int) *p] -= basic_needs[i];
-
- if (basic_groups[i] >= 0)
- for (p = reg_class_superclasses[i];
- *p != LIM_REG_CLASSES; p++)
- basic_groups[(int) *p] -= basic_groups[i];
- }
-
- /* Now count extra regs if there might be a conflict with
- the return value register. */
-
- for (r = regno; r < regno + nregs; r++)
- if (spill_reg_order[r] >= 0)
- for (i = 0; i < N_REG_CLASSES; i++)
- if (TEST_HARD_REG_BIT (reg_class_contents[i], r))
- {
- if (basic_needs[i] > 0)
- {
- enum reg_class *p;
-
- insn_needs.other.regs[0][i]++;
- p = reg_class_superclasses[i];
- while (*p != LIM_REG_CLASSES)
- insn_needs.other.regs[0][(int) *p++]++;
- }
- if (basic_groups[i] > 0)
- {
- enum reg_class *p;
-
- insn_needs.other.groups[i]++;
- p = reg_class_superclasses[i];
- while (*p != LIM_REG_CLASSES)
- insn_needs.other.groups[(int) *p++]++;
- }
- }
- }
-
- /* For each class, collect maximum need of any insn. */
-
- for (i = 0; i < N_REG_CLASSES; i++)
- {
- if (max_needs[i] < insn_needs.other.regs[0][i])
- {
- max_needs[i] = insn_needs.other.regs[0][i];
- max_needs_insn[i] = insn;
- }
- if (max_groups[i] < insn_needs.other.groups[i])
- {
- max_groups[i] = insn_needs.other.groups[i];
- max_groups_insn[i] = insn;
- }
- if (max_nongroups[i] < insn_needs.other.regs[1][i])
- {
- max_nongroups[i] = insn_needs.other.regs[1][i];
- max_nongroups_insn[i] = insn;
- }
- }
- return something_changed;
+ /* Record the needs for later. */
+ chain->need = insn_needs.other;
}
-
+
/* Find a group of exactly 2 registers.
First try to fill out the group by spilling a single register which
@@ -1708,9 +1717,10 @@ calculate_needs (this_block, insn, avoid_return_reg, global)
which are explicitly used.
Then try to create a group from any pair of registers. */
-static int
-find_tworeg_group (global, class, dumpfile)
- int global;
+
+static void
+find_tworeg_group (chain, class, dumpfile)
+ struct insn_chain *chain;
int class;
FILE *dumpfile;
{
@@ -1725,65 +1735,39 @@ find_tworeg_group (global, class, dumpfile)
&& ((j > 0 && (other = j - 1, spill_reg_order[other] >= 0)
&& TEST_HARD_REG_BIT (reg_class_contents[class], j)
&& TEST_HARD_REG_BIT (reg_class_contents[class], other)
- && HARD_REGNO_MODE_OK (other, group_mode[class])
- && ! TEST_HARD_REG_BIT (counted_for_nongroups, other)
+ && HARD_REGNO_MODE_OK (other, chain->group_mode[class])
+ && ! TEST_HARD_REG_BIT (chain->counted_for_nongroups, other)
/* We don't want one part of another group.
We could get "two groups" that overlap! */
- && ! TEST_HARD_REG_BIT (counted_for_groups, other))
+ && ! TEST_HARD_REG_BIT (chain->counted_for_groups, other))
|| (j < FIRST_PSEUDO_REGISTER - 1
&& (other = j + 1, spill_reg_order[other] >= 0)
&& TEST_HARD_REG_BIT (reg_class_contents[class], j)
&& TEST_HARD_REG_BIT (reg_class_contents[class], other)
- && HARD_REGNO_MODE_OK (j, group_mode[class])
- && ! TEST_HARD_REG_BIT (counted_for_nongroups, other)
- && ! TEST_HARD_REG_BIT (counted_for_groups, other))))
+ && HARD_REGNO_MODE_OK (j, chain->group_mode[class])
+ && ! TEST_HARD_REG_BIT (chain->counted_for_nongroups, other)
+ && ! TEST_HARD_REG_BIT (chain->counted_for_groups, other))))
{
register enum reg_class *p;
/* We have found one that will complete a group,
so count off one group as provided. */
- max_groups[class]--;
+ chain->need.groups[class]--;
p = reg_class_superclasses[class];
while (*p != LIM_REG_CLASSES)
{
- if (group_size [(int) *p] <= group_size [class])
- max_groups[(int) *p]--;
+ if (chain->group_size [(int) *p] <= chain->group_size [class])
+ chain->need.groups[(int) *p]--;
p++;
}
/* Indicate both these regs are part of a group. */
- SET_HARD_REG_BIT (counted_for_groups, j);
- SET_HARD_REG_BIT (counted_for_groups, other);
+ SET_HARD_REG_BIT (chain->counted_for_groups, j);
+ SET_HARD_REG_BIT (chain->counted_for_groups, other);
break;
}
}
/* We can't complete a group, so start one. */
- /* Look for a pair neither of which is explicitly used. */
- if (SMALL_REGISTER_CLASSES && i == FIRST_PSEUDO_REGISTER)
- for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
- {
- int j, k;
- j = potential_reload_regs[i];
- /* Verify that J+1 is a potential reload reg. */
- for (k = 0; k < FIRST_PSEUDO_REGISTER; k++)
- if (potential_reload_regs[k] == j + 1)
- break;
- if (j >= 0 && j + 1 < FIRST_PSEUDO_REGISTER
- && k < FIRST_PSEUDO_REGISTER
- && spill_reg_order[j] < 0 && spill_reg_order[j + 1] < 0
- && TEST_HARD_REG_BIT (reg_class_contents[class], j)
- && TEST_HARD_REG_BIT (reg_class_contents[class], j + 1)
- && HARD_REGNO_MODE_OK (j, group_mode[class])
- && ! TEST_HARD_REG_BIT (counted_for_nongroups,
- j + 1)
- && ! TEST_HARD_REG_BIT (bad_spill_regs, j + 1)
- /* Reject J at this stage
- if J+1 was explicitly used. */
- && ! regs_explicitly_used[j + 1])
- break;
- }
- /* Now try any group at all
- whose registers are not in bad_spill_regs. */
if (i == FIRST_PSEUDO_REGISTER)
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
{
@@ -1798,8 +1782,8 @@ find_tworeg_group (global, class, dumpfile)
&& spill_reg_order[j] < 0 && spill_reg_order[j + 1] < 0
&& TEST_HARD_REG_BIT (reg_class_contents[class], j)
&& TEST_HARD_REG_BIT (reg_class_contents[class], j + 1)
- && HARD_REGNO_MODE_OK (j, group_mode[class])
- && ! TEST_HARD_REG_BIT (counted_for_nongroups, j + 1)
+ && HARD_REGNO_MODE_OK (j, chain->group_mode[class])
+ && ! TEST_HARD_REG_BIT (chain->counted_for_nongroups, j + 1)
&& ! TEST_HARD_REG_BIT (bad_spill_regs, j + 1))
break;
}
@@ -1807,81 +1791,93 @@ find_tworeg_group (global, class, dumpfile)
/* I should be the index in potential_reload_regs
of the new reload reg we have found. */
- if (i < FIRST_PSEUDO_REGISTER)
- return new_spill_reg (i, class, max_needs, NULL_PTR,
- global, dumpfile);
-
- /* There are no groups left to spill. */
- spill_failure (max_groups_insn[class]);
- failure = 1;
- return 1;
+ new_spill_reg (chain, i, class, 0, dumpfile);
}
/* Find a group of more than 2 registers.
Look for a sufficient sequence of unspilled registers, and spill them all
at once. */
-static int
-find_group (global, class, dumpfile)
- int global;
+
+static void
+find_group (chain, class, dumpfile)
+ struct insn_chain *chain;
int class;
FILE *dumpfile;
{
- int something_changed = 0;
int i;
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
{
- int j, k;
+ int j = potential_reload_regs[i];
- j = potential_reload_regs[i];
if (j >= 0
- && j + group_size[class] <= FIRST_PSEUDO_REGISTER
- && HARD_REGNO_MODE_OK (j, group_mode[class]))
+ && j + chain->group_size[class] <= FIRST_PSEUDO_REGISTER
+ && HARD_REGNO_MODE_OK (j, chain->group_mode[class]))
{
+ int k;
/* Check each reg in the sequence. */
- for (k = 0; k < group_size[class]; k++)
+ for (k = 0; k < chain->group_size[class]; k++)
if (! (spill_reg_order[j + k] < 0
&& ! TEST_HARD_REG_BIT (bad_spill_regs, j + k)
&& TEST_HARD_REG_BIT (reg_class_contents[class], j + k)))
break;
/* We got a full sequence, so spill them all. */
- if (k == group_size[class])
+ if (k == chain->group_size[class])
{
register enum reg_class *p;
- for (k = 0; k < group_size[class]; k++)
+ for (k = 0; k < chain->group_size[class]; k++)
{
int idx;
- SET_HARD_REG_BIT (counted_for_groups, j + k);
+ SET_HARD_REG_BIT (chain->counted_for_groups, j + k);
for (idx = 0; idx < FIRST_PSEUDO_REGISTER; idx++)
if (potential_reload_regs[idx] == j + k)
break;
- something_changed |= new_spill_reg (idx, class, max_needs,
- NULL_PTR, global,
- dumpfile);
+ new_spill_reg (chain, idx, class, 0, dumpfile);
}
/* We have found one that will complete a group,
so count off one group as provided. */
- max_groups[class]--;
+ chain->need.groups[class]--;
p = reg_class_superclasses[class];
while (*p != LIM_REG_CLASSES)
{
- if (group_size [(int) *p]
- <= group_size [class])
- max_groups[(int) *p]--;
+ if (chain->group_size [(int) *p]
+ <= chain->group_size [class])
+ chain->need.groups[(int) *p]--;
p++;
}
- return something_changed;
+ return;
}
}
}
/* There are no groups left. */
- spill_failure (max_groups_insn[class]);
+ spill_failure (chain->insn);
failure = 1;
- return 1;
}
-/* Find more reload regs to satisfy the remaining need.
+/* If pseudo REG conflicts with one of our reload registers, mark it as
+ spilled. */
+static void
+maybe_mark_pseudo_spilled (reg)
+ int reg;
+{
+ int i;
+ int r = reg_renumber[reg];
+ int nregs;
+
+ if (r < 0)
+ abort ();
+ nregs = HARD_REGNO_NREGS (r, PSEUDO_REGNO_MODE (reg));
+ for (i = 0; i < n_spills; i++)
+ if (r <= spill_regs[i] && r + nregs > spill_regs[i])
+ {
+ SET_REGNO_REG_SET (spilled_pseudos, reg);
+ return;
+ }
+}
+
+/* Find more reload regs to satisfy the remaining need of an insn, which
+ is given by CHAIN.
Do it by ascending class number, since otherwise a reg
might be spilled for a big class and might fail to count
for a smaller class even though it belongs to that class.
@@ -1903,70 +1899,85 @@ find_group (global, class, dumpfile)
in counting the regs already spilled, and in choose_reload_regs.
It might be hard to avoid introducing bugs there. */
-static int
-find_reload_regs (global, dumpfile)
- int global;
+static void
+find_reload_regs (chain, dumpfile)
+ struct insn_chain *chain;
FILE *dumpfile;
{
- int class;
- int something_changed = 0;
+ int i, class;
+ short *group_needs = chain->need.groups;
+ short *simple_needs = chain->need.regs[0];
+ short *nongroup_needs = chain->need.regs[1];
- CLEAR_HARD_REG_SET (counted_for_groups);
- CLEAR_HARD_REG_SET (counted_for_nongroups);
+ if (dumpfile)
+ fprintf (dumpfile, "Spilling for insn %d.\n", INSN_UID (chain->insn));
+
+ /* Compute the order of preference for hard registers to spill.
+ Store them by decreasing preference in potential_reload_regs. */
+
+ order_regs_for_reload (chain);
+
+ /* So far, no hard regs have been spilled. */
+ n_spills = 0;
+ for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+ spill_reg_order[i] = -1;
+
+ CLEAR_HARD_REG_SET (chain->used_spill_regs);
+ CLEAR_HARD_REG_SET (chain->counted_for_groups);
+ CLEAR_HARD_REG_SET (chain->counted_for_nongroups);
for (class = 0; class < N_REG_CLASSES; class++)
{
/* First get the groups of registers.
If we got single registers first, we might fragment
possible groups. */
- while (max_groups[class] > 0)
+ while (group_needs[class] > 0)
{
/* If any single spilled regs happen to form groups,
count them now. Maybe we don't really need
to spill another group. */
- count_possible_groups (group_size, group_mode, max_groups, class);
+ count_possible_groups (chain, class);
- if (max_groups[class] <= 0)
+ if (group_needs[class] <= 0)
break;
- /* Groups of size 2 (the only groups used on most machines)
+ /* Groups of size 2, the only groups used on most machines,
are treated specially. */
- if (group_size[class] == 2)
- something_changed |= find_tworeg_group (global, class, dumpfile);
+ if (chain->group_size[class] == 2)
+ find_tworeg_group (chain, class, dumpfile);
else
- something_changed |= find_group (global, class, dumpfile);
-
+ find_group (chain, class, dumpfile);
if (failure)
- return 1;
+ return;
}
/* Now similarly satisfy all need for single registers. */
- while (max_needs[class] > 0 || max_nongroups[class] > 0)
+ while (simple_needs[class] > 0 || nongroup_needs[class] > 0)
{
- int i;
/* If we spilled enough regs, but they weren't counted
against the non-group need, see if we can count them now.
If so, we can avoid some actual spilling. */
- if (max_needs[class] <= 0 && max_nongroups[class] > 0)
+ if (simple_needs[class] <= 0 && nongroup_needs[class] > 0)
for (i = 0; i < n_spills; i++)
{
int regno = spill_regs[i];
if (TEST_HARD_REG_BIT (reg_class_contents[class], regno)
- && !TEST_HARD_REG_BIT (counted_for_groups, regno)
- && !TEST_HARD_REG_BIT (counted_for_nongroups, regno)
- && max_nongroups[class] > 0)
- {
- register enum reg_class *p;
+ && !TEST_HARD_REG_BIT (chain->counted_for_groups, regno)
+ && !TEST_HARD_REG_BIT (chain->counted_for_nongroups, regno)
+ && nongroup_needs[class] > 0)
+ {
+ register enum reg_class *p;
- SET_HARD_REG_BIT (counted_for_nongroups, regno);
- max_nongroups[class]--;
- p = reg_class_superclasses[class];
- while (*p != LIM_REG_CLASSES)
- max_nongroups[(int) *p++]--;
- }
+ SET_HARD_REG_BIT (chain->counted_for_nongroups, regno);
+ nongroup_needs[class]--;
+ p = reg_class_superclasses[class];
+ while (*p != LIM_REG_CLASSES)
+ nongroup_needs[(int) *p++]--;
+ }
}
- if (max_needs[class] <= 0 && max_nongroups[class] <= 0)
+
+ if (simple_needs[class] <= 0 && nongroup_needs[class] <= 0)
break;
/* Consider the potential reload regs that aren't
@@ -1984,8 +1995,8 @@ find_reload_regs (global, dumpfile)
but it should be sufficient to make the 386 work,
and the problem should not occur on machines with
more registers. */
- && (max_nongroups[class] == 0
- || possible_group_p (regno, max_groups)))
+ && (nongroup_needs[class] == 0
+ || possible_group_p (chain, regno)))
break;
}
@@ -1996,10 +2007,7 @@ find_reload_regs (global, dumpfile)
group even with this allocation. */
if (i >= FIRST_PSEUDO_REGISTER
- && (asm_noperands (max_needs[class] > 0
- ? max_needs_insn[class]
- : max_nongroups_insn[class])
- < 0))
+ && asm_noperands (chain->insn) < 0)
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
if (potential_reload_regs[i] >= 0
&& TEST_HARD_REG_BIT (reg_class_contents[class],
@@ -2009,89 +2017,94 @@ find_reload_regs (global, dumpfile)
/* I should be the index in potential_reload_regs
of the new reload reg we have found. */
- if (i >= FIRST_PSEUDO_REGISTER)
- {
- /* There are no possible registers left to spill. */
- spill_failure (max_needs[class] > 0 ? max_needs_insn[class]
- : max_nongroups_insn[class]);
- failure = 1;
- return 1;
- }
- else
- something_changed |= new_spill_reg (i, class, max_needs,
- max_nongroups, global,
- dumpfile);
+ new_spill_reg (chain, i, class, 1, dumpfile);
+ if (failure)
+ return;
}
}
- return something_changed;
+
+ /* We know which hard regs to use, now mark the pseudos that live in them
+ as needing to be kicked out. */
+ EXECUTE_IF_SET_IN_REG_SET
+ (chain->live_before, FIRST_PSEUDO_REGISTER, i,
+ {
+ maybe_mark_pseudo_spilled (i);
+ });
+ EXECUTE_IF_SET_IN_REG_SET
+ (chain->live_after, FIRST_PSEUDO_REGISTER, i,
+ {
+ maybe_mark_pseudo_spilled (i);
+ });
+
+ IOR_HARD_REG_SET (used_spill_regs, chain->used_spill_regs);
}
-static void
-dump_needs (dumpfile)
+void
+dump_needs (chain, dumpfile)
+ struct insn_chain *chain;
FILE *dumpfile;
{
static char *reg_class_names[] = REG_CLASS_NAMES;
int i;
+ struct needs *n = &chain->need;
for (i = 0; i < N_REG_CLASSES; i++)
{
- if (max_needs[i] > 0)
+ if (n->regs[i][0] > 0)
fprintf (dumpfile,
- ";; Need %d reg%s of class %s (for insn %d).\n",
- max_needs[i], max_needs[i] == 1 ? "" : "s",
- reg_class_names[i], INSN_UID (max_needs_insn[i]));
- if (max_nongroups[i] > 0)
+ ";; Need %d reg%s of class %s.\n",
+ n->regs[i][0], n->regs[i][0] == 1 ? "" : "s",
+ reg_class_names[i]);
+ if (n->regs[i][1] > 0)
fprintf (dumpfile,
- ";; Need %d nongroup reg%s of class %s (for insn %d).\n",
- max_nongroups[i], max_nongroups[i] == 1 ? "" : "s",
- reg_class_names[i], INSN_UID (max_nongroups_insn[i]));
- if (max_groups[i] > 0)
+ ";; Need %d nongroup reg%s of class %s.\n",
+ n->regs[i][1], n->regs[i][1] == 1 ? "" : "s",
+ reg_class_names[i]);
+ if (n->groups[i] > 0)
fprintf (dumpfile,
- ";; Need %d group%s (%smode) of class %s (for insn %d).\n",
- max_groups[i], max_groups[i] == 1 ? "" : "s",
- mode_name[(int) group_mode[i]],
- reg_class_names[i], INSN_UID (max_groups_insn[i]));
+ ";; Need %d group%s (%smode) of class %s.\n",
+ n->groups[i], n->groups[i] == 1 ? "" : "s",
+ mode_name[(int) chain->group_mode[i]],
+ reg_class_names[i]);
}
}
/* Delete all insns that were inserted by emit_caller_save_insns during
this iteration. */
static void
-delete_caller_save_insns (first)
- rtx first;
+delete_caller_save_insns ()
{
- rtx insn = first;
- int b = -1;
+ struct insn_chain *c = reload_insn_chain;
- while (insn != 0)
+ while (c != 0)
{
- if (b + 1 != n_basic_blocks
- && basic_block_head[b + 1] == insn)
- b++;
-
- while (insn != 0 && INSN_UID (insn) >= reload_first_uid)
+ while (c != 0 && c->is_caller_save_insn)
{
- rtx next = NEXT_INSN (insn);
- rtx prev = PREV_INSN (insn);
-
- if (insn == basic_block_head[b])
- basic_block_head[b] = next;
- if (insn == basic_block_end[b])
- basic_block_end[b] = prev;
-
- if (next != 0)
- PREV_INSN (next) = prev;
- if (prev != 0)
- NEXT_INSN (prev) = next;
-
- insn = next;
-
- if (b + 1 != n_basic_blocks
- && basic_block_head[b + 1] == insn)
- b++;
+ struct insn_chain *next = c->next;
+ rtx insn = c->insn;
+
+ if (insn == BLOCK_HEAD (c->block))
+ BLOCK_HEAD (c->block) = NEXT_INSN (insn);
+ if (insn == BLOCK_END (c->block))
+ BLOCK_END (c->block) = PREV_INSN (insn);
+ if (c == reload_insn_chain)
+ reload_insn_chain = next;
+
+ if (NEXT_INSN (insn) != 0)
+ PREV_INSN (NEXT_INSN (insn)) = PREV_INSN (insn);
+ if (PREV_INSN (insn) != 0)
+ NEXT_INSN (PREV_INSN (insn)) = NEXT_INSN (insn);
+
+ if (next)
+ next->prev = c->prev;
+ if (c->prev)
+ c->prev->next = next;
+ c->next = unused_insn_chains;
+ unused_insn_chains = c;
+ c = next;
}
- if (insn != 0)
- insn = NEXT_INSN (insn);
+ if (c != 0)
+ c = c->next;
}
}
@@ -2099,15 +2112,15 @@ delete_caller_save_insns (first)
it will still be possible to find a group if we still need one. */
static int
-possible_group_p (regno, max_groups)
+possible_group_p (chain, regno)
+ struct insn_chain *chain;
int regno;
- int *max_groups;
{
int i;
int class = (int) NO_REGS;
for (i = 0; i < (int) N_REG_CLASSES; i++)
- if (max_groups[i] > 0)
+ if (chain->need.groups[i] > 0)
{
class = i;
break;
@@ -2142,28 +2155,26 @@ possible_group_p (regno, max_groups)
if (spill_reg_order[i] < 0
&& ! TEST_HARD_REG_BIT (bad_spill_regs, i)
&& spill_reg_order[i + 1] >= 0
- && ! TEST_HARD_REG_BIT (counted_for_groups, i + 1)
- && ! TEST_HARD_REG_BIT (counted_for_nongroups, i + 1))
+ && ! TEST_HARD_REG_BIT (chain->counted_for_groups, i + 1)
+ && ! TEST_HARD_REG_BIT (chain->counted_for_nongroups, i + 1))
return 1;
if (spill_reg_order[i + 1] < 0
&& ! TEST_HARD_REG_BIT (bad_spill_regs, i + 1)
&& spill_reg_order[i] >= 0
- && ! TEST_HARD_REG_BIT (counted_for_groups, i)
- && ! TEST_HARD_REG_BIT (counted_for_nongroups, i))
+ && ! TEST_HARD_REG_BIT (chain->counted_for_groups, i)
+ && ! TEST_HARD_REG_BIT (chain->counted_for_nongroups, i))
return 1;
}
return 0;
}
-
+
/* Count any groups of CLASS that can be formed from the registers recently
spilled. */
static void
-count_possible_groups (group_size, group_mode, max_groups, class)
- int *group_size;
- enum machine_mode *group_mode;
- int *max_groups;
+count_possible_groups (chain, class)
+ struct insn_chain *chain;
int class;
{
HARD_REG_SET new;
@@ -2173,46 +2184,50 @@ count_possible_groups (group_size, group_mode, max_groups, class)
and mark each group off against the need for such groups.
But don't count them against ordinary need, yet. */
- if (group_size[class] == 0)
+ if (chain->group_size[class] == 0)
return;
CLEAR_HARD_REG_SET (new);
/* Make a mask of all the regs that are spill regs in class I. */
for (i = 0; i < n_spills; i++)
- if (TEST_HARD_REG_BIT (reg_class_contents[class], spill_regs[i])
- && ! TEST_HARD_REG_BIT (counted_for_groups, spill_regs[i])
- && ! TEST_HARD_REG_BIT (counted_for_nongroups, spill_regs[i]))
- SET_HARD_REG_BIT (new, spill_regs[i]);
+ {
+ int regno = spill_regs[i];
+
+ if (TEST_HARD_REG_BIT (reg_class_contents[class], regno)
+ && ! TEST_HARD_REG_BIT (chain->counted_for_groups, regno)
+ && ! TEST_HARD_REG_BIT (chain->counted_for_nongroups, regno))
+ SET_HARD_REG_BIT (new, regno);
+ }
/* Find each consecutive group of them. */
- for (i = 0; i < FIRST_PSEUDO_REGISTER && max_groups[class] > 0; i++)
+ for (i = 0; i < FIRST_PSEUDO_REGISTER && chain->need.groups[class] > 0; i++)
if (TEST_HARD_REG_BIT (new, i)
- && i + group_size[class] <= FIRST_PSEUDO_REGISTER
- && HARD_REGNO_MODE_OK (i, group_mode[class]))
+ && i + chain->group_size[class] <= FIRST_PSEUDO_REGISTER
+ && HARD_REGNO_MODE_OK (i, chain->group_mode[class]))
{
- for (j = 1; j < group_size[class]; j++)
+ for (j = 1; j < chain->group_size[class]; j++)
if (! TEST_HARD_REG_BIT (new, i + j))
break;
- if (j == group_size[class])
+ if (j == chain->group_size[class])
{
/* We found a group. Mark it off against this class's need for
groups, and against each superclass too. */
register enum reg_class *p;
- max_groups[class]--;
+ chain->need.groups[class]--;
p = reg_class_superclasses[class];
while (*p != LIM_REG_CLASSES)
{
- if (group_size [(int) *p] <= group_size [class])
- max_groups[(int) *p]--;
+ if (chain->group_size [(int) *p] <= chain->group_size [class])
+ chain->need.groups[(int) *p]--;
p++;
}
/* Don't count these registers again. */
- for (j = 0; j < group_size[class]; j++)
- SET_HARD_REG_BIT (counted_for_groups, i + j);
+ for (j = 0; j < chain->group_size[class]; j++)
+ SET_HARD_REG_BIT (chain->counted_for_groups, i + j);
}
/* Skip to the last reg in this group. When i is incremented above,
@@ -2248,7 +2263,7 @@ modes_equiv_for_class_p (allocate_mode, other_mode, class)
}
return 1;
}
-
+
/* Handle the failure to find a register to spill.
INSN should be one of the insns which needed this particular spill reg. */
@@ -2262,37 +2277,53 @@ spill_failure (insn)
fatal_insn ("Unable to find a register to spill.", insn);
}
-/* Add a new register to the tables of available spill-registers
- (as well as spilling all pseudos allocated to the register).
+/* Add a new register to the tables of available spill-registers.
+ CHAIN is the insn for which the register will be used; we decrease the
+ needs of that insn.
I is the index of this register in potential_reload_regs.
CLASS is the regclass whose need is being satisfied.
- MAX_NEEDS and MAX_NONGROUPS are the vectors of needs,
- so that this register can count off against them.
- MAX_NONGROUPS is 0 if this register is part of a group.
- GLOBAL and DUMPFILE are the same as the args that `reload' got. */
+ NONGROUP is 0 if this register is part of a group.
+ DUMPFILE is the same as the one that `reload' got. */
-static int
-new_spill_reg (i, class, max_needs, max_nongroups, global, dumpfile)
+static void
+new_spill_reg (chain, i, class, nongroup, dumpfile)
+ struct insn_chain *chain;
int i;
int class;
- int *max_needs;
- int *max_nongroups;
- int global;
+ int nongroup;
FILE *dumpfile;
{
register enum reg_class *p;
- int val;
int regno = potential_reload_regs[i];
if (i >= FIRST_PSEUDO_REGISTER)
- abort (); /* Caller failed to find any register. */
+ {
+ spill_failure (chain->insn);
+ failure = 1;
+ return;
+ }
- if (fixed_regs[regno] || TEST_HARD_REG_BIT (forbidden_regs, regno))
+ if (TEST_HARD_REG_BIT (bad_spill_regs, regno))
{
static char *reg_class_names[] = REG_CLASS_NAMES;
- fatal ("fixed or forbidden register %d (%s) was spilled for class %s.\n\
-This may be due to a compiler bug or to impossible asm\n\
-statements or clauses.", regno, reg_names[regno], reg_class_names[class]);
+
+ if (asm_noperands (PATTERN (chain->insn)) < 0)
+ {
+ /* The error message is still correct - we know only that it wasn't
+ an asm statement that caused the problem, but one of the global
+ registers declared by the users might have screwed us. */
+ error ("fixed or forbidden register %d (%s) was spilled for class %s.",
+ regno, reg_names[regno], reg_class_names[class]);
+ error ("This may be due to a compiler bug or to impossible asm");
+ error ("statements or clauses.");
+ fatal_insn ("This is the instruction:", chain->insn);
+ }
+ error_for_asm (chain->insn, "Invalid `asm' statement:");
+ error_for_asm (chain->insn,
+ "fixed or forbidden register %d (%s) was spilled for class %s.",
+ regno, reg_names[regno], reg_class_names[class]);
+ failure = 1;
+ return;
}
/* Make reg REGNO an additional reload reg. */
@@ -2301,49 +2332,26 @@ statements or clauses.", regno, reg_names[regno], reg_class_names[class]);
spill_regs[n_spills] = regno;
spill_reg_order[regno] = n_spills;
if (dumpfile)
- fprintf (dumpfile, "Spilling reg %d.\n", spill_regs[n_spills]);
+ fprintf (dumpfile, "Spilling reg %d.\n", regno);
+ SET_HARD_REG_BIT (chain->used_spill_regs, regno);
/* Clear off the needs we just satisfied. */
- max_needs[class]--;
+ chain->need.regs[0][class]--;
p = reg_class_superclasses[class];
while (*p != LIM_REG_CLASSES)
- max_needs[(int) *p++]--;
+ chain->need.regs[0][(int) *p++]--;
- if (max_nongroups && max_nongroups[class] > 0)
+ if (nongroup && chain->need.regs[1][class] > 0)
{
- SET_HARD_REG_BIT (counted_for_nongroups, regno);
- max_nongroups[class]--;
+ SET_HARD_REG_BIT (chain->counted_for_nongroups, regno);
+ chain->need.regs[1][class]--;
p = reg_class_superclasses[class];
while (*p != LIM_REG_CLASSES)
- max_nongroups[(int) *p++]--;
+ chain->need.regs[1][(int) *p++]--;
}
- /* Spill every pseudo reg that was allocated to this reg
- or to something that overlaps this reg. */
-
- val = spill_hard_reg (spill_regs[n_spills], global, dumpfile, 0);
-
- /* If there are some registers still to eliminate and this register
- wasn't ever used before, additional stack space may have to be
- allocated to store this register. Thus, we may have changed the offset
- between the stack and frame pointers, so mark that something has changed.
- (If new pseudos were spilled, thus requiring more space, VAL would have
- been set non-zero by the call to spill_hard_reg above since additional
- reloads may be needed in that case.
-
- One might think that we need only set VAL to 1 if this is a call-used
- register. However, the set of registers that must be saved by the
- prologue is not identical to the call-used set. For example, the
- register used by the call insn for the return PC is a call-used register,
- but must be saved by the prologue. */
- if (num_eliminable && ! regs_ever_live[spill_regs[n_spills]])
- val = 1;
-
- regs_ever_live[spill_regs[n_spills]] = 1;
n_spills++;
-
- return val;
}
/* Delete an unneeded INSN and any previous insns who sole purpose is loading
@@ -2535,7 +2543,7 @@ set_label_offsets (x, insn, initial_p)
{
enum rtx_code code = GET_CODE (x);
rtx tem;
- int i;
+ unsigned int i;
struct elim_table *p;
switch (code)
@@ -2572,19 +2580,7 @@ set_label_offsets (x, insn, initial_p)
else if (x == insn
&& (tem = prev_nonnote_insn (insn)) != 0
&& GET_CODE (tem) == BARRIER)
- {
- num_not_at_initial_offset = 0;
- for (i = 0; i < NUM_ELIMINABLE_REGS; i++)
- {
- reg_eliminate[i].offset = reg_eliminate[i].previous_offset
- = offsets_at[CODE_LABEL_NUMBER (x)][i];
- if (reg_eliminate[i].can_eliminate
- && (reg_eliminate[i].offset
- != reg_eliminate[i].initial_offset))
- num_not_at_initial_offset++;
- }
- }
-
+ set_offsets_for_label (insn);
else
/* If neither of the above cases is true, compare each offset
with those previously recorded and suppress any eliminations
@@ -2618,7 +2614,7 @@ set_label_offsets (x, insn, initial_p)
offsets. We want the first field for ADDR_VEC and the second
field for ADDR_DIFF_VEC. */
- for (i = 0; i < XVECLEN (x, code == ADDR_DIFF_VEC); i++)
+ for (i = 0; i < (unsigned) XVECLEN (x, code == ADDR_DIFF_VEC); i++)
set_label_offsets (XVECEXP (x, code == ADDR_DIFF_VEC, i),
insn, initial_p);
return;
@@ -2726,6 +2722,9 @@ eliminate_regs (x, mem_mode, insn)
char *fmt;
int copied = 0;
+ if (! current_function_decl)
+ return x;
+
switch (code)
{
case CONST_INT:
@@ -2770,27 +2769,11 @@ eliminate_regs (x, mem_mode, insn)
}
}
- else if (reg_equiv_memory_loc && reg_equiv_memory_loc[regno]
- && (reg_equiv_address[regno] || num_not_at_initial_offset))
- {
- /* In this case, find_reloads would attempt to either use an
- incorrect address (if something is not at its initial offset)
- or substitute an replaced address into an insn (which loses
- if the offset is changed by some later action). So we simply
- return the replaced stack slot (assuming it is changed by
- elimination) and ignore the fact that this is actually a
- reference to the pseudo. Ensure we make a copy of the
- address in case it is shared. */
- new = eliminate_regs (reg_equiv_memory_loc[regno], mem_mode, insn);
- if (new != reg_equiv_memory_loc[regno])
- {
- if (insn != 0 && GET_CODE (insn) != EXPR_LIST
- && GET_CODE (insn) != INSN_LIST)
- REG_NOTES (emit_insn_before (gen_rtx_USE (VOIDmode, x), insn))
- = gen_rtx_EXPR_LIST (REG_EQUAL, new, NULL_RTX);
- return copy_rtx (new);
- }
- }
+ else if (reg_renumber[regno] < 0 && reg_equiv_constant
+ && reg_equiv_constant[regno]
+ && ! CONSTANT_P (reg_equiv_constant[regno]))
+ return eliminate_regs (copy_rtx (reg_equiv_constant[regno]),
+ mem_mode, insn);
return x;
case PLUS:
@@ -2933,7 +2916,17 @@ eliminate_regs (x, mem_mode, insn)
{
new = eliminate_regs (XEXP (x, 0), mem_mode, insn);
if (new != XEXP (x, 0))
- x = gen_rtx_EXPR_LIST (REG_NOTE_KIND (x), new, XEXP (x, 1));
+ {
+ /* If this is a REG_DEAD note, it is not valid anymore.
+ Using the eliminated version could result in creating a
+ REG_DEAD note for the stack or frame pointer. */
+ if (GET_MODE (x) == REG_DEAD)
+ return (XEXP (x, 1)
+ ? eliminate_regs (XEXP (x, 1), mem_mode, insn)
+ : NULL_RTX);
+
+ x = gen_rtx_EXPR_LIST (REG_NOTE_KIND (x), new, XEXP (x, 1));
+ }
}
/* ... fall through ... */
@@ -2998,6 +2991,7 @@ eliminate_regs (x, mem_mode, insn)
&& reg_equiv_memory_loc != 0
&& reg_equiv_memory_loc[REGNO (SUBREG_REG (x))] != 0)
{
+#if 0
new = eliminate_regs (reg_equiv_memory_loc[REGNO (SUBREG_REG (x))],
mem_mode, insn);
@@ -3018,6 +3012,9 @@ eliminate_regs (x, mem_mode, insn)
/* Ensure NEW isn't shared in case we have to reload it. */
new = copy_rtx (new);
}
+#else
+ new = SUBREG_REG (x);
+#endif
}
else
new = eliminate_regs (SUBREG_REG (x), mem_mode, insn);
@@ -3308,7 +3305,7 @@ eliminate_regs_in_insn (insn, replace)
&& ep->to == HARD_FRAME_POINTER_REGNUM)
{
rtx src = SET_SRC (old_set);
- int offset, ok = 0;
+ int offset = 0, ok = 0;
rtx prev_insn, prev_set;
if (src == ep->to_rtx)
@@ -3380,7 +3377,7 @@ eliminate_regs_in_insn (insn, replace)
in the insn is the negative of the offset in FROM. Substitute
(set (reg) (reg to)) for the insn and change its code.
- We have to do this here, rather than in eliminate_regs, do that we can
+ We have to do this here, rather than in eliminate_regs, so that we can
change the insn code. */
if (GET_CODE (SET_SRC (old_set)) == PLUS
@@ -3467,11 +3464,7 @@ eliminate_regs_in_insn (insn, replace)
val = 1;
}
- /* Loop through all elimination pairs. See if any have changed and
- recalculate the number not at initial offset.
-
- Compute the maximum offset (minimum offset if the stack does not
- grow downward) for each elimination pair.
+ /* Loop through all elimination pairs. See if any have changed.
We also detect a cases where register elimination cannot be done,
namely, if a register would be both changed and referenced outside a MEM
@@ -3482,7 +3475,6 @@ eliminate_regs_in_insn (insn, replace)
If anything changes, return nonzero. */
- num_not_at_initial_offset = 0;
for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; ep++)
{
if (ep->previous_offset != ep->offset && ep->ref_outside_mem)
@@ -3492,16 +3484,6 @@ eliminate_regs_in_insn (insn, replace)
if (ep->previous_offset != ep->offset)
val = 1;
-
- ep->previous_offset = ep->offset;
- if (ep->can_eliminate && ep->offset != ep->initial_offset)
- num_not_at_initial_offset++;
-
-#ifdef STACK_GROWS_DOWNWARD
- ep->max_offset = MAX (ep->max_offset, ep->offset);
-#else
- ep->max_offset = MIN (ep->max_offset, ep->offset);
-#endif
}
done:
@@ -3519,6 +3501,26 @@ eliminate_regs_in_insn (insn, replace)
return val;
}
+/* Loop through all elimination pairs.
+ Recalculate the number not at initial offset.
+
+ Compute the maximum offset (minimum offset if the stack does not
+ grow downward) for each elimination pair. */
+
+static void
+update_eliminable_offsets ()
+{
+ struct elim_table *ep;
+
+ num_not_at_initial_offset = 0;
+ for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; ep++)
+ {
+ ep->previous_offset = ep->offset;
+ if (ep->can_eliminate && ep->offset != ep->initial_offset)
+ num_not_at_initial_offset++;
+ }
+}
+
/* Given X, a SET or CLOBBER of DEST, if DEST is the target of a register
replacement we currently believe is valid, mark it as not eliminable if X
modifies DEST in any way other than by adding a constant integer to it.
@@ -3538,7 +3540,7 @@ mark_not_eliminable (dest, x)
rtx dest;
rtx x;
{
- register int i;
+ register unsigned int i;
/* A SUBREG of a hard register here is just changing its mode. We should
not see a SUBREG of an eliminable hard register, but check just in
@@ -3562,47 +3564,88 @@ mark_not_eliminable (dest, x)
}
}
-/* Reset all offsets on eliminable registers to their initial values. */
+/* Verify that the initial elimination offsets did not change since the
+ last call to set_initial_elim_offsets. This is used to catch cases
+ where something illegal happened during reload_as_needed that could
+ cause incorrect code to be generated if we did not check for it. */
static void
-set_initial_elim_offsets ()
+verify_initial_elim_offsets ()
{
- rtx x;
+ int t;
#ifdef ELIMINABLE_REGS
struct elim_table *ep;
for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; ep++)
{
- INITIAL_ELIMINATION_OFFSET (ep->from, ep->to, ep->initial_offset);
- ep->previous_offset = ep->offset
- = ep->max_offset = ep->initial_offset;
+ INITIAL_ELIMINATION_OFFSET (ep->from, ep->to, t);
+ if (t != ep->initial_offset)
+ abort ();
}
#else
-#ifdef INITIAL_FRAME_POINTER_OFFSET
- INITIAL_FRAME_POINTER_OFFSET (reg_eliminate[0].initial_offset);
-#else
- if (!FRAME_POINTER_REQUIRED)
+ INITIAL_FRAME_POINTER_OFFSET (t);
+ if (t != reg_eliminate[0].initial_offset)
abort ();
- reg_eliminate[0].initial_offset = 0;
-#endif
- reg_eliminate[0].previous_offset = reg_eliminate[0].max_offset
- = reg_eliminate[0].offset = reg_eliminate[0].initial_offset;
+#endif
+}
+
+/* Reset all offsets on eliminable registers to their initial values. */
+static void
+set_initial_elim_offsets ()
+{
+ struct elim_table *ep = reg_eliminate;
+
+#ifdef ELIMINABLE_REGS
+ for (; ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; ep++)
+ {
+ INITIAL_ELIMINATION_OFFSET (ep->from, ep->to, ep->initial_offset);
+ ep->previous_offset = ep->offset = ep->initial_offset;
+ }
+#else
+ INITIAL_FRAME_POINTER_OFFSET (ep->initial_offset);
+ ep->previous_offset = ep->offset = ep->initial_offset;
#endif
num_not_at_initial_offset = 0;
+}
- bzero ((char *) &offsets_known_at[get_first_label_num ()], num_labels);
+/* Initialize the known label offsets.
+ Set a known offset for each forced label to be at the initial offset
+ of each elimination. We do this because we assume that all
+ computed jumps occur from a location where each elimination is
+ at its initial offset.
+ For all other labels, show that we don't know the offsets. */
- /* Set a known offset for each forced label to be at the initial offset
- of each elimination. We do this because we assume that all
- computed jumps occur from a location where each elimination is
- at its initial offset. */
+static void
+set_initial_label_offsets ()
+{
+ rtx x;
+ bzero ((char *) &offsets_known_at[get_first_label_num ()], num_labels);
for (x = forced_labels; x; x = XEXP (x, 1))
if (XEXP (x, 0))
set_label_offsets (XEXP (x, 0), NULL_RTX, 1);
}
+/* Set all elimination offsets to the known values for the code label given
+ by INSN. */
+static void
+set_offsets_for_label (insn)
+ rtx insn;
+{
+ unsigned int i;
+ int label_nr = CODE_LABEL_NUMBER (insn);
+ struct elim_table *ep;
+
+ num_not_at_initial_offset = 0;
+ for (i = 0, ep = reg_eliminate; i < NUM_ELIMINABLE_REGS; ep++, i++)
+ {
+ ep->offset = ep->previous_offset = offsets_at[label_nr][i];
+ if (ep->can_eliminate && ep->offset != ep->initial_offset)
+ num_not_at_initial_offset++;
+ }
+}
+
/* See if anything that happened changes which eliminations are valid.
For example, on the Sparc, whether or not the frame pointer can
be eliminated can depend on what registers have been used. We need
@@ -3693,7 +3736,18 @@ static void
init_elim_table ()
{
struct elim_table *ep;
+#ifdef ELIMINABLE_REGS
+ struct elim_table_1 *ep1;
+#endif
+ if (!reg_eliminate)
+ {
+ reg_eliminate = (struct elim_table *)
+ xmalloc(sizeof(struct elim_table) * NUM_ELIMINABLE_REGS);
+ bzero ((PTR) reg_eliminate,
+ sizeof(struct elim_table) * NUM_ELIMINABLE_REGS);
+ }
+
/* Does this function require a frame pointer? */
frame_pointer_needed = (! flag_omit_frame_pointer
@@ -3711,13 +3765,18 @@ init_elim_table ()
num_eliminable = 0;
#ifdef ELIMINABLE_REGS
- for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; ep++)
+ for (ep = reg_eliminate, ep1 = reg_eliminate_1;
+ ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; ep++, ep1++)
{
+ ep->from = ep1->from;
+ ep->to = ep1->to;
ep->can_eliminate = ep->can_eliminate_previous
= (CAN_ELIMINATE (ep->from, ep->to)
&& ! (ep->to == STACK_POINTER_REGNUM && frame_pointer_needed));
}
#else
+ reg_eliminate[0].from = reg_eliminate_1[0].from;
+ reg_eliminate[0].to = reg_eliminate_1[0].to;
reg_eliminate[0].can_eliminate = reg_eliminate[0].can_eliminate_previous
= ! frame_pointer_needed;
#endif
@@ -3735,7 +3794,6 @@ init_elim_table ()
}
/* Kick all pseudos out of hard register REGNO.
- If GLOBAL is nonzero, try to find someplace else to put them.
If DUMPFILE is nonzero, log actions taken on that file.
If CANT_ELIMINATE is nonzero, it means that we are doing this spill
@@ -3746,21 +3804,19 @@ init_elim_table ()
Return nonzero if any pseudos needed to be kicked out. */
-static int
-spill_hard_reg (regno, global, dumpfile, cant_eliminate)
+static void
+spill_hard_reg (regno, dumpfile, cant_eliminate)
register int regno;
- int global;
FILE *dumpfile;
int cant_eliminate;
{
- enum reg_class class = REGNO_REG_CLASS (regno);
- int something_changed = 0;
register int i;
- SET_HARD_REG_BIT (forbidden_regs, regno);
-
if (cant_eliminate)
- regs_ever_live[regno] = 1;
+ {
+ SET_HARD_REG_BIT (bad_spill_regs_global, regno);
+ regs_ever_live[regno] = 1;
+ }
/* Spill every pseudo reg that was allocated to this reg
or to something that overlaps this reg. */
@@ -3772,45 +3828,165 @@ spill_hard_reg (regno, global, dumpfile, cant_eliminate)
+ HARD_REGNO_NREGS (reg_renumber[i],
PSEUDO_REGNO_MODE (i))
> regno))
- {
- /* If this register belongs solely to a basic block which needed no
- spilling of any class that this register is contained in,
- leave it be, unless we are spilling this register because
- it was a hard register that can't be eliminated. */
-
- if (! cant_eliminate
- && basic_block_needs[0]
- && REG_BASIC_BLOCK (i) >= 0
- && basic_block_needs[(int) class][REG_BASIC_BLOCK (i)] == 0)
- {
- enum reg_class *p;
+ SET_REGNO_REG_SET (spilled_pseudos, i);
+}
- for (p = reg_class_superclasses[(int) class];
- *p != LIM_REG_CLASSES; p++)
- if (basic_block_needs[(int) *p][REG_BASIC_BLOCK (i)] > 0)
- break;
+/* I'm getting weird preprocessor errors if I use IOR_HARD_REG_SET
+ from within EXECUTE_IF_SET_IN_REG_SET. Hence this awkwardness. */
+static void
+ior_hard_reg_set (set1, set2)
+ HARD_REG_SET *set1, *set2;
+{
+ IOR_HARD_REG_SET (*set1, *set2);
+}
+
+/* After find_reload_regs has been run for all insn that need reloads,
+ and/or spill_hard_regs was called, this function is used to actually
+ spill pseudo registers and try to reallocate them. It also sets up the
+ spill_regs array for use by choose_reload_regs. */
- if (*p == LIM_REG_CLASSES)
- continue;
- }
+static int
+finish_spills (global, dumpfile)
+ int global;
+ FILE *dumpfile;
+{
+ struct insn_chain *chain;
+ int something_changed = 0;
+ int i;
+ /* Build the spill_regs array for the function. */
+ /* If there are some registers still to eliminate and one of the spill regs
+ wasn't ever used before, additional stack space may have to be
+ allocated to store this register. Thus, we may have changed the offset
+ between the stack and frame pointers, so mark that something has changed.
+
+ One might think that we need only set VAL to 1 if this is a call-used
+ register. However, the set of registers that must be saved by the
+ prologue is not identical to the call-used set. For example, the
+ register used by the call insn for the return PC is a call-used register,
+ but must be saved by the prologue. */
+
+ n_spills = 0;
+ for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+ if (TEST_HARD_REG_BIT (used_spill_regs, i))
+ {
+ spill_reg_order[i] = n_spills;
+ spill_regs[n_spills++] = i;
+ if (num_eliminable && ! regs_ever_live[i])
+ something_changed = 1;
+ regs_ever_live[i] = 1;
+ }
+ else
+ spill_reg_order[i] = -1;
+
+ for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
+ if (REGNO_REG_SET_P (spilled_pseudos, i))
+ {
+ /* Record the current hard register the pseudo is allocated to in
+ pseudo_previous_regs so we avoid reallocating it to the same
+ hard reg in a later pass. */
+ if (reg_renumber[i] < 0)
+ abort ();
+ SET_HARD_REG_BIT (pseudo_previous_regs[i], reg_renumber[i]);
/* Mark it as no longer having a hard register home. */
reg_renumber[i] = -1;
/* We will need to scan everything again. */
something_changed = 1;
- if (global)
- retry_global_alloc (i, forbidden_regs);
+ }
- alter_reg (i, regno);
- if (dumpfile)
+ /* Retry global register allocation if possible. */
+ if (global)
+ {
+ bzero ((char *) pseudo_forbidden_regs, max_regno * sizeof (HARD_REG_SET));
+ /* For every insn that needs reloads, set the registers used as spill
+ regs in pseudo_forbidden_regs for every pseudo live across the
+ insn. */
+ for (chain = insns_need_reload; chain; chain = chain->next_need_reload)
+ {
+ EXECUTE_IF_SET_IN_REG_SET
+ (chain->live_before, FIRST_PSEUDO_REGISTER, i,
+ {
+ ior_hard_reg_set (pseudo_forbidden_regs + i,
+ &chain->used_spill_regs);
+ });
+ EXECUTE_IF_SET_IN_REG_SET
+ (chain->live_after, FIRST_PSEUDO_REGISTER, i,
+ {
+ ior_hard_reg_set (pseudo_forbidden_regs + i,
+ &chain->used_spill_regs);
+ });
+ }
+
+ /* Retry allocating the spilled pseudos. For each reg, merge the
+ various reg sets that indicate which hard regs can't be used,
+ and call retry_global_alloc.
+ We change spill_pseudos here to only contain pseudos that did not
+ get a new hard register. */
+ for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
+ if (reg_old_renumber[i] != reg_renumber[i])
{
- if (reg_renumber[i] == -1)
- fprintf (dumpfile, " Register %d now on stack.\n\n", i);
- else
- fprintf (dumpfile, " Register %d now in %d.\n\n",
- i, reg_renumber[i]);
+ HARD_REG_SET forbidden;
+ COPY_HARD_REG_SET (forbidden, bad_spill_regs_global);
+ IOR_HARD_REG_SET (forbidden, pseudo_forbidden_regs[i]);
+ IOR_HARD_REG_SET (forbidden, pseudo_previous_regs[i]);
+ retry_global_alloc (i, forbidden);
+ if (reg_renumber[i] >= 0)
+ CLEAR_REGNO_REG_SET (spilled_pseudos, i);
}
- }
+ }
+
+ /* Fix up the register information in the insn chain.
+ This involves deleting those of the spilled pseudos which did not get
+ a new hard register home from the live_{before,after} sets. */
+ for (chain = reload_insn_chain; chain; chain = chain->next)
+ {
+ HARD_REG_SET used_by_pseudos;
+ HARD_REG_SET used_by_pseudos2;
+
+ AND_COMPL_REG_SET (chain->live_before, spilled_pseudos);
+ AND_COMPL_REG_SET (chain->live_after, spilled_pseudos);
+
+ /* Mark any unallocated hard regs as available for spills. That
+ makes inheritance work somewhat better. */
+ if (chain->need_reload)
+ {
+ REG_SET_TO_HARD_REG_SET (used_by_pseudos, chain->live_before);
+ REG_SET_TO_HARD_REG_SET (used_by_pseudos2, chain->live_after);
+ IOR_HARD_REG_SET (used_by_pseudos, used_by_pseudos2);
+
+ /* Save the old value for the sanity test below. */
+ COPY_HARD_REG_SET (used_by_pseudos2, chain->used_spill_regs);
+
+ compute_use_by_pseudos (&used_by_pseudos, chain->live_before);
+ compute_use_by_pseudos (&used_by_pseudos, chain->live_after);
+ COMPL_HARD_REG_SET (chain->used_spill_regs, used_by_pseudos);
+ AND_HARD_REG_SET (chain->used_spill_regs, used_spill_regs);
+
+ /* Make sure we only enlarge the set. */
+ GO_IF_HARD_REG_SUBSET (used_by_pseudos2, chain->used_spill_regs, ok);
+ abort ();
+ ok:;
+ }
+ }
+
+ /* Let alter_reg modify the reg rtx's for the modified pseudos. */
+ for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
+ {
+ int regno = reg_renumber[i];
+ if (reg_old_renumber[i] == regno)
+ continue;
+
+ alter_reg (i, reg_old_renumber[i]);
+ reg_old_renumber[i] = regno;
+ if (dumpfile)
+ {
+ if (regno == -1)
+ fprintf (dumpfile, " Register %d now on stack.\n\n", i);
+ else
+ fprintf (dumpfile, " Register %d now in %d.\n\n",
+ i, reg_renumber[i]);
+ }
+ }
return something_changed;
}
@@ -3830,9 +4006,11 @@ scan_paradoxical_subregs (x)
switch (code)
{
case REG:
+#if 0
if (SMALL_REGISTER_CLASSES && REGNO (x) < FIRST_PSEUDO_REGISTER
&& REG_USERVAR_P (x))
- SET_HARD_REG_BIT (forbidden_regs, REGNO (x));
+ SET_HARD_REG_BIT (bad_spill_regs_global, REGNO (x));
+#endif
return;
case CONST_INT:
@@ -3873,92 +4051,105 @@ scan_paradoxical_subregs (x)
static int
hard_reg_use_compare (p1p, p2p)
- const GENERIC_PTR p1p;
- const GENERIC_PTR p2p;
-{
- struct hard_reg_n_uses *p1 = (struct hard_reg_n_uses *)p1p,
- *p2 = (struct hard_reg_n_uses *)p2p;
- int tem = p1->uses - p2->uses;
- if (tem != 0) return tem;
+ const GENERIC_PTR p1p;
+ const GENERIC_PTR p2p;
+{
+ struct hard_reg_n_uses *p1 = (struct hard_reg_n_uses *)p1p;
+ struct hard_reg_n_uses *p2 = (struct hard_reg_n_uses *)p2p;
+ int bad1 = TEST_HARD_REG_BIT (bad_spill_regs, p1->regno);
+ int bad2 = TEST_HARD_REG_BIT (bad_spill_regs, p2->regno);
+ if (bad1 && bad2)
+ return p1->regno - p2->regno;
+ if (bad1)
+ return 1;
+ if (bad2)
+ return -1;
+ if (p1->uses > p2->uses)
+ return 1;
+ if (p1->uses < p2->uses)
+ return -1;
/* If regs are equally good, sort by regno,
so that the results of qsort leave nothing to chance. */
return p1->regno - p2->regno;
}
+/* Used for communication between order_regs_for_reload and count_pseudo.
+ Used to avoid counting one pseudo twice. */
+static regset pseudos_counted;
+
+/* Update the costs in N_USES, considering that pseudo REG is live. */
+static void
+count_pseudo (n_uses, reg)
+ struct hard_reg_n_uses *n_uses;
+ int reg;
+{
+ int r = reg_renumber[reg];
+ int nregs;
+
+ if (REGNO_REG_SET_P (pseudos_counted, reg))
+ return;
+ SET_REGNO_REG_SET (pseudos_counted, reg);
+
+ if (r < 0)
+ abort ();
+
+ nregs = HARD_REGNO_NREGS (r, PSEUDO_REGNO_MODE (reg));
+ while (nregs-- > 0)
+ n_uses[r++].uses += REG_N_REFS (reg);
+}
/* Choose the order to consider regs for use as reload registers
based on how much trouble would be caused by spilling one.
Store them in order of decreasing preference in potential_reload_regs. */
static void
-order_regs_for_reload ()
+order_regs_for_reload (chain)
+ struct insn_chain *chain;
{
register int i;
register int o = 0;
- int large = 0;
-
struct hard_reg_n_uses hard_reg_n_uses[FIRST_PSEUDO_REGISTER];
- CLEAR_HARD_REG_SET (bad_spill_regs);
+ pseudos_counted = ALLOCA_REG_SET ();
- for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
- potential_reload_regs[i] = -1;
+ COPY_HARD_REG_SET (bad_spill_regs, bad_spill_regs_global);
/* Count number of uses of each hard reg by pseudo regs allocated to it
and then order them by decreasing use. */
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
{
- hard_reg_n_uses[i].uses = 0;
- hard_reg_n_uses[i].regno = i;
- }
-
- for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
- {
- int regno = reg_renumber[i];
- if (regno >= 0)
- {
- int lim = regno + HARD_REGNO_NREGS (regno, PSEUDO_REGNO_MODE (i));
- while (regno < lim)
- hard_reg_n_uses[regno++].uses += REG_N_REFS (i);
- }
- large += REG_N_REFS (i);
- }
+ int j;
- /* Now fixed registers (which cannot safely be used for reloading)
- get a very high use count so they will be considered least desirable.
- Registers used explicitly in the rtl code are almost as bad. */
+ hard_reg_n_uses[i].regno = i;
+ hard_reg_n_uses[i].uses = 0;
- for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
- {
- if (fixed_regs[i])
+ /* Test the various reasons why we can't use a register for
+ spilling in this insn. */
+ if (fixed_regs[i]
+ || REGNO_REG_SET_P (chain->live_before, i)
+ || REGNO_REG_SET_P (chain->live_after, i))
{
- hard_reg_n_uses[i].uses += 2 * large + 2;
SET_HARD_REG_BIT (bad_spill_regs, i);
+ continue;
}
- else if (regs_explicitly_used[i])
- {
- hard_reg_n_uses[i].uses += large + 1;
- if (! SMALL_REGISTER_CLASSES)
- /* ??? We are doing this here because of the potential
- that bad code may be generated if a register explicitly
- used in an insn was used as a spill register for that
- insn. But not using these are spill registers may lose
- on some machine. We'll have to see how this works out. */
- SET_HARD_REG_BIT (bad_spill_regs, i);
- }
- }
- hard_reg_n_uses[HARD_FRAME_POINTER_REGNUM].uses += 2 * large + 2;
- SET_HARD_REG_BIT (bad_spill_regs, HARD_FRAME_POINTER_REGNUM);
-#ifdef ELIMINABLE_REGS
- /* If registers other than the frame pointer are eliminable, mark them as
- poor choices. */
- for (i = 0; i < NUM_ELIMINABLE_REGS; i++)
- {
- hard_reg_n_uses[reg_eliminate[i].from].uses += 2 * large + 2;
- SET_HARD_REG_BIT (bad_spill_regs, reg_eliminate[i].from);
+ /* Now find out which pseudos are allocated to it, and update
+ hard_reg_n_uses. */
+ CLEAR_REG_SET (pseudos_counted);
+
+ EXECUTE_IF_SET_IN_REG_SET
+ (chain->live_before, FIRST_PSEUDO_REGISTER, j,
+ {
+ count_pseudo (hard_reg_n_uses, j);
+ });
+ EXECUTE_IF_SET_IN_REG_SET
+ (chain->live_after, FIRST_PSEUDO_REGISTER, j,
+ {
+ count_pseudo (hard_reg_n_uses, j);
+ });
}
-#endif
+
+ FREE_REG_SET (pseudos_counted);
/* Prefer registers not so far used, for use in temporary loading.
Among them, if REG_ALLOC_ORDER is defined, use that order.
@@ -3969,18 +4160,21 @@ order_regs_for_reload ()
{
int regno = reg_alloc_order[i];
- if (hard_reg_n_uses[regno].uses == 0)
+ if (hard_reg_n_uses[regno].uses == 0
+ && ! TEST_HARD_REG_BIT (bad_spill_regs, regno))
potential_reload_regs[o++] = regno;
}
#else
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
{
- if (hard_reg_n_uses[i].uses == 0 && call_used_regs[i])
+ if (hard_reg_n_uses[i].uses == 0 && call_used_regs[i]
+ && ! TEST_HARD_REG_BIT (bad_spill_regs, i))
potential_reload_regs[o++] = i;
}
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
{
- if (hard_reg_n_uses[i].uses == 0 && ! call_used_regs[i])
+ if (hard_reg_n_uses[i].uses == 0 && ! call_used_regs[i]
+ && ! TEST_HARD_REG_BIT (bad_spill_regs, i))
potential_reload_regs[o++] = i;
}
#endif
@@ -3993,21 +4187,14 @@ order_regs_for_reload ()
registers will be at the end of this list. */
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
- if (hard_reg_n_uses[i].uses != 0)
+ if (hard_reg_n_uses[i].uses != 0
+ && ! TEST_HARD_REG_BIT (bad_spill_regs, hard_reg_n_uses[i].regno))
+ potential_reload_regs[o++] = hard_reg_n_uses[i].regno;
+ for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+ if (TEST_HARD_REG_BIT (bad_spill_regs, hard_reg_n_uses[i].regno))
potential_reload_regs[o++] = hard_reg_n_uses[i].regno;
}
-/* Used in reload_as_needed to sort the spilled regs. */
-
-static int
-compare_spill_regs (r1p, r2p)
- const GENERIC_PTR r1p;
- const GENERIC_PTR r2p;
-{
- short r1 = *(short *)r1p, r2 = *(short *)r2p;
- return r1 - r2;
-}
-
/* Reload pseudo-registers into hard regs around each insn as needed.
Additional register load insns are output before the insn that needs it
and perhaps store insns after insns that modify the reloaded pseudo reg.
@@ -4018,15 +4205,14 @@ compare_spill_regs (r1p, r2p)
as the insns are scanned. */
static void
-reload_as_needed (first, live_known)
- rtx first;
+reload_as_needed (live_known)
int live_known;
{
- register rtx insn;
+ struct insn_chain *chain;
+#if defined (AUTO_INC_DEC) || defined (INSN_CLOBBERS_REGNO_P)
register int i;
- int this_block = 0;
+#endif
rtx x;
- rtx after_call = 0;
bzero ((char *) spill_reg_rtx, sizeof spill_reg_rtx);
bzero ((char *) spill_reg_store, sizeof spill_reg_store);
@@ -4035,84 +4221,23 @@ reload_as_needed (first, live_known)
reg_has_output_reload = (char *) alloca (max_regno);
CLEAR_HARD_REG_SET (reg_reloaded_valid);
- /* Reset all offsets on eliminable registers to their initial values. */
-#ifdef ELIMINABLE_REGS
- for (i = 0; i < NUM_ELIMINABLE_REGS; i++)
- {
- INITIAL_ELIMINATION_OFFSET (reg_eliminate[i].from, reg_eliminate[i].to,
- reg_eliminate[i].initial_offset);
- reg_eliminate[i].previous_offset
- = reg_eliminate[i].offset = reg_eliminate[i].initial_offset;
- }
-#else
- INITIAL_FRAME_POINTER_OFFSET (reg_eliminate[0].initial_offset);
- reg_eliminate[0].previous_offset
- = reg_eliminate[0].offset = reg_eliminate[0].initial_offset;
-#endif
-
- num_not_at_initial_offset = 0;
-
- /* Order the spilled regs, so that allocate_reload_regs can guarantee to
- pack registers with group needs. */
- if (n_spills > 1)
- {
- qsort (spill_regs, n_spills, sizeof (short), compare_spill_regs);
- for (i = 0; i < n_spills; i++)
- spill_reg_order[spill_regs[i]] = i;
- }
+ set_initial_elim_offsets ();
- for (insn = first; insn;)
+ for (chain = reload_insn_chain; chain; chain = chain->next)
{
- register rtx next = NEXT_INSN (insn);
-
- /* Notice when we move to a new basic block. */
- if (live_known && this_block + 1 < n_basic_blocks
- && insn == basic_block_head[this_block+1])
- ++this_block;
+ rtx prev;
+ rtx insn = chain->insn;
+ rtx old_next = NEXT_INSN (insn);
/* If we pass a label, copy the offsets from the label information
into the current offsets of each elimination. */
if (GET_CODE (insn) == CODE_LABEL)
- {
- num_not_at_initial_offset = 0;
- for (i = 0; i < NUM_ELIMINABLE_REGS; i++)
- {
- reg_eliminate[i].offset = reg_eliminate[i].previous_offset
- = offsets_at[CODE_LABEL_NUMBER (insn)][i];
- if (reg_eliminate[i].can_eliminate
- && (reg_eliminate[i].offset
- != reg_eliminate[i].initial_offset))
- num_not_at_initial_offset++;
- }
- }
+ set_offsets_for_label (insn);
else if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
{
- rtx avoid_return_reg = 0;
rtx oldpat = PATTERN (insn);
- /* Set avoid_return_reg if this is an insn
- that might use the value of a function call. */
- if (SMALL_REGISTER_CLASSES && GET_CODE (insn) == CALL_INSN)
- {
- if (GET_CODE (PATTERN (insn)) == SET)
- after_call = SET_DEST (PATTERN (insn));
- else if (GET_CODE (PATTERN (insn)) == PARALLEL
- && GET_CODE (XVECEXP (PATTERN (insn), 0, 0)) == SET)
- after_call = SET_DEST (XVECEXP (PATTERN (insn), 0, 0));
- else
- after_call = 0;
- }
- else if (SMALL_REGISTER_CLASSES && after_call != 0
- && !(GET_CODE (PATTERN (insn)) == SET
- && SET_DEST (PATTERN (insn)) == stack_pointer_rtx)
- && GET_CODE (PATTERN (insn)) != USE)
- {
- if (reg_referenced_p (after_call, PATTERN (insn)))
- avoid_return_reg = after_call;
- after_call = 0;
- }
-
/* If this is a USE and CLOBBER of a MEM, ensure that any
references to eliminable registers have been removed. */
@@ -4126,17 +4251,25 @@ reload_as_needed (first, live_known)
/* If we need to do register elimination processing, do so.
This might delete the insn, in which case we are done. */
- if (num_eliminable && GET_MODE (insn) == QImode)
+ if ((num_eliminable || num_eliminable_invariants) && chain->need_elim)
{
eliminate_regs_in_insn (insn, 1);
if (GET_CODE (insn) == NOTE)
{
- insn = next;
+ update_eliminable_offsets ();
continue;
}
}
- if (GET_MODE (insn) == VOIDmode)
+ /* If need_elim is nonzero but need_reload is zero, one might think
+ that we could simply set n_reloads to 0. However, find_reloads
+ could have done some manipulation of the insn (such as swapping
+ commutative operands), and these manipulations are lost during
+ the first pass for every insn that needs register elimination.
+ So the actions of find_reloads must be redone here. */
+
+ if (! chain->need_elim && ! chain->need_reload
+ && ! chain->need_operand_change)
n_reloads = 0;
/* First find the pseudo regs that must be reloaded for this insn.
This info is returned in the tables reload_... (see reload.h).
@@ -4151,32 +4284,21 @@ reload_as_needed (first, live_known)
spill_reg_order);
}
+ if (num_eliminable && chain->need_elim)
+ update_eliminable_offsets ();
+
if (n_reloads > 0)
{
- rtx prev = PREV_INSN (insn), next = NEXT_INSN (insn);
+ rtx next = NEXT_INSN (insn);
rtx p;
- int class;
-
- /* If this block has not had spilling done for a
- particular clas and we have any non-optionals that need a
- spill reg in that class, abort. */
-
- for (class = 0; class < N_REG_CLASSES; class++)
- if (basic_block_needs[class] != 0
- && basic_block_needs[class][this_block] == 0)
- for (i = 0; i < n_reloads; i++)
- if (class == (int) reload_reg_class[i]
- && reload_reg_rtx[i] == 0
- && ! reload_optional[i]
- && (reload_in[i] != 0 || reload_out[i] != 0
- || reload_secondary_p[i] != 0))
- fatal_insn ("Non-optional registers need a spill register", insn);
+
+ prev = PREV_INSN (insn);
/* Now compute which reload regs to reload them into. Perhaps
reusing reload regs from previous insns, or else output
load insns to reload them. Maybe output store insns too.
Record the choices of reload reg in reload_reg_rtx. */
- choose_reload_regs (insn, avoid_return_reg);
+ choose_reload_regs (chain);
/* Merge any reloads that we didn't combine for fear of
increasing the number of spill registers needed but now
@@ -4186,7 +4308,7 @@ reload_as_needed (first, live_known)
/* Generate the insns to reload operands into or out of
their reload regs. */
- emit_reload_insns (insn, this_block);
+ emit_reload_insns (chain);
/* Substitute the chosen reload regs from reload_reg_rtx
into the insn's body (or perhaps into the bodies of other
@@ -4202,8 +4324,7 @@ reload_as_needed (first, live_known)
for (p = NEXT_INSN (prev); p != next; p = NEXT_INSN (p))
if (p != insn && GET_RTX_CLASS (GET_CODE (p)) == 'i'
&& (recog_memoized (p) < 0
- || (insn_extract (p),
- ! constrain_operands (INSN_CODE (p), 1))))
+ || (extract_insn (p), ! constrain_operands (1))))
{
error_for_asm (insn,
"`asm' operand requires impossible reload");
@@ -4222,14 +4343,109 @@ reload_as_needed (first, live_known)
/* There may have been CLOBBER insns placed after INSN. So scan
between INSN and NEXT and use them to forget old reloads. */
- for (x = NEXT_INSN (insn); x != next; x = NEXT_INSN (x))
+ for (x = NEXT_INSN (insn); x != old_next; x = NEXT_INSN (x))
if (GET_CODE (x) == INSN && GET_CODE (PATTERN (x)) == CLOBBER)
note_stores (PATTERN (x), forget_old_reloads_1);
#ifdef AUTO_INC_DEC
/* Likewise for regs altered by auto-increment in this insn.
- But note that the reg-notes are not changed by reloading:
- they still contain the pseudo-regs, not the spill regs. */
+ REG_INC notes have been changed by reloading:
+ find_reloads_address_1 records substitutions for them,
+ which have been performed by subst_reloads above. */
+ for (i = n_reloads - 1; i >= 0; i--)
+ {
+ rtx in_reg = reload_in_reg[i];
+ if (in_reg)
+ {
+ enum rtx_code code = GET_CODE (in_reg);
+ /* PRE_INC / PRE_DEC will have the reload register ending up
+ with the same value as the stack slot, but that doesn't
+ hold true for POST_INC / POST_DEC. Either we have to
+ convert the memory access to a true POST_INC / POST_DEC,
+ or we can't use the reload register for inheritance. */
+ if ((code == POST_INC || code == POST_DEC)
+ && TEST_HARD_REG_BIT (reg_reloaded_valid,
+ REGNO (reload_reg_rtx[i]))
+ /* Make sure it is the inc/dec pseudo, and not
+ some other (e.g. output operand) pseudo. */
+ && (reg_reloaded_contents[REGNO (reload_reg_rtx[i])]
+ == REGNO (XEXP (in_reg, 0))))
+
+ {
+ rtx reload_reg = reload_reg_rtx[i];
+ enum machine_mode mode = GET_MODE (reload_reg);
+ int n = 0;
+ rtx p;
+
+ for (p = PREV_INSN (old_next); p != prev; p = PREV_INSN (p))
+ {
+ /* We really want to ignore REG_INC notes here, so
+ use PATTERN (p) as argument to reg_set_p . */
+ if (reg_set_p (reload_reg, PATTERN (p)))
+ break;
+ n = count_occurrences (PATTERN (p), reload_reg);
+ if (! n)
+ continue;
+ if (n == 1)
+ {
+ n = validate_replace_rtx (reload_reg,
+ gen_rtx (code, mode,
+ reload_reg),
+ p);
+
+ /* We must also verify that the constraints
+ are met after the replacement. */
+ extract_insn (p);
+ if (n)
+ n = constrain_operands (1);
+ else
+ break;
+
+ /* If the constraints were not met, then
+ undo the replacement. */
+ if (!n)
+ {
+ validate_replace_rtx (gen_rtx (code, mode,
+ reload_reg),
+ reload_reg, p);
+ break;
+ }
+
+ }
+ break;
+ }
+ if (n == 1)
+ {
+ REG_NOTES (p)
+ = gen_rtx_EXPR_LIST (REG_INC, reload_reg,
+ REG_NOTES (p));
+ /* Mark this as having an output reload so that the
+ REG_INC processing code below won't invalidate
+ the reload for inheritance. */
+ SET_HARD_REG_BIT (reg_is_output_reload,
+ REGNO (reload_reg));
+ reg_has_output_reload[REGNO (XEXP (in_reg, 0))] = 1;
+ }
+ else
+ forget_old_reloads_1 (XEXP (in_reg, 0), NULL_RTX);
+ }
+ else if ((code == PRE_INC || code == PRE_DEC)
+ && TEST_HARD_REG_BIT (reg_reloaded_valid,
+ REGNO (reload_reg_rtx[i]))
+ /* Make sure it is the inc/dec pseudo, and not
+ some other (e.g. output operand) pseudo. */
+ && (reg_reloaded_contents[REGNO (reload_reg_rtx[i])]
+ == REGNO (XEXP (in_reg, 0))))
+ {
+ SET_HARD_REG_BIT (reg_is_output_reload,
+ REGNO (reload_reg_rtx[i]));
+ reg_has_output_reload[REGNO (XEXP (in_reg, 0))] = 1;
+ }
+ }
+ }
+ /* If a pseudo that got a hard register is auto-incremented,
+ we must purge records of copying it into pseudos without
+ hard registers. */
for (x = REG_NOTES (insn); x; x = XEXP (x, 1))
if (REG_NOTE_KIND (x) == REG_INC)
{
@@ -4264,8 +4480,6 @@ reload_as_needed (first, live_known)
CLEAR_HARD_REG_BIT (reg_reloaded_valid, i);
#endif
- insn = next;
-
#ifdef USE_C_ALLOCA
alloca (0);
#endif
@@ -4404,6 +4618,10 @@ static HARD_REG_SET reload_reg_used_at_all;
in the group. */
static HARD_REG_SET reload_reg_used_for_inherit;
+/* Records which hard regs are used in any way, either as explicit use or
+ by being allocated to a pseudo during any point of the current insn. */
+static HARD_REG_SET reg_used_in_insn;
+
/* Mark reg REGNO as in use for a reload of the sort spec'd by OPNUM and
TYPE. MODE is used to indicate how many consecutive regs are
actually used. */
@@ -4481,57 +4699,104 @@ clear_reload_reg_in_use (regno, opnum, type, mode)
enum machine_mode mode;
{
int nregs = HARD_REGNO_NREGS (regno, mode);
+ int start_regno, end_regno;
int i;
+ /* A complication is that for some reload types, inheritance might
+ allow multiple reloads of the same types to share a reload register.
+ We set check_opnum if we have to check only reloads with the same
+ operand number, and check_any if we have to check all reloads. */
+ int check_opnum = 0;
+ int check_any = 0;
+ HARD_REG_SET *used_in_set;
- for (i = regno; i < nregs + regno; i++)
+ switch (type)
{
- switch (type)
- {
- case RELOAD_OTHER:
- CLEAR_HARD_REG_BIT (reload_reg_used, i);
- break;
+ case RELOAD_OTHER:
+ used_in_set = &reload_reg_used;
+ break;
- case RELOAD_FOR_INPUT_ADDRESS:
- CLEAR_HARD_REG_BIT (reload_reg_used_in_input_addr[opnum], i);
- break;
+ case RELOAD_FOR_INPUT_ADDRESS:
+ used_in_set = &reload_reg_used_in_input_addr[opnum];
+ break;
- case RELOAD_FOR_INPADDR_ADDRESS:
- CLEAR_HARD_REG_BIT (reload_reg_used_in_inpaddr_addr[opnum], i);
- break;
+ case RELOAD_FOR_INPADDR_ADDRESS:
+ check_opnum = 1;
+ used_in_set = &reload_reg_used_in_inpaddr_addr[opnum];
+ break;
- case RELOAD_FOR_OUTPUT_ADDRESS:
- CLEAR_HARD_REG_BIT (reload_reg_used_in_output_addr[opnum], i);
- break;
+ case RELOAD_FOR_OUTPUT_ADDRESS:
+ used_in_set = &reload_reg_used_in_output_addr[opnum];
+ break;
- case RELOAD_FOR_OUTADDR_ADDRESS:
- CLEAR_HARD_REG_BIT (reload_reg_used_in_outaddr_addr[opnum], i);
- break;
+ case RELOAD_FOR_OUTADDR_ADDRESS:
+ check_opnum = 1;
+ used_in_set = &reload_reg_used_in_outaddr_addr[opnum];
+ break;
- case RELOAD_FOR_OPERAND_ADDRESS:
- CLEAR_HARD_REG_BIT (reload_reg_used_in_op_addr, i);
- break;
+ case RELOAD_FOR_OPERAND_ADDRESS:
+ used_in_set = &reload_reg_used_in_op_addr;
+ break;
- case RELOAD_FOR_OPADDR_ADDR:
- CLEAR_HARD_REG_BIT (reload_reg_used_in_op_addr_reload, i);
- break;
+ case RELOAD_FOR_OPADDR_ADDR:
+ check_any = 1;
+ used_in_set = &reload_reg_used_in_op_addr_reload;
+ break;
- case RELOAD_FOR_OTHER_ADDRESS:
- CLEAR_HARD_REG_BIT (reload_reg_used_in_other_addr, i);
- break;
+ case RELOAD_FOR_OTHER_ADDRESS:
+ used_in_set = &reload_reg_used_in_other_addr;
+ check_any = 1;
+ break;
- case RELOAD_FOR_INPUT:
- CLEAR_HARD_REG_BIT (reload_reg_used_in_input[opnum], i);
- break;
+ case RELOAD_FOR_INPUT:
+ used_in_set = &reload_reg_used_in_input[opnum];
+ break;
- case RELOAD_FOR_OUTPUT:
- CLEAR_HARD_REG_BIT (reload_reg_used_in_output[opnum], i);
- break;
+ case RELOAD_FOR_OUTPUT:
+ used_in_set = &reload_reg_used_in_output[opnum];
+ break;
- case RELOAD_FOR_INSN:
- CLEAR_HARD_REG_BIT (reload_reg_used_in_insn, i);
- break;
+ case RELOAD_FOR_INSN:
+ used_in_set = &reload_reg_used_in_insn;
+ break;
+ default:
+ abort ();
+ }
+ /* We resolve conflicts with remaining reloads of the same type by
+ excluding the intervals of of reload registers by them from the
+ interval of freed reload registers. Since we only keep track of
+ one set of interval bounds, we might have to exclude somewhat
+ more then what would be necessary if we used a HARD_REG_SET here.
+ But this should only happen very infrequently, so there should
+ be no reason to worry about it. */
+
+ start_regno = regno;
+ end_regno = regno + nregs;
+ if (check_opnum || check_any)
+ {
+ for (i = n_reloads - 1; i >= 0; i--)
+ {
+ if (reload_when_needed[i] == type
+ && (check_any || reload_opnum[i] == opnum)
+ && reload_reg_rtx[i])
+ {
+ int conflict_start = true_regnum (reload_reg_rtx[i]);
+ int conflict_end
+ = (conflict_start
+ + HARD_REGNO_NREGS (conflict_start, reload_mode[i]));
+
+ /* If there is an overlap with the first to-be-freed register,
+ adjust the interval start. */
+ if (conflict_start <= start_regno && conflict_end > start_regno)
+ start_regno = conflict_end;
+ /* Otherwise, if there is a conflict with one of the other
+ to-be-freed registers, adjust the interval end. */
+ if (conflict_start > start_regno && conflict_start < end_regno)
+ end_regno = conflict_start;
+ }
}
}
+ for (i = start_regno; i < end_regno; i++)
+ CLEAR_HARD_REG_BIT (*used_in_set, i);
}
/* 1 if reg REGNO is free as a reload reg for a reload of the sort
@@ -4690,160 +4955,6 @@ reload_reg_free_p (regno, opnum, type)
/* Return 1 if the value in reload reg REGNO, as used by a reload
needed for the part of the insn specified by OPNUM and TYPE,
- is not in use for a reload in any prior part of the insn.
-
- We can assume that the reload reg was already tested for availability
- at the time it is needed, and we should not check this again,
- in case the reg has already been marked in use.
-
- However, if EQUIV is set, we are checking the availability of a register
- holding an equivalence to the value to be loaded into the reload register,
- not the availability of the reload register itself.
-
- This is still less stringent than what reload_reg_free_p checks; for
- example, compare the checks for RELOAD_OTHER. */
-
-static int
-reload_reg_free_before_p (regno, opnum, type, equiv)
- int regno;
- int opnum;
- enum reload_type type;
- int equiv;
-{
- int i;
-
- switch (type)
- {
- case RELOAD_FOR_OTHER_ADDRESS:
- /* These always come first. */
- if (equiv && TEST_HARD_REG_BIT (reload_reg_used_in_other_addr, regno))
- return 0;
- return 1;
-
- case RELOAD_OTHER:
- if (equiv && TEST_HARD_REG_BIT (reload_reg_used, regno))
- return 0;
- return ! TEST_HARD_REG_BIT (reload_reg_used_in_other_addr, regno);
-
- /* If this use is for part of the insn,
- check the reg is not in use for any prior part. It is tempting
- to try to do this by falling through from objecs that occur
- later in the insn to ones that occur earlier, but that will not
- correctly take into account the fact that here we MUST ignore
- things that would prevent the register from being allocated in
- the first place, since we know that it was allocated. */
-
- case RELOAD_FOR_OUTPUT_ADDRESS:
- if (equiv
- && TEST_HARD_REG_BIT (reload_reg_used_in_output_addr[opnum], regno))
- return 0;
- /* Earlier reloads include RELOAD_FOR_OUTADDR_ADDRESS reloads. */
- if (TEST_HARD_REG_BIT (reload_reg_used_in_outaddr_addr[opnum], regno))
- return 0;
- /* ... fall through ... */
- case RELOAD_FOR_OUTADDR_ADDRESS:
- if (equiv
- && (TEST_HARD_REG_BIT (reload_reg_used_in_outaddr_addr[opnum], regno)
- || TEST_HARD_REG_BIT (reload_reg_used, regno)))
- return 0;
- /* Earlier reloads are for earlier outputs or their addresses,
- any RELOAD_FOR_INSN reloads, any inputs or their addresses, or any
- RELOAD_FOR_OTHER_ADDRESS reloads (we know it can't conflict with
- RELOAD_OTHER).. */
- for (i = 0; i < opnum; i++)
- if (TEST_HARD_REG_BIT (reload_reg_used_in_output_addr[i], regno)
- || TEST_HARD_REG_BIT (reload_reg_used_in_outaddr_addr[i], regno))
- return 0;
-
- if (TEST_HARD_REG_BIT (reload_reg_used_in_insn, regno))
- return 0;
-
- for (i = 0; i < reload_n_operands; i++)
- if (TEST_HARD_REG_BIT (reload_reg_used_in_input_addr[i], regno)
- || TEST_HARD_REG_BIT (reload_reg_used_in_inpaddr_addr[i], regno)
- || TEST_HARD_REG_BIT (reload_reg_used_in_input[i], regno)
- || TEST_HARD_REG_BIT (reload_reg_used_in_output[i], regno))
- return 0;
-
- return (! TEST_HARD_REG_BIT (reload_reg_used_in_other_addr, regno)
- && ! TEST_HARD_REG_BIT (reload_reg_used_in_insn, regno)
- && ! TEST_HARD_REG_BIT (reload_reg_used_in_op_addr_reload, regno)
- && ! TEST_HARD_REG_BIT (reload_reg_used_in_op_addr, regno));
-
- case RELOAD_FOR_OUTPUT:
- case RELOAD_FOR_INSN:
- /* There is no reason to call this function for output reloads, thus
- anything we'd put here wouldn't be tested. So just abort. */
- abort ();
-
- case RELOAD_FOR_OPERAND_ADDRESS:
- if (equiv && TEST_HARD_REG_BIT (reload_reg_used_in_op_addr, regno))
- return 0;
-
- /* Earlier reloads include RELOAD_FOR_OPADDR_ADDR reloads. */
- if (TEST_HARD_REG_BIT (reload_reg_used_in_op_addr_reload, regno))
- return 0;
-
- /* ... fall through ... */
-
- case RELOAD_FOR_OPADDR_ADDR:
- if (equiv)
- {
- if (TEST_HARD_REG_BIT (reload_reg_used_in_op_addr_reload, regno)
- || TEST_HARD_REG_BIT (reload_reg_used, regno))
- return 0;
- for (i = 0; i < reload_n_operands; i++)
- if (TEST_HARD_REG_BIT (reload_reg_used_in_input[i], regno))
- return 0;
- }
- /* These can't conflict with inputs, or each other, so all we have to
- test is input addresses and the addresses of OTHER items. */
-
- for (i = 0; i < reload_n_operands; i++)
- if (TEST_HARD_REG_BIT (reload_reg_used_in_input_addr[i], regno)
- || TEST_HARD_REG_BIT (reload_reg_used_in_inpaddr_addr[i], regno))
- return 0;
-
- return ! TEST_HARD_REG_BIT (reload_reg_used_in_other_addr, regno);
-
- case RELOAD_FOR_INPUT:
- if (equiv && TEST_HARD_REG_BIT (reload_reg_used, regno))
- return 0;
-
- /* The only things earlier are the address for this and
- earlier inputs, other inputs (which we know we don't conflict
- with), and addresses of RELOAD_OTHER objects. */
-
- for (i = 0; i <= opnum; i++)
- if (TEST_HARD_REG_BIT (reload_reg_used_in_input_addr[i], regno)
- || TEST_HARD_REG_BIT (reload_reg_used_in_inpaddr_addr[i], regno))
- return 0;
-
- return ! TEST_HARD_REG_BIT (reload_reg_used_in_other_addr, regno);
-
- case RELOAD_FOR_INPUT_ADDRESS:
- /* Earlier reloads include RELOAD_FOR_INPADDR_ADDRESS reloads. */
- if (TEST_HARD_REG_BIT (reload_reg_used_in_inpaddr_addr[opnum], regno))
- return 0;
- /* ... fall through ... */
- case RELOAD_FOR_INPADDR_ADDRESS:
- if (equiv && TEST_HARD_REG_BIT (reload_reg_used, regno))
- return 0;
-
- /* Similarly, all we have to check is for use in earlier inputs'
- addresses. */
- for (i = 0; i < opnum; i++)
- if (TEST_HARD_REG_BIT (reload_reg_used_in_input_addr[i], regno)
- || TEST_HARD_REG_BIT (reload_reg_used_in_inpaddr_addr[i], regno))
- return 0;
-
- return ! TEST_HARD_REG_BIT (reload_reg_used_in_other_addr, regno);
- }
- abort ();
-}
-
-/* Return 1 if the value in reload reg REGNO, as used by a reload
- needed for the part of the insn specified by OPNUM and TYPE,
is still available in REGNO at the end of the insn.
We can assume that the reload reg was already tested for availability
@@ -5078,22 +5189,37 @@ int reload_spill_index[MAX_RELOADS];
Other read-only reloads with the same value do not conflict
unless OUT is non-zero and these other reloads have to live while
output reloads live.
+ If OUT is CONST0_RTX, this is a special case: it means that the
+ test should not be for using register REGNO as reload register, but
+ for copying from register REGNO into the reload register.
RELOADNUM is the number of the reload we want to load this value for;
a reload does not conflict with itself.
+ When IGNORE_ADDRESS_RELOADS is set, we can not have conflicts with
+ reloads that load an address for the very reload we are considering.
+
The caller has to make sure that there is no conflict with the return
register. */
static int
-reload_reg_free_for_value_p (regno, opnum, type, value, out, reloadnum)
+reload_reg_free_for_value_p (regno, opnum, type, value, out, reloadnum,
+ ignore_address_reloads)
int regno;
int opnum;
enum reload_type type;
rtx value, out;
int reloadnum;
+ int ignore_address_reloads;
{
int time1;
int i;
+ int copy = 0;
+
+ if (out == const0_rtx)
+ {
+ copy = 1;
+ out = NULL_RTX;
+ }
/* We use some pseudo 'time' value to check if the lifetimes of the
new register use would overlap with the one of a previous reload
@@ -5115,6 +5241,9 @@ reload_reg_free_for_value_p (regno, opnum, type, value, out, reloadnum)
case RELOAD_FOR_OTHER_ADDRESS:
time1 = 0;
break;
+ case RELOAD_OTHER:
+ time1 = copy ? 1 : MAX_RECOG_OPERANDS * 5 + 5;
+ break;
/* For each input, we might have a sequence of RELOAD_FOR_INPADDR_ADDRESS,
RELOAD_FOR_INPUT_ADDRESS and RELOAD_FOR_INPUT. By adding 0 / 1 / 2 ,
respectively, to the time values for these, we get distinct time
@@ -5122,23 +5251,34 @@ reload_reg_free_for_value_p (regno, opnum, type, value, out, reloadnum)
multiply opnum by at least three. We round that up to four because
multiply by four is often cheaper. */
case RELOAD_FOR_INPADDR_ADDRESS:
- time1 = opnum * 4 + 1;
+ time1 = opnum * 4 + 2;
break;
case RELOAD_FOR_INPUT_ADDRESS:
- time1 = opnum * 4 + 2;
+ time1 = opnum * 4 + 3;
break;
case RELOAD_FOR_INPUT:
- /* All RELOAD_FOR_INPUT reloads remain live till just before the
- instruction is executed. */
- time1 = (MAX_RECOG_OPERANDS - 1) * 4 + 3;
+ /* All RELOAD_FOR_INPUT reloads remain live till the instruction
+ executes (inclusive). */
+ time1 = copy ? opnum * 4 + 4 : MAX_RECOG_OPERANDS * 4 + 3;
break;
- /* opnum * 4 + 3 < opnum * 4 + 4
+ case RELOAD_FOR_OPADDR_ADDR:
+ /* opnum * 4 + 4
<= (MAX_RECOG_OPERANDS - 1) * 4 + 4 == MAX_RECOG_OPERANDS * 4 */
+ time1 = MAX_RECOG_OPERANDS * 4 + 1;
+ break;
+ case RELOAD_FOR_OPERAND_ADDRESS:
+ /* RELOAD_FOR_OPERAND_ADDRESS reloads are live even while the insn
+ is executed. */
+ time1 = copy ? MAX_RECOG_OPERANDS * 4 + 2 : MAX_RECOG_OPERANDS * 4 + 3;
+ break;
+ case RELOAD_FOR_OUTADDR_ADDRESS:
+ time1 = MAX_RECOG_OPERANDS * 4 + 4 + opnum;
+ break;
case RELOAD_FOR_OUTPUT_ADDRESS:
- time1 = MAX_RECOG_OPERANDS * 4 + opnum;
+ time1 = MAX_RECOG_OPERANDS * 4 + 5 + opnum;
break;
default:
- time1 = MAX_RECOG_OPERANDS * 5;
+ time1 = MAX_RECOG_OPERANDS * 5 + 5;
}
for (i = 0; i < n_reloads; i++)
@@ -5149,13 +5289,8 @@ reload_reg_free_for_value_p (regno, opnum, type, value, out, reloadnum)
<= HARD_REGNO_NREGS (REGNO (reg), GET_MODE (reg)) - (unsigned)1)
&& i != reloadnum)
{
- if (out
- && reload_when_needed[i] != RELOAD_FOR_INPUT
- && reload_when_needed[i] != RELOAD_FOR_INPUT_ADDRESS
- && reload_when_needed[i] != RELOAD_FOR_INPADDR_ADDRESS)
- return 0;
if (! reload_in[i] || ! rtx_equal_p (reload_in[i], value)
- || reload_out[i])
+ || reload_out[i] || out)
{
int time2;
switch (reload_when_needed[i])
@@ -5164,34 +5299,96 @@ reload_reg_free_for_value_p (regno, opnum, type, value, out, reloadnum)
time2 = 0;
break;
case RELOAD_FOR_INPADDR_ADDRESS:
- time2 = reload_opnum[i] * 4 + 1;
+ /* find_reloads makes sure that a
+ RELOAD_FOR_{INP,OP,OUT}ADDR_ADDRESS reload is only used
+ by at most one - the first -
+ RELOAD_FOR_{INPUT,OPERAND,OUTPUT}_ADDRESS . If the
+ address reload is inherited, the address address reload
+ goes away, so we can ignore this conflict. */
+ if (type == RELOAD_FOR_INPUT_ADDRESS && reloadnum == i + 1
+ && ignore_address_reloads
+ /* Unless the RELOAD_FOR_INPUT is an auto_inc expression.
+ Then the address address is still needed to store
+ back the new address. */
+ && ! reload_out[reloadnum])
+ continue;
+ /* Likewise, if a RELOAD_FOR_INPUT can inherit a value, its
+ RELOAD_FOR_INPUT_ADDRESS / RELOAD_FOR_INPADDR_ADDRESS
+ reloads go away. */
+ if (type == RELOAD_FOR_INPUT && opnum == reload_opnum[i]
+ && ignore_address_reloads
+ /* Unless we are reloading an auto_inc expression. */
+ && ! reload_out[reloadnum])
+ continue;
+ time2 = reload_opnum[i] * 4 + 2;
break;
case RELOAD_FOR_INPUT_ADDRESS:
- time2 = reload_opnum[i] * 4 + 2;
+ if (type == RELOAD_FOR_INPUT && opnum == reload_opnum[i]
+ && ignore_address_reloads
+ && ! reload_out[reloadnum])
+ continue;
+ time2 = reload_opnum[i] * 4 + 3;
break;
case RELOAD_FOR_INPUT:
- time2 = reload_opnum[i] * 4 + 3;
+ time2 = reload_opnum[i] * 4 + 4;
+ break;
+ /* reload_opnum[i] * 4 + 4 <= (MAX_RECOG_OPERAND - 1) * 4 + 4
+ == MAX_RECOG_OPERAND * 4 */
+ case RELOAD_FOR_OPADDR_ADDR:
+ if (type == RELOAD_FOR_OPERAND_ADDRESS && reloadnum == i + 1
+ && ignore_address_reloads
+ && ! reload_out[reloadnum])
+ continue;
+ time2 = MAX_RECOG_OPERANDS * 4 + 1;
+ break;
+ case RELOAD_FOR_OPERAND_ADDRESS:
+ time2 = MAX_RECOG_OPERANDS * 4 + 2;
+ break;
+ case RELOAD_FOR_INSN:
+ time2 = MAX_RECOG_OPERANDS * 4 + 3;
break;
case RELOAD_FOR_OUTPUT:
/* All RELOAD_FOR_OUTPUT reloads become live just after the
instruction is executed. */
- time2 = MAX_RECOG_OPERANDS * 4;
+ time2 = MAX_RECOG_OPERANDS * 4 + 4;
+ break;
+ /* The first RELOAD_FOR_OUTADDR_ADDRESS reload conflicts with
+ the RELOAD_FOR_OUTPUT reloads, so assign it the same time
+ value. */
+ case RELOAD_FOR_OUTADDR_ADDRESS:
+ if (type == RELOAD_FOR_OUTPUT_ADDRESS && reloadnum == i + 1
+ && ignore_address_reloads
+ && ! reload_out[reloadnum])
+ continue;
+ time2 = MAX_RECOG_OPERANDS * 4 + 4 + reload_opnum[i];
break;
- /* The first RELOAD_FOR_OUTPUT_ADDRESS reload conflicts with the
- RELOAD_FOR_OUTPUT reloads, so assign it the same time value. */
case RELOAD_FOR_OUTPUT_ADDRESS:
- time2 = MAX_RECOG_OPERANDS * 4 + reload_opnum[i];
+ time2 = MAX_RECOG_OPERANDS * 4 + 5 + reload_opnum[i];
break;
case RELOAD_OTHER:
+ /* If there is no conflict in the input part, handle this
+ like an output reload. */
if (! reload_in[i] || rtx_equal_p (reload_in[i], value))
{
- time2 = MAX_RECOG_OPERANDS * 4;
+ time2 = MAX_RECOG_OPERANDS * 4 + 4;
break;
}
+ time2 = 1;
+ /* RELOAD_OTHER might be live beyond instruction execution,
+ but this is not obvious when we set time2 = 1. So check
+ here if there might be a problem with the new reload
+ clobbering the register used by the RELOAD_OTHER. */
+ if (out)
+ return 0;
+ break;
default:
- time2 = 0;
+ return 0;
}
- if (time1 >= time2)
+ if ((time1 >= time2
+ && (! reload_in[i] || reload_out[i]
+ || ! rtx_equal_p (reload_in[i], value)))
+ || (out && reload_out_reg[reloadnum]
+ && time2 >= MAX_RECOG_OPERANDS * 4 + 3))
return 0;
}
}
@@ -5209,17 +5406,15 @@ reload_reg_free_for_value_p (regno, opnum, type, value, out, reloadnum)
or 0 if we couldn't find a spill reg and we didn't change anything. */
static int
-allocate_reload_reg (r, insn, last_reload, noerror)
+allocate_reload_reg (chain, r, last_reload, noerror)
+ struct insn_chain *chain;
int r;
- rtx insn;
int last_reload;
int noerror;
{
- int i;
- int pass;
- int count;
+ rtx insn = chain->insn;
+ int i, pass, count, regno;
rtx new;
- int regno;
/* If we put this reload ahead, thinking it is a group,
then insist on finding a group. Otherwise we can grab a
@@ -5268,32 +5463,36 @@ allocate_reload_reg (r, insn, last_reload, noerror)
for (count = 0; count < n_spills; count++)
{
int class = (int) reload_reg_class[r];
+ int regnum;
- i = (i + 1) % n_spills;
+ i++;
+ if (i >= n_spills)
+ i -= n_spills;
+ regnum = spill_regs[i];
- if ((reload_reg_free_p (spill_regs[i], reload_opnum[r],
+ if ((reload_reg_free_p (regnum, reload_opnum[r],
reload_when_needed[r])
|| (reload_in[r]
/* We check reload_reg_used to make sure we
don't clobber the return register. */
- && ! TEST_HARD_REG_BIT (reload_reg_used, spill_regs[i])
- && reload_reg_free_for_value_p (spill_regs[i],
+ && ! TEST_HARD_REG_BIT (reload_reg_used, regnum)
+ && reload_reg_free_for_value_p (regnum,
reload_opnum[r],
reload_when_needed[r],
reload_in[r],
- reload_out[r], r)))
- && TEST_HARD_REG_BIT (reg_class_contents[class], spill_regs[i])
- && HARD_REGNO_MODE_OK (spill_regs[i], reload_mode[r])
+ reload_out[r], r, 1)))
+ && TEST_HARD_REG_BIT (reg_class_contents[class], regnum)
+ && HARD_REGNO_MODE_OK (regnum, reload_mode[r])
/* Look first for regs to share, then for unshared. But
don't share regs used for inherited reloads; they are
the ones we want to preserve. */
&& (pass
|| (TEST_HARD_REG_BIT (reload_reg_used_at_all,
- spill_regs[i])
+ regnum)
&& ! TEST_HARD_REG_BIT (reload_reg_used_for_inherit,
- spill_regs[i]))))
+ regnum))))
{
- int nr = HARD_REGNO_NREGS (spill_regs[i], reload_mode[r]);
+ int nr = HARD_REGNO_NREGS (regnum, reload_mode[r]);
/* Avoid the problem where spilling a GENERAL_OR_FP_REG
(on 68000) got us two FP regs. If NR is 1,
we would reject both of them. */
@@ -5311,15 +5510,15 @@ allocate_reload_reg (r, insn, last_reload, noerror)
are available here.
Also, don't use for a group registers that are
needed for nongroups. */
- if (! TEST_HARD_REG_BIT (counted_for_nongroups, spill_regs[i]))
+ if (! TEST_HARD_REG_BIT (chain->counted_for_nongroups, regnum))
while (nr > 1)
{
- regno = spill_regs[i] + nr - 1;
+ regno = regnum + nr - 1;
if (!(TEST_HARD_REG_BIT (reg_class_contents[class], regno)
&& spill_reg_order[regno] >= 0
&& reload_reg_free_p (regno, reload_opnum[r],
reload_when_needed[r])
- && ! TEST_HARD_REG_BIT (counted_for_nongroups,
+ && ! TEST_HARD_REG_BIT (chain->counted_for_nongroups,
regno)))
break;
nr--;
@@ -5415,14 +5614,15 @@ allocate_reload_reg (r, insn, last_reload, noerror)
finding a reload reg in the proper class. */
static void
-choose_reload_regs (insn, avoid_return_reg)
- rtx insn;
- rtx avoid_return_reg;
+choose_reload_regs (chain)
+ struct insn_chain *chain;
{
+ rtx insn = chain->insn;
register int i, j;
int max_group_size = 1;
enum reg_class group_class = NO_REGS;
int inheritance;
+ int pass;
rtx save_reload_reg_rtx[MAX_RELOADS];
char save_reload_inherited[MAX_RELOADS];
@@ -5453,6 +5653,16 @@ choose_reload_regs (insn, avoid_return_reg)
CLEAR_HARD_REG_SET (reload_reg_used_in_insn);
CLEAR_HARD_REG_SET (reload_reg_used_in_other_addr);
+ CLEAR_HARD_REG_SET (reg_used_in_insn);
+ {
+ HARD_REG_SET tmp;
+ REG_SET_TO_HARD_REG_SET (tmp, chain->live_before);
+ IOR_HARD_REG_SET (reg_used_in_insn, tmp);
+ REG_SET_TO_HARD_REG_SET (tmp, chain->live_after);
+ IOR_HARD_REG_SET (reg_used_in_insn, tmp);
+ compute_use_by_pseudos (&reg_used_in_insn, chain->live_before);
+ compute_use_by_pseudos (&reg_used_in_insn, chain->live_after);
+ }
for (i = 0; i < reload_n_operands; i++)
{
CLEAR_HARD_REG_SET (reload_reg_used_in_output[i]);
@@ -5463,29 +5673,8 @@ choose_reload_regs (insn, avoid_return_reg)
CLEAR_HARD_REG_SET (reload_reg_used_in_outaddr_addr[i]);
}
- /* Don't bother with avoiding the return reg
- if we have no mandatory reload that could use it. */
- if (SMALL_REGISTER_CLASSES && avoid_return_reg)
- {
- int do_avoid = 0;
- int regno = REGNO (avoid_return_reg);
- int nregs
- = HARD_REGNO_NREGS (regno, GET_MODE (avoid_return_reg));
- int r;
-
- for (r = regno; r < regno + nregs; r++)
- if (spill_reg_order[r] >= 0)
- for (j = 0; j < n_reloads; j++)
- if (!reload_optional[j] && reload_reg_rtx[j] == 0
- && (reload_in[j] != 0 || reload_out[j] != 0
- || reload_secondary_p[j])
- &&
- TEST_HARD_REG_BIT (reg_class_contents[(int) reload_reg_class[j]], r))
- do_avoid = 1;
- if (!do_avoid)
- avoid_return_reg = 0;
- }
-
+ IOR_COMPL_HARD_REG_SET (reload_reg_used, chain->used_spill_regs);
+
#if 0 /* Not needed, now that we can always retry without inheritance. */
/* See if we have more mandatory reloads than spill regs.
If so, then we cannot risk optimizations that could prevent
@@ -5495,7 +5684,7 @@ choose_reload_regs (insn, avoid_return_reg)
unless it is equal to reload_in or reload_out, count such reloads. */
{
- int tem = SMALL_REGISTER_CLASSES? (avoid_return_reg != 0): 0;
+ int tem = 0;
for (j = 0; j < n_reloads; j++)
if (! reload_optional[j]
&& (reload_in[j] != 0 || reload_out[j] != 0 || reload_secondary_p[j])
@@ -5508,20 +5697,6 @@ choose_reload_regs (insn, avoid_return_reg)
}
#endif
- /* Don't use the subroutine call return reg for a reload
- if we are supposed to avoid it. */
- if (SMALL_REGISTER_CLASSES && avoid_return_reg)
- {
- int regno = REGNO (avoid_return_reg);
- int nregs
- = HARD_REGNO_NREGS (regno, GET_MODE (avoid_return_reg));
- int r;
-
- for (r = regno; r < regno + nregs; r++)
- if (spill_reg_order[r] >= 0)
- SET_HARD_REG_BIT (reload_reg_used, r);
- }
-
/* In order to be certain of getting the registers we need,
we must sort the reloads into order of increasing register class.
Then our grabbing of reload registers will parallel the process
@@ -5630,6 +5805,7 @@ choose_reload_regs (insn, avoid_return_reg)
for (j = 0; j < n_reloads; j++)
{
register int r = reload_order[j];
+ rtx search_equiv = NULL_RTX;
/* Ignore reloads that got marked inoperative. */
if (reload_out[r] == 0 && reload_in[r] == 0
@@ -5661,7 +5837,7 @@ choose_reload_regs (insn, avoid_return_reg)
|| reload_secondary_p[reload_order[i]])
&& ! reload_optional[reload_order[i]]
&& reload_reg_rtx[reload_order[i]] == 0)
- allocate_reload_reg (reload_order[i], insn, 0, inheritance);
+ allocate_reload_reg (chain, reload_order[i], 0, inheritance);
#endif
/* First see if this pseudo is already available as reloaded
@@ -5680,6 +5856,7 @@ choose_reload_regs (insn, avoid_return_reg)
if (inheritance)
{
+ int word = 0;
register int regno = -1;
enum machine_mode mode;
@@ -5695,33 +5872,27 @@ choose_reload_regs (insn, avoid_return_reg)
regno = REGNO (reload_in_reg[r]);
mode = GET_MODE (reload_in_reg[r]);
}
- else if (GET_CODE (reload_in[r]) == MEM)
+ else if (GET_CODE (reload_in_reg[r]) == SUBREG
+ && GET_CODE (SUBREG_REG (reload_in_reg[r])) == REG)
{
- rtx prev = prev_nonnote_insn (insn), note;
-
- if (prev && GET_CODE (prev) == INSN
- && GET_CODE (PATTERN (prev)) == USE
- && GET_CODE (XEXP (PATTERN (prev), 0)) == REG
- && (REGNO (XEXP (PATTERN (prev), 0))
- >= FIRST_PSEUDO_REGISTER)
- && (note = find_reg_note (prev, REG_EQUAL, NULL_RTX))
- && GET_CODE (XEXP (note, 0)) == MEM)
- {
- rtx addr = XEXP (XEXP (note, 0), 0);
- int size_diff
- = (GET_MODE_SIZE (GET_MODE (addr))
- - GET_MODE_SIZE (GET_MODE (reload_in[r])));
- if (size_diff >= 0
- && rtx_equal_p ((BYTES_BIG_ENDIAN
- ? plus_constant (addr, size_diff)
- : addr),
- XEXP (reload_in[r], 0)))
- {
- regno = REGNO (XEXP (PATTERN (prev), 0));
- mode = GET_MODE (reload_in[r]);
- }
- }
+ word = SUBREG_WORD (reload_in_reg[r]);
+ regno = REGNO (SUBREG_REG (reload_in_reg[r]));
+ if (regno < FIRST_PSEUDO_REGISTER)
+ regno += word;
+ mode = GET_MODE (reload_in_reg[r]);
+ }
+#ifdef AUTO_INC_DEC
+ else if ((GET_CODE (reload_in_reg[r]) == PRE_INC
+ || GET_CODE (reload_in_reg[r]) == PRE_DEC
+ || GET_CODE (reload_in_reg[r]) == POST_INC
+ || GET_CODE (reload_in_reg[r]) == POST_DEC)
+ && GET_CODE (XEXP (reload_in_reg[r], 0)) == REG)
+ {
+ regno = REGNO (XEXP (reload_in_reg[r], 0));
+ mode = GET_MODE (XEXP (reload_in_reg[r], 0));
+ reload_out[r] = reload_in[r];
}
+#endif
#if 0
/* This won't work, since REGNO can be a pseudo reg number.
Also, it takes much more hair to keep track of all the things
@@ -5733,27 +5904,41 @@ choose_reload_regs (insn, avoid_return_reg)
if (regno >= 0 && reg_last_reload_reg[regno] != 0)
{
- i = REGNO (reg_last_reload_reg[regno]);
-
- if (reg_reloaded_contents[i] == regno
+ enum reg_class class = reload_reg_class[r], last_class;
+ rtx last_reg = reg_last_reload_reg[regno];
+
+ i = REGNO (last_reg) + word;
+ last_class = REGNO_REG_CLASS (i);
+ if ((GET_MODE_SIZE (GET_MODE (last_reg))
+ >= GET_MODE_SIZE (mode) + word * UNITS_PER_WORD)
+ && reg_reloaded_contents[i] == regno
&& TEST_HARD_REG_BIT (reg_reloaded_valid, i)
- && (GET_MODE_SIZE (GET_MODE (reg_last_reload_reg[regno]))
- >= GET_MODE_SIZE (mode))
&& HARD_REGNO_MODE_OK (i, reload_mode[r])
- && TEST_HARD_REG_BIT (reg_class_contents[(int) reload_reg_class[r]],
- i)
+ && (TEST_HARD_REG_BIT (reg_class_contents[(int) class], i)
+ /* Even if we can't use this register as a reload
+ register, we might use it for reload_override_in,
+ if copying it to the desired class is cheap
+ enough. */
+ || ((REGISTER_MOVE_COST (last_class, class)
+ < MEMORY_MOVE_COST (mode, class, 1))
+#ifdef SECONDARY_INPUT_RELOAD_CLASS
+ && (SECONDARY_INPUT_RELOAD_CLASS (class, mode,
+ last_reg)
+ == NO_REGS)
+#endif
+#ifdef SECONDARY_MEMORY_NEEDED
+ && ! SECONDARY_MEMORY_NEEDED (last_class, class,
+ mode)
+#endif
+ ))
+
&& (reload_nregs[r] == max_group_size
|| ! TEST_HARD_REG_BIT (reg_class_contents[(int) group_class],
i))
- && ((reload_reg_free_p (i, reload_opnum[r],
- reload_when_needed[r])
- && reload_reg_free_before_p (i, reload_opnum[r],
- reload_when_needed[r],
- 0))
- || reload_reg_free_for_value_p (i, reload_opnum[r],
- reload_when_needed[r],
- reload_in[r],
- reload_out[r], r)))
+ && reload_reg_free_for_value_p (i, reload_opnum[r],
+ reload_when_needed[r],
+ reload_in[r],
+ const0_rtx, r, 1))
{
/* If a group is needed, verify that all the subsequent
registers still have their values intact. */
@@ -5770,6 +5955,9 @@ choose_reload_regs (insn, avoid_return_reg)
{
int i1;
+ last_reg = (GET_MODE (last_reg) == mode
+ ? last_reg : gen_rtx_REG (mode, i));
+
/* We found a register that contains the
value we need. If this register is the
same as an `earlyclobber' operand of the
@@ -5784,21 +5972,34 @@ choose_reload_regs (insn, avoid_return_reg)
break;
if (i1 != n_earlyclobbers
+ || ! (reload_reg_free_for_value_p
+ (i, reload_opnum[r], reload_when_needed[r],
+ reload_in[r], reload_out[r], r, 1))
/* Don't use it if we'd clobber a pseudo reg. */
- || (spill_reg_order[i] < 0
+ || (TEST_HARD_REG_BIT (reg_used_in_insn, i)
&& reload_out[r]
&& ! TEST_HARD_REG_BIT (reg_reloaded_dead, i))
+ /* Don't clobber the frame pointer. */
+ || (i == HARD_FRAME_POINTER_REGNUM
+ && reload_out[r])
/* Don't really use the inherited spill reg
if we need it wider than we've got it. */
|| (GET_MODE_SIZE (reload_mode[r])
> GET_MODE_SIZE (mode))
+ || ! TEST_HARD_REG_BIT (reg_class_contents[(int) reload_reg_class[r]],
+ i)
+
/* If find_reloads chose reload_out as reload
register, stay with it - that leaves the
inherited register for subsequent reloads. */
- || (reload_out[r] && reload_reg_rtx
+ || (reload_out[r] && reload_reg_rtx[r]
&& rtx_equal_p (reload_out[r],
reload_reg_rtx[r])))
- reload_override_in[r] = reg_last_reload_reg[regno];
+ {
+ reload_override_in[r] = last_reg;
+ reload_inheritance_insn[r]
+ = reg_reloaded_insn[i];
+ }
else
{
int k;
@@ -5809,7 +6010,7 @@ choose_reload_regs (insn, avoid_return_reg)
reload_opnum[r],
reload_when_needed[r],
reload_mode[r]);
- reload_reg_rtx[r] = reg_last_reload_reg[regno];
+ reload_reg_rtx[r] = last_reg;
reload_inherited[r] = 1;
reload_inheritance_insn[r]
= reg_reloaded_insn[i];
@@ -5834,9 +6035,23 @@ choose_reload_regs (insn, avoid_return_reg)
|| GET_CODE (reload_in[r]) == MEM)
&& (reload_nregs[r] == max_group_size
|| ! reg_classes_intersect_p (reload_reg_class[r], group_class)))
+ search_equiv = reload_in[r];
+ /* If this is an output reload from a simple move insn, look
+ if an equivalence for the input is available. */
+ else if (inheritance && reload_in[r] == 0 && reload_out[r] != 0)
+ {
+ rtx set = single_set (insn);
+
+ if (set
+ && rtx_equal_p (reload_out[r], SET_DEST (set))
+ && CONSTANT_P (SET_SRC (set)))
+ search_equiv = SET_SRC (set);
+ }
+
+ if (search_equiv)
{
register rtx equiv
- = find_equiv_reg (reload_in[r], insn, reload_reg_class[r],
+ = find_equiv_reg (search_equiv, insn, reload_reg_class[r],
-1, NULL_PTR, 0, reload_mode[r]);
int regno;
@@ -5860,21 +6075,15 @@ choose_reload_regs (insn, avoid_return_reg)
/* If we found a spill reg, reject it unless it is free
and of the desired class. */
if (equiv != 0
- && ((spill_reg_order[regno] >= 0
- && ! (reload_reg_free_before_p (regno, reload_opnum[r],
- reload_when_needed[r], 1)
- || reload_reg_free_for_value_p (regno,
- reload_opnum[r],
- reload_when_needed[r],
- reload_in[r],
- reload_out[r], r)))
+ && ((TEST_HARD_REG_BIT (reload_reg_used_at_all, regno)
+ && ! reload_reg_free_for_value_p (regno, reload_opnum[r],
+ reload_when_needed[r],
+ reload_in[r],
+ reload_out[r], r, 1))
|| ! TEST_HARD_REG_BIT (reg_class_contents[(int) reload_reg_class[r]],
regno)))
equiv = 0;
- if (equiv != 0 && TEST_HARD_REG_BIT (reload_reg_used_at_all, regno))
- equiv = 0;
-
if (equiv != 0 && ! HARD_REGNO_MODE_OK (regno, reload_mode[r]))
equiv = 0;
@@ -5987,7 +6196,7 @@ choose_reload_regs (insn, avoid_return_reg)
if (i == n_reloads)
continue;
- allocate_reload_reg (r, insn, j == n_reloads - 1, inheritance);
+ allocate_reload_reg (chain, r, j == n_reloads - 1, inheritance);
#endif
}
@@ -6006,7 +6215,7 @@ choose_reload_regs (insn, avoid_return_reg)
if (reload_reg_rtx[r] != 0 || reload_optional[r])
continue;
- if (! allocate_reload_reg (r, insn, j == n_reloads - 1, inheritance))
+ if (! allocate_reload_reg (chain, r, j == n_reloads - 1, inheritance))
break;
}
@@ -6014,7 +6223,6 @@ choose_reload_regs (insn, avoid_return_reg)
if (j == n_reloads)
break;
- fail:
/* Loop around and try without any inheritance. */
/* First undo everything done by the failed attempt
to allocate with inheritance. */
@@ -6059,75 +6267,56 @@ choose_reload_regs (insn, avoid_return_reg)
/* If we thought we could inherit a reload, because it seemed that
nothing else wanted the same reload register earlier in the insn,
- verify that assumption, now that all reloads have been assigned. */
+ verify that assumption, now that all reloads have been assigned.
+ Likewise for reloads where reload_override_in has been set. */
- for (j = 0; j < n_reloads; j++)
+ /* If doing expensive optimizations, do one preliminary pass that doesn't
+ cancel any inheritance, but removes reloads that have been needed only
+ for reloads that we know can be inherited. */
+ for (pass = flag_expensive_optimizations; pass >= 0; pass--)
{
- register int r = reload_order[j];
-
- if (reload_inherited[r] && reload_reg_rtx[r] != 0
- && ! (reload_reg_free_before_p (true_regnum (reload_reg_rtx[r]),
- reload_opnum[r],
- reload_when_needed[r], 0)
- || reload_reg_free_for_value_p (true_regnum (reload_reg_rtx[r]),
- reload_opnum[r],
- reload_when_needed[r],
- reload_in[r],
- reload_out[r], r)))
- reload_inherited[r] = 0;
- /* If we can inherit a RELOAD_FOR_INPUT, then we do not need its related
- RELOAD_FOR_INPUT_ADDRESS / RELOAD_FOR_INPADDR_ADDRESS reloads.
- ??? This could be extended to other reload types, but these are
- more tricky to handle:
- RELOAD_FOR_OTHER_ADDRESS reloads might have been merged, so we
- can't eliminate them without a check that *all* references are
- now unused due to inheritance.
- While RELOAD_FOR_INPADDR_ADDRESS and RELOAD_FOR_OUTADDR_ADDRESS are
- not merged, we can't be sure that we have eliminated the use of
- that particular reload if we have seen just one
- RELOAD_FOR_INPUT_ADDRESS / RELOAD_FOR_OUTPUT_ADDRESS being inherited,
- since there might be multiple of the latter two reloads for a single
- operand.
- RELOAD_FOR_OPADDR_ADDR reloads for different operands are not
- merged, but might share the same register by courtesy of
- reload_reg_free_for_value_p. reload_reg_used_in_op_addr_reload
- does not differentiate by opnum, thus calling clear_reload_reg_in_use
- for one of these reloads would mark the register as free even though
- another RELOAD_FOR_OPADDR_ADDR reload might still use it. */
- else if (reload_inherited[r] && reload_when_needed[r] == RELOAD_FOR_INPUT)
+ for (j = 0; j < n_reloads; j++)
{
- for (i = 0; i < n_reloads; i++)
+ register int r = reload_order[j];
+ rtx check_reg;
+ if (reload_inherited[r] && reload_reg_rtx[r])
+ check_reg = reload_reg_rtx[r];
+ else if (reload_override_in[r]
+ && (GET_CODE (reload_override_in[r]) == REG
+ || GET_CODE (reload_override_in[r]) == SUBREG))
+ check_reg = reload_override_in[r];
+ else
+ continue;
+ if (! reload_reg_free_for_value_p (true_regnum (check_reg),
+ reload_opnum[r],
+ reload_when_needed[r],
+ reload_in[r],
+ (reload_inherited[r]
+ ? reload_out[r] : const0_rtx),
+ r, 1))
{
- if ((reload_when_needed[i] == RELOAD_FOR_INPUT_ADDRESS
- || reload_when_needed[i] == RELOAD_FOR_INPADDR_ADDRESS)
- && reload_opnum[i] == reload_opnum[r]
- && reload_in[i] && reload_reg_rtx[i])
- {
- int regno = true_regnum (reload_reg_rtx[i]);
-
- reload_in[i] = 0;
- if (spill_reg_order[regno] >= 0)
- clear_reload_reg_in_use (regno, reload_opnum[i],
- reload_when_needed[i],
- reload_mode[i]);
- reload_reg_rtx[i] = 0;
- reload_spill_index[i] = -1;
- remove_replacements (i);
- }
+ if (pass)
+ continue;
+ reload_inherited[r] = 0;
+ reload_override_in[r] = 0;
}
- }
-
- /* If we found a better place to reload from,
- validate it in the same fashion, if it is a reload reg. */
- if (reload_override_in[r]
- && (GET_CODE (reload_override_in[r]) == REG
- || GET_CODE (reload_override_in[r]) == SUBREG))
- {
- int regno = true_regnum (reload_override_in[r]);
- if (spill_reg_order[regno] >= 0
- && ! reload_reg_free_before_p (regno, reload_opnum[r],
- reload_when_needed[r], 1))
- reload_override_in[r] = 0;
+ /* If we can inherit a RELOAD_FOR_INPUT, or can use a
+ reload_override_in, then we do not need its related
+ RELOAD_FOR_INPUT_ADDRESS / RELOAD_FOR_INPADDR_ADDRESS reloads;
+ likewise for other reload types.
+ We handle this by removing a reload when its only replacement
+ is mentioned in reload_in of the reload we are going to inherit.
+ A special case are auto_inc expressions; even if the input is
+ inherited, we still need the address for the output. We can
+ recognize them because they have RELOAD_OUT set but not
+ RELOAD_OUT_REG.
+ If we suceeded removing some reload and we are doing a preliminary
+ pass just to remove such reloads, make another pass, since the
+ removal of one reload might allow us to inherit another one. */
+ else if ((! reload_out[r] || reload_out_reg[r])
+ && reload_in[r]
+ && remove_address_replacements (reload_in[r]) && pass)
+ pass = 2;
}
}
@@ -6164,10 +6353,10 @@ choose_reload_regs (insn, avoid_return_reg)
/* I is nonneg if this reload uses a register.
If reload_reg_rtx[r] is 0, this is an optional reload
that we opted to ignore. */
- if (reload_out[r] != 0 && GET_CODE (reload_out[r]) == REG
+ if (reload_out_reg[r] != 0 && GET_CODE (reload_out_reg[r]) == REG
&& reload_reg_rtx[r] != 0)
{
- register int nregno = REGNO (reload_out[r]);
+ register int nregno = REGNO (reload_out_reg[r]);
int nr = 1;
if (nregno < FIRST_PSEUDO_REGISTER)
@@ -6190,6 +6379,24 @@ choose_reload_regs (insn, avoid_return_reg)
}
}
}
+
+/* Deallocate the reload register for reload R. This is called from
+ remove_address_replacements. */
+void
+deallocate_reload_reg (r)
+ int r;
+{
+ int regno;
+
+ if (! reload_reg_rtx[r])
+ return;
+ regno = true_regnum (reload_reg_rtx[r]);
+ reload_reg_rtx[r] = 0;
+ if (spill_reg_order[regno] >= 0)
+ clear_reload_reg_in_use (regno, reload_opnum[r], reload_when_needed[r],
+ reload_mode[r]);
+ reload_spill_index[r] = -1;
+}
/* If SMALL_REGISTER_CLASSES is non-zero, we may not have merged two
reloads of the same item for fear that we might not have enough reload
@@ -6305,10 +6512,11 @@ merge_assigned_reloads (insn)
/* Output insns to reload values in and out of the chosen reload regs. */
static void
-emit_reload_insns (insn, bb)
- rtx insn;
- int bb;
+emit_reload_insns (chain)
+ struct insn_chain *chain;
{
+ rtx insn = chain->insn;
+
register int j;
rtx input_reload_insns[MAX_RECOG_OPERANDS];
rtx other_input_address_reload_insns = 0;
@@ -6349,11 +6557,17 @@ emit_reload_insns (insn, bb)
rtx this_reload_insn = 0;
int expect_occurrences = 1;
- if (reload_spill_index[j] >= 0)
- new_spill_reg_store[reload_spill_index[j]] = 0;
+ if (reload_reg_rtx[j]
+ && REGNO (reload_reg_rtx[j]) < FIRST_PSEUDO_REGISTER)
+ new_spill_reg_store[REGNO (reload_reg_rtx[j])] = 0;
- old = reload_in[j];
- if (old != 0 && ! reload_inherited[j]
+ old = (reload_in[j] && GET_CODE (reload_in[j]) == MEM
+ ? reload_in_reg[j] : reload_in[j]);
+
+ if (old != 0
+ /* AUTO_INC reloads need to be handled even if inherited. We got an
+ AUTO_INC reload if reload_out is set but reload_out_reg isn't. */
+ && (! reload_inherited[j] || (reload_out[j] && ! reload_out_reg[j]))
&& ! rtx_equal_p (reload_reg_rtx[j], old)
&& reload_reg_rtx[j] != 0)
{
@@ -6433,31 +6647,14 @@ emit_reload_insns (insn, bb)
{
int regno = true_regnum (oldequiv);
- /* If OLDEQUIV is a spill register, don't use it for this
- if any other reload needs it at an earlier stage of this insn
- or at this stage. */
- if (spill_reg_order[regno] >= 0
- && (! reload_reg_free_p (regno, reload_opnum[j],
- reload_when_needed[j])
- || ! reload_reg_free_before_p (regno, reload_opnum[j],
- reload_when_needed[j], 1)))
+ /* Don't use OLDEQUIV if any other reload changes it at an
+ earlier stage of this insn or at this stage. */
+ if (! reload_reg_free_for_value_p (regno, reload_opnum[j],
+ reload_when_needed[j],
+ reload_in[j], const0_rtx, j,
+ 0))
oldequiv = 0;
- /* If OLDEQUIV is not a spill register,
- don't use it if any other reload wants it. */
- if (spill_reg_order[regno] < 0)
- {
- int k;
- for (k = 0; k < n_reloads; k++)
- if (reload_reg_rtx[k] != 0 && k != j
- && reg_overlap_mentioned_for_reload_p (reload_reg_rtx[k],
- oldequiv))
- {
- oldequiv = 0;
- break;
- }
- }
-
/* If it is no cheaper to copy from OLDEQUIV into the
reload register than it would be to move from memory,
don't use it. Likewise, if we need a secondary register
@@ -6482,6 +6679,17 @@ emit_reload_insns (insn, bb)
oldequiv = 0;
}
+ /* delete_output_reload is only invoked properly if old contains
+ the original pseudo register. Since this is replaced with a
+ hard reg when RELOAD_OVERRIDE_IN is set, see if we can
+ find the pseudo in RELOAD_IN_REG. */
+ if (oldequiv == 0
+ && reload_override_in[j]
+ && GET_CODE (reload_in_reg[j]) == REG)
+ {
+ oldequiv = old;
+ old = reload_in_reg[j];
+ }
if (oldequiv == 0)
oldequiv = old;
else if (GET_CODE (oldequiv) == REG)
@@ -6496,11 +6704,11 @@ emit_reload_insns (insn, bb)
if (optimize && GET_CODE (oldequiv) == REG
&& REGNO (oldequiv) < FIRST_PSEUDO_REGISTER
&& spill_reg_store[REGNO (oldequiv)]
- && GET_CODE (old) == REG && dead_or_set_p (insn, old)
- /* This is unsafe if operand occurs more than once in current
- insn. Perhaps some occurrences weren't reloaded. */
- && count_occurrences (PATTERN (insn), old) == 1)
- delete_output_reload (insn, j, spill_reg_store[REGNO (oldequiv)]);
+ && GET_CODE (old) == REG
+ && (dead_or_set_p (insn, spill_reg_stored_to[REGNO (oldequiv)])
+ || rtx_equal_p (spill_reg_stored_to[REGNO (oldequiv)],
+ reload_out_reg[j])))
+ delete_output_reload (insn, j, REGNO (oldequiv));
/* Encapsulate both RELOADREG and OLDEQUIV into that mode,
then load RELOADREG from OLDEQUIV. Note that we cannot use
@@ -6554,20 +6762,35 @@ emit_reload_insns (insn, bb)
special = 0;
/* Auto-increment addresses must be reloaded in a special way. */
- if (GET_CODE (oldequiv) == POST_INC
- || GET_CODE (oldequiv) == POST_DEC
- || GET_CODE (oldequiv) == PRE_INC
- || GET_CODE (oldequiv) == PRE_DEC)
+ if (reload_out[j] && ! reload_out_reg[j])
{
/* We are not going to bother supporting the case where a
incremented register can't be copied directly from
OLDEQUIV since this seems highly unlikely. */
if (reload_secondary_in_reload[j] >= 0)
abort ();
+
+ if (reload_inherited[j])
+ oldequiv = reloadreg;
+
+ old = XEXP (reload_in_reg[j], 0);
+
+ if (optimize && GET_CODE (oldequiv) == REG
+ && REGNO (oldequiv) < FIRST_PSEUDO_REGISTER
+ && spill_reg_store[REGNO (oldequiv)]
+ && GET_CODE (old) == REG
+ && (dead_or_set_p (insn,
+ spill_reg_stored_to[REGNO (oldequiv)])
+ || rtx_equal_p (spill_reg_stored_to[REGNO (oldequiv)],
+ old)))
+ delete_output_reload (insn, j, REGNO (oldequiv));
+
/* Prevent normal processing of this reload. */
special = 1;
/* Output a special code sequence for this case. */
- inc_for_reload (reloadreg, oldequiv, reload_inc[j]);
+ new_spill_reg_store[REGNO (reloadreg)]
+ = inc_for_reload (reloadreg, oldequiv, reload_out[j],
+ reload_inc[j]);
}
/* If we are reloading a pseudo-register that was set by the previous
@@ -6579,9 +6802,11 @@ emit_reload_insns (insn, bb)
&& dead_or_set_p (insn, old)
/* This is unsafe if some other reload
uses the same reg first. */
- && reload_reg_free_before_p (REGNO (reloadreg),
- reload_opnum[j],
- reload_when_needed[j], 0))
+ && reload_reg_free_for_value_p (REGNO (reloadreg),
+ reload_opnum[j],
+ reload_when_needed[j],
+ old, reload_out[j],
+ j, 0))
{
rtx temp = PREV_INSN (insn);
while (temp && GET_CODE (temp) == NOTE)
@@ -6603,6 +6828,18 @@ emit_reload_insns (insn, bb)
{
/* Store into the reload register instead of the pseudo. */
SET_DEST (PATTERN (temp)) = reloadreg;
+
+ /* If the previous insn is an output reload, the source is
+ a reload register, and its spill_reg_store entry will
+ contain the previous destination. This is now
+ invalid. */
+ if (GET_CODE (SET_SRC (PATTERN (temp))) == REG
+ && REGNO (SET_SRC (PATTERN (temp))) < FIRST_PSEUDO_REGISTER)
+ {
+ spill_reg_store[REGNO (SET_SRC (PATTERN (temp)))] = 0;
+ spill_reg_stored_to[REGNO (SET_SRC (PATTERN (temp)))] = 0;
+ }
+
/* If these are the only uses of the pseudo reg,
pretend for GDB it lives in the reload reg we used. */
if (REG_N_DEATHS (REGNO (old)) == 1
@@ -6643,15 +6880,35 @@ emit_reload_insns (insn, bb)
/* If OLDEQUIV is a pseudo with a MEM, get the real MEM
and similarly for OLD.
See comments in get_secondary_reload in reload.c. */
+ /* If it is a pseudo that cannot be replaced with its
+ equivalent MEM, we must fall back to reload_in, which
+ will have all the necessary substitutions registered.
+ Likewise for a pseudo that can't be replaced with its
+ equivalent constant. */
+
if (GET_CODE (oldequiv) == REG
&& REGNO (oldequiv) >= FIRST_PSEUDO_REGISTER
- && reg_equiv_mem[REGNO (oldequiv)] != 0)
- real_oldequiv = reg_equiv_mem[REGNO (oldequiv)];
+ && (reg_equiv_memory_loc[REGNO (oldequiv)] != 0
+ || reg_equiv_constant[REGNO (oldequiv)] != 0))
+ {
+ if (! reg_equiv_mem[REGNO (oldequiv)]
+ || num_not_at_initial_offset)
+ real_oldequiv = reload_in[j];
+ else
+ real_oldequiv = reg_equiv_mem[REGNO (oldequiv)];
+ }
if (GET_CODE (old) == REG
&& REGNO (old) >= FIRST_PSEUDO_REGISTER
- && reg_equiv_mem[REGNO (old)] != 0)
- real_old = reg_equiv_mem[REGNO (old)];
+ && (reg_equiv_memory_loc[REGNO (old)] != 0
+ || reg_equiv_constant[REGNO (old)] != 0))
+ {
+ if (! reg_equiv_mem[REGNO (old)]
+ || num_not_at_initial_offset)
+ real_old = reload_in[j];
+ else
+ real_old = reg_equiv_mem[REGNO (old)];
+ }
second_reload_reg = reload_reg_rtx[secondary_reload];
icode = reload_secondary_in_icode[j];
@@ -6736,7 +6993,7 @@ emit_reload_insns (insn, bb)
third_reload_reg)));
}
else
- gen_reload (second_reload_reg, oldequiv,
+ gen_reload (second_reload_reg, real_oldequiv,
reload_opnum[j],
reload_when_needed[j]);
@@ -6747,8 +7004,25 @@ emit_reload_insns (insn, bb)
#endif
if (! special && ! rtx_equal_p (reloadreg, oldequiv))
- gen_reload (reloadreg, oldequiv, reload_opnum[j],
- reload_when_needed[j]);
+ {
+ rtx real_oldequiv = oldequiv;
+
+ if ((GET_CODE (oldequiv) == REG
+ && REGNO (oldequiv) >= FIRST_PSEUDO_REGISTER
+ && (reg_equiv_memory_loc[REGNO (oldequiv)] != 0
+ || reg_equiv_constant[REGNO (oldequiv)] != 0))
+ || (GET_CODE (oldequiv) == SUBREG
+ && GET_CODE (SUBREG_REG (oldequiv)) == REG
+ && (REGNO (SUBREG_REG (oldequiv))
+ >= FIRST_PSEUDO_REGISTER)
+ && ((reg_equiv_memory_loc
+ [REGNO (SUBREG_REG (oldequiv))] != 0)
+ || (reg_equiv_constant
+ [REGNO (SUBREG_REG (oldequiv))] != 0))))
+ real_oldequiv = reload_in[j];
+ gen_reload (reloadreg, real_oldequiv, reload_opnum[j],
+ reload_when_needed[j]);
+ }
}
@@ -6756,6 +7030,11 @@ emit_reload_insns (insn, bb)
/* End this sequence. */
*where = get_insns ();
end_sequence ();
+
+ /* Update reload_override_in so that delete_address_reloads_1
+ can see the actual register usage. */
+ if (oldequiv_reg)
+ reload_override_in[j] = oldequiv;
}
/* When inheriting a wider reload, we have a MEM in reload_in[j],
@@ -6763,6 +7042,7 @@ emit_reload_insns (insn, bb)
(mem:HI (plus:SI (reg:SI 14 fp) (const_int 10))) */
if (optimize && reload_inherited[j] && reload_in[j]
&& GET_CODE (reload_in[j]) == MEM
+ && GET_CODE (reload_in_reg[j]) == MEM
&& reload_spill_index[j] >= 0
&& TEST_HARD_REG_BIT (reg_reloaded_valid, reload_spill_index[j]))
{
@@ -6776,27 +7056,26 @@ emit_reload_insns (insn, bb)
output-reload, see if we can prove there was
actually no need to store the old value in it. */
- if (optimize && reload_inherited[j] && reload_spill_index[j] >= 0
- && reload_in[j] != 0
- && GET_CODE (reload_in[j]) == REG
+ if (optimize
+ && (reload_inherited[j] || reload_override_in[j])
+ && reload_reg_rtx[j]
+ && GET_CODE (reload_reg_rtx[j]) == REG
+ && spill_reg_store[REGNO (reload_reg_rtx[j])] != 0
#if 0
/* There doesn't seem to be any reason to restrict this to pseudos
and doing so loses in the case where we are copying from a
register of the wrong class. */
- && REGNO (reload_in[j]) >= FIRST_PSEUDO_REGISTER
+ && REGNO (spill_reg_stored_to[REGNO (reload_reg_rtx[j])])
+ >= FIRST_PSEUDO_REGISTER
#endif
- && spill_reg_store[reload_spill_index[j]] != 0
- /* This is unsafe if some other reload uses the same reg first. */
- && reload_reg_free_before_p (reload_spill_index[j],
- reload_opnum[j], reload_when_needed[j],
- 0)
- && dead_or_set_p (insn, reload_in[j])
- /* This is unsafe if operand occurs more than once in current
- insn. Perhaps some occurrences weren't reloaded. */
- && (count_occurrences (PATTERN (insn), reload_in[j])
- == expect_occurrences))
- delete_output_reload (insn, j,
- spill_reg_store[reload_spill_index[j]]);
+ /* The insn might have already some references to stackslots
+ replaced by MEMs, while reload_out_reg still names the
+ original pseudo. */
+ && (dead_or_set_p (insn,
+ spill_reg_stored_to[REGNO (reload_reg_rtx[j])])
+ || rtx_equal_p (spill_reg_stored_to[REGNO (reload_reg_rtx[j])],
+ reload_out_reg[j])))
+ delete_output_reload (insn, j, REGNO (reload_reg_rtx[j]));
/* Input-reloading is done. Now do output-reloading,
storing the value from the reload-register after the main insn
@@ -6804,7 +7083,33 @@ emit_reload_insns (insn, bb)
??? At some point we need to support handling output reloads of
JUMP_INSNs or insns that set cc0. */
- old = reload_out[j];
+
+ /* If this is an output reload that stores something that is
+ not loaded in this same reload, see if we can eliminate a previous
+ store. */
+ {
+ rtx pseudo = reload_out_reg[j];
+
+ if (pseudo
+ && GET_CODE (pseudo) == REG
+ && ! rtx_equal_p (reload_in_reg[j], pseudo)
+ && REGNO (pseudo) >= FIRST_PSEUDO_REGISTER
+ && reg_last_reload_reg[REGNO (pseudo)])
+ {
+ int pseudo_no = REGNO (pseudo);
+ int last_regno = REGNO (reg_last_reload_reg[pseudo_no]);
+
+ /* We don't need to test full validity of last_regno for
+ inherit here; we only want to know if the store actually
+ matches the pseudo. */
+ if (reg_reloaded_contents[last_regno] == pseudo_no
+ && spill_reg_store[last_regno]
+ && rtx_equal_p (pseudo, spill_reg_stored_to[last_regno]))
+ delete_output_reload (insn, j, last_regno);
+ }
+ }
+
+ old = reload_out_reg[j];
if (old != 0
&& reload_reg_rtx[j] != old
&& reload_reg_rtx[j] != 0)
@@ -6860,6 +7165,8 @@ emit_reload_insns (insn, bb)
else
push_to_sequence (output_reload_insns[reload_opnum[j]]);
+ old = reload_out[j];
+
/* Determine the mode to reload in.
See comments above (for input reloading). */
@@ -6990,21 +7297,22 @@ emit_reload_insns (insn, bb)
if (reg_mentioned_p (reload_reg_rtx[j], pat))
{
+ rtx set = single_set (insn);
if (reload_spill_index[j] < 0
- && GET_CODE (pat) == SET
- && SET_SRC (pat) == reload_reg_rtx[j])
+ && set
+ && SET_SRC (set) == reload_reg_rtx[j])
{
- int src = REGNO (SET_SRC (pat));
+ int src = REGNO (SET_SRC (set));
reload_spill_index[j] = src;
SET_HARD_REG_BIT (reg_is_output_reload, src);
if (find_regno_note (insn, REG_DEAD, src))
SET_HARD_REG_BIT (reg_reloaded_died, src);
}
- if (reload_spill_index[j] >= 0)
+ if (REGNO (reload_reg_rtx[j]) < FIRST_PSEUDO_REGISTER)
{
int s = reload_secondary_out_reload[j];
- rtx set = single_set (p);
+ set = single_set (p);
/* If this reload copies only to the secondary reload
register, the secondary reload does the actual
store. */
@@ -7023,13 +7331,18 @@ emit_reload_insns (insn, bb)
rtx s_reg = reload_reg_rtx[s];
rtx next = NEXT_INSN (p);
reload_out[s] = reload_out[j];
+ reload_out_reg[s] = reload_out_reg[j];
set = single_set (next);
if (set && SET_SRC (set) == s_reg
&& ! new_spill_reg_store[REGNO (s_reg)])
- new_spill_reg_store[REGNO (s_reg)] = next;
+ {
+ SET_HARD_REG_BIT (reg_is_output_reload,
+ REGNO (s_reg));
+ new_spill_reg_store[REGNO (s_reg)] = next;
+ }
}
else
- new_spill_reg_store[reload_spill_index[j]] = p;
+ new_spill_reg_store[REGNO (reload_reg_rtx[j])] = p;
}
}
}
@@ -7094,10 +7407,10 @@ emit_reload_insns (insn, bb)
/* Keep basic block info up to date. */
if (n_basic_blocks)
{
- if (basic_block_head[bb] == insn)
- basic_block_head[bb] = NEXT_INSN (before_insn);
- if (basic_block_end[bb] == insn)
- basic_block_end[bb] = PREV_INSN (following_insn);
+ if (BLOCK_HEAD (chain->block) == insn)
+ BLOCK_HEAD (chain->block) = NEXT_INSN (before_insn);
+ if (BLOCK_END (chain->block) == insn)
+ BLOCK_END (chain->block) = PREV_INSN (following_insn);
}
/* For all the spill regs newly reloaded in this instruction,
@@ -7112,6 +7425,34 @@ emit_reload_insns (insn, bb)
register int r = reload_order[j];
register int i = reload_spill_index[r];
+ /* If this is a non-inherited input reload from a pseudo, we must
+ clear any memory of a previous store to the same pseudo. Only do
+ something if there will not be an output reload for the pseudo
+ being reloaded. */
+ if (reload_in_reg[r] != 0
+ && ! (reload_inherited[r] || reload_override_in[r]))
+ {
+ rtx reg = reload_in_reg[r];
+
+ if (GET_CODE (reg) == SUBREG)
+ reg = SUBREG_REG (reg);
+
+ if (GET_CODE (reg) == REG
+ && REGNO (reg) >= FIRST_PSEUDO_REGISTER
+ && ! reg_has_output_reload[REGNO (reg)])
+ {
+ int nregno = REGNO (reg);
+
+ if (reg_last_reload_reg[nregno])
+ {
+ int last_regno = REGNO (reg_last_reload_reg[nregno]);
+
+ if (reg_reloaded_contents[last_regno] == nregno)
+ spill_reg_store[last_regno] = 0;
+ }
+ }
+ }
+
/* I is nonneg if this reload used a register.
If reload_reg_rtx[r] is 0, this is an optional reload
that we opted to ignore. */
@@ -7146,14 +7487,25 @@ emit_reload_insns (insn, bb)
CLEAR_HARD_REG_BIT (reg_reloaded_valid, i + k);
/* Maybe the spill reg contains a copy of reload_out. */
- if (reload_out[r] != 0 && GET_CODE (reload_out[r]) == REG)
+ if (reload_out[r] != 0
+ && (GET_CODE (reload_out[r]) == REG
+#ifdef AUTO_INC_DEC
+ || ! reload_out_reg[r]
+#endif
+ || GET_CODE (reload_out_reg[r]) == REG))
{
- register int nregno = REGNO (reload_out[r]);
+ rtx out = (GET_CODE (reload_out[r]) == REG
+ ? reload_out[r]
+ : reload_out_reg[r]
+ ? reload_out_reg[r]
+/* AUTO_INC */ : XEXP (reload_in_reg[r], 0));
+ register int nregno = REGNO (out);
int nnr = (nregno >= FIRST_PSEUDO_REGISTER ? 1
: HARD_REGNO_NREGS (nregno,
GET_MODE (reload_reg_rtx[r])));
spill_reg_store[i] = new_spill_reg_store[i];
+ spill_reg_stored_to[i] = out;
reg_last_reload_reg[nregno] = reload_reg_rtx[r];
/* If NREGNO is a hard register, it may occupy more than
@@ -7186,21 +7538,25 @@ emit_reload_insns (insn, bb)
/* Maybe the spill reg contains a copy of reload_in. Only do
something if there will not be an output reload for
the register being reloaded. */
- else if (reload_out[r] == 0
+ else if (reload_out_reg[r] == 0
&& reload_in[r] != 0
- && spill_reg_order[i] >= 0
&& ((GET_CODE (reload_in[r]) == REG
+ && REGNO (reload_in[r]) >= FIRST_PSEUDO_REGISTER
&& ! reg_has_output_reload[REGNO (reload_in[r])])
|| (GET_CODE (reload_in_reg[r]) == REG
- && ! reg_has_output_reload[REGNO (reload_in_reg[r])])))
+ && ! reg_has_output_reload[REGNO (reload_in_reg[r])]))
+ && ! reg_set_p (reload_reg_rtx[r], PATTERN (insn)))
{
register int nregno;
int nnr;
- if (GET_CODE (reload_in[r]) == REG)
+ if (GET_CODE (reload_in[r]) == REG
+ && REGNO (reload_in[r]) >= FIRST_PSEUDO_REGISTER)
nregno = REGNO (reload_in[r]);
- else
+ else if (GET_CODE (reload_in_reg[r]) == REG)
nregno = REGNO (reload_in_reg[r]);
+ else
+ nregno = REGNO (XEXP (reload_in_reg[r], 0));
nnr = (nregno >= FIRST_PSEUDO_REGISTER ? 1
: HARD_REGNO_NREGS (nregno,
@@ -7217,8 +7573,11 @@ emit_reload_insns (insn, bb)
: 0);
/* Unless we inherited this reload, show we haven't
- recently done a store. */
- if (! reload_inherited[r])
+ recently done a store.
+ Previous stores of inherited auto_inc expressions
+ also have to be discarded. */
+ if (! reload_inherited[r]
+ || (reload_out[r] && ! reload_out_reg[r]))
spill_reg_store[i] = 0;
for (k = 0; k < nr; k++)
@@ -7254,11 +7613,77 @@ emit_reload_insns (insn, bb)
that invalidates any previous reloaded copy of it.
But forget_old_reloads_1 won't get to see it, because
it thinks only about the original insn. So invalidate it here. */
- if (i < 0 && reload_out[r] != 0 && GET_CODE (reload_out[r]) == REG)
+ if (i < 0 && reload_out[r] != 0
+ && (GET_CODE (reload_out[r]) == REG
+ || (GET_CODE (reload_out[r]) == MEM
+ && GET_CODE (reload_out_reg[r]) == REG)))
{
- register int nregno = REGNO (reload_out[r]);
+ rtx out = (GET_CODE (reload_out[r]) == REG
+ ? reload_out[r] : reload_out_reg[r]);
+ register int nregno = REGNO (out);
if (nregno >= FIRST_PSEUDO_REGISTER)
- reg_last_reload_reg[nregno] = 0;
+ {
+ rtx src_reg, store_insn;
+
+ reg_last_reload_reg[nregno] = 0;
+
+ /* If we can find a hard register that is stored, record
+ the storing insn so that we may delete this insn with
+ delete_output_reload. */
+ src_reg = reload_reg_rtx[r];
+
+ /* If this is an optional reload, try to find the source reg
+ from an input reload. */
+ if (! src_reg)
+ {
+ rtx set = single_set (insn);
+ if (set && SET_DEST (set) == reload_out[r])
+ {
+ int k;
+
+ src_reg = SET_SRC (set);
+ store_insn = insn;
+ for (k = 0; k < n_reloads; k++)
+ {
+ if (reload_in[k] == src_reg)
+ {
+ src_reg = reload_reg_rtx[k];
+ break;
+ }
+ }
+ }
+ }
+ else
+ store_insn = new_spill_reg_store[REGNO (src_reg)];
+ if (src_reg && GET_CODE (src_reg) == REG
+ && REGNO (src_reg) < FIRST_PSEUDO_REGISTER)
+ {
+ int src_regno = REGNO (src_reg);
+ int nr = HARD_REGNO_NREGS (src_regno, reload_mode[r]);
+ /* The place where to find a death note varies with
+ PRESERVE_DEATH_INFO_REGNO_P . The condition is not
+ necessarily checked exactly in the code that moves
+ notes, so just check both locations. */
+ rtx note = find_regno_note (insn, REG_DEAD, src_regno);
+ if (! note)
+ note = find_regno_note (store_insn, REG_DEAD, src_regno);
+ while (nr-- > 0)
+ {
+ spill_reg_store[src_regno + nr] = store_insn;
+ spill_reg_stored_to[src_regno + nr] = out;
+ reg_reloaded_contents[src_regno + nr] = nregno;
+ reg_reloaded_insn[src_regno + nr] = store_insn;
+ CLEAR_HARD_REG_BIT (reg_reloaded_dead, src_regno + nr);
+ SET_HARD_REG_BIT (reg_reloaded_valid, src_regno + nr);
+ SET_HARD_REG_BIT (reg_is_output_reload, src_regno + nr);
+ if (note)
+ SET_HARD_REG_BIT (reg_reloaded_died, src_regno);
+ else
+ CLEAR_HARD_REG_BIT (reg_reloaded_died, src_regno);
+ }
+ reg_last_reload_reg[nregno] = src_reg;
+ }
+ }
else
{
int num_regs = HARD_REGNO_NREGS (nregno,GET_MODE (reload_out[r]));
@@ -7345,7 +7770,7 @@ gen_reload (out, in, opnum, type)
It might be better not to actually emit the insn unless it is valid,
but we need to pass the insn as an operand to `recog' and
- `insn_extract' and it is simpler to emit and then delete the insn if
+ `extract_insn' and it is simpler to emit and then delete the insn if
not valid than to dummy things up. */
rtx op0, op1, tem, insn;
@@ -7373,11 +7798,11 @@ gen_reload (out, in, opnum, type)
if (code >= 0)
{
- insn_extract (insn);
+ extract_insn (insn);
/* We want constrain operands to treat this insn strictly in
its validity determination, i.e., the way it would after reload
has completed. */
- if (constrain_operands (code, 1))
+ if (constrain_operands (1))
return insn;
}
@@ -7415,11 +7840,11 @@ gen_reload (out, in, opnum, type)
if (code >= 0)
{
- insn_extract (insn);
+ extract_insn (insn);
/* We want constrain operands to treat this insn strictly in
its validity determination, i.e., the way it would after reload
has completed. */
- if (constrain_operands (code, 1))
+ if (constrain_operands (1))
{
/* Add a REG_EQUIV note so that find_equiv_reg can find it. */
REG_NOTES (insn)
@@ -7484,22 +7909,68 @@ gen_reload (out, in, opnum, type)
First we double-check.
INSN is the insn now being processed.
- OUTPUT_RELOAD_INSN is the insn of the output reload.
- J is the reload-number for this insn. */
+ LAST_RELOAD_REG is the hard register number for which we want to delete
+ the last output reload.
+ J is the reload-number that originally used REG. The caller has made
+ certain that reload J doesn't use REG any longer for input. */
static void
-delete_output_reload (insn, j, output_reload_insn)
+delete_output_reload (insn, j, last_reload_reg)
rtx insn;
int j;
- rtx output_reload_insn;
+ int last_reload_reg;
{
+ rtx output_reload_insn = spill_reg_store[last_reload_reg];
+ rtx reg = spill_reg_stored_to[last_reload_reg];
+ int k;
+ int n_occurrences;
+ int n_inherited = 0;
register rtx i1;
-
+ rtx substed;
+
/* Get the raw pseudo-register referred to. */
- rtx reg = reload_in[j];
while (GET_CODE (reg) == SUBREG)
reg = SUBREG_REG (reg);
+ substed = reg_equiv_memory_loc[REGNO (reg)];
+
+ /* This is unsafe if the operand occurs more often in the current
+ insn than it is inherited. */
+ for (k = n_reloads - 1; k >= 0; k--)
+ {
+ rtx reg2 = reload_in[k];
+ if (! reg2)
+ continue;
+ if (GET_CODE (reg2) == MEM || reload_override_in[k])
+ reg2 = reload_in_reg[k];
+#ifdef AUTO_INC_DEC
+ if (reload_out[k] && ! reload_out_reg[k])
+ reg2 = XEXP (reload_in_reg[k], 0);
+#endif
+ while (GET_CODE (reg2) == SUBREG)
+ reg2 = SUBREG_REG (reg2);
+ if (rtx_equal_p (reg2, reg))
+ {
+ if (reload_inherited[k] || reload_override_in[k] || k == j)
+ {
+ n_inherited++;
+ reg2 = reload_out_reg[k];
+ if (! reg2)
+ continue;
+ while (GET_CODE (reg2) == SUBREG)
+ reg2 = XEXP (reg2, 0);
+ if (rtx_equal_p (reg2, reg))
+ n_inherited++;
+ }
+ else
+ return;
+ }
+ }
+ n_occurrences = count_occurrences (PATTERN (insn), reg);
+ if (substed)
+ n_occurrences += count_occurrences (PATTERN (insn), substed);
+ if (n_occurrences > n_inherited)
+ return;
/* If the pseudo-reg we are reloading is no longer referenced
anywhere between the store into it and here,
@@ -7514,21 +7985,14 @@ delete_output_reload (insn, j, output_reload_insn)
if ((GET_CODE (i1) == INSN || GET_CODE (i1) == CALL_INSN)
&& reg_mentioned_p (reg, PATTERN (i1)))
{
- /* If this is just a single USE with an REG_EQUAL note in front
- of INSN, this is no problem, because this mentions just the
- address that we are using here.
- But if there is more than one such USE, the insn might use
- the operand directly, or another reload might do that.
- This is analogous to the count_occurences check in the callers. */
- int num_occurences = 0;
-
- while (GET_CODE (i1) == INSN && GET_CODE (PATTERN (i1)) == USE
- && find_reg_note (i1, REG_EQUAL, NULL_RTX))
+ /* If this is USE in front of INSN, we only have to check that
+ there are no more references than accounted for by inheritance. */
+ while (GET_CODE (i1) == INSN && GET_CODE (PATTERN (i1)) == USE)
{
- num_occurences += rtx_equal_p (reg, XEXP (PATTERN (i1), 0)) != 0;
+ n_occurrences += rtx_equal_p (reg, XEXP (PATTERN (i1), 0)) != 0;
i1 = NEXT_INSN (i1);
}
- if (num_occurences == 1 && i1 == insn)
+ if (n_occurrences <= n_inherited && i1 == insn)
break;
return;
}
@@ -7545,6 +8009,7 @@ delete_output_reload (insn, j, output_reload_insn)
and forget we had a stack slot for the pseudo. */
if (reload_out[j] != reload_in[j]
&& REG_N_DEATHS (REGNO (reg)) == 1
+ && REG_N_SETS (REGNO (reg)) == 1
&& REG_BASIC_BLOCK (REGNO (reg)) >= 0
&& find_regno_note (insn, REG_DEAD, REGNO (reg)))
{
@@ -7571,7 +8036,10 @@ delete_output_reload (insn, j, output_reload_insn)
{
/* Some other ref remains; just delete the output reload we
know to be dead. */
- delete_insn (output_reload_insn);
+ delete_address_reloads (output_reload_insn, insn);
+ PUT_CODE (output_reload_insn, NOTE);
+ NOTE_SOURCE_FILE (output_reload_insn) = 0;
+ NOTE_LINE_NUMBER (output_reload_insn) = NOTE_INSN_DELETED;
return;
}
}
@@ -7583,6 +8051,7 @@ delete_output_reload (insn, j, output_reload_insn)
if (set != 0 && SET_DEST (set) == reg)
{
+ delete_address_reloads (i2, insn);
/* This might be a basic block head,
thus don't use delete_insn. */
PUT_CODE (i2, NOTE);
@@ -7599,22 +8068,179 @@ delete_output_reload (insn, j, output_reload_insn)
reg_renumber[REGNO (reg)] = REGNO (reload_reg_rtx[j]);
alter_reg (REGNO (reg), -1);
}
- delete_insn (output_reload_insn);
+ delete_address_reloads (output_reload_insn, insn);
+ PUT_CODE (output_reload_insn, NOTE);
+ NOTE_SOURCE_FILE (output_reload_insn) = 0;
+ NOTE_LINE_NUMBER (output_reload_insn) = NOTE_INSN_DELETED;
+
+}
+
+/* We are going to delete DEAD_INSN. Recursively delete loads of
+ reload registers used in DEAD_INSN that are not used till CURRENT_INSN.
+ CURRENT_INSN is being reloaded, so we have to check its reloads too. */
+static void
+delete_address_reloads (dead_insn, current_insn)
+ rtx dead_insn, current_insn;
+{
+ rtx set = single_set (dead_insn);
+ rtx set2, dst, prev, next;
+ if (set)
+ {
+ rtx dst = SET_DEST (set);
+ if (GET_CODE (dst) == MEM)
+ delete_address_reloads_1 (dead_insn, XEXP (dst, 0), current_insn);
+ }
+ /* If we deleted the store from a reloaded post_{in,de}c expression,
+ we can delete the matching adds. */
+ prev = PREV_INSN (dead_insn);
+ next = NEXT_INSN (dead_insn);
+ if (! prev || ! next)
+ return;
+ set = single_set (next);
+ set2 = single_set (prev);
+ if (! set || ! set2
+ || GET_CODE (SET_SRC (set)) != PLUS || GET_CODE (SET_SRC (set2)) != PLUS
+ || GET_CODE (XEXP (SET_SRC (set), 1)) != CONST_INT
+ || GET_CODE (XEXP (SET_SRC (set2), 1)) != CONST_INT)
+ return;
+ dst = SET_DEST (set);
+ if (! rtx_equal_p (dst, SET_DEST (set2))
+ || ! rtx_equal_p (dst, XEXP (SET_SRC (set), 0))
+ || ! rtx_equal_p (dst, XEXP (SET_SRC (set2), 0))
+ || (INTVAL (XEXP (SET_SRC (set), 1))
+ != - INTVAL (XEXP (SET_SRC (set2), 1))))
+ return;
+ delete_insn (prev);
+ delete_insn (next);
+}
+
+/* Subfunction of delete_address_reloads: process registers found in X. */
+static void
+delete_address_reloads_1 (dead_insn, x, current_insn)
+ rtx dead_insn, x, current_insn;
+{
+ rtx prev, set, dst, i2;
+ int i, j;
+ enum rtx_code code = GET_CODE (x);
+ if (code != REG)
+ {
+ char *fmt= GET_RTX_FORMAT (code);
+ for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
+ {
+ if (fmt[i] == 'e')
+ delete_address_reloads_1 (dead_insn, XEXP (x, i), current_insn);
+ else if (fmt[i] == 'E')
+ {
+ for (j = XVECLEN (x, i) - 1; j >=0; j--)
+ delete_address_reloads_1 (dead_insn, XVECEXP (x, i, j),
+ current_insn);
+ }
+ }
+ return;
+ }
+
+ if (spill_reg_order[REGNO (x)] < 0)
+ return;
+
+ /* Scan backwards for the insn that sets x. This might be a way back due
+ to inheritance. */
+ for (prev = PREV_INSN (dead_insn); prev; prev = PREV_INSN (prev))
+ {
+ code = GET_CODE (prev);
+ if (code == CODE_LABEL || code == JUMP_INSN)
+ return;
+ if (GET_RTX_CLASS (code) != 'i')
+ continue;
+ if (reg_set_p (x, PATTERN (prev)))
+ break;
+ if (reg_referenced_p (x, PATTERN (prev)))
+ return;
+ }
+ if (! prev || INSN_UID (prev) < reload_first_uid)
+ return;
+ /* Check that PREV only sets the reload register. */
+ set = single_set (prev);
+ if (! set)
+ return;
+ dst = SET_DEST (set);
+ if (GET_CODE (dst) != REG
+ || ! rtx_equal_p (dst, x))
+ return;
+ if (! reg_set_p (dst, PATTERN (dead_insn)))
+ {
+ /* Check if DST was used in a later insn -
+ it might have been inherited. */
+ for (i2 = NEXT_INSN (dead_insn); i2; i2 = NEXT_INSN (i2))
+ {
+ if (GET_CODE (i2) == CODE_LABEL)
+ break;
+ if (GET_RTX_CLASS (GET_CODE (i2)) != 'i')
+ continue;
+ if (reg_referenced_p (dst, PATTERN (i2)))
+ {
+ /* If there is a reference to the register in the current insn,
+ it might be loaded in a non-inherited reload. If no other
+ reload uses it, that means the register is set before
+ referenced. */
+ if (i2 == current_insn)
+ {
+ for (j = n_reloads - 1; j >= 0; j--)
+ if ((reload_reg_rtx[j] == dst && reload_inherited[j])
+ || reload_override_in[j] == dst)
+ return;
+ for (j = n_reloads - 1; j >= 0; j--)
+ if (reload_in[j] && reload_reg_rtx[j] == dst)
+ break;
+ if (j >= 0)
+ break;
+ }
+ return;
+ }
+ if (GET_CODE (i2) == JUMP_INSN)
+ break;
+ /* If DST is still live at CURRENT_INSN, check if it is used for
+ any reload. Note that even if CURRENT_INSN sets DST, we still
+ have to check the reloads. */
+ if (i2 == current_insn)
+ {
+ for (j = n_reloads - 1; j >= 0; j--)
+ if ((reload_reg_rtx[j] == dst && reload_inherited[j])
+ || reload_override_in[j] == dst)
+ return;
+ /* ??? We can't finish the loop here, because dst might be
+ allocated to a pseudo in this block if no reload in this
+ block needs any of the clsses containing DST - see
+ spill_hard_reg. There is no easy way to tell this, so we
+ have to scan till the end of the basic block. */
+ }
+ if (reg_set_p (dst, PATTERN (i2)))
+ break;
+ }
+ }
+ delete_address_reloads_1 (prev, SET_SRC (set), current_insn);
+ reg_reloaded_contents[REGNO (dst)] = -1;
+ /* Can't use delete_insn here because PREV might be a basic block head. */
+ PUT_CODE (prev, NOTE);
+ NOTE_LINE_NUMBER (prev) = NOTE_INSN_DELETED;
+ NOTE_SOURCE_FILE (prev) = 0;
}
/* Output reload-insns to reload VALUE into RELOADREG.
VALUE is an autoincrement or autodecrement RTX whose operand
is a register or memory location;
so reloading involves incrementing that location.
+ IN is either identical to VALUE, or some cheaper place to reload from.
INC_AMOUNT is the number to increment or decrement by (always positive).
- This cannot be deduced from VALUE. */
+ This cannot be deduced from VALUE.
-static void
-inc_for_reload (reloadreg, value, inc_amount)
+ Return the instruction that stores into RELOADREG. */
+
+static rtx
+inc_for_reload (reloadreg, in, value, inc_amount)
rtx reloadreg;
- rtx value;
+ rtx in, value;
int inc_amount;
{
/* REG or MEM to be copied and incremented. */
@@ -7625,6 +8251,8 @@ inc_for_reload (reloadreg, value, inc_amount)
rtx inc;
rtx add_insn;
int code;
+ rtx store;
+ rtx real_in = in == value ? XEXP (in, 0) : in;
/* No hard register is equivalent to this register after
inc/dec operation. If REG_LAST_RELOAD_REG were non-zero,
@@ -7639,36 +8267,38 @@ inc_for_reload (reloadreg, value, inc_amount)
inc = GEN_INT (inc_amount);
/* If this is post-increment, first copy the location to the reload reg. */
- if (post)
- emit_insn (gen_move_insn (reloadreg, incloc));
+ if (post && real_in != reloadreg)
+ emit_insn (gen_move_insn (reloadreg, real_in));
- /* See if we can directly increment INCLOC. Use a method similar to that
- in gen_reload. */
+ if (in == value)
+ {
+ /* See if we can directly increment INCLOC. Use a method similar to
+ that in gen_reload. */
- last = get_last_insn ();
- add_insn = emit_insn (gen_rtx_SET (VOIDmode, incloc,
- gen_rtx_PLUS (GET_MODE (incloc),
- incloc, inc)));
+ last = get_last_insn ();
+ add_insn = emit_insn (gen_rtx_SET (VOIDmode, incloc,
+ gen_rtx_PLUS (GET_MODE (incloc),
+ incloc, inc)));
- code = recog_memoized (add_insn);
- if (code >= 0)
- {
- insn_extract (add_insn);
- if (constrain_operands (code, 1))
+ code = recog_memoized (add_insn);
+ if (code >= 0)
{
- /* If this is a pre-increment and we have incremented the value
- where it lives, copy the incremented value to RELOADREG to
- be used as an address. */
+ extract_insn (add_insn);
+ if (constrain_operands (1))
+ {
+ /* If this is a pre-increment and we have incremented the value
+ where it lives, copy the incremented value to RELOADREG to
+ be used as an address. */
- if (! post)
- emit_insn (gen_move_insn (reloadreg, incloc));
+ if (! post)
+ emit_insn (gen_move_insn (reloadreg, incloc));
- return;
+ return add_insn;
+ }
}
+ delete_insns_since (last);
}
- delete_insns_since (last);
-
/* If couldn't do the increment directly, must increment in RELOADREG.
The way we do this depends on whether this is pre- or post-increment.
For pre-increment, copy INCLOC to the reload register, increment it
@@ -7676,9 +8306,10 @@ inc_for_reload (reloadreg, value, inc_amount)
if (! post)
{
- emit_insn (gen_move_insn (reloadreg, incloc));
+ if (in != reloadreg)
+ emit_insn (gen_move_insn (reloadreg, real_in));
emit_insn (gen_add2_insn (reloadreg, inc));
- emit_insn (gen_move_insn (incloc, reloadreg));
+ store = emit_insn (gen_move_insn (incloc, reloadreg));
}
else
{
@@ -7687,16 +8318,16 @@ inc_for_reload (reloadreg, value, inc_amount)
may not be available after the insn in an input reload, we must do
the incrementation before the insn being reloaded for.
- We have already copied INCLOC to RELOADREG. Increment the copy in
+ We have already copied IN to RELOADREG. Increment the copy in
RELOADREG, save that back, then decrement RELOADREG so it has
the original value. */
emit_insn (gen_add2_insn (reloadreg, inc));
- emit_insn (gen_move_insn (incloc, reloadreg));
+ store = emit_insn (gen_move_insn (incloc, reloadreg));
emit_insn (gen_add2_insn (reloadreg, GEN_INT (-inc_amount)));
}
- return;
+ return store;
}
/* Return 1 if we are certain that the constraint-string STRING allows
@@ -7704,7 +8335,7 @@ inc_for_reload (reloadreg, value, inc_amount)
static int
constraint_accepts_reg_p (string, reg)
- char *string;
+ const char *string;
rtx reg;
{
int value = 0;
@@ -7775,6 +8406,10 @@ count_occurrences (x, find)
case CC0:
return 0;
+ case MEM:
+ if (GET_CODE (find) == MEM && rtx_equal_p (x, find))
+ return 1;
+ break;
case SET:
if (SET_DEST (x) == find)
return count_occurrences (SET_SRC (x), find);
@@ -7807,270 +8442,6 @@ count_occurrences (x, find)
return count;
}
-static HARD_REG_SET set_regs;
-static HARD_REG_SET used_regs;
-static HARD_REG_SET live_regs;
-
-/* Walk the rtx X recursively, calling WORKER for every sub-expression with
- the type of access as parameter. */
-static void
-find_set_and_used_regs (x, read, written)
- rtx x;
- int read, written;
-{
- enum rtx_code code;
- const char *fmt;
- int i, regno, nregs;
-
- if (0 && x == 0)
- return;
-
- code = GET_CODE (x);
- if (code == SUBREG)
- {
- x = SUBREG_REG (x);
- code = GET_CODE (x);
- }
-
- switch (code)
- {
- case PC:
- case CC0:
- case SCRATCH:
- case LABEL_REF:
- case SYMBOL_REF:
- return;
-
- case REG:
- regno = REGNO (x);
- if (regno >= FIRST_PSEUDO_REGISTER)
- return;
- nregs = HARD_REGNO_NREGS (regno, GET_MODE (x));
- while (nregs-- > 0)
- {
- if (written)
- SET_HARD_REG_BIT (set_regs, regno + nregs);
- if (read)
- SET_HARD_REG_BIT (used_regs, regno + nregs);
- }
- return;
-
- case ZERO_EXTRACT:
- case SIGN_EXTRACT:
- find_set_and_used_regs (XEXP (x, 0), read, written);
- find_set_and_used_regs (XEXP (x, 1), 1, 0);
- find_set_and_used_regs (XEXP (x, 2), 1, 0);
- return;
-
- case PRE_DEC:
- case POST_DEC:
- case PRE_INC:
- case POST_INC:
- find_set_and_used_regs (XEXP (x, 0), 1, 1);
- return;
-
- case SET:
- find_set_and_used_regs (SET_SRC (x), 1, 0);
-
- /* fall through */
- case CLOBBER:
- find_set_and_used_regs (SET_DEST (x), 0, 1);
- return;
-
- default:
- break;
- }
-
- fmt = GET_RTX_FORMAT (code);
- for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
- {
- if (fmt[i] == 'e')
- find_set_and_used_regs (XEXP (x, i), 1, 0);
- else if (fmt[i] == 'E')
- {
- int j;
-
- for (j = 0; j < XVECLEN (x, i); j++)
- find_set_and_used_regs (XVECEXP (x, i, j), 1, 0);
- }
- }
-}
-
-static void
-calc_reg_usage (insn, make_notes)
- rtx insn;
- int make_notes;
-{
- int i;
-
- CLEAR_HARD_REG_SET (set_regs);
- CLEAR_HARD_REG_SET (used_regs);
- find_set_and_used_regs (PATTERN (insn), 0, 0);
-
- if (GET_CODE (insn) == CALL_INSN)
- {
- rtx x;
- for (x = CALL_INSN_FUNCTION_USAGE (insn); x != 0; x = XEXP (x, 1))
- find_set_and_used_regs (XEXP (x, 0), 0, 0);
- for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
- if (call_used_regs[i] && ! fixed_regs[i] && ! global_regs[i])
- SET_HARD_REG_BIT (set_regs, i);
- }
-
- if (! make_notes)
- return;
-
- for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
- {
- if (TEST_HARD_REG_BIT (live_regs, i))
- continue;
- if (TEST_HARD_REG_BIT (set_regs, i))
- REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_UNUSED,
- gen_rtx_REG (reg_raw_mode[i], i),
- REG_NOTES (insn));
- else if (TEST_HARD_REG_BIT (used_regs, i))
- REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_DEAD,
- gen_rtx_REG (reg_raw_mode[i], i),
- REG_NOTES (insn));
- }
- AND_COMPL_HARD_REG_SET (live_regs, set_regs);
- IOR_HARD_REG_SET (live_regs, used_regs);
-}
-
-/* Now that all pseudo registers have been eliminated, calculate hard register
- life information. */
-void
-reload_life_analysis (first)
- rtx first;
-{
- rtx insn, last;
- int b;
- int_list_ptr *s_preds, *s_succs;
- int *num_preds, *num_succs;
- HARD_REG_SET *block_sets;
- HARD_REG_SET *block_uses;
- HARD_REG_SET *live_at_start;
- HARD_REG_SET *live_at_end;
- int outside_block = 1;
-
- s_preds = (int_list_ptr *) xmalloc (n_basic_blocks * sizeof (int_list_ptr));
- s_succs = (int_list_ptr *) xmalloc (n_basic_blocks * sizeof (int_list_ptr));
- num_preds = (int *) xmalloc (n_basic_blocks * sizeof (int));
- num_succs = (int *) xmalloc (n_basic_blocks * sizeof (int));
- block_sets = (HARD_REG_SET *) xmalloc (n_basic_blocks * sizeof (HARD_REG_SET));
- block_uses = (HARD_REG_SET *) xmalloc (n_basic_blocks * sizeof (HARD_REG_SET));
- live_at_start = (HARD_REG_SET *) xmalloc (n_basic_blocks * sizeof (HARD_REG_SET));
- live_at_end = (HARD_REG_SET *) xmalloc (n_basic_blocks * sizeof (HARD_REG_SET));
-
- bzero (block_sets, n_basic_blocks * sizeof (HARD_REG_SET));
- bzero (block_uses, n_basic_blocks * sizeof (HARD_REG_SET));
- bzero (live_at_start, n_basic_blocks * sizeof (HARD_REG_SET));
- bzero (live_at_end, n_basic_blocks * sizeof (HARD_REG_SET));
-
- compute_preds_succs (s_preds, s_succs, num_preds, num_succs);
-
- b = n_basic_blocks;
- for (last = first; NEXT_INSN (last); last = NEXT_INSN (last))
- ;
- for (insn = last; insn; insn = PREV_INSN (insn))
- {
- enum rtx_code code = GET_CODE (insn);
-
- /* Start with fresh live info at the end of every basic block. */
- if (b > 0 && basic_block_end[b - 1] == insn)
- {
- outside_block = 0;
- b--;
- }
- if (GET_RTX_CLASS (code) == 'i' && outside_block)
- abort ();
-
- /* Clobbers are inserted during rtl expansion to show flow.c that some
- values die when that is non-obvious. Once all pseudos are converted
- tohard regs, that information is no longer needed, and can in fact
- be incorrect. */
- if (GET_RTX_CLASS (code) == 'i' && GET_CODE (PATTERN (insn)) == CLOBBER)
- {
- PUT_CODE (insn, NOTE);
- NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
- NOTE_SOURCE_FILE (insn) = 0;
- code = NOTE;
- }
- if (GET_RTX_CLASS (code) == 'i')
- {
- calc_reg_usage (insn, 0);
-
- IOR_HARD_REG_SET (block_sets[b], set_regs);
- AND_COMPL_HARD_REG_SET (block_sets[b], used_regs);
-
- AND_COMPL_HARD_REG_SET (block_uses[b], set_regs);
- IOR_HARD_REG_SET (block_uses[b], used_regs);
- }
-
- if (insn == basic_block_head[b])
- {
- outside_block = 1;
- }
- }
- for (;;)
- {
- int something_changed = 0;
-
- for (b = n_basic_blocks - 1; b >= 0; b--)
- {
- int_list_ptr psucc;
- HARD_REG_SET tmp;
-
- CLEAR_HARD_REG_SET (live_at_end[b]);
- for (psucc = s_succs[b]; psucc; psucc = psucc->next)
- IOR_HARD_REG_SET (live_at_end[b],
- live_at_start[INT_LIST_VAL (psucc)]);
- COPY_HARD_REG_SET (tmp, live_at_end[b]);
- AND_COMPL_HARD_REG_SET (tmp, block_sets[b]);
- IOR_HARD_REG_SET (tmp, block_uses[b]);
- GO_IF_HARD_REG_EQUAL (tmp, live_at_start[b], win);
- COPY_HARD_REG_SET (live_at_start[b], tmp);
- something_changed = 1;
-
- win:
- ;
- }
- if (! something_changed)
- break;
- }
- for (b = 0; b < n_basic_blocks; b++)
- {
- int i;
- CLEAR_REG_SET (basic_block_live_at_start[b]);
- for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
- if (TEST_HARD_REG_BIT (live_at_start[b], i))
- SET_REGNO_REG_SET (basic_block_live_at_start[b], i);
- }
- for (insn = last; insn; insn = PREV_INSN (insn))
- {
- enum rtx_code code = GET_CODE (insn);
-
- /* Start with fresh live info at the end of every basic block. */
- if (b > 0 && basic_block_end[b - 1] == insn)
- {
- b--;
- COPY_HARD_REG_SET (live_regs, live_at_end[b]);
- }
-
- if (GET_RTX_CLASS (code) == 'i')
- calc_reg_usage (insn, 1);
- }
-
- free (s_preds);
- free (s_succs);
- free (num_preds);
- free (num_succs);
- free (block_sets);
- free (block_uses);
- free (live_at_end);
- free (live_at_start);
-}
-
/* This array holds values which are equivalent to a hard register
during reload_cse_regs. Each array element is an EXPR_LIST of
values. Each time a hard register is set, we set the corresponding
@@ -8736,10 +9107,9 @@ reload_cse_simplify_operands (insn)
rtx insn;
{
#ifdef REGISTER_CONSTRAINTS
- int insn_code_number, n_operands, n_alternatives;
int i,j;
- char *constraints[MAX_RECOG_OPERANDS];
+ const char *constraints[MAX_RECOG_OPERANDS];
/* Vector recording how bad an alternative is. */
int *alternative_reject;
@@ -8754,41 +9124,33 @@ reload_cse_simplify_operands (insn)
int *alternative_order;
rtx reg = gen_rtx_REG (VOIDmode, -1);
- /* Find out some information about this insn. */
- insn_code_number = recog_memoized (insn);
- /* We don't modify asm instructions. */
- if (insn_code_number < 0)
- return 0;
+ extract_insn (insn);
- n_operands = insn_n_operands[insn_code_number];
- n_alternatives = insn_n_alternatives[insn_code_number];
-
- if (n_alternatives == 0 || n_operands == 0)
+ if (recog_n_alternatives == 0 || recog_n_operands == 0)
return 0;
- insn_extract (insn);
/* Figure out which alternative currently matches. */
- if (! constrain_operands (insn_code_number, 1))
+ if (! constrain_operands (1))
fatal_insn_not_found (insn);
- alternative_reject = (int *) alloca (n_alternatives * sizeof (int));
- alternative_nregs = (int *) alloca (n_alternatives * sizeof (int));
- alternative_order = (int *) alloca (n_alternatives * sizeof (int));
- bzero ((char *)alternative_reject, n_alternatives * sizeof (int));
- bzero ((char *)alternative_nregs, n_alternatives * sizeof (int));
+ alternative_reject = (int *) alloca (recog_n_alternatives * sizeof (int));
+ alternative_nregs = (int *) alloca (recog_n_alternatives * sizeof (int));
+ alternative_order = (int *) alloca (recog_n_alternatives * sizeof (int));
+ bzero ((char *)alternative_reject, recog_n_alternatives * sizeof (int));
+ bzero ((char *)alternative_nregs, recog_n_alternatives * sizeof (int));
- for (i = 0; i < n_operands; i++)
+ for (i = 0; i < recog_n_operands; i++)
{
enum machine_mode mode;
int regno;
- char *p;
+ const char *p;
- op_alt_regno[i] = (int *) alloca (n_alternatives * sizeof (int));
- for (j = 0; j < n_alternatives; j++)
+ op_alt_regno[i] = (int *) alloca (recog_n_alternatives * sizeof (int));
+ for (j = 0; j < recog_n_alternatives; j++)
op_alt_regno[i][j] = -1;
- p = constraints[i] = insn_operand_constraint[insn_code_number][i];
- mode = insn_operand_mode[insn_code_number][i];
+ p = constraints[i] = recog_constraints[i];
+ mode = recog_operand_mode[i];
/* Add the reject values for each alternative given by the constraints
for this operand. */
@@ -8855,7 +9217,7 @@ reload_cse_simplify_operands (insn)
default:
class
- = reg_class_subunion[(int) class][(int) REG_CLASS_FROM_LETTER (c)];
+ = reg_class_subunion[(int) class][(int) REG_CLASS_FROM_LETTER ((unsigned char)c)];
break;
case ',': case '\0':
@@ -8883,21 +9245,21 @@ reload_cse_simplify_operands (insn)
/* Record all alternatives which are better or equal to the currently
matching one in the alternative_order array. */
- for (i = j = 0; i < n_alternatives; i++)
+ for (i = j = 0; i < recog_n_alternatives; i++)
if (alternative_reject[i] <= alternative_reject[which_alternative])
alternative_order[j++] = i;
- n_alternatives = j;
+ recog_n_alternatives = j;
/* Sort it. Given a small number of alternatives, a dumb algorithm
won't hurt too much. */
- for (i = 0; i < n_alternatives - 1; i++)
+ for (i = 0; i < recog_n_alternatives - 1; i++)
{
int best = i;
int best_reject = alternative_reject[alternative_order[i]];
int best_nregs = alternative_nregs[alternative_order[i]];
int tmp;
- for (j = i + 1; j < n_alternatives; j++)
+ for (j = i + 1; j < recog_n_alternatives; j++)
{
int this_reject = alternative_reject[alternative_order[j]];
int this_nregs = alternative_nregs[alternative_order[j]];
@@ -8923,9 +9285,9 @@ reload_cse_simplify_operands (insn)
/* Pop back to the real obstacks while changing the insn. */
pop_obstacks ();
- for (i = 0; i < n_operands; i++)
+ for (i = 0; i < recog_n_operands; i++)
{
- enum machine_mode mode = insn_operand_mode[insn_code_number][i];
+ enum machine_mode mode = recog_operand_mode[i];
if (op_alt_regno[i][j] == -1)
continue;
@@ -8933,10 +9295,10 @@ reload_cse_simplify_operands (insn)
gen_rtx_REG (mode, op_alt_regno[i][j]), 1);
}
- for (i = insn_n_dups[insn_code_number] - 1; i >= 0; i--)
+ for (i = recog_n_dups - 1; i >= 0; i--)
{
int op = recog_dup_num[i];
- enum machine_mode mode = insn_operand_mode[insn_code_number][op];
+ enum machine_mode mode = recog_operand_mode[op];
if (op_alt_regno[op][j] == -1)
continue;
@@ -9140,7 +9502,10 @@ struct reg_use { rtx insn, *usep; };
register (which is first among these we have seen since we scan backwards),
OFFSET contains the constant offset that is added to the register in
all encountered uses, and USE_RUID indicates the first encountered, i.e.
- last, of these uses. */
+ last, of these uses.
+ STORE_RUID is always meaningful if we only want to use a value in a
+ register in a different place: it denotes the next insn in the insn
+ stream (i.e. the last ecountered) that sets or clobbers the register. */
static struct
{
struct reg_use reg_use[RELOAD_COMBINE_MAX_USES];
@@ -9155,6 +9520,9 @@ static struct
and the store_ruid / use_ruid fields in reg_state. */
static int reload_combine_ruid;
+#define LABEL_LIVE(LABEL) \
+ (label_live[CODE_LABEL_NUMBER (LABEL) - min_labelno])
+
static void
reload_combine ()
{
@@ -9162,11 +9530,13 @@ reload_combine ()
int first_index_reg = 1, last_index_reg = 0;
int i;
int last_label_ruid;
+ int min_labelno, n_labels;
+ HARD_REG_SET ever_live_at_start, *label_live;
/* If reg+reg can be used in offsetable memory adresses, the main chunk of
reload has already used it where appropriate, so there is no use in
trying to generate it now. */
- if (double_reg_address_ok && reload_address_index_reg_class != NO_REGS)
+ if (double_reg_address_ok && INDEX_REG_CLASS != NO_REGS)
return;
/* To avoid wasting too much time later searching for an index register,
@@ -9184,17 +9554,37 @@ reload_combine ()
if (first_index_reg > last_index_reg)
return;
+ /* Set up LABEL_LIVE and EVER_LIVE_AT_START. The register lifetime
+ information is a bit fuzzy immediately after reload, but it's
+ still good enough to determine which registers are live at a jump
+ destination. */
+ min_labelno = get_first_label_num ();
+ n_labels = max_label_num () - min_labelno;
+ label_live = (HARD_REG_SET *) xmalloc (n_labels * sizeof (HARD_REG_SET));
+ CLEAR_HARD_REG_SET (ever_live_at_start);
+ for (i = n_basic_blocks - 1; i >= 0; i--)
+ {
+ insn = BLOCK_HEAD (i);
+ if (GET_CODE (insn) == CODE_LABEL)
+ {
+ HARD_REG_SET live;
+
+ REG_SET_TO_HARD_REG_SET (live, BASIC_BLOCK (i)->global_live_at_start);
+ compute_use_by_pseudos (&live, BASIC_BLOCK (i)->global_live_at_start);
+ COPY_HARD_REG_SET (LABEL_LIVE (insn), live);
+ IOR_HARD_REG_SET (ever_live_at_start, live);
+ }
+ }
+
/* Initialize last_label_ruid, reload_combine_ruid and reg_state. */
last_label_ruid = reload_combine_ruid = 0;
for (i = FIRST_PSEUDO_REGISTER - 1; i >= 0; --i)
{
+ reg_state[i].store_ruid = reload_combine_ruid;
if (fixed_regs[i])
reg_state[i].use_index = -1;
else
- {
- reg_state[i].use_index = RELOAD_COMBINE_MAX_USES;
- reg_state[i].store_ruid = reload_combine_ruid;
- }
+ reg_state[i].use_index = RELOAD_COMBINE_MAX_USES;
}
for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
@@ -9206,6 +9596,11 @@ reload_combine ()
is and then later disable any optimization that would cross it. */
if (GET_CODE (insn) == CODE_LABEL)
last_label_ruid = reload_combine_ruid;
+ if (GET_CODE (insn) == BARRIER)
+ {
+ for (i = FIRST_PSEUDO_REGISTER - 1; i >= 0; --i)
+ reg_state[i].use_index = RELOAD_COMBINE_MAX_USES;
+ }
if (GET_RTX_CLASS (GET_CODE (insn)) != 'i')
continue;
reload_combine_ruid++;
@@ -9276,10 +9671,14 @@ reload_combine ()
}
}
}
+ /* Check that PREV_SET is indeed (set (REGX) (CONST_INT)) and that
+ (REGY), i.e. BASE, is not clobbered before the last use we'll
+ create. */
if (prev_set
&& GET_CODE (SET_SRC (prev_set)) == CONST_INT
&& rtx_equal_p (SET_DEST (prev_set), reg)
&& reg_state[regno].use_index >= 0
+ && reg_state[REGNO (base)].store_ruid <= reg_state[regno].use_ruid
&& reg_sum)
{
int i;
@@ -9356,13 +9755,19 @@ reload_combine ()
reg_state[regno].use_index = -1;
}
}
- if (GET_CODE (insn) == JUMP_INSN)
+ if (GET_CODE (insn) == JUMP_INSN && GET_CODE (PATTERN (insn)) != RETURN)
{
/* Non-spill registers might be used at the call destination in
some unknown fashion, so we have to mark the unknown use. */
+ HARD_REG_SET *live;
+ if ((condjump_p (insn) || condjump_in_parallel_p (insn))
+ && JUMP_LABEL (insn))
+ live = &LABEL_LIVE (JUMP_LABEL (insn));
+ else
+ live = &ever_live_at_start;
for (i = FIRST_PSEUDO_REGISTER - 1; i >= 0; --i)
{
- if (! TEST_HARD_REG_BIT (used_spill_regs, i))
+ if (TEST_HARD_REG_BIT (*live, i))
reg_state[i].use_index = -1;
}
}
@@ -9371,15 +9776,20 @@ reload_combine ()
{
if (REG_NOTE_KIND (note) == REG_INC
&& GET_CODE (XEXP (note, 0)) == REG)
- reg_state[REGNO (XEXP (note, 0))].use_index = -1;
+ {
+ int regno = REGNO (XEXP (note, 0));
+
+ reg_state[regno].store_ruid = reload_combine_ruid;
+ reg_state[regno].use_index = -1;
+ }
}
}
+ free (label_live);
}
/* Check if DST is a register or a subreg of a register; if it is,
update reg_state[regno].store_ruid and reg_state[regno].use_index
- accordingly. Called via note_stores from reload_combine.
- The second argument, SET, is ignored. */
+ accordingly. Called via note_stores from reload_combine. */
static void
reload_combine_note_store (dst, set)
rtx dst, set;
@@ -9396,13 +9806,25 @@ reload_combine_note_store (dst, set)
if (GET_CODE (dst) != REG)
return;
regno += REGNO (dst);
+
/* note_stores might have stripped a STRICT_LOW_PART, so we have to be
- careful with registers / register parts that are not full words. */
- if (size < UNITS_PER_WORD)
- reg_state[regno].use_index = -1;
+ careful with registers / register parts that are not full words.
+
+ Similarly for ZERO_EXTRACT and SIGN_EXTRACT. */
+ if (GET_CODE (set) != SET
+ || GET_CODE (SET_DEST (set)) == ZERO_EXTRACT
+ || GET_CODE (SET_DEST (set)) == SIGN_EXTRACT
+ || GET_CODE (SET_DEST (set)) == STRICT_LOW_PART)
+ {
+ for (i = (size - 1) / UNITS_PER_WORD + regno; i >= regno; i--)
+ {
+ reg_state[i].use_index = -1;
+ reg_state[i].store_ruid = reload_combine_ruid;
+ }
+ }
else
{
- for (i = size / UNITS_PER_WORD - 1 + regno; i >= regno; i--)
+ for (i = (size - 1) / UNITS_PER_WORD + regno; i >= regno; i--)
{
reg_state[i].store_ruid = reload_combine_ruid;
reg_state[i].use_index = RELOAD_COMBINE_MAX_USES;
@@ -9626,7 +10048,6 @@ reload_cse_move2add (first)
&& XEXP (SET_SRC (set), 0) == reg
&& GET_CODE (XEXP (SET_SRC (set), 1)) == CONST_INT)
{
- rtx src2 = SET_SRC (set);
rtx src3 = XEXP (SET_SRC (set), 1);
rtx new_src = GEN_INT (INTVAL (src3)
- INTVAL (reg_offset[regno]));
@@ -9714,7 +10135,10 @@ move2add_note_store (dst, set)
regno += REGNO (dst);
- if (HARD_REGNO_NREGS (regno, mode) == 1 && GET_CODE (set) == SET)
+ if (HARD_REGNO_NREGS (regno, mode) == 1 && GET_CODE (set) == SET
+ && GET_CODE (SET_DEST (set)) != ZERO_EXTRACT
+ && GET_CODE (SET_DEST (set)) != SIGN_EXTRACT
+ && GET_CODE (SET_DEST (set)) != STRICT_LOW_PART)
{
rtx src = SET_SRC (set);
@@ -9764,3 +10188,33 @@ move2add_note_store (dst, set)
}
}
}
+
+#ifdef AUTO_INC_DEC
+static void
+add_auto_inc_notes (insn, x)
+ rtx insn;
+ rtx x;
+{
+ enum rtx_code code = GET_CODE (x);
+ char *fmt;
+ int i, j;
+
+ if (code == MEM && auto_inc_p (XEXP (x, 0)))
+ {
+ REG_NOTES (insn)
+ = gen_rtx_EXPR_LIST (REG_INC, XEXP (XEXP (x, 0), 0), REG_NOTES (insn));
+ return;
+ }
+
+ /* Scan all the operand sub-expressions. */
+ fmt = GET_RTX_FORMAT (code);
+ for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
+ {
+ if (fmt[i] == 'e')
+ add_auto_inc_notes (insn, XEXP (x, i));
+ else if (fmt[i] == 'E')
+ for (j = XVECLEN (x, i) - 1; j >= 0; j--)
+ add_auto_inc_notes (insn, XVECEXP (x, i, j));
+ }
+}
+#endif
diff --git a/gcc/reorg.c b/gcc/reorg.c
index 71c1cf2c918..c06ce23d3c7 100644
--- a/gcc/reorg.c
+++ b/gcc/reorg.c
@@ -1,5 +1,5 @@
/* Perform instruction reorganizations for delay slot filling.
- Copyright (C) 1992, 93, 94, 95, 96, 97, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1992, 93-98, 1999 Free Software Foundation, Inc.
Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu).
Hacked by Michael Tiemann (tiemann@cygnus.com).
@@ -61,6 +61,10 @@ Boston, MA 02111-1307, USA. */
we can hoist insns from the fall-through path for forward branches or
steal insns from the target of backward branches.
+ The TMS320C3x and C4x have three branch delay slots. When the three
+ slots are filled, the branch penalty is zero. Most insns can fill the
+ delay slots except jump insns.
+
Three techniques for filling delay slots have been implemented so far:
(1) `fill_simple_delay_slots' is the simplest, most efficient way
@@ -130,12 +134,7 @@ Boston, MA 02111-1307, USA. */
#include "output.h"
#include "obstack.h"
#include "insn-attr.h"
-
-/* Import list of registers used as spill regs from reload. */
-extern HARD_REG_SET used_spill_regs;
-
-/* Import highest label used in function at end of reload. */
-extern int max_label_num_after_reload;
+#include "resource.h"
#ifdef DELAY_SLOTS
@@ -165,58 +164,9 @@ static rtx *unfilled_firstobj;
#define unfilled_slots_next \
((rtx *) obstack_next_free (&unfilled_slots_obstack))
-/* This structure is used to indicate which hardware resources are set or
- needed by insns so far. */
-
-struct resources
-{
- char memory; /* Insn sets or needs a memory location. */
- char unch_memory; /* Insn sets of needs a "unchanging" MEM. */
- char volatil; /* Insn sets or needs a volatile memory loc. */
- char cc; /* Insn sets or needs the condition codes. */
- HARD_REG_SET regs; /* Which registers are set or needed. */
-};
-
-/* Macro to clear all resources. */
-#define CLEAR_RESOURCE(RES) \
- do { (RES)->memory = (RES)->unch_memory = (RES)->volatil = (RES)->cc = 0; \
- CLEAR_HARD_REG_SET ((RES)->regs); } while (0)
-
-/* Indicates what resources are required at the beginning of the epilogue. */
-static struct resources start_of_epilogue_needs;
-
-/* Indicates what resources are required at function end. */
-static struct resources end_of_function_needs;
-
/* Points to the label before the end of the function. */
static rtx end_of_function_label;
-/* This structure is used to record liveness information at the targets or
- fallthrough insns of branches. We will most likely need the information
- at targets again, so save them in a hash table rather than recomputing them
- each time. */
-
-struct target_info
-{
- int uid; /* INSN_UID of target. */
- struct target_info *next; /* Next info for same hash bucket. */
- HARD_REG_SET live_regs; /* Registers live at target. */
- int block; /* Basic block number containing target. */
- int bb_tick; /* Generation count of basic block info. */
-};
-
-#define TARGET_HASH_PRIME 257
-
-/* Define the hash table itself. */
-static struct target_info **target_hash_table;
-
-/* For each basic block, we maintain a generation number of its basic
- block info, which is updated each time we move an insn from the
- target of a jump. This is the generation number indexed by block
- number. */
-
-static int *bb_ticks;
-
/* Mapping between INSN_UID's and position in the code since INSN_UID's do
not always monotonically increase. */
static int *uid_to_ruid;
@@ -224,25 +174,26 @@ static int *uid_to_ruid;
/* Highest valid index in `uid_to_ruid'. */
static int max_uid;
-static void mark_referenced_resources PROTO((rtx, struct resources *, int));
-static void mark_set_resources PROTO((rtx, struct resources *, int, int));
-static int stop_search_p PROTO((rtx, int));
-static int resource_conflicts_p PROTO((struct resources *,
- struct resources *));
-static int insn_references_resource_p PROTO((rtx, struct resources *, int));
-static int insn_sets_resource_p PROTO((rtx, struct resources *, int));
-static rtx find_end_label PROTO((void));
-static rtx emit_delay_sequence PROTO((rtx, rtx, int));
-static rtx add_to_delay_list PROTO((rtx, rtx));
-static rtx delete_from_delay_slot PROTO((rtx));
-static void delete_scheduled_jump PROTO((rtx));
-static void note_delay_statistics PROTO((int, int));
-static rtx optimize_skip PROTO((rtx));
-static int get_jump_flags PROTO((rtx, rtx));
-static int rare_destination PROTO((rtx));
-static int mostly_true_jump PROTO((rtx, rtx));
-static rtx get_branch_condition PROTO((rtx, rtx));
-static int condition_dominates_p PROTO((rtx, rtx));
+static int stop_search_p PROTO((rtx, int));
+static int resource_conflicts_p PROTO((struct resources *,
+ struct resources *));
+static int insn_references_resource_p PROTO((rtx, struct resources *, int));
+static int insn_sets_resource_p PROTO((rtx, struct resources *, int));
+static rtx find_end_label PROTO((void));
+static rtx emit_delay_sequence PROTO((rtx, rtx, int));
+static rtx add_to_delay_list PROTO((rtx, rtx));
+static rtx delete_from_delay_slot PROTO((rtx));
+static void delete_scheduled_jump PROTO((rtx));
+static void note_delay_statistics PROTO((int, int));
+static rtx optimize_skip PROTO((rtx));
+static int get_jump_flags PROTO((rtx, rtx));
+static int rare_destination PROTO((rtx));
+static int mostly_true_jump PROTO((rtx, rtx));
+static rtx get_branch_condition PROTO((rtx, rtx));
+static int condition_dominates_p PROTO((rtx, rtx));
+static int redirect_with_delay_slots_safe_p PROTO ((rtx, rtx, rtx));
+static int redirect_with_delay_list_safe_p PROTO ((rtx, rtx, rtx));
+static int check_annul_list_true_false PROTO ((int, rtx));
static rtx steal_delay_list_from_target PROTO((rtx, rtx, rtx, rtx,
struct resources *,
struct resources *,
@@ -253,442 +204,20 @@ static rtx steal_delay_list_from_fallthrough PROTO((rtx, rtx, rtx, rtx,
struct resources *,
struct resources *,
int, int *, int *));
-static void try_merge_delay_insns PROTO((rtx, rtx));
-static rtx redundant_insn PROTO((rtx, rtx, rtx));
-static int own_thread_p PROTO((rtx, rtx, int));
-static int find_basic_block PROTO((rtx));
-static void update_block PROTO((rtx, rtx));
-static int reorg_redirect_jump PROTO((rtx, rtx));
-static void update_reg_dead_notes PROTO((rtx, rtx));
-static void fix_reg_dead_note PROTO((rtx, rtx));
-static void update_reg_unused_notes PROTO((rtx, rtx));
-static void update_live_status PROTO((rtx, rtx));
-static rtx next_insn_no_annul PROTO((rtx));
-static rtx find_dead_or_set_registers PROTO ((rtx, struct resources *, rtx *,
- int, struct resources,
- struct resources));
-static void mark_target_live_regs PROTO((rtx, struct resources *));
-static void fill_simple_delay_slots PROTO((int));
-static rtx fill_slots_from_thread PROTO((rtx, rtx, rtx, rtx, int, int,
- int, int, int *, rtx));
-static void fill_eager_delay_slots PROTO((void));
-static void relax_delay_slots PROTO((rtx));
-static void make_return_insns PROTO((rtx));
-static int redirect_with_delay_slots_safe_p PROTO ((rtx, rtx, rtx));
-static int redirect_with_delay_list_safe_p PROTO ((rtx, rtx, rtx));
-
-/* Given X, some rtl, and RES, a pointer to a `struct resource', mark
- which resources are references by the insn. If INCLUDE_DELAYED_EFFECTS
- is TRUE, resources used by the called routine will be included for
- CALL_INSNs. */
-
-static void
-mark_referenced_resources (x, res, include_delayed_effects)
- register rtx x;
- register struct resources *res;
- register int include_delayed_effects;
-{
- register enum rtx_code code = GET_CODE (x);
- register int i, j;
- register char *format_ptr;
-
- /* Handle leaf items for which we set resource flags. Also, special-case
- CALL, SET and CLOBBER operators. */
- switch (code)
- {
- case CONST:
- case CONST_INT:
- case CONST_DOUBLE:
- case PC:
- case SYMBOL_REF:
- case LABEL_REF:
- return;
-
- case SUBREG:
- if (GET_CODE (SUBREG_REG (x)) != REG)
- mark_referenced_resources (SUBREG_REG (x), res, 0);
- else
- {
- int regno = REGNO (SUBREG_REG (x)) + SUBREG_WORD (x);
- int last_regno = regno + HARD_REGNO_NREGS (regno, GET_MODE (x));
- for (i = regno; i < last_regno; i++)
- SET_HARD_REG_BIT (res->regs, i);
- }
- return;
-
- case REG:
- for (i = 0; i < HARD_REGNO_NREGS (REGNO (x), GET_MODE (x)); i++)
- SET_HARD_REG_BIT (res->regs, REGNO (x) + i);
- return;
-
- case MEM:
- /* If this memory shouldn't change, it really isn't referencing
- memory. */
- if (RTX_UNCHANGING_P (x))
- res->unch_memory = 1;
- else
- res->memory = 1;
- res->volatil = MEM_VOLATILE_P (x);
-
- /* Mark registers used to access memory. */
- mark_referenced_resources (XEXP (x, 0), res, 0);
- return;
-
- case CC0:
- res->cc = 1;
- return;
-
- case UNSPEC_VOLATILE:
- case ASM_INPUT:
- /* Traditional asm's are always volatile. */
- res->volatil = 1;
- return;
-
- case TRAP_IF:
- res->volatil = 1;
- break;
-
- case ASM_OPERANDS:
- res->volatil = MEM_VOLATILE_P (x);
-
- /* For all ASM_OPERANDS, we must traverse the vector of input operands.
- We can not just fall through here since then we would be confused
- by the ASM_INPUT rtx inside ASM_OPERANDS, which do not indicate
- traditional asms unlike their normal usage. */
-
- for (i = 0; i < ASM_OPERANDS_INPUT_LENGTH (x); i++)
- mark_referenced_resources (ASM_OPERANDS_INPUT (x, i), res, 0);
- return;
-
- case CALL:
- /* The first operand will be a (MEM (xxx)) but doesn't really reference
- memory. The second operand may be referenced, though. */
- mark_referenced_resources (XEXP (XEXP (x, 0), 0), res, 0);
- mark_referenced_resources (XEXP (x, 1), res, 0);
- return;
-
- case SET:
- /* Usually, the first operand of SET is set, not referenced. But
- registers used to access memory are referenced. SET_DEST is
- also referenced if it is a ZERO_EXTRACT or SIGN_EXTRACT. */
-
- mark_referenced_resources (SET_SRC (x), res, 0);
-
- x = SET_DEST (x);
- if (GET_CODE (x) == SIGN_EXTRACT || GET_CODE (x) == ZERO_EXTRACT)
- mark_referenced_resources (x, res, 0);
- else if (GET_CODE (x) == SUBREG)
- x = SUBREG_REG (x);
- if (GET_CODE (x) == MEM)
- mark_referenced_resources (XEXP (x, 0), res, 0);
- return;
-
- case CLOBBER:
- return;
-
- case CALL_INSN:
- if (include_delayed_effects)
- {
- /* A CALL references memory, the frame pointer if it exists, the
- stack pointer, any global registers and any registers given in
- USE insns immediately in front of the CALL.
-
- However, we may have moved some of the parameter loading insns
- into the delay slot of this CALL. If so, the USE's for them
- don't count and should be skipped. */
- rtx insn = PREV_INSN (x);
- rtx sequence = 0;
- int seq_size = 0;
- rtx next = NEXT_INSN (x);
- int i;
-
- /* If we are part of a delay slot sequence, point at the SEQUENCE. */
- if (NEXT_INSN (insn) != x)
- {
- next = NEXT_INSN (NEXT_INSN (insn));
- sequence = PATTERN (NEXT_INSN (insn));
- seq_size = XVECLEN (sequence, 0);
- if (GET_CODE (sequence) != SEQUENCE)
- abort ();
- }
-
- res->memory = 1;
- SET_HARD_REG_BIT (res->regs, STACK_POINTER_REGNUM);
- if (frame_pointer_needed)
- {
- SET_HARD_REG_BIT (res->regs, FRAME_POINTER_REGNUM);
-#if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
- SET_HARD_REG_BIT (res->regs, HARD_FRAME_POINTER_REGNUM);
-#endif
- }
-
- for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
- if (global_regs[i])
- SET_HARD_REG_BIT (res->regs, i);
-
- /* Check for a NOTE_INSN_SETJMP. If it exists, then we must
- assume that this call can need any register.
-
- This is done to be more conservative about how we handle setjmp.
- We assume that they both use and set all registers. Using all
- registers ensures that a register will not be considered dead
- just because it crosses a setjmp call. A register should be
- considered dead only if the setjmp call returns non-zero. */
- if (next && GET_CODE (next) == NOTE
- && NOTE_LINE_NUMBER (next) == NOTE_INSN_SETJMP)
- SET_HARD_REG_SET (res->regs);
-
- {
- rtx link;
-
- for (link = CALL_INSN_FUNCTION_USAGE (x);
- link;
- link = XEXP (link, 1))
- if (GET_CODE (XEXP (link, 0)) == USE)
- {
- for (i = 1; i < seq_size; i++)
- {
- rtx slot_pat = PATTERN (XVECEXP (sequence, 0, i));
- if (GET_CODE (slot_pat) == SET
- && rtx_equal_p (SET_DEST (slot_pat),
- SET_DEST (XEXP (link, 0))))
- break;
- }
- if (i >= seq_size)
- mark_referenced_resources (SET_DEST (XEXP (link, 0)),
- res, 0);
- }
- }
- }
-
- /* ... fall through to other INSN processing ... */
-
- case INSN:
- case JUMP_INSN:
-
-#ifdef INSN_REFERENCES_ARE_DELAYED
- if (! include_delayed_effects
- && INSN_REFERENCES_ARE_DELAYED (x))
- return;
-#endif
-
- /* No special processing, just speed up. */
- mark_referenced_resources (PATTERN (x), res, include_delayed_effects);
- return;
-
- default:
- break;
- }
-
- /* Process each sub-expression and flag what it needs. */
- format_ptr = GET_RTX_FORMAT (code);
- for (i = 0; i < GET_RTX_LENGTH (code); i++)
- switch (*format_ptr++)
- {
- case 'e':
- mark_referenced_resources (XEXP (x, i), res, include_delayed_effects);
- break;
-
- case 'E':
- for (j = 0; j < XVECLEN (x, i); j++)
- mark_referenced_resources (XVECEXP (x, i, j), res,
- include_delayed_effects);
- break;
- }
-}
-
-/* Given X, a part of an insn, and a pointer to a `struct resource',
- RES, indicate which resources are modified by the insn. If
- INCLUDE_DELAYED_EFFECTS is nonzero, also mark resources potentially
- set by the called routine.
-
- If IN_DEST is nonzero, it means we are inside a SET. Otherwise,
- objects are being referenced instead of set.
-
- We never mark the insn as modifying the condition code unless it explicitly
- SETs CC0 even though this is not totally correct. The reason for this is
- that we require a SET of CC0 to immediately precede the reference to CC0.
- So if some other insn sets CC0 as a side-effect, we know it cannot affect
- our computation and thus may be placed in a delay slot. */
-
-static void
-mark_set_resources (x, res, in_dest, include_delayed_effects)
- register rtx x;
- register struct resources *res;
- int in_dest;
- int include_delayed_effects;
-{
- register enum rtx_code code;
- register int i, j;
- register char *format_ptr;
-
- restart:
-
- code = GET_CODE (x);
-
- switch (code)
- {
- case NOTE:
- case BARRIER:
- case CODE_LABEL:
- case USE:
- case CONST_INT:
- case CONST_DOUBLE:
- case LABEL_REF:
- case SYMBOL_REF:
- case CONST:
- case PC:
- /* These don't set any resources. */
- return;
-
- case CC0:
- if (in_dest)
- res->cc = 1;
- return;
-
- case CALL_INSN:
- /* Called routine modifies the condition code, memory, any registers
- that aren't saved across calls, global registers and anything
- explicitly CLOBBERed immediately after the CALL_INSN. */
-
- if (include_delayed_effects)
- {
- rtx next = NEXT_INSN (x);
- rtx prev = PREV_INSN (x);
- rtx link;
-
- res->cc = res->memory = 1;
- for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
- if (call_used_regs[i] || global_regs[i])
- SET_HARD_REG_BIT (res->regs, i);
-
- /* If X is part of a delay slot sequence, then NEXT should be
- the first insn after the sequence. */
- if (NEXT_INSN (prev) != x)
- next = NEXT_INSN (NEXT_INSN (prev));
-
- for (link = CALL_INSN_FUNCTION_USAGE (x);
- link; link = XEXP (link, 1))
- if (GET_CODE (XEXP (link, 0)) == CLOBBER)
- mark_set_resources (SET_DEST (XEXP (link, 0)), res, 1, 0);
-
- /* Check for a NOTE_INSN_SETJMP. If it exists, then we must
- assume that this call can clobber any register. */
- if (next && GET_CODE (next) == NOTE
- && NOTE_LINE_NUMBER (next) == NOTE_INSN_SETJMP)
- SET_HARD_REG_SET (res->regs);
- }
-
- /* ... and also what its RTL says it modifies, if anything. */
-
- case JUMP_INSN:
- case INSN:
-
- /* An insn consisting of just a CLOBBER (or USE) is just for flow
- and doesn't actually do anything, so we ignore it. */
-
-#ifdef INSN_SETS_ARE_DELAYED
- if (! include_delayed_effects
- && INSN_SETS_ARE_DELAYED (x))
- return;
-#endif
-
- x = PATTERN (x);
- if (GET_CODE (x) != USE && GET_CODE (x) != CLOBBER)
- goto restart;
- return;
-
- case SET:
- /* If the source of a SET is a CALL, this is actually done by
- the called routine. So only include it if we are to include the
- effects of the calling routine. */
-
- mark_set_resources (SET_DEST (x), res,
- (include_delayed_effects
- || GET_CODE (SET_SRC (x)) != CALL),
- 0);
-
- mark_set_resources (SET_SRC (x), res, 0, 0);
- return;
-
- case CLOBBER:
- mark_set_resources (XEXP (x, 0), res, 1, 0);
- return;
-
- case SEQUENCE:
- for (i = 0; i < XVECLEN (x, 0); i++)
- if (! (INSN_ANNULLED_BRANCH_P (XVECEXP (x, 0, 0))
- && INSN_FROM_TARGET_P (XVECEXP (x, 0, i))))
- mark_set_resources (XVECEXP (x, 0, i), res, 0,
- include_delayed_effects);
- return;
-
- case POST_INC:
- case PRE_INC:
- case POST_DEC:
- case PRE_DEC:
- mark_set_resources (XEXP (x, 0), res, 1, 0);
- return;
-
- case ZERO_EXTRACT:
- mark_set_resources (XEXP (x, 0), res, in_dest, 0);
- mark_set_resources (XEXP (x, 1), res, 0, 0);
- mark_set_resources (XEXP (x, 2), res, 0, 0);
- return;
-
- case MEM:
- if (in_dest)
- {
- res->memory = 1;
- res->unch_memory = RTX_UNCHANGING_P (x);
- res->volatil = MEM_VOLATILE_P (x);
- }
-
- mark_set_resources (XEXP (x, 0), res, 0, 0);
- return;
-
- case SUBREG:
- if (in_dest)
- {
- if (GET_CODE (SUBREG_REG (x)) != REG)
- mark_set_resources (SUBREG_REG (x), res,
- in_dest, include_delayed_effects);
- else
- {
- int regno = REGNO (SUBREG_REG (x)) + SUBREG_WORD (x);
- int last_regno = regno + HARD_REGNO_NREGS (regno, GET_MODE (x));
- for (i = regno; i < last_regno; i++)
- SET_HARD_REG_BIT (res->regs, i);
- }
- }
- return;
-
- case REG:
- if (in_dest)
- for (i = 0; i < HARD_REGNO_NREGS (REGNO (x), GET_MODE (x)); i++)
- SET_HARD_REG_BIT (res->regs, REGNO (x) + i);
- return;
-
- default:
- break;
- }
-
- /* Process each sub-expression and flag what it needs. */
- format_ptr = GET_RTX_FORMAT (code);
- for (i = 0; i < GET_RTX_LENGTH (code); i++)
- switch (*format_ptr++)
- {
- case 'e':
- mark_set_resources (XEXP (x, i), res, in_dest, include_delayed_effects);
- break;
-
- case 'E':
- for (j = 0; j < XVECLEN (x, i); j++)
- mark_set_resources (XVECEXP (x, i, j), res, in_dest,
- include_delayed_effects);
- break;
- }
-}
+static void try_merge_delay_insns PROTO((rtx, rtx));
+static rtx redundant_insn PROTO((rtx, rtx, rtx));
+static int own_thread_p PROTO((rtx, rtx, int));
+static void update_block PROTO((rtx, rtx));
+static int reorg_redirect_jump PROTO((rtx, rtx));
+static void update_reg_dead_notes PROTO((rtx, rtx));
+static void fix_reg_dead_note PROTO((rtx, rtx));
+static void update_reg_unused_notes PROTO((rtx, rtx));
+static void fill_simple_delay_slots PROTO((int));
+static rtx fill_slots_from_thread PROTO((rtx, rtx, rtx, rtx, int, int,
+ int, int, int *, rtx));
+static void fill_eager_delay_slots PROTO((void));
+static void relax_delay_slots PROTO((rtx));
+static void make_return_insns PROTO((rtx));
/* Return TRUE if this insn should stop the search for insn to fill delay
slots. LABELS_P indicates that labels should terminate the search.
@@ -988,16 +517,7 @@ add_to_delay_list (insn, delay_list)
if (delay_list == 0)
{
- struct target_info *tinfo;
-
- for (tinfo = target_hash_table[INSN_UID (insn) % TARGET_HASH_PRIME];
- tinfo; tinfo = tinfo->next)
- if (tinfo->uid == INSN_UID (insn))
- break;
-
- if (tinfo)
- tinfo->block = -1;
-
+ clear_hashed_info_for_insn (insn);
return gen_rtx_INSN_LIST (VOIDmode, insn, NULL_RTX);
}
@@ -1008,8 +528,8 @@ add_to_delay_list (insn, delay_list)
return delay_list;
}
-/* Delete INSN from the delay slot of the insn that it is in. This may
- produce an insn without anything in its delay slots. */
+/* Delete INSN from the delay slot of the insn that it is in, which may
+ produce an insn with no delay slots. Return the new insn. */
static rtx
delete_from_delay_slot (insn)
@@ -1379,7 +899,7 @@ mostly_true_jump (jump_insn, condition)
always gives a correct answer. */
if (flag_branch_probabilities)
{
- rtx note = find_reg_note (jump_insn, REG_BR_PROB, 0);;
+ rtx note = find_reg_note (jump_insn, REG_BR_PROB, 0);
if (note)
{
int prob = XINT (note, 0);
@@ -1648,6 +1168,7 @@ check_annul_list_true_false (annul_true_p, delay_list)
return 0;
}
}
+
return 1;
}
@@ -1691,8 +1212,9 @@ steal_delay_list_from_target (insn, condition, seq, delay_list,
int total_slots_filled = *pslots_filled;
rtx new_delay_list = 0;
int must_annul = *pannul_p;
- int i;
int used_annul = 0;
+ int i;
+ struct resources cc_set;
/* We can't do anything if there are more delay slots in SEQ than we
can handle, or if we don't know that it will be a taken branch.
@@ -1702,7 +1224,23 @@ steal_delay_list_from_target (insn, condition, seq, delay_list,
Also, exit if the branch has more than one set, since then it is computing
other results that can't be ignored, e.g. the HPPA mov&branch instruction.
??? It may be possible to move other sets into INSN in addition to
- moving the instructions in the delay slots. */
+ moving the instructions in the delay slots.
+
+ We can not steal the delay list if one of the instructions in the
+ current delay_list modifies the condition codes and the jump in the
+ sequence is a conditional jump. We can not do this because we can
+ not change the direction of the jump because the condition codes
+ will effect the direction of the jump in the sequence. */
+
+ CLEAR_RESOURCE (&cc_set);
+ for (temp = delay_list; temp; temp = XEXP (temp, 1))
+ {
+ rtx trial = XEXP (temp, 0);
+
+ mark_set_resources (trial, &cc_set, 0, 1);
+ if (insn_references_resource_p (XVECEXP (seq , 0, 0), &cc_set, 0))
+ return delay_list;
+ }
if (XVECLEN (seq, 0) - 1 > slots_remaining
|| ! condition_dominates_p (condition, XVECEXP (seq, 0, 0))
@@ -2306,41 +1844,6 @@ own_thread_p (thread, label, allow_fallthrough)
return 1;
}
-/* Find the number of the basic block that starts closest to INSN. Return -1
- if we couldn't find such a basic block. */
-
-static int
-find_basic_block (insn)
- rtx insn;
-{
- int i;
-
- /* Scan backwards to the previous BARRIER. Then see if we can find a
- label that starts a basic block. Return the basic block number. */
-
- for (insn = prev_nonnote_insn (insn);
- insn && GET_CODE (insn) != BARRIER;
- insn = prev_nonnote_insn (insn))
- ;
-
- /* The start of the function is basic block zero. */
- if (insn == 0)
- return 0;
-
- /* See if any of the upcoming CODE_LABELs start a basic block. If we reach
- anything other than a CODE_LABEL or note, we can't find this code. */
- for (insn = next_nonnote_insn (insn);
- insn && GET_CODE (insn) == CODE_LABEL;
- insn = next_nonnote_insn (insn))
- {
- for (i = 0; i < n_basic_blocks; i++)
- if (insn == basic_block_head[i])
- return i;
- }
-
- return -1;
-}
-
/* Called when INSN is being moved from a location near the target of a jump.
We leave a marker of the form (use (INSN)) immediately in front
of WHERE for mark_target_live_regs. These markers will be deleted when
@@ -2355,8 +1858,6 @@ update_block (insn, where)
rtx insn;
rtx where;
{
- int b;
-
/* Ignore if this was in a delay slot and it came from the target of
a branch. */
if (INSN_FROM_TARGET_P (insn))
@@ -2367,9 +1868,7 @@ update_block (insn, where)
/* INSN might be making a value live in a block where it didn't use to
be. So recompute liveness information for this block. */
- b = find_basic_block (insn);
- if (b != -1)
- bb_ticks[b]++;
+ incr_ticks_for_insn (insn);
}
/* Similar to REDIRECT_JUMP except that we update the BB_TICKS entry for
@@ -2380,11 +1879,7 @@ reorg_redirect_jump (jump, nlabel)
rtx jump;
rtx nlabel;
{
- int b = find_basic_block (jump);
-
- if (b != -1)
- bb_ticks[b]++;
-
+ incr_ticks_for_insn (jump);
return redirect_jump (jump, nlabel);
}
@@ -2484,557 +1979,6 @@ update_reg_unused_notes (insn, redundant_insn)
}
}
-/* Marks registers possibly live at the current place being scanned by
- mark_target_live_regs. Used only by next two function. */
-
-static HARD_REG_SET current_live_regs;
-
-/* Marks registers for which we have seen a REG_DEAD note but no assignment.
- Also only used by the next two functions. */
-
-static HARD_REG_SET pending_dead_regs;
-
-/* Utility function called from mark_target_live_regs via note_stores.
- It deadens any CLOBBERed registers and livens any SET registers. */
-
-static void
-update_live_status (dest, x)
- rtx dest;
- rtx x;
-{
- int first_regno, last_regno;
- int i;
-
- if (GET_CODE (dest) != REG
- && (GET_CODE (dest) != SUBREG || GET_CODE (SUBREG_REG (dest)) != REG))
- return;
-
- if (GET_CODE (dest) == SUBREG)
- first_regno = REGNO (SUBREG_REG (dest)) + SUBREG_WORD (dest);
- else
- first_regno = REGNO (dest);
-
- last_regno = first_regno + HARD_REGNO_NREGS (first_regno, GET_MODE (dest));
-
- if (GET_CODE (x) == CLOBBER)
- for (i = first_regno; i < last_regno; i++)
- CLEAR_HARD_REG_BIT (current_live_regs, i);
- else
- for (i = first_regno; i < last_regno; i++)
- {
- SET_HARD_REG_BIT (current_live_regs, i);
- CLEAR_HARD_REG_BIT (pending_dead_regs, i);
- }
-}
-
-/* Similar to next_insn, but ignores insns in the delay slots of
- an annulled branch. */
-
-static rtx
-next_insn_no_annul (insn)
- rtx insn;
-{
- if (insn)
- {
- /* If INSN is an annulled branch, skip any insns from the target
- of the branch. */
- if (INSN_ANNULLED_BRANCH_P (insn)
- && NEXT_INSN (PREV_INSN (insn)) != insn)
- while (INSN_FROM_TARGET_P (NEXT_INSN (insn)))
- insn = NEXT_INSN (insn);
-
- insn = NEXT_INSN (insn);
- if (insn && GET_CODE (insn) == INSN
- && GET_CODE (PATTERN (insn)) == SEQUENCE)
- insn = XVECEXP (PATTERN (insn), 0, 0);
- }
-
- return insn;
-}
-
-/* A subroutine of mark_target_live_regs. Search forward from TARGET
- looking for registers that are set before they are used. These are dead.
- Stop after passing a few conditional jumps, and/or a small
- number of unconditional branches. */
-
-static rtx
-find_dead_or_set_registers (target, res, jump_target, jump_count, set, needed)
- rtx target;
- struct resources *res;
- rtx *jump_target;
- int jump_count;
- struct resources set, needed;
-{
- HARD_REG_SET scratch;
- rtx insn, next;
- rtx jump_insn = 0;
- int i;
-
- for (insn = target; insn; insn = next)
- {
- rtx this_jump_insn = insn;
-
- next = NEXT_INSN (insn);
- switch (GET_CODE (insn))
- {
- case CODE_LABEL:
- /* After a label, any pending dead registers that weren't yet
- used can be made dead. */
- AND_COMPL_HARD_REG_SET (pending_dead_regs, needed.regs);
- AND_COMPL_HARD_REG_SET (res->regs, pending_dead_regs);
- CLEAR_HARD_REG_SET (pending_dead_regs);
-
- if (CODE_LABEL_NUMBER (insn) < max_label_num_after_reload)
- {
- /* All spill registers are dead at a label, so kill all of the
- ones that aren't needed also. */
- COPY_HARD_REG_SET (scratch, used_spill_regs);
- AND_COMPL_HARD_REG_SET (scratch, needed.regs);
- AND_COMPL_HARD_REG_SET (res->regs, scratch);
- }
- continue;
-
- case BARRIER:
- case NOTE:
- continue;
-
- case INSN:
- if (GET_CODE (PATTERN (insn)) == USE)
- {
- /* If INSN is a USE made by update_block, we care about the
- underlying insn. Any registers set by the underlying insn
- are live since the insn is being done somewhere else. */
- if (GET_RTX_CLASS (GET_CODE (XEXP (PATTERN (insn), 0))) == 'i')
- mark_set_resources (XEXP (PATTERN (insn), 0), res, 0, 1);
-
- /* All other USE insns are to be ignored. */
- continue;
- }
- else if (GET_CODE (PATTERN (insn)) == CLOBBER)
- continue;
- else if (GET_CODE (PATTERN (insn)) == SEQUENCE)
- {
- /* An unconditional jump can be used to fill the delay slot
- of a call, so search for a JUMP_INSN in any position. */
- for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
- {
- this_jump_insn = XVECEXP (PATTERN (insn), 0, i);
- if (GET_CODE (this_jump_insn) == JUMP_INSN)
- break;
- }
- }
-
- default:
- break;
- }
-
- if (GET_CODE (this_jump_insn) == JUMP_INSN)
- {
- if (jump_count++ < 10)
- {
- if (simplejump_p (this_jump_insn)
- || GET_CODE (PATTERN (this_jump_insn)) == RETURN)
- {
- next = JUMP_LABEL (this_jump_insn);
- if (jump_insn == 0)
- {
- jump_insn = insn;
- if (jump_target)
- *jump_target = JUMP_LABEL (this_jump_insn);
- }
- }
- else if (condjump_p (this_jump_insn)
- || condjump_in_parallel_p (this_jump_insn))
- {
- struct resources target_set, target_res;
- struct resources fallthrough_res;
-
- /* We can handle conditional branches here by following
- both paths, and then IOR the results of the two paths
- together, which will give us registers that are dead
- on both paths. Since this is expensive, we give it
- a much higher cost than unconditional branches. The
- cost was chosen so that we will follow at most 1
- conditional branch. */
-
- jump_count += 4;
- if (jump_count >= 10)
- break;
-
- mark_referenced_resources (insn, &needed, 1);
-
- /* For an annulled branch, mark_set_resources ignores slots
- filled by instructions from the target. This is correct
- if the branch is not taken. Since we are following both
- paths from the branch, we must also compute correct info
- if the branch is taken. We do this by inverting all of
- the INSN_FROM_TARGET_P bits, calling mark_set_resources,
- and then inverting the INSN_FROM_TARGET_P bits again. */
-
- if (GET_CODE (PATTERN (insn)) == SEQUENCE
- && INSN_ANNULLED_BRANCH_P (this_jump_insn))
- {
- for (i = 1; i < XVECLEN (PATTERN (insn), 0); i++)
- INSN_FROM_TARGET_P (XVECEXP (PATTERN (insn), 0, i))
- = ! INSN_FROM_TARGET_P (XVECEXP (PATTERN (insn), 0, i));
-
- target_set = set;
- mark_set_resources (insn, &target_set, 0, 1);
-
- for (i = 1; i < XVECLEN (PATTERN (insn), 0); i++)
- INSN_FROM_TARGET_P (XVECEXP (PATTERN (insn), 0, i))
- = ! INSN_FROM_TARGET_P (XVECEXP (PATTERN (insn), 0, i));
-
- mark_set_resources (insn, &set, 0, 1);
- }
- else
- {
- mark_set_resources (insn, &set, 0, 1);
- target_set = set;
- }
-
- target_res = *res;
- COPY_HARD_REG_SET (scratch, target_set.regs);
- AND_COMPL_HARD_REG_SET (scratch, needed.regs);
- AND_COMPL_HARD_REG_SET (target_res.regs, scratch);
-
- fallthrough_res = *res;
- COPY_HARD_REG_SET (scratch, set.regs);
- AND_COMPL_HARD_REG_SET (scratch, needed.regs);
- AND_COMPL_HARD_REG_SET (fallthrough_res.regs, scratch);
-
- find_dead_or_set_registers (JUMP_LABEL (this_jump_insn),
- &target_res, 0, jump_count,
- target_set, needed);
- find_dead_or_set_registers (next,
- &fallthrough_res, 0, jump_count,
- set, needed);
- IOR_HARD_REG_SET (fallthrough_res.regs, target_res.regs);
- AND_HARD_REG_SET (res->regs, fallthrough_res.regs);
- break;
- }
- else
- break;
- }
- else
- {
- /* Don't try this optimization if we expired our jump count
- above, since that would mean there may be an infinite loop
- in the function being compiled. */
- jump_insn = 0;
- break;
- }
- }
-
- mark_referenced_resources (insn, &needed, 1);
- mark_set_resources (insn, &set, 0, 1);
-
- COPY_HARD_REG_SET (scratch, set.regs);
- AND_COMPL_HARD_REG_SET (scratch, needed.regs);
- AND_COMPL_HARD_REG_SET (res->regs, scratch);
- }
-
- return jump_insn;
-}
-
-/* Set the resources that are live at TARGET.
-
- If TARGET is zero, we refer to the end of the current function and can
- return our precomputed value.
-
- Otherwise, we try to find out what is live by consulting the basic block
- information. This is tricky, because we must consider the actions of
- reload and jump optimization, which occur after the basic block information
- has been computed.
-
- Accordingly, we proceed as follows::
-
- We find the previous BARRIER and look at all immediately following labels
- (with no intervening active insns) to see if any of them start a basic
- block. If we hit the start of the function first, we use block 0.
-
- Once we have found a basic block and a corresponding first insns, we can
- accurately compute the live status from basic_block_live_regs and
- reg_renumber. (By starting at a label following a BARRIER, we are immune
- to actions taken by reload and jump.) Then we scan all insns between
- that point and our target. For each CLOBBER (or for call-clobbered regs
- when we pass a CALL_INSN), mark the appropriate registers are dead. For
- a SET, mark them as live.
-
- We have to be careful when using REG_DEAD notes because they are not
- updated by such things as find_equiv_reg. So keep track of registers
- marked as dead that haven't been assigned to, and mark them dead at the
- next CODE_LABEL since reload and jump won't propagate values across labels.
-
- If we cannot find the start of a basic block (should be a very rare
- case, if it can happen at all), mark everything as potentially live.
-
- Next, scan forward from TARGET looking for things set or clobbered
- before they are used. These are not live.
-
- Because we can be called many times on the same target, save our results
- in a hash table indexed by INSN_UID. */
-
-static void
-mark_target_live_regs (target, res)
- rtx target;
- struct resources *res;
-{
- int b = -1;
- int i;
- struct target_info *tinfo;
- rtx insn;
- rtx jump_insn = 0;
- rtx jump_target;
- HARD_REG_SET scratch;
- struct resources set, needed;
-
- /* Handle end of function. */
- if (target == 0)
- {
- *res = end_of_function_needs;
- return;
- }
-
- /* We have to assume memory is needed, but the CC isn't. */
- res->memory = 1;
- res->volatil = res->unch_memory = 0;
- res->cc = 0;
-
- /* See if we have computed this value already. */
- for (tinfo = target_hash_table[INSN_UID (target) % TARGET_HASH_PRIME];
- tinfo; tinfo = tinfo->next)
- if (tinfo->uid == INSN_UID (target))
- break;
-
- /* Start by getting the basic block number. If we have saved information,
- we can get it from there unless the insn at the start of the basic block
- has been deleted. */
- if (tinfo && tinfo->block != -1
- && ! INSN_DELETED_P (basic_block_head[tinfo->block]))
- b = tinfo->block;
-
- if (b == -1)
- b = find_basic_block (target);
-
- if (tinfo)
- {
- /* If the information is up-to-date, use it. Otherwise, we will
- update it below. */
- if (b == tinfo->block && b != -1 && tinfo->bb_tick == bb_ticks[b])
- {
- COPY_HARD_REG_SET (res->regs, tinfo->live_regs);
- return;
- }
- }
- else
- {
- /* Allocate a place to put our results and chain it into the
- hash table. */
- tinfo = (struct target_info *) oballoc (sizeof (struct target_info));
- tinfo->uid = INSN_UID (target);
- tinfo->block = b;
- tinfo->next = target_hash_table[INSN_UID (target) % TARGET_HASH_PRIME];
- target_hash_table[INSN_UID (target) % TARGET_HASH_PRIME] = tinfo;
- }
-
- CLEAR_HARD_REG_SET (pending_dead_regs);
-
- /* If we found a basic block, get the live registers from it and update
- them with anything set or killed between its start and the insn before
- TARGET. Otherwise, we must assume everything is live. */
- if (b != -1)
- {
- regset regs_live = basic_block_live_at_start[b];
- int j;
- int regno;
- rtx start_insn, stop_insn;
-
- /* Compute hard regs live at start of block -- this is the real hard regs
- marked live, plus live pseudo regs that have been renumbered to
- hard regs. */
-
- REG_SET_TO_HARD_REG_SET (current_live_regs, regs_live);
-
- EXECUTE_IF_SET_IN_REG_SET
- (regs_live, FIRST_PSEUDO_REGISTER, i,
- {
- if ((regno = reg_renumber[i]) >= 0)
- for (j = regno;
- j < regno + HARD_REGNO_NREGS (regno,
- PSEUDO_REGNO_MODE (i));
- j++)
- SET_HARD_REG_BIT (current_live_regs, j);
- });
-
- /* Get starting and ending insn, handling the case where each might
- be a SEQUENCE. */
- start_insn = (b == 0 ? get_insns () : basic_block_head[b]);
- stop_insn = target;
-
- if (GET_CODE (start_insn) == INSN
- && GET_CODE (PATTERN (start_insn)) == SEQUENCE)
- start_insn = XVECEXP (PATTERN (start_insn), 0, 0);
-
- if (GET_CODE (stop_insn) == INSN
- && GET_CODE (PATTERN (stop_insn)) == SEQUENCE)
- stop_insn = next_insn (PREV_INSN (stop_insn));
-
- for (insn = start_insn; insn != stop_insn;
- insn = next_insn_no_annul (insn))
- {
- rtx link;
- rtx real_insn = insn;
-
- /* If this insn is from the target of a branch, it isn't going to
- be used in the sequel. If it is used in both cases, this
- test will not be true. */
- if (INSN_FROM_TARGET_P (insn))
- continue;
-
- /* If this insn is a USE made by update_block, we care about the
- underlying insn. */
- if (GET_CODE (insn) == INSN && GET_CODE (PATTERN (insn)) == USE
- && GET_RTX_CLASS (GET_CODE (XEXP (PATTERN (insn), 0))) == 'i')
- real_insn = XEXP (PATTERN (insn), 0);
-
- if (GET_CODE (real_insn) == CALL_INSN)
- {
- /* CALL clobbers all call-used regs that aren't fixed except
- sp, ap, and fp. Do this before setting the result of the
- call live. */
- for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
- if (call_used_regs[i]
- && i != STACK_POINTER_REGNUM && i != FRAME_POINTER_REGNUM
- && i != ARG_POINTER_REGNUM
-#if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM
- && i != HARD_FRAME_POINTER_REGNUM
-#endif
-#if ARG_POINTER_REGNUM != FRAME_POINTER_REGNUM
- && ! (i == ARG_POINTER_REGNUM && fixed_regs[i])
-#endif
-#ifdef PIC_OFFSET_TABLE_REGNUM
- && ! (i == PIC_OFFSET_TABLE_REGNUM && flag_pic)
-#endif
- )
- CLEAR_HARD_REG_BIT (current_live_regs, i);
-
- /* A CALL_INSN sets any global register live, since it may
- have been modified by the call. */
- for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
- if (global_regs[i])
- SET_HARD_REG_BIT (current_live_regs, i);
- }
-
- /* Mark anything killed in an insn to be deadened at the next
- label. Ignore USE insns; the only REG_DEAD notes will be for
- parameters. But they might be early. A CALL_INSN will usually
- clobber registers used for parameters. It isn't worth bothering
- with the unlikely case when it won't. */
- if ((GET_CODE (real_insn) == INSN
- && GET_CODE (PATTERN (real_insn)) != USE
- && GET_CODE (PATTERN (real_insn)) != CLOBBER)
- || GET_CODE (real_insn) == JUMP_INSN
- || GET_CODE (real_insn) == CALL_INSN)
- {
- for (link = REG_NOTES (real_insn); link; link = XEXP (link, 1))
- if (REG_NOTE_KIND (link) == REG_DEAD
- && GET_CODE (XEXP (link, 0)) == REG
- && REGNO (XEXP (link, 0)) < FIRST_PSEUDO_REGISTER)
- {
- int first_regno = REGNO (XEXP (link, 0));
- int last_regno
- = (first_regno
- + HARD_REGNO_NREGS (first_regno,
- GET_MODE (XEXP (link, 0))));
-
- for (i = first_regno; i < last_regno; i++)
- SET_HARD_REG_BIT (pending_dead_regs, i);
- }
-
- note_stores (PATTERN (real_insn), update_live_status);
-
- /* If any registers were unused after this insn, kill them.
- These notes will always be accurate. */
- for (link = REG_NOTES (real_insn); link; link = XEXP (link, 1))
- if (REG_NOTE_KIND (link) == REG_UNUSED
- && GET_CODE (XEXP (link, 0)) == REG
- && REGNO (XEXP (link, 0)) < FIRST_PSEUDO_REGISTER)
- {
- int first_regno = REGNO (XEXP (link, 0));
- int last_regno
- = (first_regno
- + HARD_REGNO_NREGS (first_regno,
- GET_MODE (XEXP (link, 0))));
-
- for (i = first_regno; i < last_regno; i++)
- CLEAR_HARD_REG_BIT (current_live_regs, i);
- }
- }
-
- else if (GET_CODE (real_insn) == CODE_LABEL)
- {
- /* A label clobbers the pending dead registers since neither
- reload nor jump will propagate a value across a label. */
- AND_COMPL_HARD_REG_SET (current_live_regs, pending_dead_regs);
- CLEAR_HARD_REG_SET (pending_dead_regs);
- }
-
- /* The beginning of the epilogue corresponds to the end of the
- RTL chain when there are no epilogue insns. Certain resources
- are implicitly required at that point. */
- else if (GET_CODE (real_insn) == NOTE
- && NOTE_LINE_NUMBER (real_insn) == NOTE_INSN_EPILOGUE_BEG)
- IOR_HARD_REG_SET (current_live_regs, start_of_epilogue_needs.regs);
- }
-
- COPY_HARD_REG_SET (res->regs, current_live_regs);
- tinfo->block = b;
- tinfo->bb_tick = bb_ticks[b];
- }
- else
- /* We didn't find the start of a basic block. Assume everything
- in use. This should happen only extremely rarely. */
- SET_HARD_REG_SET (res->regs);
-
- CLEAR_RESOURCE (&set);
- CLEAR_RESOURCE (&needed);
-
- jump_insn = find_dead_or_set_registers (target, res, &jump_target, 0,
- set, needed);
-
- /* If we hit an unconditional branch, we have another way of finding out
- what is live: we can see what is live at the branch target and include
- anything used but not set before the branch. The only things that are
- live are those that are live using the above test and the test below. */
-
- if (jump_insn)
- {
- struct resources new_resources;
- rtx stop_insn = next_active_insn (jump_insn);
-
- mark_target_live_regs (next_active_insn (jump_target), &new_resources);
- CLEAR_RESOURCE (&set);
- CLEAR_RESOURCE (&needed);
-
- /* Include JUMP_INSN in the needed registers. */
- for (insn = target; insn != stop_insn; insn = next_active_insn (insn))
- {
- mark_referenced_resources (insn, &needed, 1);
-
- COPY_HARD_REG_SET (scratch, needed.regs);
- AND_COMPL_HARD_REG_SET (scratch, set.regs);
- IOR_HARD_REG_SET (new_resources.regs, scratch);
-
- mark_set_resources (insn, &set, 0, 1);
- }
-
- AND_HARD_REG_SET (res->regs, new_resources.regs);
- }
-
- COPY_HARD_REG_SET (tinfo->live_regs, res->regs);
-}
-
/* Scan a function looking for insns that need a delay slot and find insns to
put into the delay slot.
@@ -3189,7 +2133,7 @@ fill_simple_delay_slots (non_jumps_p)
#ifdef HAVE_cc0
/* Can't separate set of cc0 from its use. */
&& ! (reg_mentioned_p (cc0_rtx, pat)
- && ! sets_cc0_p (cc0_rtx, pat))
+ && ! sets_cc0_p (pat))
#endif
)
{
@@ -3307,9 +2251,11 @@ fill_simple_delay_slots (non_jumps_p)
break;
else if (JUMP_LABEL (trial_delay) != target)
{
- mark_target_live_regs
- (next_active_insn (JUMP_LABEL (trial_delay)),
- &needed_at_jump);
+ rtx ninsn =
+ next_active_insn (JUMP_LABEL (trial_delay));
+
+ mark_target_live_regs (get_insns (), ninsn,
+ &needed_at_jump);
needed.memory |= needed_at_jump.memory;
needed.unch_memory |= needed_at_jump.unch_memory;
IOR_HARD_REG_SET (needed.regs, needed_at_jump.regs);
@@ -3452,7 +2398,8 @@ fill_simple_delay_slots (non_jumps_p)
SET_HARD_REG_BIT (needed.regs, HARD_FRAME_POINTER_REGNUM);
#endif
#ifdef EXIT_IGNORE_STACK
- if (! EXIT_IGNORE_STACK)
+ if (! EXIT_IGNORE_STACK
+ || current_function_sp_is_unchanging)
#endif
SET_HARD_REG_BIT (needed.regs, STACK_POINTER_REGNUM);
}
@@ -3494,7 +2441,7 @@ fill_simple_delay_slots (non_jumps_p)
current_function_epilogue_delay_list
= gen_rtx_INSN_LIST (VOIDmode, trial,
current_function_epilogue_delay_list);
- mark_referenced_resources (trial, &end_of_function_needs, 1);
+ mark_end_of_function_resources (trial, 1);
update_block (trial, trial);
delete_insn (trial);
@@ -3576,7 +2523,7 @@ fill_slots_from_thread (insn, condition, thread, opposite_thread, likely,
if (condition == const_true_rtx)
CLEAR_RESOURCE (&opposite_needed);
else
- mark_target_live_regs (opposite_thread, &opposite_needed);
+ mark_target_live_regs (get_insns (), opposite_thread, &opposite_needed);
/* If the insn at THREAD can be split, do it here to avoid having to
update THREAD and NEW_THREAD if it is done in the loop below. Also
@@ -3729,8 +2676,6 @@ fill_slots_from_thread (insn, condition, thread, opposite_thread, likely,
delay_list = add_to_delay_list (temp, delay_list);
- mark_set_resources (trial, &opposite_needed, 0, 1);
-
if (slots_to_fill == ++(*pslots_filled))
{
/* Even though we have filled all the slots, we
@@ -3808,9 +2753,7 @@ fill_slots_from_thread (insn, condition, thread, opposite_thread, likely,
{
/* If this is the `true' thread, we will want to follow the jump,
so we can only do this if we have taken everything up to here. */
- if (thread_if_true && trial == new_thread
- && ! insn_references_resource_p (XVECEXP (PATTERN (trial), 0, 0),
- &opposite_needed, 0))
+ if (thread_if_true && trial == new_thread)
delay_list
= steal_delay_list_from_target (insn, condition, PATTERN (trial),
delay_list, &set, &needed,
@@ -3871,8 +2814,7 @@ fill_slots_from_thread (insn, condition, thread, opposite_thread, likely,
insn);
if (recog_memoized (ninsn) < 0
- || (insn_extract (ninsn),
- ! constrain_operands (INSN_CODE (ninsn), 1)))
+ || (extract_insn (ninsn), ! constrain_operands (1)))
{
delete_insn (ninsn);
return 0;
@@ -4160,7 +3102,7 @@ relax_delay_slots (first)
&& (other = prev_active_insn (insn)) != 0
&& (condjump_p (other) || condjump_in_parallel_p (other))
&& no_labels_between_p (other, insn)
- && 0 < mostly_true_jump (other,
+ && 0 > mostly_true_jump (other,
get_branch_condition (other,
JUMP_LABEL (other))))
{
@@ -4197,6 +3139,40 @@ relax_delay_slots (first)
continue;
}
+ /* See if we have a RETURN insn with a filled delay slot followed
+ by a RETURN insn with an unfilled a delay slot. If so, we can delete
+ the first RETURN (but not it's delay insn). This gives the same
+ effect in fewer instructions.
+
+ Only do so if optimizing for size since this results in slower, but
+ smaller code. */
+ if (optimize_size
+ && GET_CODE (PATTERN (delay_insn)) == RETURN
+ && next
+ && GET_CODE (next) == JUMP_INSN
+ && GET_CODE (PATTERN (next)) == RETURN)
+ {
+ int i;
+
+ /* Delete the RETURN and just execute the delay list insns.
+
+ We do this by deleting the INSN containing the SEQUENCE, then
+ re-emitting the insns separately, and then deleting the RETURN.
+ This allows the count of the jump target to be properly
+ decremented. */
+
+ /* Clear the from target bit, since these insns are no longer
+ in delay slots. */
+ for (i = 0; i < XVECLEN (pat, 0); i++)
+ INSN_FROM_TARGET_P (XVECEXP (pat, 0, i)) = 0;
+
+ trial = PREV_INSN (insn);
+ delete_insn (insn);
+ emit_insn_after (pat, trial);
+ delete_scheduled_jump (delay_insn);
+ continue;
+ }
+
/* Now look only at the cases where we have a filled JUMP_INSN. */
if (GET_CODE (XVECEXP (PATTERN (insn), 0, 0)) != JUMP_INSN
|| ! (condjump_p (XVECEXP (PATTERN (insn), 0, 0))
@@ -4547,7 +3523,7 @@ dbr_schedule (first, file)
epilogue_insn = insn;
}
- uid_to_ruid = (int *) alloca ((max_uid + 1) * sizeof (int *));
+ uid_to_ruid = (int *) alloca ((max_uid + 1) * sizeof (int));
for (i = 0, insn = first; insn; i++, insn = NEXT_INSN (insn))
uid_to_ruid[INSN_UID (insn)] = i;
@@ -4583,79 +3559,11 @@ dbr_schedule (first, file)
redirect_jump (insn, target);
}
- /* Indicate what resources are required to be valid at the end of the current
- function. The condition code never is and memory always is. If the
- frame pointer is needed, it is and so is the stack pointer unless
- EXIT_IGNORE_STACK is non-zero. If the frame pointer is not needed, the
- stack pointer is. Registers used to return the function value are
- needed. Registers holding global variables are needed. */
-
- end_of_function_needs.cc = 0;
- end_of_function_needs.memory = 1;
- end_of_function_needs.unch_memory = 0;
- CLEAR_HARD_REG_SET (end_of_function_needs.regs);
-
- if (frame_pointer_needed)
- {
- SET_HARD_REG_BIT (end_of_function_needs.regs, FRAME_POINTER_REGNUM);
-#if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM
- SET_HARD_REG_BIT (end_of_function_needs.regs, HARD_FRAME_POINTER_REGNUM);
-#endif
-#ifdef EXIT_IGNORE_STACK
- if (! EXIT_IGNORE_STACK)
-#endif
- SET_HARD_REG_BIT (end_of_function_needs.regs, STACK_POINTER_REGNUM);
- }
- else
- SET_HARD_REG_BIT (end_of_function_needs.regs, STACK_POINTER_REGNUM);
-
- if (current_function_return_rtx != 0)
- mark_referenced_resources (current_function_return_rtx,
- &end_of_function_needs, 1);
-
- for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
- if (global_regs[i]
-#ifdef EPILOGUE_USES
- || EPILOGUE_USES (i)
-#endif
- )
- SET_HARD_REG_BIT (end_of_function_needs.regs, i);
-
- /* The registers required to be live at the end of the function are
- represented in the flow information as being dead just prior to
- reaching the end of the function. For example, the return of a value
- might be represented by a USE of the return register immediately
- followed by an unconditional jump to the return label where the
- return label is the end of the RTL chain. The end of the RTL chain
- is then taken to mean that the return register is live.
-
- This sequence is no longer maintained when epilogue instructions are
- added to the RTL chain. To reconstruct the original meaning, the
- start of the epilogue (NOTE_INSN_EPILOGUE_BEG) is regarded as the
- point where these registers become live (start_of_epilogue_needs).
- If epilogue instructions are present, the registers set by those
- instructions won't have been processed by flow. Thus, those
- registers are additionally required at the end of the RTL chain
- (end_of_function_needs). */
-
- start_of_epilogue_needs = end_of_function_needs;
-
- while ((epilogue_insn = next_nonnote_insn (epilogue_insn)))
- mark_set_resources (epilogue_insn, &end_of_function_needs, 0, 1);
+ init_resource_info (epilogue_insn);
/* Show we haven't computed an end-of-function label yet. */
end_of_function_label = 0;
- /* Allocate and initialize the tables used by mark_target_live_regs. */
- target_hash_table
- = (struct target_info **) alloca ((TARGET_HASH_PRIME
- * sizeof (struct target_info *)));
- bzero ((char *) target_hash_table,
- TARGET_HASH_PRIME * sizeof (struct target_info *));
-
- bb_ticks = (int *) alloca (n_basic_blocks * sizeof (int));
- bzero ((char *) bb_ticks, n_basic_blocks * sizeof (int));
-
/* Initialize the statistics for this function. */
bzero ((char *) num_insns_needing_delays, sizeof num_insns_needing_delays);
bzero ((char *) num_filled_delays, sizeof num_filled_delays);
@@ -4759,5 +3667,6 @@ dbr_schedule (first, file)
GEN_INT (pred_flags),
REG_NOTES (insn));
}
+ free_resource_info ();
}
#endif /* DELAY_SLOTS */
diff --git a/gcc/rtl.c b/gcc/rtl.c
index 63faf506ea4..a4bcb845f13 100644
--- a/gcc/rtl.c
+++ b/gcc/rtl.c
@@ -1,5 +1,5 @@
/* Allocate and read RTL for GNU C Compiler.
- Copyright (C) 1987, 1988, 1991, 1994, 1997 Free Software Foundation, Inc.
+ Copyright (C) 1987, 1988, 1991, 1994, 1997, 1998 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -124,7 +124,7 @@ unsigned char mode_wider_mode[(int) MAX_MACHINE_MODE] = {
/* Indexed by machine mode, gives mask of significant bits in mode. */
-const unsigned HOST_WIDE_INT mode_mask_array[(int) MAX_MACHINE_MODE] = {
+unsigned HOST_WIDE_INT mode_mask_array[(int) MAX_MACHINE_MODE] = {
#include "machmode.def"
};
@@ -186,7 +186,8 @@ char *note_insn_name[] = { 0 , "NOTE_INSN_DELETED",
"NOTE_INSN_DELETED_LABEL", "NOTE_INSN_FUNCTION_BEG",
"NOTE_INSN_EH_REGION_BEG", "NOTE_INSN_EH_REGION_END",
"NOTE_REPEATED_LINE_NUMBER", "NOTE_INSN_RANGE_START",
- "NOTE_INSN_RANGE_END", "NOTE_INSN_LIVE" };
+ "NOTE_INSN_RANGE_END", "NOTE_INSN_LIVE",
+ "NOTE_INSN_BASIC_BLOCK" };
char *reg_note_name[] = { "", "REG_DEAD", "REG_INC", "REG_EQUIV", "REG_WAS_0",
"REG_EQUAL", "REG_RETVAL", "REG_LIBCALL",
@@ -195,9 +196,10 @@ char *reg_note_name[] = { "", "REG_DEAD", "REG_INC", "REG_EQUIV", "REG_WAS_0",
"REG_DEP_ANTI", "REG_DEP_OUTPUT", "REG_BR_PROB",
"REG_EXEC_COUNT", "REG_NOALIAS", "REG_SAVE_AREA",
"REG_BR_PRED", "REG_EH_CONTEXT",
- "REG_FRAME_RELATED_EXPR" };
+ "REG_FRAME_RELATED_EXPR", "REG_EH_REGION",
+ "REG_EH_RETHROW" };
-static void dump_and_abort PROTO((int, int, FILE *));
+static void dump_and_abort PROTO((int, int, FILE *)) ATTRIBUTE_NORETURN;
static void read_name PROTO((char *, FILE *));
/* Allocate an rtx vector of N elements.
@@ -283,11 +285,24 @@ copy_rtx (orig)
}
copy = rtx_alloc (code);
- PUT_MODE (copy, GET_MODE (orig));
- copy->in_struct = orig->in_struct;
- copy->volatil = orig->volatil;
- copy->unchanging = orig->unchanging;
- copy->integrated = orig->integrated;
+
+ /* Copy the various flags, and other information. We assume that
+ all fields need copying, and then clear the fields that should
+ not be copied. That is the sensible default behavior, and forces
+ us to explicitly document why we are *not* copying a flag. */
+ memcpy (copy, orig, sizeof (struct rtx_def) - sizeof (rtunion));
+
+ /* We do not copy the USED flag, which is used as a mark bit during
+ walks over the RTL. */
+ copy->used = 0;
+
+ /* We do not copy JUMP, CALL, or FRAME_RELATED for INSNs. */
+ if (GET_RTX_CLASS (code) == 'i')
+ {
+ copy->jump = 0;
+ copy->call = 0;
+ copy->frame_related = 0;
+ }
format_ptr = GET_RTX_FORMAT (GET_CODE (copy));
@@ -438,6 +453,28 @@ copy_most_rtx (orig, may_share)
}
return copy;
}
+
+/* Create a new copy of an rtx. Only copy just one level. */
+rtx
+shallow_copy_rtx (orig)
+ rtx orig;
+{
+ register int i;
+ register char *format_ptr;
+ register RTX_CODE code = GET_CODE (orig);
+ register rtx copy = rtx_alloc (code);
+
+ PUT_MODE (copy, GET_MODE (orig));
+ copy->in_struct = orig->in_struct;
+ copy->volatil = orig->volatil;
+ copy->unchanging = orig->unchanging;
+ copy->integrated = orig->integrated;
+
+ for (i = 0; i < GET_RTX_LENGTH (code); i++)
+ copy->fld[i] = orig->fld[i];
+
+ return copy;
+}
/* Subroutines of read_rtx. */
@@ -864,6 +901,7 @@ init_rtl ()
for (i = (int) CCmode + 1; i < (int) MAX_MACHINE_MODE; i++)
{
mode_class[i] = MODE_CC;
+ mode_mask_array[i] = mode_mask_array[(int) CCmode];
mode_size[i] = mode_size[(int) CCmode];
mode_unit_size[i] = mode_unit_size[(int) CCmode];
mode_wider_mode[i - 1] = i;
diff --git a/gcc/rtl.def b/gcc/rtl.def
index a411ce36ea8..8977400a585 100644
--- a/gcc/rtl.def
+++ b/gcc/rtl.def
@@ -1,7 +1,7 @@
/* This file contains the definitions and documentation for the
Register Transfer Expressions (rtx's) that make up the
Register Transfer Language (rtl) used in the Back End of the GNU compiler.
- Copyright (C) 1987, 88, 92, 94, 95, 97, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1987, 88, 92, 94, 95, 97, 98, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -723,6 +723,14 @@ DEF_RTL_EXPR(PRE_INC, "pre_inc", "e", 'x')
DEF_RTL_EXPR(POST_DEC, "post_dec", "e", 'x')
DEF_RTL_EXPR(POST_INC, "post_inc", "e", 'x')
+/* These binary operations are used to represent generic address
+ side-effects in memory addresses, except for simple incrementation
+ or decrementation which use the above operations. They are
+ created automatically by the life_analysis pass in flow.c.
+ (Note that these operators are currently placeholders.) */
+DEF_RTL_EXPR(PRE_MODIFY, "pre_modify", "ee", 'x')
+DEF_RTL_EXPR(POST_MODIFY, "post_modify", "ee", 'x')
+
/* Comparison operations. The ordered comparisons exist in two
flavors, signed and unsigned. */
DEF_RTL_EXPR(NE, "ne", "ee", '<')
@@ -847,6 +855,24 @@ DEF_RTL_EXPR(RANGE_LIVE, "range_live", "bi", 'x')
eliminated by the first CSE pass. */
DEF_RTL_EXPR(CONSTANT_P_RTX, "constant_p_rtx", "e", 'x')
+/* A placeholder for a CALL_INSN which may be turned into a normal call,
+ a sibling (tail) call or tail recursion.
+
+ Immediately after RTL generation, this placeholder will be replaced
+ by the insns to perform the call, sibcall or tail recursion.
+
+ This RTX has 4 operands. The first three are lists of instructions to
+ perform the call as a normal call, sibling call and tail recursion
+ respectively. The latter two lists may be NULL, the first may never
+ be NULL.
+
+ The last operand is the tail recursion CODE_LABEL, which may be NULL if no
+ potential tail recursive calls were found.
+
+ The tail recursion label is needed so that we can clear LABEL_PRESERVE_P
+ after we select a call method. */
+DEF_RTL_EXPR(CALL_PLACEHOLDER, "call_placeholder", "uuuu", 'x')
+
/*
Local variables:
mode:c
diff --git a/gcc/rtl.h b/gcc/rtl.h
index caa1b76bd40..77e5dacc362 100644
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -1,5 +1,5 @@
/* Register Transfer Language (RTL) definitions for GNU C-Compiler
- Copyright (C) 1987, 91-97, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1987, 91-98, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -91,6 +91,7 @@ typedef union rtunion_def
addr_diff_vec_flags rt_addr_diff_vec_flags;
struct bitmap_head_def *rtbit;
union tree_node *rttree;
+ struct basic_block_def *bb;
} rtunion;
/* RTL expression ("rtx"). */
@@ -163,9 +164,11 @@ typedef struct rtx_def
In a REG, nonzero means this reg refers to the return value
of the current function. */
unsigned integrated : 1;
- /* Nonzero if this rtx is related to the call frame, either changing how
- we compute the frame address or saving and restoring registers in
- the prologue and epilogue. */
+ /* 1 in an INSN or a SET if this rtx is related to the call frame,
+ either changing how we compute the frame address or saving and
+ restoring registers in the prologue and epilogue.
+ 1 in a MEM if the MEM refers to a scalar, rather than a member of
+ an aggregate. */
unsigned frame_related : 1;
/* Used by the garbage collector. */
@@ -177,8 +180,6 @@ typedef struct rtx_def
rtunion fld[1];
} *rtx;
-#include "gansidecl.h"
-
#define NULL_RTX (rtx) 0
/* Define macros to access the `code' field of the rtx. */
@@ -347,6 +348,14 @@ typedef struct rtvec_def{
REG_FRAME_RELATED_EXPR is attached to insns that are RTX_FRAME_RELATED_P,
but are too complex for DWARF to interpret what they imply. The attached
rtx is used instead of intuition. */
+/* REG_EH_REGION is used to indicate what exception region an INSN
+ belongs in. This can be used to indicate what region a call may throw
+ to. a REGION of 0 indicates that a call cannot throw at all.
+ REG_EH_RETHROW is used to indicate what that a call is actually a
+ call to rethrow, and specifies which region the rethrow is targetting.
+ This provides a way to generate the non standard flow edges required
+ for a rethrow. */
+
#define REG_NOTES(INSN) ((INSN)->fld[6].rtx)
@@ -360,7 +369,8 @@ enum reg_note { REG_DEAD = 1, REG_INC = 2, REG_EQUIV = 3, REG_WAS_0 = 4,
REG_DEP_ANTI = 14, REG_DEP_OUTPUT = 15, REG_BR_PROB = 16,
REG_EXEC_COUNT = 17, REG_NOALIAS = 18, REG_SAVE_AREA = 19,
REG_BR_PRED = 20, REG_EH_CONTEXT = 21,
- REG_FRAME_RELATED_EXPR = 22 };
+ REG_FRAME_RELATED_EXPR = 22, REG_EH_REGION = 23,
+ REG_EH_RETHROW = 24 };
/* The base value for branch probability notes. */
#define REG_BR_PROB_BASE 10000
@@ -400,6 +410,7 @@ extern char *reg_note_name[];
#define NOTE_BLOCK_NUMBER(INSN) ((INSN)->fld[3].rtint)
#define NOTE_RANGE_INFO(INSN) ((INSN)->fld[3].rtx)
#define NOTE_LIVE_INFO(INSN) ((INSN)->fld[3].rtx)
+#define NOTE_BASIC_BLOCK(INSN) ((INSN)->fld[3].bb)
/* If the NOTE_BLOCK_NUMBER field gets a -1, it means create a new
block node for a live range block. */
@@ -465,6 +476,8 @@ extern char *reg_note_name[];
#define NOTE_INSN_RANGE_END -18
/* Record which registers are currently live. */
#define NOTE_INSN_LIVE -19
+/* Record the struct for the following basic block. */
+#define NOTE_INSN_BASIC_BLOCK -20
#if 0 /* These are not used, and I don't know what they were for. --rms. */
#define NOTE_DECL_NAME(INSN) ((INSN)->fld[3].rtstr)
@@ -567,9 +580,29 @@ extern char *note_insn_name[];
Also in an ASM_OPERANDS rtx. */
#define MEM_VOLATILE_P(RTX) ((RTX)->volatil)
-/* For a MEM rtx, 1 if it refers to a field of an aggregate. */
+/* For a MEM rtx, 1 if it refers to a field of an aggregate. If zero,
+ RTX may or may not refer to a field of an aggregate. */
#define MEM_IN_STRUCT_P(RTX) ((RTX)->in_struct)
+/* For a MEM rtx, 1 if it refers to a scalar. If zero, RTX may or may
+ not refer to a scalar.*/
+#define MEM_SCALAR_P(RTX) ((RTX)->frame_related)
+
+/* Copy the MEM_VOLATILE_P, MEM_IN_STRUCT_P, and MEM_SCALAR_P
+ attributes from RHS to LHS. */
+#define MEM_COPY_ATTRIBUTES(LHS, RHS) \
+ (MEM_VOLATILE_P (LHS) = MEM_VOLATILE_P (RHS), \
+ MEM_IN_STRUCT_P (LHS) = MEM_IN_STRUCT_P (RHS), \
+ MEM_SCALAR_P (LHS) = MEM_SCALAR_P (RHS))
+
+/* If VAL is non-zero, set MEM_IN_STRUCT_P and clear MEM_SCALAR_P in
+ RTX. Otherwise, vice versa. Use this macro only when you are
+ *sure* that you know that the MEM is in a structure, or is a
+ scalar. VAL is evaluated only once. */
+#define MEM_SET_IN_STRUCT_P(RTX, VAL) \
+ ((VAL) ? (MEM_IN_STRUCT_P (RTX) = 1, MEM_SCALAR_P (RTX) = 0) \
+ : (MEM_IN_STRUCT_P (RTX) = 0, MEM_SCALAR_P (RTX) = 1))
+
/* For a MEM rtx, the alias set. If 0, this MEM is not in any alias
set, and may alias anything. Otherwise, the MEM can only alias
MEMs in the same alias set. This value is set in a
@@ -624,9 +657,75 @@ extern char *note_insn_name[];
/* Flag in a SYMBOL_REF for machine-specific purposes. */
#define SYMBOL_REF_FLAG(RTX) ((RTX)->volatil)
+/* 1 in a SYMBOL_REF if it represents a symbol which might have to change
+ if its inlined or unrolled. */
+#define SYMBOL_REF_NEED_ADJUST(RTX) ((RTX)->in_struct)
+
/* 1 means a SYMBOL_REF has been the library function in emit_library_call. */
#define SYMBOL_REF_USED(RTX) ((RTX)->used)
+/* For an INLINE_HEADER rtx, FIRST_FUNCTION_INSN is the first insn
+ of the function that is not involved in copying parameters to
+ pseudo-registers. FIRST_PARM_INSN is the very first insn of
+ the function, including the parameter copying.
+ We keep this around in case we must splice
+ this function into the assembly code at the end of the file.
+ FIRST_LABELNO is the first label number used by the function (inclusive).
+ LAST_LABELNO is the last label used by the function (exclusive).
+ MAX_REGNUM is the largest pseudo-register used by that function.
+ FUNCTION_ARGS_SIZE is the size of the argument block in the stack.
+ POPS_ARGS is the number of bytes of input arguments popped by the function
+ STACK_SLOT_LIST is the list of stack slots.
+ FORCED_LABELS is the list of labels whose address was taken.
+ FUNCTION_FLAGS are where single-bit flags are saved.
+ OUTGOING_ARGS_SIZE is the size of the largest outgoing stack parameter list.
+ ORIGINAL_ARG_VECTOR is a vector of the original DECL_RTX values
+ for the function arguments.
+ ORIGINAL_DECL_INITIAL is a pointer to the original DECL_INITIAL for the
+ function.
+ INLINE_REGNO_REG_RTX, INLINE_REGNO_POINTER_FLAG, and
+ INLINE_REGNO_POINTER_ALIGN are pointers to the corresponding arrays.
+
+ We want this to lay down like an INSN. The PREV_INSN field
+ is always NULL. The NEXT_INSN field always points to the
+ first function insn of the function being squirreled away. */
+
+#define FIRST_FUNCTION_INSN(RTX) ((RTX)->fld[2].rtx)
+#define FIRST_PARM_INSN(RTX) ((RTX)->fld[3].rtx)
+#define FIRST_LABELNO(RTX) ((RTX)->fld[4].rtint)
+#define LAST_LABELNO(RTX) ((RTX)->fld[5].rtint)
+#define MAX_PARMREG(RTX) ((RTX)->fld[6].rtint)
+#define MAX_REGNUM(RTX) ((RTX)->fld[7].rtint)
+#define FUNCTION_ARGS_SIZE(RTX) ((RTX)->fld[8].rtint)
+#define POPS_ARGS(RTX) ((RTX)->fld[9].rtint)
+#define STACK_SLOT_LIST(RTX) ((RTX)->fld[10].rtx)
+#define FORCED_LABELS(RTX) ((RTX)->fld[11].rtx)
+#define FUNCTION_FLAGS(RTX) ((RTX)->fld[12].rtint)
+#define OUTGOING_ARGS_SIZE(RTX) ((RTX)->fld[13].rtint)
+#define ORIGINAL_ARG_VECTOR(RTX) ((RTX)->fld[14].rtvec)
+#define ORIGINAL_DECL_INITIAL(RTX) ((RTX)->fld[15].rtx)
+#define INLINE_REGNO_REG_RTX(RTX) ((RTX)->fld[16].rtvec)
+#define INLINE_REGNO_POINTER_FLAG(RTX) ((RTX)->fld[17].rtstr)
+#define INLINE_REGNO_POINTER_ALIGN(RTX) ((RTX)->fld[18].rtstr)
+#define PARMREG_STACK_LOC(RTX) ((RTX)->fld[19].rtvec)
+
+/* In FUNCTION_FLAGS we save some variables computed when emitting the code
+ for the function and which must be `or'ed into the current flag values when
+ insns from that function are being inlined. */
+
+/* These ought to be an enum, but non-ANSI compilers don't like that. */
+#define FUNCTION_FLAGS_CALLS_ALLOCA 01
+#define FUNCTION_FLAGS_CALLS_SETJMP 02
+#define FUNCTION_FLAGS_RETURNS_STRUCT 04
+#define FUNCTION_FLAGS_RETURNS_PCC_STRUCT 010
+#define FUNCTION_FLAGS_NEEDS_CONTEXT 020
+#define FUNCTION_FLAGS_HAS_NONLOCAL_LABEL 040
+#define FUNCTION_FLAGS_RETURNS_POINTER 0100
+#define FUNCTION_FLAGS_USES_CONST_POOL 0200
+#define FUNCTION_FLAGS_CALLS_LONGJMP 0400
+#define FUNCTION_FLAGS_USES_PIC_OFFSET_TABLE 01000
+#define FUNCTION_FLAGS_HAS_COMPUTED_JUMP 02000
+
/* Define a macro to look for REG_INC notes,
but save time on machines where they never exist. */
@@ -645,6 +744,22 @@ extern char *note_insn_name[];
#define AUTO_INC_DEC
#endif
+#ifndef HAVE_PRE_INCREMENT
+#define HAVE_PRE_INCREMENT 0
+#endif
+
+#ifndef HAVE_PRE_DECREMENT
+#define HAVE_PRE_DECREMENT 0
+#endif
+
+#ifndef HAVE_POST_INCREMENT
+#define HAVE_POST_INCREMENT 0
+#endif
+
+#ifndef HAVE_POST_DECREMENT
+#define HAVE_POST_DECREMENT 0
+#endif
+
/* Accessors for RANGE_INFO. */
/* For RANGE_{START,END} notes return the RANGE_START note. */
#define RANGE_INFO_NOTE_START(INSN) (XEXP (INSN, 0))
@@ -772,19 +887,6 @@ extern rtvec gen_rtvec PVPROTO((int, ...));
extern rtx read_rtx PROTO((FILE *));
#endif
-#if 0
-/* At present, don't prototype xrealloc, since all of the callers don't
- cast their pointers to char *, and all of the xrealloc's don't use
- void * yet. */
-extern char *xmalloc PROTO((size_t));
-extern char *xcalloc PROTO((size_t, size_t));
-extern char *xrealloc PROTO((void *, size_t));
-#else
-extern char *xmalloc ();
-extern char *xcalloc ();
-extern char *xrealloc ();
-#endif
-
extern char *oballoc PROTO((int));
extern char *permalloc PROTO((int));
extern rtx rtx_alloc PROTO((RTX_CODE));
@@ -792,6 +894,7 @@ extern rtvec rtvec_alloc PROTO((int));
extern rtx copy_rtx PROTO((rtx));
extern rtx copy_rtx_if_shared PROTO((rtx));
extern rtx copy_most_rtx PROTO((rtx, rtx));
+extern rtx shallow_copy_rtx PROTO((rtx));
extern rtvec gen_rtvec_v PROTO((int, rtx *));
extern rtvec gen_rtvec_vv PROTO((int, rtunion *));
extern rtx gen_reg_rtx PROTO((enum machine_mode));
@@ -839,6 +942,7 @@ extern rtx emit_insn_before PROTO((rtx, rtx));
extern rtx emit_jump_insn_before PROTO((rtx, rtx));
extern rtx emit_call_insn_before PROTO((rtx, rtx));
extern rtx emit_barrier_before PROTO((rtx));
+extern rtx emit_label_before PROTO((rtx, rtx));
extern rtx emit_note_before PROTO((int, rtx));
extern rtx emit_insn_after PROTO((rtx, rtx));
extern rtx emit_jump_insn_after PROTO((rtx, rtx));
@@ -889,7 +993,6 @@ extern rtx simplify_unary_operation PROTO((enum rtx_code, enum machine_mode, rtx
extern rtx simplify_binary_operation PROTO((enum rtx_code, enum machine_mode, rtx, rtx));
extern rtx simplify_ternary_operation PROTO((enum rtx_code, enum machine_mode, enum machine_mode, rtx, rtx, rtx));
extern rtx simplify_relational_operation PROTO((enum rtx_code, enum machine_mode, rtx, rtx));
-extern rtx nonlocal_label_rtx_list PROTO((void));
extern rtx gen_move_insn PROTO((rtx, rtx));
extern rtx gen_jump PROTO((rtx));
extern rtx gen_beq PROTO((rtx));
@@ -899,14 +1002,7 @@ extern rtx gen_mem_addressof PROTO((rtx, union tree_node *));
extern rtx eliminate_constant_term PROTO((rtx, rtx *));
extern rtx expand_complex_abs PROTO((enum machine_mode, rtx, rtx, int));
extern enum machine_mode choose_hard_reg_mode PROTO((int, int));
-extern int rtx_varies_p PROTO((rtx));
-extern int may_trap_p PROTO((rtx));
-extern int side_effects_p PROTO((rtx));
-extern int volatile_refs_p PROTO((rtx));
-extern int volatile_insn_p PROTO((rtx));
-extern void remove_note PROTO((rtx, rtx));
-extern int refers_to_regno_p PROTO((int, int, rtx, rtx *));
-extern int reg_overlap_mentioned_p PROTO((rtx, rtx));
+extern void set_unique_reg_note PROTO((rtx, enum reg_note, rtx));
/* Functions in rtlanal.c */
@@ -920,15 +1016,17 @@ extern int reg_referenced_p PROTO((rtx, rtx));
extern int reg_used_between_p PROTO((rtx, rtx, rtx));
extern int reg_referenced_between_p PROTO((rtx, rtx, rtx));
extern int reg_set_between_p PROTO((rtx, rtx, rtx));
+extern int regs_set_between_p PROTO((rtx, rtx, rtx));
extern int modified_between_p PROTO((rtx, rtx, rtx));
extern int no_labels_between_p PROTO((rtx, rtx));
+extern int no_jumps_between_p PROTO((rtx, rtx));
extern int modified_in_p PROTO((rtx, rtx));
extern int reg_set_p PROTO((rtx, rtx));
extern rtx single_set PROTO((rtx));
-extern rtx find_last_value PROTO((rtx, rtx *, rtx));
+extern int multiple_sets PROTO((rtx));
+extern rtx find_last_value PROTO((rtx, rtx *, rtx, int));
extern int refers_to_regno_p PROTO((int, int, rtx, rtx *));
extern int reg_overlap_mentioned_p PROTO((rtx, rtx));
-extern rtx find_use_as_address PROTO((rtx, rtx, HOST_WIDE_INT));
extern void note_stores PROTO((rtx, void (*)()));
extern rtx reg_set_last PROTO((rtx, rtx));
extern int rtx_equal_p PROTO((rtx, rtx));
@@ -943,12 +1041,20 @@ extern int side_effects_p PROTO((rtx));
extern int volatile_refs_p PROTO((rtx));
extern int volatile_insn_p PROTO((rtx));
extern int may_trap_p PROTO((rtx));
-extern int inequality_comparison_p PROTO((rtx));
+extern int inequality_comparisons_p PROTO ((rtx));
extern rtx replace_rtx PROTO((rtx, rtx, rtx));
extern rtx replace_regs PROTO((rtx, rtx *, int, int));
extern int computed_jump_p PROTO((rtx));
typedef int (*rtx_function) PROTO((rtx *, void *));
extern int for_each_rtx PROTO((rtx *, rtx_function, void *));
+extern rtx regno_use_in PROTO((int, rtx));
+extern int auto_inc_p PROTO((rtx));
+
+/* flow.c */
+
+extern rtx find_use_as_address PROTO((rtx, rtx, HOST_WIDE_INT));
+
+/* regclass.c */
/* Maximum number of parallel sets and clobbers in any insn in this fn.
Always at least 3, since the combiner could put that many togetherm
@@ -956,14 +1062,23 @@ extern int for_each_rtx PROTO((rtx *, rtx_function, void *));
extern int max_parallel;
+/* Free up register info memory. */
+extern void free_reg_info PROTO((void));
+
+/* recog.c */
extern int asm_noperands PROTO((rtx));
-extern char *decode_asm_operands PROTO((rtx, rtx *, rtx **, char **, enum machine_mode *));
+extern char *decode_asm_operands PROTO((rtx, rtx *, rtx **,
+ const char **,
+ enum machine_mode *));
extern enum reg_class reg_preferred_class PROTO((int));
extern enum reg_class reg_alternate_class PROTO((int));
extern rtx get_first_nonparm_insn PROTO((void));
+extern void split_block_insns PROTO((int, int));
+extern void update_flow_info PROTO((rtx, rtx, rtx, rtx));
+
/* Standard pieces of rtx, to be substituted directly into things. */
#define pc_rtx (&global_rtl.pc_val)
#define cc0_rtx (&global_rtl.cc0_val)
@@ -1131,8 +1246,12 @@ extern union tree_node *make_tree PROTO((union tree_node *, rtx));
#define STORE_FLAG_VALUE 1
#endif
+/* Nonzero after the second flow pass has completed.
+ Set to 1 or 0 by toplev.c */
+extern int flow2_completed;
+
/* Nonzero after end of reload pass.
- Set to 1 or 0 by toplev.c. */
+ Set to 1 or 0 by reload1.c. */
extern int reload_completed;
@@ -1149,30 +1268,25 @@ extern int reload_in_progress;
the same indirect address eventually. */
extern int cse_not_expected;
+/* Set to nonzero before life analysis to indicate that it is unsafe to
+ generate any new pseudo registers. */
+extern int no_new_pseudos;
+
+/* Indexed by pseudo register number, gives the rtx for that pseudo.
+ Allocated in parallel with regno_pointer_flag. */
+extern rtx *regno_reg_rtx;
+
+/* Vector indexed by regno; contain the alignment in bytes and type
+ pointed to for a register that contains a pointer, if known. */
+extern char *regno_pointer_align;
+#define REGNO_POINTER_ALIGN(REGNO) regno_pointer_align[REGNO]
+
/* Translates rtx code to tree code, for those codes needed by
REAL_ARITHMETIC. The function returns an int because the caller may not
know what `enum tree_code' means. */
extern int rtx_to_tree_code PROTO((enum rtx_code));
-/* In rtlanal.c */
-extern int reg_set_p PROTO ((rtx, rtx));
-extern int reg_mentioned_p PROTO ((rtx, rtx));
-extern int reg_referenced_p PROTO ((rtx, rtx));
-extern int reg_used_between_p PROTO ((rtx, rtx, rtx));
-extern int reg_set_p PROTO ((rtx, rtx));
-extern int reg_referenced_between_p PROTO ((rtx, rtx, rtx));
-extern int reg_set_between_p PROTO ((rtx, rtx, rtx));
-extern int rtx_unstable_p PROTO ((rtx));
-extern int rtx_addr_varies_p PROTO ((rtx));
-extern int rtx_equal_p PROTO ((rtx, rtx));
-extern int inequality_comparisons_p PROTO ((rtx));
-extern int dead_or_set_p PROTO ((rtx, rtx));
-extern int dead_or_set_regno_p PROTO ((rtx, int));
-extern int no_labels_between_p PROTO ((rtx, rtx));
-extern int modified_between_p PROTO ((rtx, rtx, rtx));
-extern int modified_in_p PROTO ((rtx, rtx));
-
/* In tree.c */
extern void obfree PROTO ((char *));
struct obstack;
@@ -1198,7 +1312,9 @@ extern void cse_end_of_basic_block PROTO ((rtx,
/* In jump.c */
extern int comparison_dominates_p PROTO ((enum rtx_code, enum rtx_code));
extern int condjump_p PROTO ((rtx));
+extern rtx condjump_label PROTO ((rtx));
extern int simplejump_p PROTO ((rtx));
+extern int returnjump_p PROTO ((rtx));
extern int sets_cc0_p PROTO ((rtx));
extern int invert_jump PROTO ((rtx, rtx));
extern int rtx_renumbered_equal_p PROTO ((rtx, rtx));
@@ -1245,6 +1361,7 @@ extern void link_cc0_insns PROTO ((rtx));
extern void add_insn PROTO ((rtx));
extern void add_insn_before PROTO ((rtx, rtx));
extern void add_insn_after PROTO ((rtx, rtx));
+extern void remove_insn PROTO ((rtx));
extern void reorder_insns_with_line_notes PROTO ((rtx, rtx, rtx));
extern void emit_insn_after_with_line_notes PROTO ((rtx, rtx, rtx));
extern enum rtx_code classify_insn PROTO ((rtx));
@@ -1288,6 +1405,7 @@ extern void print_inline_rtx PROTO ((FILE *, rtx, int));
/* In loop.c */
extern void init_loop PROTO ((void));
+extern rtx libcall_other_reg PROTO ((rtx, rtx));
#ifdef BUFSIZ
extern void loop_optimize PROTO ((rtx, FILE *, int, int));
#endif
@@ -1317,6 +1435,10 @@ extern void expand_null_return PROTO ((void));
extern void emit_jump PROTO ((rtx));
extern int preserve_subexpressions_p PROTO ((void));
+/* List (chain of EXPR_LIST) of labels heading the current handlers for
+ nonlocal gotos. */
+extern rtx nonlocal_goto_handler_labels;
+
/* In expr.c */
extern void init_expr_once PROTO ((void));
extern void move_by_pieces PROTO ((rtx, rtx, int, int));
@@ -1329,10 +1451,11 @@ extern void stupid_life_analysis PROTO ((rtx, int, FILE *));
/* In flow.c */
extern void allocate_for_life_analysis PROTO ((void));
-extern void recompute_reg_usage PROTO ((rtx));
+extern void recompute_reg_usage PROTO ((rtx, int));
#ifdef BUFSIZ
extern void dump_flow_info PROTO ((FILE *));
#endif
+extern void free_bb_mem PROTO ((void));
/* In expmed.c */
extern void init_expmed PROTO ((void));
@@ -1344,7 +1467,7 @@ extern rtx expand_mult_highpart PROTO ((enum machine_mode, rtx,
/* In gcse.c */
#ifdef BUFSIZ
-extern void gcse_main PROTO ((rtx, FILE *));
+extern int gcse_main PROTO ((rtx, FILE *));
#endif
/* In global.c */
@@ -1388,6 +1511,7 @@ extern void init_optabs PROTO ((void));
extern void dump_local_alloc PROTO ((FILE *));
#endif
extern void local_alloc PROTO ((void));
+extern int function_invariant_p PROTO ((rtx));
/* In reload1.c */
extern void reload_cse_regs PROTO ((rtx));
@@ -1401,7 +1525,7 @@ extern int reload PROTO ((rtx, int, FILE *));
extern void init_caller_save PROTO ((void));
/* In profile.c */
-extern void init_branch_prob PROTO ((char *));
+extern void init_branch_prob PROTO ((const char *));
#ifdef BUFSIZ
extern void branch_prob PROTO ((rtx, FILE *));
extern void end_branch_prob PROTO ((FILE *));
@@ -1467,5 +1591,7 @@ extern void init_alias_analysis PROTO ((void));
extern void end_alias_analysis PROTO ((void));
extern void record_base_value PROTO ((int, rtx, int));
+extern void record_alias_subset PROTO ((int, int));
+extern rtx addr_side_effect_eval PROTO ((rtx, int, int));
#endif /* _RTL_H */
diff --git a/gcc/rtl.texi b/gcc/rtl.texi
index 9b69eaebaba..1b214653b08 100644
--- a/gcc/rtl.texi
+++ b/gcc/rtl.texi
@@ -1,4 +1,4 @@
-@c Copyright (C) 1988, 89, 92, 94, 97, 1998 Free Software Foundation, Inc.
+@c Copyright (C) 1988, 89, 92, 94, 97, 1998, 1999 Free Software Foundation, Inc.
@c This is part of the GCC manual.
@c For copying conditions, see the file gcc.texi.
@@ -305,10 +305,24 @@ Stored in the @code{volatil} field and printed as @samp{/v}.
@cindex @code{in_struct}, in @code{mem}
@cindex @samp{/s} in RTL dump
@item MEM_IN_STRUCT_P (@var{x})
-In @code{mem} expressions, nonzero for reference to an entire
-structure, union or array, or to a component of one. Zero for
-references to a scalar variable or through a pointer to a scalar.
-Stored in the @code{in_struct} field and printed as @samp{/s}.
+In @code{mem} expressions, nonzero for reference to an entire structure,
+union or array, or to a component of one. Zero for references to a
+scalar variable or through a pointer to a scalar. Stored in the
+@code{in_struct} field and printed as @samp{/s}. If both this flag and
+MEM_SCALAR_P are clear, then we don't know whether this MEM is in a
+structure or not. Both flags should never be simultaneously set.
+
+@findex MEM_SCALAR_P
+@cindex @code{mem} and @samp{/f}
+@cindex @code{frame_related}, in@code{mem}
+@cindex @samp{/f} in RTL dump
+@item MEM_SCALAR_P (@var{x})
+In @code{mem} expressions, nonzero for reference to a scalar known not
+to be a member of a structure, union, or array. Zero for such
+references and for indirections through pointers, even pointers pointing
+to scalar types. If both this flag and MEM_STRUCT_P are clear, then we
+don't know whether this MEM is in a structure or not. Both flags should
+never be simultaneously set.
@findex MEM_ALIAS_SET
@item MEM_ALIAS_SET (@var{x})
@@ -391,6 +405,13 @@ other functions or by aliasing.) Stored in the
Nonzero in an insn if it resulted from an in-line function call.
Stored in the @code{integrated} field and printed as @samp{/i}.
+@findex RTX_FRAME_RELATED_P
+@item RTX_FRAME_RELATED_P (@var{x})
+Nonzero in an insn or expression which is part of a function
+prologue and sets the stack pointer, sets the frame pointer, or saves a
+register. This flag is required for exception handling support
+on targets with RTL prologues.
+
@findex SYMBOL_REF_USED
@cindex @code{used}, in @code{symbol_ref}
@item SYMBOL_REF_USED (@var{x})
@@ -2036,7 +2057,7 @@ and of @var{min} and @var{max} to @var{base}. See rtl.def for details.@refill
@cindex RTL predecrement
@cindex RTL postdecrement
-Four special side-effect expression codes appear as memory addresses.
+Six special side-effect expression codes appear as memory addresses.
@table @code
@findex pre_dec
@@ -2071,6 +2092,38 @@ being decremented.
@findex post_inc
@item (post_inc:@var{m} @var{x})
Similar, but specifies incrementing @var{x} instead of decrementing it.
+
+@findex post_modify
+@item (post_modify:@var{m} @var{x} @var{y})
+
+Represents the side effect of setting @var{x} to @var{y} and
+represents @var{x} before @var{x} is modified. @var{x} must be a
+@code{reg} or @code{mem}, but most machines allow only a @code{reg}.
+@var{m} must be the machine mode for pointers on the machine in use.
+The amount @var{x} is decremented by is the length in bytes of the
+machine mode of the containing memory reference of which this expression
+serves as the address. Note that this is not currently implemented.
+
+The expression @var{y} must be one of three forms:
+@table @code
+@code{(plus:@var{m} @var{x} @var{z})},
+@code{(minus:@var{m} @var{x} @var{z})}, or
+@code{(plus:@var{m} @var{x} @var{i})},
+@end table
+where @var{z} is an index register and @var{i} is a constant.
+
+Here is an example of its use:@refill
+
+@example
+(mem:SF (post_modify:SI (reg:SI 42) (plus (reg:SI 42) (reg:SI 48))))
+@end example
+
+This says to modify pseudo register 42 by adding the contents of pseudo
+register 48 to it, after the use of what ever 42 points to.
+
+@findex post_modify
+@item (pre_modify:@var{m} @var{x} @var{expr})
+Similar except side effects happen before the use.
@end table
These embedded side effect expressions must be used with care. Instruction
@@ -2372,9 +2425,7 @@ These codes are printed symbolically when they appear in debugging dumps.
@cindex @code{HImode}, in @code{insn}
@cindex @code{QImode}, in @code{insn}
The machine mode of an insn is normally @code{VOIDmode}, but some
-phases use the mode for various purposes; for example, the reload pass
-sets it to @code{HImode} if the insn needs reloading but not register
-elimination and @code{QImode} if both are required.
+phases use the mode for various purposes.
The common subexpression elimination pass sets the mode of an insn to
@code{QImode} when it is the first insn in a block that has already
@@ -2634,11 +2685,17 @@ delete such sequences whose results are dead.
A @code{REG_EQUAL} note will also usually be attached to this insn to
provide the expression being computed by the sequence.
+These notes will be deleted after reload, since they are no longer
+accurate or useful.
+
@findex REG_LIBCALL
@item REG_LIBCALL
This is the inverse of @code{REG_RETVAL}: it is placed on the first
insn of a multi-insn sequence, and it points to the last one.
+These notes are deleted after reload, since they are no longer useful or
+accurate.
+
@findex REG_CC_SETTER
@findex REG_CC_USER
@item REG_CC_SETTER
diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c
index 6e5fa77fd3e..8347849c6e1 100644
--- a/gcc/rtlanal.c
+++ b/gcc/rtlanal.c
@@ -1,5 +1,5 @@
/* Analyze RTL for C-Compiler
- Copyright (C) 1987, 88, 92-97, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1987, 88, 92-98, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -326,6 +326,20 @@ no_labels_between_p (beg, end)
return 1;
}
+/* Return 1 if in between BEG and END, exclusive of BEG and END, there is
+ no JUMP_INSN insn. */
+
+int
+no_jumps_between_p (beg, end)
+ rtx beg, end;
+{
+ register rtx p;
+ for (p = NEXT_INSN (beg); p != end; p = NEXT_INSN (p))
+ if (GET_CODE (p) == JUMP_INSN)
+ return 0;
+ return 1;
+}
+
/* Nonzero if register REG is used in an insn between
FROM_INSN and TO_INSN (exclusive of those two). */
@@ -500,6 +514,52 @@ reg_set_p (reg, insn)
}
/* Similar to reg_set_between_p, but check all registers in X. Return 0
+ only if none of them are modified between START and END. Do not
+ consider non-registers one way or the other. */
+
+int
+regs_set_between_p (x, start, end)
+ rtx x;
+ rtx start, end;
+{
+ enum rtx_code code = GET_CODE (x);
+ char *fmt;
+ int i, j;
+
+ switch (code)
+ {
+ case CONST_INT:
+ case CONST_DOUBLE:
+ case CONST:
+ case SYMBOL_REF:
+ case LABEL_REF:
+ case PC:
+ case CC0:
+ return 0;
+
+ case REG:
+ return reg_set_between_p (x, start, end);
+
+ default:
+ break;
+ }
+
+ fmt = GET_RTX_FORMAT (code);
+ for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
+ {
+ if (fmt[i] == 'e' && regs_set_between_p (XEXP (x, i), start, end))
+ return 1;
+
+ else if (fmt[i] == 'E')
+ for (j = XVECLEN (x, i) - 1; j >= 0; j--)
+ if (regs_set_between_p (XVECEXP (x, i, j), start, end))
+ return 1;
+ }
+
+ return 0;
+}
+
+/* Similar to reg_set_between_p, but check all registers in X. Return 0
only if none of them are modified between START and END. Return 1 if
X contains a MEM; this routine does not perform any memory aliasing. */
@@ -644,17 +704,51 @@ single_set (insn)
return 0;
}
+
+/* Given an INSN, return nonzero if it has more than one SET, else return
+ zero. */
+
+int
+multiple_sets (insn)
+ rtx insn;
+{
+ int found;
+ int i;
+
+ /* INSN must be an insn. */
+ if (GET_RTX_CLASS (GET_CODE (insn)) != 'i')
+ return 0;
+
+ /* Only a PARALLEL can have multiple SETs. */
+ if (GET_CODE (PATTERN (insn)) == PARALLEL)
+ {
+ for (i = 0, found = 0; i < XVECLEN (PATTERN (insn), 0); i++)
+ if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == SET)
+ {
+ /* If we have already found a SET, then return now. */
+ if (found)
+ return 1;
+ else
+ found = 1;
+ }
+ }
+
+ /* Either zero or one SET. */
+ return 0;
+}
/* Return the last thing that X was assigned from before *PINSN. Verify that
the object is not modified up to VALID_TO. If it was, if we hit
a partial assignment to X, or hit a CODE_LABEL first, return X. If we
- found an assignment, update *PINSN to point to it. */
+ found an assignment, update *PINSN to point to it.
+ ALLOW_HWREG is set to 1 if hardware registers are allowed to be the src. */
rtx
-find_last_value (x, pinsn, valid_to)
+find_last_value (x, pinsn, valid_to, allow_hwreg)
rtx x;
rtx *pinsn;
rtx valid_to;
+ int allow_hwreg;
{
rtx p;
@@ -675,8 +769,8 @@ find_last_value (x, pinsn, valid_to)
if (! modified_between_p (src, PREV_INSN (p), valid_to)
/* Reject hard registers because we don't usually want
to use them; we'd rather use a pseudo. */
- && ! (GET_CODE (src) == REG
- && REGNO (src) < FIRST_PSEUDO_REGISTER))
+ && (! (GET_CODE (src) == REG
+ && REGNO (src) < FIRST_PSEUDO_REGISTER) || allow_hwreg))
{
*pinsn = p;
return src;
@@ -1194,30 +1288,21 @@ dead_or_set_regno_p (insn, test_regno)
int regno, endregno;
rtx link;
- /* REG_READ notes are not normally maintained after reload, so we
- ignore them if the are invalid. */
- if (! reload_completed
-#ifdef PRESERVE_DEATH_INFO_REGNO_P
- || PRESERVE_DEATH_INFO_REGNO_P (test_regno)
-#endif
- )
+ /* See if there is a death note for something that includes
+ TEST_REGNO. */
+ for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
{
- /* See if there is a death note for something that includes
- TEST_REGNO. */
- for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
- {
- if (REG_NOTE_KIND (link) != REG_DEAD
- || GET_CODE (XEXP (link, 0)) != REG)
- continue;
+ if (REG_NOTE_KIND (link) != REG_DEAD
+ || GET_CODE (XEXP (link, 0)) != REG)
+ continue;
- regno = REGNO (XEXP (link, 0));
- endregno = (regno >= FIRST_PSEUDO_REGISTER ? regno + 1
- : regno + HARD_REGNO_NREGS (regno,
- GET_MODE (XEXP (link, 0))));
+ regno = REGNO (XEXP (link, 0));
+ endregno = (regno >= FIRST_PSEUDO_REGISTER ? regno + 1
+ : regno + HARD_REGNO_NREGS (regno,
+ GET_MODE (XEXP (link, 0))));
- if (test_regno >= regno && test_regno < endregno)
- return 1;
- }
+ if (test_regno >= regno && test_regno < endregno)
+ return 1;
}
if (GET_CODE (insn) == CALL_INSN
@@ -1231,7 +1316,7 @@ dead_or_set_regno_p (insn, test_regno)
/* A value is totally replaced if it is the destination or the
destination is a SUBREG of REGNO that does not change the number of
words in it. */
- if (GET_CODE (dest) == SUBREG
+ if (GET_CODE (dest) == SUBREG
&& (((GET_MODE_SIZE (GET_MODE (dest))
+ UNITS_PER_WORD - 1) / UNITS_PER_WORD)
== ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (dest)))
@@ -2058,10 +2143,11 @@ computed_jump_p (insn)
This routine is very general, and could (should?) be used to
implement many of the other routines in this file. */
-int for_each_rtx (x, f, data)
- rtx* x;
+int
+for_each_rtx (x, f, data)
+ rtx *x;
rtx_function f;
- void* data;
+ void *data;
{
int result;
int length;
@@ -2117,3 +2203,59 @@ int for_each_rtx (x, f, data)
return 0;
}
+
+/* Searches X for any reference to REGNO, returning the rtx of the
+ reference found if any. Otherwise, returns NULL_RTX. */
+
+rtx
+regno_use_in (regno, x)
+ int regno;
+ rtx x;
+{
+ register char *fmt;
+ int i, j;
+ rtx tem;
+
+ if (GET_CODE (x) == REG && REGNO (x) == regno)
+ return x;
+
+ fmt = GET_RTX_FORMAT (GET_CODE (x));
+ for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
+ {
+ if (fmt[i] == 'e')
+ {
+ if ((tem = regno_use_in (regno, XEXP (x, i))))
+ return tem;
+ }
+ else if (fmt[i] == 'E')
+ for (j = XVECLEN (x, i) - 1; j >= 0; j--)
+ if ((tem = regno_use_in (regno , XVECEXP (x, i, j))))
+ return tem;
+ }
+
+ return NULL_RTX;
+}
+
+
+/* Return 1 if X is an autoincrement side effect and the register is
+ not the stack pointer. */
+int
+auto_inc_p (x)
+ rtx x;
+{
+ switch (GET_CODE (x))
+ {
+ case PRE_INC:
+ case POST_INC:
+ case PRE_DEC:
+ case POST_DEC:
+ case PRE_MODIFY:
+ case POST_MODIFY:
+ /* There are no REG_INC notes for SP. */
+ if (XEXP (x, 0) != stack_pointer_rtx)
+ return 1;
+ default:
+ break;
+ }
+ return 0;
+}
diff --git a/gcc/scan-decls.c b/gcc/scan-decls.c
index d2f32a86cf9..5fea64309b4 100644
--- a/gcc/scan-decls.c
+++ b/gcc/scan-decls.c
@@ -1,5 +1,5 @@
/* scan-decls.c - Extracts declarations from cpp output.
- Copyright (C) 1993, 1995, 1997, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1993, 1995, 97-98, 1999 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
@@ -19,7 +19,6 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "hconfig.h"
#include "system.h"
-#include "gansidecl.h"
#include "cpplib.h"
#include "scan.h"
@@ -78,8 +77,8 @@ Here dname is the actual name being declared.
int
scan_decls (pfile, argc, argv)
cpp_reader *pfile;
- int argc;
- char **argv;
+ int argc ATTRIBUTE_UNUSED;
+ char **argv ATTRIBUTE_UNUSED;
{
int saw_extern, saw_inline;
int start_written;
@@ -170,7 +169,7 @@ scan_decls (pfile, argc, argv)
}
break;
case CPP_OTHER:
- if (CPP_WRITTEN (pfile) == start_written + 1
+ if (CPP_WRITTEN (pfile) == (size_t) start_written + 1
&& (CPP_PWRITTEN (pfile)[-1] == '*'
|| CPP_PWRITTEN (pfile)[-1] == '&'))
declarator_start = start_written;
@@ -190,7 +189,9 @@ scan_decls (pfile, argc, argv)
maybe_handle_comma:
if (token != CPP_COMMA)
goto new_statement;
+#if 0
handle_comma:
+#endif
/* Handle multiple declarators in a single declaration,
as in: extern char *strcpy (), *strcat (), ... ; */
if (declarator_start == 0)
diff --git a/gcc/scan.c b/gcc/scan.c
index 4251dfcb8eb..24dd6632f35 100644
--- a/gcc/scan.c
+++ b/gcc/scan.c
@@ -1,5 +1,5 @@
/* Utility functions for scan-decls and fix-header programs.
- Copyright (C) 1993, 1994 Free Software Foundation, Inc.
+ Copyright (C) 1993, 1994, 1998 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
diff --git a/gcc/scan.h b/gcc/scan.h
index 12879c015bf..f59cd276ba4 100644
--- a/gcc/scan.h
+++ b/gcc/scan.h
@@ -1,5 +1,5 @@
/* scan.h - Utility declarations for scan-decls and fix-header programs.
- Copyright (C) 1993 Free Software Foundation, Inc.
+ Copyright (C) 1993, 1998, 1999 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
@@ -34,7 +34,7 @@ typedef struct sstring
if ((STR)->limit - (STR)->ptr < (COUNT)) make_sstring_space (STR, COUNT);
#ifndef _PARAMS
-#if defined(__STDC__) || defined(__cplusplus)
+#if defined(ANSI_PROTOTYPES) || defined(__cplusplus)
#define _PARAMS(args) args
#else
#define _PARAMS(args) ()
@@ -44,9 +44,9 @@ typedef struct sstring
struct partial_proto;
struct fn_decl
{
- char *fname;
- char *rtype;
- char *params;
+ const char *fname;
+ const char *rtype;
+ const char *params;
struct partial_proto *partial;
};
@@ -57,8 +57,6 @@ extern int skip_spaces _PARAMS((FILE *, int));
extern int scan_ident _PARAMS((FILE *, sstring *, int));
extern int scan_string _PARAMS((FILE *, sstring *, int));
extern int read_upto _PARAMS((FILE *, sstring *, int));
-extern char *xmalloc _PARAMS((unsigned));
-extern char *xrealloc _PARAMS((char *, unsigned));
extern unsigned long hash _PARAMS((const char *));
extern void recognized_function _PARAMS((char *, int, int, char *, int, int, char *, int));
extern void recognized_extern _PARAMS((char *, int, char *, int));
diff --git a/gcc/sched.c b/gcc/sched.c
index 5fbf7609f4d..3701ac624be 100644
--- a/gcc/sched.c
+++ b/gcc/sched.c
@@ -1,5 +1,5 @@
/* Instruction scheduling pass.
- Copyright (C) 1992, 93-97, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1992, 93-98, 1999 Free Software Foundation, Inc.
Contributed by Michael Tiemann (tiemann@cygnus.com)
Enhanced by, and currently maintained by, Jim Wilson (wilson@cygnus.com)
@@ -108,8 +108,8 @@ Boston, MA 02111-1307, USA. */
This pass must update information that subsequent passes expect to be
correct. Namely: reg_n_refs, reg_n_sets, reg_n_deaths,
- reg_n_calls_crossed, and reg_live_length. Also, basic_block_head,
- basic_block_end.
+ reg_n_calls_crossed, and reg_live_length. Also, BLOCK_HEAD,
+ BLOCK_END.
The information in the line number notes is carefully retained by
this pass. Notes that refer to the starting and ending of
@@ -126,6 +126,7 @@ Boston, MA 02111-1307, USA. */
#include "flags.h"
#include "insn-config.h"
#include "insn-attr.h"
+#include "recog.h"
#ifndef INSN_SCHEDULING
void
@@ -325,7 +326,7 @@ static void sched_analyze_1 PROTO((rtx, rtx));
static void sched_analyze_2 PROTO((rtx, rtx));
static void sched_analyze_insn PROTO((rtx, rtx, rtx));
static int sched_analyze PROTO((rtx, rtx));
-static void sched_note_set PROTO((int, rtx, int));
+static void sched_note_set PROTO((rtx, int));
static int rank_for_schedule PROTO((const GENERIC_PTR, const GENERIC_PTR));
static void swap_sort PROTO((rtx *, int));
static void queue_insn PROTO((rtx, int));
@@ -341,11 +342,9 @@ static int new_sometimes_live PROTO((struct sometimes *, int, int));
static void finish_sometimes_live PROTO((struct sometimes *, int));
static rtx reemit_notes PROTO((rtx, rtx));
static void schedule_block PROTO((int, FILE *));
-static rtx regno_use_in PROTO((int, rtx));
-static void split_hard_reg_notes PROTO((rtx, rtx, rtx, rtx));
+static void split_hard_reg_notes PROTO((rtx, rtx, rtx));
static void new_insn_dead_notes PROTO((rtx, rtx, rtx, rtx));
static void update_n_sets PROTO((rtx, int));
-static void update_flow_info PROTO((rtx, rtx, rtx, rtx));
/* Main entry point of this file. */
void schedule_insns PROTO((FILE *));
@@ -606,7 +605,7 @@ blockage_range (unit, insn)
unsigned int blockage = INSN_BLOCKAGE (insn);
unsigned int range;
- if (UNIT_BLOCKED (blockage) != unit + 1)
+ if ((int) UNIT_BLOCKED (blockage) != unit + 1)
{
range = function_units[unit].blockage_range_function (insn);
/* We only cache the blockage range for one unit and then only if
@@ -1553,27 +1552,6 @@ sched_analyze_insn (x, insn, loop_notes)
REG_NOTES (insn) = loop_notes;
}
- /* After reload, it is possible for an instruction to have a REG_DEAD note
- for a register that actually dies a few instructions earlier. For
- example, this can happen with SECONDARY_MEMORY_NEEDED reloads.
- In this case, we must consider the insn to use the register mentioned
- in the REG_DEAD note. Otherwise, we may accidentally move this insn
- after another insn that sets the register, thus getting obviously invalid
- rtl. This confuses reorg which believes that REG_DEAD notes are still
- meaningful.
-
- ??? We would get better code if we fixed reload to put the REG_DEAD
- notes in the right places, but that may not be worth the effort. */
-
- if (reload_completed)
- {
- rtx note;
-
- for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
- if (REG_NOTE_KIND (note) == REG_DEAD)
- sched_analyze_2 (XEXP (note, 0), insn);
- }
-
EXECUTE_IF_SET_IN_REG_SET (reg_pending_sets, 0, i,
{
reg_last_sets[i] = insn;
@@ -1762,8 +1740,7 @@ sched_analyze (head, tail)
are scanning forwards. Mark that register as being born. */
static void
-sched_note_set (b, x, death)
- int b;
+sched_note_set (x, death)
rtx x;
int death;
{
@@ -2637,8 +2614,8 @@ schedule_block (b, file)
int new_needs;
/* HEAD and TAIL delimit the region being scheduled. */
- rtx head = basic_block_head[b];
- rtx tail = basic_block_end[b];
+ rtx head = BLOCK_HEAD (b);
+ rtx tail = BLOCK_END (b);
/* PREV_HEAD and NEXT_TAIL are the boundaries of the insns
being scheduled. When the insns have been ordered,
these insns delimit where the new insns are to be
@@ -2652,7 +2629,7 @@ schedule_block (b, file)
if (file)
fprintf (file, ";;\t -- basic block number %d from %d to %d --\n",
- b, INSN_UID (basic_block_head[b]), INSN_UID (basic_block_end[b]));
+ b, INSN_UID (BLOCK_HEAD (b)), INSN_UID (BLOCK_END (b)));
i = max_reg_num ();
reg_last_uses = (rtx *) alloca (i * sizeof (rtx));
@@ -2902,7 +2879,7 @@ schedule_block (b, file)
if (reload_completed == 0)
{
- COPY_REG_SET (bb_live_regs, basic_block_live_at_start[b]);
+ COPY_REG_SET (bb_live_regs, BASIC_BLOCK (b)->global_live_at_start);
CLEAR_REG_SET (bb_dead_regs);
if (b == 0)
@@ -2914,7 +2891,7 @@ schedule_block (b, file)
/* We don't want to remove any REG_DEAD notes as the code below
does. */
- for (insn = basic_block_head[b]; insn != head;
+ for (insn = BLOCK_HEAD (b); insn != head;
insn = NEXT_INSN (insn))
if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
{
@@ -2926,20 +2903,20 @@ schedule_block (b, file)
a register must be marked as dead after this insn. */
if (GET_CODE (PATTERN (insn)) == SET
|| GET_CODE (PATTERN (insn)) == CLOBBER)
- sched_note_set (b, PATTERN (insn), 0);
+ sched_note_set (PATTERN (insn), 0);
else if (GET_CODE (PATTERN (insn)) == PARALLEL)
{
int j;
for (j = XVECLEN (PATTERN (insn), 0) - 1; j >= 0; j--)
if (GET_CODE (XVECEXP (PATTERN (insn), 0, j)) == SET
|| GET_CODE (XVECEXP (PATTERN (insn), 0, j)) == CLOBBER)
- sched_note_set (b, XVECEXP (PATTERN (insn), 0, j), 0);
+ sched_note_set (XVECEXP (PATTERN (insn), 0, j), 0);
/* ??? This code is obsolete and should be deleted. It
is harmless though, so we will leave it in for now. */
for (j = XVECLEN (PATTERN (insn), 0) - 1; j >= 0; j--)
if (GET_CODE (XVECEXP (PATTERN (insn), 0, j)) == USE)
- sched_note_set (b, XVECEXP (PATTERN (insn), 0, j), 0);
+ sched_note_set (XVECEXP (PATTERN (insn), 0, j), 0);
}
/* Each call clobbers (makes live) all call-clobbered regs
@@ -2998,7 +2975,7 @@ schedule_block (b, file)
block may have changed the current line number. */
rtx line = line_note_head[b];
- for (insn = basic_block_head[b];
+ for (insn = BLOCK_HEAD (b);
insn != next_tail;
insn = NEXT_INSN (insn))
if (GET_CODE (insn) == NOTE && NOTE_LINE_NUMBER (insn) > 0)
@@ -3036,20 +3013,20 @@ schedule_block (b, file)
must be marked as dead after this insn. */
if (GET_CODE (PATTERN (insn)) == SET
|| GET_CODE (PATTERN (insn)) == CLOBBER)
- sched_note_set (b, PATTERN (insn), 0);
+ sched_note_set (PATTERN (insn), 0);
else if (GET_CODE (PATTERN (insn)) == PARALLEL)
{
int j;
for (j = XVECLEN (PATTERN (insn), 0) - 1; j >= 0; j--)
if (GET_CODE (XVECEXP (PATTERN (insn), 0, j)) == SET
|| GET_CODE (XVECEXP (PATTERN (insn), 0, j)) == CLOBBER)
- sched_note_set (b, XVECEXP (PATTERN (insn), 0, j), 0);
+ sched_note_set (XVECEXP (PATTERN (insn), 0, j), 0);
/* ??? This code is obsolete and should be deleted. It
is harmless though, so we will leave it in for now. */
for (j = XVECLEN (PATTERN (insn), 0) - 1; j >= 0; j--)
if (GET_CODE (XVECEXP (PATTERN (insn), 0, j)) == USE)
- sched_note_set (b, XVECEXP (PATTERN (insn), 0, j), 0);
+ sched_note_set (XVECEXP (PATTERN (insn), 0, j), 0);
}
/* Each call clobbers (makes live) all call-clobbered regs that are
@@ -3162,9 +3139,9 @@ schedule_block (b, file)
/* Where we start inserting insns is after TAIL. */
last = next_tail;
- new_needs = (NEXT_INSN (prev_head) == basic_block_head[b]
+ new_needs = (NEXT_INSN (prev_head) == BLOCK_HEAD (b)
? NEED_HEAD : NEED_NOTHING);
- if (PREV_INSN (next_tail) == basic_block_end[b])
+ if (PREV_INSN (next_tail) == BLOCK_END (b))
new_needs |= NEED_TAIL;
new_ready = n_ready;
@@ -3279,14 +3256,14 @@ schedule_block (b, file)
/* See if this is the last notice we must take of a register. */
if (GET_CODE (PATTERN (insn)) == SET
|| GET_CODE (PATTERN (insn)) == CLOBBER)
- sched_note_set (b, PATTERN (insn), 1);
+ sched_note_set (PATTERN (insn), 1);
else if (GET_CODE (PATTERN (insn)) == PARALLEL)
{
int j;
for (j = XVECLEN (PATTERN (insn), 0) - 1; j >= 0; j--)
if (GET_CODE (XVECEXP (PATTERN (insn), 0, j)) == SET
|| GET_CODE (XVECEXP (PATTERN (insn), 0, j)) == CLOBBER)
- sched_note_set (b, XVECEXP (PATTERN (insn), 0, j), 1);
+ sched_note_set (XVECEXP (PATTERN (insn), 0, j), 1);
}
/* This code keeps life analysis information up to date. */
@@ -3471,12 +3448,12 @@ schedule_block (b, file)
#endif
if (new_needs & NEED_HEAD)
- basic_block_head[b] = head;
+ BLOCK_HEAD (b) = head;
PREV_INSN (head) = prev_head;
NEXT_INSN (prev_head) = head;
if (new_needs & NEED_TAIL)
- basic_block_end[b] = tail;
+ BLOCK_END (b) = tail;
NEXT_INSN (tail) = next_tail;
PREV_INSN (next_tail) = tail;
@@ -3486,8 +3463,8 @@ schedule_block (b, file)
rtx line, note, prev, new;
int notes = 0;
- head = basic_block_head[b];
- next_tail = NEXT_INSN (basic_block_end[b]);
+ head = BLOCK_HEAD (b);
+ next_tail = NEXT_INSN (BLOCK_END (b));
/* Determine the current line-number. We want to know the current
line number of the first insn of the block here, in case it is
@@ -3541,7 +3518,7 @@ schedule_block (b, file)
if (file)
{
fprintf (file, ";; total time = %d\n;; new basic block head = %d\n;; new basic block end = %d\n\n",
- clock, INSN_UID (basic_block_head[b]), INSN_UID (basic_block_end[b]));
+ clock, INSN_UID (BLOCK_HEAD (b)), INSN_UID (BLOCK_END (b)));
}
/* Yow! We're done! */
@@ -3554,47 +3531,14 @@ ret:
return;
}
-/* Subroutine of split_hard_reg_notes. Searches X for any reference to
- REGNO, returning the rtx of the reference found if any. Otherwise,
- returns 0. */
-
-static rtx
-regno_use_in (regno, x)
- int regno;
- rtx x;
-{
- register char *fmt;
- int i, j;
- rtx tem;
-
- if (GET_CODE (x) == REG && REGNO (x) == regno)
- return x;
-
- fmt = GET_RTX_FORMAT (GET_CODE (x));
- for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
- {
- if (fmt[i] == 'e')
- {
- if ((tem = regno_use_in (regno, XEXP (x, i))))
- return tem;
- }
- else if (fmt[i] == 'E')
- for (j = XVECLEN (x, i) - 1; j >= 0; j--)
- if ((tem = regno_use_in (regno , XVECEXP (x, i, j))))
- return tem;
- }
-
- return 0;
-}
-
/* Subroutine of update_flow_info. Determines whether any new REG_NOTEs are
needed for the hard register mentioned in the note. This can happen
if the reference to the hard register in the original insn was split into
several smaller hard register references in the split insns. */
static void
-split_hard_reg_notes (note, first, last, orig_insn)
- rtx note, first, last, orig_insn;
+split_hard_reg_notes (note, first, last)
+ rtx note, first, last;
{
rtx reg, temp, link;
int n_regs, i, new_reg;
@@ -3781,7 +3725,7 @@ update_n_sets (x, inc)
the insns from FIRST to LAST inclusive that were created by splitting
ORIG_INSN. NOTES are the original REG_NOTES. */
-static void
+void
update_flow_info (notes, first, last, orig_insn)
rtx notes;
rtx first, last;
@@ -3823,7 +3767,7 @@ update_flow_info (notes, first, last, orig_insn)
&& GET_CODE (temp) == REG
&& REGNO (temp) < FIRST_PSEUDO_REGISTER
&& HARD_REGNO_NREGS (REGNO (temp), GET_MODE (temp)) > 1)
- split_hard_reg_notes (note, first, last, orig_insn);
+ split_hard_reg_notes (note, first, last);
else
{
XEXP (note, 1) = REG_NOTES (insn);
@@ -3849,16 +3793,7 @@ update_flow_info (notes, first, last, orig_insn)
register that was not needed by this instantiation of the
pattern, so we can safely ignore it. */
if (insn == first)
- {
- /* After reload, REG_DEAD notes come sometimes an
- instruction after the register actually dies. */
- if (reload_completed && REG_NOTE_KIND (note) == REG_DEAD)
- {
- XEXP (note, 1) = REG_NOTES (insn);
- REG_NOTES (insn) = note;
- break;
- }
-
+ {
if (REG_NOTE_KIND (note) != REG_UNUSED)
abort ();
@@ -4204,8 +4139,28 @@ update_flow_info (notes, first, last, orig_insn)
}
else if (! found_orig_dest)
{
- /* This should never happen. */
- abort ();
+ int i, regno;
+
+ /* Should never reach here for a pseudo reg. */
+ if (REGNO (orig_dest) >= FIRST_PSEUDO_REGISTER)
+ abort ();
+
+ /* This can happen for a hard register, if the splitter
+ does not bother to emit instructions which would be no-ops.
+ We try to verify that this is the case by checking to see if
+ the original instruction uses all of the registers that it
+ set. This case is OK, because deleting a no-op can not affect
+ REG_DEAD notes on other insns. If this is not the case, then
+ abort. */
+
+ regno = REGNO (orig_dest);
+ for (i = HARD_REGNO_NREGS (regno, GET_MODE (orig_dest)) - 1;
+ i >= 0; i--)
+ if (! refers_to_regno_p (regno + i, regno + i + 1, orig_insn,
+ NULL_PTR))
+ break;
+ if (i >= 0)
+ abort ();
}
}
@@ -4337,7 +4292,7 @@ schedule_insns (dump_file)
determine the correct line number for the first insn of the block. */
for (b = 0; b < n_basic_blocks; b++)
- for (line = basic_block_head[b]; line; line = PREV_INSN (line))
+ for (line = BLOCK_HEAD (b); line; line = PREV_INSN (line))
if (GET_CODE (line) == NOTE && NOTE_LINE_NUMBER (line) > 0)
{
line_note_head[b] = line;
@@ -4360,7 +4315,7 @@ schedule_insns (dump_file)
/* ??? Perhaps it's done to ensure NEXT_TAIL in schedule_block is a
valid insn. */
- insn = basic_block_end[n_basic_blocks-1];
+ insn = BLOCK_END (n_basic_blocks-1);
if (NEXT_INSN (insn) == 0
|| (GET_CODE (insn) != NOTE
&& GET_CODE (insn) != CODE_LABEL
@@ -4368,86 +4323,13 @@ schedule_insns (dump_file)
jump and a BARRIER. */
&& ! (GET_CODE (insn) == JUMP_INSN
&& GET_CODE (NEXT_INSN (insn)) == BARRIER)))
- emit_note_after (NOTE_INSN_DELETED, basic_block_end[n_basic_blocks-1]);
+ emit_note_after (NOTE_INSN_DELETED, BLOCK_END (n_basic_blocks-1));
for (b = 0; b < n_basic_blocks; b++)
{
- rtx insn, next;
-
note_list = 0;
- for (insn = basic_block_head[b]; ; insn = next)
- {
- rtx prev;
- rtx set;
-
- /* Can't use `next_real_insn' because that
- might go across CODE_LABELS and short-out basic blocks. */
- next = NEXT_INSN (insn);
- if (GET_CODE (insn) != INSN)
- {
- if (insn == basic_block_end[b])
- break;
-
- continue;
- }
-
- /* Don't split no-op move insns. These should silently disappear
- later in final. Splitting such insns would break the code
- that handles REG_NO_CONFLICT blocks. */
- set = single_set (insn);
- if (set && rtx_equal_p (SET_SRC (set), SET_DEST (set)))
- {
- if (insn == basic_block_end[b])
- break;
-
- /* Nops get in the way while scheduling, so delete them now if
- register allocation has already been done. It is too risky
- to try to do this before register allocation, and there are
- unlikely to be very many nops then anyways. */
- if (reload_completed)
- {
- PUT_CODE (insn, NOTE);
- NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
- NOTE_SOURCE_FILE (insn) = 0;
- }
-
- continue;
- }
-
- /* Split insns here to get max fine-grain parallelism. */
- prev = PREV_INSN (insn);
- /* It is probably not worthwhile to try to split again in the
- second pass. However, if flag_schedule_insns is not set,
- the first and only (if any) scheduling pass is after reload. */
- if (reload_completed == 0 || ! flag_schedule_insns)
- {
- rtx last, first = PREV_INSN (insn);
- rtx notes = REG_NOTES (insn);
-
- last = try_split (PATTERN (insn), insn, 1);
- if (last != insn)
- {
- /* try_split returns the NOTE that INSN became. */
- first = NEXT_INSN (first);
- update_flow_info (notes, first, last, insn);
-
- PUT_CODE (insn, NOTE);
- NOTE_SOURCE_FILE (insn) = 0;
- NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
- if (insn == basic_block_head[b])
- basic_block_head[b] = first;
- if (insn == basic_block_end[b])
- {
- basic_block_end[b] = last;
- break;
- }
- }
- }
-
- if (insn == basic_block_end[b])
- break;
- }
+ split_block_insns (b, reload_completed == 0 || ! flag_schedule_insns);
schedule_block (b, dump_file);
diff --git a/gcc/sdbout.c b/gcc/sdbout.c
index 1823155cea5..470cca66dd7 100644
--- a/gcc/sdbout.c
+++ b/gcc/sdbout.c
@@ -59,7 +59,7 @@ AT&T C compiler. From the example below I would conclude the following:
supply usable syms.h include files. Which syms.h file to use is a
target parameter so don't use the native one if we're cross compiling. */
-#if defined(USG) && !defined(MIPS) && !defined (hpux) && !defined(_WIN32) && !defined(__linux__) && !defined(CROSS_COMPILE)
+#if defined(USG) && !defined(MIPS) && !defined (hpux) && !defined(_WIN32) && !defined(__linux__) && !defined(__INTERIX) && !defined(CROSS_COMPILE)
#include <syms.h>
/* Use T_INT if we don't have T_VOID. */
#ifndef T_VOID
@@ -338,7 +338,7 @@ void
sdbout_init (asm_file, input_file_name, syms)
FILE *asm_file;
char *input_file_name;
- tree syms;
+ tree syms ATTRIBUTE_UNUSED;
{
#ifdef MIPS_DEBUGGING_INFO
current_file = (struct sdb_file *) xmalloc (sizeof *current_file);
@@ -527,6 +527,7 @@ plain_type_1 (type, level)
{
case VOID_TYPE:
return T_VOID;
+ case BOOLEAN_TYPE:
case INTEGER_TYPE:
{
int size = int_size_in_bytes (type) * BITS_PER_UNIT;
@@ -1560,7 +1561,7 @@ void
sdbout_end_block (file, line, n)
FILE *file;
int line;
- int n;
+ int n ATTRIBUTE_UNUSED;
{
MAKE_LINE_SAFE (line);
diff --git a/gcc/stab.def b/gcc/stab.def
index 48ea231e603..81d442a47c4 100644
--- a/gcc/stab.def
+++ b/gcc/stab.def
@@ -1,5 +1,5 @@
/* Table of DBX symbol codes for the GNU system.
- Copyright (C) 1988, 1997 Free Software Foundation, Inc.
+ Copyright (C) 1988, 1997, 1998 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
diff --git a/gcc/stmt.c b/gcc/stmt.c
index 0f54b0b65f6..c8cecae6fac 100644
--- a/gcc/stmt.c
+++ b/gcc/stmt.c
@@ -1,5 +1,5 @@
/* Expands front end tree to back end RTL for GNU C-Compiler
- Copyright (C) 1987, 88, 89, 92-97, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1987, 88, 89, 92-98, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -248,7 +248,7 @@ struct nesting
/* Number of range exprs in case statement. */
int num_ranges;
/* Name of this kind of statement, for warnings. */
- char *printname;
+ const char *printname;
/* Used to save no_line_numbers till we see the first case label.
We set this to -1 when we see the first case label in this
case statement. */
@@ -402,8 +402,12 @@ struct stmt_status
static int using_eh_for_cleanups_p = 0;
+static int n_occurrences PROTO((int, const char *));
static void expand_goto_internal PROTO((tree, rtx, rtx));
static int expand_fixup PROTO((tree, rtx, rtx));
+static rtx expand_nl_handler_label PROTO((rtx, rtx));
+static void expand_nl_goto_receiver PROTO((void));
+static void expand_nl_goto_receivers PROTO((struct nesting *));
static void fixup_gotos PROTO((struct nesting *, rtx, tree,
rtx, int));
static void expand_null_return_1 PROTO((rtx, int));
@@ -670,12 +674,14 @@ expand_computed_goto (exp)
emit_queue ();
/* Be sure the function is executable. */
- if (flag_check_memory_usage)
+ if (current_function_check_memory_usage)
emit_library_call (chkr_check_exec_libfunc, 1,
VOIDmode, 1, x, ptr_mode);
do_pending_stack_adjust ();
emit_indirect_jump (x);
+
+ current_function_has_computed_jump = 1;
}
/* Handle goto statements and the labels that they can go to. */
@@ -718,16 +724,18 @@ void
declare_nonlocal_label (label)
tree label;
{
+ rtx slot = assign_stack_local (Pmode, GET_MODE_SIZE (Pmode), 0);
+
nonlocal_labels = tree_cons (NULL_TREE, label, nonlocal_labels);
LABEL_PRESERVE_P (label_rtx (label)) = 1;
- if (nonlocal_goto_handler_slot == 0)
+ if (nonlocal_goto_handler_slots == 0)
{
- nonlocal_goto_handler_slot
- = assign_stack_local (Pmode, GET_MODE_SIZE (Pmode), 0);
emit_stack_save (SAVE_NONLOCAL,
&nonlocal_goto_stack_level,
PREV_INSN (tail_recursion_reentry));
}
+ nonlocal_goto_handler_slots
+ = gen_rtx_EXPR_LIST (VOIDmode, slot, nonlocal_goto_handler_slots);
}
/* Generate RTL code for a `goto' statement with target label LABEL.
@@ -746,7 +754,15 @@ expand_goto (label)
{
struct function *p = find_function_data (context);
rtx label_ref = gen_rtx_LABEL_REF (Pmode, label_rtx (label));
- rtx temp;
+ rtx temp, handler_slot;
+ tree link;
+
+ /* Find the corresponding handler slot for this label. */
+ handler_slot = p->nonlocal_goto_handler_slots;
+ for (link = p->nonlocal_labels; TREE_VALUE (link) != label;
+ link = TREE_CHAIN (link))
+ handler_slot = XEXP (handler_slot, 1);
+ handler_slot = XEXP (handler_slot, 0);
p->has_nonlocal_label = 1;
current_function_has_nonlocal_goto = 1;
@@ -759,8 +775,8 @@ expand_goto (label)
#if HAVE_nonlocal_goto
if (HAVE_nonlocal_goto)
emit_insn (gen_nonlocal_goto (lookup_static_chain (label),
- copy_rtx (p->saved_nonlocal_goto_handler_slot),
- copy_rtx (p->saved_nonlocal_goto_stack_level),
+ copy_rtx (handler_slot),
+ copy_rtx (p->nonlocal_goto_stack_level),
label_ref));
else
#endif
@@ -781,7 +797,7 @@ expand_goto (label)
/* Get addr of containing function's current nonlocal goto handler,
which will do any cleanups and then jump to the label. */
- addr = copy_rtx (p->saved_nonlocal_goto_handler_slot);
+ addr = copy_rtx (handler_slot);
temp = copy_to_reg (replace_rtx (addr, virtual_stack_vars_rtx,
hard_frame_pointer_rtx));
@@ -794,13 +810,10 @@ expand_goto (label)
emit_stack_restore (SAVE_NONLOCAL, addr, NULL_RTX);
- /* Put in the static chain register the nonlocal label address. */
- emit_move_insn (static_chain_rtx, label_ref);
/* USE of hard_frame_pointer_rtx added for consistency; not clear if
really needed. */
emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
- emit_insn (gen_rtx_USE (VOIDmode, static_chain_rtx));
emit_indirect_jump (temp);
}
}
@@ -972,19 +985,25 @@ expand_fixup (tree_label, rtl_label, last_insn)
code which we might later insert at this point in the insn
stream. Also, the BLOCK node will be the parent (i.e. the
`SUPERBLOCK') of any other BLOCK nodes which we might create
- later on when we are expanding the fixup code. */
+ later on when we are expanding the fixup code.
+
+ Note that optimization passes (including expand_end_loop)
+ might move the *_BLOCK notes away, so we use a NOTE_INSN_DELETED
+ as a placeholder. */
{
register rtx original_before_jump
= last_insn ? last_insn : get_last_insn ();
+ rtx start;
start_sequence ();
pushlevel (0);
- fixup->before_jump = emit_note (NULL_PTR, NOTE_INSN_BLOCK_BEG);
+ start = emit_note (NULL_PTR, NOTE_INSN_BLOCK_BEG);
+ fixup->before_jump = emit_note (NULL_PTR, NOTE_INSN_DELETED);
last_block_end_note = emit_note (NULL_PTR, NOTE_INSN_BLOCK_END);
fixup->context = poplevel (1, 0, 0); /* Create the BLOCK node now! */
end_sequence ();
- emit_insns_after (fixup->before_jump, original_before_jump);
+ emit_insns_after (start, original_before_jump);
}
fixup->block_start_count = current_block_start_count;
@@ -1183,8 +1202,18 @@ fixup_gotos (thisblock, stack_level, cleanup_list, first_insn, dont_jump_in)
f->stack_level = stack_level;
}
}
-
-
+
+/* Return the number of times character C occurs in string S. */
+static int
+n_occurrences (c, s)
+ int c;
+ const char *s;
+{
+ int n = 0;
+ while (*s)
+ n += (*s++ == c);
+ return n;
+}
/* Generate RTL for an asm statement (explicit assembler code).
BODY is a STRING_CST node containing the assembler code text,
@@ -1194,7 +1223,7 @@ void
expand_asm (body)
tree body;
{
- if (flag_check_memory_usage)
+ if (current_function_check_memory_usage)
{
error ("`asm' cannot be used with `-fcheck-memory-usage'");
return;
@@ -1250,7 +1279,7 @@ expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line)
if (noutputs == 0)
vol = 1;
- if (flag_check_memory_usage)
+ if (current_function_check_memory_usage)
{
error ("`asm' cannot be used with `-fcheck-memory-usage'");
return;
@@ -1271,14 +1300,47 @@ expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line)
last_expr_type = 0;
+ /* Check that the number of alternatives is constant across all
+ operands. */
+ if (outputs || inputs)
+ {
+ tree tmp = TREE_PURPOSE (outputs ? outputs : inputs);
+ int nalternatives = n_occurrences (',', TREE_STRING_POINTER (tmp));
+ tree next = inputs;
+
+ if (nalternatives + 1 > MAX_RECOG_ALTERNATIVES)
+ {
+ error ("too many alternatives in `asm'");
+ return;
+ }
+
+ tmp = outputs;
+ while (tmp)
+ {
+ char *constraint = TREE_STRING_POINTER (TREE_PURPOSE (tmp));
+ if (n_occurrences (',', constraint) != nalternatives)
+ {
+ error ("operand constraints for `asm' differ in number of alternatives");
+ return;
+ }
+ if (TREE_CHAIN (tmp))
+ tmp = TREE_CHAIN (tmp);
+ else
+ tmp = next, next = 0;
+ }
+ }
+
for (i = 0, tail = outputs; tail; tail = TREE_CHAIN (tail), i++)
{
tree val = TREE_VALUE (tail);
tree type = TREE_TYPE (val);
+ char *constraint;
+ char *p;
+ int c_len;
int j;
- int found_equal = 0;
- int found_plus = 0;
+ int is_inout = 0;
int allows_reg = 0;
+ int allows_mem = 0;
/* If there's an erroneous arg, emit no insn. */
if (TREE_TYPE (val) == error_mark_node)
@@ -1289,29 +1351,62 @@ expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line)
the worst that happens if we get it wrong is we issue an error
message. */
- for (j = 0; j < TREE_STRING_LENGTH (TREE_PURPOSE (tail)) - 1; j++)
- switch (TREE_STRING_POINTER (TREE_PURPOSE (tail))[j])
+ c_len = TREE_STRING_LENGTH (TREE_PURPOSE (tail)) - 1;
+ constraint = TREE_STRING_POINTER (TREE_PURPOSE (tail));
+
+ /* Allow the `=' or `+' to not be at the beginning of the string,
+ since it wasn't explicitly documented that way, and there is a
+ large body of code that puts it last. Swap the character to
+ the front, so as not to uglify any place else. */
+ switch (c_len)
+ {
+ default:
+ if ((p = strchr (constraint, '=')) != NULL)
+ break;
+ if ((p = strchr (constraint, '+')) != NULL)
+ break;
+ case 0:
+ error ("output operand constraint lacks `='");
+ return;
+ }
+
+ if (p != constraint)
+ {
+ j = *p;
+ bcopy (constraint, constraint+1, p-constraint);
+ *constraint = j;
+
+ warning ("output constraint `%c' for operand %d is not at the beginning", j, i);
+ }
+
+ is_inout = constraint[0] == '+';
+ /* Replace '+' with '='. */
+ constraint[0] = '=';
+ /* Make sure we can specify the matching operand. */
+ if (is_inout && i > 9)
+ {
+ error ("output operand constraint %d contains `+'", i);
+ return;
+ }
+
+ for (j = 1; j < c_len; j++)
+ switch (constraint[j])
{
case '+':
- /* Make sure we can specify the matching operand. */
- if (i > 9)
+ case '=':
+ error ("operand constraint contains '+' or '=' at illegal position.");
+ return;
+
+ case '%':
+ if (i + 1 == ninputs + noutputs)
{
- error ("output operand constraint %d contains `+'", i);
+ error ("`%%' constraint used with last operand");
return;
}
-
- /* Replace '+' with '='. */
- TREE_STRING_POINTER (TREE_PURPOSE (tail))[j] = '=';
- found_plus = 1;
- break;
-
- case '=':
- found_equal = 1;
break;
- case '?': case '!': case '*': case '%': case '&':
- case 'V': case 'm': case 'o': case '<': case '>':
- case 'E': case 'F': case 'G': case 'H': case 'X':
+ case '?': case '!': case '*': case '&':
+ case 'E': case 'F': case 'G': case 'H':
case 's': case 'i': case 'n':
case 'I': case 'J': case 'K': case 'L': case 'M':
case 'N': case 'O': case 'P': case ',':
@@ -1325,29 +1420,41 @@ expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line)
error ("matching constraint not valid in output operand");
break;
- case 'p': case 'g': case 'r':
+ case 'V': case 'm': case 'o':
+ allows_mem = 1;
+ break;
+
+ case '<': case '>':
+ /* ??? Before flow, auto inc/dec insns are not supposed to exist,
+ excepting those that expand_call created. So match memory
+ and hope. */
+ allows_mem = 1;
+ break;
+
+ case 'g': case 'X':
+ allows_reg = 1;
+ allows_mem = 1;
+ break;
+
+ case 'p': case 'r':
default:
allows_reg = 1;
break;
}
- if (! found_equal && ! found_plus)
- {
- error ("output operand constraint lacks `='");
- return;
- }
-
/* If an output operand is not a decl or indirect ref and our constraint
allows a register, make a temporary to act as an intermediate.
Make the asm insn write into that, then our caller will copy it to
the real output operand. Likewise for promoted variables. */
- if (TREE_CODE (val) == INDIRECT_REF
+ if ((TREE_CODE (val) == INDIRECT_REF
+ && allows_mem)
|| (TREE_CODE_CLASS (TREE_CODE (val)) == 'd'
+ && (allows_mem || GET_CODE (DECL_RTL (val)) == REG)
&& ! (GET_CODE (DECL_RTL (val)) == REG
&& GET_MODE (DECL_RTL (val)) != TYPE_MODE (type)))
|| ! allows_reg
- || found_plus)
+ || is_inout)
{
if (! allows_reg)
mark_addressable (TREE_VALUE (tail));
@@ -1358,6 +1465,8 @@ expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line)
if (! allows_reg && GET_CODE (output_rtx[i]) != MEM)
error ("output number %d not directly addressable", i);
+ if (! allows_mem && GET_CODE (output_rtx[i]) == MEM)
+ error ("output number %d not restored to memory", i);
}
else
{
@@ -1365,7 +1474,7 @@ expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line)
TREE_VALUE (tail) = make_tree (type, output_rtx[i]);
}
- if (found_plus)
+ if (is_inout)
{
inout_mode[ninout] = TYPE_MODE (TREE_TYPE (TREE_VALUE (tail)));
inout_opnum[ninout++] = i;
@@ -1397,13 +1506,18 @@ expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line)
for (tail = inputs; tail; tail = TREE_CHAIN (tail))
{
int j;
- int allows_reg = 0;
+ int allows_reg = 0, allows_mem = 0;
+ char *constraint, *orig_constraint;
+ int c_len;
+ rtx op;
/* If there's an erroneous arg, emit no insn,
because the ASM_INPUT would get VOIDmode
and that could cause a crash in reload. */
if (TREE_TYPE (TREE_VALUE (tail)) == error_mark_node)
return;
+
+ /* ??? Can this happen, and does the error message make any sense? */
if (TREE_PURPOSE (tail) == NULL_TREE)
{
error ("hard register `%s' listed as input operand to `asm'",
@@ -1411,18 +1525,38 @@ expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line)
return;
}
- /* Make sure constraint has neither `=' nor `+'. */
+ c_len = TREE_STRING_LENGTH (TREE_PURPOSE (tail)) - 1;
+ constraint = TREE_STRING_POINTER (TREE_PURPOSE (tail));
+ orig_constraint = constraint;
+
+ /* Make sure constraint has neither `=', `+', nor '&'. */
- for (j = 0; j < TREE_STRING_LENGTH (TREE_PURPOSE (tail)) - 1; j++)
- switch (TREE_STRING_POINTER (TREE_PURPOSE (tail))[j])
+ for (j = 0; j < c_len; j++)
+ switch (constraint[j])
{
- case '+': case '=':
- error ("input operand constraint contains `%c'",
- TREE_STRING_POINTER (TREE_PURPOSE (tail))[j]);
- return;
+ case '+': case '=': case '&':
+ if (constraint == orig_constraint)
+ {
+ error ("input operand constraint contains `%c'", constraint[j]);
+ return;
+ }
+ break;
+
+ case '%':
+ if (constraint == orig_constraint
+ && i + 1 == ninputs - ninout)
+ {
+ error ("`%%' constraint used with last operand");
+ return;
+ }
+ break;
+
+ case 'V': case 'm': case 'o':
+ allows_mem = 1;
+ break;
- case '?': case '!': case '*': case '%': case '&':
- case 'V': case 'm': case 'o': case '<': case '>':
+ case '<': case '>':
+ case '?': case '!': case '*':
case 'E': case 'F': case 'G': case 'H': case 'X':
case 's': case 'i': case 'n':
case 'I': case 'J': case 'K': case 'L': case 'M':
@@ -1439,56 +1573,81 @@ expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line)
operands to memory. */
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
- if (TREE_STRING_POINTER (TREE_PURPOSE (tail))[j]
- >= '0' + noutputs)
+ if (constraint[j] >= '0' + noutputs)
{
error
("matching constraint references invalid operand number");
return;
}
+ /* Try and find the real constraint for this dup. */
+ if ((j == 0 && c_len == 1)
+ || (j == 1 && c_len == 2 && constraint[0] == '%'))
+ {
+ tree o = outputs;
+ for (j = constraint[j] - '0'; j > 0; --j)
+ o = TREE_CHAIN (o);
+
+ c_len = TREE_STRING_LENGTH (TREE_PURPOSE (o)) - 1;
+ constraint = TREE_STRING_POINTER (TREE_PURPOSE (o));
+ j = 0;
+ break;
+ }
+
/* ... fall through ... */
- case 'p': case 'g': case 'r':
+ case 'p': case 'r':
default:
allows_reg = 1;
break;
+
+ case 'g':
+ allows_reg = 1;
+ allows_mem = 1;
+ break;
}
- if (! allows_reg)
+ if (! allows_reg && allows_mem)
mark_addressable (TREE_VALUE (tail));
- XVECEXP (body, 3, i) /* argvec */
- = expand_expr (TREE_VALUE (tail), NULL_RTX, VOIDmode, 0);
- if (CONSTANT_P (XVECEXP (body, 3, i))
- && ! general_operand (XVECEXP (body, 3, i),
- TYPE_MODE (TREE_TYPE (TREE_VALUE (tail)))))
+ op = expand_expr (TREE_VALUE (tail), NULL_RTX, VOIDmode, 0);
+
+ if (asm_operand_ok (op, constraint) <= 0)
{
if (allows_reg)
- XVECEXP (body, 3, i)
- = force_reg (TYPE_MODE (TREE_TYPE (TREE_VALUE (tail))),
- XVECEXP (body, 3, i));
+ op = force_reg (TYPE_MODE (TREE_TYPE (TREE_VALUE (tail))), op);
+ else if (!allows_mem)
+ warning ("asm operand %d probably doesn't match constraints", i);
+ else if (CONSTANT_P (op))
+ op = force_const_mem (TYPE_MODE (TREE_TYPE (TREE_VALUE (tail))),
+ op);
+ else if (GET_CODE (op) == REG
+ || GET_CODE (op) == SUBREG
+ || GET_CODE (op) == CONCAT)
+ {
+ tree type = TREE_TYPE (TREE_VALUE (tail));
+ rtx memloc = assign_temp (type, 1, 1, 1);
+
+ emit_move_insn (memloc, op);
+ op = memloc;
+ }
+ else if (GET_CODE (op) == MEM && MEM_VOLATILE_P (op))
+ /* We won't recognize volatile memory as available a
+ memory_operand at this point. Ignore it. */
+ ;
+ else if (queued_subexp_p (op))
+ ;
else
- XVECEXP (body, 3, i)
- = force_const_mem (TYPE_MODE (TREE_TYPE (TREE_VALUE (tail))),
- XVECEXP (body, 3, i));
+ /* ??? Leave this only until we have experience with what
+ happens in combine and elsewhere when constraints are
+ not satisfied. */
+ warning ("asm operand %d probably doesn't match constraints", i);
}
+ XVECEXP (body, 3, i) = op;
- if (! allows_reg
- && (GET_CODE (XVECEXP (body, 3, i)) == REG
- || GET_CODE (XVECEXP (body, 3, i)) == SUBREG
- || GET_CODE (XVECEXP (body, 3, i)) == CONCAT))
- {
- tree type = TREE_TYPE (TREE_VALUE (tail));
- rtx memloc = assign_temp (type, 1, 1, 1);
-
- emit_move_insn (memloc, XVECEXP (body, 3, i));
- XVECEXP (body, 3, i) = memloc;
- }
-
XVECEXP (body, 4, i) /* constraints */
= gen_rtx_ASM_INPUT (TYPE_MODE (TREE_TYPE (TREE_VALUE (tail))),
- TREE_STRING_POINTER (TREE_PURPOSE (tail)));
+ orig_constraint);
i++;
}
@@ -1620,13 +1779,10 @@ expand_expr_stmt (exp)
exp = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (exp)), exp);
last_expr_type = TREE_TYPE (exp);
- if (flag_syntax_only && ! expr_stmts_for_value)
- last_expr_value = 0;
- else
- last_expr_value = expand_expr (exp,
- (expr_stmts_for_value
- ? NULL_RTX : const0_rtx),
- VOIDmode, 0);
+ last_expr_value = expand_expr (exp,
+ (expr_stmts_for_value
+ ? NULL_RTX : const0_rtx),
+ VOIDmode, 0);
/* If all we do is reference a volatile value in memory,
copy it to a register to be sure it is actually touched. */
@@ -1642,12 +1798,12 @@ expand_expr_stmt (exp)
rtx lab = gen_label_rtx ();
/* Compare the value with itself to reference it. */
- emit_cmp_insn (last_expr_value, last_expr_value, EQ,
- expand_expr (TYPE_SIZE (last_expr_type),
- NULL_RTX, VOIDmode, 0),
- BLKmode, 0,
- TYPE_ALIGN (last_expr_type) / BITS_PER_UNIT);
- emit_jump_insn ((*bcc_gen_fctn[(int) EQ]) (lab));
+ emit_cmp_and_jump_insns (last_expr_value, last_expr_value, EQ,
+ expand_expr (TYPE_SIZE (last_expr_type),
+ NULL_RTX, VOIDmode, 0),
+ BLKmode, 0,
+ TYPE_ALIGN (last_expr_type) / BITS_PER_UNIT,
+ lab);
emit_label (lab);
}
}
@@ -2000,6 +2156,7 @@ expand_end_loop ()
{
rtx start_label = loop_stack->data.loop.start_label;
rtx insn = get_last_insn ();
+ int needs_end_jump = 1;
/* Mark the continue-point at the top of the loop if none elsewhere. */
if (start_label == loop_stack->data.loop.continue_label)
@@ -2007,9 +2164,77 @@ expand_end_loop ()
do_pending_stack_adjust ();
- /* If optimizing, perhaps reorder the loop. If the loop starts with
- a loop exit, roll that to the end where it will optimize together
- with the jump back.
+ /* If optimizing, perhaps reorder the loop.
+ First, try to use a condjump near the end.
+ expand_exit_loop_if_false ends loops with unconditional jumps,
+ like this:
+
+ if (test) goto label;
+ optional: cleanup
+ goto loop_stack->data.loop.end_label
+ barrier
+ label:
+
+ If we find such a pattern, we can end the loop earlier. */
+
+ if (optimize
+ && GET_CODE (insn) == CODE_LABEL
+ && LABEL_NAME (insn) == NULL
+ && GET_CODE (PREV_INSN (insn)) == BARRIER)
+ {
+ rtx label = insn;
+ rtx jump = PREV_INSN (PREV_INSN (label));
+
+ if (GET_CODE (jump) == JUMP_INSN
+ && GET_CODE (PATTERN (jump)) == SET
+ && SET_DEST (PATTERN (jump)) == pc_rtx
+ && GET_CODE (SET_SRC (PATTERN (jump))) == LABEL_REF
+ && (XEXP (SET_SRC (PATTERN (jump)), 0)
+ == loop_stack->data.loop.end_label))
+ {
+ rtx prev;
+
+ /* The test might be complex and reference LABEL multiple times,
+ like the loop in loop_iterations to set vtop. To handle this,
+ we move LABEL. */
+ insn = PREV_INSN (label);
+ reorder_insns (label, label, start_label);
+
+ for (prev = PREV_INSN (jump); ; prev = PREV_INSN (prev))
+ {
+ /* We ignore line number notes, but if we see any other note,
+ in particular NOTE_INSN_BLOCK_*, NOTE_INSN_EH_REGION_*,
+ NOTE_INSN_LOOP_*, we disable this optimization. */
+ if (GET_CODE (prev) == NOTE)
+ {
+ if (NOTE_LINE_NUMBER (prev) < 0)
+ break;
+ continue;
+ }
+ if (GET_CODE (prev) == CODE_LABEL)
+ break;
+ if (GET_CODE (prev) == JUMP_INSN)
+ {
+ if (GET_CODE (PATTERN (prev)) == SET
+ && SET_DEST (PATTERN (prev)) == pc_rtx
+ && GET_CODE (SET_SRC (PATTERN (prev))) == IF_THEN_ELSE
+ && (GET_CODE (XEXP (SET_SRC (PATTERN (prev)), 1))
+ == LABEL_REF)
+ && XEXP (XEXP (SET_SRC (PATTERN (prev)), 1), 0) == label)
+ {
+ XEXP (XEXP (SET_SRC (PATTERN (prev)), 1), 0)
+ = start_label;
+ emit_note_after (NOTE_INSN_LOOP_END, prev);
+ needs_end_jump = 0;
+ }
+ break;
+ }
+ }
+ }
+ }
+
+ /* If the loop starts with a loop exit, roll that to the end where
+ it will optimize together with the jump back.
We look for the conditional branch to the exit, except that once
we find such a branch, we don't look past 30 instructions.
@@ -2036,6 +2261,7 @@ expand_end_loop ()
code, terminating in a test. */
if (optimize
+ && needs_end_jump
&&
! (GET_CODE (insn) == JUMP_INSN
&& GET_CODE (PATTERN (insn)) == SET
@@ -2219,8 +2445,11 @@ expand_end_loop ()
}
}
- emit_jump (start_label);
- emit_note (NULL_PTR, NOTE_INSN_LOOP_END);
+ if (needs_end_jump)
+ {
+ emit_jump (start_label);
+ emit_note (NULL_PTR, NOTE_INSN_LOOP_END);
+ }
emit_label (loop_stack->data.loop.end_label);
POPSTACK (loop_stack);
@@ -2296,6 +2525,14 @@ expand_exit_loop_if_false (whichloop, cond)
return 1;
}
+/* Return nonzero if the loop nest is empty. Else return zero. */
+
+int
+stmt_loop_nest_empty ()
+{
+ return (loop_stack == NULL);
+}
+
/* Return non-zero if we should preserve sub-expressions as separate
pseudos. We never do so if we aren't optimizing. We always do so
if -fexpensive-optimizations.
@@ -2551,32 +2788,10 @@ expand_return (retval)
return;
}
- /* For tail-recursive call to current function,
- just jump back to the beginning.
- It's unsafe if any auto variable in this function
- has its address taken; for simplicity,
- require stack frame to be empty. */
- if (optimize && retval_rhs != 0
- && get_frame_size () == 0
- && TREE_CODE (retval_rhs) == CALL_EXPR
- && TREE_CODE (TREE_OPERAND (retval_rhs, 0)) == ADDR_EXPR
- && TREE_OPERAND (TREE_OPERAND (retval_rhs, 0), 0) == current_function_decl
- /* Finish checking validity, and if valid emit code
- to set the argument variables for the new call. */
- && tail_recursion_args (TREE_OPERAND (retval_rhs, 1),
- DECL_ARGUMENTS (current_function_decl)))
- {
- if (tail_recursion_label == 0)
- {
- tail_recursion_label = gen_label_rtx ();
- emit_label_after (tail_recursion_label,
- tail_recursion_reentry);
- }
- emit_queue ();
- expand_goto_internal (NULL_TREE, tail_recursion_label, last_insn);
- emit_barrier ();
- return;
- }
+ /* Attempt to optimize the call if it is tail recursive. */
+ if (optimize_tail_recursion (retval_rhs, last_insn))
+ return;
+
#ifdef HAVE_return
/* This optimization is safe if there are local cleanups
because expand_null_return takes care of them.
@@ -2658,7 +2873,8 @@ expand_return (retval)
int big_endian_correction = 0;
int bytes = int_size_in_bytes (TREE_TYPE (retval_rhs));
int n_regs = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
- int bitsize = MIN (TYPE_ALIGN (TREE_TYPE (retval_rhs)),BITS_PER_WORD);
+ int bitsize = MIN (TYPE_ALIGN (TREE_TYPE (retval_rhs)),
+ (unsigned int)BITS_PER_WORD);
rtx *result_pseudos = (rtx *) alloca (sizeof (rtx) * n_regs);
rtx result_reg, src = NULL_RTX, dst = NULL_RTX;
rtx result_val = expand_expr (retval_rhs, NULL_RTX, VOIDmode, 0);
@@ -2780,6 +2996,49 @@ drop_through_at_end_p ()
return insn && GET_CODE (insn) != BARRIER;
}
+/* Test CALL_EXPR to determine if it is a potential tail recursion call
+ and emit code to optimize the tail recursion. LAST_INSN indicates where
+ to place the jump to the tail recursion label. Return TRUE if the
+ call was optimized into a goto.
+
+ This is only used by expand_return, but expand_call is expected to
+ use it soon. */
+
+int
+optimize_tail_recursion (call_expr, last_insn)
+ tree call_expr;
+ rtx last_insn;
+{
+ /* For tail-recursive call to current function,
+ just jump back to the beginning.
+ It's unsafe if any auto variable in this function
+ has its address taken; for simplicity,
+ require stack frame to be empty. */
+ if (optimize && call_expr != 0
+ && frame_offset == 0
+ && TREE_CODE (call_expr) == CALL_EXPR
+ && TREE_CODE (TREE_OPERAND (call_expr, 0)) == ADDR_EXPR
+ && TREE_OPERAND (TREE_OPERAND (call_expr, 0), 0) == current_function_decl
+ /* Finish checking validity, and if valid emit code
+ to set the argument variables for the new call. */
+ && tail_recursion_args (TREE_OPERAND (call_expr, 1),
+ DECL_ARGUMENTS (current_function_decl)))
+ {
+ if (tail_recursion_label == 0)
+ {
+ tail_recursion_label = gen_label_rtx ();
+ emit_label_after (tail_recursion_label,
+ tail_recursion_reentry);
+ }
+ emit_queue ();
+ expand_goto_internal (NULL_TREE, tail_recursion_label, last_insn);
+ emit_barrier ();
+ return 1;
+ }
+
+ return 0;
+}
+
/* Emit code to alter this function's formal parms for a tail-recursive call.
ACTUALS is a list of actual parameter expressions (chain of TREE_LISTs).
FORMALS is the chain of decls of formals.
@@ -2994,6 +3253,171 @@ remember_end_note (block)
last_block_end_note = NULL_RTX;
}
+/* Emit a handler label for a nonlocal goto handler.
+ Also emit code to store the handler label in SLOT before BEFORE_INSN. */
+
+static rtx
+expand_nl_handler_label (slot, before_insn)
+ rtx slot, before_insn;
+{
+ rtx insns;
+ rtx handler_label = gen_label_rtx ();
+
+ /* Don't let jump_optimize delete the handler. */
+ LABEL_PRESERVE_P (handler_label) = 1;
+
+ start_sequence ();
+ emit_move_insn (slot, gen_rtx_LABEL_REF (Pmode, handler_label));
+ insns = get_insns ();
+ end_sequence ();
+ emit_insns_before (insns, before_insn);
+
+ emit_label (handler_label);
+
+ return handler_label;
+}
+
+/* Emit code to restore vital registers at the beginning of a nonlocal goto
+ handler. */
+static void
+expand_nl_goto_receiver ()
+{
+#ifdef HAVE_nonlocal_goto
+ if (! HAVE_nonlocal_goto)
+#endif
+ /* First adjust our frame pointer to its actual value. It was
+ previously set to the start of the virtual area corresponding to
+ the stacked variables when we branched here and now needs to be
+ adjusted to the actual hardware fp value.
+
+ Assignments are to virtual registers are converted by
+ instantiate_virtual_regs into the corresponding assignment
+ to the underlying register (fp in this case) that makes
+ the original assignment true.
+ So the following insn will actually be
+ decrementing fp by STARTING_FRAME_OFFSET. */
+ emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx);
+
+#if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
+ if (fixed_regs[ARG_POINTER_REGNUM])
+ {
+#ifdef ELIMINABLE_REGS
+ /* If the argument pointer can be eliminated in favor of the
+ frame pointer, we don't need to restore it. We assume here
+ that if such an elimination is present, it can always be used.
+ This is the case on all known machines; if we don't make this
+ assumption, we do unnecessary saving on many machines. */
+ static struct elims {int from, to;} elim_regs[] = ELIMINABLE_REGS;
+ size_t i;
+
+ for (i = 0; i < sizeof elim_regs / sizeof elim_regs[0]; i++)
+ if (elim_regs[i].from == ARG_POINTER_REGNUM
+ && elim_regs[i].to == HARD_FRAME_POINTER_REGNUM)
+ break;
+
+ if (i == sizeof elim_regs / sizeof elim_regs [0])
+#endif
+ {
+ /* Now restore our arg pointer from the address at which it
+ was saved in our stack frame.
+ If there hasn't be space allocated for it yet, make
+ some now. */
+ if (arg_pointer_save_area == 0)
+ arg_pointer_save_area
+ = assign_stack_local (Pmode, GET_MODE_SIZE (Pmode), 0);
+ emit_move_insn (virtual_incoming_args_rtx,
+ /* We need a pseudo here, or else
+ instantiate_virtual_regs_1 complains. */
+ copy_to_reg (arg_pointer_save_area));
+ }
+ }
+#endif
+
+#ifdef HAVE_nonlocal_goto_receiver
+ if (HAVE_nonlocal_goto_receiver)
+ emit_insn (gen_nonlocal_goto_receiver ());
+#endif
+}
+
+/* Make handlers for nonlocal gotos taking place in the function calls in
+ block THISBLOCK. */
+
+static void
+expand_nl_goto_receivers (thisblock)
+ struct nesting *thisblock;
+{
+ tree link;
+ rtx afterward = gen_label_rtx ();
+ rtx insns, slot;
+ rtx label_list;
+ int any_invalid;
+
+ /* Record the handler address in the stack slot for that purpose,
+ during this block, saving and restoring the outer value. */
+ if (thisblock->next != 0)
+ for (slot = nonlocal_goto_handler_slots; slot; slot = XEXP (slot, 1))
+ {
+ rtx save_receiver = gen_reg_rtx (Pmode);
+ emit_move_insn (XEXP (slot, 0), save_receiver);
+
+ start_sequence ();
+ emit_move_insn (save_receiver, XEXP (slot, 0));
+ insns = get_insns ();
+ end_sequence ();
+ emit_insns_before (insns, thisblock->data.block.first_insn);
+ }
+
+ /* Jump around the handlers; they run only when specially invoked. */
+ emit_jump (afterward);
+
+ /* Make a separate handler for each label. */
+ link = nonlocal_labels;
+ slot = nonlocal_goto_handler_slots;
+ label_list = NULL_RTX;
+ for (; link; link = TREE_CHAIN (link), slot = XEXP (slot, 1))
+ /* Skip any labels we shouldn't be able to jump to from here,
+ we generate one special handler for all of them below which just calls
+ abort. */
+ if (! DECL_TOO_LATE (TREE_VALUE (link)))
+ {
+ rtx lab;
+ lab = expand_nl_handler_label (XEXP (slot, 0),
+ thisblock->data.block.first_insn);
+ label_list = gen_rtx_EXPR_LIST (VOIDmode, lab, label_list);
+
+ expand_nl_goto_receiver ();
+
+ /* Jump to the "real" nonlocal label. */
+ expand_goto (TREE_VALUE (link));
+ }
+
+ /* A second pass over all nonlocal labels; this time we handle those
+ we should not be able to jump to at this point. */
+ link = nonlocal_labels;
+ slot = nonlocal_goto_handler_slots;
+ any_invalid = 0;
+ for (; link; link = TREE_CHAIN (link), slot = XEXP (slot, 1))
+ if (DECL_TOO_LATE (TREE_VALUE (link)))
+ {
+ rtx lab;
+ lab = expand_nl_handler_label (XEXP (slot, 0),
+ thisblock->data.block.first_insn);
+ label_list = gen_rtx_EXPR_LIST (VOIDmode, lab, label_list);
+ any_invalid = 1;
+ }
+
+ if (any_invalid)
+ {
+ expand_nl_goto_receiver ();
+ emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "abort"), 0,
+ VOIDmode, 0);
+ emit_barrier ();
+ }
+
+ nonlocal_goto_handler_labels = label_list;
+ emit_label (afterward);
+}
+
/* Generate RTL code to terminate a binding contour.
VARS is the chain of VAR_DECL nodes
for the variables bound in this contour.
@@ -3044,7 +3468,7 @@ expand_end_bindings (vars, mark_ends, dont_jump_in)
emit_label (thisblock->exit_label);
}
- /* If necessary, make a handler for nonlocal gotos taking
+ /* If necessary, make handlers for nonlocal gotos taking
place in the function calls in this block. */
if (function_call_count != thisblock->data.block.n_function_calls
&& nonlocal_labels
@@ -3055,119 +3479,7 @@ expand_end_bindings (vars, mark_ends, dont_jump_in)
special to do when you jump out of it. */
: (thisblock->data.block.cleanups != 0
|| thisblock->data.block.stack_level != 0)))
- {
- tree link;
- rtx afterward = gen_label_rtx ();
- rtx handler_label = gen_label_rtx ();
- rtx save_receiver = gen_reg_rtx (Pmode);
- rtx insns;
-
- /* Don't let jump_optimize delete the handler. */
- LABEL_PRESERVE_P (handler_label) = 1;
-
- /* Record the handler address in the stack slot for that purpose,
- during this block, saving and restoring the outer value. */
- if (thisblock->next != 0)
- {
- emit_move_insn (nonlocal_goto_handler_slot, save_receiver);
-
- start_sequence ();
- emit_move_insn (save_receiver, nonlocal_goto_handler_slot);
- insns = get_insns ();
- end_sequence ();
- emit_insns_before (insns, thisblock->data.block.first_insn);
- }
-
- start_sequence ();
- emit_move_insn (nonlocal_goto_handler_slot,
- gen_rtx_LABEL_REF (Pmode, handler_label));
- insns = get_insns ();
- end_sequence ();
- emit_insns_before (insns, thisblock->data.block.first_insn);
-
- /* Jump around the handler; it runs only when specially invoked. */
- emit_jump (afterward);
- emit_label (handler_label);
-
-#ifdef HAVE_nonlocal_goto
- if (! HAVE_nonlocal_goto)
-#endif
- /* First adjust our frame pointer to its actual value. It was
- previously set to the start of the virtual area corresponding to
- the stacked variables when we branched here and now needs to be
- adjusted to the actual hardware fp value.
-
- Assignments are to virtual registers are converted by
- instantiate_virtual_regs into the corresponding assignment
- to the underlying register (fp in this case) that makes
- the original assignment true.
- So the following insn will actually be
- decrementing fp by STARTING_FRAME_OFFSET. */
- emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx);
-
-#if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
- if (fixed_regs[ARG_POINTER_REGNUM])
- {
-#ifdef ELIMINABLE_REGS
- /* If the argument pointer can be eliminated in favor of the
- frame pointer, we don't need to restore it. We assume here
- that if such an elimination is present, it can always be used.
- This is the case on all known machines; if we don't make this
- assumption, we do unnecessary saving on many machines. */
- static struct elims {int from, to;} elim_regs[] = ELIMINABLE_REGS;
- size_t i;
-
- for (i = 0; i < sizeof elim_regs / sizeof elim_regs[0]; i++)
- if (elim_regs[i].from == ARG_POINTER_REGNUM
- && elim_regs[i].to == HARD_FRAME_POINTER_REGNUM)
- break;
-
- if (i == sizeof elim_regs / sizeof elim_regs [0])
-#endif
- {
- /* Now restore our arg pointer from the address at which it
- was saved in our stack frame.
- If there hasn't be space allocated for it yet, make
- some now. */
- if (arg_pointer_save_area == 0)
- arg_pointer_save_area
- = assign_stack_local (Pmode, GET_MODE_SIZE (Pmode), 0);
- emit_move_insn (virtual_incoming_args_rtx,
- /* We need a pseudo here, or else
- instantiate_virtual_regs_1 complains. */
- copy_to_reg (arg_pointer_save_area));
- }
- }
-#endif
-
-#ifdef HAVE_nonlocal_goto_receiver
- if (HAVE_nonlocal_goto_receiver)
- emit_insn (gen_nonlocal_goto_receiver ());
-#endif
-
- /* The handler expects the desired label address in the static chain
- register. It tests the address and does an appropriate jump
- to whatever label is desired. */
- for (link = nonlocal_labels; link; link = TREE_CHAIN (link))
- /* Skip any labels we shouldn't be able to jump to from here. */
- if (! DECL_TOO_LATE (TREE_VALUE (link)))
- {
- rtx not_this = gen_label_rtx ();
- rtx this = gen_label_rtx ();
- do_jump_if_equal (static_chain_rtx,
- gen_rtx_LABEL_REF (Pmode, DECL_RTL (TREE_VALUE (link))),
- this, 0);
- emit_jump (not_this);
- emit_label (this);
- expand_goto (TREE_VALUE (link));
- emit_label (not_this);
- }
- /* If label is not recognized, abort. */
- emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "abort"), 0,
- VOIDmode, 0);
- emit_barrier ();
- emit_label (afterward);
- }
+ expand_nl_goto_receivers (thisblock);
/* Don't allow jumping into a block that has a stack level.
Cleanups are allowed, though. */
@@ -3221,7 +3533,7 @@ expand_end_bindings (vars, mark_ends, dont_jump_in)
{
emit_stack_restore (thisblock->next ? SAVE_BLOCK : SAVE_FUNCTION,
thisblock->data.block.stack_level, NULL_RTX);
- if (nonlocal_goto_handler_slot != 0)
+ if (nonlocal_goto_handler_slots != 0)
emit_stack_save (SAVE_NONLOCAL, &nonlocal_goto_stack_level,
NULL_RTX);
}
@@ -3308,7 +3620,7 @@ expand_decl (decl)
/* An initializer is going to decide the size of this array.
Until we know the size, represent its address with a reg. */
DECL_RTL (decl) = gen_rtx_MEM (BLKmode, gen_reg_rtx (Pmode));
- MEM_IN_STRUCT_P (DECL_RTL (decl)) = AGGREGATE_TYPE_P (type);
+ MEM_SET_IN_STRUCT_P (DECL_RTL (decl), AGGREGATE_TYPE_P (type));
}
else if (DECL_MODE (decl) != BLKmode
/* If -ffloat-store, don't put explicit float vars
@@ -3319,7 +3631,7 @@ expand_decl (decl)
&& ! TREE_ADDRESSABLE (decl)
&& (DECL_REGISTER (decl) || ! obey_regdecls)
/* if -fcheck-memory-usage, check all variables. */
- && ! flag_check_memory_usage)
+ && ! current_function_check_memory_usage)
{
/* Automatic variable that can go in a register. */
int unsignedp = TREE_UNSIGNED (type);
@@ -3357,13 +3669,9 @@ expand_decl (decl)
oldaddr = XEXP (DECL_RTL (decl), 0);
}
- DECL_RTL (decl)
- = assign_stack_temp (DECL_MODE (decl),
- ((TREE_INT_CST_LOW (DECL_SIZE (decl))
- + BITS_PER_UNIT - 1)
- / BITS_PER_UNIT),
- 1);
- MEM_IN_STRUCT_P (DECL_RTL (decl)) = AGGREGATE_TYPE_P (TREE_TYPE (decl));
+ DECL_RTL (decl) = assign_temp (TREE_TYPE (decl), 1, 1, 1);
+ MEM_SET_IN_STRUCT_P (DECL_RTL (decl),
+ AGGREGATE_TYPE_P (TREE_TYPE (decl)));
/* Set alignment we actually gave this decl. */
DECL_ALIGN (decl) = (DECL_MODE (decl) == BLKmode ? BIGGEST_ALIGNMENT
@@ -3378,7 +3686,8 @@ expand_decl (decl)
/* If this is a memory ref that contains aggregate components,
mark it as such for cse and loop optimize. */
- MEM_IN_STRUCT_P (DECL_RTL (decl)) = AGGREGATE_TYPE_P (TREE_TYPE (decl));
+ MEM_SET_IN_STRUCT_P (DECL_RTL (decl),
+ AGGREGATE_TYPE_P (TREE_TYPE (decl)));
#if 0
/* If this is in memory because of -ffloat-store,
set the volatile bit, to prevent optimizations from
@@ -3424,7 +3733,8 @@ expand_decl (decl)
/* If this is a memory ref that contains aggregate components,
mark it as such for cse and loop optimize. */
- MEM_IN_STRUCT_P (DECL_RTL (decl)) = AGGREGATE_TYPE_P (TREE_TYPE (decl));
+ MEM_SET_IN_STRUCT_P (DECL_RTL (decl),
+ AGGREGATE_TYPE_P (TREE_TYPE (decl)));
/* Indicate the alignment we actually gave this variable. */
#ifdef STACK_BOUNDARY
@@ -3757,7 +4067,7 @@ expand_anon_union_decl (decl, cleanup, decl_elts)
else
{
DECL_RTL (decl_elt) = gen_rtx_MEM (mode, copy_rtx (XEXP (x, 0)));
- MEM_IN_STRUCT_P (DECL_RTL (decl_elt)) = MEM_IN_STRUCT_P (x);
+ MEM_COPY_ATTRIBUTES (DECL_RTL (decl_elt), x);
RTX_UNCHANGING_P (DECL_RTL (decl_elt)) = RTX_UNCHANGING_P (x);
}
}
@@ -3951,7 +4261,7 @@ expand_start_case (exit_flag, expr, type, printname)
int exit_flag;
tree expr;
tree type;
- char *printname;
+ const char *printname;
{
register struct nesting *thiscase = ALLOC_NESTING ();
@@ -4926,7 +5236,7 @@ expand_end_case (orig_index)
#endif /* CASE_VALUES_THRESHOLD */
else if (TREE_INT_CST_HIGH (range) != 0
- || count < CASE_VALUES_THRESHOLD
+ || count < (unsigned int) CASE_VALUES_THRESHOLD
|| ((unsigned HOST_WIDE_INT) (TREE_INT_CST_LOW (range))
> 10 * count)
#ifndef ASM_OUTPUT_ADDR_DIFF_ELT
@@ -5046,8 +5356,8 @@ expand_end_case (orig_index)
index_expr, minval);
minval = integer_zero_node;
index = expand_expr (index_expr, NULL_RTX, VOIDmode, 0);
- emit_cmp_insn (rangertx, index, LTU, NULL_RTX, omode, 1, 0);
- emit_jump_insn (gen_bltu (default_label));
+ emit_cmp_and_jump_insns (rangertx, index, LTU, NULL_RTX,
+ omode, 1, 0, default_label);
/* Now we can safely truncate. */
index = convert_to_mode (index_mode, index, 0);
}
@@ -5216,8 +5526,8 @@ do_jump_if_equal (op1, op2, label, unsignedp)
enum machine_mode mode = GET_MODE (op1);
if (mode == VOIDmode)
mode = GET_MODE (op2);
- emit_cmp_insn (op1, op2, EQ, NULL_RTX, mode, unsignedp, 0);
- emit_jump_insn (gen_beq (label));
+ emit_cmp_and_jump_insns (op1, op2, EQ, NULL_RTX, mode, unsignedp,
+ 0, label);
}
}
@@ -5625,10 +5935,6 @@ emit_case_nodes (index, node, default_label, index_type)
/* If INDEX has an unsigned type, we must make unsigned branches. */
int unsignedp = TREE_UNSIGNED (index_type);
typedef rtx rtx_fn ();
- rtx_fn *gen_bgt_pat = unsignedp ? gen_bgtu : gen_bgt;
- rtx_fn *gen_bge_pat = unsignedp ? gen_bgeu : gen_bge;
- rtx_fn *gen_blt_pat = unsignedp ? gen_bltu : gen_blt;
- rtx_fn *gen_ble_pat = unsignedp ? gen_bleu : gen_ble;
enum machine_mode mode = GET_MODE (index);
/* See if our parents have already tested everything for us.
@@ -5654,20 +5960,19 @@ emit_case_nodes (index, node, default_label, index_type)
if (node_is_bounded (node->right, index_type))
{
- emit_cmp_insn (index, expand_expr (node->high, NULL_RTX,
- VOIDmode, 0),
- GT, NULL_RTX, mode, unsignedp, 0);
-
- emit_jump_insn ((*gen_bgt_pat) (label_rtx (node->right->code_label)));
+ emit_cmp_and_jump_insns (index, expand_expr (node->high, NULL_RTX,
+ VOIDmode, 0),
+ GT, NULL_RTX, mode, unsignedp, 0,
+ label_rtx (node->right->code_label));
emit_case_nodes (index, node->left, default_label, index_type);
}
else if (node_is_bounded (node->left, index_type))
{
- emit_cmp_insn (index, expand_expr (node->high, NULL_RTX,
- VOIDmode, 0),
- LT, NULL_RTX, mode, unsignedp, 0);
- emit_jump_insn ((*gen_blt_pat) (label_rtx (node->left->code_label)));
+ emit_cmp_and_jump_insns (index, expand_expr (node->high, NULL_RTX,
+ VOIDmode, 0),
+ LT, NULL_RTX, mode, unsignedp, 0,
+ label_rtx (node->left->code_label));
emit_case_nodes (index, node->right, default_label, index_type);
}
@@ -5680,10 +5985,10 @@ emit_case_nodes (index, node, default_label, index_type)
= build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
/* See if the value is on the right. */
- emit_cmp_insn (index, expand_expr (node->high, NULL_RTX,
- VOIDmode, 0),
- GT, NULL_RTX, mode, unsignedp, 0);
- emit_jump_insn ((*gen_bgt_pat) (label_rtx (test_label)));
+ emit_cmp_and_jump_insns (index, expand_expr (node->high, NULL_RTX,
+ VOIDmode, 0),
+ GT, NULL_RTX, mode, unsignedp, 0,
+ label_rtx (test_label));
/* Value must be on the left.
Handle the left-hand subtree. */
@@ -5711,10 +6016,11 @@ emit_case_nodes (index, node, default_label, index_type)
{
if (!node_has_low_bound (node, index_type))
{
- emit_cmp_insn (index, expand_expr (node->high, NULL_RTX,
- VOIDmode, 0),
- LT, NULL_RTX, mode, unsignedp, 0);
- emit_jump_insn ((*gen_blt_pat) (default_label));
+ emit_cmp_and_jump_insns (index, expand_expr (node->high,
+ NULL_RTX,
+ VOIDmode, 0),
+ LT, NULL_RTX, mode, unsignedp, 0,
+ default_label);
}
emit_case_nodes (index, node->right, default_label, index_type);
@@ -5751,10 +6057,11 @@ emit_case_nodes (index, node, default_label, index_type)
{
if (!node_has_high_bound (node, index_type))
{
- emit_cmp_insn (index, expand_expr (node->high, NULL_RTX,
- VOIDmode, 0),
- GT, NULL_RTX, mode, unsignedp, 0);
- emit_jump_insn ((*gen_bgt_pat) (default_label));
+ emit_cmp_and_jump_insns (index, expand_expr (node->high,
+ NULL_RTX,
+ VOIDmode, 0),
+ GT, NULL_RTX, mode, unsignedp, 0,
+ default_label);
}
emit_case_nodes (index, node->left, default_label, index_type);
@@ -5784,28 +6091,32 @@ emit_case_nodes (index, node, default_label, index_type)
then handle the two subtrees. */
tree test_label = 0;
- emit_cmp_insn (index, expand_expr (node->high, NULL_RTX,
- VOIDmode, 0),
- GT, NULL_RTX, mode, unsignedp, 0);
if (node_is_bounded (node->right, index_type))
/* Right hand node is fully bounded so we can eliminate any
testing and branch directly to the target code. */
- emit_jump_insn ((*gen_bgt_pat) (label_rtx (node->right->code_label)));
+ emit_cmp_and_jump_insns (index, expand_expr (node->high, NULL_RTX,
+ VOIDmode, 0),
+ GT, NULL_RTX, mode, unsignedp, 0,
+ label_rtx (node->right->code_label));
else
{
/* Right hand node requires testing.
Branch to a label where we will handle it later. */
test_label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
- emit_jump_insn ((*gen_bgt_pat) (label_rtx (test_label)));
+ emit_cmp_and_jump_insns (index, expand_expr (node->high, NULL_RTX,
+ VOIDmode, 0),
+ GT, NULL_RTX, mode, unsignedp, 0,
+ label_rtx (test_label));
}
/* Value belongs to this node or to the left-hand subtree. */
- emit_cmp_insn (index, expand_expr (node->low, NULL_RTX, VOIDmode, 0),
- GE, NULL_RTX, mode, unsignedp, 0);
- emit_jump_insn ((*gen_bge_pat) (label_rtx (node->code_label)));
+ emit_cmp_and_jump_insns (index, expand_expr (node->low, NULL_RTX,
+ VOIDmode, 0),
+ GE, NULL_RTX, mode, unsignedp, 0,
+ label_rtx (node->code_label));
/* Handle the left-hand subtree. */
emit_case_nodes (index, node->left, default_label, index_type);
@@ -5829,18 +6140,18 @@ emit_case_nodes (index, node, default_label, index_type)
if they are possible. */
if (!node_has_low_bound (node, index_type))
{
- emit_cmp_insn (index, expand_expr (node->low, NULL_RTX,
- VOIDmode, 0),
- LT, NULL_RTX, mode, unsignedp, 0);
- emit_jump_insn ((*gen_blt_pat) (default_label));
+ emit_cmp_and_jump_insns (index, expand_expr (node->low, NULL_RTX,
+ VOIDmode, 0),
+ LT, NULL_RTX, mode, unsignedp, 0,
+ default_label);
}
/* Value belongs to this node or to the right-hand subtree. */
- emit_cmp_insn (index, expand_expr (node->high, NULL_RTX,
- VOIDmode, 0),
- LE, NULL_RTX, mode, unsignedp, 0);
- emit_jump_insn ((*gen_ble_pat) (label_rtx (node->code_label)));
+ emit_cmp_and_jump_insns (index, expand_expr (node->high, NULL_RTX,
+ VOIDmode, 0),
+ LE, NULL_RTX, mode, unsignedp, 0,
+ label_rtx (node->code_label));
emit_case_nodes (index, node->right, default_label, index_type);
}
@@ -5851,17 +6162,18 @@ emit_case_nodes (index, node, default_label, index_type)
if they are possible. */
if (!node_has_high_bound (node, index_type))
{
- emit_cmp_insn (index, expand_expr (node->high, NULL_RTX,
- VOIDmode, 0),
- GT, NULL_RTX, mode, unsignedp, 0);
- emit_jump_insn ((*gen_bgt_pat) (default_label));
+ emit_cmp_and_jump_insns (index, expand_expr (node->high, NULL_RTX,
+ VOIDmode, 0),
+ GT, NULL_RTX, mode, unsignedp, 0,
+ default_label);
}
/* Value belongs to this node or to the left-hand subtree. */
- emit_cmp_insn (index, expand_expr (node->low, NULL_RTX, VOIDmode, 0),
- GE, NULL_RTX, mode, unsignedp, 0);
- emit_jump_insn ((*gen_bge_pat) (label_rtx (node->code_label)));
+ emit_cmp_and_jump_insns (index, expand_expr (node->low, NULL_RTX,
+ VOIDmode, 0),
+ GE, NULL_RTX, mode, unsignedp, 0,
+ label_rtx (node->code_label));
emit_case_nodes (index, node->left, default_label, index_type);
}
@@ -5874,18 +6186,18 @@ emit_case_nodes (index, node, default_label, index_type)
if (!node_has_high_bound (node, index_type))
{
- emit_cmp_insn (index, expand_expr (node->high, NULL_RTX,
- VOIDmode, 0),
- GT, NULL_RTX, mode, unsignedp, 0);
- emit_jump_insn ((*gen_bgt_pat) (default_label));
+ emit_cmp_and_jump_insns (index, expand_expr (node->high, NULL_RTX,
+ VOIDmode, 0),
+ GT, NULL_RTX, mode, unsignedp, 0,
+ default_label);
}
if (!node_has_low_bound (node, index_type))
{
- emit_cmp_insn (index, expand_expr (node->low, NULL_RTX,
- VOIDmode, 0),
- LT, NULL_RTX, mode, unsignedp, 0);
- emit_jump_insn ((*gen_blt_pat) (default_label));
+ emit_cmp_and_jump_insns (index, expand_expr (node->low, NULL_RTX,
+ VOIDmode, 0),
+ LT, NULL_RTX, mode, unsignedp, 0,
+ default_label);
}
emit_jump (label_rtx (node->code_label));
diff --git a/gcc/stor-layout.c b/gcc/stor-layout.c
index 8e585d81835..64d6368448e 100644
--- a/gcc/stor-layout.c
+++ b/gcc/stor-layout.c
@@ -53,8 +53,6 @@ int maximum_field_alignment;
May be overridden by front-ends. */
int set_alignment = 0;
-static enum machine_mode smallest_mode_for_size PROTO((unsigned int,
- enum mode_class));
static tree layout_record PROTO((tree));
static void layout_union PROTO((tree));
@@ -144,13 +142,13 @@ mode_for_size (size, class, limit)
{
register enum machine_mode mode;
- if (limit && size > MAX_FIXED_MODE_SIZE)
+ if (limit && size > (unsigned int)(MAX_FIXED_MODE_SIZE))
return BLKmode;
/* Get the first mode which has this size, in the specified class. */
for (mode = GET_CLASS_NARROWEST_MODE (class); mode != VOIDmode;
mode = GET_MODE_WIDER_MODE (mode))
- if (GET_MODE_BITSIZE (mode) == size)
+ if ((unsigned int)GET_MODE_BITSIZE (mode) == size)
return mode;
return BLKmode;
@@ -159,7 +157,7 @@ mode_for_size (size, class, limit)
/* Similar, but never return BLKmode; return the narrowest mode that
contains at least the requested number of bits. */
-static enum machine_mode
+enum machine_mode
smallest_mode_for_size (size, class)
unsigned int size;
enum mode_class class;
@@ -170,12 +168,43 @@ smallest_mode_for_size (size, class)
specified class. */
for (mode = GET_CLASS_NARROWEST_MODE (class); mode != VOIDmode;
mode = GET_MODE_WIDER_MODE (mode))
- if (GET_MODE_BITSIZE (mode) >= size)
+ if ((unsigned int)GET_MODE_BITSIZE (mode) >= size)
return mode;
abort ();
}
+/* Find an integer mode of the exact same size, or BLKmode on failure. */
+
+enum machine_mode
+int_mode_for_mode (mode)
+ enum machine_mode mode;
+{
+ switch (GET_MODE_CLASS (mode))
+ {
+ case MODE_INT:
+ case MODE_PARTIAL_INT:
+ break;
+
+ case MODE_COMPLEX_INT:
+ case MODE_COMPLEX_FLOAT:
+ case MODE_FLOAT:
+ mode = mode_for_size (GET_MODE_BITSIZE (mode), MODE_INT, 0);
+ break;
+
+ case MODE_RANDOM:
+ if (mode == BLKmode)
+ break;
+ /* FALLTHRU */
+
+ case MODE_CC:
+ default:
+ abort();
+ }
+
+ return mode;
+}
+
/* Return the value of VALUE, rounded up to a multiple of DIVISOR. */
tree
@@ -252,7 +281,8 @@ layout_decl (decl, known_align)
{
DECL_BIT_FIELD_TYPE (decl) = DECL_BIT_FIELD (decl) ? type : 0;
if (maximum_field_alignment != 0)
- DECL_ALIGN (decl) = MIN (DECL_ALIGN (decl), maximum_field_alignment);
+ DECL_ALIGN (decl) = MIN (DECL_ALIGN (decl),
+ (unsigned)maximum_field_alignment);
else if (DECL_PACKED (decl))
DECL_ALIGN (decl) = MIN (DECL_ALIGN (decl), BITS_PER_UNIT);
}
@@ -268,7 +298,7 @@ layout_decl (decl, known_align)
if (xmode != BLKmode
&& known_align % GET_MODE_ALIGNMENT (xmode) == 0)
{
- DECL_ALIGN (decl) = MAX (GET_MODE_ALIGNMENT (xmode),
+ DECL_ALIGN (decl) = MAX ((unsigned) GET_MODE_ALIGNMENT (xmode),
DECL_ALIGN (decl));
DECL_MODE (decl) = xmode;
DECL_SIZE (decl) = size_int (GET_MODE_BITSIZE (xmode));
@@ -382,7 +412,7 @@ layout_record (rec)
It does, however, affect the alignment of the next field
within the structure. */
if (! integer_zerop (DECL_SIZE (field)))
- record_align = MAX (record_align, desired_align);
+ record_align = MAX ((int)record_align, desired_align);
else if (! DECL_PACKED (field))
desired_align = TYPE_ALIGN (TREE_TYPE (field));
/* A named bit field of declared type `int'
@@ -395,11 +425,11 @@ layout_record (rec)
else if (DECL_PACKED (field))
type_align = MIN (type_align, BITS_PER_UNIT);
- record_align = MAX (record_align, type_align);
+ record_align = MAX ((int)record_align, type_align);
}
}
else
- record_align = MAX (record_align, desired_align);
+ record_align = MAX ((int)record_align, desired_align);
#endif
/* Does this field automatically have alignment it needs
@@ -882,7 +912,7 @@ layout_type (type)
MODE_INT, 1);
if (STRICT_ALIGNMENT && TYPE_ALIGN (type) < BIGGEST_ALIGNMENT
- && TYPE_ALIGN (type) < TREE_INT_CST_LOW (TYPE_SIZE (type))
+ && (int)TYPE_ALIGN (type) < TREE_INT_CST_LOW (TYPE_SIZE (type))
&& TYPE_MODE (type) != BLKmode)
{
TYPE_NO_FORCE_BLK (type) = 1;
@@ -948,7 +978,7 @@ layout_type (type)
then stick with BLKmode. */
if (STRICT_ALIGNMENT
&& ! (TYPE_ALIGN (type) >= BIGGEST_ALIGNMENT
- || (TYPE_ALIGN (type)
+ || ((int)TYPE_ALIGN (type)
>= TREE_INT_CST_LOW (TYPE_SIZE (type)))))
{
if (TYPE_MODE (type) != BLKmode)
@@ -980,7 +1010,7 @@ layout_type (type)
then stick with BLKmode. */
&& (! STRICT_ALIGNMENT
|| TYPE_ALIGN (type) >= BIGGEST_ALIGNMENT
- || TYPE_ALIGN (type) >= TREE_INT_CST_LOW (TYPE_SIZE (type))))
+ || (int)TYPE_ALIGN (type) >= TREE_INT_CST_LOW (TYPE_SIZE (type))))
{
tree field;
/* A union which has any BLKmode members must itself be BLKmode;
@@ -1053,6 +1083,18 @@ layout_type (type)
&& TREE_CODE (type) != ARRAY_TYPE)))
TYPE_ALIGN (type) = GET_MODE_ALIGNMENT (TYPE_MODE (type));
+ /* Do machine-dependent extra alignment. */
+#ifdef ROUND_TYPE_ALIGN
+ TYPE_ALIGN (type)
+ = ROUND_TYPE_ALIGN (type, TYPE_ALIGN (type), BITS_PER_UNIT);
+#endif
+
+#ifdef ROUND_TYPE_SIZE
+ if (TYPE_SIZE (type) != 0)
+ TYPE_SIZE (type)
+ = ROUND_TYPE_SIZE (type, TYPE_SIZE (type), TYPE_ALIGN (type));
+#endif
+
/* Evaluate nonconstant size only once, either now or as soon as safe. */
if (TYPE_SIZE (type) != 0 && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
TYPE_SIZE (type) = variable_size (TYPE_SIZE (type));
diff --git a/gcc/stupid.c b/gcc/stupid.c
index 34c9f034507..e169bd1311f 100644
--- a/gcc/stupid.c
+++ b/gcc/stupid.c
@@ -1,5 +1,5 @@
/* Dummy data flow analysis for GNU compiler in nonoptimizing mode.
- Copyright (C) 1987, 91, 94, 95, 96, 1997 Free Software Foundation, Inc.
+ Copyright (C) 1987, 91, 94-96, 1998 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -498,7 +498,7 @@ stupid_find_reg (call_preserved, class, mode,
enum reg_class class;
enum machine_mode mode;
int born_insn, dead_insn;
- int changes_size;
+ int changes_size ATTRIBUTE_UNUSED;
{
register int i, ins;
#ifdef HARD_REG_SET
@@ -520,7 +520,7 @@ stupid_find_reg (call_preserved, class, mode,
call_preserved ? call_used_reg_set : fixed_reg_set);
#ifdef ELIMINABLE_REGS
- for (i = 0; i < sizeof eliminables / sizeof eliminables[0]; i++)
+ for (i = 0; i < (int)(sizeof eliminables / sizeof eliminables[0]); i++)
SET_HARD_REG_BIT (used, eliminables[i].from);
#if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM
SET_HARD_REG_BIT (used, HARD_FRAME_POINTER_REGNUM);
diff --git a/gcc/system.h b/gcc/system.h
index 0e78de09681..7d62ed9cdba 100644
--- a/gcc/system.h
+++ b/gcc/system.h
@@ -1,14 +1,29 @@
/* system.h - Get common system includes and various definitions and
declarations based on autoconf macros.
- Copyright (C) 1998 Free Software Foundation, Inc.
+ Copyright (C) 1998, 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. */
#ifndef __GCC_SYSTEM_H__
#define __GCC_SYSTEM_H__
/* We must include stdarg.h/varargs.h before stdio.h. */
-#ifdef __STDC__
+#ifdef ANSI_PROTOTYPES
#include <stdarg.h>
#else
#include <varargs.h>
@@ -21,6 +36,31 @@
#define NULL 0
#endif
+/* The compiler is not a multi-threaded application and therefore we
+ do not have to use the locking functions.
+
+ NEED_DECLARATION_PUTC_UNLOCKED actually indicates whether or not
+ the IO code is multi-thread safe by default. If it is not declared,
+ then do not worry about using the _unlocked functions.
+
+ fputs_unlocked is an extension and needs to be prototyped specially. */
+
+#if defined HAVE_PUTC_UNLOCKED && !defined NEED_DECLARATION_PUTC_UNLOCKED
+# undef putc
+# define putc(C, Stream) putc_unlocked (C, Stream)
+#endif
+#if defined HAVE_FPUTC_UNLOCKED && !defined NEED_DECLARATION_PUTC_UNLOCKED
+# undef fputc
+# define fputc(C, Stream) fputc_unlocked (C, Stream)
+#endif
+#if defined HAVE_FPUTS_UNLOCKED && !defined NEED_DECLARATION_PUTC_UNLOCKED
+# undef fputs
+# define fputs(String, Stream) fputs_unlocked (String, Stream)
+# ifdef NEED_DECLARATION_FPUTS_UNLOCKED
+extern int fputs_unlocked PROTO ((const char *, FILE *));
+# endif
+#endif
+
#include <ctype.h>
/* Jim Meyering writes:
@@ -117,6 +157,34 @@ extern int errno;
# include <limits.h>
#endif
+/* Find HOST_WIDEST_INT and set its bit size, type and print macros.
+ It will be the largest integer mode supported by the host which may
+ (or may not) be larger than HOST_WIDE_INT. This must appear after
+ <limits.h> since we only use `long long' if its bigger than a
+ `long' and also if it is supported by macros in limits.h. For old
+ hosts which don't have a limits.h (and thus won't include it in
+ stage2 cause we don't rerun configure) we assume gcc supports long
+ long.) Note, you won't get these defined if you don't include
+ {ht}config.h before this file to set the HOST_BITS_PER_* macros. */
+
+#ifndef HOST_WIDEST_INT
+# if defined (HOST_BITS_PER_LONG) && defined (HOST_BITS_PER_LONGLONG)
+# if (HOST_BITS_PER_LONGLONG > HOST_BITS_PER_LONG) && (defined (LONG_LONG_MAX) || defined (LONGLONG_MAX) || defined (LLONG_MAX) || defined (__GNUC__))
+# define HOST_BITS_PER_WIDEST_INT HOST_BITS_PER_LONGLONG
+# define HOST_WIDEST_INT long long
+# define HOST_WIDEST_INT_PRINT_DEC "%lld"
+# define HOST_WIDEST_INT_PRINT_UNSIGNED "%llu"
+# define HOST_WIDEST_INT_PRINT_HEX "0x%llx"
+# else
+# define HOST_BITS_PER_WIDEST_INT HOST_BITS_PER_LONG
+# define HOST_WIDEST_INT long
+# define HOST_WIDEST_INT_PRINT_DEC "%ld"
+# define HOST_WIDEST_INT_PRINT_UNSIGNED "%lu"
+# define HOST_WIDEST_INT_PRINT_HEX "0x%lx"
+# endif /*(long long>long) && (LONG_LONG_MAX||LONGLONG_MAX||LLONG_MAX||GNUC)*/
+# endif /* defined(HOST_BITS_PER_LONG) && defined(HOST_BITS_PER_LONGLONG) */
+#endif /* ! HOST_WIDEST_INT */
+
#ifdef TIME_WITH_SYS_TIME
# include <sys/time.h>
# include <time.h>
@@ -156,6 +224,32 @@ extern int errno;
# define O_WRONLY 1
#endif
+/* Some systems define these in, e.g., param.h. We undefine these names
+ here to avoid the warnings. We prefer to use our definitions since we
+ know they are correct. */
+
+#undef MIN
+#undef MAX
+#define MIN(X,Y) ((X) < (Y) ? (X) : (Y))
+#define MAX(X,Y) ((X) > (Y) ? (X) : (Y))
+
+#ifdef HAVE_SYS_WAIT_H
+#include <sys/wait.h>
+#endif
+
+#ifndef WIFSIGNALED
+#define WIFSIGNALED(S) (((S) & 0xff) != 0 && ((S) & 0xff) != 0x7f)
+#endif
+#ifndef WTERMSIG
+#define WTERMSIG(S) ((S) & 0x7f)
+#endif
+#ifndef WIFEXITED
+#define WIFEXITED(S) (((S) & 0xff) == 0)
+#endif
+#ifndef WEXITSTATUS
+#define WEXITSTATUS(S) (((S) & 0xff00) >> 8)
+#endif
+
#ifndef bcopy
@@ -164,7 +258,7 @@ extern int errno;
extern void bcopy ();
# endif
# else /* ! HAVE_BCOPY */
-# define bcopy(src,dst,len) memcpy ((dst),(src),(len))
+# define bcopy(src,dst,len) memmove((dst),(src),(len))
# endif
#endif
@@ -308,7 +402,9 @@ extern void abort ();
#else
#define abort() \
(fprintf (stderr, \
- "%s:%d: Internal compiler error in function %s\n", \
+ "%s:%d: Internal compiler error in function %s\n" \
+ "Please submit a full bug report to `egcs-bugs@egcs.cygnus.com'.\n" \
+ "See <URL:http://egcs.cygnus.com/faq.html#bugreport> for details.\n", \
__FILE__, __LINE__, __PRETTY_FUNCTION__), \
exit (FATAL_EXIT_CODE))
@@ -334,9 +430,65 @@ extern void abort ();
# endif
#endif /* ! STRINGIFY */
+#if HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+
+/* Test if something is a normal file. */
+#ifndef S_ISREG
+#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
+#endif
+
+/* Test if something is a directory. */
+#ifndef S_ISDIR
+#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
+#endif
+
+/* Test if something is a character special file. */
+#ifndef S_ISCHR
+#define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
+#endif
+
+/* Test if something is a socket. */
+#ifndef S_ISSOCK
+# ifdef S_IFSOCK
+# define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK)
+# else
+# define S_ISSOCK(m) 0
+# endif
+#endif
+
+/* Test if something is a FIFO. */
+#ifndef S_ISFIFO
+# ifdef S_IFIFO
+# define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
+# else
+# define S_ISFIFO(m) 0
+# endif
+#endif
+
+/* Approximate O_NONBLOCK. */
+#ifndef O_NONBLOCK
+#define O_NONBLOCK O_NDELAY
+#endif
+
+/* Approximate O_NOCTTY. */
+#ifndef O_NOCTTY
+#define O_NOCTTY 0
+#endif
+
+/* Define well known filenos if the system does not define them. */
+#ifndef STDIN_FILENO
+# define STDIN_FILENO 0
+#endif
+#ifndef STDOUT_FILENO
+# define STDOUT_FILENO 1
+#endif
+#ifndef STDOUT_FILENO
+# define STDERR_FILENO 2
+#endif
-/* These macros are here in preparation for the use of gettext in egcs. */
-#define _(String) String
-#define N_(String) String
+/* Get libiberty declarations. */
+#include "libiberty.h"
#endif /* __GCC_SYSTEM_H__ */
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index b15599cd813..ade3278bf5a 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,452 @@
+Fri Mar 26 00:50:46 1999 Jeffrey A Law (law@cygnus.com)
+
+ * gcc.c-torture/execute/990326-1.c: New test from Charles Hannum.
+
+1999-03-26 Craig Burley <craig@jcb-sc.com>
+
+ * g77.f-torture/execute/19990325-0.f: New test.
+ * g77.f-torture/execute/19990325-1.f: New test.
+
+Wed Mar 24 22:50:50 1999 Jeffrey A Law (law@cygnus.com)
+
+ * gcc.c-torture/execute/990324-1.c: New test.
+
+1999-03-13 Craig Burley <craig@jcb-sc.com>
+
+ * g77.f-torture/execute/19990313-2.f: New test.
+ * g77.f-torture/execute/19990313-3.f: New test.
+
+1999-03-13 Craig Burley <craig@jcb-sc.com>
+
+ * g77.f-torture/execute/19990313-0.f: New test.
+ * g77.f-torture/execute/19990313-1.f: New test.
+
+1999-03-08 Craig Burley <craig@jcb-sc.com>
+
+ * g77.f-torture/execute/19981119-0.f: Improve testiness.
+
+1999-03-08 Craig Burley <craig@jcb-sc.com>
+
+ * g77.f-torture/compile/19990305-0.f: New test.
+ * g77.f-torture/execute/19981119-0.f: New test.
+
+1999-03-08 Craig Burley <craig@jcb-sc.com>
+
+ * g77.f-torture/execute/970625-2.f: call ABORT if final
+ result is not correct, instead of just printing it.
+ Add this checking via newly introduced obfuscation, to
+ trip up buggy front ends.
+
+1999-03-07 Craig Burley <craig@jcb-sc.com>
+
+ * g77.f-torture/compile/960317-1.f: Moved from being
+ in execute/. (Somehow I didn't notice "SUBROUTINE...".)
+
+1999-03-06 Craig Burley <craig@jcb-sc.com>
+
+ * g77.f-torture/execute/960317-1.f: New (old) test.
+ * g77.f-torture/execute/970625-2.f: Ditto.
+
+Mon Mar 1 23:29:14 1999 Jeffrey A Law (law@cygnus.com)
+
+ * g++.old-deja/g++.law/weak1.C: New test.
+
+1999-02-28 17:59 -0500 Zack Weinberg <zack@rabi.columbia.edu>
+
+ * gcc.c-torture/execute/990119-1.c: Renamed to...
+ * gcc.dg/990119-1.c: this, so it will only be tested once
+ (it's a preprocessor test, it doesn't need to be run at
+ multiple optimization levels).
+
+1999-02-27 13:34 -0500 Zack Weinberg <zack@rabi.columbia.edu>
+
+ * lib/g++.exp: Don't add incdir=$base_dir/../include to
+ ALWAYS_CXXFLAGS.
+
+1999-02-24 Craig Burley <craig@jcb-sc.com>
+
+ * gcc.f-torture/noncompile/19981216-0.f: Renamed from...
+ * gcc.f-torture/compile/19981216-0.f: ...as it is expected
+ to not be compilable by current g77.
+
+1999-02-24 Nick Clifton <nickc@cygnus.com>
+
+ * lib/c-torture.exp: Add -O3 to TORTURE_OPTIONS list.
+
+Mon Feb 22 01:15:08 1999 Jeffrey A Law (law@cygnus.com)
+
+ * gcc.c-torture/execute/990222-1.c: New test.
+
+1999-02-19 Craig Burley <craig@jcb-sc.com>
+
+ * g77.f-torture/compile/19990218-0.f: New test.
+ * g77.f-torture/noncompile/19990218-1.f: New test.
+
+1999-02-18 Craig Burley <craig@jcb-sc.com>
+
+ * g77.f-torture/compile/19981216-0.f: New test.
+
+Sun Feb 14 01:26:29 1999 Jeffrey A Law (law@cygnus.com)
+
+ * gcc.dg/990214-1.c: New test.
+
+Sat Feb 13 00:43:52 1999 Jeffrey A Law (law@cygnus.com)
+
+ * gcc.dg/990213-2.c: New test.
+
+ * gcc.dg/990213-1.c: New test.
+
+Fri Feb 12 11:04:35 1999 Jeffrey A Law (law@cygnus.com)
+
+ * gcc.c-torture/990106-2.c: Update to work on targets with 16bit
+ ints.
+
+1999-02-11 Nick Clifton <nickc@cygnus.com>
+
+ * lib/chill.exp: Fix typo: doesn'timeout -> doesn't
+
+Thu Feb 11 01:12:12 1999 Jeffrey A Law (law@cygnus.com)
+
+ * gcc.c-torture/execute/990211-1.c: New test from Nathan SIdwell.
+
+Wed Feb 10 13:08:12 1999 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * gcc.dg/special/ecos.exp: New test driver for new tests with
+ special requirements.
+
+ * gcc.dg/special/alias-1.c: New test.
+ * gcc.dg/special/gcsec-1.c: New test.
+ * gcc.dg/special/weak-1.c: New test.
+ * gcc.dg/special/weak-1a.c: Accompanying file to weak-1.c.
+ * gcc.dg/special/weak-2.c: New test.
+ * gcc.dg/special/weak-2a.c: Accompanying file to weak-2.c.
+ * gcc.dg/special/weak-2b.c: Accompanying file to weak-2.c.
+ * gcc.dg/special/wkali-1.c: New test.
+ * gcc.dg/special/wkali-2.c: New test.
+ * gcc.dg/special/wkali-2a.c: Accompanying file to wkali-2.c.
+ * gcc.dg/special/wkali-2b.c: Accompanying file to wkali-2.c.
+
+Wed Feb 10 12:15:35 1999 Felix Lee <flee@cygnus.com>
+
+ * lib/c-torture.exp (c-torture-compile): Pull out code for
+ analyzing gcc error messages.
+ (c-torture-execute): Likewise. Fix some (harmless) false
+ positives.
+ * lib/gcc.exp (gcc_check_compile): New function.
+
+Mon Feb 8 21:42:57 1999 Richard Henderson <rth@cygnus.com>
+
+ * gcc.c-torture/execute/990208-1.c: New test.
+
+1999-02-07 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * g++.dg/special/ecos.exp: New driver for new tests with special
+ requirements
+
+ * g++.dg/special/conpr-1.C: New test
+ * g++.dg/special/conpr-2.C: New test
+ * g++.dg/special/conpr-2a.C: New test
+ * g++.dg/special/conpr-3.C: New test
+ * g++.dg/special/conpr-3a.C: New test
+ * g++.dg/special/conpr-3b.C: New test
+
+ * lib/g++-dg.exp: New driver file, based on lib/gcc-dg.exp to
+ allow g++ to use the dg driver
+
+ * README: Add comment about g++.dg directory
+
+Sat Feb 6 18:00:38 1999 Jeffrey A Law (law@cygnus.com)
+
+ * README: Update email addresses.
+
+Sat Jan 30 16:22:47 1999 Richard Henderson <rth@cygnus.com>
+
+ * gcc.c-torture/execute/990130-1.c: New test.
+
+Sat Jan 30 11:10:06 1999 Jeffrey A Law (law@cygnus.com)
+
+ * gcc.dg/990130-1.c: New test.
+
+Sun Jan 17 00:02:33 1999 Jeffrey A Law (law@cygnus.com)
+
+ * gcc.dg/990117-1.c: New test.
+
+ * gcc.c-torture/compile/990117-1.c: New test from Horst von Brand.
+
+ * gcc.c-torture/execute/990117-1.c: New test from HJ Lu.
+
+Fri Jan 15 02:52:00 1999 Jeffrey A Law (law@cygnus.com)
+
+ * g77.f-torture/compile/990115-1.f: New test.
+
+Thu Jan 7 23:39:47 1999 Jeffrey A Law (law@cygnus.com)
+
+ * gcc.c-torture/compile/990107-1.c: New test
+
+Wed Jan 6 02:21:59 1999 Jeffrey A Law (law@cygnus.com)
+
+ * gcc.c-torture/execute/990106-2.c: New test.
+
+ * gcc.c-torture/execute/990106-1.c: New test.
+
+Wed Dec 30 23:05:28 1998 Zack Weinberg <zack@rabi.columbia.edu>
+
+ * gcc.c-torture/compile/981223-1.c: New test.
+
+Tue Dec 29 11:33:25 1998 Richard Henderson <rth@cygnus.com>
+
+ * gcc.c-torture/execute/bcp-1.c (bad10): Rename from opt3.
+ (opt3): Rename from opt4 and disable.
+
+1998-12-20 Alexandre Oliva <oliva@dcc.unicamp.br>
+
+ * g++.old-deja/g++.pt/ptrmem5.C: New test.
+
+1998-12-15 Alexandre Oliva <oliva@dcc.unicamp.br>
+
+ * g++.old-deja/g++.other/conv5.C: New test.
+
+Fri Dec 11 10:25:57 1998 Jeffrey A Law (law@cygnus.com)
+
+ * g++.old-deja/g++.benjamin/p12475.C: Expect failure on mips64 targets.
+
+Fri Dec 11 01:12:45 1998 Zack Weinberg <zack@rabi.columbia.edu>
+
+ * gcc.c-torture/compile/981211-1.c: New test.
+
+1998-12-09 Alexandre Oliva <oliva@dcc.unicamp.br>
+
+ * gcc.dg/ultrasp1.c: empty dg-options, avoid `long long' warnings
+
+ * g++.old-deja/g++.pt/instantiate6.C: linker error, not crash
+
+Tue Dec 8 22:50:04 1998 Franz Sirl <Franz.Sirl-kernel@lauterbach.com>
+
+ * gcc.special/930510-1.c: Make C9X safe.
+ * gcc.misc-tests/gcov-1.c Similarly.
+ * gcc.misc-tests/gcov-2.c Similarly.
+
+1998-12-06 Alexandre Oliva <oliva@dcc.unicamp.br>
+
+ * gcc.dg/ultrasp1.c: New test.
+
+Sun Dec 6 00:40:12 1998 Richard Henderson <rth@cygnus.com>
+
+ * gcc.c-torture/execute/981206.c: New test.
+
+1998-12-06 Alexandre Oliva <oliva@dcc.unicamp.br>
+
+ * g++.old-deja/g++.ns/template7.C: New test.
+
+ * g++.old-deja/g++.other/expr1.C: New test.
+
+ * g++.old-deja/g++.eh/tmpl3.C: New test.
+
+ * g++.old-deja/g++.eh/tmpl2.C: New test.
+
+1998-12-04 Alexandre Oliva <oliva@dcc.unicamp.br>
+
+ * g++.old-deja/g++.other/using5.C: usified using[567].C here
+ * g++.old-deja/g++.other/using6.C: removed
+ * g++.old-deja/g++.other/using7.C: Mark Mitchel removed it
+
+ * g++.old-deja/g++.pt/spec20.C: Re-insert non-bogus ERROR marks.
+
+1998-12-03 Alexandre Oliva <oliva@dcc.unicamp.br>
+
+ * g++.old-deja/g++.pt/overload8.C: New test.
+
+ * g++.old-deja/g++.pt/overload7.C: New test.
+
+ * g++.old-deja/g++.pt/spec20.C: ERROR marks were bogus
+
+ * lib/old-dejagnu.exp (old-dejagnu): ignore collect recompiling
+ and relinking messages
+ * lib/g++.exp (g++_target_compile): remove .rpo file when
+ compiling with -frepo
+
+1998-12-01 Alexandre Oliva <oliva@dcc.unicamp.br>
+
+ * g++.old-deja/g++.pt/lookup6.C: New test.
+
+1998-11-27 Alexandre Oliva <oliva@dcc.unicamp.br>
+
+ * g++.old-deja/g++.pt/explicit76.C: New test.
+
+ * g++.old-deja/g++.pt/friend38.C: New test.
+
+ * g++.old-deja/g++.ns/crash2.C: New test.
+
+ * g++.old-deja/g++.pt/defarg8.C: New test.
+
+ * g++.old-deja/g++.pt/instantiate6.C: New test.
+
+ * g++.old-deja/g++.pt/static6.C: New test.
+
+ * g++.old-deja/g++.pt/decl2.C: New test.
+
+1998-11-26 Alexandre Oliva <oliva@dcc.unicamp.br>
+
+ * g++.old-deja/g++.other/lookup5.C: New test. Not sure the
+ problem is actually related with name lookup, but so what? :-)
+
+ * g++.old-deja/g++.pt/friend37.C: New test.
+
+1998-11-25 Dave Love <d.love@dl.ac.uk>
+
+ * g77.f-torture/execute/u77-test.f (main): Avoid testing [f]statb
+ element, which fails on some systems.
+
+ * g77.f-torture/execute/labug1.f: New test.
+
+Sat Nov 21 21:41:05 1998 Jeffrey A Law (law@cygnus.com)
+
+ * gcc.c-torture/execute/980526-1.c: Do nothing if NO_LABEL_VALUES
+ is defined.
+
+1998-11-18 Dave Love <d.love@dl.ac.uk>
+
+ * g77.f-torture/compile/981117-1.f: New test.
+
+1998-11-16 Alexandre Oliva <oliva@dcc.unicamp.br>
+
+ * g++.old-deja/g++.eh/throw2.C: New test. CV-qualifiers are not
+ properly discarded.
+
+1998-11-07 Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at>
+
+ * README: New file, general information about the testsuite and
+ new description of the various C++ test subdirectories.
+ * README.g++: Eliminate obsolete information, update and move most
+ relevant stuff to README.
+
+Sat Nov 7 02:55:55 1998 Richard Henderson <rth@cygnus.com>
+
+ * gcc.c-torture/compile/981107-1.c: New test.
+
+Mon Nov 2 11:16:03 1998 Doug Evans <devans@canuck.cygnus.com>
+
+ * execute/memcpy-bi.c: New testcase.
+
+1998-10-31 Alexandre Oliva <oliva@dcc.unicamp.br>
+
+ * g++.old-deja/g++.pt/sizeof3.C: a similar testcase not involving
+ base classes
+
+ * g++.old-deja/g++.pt/sizeof2.C: incorrect specialization of base
+ template is selected
+
+ * g++.old-deja/g++.ext/arrnew2.C: if new T[n](i) is accepted for
+ classes, it should be accepted for all types.
+
+ * g++.old-deja/g++.eh/sjlj1.C: test checked sjlj-exception
+
+ * g++.old-deja/g++.pt/spec24.C: ensure that template
+ specializations start with template headers
+
+1998-10-29 Alexandre Oliva <oliva@dcc.unicamp.br>
+
+ * g++.old-deja/g++.other/dcast2.C: cannot dynamic downcast &x
+
+ * g++.old-deja/g++.other/init9.C: test cross initialization of
+ non-POD types
+
+1998-10-27 Alexandre Oliva <oliva@dcc.unicamp.br>
+
+ * lib/old-dejagnu.exp (old-dejagnu): document `Additional sources'
+
+Thu Oct 22 16:01:44 1998 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * compile/981022-1.c, compile/981022-1.x: New test and driver.
+
+Mon Oct 19 14:03:07 1998 Jeffrey A Law (law@cygnus.com)
+
+ * 981019-1.c: New test.
+
+Wed Oct 14 21:11:19 1998 Robert Lipe <robertl@dgii.com>
+
+ * lib/objc-torture.exp (objc-torture-execute): Add -I so we can
+ find objc headers.
+
+1998-10-14 Andreas Schwab <schwab@issan.cs.uni-dortmund.de>
+
+ * compile/981001-4.c: Remove use of GCC extension that triggers a
+ compiler bug.
+
+1998-10-13 Alexandre Oliva <oliva@dcc.unicamp.br>
+
+ * lib/old-dejagnu.exp (old-dejagnu): support `Additional sources:'
+
+1998-10-12 Alexandre Oliva <oliva@dcc.unicamp.br>
+
+ * g++.old-deja/g++.pt/explicit74.C: New test. Explicit
+ instantiation of template produces incorrect code for delete
+ expression.
+
+ * g++.old-deja/g++.pt/instantiate5.C: New test. `global
+ constructors' name is not unique
+ * g++.old-deja/g++.pt/instantiate5.cc: ditto
+ * g++.old-deja/g++.pt/instantiate5-main.cc: ditto
+
+ * g++.old-deja/g++.other/init8.C: New test. uninitialized
+ automatic array of const is ill-formed
+
+ * g++.old-deja/g++.pt/ttp53.C: New test. incorrect substitution
+ of template parameter?
+
+ * g++.old-deja/g++.other/conv3.C: New test. conversion discards
+ const
+
+ * g++.old-deja/g++.other/pmf2.C: New test. invalid
+ pointer-to-member expression
+
+ * g++.old-deja/g++.other/friend5.C: New test. bogus friend
+ declaration causes ICE
+
+1998-10-11 Alexandre Oliva <oliva@dcc.unicamp.br>
+
+ * g++.old-deja/g++.ns/main1.C: New test. main() should only be
+ reserved in the global namespace
+
+ * g++.old-deja/g++.pt/instantiate4.C: New test: -frepo does not
+ generate needed virtual table
+
+ * lib/old-dejagnu.exp (old-dejagnu): support `Build then link:'
+
+1998-10-10 Dariush Eslimi <eslimi@loran.com>
+
+ * g++.old-deja/g++.ext/typeof1.C: New test; typeof based on
+ template-dependent type
+
+1998-10-10 Alexandre Oliva <oliva@dcc.unicamp.br>
+
+ * g++.old-deja/g++.brendan/parse3.C: XFAILs, not ERRORs
+ * g++.old-deja/g++.brendan/parse5.C: XFAILs, not ERRORs
+ * g++.old-deja/g++.brendan/parse6.C: XFAILs, not ERRORs
+
+ * g++.old-deja/g++.other/using5.C: New test; using decl from base
+ class should be usable as argument of member function
+ * g++.old-deja/g++.other/using6.C: New test; using decl from base
+ class should be usable as return type of member function
+ * g++.old-deja/g++.other/using7.C: New test; using decl from base
+ class should be usable as type of data member
+
+ * g++.old-deja/g++.ns/extern1.C: fix XFAIL mark
+
+Fri Oct 9 19:19:19 1998 Jeffrey A Law (law@cygnus.com)
+
+ * gcc.c-torture/special/920521-1.c: Fix bogus test.
+
+Thu Oct 8 19:14:05 1998 Nick Clifton <nickc@cygnus.com>
+
+ * gcc.dg/dll-?.c Add thumb to target list.
+ Fix assembler scan patterns to match current assembler output.
+
1998-10-08 Alexandre Oliva <oliva@dcc.unicamp.br>
+ * g++.old-deja/g++.pt/expr6.C: New test. operator?: breaks
+ matching of template brackets.
+
* g++.old-deja/g++.other/using4.C: New test. Test using
declarations of methods from base classes.
diff --git a/gcc/testsuite/README.g++ b/gcc/testsuite/README.g++
index 833d5ed603b..640ab2e9282 100644
--- a/gcc/testsuite/README.g++
+++ b/gcc/testsuite/README.g++
@@ -1,64 +1,2 @@
-This file needs a little updating, but is pretty close. Here are some
-random last minute notes:
-
-make check and make check-g++ aren't in FSF's gcc yet, I am planning
-on getting this work into the tree some time...
-
-> and the command
-
-> runtest --tool g++ --srcdir ./testsuite
-
-> doesn't work. I got it to work by explicitly setting CXX and CXXFLAGS
-> on the command line, e.g.
-
-> runtest --tool g++ --srcdir ./testsuite CXX=g++ CXXFLAGS=""
-
-site.exp updated to have right CXXFLAGS and CXX, but not at the FSF yet.
-
-
- This is a collection of tests for g++, the FSF's C++ compiler. The
-driver that runs the testsuite is called DejaGnu. If you do not have
-DejaGnu yet, you will need to get it (ftp://ftp.cygnus.com/pub/dejagnu).
-You will need a snapshot of DejaGnu of 02/21/97 or later. The tests
-were developed and/or collected by Cygnus Support. These tests are
-included "as is". If any of the tests fail, don't report a bug. Bug
-reports for DejaGnu can go to bug-dejagnu@prep.ai.mit.edu. Discussion
-and comments about this testsuite can be sent to me, at the address
-below.
-
- Since these are part of the development source tree at Cygnus, this
-tar file is supposed to be untarred so that the testsuite directory is
-in the gcc source tree. Most of the time DejaGnu is run by hand using
-"runtest", but as we believe in solid testing, we've integrated it
-into the Makefile as a target. We normally use the testsuite by doing
-a "make all; make check-g++" at the top level and building and testing
-our whole tree. If you have both the gcc testsuite and the g++
-testsuite, you can check both with the "make check" command.
-
- DejaGnu can be run either installed, or uninstalled. Usually it gets
-installed so that anyone can just run the tests without having to
-configure or build DejaGnu.
-
- To run the tests, first change to the gcc-2.7.1 directory, then type:
-
- runtest --tool g++ --srcdir ./testsuite
-
-Here's a brief explanation.
-
-runtest - Is the name used to invoke DejaGnu. If DejaGnu is not
- install this will be the relative path name for runtest.
-
---tool - This tells DejaGnu which tool you are testing. It is
- mainly used to find the testsuite directories for a
- particular tool when several testsuites are in the
- same directory. (like the gcc and g++ testsuites)
-
---srcdir - This points to the top level of the directory
- containing the sources of the testsuite. This is
- ./testsuite if you are in the directory that has the
- testsuite directory.
-
-
- Mike Stump
- mrs@cygnus.com
- FSF C++ developer
+Here are some random last minute notes by this file's original maintainer,
+Mike Stump <mrs@cygnus.com>:
diff --git a/gcc/testsuite/g++.old-deja/g++.benjamin/p12475.C b/gcc/testsuite/g++.old-deja/g++.benjamin/p12475.C
index 6e911a384bc..4f9d8b55730 100644
--- a/gcc/testsuite/g++.old-deja/g++.benjamin/p12475.C
+++ b/gcc/testsuite/g++.old-deja/g++.benjamin/p12475.C
@@ -2,4 +2,4 @@
// prms-id: 12475
// excess errors test - XFAIL alpha*-*-* mips64*-*-*
-enum huh { start =-2147483648, next }; // WARNING - , XFAIL sparc64-*-* alpha*-*-*
+enum huh { start =-2147483648, next }; // WARNING - , XFAIL sparc64-*-* alpha*-*-* mips64*-*-*
diff --git a/gcc/testsuite/g++.old-deja/g++.benjamin/p15561.C b/gcc/testsuite/g++.old-deja/g++.benjamin/p15561.C
deleted file mode 100644
index 3dedd0c5bad..00000000000
--- a/gcc/testsuite/g++.old-deja/g++.benjamin/p15561.C
+++ /dev/null
@@ -1,194 +0,0 @@
-//980418 bkoz reduced from kumar's g++/15561
-// Build don't link:
-// prms-id: 15561
-
-extern int errno;
-extern int write (int, const void *, long unsigned int ) ;
-
-/* to debug
-#ifdef BUG
-*/
-//this crashes
-typedef long unsigned int size_t;
-//typedef unsigned long size_t;
-//this is ok
-//typedef unsigned int size_t;
-
-class exception {
-public:
- exception () { }
- virtual ~exception () { }
- virtual const char* what () const;
-};
-
-class bad_alloc : public exception {
-public:
- virtual const char* what() const throw() { return "bad_alloc"; }
-};
-
-struct nothrow_t {};
-extern const nothrow_t nothrow;
-
-typedef void (*new_handler)();
-new_handler set_new_handler (new_handler);
-
-void *operator new (size_t) throw (std::bad_alloc);
-void *operator new[] (size_t) throw (std::bad_alloc);
-void operator delete (void *) throw();
-void operator delete[] (void *) throw();
-void *operator new (size_t, const nothrow_t&) throw();
-void *operator new[] (size_t, const nothrow_t&) throw();
-void operator delete (void *, const nothrow_t&) throw();
-void operator delete[] (void *, const nothrow_t&) throw();
-inline void *operator new(size_t, void *place) throw() { return place; }
-inline void *operator new[](size_t, void *place) throw() { return place; }
-
-/* to debug
-#else
-#include <new>
-#endif
-*/
-
-//from kumar's ace file
-typedef unsigned long u_long;
-typedef int ACE_thread_t;
-typedef int ACE_hthread_t;
-typedef int ACE_thread_key_t;
-typedef int ssize_t;
-typedef int ACE_HANDLE;
-typedef ACE_HANDLE ACE_SOCKET;
-
-struct ACE_OVERLAPPED
-{
- u_long Internal;
- u_long InternalHigh;
- u_long Offset;
- u_long OffsetHigh;
- ACE_HANDLE hEvent;
-};
-
-struct strbuf {
- int maxlen;
- int len;
- char *buf;
-};
-
-struct flock {
- short l_type;
- short l_whence;
- long l_start;
- long l_len;
- short l_pid;
- short l_xxx;
-};
-
-class ACE_OS
-{
-public:
- struct ace_flock_t
- {
- void dump (void) const;
- struct flock lock_;
- ACE_HANDLE handle_;
- };
- static ssize_t write (ACE_HANDLE handle,
- const void *buf,
- size_t nbyte);
- static ssize_t write (ACE_HANDLE handle,
- const void *buf,
- size_t nbyte,
- ACE_OVERLAPPED *);
-
- static void *memcpy (void *t,
- const void *s,
- size_t len);
-
- static int putmsg (ACE_HANDLE handle,
- const struct strbuf *ctl,
- const struct strbuf *data,
- int flags);
-
- static ACE_thread_t NULL_thread;
- static ACE_hthread_t NULL_hthread;
- static ACE_thread_key_t NULL_key;
- static void mutex_lock_cleanup (void *mutex);
-private:
- ACE_OS (void);
-};
-
-
-
-inline ssize_t
-ACE_OS::write (ACE_HANDLE handle, const void *buf, size_t nbyte)
-{
- do {
- ssize_t ace_result_ = -1 ;
- ace_result_ = ace_result_;
- return ::write (handle, buf, nbyte) ; } while (0) ;
-}
-
-inline ssize_t
-ACE_OS::write (ACE_HANDLE handle, const void *buf, size_t nbyte,
- ACE_OVERLAPPED *overlapped)
-{
- overlapped = overlapped;
- return ACE_OS::write (handle, buf, nbyte);
-}
-
-
-inline int
-ACE_OS::putmsg (ACE_HANDLE handle, const struct strbuf *ctl,
- const struct strbuf *data, int flags)
-{
- {
- if (& flags )
- ;
- } ;
- if (ctl == 0 && data == 0)
- {
- errno = 22 ;
- return 0;
- }
-
- else if (ctl != 0)
- return ACE_OS::write (handle, ctl->buf, ctl->len);
- else if (data != 0)
- return ACE_OS::write (handle, data->buf, data->len);
- else
- {
- char *buf;
- do
- {
- buf = new char [ctl->len + data->len] ;
- if ( buf == 0)
- {
- errno = 12 ;
- return -1 ;
- }
- }
- while (0) ;
- ACE_OS::memcpy (buf, ctl->buf, ctl->len);
- ACE_OS::memcpy (buf + ctl->len, data->buf, data->len);
- int result = ACE_OS::write (handle, buf, ctl->len + data->len);
- delete [] buf;
- return result;
- }
-}
-
-int main()
-{
- return (1);
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/gcc/testsuite/g++.old-deja/g++.benjamin/tem03.C b/gcc/testsuite/g++.old-deja/g++.benjamin/tem03.C
index b74e2640203..abb956f8797 100644
--- a/gcc/testsuite/g++.old-deja/g++.benjamin/tem03.C
+++ b/gcc/testsuite/g++.old-deja/g++.benjamin/tem03.C
@@ -83,7 +83,7 @@ public:
template <class T10, int i> struct Xfour {// ERROR - .*
int T10; // ERROR - .*
void f(){
- char T10; // ERROR - .*
+ char T10;
}
};
diff --git a/gcc/testsuite/g++.old-deja/g++.benjamin/tem06.C b/gcc/testsuite/g++.old-deja/g++.benjamin/tem06.C
index 9fcd6301caa..e55ee6aafb4 100644
--- a/gcc/testsuite/g++.old-deja/g++.benjamin/tem06.C
+++ b/gcc/testsuite/g++.old-deja/g++.benjamin/tem06.C
@@ -19,7 +19,7 @@ void blah (const T &) {
x (4);
};
-main () {
+int main () {
const foo<int> v;
blah (v);
}
diff --git a/gcc/testsuite/g++.old-deja/g++.benjamin/typedef01.C b/gcc/testsuite/g++.old-deja/g++.benjamin/typedef01.C
index 179740d556c..ba6af18b632 100644
--- a/gcc/testsuite/g++.old-deja/g++.benjamin/typedef01.C
+++ b/gcc/testsuite/g++.old-deja/g++.benjamin/typedef01.C
@@ -40,12 +40,7 @@ struct S {
typedef struct S T;
S a = T(); // OK
-struct T * p; // error
+struct T * p; // ERROR - using typedef after struct
//case01
typedef bool short;// ERROR - .*
-
-
-
-
-
diff --git a/gcc/testsuite/g++.old-deja/g++.benjamin/warn02.C b/gcc/testsuite/g++.old-deja/g++.benjamin/warn02.C
index a60a2d7e150..e63d43cbec9 100644
--- a/gcc/testsuite/g++.old-deja/g++.benjamin/warn02.C
+++ b/gcc/testsuite/g++.old-deja/g++.benjamin/warn02.C
@@ -31,16 +31,16 @@ class C
class D
{
public:
- int foo2() {return b;} // WARNING -
- int foo2() {return b;} // WARNING -
+ int foo2() {return b;}
+ int foo2() {return b;} // ERROR -
int b;
};
class E
{
public:
- int foo2(); // WARNING -
- int foo2(); // WARNING -
+ int foo2();
+ int foo2(); // ERROR -
int b;
};
diff --git a/gcc/testsuite/g++.old-deja/g++.bob/inherit1.C b/gcc/testsuite/g++.old-deja/g++.bob/inherit1.C
index 4e77de34884..765014bc66d 100644
--- a/gcc/testsuite/g++.old-deja/g++.bob/inherit1.C
+++ b/gcc/testsuite/g++.old-deja/g++.bob/inherit1.C
@@ -1,25 +1 @@
-// Build don't link:
-class A {
-char str[10];
-public:
- char* m1 () { return str;};
-};
-
-class C : public A {
-public:
-};
-
-class B : public A {
-public:
- char* m1 () { C::m1(); return ""; } // ERROR -
-};
-
-main () {
-A a;
-B b;
-C c;
-
-a.m1();
-c.m1();
-b.m1();
-}
+int main () {
diff --git a/gcc/testsuite/g++.old-deja/g++.bob/packed1.C b/gcc/testsuite/g++.old-deja/g++.bob/packed1.C
index 27ae03e4a05..b5287f33795 100644
--- a/gcc/testsuite/g++.old-deja/g++.bob/packed1.C
+++ b/gcc/testsuite/g++.old-deja/g++.bob/packed1.C
@@ -1,16 +1 @@
-main() {
- struct s
- {
- int a;
- short b;
- } __attribute__((packed)) t;
-
- if (sizeof (t) != (sizeof(int)+sizeof(short)))
- {
- return 1;
- }
- else
- {
- return 0;
- }
-}
+int
diff --git a/gcc/testsuite/g++.old-deja/g++.bob/protected1.C b/gcc/testsuite/g++.old-deja/g++.bob/protected1.C
index e83f3e40b73..b5287f33795 100644
--- a/gcc/testsuite/g++.old-deja/g++.bob/protected1.C
+++ b/gcc/testsuite/g++.old-deja/g++.bob/protected1.C
@@ -1,41 +1 @@
-// Build don't link:
-class A {
-public:
- int i;
- A(int j) : i(j){}
-};
-
-class B : protected A {
-public:
- B(int j) : A(j){}
- void f(){
- A k(*this);
- }
-};
-
-class C : protected B {
-public:
- C(int j) : B(j){}
- void f();
-
- void g(){
- A k(i);
- }
-};
-
-
-class D : public C {
-public:
- D(int w) : C(i) {}
- void j() { A k(*this); }
- void h() { i=3; }
-};
-
-void C::f() {
- A k(*this);
-}
-
-B b(3);
-main() {
- A *z = &b; // ERROR -
-}
+int
diff --git a/gcc/testsuite/g++.old-deja/g++.bob/template3.C b/gcc/testsuite/g++.old-deja/g++.bob/template3.C
index 17378425a26..b5287f33795 100644
--- a/gcc/testsuite/g++.old-deja/g++.bob/template3.C
+++ b/gcc/testsuite/g++.old-deja/g++.bob/template3.C
@@ -1,48 +1 @@
-// Build don't link:
-// prms-id: 9979
-
-template < class Referencee >
-class Referencer
-{
-public:
- Referencer() {}
-};
-
-template <class T>
-class List
-{
-public:
- List() {}
-};
-
-template<class T, class KEY>
-class Dictionary
-{
-public:
- Dictionary() : i_buckets (new List<T>[1234]) {}
- ~Dictionary() { delete [] i_buckets; }
-
- List<T> * i_buckets;
-};
-
-class Exchangeable {};
-class ExchangeableHandle {};
-
-class ExchangeableList
- : public Dictionary<Referencer<Exchangeable>, ExchangeableHandle>
-{
-public:
- ExchangeableList(int size=0);
-};
-
-class ObjectExchange
-{
-public:
- ObjectExchange() {};
-
- ExchangeableList i_theWatchList; // Instruments being monitored
-};
-
-main()
-{
-}
+int
diff --git a/gcc/testsuite/g++.old-deja/g++.bob/template4.C b/gcc/testsuite/g++.old-deja/g++.bob/template4.C
index 8d86fa37ab6..b5287f33795 100644
--- a/gcc/testsuite/g++.old-deja/g++.bob/template4.C
+++ b/gcc/testsuite/g++.old-deja/g++.bob/template4.C
@@ -1,20 +1 @@
-// prms-id: 10166
-
-template <class A>
-class B {
- public:
- int f() {
- for(int x=0;x<10;x++) {
- continue;
- return 1;
- }
- return 0;
- }
- private:
- A w;
-};
-
-main() {
- B<int> c;
- return c.f();
-}
+int
diff --git a/gcc/testsuite/g++.old-deja/g++.brendan/README b/gcc/testsuite/g++.old-deja/g++.brendan/README
index 81119572caa..e69de29bb2d 100644
--- a/gcc/testsuite/g++.old-deja/g++.brendan/README
+++ b/gcc/testsuite/g++.old-deja/g++.brendan/README
@@ -1,41 +0,0 @@
-Note: nest4 misses a syntax error
-
-abstract - abstract functions
-alignof - gcc alignof builtin
-ambiguity - diagnosing ambiguities
-arm - ARM cases
-array-refs - arrays of references
-bit-fields - bit fields
-chainon - deaths cuz we call chainon() incorrectly
-copy - copy constructors
-crash - old compiler crashes/aborts
-cvt - user-defined conversions
-def-fns - default function generation (in add'n to copy)
-enum-clash - int vs enum
-enum - enumerated types
-err-msg - error messages
-friend - dealing with friend functions and classes
-groff - crashes derived from groff code
-init - initialization bugs
-label - handling labels
-line - line numbers in error messages
-misc - miscellaneous tests that didn't fit another category
-nest - nested types
-new-array - doing new of an array
-new - generic operator new bugs
-operators - tests for various overloaded operators
-parse - parser bugs
-prepost - prefix/postfix operator ++/--
-ptolemy - bugs derived from ptolemy
-recurse - infinite recursion in the compiler
-redecl - handling redeclarations
-scope - managing scopes
-shadow - shadowing of params, etc
-sizeof - ARM compliance w/ sizeof operator
-sorry - old "sorry, not implemented" messages
-static - handling static data
-template - template bugs
-union - handling unions
-visibility - access control and visibility checking
-warnings - warning messages
-
diff --git a/gcc/testsuite/g++.old-deja/g++.brendan/arm1.C b/gcc/testsuite/g++.old-deja/g++.brendan/arm1.C
index 74091f8cce5..b5287f33795 100644
--- a/gcc/testsuite/g++.old-deja/g++.brendan/arm1.C
+++ b/gcc/testsuite/g++.old-deja/g++.brendan/arm1.C
@@ -1,10 +1 @@
-// Build don't link:
-// Special g++ Options: -pedantic-errors
-// GROUPS passed ARM-compliance
-// ARM $5.7, it's illegal to do math on a `void*'.
-
-main()
-{
- void *p;
- ++p;// ERROR - .*
-}
+int
diff --git a/gcc/testsuite/g++.old-deja/g++.brendan/bit-fields2.C b/gcc/testsuite/g++.old-deja/g++.brendan/bit-fields2.C
index dae2726b89c..9f32b32bf36 100644
--- a/gcc/testsuite/g++.old-deja/g++.brendan/bit-fields2.C
+++ b/gcc/testsuite/g++.old-deja/g++.brendan/bit-fields2.C
@@ -1,13 +1,3 @@
-// Build don't link:
-// GROUPS passed bit-fields
- struct {
- char c;
- int i:8;
- } s;
-
- main()
- {
- int &ir = s.i;
- int *ip = &s.i;// ERROR - .* , XFAIL *-*-*
- ir = 10;
- }
+ int main()
+ int &ir = s.i; // ERROR - address of bitfield
+ int *ip = &s.i; // ERROR - address of bitfield
diff --git a/gcc/testsuite/g++.old-deja/g++.brendan/bool1.C b/gcc/testsuite/g++.old-deja/g++.brendan/bool1.C
index bab925521ce..b5287f33795 100644
--- a/gcc/testsuite/g++.old-deja/g++.brendan/bool1.C
+++ b/gcc/testsuite/g++.old-deja/g++.brendan/bool1.C
@@ -1,11 +1 @@
-// Build don't link:
-// GROUPS passed boolean
-main()
-{
- typedef char Boolean; // Instrinsic.h
- Boolean c = false;
- bool b = true;
-
- if (!c != !b)
- ;
-}
+int
diff --git a/gcc/testsuite/g++.old-deja/g++.brendan/copy1.C b/gcc/testsuite/g++.old-deja/g++.brendan/copy1.C
index 38242fbb8be..b5287f33795 100644
--- a/gcc/testsuite/g++.old-deja/g++.brendan/copy1.C
+++ b/gcc/testsuite/g++.old-deja/g++.brendan/copy1.C
@@ -1,21 +1 @@
-// GROUPS passed copy-ctors
-extern "C" void printf (char *, ...);
-int count = 0;
-
-class C {
-public:
- C (int) { count++; }
- operator int () { return 0; }
-};
-
-
-main ()
-{
- C c1 (1);
- C c2 (c1);
-
- if (count != 1)
- printf ("FAIL\n");
- else
- printf ("PASS\n");
-}
+int
diff --git a/gcc/testsuite/g++.old-deja/g++.brendan/copy2.C b/gcc/testsuite/g++.old-deja/g++.brendan/copy2.C
index 9f93755dae4..b5287f33795 100644
--- a/gcc/testsuite/g++.old-deja/g++.brendan/copy2.C
+++ b/gcc/testsuite/g++.old-deja/g++.brendan/copy2.C
@@ -1,79 +1 @@
-// GROUPS passed copy-ctors
-/*
-The old g++ output is
-
-Item()
-Compound()
-Pre foo
-foo
-~Compound()
-~Item()
-Post foo
-~Compound()
-~Item()
-
-The output should be something like (produced from ATT 2.1)
-
-Item()
-Compound()
-Pre foo
-Item(const Item& i) <------ missing above
-foo
-~Compound()
-~Item()
-Post foo
-~Compound()
-~Item()
-
-*/
-
-extern "C" void printf (char *, ...);
-extern "C" void exit (int);
-
-int count = 0;
-
-void
-die (int x)
-{
- if (x != ++count)
- {
- printf ("FAIL\n");
- exit (1);
- }
-}
-
-
-class Item {
- public:
- Item() { die (1); }
- Item(const Item& i) { die (4); }
- ~Item() { count++; if (count != 7 && count != 10) die (-1); }
-};
-
-
-class Compound {
- Item i;
- public:
- Compound() { die (2); }
- ~Compound() { count++; if (count != 6 && count != 9) die (-1); }
-};
-
-
-void foo(Compound a)
-{
- die (5);
-}
-
-
-main()
-{
- Compound a;
-
- die (3);
- foo(a);
-
- die (8);
-
- printf ("PASS\n");
-}
-
+int
diff --git a/gcc/testsuite/g++.old-deja/g++.brendan/copy3.C b/gcc/testsuite/g++.old-deja/g++.brendan/copy3.C
index 28b3306433b..b5287f33795 100644
--- a/gcc/testsuite/g++.old-deja/g++.brendan/copy3.C
+++ b/gcc/testsuite/g++.old-deja/g++.brendan/copy3.C
@@ -1,57 +1 @@
-// GROUPS passed copy-ctors
-/*
-
-If I compile it with cfront (AT&T C++ Translator 2.00.02 08/25/89) and run it
-I get:
-
- A::A()
- A::A(const A&)
- B::Bar()
- A::~A()
- A::~A()
-
-If I compile it with g++ (gcc version 2.2.2) and run it I get:
-
- A::A()
- B::Bar()
- A::~A()
- A::~A()
-
-*/
-extern "C" void printf (char *, ...);
-extern "C" void exit (int);
-
-int count = 0;
-
-void
-die (int x)
-{
- if (x != ++count)
- {
- printf ("FAIL\n");
- exit (1);
- }
-}
-
-
-class A {
-public:
- A() { die (1); }
- A(const A&) { die (2); }
- ~A() { count++; if (count != 4 && count != 5) die (-1); }
-};
-
-class B : public A {
-public:
- void Bar() { die (3); }
-};
-
-void Foo(B b) { b.Bar(); }
-
-main()
-{
- B b;
- Foo(b);
-
- printf ("PASS\n");
-}
+int
diff --git a/gcc/testsuite/g++.old-deja/g++.brendan/copy5.C b/gcc/testsuite/g++.old-deja/g++.brendan/copy5.C
index db63d75925b..b5287f33795 100644
--- a/gcc/testsuite/g++.old-deja/g++.brendan/copy5.C
+++ b/gcc/testsuite/g++.old-deja/g++.brendan/copy5.C
@@ -1,84 +1 @@
-// GROUPS passed copy-ctors
-/*
-bad:
-sibelius402> a.out
-a=5 a.virtMember()=30
-BaseClass::Increm --> {i=5, virtMember()=30}
-a=7 a.virtMember()=30
-b=7 b.virtMember()=30
-BaseClass::Increm --> {i=7, virtMember()=999}
-b=9 b.virtMember()=30
-sibelius403>
-
- good:
-
-sibelius406> a.out
-a=5 a.virtMember()=30
-BaseClass::Increm --> {i=5, virtMember()=30}
-a=7 a.virtMember()=30
-b=7 b.virtMember()=30
-BaseClass::Increm --> {i=7, virtMember()=30}
-b=9 b.virtMember()=30
-*/
-
-extern "C" void printf (char *, ...);
-extern "C" void exit (int);
-
-void die () { printf ("FAIL\n"); exit (1); }
-
-class BaseClass {
-
- friend int operator != (const BaseClass irv, int x);
-
- int i;
-
-public:
-
- BaseClass( const BaseClass& ir ) : i(ir.i) {};
- BaseClass() : i(5) {};
-
- virtual int virtMember() { return( 999 ); };
-
- void Increm( int r );
-};
-
-void BaseClass::Increm( int r )
-{
- if ((i == 5 && virtMember () == 30)
- || (i == 7 && virtMember () == 30))
- i += r;
- else
- die ();
-};
-
-class DerivedClass : public BaseClass {
-public:
- int virtMember() { return( 30 ); };
-};
-
-int operator != (const BaseClass irv, int x) { return irv.i != x; }
-
-main ()
-{
- DerivedClass a;
-
- if (a != 5 || a.virtMember () != 30)
- die ();
-
- a.Increm(2);
-
- if (a != 7 || a.virtMember () != 30)
- die ();
-
- DerivedClass b = a;
-
- if (b != 7 || a.virtMember () != 30)
- die ();
-
- b.Increm(2);
-
- if (b != 9 || a.virtMember () != 30)
- die ();
-
- printf ("PASS\n");
-}
+int
diff --git a/gcc/testsuite/g++.old-deja/g++.brendan/copy7.C b/gcc/testsuite/g++.old-deja/g++.brendan/copy7.C
index c98d77f6d12..b5287f33795 100644
--- a/gcc/testsuite/g++.old-deja/g++.brendan/copy7.C
+++ b/gcc/testsuite/g++.old-deja/g++.brendan/copy7.C
@@ -1,29 +1 @@
-// GROUPS passed copy-ctors
-extern "C" void printf (char *, ...);
-extern "C" void exit (int);
-
-void die () { printf ("FAIL\n"); exit (1); }
-
-class B {
-public:
- B() {}
- B(const B &) { printf ("PASS\n"); exit (0); };
-private:
- int x;
-};
-
-class A : public B {
-public:
- A() {}
-
- A(const B &) { printf ("FAIL\n"); exit (1); }
-};
-
-main()
-{
- A a;
- A b(a);
-
- printf ("FAIL\n");
- return 0;
-}
+int
diff --git a/gcc/testsuite/g++.old-deja/g++.brendan/copy9.C b/gcc/testsuite/g++.old-deja/g++.brendan/copy9.C
index 9c5114a322f..b5287f33795 100644
--- a/gcc/testsuite/g++.old-deja/g++.brendan/copy9.C
+++ b/gcc/testsuite/g++.old-deja/g++.brendan/copy9.C
@@ -1,40 +1 @@
-// GROUPS passed copy-ctors
-#include <iostream.h>
-
-// token types: from state parser
-const int T_EOF = 257;
-const int T_ERROR = 258;
-const int T_Float = 259;
-const int T_Int = 260;
-const int T_ID = 261;
-const int T_STRING = 262;
-
-class Complex;
-class State;
-
-// token, from state parser.
-class ParseToken {
-public:
- int tok;
- union {
- char cval;
- const char *sval;
- int intval;
- double doubleval;
- Complex* Complexval;
- const State* s;
- };
- ParseToken () { tok = 0; intval = 0;}
-};
-
-main () {
- ParseToken a;
- a.tok = T_Float;
- a.doubleval = 23.2;
- ParseToken b(a);
-
- if (b.doubleval == 23.2)
- cout << "PASS\n";
- else
- cout << "FAIL\n";
-}
+int
diff --git a/gcc/testsuite/g++.old-deja/g++.brendan/crash11.C b/gcc/testsuite/g++.old-deja/g++.brendan/crash11.C
index f03953ab20e..f655fbeecff 100644
--- a/gcc/testsuite/g++.old-deja/g++.brendan/crash11.C
+++ b/gcc/testsuite/g++.old-deja/g++.brendan/crash11.C
@@ -1,23 +1,3 @@
-// Build don't link:
-// GROUPS passed old-abort
-extern "C" void printf (char *, ...);
-
-class A {
- int i;
- int j;
- public:
- int h;
- A() { i=10; j=20; }
- virtual void f1() { printf("i=%d j=%d\n",i,j); }
- friend virtual void f2() { printf("i=%d j=%d\n",i,j); }// ERROR - virtual.*
-};
-
-class B : public A {
- public:
- virtual void f1() { printf("i=%d j=%d\n",i,j); }// ERROR - member.*// ERROR - member.*
- friend virtual void f2() { printf("i=%d j=%d\n",i,j); }// ERROR - virtual.*// ERROR - member.*// ERROR - member.*
-};
-
-main() {
- A * a = new A;
-}
+ int i; // ERROR - private
+ int j; // ERROR - private
+int
diff --git a/gcc/testsuite/g++.old-deja/g++.brendan/crash13.C b/gcc/testsuite/g++.old-deja/g++.brendan/crash13.C
index a292d67f235..b5287f33795 100644
--- a/gcc/testsuite/g++.old-deja/g++.brendan/crash13.C
+++ b/gcc/testsuite/g++.old-deja/g++.brendan/crash13.C
@@ -1,35 +1 @@
-// Build don't link:
-// GROUPS passed old-abort
-class gen_op
-{
-public:
- gen_op ( );
- gen_op (const gen_op &Op1);
- ~gen_op ( );
- void operator = (const gen_op &Op1);
-};
-
-
-
-
-class spin_op
-{
-public:
- spin_op();
- spin_op(const spin_op& SOp);
- ~spin_op();
- void operator= (const spin_op& SOp);
- operator gen_op();
-};
-
-
-spin_op Fe();
-
-
-gen_op Spul_U_axis()
-{
- gen_op U1;
- U1 = Fe();
-}; // ERROR - reaches end of non-void function
-
-main () {};
+int
diff --git a/gcc/testsuite/g++.old-deja/g++.brendan/crash14.C b/gcc/testsuite/g++.old-deja/g++.brendan/crash14.C
index d7a0de482f9..b5287f33795 100644
--- a/gcc/testsuite/g++.old-deja/g++.brendan/crash14.C
+++ b/gcc/testsuite/g++.old-deja/g++.brendan/crash14.C
@@ -1,23 +1 @@
-// Build don't link:
-// GROUPS passed old-abort
-extern "C" void printf (char *, ...);
-
-
-class cl
-{
- int i;
-public:
- cl(int j = 0) {i = j;}
- int get_i() {return i;}
- };
-
-main()
-{
- cl ob[3] = {1, 2, 3};
- int i;
-
- for(i=0; i<3; i++)
- printf("%d\n", ob[i].get_i());
-
- return 0;
- }
+int
diff --git a/gcc/testsuite/g++.old-deja/g++.brendan/crash15.C b/gcc/testsuite/g++.old-deja/g++.brendan/crash15.C
index a4b1ffabee3..b5287f33795 100644
--- a/gcc/testsuite/g++.old-deja/g++.brendan/crash15.C
+++ b/gcc/testsuite/g++.old-deja/g++.brendan/crash15.C
@@ -1,21 +1 @@
-// Build don't link:
-// GROUPS passed old-abort
-#include <iostream.h>
-
-class A {
- public:
- virtual ~A() {cout << "executed ~A()\n";};
-};
-
-class B : public A {
- public:
- virtual ~B() {cout << "executed ~B()\n";};
-};
-
-main() {
- cout << "starting\n";
- B b;
- b.~A();// ERROR - destructor
- cout << "done\n";
-};
-
+int
diff --git a/gcc/testsuite/g++.old-deja/g++.brendan/crash19.C b/gcc/testsuite/g++.old-deja/g++.brendan/crash19.C
index 8186a763d22..1738c736297 100644
--- a/gcc/testsuite/g++.old-deja/g++.brendan/crash19.C
+++ b/gcc/testsuite/g++.old-deja/g++.brendan/crash19.C
@@ -1,4 +1,4 @@
-// Special g++ Options:
+// Special g++ Options:
// Build don't link:
// GROUPS passed old-abort
typedef unsigned long _G_clock_t;
@@ -151,8 +151,8 @@ struct __streambuf {
char* _gptr;
char* _egptr;
char* _eback;
- char* _pbase;
- char* _pptr;
+ char* _pbase; // ERROR - inacessible
+ char* _pptr; // ERROR - inacessible
char* _epptr;
char* _base;
char* _ebuf;
@@ -1394,7 +1394,7 @@ class queue : public object {
DESTROYER destroy_f;
STRINGER string_f;
int count;
- swap()
+ int swap()
{
QUEUE tmp = Q;
Q = Q2;
diff --git a/gcc/testsuite/g++.old-deja/g++.brendan/crash29.C b/gcc/testsuite/g++.old-deja/g++.brendan/crash29.C
index 855dd990be1..b5287f33795 100644
--- a/gcc/testsuite/g++.old-deja/g++.brendan/crash29.C
+++ b/gcc/testsuite/g++.old-deja/g++.brendan/crash29.C
@@ -1,18 +1 @@
-// Build don't link:
-// GROUPS passed old-abort
-
-union Value
-{
- Value(){}
-};
-
-struct GlobalAddress
-{
- GlobalAddress(Value *nvar){}// ERROR - .*
-};// ERROR - candidates .*
-
-main()
-{
- new GlobalAddress(Value()); // internal error occured here// ERROR - no matching function .*
- //new GlobalAddress(new Value()); // This line is correct code
-}
+int
diff --git a/gcc/testsuite/g++.old-deja/g++.brendan/crash30.C b/gcc/testsuite/g++.old-deja/g++.brendan/crash30.C
index b54fe19817e..707e89841ff 100644
--- a/gcc/testsuite/g++.old-deja/g++.brendan/crash30.C
+++ b/gcc/testsuite/g++.old-deja/g++.brendan/crash30.C
@@ -2,6 +2,7 @@
// GROUPS passed old-abort
#include <string>
+int
main(void) {
string a[] = {"Hello"};
diff --git a/gcc/testsuite/g++.old-deja/g++.brendan/crash33.C b/gcc/testsuite/g++.old-deja/g++.brendan/crash33.C
index 061f5a91794..b5287f33795 100644
--- a/gcc/testsuite/g++.old-deja/g++.brendan/crash33.C
+++ b/gcc/testsuite/g++.old-deja/g++.brendan/crash33.C
@@ -1,6 +1 @@
-// Build don't link:
-// GROUPS passed old-abort
-extern void foo(void *);
-main() {
- foo((struct bar *)0);
-}
+int
diff --git a/gcc/testsuite/g++.old-deja/g++.brendan/crash38.C b/gcc/testsuite/g++.old-deja/g++.brendan/crash38.C
index d124c21e4a9..b5287f33795 100644
--- a/gcc/testsuite/g++.old-deja/g++.brendan/crash38.C
+++ b/gcc/testsuite/g++.old-deja/g++.brendan/crash38.C
@@ -1,42 +1 @@
-// Build don't link:
-// GROUPS passed old-abort
-/*
- I received the following message when using g++ (version 2.3.3):
-
- main.cc: In method 'Implicit<implicit<INTEGER,2>,3>::Implicit()':
- main.cc: Internal compiler error 241.
- main.cc: Please report this to 'bug-g++@prep.ai.mit.edu'
- */
-
-#include <stream.h>
-
-class INTEGER {
-int x;
-public:
- typedef int BASE;
- INTEGER(int y) : x(y) {}
- INTEGER() {}
- void encode() { cout << "Integer encoder";}
- int operator=(int y) { x=y; return x; }
- operator int() {return x; }
-};
-
-template< class T, int n> class Implicit : public T {
- public:
- typedef typename T::BASE BASE;
- Implicit(BASE value ): T(value) {};
- Implicit() : T() {};
- int myTag() { return n; }
- void encode() { T::encode(); }
- BASE operator=(BASE t) { return T::operator=(t); }
-};
-
-main()
-{
- Implicit<Implicit<INTEGER, 2> , 3> y;
-
- y = 10;
-};
-
-
-
+int
diff --git a/gcc/testsuite/g++.old-deja/g++.brendan/crash44.C b/gcc/testsuite/g++.old-deja/g++.brendan/crash44.C
index dd356190913..b5287f33795 100644
--- a/gcc/testsuite/g++.old-deja/g++.brendan/crash44.C
+++ b/gcc/testsuite/g++.old-deja/g++.brendan/crash44.C
@@ -1,26 +1 @@
-// Build don't link:
-// GROUPS passed old-abort
-template <class T> class bug {
-
-public:
- void Foo(const int = 0);
- void NotRedeclared(const int);
-
-private:
- T TheItem;
-};
-
-template <class T> void bug<T>::NotRedeclared(const int)
-{
-}
-
-template <class T> void bug<T>::Foo(const int)
-{
-}
-
-main()
-{
- bug<char> InstantiatedBug;
-
- return 0;
-}
+int
diff --git a/gcc/testsuite/g++.old-deja/g++.brendan/crash47.C b/gcc/testsuite/g++.old-deja/g++.brendan/crash47.C
index daf2bd8b74b..b5287f33795 100644
--- a/gcc/testsuite/g++.old-deja/g++.brendan/crash47.C
+++ b/gcc/testsuite/g++.old-deja/g++.brendan/crash47.C
@@ -1,93 +1 @@
-// Build don't link:
-// GROUPS passed old-abort
-const int TRUE = 1;
-const int FALSE = 0;
-
-class Rep {
-protected:
- Rep(): count(0)
- { }
- Rep(const Rep& other): count(0)
- { }
-
- Rep& operator=(const Rep& other)
- { /* DO NOT copy over other.count */
- return *this; }
-
-public: // TODO - for now
- // Because it is to hard to restrict these operations to the descendants
- // of Rep<REP> that we haven't named yet. So we just make them public.
- void inc()
- { count++; }
- void dec()
- { if (0 == --count) delete this; }
-private:
- unsigned count;
-};
-
-template<class REP>
-class Ref {
-public:
- Ref(): rep(0)
- { }
- Ref(const Ref<REP>& other): rep(other.rep)
- { if (rep) rep->inc(); }
- ~Ref()
- { if (rep) rep->dec();
- rep = 0; }
-
- Ref<REP>& operator=(const Ref<REP>& other)
- { if (rep != other.rep) {
- if (rep) rep->dec();
- rep = other.rep;
- if (rep) rep->inc(); }
- return *this; }
-
- bool null() const
- { return 0 == rep ? TRUE: FALSE; }
- bool valid() const
- { return 0 != rep ? TRUE: FALSE; }
-
- REP* operator->() const // should be a valid() reference
- { return rep; }
- operator REP*() const; // should be a valid() reference
-
-protected:
- REP *rep;
-
- Ref(REP *r): rep(r)
- { if (rep) rep->inc(); }
-
- Ref<REP>& operator=(REP *r)
- { if (rep != r) {
- if (rep) rep->dec();
- rep = r;
- if (rep) rep->inc(); }
- return *this; }
-};
-
-template<class REP>
-Ref<REP>::operator REP*() const // should be a valid() reference
-{ return rep; }
-
-template<class REP>
-inline int
-operator==(const Ref<REP>& a, const Ref<REP>& b)
-{ return (REP *) a == (REP *) b; }
-
-template<class REP>
-inline int
-operator!=(const Ref<REP>& a, const Ref<REP>& b)
-{ return (REP *) a != (REP *) b; }
-
-class XRep: public Rep {
-public:
- int i;
-};
-
-main()
-{
- Ref<XRep> y;
-
- return y != y;
-}
+int
diff --git a/gcc/testsuite/g++.old-deja/g++.brendan/crash48.C b/gcc/testsuite/g++.old-deja/g++.brendan/crash48.C
index 20882a80a53..b5287f33795 100644
--- a/gcc/testsuite/g++.old-deja/g++.brendan/crash48.C
+++ b/gcc/testsuite/g++.old-deja/g++.brendan/crash48.C
@@ -1,21 +1 @@
-// Build don't link:
-// GROUPS passed old-abort
-class internal {
- int field;
- int anotherfield;
-}; // ERROR - candidates are
-
-class bug {
- internal* numbers;
- bug(int size);
-}; // ERROR - several errors
-
-bug::bug(int size)
-{ // ERROR - candidates
- numbers = new internal(size * size);// ERROR - no match.*
-}
-
-main()
-{
- bug test;// ERROR - no match
-}
+int
diff --git a/gcc/testsuite/g++.old-deja/g++.brendan/crash5.C b/gcc/testsuite/g++.old-deja/g++.brendan/crash5.C
index d884189f6b8..b5287f33795 100644
--- a/gcc/testsuite/g++.old-deja/g++.brendan/crash5.C
+++ b/gcc/testsuite/g++.old-deja/g++.brendan/crash5.C
@@ -1,106 +1 @@
-// Build don't link:
-// GROUPS passed old-abort
-// Should have been fixed by:
-//
-// Sun Jun 13 12:55:22 1993 Brendan Kehoe (brendan@lisa.cygnus.com)
-//
-// * cp-cvt.c (build_default_binary_type_conversion): Look deeper into
-// what ARG1 and ARG2 are if they're POINTER_TYPEs.
-
-volatile void exit(int);
-
-class CountableSet
-{
- public:
- virtual ~CountableSet() { }
-};
-
-template<class T>
-class FixedSet : virtual public CountableSet
-{
- public:
- virtual int Get(int, T&) = 0;
- virtual ~FixedSet() { }
-};
-
-class ShrinkableSet
-{
- public:
- virtual int Remove(int) = 0;
-};
-
-template<class T>
-class PVSet : virtual public FixedSet<T>, virtual public ShrinkableSet
-{
- public:
- virtual void Append(const T&) = 0;
- virtual void operator+=(const T& a) { Append(a); }
- virtual ~PVSet() { }
-};
-
-template<class T>
-class MutSet : virtual public FixedSet<T>, virtual public FixedSet<T *>
-{
- protected:
- typedef T *Tp;
-
- public:
- void Append(const Tp& tp) { Append(*tp); }
-
- T& Access(int p)
- {
- Tp tp;
- Get(p, tp);
- return *tp;
- }
- virtual ~MutSet() { }
-};
-
-template <class T>
-class SimpleSet : virtual public MutSet<T>
-{
- protected:
- T *array;
- int size;
-
- virtual void Allocate(int s)
- {
- array = new T[s];
- }
- public:
- SimpleSet()
- {
- size = 0;
- array = ((void*)0) ; // ERROR - implicit conversion
- }
- int Get(int p, T& t)
- {
- t = array[p-1];
- return 1;
- }
- int Get(int p, T *& t)
- {
- t = &array[p-1];
- return 1;
- }
- inline void Append(const T& a)
- {
- array[size-1] = a;
- }
- inline int Remove(int n) { return 0; }
-};
-
-class Dummy
-{
- public:
- Dummy() {}
-};
-
-main()
-{
- SimpleSet<Dummy *> bs1;
- int i, j;
- Dummy foo;
-
- bs1+=&foo;// ERROR - no .*
-}
+int
diff --git a/gcc/testsuite/g++.old-deja/g++.brendan/crash50.C b/gcc/testsuite/g++.old-deja/g++.brendan/crash50.C
index 58695a2a330..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.brendan/crash50.C
+++ b/gcc/testsuite/g++.old-deja/g++.brendan/crash50.C
@@ -1,29 +1 @@
-// Build don't link:
-// GROUPS passed old-abort
-class B
- {
-public:
- int i;
- };
-int operator & (const B &s) { return ( s.i );};
-
-
-
-
-
-class C
- {
-public:
- C &operator = (const C &x)
- {
- return *this;
- };
- };
-
-C &(C::*DD)(const C &x) = &C::operator=;
-
-main()
-{
- &DD;
-
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.brendan/crash54.C b/gcc/testsuite/g++.old-deja/g++.brendan/crash54.C
index 0b85fa1cc00..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.brendan/crash54.C
+++ b/gcc/testsuite/g++.old-deja/g++.brendan/crash54.C
@@ -1,9 +1 @@
-// Build don't link:
-// GROUPS passed old-abort
-main()
-{
- int a[100], **p;
-
- p = &a[50];// ERROR - assignment to.*
-
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.brendan/crash57.C b/gcc/testsuite/g++.old-deja/g++.brendan/crash57.C
index 48014c56892..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.brendan/crash57.C
+++ b/gcc/testsuite/g++.old-deja/g++.brendan/crash57.C
@@ -1,13 +1 @@
-// Build don't link:
-// GROUPS passed old-abort
-class foo {
-private:
- char buffer[1024];
-public:
- foo();
-};
-
-main()
-{
- static foo& a = *(new foo);
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.brendan/crash7.C b/gcc/testsuite/g++.old-deja/g++.brendan/crash7.C
index c55cab97848..36745b89ae5 100644
--- a/gcc/testsuite/g++.old-deja/g++.brendan/crash7.C
+++ b/gcc/testsuite/g++.old-deja/g++.brendan/crash7.C
@@ -1,47 +1,2 @@
-// Build don't link:
-// GROUPS passed templates
-template<class T>
-class Vector
-{
- int sz;
- T *v;
-public:
- Vector (int s) : sz (s) { v = new T[sz]; }
- ~Vector () { delete[] v; }
- T &operator[] (int i) { return v[i]; }
- int size () { return sz; }
-};
-template<class T>// ERROR - previous definition of T
-struct Comparator
-{
- typedef T T;// ERROR - use of template type T in typedef to T
- static lessthan (T &a, T &b) { return a < b; }
-};
-
-template<class Comp>
-struct Sort
-{
- static void sort (Vector<Comp::T> &);// ERROR - use of bad T
-};
-
-template<class Comp>
-void Sort<Comp>::sort (Vector<Comp::T> &v)// ERROR - use of bad T
-{
- int n = v.size ();
-
- for (int i = 0; i < n - 1; i++)
- for (int j = n - 1; i < j; j--)
- if (Comp::lessthan (v[j], v[j - 1]))
- {
- typename Comp::T temp = v[j];
- v[j] = v[j - 1];
- v[j - 1] = temp;
- }
-}
-
-void
-f (Vector<int> &vi)
-{
- Sort<Comparator<int> >::sort (vi);
-}
+ static int lessthan (T &a, T &b) { return a < b; }
diff --git a/gcc/testsuite/g++.old-deja/g++.brendan/enum1.C b/gcc/testsuite/g++.old-deja/g++.brendan/enum1.C
index 7ec648f4cd9..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.brendan/enum1.C
+++ b/gcc/testsuite/g++.old-deja/g++.brendan/enum1.C
@@ -1,14 +1 @@
-// Build don't link:
-// GROUPS passed enums
-class foo {
-public:
- enum bar { baz = 1, bat = 7 };
-};
-
-class derv : public foo { };
-
-main()
-{
- foo::bar x = foo::baz;
- derv::bar y = derv::bat;
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.brendan/enum2.C b/gcc/testsuite/g++.old-deja/g++.brendan/enum2.C
index 58da846f888..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.brendan/enum2.C
+++ b/gcc/testsuite/g++.old-deja/g++.brendan/enum2.C
@@ -1,19 +1 @@
-// Build don't link:
-// GROUPS passed enums
-class foo {
-public:
- enum bar { baz = 1, bat = 7 };
-};
-
-class foo2 {
-public:
- enum bar2 { baz2 = 1, bat2 = 7 };
-};
-
-class derv : public foo, public foo2 { };
-
-main()
-{
- foo::bar x = foo::baz;
- derv::bar2 y = derv::bat2;
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.brendan/enum5.C b/gcc/testsuite/g++.old-deja/g++.brendan/enum5.C
index 2fa1ea3c9c2..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.brendan/enum5.C
+++ b/gcc/testsuite/g++.old-deja/g++.brendan/enum5.C
@@ -1,10 +1 @@
-// Build don't link:
-// Special g++ Options: -pedantic-errors
-// GROUPS passed enums
-enum Thing { FIRST, SECOND } ;
-
-main()
-{
- Thing x = FIRST ;
- x = 27 ; // this line should be a type error.// ERROR - .*
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.brendan/enum6.C b/gcc/testsuite/g++.old-deja/g++.brendan/enum6.C
index de821487b0b..6fdcb4d14ee 100644
--- a/gcc/testsuite/g++.old-deja/g++.brendan/enum6.C
+++ b/gcc/testsuite/g++.old-deja/g++.brendan/enum6.C
@@ -1,16 +1,2 @@
-// Build don't link:
-// GROUPS passed enums
-class X {
- private:
- enum E1 {a1, b1};
- public:
- enum E2 {a2, b2};
- };
-
-void h(X* p) {
- X::E2 e2;
- int x2 = X::a2;
-
- X::E1 e1;
- int x1 = X::a1; // Should be rejected, and is.// ERROR - .*
- }
+ enum E1 {a1, b1}; // ERROR - private
+ int x1 = X::a1; // ERROR - within this context
diff --git a/gcc/testsuite/g++.old-deja/g++.brendan/friend1.C b/gcc/testsuite/g++.old-deja/g++.brendan/friend1.C
index 8d942c7e2ed..ca2ac4aff42 100644
--- a/gcc/testsuite/g++.old-deja/g++.brendan/friend1.C
+++ b/gcc/testsuite/g++.old-deja/g++.brendan/friend1.C
@@ -1,19 +1 @@
-// Build don't link:
-// GROUPS passed friends
-class A
-{
-private:
- A () {}
-
-friend struct B;
-};
-
-class B
-{
-public:
- A a;
-};
-
-B b;
-
-main () {}
+int main () {}
diff --git a/gcc/testsuite/g++.old-deja/g++.brendan/groff1.C b/gcc/testsuite/g++.old-deja/g++.brendan/groff1.C
index 07604c9de09..f3832e07220 100644
--- a/gcc/testsuite/g++.old-deja/g++.brendan/groff1.C
+++ b/gcc/testsuite/g++.old-deja/g++.brendan/groff1.C
@@ -1 +1,2 @@
extern "C" void printf (const char *, ...);
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.brendan/init12.C b/gcc/testsuite/g++.old-deja/g++.brendan/init12.C
index f3c03e0690e..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.brendan/init12.C
+++ b/gcc/testsuite/g++.old-deja/g++.brendan/init12.C
@@ -1,9 +1 @@
-// Build don't link:
-// GROUPS passed array-bindings
-char * bob();
-
-main()
-{
- char a[1][2];
- a[0] = bob();// ERROR - .*
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.brendan/init3.C b/gcc/testsuite/g++.old-deja/g++.brendan/init3.C
index 91b2f7cbeb6..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.brendan/init3.C
+++ b/gcc/testsuite/g++.old-deja/g++.brendan/init3.C
@@ -1,38 +1 @@
-// GROUPS passed initialization
-// p2766: Make sure that members are initialized in order of declaration
-// in the class, not in order of specification in the mem-initializer list.
-
-extern "C" void printf (char *, ...);
-extern "C" void exit (int);
-
-int count = 0;
-
-void die () { printf ("FAIL\n"); exit (1); }
-
-class bar1 {
-public:
- bar1 (int) { if (count != 0) die (); count = 1; }
-};
-
-class bar2
-{
-public:
- bar2 (int) { if (count != 1) die (); count = 2; }
-};
-
-class foo
-{
-public:
- bar1 a;
- bar2 b;
- foo (int, int);
-};
-
-// bar1 should get built before bar2
-foo::foo (int x, int y) : b(x), a(y) {}
-
-main()
-{
- foo f (1, 2);
- printf ("PASS\n");
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.brendan/misc14.C b/gcc/testsuite/g++.old-deja/g++.brendan/misc14.C
index 7d57e30147d..237c8ce1817 100644
--- a/gcc/testsuite/g++.old-deja/g++.brendan/misc14.C
+++ b/gcc/testsuite/g++.old-deja/g++.brendan/misc14.C
@@ -1,12 +1 @@
-// Build don't link:
-// GROUPS passed miscellaneous-bugs
-class X {
-public:
- enum e {
- New,// ERROR - conflicts with other.*
- }; // ERROR - comma
-
- static int New(int);// ERROR - declaration.*
-};
-
-main() {}
+int main() {}
diff --git a/gcc/testsuite/g++.old-deja/g++.brendan/misc7.C b/gcc/testsuite/g++.old-deja/g++.brendan/misc7.C
index 078dbc9c858..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.brendan/misc7.C
+++ b/gcc/testsuite/g++.old-deja/g++.brendan/misc7.C
@@ -1,15 +1 @@
-// GROUPS passed miscellaneous
-extern "C" void printf (char *, ...);
-
-main()
-{
- int i = 0;
- // Make sure build_unary_op correctly computes this.
- int *pi = &(++i);
- *pi = 4;
-
- if (i != 4)
- printf ("FAIL\n");
- else
- printf ("PASS\n");
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.brendan/misc8.C b/gcc/testsuite/g++.old-deja/g++.brendan/misc8.C
index 7efad41d896..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.brendan/misc8.C
+++ b/gcc/testsuite/g++.old-deja/g++.brendan/misc8.C
@@ -1,18 +1 @@
-// Build don't link:
-// GROUPS passed miscellaneous
-// used to say invalid lvalue in `&\'
-class foo {
- int a;
- public:
- foo(int a);
-};
-
-foo::foo(int a)
-{
- foo::a=a;
-}
-
-main()
-{
-foo obj(4);
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.brendan/nest10.C b/gcc/testsuite/g++.old-deja/g++.brendan/nest10.C
index 751440d1947..fca7aa3a92f 100644
--- a/gcc/testsuite/g++.old-deja/g++.brendan/nest10.C
+++ b/gcc/testsuite/g++.old-deja/g++.brendan/nest10.C
@@ -1,30 +1 @@
-// Build don't link:
-// GROUPS passed nested-classes
-class A
- {
- public:
- class B
- {
- public:
- int f ();
- void g (int);
- private:
- int b;
- };
- };
-
-int A::B::f ()
- {
- int val=b;
- return val;
- }
-
-void A::B::g (int val)
- {
- b = val;
- }
-
-
-main ()
- {
- }
+int main ()
diff --git a/gcc/testsuite/g++.old-deja/g++.brendan/nest21.C b/gcc/testsuite/g++.old-deja/g++.brendan/nest21.C
index c4eb0ee78ab..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.brendan/nest21.C
+++ b/gcc/testsuite/g++.old-deja/g++.brendan/nest21.C
@@ -1,95 +1 @@
-// GROUPS passed nested-classes
-#include <iostream.h>
-#include <stdio.h>
-
-static char output[1024];
-
-class BDDRetrace {
-public:
- class Dump {
- public:
- virtual Dump& operator<<(char c) = 0;
- virtual Dump& operator<<(int i) = 0;
- virtual Dump& operator<<(double r) = 0;
- };
-
- class Dump1: public Dump {
- public:
- Dump& operator<<(char c);
- Dump& operator<<(int i);
- Dump& operator<<(double r);
- };
-};
-
-class Dump2: public BDDRetrace::Dump {
-public:
- BDDRetrace::Dump& operator<<(char c);
- BDDRetrace::Dump& operator<<(int i);
- BDDRetrace::Dump& operator<<(double r);
-};
-
-BDDRetrace::Dump&
-BDDRetrace::Dump1::operator<<(char c)
-{ char tempout[1024];
- sprintf (tempout, "%s%s%c", output, "1-", c);
- strcpy (output, tempout);
- return *this;
-}
-
-BDDRetrace::Dump&
-BDDRetrace::Dump1::operator<<(int i)
-{ char tempout[1024];
- sprintf (tempout, "%s%s%d", output, "1-", i);
- strcpy (output, tempout);
- return *this; }
-
-BDDRetrace::Dump&
-BDDRetrace::Dump1::operator<<(double r)
-{ char tempout[1024];
- sprintf (tempout, "%s%s%1.0f", output, "1-", r);
- strcpy (output, tempout);
- return *this; }
-
-BDDRetrace::Dump&
-Dump2::operator<<(char c)
-{ char tempout[1024];
- sprintf (tempout, "%s%s%c", output, "2-", c);
- strcpy (output, tempout);
- return *this; }
-
-BDDRetrace::Dump&
-Dump2::operator<<(int i)
-{ char tempout[1024];
- sprintf (tempout, "%s%s%d", output, "2-", i);
- strcpy (output, tempout);
- return *this; }
-
-BDDRetrace::Dump&
-Dump2::operator<<(double r)
-{ char tempout[1024];
- sprintf (tempout, "%s%s%1.0f", output, "2-", r);
- strcpy (output, tempout);
- return *this; }
-
-main()
-{
- BDDRetrace::Dump1 d1;
- Dump2 d2;
-
- sprintf (output, " ");
-
- d1 << 'a';
- d1 << 1;
- d1 << 1.0;
-
- d2 << 'a';
- d2 << 1;
- d2 << 1.0;
-
- if (strcmp (output, " 1-a1-11-12-a2-12-1") == 0)
- printf ("PASS\n");
- else
- printf ("FAIL\n");
-
- return 0;
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.brendan/nest3.C b/gcc/testsuite/g++.old-deja/g++.brendan/nest3.C
index 16e7df88b45..8b8d58de0ed 100644
--- a/gcc/testsuite/g++.old-deja/g++.brendan/nest3.C
+++ b/gcc/testsuite/g++.old-deja/g++.brendan/nest3.C
@@ -1,12 +1 @@
-// Build don't link:
-// GROUPS passed nested-classes
-class X {
-public:
- struct M2 { int m; };
- M2 g(int);
-};
-
-
-X::M2 X::g(int i) { X::M2 m2; return m2; }
-
-main() { }
+int main() { }
diff --git a/gcc/testsuite/g++.old-deja/g++.brendan/new-array.C b/gcc/testsuite/g++.old-deja/g++.brendan/new-array.C
index 5341010822c..765014bc66d 100644
--- a/gcc/testsuite/g++.old-deja/g++.brendan/new-array.C
+++ b/gcc/testsuite/g++.old-deja/g++.brendan/new-array.C
@@ -1,18 +1 @@
-// Build don't link:
-// GROUPS passed operator-new
-typedef struct {
- int a;
-} AStruct;
-
-void MakeBug() {
- AStruct *job;
-
- // This used to crash, it should now give error(s).
- job = new AStruct[];// ERROR - .*
-
- job = new AStruct;
-}
-
-main () {
- MakeBug();
-}
+int main () {
diff --git a/gcc/testsuite/g++.old-deja/g++.brendan/operators1.C b/gcc/testsuite/g++.old-deja/g++.brendan/operators1.C
index 6146eb401a0..b3b753c1a91 100644
--- a/gcc/testsuite/g++.old-deja/g++.brendan/operators1.C
+++ b/gcc/testsuite/g++.old-deja/g++.brendan/operators1.C
@@ -1,14 +1 @@
-// Build don't link:
-// GROUPS passed operators
-struct A {
- int x;
-};
-
-int operator()(A x,float y) { // MUST be a member function// ERROR - .*
- return 1;
-}
-
-main() {
- A x;
- x(1.0); // ERROR - no match for call
-}
+int main() {
diff --git a/gcc/testsuite/g++.old-deja/g++.brendan/overload1.C b/gcc/testsuite/g++.old-deja/g++.brendan/overload1.C
index 5658fdd8f9b..fca7aa3a92f 100644
--- a/gcc/testsuite/g++.old-deja/g++.brendan/overload1.C
+++ b/gcc/testsuite/g++.old-deja/g++.brendan/overload1.C
@@ -1,21 +1 @@
-// Build don't link:
-// GROUPS passed overloading
-class Foo
-{
-public:
- int f (void);
-};
-
-class Bar : public Foo
-{
-public:
- int f (int); // ERROR - candidates are
-};
-
-main ()
-{
- Bar b;
-
- b.f ();// ERROR -
- b.f (10);
-}
+int main ()
diff --git a/gcc/testsuite/g++.old-deja/g++.brendan/overload7.C b/gcc/testsuite/g++.old-deja/g++.brendan/overload7.C
index 0c39e0d8c21..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.brendan/overload7.C
+++ b/gcc/testsuite/g++.old-deja/g++.brendan/overload7.C
@@ -1,41 +1 @@
-// GROUPS passed overloading
-extern "C" void printf (char *, ...);
-
-struct NoName {
-
- int first;
- int second;
-};
-
-class Casted {
-
- public:
-
- NoName x;
- double y;
-
- Casted ( int _x , double _y ): y(_y)
- {
- x.first = _x;
- x.second = _x*2;
- }
-
- operator NoName() const { return x; }
- operator double() const { return y; }
-};
-
-main()
-{
- Casted c(10,12.34);
-
- NoName x;
- double y;
-
- x = c;
- y = c;
-
- if (x.first == 10 && x.second == 20 && y == 12.34)
- printf ("PASS\n");
- else
- printf ("FAIL\n");
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.brendan/overload8.C b/gcc/testsuite/g++.old-deja/g++.brendan/overload8.C
index 6057ebe7086..bd828ec79cb 100644
--- a/gcc/testsuite/g++.old-deja/g++.brendan/overload8.C
+++ b/gcc/testsuite/g++.old-deja/g++.brendan/overload8.C
@@ -1,9 +1 @@
-// Build don't link:
-// GROUPS passed overloading
-typedef struct{double re,im;} complex;
-class Complex{public:double re,im;
- inline void operator=(Complex&X){re=X.re; im=X.im;};};
-void zxcvbnm(int n,...){n=1;}
-main(){complex c; Complex C;
-zxcvbnm(1,c);
-zxcvbnm(1,C);}
+int main(){complex c; Complex C;
diff --git a/gcc/testsuite/g++.old-deja/g++.brendan/overload9.C b/gcc/testsuite/g++.old-deja/g++.brendan/overload9.C
index 2d5dfa3553d..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.brendan/overload9.C
+++ b/gcc/testsuite/g++.old-deja/g++.brendan/overload9.C
@@ -1,20 +1 @@
-// Build don't link:
-// GROUPS passed overloading
-class CLogger
-{
-public:
- void operator() (int,const char *) {}; // ERROR - candidates
- void operator() (int,const char *, ...) {}; // ERROR - candidates
-} Log;
-
-class CGLogger : public CLogger
-{
-} GLog;
-
-main()
-{
- Log(1,"Test");// ERROR - call of.*
- Log(1,"Test %d",3);
- GLog(1,"Test");// ERROR - call of.*
- GLog(1,"Test %d",3);
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.brendan/parse1.C b/gcc/testsuite/g++.old-deja/g++.brendan/parse1.C
index 76bfb0ea378..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.brendan/parse1.C
+++ b/gcc/testsuite/g++.old-deja/g++.brendan/parse1.C
@@ -1,17 +1 @@
-// Build don't link:
-// GROUPS passed parsing
-class Try {
-private:
- char s;
-public:
- // an escaped double-quote should not call consume_string inside
- // reinit_parse_for_block
- void mf() { s='\"'; }
-};
-
-main()
-{
- Try x;
- x.mf();
-}
-
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.brendan/parse3.C b/gcc/testsuite/g++.old-deja/g++.brendan/parse3.C
index c346a289f9a..8be64a39b68 100644
--- a/gcc/testsuite/g++.old-deja/g++.brendan/parse3.C
+++ b/gcc/testsuite/g++.old-deja/g++.brendan/parse3.C
@@ -18,5 +18,5 @@ A A::operator+(const A in)
if (high==0)
return A(); // this works
else
- return (A()); // this works not !! -> why ?? // ERROR -
-} // ERROR -
+ return (A()); // this works not // gets bogus error - XFAIL *-*-*
+} // gets bogus error - XFAIL *-*-*
diff --git a/gcc/testsuite/g++.old-deja/g++.brendan/parse4.C b/gcc/testsuite/g++.old-deja/g++.brendan/parse4.C
index d60cefeb3e5..6526c605951 100644
--- a/gcc/testsuite/g++.old-deja/g++.brendan/parse4.C
+++ b/gcc/testsuite/g++.old-deja/g++.brendan/parse4.C
@@ -14,7 +14,7 @@ public:
int g() { return 0; } // gets bogus error - referenced below XFAIL *-*-*
-main()
+int main()
{
int try1;
B( try1 ).f(); // no syntax error
diff --git a/gcc/testsuite/g++.old-deja/g++.brendan/parse5.C b/gcc/testsuite/g++.old-deja/g++.brendan/parse5.C
index 3b311e4b06e..81a5fe649b1 100644
--- a/gcc/testsuite/g++.old-deja/g++.brendan/parse5.C
+++ b/gcc/testsuite/g++.old-deja/g++.brendan/parse5.C
@@ -21,5 +21,5 @@ public:
int main()
{
unsigned char b[3];
- buf<3> b2(ptr8(&b[0],3)); // ERROR -
+ buf<3> b2(ptr8(&b[0],3)); // gets bogus error - XFAIL *-*-*
}
diff --git a/gcc/testsuite/g++.old-deja/g++.brendan/parse6.C b/gcc/testsuite/g++.old-deja/g++.brendan/parse6.C
index 5e27c58836f..d5ece069103 100644
--- a/gcc/testsuite/g++.old-deja/g++.brendan/parse6.C
+++ b/gcc/testsuite/g++.old-deja/g++.brendan/parse6.C
@@ -7,7 +7,7 @@
class A { };
-main() {
+int main() {
A a = a;
- A b(b); // ERROR -
+ A b(b); // gets bogus error - XFAIL *-*-*
}
diff --git a/gcc/testsuite/g++.old-deja/g++.brendan/prepost1.C b/gcc/testsuite/g++.old-deja/g++.brendan/prepost1.C
index ba1a2084efe..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.brendan/prepost1.C
+++ b/gcc/testsuite/g++.old-deja/g++.brendan/prepost1.C
@@ -1,15 +1 @@
-// Build don't link:
-// GROUPS passed prefix-postfix
-class foo {
-public:
- operator ++ (); // ERROR - no type or storage class
-};
-
-main()
-{
- foo x;
-
- // This should fall back to calling operator++(), and be an error with
- // the -pedantic flag.
- x++;// ERROR -
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.brendan/ptolemy2.C b/gcc/testsuite/g++.old-deja/g++.brendan/ptolemy2.C
index ca9c21c2814..c141c7c16da 100644
--- a/gcc/testsuite/g++.old-deja/g++.brendan/ptolemy2.C
+++ b/gcc/testsuite/g++.old-deja/g++.brendan/ptolemy2.C
@@ -1,69 +1 @@
-// GROUPS passed ptolemy-bugs
-#include <iostream.h>
-
-class PTcl {
-public:
- int dispatcher(int which,int argc,char** argv);
- // fns in the table
- int one(int argc, char** argv);
- int two(int argc, char** argv);
- int three(int argc, char** argv);
-};
-
-// An InterpFuncP is a pointer to an PTcl function that takes an argc-argv
-// argument list and returns TCL_OK or TCL_ERROR.
-
-typedef int (PTcl::*InterpFuncP)(int,char**);
-
-struct InterpTableEntry {
- char* name;
- InterpFuncP func;
-};
-
-// Here is the function table and dispatcher function.
-// These macros define entries for the table
-
-#define quote(x) #x
-#define ENTRY(verb) { quote(verb), &PTcl::verb }
-
-static InterpTableEntry funcTable[] = {
- ENTRY(one),
- ENTRY(two),
- ENTRY(three),
- {0, 0}
-};
-
-int PTcl::dispatcher(int which, int argc, char** argv) {
- return (this->*(funcTable[which].func))(argc, argv);
-}
-
-void printargs(char** argv) {
-// while (*argv) {
-// cout << " " << *argv++;
-// }
-// cout << "\n";
-}
-
-int PTcl::one(int, char** argv) {
- cout << "FAIL\n";
- printargs(argv);
- return 0;
-}
-
-int PTcl::two(int, char** argv) {
- cout << "PASS\n";
- printargs(argv);
- return 0;
-}
-
-int PTcl::three(int, char** argv) {
- cout << "FAIL\n";
- printargs(argv);
- return 0;
-}
-
-main (int argc, char** argv) {
- PTcl obj;
- obj.dispatcher(1,argc,argv);
- return 0;
-}
+int main (int argc, char** argv) {
diff --git a/gcc/testsuite/g++.old-deja/g++.brendan/recurse.C b/gcc/testsuite/g++.old-deja/g++.brendan/recurse.C
index 93baa4490b4..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.brendan/recurse.C
+++ b/gcc/testsuite/g++.old-deja/g++.brendan/recurse.C
@@ -1,80 +1 @@
-// Build don't link:
-// GROUPS passed recursive-aborts
-// types
-typedef unsigned int DBflag; // for storing user flag value
-typedef unsigned long DBoffset; // 32-bit unsigned integer
-typedef DBoffset DBsize; // type for storing sizes of objects
-typedef unsigned char DBbyte; // 8-bit unsigned char
-
-class DBlink
-{
-protected:
- DBbyte link[4]; // hold link in portable MSB first format
-public:
- DBlink(DBoffset = 0, DBflag = 0);
- DBlink &operator=(const DBlink &);
- DBlink &operator=(DBoffset);
- operator DBoffset();
- operator const DBbyte *() { return link; }
- void set_flag() { link[0] |= 0x80; }
- void reset_flag() { link[0] &= 0x7f; }
- int test_flag() const { return (link[0] & 0x80) != 0; }
-};
-
-typedef DBlink DBsizerec; // hold data record size in portable format
-
-// constants
-const DBoffset DB_NULL = 0;
-
-class DBlinkrec
-{
-protected:
- // offsets are stored with MSB in link[0]
- DBlink l; // offset into link file of right child - MSB = red bit
- DBlink r; // offset into link file of left child - MSB = delete
- DBlink d; // offset into parallel data file - MSB = user flag
-public:
- DBlinkrec():l(DB_NULL), r(DB_NULL), d(DB_NULL) {}
- void make_red() // set link to red
- { l.set_flag(); }
- void make_black() // set link to black
- { l.reset_flag(); }
- int is_red() const // indicates whether this is a red link
- { return l.test_flag(); }
- void set_discard() // set discard flag
- { r.set_flag(); }
- void reset_discard() // reset discard flag
- { r.reset_flag(); }
- int is_discarded() const // check discard flag
- { return r.test_flag(); }
- void set_flag() // set user flag
- { d.set_flag(); }
- void reset_flag() // reset user flag
- { d.reset_flag(); }
- int is_flag() const // check user flag
- { return d.test_flag(); }
-
- friend class DataBase;
-};
-
-class DBpathrec : public DBlinkrec
-{
- DBoffset offset; // offset of link record in LNK file
-public:
- DBpathrec():offset(DB_NULL) { }
- DBpathrec(DBoffset off, const DBlinkrec &lr):offset(off), DBlinkrec(lr) {}
- operator DBoffset() { return offset; }
- DBpathrec &operator=(DBoffset off) { offset = off; return *this; }
- DBpathrec &operator=(const DBpathrec &pr)
- { offset = pr.offset; (DBlinkrec)*this = (DBlinkrec)pr; return *this; }
-
- friend class DataBase;
-};
-
-main()
-{
- DBpathrec a(), b();
-
- a = b;// ERROR - non-lvalue in assignment.*
-}
-
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.brendan/scope2.C b/gcc/testsuite/g++.old-deja/g++.brendan/scope2.C
index 7085716be73..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.brendan/scope2.C
+++ b/gcc/testsuite/g++.old-deja/g++.brendan/scope2.C
@@ -1,29 +1 @@
-// Build don't link:
-// GROUPS passed scoping
-class A
-{
- public:
- A() {}
- ~A() {}
- virtual void f() {}
-};
-
-class B : public A
-{
- public:
- B() {}
- ~B() {}
- virtual void f() {}
-};
-
-
-B GLOBAL_B;
-
-B& foo() {return GLOBAL_B;}
-
-main()
-{
- // build_scoped_method_call and build_scoped_ref should know how
- // to deal with a reference for this
- foo().A::f();
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.brendan/static2.C b/gcc/testsuite/g++.old-deja/g++.brendan/static2.C
index 1e050e2cf6f..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.brendan/static2.C
+++ b/gcc/testsuite/g++.old-deja/g++.brendan/static2.C
@@ -1,19 +1 @@
-// Build don't link:
-// GROUPS passed static
-class A
-{
- public:
- void member(void)
- {
- }
-
- static void staticMember()
- {
- member (); // illegal, no object for calling non-static method// ERROR - .*
- }
-};
-
-main()
-{
- A::staticMember();
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.brendan/template11.C b/gcc/testsuite/g++.old-deja/g++.brendan/template11.C
index 55fa2b20025..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.brendan/template11.C
+++ b/gcc/testsuite/g++.old-deja/g++.brendan/template11.C
@@ -1,47 +1 @@
-// Build don't link:
-// GROUPS passed templates
-template <class Called>
-class aCallback
-{
-public:
- aCallback(Called& obj, int (Called::*met)());
-
- int callback();
-
-protected:
-
-private:
- // the object to call
- Called& object;
-
- // the method to apply
- int (Called::*method)();
-
-};
-
-template <class Called>
-aCallback<Called>::aCallback(Called& obj,
- int (Called::*met)()) :
-object(obj),
-method(met)
-{};
-
-template <class Called>
-int aCallback<Called>::callback()
-{
- return (object.*method)();
-}
-
-struct myStruct
-{
- int action() {return 24;};
-};
-
-main()
-{
- myStruct toto;
-
- aCallback<myStruct> cb(toto, &myStruct::action);
-
- return cb.callback();
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.brendan/template2.C b/gcc/testsuite/g++.old-deja/g++.brendan/template2.C
index 07e2e66a7c0..765014bc66d 100644
--- a/gcc/testsuite/g++.old-deja/g++.brendan/template2.C
+++ b/gcc/testsuite/g++.old-deja/g++.brendan/template2.C
@@ -1,14 +1 @@
-// Build don't link:
-// GROUPS passed templates
-template <class Q>
-class Conc {
-public:
- static int body();
-};
-
-template <class Q>
-int Conc<Q>::body() {return 0;}
-
-main () {
- Conc<int> s2;
-}
+int main () {
diff --git a/gcc/testsuite/g++.old-deja/g++.brendan/template20.C b/gcc/testsuite/g++.old-deja/g++.brendan/template20.C
index 7f5c4acd467..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.brendan/template20.C
+++ b/gcc/testsuite/g++.old-deja/g++.brendan/template20.C
@@ -1,21 +1 @@
-// Build don't link:
-// GROUPS passed templates
-template <class A, class B> class Map;
-
-class Foo
-{
-public:
- static Map<int,int> bar;
-};
-
-template <class A, class B>
-class Map
-{
-public :
- int find();
-};
-
-main()
-{
- int z = Foo::bar.find();
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.brendan/template22.C b/gcc/testsuite/g++.old-deja/g++.brendan/template22.C
index a977e2ffacf..fca7aa3a92f 100644
--- a/gcc/testsuite/g++.old-deja/g++.brendan/template22.C
+++ b/gcc/testsuite/g++.old-deja/g++.brendan/template22.C
@@ -1,22 +1 @@
-// GROUPS passed templates
-extern "C" int printf (const char *, ...);
-
-template <class T>
-class Foo
-{
-public:
- void func (int const& i);
-};
-
-template <class T>
-void Foo<T>::
-func (int const& i)
-{}
-
-
-main ()
-{
- Foo<int const> foo;
- printf ("PASS\n");
- return 0;
-}
+int main ()
diff --git a/gcc/testsuite/g++.old-deja/g++.brendan/template24.C b/gcc/testsuite/g++.old-deja/g++.brendan/template24.C
index 7d677023282..fca7aa3a92f 100644
--- a/gcc/testsuite/g++.old-deja/g++.brendan/template24.C
+++ b/gcc/testsuite/g++.old-deja/g++.brendan/template24.C
@@ -1,20 +1 @@
-// GROUPS passed templates
-extern "C" void printf (char *, ...);
-
-template <class F>
-class Temp
-{
- F func_;
-public:
- Temp (F f) :func_(f) {}
-};
-
-int func (int h = 1, int z = 2) { return h+z; }
-
-main ()
-{
- Temp<int(*)(int, int)> temp (func);
-
- printf ("PASS\n");
- return 0;
-}
+int main ()
diff --git a/gcc/testsuite/g++.old-deja/g++.brendan/template28.C b/gcc/testsuite/g++.old-deja/g++.brendan/template28.C
index 3ae4caf4638..c0c35bdbfa5 100644
--- a/gcc/testsuite/g++.old-deja/g++.brendan/template28.C
+++ b/gcc/testsuite/g++.old-deja/g++.brendan/template28.C
@@ -1,13 +1 @@
-// Build don't link:
-// GROUPS passed templates
-class X {
- const char *fptr;
-public:
- X(const char *ptr) { fptr = ptr; }
- operator const char*() { return fptr; }
-};
-
-main(){
- X x1("1234");
- X x2(x1+1);
-}
+int main(){
diff --git a/gcc/testsuite/g++.old-deja/g++.brendan/template29.C b/gcc/testsuite/g++.old-deja/g++.brendan/template29.C
index fa81995ed74..a5239f54404 100644
--- a/gcc/testsuite/g++.old-deja/g++.brendan/template29.C
+++ b/gcc/testsuite/g++.old-deja/g++.brendan/template29.C
@@ -1,12 +1 @@
-// Build don't link:
-// GROUPS passed templates
- template <class ElementType> class A
- { public:
- A(ElementType) {}
- ElementType get() const ;
- };
-
- template <class ElementType> ElementType A<ElementType>::get() const
- { return ElementType(0); }
-
- main() { const A<short> a(3); }
+int main() { const A<short> a(3); }
diff --git a/gcc/testsuite/g++.old-deja/g++.brendan/template8.C b/gcc/testsuite/g++.old-deja/g++.brendan/template8.C
index 0a24617239f..c0c35bdbfa5 100644
--- a/gcc/testsuite/g++.old-deja/g++.brendan/template8.C
+++ b/gcc/testsuite/g++.old-deja/g++.brendan/template8.C
@@ -1,20 +1 @@
-// Build don't link:
-// GROUPS passed templates
-#include <stdio.h>
-
-// make sure we accept unions for templates
-template<int n>
-union Double_alignt{
- double for_alignt;
- char array[n];
-
-};
-
-main(){
-
-
- Double_alignt<20000> heap;
-
- printf(" &heap.array[0] = %d, &heap.for_alignt = %d\n", &heap.array[0], &heap.for_alignt);
-
-}
+int main(){
diff --git a/gcc/testsuite/g++.old-deja/g++.brendan/temporary1.C b/gcc/testsuite/g++.old-deja/g++.brendan/temporary1.C
index 5258edf36a5..fca7aa3a92f 100644
--- a/gcc/testsuite/g++.old-deja/g++.brendan/temporary1.C
+++ b/gcc/testsuite/g++.old-deja/g++.brendan/temporary1.C
@@ -1,13 +1 @@
-// Build don't link:
-// GROUPS passed temporaries
-#include <stdio.h>
-
-main ()
-{
- int a = 2;
-
- if (----a == 0)
- printf ("a = 0\n");
-
- printf ("a = %d\n", a);
-}
+int main ()
diff --git a/gcc/testsuite/g++.old-deja/g++.brendan/visibility1.C b/gcc/testsuite/g++.old-deja/g++.brendan/visibility1.C
index 7d11f875716..cd87ccb98b7 100644
--- a/gcc/testsuite/g++.old-deja/g++.brendan/visibility1.C
+++ b/gcc/testsuite/g++.old-deja/g++.brendan/visibility1.C
@@ -1,16 +1 @@
-// Build don't link:
-// GROUPS passed visibility
-class foo {
-protected:
- int i;
-};
-
-class bar : public foo {
-public:
- friend void baz (foo *);
-};
-
-void baz (foo *f)
-{
- f->i = 1; // error: i is protected// ERROR - .*
-}
+ int i; // ERROR - protected
diff --git a/gcc/testsuite/g++.old-deja/g++.brendan/visibility4.C b/gcc/testsuite/g++.old-deja/g++.brendan/visibility4.C
index b9de78f1881..b1f443948ae 100644
--- a/gcc/testsuite/g++.old-deja/g++.brendan/visibility4.C
+++ b/gcc/testsuite/g++.old-deja/g++.brendan/visibility4.C
@@ -1,14 +1,2 @@
-// Build don't link:
-// Special g++ Options: -w
-// GROUPS passed visibility
-template <class T>
-class Feld {
-public:
- Feld(const Feld&) {}
-};
-
-class Polynom : private Feld<double> {
-friend Polynom f(const Polynom&);
-};
-
-Polynom f(const Polynom& p) { return p; }
+ Polynom();
+ friend Polynom f(const Polynom&);
diff --git a/gcc/testsuite/g++.old-deja/g++.brendan/visibility6.C b/gcc/testsuite/g++.old-deja/g++.brendan/visibility6.C
index 5ca62c0c6a7..cf15fdf3cce 100644
--- a/gcc/testsuite/g++.old-deja/g++.brendan/visibility6.C
+++ b/gcc/testsuite/g++.old-deja/g++.brendan/visibility6.C
@@ -1,17 +1 @@
-// Build don't link:
-// GROUPS passed visibility
-class bottom
-{
-public:
- int b;
-};
-class middle : private bottom
-{
-public:
- void foo () { b; }
-};
-class top : public middle
-{
-public:
- void bar () { b; }// ERROR - .*
-};
+ int b; // ERROR - private
diff --git a/gcc/testsuite/g++.old-deja/g++.brendan/visibility8.C b/gcc/testsuite/g++.old-deja/g++.brendan/visibility8.C
index a3bb856d1ad..203b1f61be4 100644
--- a/gcc/testsuite/g++.old-deja/g++.brendan/visibility8.C
+++ b/gcc/testsuite/g++.old-deja/g++.brendan/visibility8.C
@@ -1,15 +1 @@
-// Build don't link:
-// GROUPS passed visibility
-// Make sure private inheritance affects the visibility of
-// static members used in an inherited context.
-class foo
-{
-public:
- static int y;
-};
-class foo1 : private foo
-{ };
-class foo2 : public foo1
-{ public:
- void bar () { y; }// ERROR - .*
-};
+ static int y; // ERROR - private
diff --git a/gcc/testsuite/g++.old-deja/g++.bugs/900121_01.C b/gcc/testsuite/g++.old-deja/g++.bugs/900121_01.C
index 99ab8f6cbcf..4582067c0ad 100644
--- a/gcc/testsuite/g++.old-deja/g++.bugs/900121_01.C
+++ b/gcc/testsuite/g++.old-deja/g++.bugs/900121_01.C
@@ -1,16 +1 @@
-// g++ 1.36.1 bug 900121_01
-
-// The following file causes g++ 1.36.1 (and 1.36.2) to abort.
-
-// Cfront 2.0 passes this test.
-
-// keywords: abort, incomplete types, reference types, formal parameters
-
-struct s0;
-
-void function (struct s0 &arg1, struct s0 &arg2)
-{
- arg1 = arg2; // ERROR - causes abort
-}
-
-int main () { return 0; }
+struct s0; // ERROR - forward declaration
diff --git a/gcc/testsuite/g++.old-deja/g++.bugs/900213_03.C b/gcc/testsuite/g++.old-deja/g++.bugs/900213_03.C
index d25a8b2f7f7..6a12cbe96c4 100644
--- a/gcc/testsuite/g++.old-deja/g++.bugs/900213_03.C
+++ b/gcc/testsuite/g++.old-deja/g++.bugs/900213_03.C
@@ -1,28 +1 @@
-// g++ 1.36.1 bug 900213_03
-
-// g++ fails to detect an error when the address of a "bound" function is
-// assigned to a pointer-to-member-function variable.
-
-// It does however correctly detect a similar errors for data-members.
-
-// keywords: bound function, operator&, member pointers
-// Build don't link:
-
-struct struct0 {
- int data_member;
- int function_member ();
-};
-
-int i;
-int struct0::*dmp;
-int (struct0::*fmp) ();
-
-struct0 *ptr;
-
-void global_function_0 ()
-{
- fmp = &ptr->function_member; // ERROR - missed by g++, warned by cfront, XFAIL *-*-*
- //dmp = &ptr->data_member; // caught by g++, missed by cfront
-}
-
-int main () { return 0; }
+ fmp = &ptr->function_member; // ERROR -
diff --git a/gcc/testsuite/g++.old-deja/g++.bugs/900214_01.C b/gcc/testsuite/g++.old-deja/g++.bugs/900214_01.C
index 3aac764f86e..8fe79b53514 100644
--- a/gcc/testsuite/g++.old-deja/g++.bugs/900214_01.C
+++ b/gcc/testsuite/g++.old-deja/g++.bugs/900214_01.C
@@ -1,22 +1 @@
-// g++ 1.36.1 bug 900214_01
-
-// g++ allows function members of incomplete types to be declared to be
-// friends of other types.
-
-// Cfront 2.0 passes this test.
-
-// keywords: friends, incomplete types, function members
-
-struct A;
-
-struct B {
- friend void A::foo(); // ERROR - type A is incomplete
-};
-
-void A::foo(); /* ERROR - also illegal */
-
-struct A {
- void foo() {}
-};
-
-int main () { return 0; }
+struct A; // ERROR - forward declaration
diff --git a/gcc/testsuite/g++.old-deja/g++.bugs/900215_02.C b/gcc/testsuite/g++.old-deja/g++.bugs/900215_02.C
index fb08df3bd33..1616b69c11f 100644
--- a/gcc/testsuite/g++.old-deja/g++.bugs/900215_02.C
+++ b/gcc/testsuite/g++.old-deja/g++.bugs/900215_02.C
@@ -1,47 +1 @@
-// g++ 1.36.1 bug 900215_02
-
-// g++ allows global objects (which happen to be pointers to members of some
-// class X) to be dereferenced without prefix object specifications within
-// member functions of class X.
-
-// In effect, g++ treats any dereference of a pointer-to-member which appears
-// within the context of a member function (and which is not preceeded by
-// either ->* or .*) as if it had been implicitly prefixed with this->*.
-
-// The 2.0 Reference Manual only provides that such implicit prefixing
-// takes place for *members* of the containing class, and *not* for
-// global objects that happen to have certain types (i.e. pointer-to-member
-// of the containing class).
-
-// Also, cfront 2.0 provides implicit this-> prefixes *only* for *members*
-// of the containing class.
-
-// Cfront 2.0 passes this test.
-
-// keywords: member pointers, this, dereference, members
-
-struct struct0 {
- int data_member;
- void function_member ();
-};
-
-int struct0::*dmp;
-int (struct0::*fmp) ();
-int i;
-
-struct struct1 {
- int data_member;
-
- void function_member ();
-};
-
-void struct0::function_member ()
-{
- i = (this->*fmp) (); // perfectly legal - for both cfront and g++
- i = this->*dmp; // perfectly legal - for both cfront and g++
-
- i = (*fmp) (); // ERROR -
- i = *dmp; // ERROR - , XFAIL *-*-*
-}
-
-int main () { return 0; }
+ i = *dmp; // ERROR -
diff --git a/gcc/testsuite/g++.old-deja/g++.bugs/900321_01.C b/gcc/testsuite/g++.old-deja/g++.bugs/900321_01.C
index 56a333f532b..08771d07e74 100644
--- a/gcc/testsuite/g++.old-deja/g++.bugs/900321_01.C
+++ b/gcc/testsuite/g++.old-deja/g++.bugs/900321_01.C
@@ -1,29 +1,2 @@
-// g++ 1.37.1 bug 900321_01
-
-// cfront flags ERRORs on each of the lines indicated below. g++ does not
-// flag either ERRORs or warnings.
-
-// Although I cannot find where in the current C++ Reference Manual this
-// topic is covered, I am sure that these statements should get ERRORs in
-// a "strongly typed" language.
-
-// Cfront 2.0 passes this test.
-
-// keywords: array types, array bound, pointers
-
-int (*ptr_to_array_of_ints)[];
-int (*ptr_to_array_of_3_ints) [3];
-int (*ptr_to_array_of_5_ints) [5];
-
-void function_0 ()
-{
- // we miss the first two because typeck.c (comp_array_types) deems
- // it okay if one of the sizes is null
- ptr_to_array_of_ints = ptr_to_array_of_3_ints; // ERROR - , XFAIL *-*-*
- ptr_to_array_of_3_ints = ptr_to_array_of_ints; // ERROR - , XFAIL *-*-*
-
- ptr_to_array_of_3_ints = ptr_to_array_of_5_ints; // ERROR -
- ptr_to_array_of_5_ints = ptr_to_array_of_3_ints; // ERROR -
-}
-
-int main () { return 0; }
+ ptr_to_array_of_ints = ptr_to_array_of_3_ints; // ERROR -
+ ptr_to_array_of_3_ints = ptr_to_array_of_ints; // ERROR -
diff --git a/gcc/testsuite/g++.old-deja/g++.bugs/900322_01.C b/gcc/testsuite/g++.old-deja/g++.bugs/900322_01.C
index 961d95c08a9..388071e4fa0 100644
--- a/gcc/testsuite/g++.old-deja/g++.bugs/900322_01.C
+++ b/gcc/testsuite/g++.old-deja/g++.bugs/900322_01.C
@@ -1,51 +1,20 @@
-// g++ 1.37.1 bug 900322_01
-
-// The ANSI C standard, in section 3.1.2.5 (first paragraph) differentiates
-// types into three disjoint sets, i.e object types, function types, and
-// incomplete types.
-
-// Also in 3.1.2.5 (page 24) the standard says that the element type of
-// an array type is an object type.
-
-// Later in that same section the standard also notes that array types with
-// unknown size are considered incomplete types (page 25). (Struct & union
-// types which have only been "forward declared" are also incomplete types.)
-
-// Some experts infer this to mean that it is not legal to specify or to
-// construct an array *type* whose element type is an incomplete type.
-
-// This interpretation suggests that the statements indicated below contain
-// errors.
-
-// g++ fails to flag all of the indicated statements with errors (even when
-// the -pedantic option is used).
-
-// keywords: incomplete types, arrays, element types
-
-extern int extern_two_d [] []; // ERROR - , XFAIL *-*-*
-int tenative_two_d [] []; // ERROR - caught by g++
-static int static_two_d [] []; // ERROR - caught by g++
-
-int (*pointer_to_two_d)[][]; // ERROR - , XFAIL *-*-*
-
-void function_0 (int arg [] []) { /* ERROR - */
-}
-
-typedef int int_one_d_type [];
-typedef int_one_d_type int_two_d_type[];// ERROR - , XFAIL *-*-*
-
-struct s;
-
-extern struct s extern_s_array [10]; // ERROR - , XFAIL *-*-*
-struct s tenative_s_array [10]; /* ERROR - caught by g++ */
-static struct s static_s_array [10]; /* ERROR - caught by g++ */
-
-struct s (*pointer_to_s_array) []; // ERROR - , XFAIL *-*-*
-
-void function_1 (struct s arg []) { // ERROR - , XFAIL *-*-*
-}
-
-typedef struct s s_type;
-typedef s_type s_one_d_type [10]; // ERROR - , XFAIL *-*-*
-
-int main () { return 0; }
+// ** Old, obsolete commentary:
+// **************************************************************************
+// **************************************************************************
+
+// The above commentary is wrong. (jason 1998/11/13)
+// In fact, the lines marked OK are well-formed; the prohibition is only
+// against forming array types with multiple unknown bounds. This prohibition
+// is found in 8.3.4 [dcl.array].
+
+// It is also ill-formed to create an object of incomplete type.
+extern int extern_two_d [] []; // ERROR - invalid declaration
+int (*pointer_to_two_d)[][]; // ERROR - invalid declaration
+void function_0 (int arg [] []) { // ERROR - invalid declaration
+typedef int_one_d_type int_two_d_type[];// ERROR - invalid declaration
+extern struct s extern_s_array [10]; // OK
+struct s tenative_s_array [10]; // ERROR - object with incomplete type
+static struct s static_s_array [10]; // ERROR - object with incomplete type
+struct s (*pointer_to_s_array) []; // OK
+void function_1 (struct s arg []) { // OK
+typedef s_type s_one_d_type [10]; // OK
diff --git a/gcc/testsuite/g++.old-deja/g++.bugs/900428_01.C b/gcc/testsuite/g++.old-deja/g++.bugs/900428_01.C
index b46fc466529..55b1aa86bb0 100644
--- a/gcc/testsuite/g++.old-deja/g++.bugs/900428_01.C
+++ b/gcc/testsuite/g++.old-deja/g++.bugs/900428_01.C
@@ -1,51 +1,26 @@
-// g++ 1.37.1 bug 900428_01
-
-// g++ fails to issue error messages for cases where an incomplete type
-// object must be evaluated if the value of such an evaluation is not
-// actually used in the given context.
-
-// In the case where such an object is volatile, it is obvious that this
-// could be a problem, however I believe that errors should be issued
-// for such cases regardless of whether or not such values are volatile
-// because the abstract semantics seem to require the evaluation of such
-// values whether they are volatile or not.
-
-// keywords: incomplete types, evaluation, volatile qualifier
-// Build don't link:
-
-int i;
-
-void *pv;
-volatile void *pvv;
-struct s;
-extern struct s es, *ps;
-extern volatile struct s evs, *pvs;
-
-void pv_test ()
-{
- *pv; // ERROR - , XFAIL *-*-*
- (i ? *pv : *pv); // ERROR - , XFAIL *-*-*
- *pv, *pv; // ERROR - , XFAIL *-*-*
-
- *pvv; // ERROR - , XFAIL *-*-*
- (i ? *pvv : *pvv); // ERROR - , XFAIL *-*-*
- *pvv, *pvv; // ERROR - , XFAIL *-*-*
-
- es; // ERROR - , XFAIL *-*-*
- (i ? es : es); // ERROR - , XFAIL *-*-*
- es, es; // ERROR - , XFAIL *-*-*
-
- evs; // ERROR - , XFAIL *-*-*
- (i ? evs : evs); // ERROR - , XFAIL *-*-*
- evs, evs; // ERROR - , XFAIL *-*-*
-
- *ps; // ERROR - , XFAIL *-*-*
- (i ? *ps : *ps); // ERROR - , XFAIL *-*-*
- *ps, *ps; // ERROR - , XFAIL *-*-*
-
- *pvs; // ERROR - , XFAIL *-*-*
- (i ? *pvs : *pvs); // ERROR - , XFAIL *-*-*
- *pvs, *pvs; // ERROR - , XFAIL *-*-*
-}
-
-int main () { return 0; }
+struct s; // ERROR - forward declaration
+extern struct s es, *ps; // ERROR - defined here
+extern volatile struct s evs, *pvs; // ERROR - defined here
+ *pv; // ERROR - invalid void
+ (i ? *pv : *pv); // ERROR - invalid void
+ *pv, *pv; // ERROR - invalid void
+
+ *pvv; // ERROR - invalid void
+ (i ? *pvv : *pvv); // ERROR - invalid void
+ *pvv, *pvv; // ERROR - invalid void
+
+ es; // ERROR - incomplete
+ (i ? es : es); // ERROR - undefined type
+ es, es; // ERROR - incomplete
+
+ evs; // ERROR - incomplete
+ (i ? evs : evs); // ERROR - undefined type
+ evs, evs; // ERROR - incomplete
+
+ *ps; // ERROR - undefined type
+ (i ? *ps : *ps); // ERROR - undefined type
+ *ps, *ps; // ERROR - undefined type
+
+ *pvs; // ERROR - undefined type
+ (i ? *pvs : *pvs); // ERROR - undefined type
+ *pvs, *pvs; // ERROR - undefined type
diff --git a/gcc/testsuite/g++.old-deja/g++.bugs/900511_02.C b/gcc/testsuite/g++.old-deja/g++.bugs/900511_02.C
index 0154bfe4140..300e2121c16 100644
--- a/gcc/testsuite/g++.old-deja/g++.bugs/900511_02.C
+++ b/gcc/testsuite/g++.old-deja/g++.bugs/900511_02.C
@@ -1,21 +1,4 @@
-// g++ 1.37.1 bug 900511_02
-
-// g++ does not properly shadow names of types with names of data members
-// in cases where the type names in question are used in the context of
-// formal parameters lists for member functions.
-
-// keywords: typedef names, shadowing, scope, formal parameter list
-
-// cfront 2.0 passes this test.
-
-enum enum0 { enum0_value_0 }; // ERROR -
-
-struct struct0 {
- int enum0; // ERROR -
- void member_function (enum0 e);
-};
-
-void class0::member_function (enum0 e) { // ERROR -
-}
-
-int main () { return 0; }
+enum enum0 { enum0_value_0 };
+ int enum0;
+ void member_function (enum0 e); // ERROR - invalid use of struct-local member
+void class0::member_function (enum0 e) { // ERROR - syntax error
diff --git a/gcc/testsuite/g++.old-deja/g++.bugs/900511_03.C b/gcc/testsuite/g++.old-deja/g++.bugs/900511_03.C
index d8a549aa82c..18dea85b397 100644
--- a/gcc/testsuite/g++.old-deja/g++.bugs/900511_03.C
+++ b/gcc/testsuite/g++.old-deja/g++.bugs/900511_03.C
@@ -1,19 +1,3 @@
-// g++ 1.37.1 bug 900511_03
-
-// g++ does not properly shadow names of types with names of data members
-// in cases where the type names in question are used in the context of
-// formal parameters lists for member functions.
-
-// keywords: typedef names, shadowing, scope, formal parameter list
-
-class class0; // ERROR -
-
-struct struct1 {
- int class0; // ERROR -
- void member_function (class0 *);
-};
-
-void class1::member_function (class0 *p) { // ERROR -
-}
-
-int main () { return 0; }
+class class0;
+ int class0;
+ void member_function (class0 *); // ERROR - invalid use of struct-local member
diff --git a/gcc/testsuite/g++.old-deja/g++.bugs/900519_13.C b/gcc/testsuite/g++.old-deja/g++.bugs/900519_13.C
index 8161b59b801..7d5b25fd2b8 100644
--- a/gcc/testsuite/g++.old-deja/g++.bugs/900519_13.C
+++ b/gcc/testsuite/g++.old-deja/g++.bugs/900519_13.C
@@ -1,35 +1,3 @@
-// g++ 1.37.1 bug 900519_13
-
-// If multiple inheritance creates a situation in which a given name is
-// inherited from more than one base class, and if the inherited declarations
-// for the name are for different categories of members (e.g. object members,
-// function members, enumeral members), then g++ will (in some cases) fail
-// to flag errors when the ambiguous name is used.
-
-// cfront 2.0 passes this test.
-
-// keywords: inheritance, ambiguity resolution, members
-
-struct base_0 {
- enum { base_member };
-};
-
-struct base_1 {
- int base_member;
-};
-
-struct base_2 {
- int base_member ();
-};
-
-struct derived_0 : public base_0, public base_1 {
- void member () { base_member; } // ERROR -
-};
-
-struct derived_1 : public base_0, public base_2 {
- void member () { base_member; } // ERROR - missed
-};
-
-struct derived_2 : public base_1, public base_2 {
- void member () { base_member; } // ERROR - missed
-};
+ enum { base_member }; // ERROR - candidate (26, 30)
+ int base_member; // ERROR - candidate (26, 34)
+ int base_member (); // ERROR - candidate (30, 34)
diff --git a/gcc/testsuite/g++.old-deja/g++.bugs/900520_02.C b/gcc/testsuite/g++.old-deja/g++.bugs/900520_02.C
index 05c880d2e3c..9b58e81156b 100644
--- a/gcc/testsuite/g++.old-deja/g++.bugs/900520_02.C
+++ b/gcc/testsuite/g++.old-deja/g++.bugs/900520_02.C
@@ -1,34 +1,3 @@
-// g++ 1.37.1 bug 900520_02
-
-// g++ fails to allow a reference to an unbounded array type to be passed
-// into a formal parameter whose type is pointer-to-bounded-array type.
-
-// Cases other than parameter passing in which similar initializations
-// take place are allowed however.
-
-// cfront 2.0 passes this test.
-
-// keywords: reference types, initialization, parameter passing
-
-typedef int b_array[3];
-typedef int u_array[];
-
-typedef b_array &b_array_ref;
-typedef u_array &u_array_ref;
-
-void take_b_array_ref (b_array_ref arg) { }
-
-extern u_array u_array_gbl_obj;
-
-u_array_ref u_array_ref_gbl_obj0 = u_array_gbl_obj;
-
-b_array_ref b_array_ref_gbl_obj0 = u_array_ref_gbl_obj0; // OK
-
-void test_passing ()
-{
- take_b_array_ref (u_array_ref_gbl_obj0); // gets bogus error
-}
-
-b_array u_array_gbl_obj;
-
-int main () { return 0; }
+void take_b_array_ref (b_array_ref arg) { } // ERROR - passed to here
+b_array_ref b_array_ref_gbl_obj0 = u_array_ref_gbl_obj0; // ERROR - invalid declaration
+ take_b_array_ref (u_array_ref_gbl_obj0); // ERROR - invalid call
diff --git a/gcc/testsuite/g++.old-deja/g++.eh/flow1.C b/gcc/testsuite/g++.old-deja/g++.eh/flow1.C
index 81c70af3108..024670cf347 100644
--- a/gcc/testsuite/g++.old-deja/g++.eh/flow1.C
+++ b/gcc/testsuite/g++.old-deja/g++.eh/flow1.C
@@ -5,7 +5,7 @@ int bar ()
throw 100;
}
-main ()
+int main ()
{
int i = 0; // this gets deleted after flow analysis
try
diff --git a/gcc/testsuite/g++.old-deja/g++.eh/new1.C b/gcc/testsuite/g++.old-deja/g++.eh/new1.C
index 3f7ebbcba19..1671dbbe7de 100644
--- a/gcc/testsuite/g++.old-deja/g++.eh/new1.C
+++ b/gcc/testsuite/g++.old-deja/g++.eh/new1.C
@@ -17,7 +17,7 @@ void foo (B*);
int newed, created;
-main ()
+int main ()
{
try {
foo (new B (A ()));
diff --git a/gcc/testsuite/g++.old-deja/g++.eh/new2.C b/gcc/testsuite/g++.old-deja/g++.eh/new2.C
index 6699f94aa9f..ddc8ba82e58 100644
--- a/gcc/testsuite/g++.old-deja/g++.eh/new2.C
+++ b/gcc/testsuite/g++.old-deja/g++.eh/new2.C
@@ -17,8 +17,9 @@ void foo (B*);
int newed, created;
-main ()
+int main ()
{
+ newed = 0; // The libraries might call new before main starts.
try {
foo (new B (A ()));
} catch (...) { }
diff --git a/gcc/testsuite/g++.old-deja/g++.eh/pdel1.C b/gcc/testsuite/g++.old-deja/g++.eh/pdel1.C
index b30b402d1be..b8e553c0e2f 100644
--- a/gcc/testsuite/g++.old-deja/g++.eh/pdel1.C
+++ b/gcc/testsuite/g++.old-deja/g++.eh/pdel1.C
@@ -12,7 +12,7 @@ struct A {
void * operator new (size_t size, int, int) { return operator new (size); }
-main ()
+int main ()
{
try {
A* ap = new (1, 5) A;
diff --git a/gcc/testsuite/g++.old-deja/g++.eh/pdel2.C b/gcc/testsuite/g++.old-deja/g++.eh/pdel2.C
index c9b9bd13edd..12efcd386cf 100644
--- a/gcc/testsuite/g++.old-deja/g++.eh/pdel2.C
+++ b/gcc/testsuite/g++.old-deja/g++.eh/pdel2.C
@@ -12,7 +12,7 @@ struct A {
void * operator new (size_t size, int, int) { return operator new (size); }
-main ()
+int main ()
{
try {
A* ap = new (1, 5) A;
diff --git a/gcc/testsuite/g++.old-deja/g++.eh/rethrow3.C b/gcc/testsuite/g++.old-deja/g++.eh/rethrow3.C
index bea447bf27f..5da2081b1b9 100644
--- a/gcc/testsuite/g++.old-deja/g++.eh/rethrow3.C
+++ b/gcc/testsuite/g++.old-deja/g++.eh/rethrow3.C
@@ -31,7 +31,7 @@ eh_test (int level)
}
}
-main ()
+int main ()
{
std::set_terminate (&eh_terminate);
eh_test (0);
diff --git a/gcc/testsuite/g++.old-deja/g++.eh/spec1.C b/gcc/testsuite/g++.old-deja/g++.eh/spec1.C
index 8f450706b04..044af8cdb9b 100644
--- a/gcc/testsuite/g++.old-deja/g++.eh/spec1.C
+++ b/gcc/testsuite/g++.old-deja/g++.eh/spec1.C
@@ -13,7 +13,7 @@ f () throw (char, int, std::bad_exception)
throw 'a';
}
-main ()
+int main ()
{
std::set_terminate (my_term);
std::set_unexpected (my_unexp);
diff --git a/gcc/testsuite/g++.old-deja/g++.eh/spec2.C b/gcc/testsuite/g++.old-deja/g++.eh/spec2.C
index 41774bf7de4..d0269b3a4be 100644
--- a/gcc/testsuite/g++.old-deja/g++.eh/spec2.C
+++ b/gcc/testsuite/g++.old-deja/g++.eh/spec2.C
@@ -13,7 +13,7 @@ f () throw (int, std::bad_exception)
throw 'a';
}
-main ()
+int main ()
{
std::set_terminate (my_term);
std::set_unexpected (my_unexp);
diff --git a/gcc/testsuite/g++.old-deja/g++.eh/spec3.C b/gcc/testsuite/g++.old-deja/g++.eh/spec3.C
index 602cd6f5b61..57b29d48908 100644
--- a/gcc/testsuite/g++.old-deja/g++.eh/spec3.C
+++ b/gcc/testsuite/g++.old-deja/g++.eh/spec3.C
@@ -13,7 +13,7 @@ f () throw (std::bad_exception)
throw 'a';
}
-main ()
+int main ()
{
std::set_terminate (my_term);
std::set_unexpected (my_unexp);
diff --git a/gcc/testsuite/g++.old-deja/g++.eh/spec4.C b/gcc/testsuite/g++.old-deja/g++.eh/spec4.C
index adcf6751b1a..a92f7f06469 100644
--- a/gcc/testsuite/g++.old-deja/g++.eh/spec4.C
+++ b/gcc/testsuite/g++.old-deja/g++.eh/spec4.C
@@ -13,7 +13,7 @@ f () throw (short)
throw 'a';
}
-main ()
+int main ()
{
std::set_terminate (my_term);
std::set_unexpected (my_unexp);
diff --git a/gcc/testsuite/g++.old-deja/g++.ext/default.C b/gcc/testsuite/g++.old-deja/g++.ext/default.C
index 24f336e5882..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.ext/default.C
+++ b/gcc/testsuite/g++.old-deja/g++.ext/default.C
@@ -1,26 +1 @@
-// PRMS Id: 5353
-// This may be an extension, but it's a very common one...
-
-extern "C" int printf (const char *, ...);
-
-class A {
-public:
- static A*func (int = 3);
- static A*(*ptr)(int = 4);
-};
-
-A*(*A::ptr)(int) = &A::func;
-
-main()
-{
- A foo;
-
- A::ptr();
- A::ptr(47);
-}
-
-A*A::func(int i)
-{
- printf("I = %d\n",i);
- return (A*)0;
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.ext/implicit1.C b/gcc/testsuite/g++.old-deja/g++.ext/implicit1.C
index 399d2329758..33b9450f6be 100644
--- a/gcc/testsuite/g++.old-deja/g++.ext/implicit1.C
+++ b/gcc/testsuite/g++.old-deja/g++.ext/implicit1.C
@@ -1,5 +1,5 @@
// test for implicit declaration
-// Special g++ Options: -w
+// Special g++ Options: -w -fpermissive
int
main ()
diff --git a/gcc/testsuite/g++.old-deja/g++.ext/null1.C b/gcc/testsuite/g++.old-deja/g++.ext/null1.C
index 6650cbedde8..fca7aa3a92f 100644
--- a/gcc/testsuite/g++.old-deja/g++.ext/null1.C
+++ b/gcc/testsuite/g++.old-deja/g++.ext/null1.C
@@ -1,8 +1 @@
-// Test for overloading with g++ NULL.
-
-void f (int *) { }
-void f (char, char);
-main ()
-{
- f (__null);
-}
+int main ()
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/2371.C b/gcc/testsuite/g++.old-deja/g++.jason/2371.C
index a659b4eaea4..b11db5e0b33 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/2371.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/2371.C
@@ -502,7 +502,7 @@ operator<<(ostream& o, const SLS& s)
SLS gsls;
const SLS gcsls;
-foo()
+int foo()
{
const unsigned SIZE = 20;
@@ -563,7 +563,7 @@ foo()
}
// Dummy function so it'll run
-main()
+int main()
{
cout << "PASS" << endl;
}
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/access16.C b/gcc/testsuite/g++.old-deja/g++.jason/access16.C
index 16a132a5b9f..b3b753c1a91 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/access16.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/access16.C
@@ -1,20 +1 @@
-// Bug: g++ uses the same binfo for the a subobject of c and the a subobject
-// of b, so basetype_paths get bashed improperly.
-// Build don't link:
-
-class a {
-protected:
- virtual void foo() { } // gets bogus error
-};
-
-class b : public virtual a {};
-
-class c : public b {
-public:
- void bar() { b::foo(); } // gets bogus error
-};
-
-main() {
- c test;
- test.bar();
-}
+int main() {
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/access17.C b/gcc/testsuite/g++.old-deja/g++.jason/access17.C
index 9ed7d30d2a5..aaa1768b6a8 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/access17.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/access17.C
@@ -1,24 +1 @@
-// Make sure definitions of static members have the right access.
-// Build don't link:
-
-struct A {
-protected:
- int i;
- int f (); // ERROR -
-};
-
-struct B: public A {
- static int A::*p;
- static int (A::*fp)();
-};
-
-int A::* B::p = &A::i;
-int (A::* B::fp)() = &A::f;
-
-struct C {
- static int A::*p;
- static int (A::*fp)();
-};
-
-int A::* C::p = &A::i; // ERROR -
-int (A::* C::fp)() = &A::f; // ERROR -
+ int i; // ERROR - private
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/access22.C b/gcc/testsuite/g++.old-deja/g++.jason/access22.C
index 736a053a591..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/access22.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/access22.C
@@ -1,21 +1 @@
-// PRMS Id: 8518
-// Bug: Call to foo is not checked for accessibility
-
-class A
-{
- private:
- static void foo() {} // ERROR -
- public:
- void goo() {}
-};
-
-struct B : public A
-{
- void func() { foo(); } // ERROR -
-};
-
-main()
-{
- B b;
- b.func();
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/access23.C b/gcc/testsuite/g++.old-deja/g++.jason/access23.C
index 57331687b7a..7975de2d8b5 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/access23.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/access23.C
@@ -1,79 +1,11 @@
-// PRMS Id: 9127
-// Bug: members of anonymous unions are not access-controlled.
-
-#include <stdio.h>
-
-struct Foo {
-public:
- union {
- long A;
- void *pX;
- };
- union X {
- long A;
- void *pX;
- } PUB ;
- int PUB_A;
-protected:
- union {
- long B;
- void *pY;
- } ;
- union Y {
- long B;
- void *pY;
- } PRT;
- int PRT_A;
-private:
- union {
- long C;
- void *pZ;
- };
- union Z {
- long C;
- void *pZ;
- } PRV;
- int PRV_A;
-};
-
-struct Bar : public Foo {
-public:
- DoSomething() {
- PUB_A = 0;
- Foo::A = 0;
- printf("%x\n",pX);
- Foo::PUB.A = 0;
- printf("%x\n",PUB.pX);
- B = 0;
- printf("%x\n",Foo::pY);
- PRT_A = 0;
- PRT.B = 0;
- printf("%x\n",Foo::PRT.pY);
- PRV_A = 0; // ERROR -
- Foo::C = 0; // ERROR -
- printf("%x\n",pZ); // ERROR -
- Foo::PRV.C = 0; // ERROR -
- printf("%x\n",PRV.pZ); // ERROR -
- }
-};
-
-main()
-{
- Foo a;
-
- a.PUB_A = 0;
- a.A = 0;
- printf("%x\n",a.pX);
- a.PRT_A = 0; // ERROR -
- a.B = 0; // ERROR -
- printf("%x\n",a.pY); // ERROR -
- a.PRV_A = 0; // ERROR -
- a.C = 0; // ERROR -
- printf("%x\n",a.pZ); // ERROR -
- a.PUB.A = 0;
- printf("%x\n",a.PUB.pX);
- a.PRT.B = 0; // ERROR -
- printf("%x\n",a.PRT.pY); // ERROR -
- a.PRV.C = 0; // ERROR -
- printf("%x\n",a.PRV.pZ); // ERROR -
-}
+ long B; // ERROR - protected
+ void *pY; // ERROR - protected
+ } PRT; // ERROR - protected
+ int PRT_A; // ERROR - protected
+ long C; // ERROR - private
+ void *pZ; // ERROR - private
+ long C;
+ } PRV; // ERROR - private
+ int PRV_A; // ERROR - private
+ void DoSomething() {
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/access7.C b/gcc/testsuite/g++.old-deja/g++.jason/access7.C
index 708fa0fb626..788c86bff4f 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/access7.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/access7.C
@@ -1,13 +1 @@
-// Simple testcase for access control.
-// Build don't link:
-
-class A {
- protected:
- static void f ();
-};
-
-class B: public A {};
-class C: public A {};
-class D: public C, public B {
- void g () { A::f(); } // gets bogus error - wrongly ambiguous static member call, XFAIL *-*-*
-};
+ void g () { A::f(); } // gets bogus error - wrongly ambiguous static member call
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/aggregate.C b/gcc/testsuite/g++.old-deja/g++.jason/aggregate.C
index b451b23ef7c..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/aggregate.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/aggregate.C
@@ -1,13 +1 @@
-struct A { int i; };
-
-main()
-{
- A a1 = { 42 };
- A a2 (a1);
- A a3 = { 137 };
- a1 = a3;
-
- if (a1.i == 137 && a2.i == 42 && a3.i == 137)
- return 0;
- return 1;
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/binding.C b/gcc/testsuite/g++.old-deja/g++.jason/binding.C
index 0a013abd73e..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/binding.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/binding.C
@@ -1,11 +1 @@
-// Bug: g++ only looks in the current temporary binding level for a name.
-
-struct T { ~T(); };
-
-main()
-{
- foo:
- T t; // ERROR - redeclared
- bar:
- T t; // ERROR - redeclaration
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/bool2.C b/gcc/testsuite/g++.old-deja/g++.jason/bool2.C
index 4c0edcb3596..559b7d07615 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/bool2.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/bool2.C
@@ -5,7 +5,7 @@ struct F {
bool b2 : 7;
};
-main()
+int main()
{
F f = { true, true };
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/bool4.C b/gcc/testsuite/g++.old-deja/g++.jason/bool4.C
index 36a2180c927..fca7aa3a92f 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/bool4.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/bool4.C
@@ -1,10 +1 @@
-// Test for allowing conversion to bool.
-
-struct A { };
-
-main ()
-{
- bool b = (void*)0;
- b = (int A::*)0;
- b = (int (A::*)())0;
-}
+int main ()
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/bool5.C b/gcc/testsuite/g++.old-deja/g++.jason/bool5.C
index 79d848c0b19..fca7aa3a92f 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/bool5.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/bool5.C
@@ -1,10 +1 @@
-main ()
-{
- bool b = false;
- int i = b++;
- if (i != false || b != true)
- return 1;
- i = b++;
- if (i != true || b != true)
- return 1;
-}
+int main ()
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/bool6.C b/gcc/testsuite/g++.old-deja/g++.jason/bool6.C
index b8db8722b8f..fca7aa3a92f 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/bool6.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/bool6.C
@@ -1,9 +1 @@
-// Bug: The conversion from bool to int gets stripped.
-// Build don't link:
-
-bool b;
-
-main ()
-{
- return ((!b) != 0);
-}
+int main ()
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/byval.C b/gcc/testsuite/g++.old-deja/g++.jason/byval.C
index 45fb1e2836b..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/byval.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/byval.C
@@ -1,19 +1 @@
-// Bug: a is destroyed in both foo() and main()
-
-int count;
-
-struct A {
- double a,b;
- A(int) { count++; }
- A(const A&) { count++; }
- ~A() { count--; }
-};
-
-void foo (A a)
-{ }
-
-main()
-{
- foo (1);
- return count;
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/cleanup2.C b/gcc/testsuite/g++.old-deja/g++.jason/cleanup2.C
index 21addfe67d7..b3b753c1a91 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/cleanup2.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/cleanup2.C
@@ -1,15 +1 @@
-// PRMS Id: 6303
-// Bug: compiler crashes processing the cleanup for arrayOfClass.
-// Build don't link:
-
-class Class {
-public:
- ~Class(); // This dtor MUST be declared to generate the error...
-};
-
-Class varOfClass;
-
-main() {
- // This MUST be 'const' to generate the error...
- const Class arrayOfClass[1] = { varOfClass }; // causes abort
-}
+int main() {
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/cond.C b/gcc/testsuite/g++.old-deja/g++.jason/cond.C
index 8f4da347bb6..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/cond.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/cond.C
@@ -1,39 +1 @@
-// Build don't link:
-// GROUPS passed rtti
-// Negative testcase for decls in conditions.
-
-main()
-{
- float i;
-
- if (int i = 1) // ERROR - , XFAIL *-*-*
- {
- char i; // ERROR - , XFAIL *-*-*
- char j;
- }
- else
- {
- short i; // ERROR - , XFAIL *-*-*
- char j;
- }
-
- if (struct A { operator int () { return 1; } } *foo = new A) // ERROR -
- ;
-
- A bar; // ERROR -
-
- if (enum A { one, two, three } foo = one) // ERROR -
- ;
-
- struct B { operator int () { return 2; } };
-
- if (struct B * foo = new B)
- ;
-
- if (int f () = 1) // ERROR -
- ;
-
- if (int a[2] = {1, 2}) // ERROR -
- ;
-
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/cond2.C b/gcc/testsuite/g++.old-deja/g++.jason/cond2.C
index 890c3193d3d..fca7aa3a92f 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/cond2.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/cond2.C
@@ -1,65 +1 @@
-// Positive testcase for decls in conditions.
-
-extern "C" int printf(const char *, ...);
-
-int up = 0;
-int down = 0;
-
-struct T
-{
- int i;
- T(int j) { i = j; printf("UP\n"); up++; }
- T(const T& t) { i = t.i; printf("unwanted copy\n"); }
- ~T() { printf ("DOWN\n"); down++; }
- operator int () { return i; }
-};
-
-main ()
-{
- int t;
-
- if (T t = 1)
- ;
-
- printf ("\n");
-
- int j = 3;
- while (T t = j--)
- ;
-
- printf ("\n");
-
- j = 3;
- while (1)
- {
- T t = j--;
- if (t) continue;
- break;
- }
-
- printf ("\n");
-
- j = 3;
- for (;T t = j--;)
- ;
-
- printf ("\n");
-
- for (int k = 3; T t = k--;)
- ;
-
- printf ("\n");
-
- switch (T t = 34)
- {
- case 34:
- ;
- }
-
- printf ("\n");
-
- if (up == down && up == 18)
- return 0;
- else
- return 1;
-}
+int main ()
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/const2.C b/gcc/testsuite/g++.old-deja/g++.jason/const2.C
index 3aeae3c7e71..8b8d58de0ed 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/const2.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/const2.C
@@ -1,14 +1 @@
-// Example of static member constants
-
-extern "C" int printf (const char *, ...);
-
-struct T {
- static const char letter = 'a'; // this is the new stuff!
- char x[letter];
- void f();
-};
-
-void T::f() { printf ("%p", &letter); }
-const char T::letter; // still need def after class
-
-main() { }
+int main() { }
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/const3.C b/gcc/testsuite/g++.old-deja/g++.jason/const3.C
index 49360a4fabe..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/const3.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/const3.C
@@ -1,10 +1 @@
-// Bug: bar isn't emitted, which causes havoc.
-
-extern int i;
-const int bar = i;
-int i = 5;
-
-main()
-{
- return bar != 5;
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/conversion6.C b/gcc/testsuite/g++.old-deja/g++.jason/conversion6.C
index 42b9ac226d8..090a634bc24 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/conversion6.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/conversion6.C
@@ -1,40 +1 @@
-// PRMS Id: g++/6034
-
-extern "C" int printf (const char *, ...);
-
-class Base
-{
- char x;
-};
-
-template <class T>
-// remove the public Base inheritance and the problem goes away...
-class Container : public Base
-{
-public:
-
- Container(const T& aValue): myValue(aValue) { }
-
- operator const T&(void) const
- {
- printf("Container::const T& called\n");
- return myValue;
- }
-
-protected:
-
- T myValue;
-};
-
-typedef unsigned short Type;
-
-typedef Container<Type> TypeContainer;
-
-main(void)
-{
- TypeContainer myTypeContainer(2);
- Type t = myTypeContainer;
-
- printf ("myType = %d\n", t);
- return t != 2;
-}
+int main(void)
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/conversion8.C b/gcc/testsuite/g++.old-deja/g++.jason/conversion8.C
index fc4de8111b8..fca7aa3a92f 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/conversion8.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/conversion8.C
@@ -1,10 +1 @@
-// PRMS id: 8279
-
-main ()
-{
- char *const *p = 0;
- char **q = 0;
-
- (void)(p - q);
- (void)(q - p);
-}
+int main ()
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/crash8.C b/gcc/testsuite/g++.old-deja/g++.jason/crash8.C
index 4482a43f4bc..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/crash8.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/crash8.C
@@ -1,9 +1 @@
-struct A {
- A();
- A(A); // ERROR - copy ctor must take reference
-};
-main()
-{
- A a;
- A b(a); // causes compiler segfault
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/ctor1.C b/gcc/testsuite/g++.old-deja/g++.jason/ctor1.C
index 69afd425519..106ff4283c9 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/ctor1.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/ctor1.C
@@ -1,26 +1,2 @@
-// PRMS Id: 5584
-
-extern "C"
-{
- struct xx {
- void (*xx)(void);
- int x,y;
- };
-}
-
-int r = 1;
-
-void f(void)
-{
- r = 0;
-}
-
-main()
-{
- struct xx p;
-
- p.xx = f;
- p.xx();
-
- return r;
-}
+ void (*xx)(void); // ERROR - field with name of class
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/dcast2.C b/gcc/testsuite/g++.old-deja/g++.jason/dcast2.C
index 2ba1357fd62..fca7aa3a92f 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/dcast2.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/dcast2.C
@@ -1,18 +1 @@
-struct A { virtual void f() { } };
-struct B { virtual void g() { } };
-struct C : public A, public B { };
-
-main ()
-{
- C* cp = 0;
- B* bp = 0;
-
- if (dynamic_cast <B*> (cp) != 0)
- return 1;
-
- if (dynamic_cast <void *> (bp) != 0)
- return 1;
-
- if (dynamic_cast <C*> (bp) != 0)
- return 1;
-}
+int main ()
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/dcast3.C b/gcc/testsuite/g++.old-deja/g++.jason/dcast3.C
index 1dc00a138eb..fca7aa3a92f 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/dcast3.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/dcast3.C
@@ -1,32 +1 @@
-// Testcase for tricky dynamic cast situations.
-
-struct A {
- virtual void f () { }
-};
-
-struct B : public A { };
-struct C : public B { };
-struct D : public B { };
-struct E : public C, public D { };
-
-struct B2 : public virtual A { };
-struct C2 : public B2 { };
-struct D2 : public B2 { };
-struct E2 : public C2, public D2 { };
-
-main ()
-{
- E e;
- E2 e2;
-
- A* ap = (C*)&e;
-
- // ap points to base subobject of unique B; succeeds
- if (dynamic_cast <B*> (ap) == 0)
- return 1;
-
- ap = (C2*)&e2;
- // ap points to base subobject shared by two Bs; fails
- if (dynamic_cast <B2*> (ap) != 0)
- return 1;
-}
+int main ()
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/default1.C b/gcc/testsuite/g++.old-deja/g++.jason/default1.C
index e6ef57768e0..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/default1.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/default1.C
@@ -1,16 +1 @@
-// PRMS Id: 5204
-// Bug: g++ bashes the type of add_sym with the type of add, so calling it
-// with one parameter generates an error.
-// Build don't link:
-
-int add(int const &symbol,
- const unsigned char flags=(void*)0); // ERROR - invalid default arg
-
-int add_sym(int const &symbol,
- const unsigned char flags=0);
-
-main()
-{
- int fname;
- add_sym(fname); // Guarantee a symbol exists
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/defctor.C b/gcc/testsuite/g++.old-deja/g++.jason/defctor.C
index 252d43ef6ad..765014bc66d 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/defctor.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/defctor.C
@@ -1,15 +1 @@
-// Bug: g++ doesn't generate default constructor.
-
-class A {
-public:
- int i;
-};
-
-extern "C" int printf(const char *, ...);
-
-main () {
- A a;
- a.i = 1;
- A b (a);
- printf("%d\n",b.i);
-}
+int main () {
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/destruct.C b/gcc/testsuite/g++.old-deja/g++.jason/destruct.C
index a9d7e86a467..fca7aa3a92f 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/destruct.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/destruct.C
@@ -1,33 +1 @@
-// Exhaustive test for destructors of simple types.
-// PRMS Id: 2744, 3308
-// Build don't link:
-
-template <class T> class A {
- T q;
-public:
- ~A() {
- q.T::~T();
- q.~T();
- (&q)->T::~T();
- (&q)->~T();
- }
-};
-
-typedef char * cp;
-
-main ()
-{
- A<int> a;
- A<cp> b;
- int i;
- cp c;
-
- i.~int();
- i.int::~int();
- (&i)->~int();
- (&i)->int::~int();
- c.~cp();
- c.cp::~cp();
- (&c)->~cp();
- (&c)->cp::~cp();
-}
+int main ()
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/dot.C b/gcc/testsuite/g++.old-deja/g++.jason/dot.C
index 7f4bd7776d4..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/dot.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/dot.C
@@ -1,20 +1 @@
-// PRMS Id: 4143
-// Bug: Pointer is silently dereferenced in method call.
-// Build don't link:
-
-extern "C" int printf (const char *, ...);
-
-class Test
-{
- char ch;
- public:
- Test(char c) : ch(c) {}
- void Print() { printf("%c", ch); }
-};
-
-main()
-{
- Test *p = new Test('x');
-
- p.Print(); // ERROR -
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/dtor.C b/gcc/testsuite/g++.old-deja/g++.jason/dtor.C
index c9e71628d09..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/dtor.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/dtor.C
@@ -1,13 +1 @@
-struct A {
- ~A();
-};
-
-struct B {
- ~B();
-};
-
-main()
-{
- A a;
- a.~B(); // ERROR - wrong name
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/dtor2.C b/gcc/testsuite/g++.old-deja/g++.jason/dtor2.C
index 7f975136e8d..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/dtor2.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/dtor2.C
@@ -1,10 +1 @@
-// PRMS Id: 5163
-// Bug: g++ doesn't accept the explicit destructor call syntax for templates.
-
-template <class T> struct A { };
-A<int> a;
-
-main()
-{
- a.~A(); // gets bogus error
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/dtor5.C b/gcc/testsuite/g++.old-deja/g++.jason/dtor5.C
index 8ad14eabce8..4761bedf2cc 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/dtor5.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/dtor5.C
@@ -12,7 +12,7 @@ template <class T> struct A {
~A() { p[--i].~T(); r = i; }
};
-main()
+int main()
{
{ A<int> a; }
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/enum8.C b/gcc/testsuite/g++.old-deja/g++.jason/enum8.C
index 811b44cf29b..fca7aa3a92f 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/enum8.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/enum8.C
@@ -1,20 +1 @@
-// Bug: the switch fails on the Alpha because folding ef - 1 fails.
-
-enum foo { one=1, thirty=30 };
-
-int f (enum foo ef)
-{
- switch (ef)
- {
- case one:
- case thirty:
- return 0;
- default:
- return 1;
- }
-}
-
-main ()
-{
- return f (one);
-}
+int main ()
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/friend.C b/gcc/testsuite/g++.old-deja/g++.jason/friend.C
index ee6ee8d5eae..fca7aa3a92f 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/friend.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/friend.C
@@ -1,18 +1 @@
-// Bug: g++ doesn't keep track of the lexical context of friends properly.
-
-extern "C" void exit(int);
-
-struct B;
-struct A {
- static void f () { exit (1); }
-};
-
-struct B {
- static void f () { exit (0); }
- friend void g () { f (); }
-};
-
-main ()
-{
- g ();
-}
+int main ()
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/groff1.C b/gcc/testsuite/g++.old-deja/g++.jason/groff1.C
index 79a96438ad9..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/groff1.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/groff1.C
@@ -1,40 +1 @@
-// PRMS Id: 3744
-// Bug: unswitching a COND_EXPR initializer fails to set SIDE_EFFECTS on the
-// result, so expand_expr ignores it.
-
-extern "C" {
- int printf(const char *,...);
- void exit(int);
-}
-
-struct A {
- int x;
- int y;
-
- A() : x(0), y(0) { }
-};
-
-struct S {
- S() : flags(0) { }
- unsigned flags;
- A from;
- void foo(const A &pos);
-};
-
-void S::foo(const A &pos)
-{
- A a = flags ? from : pos;
- printf("%d %d\n", a.x, a.y);
- if (a.x != 17 || a.y != 12)
- exit (1);
-}
-
-main()
-{
- A pos;
- pos.x = 17;
- pos.y = 12;
- S s;
- s.foo(pos);
- return 0;
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/hmc1.C b/gcc/testsuite/g++.old-deja/g++.jason/hmc1.C
index 751cf80f481..b3b753c1a91 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/hmc1.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/hmc1.C
@@ -1,19 +1 @@
-// Build don't link:
-// GROUPS passed templates default-arguments
-template <class I>
-class Class {
-public:
- void func1(int n=1);
- void func2(int d) {}
-};
-template <class I>
-void Class<I>::func1(int n) {}
-
-//if this is replaced by:
-//void Class<I>::func1(int n=1) {}
-//the code compiles.
-
-main() {
- Class<int> C;
- return 0;
-}
+int main() {
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/init2.C b/gcc/testsuite/g++.old-deja/g++.jason/init2.C
index dcee91835dc..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/init2.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/init2.C
@@ -1,9 +1 @@
-// PRMS Id: 5126
-
-extern int i, j;
-static const int foo [] = { i, j };
-int i = 5, j = 42;
-main()
-{
- return foo[1] != 42;
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/init3.C b/gcc/testsuite/g++.old-deja/g++.jason/init3.C
index bb3d0d8cf10..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/init3.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/init3.C
@@ -1,42 +1 @@
-// PRMS Id: 5652
-// Bug: strings does not get initialized.
-
-extern "C" void * memcpy (void *, const void *, __SIZE_TYPE__);
-extern "C" int strcmp (const char *, const char *);
-
-class My_string {
- char *str;
- int len;
-public:
- My_string(const char* string);
- My_string(const My_string &);
- ~My_string() { delete str; }
- char* char_p() { return str; }
-};
-
-const My_string strings[4] = {
- "first string",
- "second string",
- "third string",
- "fourth string"
-};
-
-My_string::My_string(const char* string)
-{
- len = strlen(string) + 1;
- str = new char[len];
- memcpy(str, string, len);
-}
-
-My_string::My_string(const My_string &string)
-{
- len = string.len;
- str = new char[len];
- memcpy(str, string.str, len);
-}
-
-main()
-{
- My_string str1 = strings[0];
- return strcmp ("first string", str1.char_p ()) != 0;
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/inline.C b/gcc/testsuite/g++.old-deja/g++.jason/inline.C
index ac140ab6744..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/inline.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/inline.C
@@ -1,21 +1 @@
-// PRMS Id: 4341
-// Bug: Instantiating a template in the middle of processing the functions
-// from another template screws up lineno/input_filename.
-
-#pragma implementation "C.h"
-#line 1 "A.h"
-#pragma interface
-template <class T> class A {};
-#line 1 "C.h"
-#pragma interface
-template <class T> class C
-{
-public:
- C() { A<T> *ap; }
- ~C() { }
-};
-#line 18 "inline.C"
-main()
-{
- C<int> c;
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/jump.C b/gcc/testsuite/g++.old-deja/g++.jason/jump.C
index 754e7006c36..b3b753c1a91 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/jump.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/jump.C
@@ -1,14 +1 @@
-// PRMS Id: 6036
-
-extern int a;
-
-main() {
- switch (a) {
- case 1:
- int v2 = 3; // ERROR - referenced below
- case 2: // ERROR - jumping past initializer
- if (v2 == 7)
- ;
- }
- return 0;
-}
+int main() {
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/lex1.C b/gcc/testsuite/g++.old-deja/g++.jason/lex1.C
index 69fb0b7bbea..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/lex1.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/lex1.C
@@ -1,6 +1 @@
-main()
-{
- char c = '\351';
- if (c != '\351')
- return 1;
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/lineno5.C b/gcc/testsuite/g++.old-deja/g++.jason/lineno5.C
index f15aef05fce..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/lineno5.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/lineno5.C
@@ -1,10 +1 @@
-// Build don't link:
-// GROUPS passed error-reporting
-// Bug: incomplete instantiation messes with lineno
-template <class T> class A;
-
-main()
-{
- A<int> *p;
- undef1();// ERROR -
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/lvalue4.C b/gcc/testsuite/g++.old-deja/g++.jason/lvalue4.C
index f308213bcc4..b3b753c1a91 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/lvalue4.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/lvalue4.C
@@ -1,6 +1 @@
-main() {
- int i = 2;
- int *pi = &(++i);
-
- return i != 3;
-}
+int main() {
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/member1.C b/gcc/testsuite/g++.old-deja/g++.jason/member1.C
deleted file mode 100644
index c25a1904a4a..00000000000
--- a/gcc/testsuite/g++.old-deja/g++.jason/member1.C
+++ /dev/null
@@ -1,4 +0,0 @@
-// Build don't link:
-
-struct S { int S; } object;
-struct S function () { return object; }
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/mi.C b/gcc/testsuite/g++.old-deja/g++.jason/mi.C
index eaf59b20233..fca7aa3a92f 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/mi.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/mi.C
@@ -1,16 +1 @@
-int status;
-
-struct A { virtual void foo () { status = 1; } };
-struct B { };
-struct C : public A, public B { };
-struct D { virtual void baz () { } };
-struct E : public D, public C { void foo () { status = 0; } };
-
-main ()
-{
- E* ep = new E;
-
- ep->foo();
-
- return status;
-}
+int main ()
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/mutable1.C b/gcc/testsuite/g++.old-deja/g++.jason/mutable1.C
index 9298d2ef882..fca7aa3a92f 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/mutable1.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/mutable1.C
@@ -1,11 +1 @@
-struct X
-{
- X () { }
- mutable int x;
-};
-
-main ()
-{
- const X x;
- x.x = 0;
-}
+int main ()
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/new.C b/gcc/testsuite/g++.old-deja/g++.jason/new.C
index 0ac2562d7f9..ce865696078 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/new.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/new.C
@@ -13,13 +13,13 @@ void * operator new (size_t siz) throw (std::bad_alloc) {
return malloc (siz);
}
-main()
+int main()
{
s = 0;
float f = 3;
int* b1 = new int[(int)f];
- int* b2 = new int[f];
+ int* b2 = new int[f]; // ERROR - new requires integral size
return s;
}
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/new5.C b/gcc/testsuite/g++.old-deja/g++.jason/new5.C
index 70f5ec5d475..fca7aa3a92f 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/new5.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/new5.C
@@ -1,5 +1 @@
-main ()
-{
- const int *p = new const int (0);
- delete p;
-}
+int main ()
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/offset2.C b/gcc/testsuite/g++.old-deja/g++.jason/offset2.C
index 787e3f12081..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/offset2.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/offset2.C
@@ -1,23 +1 @@
-// PRMS Id: 5070 (testcase 2)
-
-int status = 1;
-
-struct foo {
- foo& operator= (const foo&) { status = 0; }
-};
-
-struct xx {
- foo a;
-};
-
-struct yy : public xx {
- yy(foo& a) { xx::a = a; }
-};
-
-main()
-{
- foo f;
- yy y (f);
-
- return status;
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/operator.C b/gcc/testsuite/g++.old-deja/g++.jason/operator.C
index e71c4e10544..bd21e378e14 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/operator.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/operator.C
@@ -2,7 +2,7 @@
// Build don't link:
// Special g++ Options:
-typedef unsigned long size_t;
+typedef __SIZE_TYPE__ size_t;
struct A {
int operator?:(int a, int b); // WARNING -
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/overload11.C b/gcc/testsuite/g++.old-deja/g++.jason/overload11.C
index e8c043f0545..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/overload11.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/overload11.C
@@ -1,17 +1 @@
-// PRMS Id: 4697
-// Bug: g++ calls the non-const method for a const object.
-
-class A {
-public:
- void foo(int &i) const { i = 0; }
- void foo(int &i) { i = 1; }
-};
-
-main()
-{
- A a;
- const A& b = a;
- int i = 2;
- b.foo (i);
- return i;
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/overload12.C b/gcc/testsuite/g++.old-deja/g++.jason/overload12.C
index dc336c5caed..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/overload12.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/overload12.C
@@ -1,15 +1 @@
-// PRMS Id: 4066
-// Bug: g++ doesn't notice the const on reference returns.
-
-struct B {
- int foo() { return 1; }
- int foo() const { return 0; }
-};
-
-B b_;
-const B &b () { return b_; }
-
-main()
-{
- return b().foo();
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/overload13.C b/gcc/testsuite/g++.old-deja/g++.jason/overload13.C
index 602dc2b4e1d..b3b753c1a91 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/overload13.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/overload13.C
@@ -1,27 +1 @@
-// Bug: g++ screws up derived->base conversions when calling a global function
-// in the presence of matching members in the base. Whew.
-
-struct xios {
- virtual ~xios() { }
-};
-
-struct xistream: virtual public xios {
- int j;
- void operator>>(char&);
-};
-
-struct xfstreambase: virtual public xios { };
-
-struct xifstream: public xfstreambase, public xistream { };
-
-void operator>>(xistream& i, int j)
-{
- i.j = 0;
-}
-
-main() {
- int i;
- xifstream ifs;
-
- ifs >> i;
-}
+int main() {
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/overload16.C b/gcc/testsuite/g++.old-deja/g++.jason/overload16.C
index e1b7f3f8a1f..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/overload16.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/overload16.C
@@ -1,6 +1 @@
-void f (int); // ERROR -
-void f (long); // ERROR -
-main()
-{
- f (1 & 0xffffff00UL); // ERROR - ambiguous
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/overload20.C b/gcc/testsuite/g++.old-deja/g++.jason/overload20.C
index dde686c5c30..8f72c24e975 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/overload20.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/overload20.C
@@ -1,11 +1,2 @@
-// Bug: this code causes an internal compiler error 4.
-
-void f (char *);
-void f (int);
-struct A {
- void f ();
- void f (int);
- void g () {
- void (*p)(char *) = f; // ERROR - no matching function in scope
- }
-};
+ void f (); // ERROR - candidate
+ void f (int); // ERROR - candidate
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/overload23.C b/gcc/testsuite/g++.old-deja/g++.jason/overload23.C
index 1cc1d0bc3fb..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/overload23.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/overload23.C
@@ -1,27 +1 @@
-// From: panisset@cae.ca (Jean-Francois Panisset)
-// Date: Mon, 6 Jun 94 13:39:25 EDT
-// Subject: Problem with operator overloading
-
-// Build don't link:
-
-class ostream {
-public:
- ostream& operator<<(double n);
- ostream& operator<<(float n);
-};
-
-class X
-{
-public:
- operator long() const;
- operator double() const;
-};
-ostream& operator<< (ostream& os, const X& x);
-
-
-main()
-{
- X x;
- ostream os;
- os << x; // gets bogus error - converting to float
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/overload26.C b/gcc/testsuite/g++.old-deja/g++.jason/overload26.C
index 872b0b206e0..fca7aa3a92f 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/overload26.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/overload26.C
@@ -1,22 +1 @@
-// Bug: g++ tries to build up a mangled name for its ideal match, which
-// fails for one call below.
-// Build don't link:
-
-extern const char foo[];
-extern const char baz[10];
-extern const char *fred;
-
-struct A {
- void f(const char *);
-} *a;
-
-void bing(const char *);
-main ()
-{
- a->f(foo); // gets bogus error because foo's size unknown.
- a->f(baz);
- a->f(fred);
- bing(fred);
- bing(foo);
- bing(baz);
-}
+int main ()
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/overload27.C b/gcc/testsuite/g++.old-deja/g++.jason/overload27.C
index 3ae1a1dab5e..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/overload27.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/overload27.C
@@ -1,7 +1 @@
-void f(const int &) { }
-void f(const float &);
-
-main()
-{
- f(false); // gets bogus error
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/overload28.C b/gcc/testsuite/g++.old-deja/g++.jason/overload28.C
index e94e97872ec..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/overload28.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/overload28.C
@@ -1,11 +1 @@
-// PRMS Id: 6056
-
-struct Foo {
- Foo() { } // ERROR - candidate
- Foo(int i = 25) { } // ERROR - candidate
-};
-
-main()
-{
- Foo* f1 = new Foo(); // ERROR - ambiguous
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/parse10.C b/gcc/testsuite/g++.old-deja/g++.jason/parse10.C
index 477f7f53a63..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/parse10.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/parse10.C
@@ -1,15 +1 @@
-// Testcase for precedence of ?: wrt =
-
-extern "C" int printf (const char *, ...);
-
-main()
-{
- int j = 0, k = 0;
- 1 ? j : k = 5; // should be parsed 1 ? j : (k = 5)
- (void) (1 ? k = 5 : 0);
- k = 5 ? 1 : 0; // should be parsed k = (5 ? 1 : 0)
-
- printf ("%d %d\n", j, k);
-
- return j == 5 || k == 5;
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/parse12.C b/gcc/testsuite/g++.old-deja/g++.jason/parse12.C
index 7829a8b1b0d..fca7aa3a92f 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/parse12.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/parse12.C
@@ -1,17 +1 @@
-// PRMS Id: 6821
-
-struct A {
- int operator()(int i) { return i; }
-};
-
-struct B {
- A* p;
- int f () { return (*p)(42); } // gets bogus error
-};
-
-main ()
-{
- B b = { new A };
-
- return b.f () != 42;
-}
+int main ()
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/parse9.C b/gcc/testsuite/g++.old-deja/g++.jason/parse9.C
index 62836e46438..4a01ce93b8e 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/parse9.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/parse9.C
@@ -1,18 +1 @@
-// PRMS Id: 5720
-// Bug: the extra set of parens confuses the expr/declarator disambiguation.
-
-class Fu
-{
- int val;
-public:
- Fu(int i) : val(i) { };
- void print() { }
-};
-
-main(int argc, char * argv[])
-{
- int * i = &argc;
-
- Fu((*i)).print(); // gets bogus error
- Fu((*j));
-}
+int main(int argc, char * argv[])
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/pmem2.C b/gcc/testsuite/g++.old-deja/g++.jason/pmem2.C
index f8d9797a2ce..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/pmem2.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/pmem2.C
@@ -1,43 +1 @@
-template <class Called>
-class aCallback
-{
-public:
- aCallback(Called& obj, int (Called::*met)());
-
- int callback();
-
-protected:
-
-private:
- Called& object;
-
- int (Called::*method)();
-
-};
-
-template <class Called>
-aCallback<Called>::aCallback(Called& obj,
- int (Called::*met)()) :
-object(obj),
-method(met)
-{};
-
-template <class Called>
-int aCallback<Called>::callback()
-{
- return (object.*method)();
-}
-
-struct myStruct
-{
- int action() {return 0;};
-};
-
-main()
-{
- myStruct toto;
-
- aCallback<myStruct> cb(toto, &myStruct::action);
-
- return cb.callback();
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/pmem3.C b/gcc/testsuite/g++.old-deja/g++.jason/pmem3.C
index 343953b9604..fca7aa3a92f 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/pmem3.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/pmem3.C
@@ -1,11 +1 @@
-// Test that comparison of pointers to members does not complain about
-// contravariance violation.
-
-struct A { int i; };
-struct B : public A { int j; int f (); };
-main ()
-{
- int A::*apm = &A::i;
- int B::*bpm = apm;
- return apm != bpm;
-}
+int main ()
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/pmf2.C b/gcc/testsuite/g++.old-deja/g++.jason/pmf2.C
index c3decc2e639..5c2b2f5ddc6 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/pmf2.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/pmf2.C
@@ -1,13 +1 @@
-// PRMS Id: 4484 (bug 3)
-// Bug: g++ does implicitly take the address of methods passed to fns.
-// Build don't link:
-
-struct A {
- void f ();
-};
-
-void g (void (A::*)());
-
-void h () {
- g (A::f); // ERROR - failed conversion to method pointer XFAIL *-*-*
-}
+ g (A::f); // ERROR - failed conversion to method pointer
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/pmf7.C b/gcc/testsuite/g++.old-deja/g++.jason/pmf7.C
index 303dfb9b241..fca7aa3a92f 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/pmf7.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/pmf7.C
@@ -1,27 +1 @@
-// PRMS Id: 6486
-// Make sure that no confused handling of COND_EXPRs and SAVE_EXPRs messes
-// with the number of calls to foo.
-
-int c;
-
-struct A {
- void f () {}
- virtual void g () {}
-};
-
-A& foo ()
-{
- static A a;
- ++c;
- return a;
-}
-
-main ()
-{
- void (A::*p)() = &A::f;
- (foo ().*p)();
- p = &A::g;
- (foo ().*p)();
-
- return 2 - c;
-}
+int main ()
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/pmf8.C b/gcc/testsuite/g++.old-deja/g++.jason/pmf8.C
index 97f551eb9bf..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/pmf8.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/pmf8.C
@@ -1,29 +1 @@
-// PRMS Id: 6905
-
-class Parent {
-public:
- void DoSomething() { return; };
- int i;
-};
-
-class Child : public Parent {
-public:
-};
-
-class User {
-public:
- void DoAnyThing(void (Parent::*)(void)) { return; }
- void DoAThing(void (Child::*)(void)) { return; }
- void DoAThing(int Child::*) { return; }
-};
-
-
-main()
-{
- User a;
-
- a.DoAnyThing(&Child::DoSomething);
- a.DoAThing(&Child::DoSomething);
- a.DoAThing(&Parent::DoSomething);
- a.DoAThing(&Parent::i);
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/ref10.C b/gcc/testsuite/g++.old-deja/g++.jason/ref10.C
index faadb2e79da..b3b753c1a91 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/ref10.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/ref10.C
@@ -1,31 +1 @@
-// Test that conversion from D* to B*& works properly.
-
-extern "C" int printf (const char *, ...);
-
-struct V {
- int a;
-};
-
-struct B: virtual V {
- int b;
-};
-
-struct D: B {
- int c;
-};
-
-V* gp = 0;
-
-void foo(V * const &r) {
- gp = r;
-}
-
-int bar(V *r) {
- return (r != gp);
-}
-
-main() {
- D *p = new D;
- foo(p);
- return bar(p);
-}
+int main() {
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/ref12.C b/gcc/testsuite/g++.old-deja/g++.jason/ref12.C
index 7a33647ffb6..fca7aa3a92f 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/ref12.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/ref12.C
@@ -1,5 +1 @@
-void f (char *const &) { }
-main ()
-{
- f ("hi");
-}
+int main ()
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/ref5.C b/gcc/testsuite/g++.old-deja/g++.jason/ref5.C
index ca0135323b5..8d513781cd2 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/ref5.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/ref5.C
@@ -1,10 +1,3 @@
-// Build don't link:
-// Special g++ Options: -w
-int i;
-int &const j = i;
-int &const f();
-void g ()
-{
- j = 1;
- f() = 1;
-}
+
+int &const j = i; // ERROR - invalid const
+int &const f(); // ERROR - invalid const
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/ref7.C b/gcc/testsuite/g++.old-deja/g++.jason/ref7.C
index ba7bd1d2cb1..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/ref7.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/ref7.C
@@ -1,21 +1 @@
-// Testcase for the lifetime of a temporary object which is used to
-// initialize a reference.
-
-int destroyed = 0;
-
-struct A {
- A() { }
- A(int) { }
- ~A() { destroyed++; }
-};
-
-A a;
-A foo () { return a; }
-
-main()
-{
- const A& ar = foo();
- const A& ar2 = A();
- const A& ar3 = (A)1;
- return destroyed;
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/ref8.C b/gcc/testsuite/g++.old-deja/g++.jason/ref8.C
index 53f9c1ceef9..b3b753c1a91 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/ref8.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/ref8.C
@@ -1,17 +1 @@
-// PRMS Id: 5184
-// Bug: cast to C& below does not adjust address
-
-struct A {};
-struct B {
- virtual void foo () {};
-};
-struct C : public B, public A {};
-
-main() {
- C c;
-
- A& ar = c;
- C& cr = (C&)ar;
-
- cr.foo(); // this line causes core dump
-}
+int main() {
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/return3.C b/gcc/testsuite/g++.old-deja/g++.jason/return3.C
index 61e3dda02ce..fca7aa3a92f 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/return3.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/return3.C
@@ -1,19 +1 @@
-// PRMS id: 10912
-
-struct A {
- A() { i=10; };
- int i;
-};
-struct B : public A {};
-B b;
-
-A f()
-{
- return b;
-}
-
-main ()
-{
- A a = f ();
- return a.i != 10;
-}
+int main ()
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/rvalue2.C b/gcc/testsuite/g++.old-deja/g++.jason/rvalue2.C
index 522c35fb003..fca7aa3a92f 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/rvalue2.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/rvalue2.C
@@ -1,17 +1 @@
-// Test for undesired aliasing.
-
-struct A {
- const A * get_this () const { return this; }
-};
-
-main ()
-{
- A a;
- int r = 0;
- const A& ar1 = (A)a;
- if (&ar1 == &a)
- r |= 1;
- if (A(a).get_this () == &a)
- r |= 2;
- return r;
-}
+int main ()
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/rvalue3.C b/gcc/testsuite/g++.old-deja/g++.jason/rvalue3.C
index 12fe76d3163..fca7aa3a92f 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/rvalue3.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/rvalue3.C
@@ -1,5 +1 @@
-main ()
-{
- int i;
- int &ir = (int&)(int)i; // ERROR - casting rvalue to reference type
-}
+int main ()
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/scoping17.C b/gcc/testsuite/g++.old-deja/g++.jason/scoping17.C
index a05acef3d91..fca7aa3a92f 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/scoping17.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/scoping17.C
@@ -1,8 +1 @@
-// Test that the integer hides the struct in block scope.
-
-main ()
-{
- int A;
- struct A { };
- A = 1;
-}
+int main ()
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/scoping4.C b/gcc/testsuite/g++.old-deja/g++.jason/scoping4.C
index 33f11a672ec..b3b753c1a91 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/scoping4.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/scoping4.C
@@ -1,30 +1 @@
-// PRMS Id: 4375
-// Bug: g++ fails to keep track of nested typedefs properly.
-// Build don't link:
-
-class A {
-public:
- typedef char * Ptr;
- Ptr s;
- Ptr get_string();
- A(Ptr string); // { s = string; };
-};
-
-class B {
-public:
- typedef A * Ptr;
- Ptr a;
- Ptr get_A();
- B(Ptr a_ptr);
-};
-
-A::A(Ptr string) { // gets bogus error -
- s = string; // gets bogus error -
-}
-
-main() {
- A a("testing");
- A *a_ptr;
- B b(&a);
- a_ptr = b.get_A();
-}
+int main() {
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/static1.C b/gcc/testsuite/g++.old-deja/g++.jason/static1.C
index 994da851039..8c5bdff359b 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/static1.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/static1.C
@@ -25,7 +25,7 @@ extern AAA arr1[];
AAA arr1[] = {(int)E1 };
-main()
+int main()
{
return 0;
}
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/synth5.C b/gcc/testsuite/g++.old-deja/g++.jason/synth5.C
index cfc68c53448..8b8d58de0ed 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/synth5.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/synth5.C
@@ -1,14 +1 @@
-// Bug: generated B::operator= tries to call A::operator=
-
-#pragma implementation
-#line 1 "synth5.h"
-#pragma interface
-
-struct A {
- virtual A& operator= (const A&) = 0;
-};
-
-struct B: public A {
-};
-#line 5 "synth5.C"
-main() { }
+int main() { }
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/synth7.C b/gcc/testsuite/g++.old-deja/g++.jason/synth7.C
index 1d4264b2983..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/synth7.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/synth7.C
@@ -1,11 +1 @@
-// Testcase to make sure that synthesized methods are found when needed.
-
-struct B { ~B() { } };
-struct A { B b; };
-
-main()
-{
- A a, b (a), c = A();
- A& (A::*afp)(const A&) = &A::operator=;
- (a.*afp) (b);
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/tempdest.C b/gcc/testsuite/g++.old-deja/g++.jason/tempdest.C
index 78fb75df22c..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/tempdest.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/tempdest.C
@@ -1,20 +1 @@
-// Build don't link:
-// GROUPS passed templates destructors
-// Example of PR 3308 workaround
-
-template <class T>
-class A
-{
- T q;
-public:
- ~A() { (&q)->T::~T(); }
-};
-
-typedef unsigned int ui;
-
-main()
-{
- A<ui> *ap = new A<ui>;
-
- delete ap;
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/template11.C b/gcc/testsuite/g++.old-deja/g++.jason/template11.C
index 25449e2e742..fca7aa3a92f 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/template11.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/template11.C
@@ -1,14 +1 @@
-// Bug: initializers for static data members of templates don't get run.
-
-template <class T> struct A {
- static T t;
-};
-
-int foo () { return 1; }
-
-int A<int>::t = foo ();
-
-main ()
-{
- return (A<int>::t != 1);
-}
+int main ()
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/template13.C b/gcc/testsuite/g++.old-deja/g++.jason/template13.C
index 75bd64d7ff3..fbd16a9995e 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/template13.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/template13.C
@@ -5,6 +5,6 @@
template <class T> inline T min (T a, T b) { return a<b?a:b; }
double min (double, double);
-main () {
+int main () {
return (int) min (0, 1.0);
}
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/template14.C b/gcc/testsuite/g++.old-deja/g++.jason/template14.C
index 464638d5b55..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/template14.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/template14.C
@@ -1,16 +1 @@
-// PRMS Id: 4745
-// Bug: g++ gets the constructor and destructor confused because the default
-// parm prevents the two constructor types from satisfying ==.
-
-template <class T> struct A {
- A(int = 1);
- ~A();
-};
-
-template <class T> A<T>::A(int) { } // causes compiler abort
-template <class T> A<T>::~A() { }
-
-main()
-{
- A<int> a;
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/template15.C b/gcc/testsuite/g++.old-deja/g++.jason/template15.C
index 99e129bea89..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/template15.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/template15.C
@@ -1,27 +1 @@
-// PRMS Id: 2139
-// Bug: g++ tries to instantiate the template with types on the function
-// obstack and fails.
-
-template<class T>
-class X {
-public:
- X(int) { }
-
- T x;
-};
-
-class A { };
-
-main()
-{
- int i;
- X<int> xi(i);
- X<double> xd(i);
-
- X<int (*)(int, void *)> fp0(i);
- X<int (*)(int, char, double)> fp1(i);
- X<int (*)(int, double**, void *)> fp2(i);
-
- X<int (A::*)()> mp0 (i);
- X<int A::*> mp1 (i);
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/template18.C b/gcc/testsuite/g++.old-deja/g++.jason/template18.C
index bcee653c64e..5a660df5982 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/template18.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/template18.C
@@ -1,16 +1,9 @@
-// Build don't link:
-// Special g++ Options: -g -fexternal-templates
-// GROUPS passed templates
-// Bug: g++ emits template instances when it shouldn't.
-// Special g++ Options: -g -fexternal-templates
+// We mark this XFAIL because we can't test for expected linker errors.
+// If we get an XPASS for this testcase, that's a bug.
+// (OK) excess errors test - XFAIL *-*-*
-#pragma implementation "irrelevant_file"
-#line 1 "wa.h"
-#pragma interface // ERROR - , XFAIL *-*-*
-template <class T> inline T min (T a, T b) { return a<b?a:b; }
-#line 3 "wa.C"
-
-main()
-{
- min (1, 1);
-}// UNKNOWN "min"
+#line 1 "template18.h"
+#pragma interface
+#line 13 "template18.C"
+ min (1, 1); // should produce an undefined symbol error.
+}
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/template19.C b/gcc/testsuite/g++.old-deja/g++.jason/template19.C
index ab344432530..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/template19.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/template19.C
@@ -1,9 +1 @@
-// Make sure type deduction isn't confused by top-level cv-quals.
-template <class T> T max (const T a, const T b) { return a>b?a:b; }
-
-main()
-{
- int a = 0, b = 1;
- int c = max (a, b);
- int d = max ((const int)a, (const int)b);
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/template20.C b/gcc/testsuite/g++.old-deja/g++.jason/template20.C
index fe776c9ff21..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/template20.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/template20.C
@@ -1,9 +1 @@
-// Make sure type deduction works for both types of array parameters.
-template <class T> void f (T (&a)[2]) { }
-template <class T> void g (T a[2]) { }
-main()
-{
- int a[2] = { 0, 0 };
- f (a);
- g (a);
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/template22.C b/gcc/testsuite/g++.old-deja/g++.jason/template22.C
index db2c6202767..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/template22.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/template22.C
@@ -1,31 +1 @@
-// Testcase for proper unification of code involving references.
-// Build don't link:
-
-template<class T>
-struct A
-{
- void foo();
-};
-
-template<class T> void A<T>::foo() { }
-
-template class A<int&>;
-
-const int& f1 ();
-int& f2 ();
-int f3 ();
-
-template <class T> void g1 (const T&);
-template <class T> void g2 (T&);
-template <class T> void g3 (T);
-
-main()
-{
- g1 (f1 ());
- g1 (f2 ());
- g1 (f3 ());
- g2 (f2 ());
- g3 (f1 ());
- g3 (f2 ());
- g3 (f3 ());
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/template24.C b/gcc/testsuite/g++.old-deja/g++.jason/template24.C
index c56d92a8564..fca7aa3a92f 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/template24.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/template24.C
@@ -1,21 +1 @@
-// Bug: g++ doesn't find the conversion from ostream_withassign to ostream.
-
-#include <iostream.h>
-
-template <class T>
-struct A {
- T t;
-};
-
-template <class T>
-ostream & operator<< (ostream & os, A<T> & a)
-{
- os << a.t;
- return os;
-}
-
-main ()
-{
- A<int> a = { 1 };
- cout << a << endl;
-}
+int main ()
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/template25.C b/gcc/testsuite/g++.old-deja/g++.jason/template25.C
index 4fc2a993863..fca7aa3a92f 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/template25.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/template25.C
@@ -1,48 +1 @@
-// PRMS Id: 6393
-// Bug: g++ is too lax in considering UPTs to be the same.
-
-template <class R, class T>
-class Bar
-{
-public:
- R do_bar (T arg);
-};
-
-
-template <class T>
-class Foo
-{
- T i;
-
-public:
- void do_foo () {}
- void do_foo (T const & t) {}
- void do_foo (Bar<char, T> const & bar); // {} Put the body here and it works
- void do_foo (Bar<T, T> const & bar); // {} Put the body here and it works
-};
-
-// These definitions don't work
-
-template <class T>
-inline void Foo<T>::
-do_foo (Bar<char, T> const & bar)
-{}
-
-template <class T>
-inline void Foo<T>::
-do_foo (Bar<T, T> const & bar)
-{}
-
-
-main ()
-{ int i;
- Bar<char, int> bar1;
- Bar<int, int> bar2;
- Foo<int> foo;
- foo.do_foo();
- foo.do_foo(i);
- foo.do_foo(bar1);
- foo.do_foo(bar2);
-
- return 0;
-}
+int main ()
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/template27.C b/gcc/testsuite/g++.old-deja/g++.jason/template27.C
index 3806da0ac7f..85cd2da835f 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/template27.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/template27.C
@@ -1,48 +1,3 @@
-// PRMS Id: 6826
-// Check that unnecessary templates are not instantiated.
-
-template <class T>
-class Test
-{
- public:
- void doThiss();
- void doThat();
-};
-
-template <class T>
-void Test<T>::doThiss()
-{
- T x;
-
- x.thiss();
-}
-
-template <class T>
-void Test<T>::doThat()
-{
- T x;
-
- x.that();
-}
-
-class A
-{
- public:
- thiss() {};
-};
-
-class B
-{
- public:
- that() {};
-};
-
-main()
-{
- Test<A> a;
- a.doThiss(); // a.doThat() is not well formed, but then
- // it's not used so needn't be instantiated.
-
- Test<B> b;
- b.doThat(); // simillarly b.doThiss();
-}
+ void thiss() {};
+ void that() {};
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/template3.C b/gcc/testsuite/g++.old-deja/g++.jason/template3.C
index e03b8a9ab35..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/template3.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/template3.C
@@ -1,14 +1 @@
-// PRMS Id: 4679
-// Bug: g++ doesn't re-instantiate templates after definition is seen.
-
-template <class T> struct A;
-
-A<int> *a;
-
-template <class T> struct A { T t; };
-
-main()
-{
- if (a)
- a->t = 1; // gets bogus error
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/template30.C b/gcc/testsuite/g++.old-deja/g++.jason/template30.C
index b9a6dbeaf3f..fca7aa3a92f 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/template30.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/template30.C
@@ -1,13 +1 @@
-template <class T, class U>
-int func(U, T); // ERROR - ref below
-
-template <class T, class U>
-int func(T, U)
-{ // ERROR - ref below
- return 2;
-}
-
-main ()
-{
- func (0, 1); // ERROR - ambiguous
-}
+int main ()
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/template31.C b/gcc/testsuite/g++.old-deja/g++.jason/template31.C
index 2ef14761bd4..06c55cb53e2 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/template31.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/template31.C
@@ -2,3 +2,4 @@
using std::vector;
template class std::__malloc_alloc_template<0>;
template class std::__default_alloc_template<false, 0>;
+int main(int argc, char**argv) {
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/template34.C b/gcc/testsuite/g++.old-deja/g++.jason/template34.C
index 76943291db8..b3b753c1a91 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/template34.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/template34.C
@@ -1,24 +1 @@
-template<class T>
-class Set {
- public:
- typedef int (*Compare)(const T&, const T&);
- static Compare cmp1;
- static int (*cmp2)(const T&, const T&);
-};
-
-template<class T>
-int gen_cmp(const T& a, const T& b) {
- if (a<b) return -1;
- else if (a==b) return 0;
- else return 1;
-}
-
-template<class T>
-Set<T>::Compare Set<T>::cmp1 = &gen_cmp;
-
-template<class T>
-int (*Set<T>::cmp2)(const T&, const T&) = &gen_cmp;
-
-main() {
- Set<int> s;
-}
+int main() {
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/template37.C b/gcc/testsuite/g++.old-deja/g++.jason/template37.C
index fc237ca439e..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/template37.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/template37.C
@@ -1,36 +1 @@
-// PRMS Id: 9930
-// Test of -fexternal-templates hackery in new template code
-// Special g++ options: -fexternal-templates
-
- #pragma implementation "foo.hh"
- #pragma interface "foo.hh"
-
- template<class T>
- class ONE
- {
- public:
- static void func();
- };
-
- template<class T>
- void ONE<T>::func()
- {
- }
-
- class ONE<int>
- {
- public:
- static void func();
- };
-
- void ONE<int>::func()
- {
- }
-
- main()
- {
- ONE<char>::func();
- ONE<int>::func();
-
- return 0;
- }
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/template40.C b/gcc/testsuite/g++.old-deja/g++.jason/template40.C
index 635dffcf143..7c71c9d6e22 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/template40.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/template40.C
@@ -1,19 +1 @@
-// PRMS id: 11315
-// Bug: g++ doesn't recognize the copy ctor for Array<long>.
-
-template <class Type>
-class Array {
-public:
- Array(int sz=12)
- : ia (new Type[sz]), size(sz) {}
- ~Array() { delete[] ia;}
- Array(const Array<long>& r) : size(0) {} // just for testing
-private:
- Type *ia;
- int size;
-};
-
-main(int argc, char *argv[])
-{
- Array<long> ia; // looping occurs on this line
-}
+int main(int argc, char *argv[])
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/template42.C b/gcc/testsuite/g++.old-deja/g++.jason/template42.C
index 529aaccd348..fca7aa3a92f 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/template42.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/template42.C
@@ -1,18 +1 @@
-// Testcase for not evaluating template default args if they are
-// never used.
-
-struct X {
- X(int) { }
-};
-
-template <class T>
-struct A {
- void f (T t = T()) { }
-};
-
-main ()
-{
- A<X> a;
- X x (1);
- a.f (x);
-}
+int main ()
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/template43.C b/gcc/testsuite/g++.old-deja/g++.jason/template43.C
index 62c7ee76182..fca7aa3a92f 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/template43.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/template43.C
@@ -1,30 +1 @@
-// Test matching of partial specializations.
-
-template <int* x, int* y>
-class EQUAL {
-public:
- enum { value = 0 };
-};
-template <int* x>
-class EQUAL<x,x> {
-public:
- enum { value = 1 };
-};
-
-int x;
-int y;
-
-int equals_x_x = EQUAL<&x,&x>::value; // expected value: 1
-int equals_x_y = EQUAL<&x,&y>::value; // expected value: 0
-int equals_y_x = EQUAL<&y,&x>::value; // expected value: 0
-int equals_y_y = EQUAL<&y,&y>::value; // expected value: 1
-
-main ()
-{
- if (equals_x_x == 1
- && equals_x_y == 0
- && equals_y_x == 0
- && equals_y_y == 1)
- return 0;
- return 1;
-}
+int main ()
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/temporary2.C b/gcc/testsuite/g++.old-deja/g++.jason/temporary2.C
index ea80a3fa6b9..b02dd1dad86 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/temporary2.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/temporary2.C
@@ -1,16 +1 @@
-class X // Indentation has been done so to see the similarities.
-{
-public:
- X() {} // ERROR - referenced below
- X(X& x) {x.i=7;} // ERROR - Both functions modify the
- void bar(X& x) {x.i=7;} // ERROR - reference parameter x.
- int i;
-};
-
-X foo() { X x; return x; }
-
-main()
-{
- X x(foo()); // ERROR - Compiler doesn't warn about temporary reference.
- x.bar(foo()); // ERROR - The same mistake is warned about in this case.
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/temporary3.C b/gcc/testsuite/g++.old-deja/g++.jason/temporary3.C
index ec5984c3aee..fca7aa3a92f 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/temporary3.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/temporary3.C
@@ -1,26 +1 @@
-// Bug: the temporary returned from f is elided, causing a to be constructed
-// twice but only destroyed once.
-
-extern "C" int printf (const char *, ...);
-
-int c,d;
-
-struct A {
- A (int) { c++; }
- ~A () { d++; }
- A (const A&) { c++; }
- int i;
-};
-
-A f ()
-{ return 1; }
-
-main ()
-{
- {
- A a (1);
- a = f ();
- }
- printf ("%d %d\n", c, d);
- return c != d;
-}
+int main ()
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/temporary4.C b/gcc/testsuite/g++.old-deja/g++.jason/temporary4.C
index 97ce95a81c0..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/temporary4.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/temporary4.C
@@ -1,31 +1 @@
-// Bug: g++ initializes both B::i and B::j before destroying any temps.
-
-extern "C" int printf (const char *, ...);
-
-int c = 0;
-int d = 0;
-int r = 0;
-
-struct A {
- A() { if (c != d) r = 1; ++c; }
- A(const A&); // declare so g++ returns A on the stack
- ~A() { ++d; }
- operator int () { return 0; }
-};
-
-A foo ()
-{
- return A();
-}
-
-struct B {
- int i;
- int j;
- B(): i(foo()), j(foo()) { }
-};
-
-main()
-{
- B b;
- return r;
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/temporary5.C b/gcc/testsuite/g++.old-deja/g++.jason/temporary5.C
index 07033d0e934..fca7aa3a92f 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/temporary5.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/temporary5.C
@@ -1,16 +1 @@
-// PRMS Id: 6604
-// Bug: Scoped constructor call is not properly recognized as a functional cast
-
-int c;
-
-struct A {
- A() { ++c; }
- ~A() { --c; }
- operator int () { return 1; }
-};
-
-main ()
-{
- A::A();
- return c;
-}
+int main ()
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/thunk3.C b/gcc/testsuite/g++.old-deja/g++.jason/thunk3.C
index 083eb045e54..a2a28c4a1d4 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/thunk3.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/thunk3.C
@@ -1 +1,4 @@
-// excess errors test - XFAIL mips*-*-* alpha*-*-* rs6000-*-* powerpc-*-eabi m68k-*-coff m68k-motorola-sysv m88k-motorola-sysv3
+// Test that variadic function calls using thunks work right.
+// Note that this will break on any target that uses the generic thunk
+// support, because it doesn't support variadic functions.
+
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/typeid1.C b/gcc/testsuite/g++.old-deja/g++.jason/typeid1.C
index 03601d670e1..8c0812bbcd3 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/typeid1.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/typeid1.C
@@ -1 +1,2 @@
const std::type_info &r = typeid (f);
+int main() {
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/typeid2.C b/gcc/testsuite/g++.old-deja/g++.jason/typeid2.C
index 16d5e970142..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/typeid2.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/typeid2.C
@@ -1,30 +1 @@
-// PRMS Id: 11596
-
-#include <typeinfo>
-extern "C" int printf (const char *, ...);
-
-class Chicken
-{
-public:
- int eggs_per_day;
-};
-
-template <class Bird>
-class Flock
-{
-public:
- Bird * flock_head;
- int head_count;
- void print_self() {
- printf ("A flock of %d %ss\n", head_count, typeid (Bird).name ());
- printf ("A flock of %d %ss\n", head_count, typeid (*flock_head).name ());
- }
-};
-
-main()
-{
- Flock<Chicken> x;
- printf ("%s\n", typeid(x).name());
- x.head_count = 42;
- x.print_self();
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/virtual.C b/gcc/testsuite/g++.old-deja/g++.jason/virtual.C
index 65e8c94f242..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/virtual.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/virtual.C
@@ -1,41 +1 @@
-// From: chw@bellcore.com (Charlie Woloszynski,MRE 2J-278,8295228,,27143)
-// Newsgroups: gnu.g++.bug
-// Subject: gcc-2.5.5 bug in multiple inheritance and pure virtual functions
-// Date: 25 Jan 1994 23:41:36 -0500
-
-// Bug: g++ fails to notice definitions of abstract virtuals.
-// Build don't link:
-
-class A
-{
-public:
- virtual void a1() = 0;
- virtual void a2() = 0;
-};
-
-class B
-{
-public:
- virtual void b1() = 0;
- virtual void b2() = 0;
-};
-
-
-class C: public A, public B
-{
-public:
- virtual void a2() {};
- virtual void b2() {};
-};
-
-class D : public C
-{
-public:
- virtual void a1() {};
- virtual void b1() {};
-};
-
-main()
-{
- D d; // gets bogus error
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/virtual2.C b/gcc/testsuite/g++.old-deja/g++.jason/virtual2.C
index 22b9fec5e74..fca7aa3a92f 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/virtual2.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/virtual2.C
@@ -1,13 +1 @@
-struct A {
- virtual A* f () { return this; }
-};
-
-struct B: public A {
- virtual B* f () { return 0; }
-};
-
-main ()
-{
- A* ap = new B;
- return (ap->f () != 0);
-}
+int main ()
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/warning2.C b/gcc/testsuite/g++.old-deja/g++.jason/warning2.C
index 778a6158a8c..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/warning2.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/warning2.C
@@ -1,14 +1 @@
-// g++ ought to warn about casting a base pointer to a derived reference.
-// Build don't link:
-
-struct A {
- virtual int f () = 0;
-};
-
-struct B: public A { int f () { } };
-
-main()
-{
- B* bp;
- A& ar = (A&)bp; // WARNING -
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/warning5.C b/gcc/testsuite/g++.old-deja/g++.jason/warning5.C
index ffa8713ea64..b5287f33795 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/warning5.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/warning5.C
@@ -1,23 +1 @@
-// PRMS Id: 5135
-// Bug: g++ complains that the result of the new expression is not used.
-// Special g++ Options: -Wall
-
-extern "C" int printf (const char *, ...);
-inline void * operator new (__SIZE_TYPE__, void *p) { return p; }
-
-class foo {
-public:
- foo() : a(42) {};
- int a;
-};
-
-main()
-{
- char buffer[1024];
-
- new (buffer) foo;
-
- foo* pY = (foo *)buffer;
-
- return pY->a != 42;
-}
+int
diff --git a/gcc/testsuite/g++.old-deja/g++.law/access2.C b/gcc/testsuite/g++.old-deja/g++.law/access2.C
index 02b27c3e8c6..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/access2.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/access2.C
@@ -1,20 +1 @@
-// Build don't link:
-// GROUPS passed access
-// access file
-// Message-Id: <9306301534.AA05072@sparc1.cnm.us.es>
-// From: juando@cnm.us.es (Juan D. Martin)
-// Subject: Compiler lets access to private constructor in template.
-// Date: Wed, 30 Jun 93 17:34:10 +0200
-
-template <class T> class Foo
-{
-private:
- friend class Bar; // To avoid warning.
- Foo(const T &v) {}; // ERROR - private
-};
-
-
-main()
-{
- Foo<int>(1);// ERROR -
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.law/arg1.C b/gcc/testsuite/g++.old-deja/g++.law/arg1.C
index f980874e48c..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/arg1.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/arg1.C
@@ -1,29 +1 @@
-// Build don't link:
-// GROUPS passed arg-matching
-// arg-matching file
-// Subject: argument matching depending on the def order
-// From: kondo@akane.mech.ibaraki.ac.jp
-// Date: Fri, 04 Sep 92 17:41:05 JST
-
-#include <iostream.h>
-// check the order of declarations
-class A {
-public:
- void f(double* p) { cout << "A(double*)\n"; } // ERROR - candidate
- void f(int* p) { cout << "A(int*)\n"; } // ERROR - candidate
-};
-
-class B {
-public:
- void f(int* p) { cout << "B(int*)\n"; } // ERROR - candidate
- void f(double* p) { cout << "B(double*)\n"; } // ERROR - candidate
-};
-
-main()
-{
- A a;
- B b;
-
- a.f(0);// ERROR - .*
- b.f(0);// ERROR - .*
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.law/arg11.C b/gcc/testsuite/g++.old-deja/g++.law/arg11.C
index 77ea8d84e45..70599cffd21 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/arg11.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/arg11.C
@@ -1,23 +1 @@
-// Build don't link:
-// GROUPS passed arg-matching
-// excess errors test - XFAIL *-*-*
-// From: gustavo@cpqd.br (Gustavo Chaves)
-// Date: Wed, 25 May 94 09:38:00 EST
-// Subject: problem with user defined conversions in initialization
-// Message-ID: <9405251238.AA19815@moon.cpqd.br>
-
-struct String { String(const char*); };
-
-struct Ack { Ack(String); };
-
-struct S { void method(Ack); };
-
-void function(Ack);
-
-int
-foo(S *o)
-{ // Neither call has a usable constructor for conversions of char[5] to Ack.
- function("adsf");// ERROR -
- o->method("adsf");// ERROR -
- return 0;
-}
+struct S { void method(Ack); }; // ERROR - referenced below
diff --git a/gcc/testsuite/g++.old-deja/g++.law/arg3.C b/gcc/testsuite/g++.old-deja/g++.law/arg3.C
index 0037c40d72a..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/arg3.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/arg3.C
@@ -1,22 +1 @@
-// Build don't link:
-// GROUPS passed arg-matching
-typedef void* Ptr;
-
-
-void func(int, const Ptr& p);
-
-template <class T> void func(T, const Ptr& p);
-
-
-Ptr& return_ref();
-
-
-main()
-{
- char* x;
-
- func(x,return_ref()); // bug:
- // call of func(int, const Ptr&)
- // instead of func(char*,const Ptr&)
-
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.law/arg7.C b/gcc/testsuite/g++.old-deja/g++.law/arg7.C
index 5cf1cd0b3d3..4e43abb0449 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/arg7.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/arg7.C
@@ -1,33 +1 @@
-// GROUPS passed arg-matching
-// arg-matching file
-// Message-Id: <9305041759.AA04913@malachite.bbn.com>
-// From: Dan Franklin <dan@diamond.bbn.com>
-// Subject: overloaded function resolved incorrectly
-// Date: Tue, 4 May 93 13:59:18 EDT
-
-#include <stdio.h>
-
-// Given the following overloaded function definitions
-
-void ovf(unsigned long, short, short) { printf ("PASS\n"); }
-void ovf( int, short, unsigned long) { printf ("FAIL\n"); }
-
-// and the call
-//
-// ovf(unsigned long, unsigned int, unsigned int)
-//
-// it seems to me (and to cfront) that this should resolve to ovf #1 above,
-// but g++ resolves it to ovf #2. Resolving to ovf #1 requires two conversions
-// (unsigned int => short) while resolving to ovf #2 takes two conversions
-// (unsigned long => int, unsigned int => short) and a promotion
-// (unsigned int => unsigned long).
-
-main(int, char**)
-{
- unsigned long pixmap = 0;
- unsigned int x = 0;
- unsigned int y = 0;
-
- ovf(pixmap, x, y);
- return 0;
-}
+int main(int, char**)
diff --git a/gcc/testsuite/g++.old-deja/g++.law/arg9.C b/gcc/testsuite/g++.old-deja/g++.law/arg9.C
index 809f2b76a4a..b3b753c1a91 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/arg9.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/arg9.C
@@ -1,39 +1 @@
-// Build don't link:
-// GROUPS passed arg-matching
-// arg-matching file
-// Message-Id: <199405132049.QAA06835@elan.cs.UMD.EDU>
-// Subject: Bug in g++ 2.4.5 and 2.5.8
-// Date: Fri, 13 May 1994 16:49:22 -0400
-// From: Evan Rosser <ejr@cs.umd.edu>
-
-#include <assert.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-class TupleIterator {
-public:
- TupleIterator(int *tpl);
- int& operator*();
- int live() const;
-// The compile fails with "no post-increment operator for type" at "TI++"
-// below.
-// It succeeds with the same declarations if set_position does not take an int.
-// This occurs with G++ 2.4.5 and 2.5.8.
-// Sun CC works OK with either case.
- void operator++(int);
- void set_position(int);
-private:
-};
-
-main() {
-
-int t[5];
-t[1] = 1; t[2] = 2;t[3] = 3;t[4] = 4;
-TupleIterator TI(t);
-
- while(TI.live()){
- printf("%d", *TI);
- TI++;
- }
-}
-
+int main() {
diff --git a/gcc/testsuite/g++.old-deja/g++.law/arm13.C b/gcc/testsuite/g++.old-deja/g++.law/arm13.C
index e69de29bb2d..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/arm13.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/arm13.C
@@ -0,0 +1 @@
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.law/arm14.C b/gcc/testsuite/g++.old-deja/g++.law/arm14.C
index 91674288935..1e34e6a56a4 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/arm14.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/arm14.C
@@ -1,24 +1 @@
-// Build don't link:
-// GROUPS passed ARM-compliance
-// unsorted.2 file
-// Message-Id: <BpBu19.GrF@math.waterloo.edu>
-// Date: Thu, 4 Jun 1992 15:07:56 GMT
-// Subject: access control
-// From: gjditchf@plg.waterloo.edu (Glen Ditchfield)
-
-
-class X {
- private:
- enum E1 {a1, b1};
- public:
- enum E2 {a2, b2};
- };
-
-void h(X* p) {
- X::E2 e2;
- int x2 = X::a2;
-
- X::E1 e1; // Should be rejected, but isn't.// ERROR - .* , XFAIL *-*-*
- int x1 = X::a1; // ERROR - Should be rejected, and is.
- }
-
+ enum E1 {a1, b1}; // ERROR - private
diff --git a/gcc/testsuite/g++.old-deja/g++.law/arm9.C b/gcc/testsuite/g++.old-deja/g++.law/arm9.C
index 528478f9f3f..b3b753c1a91 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/arm9.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/arm9.C
@@ -1,33 +1 @@
-// Build don't link:
-// GROUPS passed ARM-compliance
-#include <iostream.h>
-enum f1 {
- F1
-};
-
-enum f2 {
- F2
-};
-
-class A {
-public:
- void set (f1 f);
-};
-void A::set (f1 f) { cout << "called A f1\n";}
-
-class B : public A {
-public:
- void set (f2 f);
-};
-void B::set (f2 f) { cout << "called B\n";} // ERROR - candidate
-
-main() {
- B b;
- b.set(F1); // ARM page 309: should call A.set(f1) and that what g++ does,// ERROR - .*
- // but 13.1 of ARM clearly states that it should call B::set()
- // or generate an error because overloading works only for
- // functions within the same scope (first page of chapter 13)
- // while member of derived and base classes are considered to
- // belong to different scopes. Thus B::set() should have
- // hidden (completely) the A::set() function.
-}
+int main() {
diff --git a/gcc/testsuite/g++.old-deja/g++.law/array1.C b/gcc/testsuite/g++.old-deja/g++.law/array1.C
index fc40bc581e0..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/array1.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/array1.C
@@ -1,31 +1 @@
-// GROUPS passed arrays
-// array file
-// Message-Id: <9204120353.AA06266@cs.rice.edu>
-// From: dougm@cs.rice.edu (Doug Moore)
-// Subject: constructors not called on new'ed array elements
-// Date: Sat, 11 Apr 92 22:53:35 CDT
-
-#include <stdio.h>
-
-int i = 0;
-
-class foo
-{
-private:
- static foo *array;
-public:
- foo()
- {
- i++;
- }
-};
-
-foo* foo::array = new foo [5];
-
-main()
-{
- if (i != 5)
- printf ("FAIL\n");
- else
- printf ("PASS\n");
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.law/bad-error6.C b/gcc/testsuite/g++.old-deja/g++.law/bad-error6.C
index a58a5fad2e4..a1bf1a8b294 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/bad-error6.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/bad-error6.C
@@ -1,26 +1 @@
-// Build don't link:
-// GROUPS passed bad-errors
-typedef unsigned long size_t;
-
-class tt {
- public:
- tt(int);
-
- private:
- void *operator new(size_t a); // Forbid object creation in heap memory.
-};
-
-void st(const tt&, int);
-
-void ff(int i, int j)
-{
- if( i > 0 ) {
- // This work ok.
- tt a_tt(i);
- st(a_tt, j);
- }
- else {
- // This triggers an error because of private operator new ????.
- st(tt(-i), j);
- }
-}
+typedef __SIZE_TYPE__ size_t;
diff --git a/gcc/testsuite/g++.old-deja/g++.law/bad-error7.C b/gcc/testsuite/g++.old-deja/g++.law/bad-error7.C
index 479dbf575f1..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/bad-error7.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/bad-error7.C
@@ -1,24 +1 @@
-// Build don't link:
-// GROUPS passed bad-errors
-#include <iostream.h>
-
-class ParX
- {
- public:
- ParX() {}
- };
-
-class X : public ParX
- {
- public:
- void fn2() { cout << "hi" << endl; }
- };
-
-main()
- {
- X x;
- ParX* pParX = &x;
- void (ParX::*p)() = (void (ParX::*)()) &X::fn2; // line 19
-
- (pParX->*p)();
- }
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.law/code-gen1.C b/gcc/testsuite/g++.old-deja/g++.law/code-gen1.C
index b122e908988..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/code-gen1.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/code-gen1.C
@@ -1,20 +1 @@
-// GROUPS passed code-generation
-// code-gen file
-// From: Jeffrey C. Gealow <jgealow@mtl.mit.edu>
-// Date: Sun, 4 Jul 93 18:57:53 -0400
-// Subject: increment bug (0 + 1 + 1 = 3)
-// Message-ID: <9307042257.AA23538@mtl.mit.edu>
-
-#include <stdio.h>
-
-main()
-{
- int i = 0;
- (++i)++;
- if (i == 2)
- printf ("PASS\n");
- else
- printf ("FAIL\n");
-}
-
-
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.law/code-gen3.C b/gcc/testsuite/g++.old-deja/g++.law/code-gen3.C
deleted file mode 100644
index a9de4838ca1..00000000000
--- a/gcc/testsuite/g++.old-deja/g++.law/code-gen3.C
+++ /dev/null
@@ -1,33 +0,0 @@
-// GROUPS passed code-generation
-// execution test - XFAIL *-*-*
-// code-gen file
-// From: mscha@anne.wifo.uni-mannheim.de (Martin Schader)
-// Date: Wed, 4 Aug 93 19:14:52 +0200
-// Message-ID: <9308041714.AA00752@anne.wifo.uni-mannheim.de>
-
-extern "C" int printf (const char *, ...);
-
-template<class T> struct Y {
- Y* next;
-};
-
-template<class T> struct X {
- X() { ptrY = 0; }
- void f();
- Y<T>* ptrY;
-};
-
-template<class T> void X<T>::f() {
- ptrY->next = ptrY = new Y<T>;
-//
-// Use two assignment statements and it works
-// ptrY = new Y<T>;
-// ptrY->next = ptrY;
-}
-
-int main() {
- X<int> x;
- x.f();
- printf ("PASS\n");
- exit(0);
-}
diff --git a/gcc/testsuite/g++.old-deja/g++.law/code-gen4.C b/gcc/testsuite/g++.old-deja/g++.law/code-gen4.C
index a9070ed4ea8..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/code-gen4.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/code-gen4.C
@@ -1,30 +1 @@
-// GROUPS passed code-generation
-// code-gen file
-// From: david.binderman@pmsr.philips.co.uk
-// Date: Tue, 17 Aug 93 10:09:38 BST
-// Subject: .* broken in 2.4.5
-// Message-ID: <9308170909.AA05509@pmsr.philips.co.uk>
-
-class A {
-public:
- char c;
-};
-
-typedef char A::*PMA;
-
-PMA pmA = &A::c;
-
-A oA;
-
-extern "C" int printf( const char *, ...);
-
-main()
-{
- oA.c = 'q';
-
- if ( (oA .* pmA))
- printf( "PASS\n");
- else
- printf(" FAIL\n");
-}
-
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.law/code-gen5.C b/gcc/testsuite/g++.old-deja/g++.law/code-gen5.C
index fa55dbe8302..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/code-gen5.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/code-gen5.C
@@ -1,283 +1 @@
-// GROUPS passed code-generation
-// code-gen file
-// From: "David" <norman@pi14.arc.umn.edu>
-// Date: Mon, 15 Nov 1993 20:59:14 -0600 (CST)
-// Subject: An error!
-// Message-ID: <9311160259.AA03353@pi14.arc.umn.edu>
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <assert.h>
-#include <fstream.h>
-#include <iostream.h>
-#include <math.h>
-
-#define ANSI_C
-
-typedef double VEC ;
-
-class Vector;
-
-class VectorInt
-{
- public:
-
- /* Nothing public!! Only Vector can use this class */
-
- private:
-
- VectorInt( int );
- VectorInt( int, double *, int = 0 );
- VectorInt( const VectorInt & );
- ~VectorInt();
-
- VectorInt *refer();
- void unrefer();
- int count; /* Number of Vector's refering to me */
-
- VEC *vec;
-
- friend class Vector;
- friend class VecElem;
-};
-
-class VecElem
-{
- public:
-
- operator double();
- double operator=( double );
-
- private:
-
- VecElem( Vector &, int );
- VecElem( const VecElem & );
-
- Vector &v;
- int row; /* Row element refers to */
-
- friend class Vector;
-};
-
-class Vector
-{
- public:
-
- Vector(); // Must be assigned to before used
- Vector( VectorInt * );
- Vector( int );
- Vector( int, double *, int beg = 0 );
- Vector( const Vector & );
- Vector &operator=( const Vector & );
- ~Vector() { if(r) r->unrefer(); };
-
- int row() const { return 19; }
- int dim() const { return 10; }
-
- double operator()( int ) const;
- VecElem operator()( int );
-
- double assign( int, double );
-
- friend ostream& operator<<( ostream&, const Vector& m );
-
- private:
-
- VectorInt *r; /* Reference to real data */
-
- friend class VecElem;
- friend class LUDecom;
- friend class SVD;
-};
-
-
-Vector::
-Vector()
- : r(0)
-{}
-
-Vector::
-Vector( VectorInt *vi )
- : r(vi)
-{
- r->refer();
-}
-
-Vector::
-Vector( int row )
-{
- assert( row > 0 );
-
- r = new VectorInt( row );
-
- r->refer();
-}
-
-Vector::
-Vector( int row, double *d, int beg )
-{
- assert( row > 0 );
-
- r = new VectorInt( row, d, beg );
-
- r->refer();
-}
-
-Vector::
-Vector( const Vector &A )
- : r( A.r->refer() )
-{}
-
-Vector& Vector::
-operator=( const Vector &A )
-{
- if( r )
- r->unrefer();
-
- r = A.r->refer();
-
- return *this;
-}
-
-double Vector::
-operator()( int row ) const
-{
- assert( r );
-
- return *r->vec;
-}
-
-VecElem Vector::
-operator()( int r )
-{
- assert(r);
-
- return VecElem( *this, r );
-}
-
- /* assign changes the matrix, it does not create a new one! */
-double Vector::
-assign( int rownum, double d )
-{
- assert(r);
-
- if( rownum > row() || rownum <= 0 ) {
- cerr << "Warning: trying to assign out of bounds" << endl;
- cerr << "row " << rownum << endl;
- cerr << "Vector size " << row() << endl;
- abort();
- }
-
- if( r->count == 1 ) {
- /* Don't need to create a new matrix, since we are the only */
- /* one pointing to ours */
- }
- else {
- VectorInt *vi = new VectorInt( *r );
- r->unrefer();
- r = vi->refer();
- }
-
- return d;
-}
-
-
-VectorInt::
-VectorInt( int sx )
- : vec( new double[sx] ), count(0)
-{ }
-
-VectorInt::
-VectorInt( int sx, double *, int )
- : vec( new double[sx] ), count(0)
-{
-}
-
-VectorInt::
-VectorInt( const VectorInt & )
- : vec( new double[10] ), count(0)
-{
-}
-
-VectorInt * VectorInt::
-refer()
-{
- count ++;
- return this;
-
- // cout << "Refering vec" << endl;
-}
-
-void VectorInt::
-unrefer()
-{
- count--;
-
- if( count == 0 ) {
- delete this;
- }
-
- // cout << "Unrefering vec" << endl;
-}
-
-VectorInt::
-~VectorInt()
-{
- delete vec;
- vec = 0;
-}
-
-VecElem::
-VecElem( Vector &vec, int r )
- : v(vec), row(r)
-{
- if( r < 1 || r > vec.row() ) {
- cerr << "Trying to access vector element out of bounds" << endl;
- abort();
- }
-}
-
-VecElem::
-VecElem( const VecElem &elem )
- : v(elem.v), row(elem.row)
-{}
-
-VecElem::
-operator double()
-{
- assert( v.r->vec );
- return *v.r->vec;
-};
-
-double VecElem::
-operator=( double d )
-{
- return v.assign( row, d );
-}
-
-
-
-
-
-int makeforms( Vector cen, Vector **a, Vector **b );
-
-main()
-{
- Vector *a[8], *b[8], disp(3);
- Vector cen(3), cen2(3);
- int i, j;
-
- if (makeforms (cen,a,b) != 10)
- printf ("FAIL\n");
- else
- printf ("PASS\n");
-
-
-}
-
-int
-makeforms( Vector cen, Vector **a, Vector **b)
-{
- return 10;
-}
-
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.law/copy1.C b/gcc/testsuite/g++.old-deja/g++.law/copy1.C
index cd237068628..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/copy1.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/copy1.C
@@ -1,66 +1 @@
-// GROUPS passed copy-ctors
-#include <stdio.h>
-
-int pass = 0;
-class name {
- int namestuff;
-public:
- name() {
- namestuff = 111;
- }
- name(const name& subject);
-
- name & operator = (const name& right) {
- this->namestuff = right.namestuff;
- return *this;
- }
-
- ~name() {
- ;
- }
-};
-
-name::name(const name& subject) {
- pass = 1;
-}
-
-class person {
- int personstuff;
- name personname;
-public:
- person() {
- ;
- personstuff = 222;
- }
- ~person() {
- ;
- }
- void print() {
- ;
- }
-
-};
-
-void
-test(person argp)
-{
- person testp;
-
- ;
- argp.print();
- testp = argp;
- argp.print();
- testp.print();
- ;
-}
-
-main()
-{
- person mainp;
- test(mainp);
- if (pass)
- printf ("PASS\n");
- else
- printf ("FAIL\n");
-}
-
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.law/ctors11.C b/gcc/testsuite/g++.old-deja/g++.law/ctors11.C
index 8472fb89394..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/ctors11.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/ctors11.C
@@ -1,21 +1 @@
-// Build don't link:
-// GROUPS passed constructors
-// ctor file
-// Message-Id: <9302081631.AA14744@tera.com>
-// From: rrh@tera.com (Robert R. Henry)
-// Date: Mon, 8 Feb 93 08:31:39 PST
-extern "C" void printf(const char *,...);
-class A{
-public:
- inline A(int x){printf("constructing A with %d\n", x);}
-};
-
-class B:public A{
-private:
-public:
-}; // ERROR - non-default constructor
-
-main()
-{
- B(10);// ERROR - B doesn't have a constructor taking int
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.law/ctors12.C b/gcc/testsuite/g++.old-deja/g++.law/ctors12.C
index 37d45884398..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/ctors12.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/ctors12.C
@@ -1,33 +1 @@
-// GROUPS passed constructors
-#include <stdio.h>
-#include <stdlib.h>
-#include <iostream.h>
-
-#define MAGIC 7654
-
-class complex {
- double re;
- double im;
- int magic;
- static int count;
-public:
- complex() { re=im=0; magic=MAGIC; }
- complex(double d) { re=d; im=0; magic=MAGIC; }
- complex(double d, double d2) {re=d; im=d2; magic=MAGIC; }
- ~complex() {if(magic!=MAGIC) {printf("FAIL\n");exit(0);}}
- friend ostream& operator << (ostream& o, const complex& c)
- { return o << "(" << c.re << "," << c.im << ")"; }
-};
-
-int complex::count=0;
-
-main()
-{
- complex v[6] = {1, complex(1,2), complex(), 2 }; // ARM Sect. 12.6.1
- int i; // page 289
-
- for(i=0; i<6; i++) ;
- printf ("PASS\n");
-
- return 0;
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.law/ctors13.C b/gcc/testsuite/g++.old-deja/g++.law/ctors13.C
index a0bb6f2008f..c78f8beb520 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/ctors13.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/ctors13.C
@@ -1,16 +1,2 @@
-// Build don't link:
-// GROUPS passed constructors
-#include <iostream.h>
-
-class A {
- A() {} // private constructor// ERROR - .*
-}; // WARNING - all member functions are private
-
-main() {
- A* a = new A();// ERROR - .*
- if (a) {
- cout << "a != NULL\n";
- } else {
- cout << "a == NULL\n";
- }
-}
+};
+int main() {
diff --git a/gcc/testsuite/g++.old-deja/g++.law/ctors16.C b/gcc/testsuite/g++.old-deja/g++.law/ctors16.C
index 4da7f058b5a..b3b753c1a91 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/ctors16.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/ctors16.C
@@ -1,49 +1 @@
-// GROUPS passed constructors
-// ctor file
-// Message-Id: <9306021533.AA14347@icepick.jts.com>
-// From: roland@jts.com (Roland Knight )
-// Subject: gcc 2.4.1 bug
-// Date: Wed, 2 Jun 1993 11:33:34 -0400
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-char stuff[50];
-char *p = stuff;
-
-class A {
-public:
- A() { *p++ = 'A';}
-};
-
-class B {
-public:
- B() { *p++ = 'B'; }
-};
-
-class C : public A, public B {
-public:
- C() : B(), A() { *p++ = 'C'; }
-};
-
-class D : public A, public B {
-public:
- D() : B() { *p++ = 'D'; }
-};
-
-class E : public A, public B {
-public:
- E() { *p++ = 'E'; }
-};
-
-
-main() {
- C c;
- D d;
- E e;
- if (strncmp ("ABCABDABE", stuff, 9))
- printf ("FAIL\n");
- else
- printf ("PASS\n");
-}
+int main() {
diff --git a/gcc/testsuite/g++.old-deja/g++.law/ctors17.C b/gcc/testsuite/g++.old-deja/g++.law/ctors17.C
index 41e3217faf9..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/ctors17.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/ctors17.C
@@ -1,21 +1 @@
-// Build don't link:
-// GROUPS passed constructors
-// ctor file
-// Message-Id: <199306151813.gD28471@mail.Germany.EU.net>
-// From: stephan@ifconnection.de (Stephan Muehlstrasser)
-// Subject: gcc 2.4.3.1: illegal constructor call not rejected
-// Date: Tue, 15 Jun 1993 18:34:14 +0200 (MET DST)
-
-
-#include <fstream.h>
-
-class X : public ifstream {
- public:
- X(int a, char *b) {} // ERROR - candidate
-}; // ERROR - candidate
-main()
-{
- X *y = new X(10, "123");
- // the compiler must reject this constructor call:
- X *x = new X("abc");// ERROR - .*
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.law/ctors2.C b/gcc/testsuite/g++.old-deja/g++.law/ctors2.C
index 8ceb5395f69..b3b753c1a91 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/ctors2.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/ctors2.C
@@ -1,69 +1 @@
-// GROUPS passed constructors
-// Message-Id: <m0p8Am6-0002fCC@neal.ctd.comsat.com>
-// Date: Fri, 10 Dec 93 11:33 EST
-// From: neal@ctd.comsat.com (Neal Becker)
-// Subject: serious problems with static constructors
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#define CONST const
-
-class Sig {
-
-public:
-
- enum Type { Byte_t, Word_t, Long_t, Float_t, Double_t, Complex_t, ComplexLong_t, Bad_t };
-
-private:
-
- Type T;
-
-public:
-
- static CONST char *ByteMagic, *WordMagic, *LongMagic,
- *FloatMagic, *DoubleMagic, *ComplexMagic, *ComplexLongMagic, *BadMagic;
-
- struct SigTable {
- Type T;
- CONST char* Magic;
- };
-
- static CONST SigTable sigTable[];
-
-};
-
-CONST char
-*Sig::ByteMagic = "BYTE",
-*Sig::WordMagic = "WORD",
-*Sig::LongMagic = "LONG",
-*Sig::FloatMagic = "FLOA",
-*Sig::DoubleMagic = "DOUB",
-*Sig::ComplexMagic = "COMP",
-*Sig::ComplexLongMagic = "CMPL",
-*Sig::BadMagic = NULL;
-
-
-CONST Sig::SigTable Sig::sigTable[] = {
- { Byte_t, ByteMagic },
- { Word_t, WordMagic },
- { Long_t, LongMagic },
- { Float_t, FloatMagic },
- { Double_t, DoubleMagic },
- { Complex_t, ComplexMagic },
- { ComplexLong_t, ComplexLongMagic },
- { Bad_t, BadMagic }
-};
-
-main() {
- if (strcmp (Sig::sigTable[0].Magic, "BYTE")
- || strcmp (Sig::sigTable[1].Magic, "WORD")
- || strcmp (Sig::sigTable[2].Magic, "LONG")
- || strcmp (Sig::sigTable[3].Magic, "FLOA")
- || strcmp (Sig::sigTable[4].Magic, "DOUB")
- || strcmp (Sig::sigTable[5].Magic, "COMP"))
- printf ("FAIL\n");
- else
- printf ("PASS\n");
-}
+int main() {
diff --git a/gcc/testsuite/g++.old-deja/g++.law/ctors8.C b/gcc/testsuite/g++.old-deja/g++.law/ctors8.C
index f773d093633..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/ctors8.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/ctors8.C
@@ -1,24 +1 @@
-// GROUPS passed constructors
-// ctor file
-// Message-Id: <199212160609.AA18247@phecda.cs.sfu.ca>
-// From: Taj Khattra <khattra@cs.sfu.ca>
-// Subject: gcc 2.3.1 global ctor bug ?
-// Date: Tue, 15 Dec 92 22:09:37 PST
-
-#include <stdio.h>
-
-struct foo {
- foo() : index(-1) {}
- int index;
-};
-
-foo *arr = new foo[2];
-
-main()
-{
- if (arr[0].index == -1
- && arr[1].index == -1)
- printf ("PASS\n");
- else
- printf ("FAIL\n");
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.law/ctors9.C b/gcc/testsuite/g++.old-deja/g++.law/ctors9.C
index 280b429c352..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/ctors9.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/ctors9.C
@@ -1,39 +1 @@
-// Build don't link:
-// Special g++ Options: -pedantic-errors
-// GROUPS passed constructors
-// ctors file
-// Message-Id: <9301132030.AA05210@cs.rice.edu>
-// From: dougm@cs.rice.edu (Doug Moore)
-// Subject: 2.3.3: accepts ctor-less derived class of ctor-ful base class
-// Date: Wed, 13 Jan 93 14:30:21 CST
-// Note: It gives an error now. But not a very good one.
-
-struct Foo
-{
- Foo(int aa);
- int a;
- const Foo* operator-> () const {return this;}
-};
-
-Foo::Foo(int aa)
-:a(aa)
-{ }
-
-
-struct var_Foo: public Foo
-{
- var_Foo* operator-> () {return this;}
-};// ERROR - base.*// ERROR - in class.*
-
-int blort(Foo& f)
-{
- return f->a;
-};
-
-main()
-{
- var_Foo b(2);// ERROR -
- b->a = 0;
- int x = blort(b);
- return x;
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.law/cvt1.C b/gcc/testsuite/g++.old-deja/g++.law/cvt1.C
index 82641242b49..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/cvt1.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/cvt1.C
@@ -1,12 +1 @@
-// Build don't link:
-// GROUPS passed conversions
-// cvt file
-// From: dak@pool.informatik.rwth-aachen.de
-// Date: Sun, 21 Nov 93 17:40:32 +0100
-// Subject: g++ mixes up array dimensions with new
-// Message-ID: <9311211640.AA11787@messua>
-
-main()
-{
- int (*a)[5] = new int[6][5];
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.law/cvt10.C b/gcc/testsuite/g++.old-deja/g++.law/cvt10.C
index 01f1e807148..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/cvt10.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/cvt10.C
@@ -1,60 +1 @@
-// Build don't link:
-// GROUPS passed conversions
-// cvt file
-// Message-Id: <CC7oHn.B4F@izf.tno.nl>
-// From: tom@izfcs.izf.tno.nl (Tom Vijlbrief)
-// Subject: g++ 2.4.5 has problems with NON virtual shared base classes
-// Date: Mon, 23 Aug 1993 12:10:34 GMT
-
-
-#include <stdio.h>
-
-#define FAIL
-
-class Base {
-public:
- Base() { printf("Base::Base\n"); }
- virtual ~Base() { printf("Base::~Base\n"); }
- virtual void v() { printf("Base::v\n"); }
-};
-
-class Base2 {
-public:
- Base2() { printf("Base2::Base2\n"); }
- virtual ~Base2() { printf("Base2::~Base2\n"); }
- virtual void v() { printf("Base2::v\n"); }
-};
-
-class A: public Base {
-public:
- A() { printf("A::A\n"); }
- ~A() { printf("A::~A\n"); }
- virtual void va() { printf("A::va\n"); }
-};
-
-#ifdef FAIL
-class B: public Base {
-#else
-class B: public Base2 {
-#endif
-public:
- B() { printf("B::B\n"); }
- ~B() { printf("B::~B\n"); }
- virtual void vb() { printf("B::vb\n"); }
-};
-
-class C: public A, public B {
-public:
- C() { printf("C::C\n"); }
- ~C() { printf("C::~C\n"); }
- void va() { printf("C::va\n"); }
-};
-
-
-main()
-{
- C *cp= new C;
- cp->va();
- delete cp;
-}
-
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.law/cvt11.C b/gcc/testsuite/g++.old-deja/g++.law/cvt11.C
index 321368caa74..f48a8ee83de 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/cvt11.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/cvt11.C
@@ -1,30 +1 @@
-// Build don't link:
-// GROUPS passed conversions
-// cvt file
-// Date: Tue, 10 Nov 92 11:08:08 PST
-// From: rrh@tera.com (Robert R. Henry)
-// Message-Id: <9211101908.AA13557@tera.com>
-// Subject: type cast of qualified const member breaks g++2.3.1
-
-#include <stdio.h>
-
-class Thing{
-private: int x;
- public: const int N = -1; // ERROR - bad initialization
- Thing(int y);
-};
-
-class Bar{ public: void doit(void); };
-
-void Bar::doit(void)
-{
- int i, j;
- i = Thing::N;
- printf("i = %d\n", i);
-
- j = (int)Thing::N;
- printf("i = %d\n", j);
-}
-Thing::Thing(int y) { x = y; }
-main(){ Bar x; x.doit(); }
-
+int main(){ Bar x; x.doit(); }
diff --git a/gcc/testsuite/g++.old-deja/g++.law/cvt12.C b/gcc/testsuite/g++.old-deja/g++.law/cvt12.C
index cce2d9bcda0..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/cvt12.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/cvt12.C
@@ -1,29 +1 @@
-// GROUPS passed conversions
-// cvt file
-// Message-Id: <9301071708.AA03432@muresh.et.tudelft.nl>
-// From: stravers@muresh.et.tudelft.nl (Paul Stravers)
-// Subject: conversion method never called
-// Date: Thu, 7 Jan 93 18:08:33 +0100
-
-#include <stdio.h>
-
-class test
-{
- double d;
- int i;
-public:
- test(double dd,int ii) {d=dd; i=ii;} // constructor
- operator int&() {return i;} // define a conversion from test to int&
- int& geti() {return i;} // same thing, but different
-};
-
-main()
-{
- test t(3.14, 5); // Create an object t of class "test"
- int x = (int&)t; // This should call operator int&() but it does not ...
- int y = t.geti(); // x and y should both be 5 ...
- if (x == 5 && y == 5)
- printf ("PASS\n");
- else
- printf ("FAIL\n");
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.law/cvt13.C b/gcc/testsuite/g++.old-deja/g++.law/cvt13.C
index d2f04cc9ec6..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/cvt13.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/cvt13.C
@@ -1,19 +1 @@
-// Build don't link:
-// GROUPS passed conversions
-// cvt file
-// Message-Id: <ISHAI.93Mar26102509@cs73.technion.ac.il>
-// From: ishai@cs.technion.ac.il (& Ben-Aroya)
-// Subject: Type conversion problem.
-// Date: Fri, 26 Mar 1993 08:25:09 GMT
-
-typedef int array[10];
-
-void f(array &arg)
-{
-}
-
-main()
-{
- array var;
- f(var);
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.law/cvt14.C b/gcc/testsuite/g++.old-deja/g++.law/cvt14.C
index 2cf02359f4a..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/cvt14.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/cvt14.C
@@ -1,15 +1 @@
-// Build don't link:
-// GROUPS passed conversions
-// cvt file
-// Message-Id: <9303241504.AA25988@spock.orl.mmc.com>
-// Subject: internal compiler error
-// Date: Wed, 24 Mar 1993 10:04:06 -0500
-// From: "Malcolm C. Strickland" <chucks@orl.mmc.com>
-
-
- main()
- {
- double *d;
- d = new double(10);
- return 1;
- }
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.law/cvt17.C b/gcc/testsuite/g++.old-deja/g++.law/cvt17.C
index 6ddffe29d28..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/cvt17.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/cvt17.C
@@ -1,20 +1 @@
-// Build don't link:
-// GROUPS passed conversions
-// cvt file
-// Message-Id: <9305210124.AA02409@kato.cs.brown.edu>
-// From: pcm@cs.brown.edu (Peter C. McCluskey)
-// Subject: illegal code compiles silently
-// Date: Thu, 20 May 93 21:24:22 -0400
-
-
-
-class Point {};
-class Line_Segment{ public: Line_Segment(const Point&){} };
-class Node { public: Point Location(){ Point p; return p; } };
-
-main()
-{
- Node** node1;
- Line_Segment(node1->Location()); // intended (*node1)// ERROR - .*
-}
-
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.law/cvt19.C b/gcc/testsuite/g++.old-deja/g++.law/cvt19.C
index b15bdfd705a..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/cvt19.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/cvt19.C
@@ -1,27 +1 @@
-// Build don't link:
-// GROUPS passed conversions
-// cvt file
-// Message-Id: <1166.9307131600@ace.eng.cam.ac.uk>
-// From: ajp@eng.cam.ac.uk
-// Date: Tue, 13 Jul 93 17:00:44 BST
-
-
-class B {};
-
-class A {
- public:
- operator const B*() const {
- return b;
- }
- private:
- B* b;
-};
-
-
-main()
-{
- A a;
- if (a!=0) {
- }
-}
-
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.law/cvt2.C b/gcc/testsuite/g++.old-deja/g++.law/cvt2.C
index 3a5a1b94303..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/cvt2.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/cvt2.C
@@ -1,42 +1 @@
-// GROUPS passed conversions
-#include <stdio.h>
-#include <stdlib.h>
-#include <iostream.h>
-#include <fstream.h>
-
-extern "C" {
-int strncmp (const char *, const char *, size_t);
-}
-
-class cvec {
-public:
- ~cvec(){ delete s; }
- cvec(const char*x) { s = new char[strlen(x)+1]; strcpy(s, x); }
- cvec(const cvec& c) { s = new char[strlen(c.s)+1]; strcpy(s, c.s); }
- operator const char*() { return s; }
-private:
- char *s;
-};
-
-cvec
-B(const char* a)
-{
- return a;
-}
-
-void
-A(const char* s)
-{
- // s still ok here
- ifstream inf(s);
- if (strncmp ("aaa", s, 3))
- printf ("FAIL\n");
- else
- printf ("PASS\n");
-}
-
-main()
-{
- A(B("aaa"));
-}
-
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.law/cvt20.C b/gcc/testsuite/g++.old-deja/g++.law/cvt20.C
index 72abbb74807..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/cvt20.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/cvt20.C
@@ -1,20 +1 @@
-// Build don't link:
-// GROUPS passed conversions
-// cvt file
-// Message-Id: <9307152250.AA24812@volterra>
-// From: rst@ai.mit.edu (Robert S. Thau)
-// Subject: g++ won't convert char[] to char*&
-// Date: Thu, 15 Jul 93 18:50:59 EDT
-
-
-// Compiles fine with Sun CC 2.1
-
-void f(char *& x)
-{// ERROR - location of error
- x++;
-}
-
-main()
-{
- f ("foo");// ERROR - init of non-const ref from char*
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.law/cvt21.C b/gcc/testsuite/g++.old-deja/g++.law/cvt21.C
index c4516c85e26..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/cvt21.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/cvt21.C
@@ -1,36 +1 @@
-// Build don't link:
-// GROUPS passed conversions
-// cvt file
-// Message-Id: <9307200528.AA02094@legolas>
-// From: Mark Kuzmycz <kuzmycz@deakin.edu.au>
-// Subject: int & conversion operator
-// Date: Tue, 20 Jul 93 15:28:47 EST
-
-class Int
-{
- public:
- Int(void);
- Int(int);
- Int(const Int&);
-
- Int* copy(void) const;
-
- operator int&();
-
- Int& operator ++(void);
- Int& operator --(void);
-
- private:
- int value;
-};
-
-main()
-{
- Int data = 2;
- Int test;
-
- test = data * 12;
- data += 1;
-}
-
-// UNKNOWN "FAIL"
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.law/cvt22.C b/gcc/testsuite/g++.old-deja/g++.law/cvt22.C
index 9d72a6c4219..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/cvt22.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/cvt22.C
@@ -1,14 +1 @@
-// Build don't link:
-// GROUPS passed conversions
-// cvt file
-// Message-Id: <93Aug2.163542pdt.26892@franklin.parc.xerox.com>
-// From: Jesse Hull <jhull@parc.xerox.com>
-// Subject: typedef bug
-// Date: Mon, 2 Aug 1993 16:35:28 PDT
-
-typedef int A[10];
-
-main()
-{
- int* a1 = new A;
-};
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.law/cvt4.C b/gcc/testsuite/g++.old-deja/g++.law/cvt4.C
index 6863c8f74ae..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/cvt4.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/cvt4.C
@@ -1,27 +1 @@
-// GROUPS passed conversions
-// cvt file
-// Message-Id: <9308091213.AA11572@emmy.Mathematik.Uni-Dortmund.DE>
-// From: Michael Strauch <strauch@emmy.mathematik.uni-dortmund.de>
-// Subject: Bug in GCC 2.4.5
-// Date: Mon, 9 Aug 93 14:13:50 MESZ
-
-extern "C" int printf (const char *, ...);
-
-int destruct = 2;
-
- class Test{
- protected:
- long x;
- public:
- Test(){;}
- Test(long l) {x=l;}
- ~Test() {if (--destruct == 0) printf ("PASS\n");}
- };
-
- main()
- {
- long i=1;
- Test t;
-
- t=(Test)i;
- }
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.law/cvt5.C b/gcc/testsuite/g++.old-deja/g++.law/cvt5.C
index d244b4f5225..c0c35bdbfa5 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/cvt5.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/cvt5.C
@@ -1,28 +1 @@
-// Build don't link:
-// GROUPS passed conversions
-// cvt file
-// Message-Id: <1992Jul31.142856.10082@ericsson.se>
-// From: jonas@ericsson.se (Jonas Nygren)
-// Subject: g++ bug
-// Date: Fri, 31 Jul 1992 14:28:56 GMT
-
-class A {};
-class B : public A {};
-
-B b;
-
-class R{
-public:
- R() {}
- operator B&() { return b; }
-};
-
-void f(A&) {}
-
-main(){
- R r;
-
- f(r); // problem to cast to B& and then to A&
-}
-
-
+int main(){
diff --git a/gcc/testsuite/g++.old-deja/g++.law/cvt6.C b/gcc/testsuite/g++.old-deja/g++.law/cvt6.C
index 85d5af80abd..b3b753c1a91 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/cvt6.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/cvt6.C
@@ -1,28 +1 @@
-// Build don't link:
-// GROUPS passed conversions
-// cvt file
-// Message-Id: <9208261851.AA16997@josquin.media.mit.edu>
-// From: bilmes@media.mit.edu
-// Subject: gcc (g++) 2.2.2 constructing nested class from external scope
-// Date: Wed, 26 Aug 92 14:51:17 -0400
-
-
-class foo {
-
- class bar {
- int i;
- public:
- bar(int j) { i = j; }
- };
-
- bar b;
-public:
- foo() : b(3) {}
- void test(bar lb) { b = lb; }
-};
-
-
-main() {
- foo f;
- f.test(34); // line 18
-}
+int main() {
diff --git a/gcc/testsuite/g++.old-deja/g++.law/cvt7.C b/gcc/testsuite/g++.old-deja/g++.law/cvt7.C
index 34cccd848e0..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/cvt7.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/cvt7.C
@@ -1,74 +1 @@
-// GROUPS passed conversions
-// cvt file
-// From: krste@icsi.berkeley.edu (Krste Asanovic)
-// Date: Mon, 24 Aug 92 19:05:10 PDT
-// Message-Id: <9208250205.AA26351@icsib43.ICSI.Berkeley.EDU>
-// Subject: implicit int. convs. from member refs. in switch expressions
-
-#include <stream.h>
-#include <stdio.h>
-
-class A
-{
-public:
- A(int j) { i = j; }
- A(A& a) { i = a.i; }
- operator int() { return i; }
-
- void assign(int v) { i = v; }
- int i;
-};
-
-class B
-{
-public:
- B(A& inArg) : in(inArg), out(0) {}
-
- A& in;
- A out;
-
- void run();
-};
-
-void
-B::run()
-{
- // I get a "switch quantity not an integer" error for this statement.
- switch (in)
- // Replacing above with "switch (int(in))" removes the error.
- {
- case 0:
- out = 1;
- break;
- default:
- out = 0;
- break;
- }
-}
-
-main()
-{
- A a(1);
-
- A& ar = a;
-
- A& ar2 = ar;
-
- // ....but no errors for this switch statement.
- switch (ar2)
- {
- case 1:
- printf ("PASS\n");
- break;
- default:
- printf ("FAIL\n");
- }
-
- B b(a);
- a.assign(3);
- b.run();
- a.assign(0);
- b.run();
-
- return 0;
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.law/cvt8.C b/gcc/testsuite/g++.old-deja/g++.law/cvt8.C
index 031e76662a4..b3b753c1a91 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/cvt8.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/cvt8.C
@@ -1,35 +1 @@
-// Build don't link:
-// GROUPS passed conversions
-// cvt file
-// From: solomon@cs.wisc.edu (Marvin Solomon)
-// Message-Id: <9209141509.AA23124@gjetost.cs.wisc.edu>
-// Subject: g++ 2.2.2 seems to be forgetting a "const"
-// Date: Mon, 14 Sep 92 10:09:58 -0500
-
-extern "C" void printf(...);
-
-struct A {
- int i;
-};
-
-struct B {
- int i;
- operator const A&() const;
-};
-
-B::operator const A&() const {
- static A a;
- a.i = i;
- printf("convert B to A at %x\n", &a);
- return a;
-}
-
-void f(A &a) { // ERROR - in passing argument
- printf("A at %x is %d\n", &a, a.i);
-}
-
-main() {
- B b;
- b.i = 99;
- f(b);// ERROR - .*
-}
+int main() {
diff --git a/gcc/testsuite/g++.old-deja/g++.law/dtors2.C b/gcc/testsuite/g++.old-deja/g++.law/dtors2.C
index c1f2d423cc4..b3b753c1a91 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/dtors2.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/dtors2.C
@@ -1,40 +1 @@
-// GROUPS passed destructors
-#include <stdio.h>
-
-int destruct = 0;
-
-class bla {
-
-public:
-
- inline bla(char * jim) { ; };
-
- inline ~bla() { destruct++; if (destruct == 2) printf ("PASS\n");};
-};
-
-class ulk {
-
-public:
-
- inline ulk() {};
- inline ~ulk() {};
-
- void funk(const bla & bob) { ;};
- // ^ interestingly, the code compiles right if
- // this & is deleted (and therefore the parameter
- // passed as value)
-};
-
-main() {
-
- ulk dumm;
-
- dumm.funk(bla("laberababa")); // this compiles correctly
-
- dumm.funk((bla)"laberababa"); // this produces incorrect code -
- // the temporary instance of
- // the class "bla" is constructed
- // but never destructed...
-
-
-}
+int main() {
diff --git a/gcc/testsuite/g++.old-deja/g++.law/dtors3.C b/gcc/testsuite/g++.old-deja/g++.law/dtors3.C
index ce5aaf335f0..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/dtors3.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/dtors3.C
@@ -1,37 +1 @@
-// GROUPS passed destructors
-// dtor file
-// Message-Id: <9301242117.AA04053@cs.rice.edu>
-// From: dougm@cs.rice.edu (Doug Moore)
-// Subject: 2.3.3: premature dtor of temp?
-// Date: Sun, 24 Jan 93 15:17:07 CST
-
-#include <stdio.h>
-#include <stdlib.h>
-
-int killed = 0;
-
-class Foo
-{
- int a;
-public:
- Foo()
- :a(0) {;}
- ~Foo() { killed++;}
- Foo& operator << (int b)
- {
- a += b;
- if (killed)
- {
- printf ("FAIL\n");
- exit (0);
- }
- return *this;
- }
-};
-
-main()
-{
- Foo() << 1 << 3 << 5 << 7;
- printf ("PASS\n");
-}
-
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.law/dtors4.C b/gcc/testsuite/g++.old-deja/g++.law/dtors4.C
index 028839515b5..c0c35bdbfa5 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/dtors4.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/dtors4.C
@@ -1,22 +1 @@
-// GROUPS passed destructors
-#include <stdio.h>
-
-int destruct = 2;
-
-class a {
- public:
- char *p;
- a(){ ; }
- ~a(){ destruct--; if (! destruct) printf ("PASS\n");}
-};
-
-a test(){
- return a();
-}
-
-main(){
- a ai;
-
- ai = test();
-}
-
+int main(){
diff --git a/gcc/testsuite/g++.old-deja/g++.law/dtors5.C b/gcc/testsuite/g++.old-deja/g++.law/dtors5.C
index 9aa2e6d79ec..b3b753c1a91 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/dtors5.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/dtors5.C
@@ -1,33 +1 @@
-// GROUPS passed destructors
-// dtor file:
-// Message-Id: <1992Jun25.181845.18886@leland.Stanford.EDU>
-// From: niz@leland.stanford.edu (Jim Nisbet)
-// Subject: gcc 2.2.2 -- c++ bug: destructor called twice (example)
-// Date: 25 Jun 92 18:18:45 GMT
-
-#include <stdio.h>
-
-int things = 0;
-
-class foo {
-public:
- foo() { things++; }
- foo(const foo&) { things++; }
- ~foo() { things--; }
-
- int i;
-};
-
-void
-sub(foo f) {
- ;
-};
-
-
-main() {
- sub(foo());
- if (things == 0)
- printf ("PASS\n");
- else
- printf ("FAIL\n");
-}
+int main() {
diff --git a/gcc/testsuite/g++.old-deja/g++.law/enum3.C b/gcc/testsuite/g++.old-deja/g++.law/enum3.C
index c7db587bd24..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/enum3.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/enum3.C
@@ -1,21 +1 @@
-// Build don't link:
-// GROUPS passed enums
-// enum file
-// From: frode@auticon.no
-// Date: Wed, 13 Jan 93 9:24:50 PST
-// Subject: enum trouble
-// Message-ID: <"nac.no.001:13.00.93.18.40.52"@nac.no>
-
-typedef enum{on, off} TOGGLE;
-
-class field {
-private:
- TOGGLE toggle;
-public:
- virtual void on(void) { toggle = 3; };// ERROR - .*
- virtual void off(void) { toggle = on; };// ERROR - .*
-};
-
-main()
-{
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.law/except6.C b/gcc/testsuite/g++.old-deja/g++.law/except6.C
index da09ae6bc1a..fedb04aa71d 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/except6.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/except6.C
@@ -1,27 +1 @@
-// Build don't link:
-// Special g++ Options: -fexceptions
-// GROUPS passed exceptions
-// except file
-// From: GUSTAVO%DRAGON@orion.cpqd.ansp.br
-// Date: 15 Dec 1993 09:33:30 +0000 (C)
-// Subject: exception handling problem
-// Message-ID: <01H6I5GEAF5UPBJ0UV@VENUS.CPQD.ANSP.BR>
-
-struct Exception
- {
- int v;
- Exception(int i) { v = i; };
- };
-
- inc(int &i)
- {
- try {
- if (i == 0)
- throw Exception(i);
- else
- i++;
- }
- catch (Exception v) {
- i = v.v;
- }
- }
+void inc(int &i)
diff --git a/gcc/testsuite/g++.old-deja/g++.law/friend4.C b/gcc/testsuite/g++.old-deja/g++.law/friend4.C
index 5502a002dc5..e69de29bb2d 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/friend4.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/friend4.C
@@ -1,20 +0,0 @@
-// Build don't link:
-// GROUPS passed friends
-// excess errors test - XFAIL *-*-*
-// friends file
-// From: osinski@cs.nyu.edu (Ed Osinski)
-// Date: Fri, 05 Jun 92 20:47:37 -0400
-// Subject: parameter name forgotten in certain friends
-// Message-ID: <9206060047.AA05594@MURRAY.CS.NYU.EDU>
-
-class T2;
-
-class T {
- friend void f (int&);
-};
-
-class T2 {
- friend void f (int& i) { // BOGUS -
- i = 1;
- };
-};
diff --git a/gcc/testsuite/g++.old-deja/g++.law/global-init1.C b/gcc/testsuite/g++.old-deja/g++.law/global-init1.C
index ce641254e62..fca7aa3a92f 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/global-init1.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/global-init1.C
@@ -1,20 +1 @@
-// GROUPS passed initialization
-// global-init file
-// Message-Id: <9212021756.AA12639@grumpy.pocs.com>
-// From: wp@pocs.com (Wolfgang Polak)
-// Subject: Initializers - gcc 2.2.2 (g++), Sparc, SunOS 4.1.1
-// Date: Wed, 2 Dec 92 09:56:01 PST
-
-#include <stdio.h>
-struct S { int a; int c; };
-int i = 3;
-S s = {6, i};
-S * the_s () { return &s; };
-main ()
-{
- S * cls = the_s ();
- if (cls->a != 6)
- printf ("FAIL\n");
- else
- printf ("PASS\n");
-}
+int main ()
diff --git a/gcc/testsuite/g++.old-deja/g++.law/init11.C b/gcc/testsuite/g++.old-deja/g++.law/init11.C
index d5c4e769e4f..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/init11.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/init11.C
@@ -1,24 +1 @@
-// GROUPS passed initialization
-// init file
-// From: hansen@srd.ull.rdc.toshiba.co.jp
-// Date: Mon, 13 Dec 93 18:27:51 +0900
-// Subject: g++ Bug
-// Message-ID: <9312130927.AA08192@VLCS151.noname>
-
-#include <stdio.h>
-
-int X = 7;
-
-struct foo {
- int a,b,c;
-};
-
-struct foo Ack = {5, X, 3};
-
-main()
-{
- if (Ack.a == 5 && Ack.b == 7 && Ack.c == 3)
- printf ("PASS\n");
- else
- printf ("FAIL\n");
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.law/init14.C b/gcc/testsuite/g++.old-deja/g++.law/init14.C
index a65dc68af59..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/init14.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/init14.C
@@ -1,26 +1 @@
-// GROUPS passed initialization
-// init file
-// From: hansen@srd.ull.rdc.toshiba.co.jp
-// Message-Id: <9312130927.AA08192@VLCS151.noname>
-// Subject: g++ Bug
-// Date: Mon, 13 Dec 93 18:27:51 +0900
-
-#include <stdio.h>
-
-int X = 7;
-
-struct foo {
- int a,b,c;
-};
-
-struct foo Ack = {5, X, 3};
-
-main()
-{
- if (Ack.a != 5
- || Ack.b != 7
- || Ack.c != 3)
- printf ("FAIL\n");
- else
- printf ("PASS\n");
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.law/init3.C b/gcc/testsuite/g++.old-deja/g++.law/init3.C
index de0473ec5a1..b3b753c1a91 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/init3.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/init3.C
@@ -1,12 +1 @@
-// Build don't link:
-// GROUPS passed initialization
-// init file
-// From: thayer@moose.cs.columbia.edu (Charles Thayer)
-// Date: Wed, 30 Sep 92 02:38:17 EDT
-// Subject: small bug
-// Message-ID: <9209300638.AA22334@moose.cs.columbia.edu>
-
-main() {
-int offset;
-char buf[offset]=""; // ERROR - ansi forbids variable arrays
-}
+int main() {
diff --git a/gcc/testsuite/g++.old-deja/g++.law/init9.C b/gcc/testsuite/g++.old-deja/g++.law/init9.C
index baad1396a92..b3b753c1a91 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/init9.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/init9.C
@@ -1,35 +1 @@
-// GROUPS passed initialization
-// init file
-// From: Richard Speed <speed@cs.montana.edu>
-// Date: Sun, 6 Jun 1993 15:19:41 -0600 (MDT)
-// Subject: excess elements in aggr initzer
-// Message-ID: <Pine.3.07.9306061541.A10267-b100000@fubar.cs.montana.edu>
-
-extern "C" void printf (char *, ...);
-
-class samp {
- int a;
-public:
- samp(int n) { a = n; }
- int get_a() { return a; }
-};
-
-main() {
- samp ob[4] [2] = { // Generated Error
- 1, 2,
- 3, 4,
- 5, 6,
- 7, 8,
- };
- int i;
-
- if (ob[0][0].get_a() == 1 && ob[0][1].get_a() == 2
- && ob[1][0].get_a() == 3 && ob[1][1].get_a() == 4
- && ob[2][0].get_a() == 5 && ob[2][1].get_a() == 6
- && ob[3][0].get_a() == 7 && ob[3][1].get_a() == 8)
- printf ("PASS\n");
- else
- printf ("FAIL\n");
-
- return 0;
-}
+int main() {
diff --git a/gcc/testsuite/g++.old-deja/g++.law/inline4.C b/gcc/testsuite/g++.old-deja/g++.law/inline4.C
index c6a15a9ad8f..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/inline4.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/inline4.C
@@ -1,20 +1 @@
-// GROUPS passed inlining
-// inline file
-// Message-Id: <9306020823.AA14027@joker>
-// From: stefan@mpi-sb.mpg.de
-// Subject: gcc-2.4.2 template function bug (1)
-// Date: Wed, 2 Jun 93 10:23:14 +0200
-
-extern "C" int printf (const char *, ...);
-
-template <class T> inline T func(const T& x) { return x; }
-
-inline int func(const int& x) { return x; }
-
-
-main()
-{ int x;
- func(x);
- printf ("PASS\n");
- }
-
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.law/missed-error1.C b/gcc/testsuite/g++.old-deja/g++.law/missed-error1.C
index 50accb55440..91d909a57ad 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/missed-error1.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/missed-error1.C
@@ -1,11 +1,12 @@
-// Build don't link:
-// GROUPS passed missed-error
-// missed-error file
-// From: John Carr <jfc@Athena.MIT.EDU>
-// Date: Tue, 02 Feb 1993 07:38:53 EST
-// Subject: Re: g++ ignores language context of function pointers
-// Message-ID: <9302021238.AA01513@Achates.MIT.EDU>
-
- typedef void (*pfv2)(double, double);
- extern "C" { typedef void (*pfv3)(double, double); }// ERROR - , XFAIL *-*-*
+typedef void (*pfv)();
+void f ();
+extern "C"
+{
+ typedef void (*pcfv)(void);
+ void cf (void);
+}
+pfv p = f;
+pfv p2 = cf; // ERROR - mismatch XFAIL *-*-*
+pcfv p3 = f; // ERROR - mismatch XFAIL *-*-*
+pcfv p4 = cf;
diff --git a/gcc/testsuite/g++.old-deja/g++.law/missed-error2.C b/gcc/testsuite/g++.old-deja/g++.law/missed-error2.C
index 4589bb11235..18a026d1502 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/missed-error2.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/missed-error2.C
@@ -11,7 +11,7 @@
inline int max(int a, int b) {return a > b ? a : b;}; // ERROR - candidate
inline double max(double a, double b) {return a > b ? a : b;}; // ERROR - candidate
-main() {
+int main() {
static void foo(int i, int j, double x, double y) ;// ERROR - .*
foo(4, -37, 14.39, 14.38);
diff --git a/gcc/testsuite/g++.old-deja/g++.law/nest3.C b/gcc/testsuite/g++.old-deja/g++.law/nest3.C
index 405a1604250..b3b753c1a91 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/nest3.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/nest3.C
@@ -1,25 +1 @@
-// Build don't link:
-// GROUPS passed nest
-#include <iostream.h>
-
-struct inner {
- static void f() { cout << "inner::f()\n";}
-};
-
-struct outer {
-
- struct inner {
- static void f() { cout << "outer::inner::f()\n";}
- };
-
- static void f() {
- inner::f(); //call of outer::inner::f()
- ::inner::f(); //(try to) call inner::f() => parse error
- }
-};
-
-main() {
- outer::f();
- cout << endl;
- return 0;
-}
+int main() {
diff --git a/gcc/testsuite/g++.old-deja/g++.law/nest4.C b/gcc/testsuite/g++.old-deja/g++.law/nest4.C
index 183442d61db..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/nest4.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/nest4.C
@@ -1,20 +1 @@
-// Build don't link:
-// GROUPS passed nest
-// nest file
-// From: Neal Young <ney@princeton.edu>
-// Date: Mon, 11 Oct 93 17:03:59 EDT
-// Subject: g++ 2.4.5 bug report: local class decl can't access local static var
-// Message-ID: <9310112103.AA06326@cs>
-
-void f()
-{
- static int s;
-
- struct local {
- int j() { return s; } // should be okay, see 1991 ref. man. r.9.8
- };
-}
-
-main()
-{
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.law/operators1.C b/gcc/testsuite/g++.old-deja/g++.law/operators1.C
deleted file mode 100644
index fa4c10cf3b9..00000000000
--- a/gcc/testsuite/g++.old-deja/g++.law/operators1.C
+++ /dev/null
@@ -1,27 +0,0 @@
-// GROUPS passed operators
-// opr-conv file
-// Message-Id: <199301040217.AA04377@cypress.ucsc.edu>
-// From: "Dean R. E. Long" <dlong@cse.ucsc.edu>
-// Subject: conversion operator bug?
-// Date: Sun, 3 Jan 1993 18:17:20 -0800
-
-#include <stdio.h>
-class B {};
-
-class A {
- B *p;
-public:
- A() { p = 0; }
- operator B * () { return p; }
- operator B & () { return *p; }
-};
-
-main()
-{
- A a;
- B &b = (B &)a;
- B *bp = (B *)a;
- B &br = a.operator B&();
-// What's the right test?
- printf ("FAIL\n");
-}
diff --git a/gcc/testsuite/g++.old-deja/g++.law/operators10.C b/gcc/testsuite/g++.old-deja/g++.law/operators10.C
index fe4f13d4b99..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/operators10.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/operators10.C
@@ -1,23 +1 @@
-// Build don't link:
-// GROUPS passed operators
-// opr-eq file
-// Message-Id: <9306040324.AA22954@balder.cs.wisc.edu>
-// From: so@cs.wisc.edu (Bryan So)
-// Subject: g++ bug
-// Date: Thu, 3 Jun 93 22:24:13 -0500
-
-template <class T>
-struct Test {
- int data;
- Test& operator=(int i) { data = i; return *this; }
-};
-
-
-main()
-{
- Test<int> i, j;
-
- i = j;
-
- return 0;
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.law/operators13.C b/gcc/testsuite/g++.old-deja/g++.law/operators13.C
index 3675d50b7fb..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/operators13.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/operators13.C
@@ -1,24 +1 @@
-// Build don't link:
-// GROUPS passed operators
-// opr-eq file
-// Message-Id: <1993Nov18.210502.28842@midway.uchicago.edu>
-// From: mps@dent.uchicago.edu (Michael Spertus)
-// Subject: g++ 2.5.4 bug : operator=
-// Date: Thu, 18 Nov 1993 21:05:02 GMT
-
-class T {
-};
-
-class EP {
-public:
- void operator=(T *);
-};
-
-
-void EP::operator=(T *) { }
-
-main()
-{
- EP ep1, ep2;
- ep1 = ep2;
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.law/operators14.C b/gcc/testsuite/g++.old-deja/g++.law/operators14.C
index 191266fe4a2..b3b753c1a91 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/operators14.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/operators14.C
@@ -1,10 +1 @@
-// Build don't link:
-// GROUPS passed operators
-void foo (int * a, int * b, int * c) {}
-
-main() {
- int a,b,c;
- foo (&a, &b, &c);
- (a = b) = c;
-}
-
+int main() {
diff --git a/gcc/testsuite/g++.old-deja/g++.law/operators16.C b/gcc/testsuite/g++.old-deja/g++.law/operators16.C
index 384c4e9c286..090a634bc24 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/operators16.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/operators16.C
@@ -1,29 +1 @@
-// GROUPS passed operators
-// copy file
-// From: gfm@mencon.mencon.oz.au (Graham Menhennitt)
-// Date: Thu, 29 Apr 93 20:53:07 EST
-// Subject: 4 bugs in g++ 2.3.3
-// Message-ID: <9304291053.AA00090@mencon>
-
-#include <stdio.h>
-
-int pass = 0;
-struct A {
- A(void) {}
- A(const A& a) { ; }
- A& operator = (const A& a) { pass = 1; }
-};
-
-struct B {
- B(const A& aa) { B::a = aa; }
- A a;
-};
-
-main(void)
-{
- B(A());
- if (pass)
- printf ("PASS\n");
- else
- printf ("FAIL\n");
-}
+int main(void)
diff --git a/gcc/testsuite/g++.old-deja/g++.law/operators21.C b/gcc/testsuite/g++.old-deja/g++.law/operators21.C
index c1f8b8be133..b3b753c1a91 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/operators21.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/operators21.C
@@ -1,16 +1 @@
-// Build don't link:
-// GROUPS passed operators
-
-struct A {
- int x;
-};
-
-int operator()(A x,float y) {// ERROR - .*
- return 1;
-}
-
-main() {
- A x;
- x(1.0); // ERROR - no match
-}
-
+int main() {
diff --git a/gcc/testsuite/g++.old-deja/g++.law/operators28.C b/gcc/testsuite/g++.old-deja/g++.law/operators28.C
index c0d1ecdad2d..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/operators28.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/operators28.C
@@ -1,30 +1 @@
-// Build don't link:
-// GROUPS passed operators
-#include <sys/types.h>
-#include <stdio.h>
-
-class new_test
-{
- int type;
-public:
- void* operator new(size_t sz, int count, int type);
-};
-
-void* new_test::operator new(size_t sz, int count, int type)
-{
- void *p;
-
- printf("%d %d %d\n", sz, count, type);
-
- p = new char[sz * count];
- ((new_test *)p)->type = type;
- return p;
-};
-
-main()
-{
- new_test *test;
- int count = 13;
-
- test = new(count, 1) new_test;
-};
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.law/operators30.C b/gcc/testsuite/g++.old-deja/g++.law/operators30.C
index 3c23a060a2d..e9b6d280feb 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/operators30.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/operators30.C
@@ -1,25 +1,3 @@
-// GROUPS passed operators
-// opr-mm file
-// Date: Thu, 2 Jun 94 10:00:29 +0200
-// From: chatty@cenatls.cena.dgac.fr (Stephane Chatty)
-// Message-Id: <9406020800.AA14201@geant.cenatls.cena.dgac.fr>
-// Subject: result of operator -- with g++-2.5.8
-
-#include <stdio.h>
-
-nop()
-{
-} // ERROR - non-void
-
-main ()
-{
- int a = 2;
-
- if (----a == 0)
- nop ();
-
- if (a == 0)
- printf("PASS\n");
- else
- printf("FAIL\n");
+void nop()
}
+int main ()
diff --git a/gcc/testsuite/g++.old-deja/g++.law/operators32.C b/gcc/testsuite/g++.old-deja/g++.law/operators32.C
index bb6f8c902ae..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/operators32.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/operators32.C
@@ -1,55 +1 @@
-// Build don't link:
-// GROUPS passed operators
-#include <iostream.h>
-
-//
-// frees space allocated for N-D array
-//
-
-template <class T>
-void free(long rows, T** array)
-{
-for( long i = 0; i < rows; i++ )
- delete [] array[i]; // delete row
-delete [] array; // delete outer array
-}
-
-template <class T>
-T* allocate1d(long size, T*& array)
-{
-return array = new T[size];
-}
-
-template <class T>
-T** allocate2d(long d1, long d2, T**& array)
-{
-if( allocate1d(d1, array) != 0 )
- {
- for( long i = 0; i < d1; i++ )
- {
- if( allocate1d(d2, array[i]) == 0 )
- {
- free(i,array);
- return array;
- }
- }
- }
-return array;
-}
-
-main()
-{
-long d1 = 3, d2 = 4;
-class foo
-{
-public:
-foo() {cout << "foo created" << endl; }
-
-~foo() {cout << "foo deleted" << endl; }
-};
-
-foo **f2;
-allocate2d(d1, d2, f2);// ERROR - type.*// ERROR - trying to.*
-free(d1, f2);// ERROR - type.*// ERROR - trying to.*
-
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.law/operators4.C b/gcc/testsuite/g++.old-deja/g++.law/operators4.C
index e5df81d3a29..044249fa8b7 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/operators4.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/operators4.C
@@ -22,7 +22,7 @@ void foo(int s)
Vector junk(s);
}
-main()
+int main()
{
Vector* test;
for (int i=0;i<40;i++) // was 100000
diff --git a/gcc/testsuite/g++.old-deja/g++.law/operators7.C b/gcc/testsuite/g++.old-deja/g++.law/operators7.C
deleted file mode 100644
index 7d00bd7c2ba..00000000000
--- a/gcc/testsuite/g++.old-deja/g++.law/operators7.C
+++ /dev/null
@@ -1,44 +0,0 @@
-// GROUPS passed operators
-// opr-as file
-// From: amichail@lambert.waterloo.edu (Amir Michail)
-// Date: Mon, 15 Jun 1992 19:41:37 GMT
-// Subject: inheretance bug
-// Message-ID: <AMICHAIL.92Jun15144137@lambert.waterloo.edu>
-
-#include <stdio.h>
-class window {
- public:
- int k;
- virtual void inc() {}
-};
-
-class window_border : public virtual window {
- public:
- void inc () { k++; }
-};
-
-class container {
- public:
- window_border c;
-#if 0
- container& operator = (const container& o) {
- this->c = o.c;
- return *this;
- }
-#endif
-};
-
-int main() {
- container test, *test2;
- void *vp;
- test2 = new container;
- test.c.k = 34;
- vp = (window *)&test2->c;
- *test2 = test;
- test.c.k = 60;
- if (test2->c.k == 35
- && test.c.k == 60)
- printf ("PASS\n");
- else
- printf ("FAIL\n");
-}
diff --git a/gcc/testsuite/g++.old-deja/g++.law/operators8.C b/gcc/testsuite/g++.old-deja/g++.law/operators8.C
index 0b59d3cd1b5..b3b753c1a91 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/operators8.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/operators8.C
@@ -1,49 +1 @@
-// GROUPS passed operators
-#include <stdio.h>
-
-class shape {
- public:
- virtual void vDisplay(void) const = 0;
- protected:
- int X;
- int Y;
-};
-
-class square :public shape {
- public:
- square(int x, int y, int width_) {
- X = x;
- Y = y;
- width = width_;
- }
- void vDisplay(void) const {
- printf ("PASS\n");
- }
- protected:
- int width;
-};
-
-
-class triangle :public shape {
- public:
- triangle(int x, int y, int width_, int height_) {
- X = x;
- Y = y;
- width = width_;
- height = height_;
- }
- void vDisplay(void) const {
- printf ("FAIL\n");
- }
- protected:
- int width;
- int height;
-};
-
-main() {
- shape* s1 = new square(4,4,5);
- shape* s2 = new triangle(6,6,2,3);
- *s1 = *s2;
- s1->vDisplay();
-}
-
+int main() {
diff --git a/gcc/testsuite/g++.old-deja/g++.law/parsing6.C b/gcc/testsuite/g++.old-deja/g++.law/parsing6.C
index 7fcc13c5071..b3b753c1a91 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/parsing6.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/parsing6.C
@@ -1,15 +1 @@
-// Build don't link:
-// GROUPS passed parsing
-// parsing folder
-// From: "James S. Vera" <vera@fanaraaken.stanford.edu>
-// Date: Thu, 01 Jul 1993 16:36:32 -0700
-// Subject: Mildly complicated type not understood, 2.4.5
-// Message-ID: <9307012336.AA13841@fanaraaken.Stanford.EDU>
-
-typedef int (*cow[3])(...);
-
-main() {
- cow fs;
- int (*pig[3])(...); // line 5
-
-}
+int main() {
diff --git a/gcc/testsuite/g++.old-deja/g++.law/parsing8.C b/gcc/testsuite/g++.old-deja/g++.law/parsing8.C
index 9a714a35493..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/parsing8.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/parsing8.C
@@ -1,31 +1 @@
-// Build don't link:
-// GROUPS passed parsing
-// parsing folder
-// From: nag@soft.flab.fujitsu.co.jp
-// Date: Thu, 08 Jul 1993 10:54:59 +0900
-// Subject: g++ cannot understand `void (**f)()'
-// Message-ID: <9307080155.AA00496@kumade.soft.flab.fujitsu.co.jp>
-
- void
- func() {
- int ( * * i )[ 2 ];
- }
-
-// Looks like this is probably the same problem
-// parsing folder
-// From: nag@soft.flab.fujitsu.co.jp
-// Date: Thu, 08 Jul 1993 10:54:59 +0900
-// Subject: g++ cannot understand `void (**f)()'
-// Message-ID: <9307080155.AA00496@kumade.soft.flab.fujitsu.co.jp>
-main()
-{
- void (**f)();
-}
-
-
-// Same as
-// From: Chris Dodd <dodd@csl.sri.com>
-// Date: Fri, 16 Jul 93 17:05:04 -0700
-// Subject: bug in declaration parsing in g++ 2.4.5
-// Message-ID: <9307170005.AA03857@pekoe.csl.sri.com>
-
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.law/parsing9.C b/gcc/testsuite/g++.old-deja/g++.law/parsing9.C
index 13138ed9fce..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/parsing9.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/parsing9.C
@@ -1,32 +1 @@
-// Build don't link:
-// GROUPS passed parsing
-// From: Jason Merrill <jason@cygnus.com>
-// Date: Fri, 13 Aug 93 12:49:11 PDT
-// Subject: 2.4.5 won't compile array of pointers to functions returning T
-// Message-ID: <9308131949.AA26348@cygnus.com>
-// From: "Robert M. Keller" <keller@jarthur.Claremont.EDU>
-// Subject: g++ bug
-// Date: Fri, 13 Aug 93 10:09:27 PDT
-
-/* Testing declaration of "array of pointers to functions returning T" */
-
-typedef int T;
-
-T foo()
-{ return 10; }
-
-T bar()
-{ return 20; }
-
-T baz()
-{ return 30; }
-
-main()
-{
-T (*apfrt[10])();
-
-apfrt[0] = foo;
-apfrt[1] = bar;
-apfrt[2] = baz;
-
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.law/patches1.C b/gcc/testsuite/g++.old-deja/g++.law/patches1.C
index e151a33fa24..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/patches1.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/patches1.C
@@ -1,24 +1 @@
-// Build don't link:
-// GROUPS passed patches
-// patches file
-// From: david.binderman@pmsr.philips.co.uk
-// Date: Wed, 6 Oct 93 17:05:54 BST
-// Subject: Reno 1.2 bug fix
-// Message-ID: <9310061605.AA04160@pmsr.philips.co.uk>
-
-int type(float) { return 1; }
-int type(double) { return 2; }
-int type(long double) { return 3; }
-
-extern "C" int printf( const char *, ...);
-
-main()
-{
- int i = 0;
- if (type(0.0) != 2)
- ++i;
- if (i > 0)
- printf ("FAIL\n");
- else
- printf ("PASS\n");
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.law/refs1.C b/gcc/testsuite/g++.old-deja/g++.law/refs1.C
index f0b7f118a0f..b3b753c1a91 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/refs1.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/refs1.C
@@ -1,42 +1 @@
-// GROUPS passed references
-// (Message bugs/refs:1)
-// From: tal@vlsi.cs.caltech.edu
-// Date: Fri, 25 Feb 94 23:55:50 -0800
-// Subject: g++-2.5.8 produces incorrect code for references
-// Message-ID: <9402260755.AA27693@vlsi.cs.caltech.edu>
-
-#include <stdio.h>
-
-class C {
-private:
- char** list;
-public:
- C(char** );
- void count (int&);
-};
-
-C::C (char** l) {
- list = l;
-}
-
-void C::count (int& total) {
- if (*list == NULL)
- return;
- else {
- list++;
- count (++total); // THIS IS WHERE THE TROUBLE STARTS
- }
-}
-
-char * foo[] = {
- "one", "two", "three", NULL};
-
-main() {
- C c(foo);
- int i = 0;
- c.count(i);
- if (i == 3)
- printf ("PASS\n");
- else
- printf ("FAIL\n");
-}
+int main() {
diff --git a/gcc/testsuite/g++.old-deja/g++.law/refs4.C b/gcc/testsuite/g++.old-deja/g++.law/refs4.C
index a73c078ce98..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/refs4.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/refs4.C
@@ -1,21 +1 @@
-// GROUPS passed references
-extern "C" void printf (char *, ...);
-
-const int& min(const int& tX, const int& tY)
-{
- return tX < tY ? tX : tY;
-}
-
-void foo(const int m, const int n)
-{
- if (m == 1 && n == 100)
- printf("PASS\n");
- else
- printf("FAIL\n");
-}
-
-main()
-{
- foo(min(2, 1), min(100, 200));
- return 0;
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.law/scope2.C b/gcc/testsuite/g++.old-deja/g++.law/scope2.C
index f8b90529d73..fca7aa3a92f 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/scope2.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/scope2.C
@@ -1,44 +1 @@
-// GROUPS passed scoping
-// scoping file
-// From: svkakkad@cs.utexas.edu (Sheetal V. Kakkad)
-// Date: Tue, 5 Oct 93 12:38:49 -0500
-// Subject: G++ 2.4.5 - global delete operator not called when using "::delete"
-// Message-ID: <9310051738.AA14586@boogie.cs.utexas.edu>
-
-#include <stdio.h>
-#include <stddef.h>
-#include <stdlib.h>
-
-class foo
-{
- public:
- foo () { ; }
- ~foo () { ; }
- void *operator new (size_t);
- void operator delete (void *);
-};
-
-void *foo::operator new (size_t size)
-{
- return malloc (size);
-}
-
-int overloaded_delete = 0;
-
-void foo::operator delete (void *data)
-{
- free ((char *) data);
- overloaded_delete++;
-}
-
-main ()
-{
- foo *f = new foo;
- foo *ff = ::new foo;
- ::delete ff; // should call the default delete operator
- delete f;
- if (overloaded_delete == 1)
- printf ("PASS\n");
- else
- printf ("FAIL\n");
-}
+int main ()
diff --git a/gcc/testsuite/g++.old-deja/g++.law/scope5.C b/gcc/testsuite/g++.old-deja/g++.law/scope5.C
index 2aea15bd94c..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/scope5.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/scope5.C
@@ -1,25 +1 @@
-// Build don't link:
-// GROUPS passed scoping
-// local-class file
-// From: schlaege@methusalix.ert.rwth-aachen.de (Chris Schlaeger H Zivojnovic)
-// Date: Tue, 10 Aug 93 16:50:33 +0200
-// Subject: Bug report
-// Message-ID: <9308101450.AA28016@methusalix.ert.rwth-aachen.de>
-
-main()
-{
- class foo
- {
- int i;
- } ;
- class bar
- {
- public:
- bar() { y = 0; }
- void f() { foo x; }
- private:
- int y;
- } ;
-
- bar c;
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.law/static-mem4.C b/gcc/testsuite/g++.old-deja/g++.law/static-mem4.C
index 4e026478e55..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/static-mem4.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/static-mem4.C
@@ -1,13 +1 @@
-// Build don't link:
-// GROUPS passed static-mem
-struct test {
- void test_member() {
- static test& ds = *this; // FIX: static test* ds = this;
- }
-};
-
-
-main()
-{
- test t;
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.law/template1.C b/gcc/testsuite/g++.old-deja/g++.law/template1.C
index 809e5090c88..b3b753c1a91 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/template1.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/template1.C
@@ -1,30 +1 @@
-// Build don't link:
-// GROUPS passed templates
-
-class String {
- char s[100];
-};
-
-template <class Element>
-class Art {
-public:
- Element *data;
- Art() { data=new Element[100]; }
-};
-
-template <class Key,class Value>
-class Assoc {
-public:
- struct KeyValue {
- Key key;
- Value value;
- int filled;
- };
-
- Art<KeyValue> data;
- int fill;
-};
-
-main() {
- Assoc<String,String> table;
-}
+int main() {
diff --git a/gcc/testsuite/g++.old-deja/g++.law/temps2.C b/gcc/testsuite/g++.old-deja/g++.law/temps2.C
index d9684814368..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/temps2.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/temps2.C
@@ -1,54 +1 @@
-// GROUPS passed temps
-// temps file
-// Message-Id: <9212181914.AA05066@sparc1.cnm.us.es>
-// From: juando@cnm.us.es (Juan Domingo Martin Gomez)
-// Subject: Temporaries destroyed too soon
-// Date: Fri, 18 Dec 92 20:14:45 +0100
-
-#include <stdio.h>
-
-int status = 0;
-int fail = 0;
-
-class Foo
-{
-public:
- Foo();
- ~Foo();
-
- Foo &method();
-};
-
-Foo f1()
-{
- return Foo();
-}
-
-Foo::Foo()
-{
-}
-
-Foo::~Foo()
-{
- if (status == 2)
- fail = 0;
- else
- fail = 1;
-}
-
-Foo &Foo::method()
-{
- status++;
- return *this;
-}
-
-main()
-{
- // f1() returns a temporary object. The member function
- // method() returns a reference to the same object.
- f1().method().method();
- if (fail)
- printf ("FAIL\n");
- else
- printf ("PASS\n");
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.law/temps3.C b/gcc/testsuite/g++.old-deja/g++.law/temps3.C
index 7b092844c5c..fca7aa3a92f 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/temps3.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/temps3.C
@@ -1,28 +1 @@
-// GROUPS passed temps
-// temps file
-// Message-Id: <9308231535.AA19432@geant.cenatls.cena.dgac.fr>
-// From: chatty@geant.cenatls.cena.dgac.fr (Stephane CHATTY)
-// Subject: g++ 2.4.5 does not destroy temporaries
-// Date: Mon, 23 Aug 93 17:35:34 +0200
-
-#include <stdio.h>
-
-class A {
-public:
- int a;
- A (int i) : a (i) { ;}
- A (const A& aa) : a (aa.a) { ;}
- ~A () { printf ("PASS\n");; }
-};
-
-A
-foo ()
-{
- return A (10);
-}
-
-main ()
-{
- int x = foo ().a;
-}
-
+int main ()
diff --git a/gcc/testsuite/g++.old-deja/g++.law/temps6.C b/gcc/testsuite/g++.old-deja/g++.law/temps6.C
index e228ce8ea75..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/temps6.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/temps6.C
@@ -1,24 +1 @@
-// GROUPS passed temps
-// Date: Tue, 22 Mar 94 12:46:28 +0100
-// From: dak@pool.informatik.rwth-aachen.de
-// Message-Id: <9403221146.AA07815@messua>
-// Subject: Bad code for pointer to member use as reference in g++ 2.5.8
-
-#include <stdio.h>
-struct str {
- int i;
-} xxx = {0};
-
-int& test(str *arg1, int str::*arg2)
-{
- return (arg1->*arg2);
-}
-
-main()
-{
- test(&xxx, &str::i) = 5;
- if (xxx.i == 0)
- printf ("FAIL\n");
- else
- printf ("PASS\n");
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.law/typeck1.C b/gcc/testsuite/g++.old-deja/g++.law/typeck1.C
index 2fabfe9db83..3c117d16672 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/typeck1.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/typeck1.C
@@ -1,18 +1 @@
-// Build don't link:
-// GROUPS passed typeck
-// typeck file
-// From: vern@daffy.ee.lbl.gov (Vern Paxson)
-// Date: 24 Sep 1992 23:11:22 GMT
-// Subject: 2.2.2 type-checking error (?) when comparing pointers
-// Message-ID: <26475@dog.ee.lbl.gov>
-
-
- class a { };
- class foo : a { };
- class bar : a { };
-
- test( const foo* f, const bar* b )
- {
- return f == b;// ERROR -
- }
-
+ int test( const foo* f, const bar* b )
diff --git a/gcc/testsuite/g++.old-deja/g++.law/typeck2.C b/gcc/testsuite/g++.old-deja/g++.law/typeck2.C
index 485a9291866..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/typeck2.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/typeck2.C
@@ -1,16 +1 @@
-// Build don't link:
-// GROUPS passed typeck
-// typeck file
-// From: Jutta Degener <jutta@cs.tu-berlin.de>
-// Date: Wed, 9 Jun 1993 17:58:35 +0200 (MET DST)
-// Subject: 2.4.3: Type of new <typedef'ed array>
-// Message-ID: <199306091558.AA19075@mail.cs.tu-berlin.de>
-
- typedef int arr[10];
- main()
- {
- int * p = new int[10];
- int * q = new arr; /* g++ complains, but shouldn't */
- int (* r)[10] = new arr; /* g++ doesn't complain, but should */// ERROR -
- }
-
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.law/union1.C b/gcc/testsuite/g++.old-deja/g++.law/union1.C
index 5ab9c905583..b3b753c1a91 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/union1.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/union1.C
@@ -1,30 +1 @@
-// Build don't link:
-// GROUPS passed unions
-// excess errors test - XFAIL *-*-*
-// anon-union file
-// From: "Terry R. Coley" <terry@wag.caltech.edu>
-// Date: Tue, 25 Aug 1992 17:33:29 -0700
-// Subject: possible bug in gcc/g++
-// Message-ID: <199208260033.AA19417@brahms.wag.caltech.edu>
-
-typedef enum { BADBINOP = 0, PLUS, MINUS, MULT, DIV, POWR } binoptype;
-typedef enum { BADUNOP = 0, NEG = POWR+1, SIN, COS, TAN } unoptype;
-
-typedef struct {
- char *s;
- union {
- binoptype bop;
- unoptype uop;
- };
-}
-op_to_charp;
-
-op_to_charp BINOPS[] = { {"+", PLUS},
- {"-", MINUS},
- {"*", MULT},
- {"/", DIV},
- {"^", POWR} };
-
-main() {
- int dummy;
-}
+int main() {
diff --git a/gcc/testsuite/g++.old-deja/g++.law/union2.C b/gcc/testsuite/g++.old-deja/g++.law/union2.C
index 9f812d762e8..32b5a651ca8 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/union2.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/union2.C
@@ -1,25 +1,2 @@
-// Build don't link:
-// GROUPS passed unions
-// anon-union file
-// From: gerlek@dat.cse.ogi.edu (Michael Gerlek)
-// Date: Tue, 8 Dec 92 12:56 PST
-// Subject: private anonymous unions have public members? (gcc-2.3.1)
-// Message-ID: <m0mzByL-0000hoC@dat.cse.ogi.edu>
-
-class A {
-public:
- int x;
-private:
- int y;
- union {
- int z;
- };
-};
-
-void f() {
- A a;
-
- a.x = 0;
- a.y = 1;// ERROR - .*
- a.z = 2;// ERROR -
-}
+ int y; // ERROR - private
+ int z; // ERROR - private
diff --git a/gcc/testsuite/g++.old-deja/g++.law/unsorted2.C b/gcc/testsuite/g++.old-deja/g++.law/unsorted2.C
index 3b81431233d..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/unsorted2.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/unsorted2.C
@@ -1,26 +1 @@
-// Build don't link:
-// GROUPS passed unsorted
-// code-gen file
-// From: klaus@steinitz.mathematik.uni-dortmund.de
-// Date: Mon, 15 Nov 1993 16:51:11 +0100
-// Message-ID: <9311151551.AA17761@steinitz.mathematik.uni-dortmund.de>
-
-template <int A,int B>
-class X
-{
-};
-
-template <int A,int B,int C>
-X<A,C> f(X<A,B>,X<B,C>)
-{
- X<A,C> result;
- return result;
-}
-
-main()
-{
- X<1,3> x;
- X<1,2> y;
- X<2,3> z;
- x=f(y,z);
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.law/vbase1.C b/gcc/testsuite/g++.old-deja/g++.law/vbase1.C
index a68c3b143b5..b3b753c1a91 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/vbase1.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/vbase1.C
@@ -1,28 +1 @@
-// Build don't link:
-// GROUPS passed vbase
-// vbase file
-// From: pino@hubble.eecs.berkeley.edu (Jose Luis Pino)
-// Date: 28 Jul 1994 05:17:39 GMT
-// Subject: g++ 2.6 bug: virtual base class & protected methods
-// Message-ID: <317f1j$o9c@agate.berkeley.edu>
-
-
-#include <iostream.h>
-
-class a {
-protected:
- virtual void foo() { cout << "Class A\n";}
-};
-
-class b : public virtual a {};
-
-class c : public b {
-public:
- void bar() { b::foo();}
-};
-
-main() {
- c test;
- test.bar();
-}
-
+int main() {
diff --git a/gcc/testsuite/g++.old-deja/g++.law/virtual3.C b/gcc/testsuite/g++.old-deja/g++.law/virtual3.C
index d141f87ecb1..b3b753c1a91 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/virtual3.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/virtual3.C
@@ -1,47 +1 @@
-// GROUPS passed virtual-functions
-// virtual file
-// From: allan@ramjet.multinet.DE (Allan Brighton)
-// Subject: pos. bug in gcc-2.5.2 on hp
-// Date: 4 Nov 1993 22:57:36 -0500
-// Message-ID: <9311041820.AA05942@ramjet.multinet.DE>
-
-#include <iostream.h>
-#include <strstream.h>
-
-
-class BugStream : public ostrstream {
-public:
- BugStream() {}
- BugStream& eval();
-};
-
-
-static struct Eval_ { } eval;
-BugStream& operator<<(ostream& os, Eval_);
-
-BugStream& BugStream::eval()
-{
- // make sure str is null terminated
- *this << ends;
-
- // eval the command and set the status
- char* s = str();
- cerr << s << endl;
-
- // reset the stream for the next command
- clear(0);
- rdbuf()->freeze(0);
- seekp(0);
-
- return *this;
-}
-
-BugStream& operator<<(ostream& os, Eval_)
-{
- return ((BugStream&)os).eval();
-}
-
-main() {
- BugStream bs;
- bs << "PASS" << eval;
-}
+int main() {
diff --git a/gcc/testsuite/g++.old-deja/g++.law/virtual4.C b/gcc/testsuite/g++.old-deja/g++.law/virtual4.C
index f6310d35fa1..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/virtual4.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/virtual4.C
@@ -1,31 +1 @@
-// GROUPS passed virtual-functions
-#include <stdio.h>
-#include <stdlib.h>
-
-int aset = 0;
-class A
-{
- public:
- void Set() { SetProp(); }
- virtual void SetProp() { aset++;}
-};
-
-class B:public A
-{
- public:
- void SetProp() { if (!aset) { printf ("FAIL\n"); exit (0);} aset--;}
-};
-
-main()
-{
- A a;
- B b;
- A *c=new A;
- A *d=new B;
-
- a.Set();
- b.Set();
- c->Set();
- d->Set();
- printf ("PASS\n");
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.law/visibility1.C b/gcc/testsuite/g++.old-deja/g++.law/visibility1.C
index 0314c0741c2..67f4bcd9919 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/visibility1.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/visibility1.C
@@ -51,7 +51,7 @@ derived_friend()
-main(int argc, char *argv[])
+int main(int argc, char *argv[])
//==========================
{
base b;
diff --git a/gcc/testsuite/g++.old-deja/g++.law/visibility11.C b/gcc/testsuite/g++.old-deja/g++.law/visibility11.C
index 9fa31dc3163..e10148ac124 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/visibility11.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/visibility11.C
@@ -1,48 +1,5 @@
-// Build don't link:
-// Special g++ Options: -w
-// GROUPS passed visibility
-// visibility file
-// From: Alan Shepherd <a.shepherd@nexor.co.uk>
-// Date: Tue, 22 Jun 1993 14:53:23 +0100
-// Subject: bug with MI in gcc-2.4.5
-// Message-ID: <9659.740757203@nexor.co.uk>
-
-class A
-{
- int a;
-
-protected:
-
- virtual void State(int b) { a = b; }
-
-};
-
-class B : public A
-{
- char* foo;
-
public:
+ D();
- B(const char*);
-};
-
-class C : public A
-{
- char* foo2;
-
-public:
-
- C(const char*);
-};
-
-class D : public B, public C
-{
-protected:
- virtual void State(int a)
- {
- B::State(a);
- C::State(a);
- }
-};
diff --git a/gcc/testsuite/g++.old-deja/g++.law/visibility12.C b/gcc/testsuite/g++.old-deja/g++.law/visibility12.C
index c3a9963f994..212614ac243 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/visibility12.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/visibility12.C
@@ -1,18 +1 @@
-// Build don't link:
-// GROUPS passed visibility
-// visibility file
-// From: Mark Rawling <Mark.Rawling@mel.dit.csiro.au>
-// Date: Wed, 30 Jun 93 15:28:34 +1000
-// Subject: member access rule bug
-// Message-ID: <9306300528.AA17185@coda.mel.dit.CSIRO.AU>
-struct a {
- int aa;
- };
-
-class b : private a {
- };
-
-class c : public b {
- int xx(void) { return (aa); } // aa should be invisible// ERROR - .*
- };
-
+ int aa; // ERROR - private
diff --git a/gcc/testsuite/g++.old-deja/g++.law/visibility13.C b/gcc/testsuite/g++.old-deja/g++.law/visibility13.C
index 8bd6a851b71..7f634e20cd8 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/visibility13.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/visibility13.C
@@ -23,8 +23,8 @@ public:
virtual Type& operator[](int ix) { return ia[ix]; }
private:
void init(const Type*, int);
- int size;
- int *ia;
+ int size; // ERROR - private
+ int *ia; // ERROR - private
};
template <class Type>
@@ -94,7 +94,7 @@ try_array( Array_RC<Type> &rc )
try_array( ((Array<Type>&)rc) );
}
-main()
+int main()
{
static int ia[10] = { 12, 7, 14, 9, 128, 17, 6, 3, 27, 5 };
Array_RC<int> iA(ia, 10);// ERROR - instantiated from here
diff --git a/gcc/testsuite/g++.old-deja/g++.law/visibility16.C b/gcc/testsuite/g++.old-deja/g++.law/visibility16.C
index b5d87ef363d..27c1b484b3d 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/visibility16.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/visibility16.C
@@ -1,35 +1,3 @@
-// Build don't link:
-// GROUPS passed visibility
-// visibility file
-// From: Marie Trapp <Marie.Trapp@analog.com>
-// Date: Thu, 5 Aug 93 11:55:15 EDT
-// Subject: access of protected members
-// Message-ID: <9308051553.AA07639@nwd2sun1.analog.com>
-class A {
- protected:
- int astuff;
- A() {
- astuff = 3;
- }
-};
-
-class B : public A {
- int bstuff;
- public:
- B( A *p) {
- bstuff = p->astuff;// ERROR - .*
- }
-};
-
-class C : public A {
- int cstuff;
- public:
- C() {
- cstuff = 5;
- }
-};
-
-main() {
- C cvar;
- B bvar(&cvar);
-}
+ int astuff; // ERROR - protected
+ astuff = 3;
+int main() {
diff --git a/gcc/testsuite/g++.old-deja/g++.law/visibility17.C b/gcc/testsuite/g++.old-deja/g++.law/visibility17.C
index ae198b0bc83..210ffd1442e 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/visibility17.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/visibility17.C
@@ -1,63 +1 @@
-// Build don't link:
-// GROUPS passed visibility
-// visibility file
-// From: Sandeep Shroff <ss@caere.com>
-// Date: Thu, 05 Aug 1993 17:23:20 -0700
-// Subject: Access to private constructor.
-// Message-ID: <9308060023.AA10283@neptune.caere.com>
-#include <iostream.h>
-
-class Base
-{
-public:
- char* getName() {return name_;}
-
-private:
- Base();
- Base(char* str);
-
- char* name_;
-};
-
-class Derived : public Base
-{
-public:
- Derived(int n, char* str);
- Derived(int n);
-
- getNum() {return num_;}
-private:
- int num_;
-};
-
-Base::Base()
-{ // ERROR - private
- name_ = strcpy(new char[strlen(" ") + 1], " ");
-}
-
-Base::Base(char* str)
-{ // ERROR - private
- if(str != NULL)
- name_ = strcpy(new char[strlen(str) + 1], str);
-}
-
-Derived::Derived(int n, char* str) : Base(str)
-{// ERROR - .*
- num_ = n;
-}
-
-Derived::Derived(int n) : Base()
-{// ERROR - .*
- num_ = n;
-}
-
-
-
-int main()
-{
- // Derived* d = new Derived(10, "test");
- Derived* d = new Derived(10);
-
- cerr << d->getNum() << "\t" << d->getName() << endl;
-}
-
+ int getNum() {return num_;}
diff --git a/gcc/testsuite/g++.old-deja/g++.law/visibility18.C b/gcc/testsuite/g++.old-deja/g++.law/visibility18.C
index a294f13edf9..213404624ce 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/visibility18.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/visibility18.C
@@ -1,20 +1 @@
-// Build don't link:
-// GROUPS passed visibility
-// visibility file
-// From: cmwang@iis.sinica.edu.tw (Chien-Min Wang)
-// Date: Fri, 6 Aug 93 19:42:31 CST
-// Subject: A bug in g++ 2.4.5
-// Message-ID: <9308061142.AA08533@iiserv>
-struct T1 { int i; };
-
-struct T2 { int j; };
-
-struct T3 : public T1, private T2 {
-} x;
-
-int main ()
-{
- x.i = 1;
- x.j = 2; // error: x.j is private// ERROR - .*
- return 0;
-}
+struct T2 { int j; }; // ERROR - private
diff --git a/gcc/testsuite/g++.old-deja/g++.law/visibility19.C b/gcc/testsuite/g++.old-deja/g++.law/visibility19.C
index 0f22d6568b7..ba212f3629e 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/visibility19.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/visibility19.C
@@ -1,40 +1 @@
-// Build don't link:
-// GROUPS passed visibility
-// visibility file
-// From: mclaugh@tnt.acsys.com (Mark A. McLaughlin)
-// Date: Wed, 25 Aug 93 14:30:47 MDT
-// Subject: g++ bug
-// Message-ID: <9308252030.AA02352@tnt.acsys.com>
-class B {
-protected:
- int i;
-};
-
-class D1 : public B {
-};
-
-class D2 : public B {
- friend void fr(B*,D1*,D2*);
- void mem(B*,D1*);
-};
-
-void fr(B* pb, D1* p1, D2* p2)
-{
- pb->i = 1; // illegal// ERROR - .*
- p1->i = 2; // illegal// ERROR - .*
- p2->i = 3; // ok (access through D2)
-}
-
-void D2::mem(B* pb, D1* p1)
-{
- pb->i = 1; // illegal// ERROR - .*
- p1->i = 2; // illegal// ERROR - .*
- i = 3; // ok (access through `this')
-}
-
-void g(B* pb, D1* p1, D2* p2)
-{
- pb->i = 1; // illegal// ERROR - .*
- p1->i = 2; // illegal// ERROR - .*
- p2->i = 3; // illegal// ERROR - .*
-}
+ int i; // ERROR - protected
diff --git a/gcc/testsuite/g++.old-deja/g++.law/visibility2.C b/gcc/testsuite/g++.old-deja/g++.law/visibility2.C
index 8ac5cb9e71c..5806fc564b7 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/visibility2.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/visibility2.C
@@ -51,7 +51,7 @@ derived_friend()
-main(int argc, char *argv[])
+int main(int argc, char *argv[])
//==========================
{
base b;
diff --git a/gcc/testsuite/g++.old-deja/g++.law/visibility20.C b/gcc/testsuite/g++.old-deja/g++.law/visibility20.C
index 011abef44c9..b3b753c1a91 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/visibility20.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/visibility20.C
@@ -1,36 +1 @@
-// Build don't link:
-// GROUPS passed visibility
-// visibility file
-// From: doug@foxtrot.ccmrc.ucsb.edu (Douglas Scott)
-// Date: Tue, 10 Aug 93 10:06:33 PDT
-// Subject: G++ 2.4.5 allows access to protected base members
-// Message-ID: <9308101706.AA04485@foxtrot.ccmrc.ucsb.edu>
-
-class Base {
-protected:
- void protectedBaseFunction() {} // ERROR - protected
-public:
- Base() {}
-};
-
-
-class Derived : public Base {
-public:
- Derived() {}
- void noticeThisFunction(Base *);
-};
-
-
-void
-Derived::noticeThisFunction(Base *b) {
- b->protectedBaseFunction(); // ARM says this is not allowed// ERROR - .*
- // since it is not called on 'this'
-}
-
-main() {
- Base b;
- Derived d;
- d.noticeThisFunction(&b);
- printf("gpptest run\n");// ERROR - .*
-}
-
+int main() {
diff --git a/gcc/testsuite/g++.old-deja/g++.law/visibility23.C b/gcc/testsuite/g++.old-deja/g++.law/visibility23.C
deleted file mode 100644
index 3299add8c2b..00000000000
--- a/gcc/testsuite/g++.old-deja/g++.law/visibility23.C
+++ /dev/null
@@ -1,26 +0,0 @@
-// Build don't link:
-// GROUPS passed visibility
-// visibility file
-// From: Robert Carden <carden@thoth.ics.uci.edu>
-// Date: Thu, 12 Aug 1993 13:47:11 -0700
-// Subject: bug 8/12/93 -- #4
-// Message-ID: <9308121347.aa26185@Paris.ics.uci.edu>
-//
-// 4.cc
-//
-#include <stream.h>
-
-class A {
- int x;
-public:
- void f(int);
- void f(float);
- void g(void *);
-};
-
-
-class B : public A {
-private:
- A::f;
- A::g;// ERROR - .* , XFAIL *-*-*
-};
diff --git a/gcc/testsuite/g++.old-deja/g++.law/visibility24.C b/gcc/testsuite/g++.old-deja/g++.law/visibility24.C
index b40075fdbe1..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/visibility24.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/visibility24.C
@@ -1,40 +1 @@
-// Build don't link:
-// GROUPS passed visibility
-// visibility file
-// From: joe@consolve.com (Joe Shapiro)
-// Date: Fri, 20 Aug 93 17:18:18 EDT
-// Subject: Template classes seem to allow users to get at private members
-// Message-ID: <9308202118.AA25599@ghana.consolve>
-/*
- * private.cc
- */
-extern "C" void printf(...);
-
-template <class T>
-class A
-{
-public:
- void Fun() { printf( "Fun fun fun!\n" ); } // ERROR - private
-};
-
-
-template <class T>
-class B: private A<T>
-{
-};
-
-
-class C
-{
-public:
- C() { _b.Fun(); }// ERROR - .*
-
-private:
- B<int> _b;
-};
-
-
-main()
-{
- C c;
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.law/visibility4.C b/gcc/testsuite/g++.old-deja/g++.law/visibility4.C
index 5a92c6c0794..b2d344d47d2 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/visibility4.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/visibility4.C
@@ -1,25 +1 @@
-// Build don't link:
-// GROUPS passed visibility
-// visibility file
-// From: dcb@us-es.sel.de (David Binderman 3841)
-// Date: Tue, 30 Mar 93 15:48:47 +0200
-// Subject: page 242 of the ARM
-// Message-ID: <9303301348.AA20751@slsvitt>
-
-class A {
-public:
- int b;
-};
-
-class C : private A { // NOTE WELL. private, not public
-public:
- int d;
-};
-
-extern "C" int printf( const char *, ...);
-
-class E : public C {
- void f() {
- printf( "%d\n", b);// ERROR - .*
- };
-};
+ int b; // ERROR - private
diff --git a/gcc/testsuite/g++.old-deja/g++.law/visibility7.C b/gcc/testsuite/g++.old-deja/g++.law/visibility7.C
index 26d172bcf81..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/visibility7.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/visibility7.C
@@ -1,71 +1 @@
-// Build don't link:
-// GROUPS passed visibility
-// visibility file
-// From: Gordon Joly <G.Joly@cs.ucl.ac.uk>
-// Date: Wed, 21 Apr 93 09:42:07 +0100
-// Subject: /*** BUG REPORT : THE MYTH OF PRIVATE INHERITANCE ***/
-// Message-ID: <9304210842.AA01815@life.ai.mit.edu>
-#include <iostream.h>
-
-class A {
- private:
- int number;
- public:
- A(int i) : number(i)
- {}
- virtual ~A()
- {}
- virtual void Number(int c)
- { number = c; } // ERROR - private
- virtual int Number()
- { return number; } // ERROR - private
-};
-
-class B : private A {
- private:
- int second_number;
- public:
- B(int c, int i) : second_number(c), A(i)
- {}
- virtual ~B()
- {}
-
- virtual void firstNumber(int b) // renames member function Number(int) of class A
- { A::Number(b); }
- virtual int firstNumber() // renames member function Number() of class A
- { return A::Number(); }
-};
-
-
-
-
-class C {
- private:
- B* bobject;
- public:
- C(B* bp) : bobject(bp)
- {}
- virtual ~C()
- {}
- //
- // the following two functions access
- // private member functions of class B
- // and they should not be able to do so
- //
- virtual void setBValue(int i)
- { if (bobject) bobject->Number(i); }// ERROR - .*
- virtual int getBValue()
- { if (bobject) { return bobject->Number(); } return 0; }// ERROR - .*
-};
-
-
-main()
-{
- B* bobject = new B(2, 1);
- C* cobject = new C(bobject);
- cobject->setBValue(8);
- cout << cobject->getBValue() << endl;
- delete bobject;
- delete cobject;
-}
-
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.law/visibility8.C b/gcc/testsuite/g++.old-deja/g++.law/visibility8.C
index 3e5178c6c01..3e2fa4447d0 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/visibility8.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/visibility8.C
@@ -1,26 +1 @@
-// Build don't link:
-// GROUPS passed visibility
-// visibility file
-// From: roland@jts.com (Roland Knight )
-// Date: Thu, 29 Apr 1993 16:17:00 -0400
-// Subject: gcc 2.3.3 bug
-// Message-ID: <m0nof3E-0021ifC@jts.com
-class t1 {
-protected:
- int a;
-};
-
-
-class t2 : private t1 {
-public:
- int b;
-};
-
-
-class t3 : public t2 {
-public:
- int ttt();
-};
-
-
-int t3::ttt() { return a; }// ERROR - .*
+ int a; // ERROR - protected
diff --git a/gcc/testsuite/g++.old-deja/g++.law/visibility9.C b/gcc/testsuite/g++.old-deja/g++.law/visibility9.C
index df98640c90d..3e2fa4447d0 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/visibility9.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/visibility9.C
@@ -1,22 +1 @@
-// Build don't link:
-// GROUPS passed visibility
-// visibility file
-// rom: roland@jts.com (Roland Knight )
-// Date: Sat, 8 May 1993 17:27:35 -0400
-// Subject: gcc 2.3.3 protected member access bug
-// Message-ID: <9305082127.AA19577@icepick.jts.com>
-
-class A {
-protected:
- int a;
-};
-
-class B : public A {
-public:
- void f1(A* pa);
-};
-
-
-void B::f1(A* pa) {
- pa->a = 1; // illegal but allowed by gcc// ERROR - .*
-}
+ int a; // ERROR - protected
diff --git a/gcc/testsuite/g++.old-deja/g++.law/vtable1.C b/gcc/testsuite/g++.old-deja/g++.law/vtable1.C
index c788c179054..dd57290826b 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/vtable1.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/vtable1.C
@@ -1,27 +1,2 @@
-// Build don't link:
-// GROUPS passed vtable
-// excess errors test - XFAIL *-*-*
-// vtable file
-// From: mrs@cygnus.com (Mike Stump)
-// Date: Wed, 20 Apr 1994 17:46:11 -0700
-// Subject: vtable name generation is wrong
-// Message-ID: <199404210046.RAA25652@rtl.cygnus.com>
-
-// prepare_fresh_vtable doesn't build the names of
-// vtables very well.
-
-struct B {
- virtual void vf() { }
-};
-
-struct Main {
- virtual void vf() { }
-};
-
-struct Other : public Main, public B {
- virtual void vf() { }
-};
-
-struct D : public Main, public B, public Other {
- virtual void vf() { }
-} a;
+// Build don't link:
+// Special g++ Options: -w
diff --git a/gcc/testsuite/g++.old-deja/g++.law/vtable3.C b/gcc/testsuite/g++.old-deja/g++.law/vtable3.C
index 5759026331d..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/vtable3.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/vtable3.C
@@ -1,24 +1 @@
-// GROUPS passed vtable
-// vtable file
-// From: Pete Bevin <pete@deng.icl.co.uk>
-// Date: Mon, 28 Nov 1994 19:57:53 +0000 (GMT)
-// Subject: g++-2.6.2: Virtual inheritance causes incorrect padding
-// Message-ID: <Pine.SOL.3.91.941128194453.7510A-100000@gabriel>
-
-extern "C" void printf (char *, ...);
-
-struct A {
-};
-
-
-struct B : virtual A {
- public:
- int b;
-};
-
-
-main()
-{
- B blist[10];
- printf ("PASS\n");
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.martin/ambig1.C b/gcc/testsuite/g++.old-deja/g++.martin/ambig1.C
index 3ee730ddc26..9886991e29b 100644
--- a/gcc/testsuite/g++.old-deja/g++.martin/ambig1.C
+++ b/gcc/testsuite/g++.old-deja/g++.martin/ambig1.C
@@ -2,12 +2,12 @@
//Based on a report by Bill Currie <bcurrie@tssc.co.nz>
struct foo {
protected:
- int x;
+ int x; // ERROR - candidate
};
struct bar {
public:
- int x();
+ int x(); // ERROR - candidate
};
struct foobar: public foo, public bar {
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/align1.C b/gcc/testsuite/g++.old-deja/g++.mike/align1.C
index e26d398e0a9..765014bc66d 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/align1.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/align1.C
@@ -1,56 +1 @@
-// Check to make sure we align virtual base classes properly
-
-class eel_base {
-public:
-};
-
-class markable_eel_base : public eel_base {
-private:
- int mark;
-};
-
-class eel_edge : public markable_eel_base {
-public:
-private:
- int foo;
-};
-
-class edge : public virtual eel_edge {
-public:
- edge() {
- _weight = 0.0;
- }
-private:
- double _weight;
-};
-class eel_branch_edge : public virtual edge {
-};
-class branch_edge : public eel_branch_edge {
-};
-
-class eel_interproc_branch_edge : public branch_edge {
-};
-
-class interproc_edge : public virtual edge {
-};
-
-class eel_jump_edge : public virtual edge {
-protected:
-};
-
-class jump_edge : public eel_jump_edge {
-public:
-};
-
-class eel_interproc_jump_edge : public jump_edge {
-protected:
-};
-
-class interproc_jump_edge : public eel_interproc_jump_edge,
- public interproc_edge {
-public:
-};
-
-main () {
- void *vp = new interproc_jump_edge();
-}
+int main () {
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/align2.C b/gcc/testsuite/g++.old-deja/g++.mike/align2.C
index 36791fed803..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/align2.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/align2.C
@@ -1,16 +1 @@
-class Foo {
-};
-
-class Bar : virtual Foo {
-public:
- int b;
-} x;
-
-main()
-{
- // printf("Foo offset %d\n", (int)(Foo*)&x - (int)&x);
- // printf("b offset %d\n", (int)&x.b - (int)&x);
- // printf("sizeof is %d\n", sizeof(Bar));
- // This core dumps on a SPARC is alignment is wrong.
- Bar blist[10];
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/ambig1.C b/gcc/testsuite/g++.old-deja/g++.mike/ambig1.C
index 5f67b743109..b3b753c1a91 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/ambig1.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/ambig1.C
@@ -1,32 +1 @@
-extern "C" int printf(const char *, ...);
-
-struct VB {
- virtual void f() {
- printf("VB\n");
- }
-};
-
-class M : public virtual VB {
-public:
- int i;
- void f() {
- printf("M(%d)\n", i);
- }
-};
-
-class lM : public M {
-};
-
-class rM : public M {
-};
-
-class D : public lM, rM {
-} d; // ERROR - ambiguous function
-
-main() {
- ((lM*)&d)->i = 1;
- ((rM*)&d)->i = 2;
- ((rM*)&d)->f();
- ((lM*)&d)->f();
- ((VB*)&d)->f();
-}
+int main() {
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/conv1.C b/gcc/testsuite/g++.old-deja/g++.mike/conv1.C
index b67ecbb0e6f..b3b753c1a91 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/conv1.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/conv1.C
@@ -1,10 +1 @@
-enum E { C };
-
-E foo() {
- return C;
-}
-
-main() {
- if (foo() != C)
- return 1;
-}
+int main() {
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/dyncast1.C b/gcc/testsuite/g++.old-deja/g++.mike/dyncast1.C
index fbcc489eaaf..3bddb3ce1e4 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/dyncast1.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/dyncast1.C
@@ -4,11 +4,11 @@
#include <typeinfo>
struct B {
- virtual f() { }
+ virtual int f() { }
};
struct D {
- virtual f() { }
+ virtual int f() { }
};
main() {
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/dyncast2.C b/gcc/testsuite/g++.old-deja/g++.mike/dyncast2.C
index ba7a39edbaa..fcf625e8c69 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/dyncast2.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/dyncast2.C
@@ -6,11 +6,11 @@
#include <typeinfo>
struct B {
- virtual f() { }
+ virtual int f() { }
} ob;
struct D : public B {
- virtual f() { }
+ virtual int f() { }
} od;
main() {
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/dyncast3.C b/gcc/testsuite/g++.old-deja/g++.mike/dyncast3.C
index ee775d043f1..72f73f04424 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/dyncast3.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/dyncast3.C
@@ -1,19 +1,2 @@
-// Special g++ Options: -fexceptions -w
-// excess errors test - XFAIL a29k-*-* sparc64-*-elf sh-*-* arm-*-pe**-*
-// Ensure that the return type of dynamic_cast is the real type.
-
-struct B {
- virtual f() { }
-};
-
-struct D : public B {
- virtual f() { }
- int i;
-} od;
-
-main() {
- B *b=&od;
- if (dynamic_cast<D*>(b)->i)
- return 1;
- return 0;
-}
+ virtual int f() { }
+ virtual int f() { }
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/eh19.C b/gcc/testsuite/g++.old-deja/g++.mike/eh19.C
index 38b4bf16d8b..54f870e7c06 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/eh19.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/eh19.C
@@ -1 +1,3 @@
} catch(test1::fehler()) // function type promoted to pointer
+ void func(int a) {
+int main() {
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/eh20.C b/gcc/testsuite/g++.old-deja/g++.mike/eh20.C
index 31f3c6f928a..b5287f33795 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/eh20.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/eh20.C
@@ -1,6 +1 @@
-// Build don't link:
-// Special g++ Options: -fexceptions -Wall
-
-main() {
- throw 1;
-}
+int
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/eh33.C b/gcc/testsuite/g++.old-deja/g++.mike/eh33.C
index 49214f12c88..234b745f3a3 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/eh33.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/eh33.C
@@ -7,9 +7,9 @@ void my_unexpected() {
throw 42;
}
-foo() throw (int) { throw "Hi"; }
+void foo() throw (int) { throw "Hi"; }
-main() {
+int main() {
std::set_unexpected (my_unexpected);
try {
foo();
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/eh34.C b/gcc/testsuite/g++.old-deja/g++.mike/eh34.C
index 0f278010023..9c7e985bbea 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/eh34.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/eh34.C
@@ -7,9 +7,9 @@ void my_unexpected() {
exit (0);
}
-foo() throw () { throw "Hi"; }
+void foo() throw () { throw "Hi"; }
-main() {
+int main() {
std::set_unexpected (my_unexpected);
foo();
return 1;
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/eh4.C b/gcc/testsuite/g++.old-deja/g++.mike/eh4.C
index 5de9b03ffe6..79c37a0804b 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/eh4.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/eh4.C
@@ -1,6 +1 @@
-// Build don't link:
-// Special g++ Options: -fexceptions
-
-foo() {
- throw 1;
-}
+void foo() {
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/eh49.C b/gcc/testsuite/g++.old-deja/g++.mike/eh49.C
index 3a301cc54ee..278f434dbab 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/eh49.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/eh49.C
@@ -1,15 +1,2 @@
-// Special g++ Options: -fexceptions -O9
-// excess errors test - XFAIL a29k-*-* sparc64-*-elf sh-*-* arm-*-pe**-*
-
-main1() {
- throw 1;
-}
-
-main() {
- try {
- main1();
- } catch (...) {
- return 0;
- }
- return 1;
-}
+void main1() {
+int main() {
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/eh6.C b/gcc/testsuite/g++.old-deja/g++.mike/eh6.C
index f5409867a23..278f434dbab 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/eh6.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/eh6.C
@@ -1,19 +1,2 @@
-// Special g++ Options: -fexceptions
-// excess errors test - XFAIL a29k-*-* sparc64-*-elf sh-*-* arm-*-pe**-*
-
-extern "C" int printf(const char *, ...);
-
-main1() {
- throw 1;
-}
-
-
-main() {
- try {
- main1();
- } catch (...) {
- printf("Unwind works!\n");
- return 0;
- }
- return 1;
-}
+void main1() {
+int main() {
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/err2.C b/gcc/testsuite/g++.old-deja/g++.mike/err2.C
index e7f0be2a987..35e3bc68521 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/err2.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/err2.C
@@ -1,6 +1 @@
-class foo {
-public:
- apply(foo *(foo::*memptr)()) {
- this->*memptr(); // ERROR - wrong
- }
-};
+ void apply(foo *(foo::*memptr)()) {
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/leak1.C b/gcc/testsuite/g++.old-deja/g++.mike/leak1.C
index 849322f128c..b3b753c1a91 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/leak1.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/leak1.C
@@ -1,38 +1 @@
-int count = 0;
-
-class T {
- int i;
-public:
- T() {
- i = 1;
- ++count;
- }
- T(const T& o) {
- i = o.i;
- ++count;
- }
- T operator +(const T& o) {
- T r;
- r.i = this->i + o.i;
- return r;
- }
- operator int () {
- return i;
- }
- ~T() {
- --count;
- }
-} s, b;
-
-void bar() {
- static int j = int(s+b);
- int i = int(s+b);
-}
-
-int i = int(s+b);
-
-main() {
- bar();
- bar();
- return count != 2;
-}
+int main() {
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/misc1.C b/gcc/testsuite/g++.old-deja/g++.mike/misc1.C
index 1703b546318..1ee5e393520 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/misc1.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/misc1.C
@@ -1,53 +1,2 @@
-// GROUPS passed construct-destruct
-/* g++ constructs j 13 times, and destructs it once. */
-
-extern "C" {
- int printf(...);
- void exit(int);
-}
-
-void foo() {
-}
-
-class C {
- int val;
- public:
- static int count;
- C(int ii) {
- val = ii;
- ++count;
- printf("up\n");
- }
- ~C() {
- --count;
- printf("down\n");
- }
- operator ++() {
- return ++val;
- }
- operator int() {
- return val;
- }
-};
-
-int C::count = 0;
-
-void bar() {
- for (int ii=0; ii<13; ++ii)
- for (C j=1; j<9; ++j)
- foo();
-}
-
-main() {
- bar();
- if (C::count)
- {
- printf("FAIL\n");
- exit(1);
- }
- else
- {
- printf("PASS\n");
- }
- return 0;
-}
+ int operator ++() {
+int main() {
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/misc13.C b/gcc/testsuite/g++.old-deja/g++.mike/misc13.C
index 80874b15e03..166e33dce6a 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/misc13.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/misc13.C
@@ -39,7 +39,7 @@ ivHandler *bar2() {
return &a;
}
-main() {
+int main() {
want=vf_request;
bar()->request();
want=vf_event;
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/misc14.C b/gcc/testsuite/g++.old-deja/g++.mike/misc14.C
index 75827cb8c46..4886dcc9274 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/misc14.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/misc14.C
@@ -18,7 +18,7 @@ public:
}
};
-main() {
+int main() {
B b;
A *ap = &b;
ap->~A(); // This should call the destructor virtually.
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/misc5.C b/gcc/testsuite/g++.old-deja/g++.mike/misc5.C
index bd3e85cee48..9e53eb4eacc 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/misc5.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/misc5.C
@@ -1,11 +1 @@
-// Build don't link:
-// GROUPS uncaught
-// Cfront bug A.3 (See Language System Release Notes for the
-// SPARCompiler C++ version 3.0)
-
-struct S1 {
- static int S1; // ERROR - uses same name 9.3
-};
-struct S2 {
- union { int ii; float S2; }; // ERROR - uses same name 9.3 , XFAIL *-*-*
-};
+ union { int ii; float S2; }; // ERROR - uses same name 9.3
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/misc8.C b/gcc/testsuite/g++.old-deja/g++.mike/misc8.C
index 4cea2133422..3e0eff5c112 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/misc8.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/misc8.C
@@ -1,5 +1 @@
-// Build don't link:
-// GROUPS passed vtable
-class T { public: virtual ~T() {} };
-template<class P> class X : public virtual T {};
-main() { X<int> x; }
+int main() { X<int> x; }
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/net10.C b/gcc/testsuite/g++.old-deja/g++.mike/net10.C
index a290b46e25a..4546bf1bd0b 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/net10.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/net10.C
@@ -4,7 +4,7 @@
const int ci=10, *pc = &ci, *const cpc = pc, **ppc;
int i, *p, *const cp = &i;
-main()
+int main()
{
i = ci;
*cp = ci;
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/net17.C b/gcc/testsuite/g++.old-deja/g++.mike/net17.C
index f80eeb39613..b3b753c1a91 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/net17.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/net17.C
@@ -1,58 +1 @@
-// example from the ARM page 292 and 293
-
-extern "C" int printf(const char *, ...);
-extern "C" void exit(int);
-
-int i = 0;
-
-class A {
-public:
- A() {
- printf("Doing A\n");
- if (++i != 1)
- exit(1);
- }
-};
-
-class B {
-public:
- B() {
- printf("Doing B\n");
- if (++i != 2)
- exit(1);
- }
-};
-
-class C : public virtual A, public virtual B {
-public:
- C() {
- printf("Doing C\n");
- if (++i != 3)
- exit(1);
- }
-};
-
-class D : public virtual B, public virtual A {
-public:
- D() {
- printf("Doing D\n");
- if (++i != 4)
- exit(1);
- }
-};
-
-class E : public C, public D {
-public:
- E() {
- printf("Doing E\n");
- if (++i != 5)
- exit(1);
- }
-} e;
-
-
-main() {
- if (++i != 6)
- exit(1);
- return 0;
-}
+int main() {
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/net22.C b/gcc/testsuite/g++.old-deja/g++.mike/net22.C
index 088a0fea4d8..b3b753c1a91 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/net22.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/net22.C
@@ -1,13 +1 @@
-class Parent {
-public:
- Parent() {}
- Parent( char *s ) {}
-};
-
-class Child : public Parent {
-}; // ERROR - called
-
-main() {
- Child c( "String initializer" ); // ERROR - bad
- return 0;
-}
+int main() {
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/net26.C b/gcc/testsuite/g++.old-deja/g++.mike/net26.C
index 5a00c8e0450..b3b753c1a91 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/net26.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/net26.C
@@ -1,27 +1 @@
-// A test case found by InterViews testing...
-
-extern "C" int printf(const char *, ...);
-
-class A {
-public:
- int foo() { printf("ok nv\n"); }
- virtual int vfoo() { printf("ok v\n"); }
-};
-
-struct S {
- int (A::*pfn1)();
- int (A::*pfn2)();
- int (A::*pfn3)();
-};
-
-// This failed before.
-S s = { &A::foo, &A::vfoo, &A::foo };
-
-A a;
-
-main() {
- (a.*s.pfn1)();
- (a.*s.pfn2)();
- printf("PASS\n");
- return 0;
-}
+int main() {
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/net34.C b/gcc/testsuite/g++.old-deja/g++.mike/net34.C
index 06d196c890a..b3b753c1a91 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/net34.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/net34.C
@@ -1,36 +1 @@
-#include <iostream.h>
-
-class foo {
-public:
- foo(int i) {k = i;}
-protected:
- int k;
-};
-
-class bar_1 : public foo {
-public:
- bar_1(int i) : foo(i) {}
- int get_k() {return k;}
-};
-
-class bar_2 : public foo {
-public:
- bar_2(int i) : foo(i) {};
- int get_k() {return k;}
-};
-
-class multiple : public bar_1, public bar_2 {
-public:
- multiple(int i1, int i2) : bar_1(i1), bar_2(i2) {}
- void print() {
- cout << "bar_1::k -> " << bar_1::k << "\n";
- cout << "bar_2::k -> " << bar_2::k << "\n";
- cout << "bar_1::get_k() -> " << bar_1::get_k() << "\n";
- cout << "bar_2::get_k() -> " << bar_2::get_k() << "\n";
- }
-};
-
-main() {
- multiple m(1,2);
- m.print();
-}
+int main() {
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/net38.C b/gcc/testsuite/g++.old-deja/g++.mike/net38.C
index 5732d594f71..765014bc66d 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/net38.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/net38.C
@@ -1,28 +1 @@
-struct A {
- virtual int a () { return 0; }
-};
-
-struct B {
- virtual int b () { return 0; }
- virtual int b2 () { return 0; }
-};
-
-struct C : public A, public B {
- virtual int a () { return 1; }
- virtual int b () { return 2; }
- virtual int b2 () { return 3; }
-};
-
-int (C::*vmpb) () = &C::b;
-int (C::*vmpb2) () = &C::b2;
-int (C::*vmpa) () = &C::a;
-
-main () {
- C c;
- if ((c.*vmpa)() != 1)
- return 1;
- if ((c.*vmpb)() != 2)
- return 1;
- if ((c.*vmpb2)() != 3)
- return 1;
-}
+int main () {
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/net41.C b/gcc/testsuite/g++.old-deja/g++.mike/net41.C
index 6f02d3ce0f4..b3b753c1a91 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/net41.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/net41.C
@@ -1,3 +1 @@
-main() {
- int i = ~ false;
-}
+int main() {
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/net43.C b/gcc/testsuite/g++.old-deja/g++.mike/net43.C
index c2c789325d6..fca7aa3a92f 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/net43.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/net43.C
@@ -1,11 +1 @@
-// Build don't link:
-
-class foo {
- public:
- friend int operator ^(const foo&, const foo&);
-};
-
-main ()
-{
- int (*funptr) (const foo &, const foo &) = operator ^;
-}
+int main ()
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/net45.C b/gcc/testsuite/g++.old-deja/g++.mike/net45.C
index 6f9dc3a391b..cef8734d1e8 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/net45.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/net45.C
@@ -1,20 +1 @@
-// Build don't link:
-
-template <class T1, class T2>
-struct pair {
- T1 first;
- T2 second;
- pair(const T1& a, const T2& b) : first(a), second(b) {}
-};
-
-struct myint {
- myint() {
- }
- myint(const myint& mi) {
- }
- operator=(const myint& mi) {
- }
-};
-
-extern pair<const myint, myint> a;
-pair<const myint, myint> b(a);
+ myint& operator=(const myint& mi) {
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/net46.C b/gcc/testsuite/g++.old-deja/g++.mike/net46.C
index 235cbfb87e1..ac7950117f9 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/net46.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/net46.C
@@ -9,7 +9,7 @@ static void *operator new(size_t size) throw (std::bad_alloc) {
return (void*) 0;
}
-main() {
+int main() {
cout << "";
new int;
return fail;
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/net47.C b/gcc/testsuite/g++.old-deja/g++.mike/net47.C
index 431ff22f1a0..dedb71e7a4a 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/net47.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/net47.C
@@ -1,8 +1 @@
-// Build don't link:
-// Special g++ Options: -w
-
-class foo {};
-class bar : foo {
-public:
- bar () : () {}
-};
+// Special g++ Options: -w -fpermissive
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/net8.C b/gcc/testsuite/g++.old-deja/g++.mike/net8.C
index 62b4fedb569..fca7aa3a92f 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/net8.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/net8.C
@@ -1,32 +1 @@
-// Build don't link:
-// Special g++ Options: -pedantic-errors
-
-class Base {
-public:
- int foo;
-};
-
-class Derived : public Base {
-public:
- int bar;
-};
-
-void func(Base&); // ERROR -
-
-void func2(const Derived& d) {
- func(d); // ERROR - this is bad
-}
-
-void
-foo (int& a)
-{ // ERROR -
-}
-
-main ()
-{
- int b;
- const int*const a = &b;
- *a = 10; // ERROR - it's const
- foo (*a); // ERROR - it's const
- return 0;
-}
+int main ()
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/net9.C b/gcc/testsuite/g++.old-deja/g++.mike/net9.C
index c36151c88a9..7d876dc95f4 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/net9.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/net9.C
@@ -4,7 +4,7 @@
const int ci=10, *pc = &ci, *const cpc = pc, **ppc;
int i, *p, *const cp = &i;
-main()
+int main()
{
ci = 1; // ERROR - bad
ci++; // ERROR - bad
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/ns1.C b/gcc/testsuite/g++.old-deja/g++.mike/ns1.C
index c9189270180..c347d2d93a4 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/ns1.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/ns1.C
@@ -1,11 +1,11 @@
namespace Foo {
- bar() {
+ int bar() {
return 0;
}
}
using namespace Foo;
-main() {
+int main() {
bar();
}
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/ns10.C b/gcc/testsuite/g++.old-deja/g++.mike/ns10.C
index 2418004ba5e..a6b1c3aedd3 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/ns10.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/ns10.C
@@ -1,9 +1,9 @@
namespace Foo {
- bar() {
+ int bar() {
return 0;
}
}
-main() {
+int main() {
return Foo::bar();
}
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/ns11.C b/gcc/testsuite/g++.old-deja/g++.mike/ns11.C
index e69de29bb2d..a25b7878e68 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/ns11.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/ns11.C
@@ -0,0 +1,3 @@
+ int bar() {
+ int mymain() {
+int main() {
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/ns2.C b/gcc/testsuite/g++.old-deja/g++.mike/ns2.C
index 30a263d43c6..365eb8c0923 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/ns2.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/ns2.C
@@ -4,6 +4,6 @@ namespace N {
using namespace N;
-main() {
+int main() {
return i;
}
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/ns9.C b/gcc/testsuite/g++.old-deja/g++.mike/ns9.C
index e69de29bb2d..27a0f186ad6 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/ns9.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/ns9.C
@@ -0,0 +1,2 @@
+ int bar() {
+int main() {
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/opr-as1.C b/gcc/testsuite/g++.old-deja/g++.mike/opr-as1.C
index 38795b5ba24..b3b753c1a91 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/opr-as1.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/opr-as1.C
@@ -1,11 +1 @@
-// Shows a problem with the default op= not being an implementation...
-
-class C {
- int i;
-};
-
-C a, b;
-
-main() {
- a = b;
-}
+int main() {
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/opr-dot1.C b/gcc/testsuite/g++.old-deja/g++.mike/opr-dot1.C
index e709057c33a..d5d88e10c74 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/opr-dot1.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/opr-dot1.C
@@ -1,22 +1 @@
-// Build don't link:
-
-typedef struct base1 {
- int x;
-} base1_t;
-
-typedef struct base2 {
- int x;
-} base2_t;
-
-class derived1 : public base1 {
-};
-
-class derived2 : public derived1, public base2 {
-};
-
-struct test {
- derived2& fails;
- test1() {
- fails.base1::x = 5;
- }
-};
+ void test1() {
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/p10148.C b/gcc/testsuite/g++.old-deja/g++.mike/p10148.C
index 36309763fde..b3b753c1a91 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/p10148.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/p10148.C
@@ -1,33 +1 @@
-// prms-id: 10148
-
-int fail = 1;
-void ok() { fail = 0; }
-
-class TC {
- int s_;
-};
-
-class TIRD {
- public:
- void (*itc)();
- TIRD() { itc = ok; }
-};
-
-class TCCB : public TC, public TIRD {
-};
-
-class TCRCB : public TCCB {
-public:
- virtual void eat ();
-};
-
-void TCRCB::eat () {
- void *vp = (TIRD*)this->itc;
- this->itc();
-}
-
-main() {
- TCRCB a;
- a.eat();
- return fail;
-}
+int main() {
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/p10769a.C b/gcc/testsuite/g++.old-deja/g++.mike/p10769a.C
index c0bd36c6269..f5ff345a3fd 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/p10769a.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/p10769a.C
@@ -9,7 +9,7 @@ class A {
public:
void f1a() { ok += 3; }
void f1b() { ok += 5; }
- void f2a() { ok += 7; }
+ void f2a() { ok += 7; } // gets bogus error XFAIL *-*-*
void f2b() { }
const static void (*table[2][2])();
void main();
@@ -31,7 +31,7 @@ void A::main() {
void (A::*mPtr)() = &A::f1a;
(*(void (*)(A*))PMF2PF(mPtr))(&a);
- (*(void (*)(A*))PMF2PF(f2a))(&a);
+ (*(void (*)(A*))PMF2PF(f2a))(&a); // gets bogus error XFAIL *-*-*
}
int main() {
@@ -40,6 +40,6 @@ int main() {
void (A::*mPtr)() = &A::f1b;
(*(void (*)(A*))PMF2PF(a.*mPtr))(&a);
- (*(void (*)(A*))PMF2PF(a.f2a))(&a);
+ (*(void (*)(A*))PMF2PF(a.f2a))(&a); // gets bogus error XFAIL *-*-*
return ok != 3+3+5+5+7+7;
}
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/p10849a.C b/gcc/testsuite/g++.old-deja/g++.mike/p10849a.C
index a5c377312a1..d6d46569b87 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/p10849a.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/p10849a.C
@@ -27,7 +27,7 @@ struct D : public B, public C
D() : B(41), C(42) { }
} d;
-main() {
+int main() {
if (! d.g())
return 1;
}
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/p1248.C b/gcc/testsuite/g++.old-deja/g++.mike/p1248.C
index 3db677c5b80..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/p1248.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/p1248.C
@@ -1,28 +1 @@
-// GROUPS passed pure-virt
-extern "C" { void printf(const char *, ...); }
-class Base {
-public:
- virtual ~Base() =0;
-};
-
-class Deranged : public Base {
-public:
- int value;
- virtual ~Deranged();
-};
-
-
-Deranged::~Deranged(){}
-
-void foo() {
- Deranged d;
-}
-
-main()
-{
- foo();
- printf("PASS\n");
- return 0;
-}
-
-Base::~Base () { }
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/p1567.C b/gcc/testsuite/g++.old-deja/g++.mike/p1567.C
index c805818e0ea..0b35bd972e0 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/p1567.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/p1567.C
@@ -29,7 +29,7 @@ public:
const char* f3() { return A::f3(); }
};
-main() {
+int main() {
C* tempC = new C;
D* tempD = new D;
A* a = tempC;
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/p16146.C b/gcc/testsuite/g++.old-deja/g++.mike/p16146.C
index 2fd95e52bd7..070dc2ea4b8 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/p16146.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/p16146.C
@@ -81,7 +81,7 @@ public:
void j () {};
};
-main () {
+int main () {
firstBase* fbp = new classImplementation;
classImplementation* cip = dynamic_cast <classImplementation*> (fbp);
cip->addRef();
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/p1862.C b/gcc/testsuite/g++.old-deja/g++.mike/p1862.C
index ff7266f150c..401b3700777 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/p1862.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/p1862.C
@@ -45,7 +45,7 @@ public:
}
};
-main()
+int main()
{
C1 *one = new C1;
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/p2736.C b/gcc/testsuite/g++.old-deja/g++.mike/p2736.C
index 0ef5b3a0001..b3b753c1a91 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/p2736.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/p2736.C
@@ -1,28 +1 @@
-// This is a poor test case, it is meant to ensure that function local
-// statics are destroyed at the right time. See PR 2736 for details.
-// prms-id: 2736
-
-int count;
-
-struct A {
- int which;
- A(int i) :which(i) {
- // printf("ctor %x\n", this);
- }
- ~A() {
- // printf("dtor %x\n", this);
- if (++count != which)
- abort ();
- }
-};
-
-void
-foo() {
- static A a(1);
-}
-
-A a(2);
-
-main() {
- foo();
-}
+int main() {
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/p2846.C b/gcc/testsuite/g++.old-deja/g++.mike/p2846.C
index 953e80037b8..fca7aa3a92f 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/p2846.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/p2846.C
@@ -1,55 +1 @@
-// prms-id: 2846
-
-extern "C" int printf(const char *, ...);
-extern "C" void exit(int);
-
-class A;
-class B;
-
-class A {
-public:
-
- A(void){}
- A(const A&){}
- A(const B&);
-
- virtual ~A(void){}
-
- virtual void print(void) const {
- printf("A::print\n");
- printf("FAIL\n");
- exit(1);
- }
- B compute(void) const;
-};
-
-class B : private A {
-friend class A;
-public:
-
- virtual ~B(void){}
-
- void print(void) const {
- printf("B::print\n");
- }
-
-private:
- B(const A& x, int){}
-};
-
-A::A(const B& s) {
- s.print();
-}
-
-B A::compute(void) const {
- B sub(*this, 1);
- return sub;
-}
-
-main ()
-{
- A titi;
- A toto = titi.compute();
- printf("PASS\n");
- return 0;
-}
+int main ()
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/p2846a.C b/gcc/testsuite/g++.old-deja/g++.mike/p2846a.C
index 363ed5b0177..765014bc66d 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/p2846a.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/p2846a.C
@@ -1,34 +1 @@
-// Shows that problem of initializing one object's vtable pointer from
-// another object's vtable pointer when doing a default copy of it
-// and the vtable pointer involved is the main one.
-
-// Correct answer is B::print.
-// g++ prints D::print, which is wrong. Cfront gets is right.
-
-// prms-id: 2846
-
-extern "C" int printf(const char *, ...);
-extern "C" void exit(int);
-
-class B {
-public:
- virtual void print(void) const { printf("B::print\n"); }
-};
-
-class D : public B {
-public:
- void print(void) const { printf("D::print\n"); exit(1); }
- B compute(void) const;
-};
-
-B D::compute(void) const
-{
- B sub(*(B*)this);
- return sub;
-}
-
-main () {
- D titi;
- titi.compute().print();
- return 0;
-}
+int main () {
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/p2846b.C b/gcc/testsuite/g++.old-deja/g++.mike/p2846b.C
index 0fb8217456e..fca7aa3a92f 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/p2846b.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/p2846b.C
@@ -1,52 +1 @@
-// Shows that problem of initializing one object's secondary base from
-// another object via a user defined copy constructor for that base,
-// the pointer for the secondary vtable is not set after implicit
-// copying of the outer class, but rather has the pointer to the main
-// vtable for the secondary base left over from the user defined copy
-// constructor for that base.
-
-// Correct answer is B::beefy.
-// g++ prints A::beefy, which is wrong. Cfront gets it right.
-
-// prms-id: 2846
-
-extern "C" int printf(const char *, ...);
-extern "C" void exit(int);
-
-class B;
-
-class A {
- public:
-
- A(void){}
- A(const A&){}
-
- virtual void print(void) const { }
- B compute(void) const;
-};
-
-class C {
-public:
- C() { }
- C(C& o) { } // with it, things are wrong, without it, they're ok
- virtual void beefy(void) const { printf("A::beefy\n"); exit(1); }
-};
-
-class B : private A, public C {
-public:
- B(const A& x, int){}
- void beefy(void) const { printf("B::beefy\n"); }
-};
-
-B A::compute(void) const
-{
- B sub(*this, 1);
- return sub;
-}
-
-main ()
-{
- A titi;
- titi.compute().beefy();
- return 0;
-}
+int main ()
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/p2960.C b/gcc/testsuite/g++.old-deja/g++.mike/p2960.C
index f7c88d9843c..b3b753c1a91 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/p2960.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/p2960.C
@@ -1,30 +1 @@
-// prms-id: 2960
-
-extern "C" int printf(const char *, ...);
-
-class Test0 {
-public:
- virtual void f0() { } // works fine if this virtual removed
-};
-
-class Test1 : public Test0 {
-public:
- void f1() { f2(); } // generates bus error here
- virtual void f2() { printf("Test1::f2\n"); }
-};
-
-class Test2 {
-public:
- virtual void f3() { }
-};
-
-class Test3 : public Test2, public Test1 { // works fine if Test1 first
-public:
- virtual ~Test3() { f1(); } // calling f2 directly works
- virtual void f2() { printf("Test3::f2\n"); }
-};
-
-main() {
- Test3 t3;
- return 0;
-}
+int main() {
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/p3041.C b/gcc/testsuite/g++.old-deja/g++.mike/p3041.C
index c059c0e6cdb..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/p3041.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/p3041.C
@@ -1,33 +1 @@
-// prms-id: 3041
-
-class A {
-public:
- A() { }
- virtual void a() = 0;
- static int b(A * p) {
- p->a();
- return 1;
- }
-};
-
-class B : virtual public A {
-public:
- B() {
- static int installed = b(this);
- }
- void a() { }
-};
-
-class C : virtual public B {
-public:
- C() {
- static int installed = b(this);
- }
- void a() { }
-};
-
-main()
-{
- C c;
- return 0;
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/p3060d.C b/gcc/testsuite/g++.old-deja/g++.mike/p3060d.C
index 2813d66c871..b3b753c1a91 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/p3060d.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/p3060d.C
@@ -1,34 +1 @@
-// This is a test case to make sure the explicit cast on a pointer to
-// a member function works ok.
-// prms-id: 3060
-
-extern "C" int printf(const char *, ...);
-
-class Object;
-
-typedef void (Object::*VoidObjMemberFunc)(Object *, ...);
-
-class Object {
-public:
- int foo;
-};
-
-class Clipper: public Object {
-public:
- int bar;
- void Feedback(Object*, void*);
-};
-void Clipper::Feedback(Object *tracker, void *ap) {
- printf("Doing feedback\n");
-}
-
-void vfunc(VoidObjMemberFunc of, Object *op, void *v1) {
- (op->*of)(op, v1);
-}
-
-main() {
- Object o;
-
- vfunc((VoidObjMemberFunc)&Clipper::Feedback, &o, 0);
- return 0;
-}
+int main() {
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/p3068.C b/gcc/testsuite/g++.old-deja/g++.mike/p3068.C
index 52c5cd56de3..b3b753c1a91 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/p3068.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/p3068.C
@@ -1,60 +1 @@
-// prms-id: 3068
-
-extern "C" int printf(const char *, ...);
-extern "C" void exit(int);
-
-class LB {
-public:
- virtual int test() { return 0; }
- virtual ~LB() { }
-protected:
- LB() { }
-};
-
-class RRB {
-public:
- virtual ~RRB() { }
- virtual void test2(int a) { }
-};
-
-class RR : public RRB {
-public:
- virtual ~RR() { }
-};
-
-class RL {
-public:
- virtual void real(int a) {
- printf("RL::real\n");
- }
-};
-
-
-class R : public RL, public RR {
-public:
- virtual void test3(int a) { }
- virtual void test2(int a) { }
-};
-
-class L : public LB {
-};
-
-class C : public L, public R {
-public:
- C() { }
- virtual ~C() {
- printf("C::~C\n");
- exit(1);
- }
- virtual void real(int a) {
- printf("RL::real\n");
- }
-};
-
-main() {
- C& bb = *new C;
- R& mv = bb;
- bb.real(0);
- mv.real(0);
- return 0;
-}
+int main() {
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/p3139.C b/gcc/testsuite/g++.old-deja/g++.mike/p3139.C
index 9ff9b23cfa5..b3b753c1a91 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/p3139.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/p3139.C
@@ -1,25 +1 @@
-// prms-id: 3139
-
-extern "C" int printf(const char *, ...);
-
-class A {
- public:
- A() { }
- virtual int a() = 0;
-};
-
-class B : virtual public A {
- public:
- virtual int a() = 0;
-};
-
-class C : public B {
- public:
- int a() { return 42; }
-};
-
-main() {
- B * b = new C;
- printf("%d.\n", b->a());
- return 0;
-}
+int main() {
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/p3570.C b/gcc/testsuite/g++.old-deja/g++.mike/p3570.C
index abccf793cb6..fca7aa3a92f 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/p3570.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/p3570.C
@@ -1,29 +1 @@
-// prms-id: 3570
-
-extern "C" int printf(const char *, ...);
-
-struct A {
- void print() {printf("A");};
-};
-
-struct B : A {
- typedef A superB;
- void print() {superB::print(); printf("B");};
-};
-
-struct C : B {
- typedef B superC;
- void print() {superC::print(); printf("C");};
-};
-
-main ()
-{
- A a;
- B b;
- C c;
-
- a.print(); printf("\n");
- b.print(); printf("\n");
- c.print(); printf("\n");
- return 0;
-}
+int main ()
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/p3708.C b/gcc/testsuite/g++.old-deja/g++.mike/p3708.C
index 2f5e401e56d..a6d00e8ef89 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/p3708.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/p3708.C
@@ -1,86 +1,4 @@
-// prms-id: 3708
-
-extern "C" void printf (char *, ...);
-extern "C" int atoi (char *);
-
-void *ptr;
-
-class A {
-public:
- A() { printf ("A is constructed.\n"); }
- virtual xx(int doit) { printf ("A is destructed.\n"); }
-};
-
-class A1 {
-public:
- A1() { printf ("A1 is constructed.\n"); }
- virtual xx(int doit) { printf ("A1 is destructed.\n"); }
-};
-
-class B : public virtual A, public A1 {
-public:
- B() { printf ("B is constructed.\n"); }
- virtual xx(int doit) {
- printf ("B is destructed.\n");
- A1::xx (1);
- if (doit) A::xx (1);
- }
-};
-
-int num;
-
-class C : public virtual A, public B {
-public:
- C() { ++num; printf ("C is constructed.\n");
- ptr = this;
- }
- virtual xx(int doit) {
- --num;
- if (ptr != this)
- printf("FAIL\n%x != %x\n", ptr, this);
- printf ("C is destructed.\n");
- B::xx (0);
- if (doit) A::xx (1);
- }
-};
-
-void fooA(A *a) {
- printf ("Casting to A!\n");
- a->xx (1);
-}
-void fooA1(A1 *a) {
- printf ("Casting to A1!\n");
- a->xx (1);
-}
-
-void fooB(B *b) {
- printf ("Casting to B!\n");
- b->xx (1);
-}
-
-void fooC(C *c) {
- printf ("Casting to C!\n");
- c->xx (1);
-}
-
-int main(int argc, char *argv[]) {
- printf ("*** Construct C object!\n");
- C *c = new C();
-
- int i = 0;
-
- printf ("*** Try to delete the casting pointer!\n");
- switch (i)
- {
- case 0: fooA1(c);
- break;
- case 1: fooA(c);
- break;
- case 2: fooB(c);
- break;
- case 3: fooC(c);
- break;
- }
-
- return num!=0;
-}
+ virtual void xx(int doit) { printf ("A is destructed.\n"); }
+ virtual void xx(int doit) { printf ("A1 is destructed.\n"); }
+ virtual void xx(int doit) {
+ virtual void xx(int doit) {
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/p3708a.C b/gcc/testsuite/g++.old-deja/g++.mike/p3708a.C
index 1fecb16be36..a6d00e8ef89 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/p3708a.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/p3708a.C
@@ -1,86 +1,4 @@
-// prms-id: 3708
-
-extern "C" void printf (char *, ...);
-extern "C" int atoi (char *);
-
-void *ptr;
-
-class A {
-public:
- A() { printf ("A is constructed.\n"); }
- virtual xx(int doit) { printf ("A is destructed.\n"); }
-};
-
-class A1 {
-public:
- A1() { printf ("A1 is constructed.\n"); }
- virtual xx(int doit) { printf ("A1 is destructed.\n"); }
-};
-
-class B : public A1, public virtual A {
-public:
- B() { printf ("B is constructed.\n"); }
- virtual xx(int doit) {
- printf ("B is destructed.\n");
- A1::xx (1);
- if (doit) A::xx (1);
- }
-};
-
-int num;
-
-class C : public virtual A, public B {
-public:
- C() { ++num; printf ("C is constructed.\n");
- ptr = this;
- }
- virtual xx(int doit) {
- --num;
- if (ptr != this)
- printf("FAIL\n%x != %x\n", ptr, this);
- printf ("C is destructed.\n");
- B::xx (0);
- if (doit) A::xx (1);
- }
-};
-
-void fooA(A *a) {
- printf ("Casting to A!\n");
- a->xx (1);
-}
-void fooA1(A1 *a) {
- printf ("Casting to A1!\n");
- a->xx (1);
-}
-
-void fooB(B *b) {
- printf ("Casting to B!\n");
- b->xx (1);
-}
-
-void fooC(C *c) {
- printf ("Casting to C!\n");
- c->xx (1);
-}
-
-int main(int argc, char *argv[]) {
- printf ("*** Construct C object!\n");
- C *c = new C();
-
- int i = 0;
-
- printf ("*** Try to delete the casting pointer!\n");
- switch (i)
- {
- case 0: fooA1(c);
- break;
- case 1: fooA(c);
- break;
- case 2: fooB(c);
- break;
- case 3: fooC(c);
- break;
- }
-
- return num!=0;
-}
+ virtual void xx(int doit) { printf ("A is destructed.\n"); }
+ virtual void xx(int doit) { printf ("A1 is destructed.\n"); }
+ virtual void xx(int doit) {
+ virtual void xx(int doit) {
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/p3708b.C b/gcc/testsuite/g++.old-deja/g++.mike/p3708b.C
index dddb77c2e51..d7e629719c4 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/p3708b.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/p3708b.C
@@ -1,85 +1,5 @@
-// prms-id: 3708
-
-extern "C" void printf (char *, ...);
-extern "C" void exit(int);
-
-void *ptr;
-
-class A {
-public:
- A() { printf ("A is constructed.\n"); }
- virtual xx(int doit) { printf ("A is destructed.\n"); }
-};
-
-class A1 {
-public:
- A1() { printf ("A1 is constructed.\n"); }
- virtual xx(int doit) { printf ("A1 is destructed.\n"); }
-};
-
-class B : public virtual A, public A1 {
-public:
- B() { printf ("B is constructed.\n"); }
- virtual xx(int doit) {
- printf ("B is destructed.\n");
- A1::xx (1);
- if (doit) A::xx (1);
- }
-};
-
-int num;
-
-class C : public virtual A {
-public:
- C() { printf ("C is constructed.\n");
- }
- virtual xx(int doit) {
- printf ("C is destructed.\n");
- if (doit) A::xx (1);
- }
-};
-
-class D : public C, public B {
-public:
- D() { ++num; printf ("D is constructed.\n");
- ptr = this;
- }
- virtual xx(int doit) {
- --num;
- if (ptr != this) {
- printf("FAIL\n%x != %x\n", ptr, this);
- exit(1);
- }
- printf ("D is destructed.\n");
- C::xx (0);
- B::xx (0);
- }
-};
-
-void fooA(A *a) {
- printf ("Casting to A!\n");
- a->xx (1);
-}
-void fooA1(A1 *a) {
- printf ("Casting to A1!\n");
- a->xx (1);
-}
-
-void fooB(B *b) {
- printf ("Casting to B!\n");
- b->xx (1);
-}
-
-void fooC(C *c) {
- printf ("Casting to C!\n");
- c->xx (1);
-}
-
-int main(int argc, char *argv[]) {
- printf ("*** Construct D object!\n");
- D *d = new D();
-
- printf ("*** Try to delete the casting pointer!\n");
- fooA1(d);
- return num!=0;
-}
+ virtual void xx(int doit) { printf ("A is destructed.\n"); }
+ virtual void xx(int doit) { printf ("A1 is destructed.\n"); }
+ virtual void xx(int doit) {
+ virtual void xx(int doit) {
+ virtual void xx(int doit) {
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/p4068.C b/gcc/testsuite/g++.old-deja/g++.mike/p4068.C
index e2531ed81fe..b3b753c1a91 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/p4068.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/p4068.C
@@ -1,22 +1 @@
-// prms-id: 4068
-
-struct A {
- A();
- typedef void (A::*F)();
- void d();
- void foo() { }
- F& f() { return f_; }
- F f_;
-};
-
-A::A() : f_(&A::foo) {
-}
-
-void A::d() {
- (this->*(f()))();
-}
-
-main() {
- A a;
- a.d();
-}
+int main() {
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/p4173.C b/gcc/testsuite/g++.old-deja/g++.mike/p4173.C
index a5b11f226d2..4f388e32cbc 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/p4173.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/p4173.C
@@ -1,24 +1,2 @@
-// This error happens because lvalue is not done well in the C++ front-end.
-// NOPs should be lvalues if their arguments are.
-// NON_LVALUE_EXPRs shouldn't be.
-// Special g++ Options: -Wall -ansi -pedantic-errors
-// Build don't link:
-// prms-id: 4173
-
-enum TypeKind {
- RecordTypeKind
-};
-struct Type
-{
- enum TypeKind kind : 8;
- unsigned char prefixLen;
-};
-
-Type a;
-Type b;
-TypeKind c;
-main() {
- a.kind = b.kind = c;
- (a.kind = c) = b.kind; // gets bogus error
-}
+int
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/p4246.C b/gcc/testsuite/g++.old-deja/g++.mike/p4246.C
index 1eb6668e969..61e680d3728 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/p4246.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/p4246.C
@@ -1,48 +1,5 @@
-// prms-id: 4246
-
-extern "C" void abort ();
-int num_d;
-
-class A
-{
- public:
- A() { }
- virtual ~A() { }
- virtual id() { }
-};
-
-class B
-{
- public:
- B() { }
- virtual ~B() { }
- virtual id() { }
-};
-
-class C : public A, public B
-{
- public:
- C() { }
- virtual ~C() { }
- id() { abort(); }
-};
-
-class D : public C
-{
- public:
- D() { ++num_d; }
- virtual ~D() { -- num_d; }
- id() { }
-};
-
-main()
-{
- D* dp2 = new D;
- ((B*)dp2)->id();
- delete (B*) dp2;
-
- B* bp1 = new D;
- bp1->id();
- delete bp1;
- return num_d != 0;
-}
+ virtual void id() { }
+ virtual void id() { }
+ void id() { abort(); }
+ void id() { }
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/p4511.C b/gcc/testsuite/g++.old-deja/g++.mike/p4511.C
index a3c83105bb9..b3b753c1a91 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/p4511.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/p4511.C
@@ -1,33 +1 @@
-// prms-id: 4511
-
-int bad;
-
-class A {
-public:
- virtual void dummy (){};
-};
-
-class B {
-public:
- virtual void f(void) = 0;
-};
-
-class C : public A, public B {
-public:
- void f(void) { bad=1; };
-};
-
-class D : public C {
-public:
- void f(void) { };
-};
-
-class E : public D { };
-
-main() {
- E e;
- e.f();
- E * ep = &e;
- ep->f();
- return bad;
-}
+int main() {
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/p4619.C b/gcc/testsuite/g++.old-deja/g++.mike/p4619.C
index b401d7dda17..b3b753c1a91 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/p4619.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/p4619.C
@@ -1,10 +1 @@
-// Build don't link:
-// prms-id: 4619
-
-main() {
- int i = 3;
- int (*p)[10] = new int [20][10];
- int (*p1)[5][7][13][10] = new int [i][5][7][13][10];
- delete [] p1;
- delete [] p;
-}
+int main() {
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/p4623.C b/gcc/testsuite/g++.old-deja/g++.mike/p4623.C
index c96388de6d2..b3b753c1a91 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/p4623.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/p4623.C
@@ -1,35 +1 @@
-// prms-id: 4623
-
-class base {
-public:
- int b_data;
- base( int i=0 ) { b_data = i; }
- void b_print() { }
-};
-
-class base1: virtual public base {
-public:
- int b1_data;
- base1( int i = 0 ) { b1_data = i; b_data++; }
- void b1_print() { }
-};
-
-class base2: virtual public base {
-public:
- int b2_data;
- base2( int i = 0 ) { b2_data = i; b_data++; }
- void b2_print() { }
-};
-
-class base3: public base {};
-
-class derived: public base3, public base1, public base2 {
-public:
- int d_data;
- derived( int i ) { d_data = i; base3::b_data++; }
- void d_print() { }
-};
-
-main() {
- derived d(1); d.d_print(); return 0;
-}
+int main() {
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/p4693.C b/gcc/testsuite/g++.old-deja/g++.mike/p4693.C
index 09e1333933e..b3b753c1a91 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/p4693.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/p4693.C
@@ -1,24 +1 @@
-// Build don't link:
-// prms-id: 4693
-
-class a {
-public:
- virtual ~a();
-};
-
-class b {
-public:
- virtual void set_var() = 0;
-};
-
-class c : public b, public a { };
-
-class d : public c {
-public:
- void set_var() { }
-};
-
-main() {
- d * test;
- test = new d;
-}
+int main() {
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/p4736b.C b/gcc/testsuite/g++.old-deja/g++.mike/p4736b.C
index 19d655c6f09..b3b753c1a91 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/p4736b.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/p4736b.C
@@ -1,48 +1 @@
-// prms-id: 4736
-
-class Rep {
-public:
- virtual int foo() { return 1; }
-};
-
-class Rep_1 : public Rep {
-};
-
-class VBaseMain {
-public:
- virtual int foo() { return 2; }
-};
-
-class OtherVBase {
-public:
- virtual int foo() { return 3; }
-};
-
-class Rep_2 : public Rep {
-};
-
-class DVBase : public VBaseMain, public Rep_2, public OtherVBase {
-public:
- virtual int foo() { return 4; }
-};
-
-class Main : public Rep_1, virtual public DVBase {
-public:
- virtual int foo() { return 5; }
-};
-
-main() {
- Main m;
- if (m.foo() != 5)
- return 1;
- if (((Rep*)(Rep_1*)&m)->foo() != 5)
- return 2;
- if (((DVBase*)&m)->foo() != 5)
- return 3;
- if (((VBaseMain*)(DVBase*)&m)->foo() != 5)
- return 4;
- if (((Rep*)(Rep_2*)(DVBase*)&m)->foo() != 5)
- return 5;
- if (((OtherVBase*)(DVBase*)&m)->foo() != 5)
- return 6;
-}
+int main() {
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/p4736c.C b/gcc/testsuite/g++.old-deja/g++.mike/p4736c.C
index de5e4b6962c..b3b753c1a91 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/p4736c.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/p4736c.C
@@ -1,62 +1 @@
-// prms-id: 4736
-
-int did_fail;
-
-class Rep {
-public:
- virtual ~Rep() { }
-};
-
-class Rep_1 : public Rep {
-};
-
-class VBaseMain {
-public:
- virtual ~VBaseMain() { }
-};
-
-class OtherVBase {
-public:
- virtual ~OtherVBase() { }
-};
-
-class Rep_2 : public Rep {
-};
-
-class DVBase : public VBaseMain, public Rep_2, public OtherVBase {
-public:
- virtual ~DVBase() { }
-};
-
-class Main : public Rep_1, virtual public DVBase {
-public:
- virtual ~Main() { did_fail = 0; }
-};
-
-main() {
- Main* m;
- did_fail = 1;
- delete new Main;
- if (did_fail)
- return 1;
- did_fail = 1;
- delete (Rep*)(Rep_1*)new Main;
- if (did_fail)
- return 2;
- did_fail = 1;
- delete (DVBase*)new Main;
- if (did_fail)
- return 3;
- did_fail = 1;
- delete (VBaseMain*)(DVBase*)new Main;
- if (did_fail)
- return 4;
- did_fail = 1;
- delete (Rep*)(Rep_2*)(DVBase*)new Main;
- if (did_fail)
- return 5;
- did_fail = 1;
- delete (OtherVBase*)(DVBase*)new Main;
- if (did_fail)
- return 6;
-}
+int main() {
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/p5469.C b/gcc/testsuite/g++.old-deja/g++.mike/p5469.C
index 3f5029dc3ce..b3b753c1a91 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/p5469.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/p5469.C
@@ -1,21 +1 @@
-// prms-id: 5469
-
-int count;
-
-class A {
- A();
- A(const A&);
-public:
- A(int) { ++count; }
- ~A() { --count; }
- int operator== (const A& r) { return 0; }
-};
-
-main() {
- {
- A a (1);
- if (a == 2 && a == 1)
- ;
- }
- return count;
-}
+int main() {
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/p5469a.C b/gcc/testsuite/g++.old-deja/g++.mike/p5469a.C
index efcd2f4b652..b3b753c1a91 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/p5469a.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/p5469a.C
@@ -1,21 +1 @@
-// prms-id: 5469
-
-int count;
-
-class A {
- A();
- A(const A&);
-public:
- A(int) { ++count; }
- ~A() { --count; }
- int operator== (const A& r) { return 1; }
-};
-
-main() {
- {
- A a (1);
- if (a == 2 || a == 1)
- ;
- }
- return count;
-}
+int main() {
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/p5571.C b/gcc/testsuite/g++.old-deja/g++.mike/p5571.C
index d9a3a471dd8..1cc419954e9 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/p5571.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/p5571.C
@@ -1,70 +1,2 @@
-// prms-id: 5571
-
-int err = 0;
-void *vp = 0;
-
-class ParentOne {
-public:
- ParentOne() {};
-#ifdef MAKE_WORK
- virtual ~ParentOne() {};
-#endif
-private:
- char SomeData[101];
-};
-
-class ParentTwo {
-public:
- ParentTwo() {};
- virtual ~ParentTwo() {};
-private:
- int MoreData[12];
- virtual foo() { return 0; }
-};
-
-struct Child : public ParentOne, public ParentTwo {
- int ChildsToy;
- virtual void PrintThis() = 0;
-};
-
-struct Student : public Child {
- int StudentsBook;
- void PrintThis() {
- if (vp == 0)
- vp = (void *)this;
- else
- {
- if (vp != (void *)this)
- ++err;
- }
- }
- void LocalPrintThis() {
- if (vp == 0)
- vp = (void *)this;
- else
- {
- if (vp != (void *)this)
- ++err;
- }
- PrintThis();
- }
- void ForcedPrintThis() {
- if (vp == 0)
- vp = (void *)this;
- else
- {
- if (vp != (void *)this)
- ++err;
- }
- Student::PrintThis();
- }
-};
-
-main() {
- Student o;
- o.LocalPrintThis();
- o.ForcedPrintThis();
- Child* pX = &o;
- pX->PrintThis();
- return err;
-}
+ virtual int foo() { return 0; }
+int main() {
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/p5673.C b/gcc/testsuite/g++.old-deja/g++.mike/p5673.C
index 8d29191861e..b3b753c1a91 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/p5673.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/p5673.C
@@ -1,20 +1 @@
-// prms-id: 5673
-
-class A {
-public:
- operator int () {
- return 7;
- }
- ~A();
-};
-
-int foo() {
- return A();
-}
-
-main() {
- return foo() != 7;
-}
-
-A::~A() {
-}
+int main() {
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/p5840.C b/gcc/testsuite/g++.old-deja/g++.mike/p5840.C
index 53b9510102f..34dd37df6c3 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/p5840.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/p5840.C
@@ -28,7 +28,7 @@ Derived a;
/* Bar<Derived, &Signal::Name> dispatcher1; */
Bar<Derived, &Derived::Name> dispatcher2;
-main() {
+int main() {
/* int i1 = dispatcher1.value(&a); */
int i2 = dispatcher2.value(&a);
return /* i1 != 1 || */ i2 != 2;
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/p6058.C b/gcc/testsuite/g++.old-deja/g++.mike/p6058.C
index aa78b7ff63d..91ebd22bac2 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/p6058.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/p6058.C
@@ -1,18 +1 @@
-// Build don't link:
-// Special g++ Options: -fexceptions -pedantic-errors
-// prms-id: 6058
-
-void bar(struct s1 { } a) { (void)a; } // ERROR -
-
-struct s2*fooey() // ERROR - XFAIL *-*-*
-{
- try {
- static_cast<struct s3 { } *>(0); // ERROR -
- const_cast<struct s4 { } *>((s4*)0); // ERROR -
- reinterpret_cast<struct s5 { } *>((s3*)0); // ERROR -
- dynamic_cast<struct s6 { } *>((s6*)0); // ERROR -
- (struct s7 { } *)(int*)0xffedec; // ERROR -
- } catch (struct s8 { } s) { // ERROR -
- }
- return 0;
-}
+struct s2*fooey()
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/p6311.C b/gcc/testsuite/g++.old-deja/g++.mike/p6311.C
index 12d3cfc6169..b3b753c1a91 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/p6311.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/p6311.C
@@ -1,16 +1 @@
-// prms-id: 6311
-
-struct Foo {
- int member;
-} a = { 42 }, *ptra = &a;
-
-int Foo::*pmd = &Foo::member;
-
-main() {
- if (pmd == 0)
- return 1;
- if (a.*pmd != 42)
- return 2;
- if (ptra->*pmd != 42)
- return 3;
-}
+int main() {
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/p658.C b/gcc/testsuite/g++.old-deja/g++.mike/p658.C
index 614f7e933d1..14658f04956 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/p658.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/p658.C
@@ -35,7 +35,7 @@ private:
char _c;
};
-main()
+int main()
{
Char r, s;
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/p6927.C b/gcc/testsuite/g++.old-deja/g++.mike/p6927.C
index 827ef29b24d..b3b753c1a91 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/p6927.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/p6927.C
@@ -1,16 +1 @@
-// prms-id: 6927
-
-class Object {
-public:
- Object();
- int Value;
-};
-
-Object::Object() : Value(-1) { }
-
-Object *pArr = new Object[2];
-
-main() {
- if (pArr[0].Value != -1 || pArr[1].Value != -1)
- return 1;
-}
+int main() {
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/p701.C b/gcc/testsuite/g++.old-deja/g++.mike/p701.C
index 4acf17038d4..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/p701.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/p701.C
@@ -1,34 +1 @@
-// Build don't link:
-// prms-id: 701
-
-extern "C"
-{
- int printf(const char *, ...);
-};
-
-
-void Munge(int& x)
-{ // ERROR - referenced below
- x = 2;
-}
-
-
-class A
-{
- public:
- int i;
- A(int x) : i(x) {}
- void Safe() const;
-};
-
-void
-A::Safe() const
-{
- Munge(i); // ERROR - should not be able to modify a const object
-}
-
-main()
-{
- const A a(1);
- a.Safe();
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/p710.C b/gcc/testsuite/g++.old-deja/g++.mike/p710.C
index c6ab3b1d902..62dffe9ff8e 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/p710.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/p710.C
@@ -35,7 +35,7 @@ class B
void operator delete(void*){}
};
-main()
+int main()
{
B* p = new B;
delete p;
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/p7325.C b/gcc/testsuite/g++.old-deja/g++.mike/p7325.C
index 9cf4604daab..e6d76f5321e 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/p7325.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/p7325.C
@@ -48,7 +48,7 @@ void g ()
A::match_this = 0;
}
-main() {
+int main() {
f();
g();
return fail;
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/p755.C b/gcc/testsuite/g++.old-deja/g++.mike/p755.C
index 9dbebff5485..256c985e271 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/p755.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/p755.C
@@ -10,7 +10,7 @@ void* operator new(size_t sz) throw (std::bad_alloc) {
return p;
}
-main () {
+int main () {
int* i = new int;
delete i;
return 1;
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/p755a.C b/gcc/testsuite/g++.old-deja/g++.mike/p755a.C
index 9f496c1e337..765014bc66d 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/p755a.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/p755a.C
@@ -1,14 +1 @@
-// It checks to see if you can define your own global delete operator.
-// prms-id: 755
-
-extern "C" void exit(int);
-
-void operator delete(void *p) throw() {
- exit(0);
-}
-
-main () {
- int* i = new int;
- delete i;
- return 1;
-}
+int main () {
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/p7626.C b/gcc/testsuite/g++.old-deja/g++.mike/p7626.C
index 61636d61fdb..b3b753c1a91 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/p7626.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/p7626.C
@@ -1,43 +1 @@
-// Build don't link:
-// prms-id: 7626
-
-int fail;
-
-typedef unsigned int UINT;
-
-class CObject{};
-
-class CCmdTarget : public CObject {
-};
-
-typedef void (CCmdTarget::*AFX_PMSG)(void);
-
-struct AFX_MSGMAP_ENTRY {
- AFX_PMSG pfn;
-};
-
-class CWnd : public CCmdTarget {
-public:
- void OnMyMsg() { fail = 1; } // If this one is called, something is wrong.
- static AFX_MSGMAP_ENTRY _messageEntries[];
-};
-
-typedef void (CWnd::*AFX_PMSGW)(void);
-
-class CDialog : public CWnd
-{
-public:
- void OnMyMsg() { }
- static AFX_MSGMAP_ENTRY _messageEntries[];
-};
-
-AFX_MSGMAP_ENTRY CDialog ::_messageEntries[] = {
- { (AFX_PMSG)(AFX_PMSGW)(void (CWnd::*)())&CDialog::OnMyMsg },
- { (AFX_PMSG)0 }
-};
-
-main() {
- CDialog d;
- (d.*((CDialog::_messageEntries)[0]).pfn)(); // This should call CDialog::OnMyMsg
- return fail;
-}
+int main() {
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/p7651.C b/gcc/testsuite/g++.old-deja/g++.mike/p7651.C
index a295a8971af..b3b753c1a91 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/p7651.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/p7651.C
@@ -1,25 +1 @@
-// prms-id: 7651
-
-int fail = 0;
-
-class Foo {
-public:
- Foo(double i) : data(i) { if (data != 1.0) fail = 1; }
- ~Foo() { if (data != 1.0) fail = 1; }
-private:
- volatile double data;
-};
-
-int DingDong(double A) {
- volatile Foo a(A);
-
- if ( A != 0.0 ) {
- return 1;
- }
- return 0;
-}
-
-
-main() {
- DingDong(1.0);
-}
+int main() {
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/p783.C b/gcc/testsuite/g++.old-deja/g++.mike/p783.C
index ce22a7c14b5..a9ac84ed14b 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/p783.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/p783.C
@@ -1,15 +1 @@
-// prms-id: 783
-
-extern "C" void printf (char *, ...);
-
-class C {
-public:
- C() { }
- ~C() { }
-};
-
-main(int argc, char**argv) {
- C c,d;
- c = (argc&1) ? C() : d;
- return 0;
-}
+int main(int argc, char**argv) {
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/p783a.C b/gcc/testsuite/g++.old-deja/g++.mike/p783a.C
index 1883fc7ded2..a9ac84ed14b 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/p783a.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/p783a.C
@@ -1,26 +1 @@
-// Copying into an object directly is a lose according to tiemann.
-// Deleting an object many times is a lose.
-// prms-id: 783
-
-extern "C" void printf (char *, ...);
-extern "C" void exit (int);
-
-class C {
- int i;
-public:
- C() {
- i = 1;
- }
- ~C() {
- if (i != 1) {
- exit(1);
- }
- i = 0;
- }
-};
-
-main(int argc, char**argv) {
- C c;
- c = C();
- return 0;
-}
+int main(int argc, char**argv) {
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/p783b.C b/gcc/testsuite/g++.old-deja/g++.mike/p783b.C
index f4170bc21cc..a9ac84ed14b 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/p783b.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/p783b.C
@@ -1,37 +1 @@
-// This one check for objects being destroyed twice. The bug it is
-// looking for is the extra dtor call on C() even though it is never
-// built.
-// prms-id: 783
-
-extern "C" void printf (char *, ...);
-extern "C" void exit (int);
-
-class C {
- int i;
-public:
-// C() {printf ("C ctor at %x\n", this);}
-// ~C() {printf ("C dtor at %x\n", this);}
- C() {
- i = 1;
- }
- ~C() {
- if (i != 1) {
- exit(1);
- }
- i = 0;
- }
-};
-
-C g;
-
-C func() {
- return g;
-}
-
-main(int argc, char**argv) {
- C c,d;
-// printf ("\n");
- c = (argc != 1) ? C() : d;
-// printf ("\n");
- return 0;
-}
+int main(int argc, char**argv) {
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/p784.C b/gcc/testsuite/g++.old-deja/g++.mike/p784.C
index 6af675df593..ce6104977f1 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/p784.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/p784.C
@@ -616,7 +616,7 @@ class ostream : public ios
void do_osfx();
public:
ostream();
- ostream(streambuf* sb, ostream* tied=((void *)0) );
+ ostream(streambuf* sb, ostream* tied=(__null) );
~ostream();
int opfx() { if (!good()) return 0; if (_tie) _tie->flush(); return 1; }
@@ -661,7 +661,7 @@ class istream : public ios
size_t _gcount;
public:
istream();
- istream(streambuf* sb, ostream*tied=((void *)0) );
+ istream(streambuf* sb, ostream*tied=(__null) );
~istream();
streambuf* istreambuf() const { return _strbuf; }
istream& get(char& c);
@@ -2238,7 +2238,7 @@ class strstreambuf : public streambuf {
public:
strstreambuf();
strstreambuf(int initial);
- strstreambuf(char *ptr, int size, char *pstart = ((void *)0) );
+ strstreambuf(char *ptr, int size, char *pstart = (__null) );
~strstreambuf();
int frozen() { return _frozen; }
void freeze(int n=1) { _frozen = n != 0; }
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/p786.C b/gcc/testsuite/g++.old-deja/g++.mike/p786.C
index 258c36511de..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/p786.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/p786.C
@@ -1,35 +1 @@
-// prms-id: 786
-
-extern "C" void printf (char *, ...);
-extern "C" void exit(int);
-class C
- {
- int a;
-public:
- C() {a = 1;}
- };
-
-void func(const C& a, C& b)
-{
- printf ("in const func\n");
- exit(1);
-}
-
-void func(C& a, C& b)
-{
- printf ("in non-const func\n");
-}
-
-void testit(const C& a, C& b)
-{
- func(a,b);
-}
-
-main()
-{
- C a;
- C b;
-
- func(a,b);
- return 0;
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/p7865.C b/gcc/testsuite/g++.old-deja/g++.mike/p7865.C
index d9a611889b1..b3b753c1a91 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/p7865.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/p7865.C
@@ -1,28 +1 @@
-// prms-id: 7865
-
-int count;
-
-struct A {
- A() { ++count; }
- ~A() { --count; }
-};
-
-int foo() { return 1; }
-
-int bar()
-{
- A a;
- for (;;) {
- A b;
- if (foo())
- return 0;
- if (foo())
- return 0;
- }
- return 0;
-}
-
-main() {
- bar();
- return count;
-}
+int main() {
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/p7868.C b/gcc/testsuite/g++.old-deja/g++.mike/p7868.C
index d8ce95d3c66..cde795445b9 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/p7868.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/p7868.C
@@ -1,21 +1,2 @@
-// Build don't link:
-// prms-id: 7868
-
-struct DIAGTYP {
-};
-struct DIAGTYP1 {
- struct DIAGTYP;
- void bar() { new struct DIAGTYP; } // ERROR - undefined
- void foo() { new struct DIAGTYP1; }
-};
-
-int main () {
- struct DIAGTYP;
- struct DIAGTYP *lerror_desc;
- lerror_desc= new struct DIAGTYP; // ERROR - undefined
-}
-
-void foo () {
- struct DIAGTYP *lerror_desc;
- lerror_desc= new struct DIAGTYP;
-}
+ struct DIAGTYP; // ERROR - forward declaration
+ struct DIAGTYP; // ERROR - forward declaration
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/p789.C b/gcc/testsuite/g++.old-deja/g++.mike/p789.C
index 09815989d5b..fca7aa3a92f 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/p789.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/p789.C
@@ -1,28 +1 @@
-// prms-id: 789
-
-extern "C" void printf (char *, ...);
-struct foo
-{
- static int count;
- virtual void print (int i, int j) { printf ("foo[%d][%d] = %d\n", i, j, x); }
- int x;
- foo () { x = count++; }
-};
-int foo::count;
-struct bar : virtual public foo
-{
- virtual void print (int i, int j) { printf ("bar[%d][%d] = %d\n", i, j, x); }
-};
-
-// bar array[3][3];
-foo array[3][3];
-
-main ()
-{
- for (int i = 0; i < 3; i++)
- for (int j = 0; j < 3; j++) {
-// printf("&a[%d][%d] = %x\n", i, j, (void *)&array[i][j]);
- array[i][j].print (i, j);
- }
- return 0;
-}
+int main ()
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/p789a.C b/gcc/testsuite/g++.old-deja/g++.mike/p789a.C
index 9086ff54cfe..fca7aa3a92f 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/p789a.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/p789a.C
@@ -1,43 +1 @@
-// global and local multidimensional array objects are not getting
-// constructors called on any dimension, other than the first. Also,
-// the destructors are not being called. Seems odd, they probably
-// used to work. :-(
-// prms-id: 789
-
-extern "C" void printf (char *, ...);
-struct foo
-{
- static int count;
- void print (int i, int j) { printf ("foo[%d][%d] = %d\n", i, j, x); }
- int x;
- foo () {
- x = count++;
- printf("this %d = %x\n", x, (void *)this);
- }
- virtual ~foo () {
- printf("this %d = %x\n", x, (void *)this);
- --count;
- }
-};
-int foo::count;
-
-
-main ()
-{
- {
- foo array[3][3];
- for (int i = 0; i < 3; i++)
- {
- for (int j = 0; j < 3; j++)
- {
- printf("&a[%d][%d] = %x\n", i, j, (void *)&array[i][j]);
- }
- }
- // The count should be nine, if not, fail the test.
- if (foo::count != 9)
- return 1;
- }
- if (foo::count != 0)
- return 1;
- return 0;
-}
+int main ()
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/p8039.C b/gcc/testsuite/g++.old-deja/g++.mike/p8039.C
index 73defeccd97..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/p8039.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/p8039.C
@@ -1,14 +1 @@
-// prms-id: 8039
-
-class C {
-public:
- int func ();
-};
-
-extern void bar(int*);
-
-main()
-{
- int (C::*mfp)() = &C::func;
- bar((int*)mfp); // ERROR - no clear semantics
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/p807.C b/gcc/testsuite/g++.old-deja/g++.mike/p807.C
index 59df08e5149..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/p807.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/p807.C
@@ -1,34 +1 @@
-// prms-id: 807
-
-extern "C" int printf(const char*, ...);
-
-class B;
-
-class AX
-{
- protected:
- int x;
-
- public:
- operator B();
-};
-
-
-class B
-{
- private:
- int x;
- public:
- B(const AX&);
-};
-
-
-int foo(B& b); // ERROR - referenced below
-
-
-main()
-{
- AX a;
- foo(a); // ERROR - Ambiguous B(a) or a.operator B() // See ARM 12.3.2
-
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/p8155.C b/gcc/testsuite/g++.old-deja/g++.mike/p8155.C
index f62291062f1..bf854151126 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/p8155.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/p8155.C
@@ -1,147 +1 @@
-// prms-id: 8155
-
-int fail = 1;
-
-class CMainWindow;
-class CFrameWnd;
-class CWnd;
-class CCmdTarget;
-
-typedef void (CCmdTarget::*AFX_PMSG)( void);
-typedef void (CWnd::*AFX_PMSGW)( void);
-
-struct AFX_MSGMAP_ENTRY {
- unsigned int nMessage;
- AFX_PMSG pfn;
-};
-
-struct AFX_MSGMAP {
- const AFX_MSGMAP* pBaseMap;
- const AFX_MSGMAP_ENTRY* lpEntries;
-};
-
-class CCmdTarget {
-public:
- CCmdTarget();
-private:
- static AFX_MSGMAP_ENTRY _messageEntries[];
-protected:
- static const AFX_MSGMAP messageMap;
- virtual const AFX_MSGMAP* GetMessageMap() const;
-};
-
-const AFX_MSGMAP CCmdTarget::messageMap = {
- 0, &CCmdTarget::_messageEntries[0]
-};
-
-const AFX_MSGMAP* CCmdTarget::GetMessageMap() const {
- return &CCmdTarget::messageMap;
-}
-
-AFX_MSGMAP_ENTRY CCmdTarget::_messageEntries[] =
-{
- { 0, 0 }
-};
-
-CCmdTarget :: CCmdTarget() { }
-
-class CWnd : public CCmdTarget {
-public:
- CWnd();
-
-protected:
- void OnPaint();
-private:
- static AFX_MSGMAP_ENTRY _messageEntries[];
-protected:
- static const AFX_MSGMAP messageMap;
- virtual const AFX_MSGMAP* GetMessageMap() const;
-};
-
-CWnd :: CWnd() {
-}
-
-void CWnd :: OnPaint() {
-}
-
-const AFX_MSGMAP* CWnd ::GetMessageMap() const {
- return & CWnd ::messageMap;
-}
-const AFX_MSGMAP CWnd ::messageMap = {
- & CCmdTarget ::messageMap, & CWnd ::_messageEntries[0]
- };
-AFX_MSGMAP_ENTRY CWnd ::_messageEntries[] = {
- {0, (AFX_PMSG)0 } };
-
-class CFrameWnd : public CWnd {
-public:
- CFrameWnd();
-protected:
-private:
- static AFX_MSGMAP_ENTRY _messageEntries[];
-protected:
- static const AFX_MSGMAP messageMap;
- virtual const AFX_MSGMAP* GetMessageMap() const;
-};
-
-CFrameWnd :: CFrameWnd() { }
-
-const AFX_MSGMAP* CFrameWnd ::GetMessageMap() const {
- return & CFrameWnd ::messageMap;
-}
-const AFX_MSGMAP CFrameWnd ::messageMap = {
- & CWnd ::messageMap, & CFrameWnd ::_messageEntries[0]
- };
-AFX_MSGMAP_ENTRY CFrameWnd ::_messageEntries[] = {
- {0, (AFX_PMSG)0 } };
-
-class CMainWindow : public CFrameWnd {
-public:
- CMainWindow();
- void OnPaint();
- void callProc();
-private:
- static AFX_MSGMAP_ENTRY _messageEntries[];
-protected:
- static const AFX_MSGMAP messageMap;
- virtual const AFX_MSGMAP* GetMessageMap() const;
-};
-
-CMainWindow :: CMainWindow()
-{
-}
-void CMainWindow :: OnPaint()
-{
- fail = 0;
-}
-
-void CMainWindow :: callProc()
-{
- const AFX_MSGMAP* pMessageMap;
- const AFX_MSGMAP_ENTRY *lpEntry;
-
- pMessageMap = GetMessageMap();
- lpEntry = pMessageMap->lpEntries;
-
- if( lpEntry->nMessage == 100) {
- (this->*lpEntry->pfn)();
- }
-}
-
-const AFX_MSGMAP* CMainWindow ::GetMessageMap() const {
- return & CMainWindow ::messageMap;
-}
-const AFX_MSGMAP CMainWindow ::messageMap = {
- & CFrameWnd ::messageMap, & CMainWindow ::_messageEntries[0]
- };
-AFX_MSGMAP_ENTRY CMainWindow ::_messageEntries[] = {
- { 100, (AFX_PMSG)(AFX_PMSGW)(void (CWnd::*)(void))&CMainWindow::OnPaint },
- {0, (AFX_PMSG)0 }
-};
-
-main( int argc, char **argv) {
- CMainWindow myWindow;
-
- myWindow.callProc();
- return fail;
-}
+int main( int argc, char **argv) {
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/p8460.C b/gcc/testsuite/g++.old-deja/g++.mike/p8460.C
index 542921c5738..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/p8460.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/p8460.C
@@ -1,17 +1 @@
-// Build don't link:
-// prms-id: 8460
-
-class A {
-public:
- A();
- A(int) { }
- A(const A&) { }
-private:
-};
-
-main()
-{
- A a;
-
- a.A(1); // ERROR - cannot find name this way
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/p8483.C b/gcc/testsuite/g++.old-deja/g++.mike/p8483.C
index b04901844fa..b3b753c1a91 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/p8483.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/p8483.C
@@ -1,35 +1 @@
-// prms-id: 8483
-
-int count;
-
-class A {
-public:
- A() { ++count; }
- ~A() { }
-};
-
-class B {
-private:
- A b[2];
-};
-
-class C {
-public:
-private:
- A c[2][2];
-};
-
-class D {
-public:
-private:
- A d[2][2][2];
-};
-
-main() {
- { A a; }
- { B b; }
- { C c; }
- { D d; }
- if (count != 15)
- return 1;
-}
+int main() {
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/p8785.C b/gcc/testsuite/g++.old-deja/g++.mike/p8785.C
index 9c977fdcd30..2ab5fcb524a 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/p8785.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/p8785.C
@@ -1,25 +1,2 @@
-// Build don't link:
-// prms-id: 8785
-
-class Outer {
-private:
- int x;
-public:
- struct Inner {
- int y;
- void f( Outer * p, int i) {
- p->x = i; // ERROR -
- };
- void f( Outer & p) {
- p.x = y; // ERROR -
- };
- };
-};
-
-main() {
- Outer::Inner A;
- Outer Thing;
-
- A.f(Thing);
- A.f(&Thing,2);
-}
+ int x; // ERROR - private
+int main() {
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/p8804.C b/gcc/testsuite/g++.old-deja/g++.mike/p8804.C
index e46a4c677ec..b3b753c1a91 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/p8804.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/p8804.C
@@ -1,18 +1 @@
-// prms-id: 8804
-
-extern "C" int printf (const char *, ...);
-
-struct Fails {
- int i;
- union {
- union {
- int c;
- };
- };
-};
-
-Fails d;
-
-main() {
- return &d.i == &d.c;
-}
+int main() {
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/pmf1.C b/gcc/testsuite/g++.old-deja/g++.mike/pmf1.C
index 5b2dde87543..29b55ae70ac 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/pmf1.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/pmf1.C
@@ -1,90 +1 @@
-// extern "C" printf(const char *, ...);
-
-class X
-{
-public:
- int a;
- int f(int);
-};
-
-class Y
-{
-public:
- int b;
- int c;
- int g(int);
-};
-
-class MD : public X, public Y
-{
-public:
- int c;
- int hf(int);
-};
-
-int MD::* pmi0 = &MD::a;
-int MD::* pmi1 = &MD::b;
-int MD::* pmi2 = &MD::c;
-
-int (MD::* pmf0)(int) = &MD::f;
-int (MD::* pmf1)(int) = &MD::g;
-int (MD::* pmf2)(int) = &MD::hf;
-
-main()
-{
- MD obj;
- int fail = 0;
-
- obj.a = 1;
- obj.b = 2;
- obj.c = 3;
-
- obj.*pmi0 = 7;
- obj.*pmi1 = 8;
- obj.*pmi2 = 9;
-
- fail += (obj.*pmf0)(7);
- fail += (obj.*pmf1)(8);
- fail += (obj.*pmf2)(9);
-
-#if 0
- if (fail != 0)
- printf ("failed %d tests\n", fail);
- else
- printf ("passed\n");
-
- printf ("sizeof(X) = %d, sizeof(Y) = %d, sizeof(MD) = %d\n",
- sizeof(X), sizeof(Y), sizeof(MD));
-#endif
- return fail;
-}
-
-int X::f(int v)
-{
- if (v != a)
- {
-// printf ("failed in X::f, a = %d\n", a);
- return 1;
- }
- return 0;
-}
-
-int Y::g(int v)
-{
- if (v != b)
- {
-// printf ("failed in Y::g, b = %d\n", b);
- return 1;
- }
- return 0;
-}
-
-int MD::hf(int v)
-{
- if (v != c)
- {
-// printf ("failed in MD::hf, c = %d\n", c);
- return 1;
- }
- return 0;
-}
+int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/pmf2.C b/gcc/testsuite/g++.old-deja/g++.mike/pmf2.C
index 2f1bec51e95..b3b753c1a91 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/pmf2.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/pmf2.C
@@ -1,54 +1 @@
-extern "C" int printf(const char *, ...);
-
-class A_table {
- int c;
-public:
- A_table() { c = 3;}
- virtual void func2(int &item) { printf("func2(%d,) c=%d\n",item,c);}
-};
-
-class B_table : private A_table {
- typedef void (B_table::* B_ti_fn) (int &item);
-public:
- B_table() { j = 0x4321;}
- virtual void call_fn_fn1(int &item, void *pfn1);
- void func1(int &item) { printf("func1(%d)\n",item);}
- virtual void func2(int &item) { printf("func2(%d) j=%d\n",item,j);}
- int j;
-};
-
-class foo : public A_table {
-public:
- int i;
- virtual ~foo();
- virtual void func2(int &item) { printf("func2(%d) i=%d\n",item,i);}
-};
-foo::~foo() { i = 0;}
-
-class bar :public foo,public B_table {
-public:
- int w;
- virtual ~bar();
- virtual void func2(int &item) { printf("func2(%d) w=%d\n",item,w);}
-};
-bar::~bar() { w = 0;}
-
-void B_table::call_fn_fn1(int &item, void *pfn1) {
- (this->*(*(B_ti_fn*)pfn1))(item);
-}
-
-B_table b;
-bar jar;
-
-main() {
- printf("ptr to B_table=%x, ptr to A_table=%x\n",&b,(A_table*)&b);
- B_table::B_ti_fn z = &B_table::func1;
- int j = 1;
- jar.call_fn_fn1(j,(void *)&z);
- j++;
- z = &B_table::func2;
- b.call_fn_fn1(j,(void *)&z);
- j++;
- jar.call_fn_fn1(j,(void *)&z);
- return 0;
-}
+int main() {
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/pmf3.C b/gcc/testsuite/g++.old-deja/g++.mike/pmf3.C
index 24753eb1f9a..76fa1ef28e1 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/pmf3.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/pmf3.C
@@ -1,19 +1,3 @@
-struct Fooey {
- void f(char* pX);
- void f(int in);
- void f(float fx);
- void h(double dx);
-};
-
-void Fooey::f(char*) { }
-void Fooey::f(int) { }
-void Fooey::f(float) { }
-void Fooey::h(double zahl) { }
-
-int main() {
- Fooey Blah;
- void (Fooey::*pointer)(double);
- pointer = &Fooey::f; // ERROR - don't call Fooey::h
- (Blah.*pointer)(42.5);
- return 0;
-}
+void Fooey::f(char*) { } // ERROR - candidate
+void Fooey::f(int) { } // ERROR - candidate
+void Fooey::f(float) { } // ERROR - candidate
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/pmf6.C b/gcc/testsuite/g++.old-deja/g++.mike/pmf6.C
index c5327070617..0833700f387 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/pmf6.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/pmf6.C
@@ -1,12 +1 @@
-// Special g++ Options:
-
-class S {
-public:
- void (S::*pmf)();
- void foo() {
- pmf(); // WARNING -
- }
- static foo1(S* sp) {
- (sp->pmf)(); // ERROR -
- }
-};
+ static void foo1(S* sp) {
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/rtti2.C b/gcc/testsuite/g++.old-deja/g++.mike/rtti2.C
index bf08ede33fd..b3b753c1a91 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/rtti2.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/rtti2.C
@@ -1,5 +1 @@
-#include <typeinfo>
-
-main() {
- typeid(bool);
-}
+int main() {
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/scast1.C b/gcc/testsuite/g++.old-deja/g++.mike/scast1.C
index dbc5efc4e40..b3b753c1a91 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/scast1.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/scast1.C
@@ -1,7 +1 @@
-class A {};
-class C {};
-
-main() {
- A* a = 0;
- C* c = static_cast<C*>(a); // ERROR - bad static cast
-}
+int main() {
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/temp.C b/gcc/testsuite/g++.old-deja/g++.mike/temp.C
index 8ca31f345b3..b3b753c1a91 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/temp.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/temp.C
@@ -1,31 +1 @@
-extern "C" int printf(const char *, ...);
-extern "C" const char *getenv(const char *);
-
-class T {
- int i;
-public:
- T() {
- i = 1;
- printf("T() at %x\n", this);
- }
- T(const T& o) {
- i = o.i;
- printf("T(const T&) at %x <-- %x\n", this, &o);
- }
- T operator +(const T& o) {
- T r;
- r.i = this->i + o.i;
- return r;
- }
- operator int () {
- return i;
- }
- ~T() { printf("~T() at %x\n", this); }
-} s, b;
-
-int foo() { return getenv("TEST") == 0; }
-
-main() {
- int i = foo() ? s+b : s;
- return i != 2;
-}
+int main() {
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/virt4.C b/gcc/testsuite/g++.old-deja/g++.mike/virt4.C
index 989701833b6..b3f1a9e8871 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/virt4.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/virt4.C
@@ -1,25 +1,2 @@
-void Foo () {}
+// Special g++ Options:
-class B {
-public:
- virtual void foo() = 0;
-};
-
-class D: virtual public B {
-public:
- void foo() { Foo(); }
-};
-
-class D1: public D {};
-
-class D2: public D {};
-
-class D1_2: public D1, public D2 {
-public:
- void foo() { D1::foo(); D2::foo(); }
-};
-
-main() {
- D1_2 h;
- h.foo();
-}
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/virt5.C b/gcc/testsuite/g++.old-deja/g++.mike/virt5.C
index a9040c95879..b3b753c1a91 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/virt5.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/virt5.C
@@ -1,53 +1 @@
-// Ensure that virtual base upcast and downcasting works on this
-// conversions during virtual function dispatch at ctor/dtor time
-// when dynamic vtable fixups for deltas are needed.
-
-int fail = 0;
-
-struct BASE1 {
- virtual ~BASE1 () { }
-};
-
-class MID;
-
-class BASE2 {
-public:
- virtual MID *VFN (){ return 0; }
-};
-
-class MIBASE : public BASE1, public BASE2 { };
-
-class VBB : public MIBASE {
-public:
- virtual long get_STATE () const = 0;
- void print_STATE() { if (get_STATE () != 87654321) fail = 1; }
-};
-
-class VBD : public virtual VBB {
- long STATE;
-public:
- long get_STATE() const { return STATE; }
- VBD() { STATE = 87654321; }
- ~VBD() { STATE = 87654321; }
-};
-
-class MID : public virtual VBD {
-public:
- MID () { print_STATE(); }
- ~MID () { print_STATE(); }
- virtual MID *VFN() { return this; }
-};
-
-class LAST : public MID {
-public:
- LAST () { print_STATE(); }
- ~LAST () { print_STATE(); }
-};
-
-main() {
- MIBASE *o = new LAST;
- MID *p = o->VFN();
- p->print_STATE();
- delete o;
- return fail;
-}
+int main() {
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/warn2.C b/gcc/testsuite/g++.old-deja/g++.mike/warn2.C
index a7ce899a31e..4f388e32cbc 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/warn2.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/warn2.C
@@ -1,24 +1,2 @@
-// Build don't link:
-// Special g++ Options: -Wall
-enum Boolean {
- Ok = 0,
- NotOk = 1,
-};
-
-enum OpResult {
- Succeeded = 0,
- TempFail = 1,
- PermFail = 2,
-};
-
-OpResult fn1() {
- return TempFail;
-}
-
-extern void foo();
-main () {
- if (fn1() == Ok) { // WARNING -
- foo();
- }
-}
+int
diff --git a/gcc/testsuite/g++.old-deja/g++.niklas/t141.C b/gcc/testsuite/g++.old-deja/g++.niklas/t141.C
index dda60f549eb..6c81695aebe 100644
--- a/gcc/testsuite/g++.old-deja/g++.niklas/t141.C
+++ b/gcc/testsuite/g++.old-deja/g++.niklas/t141.C
@@ -1,6 +1 @@
-// Build don't link:
-// Special g++ Options: -Wshadow
-// GROUPS passed niklas scoping ARM
-class X { X (int); }; // WARNING - private
-void X (int);// ERROR - .*hides constructor.*
-void f () { X (1); }
+class X { X (int); };
diff --git a/gcc/testsuite/g++.old-deja/g++.ns/extern1.C b/gcc/testsuite/g++.old-deja/g++.ns/extern1.C
index f4ab5ef9e74..906b97b8f06 100644
--- a/gcc/testsuite/g++.old-deja/g++.ns/extern1.C
+++ b/gcc/testsuite/g++.old-deja/g++.ns/extern1.C
@@ -7,7 +7,7 @@
namespace {
void foo() {
- extern int xx; // causes linker error - XFAIL *-*-*
+ extern int xx;
xx = 0;
}
int xx = 1;
diff --git a/gcc/testsuite/g++.old-deja/g++.ns/lookup3.C b/gcc/testsuite/g++.old-deja/g++.ns/lookup3.C
index cd1aaaef517..3ace233c1b9 100644
--- a/gcc/testsuite/g++.old-deja/g++.ns/lookup3.C
+++ b/gcc/testsuite/g++.old-deja/g++.ns/lookup3.C
@@ -8,7 +8,7 @@ int A::f()
return i;
}
-main()
+int main()
{
return A::f();
}
diff --git a/gcc/testsuite/g++.old-deja/g++.ns/ns1.C b/gcc/testsuite/g++.old-deja/g++.ns/ns1.C
index 7c4fd920e5d..f835716d2c3 100644
--- a/gcc/testsuite/g++.old-deja/g++.ns/ns1.C
+++ b/gcc/testsuite/g++.old-deja/g++.ns/ns1.C
@@ -10,7 +10,7 @@ namespace foo{
}
}
-main(int,char**)
+int main(int,char**)
{
return foo::eine_funktion(1);
}
diff --git a/gcc/testsuite/g++.old-deja/g++.ns/ns12.C b/gcc/testsuite/g++.old-deja/g++.ns/ns12.C
index 33d50b1d26c..40f5b7cfe25 100644
--- a/gcc/testsuite/g++.old-deja/g++.ns/ns12.C
+++ b/gcc/testsuite/g++.old-deja/g++.ns/ns12.C
@@ -16,7 +16,7 @@ int barney()
return 1;
}
-main()
+int main()
{
return fred::barney();
}
diff --git a/gcc/testsuite/g++.old-deja/g++.ns/ns13.C b/gcc/testsuite/g++.old-deja/g++.ns/ns13.C
index 0272055d52c..0b8c38a1cbb 100644
--- a/gcc/testsuite/g++.old-deja/g++.ns/ns13.C
+++ b/gcc/testsuite/g++.old-deja/g++.ns/ns13.C
@@ -7,7 +7,7 @@ namespace std{
void std::g()
{}
-main()
+int main()
{
return std::i-5;
}
diff --git a/gcc/testsuite/g++.old-deja/g++.ns/ns2.C b/gcc/testsuite/g++.old-deja/g++.ns/ns2.C
index dcef2039340..e0d1bdade04 100644
--- a/gcc/testsuite/g++.old-deja/g++.ns/ns2.C
+++ b/gcc/testsuite/g++.old-deja/g++.ns/ns2.C
@@ -19,7 +19,7 @@ void andere_funktion()
var=4;
}
-main(int,char**)
+int main(int,char**)
{
andere_funktion();
return 0;
diff --git a/gcc/testsuite/g++.old-deja/g++.ns/ns6.C b/gcc/testsuite/g++.old-deja/g++.ns/ns6.C
index 0617b79a2ef..ba2508c6ded 100644
--- a/gcc/testsuite/g++.old-deja/g++.ns/ns6.C
+++ b/gcc/testsuite/g++.old-deja/g++.ns/ns6.C
@@ -7,7 +7,7 @@ namespace A{
}
}
-main()
+int main()
{
return A::i-A::B::i;
}
diff --git a/gcc/testsuite/g++.old-deja/g++.ns/overload1.C b/gcc/testsuite/g++.old-deja/g++.ns/overload1.C
index 6f6f3d47f51..55d66a1de09 100644
--- a/gcc/testsuite/g++.old-deja/g++.ns/overload1.C
+++ b/gcc/testsuite/g++.old-deja/g++.ns/overload1.C
@@ -21,7 +21,7 @@ int f(int,int)
using namespace A;
using namespace B;
-main()
+int main()
{
if(f() != 1)
return 1;
diff --git a/gcc/testsuite/g++.old-deja/g++.ns/overload4.C b/gcc/testsuite/g++.old-deja/g++.ns/overload4.C
index 24d0ced19a5..ad961576419 100644
--- a/gcc/testsuite/g++.old-deja/g++.ns/overload4.C
+++ b/gcc/testsuite/g++.old-deja/g++.ns/overload4.C
@@ -1,6 +1,6 @@
// Build don't link:
namespace A{
- void f(); // ERROR - .*
+ void f();
}
using A::f;
diff --git a/gcc/testsuite/g++.old-deja/g++.ns/overload5.C b/gcc/testsuite/g++.old-deja/g++.ns/overload5.C
index 210f3b0eb59..24a0a6df4da 100644
--- a/gcc/testsuite/g++.old-deja/g++.ns/overload5.C
+++ b/gcc/testsuite/g++.old-deja/g++.ns/overload5.C
@@ -1,6 +1,6 @@
// Build don't link:
namespace A{
- void f(){} // ERROR - previous declaration
+ void f(){}
}
using A::f;
diff --git a/gcc/testsuite/g++.old-deja/g++.ns/template6.C b/gcc/testsuite/g++.old-deja/g++.ns/template6.C
index 66fe956d6b0..324b4d22a59 100644
--- a/gcc/testsuite/g++.old-deja/g++.ns/template6.C
+++ b/gcc/testsuite/g++.old-deja/g++.ns/template6.C
@@ -13,7 +13,7 @@ namespace A {
};
template <>
- const unsigned B<int,int>::count = 2;
+ const unsigned B<int,int>::count = 2; // ERROR - duplicate init
}
};
diff --git a/gcc/testsuite/g++.old-deja/g++.other/ambig1.C b/gcc/testsuite/g++.old-deja/g++.other/ambig1.C
index 04e4afa1205..d6574a2b79c 100644
--- a/gcc/testsuite/g++.old-deja/g++.other/ambig1.C
+++ b/gcc/testsuite/g++.old-deja/g++.other/ambig1.C
@@ -1,15 +1,15 @@
// Build don't link:
struct A {
- int operator ++();
- void operator ()();
- void operator delete(void*);
+ int operator ++(); // ERROR - candidates
+ void operator ()(); // ERROR - candidates
+ void operator delete(void*); // ERROR - candidates
};
struct B {
- int operator ++(int);
- void operator ()();
- void operator delete(void*);
+ int operator ++(int); // ERROR - candidates
+ void operator ()(); // ERROR - candidates
+ void operator delete(void*); // ERROR - candidates
void f();
};
diff --git a/gcc/testsuite/g++.old-deja/g++.other/badopt1.C b/gcc/testsuite/g++.old-deja/g++.other/badopt1.C
index ea8b6844b68..096770e77ad 100644
--- a/gcc/testsuite/g++.old-deja/g++.other/badopt1.C
+++ b/gcc/testsuite/g++.old-deja/g++.other/badopt1.C
@@ -1,8 +1,6 @@
// Based on a testcase by Bryan Weston <bryanw@bluemoon.sps.mot.com>
// egcs 1.1 fails to increment count
-// execution test - XFAIL *-*-*
-
#include <cstdlib>
struct Base { Base() {} }; // removing the constructor fixes the problem
diff --git a/gcc/testsuite/g++.old-deja/g++.other/cleanup1.C b/gcc/testsuite/g++.old-deja/g++.other/cleanup1.C
index ce373601ded..fd4dc6e4db0 100644
--- a/gcc/testsuite/g++.old-deja/g++.other/cleanup1.C
+++ b/gcc/testsuite/g++.old-deja/g++.other/cleanup1.C
@@ -12,7 +12,7 @@ int f (const A& a)
return 1;
}
-main ()
+int main ()
{
if (f (A()) && d == 0)
return 0;
diff --git a/gcc/testsuite/g++.old-deja/g++.other/decl2.C b/gcc/testsuite/g++.old-deja/g++.other/decl2.C
index 35046504fb4..1da75406d9f 100644
--- a/gcc/testsuite/g++.old-deja/g++.other/decl2.C
+++ b/gcc/testsuite/g++.old-deja/g++.other/decl2.C
@@ -1,8 +1,6 @@
// Build don't link:
// Based on a test-case by Maciej Radziejewski <maciejr@iws.uni-stuttgart.de>
-// crash test - XFAIL *-*-*
-
int i(0)(1); // ERROR - multiple initialization
int j(2) = 3; // ERROR - multiple initialization
int k(4)(5)(6); // ERROR - multiple initialization
diff --git a/gcc/testsuite/g++.old-deja/g++.other/delete2.C b/gcc/testsuite/g++.old-deja/g++.other/delete2.C
index 09362f6895f..d90def03a3f 100644
--- a/gcc/testsuite/g++.old-deja/g++.other/delete2.C
+++ b/gcc/testsuite/g++.old-deja/g++.other/delete2.C
@@ -5,8 +5,8 @@ struct foo {
};
void bar(foo a) {
- delete a; // should be accepted - XFAIL *-*-*
- delete[] a; // should be accepted - XFAIL *-*-*
+ delete a; // should be accepted
+ delete[] a; // should be accepted
char b[1];
delete b; // ERROR - expecting pointer type
delete[] b; // ERROR - expecting pointer type
diff --git a/gcc/testsuite/g++.old-deja/g++.other/friend1.C b/gcc/testsuite/g++.old-deja/g++.other/friend1.C
index e00f5e6b259..76fcebe1fae 100644
--- a/gcc/testsuite/g++.old-deja/g++.other/friend1.C
+++ b/gcc/testsuite/g++.old-deja/g++.other/friend1.C
@@ -9,21 +9,77 @@
// From: Alexandre Oliva <oliva@dcc.unicamp.br>
// Date: 06 Mar 1998 01:43:18 -0300
+template <int*>
+class X {};
+
+template <typename T>
+void g();
+
+struct S;
+
+template <typename T>
+struct R;
class B {
protected:
- int i;
- static int j;
+ int i; // ERROR - in this context
+ static int j;
};
class D : public B {
- friend void f();
+ friend void f();
+ template <typename T>
+ friend void g();
+ friend struct S;
+ template <typename T>
+ friend struct R;
+};
+
+struct S {
+ void h();
+ X<&B::j> x;
+};
+
+template <typename T>
+struct R {
+ void h();
+ X<&B::j> x;
};
void f()
{
((B*)0)->i = 3; // ERROR - protected
((D*)0)->i = 4;
- B::j = 5; // gets bogus error - XFAIL *-*-*
+ B::j = 5;
D::j = 6;
}
+
+template <typename T>
+void g()
+{
+ ((B*)0)->i = 3; // ERROR - protected
+ ((D*)0)->i = 4;
+ B::j = 5;
+ D::j = 6;
+}
+
+template void g<int>();
+
+void S::h()
+{
+ ((B*)0)->i = 3; // ERROR - protected
+ ((D*)0)->i = 4;
+ B::j = 5;
+ D::j = 6;
+}
+
+template <typename T>
+void R<T>::h()
+{
+ ((B*)0)->i = 3; // ERROR - protected
+ ((D*)0)->i = 4;
+ B::j = 5;
+ D::j = 6;
+}
+
+template struct R<double>;
diff --git a/gcc/testsuite/g++.old-deja/g++.other/friend4.C b/gcc/testsuite/g++.old-deja/g++.other/friend4.C
index 468340f7b64..07969cd5487 100644
--- a/gcc/testsuite/g++.old-deja/g++.other/friend4.C
+++ b/gcc/testsuite/g++.old-deja/g++.other/friend4.C
@@ -10,7 +10,7 @@
template <class A, class B> void foo();
template <class C> class bar {
- int i;
+ int i; // ERROR - private
template <class B> friend void foo<C,B>(); // ERROR - bogus declaration
};
template <class A, class B> void foo() {
diff --git a/gcc/testsuite/g++.old-deja/g++.other/init7.C b/gcc/testsuite/g++.old-deja/g++.other/init7.C
index 9a3d5d03dfa..3b17da029e8 100644
--- a/gcc/testsuite/g++.old-deja/g++.other/init7.C
+++ b/gcc/testsuite/g++.old-deja/g++.other/init7.C
@@ -4,8 +4,6 @@
// The initialization of a static local variable must be retried if a
// previous try finished by throwing an exception [stmt.dcl]/4
-// execution test - XFAIL *-*-*
-
struct foo {
foo() { throw true; }
};
diff --git a/gcc/testsuite/g++.old-deja/g++.other/overload1.C b/gcc/testsuite/g++.old-deja/g++.other/overload1.C
index dde6d4fafc7..59191d501e2 100644
--- a/gcc/testsuite/g++.old-deja/g++.other/overload1.C
+++ b/gcc/testsuite/g++.old-deja/g++.other/overload1.C
@@ -4,7 +4,7 @@ struct A {
A operator+ (A, float);
-main ()
+int main ()
{
A a;
a + 1;
diff --git a/gcc/testsuite/g++.old-deja/g++.other/rttid4.C b/gcc/testsuite/g++.old-deja/g++.other/rttid4.C
index 72100b7409d..d77ff3b0b0d 100644
--- a/gcc/testsuite/g++.old-deja/g++.other/rttid4.C
+++ b/gcc/testsuite/g++.old-deja/g++.other/rttid4.C
@@ -1,111 +1,6 @@
-// test of rtti of single inheritance and multiple inheritance with
-// virtual inheritance
-// dynamic casting
-// Special g++ Options: -frtti -w
-
-#include <typeinfo>
-
-extern "C" {
- int printf(const char *, ...);
- void exit(int);
-}
-
-class X {
- public:
- int xi;
- virtual int f() {};
-};
-
-class Y : public virtual X {
- short ys;
-};
-
-class Z : public virtual Y {
- int zi;
-};
-
-Z z;
-Y y;
-Y *yp = &z;
-X *xp = &z;
-Z *zp = &z;
-
-class A {
-public:
- int Ai;
- virtual int a() {};
-};
-
-class B {
-public:
- int Bi;
- virtual int g() {};
-};
-
-class D : public virtual A, private B {
- int Di;
-};
-
-class E : public virtual D, public B {
- int Ei;
-};
-
-class F : public E, public virtual D {
- int Fi;
-};
-
-D d;
-A *ap = &d;
-B *bp = (B *)&d;
-F f;
-F *fp = &f;
-A *aap = &f;
-D *dp = &f;
-E *ep = &f;
-B *bbp = (B *)dp;
-
-void *vp = zp;
-
-/*
-void error (int i)
-{
- printf("FAIL\n");
- exit(i);
-}
-*/
-
-void error (int i)
-{
- exit(i);
-}
-
-int main ()
-{
- vp = (void *)0;
-
- vp = dynamic_cast<Y *> (&z);
- if (vp == 0) error(11);
-
- vp = dynamic_cast<Z *> (yp);
- if (vp == 0) error(11);
-
- vp = dynamic_cast<X *> (yp);
- if (vp == 0) error(12);
-
- vp = dynamic_cast<D *> (dp);
- if (vp != (void *)dp) error(21);
-
- vp = dynamic_cast<B *> (dp);
- if (vp == (void *)dp) error(21);
-
- vp = dynamic_cast<B *> (fp);
- if (vp == (void *)bbp) error(22);
-
- vp = dynamic_cast<void *> (aap);
- if (vp != (void *)fp) error(23);
-
- vp = dynamic_cast<B *> (aap);
- if (vp == (void *)bbp) error(24);
-
-}
-
+// Special g++ Options: -w
+ // Ill-formed: dynamic_cast to private or ambiguous base
+ // vp = dynamic_cast<B *> (dp);
+ // if (vp == (void *)dp) error(21);
+ // vp = dynamic_cast<B *> (fp);
+ // if (vp == (void *)bbp) error(22);
diff --git a/gcc/testsuite/g++.old-deja/g++.other/singleton.C b/gcc/testsuite/g++.old-deja/g++.other/singleton.C
index c2c481075ff..075d83ac79a 100644
--- a/gcc/testsuite/g++.old-deja/g++.other/singleton.C
+++ b/gcc/testsuite/g++.old-deja/g++.other/singleton.C
@@ -1,4 +1,3 @@
-// execution test - re-initialization of statics XFAIL *-*-*
// This tests two things:
// 1. there is an annoying warning.
// singleton.C:26: warning: `class singleton' only defines private constructors and has no friends
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/array1.C b/gcc/testsuite/g++.old-deja/g++.pt/array1.C
index 436b4efaf77..669600f0443 100644
--- a/gcc/testsuite/g++.old-deja/g++.pt/array1.C
+++ b/gcc/testsuite/g++.old-deja/g++.pt/array1.C
@@ -3,7 +3,7 @@ template <class T, unsigned N>
template <class T, unsigned N>
unsigned size(T const (&)[N]) { return N; }
-main() {
+int main() {
short iarray[] = { 1, 2, 3, 4, 5 };
const short carray[] = { 1, 2, 3, 4, 5 };
return size(iarray) - size(carray);
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/crash10.C b/gcc/testsuite/g++.old-deja/g++.pt/crash10.C
index 974cafc8731..033e2341c24 100644
--- a/gcc/testsuite/g++.old-deja/g++.pt/crash10.C
+++ b/gcc/testsuite/g++.old-deja/g++.pt/crash10.C
@@ -6,6 +6,6 @@ public:
enum { val = (N == 0) ? M : GCD<N, M % N>::val };
};
-main() {
+int main() {
GCD< 1, 0 >::val; // ERROR - division
}
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/crash21.C b/gcc/testsuite/g++.old-deja/g++.pt/crash21.C
index 4944d118edd..c84809b38dc 100644
--- a/gcc/testsuite/g++.old-deja/g++.pt/crash21.C
+++ b/gcc/testsuite/g++.old-deja/g++.pt/crash21.C
@@ -1,6 +1,5 @@
// Build don't link:
// Special g++ Options:
-// crash test - XFAIL
class Pooled
{
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/crash5.C b/gcc/testsuite/g++.old-deja/g++.pt/crash5.C
index 786cdf2c902..5797eee23e6 100644
--- a/gcc/testsuite/g++.old-deja/g++.pt/crash5.C
+++ b/gcc/testsuite/g++.old-deja/g++.pt/crash5.C
@@ -3,7 +3,7 @@
template <class T, int i>
struct K {
void f();
-};
+}; // ERROR - forward declaration
template <class T>
void
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/crash8.C b/gcc/testsuite/g++.old-deja/g++.pt/crash8.C
index 2fd687ac819..deff42dba89 100644
--- a/gcc/testsuite/g++.old-deja/g++.pt/crash8.C
+++ b/gcc/testsuite/g++.old-deja/g++.pt/crash8.C
@@ -27,7 +27,7 @@ void doit(T x) {
p2 = TestClass2(); // ERROR - template used as expression
}
-main() {
+int main() {
double x;
doit(x);
}
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/enum5.C b/gcc/testsuite/g++.old-deja/g++.pt/enum5.C
index fc88afa92d3..f6feefb5608 100644
--- a/gcc/testsuite/g++.old-deja/g++.pt/enum5.C
+++ b/gcc/testsuite/g++.old-deja/g++.pt/enum5.C
@@ -1,4 +1,4 @@
// Build don't link:
template <>
-enum E {e}; // ERROR - template declaration of enum XFAIL *-*-*
+enum E {e}; // ERROR - template declaration of enum
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/explicit1.C b/gcc/testsuite/g++.old-deja/g++.pt/explicit1.C
index 0daf54f2373..d218474ec8b 100644
--- a/gcc/testsuite/g++.old-deja/g++.pt/explicit1.C
+++ b/gcc/testsuite/g++.old-deja/g++.pt/explicit1.C
@@ -5,5 +5,5 @@ void foo(T t) {}
void bar()
{
- &foo<double>;
+ (void (*)(double)) &foo<double>;
}
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/explicit2.C b/gcc/testsuite/g++.old-deja/g++.pt/explicit2.C
index 4d88c397f7d..73880315b64 100644
--- a/gcc/testsuite/g++.old-deja/g++.pt/explicit2.C
+++ b/gcc/testsuite/g++.old-deja/g++.pt/explicit2.C
@@ -5,5 +5,5 @@ void foo(T t) {}
void bar()
{
- (void (*)(int)) &foo<double>;
+ (void (*)(int)) (void (*)(double)) &foo<double>;
}
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/explicit22.C b/gcc/testsuite/g++.old-deja/g++.pt/explicit22.C
index 2cb23381653..0f06c53f8fc 100644
--- a/gcc/testsuite/g++.old-deja/g++.pt/explicit22.C
+++ b/gcc/testsuite/g++.old-deja/g++.pt/explicit22.C
@@ -1,10 +1,10 @@
// Build don't link:
// GROUPS passed templates
template <class T, class U>
-T foo(T t, U* u); // ERROR - template candidate
+T foo(T t, U* u);
template <class T>
-T foo(T t, T* t); // ERROR - template candidate
+T foo(T t, T* u);
template <>
-int foo<int>(int, int*); // ERROR - ambiguous template specialization
+int foo<int>(int, int*);
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/explicit26.C b/gcc/testsuite/g++.old-deja/g++.pt/explicit26.C
index eba8d79e292..7d1616255b2 100644
--- a/gcc/testsuite/g++.old-deja/g++.pt/explicit26.C
+++ b/gcc/testsuite/g++.old-deja/g++.pt/explicit26.C
@@ -8,5 +8,5 @@ int foo(int i) { return 0; }
int main()
{
- &foo<int>;
+ (int (*)(int)) &foo<int>;
}
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/explicit27.C b/gcc/testsuite/g++.old-deja/g++.pt/explicit27.C
index 4a5adb59e70..a8d82211fc2 100644
--- a/gcc/testsuite/g++.old-deja/g++.pt/explicit27.C
+++ b/gcc/testsuite/g++.old-deja/g++.pt/explicit27.C
@@ -8,5 +8,5 @@ void foo(int i) {}
int main()
{
- &foo<int>;
+ (void (*)(int)) &foo<int>;
}
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/explicit28.C b/gcc/testsuite/g++.old-deja/g++.pt/explicit28.C
index b842b893289..0133f16c5af 100644
--- a/gcc/testsuite/g++.old-deja/g++.pt/explicit28.C
+++ b/gcc/testsuite/g++.old-deja/g++.pt/explicit28.C
@@ -8,5 +8,5 @@ int foo(int i) { return 0; }
int main()
{
- return (*&foo<int>)(3);
+ return (*((int (*)(int)) &foo<int>))(3);
}
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/explicit30.C b/gcc/testsuite/g++.old-deja/g++.pt/explicit30.C
index 5a697135c46..468dd7914b6 100644
--- a/gcc/testsuite/g++.old-deja/g++.pt/explicit30.C
+++ b/gcc/testsuite/g++.old-deja/g++.pt/explicit30.C
@@ -7,5 +7,5 @@ void foo(T, T*);
void bar()
{
double d;
- (*((void (*)(int, double*)) &foo<int>))(3, &d);
+ (*((void (*)(int, double*)) (void (*)(int, int*)) &foo<int>))(3, &d);
}
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/explicit73.C b/gcc/testsuite/g++.old-deja/g++.pt/explicit73.C
index 106f573c625..1dd0f69ab22 100644
--- a/gcc/testsuite/g++.old-deja/g++.pt/explicit73.C
+++ b/gcc/testsuite/g++.old-deja/g++.pt/explicit73.C
@@ -7,9 +7,9 @@
// the template
namespace N {
- template <class T> class foo;
+ template <class T> class foo; // ERROR - referenced below
}
using namespace N;
-template <> class foo<void>; // ERROR - invalid specialization - XFAIL *-*-*
+template <> class foo<void>; // ERROR - invalid specialization
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/friend11.C b/gcc/testsuite/g++.old-deja/g++.pt/friend11.C
index d70fae6e0c8..1aeba3a1018 100644
--- a/gcc/testsuite/g++.old-deja/g++.pt/friend11.C
+++ b/gcc/testsuite/g++.old-deja/g++.pt/friend11.C
@@ -20,7 +20,7 @@ class C
template <class U>
friend void S<T>::f(U);
- int i;
+ int i; // ERROR - private
};
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/friend21.C b/gcc/testsuite/g++.old-deja/g++.pt/friend21.C
index c89fe1dc1d2..3f690a4404a 100644
--- a/gcc/testsuite/g++.old-deja/g++.pt/friend21.C
+++ b/gcc/testsuite/g++.old-deja/g++.pt/friend21.C
@@ -7,7 +7,7 @@ template <class T> struct A {
template <class T> class B
{
friend class A<T>;
- static int i;
+ static int i; // ERROR - private
};
template <class T> class C
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/friend3.C b/gcc/testsuite/g++.old-deja/g++.pt/friend3.C
index 77aabd3bee3..74d0e06699c 100644
--- a/gcc/testsuite/g++.old-deja/g++.pt/friend3.C
+++ b/gcc/testsuite/g++.old-deja/g++.pt/friend3.C
@@ -7,7 +7,7 @@ class C
{
friend void f<>(double);
- int i;
+ int i; // ERROR - private
};
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/friend34.C b/gcc/testsuite/g++.old-deja/g++.pt/friend34.C
index 8ba2c739d30..56eb80a5056 100644
--- a/gcc/testsuite/g++.old-deja/g++.pt/friend34.C
+++ b/gcc/testsuite/g++.old-deja/g++.pt/friend34.C
@@ -1,5 +1,5 @@
// Build don't link:
-// excess errors test - XFAIL *-*-*
+// excess errors test
// This testcase won't fail if class ::foo is forward-declared in the
// global namespace, nor if class bar is not a template class.
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/friend38.C b/gcc/testsuite/g++.old-deja/g++.pt/friend38.C
index e3a6a060ef6..41c7714acc5 100644
--- a/gcc/testsuite/g++.old-deja/g++.pt/friend38.C
+++ b/gcc/testsuite/g++.old-deja/g++.pt/friend38.C
@@ -2,7 +2,9 @@
// Overly simplified from testcase by "B. K. Oxley" <binkley@bigfoot.com>
+// crash test - XFAIL *-*-*
+
template<class P> struct foo {
typedef P parent_type;
- friend parent_type; // ERROR - template parameters cannot be friends - XFAIL *-*-*
+ friend parent_type; // ERROR - template parameters cannot be friends
};
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/m1.C b/gcc/testsuite/g++.old-deja/g++.pt/m1.C
index 2d1321380be..8b13acb23d9 100644
--- a/gcc/testsuite/g++.old-deja/g++.pt/m1.C
+++ b/gcc/testsuite/g++.old-deja/g++.pt/m1.C
@@ -1,16 +1 @@
-// Build don't link:
-
-int f1 () {
- struct A {
- A() : b (2) { }
- fred () { return b.hi_mom; }
- struct B {
- int hi_mom;
- B (int a) { hi_mom = a; }
- };
- B b;
- };
- A aa;
- return aa.fred();
-}
-/* crashes with signal 11 */
+ int fred () { return b.hi_mom; }
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/memclass1.C b/gcc/testsuite/g++.old-deja/g++.pt/memclass1.C
index 2a9a6f6c02e..5ad839c231e 100644
--- a/gcc/testsuite/g++.old-deja/g++.pt/memclass1.C
+++ b/gcc/testsuite/g++.old-deja/g++.pt/memclass1.C
@@ -5,7 +5,7 @@ template <class T> struct A {
};
};
-main ()
+int main ()
{
A<int>::B<char> b;
b.f (42);
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/memclass2.C b/gcc/testsuite/g++.old-deja/g++.pt/memclass2.C
index 2fc5c31a40e..895fd6128e3 100644
--- a/gcc/testsuite/g++.old-deja/g++.pt/memclass2.C
+++ b/gcc/testsuite/g++.old-deja/g++.pt/memclass2.C
@@ -8,7 +8,7 @@ template <class T> struct A {
};
};
-main ()
+int main ()
{
A<int>::B<char> b;
b.f (42);
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/memclass3.C b/gcc/testsuite/g++.old-deja/g++.pt/memclass3.C
index 2174a3b17b0..77744f854a9 100644
--- a/gcc/testsuite/g++.old-deja/g++.pt/memclass3.C
+++ b/gcc/testsuite/g++.old-deja/g++.pt/memclass3.C
@@ -13,7 +13,7 @@ template <class T> struct A {
};
};
-main ()
+int main ()
{
A<int>::B<int>::C<int>::D<int>::E<int>::F<int> b;
b.f (42);
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/memclass4.C b/gcc/testsuite/g++.old-deja/g++.pt/memclass4.C
index de490e09a83..4c101c6609d 100644
--- a/gcc/testsuite/g++.old-deja/g++.pt/memclass4.C
+++ b/gcc/testsuite/g++.old-deja/g++.pt/memclass4.C
@@ -15,7 +15,7 @@ struct alloc_traits
typedef typename Allocator::template rebind<T>::other allocator_type;
};
-main ()
+int main ()
{
typedef alloc_traits<int, allocator<void> >::allocator_type at;
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/memclass5.C b/gcc/testsuite/g++.old-deja/g++.pt/memclass5.C
index 69b3bcc3e17..06a1413eb0e 100644
--- a/gcc/testsuite/g++.old-deja/g++.pt/memclass5.C
+++ b/gcc/testsuite/g++.old-deja/g++.pt/memclass5.C
@@ -16,7 +16,7 @@ void f ()
template <class T> struct C: public A<T>::B<T> { };
-main ()
+int main ()
{
f<int, char>();
}
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/memtemp43.C b/gcc/testsuite/g++.old-deja/g++.pt/memtemp43.C
index 0948f828279..3d8e3ad7cff 100644
--- a/gcc/testsuite/g++.old-deja/g++.pt/memtemp43.C
+++ b/gcc/testsuite/g++.old-deja/g++.pt/memtemp43.C
@@ -8,7 +8,7 @@ public:
void operator=(A<U, N> const & a) { return; }
};
-main()
+int main()
{
A<float, 3> a;
A<double, 3> b;
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/memtemp44.C b/gcc/testsuite/g++.old-deja/g++.pt/memtemp44.C
index e6d2f879397..c8d6f163c4d 100644
--- a/gcc/testsuite/g++.old-deja/g++.pt/memtemp44.C
+++ b/gcc/testsuite/g++.old-deja/g++.pt/memtemp44.C
@@ -13,7 +13,7 @@ public:
void func(U v1) {}
};
-main()
+int main()
{
A<float> a;
a.func(3);
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/memtemp45.C b/gcc/testsuite/g++.old-deja/g++.pt/memtemp45.C
index f8bb4789fbd..d71f25d07d5 100644
--- a/gcc/testsuite/g++.old-deja/g++.pt/memtemp45.C
+++ b/gcc/testsuite/g++.old-deja/g++.pt/memtemp45.C
@@ -13,7 +13,7 @@ public:
void func(U v1 = 0) {}
};
-main()
+int main()
{
A<float> a;
a.func(3);
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/memtemp46.C b/gcc/testsuite/g++.old-deja/g++.pt/memtemp46.C
index e841ae899c5..2212a52123f 100644
--- a/gcc/testsuite/g++.old-deja/g++.pt/memtemp46.C
+++ b/gcc/testsuite/g++.old-deja/g++.pt/memtemp46.C
@@ -13,7 +13,7 @@ public:
void func(V v1 = 0) {}
};
-main()
+int main()
{
A<float, int> a;
a.func("abc");
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/memtemp63.C b/gcc/testsuite/g++.old-deja/g++.pt/memtemp63.C
index 6b7fc8e44f9..4f793d40e53 100644
--- a/gcc/testsuite/g++.old-deja/g++.pt/memtemp63.C
+++ b/gcc/testsuite/g++.old-deja/g++.pt/memtemp63.C
@@ -6,7 +6,7 @@ A<int> a;
template <class T> template <class U> void A<T>::f (U u) { }
-main()
+int main()
{
a.f (24);
}
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/memtemp67.C b/gcc/testsuite/g++.old-deja/g++.pt/memtemp67.C
index bcf59606384..7170c9027b8 100644
--- a/gcc/testsuite/g++.old-deja/g++.pt/memtemp67.C
+++ b/gcc/testsuite/g++.old-deja/g++.pt/memtemp67.C
@@ -5,7 +5,7 @@ struct A
operator A<T2>() const { return A<T2>(); }
};
-main()
+int main()
{
A<int> a1;
A<long> a2;
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/memtemp69.C b/gcc/testsuite/g++.old-deja/g++.pt/memtemp69.C
index 18932194a27..4c9a2a91ca7 100644
--- a/gcc/testsuite/g++.old-deja/g++.pt/memtemp69.C
+++ b/gcc/testsuite/g++.old-deja/g++.pt/memtemp69.C
@@ -24,7 +24,7 @@ struct X
void f(const T1&) {}
};
-main(int ac, char* av[]) {
+int main(int ac, char* av[]) {
S s;
s.g();
int i[] = {1,2,3,4,5};
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/overload5.C b/gcc/testsuite/g++.old-deja/g++.pt/overload5.C
index ca1a0d3b2d7..058f4f4325c 100644
--- a/gcc/testsuite/g++.old-deja/g++.pt/overload5.C
+++ b/gcc/testsuite/g++.old-deja/g++.pt/overload5.C
@@ -1,8 +1,6 @@
// Build don't link:
-// crash test - XFAIL *-*-*
-
-template <class T> void foo();
+template <class T> void foo(); // ERROR - candidate
void (*bar)() = foo<void>;
void (*baz)() = foo; // ERROR - can't deduce T
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/spec20.C b/gcc/testsuite/g++.old-deja/g++.pt/spec20.C
index 497a32d7554..c6b699d9411 100644
--- a/gcc/testsuite/g++.old-deja/g++.pt/spec20.C
+++ b/gcc/testsuite/g++.old-deja/g++.pt/spec20.C
@@ -1,11 +1,16 @@
// Build don't link:
+// According to the non-normative example in
+// [temp.class.spec.mfunc]/2, these should be valid, but the grammar
+// in the Standard does not allow partial nor full specializations as
+// member-declarations, so we'd better not support them.
+
template <class T>
struct S {
template <class U> void f(U);
- template <> void f<int>(int); // ERROR - specialization
+ template <> void f<int>(int); // ERROR - invalid specialization
template <class V> struct I {};
template <class V> struct I<V*> {};
- template <> struct I<int>; // ERROR - specialization
+ template <> struct I<int>; // ERROR - invalid specialization
};
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/spec22.C b/gcc/testsuite/g++.old-deja/g++.pt/spec22.C
index 88d55d38db6..e170b6e3476 100644
--- a/gcc/testsuite/g++.old-deja/g++.pt/spec22.C
+++ b/gcc/testsuite/g++.old-deja/g++.pt/spec22.C
@@ -11,5 +11,5 @@ struct S
template <class T>
template <> // ERROR - enclosing classes not specialized
void S<T>::f<int> ()
-{
+{ // ERROR - template does not match any declaration
}
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/static3.C b/gcc/testsuite/g++.old-deja/g++.pt/static3.C
index b3040acb0f5..724355e4257 100644
--- a/gcc/testsuite/g++.old-deja/g++.pt/static3.C
+++ b/gcc/testsuite/g++.old-deja/g++.pt/static3.C
@@ -1,3 +1,7 @@
+// On targets that don't support weak symbols, we require an explicit
+// instantiation of arr.
+// excess errors test - XFAIL *-*-aout *-*-coff
+
template<class T>
struct A {
static T arr[5];
@@ -6,7 +10,7 @@ struct A {
template <class T>
T A<T>::arr[5] = { 0, 1, 2, 3, 4 };
-main ()
+int main ()
{
return A<int>::arr[0];
}
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/static_cast.C b/gcc/testsuite/g++.old-deja/g++.pt/static_cast.C
index f4c334eaf5d..26f26c56fc9 100644
--- a/gcc/testsuite/g++.old-deja/g++.pt/static_cast.C
+++ b/gcc/testsuite/g++.old-deja/g++.pt/static_cast.C
@@ -16,7 +16,7 @@ template<class R> void f(R)
accumulate(0, static_cast<int (*)(int, R&)>(p) );
}
-main()
+int main()
{
f(0);
}
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/t16.C b/gcc/testsuite/g++.old-deja/g++.pt/t16.C
index a5b19e43fa6..fca7aa3a92f 100644
--- a/gcc/testsuite/g++.old-deja/g++.pt/t16.C
+++ b/gcc/testsuite/g++.old-deja/g++.pt/t16.C
@@ -1,30 +1 @@
-extern "C" void printf (char *, ...);
-template <class T> T max (const T&x, const T&y)
-{
- return (x>y)?x:y;
-}
-int min (const float&, const float&);
-int min (const int& i1, const int& i2) {
- return (i1 < i2) ? i1 : i2;
-}
-
-class complex
-{
- double re, im;
- public:
- complex (double r, double i=0) { re = r; im = i; }
- friend int operator > (const complex& x, const complex &y) { return 0; }
- void print () { }
-};
-
-main ()
-{
- complex c1 (1, 0);
- complex c2 (2, 0);
-
- int j = max (1, 37);
- complex m1 = max (c1, c2);
- m1.print ();
- printf ("j=%d\n", j);
- return 0;
-}
+int main ()
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/tiemann2.C b/gcc/testsuite/g++.old-deja/g++.pt/tiemann2.C
index 31465d86025..fca7aa3a92f 100644
--- a/gcc/testsuite/g++.old-deja/g++.pt/tiemann2.C
+++ b/gcc/testsuite/g++.old-deja/g++.pt/tiemann2.C
@@ -1,34 +1 @@
-extern "C" void printf (char *, ...);
-template <class T> T max (const T&x, const T&y)
-{
- return (x>y)?x:y;
-}
-
-class complex
-{
- double re, im;
- public:
- complex (double r, double i=0) { re = r; im = i; }
- friend int operator > (const complex& x, const complex &y);
- void print () { printf ("re = %g; im = %g;\n", re, im); }
-};
-int operator >(const complex& x, const complex &y)
-{
- double c1 = x.re * x.re + x.im * x.im;
- double c2 = y.re * y.re + y.im * y.im;
- return c1 > c2;
-}
-
-main ()
-{
- complex c1 (1, 0);
- complex c2 (2, 0);
- complex c3 (2, 3);
- complex c4 (2, 1);
-
- complex m1 = max (c1, c2);
- complex m2 = max (c3, c4);
- m1.print ();
- m2.print ();
- return 0;
-}
+int main ()
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/tt2.C b/gcc/testsuite/g++.old-deja/g++.pt/tt2.C
index c4323a50340..c0033749484 100644
--- a/gcc/testsuite/g++.old-deja/g++.pt/tt2.C
+++ b/gcc/testsuite/g++.old-deja/g++.pt/tt2.C
@@ -1,22 +1,7 @@
-// Build don't link:
-
-int f1 () {
+ int fred () { return b.hi_mom; }
struct A {
- A() : b (2) { }
- fred () { return b.hi_mom; }
- struct B {
- int hi_mom;
- B (int a) { hi_mom = a; }
- };
- B b;
+ ~A() { a = 3; }
+ int a;
+ int fred () { return a + 1; }
};
- A aa;
- return aa.fred();
-}
-int f2 () {
- struct A { ~A() { a = 3; } int a; fred () { return a + 1; } };
- A ab;
- ab.a = 12;
- return ab.fred();
-}
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/ttp14.C b/gcc/testsuite/g++.old-deja/g++.pt/ttp14.C
index 3b284ae8700..04877d65b75 100644
--- a/gcc/testsuite/g++.old-deja/g++.pt/ttp14.C
+++ b/gcc/testsuite/g++.old-deja/g++.pt/ttp14.C
@@ -17,7 +17,7 @@ template<class E,template<class> class DD = D> class C
int f();
};
-template<class E,template<class> class DD = D> int C<E,DD>::f()
+template<class E,template<class> class DD> int C<E,DD>::f()
{
DD<E> d2;
return d2.f();
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/ttp3.C b/gcc/testsuite/g++.old-deja/g++.pt/ttp3.C
index 9a047a846f0..322dd1991e3 100644
--- a/gcc/testsuite/g++.old-deja/g++.pt/ttp3.C
+++ b/gcc/testsuite/g++.old-deja/g++.pt/ttp3.C
@@ -10,5 +10,5 @@ template<template<class> class D,class E> class C
int main()
{
- C<D,int> c; // ERROR - param list not match
+ C<D,int> c; // ERROR - param list not match// WARNING - sees it as not having a type
}
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/typename3.C b/gcc/testsuite/g++.old-deja/g++.pt/typename3.C
index 0b19d54723e..55d6430f2ef 100644
--- a/gcc/testsuite/g++.old-deja/g++.pt/typename3.C
+++ b/gcc/testsuite/g++.old-deja/g++.pt/typename3.C
@@ -16,6 +16,6 @@ struct B : public A<U>
template <class U>
-A<U>::A_Type B<U>::Func()
+B<U>::A_Type B<U>::Func()
{
}
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/typename6.C b/gcc/testsuite/g++.old-deja/g++.pt/typename6.C
index 0b19d54723e..a3df71840e7 100644
--- a/gcc/testsuite/g++.old-deja/g++.pt/typename6.C
+++ b/gcc/testsuite/g++.old-deja/g++.pt/typename6.C
@@ -1,3 +1,5 @@
+// We don't try to make implicit typename handle this case.
+
// Build don't link:
// Special g++ Options:
@@ -11,11 +13,10 @@ struct A
template <class U>
struct B : public A<U>
{
- A_Type Func();
+ A_Type Func(); // ERROR - candidate
};
-
template <class U>
A<U>::A_Type B<U>::Func()
-{
+{ // ERROR - no match
}
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/typename8.C b/gcc/testsuite/g++.old-deja/g++.pt/typename8.C
index d2eb4cede91..86881f51127 100644
--- a/gcc/testsuite/g++.old-deja/g++.pt/typename8.C
+++ b/gcc/testsuite/g++.old-deja/g++.pt/typename8.C
@@ -16,7 +16,7 @@ public:
}
};
-class B : public A< B >
+class B : public A< B > // ERROR - forward declaration
{
public:
typedef int myT;
diff --git a/gcc/testsuite/g++.old-deja/g++.robertl/eb125.C b/gcc/testsuite/g++.old-deja/g++.robertl/eb125.C
index 5faa28087c8..aff6ae61007 100644
--- a/gcc/testsuite/g++.old-deja/g++.robertl/eb125.C
+++ b/gcc/testsuite/g++.old-deja/g++.robertl/eb125.C
@@ -1,3 +1,6 @@
+// This is a crash test; we don't care how many normal errors we get.
+// excess errors test - XFAIL *-*-*
+
struct test_box
{
void print(void);
@@ -17,5 +20,4 @@ template <class BOX> void test(BOX *the_box) // ERROR - semicolon missing
the_box->print();
};
-template void test<> (test_box *); // gets bogus error - test is declared XFAIL *-*-*
-
+template void test<> (test_box *);
diff --git a/gcc/testsuite/g++.old-deja/g++.robertl/eb131.C b/gcc/testsuite/g++.old-deja/g++.robertl/eb131.C
index faa391df4a4..d966fd9c01f 100644
--- a/gcc/testsuite/g++.old-deja/g++.robertl/eb131.C
+++ b/gcc/testsuite/g++.old-deja/g++.robertl/eb131.C
@@ -10,12 +10,11 @@ struct a {
void bar( double );
void bar( float );
- void foo( void (a::*member)(float) ); // ERROR -
+ void foo( void (a::*member)(float) ); // ERROR - candidate
};
a::a()
{
foo( &junk ); // ERROR - junk is an unqualified-id.
- foo( &bar ); // ERROR - bar is an unqualified-id. XFAIL *-*-*
+ foo( &bar ); // ERROR - bar is an unqualified-id.
}
-
diff --git a/gcc/testsuite/g++.old-deja/g++.robertl/eb26.C b/gcc/testsuite/g++.old-deja/g++.robertl/eb26.C
index 1f9cc126f63..2374b557346 100644
--- a/gcc/testsuite/g++.old-deja/g++.robertl/eb26.C
+++ b/gcc/testsuite/g++.old-deja/g++.robertl/eb26.C
@@ -3,7 +3,6 @@
// cannot declare friend of enclosing class using its scope, works fine
// without scope or for definition of foo::bar::f
//
-// excess errors test - XFAIL *-*-*
class foo
{
@@ -18,6 +17,8 @@ public:
};
};
+int foo::bar::x;
+
int foo::f() {
return bar::x;
}
diff --git a/gcc/testsuite/g++.old-deja/g++.robertl/eb27.C b/gcc/testsuite/g++.old-deja/g++.robertl/eb27.C
index edba6cd4da0..9e44f3af8b9 100644
--- a/gcc/testsuite/g++.old-deja/g++.robertl/eb27.C
+++ b/gcc/testsuite/g++.old-deja/g++.robertl/eb27.C
@@ -3,7 +3,6 @@
*/
/* (w) 4.9.97 by Kurt Garloff <K.Garloff@ping.de> */
// Special g++ Options:
-// crash test - XFAIL *-*-*
// 8/28/1998 - This dies in add_conversions from dfs_walk, null CLASSTYPE_METHOD_VEC
// for the test<T> record_type. This is marked as an expected failure for now,
// until we actually fix it.
diff --git a/gcc/testsuite/g++.old-deja/g++.robertl/eb36.C b/gcc/testsuite/g++.old-deja/g++.robertl/eb36.C
index e01dbdae6db..415e5bdf6f4 100644
--- a/gcc/testsuite/g++.old-deja/g++.robertl/eb36.C
+++ b/gcc/testsuite/g++.old-deja/g++.robertl/eb36.C
@@ -1,5 +1,3 @@
-// Build don't link:
-
#include <vector>
template <typename T=float> class foo {
@@ -13,7 +11,7 @@ private:
template <typename T>
foo<T>::foo() :v(), t() {}
-template <typename T=float> // ERROR - default parm for member template XFAIL *-*-*
-foo<T>::foo(vector<int> v_) :v(v_), t() {}
+template <typename T=float>
+foo<T>::foo(vector<int> v_) :v(v_), t() {} // ERROR - default arg for member template
foo<float> a;
diff --git a/gcc/testsuite/g++.old-deja/g++.robertl/eb4.C b/gcc/testsuite/g++.old-deja/g++.robertl/eb4.C
index 04858587d45..b51d3eafb98 100644
--- a/gcc/testsuite/g++.old-deja/g++.robertl/eb4.C
+++ b/gcc/testsuite/g++.old-deja/g++.robertl/eb4.C
@@ -6,7 +6,7 @@ class some_base
{
public:
class base_func_args;
- virtual void func(base_func_args &) = 0;
+ virtual void func(base_func_args &) = 0; // ERROR - referenced below
};
class some_base::base_func_args
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 8850f9fa639..00000000000
--- a/gcc/testsuite/g++.old-deja/g++.robertl/eb42.C
+++ /dev/null
@@ -1,19 +0,0 @@
-//Build don't link:
-#include <vector.h>
-#include <algo.h>
-
-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()
-{
-vector<int> a(3);
-sort( a.begin(), a.end(), compare ); // ERROR - no matching function
-}
diff --git a/gcc/testsuite/g++.old-deja/g++.robertl/eb43.C b/gcc/testsuite/g++.old-deja/g++.robertl/eb43.C
index 8690d11a038..7f8647226c8 100644
--- a/gcc/testsuite/g++.old-deja/g++.robertl/eb43.C
+++ b/gcc/testsuite/g++.old-deja/g++.robertl/eb43.C
@@ -1,4 +1,7 @@
-// excess errors test - XFAIL *-*-*
+// All the pointer_to_binary_function cases used to fail because g++
+// couldn't handle converting an overloaded function to a class type.
+// The first one should still fail because it requires an implicit conversion
+// to pointer_to_binary_function, which has an `explicit' constructor.
#include <vector.h>
#include <algo.h>
@@ -13,7 +16,7 @@ public :
template <class T >
inline bool compare(const Expr<T> a, const Expr<T> b){ return true; };
-void main()
+int main()
{
vector<int> a(3);
sort( a.begin(), a.end(),
@@ -21,7 +24,7 @@ void main()
sort( a.begin(), a.end(), compare<int> );
sort<vector<int>::iterator,
pointer_to_binary_function<const Expr<int>, const Expr<int>, bool> >
- ( a.begin(), a.end(), compare );
+ ( a.begin(), a.end(), compare ); // ERROR - constructor is explicit
sort( a.begin(), a.end(),
ptr_fun<const Expr<int>, const Expr<int>, bool> (compare) );
sort( a.begin(), a.end(),
diff --git a/gcc/testsuite/g++.old-deja/g++.robertl/eb44.C b/gcc/testsuite/g++.old-deja/g++.robertl/eb44.C
index 19c4bbf00ff..54eab153609 100644
--- a/gcc/testsuite/g++.old-deja/g++.robertl/eb44.C
+++ b/gcc/testsuite/g++.old-deja/g++.robertl/eb44.C
@@ -27,7 +27,7 @@ ostream& operator<< (ostream& out, const Vector<char>&)
return out;
}
-main()
+int main()
{
Vector<char> vc;
ostream out;
diff --git a/gcc/testsuite/g++.old-deja/g++.robertl/eb46.C b/gcc/testsuite/g++.old-deja/g++.robertl/eb46.C
index 4b40322805d..ad077e38dc3 100644
--- a/gcc/testsuite/g++.old-deja/g++.robertl/eb46.C
+++ b/gcc/testsuite/g++.old-deja/g++.robertl/eb46.C
@@ -1,8 +1,9 @@
#include <iostream.h>
class A1 {
+ friend class B;
public:
- virtual void foo() {friend class B;};
+ virtual void foo() {};
};
class A2 : public virtual A1 {friend class B;};
diff --git a/gcc/testsuite/g++.old-deja/g++.robertl/eb59.C b/gcc/testsuite/g++.old-deja/g++.robertl/eb59.C
index 4bc50b12e2a..7c0c1534ae4 100644
--- a/gcc/testsuite/g++.old-deja/g++.robertl/eb59.C
+++ b/gcc/testsuite/g++.old-deja/g++.robertl/eb59.C
@@ -21,7 +21,7 @@ template<class R> void f( vector<R>& v )
#endif
}
-main()
+int main()
{
vector<int> r;
f( r );
diff --git a/gcc/testsuite/g++.old-deja/g++.robertl/eb66.C b/gcc/testsuite/g++.old-deja/g++.robertl/eb66.C
index e9a303afdf6..d79865f21d9 100644
--- a/gcc/testsuite/g++.old-deja/g++.robertl/eb66.C
+++ b/gcc/testsuite/g++.old-deja/g++.robertl/eb66.C
@@ -6,7 +6,7 @@ int bar ()
throw 100;
}
-main ()
+int main ()
{
int i = 0;
try
diff --git a/gcc/testsuite/g++.old-deja/g++.robertl/eb69.C b/gcc/testsuite/g++.old-deja/g++.robertl/eb69.C
index bd413ddacf5..9cc5f4a3ffe 100644
--- a/gcc/testsuite/g++.old-deja/g++.robertl/eb69.C
+++ b/gcc/testsuite/g++.old-deja/g++.robertl/eb69.C
@@ -6,4 +6,4 @@
typedef int an_int;
bar() : bar::an_int(3) {}; // will call foo::foo(3)
};
- main() { bar b; }
+int main() { bar b; }
diff --git a/gcc/testsuite/g++.old-deja/g++.robertl/eb70.C b/gcc/testsuite/g++.old-deja/g++.robertl/eb70.C
index a82a399d540..30da1845973 100644
--- a/gcc/testsuite/g++.old-deja/g++.robertl/eb70.C
+++ b/gcc/testsuite/g++.old-deja/g++.robertl/eb70.C
@@ -1,19 +1,17 @@
// conversion ops should be treated as coming from the most derived class
// for overload resolution. See [over.match.funcs].
// Build don't link:
-// excess errors test - XFAIL *-*-*
class X {
public:
- inline operator bool() const { return true; }
+ operator bool() const;
};
class Y : public X {
private:
- inline operator void*() const { return 0; }
+ operator void*() const;
};
-
int f(Y const& y) {
return bool(y);
}
diff --git a/gcc/testsuite/g++.old-deja/g++.robertl/eb78.C b/gcc/testsuite/g++.old-deja/g++.robertl/eb78.C
index 15f26318efb..3baea64743d 100644
--- a/gcc/testsuite/g++.old-deja/g++.robertl/eb78.C
+++ b/gcc/testsuite/g++.old-deja/g++.robertl/eb78.C
@@ -119,6 +119,7 @@ tryIt(const String& filename)
}
}
+int
main()
{
tryIt("goodFile.txt");
diff --git a/gcc/testsuite/g++.old-deja/old-deja.exp b/gcc/testsuite/g++.old-deja/old-deja.exp
index 072ed14d173..ff685b5d9f5 100644
--- a/gcc/testsuite/g++.old-deja/old-deja.exp
+++ b/gcc/testsuite/g++.old-deja/old-deja.exp
@@ -1,3 +1,4 @@
set dirlen [expr [string length "$srcdir/$subdir"] + 1];
set tfile [string range $file $dirlen end];
if ![runtest_file_p $runtests $tfile] then {
+ old-dejagnu $GXX_UNDER_TEST "$file" "$tfile" "" "$DEFAULT_CXXFLAGS" "-lstdc++"
diff --git a/gcc/testsuite/g77.f-torture/execute/u77-test.f b/gcc/testsuite/g77.f-torture/execute/u77-test.f
index bcb3270baa5..bb6e1e851db 100644
--- a/gcc/testsuite/g77.f-torture/execute/u77-test.f
+++ b/gcc/testsuite/g77.f-torture/execute/u77-test.f
@@ -233,9 +233,12 @@ C the better to test with, my dear! (-- burley)
end do
i = lstat ('foo', fstatb)
do i=1,13
- if (fstatb (i) .ne. statb (i)) then
- write (6,*) '*** LSTAT and STAT don''t agree on '// '
- + array element ', i, ' value ', fstatb (i), statb (i)
+c For some reason that I haven't investigated, some people see
+c failures with the 7th element which doesn't seem to indicate a u77
+c bug.
+ if (fstatb (i) .ne. statb (i) .and. i .ne. 7) then
+ write (6,*) '*** LSTAT and STAT don''t agree on '//
+ + 'array element ', i, ' value ', fstatb (i), statb (i)
call abort
end if
end do
diff --git a/gcc/testsuite/gcc.c-torture/ChangeLog b/gcc/testsuite/gcc.c-torture/ChangeLog
index 6663d8a8dbb..dade5118447 100644
--- a/gcc/testsuite/gcc.c-torture/ChangeLog
+++ b/gcc/testsuite/gcc.c-torture/ChangeLog
@@ -1,3 +1,58 @@
+Mon Mar 22 14:55:58 1999 Jim Wilson <wilson@cygnus.com>
+
+ * execute/bf-sign-2.c (main): Replace struct sizeof test with 4.
+
+Wed Mar 17 12:22:39 1999 Richard Henderson <rth@cygnus.com>
+
+ * gcc.c-torture/execute/ieee/980619-1.x: New. Expected fail on x86.
+
+Fri Mar 12 16:17:28 1999 Jim Wilson <wilson@cygnus.com>
+
+ * execute/970312-1.c, execute/980605-1.c (f): Change printf to sprintf.
+ * execute/bf-sign-2.c (struct X): Add u15 field.
+ (main): Add check for u15. Conditionalize u31 check depending on
+ whether ints are <32 bits or >=32 bits.
+
+1999-03-01 Zack Weinberg <zack@rabi.columbia.edu>
+
+ * noncompile/noncompile.exp (951025-1.c): Accept an error
+ message on line 1 or line 2; cccp and cpplib do this differently.
+
+1999-02-03 Nick Clifton <nickc@cygnus.com>
+
+ * execute/memcheck/blkarg.c (foo): Use 10 leading arguments in
+ order to force structure S onto the stack even on the alpha.
+ (test): Pass 10 leading arguments to function foo as well as the
+ structure S.
+
+ * execute/memcheck/blkarg.x: New file: Expected failure for all
+ targets.
+
+ * execute/memcheck/driver.c (main): Use exit or abort to terminate
+ program execution.
+
+1999-01-28 Michael Meissner <meissner@cygnus.com>
+
+ * execute/990128-1.c: New test.
+
+1999-01-27 Michael Meissner <meissner@cygnus.com>
+
+ * execute/990127-{1,2}.c: New tests.
+
+1998-12-14 Nick Clifton <nickc@cygnus.com>
+
+ * execute/920501-4.c (main): Fix typo: replace | with ||.
+
+1998-11-30 Nick Clifton <nickc@cygnus.com>
+
+ * execute/981130-1.c: New test.
+ * execute/981130-1.x: New test failure expectations.
+
+Sun Oct 11 05:04:28 1998 Ken Raeburn <raeburn@cygnus.com>
+
+ * execute/memcheck: New directory of tests for
+ -fcheck-memory-usage.
+
1998-10-06 Ken Raeburn <raeburn@cygnus.com>
* special/981006-1.c: New test. Make sure gcc doesn't lose track
@@ -9,6 +64,10 @@ Thu Oct 1 17:15:26 1998 Nick Clifton <nickc@cygnus.com>
* compile/981001-1.c: New test.
* execute/981001-1.c: New test.
+Mon Aug 31 12:00:00 1998 Catherine Moore <clm@cygnus.com>
+
+ * execute/941014-1.x: New file.
+
Wed Aug 26 16:10:00 1997 J"orn Rennecke <amylaar@cygnus.co.uk>
* execute/loop-4b.c: New test.
diff --git a/gcc/testsuite/gcc.c-torture/compile/981001-4.c b/gcc/testsuite/gcc.c-torture/compile/981001-4.c
index 2ec5d8b2605..dd3df9cce4b 100644
--- a/gcc/testsuite/gcc.c-torture/compile/981001-4.c
+++ b/gcc/testsuite/gcc.c-torture/compile/981001-4.c
@@ -1,7 +1,7 @@
#define P(a,b) P1(a,b)
#define P1(a,b) a##b
-#define ONCE(x, y) (x ?: x = y())
+#define ONCE(x, y) (x ?: (x = y()))
#define PREFIX
extern int P(PREFIX, init) (void);
diff --git a/gcc/testsuite/gcc.c-torture/execute/920501-4.c b/gcc/testsuite/gcc.c-torture/execute/920501-4.c
index b936c4984b6..46b0da1f7de 100644
--- a/gcc/testsuite/gcc.c-torture/execute/920501-4.c
+++ b/gcc/testsuite/gcc.c-torture/execute/920501-4.c
@@ -1,6 +1,24 @@
-#ifndef NO_LABEL_VALUES
-x(int i){static const void*j[]={&&x,&&y,&&z};goto*j[i];x:return 2;y:return 3;z:return 5;}
-main(){if(x(0)!=2||x(1)!=3|x(2)!=5)abort();exit(0);}
-#else
-main(){ exit (0); }
-#endif
+int
+x (int i)
+{
+ static const void *j[] = {&& x, && y, && z};
+
+ goto *j[i];
+
+ x: return 2;
+ y: return 3;
+ z: return 5;
+}
+
+int
+main (void)
+{
+ if ( x (0) != 2
+ || x (1) != 3
+ || x (2) != 5)
+ abort ();
+
+ exit (0);
+}
+int
+main (void) { exit (0); }
diff --git a/gcc/testsuite/gcc.c-torture/execute/970312-1.c b/gcc/testsuite/gcc.c-torture/execute/970312-1.c
index b303c4a8e60..9342edee478 100644
--- a/gcc/testsuite/gcc.c-torture/execute/970312-1.c
+++ b/gcc/testsuite/gcc.c-torture/execute/970312-1.c
@@ -1,71 +1,3 @@
-#include <stdio.h>
+char buf[10];
-__inline__ static int
-dummy (x)
-{
- int y;
- y = (long) (x * 4711.3);
- return y;
-}
-
-int getval (void);
-
-int
-f2 (double x)
-{
- unsigned short s;
- int a, b, c, d, e, f, g, h, i, j;
-
- a = getval ();
- b = getval ();
- c = getval ();
- d = getval ();
- e = getval ();
- f = getval ();
- g = getval ();
- h = getval ();
- i = getval ();
- j = getval ();
-
-
- s = x;
-
- return a + b + c + d + e + f + g + h + i + j + s;
-}
-
-int x = 1;
-
-int
-getval (void)
-{
- return x++;
-}
-
-void
-f ()
-{
- int a, b, c, d, e, f, g, h, i, j, k;
-
- a = getval ();
- b = getval ();
- c = getval ();
- d = getval ();
- e = getval ();
- f = getval ();
- g = getval ();
- h = getval ();
- i = getval ();
- j = getval ();
-
- k = f2 (17.0);
-
- printf ("%d\n", a + b + c + d + e + f + g + h + i + j + k);
- if (a + b + c + d + e + f + g + h + i + j + k != 227)
- abort ();
-}
-
-main ()
-{
- f ();
- exit (0);
-}
+ sprintf (buf, "%d\n", a + b + c + d + e + f + g + h + i + j + k);
diff --git a/gcc/testsuite/gcc.c-torture/execute/980526-1.c b/gcc/testsuite/gcc.c-torture/execute/980526-1.c
index 491068f9b64..57a910e4366 100644
--- a/gcc/testsuite/gcc.c-torture/execute/980526-1.c
+++ b/gcc/testsuite/gcc.c-torture/execute/980526-1.c
@@ -29,7 +29,9 @@ static void do2(void){
}
int main(void){
+#ifndef NO_LABEL_VALUES
do1();
do2();
+#endif
exit(0);
}
diff --git a/gcc/testsuite/gcc.c-torture/execute/980605-1.c b/gcc/testsuite/gcc.c-torture/execute/980605-1.c
index 5ce89a28a76..2fc2691e535 100644
--- a/gcc/testsuite/gcc.c-torture/execute/980605-1.c
+++ b/gcc/testsuite/gcc.c-torture/execute/980605-1.c
@@ -45,6 +45,8 @@ getval (void)
return x++;
}
+char buf[10];
+
void
f ()
{
@@ -64,7 +66,7 @@ f ()
k = f2 (17.0);
- printf ("%d\n", a + b + c + d + e + f + g + h + i + j + k);
+ sprintf (buf, "%d\n", a + b + c + d + e + f + g + h + i + j + k);
if (a + b + c + d + e + f + g + h + i + j + k != 227)
abort ();
}
diff --git a/gcc/testsuite/gcc.c-torture/execute/bcp-1.c b/gcc/testsuite/gcc.c-torture/execute/bcp-1.c
index 1eafec5beb9..38b1d3e8e93 100644
--- a/gcc/testsuite/gcc.c-torture/execute/bcp-1.c
+++ b/gcc/testsuite/gcc.c-torture/execute/bcp-1.c
@@ -11,6 +11,7 @@ inline int bad6(int x) { return __builtin_constant_p(x+1); }
int bad7(void) { return __builtin_constant_p(abort()); }
int bad8(void) { char buf[10]; return __builtin_constant_p(buf); }
int bad9(const char *x) { return __builtin_constant_p(x[123456]); }
+int bad10(void) { return __builtin_constant_p(&global); }
/* These must pass, or we've broken gcc2 functionality. */
int good0(void) { return __builtin_constant_p(1); }
@@ -20,14 +21,25 @@ int good2(void) { return __builtin_constant_p((1234 + 45) & ~7); }
/* These are extensions to gcc2. Failure indicates an optimization
regression. */
int opt0(void) { return bad3(1); }
-int opt1(void) { return bad4("hi"); }
-int opt2(void) { return bad6(1); }
-int opt3(void) { return __builtin_constant_p(&global); }
-int opt4(void) { return __builtin_constant_p("hi"[0]); }
+int opt1(void) { return bad6(1); }
+int opt2(void) { return __builtin_constant_p("hi"[0]); }
+
+/*
+ * Opt3 is known to fail. It is one of the important cases that glibc
+ * was interested in though, so keep this around as a reminder.
+ *
+ * The solution is to add bits to recover bytes from constant pool
+ * elements given nothing but a constant pool label and an offset.
+ * When we can do that, and we can simplify strlen after the fact,
+ * then we can enable recognition of constant pool labels as constants.
+ */
+
+/* int opt3(void) { return bad4("hi"); } */
+
/* Call through tables so -finline-functions can't screw with us. */
int (*bad_t0[])(void) = {
- bad0, bad1, bad5, bad7, bad8
+ bad0, bad1, bad5, bad7, bad8, bad10
};
int (*bad_t1[])(int x) = {
@@ -43,7 +55,7 @@ int (*good_t0[])(void) = {
};
int (*opt_t0[])(void) = {
- opt0, opt1, opt2, opt3, opt4
+ opt0, opt1, opt2 /* , opt3 */
};
#define N(arr) (sizeof(arr)/sizeof(*arr))
diff --git a/gcc/testsuite/gcc.c-torture/execute/bf-sign-2.c b/gcc/testsuite/gcc.c-torture/execute/bf-sign-2.c
index 479082217eb..ede55918c31 100644
--- a/gcc/testsuite/gcc.c-torture/execute/bf-sign-2.c
+++ b/gcc/testsuite/gcc.c-torture/execute/bf-sign-2.c
@@ -1,52 +1,16 @@
-/*
- This test checks promotion of bitfields. Bitfields should be promoted
- very much like chars and shorts:
-
- Bitfields (signed or unsigned) should be promoted to signed int if their
- value will fit in a signed int, otherwise to an unsigned int if their
- value will fit in an unsigned int, otherwise we don't promote them (ANSI/ISO
- does not specify the behavior of bitfields larger than an unsigned int).
-
- We test the behavior by subtracting two from the promoted value: this will
- result in a negitive value for signed types, a positive value for unsigned
- types. This test (of course) assumes that the compiler is correctly
- implementing signed and unsigned arithmatic.
- */
-
-struct X {
- unsigned int u3:3;
- long int s31:31;
- long int s32:32;
- unsigned long int u31:31;
- unsigned long int u32:32;
- unsigned long long ull3 :3;
- unsigned long long ull35:35;
-};
-
-struct X x;
-
-main ()
-{
- if ((x.u3 - 2) >= 0) /* promoted value should be signed */
- abort ();
-
- if ((x.s31 - 2) >= 0) /* promoted value should be signed */
- abort ();
-
- if ((x.s32 - 2) >= 0) /* promoted value should be signed */
- abort ();
-
- if ((x.u31 - 2) >= 0) /* promoted value should be signed */
- abort ();
-
- if ((x.u32 - 2) < 0) /* promoted value should be UNsigned */
- abort ();
-
- if ((x.ull3 - 2) >= 0) /* promoted value should be signed */
- abort ();
-
- if ((x.ull35 - 2) < 0) /* promoted value should be UNsigned */
- abort ();
-
- exit (0);
-}
+ implementing signed and unsigned arithmetic.
+ unsigned u15:15;
+ if ((x.u15 - 2) >= 0) /* promoted value should be signed */
+
+ /* Conditionalize check on whether integers are 4 bytes or larger, i.e.
+ larger than a 31 bit bitfield. */
+ if (sizeof (int) >= 4)
+ {
+ if ((x.u31 - 2) >= 0) /* promoted value should be signed */
+ abort ();
+ }
+ else
+ {
+ if ((x.u31 - 2) < 0) /* promoted value should be UNsigned */
+ abort ();
+ }
diff --git a/gcc/testsuite/gcc.c-torture/noncompile/noncompile.exp b/gcc/testsuite/gcc.c-torture/noncompile/noncompile.exp
index be7e234e492..ddebf06ddcf 100644
--- a/gcc/testsuite/gcc.c-torture/noncompile/noncompile.exp
+++ b/gcc/testsuite/gcc.c-torture/noncompile/noncompile.exp
@@ -225,7 +225,7 @@ postbase $src_code $run $groups
# Test 951025-1.c
prebase
set src_code 951025-1.c
-set compiler_output ".*:2:"
+set compiler_output ".*:\[12\]:"
set groups {passed gcc-noncompile}
diff --git a/gcc/testsuite/gcc.c-torture/special/920521-1.c b/gcc/testsuite/gcc.c-torture/special/920521-1.c
index 0f4dc08fb30..95b949798dc 100644
--- a/gcc/testsuite/gcc.c-torture/special/920521-1.c
+++ b/gcc/testsuite/gcc.c-torture/special/920521-1.c
@@ -1 +1 @@
-f(){asm("f":::"cc");}g(x){asm("g"::"%r"(x));}
+f(){asm("f":::"cc");}g(x,y){asm("g"::"%r"(x), "r"(y));}
diff --git a/gcc/testsuite/gcc.c-torture/special/930510-1.c b/gcc/testsuite/gcc.c-torture/special/930510-1.c
index f973bc63321..26770f3455d 100644
--- a/gcc/testsuite/gcc.c-torture/special/930510-1.c
+++ b/gcc/testsuite/gcc.c-torture/special/930510-1.c
@@ -1,3 +1 @@
-#define ugly 3
-#ugly "foobar" 3 /* { dg-error "invalid" "invalid directive" } */
-main() { exit (0); }
+int main() { exit (0); }
diff --git a/gcc/testsuite/gcc.dg/980827-1.c b/gcc/testsuite/gcc.dg/980827-1.c
index 33a496b9624..a841739c466 100644
--- a/gcc/testsuite/gcc.dg/980827-1.c
+++ b/gcc/testsuite/gcc.dg/980827-1.c
@@ -1,6 +1,8 @@
/* { dg-do run { target powerpc*-*-* } } */
/* { dg-options -O2 } */
+double dval = 0;
+
void splat (double d);
int main(void)
diff --git a/gcc/testsuite/gcc.dg/dll-1.c b/gcc/testsuite/gcc.dg/dll-1.c
index 72c6ba5b24e..b9f7e3b775d 100644
--- a/gcc/testsuite/gcc.dg/dll-1.c
+++ b/gcc/testsuite/gcc.dg/dll-1.c
@@ -1,9 +1,2 @@
-/* { dg-do compile { target arm*-*-pe* } } */
-/* { dg-options -mno-nop-fun-dllimport } */
-
-__declspec (dllimport) void imp ();
-
-__declspec (dllexport) void exp () { imp (); }
-
-/* { dg-final { scan-assembler dll-1.c "__imp_imp.*\.section\[ \t\]*.drectve\n\[^\n\]*-export:exp" } } */
-/* { dg-final { scan-assembler-not dll-1.c "__imp_exp" } } */
+/* { dg-do compile { target thumb*-*-pe* } } */
+/* { dg-final { scan-assembler dll-1.c "\.section\[ \t\]*.drectve\n\[^\n\]*-export:exp.*__imp_imp" } } */
diff --git a/gcc/testsuite/gcc.dg/dll-2.c b/gcc/testsuite/gcc.dg/dll-2.c
index e49f6e2027d..1a28b189e7b 100644
--- a/gcc/testsuite/gcc.dg/dll-2.c
+++ b/gcc/testsuite/gcc.dg/dll-2.c
@@ -1,23 +1 @@
-/* These dllimport and dllexport appearing for a symbol.
- The desired behaviour is that if both dllimport
- and dllexport appear (in either order) the result is dllexport.
-
- Microsoft's MSVC 2.0 allows dllimport followed by dllexport for variables,
- but does not allow dllexport followed by dllimport.
-
- In C, it's ok to redeclare a variable so this works for variables
- and functions. In C++, it only works for functions. */
-
-/* { dg-do compile { target arm*-*-pe* } } */
-
-__declspec (dllimport) int foo1 ();
-__declspec (dllexport) int foo1 ();
-
-__declspec (dllexport) int foo2 ();
-__declspec (dllimport) int foo2 ();
-
-__declspec (dllimport) int bar1;
-__declspec (dllexport) int bar1;
-
-__declspec (dllexport) int bar2;
-__declspec (dllimport) int bar2;
+/* { dg-do compile { target thumb*-*-pe* } } */
diff --git a/gcc/testsuite/gcc.dg/dll-3.c b/gcc/testsuite/gcc.dg/dll-3.c
index 4976ebbbcc6..1a28b189e7b 100644
--- a/gcc/testsuite/gcc.dg/dll-3.c
+++ b/gcc/testsuite/gcc.dg/dll-3.c
@@ -1,15 +1 @@
-/* Ensure dllexport overrides dllimport. */
-
-/* { dg-do compile { target arm*-*-pe* } } */
-
-__declspec (dllimport) int foo1 ();
-__declspec (dllexport) int foo1 ();
-
-__declspec (dllexport) int foo2 ();
-__declspec (dllimport) int foo2 ();
-
-__declspec (dllexport) int foo1 () { return foo2 (); }
-__declspec (dllexport) int foo2 () { return foo1 (); }
-
-/* { dg-final { scan-assembler dll-3.c "\.section\[ \t\]*\.drectve\n\[^\n\]*-export:foo1.*\.section\[ \t\]*\.drectve\n\[^\n\]*-export:foo2" } } */
-/* { dg-final { scan-assembler-not dll-3.c "(__imp_foo1|__imp_foo2)" } } */
+/* { dg-do compile { target thumb*-*-pe* } } */
diff --git a/gcc/testsuite/gcc.dg/dll-4.c b/gcc/testsuite/gcc.dg/dll-4.c
index ae617861951..b50eafe1d3e 100644
--- a/gcc/testsuite/gcc.dg/dll-4.c
+++ b/gcc/testsuite/gcc.dg/dll-4.c
@@ -1,13 +1,2 @@
-/* { dg-do compile { target arm*-*-pe* } } */
-
-__declspec (dllimport) int foo1;
-int foo1;
-
-__declspec (dllimport) int foo2;
-int foo2 = 5;
-
-int f () { return foo1 + foo2; }
-
-/* FIXME: We should scan the output of nm for this case. */
-/* { dg-final { scan-assembler dll-4.c "(\.comm\[ \t\]*foo1.*\nfoo2:|\nfoo2:.*\.comm\[ \t\]*foo1)" } } */
-/* { dg-final { scan-assembler-not dll-4.c "__imp_" } } */
+/* { dg-do compile { target thumb*-*-pe* } } */
+/* { dg-final { scan-assembler dll-4.c "(foo2:.*\.comm\[ \t_\]*foo1)" } } */
diff --git a/gcc/testsuite/gcc.misc-tests/gcov-1.c b/gcc/testsuite/gcc.misc-tests/gcov-1.c
index 20fc950dddc..9196059e635 100644
--- a/gcc/testsuite/gcc.misc-tests/gcov-1.c
+++ b/gcc/testsuite/gcc.misc-tests/gcov-1.c
@@ -1,20 +1,2 @@
-/* Test Gcov basics. */
-
-/* { dg-options "-fprofile-arcs -ftest-coverage" } */
-/* { dg-do run { target native } } */
-
-noop ()
-{
-}
-
-main ()
-{
- int i;
-
- for (i = 0; i < 10; i++) /* count(11) */
- noop (); /* count(10) */
-
- return 0; /* count(1) */
-}
-
-/* { dg-final { run-gcov gcov-1.c } } */
+void noop ()
+int main ()
diff --git a/gcc/testsuite/gcc.misc-tests/gcov-2.c b/gcc/testsuite/gcc.misc-tests/gcov-2.c
index 3d64d8cad4e..9196059e635 100644
--- a/gcc/testsuite/gcc.misc-tests/gcov-2.c
+++ b/gcc/testsuite/gcc.misc-tests/gcov-2.c
@@ -1,21 +1,2 @@
-/* Test Gcov basics. */
-
-/* { dg-prms-id 8294 } */
-/* { dg-options "-fprofile-arcs -ftest-coverage -g" } */
-/* { dg-do run { target native } } */
-
-noop ()
-{
-}
-
-main ()
-{
- int i;
-
- for (i = 0; i < 10; i++) /* count(11) */
- noop (); /* count(10) */
-
- return 0; /* count(1) */
-}
-
-int a_variable = 0;
+void noop ()
+int main ()
diff --git a/gcc/testsuite/lib/c-torture.exp b/gcc/testsuite/lib/c-torture.exp
index 3ff1de0e459..e2031d87bcd 100644
--- a/gcc/testsuite/lib/c-torture.exp
+++ b/gcc/testsuite/lib/c-torture.exp
@@ -1,4 +1,4 @@
-# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997 Free Software Foundation, Inc.
+# Copyright (C) 1992-1998, 1999 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
@@ -23,16 +23,22 @@
# TORTURE_OPTIONS="{ { list1 } ... { listN } }"
if ![info exists TORTURE_OPTIONS] {
- # It is theoretically beneficial to group all of the O2 options together,
+ # It is theoretically beneficial to group all of the O2/O3 options together,
# as in many cases the compiler will generate identical executables for
# all of them--and the c-torture testsuite will skip testing identical
# executables multiple times.
+ # Also note that -finline-functions is explicitly included in one of the
+ # items below, even though -O3 is also specified, because some ports may
+ # choose to disable inlining functions by default, even when optimizing.
set TORTURE_OPTIONS [list \
- { -O0 } { -O1 } { -O2 } \
- { -O2 -fomit-frame-pointer -finline-functions } \
- { -O2 -fomit-frame-pointer -finline-functions -funroll-loops } \
- { -O2 -fomit-frame-pointer -finline-functions -funroll-all-loops } \
- { -O2 -g } { -Os } ]
+ { -O0 } \
+ { -O1 } \
+ { -O2 } \
+ { -O3 -fomit-frame-pointer } \
+ { -O3 -fomit-frame-pointer -funroll-loops } \
+ { -O3 -fomit-frame-pointer -funroll-all-loops -finline-functions } \
+ { -O3 -g } \
+ { -Os } ]
}
@@ -76,50 +82,7 @@ proc c-torture-compile { src option } {
lappend options "additional_flags=-w $option"
set comp_output [gcc_target_compile "$src" "$output" object $options];
-
- # Set a few common compiler messages.
- set fatal_signal "*cc: Internal compiler error: program*got fatal signal"
-
- if [string match "$fatal_signal 6" $comp_output] then {
- gcc_fail $testcase "Got Signal 6, $option"
- remote_file build delete $output
- return
- }
-
- if [string match "$fatal_signal 11" $comp_output] then {
- gcc_fail $testcase "Got Signal 11, $option"
- remote_file build delete $output
- return
- }
-
- # We shouldn't get these because of -w, but just in case.
- if [string match "*cc:*warning:*" $comp_output] then {
- warning "$testcase: (with warnings) $option"
- send_log "$comp_output\n"
- unresolved "$testcase, $option"
- remote_file build delete $output
- return
- }
-
- set comp_output [prune_warnings $comp_output]
-
- set unsupported_message [gcc_check_unsupported_p $comp_output]
- if { $unsupported_message != "" } {
- unsupported "$testcase: $unsupported_message"
- remote_file build delete $output
- return
- }
-
- # remove any leftover LF/CR to make sure any output is legit
- regsub -all -- "\[\r\n\]*" $comp_output "" comp_output
- # If any message remains, we fail.
- if ![string match "" $comp_output] then {
- gcc_fail $testcase $option
- remote_file build delete $output
- return
- }
-
- gcc_pass $testcase $option
+ gcc_check_compile $testcase $option $output $comp_output
remote_file build delete $output
}
@@ -201,57 +164,17 @@ proc c-torture-execute { src args } {
}
set comp_output [gcc_target_compile "$src" "${execname}" executable $options];
- # Set a few common compiler messages.
- set fatal_signal "*cc: Internal compiler error: program*got fatal signal"
-
- if [string match "$fatal_signal 6" $comp_output] then {
- gcc_fail $testcase "Got Signal 6, $option"
+ if ![gcc_check_compile "$testcase compilation" $option $execname $comp_output] {
+ unresolved "$testcase execution, $option"
remote_file build delete $execname
continue
}
-
- if [string match "$fatal_signal 11" $comp_output] then {
- gcc_fail $testcase "Got Signal 11, $option"
- remote_file build delete $execname
- continue
- }
-
- # We shouldn't get these because of -w, but just in case.
- if [string match "*cc:*warning:*" $comp_output] then {
- warning "$testcase: (with warnings) $option"
- send_log "$comp_output\n"
- unresolved "$testcase, $option"
- remote_file build delete $execname
- continue
- }
-
- set comp_output [prune_warnings $comp_output]
-
- set unsupported_message [gcc_check_unsupported_p $comp_output]
-
- if { $unsupported_message != "" } {
- unsupported "$testcase: $unsupported_message"
- continue
- } elseif ![file exists $execname] {
- if ![is3way] {
- fail "$testcase compilation, $option"
- untested "$testcase execution, $option"
- continue
- } else {
- # FIXME: since we can't test for the existance of a remote
- # file without short of doing an remote file list, we assume
- # that since we got no output, it must have compiled.
- pass "$testcase compilation, $option"
- }
- } else {
- pass "$testcase compilation, $option"
- }
# See if this source file uses "long long" types, if it does, and
# no_long_long is set, skip execution of the test.
if [target_info exists no_long_long] then {
if [expr [search_for $src "long long"]] then {
- untested "$testcase execution, $option"
+ unsupported "$testcase execution, $option"
continue
}
}
diff --git a/gcc/testsuite/lib/chill.exp b/gcc/testsuite/lib/chill.exp
index bd8c4f64f2b..716021146f5 100644
--- a/gcc/testsuite/lib/chill.exp
+++ b/gcc/testsuite/lib/chill.exp
@@ -1,365 +1 @@
-#
-# Expect script for Chill Regression Tests
-# Copyright (C) 1993, 1996, 1997 Free Software Foundation
-#
-# This file is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#
-# Written by Jeffrey Wheat (cassidy@cygnus.com)
-#
-
-#
-# chill support library procedures and testsuite specific instructions
-#
-
-#
-# default_chill_version
-# extract and print the version number of the chill compiler
-# exits if compiler does not exist
-#
-proc default_chill_version { } {
- global GCC_UNDER_TEST
-
- # ignore any arguments after the command
- set compiler [lindex $GCC_UNDER_TEST 0]
-
- # verify that the compiler exists
- if {[which $compiler] != 0} then {
- set tmp [ exec $compiler -v ]
- regexp "version.*$" $tmp version
-
- if [info exists version] then {
- clone_output "[which $compiler] $version\n"
- }
- } else {
- warning "$compiler does not exist"
- exit -1
- }
-}
-
-#
-# chill_compile
-# compile the specified file
-#
-# returns values:
-# return 0 on success
-# return 1 on failure with $result containing compiler output
-# exit with -1 if compiler doesn't exist
-#
-# verbosity output:
-# 1 - indicate compile in progress
-# 2 - indicate compile, target name
-# 3 - indicate compile, target name, exec command, and result
-#
-proc chill_compile { src obj } {
- global GCC_UNDER_TEST
- global CFLAGS
-
- global errno
- global result
- global verbose
-
- global subdir
- global tmpdir
-
- set errno 0
- set cflags $CFLAGS
- set dumpfile [file rootname $obj].cmp ;# name of file to dump stderr in
-
- # verify that the compiler exists
- if { [which $GCC_UNDER_TEST] == 0 } then {
- warning "$GCC_UNDER_TEST does not exist"
- exit -1
- }
-
- if { $verbose == 1 } then {
- send_user "Compiling... "
- } else {
- verbose " - CMPL: Compiling [file tail $src]" 2
- }
-
- # if object type is a grt file, then only build a grant file
- if [string match "*.grt" $obj] then {
- set cflags [concat $cflags -fgrant-only]
- }
-
- # build command line
- set commandline "$GCC_UNDER_TEST $cflags -I$subdir -c $src"
-
- # write command line to logfile
- send_log "\n### EXEC: $commandline\n"
-
- # tell us whats going on if verbose
- verbose "### EXEC: $commandline" 3
-
- # exec the compiler with the appropriate flags
- set errno [catch "exec $commandline" result]
-
- # dump compiler's stderr output into $dumpfile - this is a gross hack
- set dumpfile [open $dumpfile w+]; puts $dumpfile $result; close $dumpfile
-
- # log any compiler output unless its null
- if ![string match "" $result] then { send_log "\n$result\n" }
- unset cflags
- return
-}
-
-#
-# chill_link
-# link the specified files
-#
-# returns values:
-# return 0 on success
-# return 1 on failure with $result containing compiler output
-# exit with -1 if compiler doesn't exist
-#
-# verbosity output:
-# 1 - indicate linking in progress
-# 2 - indicate linking, target name
-# 3 - indicate linking, target name, exec command, and result
-#
-proc chill_link { target } {
- global GCC_UNDER_TEST
- global CFLAGS
-
- global errno
- global result
- global verbose
- global tmptarget
-
- global crt0
- global libs
- global objs
-
- set errno 0
-
- # verify that the compiler exists
- if { [which $GCC_UNDER_TEST] == 0 } then {
- warning "$GCC_UNDER_TEST does not exist"
- exit -1
- }
-
- if { $verbose == 1 } then {
- send_user "Linking... "
- } else {
- verbose " - LINK: Linking [file tail $target]" 2
- }
-
- # verify that the object exists
- if ![file exists $target.o] then {
- set errno 1
- set result "file $target.o doesn'timeout exist"
- return
- }
-
- # build command line
- set commandline "$GCC_UNDER_TEST $CFLAGS -o $target $target.o $objs $crt0 $libs"
-
- # write command line to logfile
- send_log "\n### EXEC: $commandline\n"
-
- # tell us whats going on if we are verbose
- verbose "### EXEC: $commandline" 3
-
- # link the objects, sending any linker output to $result
- set errno [catch "exec $commandline > $tmptarget.lnk" result]
-
- # log any linker output unless its null
- if ![string match "" $result] then { send_log "\n$result\n" }
- return
-}
-
-#
-# default_chill_start
-#
-proc default_chill_start { } {
- global srcdir
- global subdir
- global tmpdir
- global verbose
-
- if { $verbose > 1 } then { send_user "Configuring testsuite... " }
-
- # tmpdir is obtained from $objdir/site.exp. if not, set it to /tmp
- if ![info exists tmpdir] then { set tmpdir /tmp }
-
- # save and convert $srcdir to an absolute pathname, stomp on the old value
- # stomp on $subdir and set to the absolute path to the subdirectory
- global osrcdir; set osrcdir $srcdir; set srcdir [cd $srcdir; pwd]
- global osubdir; set osubdir $subdir; set subdir $srcdir/$subdir
-
- # cd the temporary directory, $tmpdir
- cd $tmpdir; verbose "### PWD: [pwd]" 5
-
- # copy init files to the tmpdir
- foreach initfile [glob -nocomplain $subdir/*.init] {
- set targfile $tmpdir/[file tail [file rootname $initfile]]
- verbose "### EXEC: cp $initfile $targfile" 5
- if [catch "exec cp $initfile $targfile"] then {
- send_user "\nConfigure failed.\n"
- exit -1
- }
- }
- if { $verbose > 1 } then { send_user "Configuring finished.\n" }
-}
-
-#
-# default_chill_exit
-#
-#
-proc default_chill_exit { } {
- global srcdir
- global objdir
- global tmpdir
- global osrcdir
- global osubdir
-
- # reset directory variables
- set srcdir $osrcdir; set subdir $osubdir
-
- # remove all generated targets and objects
- verbose "### EXEC: rm -f $tmpdir/*" 3
- catch "exec rm -f $tmpdir/*" result
-
- # change back to the main object directory
- cd $objdir
- verbose "### SANITY: [pwd]" 5
-}
-
-#
-# chill_diff
-# compare two files line-by-line
-#
-# returns values:
-# return 0 on success
-# return 1 if different
-# return -1 if output file doesn't exist
-#
-# verbosity output:
-# 1 - indicate diffing in progress
-# 2 - indicate diffing, target names
-# 3 - indicate diffing, target names, and result
-#
-proc chill_diff { file_1 file_2 } {
- global errno
- global result
- global target
- global tmptarget
-
- global verbose
-
- set eof -1
- set errno 0
- set differences 0
-
- if { $verbose == 1 } then {
- send_user "Diffing... "
- } else {
- verbose " - DIFF: Diffing [file tail $file_1] [file tail $file_2]" 2
- }
-
- # write command line to logfile
- send_log "### EXEC: diff $file_1 $file_2\n"
-
- # tell us whats going on if we are verbose
- verbose "### EXEC: diff $file_1 $file_2" 3
-
- # verify file exists and open it
- if [file exists $file_1] then {
- set file_a [open $file_1 r]
- } else {
- set errno -1; set result "$file_1 doesn't exist"
- return
- }
-
- # verify file exists and is not zero length, and then open it
- if [file exists $file_2] then {
- if [file size $file_2]!=0 then {
- set file_b [open $file_2 r]
- } else {
- set errno -1; set result "$file_2 is zero bytes"; return
- }
- } else {
- set errno -1; set result "$file_2 doesn't exist"; return
- }
-
- # spoof the diff routine
- lappend list_a $target
-
- while { [gets $file_a line] != $eof } {
- if [regexp "^#.*$" $line] then {
- continue
- } else {
- lappend list_a $line
- }
- }
- close $file_a
-
- # spoof the diff routine
- lappend list_b $target
-
- while { [gets $file_b line] != $eof } {
- if [regexp "^#.*$" $line] then {
- continue
- } else {
- # use [file tail $line] to strip off pathname
- lappend list_b [file tail $line]
- }
- }
- close $file_b
-
- for { set i 0 } { $i < [llength $list_a] } { incr i } {
- set line_a [lindex $list_a $i]
- set line_b [lindex $list_b $i]
-
- if [string compare $line_a $line_b] then {
- set errno 1
- set count [expr $i+1]
- set linenum [format %dc%d $count $count]
- verbose "$linenum" 3
- verbose "< $line_a" 3
- verbose "---" 3
- verbose "> $line_b" 3
-
- send_log "$file_1: < $count: $line_a\n"
- send_log "$file_2: > $count: $line_b\n"
- set result "differences found"
- }
- }
- return
-}
-
-#
-# chill_fail
-# a wrapper around the framework fail proc
-#
-proc chill_fail { target result } {
- global verbose
-
- if { $verbose == 1 } then { send_user "\n" }
- fail $target
- verbose "--------------------------------------------------" 3
- verbose "### RESULT: $result" 3
-}
-
-#
-# chill_pass
-# a wrapper around the framework fail proc
-#
-proc chill_pass { target } {
- global verbose
-
- if { $verbose == 1 } then { send_user "\n" }
- pass $target
-}
+ set result "file $target.o doesn't exist"
diff --git a/gcc/testsuite/lib/f-torture.exp b/gcc/testsuite/lib/f-torture.exp
index 2be2b3abef7..6596b6f2354 100644
--- a/gcc/testsuite/lib/f-torture.exp
+++ b/gcc/testsuite/lib/f-torture.exp
@@ -1,4 +1,4 @@
-# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997 Free Software Foundation, Inc.
+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998 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
diff --git a/gcc/testsuite/lib/g++.exp b/gcc/testsuite/lib/g++.exp
index b0f6039544c..0cc681f3293 100644
--- a/gcc/testsuite/lib/g++.exp
+++ b/gcc/testsuite/lib/g++.exp
@@ -125,7 +125,6 @@ proc g++_init { args } {
if ![is_remote host] {
lappend ALWAYS_CXXFLAGS "additional_flags=[g++_include_flags]";
lappend ALWAYS_CXXFLAGS "ldflags=[g++_link_flags]";
- lappend ALWAYS_CXXFLAGS "incdir=$base_dir/../include"
}
if [info exists TOOL_OPTIONS] {
@@ -157,6 +156,12 @@ proc g++_target_compile { source dest type options } {
set options [concat $options "$ALWAYS_CXXFLAGS"];
+ if { [regexp "(^| )-frepo( |$)" $options] && \
+ [regexp "\.o(|bj)$" $dest] } then {
+ regsub "\.o(|bj)$" $dest ".rpo" rponame
+ exec rm -f $rponame
+ }
+
return [target_compile $source $dest $type $options]
}
diff --git a/gcc/testsuite/lib/gcc.exp b/gcc/testsuite/lib/gcc.exp
index ac11d0ba26d..44dc08a6d4e 100644
--- a/gcc/testsuite/lib/gcc.exp
+++ b/gcc/testsuite/lib/gcc.exp
@@ -1,268 +1,55 @@
-# Copyright (C) 1992, 1993, 1994, 1996, 1997 Free Software Foundation, Inc.
+# Copyright (C) 1992, 1993, 1994, 1996, 1997, 1999 Free Software Foundation, Inc.
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-# Please email any bugs, comments, and/or additions to this file to:
-# bug-gcc@prep.ai.mit.edu
+# Reports pass/fail for a gcc compilation and returns true/false.
+proc gcc_check_compile {testcase option objname gcc_output} {
-# This file was written by Rob Savoye (rob@cygnus.com)
-# Currently maintained by Doug Evans (dje@cygnus.com)
-
-# This file is loaded by the tool init file (eg: unix.exp). It provides
-# default definitions for gcc_start, etc. and other supporting cast members.
-
-# These globals are used by gcc_start if no compiler arguments are provided.
-# They are also used by the various testsuites to define the environment:
-# where to find stdio.h, libc.a, etc.
-
-# we want to use libgloss so we can get find_gcc.
-load_lib libgloss.exp
-
-#
-# GCC_UNDER_TEST is the compiler under test.
-#
-
-#
-# default_gcc_version -- extract and print the version number of the compiler
-#
-
-proc default_gcc_version { } {
- global GCC_UNDER_TEST
-
- gcc_init;
-
- # ignore any arguments after the command
- set compiler [lindex $GCC_UNDER_TEST 0]
-
- if ![is_remote host] {
- set compiler_name [which $compiler];
- } else {
- set compiler_name $compiler;
- }
-
- # verify that the compiler exists
- if { $compiler_name != 0 } then {
- set tmp [remote_exec host "$compiler -v"]
- set status [lindex $tmp 0];
- set output [lindex $tmp 1];
- regexp "version.*$" $output version
- if { $status == 0 && [info exists version] } then {
- clone_output "$compiler_name $version\n"
- } else {
- clone_output "Couldn't determine version of $compiler_name: $output\n"
- }
- } else {
- # compiler does not exist (this should have already been detected)
- warning "$compiler does not exist"
- }
-}
-
-#
-# Call gcc_version. We do it this way so we can override it if needed.
-#
-proc gcc_version { } {
- default_gcc_version;
-}
-
-#
-# gcc_init -- called at the start of each .exp script.
-#
-# There currently isn't much to do, but always using it allows us to
-# make some enhancements without having to go back and rewrite the scripts.
-#
-
-set gcc_initialized 0
-
-proc gcc_init { args } {
- global tmpdir
- global libdir
- global gluefile wrap_flags
- global gcc_initialized
- global GCC_UNDER_TEST
- global TOOL_EXECUTABLE
-
- if { $gcc_initialized == 1 } { return; }
-
- if ![info exists GCC_UNDER_TEST] {
- if [info exists TOOL_EXECUTABLE] {
- set GCC_UNDER_TEST $TOOL_EXECUTABLE;
- } else {
- set GCC_UNDER_TEST "[find_gcc]"
- }
- }
-
- if ![info exists tmpdir] then {
- set tmpdir /tmp
- }
- if { [target_info needs_status_wrapper]!="" && ![info exists gluefile] } {
- set gluefile ${tmpdir}/testglue.o;
- set result [build_wrapper $gluefile];
- if { $result != "" } {
- set gluefile [lindex $result 0];
- set wrap_flags [lindex $result 1];
- } else {
- unset gluefile
- }
- }
-}
-
-proc gcc_target_compile { source dest type options } {
- global tmpdir;
- global gluefile wrap_flags;
- global GCC_UNDER_TEST
- global TOOL_OPTIONS
-
- if { [target_info needs_status_wrapper]!="" && [info exists gluefile] } {
- lappend options "libs=${gluefile}"
- lappend options "ldflags=$wrap_flags"
+ set fatal_signal "*cc: Internal compiler error: program*got fatal signal"
+
+ if [string match "$fatal_signal 6" $gcc_output] then {
+ gcc_fail $testcase "Got Signal 6, $option"
+ return 0
}
- if [target_info exists gcc,stack_size] {
- lappend options "additional_flags=-DSTACK_SIZE=[target_info gcc,stack_size]"
+ if [string match "$fatal_signal 11" $gcc_output] then {
+ gcc_fail $testcase "Got Signal 11, $option"
+ return 0
}
- if [target_info exists gcc,no_trampolines] {
- lappend options "additional_flags=-DNO_TRAMPOLINES"
- }
- if [target_info exists gcc,no_label_values] {
- lappend options "additional_flags=-DNO_LABEL_VALUES"
- }
- if [info exists TOOL_OPTIONS] {
- lappend options "additional_flags=$TOOL_OPTIONS"
- }
- if [target_info exists gcc,no_varargs] {
- lappend options "additional_flags=-DNO_VARARGS"
- }
- lappend options "compiler=$GCC_UNDER_TEST"
- return [target_compile $source $dest $type $options]
-}
-
-#
-# gcc_pass -- utility to record a testcase passed
-#
-proc gcc_pass { testcase cflags } {
- if { "$cflags" == "" } {
- pass "$testcase"
- } else {
- pass "$testcase, $cflags"
+ # We shouldn't get these because of -w, but just in case.
+ if [string match "*cc:*warning:*" $gcc_output] then {
+ warning "$testcase: (with warnings) $option"
+ send_log "$gcc_output\n"
+ unresolved "$testcase, $option"
+ return 0
}
-}
-#
-# gcc_fail -- utility to record a testcase failed
-#
+ set gcc_output [prune_warnings $gcc_output]
-proc gcc_fail { testcase cflags } {
- if { "$cflags" == "" } {
- fail "$testcase"
- } else {
- fail "$testcase, $cflags"
+ set unsupported_message [gcc_check_unsupported_p $gcc_output]
+ if { $unsupported_message != "" } {
+ unsupported "$testcase: $unsupported_message"
+ return 0
}
-}
-
-#
-# gcc_finish -- called at the end of every .exp script that calls gcc_init
-#
-# The purpose of this proc is to hide all quirks of the testing environment
-# from the testsuites. It also exists to undo anything that gcc_init did
-# (that needs undoing).
-#
-proc gcc_finish { } {
- # The testing harness apparently requires this.
- global errorInfo;
+ # remove any leftover LF/CR to make sure any output is legit
+ regsub -all -- "\[\r\n\]*" $gcc_output "" gcc_output
- if [info exists errorInfo] then {
- unset errorInfo
+ # If any message remains, we fail.
+ if ![string match "" $gcc_output] then {
+ gcc_fail $testcase $option
+ return 0
}
- # Might as well reset these (keeps our caller from wondering whether
- # s/he has to or not).
- global prms_id bug_id
- set prms_id 0
- set bug_id 0
-}
-
-proc gcc_exit { } {
- global gluefile;
-
- if [info exists gluefile] {
- file_on_build delete $gluefile;
- unset gluefile;
+ # fail if the desired object file doesn't exist.
+ # FIXME: there's no way of checking for existence on a remote host.
+ if {$objname != "" && ![is3way] && ![file exists $objname]} {
+ gcc_fail $testcase $option
+ return 0
}
-}
-
-# If this is an older version of dejagnu (without runtest_file_p),
-# provide one and assume the old syntax: foo1.exp bar1.c foo2.exp bar2.c.
-# This can be deleted after next dejagnu release.
-if { [info procs runtest_file_p] == "" } then {
- proc runtest_file_p { runtests testcase } {
- if { $runtests != "" && [regexp "\[.\]\[cC\]" $runtests] } then {
- if { [lsearch $runtests [file tail $testcase]] >= 0 } then {
- return 1
- } else {
- return 0
- }
- }
- return 1
- }
+ gcc_pass $testcase $option
+ return 1
}
-# Provide a definition of this if missing (delete after next dejagnu release).
-
-if { [info procs prune_warnings] == "" } then {
- proc prune_warnings { text } {
- return $text
- }
-}
-
-# Utility used by mike-gcc.exp and c-torture.exp.
-# Check the compiler(/assembler/linker) output for text indicating that
-# the testcase should be marked as "unsupported".
-#
-# When dealing with a large number of tests, it's difficult to weed out the
-# ones that are too big for a particular cpu (eg: 16 bit with a small amount
-# of memory). There are various ways to deal with this. Here's one.
-# Fortunately, all of the cases where this is likely to happen will be using
-# gld so we can tell what the error text will look like.
-
-proc ${tool}_check_unsupported_p { output } {
- if [regexp "(^|\n)\[^\n\]*: region \[^\n\]* is full" $output] {
- return "memory full"
- }
- return ""
-}
-
-# Prune messages from gcc that aren't useful.
-
-proc prune_gcc_output { text } {
- #send_user "Before:$text\n"
- regsub -all "(^|\n)\[^\n\]*: In (function|method) \[^\n\]*" $text "" text
- regsub -all "(^|\n)\[^\n\]*: At top level:\[^\n\]*" $text "" text
-
- # It would be nice to avoid passing anything to gcc that would cause it to
- # issue these messages (since ignoring them seems like a hack on our part),
- # but that's too difficult in the general case. For example, sometimes
- # you need to use -B to point gcc at crt0.o, but there are some targets
- # that don't have crt0.o.
- regsub -all "(^|\n)\[^\n\]*file path prefix \[^\n\]* never used" $text "" text
- regsub -all "(^|\n)\[^\n\]*linker input file unused since linking not done" $text "" text
-
- #send_user "After:$text\n"
-
- return $text
-}
diff --git a/gcc/testsuite/lib/objc-torture.exp b/gcc/testsuite/lib/objc-torture.exp
index 517d6ca5df4..5eadd489c47 100644
--- a/gcc/testsuite/lib/objc-torture.exp
+++ b/gcc/testsuite/lib/objc-torture.exp
@@ -169,7 +169,7 @@ proc objc-torture-execute { src } {
verbose "Testing $testcase, $option" 1
set options ""
- lappend options "additional_flags=-w $option"
+ lappend options "additional_flags=-w $option -I${srcdir}/../../libobjc"
set comp_output [objc_target_compile "$src" "$executable" executable $options];
# Set a few common compiler messages.
diff --git a/gcc/testsuite/lib/old-dejagnu.exp b/gcc/testsuite/lib/old-dejagnu.exp
index 30d2236d423..bfa29b0643c 100644
--- a/gcc/testsuite/lib/old-dejagnu.exp
+++ b/gcc/testsuite/lib/old-dejagnu.exp
@@ -119,11 +119,7 @@ proc old-dejagnu-stat { } {
# Returns 0 if successful, 1 if their were any errors.
# PROG is the full path name of the file to compile.
#
-# CFLAGS_VAR is the name of the global variable containing compiler flags.
-# We ignore this now.
-#
-# CFLAGS is the options to always pass to the compiler.
-# This is also ignored.
+# CFLAGSX is the options to always pass to the compiler.
#
# DEFAULT_CFLAGS are additional options if the testcase has none.
#
@@ -137,7 +133,7 @@ proc old-dejagnu-stat { } {
#
# Think of "cflags" here as "compiler flags", not "C compiler flags".
-proc old-dejagnu { compiler prog cflagsx default_cflags libs } {
+proc old-dejagnu { compiler prog name cflagsx default_cflags libs } {
global verbose
global tool
global subdir ;# eg: g++.old-dejagnu
@@ -196,9 +192,11 @@ proc old-dejagnu { compiler prog cflagsx default_cflags libs } {
# is right. If no such Special Options are found, $default_cflags is used.
# FIXME: Can there be multiple lines of these?
#
-# Other keywords: "Build don't link:", "Build don't run:".
+# Other keywords: "Build don't link:", "Build don't run:", "Build then link:",
+# "Additional sources: <file>.cc ..."
- set name "[file tail [file dirname $prog]]/[file tail $prog]"
+# $name is now passed in.
+# set name "[file tail [file dirname $prog]]/[file tail $prog]"
set tmp [grep $prog "FIXME -.*"]
if ![string match "" $tmp] then {
@@ -225,6 +223,16 @@ proc old-dejagnu { compiler prog cflagsx default_cflags libs } {
lappend cflags "additional_flags=$cflagsx"
}
+ set tmp [lindex [grep $prog "Additional sources: .*"] 0]
+ regsub -all "\n\[^\n\]+(\n|$)" $tmp "\n" tmp
+ set tmp [string trim $tmp]
+ if ![string match "" $tmp] then {
+ regsub "^.*Additional.*sources:" $tmp "" tmp
+ regsub -all " " $tmp " [file dirname $prog]/" tmp
+ lappend cflags "additional_flags=$tmp"
+ verbose "Adding sources $tmp"
+ }
+
lappend cflags "compiler=$compiler"
regsub -all "\[./\]" "$name" "-" output;
@@ -239,6 +247,15 @@ proc old-dejagnu { compiler prog cflagsx default_cflags libs } {
verbose "Will compile $prog to object" 3
}
+ set tmp [lindex [grep $prog "Build then link:"] 0]
+ if ![string match "" $tmp] then {
+ set compile_type "object"
+ set runflag 2
+ set final_output "$output"
+ set output "$tmpdir/[file tail [file rootname $prog]].o"
+ verbose "Will compile $prog to object, then link it" 3
+ }
+
set tmp [lindex [grep $prog "Build don.t run:"] 0]
if ![string match "" $tmp] then {
set runflag 0
@@ -399,6 +416,11 @@ proc old-dejagnu { compiler prog cflagsx default_cflags libs } {
# we can't run a.out when the compilation fails.
remote_file build delete $output
set comp_output [${tool}_target_compile $prog $output $compile_type $cflags]
+ if { $runflag == 2 && [file exists $output] } then {
+ set runflag 0
+ set comp_output [concat $comp_output [${tool}_target_compile $output $final_output "executable" $cflags]]
+ set output $final_output
+ }
# Delete things like "ld.so: warning" messages.
set comp_output [prune_warnings $comp_output]
@@ -510,6 +532,7 @@ proc old-dejagnu { compiler prog cflagsx default_cflags libs } {
regsub -all "(^|\n)\[^\n\]*: At top level:\[^\n\]*" $comp_output "" comp_output
regsub -all "(^|\n)\[^\n\]*file path prefix \[^\n\]* never used" $comp_output "" comp_output
regsub -all "(^|\n)\[^\n\]*linker input file unused since linking not done" $comp_output "" comp_output
+ regsub -all "(^|\n)collect: re(compiling|linking)\[^\n\]*" $comp_output "" comp_output
set unsupported_message [${tool}_check_unsupported_p $comp_output]
if { $unsupported_message != "" } {
diff --git a/gcc/texinfo.tex b/gcc/texinfo.tex
index 4327aa3ecc2..475145dc7ff 100644
--- a/gcc/texinfo.tex
+++ b/gcc/texinfo.tex
@@ -1,5 +1,5 @@
% texinfo.tex -- TeX macros to handle Texinfo files.
-% $Id: texinfo.tex,v 1.5 1998/06/29 21:40:12 law Exp $
+% $Id: texinfo.tex,v 1.6 1998/12/16 20:58:28 law Exp $
%
% Copyright (C) 1985, 86, 88, 90, 91, 92, 93, 94, 95, 96, 97, 98
% Free Software Foundation, Inc.
@@ -58,7 +58,7 @@
% This automatically updates the version number based on RCS.
\def\deftexinfoversion$#1: #2 ${\def\texinfoversion{#2}}
-\deftexinfoversion$Revision: 1.5 $
+\deftexinfoversion$Revision: 1.6 $
\message{Loading texinfo package [Version \texinfoversion]:}
% If in a .fmt file, print the version number
diff --git a/gcc/tlink.c b/gcc/tlink.c
index a4c5b5311cd..9f058c9b284 100644
--- a/gcc/tlink.c
+++ b/gcc/tlink.c
@@ -18,13 +18,15 @@ 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
#include "config.h"
#include "system.h"
#include "hash.h"
#include "demangle.h"
#include "toplev.h"
+#include "collect2.h"
#define MAX_ITERATIONS 17
@@ -32,8 +34,6 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#define obstack_chunk_alloc xmalloc
#define obstack_chunk_free free
-extern char * xmalloc PARAMS((unsigned));
-
/* Defined in collect2.c. */
extern int vflag, debug;
extern char *ldout;
@@ -47,7 +47,8 @@ extern int prepends_underscore;
static int tlink_verbose;
-/* Hash table code. */
+/* Hash table boilerplate for working with hash.[ch]. We have hash tables
+ for symbol names, file names, and demangled symbols. */
typedef struct symbol_hash_entry
{
@@ -75,11 +76,46 @@ typedef struct demangled_hash_entry
static struct hash_table symbol_table;
+static struct hash_entry * symbol_hash_newfunc PARAMS ((struct hash_entry *,
+ struct hash_table *,
+ hash_table_key));
+static struct symbol_hash_entry * symbol_hash_lookup PARAMS ((const char *,
+ boolean));
+static struct hash_entry * file_hash_newfunc PARAMS ((struct hash_entry *,
+ struct hash_table *,
+ hash_table_key));
+static struct file_hash_entry * file_hash_lookup PARAMS ((const char *));
+static struct hash_entry * demangled_hash_newfunc PARAMS ((struct hash_entry *,
+ struct hash_table *,
+ hash_table_key));
+static struct demangled_hash_entry *
+ demangled_hash_lookup PARAMS ((const char *, boolean));
+static void symbol_push PARAMS ((symbol *));
+static symbol * symbol_pop PARAMS ((void));
+static void file_push PARAMS ((file *));
+static file * file_pop PARAMS ((void));
+static void tlink_init PARAMS ((void));
+static int tlink_execute PARAMS ((char *, char **, char *));
+static char * frob_extension PARAMS ((char *, const char *));
+static char * obstack_fgets PARAMS ((FILE *, struct obstack *));
+static char * tfgets PARAMS ((FILE *));
+static char * pfgets PARAMS ((FILE *));
+static void freadsym PARAMS ((FILE *, file *, int));
+static void read_repo_file PARAMS ((file *));
+static void maybe_tweak PARAMS ((char *, file *));
+static int recompile_files PARAMS ((void));
+static int read_repo_files PARAMS ((char **));
+static void demangle_new_symbols PARAMS ((void));
+static int scan_linker_output PARAMS ((const char *));
+
+/* Create a new entry for the symbol hash table.
+ Passed to hash_table_init. */
+
static struct hash_entry *
symbol_hash_newfunc (entry, table, string)
struct hash_entry *entry;
struct hash_table *table;
- const char *string;
+ hash_table_key string;
{
struct symbol_hash_entry *ret = (struct symbol_hash_entry *) entry;
if (ret == NULL)
@@ -89,8 +125,6 @@ symbol_hash_newfunc (entry, table, string)
if (ret == NULL)
return NULL;
}
- ret = ((struct symbol_hash_entry *)
- hash_newfunc ((struct hash_entry *) ret, table, string));
ret->file = NULL;
ret->chosen = 0;
ret->tweaking = 0;
@@ -98,22 +132,28 @@ symbol_hash_newfunc (entry, table, string)
return (struct hash_entry *) ret;
}
+/* Look up an entry in the symbol hash table. */
+
static struct symbol_hash_entry *
symbol_hash_lookup (string, create)
const char *string;
boolean create;
{
return ((struct symbol_hash_entry *)
- hash_lookup (&symbol_table, string, create, true));
+ hash_lookup (&symbol_table, (hash_table_key) string,
+ create, &string_copy));
}
static struct hash_table file_table;
+/* Create a new entry for the file hash table.
+ Passed to hash_table_init. */
+
static struct hash_entry *
file_hash_newfunc (entry, table, string)
struct hash_entry *entry;
struct hash_table *table;
- const char *string;
+ hash_table_key string;
{
struct file_hash_entry *ret = (struct file_hash_entry *) entry;
if (ret == NULL)
@@ -123,8 +163,6 @@ file_hash_newfunc (entry, table, string)
if (ret == NULL)
return NULL;
}
- ret = ((struct file_hash_entry *)
- hash_newfunc ((struct hash_entry *) ret, table, string));
ret->args = NULL;
ret->dir = NULL;
ret->main = NULL;
@@ -132,21 +170,27 @@ file_hash_newfunc (entry, table, string)
return (struct hash_entry *) ret;
}
+/* Look up an entry in the file hash table. */
+
static struct file_hash_entry *
file_hash_lookup (string)
const char *string;
{
return ((struct file_hash_entry *)
- hash_lookup (&file_table, string, true, true));
+ hash_lookup (&file_table, (hash_table_key) string, true,
+ &string_copy));
}
static struct hash_table demangled_table;
+/* Create a new entry for the demangled name hash table.
+ Passed to hash_table_init. */
+
static struct hash_entry *
demangled_hash_newfunc (entry, table, string)
struct hash_entry *entry;
struct hash_table *table;
- const char *string;
+ hash_table_key string;
{
struct demangled_hash_entry *ret = (struct demangled_hash_entry *) entry;
if (ret == NULL)
@@ -156,19 +200,20 @@ demangled_hash_newfunc (entry, table, string)
if (ret == NULL)
return NULL;
}
- ret = ((struct demangled_hash_entry *)
- hash_newfunc ((struct hash_entry *) ret, table, string));
ret->mangled = NULL;
return (struct hash_entry *) ret;
}
+/* Look up an entry in the demangled name hash table. */
+
static struct demangled_hash_entry *
demangled_hash_lookup (string, create)
const char *string;
boolean create;
{
return ((struct demangled_hash_entry *)
- hash_lookup (&demangled_table, string, create, true));
+ hash_lookup (&demangled_table, (hash_table_key) string,
+ create, &string_copy));
}
/* Stack code. */
@@ -246,14 +291,19 @@ file_pop ()
/* Other machinery. */
+/* Initialize the tlink machinery. Called from do_tlink. */
+
static void
tlink_init ()
{
char *p;
- hash_table_init (&symbol_table, symbol_hash_newfunc);
- hash_table_init (&file_table, file_hash_newfunc);
- hash_table_init (&demangled_table, demangled_hash_newfunc);
+ hash_table_init (&symbol_table, symbol_hash_newfunc, &string_hash,
+ &string_compare);
+ hash_table_init (&file_table, file_hash_newfunc, &string_hash,
+ &string_compare);
+ hash_table_init (&demangled_table, demangled_hash_newfunc,
+ &string_hash, &string_compare);
obstack_begin (&symbol_stack_obstack, 0);
obstack_begin (&file_stack_obstack, 0);
@@ -282,7 +332,8 @@ tlink_execute (prog, argv, redir)
static char *
frob_extension (s, ext)
- char *s, *ext;
+ char *s;
+ const char *ext;
{
char *p = rindex (s, '/');
if (! p)
@@ -325,6 +376,12 @@ pfgets (stream)
/* Real tlink code. */
+/* Subroutine of read_repo_file. We are reading the repo file for file F,
+ which is coming in on STREAM, and the symbol that comes next in STREAM
+ is offerred, chosen or provided if CHOSEN is 0, 1 or 2, respectively.
+
+ XXX "provided" is unimplemented, both here and in the compiler. */
+
static void
freadsym (stream, f, chosen)
FILE *stream;
@@ -340,12 +397,16 @@ freadsym (stream, f, chosen)
if (sym->file == NULL)
{
+ /* We didn't have this symbol already, so we choose this file. */
+
symbol_push (sym);
sym->file = f;
sym->chosen = chosen;
}
else if (chosen)
{
+ /* We want this file; cast aside any pretender. */
+
if (sym->chosen && sym->file != f)
{
if (sym->chosen == 1)
@@ -362,15 +423,18 @@ freadsym (stream, f, chosen)
}
}
+/* Read in the repo file denoted by F, and record all its information. */
+
static void
read_repo_file (f)
file *f;
{
char c;
- FILE *stream = fopen (f->root.string, "r");
+ FILE *stream = fopen ((char*) f->root.key, "r");
if (tlink_verbose >= 2)
- fprintf (stderr, "collect: reading %s\n", f->root.string);
+ fprintf (stderr, "collect: reading %s\n",
+ (char*) f->root.key);
while (fscanf (stream, "%c ", &c) == 1)
{
@@ -404,6 +468,11 @@ read_repo_file (f)
f->dir = ".";
}
+/* We might want to modify LINE, which is a symbol line from file F. We do
+ this if either we saw an error message referring to the symbol in
+ question, or we have already allocated the symbol to another file and
+ this one wants to emit it as well. */
+
static void
maybe_tweak (line, f)
char *line;
@@ -424,6 +493,11 @@ maybe_tweak (line, f)
}
}
+/* Update the repo files for each of the object files we have adjusted and
+ recompile.
+
+ XXX Should this use collect_execute instead of system? */
+
static int
recompile_files ()
{
@@ -432,8 +506,8 @@ recompile_files ()
while ((f = file_pop ()) != NULL)
{
char *line, *command;
- FILE *stream = fopen (f->root.string, "r");
- char *outname = frob_extension (f->root.string, ".rnw");
+ FILE *stream = fopen ((char*) f->root.key, "r");
+ char *outname = frob_extension ((char*) f->root.key, ".rnw");
FILE *output = fopen (outname, "w");
while ((line = tfgets (stream)) != NULL)
@@ -448,7 +522,7 @@ recompile_files ()
}
fclose (stream);
fclose (output);
- rename (outname, f->root.string);
+ rename (outname, (char*) f->root.key);
obstack_grow (&temporary_obstack, "cd ", 3);
obstack_grow (&temporary_obstack, f->dir, strlen (f->dir));
@@ -474,6 +548,9 @@ recompile_files ()
return 1;
}
+/* The first phase of processing: determine which object files have
+ .rpo files associated with them, and read in the information. */
+
static int
read_repo_files (object_lst)
char **object_lst;
@@ -499,6 +576,8 @@ read_repo_files (object_lst)
return (symbol_stack != NULL);
}
+/* Add the demangled forms of any new symbols to the hash table. */
+
static void
demangle_new_symbols ()
{
@@ -507,19 +586,23 @@ demangle_new_symbols ()
while ((sym = symbol_pop ()) != NULL)
{
demangled *dem;
- char *p = cplus_demangle (sym->root.string, DMGL_PARAMS | DMGL_ANSI);
+ char *p = cplus_demangle ((char*) sym->root.key,
+ DMGL_PARAMS | DMGL_ANSI);
if (! p)
continue;
dem = demangled_hash_lookup (p, true);
- dem->mangled = sym->root.string;
+ dem->mangled = (char*) sym->root.key;
}
}
+/* Step through the output of the linker, in the file named FNAME, and
+ adjust the settings for each symbol encountered. */
+
static int
scan_linker_output (fname)
- char *fname;
+ const char *fname;
{
FILE *stream = fopen (fname, "r");
char *line;
@@ -530,13 +613,13 @@ scan_linker_output (fname)
symbol *sym;
int end;
- while (*p && ISSPACE (*p))
+ while (*p && ISSPACE ((unsigned char)*p))
++p;
if (! *p)
continue;
- for (q = p; *q && ! ISSPACE (*q); ++q)
+ for (q = p; *q && ! ISSPACE ((unsigned char)*q); ++q)
;
/* Try the first word on the line. */
@@ -584,7 +667,7 @@ scan_linker_output (fname)
{
if (tlink_verbose >= 2)
fprintf (stderr, "collect: tweaking %s in %s\n",
- sym->root.string, sym->file->root.string);
+ (char*) sym->root.key, (char*) sym->file->root.key);
sym->tweaking = 1;
file_push (sym->file);
}
@@ -596,6 +679,15 @@ scan_linker_output (fname)
return (file_stack != NULL);
}
+/* Entry point for tlink. Called from main in collect2.c.
+
+ Iteratively try to provide definitions for all the unresolved symbols
+ mentioned in the linker error messages.
+
+ LD_ARGV is an array of arguments for the linker.
+ OBJECT_LST is an array of object files that we may be able to recompile
+ to provide missing definitions. Currently ignored. */
+
void
do_tlink (ld_argv, object_lst)
char **ld_argv, **object_lst;
diff --git a/gcc/tm.texi b/gcc/tm.texi
index cf11d7b5aff..bed9e0a4ff5 100644
--- a/gcc/tm.texi
+++ b/gcc/tm.texi
@@ -1,4 +1,4 @@
-@c Copyright (C) 1988,89,92,93,94,96,97,1998 Free Software Foundation, Inc.
+@c Copyright (C) 1988,89,92,93,94,96,97,98,1999 Free Software Foundation, Inc.
@c This is part of the GCC manual.
@c For copying conditions, see the file gcc.texi.
@@ -790,15 +790,24 @@ size of an integer.
@findex STACK_BOUNDARY
@item STACK_BOUNDARY
+Define this macro if there is a guaranteed alignment for the stack
+pointer on this machine. The definition is a C expression
+for the desired alignment (measured in bits). This value is used as a
+default if PREFERRED_STACK_BOUNDARY is not defined.
+
+@findex PREFERRED_STACK_BOUNDARY
+@item PREFERRED_STACK_BOUNDARY
Define this macro if you wish to preserve a certain alignment for
the stack pointer. The definition is a C expression
-for the desired alignment (measured in bits).
+for the desired alignment (measured in bits). If STACK_BOUNDARY is
+also defined, this macro must evaluate to a value equal to or larger
+than STACK_BOUNDARY.
-@cindex @code{PUSH_ROUNDING}, interaction with @code{STACK_BOUNDARY}
+@cindex @code{PUSH_ROUNDING}, interaction with @code{PREFERRED_STACK_BOUNDARY}
If @code{PUSH_ROUNDING} is not defined, the stack will always be aligned
-to the specified boundary. If @code{PUSH_ROUNDING} is defined and specifies a
-less strict alignment than @code{STACK_BOUNDARY}, the stack may be
-momentarily unaligned while pushing arguments.
+to the specified boundary. If @code{PUSH_ROUNDING} is defined and specifies
+a less strict alignment than @code{PREFERRED_STACK_BOUNDARY}, the stack may
+be momentarily unaligned while pushing arguments.
@findex FUNCTION_BOUNDARY
@item FUNCTION_BOUNDARY
@@ -864,6 +873,18 @@ The typical use of this macro is to increase alignment for string
constants to be word aligned so that @code{strcpy} calls that copy
constants can be done inline.
+@findex LOCAL_ALIGNMENT
+@item LOCAL_ALIGNMENT (@var{type}, @var{basic-align})
+If defined, a C expression to compute the alignment for a variables in
+the local store. @var{type} is the data type, and @var{basic-align} is
+the alignment that the object would ordinarily have. The value of this
+macro is used instead of that alignment to align the object.
+
+If this macro is not defined, then @var{basic-align} is used.
+
+One use of this macro is to increase alignment of medium-size data to
+make it all fit in fewer cache lines.
+
@findex EMPTY_FIELD_BOUNDARY
@item EMPTY_FIELD_BOUNDARY
Alignment in bits to be given to a structure bit field that follows an
@@ -957,18 +978,18 @@ Like PCC_BITFIELD_TYPE_MATTERS except that its effect is limited to
aligning a bitfield within the structure.
@findex ROUND_TYPE_SIZE
-@item ROUND_TYPE_SIZE (@var{struct}, @var{size}, @var{align})
-Define this macro as an expression for the overall size of a structure
-(given by @var{struct} as a tree node) when the size computed from the
-fields is @var{size} and the alignment is @var{align}.
+@item ROUND_TYPE_SIZE (@var{type}, @var{computed}, @var{specified})
+Define this macro as an expression for the overall size of a type
+(given by @var{type} as a tree node) when the size computed in the
+usual way is @var{computed} and the alignment is @var{specified}.
-The default is to round @var{size} up to a multiple of @var{align}.
+The default is to round @var{computed} up to a multiple of @var{specified}.
@findex ROUND_TYPE_ALIGN
-@item ROUND_TYPE_ALIGN (@var{struct}, @var{computed}, @var{specified})
-Define this macro as an expression for the alignment of a structure
-(given by @var{struct} as a tree node) if the alignment computed in the
-usual way is @var{computed} and the alignment explicitly specified was
+@item ROUND_TYPE_ALIGN (@var{type}, @var{computed}, @var{specified})
+Define this macro as an expression for the alignment of a type (given
+by @var{type} as a tree node) if the alignment computed in the usual
+way is @var{computed} and the alignment explicitly specified was
@var{specified}.
The default is to use @var{specified} if it is larger; otherwise, use
@@ -1348,9 +1369,17 @@ preserve the entire contents of a register across a call.
@findex fixed_regs
@findex call_used_regs
@item CONDITIONAL_REGISTER_USAGE
-Zero or more C statements that may conditionally modify two variables
-@code{fixed_regs} and @code{call_used_regs} (both of type @code{char
-[]}) after they have been initialized from the two preceding macros.
+Zero or more C statements that may conditionally modify four variables
+@code{fixed_regs}, @code{call_used_regs}, @code{global_regs}
+(these three are of type @code{char []}) and @code{reg_class_contents}
+(of type @code{HARD_REG_SET}).
+Before the macro is called @code{fixed_regs}, @code{call_used_regs}
+and @code{reg_class_contents} have been initialized from
+@code{FIXED_REGISTERS}, @code{CALL_USED_REGISTERS} and
+@code{REG_CLASS_CONTENTS}, respectively,
+@code{global_regs} has been cleared, and any @samp{-ffixed-@var{reg}},
+@samp{-fcall-used-@var{reg}} and @samp{-fcall-saved-@var{reg}} command
+options have been applied.
This is necessary in case the fixed or call-clobbered registers depend
on target flags.
@@ -1684,24 +1713,6 @@ If this macro is not defined, it means that no insn clobbers registers
mysteriously. This is the usual situation; all else being equal,
it is best for the RTL expression to show all the activity.
-@cindex death notes
-@findex PRESERVE_DEATH_INFO_REGNO_P
-@item PRESERVE_DEATH_INFO_REGNO_P (@var{regno})
-If defined, this is a C expression whose value is nonzero if correct
-@code{REG_DEAD} notes are needed for hard register number @var{regno}
-after reload.
-
-You would arrange to preserve death info for a register when some of the
-code in the machine description which is executed to write the assembler
-code looks at the death notes. This is necessary only when the actual
-hardware feature which GNU CC thinks of as a register is not actually a
-register of the usual sort. (It might, for example, be a hardware
-stack.)
-
-It is also useful for peepholes and linker relaxation.
-
-If this macro is not defined, it means that no death notes need to be
-preserved, and some may even be incorrect. This is the usual situation.
@end table
@node Register Classes
@@ -2023,17 +2034,15 @@ is @code{BITS_PER_WORD} bits wide is correct for your machine.
@findex SMALL_REGISTER_CLASSES
@item SMALL_REGISTER_CLASSES
-Normally the compiler avoids choosing registers that have been
-explicitly mentioned in the rtl as spill registers (these registers are
-normally those used to pass parameters and return values). However,
-some machines have so few registers of certain classes that there
-would not be enough registers to use as spill registers if this were
-done.
+On some machines, it is risky to let hard registers live across arbitrary
+insns. Typically, these machines have instructions that require values
+to be in specific registers (like an accumulator), and reload will fail
+if the required hard register is used for another purpose across such an
+insn.
Define @code{SMALL_REGISTER_CLASSES} to be an expression with a non-zero
value on these machines. When this macro has a non-zero value, the
-compiler allows registers explicitly used in the rtl to be used as spill
-registers but avoids extending the lifetime of these registers.
+compiler will try to minimize the lifetime of hard registers.
It is always safe to define this macro with a non-zero value, but if you
unnecessarily define it, you will reduce the amount of optimizations
@@ -2642,7 +2651,8 @@ allocated for arguments even when their values are passed in
registers.
The value of this macro is the size, in bytes, of the area reserved for
-arguments passed in registers for the function represented by @var{fndecl}.
+arguments passed in registers for the function represented by @var{fndecl},
+which can be zero if GNU CC is calling a library function.
This space can be allocated by the caller, or be a part of the
machine-dependent stack frame: @code{OUTGOING_REG_PARM_STACK_SPACE} says
@@ -3729,11 +3739,8 @@ that were passed to @code{__builtin_saveregs}.
If this macro is not defined, the compiler will output an ordinary
call to the library function @samp{__builtin_saveregs}.
-@c !!! a bug in texinfo; how to make the entry on the @item line allow
-@c more than one line of text... help... --mew 10feb93
@findex SETUP_INCOMING_VARARGS
-@item SETUP_INCOMING_VARARGS (@var{args_so_far}, @var{mode}, @var{type},
-@var{pretend_args_size}, @var{second_time})
+@item SETUP_INCOMING_VARARGS (@var{args_so_far}, @var{mode}, @var{type}, @var{pretend_args_size}, @var{second_time})
This macro offers an alternative to using @code{__builtin_saveregs} and
defining the macro @code{EXPAND_BUILTIN_SAVEREGS}. Use it to store the
anonymous register arguments into the stack so that all the arguments
@@ -3779,6 +3786,15 @@ are treated as named. Otherwise, all named arguments except the last
are treated as named.
You need not define this macro if it always returns zero.
+
+@findex PRETEND_OUTGOING_VARARGS_NAMED
+@item PRETEND_OUTGOING_VARARGS_NAMED
+If you need to conditionally change ABIs so that one works with
+@code{SETUP_INCOMING_VARARGS}, but the other works like neither
+@code{SETUP_INCOMING_VARARGS} nor @code{STRICT_ARGUMENT_NAMING} was
+defined, then define this macro to return nonzero if
+@code{SETUP_INCOMING_VARARGS} is used, zero otherwise.
+Otherwise, you should not define this macro.
@end table
@node Trampolines
@@ -4165,7 +4181,7 @@ This is about addressing modes.
@table @code
@findex HAVE_POST_INCREMENT
@item HAVE_POST_INCREMENT
-Define this macro if the machine supports post-increment addressing.
+A C expression that is nonzero the machine supports post-increment addressing.
@findex HAVE_PRE_INCREMENT
@findex HAVE_POST_DECREMENT
@@ -4392,16 +4408,6 @@ an immediate operand on the target machine. You can assume that
@var{x} satisfies @code{CONSTANT_P}, so you need not check this. In fact,
@samp{1} is a suitable definition for this macro on machines where
anything @code{CONSTANT_P} is valid.@refill
-
-@findex DONT_RECORD_EQUIVALENCE
-@item DONT_RECORD_EQUIVALENCE (@var{note})
-A C expression that is nonzero if the @code{REG_EQUAL} note @var{x} should not
-be promoted to a @code{REG_EQUIV} note.
-
-Define this macro if @var{note} refers to a constant that must be accepted
-by @code{LEGITIMATE_CONSTANT_P}, but must not appear as an immediate operand.
-
-Most machine descriptions do not need to define this macro.
@end table
@node Condition Code
@@ -4767,6 +4773,42 @@ the corresponding number of memory-to-memory @emph{sequences}.
If you don't define this, a reasonable default is used.
+@findex MOVE_BY_PIECES_P
+@item MOVE_BY_PIECES_P (@var{size}, @var{alignment})
+A C expression used to determine whether @code{move_by_pieces} will be used to
+copy a chunk of memory, or whether some other block move mechanism
+will be used. Defaults to 1 if @code{move_by_pieces_ninsns} returns less
+than @code{MOVE_RATIO}.
+
+@findex MOVE_MAX_PIECES
+@item MOVE_MAX_PIECES
+A C expression used by @code{move_by_pieces} to determine the largest unit
+a load or store used to copy memory is. Defaults to @code{MOVE_MAX}.
+
+@findex USE_LOAD_POST_INCREMENT
+@item USE_LOAD_POST_INCREMENT (@var{mode})
+A C expression used to determine whether a load postincrement is
+a good thing for @code{move_by_pieces} to use for a given mode. Defaults
+to the value of @code{HAVE_POST_INCREMENT}.
+
+@findex USE_LOAD_PRE_INCREMENT
+@item USE_LOAD_PRE_INCREMENT (@var{mode})
+A C expression used to determine whether a load preincrement is
+a good thing for @code{move_by_pieces} to use for a given mode. Defaults
+to the value of @code{HAVE_PRE_INCREMENT}.
+
+@findex USE_STORE_POST_INCREMENT
+@item USE_STORE_POST_INCREMENT (@var{mode})
+A C expression used to determine whether a store postincrement is
+a good thing for @code{move_by_pieces} to use for a given mode. Defaults
+to the value of @code{HAVE_POST_INCREMENT}.
+
+@findex USE_STORE_PRE_INCREMENT
+@item USE_STORE_PRE_INCREMENT (@var{mode})
+This macro is used to determine whether a store preincrement is
+a good thing for @code{move_by_pieces} to use for a given mode. Defaults
+to the value of @code{HAVE_PRE_INCREMENT}.
+
@findex NO_FUNCTION_CSE
@item NO_FUNCTION_CSE
Define this macro if it is as good or better to call a constant
@@ -5940,13 +5982,20 @@ names.
@findex ASM_OUTPUT_DESTRUCTOR
This is like @code{ASM_OUTPUT_CONSTRUCTOR} but used for termination
functions rather than initialization functions.
+
+When @code{ASM_OUTPUT_CONSTRUCTOR} and @code{ASM_OUTPUT_DESTRUCTOR} are
+defined, the initializaiton routine generated for the generated object
+file will have static linkage.
@end table
If your system uses @code{collect2} as the means of processing
constructors, then that program normally uses @code{nm} to scan an
-object file for constructor functions to be called. On certain kinds of
-systems, you can define these macros to make @code{collect2} work faster
-(and, in some cases, make it work at all):
+object file for constructor functions to be called. On such systems you
+must not define @code{ASM_OUTPUT_CONSTRUCTOR} and @code{ASM_OUTPUT_DESTRUCTOR}
+as the object file's initialization routine must have global scope.
+
+On certain kinds of systems, you can define these macros to make
+@code{collect2} work faster (and, in some cases, make it work at all):
@table @code
@findex OBJECT_FORMAT_COFF
@@ -6393,6 +6442,14 @@ section.
A C statement to output to the stdio stream @var{stream} an assembler
command to advance the location counter to a multiple of 2 to the
@var{power} bytes. @var{power} will be a C expression of type @code{int}.
+
+@findex ASM_OUTPUT_MAX_SKIP_ALIGN
+@item ASM_OUTPUT_MAX_SKIP_ALIGN (@var{stream}, @var{power}, @var{max_skip})
+A C statement to output to the stdio stream @var{stream} an assembler
+command to advance the location counter to a multiple of 2 to the
+@var{power} bytes, but only if @var{max_skip} or fewer bytes are needed to
+satisfy the alignment request. @var{power} and @var{max_skip} will be
+a C expression of type @code{int}.
@end table
@need 3000
@@ -7551,7 +7608,7 @@ same time if the machine is a superscalar machine. This is only used by
the @samp{Haifa} scheduler, and not the traditional scheduler.
@findex MD_SCHED_INIT
-@item MD_SCHED_INIT (@var{file}, @var{verbose}
+@item MD_SCHED_INIT (@var{file}, @var{verbose})
A C statement which is executed by the @samp{Haifa} scheduler at the
beginning of each block of instructions that are to be scheduled.
@var{file} is either a null pointer, or a stdio stream to write any
diff --git a/gcc/toplev.c b/gcc/toplev.c
index 68cf5fafa58..7dff81ce044 100644
--- a/gcc/toplev.c
+++ b/gcc/toplev.c
@@ -1,5 +1,5 @@
/* Top level of GNU C compiler
- Copyright (C) 1987, 88, 89, 92-7, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1987, 88, 89, 92-98, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -29,7 +29,6 @@ Boston, MA 02111-1307, USA. */
#include "system.h"
#include <signal.h>
#include <setjmp.h>
-#include <sys/stat.h>
#ifdef HAVE_SYS_RESOURCE_H
# include <sys/resource.h>
@@ -53,6 +52,8 @@ Boston, MA 02111-1307, USA. */
#include "except.h"
#include "toplev.h"
#include "expr.h"
+#include "basic-block.h"
+#include "intl.h"
#include "ggc.h"
#ifdef DWARF_DEBUGGING_INFO
@@ -165,53 +166,68 @@ extern void print_rtl ();
extern void print_rtl_with_bb ();
void rest_of_decl_compilation ();
-void error_with_file_and_line PVPROTO((char *file, int line, char *s, ...));
-void error_with_decl PVPROTO((tree decl, char *s, ...));
-void error PVPROTO((char *s, ...));
-void fatal PVPROTO((char *s, ...));
-void warning_with_file_and_line PVPROTO((char *file, int line, char *s, ...));
-void warning_with_decl PVPROTO((tree decl, char *s, ...));
-void warning PVPROTO((char *s, ...));
-void pedwarn PVPROTO((char *s, ...));
-void pedwarn_with_decl PVPROTO((tree decl, char *s, ...));
-void pedwarn_with_file_and_line PVPROTO((char *file, int line, char *s, ...));
-void sorry PVPROTO((char *s, ...));
-static void set_target_switch PROTO((char *));
+void error_with_file_and_line PVPROTO((const char *file,
+ int line, const char *s, ...));
+void error_with_decl PVPROTO((tree decl, const char *s, ...));
+void error_for_asm PVPROTO((rtx insn, const char *s, ...));
+void notice PVPROTO((const char *s, ...));
+void error PVPROTO((const char *s, ...));
+void fatal PVPROTO((const char *s, ...));
+void warning_with_file_and_line PVPROTO((const char *file,
+ int line, const char *s, ...));
+void warning_with_decl PVPROTO((tree decl, const char *s, ...));
+void warning PVPROTO((const char *s, ...));
+void pedwarn PVPROTO((const char *s, ...));
+void pedwarn_with_decl PVPROTO((tree decl, const char *s, ...));
+void pedwarn_with_file_and_line PVPROTO((const char *file,
+ int line, const char *s, ...));
+void sorry PVPROTO((const char *s, ...));
+static void set_target_switch PROTO((const char *));
static char *decl_name PROTO((tree, int));
-static void vmessage PROTO((char *, char *, va_list));
-static void v_message_with_file_and_line PROTO((char *, int, char *,
- char *, va_list));
-static void v_message_with_decl PROTO((tree, char *, char *, va_list));
+static void vmessage PROTO((const char *, const char *, va_list));
+static void v_message_with_file_and_line PROTO((const char *, int, int,
+ const char *, va_list));
+static void v_message_with_decl PROTO((tree, int, const char *, va_list));
static void file_and_line_for_asm PROTO((rtx, char **, int *));
-static void v_error_with_file_and_line PROTO((char *, int, char *, va_list));
-static void v_error_with_decl PROTO((tree, char *, va_list));
-static void v_error_for_asm PROTO((rtx, char *, va_list));
-static void verror PROTO((char *, va_list));
-static void vfatal PROTO((char *, va_list)) ATTRIBUTE_NORETURN;
-static void v_warning_with_file_and_line PROTO ((char *, int, char *, va_list));
-static void v_warning_with_decl PROTO((tree, char *, va_list));
-static void v_warning_for_asm PROTO((rtx, char *, va_list));
-static void vwarning PROTO((char *, va_list));
-static void vpedwarn PROTO((char *, va_list));
-static void v_pedwarn_with_decl PROTO((tree, char *, va_list));
-static void v_pedwarn_with_file_and_line PROTO((char *, int, char *, va_list));
-static void vsorry PROTO((char *, va_list));
-static void v_really_sorry PROTO((char *, va_list)) ATTRIBUTE_NORETURN;
-static void float_signal PROTO((int));
-static void pipe_closed PROTO((int));
-static void output_lang_identify PROTO((FILE *));
-static void open_dump_file PROTO((char *, char *));
+static void v_error_with_file_and_line PROTO((const char *, int,
+ const char *, va_list));
+static void v_error_with_decl PROTO((tree, const char *, va_list));
+static void v_error_for_asm PROTO((rtx, const char *, va_list));
+static void verror PROTO((const char *, va_list));
+static void vfatal PROTO((const char *, va_list)) ATTRIBUTE_NORETURN;
+static void v_warning_with_file_and_line PROTO ((const char *, int,
+ const char *, va_list));
+static void v_warning_with_decl PROTO((tree, const char *, va_list));
+static void v_warning_for_asm PROTO((rtx, const char *, va_list));
+static void vwarning PROTO((const char *, va_list));
+static void vpedwarn PROTO((const char *, va_list));
+static void v_pedwarn_with_decl PROTO((tree, const char *, va_list));
+static void v_pedwarn_with_file_and_line PROTO((const char *, int,
+ const char *, va_list));
+static void vsorry PROTO((const char *, va_list));
+static void float_signal PROTO((int)) ATTRIBUTE_NORETURN;
+static void pipe_closed PROTO((int)) ATTRIBUTE_NORETURN;
+#ifdef ASM_IDENTIFY_LANGUAGE
+/* This might or might not be used in ASM_IDENTIFY_LANGUAGE. */
+static void output_lang_identify PROTO((FILE *)) ATTRIBUTE_UNUSED;
+#endif
+static void open_dump_file PROTO((const char *, const char *));
static void close_dump_file PROTO((void (*) (FILE *, rtx), rtx));
-static void dump_rtl PROTO((char *, tree, void (*) (FILE *, rtx), rtx));
-static void clean_dump_file PROTO((char *));
+static void dump_rtl PROTO((const char *, tree, void (*) (FILE *, rtx), rtx));
+static void clean_dump_file PROTO((const char *));
static void compile_file PROTO((char *));
static void display_help PROTO ((void));
-static void print_version PROTO((FILE *, char *));
-static int print_single_switch PROTO((FILE *, int, int, char *, char *, char *,
- char *, char *));
-static void print_switch_values PROTO((FILE *, int, int, char *, char *,
- char *));
+static void print_version PROTO((FILE *, const char *));
+static int print_single_switch PROTO((FILE *, int, int, const char *,
+ const char *, const char *,
+ const char *, const char *));
+static void print_switch_values PROTO((FILE *, int, int, const char *,
+ const char *, const char *));
+
+void print_rtl_graph_with_bb PROTO ((const char *, const char *, rtx));
+void clean_graph_dump_file PROTO ((const char *, const char *));
+void finish_graph_dump_file PROTO ((const char *, const char *));
/* Length of line when printing switch values. */
#define MAX_LINE 75
@@ -238,6 +254,9 @@ char *main_input_filename;
int lineno;
+/* Nonzero if it is unsafe to create any new pseudo registers. */
+int no_new_pseudos;
+
/* Stack of currently pending input files. */
struct file_stack *input_file_stack;
@@ -251,7 +270,7 @@ extern tree current_function_decl;
/* Name to use as base of names for dump output files. */
-char *dump_base_name;
+const char *dump_base_name;
/* Bit flags that specify the machine subtype we are compiling for.
Bits are tested using macros TARGET_... defined in the tm.h file
@@ -276,6 +295,7 @@ int regmove_dump = 0;
int sched_dump = 0;
int local_reg_dump = 0;
int global_reg_dump = 0;
+int flow2_dump = 0;
int sched2_dump = 0;
int jump2_opt_dump = 0;
#ifdef DELAY_SLOTS
@@ -288,6 +308,7 @@ int stack_reg_dump = 0;
#ifdef MACHINE_DEPENDENT_REORG
int mach_dep_reorg_dump = 0;
#endif
+enum graph_dump_types graph_dump_format;
/* Name for output file of assembly code, specified with -o. */
@@ -357,10 +378,6 @@ lang_expand_expr_t lang_expand_expr = 0;
void (*incomplete_decl_finalize_hook) PROTO((tree)) = 0;
-/* Highest label number used at the end of reload. */
-
-int max_label_num_after_reload;
-
/* Nonzero if generating code to do profiling. */
int profile_flag = 0;
@@ -543,10 +560,14 @@ int flag_fast_math = 0;
int flag_volatile;
-/* Nonzero means treat all global and extern variables as global. */
+/* Nonzero means treat all global and extern variables as volatile. */
int flag_volatile_global;
+/* Nonzero means treat all static variables as volatile. */
+
+int flag_volatile_static;
+
/* Nonzero means just do syntax checking; don't output anything. */
int flag_syntax_only = 0;
@@ -656,12 +677,11 @@ int flag_schedule_interblock = 1;
int flag_schedule_speculative = 1;
int flag_schedule_speculative_load = 0;
int flag_schedule_speculative_load_dangerous = 0;
+#endif /* HAIFA */
/* flag_on_branch_count_reg means try to replace add-1,compare,branch tupple
by a cheaper branch, on a count register. */
int flag_branch_on_count_reg;
-#endif /* HAIFA */
-
/* -finhibit-size-directive inhibits output of .size for ELF.
This is used only for compiling crtstuff.c,
@@ -730,16 +750,21 @@ int flag_strict_aliasing = 0;
/* Instrument functions with calls at entry and exit, for profiling. */
int flag_instrument_function_entry_exit = 0;
+/* Nonzero means ignore `#ident' directives. 0 means handle them.
+ On SVR4 targets, it also controls whether or not to emit a
+ string identifying the compiler. */
+
+int flag_no_ident = 0;
/* Table of supported debugging formats. */
static struct
{
- char * arg;
+ const char * arg;
/* Since PREFERRED_DEBUGGING_TYPE isn't necessarily a
constant expression, we use NO_DEBUG in its place. */
enum debug_info_type debug_type;
int use_extensions_p;
- char * description;
+ const char * description;
} *da,
debug_args[] =
{
@@ -765,18 +790,29 @@ debug_args[] =
#ifdef SDB_DEBUGGING_INFO
{ "gcoff", SDB_DEBUG, 0, "Generate COFF format debug output" },
#endif
- { 0, 0, 0 }
+ { 0, 0, 0, 0 }
};
typedef struct
{
- char * string;
+ const char * string;
int * variable;
int on_value;
- char * description;
+ const char * description;
}
lang_independent_options;
+/* Add or remove a leading underscore from user symbols. */
+int flag_leading_underscore = -1;
+
+/* The user symbol prefix after having resolved same. */
+const char *user_label_prefix;
+
+/* A default for same. */
+#ifndef USER_LABEL_PREFIX
+#define USER_LABEL_PREFIX ""
+#endif
+
/* Table of language-independent -f options.
STRING is the option name. VARIABLE is the address of the variable.
ON_VALUE is the value to store in VARIABLE
@@ -791,6 +827,8 @@ lang_independent_options f_options[] =
"Consider all mem refs through pointers as volatile"},
{"volatile-global", &flag_volatile_global, 1,
"Consider all mem refs to global data to be volatile" },
+ {"volatile-static", &flag_volatile_static, 1,
+ "Consider all mem refs to static data to be volatile" },
{"defer-pop", &flag_defer_pop, 1,
"Defer popping functions args from stack until later" },
{"omit-frame-pointer", &flag_omit_frame_pointer, 1,
@@ -806,9 +844,9 @@ lang_independent_options f_options[] =
{"strength-reduce", &flag_strength_reduce, 1,
"Perform strength reduction optimisations" },
{"unroll-loops", &flag_unroll_loops, 1,
- "Perform loop unrolling when interation count is known" },
+ "Perform loop unrolling when iteration count is known" },
{"unroll-all-loops", &flag_unroll_all_loops, 1,
- "Perofm loop onrolling for all loops" },
+ "Perform loop unrolling for all loops" },
{"move-all-movables", &flag_move_all_movables, 1,
"Force all loop invariant computations out of loops" },
{"reduce-all-givs", &flag_reduce_all_givs, 1,
@@ -864,9 +902,9 @@ lang_independent_options f_options[] =
"Allow speculative motion of some loads" },
{"sched-spec-load-dangerous",&flag_schedule_speculative_load_dangerous, 1,
"Allow speculative motion of more loads" },
+#endif /* HAIFA */
{"branch-count-reg",&flag_branch_on_count_reg, 1,
"Replace add,compare,branch with branch on count reg"},
-#endif /* HAIFA */
{"pic", &flag_pic, 1,
"Generate position independent code, if possible"},
{"PIC", &flag_pic, 2, ""},
@@ -883,7 +921,7 @@ lang_independent_options f_options[] =
{"test-coverage", &flag_test_coverage, 1,
"Create data files needed by gcov" },
{"branch-probabilities", &flag_branch_probabilities, 1,
- "Use profiling information for branch porbabilities" },
+ "Use profiling information for branch probabilities" },
{"fast-math", &flag_fast_math, 1,
"Improve FP speed by violating ANSI & IEEE rules" },
{"common", &flag_no_common, 0,
@@ -899,8 +937,9 @@ lang_independent_options f_options[] =
{"gnu-linker", &flag_gnu_linker, 1,
"Output GNU ld formatted global initialisers"},
{"regmove", &flag_regmove, 1,
- "Enables a regoster move optimisation"},
- {"optimize-register-move", &flag_regmove, 1},
+ "Enables a register move optimisation"},
+ {"optimize-register-move", &flag_regmove, 1,
+ "Do the full regmove optimization pass"},
{"pack-struct", &flag_pack_struct, 1,
"Pack structure members together without holes" },
{"stack-check", &flag_stack_check, 1,
@@ -917,9 +956,14 @@ lang_independent_options f_options[] =
"Generate code to check every memory access" },
{"prefix-function-name", &flag_prefix_function_name, 1,
"Add a prefix to all function names" },
- {"dump-unnumbered", &flag_dump_unnumbered, 1},
+ {"dump-unnumbered", &flag_dump_unnumbered, 1,
+ "Suppress output of instruction numbers and line number notes in debugging dumps"},
{"instrument-functions", &flag_instrument_function_entry_exit, 1,
"Instrument function entry/exit with profiling calls"},
+ {"leading-underscore", &flag_leading_underscore, 1,
+ "External symbols have a leading underscore" },
+ {"ident", &flag_no_ident, 0,
+ "Process #ident directives"}
};
#define NUM_ELEM(a) (sizeof (a) / sizeof ((a)[0]))
@@ -928,8 +972,8 @@ lang_independent_options f_options[] =
static struct lang_opt
{
- char * option;
- char * description;
+ const char * option;
+ const char * description;
}
documented_lang_options[] =
{
@@ -940,6 +984,7 @@ documented_lang_options[] =
{ "-ansi", "Compile just for ANSI C" },
{ "-fallow-single-precision",
"Do not promote floats to double if using -traditional" },
+ { "-std= ", "Determine language standard"},
{ "-fsigned-bitfields", "" },
{ "-funsigned-bitfields","Make bitfields by unsigned by default" },
@@ -966,10 +1011,8 @@ documented_lang_options[] =
{ "-fno-freestanding", "" },
{ "-fcond-mismatch", "Allow different types as args of ? operator"},
{ "-fno-cond-mismatch", "" },
- { "-fdollars-in-identifiers", "Allow the use of $ inside indentifiers" },
+ { "-fdollars-in-identifiers", "Allow the use of $ inside identifiers" },
{ "-fno-dollars-in-identifiers", "" },
- { "-fident", "" },
- { "-fno-ident", "Ignore #ident directives" },
{ "-fshort-double", "Use the same size for double as for float" },
{ "-fno-short-double", "" },
{ "-fshort-enums", "Use the smallest fitting integer to hold enums"},
@@ -979,14 +1022,17 @@ documented_lang_options[] =
{ "-Wbad-function-cast",
"Warn about casting functions to incompatible types" },
{ "-Wno-bad-function-cast", "" },
+ { "-Wmissing-noreturn",
+ "Warn about functions which might be candidates for attribute noreturn" },
+ { "-Wno-missing-noreturn", "" },
{ "-Wcast-qual", "Warn about casts which discard qualifiers"},
{ "-Wno-cast-qual", "" },
{ "-Wchar-subscripts", "Warn about subscripts whose type is 'char'"},
{ "-Wno-char-subscripts", "" },
{ "-Wcomment", "Warn if nested comments are detected" },
- { "-Wno-comment", },
- { "-Wcomments", },
- { "-Wno-comments", },
+ { "-Wno-comment", "" },
+ { "-Wcomments", "Warn if nested comments are detected" },
+ { "-Wno-comments", "" },
{ "-Wconversion", "Warn about possibly confusing type conversions" },
{ "-Wno-conversion", "" },
{ "-Wformat", "Warn about printf format anomalies" },
@@ -1046,6 +1092,7 @@ documented_lang_options[] =
{ "-D", "" },
{ "-I", "" },
{ "-U", "" },
+ { "-H", "" },
{ "-idirafter", "" },
{ "-imacros", "" },
{ "-include", "" },
@@ -1069,7 +1116,7 @@ documented_lang_options[] =
{ "-lang-objc", "" },
{ "-gen-decls", "Dump decls to a .decl file" },
- { "-fgnu-runtime", "Generate code for GNU runtime envrionment" },
+ { "-fgnu-runtime", "Generate code for GNU runtime environment" },
{ "-fno-gnu-runtime", "" },
{ "-fnext-runtime", "Generate code for NeXT runtime environment" },
{ "-fno-next-runtime", "" },
@@ -1092,9 +1139,9 @@ documented_lang_options[] =
struct
{
- char * name;
+ const char * name;
int value;
- char * description;
+ const char * description;
}
target_switches [] = TARGET_SWITCHES;
@@ -1103,9 +1150,9 @@ target_switches [] = TARGET_SWITCHES;
#ifdef TARGET_OPTIONS
struct
{
- char * prefix;
- char ** variable;
- char * description;
+ const char * prefix;
+ const char ** variable;
+ const char * description;
}
target_options [] = TARGET_OPTIONS;
#endif
@@ -1199,6 +1246,38 @@ FILE *asm_out_file;
FILE *aux_info_file;
FILE *rtl_dump_file = NULL;
+/* Decode the string P as an integral parameter.
+ If the string is indeed an integer return its numeric value else
+ issue an Invalid Option error for the option PNAME and return DEFVAL.
+ If PNAME is zero just return DEFVAL, do not call error. */
+
+int
+read_integral_parameter (p, pname, defval)
+ const char *p;
+ const char *pname;
+ const int defval;
+{
+ const char *endp = p;
+
+ while (*endp)
+ {
+ if (*endp >= '0' && *endp <= '9')
+ endp++;
+ else
+ break;
+ }
+
+ if (*endp != 0)
+ {
+ if (pname != 0)
+ error ("Invalid option `%s'", pname);
+ return defval;
+ }
+
+ return atoi (p);
+}
+
+
/* Time accumulators, to count the total time spent in various passes. */
int parse_time;
@@ -1216,6 +1295,7 @@ int regmove_time;
int sched_time;
int local_alloc_time;
int global_alloc_time;
+int flow2_time;
int sched2_time;
#ifdef DELAY_SLOTS
int dbr_sched_time;
@@ -1230,7 +1310,7 @@ int all_time;
/* Return time used so far, in microseconds. */
-int
+long
get_run_time ()
{
if (quiet_flag)
@@ -1239,7 +1319,7 @@ get_run_time ()
#ifdef __BEOS__
return 0;
#else /* not BeOS */
-#if defined (_WIN32) && !defined (__CYGWIN32__)
+#if defined (_WIN32) && !defined (__CYGWIN__)
if (clock() < 0)
return 0;
else
@@ -1302,7 +1382,7 @@ do { int otime = get_run_time (); BODY; VAR += get_run_time () - otime; } while
void
print_time (str, total)
- char *str;
+ const char *str;
int total;
{
fprintf (stderr,
@@ -1328,7 +1408,7 @@ count_error (warningp)
if (warningp && !warning_message)
{
- fprintf (stderr, "%s: warnings being treated as errors\n", progname);
+ notice ("%s: warnings being treated as errors\n", progname);
warning_message = 1;
}
errorcount++;
@@ -1342,7 +1422,7 @@ count_error (warningp)
void
pfatal_with_name (name)
- char *name;
+ const char *name;
{
fprintf (stderr, "%s: ", progname);
perror (name);
@@ -1351,9 +1431,9 @@ pfatal_with_name (name)
void
fatal_io_error (name)
- char *name;
+ const char *name;
{
- fprintf (stderr, "%s: %s: I/O error\n", progname, name);
+ notice ("%s: %s: I/O error\n", progname, name);
exit (FATAL_EXIT_CODE);
}
@@ -1361,11 +1441,11 @@ fatal_io_error (name)
just calling abort(). */
void
-fatal_insn (message, insn)
- char *message;
+fatal_insn (msgid, insn)
+ const char *msgid;
rtx insn;
{
- error (message);
+ error (msgid);
debug_rtx (insn);
if (asm_out_file)
fflush (asm_out_file);
@@ -1436,25 +1516,20 @@ announce_function (decl)
void
default_print_error_function (file)
- char *file;
+ const char *file;
{
if (last_error_function != current_function_decl)
{
- char *kind = "function";
- if (current_function_decl != 0
- && TREE_CODE (TREE_TYPE (current_function_decl)) == METHOD_TYPE)
- kind = "method";
-
if (file)
fprintf (stderr, "%s: ", file);
if (current_function_decl == NULL)
- fprintf (stderr, "At top level:\n");
+ notice ("At top level:\n");
else
- {
- char *name = (*decl_printable_name) (current_function_decl, 2);
- fprintf (stderr, "In %s `%s':\n", kind, name);
- }
+ notice ((TREE_CODE (TREE_TYPE (current_function_decl)) == METHOD_TYPE
+ ? "In method `%s':\n"
+ : "In function `%s':\n"),
+ (*decl_printable_name) (current_function_decl, 2));
last_error_function = current_function_decl;
}
@@ -1463,14 +1538,15 @@ default_print_error_function (file)
/* Called by report_error_function to print out function name.
* Default may be overridden by language front-ends. */
-void (*print_error_function) PROTO((char *)) = default_print_error_function;
+void (*print_error_function) PROTO((const char *)) =
+ default_print_error_function;
/* Prints out, if necessary, the name of the current function
that caused an error. Called from all error and warning functions. */
void
report_error_function (file)
- char *file;
+ const char *file;
{
struct file_stack *p;
@@ -1486,13 +1562,11 @@ report_error_function (file)
&& input_file_stack_tick != last_error_tick
&& file == input_filename)
{
- fprintf (stderr, "In file included");
for (p = input_file_stack->next; p; p = p->next)
- {
- fprintf (stderr, " from %s:%d", p->name, p->line);
- if (p->next)
- fprintf (stderr, ",\n ");
- }
+ notice ((p == input_file_stack->next
+ ? "In file included from %s:%d"
+ : ",\n from %s:%d"),
+ p->name, p->line);
fprintf (stderr, ":\n");
last_error_tick = input_file_stack_tick;
}
@@ -1501,81 +1575,142 @@ report_error_function (file)
/* Print a message. */
static void
-vmessage (prefix, s, ap)
- char *prefix;
- char *s;
+vnotice (file, msgid, ap)
+ FILE *file;
+ char *msgid;
va_list ap;
{
- if (prefix)
- fprintf (stderr, "%s: ", prefix);
+ vfprintf (file, _(msgid), ap);
+}
+
+void
+notice VPROTO((const char *msgid, ...))
+{
+#ifndef ANSI_PROTOTYPES
+ char *msgid;
+#endif
+ va_list ap;
+
+ VA_START (ap, msgid);
- vfprintf (stderr, s, ap);
+#ifndef ANSI_PROTOTYPES
+ msgid = va_arg (ap, char *);
+#endif
+
+ vnotice (stderr, msgid, ap);
+ va_end (ap);
}
-/* Print a message relevant to line LINE of file FILE. */
+void
+fnotice VPROTO((FILE *file, const char *msgid, ...))
+{
+#ifndef ANSI_PROTOTYPES
+ FILE *file;
+ const char *msgid;
+#endif
+ va_list ap;
+
+ VA_START (ap, msgid);
+
+#ifndef ANSI_PROTOTYPES
+ file = va_arg (ap, FILE *);
+ msgid = va_arg (ap, const char *);
+#endif
+
+ vnotice (file, msgid, ap);
+ va_end (ap);
+}
+
+/* Report FILE and LINE (or program name), and optionally just WARN. */
static void
-v_message_with_file_and_line (file, line, prefix, s, ap)
+report_file_and_line (file, line, warn)
char *file;
int line;
- char *prefix;
- char *s;
- va_list ap;
+ int warn;
{
if (file)
fprintf (stderr, "%s:%d: ", file, line);
else
fprintf (stderr, "%s: ", progname);
- vmessage (prefix, s, ap);
+ if (warn)
+ notice ("warning: ");
+}
+
+/* Print a message. */
+
+static void
+vmessage (prefix, msgid, ap)
+ const char *prefix;
+ const char *msgid;
+ va_list ap;
+{
+ if (prefix)
+ fprintf (stderr, "%s: ", prefix);
+
+ vfprintf (stderr, msgid, ap);
+}
+
+/* Print a message relevant to line LINE of file FILE. */
+
+static void
+v_message_with_file_and_line (file, line, warn, msgid, ap)
+ const char *file;
+ int line;
+ int warn;
+ const char *msgid;
+ va_list ap;
+{
+ report_file_and_line (file, line, warn);
+ vnotice (stderr, msgid, ap);
fputc ('\n', stderr);
}
/* Print a message relevant to the given DECL. */
static void
-v_message_with_decl (decl, prefix, s, ap)
+v_message_with_decl (decl, warn, msgid, ap)
tree decl;
- char *prefix;
- char *s;
+ int warn;
+ const char *msgid;
va_list ap;
{
- char *p;
+ const char *p;
- fprintf (stderr, "%s:%d: ",
- DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl));
-
- if (prefix)
- fprintf (stderr, "%s: ", prefix);
+ report_file_and_line (DECL_SOURCE_FILE (decl),
+ DECL_SOURCE_LINE (decl), warn);
/* Do magic to get around lack of varargs support for insertion
of arguments into existing list. We know that the decl is first;
we ass_u_me that it will be printed with "%s". */
- for (p = s; *p; ++p)
+ for (p = _(msgid); *p; ++p)
{
if (*p == '%')
{
if (*(p + 1) == '%')
++p;
+ else if (*(p + 1) != 's')
+ abort ();
else
break;
}
}
- if (p > s) /* Print the left-hand substring. */
+ if (p > _(msgid)) /* Print the left-hand substring. */
{
char fmt[sizeof "%.255s"];
- long width = p - s;
+ long width = p - _(msgid);
if (width > 255L) width = 255L; /* arbitrary */
sprintf (fmt, "%%.%lds", width);
- fprintf (stderr, fmt, s);
+ fprintf (stderr, fmt, _(msgid));
}
if (*p == '%') /* Print the name. */
{
- char *n = (DECL_NAME (decl)
+ const char *n = (DECL_NAME (decl)
? (*decl_printable_name) (decl, 2)
: "((anonymous))");
fputs (n, stderr);
@@ -1633,71 +1768,72 @@ file_and_line_for_asm (insn, pfile, pline)
/* Report an error at line LINE of file FILE. */
static void
-v_error_with_file_and_line (file, line, s, ap)
- char *file;
+v_error_with_file_and_line (file, line, msgid, ap)
+ const char *file;
int line;
- char *s;
+ const char *msgid;
va_list ap;
{
count_error (0);
report_error_function (file);
- v_message_with_file_and_line (file, line, (char *)NULL, s, ap);
+ v_message_with_file_and_line (file, line, 0, msgid, ap);
}
void
-error_with_file_and_line VPROTO((char *file, int line, char *s, ...))
+error_with_file_and_line VPROTO((const char *file, int line,
+ const char *msgid, ...))
{
-#ifndef __STDC__
- char *file;
+#ifndef ANSI_PROTOTYPES
+ const char *file;
int line;
- char *s;
+ const char *msgid;
#endif
va_list ap;
- VA_START (ap, s);
+ VA_START (ap, msgid);
-#ifndef __STDC__
- file = va_arg (ap, char *);
+#ifndef ANSI_PROTOTYPES
+ file = va_arg (ap, const char *);
line = va_arg (ap, int);
- s = va_arg (ap, char *);
+ msgid = va_arg (ap, const char *);
#endif
- v_error_with_file_and_line (file, line, s, ap);
+ v_error_with_file_and_line (file, line, msgid, ap);
va_end (ap);
}
/* Report an error at the declaration DECL.
- S is a format string which uses %s to substitute the declaration
+ MSGID is a format string which uses %s to substitute the declaration
name; subsequent substitutions are a la printf. */
static void
-v_error_with_decl (decl, s, ap)
+v_error_with_decl (decl, msgid, ap)
tree decl;
- char *s;
+ const char *msgid;
va_list ap;
{
count_error (0);
report_error_function (DECL_SOURCE_FILE (decl));
- v_message_with_decl (decl, (char *)NULL, s, ap);
+ v_message_with_decl (decl, 0, msgid, ap);
}
void
-error_with_decl VPROTO((tree decl, char *s, ...))
+error_with_decl VPROTO((tree decl, const char *msgid, ...))
{
-#ifndef __STDC__
+#ifndef ANSI_PROTOTYPES
tree decl;
- char *s;
+ const char *msgid;
#endif
va_list ap;
- VA_START (ap, s);
+ VA_START (ap, msgid);
-#ifndef __STDC__
+#ifndef ANSI_PROTOTYPES
decl = va_arg (ap, tree);
- s = va_arg (ap, char *);
+ msgid = va_arg (ap, const char *);
#endif
- v_error_with_decl (decl, s, ap);
+ v_error_with_decl (decl, msgid, ap);
va_end (ap);
}
@@ -1706,9 +1842,9 @@ error_with_decl VPROTO((tree decl, char *s, ...))
and each ASM_OPERANDS records its own source file and line. */
static void
-v_error_for_asm (insn, s, ap)
+v_error_for_asm (insn, msgid, ap)
rtx insn;
- char *s;
+ const char *msgid;
va_list ap;
{
char *file;
@@ -1717,158 +1853,159 @@ v_error_for_asm (insn, s, ap)
count_error (0);
file_and_line_for_asm (insn, &file, &line);
report_error_function (file);
- v_message_with_file_and_line (file, line, (char *)NULL, s, ap);
+ v_message_with_file_and_line (file, line, 0, msgid, ap);
}
void
-error_for_asm VPROTO((rtx insn, char *s, ...))
+error_for_asm VPROTO((rtx insn, const char *msgid, ...))
{
-#ifndef __STDC__
+#ifndef ANSI_PROTOTYPES
rtx insn;
- char *s;
+ const char *msgid;
#endif
va_list ap;
- VA_START (ap, s);
+ VA_START (ap, msgid);
-#ifndef __STDC__
+#ifndef ANSI_PROTOTYPES
insn = va_arg (ap, rtx);
- s = va_arg (ap, char *);
+ msgid = va_arg (ap, const char *);
#endif
- v_error_for_asm (insn, s, ap);
+ v_error_for_asm (insn, msgid, ap);
va_end (ap);
}
/* Report an error at the current line number. */
static void
-verror (s, ap)
- char *s;
+verror (msgid, ap)
+ const char *msgid;
va_list ap;
{
- v_error_with_file_and_line (input_filename, lineno, s, ap);
+ v_error_with_file_and_line (input_filename, lineno, msgid, ap);
}
void
-error VPROTO((char *s, ...))
+error VPROTO((const char *msgid, ...))
{
-#ifndef __STDC__
- char *s;
+#ifndef ANSI_PROTOTYPES
+ const char *msgid;
#endif
va_list ap;
- VA_START (ap, s);
+ VA_START (ap, msgid);
-#ifndef __STDC__
- s = va_arg (ap, char *);
+#ifndef ANSI_PROTOTYPES
+ msgid = va_arg (ap, const char *);
#endif
- verror (s, ap);
+ verror (msgid, ap);
va_end (ap);
}
/* Report a fatal error at the current line number. */
static void
-vfatal (s, ap)
- char *s;
+vfatal (msgid, ap)
+ const char *msgid;
va_list ap;
{
- verror (s, ap);
+ verror (msgid, ap);
exit (FATAL_EXIT_CODE);
}
void
-fatal VPROTO((char *s, ...))
+fatal VPROTO((const char *msgid, ...))
{
-#ifndef __STDC__
- char *s;
+#ifndef ANSI_PROTOTYPES
+ const char *msgid;
#endif
va_list ap;
- VA_START (ap, s);
+ VA_START (ap, msgid);
-#ifndef __STDC__
- s = va_arg (ap, char *);
+#ifndef ANSI_PROTOTYPES
+ msgid = va_arg (ap, const char *);
#endif
- vfatal (s, ap);
+ vfatal (msgid, ap);
va_end (ap);
}
/* Report a warning at line LINE of file FILE. */
static void
-v_warning_with_file_and_line (file, line, s, ap)
- char *file;
+v_warning_with_file_and_line (file, line, msgid, ap)
+ const char *file;
int line;
- char *s;
+ const char *msgid;
va_list ap;
{
if (count_error (1))
{
report_error_function (file);
- v_message_with_file_and_line (file, line, "warning", s, ap);
+ v_message_with_file_and_line (file, line, 1, msgid, ap);
}
}
void
-warning_with_file_and_line VPROTO((char *file, int line, char *s, ...))
+warning_with_file_and_line VPROTO((const char *file, int line,
+ const char *msgid, ...))
{
-#ifndef __STDC__
- char *file;
+#ifndef ANSI_PROTOTYPES
+ const char *file;
int line;
- char *s;
+ const char *msgid;
#endif
va_list ap;
- VA_START (ap, s);
+ VA_START (ap, msgid);
-#ifndef __STDC__
- file = va_arg (ap, char *);
+#ifndef ANSI_PROTOTYPES
+ file = va_arg (ap, const char *);
line = va_arg (ap, int);
- s = va_arg (ap, char *);
+ msgid = va_arg (ap, const char *);
#endif
- v_warning_with_file_and_line (file, line, s, ap);
+ v_warning_with_file_and_line (file, line, msgid, ap);
va_end (ap);
}
/* Report a warning at the declaration DECL.
- S is a format string which uses %s to substitute the declaration
+ MSGID is a format string which uses %s to substitute the declaration
name; subsequent substitutions are a la printf. */
static void
-v_warning_with_decl (decl, s, ap)
+v_warning_with_decl (decl, msgid, ap)
tree decl;
- char *s;
+ const char *msgid;
va_list ap;
{
if (count_error (1))
{
report_error_function (DECL_SOURCE_FILE (decl));
- v_message_with_decl (decl, "warning", s, ap);
+ v_message_with_decl (decl, 1, msgid, ap);
}
}
void
-warning_with_decl VPROTO((tree decl, char *s, ...))
+warning_with_decl VPROTO((tree decl, const char *msgid, ...))
{
-#ifndef __STDC__
+#ifndef ANSI_PROTOTYPES
tree decl;
- char *s;
+ const char *msgid;
#endif
va_list ap;
- VA_START (ap, s);
+ VA_START (ap, msgid);
-#ifndef __STDC__
+#ifndef ANSI_PROTOTYPES
decl = va_arg (ap, tree);
- s = va_arg (ap, char *);
+ msgid = va_arg (ap, const char *);
#endif
- v_warning_with_decl (decl, s, ap);
+ v_warning_with_decl (decl, msgid, ap);
va_end (ap);
}
@@ -1877,9 +2014,9 @@ warning_with_decl VPROTO((tree decl, char *s, ...))
and each ASM_OPERANDS records its own source file and line. */
static void
-v_warning_for_asm (insn, s, ap)
+v_warning_for_asm (insn, msgid, ap)
rtx insn;
- char *s;
+ const char *msgid;
va_list ap;
{
if (count_error (1))
@@ -1889,55 +2026,55 @@ v_warning_for_asm (insn, s, ap)
file_and_line_for_asm (insn, &file, &line);
report_error_function (file);
- v_message_with_file_and_line (file, line, "warning", s, ap);
+ v_message_with_file_and_line (file, line, 1, msgid, ap);
}
}
void
-warning_for_asm VPROTO((rtx insn, char *s, ...))
+warning_for_asm VPROTO((rtx insn, const char *msgid, ...))
{
-#ifndef __STDC__
+#ifndef ANSI_PROTOTYPES
rtx insn;
- char *s;
+ const char *msgid;
#endif
va_list ap;
- VA_START (ap, s);
+ VA_START (ap, msgid);
-#ifndef __STDC__
+#ifndef ANSI_PROTOTYPES
insn = va_arg (ap, rtx);
- s = va_arg (ap, char *);
+ msgid = va_arg (ap, const char *);
#endif
- v_warning_for_asm (insn, s, ap);
+ v_warning_for_asm (insn, msgid, ap);
va_end (ap);
}
/* Report a warning at the current line number. */
static void
-vwarning (s, ap)
- char *s;
+vwarning (msgid, ap)
+ const char *msgid;
va_list ap;
{
- v_warning_with_file_and_line (input_filename, lineno, s, ap);
+ v_warning_with_file_and_line (input_filename, lineno, msgid, ap);
}
void
-warning VPROTO((char *s, ...))
+warning VPROTO((const char *msgid, ...))
{
-#ifndef __STDC__
- char *s;
+#ifndef ANSI_PROTOTYPES
+ const char *msgid;
#endif
va_list ap;
- VA_START (ap, s);
+ VA_START (ap, msgid);
-#ifndef __STDC__
- s = va_arg (ap, char *);
+#ifndef ANSI_PROTOTYPES
+ msgid = va_arg (ap, const char *);
#endif
- vwarning (s, ap);
+ vwarning (msgid, ap);
va_end (ap);
}
@@ -1945,38 +2082,38 @@ warning VPROTO((char *s, ...))
-pedantic-errors. */
static void
-vpedwarn (s, ap)
- char *s;
+vpedwarn (msgid, ap)
+ const char *msgid;
va_list ap;
{
if (flag_pedantic_errors)
- verror (s, ap);
+ verror (msgid, ap);
else
- vwarning (s, ap);
+ vwarning (msgid, ap);
}
void
-pedwarn VPROTO((char *s, ...))
+pedwarn VPROTO((const char *msgid, ...))
{
-#ifndef __STDC__
- char *s;
+#ifndef ANSI_PROTOTYPES
+ const char *msgid;
#endif
va_list ap;
- VA_START (ap, s);
+ VA_START (ap, msgid);
-#ifndef __STDC__
- s = va_arg (ap, char *);
+#ifndef ANSI_PROTOTYPES
+ msgid = va_arg (ap, const char *);
#endif
- vpedwarn (s, ap);
+ vpedwarn (msgid, ap);
va_end (ap);
}
static void
-v_pedwarn_with_decl (decl, s, ap)
+v_pedwarn_with_decl (decl, msgid, ap)
tree decl;
- char *s;
+ const char *msgid;
va_list ap;
{
/* We don't want -pedantic-errors to cause the compilation to fail from
@@ -1989,72 +2126,73 @@ v_pedwarn_with_decl (decl, s, ap)
if (! DECL_IN_SYSTEM_HEADER (decl))
{
if (flag_pedantic_errors)
- v_error_with_decl (decl, s, ap);
+ v_error_with_decl (decl, msgid, ap);
else
- v_warning_with_decl (decl, s, ap);
+ v_warning_with_decl (decl, msgid, ap);
}
}
void
-pedwarn_with_decl VPROTO((tree decl, char *s, ...))
+pedwarn_with_decl VPROTO((tree decl, const char *msgid, ...))
{
-#ifndef __STDC__
+#ifndef ANSI_PROTOTYPES
tree decl;
- char *s;
+ const char *msgid;
#endif
va_list ap;
- VA_START (ap, s);
+ VA_START (ap, msgid);
-#ifndef __STDC__
+#ifndef ANSI_PROTOTYPES
decl = va_arg (ap, tree);
- s = va_arg (ap, char *);
+ msgid = va_arg (ap, const char *);
#endif
- v_pedwarn_with_decl (decl, s, ap);
+ v_pedwarn_with_decl (decl, msgid, ap);
va_end (ap);
}
static void
-v_pedwarn_with_file_and_line (file, line, s, ap)
- char *file;
+v_pedwarn_with_file_and_line (file, line, msgid, ap)
+ const char *file;
int line;
- char *s;
+ const char *msgid;
va_list ap;
{
if (flag_pedantic_errors)
- v_error_with_file_and_line (file, line, s, ap);
+ v_error_with_file_and_line (file, line, msgid, ap);
else
- v_warning_with_file_and_line (file, line, s, ap);
+ v_warning_with_file_and_line (file, line, msgid, ap);
}
void
-pedwarn_with_file_and_line VPROTO((char *file, int line, char *s, ...))
+pedwarn_with_file_and_line VPROTO((const char *file, int line,
+ const char *msgid, ...))
{
-#ifndef __STDC__
- char *file;
+#ifndef ANSI_PROTOTYPES
+ const char *file;
int line;
- char *s;
+ const char *msgid;
#endif
va_list ap;
- VA_START (ap, s);
+ VA_START (ap, msgid);
-#ifndef __STDC__
- file = va_arg (ap, char *);
+#ifndef ANSI_PROTOTYPES
+ file = va_arg (ap, const char *);
line = va_arg (ap, int);
- s = va_arg (ap, char *);
+ msgid = va_arg (ap, const char *);
#endif
- v_pedwarn_with_file_and_line (file, line, s, ap);
+ v_pedwarn_with_file_and_line (file, line, msgid, ap);
va_end (ap);
}
/* Apologize for not implementing some feature. */
static void
-vsorry (s, ap)
- char *s;
+vsorry (msgid, ap)
+ const char *msgid;
va_list ap;
{
sorrycount++;
@@ -2062,7 +2200,8 @@ vsorry (s, ap)
fprintf (stderr, "%s:%d: ", input_filename, lineno);
else
fprintf (stderr, "%s: ", progname);
- vmessage ("sorry, not implemented", s, ap);
+ notice ("sorry, not implemented: ");
+ vnotice (stderr, msgid, ap);
fputc ('\n', stderr);
}
@@ -2101,20 +2240,20 @@ v_really_sorry (s, ap)
}
void
-really_sorry VPROTO((char *s, ...))
+sorry VPROTO((const char *msgid, ...))
{
-#ifndef __STDC__
- char *s;
+#ifndef ANSI_PROTOTYPES
+ const char *msgid;
#endif
va_list ap;
- VA_START (ap, s);
+ VA_START (ap, msgid);
-#ifndef __STDC__
- s = va_arg (ap, char *);
+#ifndef ANSI_PROTOTYPES
+ msgid = va_arg (ap, const char *);
#endif
- v_really_sorry (s, ap);
+ vsorry (msgid, ap);
va_end (ap);
}
@@ -2146,23 +2285,23 @@ do_abort ()
void
botch (s)
- char * s ATTRIBUTE_UNUSED;
+ const char * s ATTRIBUTE_UNUSED;
{
abort ();
}
/* Same as `malloc' but report error if no memory available. */
-char *
+PTR
xmalloc (size)
- unsigned size;
+ size_t size;
{
- register char *value;
+ register PTR value;
if (size == 0)
size = 1;
- value = (char *) malloc (size);
+ value = (PTR) malloc (size);
if (value == 0)
fatal ("virtual memory exhausted");
return value;
@@ -2170,16 +2309,16 @@ xmalloc (size)
/* Same as `calloc' but report error if no memory available. */
-char *
+PTR
xcalloc (size1, size2)
- unsigned size1, size2;
+ size_t size1, size2;
{
- register char *value;
+ register PTR value;
if (size1 == 0 || size2 == 0)
size1 = size2 = 1;
- value = (char *) calloc (size1, size2);
+ value = (PTR) calloc (size1, size2);
if (value == 0)
fatal ("virtual memory exhausted");
return value;
@@ -2188,19 +2327,17 @@ xcalloc (size1, size2)
/* Same as `realloc' but report error if no memory available.
Also handle null PTR even if the vendor realloc gets it wrong. */
-char *
+PTR
xrealloc (ptr, size)
- char *ptr;
- int size;
+ PTR ptr;
+ size_t size;
{
- char *result;
+ register PTR result;
if (size == 0)
size = 1;
- result = (ptr
- ? (char *) realloc (ptr, size)
- : (char *) malloc (size));
+ result = (ptr ? (PTR) realloc (ptr, size) : (PTR) malloc (size));
if (!result)
fatal ("virtual memory exhausted");
@@ -2212,7 +2349,7 @@ xrealloc (ptr, size)
char *
xstrdup (s)
- register char *s;
+ register const char *s;
{
register char *result = (char *) malloc (strlen (s) + 1);
@@ -2295,6 +2432,33 @@ set_float_handler (handler)
}
}
+/* This is a wrapper function for code which might elicit an
+ arithmetic exception. That code should be passed in as a function
+ pointer FN, and one argument DATA. DATA is usually a struct which
+ contains the real input and output for function FN. This function
+ returns 0 (failure) if longjmp was called (i.e. an exception
+ occured.) It returns 1 (success) otherwise. */
+
+int
+do_float_handler (fn, data)
+ void (*fn) PROTO ((PTR));
+ PTR data;
+{
+ jmp_buf buf;
+
+ if (setjmp (buf))
+ {
+ /* We got here via longjmp() caused by an exception in function fn() */
+ set_float_handler (NULL);
+ return 0;
+ }
+
+ set_float_handler (buf);
+ (*fn)(data);
+ set_float_handler (NULL);
+ return 1;
+}
+
/* Specify, in HANDLER, where to longjmp to when a floating arithmetic
error happens, pushing the previous specification into OLD_HANDLER.
Return an indication of whether there was a previous handler in effect. */
@@ -2363,7 +2527,7 @@ strip_off_ending (name, len)
void
output_quoted_string (asm_file, string)
FILE *asm_file;
- char *string;
+ const char *string;
{
#ifdef OUTPUT_QUOTED_STRING
OUTPUT_QUOTED_STRING (asm_file, string);
@@ -2386,16 +2550,20 @@ output_quoted_string (asm_file, string)
void
output_file_directive (asm_file, input_name)
FILE *asm_file;
- char *input_name;
+ const char *input_name;
{
int len = strlen (input_name);
- char *na = input_name + len;
+ const char *na = input_name + len;
/* NA gets INPUT_NAME sans directory names. */
while (na > input_name)
{
if (na[-1] == '/')
break;
+#ifdef DIR_SEPARATOR
+ if (na[-1] == DIR_SEPARATOR)
+ break;
+#endif
na--;
}
@@ -2412,8 +2580,8 @@ output_file_directive (asm_file, input_name)
#endif
}
+#ifdef ASM_IDENTIFY_LANGUAGE
/* Routine to build language identifier for object file. */
-
static void
output_lang_identify (asm_out_file)
FILE *asm_out_file;
@@ -2423,12 +2591,13 @@ output_lang_identify (asm_out_file)
sprintf (s, "__gnu_compiled_%s", lang_identify ());
ASM_OUTPUT_LABEL (asm_out_file, s);
}
+#endif
/* Routine to open a dump file. */
static void
open_dump_file (suffix, function_name)
- char *suffix;
- char *function_name;
+ const char *suffix;
+ const char *function_name;
{
char *dumpname;
@@ -2481,7 +2650,7 @@ close_dump_file (func, insns)
/* Routine to dump rtl into a file. */
static void
dump_rtl (suffix, decl, func, insns)
- char *suffix;
+ const char *suffix;
tree decl;
void (*func) PROTO ((FILE *, rtx));
rtx insns;
@@ -2493,9 +2662,9 @@ dump_rtl (suffix, decl, func, insns)
/* Routine to empty a dump file. */
static void
clean_dump_file (suffix)
- char * suffix;
+ const char *suffix;
{
- char * dumpname;
+ char *dumpname;
dumpname = (char *) xmalloc (strlen (dump_base_name) + strlen (suffix) + 1);
@@ -2546,6 +2715,7 @@ compile_file (name)
sched_time = 0;
local_alloc_time = 0;
global_alloc_time = 0;
+ flow2_time = 0;
sched2_time = 0;
#ifdef DELAY_SLOTS
dbr_sched_time = 0;
@@ -2594,80 +2764,163 @@ compile_file (name)
pfatal_with_name (aux_info_file_name);
}
- /* Clear the dump files file. */
+ /* Clear the dump files. */
if (rtl_dump)
clean_dump_file (".rtl");
if (jump_opt_dump)
- clean_dump_file (".jump");
+ {
+ clean_dump_file (".jump");
+ if (graph_dump_format != no_graph)
+ clean_graph_dump_file (dump_base_name, ".jump");
+ }
if (addressof_dump)
- clean_dump_file (".addressof");
+ {
+ clean_dump_file (".addressof");
+ if (graph_dump_format != no_graph)
+ clean_graph_dump_file (dump_base_name, ".addressof");
+ }
if (cse_dump)
- clean_dump_file (".cse");
+ {
+ clean_dump_file (".cse");
+ if (graph_dump_format != no_graph)
+ clean_graph_dump_file (dump_base_name, ".cse");
+ }
if (loop_dump)
- clean_dump_file (".loop");
+ {
+ clean_dump_file (".loop");
+ if (graph_dump_format != no_graph)
+ clean_graph_dump_file (dump_base_name, ".loop");
+ }
if (cse2_dump)
- clean_dump_file (".cse2");
+ {
+ clean_dump_file (".cse2");
+ if (graph_dump_format != no_graph)
+ clean_graph_dump_file (dump_base_name, ".cse2");
+ }
if (branch_prob_dump)
- clean_dump_file (".bp");
+ {
+ clean_dump_file (".bp");
+ if (graph_dump_format != no_graph)
+ clean_graph_dump_file (dump_base_name, ".bp");
+ }
if (flow_dump)
- clean_dump_file (".flow");
+ {
+ clean_dump_file (".flow");
+ if (graph_dump_format != no_graph)
+ clean_graph_dump_file (dump_base_name, ".flow");
+ }
if (combine_dump)
- clean_dump_file (".combine");
+ {
+ clean_dump_file (".combine");
+ if (graph_dump_format != no_graph)
+ clean_graph_dump_file (dump_base_name, ".combine");
+ }
if (regmove_dump)
- clean_dump_file (".regmove");
+ {
+ clean_dump_file (".regmove");
+ if (graph_dump_format != no_graph)
+ clean_graph_dump_file (dump_base_name, ".regmove");
+ }
if (sched_dump)
- clean_dump_file (".sched");
+ {
+ clean_dump_file (".sched");
+ if (graph_dump_format != no_graph)
+ clean_graph_dump_file (dump_base_name, ".sched");
+ }
if (local_reg_dump)
- clean_dump_file (".lreg");
+ {
+ clean_dump_file (".lreg");
+ if (graph_dump_format != no_graph)
+ clean_graph_dump_file (dump_base_name, ".lreg");
+ }
if (global_reg_dump)
- clean_dump_file (".greg");
+ {
+ clean_dump_file (".greg");
+ if (graph_dump_format != no_graph)
+ clean_graph_dump_file (dump_base_name, ".greg");
+ }
+ if (flow2_dump)
+ {
+ clean_dump_file (".flow2");
+ if (graph_dump_format != no_graph)
+ clean_graph_dump_file (dump_base_name, ".flow2");
+ }
if (sched2_dump)
- clean_dump_file (".sched2");
+ {
+ clean_dump_file (".sched2");
+ if (graph_dump_format != no_graph)
+ clean_graph_dump_file (dump_base_name, ".sched2");
+ }
if (jump2_opt_dump)
- clean_dump_file (".jump2");
+ {
+ clean_dump_file (".jump2");
+ if (graph_dump_format != no_graph)
+ clean_graph_dump_file (dump_base_name, ".jump2");
+ }
#ifdef DELAY_SLOTS
if (dbr_sched_dump)
- clean_dump_file (".dbr");
+ {
+ clean_dump_file (".dbr");
+ if (graph_dump_format != no_graph)
+ clean_graph_dump_file (dump_base_name, ".dbr");
+ }
#endif
if (gcse_dump)
- clean_dump_file (".gcse");
+ {
+ clean_dump_file (".gcse");
+ if (graph_dump_format != no_graph)
+ clean_graph_dump_file (dump_base_name, ".gcse");
+ }
#ifdef STACK_REGS
if (stack_reg_dump)
- clean_dump_file (".stack");
+ {
+ clean_dump_file (".stack");
+ if (graph_dump_format != no_graph)
+ clean_graph_dump_file (dump_base_name, ".stack");
+ }
#endif
#ifdef MACHINE_DEPENDENT_REORG
if (mach_dep_reorg_dump)
- clean_dump_file (".mach");
+ {
+ clean_dump_file (".mach");
+ if (graph_dump_format != no_graph)
+ clean_graph_dump_file (dump_base_name, ".mach");
+ }
#endif
/* Open assembler code output file. */
- if (! name_specified && asm_file_name == 0)
- asm_out_file = stdout;
+ if (flag_syntax_only)
+ asm_out_file = NULL;
else
{
- int len = strlen (dump_base_name);
- register char *dumpname = (char *) xmalloc (len + 6);
- strcpy (dumpname, dump_base_name);
- strip_off_ending (dumpname, len);
- strcat (dumpname, ".s");
- if (asm_file_name == 0)
- {
- asm_file_name = (char *) xmalloc (strlen (dumpname) + 1);
- strcpy (asm_file_name, dumpname);
- }
- if (!strcmp (asm_file_name, "-"))
+ if (! name_specified && asm_file_name == 0)
asm_out_file = stdout;
else
- asm_out_file = fopen (asm_file_name, "w");
- if (asm_out_file == 0)
- pfatal_with_name (asm_file_name);
- }
+ {
+ int len = strlen (dump_base_name);
+ register char *dumpname = (char *) xmalloc (len + 6);
+ strcpy (dumpname, dump_base_name);
+ strip_off_ending (dumpname, len);
+ strcat (dumpname, ".s");
+ if (asm_file_name == 0)
+ {
+ asm_file_name = (char *) xmalloc (strlen (dumpname) + 1);
+ strcpy (asm_file_name, dumpname);
+ }
+ if (!strcmp (asm_file_name, "-"))
+ asm_out_file = stdout;
+ else
+ asm_out_file = fopen (asm_file_name, "w");
+ if (asm_out_file == 0)
+ pfatal_with_name (asm_file_name);
+ }
#ifdef IO_BUFFER_SIZE
- setvbuf (asm_out_file, (char *) xmalloc (IO_BUFFER_SIZE),
- _IOFBF, IO_BUFFER_SIZE);
+ setvbuf (asm_out_file, (char *) xmalloc (IO_BUFFER_SIZE),
+ _IOFBF, IO_BUFFER_SIZE);
#endif
+ }
input_filename = name;
@@ -2686,32 +2939,41 @@ compile_file (name)
if (main_input_filename == 0)
main_input_filename = name;
- ASM_FILE_START (asm_out_file);
+ if (flag_syntax_only)
+ {
+ write_symbols = NO_DEBUG;
+ profile_flag = 0;
+ profile_block_flag = 0;
+ }
+ else
+ {
+ ASM_FILE_START (asm_out_file);
#ifdef ASM_COMMENT_START
- if (flag_verbose_asm)
- {
- /* Print the list of options in effect. */
- print_version (asm_out_file, ASM_COMMENT_START);
- print_switch_values (asm_out_file, 0, MAX_LINE,
+ if (flag_verbose_asm)
+ {
+ /* Print the list of options in effect. */
+ print_version (asm_out_file, ASM_COMMENT_START);
+ print_switch_values (asm_out_file, 0, MAX_LINE,
ASM_COMMENT_START, " ", "\n");
- /* Add a blank line here so it appears in assembler output but not
- screen output. */
- fprintf (asm_out_file, "\n");
- }
+ /* Add a blank line here so it appears in assembler output but not
+ screen output. */
+ fprintf (asm_out_file, "\n");
+ }
#endif
- /* Output something to inform GDB that this compilation was by GCC. */
+ /* Output something to inform GDB that this compilation was by GCC. */
#ifndef ASM_IDENTIFY_GCC
- fprintf (asm_out_file, "gcc2_compiled.:\n");
+ fprintf (asm_out_file, "gcc2_compiled.:\n");
#else
- ASM_IDENTIFY_GCC (asm_out_file);
+ ASM_IDENTIFY_GCC (asm_out_file);
#endif
/* Output something to identify which front-end produced this file. */
#ifdef ASM_IDENTIFY_LANGUAGE
- ASM_IDENTIFY_LANGUAGE (asm_out_file);
+ ASM_IDENTIFY_LANGUAGE (asm_out_file);
#endif
+ } /* ! flag_syntax_only */
#ifndef ASM_OUTPUT_SECTION_NAME
if (flag_function_sections)
@@ -2733,8 +2995,10 @@ compile_file (name)
flag_function_sections = 0;
}
+#ifndef OBJECT_FORMAT_ELF
if (flag_function_sections && write_symbols != NO_DEBUG)
warning ("-ffunction-sections may affect debugging on some targets.");
+#endif
/* ??? Note: There used to be a conditional here
to call assemble_zeros without fail if DBX_DEBUGGING_INFO is defined.
@@ -2796,7 +3060,7 @@ compile_file (name)
if (yyparse () != 0)
{
if (errorcount == 0)
- fprintf (stderr, "Errors detected in input file (your bison.simple is out of date)");
+ notice ("Errors detected in input file (your bison.simple is out of date)\n");
/* In case there were missing closebraces,
get us back to the global binding level. */
@@ -2804,8 +3068,6 @@ compile_file (name)
poplevel (0, 0, 0);
}
- output_func_start_profiler ();
-
/* Compilation is now finished except for writing
what's left of the symbol table output. */
@@ -2814,6 +3076,9 @@ compile_file (name)
parse_time -= integration_time;
parse_time -= varconst_time;
+ if (flag_syntax_only)
+ goto finish_syntax;
+
globals = getdecls ();
/* Really define vars that have had only a tentative definition.
@@ -2908,6 +3173,15 @@ compile_file (name)
}
}
+ /* This must occur after the loop to output deferred functions. Else
+ the profiler initializer would not be emitted if all the functions
+ in this compilation unit were deferred.
+
+ output_func_start_profiler can not cause any additional functions or
+ data to need to be output, so it need not be in the deferred function
+ loop above. */
+ output_func_start_profiler ();
+
/* Now that all possible functions have been output, we can dump
the exception table. */
@@ -2937,8 +3211,12 @@ compile_file (name)
&& ! DECL_ARTIFICIAL (decl)
&& ! TREE_PUBLIC (decl))
{
- pedwarn_with_decl (decl,
- "`%s' declared `static' but never defined");
+ if (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))
+ pedwarn_with_decl (decl,
+ "`%s' used but never defined");
+ else
+ warning_with_decl (decl,
+ "`%s' declared `static' but never defined");
/* This symbol is effectively an "extern" declaration now. */
TREE_PUBLIC (decl) = 1;
assemble_external (decl);
@@ -3055,8 +3333,9 @@ compile_file (name)
ASM_FILE_END (asm_out_file);
#endif
- /* Language-specific end of compilation actions. */
+ /* Language-specific end of compilation actions. */
+ finish_syntax:
lang_finish ();
/* Close the dump files. */
@@ -3081,9 +3360,62 @@ compile_file (name)
finish_parse ();
- if (ferror (asm_out_file) != 0 || fclose (asm_out_file) != 0)
+ if (! flag_syntax_only
+ && (ferror (asm_out_file) != 0 || fclose (asm_out_file) != 0))
fatal_io_error (asm_file_name);
+ /* Do whatever is necessary to finish printing the graphs. */
+ if (graph_dump_format != no_graph)
+ {
+ if (jump_opt_dump)
+ finish_graph_dump_file (dump_base_name, ".jump");
+ if (addressof_dump)
+ finish_graph_dump_file (dump_base_name, ".addressof");
+ if (cse_dump)
+ finish_graph_dump_file (dump_base_name, ".cse");
+ if (loop_dump)
+ finish_graph_dump_file (dump_base_name, ".loop");
+ if (cse2_dump)
+ finish_graph_dump_file (dump_base_name, ".cse2");
+ if (branch_prob_dump)
+ finish_graph_dump_file (dump_base_name, ".bp");
+ if (flow_dump)
+ finish_graph_dump_file (dump_base_name, ".flow");
+ if (combine_dump)
+ finish_graph_dump_file (dump_base_name, ".combine");
+ if (regmove_dump)
+ finish_graph_dump_file (dump_base_name, ".regmove");
+ if (sched_dump)
+ finish_graph_dump_file (dump_base_name, ".sched");
+ if (local_reg_dump)
+ finish_graph_dump_file (dump_base_name, ".lreg");
+ if (global_reg_dump)
+ finish_graph_dump_file (dump_base_name, ".greg");
+ if (flow_dump)
+ finish_graph_dump_file (dump_base_name, ".flow2");
+ if (sched2_dump)
+ finish_graph_dump_file (dump_base_name, ".sched2");
+ if (jump2_opt_dump)
+ finish_graph_dump_file (dump_base_name, ".jump2");
+#ifdef DELAY_SLOTS
+ if (dbr_sched_dump)
+ finish_graph_dump_file (dump_base_name, ".dbr");
+#endif
+ if (gcse_dump)
+ finish_graph_dump_file (dump_base_name, ".gcse");
+#ifdef STACK_REGS
+ if (stack_reg_dump)
+ finish_graph_dump_file (dump_base_name, ".stack");
+#endif
+#ifdef MACHINE_DEPENDENT_REORG
+ if (mach_dep_reorg_dump)
+ finish_graph_dump_file (dump_base_name, ".mach");
+#endif
+ }
+
+ /* Free up memory for the benefit of leak detectors. */
+ free_reg_info ();
+
/* Print the times. */
if (! quiet_flag)
@@ -3106,6 +3438,7 @@ compile_file (name)
print_time ("sched", sched_time);
print_time ("local-alloc", local_alloc_time);
print_time ("global-alloc", global_alloc_time);
+ print_time ("flow2", flow2_time);
print_time ("sched2", sched2_time);
#ifdef DELAY_SLOTS
print_time ("dbranch", dbr_sched_time);
@@ -3134,7 +3467,7 @@ compile_file (name)
void
rest_of_decl_compilation (decl, asmspec, top_level, at_end)
tree decl;
- char *asmspec;
+ const char *asmspec;
int top_level;
int at_end;
{
@@ -3244,7 +3577,7 @@ rest_of_compilation (decl)
if (DECL_SAVED_INSNS (decl) == 0)
{
int inlinable = 0;
- char *lose;
+ const char *lose;
/* If requested, consider whether to make this function inline. */
if (DECL_INLINE (decl) || flag_inline_functions)
@@ -3445,9 +3778,13 @@ rest_of_compilation (decl)
!JUMP_AFTER_REGSCAN));
/* Dump rtl code after cse, if we are doing that. */
-
+
if (cse_dump)
- close_dump_file (print_rtl, insns);
+ {
+ close_dump_file (print_rtl, insns);
+ if (graph_dump_format != no_graph)
+ print_rtl_graph_with_bb (dump_base_name, ".cse", insns);
+ }
ggc_collect ();
}
@@ -3456,8 +3793,12 @@ rest_of_compilation (decl)
reg_scan (insns, max_reg_num (), 1);
if (addressof_dump)
- dump_rtl (".addressof", decl, print_rtl, insns);
-
+ {
+ dump_rtl (".addressof", decl, print_rtl, insns);
+ if (graph_dump_format != no_graph)
+ print_rtl_graph_with_bb (dump_base_name, ".addressof", insns);
+ }
+
ggc_collect ();
/* Perform global cse. */
@@ -3466,11 +3807,24 @@ rest_of_compilation (decl)
{
if (gcse_dump)
open_dump_file (".gcse", IDENTIFIER_POINTER (DECL_NAME (decl)));
-
- TIMEVAR (gcse_time, gcse_main (insns, rtl_dump_file));
+
+ TIMEVAR (gcse_time, tem = gcse_main (insns, rtl_dump_file));
+
+ /* If gcse altered any jumps, rerun jump optimizations to clean
+ things up. */
+ if (tem)
+ {
+ TIMEVAR (jump_time, jump_optimize (insns, !JUMP_CROSS_JUMP,
+ !JUMP_NOOP_MOVES,
+ !JUMP_AFTER_REGSCAN));
+ }
if (gcse_dump)
- close_dump_file (print_rtl, insns);
+ {
+ close_dump_file (print_rtl, insns);
+ if (graph_dump_format != no_graph)
+ print_rtl_graph_with_bb (dump_base_name, ".gcse", insns);
+ }
ggc_collect ();
}
@@ -3503,11 +3857,15 @@ rest_of_compilation (decl)
}
loop_optimize (insns, rtl_dump_file, flag_unroll_loops, 1);
});
-
+
/* Dump rtl code after loop opt, if we are doing that. */
-
+
if (loop_dump)
- close_dump_file (print_rtl, insns);
+ {
+ close_dump_file (print_rtl, insns);
+ if (graph_dump_format != no_graph)
+ print_rtl_graph_with_bb (dump_base_name, ".loop", insns);
+ }
ggc_collect ();
}
@@ -3516,7 +3874,7 @@ rest_of_compilation (decl)
{
if (cse2_dump)
open_dump_file (".cse2", decl_printable_name (decl, 2));
-
+
if (flag_rerun_cse_after_loop)
{
/* Running another jump optimization pass before the second
@@ -3545,32 +3903,40 @@ rest_of_compilation (decl)
TIMEVAR (jump_time, reg_scan (insns, max_reg_num (), 0));
TIMEVAR (jump_time, thread_jumps (insns, max_reg_num (), 0));
}
-
+
/* Dump rtl code after cse, if we are doing that. */
-
+
if (cse2_dump)
- close_dump_file (print_rtl, insns);
+ {
+ close_dump_file (print_rtl, insns);
+ if (graph_dump_format != no_graph)
+ print_rtl_graph_with_bb (dump_base_name, ".cse2", insns);
+ }
ggc_collect ();
}
-
+
if (profile_arc_flag || flag_test_coverage || flag_branch_probabilities)
{
if (branch_prob_dump)
open_dump_file (".bp", decl_printable_name (decl, 2));
-
+
TIMEVAR
(branch_prob_time,
{
branch_prob (insns, rtl_dump_file);
});
-
+
if (branch_prob_dump)
- close_dump_file (print_rtl, insns);
+ {
+ close_dump_file (print_rtl, insns);
+ if (graph_dump_format != no_graph)
+ print_rtl_graph_with_bb (dump_base_name, ".bp", insns);
+ }
ggc_collect ();
}
-
+
/* We are no longer anticipating cse in this function, at least. */
cse_not_expected = 1;
@@ -3607,7 +3973,7 @@ rest_of_compilation (decl)
TIMEVAR
(flow_time,
{
- find_basic_blocks (insns, max_reg_num (), rtl_dump_file, 1);
+ find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
life_analysis (insns, max_reg_num (), rtl_dump_file);
});
@@ -3621,20 +3987,32 @@ rest_of_compilation (decl)
/* Dump rtl after flow analysis. */
if (flow_dump)
- close_dump_file (print_rtl_with_bb, insns);
-
+ {
+ close_dump_file (print_rtl_with_bb, insns);
+ if (graph_dump_format != no_graph)
+ print_rtl_graph_with_bb (dump_base_name, ".flow", insns);
+ }
+
ggc_collect ();
+
+ /* The first life analysis pass has finished. From now on we can not
+ generate any new pseudos. */
+ no_new_pseudos = 1;
/* If -opt, try combining insns through substitution. */
if (optimize > 0)
{
TIMEVAR (combine_time, combine_instructions (insns, max_reg_num ()));
-
+
/* Dump rtl code after insn combination. */
-
+
if (combine_dump)
- dump_rtl (".combine", decl, print_rtl_with_bb, insns);
+ {
+ dump_rtl (".combine", decl, print_rtl_with_bb, insns);
+ if (graph_dump_format != no_graph)
+ print_rtl_graph_with_bb (dump_base_name, ".combine", insns);
+ }
ggc_collect ();
}
@@ -3645,12 +4023,16 @@ rest_of_compilation (decl)
{
if (regmove_dump)
open_dump_file (".regmove", decl_printable_name (decl, 2));
-
+
TIMEVAR (regmove_time, regmove_optimize (insns, max_reg_num (),
rtl_dump_file));
-
+
if (regmove_dump)
- close_dump_file (print_rtl_with_bb, insns);
+ {
+ close_dump_file (print_rtl_with_bb, insns);
+ if (graph_dump_format != no_graph)
+ print_rtl_graph_with_bb (dump_base_name, ".regmove", insns);
+ }
ggc_collect ();
}
@@ -3662,16 +4044,20 @@ rest_of_compilation (decl)
{
if (sched_dump)
open_dump_file (".sched", decl_printable_name (decl, 2));
-
+
/* Do control and data sched analysis,
and write some of the results to dump file. */
TIMEVAR (sched_time, schedule_insns (rtl_dump_file));
-
+
/* Dump rtl after instruction scheduling. */
-
+
if (sched_dump)
- close_dump_file (print_rtl_with_bb, insns);
+ {
+ close_dump_file (print_rtl_with_bb, insns);
+ if (graph_dump_format != no_graph)
+ print_rtl_graph_with_bb (dump_base_name, ".sched", insns);
+ }
ggc_collect ();
}
@@ -3682,7 +4068,7 @@ rest_of_compilation (decl)
if (!obey_regdecls)
TIMEVAR (local_alloc_time,
{
- recompute_reg_usage (insns);
+ recompute_reg_usage (insns, ! optimize_size);
regclass (insns, max_reg_num ());
local_alloc ();
});
@@ -3692,11 +4078,13 @@ rest_of_compilation (decl)
if (local_reg_dump)
{
open_dump_file (".lreg", decl_printable_name (decl, 2));
-
+
TIMEVAR (dump_time, dump_flow_info (rtl_dump_file));
TIMEVAR (dump_time, dump_local_alloc (rtl_dump_file));
-
+
close_dump_file (print_rtl_with_bb, insns);
+ if (graph_dump_format != no_graph)
+ print_rtl_graph_with_bb (dump_base_name, ".lreg", insns);
}
ggc_collect ();
@@ -3704,10 +4092,6 @@ rest_of_compilation (decl)
if (global_reg_dump)
open_dump_file (".greg", decl_printable_name (decl, 2));
- /* Save the last label number used so far, so reorg can tell
- when it's safe to kill spill regs. */
- max_label_num_after_reload = max_label_num ();
-
/* Unless we did stupid register allocation,
allocate remaining pseudo-regs, then do the reload pass
fixing up any insns that are invalid. */
@@ -3725,12 +4109,65 @@ rest_of_compilation (decl)
goto exit_rest_of_compilation;
ggc_collect ();
- reload_completed = 1;
/* Do a very simple CSE pass over just the hard registers. */
if (optimize > 0)
reload_cse_regs (insns);
+ /* If optimizing and we are performing instruction scheduling after
+ reload, then go ahead and split insns now since we are about to
+ recompute flow information anyway.
+
+ reload_cse_regs may expose more splitting opportunities, expecially
+ for double-word operations. */
+ if (optimize > 0 && flag_schedule_insns_after_reload)
+ {
+ rtx insn;
+
+ for (insn = insns; insn; insn = NEXT_INSN (insn))
+ {
+ rtx last;
+
+ if (GET_RTX_CLASS (GET_CODE (insn)) != 'i')
+ continue;
+
+ last = try_split (PATTERN (insn), insn, 1);
+
+ if (last != insn)
+ {
+ PUT_CODE (insn, NOTE);
+ NOTE_SOURCE_FILE (insn) = 0;
+ NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
+ }
+ }
+ }
+
+ if (global_reg_dump)
+ {
+ TIMEVAR (dump_time, dump_global_regs (rtl_dump_file));
+ close_dump_file (print_rtl_with_bb, insns);
+ if (graph_dump_format != no_graph)
+ print_rtl_graph_with_bb (dump_base_name, ".greg", insns);
+ }
+
+ /* Re-create the death notes which were deleted during reload. */
+ if (flow2_dump)
+ open_dump_file (".flow2", decl_printable_name (decl, 2));
+
+ if (optimize)
+ {
+ TIMEVAR
+ (flow2_time,
+ {
+ find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
+ life_analysis (insns, max_reg_num (), rtl_dump_file);
+ });
+
+ ggc_collect ();
+ }
+
+ flow2_completed = 1;
+
/* 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
@@ -3738,11 +4175,13 @@ rest_of_compilation (decl)
thread_prologue_and_epilogue_insns (insns);
- if (global_reg_dump)
+ if (flow2_dump)
{
- TIMEVAR (dump_time, dump_global_regs (rtl_dump_file));
close_dump_file (print_rtl_with_bb, insns);
+ if (graph_dump_format != no_graph)
+ print_rtl_graph_with_bb (dump_base_name, ".flow2", insns);
}
+
if (optimize > 0 && flag_schedule_insns_after_reload)
{
if (sched2_dump)
@@ -3756,7 +4195,11 @@ rest_of_compilation (decl)
/* Dump rtl after post-reorder instruction scheduling. */
if (sched2_dump)
- close_dump_file (print_rtl_with_bb, insns);
+ {
+ close_dump_file (print_rtl_with_bb, insns);
+ if (graph_dump_format != no_graph)
+ print_rtl_graph_with_bb (dump_base_name, ".sched2", insns);
+ }
ggc_collect ();
}
@@ -3777,11 +4220,15 @@ rest_of_compilation (decl)
TIMEVAR (jump_time, jump_optimize (insns, JUMP_CROSS_JUMP,
JUMP_NOOP_MOVES,
!JUMP_AFTER_REGSCAN));
-
+
/* Dump rtl code after jump, if we are doing that. */
if (jump2_opt_dump)
- dump_rtl (".jump2", decl, print_rtl_with_bb, insns);
+ {
+ dump_rtl (".jump2", decl, print_rtl_with_bb, insns);
+ if (graph_dump_format != no_graph)
+ print_rtl_graph_with_bb (dump_base_name, ".jump2", insns);
+ }
ggc_collect ();
}
@@ -3791,7 +4238,12 @@ rest_of_compilation (decl)
MACHINE_DEPENDENT_REORG (insns);
if (mach_dep_reorg_dump)
- dump_rtl (".mach", decl, print_rtl_with_bb, insns);
+ {
+ dump_rtl (".mach", decl, print_rtl_with_bb, insns);
+ if (graph_dump_format != no_graph)
+ print_rtl_graph_with_bb (dump_base_name, ".mach", insns);
+ }
+
ggc_collect ();
#endif
@@ -3802,9 +4254,13 @@ rest_of_compilation (decl)
if (optimize > 0 && flag_delayed_branch)
{
TIMEVAR (dbr_sched_time, dbr_schedule (insns, rtl_dump_file));
-
+
if (dbr_sched_dump)
- dump_rtl (".dbr", decl, print_rtl_with_bb, insns);
+ {
+ dump_rtl (".dbr", decl, print_rtl_with_bb, insns);
+ if (graph_dump_format != no_graph)
+ print_rtl_graph_with_bb (dump_base_name, ".dbr", insns);
+ }
ggc_collect ();
}
@@ -3823,7 +4279,12 @@ rest_of_compilation (decl)
TIMEVAR (stack_reg_time, reg_to_stack (insns, rtl_dump_file));
if (stack_reg_dump)
- dump_rtl (".stack", decl, print_rtl_with_bb, insns);
+ {
+ dump_rtl (".stack", decl, print_rtl_with_bb, insns);
+ if (graph_dump_format != no_graph)
+ print_rtl_graph_with_bb (dump_base_name, ".stack", insns);
+ }
+
ggc_collect ();
#endif
@@ -3854,6 +4315,9 @@ rest_of_compilation (decl)
if (! quiet_flag)
fflush (asm_out_file);
+ /* Release all memory allocated by flow. */
+ free_basic_block_vars (0);
+
/* Release all memory held by regsets now */
regset_release_memory ();
});
@@ -3886,6 +4350,8 @@ rest_of_compilation (decl)
exit_rest_of_compilation:
+ free_bb_mem ();
+
/* In case the function was not output,
don't leave any temporary anonymous types
queued up for sdb output. */
@@ -3907,6 +4373,8 @@ rest_of_compilation (decl)
}
reload_completed = 0;
+ flow2_completed = 0;
+ no_new_pseudos = 0;
TIMEVAR (final_time,
{
@@ -3948,6 +4416,9 @@ rest_of_compilation (decl)
*except* what is spent in this function. */
parse_time -= get_run_time () - start_time;
+
+ /* Reset global variables. */
+ free_basic_block_vars (0);
}
static void
@@ -3955,7 +4426,7 @@ display_help ()
{
int undoc;
unsigned long i;
- char * lang;
+ const char * lang;
#ifndef USE_CPPLIB
printf ("Usage: %s input [switches]\n", progname);
@@ -3967,7 +4438,7 @@ display_help ()
for (i = NUM_ELEM (f_options); i--;)
{
- char * description = f_options[i].description;
+ const char * description = f_options[i].description;
if (description != NULL && * description != 0)
printf (" -f%-21s %s\n",
@@ -3983,7 +4454,7 @@ display_help ()
for (i = NUM_ELEM (W_options); i--;)
{
- char * description = W_options[i].description;
+ const char * description = W_options[i].description;
if (description != NULL && * description != 0)
printf (" -W%-21s %s\n",
@@ -4036,11 +4507,16 @@ display_help ()
for (i = 0; i < NUM_ELEM (documented_lang_options); i++)
{
- char * description = documented_lang_options[i].description;
- char * option = documented_lang_options[i].option;
+ const char * description = documented_lang_options[i].description;
+ const char * option = documented_lang_options[i].option;
if (description == NULL)
- undoc = 1;
+ {
+ undoc = 1;
+
+ if (extra_warnings)
+ printf (" %-23.23s [undocumented]\n", option);
+ }
else if (* description == 0)
continue;
else if (option == NULL)
@@ -4077,29 +4553,39 @@ display_help ()
for (i = NUM_ELEM (target_switches); i--;)
{
- char * option = target_switches[i].name;
- char * description = target_switches[i].description;
+ const char * option = target_switches[i].name;
+ const char * description = target_switches[i].description;
- if (option == NULL)
+ if (option == NULL || * option == 0)
continue;
else if (description == NULL)
- undoc = 1;
+ {
+ undoc = 1;
+
+ if (extra_warnings)
+ printf (" -m%-21.21s [undocumented]\n", option);
+ }
else if (* description != 0)
- doc += printf (" %-23.23s %s\n", option, description);
+ doc += printf (" -m%-21.21s %s\n", option, description);
}
#ifdef TARGET_OPTIONS
for (i = NUM_ELEM (target_options); i--;)
{
- char * option = target_options[i].prefix;
- char * description = target_options[i].description;
+ const char * option = target_options[i].prefix;
+ const char * description = target_options[i].description;
- if (option == NULL)
+ if (option == NULL || * option == 0)
continue;
else if (description == NULL)
- undoc = 1;
+ {
+ undoc = 1;
+
+ if (extra_warnings)
+ printf (" -m%-21.21s [undocumented]\n", option);
+ }
else if (* description != 0)
- doc += printf (" %-23.23s %s\n", option, description);
+ doc += printf (" -m%-21.21s %s\n", option, description);
}
#endif
if (undoc)
@@ -4124,55 +4610,59 @@ check_lang_option (option, lang_option)
lang_independent_options * indep_options;
int len;
long k;
-
+ char * space;
+
/* Ignore NULL entries. */
if (option == NULL || lang_option == NULL)
return 0;
- len = strlen (lang_option);
-
+ if ((space = strchr (lang_option, ' ')) != NULL)
+ len = space - lang_option;
+ else
+ len = strlen (lang_option);
+
/* If they do not match to the first n characters then fail. */
if (strncmp (option, lang_option, len) != 0)
return 0;
-
+
/* Do not accept a lang option, if it matches a normal -f or -W
option. Chill defines a -fpack, but we want to support
-fpack-struct. */
-
+
/* An exact match is OK */
- if (strlen (option) == len)
+ if ((int) strlen (option) == len)
return 1;
-
+
/* If it is not an -f or -W option allow the match */
if (option[0] != '-')
return 1;
-
+
switch (option[1])
{
case 'f': indep_options = f_options; break;
case 'W': indep_options = W_options; break;
default: return 1;
}
-
+
/* The option is a -f or -W option.
Skip past the prefix and search for the remainder in the
appropriate table of options. */
option += 2;
-
+
if (option[0] == 'n' && option[1] == 'o' && option[2] == '-')
option += 3;
-
+
for (k = NUM_ELEM (indep_options); k--;)
{
if (!strcmp (option, indep_options[k].string))
{
/* The option matched a language independent option,
do not allow the language specific match. */
-
+
return 0;
}
}
-
+
/* The option matches the start of the langauge specific option
and it is not an exact match for a language independent option. */
return 1;
@@ -4218,6 +4708,12 @@ main (argc, argv)
}
#endif
+#ifdef HAVE_LC_MESSAGES
+ setlocale (LC_MESSAGES, "");
+#endif
+ (void) bindtextdomain (PACKAGE, localedir);
+ (void) textdomain (PACKAGE);
+
signal (SIGFPE, float_signal);
#ifdef SIGPIPE
@@ -4244,30 +4740,32 @@ main (argc, argv)
if (!strcmp (argv[i], "-O"))
{
optimize = 1;
+ optimize_size = 0;
}
else if (argv[i][0] == '-' && argv[i][1] == 'O')
{
/* Handle -Os, -O2, -O3, -O69, ... */
char *p = &argv[i][2];
- int c;
if ((p[0] == 's') && (p[1] == 0))
- optimize_size = 1;
+ {
+ optimize_size = 1;
+
+ /* Optimizing for size forces optimize to be 2. */
+ optimize = 2;
+ }
else
{
- while ((c = *p++))
- if (! (c >= '0' && c <= '9'))
- break;
- if (c == 0)
- optimize = atoi (&argv[i][2]);
+ const int optimize_val = read_integral_parameter (p, p - 2, -1);
+ if (optimize_val != -1)
+ {
+ optimize = optimize_val;
+ optimize_size = 0;
+ }
}
}
}
- /* Optimizing for size forces optimize to be no less than 2. */
- if (optimize_size && (optimize < 2))
- optimize = 2;
-
obey_regdecls = (optimize == 0);
if (optimize >= 1)
@@ -4369,6 +4867,7 @@ main (argc, argv)
dbr_sched_dump = 1;
#endif
flow_dump = 1;
+ flow2_dump = 1;
global_reg_dump = 1;
jump_opt_dump = 1;
addressof_dump = 1;
@@ -4460,12 +4959,21 @@ main (argc, argv)
case 'N':
regmove_dump = 1;
break;
+ case 'v':
+ graph_dump_format = vcg;
+ break;
+ case 'w':
+ flow2_dump = 1;
+ break;
case 'y':
set_yydebug (1);
break;
case 'x':
rtl_dump_and_exit = 1;
break;
+ case 'D': /* these are handled by the preprocessor */
+ case 'I':
+ break;
default:
warning ("unrecognised gcc debugging option: %c", p[-1]);
break;
@@ -4518,16 +5026,7 @@ main (argc, argv)
}
else if (str[0] == 'O')
{
- register char *p = str+1;
- if (*p == 's')
- p++;
- else
- while (*p && *p >= '0' && *p <= '9')
- p++;
- if (*p == '\0')
- ;
- else
- error ("Invalid option `%s'", argv[i]);
+ /* Already been treated above. Do nothing. */
}
else if (!strcmp (str, "pedantic"))
pedantic = 1;
@@ -4580,39 +5079,23 @@ main (argc, argv)
;
else if (!strncmp (p, "id-clash-", 9))
{
- char *endp = p + 9;
-
- while (*endp)
+ const int id_clash_val
+ = read_integral_parameter (p + 9, p - 2, -1);
+ if (id_clash_val != -1)
{
- if (*endp >= '0' && *endp <= '9')
- endp++;
- else
- {
- error ("Invalid option `%s'", argv[i]);
- goto id_clash_lose;
- }
+ id_clash_len = id_clash_val;
+ warn_id_clash = 1;
}
- warn_id_clash = 1;
- id_clash_len = atoi (str + 10);
- id_clash_lose: ;
}
else if (!strncmp (p, "larger-than-", 12))
{
- char *endp = p + 12;
-
- while (*endp)
+ const int larger_than_val
+ = read_integral_parameter (p + 12, p - 2, -1);
+ if (larger_than_val != -1)
{
- if (*endp >= '0' && *endp <= '9')
- endp++;
- else
- {
- error ("Invalid option `%s'", argv[i]);
- goto larger_than_lose;
- }
+ larger_than_size = larger_than_val;
+ warn_larger_than = 1;
}
- warn_larger_than = 1;
- larger_than_size = atoi (str + 13);
- larger_than_lose: ;
}
else
error ("Invalid option `%s'", argv[i]);
@@ -4640,7 +5123,6 @@ main (argc, argv)
}
else if (str[0] == 'g')
{
- unsigned len;
unsigned level;
/* A lot of code assumes write_symbols == NO_DEBUG if the
debugging level is 0 (thus -gstabs1 -gstabs0 would lose track
@@ -4653,53 +5135,60 @@ main (argc, argv)
-gdwarf -g3 is equivalent to -gdwarf3. */
static int type_explicitly_set_p = 0;
/* Indexed by enum debug_info_type. */
- static char *debug_type_names[] =
+ static const char *debug_type_names[] =
{
"none", "stabs", "coff", "dwarf-1", "dwarf-2", "xcoff"
};
+ /* The maximum admissible debug level value. */
+ static const unsigned max_debug_level = 3;
+
/* Look up STR in the table. */
for (da = debug_args; da->arg; da++)
{
- if (! strncmp (str, da->arg, strlen (da->arg)))
+ const int da_len = strlen (da->arg);
+
+ if (! strncmp (str, da->arg, da_len))
{
enum debug_info_type type = da->debug_type;
- char *p, *q;
+ const char *p = str + da_len;
- p = str + strlen (da->arg);
if (*p && (*p < '0' || *p > '9'))
continue;
- len = p - str;
- q = p;
- while (*q && (*q >= '0' && *q <= '9'))
- q++;
+
+ /* A debug flag without a level defaults to level 2.
+ Note we do not want to call read_integral_parameter
+ for that case since it will call atoi which
+ will return zero.
+
+ ??? We may want to generalize the interface to
+ read_integral_parameter to better handle this case
+ if this case shows up often. */
if (*p)
+ level = read_integral_parameter (p, 0,
+ max_debug_level + 1);
+ else
+ level = 2;
+
+ if (da_len > 1 && !strncmp (str, "gdwarf", da_len))
{
- level = atoi (p);
- if (len > 1 && !strncmp (str, "gdwarf", len))
- {
- error ("use -gdwarf -g%d for DWARF v1, level %d",
- level, level);
- if (level == 2)
- error ("use -gdwarf-2 for DWARF v2");
- }
+ error ("use -gdwarf -g%d for DWARF v1, level %d",
+ level, level);
+ if (level == 2)
+ error ("use -gdwarf-2 for DWARF v2");
}
- else
- level = 2; /* default debugging info level */
- if (*q || level > 3)
+
+ if (level > max_debug_level)
{
- warning ("invalid debug level specification in option: `-%s'",
- str);
- /* ??? This error message is incorrect in the case of
- -g4 -g. */
- warning ("no debugging information will be generated");
- level = 0;
+ warning ("ignoring option `%s' due to invalid debug level specification",
+ str - 1);
+ level = debug_info_level;
}
if (type == NO_DEBUG)
{
type = PREFERRED_DEBUGGING_TYPE;
- if (len > 1 && strncmp (str, "ggdb", len) == 0)
+ if (da_len > 1 && strncmp (str, "ggdb", da_len) == 0)
{
#if defined (DWARF2_DEBUGGING_INFO) && !defined (LINKER_DOES_NOT_WORK_WITH_DWARF2)
type = DWARF2_DEBUG;
@@ -4753,8 +5242,19 @@ main (argc, argv)
}
else if (str[0] == 'G')
{
- g_switch_set = TRUE;
- g_switch_value = atoi ((str[1] != '\0') ? str+1 : argv[++i]);
+ const int g_switch_val = (str[1] != '\0') ?
+ read_integral_parameter(str + 1, 0, -1) :
+ read_integral_parameter(argv[++i], 0, -1);
+
+ if (g_switch_val != -1)
+ {
+ g_switch_set = TRUE;
+ g_switch_value = g_switch_val;
+ }
+ else
+ {
+ error("Invalid option `-%s'",str);
+ }
}
else if (!strncmp (str, "aux-info", 8))
{
@@ -4837,6 +5337,21 @@ main (argc, argv)
warning ("this target machine does not have delayed branches");
#endif
+ user_label_prefix = USER_LABEL_PREFIX;
+ if (flag_leading_underscore != -1)
+ {
+ /* If the default prefix is more complicated than "" or "_",
+ issue a warning and ignore this option. */
+ if (user_label_prefix[0] == 0 ||
+ (user_label_prefix[0] == '_' && user_label_prefix[1] == 0))
+ {
+ user_label_prefix = flag_leading_underscore ? "_" : "";
+ }
+ else
+ warning ("-f%sleading-underscore not supported on this target machine",
+ flag_leading_underscore ? "" : "no-");
+ }
+
/* If we are in verbose mode, write out the version and maybe all the
option flags in use. */
if (version_flag)
@@ -4848,12 +5363,12 @@ main (argc, argv)
compile_file (filename);
-#if !defined(OS2) && !defined(VMS) && (!defined(_WIN32) || defined (__CYGWIN32__))
+#if !defined(OS2) && !defined(VMS) && (!defined(_WIN32) || defined (__CYGWIN__)) && !defined(__INTERIX)
if (flag_print_mem)
{
char *lim = (char *) sbrk (0);
- fprintf (stderr, "Data size %ld.\n", (long)(lim - (char *) &environ));
+ notice ("Data size %ld.\n", (long) (lim - (char *) &environ));
fflush (stderr);
#ifndef __MSDOS__
@@ -4864,7 +5379,7 @@ main (argc, argv)
#endif /* not USG */
#endif
}
-#endif /* ! OS2 && ! VMS && (! _WIN32 || CYGWIN32) */
+#endif /* ! OS2 && ! VMS && (! _WIN32 || CYGWIN) && ! __INTERIX */
if (errorcount)
exit (FATAL_EXIT_CODE);
@@ -4879,10 +5394,10 @@ main (argc, argv)
static void
set_target_switch (name)
- char *name;
+ const char *name;
{
register size_t j;
- int valid = 0;
+ int valid_target_option = 0;
for (j = 0; j < sizeof target_switches / sizeof target_switches[0]; j++)
if (!strcmp (target_switches[j].name, name))
@@ -4891,23 +5406,23 @@ set_target_switch (name)
target_flags &= ~-target_switches[j].value;
else
target_flags |= target_switches[j].value;
- valid = 1;
+ valid_target_option = 1;
}
#ifdef TARGET_OPTIONS
- if (!valid)
+ if (!valid_target_option)
for (j = 0; j < sizeof target_options / sizeof target_options[0]; j++)
{
int len = strlen (target_options[j].prefix);
if (!strncmp (target_options[j].prefix, name, len))
{
*target_options[j].variable = name + len;
- valid = 1;
+ valid_target_option = 1;
}
}
#endif
- if (!valid)
+ if (!valid_target_option)
error ("Invalid option `%s'", name);
}
@@ -4918,19 +5433,19 @@ set_target_switch (name)
static void
print_version (file, indent)
FILE *file;
- char *indent;
+ const char *indent;
{
- fprintf (file, "%s%s%s version %s", indent, *indent != 0 ? " " : "",
- language_string, version_string);
- fprintf (file, " (%s)", TARGET_NAME);
-#ifdef __GNUC__
#ifndef __VERSION__
-#define __VERSION__ "[unknown]"
+#define __VERSION__ "[?]"
#endif
- fprintf (file, " compiled by GNU C version %s.\n", __VERSION__);
+ fnotice (file,
+#ifdef __GNUC__
+ "%s%s%s version %s (%s) compiled by GNU C version %s.\n"
#else
- fprintf (file, " compiled by CC.\n");
+ "%s%s%s version %s (%s) compiled by CC.\n"
#endif
+ , indent, *indent != 0 ? " " : "",
+ language_string, version_string, TARGET_NAME, __VERSION__);
}
/* Print an option value and return the adjusted position in the line.
@@ -4941,7 +5456,7 @@ static int
print_single_switch (file, pos, max, indent, sep, term, type, name)
FILE *file;
int pos, max;
- char *indent, *sep, *term, *type, *name;
+ const char *indent, *sep, *term, *type, *name;
{
/* The ultrix fprintf returns 0 on success, so compute the result we want
here since we need it for the following test. */
@@ -4972,7 +5487,7 @@ static void
print_switch_values (file, pos, max, indent, sep, term)
FILE *file;
int pos, max;
- char *indent, *sep, *term;
+ const char *indent, *sep, *term;
{
size_t j;
char **p;
@@ -4980,7 +5495,7 @@ print_switch_values (file, pos, max, indent, sep, term)
/* Print the options as passed. */
pos = print_single_switch (file, pos, max, indent, *indent ? " " : "", term,
- "options passed: ", "");
+ _("options passed: "), "");
for (p = &save_argv[1]; *p != NULL; p++)
if (**p == '-')
@@ -5009,7 +5524,7 @@ print_switch_values (file, pos, max, indent, sep, term)
should suffice. */
pos = print_single_switch (file, 0, max, indent, *indent ? " " : "", term,
- "options enabled: ", "");
+ _("options enabled: "), "");
for (j = 0; j < sizeof f_options / sizeof f_options[0]; j++)
if (*f_options[j].variable == f_options[j].on_value)
@@ -5046,7 +5561,7 @@ print_switch_values (file, pos, max, indent, sep, term)
void
debug_start_source_file (filename)
- register char *filename;
+ register char *filename ATTRIBUTE_UNUSED;
{
#ifdef DBX_DEBUGGING_INFO
if (write_symbols == DBX_DEBUG)
@@ -5073,7 +5588,7 @@ debug_start_source_file (filename)
void
debug_end_source_file (lineno)
- register unsigned lineno;
+ register unsigned lineno ATTRIBUTE_UNUSED;
{
#ifdef DBX_DEBUGGING_INFO
if (write_symbols == DBX_DEBUG)
@@ -5101,8 +5616,8 @@ debug_end_source_file (lineno)
void
debug_define (lineno, buffer)
- register unsigned lineno;
- register char *buffer;
+ register unsigned lineno ATTRIBUTE_UNUSED;
+ register char *buffer ATTRIBUTE_UNUSED;
{
#ifdef DWARF_DEBUGGING_INFO
if (debug_info_level == DINFO_LEVEL_VERBOSE
@@ -5122,8 +5637,8 @@ debug_define (lineno, buffer)
void
debug_undef (lineno, buffer)
- register unsigned lineno;
- register char *buffer;
+ register unsigned lineno ATTRIBUTE_UNUSED;
+ register char *buffer ATTRIBUTE_UNUSED;
{
#ifdef DWARF_DEBUGGING_INFO
if (debug_info_level == DINFO_LEVEL_VERBOSE
diff --git a/gcc/toplev.h b/gcc/toplev.h
index 740dda12c31..05a9c40315b 100644
--- a/gcc/toplev.h
+++ b/gcc/toplev.h
@@ -1,75 +1,113 @@
/* toplev.h - Various declarations for functions found in toplev.c
- Copyright (C) 1998 Free Software Foundation, Inc.
- */
+ Copyright (C) 1998, 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. */
#ifndef __GCC_TOPLEV_H__
#define __GCC_TOPLEV_H__
-#ifdef __STDC__
+#ifdef ANSI_PROTOTYPES
union tree_node;
struct rtx_def;
#endif
+extern int read_integral_parameter PROTO ((const char *, const char *,
+ const int));
extern int count_error PROTO ((int));
extern void strip_off_ending PROTO ((char *, int));
-extern void print_time PROTO ((char *, int));
-extern int get_run_time PROTO ((void));
+extern void print_time PROTO ((const char *, int));
extern void debug_start_source_file PROTO ((char *));
extern void debug_end_source_file PROTO ((unsigned));
extern void debug_define PROTO ((unsigned, char *));
extern void debug_undef PROTO ((unsigned, char *));
-extern void fatal PVPROTO ((char *, ...))
+extern void fatal PVPROTO ((const char *, ...))
ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN;
-extern void fatal_io_error PROTO ((char *)) ATTRIBUTE_NORETURN;
-extern void pfatal_with_name PROTO ((char *)) ATTRIBUTE_NORETURN;
+extern void fatal_io_error PROTO ((const char *))
+ ATTRIBUTE_NORETURN;
+extern void pfatal_with_name PROTO ((const char *))
+ ATTRIBUTE_NORETURN;
extern void fatal_insn_not_found PROTO ((struct rtx_def *))
ATTRIBUTE_NORETURN;
-extern void fatal_insn PROTO ((char *, struct rtx_def *))
+extern void fatal_insn PROTO ((const char *, struct rtx_def *))
ATTRIBUTE_NORETURN;
-extern void warning PVPROTO ((char *, ...))
- ATTRIBUTE_PRINTF_1;
-extern void error PVPROTO ((char *, ...))
+extern void warning PVPROTO ((const char *, ...))
ATTRIBUTE_PRINTF_1;
-extern void pedwarn PVPROTO ((char *, ...))
+extern void error PVPROTO ((const char *, ...))
ATTRIBUTE_PRINTF_1;
-extern void pedwarn_with_file_and_line PVPROTO ((char *, int, char *, ...))
- ATTRIBUTE_PRINTF_3;
-extern void warning_with_file_and_line PVPROTO ((char *, int, char *, ...))
- ATTRIBUTE_PRINTF_3;
-extern void error_with_file_and_line PVPROTO ((char *, int, char *, ...))
- ATTRIBUTE_PRINTF_3;
-extern void sorry PVPROTO ((char *s, ...))
+extern void pedwarn PVPROTO ((const char *, ...))
ATTRIBUTE_PRINTF_1;
-extern void really_sorry PVPROTO((char *s, ...))
+extern void pedwarn_with_file_and_line PVPROTO ((const char *, int,
+ const char *, ...))
+ ATTRIBUTE_PRINTF_3;
+extern void warning_with_file_and_line PVPROTO ((const char *, int,
+ const char *, ...))
+ ATTRIBUTE_PRINTF_3;
+extern void error_with_file_and_line PVPROTO ((const char *, int,
+ const char *, ...))
+ ATTRIBUTE_PRINTF_3;
+extern void sorry PVPROTO ((const char *, ...))
+ ATTRIBUTE_PRINTF_1;
+extern void really_sorry PVPROTO((const char *, ...))
ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN;
-extern void default_print_error_function PROTO ((char *));
-extern void report_error_function PROTO ((char *));
+extern void default_print_error_function PROTO ((const char *));
+extern void report_error_function PROTO ((const char *));
-extern void rest_of_decl_compilation PROTO ((union tree_node *, char *, int, int));
+extern void rest_of_decl_compilation PROTO ((union tree_node *,
+ const char *, int, int));
extern void rest_of_type_compilation PROTO ((union tree_node *, int));
extern void rest_of_compilation PROTO ((union tree_node *));
-extern void pedwarn_with_decl PVPROTO ((union tree_node *, char *, ...));
-extern void warning_with_decl PVPROTO ((union tree_node *, char *, ...));
-extern void error_with_decl PVPROTO ((union tree_node *, char *, ...));
+
+/* The *_with_decl functions aren't suitable for ATTRIBUTE_PRINTF. */
+extern void pedwarn_with_decl PVPROTO ((union tree_node *,
+ const char *, ...));
+extern void warning_with_decl PVPROTO ((union tree_node *,
+ const char *, ...));
+extern void error_with_decl PVPROTO ((union tree_node *,
+ const char *, ...));
+
extern void announce_function PROTO ((union tree_node *));
-extern void error_for_asm PVPROTO((struct rtx_def *, char *, ...))
- ATTRIBUTE_PRINTF_2;
-extern void warning_for_asm PVPROTO((struct rtx_def *, char *, ...))
- ATTRIBUTE_PRINTF_2;
-#ifdef _JBLEN
+extern void error_for_asm PVPROTO((struct rtx_def *,
+ const char *, ...))
+ ATTRIBUTE_PRINTF_2;
+extern void warning_for_asm PVPROTO((struct rtx_def *,
+ const char *, ...))
+ ATTRIBUTE_PRINTF_2;
+#if defined (_JBLEN) || defined (setjmp)
extern void set_float_handler PROTO((jmp_buf));
extern int push_float_handler PROTO((jmp_buf, jmp_buf));
extern void pop_float_handler PROTO((int, jmp_buf));
#endif
+extern int do_float_handler PROTO((void (*) (PTR), PTR));
#ifdef BUFSIZ
-extern void output_quoted_string PROTO ((FILE *, char *));
-extern void output_file_directive PROTO ((FILE *, char *));
+extern void output_quoted_string PROTO ((FILE *, const char *));
+extern void output_file_directive PROTO ((FILE *, const char *));
#endif
extern void fancy_abort PROTO ((void)) ATTRIBUTE_NORETURN;
extern void do_abort PROTO ((void)) ATTRIBUTE_NORETURN;
-extern void botch PROTO ((char *)) ATTRIBUTE_NORETURN;
+extern void botch PROTO ((const char *))
+ ATTRIBUTE_NORETURN;
+
+#ifdef BUFSIZ
+extern void fnotice PROTO ((FILE *, const char *, ...))
+ ATTRIBUTE_PRINTF_2;
+#endif
#endif /* __GCC_TOPLEV_H */
diff --git a/gcc/tree.c b/gcc/tree.c
index 0d6b42adbae..1132434e093 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -1,5 +1,5 @@
/* Language-independent node constructors for parse phase of GNU compiler.
- Copyright (C) 1987, 88, 92-97, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1987, 88, 92-98, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -35,7 +35,6 @@ Boston, MA 02111-1307, USA. */
#include "config.h"
#include "system.h"
-#include <setjmp.h>
#include "flags.h"
#include "tree.h"
#include "except.h"
@@ -226,7 +225,7 @@ int tree_node_counts[(int)all_kinds];
int tree_node_sizes[(int)all_kinds];
int id_string_size = 0;
-char *tree_node_kind_names[] = {
+const char *tree_node_kind_names[] = {
"decls",
"types",
"blocks",
@@ -265,6 +264,10 @@ int (*lang_get_alias_set) PROTO((tree));
codes are made. */
#define TYPE_HASH(TYPE) ((unsigned long) (TYPE) & 0777777)
+static void set_type_quals PROTO((tree, int));
+static void append_random_chars PROTO((char *));
+static void build_real_from_int_cst_1 PROTO((PTR));
+
extern char *mode_name[];
void gcc_obstack_init ();
@@ -289,8 +292,11 @@ gcc_obstack_init (obstack)
(void (*) ()) OBSTACK_CHUNK_FREE);
}
-/* Save all variables describing the current status into the structure *P.
- This is used before starting a nested function.
+/* Save all variables describing the current status into the structure
+ *P. This function is called whenever we start compiling one
+ function in the midst of compiling another. For example, when
+ compiling a nested function, or, in C++, a template instantiation
+ that is required by the function we are currently compiling.
CONTEXT is the decl_function_context for the function we're about to
compile; if it isn't current_function_decl, we have to play some games. */
@@ -314,7 +320,7 @@ save_tree_status (p, context)
p->rtl_obstack = rtl_obstack;
p->inline_obstacks = inline_obstacks;
- if (context == current_function_decl)
+ if (current_function_decl && context == current_function_decl)
/* Objects that need to be saved in this function can be in the nonsaved
obstack of the enclosing function since they can't possibly be needed
once it has returned. */
@@ -718,10 +724,10 @@ void
print_obstack_name (object, file, prefix)
char *object;
FILE *file;
- char *prefix;
+ const char *prefix;
{
struct obstack *obstack = NULL;
- char *obstack_name = NULL;
+ const char *obstack_name = NULL;
struct function *p;
for (p = outer_function_chain; p; p = p->next)
@@ -915,7 +921,6 @@ make_node (code)
register int type = TREE_CODE_CLASS (code);
register int length = 0;
register struct obstack *obstack = current_obstack;
- register int i;
#ifdef GATHER_STATISTICS
register tree_node_kind kind;
#endif
@@ -1071,6 +1076,9 @@ make_node (code)
DECL_SOURCE_LINE (t) = lineno;
DECL_SOURCE_FILE (t) = (input_filename) ? input_filename : "<built-in>";
DECL_UID (t) = next_decl_uid++;
+ /* Note that we have not yet computed the alias set for this
+ declaration. */
+ DECL_POINTER_ALIAS_SET (t) = -1;
break;
case 't':
@@ -1105,7 +1113,6 @@ copy_node (node)
register tree t;
register enum tree_code code = TREE_CODE (node);
register int length = 0;
- register int i;
switch (TREE_CODE_CLASS (code))
{
@@ -1154,12 +1161,7 @@ copy_node (node)
}
t = ggc_alloc_tree (length);
-
- for (i = (length / sizeof (int)) - 1; i >= 0; i--)
- ((int *) t)[i] = ((int *) node)[i];
- /* Clear any extra bytes. */
- for (i = length / sizeof (int) * sizeof (int); i < length; i++)
- ((char *) t)[i] = ((char *) node)[i];
+ memcpy (t, node, length);
/* EXPR_WITH_FILE_LOCATION must keep filename info stored in TREE_CHAIN */
if (TREE_CODE (node) != EXPR_WITH_FILE_LOCATION)
@@ -1219,7 +1221,7 @@ copy_list (list)
tree
get_identifier (text)
- register char *text;
+ register const char *text;
{
register int hi;
register int i;
@@ -1231,7 +1233,7 @@ get_identifier (text)
/* Decide how much of that length to hash on */
hash_len = len;
- if (warn_id_clash && len > id_clash_len)
+ if (warn_id_clash && (unsigned)len > id_clash_len)
hash_len = id_clash_len;
/* Compute hash code */
@@ -1250,7 +1252,7 @@ get_identifier (text)
return idp; /* <-- return if found */
/* Not found; optionally warn about a similar identifier */
- if (warn_id_clash && do_identifier_warnings && len >= id_clash_len)
+ if (warn_id_clash && do_identifier_warnings && (unsigned)len >= id_clash_len)
for (idp = hash_table[hi]; idp; idp = TREE_CHAIN (idp))
if (!strncmp (IDENTIFIER_POINTER (idp), text, id_clash_len))
{
@@ -1282,7 +1284,7 @@ get_identifier (text)
tree
maybe_get_identifier (text)
- register char *text;
+ register const char *text;
{
register int hi;
register int i;
@@ -1290,11 +1292,11 @@ maybe_get_identifier (text)
register int len, hash_len;
/* Compute length of text in len. */
- for (len = 0; text[len]; len++);
+ len = strlen (text);
/* Decide how much of that length to hash on */
hash_len = len;
- if (warn_id_clash && len > id_clash_len)
+ if (warn_id_clash && (unsigned)len > id_clash_len)
hash_len = id_clash_len;
/* Compute hash code */
@@ -1425,6 +1427,29 @@ real_value_from_int_cst (type, i)
return d;
}
+struct brfic_args
+{
+ /* Input */
+ tree type, i;
+ /* Output */
+ REAL_VALUE_TYPE d;
+};
+
+static void
+build_real_from_int_cst_1 (data)
+ PTR data;
+{
+ struct brfic_args * args = (struct brfic_args *) data;
+
+#ifdef REAL_ARITHMETIC
+ args->d = real_value_from_int_cst (args->type, args->i);
+#else
+ args->d =
+ REAL_VALUE_TRUNCATE (TYPE_MODE (args->type),
+ real_value_from_int_cst (args->type, args->i));
+#endif
+}
+
/* This function can't be implemented if we can't do arithmetic
on the float representation. */
@@ -1436,32 +1461,29 @@ build_real_from_int_cst (type, i)
tree v;
int overflow = TREE_OVERFLOW (i);
REAL_VALUE_TYPE d;
- jmp_buf float_error;
+ struct brfic_args args;
v = make_node (REAL_CST);
TREE_TYPE (v) = type;
- if (setjmp (float_error))
+ /* Setup input for build_real_from_int_cst_1() */
+ args.type = type;
+ args.i = i;
+
+ if (do_float_handler (build_real_from_int_cst_1, (PTR) &args))
+ {
+ /* Receive output from build_real_from_int_cst_1() */
+ d = args.d;
+ }
+ else
{
+ /* We got an exception from build_real_from_int_cst_1() */
d = dconst0;
overflow = 1;
- goto got_it;
}
-
- set_float_handler (float_error);
-
-#ifdef REAL_ARITHMETIC
- d = real_value_from_int_cst (type, i);
-#else
- d = REAL_VALUE_TRUNCATE (TYPE_MODE (type),
- real_value_from_int_cst (type, i));
-#endif
-
+
/* Check for valid float value for this type on this target machine. */
- got_it:
- set_float_handler (NULL_PTR);
-
#ifdef CHECK_FLOAT_VALUE
CHECK_FLOAT_VALUE (TYPE_MODE (type), d, overflow);
#endif
@@ -1480,7 +1502,7 @@ build_real_from_int_cst (type, i)
tree
build_string (len, str)
int len;
- char *str;
+ const char *str;
{
/* Put the string in saveable_obstack since it will be placed in the RTL
for an "asm" statement and will also be kept around a while if
@@ -1522,7 +1544,6 @@ make_tree_vec (len)
register tree t;
register int length = (len-1) * sizeof (tree) + sizeof (struct tree_vec);
register struct obstack *obstack = current_obstack;
- register int i;
#ifdef GATHER_STATISTICS
tree_node_counts[(int)vec_kind]++;
@@ -2359,6 +2380,7 @@ first_rtl_op (code)
{
case SAVE_EXPR:
return 2;
+ case GOTO_SUBROUTINE_EXPR:
case RTL_EXPR:
return 0;
case CALL_EXPR:
@@ -2552,6 +2574,7 @@ has_cleanups (exp)
switch (TREE_CODE (exp))
{
case TARGET_EXPR:
+ case GOTO_SUBROUTINE_EXPR:
case WITH_CLEANUP_EXPR:
return 1;
@@ -2942,7 +2965,7 @@ stabilize_reference_1 (e)
tree
build VPROTO((enum tree_code code, tree tt, ...))
{
-#ifndef __STDC__
+#ifndef ANSI_PROTOTYPES
enum tree_code code;
tree tt;
#endif
@@ -2953,7 +2976,7 @@ build VPROTO((enum tree_code code, tree tt, ...))
VA_START (p, tt);
-#ifndef __STDC__
+#ifndef ANSI_PROTOTYPES
code = va_arg (p, enum tree_code);
tt = va_arg (p, tree);
#endif
@@ -3017,7 +3040,7 @@ build1 (code, type, node)
tree node;
{
register struct obstack *obstack = expression_obstack;
- register int i, length;
+ register int length;
#ifdef GATHER_STATISTICS
register tree_node_kind kind;
#endif
@@ -3065,7 +3088,7 @@ build1 (code, type, node)
tree
build_nt VPROTO((enum tree_code code, ...))
{
-#ifndef __STDC__
+#ifndef ANSI_PROTOTYPES
enum tree_code code;
#endif
va_list p;
@@ -3075,7 +3098,7 @@ build_nt VPROTO((enum tree_code code, ...))
VA_START (p, code);
-#ifndef __STDC__
+#ifndef ANSI_PROTOTYPES
code = va_arg (p, enum tree_code);
#endif
@@ -3095,7 +3118,7 @@ build_nt VPROTO((enum tree_code code, ...))
tree
build_parse_node VPROTO((enum tree_code code, ...))
{
-#ifndef __STDC__
+#ifndef ANSI_PROTOTYPES
enum tree_code code;
#endif
register struct obstack *ambient_obstack = expression_obstack;
@@ -3106,7 +3129,7 @@ build_parse_node VPROTO((enum tree_code code, ...))
VA_START (p, code);
-#ifndef __STDC__
+#ifndef ANSI_PROTOTYPES
code = va_arg (p, enum tree_code);
#endif
@@ -3194,10 +3217,10 @@ build_block (vars, tags, subblocks, supercontext, chain)
tree
build_expr_wfl (node, file, line, col)
tree node;
- char *file;
+ const char *file;
int line, col;
{
- static char *last_file = 0;
+ static const char *last_file = 0;
static tree last_filenode = NULL_TREE;
register tree wfl = make_node (EXPR_WITH_FILE_LOCATION);
@@ -3256,7 +3279,7 @@ build_type_attribute_variant (ttype, attribute)
/* Create a new main variant of TYPE. */
TYPE_MAIN_VARIANT (ntype) = ntype;
TYPE_NEXT_VARIANT (ntype) = 0;
- TYPE_READONLY (ntype) = TYPE_VOLATILE (ntype) = 0;
+ set_type_quals (ntype, TYPE_UNQUALIFIED);
hashcode = TYPE_HASH (TREE_CODE (ntype))
+ TYPE_HASH (TREE_TYPE (ntype))
@@ -3281,8 +3304,7 @@ build_type_attribute_variant (ttype, attribute)
}
ntype = type_hash_canon (hashcode, ntype);
- ttype = build_type_variant (ntype, TYPE_READONLY (ttype),
- TYPE_VOLATILE (ttype));
+ ttype = build_qualified_type (ntype, TYPE_QUALS (ttype));
}
return ttype;
@@ -3294,11 +3316,12 @@ build_type_attribute_variant (ttype, attribute)
int
valid_machine_attribute (attr_name, attr_args, decl, type)
- tree attr_name, attr_args;
- tree decl;
- tree type;
+ tree attr_name;
+ tree attr_args ATTRIBUTE_UNUSED;
+ tree decl ATTRIBUTE_UNUSED;
+ tree type ATTRIBUTE_UNUSED;
{
- int valid = 0;
+ int validated = 0;
#ifdef VALID_MACHINE_DECL_ATTRIBUTE
tree decl_attr_list = decl != 0 ? DECL_MACHINE_ATTRIBUTES (decl) : 0;
#endif
@@ -3328,12 +3351,12 @@ valid_machine_attribute (attr_name, attr_args, decl, type)
decl = build_decl_attribute_variant (decl, decl_attr_list);
}
- valid = 1;
+ validated = 1;
}
#endif
#ifdef VALID_MACHINE_TYPE_ATTRIBUTE
- if (valid)
+ if (validated)
/* Don't apply the attribute to both the decl and the type. */;
else if (VALID_MACHINE_TYPE_ATTRIBUTE (type, type_attr_list, attr_name,
attr_args))
@@ -3362,7 +3385,7 @@ valid_machine_attribute (attr_name, attr_args, decl, type)
}
if (decl != 0)
TREE_TYPE (decl) = type;
- valid = 1;
+ validated = 1;
}
/* Handle putting a type attribute on pointer-to-function-type by putting
@@ -3389,11 +3412,11 @@ valid_machine_attribute (attr_name, attr_args, decl, type)
if (decl != 0)
TREE_TYPE (decl) = build_pointer_type (inner_type);
- valid = 1;
+ validated = 1;
}
#endif
- return valid;
+ return validated;
}
/* Return non-zero if IDENT is a valid name for attribute ATTR,
@@ -3406,7 +3429,7 @@ valid_machine_attribute (attr_name, attr_args, decl, type)
int
is_attribute_p (attr, ident)
- char *attr;
+ const char *attr;
tree ident;
{
int ident_len, attr_len;
@@ -3451,7 +3474,7 @@ is_attribute_p (attr, ident)
tree
lookup_attribute (attr_name, list)
- char *attr_name;
+ const char *attr_name;
tree list;
{
tree l;
@@ -3537,45 +3560,44 @@ merge_machine_decl_attributes (olddecl, newdecl)
#endif
}
-/* Return a type like TYPE except that its TYPE_READONLY is CONSTP
- and its TYPE_VOLATILE is VOLATILEP.
+/* Set the type qualifiers for TYPE to TYPE_QUALS, which is a bitmask
+ of the various TYPE_QUAL values. */
- Such variant types already made are recorded so that duplicates
- are not made.
+static void
+set_type_quals (type, type_quals)
+ tree type;
+ int type_quals;
+{
+ TYPE_READONLY (type) = (type_quals & TYPE_QUAL_CONST) != 0;
+ TYPE_VOLATILE (type) = (type_quals & TYPE_QUAL_VOLATILE) != 0;
+ TYPE_RESTRICT (type) = (type_quals & TYPE_QUAL_RESTRICT) != 0;
+}
- A variant types should never be used as the type of an expression.
- Always copy the variant information into the TREE_READONLY
- and TREE_THIS_VOLATILE of the expression, and then give the expression
- as its type the "main variant", the variant whose TYPE_READONLY
- and TYPE_VOLATILE are zero. Use TYPE_MAIN_VARIANT to find the
- main variant. */
+/* Given a type node TYPE and a TYPE_QUALIFIER_SET, return a type for
+ the same kind of data as TYPE describes. Variants point to the
+ "main variant" (which has no qualifiers set) via TYPE_MAIN_VARIANT,
+ and it points to a chain of other variants so that duplicate
+ variants are never made. Only main variants should ever appear as
+ types of expressions. */
tree
-build_type_variant (type, constp, volatilep)
+build_qualified_type (type, type_quals)
tree type;
- int constp, volatilep;
+ int type_quals;
{
register tree t;
-
- /* Treat any nonzero argument as 1. */
- constp = !!constp;
- volatilep = !!volatilep;
-
+
/* Search the chain of variants to see if there is already one there just
like the one we need to have. If so, use that existing one. We must
preserve the TYPE_NAME, since there is code that depends on this. */
for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
- if (constp == TYPE_READONLY (t) && volatilep == TYPE_VOLATILE (t)
- && TYPE_NAME (t) == TYPE_NAME (type))
+ if (TYPE_QUALS (t) == type_quals && TYPE_NAME (t) == TYPE_NAME (type))
return t;
/* We need a new one. */
-
t = build_type_copy (type);
- TYPE_READONLY (t) = constp;
- TYPE_VOLATILE (t) = volatilep;
-
+ set_type_quals (t, type_quals);
return t;
}
@@ -4387,8 +4409,7 @@ build_complex_type (component_type)
t = make_node (COMPLEX_TYPE);
TREE_TYPE (t) = TYPE_MAIN_VARIANT (component_type);
- TYPE_VOLATILE (t) = TYPE_VOLATILE (component_type);
- TYPE_READONLY (t) = TYPE_READONLY (component_type);
+ set_type_quals (t, TYPE_QUALS (component_type));
/* If we already have such a type, use the old one and free this one. */
hashcode = TYPE_HASH (component_type);
@@ -4710,7 +4731,7 @@ print_inline_obstack_statistics ()
void
print_obstack_statistics (str, o)
- char *str;
+ const char *str;
struct obstack *o;
{
struct _obstack_chunk *chunk = o->chunk;
@@ -4783,24 +4804,83 @@ dump_tree_statistics ()
extern char * first_global_object_name;
extern char * weak_global_object_name;
-/* TYPE is some string to identify this function to the linker or
- collect2. */
+/* Appends 6 random characters to TEMPLATE to (hopefully) avoid name
+ clashes in cases where we can't reliably choose a unique name.
+
+ Derived from mkstemp.c in libiberty. */
+
+static void
+append_random_chars (template)
+ char *template;
+{
+ static const char letters[]
+ = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
+ static unsigned HOST_WIDE_INT value;
+ unsigned HOST_WIDE_INT v;
+
+#ifdef HAVE_GETTIMEOFDAY
+ struct timeval tv;
+#endif
+
+ template += strlen (template);
+
+#ifdef HAVE_GETTIMEOFDAY
+ /* Get some more or less random data. */
+ gettimeofday (&tv, NULL);
+ value += ((unsigned HOST_WIDE_INT) tv.tv_usec << 16) ^ tv.tv_sec ^ getpid ();
+#else
+ value += getpid ();
+#endif
+
+ v = value;
+
+ /* Fill in the random bits. */
+ template[0] = letters[v % 62];
+ v /= 62;
+ template[1] = letters[v % 62];
+ v /= 62;
+ template[2] = letters[v % 62];
+ v /= 62;
+ template[3] = letters[v % 62];
+ v /= 62;
+ template[4] = letters[v % 62];
+ v /= 62;
+ template[5] = letters[v % 62];
+
+ template[6] = '\0';
+}
+
+/* Generate a name for a function unique to this translation unit.
+ TYPE is some string to identify the purpose of this function to the
+ linker or collect2. */
tree
get_file_function_name_long (type)
- char *type;
+ const char *type;
{
char *buf;
register char *p;
if (first_global_object_name)
p = first_global_object_name;
- else if (weak_global_object_name)
- p = weak_global_object_name;
- else if (main_input_filename)
- p = main_input_filename;
else
- p = input_filename;
+ {
+ /* We don't have anything that we know to be unique to this translation
+ unit, so use what we do have and throw in some randomness. */
+
+ const char *name = weak_global_object_name;
+ const char *file = main_input_filename;
+
+ if (! name)
+ name = "";
+ if (! file)
+ file = input_filename;
+
+ p = (char *) alloca (7 + strlen (name) + strlen (file));
+
+ sprintf (p, "%s%s", name, file);
+ append_random_chars (p);
+ }
buf = (char *) alloca (sizeof (FILE_FUNCTION_FORMAT) + strlen (p)
+ strlen (type));
@@ -5005,7 +5085,7 @@ tree
tree_check (node, code, file, line, nofatal)
tree node;
enum tree_code code;
- char *file;
+ const char *file;
int line;
int nofatal;
{
@@ -5025,7 +5105,7 @@ tree
tree_class_check (node, cl, file, line, nofatal)
tree node;
char cl;
- char *file;
+ const char *file;
int line;
int nofatal;
{
@@ -5044,7 +5124,7 @@ tree
expr_check (node, ignored, file, line, nofatal)
tree node;
int ignored;
- char *file;
+ const char *file;
int line;
int nofatal;
{
@@ -5091,5 +5171,8 @@ int
new_alias_set ()
{
static int last_alias_set;
- return ++last_alias_set;
+ if (flag_strict_aliasing)
+ return ++last_alias_set;
+ else
+ return 0;
}
diff --git a/gcc/tree.def b/gcc/tree.def
index 71d0687043c..02305e1ea66 100644
--- a/gcc/tree.def
+++ b/gcc/tree.def
@@ -1,6 +1,6 @@
/* This file contains the definitions and documentation for the
tree codes used in the GNU C compiler.
- Copyright (C) 1987, 1988, 1993, 1995, 1997 Free Software Foundation, Inc.
+ Copyright (C) 1987, 1988, 1993, 1995, 1997, 1998 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -702,6 +702,27 @@ DEFTREECODE (POSTINCREMENT_EXPR, "postincrement_expr", 'e', 2)
evaluated unless an exception is throw. */
DEFTREECODE (TRY_CATCH_EXPR, "try_catch_expr", 'e', 2)
+/* Evaluate the first operand.
+ The second operand is a a cleanup expression which is evaluated
+ before an exit (normal, exception, or jump out) from this expression.
+
+ Like a CLEANUP_POINT_EXPR/WITH_CLEANUP_EXPR combination, but those
+ always copy the cleanup expression where needed. In contrast,
+ TRY_FINALLY_EXPR generates a jump to a cleanup subroutine.
+ (At least conceptually; the optimizer could inline the cleanup
+ subroutine in the same way it could inline normal subroutines.)
+ TRY_FINALLY_EXPR should be used when the cleanup is actual statements
+ in the source of the current function (which people might want to
+ set breakpoints in). */
+DEFTREECODE (TRY_FINALLY_EXPR, "try_finally", 'e', 2)
+
+/* Used internally for cleanups in the implementation of TRY_FINALLY_EXPR.
+ (Specifically, it is created by expand_expr, not front-ends.)
+ Operand 0 is the rtx for the start of the subroutine we need to call.
+ Operand 1 is the rtx for a variable in which to store the address
+ of where the subroutine should return to. */
+DEFTREECODE (GOTO_SUBROUTINE_EXPR, "goto_subroutine", 'e', 2)
+
/* Pop the top element off the dynamic handler chain. Used in
conjunction with setjmp/longjmp based exception handling, see
except.c for more details. This is meant to be used only by the
diff --git a/gcc/tree.h b/gcc/tree.h
index 1cfaefaa927..f87905d0fca 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -1,5 +1,5 @@
/* Front-end tree definitions for GNU compiler.
- Copyright (C) 1989, 93, 94, 95, 96, 97, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1989, 93-98, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -330,8 +330,8 @@ struct tree_common
#include "tree-check.h"
-#define TYPE_CHECK(t) DO_CHECK (tree_class_check, t, 't')
-#define TYPE_CHECK1(t) DO_CHECK1 (tree_class_check, t, 't')
+#define TYPE_CHECK(tree) DO_CHECK (tree_class_check, tree, 't')
+#define TYPE_CHECK1(tree) DO_CHECK1 (tree_class_check, tree, 't')
#define DECL_CHECK(t) DO_CHECK (tree_class_check, t, 'd')
#define DECL_CHECK1(t) DO_CHECK1 (tree_class_check, t, 'd')
#define CST_CHECK(t) DO_CHECK (tree_class_check, t, 'c')
@@ -833,6 +833,25 @@ struct tree_block
/* Means this type is const-qualified. */
#define TYPE_READONLY(NODE) ((NODE)->common.readonly_flag)
+/* If nonzero, this type is `restrict'-qualified, in the C sense of
+ the term. */
+#define TYPE_RESTRICT(NODE) (TYPE_CHECK (NODE)->type.restrict_flag)
+
+/* There is a TYPE_QUAL value for each type qualifier. They can be
+ combined by bitwise-or to form the complete set of qualifiers for a
+ type. */
+
+#define TYPE_UNQUALIFIED 0x0
+#define TYPE_QUAL_CONST 0x1
+#define TYPE_QUAL_VOLATILE 0x2
+#define TYPE_QUAL_RESTRICT 0x4
+
+/* The set of type qualifiers for this type. */
+#define TYPE_QUALS(NODE) \
+ ((TYPE_READONLY(NODE) * TYPE_QUAL_CONST) | \
+ (TYPE_VOLATILE(NODE) * TYPE_QUAL_VOLATILE) | \
+ (TYPE_RESTRICT(NODE) * TYPE_QUAL_RESTRICT))
+
/* These flags are available for each language front end to use internally. */
#define TYPE_LANG_FLAG_0(NODE) (TYPE_CHECK (NODE)->type.lang_flag_0)
#define TYPE_LANG_FLAG_1(NODE) (TYPE_CHECK (NODE)->type.lang_flag_1)
@@ -884,6 +903,8 @@ struct tree_type
unsigned needs_constructing_flag : 1;
unsigned transparent_union_flag : 1;
unsigned packed_flag : 1;
+ unsigned restrict_flag : 1;
+
unsigned lang_flag_0 : 1;
unsigned lang_flag_1 : 1;
unsigned lang_flag_2 : 1;
@@ -891,7 +912,7 @@ struct tree_type
unsigned lang_flag_4 : 1;
unsigned lang_flag_5 : 1;
unsigned lang_flag_6 : 1;
- /* room for 4 more bits */
+ /* room for 3 more bits */
unsigned int align;
union tree_node *pointer_to;
@@ -994,6 +1015,8 @@ struct tree_type
/* Define fields and accessors for nodes representing declared names. */
+/* Nonzero if DECL represents a decl. */
+#define DECL_P(DECL) (TREE_CODE_CLASS (TREE_CODE (DECL)) == 'd')
/* This is the name of the object as written by the user.
It is an IDENTIFIER_NODE. */
#define DECL_NAME(NODE) (DECL_CHECK (NODE)->decl.name)
@@ -1144,6 +1167,7 @@ struct tree_type
initializatons. */
#define DEFAULT_INIT_PRIORITY 65535
#define MAX_INIT_PRIORITY 65535
+#define MAX_RESERVED_INIT_PRIORITY 100
/* In a TYPE_DECL
nonzero means the detail info about this type is not dumped into stabs.
@@ -1226,6 +1250,10 @@ struct tree_type
be instrumented with calls to support routines. */
#define DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT(NODE) ((NODE)->decl.no_instrument_function_entry_exit)
+/* Used in FUNCTION_DECLs to indicate that in this function,
+ check-memory-usage should be disabled. */
+#define DECL_NO_CHECK_MEMORY_USAGE(NODE) ((NODE)->decl.no_check_memory_usage)
+
/* Additional flags for language-specific uses. */
#define DECL_LANG_FLAG_0(NODE) (DECL_CHECK (NODE)->decl.lang_flag_0)
#define DECL_LANG_FLAG_1(NODE) (DECL_CHECK (NODE)->decl.lang_flag_1)
@@ -1240,6 +1268,16 @@ struct tree_type
an address constant. */
#define DECL_NON_ADDR_CONST_P(NODE) (DECL_CHECK (NODE)->decl.non_addr_const_p)
+/* Used to indicate an alias set for the memory pointed to by this
+ particular FIELD_DECL, PARM_DECL, or VAR_DECL, which must have
+ pointer (or reference) type. */
+#define DECL_POINTER_ALIAS_SET(NODE) \
+ (DECL_CHECK (NODE)->decl.pointer_alias_set)
+
+/* Nonzero if an alias set has been assigned to this declaration. */
+#define DECL_POINTER_ALIAS_SET_KNOWN_P(NODE) \
+ (DECL_POINTER_ALIAS_SET (NODE) != - 1)
+
struct tree_decl
{
char common[sizeof (struct tree_common)];
@@ -1282,6 +1320,7 @@ struct tree_decl
unsigned non_addr_const_p : 1;
unsigned no_instrument_function_entry_exit : 1;
+ unsigned no_check_memory_usage : 1;
/* For a FUNCTION_DECL, if inline, this is the size of frame needed.
If built-in, this is the code for which built-in function.
@@ -1312,6 +1351,7 @@ struct tree_decl
struct function *f;
} saved_insns;
union tree_node *vindex;
+ int pointer_alias_set;
/* Points to a structure whose details depend on the language in use. */
struct lang_decl *lang_specific;
};
@@ -1336,8 +1376,6 @@ union tree_node
struct tree_block block;
};
-#include "gansidecl.h"
-
#define NULL_TREE (tree) NULL
/* The following functions accept a wide integer argument. Rather than
@@ -1351,21 +1389,6 @@ union tree_node
extern int exact_log2_wide PROTO((unsigned HOST_WIDE_INT));
extern int floor_log2_wide PROTO((unsigned HOST_WIDE_INT));
-#if 0
-/* At present, don't prototype xrealloc, since all of the callers don't
- cast their pointers to char *, and all of the xrealloc's don't use
- void * yet. */
-extern char *xmalloc PROTO((size_t));
-extern char *xcalloc PROTO((size_t, size_t));
-extern char *xrealloc PROTO((void *, size_t));
-#else
-extern char *xmalloc ();
-extern char *xcalloc ();
-extern char *xrealloc ();
-#endif
-
-extern char *xstrdup PROTO((char *));
-
extern char *oballoc PROTO((int));
extern char *permalloc PROTO((int));
extern char *savealloc PROTO((int));
@@ -1394,13 +1417,13 @@ extern tree make_tree_vec PROTO((int));
/* Return the (unique) IDENTIFIER_NODE node for a given name.
The name is supplied as a char *. */
-extern tree get_identifier PROTO((char *));
+extern tree get_identifier PROTO((const char *));
/* If an identifier with the name TEXT (a null-terminated string) has
previously been referred to, return that node; otherwise return
NULL_TREE. */
-extern tree maybe_get_identifier PROTO((char *));
+extern tree maybe_get_identifier PROTO((const char *));
/* Construct various types of nodes. */
@@ -1415,14 +1438,14 @@ extern tree build_int_2_wide PROTO((HOST_WIDE_INT, HOST_WIDE_INT));
extern tree build_real PROTO((tree, REAL_VALUE_TYPE));
extern tree build_real_from_int_cst PROTO((tree, tree));
extern tree build_complex PROTO((tree, tree, tree));
-extern tree build_string PROTO((int, char *));
+extern tree build_string PROTO((int, const char *));
extern tree build1 PROTO((enum tree_code, tree, tree));
extern tree build_tree_list PROTO((tree, tree));
extern tree build_decl_list PROTO((tree, tree));
extern tree build_expr_list PROTO((tree, tree));
extern tree build_decl PROTO((enum tree_code, tree, tree));
extern tree build_block PROTO((tree, tree, tree, tree, tree));
-extern tree build_expr_wfl PROTO((tree, char *, int, int));
+extern tree build_expr_wfl PROTO((tree, const char *, int, int));
/* Construct various nodes representing data types. */
@@ -1487,25 +1510,35 @@ extern int valid_machine_attribute PROTO((tree, tree, tree, tree));
/* Given a tree node and a string, return non-zero if the tree node is
a valid attribute name for the string. */
-extern int is_attribute_p PROTO((char *, tree));
+extern int is_attribute_p PROTO((const char *, tree));
/* Given an attribute name and a list of attributes, return the list element
of the attribute or NULL_TREE if not found. */
-extern tree lookup_attribute PROTO((char *, tree));
+extern tree lookup_attribute PROTO((const char *, tree));
/* Given two attributes lists, return a list of their union. */
extern tree merge_attributes PROTO((tree, tree));
-/* Given a type node TYPE, and CONSTP and VOLATILEP, return a type
- for the same kind of data as TYPE describes.
- Variants point to the "main variant" (which has neither CONST nor VOLATILE)
- via TYPE_MAIN_VARIANT, and it points to a chain of other variants
- so that duplicate variants are never made.
- Only main variants should ever appear as types of expressions. */
+/* Given a type node TYPE and a TYPE_QUALIFIER_SET, return a type for
+ the same kind of data as TYPE describes. Variants point to the
+ "main variant" (which has no qualifiers set) via TYPE_MAIN_VARIANT,
+ and it points to a chain of other variants so that duplicate
+ variants are never made. Only main variants should ever appear as
+ types of expressions. */
+
+extern tree build_qualified_type PROTO((tree, int));
-extern tree build_type_variant PROTO((tree, int, int));
+/* Like build_qualified_type, but only deals with the `const' and
+ `volatile' qualifiers. This interface is retained for backwards
+ compatiblity with the various front-ends; new code should use
+ build_qualified_type instead. */
+
+#define build_type_variant(TYPE, CONST_P, VOLATILE_P) \
+ build_qualified_type (TYPE, \
+ ((CONST_P) ? TYPE_QUAL_CONST : 0) \
+ | ((VOLATILE_P) ? TYPE_QUAL_VOLATILE : 0))
/* Make a copy of a type node. */
@@ -1640,7 +1673,7 @@ extern int staticp PROTO((tree));
/* Gets an error if argument X is not an lvalue.
Also returns 1 if X is an lvalue, 0 if not. */
-extern int lvalue_or_else PROTO((tree, char *));
+extern int lvalue_or_else PROTO((tree, const char *));
/* save_expr (EXP) returns an expression equivalent to EXP
but it can be used multiple times within context CTX
@@ -1773,7 +1806,7 @@ extern tree decl_type_context PROTO((tree));
Otherwise return a warning message with a single %s
for the function's name. */
-extern char *function_cannot_inline_p PROTO((tree));
+extern const char *function_cannot_inline_p PROTO((tree));
/* Return 1 if EXPR is the real constant zero. */
extern int real_zerop PROTO((tree));
@@ -1857,7 +1890,7 @@ extern void (*incomplete_decl_finalize_hook) PROTO((tree));
/* In tree.c */
extern char *perm_calloc PROTO((int, long));
extern tree get_file_function_name PROTO((int));
-extern tree get_file_function_name_long PROTO((char *));
+extern tree get_file_function_name_long PROTO((const char *));
extern tree get_set_constructor_bits PROTO((tree, char *, int));
extern tree get_set_constructor_bytes PROTO((tree,
unsigned char *, int));
@@ -1894,6 +1927,7 @@ extern int expand_exit_something PROTO((void));
extern void expand_null_return PROTO((void));
extern void expand_return PROTO((tree));
+extern int optimize_tail_recursion PROTO((tree, struct rtx_def *));
extern void expand_start_bindings PROTO((int));
extern void expand_end_bindings PROTO((tree, int, int));
extern void start_cleanup_deferral PROTO((void));
@@ -1906,7 +1940,7 @@ extern tree last_cleanup_this_contour PROTO((void));
extern int expand_dhc_cleanup PROTO((tree));
extern int expand_dcc_cleanup PROTO((tree));
extern void expand_start_case PROTO((int, tree, tree,
- char *));
+ const char *));
extern void expand_end_case PROTO((tree));
extern int pushcase PROTO((tree,
tree (*) (tree, tree),
@@ -1915,6 +1949,7 @@ extern int pushcase_range PROTO((tree, tree,
tree (*) (tree, tree),
tree, tree *));
extern void using_eh_for_cleanups PROTO((void));
+extern int stmt_loop_nest_empty PROTO((void));
/* In fold-const.c */
@@ -2112,9 +2147,10 @@ extern void rtl_in_current_obstack PROTO ((void));
extern void rtl_in_saveable_obstack PROTO ((void));
extern void init_tree_codes PROTO ((void));
extern void dump_tree_statistics PROTO ((void));
-extern void print_obstack_statistics PROTO ((char *, struct obstack *));
+extern void print_obstack_statistics PROTO ((const char *,
+ struct obstack *));
#ifdef BUFSIZ
-extern void print_obstack_name PROTO ((char *, FILE *, char *));
+extern void print_obstack_name PROTO ((char *, FILE *, const char *));
#endif
extern void expand_function_end PROTO ((char *, int, int));
extern void expand_function_start PROTO ((tree, int));
@@ -2124,9 +2160,12 @@ extern void start_identifier_warnings PROTO ((void));
extern void gcc_obstack_init PROTO ((struct obstack *));
extern void init_obstacks PROTO ((void));
extern void obfree PROTO ((char *));
-extern tree tree_check PROTO ((tree, enum tree_code, char*, int, int));
-extern tree tree_class_check PROTO ((tree, char, char*, int, int));
-extern tree expr_check PROTO ((tree, int, char*, int, int));
+extern tree tree_check PROTO ((tree, enum tree_code,
+ const char *, int, int));
+extern tree tree_class_check PROTO ((tree, char, const char *,
+ int, int));
+extern tree expr_check PROTO ((tree, int, const char *,
+ int, int));
/* In function.c */
extern void setjmp_protect_args PROTO ((void));
@@ -2164,8 +2203,8 @@ extern void print_rtl PROTO ((FILE *, struct rtx_def *));
/* In print-tree.c */
extern void debug_tree PROTO ((tree));
#ifdef BUFSIZ
-extern void print_node PROTO ((FILE *, char *, tree, int));
-extern void print_node_brief PROTO ((FILE *, char *, tree, int));
+extern void print_node PROTO ((FILE *, const char *, tree, int));
+extern void print_node_brief PROTO ((FILE *, const char *, tree, int));
extern void indent_to PROTO ((FILE *, int));
#endif
@@ -2221,7 +2260,7 @@ extern void set_yydebug PROTO ((int));
extern void fixup_signed_type PROTO ((tree));
/* varasm.c */
-extern void make_decl_rtl PROTO ((tree, char *, int));
+extern void make_decl_rtl PROTO ((tree, const char *, int));
extern void make_decl_one_only PROTO ((tree));
extern int supports_one_only PROTO ((void));
extern void variable_section PROTO ((tree, int));
diff --git a/gcc/unroll.c b/gcc/unroll.c
index f6ebc37bd2c..fb55d0cad45 100644
--- a/gcc/unroll.c
+++ b/gcc/unroll.c
@@ -1,5 +1,5 @@
/* Try to unroll loops, and split induction variables.
- Copyright (C) 1992, 93, 94, 95, 97, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1992, 93, 94, 95, 97, 98, 1999 Free Software Foundation, Inc.
Contributed by James E. Wilson, Cygnus Support/UC Berkeley.
This file is part of GNU CC.
@@ -99,11 +99,11 @@ Boston, MA 02111-1307, USA. */
int iterations = (len + 1) >> 1;
int i;
for (p; p < q; p++, q--;)
- {
- tmp = *q;
- *q = *p;
- *p = tmp;
- }
+ {
+ tmp = *q;
+ *q = *p;
+ *p = tmp;
+ }
}
Note that:
start value = p = &buffer + current_iteration
@@ -141,7 +141,7 @@ Boston, MA 02111-1307, USA. */
struct _factor { int factor, count; } factors[NUM_FACTORS]
= { {2, 0}, {3, 0}, {5, 0}, {7, 0}};
-
+
/* Describes the different types of loop unrolling performed. */
enum unroll_types { UNROLL_COMPLETELY, UNROLL_MODULO, UNROLL_NAIVE };
@@ -181,34 +181,28 @@ static struct induction **addr_combined_regs;
static rtx *splittable_regs;
/* Indexed by register number, if this is a splittable induction variable,
+ this indicates if it was made from a derived giv. */
+static char *derived_regs;
+
+/* Indexed by register number, if this is a splittable induction variable,
then this will hold the number of instructions in the loop that modify
the induction variable. Used to ensure that only the last insn modifying
a split iv will update the original iv of the dest. */
static int *splittable_regs_updates;
-/* Values describing the current loop's iteration variable. These are set up
- by loop_iterations, and used by precondition_loop_p. */
-
-rtx loop_iteration_var;
-rtx loop_initial_value;
-rtx loop_increment;
-rtx loop_final_value;
-enum rtx_code loop_comparison_code;
-
/* Forward declarations. */
static void init_reg_map PROTO((struct inline_remap *, int));
-static int precondition_loop_p PROTO((rtx *, rtx *, rtx *, rtx, rtx));
static rtx calculate_giv_inc PROTO((rtx, rtx, int));
static rtx initial_reg_note_copy PROTO((rtx, struct inline_remap *));
static void final_reg_note_copy PROTO((rtx, struct inline_remap *));
static void copy_loop_body PROTO((rtx, rtx, struct inline_remap *, rtx, int,
enum unroll_types, rtx, rtx, rtx, rtx));
-void iteration_info PROTO((rtx, rtx *, rtx *, rtx, rtx));
-static rtx approx_final_value PROTO((enum rtx_code, rtx, int *, int *));
-static int find_splittable_regs PROTO((enum unroll_types, rtx, rtx, rtx, int));
-static int find_splittable_givs PROTO((struct iv_class *,enum unroll_types,
+static void iteration_info PROTO((rtx, rtx *, rtx *, rtx, rtx));
+static int find_splittable_regs PROTO((enum unroll_types, rtx, rtx, rtx, int,
+ unsigned HOST_WIDE_INT));
+static int find_splittable_givs PROTO((struct iv_class *, enum unroll_types,
rtx, rtx, rtx, int));
static int reg_dead_after_loop PROTO((rtx, rtx, rtx));
static rtx fold_rtx_mult_add PROTO((rtx, rtx, rtx, enum machine_mode));
@@ -228,11 +222,12 @@ static rtx remap_split_bivs PROTO((rtx));
void
unroll_loop (loop_end, insn_count, loop_start, end_insert_before,
- strength_reduce_p)
+ loop_info, strength_reduce_p)
rtx loop_end;
int insn_count;
rtx loop_start;
rtx end_insert_before;
+ struct loop_info *loop_info;
int strength_reduce_p;
{
int i, j, temp;
@@ -244,8 +239,8 @@ unroll_loop (loop_end, insn_count, loop_start, end_insert_before,
struct inline_remap *map;
char *local_label;
char *local_regno;
+ int max_local_regnum;
int maxregnum;
- int new_maxregnum;
rtx exit_label = 0;
rtx start_label;
struct iv_class *bl;
@@ -305,18 +300,19 @@ unroll_loop (loop_end, insn_count, loop_start, end_insert_before,
/* Determine type of unroll to perform. Depends on the number of iterations
and the size of the loop. */
- /* If there is no strength reduce info, then set loop_n_iterations to zero.
- This can happen if strength_reduce can't find any bivs in the loop.
- A value of zero indicates that the number of iterations could not be
- calculated. */
+ /* If there is no strength reduce info, then set
+ loop_info->n_iterations to zero. This can happen if
+ strength_reduce can't find any bivs in the loop. A value of zero
+ indicates that the number of iterations could not be calculated. */
if (! strength_reduce_p)
- loop_n_iterations = 0;
+ loop_info->n_iterations = 0;
- if (loop_dump_stream && loop_n_iterations > 0)
+ if (loop_dump_stream && loop_info->n_iterations > 0)
{
fputs ("Loop unrolling: ", loop_dump_stream);
- fprintf (loop_dump_stream, HOST_WIDE_INT_PRINT_DEC, loop_n_iterations);
+ fprintf (loop_dump_stream, HOST_WIDE_INT_PRINT_DEC,
+ loop_info->n_iterations);
fputs (" iterations.\n", loop_dump_stream);
}
@@ -327,7 +323,7 @@ unroll_loop (loop_end, insn_count, loop_start, end_insert_before,
/* Calculate how many times to unroll the loop. Indicate whether or
not the loop is being completely unrolled. */
- if (loop_n_iterations == 1)
+ if (loop_info->n_iterations == 1)
{
/* If number of iterations is exactly 1, then eliminate the compare and
branch at the end of the loop since they will never be taken.
@@ -356,13 +352,13 @@ unroll_loop (loop_end, insn_count, loop_start, end_insert_before,
}
return;
}
- else if (loop_n_iterations > 0
- && loop_n_iterations * insn_count < MAX_UNROLLED_INSNS)
+ else if (loop_info->n_iterations > 0
+ && loop_info->n_iterations * insn_count < MAX_UNROLLED_INSNS)
{
- unroll_number = loop_n_iterations;
+ unroll_number = loop_info->n_iterations;
unroll_type = UNROLL_COMPLETELY;
}
- else if (loop_n_iterations > 0)
+ else if (loop_info->n_iterations > 0)
{
/* Try to factor the number of iterations. Don't bother with the
general case, only using 2, 3, 5, and 7 will get 75% of all
@@ -371,7 +367,7 @@ unroll_loop (loop_end, insn_count, loop_start, end_insert_before,
for (i = 0; i < NUM_FACTORS; i++)
factors[i].count = 0;
- temp = loop_n_iterations;
+ temp = loop_info->n_iterations;
for (i = NUM_FACTORS - 1; i >= 0; i--)
while (temp % factors[i].factor == 0)
{
@@ -689,6 +685,7 @@ unroll_loop (loop_end, insn_count, loop_start, end_insert_before,
map = (struct inline_remap *) alloca (sizeof (struct inline_remap));
map->integrating = 0;
+ map->const_equiv_varray = 0;
/* Allocate the label map. */
@@ -760,6 +757,9 @@ unroll_loop (loop_end, insn_count, loop_start, end_insert_before,
/* The preconditioning code may allocate two new pseudo registers. */
maxregnum = max_reg_num ();
+ /* local_regno is only valid for regnos < max_local_regnum. */
+ max_local_regnum = maxregnum;
+
/* Allocate and zero out the splittable_regs and addr_combined_regs
arrays. These must be zeroed here because they will be used if
loop preconditioning is performed, and must be zero for that case.
@@ -770,16 +770,15 @@ unroll_loop (loop_end, insn_count, loop_start, end_insert_before,
splittable_regs = (rtx *) alloca (maxregnum * sizeof (rtx));
bzero ((char *) splittable_regs, maxregnum * sizeof (rtx));
+ derived_regs = alloca (maxregnum);
+ bzero (derived_regs, maxregnum);
splittable_regs_updates = (int *) alloca (maxregnum * sizeof (int));
bzero ((char *) splittable_regs_updates, maxregnum * sizeof (int));
addr_combined_regs
= (struct induction **) alloca (maxregnum * sizeof (struct induction *));
bzero ((char *) addr_combined_regs, maxregnum * sizeof (struct induction *));
- /* We must limit it to max_reg_before_loop, because only these pseudo
- registers have valid regno_first_uid info. Any register created after
- that is unlikely to be local to the loop anyways. */
- local_regno = (char *) alloca (max_reg_before_loop);
- bzero (local_regno, max_reg_before_loop);
+ local_regno = (char *) alloca (maxregnum);
+ bzero (local_regno, maxregnum);
/* Mark all local registers, i.e. the ones which are referenced only
inside the loop. */
@@ -802,6 +801,8 @@ unroll_loop (loop_end, insn_count, loop_start, end_insert_before,
/* If a pseudo's lifetime is entirely contained within this loop, then we
can use a different pseudo in each unrolled copy of the loop. This
results in better code. */
+ /* We must limit the generic test to max_reg_before_loop, because only
+ these pseudo registers have valid regno_first_uid info. */
for (j = FIRST_PSEUDO_REGISTER; j < max_reg_before_loop; ++j)
if (REGNO_FIRST_UID (j) > 0 && REGNO_FIRST_UID (j) <= max_uid_for_loop
&& uid_luid[REGNO_FIRST_UID (j)] >= copy_start_luid
@@ -830,6 +831,14 @@ unroll_loop (loop_end, insn_count, loop_start, end_insert_before,
j);
}
}
+ /* Givs that have been created from multiple biv increments always have
+ local registers. */
+ for (j = first_increment_giv; j <= last_increment_giv; j++)
+ {
+ local_regno[j] = 1;
+ if (loop_dump_stream)
+ fprintf (loop_dump_stream, "Marked reg %d as local\n", j);
+ }
}
/* If this loop requires exit tests when unrolled, check to see if we
@@ -857,23 +866,21 @@ unroll_loop (loop_end, insn_count, loop_start, end_insert_before,
if (unroll_type == UNROLL_NAIVE && ! splitting_not_safe && strength_reduce_p)
{
rtx initial_value, final_value, increment;
+ enum machine_mode mode;
- if (precondition_loop_p (&initial_value, &final_value, &increment,
- loop_start, loop_end))
+ if (precondition_loop_p (loop_start, loop_info,
+ &initial_value, &final_value, &increment,
+ &mode))
{
register rtx diff ;
- enum machine_mode mode;
rtx *labels;
int abs_inc, neg_inc;
map->reg_map = (rtx *) alloca (maxregnum * sizeof (rtx));
- map->const_equiv_map = (rtx *) alloca (maxregnum * sizeof (rtx));
- map->const_age_map = (unsigned *) alloca (maxregnum
- * sizeof (unsigned));
- map->const_equiv_map_size = maxregnum;
- global_const_equiv_map = map->const_equiv_map;
- global_const_equiv_map_size = maxregnum;
+ VARRAY_CONST_EQUIV_INIT (map->const_equiv_varray, maxregnum,
+ "unroll_loop");
+ global_const_equiv_varray = map->const_equiv_varray;
init_reg_map (map, maxregnum);
@@ -894,25 +901,10 @@ unroll_loop (loop_end, insn_count, loop_start, end_insert_before,
start_sequence ();
- /* Decide what mode to do these calculations in. Choose the larger
- of final_value's mode and initial_value's mode, or a full-word if
- both are constants. */
- mode = GET_MODE (final_value);
- if (mode == VOIDmode)
- {
- mode = GET_MODE (initial_value);
- if (mode == VOIDmode)
- mode = word_mode;
- }
- else if (mode != GET_MODE (initial_value)
- && (GET_MODE_SIZE (mode)
- < GET_MODE_SIZE (GET_MODE (initial_value))))
- mode = GET_MODE (initial_value);
-
/* Calculate the difference between the final and initial values.
Final value may be a (plus (reg x) (const_int 1)) rtx.
Let the following cse pass simplify this if initial value is
- a constant.
+ a constant.
We must copy the final and initial values here to avoid
improperly shared rtl. */
@@ -940,14 +932,11 @@ unroll_loop (loop_end, insn_count, loop_start, end_insert_before,
case. This check does not apply if the loop has a NE
comparison at the end. */
- if (loop_comparison_code != NE)
+ if (loop_info->comparison_code != NE)
{
- emit_cmp_insn (initial_value, final_value, neg_inc ? LE : GE,
- NULL_RTX, mode, 0, 0);
- if (neg_inc)
- emit_jump_insn (gen_ble (labels[1]));
- else
- emit_jump_insn (gen_bge (labels[1]));
+ emit_cmp_and_jump_insns (initial_value, final_value,
+ neg_inc ? LE : GE,
+ NULL_RTX, mode, 0, 0, labels[1]);
JUMP_LABEL (get_last_insn ()) = labels[1];
LABEL_NUSES (labels[1])++;
}
@@ -988,15 +977,9 @@ unroll_loop (loop_end, insn_count, loop_start, end_insert_before,
cmp_code = LE;
}
- emit_cmp_insn (diff, GEN_INT (abs_inc * cmp_const),
- cmp_code, NULL_RTX, mode, 0, 0);
-
- if (i == 0)
- emit_jump_insn (gen_beq (labels[i]));
- else if (neg_inc)
- emit_jump_insn (gen_bge (labels[i]));
- else
- emit_jump_insn (gen_ble (labels[i]));
+ emit_cmp_and_jump_insns (diff, GEN_INT (abs_inc * cmp_const),
+ cmp_code, NULL_RTX, mode, 0, 0,
+ labels[i]);
JUMP_LABEL (get_last_insn ()) = labels[i];
LABEL_NUSES (labels[i])++;
}
@@ -1009,7 +992,7 @@ unroll_loop (loop_end, insn_count, loop_start, end_insert_before,
For the negative increment case, the branch here could easily
be merged with the `0' case branch above. For the positive
increment case, it is not clear how this can be simplified. */
-
+
if (abs_inc != 1)
{
int cmp_const;
@@ -1026,13 +1009,8 @@ unroll_loop (loop_end, insn_count, loop_start, end_insert_before,
cmp_code = GE;
}
- emit_cmp_insn (diff, GEN_INT (cmp_const), cmp_code, NULL_RTX,
- mode, 0, 0);
-
- if (neg_inc)
- emit_jump_insn (gen_ble (labels[0]));
- else
- emit_jump_insn (gen_bge (labels[0]));
+ emit_cmp_and_jump_insns (diff, GEN_INT (cmp_const), cmp_code,
+ NULL_RTX, mode, 0, 0, labels[0]);
JUMP_LABEL (get_last_insn ()) = labels[0];
LABEL_NUSES (labels[0])++;
}
@@ -1040,7 +1018,7 @@ unroll_loop (loop_end, insn_count, loop_start, end_insert_before,
sequence = gen_sequence ();
end_sequence ();
emit_insn_before (sequence, loop_start);
-
+
/* Only the last copy of the loop body here needs the exit
test, so set copy_end to exclude the compare/branch here,
and then reset it inside the loop when get to the last
@@ -1069,16 +1047,16 @@ unroll_loop (loop_end, insn_count, loop_start, end_insert_before,
PREV_INSN (loop_start));
bzero ((char *) map->insn_map, max_insnno * sizeof (rtx));
- bzero ((char *) map->const_equiv_map, maxregnum * sizeof (rtx));
- bzero ((char *) map->const_age_map,
- maxregnum * sizeof (unsigned));
+ bzero ((char *) &VARRAY_CONST_EQUIV (map->const_equiv_varray, 0),
+ (VARRAY_SIZE (map->const_equiv_varray)
+ * sizeof (struct const_equiv_data)));
map->const_age = 0;
for (j = 0; j < max_labelno; j++)
if (local_label[j])
set_label_in_map (map, j, gen_label_rtx ());
- for (j = FIRST_PSEUDO_REGISTER; j < max_reg_before_loop; j++)
+ for (j = FIRST_PSEUDO_REGISTER; j < max_local_regnum; j++)
if (local_regno[j])
{
map->reg_map[j] = gen_reg_rtx (GET_MODE (regno_reg_rtx[j]));
@@ -1137,16 +1115,16 @@ unroll_loop (loop_end, insn_count, loop_start, end_insert_before,
{
if (loop_dump_stream)
fprintf (loop_dump_stream, "Unrolling failure: Naive unrolling not being done.\n");
- return;
+ goto egress;
}
/* At this point, we are guaranteed to unroll the loop. */
- /* Keep track of the unroll factor for each loop. */
+ /* Keep track of the unroll factor for the loop. */
if (unroll_type == UNROLL_COMPLETELY)
- loop_unroll_factor [uid_loop_num [INSN_UID (loop_start)]] = -1;
+ loop_info->unroll_number = -1;
else
- loop_unroll_factor [uid_loop_num [INSN_UID (loop_start)]] = unroll_number;
+ loop_info->unroll_number = unroll_number;
/* For each biv and giv, determine whether it can be safely split into
@@ -1161,7 +1139,8 @@ unroll_loop (loop_end, insn_count, loop_start, end_insert_before,
temp = 0;
else
temp = find_splittable_regs (unroll_type, loop_start, loop_end,
- end_insert_before, unroll_number);
+ end_insert_before, unroll_number,
+ loop_info->n_iterations);
/* find_splittable_regs may have created some new registers, so must
reallocate the reg_map with the new larger size, and must realloc
@@ -1172,19 +1151,11 @@ unroll_loop (loop_end, insn_count, loop_start, end_insert_before,
init_reg_map (map, maxregnum);
- /* Space is needed in some of the map for new registers, so new_maxregnum
- is an (over)estimate of how many registers will exist at the end. */
- new_maxregnum = maxregnum + (temp * unroll_number * 2);
-
- /* Must realloc space for the constant maps, because the number of registers
- may have changed. */
-
- map->const_equiv_map = (rtx *) alloca (new_maxregnum * sizeof (rtx));
- map->const_age_map = (unsigned *) alloca (new_maxregnum * sizeof (unsigned));
-
- map->const_equiv_map_size = new_maxregnum;
- global_const_equiv_map = map->const_equiv_map;
- global_const_equiv_map_size = new_maxregnum;
+ if (map->const_equiv_varray == 0)
+ VARRAY_CONST_EQUIV_INIT (map->const_equiv_varray,
+ maxregnum + temp * unroll_number * 2,
+ "unroll_loop");
+ global_const_equiv_varray = map->const_equiv_varray;
/* Search the list of bivs and givs to find ones which need to be remapped
when split, and set their reg_map entry appropriately. */
@@ -1218,22 +1189,22 @@ unroll_loop (loop_end, insn_count, loop_start, end_insert_before,
PATTERN (insn) = remap_split_bivs (PATTERN (insn));
}
- /* For unroll_number - 1 times, make a copy of each instruction
+ /* For unroll_number times, make a copy of each instruction
between copy_start and copy_end, and insert these new instructions
before the end of the loop. */
for (i = 0; i < unroll_number; i++)
{
bzero ((char *) map->insn_map, max_insnno * sizeof (rtx));
- bzero ((char *) map->const_equiv_map, new_maxregnum * sizeof (rtx));
- bzero ((char *) map->const_age_map, new_maxregnum * sizeof (unsigned));
+ bzero ((char *) &VARRAY_CONST_EQUIV (map->const_equiv_varray, 0),
+ VARRAY_SIZE (map->const_equiv_varray) * sizeof (struct const_equiv_data));
map->const_age = 0;
for (j = 0; j < max_labelno; j++)
if (local_label[j])
set_label_in_map (map, j, gen_label_rtx ());
- for (j = FIRST_PSEUDO_REGISTER; j < max_reg_before_loop; j++)
+ for (j = FIRST_PSEUDO_REGISTER; j < max_local_regnum; j++)
if (local_regno[j])
{
map->reg_map[j] = gen_reg_rtx (GET_MODE (regno_reg_rtx[j]));
@@ -1247,7 +1218,7 @@ unroll_loop (loop_end, insn_count, loop_start, end_insert_before,
{
insn = PREV_INSN (copy_start);
pattern = PATTERN (insn);
-
+
tem = get_label_from_map (map,
CODE_LABEL_NUMBER
(XEXP (SET_SRC (pattern), 0)));
@@ -1278,7 +1249,7 @@ unroll_loop (loop_end, insn_count, loop_start, end_insert_before,
else
safety_label = emit_label_after (gen_label_rtx (), copy_end);
- /* Delete all of the original loop instructions. Don't delete the
+ /* Delete all of the original loop instructions. Don't delete the
LOOP_BEG note, or the first code label in the loop. */
insn = NEXT_INSN (copy_start);
@@ -1303,6 +1274,10 @@ unroll_loop (loop_end, insn_count, loop_start, end_insert_before,
not taken. */
if (exit_label)
emit_label_after (exit_label, loop_end);
+
+ egress:
+ if (map && map->const_equiv_varray)
+ VARRAY_FREE (map->const_equiv_varray);
}
/* Return true if the loop can be safely, and profitably, preconditioned
@@ -1317,55 +1292,61 @@ unroll_loop (loop_end, insn_count, loop_start, end_insert_before,
/* ??? If the loop is known to be executed very many times, or the machine
has a very cheap divide instruction, then preconditioning is a win even
when the increment is not a power of 2. Use RTX_COST to compute
- whether divide is cheap. */
+ whether divide is cheap.
+ ??? A divide by constant doesn't actually need a divide, look at
+ expand_divmod. The reduced cost of this optimized modulo is not
+ reflected in RTX_COST. */
-static int
-precondition_loop_p (initial_value, final_value, increment, loop_start,
- loop_end)
+int
+precondition_loop_p (loop_start, loop_info,
+ initial_value, final_value, increment, mode)
+ rtx loop_start;
+ struct loop_info *loop_info;
rtx *initial_value, *final_value, *increment;
- rtx loop_start, loop_end;
+ enum machine_mode *mode;
{
- if (loop_n_iterations > 0)
+ if (loop_info->n_iterations > 0)
{
*initial_value = const0_rtx;
*increment = const1_rtx;
- *final_value = GEN_INT (loop_n_iterations);
+ *final_value = GEN_INT (loop_info->n_iterations);
+ *mode = word_mode;
if (loop_dump_stream)
{
fputs ("Preconditioning: Success, number of iterations known, ",
loop_dump_stream);
fprintf (loop_dump_stream, HOST_WIDE_INT_PRINT_DEC,
- loop_n_iterations);
+ loop_info->n_iterations);
fputs (".\n", loop_dump_stream);
}
return 1;
}
- if (loop_initial_value == 0)
+ if (loop_info->initial_value == 0)
{
if (loop_dump_stream)
fprintf (loop_dump_stream,
"Preconditioning: Could not find initial value.\n");
return 0;
}
- else if (loop_increment == 0)
+ else if (loop_info->increment == 0)
{
if (loop_dump_stream)
fprintf (loop_dump_stream,
"Preconditioning: Could not find increment value.\n");
return 0;
}
- else if (GET_CODE (loop_increment) != CONST_INT)
+ else if (GET_CODE (loop_info->increment) != CONST_INT)
{
if (loop_dump_stream)
fprintf (loop_dump_stream,
"Preconditioning: Increment not a constant.\n");
return 0;
}
- else if ((exact_log2 (INTVAL (loop_increment)) < 0)
- && (exact_log2 (- INTVAL (loop_increment)) < 0))
+ else if ((exact_log2 (INTVAL (loop_info->increment)) < 0)
+ && (exact_log2 (- INTVAL (loop_info->increment)) < 0))
{
if (loop_dump_stream)
fprintf (loop_dump_stream,
@@ -1376,7 +1357,7 @@ precondition_loop_p (initial_value, final_value, increment, loop_start,
/* Unsigned_compare and compare_dir can be ignored here, since they do
not matter for preconditioning. */
- if (loop_final_value == 0)
+ if (loop_info->final_value == 0)
{
if (loop_dump_stream)
fprintf (loop_dump_stream,
@@ -1389,11 +1370,11 @@ precondition_loop_p (initial_value, final_value, increment, loop_start,
to make sure that the register is in the range covered by invariant_p.
If it isn't, then it is most likely a biv/giv which by definition are
not invariant. */
- if ((GET_CODE (loop_final_value) == REG
- && REGNO (loop_final_value) >= max_reg_before_loop)
- || (GET_CODE (loop_final_value) == PLUS
- && REGNO (XEXP (loop_final_value, 0)) >= max_reg_before_loop)
- || ! invariant_p (loop_final_value))
+ if ((GET_CODE (loop_info->final_value) == REG
+ && REGNO (loop_info->final_value) >= max_reg_before_loop)
+ || (GET_CODE (loop_info->final_value) == PLUS
+ && REGNO (XEXP (loop_info->final_value, 0)) >= max_reg_before_loop)
+ || ! invariant_p (loop_info->final_value))
{
if (loop_dump_stream)
fprintf (loop_dump_stream,
@@ -1403,8 +1384,8 @@ precondition_loop_p (initial_value, final_value, increment, loop_start,
/* Fail for floating point values, since the caller of this function
does not have code to deal with them. */
- if (GET_MODE_CLASS (GET_MODE (loop_final_value)) == MODE_FLOAT
- || GET_MODE_CLASS (GET_MODE (loop_initial_value)) == MODE_FLOAT)
+ if (GET_MODE_CLASS (GET_MODE (loop_info->final_value)) == MODE_FLOAT
+ || GET_MODE_CLASS (GET_MODE (loop_info->initial_value)) == MODE_FLOAT)
{
if (loop_dump_stream)
fprintf (loop_dump_stream,
@@ -1412,23 +1393,10 @@ precondition_loop_p (initial_value, final_value, increment, loop_start,
return 0;
}
- /* Now set initial_value to be the iteration_var, since that may be a
- simpler expression, and is guaranteed to be correct if all of the
- above tests succeed.
-
- We can not use the initial_value as calculated, because it will be
- one too small for loops of the form "while (i-- > 0)". We can not
- emit code before the loop_skip_over insns to fix this problem as this
- will then give a number one too large for loops of the form
- "while (--i > 0)".
-
- Note that all loops that reach here are entered at the top, because
- this function is not called if the loop starts with a jump. */
+ /* Fail if loop_info->iteration_var is not live before loop_start,
+ since we need to test its value in the preconditioning code. */
- /* Fail if loop_iteration_var is not live before loop_start, since we need
- to test its value in the preconditioning code. */
-
- if (uid_luid[REGNO_FIRST_UID (REGNO (loop_iteration_var))]
+ if (uid_luid[REGNO_FIRST_UID (REGNO (loop_info->iteration_var))]
> INSN_LUID (loop_start))
{
if (loop_dump_stream)
@@ -1437,9 +1405,31 @@ precondition_loop_p (initial_value, final_value, increment, loop_start,
return 0;
}
- *initial_value = loop_iteration_var;
- *increment = loop_increment;
- *final_value = loop_final_value;
+ /* Note that iteration_info biases the initial value for GIV iterators
+ such as "while (i-- > 0)" so that we can calculate the number of
+ iterations just like for BIV iterators.
+
+ Also note that the absolute values of initial_value and
+ final_value are unimportant as only their difference is used for
+ calculating the number of loop iterations. */
+ *initial_value = loop_info->initial_value;
+ *increment = loop_info->increment;
+ *final_value = loop_info->final_value;
+
+ /* Decide what mode to do these calculations in. Choose the larger
+ of final_value's mode and initial_value's mode, or a full-word if
+ both are constants. */
+ *mode = GET_MODE (*final_value);
+ if (*mode == VOIDmode)
+ {
+ *mode = GET_MODE (*initial_value);
+ if (*mode == VOIDmode)
+ *mode = word_mode;
+ }
+ else if (*mode != GET_MODE (*initial_value)
+ && (GET_MODE_SIZE (*mode)
+ < GET_MODE_SIZE (GET_MODE (*initial_value))))
+ *mode = GET_MODE (*initial_value);
/* Success! */
if (loop_dump_stream)
@@ -1502,7 +1492,7 @@ calculate_giv_inc (pattern, src_insn, regno)
pattern = PATTERN (src_insn);
if (GET_CODE (SET_SRC (pattern)) != PLUS)
abort ();
-
+
/* The last insn emitted is not needed, so delete it to avoid confusing
the second cse pass. This insn sets the giv unnecessarily. */
delete_insn (get_last_insn ());
@@ -1526,11 +1516,11 @@ calculate_giv_inc (pattern, src_insn, regno)
/* Some ports store large constants in memory and add a REG_EQUAL
note to the store insn. */
else if (GET_CODE (increment) == MEM)
- {
- rtx note = find_reg_note (src_insn, REG_EQUAL, 0);
- if (note)
- increment = XEXP (note, 0);
- }
+ {
+ rtx note = find_reg_note (src_insn, REG_EQUAL, 0);
+ if (note)
+ increment = XEXP (note, 0);
+ }
else if (GET_CODE (increment) == IOR
|| GET_CODE (increment) == ASHIFT
@@ -1560,7 +1550,7 @@ calculate_giv_inc (pattern, src_insn, regno)
if (GET_CODE (increment) != CONST_INT)
abort ();
-
+
/* The insn loading the constant into a register is no longer needed,
so delete it. */
delete_insn (get_last_insn ());
@@ -1644,7 +1634,7 @@ final_reg_note_copy (notes, map)
/* Copy each instruction in the loop, substituting from map as appropriate.
This is very similar to a loop in expand_inline_function. */
-
+
static void
copy_loop_body (copy_start, copy_end, map, exit_label, last_iteration,
unroll_type, start_label, loop_end, insert_before,
@@ -1675,35 +1665,35 @@ copy_loop_body (copy_start, copy_end, map, exit_label, last_iteration,
{
final_label = gen_label_rtx ();
set_label_in_map (map, CODE_LABEL_NUMBER (start_label),
- final_label);
+ final_label);
}
else
set_label_in_map (map, CODE_LABEL_NUMBER (start_label), start_label);
start_sequence ();
-
+
insn = copy_start;
do
{
insn = NEXT_INSN (insn);
-
+
map->orig_asm_operands_vector = 0;
-
+
switch (GET_CODE (insn))
{
case INSN:
pattern = PATTERN (insn);
copy = 0;
giv_inc = 0;
-
+
/* Check to see if this is a giv that has been combined with
- some split address givs. (Combined in the sense that
+ some split address givs. (Combined in the sense that
`combine_givs' in loop.c has put two givs in the same register.)
In this case, we must search all givs based on the same biv to
find the address givs. Then split the address givs.
Do this before splitting the giv, since that may map the
SET_DEST to a new register. */
-
+
if ((set = single_set (insn))
&& GET_CODE (SET_DEST (set)) == REG
&& addr_combined_regs[REGNO (SET_DEST (set))])
@@ -1711,17 +1701,18 @@ copy_loop_body (copy_start, copy_end, map, exit_label, last_iteration,
struct iv_class *bl;
struct induction *v, *tv;
int regno = REGNO (SET_DEST (set));
-
+
v = addr_combined_regs[REGNO (SET_DEST (set))];
bl = reg_biv_class[REGNO (v->src_reg)];
-
+
/* Although the giv_inc amount is not needed here, we must call
calculate_giv_inc here since it might try to delete the
last insn emitted. If we wait until later to call it,
we might accidentally delete insns generated immediately
below by emit_unrolled_add. */
- giv_inc = calculate_giv_inc (set, insn, regno);
+ if (! derived_regs[regno])
+ giv_inc = calculate_giv_inc (set, insn, regno);
/* Now find all address giv's that were combined with this
giv 'v'. */
@@ -1740,24 +1731,24 @@ copy_loop_body (copy_start, copy_end, map, exit_label, last_iteration,
if (tv->mult_val != v->mult_val)
this_giv_inc = (this_giv_inc / INTVAL (v->mult_val)
* INTVAL (tv->mult_val));
-
+
tv->dest_reg = plus_constant (tv->dest_reg, this_giv_inc);
*tv->location = tv->dest_reg;
-
+
if (last_iteration && unroll_type != UNROLL_COMPLETELY)
{
/* Must emit an insn to increment the split address
giv. Add in the const_adjust field in case there
was a constant eliminated from the address. */
rtx value, dest_reg;
-
+
/* tv->dest_reg will be either a bare register,
or else a register plus a constant. */
if (GET_CODE (tv->dest_reg) == REG)
dest_reg = tv->dest_reg;
else
dest_reg = XEXP (tv->dest_reg, 0);
-
+
/* Check for shared address givs, and avoid
incrementing the shared pseudo reg more than
once. */
@@ -1776,7 +1767,7 @@ copy_loop_body (copy_start, copy_end, map, exit_label, last_iteration,
emit_unrolled_add (dest_reg, XEXP (value, 0),
XEXP (value, 1));
}
-
+
/* Reset the giv to be just the register again, in case
it is used after the set we have just emitted.
We must subtract the const_adjust factor added in
@@ -1787,39 +1778,53 @@ copy_loop_body (copy_start, copy_end, map, exit_label, last_iteration,
}
}
}
-
+
/* If this is a setting of a splittable variable, then determine
how to split the variable, create a new set based on this split,
and set up the reg_map so that later uses of the variable will
use the new split variable. */
-
+
dest_reg_was_split = 0;
-
+
if ((set = single_set (insn))
&& GET_CODE (SET_DEST (set)) == REG
&& splittable_regs[REGNO (SET_DEST (set))])
{
int regno = REGNO (SET_DEST (set));
-
+ int src_regno;
+
dest_reg_was_split = 1;
-
- /* Compute the increment value for the giv, if it wasn't
- already computed above. */
- if (giv_inc == 0)
- giv_inc = calculate_giv_inc (set, insn, regno);
giv_dest_reg = SET_DEST (set);
- giv_src_reg = SET_DEST (set);
+ if (derived_regs[regno])
+ {
+ /* ??? This relies on SET_SRC (SET) to be of
+ the form (plus (reg) (const_int)), and thus
+ forces recombine_givs to restrict the kind
+ of giv derivations it does before unrolling. */
+ giv_src_reg = XEXP (SET_SRC (set), 0);
+ giv_inc = XEXP (SET_SRC (set), 1);
+ }
+ else
+ {
+ giv_src_reg = giv_dest_reg;
+ /* Compute the increment value for the giv, if it wasn't
+ already computed above. */
+ if (giv_inc == 0)
+ giv_inc = calculate_giv_inc (set, insn, regno);
+ }
+ src_regno = REGNO (giv_src_reg);
if (unroll_type == UNROLL_COMPLETELY)
{
/* Completely unrolling the loop. Set the induction
variable to a known constant value. */
-
+
/* The value in splittable_regs may be an invariant
value, so we must use plus_constant here. */
splittable_regs[regno]
- = plus_constant (splittable_regs[regno], INTVAL (giv_inc));
+ = plus_constant (splittable_regs[src_regno],
+ INTVAL (giv_inc));
if (GET_CODE (splittable_regs[regno]) == PLUS)
{
@@ -1842,7 +1847,7 @@ copy_loop_body (copy_start, copy_end, map, exit_label, last_iteration,
be a constant plus the original register. Except
on the last iteration, when the result has to
go back into the original iteration var register. */
-
+
/* Handle bivs which must be mapped to a new register
when split. This happens for bivs which need their
final value set before loop entry. The new register
@@ -1850,23 +1855,23 @@ copy_loop_body (copy_start, copy_end, map, exit_label, last_iteration,
induction entry by find_splittable_regs. */
if (regno < max_reg_before_loop
- && reg_iv_type[regno] == BASIC_INDUCT)
+ && REG_IV_TYPE (regno) == BASIC_INDUCT)
{
giv_src_reg = reg_biv_class[regno]->biv->src_reg;
giv_dest_reg = giv_src_reg;
}
-
+
#if 0
/* If non-reduced/final-value givs were split, then
this would have to remap those givs also. See
find_splittable_regs. */
#endif
-
+
splittable_regs[regno]
= GEN_INT (INTVAL (giv_inc)
- + INTVAL (splittable_regs[regno]));
+ + INTVAL (splittable_regs[src_regno]));
giv_inc = splittable_regs[regno];
-
+
/* Now split the induction variable by changing the dest
of this insn to a new register, and setting its
reg_map entry to point to this new register.
@@ -1910,7 +1915,7 @@ copy_loop_body (copy_start, copy_end, map, exit_label, last_iteration,
copy = emit_insn (pattern);
}
REG_NOTES (copy) = initial_reg_note_copy (REG_NOTES (insn), map);
-
+
#ifdef HAVE_cc0
/* If this insn is setting CC0, it may need to look at
the insn that uses CC0 to see what type of insn it is.
@@ -1945,12 +1950,13 @@ copy_loop_body (copy_start, copy_end, map, exit_label, last_iteration,
{
int regno = REGNO (SET_DEST (pattern));
- if (regno < map->const_equiv_map_size
- && map->const_age_map[regno] == map->const_age)
- map->const_age_map[regno] = -1;
+ if (regno < VARRAY_SIZE (map->const_equiv_varray)
+ && (VARRAY_CONST_EQUIV (map->const_equiv_varray, regno).age
+ == map->const_age))
+ VARRAY_CONST_EQUIV (map->const_equiv_varray, regno).age = -1;
}
break;
-
+
case JUMP_INSN:
pattern = copy_rtx_and_substitute (PATTERN (insn), map);
copy = emit_jump_insn (pattern);
@@ -1994,7 +2000,7 @@ copy_loop_body (copy_start, copy_end, map, exit_label, last_iteration,
abort ();
}
}
-
+
#ifdef HAVE_cc0
if (cc0_insn)
try_constants (cc0_insn, map);
@@ -2032,10 +2038,10 @@ copy_loop_body (copy_start, copy_end, map, exit_label, last_iteration,
for a switch statement. This label must have been mapped,
so just use the label_map to get the new jump label. */
JUMP_LABEL (copy)
- = get_label_from_map (map,
- CODE_LABEL_NUMBER (JUMP_LABEL (insn)));
+ = get_label_from_map (map,
+ CODE_LABEL_NUMBER (JUMP_LABEL (insn)));
}
-
+
/* If this is a non-local jump, then must increase the label
use count so that the label will not be deleted when the
original jump is deleted. */
@@ -2082,7 +2088,7 @@ copy_loop_body (copy_start, copy_end, map, exit_label, last_iteration,
emit_barrier ();
}
break;
-
+
case CALL_INSN:
pattern = copy_rtx_and_substitute (PATTERN (insn), map);
copy = emit_call_insn (pattern);
@@ -2102,9 +2108,9 @@ copy_loop_body (copy_start, copy_end, map, exit_label, last_iteration,
/* Be lazy and assume CALL_INSNs clobber all hard registers. */
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
- map->const_equiv_map[i] = 0;
+ VARRAY_CONST_EQUIV (map->const_equiv_varray, i).rtx = 0;
break;
-
+
case CODE_LABEL:
/* If this is the loop start label, then we don't need to emit a
copy of this label since no one will use it. */
@@ -2116,33 +2122,38 @@ copy_loop_body (copy_start, copy_end, map, exit_label, last_iteration,
map->const_age++;
}
break;
-
+
case BARRIER:
copy = emit_barrier ();
break;
-
+
case NOTE:
- /* VTOP notes are valid only before the loop exit test. If placed
- anywhere else, loop may generate bad code. */
-
+ /* VTOP and CONT notes are valid only before the loop exit test.
+ If placed anywhere else, loop may generate bad code. */
+ /* BASIC_BLOCK notes exist to stabilize basic block structures with
+ the associated rtl. We do not want to share the structure in
+ this new block. */
+
if (NOTE_LINE_NUMBER (insn) != NOTE_INSN_DELETED
- && (NOTE_LINE_NUMBER (insn) != NOTE_INSN_LOOP_VTOP
+ && NOTE_LINE_NUMBER (insn) != NOTE_INSN_BASIC_BLOCK
+ && ((NOTE_LINE_NUMBER (insn) != NOTE_INSN_LOOP_VTOP
+ && NOTE_LINE_NUMBER (insn) != NOTE_INSN_LOOP_CONT)
|| (last_iteration && unroll_type != UNROLL_COMPLETELY)))
copy = emit_note (NOTE_SOURCE_FILE (insn),
NOTE_LINE_NUMBER (insn));
else
copy = 0;
break;
-
+
default:
abort ();
break;
}
-
+
map->insn_map[INSN_UID (insn)] = copy;
}
while (insn != copy_end);
-
+
/* Now finish coping the REG_NOTES. */
insn = copy_start;
do
@@ -2170,7 +2181,8 @@ copy_loop_body (copy_start, copy_end, map, exit_label, last_iteration,
for (insn = copy_notes_from; insn != loop_end; insn = NEXT_INSN (insn))
{
if (GET_CODE (insn) == NOTE
- && NOTE_LINE_NUMBER (insn) != NOTE_INSN_DELETED)
+ && NOTE_LINE_NUMBER (insn) != NOTE_INSN_DELETED
+ && NOTE_LINE_NUMBER (insn) != NOTE_INSN_BASIC_BLOCK)
emit_note (NOTE_SOURCE_FILE (insn), NOTE_LINE_NUMBER (insn));
}
}
@@ -2237,7 +2249,7 @@ back_branch_in_range_p (insn, loop_start, loop_end)
if (GET_CODE (p) == JUMP_INSN)
{
target_insn = JUMP_LABEL (p);
-
+
/* Search from loop_start to insn, to see if one of them is
the target_insn. We can't use INSN_LUID comparisons here,
since insn may not have an LUID entry. */
@@ -2303,7 +2315,7 @@ fold_rtx_mult_add (mult1, mult2, add1, mode)
Returns the increment value as an rtx, simplified as much as possible,
if it can be calculated. Otherwise, returns 0. */
-rtx
+rtx
biv_total_increment (bl, loop_start, loop_end)
struct iv_class *bl;
rtx loop_start, loop_end;
@@ -2322,7 +2334,7 @@ biv_total_increment (bl, loop_start, loop_end)
for (v = bl->biv; v; v = v->next_iv)
{
if (v->always_computable && v->mult_val == const1_rtx
- && ! back_branch_in_range_p (v->insn, loop_start, loop_end))
+ && ! v->maybe_multiple)
result = fold_rtx_mult_add (result, const1_rtx, v->add_val, v->mode);
else
return 0;
@@ -2338,7 +2350,7 @@ biv_total_increment (bl, loop_start, loop_end)
Initial_value and/or increment are set to zero if their values could not
be calculated. */
-void
+static void
iteration_info (iteration_var, initial_value, increment, loop_start, loop_end)
rtx iteration_var, *initial_value, *increment;
rtx loop_start, loop_end;
@@ -2358,7 +2370,7 @@ iteration_info (iteration_var, initial_value, increment, loop_start, loop_end)
/* If this is a new register, can't handle it since we don't have any
reg_iv_type entry for it. */
- if (REGNO (iteration_var) >= max_reg_before_loop)
+ if ((unsigned) REGNO (iteration_var) >= reg_iv_type->num_elements)
{
if (loop_dump_stream)
fprintf (loop_dump_stream,
@@ -2368,7 +2380,7 @@ iteration_info (iteration_var, initial_value, increment, loop_start, loop_end)
/* Reject iteration variables larger than the host wide int size, since they
could result in a number of iterations greater than the range of our
- `unsigned HOST_WIDE_INT' variable loop_n_iterations. */
+ `unsigned HOST_WIDE_INT' variable loop_info->n_iterations. */
else if ((GET_MODE_BITSIZE (GET_MODE (iteration_var))
> HOST_BITS_PER_WIDE_INT))
{
@@ -2384,44 +2396,62 @@ iteration_info (iteration_var, initial_value, increment, loop_start, loop_end)
"Loop unrolling: Iteration var not an integer.\n");
return;
}
- else if (reg_iv_type[REGNO (iteration_var)] == BASIC_INDUCT)
+ else if (REG_IV_TYPE (REGNO (iteration_var)) == BASIC_INDUCT)
{
+ /* When reg_iv_type / reg_iv_info is resized for biv increments
+ that are turned into givs, reg_biv_class is not resized.
+ So check here that we don't make an out-of-bounds access. */
+ if (REGNO (iteration_var) >= max_reg_before_loop)
+ abort ();
+
/* Grab initial value, only useful if it is a constant. */
bl = reg_biv_class[REGNO (iteration_var)];
*initial_value = bl->initial_value;
*increment = biv_total_increment (bl, loop_start, loop_end);
}
- else if (reg_iv_type[REGNO (iteration_var)] == GENERAL_INDUCT)
- {
-#if 1
- /* ??? The code below does not work because the incorrect number of
- iterations is calculated when the biv is incremented after the giv
- is set (which is the usual case). This can probably be accounted
- for by biasing the initial_value by subtracting the amount of the
- increment that occurs between the giv set and the giv test. However,
- a giv as an iterator is very rare, so it does not seem worthwhile
- to handle this. */
- /* ??? An example failure is: i = 6; do {;} while (i++ < 9). */
- if (loop_dump_stream)
- fprintf (loop_dump_stream,
- "Loop unrolling: Giv iterators are not handled.\n");
- return;
-#else
- /* Initial value is mult_val times the biv's initial value plus
- add_val. Only useful if it is a constant. */
- v = reg_iv_info[REGNO (iteration_var)];
+ else if (REG_IV_TYPE (REGNO (iteration_var)) == GENERAL_INDUCT)
+ {
+ HOST_WIDE_INT offset = 0;
+ struct induction *v = REG_IV_INFO (REGNO (iteration_var));
+
+ if (REGNO (v->src_reg) >= max_reg_before_loop)
+ abort ();
+
bl = reg_biv_class[REGNO (v->src_reg)];
- *initial_value = fold_rtx_mult_add (v->mult_val, bl->initial_value,
- v->add_val, v->mode);
-
+
/* Increment value is mult_val times the increment value of the biv. */
*increment = biv_total_increment (bl, loop_start, loop_end);
if (*increment)
- *increment = fold_rtx_mult_add (v->mult_val, *increment, const0_rtx,
- v->mode);
-#endif
+ {
+ struct induction *biv_inc;
+
+ *increment
+ = fold_rtx_mult_add (v->mult_val, *increment, const0_rtx, v->mode);
+ /* The caller assumes that one full increment has occured at the
+ first loop test. But that's not true when the biv is incremented
+ after the giv is set (which is the usual case), e.g.:
+ i = 6; do {;} while (i++ < 9) .
+ Therefore, we bias the initial value by subtracting the amount of
+ the increment that occurs between the giv set and the giv test. */
+ for (biv_inc = bl->biv; biv_inc; biv_inc = biv_inc->next_iv)
+ {
+ if (loop_insn_first_p (v->insn, biv_inc->insn))
+ offset -= INTVAL (biv_inc->add_val);
+ }
+ offset *= INTVAL (v->mult_val);
+ }
+ if (loop_dump_stream)
+ fprintf (loop_dump_stream,
+ "Loop unrolling: Giv iterator, initial value bias %ld.\n",
+ (long) offset);
+ /* Initial value is mult_val times the biv's initial value plus
+ add_val. Only useful if it is a constant. */
+ *initial_value
+ = fold_rtx_mult_add (v->mult_val,
+ plus_constant (bl->initial_value, offset),
+ v->add_val, v->mode);
}
else
{
@@ -2432,60 +2462,6 @@ iteration_info (iteration_var, initial_value, increment, loop_start, loop_end)
}
}
-/* Calculate the approximate final value of the iteration variable
- which has an loop exit test with code COMPARISON_CODE and comparison value
- of COMPARISON_VALUE. Also returns an indication of whether the comparison
- was signed or unsigned, and the direction of the comparison. This info is
- needed to calculate the number of loop iterations. */
-
-static rtx
-approx_final_value (comparison_code, comparison_value, unsigned_p, compare_dir)
- enum rtx_code comparison_code;
- rtx comparison_value;
- int *unsigned_p;
- int *compare_dir;
-{
- /* Calculate the final value of the induction variable.
- The exact final value depends on the branch operator, and increment sign.
- This is only an approximate value. It will be wrong if the iteration
- variable is not incremented by one each time through the loop, and
- approx final value - start value % increment != 0. */
-
- *unsigned_p = 0;
- switch (comparison_code)
- {
- case LEU:
- *unsigned_p = 1;
- case LE:
- *compare_dir = 1;
- return plus_constant (comparison_value, 1);
- case GEU:
- *unsigned_p = 1;
- case GE:
- *compare_dir = -1;
- return plus_constant (comparison_value, -1);
- case EQ:
- /* Can not calculate a final value for this case. */
- *compare_dir = 0;
- return 0;
- case LTU:
- *unsigned_p = 1;
- case LT:
- *compare_dir = 1;
- return comparison_value;
- break;
- case GTU:
- *unsigned_p = 1;
- case GT:
- *compare_dir = -1;
- return comparison_value;
- case NE:
- *compare_dir = 0;
- return comparison_value;
- default:
- abort ();
- }
-}
/* For each biv and giv, determine whether it can be safely split into
a different variable for each unrolled copy of the loop body. If it
@@ -2513,11 +2489,12 @@ approx_final_value (comparison_code, comparison_value, unsigned_p, compare_dir)
static int
find_splittable_regs (unroll_type, loop_start, loop_end, end_insert_before,
- unroll_number)
+ unroll_number, n_iterations)
enum unroll_types unroll_type;
rtx loop_start, loop_end;
rtx end_insert_before;
int unroll_number;
+ unsigned HOST_WIDE_INT n_iterations;
{
struct iv_class *bl;
struct induction *v;
@@ -2555,7 +2532,8 @@ find_splittable_regs (unroll_type, loop_start, loop_end, end_insert_before,
|| (uid_luid[REGNO_FIRST_UID (bl->regno)]
< INSN_LUID (bl->init_insn))
|| reg_mentioned_p (bl->biv->dest_reg, SET_SRC (bl->init_set)))
- && ! (biv_final_value = final_biv_value (bl, loop_start, loop_end)))
+ && ! (biv_final_value = final_biv_value (bl, loop_start, loop_end,
+ n_iterations)))
biv_splittable = 0;
/* If any of the insns setting the BIV don't do so with a simple
@@ -2744,7 +2722,7 @@ find_splittable_givs (bl, unroll_type, loop_start, loop_end, increment,
&& (! v->always_computable
|| back_branch_in_range_p (v->insn, loop_start, loop_end)))
continue;
-
+
/* The giv increment value must be a constant. */
giv_inc = fold_rtx_mult_add (v->mult_val, increment, const0_rtx,
v->mode);
@@ -2756,7 +2734,7 @@ find_splittable_givs (bl, unroll_type, loop_start, loop_end, increment,
the loop, or else the final value of the giv must be known.
Otherwise, it is not safe to split the giv since it may not have the
proper value on loop exit. */
-
+
/* The used outside loop test will fail for DEST_ADDR givs. They are
never used outside the loop anyways, so it is always safe to split a
DEST_ADDR giv. */
@@ -2780,6 +2758,10 @@ find_splittable_givs (bl, unroll_type, loop_start, loop_end, increment,
/* Line above always fails if INSN was moved by loop opt. */
|| (uid_luid[REGNO_LAST_UID (REGNO (v->dest_reg))]
>= INSN_LUID (loop_end)))
+ /* Givs made from biv increments are missed by the above test, so
+ test explicitly for them. */
+ && (REGNO (v->dest_reg) < first_increment_giv
+ || REGNO (v->dest_reg) > last_increment_giv)
&& ! (final_value = v->final_value))
continue;
@@ -2800,11 +2782,11 @@ find_splittable_givs (bl, unroll_type, loop_start, loop_end, increment,
emit_insn_before (gen_move_insn (tem, v->dest_reg), loop_start);
emit_insn_before (gen_move_insn (v->dest_reg, final_value),
loop_start);
-
+
if (loop_dump_stream)
fprintf (loop_dump_stream, "Giv %d mapped to %d for split.\n",
REGNO (v->dest_reg), REGNO (tem));
-
+
v->src_reg = tem;
}
#endif
@@ -2878,8 +2860,9 @@ find_splittable_givs (bl, unroll_type, loop_start, loop_end, increment,
v->add_val, tem, loop_start);
value = tem;
}
-
+
splittable_regs[REGNO (v->new_reg)] = value;
+ derived_regs[REGNO (v->new_reg)] = v->derived_from != 0;
}
else
{
@@ -2919,8 +2902,11 @@ find_splittable_givs (bl, unroll_type, loop_start, loop_end, increment,
To share a register here, the values must be
equal. */
&& rtx_equal_p (v->same->mult_val, v->mult_val)
- && rtx_equal_p (v->same->add_val, v->add_val))
-
+ && rtx_equal_p (v->same->add_val, v->add_val)
+ /* If the memory references have different modes,
+ then the address may not be valid and we must
+ not share registers. */
+ && verify_addresses (v, giv_inc, unroll_number))
{
v->dest_reg = v->same->dest_reg;
v->shared = 1;
@@ -2932,17 +2918,38 @@ find_splittable_givs (bl, unroll_type, loop_start, loop_end, increment,
Emit insn to initialize its value before loop start. */
rtx tem = gen_reg_rtx (v->mode);
+ struct induction *same = v->same;
+ rtx new_reg = v->new_reg;
record_base_value (REGNO (tem), v->add_val, 0);
+ if (same && same->derived_from)
+ {
+ /* calculate_giv_inc doesn't work for derived givs.
+ copy_loop_body works around the problem for the
+ DEST_REG givs themselves, but it can't handle
+ DEST_ADDR givs that have been combined with
+ a derived DEST_REG giv.
+ So Handle V as if the giv from which V->SAME has
+ been derived has been combined with V.
+ recombine_givs only derives givs from givs that
+ are reduced the ordinary, so we need not worry
+ about same->derived_from being in turn derived. */
+
+ same = same->derived_from;
+ new_reg = express_from (same, v);
+ new_reg = replace_rtx (new_reg, same->dest_reg,
+ same->new_reg);
+ }
+
/* If the address giv has a constant in its new_reg value,
then this constant can be pulled out and put in value,
instead of being part of the initialization code. */
-
- if (GET_CODE (v->new_reg) == PLUS
- && GET_CODE (XEXP (v->new_reg, 1)) == CONST_INT)
+
+ if (GET_CODE (new_reg) == PLUS
+ && GET_CODE (XEXP (new_reg, 1)) == CONST_INT)
{
v->dest_reg
- = plus_constant (tem, INTVAL (XEXP (v->new_reg,1)));
+ = plus_constant (tem, INTVAL (XEXP (new_reg, 1)));
/* Only succeed if this will give valid addresses.
Try to validate both the first and the last
@@ -2953,9 +2960,9 @@ find_splittable_givs (bl, unroll_type, loop_start, loop_end, increment,
/* Save the negative of the eliminated const, so
that we can calculate the dest_reg's increment
value later. */
- v->const_adjust = - INTVAL (XEXP (v->new_reg, 1));
+ v->const_adjust = - INTVAL (XEXP (new_reg, 1));
- v->new_reg = XEXP (v->new_reg, 0);
+ new_reg = XEXP (new_reg, 0);
if (loop_dump_stream)
fprintf (loop_dump_stream,
"Eliminating constant from giv %d\n",
@@ -2966,7 +2973,7 @@ find_splittable_givs (bl, unroll_type, loop_start, loop_end, increment,
}
else
v->dest_reg = tem;
-
+
/* If the address hasn't been checked for validity yet, do so
now, and fail completely if either the first or the last
unrolled copy of the address is not a valid address
@@ -2984,7 +2991,10 @@ find_splittable_givs (bl, unroll_type, loop_start, loop_end, increment,
INSN_UID (v->insn));
continue;
}
-
+
+ v->new_reg = new_reg;
+ v->same = same;
+
/* We set this after the address check, to guarantee that
the register will be initialized. */
v->unrolled = 1;
@@ -3023,7 +3033,7 @@ find_splittable_givs (bl, unroll_type, loop_start, loop_end, increment,
else
{
v->dest_reg = value;
-
+
/* Check the resulting address for validity, and fail
if the resulting address would be invalid. */
if (! verify_addresses (v, giv_inc, unroll_number))
@@ -3038,29 +3048,41 @@ find_splittable_givs (bl, unroll_type, loop_start, loop_end, increment,
INSN_UID (v->insn));
continue;
}
+ if (v->same && v->same->derived_from)
+ {
+ /* Handle V as if the giv from which V->SAME has
+ been derived has been combined with V. */
+
+ v->same = v->same->derived_from;
+ v->new_reg = express_from (v->same, v);
+ v->new_reg = replace_rtx (v->new_reg, v->same->dest_reg,
+ v->same->new_reg);
+ }
+
}
-
+
/* Store the value of dest_reg into the insn. This sharing
will not be a problem as this insn will always be copied
later. */
-
+
*v->location = v->dest_reg;
-
+
/* If this address giv is combined with a dest reg giv, then
save the base giv's induction pointer so that we will be
able to handle this address giv properly. The base giv
itself does not have to be splittable. */
-
+
if (v->same && v->same->giv_type == DEST_REG)
addr_combined_regs[REGNO (v->same->new_reg)] = v->same;
-
+
if (GET_CODE (v->new_reg) == REG)
{
/* This giv maybe hasn't been combined with any others.
Make sure that it's giv is marked as splittable here. */
-
+
splittable_regs[REGNO (v->new_reg)] = value;
-
+ derived_regs[REGNO (v->new_reg)] = v->derived_from != 0;
+
/* Make it appear to depend upon itself, so that the
giv will be properly split in the main loop above. */
if (! v->same)
@@ -3083,7 +3105,7 @@ find_splittable_givs (bl, unroll_type, loop_start, loop_end, increment,
it makes sense to reduce&split givs when possible, as this will
result in simpler instructions, and will not require that a reg
be live across loop iterations. */
-
+
splittable_regs[REGNO (v->dest_reg)] = value;
fprintf (stderr, "Giv %d at insn %d not reduced\n",
REGNO (v->dest_reg), INSN_UID (v->insn));
@@ -3091,7 +3113,7 @@ find_splittable_givs (bl, unroll_type, loop_start, loop_end, increment,
continue;
#endif
}
-
+
/* Unreduced givs are only updated once by definition. Reduced givs
are updated as many times as their biv is. Mark it so if this is
a splittable register. Don't need to do anything for address givs
@@ -3103,15 +3125,20 @@ find_splittable_givs (bl, unroll_type, loop_start, loop_end, increment,
if (! v->ignore)
count = reg_biv_class[REGNO (v->src_reg)]->biv_count;
+ if (count > 1 && v->derived_from)
+ /* In this case, there is one set where the giv insn was and one
+ set each after each biv increment. (Most are likely dead.) */
+ count++;
+
splittable_regs_updates[REGNO (v->new_reg)] = count;
}
result++;
-
+
if (loop_dump_stream)
{
int regnum;
-
+
if (GET_CODE (v->dest_reg) == CONST_INT)
regnum = -1;
else if (GET_CODE (v->dest_reg) != REG)
@@ -3148,7 +3175,7 @@ reg_dead_after_loop (reg, loop_start, loop_end)
all exits of inner nested loops that would exit this loop. We don't
have any way to identify those, so we just give up if there are any
such inner loop exits. */
-
+
for (label = loop_number_exit_labels[this_loop_num]; label;
label = LABEL_NEXTREF (label))
label_count++;
@@ -3206,11 +3233,12 @@ reg_dead_after_loop (reg, loop_start, loop_end)
/* Try to calculate the final value of the biv, the value it will have at
the end of the loop. If we can do it, return that value. */
-
+
rtx
-final_biv_value (bl, loop_start, loop_end)
+final_biv_value (bl, loop_start, loop_end, n_iterations)
struct iv_class *bl;
rtx loop_start, loop_end;
+ unsigned HOST_WIDE_INT n_iterations;
{
rtx increment, tem;
@@ -3228,7 +3256,7 @@ final_biv_value (bl, loop_start, loop_end)
if (loop_dump_stream)
fprintf (loop_dump_stream,
"Final biv value for %d, reversed biv.\n", bl->regno);
-
+
return const0_rtx;
}
@@ -3238,12 +3266,12 @@ final_biv_value (bl, loop_start, loop_end)
it may not have its final value when the loop exits), and the initial
value of the biv must be invariant. */
- if (loop_n_iterations != 0
+ if (n_iterations != 0
&& ! loop_number_exit_count[uid_loop_num[INSN_UID (loop_start)]]
&& invariant_p (bl->initial_value))
{
increment = biv_total_increment (bl, loop_start, loop_end);
-
+
if (increment && invariant_p (increment))
{
/* Can calculate the loop exit value, emit insns after loop
@@ -3255,13 +3283,13 @@ final_biv_value (bl, loop_start, loop_end)
/* Make sure loop_end is not the last insn. */
if (NEXT_INSN (loop_end) == 0)
emit_note_after (NOTE_INSN_DELETED, loop_end);
- emit_iv_add_mult (increment, GEN_INT (loop_n_iterations),
+ emit_iv_add_mult (increment, GEN_INT (n_iterations),
bl->initial_value, tem, NEXT_INSN (loop_end));
if (loop_dump_stream)
fprintf (loop_dump_stream,
"Final biv value for %d, calculated.\n", bl->regno);
-
+
return tem;
}
}
@@ -3284,9 +3312,10 @@ final_biv_value (bl, loop_start, loop_end)
the end of the loop. If we can do it, return that value. */
rtx
-final_giv_value (v, loop_start, loop_end)
+final_giv_value (v, loop_start, loop_end, n_iterations)
struct induction *v;
rtx loop_start, loop_end;
+ unsigned HOST_WIDE_INT n_iterations;
{
struct iv_class *bl;
rtx insn;
@@ -3311,13 +3340,13 @@ final_giv_value (v, loop_start, loop_end)
/* Try to calculate the final value as a function of the biv it depends
upon. The only exit from the loop must be the fall through at the bottom
(otherwise it may not have its final value when the loop exits). */
-
+
/* ??? Can calculate the final giv value by subtracting off the
extra biv increments times the giv's mult_val. The loop must have
only one exit for this to work, but the loop iterations does not need
to be known. */
- if (loop_n_iterations != 0
+ if (n_iterations != 0
&& ! loop_number_exit_count[uid_loop_num[INSN_UID (loop_start)]])
{
/* ?? It is tempting to use the biv's value here since these insns will
@@ -3337,8 +3366,8 @@ final_giv_value (v, loop_start, loop_end)
&& invariant_p (bl->initial_value))
{
/* Can calculate the loop exit value of its biv as
- (loop_n_iterations * increment) + initial_value */
-
+ (n_iterations * increment) + initial_value */
+
/* The loop exit value of the giv is then
(final_biv_value - extra increments) * mult_val + add_val.
The extra increments are any increments to the biv which
@@ -3351,7 +3380,7 @@ final_giv_value (v, loop_start, loop_end)
/* Put the final biv value in tem. */
tem = gen_reg_rtx (bl->biv->mode);
record_base_value (REGNO (tem), bl->biv->add_val, 0);
- emit_iv_add_mult (increment, GEN_INT (loop_n_iterations),
+ emit_iv_add_mult (increment, GEN_INT (n_iterations),
bl->initial_value, tem, insert_before);
/* Subtract off extra increments as we find them. */
@@ -3372,11 +3401,11 @@ final_giv_value (v, loop_start, loop_end)
emit_insn_before (seq, insert_before);
}
}
-
+
/* Now calculate the giv's final value. */
emit_iv_add_mult (tem, v->mult_val, v->add_val, tem,
insert_before);
-
+
if (loop_dump_stream)
fprintf (loop_dump_stream,
"Final giv value for %d, calc from biv's value.\n",
@@ -3405,43 +3434,185 @@ final_giv_value (v, loop_start, loop_end)
}
+/* Look back before LOOP_START for then insn that sets REG and return
+ the equivalent constant if there is a REG_EQUAL note otherwise just
+ the SET_SRC of REG. */
+
+static rtx
+loop_find_equiv_value (loop_start, reg)
+ rtx loop_start;
+ rtx reg;
+{
+ rtx insn, set;
+ rtx ret;
+
+ ret = reg;
+ for (insn = PREV_INSN (loop_start); insn ; insn = PREV_INSN (insn))
+ {
+ if (GET_CODE (insn) == CODE_LABEL)
+ break;
+
+ else if (GET_RTX_CLASS (GET_CODE (insn)) == 'i'
+ && reg_set_p (reg, insn))
+ {
+ /* We found the last insn before the loop that sets the register.
+ If it sets the entire register, and has a REG_EQUAL note,
+ then use the value of the REG_EQUAL note. */
+ if ((set = single_set (insn))
+ && (SET_DEST (set) == reg))
+ {
+ rtx note = find_reg_note (insn, REG_EQUAL, NULL_RTX);
+
+ /* Only use the REG_EQUAL note if it is a constant.
+ Other things, divide in particular, will cause
+ problems later if we use them. */
+ if (note && GET_CODE (XEXP (note, 0)) != EXPR_LIST
+ && CONSTANT_P (XEXP (note, 0)))
+ ret = XEXP (note, 0);
+ else
+ ret = SET_SRC (set);
+ }
+ break;
+ }
+ }
+ return ret;
+}
+
+
+/* Return a simplified rtx for the expression OP - REG.
+
+ REG must appear in OP, and OP must be a register or the sum of a register
+ and a second term.
+
+ Thus, the return value must be const0_rtx or the second term.
+
+ The caller is responsible for verifying that REG appears in OP and OP has
+ the proper form. */
+
+static rtx
+subtract_reg_term (op, reg)
+ rtx op, reg;
+{
+ if (op == reg)
+ return const0_rtx;
+ if (GET_CODE (op) == PLUS)
+ {
+ if (XEXP (op, 0) == reg)
+ return XEXP (op, 1);
+ else if (XEXP (op, 1) == reg)
+ return XEXP (op, 0);
+ }
+ /* OP does not contain REG as a term. */
+ abort ();
+}
+
+
+/* Find and return register term common to both expressions OP0 and
+ OP1 or NULL_RTX if no such term exists. Each expression must be a
+ REG or a PLUS of a REG. */
+
+static rtx
+find_common_reg_term (op0, op1)
+ rtx op0, op1;
+{
+ if ((GET_CODE (op0) == REG || GET_CODE (op0) == PLUS)
+ && (GET_CODE (op1) == REG || GET_CODE (op1) == PLUS))
+ {
+ rtx op00;
+ rtx op01;
+ rtx op10;
+ rtx op11;
+
+ if (GET_CODE (op0) == PLUS)
+ op01 = XEXP (op0, 1), op00 = XEXP (op0, 0);
+ else
+ op01 = const0_rtx, op00 = op0;
+
+ if (GET_CODE (op1) == PLUS)
+ op11 = XEXP (op1, 1), op10 = XEXP (op1, 0);
+ else
+ op11 = const0_rtx, op10 = op1;
+
+ /* Find and return common register term if present. */
+ if (REG_P (op00) && (op00 == op10 || op00 == op11))
+ return op00;
+ else if (REG_P (op01) && (op01 == op10 || op01 == op11))
+ return op01;
+ }
+
+ /* No common register term found. */
+ return NULL_RTX;
+}
+
+
/* Calculate the number of loop iterations. Returns the exact number of loop
iterations if it can be calculated, otherwise returns zero. */
unsigned HOST_WIDE_INT
-loop_iterations (loop_start, loop_end)
+loop_iterations (loop_start, loop_end, loop_info)
rtx loop_start, loop_end;
+ struct loop_info *loop_info;
{
rtx comparison, comparison_value;
rtx iteration_var, initial_value, increment, final_value;
enum rtx_code comparison_code;
- HOST_WIDE_INT i;
+ HOST_WIDE_INT abs_inc;
+ unsigned HOST_WIDE_INT abs_diff;
+ int off_by_one;
int increment_dir;
- int unsigned_compare, compare_dir, final_larger;
- unsigned long tempu;
+ int unsigned_p, compare_dir, final_larger;
rtx last_loop_insn;
-
- /* First find the iteration variable. If the last insn is a conditional
- branch, and the insn before tests a register value, make that the
- iteration variable. */
-
- loop_initial_value = 0;
- loop_increment = 0;
- loop_final_value = 0;
- loop_iteration_var = 0;
-
- /* We used to use pren_nonnote_insn here, but that fails because it might
+ rtx vtop;
+ rtx reg_term;
+
+ loop_info->n_iterations = 0;
+ loop_info->initial_value = 0;
+ loop_info->initial_equiv_value = 0;
+ loop_info->comparison_value = 0;
+ loop_info->final_value = 0;
+ loop_info->final_equiv_value = 0;
+ loop_info->increment = 0;
+ loop_info->iteration_var = 0;
+ loop_info->unroll_number = 1;
+ loop_info->vtop = 0;
+
+ /* We used to use prev_nonnote_insn here, but that fails because it might
accidentally get the branch for a contained loop if the branch for this
loop was deleted. We can only trust branches immediately before the
loop_end. */
last_loop_insn = PREV_INSN (loop_end);
+ /* ??? We should probably try harder to find the jump insn
+ at the end of the loop. The following code assumes that
+ the last loop insn is a jump to the top of the loop. */
+ if (GET_CODE (last_loop_insn) != JUMP_INSN)
+ {
+ if (loop_dump_stream)
+ fprintf (loop_dump_stream,
+ "Loop iterations: No final conditional branch found.\n");
+ return 0;
+ }
+
+ /* If there is a more than a single jump to the top of the loop
+ we cannot (easily) determine the iteration count. */
+ if (LABEL_NUSES (JUMP_LABEL (last_loop_insn)) > 1)
+ {
+ if (loop_dump_stream)
+ fprintf (loop_dump_stream,
+ "Loop iterations: Loop has multiple back edges.\n");
+ return 0;
+ }
+
+ /* Find the iteration variable. If the last insn is a conditional
+ branch, and the insn before tests a register value, make that the
+ iteration variable. */
+
comparison = get_condition_for_loop (last_loop_insn);
if (comparison == 0)
{
if (loop_dump_stream)
fprintf (loop_dump_stream,
- "Loop unrolling: No final conditional branch found.\n");
+ "Loop iterations: No final comparison found.\n");
return 0;
}
@@ -3452,18 +3623,37 @@ loop_iterations (loop_start, loop_end)
iteration_var = XEXP (comparison, 0);
comparison_value = XEXP (comparison, 1);
+ /* Check if there is a NOTE_INSN_LOOP_VTOP note. If there is,
+ that means that this is a for or while style loop, with
+ a loop exit test at the start. Thus, we can assume that
+ the loop condition was true when the loop was entered.
+
+ We start at the end and search backwards for the previous
+ NOTE. If there is no NOTE_INSN_LOOP_VTOP for this loop,
+ the search will stop at the NOTE_INSN_LOOP_CONT. */
+ vtop = loop_end;
+ do
+ vtop = PREV_INSN (vtop);
+ while (GET_CODE (vtop) != NOTE
+ || NOTE_LINE_NUMBER (vtop) > 0
+ || NOTE_LINE_NUMBER (vtop) == NOTE_REPEATED_LINE_NUMBER
+ || NOTE_LINE_NUMBER (vtop) == NOTE_INSN_DELETED);
+ if (NOTE_LINE_NUMBER (vtop) != NOTE_INSN_LOOP_VTOP)
+ vtop = NULL_RTX;
+ loop_info->vtop = vtop;
+
if (GET_CODE (iteration_var) != REG)
{
if (loop_dump_stream)
fprintf (loop_dump_stream,
- "Loop unrolling: Comparison not against register.\n");
+ "Loop iterations: Comparison not against register.\n");
return 0;
}
- /* Loop iterations is always called before any new registers are created
- now, so this should never occur. */
+ /* The only new registers that care created before loop iterations are
+ givs made from biv increments, so this should never occur. */
- if (REGNO (iteration_var) >= max_reg_before_loop)
+ if ((unsigned) REGNO (iteration_var) >= reg_iv_type->num_elements)
abort ();
iteration_info (iteration_var, &initial_value, &increment,
@@ -3472,102 +3662,233 @@ loop_iterations (loop_start, loop_end)
/* iteration_info already printed a message. */
return 0;
+ unsigned_p = 0;
+ off_by_one = 0;
+ switch (comparison_code)
+ {
+ case LEU:
+ unsigned_p = 1;
+ case LE:
+ compare_dir = 1;
+ off_by_one = 1;
+ break;
+ case GEU:
+ unsigned_p = 1;
+ case GE:
+ compare_dir = -1;
+ off_by_one = -1;
+ break;
+ case EQ:
+ /* Cannot determine loop iterations with this case. */
+ compare_dir = 0;
+ break;
+ case LTU:
+ unsigned_p = 1;
+ case LT:
+ compare_dir = 1;
+ break;
+ case GTU:
+ unsigned_p = 1;
+ case GT:
+ compare_dir = -1;
+ case NE:
+ compare_dir = 0;
+ break;
+ default:
+ abort ();
+ }
+
/* If the comparison value is an invariant register, then try to find
its value from the insns before the start of the loop. */
+ final_value = comparison_value;
if (GET_CODE (comparison_value) == REG && invariant_p (comparison_value))
{
- rtx insn, set;
-
- for (insn = PREV_INSN (loop_start); insn ; insn = PREV_INSN (insn))
+ final_value = loop_find_equiv_value (loop_start, comparison_value);
+ /* If we don't get an invariant final value, we are better
+ off with the original register. */
+ if (!invariant_p (final_value))
+ final_value = comparison_value;
+ }
+
+ /* Calculate the approximate final value of the induction variable
+ (on the last successful iteration). The exact final value
+ depends on the branch operator, and increment sign. It will be
+ wrong if the iteration variable is not incremented by one each
+ time through the loop and (comparison_value + off_by_one -
+ initial_value) % increment != 0.
+ ??? Note that the final_value may overflow and thus final_larger
+ will be bogus. A potentially infinite loop will be classified
+ as immediate, e.g. for (i = 0x7ffffff0; i <= 0x7fffffff; i++) */
+ if (off_by_one)
+ final_value = plus_constant (final_value, off_by_one);
+
+ /* Save the calculated values describing this loop's bounds, in case
+ precondition_loop_p will need them later. These values can not be
+ recalculated inside precondition_loop_p because strength reduction
+ optimizations may obscure the loop's structure.
+
+ These values are only required by precondition_loop_p and insert_bct
+ whenever the number of iterations cannot be computed at compile time.
+ Only the difference between final_value and initial_value is
+ important. Note that final_value is only approximate. */
+ loop_info->initial_value = initial_value;
+ loop_info->comparison_value = comparison_value;
+ loop_info->final_value = plus_constant (comparison_value, off_by_one);
+ loop_info->increment = increment;
+ loop_info->iteration_var = iteration_var;
+ loop_info->comparison_code = comparison_code;
+
+ /* Try to determine the iteration count for loops such
+ as (for i = init; i < init + const; i++). When running the
+ loop optimization twice, the first pass often converts simple
+ loops into this form. */
+
+ if (REG_P (initial_value))
+ {
+ rtx reg1;
+ rtx reg2;
+ rtx const2;
+
+ reg1 = initial_value;
+ if (GET_CODE (final_value) == PLUS)
+ reg2 = XEXP (final_value, 0), const2 = XEXP (final_value, 1);
+ else
+ reg2 = final_value, const2 = const0_rtx;
+
+ /* Check for initial_value = reg1, final_value = reg2 + const2,
+ where reg1 != reg2. */
+ if (REG_P (reg2) && reg2 != reg1)
{
- if (GET_CODE (insn) == CODE_LABEL)
- break;
+ rtx temp;
- else if (GET_RTX_CLASS (GET_CODE (insn)) == 'i'
- && reg_set_p (comparison_value, insn))
+ /* Find what reg1 is equivalent to. Hopefully it will
+ either be reg2 or reg2 plus a constant. */
+ temp = loop_find_equiv_value (loop_start, reg1);
+ if (find_common_reg_term (temp, reg2))
+ initial_value = temp;
+ else
{
- /* We found the last insn before the loop that sets the register.
- If it sets the entire register, and has a REG_EQUAL note,
- then use the value of the REG_EQUAL note. */
- if ((set = single_set (insn))
- && (SET_DEST (set) == comparison_value))
- {
- rtx note = find_reg_note (insn, REG_EQUAL, NULL_RTX);
-
- /* Only use the REG_EQUAL note if it is a constant.
- Other things, divide in particular, will cause
- problems later if we use them. */
- if (note && GET_CODE (XEXP (note, 0)) != EXPR_LIST
- && CONSTANT_P (XEXP (note, 0)))
- comparison_value = XEXP (note, 0);
- }
- break;
+ /* Find what reg2 is equivalent to. Hopefully it will
+ either be reg1 or reg1 plus a constant. Let's ignore
+ the latter case for now since it is not so common. */
+ temp = loop_find_equiv_value (loop_start, reg2);
+ if (temp == loop_info->iteration_var)
+ temp = initial_value;
+ if (temp == reg1)
+ final_value = (const2 == const0_rtx)
+ ? reg1 : gen_rtx_PLUS (GET_MODE (reg1), reg1, const2);
+ }
+ }
+ else if (loop_info->vtop && GET_CODE (reg2) == CONST_INT)
+ {
+ rtx temp;
+
+ /* When running the loop optimizer twice, check_dbra_loop
+ further obfuscates reversible loops of the form:
+ for (i = init; i < init + const; i++). We often end up with
+ final_value = 0, initial_value = temp, temp = temp2 - init,
+ where temp2 = init + const. If the loop has a vtop we
+ can replace initial_value with const. */
+
+ temp = loop_find_equiv_value (loop_start, reg1);
+ if (GET_CODE (temp) == MINUS && REG_P (XEXP (temp, 0)))
+ {
+ rtx temp2 = loop_find_equiv_value (loop_start, XEXP (temp, 0));
+ if (GET_CODE (temp2) == PLUS
+ && XEXP (temp2, 0) == XEXP (temp, 1))
+ initial_value = XEXP (temp2, 1);
}
}
}
- final_value = approx_final_value (comparison_code, comparison_value,
- &unsigned_compare, &compare_dir);
+ /* If have initial_value = reg + const1 and final_value = reg +
+ const2, then replace initial_value with const1 and final_value
+ with const2. This should be safe since we are protected by the
+ initial comparison before entering the loop if we have a vtop.
+ For example, a + b < a + c is not equivalent to b < c for all a
+ when using modulo arithmetic.
- /* Save the calculated values describing this loop's bounds, in case
- precondition_loop_p will need them later. These values can not be
- recalculated inside precondition_loop_p because strength reduction
- optimizations may obscure the loop's structure. */
+ ??? Without a vtop we could still perform the optimization if we check
+ the initial and final values carefully. */
+ if (loop_info->vtop
+ && (reg_term = find_common_reg_term (initial_value, final_value)))
+ {
+ initial_value = subtract_reg_term (initial_value, reg_term);
+ final_value = subtract_reg_term (final_value, reg_term);
+ }
+
+ loop_info->initial_equiv_value = initial_value;
+ loop_info->final_equiv_value = final_value;
- loop_iteration_var = iteration_var;
- loop_initial_value = initial_value;
- loop_increment = increment;
- loop_final_value = final_value;
- loop_comparison_code = comparison_code;
+ /* For EQ comparison loops, we don't have a valid final value.
+ Check this now so that we won't leave an invalid value if we
+ return early for any other reason. */
+ if (comparison_code == EQ)
+ loop_info->final_equiv_value = loop_info->final_value = 0;
if (increment == 0)
{
if (loop_dump_stream)
fprintf (loop_dump_stream,
- "Loop unrolling: Increment value can't be calculated.\n");
+ "Loop iterations: Increment value can't be calculated.\n");
return 0;
}
- else if (GET_CODE (increment) != CONST_INT)
+
+ if (GET_CODE (increment) != CONST_INT)
{
- if (loop_dump_stream)
- fprintf (loop_dump_stream,
- "Loop unrolling: Increment value not constant.\n");
- return 0;
+ /* If we have a REG, check to see if REG holds a constant value. */
+ /* ??? Other RTL, such as (neg (reg)) is possible here, but it isn't
+ clear if it is worthwhile to try to handle such RTL. */
+ if (GET_CODE (increment) == REG || GET_CODE (increment) == SUBREG)
+ increment = loop_find_equiv_value (loop_start, increment);
+
+ if (GET_CODE (increment) != CONST_INT)
+ {
+ if (loop_dump_stream)
+ {
+ fprintf (loop_dump_stream,
+ "Loop iterations: Increment value not constant ");
+ print_rtl (loop_dump_stream, increment);
+ fprintf (loop_dump_stream, ".\n");
+ }
+ return 0;
+ }
+ loop_info->increment = increment;
}
- else if (GET_CODE (initial_value) != CONST_INT)
+
+ if (GET_CODE (initial_value) != CONST_INT)
{
if (loop_dump_stream)
- fprintf (loop_dump_stream,
- "Loop unrolling: Initial value not constant.\n");
+ {
+ fprintf (loop_dump_stream,
+ "Loop iterations: Initial value not constant ");
+ print_rtl (loop_dump_stream, initial_value);
+ fprintf (loop_dump_stream, ".\n");
+ }
return 0;
}
- else if (final_value == 0)
+ else if (comparison_code == EQ)
{
if (loop_dump_stream)
fprintf (loop_dump_stream,
- "Loop unrolling: EQ comparison loop.\n");
+ "Loop iterations: EQ comparison loop.\n");
return 0;
}
else if (GET_CODE (final_value) != CONST_INT)
{
if (loop_dump_stream)
- fprintf (loop_dump_stream,
- "Loop unrolling: Final value not constant.\n");
+ {
+ fprintf (loop_dump_stream,
+ "Loop iterations: Final value not constant ");
+ print_rtl (loop_dump_stream, final_value);
+ fprintf (loop_dump_stream, ".\n");
+ }
return 0;
}
- /* ?? Final value and initial value do not have to be constants.
- Only their difference has to be constant. When the iteration variable
- is an array address, the final value and initial value might both
- be addresses with the same base but different constant offsets.
- Final value must be invariant for this to work.
-
- To do this, need some way to find the values of registers which are
- invariant. */
-
/* Final_larger is 1 if final larger, 0 if they are equal, otherwise -1. */
- if (unsigned_compare)
+ if (unsigned_p)
final_larger
= ((unsigned HOST_WIDE_INT) INTVAL (final_value)
> (unsigned HOST_WIDE_INT) INTVAL (initial_value))
@@ -3590,7 +3911,7 @@ loop_iterations (loop_start, loop_end)
will overflow before the loop exits), 4 infinite loop cases, and 15
immediate exit (0 or 1 iteration depending on loop type) cases.
Only try to optimize the normal cases. */
-
+
/* (compare_dir/final_larger/increment_dir)
Normal cases: (0/-1/-1), (0/1/1), (-1/-1/-1), (1/1/1)
Reverse cases: (0/-1/1), (0/1/-1), (-1/-1/1), (1/1/-1)
@@ -3619,35 +3940,40 @@ loop_iterations (loop_start, loop_end)
{
if (loop_dump_stream)
fprintf (loop_dump_stream,
- "Loop unrolling: Not normal loop.\n");
+ "Loop iterations: Not normal loop.\n");
return 0;
}
/* Calculate the number of iterations, final_value is only an approximation,
- so correct for that. Note that tempu and loop_n_iterations are
+ so correct for that. Note that abs_diff and n_iterations are
unsigned, because they can be as large as 2^n - 1. */
- i = INTVAL (increment);
- if (i > 0)
- tempu = INTVAL (final_value) - INTVAL (initial_value);
- else if (i < 0)
+ abs_inc = INTVAL (increment);
+ if (abs_inc > 0)
+ abs_diff = INTVAL (final_value) - INTVAL (initial_value);
+ else if (abs_inc < 0)
{
- tempu = INTVAL (initial_value) - INTVAL (final_value);
- i = -i;
+ abs_diff = INTVAL (initial_value) - INTVAL (final_value);
+ abs_inc = -abs_inc;
}
else
abort ();
- /* For NE tests, make sure that the iteration variable won't miss the
- final value. If tempu mod i is not zero, then the iteration variable
- will overflow before the loop exits, and we can not calculate the
- number of iterations. */
- if (compare_dir == 0 && (tempu % i) != 0)
+ /* For NE tests, make sure that the iteration variable won't miss
+ the final value. If abs_diff mod abs_incr is not zero, then the
+ iteration variable will overflow before the loop exits, and we
+ can not calculate the number of iterations. */
+ if (compare_dir == 0 && (abs_diff % abs_inc) != 0)
return 0;
- return tempu / i + ((tempu % i) != 0);
+ /* Note that the number of iterations could be calculated using
+ (abs_diff + abs_inc - 1) / abs_inc, provided care was taken to
+ handle potential overflow of the summation. */
+ loop_info->n_iterations = abs_diff / abs_inc + ((abs_diff % abs_inc) != 0);
+ return loop_info->n_iterations;
}
+
/* Replace uses of split bivs with their split pseudo register. This is
for original instructions which remain after loop unrolling without
copying. */
@@ -3682,10 +4008,10 @@ remap_split_bivs (x)
have to remap those givs also. */
#endif
if (REGNO (x) < max_reg_before_loop
- && reg_iv_type[REGNO (x)] == BASIC_INDUCT)
+ && REG_IV_TYPE (REGNO (x)) == BASIC_INDUCT)
return reg_biv_class[REGNO (x)]->biv->src_reg;
break;
-
+
default:
break;
}
diff --git a/gcc/varasm.c b/gcc/varasm.c
index 18628bbf3c1..d7c9d4a6a18 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -1,5 +1,5 @@
/* Output variables, constants and external declarations, for GNU compiler.
- Copyright (C) 1987, 88, 89, 92-97, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1987, 88, 89, 92-98, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -164,7 +164,7 @@ tree last_assemble_variable_decl;
static int function_defined;
-static char *strip_reg_name PROTO((char *));
+static const char *strip_reg_name PROTO((const char *));
static int contains_pointers_p PROTO((tree));
static void decode_addr_const PROTO((tree, struct addr_const *));
static int const_hash PROTO((tree));
@@ -255,6 +255,15 @@ data_section ()
in_section = in_data;
}
}
+/* Tell assembler to ALWAYS switch to data section, in case
+ it's not sure where it it. */
+
+void
+force_data_section ()
+{
+ in_section = no_section;
+ data_section ();
+}
/* Tell assembler to switch to read-only data section. This is normally
the text section. */
@@ -293,8 +302,8 @@ in_data_section ()
void
named_section (decl, name, reloc)
tree decl;
- char *name;
- int reloc;
+ const char *name;
+ int reloc ATTRIBUTE_UNUSED;
{
if (decl != NULL_TREE
&& TREE_CODE_CLASS (TREE_CODE (decl)) != 'd')
@@ -579,9 +588,9 @@ make_function_rtl (decl)
/* Given NAME, a putative register name, discard any customary prefixes. */
-static char *
+static const char *
strip_reg_name (name)
- char *name;
+ const char *name;
{
#ifdef REGISTER_PREFIX
if (!strncmp (name, REGISTER_PREFIX, strlen (REGISTER_PREFIX)))
@@ -602,7 +611,7 @@ strip_reg_name (name)
int
decode_reg_name (asmspec)
- char *asmspec;
+ const char *asmspec;
{
if (asmspec != 0)
{
@@ -631,10 +640,10 @@ decode_reg_name (asmspec)
#ifdef ADDITIONAL_REGISTER_NAMES
{
- static struct { char *name; int number; } table[]
+ static struct { const char *name; int number; } table[]
= ADDITIONAL_REGISTER_NAMES;
- for (i = 0; i < sizeof (table) / sizeof (table[0]); i++)
+ for (i = 0; i < (int)(sizeof (table) / sizeof (table[0])); i++)
if (! strcmp (asmspec, table[i].name))
return table[i].number;
}
@@ -663,7 +672,7 @@ decode_reg_name (asmspec)
void
make_decl_rtl (decl, asmspec, top_level)
tree decl;
- char *asmspec;
+ const char *asmspec;
int top_level;
{
register char *name = 0;
@@ -799,13 +808,17 @@ make_decl_rtl (decl, asmspec, top_level)
if (flag_volatile_global && TREE_CODE (decl) == VAR_DECL
&& TREE_PUBLIC (decl))
TREE_SIDE_EFFECTS (decl) = 1;
+ else if (flag_volatile_static && TREE_CODE (decl) == VAR_DECL
+ && (TREE_PUBLIC (decl) || TREE_STATIC (decl)))
+ TREE_SIDE_EFFECTS (decl) = 1;
+
if (TREE_SIDE_EFFECTS (decl))
MEM_VOLATILE_P (DECL_RTL (decl)) = 1;
if (TREE_READONLY (decl))
RTX_UNCHANGING_P (DECL_RTL (decl)) = 1;
- MEM_IN_STRUCT_P (DECL_RTL (decl))
- = AGGREGATE_TYPE_P (TREE_TYPE (decl));
+ MEM_SET_IN_STRUCT_P (DECL_RTL (decl),
+ AGGREGATE_TYPE_P (TREE_TYPE (decl)));
/* Optionally set flags or add text to the name to record information
such as that it is a function name.
@@ -1044,11 +1057,12 @@ assemble_start_function (decl, fnname)
strcpy (*name, p);
}
- ASM_GLOBALIZE_LABEL (asm_out_file, fnname);
#ifdef ASM_WEAKEN_LABEL
if (DECL_WEAK (decl))
ASM_WEAKEN_LABEL (asm_out_file, fnname);
+ else
#endif
+ ASM_GLOBALIZE_LABEL (asm_out_file, fnname);
}
/* Do any machine/system dependent processing of the function name */
@@ -1087,6 +1101,10 @@ void
assemble_zeros (size)
int size;
{
+ /* Do no output if -fsyntax-only. */
+ if (flag_syntax_only)
+ return;
+
#ifdef ASM_NO_SKIP_IN_TEXT
/* The `space' pseudo in the text section outputs nop insns rather than 0s,
so we must output 0s explicitly in the text section. */
@@ -1137,7 +1155,7 @@ assemble_align (align)
void
assemble_string (p, size)
- char *p;
+ const char *p;
int size;
{
int pos = 0;
@@ -1172,7 +1190,7 @@ assemble_string (p, size)
void
assemble_variable (decl, top_level, at_end, dont_output_data)
tree decl;
- int top_level;
+ int top_level ATTRIBUTE_UNUSED;
int at_end;
int dont_output_data;
{
@@ -1193,6 +1211,10 @@ assemble_variable (decl, top_level, at_end, dont_output_data)
return;
TREE_ASM_WRITTEN (decl) = 1;
+ /* Do no output if -fsyntax-only. */
+ if (flag_syntax_only)
+ return;
+
#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
/* File-scope global variables are output here. */
if ((write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
@@ -1260,6 +1282,10 @@ assemble_variable (decl, top_level, at_end, dont_output_data)
TREE_ASM_WRITTEN (decl) = 1;
+ /* Do no output if -fsyntax-only. */
+ if (flag_syntax_only)
+ return;
+
app_disable ();
if (! dont_output_data)
@@ -1343,6 +1369,7 @@ assemble_variable (decl, top_level, at_end, dont_output_data)
#if ! defined (ASM_OUTPUT_BSS) && ! defined (ASM_OUTPUT_ALIGNED_BSS)
&& DECL_COMMON (decl)
#endif
+ && DECL_SECTION_NAME (decl) == 0
&& ! dont_output_data)
{
int size = TREE_INT_CST_LOW (size_tree);
@@ -1464,11 +1491,12 @@ assemble_variable (decl, top_level, at_end, dont_output_data)
/* First make the assembler name(s) global if appropriate. */
if (TREE_PUBLIC (decl) && DECL_NAME (decl))
{
- ASM_GLOBALIZE_LABEL (asm_out_file, name);
#ifdef ASM_WEAKEN_LABEL
if (DECL_WEAK (decl))
ASM_WEAKEN_LABEL (asm_out_file, name);
+ else
#endif
+ ASM_GLOBALIZE_LABEL (asm_out_file, name);
}
#if 0
for (d = equivalents; d; d = TREE_CHAIN (d))
@@ -1622,7 +1650,7 @@ contains_pointers_p (type)
void
assemble_external (decl)
- tree decl;
+ tree decl ATTRIBUTE_UNUSED;
{
#ifdef ASM_OUTPUT_EXTERNAL
if (TREE_CODE_CLASS (TREE_CODE (decl)) == 'd'
@@ -1645,7 +1673,7 @@ assemble_external (decl)
void
assemble_external_libcall (fun)
- rtx fun;
+ rtx fun ATTRIBUTE_UNUSED;
{
#ifdef ASM_OUTPUT_EXTERNAL_LIBCALL
/* Declare library function name external when first used, if nec. */
@@ -1739,9 +1767,11 @@ assemble_static_space (size)
{
/* Round size up to multiple of BIGGEST_ALIGNMENT bits
so that each uninitialized object starts on such a boundary. */
- int rounded = ((size + (BIGGEST_ALIGNMENT / BITS_PER_UNIT) - 1)
- / (BIGGEST_ALIGNMENT / BITS_PER_UNIT)
- * (BIGGEST_ALIGNMENT / BITS_PER_UNIT));
+ /* Variable `rounded' might or might not be used in ASM_OUTPUT_LOCAL. */
+ int rounded ATTRIBUTE_UNUSED
+ = ((size + (BIGGEST_ALIGNMENT / BITS_PER_UNIT) - 1)
+ / (BIGGEST_ALIGNMENT / BITS_PER_UNIT)
+ * (BIGGEST_ALIGNMENT / BITS_PER_UNIT));
ASM_OUTPUT_LOCAL (asm_out_file, name, size, rounded);
}
#endif
@@ -2954,7 +2984,7 @@ output_constant_def (exp)
= gen_rtx_MEM (TYPE_MODE (TREE_TYPE (exp)), def);
RTX_UNCHANGING_P (TREE_CST_RTL (exp)) = 1;
if (AGGREGATE_TYPE_P (TREE_TYPE (exp)))
- MEM_IN_STRUCT_P (TREE_CST_RTL (exp)) = 1;
+ MEM_SET_IN_STRUCT_P (TREE_CST_RTL (exp), 1);
pop_obstacks ();
@@ -3000,7 +3030,12 @@ output_constant_def (exp)
}
}
else
- output_constant_def_contents (exp, reloc, const_labelno++);
+ {
+ /* Do no output if -fsyntax-only. */
+ if (! flag_syntax_only)
+ output_constant_def_contents (exp, reloc, const_labelno);
+ ++const_labelno;
+ }
}
return TREE_CST_RTL (exp);
@@ -3569,8 +3604,8 @@ get_pool_size ()
void
output_constant_pool (fnname, fndecl)
- char *fnname;
- tree fndecl;
+ char *fnname ATTRIBUTE_UNUSED;
+ tree fndecl ATTRIBUTE_UNUSED;
{
struct pool_constant *pool;
rtx x;
@@ -3620,7 +3655,7 @@ output_constant_pool (fnname, fndecl)
#endif
if (pool->align > 1)
- ASM_OUTPUT_ALIGN (asm_out_file, exact_log2 (pool->align));
+ ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (pool->align));
/* Output the label. */
ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "LC", pool->labelno);
@@ -3976,7 +4011,11 @@ output_constructor (exp, size)
FIELD goes through the structure fields, if the constant is a structure.
if the constant is a union, then we override this,
by getting the field from the TREE_LIST element.
- But the constant could also be an array. Then FIELD is zero. */
+ But the constant could also be an array. Then FIELD is zero.
+
+ There is always a maximum of one element in the chain LINK for unions
+ (even if the initializer in a source program incorrectly contains
+ more one). */
for (link = CONSTRUCTOR_ELTS (exp);
link;
link = TREE_CHAIN (link),
@@ -4226,6 +4265,31 @@ output_constructor (exp, size)
assemble_zeros (size - total_bytes);
}
+#ifdef HANDLE_PRAGMA_WEAK
+/* Add function NAME to the weak symbols list. VALUE is a weak alias
+ associatd with NAME. */
+
+int
+add_weak (name, value)
+ char *name;
+ char *value;
+{
+ struct weak_syms *weak;
+
+ weak = (struct weak_syms *) permalloc (sizeof (struct weak_syms));
+
+ if (weak == NULL)
+ return 0;
+
+ weak->next = weak_decls;
+ weak->name = name;
+ weak->value = value;
+ weak_decls = weak;
+
+ return 1;
+}
+#endif /* HANDLE_PRAGMA_WEAK */
+
/* Declare DECL to be a weak symbol. */
void
@@ -4238,6 +4302,9 @@ declare_weak (decl)
error_with_decl (decl, "weak declaration of `%s' must precede definition");
else if (SUPPORTS_WEAK)
DECL_WEAK (decl) = 1;
+#ifdef HANDLE_PRAGMA_WEAK
+ add_weak (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)), NULL);
+#endif
}
/* Emit any pending weak declarations. */
@@ -4255,7 +4322,6 @@ weak_finish ()
struct weak_syms *t;
for (t = weak_decls; t; t = t->next)
{
- ASM_GLOBALIZE_LABEL (asm_out_file, t->name);
ASM_WEAKEN_LABEL (asm_out_file, t->name);
if (t->value)
ASM_OUTPUT_DEF (asm_out_file, t->name, t->value);
@@ -4266,7 +4332,7 @@ weak_finish ()
void
assemble_alias (decl, target)
- tree decl, target;
+ tree decl, target ATTRIBUTE_UNUSED;
{
char *name;
@@ -4278,11 +4344,12 @@ assemble_alias (decl, target)
if (TREE_PUBLIC (decl))
{
- ASM_GLOBALIZE_LABEL (asm_out_file, name);
#ifdef ASM_WEAKEN_LABEL
if (DECL_WEAK (decl))
ASM_WEAKEN_LABEL (asm_out_file, name);
+ else
#endif
+ ASM_GLOBALIZE_LABEL (asm_out_file, name);
}
ASM_OUTPUT_DEF (asm_out_file, name, IDENTIFIER_POINTER (target));
diff --git a/gcc/varray.h b/gcc/varray.h
index eb5a44e1a8b..7d4f6972f26 100644
--- a/gcc/varray.h
+++ b/gcc/varray.h
@@ -22,10 +22,6 @@
#ifndef _VARRAY_H_
#define _VARRAY_H_
-#ifndef PROTO
-#include "gansidecl.h"
-#endif
-
#ifndef HOST_WIDE_INT
#include "machmode.h"
#endif
@@ -34,6 +30,30 @@
#include "system.h"
#endif
+/* Auxiliary structure used inside the varray structure, used for
+ function integration data. */
+
+struct const_equiv_data {
+ /* Map pseudo reg number in calling function to equivalent constant. We
+ cannot in general substitute constants into parameter pseudo registers,
+ since some machine descriptions (many RISCs) won't always handle
+ the resulting insns. So if an incoming parameter has a constant
+ equivalent, we record it here, and if the resulting insn is
+ recognizable, we go with it.
+
+ We also use this mechanism to convert references to incoming arguments
+ and stacked variables. copy_rtx_and_substitute will replace the virtual
+ incoming argument and virtual stacked variables registers with new
+ pseudos that contain pointers into the replacement area allocated for
+ this inline instance. These pseudos are then marked as being equivalent
+ to the appropriate address and substituted if valid. */
+ rtx rtx;
+
+ /* Record the valid age for each entry. The entry is invalid if its
+ age is less than const_age. */
+ unsigned age;
+};
+
/* Union of various array types that are used. */
typedef union varray_data_tag {
char c[1];
@@ -54,6 +74,8 @@ typedef union varray_data_tag {
struct bitmap_head_def *bitmap[1];
struct sched_info_tag *sched[1];
struct reg_info_def *reg[1];
+ struct const_equiv_data const_equiv[1];
+ struct basic_block_def *bb[1];
} varray_data;
/* Virtual array of pointers header. */
@@ -122,6 +144,12 @@ extern varray_type varray_init PROTO ((size_t, size_t, const char *));
#define VARRAY_REG_INIT(va, num, name) \
va = varray_init (num, sizeof (struct reg_info_def *), name)
+#define VARRAY_CONST_EQUIV_INIT(va, num, name) \
+ va = varray_init (num, sizeof (struct const_equiv_data), name)
+
+#define VARRAY_BB_INIT(va, num, name) \
+ va = varray_init (num, sizeof (struct basic_block_def *), name)
+
/* Free up memory allocated by the virtual array, but do not free any of the
elements involved. */
#define VARRAY_FREE(vp) \
@@ -132,6 +160,8 @@ extern varray_type varray_grow PROTO((varray_type, size_t));
#define VARRAY_GROW(VA, N) ((VA) = varray_grow (VA, N))
+#define VARRAY_SIZE(VA) ((VA)->num_elements)
+
/* Check for VARRAY_xxx macros being in bound, return N for use as an
index. */
#ifdef ENABLE_CHECKING
@@ -163,5 +193,7 @@ extern varray_type varray_grow PROTO((varray_type, size_t));
#define VARRAY_BITMAP(VA, N) ((VA)->data.bitmap[ VARRAY_CHECK (VA, N) ])
#define VARRAY_SCHED(VA, N) ((VA)->data.sched[ VARRAY_CHECK (VA, N) ])
#define VARRAY_REG(VA, N) ((VA)->data.reg[ VARRAY_CHECK (VA, N) ])
+#define VARRAY_CONST_EQUIV(VA, N) ((VA)->data.const_equiv[VARRAY_CHECK (VA, N)])
+#define VARRAY_BB(VA, N) ((VA)->data.bb[ VARRAY_CHECK (VA, N) ])
#endif /* _VARRAY_H_ */
diff --git a/gcc/version.c b/gcc/version.c
index c2623f48c36..c5c1a4ca77e 100644
--- a/gcc/version.c
+++ b/gcc/version.c
@@ -1 +1 @@
-char *version_string = "egcs-2.92.13 19981007 (gcc2 ss-980609 experimental)";
+char *version_string = "egcs-2.93.13 19990327 (gcc2 ss-980929 experimental)";
diff --git a/gcc/xcoffout.c b/gcc/xcoffout.c
index baa0cd2ed01..4da507979ba 100644
--- a/gcc/xcoffout.c
+++ b/gcc/xcoffout.c
@@ -1,5 +1,5 @@
/* Output xcoff-format symbol table information from GNU compiler.
- Copyright (C) 1992, 1994, 1995, 1997 Free Software Foundation, Inc.
+ Copyright (C) 1992, 1994, 1995, 1997, 1998 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -177,7 +177,7 @@ xcoff_output_standard_types (syms)
#define UNKNOWN_STAB(STR) \
do { \
- fprintf(stderr, "Error, unknown stab %s: : 0x%x\n", STR, stab); \
+ error ("Unknown stab %s: : 0x%x\n", STR, stab); \
fflush (stderr); \
} while (0)
diff --git a/gcc/xcoffout.h b/gcc/xcoffout.h
index 2781a790324..1683a88413c 100644
--- a/gcc/xcoffout.h
+++ b/gcc/xcoffout.h
@@ -1,5 +1,24 @@
/* XCOFF definitions. These are needed in dbxout.c, final.c,
- and xcoffout.h. */
+ and xcoffout.h.
+ Copyright (C) 1998 Free Software Foundation, Inc.
+
+This file is part of GNU CC.
+
+GNU CC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU CC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
#define ASM_STABS_OP ".stabx"