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/cp/error.cc | |
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/cp/error.cc')
-rw-r--r-- | gcc/cp/error.cc | 4659 |
1 files changed, 4659 insertions, 0 deletions
diff --git a/gcc/cp/error.cc b/gcc/cp/error.cc new file mode 100644 index 0000000..8a3b7b5 --- /dev/null +++ b/gcc/cp/error.cc @@ -0,0 +1,4659 @@ +/* Call-backs for C++ error reporting. + This code is non-reentrant. + Copyright (C) 1993-2022 Free Software Foundation, Inc. + This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 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/>. */ + +#include "config.h" +/* For use with name_hint. */ +#define INCLUDE_MEMORY +#include "system.h" +#include "coretypes.h" +#include "cp-tree.h" +#include "stringpool.h" +#include "tree-diagnostic.h" +#include "langhooks-def.h" +#include "intl.h" +#include "cxx-pretty-print.h" +#include "tree-pretty-print.h" +#include "gimple-pretty-print.h" +#include "c-family/c-objc.h" +#include "ubsan.h" +#include "internal-fn.h" +#include "gcc-rich-location.h" +#include "cp-name-hint.h" + +#define pp_separate_with_comma(PP) pp_cxx_separate_with (PP, ',') +#define pp_separate_with_semicolon(PP) pp_cxx_separate_with (PP, ';') + +/* cxx_pp is a C++ front-end-specific pretty printer: this is where we + dump C++ ASTs as strings. It is mostly used only by the various + tree -> string functions that are occasionally called from the + debugger or by the front-end for things like + __PRETTY_FUNCTION__. */ +static cxx_pretty_printer actual_pretty_printer; +static cxx_pretty_printer * const cxx_pp = &actual_pretty_printer; + +/* Translate if being used for diagnostics, but not for dump files or + __PRETTY_FUNCTION. */ +#define M_(msgid) (pp_translate_identifiers (cxx_pp) ? _(msgid) : (msgid)) + +# define NEXT_CODE(T) (TREE_CODE (TREE_TYPE (T))) + +static const char *args_to_string (tree, int); +static const char *code_to_string (enum tree_code); +static const char *cv_to_string (tree, int); +static const char *decl_to_string (tree, int); +static const char *fndecl_to_string (tree, int); +static const char *op_to_string (bool, enum tree_code); +static const char *parm_to_string (int); +static const char *type_to_string (tree, int, bool, bool *, bool); + +static void dump_alias_template_specialization (cxx_pretty_printer *, tree, int); +static void dump_type (cxx_pretty_printer *, tree, int); +static void dump_typename (cxx_pretty_printer *, tree, int); +static void dump_simple_decl (cxx_pretty_printer *, tree, tree, int); +static void dump_decl (cxx_pretty_printer *, tree, int); +static void dump_template_decl (cxx_pretty_printer *, tree, int); +static void dump_function_decl (cxx_pretty_printer *, tree, int); +static void dump_expr (cxx_pretty_printer *, tree, int); +static void dump_unary_op (cxx_pretty_printer *, const char *, tree, int); +static void dump_binary_op (cxx_pretty_printer *, const char *, tree, int); +static void dump_aggr_type (cxx_pretty_printer *, tree, int); +static void dump_type_prefix (cxx_pretty_printer *, tree, int); +static void dump_type_suffix (cxx_pretty_printer *, tree, int); +static void dump_function_name (cxx_pretty_printer *, tree, int); +static void dump_call_expr_args (cxx_pretty_printer *, tree, int, bool); +static void dump_aggr_init_expr_args (cxx_pretty_printer *, tree, int, bool); +static void dump_expr_list (cxx_pretty_printer *, tree, int); +static void dump_global_iord (cxx_pretty_printer *, tree); +static void dump_parameters (cxx_pretty_printer *, tree, int); +static void dump_ref_qualifier (cxx_pretty_printer *, tree, int); +static void dump_exception_spec (cxx_pretty_printer *, tree, int); +static void dump_template_argument (cxx_pretty_printer *, tree, int); +static void dump_template_argument_list (cxx_pretty_printer *, tree, int); +static void dump_template_parameter (cxx_pretty_printer *, tree, int); +static void dump_template_bindings (cxx_pretty_printer *, tree, tree, + vec<tree, va_gc> *); +static void dump_scope (cxx_pretty_printer *, tree, int); +static void dump_template_parms (cxx_pretty_printer *, tree, int, int); +static int get_non_default_template_args_count (tree, int); +static const char *function_category (tree); +static void maybe_print_constexpr_context (diagnostic_context *); +static void maybe_print_instantiation_context (diagnostic_context *); +static void print_instantiation_full_context (diagnostic_context *); +static void print_instantiation_partial_context (diagnostic_context *, + struct tinst_level *, + location_t); +static void maybe_print_constraint_context (diagnostic_context *); +static void cp_diagnostic_starter (diagnostic_context *, diagnostic_info *); +static void cp_print_error_function (diagnostic_context *, diagnostic_info *); + +static bool cp_printer (pretty_printer *, text_info *, const char *, + int, bool, bool, bool, bool *, const char **); + +/* Struct for handling %H or %I, which require delaying printing the + type until a postprocessing stage. */ + +class deferred_printed_type +{ +public: + deferred_printed_type () + : m_tree (NULL_TREE), m_buffer_ptr (NULL), m_verbose (false), m_quote (false) + {} + + deferred_printed_type (tree type, const char **buffer_ptr, bool verbose, + bool quote) + : m_tree (type), m_buffer_ptr (buffer_ptr), m_verbose (verbose), + m_quote (quote) + { + gcc_assert (type); + gcc_assert (buffer_ptr); + } + + /* The tree is not GTY-marked: they are only non-NULL within a + call to pp_format. */ + tree m_tree; + const char **m_buffer_ptr; + bool m_verbose; + bool m_quote; +}; + +/* Subclass of format_postprocessor for the C++ frontend. + This handles the %H and %I formatting codes, printing them + in a postprocessing phase (since they affect each other). */ + +class cxx_format_postprocessor : public format_postprocessor +{ + public: + cxx_format_postprocessor () + : m_type_a (), m_type_b () + {} + + format_postprocessor *clone() const FINAL OVERRIDE + { + return new cxx_format_postprocessor (); + } + + void handle (pretty_printer *pp) FINAL OVERRIDE; + + deferred_printed_type m_type_a; + deferred_printed_type m_type_b; +}; + +/* CONTEXT->printer is a basic pretty printer that was constructed + presumably by diagnostic_initialize(), called early in the + compiler's initialization process (in general_init) Before the FE + is initialized. This (C++) FE-specific diagnostic initializer is + thus replacing the basic pretty printer with one that has C++-aware + capacities. */ + +void +cxx_initialize_diagnostics (diagnostic_context *context) +{ + pretty_printer *base = context->printer; + cxx_pretty_printer *pp = XNEW (cxx_pretty_printer); + context->printer = new (pp) cxx_pretty_printer (); + + /* It is safe to free this object because it was previously XNEW()'d. */ + base->~pretty_printer (); + XDELETE (base); + + c_common_diagnostics_set_defaults (context); + diagnostic_starter (context) = cp_diagnostic_starter; + /* diagnostic_finalizer is already c_diagnostic_finalizer. */ + diagnostic_format_decoder (context) = cp_printer; + pp->m_format_postprocessor = new cxx_format_postprocessor (); +} + +/* Dump an '@module' name suffix for DECL, if any. */ + +static void +dump_module_suffix (cxx_pretty_printer *pp, tree decl) +{ + if (!modules_p ()) + return; + + if (!DECL_CONTEXT (decl)) + return; + + if (TREE_CODE (decl) != CONST_DECL + || !UNSCOPED_ENUM_P (DECL_CONTEXT (decl))) + { + if (!DECL_NAMESPACE_SCOPE_P (decl)) + return; + + if (TREE_CODE (decl) == NAMESPACE_DECL + && !DECL_NAMESPACE_ALIAS (decl) + && (TREE_PUBLIC (decl) || !TREE_PUBLIC (CP_DECL_CONTEXT (decl)))) + return; + } + + if (unsigned m = get_originating_module (decl)) + if (const char *n = module_name (m, false)) + { + pp_character (pp, '@'); + pp->padding = pp_none; + pp_string (pp, n); + } +} + +/* The scope of the declaration we're currently printing, to avoid redundantly + dumping the same scope on parameter types. */ +static tree current_dump_scope; + +/* Dump a scope, if deemed necessary. */ + +static void +dump_scope (cxx_pretty_printer *pp, tree scope, int flags) +{ + int f = flags & (TFF_SCOPE | TFF_CHASE_TYPEDEF); + + if (scope == NULL_TREE || scope == current_dump_scope) + return; + + /* Enum values within an unscoped enum will be CONST_DECL with an + ENUMERAL_TYPE as their "scope". Use CP_TYPE_CONTEXT of the + ENUMERAL_TYPE, so as to print any enclosing namespace. */ + if (UNSCOPED_ENUM_P (scope)) + scope = CP_TYPE_CONTEXT (scope); + + if (TREE_CODE (scope) == NAMESPACE_DECL) + { + if (scope != global_namespace) + { + dump_decl (pp, scope, f); + pp_cxx_colon_colon (pp); + } + } + else if (AGGREGATE_TYPE_P (scope) + || SCOPED_ENUM_P (scope)) + { + dump_type (pp, scope, f); + pp_cxx_colon_colon (pp); + } + else if ((flags & TFF_SCOPE) && TREE_CODE (scope) == FUNCTION_DECL) + { + dump_function_decl (pp, scope, f | TFF_NO_TEMPLATE_BINDINGS); + pp_cxx_colon_colon (pp); + } +} + +/* Dump the template ARGument under control of FLAGS. */ + +static void +dump_template_argument (cxx_pretty_printer *pp, tree arg, int flags) +{ + if (ARGUMENT_PACK_P (arg)) + dump_template_argument_list (pp, ARGUMENT_PACK_ARGS (arg), + /* No default args in argument packs. */ + flags|TFF_NO_OMIT_DEFAULT_TEMPLATE_ARGUMENTS); + else if (TYPE_P (arg) || TREE_CODE (arg) == TEMPLATE_DECL) + dump_type (pp, arg, flags & ~TFF_CLASS_KEY_OR_ENUM); + else + { + if (TREE_CODE (arg) == TREE_LIST) + arg = TREE_VALUE (arg); + + /* Strip implicit conversions. */ + while (CONVERT_EXPR_P (arg)) + arg = TREE_OPERAND (arg, 0); + + dump_expr (pp, arg, (flags | TFF_EXPR_IN_PARENS) & ~TFF_CLASS_KEY_OR_ENUM); + } +} + +/* Count the number of template arguments ARGS whose value does not + match the (optional) default template parameter in PARAMS */ + +static int +get_non_default_template_args_count (tree args, int flags) +{ + int n = TREE_VEC_LENGTH (INNERMOST_TEMPLATE_ARGS (args)); + + if (/* We use this flag when generating debug information. We don't + want to expand templates at this point, for this may generate + new decls, which gets decl counts out of sync, which may in + turn cause codegen differences between compilations with and + without -g. */ + (flags & TFF_NO_OMIT_DEFAULT_TEMPLATE_ARGUMENTS) != 0 + || !flag_pretty_templates) + return n; + + return GET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (INNERMOST_TEMPLATE_ARGS (args)); +} + +/* Dump a template-argument-list ARGS (always a TREE_VEC) under control + of FLAGS. */ + +static void +dump_template_argument_list (cxx_pretty_printer *pp, tree args, int flags) +{ + int n = get_non_default_template_args_count (args, flags); + int need_comma = 0; + int i; + + for (i = 0; i < n; ++i) + { + tree arg = TREE_VEC_ELT (args, i); + + /* Only print a comma if we know there is an argument coming. In + the case of an empty template argument pack, no actual + argument will be printed. */ + if (need_comma + && (!ARGUMENT_PACK_P (arg) + || TREE_VEC_LENGTH (ARGUMENT_PACK_ARGS (arg)) > 0)) + pp_separate_with_comma (pp); + + dump_template_argument (pp, arg, flags); + need_comma = 1; + } +} + +/* Dump a template parameter PARM (a TREE_LIST) under control of FLAGS. */ + +static void +dump_template_parameter (cxx_pretty_printer *pp, tree parm, int flags) +{ + tree p; + tree a; + + if (parm == error_mark_node) + return; + + p = TREE_VALUE (parm); + a = TREE_PURPOSE (parm); + + if (TREE_CODE (p) == TYPE_DECL) + { + if (flags & TFF_DECL_SPECIFIERS) + { + pp_cxx_ws_string (pp, "class"); + if (TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (p))) + pp_cxx_ws_string (pp, "..."); + if (DECL_NAME (p)) + pp_cxx_tree_identifier (pp, DECL_NAME (p)); + } + else if (DECL_NAME (p)) + pp_cxx_tree_identifier (pp, DECL_NAME (p)); + else + pp_cxx_canonical_template_parameter (pp, TREE_TYPE (p)); + } + else + dump_decl (pp, p, flags | TFF_DECL_SPECIFIERS); + + if ((flags & TFF_FUNCTION_DEFAULT_ARGUMENTS) && a != NULL_TREE) + { + pp_cxx_whitespace (pp); + pp_equal (pp); + pp_cxx_whitespace (pp); + if (TREE_CODE (p) == TYPE_DECL || TREE_CODE (p) == TEMPLATE_DECL) + dump_type (pp, a, flags & ~TFF_CHASE_TYPEDEF); + else + dump_expr (pp, a, flags | TFF_EXPR_IN_PARENS); + } +} + +/* Dump, under control of FLAGS, a template-parameter-list binding. + PARMS is a TREE_LIST of TREE_VEC of TREE_LIST and ARGS is a + TREE_VEC. */ + +static void +dump_template_bindings (cxx_pretty_printer *pp, tree parms, tree args, + vec<tree, va_gc> *typenames) +{ + /* Print "[with" and ']', conditional on whether anything is printed at all. + This is tied to whether a semicolon is needed to separate multiple template + parameters. */ + struct prepost_semicolon + { + cxx_pretty_printer *pp; + bool need_semicolon; + + void operator() () + { + if (need_semicolon) + pp_separate_with_semicolon (pp); + else + { + pp_cxx_whitespace (pp); + pp_cxx_left_bracket (pp); + pp->translate_string ("with"); + pp_cxx_whitespace (pp); + need_semicolon = true; + } + } + + ~prepost_semicolon () + { + if (need_semicolon) + pp_cxx_right_bracket (pp); + } + } semicolon_or_introducer = {pp, false}; + + int i; + tree t; + + while (parms) + { + tree p = TREE_VALUE (parms); + int lvl = TMPL_PARMS_DEPTH (parms); + int arg_idx = 0; + int i; + tree lvl_args = NULL_TREE; + + /* Don't crash if we had an invalid argument list. */ + if (TMPL_ARGS_DEPTH (args) >= lvl) + lvl_args = TMPL_ARGS_LEVEL (args, lvl); + + for (i = 0; i < TREE_VEC_LENGTH (p); ++i) + { + tree arg = NULL_TREE; + + /* Don't crash if we had an invalid argument list. */ + if (lvl_args && NUM_TMPL_ARGS (lvl_args) > arg_idx) + arg = TREE_VEC_ELT (lvl_args, arg_idx); + + tree parm_i = TREE_VEC_ELT (p, i); + /* If the template argument repeats the template parameter (T = T), + skip the parameter.*/ + if (arg && TREE_CODE (arg) == TEMPLATE_TYPE_PARM + && TREE_CODE (parm_i) == TREE_LIST + && TREE_CODE (TREE_VALUE (parm_i)) == TYPE_DECL + && TREE_CODE (TREE_TYPE (TREE_VALUE (parm_i))) + == TEMPLATE_TYPE_PARM + && DECL_NAME (TREE_VALUE (parm_i)) + == DECL_NAME (TREE_CHAIN (arg))) + continue; + + semicolon_or_introducer (); + dump_template_parameter (pp, parm_i, TFF_PLAIN_IDENTIFIER); + pp_cxx_whitespace (pp); + pp_equal (pp); + pp_cxx_whitespace (pp); + if (arg) + { + if (ARGUMENT_PACK_P (arg)) + pp_cxx_left_brace (pp); + dump_template_argument (pp, arg, TFF_PLAIN_IDENTIFIER); + if (ARGUMENT_PACK_P (arg)) + pp_cxx_right_brace (pp); + } + else + pp_string (pp, M_("<missing>")); + + ++arg_idx; + } + + parms = TREE_CHAIN (parms); + } + + /* Don't bother with typenames for a partial instantiation. */ + if (vec_safe_is_empty (typenames) || uses_template_parms (args)) + return; + + /* Don't try to print typenames when we're processing a clone. */ + if (current_function_decl + && !DECL_LANG_SPECIFIC (current_function_decl)) + return; + + /* Don't try to do this once cgraph starts throwing away front-end + information. */ + if (at_eof >= 2) + return; + + FOR_EACH_VEC_SAFE_ELT (typenames, i, t) + { + semicolon_or_introducer (); + dump_type (pp, t, TFF_PLAIN_IDENTIFIER); + pp_cxx_whitespace (pp); + pp_equal (pp); + pp_cxx_whitespace (pp); + push_deferring_access_checks (dk_no_check); + t = tsubst (t, args, tf_none, NULL_TREE); + pop_deferring_access_checks (); + /* Strip typedefs. We can't just use TFF_CHASE_TYPEDEF because + pp_simple_type_specifier doesn't know about it. */ + t = strip_typedefs (t, NULL, STF_USER_VISIBLE); + dump_type (pp, t, TFF_PLAIN_IDENTIFIER); + } +} + +/* Dump a human-readable equivalent of the alias template + specialization of T. */ + +static void +dump_alias_template_specialization (cxx_pretty_printer *pp, tree t, int flags) +{ + gcc_assert (alias_template_specialization_p (t, nt_opaque)); + + tree decl = TYPE_NAME (t); + if (!(flags & TFF_UNQUALIFIED_NAME)) + dump_scope (pp, CP_DECL_CONTEXT (decl), flags); + pp_cxx_tree_identifier (pp, DECL_NAME (decl)); + dump_template_parms (pp, DECL_TEMPLATE_INFO (decl), + /*primary=*/false, + flags & ~TFF_TEMPLATE_HEADER); +} + +/* Dump a human-readable equivalent of TYPE. FLAGS controls the + format. */ + +static void +dump_type (cxx_pretty_printer *pp, tree t, int flags) +{ + if (t == NULL_TREE) + return; + + /* Don't print e.g. "struct mytypedef". */ + if (TYPE_P (t) && typedef_variant_p (t)) + { + tree decl = TYPE_NAME (t); + if ((flags & TFF_CHASE_TYPEDEF) + || DECL_SELF_REFERENCE_P (decl) + || (!flag_pretty_templates + && DECL_LANG_SPECIFIC (decl) && DECL_TEMPLATE_INFO (decl))) + { + unsigned int stf_flags = (!(pp->flags & pp_c_flag_gnu_v3) + ? STF_USER_VISIBLE : 0); + t = strip_typedefs (t, NULL, stf_flags); + } + else if (alias_template_specialization_p (t, nt_opaque)) + { + dump_alias_template_specialization (pp, t, flags); + return; + } + else if (same_type_p (t, TREE_TYPE (decl))) + t = decl; + else + { + pp_cxx_cv_qualifier_seq (pp, t); + if (! (flags & TFF_UNQUALIFIED_NAME)) + dump_scope (pp, CP_DECL_CONTEXT (decl), flags); + pp_cxx_tree_identifier (pp, TYPE_IDENTIFIER (t)); + return; + } + } + + if (TYPE_PTRMEMFUNC_P (t)) + goto offset_type; + + switch (TREE_CODE (t)) + { + case LANG_TYPE: + if (t == init_list_type_node) + pp_string (pp, M_("<brace-enclosed initializer list>")); + else if (t == unknown_type_node) + pp_string (pp, M_("<unresolved overloaded function type>")); + else + { + pp_cxx_cv_qualifier_seq (pp, t); + pp_cxx_tree_identifier (pp, TYPE_IDENTIFIER (t)); + } + break; + + case TREE_LIST: + /* A list of function parms. */ + dump_parameters (pp, t, flags); + break; + + case IDENTIFIER_NODE: + pp_cxx_tree_identifier (pp, t); + break; + + case TREE_BINFO: + dump_type (pp, BINFO_TYPE (t), flags); + break; + + case RECORD_TYPE: + case UNION_TYPE: + case ENUMERAL_TYPE: + dump_aggr_type (pp, t, flags); + break; + + case TYPE_DECL: + if (flags & TFF_CHASE_TYPEDEF) + { + dump_type (pp, DECL_ORIGINAL_TYPE (t) + ? DECL_ORIGINAL_TYPE (t) : TREE_TYPE (t), flags); + break; + } + /* Fall through. */ + + case TEMPLATE_DECL: + case NAMESPACE_DECL: + dump_decl (pp, t, flags & ~TFF_DECL_SPECIFIERS); + break; + + case INTEGER_TYPE: + case REAL_TYPE: + case VOID_TYPE: + case OPAQUE_TYPE: + case BOOLEAN_TYPE: + case COMPLEX_TYPE: + case VECTOR_TYPE: + case FIXED_POINT_TYPE: + pp_type_specifier_seq (pp, t); + break; + + case TEMPLATE_TEMPLATE_PARM: + /* For parameters inside template signature. */ + if (TYPE_IDENTIFIER (t)) + pp_cxx_tree_identifier (pp, TYPE_IDENTIFIER (t)); + else + pp_cxx_canonical_template_parameter (pp, t); + break; + + case BOUND_TEMPLATE_TEMPLATE_PARM: + { + tree args = TYPE_TI_ARGS (t); + pp_cxx_cv_qualifier_seq (pp, t); + pp_cxx_tree_identifier (pp, TYPE_IDENTIFIER (t)); + pp_cxx_begin_template_argument_list (pp); + dump_template_argument_list (pp, args, flags); + pp_cxx_end_template_argument_list (pp); + } + break; + + case TEMPLATE_TYPE_PARM: + pp_cxx_cv_qualifier_seq (pp, t); + if (template_placeholder_p (t)) + { + t = TREE_TYPE (CLASS_PLACEHOLDER_TEMPLATE (t)); + pp_cxx_tree_identifier (pp, TYPE_IDENTIFIER (t)); + pp_string (pp, "<...auto...>"); + } + else if (TYPE_IDENTIFIER (t)) + pp_cxx_tree_identifier (pp, TYPE_IDENTIFIER (t)); + else + pp_cxx_canonical_template_parameter + (pp, TEMPLATE_TYPE_PARM_INDEX (t)); + /* If this is a constrained placeholder, add the requirements. */ + if (tree c = PLACEHOLDER_TYPE_CONSTRAINTS (t)) + pp_cxx_constrained_type_spec (pp, c); + break; + + /* This is not always necessary for pointers and such, but doing this + reduces code size. */ + case ARRAY_TYPE: + case POINTER_TYPE: + case REFERENCE_TYPE: + case OFFSET_TYPE: + offset_type: + case FUNCTION_TYPE: + case METHOD_TYPE: + { + dump_type_prefix (pp, t, flags); + dump_type_suffix (pp, t, flags); + break; + } + case TYPENAME_TYPE: + if (! (flags & TFF_CHASE_TYPEDEF) + && DECL_ORIGINAL_TYPE (TYPE_NAME (t))) + { + dump_decl (pp, TYPE_NAME (t), TFF_PLAIN_IDENTIFIER); + break; + } + pp_cxx_cv_qualifier_seq (pp, t); + pp_cxx_ws_string (pp, + TYPENAME_IS_ENUM_P (t) ? "enum" + : TYPENAME_IS_CLASS_P (t) ? "class" + : "typename"); + dump_typename (pp, t, flags); + break; + + case UNBOUND_CLASS_TEMPLATE: + if (! (flags & TFF_UNQUALIFIED_NAME)) + { + dump_type (pp, TYPE_CONTEXT (t), flags); + pp_cxx_colon_colon (pp); + } + pp_cxx_ws_string (pp, "template"); + dump_type (pp, TYPE_IDENTIFIER (t), flags); + break; + + case TYPEOF_TYPE: + pp_cxx_ws_string (pp, "__typeof__"); + pp_cxx_whitespace (pp); + pp_cxx_left_paren (pp); + dump_expr (pp, TYPEOF_TYPE_EXPR (t), flags & ~TFF_EXPR_IN_PARENS); + pp_cxx_right_paren (pp); + break; + + case UNDERLYING_TYPE: + pp_cxx_ws_string (pp, "__underlying_type"); + pp_cxx_whitespace (pp); + pp_cxx_left_paren (pp); + dump_expr (pp, UNDERLYING_TYPE_TYPE (t), flags & ~TFF_EXPR_IN_PARENS); + pp_cxx_right_paren (pp); + break; + + case TYPE_PACK_EXPANSION: + dump_type (pp, PACK_EXPANSION_PATTERN (t), flags); + pp_cxx_ws_string (pp, "..."); + break; + + case TYPE_ARGUMENT_PACK: + dump_template_argument (pp, t, flags); + break; + + case DECLTYPE_TYPE: + pp_cxx_ws_string (pp, "decltype"); + pp_cxx_whitespace (pp); + pp_cxx_left_paren (pp); + dump_expr (pp, DECLTYPE_TYPE_EXPR (t), flags & ~TFF_EXPR_IN_PARENS); + pp_cxx_right_paren (pp); + break; + + case NULLPTR_TYPE: + pp_string (pp, "std::nullptr_t"); + break; + + default: + pp_unsupported_tree (pp, t); + /* Fall through. */ + + case ERROR_MARK: + pp_string (pp, M_("<type error>")); + break; + } +} + +/* Dump a TYPENAME_TYPE. We need to notice when the context is itself + a TYPENAME_TYPE. */ + +static void +dump_typename (cxx_pretty_printer *pp, tree t, int flags) +{ + tree ctx = TYPE_CONTEXT (t); + + if (TREE_CODE (ctx) == TYPENAME_TYPE) + dump_typename (pp, ctx, flags); + else + dump_type (pp, ctx, flags & ~TFF_CLASS_KEY_OR_ENUM); + pp_cxx_colon_colon (pp); + dump_decl (pp, TYPENAME_TYPE_FULLNAME (t), flags); +} + +/* Return the name of the supplied aggregate, or enumeral type. */ + +const char * +class_key_or_enum_as_string (tree t) +{ + if (TREE_CODE (t) == ENUMERAL_TYPE) + { + if (SCOPED_ENUM_P (t)) + return "enum class"; + else + return "enum"; + } + else if (TREE_CODE (t) == UNION_TYPE) + return "union"; + else if (TYPE_LANG_SPECIFIC (t) && CLASSTYPE_DECLARED_CLASS (t)) + return "class"; + else + return "struct"; +} + +/* Print out a class declaration T under the control of FLAGS, + in the form `class foo'. */ + +static void +dump_aggr_type (cxx_pretty_printer *pp, tree t, int flags) +{ + const char *variety = class_key_or_enum_as_string (t); + int typdef = 0; + int tmplate = 0; + + pp_cxx_cv_qualifier_seq (pp, t); + + if (flags & TFF_CLASS_KEY_OR_ENUM) + pp_cxx_ws_string (pp, variety); + + tree decl = TYPE_NAME (t); + + if (decl) + { + typdef = (!DECL_ARTIFICIAL (decl) + /* An alias specialization is not considered to be a + typedef. */ + && !alias_template_specialization_p (t, nt_opaque)); + + if ((typdef + && ((flags & TFF_CHASE_TYPEDEF) + || (!flag_pretty_templates && DECL_LANG_SPECIFIC (decl) + && DECL_TEMPLATE_INFO (decl)))) + || DECL_SELF_REFERENCE_P (decl)) + { + t = TYPE_MAIN_VARIANT (t); + decl = TYPE_NAME (t); + typdef = 0; + } + + tmplate = !typdef && TREE_CODE (t) != ENUMERAL_TYPE + && TYPE_LANG_SPECIFIC (t) && CLASSTYPE_TEMPLATE_INFO (t) + && (TREE_CODE (CLASSTYPE_TI_TEMPLATE (t)) != TEMPLATE_DECL + || PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (t))); + + if (! (flags & TFF_UNQUALIFIED_NAME)) + dump_scope (pp, CP_DECL_CONTEXT (decl), flags | TFF_SCOPE); + flags &= ~TFF_UNQUALIFIED_NAME; + if (tmplate) + { + /* Because the template names are mangled, we have to locate + the most general template, and use that name. */ + tree tpl = TYPE_TI_TEMPLATE (t); + + while (DECL_TEMPLATE_INFO (tpl)) + tpl = DECL_TI_TEMPLATE (tpl); + decl = tpl; + } + } + + if (LAMBDA_TYPE_P (t)) + { + /* A lambda's "type" is essentially its signature. */ + pp_string (pp, M_("<lambda")); + if (lambda_function (t)) + dump_parameters (pp, + FUNCTION_FIRST_USER_PARMTYPE (lambda_function (t)), + flags); + pp_greater (pp); + } + else if (!decl || IDENTIFIER_ANON_P (DECL_NAME (decl))) + { + if (flags & TFF_CLASS_KEY_OR_ENUM) + pp_string (pp, M_("<unnamed>")); + else + pp_printf (pp, M_("<unnamed %s>"), variety); + } + else + pp_cxx_tree_identifier (pp, DECL_NAME (decl)); + + dump_module_suffix (pp, decl); + + if (tmplate) + dump_template_parms (pp, TYPE_TEMPLATE_INFO (t), + !CLASSTYPE_USE_TEMPLATE (t), + flags & ~TFF_TEMPLATE_HEADER); +} + +/* Dump into the obstack the initial part of the output for a given type. + This is necessary when dealing with things like functions returning + functions. Examples: + + return type of `int (* fee ())()': pointer -> function -> int. Both + pointer (and reference and offset) and function (and member) types must + deal with prefix and suffix. + + Arrays must also do this for DECL nodes, like int a[], and for things like + int *[]&. */ + +static void +dump_type_prefix (cxx_pretty_printer *pp, tree t, int flags) +{ + if (TYPE_PTRMEMFUNC_P (t)) + { + t = TYPE_PTRMEMFUNC_FN_TYPE (t); + goto offset_type; + } + + switch (TREE_CODE (t)) + { + case POINTER_TYPE: + case REFERENCE_TYPE: + { + tree sub = TREE_TYPE (t); + + dump_type_prefix (pp, sub, flags); + if (TREE_CODE (sub) == ARRAY_TYPE + || TREE_CODE (sub) == FUNCTION_TYPE) + { + pp_cxx_whitespace (pp); + pp_cxx_left_paren (pp); + pp_c_attributes_display (pp, TYPE_ATTRIBUTES (sub)); + } + if (TYPE_PTR_P (t)) + pp_star (pp); + else if (TYPE_REF_P (t)) + { + if (TYPE_REF_IS_RVALUE (t)) + pp_ampersand_ampersand (pp); + else + pp_ampersand (pp); + } + pp->padding = pp_before; + pp_cxx_cv_qualifier_seq (pp, t); + } + break; + + case OFFSET_TYPE: + offset_type: + dump_type_prefix (pp, TREE_TYPE (t), flags); + if (TREE_CODE (t) == OFFSET_TYPE) /* pmfs deal with this in d_t_p */ + { + pp_maybe_space (pp); + if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE) + pp_cxx_left_paren (pp); + dump_type (pp, TYPE_OFFSET_BASETYPE (t), flags); + pp_cxx_colon_colon (pp); + } + pp_cxx_star (pp); + pp_cxx_cv_qualifier_seq (pp, t); + pp->padding = pp_before; + break; + + /* This can be reached without a pointer when dealing with + templates, e.g. std::is_function. */ + case FUNCTION_TYPE: + dump_type_prefix (pp, TREE_TYPE (t), flags); + break; + + case METHOD_TYPE: + dump_type_prefix (pp, TREE_TYPE (t), flags); + pp_maybe_space (pp); + pp_cxx_left_paren (pp); + dump_aggr_type (pp, TYPE_METHOD_BASETYPE (t), flags); + pp_cxx_colon_colon (pp); + break; + + case ARRAY_TYPE: + dump_type_prefix (pp, TREE_TYPE (t), flags); + break; + + case ENUMERAL_TYPE: + case IDENTIFIER_NODE: + case INTEGER_TYPE: + case BOOLEAN_TYPE: + case REAL_TYPE: + case RECORD_TYPE: + case TEMPLATE_TYPE_PARM: + case TEMPLATE_TEMPLATE_PARM: + case BOUND_TEMPLATE_TEMPLATE_PARM: + case TREE_LIST: + case TYPE_DECL: + case TREE_VEC: + case UNION_TYPE: + case LANG_TYPE: + case VOID_TYPE: + case OPAQUE_TYPE: + case TYPENAME_TYPE: + case COMPLEX_TYPE: + case VECTOR_TYPE: + case TYPEOF_TYPE: + case UNDERLYING_TYPE: + case DECLTYPE_TYPE: + case TYPE_PACK_EXPANSION: + case FIXED_POINT_TYPE: + case NULLPTR_TYPE: + dump_type (pp, t, flags); + pp->padding = pp_before; + break; + + default: + pp_unsupported_tree (pp, t); + /* fall through. */ + case ERROR_MARK: + pp_string (pp, M_("<typeprefixerror>")); + break; + } +} + +/* Dump the suffix of type T, under control of FLAGS. This is the part + which appears after the identifier (or function parms). */ + +static void +dump_type_suffix (cxx_pretty_printer *pp, tree t, int flags) +{ + if (TYPE_PTRMEMFUNC_P (t)) + t = TYPE_PTRMEMFUNC_FN_TYPE (t); + + switch (TREE_CODE (t)) + { + case POINTER_TYPE: + case REFERENCE_TYPE: + case OFFSET_TYPE: + if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE + || TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE) + pp_cxx_right_paren (pp); + if (TREE_CODE (t) == POINTER_TYPE) + flags |= TFF_POINTER; + dump_type_suffix (pp, TREE_TYPE (t), flags); + break; + + case FUNCTION_TYPE: + case METHOD_TYPE: + { + tree arg; + if (TREE_CODE (t) == METHOD_TYPE) + /* Can only be reached through a pointer. */ + pp_cxx_right_paren (pp); + arg = TYPE_ARG_TYPES (t); + if (TREE_CODE (t) == METHOD_TYPE) + arg = TREE_CHAIN (arg); + + /* Function pointers don't have default args. Not in standard C++, + anyway; they may in g++, but we'll just pretend otherwise. */ + dump_parameters (pp, arg, flags & ~TFF_FUNCTION_DEFAULT_ARGUMENTS); + + pp->padding = pp_before; + pp_cxx_cv_qualifiers (pp, type_memfn_quals (t), + TREE_CODE (t) == FUNCTION_TYPE + && (flags & TFF_POINTER)); + dump_ref_qualifier (pp, t, flags); + if (tx_safe_fn_type_p (t)) + pp_cxx_ws_string (pp, "transaction_safe"); + dump_exception_spec (pp, TYPE_RAISES_EXCEPTIONS (t), flags); + dump_type_suffix (pp, TREE_TYPE (t), flags); + break; + } + + case ARRAY_TYPE: + pp_maybe_space (pp); + pp_cxx_left_bracket (pp); + if (tree dtype = TYPE_DOMAIN (t)) + { + tree max = TYPE_MAX_VALUE (dtype); + /* Zero-length arrays have a null upper bound in C and SIZE_MAX + in C++. Handle both since the type might be constructed by + the middle end and end up here as a result of a warning (see + PR c++/97201). */ + if (!max || integer_all_onesp (max)) + pp_character (pp, '0'); + else if (tree_fits_shwi_p (max)) + pp_wide_integer (pp, tree_to_shwi (max) + 1); + else + { + STRIP_NOPS (max); + if (TREE_CODE (max) == SAVE_EXPR) + max = TREE_OPERAND (max, 0); + if (TREE_CODE (max) == MINUS_EXPR + || TREE_CODE (max) == PLUS_EXPR) + { + max = TREE_OPERAND (max, 0); + while (CONVERT_EXPR_P (max)) + max = TREE_OPERAND (max, 0); + } + else + max = fold_build2_loc (input_location, + PLUS_EXPR, dtype, max, + build_int_cst (dtype, 1)); + dump_expr (pp, max, flags & ~TFF_EXPR_IN_PARENS); + } + } + pp_cxx_right_bracket (pp); + dump_type_suffix (pp, TREE_TYPE (t), flags); + break; + + case ENUMERAL_TYPE: + case IDENTIFIER_NODE: + case INTEGER_TYPE: + case BOOLEAN_TYPE: + case REAL_TYPE: + case RECORD_TYPE: + case TEMPLATE_TYPE_PARM: + case TEMPLATE_TEMPLATE_PARM: + case BOUND_TEMPLATE_TEMPLATE_PARM: + case TREE_LIST: + case TYPE_DECL: + case TREE_VEC: + case UNION_TYPE: + case LANG_TYPE: + case VOID_TYPE: + case OPAQUE_TYPE: + case TYPENAME_TYPE: + case COMPLEX_TYPE: + case VECTOR_TYPE: + case TYPEOF_TYPE: + case UNDERLYING_TYPE: + case DECLTYPE_TYPE: + case TYPE_PACK_EXPANSION: + case FIXED_POINT_TYPE: + case NULLPTR_TYPE: + break; + + default: + pp_unsupported_tree (pp, t); + case ERROR_MARK: + /* Don't mark it here, we should have already done in + dump_type_prefix. */ + break; + } +} + +static void +dump_global_iord (cxx_pretty_printer *pp, tree t) +{ + const char *p = NULL; + + if (DECL_GLOBAL_CTOR_P (t)) + p = M_("(static initializers for %s)"); + else if (DECL_GLOBAL_DTOR_P (t)) + p = M_("(static destructors for %s)"); + else + gcc_unreachable (); + + pp_printf (pp, p, DECL_SOURCE_FILE (t)); +} + +static void +dump_simple_decl (cxx_pretty_printer *pp, tree t, tree type, int flags) +{ + if (template_parm_object_p (t)) + return dump_expr (pp, DECL_INITIAL (t), flags); + + if (flags & TFF_DECL_SPECIFIERS) + { + if (concept_definition_p (t)) + pp_cxx_ws_string (pp, "concept"); + else if (VAR_P (t) && DECL_DECLARED_CONSTEXPR_P (t)) + pp_cxx_ws_string (pp, "constexpr"); + + if (!standard_concept_p (t)) + dump_type_prefix (pp, type, flags & ~TFF_UNQUALIFIED_NAME); + pp_maybe_space (pp); + } + if (! (flags & TFF_UNQUALIFIED_NAME) + && TREE_CODE (t) != PARM_DECL + && (!DECL_INITIAL (t) + || TREE_CODE (DECL_INITIAL (t)) != TEMPLATE_PARM_INDEX)) + dump_scope (pp, CP_DECL_CONTEXT (t), flags); + flags &= ~TFF_UNQUALIFIED_NAME; + if ((flags & TFF_DECL_SPECIFIERS) + && DECL_TEMPLATE_PARM_P (t) + && TEMPLATE_PARM_PARAMETER_PACK (DECL_INITIAL (t))) + pp_string (pp, "..."); + if (DECL_NAME (t)) + { + if (TREE_CODE (t) == FIELD_DECL && DECL_NORMAL_CAPTURE_P (t)) + { + pp_less (pp); + pp_string (pp, IDENTIFIER_POINTER (DECL_NAME (t)) + 2); + pp_string (pp, " capture>"); + } + else + dump_decl (pp, DECL_NAME (t), flags); + } + else if (DECL_DECOMPOSITION_P (t)) + pp_string (pp, M_("<structured bindings>")); + else + pp_string (pp, M_("<anonymous>")); + + dump_module_suffix (pp, t); + + if (flags & TFF_DECL_SPECIFIERS) + dump_type_suffix (pp, type, flags); +} + +/* Print an IDENTIFIER_NODE that is the name of a declaration. */ + +static void +dump_decl_name (cxx_pretty_printer *pp, tree t, int flags) +{ + /* These special cases are duplicated here so that other functions + can feed identifiers to error and get them demangled properly. */ + if (IDENTIFIER_CONV_OP_P (t)) + { + pp_cxx_ws_string (pp, "operator"); + /* Not exactly IDENTIFIER_TYPE_VALUE. */ + dump_type (pp, TREE_TYPE (t), flags); + return; + } + if (dguide_name_p (t)) + { + dump_decl (pp, CLASSTYPE_TI_TEMPLATE (TREE_TYPE (t)), + TFF_UNQUALIFIED_NAME); + return; + } + + const char *str = IDENTIFIER_POINTER (t); + if (startswith (str, "_ZGR")) + { + pp_cxx_ws_string (pp, "<temporary>"); + return; + } + + pp_cxx_tree_identifier (pp, t); +} + +/* Dump a human readable string for the decl T under control of FLAGS. */ + +static void +dump_decl (cxx_pretty_printer *pp, tree t, int flags) +{ + if (t == NULL_TREE) + return; + + /* If doing Objective-C++, give Objective-C a chance to demangle + Objective-C method names. */ + if (c_dialect_objc ()) + { + const char *demangled = objc_maybe_printable_name (t, flags); + if (demangled) + { + pp_string (pp, demangled); + return; + } + } + + switch (TREE_CODE (t)) + { + case TYPE_DECL: + /* Don't say 'typedef class A' */ + if (DECL_ARTIFICIAL (t) && !DECL_SELF_REFERENCE_P (t)) + { + if ((flags & TFF_DECL_SPECIFIERS) + && TREE_CODE (TREE_TYPE (t)) == TEMPLATE_TYPE_PARM) + { + /* Say `class T' not just `T'. */ + pp_cxx_ws_string (pp, "class"); + + /* Emit the `...' for a parameter pack. */ + if (TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (t))) + pp_cxx_ws_string (pp, "..."); + } + + dump_type (pp, TREE_TYPE (t), flags); + break; + } + if (TYPE_DECL_ALIAS_P (t) + && (flags & TFF_DECL_SPECIFIERS + || flags & TFF_CLASS_KEY_OR_ENUM)) + { + pp_cxx_ws_string (pp, "using"); + dump_decl (pp, DECL_NAME (t), flags); + pp_cxx_whitespace (pp); + pp_cxx_ws_string (pp, "="); + pp_cxx_whitespace (pp); + dump_type (pp, (DECL_ORIGINAL_TYPE (t) + ? DECL_ORIGINAL_TYPE (t) : TREE_TYPE (t)), + flags); + break; + } + if ((flags & TFF_DECL_SPECIFIERS) + && !DECL_SELF_REFERENCE_P (t)) + pp_cxx_ws_string (pp, "typedef"); + dump_simple_decl (pp, t, DECL_ORIGINAL_TYPE (t) + ? DECL_ORIGINAL_TYPE (t) : TREE_TYPE (t), + flags); + break; + + case VAR_DECL: + if (DECL_NAME (t) && VTABLE_NAME_P (DECL_NAME (t))) + { + pp_string (pp, M_("vtable for ")); + gcc_assert (TYPE_P (DECL_CONTEXT (t))); + dump_type (pp, DECL_CONTEXT (t), flags); + break; + } + /* Fall through. */ + case FIELD_DECL: + case PARM_DECL: + dump_simple_decl (pp, t, TREE_TYPE (t), flags); + + /* Handle variable template specializations. */ + if (VAR_P (t) + && DECL_LANG_SPECIFIC (t) + && DECL_TEMPLATE_INFO (t) + && PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (t))) + { + pp_cxx_begin_template_argument_list (pp); + tree args = INNERMOST_TEMPLATE_ARGS (DECL_TI_ARGS (t)); + dump_template_argument_list (pp, args, flags); + pp_cxx_end_template_argument_list (pp); + } + break; + + case RESULT_DECL: + pp_string (pp, M_("<return value> ")); + dump_simple_decl (pp, t, TREE_TYPE (t), flags); + break; + + case NAMESPACE_DECL: + if (flags & TFF_DECL_SPECIFIERS) + pp->declaration (t); + else + { + if (! (flags & TFF_UNQUALIFIED_NAME)) + dump_scope (pp, CP_DECL_CONTEXT (t), flags); + flags &= ~TFF_UNQUALIFIED_NAME; + if (DECL_NAME (t) == NULL_TREE) + { + if (!(pp->flags & pp_c_flag_gnu_v3)) + pp_cxx_ws_string (pp, M_("{anonymous}")); + else + pp_cxx_ws_string (pp, M_("(anonymous namespace)")); + } + else + pp_cxx_tree_identifier (pp, DECL_NAME (t)); + } + break; + + case SCOPE_REF: + dump_type (pp, TREE_OPERAND (t, 0), flags); + pp_cxx_colon_colon (pp); + dump_decl (pp, TREE_OPERAND (t, 1), TFF_UNQUALIFIED_NAME); + break; + + case ARRAY_REF: + dump_decl (pp, TREE_OPERAND (t, 0), flags); + pp_cxx_left_bracket (pp); + dump_decl (pp, TREE_OPERAND (t, 1), flags); + pp_cxx_right_bracket (pp); + break; + + /* So that we can do dump_decl on an aggr type. */ + case RECORD_TYPE: + case UNION_TYPE: + case ENUMERAL_TYPE: + dump_type (pp, t, flags); + break; + + case BIT_NOT_EXPR: + /* This is a pseudo destructor call which has not been folded into + a PSEUDO_DTOR_EXPR yet. */ + pp_cxx_complement (pp); + dump_type (pp, TREE_OPERAND (t, 0), flags); + break; + + case TYPE_EXPR: + gcc_unreachable (); + break; + + case IDENTIFIER_NODE: + dump_decl_name (pp, t, flags); + break; + + case OVERLOAD: + if (!OVL_SINGLE_P (t)) + { + tree ctx = ovl_scope (t); + if (ctx != global_namespace) + { + if (TYPE_P (ctx)) + dump_type (pp, ctx, flags); + else + dump_decl (pp, ctx, flags); + pp_cxx_colon_colon (pp); + } + dump_decl (pp, OVL_NAME (t), flags); + break; + } + + /* If there's only one function, just treat it like an ordinary + FUNCTION_DECL. */ + t = OVL_FIRST (t); + /* Fall through. */ + + case FUNCTION_DECL: + if (! DECL_LANG_SPECIFIC (t)) + { + if (DECL_ABSTRACT_ORIGIN (t) + && DECL_ABSTRACT_ORIGIN (t) != t) + dump_decl (pp, DECL_ABSTRACT_ORIGIN (t), flags); + else + dump_function_name (pp, t, flags); + } + else if (DECL_GLOBAL_CTOR_P (t) || DECL_GLOBAL_DTOR_P (t)) + dump_global_iord (pp, t); + else + dump_function_decl (pp, t, flags); + break; + + case TEMPLATE_DECL: + dump_template_decl (pp, t, flags); + break; + + case CONCEPT_DECL: + dump_simple_decl (pp, t, TREE_TYPE (t), flags); + break; + + case WILDCARD_DECL: + pp_string (pp, "<wildcard>"); + break; + + case TEMPLATE_ID_EXPR: + { + tree name = TREE_OPERAND (t, 0); + tree args = TREE_OPERAND (t, 1); + + if (!identifier_p (name)) + name = OVL_NAME (name); + dump_decl (pp, name, flags); + pp_cxx_begin_template_argument_list (pp); + if (args == error_mark_node) + pp_string (pp, M_("<template arguments error>")); + else if (args) + dump_template_argument_list + (pp, args, flags|TFF_NO_OMIT_DEFAULT_TEMPLATE_ARGUMENTS); + pp_cxx_end_template_argument_list (pp); + } + break; + + case LABEL_DECL: + if (DECL_NAME (t)) + pp_cxx_tree_identifier (pp, DECL_NAME (t)); + else + dump_generic_node (pp, t, 0, TDF_SLIM, false); + break; + + case CONST_DECL: + if ((TREE_TYPE (t) != NULL_TREE && NEXT_CODE (t) == ENUMERAL_TYPE) + || (DECL_INITIAL (t) && + TREE_CODE (DECL_INITIAL (t)) == TEMPLATE_PARM_INDEX)) + dump_simple_decl (pp, t, TREE_TYPE (t), flags); + else if (DECL_NAME (t)) + dump_decl (pp, DECL_NAME (t), flags); + else if (DECL_INITIAL (t)) + dump_expr (pp, DECL_INITIAL (t), flags | TFF_EXPR_IN_PARENS); + else + pp_string (pp, M_("<enumerator>")); + break; + + case USING_DECL: + { + pp_cxx_ws_string (pp, "using"); + tree scope = USING_DECL_SCOPE (t); + bool variadic = false; + if (PACK_EXPANSION_P (scope)) + { + scope = PACK_EXPANSION_PATTERN (scope); + variadic = true; + } + dump_type (pp, scope, flags); + pp_cxx_colon_colon (pp); + dump_decl (pp, DECL_NAME (t), flags); + if (variadic) + pp_cxx_ws_string (pp, "..."); + } + break; + + case STATIC_ASSERT: + pp->declaration (t); + break; + + case BASELINK: + dump_decl (pp, BASELINK_FUNCTIONS (t), flags); + break; + + case NON_DEPENDENT_EXPR: + dump_expr (pp, t, flags); + break; + + case TEMPLATE_TYPE_PARM: + if (flags & TFF_DECL_SPECIFIERS) + pp->declaration (t); + else + pp->type_id (t); + break; + + case UNBOUND_CLASS_TEMPLATE: + case TYPE_PACK_EXPANSION: + case TREE_BINFO: + dump_type (pp, t, flags); + break; + + default: + pp_unsupported_tree (pp, t); + /* Fall through. */ + + case ERROR_MARK: + pp_string (pp, M_("<declaration error>")); + break; + } +} + +/* Dump a template declaration T under control of FLAGS. This means the + 'template <...> leaders plus the 'class X' or 'void fn(...)' part. */ + +static void +dump_template_decl (cxx_pretty_printer *pp, tree t, int flags) +{ + tree orig_parms = DECL_TEMPLATE_PARMS (t); + tree parms; + int i; + + if (flags & TFF_TEMPLATE_HEADER) + { + for (parms = orig_parms = nreverse (orig_parms); + parms; + parms = TREE_CHAIN (parms)) + { + tree inner_parms = INNERMOST_TEMPLATE_PARMS (parms); + int len = TREE_VEC_LENGTH (inner_parms); + + if (len == 0) + { + /* Skip over the dummy template levels of a template template + parm. */ + gcc_assert (TREE_CODE (TREE_TYPE (t)) == TEMPLATE_TEMPLATE_PARM); + continue; + } + + pp_cxx_ws_string (pp, "template"); + pp_cxx_begin_template_argument_list (pp); + + /* If we've shown the template prefix, we'd better show the + parameters' and decl's type too. */ + flags |= TFF_DECL_SPECIFIERS; + + for (i = 0; i < len; i++) + { + if (i) + pp_separate_with_comma (pp); + dump_template_parameter (pp, TREE_VEC_ELT (inner_parms, i), + flags); + } + pp_cxx_end_template_argument_list (pp); + pp_cxx_whitespace (pp); + } + nreverse(orig_parms); + + if (DECL_TEMPLATE_TEMPLATE_PARM_P (t)) + { + /* Say `template<arg> class TT' not just `template<arg> TT'. */ + pp_cxx_ws_string (pp, "class"); + + /* If this is a parameter pack, print the ellipsis. */ + if (TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (t))) + pp_cxx_ws_string (pp, "..."); + } + + /* Only print the requirements if we're also printing + the template header. */ + if (flag_concepts) + if (tree ci = get_constraints (t)) + if (check_constraint_info (ci)) + if (tree reqs = CI_TEMPLATE_REQS (ci)) + { + pp_cxx_requires_clause (pp, reqs); + pp_cxx_whitespace (pp); + } + } + + + if (DECL_CLASS_TEMPLATE_P (t)) + dump_type (pp, TREE_TYPE (t), + ((flags & ~TFF_CLASS_KEY_OR_ENUM) | TFF_TEMPLATE_NAME + | (flags & TFF_DECL_SPECIFIERS ? TFF_CLASS_KEY_OR_ENUM : 0))); + else if (DECL_TEMPLATE_RESULT (t) + && (VAR_P (DECL_TEMPLATE_RESULT (t)) + /* Alias template. */ + || DECL_TYPE_TEMPLATE_P (t) + /* Concept definition. &*/ + || TREE_CODE (DECL_TEMPLATE_RESULT (t)) == CONCEPT_DECL)) + dump_decl (pp, DECL_TEMPLATE_RESULT (t), flags | TFF_TEMPLATE_NAME); + else + { + gcc_assert (TREE_TYPE (t)); + switch (NEXT_CODE (t)) + { + case METHOD_TYPE: + case FUNCTION_TYPE: + dump_function_decl (pp, t, flags | TFF_TEMPLATE_NAME); + break; + default: + /* This case can occur with some invalid code. */ + dump_type (pp, TREE_TYPE (t), + (flags & ~TFF_CLASS_KEY_OR_ENUM) | TFF_TEMPLATE_NAME + | (flags & TFF_DECL_SPECIFIERS + ? TFF_CLASS_KEY_OR_ENUM : 0)); + } + } +} + +/* find_typenames looks through the type of the function template T + and returns a vec containing any typedefs, decltypes or TYPENAME_TYPEs + it finds. */ + +struct find_typenames_t +{ + hash_set<tree> *p_set; + vec<tree, va_gc> *typenames; +}; + +static tree +find_typenames_r (tree *tp, int *walk_subtrees, void *data) +{ + struct find_typenames_t *d = (struct find_typenames_t *)data; + tree mv = NULL_TREE; + + if (TYPE_P (*tp) && is_typedef_decl (TYPE_NAME (*tp))) + /* Add the type of the typedef without any additional cv-quals. */ + mv = TREE_TYPE (TYPE_NAME (*tp)); + else if (TREE_CODE (*tp) == TYPENAME_TYPE + || TREE_CODE (*tp) == DECLTYPE_TYPE) + /* Add the typename without any cv-qualifiers. */ + mv = TYPE_MAIN_VARIANT (*tp); + + if (PACK_EXPANSION_P (*tp)) + { + /* Don't mess with parameter packs since we don't remember + the pack expansion context for a particular typename. */ + *walk_subtrees = false; + return NULL_TREE; + } + + if (mv && (mv == *tp || !d->p_set->add (mv))) + vec_safe_push (d->typenames, mv); + + return NULL_TREE; +} + +static vec<tree, va_gc> * +find_typenames (tree t) +{ + struct find_typenames_t ft; + ft.p_set = new hash_set<tree>; + ft.typenames = NULL; + cp_walk_tree (&TREE_TYPE (DECL_TEMPLATE_RESULT (t)), + find_typenames_r, &ft, ft.p_set); + delete ft.p_set; + return ft.typenames; +} + +/* Output the "[with ...]" clause for a template instantiation T iff + TEMPLATE_PARMS, TEMPLATE_ARGS and FLAGS are suitable. T may be NULL if + formatting a deduction/substitution diagnostic rather than an + instantiation. */ + +static void +dump_substitution (cxx_pretty_printer *pp, + tree t, tree template_parms, tree template_args, + int flags) +{ + if (template_parms != NULL_TREE && template_args != NULL_TREE + && !(flags & TFF_NO_TEMPLATE_BINDINGS)) + { + vec<tree, va_gc> *typenames = t ? find_typenames (t) : NULL; + dump_template_bindings (pp, template_parms, template_args, typenames); + } +} + +/* Dump the lambda function FN including its 'mutable' qualifier and any + template bindings. */ + +static void +dump_lambda_function (cxx_pretty_printer *pp, + tree fn, tree template_parms, tree template_args, + int flags) +{ + /* A lambda's signature is essentially its "type". */ + dump_type (pp, DECL_CONTEXT (fn), flags); + if (!(TYPE_QUALS (class_of_this_parm (TREE_TYPE (fn))) & TYPE_QUAL_CONST)) + { + pp->padding = pp_before; + pp_c_ws_string (pp, "mutable"); + } + dump_substitution (pp, fn, template_parms, template_args, flags); +} + +/* Pretty print a function decl. There are several ways we want to print a + function declaration. The TFF_ bits in FLAGS tells us how to behave. + As error can only apply the '#' flag once to give 0 and 1 for V, there + is %D which doesn't print the throw specs, and %F which does. */ + +static void +dump_function_decl (cxx_pretty_printer *pp, tree t, int flags) +{ + tree fntype; + tree parmtypes; + tree cname = NULL_TREE; + tree template_args = NULL_TREE; + tree template_parms = NULL_TREE; + int show_return = flags & TFF_RETURN_TYPE || flags & TFF_DECL_SPECIFIERS; + int do_outer_scope = ! (flags & TFF_UNQUALIFIED_NAME); + tree exceptions; + bool constexpr_p; + tree ret = NULL_TREE; + + int dump_function_name_flags = flags & ~TFF_UNQUALIFIED_NAME; + flags = dump_function_name_flags & ~TFF_TEMPLATE_NAME; + if (TREE_CODE (t) == TEMPLATE_DECL) + t = DECL_TEMPLATE_RESULT (t); + + /* Save the exceptions, in case t is a specialization and we are + emitting an error about incompatible specifications. */ + exceptions = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (t)); + + /* Likewise for the constexpr specifier, in case t is a specialization. */ + constexpr_p = (DECL_DECLARED_CONSTEXPR_P (t) + && !decl_implicit_constexpr_p (t)); + + /* Pretty print template instantiations only. */ + if (DECL_USE_TEMPLATE (t) && DECL_TEMPLATE_INFO (t) + && !(flags & TFF_NO_TEMPLATE_BINDINGS) + && flag_pretty_templates) + { + tree tmpl; + + template_args = DECL_TI_ARGS (t); + tmpl = most_general_template (t); + if (tmpl && TREE_CODE (tmpl) == TEMPLATE_DECL) + { + template_parms = DECL_TEMPLATE_PARMS (tmpl); + t = tmpl; + } + } + + if (DECL_NAME (t) && LAMBDA_FUNCTION_P (t)) + return dump_lambda_function (pp, t, template_parms, template_args, flags); + + fntype = TREE_TYPE (t); + parmtypes = FUNCTION_FIRST_USER_PARMTYPE (t); + + if (DECL_CLASS_SCOPE_P (t)) + cname = DECL_CONTEXT (t); + /* This is for partially instantiated template methods. */ + else if (TREE_CODE (fntype) == METHOD_TYPE) + cname = TREE_TYPE (TREE_VALUE (parmtypes)); + + if (flags & TFF_DECL_SPECIFIERS) + { + if (DECL_STATIC_FUNCTION_P (t)) + pp_cxx_ws_string (pp, "static"); + else if (DECL_VIRTUAL_P (t)) + pp_cxx_ws_string (pp, "virtual"); + + if (constexpr_p) + { + if (DECL_DECLARED_CONCEPT_P (t)) + pp_cxx_ws_string (pp, "concept"); + else if (DECL_IMMEDIATE_FUNCTION_P (t)) + pp_cxx_ws_string (pp, "consteval"); + else + pp_cxx_ws_string (pp, "constexpr"); + } + } + + /* Print the return type? */ + if (show_return) + show_return = (!DECL_CONV_FN_P (t) && !DECL_CONSTRUCTOR_P (t) + && !DECL_DESTRUCTOR_P (t) && !deduction_guide_p (t)); + if (show_return) + { + ret = fndecl_declared_return_type (t); + dump_type_prefix (pp, ret, flags); + } + + /* Print the function name. */ + if (!do_outer_scope) + /* Nothing. */; + else if (cname) + { + dump_type (pp, cname, flags); + pp_cxx_colon_colon (pp); + } + else + dump_scope (pp, CP_DECL_CONTEXT (t), flags); + + /* Name lookup for the rest of the function declarator is implicitly in the + scope of the function, so avoid printing redundant scope qualifiers. */ + auto cds = make_temp_override (current_dump_scope, CP_DECL_CONTEXT (t)); + + dump_function_name (pp, t, dump_function_name_flags); + + if (!(flags & TFF_NO_FUNCTION_ARGUMENTS)) + { + dump_parameters (pp, parmtypes, flags); + + if (TREE_CODE (fntype) == METHOD_TYPE) + { + pp->padding = pp_before; + pp_cxx_cv_qualifier_seq (pp, class_of_this_parm (fntype)); + dump_ref_qualifier (pp, fntype, flags); + } + + if (tx_safe_fn_type_p (fntype)) + { + pp->padding = pp_before; + pp_cxx_ws_string (pp, "transaction_safe"); + } + + if (flags & TFF_EXCEPTION_SPECIFICATION) + { + pp->padding = pp_before; + dump_exception_spec (pp, exceptions, flags); + } + + if (show_return) + dump_type_suffix (pp, ret, flags); + else if (deduction_guide_p (t)) + { + pp_cxx_ws_string (pp, "->"); + dump_type (pp, TREE_TYPE (TREE_TYPE (t)), flags); + } + + if (flag_concepts) + if (tree ci = get_constraints (t)) + if (tree reqs = CI_DECLARATOR_REQS (ci)) + pp_cxx_requires_clause (pp, reqs); + + dump_substitution (pp, t, template_parms, template_args, flags); + + if (tree base = DECL_INHERITED_CTOR_BASE (t)) + { + pp_cxx_ws_string (pp, "[inherited from"); + dump_type (pp, base, TFF_PLAIN_IDENTIFIER); + pp_character (pp, ']'); + } + } + else if (template_args) + { + bool need_comma = false; + int i; + pp_cxx_begin_template_argument_list (pp); + template_args = INNERMOST_TEMPLATE_ARGS (template_args); + for (i = 0; i < TREE_VEC_LENGTH (template_args); ++i) + { + tree arg = TREE_VEC_ELT (template_args, i); + if (need_comma) + pp_separate_with_comma (pp); + if (ARGUMENT_PACK_P (arg)) + pp_cxx_left_brace (pp); + dump_template_argument (pp, arg, TFF_PLAIN_IDENTIFIER); + if (ARGUMENT_PACK_P (arg)) + pp_cxx_right_brace (pp); + need_comma = true; + } + pp_cxx_end_template_argument_list (pp); + } +} + +/* Print a parameter list. If this is for a member function, the + member object ptr (and any other hidden args) should have + already been removed. */ + +static void +dump_parameters (cxx_pretty_printer *pp, tree parmtypes, int flags) +{ + int first = 1; + flags &= ~TFF_SCOPE; + pp_cxx_left_paren (pp); + + for (first = 1; parmtypes != void_list_node; + parmtypes = TREE_CHAIN (parmtypes)) + { + if (!first) + pp_separate_with_comma (pp); + first = 0; + if (!parmtypes) + { + pp_cxx_ws_string (pp, "..."); + break; + } + + dump_type (pp, TREE_VALUE (parmtypes), flags); + + if ((flags & TFF_FUNCTION_DEFAULT_ARGUMENTS) && TREE_PURPOSE (parmtypes)) + { + pp_cxx_whitespace (pp); + pp_equal (pp); + pp_cxx_whitespace (pp); + dump_expr (pp, TREE_PURPOSE (parmtypes), flags | TFF_EXPR_IN_PARENS); + } + } + + pp_cxx_right_paren (pp); +} + +/* Print ref-qualifier of a FUNCTION_TYPE or METHOD_TYPE. FLAGS are ignored. */ + +static void +dump_ref_qualifier (cxx_pretty_printer *pp, tree t, int flags ATTRIBUTE_UNUSED) +{ + if (FUNCTION_REF_QUALIFIED (t)) + { + pp->padding = pp_before; + if (FUNCTION_RVALUE_QUALIFIED (t)) + pp_cxx_ws_string (pp, "&&"); + else + pp_cxx_ws_string (pp, "&"); + } +} + +/* Print an exception specification. T is the exception specification. */ + +static void +dump_exception_spec (cxx_pretty_printer *pp, tree t, int flags) +{ + if (t && TREE_PURPOSE (t)) + { + pp_cxx_ws_string (pp, "noexcept"); + if (!integer_onep (TREE_PURPOSE (t))) + { + pp_cxx_whitespace (pp); + pp_cxx_left_paren (pp); + if (DEFERRED_NOEXCEPT_SPEC_P (t)) + pp_cxx_ws_string (pp, "<uninstantiated>"); + else + dump_expr (pp, TREE_PURPOSE (t), flags); + pp_cxx_right_paren (pp); + } + } + else if (t) + { + pp_cxx_ws_string (pp, "throw"); + pp_cxx_whitespace (pp); + pp_cxx_left_paren (pp); + if (TREE_VALUE (t) != NULL_TREE) + while (1) + { + dump_type (pp, TREE_VALUE (t), flags); + t = TREE_CHAIN (t); + if (!t) + break; + pp_separate_with_comma (pp); + } + pp_cxx_right_paren (pp); + } +} + +/* Handle the function name for a FUNCTION_DECL node, grokking operators + and destructors properly. */ + +static void +dump_function_name (cxx_pretty_printer *pp, tree t, int flags) +{ + tree name = DECL_NAME (t); + + /* We can get here with a decl that was synthesized by language- + independent machinery (e.g. coverage.c) in which case it won't + have a lang_specific structure attached and DECL_CONSTRUCTOR_P + will crash. In this case it is safe just to print out the + literal name. */ + if (!DECL_LANG_SPECIFIC (t)) + { + pp_cxx_tree_identifier (pp, name); + return; + } + + if (TREE_CODE (t) == TEMPLATE_DECL) + t = DECL_TEMPLATE_RESULT (t); + + /* Don't let the user see __comp_ctor et al. */ + if (DECL_CONSTRUCTOR_P (t) + || DECL_DESTRUCTOR_P (t)) + { + if (LAMBDA_TYPE_P (DECL_CONTEXT (t))) + name = get_identifier ("<lambda>"); + else if (TYPE_UNNAMED_P (DECL_CONTEXT (t))) + name = get_identifier ("<constructor>"); + else + name = constructor_name (DECL_CONTEXT (t)); + } + + if (DECL_DESTRUCTOR_P (t)) + { + pp_cxx_complement (pp); + dump_decl (pp, name, TFF_PLAIN_IDENTIFIER); + } + else if (DECL_CONV_FN_P (t)) + { + /* This cannot use the hack that the operator's return + type is stashed off of its name because it may be + used for error reporting. In the case of conflicting + declarations, both will have the same name, yet + the types will be different, hence the TREE_TYPE field + of the first name will be clobbered by the second. */ + pp_cxx_ws_string (pp, "operator"); + dump_type (pp, TREE_TYPE (TREE_TYPE (t)), flags); + } + else + dump_decl (pp, name, flags); + + dump_module_suffix (pp, t); + + if (DECL_TEMPLATE_INFO (t) + && !(flags & TFF_TEMPLATE_NAME) + && !DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION (t) + && (TREE_CODE (DECL_TI_TEMPLATE (t)) != TEMPLATE_DECL + || PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (t)))) + dump_template_parms (pp, DECL_TEMPLATE_INFO (t), !DECL_USE_TEMPLATE (t), + flags); +} + +/* Dump the template parameters from the template info INFO under control of + FLAGS. PRIMARY indicates whether this is a primary template decl, or + specialization (partial or complete). For partial specializations we show + the specialized parameter values. For a primary template we show no + decoration. */ + +static void +dump_template_parms (cxx_pretty_printer *pp, tree info, + int primary, int flags) +{ + tree args = info ? TI_ARGS (info) : NULL_TREE; + + if (primary && flags & TFF_TEMPLATE_NAME) + return; + flags &= ~(TFF_CLASS_KEY_OR_ENUM | TFF_TEMPLATE_NAME); + pp_cxx_begin_template_argument_list (pp); + + /* Be careful only to print things when we have them, so as not + to crash producing error messages. */ + if (args && !primary) + { + int len, ix; + len = get_non_default_template_args_count (args, flags); + + args = INNERMOST_TEMPLATE_ARGS (args); + for (ix = 0; ix != len; ix++) + { + tree arg = TREE_VEC_ELT (args, ix); + + /* Only print a comma if we know there is an argument coming. In + the case of an empty template argument pack, no actual + argument will be printed. */ + if (ix + && (!ARGUMENT_PACK_P (arg) + || TREE_VEC_LENGTH (ARGUMENT_PACK_ARGS (arg)) > 0)) + pp_separate_with_comma (pp); + + if (!arg) + pp_string (pp, M_("<template parameter error>")); + else + dump_template_argument (pp, arg, flags); + } + } + else if (primary) + { + tree tpl = TI_TEMPLATE (info); + tree parms = DECL_TEMPLATE_PARMS (tpl); + int len, ix; + + parms = TREE_CODE (parms) == TREE_LIST ? TREE_VALUE (parms) : NULL_TREE; + len = parms ? TREE_VEC_LENGTH (parms) : 0; + + for (ix = 0; ix != len; ix++) + { + tree parm; + + if (TREE_VEC_ELT (parms, ix) == error_mark_node) + { + pp_string (pp, M_("<template parameter error>")); + continue; + } + + parm = TREE_VALUE (TREE_VEC_ELT (parms, ix)); + + if (ix) + pp_separate_with_comma (pp); + + dump_decl (pp, parm, flags & ~TFF_DECL_SPECIFIERS); + } + } + pp_cxx_end_template_argument_list (pp); +} + +/* Print out the arguments of CALL_EXPR T as a parenthesized list using + flags FLAGS. Skip over the first argument if SKIPFIRST is true. */ + +static void +dump_call_expr_args (cxx_pretty_printer *pp, tree t, int flags, bool skipfirst) +{ + tree arg; + call_expr_arg_iterator iter; + + pp_cxx_left_paren (pp); + FOR_EACH_CALL_EXPR_ARG (arg, iter, t) + { + if (skipfirst) + skipfirst = false; + else + { + dump_expr (pp, arg, flags | TFF_EXPR_IN_PARENS); + if (more_call_expr_args_p (&iter)) + pp_separate_with_comma (pp); + } + } + pp_cxx_right_paren (pp); +} + +/* Print out the arguments of AGGR_INIT_EXPR T as a parenthesized list + using flags FLAGS. Skip over the first argument if SKIPFIRST is + true. */ + +static void +dump_aggr_init_expr_args (cxx_pretty_printer *pp, tree t, int flags, + bool skipfirst) +{ + tree arg; + aggr_init_expr_arg_iterator iter; + + pp_cxx_left_paren (pp); + FOR_EACH_AGGR_INIT_EXPR_ARG (arg, iter, t) + { + if (skipfirst) + skipfirst = false; + else + { + dump_expr (pp, arg, flags | TFF_EXPR_IN_PARENS); + if (more_aggr_init_expr_args_p (&iter)) + pp_separate_with_comma (pp); + } + } + pp_cxx_right_paren (pp); +} + +/* Print out a list of initializers (subr of dump_expr). */ + +static void +dump_expr_list (cxx_pretty_printer *pp, tree l, int flags) +{ + while (l) + { + dump_expr (pp, TREE_VALUE (l), flags | TFF_EXPR_IN_PARENS); + l = TREE_CHAIN (l); + if (l) + pp_separate_with_comma (pp); + } +} + +/* Print out a vector of initializers (subr of dump_expr). */ + +static void +dump_expr_init_vec (cxx_pretty_printer *pp, vec<constructor_elt, va_gc> *v, + int flags) +{ + unsigned HOST_WIDE_INT idx; + tree value; + + FOR_EACH_CONSTRUCTOR_VALUE (v, idx, value) + { + dump_expr (pp, value, flags | TFF_EXPR_IN_PARENS); + if (idx != v->length () - 1) + pp_separate_with_comma (pp); + } +} + + +/* We've gotten an indirect REFERENCE (an OBJ_TYPE_REF) to a virtual + function. Resolve it to a close relative -- in the sense of static + type -- variant being overridden. That is close to what was written in + the source code. Subroutine of dump_expr. */ + +static tree +resolve_virtual_fun_from_obj_type_ref (tree ref) +{ + tree obj_type = TREE_TYPE (OBJ_TYPE_REF_TOKEN (ref)); + HOST_WIDE_INT index = tree_to_uhwi (OBJ_TYPE_REF_TOKEN (ref)); + tree fun = BINFO_VIRTUALS (TYPE_BINFO (TREE_TYPE (obj_type))); + while (index) + { + fun = TREE_CHAIN (fun); + index -= (TARGET_VTABLE_USES_DESCRIPTORS + ? TARGET_VTABLE_USES_DESCRIPTORS : 1); + } + + return BV_FN (fun); +} + +/* Print out an expression E under control of FLAGS. */ + +static void +dump_expr (cxx_pretty_printer *pp, tree t, int flags) +{ + tree op; + + if (t == 0) + return; + + if (STATEMENT_CLASS_P (t)) + { + pp_cxx_ws_string (pp, M_("<statement>")); + return; + } + + switch (TREE_CODE (t)) + { + case VAR_DECL: + case PARM_DECL: + case FIELD_DECL: + case CONST_DECL: + case FUNCTION_DECL: + case TEMPLATE_DECL: + case NAMESPACE_DECL: + case LABEL_DECL: + case WILDCARD_DECL: + case OVERLOAD: + case TYPE_DECL: + case IDENTIFIER_NODE: + dump_decl (pp, t, ((flags & ~(TFF_DECL_SPECIFIERS|TFF_RETURN_TYPE + |TFF_TEMPLATE_HEADER)) + | TFF_NO_TEMPLATE_BINDINGS + | TFF_NO_FUNCTION_ARGUMENTS)); + break; + + case SSA_NAME: + if (SSA_NAME_VAR (t) + && !DECL_ARTIFICIAL (SSA_NAME_VAR (t))) + dump_expr (pp, SSA_NAME_VAR (t), flags); + else + pp_cxx_ws_string (pp, M_("<unknown>")); + break; + + case VOID_CST: + case INTEGER_CST: + case REAL_CST: + case STRING_CST: + case COMPLEX_CST: + pp->constant (t); + break; + + case USERDEF_LITERAL: + pp_cxx_userdef_literal (pp, t); + break; + + case THROW_EXPR: + /* While waiting for caret diagnostics, avoid printing + __cxa_allocate_exception, __cxa_throw, and the like. */ + pp_cxx_ws_string (pp, M_("<throw-expression>")); + break; + + case PTRMEM_CST: + pp_ampersand (pp); + dump_type (pp, PTRMEM_CST_CLASS (t), flags); + pp_cxx_colon_colon (pp); + pp_cxx_tree_identifier (pp, DECL_NAME (PTRMEM_CST_MEMBER (t))); + break; + + case COMPOUND_EXPR: + pp_cxx_left_paren (pp); + dump_expr (pp, TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS); + pp_separate_with_comma (pp); + dump_expr (pp, TREE_OPERAND (t, 1), flags | TFF_EXPR_IN_PARENS); + pp_cxx_right_paren (pp); + break; + + case COND_EXPR: + case VEC_COND_EXPR: + pp_cxx_left_paren (pp); + dump_expr (pp, TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS); + pp_string (pp, " ? "); + dump_expr (pp, TREE_OPERAND (t, 1), flags | TFF_EXPR_IN_PARENS); + pp_string (pp, " : "); + dump_expr (pp, TREE_OPERAND (t, 2), flags | TFF_EXPR_IN_PARENS); + pp_cxx_right_paren (pp); + break; + + case SAVE_EXPR: + if (TREE_HAS_CONSTRUCTOR (t)) + { + pp_cxx_ws_string (pp, "new"); + pp_cxx_whitespace (pp); + dump_type (pp, TREE_TYPE (TREE_TYPE (t)), flags); + } + else + dump_expr (pp, TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS); + break; + + case AGGR_INIT_EXPR: + { + tree fn = NULL_TREE; + + if (TREE_CODE (AGGR_INIT_EXPR_FN (t)) == ADDR_EXPR) + fn = TREE_OPERAND (AGGR_INIT_EXPR_FN (t), 0); + + if (fn && TREE_CODE (fn) == FUNCTION_DECL) + { + if (DECL_CONSTRUCTOR_P (fn)) + dump_type (pp, DECL_CONTEXT (fn), flags); + else + dump_decl (pp, fn, 0); + } + else + dump_expr (pp, AGGR_INIT_EXPR_FN (t), 0); + } + dump_aggr_init_expr_args (pp, t, flags, true); + break; + + case CALL_EXPR: + { + tree fn = CALL_EXPR_FN (t); + bool skipfirst = false; + + /* Deal with internal functions. */ + if (fn == NULL_TREE) + { + pp_string (pp, internal_fn_name (CALL_EXPR_IFN (t))); + dump_call_expr_args (pp, t, flags, skipfirst); + break; + } + + if (TREE_CODE (fn) == ADDR_EXPR) + fn = TREE_OPERAND (fn, 0); + + /* Nobody is interested in seeing the guts of vcalls. */ + if (TREE_CODE (fn) == OBJ_TYPE_REF) + fn = resolve_virtual_fun_from_obj_type_ref (fn); + + if (TREE_TYPE (fn) != NULL_TREE + && NEXT_CODE (fn) == METHOD_TYPE + && call_expr_nargs (t)) + { + tree ob = CALL_EXPR_ARG (t, 0); + if (TREE_CODE (ob) == ADDR_EXPR) + { + dump_expr (pp, TREE_OPERAND (ob, 0), + flags | TFF_EXPR_IN_PARENS); + pp_cxx_dot (pp); + } + else if (!is_this_parameter (ob)) + { + dump_expr (pp, ob, flags | TFF_EXPR_IN_PARENS); + pp_cxx_arrow (pp); + } + skipfirst = true; + } + if (flag_sanitize & SANITIZE_UNDEFINED + && is_ubsan_builtin_p (fn)) + { + pp_string (cxx_pp, M_("<ubsan routine call>")); + break; + } + dump_expr (pp, fn, flags | TFF_EXPR_IN_PARENS); + dump_call_expr_args (pp, t, flags, skipfirst); + } + break; + + case TARGET_EXPR: + /* Note that this only works for G++ target exprs. If somebody + builds a general TARGET_EXPR, there's no way to represent that + it initializes anything other that the parameter slot for the + default argument. Note we may have cleared out the first + operand in expand_expr, so don't go killing ourselves. */ + if (TREE_OPERAND (t, 1)) + dump_expr (pp, TREE_OPERAND (t, 1), flags | TFF_EXPR_IN_PARENS); + break; + + case POINTER_PLUS_EXPR: + dump_binary_op (pp, "+", t, flags); + break; + + case POINTER_DIFF_EXPR: + dump_binary_op (pp, "-", t, flags); + break; + + case INIT_EXPR: + case MODIFY_EXPR: + dump_binary_op (pp, OVL_OP_INFO (true, NOP_EXPR)->name, t, flags); + break; + + case PLUS_EXPR: + case MINUS_EXPR: + case MULT_EXPR: + case TRUNC_DIV_EXPR: + case TRUNC_MOD_EXPR: + case MIN_EXPR: + case MAX_EXPR: + case LSHIFT_EXPR: + case RSHIFT_EXPR: + case BIT_IOR_EXPR: + case BIT_XOR_EXPR: + case BIT_AND_EXPR: + case TRUTH_ANDIF_EXPR: + case TRUTH_ORIF_EXPR: + case LT_EXPR: + case LE_EXPR: + case GT_EXPR: + case GE_EXPR: + case EQ_EXPR: + case NE_EXPR: + case SPACESHIP_EXPR: + case EXACT_DIV_EXPR: + dump_binary_op (pp, OVL_OP_INFO (false, TREE_CODE (t))->name, t, flags); + break; + + case CEIL_DIV_EXPR: + case FLOOR_DIV_EXPR: + case ROUND_DIV_EXPR: + case RDIV_EXPR: + dump_binary_op (pp, "/", t, flags); + break; + + case CEIL_MOD_EXPR: + case FLOOR_MOD_EXPR: + case ROUND_MOD_EXPR: + dump_binary_op (pp, "%", t, flags); + break; + + case COMPONENT_REF: + { + tree ob = TREE_OPERAND (t, 0); + if (INDIRECT_REF_P (ob)) + { + ob = TREE_OPERAND (ob, 0); + if (!is_this_parameter (ob) + && !is_dummy_object (ob)) + { + dump_expr (pp, ob, flags | TFF_EXPR_IN_PARENS); + if (TYPE_REF_P (TREE_TYPE (ob))) + pp_cxx_dot (pp); + else + pp_cxx_arrow (pp); + } + } + else + { + dump_expr (pp, ob, flags | TFF_EXPR_IN_PARENS); + if (TREE_CODE (ob) != ARROW_EXPR) + pp_cxx_dot (pp); + } + dump_expr (pp, TREE_OPERAND (t, 1), flags & ~TFF_EXPR_IN_PARENS); + } + break; + + case ARRAY_REF: + dump_expr (pp, TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS); + pp_cxx_left_bracket (pp); + dump_expr (pp, TREE_OPERAND (t, 1), flags | TFF_EXPR_IN_PARENS); + pp_cxx_right_bracket (pp); + break; + + case UNARY_PLUS_EXPR: + dump_unary_op (pp, "+", t, flags); + break; + + case ADDR_EXPR: + if (TREE_CODE (TREE_OPERAND (t, 0)) == FUNCTION_DECL + || TREE_CODE (TREE_OPERAND (t, 0)) == STRING_CST + /* An ADDR_EXPR can have reference type. In that case, we + shouldn't print the `&' doing so indicates to the user + that the expression has pointer type. */ + || (TREE_TYPE (t) + && TYPE_REF_P (TREE_TYPE (t)))) + dump_expr (pp, TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS); + else if (TREE_CODE (TREE_OPERAND (t, 0)) == LABEL_DECL) + dump_unary_op (pp, "&&", t, flags); + else + dump_unary_op (pp, "&", t, flags); + break; + + case INDIRECT_REF: + if (TREE_HAS_CONSTRUCTOR (t)) + { + t = TREE_OPERAND (t, 0); + gcc_assert (TREE_CODE (t) == CALL_EXPR); + dump_expr (pp, CALL_EXPR_FN (t), flags | TFF_EXPR_IN_PARENS); + dump_call_expr_args (pp, t, flags, true); + } + else + { + if (TREE_OPERAND (t,0) != NULL_TREE + && TREE_TYPE (TREE_OPERAND (t, 0)) + && NEXT_CODE (TREE_OPERAND (t, 0)) == REFERENCE_TYPE) + dump_expr (pp, TREE_OPERAND (t, 0), flags); + else + dump_unary_op (pp, "*", t, flags); + } + break; + + case MEM_REF: + /* Delegate to the base "C" pretty printer. */ + pp->c_pretty_printer::unary_expression (t); + break; + + case TARGET_MEM_REF: + /* TARGET_MEM_REF can't appear directly from source, but can appear + during late GIMPLE optimizations and through late diagnostic we might + need to support it. Print it as dereferencing of a pointer after + cast to the TARGET_MEM_REF type, with pointer arithmetics on some + pointer to single byte types, so + *(type *)((char *) ptr + step * index + index2) if all the operands + are present and the casts are needed. */ + pp_cxx_star (pp); + pp_cxx_left_paren (pp); + if (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (TMR_BASE (t)))) == NULL_TREE + || !integer_onep (TYPE_SIZE_UNIT + (TREE_TYPE (TREE_TYPE (TMR_BASE (t)))))) + { + if (TYPE_SIZE_UNIT (TREE_TYPE (t)) + && integer_onep (TYPE_SIZE_UNIT (TREE_TYPE (t)))) + { + pp_cxx_left_paren (pp); + dump_type (pp, build_pointer_type (TREE_TYPE (t)), flags); + } + else + { + dump_type (pp, build_pointer_type (TREE_TYPE (t)), flags); + pp_cxx_right_paren (pp); + pp_cxx_left_paren (pp); + pp_cxx_left_paren (pp); + dump_type (pp, build_pointer_type (char_type_node), flags); + } + pp_cxx_right_paren (pp); + } + else if (!same_type_p (TREE_TYPE (t), + TREE_TYPE (TREE_TYPE (TMR_BASE (t))))) + { + dump_type (pp, build_pointer_type (TREE_TYPE (t)), flags); + pp_cxx_right_paren (pp); + pp_cxx_left_paren (pp); + } + dump_expr (pp, TMR_BASE (t), flags); + if (TMR_STEP (t) && TMR_INDEX (t)) + { + pp_cxx_ws_string (pp, "+"); + dump_expr (pp, TMR_INDEX (t), flags); + pp_cxx_ws_string (pp, "*"); + dump_expr (pp, TMR_STEP (t), flags); + } + if (TMR_INDEX2 (t)) + { + pp_cxx_ws_string (pp, "+"); + dump_expr (pp, TMR_INDEX2 (t), flags); + } + if (!integer_zerop (TMR_OFFSET (t))) + { + pp_cxx_ws_string (pp, "+"); + dump_expr (pp, fold_convert (ssizetype, TMR_OFFSET (t)), flags); + } + pp_cxx_right_paren (pp); + break; + + case NEGATE_EXPR: + case BIT_NOT_EXPR: + case TRUTH_NOT_EXPR: + case PREDECREMENT_EXPR: + case PREINCREMENT_EXPR: + dump_unary_op (pp, OVL_OP_INFO (false, TREE_CODE (t))->name, t, flags); + break; + + case POSTDECREMENT_EXPR: + case POSTINCREMENT_EXPR: + pp_cxx_left_paren (pp); + dump_expr (pp, TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS); + pp_cxx_ws_string (pp, OVL_OP_INFO (false, TREE_CODE (t))->name); + pp_cxx_right_paren (pp); + break; + + case NON_LVALUE_EXPR: + /* FIXME: This is a KLUDGE workaround for a parsing problem. There + should be another level of INDIRECT_REF so that I don't have to do + this. */ + if (TREE_TYPE (t) != NULL_TREE && NEXT_CODE (t) == POINTER_TYPE) + { + tree next = TREE_TYPE (TREE_TYPE (t)); + + while (TYPE_PTR_P (next)) + next = TREE_TYPE (next); + + if (TREE_CODE (next) == FUNCTION_TYPE) + { + if (flags & TFF_EXPR_IN_PARENS) + pp_cxx_left_paren (pp); + pp_cxx_star (pp); + dump_expr (pp, TREE_OPERAND (t, 0), flags & ~TFF_EXPR_IN_PARENS); + if (flags & TFF_EXPR_IN_PARENS) + pp_cxx_right_paren (pp); + break; + } + /* Else fall through. */ + } + dump_expr (pp, TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS); + break; + + CASE_CONVERT: + case IMPLICIT_CONV_EXPR: + case VIEW_CONVERT_EXPR: + { + tree op = TREE_OPERAND (t, 0); + tree ttype = TREE_TYPE (t); + tree optype = TREE_TYPE (op); + + if (TREE_CODE (ttype) != TREE_CODE (optype) + && INDIRECT_TYPE_P (ttype) + && INDIRECT_TYPE_P (optype) + && same_type_p (TREE_TYPE (optype), + TREE_TYPE (ttype))) + { + if (TYPE_REF_P (ttype)) + { + STRIP_NOPS (op); + if (TREE_CODE (op) == ADDR_EXPR) + dump_expr (pp, TREE_OPERAND (op, 0), flags); + else + dump_unary_op (pp, "*", t, flags); + } + else + dump_unary_op (pp, "&", t, flags); + } + else if (!same_type_p (TREE_TYPE (op), TREE_TYPE (t))) + { + /* It is a cast, but we cannot tell whether it is a + reinterpret or static cast. Use the C style notation. */ + if (flags & TFF_EXPR_IN_PARENS) + pp_cxx_left_paren (pp); + pp_cxx_left_paren (pp); + dump_type (pp, TREE_TYPE (t), flags); + pp_cxx_right_paren (pp); + dump_expr (pp, op, flags | TFF_EXPR_IN_PARENS); + if (flags & TFF_EXPR_IN_PARENS) + pp_cxx_right_paren (pp); + } + else + dump_expr (pp, op, flags); + break; + } + + case CONSTRUCTOR: + if (TREE_TYPE (t) && TYPE_PTRMEMFUNC_P (TREE_TYPE (t))) + { + tree idx = build_ptrmemfunc_access_expr (t, pfn_identifier); + + if (integer_zerop (idx)) + { + /* A NULL pointer-to-member constant. */ + pp_cxx_left_paren (pp); + pp_cxx_left_paren (pp); + dump_type (pp, TREE_TYPE (t), flags); + pp_cxx_right_paren (pp); + pp_character (pp, '0'); + pp_cxx_right_paren (pp); + break; + } + else if (tree_fits_shwi_p (idx)) + { + tree virtuals; + unsigned HOST_WIDE_INT n; + + t = TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (TREE_TYPE (t))); + t = TYPE_METHOD_BASETYPE (t); + virtuals = BINFO_VIRTUALS (TYPE_BINFO (TYPE_MAIN_VARIANT (t))); + + n = tree_to_shwi (idx); + + /* Map vtable index back one, to allow for the null pointer to + member. */ + --n; + + while (n > 0 && virtuals) + { + --n; + virtuals = TREE_CHAIN (virtuals); + } + if (virtuals) + { + dump_expr (pp, BV_FN (virtuals), + flags | TFF_EXPR_IN_PARENS); + break; + } + } + } + if (TREE_TYPE (t) && LAMBDA_TYPE_P (TREE_TYPE (t))) + pp_string (pp, "<lambda closure object>"); + if (TREE_TYPE (t) && EMPTY_CONSTRUCTOR_P (t)) + { + dump_type (pp, TREE_TYPE (t), 0); + pp_cxx_left_paren (pp); + pp_cxx_right_paren (pp); + } + else + { + if (!BRACE_ENCLOSED_INITIALIZER_P (t)) + dump_type (pp, TREE_TYPE (t), 0); + pp_cxx_left_brace (pp); + dump_expr_init_vec (pp, CONSTRUCTOR_ELTS (t), flags); + pp_cxx_right_brace (pp); + } + + break; + + case OFFSET_REF: + { + tree ob = TREE_OPERAND (t, 0); + if (is_dummy_object (ob)) + { + t = TREE_OPERAND (t, 1); + if (TREE_CODE (t) == FUNCTION_DECL) + /* A::f */ + dump_expr (pp, t, flags | TFF_EXPR_IN_PARENS); + else if (BASELINK_P (t)) + dump_expr (pp, OVL_FIRST (BASELINK_FUNCTIONS (t)), + flags | TFF_EXPR_IN_PARENS); + else + dump_decl (pp, t, flags); + } + else + { + if (INDIRECT_REF_P (ob)) + { + dump_expr (pp, TREE_OPERAND (ob, 0), flags | TFF_EXPR_IN_PARENS); + pp_cxx_arrow (pp); + pp_cxx_star (pp); + } + else + { + dump_expr (pp, ob, flags | TFF_EXPR_IN_PARENS); + pp_cxx_dot (pp); + pp_cxx_star (pp); + } + dump_expr (pp, TREE_OPERAND (t, 1), flags | TFF_EXPR_IN_PARENS); + } + break; + } + + case TEMPLATE_PARM_INDEX: + dump_decl (pp, TEMPLATE_PARM_DECL (t), flags & ~TFF_DECL_SPECIFIERS); + break; + + case CAST_EXPR: + if (TREE_OPERAND (t, 0) == NULL_TREE + || TREE_CHAIN (TREE_OPERAND (t, 0))) + { + dump_type (pp, TREE_TYPE (t), flags); + pp_cxx_left_paren (pp); + dump_expr_list (pp, TREE_OPERAND (t, 0), flags); + pp_cxx_right_paren (pp); + } + else + { + pp_cxx_left_paren (pp); + dump_type (pp, TREE_TYPE (t), flags); + pp_cxx_right_paren (pp); + pp_cxx_left_paren (pp); + dump_expr_list (pp, TREE_OPERAND (t, 0), flags); + pp_cxx_right_paren (pp); + } + break; + + case STATIC_CAST_EXPR: + pp_cxx_ws_string (pp, "static_cast"); + goto cast; + case REINTERPRET_CAST_EXPR: + pp_cxx_ws_string (pp, "reinterpret_cast"); + goto cast; + case CONST_CAST_EXPR: + pp_cxx_ws_string (pp, "const_cast"); + goto cast; + case DYNAMIC_CAST_EXPR: + pp_cxx_ws_string (pp, "dynamic_cast"); + cast: + pp_cxx_begin_template_argument_list (pp); + dump_type (pp, TREE_TYPE (t), flags); + pp_cxx_end_template_argument_list (pp); + pp_cxx_left_paren (pp); + dump_expr (pp, TREE_OPERAND (t, 0), flags); + pp_cxx_right_paren (pp); + break; + + case ARROW_EXPR: + dump_expr (pp, TREE_OPERAND (t, 0), flags); + pp_cxx_arrow (pp); + break; + + case SIZEOF_EXPR: + case ALIGNOF_EXPR: + if (TREE_CODE (t) == SIZEOF_EXPR) + pp_cxx_ws_string (pp, "sizeof"); + else + { + gcc_assert (TREE_CODE (t) == ALIGNOF_EXPR); + pp_cxx_ws_string (pp, "__alignof__"); + } + op = TREE_OPERAND (t, 0); + if (PACK_EXPANSION_P (op)) + { + pp_string (pp, "..."); + op = PACK_EXPANSION_PATTERN (op); + } + pp_cxx_whitespace (pp); + pp_cxx_left_paren (pp); + if (TREE_CODE (t) == SIZEOF_EXPR && SIZEOF_EXPR_TYPE_P (t)) + dump_type (pp, TREE_TYPE (op), flags); + else if (TYPE_P (TREE_OPERAND (t, 0))) + dump_type (pp, op, flags); + else + dump_expr (pp, op, flags); + pp_cxx_right_paren (pp); + break; + + case AT_ENCODE_EXPR: + pp_cxx_ws_string (pp, "@encode"); + pp_cxx_whitespace (pp); + pp_cxx_left_paren (pp); + dump_type (pp, TREE_OPERAND (t, 0), flags); + pp_cxx_right_paren (pp); + break; + + case NOEXCEPT_EXPR: + pp_cxx_ws_string (pp, "noexcept"); + pp_cxx_whitespace (pp); + pp_cxx_left_paren (pp); + dump_expr (pp, TREE_OPERAND (t, 0), flags); + pp_cxx_right_paren (pp); + break; + + case REALPART_EXPR: + case IMAGPART_EXPR: + pp_cxx_ws_string (pp, OVL_OP_INFO (false, TREE_CODE (t))->name); + pp_cxx_whitespace (pp); + dump_expr (pp, TREE_OPERAND (t, 0), flags); + break; + + case DEFERRED_PARSE: + pp_string (pp, M_("<unparsed>")); + break; + + case TRY_CATCH_EXPR: + case CLEANUP_POINT_EXPR: + dump_expr (pp, TREE_OPERAND (t, 0), flags); + break; + + case PSEUDO_DTOR_EXPR: + dump_expr (pp, TREE_OPERAND (t, 0), flags); + pp_cxx_dot (pp); + if (TREE_OPERAND (t, 1)) + { + dump_type (pp, TREE_OPERAND (t, 1), flags); + pp_cxx_colon_colon (pp); + } + pp_cxx_complement (pp); + dump_type (pp, TREE_OPERAND (t, 2), flags); + break; + + case TEMPLATE_ID_EXPR: + dump_decl (pp, t, flags); + break; + + case BIND_EXPR: + case STMT_EXPR: + case EXPR_STMT: + case STATEMENT_LIST: + /* We don't yet have a way of dumping statements in a + human-readable format. */ + pp_string (pp, "({...})"); + break; + + case LOOP_EXPR: + pp_string (pp, "while (1) { "); + dump_expr (pp, TREE_OPERAND (t, 0), flags & ~TFF_EXPR_IN_PARENS); + pp_cxx_right_brace (pp); + break; + + case EXIT_EXPR: + pp_string (pp, "if ("); + dump_expr (pp, TREE_OPERAND (t, 0), flags & ~TFF_EXPR_IN_PARENS); + pp_string (pp, ") break; "); + break; + + case BASELINK: + dump_expr (pp, BASELINK_FUNCTIONS (t), flags & ~TFF_EXPR_IN_PARENS); + break; + + case EMPTY_CLASS_EXPR: + dump_type (pp, TREE_TYPE (t), flags); + pp_cxx_left_paren (pp); + pp_cxx_right_paren (pp); + break; + + case NON_DEPENDENT_EXPR: + dump_expr (pp, TREE_OPERAND (t, 0), flags); + break; + + case ARGUMENT_PACK_SELECT: + dump_template_argument (pp, ARGUMENT_PACK_SELECT_FROM_PACK (t), flags); + break; + + case RECORD_TYPE: + case UNION_TYPE: + case ENUMERAL_TYPE: + case REAL_TYPE: + case VOID_TYPE: + case OPAQUE_TYPE: + case BOOLEAN_TYPE: + case INTEGER_TYPE: + case COMPLEX_TYPE: + case VECTOR_TYPE: + case DECLTYPE_TYPE: + pp_type_specifier_seq (pp, t); + break; + + case TYPENAME_TYPE: + /* We get here when we want to print a dependent type as an + id-expression, without any disambiguator decoration. */ + pp->id_expression (t); + break; + + case TEMPLATE_TYPE_PARM: + case TEMPLATE_TEMPLATE_PARM: + case BOUND_TEMPLATE_TEMPLATE_PARM: + dump_type (pp, t, flags); + break; + + case TRAIT_EXPR: + pp_cxx_trait_expression (pp, t); + break; + + case VA_ARG_EXPR: + pp_cxx_va_arg_expression (pp, t); + break; + + case OFFSETOF_EXPR: + pp_cxx_offsetof_expression (pp, t); + break; + + case ADDRESSOF_EXPR: + pp_cxx_addressof_expression (pp, t); + break; + + case SCOPE_REF: + dump_decl (pp, t, flags); + break; + + case EXPR_PACK_EXPANSION: + case UNARY_LEFT_FOLD_EXPR: + case UNARY_RIGHT_FOLD_EXPR: + case BINARY_LEFT_FOLD_EXPR: + case BINARY_RIGHT_FOLD_EXPR: + case TYPEID_EXPR: + case MEMBER_REF: + case DOTSTAR_EXPR: + case NEW_EXPR: + case VEC_NEW_EXPR: + case DELETE_EXPR: + case VEC_DELETE_EXPR: + case MODOP_EXPR: + case ABS_EXPR: + case ABSU_EXPR: + case CONJ_EXPR: + case VECTOR_CST: + case FIXED_CST: + case UNORDERED_EXPR: + case ORDERED_EXPR: + case UNLT_EXPR: + case UNLE_EXPR: + case UNGT_EXPR: + case UNGE_EXPR: + case UNEQ_EXPR: + case LTGT_EXPR: + case COMPLEX_EXPR: + case BIT_FIELD_REF: + case FIX_TRUNC_EXPR: + case FLOAT_EXPR: + pp->expression (t); + break; + + case TRUTH_AND_EXPR: + case TRUTH_OR_EXPR: + case TRUTH_XOR_EXPR: + if (flags & TFF_EXPR_IN_PARENS) + pp_cxx_left_paren (pp); + pp->expression (t); + if (flags & TFF_EXPR_IN_PARENS) + pp_cxx_right_paren (pp); + break; + + case OBJ_TYPE_REF: + dump_expr (pp, resolve_virtual_fun_from_obj_type_ref (t), flags); + break; + + case LAMBDA_EXPR: + pp_string (pp, M_("<lambda>")); + break; + + case PAREN_EXPR: + pp_cxx_left_paren (pp); + dump_expr (pp, TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS); + pp_cxx_right_paren (pp); + break; + + case REQUIRES_EXPR: + pp_cxx_requires_expr (cxx_pp, t); + break; + + case SIMPLE_REQ: + pp_cxx_simple_requirement (cxx_pp, t); + break; + + case TYPE_REQ: + pp_cxx_type_requirement (cxx_pp, t); + break; + + case COMPOUND_REQ: + pp_cxx_compound_requirement (cxx_pp, t); + break; + + case NESTED_REQ: + pp_cxx_nested_requirement (cxx_pp, t); + break; + + case ATOMIC_CONSTR: + case CHECK_CONSTR: + case CONJ_CONSTR: + case DISJ_CONSTR: + { + pp_cxx_constraint (cxx_pp, t); + break; + } + + case PLACEHOLDER_EXPR: + pp_string (pp, M_("*this")); + break; + + case TREE_LIST: + dump_expr_list (pp, t, flags); + break; + + /* This list is incomplete, but should suffice for now. + It is very important that `sorry' does not call + `report_error_function'. That could cause an infinite loop. */ + default: + pp_unsupported_tree (pp, t); + /* Fall through. */ + case ERROR_MARK: + pp_string (pp, M_("<expression error>")); + break; + } +} + +static void +dump_binary_op (cxx_pretty_printer *pp, const char *opstring, tree t, + int flags) +{ + pp_cxx_left_paren (pp); + dump_expr (pp, TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS); + pp_cxx_whitespace (pp); + if (opstring) + pp_cxx_ws_string (pp, opstring); + else + pp_string (pp, M_("<unknown operator>")); + pp_cxx_whitespace (pp); + tree op1 = TREE_OPERAND (t, 1); + if (TREE_CODE (t) == POINTER_PLUS_EXPR + && TREE_CODE (op1) == INTEGER_CST + && tree_int_cst_sign_bit (op1)) + /* A pointer minus an integer is represented internally as plus a very + large number, don't expose that to users. */ + op1 = convert (ssizetype, op1); + dump_expr (pp, op1, flags | TFF_EXPR_IN_PARENS); + pp_cxx_right_paren (pp); +} + +static void +dump_unary_op (cxx_pretty_printer *pp, const char *opstring, tree t, int flags) +{ + if (flags & TFF_EXPR_IN_PARENS) + pp_cxx_left_paren (pp); + pp_cxx_ws_string (pp, opstring); + dump_expr (pp, TREE_OPERAND (t, 0), flags & ~TFF_EXPR_IN_PARENS); + if (flags & TFF_EXPR_IN_PARENS) + pp_cxx_right_paren (pp); +} + +static void +reinit_cxx_pp (void) +{ + pp_clear_output_area (cxx_pp); + cxx_pp->padding = pp_none; + pp_indentation (cxx_pp) = 0; + pp_needs_newline (cxx_pp) = false; + cxx_pp->enclosing_scope = current_function_decl; +} + +/* Same as pp_formatted_text, except the return string is a separate + copy and has a GGC storage duration, e.g. an indefinite lifetime. */ + +inline const char * +pp_ggc_formatted_text (pretty_printer *pp) +{ + return ggc_strdup (pp_formatted_text (pp)); +} + +/* Exported interface to stringifying types, exprs and decls under TFF_* + control. */ + +const char * +type_as_string (tree typ, int flags) +{ + reinit_cxx_pp (); + pp_translate_identifiers (cxx_pp) = false; + dump_type (cxx_pp, typ, flags); + return pp_ggc_formatted_text (cxx_pp); +} + +const char * +type_as_string_translate (tree typ, int flags) +{ + reinit_cxx_pp (); + dump_type (cxx_pp, typ, flags); + return pp_ggc_formatted_text (cxx_pp); +} + +const char * +expr_as_string (tree decl, int flags) +{ + reinit_cxx_pp (); + pp_translate_identifiers (cxx_pp) = false; + dump_expr (cxx_pp, decl, flags); + return pp_ggc_formatted_text (cxx_pp); +} + +/* Wrap decl_as_string with options appropriate for dwarf. */ + +const char * +decl_as_dwarf_string (tree decl, int flags) +{ + const char *name; + /* Curiously, reinit_cxx_pp doesn't reset the flags field, so setting the flag + here will be adequate to get the desired behavior. */ + cxx_pp->flags |= pp_c_flag_gnu_v3; + name = decl_as_string (decl, flags); + /* Subsequent calls to the pretty printer shouldn't use this style. */ + cxx_pp->flags &= ~pp_c_flag_gnu_v3; + return name; +} + +const char * +decl_as_string (tree decl, int flags) +{ + reinit_cxx_pp (); + pp_translate_identifiers (cxx_pp) = false; + dump_decl (cxx_pp, decl, flags); + return pp_ggc_formatted_text (cxx_pp); +} + +const char * +decl_as_string_translate (tree decl, int flags) +{ + reinit_cxx_pp (); + dump_decl (cxx_pp, decl, flags); + return pp_ggc_formatted_text (cxx_pp); +} + +/* Wrap lang_decl_name with options appropriate for dwarf. */ + +const char * +lang_decl_dwarf_name (tree decl, int v, bool translate) +{ + const char *name; + /* Curiously, reinit_cxx_pp doesn't reset the flags field, so setting the flag + here will be adequate to get the desired behavior. */ + cxx_pp->flags |= pp_c_flag_gnu_v3; + name = lang_decl_name (decl, v, translate); + /* Subsequent calls to the pretty printer shouldn't use this style. */ + cxx_pp->flags &= ~pp_c_flag_gnu_v3; + return name; +} + +/* Generate the three forms of printable names for cxx_printable_name. */ + +const char * +lang_decl_name (tree decl, int v, bool translate) +{ + if (v >= 2) + return (translate + ? decl_as_string_translate (decl, TFF_DECL_SPECIFIERS) + : decl_as_string (decl, TFF_DECL_SPECIFIERS)); + + reinit_cxx_pp (); + pp_translate_identifiers (cxx_pp) = translate; + if (v == 1 + && (DECL_CLASS_SCOPE_P (decl) + || (DECL_NAMESPACE_SCOPE_P (decl) + && CP_DECL_CONTEXT (decl) != global_namespace))) + { + dump_type (cxx_pp, CP_DECL_CONTEXT (decl), TFF_PLAIN_IDENTIFIER); + pp_cxx_colon_colon (cxx_pp); + } + + if (TREE_CODE (decl) == FUNCTION_DECL) + dump_function_name (cxx_pp, decl, TFF_PLAIN_IDENTIFIER); + else if ((DECL_NAME (decl) == NULL_TREE) + && TREE_CODE (decl) == NAMESPACE_DECL) + dump_decl (cxx_pp, decl, TFF_PLAIN_IDENTIFIER | TFF_UNQUALIFIED_NAME); + else + dump_decl (cxx_pp, DECL_NAME (decl), TFF_PLAIN_IDENTIFIER); + + return pp_ggc_formatted_text (cxx_pp); +} + +/* Return the location of a tree passed to %+ formats. */ + +location_t +location_of (tree t) +{ + if (TYPE_P (t)) + { + t = TYPE_MAIN_DECL (t); + if (t == NULL_TREE) + return input_location; + } + else if (TREE_CODE (t) == OVERLOAD) + t = OVL_FIRST (t); + + if (DECL_P (t)) + return DECL_SOURCE_LOCATION (t); + if (TREE_CODE (t) == DEFERRED_PARSE) + return defparse_location (t); + return cp_expr_loc_or_input_loc (t); +} + +/* Now the interfaces from error et al to dump_type et al. Each takes an + on/off VERBOSE flag and supply the appropriate TFF_ flags to a dump_ + function. */ + +static const char * +decl_to_string (tree decl, int verbose) +{ + int flags = 0; + + if (TREE_CODE (decl) == TYPE_DECL || TREE_CODE (decl) == RECORD_TYPE + || TREE_CODE (decl) == UNION_TYPE || TREE_CODE (decl) == ENUMERAL_TYPE) + flags = TFF_CLASS_KEY_OR_ENUM; + if (verbose) + flags |= TFF_DECL_SPECIFIERS; + else if (TREE_CODE (decl) == FUNCTION_DECL) + flags |= TFF_DECL_SPECIFIERS | TFF_RETURN_TYPE; + flags |= TFF_TEMPLATE_HEADER; + + reinit_cxx_pp (); + dump_decl (cxx_pp, decl, flags); + return pp_ggc_formatted_text (cxx_pp); +} + +const char * +expr_to_string (tree decl) +{ + reinit_cxx_pp (); + dump_expr (cxx_pp, decl, 0); + return pp_ggc_formatted_text (cxx_pp); +} + +static const char * +fndecl_to_string (tree fndecl, int verbose) +{ + int flags; + + flags = TFF_EXCEPTION_SPECIFICATION | TFF_DECL_SPECIFIERS + | TFF_TEMPLATE_HEADER; + if (verbose) + flags |= TFF_FUNCTION_DEFAULT_ARGUMENTS; + reinit_cxx_pp (); + dump_decl (cxx_pp, fndecl, flags); + return pp_ggc_formatted_text (cxx_pp); +} + + +static const char * +code_to_string (enum tree_code c) +{ + return get_tree_code_name (c); +} + +const char * +language_to_string (enum languages c) +{ + switch (c) + { + case lang_c: + return "C"; + + case lang_cplusplus: + return "C++"; + + default: + gcc_unreachable (); + } + return NULL; +} + +/* Return the proper printed version of a parameter to a C++ function. */ + +static const char * +parm_to_string (int p) +{ + reinit_cxx_pp (); + if (p < 0) + pp_string (cxx_pp, "'this'"); + else + pp_decimal_int (cxx_pp, p + 1); + return pp_ggc_formatted_text (cxx_pp); +} + +static const char * +op_to_string (bool assop, enum tree_code p) +{ + tree id = ovl_op_identifier (assop, p); + return id ? IDENTIFIER_POINTER (id) : M_("<unknown>"); +} + +/* Return a GC-allocated representation of type TYP, with verbosity VERBOSE. + + If QUOTE is non-NULL and if *QUOTE is true, then quotes are added to the + string in appropriate places, and *QUOTE is written to with false + to suppress pp_format's trailing close quote so that e.g. + foo_typedef {aka underlying_foo} {enum} + can be printed by "%qT" as: + `foo_typedef' {aka `underlying_foo'} {enum} + rather than: + `foo_typedef {aka underlying_foo} {enum}' + When adding such quotes, if POSTPROCESSED is true (for handling %H and %I) + then a leading open quote will be added, whereas if POSTPROCESSED is false + (for handling %T) then any leading quote has already been added by + pp_format, or is not needed due to QUOTE being NULL (for template arguments + within %H and %I). + + SHOW_COLOR is used to determine the colorization of any quotes that + are added. */ + +static const char * +type_to_string (tree typ, int verbose, bool postprocessed, bool *quote, + bool show_color) +{ + int flags = 0; + if (verbose) + flags |= TFF_CLASS_KEY_OR_ENUM; + flags |= TFF_TEMPLATE_HEADER; + + reinit_cxx_pp (); + + if (postprocessed && quote && *quote) + pp_begin_quote (cxx_pp, show_color); + + struct obstack *ob = pp_buffer (cxx_pp)->obstack; + int type_start, type_len; + type_start = obstack_object_size (ob); + + dump_type (cxx_pp, typ, flags); + + /* Remember the end of the initial dump. */ + type_len = obstack_object_size (ob) - type_start; + + /* If we're printing a type that involves typedefs, also print the + stripped version. But sometimes the stripped version looks + exactly the same, so we don't want it after all. To avoid printing + it in that case, we play ugly obstack games. */ + if (typ && TYPE_P (typ) && typ != TYPE_CANONICAL (typ) + && !uses_template_parms (typ)) + { + int aka_start, aka_len; char *p; + tree aka = strip_typedefs (typ, NULL, STF_USER_VISIBLE); + if (quote && *quote) + pp_end_quote (cxx_pp, show_color); + pp_string (cxx_pp, " {aka"); + pp_cxx_whitespace (cxx_pp); + if (quote && *quote) + pp_begin_quote (cxx_pp, show_color); + /* And remember the start of the aka dump. */ + aka_start = obstack_object_size (ob); + dump_type (cxx_pp, aka, flags); + aka_len = obstack_object_size (ob) - aka_start; + if (quote && *quote) + pp_end_quote (cxx_pp, show_color); + pp_right_brace (cxx_pp); + p = (char*)obstack_base (ob); + /* If they are identical, cut off the aka by unwinding the obstack. */ + if (type_len == aka_len + && memcmp (p + type_start, p+aka_start, type_len) == 0) + { + /* We can't add a '\0' here, since we may be adding a closing quote + below, and it would be hidden by the '\0'. + Instead, manually unwind the current object within the obstack + so that the insertion point is at the end of the type, before + the "' {aka". */ + int delta = type_start + type_len - obstack_object_size (ob); + gcc_assert (delta <= 0); + obstack_blank_fast (ob, delta); + } + else + if (quote) + /* No further closing quotes are needed. */ + *quote = false; + } + + if (quote && *quote) + { + pp_end_quote (cxx_pp, show_color); + *quote = false; + } + return pp_ggc_formatted_text (cxx_pp); +} + +static const char * +args_to_string (tree p, int verbose) +{ + int flags = 0; + if (verbose) + flags |= TFF_CLASS_KEY_OR_ENUM; + + if (p == NULL_TREE) + return ""; + + if (TYPE_P (TREE_VALUE (p))) + return type_as_string_translate (p, flags); + + reinit_cxx_pp (); + for (; p; p = TREE_CHAIN (p)) + { + if (null_node_p (TREE_VALUE (p))) + pp_cxx_ws_string (cxx_pp, "NULL"); + else + dump_type (cxx_pp, error_type (TREE_VALUE (p)), flags); + if (TREE_CHAIN (p)) + pp_separate_with_comma (cxx_pp); + } + return pp_ggc_formatted_text (cxx_pp); +} + +/* Pretty-print a deduction substitution (from deduction_tsubst_fntype). P + is a TREE_LIST with purpose the TEMPLATE_DECL, value the template + arguments. */ + +static const char * +subst_to_string (tree p) +{ + tree decl = TREE_PURPOSE (p); + tree targs = TREE_VALUE (p); + tree tparms = DECL_TEMPLATE_PARMS (decl); + int flags = (TFF_DECL_SPECIFIERS|TFF_TEMPLATE_HEADER + |TFF_NO_TEMPLATE_BINDINGS); + + if (p == NULL_TREE) + return ""; + + reinit_cxx_pp (); + dump_template_decl (cxx_pp, TREE_PURPOSE (p), flags); + dump_substitution (cxx_pp, NULL, tparms, targs, /*flags=*/0); + return pp_ggc_formatted_text (cxx_pp); +} + +static const char * +cv_to_string (tree p, int v) +{ + reinit_cxx_pp (); + cxx_pp->padding = v ? pp_before : pp_none; + pp_cxx_cv_qualifier_seq (cxx_pp, p); + return pp_ggc_formatted_text (cxx_pp); +} + +static const char * +eh_spec_to_string (tree p, int /*v*/) +{ + int flags = 0; + reinit_cxx_pp (); + dump_exception_spec (cxx_pp, p, flags); + return pp_ggc_formatted_text (cxx_pp); +} + +/* Langhook for print_error_function. */ +void +cxx_print_error_function (diagnostic_context *context, const char *file, + diagnostic_info *diagnostic) +{ + char *prefix; + if (file) + prefix = xstrdup (file); + else + prefix = NULL; + lhd_print_error_function (context, file, diagnostic); + pp_set_prefix (context->printer, prefix); + maybe_print_instantiation_context (context); +} + +static void +cp_diagnostic_starter (diagnostic_context *context, + diagnostic_info *diagnostic) +{ + diagnostic_report_current_module (context, diagnostic_location (diagnostic)); + cp_print_error_function (context, diagnostic); + maybe_print_instantiation_context (context); + maybe_print_constexpr_context (context); + maybe_print_constraint_context (context); + pp_set_prefix (context->printer, diagnostic_build_prefix (context, + diagnostic)); +} + +/* Print current function onto BUFFER, in the process of reporting + a diagnostic message. Called from cp_diagnostic_starter. */ +static void +cp_print_error_function (diagnostic_context *context, + diagnostic_info *diagnostic) +{ + /* If we are in an instantiation context, current_function_decl is likely + to be wrong, so just rely on print_instantiation_full_context. */ + if (current_instantiation ()) + return; + /* The above is true for constraint satisfaction also. */ + if (current_failed_constraint) + return; + if (diagnostic_last_function_changed (context, diagnostic)) + { + char *old_prefix = pp_take_prefix (context->printer); + const char *file = LOCATION_FILE (diagnostic_location (diagnostic)); + tree abstract_origin = diagnostic_abstract_origin (diagnostic); + char *new_prefix = (file && abstract_origin == NULL) + ? file_name_as_prefix (context, file) : NULL; + + pp_set_prefix (context->printer, new_prefix); + + if (current_function_decl == NULL) + pp_string (context->printer, _("At global scope:")); + else + { + tree fndecl, ao; + + if (abstract_origin) + { + ao = BLOCK_ABSTRACT_ORIGIN (abstract_origin); + gcc_assert (TREE_CODE (ao) == FUNCTION_DECL); + fndecl = ao; + } + else + fndecl = current_function_decl; + + pp_printf (context->printer, function_category (fndecl), + cxx_printable_name_translate (fndecl, 2)); + + while (abstract_origin) + { + location_t *locus; + tree block = abstract_origin; + + locus = &BLOCK_SOURCE_LOCATION (block); + fndecl = NULL; + block = BLOCK_SUPERCONTEXT (block); + while (block && TREE_CODE (block) == BLOCK + && BLOCK_ABSTRACT_ORIGIN (block)) + { + ao = BLOCK_ABSTRACT_ORIGIN (block); + if (TREE_CODE (ao) == FUNCTION_DECL) + { + fndecl = ao; + break; + } + else if (TREE_CODE (ao) != BLOCK) + break; + + block = BLOCK_SUPERCONTEXT (block); + } + if (fndecl) + abstract_origin = block; + else + { + while (block && TREE_CODE (block) == BLOCK) + block = BLOCK_SUPERCONTEXT (block); + + if (block && TREE_CODE (block) == FUNCTION_DECL) + fndecl = block; + abstract_origin = NULL; + } + if (fndecl) + { + expanded_location s = expand_location (*locus); + pp_character (context->printer, ','); + pp_newline (context->printer); + if (s.file != NULL) + { + if (context->show_column && s.column != 0) + pp_printf (context->printer, + _(" inlined from %qs at %r%s:%d:%d%R"), + cxx_printable_name_translate (fndecl, 2), + "locus", s.file, s.line, s.column); + else + pp_printf (context->printer, + _(" inlined from %qs at %r%s:%d%R"), + cxx_printable_name_translate (fndecl, 2), + "locus", s.file, s.line); + + } + else + pp_printf (context->printer, _(" inlined from %qs"), + cxx_printable_name_translate (fndecl, 2)); + } + } + pp_character (context->printer, ':'); + } + pp_newline (context->printer); + + diagnostic_set_last_function (context, diagnostic); + pp_destroy_prefix (context->printer); + context->printer->prefix = old_prefix; + } +} + +/* Returns a description of FUNCTION using standard terminology. The + result is a format string of the form "In CATEGORY %qs". */ +static const char * +function_category (tree fn) +{ + /* We can get called from the middle-end for diagnostics of function + clones. Make sure we have language specific information before + dereferencing it. */ + if (DECL_LANG_SPECIFIC (STRIP_TEMPLATE (fn)) + && DECL_FUNCTION_MEMBER_P (fn)) + { + if (DECL_STATIC_FUNCTION_P (fn)) + return _("In static member function %qs"); + else if (DECL_COPY_CONSTRUCTOR_P (fn)) + return _("In copy constructor %qs"); + else if (DECL_CONSTRUCTOR_P (fn)) + return _("In constructor %qs"); + else if (DECL_DESTRUCTOR_P (fn)) + return _("In destructor %qs"); + else if (LAMBDA_FUNCTION_P (fn)) + return _("In lambda function"); + else + return _("In member function %qs"); + } + else + return _("In function %qs"); +} + +/* Disable warnings about missing quoting in GCC diagnostics for + the pp_verbatim calls. Their format strings deliberately don't + follow GCC diagnostic conventions. */ +#if __GNUC__ >= 10 +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wformat-diag" +#endif + +/* Report the full context of a current template instantiation, + onto BUFFER. */ +static void +print_instantiation_full_context (diagnostic_context *context) +{ + struct tinst_level *p = current_instantiation (); + location_t location = input_location; + + if (p) + { + pp_verbatim (context->printer, + p->list_p () + ? _("%s: In substitution of %qS:\n") + : _("%s: In instantiation of %q#D:\n"), + LOCATION_FILE (location), + p->get_node ()); + + location = p->locus; + p = p->next; + } + + print_instantiation_partial_context (context, p, location); +} + +/* Helper function of print_instantiation_partial_context() that + prints a single line of instantiation context. */ + +static void +print_instantiation_partial_context_line (diagnostic_context *context, + struct tinst_level *t, + location_t loc, bool recursive_p) +{ + if (loc == UNKNOWN_LOCATION) + return; + + expanded_location xloc = expand_location (loc); + + if (context->show_column) + pp_verbatim (context->printer, _("%r%s:%d:%d:%R "), + "locus", xloc.file, xloc.line, xloc.column); + else + pp_verbatim (context->printer, _("%r%s:%d:%R "), + "locus", xloc.file, xloc.line); + + if (t != NULL) + { + if (t->list_p ()) + pp_verbatim (context->printer, + recursive_p + ? _("recursively required by substitution of %qS\n") + : _("required by substitution of %qS\n"), + t->get_node ()); + else + pp_verbatim (context->printer, + recursive_p + ? _("recursively required from %q#D\n") + : _("required from %q#D\n"), + t->get_node ()); + } + else + { + pp_verbatim (context->printer, + recursive_p + ? _("recursively required from here\n") + : _("required from here\n")); + } +} + +/* Same as print_instantiation_full_context but less verbose. */ + +static void +print_instantiation_partial_context (diagnostic_context *context, + struct tinst_level *t0, location_t loc) +{ + struct tinst_level *t; + int n_total = 0; + int n; + location_t prev_loc = loc; + + for (t = t0; t != NULL; t = t->next) + if (prev_loc != t->locus) + { + prev_loc = t->locus; + n_total++; + } + + t = t0; + + if (template_backtrace_limit + && n_total > template_backtrace_limit) + { + int skip = n_total - template_backtrace_limit; + int head = template_backtrace_limit / 2; + + /* Avoid skipping just 1. If so, skip 2. */ + if (skip == 1) + { + skip = 2; + head = (template_backtrace_limit - 1) / 2; + } + + for (n = 0; n < head; n++) + { + gcc_assert (t != NULL); + if (loc != t->locus) + print_instantiation_partial_context_line (context, t, loc, + /*recursive_p=*/false); + loc = t->locus; + t = t->next; + } + if (t != NULL && skip > 0) + { + expanded_location xloc; + xloc = expand_location (loc); + if (context->show_column) + pp_verbatim (context->printer, + _("%r%s:%d:%d:%R [ skipping %d instantiation " + "contexts, use -ftemplate-backtrace-limit=0 to " + "disable ]\n"), + "locus", xloc.file, xloc.line, xloc.column, skip); + else + pp_verbatim (context->printer, + _("%r%s:%d:%R [ skipping %d instantiation " + "contexts, use -ftemplate-backtrace-limit=0 to " + "disable ]\n"), + "locus", xloc.file, xloc.line, skip); + + do { + loc = t->locus; + t = t->next; + } while (t != NULL && --skip > 0); + } + } + + while (t != NULL) + { + while (t->next != NULL && t->locus == t->next->locus) + { + loc = t->locus; + t = t->next; + } + print_instantiation_partial_context_line (context, t, loc, + t->locus == loc); + loc = t->locus; + t = t->next; + } + print_instantiation_partial_context_line (context, NULL, loc, + /*recursive_p=*/false); +} + +/* Called from cp_thing to print the template context for an error. */ +static void +maybe_print_instantiation_context (diagnostic_context *context) +{ + if (!problematic_instantiation_changed () || current_instantiation () == 0) + return; + + record_last_problematic_instantiation (); + print_instantiation_full_context (context); +} + +/* Report what constexpr call(s) we're trying to expand, if any. */ + +void +maybe_print_constexpr_context (diagnostic_context *context) +{ + vec<tree> call_stack = cx_error_context (); + unsigned ix; + tree t; + + FOR_EACH_VEC_ELT (call_stack, ix, t) + { + expanded_location xloc = expand_location (EXPR_LOCATION (t)); + const char *s = expr_as_string (t, 0); + if (context->show_column) + pp_verbatim (context->printer, + _("%r%s:%d:%d:%R in %<constexpr%> expansion of %qs"), + "locus", xloc.file, xloc.line, xloc.column, s); + else + pp_verbatim (context->printer, + _("%r%s:%d:%R in %<constexpr%> expansion of %qs"), + "locus", xloc.file, xloc.line, s); + pp_newline (context->printer); + } +} + + +static void +print_location (diagnostic_context *context, location_t loc) +{ + expanded_location xloc = expand_location (loc); + if (context->show_column) + pp_verbatim (context->printer, _("%r%s:%d:%d:%R "), + "locus", xloc.file, xloc.line, xloc.column); + else + pp_verbatim (context->printer, _("%r%s:%d:%R "), + "locus", xloc.file, xloc.line); +} + +static void +print_constrained_decl_info (diagnostic_context *context, tree decl) +{ + print_location (context, DECL_SOURCE_LOCATION (decl)); + pp_verbatim (context->printer, "required by the constraints of %q#D\n", decl); +} + +static void +print_concept_check_info (diagnostic_context *context, tree expr, tree map, tree args) +{ + gcc_assert (concept_check_p (expr)); + + tree id = unpack_concept_check (expr); + tree tmpl = TREE_OPERAND (id, 0); + if (OVL_P (tmpl)) + tmpl = OVL_FIRST (tmpl); + + print_location (context, DECL_SOURCE_LOCATION (tmpl)); + + cxx_pretty_printer *pp = (cxx_pretty_printer *)context->printer; + pp_verbatim (pp, "required for the satisfaction of %qE", expr); + if (map && map != error_mark_node) + { + tree subst_map = tsubst_parameter_mapping (map, args, tf_none, NULL_TREE); + pp_cxx_parameter_mapping (pp, (subst_map != error_mark_node + ? subst_map : map)); + } + pp_newline (pp); +} + +/* Diagnose the entry point into the satisfaction error. Returns the next + context, if any. */ + +static tree +print_constraint_context_head (diagnostic_context *context, tree cxt, tree args) +{ + tree src = TREE_VALUE (cxt); + if (!src) + { + print_location (context, input_location); + pp_verbatim (context->printer, "required for constraint satisfaction\n"); + return NULL_TREE; + } + if (DECL_P (src)) + { + print_constrained_decl_info (context, src); + return NULL_TREE; + } + else + { + print_concept_check_info (context, src, TREE_PURPOSE (cxt), args); + return TREE_CHAIN (cxt); + } +} + +static void +print_requires_expression_info (diagnostic_context *context, tree constr, tree args) +{ + + tree expr = ATOMIC_CONSTR_EXPR (constr); + tree map = ATOMIC_CONSTR_MAP (constr); + map = tsubst_parameter_mapping (map, args, tf_none, NULL_TREE); + if (map == error_mark_node) + return; + + print_location (context, cp_expr_loc_or_input_loc (expr)); + pp_verbatim (context->printer, "in requirements "); + + tree parms = TREE_OPERAND (expr, 0); + if (parms) + pp_verbatim (context->printer, "with "); + while (parms) + { + pp_verbatim (context->printer, "%q#D", parms); + if (TREE_CHAIN (parms)) + pp_separate_with_comma ((cxx_pretty_printer *)context->printer); + parms = TREE_CHAIN (parms); + } + pp_cxx_parameter_mapping ((cxx_pretty_printer *)context->printer, map); + + pp_verbatim (context->printer, "\n"); +} + +void +maybe_print_single_constraint_context (diagnostic_context *context, tree failed) +{ + if (!failed) + return; + + tree constr = TREE_VALUE (failed); + if (!constr || constr == error_mark_node) + return; + tree cxt = CONSTR_CONTEXT (constr); + if (!cxt) + return; + tree args = TREE_PURPOSE (failed); + + /* Print the stack of requirements. */ + cxt = print_constraint_context_head (context, cxt, args); + while (cxt && !DECL_P (TREE_VALUE (cxt))) + { + tree expr = TREE_VALUE (cxt); + tree map = TREE_PURPOSE (cxt); + print_concept_check_info (context, expr, map, args); + cxt = TREE_CHAIN (cxt); + } + + /* For certain constraints, we can provide additional context. */ + if (TREE_CODE (constr) == ATOMIC_CONSTR + && TREE_CODE (ATOMIC_CONSTR_EXPR (constr)) == REQUIRES_EXPR) + print_requires_expression_info (context, constr, args); +} + +void +maybe_print_constraint_context (diagnostic_context *context) +{ + if (!current_failed_constraint) + return; + + tree cur = current_failed_constraint; + + /* Recursively print nested contexts. */ + current_failed_constraint = TREE_CHAIN (current_failed_constraint); + if (current_failed_constraint) + maybe_print_constraint_context (context); + + /* Print this context. */ + maybe_print_single_constraint_context (context, cur); +} + +/* Return true iff TYPE_A and TYPE_B are template types that are + meaningful to compare. */ + +static bool +comparable_template_types_p (tree type_a, tree type_b) +{ + if (!CLASS_TYPE_P (type_a)) + return false; + if (!CLASS_TYPE_P (type_b)) + return false; + + tree tinfo_a = TYPE_TEMPLATE_INFO (type_a); + tree tinfo_b = TYPE_TEMPLATE_INFO (type_b); + if (!tinfo_a || !tinfo_b) + return false; + + return TI_TEMPLATE (tinfo_a) == TI_TEMPLATE (tinfo_b); +} + +/* Start a new line indented by SPC spaces on PP. */ + +static void +newline_and_indent (pretty_printer *pp, int spc) +{ + pp_newline (pp); + for (int i = 0; i < spc; i++) + pp_space (pp); +} + +/* Generate a GC-allocated string for ARG, an expression or type. */ + +static const char * +arg_to_string (tree arg, bool verbose) +{ + if (TYPE_P (arg)) + return type_to_string (arg, verbose, true, NULL, false); + else + return expr_to_string (arg); +} + +/* Subroutine to type_to_string_with_compare and + print_template_tree_comparison. + + Print a representation of ARG (an expression or type) to PP, + colorizing it as "type-diff" if PP->show_color. */ + +static void +print_nonequal_arg (pretty_printer *pp, tree arg, bool verbose) +{ + pp_printf (pp, "%r%s%R", + "type-diff", + (arg + ? arg_to_string (arg, verbose) + : G_("(no argument)"))); +} + +/* Recursively print template TYPE_A to PP, as compared to template TYPE_B. + + The types must satisfy comparable_template_types_p. + + If INDENT is 0, then this is equivalent to type_to_string (TYPE_A), but + potentially colorizing/eliding in comparison with TYPE_B. + + For example given types: + vector<map<int,double>> + and + vector<map<int,float>> + then the result on PP would be: + vector<map<[...],double>> + with type elision, and: + vector<map<int,double>> + without type elision. + + In both cases the parts of TYPE that differ from PEER will be colorized + if pp_show_color (pp) is true. In the above example, this would be + "double". + + If INDENT is non-zero, then the types are printed in a tree-like form + which shows both types. In the above example, the result on PP would be: + + vector< + map< + [...], + [double != float]>> + + and without type-elision would be: + + vector< + map< + int, + [double != float]>> + + As before, the differing parts of the types are colorized if + pp_show_color (pp) is true ("double" and "float" in this example). + + Template arguments in which both types are using the default arguments + are not printed; if at least one of the two types is using a non-default + argument, then that argument is printed (or both arguments for the + tree-like print format). */ + +static void +print_template_differences (pretty_printer *pp, tree type_a, tree type_b, + bool verbose, int indent) +{ + if (indent) + newline_and_indent (pp, indent); + + tree tinfo_a = TYPE_TEMPLATE_INFO (type_a); + tree tinfo_b = TYPE_TEMPLATE_INFO (type_b); + + pp_printf (pp, "%s<", + IDENTIFIER_POINTER (DECL_NAME (TI_TEMPLATE (tinfo_a)))); + + tree args_a = TI_ARGS (tinfo_a); + tree args_b = TI_ARGS (tinfo_b); + gcc_assert (TREE_CODE (args_a) == TREE_VEC); + gcc_assert (TREE_CODE (args_b) == TREE_VEC); + int flags = 0; + int len_a = get_non_default_template_args_count (args_a, flags); + args_a = INNERMOST_TEMPLATE_ARGS (args_a); + int len_b = get_non_default_template_args_count (args_b, flags); + args_b = INNERMOST_TEMPLATE_ARGS (args_b); + /* Determine the maximum range of args for which non-default template args + were used; beyond this, only default args (if any) were used, and so + they will be equal from this point onwards. + One of the two peers might have used default arguments within this + range, but the other will be using non-default arguments, and so + it's more readable to print both within this range, to highlight + the differences. */ + int len_max = MAX (len_a, len_b); + gcc_assert (TREE_CODE (args_a) == TREE_VEC); + gcc_assert (TREE_CODE (args_b) == TREE_VEC); + for (int idx = 0; idx < len_max; idx++) + { + if (idx) + pp_character (pp, ','); + + tree arg_a = TREE_VEC_ELT (args_a, idx); + tree arg_b = TREE_VEC_ELT (args_b, idx); + if (arg_a == arg_b) + { + if (indent) + newline_and_indent (pp, indent + 2); + /* Can do elision here, printing "[...]". */ + if (flag_elide_type) + pp_string (pp, G_("[...]")); + else + pp_string (pp, arg_to_string (arg_a, verbose)); + } + else + { + int new_indent = indent ? indent + 2 : 0; + if (comparable_template_types_p (arg_a, arg_b)) + print_template_differences (pp, arg_a, arg_b, verbose, new_indent); + else + if (indent) + { + newline_and_indent (pp, indent + 2); + pp_character (pp, '['); + print_nonequal_arg (pp, arg_a, verbose); + pp_string (pp, " != "); + print_nonequal_arg (pp, arg_b, verbose); + pp_character (pp, ']'); + } + else + print_nonequal_arg (pp, arg_a, verbose); + } + } + pp_printf (pp, ">"); +} + +/* As type_to_string, but for a template, potentially colorizing/eliding + in comparison with PEER. + For example, if TYPE is map<int,double> and PEER is map<int,int>, + then the resulting string would be: + map<[...],double> + with type elision, and: + map<int,double> + without type elision. + + In both cases the parts of TYPE that differ from PEER will be colorized + if SHOW_COLOR is true. In the above example, this would be "double". + + Template arguments in which both types are using the default arguments + are not printed; if at least one of the two types is using a non-default + argument, then both arguments are printed. + + The resulting string is in a GC-allocated buffer. */ + +static const char * +type_to_string_with_compare (tree type, tree peer, bool verbose, + bool show_color) +{ + pretty_printer inner_pp; + pretty_printer *pp = &inner_pp; + pp_show_color (pp) = show_color; + + print_template_differences (pp, type, peer, verbose, 0); + return pp_ggc_formatted_text (pp); +} + +/* Recursively print a tree-like comparison of TYPE_A and TYPE_B to PP, + indented by INDENT spaces. + + For example given types: + + vector<map<int,double>> + + and + + vector<map<double,float>> + + the output with type elision would be: + + vector< + map< + [...], + [double != float]>> + + and without type-elision would be: + + vector< + map< + int, + [double != float]>> + + TYPE_A and TYPE_B must both be comparable template types + (as per comparable_template_types_p). + + Template arguments in which both types are using the default arguments + are not printed; if at least one of the two types is using a non-default + argument, then both arguments are printed. */ + +static void +print_template_tree_comparison (pretty_printer *pp, tree type_a, tree type_b, + bool verbose, int indent) +{ + print_template_differences (pp, type_a, type_b, verbose, indent); +} + +/* Subroutine for use in a format_postprocessor::handle + implementation. Adds a chunk to the end of + formatted output, so that it will be printed + by pp_output_formatted_text. */ + +static void +append_formatted_chunk (pretty_printer *pp, const char *content) +{ + output_buffer *buffer = pp_buffer (pp); + struct chunk_info *chunk_array = buffer->cur_chunk_array; + const char **args = chunk_array->args; + + unsigned int chunk_idx; + for (chunk_idx = 0; args[chunk_idx]; chunk_idx++) + ; + args[chunk_idx++] = content; + args[chunk_idx] = NULL; +} + +/* Create a copy of CONTENT, with quotes added, and, + potentially, with colorization. + No escaped is performed on CONTENT. + The result is in a GC-allocated buffer. */ + +static const char * +add_quotes (const char *content, bool show_color) +{ + pretty_printer tmp_pp; + pp_show_color (&tmp_pp) = show_color; + + /* We have to use "%<%s%>" rather than "%qs" here in order to avoid + quoting colorization bytes within the results and using either + pp_quote or pp_begin_quote doesn't work the same. */ + pp_printf (&tmp_pp, "%<%s%>", content); + + return pp_ggc_formatted_text (&tmp_pp); +} + +#if __GNUC__ >= 10 +# pragma GCC diagnostic pop +#endif + +/* If we had %H and %I, and hence deferred printing them, + print them now, storing the result into the chunk_info + for pp_format. Quote them if 'q' was provided. + Also print the difference in tree form, adding it as + an additional chunk. */ + +void +cxx_format_postprocessor::handle (pretty_printer *pp) +{ + /* If we have one of %H and %I, the other should have + been present. */ + if (m_type_a.m_tree || m_type_b.m_tree) + { + /* Avoid reentrancy issues by working with a copy of + m_type_a and m_type_b, resetting them now. */ + deferred_printed_type type_a = m_type_a; + deferred_printed_type type_b = m_type_b; + m_type_a = deferred_printed_type (); + m_type_b = deferred_printed_type (); + + gcc_assert (type_a.m_buffer_ptr); + gcc_assert (type_b.m_buffer_ptr); + + bool show_color = pp_show_color (pp); + + const char *type_a_text; + const char *type_b_text; + + if (comparable_template_types_p (type_a.m_tree, type_b.m_tree)) + { + type_a_text + = type_to_string_with_compare (type_a.m_tree, type_b.m_tree, + type_a.m_verbose, show_color); + type_b_text + = type_to_string_with_compare (type_b.m_tree, type_a.m_tree, + type_b.m_verbose, show_color); + + if (flag_diagnostics_show_template_tree) + { + pretty_printer inner_pp; + pp_show_color (&inner_pp) = pp_show_color (pp); + print_template_tree_comparison + (&inner_pp, type_a.m_tree, type_b.m_tree, type_a.m_verbose, 2); + append_formatted_chunk (pp, pp_ggc_formatted_text (&inner_pp)); + } + } + else + { + /* If the types were not comparable (or if only one of %H/%I was + provided), they are printed normally, and no difference tree + is printed. */ + type_a_text = type_to_string (type_a.m_tree, type_a.m_verbose, + true, &type_a.m_quote, show_color); + type_b_text = type_to_string (type_b.m_tree, type_b.m_verbose, + true, &type_b.m_quote, show_color); + } + + if (type_a.m_quote) + type_a_text = add_quotes (type_a_text, show_color); + *type_a.m_buffer_ptr = type_a_text; + + if (type_b.m_quote) + type_b_text = add_quotes (type_b_text, show_color); + *type_b.m_buffer_ptr = type_b_text; + } +} + +/* Subroutine for handling %H and %I, to support i18n of messages like: + + error_at (loc, "could not convert %qE from %qH to %qI", + expr, type_a, type_b); + + so that we can print things like: + + could not convert 'foo' from 'map<int,double>' to 'map<int,int>' + + and, with type-elision: + + could not convert 'foo' from 'map<[...],double>' to 'map<[...],int>' + + (with color-coding of the differences between the types). + + The %H and %I format codes are peers: both must be present, + and they affect each other. Hence to handle them, we must + delay printing until we have both, deferring the printing to + pretty_printer's m_format_postprocessor hook. + + This is called in phase 2 of pp_format, when it is accumulating + a series of formatted chunks. We stash the location of the chunk + we're meant to have written to, so that we can write to it in the + m_format_postprocessor hook. + + We also need to stash whether a 'q' prefix was provided (the QUOTE + param) so that we can add the quotes when writing out the delayed + chunk. */ + +static void +defer_phase_2_of_type_diff (deferred_printed_type *deferred, + tree type, const char **buffer_ptr, + bool verbose, bool quote) +{ + gcc_assert (deferred->m_tree == NULL_TREE); + gcc_assert (deferred->m_buffer_ptr == NULL); + *deferred = deferred_printed_type (type, buffer_ptr, verbose, quote); +} + + +/* Called from output_format -- during diagnostic message processing -- + to handle C++ specific format specifier with the following meanings: + %A function argument-list. + %C tree code. + %D declaration. + %E expression. + %F function declaration. + %H type difference (from). + %I type difference (to). + %L language as used in extern "lang". + %O binary operator. + %P function parameter whose position is indicated by an integer. + %Q assignment operator. + %S substitution (template + args) + %T type. + %V cv-qualifier. + %X exception-specification. */ +static bool +cp_printer (pretty_printer *pp, text_info *text, const char *spec, + int precision, bool wide, bool set_locus, bool verbose, + bool *quoted, const char **buffer_ptr) +{ + gcc_assert (pp->m_format_postprocessor); + cxx_format_postprocessor *postprocessor + = static_cast <cxx_format_postprocessor *> (pp->m_format_postprocessor); + + const char *result; + tree t = NULL; +#define next_tree (t = va_arg (*text->args_ptr, tree)) +#define next_tcode ((enum tree_code) va_arg (*text->args_ptr, int)) +#define next_lang ((enum languages) va_arg (*text->args_ptr, int)) +#define next_int va_arg (*text->args_ptr, int) + + if (precision != 0 || wide) + return false; + + switch (*spec) + { + case 'A': result = args_to_string (next_tree, verbose); break; + case 'C': result = code_to_string (next_tcode); break; + case 'D': + { + tree temp = next_tree; + if (VAR_P (temp) + && DECL_HAS_DEBUG_EXPR_P (temp)) + { + temp = DECL_DEBUG_EXPR (temp); + if (!DECL_P (temp)) + { + result = expr_to_string (temp); + break; + } + } + result = decl_to_string (temp, verbose); + } + break; + case 'E': result = expr_to_string (next_tree); break; + case 'F': result = fndecl_to_string (next_tree, verbose); break; + case 'H': + defer_phase_2_of_type_diff (&postprocessor->m_type_a, next_tree, + buffer_ptr, verbose, *quoted); + return true; + case 'I': + defer_phase_2_of_type_diff (&postprocessor->m_type_b, next_tree, + buffer_ptr, verbose, *quoted); + return true; + case 'L': result = language_to_string (next_lang); break; + case 'O': result = op_to_string (false, next_tcode); break; + case 'P': result = parm_to_string (next_int); break; + case 'Q': result = op_to_string (true, next_tcode); break; + case 'S': result = subst_to_string (next_tree); break; + case 'T': + { + result = type_to_string (next_tree, verbose, false, quoted, + pp_show_color (pp)); + } + break; + case 'V': result = cv_to_string (next_tree, verbose); break; + case 'X': result = eh_spec_to_string (next_tree, verbose); break; + + default: + return false; + } + + pp_string (pp, result); + if (set_locus && t != NULL) + text->set_location (0, location_of (t), SHOW_RANGE_WITH_CARET); + return true; +#undef next_tree +#undef next_tcode +#undef next_lang +#undef next_int +} + +/* Warn about the use of C++0x features when appropriate. */ +void +maybe_warn_cpp0x (cpp0x_warn_str str, location_t loc/*=input_location*/) +{ + if (cxx_dialect == cxx98) + switch (str) + { + case CPP0X_INITIALIZER_LISTS: + pedwarn (loc, OPT_Wc__11_extensions, + "extended initializer lists " + "only available with %<-std=c++11%> or %<-std=gnu++11%>"); + break; + case CPP0X_EXPLICIT_CONVERSION: + pedwarn (loc, OPT_Wc__11_extensions, + "explicit conversion operators " + "only available with %<-std=c++11%> or %<-std=gnu++11%>"); + break; + case CPP0X_VARIADIC_TEMPLATES: + pedwarn (loc, OPT_Wc__11_extensions, + "variadic templates " + "only available with %<-std=c++11%> or %<-std=gnu++11%>"); + break; + case CPP0X_LAMBDA_EXPR: + pedwarn (loc, OPT_Wc__11_extensions, + "lambda expressions " + "only available with %<-std=c++11%> or %<-std=gnu++11%>"); + break; + case CPP0X_AUTO: + pedwarn (loc, OPT_Wc__11_extensions, + "C++11 auto only available with %<-std=c++11%> or " + "%<-std=gnu++11%>"); + break; + case CPP0X_SCOPED_ENUMS: + pedwarn (loc, OPT_Wc__11_extensions, + "scoped enums only available with %<-std=c++11%> or " + "%<-std=gnu++11%>"); + break; + case CPP0X_DEFAULTED_DELETED: + pedwarn (loc, OPT_Wc__11_extensions, + "defaulted and deleted functions " + "only available with %<-std=c++11%> or %<-std=gnu++11%>"); + break; + case CPP0X_INLINE_NAMESPACES: + if (pedantic) + pedwarn (loc, OPT_Wc__11_extensions, + "inline namespaces " + "only available with %<-std=c++11%> or %<-std=gnu++11%>"); + break; + case CPP0X_OVERRIDE_CONTROLS: + pedwarn (loc, OPT_Wc__11_extensions, + "override controls (override/final) " + "only available with %<-std=c++11%> or %<-std=gnu++11%>"); + break; + case CPP0X_NSDMI: + pedwarn (loc, OPT_Wc__11_extensions, + "non-static data member initializers " + "only available with %<-std=c++11%> or %<-std=gnu++11%>"); + break; + case CPP0X_USER_DEFINED_LITERALS: + pedwarn (loc, OPT_Wc__11_extensions, + "user-defined literals " + "only available with %<-std=c++11%> or %<-std=gnu++11%>"); + break; + case CPP0X_DELEGATING_CTORS: + pedwarn (loc, OPT_Wc__11_extensions, + "delegating constructors " + "only available with %<-std=c++11%> or %<-std=gnu++11%>"); + break; + case CPP0X_INHERITING_CTORS: + pedwarn (loc, OPT_Wc__11_extensions, + "inheriting constructors " + "only available with %<-std=c++11%> or %<-std=gnu++11%>"); + break; + case CPP0X_ATTRIBUTES: + pedwarn (loc, OPT_Wc__11_extensions, + "C++11 attributes " + "only available with %<-std=c++11%> or %<-std=gnu++11%>"); + break; + case CPP0X_REF_QUALIFIER: + pedwarn (loc, OPT_Wc__11_extensions, + "ref-qualifiers " + "only available with %<-std=c++11%> or %<-std=gnu++11%>"); + break; + default: + gcc_unreachable (); + } +} + +/* Warn about the use of variadic templates when appropriate. */ +void +maybe_warn_variadic_templates (void) +{ + maybe_warn_cpp0x (CPP0X_VARIADIC_TEMPLATES); +} + + +/* Issue an ISO C++98 pedantic warning at LOCATION, conditional on + option OPT with text GMSGID. Use this function to report + diagnostics for constructs that are invalid C++98, but valid + C++0x. */ +bool +pedwarn_cxx98 (location_t location, int opt, const char *gmsgid, ...) +{ + diagnostic_info diagnostic; + va_list ap; + bool ret; + rich_location richloc (line_table, location); + + va_start (ap, gmsgid); + diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, + (cxx_dialect == cxx98) ? DK_PEDWARN : DK_WARNING); + diagnostic.option_index = opt; + ret = diagnostic_report_diagnostic (global_dc, &diagnostic); + va_end (ap); + return ret; +} + +/* Issue a diagnostic that NAME cannot be found in SCOPE. DECL is what + we found when we tried to do the lookup. LOCATION is the location of + the NAME identifier. */ + +void +qualified_name_lookup_error (tree scope, tree name, + tree decl, location_t location) +{ + if (scope == error_mark_node) + ; /* We already complained. */ + else if (TYPE_P (scope)) + { + if (!COMPLETE_TYPE_P (scope)) + error_at (location, "incomplete type %qT used in nested name specifier", + scope); + else if (TREE_CODE (decl) == TREE_LIST) + { + error_at (location, "reference to %<%T::%D%> is ambiguous", + scope, name); + print_candidates (decl); + } + else + { + name_hint hint; + if (SCOPED_ENUM_P (scope) && TREE_CODE (name) == IDENTIFIER_NODE) + hint = suggest_alternative_in_scoped_enum (name, scope); + if (const char *suggestion = hint.suggestion ()) + { + gcc_rich_location richloc (location); + richloc.add_fixit_replace (suggestion); + error_at (&richloc, + "%qD is not a member of %qT; did you mean %qs?", + name, scope, suggestion); + } + else + error_at (location, "%qD is not a member of %qT", name, scope); + } + } + else if (scope != global_namespace) + { + auto_diagnostic_group d; + bool emit_fixit = true; + name_hint hint + = suggest_alternative_in_explicit_scope (location, name, scope); + if (!hint) + { + hint = suggest_alternatives_in_other_namespaces (location, name); + /* "location" is just the location of the name, not of the explicit + scope, and it's not easy to get at the latter, so we can't issue + fix-it hints for the suggestion. */ + emit_fixit = false; + } + if (const char *suggestion = hint.suggestion ()) + { + gcc_rich_location richloc (location); + if (emit_fixit) + richloc.add_fixit_replace (suggestion); + error_at (&richloc, "%qD is not a member of %qD; did you mean %qs?", + name, scope, suggestion); + } + else + error_at (location, "%qD is not a member of %qD", name, scope); + } + else + { + auto_diagnostic_group d; + name_hint hint = suggest_alternatives_for (location, name, true); + if (const char *suggestion = hint.suggestion ()) + { + gcc_rich_location richloc (location); + richloc.add_fixit_replace (suggestion); + error_at (&richloc, + "%<::%D%> has not been declared; did you mean %qs?", + name, suggestion); + } + else + error_at (location, "%<::%D%> has not been declared", name); + } +} + +/* C++-specific implementation of range_label::get_text () vfunc for + range_label_for_type_mismatch. + + Compare with print_template_differences above. */ + +label_text +range_label_for_type_mismatch::get_text (unsigned /*range_idx*/) const +{ + if (m_labelled_type == NULL_TREE) + return label_text::borrow (NULL); + + const bool verbose = false; + const bool show_color = false; + + const char *result; + if (m_other_type + && comparable_template_types_p (m_labelled_type, m_other_type)) + result = type_to_string_with_compare (m_labelled_type, m_other_type, + verbose, show_color); + else + result = type_to_string (m_labelled_type, verbose, true, NULL, show_color); + + /* Both of the above return GC-allocated buffers, so the caller mustn't + free them. */ + return label_text::borrow (result); +} |