aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/error.cc
diff options
context:
space:
mode:
authorMartin Liska <mliska@suse.cz>2022-01-14 16:56:44 +0100
committerMartin Liska <mliska@suse.cz>2022-01-17 22:12:04 +0100
commit5c69acb32329d49e58c26fa41ae74229a52b9106 (patch)
treeddb05f9d73afb6f998457d2ac4b720e3b3b60483 /gcc/cp/error.cc
parent490e23032baaece71f2ec09fa1805064b150fbc2 (diff)
downloadgcc-5c69acb32329d49e58c26fa41ae74229a52b9106.zip
gcc-5c69acb32329d49e58c26fa41ae74229a52b9106.tar.gz
gcc-5c69acb32329d49e58c26fa41ae74229a52b9106.tar.bz2
Rename .c files to .cc files.
gcc/ada/ChangeLog: * adadecode.c: Moved to... * adadecode.cc: ...here. * affinity.c: Moved to... * affinity.cc: ...here. * argv-lynxos178-raven-cert.c: Moved to... * argv-lynxos178-raven-cert.cc: ...here. * argv.c: Moved to... * argv.cc: ...here. * aux-io.c: Moved to... * aux-io.cc: ...here. * cio.c: Moved to... * cio.cc: ...here. * cstreams.c: Moved to... * cstreams.cc: ...here. * env.c: Moved to... * env.cc: ...here. * exit.c: Moved to... * exit.cc: ...here. * expect.c: Moved to... * expect.cc: ...here. * final.c: Moved to... * final.cc: ...here. * gcc-interface/cuintp.c: Moved to... * gcc-interface/cuintp.cc: ...here. * gcc-interface/decl.c: Moved to... * gcc-interface/decl.cc: ...here. * gcc-interface/misc.c: Moved to... * gcc-interface/misc.cc: ...here. * gcc-interface/targtyps.c: Moved to... * gcc-interface/targtyps.cc: ...here. * gcc-interface/trans.c: Moved to... * gcc-interface/trans.cc: ...here. * gcc-interface/utils.c: Moved to... * gcc-interface/utils.cc: ...here. * gcc-interface/utils2.c: Moved to... * gcc-interface/utils2.cc: ...here. * init.c: Moved to... * init.cc: ...here. * initialize.c: Moved to... * initialize.cc: ...here. * libgnarl/thread.c: Moved to... * libgnarl/thread.cc: ...here. * link.c: Moved to... * link.cc: ...here. * locales.c: Moved to... * locales.cc: ...here. * mkdir.c: Moved to... * mkdir.cc: ...here. * raise.c: Moved to... * raise.cc: ...here. * rtfinal.c: Moved to... * rtfinal.cc: ...here. * rtinit.c: Moved to... * rtinit.cc: ...here. * seh_init.c: Moved to... * seh_init.cc: ...here. * sigtramp-armdroid.c: Moved to... * sigtramp-armdroid.cc: ...here. * sigtramp-ios.c: Moved to... * sigtramp-ios.cc: ...here. * sigtramp-qnx.c: Moved to... * sigtramp-qnx.cc: ...here. * sigtramp-vxworks.c: Moved to... * sigtramp-vxworks.cc: ...here. * socket.c: Moved to... * socket.cc: ...here. * tracebak.c: Moved to... * tracebak.cc: ...here. * version.c: Moved to... * version.cc: ...here. * vx_stack_info.c: Moved to... * vx_stack_info.cc: ...here. gcc/ChangeLog: * adjust-alignment.c: Moved to... * adjust-alignment.cc: ...here. * alias.c: Moved to... * alias.cc: ...here. * alloc-pool.c: Moved to... * alloc-pool.cc: ...here. * asan.c: Moved to... * asan.cc: ...here. * attribs.c: Moved to... * attribs.cc: ...here. * auto-inc-dec.c: Moved to... * auto-inc-dec.cc: ...here. * auto-profile.c: Moved to... * auto-profile.cc: ...here. * bb-reorder.c: Moved to... * bb-reorder.cc: ...here. * bitmap.c: Moved to... * bitmap.cc: ...here. * btfout.c: Moved to... * btfout.cc: ...here. * builtins.c: Moved to... * builtins.cc: ...here. * caller-save.c: Moved to... * caller-save.cc: ...here. * calls.c: Moved to... * calls.cc: ...here. * ccmp.c: Moved to... * ccmp.cc: ...here. * cfg.c: Moved to... * cfg.cc: ...here. * cfganal.c: Moved to... * cfganal.cc: ...here. * cfgbuild.c: Moved to... * cfgbuild.cc: ...here. * cfgcleanup.c: Moved to... * cfgcleanup.cc: ...here. * cfgexpand.c: Moved to... * cfgexpand.cc: ...here. * cfghooks.c: Moved to... * cfghooks.cc: ...here. * cfgloop.c: Moved to... * cfgloop.cc: ...here. * cfgloopanal.c: Moved to... * cfgloopanal.cc: ...here. * cfgloopmanip.c: Moved to... * cfgloopmanip.cc: ...here. * cfgrtl.c: Moved to... * cfgrtl.cc: ...here. * cgraph.c: Moved to... * cgraph.cc: ...here. * cgraphbuild.c: Moved to... * cgraphbuild.cc: ...here. * cgraphclones.c: Moved to... * cgraphclones.cc: ...here. * cgraphunit.c: Moved to... * cgraphunit.cc: ...here. * collect-utils.c: Moved to... * collect-utils.cc: ...here. * collect2-aix.c: Moved to... * collect2-aix.cc: ...here. * collect2.c: Moved to... * collect2.cc: ...here. * combine-stack-adj.c: Moved to... * combine-stack-adj.cc: ...here. * combine.c: Moved to... * combine.cc: ...here. * common/common-targhooks.c: Moved to... * common/common-targhooks.cc: ...here. * common/config/aarch64/aarch64-common.c: Moved to... * common/config/aarch64/aarch64-common.cc: ...here. * common/config/alpha/alpha-common.c: Moved to... * common/config/alpha/alpha-common.cc: ...here. * common/config/arc/arc-common.c: Moved to... * common/config/arc/arc-common.cc: ...here. * common/config/arm/arm-common.c: Moved to... * common/config/arm/arm-common.cc: ...here. * common/config/avr/avr-common.c: Moved to... * common/config/avr/avr-common.cc: ...here. * common/config/bfin/bfin-common.c: Moved to... * common/config/bfin/bfin-common.cc: ...here. * common/config/bpf/bpf-common.c: Moved to... * common/config/bpf/bpf-common.cc: ...here. * common/config/c6x/c6x-common.c: Moved to... * common/config/c6x/c6x-common.cc: ...here. * common/config/cr16/cr16-common.c: Moved to... * common/config/cr16/cr16-common.cc: ...here. * common/config/cris/cris-common.c: Moved to... * common/config/cris/cris-common.cc: ...here. * common/config/csky/csky-common.c: Moved to... * common/config/csky/csky-common.cc: ...here. * common/config/default-common.c: Moved to... * common/config/default-common.cc: ...here. * common/config/epiphany/epiphany-common.c: Moved to... * common/config/epiphany/epiphany-common.cc: ...here. * common/config/fr30/fr30-common.c: Moved to... * common/config/fr30/fr30-common.cc: ...here. * common/config/frv/frv-common.c: Moved to... * common/config/frv/frv-common.cc: ...here. * common/config/gcn/gcn-common.c: Moved to... * common/config/gcn/gcn-common.cc: ...here. * common/config/h8300/h8300-common.c: Moved to... * common/config/h8300/h8300-common.cc: ...here. * common/config/i386/i386-common.c: Moved to... * common/config/i386/i386-common.cc: ...here. * common/config/ia64/ia64-common.c: Moved to... * common/config/ia64/ia64-common.cc: ...here. * common/config/iq2000/iq2000-common.c: Moved to... * common/config/iq2000/iq2000-common.cc: ...here. * common/config/lm32/lm32-common.c: Moved to... * common/config/lm32/lm32-common.cc: ...here. * common/config/m32r/m32r-common.c: Moved to... * common/config/m32r/m32r-common.cc: ...here. * common/config/m68k/m68k-common.c: Moved to... * common/config/m68k/m68k-common.cc: ...here. * common/config/mcore/mcore-common.c: Moved to... * common/config/mcore/mcore-common.cc: ...here. * common/config/microblaze/microblaze-common.c: Moved to... * common/config/microblaze/microblaze-common.cc: ...here. * common/config/mips/mips-common.c: Moved to... * common/config/mips/mips-common.cc: ...here. * common/config/mmix/mmix-common.c: Moved to... * common/config/mmix/mmix-common.cc: ...here. * common/config/mn10300/mn10300-common.c: Moved to... * common/config/mn10300/mn10300-common.cc: ...here. * common/config/msp430/msp430-common.c: Moved to... * common/config/msp430/msp430-common.cc: ...here. * common/config/nds32/nds32-common.c: Moved to... * common/config/nds32/nds32-common.cc: ...here. * common/config/nios2/nios2-common.c: Moved to... * common/config/nios2/nios2-common.cc: ...here. * common/config/nvptx/nvptx-common.c: Moved to... * common/config/nvptx/nvptx-common.cc: ...here. * common/config/or1k/or1k-common.c: Moved to... * common/config/or1k/or1k-common.cc: ...here. * common/config/pa/pa-common.c: Moved to... * common/config/pa/pa-common.cc: ...here. * common/config/pdp11/pdp11-common.c: Moved to... * common/config/pdp11/pdp11-common.cc: ...here. * common/config/pru/pru-common.c: Moved to... * common/config/pru/pru-common.cc: ...here. * common/config/riscv/riscv-common.c: Moved to... * common/config/riscv/riscv-common.cc: ...here. * common/config/rs6000/rs6000-common.c: Moved to... * common/config/rs6000/rs6000-common.cc: ...here. * common/config/rx/rx-common.c: Moved to... * common/config/rx/rx-common.cc: ...here. * common/config/s390/s390-common.c: Moved to... * common/config/s390/s390-common.cc: ...here. * common/config/sh/sh-common.c: Moved to... * common/config/sh/sh-common.cc: ...here. * common/config/sparc/sparc-common.c: Moved to... * common/config/sparc/sparc-common.cc: ...here. * common/config/tilegx/tilegx-common.c: Moved to... * common/config/tilegx/tilegx-common.cc: ...here. * common/config/tilepro/tilepro-common.c: Moved to... * common/config/tilepro/tilepro-common.cc: ...here. * common/config/v850/v850-common.c: Moved to... * common/config/v850/v850-common.cc: ...here. * common/config/vax/vax-common.c: Moved to... * common/config/vax/vax-common.cc: ...here. * common/config/visium/visium-common.c: Moved to... * common/config/visium/visium-common.cc: ...here. * common/config/xstormy16/xstormy16-common.c: Moved to... * common/config/xstormy16/xstormy16-common.cc: ...here. * common/config/xtensa/xtensa-common.c: Moved to... * common/config/xtensa/xtensa-common.cc: ...here. * compare-elim.c: Moved to... * compare-elim.cc: ...here. * config/aarch64/aarch64-bti-insert.c: Moved to... * config/aarch64/aarch64-bti-insert.cc: ...here. * config/aarch64/aarch64-builtins.c: Moved to... * config/aarch64/aarch64-builtins.cc: ...here. * config/aarch64/aarch64-c.c: Moved to... * config/aarch64/aarch64-c.cc: ...here. * config/aarch64/aarch64-d.c: Moved to... * config/aarch64/aarch64-d.cc: ...here. * config/aarch64/aarch64.c: Moved to... * config/aarch64/aarch64.cc: ...here. * config/aarch64/cortex-a57-fma-steering.c: Moved to... * config/aarch64/cortex-a57-fma-steering.cc: ...here. * config/aarch64/driver-aarch64.c: Moved to... * config/aarch64/driver-aarch64.cc: ...here. * config/aarch64/falkor-tag-collision-avoidance.c: Moved to... * config/aarch64/falkor-tag-collision-avoidance.cc: ...here. * config/aarch64/host-aarch64-darwin.c: Moved to... * config/aarch64/host-aarch64-darwin.cc: ...here. * config/alpha/alpha.c: Moved to... * config/alpha/alpha.cc: ...here. * config/alpha/driver-alpha.c: Moved to... * config/alpha/driver-alpha.cc: ...here. * config/arc/arc-c.c: Moved to... * config/arc/arc-c.cc: ...here. * config/arc/arc.c: Moved to... * config/arc/arc.cc: ...here. * config/arc/driver-arc.c: Moved to... * config/arc/driver-arc.cc: ...here. * config/arm/aarch-common.c: Moved to... * config/arm/aarch-common.cc: ...here. * config/arm/arm-builtins.c: Moved to... * config/arm/arm-builtins.cc: ...here. * config/arm/arm-c.c: Moved to... * config/arm/arm-c.cc: ...here. * config/arm/arm-d.c: Moved to... * config/arm/arm-d.cc: ...here. * config/arm/arm.c: Moved to... * config/arm/arm.cc: ...here. * config/arm/driver-arm.c: Moved to... * config/arm/driver-arm.cc: ...here. * config/avr/avr-c.c: Moved to... * config/avr/avr-c.cc: ...here. * config/avr/avr-devices.c: Moved to... * config/avr/avr-devices.cc: ...here. * config/avr/avr-log.c: Moved to... * config/avr/avr-log.cc: ...here. * config/avr/avr.c: Moved to... * config/avr/avr.cc: ...here. * config/avr/driver-avr.c: Moved to... * config/avr/driver-avr.cc: ...here. * config/avr/gen-avr-mmcu-specs.c: Moved to... * config/avr/gen-avr-mmcu-specs.cc: ...here. * config/avr/gen-avr-mmcu-texi.c: Moved to... * config/avr/gen-avr-mmcu-texi.cc: ...here. * config/bfin/bfin.c: Moved to... * config/bfin/bfin.cc: ...here. * config/bpf/bpf.c: Moved to... * config/bpf/bpf.cc: ...here. * config/bpf/coreout.c: Moved to... * config/bpf/coreout.cc: ...here. * config/c6x/c6x.c: Moved to... * config/c6x/c6x.cc: ...here. * config/cr16/cr16.c: Moved to... * config/cr16/cr16.cc: ...here. * config/cris/cris.c: Moved to... * config/cris/cris.cc: ...here. * config/csky/csky.c: Moved to... * config/csky/csky.cc: ...here. * config/darwin-c.c: Moved to... * config/darwin-c.cc: ...here. * config/darwin-d.c: Moved to... * config/darwin-d.cc: ...here. * config/darwin-driver.c: Moved to... * config/darwin-driver.cc: ...here. * config/darwin-f.c: Moved to... * config/darwin-f.cc: ...here. * config/darwin.c: Moved to... * config/darwin.cc: ...here. * config/default-c.c: Moved to... * config/default-c.cc: ...here. * config/default-d.c: Moved to... * config/default-d.cc: ...here. * config/dragonfly-d.c: Moved to... * config/dragonfly-d.cc: ...here. * config/epiphany/epiphany.c: Moved to... * config/epiphany/epiphany.cc: ...here. * config/epiphany/mode-switch-use.c: Moved to... * config/epiphany/mode-switch-use.cc: ...here. * config/epiphany/resolve-sw-modes.c: Moved to... * config/epiphany/resolve-sw-modes.cc: ...here. * config/fr30/fr30.c: Moved to... * config/fr30/fr30.cc: ...here. * config/freebsd-d.c: Moved to... * config/freebsd-d.cc: ...here. * config/frv/frv.c: Moved to... * config/frv/frv.cc: ...here. * config/ft32/ft32.c: Moved to... * config/ft32/ft32.cc: ...here. * config/gcn/driver-gcn.c: Moved to... * config/gcn/driver-gcn.cc: ...here. * config/gcn/gcn-run.c: Moved to... * config/gcn/gcn-run.cc: ...here. * config/gcn/gcn-tree.c: Moved to... * config/gcn/gcn-tree.cc: ...here. * config/gcn/gcn.c: Moved to... * config/gcn/gcn.cc: ...here. * config/gcn/mkoffload.c: Moved to... * config/gcn/mkoffload.cc: ...here. * config/glibc-c.c: Moved to... * config/glibc-c.cc: ...here. * config/glibc-d.c: Moved to... * config/glibc-d.cc: ...here. * config/h8300/h8300.c: Moved to... * config/h8300/h8300.cc: ...here. * config/host-darwin.c: Moved to... * config/host-darwin.cc: ...here. * config/host-hpux.c: Moved to... * config/host-hpux.cc: ...here. * config/host-linux.c: Moved to... * config/host-linux.cc: ...here. * config/host-netbsd.c: Moved to... * config/host-netbsd.cc: ...here. * config/host-openbsd.c: Moved to... * config/host-openbsd.cc: ...here. * config/host-solaris.c: Moved to... * config/host-solaris.cc: ...here. * config/i386/djgpp.c: Moved to... * config/i386/djgpp.cc: ...here. * config/i386/driver-i386.c: Moved to... * config/i386/driver-i386.cc: ...here. * config/i386/driver-mingw32.c: Moved to... * config/i386/driver-mingw32.cc: ...here. * config/i386/gnu-property.c: Moved to... * config/i386/gnu-property.cc: ...here. * config/i386/host-cygwin.c: Moved to... * config/i386/host-cygwin.cc: ...here. * config/i386/host-i386-darwin.c: Moved to... * config/i386/host-i386-darwin.cc: ...here. * config/i386/host-mingw32.c: Moved to... * config/i386/host-mingw32.cc: ...here. * config/i386/i386-builtins.c: Moved to... * config/i386/i386-builtins.cc: ...here. * config/i386/i386-c.c: Moved to... * config/i386/i386-c.cc: ...here. * config/i386/i386-d.c: Moved to... * config/i386/i386-d.cc: ...here. * config/i386/i386-expand.c: Moved to... * config/i386/i386-expand.cc: ...here. * config/i386/i386-features.c: Moved to... * config/i386/i386-features.cc: ...here. * config/i386/i386-options.c: Moved to... * config/i386/i386-options.cc: ...here. * config/i386/i386.c: Moved to... * config/i386/i386.cc: ...here. * config/i386/intelmic-mkoffload.c: Moved to... * config/i386/intelmic-mkoffload.cc: ...here. * config/i386/msformat-c.c: Moved to... * config/i386/msformat-c.cc: ...here. * config/i386/winnt-cxx.c: Moved to... * config/i386/winnt-cxx.cc: ...here. * config/i386/winnt-d.c: Moved to... * config/i386/winnt-d.cc: ...here. * config/i386/winnt-stubs.c: Moved to... * config/i386/winnt-stubs.cc: ...here. * config/i386/winnt.c: Moved to... * config/i386/winnt.cc: ...here. * config/i386/x86-tune-sched-atom.c: Moved to... * config/i386/x86-tune-sched-atom.cc: ...here. * config/i386/x86-tune-sched-bd.c: Moved to... * config/i386/x86-tune-sched-bd.cc: ...here. * config/i386/x86-tune-sched-core.c: Moved to... * config/i386/x86-tune-sched-core.cc: ...here. * config/i386/x86-tune-sched.c: Moved to... * config/i386/x86-tune-sched.cc: ...here. * config/ia64/ia64-c.c: Moved to... * config/ia64/ia64-c.cc: ...here. * config/ia64/ia64.c: Moved to... * config/ia64/ia64.cc: ...here. * config/iq2000/iq2000.c: Moved to... * config/iq2000/iq2000.cc: ...here. * config/linux.c: Moved to... * config/linux.cc: ...here. * config/lm32/lm32.c: Moved to... * config/lm32/lm32.cc: ...here. * config/m32c/m32c-pragma.c: Moved to... * config/m32c/m32c-pragma.cc: ...here. * config/m32c/m32c.c: Moved to... * config/m32c/m32c.cc: ...here. * config/m32r/m32r.c: Moved to... * config/m32r/m32r.cc: ...here. * config/m68k/m68k.c: Moved to... * config/m68k/m68k.cc: ...here. * config/mcore/mcore.c: Moved to... * config/mcore/mcore.cc: ...here. * config/microblaze/microblaze-c.c: Moved to... * config/microblaze/microblaze-c.cc: ...here. * config/microblaze/microblaze.c: Moved to... * config/microblaze/microblaze.cc: ...here. * config/mips/driver-native.c: Moved to... * config/mips/driver-native.cc: ...here. * config/mips/frame-header-opt.c: Moved to... * config/mips/frame-header-opt.cc: ...here. * config/mips/mips-d.c: Moved to... * config/mips/mips-d.cc: ...here. * config/mips/mips.c: Moved to... * config/mips/mips.cc: ...here. * config/mmix/mmix.c: Moved to... * config/mmix/mmix.cc: ...here. * config/mn10300/mn10300.c: Moved to... * config/mn10300/mn10300.cc: ...here. * config/moxie/moxie.c: Moved to... * config/moxie/moxie.cc: ...here. * config/msp430/driver-msp430.c: Moved to... * config/msp430/driver-msp430.cc: ...here. * config/msp430/msp430-c.c: Moved to... * config/msp430/msp430-c.cc: ...here. * config/msp430/msp430-devices.c: Moved to... * config/msp430/msp430-devices.cc: ...here. * config/msp430/msp430.c: Moved to... * config/msp430/msp430.cc: ...here. * config/nds32/nds32-cost.c: Moved to... * config/nds32/nds32-cost.cc: ...here. * config/nds32/nds32-fp-as-gp.c: Moved to... * config/nds32/nds32-fp-as-gp.cc: ...here. * config/nds32/nds32-intrinsic.c: Moved to... * config/nds32/nds32-intrinsic.cc: ...here. * config/nds32/nds32-isr.c: Moved to... * config/nds32/nds32-isr.cc: ...here. * config/nds32/nds32-md-auxiliary.c: Moved to... * config/nds32/nds32-md-auxiliary.cc: ...here. * config/nds32/nds32-memory-manipulation.c: Moved to... * config/nds32/nds32-memory-manipulation.cc: ...here. * config/nds32/nds32-pipelines-auxiliary.c: Moved to... * config/nds32/nds32-pipelines-auxiliary.cc: ...here. * config/nds32/nds32-predicates.c: Moved to... * config/nds32/nds32-predicates.cc: ...here. * config/nds32/nds32-relax-opt.c: Moved to... * config/nds32/nds32-relax-opt.cc: ...here. * config/nds32/nds32-utils.c: Moved to... * config/nds32/nds32-utils.cc: ...here. * config/nds32/nds32.c: Moved to... * config/nds32/nds32.cc: ...here. * config/netbsd-d.c: Moved to... * config/netbsd-d.cc: ...here. * config/netbsd.c: Moved to... * config/netbsd.cc: ...here. * config/nios2/nios2.c: Moved to... * config/nios2/nios2.cc: ...here. * config/nvptx/mkoffload.c: Moved to... * config/nvptx/mkoffload.cc: ...here. * config/nvptx/nvptx-c.c: Moved to... * config/nvptx/nvptx-c.cc: ...here. * config/nvptx/nvptx.c: Moved to... * config/nvptx/nvptx.cc: ...here. * config/openbsd-d.c: Moved to... * config/openbsd-d.cc: ...here. * config/or1k/or1k.c: Moved to... * config/or1k/or1k.cc: ...here. * config/pa/pa-d.c: Moved to... * config/pa/pa-d.cc: ...here. * config/pa/pa.c: Moved to... * config/pa/pa.cc: ...here. * config/pdp11/pdp11.c: Moved to... * config/pdp11/pdp11.cc: ...here. * config/pru/pru-passes.c: Moved to... * config/pru/pru-passes.cc: ...here. * config/pru/pru-pragma.c: Moved to... * config/pru/pru-pragma.cc: ...here. * config/pru/pru.c: Moved to... * config/pru/pru.cc: ...here. * config/riscv/riscv-builtins.c: Moved to... * config/riscv/riscv-builtins.cc: ...here. * config/riscv/riscv-c.c: Moved to... * config/riscv/riscv-c.cc: ...here. * config/riscv/riscv-d.c: Moved to... * config/riscv/riscv-d.cc: ...here. * config/riscv/riscv-shorten-memrefs.c: Moved to... * config/riscv/riscv-shorten-memrefs.cc: ...here. * config/riscv/riscv-sr.c: Moved to... * config/riscv/riscv-sr.cc: ...here. * config/riscv/riscv.c: Moved to... * config/riscv/riscv.cc: ...here. * config/rl78/rl78-c.c: Moved to... * config/rl78/rl78-c.cc: ...here. * config/rl78/rl78.c: Moved to... * config/rl78/rl78.cc: ...here. * config/rs6000/driver-rs6000.c: Moved to... * config/rs6000/driver-rs6000.cc: ...here. * config/rs6000/host-darwin.c: Moved to... * config/rs6000/host-darwin.cc: ...here. * config/rs6000/host-ppc64-darwin.c: Moved to... * config/rs6000/host-ppc64-darwin.cc: ...here. * config/rs6000/rbtree.c: Moved to... * config/rs6000/rbtree.cc: ...here. * config/rs6000/rs6000-c.c: Moved to... * config/rs6000/rs6000-c.cc: ...here. * config/rs6000/rs6000-call.c: Moved to... * config/rs6000/rs6000-call.cc: ...here. * config/rs6000/rs6000-d.c: Moved to... * config/rs6000/rs6000-d.cc: ...here. * config/rs6000/rs6000-gen-builtins.c: Moved to... * config/rs6000/rs6000-gen-builtins.cc: ...here. * config/rs6000/rs6000-linux.c: Moved to... * config/rs6000/rs6000-linux.cc: ...here. * config/rs6000/rs6000-logue.c: Moved to... * config/rs6000/rs6000-logue.cc: ...here. * config/rs6000/rs6000-p8swap.c: Moved to... * config/rs6000/rs6000-p8swap.cc: ...here. * config/rs6000/rs6000-pcrel-opt.c: Moved to... * config/rs6000/rs6000-pcrel-opt.cc: ...here. * config/rs6000/rs6000-string.c: Moved to... * config/rs6000/rs6000-string.cc: ...here. * config/rs6000/rs6000.c: Moved to... * config/rs6000/rs6000.cc: ...here. * config/rx/rx.c: Moved to... * config/rx/rx.cc: ...here. * config/s390/driver-native.c: Moved to... * config/s390/driver-native.cc: ...here. * config/s390/s390-c.c: Moved to... * config/s390/s390-c.cc: ...here. * config/s390/s390-d.c: Moved to... * config/s390/s390-d.cc: ...here. * config/s390/s390.c: Moved to... * config/s390/s390.cc: ...here. * config/sh/divtab-sh4-300.c: Moved to... * config/sh/divtab-sh4-300.cc: ...here. * config/sh/divtab-sh4.c: Moved to... * config/sh/divtab-sh4.cc: ...here. * config/sh/divtab.c: Moved to... * config/sh/divtab.cc: ...here. * config/sh/sh-c.c: Moved to... * config/sh/sh-c.cc: ...here. * config/sh/sh.c: Moved to... * config/sh/sh.cc: ...here. * config/sol2-c.c: Moved to... * config/sol2-c.cc: ...here. * config/sol2-cxx.c: Moved to... * config/sol2-cxx.cc: ...here. * config/sol2-d.c: Moved to... * config/sol2-d.cc: ...here. * config/sol2-stubs.c: Moved to... * config/sol2-stubs.cc: ...here. * config/sol2.c: Moved to... * config/sol2.cc: ...here. * config/sparc/driver-sparc.c: Moved to... * config/sparc/driver-sparc.cc: ...here. * config/sparc/sparc-c.c: Moved to... * config/sparc/sparc-c.cc: ...here. * config/sparc/sparc-d.c: Moved to... * config/sparc/sparc-d.cc: ...here. * config/sparc/sparc.c: Moved to... * config/sparc/sparc.cc: ...here. * config/stormy16/stormy16.c: Moved to... * config/stormy16/stormy16.cc: ...here. * config/tilegx/mul-tables.c: Moved to... * config/tilegx/mul-tables.cc: ...here. * config/tilegx/tilegx-c.c: Moved to... * config/tilegx/tilegx-c.cc: ...here. * config/tilegx/tilegx.c: Moved to... * config/tilegx/tilegx.cc: ...here. * config/tilepro/mul-tables.c: Moved to... * config/tilepro/mul-tables.cc: ...here. * config/tilepro/tilepro-c.c: Moved to... * config/tilepro/tilepro-c.cc: ...here. * config/tilepro/tilepro.c: Moved to... * config/tilepro/tilepro.cc: ...here. * config/v850/v850-c.c: Moved to... * config/v850/v850-c.cc: ...here. * config/v850/v850.c: Moved to... * config/v850/v850.cc: ...here. * config/vax/vax.c: Moved to... * config/vax/vax.cc: ...here. * config/visium/visium.c: Moved to... * config/visium/visium.cc: ...here. * config/vms/vms-c.c: Moved to... * config/vms/vms-c.cc: ...here. * config/vms/vms-f.c: Moved to... * config/vms/vms-f.cc: ...here. * config/vms/vms.c: Moved to... * config/vms/vms.cc: ...here. * config/vxworks-c.c: Moved to... * config/vxworks-c.cc: ...here. * config/vxworks.c: Moved to... * config/vxworks.cc: ...here. * config/winnt-c.c: Moved to... * config/winnt-c.cc: ...here. * config/xtensa/xtensa.c: Moved to... * config/xtensa/xtensa.cc: ...here. * context.c: Moved to... * context.cc: ...here. * convert.c: Moved to... * convert.cc: ...here. * coverage.c: Moved to... * coverage.cc: ...here. * cppbuiltin.c: Moved to... * cppbuiltin.cc: ...here. * cppdefault.c: Moved to... * cppdefault.cc: ...here. * cprop.c: Moved to... * cprop.cc: ...here. * cse.c: Moved to... * cse.cc: ...here. * cselib.c: Moved to... * cselib.cc: ...here. * ctfc.c: Moved to... * ctfc.cc: ...here. * ctfout.c: Moved to... * ctfout.cc: ...here. * data-streamer-in.c: Moved to... * data-streamer-in.cc: ...here. * data-streamer-out.c: Moved to... * data-streamer-out.cc: ...here. * data-streamer.c: Moved to... * data-streamer.cc: ...here. * dbgcnt.c: Moved to... * dbgcnt.cc: ...here. * dbxout.c: Moved to... * dbxout.cc: ...here. * dce.c: Moved to... * dce.cc: ...here. * ddg.c: Moved to... * ddg.cc: ...here. * debug.c: Moved to... * debug.cc: ...here. * df-core.c: Moved to... * df-core.cc: ...here. * df-problems.c: Moved to... * df-problems.cc: ...here. * df-scan.c: Moved to... * df-scan.cc: ...here. * dfp.c: Moved to... * dfp.cc: ...here. * diagnostic-color.c: Moved to... * diagnostic-color.cc: ...here. * diagnostic-show-locus.c: Moved to... * diagnostic-show-locus.cc: ...here. * diagnostic-spec.c: Moved to... * diagnostic-spec.cc: ...here. * diagnostic.c: Moved to... * diagnostic.cc: ...here. * dojump.c: Moved to... * dojump.cc: ...here. * dominance.c: Moved to... * dominance.cc: ...here. * domwalk.c: Moved to... * domwalk.cc: ...here. * double-int.c: Moved to... * double-int.cc: ...here. * dse.c: Moved to... * dse.cc: ...here. * dumpfile.c: Moved to... * dumpfile.cc: ...here. * dwarf2asm.c: Moved to... * dwarf2asm.cc: ...here. * dwarf2cfi.c: Moved to... * dwarf2cfi.cc: ...here. * dwarf2ctf.c: Moved to... * dwarf2ctf.cc: ...here. * dwarf2out.c: Moved to... * dwarf2out.cc: ...here. * early-remat.c: Moved to... * early-remat.cc: ...here. * edit-context.c: Moved to... * edit-context.cc: ...here. * emit-rtl.c: Moved to... * emit-rtl.cc: ...here. * errors.c: Moved to... * errors.cc: ...here. * et-forest.c: Moved to... * et-forest.cc: ...here. * except.c: Moved to... * except.cc: ...here. * explow.c: Moved to... * explow.cc: ...here. * expmed.c: Moved to... * expmed.cc: ...here. * expr.c: Moved to... * expr.cc: ...here. * fibonacci_heap.c: Moved to... * fibonacci_heap.cc: ...here. * file-find.c: Moved to... * file-find.cc: ...here. * file-prefix-map.c: Moved to... * file-prefix-map.cc: ...here. * final.c: Moved to... * final.cc: ...here. * fixed-value.c: Moved to... * fixed-value.cc: ...here. * fold-const-call.c: Moved to... * fold-const-call.cc: ...here. * fold-const.c: Moved to... * fold-const.cc: ...here. * fp-test.c: Moved to... * fp-test.cc: ...here. * function-tests.c: Moved to... * function-tests.cc: ...here. * function.c: Moved to... * function.cc: ...here. * fwprop.c: Moved to... * fwprop.cc: ...here. * gcc-ar.c: Moved to... * gcc-ar.cc: ...here. * gcc-main.c: Moved to... * gcc-main.cc: ...here. * gcc-rich-location.c: Moved to... * gcc-rich-location.cc: ...here. * gcc.c: Moved to... * gcc.cc: ...here. * gcov-dump.c: Moved to... * gcov-dump.cc: ...here. * gcov-io.c: Moved to... * gcov-io.cc: ...here. * gcov-tool.c: Moved to... * gcov-tool.cc: ...here. * gcov.c: Moved to... * gcov.cc: ...here. * gcse-common.c: Moved to... * gcse-common.cc: ...here. * gcse.c: Moved to... * gcse.cc: ...here. * genattr-common.c: Moved to... * genattr-common.cc: ...here. * genattr.c: Moved to... * genattr.cc: ...here. * genattrtab.c: Moved to... * genattrtab.cc: ...here. * genautomata.c: Moved to... * genautomata.cc: ...here. * gencfn-macros.c: Moved to... * gencfn-macros.cc: ...here. * gencheck.c: Moved to... * gencheck.cc: ...here. * genchecksum.c: Moved to... * genchecksum.cc: ...here. * gencodes.c: Moved to... * gencodes.cc: ...here. * genconditions.c: Moved to... * genconditions.cc: ...here. * genconfig.c: Moved to... * genconfig.cc: ...here. * genconstants.c: Moved to... * genconstants.cc: ...here. * genemit.c: Moved to... * genemit.cc: ...here. * genenums.c: Moved to... * genenums.cc: ...here. * generic-match-head.c: Moved to... * generic-match-head.cc: ...here. * genextract.c: Moved to... * genextract.cc: ...here. * genflags.c: Moved to... * genflags.cc: ...here. * gengenrtl.c: Moved to... * gengenrtl.cc: ...here. * gengtype-parse.c: Moved to... * gengtype-parse.cc: ...here. * gengtype-state.c: Moved to... * gengtype-state.cc: ...here. * gengtype.c: Moved to... * gengtype.cc: ...here. * genhooks.c: Moved to... * genhooks.cc: ...here. * genmatch.c: Moved to... * genmatch.cc: ...here. * genmddeps.c: Moved to... * genmddeps.cc: ...here. * genmddump.c: Moved to... * genmddump.cc: ...here. * genmodes.c: Moved to... * genmodes.cc: ...here. * genopinit.c: Moved to... * genopinit.cc: ...here. * genoutput.c: Moved to... * genoutput.cc: ...here. * genpeep.c: Moved to... * genpeep.cc: ...here. * genpreds.c: Moved to... * genpreds.cc: ...here. * genrecog.c: Moved to... * genrecog.cc: ...here. * gensupport.c: Moved to... * gensupport.cc: ...here. * gentarget-def.c: Moved to... * gentarget-def.cc: ...here. * genversion.c: Moved to... * genversion.cc: ...here. * ggc-common.c: Moved to... * ggc-common.cc: ...here. * ggc-none.c: Moved to... * ggc-none.cc: ...here. * ggc-page.c: Moved to... * ggc-page.cc: ...here. * ggc-tests.c: Moved to... * ggc-tests.cc: ...here. * gimple-builder.c: Moved to... * gimple-builder.cc: ...here. * gimple-expr.c: Moved to... * gimple-expr.cc: ...here. * gimple-fold.c: Moved to... * gimple-fold.cc: ...here. * gimple-iterator.c: Moved to... * gimple-iterator.cc: ...here. * gimple-laddress.c: Moved to... * gimple-laddress.cc: ...here. * gimple-loop-jam.c: Moved to... * gimple-loop-jam.cc: ...here. * gimple-low.c: Moved to... * gimple-low.cc: ...here. * gimple-match-head.c: Moved to... * gimple-match-head.cc: ...here. * gimple-pretty-print.c: Moved to... * gimple-pretty-print.cc: ...here. * gimple-ssa-backprop.c: Moved to... * gimple-ssa-backprop.cc: ...here. * gimple-ssa-evrp-analyze.c: Moved to... * gimple-ssa-evrp-analyze.cc: ...here. * gimple-ssa-evrp.c: Moved to... * gimple-ssa-evrp.cc: ...here. * gimple-ssa-isolate-paths.c: Moved to... * gimple-ssa-isolate-paths.cc: ...here. * gimple-ssa-nonnull-compare.c: Moved to... * gimple-ssa-nonnull-compare.cc: ...here. * gimple-ssa-split-paths.c: Moved to... * gimple-ssa-split-paths.cc: ...here. * gimple-ssa-sprintf.c: Moved to... * gimple-ssa-sprintf.cc: ...here. * gimple-ssa-store-merging.c: Moved to... * gimple-ssa-store-merging.cc: ...here. * gimple-ssa-strength-reduction.c: Moved to... * gimple-ssa-strength-reduction.cc: ...here. * gimple-ssa-warn-alloca.c: Moved to... * gimple-ssa-warn-alloca.cc: ...here. * gimple-ssa-warn-restrict.c: Moved to... * gimple-ssa-warn-restrict.cc: ...here. * gimple-streamer-in.c: Moved to... * gimple-streamer-in.cc: ...here. * gimple-streamer-out.c: Moved to... * gimple-streamer-out.cc: ...here. * gimple-walk.c: Moved to... * gimple-walk.cc: ...here. * gimple-warn-recursion.c: Moved to... * gimple-warn-recursion.cc: ...here. * gimple.c: Moved to... * gimple.cc: ...here. * gimplify-me.c: Moved to... * gimplify-me.cc: ...here. * gimplify.c: Moved to... * gimplify.cc: ...here. * godump.c: Moved to... * godump.cc: ...here. * graph.c: Moved to... * graph.cc: ...here. * graphds.c: Moved to... * graphds.cc: ...here. * graphite-dependences.c: Moved to... * graphite-dependences.cc: ...here. * graphite-isl-ast-to-gimple.c: Moved to... * graphite-isl-ast-to-gimple.cc: ...here. * graphite-optimize-isl.c: Moved to... * graphite-optimize-isl.cc: ...here. * graphite-poly.c: Moved to... * graphite-poly.cc: ...here. * graphite-scop-detection.c: Moved to... * graphite-scop-detection.cc: ...here. * graphite-sese-to-poly.c: Moved to... * graphite-sese-to-poly.cc: ...here. * graphite.c: Moved to... * graphite.cc: ...here. * haifa-sched.c: Moved to... * haifa-sched.cc: ...here. * hash-map-tests.c: Moved to... * hash-map-tests.cc: ...here. * hash-set-tests.c: Moved to... * hash-set-tests.cc: ...here. * hash-table.c: Moved to... * hash-table.cc: ...here. * hooks.c: Moved to... * hooks.cc: ...here. * host-default.c: Moved to... * host-default.cc: ...here. * hw-doloop.c: Moved to... * hw-doloop.cc: ...here. * hwint.c: Moved to... * hwint.cc: ...here. * ifcvt.c: Moved to... * ifcvt.cc: ...here. * inchash.c: Moved to... * inchash.cc: ...here. * incpath.c: Moved to... * incpath.cc: ...here. * init-regs.c: Moved to... * init-regs.cc: ...here. * input.c: Moved to... * input.cc: ...here. * internal-fn.c: Moved to... * internal-fn.cc: ...here. * intl.c: Moved to... * intl.cc: ...here. * ipa-comdats.c: Moved to... * ipa-comdats.cc: ...here. * ipa-cp.c: Moved to... * ipa-cp.cc: ...here. * ipa-devirt.c: Moved to... * ipa-devirt.cc: ...here. * ipa-fnsummary.c: Moved to... * ipa-fnsummary.cc: ...here. * ipa-icf-gimple.c: Moved to... * ipa-icf-gimple.cc: ...here. * ipa-icf.c: Moved to... * ipa-icf.cc: ...here. * ipa-inline-analysis.c: Moved to... * ipa-inline-analysis.cc: ...here. * ipa-inline-transform.c: Moved to... * ipa-inline-transform.cc: ...here. * ipa-inline.c: Moved to... * ipa-inline.cc: ...here. * ipa-modref-tree.c: Moved to... * ipa-modref-tree.cc: ...here. * ipa-modref.c: Moved to... * ipa-modref.cc: ...here. * ipa-param-manipulation.c: Moved to... * ipa-param-manipulation.cc: ...here. * ipa-polymorphic-call.c: Moved to... * ipa-polymorphic-call.cc: ...here. * ipa-predicate.c: Moved to... * ipa-predicate.cc: ...here. * ipa-profile.c: Moved to... * ipa-profile.cc: ...here. * ipa-prop.c: Moved to... * ipa-prop.cc: ...here. * ipa-pure-const.c: Moved to... * ipa-pure-const.cc: ...here. * ipa-ref.c: Moved to... * ipa-ref.cc: ...here. * ipa-reference.c: Moved to... * ipa-reference.cc: ...here. * ipa-split.c: Moved to... * ipa-split.cc: ...here. * ipa-sra.c: Moved to... * ipa-sra.cc: ...here. * ipa-utils.c: Moved to... * ipa-utils.cc: ...here. * ipa-visibility.c: Moved to... * ipa-visibility.cc: ...here. * ipa.c: Moved to... * ipa.cc: ...here. * ira-build.c: Moved to... * ira-build.cc: ...here. * ira-color.c: Moved to... * ira-color.cc: ...here. * ira-conflicts.c: Moved to... * ira-conflicts.cc: ...here. * ira-costs.c: Moved to... * ira-costs.cc: ...here. * ira-emit.c: Moved to... * ira-emit.cc: ...here. * ira-lives.c: Moved to... * ira-lives.cc: ...here. * ira.c: Moved to... * ira.cc: ...here. * jump.c: Moved to... * jump.cc: ...here. * langhooks.c: Moved to... * langhooks.cc: ...here. * lcm.c: Moved to... * lcm.cc: ...here. * lists.c: Moved to... * lists.cc: ...here. * loop-doloop.c: Moved to... * loop-doloop.cc: ...here. * loop-init.c: Moved to... * loop-init.cc: ...here. * loop-invariant.c: Moved to... * loop-invariant.cc: ...here. * loop-iv.c: Moved to... * loop-iv.cc: ...here. * loop-unroll.c: Moved to... * loop-unroll.cc: ...here. * lower-subreg.c: Moved to... * lower-subreg.cc: ...here. * lra-assigns.c: Moved to... * lra-assigns.cc: ...here. * lra-coalesce.c: Moved to... * lra-coalesce.cc: ...here. * lra-constraints.c: Moved to... * lra-constraints.cc: ...here. * lra-eliminations.c: Moved to... * lra-eliminations.cc: ...here. * lra-lives.c: Moved to... * lra-lives.cc: ...here. * lra-remat.c: Moved to... * lra-remat.cc: ...here. * lra-spills.c: Moved to... * lra-spills.cc: ...here. * lra.c: Moved to... * lra.cc: ...here. * lto-cgraph.c: Moved to... * lto-cgraph.cc: ...here. * lto-compress.c: Moved to... * lto-compress.cc: ...here. * lto-opts.c: Moved to... * lto-opts.cc: ...here. * lto-section-in.c: Moved to... * lto-section-in.cc: ...here. * lto-section-out.c: Moved to... * lto-section-out.cc: ...here. * lto-streamer-in.c: Moved to... * lto-streamer-in.cc: ...here. * lto-streamer-out.c: Moved to... * lto-streamer-out.cc: ...here. * lto-streamer.c: Moved to... * lto-streamer.cc: ...here. * lto-wrapper.c: Moved to... * lto-wrapper.cc: ...here. * main.c: Moved to... * main.cc: ...here. * mcf.c: Moved to... * mcf.cc: ...here. * mode-switching.c: Moved to... * mode-switching.cc: ...here. * modulo-sched.c: Moved to... * modulo-sched.cc: ...here. * multiple_target.c: Moved to... * multiple_target.cc: ...here. * omp-expand.c: Moved to... * omp-expand.cc: ...here. * omp-general.c: Moved to... * omp-general.cc: ...here. * omp-low.c: Moved to... * omp-low.cc: ...here. * omp-offload.c: Moved to... * omp-offload.cc: ...here. * omp-simd-clone.c: Moved to... * omp-simd-clone.cc: ...here. * opt-suggestions.c: Moved to... * opt-suggestions.cc: ...here. * optabs-libfuncs.c: Moved to... * optabs-libfuncs.cc: ...here. * optabs-query.c: Moved to... * optabs-query.cc: ...here. * optabs-tree.c: Moved to... * optabs-tree.cc: ...here. * optabs.c: Moved to... * optabs.cc: ...here. * opts-common.c: Moved to... * opts-common.cc: ...here. * opts-global.c: Moved to... * opts-global.cc: ...here. * opts.c: Moved to... * opts.cc: ...here. * passes.c: Moved to... * passes.cc: ...here. * plugin.c: Moved to... * plugin.cc: ...here. * postreload-gcse.c: Moved to... * postreload-gcse.cc: ...here. * postreload.c: Moved to... * postreload.cc: ...here. * predict.c: Moved to... * predict.cc: ...here. * prefix.c: Moved to... * prefix.cc: ...here. * pretty-print.c: Moved to... * pretty-print.cc: ...here. * print-rtl-function.c: Moved to... * print-rtl-function.cc: ...here. * print-rtl.c: Moved to... * print-rtl.cc: ...here. * print-tree.c: Moved to... * print-tree.cc: ...here. * profile-count.c: Moved to... * profile-count.cc: ...here. * profile.c: Moved to... * profile.cc: ...here. * read-md.c: Moved to... * read-md.cc: ...here. * read-rtl-function.c: Moved to... * read-rtl-function.cc: ...here. * read-rtl.c: Moved to... * read-rtl.cc: ...here. * real.c: Moved to... * real.cc: ...here. * realmpfr.c: Moved to... * realmpfr.cc: ...here. * recog.c: Moved to... * recog.cc: ...here. * ree.c: Moved to... * ree.cc: ...here. * reg-stack.c: Moved to... * reg-stack.cc: ...here. * regcprop.c: Moved to... * regcprop.cc: ...here. * reginfo.c: Moved to... * reginfo.cc: ...here. * regrename.c: Moved to... * regrename.cc: ...here. * regstat.c: Moved to... * regstat.cc: ...here. * reload.c: Moved to... * reload.cc: ...here. * reload1.c: Moved to... * reload1.cc: ...here. * reorg.c: Moved to... * reorg.cc: ...here. * resource.c: Moved to... * resource.cc: ...here. * rtl-error.c: Moved to... * rtl-error.cc: ...here. * rtl-tests.c: Moved to... * rtl-tests.cc: ...here. * rtl.c: Moved to... * rtl.cc: ...here. * rtlanal.c: Moved to... * rtlanal.cc: ...here. * rtlhash.c: Moved to... * rtlhash.cc: ...here. * rtlhooks.c: Moved to... * rtlhooks.cc: ...here. * rtx-vector-builder.c: Moved to... * rtx-vector-builder.cc: ...here. * run-rtl-passes.c: Moved to... * run-rtl-passes.cc: ...here. * sancov.c: Moved to... * sancov.cc: ...here. * sanopt.c: Moved to... * sanopt.cc: ...here. * sbitmap.c: Moved to... * sbitmap.cc: ...here. * sched-deps.c: Moved to... * sched-deps.cc: ...here. * sched-ebb.c: Moved to... * sched-ebb.cc: ...here. * sched-rgn.c: Moved to... * sched-rgn.cc: ...here. * sel-sched-dump.c: Moved to... * sel-sched-dump.cc: ...here. * sel-sched-ir.c: Moved to... * sel-sched-ir.cc: ...here. * sel-sched.c: Moved to... * sel-sched.cc: ...here. * selftest-diagnostic.c: Moved to... * selftest-diagnostic.cc: ...here. * selftest-rtl.c: Moved to... * selftest-rtl.cc: ...here. * selftest-run-tests.c: Moved to... * selftest-run-tests.cc: ...here. * selftest.c: Moved to... * selftest.cc: ...here. * sese.c: Moved to... * sese.cc: ...here. * shrink-wrap.c: Moved to... * shrink-wrap.cc: ...here. * simplify-rtx.c: Moved to... * simplify-rtx.cc: ...here. * sparseset.c: Moved to... * sparseset.cc: ...here. * spellcheck-tree.c: Moved to... * spellcheck-tree.cc: ...here. * spellcheck.c: Moved to... * spellcheck.cc: ...here. * sreal.c: Moved to... * sreal.cc: ...here. * stack-ptr-mod.c: Moved to... * stack-ptr-mod.cc: ...here. * statistics.c: Moved to... * statistics.cc: ...here. * stmt.c: Moved to... * stmt.cc: ...here. * stor-layout.c: Moved to... * stor-layout.cc: ...here. * store-motion.c: Moved to... * store-motion.cc: ...here. * streamer-hooks.c: Moved to... * streamer-hooks.cc: ...here. * stringpool.c: Moved to... * stringpool.cc: ...here. * substring-locations.c: Moved to... * substring-locations.cc: ...here. * symtab.c: Moved to... * symtab.cc: ...here. * target-globals.c: Moved to... * target-globals.cc: ...here. * targhooks.c: Moved to... * targhooks.cc: ...here. * timevar.c: Moved to... * timevar.cc: ...here. * toplev.c: Moved to... * toplev.cc: ...here. * tracer.c: Moved to... * tracer.cc: ...here. * trans-mem.c: Moved to... * trans-mem.cc: ...here. * tree-affine.c: Moved to... * tree-affine.cc: ...here. * tree-call-cdce.c: Moved to... * tree-call-cdce.cc: ...here. * tree-cfg.c: Moved to... * tree-cfg.cc: ...here. * tree-cfgcleanup.c: Moved to... * tree-cfgcleanup.cc: ...here. * tree-chrec.c: Moved to... * tree-chrec.cc: ...here. * tree-complex.c: Moved to... * tree-complex.cc: ...here. * tree-data-ref.c: Moved to... * tree-data-ref.cc: ...here. * tree-dfa.c: Moved to... * tree-dfa.cc: ...here. * tree-diagnostic.c: Moved to... * tree-diagnostic.cc: ...here. * tree-dump.c: Moved to... * tree-dump.cc: ...here. * tree-eh.c: Moved to... * tree-eh.cc: ...here. * tree-emutls.c: Moved to... * tree-emutls.cc: ...here. * tree-if-conv.c: Moved to... * tree-if-conv.cc: ...here. * tree-inline.c: Moved to... * tree-inline.cc: ...here. * tree-into-ssa.c: Moved to... * tree-into-ssa.cc: ...here. * tree-iterator.c: Moved to... * tree-iterator.cc: ...here. * tree-loop-distribution.c: Moved to... * tree-loop-distribution.cc: ...here. * tree-nested.c: Moved to... * tree-nested.cc: ...here. * tree-nrv.c: Moved to... * tree-nrv.cc: ...here. * tree-object-size.c: Moved to... * tree-object-size.cc: ...here. * tree-outof-ssa.c: Moved to... * tree-outof-ssa.cc: ...here. * tree-parloops.c: Moved to... * tree-parloops.cc: ...here. * tree-phinodes.c: Moved to... * tree-phinodes.cc: ...here. * tree-predcom.c: Moved to... * tree-predcom.cc: ...here. * tree-pretty-print.c: Moved to... * tree-pretty-print.cc: ...here. * tree-profile.c: Moved to... * tree-profile.cc: ...here. * tree-scalar-evolution.c: Moved to... * tree-scalar-evolution.cc: ...here. * tree-sra.c: Moved to... * tree-sra.cc: ...here. * tree-ssa-address.c: Moved to... * tree-ssa-address.cc: ...here. * tree-ssa-alias.c: Moved to... * tree-ssa-alias.cc: ...here. * tree-ssa-ccp.c: Moved to... * tree-ssa-ccp.cc: ...here. * tree-ssa-coalesce.c: Moved to... * tree-ssa-coalesce.cc: ...here. * tree-ssa-copy.c: Moved to... * tree-ssa-copy.cc: ...here. * tree-ssa-dce.c: Moved to... * tree-ssa-dce.cc: ...here. * tree-ssa-dom.c: Moved to... * tree-ssa-dom.cc: ...here. * tree-ssa-dse.c: Moved to... * tree-ssa-dse.cc: ...here. * tree-ssa-forwprop.c: Moved to... * tree-ssa-forwprop.cc: ...here. * tree-ssa-ifcombine.c: Moved to... * tree-ssa-ifcombine.cc: ...here. * tree-ssa-live.c: Moved to... * tree-ssa-live.cc: ...here. * tree-ssa-loop-ch.c: Moved to... * tree-ssa-loop-ch.cc: ...here. * tree-ssa-loop-im.c: Moved to... * tree-ssa-loop-im.cc: ...here. * tree-ssa-loop-ivcanon.c: Moved to... * tree-ssa-loop-ivcanon.cc: ...here. * tree-ssa-loop-ivopts.c: Moved to... * tree-ssa-loop-ivopts.cc: ...here. * tree-ssa-loop-manip.c: Moved to... * tree-ssa-loop-manip.cc: ...here. * tree-ssa-loop-niter.c: Moved to... * tree-ssa-loop-niter.cc: ...here. * tree-ssa-loop-prefetch.c: Moved to... * tree-ssa-loop-prefetch.cc: ...here. * tree-ssa-loop-split.c: Moved to... * tree-ssa-loop-split.cc: ...here. * tree-ssa-loop-unswitch.c: Moved to... * tree-ssa-loop-unswitch.cc: ...here. * tree-ssa-loop.c: Moved to... * tree-ssa-loop.cc: ...here. * tree-ssa-math-opts.c: Moved to... * tree-ssa-math-opts.cc: ...here. * tree-ssa-operands.c: Moved to... * tree-ssa-operands.cc: ...here. * tree-ssa-phiopt.c: Moved to... * tree-ssa-phiopt.cc: ...here. * tree-ssa-phiprop.c: Moved to... * tree-ssa-phiprop.cc: ...here. * tree-ssa-pre.c: Moved to... * tree-ssa-pre.cc: ...here. * tree-ssa-propagate.c: Moved to... * tree-ssa-propagate.cc: ...here. * tree-ssa-reassoc.c: Moved to... * tree-ssa-reassoc.cc: ...here. * tree-ssa-sccvn.c: Moved to... * tree-ssa-sccvn.cc: ...here. * tree-ssa-scopedtables.c: Moved to... * tree-ssa-scopedtables.cc: ...here. * tree-ssa-sink.c: Moved to... * tree-ssa-sink.cc: ...here. * tree-ssa-strlen.c: Moved to... * tree-ssa-strlen.cc: ...here. * tree-ssa-structalias.c: Moved to... * tree-ssa-structalias.cc: ...here. * tree-ssa-tail-merge.c: Moved to... * tree-ssa-tail-merge.cc: ...here. * tree-ssa-ter.c: Moved to... * tree-ssa-ter.cc: ...here. * tree-ssa-threadbackward.c: Moved to... * tree-ssa-threadbackward.cc: ...here. * tree-ssa-threadedge.c: Moved to... * tree-ssa-threadedge.cc: ...here. * tree-ssa-threadupdate.c: Moved to... * tree-ssa-threadupdate.cc: ...here. * tree-ssa-uncprop.c: Moved to... * tree-ssa-uncprop.cc: ...here. * tree-ssa-uninit.c: Moved to... * tree-ssa-uninit.cc: ...here. * tree-ssa.c: Moved to... * tree-ssa.cc: ...here. * tree-ssanames.c: Moved to... * tree-ssanames.cc: ...here. * tree-stdarg.c: Moved to... * tree-stdarg.cc: ...here. * tree-streamer-in.c: Moved to... * tree-streamer-in.cc: ...here. * tree-streamer-out.c: Moved to... * tree-streamer-out.cc: ...here. * tree-streamer.c: Moved to... * tree-streamer.cc: ...here. * tree-switch-conversion.c: Moved to... * tree-switch-conversion.cc: ...here. * tree-tailcall.c: Moved to... * tree-tailcall.cc: ...here. * tree-vect-data-refs.c: Moved to... * tree-vect-data-refs.cc: ...here. * tree-vect-generic.c: Moved to... * tree-vect-generic.cc: ...here. * tree-vect-loop-manip.c: Moved to... * tree-vect-loop-manip.cc: ...here. * tree-vect-loop.c: Moved to... * tree-vect-loop.cc: ...here. * tree-vect-patterns.c: Moved to... * tree-vect-patterns.cc: ...here. * tree-vect-slp-patterns.c: Moved to... * tree-vect-slp-patterns.cc: ...here. * tree-vect-slp.c: Moved to... * tree-vect-slp.cc: ...here. * tree-vect-stmts.c: Moved to... * tree-vect-stmts.cc: ...here. * tree-vector-builder.c: Moved to... * tree-vector-builder.cc: ...here. * tree-vectorizer.c: Moved to... * tree-vectorizer.cc: ...here. * tree-vrp.c: Moved to... * tree-vrp.cc: ...here. * tree.c: Moved to... * tree.cc: ...here. * tsan.c: Moved to... * tsan.cc: ...here. * typed-splay-tree.c: Moved to... * typed-splay-tree.cc: ...here. * ubsan.c: Moved to... * ubsan.cc: ...here. * valtrack.c: Moved to... * valtrack.cc: ...here. * value-prof.c: Moved to... * value-prof.cc: ...here. * var-tracking.c: Moved to... * var-tracking.cc: ...here. * varasm.c: Moved to... * varasm.cc: ...here. * varpool.c: Moved to... * varpool.cc: ...here. * vec-perm-indices.c: Moved to... * vec-perm-indices.cc: ...here. * vec.c: Moved to... * vec.cc: ...here. * vmsdbgout.c: Moved to... * vmsdbgout.cc: ...here. * vr-values.c: Moved to... * vr-values.cc: ...here. * vtable-verify.c: Moved to... * vtable-verify.cc: ...here. * web.c: Moved to... * web.cc: ...here. * xcoffout.c: Moved to... * xcoffout.cc: ...here. gcc/c-family/ChangeLog: * c-ada-spec.c: Moved to... * c-ada-spec.cc: ...here. * c-attribs.c: Moved to... * c-attribs.cc: ...here. * c-common.c: Moved to... * c-common.cc: ...here. * c-cppbuiltin.c: Moved to... * c-cppbuiltin.cc: ...here. * c-dump.c: Moved to... * c-dump.cc: ...here. * c-format.c: Moved to... * c-format.cc: ...here. * c-gimplify.c: Moved to... * c-gimplify.cc: ...here. * c-indentation.c: Moved to... * c-indentation.cc: ...here. * c-lex.c: Moved to... * c-lex.cc: ...here. * c-omp.c: Moved to... * c-omp.cc: ...here. * c-opts.c: Moved to... * c-opts.cc: ...here. * c-pch.c: Moved to... * c-pch.cc: ...here. * c-ppoutput.c: Moved to... * c-ppoutput.cc: ...here. * c-pragma.c: Moved to... * c-pragma.cc: ...here. * c-pretty-print.c: Moved to... * c-pretty-print.cc: ...here. * c-semantics.c: Moved to... * c-semantics.cc: ...here. * c-ubsan.c: Moved to... * c-ubsan.cc: ...here. * c-warn.c: Moved to... * c-warn.cc: ...here. * cppspec.c: Moved to... * cppspec.cc: ...here. * stub-objc.c: Moved to... * stub-objc.cc: ...here. gcc/c/ChangeLog: * c-aux-info.c: Moved to... * c-aux-info.cc: ...here. * c-convert.c: Moved to... * c-convert.cc: ...here. * c-decl.c: Moved to... * c-decl.cc: ...here. * c-errors.c: Moved to... * c-errors.cc: ...here. * c-fold.c: Moved to... * c-fold.cc: ...here. * c-lang.c: Moved to... * c-lang.cc: ...here. * c-objc-common.c: Moved to... * c-objc-common.cc: ...here. * c-parser.c: Moved to... * c-parser.cc: ...here. * c-typeck.c: Moved to... * c-typeck.cc: ...here. * gccspec.c: Moved to... * gccspec.cc: ...here. * gimple-parser.c: Moved to... * gimple-parser.cc: ...here. gcc/cp/ChangeLog: * call.c: Moved to... * call.cc: ...here. * class.c: Moved to... * class.cc: ...here. * constexpr.c: Moved to... * constexpr.cc: ...here. * cp-gimplify.c: Moved to... * cp-gimplify.cc: ...here. * cp-lang.c: Moved to... * cp-lang.cc: ...here. * cp-objcp-common.c: Moved to... * cp-objcp-common.cc: ...here. * cp-ubsan.c: Moved to... * cp-ubsan.cc: ...here. * cvt.c: Moved to... * cvt.cc: ...here. * cxx-pretty-print.c: Moved to... * cxx-pretty-print.cc: ...here. * decl.c: Moved to... * decl.cc: ...here. * decl2.c: Moved to... * decl2.cc: ...here. * dump.c: Moved to... * dump.cc: ...here. * error.c: Moved to... * error.cc: ...here. * except.c: Moved to... * except.cc: ...here. * expr.c: Moved to... * expr.cc: ...here. * friend.c: Moved to... * friend.cc: ...here. * g++spec.c: Moved to... * g++spec.cc: ...here. * init.c: Moved to... * init.cc: ...here. * lambda.c: Moved to... * lambda.cc: ...here. * lex.c: Moved to... * lex.cc: ...here. * mangle.c: Moved to... * mangle.cc: ...here. * method.c: Moved to... * method.cc: ...here. * name-lookup.c: Moved to... * name-lookup.cc: ...here. * optimize.c: Moved to... * optimize.cc: ...here. * parser.c: Moved to... * parser.cc: ...here. * pt.c: Moved to... * pt.cc: ...here. * ptree.c: Moved to... * ptree.cc: ...here. * rtti.c: Moved to... * rtti.cc: ...here. * search.c: Moved to... * search.cc: ...here. * semantics.c: Moved to... * semantics.cc: ...here. * tree.c: Moved to... * tree.cc: ...here. * typeck.c: Moved to... * typeck.cc: ...here. * typeck2.c: Moved to... * typeck2.cc: ...here. * vtable-class-hierarchy.c: Moved to... * vtable-class-hierarchy.cc: ...here. gcc/fortran/ChangeLog: * arith.c: Moved to... * arith.cc: ...here. * array.c: Moved to... * array.cc: ...here. * bbt.c: Moved to... * bbt.cc: ...here. * check.c: Moved to... * check.cc: ...here. * class.c: Moved to... * class.cc: ...here. * constructor.c: Moved to... * constructor.cc: ...here. * convert.c: Moved to... * convert.cc: ...here. * cpp.c: Moved to... * cpp.cc: ...here. * data.c: Moved to... * data.cc: ...here. * decl.c: Moved to... * decl.cc: ...here. * dependency.c: Moved to... * dependency.cc: ...here. * dump-parse-tree.c: Moved to... * dump-parse-tree.cc: ...here. * error.c: Moved to... * error.cc: ...here. * expr.c: Moved to... * expr.cc: ...here. * f95-lang.c: Moved to... * f95-lang.cc: ...here. * frontend-passes.c: Moved to... * frontend-passes.cc: ...here. * gfortranspec.c: Moved to... * gfortranspec.cc: ...here. * interface.c: Moved to... * interface.cc: ...here. * intrinsic.c: Moved to... * intrinsic.cc: ...here. * io.c: Moved to... * io.cc: ...here. * iresolve.c: Moved to... * iresolve.cc: ...here. * match.c: Moved to... * match.cc: ...here. * matchexp.c: Moved to... * matchexp.cc: ...here. * misc.c: Moved to... * misc.cc: ...here. * module.c: Moved to... * module.cc: ...here. * openmp.c: Moved to... * openmp.cc: ...here. * options.c: Moved to... * options.cc: ...here. * parse.c: Moved to... * parse.cc: ...here. * primary.c: Moved to... * primary.cc: ...here. * resolve.c: Moved to... * resolve.cc: ...here. * scanner.c: Moved to... * scanner.cc: ...here. * simplify.c: Moved to... * simplify.cc: ...here. * st.c: Moved to... * st.cc: ...here. * symbol.c: Moved to... * symbol.cc: ...here. * target-memory.c: Moved to... * target-memory.cc: ...here. * trans-array.c: Moved to... * trans-array.cc: ...here. * trans-common.c: Moved to... * trans-common.cc: ...here. * trans-const.c: Moved to... * trans-const.cc: ...here. * trans-decl.c: Moved to... * trans-decl.cc: ...here. * trans-expr.c: Moved to... * trans-expr.cc: ...here. * trans-intrinsic.c: Moved to... * trans-intrinsic.cc: ...here. * trans-io.c: Moved to... * trans-io.cc: ...here. * trans-openmp.c: Moved to... * trans-openmp.cc: ...here. * trans-stmt.c: Moved to... * trans-stmt.cc: ...here. * trans-types.c: Moved to... * trans-types.cc: ...here. * trans.c: Moved to... * trans.cc: ...here. gcc/go/ChangeLog: * go-backend.c: Moved to... * go-backend.cc: ...here. * go-lang.c: Moved to... * go-lang.cc: ...here. * gospec.c: Moved to... * gospec.cc: ...here. gcc/jit/ChangeLog: * dummy-frontend.c: Moved to... * dummy-frontend.cc: ...here. * jit-builtins.c: Moved to... * jit-builtins.cc: ...here. * jit-logging.c: Moved to... * jit-logging.cc: ...here. * jit-playback.c: Moved to... * jit-playback.cc: ...here. * jit-recording.c: Moved to... * jit-recording.cc: ...here. * jit-result.c: Moved to... * jit-result.cc: ...here. * jit-spec.c: Moved to... * jit-spec.cc: ...here. * jit-tempdir.c: Moved to... * jit-tempdir.cc: ...here. * jit-w32.c: Moved to... * jit-w32.cc: ...here. * libgccjit.c: Moved to... * libgccjit.cc: ...here. gcc/lto/ChangeLog: * common.c: Moved to... * common.cc: ...here. * lto-common.c: Moved to... * lto-common.cc: ...here. * lto-dump.c: Moved to... * lto-dump.cc: ...here. * lto-lang.c: Moved to... * lto-lang.cc: ...here. * lto-object.c: Moved to... * lto-object.cc: ...here. * lto-partition.c: Moved to... * lto-partition.cc: ...here. * lto-symtab.c: Moved to... * lto-symtab.cc: ...here. * lto.c: Moved to... * lto.cc: ...here. gcc/objc/ChangeLog: * objc-act.c: Moved to... * objc-act.cc: ...here. * objc-encoding.c: Moved to... * objc-encoding.cc: ...here. * objc-gnu-runtime-abi-01.c: Moved to... * objc-gnu-runtime-abi-01.cc: ...here. * objc-lang.c: Moved to... * objc-lang.cc: ...here. * objc-map.c: Moved to... * objc-map.cc: ...here. * objc-next-runtime-abi-01.c: Moved to... * objc-next-runtime-abi-01.cc: ...here. * objc-next-runtime-abi-02.c: Moved to... * objc-next-runtime-abi-02.cc: ...here. * objc-runtime-shared-support.c: Moved to... * objc-runtime-shared-support.cc: ...here. gcc/objcp/ChangeLog: * objcp-decl.c: Moved to... * objcp-decl.cc: ...here. * objcp-lang.c: Moved to... * objcp-lang.cc: ...here. libcpp/ChangeLog: * charset.c: Moved to... * charset.cc: ...here. * directives.c: Moved to... * directives.cc: ...here. * errors.c: Moved to... * errors.cc: ...here. * expr.c: Moved to... * expr.cc: ...here. * files.c: Moved to... * files.cc: ...here. * identifiers.c: Moved to... * identifiers.cc: ...here. * init.c: Moved to... * init.cc: ...here. * lex.c: Moved to... * lex.cc: ...here. * line-map.c: Moved to... * line-map.cc: ...here. * macro.c: Moved to... * macro.cc: ...here. * makeucnid.c: Moved to... * makeucnid.cc: ...here. * mkdeps.c: Moved to... * mkdeps.cc: ...here. * pch.c: Moved to... * pch.cc: ...here. * symtab.c: Moved to... * symtab.cc: ...here. * traditional.c: Moved to... * traditional.cc: ...here.
Diffstat (limited to 'gcc/cp/error.cc')
-rw-r--r--gcc/cp/error.cc4659
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);
+}