aboutsummaryrefslogtreecommitdiff
path: root/gcc/except.c
diff options
context:
space:
mode:
authorMartin Liska <mliska@suse.cz>2022-01-14 16:56:44 +0100
committerMartin Liska <mliska@suse.cz>2022-01-17 22:12:04 +0100
commit5c69acb32329d49e58c26fa41ae74229a52b9106 (patch)
treeddb05f9d73afb6f998457d2ac4b720e3b3b60483 /gcc/except.c
parent490e23032baaece71f2ec09fa1805064b150fbc2 (diff)
downloadgcc-5c69acb32329d49e58c26fa41ae74229a52b9106.zip
gcc-5c69acb32329d49e58c26fa41ae74229a52b9106.tar.gz
gcc-5c69acb32329d49e58c26fa41ae74229a52b9106.tar.bz2
Rename .c files to .cc files.
gcc/ada/ChangeLog: * adadecode.c: Moved to... * adadecode.cc: ...here. * affinity.c: Moved to... * affinity.cc: ...here. * argv-lynxos178-raven-cert.c: Moved to... * argv-lynxos178-raven-cert.cc: ...here. * argv.c: Moved to... * argv.cc: ...here. * aux-io.c: Moved to... * aux-io.cc: ...here. * cio.c: Moved to... * cio.cc: ...here. * cstreams.c: Moved to... * cstreams.cc: ...here. * env.c: Moved to... * env.cc: ...here. * exit.c: Moved to... * exit.cc: ...here. * expect.c: Moved to... * expect.cc: ...here. * final.c: Moved to... * final.cc: ...here. * gcc-interface/cuintp.c: Moved to... * gcc-interface/cuintp.cc: ...here. * gcc-interface/decl.c: Moved to... * gcc-interface/decl.cc: ...here. * gcc-interface/misc.c: Moved to... * gcc-interface/misc.cc: ...here. * gcc-interface/targtyps.c: Moved to... * gcc-interface/targtyps.cc: ...here. * gcc-interface/trans.c: Moved to... * gcc-interface/trans.cc: ...here. * gcc-interface/utils.c: Moved to... * gcc-interface/utils.cc: ...here. * gcc-interface/utils2.c: Moved to... * gcc-interface/utils2.cc: ...here. * init.c: Moved to... * init.cc: ...here. * initialize.c: Moved to... * initialize.cc: ...here. * libgnarl/thread.c: Moved to... * libgnarl/thread.cc: ...here. * link.c: Moved to... * link.cc: ...here. * locales.c: Moved to... * locales.cc: ...here. * mkdir.c: Moved to... * mkdir.cc: ...here. * raise.c: Moved to... * raise.cc: ...here. * rtfinal.c: Moved to... * rtfinal.cc: ...here. * rtinit.c: Moved to... * rtinit.cc: ...here. * seh_init.c: Moved to... * seh_init.cc: ...here. * sigtramp-armdroid.c: Moved to... * sigtramp-armdroid.cc: ...here. * sigtramp-ios.c: Moved to... * sigtramp-ios.cc: ...here. * sigtramp-qnx.c: Moved to... * sigtramp-qnx.cc: ...here. * sigtramp-vxworks.c: Moved to... * sigtramp-vxworks.cc: ...here. * socket.c: Moved to... * socket.cc: ...here. * tracebak.c: Moved to... * tracebak.cc: ...here. * version.c: Moved to... * version.cc: ...here. * vx_stack_info.c: Moved to... * vx_stack_info.cc: ...here. gcc/ChangeLog: * adjust-alignment.c: Moved to... * adjust-alignment.cc: ...here. * alias.c: Moved to... * alias.cc: ...here. * alloc-pool.c: Moved to... * alloc-pool.cc: ...here. * asan.c: Moved to... * asan.cc: ...here. * attribs.c: Moved to... * attribs.cc: ...here. * auto-inc-dec.c: Moved to... * auto-inc-dec.cc: ...here. * auto-profile.c: Moved to... * auto-profile.cc: ...here. * bb-reorder.c: Moved to... * bb-reorder.cc: ...here. * bitmap.c: Moved to... * bitmap.cc: ...here. * btfout.c: Moved to... * btfout.cc: ...here. * builtins.c: Moved to... * builtins.cc: ...here. * caller-save.c: Moved to... * caller-save.cc: ...here. * calls.c: Moved to... * calls.cc: ...here. * ccmp.c: Moved to... * ccmp.cc: ...here. * cfg.c: Moved to... * cfg.cc: ...here. * cfganal.c: Moved to... * cfganal.cc: ...here. * cfgbuild.c: Moved to... * cfgbuild.cc: ...here. * cfgcleanup.c: Moved to... * cfgcleanup.cc: ...here. * cfgexpand.c: Moved to... * cfgexpand.cc: ...here. * cfghooks.c: Moved to... * cfghooks.cc: ...here. * cfgloop.c: Moved to... * cfgloop.cc: ...here. * cfgloopanal.c: Moved to... * cfgloopanal.cc: ...here. * cfgloopmanip.c: Moved to... * cfgloopmanip.cc: ...here. * cfgrtl.c: Moved to... * cfgrtl.cc: ...here. * cgraph.c: Moved to... * cgraph.cc: ...here. * cgraphbuild.c: Moved to... * cgraphbuild.cc: ...here. * cgraphclones.c: Moved to... * cgraphclones.cc: ...here. * cgraphunit.c: Moved to... * cgraphunit.cc: ...here. * collect-utils.c: Moved to... * collect-utils.cc: ...here. * collect2-aix.c: Moved to... * collect2-aix.cc: ...here. * collect2.c: Moved to... * collect2.cc: ...here. * combine-stack-adj.c: Moved to... * combine-stack-adj.cc: ...here. * combine.c: Moved to... * combine.cc: ...here. * common/common-targhooks.c: Moved to... * common/common-targhooks.cc: ...here. * common/config/aarch64/aarch64-common.c: Moved to... * common/config/aarch64/aarch64-common.cc: ...here. * common/config/alpha/alpha-common.c: Moved to... * common/config/alpha/alpha-common.cc: ...here. * common/config/arc/arc-common.c: Moved to... * common/config/arc/arc-common.cc: ...here. * common/config/arm/arm-common.c: Moved to... * common/config/arm/arm-common.cc: ...here. * common/config/avr/avr-common.c: Moved to... * common/config/avr/avr-common.cc: ...here. * common/config/bfin/bfin-common.c: Moved to... * common/config/bfin/bfin-common.cc: ...here. * common/config/bpf/bpf-common.c: Moved to... * common/config/bpf/bpf-common.cc: ...here. * common/config/c6x/c6x-common.c: Moved to... * common/config/c6x/c6x-common.cc: ...here. * common/config/cr16/cr16-common.c: Moved to... * common/config/cr16/cr16-common.cc: ...here. * common/config/cris/cris-common.c: Moved to... * common/config/cris/cris-common.cc: ...here. * common/config/csky/csky-common.c: Moved to... * common/config/csky/csky-common.cc: ...here. * common/config/default-common.c: Moved to... * common/config/default-common.cc: ...here. * common/config/epiphany/epiphany-common.c: Moved to... * common/config/epiphany/epiphany-common.cc: ...here. * common/config/fr30/fr30-common.c: Moved to... * common/config/fr30/fr30-common.cc: ...here. * common/config/frv/frv-common.c: Moved to... * common/config/frv/frv-common.cc: ...here. * common/config/gcn/gcn-common.c: Moved to... * common/config/gcn/gcn-common.cc: ...here. * common/config/h8300/h8300-common.c: Moved to... * common/config/h8300/h8300-common.cc: ...here. * common/config/i386/i386-common.c: Moved to... * common/config/i386/i386-common.cc: ...here. * common/config/ia64/ia64-common.c: Moved to... * common/config/ia64/ia64-common.cc: ...here. * common/config/iq2000/iq2000-common.c: Moved to... * common/config/iq2000/iq2000-common.cc: ...here. * common/config/lm32/lm32-common.c: Moved to... * common/config/lm32/lm32-common.cc: ...here. * common/config/m32r/m32r-common.c: Moved to... * common/config/m32r/m32r-common.cc: ...here. * common/config/m68k/m68k-common.c: Moved to... * common/config/m68k/m68k-common.cc: ...here. * common/config/mcore/mcore-common.c: Moved to... * common/config/mcore/mcore-common.cc: ...here. * common/config/microblaze/microblaze-common.c: Moved to... * common/config/microblaze/microblaze-common.cc: ...here. * common/config/mips/mips-common.c: Moved to... * common/config/mips/mips-common.cc: ...here. * common/config/mmix/mmix-common.c: Moved to... * common/config/mmix/mmix-common.cc: ...here. * common/config/mn10300/mn10300-common.c: Moved to... * common/config/mn10300/mn10300-common.cc: ...here. * common/config/msp430/msp430-common.c: Moved to... * common/config/msp430/msp430-common.cc: ...here. * common/config/nds32/nds32-common.c: Moved to... * common/config/nds32/nds32-common.cc: ...here. * common/config/nios2/nios2-common.c: Moved to... * common/config/nios2/nios2-common.cc: ...here. * common/config/nvptx/nvptx-common.c: Moved to... * common/config/nvptx/nvptx-common.cc: ...here. * common/config/or1k/or1k-common.c: Moved to... * common/config/or1k/or1k-common.cc: ...here. * common/config/pa/pa-common.c: Moved to... * common/config/pa/pa-common.cc: ...here. * common/config/pdp11/pdp11-common.c: Moved to... * common/config/pdp11/pdp11-common.cc: ...here. * common/config/pru/pru-common.c: Moved to... * common/config/pru/pru-common.cc: ...here. * common/config/riscv/riscv-common.c: Moved to... * common/config/riscv/riscv-common.cc: ...here. * common/config/rs6000/rs6000-common.c: Moved to... * common/config/rs6000/rs6000-common.cc: ...here. * common/config/rx/rx-common.c: Moved to... * common/config/rx/rx-common.cc: ...here. * common/config/s390/s390-common.c: Moved to... * common/config/s390/s390-common.cc: ...here. * common/config/sh/sh-common.c: Moved to... * common/config/sh/sh-common.cc: ...here. * common/config/sparc/sparc-common.c: Moved to... * common/config/sparc/sparc-common.cc: ...here. * common/config/tilegx/tilegx-common.c: Moved to... * common/config/tilegx/tilegx-common.cc: ...here. * common/config/tilepro/tilepro-common.c: Moved to... * common/config/tilepro/tilepro-common.cc: ...here. * common/config/v850/v850-common.c: Moved to... * common/config/v850/v850-common.cc: ...here. * common/config/vax/vax-common.c: Moved to... * common/config/vax/vax-common.cc: ...here. * common/config/visium/visium-common.c: Moved to... * common/config/visium/visium-common.cc: ...here. * common/config/xstormy16/xstormy16-common.c: Moved to... * common/config/xstormy16/xstormy16-common.cc: ...here. * common/config/xtensa/xtensa-common.c: Moved to... * common/config/xtensa/xtensa-common.cc: ...here. * compare-elim.c: Moved to... * compare-elim.cc: ...here. * config/aarch64/aarch64-bti-insert.c: Moved to... * config/aarch64/aarch64-bti-insert.cc: ...here. * config/aarch64/aarch64-builtins.c: Moved to... * config/aarch64/aarch64-builtins.cc: ...here. * config/aarch64/aarch64-c.c: Moved to... * config/aarch64/aarch64-c.cc: ...here. * config/aarch64/aarch64-d.c: Moved to... * config/aarch64/aarch64-d.cc: ...here. * config/aarch64/aarch64.c: Moved to... * config/aarch64/aarch64.cc: ...here. * config/aarch64/cortex-a57-fma-steering.c: Moved to... * config/aarch64/cortex-a57-fma-steering.cc: ...here. * config/aarch64/driver-aarch64.c: Moved to... * config/aarch64/driver-aarch64.cc: ...here. * config/aarch64/falkor-tag-collision-avoidance.c: Moved to... * config/aarch64/falkor-tag-collision-avoidance.cc: ...here. * config/aarch64/host-aarch64-darwin.c: Moved to... * config/aarch64/host-aarch64-darwin.cc: ...here. * config/alpha/alpha.c: Moved to... * config/alpha/alpha.cc: ...here. * config/alpha/driver-alpha.c: Moved to... * config/alpha/driver-alpha.cc: ...here. * config/arc/arc-c.c: Moved to... * config/arc/arc-c.cc: ...here. * config/arc/arc.c: Moved to... * config/arc/arc.cc: ...here. * config/arc/driver-arc.c: Moved to... * config/arc/driver-arc.cc: ...here. * config/arm/aarch-common.c: Moved to... * config/arm/aarch-common.cc: ...here. * config/arm/arm-builtins.c: Moved to... * config/arm/arm-builtins.cc: ...here. * config/arm/arm-c.c: Moved to... * config/arm/arm-c.cc: ...here. * config/arm/arm-d.c: Moved to... * config/arm/arm-d.cc: ...here. * config/arm/arm.c: Moved to... * config/arm/arm.cc: ...here. * config/arm/driver-arm.c: Moved to... * config/arm/driver-arm.cc: ...here. * config/avr/avr-c.c: Moved to... * config/avr/avr-c.cc: ...here. * config/avr/avr-devices.c: Moved to... * config/avr/avr-devices.cc: ...here. * config/avr/avr-log.c: Moved to... * config/avr/avr-log.cc: ...here. * config/avr/avr.c: Moved to... * config/avr/avr.cc: ...here. * config/avr/driver-avr.c: Moved to... * config/avr/driver-avr.cc: ...here. * config/avr/gen-avr-mmcu-specs.c: Moved to... * config/avr/gen-avr-mmcu-specs.cc: ...here. * config/avr/gen-avr-mmcu-texi.c: Moved to... * config/avr/gen-avr-mmcu-texi.cc: ...here. * config/bfin/bfin.c: Moved to... * config/bfin/bfin.cc: ...here. * config/bpf/bpf.c: Moved to... * config/bpf/bpf.cc: ...here. * config/bpf/coreout.c: Moved to... * config/bpf/coreout.cc: ...here. * config/c6x/c6x.c: Moved to... * config/c6x/c6x.cc: ...here. * config/cr16/cr16.c: Moved to... * config/cr16/cr16.cc: ...here. * config/cris/cris.c: Moved to... * config/cris/cris.cc: ...here. * config/csky/csky.c: Moved to... * config/csky/csky.cc: ...here. * config/darwin-c.c: Moved to... * config/darwin-c.cc: ...here. * config/darwin-d.c: Moved to... * config/darwin-d.cc: ...here. * config/darwin-driver.c: Moved to... * config/darwin-driver.cc: ...here. * config/darwin-f.c: Moved to... * config/darwin-f.cc: ...here. * config/darwin.c: Moved to... * config/darwin.cc: ...here. * config/default-c.c: Moved to... * config/default-c.cc: ...here. * config/default-d.c: Moved to... * config/default-d.cc: ...here. * config/dragonfly-d.c: Moved to... * config/dragonfly-d.cc: ...here. * config/epiphany/epiphany.c: Moved to... * config/epiphany/epiphany.cc: ...here. * config/epiphany/mode-switch-use.c: Moved to... * config/epiphany/mode-switch-use.cc: ...here. * config/epiphany/resolve-sw-modes.c: Moved to... * config/epiphany/resolve-sw-modes.cc: ...here. * config/fr30/fr30.c: Moved to... * config/fr30/fr30.cc: ...here. * config/freebsd-d.c: Moved to... * config/freebsd-d.cc: ...here. * config/frv/frv.c: Moved to... * config/frv/frv.cc: ...here. * config/ft32/ft32.c: Moved to... * config/ft32/ft32.cc: ...here. * config/gcn/driver-gcn.c: Moved to... * config/gcn/driver-gcn.cc: ...here. * config/gcn/gcn-run.c: Moved to... * config/gcn/gcn-run.cc: ...here. * config/gcn/gcn-tree.c: Moved to... * config/gcn/gcn-tree.cc: ...here. * config/gcn/gcn.c: Moved to... * config/gcn/gcn.cc: ...here. * config/gcn/mkoffload.c: Moved to... * config/gcn/mkoffload.cc: ...here. * config/glibc-c.c: Moved to... * config/glibc-c.cc: ...here. * config/glibc-d.c: Moved to... * config/glibc-d.cc: ...here. * config/h8300/h8300.c: Moved to... * config/h8300/h8300.cc: ...here. * config/host-darwin.c: Moved to... * config/host-darwin.cc: ...here. * config/host-hpux.c: Moved to... * config/host-hpux.cc: ...here. * config/host-linux.c: Moved to... * config/host-linux.cc: ...here. * config/host-netbsd.c: Moved to... * config/host-netbsd.cc: ...here. * config/host-openbsd.c: Moved to... * config/host-openbsd.cc: ...here. * config/host-solaris.c: Moved to... * config/host-solaris.cc: ...here. * config/i386/djgpp.c: Moved to... * config/i386/djgpp.cc: ...here. * config/i386/driver-i386.c: Moved to... * config/i386/driver-i386.cc: ...here. * config/i386/driver-mingw32.c: Moved to... * config/i386/driver-mingw32.cc: ...here. * config/i386/gnu-property.c: Moved to... * config/i386/gnu-property.cc: ...here. * config/i386/host-cygwin.c: Moved to... * config/i386/host-cygwin.cc: ...here. * config/i386/host-i386-darwin.c: Moved to... * config/i386/host-i386-darwin.cc: ...here. * config/i386/host-mingw32.c: Moved to... * config/i386/host-mingw32.cc: ...here. * config/i386/i386-builtins.c: Moved to... * config/i386/i386-builtins.cc: ...here. * config/i386/i386-c.c: Moved to... * config/i386/i386-c.cc: ...here. * config/i386/i386-d.c: Moved to... * config/i386/i386-d.cc: ...here. * config/i386/i386-expand.c: Moved to... * config/i386/i386-expand.cc: ...here. * config/i386/i386-features.c: Moved to... * config/i386/i386-features.cc: ...here. * config/i386/i386-options.c: Moved to... * config/i386/i386-options.cc: ...here. * config/i386/i386.c: Moved to... * config/i386/i386.cc: ...here. * config/i386/intelmic-mkoffload.c: Moved to... * config/i386/intelmic-mkoffload.cc: ...here. * config/i386/msformat-c.c: Moved to... * config/i386/msformat-c.cc: ...here. * config/i386/winnt-cxx.c: Moved to... * config/i386/winnt-cxx.cc: ...here. * config/i386/winnt-d.c: Moved to... * config/i386/winnt-d.cc: ...here. * config/i386/winnt-stubs.c: Moved to... * config/i386/winnt-stubs.cc: ...here. * config/i386/winnt.c: Moved to... * config/i386/winnt.cc: ...here. * config/i386/x86-tune-sched-atom.c: Moved to... * config/i386/x86-tune-sched-atom.cc: ...here. * config/i386/x86-tune-sched-bd.c: Moved to... * config/i386/x86-tune-sched-bd.cc: ...here. * config/i386/x86-tune-sched-core.c: Moved to... * config/i386/x86-tune-sched-core.cc: ...here. * config/i386/x86-tune-sched.c: Moved to... * config/i386/x86-tune-sched.cc: ...here. * config/ia64/ia64-c.c: Moved to... * config/ia64/ia64-c.cc: ...here. * config/ia64/ia64.c: Moved to... * config/ia64/ia64.cc: ...here. * config/iq2000/iq2000.c: Moved to... * config/iq2000/iq2000.cc: ...here. * config/linux.c: Moved to... * config/linux.cc: ...here. * config/lm32/lm32.c: Moved to... * config/lm32/lm32.cc: ...here. * config/m32c/m32c-pragma.c: Moved to... * config/m32c/m32c-pragma.cc: ...here. * config/m32c/m32c.c: Moved to... * config/m32c/m32c.cc: ...here. * config/m32r/m32r.c: Moved to... * config/m32r/m32r.cc: ...here. * config/m68k/m68k.c: Moved to... * config/m68k/m68k.cc: ...here. * config/mcore/mcore.c: Moved to... * config/mcore/mcore.cc: ...here. * config/microblaze/microblaze-c.c: Moved to... * config/microblaze/microblaze-c.cc: ...here. * config/microblaze/microblaze.c: Moved to... * config/microblaze/microblaze.cc: ...here. * config/mips/driver-native.c: Moved to... * config/mips/driver-native.cc: ...here. * config/mips/frame-header-opt.c: Moved to... * config/mips/frame-header-opt.cc: ...here. * config/mips/mips-d.c: Moved to... * config/mips/mips-d.cc: ...here. * config/mips/mips.c: Moved to... * config/mips/mips.cc: ...here. * config/mmix/mmix.c: Moved to... * config/mmix/mmix.cc: ...here. * config/mn10300/mn10300.c: Moved to... * config/mn10300/mn10300.cc: ...here. * config/moxie/moxie.c: Moved to... * config/moxie/moxie.cc: ...here. * config/msp430/driver-msp430.c: Moved to... * config/msp430/driver-msp430.cc: ...here. * config/msp430/msp430-c.c: Moved to... * config/msp430/msp430-c.cc: ...here. * config/msp430/msp430-devices.c: Moved to... * config/msp430/msp430-devices.cc: ...here. * config/msp430/msp430.c: Moved to... * config/msp430/msp430.cc: ...here. * config/nds32/nds32-cost.c: Moved to... * config/nds32/nds32-cost.cc: ...here. * config/nds32/nds32-fp-as-gp.c: Moved to... * config/nds32/nds32-fp-as-gp.cc: ...here. * config/nds32/nds32-intrinsic.c: Moved to... * config/nds32/nds32-intrinsic.cc: ...here. * config/nds32/nds32-isr.c: Moved to... * config/nds32/nds32-isr.cc: ...here. * config/nds32/nds32-md-auxiliary.c: Moved to... * config/nds32/nds32-md-auxiliary.cc: ...here. * config/nds32/nds32-memory-manipulation.c: Moved to... * config/nds32/nds32-memory-manipulation.cc: ...here. * config/nds32/nds32-pipelines-auxiliary.c: Moved to... * config/nds32/nds32-pipelines-auxiliary.cc: ...here. * config/nds32/nds32-predicates.c: Moved to... * config/nds32/nds32-predicates.cc: ...here. * config/nds32/nds32-relax-opt.c: Moved to... * config/nds32/nds32-relax-opt.cc: ...here. * config/nds32/nds32-utils.c: Moved to... * config/nds32/nds32-utils.cc: ...here. * config/nds32/nds32.c: Moved to... * config/nds32/nds32.cc: ...here. * config/netbsd-d.c: Moved to... * config/netbsd-d.cc: ...here. * config/netbsd.c: Moved to... * config/netbsd.cc: ...here. * config/nios2/nios2.c: Moved to... * config/nios2/nios2.cc: ...here. * config/nvptx/mkoffload.c: Moved to... * config/nvptx/mkoffload.cc: ...here. * config/nvptx/nvptx-c.c: Moved to... * config/nvptx/nvptx-c.cc: ...here. * config/nvptx/nvptx.c: Moved to... * config/nvptx/nvptx.cc: ...here. * config/openbsd-d.c: Moved to... * config/openbsd-d.cc: ...here. * config/or1k/or1k.c: Moved to... * config/or1k/or1k.cc: ...here. * config/pa/pa-d.c: Moved to... * config/pa/pa-d.cc: ...here. * config/pa/pa.c: Moved to... * config/pa/pa.cc: ...here. * config/pdp11/pdp11.c: Moved to... * config/pdp11/pdp11.cc: ...here. * config/pru/pru-passes.c: Moved to... * config/pru/pru-passes.cc: ...here. * config/pru/pru-pragma.c: Moved to... * config/pru/pru-pragma.cc: ...here. * config/pru/pru.c: Moved to... * config/pru/pru.cc: ...here. * config/riscv/riscv-builtins.c: Moved to... * config/riscv/riscv-builtins.cc: ...here. * config/riscv/riscv-c.c: Moved to... * config/riscv/riscv-c.cc: ...here. * config/riscv/riscv-d.c: Moved to... * config/riscv/riscv-d.cc: ...here. * config/riscv/riscv-shorten-memrefs.c: Moved to... * config/riscv/riscv-shorten-memrefs.cc: ...here. * config/riscv/riscv-sr.c: Moved to... * config/riscv/riscv-sr.cc: ...here. * config/riscv/riscv.c: Moved to... * config/riscv/riscv.cc: ...here. * config/rl78/rl78-c.c: Moved to... * config/rl78/rl78-c.cc: ...here. * config/rl78/rl78.c: Moved to... * config/rl78/rl78.cc: ...here. * config/rs6000/driver-rs6000.c: Moved to... * config/rs6000/driver-rs6000.cc: ...here. * config/rs6000/host-darwin.c: Moved to... * config/rs6000/host-darwin.cc: ...here. * config/rs6000/host-ppc64-darwin.c: Moved to... * config/rs6000/host-ppc64-darwin.cc: ...here. * config/rs6000/rbtree.c: Moved to... * config/rs6000/rbtree.cc: ...here. * config/rs6000/rs6000-c.c: Moved to... * config/rs6000/rs6000-c.cc: ...here. * config/rs6000/rs6000-call.c: Moved to... * config/rs6000/rs6000-call.cc: ...here. * config/rs6000/rs6000-d.c: Moved to... * config/rs6000/rs6000-d.cc: ...here. * config/rs6000/rs6000-gen-builtins.c: Moved to... * config/rs6000/rs6000-gen-builtins.cc: ...here. * config/rs6000/rs6000-linux.c: Moved to... * config/rs6000/rs6000-linux.cc: ...here. * config/rs6000/rs6000-logue.c: Moved to... * config/rs6000/rs6000-logue.cc: ...here. * config/rs6000/rs6000-p8swap.c: Moved to... * config/rs6000/rs6000-p8swap.cc: ...here. * config/rs6000/rs6000-pcrel-opt.c: Moved to... * config/rs6000/rs6000-pcrel-opt.cc: ...here. * config/rs6000/rs6000-string.c: Moved to... * config/rs6000/rs6000-string.cc: ...here. * config/rs6000/rs6000.c: Moved to... * config/rs6000/rs6000.cc: ...here. * config/rx/rx.c: Moved to... * config/rx/rx.cc: ...here. * config/s390/driver-native.c: Moved to... * config/s390/driver-native.cc: ...here. * config/s390/s390-c.c: Moved to... * config/s390/s390-c.cc: ...here. * config/s390/s390-d.c: Moved to... * config/s390/s390-d.cc: ...here. * config/s390/s390.c: Moved to... * config/s390/s390.cc: ...here. * config/sh/divtab-sh4-300.c: Moved to... * config/sh/divtab-sh4-300.cc: ...here. * config/sh/divtab-sh4.c: Moved to... * config/sh/divtab-sh4.cc: ...here. * config/sh/divtab.c: Moved to... * config/sh/divtab.cc: ...here. * config/sh/sh-c.c: Moved to... * config/sh/sh-c.cc: ...here. * config/sh/sh.c: Moved to... * config/sh/sh.cc: ...here. * config/sol2-c.c: Moved to... * config/sol2-c.cc: ...here. * config/sol2-cxx.c: Moved to... * config/sol2-cxx.cc: ...here. * config/sol2-d.c: Moved to... * config/sol2-d.cc: ...here. * config/sol2-stubs.c: Moved to... * config/sol2-stubs.cc: ...here. * config/sol2.c: Moved to... * config/sol2.cc: ...here. * config/sparc/driver-sparc.c: Moved to... * config/sparc/driver-sparc.cc: ...here. * config/sparc/sparc-c.c: Moved to... * config/sparc/sparc-c.cc: ...here. * config/sparc/sparc-d.c: Moved to... * config/sparc/sparc-d.cc: ...here. * config/sparc/sparc.c: Moved to... * config/sparc/sparc.cc: ...here. * config/stormy16/stormy16.c: Moved to... * config/stormy16/stormy16.cc: ...here. * config/tilegx/mul-tables.c: Moved to... * config/tilegx/mul-tables.cc: ...here. * config/tilegx/tilegx-c.c: Moved to... * config/tilegx/tilegx-c.cc: ...here. * config/tilegx/tilegx.c: Moved to... * config/tilegx/tilegx.cc: ...here. * config/tilepro/mul-tables.c: Moved to... * config/tilepro/mul-tables.cc: ...here. * config/tilepro/tilepro-c.c: Moved to... * config/tilepro/tilepro-c.cc: ...here. * config/tilepro/tilepro.c: Moved to... * config/tilepro/tilepro.cc: ...here. * config/v850/v850-c.c: Moved to... * config/v850/v850-c.cc: ...here. * config/v850/v850.c: Moved to... * config/v850/v850.cc: ...here. * config/vax/vax.c: Moved to... * config/vax/vax.cc: ...here. * config/visium/visium.c: Moved to... * config/visium/visium.cc: ...here. * config/vms/vms-c.c: Moved to... * config/vms/vms-c.cc: ...here. * config/vms/vms-f.c: Moved to... * config/vms/vms-f.cc: ...here. * config/vms/vms.c: Moved to... * config/vms/vms.cc: ...here. * config/vxworks-c.c: Moved to... * config/vxworks-c.cc: ...here. * config/vxworks.c: Moved to... * config/vxworks.cc: ...here. * config/winnt-c.c: Moved to... * config/winnt-c.cc: ...here. * config/xtensa/xtensa.c: Moved to... * config/xtensa/xtensa.cc: ...here. * context.c: Moved to... * context.cc: ...here. * convert.c: Moved to... * convert.cc: ...here. * coverage.c: Moved to... * coverage.cc: ...here. * cppbuiltin.c: Moved to... * cppbuiltin.cc: ...here. * cppdefault.c: Moved to... * cppdefault.cc: ...here. * cprop.c: Moved to... * cprop.cc: ...here. * cse.c: Moved to... * cse.cc: ...here. * cselib.c: Moved to... * cselib.cc: ...here. * ctfc.c: Moved to... * ctfc.cc: ...here. * ctfout.c: Moved to... * ctfout.cc: ...here. * data-streamer-in.c: Moved to... * data-streamer-in.cc: ...here. * data-streamer-out.c: Moved to... * data-streamer-out.cc: ...here. * data-streamer.c: Moved to... * data-streamer.cc: ...here. * dbgcnt.c: Moved to... * dbgcnt.cc: ...here. * dbxout.c: Moved to... * dbxout.cc: ...here. * dce.c: Moved to... * dce.cc: ...here. * ddg.c: Moved to... * ddg.cc: ...here. * debug.c: Moved to... * debug.cc: ...here. * df-core.c: Moved to... * df-core.cc: ...here. * df-problems.c: Moved to... * df-problems.cc: ...here. * df-scan.c: Moved to... * df-scan.cc: ...here. * dfp.c: Moved to... * dfp.cc: ...here. * diagnostic-color.c: Moved to... * diagnostic-color.cc: ...here. * diagnostic-show-locus.c: Moved to... * diagnostic-show-locus.cc: ...here. * diagnostic-spec.c: Moved to... * diagnostic-spec.cc: ...here. * diagnostic.c: Moved to... * diagnostic.cc: ...here. * dojump.c: Moved to... * dojump.cc: ...here. * dominance.c: Moved to... * dominance.cc: ...here. * domwalk.c: Moved to... * domwalk.cc: ...here. * double-int.c: Moved to... * double-int.cc: ...here. * dse.c: Moved to... * dse.cc: ...here. * dumpfile.c: Moved to... * dumpfile.cc: ...here. * dwarf2asm.c: Moved to... * dwarf2asm.cc: ...here. * dwarf2cfi.c: Moved to... * dwarf2cfi.cc: ...here. * dwarf2ctf.c: Moved to... * dwarf2ctf.cc: ...here. * dwarf2out.c: Moved to... * dwarf2out.cc: ...here. * early-remat.c: Moved to... * early-remat.cc: ...here. * edit-context.c: Moved to... * edit-context.cc: ...here. * emit-rtl.c: Moved to... * emit-rtl.cc: ...here. * errors.c: Moved to... * errors.cc: ...here. * et-forest.c: Moved to... * et-forest.cc: ...here. * except.c: Moved to... * except.cc: ...here. * explow.c: Moved to... * explow.cc: ...here. * expmed.c: Moved to... * expmed.cc: ...here. * expr.c: Moved to... * expr.cc: ...here. * fibonacci_heap.c: Moved to... * fibonacci_heap.cc: ...here. * file-find.c: Moved to... * file-find.cc: ...here. * file-prefix-map.c: Moved to... * file-prefix-map.cc: ...here. * final.c: Moved to... * final.cc: ...here. * fixed-value.c: Moved to... * fixed-value.cc: ...here. * fold-const-call.c: Moved to... * fold-const-call.cc: ...here. * fold-const.c: Moved to... * fold-const.cc: ...here. * fp-test.c: Moved to... * fp-test.cc: ...here. * function-tests.c: Moved to... * function-tests.cc: ...here. * function.c: Moved to... * function.cc: ...here. * fwprop.c: Moved to... * fwprop.cc: ...here. * gcc-ar.c: Moved to... * gcc-ar.cc: ...here. * gcc-main.c: Moved to... * gcc-main.cc: ...here. * gcc-rich-location.c: Moved to... * gcc-rich-location.cc: ...here. * gcc.c: Moved to... * gcc.cc: ...here. * gcov-dump.c: Moved to... * gcov-dump.cc: ...here. * gcov-io.c: Moved to... * gcov-io.cc: ...here. * gcov-tool.c: Moved to... * gcov-tool.cc: ...here. * gcov.c: Moved to... * gcov.cc: ...here. * gcse-common.c: Moved to... * gcse-common.cc: ...here. * gcse.c: Moved to... * gcse.cc: ...here. * genattr-common.c: Moved to... * genattr-common.cc: ...here. * genattr.c: Moved to... * genattr.cc: ...here. * genattrtab.c: Moved to... * genattrtab.cc: ...here. * genautomata.c: Moved to... * genautomata.cc: ...here. * gencfn-macros.c: Moved to... * gencfn-macros.cc: ...here. * gencheck.c: Moved to... * gencheck.cc: ...here. * genchecksum.c: Moved to... * genchecksum.cc: ...here. * gencodes.c: Moved to... * gencodes.cc: ...here. * genconditions.c: Moved to... * genconditions.cc: ...here. * genconfig.c: Moved to... * genconfig.cc: ...here. * genconstants.c: Moved to... * genconstants.cc: ...here. * genemit.c: Moved to... * genemit.cc: ...here. * genenums.c: Moved to... * genenums.cc: ...here. * generic-match-head.c: Moved to... * generic-match-head.cc: ...here. * genextract.c: Moved to... * genextract.cc: ...here. * genflags.c: Moved to... * genflags.cc: ...here. * gengenrtl.c: Moved to... * gengenrtl.cc: ...here. * gengtype-parse.c: Moved to... * gengtype-parse.cc: ...here. * gengtype-state.c: Moved to... * gengtype-state.cc: ...here. * gengtype.c: Moved to... * gengtype.cc: ...here. * genhooks.c: Moved to... * genhooks.cc: ...here. * genmatch.c: Moved to... * genmatch.cc: ...here. * genmddeps.c: Moved to... * genmddeps.cc: ...here. * genmddump.c: Moved to... * genmddump.cc: ...here. * genmodes.c: Moved to... * genmodes.cc: ...here. * genopinit.c: Moved to... * genopinit.cc: ...here. * genoutput.c: Moved to... * genoutput.cc: ...here. * genpeep.c: Moved to... * genpeep.cc: ...here. * genpreds.c: Moved to... * genpreds.cc: ...here. * genrecog.c: Moved to... * genrecog.cc: ...here. * gensupport.c: Moved to... * gensupport.cc: ...here. * gentarget-def.c: Moved to... * gentarget-def.cc: ...here. * genversion.c: Moved to... * genversion.cc: ...here. * ggc-common.c: Moved to... * ggc-common.cc: ...here. * ggc-none.c: Moved to... * ggc-none.cc: ...here. * ggc-page.c: Moved to... * ggc-page.cc: ...here. * ggc-tests.c: Moved to... * ggc-tests.cc: ...here. * gimple-builder.c: Moved to... * gimple-builder.cc: ...here. * gimple-expr.c: Moved to... * gimple-expr.cc: ...here. * gimple-fold.c: Moved to... * gimple-fold.cc: ...here. * gimple-iterator.c: Moved to... * gimple-iterator.cc: ...here. * gimple-laddress.c: Moved to... * gimple-laddress.cc: ...here. * gimple-loop-jam.c: Moved to... * gimple-loop-jam.cc: ...here. * gimple-low.c: Moved to... * gimple-low.cc: ...here. * gimple-match-head.c: Moved to... * gimple-match-head.cc: ...here. * gimple-pretty-print.c: Moved to... * gimple-pretty-print.cc: ...here. * gimple-ssa-backprop.c: Moved to... * gimple-ssa-backprop.cc: ...here. * gimple-ssa-evrp-analyze.c: Moved to... * gimple-ssa-evrp-analyze.cc: ...here. * gimple-ssa-evrp.c: Moved to... * gimple-ssa-evrp.cc: ...here. * gimple-ssa-isolate-paths.c: Moved to... * gimple-ssa-isolate-paths.cc: ...here. * gimple-ssa-nonnull-compare.c: Moved to... * gimple-ssa-nonnull-compare.cc: ...here. * gimple-ssa-split-paths.c: Moved to... * gimple-ssa-split-paths.cc: ...here. * gimple-ssa-sprintf.c: Moved to... * gimple-ssa-sprintf.cc: ...here. * gimple-ssa-store-merging.c: Moved to... * gimple-ssa-store-merging.cc: ...here. * gimple-ssa-strength-reduction.c: Moved to... * gimple-ssa-strength-reduction.cc: ...here. * gimple-ssa-warn-alloca.c: Moved to... * gimple-ssa-warn-alloca.cc: ...here. * gimple-ssa-warn-restrict.c: Moved to... * gimple-ssa-warn-restrict.cc: ...here. * gimple-streamer-in.c: Moved to... * gimple-streamer-in.cc: ...here. * gimple-streamer-out.c: Moved to... * gimple-streamer-out.cc: ...here. * gimple-walk.c: Moved to... * gimple-walk.cc: ...here. * gimple-warn-recursion.c: Moved to... * gimple-warn-recursion.cc: ...here. * gimple.c: Moved to... * gimple.cc: ...here. * gimplify-me.c: Moved to... * gimplify-me.cc: ...here. * gimplify.c: Moved to... * gimplify.cc: ...here. * godump.c: Moved to... * godump.cc: ...here. * graph.c: Moved to... * graph.cc: ...here. * graphds.c: Moved to... * graphds.cc: ...here. * graphite-dependences.c: Moved to... * graphite-dependences.cc: ...here. * graphite-isl-ast-to-gimple.c: Moved to... * graphite-isl-ast-to-gimple.cc: ...here. * graphite-optimize-isl.c: Moved to... * graphite-optimize-isl.cc: ...here. * graphite-poly.c: Moved to... * graphite-poly.cc: ...here. * graphite-scop-detection.c: Moved to... * graphite-scop-detection.cc: ...here. * graphite-sese-to-poly.c: Moved to... * graphite-sese-to-poly.cc: ...here. * graphite.c: Moved to... * graphite.cc: ...here. * haifa-sched.c: Moved to... * haifa-sched.cc: ...here. * hash-map-tests.c: Moved to... * hash-map-tests.cc: ...here. * hash-set-tests.c: Moved to... * hash-set-tests.cc: ...here. * hash-table.c: Moved to... * hash-table.cc: ...here. * hooks.c: Moved to... * hooks.cc: ...here. * host-default.c: Moved to... * host-default.cc: ...here. * hw-doloop.c: Moved to... * hw-doloop.cc: ...here. * hwint.c: Moved to... * hwint.cc: ...here. * ifcvt.c: Moved to... * ifcvt.cc: ...here. * inchash.c: Moved to... * inchash.cc: ...here. * incpath.c: Moved to... * incpath.cc: ...here. * init-regs.c: Moved to... * init-regs.cc: ...here. * input.c: Moved to... * input.cc: ...here. * internal-fn.c: Moved to... * internal-fn.cc: ...here. * intl.c: Moved to... * intl.cc: ...here. * ipa-comdats.c: Moved to... * ipa-comdats.cc: ...here. * ipa-cp.c: Moved to... * ipa-cp.cc: ...here. * ipa-devirt.c: Moved to... * ipa-devirt.cc: ...here. * ipa-fnsummary.c: Moved to... * ipa-fnsummary.cc: ...here. * ipa-icf-gimple.c: Moved to... * ipa-icf-gimple.cc: ...here. * ipa-icf.c: Moved to... * ipa-icf.cc: ...here. * ipa-inline-analysis.c: Moved to... * ipa-inline-analysis.cc: ...here. * ipa-inline-transform.c: Moved to... * ipa-inline-transform.cc: ...here. * ipa-inline.c: Moved to... * ipa-inline.cc: ...here. * ipa-modref-tree.c: Moved to... * ipa-modref-tree.cc: ...here. * ipa-modref.c: Moved to... * ipa-modref.cc: ...here. * ipa-param-manipulation.c: Moved to... * ipa-param-manipulation.cc: ...here. * ipa-polymorphic-call.c: Moved to... * ipa-polymorphic-call.cc: ...here. * ipa-predicate.c: Moved to... * ipa-predicate.cc: ...here. * ipa-profile.c: Moved to... * ipa-profile.cc: ...here. * ipa-prop.c: Moved to... * ipa-prop.cc: ...here. * ipa-pure-const.c: Moved to... * ipa-pure-const.cc: ...here. * ipa-ref.c: Moved to... * ipa-ref.cc: ...here. * ipa-reference.c: Moved to... * ipa-reference.cc: ...here. * ipa-split.c: Moved to... * ipa-split.cc: ...here. * ipa-sra.c: Moved to... * ipa-sra.cc: ...here. * ipa-utils.c: Moved to... * ipa-utils.cc: ...here. * ipa-visibility.c: Moved to... * ipa-visibility.cc: ...here. * ipa.c: Moved to... * ipa.cc: ...here. * ira-build.c: Moved to... * ira-build.cc: ...here. * ira-color.c: Moved to... * ira-color.cc: ...here. * ira-conflicts.c: Moved to... * ira-conflicts.cc: ...here. * ira-costs.c: Moved to... * ira-costs.cc: ...here. * ira-emit.c: Moved to... * ira-emit.cc: ...here. * ira-lives.c: Moved to... * ira-lives.cc: ...here. * ira.c: Moved to... * ira.cc: ...here. * jump.c: Moved to... * jump.cc: ...here. * langhooks.c: Moved to... * langhooks.cc: ...here. * lcm.c: Moved to... * lcm.cc: ...here. * lists.c: Moved to... * lists.cc: ...here. * loop-doloop.c: Moved to... * loop-doloop.cc: ...here. * loop-init.c: Moved to... * loop-init.cc: ...here. * loop-invariant.c: Moved to... * loop-invariant.cc: ...here. * loop-iv.c: Moved to... * loop-iv.cc: ...here. * loop-unroll.c: Moved to... * loop-unroll.cc: ...here. * lower-subreg.c: Moved to... * lower-subreg.cc: ...here. * lra-assigns.c: Moved to... * lra-assigns.cc: ...here. * lra-coalesce.c: Moved to... * lra-coalesce.cc: ...here. * lra-constraints.c: Moved to... * lra-constraints.cc: ...here. * lra-eliminations.c: Moved to... * lra-eliminations.cc: ...here. * lra-lives.c: Moved to... * lra-lives.cc: ...here. * lra-remat.c: Moved to... * lra-remat.cc: ...here. * lra-spills.c: Moved to... * lra-spills.cc: ...here. * lra.c: Moved to... * lra.cc: ...here. * lto-cgraph.c: Moved to... * lto-cgraph.cc: ...here. * lto-compress.c: Moved to... * lto-compress.cc: ...here. * lto-opts.c: Moved to... * lto-opts.cc: ...here. * lto-section-in.c: Moved to... * lto-section-in.cc: ...here. * lto-section-out.c: Moved to... * lto-section-out.cc: ...here. * lto-streamer-in.c: Moved to... * lto-streamer-in.cc: ...here. * lto-streamer-out.c: Moved to... * lto-streamer-out.cc: ...here. * lto-streamer.c: Moved to... * lto-streamer.cc: ...here. * lto-wrapper.c: Moved to... * lto-wrapper.cc: ...here. * main.c: Moved to... * main.cc: ...here. * mcf.c: Moved to... * mcf.cc: ...here. * mode-switching.c: Moved to... * mode-switching.cc: ...here. * modulo-sched.c: Moved to... * modulo-sched.cc: ...here. * multiple_target.c: Moved to... * multiple_target.cc: ...here. * omp-expand.c: Moved to... * omp-expand.cc: ...here. * omp-general.c: Moved to... * omp-general.cc: ...here. * omp-low.c: Moved to... * omp-low.cc: ...here. * omp-offload.c: Moved to... * omp-offload.cc: ...here. * omp-simd-clone.c: Moved to... * omp-simd-clone.cc: ...here. * opt-suggestions.c: Moved to... * opt-suggestions.cc: ...here. * optabs-libfuncs.c: Moved to... * optabs-libfuncs.cc: ...here. * optabs-query.c: Moved to... * optabs-query.cc: ...here. * optabs-tree.c: Moved to... * optabs-tree.cc: ...here. * optabs.c: Moved to... * optabs.cc: ...here. * opts-common.c: Moved to... * opts-common.cc: ...here. * opts-global.c: Moved to... * opts-global.cc: ...here. * opts.c: Moved to... * opts.cc: ...here. * passes.c: Moved to... * passes.cc: ...here. * plugin.c: Moved to... * plugin.cc: ...here. * postreload-gcse.c: Moved to... * postreload-gcse.cc: ...here. * postreload.c: Moved to... * postreload.cc: ...here. * predict.c: Moved to... * predict.cc: ...here. * prefix.c: Moved to... * prefix.cc: ...here. * pretty-print.c: Moved to... * pretty-print.cc: ...here. * print-rtl-function.c: Moved to... * print-rtl-function.cc: ...here. * print-rtl.c: Moved to... * print-rtl.cc: ...here. * print-tree.c: Moved to... * print-tree.cc: ...here. * profile-count.c: Moved to... * profile-count.cc: ...here. * profile.c: Moved to... * profile.cc: ...here. * read-md.c: Moved to... * read-md.cc: ...here. * read-rtl-function.c: Moved to... * read-rtl-function.cc: ...here. * read-rtl.c: Moved to... * read-rtl.cc: ...here. * real.c: Moved to... * real.cc: ...here. * realmpfr.c: Moved to... * realmpfr.cc: ...here. * recog.c: Moved to... * recog.cc: ...here. * ree.c: Moved to... * ree.cc: ...here. * reg-stack.c: Moved to... * reg-stack.cc: ...here. * regcprop.c: Moved to... * regcprop.cc: ...here. * reginfo.c: Moved to... * reginfo.cc: ...here. * regrename.c: Moved to... * regrename.cc: ...here. * regstat.c: Moved to... * regstat.cc: ...here. * reload.c: Moved to... * reload.cc: ...here. * reload1.c: Moved to... * reload1.cc: ...here. * reorg.c: Moved to... * reorg.cc: ...here. * resource.c: Moved to... * resource.cc: ...here. * rtl-error.c: Moved to... * rtl-error.cc: ...here. * rtl-tests.c: Moved to... * rtl-tests.cc: ...here. * rtl.c: Moved to... * rtl.cc: ...here. * rtlanal.c: Moved to... * rtlanal.cc: ...here. * rtlhash.c: Moved to... * rtlhash.cc: ...here. * rtlhooks.c: Moved to... * rtlhooks.cc: ...here. * rtx-vector-builder.c: Moved to... * rtx-vector-builder.cc: ...here. * run-rtl-passes.c: Moved to... * run-rtl-passes.cc: ...here. * sancov.c: Moved to... * sancov.cc: ...here. * sanopt.c: Moved to... * sanopt.cc: ...here. * sbitmap.c: Moved to... * sbitmap.cc: ...here. * sched-deps.c: Moved to... * sched-deps.cc: ...here. * sched-ebb.c: Moved to... * sched-ebb.cc: ...here. * sched-rgn.c: Moved to... * sched-rgn.cc: ...here. * sel-sched-dump.c: Moved to... * sel-sched-dump.cc: ...here. * sel-sched-ir.c: Moved to... * sel-sched-ir.cc: ...here. * sel-sched.c: Moved to... * sel-sched.cc: ...here. * selftest-diagnostic.c: Moved to... * selftest-diagnostic.cc: ...here. * selftest-rtl.c: Moved to... * selftest-rtl.cc: ...here. * selftest-run-tests.c: Moved to... * selftest-run-tests.cc: ...here. * selftest.c: Moved to... * selftest.cc: ...here. * sese.c: Moved to... * sese.cc: ...here. * shrink-wrap.c: Moved to... * shrink-wrap.cc: ...here. * simplify-rtx.c: Moved to... * simplify-rtx.cc: ...here. * sparseset.c: Moved to... * sparseset.cc: ...here. * spellcheck-tree.c: Moved to... * spellcheck-tree.cc: ...here. * spellcheck.c: Moved to... * spellcheck.cc: ...here. * sreal.c: Moved to... * sreal.cc: ...here. * stack-ptr-mod.c: Moved to... * stack-ptr-mod.cc: ...here. * statistics.c: Moved to... * statistics.cc: ...here. * stmt.c: Moved to... * stmt.cc: ...here. * stor-layout.c: Moved to... * stor-layout.cc: ...here. * store-motion.c: Moved to... * store-motion.cc: ...here. * streamer-hooks.c: Moved to... * streamer-hooks.cc: ...here. * stringpool.c: Moved to... * stringpool.cc: ...here. * substring-locations.c: Moved to... * substring-locations.cc: ...here. * symtab.c: Moved to... * symtab.cc: ...here. * target-globals.c: Moved to... * target-globals.cc: ...here. * targhooks.c: Moved to... * targhooks.cc: ...here. * timevar.c: Moved to... * timevar.cc: ...here. * toplev.c: Moved to... * toplev.cc: ...here. * tracer.c: Moved to... * tracer.cc: ...here. * trans-mem.c: Moved to... * trans-mem.cc: ...here. * tree-affine.c: Moved to... * tree-affine.cc: ...here. * tree-call-cdce.c: Moved to... * tree-call-cdce.cc: ...here. * tree-cfg.c: Moved to... * tree-cfg.cc: ...here. * tree-cfgcleanup.c: Moved to... * tree-cfgcleanup.cc: ...here. * tree-chrec.c: Moved to... * tree-chrec.cc: ...here. * tree-complex.c: Moved to... * tree-complex.cc: ...here. * tree-data-ref.c: Moved to... * tree-data-ref.cc: ...here. * tree-dfa.c: Moved to... * tree-dfa.cc: ...here. * tree-diagnostic.c: Moved to... * tree-diagnostic.cc: ...here. * tree-dump.c: Moved to... * tree-dump.cc: ...here. * tree-eh.c: Moved to... * tree-eh.cc: ...here. * tree-emutls.c: Moved to... * tree-emutls.cc: ...here. * tree-if-conv.c: Moved to... * tree-if-conv.cc: ...here. * tree-inline.c: Moved to... * tree-inline.cc: ...here. * tree-into-ssa.c: Moved to... * tree-into-ssa.cc: ...here. * tree-iterator.c: Moved to... * tree-iterator.cc: ...here. * tree-loop-distribution.c: Moved to... * tree-loop-distribution.cc: ...here. * tree-nested.c: Moved to... * tree-nested.cc: ...here. * tree-nrv.c: Moved to... * tree-nrv.cc: ...here. * tree-object-size.c: Moved to... * tree-object-size.cc: ...here. * tree-outof-ssa.c: Moved to... * tree-outof-ssa.cc: ...here. * tree-parloops.c: Moved to... * tree-parloops.cc: ...here. * tree-phinodes.c: Moved to... * tree-phinodes.cc: ...here. * tree-predcom.c: Moved to... * tree-predcom.cc: ...here. * tree-pretty-print.c: Moved to... * tree-pretty-print.cc: ...here. * tree-profile.c: Moved to... * tree-profile.cc: ...here. * tree-scalar-evolution.c: Moved to... * tree-scalar-evolution.cc: ...here. * tree-sra.c: Moved to... * tree-sra.cc: ...here. * tree-ssa-address.c: Moved to... * tree-ssa-address.cc: ...here. * tree-ssa-alias.c: Moved to... * tree-ssa-alias.cc: ...here. * tree-ssa-ccp.c: Moved to... * tree-ssa-ccp.cc: ...here. * tree-ssa-coalesce.c: Moved to... * tree-ssa-coalesce.cc: ...here. * tree-ssa-copy.c: Moved to... * tree-ssa-copy.cc: ...here. * tree-ssa-dce.c: Moved to... * tree-ssa-dce.cc: ...here. * tree-ssa-dom.c: Moved to... * tree-ssa-dom.cc: ...here. * tree-ssa-dse.c: Moved to... * tree-ssa-dse.cc: ...here. * tree-ssa-forwprop.c: Moved to... * tree-ssa-forwprop.cc: ...here. * tree-ssa-ifcombine.c: Moved to... * tree-ssa-ifcombine.cc: ...here. * tree-ssa-live.c: Moved to... * tree-ssa-live.cc: ...here. * tree-ssa-loop-ch.c: Moved to... * tree-ssa-loop-ch.cc: ...here. * tree-ssa-loop-im.c: Moved to... * tree-ssa-loop-im.cc: ...here. * tree-ssa-loop-ivcanon.c: Moved to... * tree-ssa-loop-ivcanon.cc: ...here. * tree-ssa-loop-ivopts.c: Moved to... * tree-ssa-loop-ivopts.cc: ...here. * tree-ssa-loop-manip.c: Moved to... * tree-ssa-loop-manip.cc: ...here. * tree-ssa-loop-niter.c: Moved to... * tree-ssa-loop-niter.cc: ...here. * tree-ssa-loop-prefetch.c: Moved to... * tree-ssa-loop-prefetch.cc: ...here. * tree-ssa-loop-split.c: Moved to... * tree-ssa-loop-split.cc: ...here. * tree-ssa-loop-unswitch.c: Moved to... * tree-ssa-loop-unswitch.cc: ...here. * tree-ssa-loop.c: Moved to... * tree-ssa-loop.cc: ...here. * tree-ssa-math-opts.c: Moved to... * tree-ssa-math-opts.cc: ...here. * tree-ssa-operands.c: Moved to... * tree-ssa-operands.cc: ...here. * tree-ssa-phiopt.c: Moved to... * tree-ssa-phiopt.cc: ...here. * tree-ssa-phiprop.c: Moved to... * tree-ssa-phiprop.cc: ...here. * tree-ssa-pre.c: Moved to... * tree-ssa-pre.cc: ...here. * tree-ssa-propagate.c: Moved to... * tree-ssa-propagate.cc: ...here. * tree-ssa-reassoc.c: Moved to... * tree-ssa-reassoc.cc: ...here. * tree-ssa-sccvn.c: Moved to... * tree-ssa-sccvn.cc: ...here. * tree-ssa-scopedtables.c: Moved to... * tree-ssa-scopedtables.cc: ...here. * tree-ssa-sink.c: Moved to... * tree-ssa-sink.cc: ...here. * tree-ssa-strlen.c: Moved to... * tree-ssa-strlen.cc: ...here. * tree-ssa-structalias.c: Moved to... * tree-ssa-structalias.cc: ...here. * tree-ssa-tail-merge.c: Moved to... * tree-ssa-tail-merge.cc: ...here. * tree-ssa-ter.c: Moved to... * tree-ssa-ter.cc: ...here. * tree-ssa-threadbackward.c: Moved to... * tree-ssa-threadbackward.cc: ...here. * tree-ssa-threadedge.c: Moved to... * tree-ssa-threadedge.cc: ...here. * tree-ssa-threadupdate.c: Moved to... * tree-ssa-threadupdate.cc: ...here. * tree-ssa-uncprop.c: Moved to... * tree-ssa-uncprop.cc: ...here. * tree-ssa-uninit.c: Moved to... * tree-ssa-uninit.cc: ...here. * tree-ssa.c: Moved to... * tree-ssa.cc: ...here. * tree-ssanames.c: Moved to... * tree-ssanames.cc: ...here. * tree-stdarg.c: Moved to... * tree-stdarg.cc: ...here. * tree-streamer-in.c: Moved to... * tree-streamer-in.cc: ...here. * tree-streamer-out.c: Moved to... * tree-streamer-out.cc: ...here. * tree-streamer.c: Moved to... * tree-streamer.cc: ...here. * tree-switch-conversion.c: Moved to... * tree-switch-conversion.cc: ...here. * tree-tailcall.c: Moved to... * tree-tailcall.cc: ...here. * tree-vect-data-refs.c: Moved to... * tree-vect-data-refs.cc: ...here. * tree-vect-generic.c: Moved to... * tree-vect-generic.cc: ...here. * tree-vect-loop-manip.c: Moved to... * tree-vect-loop-manip.cc: ...here. * tree-vect-loop.c: Moved to... * tree-vect-loop.cc: ...here. * tree-vect-patterns.c: Moved to... * tree-vect-patterns.cc: ...here. * tree-vect-slp-patterns.c: Moved to... * tree-vect-slp-patterns.cc: ...here. * tree-vect-slp.c: Moved to... * tree-vect-slp.cc: ...here. * tree-vect-stmts.c: Moved to... * tree-vect-stmts.cc: ...here. * tree-vector-builder.c: Moved to... * tree-vector-builder.cc: ...here. * tree-vectorizer.c: Moved to... * tree-vectorizer.cc: ...here. * tree-vrp.c: Moved to... * tree-vrp.cc: ...here. * tree.c: Moved to... * tree.cc: ...here. * tsan.c: Moved to... * tsan.cc: ...here. * typed-splay-tree.c: Moved to... * typed-splay-tree.cc: ...here. * ubsan.c: Moved to... * ubsan.cc: ...here. * valtrack.c: Moved to... * valtrack.cc: ...here. * value-prof.c: Moved to... * value-prof.cc: ...here. * var-tracking.c: Moved to... * var-tracking.cc: ...here. * varasm.c: Moved to... * varasm.cc: ...here. * varpool.c: Moved to... * varpool.cc: ...here. * vec-perm-indices.c: Moved to... * vec-perm-indices.cc: ...here. * vec.c: Moved to... * vec.cc: ...here. * vmsdbgout.c: Moved to... * vmsdbgout.cc: ...here. * vr-values.c: Moved to... * vr-values.cc: ...here. * vtable-verify.c: Moved to... * vtable-verify.cc: ...here. * web.c: Moved to... * web.cc: ...here. * xcoffout.c: Moved to... * xcoffout.cc: ...here. gcc/c-family/ChangeLog: * c-ada-spec.c: Moved to... * c-ada-spec.cc: ...here. * c-attribs.c: Moved to... * c-attribs.cc: ...here. * c-common.c: Moved to... * c-common.cc: ...here. * c-cppbuiltin.c: Moved to... * c-cppbuiltin.cc: ...here. * c-dump.c: Moved to... * c-dump.cc: ...here. * c-format.c: Moved to... * c-format.cc: ...here. * c-gimplify.c: Moved to... * c-gimplify.cc: ...here. * c-indentation.c: Moved to... * c-indentation.cc: ...here. * c-lex.c: Moved to... * c-lex.cc: ...here. * c-omp.c: Moved to... * c-omp.cc: ...here. * c-opts.c: Moved to... * c-opts.cc: ...here. * c-pch.c: Moved to... * c-pch.cc: ...here. * c-ppoutput.c: Moved to... * c-ppoutput.cc: ...here. * c-pragma.c: Moved to... * c-pragma.cc: ...here. * c-pretty-print.c: Moved to... * c-pretty-print.cc: ...here. * c-semantics.c: Moved to... * c-semantics.cc: ...here. * c-ubsan.c: Moved to... * c-ubsan.cc: ...here. * c-warn.c: Moved to... * c-warn.cc: ...here. * cppspec.c: Moved to... * cppspec.cc: ...here. * stub-objc.c: Moved to... * stub-objc.cc: ...here. gcc/c/ChangeLog: * c-aux-info.c: Moved to... * c-aux-info.cc: ...here. * c-convert.c: Moved to... * c-convert.cc: ...here. * c-decl.c: Moved to... * c-decl.cc: ...here. * c-errors.c: Moved to... * c-errors.cc: ...here. * c-fold.c: Moved to... * c-fold.cc: ...here. * c-lang.c: Moved to... * c-lang.cc: ...here. * c-objc-common.c: Moved to... * c-objc-common.cc: ...here. * c-parser.c: Moved to... * c-parser.cc: ...here. * c-typeck.c: Moved to... * c-typeck.cc: ...here. * gccspec.c: Moved to... * gccspec.cc: ...here. * gimple-parser.c: Moved to... * gimple-parser.cc: ...here. gcc/cp/ChangeLog: * call.c: Moved to... * call.cc: ...here. * class.c: Moved to... * class.cc: ...here. * constexpr.c: Moved to... * constexpr.cc: ...here. * cp-gimplify.c: Moved to... * cp-gimplify.cc: ...here. * cp-lang.c: Moved to... * cp-lang.cc: ...here. * cp-objcp-common.c: Moved to... * cp-objcp-common.cc: ...here. * cp-ubsan.c: Moved to... * cp-ubsan.cc: ...here. * cvt.c: Moved to... * cvt.cc: ...here. * cxx-pretty-print.c: Moved to... * cxx-pretty-print.cc: ...here. * decl.c: Moved to... * decl.cc: ...here. * decl2.c: Moved to... * decl2.cc: ...here. * dump.c: Moved to... * dump.cc: ...here. * error.c: Moved to... * error.cc: ...here. * except.c: Moved to... * except.cc: ...here. * expr.c: Moved to... * expr.cc: ...here. * friend.c: Moved to... * friend.cc: ...here. * g++spec.c: Moved to... * g++spec.cc: ...here. * init.c: Moved to... * init.cc: ...here. * lambda.c: Moved to... * lambda.cc: ...here. * lex.c: Moved to... * lex.cc: ...here. * mangle.c: Moved to... * mangle.cc: ...here. * method.c: Moved to... * method.cc: ...here. * name-lookup.c: Moved to... * name-lookup.cc: ...here. * optimize.c: Moved to... * optimize.cc: ...here. * parser.c: Moved to... * parser.cc: ...here. * pt.c: Moved to... * pt.cc: ...here. * ptree.c: Moved to... * ptree.cc: ...here. * rtti.c: Moved to... * rtti.cc: ...here. * search.c: Moved to... * search.cc: ...here. * semantics.c: Moved to... * semantics.cc: ...here. * tree.c: Moved to... * tree.cc: ...here. * typeck.c: Moved to... * typeck.cc: ...here. * typeck2.c: Moved to... * typeck2.cc: ...here. * vtable-class-hierarchy.c: Moved to... * vtable-class-hierarchy.cc: ...here. gcc/fortran/ChangeLog: * arith.c: Moved to... * arith.cc: ...here. * array.c: Moved to... * array.cc: ...here. * bbt.c: Moved to... * bbt.cc: ...here. * check.c: Moved to... * check.cc: ...here. * class.c: Moved to... * class.cc: ...here. * constructor.c: Moved to... * constructor.cc: ...here. * convert.c: Moved to... * convert.cc: ...here. * cpp.c: Moved to... * cpp.cc: ...here. * data.c: Moved to... * data.cc: ...here. * decl.c: Moved to... * decl.cc: ...here. * dependency.c: Moved to... * dependency.cc: ...here. * dump-parse-tree.c: Moved to... * dump-parse-tree.cc: ...here. * error.c: Moved to... * error.cc: ...here. * expr.c: Moved to... * expr.cc: ...here. * f95-lang.c: Moved to... * f95-lang.cc: ...here. * frontend-passes.c: Moved to... * frontend-passes.cc: ...here. * gfortranspec.c: Moved to... * gfortranspec.cc: ...here. * interface.c: Moved to... * interface.cc: ...here. * intrinsic.c: Moved to... * intrinsic.cc: ...here. * io.c: Moved to... * io.cc: ...here. * iresolve.c: Moved to... * iresolve.cc: ...here. * match.c: Moved to... * match.cc: ...here. * matchexp.c: Moved to... * matchexp.cc: ...here. * misc.c: Moved to... * misc.cc: ...here. * module.c: Moved to... * module.cc: ...here. * openmp.c: Moved to... * openmp.cc: ...here. * options.c: Moved to... * options.cc: ...here. * parse.c: Moved to... * parse.cc: ...here. * primary.c: Moved to... * primary.cc: ...here. * resolve.c: Moved to... * resolve.cc: ...here. * scanner.c: Moved to... * scanner.cc: ...here. * simplify.c: Moved to... * simplify.cc: ...here. * st.c: Moved to... * st.cc: ...here. * symbol.c: Moved to... * symbol.cc: ...here. * target-memory.c: Moved to... * target-memory.cc: ...here. * trans-array.c: Moved to... * trans-array.cc: ...here. * trans-common.c: Moved to... * trans-common.cc: ...here. * trans-const.c: Moved to... * trans-const.cc: ...here. * trans-decl.c: Moved to... * trans-decl.cc: ...here. * trans-expr.c: Moved to... * trans-expr.cc: ...here. * trans-intrinsic.c: Moved to... * trans-intrinsic.cc: ...here. * trans-io.c: Moved to... * trans-io.cc: ...here. * trans-openmp.c: Moved to... * trans-openmp.cc: ...here. * trans-stmt.c: Moved to... * trans-stmt.cc: ...here. * trans-types.c: Moved to... * trans-types.cc: ...here. * trans.c: Moved to... * trans.cc: ...here. gcc/go/ChangeLog: * go-backend.c: Moved to... * go-backend.cc: ...here. * go-lang.c: Moved to... * go-lang.cc: ...here. * gospec.c: Moved to... * gospec.cc: ...here. gcc/jit/ChangeLog: * dummy-frontend.c: Moved to... * dummy-frontend.cc: ...here. * jit-builtins.c: Moved to... * jit-builtins.cc: ...here. * jit-logging.c: Moved to... * jit-logging.cc: ...here. * jit-playback.c: Moved to... * jit-playback.cc: ...here. * jit-recording.c: Moved to... * jit-recording.cc: ...here. * jit-result.c: Moved to... * jit-result.cc: ...here. * jit-spec.c: Moved to... * jit-spec.cc: ...here. * jit-tempdir.c: Moved to... * jit-tempdir.cc: ...here. * jit-w32.c: Moved to... * jit-w32.cc: ...here. * libgccjit.c: Moved to... * libgccjit.cc: ...here. gcc/lto/ChangeLog: * common.c: Moved to... * common.cc: ...here. * lto-common.c: Moved to... * lto-common.cc: ...here. * lto-dump.c: Moved to... * lto-dump.cc: ...here. * lto-lang.c: Moved to... * lto-lang.cc: ...here. * lto-object.c: Moved to... * lto-object.cc: ...here. * lto-partition.c: Moved to... * lto-partition.cc: ...here. * lto-symtab.c: Moved to... * lto-symtab.cc: ...here. * lto.c: Moved to... * lto.cc: ...here. gcc/objc/ChangeLog: * objc-act.c: Moved to... * objc-act.cc: ...here. * objc-encoding.c: Moved to... * objc-encoding.cc: ...here. * objc-gnu-runtime-abi-01.c: Moved to... * objc-gnu-runtime-abi-01.cc: ...here. * objc-lang.c: Moved to... * objc-lang.cc: ...here. * objc-map.c: Moved to... * objc-map.cc: ...here. * objc-next-runtime-abi-01.c: Moved to... * objc-next-runtime-abi-01.cc: ...here. * objc-next-runtime-abi-02.c: Moved to... * objc-next-runtime-abi-02.cc: ...here. * objc-runtime-shared-support.c: Moved to... * objc-runtime-shared-support.cc: ...here. gcc/objcp/ChangeLog: * objcp-decl.c: Moved to... * objcp-decl.cc: ...here. * objcp-lang.c: Moved to... * objcp-lang.cc: ...here. libcpp/ChangeLog: * charset.c: Moved to... * charset.cc: ...here. * directives.c: Moved to... * directives.cc: ...here. * errors.c: Moved to... * errors.cc: ...here. * expr.c: Moved to... * expr.cc: ...here. * files.c: Moved to... * files.cc: ...here. * identifiers.c: Moved to... * identifiers.cc: ...here. * init.c: Moved to... * init.cc: ...here. * lex.c: Moved to... * lex.cc: ...here. * line-map.c: Moved to... * line-map.cc: ...here. * macro.c: Moved to... * macro.cc: ...here. * makeucnid.c: Moved to... * makeucnid.cc: ...here. * mkdeps.c: Moved to... * mkdeps.cc: ...here. * pch.c: Moved to... * pch.cc: ...here. * symtab.c: Moved to... * symtab.cc: ...here. * traditional.c: Moved to... * traditional.cc: ...here.
Diffstat (limited to 'gcc/except.c')
-rw-r--r--gcc/except.c3522
1 files changed, 0 insertions, 3522 deletions
diff --git a/gcc/except.c b/gcc/except.c
deleted file mode 100644
index 0e17f28..0000000
--- a/gcc/except.c
+++ /dev/null
@@ -1,3522 +0,0 @@
-/* Implements exception handling.
- Copyright (C) 1989-2022 Free Software Foundation, Inc.
- Contributed by Mike Stump <mrs@cygnus.com>.
-
-This file is part of GCC.
-
-GCC is free software; you can redistribute it and/or modify it under
-the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 3, or (at your option) any later
-version.
-
-GCC is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or
-FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-for more details.
-
-You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING3. If not see
-<http://www.gnu.org/licenses/>. */
-
-
-/* An exception is an event that can be "thrown" from within a
- function. This event can then be "caught" by the callers of
- the function.
-
- The representation of exceptions changes several times during
- the compilation process:
-
- In the beginning, in the front end, we have the GENERIC trees
- TRY_CATCH_EXPR, TRY_FINALLY_EXPR, EH_ELSE_EXPR, WITH_CLEANUP_EXPR,
- CLEANUP_POINT_EXPR, CATCH_EXPR, and EH_FILTER_EXPR.
-
- During initial gimplification (gimplify.c) these are lowered to the
- GIMPLE_TRY, GIMPLE_CATCH, GIMPLE_EH_ELSE, and GIMPLE_EH_FILTER
- nodes. The WITH_CLEANUP_EXPR and CLEANUP_POINT_EXPR nodes are
- converted into GIMPLE_TRY_FINALLY nodes; the others are a more
- direct 1-1 conversion.
-
- During pass_lower_eh (tree-eh.c) we record the nested structure
- of the TRY nodes in EH_REGION nodes in CFUN->EH->REGION_TREE.
- We expand the eh_protect_cleanup_actions langhook into MUST_NOT_THROW
- regions at this time. We can then flatten the statements within
- the TRY nodes to straight-line code. Statements that had been within
- TRY nodes that can throw are recorded within CFUN->EH->THROW_STMT_TABLE,
- so that we may remember what action is supposed to be taken if
- a given statement does throw. During this lowering process,
- we create an EH_LANDING_PAD node for each EH_REGION that has
- some code within the function that needs to be executed if a
- throw does happen. We also create RESX statements that are
- used to transfer control from an inner EH_REGION to an outer
- EH_REGION. We also create EH_DISPATCH statements as placeholders
- for a runtime type comparison that should be made in order to
- select the action to perform among different CATCH and EH_FILTER
- regions.
-
- During pass_lower_eh_dispatch (tree-eh.c), which is run after
- all inlining is complete, we are able to run assign_filter_values,
- which allows us to map the set of types manipulated by all of the
- CATCH and EH_FILTER regions to a set of integers. This set of integers
- will be how the exception runtime communicates with the code generated
- within the function. We then expand the GIMPLE_EH_DISPATCH statements
- to a switch or conditional branches that use the argument provided by
- the runtime (__builtin_eh_filter) and the set of integers we computed
- in assign_filter_values.
-
- During pass_lower_resx (tree-eh.c), which is run near the end
- of optimization, we expand RESX statements. If the eh region
- that is outer to the RESX statement is a MUST_NOT_THROW, then
- the RESX expands to some form of abort statement. If the eh
- region that is outer to the RESX statement is within the current
- function, then the RESX expands to a bookkeeping call
- (__builtin_eh_copy_values) and a goto. Otherwise, the next
- handler for the exception must be within a function somewhere
- up the call chain, so we call back into the exception runtime
- (__builtin_unwind_resume).
-
- During pass_expand (cfgexpand.c), we generate REG_EH_REGION notes
- that create an rtl to eh_region mapping that corresponds to the
- gimple to eh_region mapping that had been recorded in the
- THROW_STMT_TABLE.
-
- Then, via finish_eh_generation, we generate the real landing pads
- to which the runtime will actually transfer control. These new
- landing pads perform whatever bookkeeping is needed by the target
- backend in order to resume execution within the current function.
- Each of these new landing pads falls through into the post_landing_pad
- label which had been used within the CFG up to this point. All
- exception edges within the CFG are redirected to the new landing pads.
- If the target uses setjmp to implement exceptions, the various extra
- calls into the runtime to register and unregister the current stack
- frame are emitted at this time.
-
- During pass_convert_to_eh_region_ranges (except.c), we transform
- the REG_EH_REGION notes attached to individual insns into
- non-overlapping ranges of insns bounded by NOTE_INSN_EH_REGION_BEG
- and NOTE_INSN_EH_REGION_END. Each insn within such ranges has the
- same associated action within the exception region tree, meaning
- that (1) the exception is caught by the same landing pad within the
- current function, (2) the exception is blocked by the runtime with
- a MUST_NOT_THROW region, or (3) the exception is not handled at all
- within the current function.
-
- Finally, during assembly generation, we call
- output_function_exception_table (except.c) to emit the tables with
- which the exception runtime can determine if a given stack frame
- handles a given exception, and if so what filter value to provide
- to the function when the non-local control transfer is effected.
- If the target uses dwarf2 unwinding to implement exceptions, then
- output_call_frame_info (dwarf2out.c) emits the required unwind data. */
-
-
-#include "config.h"
-#include "system.h"
-#include "coretypes.h"
-#include "backend.h"
-#include "target.h"
-#include "rtl.h"
-#include "tree.h"
-#include "cfghooks.h"
-#include "tree-pass.h"
-#include "memmodel.h"
-#include "tm_p.h"
-#include "stringpool.h"
-#include "expmed.h"
-#include "optabs.h"
-#include "emit-rtl.h"
-#include "cgraph.h"
-#include "diagnostic.h"
-#include "fold-const.h"
-#include "stor-layout.h"
-#include "explow.h"
-#include "stmt.h"
-#include "expr.h"
-#include "calls.h"
-#include "libfuncs.h"
-#include "except.h"
-#include "output.h"
-#include "dwarf2asm.h"
-#include "dwarf2.h"
-#include "common/common-target.h"
-#include "langhooks.h"
-#include "cfgrtl.h"
-#include "tree-pretty-print.h"
-#include "cfgloop.h"
-#include "builtins.h"
-#include "tree-hash-traits.h"
-#include "flags.h"
-
-static GTY(()) int call_site_base;
-
-static GTY(()) hash_map<tree_hash, tree> *type_to_runtime_map;
-
-static GTY(()) tree setjmp_fn;
-
-/* Describe the SjLj_Function_Context structure. */
-static GTY(()) tree sjlj_fc_type_node;
-static int sjlj_fc_call_site_ofs;
-static int sjlj_fc_data_ofs;
-static int sjlj_fc_personality_ofs;
-static int sjlj_fc_lsda_ofs;
-static int sjlj_fc_jbuf_ofs;
-
-
-struct GTY(()) call_site_record_d
-{
- rtx landing_pad;
- int action;
-};
-
-/* In the following structure and associated functions,
- we represent entries in the action table as 1-based indices.
- Special cases are:
-
- 0: null action record, non-null landing pad; implies cleanups
- -1: null action record, null landing pad; implies no action
- -2: no call-site entry; implies must_not_throw
- -3: we have yet to process outer regions
-
- Further, no special cases apply to the "next" field of the record.
- For next, 0 means end of list. */
-
-struct action_record
-{
- int offset;
- int filter;
- int next;
-};
-
-/* Hashtable helpers. */
-
-struct action_record_hasher : free_ptr_hash <action_record>
-{
- static inline hashval_t hash (const action_record *);
- static inline bool equal (const action_record *, const action_record *);
-};
-
-inline hashval_t
-action_record_hasher::hash (const action_record *entry)
-{
- return entry->next * 1009 + entry->filter;
-}
-
-inline bool
-action_record_hasher::equal (const action_record *entry,
- const action_record *data)
-{
- return entry->filter == data->filter && entry->next == data->next;
-}
-
-typedef hash_table<action_record_hasher> action_hash_type;
-
-static bool get_eh_region_and_lp_from_rtx (const_rtx, eh_region *,
- eh_landing_pad *);
-
-static void dw2_build_landing_pads (void);
-
-static int collect_one_action_chain (action_hash_type *, eh_region);
-static int add_call_site (rtx, int, int);
-
-static void push_uleb128 (vec<uchar, va_gc> **, unsigned int);
-static void push_sleb128 (vec<uchar, va_gc> **, int);
-static int dw2_size_of_call_site_table (int);
-static int sjlj_size_of_call_site_table (void);
-static void dw2_output_call_site_table (int, int);
-static void sjlj_output_call_site_table (void);
-
-
-void
-init_eh (void)
-{
- if (! flag_exceptions)
- return;
-
- type_to_runtime_map = hash_map<tree_hash, tree>::create_ggc (31);
-
- /* Create the SjLj_Function_Context structure. This should match
- the definition in unwind-sjlj.c. */
- if (targetm_common.except_unwind_info (&global_options) == UI_SJLJ)
- {
- tree f_jbuf, f_per, f_lsda, f_prev, f_cs, f_data, tmp;
-
- sjlj_fc_type_node = lang_hooks.types.make_type (RECORD_TYPE);
-
- f_prev = build_decl (BUILTINS_LOCATION,
- FIELD_DECL, get_identifier ("__prev"),
- build_pointer_type (sjlj_fc_type_node));
- DECL_FIELD_CONTEXT (f_prev) = sjlj_fc_type_node;
-
- f_cs = build_decl (BUILTINS_LOCATION,
- FIELD_DECL, get_identifier ("__call_site"),
- integer_type_node);
- DECL_FIELD_CONTEXT (f_cs) = sjlj_fc_type_node;
-
- tmp = build_index_type (size_int (4 - 1));
- tmp = build_array_type (lang_hooks.types.type_for_mode
- (targetm.unwind_word_mode (), 1),
- tmp);
- f_data = build_decl (BUILTINS_LOCATION,
- FIELD_DECL, get_identifier ("__data"), tmp);
- DECL_FIELD_CONTEXT (f_data) = sjlj_fc_type_node;
-
- f_per = build_decl (BUILTINS_LOCATION,
- FIELD_DECL, get_identifier ("__personality"),
- ptr_type_node);
- DECL_FIELD_CONTEXT (f_per) = sjlj_fc_type_node;
-
- f_lsda = build_decl (BUILTINS_LOCATION,
- FIELD_DECL, get_identifier ("__lsda"),
- ptr_type_node);
- DECL_FIELD_CONTEXT (f_lsda) = sjlj_fc_type_node;
-
-#ifdef DONT_USE_BUILTIN_SETJMP
-#ifdef JMP_BUF_SIZE
- tmp = size_int (JMP_BUF_SIZE - 1);
-#else
- /* Should be large enough for most systems, if it is not,
- JMP_BUF_SIZE should be defined with the proper value. It will
- also tend to be larger than necessary for most systems, a more
- optimal port will define JMP_BUF_SIZE. */
- tmp = size_int (FIRST_PSEUDO_REGISTER + 2 - 1);
-#endif
-#else
- /* Compute a minimally sized jump buffer. We need room to store at
- least 3 pointers - stack pointer, frame pointer and return address.
- Plus for some targets we need room for an extra pointer - in the
- case of MIPS this is the global pointer. This makes a total of four
- pointers, but to be safe we actually allocate room for 5.
-
- If pointers are smaller than words then we allocate enough room for
- 5 words, just in case the backend needs this much room. For more
- discussion on this issue see:
- http://gcc.gnu.org/ml/gcc-patches/2014-05/msg00313.html. */
- if (POINTER_SIZE > BITS_PER_WORD)
- tmp = size_int (5 - 1);
- else
- tmp = size_int ((5 * BITS_PER_WORD / POINTER_SIZE) - 1);
-#endif
-
- tmp = build_index_type (tmp);
- tmp = build_array_type (ptr_type_node, tmp);
- f_jbuf = build_decl (BUILTINS_LOCATION,
- FIELD_DECL, get_identifier ("__jbuf"), tmp);
-#ifdef DONT_USE_BUILTIN_SETJMP
- /* We don't know what the alignment requirements of the
- runtime's jmp_buf has. Overestimate. */
- SET_DECL_ALIGN (f_jbuf, BIGGEST_ALIGNMENT);
- DECL_USER_ALIGN (f_jbuf) = 1;
-#endif
- DECL_FIELD_CONTEXT (f_jbuf) = sjlj_fc_type_node;
-
- TYPE_FIELDS (sjlj_fc_type_node) = f_prev;
- TREE_CHAIN (f_prev) = f_cs;
- TREE_CHAIN (f_cs) = f_data;
- TREE_CHAIN (f_data) = f_per;
- TREE_CHAIN (f_per) = f_lsda;
- TREE_CHAIN (f_lsda) = f_jbuf;
-
- layout_type (sjlj_fc_type_node);
-
- /* Cache the interesting field offsets so that we have
- easy access from rtl. */
- sjlj_fc_call_site_ofs
- = (tree_to_uhwi (DECL_FIELD_OFFSET (f_cs))
- + tree_to_uhwi (DECL_FIELD_BIT_OFFSET (f_cs)) / BITS_PER_UNIT);
- sjlj_fc_data_ofs
- = (tree_to_uhwi (DECL_FIELD_OFFSET (f_data))
- + tree_to_uhwi (DECL_FIELD_BIT_OFFSET (f_data)) / BITS_PER_UNIT);
- sjlj_fc_personality_ofs
- = (tree_to_uhwi (DECL_FIELD_OFFSET (f_per))
- + tree_to_uhwi (DECL_FIELD_BIT_OFFSET (f_per)) / BITS_PER_UNIT);
- sjlj_fc_lsda_ofs
- = (tree_to_uhwi (DECL_FIELD_OFFSET (f_lsda))
- + tree_to_uhwi (DECL_FIELD_BIT_OFFSET (f_lsda)) / BITS_PER_UNIT);
- sjlj_fc_jbuf_ofs
- = (tree_to_uhwi (DECL_FIELD_OFFSET (f_jbuf))
- + tree_to_uhwi (DECL_FIELD_BIT_OFFSET (f_jbuf)) / BITS_PER_UNIT);
-
-#ifdef DONT_USE_BUILTIN_SETJMP
- tmp = build_function_type_list (integer_type_node, TREE_TYPE (f_jbuf),
- NULL);
- setjmp_fn = build_decl (BUILTINS_LOCATION, FUNCTION_DECL,
- get_identifier ("setjmp"), tmp);
- TREE_PUBLIC (setjmp_fn) = 1;
- DECL_EXTERNAL (setjmp_fn) = 1;
- DECL_ASSEMBLER_NAME (setjmp_fn);
-#endif
- }
-}
-
-void
-init_eh_for_function (void)
-{
- cfun->eh = ggc_cleared_alloc<eh_status> ();
-
- /* Make sure zero'th entries are used. */
- vec_safe_push (cfun->eh->region_array, (eh_region)0);
- vec_safe_push (cfun->eh->lp_array, (eh_landing_pad)0);
-}
-
-/* Routines to generate the exception tree somewhat directly.
- These are used from tree-eh.c when processing exception related
- nodes during tree optimization. */
-
-static eh_region
-gen_eh_region (enum eh_region_type type, eh_region outer)
-{
- eh_region new_eh;
-
- /* Insert a new blank region as a leaf in the tree. */
- new_eh = ggc_cleared_alloc<eh_region_d> ();
- new_eh->type = type;
- new_eh->outer = outer;
- if (outer)
- {
- new_eh->next_peer = outer->inner;
- outer->inner = new_eh;
- }
- else
- {
- new_eh->next_peer = cfun->eh->region_tree;
- cfun->eh->region_tree = new_eh;
- }
-
- new_eh->index = vec_safe_length (cfun->eh->region_array);
- vec_safe_push (cfun->eh->region_array, new_eh);
-
- /* Copy the language's notion of whether to use __cxa_end_cleanup. */
- if (targetm.arm_eabi_unwinder && lang_hooks.eh_use_cxa_end_cleanup)
- new_eh->use_cxa_end_cleanup = true;
-
- return new_eh;
-}
-
-eh_region
-gen_eh_region_cleanup (eh_region outer)
-{
- return gen_eh_region (ERT_CLEANUP, outer);
-}
-
-eh_region
-gen_eh_region_try (eh_region outer)
-{
- return gen_eh_region (ERT_TRY, outer);
-}
-
-eh_catch
-gen_eh_region_catch (eh_region t, tree type_or_list)
-{
- eh_catch c, l;
- tree type_list, type_node;
-
- gcc_assert (t->type == ERT_TRY);
-
- /* Ensure to always end up with a type list to normalize further
- processing, then register each type against the runtime types map. */
- type_list = type_or_list;
- if (type_or_list)
- {
- if (TREE_CODE (type_or_list) != TREE_LIST)
- type_list = tree_cons (NULL_TREE, type_or_list, NULL_TREE);
-
- type_node = type_list;
- for (; type_node; type_node = TREE_CHAIN (type_node))
- add_type_for_runtime (TREE_VALUE (type_node));
- }
-
- c = ggc_cleared_alloc<eh_catch_d> ();
- c->type_list = type_list;
- l = t->u.eh_try.last_catch;
- c->prev_catch = l;
- if (l)
- l->next_catch = c;
- else
- t->u.eh_try.first_catch = c;
- t->u.eh_try.last_catch = c;
-
- return c;
-}
-
-eh_region
-gen_eh_region_allowed (eh_region outer, tree allowed)
-{
- eh_region region = gen_eh_region (ERT_ALLOWED_EXCEPTIONS, outer);
- region->u.allowed.type_list = allowed;
-
- for (; allowed ; allowed = TREE_CHAIN (allowed))
- add_type_for_runtime (TREE_VALUE (allowed));
-
- return region;
-}
-
-eh_region
-gen_eh_region_must_not_throw (eh_region outer)
-{
- return gen_eh_region (ERT_MUST_NOT_THROW, outer);
-}
-
-eh_landing_pad
-gen_eh_landing_pad (eh_region region)
-{
- eh_landing_pad lp = ggc_cleared_alloc<eh_landing_pad_d> ();
-
- lp->next_lp = region->landing_pads;
- lp->region = region;
- lp->index = vec_safe_length (cfun->eh->lp_array);
- region->landing_pads = lp;
-
- vec_safe_push (cfun->eh->lp_array, lp);
-
- return lp;
-}
-
-eh_region
-get_eh_region_from_number_fn (struct function *ifun, int i)
-{
- return (*ifun->eh->region_array)[i];
-}
-
-eh_region
-get_eh_region_from_number (int i)
-{
- return get_eh_region_from_number_fn (cfun, i);
-}
-
-eh_landing_pad
-get_eh_landing_pad_from_number_fn (struct function *ifun, int i)
-{
- return (*ifun->eh->lp_array)[i];
-}
-
-eh_landing_pad
-get_eh_landing_pad_from_number (int i)
-{
- return get_eh_landing_pad_from_number_fn (cfun, i);
-}
-
-eh_region
-get_eh_region_from_lp_number_fn (struct function *ifun, int i)
-{
- if (i < 0)
- return (*ifun->eh->region_array)[-i];
- else if (i == 0)
- return NULL;
- else
- {
- eh_landing_pad lp;
- lp = (*ifun->eh->lp_array)[i];
- return lp->region;
- }
-}
-
-eh_region
-get_eh_region_from_lp_number (int i)
-{
- return get_eh_region_from_lp_number_fn (cfun, i);
-}
-
-/* Returns true if the current function has exception handling regions. */
-
-bool
-current_function_has_exception_handlers (void)
-{
- return cfun->eh->region_tree != NULL;
-}
-
-/* A subroutine of duplicate_eh_regions. Copy the eh_region tree at OLD.
- Root it at OUTER, and apply LP_OFFSET to the lp numbers. */
-
-struct duplicate_eh_regions_data
-{
- duplicate_eh_regions_map label_map;
- void *label_map_data;
- hash_map<void *, void *> *eh_map;
-};
-
-static void
-duplicate_eh_regions_1 (struct duplicate_eh_regions_data *data,
- eh_region old_r, eh_region outer)
-{
- eh_landing_pad old_lp, new_lp;
- eh_region new_r;
-
- new_r = gen_eh_region (old_r->type, outer);
- gcc_assert (!data->eh_map->put (old_r, new_r));
-
- switch (old_r->type)
- {
- case ERT_CLEANUP:
- break;
-
- case ERT_TRY:
- {
- eh_catch oc, nc;
- for (oc = old_r->u.eh_try.first_catch; oc ; oc = oc->next_catch)
- {
- /* We should be doing all our region duplication before and
- during inlining, which is before filter lists are created. */
- gcc_assert (oc->filter_list == NULL);
- nc = gen_eh_region_catch (new_r, oc->type_list);
- nc->label = data->label_map (oc->label, data->label_map_data);
- }
- }
- break;
-
- case ERT_ALLOWED_EXCEPTIONS:
- new_r->u.allowed.type_list = old_r->u.allowed.type_list;
- if (old_r->u.allowed.label)
- new_r->u.allowed.label
- = data->label_map (old_r->u.allowed.label, data->label_map_data);
- else
- new_r->u.allowed.label = NULL_TREE;
- break;
-
- case ERT_MUST_NOT_THROW:
- new_r->u.must_not_throw.failure_loc =
- LOCATION_LOCUS (old_r->u.must_not_throw.failure_loc);
- new_r->u.must_not_throw.failure_decl =
- old_r->u.must_not_throw.failure_decl;
- break;
- }
-
- for (old_lp = old_r->landing_pads; old_lp ; old_lp = old_lp->next_lp)
- {
- /* Don't bother copying unused landing pads. */
- if (old_lp->post_landing_pad == NULL)
- continue;
-
- new_lp = gen_eh_landing_pad (new_r);
- gcc_assert (!data->eh_map->put (old_lp, new_lp));
-
- new_lp->post_landing_pad
- = data->label_map (old_lp->post_landing_pad, data->label_map_data);
- EH_LANDING_PAD_NR (new_lp->post_landing_pad) = new_lp->index;
- }
-
- /* Make sure to preserve the original use of __cxa_end_cleanup. */
- new_r->use_cxa_end_cleanup = old_r->use_cxa_end_cleanup;
-
- for (old_r = old_r->inner; old_r ; old_r = old_r->next_peer)
- duplicate_eh_regions_1 (data, old_r, new_r);
-}
-
-/* Duplicate the EH regions from IFUN rooted at COPY_REGION into
- the current function and root the tree below OUTER_REGION.
- The special case of COPY_REGION of NULL means all regions.
- Remap labels using MAP/MAP_DATA callback. Return a pointer map
- that allows the caller to remap uses of both EH regions and
- EH landing pads. */
-
-hash_map<void *, void *> *
-duplicate_eh_regions (struct function *ifun,
- eh_region copy_region, int outer_lp,
- duplicate_eh_regions_map map, void *map_data)
-{
- struct duplicate_eh_regions_data data;
- eh_region outer_region;
-
- if (flag_checking)
- verify_eh_tree (ifun);
-
- data.label_map = map;
- data.label_map_data = map_data;
- data.eh_map = new hash_map<void *, void *>;
-
- outer_region = get_eh_region_from_lp_number_fn (cfun, outer_lp);
-
- /* Copy all the regions in the subtree. */
- if (copy_region)
- duplicate_eh_regions_1 (&data, copy_region, outer_region);
- else
- {
- eh_region r;
- for (r = ifun->eh->region_tree; r ; r = r->next_peer)
- duplicate_eh_regions_1 (&data, r, outer_region);
- }
-
- if (flag_checking)
- verify_eh_tree (cfun);
-
- return data.eh_map;
-}
-
-/* Return the region that is outer to both REGION_A and REGION_B in IFUN. */
-
-eh_region
-eh_region_outermost (struct function *ifun, eh_region region_a,
- eh_region region_b)
-{
- gcc_assert (ifun->eh->region_array);
- gcc_assert (ifun->eh->region_tree);
-
- auto_sbitmap b_outer (ifun->eh->region_array->length ());
- bitmap_clear (b_outer);
-
- do
- {
- bitmap_set_bit (b_outer, region_b->index);
- region_b = region_b->outer;
- }
- while (region_b);
-
- do
- {
- if (bitmap_bit_p (b_outer, region_a->index))
- break;
- region_a = region_a->outer;
- }
- while (region_a);
-
- return region_a;
-}
-
-void
-add_type_for_runtime (tree type)
-{
- /* If TYPE is NOP_EXPR, it means that it already is a runtime type. */
- if (TREE_CODE (type) == NOP_EXPR)
- return;
-
- bool existed = false;
- tree *slot = &type_to_runtime_map->get_or_insert (type, &existed);
- if (!existed)
- *slot = lang_hooks.eh_runtime_type (type);
-}
-
-tree
-lookup_type_for_runtime (tree type)
-{
- /* If TYPE is NOP_EXPR, it means that it already is a runtime type. */
- if (TREE_CODE (type) == NOP_EXPR)
- return type;
-
- /* We should have always inserted the data earlier. */
- return *type_to_runtime_map->get (type);
-}
-
-
-/* Represent an entry in @TTypes for either catch actions
- or exception filter actions. */
-struct ttypes_filter {
- tree t;
- int filter;
-};
-
-/* Helper for ttypes_filter hashing. */
-
-struct ttypes_filter_hasher : free_ptr_hash <ttypes_filter>
-{
- typedef tree_node *compare_type;
- static inline hashval_t hash (const ttypes_filter *);
- static inline bool equal (const ttypes_filter *, const tree_node *);
-};
-
-/* Compare ENTRY (a ttypes_filter entry in the hash table) with DATA
- (a tree) for a @TTypes type node we are thinking about adding. */
-
-inline bool
-ttypes_filter_hasher::equal (const ttypes_filter *entry, const tree_node *data)
-{
- return entry->t == data;
-}
-
-inline hashval_t
-ttypes_filter_hasher::hash (const ttypes_filter *entry)
-{
- return TREE_HASH (entry->t);
-}
-
-typedef hash_table<ttypes_filter_hasher> ttypes_hash_type;
-
-
-/* Helper for ehspec hashing. */
-
-struct ehspec_hasher : free_ptr_hash <ttypes_filter>
-{
- static inline hashval_t hash (const ttypes_filter *);
- static inline bool equal (const ttypes_filter *, const ttypes_filter *);
-};
-
-/* Compare ENTRY with DATA (both struct ttypes_filter) for a @TTypes
- exception specification list we are thinking about adding. */
-/* ??? Currently we use the type lists in the order given. Someone
- should put these in some canonical order. */
-
-inline bool
-ehspec_hasher::equal (const ttypes_filter *entry, const ttypes_filter *data)
-{
- return type_list_equal (entry->t, data->t);
-}
-
-/* Hash function for exception specification lists. */
-
-inline hashval_t
-ehspec_hasher::hash (const ttypes_filter *entry)
-{
- hashval_t h = 0;
- tree list;
-
- for (list = entry->t; list ; list = TREE_CHAIN (list))
- h = (h << 5) + (h >> 27) + TREE_HASH (TREE_VALUE (list));
- return h;
-}
-
-typedef hash_table<ehspec_hasher> ehspec_hash_type;
-
-
-/* Add TYPE (which may be NULL) to cfun->eh->ttype_data, using TYPES_HASH
- to speed up the search. Return the filter value to be used. */
-
-static int
-add_ttypes_entry (ttypes_hash_type *ttypes_hash, tree type)
-{
- struct ttypes_filter **slot, *n;
-
- slot = ttypes_hash->find_slot_with_hash (type, (hashval_t) TREE_HASH (type),
- INSERT);
-
- if ((n = *slot) == NULL)
- {
- /* Filter value is a 1 based table index. */
-
- n = XNEW (struct ttypes_filter);
- n->t = type;
- n->filter = vec_safe_length (cfun->eh->ttype_data) + 1;
- *slot = n;
-
- vec_safe_push (cfun->eh->ttype_data, type);
- }
-
- return n->filter;
-}
-
-/* Add LIST to cfun->eh->ehspec_data, using EHSPEC_HASH and TYPES_HASH
- to speed up the search. Return the filter value to be used. */
-
-static int
-add_ehspec_entry (ehspec_hash_type *ehspec_hash, ttypes_hash_type *ttypes_hash,
- tree list)
-{
- struct ttypes_filter **slot, *n;
- struct ttypes_filter dummy;
-
- dummy.t = list;
- slot = ehspec_hash->find_slot (&dummy, INSERT);
-
- if ((n = *slot) == NULL)
- {
- int len;
-
- if (targetm.arm_eabi_unwinder)
- len = vec_safe_length (cfun->eh->ehspec_data.arm_eabi);
- else
- len = vec_safe_length (cfun->eh->ehspec_data.other);
-
- /* Filter value is a -1 based byte index into a uleb128 buffer. */
-
- n = XNEW (struct ttypes_filter);
- n->t = list;
- n->filter = -(len + 1);
- *slot = n;
-
- /* Generate a 0 terminated list of filter values. */
- for (; list ; list = TREE_CHAIN (list))
- {
- if (targetm.arm_eabi_unwinder)
- vec_safe_push (cfun->eh->ehspec_data.arm_eabi, TREE_VALUE (list));
- else
- {
- /* Look up each type in the list and encode its filter
- value as a uleb128. */
- push_uleb128 (&cfun->eh->ehspec_data.other,
- add_ttypes_entry (ttypes_hash, TREE_VALUE (list)));
- }
- }
- if (targetm.arm_eabi_unwinder)
- vec_safe_push (cfun->eh->ehspec_data.arm_eabi, NULL_TREE);
- else
- vec_safe_push (cfun->eh->ehspec_data.other, (uchar)0);
- }
-
- return n->filter;
-}
-
-/* Generate the action filter values to be used for CATCH and
- ALLOWED_EXCEPTIONS regions. When using dwarf2 exception regions,
- we use lots of landing pads, and so every type or list can share
- the same filter value, which saves table space. */
-
-void
-assign_filter_values (void)
-{
- int i;
- eh_region r;
- eh_catch c;
-
- vec_alloc (cfun->eh->ttype_data, 16);
- if (targetm.arm_eabi_unwinder)
- vec_alloc (cfun->eh->ehspec_data.arm_eabi, 64);
- else
- vec_alloc (cfun->eh->ehspec_data.other, 64);
-
- ehspec_hash_type ehspec (31);
- ttypes_hash_type ttypes (31);
-
- for (i = 1; vec_safe_iterate (cfun->eh->region_array, i, &r); ++i)
- {
- if (r == NULL)
- continue;
-
- switch (r->type)
- {
- case ERT_TRY:
- for (c = r->u.eh_try.first_catch; c ; c = c->next_catch)
- {
- /* Whatever type_list is (NULL or true list), we build a list
- of filters for the region. */
- c->filter_list = NULL_TREE;
-
- if (c->type_list != NULL)
- {
- /* Get a filter value for each of the types caught and store
- them in the region's dedicated list. */
- tree tp_node = c->type_list;
-
- for ( ; tp_node; tp_node = TREE_CHAIN (tp_node))
- {
- int flt
- = add_ttypes_entry (&ttypes, TREE_VALUE (tp_node));
- tree flt_node = build_int_cst (integer_type_node, flt);
-
- c->filter_list
- = tree_cons (NULL_TREE, flt_node, c->filter_list);
- }
- }
- else
- {
- /* Get a filter value for the NULL list also since it
- will need an action record anyway. */
- int flt = add_ttypes_entry (&ttypes, NULL);
- tree flt_node = build_int_cst (integer_type_node, flt);
-
- c->filter_list
- = tree_cons (NULL_TREE, flt_node, NULL);
- }
- }
- break;
-
- case ERT_ALLOWED_EXCEPTIONS:
- r->u.allowed.filter
- = add_ehspec_entry (&ehspec, &ttypes, r->u.allowed.type_list);
- break;
-
- default:
- break;
- }
- }
-}
-
-/* Emit SEQ into basic block just before INSN (that is assumed to be
- first instruction of some existing BB and return the newly
- produced block. */
-static basic_block
-emit_to_new_bb_before (rtx_insn *seq, rtx_insn *insn)
-{
- rtx_insn *next, *last;
- basic_block bb;
- edge e;
- edge_iterator ei;
-
- /* If there happens to be a fallthru edge (possibly created by cleanup_cfg
- call), we don't want it to go into newly created landing pad or other EH
- construct. */
- for (ei = ei_start (BLOCK_FOR_INSN (insn)->preds); (e = ei_safe_edge (ei)); )
- if (e->flags & EDGE_FALLTHRU)
- force_nonfallthru (e);
- else
- ei_next (&ei);
-
- /* Make sure to put the location of INSN or a subsequent instruction on SEQ
- to avoid inheriting the location of the previous instruction. */
- next = insn;
- while (next && !NONDEBUG_INSN_P (next))
- next = NEXT_INSN (next);
- if (next)
- last = emit_insn_before_setloc (seq, insn, INSN_LOCATION (next));
- else
- last = emit_insn_before (seq, insn);
- if (BARRIER_P (last))
- last = PREV_INSN (last);
- bb = create_basic_block (seq, last, BLOCK_FOR_INSN (insn)->prev_bb);
- update_bb_for_insn (bb);
- bb->flags |= BB_SUPERBLOCK;
- return bb;
-}
-
-/* A subroutine of dw2_build_landing_pads, also used for edge splitting
- at the rtl level. Emit the code required by the target at a landing
- pad for the given region. */
-
-static void
-expand_dw2_landing_pad_for_region (eh_region region)
-{
- if (targetm.have_exception_receiver ())
- emit_insn (targetm.gen_exception_receiver ());
- else if (targetm.have_nonlocal_goto_receiver ())
- emit_insn (targetm.gen_nonlocal_goto_receiver ());
- else
- { /* Nothing */ }
-
- if (region->exc_ptr_reg)
- emit_move_insn (region->exc_ptr_reg,
- gen_rtx_REG (ptr_mode, EH_RETURN_DATA_REGNO (0)));
- if (region->filter_reg)
- emit_move_insn (region->filter_reg,
- gen_rtx_REG (targetm.eh_return_filter_mode (),
- EH_RETURN_DATA_REGNO (1)));
-}
-
-/* Expand the extra code needed at landing pads for dwarf2 unwinding. */
-
-static void
-dw2_build_landing_pads (void)
-{
- int i;
- eh_landing_pad lp;
- int e_flags = EDGE_FALLTHRU;
-
- /* If we're going to partition blocks, we need to be able to add
- new landing pads later, which means that we need to hold on to
- the post-landing-pad block. Prevent it from being merged away.
- We'll remove this bit after partitioning. */
- if (flag_reorder_blocks_and_partition)
- e_flags |= EDGE_PRESERVE;
-
- for (i = 1; vec_safe_iterate (cfun->eh->lp_array, i, &lp); ++i)
- {
- basic_block bb;
- rtx_insn *seq;
-
- if (lp == NULL || lp->post_landing_pad == NULL)
- continue;
-
- start_sequence ();
-
- lp->landing_pad = gen_label_rtx ();
- emit_label (lp->landing_pad);
- LABEL_PRESERVE_P (lp->landing_pad) = 1;
-
- expand_dw2_landing_pad_for_region (lp->region);
-
- seq = get_insns ();
- end_sequence ();
-
- bb = emit_to_new_bb_before (seq, label_rtx (lp->post_landing_pad));
- bb->count = bb->next_bb->count;
- make_single_succ_edge (bb, bb->next_bb, e_flags);
- if (current_loops)
- {
- class loop *loop = bb->next_bb->loop_father;
- /* If we created a pre-header block, add the new block to the
- outer loop, otherwise to the loop itself. */
- if (bb->next_bb == loop->header)
- add_bb_to_loop (bb, loop_outer (loop));
- else
- add_bb_to_loop (bb, loop);
- }
- }
-}
-
-
-static vec<int> sjlj_lp_call_site_index;
-
-/* Process all active landing pads. Assign each one a compact dispatch
- index, and a call-site index. */
-
-static int
-sjlj_assign_call_site_values (void)
-{
- action_hash_type ar_hash (31);
- int i, disp_index;
- eh_landing_pad lp;
-
- vec_alloc (crtl->eh.action_record_data, 64);
-
- disp_index = 0;
- call_site_base = 1;
- for (i = 1; vec_safe_iterate (cfun->eh->lp_array, i, &lp); ++i)
- if (lp && lp->post_landing_pad)
- {
- int action, call_site;
-
- /* First: build the action table. */
- action = collect_one_action_chain (&ar_hash, lp->region);
-
- /* Next: assign call-site values. If dwarf2 terms, this would be
- the region number assigned by convert_to_eh_region_ranges, but
- handles no-action and must-not-throw differently. */
- /* Map must-not-throw to otherwise unused call-site index 0. */
- if (action == -2)
- call_site = 0;
- /* Map no-action to otherwise unused call-site index -1. */
- else if (action == -1)
- call_site = -1;
- /* Otherwise, look it up in the table. */
- else
- call_site = add_call_site (GEN_INT (disp_index), action, 0);
- sjlj_lp_call_site_index[i] = call_site;
-
- disp_index++;
- }
-
- return disp_index;
-}
-
-/* Emit code to record the current call-site index before every
- insn that can throw. */
-
-static void
-sjlj_mark_call_sites (void)
-{
- int last_call_site = -2;
- rtx_insn *insn;
- rtx mem;
-
- for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
- {
- eh_landing_pad lp;
- eh_region r;
- bool nothrow;
- int this_call_site;
- rtx_insn *before, *p;
-
- /* Reset value tracking at extended basic block boundaries. */
- if (LABEL_P (insn))
- last_call_site = -2;
-
- /* If the function allocates dynamic stack space, the context must
- be updated after every allocation/deallocation accordingly. */
- if (NOTE_P (insn) && NOTE_KIND (insn) == NOTE_INSN_UPDATE_SJLJ_CONTEXT)
- {
- rtx buf_addr;
-
- start_sequence ();
- buf_addr = plus_constant (Pmode, XEXP (crtl->eh.sjlj_fc, 0),
- sjlj_fc_jbuf_ofs);
- expand_builtin_update_setjmp_buf (buf_addr);
- p = get_insns ();
- end_sequence ();
- emit_insn_before (p, insn);
- }
-
- if (! INSN_P (insn))
- continue;
-
- nothrow = get_eh_region_and_lp_from_rtx (insn, &r, &lp);
- if (nothrow)
- continue;
- if (lp)
- this_call_site = sjlj_lp_call_site_index[lp->index];
- else if (r == NULL)
- {
- /* Calls (and trapping insns) without notes are outside any
- exception handling region in this function. Mark them as
- no action. */
- this_call_site = -1;
- }
- else
- {
- gcc_assert (r->type == ERT_MUST_NOT_THROW);
- this_call_site = 0;
- }
-
- if (this_call_site != -1)
- crtl->uses_eh_lsda = 1;
-
- if (this_call_site == last_call_site)
- continue;
-
- /* Don't separate a call from it's argument loads. */
- before = insn;
- if (CALL_P (insn))
- before = find_first_parameter_load (insn, NULL);
-
- start_sequence ();
- mem = adjust_address (crtl->eh.sjlj_fc, TYPE_MODE (integer_type_node),
- sjlj_fc_call_site_ofs);
- emit_move_insn (mem, gen_int_mode (this_call_site, GET_MODE (mem)));
- p = get_insns ();
- end_sequence ();
-
- emit_insn_before (p, before);
- last_call_site = this_call_site;
- }
-}
-
-/* Construct the SjLj_Function_Context. */
-
-static void
-sjlj_emit_function_enter (rtx_code_label *dispatch_label)
-{
- rtx_insn *fn_begin, *seq;
- rtx fc, mem;
- bool fn_begin_outside_block;
- rtx personality = get_personality_function (current_function_decl);
-
- fc = crtl->eh.sjlj_fc;
-
- start_sequence ();
-
- /* We're storing this libcall's address into memory instead of
- calling it directly. Thus, we must call assemble_external_libcall
- here, as we cannot depend on emit_library_call to do it for us. */
- assemble_external_libcall (personality);
- mem = adjust_address (fc, Pmode, sjlj_fc_personality_ofs);
- emit_move_insn (mem, personality);
-
- mem = adjust_address (fc, Pmode, sjlj_fc_lsda_ofs);
- if (crtl->uses_eh_lsda)
- {
- char buf[20];
- rtx sym;
-
- ASM_GENERATE_INTERNAL_LABEL (buf, "LLSDA", current_function_funcdef_no);
- sym = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
- SYMBOL_REF_FLAGS (sym) = SYMBOL_FLAG_LOCAL;
- emit_move_insn (mem, sym);
- }
- else
- emit_move_insn (mem, const0_rtx);
-
- if (dispatch_label)
- {
- rtx addr = plus_constant (Pmode, XEXP (fc, 0), sjlj_fc_jbuf_ofs);
-
-#ifdef DONT_USE_BUILTIN_SETJMP
- addr = copy_addr_to_reg (addr);
- addr = convert_memory_address (ptr_mode, addr);
- tree addr_tree = make_tree (ptr_type_node, addr);
-
- tree call_expr = build_call_expr (setjmp_fn, 1, addr_tree);
- rtx x = expand_call (call_expr, NULL_RTX, false);
-
- emit_cmp_and_jump_insns (x, const0_rtx, NE, 0,
- TYPE_MODE (integer_type_node), 0,
- dispatch_label,
- profile_probability::unlikely ());
-#else
- expand_builtin_setjmp_setup (addr, dispatch_label);
-#endif
- }
-
- emit_library_call (unwind_sjlj_register_libfunc, LCT_NORMAL, VOIDmode,
- XEXP (fc, 0), Pmode);
-
- seq = get_insns ();
- end_sequence ();
-
- /* ??? Instead of doing this at the beginning of the function,
- do this in a block that is at loop level 0 and dominates all
- can_throw_internal instructions. */
-
- fn_begin_outside_block = true;
- for (fn_begin = get_insns (); ; fn_begin = NEXT_INSN (fn_begin))
- if (NOTE_P (fn_begin))
- {
- if (NOTE_KIND (fn_begin) == NOTE_INSN_FUNCTION_BEG)
- break;
- else if (NOTE_INSN_BASIC_BLOCK_P (fn_begin))
- fn_begin_outside_block = false;
- }
-
-#ifdef DONT_USE_BUILTIN_SETJMP
- if (dispatch_label)
- {
- /* The sequence contains a branch in the middle so we need to force
- the creation of a new basic block by means of BB_SUPERBLOCK. */
- if (fn_begin_outside_block)
- {
- basic_block bb
- = split_edge (single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun)));
- if (JUMP_P (BB_END (bb)))
- emit_insn_before (seq, BB_END (bb));
- else
- emit_insn_after (seq, BB_END (bb));
- }
- else
- emit_insn_after (seq, fn_begin);
-
- single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun))->flags |= BB_SUPERBLOCK;
- return;
- }
-#endif
-
- if (fn_begin_outside_block)
- insert_insn_on_edge (seq, single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun)));
- else
- emit_insn_after (seq, fn_begin);
-}
-
-/* Call back from expand_function_end to know where we should put
- the call to unwind_sjlj_unregister_libfunc if needed. */
-
-void
-sjlj_emit_function_exit_after (rtx_insn *after)
-{
- crtl->eh.sjlj_exit_after = after;
-}
-
-static void
-sjlj_emit_function_exit (void)
-{
- rtx_insn *seq, *insn;
-
- start_sequence ();
-
- emit_library_call (unwind_sjlj_unregister_libfunc, LCT_NORMAL, VOIDmode,
- XEXP (crtl->eh.sjlj_fc, 0), Pmode);
-
- seq = get_insns ();
- end_sequence ();
-
- /* ??? Really this can be done in any block at loop level 0 that
- post-dominates all can_throw_internal instructions. This is
- the last possible moment. */
-
- insn = crtl->eh.sjlj_exit_after;
- if (LABEL_P (insn))
- insn = NEXT_INSN (insn);
-
- emit_insn_after (seq, insn);
-}
-
-static void
-sjlj_emit_dispatch_table (rtx_code_label *dispatch_label, int num_dispatch)
-{
- scalar_int_mode unwind_word_mode = targetm.unwind_word_mode ();
- scalar_int_mode filter_mode = targetm.eh_return_filter_mode ();
- eh_landing_pad lp;
- rtx mem, fc, exc_ptr_reg, filter_reg;
- rtx_insn *seq;
- basic_block bb;
- eh_region r;
- int i, disp_index;
- vec<tree> dispatch_labels = vNULL;
-
- fc = crtl->eh.sjlj_fc;
-
- start_sequence ();
-
- emit_label (dispatch_label);
-
-#ifndef DONT_USE_BUILTIN_SETJMP
- expand_builtin_setjmp_receiver (dispatch_label);
-
- /* The caller of expand_builtin_setjmp_receiver is responsible for
- making sure that the label doesn't vanish. The only other caller
- is the expander for __builtin_setjmp_receiver, which places this
- label on the nonlocal_goto_label list. Since we're modeling these
- CFG edges more exactly, we can use the forced_labels list instead. */
- LABEL_PRESERVE_P (dispatch_label) = 1;
- vec_safe_push<rtx_insn *> (forced_labels, dispatch_label);
-#endif
-
- /* Load up exc_ptr and filter values from the function context. */
- mem = adjust_address (fc, unwind_word_mode, sjlj_fc_data_ofs);
- if (unwind_word_mode != ptr_mode)
- {
-#ifdef POINTERS_EXTEND_UNSIGNED
- mem = convert_memory_address (ptr_mode, mem);
-#else
- mem = convert_to_mode (ptr_mode, mem, 0);
-#endif
- }
- exc_ptr_reg = force_reg (ptr_mode, mem);
-
- mem = adjust_address (fc, unwind_word_mode,
- sjlj_fc_data_ofs + GET_MODE_SIZE (unwind_word_mode));
- if (unwind_word_mode != filter_mode)
- mem = convert_to_mode (filter_mode, mem, 0);
- filter_reg = force_reg (filter_mode, mem);
-
- /* Jump to one of the directly reachable regions. */
-
- disp_index = 0;
- rtx_code_label *first_reachable_label = NULL;
-
- /* If there's exactly one call site in the function, don't bother
- generating a switch statement. */
- if (num_dispatch > 1)
- dispatch_labels.create (num_dispatch);
-
- for (i = 1; vec_safe_iterate (cfun->eh->lp_array, i, &lp); ++i)
- if (lp && lp->post_landing_pad)
- {
- rtx_insn *seq2;
- rtx_code_label *label;
-
- start_sequence ();
-
- lp->landing_pad = dispatch_label;
-
- if (num_dispatch > 1)
- {
- tree t_label, case_elt, t;
-
- t_label = create_artificial_label (UNKNOWN_LOCATION);
- t = build_int_cst (integer_type_node, disp_index);
- case_elt = build_case_label (t, NULL, t_label);
- dispatch_labels.quick_push (case_elt);
- label = jump_target_rtx (t_label);
- }
- else
- label = gen_label_rtx ();
-
- if (disp_index == 0)
- first_reachable_label = label;
- emit_label (label);
-
- r = lp->region;
- if (r->exc_ptr_reg)
- emit_move_insn (r->exc_ptr_reg, exc_ptr_reg);
- if (r->filter_reg)
- emit_move_insn (r->filter_reg, filter_reg);
-
- seq2 = get_insns ();
- end_sequence ();
-
- rtx_insn *before = label_rtx (lp->post_landing_pad);
- bb = emit_to_new_bb_before (seq2, before);
- make_single_succ_edge (bb, bb->next_bb, EDGE_FALLTHRU);
- if (current_loops)
- {
- class loop *loop = bb->next_bb->loop_father;
- /* If we created a pre-header block, add the new block to the
- outer loop, otherwise to the loop itself. */
- if (bb->next_bb == loop->header)
- add_bb_to_loop (bb, loop_outer (loop));
- else
- add_bb_to_loop (bb, loop);
- /* ??? For multiple dispatches we will end up with edges
- from the loop tree root into this loop, making it a
- multiple-entry loop. Discard all affected loops. */
- if (num_dispatch > 1)
- {
- for (loop = bb->loop_father;
- loop_outer (loop); loop = loop_outer (loop))
- mark_loop_for_removal (loop);
- }
- }
-
- disp_index++;
- }
- gcc_assert (disp_index == num_dispatch);
-
- if (num_dispatch > 1)
- {
- rtx disp = adjust_address (fc, TYPE_MODE (integer_type_node),
- sjlj_fc_call_site_ofs);
- expand_sjlj_dispatch_table (disp, dispatch_labels);
- }
-
- seq = get_insns ();
- end_sequence ();
-
- bb = emit_to_new_bb_before (seq, first_reachable_label);
- if (num_dispatch == 1)
- {
- make_single_succ_edge (bb, bb->next_bb, EDGE_FALLTHRU);
- if (current_loops)
- {
- class loop *loop = bb->next_bb->loop_father;
- /* If we created a pre-header block, add the new block to the
- outer loop, otherwise to the loop itself. */
- if (bb->next_bb == loop->header)
- add_bb_to_loop (bb, loop_outer (loop));
- else
- add_bb_to_loop (bb, loop);
- }
- }
- else
- {
- /* We are not wiring up edges here, but as the dispatcher call
- is at function begin simply associate the block with the
- outermost (non-)loop. */
- if (current_loops)
- add_bb_to_loop (bb, current_loops->tree_root);
- }
-}
-
-static void
-sjlj_build_landing_pads (void)
-{
- int num_dispatch;
-
- num_dispatch = vec_safe_length (cfun->eh->lp_array);
- if (num_dispatch == 0)
- return;
- sjlj_lp_call_site_index.safe_grow_cleared (num_dispatch, true);
-
- num_dispatch = sjlj_assign_call_site_values ();
- if (num_dispatch > 0)
- {
- rtx_code_label *dispatch_label = gen_label_rtx ();
- int align = STACK_SLOT_ALIGNMENT (sjlj_fc_type_node,
- TYPE_MODE (sjlj_fc_type_node),
- TYPE_ALIGN (sjlj_fc_type_node));
- crtl->eh.sjlj_fc
- = assign_stack_local (TYPE_MODE (sjlj_fc_type_node),
- int_size_in_bytes (sjlj_fc_type_node),
- align);
-
- sjlj_mark_call_sites ();
- sjlj_emit_function_enter (dispatch_label);
- sjlj_emit_dispatch_table (dispatch_label, num_dispatch);
- sjlj_emit_function_exit ();
- }
-
- /* If we do not have any landing pads, we may still need to register a
- personality routine and (empty) LSDA to handle must-not-throw regions. */
- else if (function_needs_eh_personality (cfun) != eh_personality_none)
- {
- int align = STACK_SLOT_ALIGNMENT (sjlj_fc_type_node,
- TYPE_MODE (sjlj_fc_type_node),
- TYPE_ALIGN (sjlj_fc_type_node));
- crtl->eh.sjlj_fc
- = assign_stack_local (TYPE_MODE (sjlj_fc_type_node),
- int_size_in_bytes (sjlj_fc_type_node),
- align);
-
- sjlj_mark_call_sites ();
- sjlj_emit_function_enter (NULL);
- sjlj_emit_function_exit ();
- }
-
- sjlj_lp_call_site_index.release ();
-}
-
-/* Update the sjlj function context. This function should be called
- whenever we allocate or deallocate dynamic stack space. */
-
-void
-update_sjlj_context (void)
-{
- if (!flag_exceptions)
- return;
-
- emit_note (NOTE_INSN_UPDATE_SJLJ_CONTEXT);
-}
-
-/* After initial rtl generation, call back to finish generating
- exception support code. */
-
-void
-finish_eh_generation (void)
-{
- basic_block bb;
-
- /* Construct the landing pads. */
- if (targetm_common.except_unwind_info (&global_options) == UI_SJLJ)
- sjlj_build_landing_pads ();
- else
- dw2_build_landing_pads ();
-
- break_superblocks ();
-
- /* Redirect all EH edges from the post_landing_pad to the landing pad. */
- FOR_EACH_BB_FN (bb, cfun)
- {
- eh_landing_pad lp;
- edge_iterator ei;
- edge e;
-
- lp = get_eh_landing_pad_from_rtx (BB_END (bb));
-
- FOR_EACH_EDGE (e, ei, bb->succs)
- if (e->flags & EDGE_EH)
- break;
-
- /* We should not have generated any new throwing insns during this
- pass, and we should not have lost any EH edges, so we only need
- to handle two cases here:
- (1) reachable handler and an existing edge to post-landing-pad,
- (2) no reachable handler and no edge. */
- gcc_assert ((lp != NULL) == (e != NULL));
- if (lp != NULL)
- {
- gcc_assert (BB_HEAD (e->dest) == label_rtx (lp->post_landing_pad));
-
- redirect_edge_succ (e, BLOCK_FOR_INSN (lp->landing_pad));
- e->flags |= (CALL_P (BB_END (bb))
- ? EDGE_ABNORMAL | EDGE_ABNORMAL_CALL
- : EDGE_ABNORMAL);
- }
- }
-
- if (targetm_common.except_unwind_info (&global_options) == UI_SJLJ
- /* Kludge for Alpha (see alpha_gp_save_rtx). */
- || single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun))->insns.r)
- commit_edge_insertions ();
-}
-
-/* This section handles removing dead code for flow. */
-
-void
-remove_eh_landing_pad (eh_landing_pad lp)
-{
- eh_landing_pad *pp;
-
- for (pp = &lp->region->landing_pads; *pp != lp; pp = &(*pp)->next_lp)
- continue;
- *pp = lp->next_lp;
-
- if (lp->post_landing_pad)
- EH_LANDING_PAD_NR (lp->post_landing_pad) = 0;
- (*cfun->eh->lp_array)[lp->index] = NULL;
-}
-
-/* Splice the EH region at PP from the region tree. */
-
-static void
-remove_eh_handler_splicer (eh_region *pp)
-{
- eh_region region = *pp;
- eh_landing_pad lp;
-
- for (lp = region->landing_pads; lp ; lp = lp->next_lp)
- {
- if (lp->post_landing_pad)
- EH_LANDING_PAD_NR (lp->post_landing_pad) = 0;
- (*cfun->eh->lp_array)[lp->index] = NULL;
- }
-
- if (region->inner)
- {
- eh_region p, outer;
- outer = region->outer;
-
- *pp = p = region->inner;
- do
- {
- p->outer = outer;
- pp = &p->next_peer;
- p = *pp;
- }
- while (p);
- }
- *pp = region->next_peer;
-
- (*cfun->eh->region_array)[region->index] = NULL;
-}
-
-/* Splice a single EH region REGION from the region tree.
-
- To unlink REGION, we need to find the pointer to it with a relatively
- expensive search in REGION's outer region. If you are going to
- remove a number of handlers, using remove_unreachable_eh_regions may
- be a better option. */
-
-void
-remove_eh_handler (eh_region region)
-{
- eh_region *pp, *pp_start, p, outer;
-
- outer = region->outer;
- if (outer)
- pp_start = &outer->inner;
- else
- pp_start = &cfun->eh->region_tree;
- for (pp = pp_start, p = *pp; p != region; pp = &p->next_peer, p = *pp)
- continue;
-
- remove_eh_handler_splicer (pp);
-}
-
-/* Worker for remove_unreachable_eh_regions.
- PP is a pointer to the region to start a region tree depth-first
- search from. R_REACHABLE is the set of regions that have to be
- preserved. */
-
-static void
-remove_unreachable_eh_regions_worker (eh_region *pp, sbitmap r_reachable)
-{
- while (*pp)
- {
- eh_region region = *pp;
- remove_unreachable_eh_regions_worker (&region->inner, r_reachable);
- if (!bitmap_bit_p (r_reachable, region->index))
- remove_eh_handler_splicer (pp);
- else
- pp = &region->next_peer;
- }
-}
-
-/* Splice all EH regions *not* marked in R_REACHABLE from the region tree.
- Do this by traversing the EH tree top-down and splice out regions that
- are not marked. By removing regions from the leaves, we avoid costly
- searches in the region tree. */
-
-void
-remove_unreachable_eh_regions (sbitmap r_reachable)
-{
- remove_unreachable_eh_regions_worker (&cfun->eh->region_tree, r_reachable);
-}
-
-/* Invokes CALLBACK for every exception handler landing pad label.
- Only used by reload hackery; should not be used by new code. */
-
-void
-for_each_eh_label (void (*callback) (rtx))
-{
- eh_landing_pad lp;
- int i;
-
- for (i = 1; vec_safe_iterate (cfun->eh->lp_array, i, &lp); ++i)
- {
- if (lp)
- {
- rtx_code_label *lab = lp->landing_pad;
- if (lab && LABEL_P (lab))
- (*callback) (lab);
- }
- }
-}
-
-/* Create the REG_EH_REGION note for INSN, given its ECF_FLAGS for a
- call insn.
-
- At the gimple level, we use LP_NR
- > 0 : The statement transfers to landing pad LP_NR
- = 0 : The statement is outside any EH region
- < 0 : The statement is within MUST_NOT_THROW region -LP_NR.
-
- At the rtl level, we use LP_NR
- > 0 : The insn transfers to landing pad LP_NR
- = 0 : The insn cannot throw
- < 0 : The insn is within MUST_NOT_THROW region -LP_NR
- = INT_MIN : The insn cannot throw or execute a nonlocal-goto.
- missing note: The insn is outside any EH region.
-
- ??? This difference probably ought to be avoided. We could stand
- to record nothrow for arbitrary gimple statements, and so avoid
- some moderately complex lookups in stmt_could_throw_p. Perhaps
- NOTHROW should be mapped on both sides to INT_MIN. Perhaps the
- no-nonlocal-goto property should be recorded elsewhere as a bit
- on the call_insn directly. Perhaps we should make more use of
- attaching the trees to call_insns (reachable via symbol_ref in
- direct call cases) and just pull the data out of the trees. */
-
-void
-make_reg_eh_region_note (rtx_insn *insn, int ecf_flags, int lp_nr)
-{
- rtx value;
- if (ecf_flags & ECF_NOTHROW)
- value = const0_rtx;
- else if (lp_nr != 0)
- value = GEN_INT (lp_nr);
- else
- return;
- add_reg_note (insn, REG_EH_REGION, value);
-}
-
-/* Create a REG_EH_REGION note for a CALL_INSN that cannot throw
- nor perform a non-local goto. Replace the region note if it
- already exists. */
-
-void
-make_reg_eh_region_note_nothrow_nononlocal (rtx_insn *insn)
-{
- rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
- rtx intmin = GEN_INT (INT_MIN);
-
- if (note != 0)
- XEXP (note, 0) = intmin;
- else
- add_reg_note (insn, REG_EH_REGION, intmin);
-}
-
-/* Return true if INSN could throw, assuming no REG_EH_REGION note
- to the contrary. */
-
-bool
-insn_could_throw_p (const_rtx insn)
-{
- if (!flag_exceptions)
- return false;
- if (CALL_P (insn))
- return true;
- if (INSN_P (insn) && cfun->can_throw_non_call_exceptions)
- return may_trap_p (PATTERN (insn));
- return false;
-}
-
-/* Copy an REG_EH_REGION note to each insn that might throw beginning
- at FIRST and ending at LAST. NOTE_OR_INSN is either the source insn
- to look for a note, or the note itself. */
-
-void
-copy_reg_eh_region_note_forward (rtx note_or_insn, rtx_insn *first, rtx last)
-{
- rtx_insn *insn;
- rtx note = note_or_insn;
-
- if (INSN_P (note_or_insn))
- {
- note = find_reg_note (note_or_insn, REG_EH_REGION, NULL_RTX);
- if (note == NULL)
- return;
- }
- else if (is_a <rtx_insn *> (note_or_insn))
- return;
- note = XEXP (note, 0);
-
- for (insn = first; insn != last ; insn = NEXT_INSN (insn))
- if (!find_reg_note (insn, REG_EH_REGION, NULL_RTX)
- && insn_could_throw_p (insn))
- add_reg_note (insn, REG_EH_REGION, note);
-}
-
-/* Likewise, but iterate backward. */
-
-void
-copy_reg_eh_region_note_backward (rtx note_or_insn, rtx_insn *last, rtx first)
-{
- rtx_insn *insn;
- rtx note = note_or_insn;
-
- if (INSN_P (note_or_insn))
- {
- note = find_reg_note (note_or_insn, REG_EH_REGION, NULL_RTX);
- if (note == NULL)
- return;
- }
- else if (is_a <rtx_insn *> (note_or_insn))
- return;
- note = XEXP (note, 0);
-
- for (insn = last; insn != first; insn = PREV_INSN (insn))
- if (insn_could_throw_p (insn))
- add_reg_note (insn, REG_EH_REGION, note);
-}
-
-
-/* Extract all EH information from INSN. Return true if the insn
- was marked NOTHROW. */
-
-static bool
-get_eh_region_and_lp_from_rtx (const_rtx insn, eh_region *pr,
- eh_landing_pad *plp)
-{
- eh_landing_pad lp = NULL;
- eh_region r = NULL;
- bool ret = false;
- rtx note;
- int lp_nr;
-
- if (! INSN_P (insn))
- goto egress;
-
- if (NONJUMP_INSN_P (insn)
- && GET_CODE (PATTERN (insn)) == SEQUENCE)
- insn = XVECEXP (PATTERN (insn), 0, 0);
-
- note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
- if (!note)
- {
- ret = !insn_could_throw_p (insn);
- goto egress;
- }
-
- lp_nr = INTVAL (XEXP (note, 0));
- if (lp_nr == 0 || lp_nr == INT_MIN)
- {
- ret = true;
- goto egress;
- }
-
- if (lp_nr < 0)
- r = (*cfun->eh->region_array)[-lp_nr];
- else
- {
- lp = (*cfun->eh->lp_array)[lp_nr];
- r = lp->region;
- }
-
- egress:
- *plp = lp;
- *pr = r;
- return ret;
-}
-
-/* Return the landing pad to which INSN may go, or NULL if it does not
- have a reachable landing pad within this function. */
-
-eh_landing_pad
-get_eh_landing_pad_from_rtx (const_rtx insn)
-{
- eh_landing_pad lp;
- eh_region r;
-
- get_eh_region_and_lp_from_rtx (insn, &r, &lp);
- return lp;
-}
-
-/* Return the region to which INSN may go, or NULL if it does not
- have a reachable region within this function. */
-
-eh_region
-get_eh_region_from_rtx (const_rtx insn)
-{
- eh_landing_pad lp;
- eh_region r;
-
- get_eh_region_and_lp_from_rtx (insn, &r, &lp);
- return r;
-}
-
-/* Return true if INSN throws and is caught by something in this function. */
-
-bool
-can_throw_internal (const_rtx insn)
-{
- return get_eh_landing_pad_from_rtx (insn) != NULL;
-}
-
-/* Return true if INSN throws and escapes from the current function. */
-
-bool
-can_throw_external (const_rtx insn)
-{
- eh_landing_pad lp;
- eh_region r;
- bool nothrow;
-
- if (! INSN_P (insn))
- return false;
-
- if (NONJUMP_INSN_P (insn)
- && GET_CODE (PATTERN (insn)) == SEQUENCE)
- {
- rtx_sequence *seq = as_a <rtx_sequence *> (PATTERN (insn));
- int i, n = seq->len ();
-
- for (i = 0; i < n; i++)
- if (can_throw_external (seq->element (i)))
- return true;
-
- return false;
- }
-
- nothrow = get_eh_region_and_lp_from_rtx (insn, &r, &lp);
-
- /* If we can't throw, we obviously can't throw external. */
- if (nothrow)
- return false;
-
- /* If we have an internal landing pad, then we're not external. */
- if (lp != NULL)
- return false;
-
- /* If we're not within an EH region, then we are external. */
- if (r == NULL)
- return true;
-
- /* The only thing that ought to be left is MUST_NOT_THROW regions,
- which don't always have landing pads. */
- gcc_assert (r->type == ERT_MUST_NOT_THROW);
- return false;
-}
-
-/* Return true if INSN cannot throw at all. */
-
-bool
-insn_nothrow_p (const_rtx insn)
-{
- eh_landing_pad lp;
- eh_region r;
-
- if (! INSN_P (insn))
- return true;
-
- if (NONJUMP_INSN_P (insn)
- && GET_CODE (PATTERN (insn)) == SEQUENCE)
- {
- rtx_sequence *seq = as_a <rtx_sequence *> (PATTERN (insn));
- int i, n = seq->len ();
-
- for (i = 0; i < n; i++)
- if (!insn_nothrow_p (seq->element (i)))
- return false;
-
- return true;
- }
-
- return get_eh_region_and_lp_from_rtx (insn, &r, &lp);
-}
-
-/* Return true if INSN can perform a non-local goto. */
-/* ??? This test is here in this file because it (ab)uses REG_EH_REGION. */
-
-bool
-can_nonlocal_goto (const rtx_insn *insn)
-{
- if (nonlocal_goto_handler_labels && CALL_P (insn))
- {
- rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
- if (!note || INTVAL (XEXP (note, 0)) != INT_MIN)
- return true;
- }
- return false;
-}
-
-/* Set TREE_NOTHROW and crtl->all_throwers_are_sibcalls. */
-
-static unsigned int
-set_nothrow_function_flags (void)
-{
- rtx_insn *insn;
-
- crtl->nothrow = 1;
-
- /* Assume crtl->all_throwers_are_sibcalls until we encounter
- something that can throw an exception. We specifically exempt
- CALL_INSNs that are SIBLING_CALL_P, as these are really jumps,
- and can't throw. Most CALL_INSNs are not SIBLING_CALL_P, so this
- is optimistic. */
-
- crtl->all_throwers_are_sibcalls = 1;
-
- /* If we don't know that this implementation of the function will
- actually be used, then we must not set TREE_NOTHROW, since
- callers must not assume that this function does not throw. */
- if (TREE_NOTHROW (current_function_decl))
- return 0;
-
- if (! flag_exceptions)
- return 0;
-
- for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
- if (can_throw_external (insn))
- {
- crtl->nothrow = 0;
-
- if (!CALL_P (insn) || !SIBLING_CALL_P (insn))
- {
- crtl->all_throwers_are_sibcalls = 0;
- return 0;
- }
- }
-
- if (crtl->nothrow
- && (cgraph_node::get (current_function_decl)->get_availability ()
- >= AVAIL_AVAILABLE))
- {
- struct cgraph_node *node = cgraph_node::get (current_function_decl);
- struct cgraph_edge *e;
- for (e = node->callers; e; e = e->next_caller)
- e->can_throw_external = false;
- node->set_nothrow_flag (true);
-
- if (dump_file)
- fprintf (dump_file, "Marking function nothrow: %s\n\n",
- current_function_name ());
- }
- return 0;
-}
-
-namespace {
-
-const pass_data pass_data_set_nothrow_function_flags =
-{
- RTL_PASS, /* type */
- "nothrow", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- TV_NONE, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0, /* todo_flags_finish */
-};
-
-class pass_set_nothrow_function_flags : public rtl_opt_pass
-{
-public:
- pass_set_nothrow_function_flags (gcc::context *ctxt)
- : rtl_opt_pass (pass_data_set_nothrow_function_flags, ctxt)
- {}
-
- /* opt_pass methods: */
- virtual unsigned int execute (function *)
- {
- return set_nothrow_function_flags ();
- }
-
-}; // class pass_set_nothrow_function_flags
-
-} // anon namespace
-
-rtl_opt_pass *
-make_pass_set_nothrow_function_flags (gcc::context *ctxt)
-{
- return new pass_set_nothrow_function_flags (ctxt);
-}
-
-
-/* Various hooks for unwind library. */
-
-/* Expand the EH support builtin functions:
- __builtin_eh_pointer and __builtin_eh_filter. */
-
-static eh_region
-expand_builtin_eh_common (tree region_nr_t)
-{
- HOST_WIDE_INT region_nr;
- eh_region region;
-
- gcc_assert (tree_fits_shwi_p (region_nr_t));
- region_nr = tree_to_shwi (region_nr_t);
-
- region = (*cfun->eh->region_array)[region_nr];
-
- /* ??? We shouldn't have been able to delete a eh region without
- deleting all the code that depended on it. */
- gcc_assert (region != NULL);
-
- return region;
-}
-
-/* Expand to the exc_ptr value from the given eh region. */
-
-rtx
-expand_builtin_eh_pointer (tree exp)
-{
- eh_region region
- = expand_builtin_eh_common (CALL_EXPR_ARG (exp, 0));
- if (region->exc_ptr_reg == NULL)
- region->exc_ptr_reg = gen_reg_rtx (ptr_mode);
- return region->exc_ptr_reg;
-}
-
-/* Expand to the filter value from the given eh region. */
-
-rtx
-expand_builtin_eh_filter (tree exp)
-{
- eh_region region
- = expand_builtin_eh_common (CALL_EXPR_ARG (exp, 0));
- if (region->filter_reg == NULL)
- region->filter_reg = gen_reg_rtx (targetm.eh_return_filter_mode ());
- return region->filter_reg;
-}
-
-/* Copy the exc_ptr and filter values from one landing pad's registers
- to another. This is used to inline the resx statement. */
-
-rtx
-expand_builtin_eh_copy_values (tree exp)
-{
- eh_region dst
- = expand_builtin_eh_common (CALL_EXPR_ARG (exp, 0));
- eh_region src
- = expand_builtin_eh_common (CALL_EXPR_ARG (exp, 1));
- scalar_int_mode fmode = targetm.eh_return_filter_mode ();
-
- if (dst->exc_ptr_reg == NULL)
- dst->exc_ptr_reg = gen_reg_rtx (ptr_mode);
- if (src->exc_ptr_reg == NULL)
- src->exc_ptr_reg = gen_reg_rtx (ptr_mode);
-
- if (dst->filter_reg == NULL)
- dst->filter_reg = gen_reg_rtx (fmode);
- if (src->filter_reg == NULL)
- src->filter_reg = gen_reg_rtx (fmode);
-
- emit_move_insn (dst->exc_ptr_reg, src->exc_ptr_reg);
- emit_move_insn (dst->filter_reg, src->filter_reg);
-
- return const0_rtx;
-}
-
-/* Do any necessary initialization to access arbitrary stack frames.
- On the SPARC, this means flushing the register windows. */
-
-void
-expand_builtin_unwind_init (void)
-{
- /* Set this so all the registers get saved in our frame; we need to be
- able to copy the saved values for any registers from frames we unwind. */
- crtl->saves_all_registers = 1;
-
- SETUP_FRAME_ADDRESSES ();
-}
-
-/* Map a non-negative number to an eh return data register number; expands
- to -1 if no return data register is associated with the input number.
- At least the inputs 0 and 1 must be mapped; the target may provide more. */
-
-rtx
-expand_builtin_eh_return_data_regno (tree exp)
-{
- tree which = CALL_EXPR_ARG (exp, 0);
- unsigned HOST_WIDE_INT iwhich;
-
- if (TREE_CODE (which) != INTEGER_CST)
- {
- error ("argument of %<__builtin_eh_return_regno%> must be constant");
- return constm1_rtx;
- }
-
- iwhich = tree_to_uhwi (which);
- iwhich = EH_RETURN_DATA_REGNO (iwhich);
- if (iwhich == INVALID_REGNUM)
- return constm1_rtx;
-
-#ifdef DWARF_FRAME_REGNUM
- iwhich = DWARF_FRAME_REGNUM (iwhich);
-#else
- iwhich = DBX_REGISTER_NUMBER (iwhich);
-#endif
-
- return GEN_INT (iwhich);
-}
-
-/* Given a value extracted from the return address register or stack slot,
- return the actual address encoded in that value. */
-
-rtx
-expand_builtin_extract_return_addr (tree addr_tree)
-{
- rtx addr = expand_expr (addr_tree, NULL_RTX, Pmode, EXPAND_NORMAL);
-
- if (GET_MODE (addr) != Pmode
- && GET_MODE (addr) != VOIDmode)
- {
-#ifdef POINTERS_EXTEND_UNSIGNED
- addr = convert_memory_address (Pmode, addr);
-#else
- addr = convert_to_mode (Pmode, addr, 0);
-#endif
- }
-
- /* First mask out any unwanted bits. */
- rtx mask = MASK_RETURN_ADDR;
- if (mask)
- expand_and (Pmode, addr, mask, addr);
-
- /* Then adjust to find the real return address. */
- if (RETURN_ADDR_OFFSET)
- addr = plus_constant (Pmode, addr, RETURN_ADDR_OFFSET);
-
- return addr;
-}
-
-/* Given an actual address in addr_tree, do any necessary encoding
- and return the value to be stored in the return address register or
- stack slot so the epilogue will return to that address. */
-
-rtx
-expand_builtin_frob_return_addr (tree addr_tree)
-{
- rtx addr = expand_expr (addr_tree, NULL_RTX, ptr_mode, EXPAND_NORMAL);
-
- addr = convert_memory_address (Pmode, addr);
-
- if (RETURN_ADDR_OFFSET)
- {
- addr = force_reg (Pmode, addr);
- addr = plus_constant (Pmode, addr, -RETURN_ADDR_OFFSET);
- }
-
- return addr;
-}
-
-/* Set up the epilogue with the magic bits we'll need to return to the
- exception handler. */
-
-void
-expand_builtin_eh_return (tree stackadj_tree ATTRIBUTE_UNUSED,
- tree handler_tree)
-{
- rtx tmp;
-
-#ifdef EH_RETURN_STACKADJ_RTX
- tmp = expand_expr (stackadj_tree, crtl->eh.ehr_stackadj,
- VOIDmode, EXPAND_NORMAL);
- tmp = convert_memory_address (Pmode, tmp);
- if (!crtl->eh.ehr_stackadj)
- crtl->eh.ehr_stackadj = copy_addr_to_reg (tmp);
- else if (tmp != crtl->eh.ehr_stackadj)
- emit_move_insn (crtl->eh.ehr_stackadj, tmp);
-#endif
-
- tmp = expand_expr (handler_tree, crtl->eh.ehr_handler,
- VOIDmode, EXPAND_NORMAL);
- tmp = convert_memory_address (Pmode, tmp);
- if (!crtl->eh.ehr_handler)
- crtl->eh.ehr_handler = copy_addr_to_reg (tmp);
- else if (tmp != crtl->eh.ehr_handler)
- emit_move_insn (crtl->eh.ehr_handler, tmp);
-
- if (!crtl->eh.ehr_label)
- crtl->eh.ehr_label = gen_label_rtx ();
- emit_jump (crtl->eh.ehr_label);
-}
-
-/* Expand __builtin_eh_return. This exit path from the function loads up
- the eh return data registers, adjusts the stack, and branches to a
- given PC other than the normal return address. */
-
-void
-expand_eh_return (void)
-{
- rtx_code_label *around_label;
-
- if (! crtl->eh.ehr_label)
- return;
-
- crtl->calls_eh_return = 1;
-
-#ifdef EH_RETURN_STACKADJ_RTX
- emit_move_insn (EH_RETURN_STACKADJ_RTX, const0_rtx);
-#endif
-
- around_label = gen_label_rtx ();
- emit_jump (around_label);
-
- emit_label (crtl->eh.ehr_label);
- clobber_return_register ();
-
-#ifdef EH_RETURN_STACKADJ_RTX
- emit_move_insn (EH_RETURN_STACKADJ_RTX, crtl->eh.ehr_stackadj);
-#endif
-
- if (targetm.have_eh_return ())
- emit_insn (targetm.gen_eh_return (crtl->eh.ehr_handler));
- else
- {
- if (rtx handler = EH_RETURN_HANDLER_RTX)
- emit_move_insn (handler, crtl->eh.ehr_handler);
- else
- error ("%<__builtin_eh_return%> not supported on this target");
- }
-
- emit_label (around_label);
-}
-
-/* Convert a ptr_mode address ADDR_TREE to a Pmode address controlled by
- POINTERS_EXTEND_UNSIGNED and return it. */
-
-rtx
-expand_builtin_extend_pointer (tree addr_tree)
-{
- rtx addr = expand_expr (addr_tree, NULL_RTX, ptr_mode, EXPAND_NORMAL);
- int extend;
-
-#ifdef POINTERS_EXTEND_UNSIGNED
- extend = POINTERS_EXTEND_UNSIGNED;
-#else
- /* The previous EH code did an unsigned extend by default, so we do this also
- for consistency. */
- extend = 1;
-#endif
-
- return convert_modes (targetm.unwind_word_mode (), ptr_mode, addr, extend);
-}
-
-static int
-add_action_record (action_hash_type *ar_hash, int filter, int next)
-{
- struct action_record **slot, *new_ar, tmp;
-
- tmp.filter = filter;
- tmp.next = next;
- slot = ar_hash->find_slot (&tmp, INSERT);
-
- if ((new_ar = *slot) == NULL)
- {
- new_ar = XNEW (struct action_record);
- new_ar->offset = crtl->eh.action_record_data->length () + 1;
- new_ar->filter = filter;
- new_ar->next = next;
- *slot = new_ar;
-
- /* The filter value goes in untouched. The link to the next
- record is a "self-relative" byte offset, or zero to indicate
- that there is no next record. So convert the absolute 1 based
- indices we've been carrying around into a displacement. */
-
- push_sleb128 (&crtl->eh.action_record_data, filter);
- if (next)
- next -= crtl->eh.action_record_data->length () + 1;
- push_sleb128 (&crtl->eh.action_record_data, next);
- }
-
- return new_ar->offset;
-}
-
-static int
-collect_one_action_chain (action_hash_type *ar_hash, eh_region region)
-{
- int next;
-
- /* If we've reached the top of the region chain, then we have
- no actions, and require no landing pad. */
- if (region == NULL)
- return -1;
-
- switch (region->type)
- {
- case ERT_CLEANUP:
- {
- eh_region r;
- /* A cleanup adds a zero filter to the beginning of the chain, but
- there are special cases to look out for. If there are *only*
- cleanups along a path, then it compresses to a zero action.
- Further, if there are multiple cleanups along a path, we only
- need to represent one of them, as that is enough to trigger
- entry to the landing pad at runtime. */
- next = collect_one_action_chain (ar_hash, region->outer);
- if (next <= 0)
- return 0;
- for (r = region->outer; r ; r = r->outer)
- if (r->type == ERT_CLEANUP)
- return next;
- return add_action_record (ar_hash, 0, next);
- }
-
- case ERT_TRY:
- {
- eh_catch c;
-
- /* Process the associated catch regions in reverse order.
- If there's a catch-all handler, then we don't need to
- search outer regions. Use a magic -3 value to record
- that we haven't done the outer search. */
- next = -3;
- for (c = region->u.eh_try.last_catch; c ; c = c->prev_catch)
- {
- if (c->type_list == NULL)
- {
- /* Retrieve the filter from the head of the filter list
- where we have stored it (see assign_filter_values). */
- int filter = TREE_INT_CST_LOW (TREE_VALUE (c->filter_list));
- next = add_action_record (ar_hash, filter, 0);
- }
- else
- {
- /* Once the outer search is done, trigger an action record for
- each filter we have. */
- tree flt_node;
-
- if (next == -3)
- {
- next = collect_one_action_chain (ar_hash, region->outer);
-
- /* If there is no next action, terminate the chain. */
- if (next == -1)
- next = 0;
- /* If all outer actions are cleanups or must_not_throw,
- we'll have no action record for it, since we had wanted
- to encode these states in the call-site record directly.
- Add a cleanup action to the chain to catch these. */
- else if (next <= 0)
- next = add_action_record (ar_hash, 0, 0);
- }
-
- flt_node = c->filter_list;
- for (; flt_node; flt_node = TREE_CHAIN (flt_node))
- {
- int filter = TREE_INT_CST_LOW (TREE_VALUE (flt_node));
- next = add_action_record (ar_hash, filter, next);
- }
- }
- }
- return next;
- }
-
- case ERT_ALLOWED_EXCEPTIONS:
- /* An exception specification adds its filter to the
- beginning of the chain. */
- next = collect_one_action_chain (ar_hash, region->outer);
-
- /* If there is no next action, terminate the chain. */
- if (next == -1)
- next = 0;
- /* If all outer actions are cleanups or must_not_throw,
- we'll have no action record for it, since we had wanted
- to encode these states in the call-site record directly.
- Add a cleanup action to the chain to catch these. */
- else if (next <= 0)
- next = add_action_record (ar_hash, 0, 0);
-
- return add_action_record (ar_hash, region->u.allowed.filter, next);
-
- case ERT_MUST_NOT_THROW:
- /* A must-not-throw region with no inner handlers or cleanups
- requires no call-site entry. Note that this differs from
- the no handler or cleanup case in that we do require an lsda
- to be generated. Return a magic -2 value to record this. */
- return -2;
- }
-
- gcc_unreachable ();
-}
-
-static int
-add_call_site (rtx landing_pad, int action, int section)
-{
- call_site_record record;
-
- record = ggc_alloc<call_site_record_d> ();
- record->landing_pad = landing_pad;
- record->action = action;
-
- vec_safe_push (crtl->eh.call_site_record_v[section], record);
-
- return call_site_base + crtl->eh.call_site_record_v[section]->length () - 1;
-}
-
-static rtx_note *
-emit_note_eh_region_end (rtx_insn *insn)
-{
- return emit_note_after (NOTE_INSN_EH_REGION_END, insn);
-}
-
-/* Add NOP after NOTE_INSN_SWITCH_TEXT_SECTIONS when the cold section starts
- with landing pad.
- With landing pad being at offset 0 from the start label of the section
- we would miss EH delivery because 0 is special and means no landing pad. */
-
-static bool
-maybe_add_nop_after_section_switch (void)
-{
- if (!crtl->uses_eh_lsda
- || !crtl->eh.call_site_record_v[1])
- return false;
- int n = vec_safe_length (crtl->eh.call_site_record_v[1]);
- hash_set<rtx_insn *> visited;
-
- for (int i = 0; i < n; ++i)
- {
- struct call_site_record_d *cs
- = (*crtl->eh.call_site_record_v[1])[i];
- if (cs->landing_pad)
- {
- rtx_insn *insn = as_a <rtx_insn *> (cs->landing_pad);
- while (true)
- {
- /* Landing pads have LABEL_PRESERVE_P flag set. This check make
- sure that we do not walk past landing pad visited earlier
- which would result in possible quadratic behaviour. */
- if (LABEL_P (insn) && LABEL_PRESERVE_P (insn)
- && visited.add (insn))
- break;
-
- /* Conservatively assume that ASM insn may be empty. We have
- now way to tell what they contain. */
- if (active_insn_p (insn)
- && GET_CODE (PATTERN (insn)) != ASM_INPUT
- && GET_CODE (PATTERN (insn)) != ASM_OPERANDS)
- break;
-
- /* If we reached the start of hot section, then NOP will be
- needed. */
- if (GET_CODE (insn) == NOTE
- && NOTE_KIND (insn) == NOTE_INSN_SWITCH_TEXT_SECTIONS)
- {
- emit_insn_after (gen_nop (), insn);
- break;
- }
-
- /* We visit only labels from cold section. We should never hit
- begining of the insn stream here. */
- insn = PREV_INSN (insn);
- }
- }
- }
- return false;
-}
-
-/* Turn REG_EH_REGION notes back into NOTE_INSN_EH_REGION notes.
- The new note numbers will not refer to region numbers, but
- instead to call site entries. */
-
-static unsigned int
-convert_to_eh_region_ranges (void)
-{
- rtx insn;
- rtx_insn *iter;
- rtx_note *note;
- action_hash_type ar_hash (31);
- int last_action = -3;
- rtx_insn *last_action_insn = NULL;
- rtx last_landing_pad = NULL_RTX;
- rtx_insn *first_no_action_insn = NULL;
- int call_site = 0;
- int cur_sec = 0;
- rtx_insn *section_switch_note = NULL;
- rtx_insn *first_no_action_insn_before_switch = NULL;
- rtx_insn *last_no_action_insn_before_switch = NULL;
- int saved_call_site_base = call_site_base;
-
- vec_alloc (crtl->eh.action_record_data, 64);
-
- for (iter = get_insns (); iter ; iter = NEXT_INSN (iter))
- if (INSN_P (iter))
- {
- eh_landing_pad lp;
- eh_region region;
- bool nothrow;
- int this_action;
- rtx_code_label *this_landing_pad;
-
- insn = iter;
- if (NONJUMP_INSN_P (insn)
- && GET_CODE (PATTERN (insn)) == SEQUENCE)
- insn = XVECEXP (PATTERN (insn), 0, 0);
-
- nothrow = get_eh_region_and_lp_from_rtx (insn, &region, &lp);
- if (nothrow)
- continue;
- if (region)
- this_action = collect_one_action_chain (&ar_hash, region);
- else
- this_action = -1;
-
- /* Existence of catch handlers, or must-not-throw regions
- implies that an lsda is needed (even if empty). */
- if (this_action != -1)
- crtl->uses_eh_lsda = 1;
-
- /* Delay creation of region notes for no-action regions
- until we're sure that an lsda will be required. */
- else if (last_action == -3)
- {
- first_no_action_insn = iter;
- last_action = -1;
- }
-
- if (this_action >= 0)
- this_landing_pad = lp->landing_pad;
- else
- this_landing_pad = NULL;
-
- /* Differing actions or landing pads implies a change in call-site
- info, which implies some EH_REGION note should be emitted. */
- if (last_action != this_action
- || last_landing_pad != this_landing_pad)
- {
- /* If there is a queued no-action region in the other section
- with hot/cold partitioning, emit it now. */
- if (first_no_action_insn_before_switch)
- {
- gcc_assert (this_action != -1
- && last_action == (first_no_action_insn
- ? -1 : -3));
- call_site = add_call_site (NULL_RTX, 0, 0);
- note = emit_note_before (NOTE_INSN_EH_REGION_BEG,
- first_no_action_insn_before_switch);
- NOTE_EH_HANDLER (note) = call_site;
- note
- = emit_note_eh_region_end (last_no_action_insn_before_switch);
- NOTE_EH_HANDLER (note) = call_site;
- gcc_assert (last_action != -3
- || (last_action_insn
- == last_no_action_insn_before_switch));
- first_no_action_insn_before_switch = NULL;
- last_no_action_insn_before_switch = NULL;
- call_site_base++;
- }
- /* If we'd not seen a previous action (-3) or the previous
- action was must-not-throw (-2), then we do not need an
- end note. */
- if (last_action >= -1)
- {
- /* If we delayed the creation of the begin, do it now. */
- if (first_no_action_insn)
- {
- call_site = add_call_site (NULL_RTX, 0, cur_sec);
- note = emit_note_before (NOTE_INSN_EH_REGION_BEG,
- first_no_action_insn);
- NOTE_EH_HANDLER (note) = call_site;
- first_no_action_insn = NULL;
- }
-
- note = emit_note_eh_region_end (last_action_insn);
- NOTE_EH_HANDLER (note) = call_site;
- }
-
- /* If the new action is must-not-throw, then no region notes
- are created. */
- if (this_action >= -1)
- {
- call_site = add_call_site (this_landing_pad,
- this_action < 0 ? 0 : this_action,
- cur_sec);
- note = emit_note_before (NOTE_INSN_EH_REGION_BEG, iter);
- NOTE_EH_HANDLER (note) = call_site;
- }
-
- last_action = this_action;
- last_landing_pad = this_landing_pad;
- }
- last_action_insn = iter;
- }
- else if (NOTE_P (iter)
- && NOTE_KIND (iter) == NOTE_INSN_SWITCH_TEXT_SECTIONS)
- {
- gcc_assert (section_switch_note == NULL_RTX);
- gcc_assert (flag_reorder_blocks_and_partition);
- section_switch_note = iter;
- if (first_no_action_insn)
- {
- first_no_action_insn_before_switch = first_no_action_insn;
- last_no_action_insn_before_switch = last_action_insn;
- first_no_action_insn = NULL;
- gcc_assert (last_action == -1);
- last_action = -3;
- }
- /* Force closing of current EH region before section switch and
- opening a new one afterwards. */
- else if (last_action != -3)
- last_landing_pad = pc_rtx;
- if (crtl->eh.call_site_record_v[cur_sec])
- call_site_base += crtl->eh.call_site_record_v[cur_sec]->length ();
- cur_sec++;
- gcc_assert (crtl->eh.call_site_record_v[cur_sec] == NULL);
- vec_alloc (crtl->eh.call_site_record_v[cur_sec], 10);
- }
-
- if (last_action >= -1 && ! first_no_action_insn)
- {
- note = emit_note_eh_region_end (last_action_insn);
- NOTE_EH_HANDLER (note) = call_site;
- }
-
- call_site_base = saved_call_site_base;
-
- return 0;
-}
-
-namespace {
-
-const pass_data pass_data_convert_to_eh_region_ranges =
-{
- RTL_PASS, /* type */
- "eh_ranges", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- TV_NONE, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0, /* todo_flags_finish */
-};
-
-class pass_convert_to_eh_region_ranges : public rtl_opt_pass
-{
-public:
- pass_convert_to_eh_region_ranges (gcc::context *ctxt)
- : rtl_opt_pass (pass_data_convert_to_eh_region_ranges, ctxt)
- {}
-
- /* opt_pass methods: */
- virtual bool gate (function *);
- virtual unsigned int execute (function *)
- {
- int ret = convert_to_eh_region_ranges ();
- maybe_add_nop_after_section_switch ();
- return ret;
- }
-
-}; // class pass_convert_to_eh_region_ranges
-
-bool
-pass_convert_to_eh_region_ranges::gate (function *)
-{
- /* Nothing to do for SJLJ exceptions or if no regions created. */
- if (cfun->eh->region_tree == NULL)
- return false;
- if (targetm_common.except_unwind_info (&global_options) == UI_SJLJ)
- return false;
- return true;
-}
-
-} // anon namespace
-
-rtl_opt_pass *
-make_pass_convert_to_eh_region_ranges (gcc::context *ctxt)
-{
- return new pass_convert_to_eh_region_ranges (ctxt);
-}
-
-static void
-push_uleb128 (vec<uchar, va_gc> **data_area, unsigned int value)
-{
- do
- {
- unsigned char byte = value & 0x7f;
- value >>= 7;
- if (value)
- byte |= 0x80;
- vec_safe_push (*data_area, byte);
- }
- while (value);
-}
-
-static void
-push_sleb128 (vec<uchar, va_gc> **data_area, int value)
-{
- unsigned char byte;
- int more;
-
- do
- {
- byte = value & 0x7f;
- value >>= 7;
- more = ! ((value == 0 && (byte & 0x40) == 0)
- || (value == -1 && (byte & 0x40) != 0));
- if (more)
- byte |= 0x80;
- vec_safe_push (*data_area, byte);
- }
- while (more);
-}
-
-
-static int
-dw2_size_of_call_site_table (int section)
-{
- int n = vec_safe_length (crtl->eh.call_site_record_v[section]);
- int size = n * (4 + 4 + 4);
- int i;
-
- for (i = 0; i < n; ++i)
- {
- struct call_site_record_d *cs =
- (*crtl->eh.call_site_record_v[section])[i];
- size += size_of_uleb128 (cs->action);
- }
-
- return size;
-}
-
-static int
-sjlj_size_of_call_site_table (void)
-{
- int n = vec_safe_length (crtl->eh.call_site_record_v[0]);
- int size = 0;
- int i;
-
- for (i = 0; i < n; ++i)
- {
- struct call_site_record_d *cs =
- (*crtl->eh.call_site_record_v[0])[i];
- size += size_of_uleb128 (INTVAL (cs->landing_pad));
- size += size_of_uleb128 (cs->action);
- }
-
- return size;
-}
-
-static void
-dw2_output_call_site_table (int cs_format, int section)
-{
- int n = vec_safe_length (crtl->eh.call_site_record_v[section]);
- int i;
- const char *begin;
-
- if (section == 0)
- begin = current_function_func_begin_label;
- else if (first_function_block_is_cold)
- begin = crtl->subsections.hot_section_label;
- else
- begin = crtl->subsections.cold_section_label;
-
- for (i = 0; i < n; ++i)
- {
- struct call_site_record_d *cs = (*crtl->eh.call_site_record_v[section])[i];
- char reg_start_lab[32];
- char reg_end_lab[32];
- char landing_pad_lab[32];
-
- ASM_GENERATE_INTERNAL_LABEL (reg_start_lab, "LEHB", call_site_base + i);
- ASM_GENERATE_INTERNAL_LABEL (reg_end_lab, "LEHE", call_site_base + i);
-
- if (cs->landing_pad)
- ASM_GENERATE_INTERNAL_LABEL (landing_pad_lab, "L",
- CODE_LABEL_NUMBER (cs->landing_pad));
-
- /* ??? Perhaps use insn length scaling if the assembler supports
- generic arithmetic. */
- /* ??? Perhaps use attr_length to choose data1 or data2 instead of
- data4 if the function is small enough. */
- if (cs_format == DW_EH_PE_uleb128)
- {
- dw2_asm_output_delta_uleb128 (reg_start_lab, begin,
- "region %d start", i);
- dw2_asm_output_delta_uleb128 (reg_end_lab, reg_start_lab,
- "length");
- if (cs->landing_pad)
- dw2_asm_output_delta_uleb128 (landing_pad_lab, begin,
- "landing pad");
- else
- dw2_asm_output_data_uleb128 (0, "landing pad");
- }
- else
- {
- dw2_asm_output_delta (4, reg_start_lab, begin,
- "region %d start", i);
- dw2_asm_output_delta (4, reg_end_lab, reg_start_lab, "length");
- if (cs->landing_pad)
- dw2_asm_output_delta (4, landing_pad_lab, begin,
- "landing pad");
- else
- dw2_asm_output_data (4, 0, "landing pad");
- }
- dw2_asm_output_data_uleb128 (cs->action, "action");
- }
-
- call_site_base += n;
-}
-
-static void
-sjlj_output_call_site_table (void)
-{
- int n = vec_safe_length (crtl->eh.call_site_record_v[0]);
- int i;
-
- for (i = 0; i < n; ++i)
- {
- struct call_site_record_d *cs = (*crtl->eh.call_site_record_v[0])[i];
-
- dw2_asm_output_data_uleb128 (INTVAL (cs->landing_pad),
- "region %d landing pad", i);
- dw2_asm_output_data_uleb128 (cs->action, "action");
- }
-
- call_site_base += n;
-}
-
-/* Switch to the section that should be used for exception tables. */
-
-static void
-switch_to_exception_section (const char * ARG_UNUSED (fnname))
-{
- section *s;
-
- if (exception_section)
- s = exception_section;
- else
- {
- int flags;
-
- if (EH_TABLES_CAN_BE_READ_ONLY)
- {
- int tt_format =
- ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/0, /*global=*/1);
- flags = ((! flag_pic
- || ((tt_format & 0x70) != DW_EH_PE_absptr
- && (tt_format & 0x70) != DW_EH_PE_aligned))
- ? 0 : SECTION_WRITE);
- }
- else
- flags = SECTION_WRITE;
-
- /* Compute the section and cache it into exception_section,
- unless it depends on the function name. */
- if (targetm_common.have_named_sections)
- {
-#ifdef HAVE_LD_EH_GC_SECTIONS
- if (flag_function_sections
- || (DECL_COMDAT_GROUP (current_function_decl) && HAVE_COMDAT_GROUP))
- {
- char *section_name = XNEWVEC (char, strlen (fnname) + 32);
- /* The EH table must match the code section, so only mark
- it linkonce if we have COMDAT groups to tie them together. */
- if (DECL_COMDAT_GROUP (current_function_decl) && HAVE_COMDAT_GROUP)
- flags |= SECTION_LINKONCE;
- sprintf (section_name, ".gcc_except_table.%s", fnname);
- s = get_section (section_name, flags, current_function_decl);
- free (section_name);
- }
- else
-#endif
- exception_section
- = s = get_section (".gcc_except_table", flags, NULL);
- }
- else
- exception_section
- = s = flags == SECTION_WRITE ? data_section : readonly_data_section;
- }
-
- switch_to_section (s);
-}
-
-/* Output a reference from an exception table to the type_info object TYPE.
- TT_FORMAT and TT_FORMAT_SIZE describe the DWARF encoding method used for
- the value. */
-
-static void
-output_ttype (tree type, int tt_format, int tt_format_size)
-{
- rtx value;
- bool is_public = true;
-
- if (type == NULL_TREE)
- value = const0_rtx;
- else
- {
- /* FIXME lto. pass_ipa_free_lang_data changes all types to
- runtime types so TYPE should already be a runtime type
- reference. When pass_ipa_free_lang data is made a default
- pass, we can then remove the call to lookup_type_for_runtime
- below. */
- if (TYPE_P (type))
- type = lookup_type_for_runtime (type);
-
- value = expand_expr (type, NULL_RTX, VOIDmode, EXPAND_INITIALIZER);
-
- /* Let cgraph know that the rtti decl is used. Not all of the
- paths below go through assemble_integer, which would take
- care of this for us. */
- STRIP_NOPS (type);
- if (TREE_CODE (type) == ADDR_EXPR)
- {
- type = TREE_OPERAND (type, 0);
- if (VAR_P (type))
- is_public = TREE_PUBLIC (type);
- }
- else
- gcc_assert (TREE_CODE (type) == INTEGER_CST);
- }
-
- /* Allow the target to override the type table entry format. */
- if (targetm.asm_out.ttype (value))
- return;
-
- if (tt_format == DW_EH_PE_absptr || tt_format == DW_EH_PE_aligned)
- assemble_integer (value, tt_format_size,
- tt_format_size * BITS_PER_UNIT, 1);
- else
- dw2_asm_output_encoded_addr_rtx (tt_format, value, is_public, NULL);
-}
-
-/* Output an exception table for the current function according to SECTION.
-
- If the function has been partitioned into hot and cold parts, value 0 for
- SECTION refers to the table associated with the hot part while value 1
- refers to the table associated with the cold part. If the function has
- not been partitioned, value 0 refers to the single exception table. */
-
-static void
-output_one_function_exception_table (int section)
-{
- int tt_format, cs_format, lp_format, i;
- char ttype_label[32];
- char cs_after_size_label[32];
- char cs_end_label[32];
- int call_site_len;
- int have_tt_data;
- int tt_format_size = 0;
-
- have_tt_data = (vec_safe_length (cfun->eh->ttype_data)
- || (targetm.arm_eabi_unwinder
- ? vec_safe_length (cfun->eh->ehspec_data.arm_eabi)
- : vec_safe_length (cfun->eh->ehspec_data.other)));
-
- /* Indicate the format of the @TType entries. */
- if (! have_tt_data)
- tt_format = DW_EH_PE_omit;
- else
- {
- tt_format = ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/0, /*global=*/1);
- if (HAVE_AS_LEB128)
- ASM_GENERATE_INTERNAL_LABEL (ttype_label,
- section ? "LLSDATTC" : "LLSDATT",
- current_function_funcdef_no);
-
- tt_format_size = size_of_encoded_value (tt_format);
-
- assemble_align (tt_format_size * BITS_PER_UNIT);
- }
-
- targetm.asm_out.internal_label (asm_out_file, section ? "LLSDAC" : "LLSDA",
- current_function_funcdef_no);
-
- /* The LSDA header. */
-
- /* Indicate the format of the landing pad start pointer. An omitted
- field implies @LPStart == @Start. */
- /* Currently we always put @LPStart == @Start. This field would
- be most useful in moving the landing pads completely out of
- line to another section, but it could also be used to minimize
- the size of uleb128 landing pad offsets. */
- lp_format = DW_EH_PE_omit;
- dw2_asm_output_data (1, lp_format, "@LPStart format (%s)",
- eh_data_format_name (lp_format));
-
- /* @LPStart pointer would go here. */
-
- dw2_asm_output_data (1, tt_format, "@TType format (%s)",
- eh_data_format_name (tt_format));
-
- if (!HAVE_AS_LEB128)
- {
- if (targetm_common.except_unwind_info (&global_options) == UI_SJLJ)
- call_site_len = sjlj_size_of_call_site_table ();
- else
- call_site_len = dw2_size_of_call_site_table (section);
- }
-
- /* A pc-relative 4-byte displacement to the @TType data. */
- if (have_tt_data)
- {
- if (HAVE_AS_LEB128)
- {
- char ttype_after_disp_label[32];
- ASM_GENERATE_INTERNAL_LABEL (ttype_after_disp_label,
- section ? "LLSDATTDC" : "LLSDATTD",
- current_function_funcdef_no);
- dw2_asm_output_delta_uleb128 (ttype_label, ttype_after_disp_label,
- "@TType base offset");
- ASM_OUTPUT_LABEL (asm_out_file, ttype_after_disp_label);
- }
- else
- {
- /* Ug. Alignment queers things. */
- unsigned int before_disp, after_disp, last_disp, disp;
-
- before_disp = 1 + 1;
- after_disp = (1 + size_of_uleb128 (call_site_len)
- + call_site_len
- + vec_safe_length (crtl->eh.action_record_data)
- + (vec_safe_length (cfun->eh->ttype_data)
- * tt_format_size));
-
- disp = after_disp;
- do
- {
- unsigned int disp_size, pad;
-
- last_disp = disp;
- disp_size = size_of_uleb128 (disp);
- pad = before_disp + disp_size + after_disp;
- if (pad % tt_format_size)
- pad = tt_format_size - (pad % tt_format_size);
- else
- pad = 0;
- disp = after_disp + pad;
- }
- while (disp != last_disp);
-
- dw2_asm_output_data_uleb128 (disp, "@TType base offset");
- }
- }
-
- /* Indicate the format of the call-site offsets. */
- if (HAVE_AS_LEB128)
- cs_format = DW_EH_PE_uleb128;
- else
- cs_format = DW_EH_PE_udata4;
-
- dw2_asm_output_data (1, cs_format, "call-site format (%s)",
- eh_data_format_name (cs_format));
-
- if (HAVE_AS_LEB128)
- {
- ASM_GENERATE_INTERNAL_LABEL (cs_after_size_label,
- section ? "LLSDACSBC" : "LLSDACSB",
- current_function_funcdef_no);
- ASM_GENERATE_INTERNAL_LABEL (cs_end_label,
- section ? "LLSDACSEC" : "LLSDACSE",
- current_function_funcdef_no);
- dw2_asm_output_delta_uleb128 (cs_end_label, cs_after_size_label,
- "Call-site table length");
- ASM_OUTPUT_LABEL (asm_out_file, cs_after_size_label);
- if (targetm_common.except_unwind_info (&global_options) == UI_SJLJ)
- sjlj_output_call_site_table ();
- else
- dw2_output_call_site_table (cs_format, section);
- ASM_OUTPUT_LABEL (asm_out_file, cs_end_label);
- }
- else
- {
- dw2_asm_output_data_uleb128 (call_site_len, "Call-site table length");
- if (targetm_common.except_unwind_info (&global_options) == UI_SJLJ)
- sjlj_output_call_site_table ();
- else
- dw2_output_call_site_table (cs_format, section);
- }
-
- /* ??? Decode and interpret the data for flag_debug_asm. */
- {
- uchar uc;
- FOR_EACH_VEC_ELT (*crtl->eh.action_record_data, i, uc)
- dw2_asm_output_data (1, uc, i ? NULL : "Action record table");
- }
-
- if (have_tt_data)
- assemble_align (tt_format_size * BITS_PER_UNIT);
-
- i = vec_safe_length (cfun->eh->ttype_data);
- while (i-- > 0)
- {
- tree type = (*cfun->eh->ttype_data)[i];
- output_ttype (type, tt_format, tt_format_size);
- }
-
- if (HAVE_AS_LEB128 && have_tt_data)
- ASM_OUTPUT_LABEL (asm_out_file, ttype_label);
-
- /* ??? Decode and interpret the data for flag_debug_asm. */
- if (targetm.arm_eabi_unwinder)
- {
- tree type;
- for (i = 0;
- vec_safe_iterate (cfun->eh->ehspec_data.arm_eabi, i, &type); ++i)
- output_ttype (type, tt_format, tt_format_size);
- }
- else
- {
- uchar uc;
- for (i = 0;
- vec_safe_iterate (cfun->eh->ehspec_data.other, i, &uc); ++i)
- dw2_asm_output_data (1, uc,
- i ? NULL : "Exception specification table");
- }
-}
-
-/* Output an exception table for the current function according to SECTION,
- switching back and forth from the function section appropriately.
-
- If the function has been partitioned into hot and cold parts, value 0 for
- SECTION refers to the table associated with the hot part while value 1
- refers to the table associated with the cold part. If the function has
- not been partitioned, value 0 refers to the single exception table. */
-
-void
-output_function_exception_table (int section)
-{
- const char *fnname = get_fnname_from_decl (current_function_decl);
- rtx personality = get_personality_function (current_function_decl);
-
- /* Not all functions need anything. */
- if (!crtl->uses_eh_lsda
- || targetm_common.except_unwind_info (&global_options) == UI_NONE)
- return;
-
- /* No need to emit any boilerplate stuff for the cold part. */
- if (section == 1 && !crtl->eh.call_site_record_v[1])
- return;
-
- if (personality)
- {
- assemble_external_libcall (personality);
-
- if (targetm.asm_out.emit_except_personality)
- targetm.asm_out.emit_except_personality (personality);
- }
-
- switch_to_exception_section (fnname);
-
- /* If the target wants a label to begin the table, emit it here. */
- targetm.asm_out.emit_except_table_label (asm_out_file);
-
- /* Do the real work. */
- output_one_function_exception_table (section);
-
- switch_to_section (current_function_section ());
-}
-
-void
-set_eh_throw_stmt_table (function *fun, hash_map<gimple *, int> *table)
-{
- fun->eh->throw_stmt_table = table;
-}
-
-hash_map<gimple *, int> *
-get_eh_throw_stmt_table (struct function *fun)
-{
- return fun->eh->throw_stmt_table;
-}
-
-/* Determine if the function needs an EH personality function. */
-
-enum eh_personality_kind
-function_needs_eh_personality (struct function *fn)
-{
- enum eh_personality_kind kind = eh_personality_none;
- eh_region i;
-
- FOR_ALL_EH_REGION_FN (i, fn)
- {
- switch (i->type)
- {
- case ERT_CLEANUP:
- /* Can do with any personality including the generic C one. */
- kind = eh_personality_any;
- break;
-
- case ERT_TRY:
- case ERT_ALLOWED_EXCEPTIONS:
- /* Always needs a EH personality function. The generic C
- personality doesn't handle these even for empty type lists. */
- return eh_personality_lang;
-
- case ERT_MUST_NOT_THROW:
- /* Always needs a EH personality function. The language may specify
- what abort routine that must be used, e.g. std::terminate. */
- return eh_personality_lang;
- }
- }
-
- return kind;
-}
-
-/* Dump EH information to OUT. */
-
-void
-dump_eh_tree (FILE * out, struct function *fun)
-{
- eh_region i;
- int depth = 0;
- static const char *const type_name[] = {
- "cleanup", "try", "allowed_exceptions", "must_not_throw"
- };
-
- i = fun->eh->region_tree;
- if (!i)
- return;
-
- fprintf (out, "Eh tree:\n");
- while (1)
- {
- fprintf (out, " %*s %i %s", depth * 2, "",
- i->index, type_name[(int) i->type]);
-
- if (i->landing_pads)
- {
- eh_landing_pad lp;
-
- fprintf (out, " land:");
- if (current_ir_type () == IR_GIMPLE)
- {
- for (lp = i->landing_pads; lp ; lp = lp->next_lp)
- {
- fprintf (out, "{%i,", lp->index);
- print_generic_expr (out, lp->post_landing_pad);
- fputc ('}', out);
- if (lp->next_lp)
- fputc (',', out);
- }
- }
- else
- {
- for (lp = i->landing_pads; lp ; lp = lp->next_lp)
- {
- fprintf (out, "{%i,", lp->index);
- if (lp->landing_pad)
- fprintf (out, "%i%s,", INSN_UID (lp->landing_pad),
- NOTE_P (lp->landing_pad) ? "(del)" : "");
- else
- fprintf (out, "(nil),");
- if (lp->post_landing_pad)
- {
- rtx_insn *lab = label_rtx (lp->post_landing_pad);
- fprintf (out, "%i%s}", INSN_UID (lab),
- NOTE_P (lab) ? "(del)" : "");
- }
- else
- fprintf (out, "(nil)}");
- if (lp->next_lp)
- fputc (',', out);
- }
- }
- }
-
- switch (i->type)
- {
- case ERT_CLEANUP:
- case ERT_MUST_NOT_THROW:
- break;
-
- case ERT_TRY:
- {
- eh_catch c;
- fprintf (out, " catch:");
- for (c = i->u.eh_try.first_catch; c; c = c->next_catch)
- {
- fputc ('{', out);
- if (c->label)
- {
- fprintf (out, "lab:");
- print_generic_expr (out, c->label);
- fputc (';', out);
- }
- print_generic_expr (out, c->type_list);
- fputc ('}', out);
- if (c->next_catch)
- fputc (',', out);
- }
- }
- break;
-
- case ERT_ALLOWED_EXCEPTIONS:
- fprintf (out, " filter :%i types:", i->u.allowed.filter);
- print_generic_expr (out, i->u.allowed.type_list);
- break;
- }
- fputc ('\n', out);
-
- /* If there are sub-regions, process them. */
- if (i->inner)
- i = i->inner, depth++;
- /* If there are peers, process them. */
- else if (i->next_peer)
- i = i->next_peer;
- /* Otherwise, step back up the tree to the next peer. */
- else
- {
- do
- {
- i = i->outer;
- depth--;
- if (i == NULL)
- return;
- }
- while (i->next_peer == NULL);
- i = i->next_peer;
- }
- }
-}
-
-/* Dump the EH tree for FN on stderr. */
-
-DEBUG_FUNCTION void
-debug_eh_tree (struct function *fn)
-{
- dump_eh_tree (stderr, fn);
-}
-
-/* Verify invariants on EH datastructures. */
-
-DEBUG_FUNCTION void
-verify_eh_tree (struct function *fun)
-{
- eh_region r, outer;
- int nvisited_lp, nvisited_r;
- int count_lp, count_r, depth, i;
- eh_landing_pad lp;
- bool err = false;
-
- if (!fun->eh->region_tree)
- return;
-
- count_r = 0;
- for (i = 1; vec_safe_iterate (fun->eh->region_array, i, &r); ++i)
- if (r)
- {
- if (r->index == i)
- count_r++;
- else
- {
- error ("%<region_array%> is corrupted for region %i", r->index);
- err = true;
- }
- }
-
- count_lp = 0;
- for (i = 1; vec_safe_iterate (fun->eh->lp_array, i, &lp); ++i)
- if (lp)
- {
- if (lp->index == i)
- count_lp++;
- else
- {
- error ("%<lp_array%> is corrupted for lp %i", lp->index);
- err = true;
- }
- }
-
- depth = nvisited_lp = nvisited_r = 0;
- outer = NULL;
- r = fun->eh->region_tree;
- while (1)
- {
- if ((*fun->eh->region_array)[r->index] != r)
- {
- error ("%<region_array%> is corrupted for region %i", r->index);
- err = true;
- }
- if (r->outer != outer)
- {
- error ("outer block of region %i is wrong", r->index);
- err = true;
- }
- if (depth < 0)
- {
- error ("negative nesting depth of region %i", r->index);
- err = true;
- }
- nvisited_r++;
-
- for (lp = r->landing_pads; lp ; lp = lp->next_lp)
- {
- if ((*fun->eh->lp_array)[lp->index] != lp)
- {
- error ("%<lp_array%> is corrupted for lp %i", lp->index);
- err = true;
- }
- if (lp->region != r)
- {
- error ("region of lp %i is wrong", lp->index);
- err = true;
- }
- nvisited_lp++;
- }
-
- if (r->inner)
- outer = r, r = r->inner, depth++;
- else if (r->next_peer)
- r = r->next_peer;
- else
- {
- do
- {
- r = r->outer;
- if (r == NULL)
- goto region_done;
- depth--;
- outer = r->outer;
- }
- while (r->next_peer == NULL);
- r = r->next_peer;
- }
- }
- region_done:
- if (depth != 0)
- {
- error ("tree list ends on depth %i", depth);
- err = true;
- }
- if (count_r != nvisited_r)
- {
- error ("%<region_array%> does not match %<region_tree%>");
- err = true;
- }
- if (count_lp != nvisited_lp)
- {
- error ("%<lp_array%> does not match %<region_tree%>");
- err = true;
- }
-
- if (err)
- {
- dump_eh_tree (stderr, fun);
- internal_error ("%qs failed", __func__);
- }
-}
-
-#include "gt-except.h"