diff options
author | Martin Liska <mliska@suse.cz> | 2022-01-14 16:56:44 +0100 |
---|---|---|
committer | Martin Liska <mliska@suse.cz> | 2022-01-17 22:12:04 +0100 |
commit | 5c69acb32329d49e58c26fa41ae74229a52b9106 (patch) | |
tree | ddb05f9d73afb6f998457d2ac4b720e3b3b60483 /gcc/except.c | |
parent | 490e23032baaece71f2ec09fa1805064b150fbc2 (diff) | |
download | gcc-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.c | 3522 |
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 (®ion->inner, r_reachable); - if (!bitmap_bit_p (r_reachable, region->index)) - remove_eh_handler_splicer (pp); - else - pp = ®ion->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, ®ion, &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" |