diff options
author | Martin Liska <mliska@suse.cz> | 2022-01-14 16:56:44 +0100 |
---|---|---|
committer | Martin Liska <mliska@suse.cz> | 2022-01-17 22:12:04 +0100 |
commit | 5c69acb32329d49e58c26fa41ae74229a52b9106 (patch) | |
tree | ddb05f9d73afb6f998457d2ac4b720e3b3b60483 /gcc/cp/mangle.cc | |
parent | 490e23032baaece71f2ec09fa1805064b150fbc2 (diff) | |
download | gcc-5c69acb32329d49e58c26fa41ae74229a52b9106.zip gcc-5c69acb32329d49e58c26fa41ae74229a52b9106.tar.gz gcc-5c69acb32329d49e58c26fa41ae74229a52b9106.tar.bz2 |
Rename .c files to .cc files.
gcc/ada/ChangeLog:
* adadecode.c: Moved to...
* adadecode.cc: ...here.
* affinity.c: Moved to...
* affinity.cc: ...here.
* argv-lynxos178-raven-cert.c: Moved to...
* argv-lynxos178-raven-cert.cc: ...here.
* argv.c: Moved to...
* argv.cc: ...here.
* aux-io.c: Moved to...
* aux-io.cc: ...here.
* cio.c: Moved to...
* cio.cc: ...here.
* cstreams.c: Moved to...
* cstreams.cc: ...here.
* env.c: Moved to...
* env.cc: ...here.
* exit.c: Moved to...
* exit.cc: ...here.
* expect.c: Moved to...
* expect.cc: ...here.
* final.c: Moved to...
* final.cc: ...here.
* gcc-interface/cuintp.c: Moved to...
* gcc-interface/cuintp.cc: ...here.
* gcc-interface/decl.c: Moved to...
* gcc-interface/decl.cc: ...here.
* gcc-interface/misc.c: Moved to...
* gcc-interface/misc.cc: ...here.
* gcc-interface/targtyps.c: Moved to...
* gcc-interface/targtyps.cc: ...here.
* gcc-interface/trans.c: Moved to...
* gcc-interface/trans.cc: ...here.
* gcc-interface/utils.c: Moved to...
* gcc-interface/utils.cc: ...here.
* gcc-interface/utils2.c: Moved to...
* gcc-interface/utils2.cc: ...here.
* init.c: Moved to...
* init.cc: ...here.
* initialize.c: Moved to...
* initialize.cc: ...here.
* libgnarl/thread.c: Moved to...
* libgnarl/thread.cc: ...here.
* link.c: Moved to...
* link.cc: ...here.
* locales.c: Moved to...
* locales.cc: ...here.
* mkdir.c: Moved to...
* mkdir.cc: ...here.
* raise.c: Moved to...
* raise.cc: ...here.
* rtfinal.c: Moved to...
* rtfinal.cc: ...here.
* rtinit.c: Moved to...
* rtinit.cc: ...here.
* seh_init.c: Moved to...
* seh_init.cc: ...here.
* sigtramp-armdroid.c: Moved to...
* sigtramp-armdroid.cc: ...here.
* sigtramp-ios.c: Moved to...
* sigtramp-ios.cc: ...here.
* sigtramp-qnx.c: Moved to...
* sigtramp-qnx.cc: ...here.
* sigtramp-vxworks.c: Moved to...
* sigtramp-vxworks.cc: ...here.
* socket.c: Moved to...
* socket.cc: ...here.
* tracebak.c: Moved to...
* tracebak.cc: ...here.
* version.c: Moved to...
* version.cc: ...here.
* vx_stack_info.c: Moved to...
* vx_stack_info.cc: ...here.
gcc/ChangeLog:
* adjust-alignment.c: Moved to...
* adjust-alignment.cc: ...here.
* alias.c: Moved to...
* alias.cc: ...here.
* alloc-pool.c: Moved to...
* alloc-pool.cc: ...here.
* asan.c: Moved to...
* asan.cc: ...here.
* attribs.c: Moved to...
* attribs.cc: ...here.
* auto-inc-dec.c: Moved to...
* auto-inc-dec.cc: ...here.
* auto-profile.c: Moved to...
* auto-profile.cc: ...here.
* bb-reorder.c: Moved to...
* bb-reorder.cc: ...here.
* bitmap.c: Moved to...
* bitmap.cc: ...here.
* btfout.c: Moved to...
* btfout.cc: ...here.
* builtins.c: Moved to...
* builtins.cc: ...here.
* caller-save.c: Moved to...
* caller-save.cc: ...here.
* calls.c: Moved to...
* calls.cc: ...here.
* ccmp.c: Moved to...
* ccmp.cc: ...here.
* cfg.c: Moved to...
* cfg.cc: ...here.
* cfganal.c: Moved to...
* cfganal.cc: ...here.
* cfgbuild.c: Moved to...
* cfgbuild.cc: ...here.
* cfgcleanup.c: Moved to...
* cfgcleanup.cc: ...here.
* cfgexpand.c: Moved to...
* cfgexpand.cc: ...here.
* cfghooks.c: Moved to...
* cfghooks.cc: ...here.
* cfgloop.c: Moved to...
* cfgloop.cc: ...here.
* cfgloopanal.c: Moved to...
* cfgloopanal.cc: ...here.
* cfgloopmanip.c: Moved to...
* cfgloopmanip.cc: ...here.
* cfgrtl.c: Moved to...
* cfgrtl.cc: ...here.
* cgraph.c: Moved to...
* cgraph.cc: ...here.
* cgraphbuild.c: Moved to...
* cgraphbuild.cc: ...here.
* cgraphclones.c: Moved to...
* cgraphclones.cc: ...here.
* cgraphunit.c: Moved to...
* cgraphunit.cc: ...here.
* collect-utils.c: Moved to...
* collect-utils.cc: ...here.
* collect2-aix.c: Moved to...
* collect2-aix.cc: ...here.
* collect2.c: Moved to...
* collect2.cc: ...here.
* combine-stack-adj.c: Moved to...
* combine-stack-adj.cc: ...here.
* combine.c: Moved to...
* combine.cc: ...here.
* common/common-targhooks.c: Moved to...
* common/common-targhooks.cc: ...here.
* common/config/aarch64/aarch64-common.c: Moved to...
* common/config/aarch64/aarch64-common.cc: ...here.
* common/config/alpha/alpha-common.c: Moved to...
* common/config/alpha/alpha-common.cc: ...here.
* common/config/arc/arc-common.c: Moved to...
* common/config/arc/arc-common.cc: ...here.
* common/config/arm/arm-common.c: Moved to...
* common/config/arm/arm-common.cc: ...here.
* common/config/avr/avr-common.c: Moved to...
* common/config/avr/avr-common.cc: ...here.
* common/config/bfin/bfin-common.c: Moved to...
* common/config/bfin/bfin-common.cc: ...here.
* common/config/bpf/bpf-common.c: Moved to...
* common/config/bpf/bpf-common.cc: ...here.
* common/config/c6x/c6x-common.c: Moved to...
* common/config/c6x/c6x-common.cc: ...here.
* common/config/cr16/cr16-common.c: Moved to...
* common/config/cr16/cr16-common.cc: ...here.
* common/config/cris/cris-common.c: Moved to...
* common/config/cris/cris-common.cc: ...here.
* common/config/csky/csky-common.c: Moved to...
* common/config/csky/csky-common.cc: ...here.
* common/config/default-common.c: Moved to...
* common/config/default-common.cc: ...here.
* common/config/epiphany/epiphany-common.c: Moved to...
* common/config/epiphany/epiphany-common.cc: ...here.
* common/config/fr30/fr30-common.c: Moved to...
* common/config/fr30/fr30-common.cc: ...here.
* common/config/frv/frv-common.c: Moved to...
* common/config/frv/frv-common.cc: ...here.
* common/config/gcn/gcn-common.c: Moved to...
* common/config/gcn/gcn-common.cc: ...here.
* common/config/h8300/h8300-common.c: Moved to...
* common/config/h8300/h8300-common.cc: ...here.
* common/config/i386/i386-common.c: Moved to...
* common/config/i386/i386-common.cc: ...here.
* common/config/ia64/ia64-common.c: Moved to...
* common/config/ia64/ia64-common.cc: ...here.
* common/config/iq2000/iq2000-common.c: Moved to...
* common/config/iq2000/iq2000-common.cc: ...here.
* common/config/lm32/lm32-common.c: Moved to...
* common/config/lm32/lm32-common.cc: ...here.
* common/config/m32r/m32r-common.c: Moved to...
* common/config/m32r/m32r-common.cc: ...here.
* common/config/m68k/m68k-common.c: Moved to...
* common/config/m68k/m68k-common.cc: ...here.
* common/config/mcore/mcore-common.c: Moved to...
* common/config/mcore/mcore-common.cc: ...here.
* common/config/microblaze/microblaze-common.c: Moved to...
* common/config/microblaze/microblaze-common.cc: ...here.
* common/config/mips/mips-common.c: Moved to...
* common/config/mips/mips-common.cc: ...here.
* common/config/mmix/mmix-common.c: Moved to...
* common/config/mmix/mmix-common.cc: ...here.
* common/config/mn10300/mn10300-common.c: Moved to...
* common/config/mn10300/mn10300-common.cc: ...here.
* common/config/msp430/msp430-common.c: Moved to...
* common/config/msp430/msp430-common.cc: ...here.
* common/config/nds32/nds32-common.c: Moved to...
* common/config/nds32/nds32-common.cc: ...here.
* common/config/nios2/nios2-common.c: Moved to...
* common/config/nios2/nios2-common.cc: ...here.
* common/config/nvptx/nvptx-common.c: Moved to...
* common/config/nvptx/nvptx-common.cc: ...here.
* common/config/or1k/or1k-common.c: Moved to...
* common/config/or1k/or1k-common.cc: ...here.
* common/config/pa/pa-common.c: Moved to...
* common/config/pa/pa-common.cc: ...here.
* common/config/pdp11/pdp11-common.c: Moved to...
* common/config/pdp11/pdp11-common.cc: ...here.
* common/config/pru/pru-common.c: Moved to...
* common/config/pru/pru-common.cc: ...here.
* common/config/riscv/riscv-common.c: Moved to...
* common/config/riscv/riscv-common.cc: ...here.
* common/config/rs6000/rs6000-common.c: Moved to...
* common/config/rs6000/rs6000-common.cc: ...here.
* common/config/rx/rx-common.c: Moved to...
* common/config/rx/rx-common.cc: ...here.
* common/config/s390/s390-common.c: Moved to...
* common/config/s390/s390-common.cc: ...here.
* common/config/sh/sh-common.c: Moved to...
* common/config/sh/sh-common.cc: ...here.
* common/config/sparc/sparc-common.c: Moved to...
* common/config/sparc/sparc-common.cc: ...here.
* common/config/tilegx/tilegx-common.c: Moved to...
* common/config/tilegx/tilegx-common.cc: ...here.
* common/config/tilepro/tilepro-common.c: Moved to...
* common/config/tilepro/tilepro-common.cc: ...here.
* common/config/v850/v850-common.c: Moved to...
* common/config/v850/v850-common.cc: ...here.
* common/config/vax/vax-common.c: Moved to...
* common/config/vax/vax-common.cc: ...here.
* common/config/visium/visium-common.c: Moved to...
* common/config/visium/visium-common.cc: ...here.
* common/config/xstormy16/xstormy16-common.c: Moved to...
* common/config/xstormy16/xstormy16-common.cc: ...here.
* common/config/xtensa/xtensa-common.c: Moved to...
* common/config/xtensa/xtensa-common.cc: ...here.
* compare-elim.c: Moved to...
* compare-elim.cc: ...here.
* config/aarch64/aarch64-bti-insert.c: Moved to...
* config/aarch64/aarch64-bti-insert.cc: ...here.
* config/aarch64/aarch64-builtins.c: Moved to...
* config/aarch64/aarch64-builtins.cc: ...here.
* config/aarch64/aarch64-c.c: Moved to...
* config/aarch64/aarch64-c.cc: ...here.
* config/aarch64/aarch64-d.c: Moved to...
* config/aarch64/aarch64-d.cc: ...here.
* config/aarch64/aarch64.c: Moved to...
* config/aarch64/aarch64.cc: ...here.
* config/aarch64/cortex-a57-fma-steering.c: Moved to...
* config/aarch64/cortex-a57-fma-steering.cc: ...here.
* config/aarch64/driver-aarch64.c: Moved to...
* config/aarch64/driver-aarch64.cc: ...here.
* config/aarch64/falkor-tag-collision-avoidance.c: Moved to...
* config/aarch64/falkor-tag-collision-avoidance.cc: ...here.
* config/aarch64/host-aarch64-darwin.c: Moved to...
* config/aarch64/host-aarch64-darwin.cc: ...here.
* config/alpha/alpha.c: Moved to...
* config/alpha/alpha.cc: ...here.
* config/alpha/driver-alpha.c: Moved to...
* config/alpha/driver-alpha.cc: ...here.
* config/arc/arc-c.c: Moved to...
* config/arc/arc-c.cc: ...here.
* config/arc/arc.c: Moved to...
* config/arc/arc.cc: ...here.
* config/arc/driver-arc.c: Moved to...
* config/arc/driver-arc.cc: ...here.
* config/arm/aarch-common.c: Moved to...
* config/arm/aarch-common.cc: ...here.
* config/arm/arm-builtins.c: Moved to...
* config/arm/arm-builtins.cc: ...here.
* config/arm/arm-c.c: Moved to...
* config/arm/arm-c.cc: ...here.
* config/arm/arm-d.c: Moved to...
* config/arm/arm-d.cc: ...here.
* config/arm/arm.c: Moved to...
* config/arm/arm.cc: ...here.
* config/arm/driver-arm.c: Moved to...
* config/arm/driver-arm.cc: ...here.
* config/avr/avr-c.c: Moved to...
* config/avr/avr-c.cc: ...here.
* config/avr/avr-devices.c: Moved to...
* config/avr/avr-devices.cc: ...here.
* config/avr/avr-log.c: Moved to...
* config/avr/avr-log.cc: ...here.
* config/avr/avr.c: Moved to...
* config/avr/avr.cc: ...here.
* config/avr/driver-avr.c: Moved to...
* config/avr/driver-avr.cc: ...here.
* config/avr/gen-avr-mmcu-specs.c: Moved to...
* config/avr/gen-avr-mmcu-specs.cc: ...here.
* config/avr/gen-avr-mmcu-texi.c: Moved to...
* config/avr/gen-avr-mmcu-texi.cc: ...here.
* config/bfin/bfin.c: Moved to...
* config/bfin/bfin.cc: ...here.
* config/bpf/bpf.c: Moved to...
* config/bpf/bpf.cc: ...here.
* config/bpf/coreout.c: Moved to...
* config/bpf/coreout.cc: ...here.
* config/c6x/c6x.c: Moved to...
* config/c6x/c6x.cc: ...here.
* config/cr16/cr16.c: Moved to...
* config/cr16/cr16.cc: ...here.
* config/cris/cris.c: Moved to...
* config/cris/cris.cc: ...here.
* config/csky/csky.c: Moved to...
* config/csky/csky.cc: ...here.
* config/darwin-c.c: Moved to...
* config/darwin-c.cc: ...here.
* config/darwin-d.c: Moved to...
* config/darwin-d.cc: ...here.
* config/darwin-driver.c: Moved to...
* config/darwin-driver.cc: ...here.
* config/darwin-f.c: Moved to...
* config/darwin-f.cc: ...here.
* config/darwin.c: Moved to...
* config/darwin.cc: ...here.
* config/default-c.c: Moved to...
* config/default-c.cc: ...here.
* config/default-d.c: Moved to...
* config/default-d.cc: ...here.
* config/dragonfly-d.c: Moved to...
* config/dragonfly-d.cc: ...here.
* config/epiphany/epiphany.c: Moved to...
* config/epiphany/epiphany.cc: ...here.
* config/epiphany/mode-switch-use.c: Moved to...
* config/epiphany/mode-switch-use.cc: ...here.
* config/epiphany/resolve-sw-modes.c: Moved to...
* config/epiphany/resolve-sw-modes.cc: ...here.
* config/fr30/fr30.c: Moved to...
* config/fr30/fr30.cc: ...here.
* config/freebsd-d.c: Moved to...
* config/freebsd-d.cc: ...here.
* config/frv/frv.c: Moved to...
* config/frv/frv.cc: ...here.
* config/ft32/ft32.c: Moved to...
* config/ft32/ft32.cc: ...here.
* config/gcn/driver-gcn.c: Moved to...
* config/gcn/driver-gcn.cc: ...here.
* config/gcn/gcn-run.c: Moved to...
* config/gcn/gcn-run.cc: ...here.
* config/gcn/gcn-tree.c: Moved to...
* config/gcn/gcn-tree.cc: ...here.
* config/gcn/gcn.c: Moved to...
* config/gcn/gcn.cc: ...here.
* config/gcn/mkoffload.c: Moved to...
* config/gcn/mkoffload.cc: ...here.
* config/glibc-c.c: Moved to...
* config/glibc-c.cc: ...here.
* config/glibc-d.c: Moved to...
* config/glibc-d.cc: ...here.
* config/h8300/h8300.c: Moved to...
* config/h8300/h8300.cc: ...here.
* config/host-darwin.c: Moved to...
* config/host-darwin.cc: ...here.
* config/host-hpux.c: Moved to...
* config/host-hpux.cc: ...here.
* config/host-linux.c: Moved to...
* config/host-linux.cc: ...here.
* config/host-netbsd.c: Moved to...
* config/host-netbsd.cc: ...here.
* config/host-openbsd.c: Moved to...
* config/host-openbsd.cc: ...here.
* config/host-solaris.c: Moved to...
* config/host-solaris.cc: ...here.
* config/i386/djgpp.c: Moved to...
* config/i386/djgpp.cc: ...here.
* config/i386/driver-i386.c: Moved to...
* config/i386/driver-i386.cc: ...here.
* config/i386/driver-mingw32.c: Moved to...
* config/i386/driver-mingw32.cc: ...here.
* config/i386/gnu-property.c: Moved to...
* config/i386/gnu-property.cc: ...here.
* config/i386/host-cygwin.c: Moved to...
* config/i386/host-cygwin.cc: ...here.
* config/i386/host-i386-darwin.c: Moved to...
* config/i386/host-i386-darwin.cc: ...here.
* config/i386/host-mingw32.c: Moved to...
* config/i386/host-mingw32.cc: ...here.
* config/i386/i386-builtins.c: Moved to...
* config/i386/i386-builtins.cc: ...here.
* config/i386/i386-c.c: Moved to...
* config/i386/i386-c.cc: ...here.
* config/i386/i386-d.c: Moved to...
* config/i386/i386-d.cc: ...here.
* config/i386/i386-expand.c: Moved to...
* config/i386/i386-expand.cc: ...here.
* config/i386/i386-features.c: Moved to...
* config/i386/i386-features.cc: ...here.
* config/i386/i386-options.c: Moved to...
* config/i386/i386-options.cc: ...here.
* config/i386/i386.c: Moved to...
* config/i386/i386.cc: ...here.
* config/i386/intelmic-mkoffload.c: Moved to...
* config/i386/intelmic-mkoffload.cc: ...here.
* config/i386/msformat-c.c: Moved to...
* config/i386/msformat-c.cc: ...here.
* config/i386/winnt-cxx.c: Moved to...
* config/i386/winnt-cxx.cc: ...here.
* config/i386/winnt-d.c: Moved to...
* config/i386/winnt-d.cc: ...here.
* config/i386/winnt-stubs.c: Moved to...
* config/i386/winnt-stubs.cc: ...here.
* config/i386/winnt.c: Moved to...
* config/i386/winnt.cc: ...here.
* config/i386/x86-tune-sched-atom.c: Moved to...
* config/i386/x86-tune-sched-atom.cc: ...here.
* config/i386/x86-tune-sched-bd.c: Moved to...
* config/i386/x86-tune-sched-bd.cc: ...here.
* config/i386/x86-tune-sched-core.c: Moved to...
* config/i386/x86-tune-sched-core.cc: ...here.
* config/i386/x86-tune-sched.c: Moved to...
* config/i386/x86-tune-sched.cc: ...here.
* config/ia64/ia64-c.c: Moved to...
* config/ia64/ia64-c.cc: ...here.
* config/ia64/ia64.c: Moved to...
* config/ia64/ia64.cc: ...here.
* config/iq2000/iq2000.c: Moved to...
* config/iq2000/iq2000.cc: ...here.
* config/linux.c: Moved to...
* config/linux.cc: ...here.
* config/lm32/lm32.c: Moved to...
* config/lm32/lm32.cc: ...here.
* config/m32c/m32c-pragma.c: Moved to...
* config/m32c/m32c-pragma.cc: ...here.
* config/m32c/m32c.c: Moved to...
* config/m32c/m32c.cc: ...here.
* config/m32r/m32r.c: Moved to...
* config/m32r/m32r.cc: ...here.
* config/m68k/m68k.c: Moved to...
* config/m68k/m68k.cc: ...here.
* config/mcore/mcore.c: Moved to...
* config/mcore/mcore.cc: ...here.
* config/microblaze/microblaze-c.c: Moved to...
* config/microblaze/microblaze-c.cc: ...here.
* config/microblaze/microblaze.c: Moved to...
* config/microblaze/microblaze.cc: ...here.
* config/mips/driver-native.c: Moved to...
* config/mips/driver-native.cc: ...here.
* config/mips/frame-header-opt.c: Moved to...
* config/mips/frame-header-opt.cc: ...here.
* config/mips/mips-d.c: Moved to...
* config/mips/mips-d.cc: ...here.
* config/mips/mips.c: Moved to...
* config/mips/mips.cc: ...here.
* config/mmix/mmix.c: Moved to...
* config/mmix/mmix.cc: ...here.
* config/mn10300/mn10300.c: Moved to...
* config/mn10300/mn10300.cc: ...here.
* config/moxie/moxie.c: Moved to...
* config/moxie/moxie.cc: ...here.
* config/msp430/driver-msp430.c: Moved to...
* config/msp430/driver-msp430.cc: ...here.
* config/msp430/msp430-c.c: Moved to...
* config/msp430/msp430-c.cc: ...here.
* config/msp430/msp430-devices.c: Moved to...
* config/msp430/msp430-devices.cc: ...here.
* config/msp430/msp430.c: Moved to...
* config/msp430/msp430.cc: ...here.
* config/nds32/nds32-cost.c: Moved to...
* config/nds32/nds32-cost.cc: ...here.
* config/nds32/nds32-fp-as-gp.c: Moved to...
* config/nds32/nds32-fp-as-gp.cc: ...here.
* config/nds32/nds32-intrinsic.c: Moved to...
* config/nds32/nds32-intrinsic.cc: ...here.
* config/nds32/nds32-isr.c: Moved to...
* config/nds32/nds32-isr.cc: ...here.
* config/nds32/nds32-md-auxiliary.c: Moved to...
* config/nds32/nds32-md-auxiliary.cc: ...here.
* config/nds32/nds32-memory-manipulation.c: Moved to...
* config/nds32/nds32-memory-manipulation.cc: ...here.
* config/nds32/nds32-pipelines-auxiliary.c: Moved to...
* config/nds32/nds32-pipelines-auxiliary.cc: ...here.
* config/nds32/nds32-predicates.c: Moved to...
* config/nds32/nds32-predicates.cc: ...here.
* config/nds32/nds32-relax-opt.c: Moved to...
* config/nds32/nds32-relax-opt.cc: ...here.
* config/nds32/nds32-utils.c: Moved to...
* config/nds32/nds32-utils.cc: ...here.
* config/nds32/nds32.c: Moved to...
* config/nds32/nds32.cc: ...here.
* config/netbsd-d.c: Moved to...
* config/netbsd-d.cc: ...here.
* config/netbsd.c: Moved to...
* config/netbsd.cc: ...here.
* config/nios2/nios2.c: Moved to...
* config/nios2/nios2.cc: ...here.
* config/nvptx/mkoffload.c: Moved to...
* config/nvptx/mkoffload.cc: ...here.
* config/nvptx/nvptx-c.c: Moved to...
* config/nvptx/nvptx-c.cc: ...here.
* config/nvptx/nvptx.c: Moved to...
* config/nvptx/nvptx.cc: ...here.
* config/openbsd-d.c: Moved to...
* config/openbsd-d.cc: ...here.
* config/or1k/or1k.c: Moved to...
* config/or1k/or1k.cc: ...here.
* config/pa/pa-d.c: Moved to...
* config/pa/pa-d.cc: ...here.
* config/pa/pa.c: Moved to...
* config/pa/pa.cc: ...here.
* config/pdp11/pdp11.c: Moved to...
* config/pdp11/pdp11.cc: ...here.
* config/pru/pru-passes.c: Moved to...
* config/pru/pru-passes.cc: ...here.
* config/pru/pru-pragma.c: Moved to...
* config/pru/pru-pragma.cc: ...here.
* config/pru/pru.c: Moved to...
* config/pru/pru.cc: ...here.
* config/riscv/riscv-builtins.c: Moved to...
* config/riscv/riscv-builtins.cc: ...here.
* config/riscv/riscv-c.c: Moved to...
* config/riscv/riscv-c.cc: ...here.
* config/riscv/riscv-d.c: Moved to...
* config/riscv/riscv-d.cc: ...here.
* config/riscv/riscv-shorten-memrefs.c: Moved to...
* config/riscv/riscv-shorten-memrefs.cc: ...here.
* config/riscv/riscv-sr.c: Moved to...
* config/riscv/riscv-sr.cc: ...here.
* config/riscv/riscv.c: Moved to...
* config/riscv/riscv.cc: ...here.
* config/rl78/rl78-c.c: Moved to...
* config/rl78/rl78-c.cc: ...here.
* config/rl78/rl78.c: Moved to...
* config/rl78/rl78.cc: ...here.
* config/rs6000/driver-rs6000.c: Moved to...
* config/rs6000/driver-rs6000.cc: ...here.
* config/rs6000/host-darwin.c: Moved to...
* config/rs6000/host-darwin.cc: ...here.
* config/rs6000/host-ppc64-darwin.c: Moved to...
* config/rs6000/host-ppc64-darwin.cc: ...here.
* config/rs6000/rbtree.c: Moved to...
* config/rs6000/rbtree.cc: ...here.
* config/rs6000/rs6000-c.c: Moved to...
* config/rs6000/rs6000-c.cc: ...here.
* config/rs6000/rs6000-call.c: Moved to...
* config/rs6000/rs6000-call.cc: ...here.
* config/rs6000/rs6000-d.c: Moved to...
* config/rs6000/rs6000-d.cc: ...here.
* config/rs6000/rs6000-gen-builtins.c: Moved to...
* config/rs6000/rs6000-gen-builtins.cc: ...here.
* config/rs6000/rs6000-linux.c: Moved to...
* config/rs6000/rs6000-linux.cc: ...here.
* config/rs6000/rs6000-logue.c: Moved to...
* config/rs6000/rs6000-logue.cc: ...here.
* config/rs6000/rs6000-p8swap.c: Moved to...
* config/rs6000/rs6000-p8swap.cc: ...here.
* config/rs6000/rs6000-pcrel-opt.c: Moved to...
* config/rs6000/rs6000-pcrel-opt.cc: ...here.
* config/rs6000/rs6000-string.c: Moved to...
* config/rs6000/rs6000-string.cc: ...here.
* config/rs6000/rs6000.c: Moved to...
* config/rs6000/rs6000.cc: ...here.
* config/rx/rx.c: Moved to...
* config/rx/rx.cc: ...here.
* config/s390/driver-native.c: Moved to...
* config/s390/driver-native.cc: ...here.
* config/s390/s390-c.c: Moved to...
* config/s390/s390-c.cc: ...here.
* config/s390/s390-d.c: Moved to...
* config/s390/s390-d.cc: ...here.
* config/s390/s390.c: Moved to...
* config/s390/s390.cc: ...here.
* config/sh/divtab-sh4-300.c: Moved to...
* config/sh/divtab-sh4-300.cc: ...here.
* config/sh/divtab-sh4.c: Moved to...
* config/sh/divtab-sh4.cc: ...here.
* config/sh/divtab.c: Moved to...
* config/sh/divtab.cc: ...here.
* config/sh/sh-c.c: Moved to...
* config/sh/sh-c.cc: ...here.
* config/sh/sh.c: Moved to...
* config/sh/sh.cc: ...here.
* config/sol2-c.c: Moved to...
* config/sol2-c.cc: ...here.
* config/sol2-cxx.c: Moved to...
* config/sol2-cxx.cc: ...here.
* config/sol2-d.c: Moved to...
* config/sol2-d.cc: ...here.
* config/sol2-stubs.c: Moved to...
* config/sol2-stubs.cc: ...here.
* config/sol2.c: Moved to...
* config/sol2.cc: ...here.
* config/sparc/driver-sparc.c: Moved to...
* config/sparc/driver-sparc.cc: ...here.
* config/sparc/sparc-c.c: Moved to...
* config/sparc/sparc-c.cc: ...here.
* config/sparc/sparc-d.c: Moved to...
* config/sparc/sparc-d.cc: ...here.
* config/sparc/sparc.c: Moved to...
* config/sparc/sparc.cc: ...here.
* config/stormy16/stormy16.c: Moved to...
* config/stormy16/stormy16.cc: ...here.
* config/tilegx/mul-tables.c: Moved to...
* config/tilegx/mul-tables.cc: ...here.
* config/tilegx/tilegx-c.c: Moved to...
* config/tilegx/tilegx-c.cc: ...here.
* config/tilegx/tilegx.c: Moved to...
* config/tilegx/tilegx.cc: ...here.
* config/tilepro/mul-tables.c: Moved to...
* config/tilepro/mul-tables.cc: ...here.
* config/tilepro/tilepro-c.c: Moved to...
* config/tilepro/tilepro-c.cc: ...here.
* config/tilepro/tilepro.c: Moved to...
* config/tilepro/tilepro.cc: ...here.
* config/v850/v850-c.c: Moved to...
* config/v850/v850-c.cc: ...here.
* config/v850/v850.c: Moved to...
* config/v850/v850.cc: ...here.
* config/vax/vax.c: Moved to...
* config/vax/vax.cc: ...here.
* config/visium/visium.c: Moved to...
* config/visium/visium.cc: ...here.
* config/vms/vms-c.c: Moved to...
* config/vms/vms-c.cc: ...here.
* config/vms/vms-f.c: Moved to...
* config/vms/vms-f.cc: ...here.
* config/vms/vms.c: Moved to...
* config/vms/vms.cc: ...here.
* config/vxworks-c.c: Moved to...
* config/vxworks-c.cc: ...here.
* config/vxworks.c: Moved to...
* config/vxworks.cc: ...here.
* config/winnt-c.c: Moved to...
* config/winnt-c.cc: ...here.
* config/xtensa/xtensa.c: Moved to...
* config/xtensa/xtensa.cc: ...here.
* context.c: Moved to...
* context.cc: ...here.
* convert.c: Moved to...
* convert.cc: ...here.
* coverage.c: Moved to...
* coverage.cc: ...here.
* cppbuiltin.c: Moved to...
* cppbuiltin.cc: ...here.
* cppdefault.c: Moved to...
* cppdefault.cc: ...here.
* cprop.c: Moved to...
* cprop.cc: ...here.
* cse.c: Moved to...
* cse.cc: ...here.
* cselib.c: Moved to...
* cselib.cc: ...here.
* ctfc.c: Moved to...
* ctfc.cc: ...here.
* ctfout.c: Moved to...
* ctfout.cc: ...here.
* data-streamer-in.c: Moved to...
* data-streamer-in.cc: ...here.
* data-streamer-out.c: Moved to...
* data-streamer-out.cc: ...here.
* data-streamer.c: Moved to...
* data-streamer.cc: ...here.
* dbgcnt.c: Moved to...
* dbgcnt.cc: ...here.
* dbxout.c: Moved to...
* dbxout.cc: ...here.
* dce.c: Moved to...
* dce.cc: ...here.
* ddg.c: Moved to...
* ddg.cc: ...here.
* debug.c: Moved to...
* debug.cc: ...here.
* df-core.c: Moved to...
* df-core.cc: ...here.
* df-problems.c: Moved to...
* df-problems.cc: ...here.
* df-scan.c: Moved to...
* df-scan.cc: ...here.
* dfp.c: Moved to...
* dfp.cc: ...here.
* diagnostic-color.c: Moved to...
* diagnostic-color.cc: ...here.
* diagnostic-show-locus.c: Moved to...
* diagnostic-show-locus.cc: ...here.
* diagnostic-spec.c: Moved to...
* diagnostic-spec.cc: ...here.
* diagnostic.c: Moved to...
* diagnostic.cc: ...here.
* dojump.c: Moved to...
* dojump.cc: ...here.
* dominance.c: Moved to...
* dominance.cc: ...here.
* domwalk.c: Moved to...
* domwalk.cc: ...here.
* double-int.c: Moved to...
* double-int.cc: ...here.
* dse.c: Moved to...
* dse.cc: ...here.
* dumpfile.c: Moved to...
* dumpfile.cc: ...here.
* dwarf2asm.c: Moved to...
* dwarf2asm.cc: ...here.
* dwarf2cfi.c: Moved to...
* dwarf2cfi.cc: ...here.
* dwarf2ctf.c: Moved to...
* dwarf2ctf.cc: ...here.
* dwarf2out.c: Moved to...
* dwarf2out.cc: ...here.
* early-remat.c: Moved to...
* early-remat.cc: ...here.
* edit-context.c: Moved to...
* edit-context.cc: ...here.
* emit-rtl.c: Moved to...
* emit-rtl.cc: ...here.
* errors.c: Moved to...
* errors.cc: ...here.
* et-forest.c: Moved to...
* et-forest.cc: ...here.
* except.c: Moved to...
* except.cc: ...here.
* explow.c: Moved to...
* explow.cc: ...here.
* expmed.c: Moved to...
* expmed.cc: ...here.
* expr.c: Moved to...
* expr.cc: ...here.
* fibonacci_heap.c: Moved to...
* fibonacci_heap.cc: ...here.
* file-find.c: Moved to...
* file-find.cc: ...here.
* file-prefix-map.c: Moved to...
* file-prefix-map.cc: ...here.
* final.c: Moved to...
* final.cc: ...here.
* fixed-value.c: Moved to...
* fixed-value.cc: ...here.
* fold-const-call.c: Moved to...
* fold-const-call.cc: ...here.
* fold-const.c: Moved to...
* fold-const.cc: ...here.
* fp-test.c: Moved to...
* fp-test.cc: ...here.
* function-tests.c: Moved to...
* function-tests.cc: ...here.
* function.c: Moved to...
* function.cc: ...here.
* fwprop.c: Moved to...
* fwprop.cc: ...here.
* gcc-ar.c: Moved to...
* gcc-ar.cc: ...here.
* gcc-main.c: Moved to...
* gcc-main.cc: ...here.
* gcc-rich-location.c: Moved to...
* gcc-rich-location.cc: ...here.
* gcc.c: Moved to...
* gcc.cc: ...here.
* gcov-dump.c: Moved to...
* gcov-dump.cc: ...here.
* gcov-io.c: Moved to...
* gcov-io.cc: ...here.
* gcov-tool.c: Moved to...
* gcov-tool.cc: ...here.
* gcov.c: Moved to...
* gcov.cc: ...here.
* gcse-common.c: Moved to...
* gcse-common.cc: ...here.
* gcse.c: Moved to...
* gcse.cc: ...here.
* genattr-common.c: Moved to...
* genattr-common.cc: ...here.
* genattr.c: Moved to...
* genattr.cc: ...here.
* genattrtab.c: Moved to...
* genattrtab.cc: ...here.
* genautomata.c: Moved to...
* genautomata.cc: ...here.
* gencfn-macros.c: Moved to...
* gencfn-macros.cc: ...here.
* gencheck.c: Moved to...
* gencheck.cc: ...here.
* genchecksum.c: Moved to...
* genchecksum.cc: ...here.
* gencodes.c: Moved to...
* gencodes.cc: ...here.
* genconditions.c: Moved to...
* genconditions.cc: ...here.
* genconfig.c: Moved to...
* genconfig.cc: ...here.
* genconstants.c: Moved to...
* genconstants.cc: ...here.
* genemit.c: Moved to...
* genemit.cc: ...here.
* genenums.c: Moved to...
* genenums.cc: ...here.
* generic-match-head.c: Moved to...
* generic-match-head.cc: ...here.
* genextract.c: Moved to...
* genextract.cc: ...here.
* genflags.c: Moved to...
* genflags.cc: ...here.
* gengenrtl.c: Moved to...
* gengenrtl.cc: ...here.
* gengtype-parse.c: Moved to...
* gengtype-parse.cc: ...here.
* gengtype-state.c: Moved to...
* gengtype-state.cc: ...here.
* gengtype.c: Moved to...
* gengtype.cc: ...here.
* genhooks.c: Moved to...
* genhooks.cc: ...here.
* genmatch.c: Moved to...
* genmatch.cc: ...here.
* genmddeps.c: Moved to...
* genmddeps.cc: ...here.
* genmddump.c: Moved to...
* genmddump.cc: ...here.
* genmodes.c: Moved to...
* genmodes.cc: ...here.
* genopinit.c: Moved to...
* genopinit.cc: ...here.
* genoutput.c: Moved to...
* genoutput.cc: ...here.
* genpeep.c: Moved to...
* genpeep.cc: ...here.
* genpreds.c: Moved to...
* genpreds.cc: ...here.
* genrecog.c: Moved to...
* genrecog.cc: ...here.
* gensupport.c: Moved to...
* gensupport.cc: ...here.
* gentarget-def.c: Moved to...
* gentarget-def.cc: ...here.
* genversion.c: Moved to...
* genversion.cc: ...here.
* ggc-common.c: Moved to...
* ggc-common.cc: ...here.
* ggc-none.c: Moved to...
* ggc-none.cc: ...here.
* ggc-page.c: Moved to...
* ggc-page.cc: ...here.
* ggc-tests.c: Moved to...
* ggc-tests.cc: ...here.
* gimple-builder.c: Moved to...
* gimple-builder.cc: ...here.
* gimple-expr.c: Moved to...
* gimple-expr.cc: ...here.
* gimple-fold.c: Moved to...
* gimple-fold.cc: ...here.
* gimple-iterator.c: Moved to...
* gimple-iterator.cc: ...here.
* gimple-laddress.c: Moved to...
* gimple-laddress.cc: ...here.
* gimple-loop-jam.c: Moved to...
* gimple-loop-jam.cc: ...here.
* gimple-low.c: Moved to...
* gimple-low.cc: ...here.
* gimple-match-head.c: Moved to...
* gimple-match-head.cc: ...here.
* gimple-pretty-print.c: Moved to...
* gimple-pretty-print.cc: ...here.
* gimple-ssa-backprop.c: Moved to...
* gimple-ssa-backprop.cc: ...here.
* gimple-ssa-evrp-analyze.c: Moved to...
* gimple-ssa-evrp-analyze.cc: ...here.
* gimple-ssa-evrp.c: Moved to...
* gimple-ssa-evrp.cc: ...here.
* gimple-ssa-isolate-paths.c: Moved to...
* gimple-ssa-isolate-paths.cc: ...here.
* gimple-ssa-nonnull-compare.c: Moved to...
* gimple-ssa-nonnull-compare.cc: ...here.
* gimple-ssa-split-paths.c: Moved to...
* gimple-ssa-split-paths.cc: ...here.
* gimple-ssa-sprintf.c: Moved to...
* gimple-ssa-sprintf.cc: ...here.
* gimple-ssa-store-merging.c: Moved to...
* gimple-ssa-store-merging.cc: ...here.
* gimple-ssa-strength-reduction.c: Moved to...
* gimple-ssa-strength-reduction.cc: ...here.
* gimple-ssa-warn-alloca.c: Moved to...
* gimple-ssa-warn-alloca.cc: ...here.
* gimple-ssa-warn-restrict.c: Moved to...
* gimple-ssa-warn-restrict.cc: ...here.
* gimple-streamer-in.c: Moved to...
* gimple-streamer-in.cc: ...here.
* gimple-streamer-out.c: Moved to...
* gimple-streamer-out.cc: ...here.
* gimple-walk.c: Moved to...
* gimple-walk.cc: ...here.
* gimple-warn-recursion.c: Moved to...
* gimple-warn-recursion.cc: ...here.
* gimple.c: Moved to...
* gimple.cc: ...here.
* gimplify-me.c: Moved to...
* gimplify-me.cc: ...here.
* gimplify.c: Moved to...
* gimplify.cc: ...here.
* godump.c: Moved to...
* godump.cc: ...here.
* graph.c: Moved to...
* graph.cc: ...here.
* graphds.c: Moved to...
* graphds.cc: ...here.
* graphite-dependences.c: Moved to...
* graphite-dependences.cc: ...here.
* graphite-isl-ast-to-gimple.c: Moved to...
* graphite-isl-ast-to-gimple.cc: ...here.
* graphite-optimize-isl.c: Moved to...
* graphite-optimize-isl.cc: ...here.
* graphite-poly.c: Moved to...
* graphite-poly.cc: ...here.
* graphite-scop-detection.c: Moved to...
* graphite-scop-detection.cc: ...here.
* graphite-sese-to-poly.c: Moved to...
* graphite-sese-to-poly.cc: ...here.
* graphite.c: Moved to...
* graphite.cc: ...here.
* haifa-sched.c: Moved to...
* haifa-sched.cc: ...here.
* hash-map-tests.c: Moved to...
* hash-map-tests.cc: ...here.
* hash-set-tests.c: Moved to...
* hash-set-tests.cc: ...here.
* hash-table.c: Moved to...
* hash-table.cc: ...here.
* hooks.c: Moved to...
* hooks.cc: ...here.
* host-default.c: Moved to...
* host-default.cc: ...here.
* hw-doloop.c: Moved to...
* hw-doloop.cc: ...here.
* hwint.c: Moved to...
* hwint.cc: ...here.
* ifcvt.c: Moved to...
* ifcvt.cc: ...here.
* inchash.c: Moved to...
* inchash.cc: ...here.
* incpath.c: Moved to...
* incpath.cc: ...here.
* init-regs.c: Moved to...
* init-regs.cc: ...here.
* input.c: Moved to...
* input.cc: ...here.
* internal-fn.c: Moved to...
* internal-fn.cc: ...here.
* intl.c: Moved to...
* intl.cc: ...here.
* ipa-comdats.c: Moved to...
* ipa-comdats.cc: ...here.
* ipa-cp.c: Moved to...
* ipa-cp.cc: ...here.
* ipa-devirt.c: Moved to...
* ipa-devirt.cc: ...here.
* ipa-fnsummary.c: Moved to...
* ipa-fnsummary.cc: ...here.
* ipa-icf-gimple.c: Moved to...
* ipa-icf-gimple.cc: ...here.
* ipa-icf.c: Moved to...
* ipa-icf.cc: ...here.
* ipa-inline-analysis.c: Moved to...
* ipa-inline-analysis.cc: ...here.
* ipa-inline-transform.c: Moved to...
* ipa-inline-transform.cc: ...here.
* ipa-inline.c: Moved to...
* ipa-inline.cc: ...here.
* ipa-modref-tree.c: Moved to...
* ipa-modref-tree.cc: ...here.
* ipa-modref.c: Moved to...
* ipa-modref.cc: ...here.
* ipa-param-manipulation.c: Moved to...
* ipa-param-manipulation.cc: ...here.
* ipa-polymorphic-call.c: Moved to...
* ipa-polymorphic-call.cc: ...here.
* ipa-predicate.c: Moved to...
* ipa-predicate.cc: ...here.
* ipa-profile.c: Moved to...
* ipa-profile.cc: ...here.
* ipa-prop.c: Moved to...
* ipa-prop.cc: ...here.
* ipa-pure-const.c: Moved to...
* ipa-pure-const.cc: ...here.
* ipa-ref.c: Moved to...
* ipa-ref.cc: ...here.
* ipa-reference.c: Moved to...
* ipa-reference.cc: ...here.
* ipa-split.c: Moved to...
* ipa-split.cc: ...here.
* ipa-sra.c: Moved to...
* ipa-sra.cc: ...here.
* ipa-utils.c: Moved to...
* ipa-utils.cc: ...here.
* ipa-visibility.c: Moved to...
* ipa-visibility.cc: ...here.
* ipa.c: Moved to...
* ipa.cc: ...here.
* ira-build.c: Moved to...
* ira-build.cc: ...here.
* ira-color.c: Moved to...
* ira-color.cc: ...here.
* ira-conflicts.c: Moved to...
* ira-conflicts.cc: ...here.
* ira-costs.c: Moved to...
* ira-costs.cc: ...here.
* ira-emit.c: Moved to...
* ira-emit.cc: ...here.
* ira-lives.c: Moved to...
* ira-lives.cc: ...here.
* ira.c: Moved to...
* ira.cc: ...here.
* jump.c: Moved to...
* jump.cc: ...here.
* langhooks.c: Moved to...
* langhooks.cc: ...here.
* lcm.c: Moved to...
* lcm.cc: ...here.
* lists.c: Moved to...
* lists.cc: ...here.
* loop-doloop.c: Moved to...
* loop-doloop.cc: ...here.
* loop-init.c: Moved to...
* loop-init.cc: ...here.
* loop-invariant.c: Moved to...
* loop-invariant.cc: ...here.
* loop-iv.c: Moved to...
* loop-iv.cc: ...here.
* loop-unroll.c: Moved to...
* loop-unroll.cc: ...here.
* lower-subreg.c: Moved to...
* lower-subreg.cc: ...here.
* lra-assigns.c: Moved to...
* lra-assigns.cc: ...here.
* lra-coalesce.c: Moved to...
* lra-coalesce.cc: ...here.
* lra-constraints.c: Moved to...
* lra-constraints.cc: ...here.
* lra-eliminations.c: Moved to...
* lra-eliminations.cc: ...here.
* lra-lives.c: Moved to...
* lra-lives.cc: ...here.
* lra-remat.c: Moved to...
* lra-remat.cc: ...here.
* lra-spills.c: Moved to...
* lra-spills.cc: ...here.
* lra.c: Moved to...
* lra.cc: ...here.
* lto-cgraph.c: Moved to...
* lto-cgraph.cc: ...here.
* lto-compress.c: Moved to...
* lto-compress.cc: ...here.
* lto-opts.c: Moved to...
* lto-opts.cc: ...here.
* lto-section-in.c: Moved to...
* lto-section-in.cc: ...here.
* lto-section-out.c: Moved to...
* lto-section-out.cc: ...here.
* lto-streamer-in.c: Moved to...
* lto-streamer-in.cc: ...here.
* lto-streamer-out.c: Moved to...
* lto-streamer-out.cc: ...here.
* lto-streamer.c: Moved to...
* lto-streamer.cc: ...here.
* lto-wrapper.c: Moved to...
* lto-wrapper.cc: ...here.
* main.c: Moved to...
* main.cc: ...here.
* mcf.c: Moved to...
* mcf.cc: ...here.
* mode-switching.c: Moved to...
* mode-switching.cc: ...here.
* modulo-sched.c: Moved to...
* modulo-sched.cc: ...here.
* multiple_target.c: Moved to...
* multiple_target.cc: ...here.
* omp-expand.c: Moved to...
* omp-expand.cc: ...here.
* omp-general.c: Moved to...
* omp-general.cc: ...here.
* omp-low.c: Moved to...
* omp-low.cc: ...here.
* omp-offload.c: Moved to...
* omp-offload.cc: ...here.
* omp-simd-clone.c: Moved to...
* omp-simd-clone.cc: ...here.
* opt-suggestions.c: Moved to...
* opt-suggestions.cc: ...here.
* optabs-libfuncs.c: Moved to...
* optabs-libfuncs.cc: ...here.
* optabs-query.c: Moved to...
* optabs-query.cc: ...here.
* optabs-tree.c: Moved to...
* optabs-tree.cc: ...here.
* optabs.c: Moved to...
* optabs.cc: ...here.
* opts-common.c: Moved to...
* opts-common.cc: ...here.
* opts-global.c: Moved to...
* opts-global.cc: ...here.
* opts.c: Moved to...
* opts.cc: ...here.
* passes.c: Moved to...
* passes.cc: ...here.
* plugin.c: Moved to...
* plugin.cc: ...here.
* postreload-gcse.c: Moved to...
* postreload-gcse.cc: ...here.
* postreload.c: Moved to...
* postreload.cc: ...here.
* predict.c: Moved to...
* predict.cc: ...here.
* prefix.c: Moved to...
* prefix.cc: ...here.
* pretty-print.c: Moved to...
* pretty-print.cc: ...here.
* print-rtl-function.c: Moved to...
* print-rtl-function.cc: ...here.
* print-rtl.c: Moved to...
* print-rtl.cc: ...here.
* print-tree.c: Moved to...
* print-tree.cc: ...here.
* profile-count.c: Moved to...
* profile-count.cc: ...here.
* profile.c: Moved to...
* profile.cc: ...here.
* read-md.c: Moved to...
* read-md.cc: ...here.
* read-rtl-function.c: Moved to...
* read-rtl-function.cc: ...here.
* read-rtl.c: Moved to...
* read-rtl.cc: ...here.
* real.c: Moved to...
* real.cc: ...here.
* realmpfr.c: Moved to...
* realmpfr.cc: ...here.
* recog.c: Moved to...
* recog.cc: ...here.
* ree.c: Moved to...
* ree.cc: ...here.
* reg-stack.c: Moved to...
* reg-stack.cc: ...here.
* regcprop.c: Moved to...
* regcprop.cc: ...here.
* reginfo.c: Moved to...
* reginfo.cc: ...here.
* regrename.c: Moved to...
* regrename.cc: ...here.
* regstat.c: Moved to...
* regstat.cc: ...here.
* reload.c: Moved to...
* reload.cc: ...here.
* reload1.c: Moved to...
* reload1.cc: ...here.
* reorg.c: Moved to...
* reorg.cc: ...here.
* resource.c: Moved to...
* resource.cc: ...here.
* rtl-error.c: Moved to...
* rtl-error.cc: ...here.
* rtl-tests.c: Moved to...
* rtl-tests.cc: ...here.
* rtl.c: Moved to...
* rtl.cc: ...here.
* rtlanal.c: Moved to...
* rtlanal.cc: ...here.
* rtlhash.c: Moved to...
* rtlhash.cc: ...here.
* rtlhooks.c: Moved to...
* rtlhooks.cc: ...here.
* rtx-vector-builder.c: Moved to...
* rtx-vector-builder.cc: ...here.
* run-rtl-passes.c: Moved to...
* run-rtl-passes.cc: ...here.
* sancov.c: Moved to...
* sancov.cc: ...here.
* sanopt.c: Moved to...
* sanopt.cc: ...here.
* sbitmap.c: Moved to...
* sbitmap.cc: ...here.
* sched-deps.c: Moved to...
* sched-deps.cc: ...here.
* sched-ebb.c: Moved to...
* sched-ebb.cc: ...here.
* sched-rgn.c: Moved to...
* sched-rgn.cc: ...here.
* sel-sched-dump.c: Moved to...
* sel-sched-dump.cc: ...here.
* sel-sched-ir.c: Moved to...
* sel-sched-ir.cc: ...here.
* sel-sched.c: Moved to...
* sel-sched.cc: ...here.
* selftest-diagnostic.c: Moved to...
* selftest-diagnostic.cc: ...here.
* selftest-rtl.c: Moved to...
* selftest-rtl.cc: ...here.
* selftest-run-tests.c: Moved to...
* selftest-run-tests.cc: ...here.
* selftest.c: Moved to...
* selftest.cc: ...here.
* sese.c: Moved to...
* sese.cc: ...here.
* shrink-wrap.c: Moved to...
* shrink-wrap.cc: ...here.
* simplify-rtx.c: Moved to...
* simplify-rtx.cc: ...here.
* sparseset.c: Moved to...
* sparseset.cc: ...here.
* spellcheck-tree.c: Moved to...
* spellcheck-tree.cc: ...here.
* spellcheck.c: Moved to...
* spellcheck.cc: ...here.
* sreal.c: Moved to...
* sreal.cc: ...here.
* stack-ptr-mod.c: Moved to...
* stack-ptr-mod.cc: ...here.
* statistics.c: Moved to...
* statistics.cc: ...here.
* stmt.c: Moved to...
* stmt.cc: ...here.
* stor-layout.c: Moved to...
* stor-layout.cc: ...here.
* store-motion.c: Moved to...
* store-motion.cc: ...here.
* streamer-hooks.c: Moved to...
* streamer-hooks.cc: ...here.
* stringpool.c: Moved to...
* stringpool.cc: ...here.
* substring-locations.c: Moved to...
* substring-locations.cc: ...here.
* symtab.c: Moved to...
* symtab.cc: ...here.
* target-globals.c: Moved to...
* target-globals.cc: ...here.
* targhooks.c: Moved to...
* targhooks.cc: ...here.
* timevar.c: Moved to...
* timevar.cc: ...here.
* toplev.c: Moved to...
* toplev.cc: ...here.
* tracer.c: Moved to...
* tracer.cc: ...here.
* trans-mem.c: Moved to...
* trans-mem.cc: ...here.
* tree-affine.c: Moved to...
* tree-affine.cc: ...here.
* tree-call-cdce.c: Moved to...
* tree-call-cdce.cc: ...here.
* tree-cfg.c: Moved to...
* tree-cfg.cc: ...here.
* tree-cfgcleanup.c: Moved to...
* tree-cfgcleanup.cc: ...here.
* tree-chrec.c: Moved to...
* tree-chrec.cc: ...here.
* tree-complex.c: Moved to...
* tree-complex.cc: ...here.
* tree-data-ref.c: Moved to...
* tree-data-ref.cc: ...here.
* tree-dfa.c: Moved to...
* tree-dfa.cc: ...here.
* tree-diagnostic.c: Moved to...
* tree-diagnostic.cc: ...here.
* tree-dump.c: Moved to...
* tree-dump.cc: ...here.
* tree-eh.c: Moved to...
* tree-eh.cc: ...here.
* tree-emutls.c: Moved to...
* tree-emutls.cc: ...here.
* tree-if-conv.c: Moved to...
* tree-if-conv.cc: ...here.
* tree-inline.c: Moved to...
* tree-inline.cc: ...here.
* tree-into-ssa.c: Moved to...
* tree-into-ssa.cc: ...here.
* tree-iterator.c: Moved to...
* tree-iterator.cc: ...here.
* tree-loop-distribution.c: Moved to...
* tree-loop-distribution.cc: ...here.
* tree-nested.c: Moved to...
* tree-nested.cc: ...here.
* tree-nrv.c: Moved to...
* tree-nrv.cc: ...here.
* tree-object-size.c: Moved to...
* tree-object-size.cc: ...here.
* tree-outof-ssa.c: Moved to...
* tree-outof-ssa.cc: ...here.
* tree-parloops.c: Moved to...
* tree-parloops.cc: ...here.
* tree-phinodes.c: Moved to...
* tree-phinodes.cc: ...here.
* tree-predcom.c: Moved to...
* tree-predcom.cc: ...here.
* tree-pretty-print.c: Moved to...
* tree-pretty-print.cc: ...here.
* tree-profile.c: Moved to...
* tree-profile.cc: ...here.
* tree-scalar-evolution.c: Moved to...
* tree-scalar-evolution.cc: ...here.
* tree-sra.c: Moved to...
* tree-sra.cc: ...here.
* tree-ssa-address.c: Moved to...
* tree-ssa-address.cc: ...here.
* tree-ssa-alias.c: Moved to...
* tree-ssa-alias.cc: ...here.
* tree-ssa-ccp.c: Moved to...
* tree-ssa-ccp.cc: ...here.
* tree-ssa-coalesce.c: Moved to...
* tree-ssa-coalesce.cc: ...here.
* tree-ssa-copy.c: Moved to...
* tree-ssa-copy.cc: ...here.
* tree-ssa-dce.c: Moved to...
* tree-ssa-dce.cc: ...here.
* tree-ssa-dom.c: Moved to...
* tree-ssa-dom.cc: ...here.
* tree-ssa-dse.c: Moved to...
* tree-ssa-dse.cc: ...here.
* tree-ssa-forwprop.c: Moved to...
* tree-ssa-forwprop.cc: ...here.
* tree-ssa-ifcombine.c: Moved to...
* tree-ssa-ifcombine.cc: ...here.
* tree-ssa-live.c: Moved to...
* tree-ssa-live.cc: ...here.
* tree-ssa-loop-ch.c: Moved to...
* tree-ssa-loop-ch.cc: ...here.
* tree-ssa-loop-im.c: Moved to...
* tree-ssa-loop-im.cc: ...here.
* tree-ssa-loop-ivcanon.c: Moved to...
* tree-ssa-loop-ivcanon.cc: ...here.
* tree-ssa-loop-ivopts.c: Moved to...
* tree-ssa-loop-ivopts.cc: ...here.
* tree-ssa-loop-manip.c: Moved to...
* tree-ssa-loop-manip.cc: ...here.
* tree-ssa-loop-niter.c: Moved to...
* tree-ssa-loop-niter.cc: ...here.
* tree-ssa-loop-prefetch.c: Moved to...
* tree-ssa-loop-prefetch.cc: ...here.
* tree-ssa-loop-split.c: Moved to...
* tree-ssa-loop-split.cc: ...here.
* tree-ssa-loop-unswitch.c: Moved to...
* tree-ssa-loop-unswitch.cc: ...here.
* tree-ssa-loop.c: Moved to...
* tree-ssa-loop.cc: ...here.
* tree-ssa-math-opts.c: Moved to...
* tree-ssa-math-opts.cc: ...here.
* tree-ssa-operands.c: Moved to...
* tree-ssa-operands.cc: ...here.
* tree-ssa-phiopt.c: Moved to...
* tree-ssa-phiopt.cc: ...here.
* tree-ssa-phiprop.c: Moved to...
* tree-ssa-phiprop.cc: ...here.
* tree-ssa-pre.c: Moved to...
* tree-ssa-pre.cc: ...here.
* tree-ssa-propagate.c: Moved to...
* tree-ssa-propagate.cc: ...here.
* tree-ssa-reassoc.c: Moved to...
* tree-ssa-reassoc.cc: ...here.
* tree-ssa-sccvn.c: Moved to...
* tree-ssa-sccvn.cc: ...here.
* tree-ssa-scopedtables.c: Moved to...
* tree-ssa-scopedtables.cc: ...here.
* tree-ssa-sink.c: Moved to...
* tree-ssa-sink.cc: ...here.
* tree-ssa-strlen.c: Moved to...
* tree-ssa-strlen.cc: ...here.
* tree-ssa-structalias.c: Moved to...
* tree-ssa-structalias.cc: ...here.
* tree-ssa-tail-merge.c: Moved to...
* tree-ssa-tail-merge.cc: ...here.
* tree-ssa-ter.c: Moved to...
* tree-ssa-ter.cc: ...here.
* tree-ssa-threadbackward.c: Moved to...
* tree-ssa-threadbackward.cc: ...here.
* tree-ssa-threadedge.c: Moved to...
* tree-ssa-threadedge.cc: ...here.
* tree-ssa-threadupdate.c: Moved to...
* tree-ssa-threadupdate.cc: ...here.
* tree-ssa-uncprop.c: Moved to...
* tree-ssa-uncprop.cc: ...here.
* tree-ssa-uninit.c: Moved to...
* tree-ssa-uninit.cc: ...here.
* tree-ssa.c: Moved to...
* tree-ssa.cc: ...here.
* tree-ssanames.c: Moved to...
* tree-ssanames.cc: ...here.
* tree-stdarg.c: Moved to...
* tree-stdarg.cc: ...here.
* tree-streamer-in.c: Moved to...
* tree-streamer-in.cc: ...here.
* tree-streamer-out.c: Moved to...
* tree-streamer-out.cc: ...here.
* tree-streamer.c: Moved to...
* tree-streamer.cc: ...here.
* tree-switch-conversion.c: Moved to...
* tree-switch-conversion.cc: ...here.
* tree-tailcall.c: Moved to...
* tree-tailcall.cc: ...here.
* tree-vect-data-refs.c: Moved to...
* tree-vect-data-refs.cc: ...here.
* tree-vect-generic.c: Moved to...
* tree-vect-generic.cc: ...here.
* tree-vect-loop-manip.c: Moved to...
* tree-vect-loop-manip.cc: ...here.
* tree-vect-loop.c: Moved to...
* tree-vect-loop.cc: ...here.
* tree-vect-patterns.c: Moved to...
* tree-vect-patterns.cc: ...here.
* tree-vect-slp-patterns.c: Moved to...
* tree-vect-slp-patterns.cc: ...here.
* tree-vect-slp.c: Moved to...
* tree-vect-slp.cc: ...here.
* tree-vect-stmts.c: Moved to...
* tree-vect-stmts.cc: ...here.
* tree-vector-builder.c: Moved to...
* tree-vector-builder.cc: ...here.
* tree-vectorizer.c: Moved to...
* tree-vectorizer.cc: ...here.
* tree-vrp.c: Moved to...
* tree-vrp.cc: ...here.
* tree.c: Moved to...
* tree.cc: ...here.
* tsan.c: Moved to...
* tsan.cc: ...here.
* typed-splay-tree.c: Moved to...
* typed-splay-tree.cc: ...here.
* ubsan.c: Moved to...
* ubsan.cc: ...here.
* valtrack.c: Moved to...
* valtrack.cc: ...here.
* value-prof.c: Moved to...
* value-prof.cc: ...here.
* var-tracking.c: Moved to...
* var-tracking.cc: ...here.
* varasm.c: Moved to...
* varasm.cc: ...here.
* varpool.c: Moved to...
* varpool.cc: ...here.
* vec-perm-indices.c: Moved to...
* vec-perm-indices.cc: ...here.
* vec.c: Moved to...
* vec.cc: ...here.
* vmsdbgout.c: Moved to...
* vmsdbgout.cc: ...here.
* vr-values.c: Moved to...
* vr-values.cc: ...here.
* vtable-verify.c: Moved to...
* vtable-verify.cc: ...here.
* web.c: Moved to...
* web.cc: ...here.
* xcoffout.c: Moved to...
* xcoffout.cc: ...here.
gcc/c-family/ChangeLog:
* c-ada-spec.c: Moved to...
* c-ada-spec.cc: ...here.
* c-attribs.c: Moved to...
* c-attribs.cc: ...here.
* c-common.c: Moved to...
* c-common.cc: ...here.
* c-cppbuiltin.c: Moved to...
* c-cppbuiltin.cc: ...here.
* c-dump.c: Moved to...
* c-dump.cc: ...here.
* c-format.c: Moved to...
* c-format.cc: ...here.
* c-gimplify.c: Moved to...
* c-gimplify.cc: ...here.
* c-indentation.c: Moved to...
* c-indentation.cc: ...here.
* c-lex.c: Moved to...
* c-lex.cc: ...here.
* c-omp.c: Moved to...
* c-omp.cc: ...here.
* c-opts.c: Moved to...
* c-opts.cc: ...here.
* c-pch.c: Moved to...
* c-pch.cc: ...here.
* c-ppoutput.c: Moved to...
* c-ppoutput.cc: ...here.
* c-pragma.c: Moved to...
* c-pragma.cc: ...here.
* c-pretty-print.c: Moved to...
* c-pretty-print.cc: ...here.
* c-semantics.c: Moved to...
* c-semantics.cc: ...here.
* c-ubsan.c: Moved to...
* c-ubsan.cc: ...here.
* c-warn.c: Moved to...
* c-warn.cc: ...here.
* cppspec.c: Moved to...
* cppspec.cc: ...here.
* stub-objc.c: Moved to...
* stub-objc.cc: ...here.
gcc/c/ChangeLog:
* c-aux-info.c: Moved to...
* c-aux-info.cc: ...here.
* c-convert.c: Moved to...
* c-convert.cc: ...here.
* c-decl.c: Moved to...
* c-decl.cc: ...here.
* c-errors.c: Moved to...
* c-errors.cc: ...here.
* c-fold.c: Moved to...
* c-fold.cc: ...here.
* c-lang.c: Moved to...
* c-lang.cc: ...here.
* c-objc-common.c: Moved to...
* c-objc-common.cc: ...here.
* c-parser.c: Moved to...
* c-parser.cc: ...here.
* c-typeck.c: Moved to...
* c-typeck.cc: ...here.
* gccspec.c: Moved to...
* gccspec.cc: ...here.
* gimple-parser.c: Moved to...
* gimple-parser.cc: ...here.
gcc/cp/ChangeLog:
* call.c: Moved to...
* call.cc: ...here.
* class.c: Moved to...
* class.cc: ...here.
* constexpr.c: Moved to...
* constexpr.cc: ...here.
* cp-gimplify.c: Moved to...
* cp-gimplify.cc: ...here.
* cp-lang.c: Moved to...
* cp-lang.cc: ...here.
* cp-objcp-common.c: Moved to...
* cp-objcp-common.cc: ...here.
* cp-ubsan.c: Moved to...
* cp-ubsan.cc: ...here.
* cvt.c: Moved to...
* cvt.cc: ...here.
* cxx-pretty-print.c: Moved to...
* cxx-pretty-print.cc: ...here.
* decl.c: Moved to...
* decl.cc: ...here.
* decl2.c: Moved to...
* decl2.cc: ...here.
* dump.c: Moved to...
* dump.cc: ...here.
* error.c: Moved to...
* error.cc: ...here.
* except.c: Moved to...
* except.cc: ...here.
* expr.c: Moved to...
* expr.cc: ...here.
* friend.c: Moved to...
* friend.cc: ...here.
* g++spec.c: Moved to...
* g++spec.cc: ...here.
* init.c: Moved to...
* init.cc: ...here.
* lambda.c: Moved to...
* lambda.cc: ...here.
* lex.c: Moved to...
* lex.cc: ...here.
* mangle.c: Moved to...
* mangle.cc: ...here.
* method.c: Moved to...
* method.cc: ...here.
* name-lookup.c: Moved to...
* name-lookup.cc: ...here.
* optimize.c: Moved to...
* optimize.cc: ...here.
* parser.c: Moved to...
* parser.cc: ...here.
* pt.c: Moved to...
* pt.cc: ...here.
* ptree.c: Moved to...
* ptree.cc: ...here.
* rtti.c: Moved to...
* rtti.cc: ...here.
* search.c: Moved to...
* search.cc: ...here.
* semantics.c: Moved to...
* semantics.cc: ...here.
* tree.c: Moved to...
* tree.cc: ...here.
* typeck.c: Moved to...
* typeck.cc: ...here.
* typeck2.c: Moved to...
* typeck2.cc: ...here.
* vtable-class-hierarchy.c: Moved to...
* vtable-class-hierarchy.cc: ...here.
gcc/fortran/ChangeLog:
* arith.c: Moved to...
* arith.cc: ...here.
* array.c: Moved to...
* array.cc: ...here.
* bbt.c: Moved to...
* bbt.cc: ...here.
* check.c: Moved to...
* check.cc: ...here.
* class.c: Moved to...
* class.cc: ...here.
* constructor.c: Moved to...
* constructor.cc: ...here.
* convert.c: Moved to...
* convert.cc: ...here.
* cpp.c: Moved to...
* cpp.cc: ...here.
* data.c: Moved to...
* data.cc: ...here.
* decl.c: Moved to...
* decl.cc: ...here.
* dependency.c: Moved to...
* dependency.cc: ...here.
* dump-parse-tree.c: Moved to...
* dump-parse-tree.cc: ...here.
* error.c: Moved to...
* error.cc: ...here.
* expr.c: Moved to...
* expr.cc: ...here.
* f95-lang.c: Moved to...
* f95-lang.cc: ...here.
* frontend-passes.c: Moved to...
* frontend-passes.cc: ...here.
* gfortranspec.c: Moved to...
* gfortranspec.cc: ...here.
* interface.c: Moved to...
* interface.cc: ...here.
* intrinsic.c: Moved to...
* intrinsic.cc: ...here.
* io.c: Moved to...
* io.cc: ...here.
* iresolve.c: Moved to...
* iresolve.cc: ...here.
* match.c: Moved to...
* match.cc: ...here.
* matchexp.c: Moved to...
* matchexp.cc: ...here.
* misc.c: Moved to...
* misc.cc: ...here.
* module.c: Moved to...
* module.cc: ...here.
* openmp.c: Moved to...
* openmp.cc: ...here.
* options.c: Moved to...
* options.cc: ...here.
* parse.c: Moved to...
* parse.cc: ...here.
* primary.c: Moved to...
* primary.cc: ...here.
* resolve.c: Moved to...
* resolve.cc: ...here.
* scanner.c: Moved to...
* scanner.cc: ...here.
* simplify.c: Moved to...
* simplify.cc: ...here.
* st.c: Moved to...
* st.cc: ...here.
* symbol.c: Moved to...
* symbol.cc: ...here.
* target-memory.c: Moved to...
* target-memory.cc: ...here.
* trans-array.c: Moved to...
* trans-array.cc: ...here.
* trans-common.c: Moved to...
* trans-common.cc: ...here.
* trans-const.c: Moved to...
* trans-const.cc: ...here.
* trans-decl.c: Moved to...
* trans-decl.cc: ...here.
* trans-expr.c: Moved to...
* trans-expr.cc: ...here.
* trans-intrinsic.c: Moved to...
* trans-intrinsic.cc: ...here.
* trans-io.c: Moved to...
* trans-io.cc: ...here.
* trans-openmp.c: Moved to...
* trans-openmp.cc: ...here.
* trans-stmt.c: Moved to...
* trans-stmt.cc: ...here.
* trans-types.c: Moved to...
* trans-types.cc: ...here.
* trans.c: Moved to...
* trans.cc: ...here.
gcc/go/ChangeLog:
* go-backend.c: Moved to...
* go-backend.cc: ...here.
* go-lang.c: Moved to...
* go-lang.cc: ...here.
* gospec.c: Moved to...
* gospec.cc: ...here.
gcc/jit/ChangeLog:
* dummy-frontend.c: Moved to...
* dummy-frontend.cc: ...here.
* jit-builtins.c: Moved to...
* jit-builtins.cc: ...here.
* jit-logging.c: Moved to...
* jit-logging.cc: ...here.
* jit-playback.c: Moved to...
* jit-playback.cc: ...here.
* jit-recording.c: Moved to...
* jit-recording.cc: ...here.
* jit-result.c: Moved to...
* jit-result.cc: ...here.
* jit-spec.c: Moved to...
* jit-spec.cc: ...here.
* jit-tempdir.c: Moved to...
* jit-tempdir.cc: ...here.
* jit-w32.c: Moved to...
* jit-w32.cc: ...here.
* libgccjit.c: Moved to...
* libgccjit.cc: ...here.
gcc/lto/ChangeLog:
* common.c: Moved to...
* common.cc: ...here.
* lto-common.c: Moved to...
* lto-common.cc: ...here.
* lto-dump.c: Moved to...
* lto-dump.cc: ...here.
* lto-lang.c: Moved to...
* lto-lang.cc: ...here.
* lto-object.c: Moved to...
* lto-object.cc: ...here.
* lto-partition.c: Moved to...
* lto-partition.cc: ...here.
* lto-symtab.c: Moved to...
* lto-symtab.cc: ...here.
* lto.c: Moved to...
* lto.cc: ...here.
gcc/objc/ChangeLog:
* objc-act.c: Moved to...
* objc-act.cc: ...here.
* objc-encoding.c: Moved to...
* objc-encoding.cc: ...here.
* objc-gnu-runtime-abi-01.c: Moved to...
* objc-gnu-runtime-abi-01.cc: ...here.
* objc-lang.c: Moved to...
* objc-lang.cc: ...here.
* objc-map.c: Moved to...
* objc-map.cc: ...here.
* objc-next-runtime-abi-01.c: Moved to...
* objc-next-runtime-abi-01.cc: ...here.
* objc-next-runtime-abi-02.c: Moved to...
* objc-next-runtime-abi-02.cc: ...here.
* objc-runtime-shared-support.c: Moved to...
* objc-runtime-shared-support.cc: ...here.
gcc/objcp/ChangeLog:
* objcp-decl.c: Moved to...
* objcp-decl.cc: ...here.
* objcp-lang.c: Moved to...
* objcp-lang.cc: ...here.
libcpp/ChangeLog:
* charset.c: Moved to...
* charset.cc: ...here.
* directives.c: Moved to...
* directives.cc: ...here.
* errors.c: Moved to...
* errors.cc: ...here.
* expr.c: Moved to...
* expr.cc: ...here.
* files.c: Moved to...
* files.cc: ...here.
* identifiers.c: Moved to...
* identifiers.cc: ...here.
* init.c: Moved to...
* init.cc: ...here.
* lex.c: Moved to...
* lex.cc: ...here.
* line-map.c: Moved to...
* line-map.cc: ...here.
* macro.c: Moved to...
* macro.cc: ...here.
* makeucnid.c: Moved to...
* makeucnid.cc: ...here.
* mkdeps.c: Moved to...
* mkdeps.cc: ...here.
* pch.c: Moved to...
* pch.cc: ...here.
* symtab.c: Moved to...
* symtab.cc: ...here.
* traditional.c: Moved to...
* traditional.cc: ...here.
Diffstat (limited to 'gcc/cp/mangle.cc')
-rw-r--r-- | gcc/cp/mangle.cc | 4575 |
1 files changed, 4575 insertions, 0 deletions
diff --git a/gcc/cp/mangle.cc b/gcc/cp/mangle.cc new file mode 100644 index 0000000..a20f0e0 --- /dev/null +++ b/gcc/cp/mangle.cc @@ -0,0 +1,4575 @@ +/* Name mangling for the 3.0 -*- C++ -*- ABI. + Copyright (C) 2000-2022 Free Software Foundation, Inc. + Written by Alex Samuel <samuel@codesourcery.com> + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + GCC is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +<http://www.gnu.org/licenses/>. */ + +/* This file implements mangling of C++ names according to the IA64 + C++ ABI specification. A mangled name encodes a function or + variable's name, scope, type, and/or template arguments into a text + identifier. This identifier is used as the function's or + variable's linkage name, to preserve compatibility between C++'s + language features (templates, scoping, and overloading) and C + linkers. + + Additionally, g++ uses mangled names internally. To support this, + mangling of types is allowed, even though the mangled name of a + type should not appear by itself as an exported name. Ditto for + uninstantiated templates. + + The primary entry point for this module is mangle_decl, which + returns an identifier containing the mangled name for a decl. + Additional entry points are provided to build mangled names of + particular constructs when the appropriate decl for that construct + is not available. These are: + + mangle_typeinfo_for_type: typeinfo data + mangle_typeinfo_string_for_type: typeinfo type name + mangle_vtbl_for_type: virtual table data + mangle_vtt_for_type: VTT data + mangle_ctor_vtbl_for_type: `C-in-B' constructor virtual table data + mangle_thunk: thunk function or entry */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "target.h" +#include "vtable-verify.h" +#include "cp-tree.h" +#include "stringpool.h" +#include "cgraph.h" +#include "stor-layout.h" +#include "flags.h" +#include "attribs.h" + +/* Debugging support. */ + +/* Define DEBUG_MANGLE to enable very verbose trace messages. */ +#ifndef DEBUG_MANGLE +#define DEBUG_MANGLE 0 +#endif + +/* Macros for tracing the write_* functions. */ +#if DEBUG_MANGLE +# define MANGLE_TRACE(FN, INPUT) \ + fprintf (stderr, " %-24s: %-24s\n", (FN), (INPUT)) +# define MANGLE_TRACE_TREE(FN, NODE) \ + fprintf (stderr, " %-24s: %-24s (%p)\n", \ + (FN), get_tree_code_name (TREE_CODE (NODE)), (void *) (NODE)) +#else +# define MANGLE_TRACE(FN, INPUT) +# define MANGLE_TRACE_TREE(FN, NODE) +#endif + +/* Nonzero if NODE is a class template-id. We can't rely on + CLASSTYPE_USE_TEMPLATE here because of tricky bugs in the parser + that hard to distinguish A<T> from A, where A<T> is the type as + instantiated outside of the template, and A is the type used + without parameters inside the template. */ +#define CLASSTYPE_TEMPLATE_ID_P(NODE) \ + (TREE_CODE (NODE) == BOUND_TEMPLATE_TEMPLATE_PARM \ + || (CLASS_TYPE_P (NODE) \ + && CLASSTYPE_TEMPLATE_INFO (NODE) != NULL \ + && PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (NODE)))) + +/* For deciding whether to set G.need_abi_warning, we need to consider both + warn_abi_version and flag_abi_compat_version. */ +#define abi_warn_or_compat_version_crosses(N) \ + (abi_version_crosses (N) || abi_compat_version_crosses (N)) + +/* And sometimes we can simplify the code path if we don't need to worry about + previous ABIs. */ +#define abi_flag_at_least(flag,N) (flag == 0 || flag >= N) +#define any_abi_below(N) \ + (!abi_version_at_least (N) \ + || !abi_flag_at_least (warn_abi_version, (N)) \ + || !abi_flag_at_least (flag_abi_compat_version, (N))) + +/* Things we only need one of. This module is not reentrant. */ +struct GTY(()) globals { + /* An array of the current substitution candidates, in the order + we've seen them. */ + vec<tree, va_gc> *substitutions; + + /* The entity that is being mangled. */ + tree GTY ((skip)) entity; + + /* How many parameter scopes we are inside. */ + int parm_depth; + + /* True if the mangling will be different in a future version of the + ABI. */ + bool need_abi_warning; + + /* True if the mangling will be different in C++17 mode. */ + bool need_cxx17_warning; + + /* True if we mangled a module name. */ + bool mod; +}; + +static GTY (()) globals G; + +/* The obstack on which we build mangled names. */ +static struct obstack *mangle_obstack; + +/* The obstack on which we build mangled names that are not going to + be IDENTIFIER_NODEs. */ +static struct obstack name_obstack; + +/* The first object on the name_obstack; we use this to free memory + allocated on the name_obstack. */ +static void *name_base; + +/* Indices into subst_identifiers. These are identifiers used in + special substitution rules. */ +typedef enum +{ + SUBID_ALLOCATOR, + SUBID_BASIC_STRING, + SUBID_CHAR_TRAITS, + SUBID_BASIC_ISTREAM, + SUBID_BASIC_OSTREAM, + SUBID_BASIC_IOSTREAM, + SUBID_MAX +} +substitution_identifier_index_t; + +/* For quick substitution checks, look up these common identifiers + once only. */ +static GTY(()) tree subst_identifiers[SUBID_MAX]; + +/* Single-letter codes for builtin integer types, defined in + <builtin-type>. These are indexed by integer_type_kind values. */ +static const char +integer_type_codes[itk_none] = +{ + 'c', /* itk_char */ + 'a', /* itk_signed_char */ + 'h', /* itk_unsigned_char */ + 's', /* itk_short */ + 't', /* itk_unsigned_short */ + 'i', /* itk_int */ + 'j', /* itk_unsigned_int */ + 'l', /* itk_long */ + 'm', /* itk_unsigned_long */ + 'x', /* itk_long_long */ + 'y', /* itk_unsigned_long_long */ + /* __intN types are handled separately */ + '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0' +}; + +static tree maybe_template_info (const tree); + +/* Functions for handling substitutions. */ + +static inline tree canonicalize_for_substitution (tree); +static void add_substitution (tree); +static inline int is_std_substitution (const tree, + const substitution_identifier_index_t); +static inline int is_std_substitution_char (const tree, + const substitution_identifier_index_t); +static int find_substitution (tree); +static void mangle_call_offset (const tree, const tree); + +/* Functions for emitting mangled representations of things. */ + +static void write_mangled_name (const tree, bool); +static void write_encoding (const tree); +static void write_name (tree, const int); +static void write_abi_tags (tree); +static void write_unscoped_name (const tree); +static void write_unscoped_template_name (const tree); +static void write_nested_name (const tree); +static void write_prefix (const tree); +static void write_template_prefix (const tree); +static void write_unqualified_name (tree); +static void write_conversion_operator_name (const tree); +static void write_source_name (tree); +static void write_literal_operator_name (tree); +static void write_unnamed_type_name (const tree); +static void write_closure_type_name (const tree); +static int hwint_to_ascii (unsigned HOST_WIDE_INT, const unsigned int, char *, + const unsigned int); +static void write_number (unsigned HOST_WIDE_INT, const int, + const unsigned int); +static void write_compact_number (int num); +static void write_integer_cst (const tree); +static void write_real_cst (const tree); +static void write_identifier (const char *); +static void write_special_name_constructor (const tree); +static void write_special_name_destructor (const tree); +static void write_type (tree); +static int write_CV_qualifiers_for_type (const tree); +static void write_builtin_type (tree); +static void write_function_type (const tree); +static void write_bare_function_type (const tree, const int, const tree); +static void write_method_parms (tree, const int, const tree); +static void write_class_enum_type (const tree); +static void write_template_args (tree); +static void write_expression (tree); +static void write_template_arg_literal (const tree); +static void write_template_arg (tree); +static void write_template_template_arg (const tree); +static void write_array_type (const tree); +static void write_pointer_to_member_type (const tree); +static void write_template_param (const tree); +static void write_template_template_param (const tree); +static void write_substitution (const int); +static int discriminator_for_local_entity (tree); +static int discriminator_for_string_literal (tree, tree); +static void write_discriminator (const int); +static void write_local_name (tree, const tree, const tree); +static void dump_substitution_candidates (void); +static tree mangle_decl_string (const tree); +static void maybe_check_abi_tags (tree, tree = NULL_TREE, int = 10); +static bool equal_abi_tags (tree, tree); + +/* Control functions. */ + +static inline void start_mangling (const tree); +static tree mangle_special_for_type (const tree, const char *); + +/* Append a single character to the end of the mangled + representation. */ +#define write_char(CHAR) \ + obstack_1grow (mangle_obstack, (CHAR)) + +/* Append a sized buffer to the end of the mangled representation. */ +#define write_chars(CHAR, LEN) \ + obstack_grow (mangle_obstack, (CHAR), (LEN)) + +/* Append a NUL-terminated string to the end of the mangled + representation. */ +#define write_string(STRING) \ + obstack_grow (mangle_obstack, (STRING), strlen (STRING)) + +/* Nonzero if NODE1 and NODE2 are both TREE_LIST nodes and have the + same purpose (context, which may be a type) and value (template + decl). See write_template_prefix for more information on what this + is used for. */ +#define NESTED_TEMPLATE_MATCH(NODE1, NODE2) \ + (TREE_CODE (NODE1) == TREE_LIST \ + && TREE_CODE (NODE2) == TREE_LIST \ + && ((TYPE_P (TREE_PURPOSE (NODE1)) \ + && same_type_p (TREE_PURPOSE (NODE1), TREE_PURPOSE (NODE2))) \ + || TREE_PURPOSE (NODE1) == TREE_PURPOSE (NODE2)) \ + && TREE_VALUE (NODE1) == TREE_VALUE (NODE2)) + +/* Write out an unsigned quantity in base 10. */ +#define write_unsigned_number(NUMBER) \ + write_number ((NUMBER), /*unsigned_p=*/1, 10) + +/* If DECL is a template instance (including the uninstantiated template + itself), return its TEMPLATE_INFO. Otherwise return NULL. */ + +static tree +maybe_template_info (const tree decl) +{ + if (TREE_CODE (decl) == TYPE_DECL) + { + /* TYPE_DECLs are handled specially. Look at its type to decide + if this is a template instantiation. */ + const tree type = TREE_TYPE (decl); + + if (CLASS_TYPE_P (type) && CLASSTYPE_TEMPLATE_ID_P (type)) + return TYPE_TEMPLATE_INFO (type); + } + else + { + /* Check if the template is a primary template. */ + if (DECL_LANG_SPECIFIC (decl) != NULL + && VAR_OR_FUNCTION_DECL_P (decl) + && DECL_TEMPLATE_INFO (decl) + && PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (decl))) + return DECL_TEMPLATE_INFO (decl); + } + + /* It's not a template id. */ + return NULL_TREE; +} + +/* Produce debugging output of current substitution candidates. */ + +static void +dump_substitution_candidates (void) +{ + unsigned i; + tree el; + + fprintf (stderr, " ++ substitutions "); + FOR_EACH_VEC_ELT (*G.substitutions, i, el) + { + const char *name = "???"; + + if (i > 0) + fprintf (stderr, " "); + if (DECL_P (el)) + name = IDENTIFIER_POINTER (DECL_NAME (el)); + else if (TREE_CODE (el) == TREE_LIST) + name = IDENTIFIER_POINTER (DECL_NAME (TREE_VALUE (el))); + else if (TYPE_NAME (el)) + name = TYPE_NAME_STRING (el); + fprintf (stderr, " S%d_ = ", i - 1); + if (TYPE_P (el) && + (CP_TYPE_RESTRICT_P (el) + || CP_TYPE_VOLATILE_P (el) + || CP_TYPE_CONST_P (el))) + fprintf (stderr, "CV-"); + fprintf (stderr, "%s (%s at %p)\n", + name, get_tree_code_name (TREE_CODE (el)), (void *) el); + } +} + +/* <exception-spec> ::= + Do -- non-throwing exception specification + DO <expression> E -- computed (instantiation-dependent) noexcept + Dw <type>* E -- throw (types) */ + +static void +write_exception_spec (tree spec) +{ + + if (!spec || spec == noexcept_false_spec) + /* Nothing. */ + return; + + if (!flag_noexcept_type) + { + G.need_cxx17_warning = true; + return; + } + + if (spec == noexcept_true_spec || spec == empty_except_spec) + write_string ("Do"); + else if (tree expr = TREE_PURPOSE (spec)) + { + /* noexcept (expr) */ + gcc_assert (uses_template_parms (expr)); + write_string ("DO"); + write_expression (expr); + write_char ('E'); + } + else + { + /* throw (type-list) */ + write_string ("Dw"); + for (tree t = spec; t; t = TREE_CHAIN (t)) + write_type (TREE_VALUE (t)); + write_char ('E'); + } +} + +/* Both decls and types can be substitution candidates, but sometimes + they refer to the same thing. For instance, a TYPE_DECL and + RECORD_TYPE for the same class refer to the same thing, and should + be treated accordingly in substitutions. This function returns a + canonicalized tree node representing NODE that is used when adding + and substitution candidates and finding matches. */ + +static inline tree +canonicalize_for_substitution (tree node) +{ + /* For a TYPE_DECL, use the type instead. */ + if (TREE_CODE (node) == TYPE_DECL) + node = TREE_TYPE (node); + if (TYPE_P (node) + && TYPE_CANONICAL (node) != node + && TYPE_MAIN_VARIANT (node) != node) + { + tree orig = node; + /* Here we want to strip the topmost typedef only. + We need to do that so is_std_substitution can do proper + name matching. */ + if (TREE_CODE (node) == FUNCTION_TYPE) + /* Use build_qualified_type and TYPE_QUALS here to preserve + the old buggy mangling of attribute noreturn with abi<5. */ + node = build_qualified_type (TYPE_MAIN_VARIANT (node), + TYPE_QUALS (node)); + else + node = cp_build_qualified_type (TYPE_MAIN_VARIANT (node), + cp_type_quals (node)); + if (FUNC_OR_METHOD_TYPE_P (node)) + { + node = build_ref_qualified_type (node, type_memfn_rqual (orig)); + tree r = canonical_eh_spec (TYPE_RAISES_EXCEPTIONS (orig)); + if (flag_noexcept_type) + node = build_exception_variant (node, r); + else + /* Set the warning flag if appropriate. */ + write_exception_spec (r); + } + } + return node; +} + +/* Add NODE as a substitution candidate. NODE must not already be on + the list of candidates. */ + +static void +add_substitution (tree node) +{ + tree c; + + if (DEBUG_MANGLE) + fprintf (stderr, " ++ add_substitution (%s at %10p)\n", + get_tree_code_name (TREE_CODE (node)), (void *) node); + + /* Get the canonicalized substitution candidate for NODE. */ + c = canonicalize_for_substitution (node); + if (DEBUG_MANGLE && c != node) + fprintf (stderr, " ++ using candidate (%s at %10p)\n", + get_tree_code_name (TREE_CODE (node)), (void *) node); + node = c; + + /* Make sure NODE isn't already a candidate. */ + if (flag_checking) + { + int i; + tree candidate; + + FOR_EACH_VEC_SAFE_ELT (G.substitutions, i, candidate) + { + gcc_assert (!(DECL_P (node) && node == candidate)); + gcc_assert (!(TYPE_P (node) && TYPE_P (candidate) + && same_type_p (node, candidate))); + } + } + + /* Put the decl onto the varray of substitution candidates. */ + vec_safe_push (G.substitutions, node); + + if (DEBUG_MANGLE) + dump_substitution_candidates (); +} + +/* Helper function for find_substitution. Returns nonzero if NODE, + which may be a decl or a CLASS_TYPE, is a template-id with template + name of substitution_index[INDEX] in the ::std namespace. */ + +static inline int +is_std_substitution (const tree node, + const substitution_identifier_index_t index) +{ + tree type = NULL; + tree decl = NULL; + + if (DECL_P (node)) + { + type = TREE_TYPE (node); + decl = node; + } + else if (CLASS_TYPE_P (node)) + { + type = node; + decl = TYPE_NAME (node); + } + else + /* These are not the droids you're looking for. */ + return 0; + + return (DECL_NAMESPACE_STD_P (CP_DECL_CONTEXT (decl)) + && TYPE_LANG_SPECIFIC (type) + && TYPE_TEMPLATE_INFO (type) + && (DECL_NAME (TYPE_TI_TEMPLATE (type)) + == subst_identifiers[index])); +} + +/* Return the ABI tags (the TREE_VALUE of the "abi_tag" attribute entry) for T, + which can be a decl or type. */ + +static tree +get_abi_tags (tree t) +{ + if (!t || TREE_CODE (t) == NAMESPACE_DECL) + return NULL_TREE; + + if (DECL_P (t) && DECL_DECLARES_TYPE_P (t)) + t = TREE_TYPE (t); + + tree attrs; + if (TYPE_P (t)) + attrs = TYPE_ATTRIBUTES (t); + else + attrs = DECL_ATTRIBUTES (t); + + tree tags = lookup_attribute ("abi_tag", attrs); + if (tags) + tags = TREE_VALUE (tags); + return tags; +} + +/* Helper function for find_substitution. Returns nonzero if NODE, + which may be a decl or a CLASS_TYPE, is the template-id + ::std::identifier<char>, where identifier is + substitution_index[INDEX]. */ + +static inline int +is_std_substitution_char (const tree node, + const substitution_identifier_index_t index) +{ + tree args; + /* Check NODE's name is ::std::identifier. */ + if (!is_std_substitution (node, index)) + return 0; + /* Figure out its template args. */ + if (DECL_P (node)) + args = DECL_TI_ARGS (node); + else if (CLASS_TYPE_P (node)) + args = CLASSTYPE_TI_ARGS (node); + else + /* Oops, not a template. */ + return 0; + /* NODE's template arg list should be <char>. */ + return + TREE_VEC_LENGTH (args) == 1 + && TREE_VEC_ELT (args, 0) == char_type_node; +} + +/* Check whether a substitution should be used to represent NODE in + the mangling. + + First, check standard special-case substitutions. + + <substitution> ::= St + # ::std + + ::= Sa + # ::std::allocator + + ::= Sb + # ::std::basic_string + + ::= Ss + # ::std::basic_string<char, + ::std::char_traits<char>, + ::std::allocator<char> > + + ::= Si + # ::std::basic_istream<char, ::std::char_traits<char> > + + ::= So + # ::std::basic_ostream<char, ::std::char_traits<char> > + + ::= Sd + # ::std::basic_iostream<char, ::std::char_traits<char> > + + Then examine the stack of currently available substitution + candidates for entities appearing earlier in the same mangling + + If a substitution is found, write its mangled representation and + return nonzero. If none is found, just return zero. */ + +static int +find_substitution (tree node) +{ + int i; + const int size = vec_safe_length (G.substitutions); + tree decl; + tree type; + const char *abbr = NULL; + + if (DEBUG_MANGLE) + fprintf (stderr, " ++ find_substitution (%s at %p)\n", + get_tree_code_name (TREE_CODE (node)), (void *) node); + + /* Obtain the canonicalized substitution representation for NODE. + This is what we'll compare against. */ + node = canonicalize_for_substitution (node); + + /* Check for builtin substitutions. */ + + decl = TYPE_P (node) ? TYPE_NAME (node) : node; + type = TYPE_P (node) ? node : TREE_TYPE (node); + + /* Check for std::allocator. */ + if (decl + && is_std_substitution (decl, SUBID_ALLOCATOR) + && !CLASSTYPE_USE_TEMPLATE (TREE_TYPE (decl))) + abbr = "Sa"; + + /* Check for std::basic_string. */ + else if (decl && is_std_substitution (decl, SUBID_BASIC_STRING)) + { + if (TYPE_P (node)) + { + /* If this is a type (i.e. a fully-qualified template-id), + check for + std::basic_string <char, + std::char_traits<char>, + std::allocator<char> > . */ + if (cp_type_quals (type) == TYPE_UNQUALIFIED + && CLASSTYPE_USE_TEMPLATE (type)) + { + tree args = CLASSTYPE_TI_ARGS (type); + if (TREE_VEC_LENGTH (args) == 3 + && template_args_equal (TREE_VEC_ELT (args, 0), char_type_node) + && is_std_substitution_char (TREE_VEC_ELT (args, 1), + SUBID_CHAR_TRAITS) + && is_std_substitution_char (TREE_VEC_ELT (args, 2), + SUBID_ALLOCATOR)) + abbr = "Ss"; + } + } + else + /* Substitute for the template name only if this isn't a type. */ + abbr = "Sb"; + } + + /* Check for basic_{i,o,io}stream. */ + else if (TYPE_P (node) + && cp_type_quals (type) == TYPE_UNQUALIFIED + && CLASS_TYPE_P (type) + && CLASSTYPE_USE_TEMPLATE (type) + && CLASSTYPE_TEMPLATE_INFO (type) != NULL) + { + /* First, check for the template + args <char, std::char_traits<char> > . */ + tree args = CLASSTYPE_TI_ARGS (type); + if (TREE_VEC_LENGTH (args) == 2 + && template_args_equal (TREE_VEC_ELT (args, 0), char_type_node) + && is_std_substitution_char (TREE_VEC_ELT (args, 1), + SUBID_CHAR_TRAITS)) + { + /* Got them. Is this basic_istream? */ + if (is_std_substitution (decl, SUBID_BASIC_ISTREAM)) + abbr = "Si"; + /* Or basic_ostream? */ + else if (is_std_substitution (decl, SUBID_BASIC_OSTREAM)) + abbr = "So"; + /* Or basic_iostream? */ + else if (is_std_substitution (decl, SUBID_BASIC_IOSTREAM)) + abbr = "Sd"; + } + } + + /* Check for namespace std. */ + else if (decl && DECL_NAMESPACE_STD_P (decl)) + { + write_string ("St"); + return 1; + } + + tree tags = NULL_TREE; + if (OVERLOAD_TYPE_P (node) || DECL_CLASS_TEMPLATE_P (node)) + tags = get_abi_tags (type); + /* Now check the list of available substitutions for this mangling + operation. */ + if (!abbr || tags) for (i = 0; i < size; ++i) + { + tree candidate = (*G.substitutions)[i]; + /* NODE is a matched to a candidate if it's the same decl node or + if it's the same type. */ + if (decl == candidate + || (TYPE_P (candidate) && type && TYPE_P (node) + && same_type_p (type, candidate)) + || NESTED_TEMPLATE_MATCH (node, candidate)) + { + write_substitution (i); + return 1; + } + } + + if (!abbr) + /* No substitution found. */ + return 0; + + write_string (abbr); + if (tags) + { + /* If there are ABI tags on the abbreviation, it becomes + a substitution candidate. */ + write_abi_tags (tags); + add_substitution (node); + } + return 1; +} + +/* Returns whether DECL's symbol name should be the plain unqualified-id + rather than a more complicated mangled name. */ + +static bool +unmangled_name_p (const tree decl) +{ + if (TREE_CODE (decl) == FUNCTION_DECL) + { + /* The names of `extern "C"' functions are not mangled. */ + return (DECL_EXTERN_C_FUNCTION_P (decl) + /* But overloaded operator names *are* mangled. */ + && !DECL_OVERLOADED_OPERATOR_P (decl)); + } + else if (VAR_P (decl)) + { + /* static variables are mangled. */ + if (!DECL_EXTERNAL_LINKAGE_P (decl)) + return false; + + /* extern "C" declarations aren't mangled. */ + if (DECL_EXTERN_C_P (decl)) + return true; + + /* Other variables at non-global scope are mangled. */ + if (CP_DECL_CONTEXT (decl) != global_namespace) + return false; + + /* Variable template instantiations are mangled. */ + if (DECL_LANG_SPECIFIC (decl) && DECL_TEMPLATE_INFO (decl) + && variable_template_p (DECL_TI_TEMPLATE (decl))) + return false; + + /* Declarations with ABI tags are mangled. */ + if (get_abi_tags (decl)) + return false; + + /* The names of non-static global variables aren't mangled. */ + return true; + } + + return false; +} + +/* TOP_LEVEL is true, if this is being called at outermost level of + mangling. It should be false when mangling a decl appearing in an + expression within some other mangling. + + <mangled-name> ::= _Z <encoding> */ + +static void +write_mangled_name (const tree decl, bool top_level) +{ + MANGLE_TRACE_TREE ("mangled-name", decl); + + check_abi_tags (decl); + + if (unmangled_name_p (decl)) + { + if (top_level) + write_string (IDENTIFIER_POINTER (DECL_NAME (decl))); + else + { + /* The standard notes: "The <encoding> of an extern "C" + function is treated like global-scope data, i.e. as its + <source-name> without a type." We cannot write + overloaded operators that way though, because it contains + characters invalid in assembler. */ + write_string ("_Z"); + write_source_name (DECL_NAME (decl)); + } + } + else + { + write_string ("_Z"); + write_encoding (decl); + } +} + +/* Returns true if the return type of DECL is part of its signature, and + therefore its mangling. */ + +bool +mangle_return_type_p (tree decl) +{ + return (!DECL_CONSTRUCTOR_P (decl) + && !DECL_DESTRUCTOR_P (decl) + && !DECL_CONV_FN_P (decl) + && maybe_template_info (decl)); +} + +/* <encoding> ::= <function name> <bare-function-type> + ::= <data name> */ + +static void +write_encoding (const tree decl) +{ + MANGLE_TRACE_TREE ("encoding", decl); + + if (DECL_LANG_SPECIFIC (decl) && DECL_EXTERN_C_FUNCTION_P (decl)) + { + /* For overloaded operators write just the mangled name + without arguments. */ + if (DECL_OVERLOADED_OPERATOR_P (decl)) + write_name (decl, /*ignore_local_scope=*/0); + else + write_source_name (DECL_NAME (decl)); + return; + } + + write_name (decl, /*ignore_local_scope=*/0); + if (TREE_CODE (decl) == FUNCTION_DECL) + { + tree fn_type; + tree d; + + if (maybe_template_info (decl)) + { + fn_type = get_mostly_instantiated_function_type (decl); + /* FN_TYPE will not have parameter types for in-charge or + VTT parameters. Therefore, we pass NULL_TREE to + write_bare_function_type -- otherwise, it will get + confused about which artificial parameters to skip. */ + d = NULL_TREE; + } + else + { + fn_type = TREE_TYPE (decl); + d = decl; + } + + write_bare_function_type (fn_type, + mangle_return_type_p (decl), + d); + + /* If this is a coroutine helper, then append an appropriate string to + identify which. */ + if (tree ramp = DECL_RAMP_FN (decl)) + { + if (DECL_ACTOR_FN (ramp) == decl) + write_string (JOIN_STR "actor"); + else if (DECL_DESTROY_FN (ramp) == decl) + write_string (JOIN_STR "destroy"); + else + gcc_unreachable (); + } + } +} + +/* Interface to substitution and identifier mangling, used by the + module name mangler. */ + +void +mangle_module_substitution (int v) +{ + if (v < 10) + { + write_char ('_'); + write_char ('0' + v); + } + else + { + write_char ('W'); + write_unsigned_number (v - 10); + write_char ('_'); + } +} + +void +mangle_identifier (char c, tree id) +{ + if (c) + write_char (c); + write_source_name (id); +} + +/* If the outermost non-namespace context (including DECL itself) is + a module-linkage decl, mangle the module information. For module + global initializers we need to include the partition part. + + <module-name> ::= W <module-id>+ E + <module-id> :: <unqualified-name> + || _ <digit> ;; short backref + || W <number> _ ;; long backref + || P <module-id> ;; partition introducer +*/ + +static void +write_module (int m, bool include_partition) +{ + G.mod = true; + + write_char ('W'); + mangle_module (m, include_partition); + write_char ('E'); +} + +static void +maybe_write_module (tree decl) +{ + int m = get_originating_module (decl, true); + if (m >= 0) + write_module (m, false); +} + +/* Lambdas can have a bit more context for mangling, specifically VAR_DECL + or PARM_DECL context, which doesn't belong in DECL_CONTEXT. */ + +static tree +decl_mangling_context (tree decl) +{ + tree tcontext = targetm.cxx.decl_mangling_context (decl); + + if (tcontext != NULL_TREE) + return tcontext; + + if (TREE_CODE (decl) == TEMPLATE_DECL + && DECL_TEMPLATE_RESULT (decl)) + decl = DECL_TEMPLATE_RESULT (decl); + + if (TREE_CODE (decl) == TYPE_DECL + && LAMBDA_TYPE_P (TREE_TYPE (decl))) + { + tree extra = LAMBDA_TYPE_EXTRA_SCOPE (TREE_TYPE (decl)); + if (extra) + return extra; + } + else if (template_type_parameter_p (decl)) + /* template type parms have no mangling context. */ + return NULL_TREE; + + tcontext = CP_DECL_CONTEXT (decl); + + /* Ignore the artificial declare reduction functions. */ + if (tcontext + && TREE_CODE (tcontext) == FUNCTION_DECL + && DECL_OMP_DECLARE_REDUCTION_P (tcontext)) + return decl_mangling_context (tcontext); + + return tcontext; +} + +/* <name> ::= <unscoped-name> + ::= <unscoped-template-name> <template-args> + ::= <nested-name> + ::= <local-name> + + If IGNORE_LOCAL_SCOPE is nonzero, this production of <name> is + called from <local-name>, which mangles the enclosing scope + elsewhere and then uses this function to mangle just the part + underneath the function scope. So don't use the <local-name> + production, to avoid an infinite recursion. */ + +static void +write_name (tree decl, const int ignore_local_scope) +{ + tree context; + + MANGLE_TRACE_TREE ("name", decl); + + if (TREE_CODE (decl) == TYPE_DECL) + { + /* In case this is a typedef, fish out the corresponding + TYPE_DECL for the main variant. */ + decl = TYPE_NAME (TYPE_MAIN_VARIANT (TREE_TYPE (decl))); + } + + if (modules_p ()) + maybe_write_module (decl); + + context = decl_mangling_context (decl); + + gcc_assert (context != NULL_TREE); + + if (abi_warn_or_compat_version_crosses (7) + && ignore_local_scope + && TREE_CODE (context) == PARM_DECL) + G.need_abi_warning = 1; + + /* A decl in :: or ::std scope is treated specially. The former is + mangled using <unscoped-name> or <unscoped-template-name>, the + latter with a special substitution. Also, a name that is + directly in a local function scope is also mangled with + <unscoped-name> rather than a full <nested-name>. */ + if (context == global_namespace + || DECL_NAMESPACE_STD_P (context) + || (ignore_local_scope + && (TREE_CODE (context) == FUNCTION_DECL + || (abi_version_at_least (7) + && TREE_CODE (context) == PARM_DECL)))) + { + /* Is this a template instance? */ + if (tree info = maybe_template_info (decl)) + { + /* Yes: use <unscoped-template-name>. */ + write_unscoped_template_name (TI_TEMPLATE (info)); + write_template_args (TI_ARGS (info)); + } + else + /* Everything else gets an <unqualified-name>. */ + write_unscoped_name (decl); + } + else + { + /* Handle local names, unless we asked not to (that is, invoked + under <local-name>, to handle only the part of the name under + the local scope). */ + if (!ignore_local_scope) + { + /* Scan up the list of scope context, looking for a + function. If we find one, this entity is in local + function scope. local_entity tracks context one scope + level down, so it will contain the element that's + directly in that function's scope, either decl or one of + its enclosing scopes. */ + tree local_entity = decl; + while (context != global_namespace) + { + /* Make sure we're always dealing with decls. */ + if (TYPE_P (context)) + context = TYPE_NAME (context); + /* Is this a function? */ + if (TREE_CODE (context) == FUNCTION_DECL + || TREE_CODE (context) == PARM_DECL) + { + /* Yes, we have local scope. Use the <local-name> + production for the innermost function scope. */ + write_local_name (context, local_entity, decl); + return; + } + /* Up one scope level. */ + local_entity = context; + context = decl_mangling_context (context); + } + + /* No local scope found? Fall through to <nested-name>. */ + } + + /* Other decls get a <nested-name> to encode their scope. */ + write_nested_name (decl); + } +} + +/* <unscoped-name> ::= <unqualified-name> + ::= St <unqualified-name> # ::std:: */ + +static void +write_unscoped_name (const tree decl) +{ + tree context = decl_mangling_context (decl); + + MANGLE_TRACE_TREE ("unscoped-name", decl); + + /* Is DECL in ::std? */ + if (DECL_NAMESPACE_STD_P (context)) + { + write_string ("St"); + write_unqualified_name (decl); + } + else + { + /* If not, it should be either in the global namespace, or directly + in a local function scope. A lambda can also be mangled in the + scope of a default argument. */ + gcc_assert (context == global_namespace + || TREE_CODE (context) == PARM_DECL + || TREE_CODE (context) == FUNCTION_DECL); + + write_unqualified_name (decl); + } +} + +/* <unscoped-template-name> ::= <unscoped-name> + ::= <substitution> */ + +static void +write_unscoped_template_name (const tree decl) +{ + MANGLE_TRACE_TREE ("unscoped-template-name", decl); + + if (find_substitution (decl)) + return; + write_unscoped_name (decl); + add_substitution (decl); +} + +/* Write the nested name, including CV-qualifiers, of DECL. + + <nested-name> ::= N [<CV-qualifiers>] [<ref-qualifier>] <prefix> <unqualified-name> E + ::= N [<CV-qualifiers>] [<ref-qualifier>] <template-prefix> <template-args> E + + <ref-qualifier> ::= R # & ref-qualifier + ::= O # && ref-qualifier + <CV-qualifiers> ::= [r] [V] [K] */ + +static void +write_nested_name (const tree decl) +{ + MANGLE_TRACE_TREE ("nested-name", decl); + + write_char ('N'); + + /* Write CV-qualifiers, if this is a member function. */ + if (TREE_CODE (decl) == FUNCTION_DECL + && DECL_NONSTATIC_MEMBER_FUNCTION_P (decl)) + { + if (DECL_VOLATILE_MEMFUNC_P (decl)) + write_char ('V'); + if (DECL_CONST_MEMFUNC_P (decl)) + write_char ('K'); + if (FUNCTION_REF_QUALIFIED (TREE_TYPE (decl))) + { + if (FUNCTION_RVALUE_QUALIFIED (TREE_TYPE (decl))) + write_char ('O'); + else + write_char ('R'); + } + } + + /* Is this a template instance? */ + if (tree info = maybe_template_info (decl)) + { + /* Yes, use <template-prefix>. */ + write_template_prefix (decl); + write_template_args (TI_ARGS (info)); + } + else if ((!abi_version_at_least (10) || TREE_CODE (decl) == TYPE_DECL) + && TREE_CODE (TREE_TYPE (decl)) == TYPENAME_TYPE) + { + tree name = TYPENAME_TYPE_FULLNAME (TREE_TYPE (decl)); + if (TREE_CODE (name) == TEMPLATE_ID_EXPR) + { + write_template_prefix (decl); + write_template_args (TREE_OPERAND (name, 1)); + } + else + { + write_prefix (decl_mangling_context (decl)); + write_unqualified_name (decl); + } + } + else + { + /* No, just use <prefix> */ + write_prefix (decl_mangling_context (decl)); + write_unqualified_name (decl); + } + write_char ('E'); +} + +/* <prefix> ::= <prefix> <unqualified-name> + ::= <template-param> + ::= <template-prefix> <template-args> + ::= <decltype> + ::= # empty + ::= <substitution> */ + +static void +write_prefix (const tree node) +{ + tree decl; + + if (node == NULL + || node == global_namespace) + return; + + MANGLE_TRACE_TREE ("prefix", node); + + if (TREE_CODE (node) == DECLTYPE_TYPE) + { + write_type (node); + return; + } + + if (find_substitution (node)) + return; + + tree template_info = NULL_TREE; + if (DECL_P (node)) + { + /* If this is a function or parm decl, that means we've hit function + scope, so this prefix must be for a local name. In this + case, we're under the <local-name> production, which encodes + the enclosing function scope elsewhere. So don't continue + here. */ + if (TREE_CODE (node) == FUNCTION_DECL + || TREE_CODE (node) == PARM_DECL) + return; + + decl = node; + template_info = maybe_template_info (decl); + } + else + { + /* Node is a type. */ + decl = TYPE_NAME (node); + /* The DECL might not point at the node. */ + if (CLASSTYPE_TEMPLATE_ID_P (node)) + template_info = TYPE_TEMPLATE_INFO (node); + } + + if (TREE_CODE (node) == TEMPLATE_TYPE_PARM) + write_template_param (node); + else if (template_info) + /* Templated. */ + { + write_template_prefix (decl); + write_template_args (TI_ARGS (template_info)); + } + else if (TREE_CODE (TREE_TYPE (decl)) == TYPENAME_TYPE) + { + tree name = TYPENAME_TYPE_FULLNAME (TREE_TYPE (decl)); + if (TREE_CODE (name) == TEMPLATE_ID_EXPR) + { + write_template_prefix (decl); + write_template_args (TREE_OPERAND (name, 1)); + } + else + { + write_prefix (decl_mangling_context (decl)); + write_unqualified_name (decl); + } + } + else + /* Not templated. */ + { + write_prefix (decl_mangling_context (decl)); + write_unqualified_name (decl); + if (VAR_P (decl) + || TREE_CODE (decl) == FIELD_DECL) + { + /* <data-member-prefix> := <member source-name> M */ + write_char ('M'); + return; + } + } + + add_substitution (node); +} + +/* <template-prefix> ::= <prefix> <template component> + ::= <template-param> + ::= <substitution> */ + +static void +write_template_prefix (const tree node) +{ + tree decl = DECL_P (node) ? node : TYPE_NAME (node); + tree type = DECL_P (node) ? TREE_TYPE (node) : node; + tree context = decl_mangling_context (decl); + tree templ; + tree substitution; + + MANGLE_TRACE_TREE ("template-prefix", node); + + /* Find the template decl. */ + if (tree info = maybe_template_info (decl)) + templ = TI_TEMPLATE (info); + else if (TREE_CODE (type) == TYPENAME_TYPE) + /* For a typename type, all we have is the name. */ + templ = DECL_NAME (decl); + else + { + gcc_assert (CLASSTYPE_TEMPLATE_ID_P (type)); + + templ = TYPE_TI_TEMPLATE (type); + } + + /* For a member template, though, the template name for the + innermost name must have all the outer template levels + instantiated. For instance, consider + + template<typename T> struct Outer { + template<typename U> struct Inner {}; + }; + + The template name for `Inner' in `Outer<int>::Inner<float>' is + `Outer<int>::Inner<U>'. In g++, we don't instantiate the template + levels separately, so there's no TEMPLATE_DECL available for this + (there's only `Outer<T>::Inner<U>'). + + In order to get the substitutions right, we create a special + TREE_LIST to represent the substitution candidate for a nested + template. The TREE_PURPOSE is the template's context, fully + instantiated, and the TREE_VALUE is the TEMPLATE_DECL for the inner + template. + + So, for the example above, `Outer<int>::Inner' is represented as a + substitution candidate by a TREE_LIST whose purpose is `Outer<int>' + and whose value is `Outer<T>::Inner<U>'. */ + if (context && TYPE_P (context)) + substitution = build_tree_list (context, templ); + else + substitution = templ; + + if (find_substitution (substitution)) + return; + + if (TREE_TYPE (templ) + && TREE_CODE (TREE_TYPE (templ)) == TEMPLATE_TEMPLATE_PARM) + write_template_param (TREE_TYPE (templ)); + else + { + write_prefix (context); + write_unqualified_name (decl); + } + + add_substitution (substitution); +} + +/* As the list of identifiers for the structured binding declaration + DECL is likely gone, try to recover the DC <source-name>+ E portion + from its mangled name. Return pointer to the DC and set len to + the length up to and including the terminating E. On failure + return NULL. */ + +static const char * +find_decomp_unqualified_name (tree decl, size_t *len) +{ + const char *p = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)); + const char *end = p + IDENTIFIER_LENGTH (DECL_ASSEMBLER_NAME (decl)); + bool nested = false; + if (!startswith (p, "_Z")) + return NULL; + p += 2; + if (startswith (p, "St")) + p += 2; + else if (*p == 'N') + { + nested = true; + ++p; + while (ISDIGIT (p[0])) + { + char *e; + long num = strtol (p, &e, 10); + if (num >= 1 && num < end - e) + p = e + num; + else + break; + } + } + if (!startswith (p, "DC")) + return NULL; + if (nested) + { + if (end[-1] != 'E') + return NULL; + --end; + } + if (end[-1] != 'E') + return NULL; + *len = end - p; + return p; +} + +/* We don't need to handle thunks, vtables, or VTTs here. Those are + mangled through special entry points. + + <unqualified-name> ::= <operator-name> + ::= <special-name> + ::= <source-name> + ::= <unnamed-type-name> + ::= <local-source-name> + + <local-source-name> ::= L <source-name> <discriminator> */ + +static void +write_unqualified_id (tree identifier) +{ + if (IDENTIFIER_CONV_OP_P (identifier)) + write_conversion_operator_name (TREE_TYPE (identifier)); + else if (IDENTIFIER_OVL_OP_P (identifier)) + { + const ovl_op_info_t *ovl_op = IDENTIFIER_OVL_OP_INFO (identifier); + write_string (ovl_op->mangled_name); + } + else if (UDLIT_OPER_P (identifier)) + write_literal_operator_name (identifier); + else + write_source_name (identifier); +} + +static void +write_unqualified_name (tree decl) +{ + MANGLE_TRACE_TREE ("unqualified-name", decl); + + if (identifier_p (decl)) + { + write_unqualified_id (decl); + return; + } + + bool found = false; + + if (DECL_NAME (decl) == NULL_TREE) + { + found = true; + gcc_assert (DECL_ASSEMBLER_NAME_SET_P (decl)); + const char *decomp_str = NULL; + size_t decomp_len = 0; + if (VAR_P (decl) + && DECL_DECOMPOSITION_P (decl) + && DECL_NAME (decl) == NULL_TREE + && DECL_NAMESPACE_SCOPE_P (decl)) + decomp_str = find_decomp_unqualified_name (decl, &decomp_len); + if (decomp_str) + write_chars (decomp_str, decomp_len); + else + write_source_name (DECL_ASSEMBLER_NAME (decl)); + } + else if (DECL_DECLARES_FUNCTION_P (decl)) + { + found = true; + if (DECL_CONSTRUCTOR_P (decl)) + write_special_name_constructor (decl); + else if (DECL_DESTRUCTOR_P (decl)) + write_special_name_destructor (decl); + else if (DECL_CONV_FN_P (decl)) + { + /* Conversion operator. Handle it right here. + <operator> ::= cv <type> */ + tree type; + if (maybe_template_info (decl)) + { + tree fn_type; + fn_type = get_mostly_instantiated_function_type (decl); + type = TREE_TYPE (fn_type); + } + else if (FNDECL_USED_AUTO (decl)) + type = DECL_SAVED_AUTO_RETURN_TYPE (decl); + else + type = DECL_CONV_FN_TYPE (decl); + write_conversion_operator_name (type); + } + else if (DECL_OVERLOADED_OPERATOR_P (decl)) + { + tree t; + if (!(t = DECL_RAMP_FN (decl))) + t = decl; + const char *mangled_name + = (ovl_op_info[DECL_ASSIGNMENT_OPERATOR_P (t)] + [DECL_OVERLOADED_OPERATOR_CODE_RAW (t)].mangled_name); + write_string (mangled_name); + } + else if (UDLIT_OPER_P (DECL_NAME (decl))) + write_literal_operator_name (DECL_NAME (decl)); + else + found = false; + } + + if (found) + /* OK */; + else if (VAR_OR_FUNCTION_DECL_P (decl) && ! TREE_PUBLIC (decl) + && DECL_NAMESPACE_SCOPE_P (decl) + && decl_linkage (decl) == lk_internal) + { + MANGLE_TRACE_TREE ("local-source-name", decl); + write_char ('L'); + write_source_name (DECL_NAME (decl)); + /* The default discriminator is 1, and that's all we ever use, + so there's no code to output one here. */ + } + else + { + tree type = TREE_TYPE (decl); + + if (TREE_CODE (decl) == TYPE_DECL + && TYPE_UNNAMED_P (type)) + write_unnamed_type_name (type); + else if (TREE_CODE (decl) == TYPE_DECL && LAMBDA_TYPE_P (type)) + write_closure_type_name (type); + else + write_source_name (DECL_NAME (decl)); + } + + /* We use the ABI tags from the primary class template, ignoring tags on any + specializations. This is necessary because C++ doesn't require a + specialization to be declared before it is used unless the use requires a + complete type, but we need to get the tags right on incomplete types as + well. */ + if (tree tmpl = most_general_template (decl)) + { + tree res = DECL_TEMPLATE_RESULT (tmpl); + if (res == NULL_TREE) + /* UNBOUND_CLASS_TEMPLATE. */; + else if (DECL_DECLARES_TYPE_P (decl)) + decl = res; + else if (any_abi_below (11)) + { + /* ABI v10 implicit tags on the template. */ + tree mtags = missing_abi_tags (res); + /* Explicit tags on the template. */ + tree ttags = get_abi_tags (res); + /* Tags on the instantiation. */ + tree dtags = get_abi_tags (decl); + + if (mtags && abi_warn_or_compat_version_crosses (10)) + G.need_abi_warning = 1; + + /* Add the v10 tags to the explicit tags now. */ + mtags = chainon (mtags, ttags); + + if (!G.need_abi_warning + && abi_warn_or_compat_version_crosses (11) + && !equal_abi_tags (dtags, mtags)) + G.need_abi_warning = 1; + + if (!abi_version_at_least (10)) + /* In abi <10, we only got the explicit tags. */ + decl = res; + else if (flag_abi_version == 10) + { + /* In ABI 10, we want explict and implicit tags. */ + write_abi_tags (mtags); + return; + } + } + } + + tree tags = get_abi_tags (decl); + if (TREE_CODE (decl) == FUNCTION_DECL && DECL_CONV_FN_P (decl) + && any_abi_below (11)) + if (tree mtags = missing_abi_tags (decl)) + { + if (abi_warn_or_compat_version_crosses (11)) + G.need_abi_warning = true; + if (!abi_version_at_least (11)) + tags = chainon (mtags, tags); + } + write_abi_tags (tags); +} + +/* Write the unqualified-name for a conversion operator to TYPE. */ + +static void +write_conversion_operator_name (const tree type) +{ + write_string ("cv"); + write_type (type); +} + +/* Non-terminal <source-name>. IDENTIFIER is an IDENTIFIER_NODE. + + <source-name> ::= </length/ number> <identifier> */ + +static void +write_source_name (tree identifier) +{ + MANGLE_TRACE_TREE ("source-name", identifier); + + write_unsigned_number (IDENTIFIER_LENGTH (identifier)); + write_identifier (IDENTIFIER_POINTER (identifier)); +} + +/* Compare two TREE_STRINGs like strcmp. */ + +int +tree_string_cmp (const void *p1, const void *p2) +{ + if (p1 == p2) + return 0; + tree s1 = *(const tree*)p1; + tree s2 = *(const tree*)p2; + return strcmp (TREE_STRING_POINTER (s1), + TREE_STRING_POINTER (s2)); +} + +/* Return the TREE_LIST of TAGS as a sorted VEC. */ + +static vec<tree, va_gc> * +sorted_abi_tags (tree tags) +{ + vec<tree, va_gc> * vec = make_tree_vector(); + + for (tree t = tags; t; t = TREE_CHAIN (t)) + { + if (ABI_TAG_IMPLICIT (t)) + continue; + tree str = TREE_VALUE (t); + vec_safe_push (vec, str); + } + + vec->qsort (tree_string_cmp); + + return vec; +} + +/* ID is the name of a function or type with abi_tags attribute TAGS. + Write out the name, suitably decorated. */ + +static void +write_abi_tags (tree tags) +{ + if (tags == NULL_TREE) + return; + + vec<tree, va_gc> * vec = sorted_abi_tags (tags); + + unsigned i; tree str; + FOR_EACH_VEC_ELT (*vec, i, str) + { + write_string ("B"); + write_unsigned_number (TREE_STRING_LENGTH (str) - 1); + write_identifier (TREE_STRING_POINTER (str)); + } + + release_tree_vector (vec); +} + +/* True iff the TREE_LISTS T1 and T2 of ABI tags are equivalent. */ + +static bool +equal_abi_tags (tree t1, tree t2) +{ + releasing_vec v1 = sorted_abi_tags (t1); + releasing_vec v2 = sorted_abi_tags (t2); + + unsigned len1 = v1->length(); + if (len1 != v2->length()) + return false; + for (unsigned i = 0; i < len1; ++i) + if (tree_string_cmp (v1[i], v2[i]) != 0) + return false; + return true; +} + +/* Write a user-defined literal operator. + ::= li <source-name> # "" <source-name> + IDENTIFIER is an LITERAL_IDENTIFIER_NODE. */ + +static void +write_literal_operator_name (tree identifier) +{ + const char* suffix = UDLIT_OP_SUFFIX (identifier); + write_identifier (UDLIT_OP_MANGLED_PREFIX); + write_unsigned_number (strlen (suffix)); + write_identifier (suffix); +} + +/* Encode 0 as _, and 1+ as n-1_. */ + +static void +write_compact_number (int num) +{ + gcc_checking_assert (num >= 0); + if (num > 0) + write_unsigned_number (num - 1); + write_char ('_'); +} + +/* Return how many unnamed types precede TYPE in its enclosing class. */ + +static int +nested_anon_class_index (tree type) +{ + int index = 0; + tree member = TYPE_FIELDS (TYPE_CONTEXT (type)); + for (; member; member = DECL_CHAIN (member)) + if (DECL_IMPLICIT_TYPEDEF_P (member)) + { + tree memtype = TREE_TYPE (member); + if (memtype == type) + return index; + else if (TYPE_UNNAMED_P (memtype)) + ++index; + } + + if (seen_error ()) + return -1; + + gcc_unreachable (); +} + +/* <unnamed-type-name> ::= Ut [ <nonnegative number> ] _ */ + +static void +write_unnamed_type_name (const tree type) +{ + int discriminator; + MANGLE_TRACE_TREE ("unnamed-type-name", type); + + if (TYPE_FUNCTION_SCOPE_P (type)) + discriminator = discriminator_for_local_entity (TYPE_NAME (type)); + else if (TYPE_CLASS_SCOPE_P (type)) + discriminator = nested_anon_class_index (type); + else + { + gcc_assert (no_linkage_check (type, /*relaxed_p=*/true)); + /* Just use the old mangling at namespace scope. */ + write_source_name (TYPE_IDENTIFIER (type)); + return; + } + + write_string ("Ut"); + write_compact_number (discriminator); +} + +/* <closure-type-name> ::= Ul <lambda-sig> E [ <nonnegative number> ] _ + <lambda-sig> ::= <parameter type>+ # Parameter types or "v" if the lambda has no parameters */ + +static void +write_closure_type_name (const tree type) +{ + tree fn = lambda_function (type); + tree lambda = CLASSTYPE_LAMBDA_EXPR (type); + tree parms = TYPE_ARG_TYPES (TREE_TYPE (fn)); + + MANGLE_TRACE_TREE ("closure-type-name", type); + + write_string ("Ul"); + write_method_parms (parms, /*method_p=*/1, fn); + write_char ('E'); + write_compact_number (LAMBDA_EXPR_DISCRIMINATOR (lambda)); +} + +/* Convert NUMBER to ascii using base BASE and generating at least + MIN_DIGITS characters. BUFFER points to the _end_ of the buffer + into which to store the characters. Returns the number of + characters generated (these will be laid out in advance of where + BUFFER points). */ + +static int +hwint_to_ascii (unsigned HOST_WIDE_INT number, const unsigned int base, + char *buffer, const unsigned int min_digits) +{ + static const char base_digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + unsigned digits = 0; + + while (number) + { + unsigned HOST_WIDE_INT d = number / base; + + *--buffer = base_digits[number - d * base]; + digits++; + number = d; + } + while (digits < min_digits) + { + *--buffer = base_digits[0]; + digits++; + } + return digits; +} + +/* Non-terminal <number>. + + <number> ::= [n] </decimal integer/> */ + +static void +write_number (unsigned HOST_WIDE_INT number, const int unsigned_p, + const unsigned int base) +{ + char buffer[sizeof (HOST_WIDE_INT) * 8]; + unsigned count = 0; + + if (!unsigned_p && (HOST_WIDE_INT) number < 0) + { + write_char ('n'); + number = -((HOST_WIDE_INT) number); + } + count = hwint_to_ascii (number, base, buffer + sizeof (buffer), 1); + write_chars (buffer + sizeof (buffer) - count, count); +} + +/* Write out an integral CST in decimal. Most numbers are small, and + representable in a HOST_WIDE_INT. Occasionally we'll have numbers + bigger than that, which we must deal with. */ + +static inline void +write_integer_cst (const tree cst) +{ + int sign = tree_int_cst_sgn (cst); + widest_int abs_value = wi::abs (wi::to_widest (cst)); + if (!wi::fits_uhwi_p (abs_value)) + { + /* A bignum. We do this in chunks, each of which fits in a + HOST_WIDE_INT. */ + char buffer[sizeof (HOST_WIDE_INT) * 8 * 2]; + unsigned HOST_WIDE_INT chunk; + unsigned chunk_digits; + char *ptr = buffer + sizeof (buffer); + unsigned count = 0; + tree n, base, type; + int done; + + /* HOST_WIDE_INT must be at least 32 bits, so 10^9 is + representable. */ + chunk = 1000000000; + chunk_digits = 9; + + if (sizeof (HOST_WIDE_INT) >= 8) + { + /* It is at least 64 bits, so 10^18 is representable. */ + chunk_digits = 18; + chunk *= chunk; + } + + type = c_common_signed_or_unsigned_type (1, TREE_TYPE (cst)); + base = build_int_cstu (type, chunk); + n = wide_int_to_tree (type, wi::to_wide (cst)); + + if (sign < 0) + { + write_char ('n'); + n = fold_build1_loc (input_location, NEGATE_EXPR, type, n); + } + do + { + tree d = fold_build2_loc (input_location, FLOOR_DIV_EXPR, type, n, base); + tree tmp = fold_build2_loc (input_location, MULT_EXPR, type, d, base); + unsigned c; + + done = integer_zerop (d); + tmp = fold_build2_loc (input_location, MINUS_EXPR, type, n, tmp); + c = hwint_to_ascii (TREE_INT_CST_LOW (tmp), 10, ptr, + done ? 1 : chunk_digits); + ptr -= c; + count += c; + n = d; + } + while (!done); + write_chars (ptr, count); + } + else + { + /* A small num. */ + if (sign < 0) + write_char ('n'); + write_unsigned_number (abs_value.to_uhwi ()); + } +} + +/* Write out a floating-point literal. + + "Floating-point literals are encoded using the bit pattern of the + target processor's internal representation of that number, as a + fixed-length lowercase hexadecimal string, high-order bytes first + (even if the target processor would store low-order bytes first). + The "n" prefix is not used for floating-point literals; the sign + bit is encoded with the rest of the number. + + Here are some examples, assuming the IEEE standard representation + for floating point numbers. (Spaces are for readability, not + part of the encoding.) + + 1.0f Lf 3f80 0000 E + -1.0f Lf bf80 0000 E + 1.17549435e-38f Lf 0080 0000 E + 1.40129846e-45f Lf 0000 0001 E + 0.0f Lf 0000 0000 E" + + Caller is responsible for the Lx and the E. */ +static void +write_real_cst (const tree value) +{ + long target_real[4]; /* largest supported float */ + /* Buffer for eight hex digits in a 32-bit number but big enough + even for 64-bit long to avoid warnings. */ + char buffer[17]; + int i, limit, dir; + + tree type = TREE_TYPE (value); + int words = GET_MODE_BITSIZE (SCALAR_FLOAT_TYPE_MODE (type)) / 32; + + real_to_target (target_real, &TREE_REAL_CST (value), + TYPE_MODE (type)); + + /* The value in target_real is in the target word order, + so we must write it out backward if that happens to be + little-endian. write_number cannot be used, it will + produce uppercase. */ + if (FLOAT_WORDS_BIG_ENDIAN) + i = 0, limit = words, dir = 1; + else + i = words - 1, limit = -1, dir = -1; + + for (; i != limit; i += dir) + { + sprintf (buffer, "%08lx", (unsigned long) target_real[i]); + write_chars (buffer, 8); + } +} + +/* Non-terminal <identifier>. + + <identifier> ::= </unqualified source code identifier> */ + +static void +write_identifier (const char *identifier) +{ + MANGLE_TRACE ("identifier", identifier); + write_string (identifier); +} + +/* Handle constructor productions of non-terminal <special-name>. + CTOR is a constructor FUNCTION_DECL. + + <special-name> ::= C1 # complete object constructor + ::= C2 # base object constructor + ::= C3 # complete object allocating constructor + + Currently, allocating constructors are never used. */ + +static void +write_special_name_constructor (const tree ctor) +{ + write_char ('C'); + bool new_inh = (flag_new_inheriting_ctors + && DECL_INHERITED_CTOR (ctor)); + if (new_inh) + write_char ('I'); + if (DECL_BASE_CONSTRUCTOR_P (ctor)) + write_char ('2'); + /* This is the old-style "[unified]" constructor. + In some cases, we may emit this function and call + it from the clones in order to share code and save space. */ + else if (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (ctor)) + write_char ('4'); + else + { + gcc_assert (DECL_COMPLETE_CONSTRUCTOR_P (ctor)); + write_char ('1'); + } + if (new_inh) + write_type (DECL_INHERITED_CTOR_BASE (ctor)); +} + +/* Handle destructor productions of non-terminal <special-name>. + DTOR is a destructor FUNCTION_DECL. + + <special-name> ::= D0 # deleting (in-charge) destructor + ::= D1 # complete object (in-charge) destructor + ::= D2 # base object (not-in-charge) destructor */ + +static void +write_special_name_destructor (const tree dtor) +{ + if (DECL_DELETING_DESTRUCTOR_P (dtor)) + write_string ("D0"); + else if (DECL_BASE_DESTRUCTOR_P (dtor)) + write_string ("D2"); + else if (DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (dtor)) + /* This is the old-style "[unified]" destructor. + In some cases, we may emit this function and call + it from the clones in order to share code and save space. */ + write_string ("D4"); + else + { + gcc_assert (DECL_COMPLETE_DESTRUCTOR_P (dtor)); + write_string ("D1"); + } +} + +/* Return the discriminator for ENTITY appearing inside + FUNCTION. The discriminator is the lexical ordinal of VAR or TYPE among + entities with the same name and kind in the same FUNCTION. */ + +static int +discriminator_for_local_entity (tree entity) +{ + if (!DECL_LANG_SPECIFIC (entity)) + { + /* Some decls, like __FUNCTION__, don't need a discriminator. */ + gcc_checking_assert (DECL_ARTIFICIAL (entity)); + return 0; + } + else if (tree disc = DECL_DISCRIMINATOR (entity)) + return TREE_INT_CST_LOW (disc); + else + /* The first entity with a particular name doesn't get + DECL_DISCRIMINATOR set up. */ + return 0; +} + +/* Return the discriminator for STRING, a string literal used inside + FUNCTION. The discriminator is the lexical ordinal of STRING among + string literals used in FUNCTION. */ + +static int +discriminator_for_string_literal (tree /*function*/, + tree /*string*/) +{ + /* For now, we don't discriminate amongst string literals. */ + return 0; +} + +/* <discriminator> := _ <number> # when number < 10 + := __ <number> _ # when number >= 10 + + The discriminator is used only for the second and later occurrences + of the same name within a single function. In this case <number> is + n - 2, if this is the nth occurrence, in lexical order. */ + +static void +write_discriminator (const int discriminator) +{ + /* If discriminator is zero, don't write anything. Otherwise... */ + if (discriminator > 0) + { + write_char ('_'); + if (discriminator - 1 >= 10) + { + if (abi_warn_or_compat_version_crosses (11)) + G.need_abi_warning = 1; + if (abi_version_at_least (11)) + write_char ('_'); + } + write_unsigned_number (discriminator - 1); + if (abi_version_at_least (11) && discriminator - 1 >= 10) + write_char ('_'); + } +} + +/* Mangle the name of a function-scope entity. FUNCTION is the + FUNCTION_DECL for the enclosing function, or a PARM_DECL for lambdas in + default argument scope. ENTITY is the decl for the entity itself. + LOCAL_ENTITY is the entity that's directly scoped in FUNCTION_DECL, + either ENTITY itself or an enclosing scope of ENTITY. + + <local-name> := Z <function encoding> E <entity name> [<discriminator>] + := Z <function encoding> E s [<discriminator>] + := Z <function encoding> Ed [ <parameter number> ] _ <entity name> */ + +static void +write_local_name (tree function, const tree local_entity, + const tree entity) +{ + tree parm = NULL_TREE; + + MANGLE_TRACE_TREE ("local-name", entity); + + if (TREE_CODE (function) == PARM_DECL) + { + parm = function; + function = DECL_CONTEXT (parm); + } + + write_char ('Z'); + write_encoding (function); + write_char ('E'); + + /* For this purpose, parameters are numbered from right-to-left. */ + if (parm) + { + int i = list_length (parm); + write_char ('d'); + write_compact_number (i - 1); + } + + if (TREE_CODE (entity) == STRING_CST) + { + write_char ('s'); + write_discriminator (discriminator_for_string_literal (function, + entity)); + } + else + { + /* Now the <entity name>. Let write_name know its being called + from <local-name>, so it doesn't try to process the enclosing + function scope again. */ + write_name (entity, /*ignore_local_scope=*/1); + if (DECL_DISCRIMINATOR_P (local_entity) + && !(TREE_CODE (local_entity) == TYPE_DECL + && TYPE_ANON_P (TREE_TYPE (local_entity)))) + write_discriminator (discriminator_for_local_entity (local_entity)); + } +} + +/* Non-terminals <type> and <CV-qualifier>. + + <type> ::= <builtin-type> + ::= <function-type> + ::= <class-enum-type> + ::= <array-type> + ::= <pointer-to-member-type> + ::= <template-param> + ::= <substitution> + ::= <CV-qualifier> + ::= P <type> # pointer-to + ::= R <type> # reference-to + ::= C <type> # complex pair (C 2000) + ::= G <type> # imaginary (C 2000) [not supported] + ::= U <source-name> <type> # vendor extended type qualifier + + C++0x extensions + + <type> ::= RR <type> # rvalue reference-to + <type> ::= Dt <expression> # decltype of an id-expression or + # class member access + <type> ::= DT <expression> # decltype of an expression + <type> ::= Dn # decltype of nullptr + + TYPE is a type node. */ + +static void +write_type (tree type) +{ + /* This gets set to nonzero if TYPE turns out to be a (possibly + CV-qualified) builtin type. */ + int is_builtin_type = 0; + + MANGLE_TRACE_TREE ("type", type); + + if (type == error_mark_node) + return; + + type = canonicalize_for_substitution (type); + if (find_substitution (type)) + return; + + + if (write_CV_qualifiers_for_type (type) > 0) + /* If TYPE was CV-qualified, we just wrote the qualifiers; now + mangle the unqualified type. The recursive call is needed here + since both the qualified and unqualified types are substitution + candidates. */ + { + tree t = TYPE_MAIN_VARIANT (type); + if (TYPE_ATTRIBUTES (t) && !OVERLOAD_TYPE_P (t)) + { + tree attrs = NULL_TREE; + if (tx_safe_fn_type_p (type)) + attrs = tree_cons (get_identifier ("transaction_safe"), + NULL_TREE, attrs); + t = cp_build_type_attribute_variant (t, attrs); + } + gcc_assert (t != type); + if (FUNC_OR_METHOD_TYPE_P (t)) + { + t = build_ref_qualified_type (t, type_memfn_rqual (type)); + if (flag_noexcept_type) + { + tree r = TYPE_RAISES_EXCEPTIONS (type); + t = build_exception_variant (t, r); + } + if (abi_version_at_least (8) + || type == TYPE_MAIN_VARIANT (type)) + /* Avoid adding the unqualified function type as a substitution. */ + write_function_type (t); + else + write_type (t); + if (abi_warn_or_compat_version_crosses (8)) + G.need_abi_warning = 1; + } + else + write_type (t); + } + else if (TREE_CODE (type) == ARRAY_TYPE) + /* It is important not to use the TYPE_MAIN_VARIANT of TYPE here + so that the cv-qualification of the element type is available + in write_array_type. */ + write_array_type (type); + else + { + tree type_orig = type; + + /* See through any typedefs. */ + type = TYPE_MAIN_VARIANT (type); + if (FUNC_OR_METHOD_TYPE_P (type)) + type = cxx_copy_lang_qualifiers (type, type_orig); + + /* According to the C++ ABI, some library classes are passed the + same as the scalar type of their single member and use the same + mangling. */ + if (TREE_CODE (type) == RECORD_TYPE && TYPE_TRANSPARENT_AGGR (type)) + type = TREE_TYPE (first_field (type)); + + if (TYPE_PTRDATAMEM_P (type)) + write_pointer_to_member_type (type); + else + { + /* Handle any target-specific fundamental types. */ + const char *target_mangling + = targetm.mangle_type (type_orig); + + if (target_mangling) + { + write_string (target_mangling); + /* Add substitutions for types other than fundamental + types. */ + if (!VOID_TYPE_P (type) + && TREE_CODE (type) != INTEGER_TYPE + && TREE_CODE (type) != REAL_TYPE + && TREE_CODE (type) != BOOLEAN_TYPE) + add_substitution (type); + return; + } + + switch (TREE_CODE (type)) + { + case VOID_TYPE: + case BOOLEAN_TYPE: + case INTEGER_TYPE: /* Includes wchar_t. */ + case REAL_TYPE: + case FIXED_POINT_TYPE: + { + /* If this is a typedef, TYPE may not be one of + the standard builtin type nodes, but an alias of one. Use + TYPE_MAIN_VARIANT to get to the underlying builtin type. */ + write_builtin_type (TYPE_MAIN_VARIANT (type)); + ++is_builtin_type; + } + break; + + case COMPLEX_TYPE: + write_char ('C'); + write_type (TREE_TYPE (type)); + break; + + case FUNCTION_TYPE: + case METHOD_TYPE: + write_function_type (type); + break; + + case UNION_TYPE: + case RECORD_TYPE: + case ENUMERAL_TYPE: + /* A pointer-to-member function is represented as a special + RECORD_TYPE, so check for this first. */ + if (TYPE_PTRMEMFUNC_P (type)) + write_pointer_to_member_type (type); + else + write_class_enum_type (type); + break; + + case TYPENAME_TYPE: + case UNBOUND_CLASS_TEMPLATE: + /* We handle TYPENAME_TYPEs and UNBOUND_CLASS_TEMPLATEs like + ordinary nested names. */ + write_nested_name (TYPE_STUB_DECL (type)); + break; + + case POINTER_TYPE: + case REFERENCE_TYPE: + if (TYPE_PTR_P (type)) + write_char ('P'); + else if (TYPE_REF_IS_RVALUE (type)) + write_char ('O'); + else + write_char ('R'); + { + tree target = TREE_TYPE (type); + /* Attribute const/noreturn are not reflected in mangling. + We strip them here rather than at a lower level because + a typedef or template argument can have function type + with function-cv-quals (that use the same representation), + but you can't have a pointer/reference to such a type. */ + if (TREE_CODE (target) == FUNCTION_TYPE) + { + if (abi_warn_or_compat_version_crosses (5) + && TYPE_QUALS (target) != TYPE_UNQUALIFIED) + G.need_abi_warning = 1; + if (abi_version_at_least (5)) + target = build_qualified_type (target, TYPE_UNQUALIFIED); + } + write_type (target); + } + break; + + case TEMPLATE_TYPE_PARM: + if (is_auto (type)) + { + if (AUTO_IS_DECLTYPE (type)) + write_identifier ("Dc"); + else + write_identifier ("Da"); + ++is_builtin_type; + break; + } + /* fall through. */ + case TEMPLATE_PARM_INDEX: + write_template_param (type); + break; + + case TEMPLATE_TEMPLATE_PARM: + write_template_template_param (type); + break; + + case BOUND_TEMPLATE_TEMPLATE_PARM: + write_template_template_param (type); + write_template_args + (TI_ARGS (TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (type))); + break; + + case VECTOR_TYPE: + if (abi_version_at_least (4)) + { + write_string ("Dv"); + /* Non-constant vector size would be encoded with + _ expression, but we don't support that yet. */ + write_unsigned_number (TYPE_VECTOR_SUBPARTS (type) + .to_constant ()); + write_char ('_'); + } + else + write_string ("U8__vector"); + if (abi_warn_or_compat_version_crosses (4)) + G.need_abi_warning = 1; + write_type (TREE_TYPE (type)); + break; + + case TYPE_PACK_EXPANSION: + write_string ("Dp"); + write_type (PACK_EXPANSION_PATTERN (type)); + break; + + case DECLTYPE_TYPE: + /* These shouldn't make it into mangling. */ + gcc_assert (!DECLTYPE_FOR_LAMBDA_CAPTURE (type) + && !DECLTYPE_FOR_LAMBDA_PROXY (type)); + + /* In ABI <5, we stripped decltype of a plain decl. */ + if (DECLTYPE_TYPE_ID_EXPR_OR_MEMBER_ACCESS_P (type)) + { + tree expr = DECLTYPE_TYPE_EXPR (type); + tree etype = NULL_TREE; + switch (TREE_CODE (expr)) + { + case VAR_DECL: + case PARM_DECL: + case RESULT_DECL: + case FUNCTION_DECL: + case CONST_DECL: + case TEMPLATE_PARM_INDEX: + etype = TREE_TYPE (expr); + break; + + default: + break; + } + + if (etype && !type_uses_auto (etype)) + { + if (abi_warn_or_compat_version_crosses (5)) + G.need_abi_warning = 1; + if (!abi_version_at_least (5)) + { + write_type (etype); + return; + } + } + } + + write_char ('D'); + if (DECLTYPE_TYPE_ID_EXPR_OR_MEMBER_ACCESS_P (type)) + write_char ('t'); + else + write_char ('T'); + ++cp_unevaluated_operand; + write_expression (DECLTYPE_TYPE_EXPR (type)); + --cp_unevaluated_operand; + write_char ('E'); + break; + + case NULLPTR_TYPE: + write_string ("Dn"); + if (abi_version_at_least (7)) + ++is_builtin_type; + if (abi_warn_or_compat_version_crosses (7)) + G.need_abi_warning = 1; + break; + + case TYPEOF_TYPE: + sorry ("mangling %<typeof%>, use %<decltype%> instead"); + break; + + case UNDERLYING_TYPE: + sorry ("mangling %<__underlying_type%>"); + break; + + case LANG_TYPE: + /* fall through. */ + + default: + gcc_unreachable (); + } + } + } + + /* Types other than builtin types are substitution candidates. */ + if (!is_builtin_type) + add_substitution (type); +} + +/* qsort callback for sorting a vector of attribute entries. */ + +static int +attr_strcmp (const void *p1, const void *p2) +{ + tree a1 = *(const tree*)p1; + tree a2 = *(const tree*)p2; + + const attribute_spec *as1 = lookup_attribute_spec (get_attribute_name (a1)); + const attribute_spec *as2 = lookup_attribute_spec (get_attribute_name (a2)); + + return strcmp (as1->name, as2->name); +} + +/* Return true if we should mangle a type attribute with name NAME. */ + +static bool +mangle_type_attribute_p (tree name) +{ + const attribute_spec *as = lookup_attribute_spec (name); + if (!as || !as->affects_type_identity) + return false; + + /* Skip internal-only attributes, which are distinguished from others + by having a space. At present, all internal-only attributes that + affect type identity are target-specific and are handled by + targetm.mangle_type instead. + + Another reason to do this is that a space isn't a valid identifier + character for most file formats. */ + if (strchr (IDENTIFIER_POINTER (name), ' ')) + return false; + + /* The following attributes are mangled specially. */ + if (is_attribute_p ("transaction_safe", name)) + return false; + if (is_attribute_p ("abi_tag", name)) + return false; + + return true; +} + +/* Non-terminal <CV-qualifiers> for type nodes. Returns the number of + CV-qualifiers written for TYPE. + + <CV-qualifiers> ::= [r] [V] [K] */ + +static int +write_CV_qualifiers_for_type (const tree type) +{ + int num_qualifiers = 0; + + /* The order is specified by: + + "In cases where multiple order-insensitive qualifiers are + present, they should be ordered 'K' (closest to the base type), + 'V', 'r', and 'U' (farthest from the base type) ..." */ + + /* Mangle attributes that affect type identity as extended qualifiers. + + We don't do this with classes and enums because their attributes + are part of their definitions, not something added on. */ + + if (!OVERLOAD_TYPE_P (type)) + { + auto_vec<tree> vec; + for (tree a = TYPE_ATTRIBUTES (type); a; a = TREE_CHAIN (a)) + if (mangle_type_attribute_p (get_attribute_name (a))) + vec.safe_push (a); + if (abi_warn_or_compat_version_crosses (10) && !vec.is_empty ()) + G.need_abi_warning = true; + if (abi_version_at_least (10)) + { + vec.qsort (attr_strcmp); + while (!vec.is_empty()) + { + tree a = vec.pop(); + const attribute_spec *as + = lookup_attribute_spec (get_attribute_name (a)); + + write_char ('U'); + write_unsigned_number (strlen (as->name)); + write_string (as->name); + if (TREE_VALUE (a)) + { + write_char ('I'); + for (tree args = TREE_VALUE (a); args; + args = TREE_CHAIN (args)) + { + tree arg = TREE_VALUE (args); + write_template_arg (arg); + } + write_char ('E'); + } + + ++num_qualifiers; + } + } + } + + /* Note that we do not use cp_type_quals below; given "const + int[3]", the "const" is emitted with the "int", not with the + array. */ + cp_cv_quals quals = TYPE_QUALS (type); + + if (quals & TYPE_QUAL_RESTRICT) + { + write_char ('r'); + ++num_qualifiers; + } + if (quals & TYPE_QUAL_VOLATILE) + { + write_char ('V'); + ++num_qualifiers; + } + if (quals & TYPE_QUAL_CONST) + { + write_char ('K'); + ++num_qualifiers; + } + + return num_qualifiers; +} + +/* Non-terminal <builtin-type>. + + <builtin-type> ::= v # void + ::= b # bool + ::= w # wchar_t + ::= c # char + ::= a # signed char + ::= h # unsigned char + ::= s # short + ::= t # unsigned short + ::= i # int + ::= j # unsigned int + ::= l # long + ::= m # unsigned long + ::= x # long long, __int64 + ::= y # unsigned long long, __int64 + ::= n # __int128 + ::= o # unsigned __int128 + ::= f # float + ::= d # double + ::= e # long double, __float80 + ::= g # __float128 [not supported] + ::= u <source-name> # vendor extended type */ + +static void +write_builtin_type (tree type) +{ + if (TYPE_CANONICAL (type)) + type = TYPE_CANONICAL (type); + + switch (TREE_CODE (type)) + { + case VOID_TYPE: + write_char ('v'); + break; + + case BOOLEAN_TYPE: + write_char ('b'); + break; + + case INTEGER_TYPE: + /* TYPE may still be wchar_t, char8_t, char16_t, or char32_t, since that + isn't in integer_type_nodes. */ + if (type == wchar_type_node) + write_char ('w'); + else if (type == char8_type_node) + write_string ("Du"); + else if (type == char16_type_node) + write_string ("Ds"); + else if (type == char32_type_node) + write_string ("Di"); + else + { + size_t itk; + /* Assume TYPE is one of the shared integer type nodes. Find + it in the array of these nodes. */ + iagain: + for (itk = 0; itk < itk_none; ++itk) + if (integer_types[itk] != NULL_TREE + && integer_type_codes[itk] != '\0' + && type == integer_types[itk]) + { + /* Print the corresponding single-letter code. */ + write_char (integer_type_codes[itk]); + break; + } + + if (itk == itk_none) + { + tree t = c_common_type_for_mode (TYPE_MODE (type), + TYPE_UNSIGNED (type)); + if (type != t) + { + type = t; + goto iagain; + } + + if (TYPE_PRECISION (type) == 128) + write_char (TYPE_UNSIGNED (type) ? 'o' : 'n'); + else + { + /* Allow for cases where TYPE is not one of the shared + integer type nodes and write a "vendor extended builtin + type" with a name the form intN or uintN, respectively. + Situations like this can happen if you have an + __attribute__((__mode__(__SI__))) type and use exotic + switches like '-mint8' on AVR. Of course, this is + undefined by the C++ ABI (and '-mint8' is not even + Standard C conforming), but when using such special + options you're pretty much in nowhere land anyway. */ + const char *prefix; + char prec[11]; /* up to ten digits for an unsigned */ + + prefix = TYPE_UNSIGNED (type) ? "uint" : "int"; + sprintf (prec, "%u", (unsigned) TYPE_PRECISION (type)); + write_char ('u'); /* "vendor extended builtin type" */ + write_unsigned_number (strlen (prefix) + strlen (prec)); + write_string (prefix); + write_string (prec); + } + } + } + break; + + case REAL_TYPE: + if (type == float_type_node) + write_char ('f'); + else if (type == double_type_node) + write_char ('d'); + else if (type == long_double_type_node) + write_char ('e'); + else if (type == dfloat32_type_node || type == fallback_dfloat32_type) + write_string ("Df"); + else if (type == dfloat64_type_node || type == fallback_dfloat64_type) + write_string ("Dd"); + else if (type == dfloat128_type_node || type == fallback_dfloat128_type) + write_string ("De"); + else + gcc_unreachable (); + break; + + case FIXED_POINT_TYPE: + write_string ("DF"); + if (GET_MODE_IBIT (TYPE_MODE (type)) > 0) + write_unsigned_number (GET_MODE_IBIT (TYPE_MODE (type))); + if (type == fract_type_node + || type == sat_fract_type_node + || type == accum_type_node + || type == sat_accum_type_node) + write_char ('i'); + else if (type == unsigned_fract_type_node + || type == sat_unsigned_fract_type_node + || type == unsigned_accum_type_node + || type == sat_unsigned_accum_type_node) + write_char ('j'); + else if (type == short_fract_type_node + || type == sat_short_fract_type_node + || type == short_accum_type_node + || type == sat_short_accum_type_node) + write_char ('s'); + else if (type == unsigned_short_fract_type_node + || type == sat_unsigned_short_fract_type_node + || type == unsigned_short_accum_type_node + || type == sat_unsigned_short_accum_type_node) + write_char ('t'); + else if (type == long_fract_type_node + || type == sat_long_fract_type_node + || type == long_accum_type_node + || type == sat_long_accum_type_node) + write_char ('l'); + else if (type == unsigned_long_fract_type_node + || type == sat_unsigned_long_fract_type_node + || type == unsigned_long_accum_type_node + || type == sat_unsigned_long_accum_type_node) + write_char ('m'); + else if (type == long_long_fract_type_node + || type == sat_long_long_fract_type_node + || type == long_long_accum_type_node + || type == sat_long_long_accum_type_node) + write_char ('x'); + else if (type == unsigned_long_long_fract_type_node + || type == sat_unsigned_long_long_fract_type_node + || type == unsigned_long_long_accum_type_node + || type == sat_unsigned_long_long_accum_type_node) + write_char ('y'); + else + sorry ("mangling unknown fixed point type"); + write_unsigned_number (GET_MODE_FBIT (TYPE_MODE (type))); + if (TYPE_SATURATING (type)) + write_char ('s'); + else + write_char ('n'); + break; + + default: + gcc_unreachable (); + } +} + +/* Non-terminal <function-type>. NODE is a FUNCTION_TYPE or + METHOD_TYPE. The return type is mangled before the parameter + types. + + <function-type> ::= F [Y] <bare-function-type> [<ref-qualifier>] E */ + +static void +write_function_type (const tree type) +{ + MANGLE_TRACE_TREE ("function-type", type); + + /* For a pointer to member function, the function type may have + cv-qualifiers, indicating the quals for the artificial 'this' + parameter. */ + if (TREE_CODE (type) == METHOD_TYPE) + { + /* The first parameter must be a POINTER_TYPE pointing to the + `this' parameter. */ + tree this_type = class_of_this_parm (type); + write_CV_qualifiers_for_type (this_type); + } + + write_exception_spec (TYPE_RAISES_EXCEPTIONS (type)); + + if (tx_safe_fn_type_p (type)) + write_string ("Dx"); + + write_char ('F'); + /* We don't track whether or not a type is `extern "C"'. Note that + you can have an `extern "C"' function that does not have + `extern "C"' type, and vice versa: + + extern "C" typedef void function_t(); + function_t f; // f has C++ linkage, but its type is + // `extern "C"' + + typedef void function_t(); + extern "C" function_t f; // Vice versa. + + See [dcl.link]. */ + write_bare_function_type (type, /*include_return_type_p=*/1, + /*decl=*/NULL); + if (FUNCTION_REF_QUALIFIED (type)) + { + if (FUNCTION_RVALUE_QUALIFIED (type)) + write_char ('O'); + else + write_char ('R'); + } + write_char ('E'); +} + +/* Non-terminal <bare-function-type>. TYPE is a FUNCTION_TYPE or + METHOD_TYPE. If INCLUDE_RETURN_TYPE is nonzero, the return value + is mangled before the parameter types. If non-NULL, DECL is + FUNCTION_DECL for the function whose type is being emitted. */ + +static void +write_bare_function_type (const tree type, const int include_return_type_p, + const tree decl) +{ + MANGLE_TRACE_TREE ("bare-function-type", type); + + /* Mangle the return type, if requested. */ + if (include_return_type_p) + write_type (TREE_TYPE (type)); + + /* Now mangle the types of the arguments. */ + ++G.parm_depth; + write_method_parms (TYPE_ARG_TYPES (type), + TREE_CODE (type) == METHOD_TYPE, + decl); + --G.parm_depth; +} + +/* Write the mangled representation of a method parameter list of + types given in PARM_TYPES. If METHOD_P is nonzero, the function is + considered a non-static method, and the this parameter is omitted. + If non-NULL, DECL is the FUNCTION_DECL for the function whose + parameters are being emitted. */ + +static void +write_method_parms (tree parm_types, const int method_p, const tree decl) +{ + tree first_parm_type; + tree parm_decl = decl ? DECL_ARGUMENTS (decl) : NULL_TREE; + + /* Assume this parameter type list is variable-length. If it ends + with a void type, then it's not. */ + int varargs_p = 1; + + /* If this is a member function, skip the first arg, which is the + this pointer. + "Member functions do not encode the type of their implicit this + parameter." + + Similarly, there's no need to mangle artificial parameters, like + the VTT parameters for constructors and destructors. */ + if (method_p) + { + parm_types = TREE_CHAIN (parm_types); + parm_decl = parm_decl ? DECL_CHAIN (parm_decl) : NULL_TREE; + + while (parm_decl && DECL_ARTIFICIAL (parm_decl)) + { + parm_types = TREE_CHAIN (parm_types); + parm_decl = DECL_CHAIN (parm_decl); + } + + if (decl && ctor_omit_inherited_parms (decl)) + /* Bring back parameters omitted from an inherited ctor. */ + parm_types = FUNCTION_FIRST_USER_PARMTYPE (DECL_ORIGIN (decl)); + } + + for (first_parm_type = parm_types; + parm_types; + parm_types = TREE_CHAIN (parm_types)) + { + tree parm = TREE_VALUE (parm_types); + if (parm == void_type_node) + { + /* "Empty parameter lists, whether declared as () or + conventionally as (void), are encoded with a void parameter + (v)." */ + if (parm_types == first_parm_type) + write_type (parm); + /* If the parm list is terminated with a void type, it's + fixed-length. */ + varargs_p = 0; + /* A void type better be the last one. */ + gcc_assert (TREE_CHAIN (parm_types) == NULL); + } + else + write_type (parm); + } + + if (varargs_p) + /* <builtin-type> ::= z # ellipsis */ + write_char ('z'); +} + +/* <class-enum-type> ::= <name> */ + +static void +write_class_enum_type (const tree type) +{ + write_name (TYPE_NAME (type), /*ignore_local_scope=*/0); +} + +/* Non-terminal <template-args>. ARGS is a TREE_VEC of template + arguments. + + <template-args> ::= I <template-arg>* E */ + +static void +write_template_args (tree args) +{ + int i; + int length = 0; + + MANGLE_TRACE_TREE ("template-args", args); + + write_char ('I'); + + if (args) + length = TREE_VEC_LENGTH (args); + + if (args && length && TREE_CODE (TREE_VEC_ELT (args, 0)) == TREE_VEC) + { + /* We have nested template args. We want the innermost template + argument list. */ + args = TREE_VEC_ELT (args, length - 1); + length = TREE_VEC_LENGTH (args); + } + for (i = 0; i < length; ++i) + write_template_arg (TREE_VEC_ELT (args, i)); + + write_char ('E'); +} + +/* Write out the + <unqualified-name> + <unqualified-name> <template-args> + part of SCOPE_REF or COMPONENT_REF mangling. */ + +static void +write_member_name (tree member) +{ + if (identifier_p (member)) + { + if (IDENTIFIER_ANY_OP_P (member)) + { + if (abi_version_at_least (11)) + write_string ("on"); + if (abi_warn_or_compat_version_crosses (11)) + G.need_abi_warning = 1; + } + write_unqualified_id (member); + } + else if (DECL_P (member)) + { + gcc_assert (!DECL_OVERLOADED_OPERATOR_P (member)); + write_unqualified_name (member); + } + else if (TREE_CODE (member) == TEMPLATE_ID_EXPR) + { + tree name = TREE_OPERAND (member, 0); + name = OVL_FIRST (name); + write_member_name (name); + write_template_args (TREE_OPERAND (member, 1)); + } + else + write_expression (member); +} + +/* EXPR is a base COMPONENT_REF; write the minimized base conversion path for + converting to BASE, or just the conversion of EXPR if BASE is null. + + "Given a fully explicit base path P := C_n -> ... -> C_0, the minimized base + path Min(P) is defined as follows: let C_i be the last element for which the + conversion to C_0 is unambiguous; if that element is C_n, the minimized path + is C_n -> C_0; otherwise, the minimized path is Min(C_n -> ... -> C_i) -> + C_0." + + We mangle the conversion to C_i if it's different from C_n. */ + +static bool +write_base_ref (tree expr, tree base = NULL_TREE) +{ + if (TREE_CODE (expr) != COMPONENT_REF) + return false; + + tree field = TREE_OPERAND (expr, 1); + + if (TREE_CODE (field) != FIELD_DECL || !DECL_FIELD_IS_BASE (field)) + return false; + + tree object = TREE_OPERAND (expr, 0); + + tree binfo = NULL_TREE; + if (base) + { + tree cur = TREE_TYPE (object); + binfo = lookup_base (cur, base, ba_unique, NULL, tf_none); + } + else + /* We're at the end of the base conversion chain, so it can't be + ambiguous. */ + base = TREE_TYPE (field); + + if (binfo == error_mark_node) + { + /* cur->base is ambiguous, so make the conversion to + last explicit, expressed as a cast (last&)object. */ + tree last = TREE_TYPE (expr); + write_string (OVL_OP_INFO (false, CAST_EXPR)->mangled_name); + write_type (build_reference_type (last)); + write_expression (object); + } + else if (write_base_ref (object, base)) + /* cur->base is unambiguous, but we had another base conversion + underneath and wrote it out. */; + else + /* No more base conversions, just write out the object. */ + write_expression (object); + + return true; +} + +/* The number of elements spanned by a RANGE_EXPR. */ + +unsigned HOST_WIDE_INT +range_expr_nelts (tree expr) +{ + tree lo = TREE_OPERAND (expr, 0); + tree hi = TREE_OPERAND (expr, 1); + return tree_to_uhwi (hi) - tree_to_uhwi (lo) + 1; +} + +/* <expression> ::= <unary operator-name> <expression> + ::= <binary operator-name> <expression> <expression> + ::= <expr-primary> + + <expr-primary> ::= <template-param> + ::= L <type> <value number> E # literal + ::= L <mangled-name> E # external name + ::= st <type> # sizeof + ::= sr <type> <unqualified-name> # dependent name + ::= sr <type> <unqualified-name> <template-args> */ + +static void +write_expression (tree expr) +{ + enum tree_code code = TREE_CODE (expr); + + if (TREE_CODE (expr) == TARGET_EXPR) + { + expr = TARGET_EXPR_INITIAL (expr); + code = TREE_CODE (expr); + } + + /* Skip NOP_EXPR and CONVERT_EXPR. They can occur when (say) a pointer + argument is converted (via qualification conversions) to another type. */ + while (CONVERT_EXPR_CODE_P (code) + || code == IMPLICIT_CONV_EXPR + || location_wrapper_p (expr) + /* Parentheses aren't mangled. */ + || code == PAREN_EXPR + || code == NON_LVALUE_EXPR + || (code == VIEW_CONVERT_EXPR + && TREE_CODE (TREE_OPERAND (expr, 0)) == TEMPLATE_PARM_INDEX)) + { + expr = TREE_OPERAND (expr, 0); + code = TREE_CODE (expr); + } + + if (code == BASELINK + && (!type_unknown_p (expr) + || !BASELINK_QUALIFIED_P (expr))) + { + expr = BASELINK_FUNCTIONS (expr); + code = TREE_CODE (expr); + } + + /* Handle pointers-to-members by making them look like expression + nodes. */ + if (code == PTRMEM_CST) + { + expr = build_nt (ADDR_EXPR, + build_qualified_name (/*type=*/NULL_TREE, + PTRMEM_CST_CLASS (expr), + PTRMEM_CST_MEMBER (expr), + /*template_p=*/false)); + code = TREE_CODE (expr); + } + + /* Handle template parameters. */ + if (code == TEMPLATE_TYPE_PARM + || code == TEMPLATE_TEMPLATE_PARM + || code == BOUND_TEMPLATE_TEMPLATE_PARM + || code == TEMPLATE_PARM_INDEX) + write_template_param (expr); + /* Handle literals. */ + else if (TREE_CODE_CLASS (code) == tcc_constant + || code == CONST_DECL) + write_template_arg_literal (expr); + else if (code == PARM_DECL && DECL_ARTIFICIAL (expr)) + { + gcc_assert (id_equal (DECL_NAME (expr), "this")); + write_string ("fpT"); + } + else if (code == PARM_DECL) + { + /* A function parameter used in a late-specified return type. */ + int index = DECL_PARM_INDEX (expr); + int level = DECL_PARM_LEVEL (expr); + int delta = G.parm_depth - level + 1; + gcc_assert (index >= 1); + write_char ('f'); + if (delta != 0) + { + if (abi_version_at_least (5)) + { + /* Let L be the number of function prototype scopes from the + innermost one (in which the parameter reference occurs) up + to (and including) the one containing the declaration of + the referenced parameter. If the parameter declaration + clause of the innermost function prototype scope has been + completely seen, it is not counted (in that case -- which + is perhaps the most common -- L can be zero). */ + write_char ('L'); + write_unsigned_number (delta - 1); + } + if (abi_warn_or_compat_version_crosses (5)) + G.need_abi_warning = true; + } + write_char ('p'); + write_compact_number (index - 1); + } + else if (DECL_P (expr)) + { + write_char ('L'); + write_mangled_name (expr, false); + write_char ('E'); + } + else if (TREE_CODE (expr) == SIZEOF_EXPR) + { + tree op = TREE_OPERAND (expr, 0); + + if (PACK_EXPANSION_P (op)) + { + if (abi_warn_or_compat_version_crosses (11)) + G.need_abi_warning = true; + if (abi_version_at_least (11)) + { + /* sZ rather than szDp. */ + write_string ("sZ"); + write_expression (PACK_EXPANSION_PATTERN (op)); + return; + } + } + + if (SIZEOF_EXPR_TYPE_P (expr)) + { + write_string ("st"); + write_type (TREE_TYPE (op)); + } + else if (ARGUMENT_PACK_P (op)) + { + tree args = ARGUMENT_PACK_ARGS (op); + int length = TREE_VEC_LENGTH (args); + if (abi_warn_or_compat_version_crosses (10)) + G.need_abi_warning = true; + if (abi_version_at_least (10)) + { + /* sP <template-arg>* E # sizeof...(T), size of a captured + template parameter pack from an alias template */ + write_string ("sP"); + for (int i = 0; i < length; ++i) + write_template_arg (TREE_VEC_ELT (args, i)); + write_char ('E'); + } + else + { + /* In GCC 5 we represented this sizeof wrong, with the effect + that we mangled it as the last element of the pack. */ + tree arg = TREE_VEC_ELT (args, length-1); + if (TYPE_P (op)) + { + write_string ("st"); + write_type (arg); + } + else + { + write_string ("sz"); + write_expression (arg); + } + } + } + else if (TYPE_P (TREE_OPERAND (expr, 0))) + { + write_string ("st"); + write_type (TREE_OPERAND (expr, 0)); + } + else + goto normal_expr; + } + else if (TREE_CODE (expr) == ALIGNOF_EXPR) + { + if (!ALIGNOF_EXPR_STD_P (expr)) + { + if (abi_warn_or_compat_version_crosses (16)) + G.need_abi_warning = true; + if (abi_version_at_least (16)) + { + /* We used to mangle __alignof__ like alignof. */ + write_string ("u11__alignof__"); + write_template_arg (TREE_OPERAND (expr, 0)); + write_char ('E'); + return; + } + } + if (TYPE_P (TREE_OPERAND (expr, 0))) + { + write_string ("at"); + write_type (TREE_OPERAND (expr, 0)); + } + else + goto normal_expr; + } + else if (code == SCOPE_REF + || code == BASELINK) + { + tree scope, member; + if (code == SCOPE_REF) + { + scope = TREE_OPERAND (expr, 0); + member = TREE_OPERAND (expr, 1); + if (BASELINK_P (member)) + member = BASELINK_FUNCTIONS (member); + } + else + { + scope = BINFO_TYPE (BASELINK_ACCESS_BINFO (expr)); + member = BASELINK_FUNCTIONS (expr); + } + + /* If the MEMBER is a real declaration, then the qualifying + scope was not dependent. Ideally, we would not have a + SCOPE_REF in those cases, but sometimes we do. If the second + argument is a DECL, then the name must not have been + dependent. */ + if (DECL_P (member)) + write_expression (member); + else + { + gcc_assert (code != BASELINK || BASELINK_QUALIFIED_P (expr)); + write_string ("sr"); + write_type (scope); + write_member_name (member); + } + } + else if (INDIRECT_REF_P (expr) + && TREE_TYPE (TREE_OPERAND (expr, 0)) + && TYPE_REF_P (TREE_TYPE (TREE_OPERAND (expr, 0)))) + { + write_expression (TREE_OPERAND (expr, 0)); + } + else if (identifier_p (expr)) + { + /* An operator name appearing as a dependent name needs to be + specially marked to disambiguate between a use of the operator + name and a use of the operator in an expression. */ + if (IDENTIFIER_ANY_OP_P (expr)) + write_string ("on"); + write_unqualified_id (expr); + } + else if (TREE_CODE (expr) == TEMPLATE_ID_EXPR) + { + tree fn = TREE_OPERAND (expr, 0); + fn = OVL_NAME (fn); + if (IDENTIFIER_ANY_OP_P (fn)) + write_string ("on"); + write_unqualified_id (fn); + write_template_args (TREE_OPERAND (expr, 1)); + } + else if (TREE_CODE (expr) == MODOP_EXPR) + { + enum tree_code subop = TREE_CODE (TREE_OPERAND (expr, 1)); + const char *name = OVL_OP_INFO (true, subop)->mangled_name; + + write_string (name); + write_expression (TREE_OPERAND (expr, 0)); + write_expression (TREE_OPERAND (expr, 2)); + } + else if (code == NEW_EXPR || code == VEC_NEW_EXPR) + { + /* ::= [gs] nw <expression>* _ <type> E + ::= [gs] nw <expression>* _ <type> <initializer> + ::= [gs] na <expression>* _ <type> E + ::= [gs] na <expression>* _ <type> <initializer> + <initializer> ::= pi <expression>* E */ + tree placement = TREE_OPERAND (expr, 0); + tree type = TREE_OPERAND (expr, 1); + tree nelts = TREE_OPERAND (expr, 2); + tree init = TREE_OPERAND (expr, 3); + tree t; + + gcc_assert (code == NEW_EXPR); + if (TREE_OPERAND (expr, 2)) + code = VEC_NEW_EXPR; + + if (NEW_EXPR_USE_GLOBAL (expr)) + write_string ("gs"); + + write_string (OVL_OP_INFO (false, code)->mangled_name); + + for (t = placement; t; t = TREE_CHAIN (t)) + write_expression (TREE_VALUE (t)); + + write_char ('_'); + + if (nelts) + { + tree domain; + ++processing_template_decl; + domain = compute_array_index_type (NULL_TREE, nelts, + tf_warning_or_error); + type = build_cplus_array_type (type, domain); + --processing_template_decl; + } + write_type (type); + + if (init && TREE_CODE (init) == TREE_LIST + && DIRECT_LIST_INIT_P (TREE_VALUE (init))) + write_expression (TREE_VALUE (init)); + else + { + if (init) + write_string ("pi"); + if (init && init != void_node) + for (t = init; t; t = TREE_CHAIN (t)) + write_expression (TREE_VALUE (t)); + write_char ('E'); + } + } + else if (code == DELETE_EXPR || code == VEC_DELETE_EXPR) + { + gcc_assert (code == DELETE_EXPR); + if (DELETE_EXPR_USE_VEC (expr)) + code = VEC_DELETE_EXPR; + + if (DELETE_EXPR_USE_GLOBAL (expr)) + write_string ("gs"); + + write_string (OVL_OP_INFO (false, code)->mangled_name); + + write_expression (TREE_OPERAND (expr, 0)); + } + else if (code == THROW_EXPR) + { + tree op = TREE_OPERAND (expr, 0); + if (op) + { + write_string ("tw"); + write_expression (op); + } + else + write_string ("tr"); + } + else if (code == CONSTRUCTOR) + { + bool braced_init = BRACE_ENCLOSED_INITIALIZER_P (expr); + tree etype = TREE_TYPE (expr); + + if (braced_init) + write_string ("il"); + else + { + write_string ("tl"); + write_type (etype); + } + + /* If this is an undigested initializer, mangle it as written. + COMPOUND_LITERAL_P doesn't actually distinguish between digested and + undigested braced casts, but it should work to use it to distinguish + between braced casts in a template signature (undigested) and template + parm object values (digested), and all CONSTRUCTORS that get here + should be one of those two cases. */ + bool undigested = braced_init || COMPOUND_LITERAL_P (expr); + if (undigested || !zero_init_expr_p (expr)) + { + /* Convert braced initializer lists to STRING_CSTs so that + A<"Foo"> mangles the same as A<{'F', 'o', 'o', 0}> while + still using the latter mangling for strings that + originated as braced initializer lists. */ + expr = braced_lists_to_strings (etype, expr); + + if (TREE_CODE (expr) == CONSTRUCTOR) + { + vec<constructor_elt, va_gc> *elts = CONSTRUCTOR_ELTS (expr); + unsigned last_nonzero = UINT_MAX; + constructor_elt *ce; + + if (!undigested) + for (HOST_WIDE_INT i = 0; vec_safe_iterate (elts, i, &ce); ++i) + if ((TREE_CODE (etype) == UNION_TYPE + && ce->index != first_field (etype)) + || !zero_init_expr_p (ce->value)) + last_nonzero = i; + + if (undigested || last_nonzero != UINT_MAX) + for (HOST_WIDE_INT i = 0; vec_safe_iterate (elts, i, &ce); ++i) + { + if (i > last_nonzero) + break; + if (TREE_CODE (etype) == UNION_TYPE) + { + /* Express the active member as a designator. */ + write_string ("di"); + write_unqualified_name (ce->index); + } + unsigned reps = 1; + if (ce->index && TREE_CODE (ce->index) == RANGE_EXPR) + reps = range_expr_nelts (ce->index); + for (unsigned j = 0; j < reps; ++j) + write_expression (ce->value); + } + } + else + { + gcc_assert (TREE_CODE (expr) == STRING_CST); + write_expression (expr); + } + } + write_char ('E'); + } + else if (code == LAMBDA_EXPR) + { + /* [temp.over.link] Two lambda-expressions are never considered + equivalent. + + So just use the closure type mangling. */ + write_string ("tl"); + write_type (LAMBDA_EXPR_CLOSURE (expr)); + write_char ('E'); + } + else if (dependent_name (expr)) + { + tree name = dependent_name (expr); + if (IDENTIFIER_ANY_OP_P (name)) + { + if (abi_version_at_least (16)) + write_string ("on"); + if (abi_warn_or_compat_version_crosses (16)) + G.need_abi_warning = 1; + } + write_unqualified_id (name); + } + else + { + normal_expr: + int i, len; + const char *name; + + /* When we bind a variable or function to a non-type template + argument with reference type, we create an ADDR_EXPR to show + the fact that the entity's address has been taken. But, we + don't actually want to output a mangling code for the `&'. */ + if (TREE_CODE (expr) == ADDR_EXPR + && TREE_TYPE (expr) + && TYPE_REF_P (TREE_TYPE (expr))) + { + expr = TREE_OPERAND (expr, 0); + if (DECL_P (expr)) + { + write_expression (expr); + return; + } + + code = TREE_CODE (expr); + } + + if (code == COMPONENT_REF) + { + tree ob = TREE_OPERAND (expr, 0); + + if (TREE_CODE (ob) == ARROW_EXPR) + { + write_string (OVL_OP_INFO (false, code)->mangled_name); + ob = TREE_OPERAND (ob, 0); + write_expression (ob); + } + else if (write_base_ref (expr)) + return; + else if (!is_dummy_object (ob)) + { + write_string ("dt"); + write_expression (ob); + } + /* else, for a non-static data member with no associated object (in + unevaluated context), use the unresolved-name mangling. */ + + write_member_name (TREE_OPERAND (expr, 1)); + return; + } + + /* If it wasn't any of those, recursively expand the expression. */ + name = OVL_OP_INFO (false, code)->mangled_name; + + /* We used to mangle const_cast and static_cast like a C cast. */ + if (code == CONST_CAST_EXPR + || code == STATIC_CAST_EXPR) + { + if (abi_warn_or_compat_version_crosses (6)) + G.need_abi_warning = 1; + if (!abi_version_at_least (6)) + name = OVL_OP_INFO (false, CAST_EXPR)->mangled_name; + } + + if (name == NULL) + { + switch (code) + { + case TRAIT_EXPR: + error ("use of built-in trait %qE in function signature; " + "use library traits instead", expr); + break; + + default: + sorry ("mangling %C", code); + break; + } + return; + } + else + write_string (name); + + switch (code) + { + case CALL_EXPR: + { + tree fn = CALL_EXPR_FN (expr); + + if (TREE_CODE (fn) == ADDR_EXPR) + fn = TREE_OPERAND (fn, 0); + + /* Mangle a dependent name as the name, not whatever happens to + be the first function in the overload set. */ + if (OVL_P (fn) + && type_dependent_expression_p_push (expr)) + fn = OVL_NAME (fn); + + write_expression (fn); + } + + for (i = 0; i < call_expr_nargs (expr); ++i) + write_expression (CALL_EXPR_ARG (expr, i)); + write_char ('E'); + break; + + case CAST_EXPR: + write_type (TREE_TYPE (expr)); + if (list_length (TREE_OPERAND (expr, 0)) == 1) + write_expression (TREE_VALUE (TREE_OPERAND (expr, 0))); + else + { + tree args = TREE_OPERAND (expr, 0); + write_char ('_'); + for (; args; args = TREE_CHAIN (args)) + write_expression (TREE_VALUE (args)); + write_char ('E'); + } + break; + + case DYNAMIC_CAST_EXPR: + case REINTERPRET_CAST_EXPR: + case STATIC_CAST_EXPR: + case CONST_CAST_EXPR: + write_type (TREE_TYPE (expr)); + write_expression (TREE_OPERAND (expr, 0)); + break; + + case PREINCREMENT_EXPR: + case PREDECREMENT_EXPR: + if (abi_version_at_least (6)) + write_char ('_'); + if (abi_warn_or_compat_version_crosses (6)) + G.need_abi_warning = 1; + /* Fall through. */ + + default: + /* In the middle-end, some expressions have more operands than + they do in templates (and mangling). */ + len = cp_tree_operand_length (expr); + + for (i = 0; i < len; ++i) + { + tree operand = TREE_OPERAND (expr, i); + /* As a GNU extension, the middle operand of a + conditional may be omitted. Since expression + manglings are supposed to represent the input token + stream, there's no good way to mangle such an + expression without extending the C++ ABI. */ + if (code == COND_EXPR && i == 1 && !operand) + { + error ("omitted middle operand to %<?:%> operand " + "cannot be mangled"); + continue; + } + else if (FOLD_EXPR_P (expr)) + { + /* The first 'operand' of a fold-expression is the operator + that it folds over. */ + if (i == 0) + { + int fcode = TREE_INT_CST_LOW (operand); + write_string (OVL_OP_INFO (false, fcode)->mangled_name); + continue; + } + else if (code == BINARY_LEFT_FOLD_EXPR) + { + /* The order of operands of the binary left and right + folds is the same, but we want to mangle them in + lexical order, i.e. non-pack first. */ + if (i == 1) + operand = FOLD_EXPR_INIT (expr); + else + operand = FOLD_EXPR_PACK (expr); + } + if (PACK_EXPANSION_P (operand)) + operand = PACK_EXPANSION_PATTERN (operand); + } + write_expression (operand); + } + } + } +} + +/* Literal subcase of non-terminal <template-arg>. + + "Literal arguments, e.g. "A<42L>", are encoded with their type + and value. Negative integer values are preceded with "n"; for + example, "A<-42L>" becomes "1AILln42EE". The bool value false is + encoded as 0, true as 1." */ + +static void +write_template_arg_literal (const tree value) +{ + if (TREE_CODE (value) == STRING_CST) + /* Temporarily mangle strings as braced initializer lists. */ + write_string ("tl"); + else + write_char ('L'); + + tree valtype = TREE_TYPE (value); + write_type (valtype); + + /* Write a null member pointer value as (type)0, regardless of its + real representation. */ + if (null_member_pointer_value_p (value)) + write_integer_cst (integer_zero_node); + else + switch (TREE_CODE (value)) + { + case CONST_DECL: + write_integer_cst (DECL_INITIAL (value)); + break; + + case INTEGER_CST: + gcc_assert (!same_type_p (TREE_TYPE (value), boolean_type_node) + || integer_zerop (value) || integer_onep (value)); + if (!(abi_version_at_least (14) + && NULLPTR_TYPE_P (TREE_TYPE (value)))) + write_integer_cst (value); + break; + + case REAL_CST: + write_real_cst (value); + break; + + case COMPLEX_CST: + if (TREE_CODE (TREE_REALPART (value)) == INTEGER_CST + && TREE_CODE (TREE_IMAGPART (value)) == INTEGER_CST) + { + write_integer_cst (TREE_REALPART (value)); + write_char ('_'); + write_integer_cst (TREE_IMAGPART (value)); + } + else if (TREE_CODE (TREE_REALPART (value)) == REAL_CST + && TREE_CODE (TREE_IMAGPART (value)) == REAL_CST) + { + write_real_cst (TREE_REALPART (value)); + write_char ('_'); + write_real_cst (TREE_IMAGPART (value)); + } + else + gcc_unreachable (); + break; + + case STRING_CST: + { + /* Mangle strings the same as braced initializer lists. */ + unsigned n = TREE_STRING_LENGTH (value); + const char *str = TREE_STRING_POINTER (value); + + /* Count the number of trailing nuls and subtract them from + STRSIZE because they don't need to be mangled. */ + for (const char *p = str + n - 1; ; --p) + { + if (*p || p == str) + { + n -= str + n - !!*p - p; + break; + } + } + tree eltype = TREE_TYPE (valtype); + for (const char *p = str; n--; ++p) + { + write_char ('L'); + write_type (eltype); + write_unsigned_number (*(const unsigned char*)p); + write_string ("E"); + } + break; + } + + default: + gcc_unreachable (); + } + + write_char ('E'); +} + +/* Non-terminal <template-arg>. + + <template-arg> ::= <type> # type + ::= L <type> </value/ number> E # literal + ::= LZ <name> E # external name + ::= X <expression> E # expression */ + +static void +write_template_arg (tree node) +{ + enum tree_code code = TREE_CODE (node); + + MANGLE_TRACE_TREE ("template-arg", node); + + /* A template template parameter's argument list contains TREE_LIST + nodes of which the value field is the actual argument. */ + if (code == TREE_LIST) + { + node = TREE_VALUE (node); + /* If it's a decl, deal with its type instead. */ + if (DECL_P (node)) + { + node = TREE_TYPE (node); + code = TREE_CODE (node); + } + } + + if (template_parm_object_p (node)) + /* We want to mangle the argument, not the var we stored it in. */ + node = tparm_object_argument (node); + + /* Strip a conversion added by convert_nontype_argument. */ + if (TREE_CODE (node) == IMPLICIT_CONV_EXPR) + node = TREE_OPERAND (node, 0); + if (REFERENCE_REF_P (node)) + node = TREE_OPERAND (node, 0); + if (TREE_CODE (node) == NOP_EXPR + && TYPE_REF_P (TREE_TYPE (node))) + { + /* Template parameters can be of reference type. To maintain + internal consistency, such arguments use a conversion from + address of object to reference type. */ + gcc_assert (TREE_CODE (TREE_OPERAND (node, 0)) == ADDR_EXPR); + node = TREE_OPERAND (TREE_OPERAND (node, 0), 0); + } + + if (TREE_CODE (node) == BASELINK + && !type_unknown_p (node)) + { + if (abi_version_at_least (6)) + node = BASELINK_FUNCTIONS (node); + if (abi_warn_or_compat_version_crosses (6)) + /* We wrongly wrapped a class-scope function in X/E. */ + G.need_abi_warning = 1; + } + + if (ARGUMENT_PACK_P (node)) + { + /* Expand the template argument pack. */ + tree args = ARGUMENT_PACK_ARGS (node); + int i, length = TREE_VEC_LENGTH (args); + if (abi_version_at_least (6)) + write_char ('J'); + else + write_char ('I'); + if (abi_warn_or_compat_version_crosses (6)) + G.need_abi_warning = 1; + for (i = 0; i < length; ++i) + write_template_arg (TREE_VEC_ELT (args, i)); + write_char ('E'); + } + else if (TYPE_P (node)) + write_type (node); + else if (code == TEMPLATE_DECL) + /* A template appearing as a template arg is a template template arg. */ + write_template_template_arg (node); + else if ((TREE_CODE_CLASS (code) == tcc_constant && code != PTRMEM_CST) + || code == CONST_DECL + || null_member_pointer_value_p (node)) + write_template_arg_literal (node); + else if (DECL_P (node)) + { + write_char ('L'); + /* Until ABI version 3, the underscore before the mangled name + was incorrectly omitted. */ + if (!abi_version_at_least (3)) + write_char ('Z'); + else + write_string ("_Z"); + if (abi_warn_or_compat_version_crosses (3)) + G.need_abi_warning = 1; + write_encoding (node); + write_char ('E'); + } + else + { + /* Template arguments may be expressions. */ + write_char ('X'); + write_expression (node); + write_char ('E'); + } +} + +/* <template-template-arg> + ::= <name> + ::= <substitution> */ + +static void +write_template_template_arg (const tree decl) +{ + MANGLE_TRACE_TREE ("template-template-arg", decl); + + if (find_substitution (decl)) + return; + write_name (decl, /*ignore_local_scope=*/0); + add_substitution (decl); +} + + +/* Non-terminal <array-type>. TYPE is an ARRAY_TYPE. + + <array-type> ::= A [</dimension/ number>] _ </element/ type> + ::= A <expression> _ </element/ type> + + "Array types encode the dimension (number of elements) and the + element type. For variable length arrays, the dimension (but not + the '_' separator) is omitted." + Note that for flexible array members, like for other arrays of + unspecified size, the dimension is also omitted. */ + +static void +write_array_type (const tree type) +{ + write_char ('A'); + if (TYPE_DOMAIN (type)) + { + tree index_type; + + index_type = TYPE_DOMAIN (type); + /* The INDEX_TYPE gives the upper and lower bounds of the array. + It's null for flexible array members which have no upper bound + (this is a change from GCC 5 and prior where such members were + incorrectly mangled as zero-length arrays). */ + if (tree max = TYPE_MAX_VALUE (index_type)) + { + if (TREE_CODE (max) == INTEGER_CST) + { + /* The ABI specifies that we should mangle the number of + elements in the array, not the largest allowed index. */ + offset_int wmax = wi::to_offset (max) + 1; + /* Truncate the result - this will mangle [0, SIZE_INT_MAX] + number of elements as zero. */ + wmax = wi::zext (wmax, TYPE_PRECISION (TREE_TYPE (max))); + gcc_assert (wi::fits_uhwi_p (wmax)); + write_unsigned_number (wmax.to_uhwi ()); + } + else + { + max = TREE_OPERAND (max, 0); + write_expression (max); + } + } + } + write_char ('_'); + write_type (TREE_TYPE (type)); +} + +/* Non-terminal <pointer-to-member-type> for pointer-to-member + variables. TYPE is a pointer-to-member POINTER_TYPE. + + <pointer-to-member-type> ::= M </class/ type> </member/ type> */ + +static void +write_pointer_to_member_type (const tree type) +{ + write_char ('M'); + write_type (TYPE_PTRMEM_CLASS_TYPE (type)); + write_type (TYPE_PTRMEM_POINTED_TO_TYPE (type)); +} + +/* Non-terminal <template-param>. PARM is a TEMPLATE_TYPE_PARM, + TEMPLATE_TEMPLATE_PARM, BOUND_TEMPLATE_TEMPLATE_PARM or a + TEMPLATE_PARM_INDEX. + + <template-param> ::= T </parameter/ number> _ */ + +static void +write_template_param (const tree parm) +{ + int parm_index; + + MANGLE_TRACE_TREE ("template-parm", parm); + + switch (TREE_CODE (parm)) + { + case TEMPLATE_TYPE_PARM: + case TEMPLATE_TEMPLATE_PARM: + case BOUND_TEMPLATE_TEMPLATE_PARM: + parm_index = TEMPLATE_TYPE_IDX (parm); + break; + + case TEMPLATE_PARM_INDEX: + parm_index = TEMPLATE_PARM_IDX (parm); + break; + + default: + gcc_unreachable (); + } + + write_char ('T'); + /* NUMBER as it appears in the mangling is (-1)-indexed, with the + earliest template param denoted by `_'. */ + write_compact_number (parm_index); +} + +/* <template-template-param> + ::= <template-param> + ::= <substitution> */ + +static void +write_template_template_param (const tree parm) +{ + tree templ = NULL_TREE; + + /* PARM, a TEMPLATE_TEMPLATE_PARM, is an instantiation of the + template template parameter. The substitution candidate here is + only the template. */ + if (TREE_CODE (parm) == BOUND_TEMPLATE_TEMPLATE_PARM) + { + templ + = TI_TEMPLATE (TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (parm)); + if (find_substitution (templ)) + return; + } + + /* <template-param> encodes only the template parameter position, + not its template arguments, which is fine here. */ + write_template_param (parm); + if (templ) + add_substitution (templ); +} + +/* Non-terminal <substitution>. + + <substitution> ::= S <seq-id> _ + ::= S_ */ + +static void +write_substitution (const int seq_id) +{ + MANGLE_TRACE ("substitution", ""); + + write_char ('S'); + if (seq_id > 0) + write_number (seq_id - 1, /*unsigned=*/1, 36); + write_char ('_'); +} + +/* Start mangling ENTITY. */ + +static inline void +start_mangling (const tree entity) +{ + G.entity = entity; + G.need_abi_warning = false; + G.need_cxx17_warning = false; + G.mod = false; + obstack_free (&name_obstack, name_base); + mangle_obstack = &name_obstack; + name_base = obstack_alloc (&name_obstack, 0); +} + +/* Done with mangling. Release the data. */ + +static void +finish_mangling_internal (void) +{ + /* Clear all the substitutions. */ + vec_safe_truncate (G.substitutions, 0); + + if (G.mod) + mangle_module_fini (); + + /* Null-terminate the string. */ + write_char ('\0'); +} + + +/* Like finish_mangling_internal, but return the mangled string. */ + +static inline const char * +finish_mangling (void) +{ + finish_mangling_internal (); + return (const char *) obstack_finish (mangle_obstack); +} + +/* Like finish_mangling_internal, but return an identifier. */ + +static tree +finish_mangling_get_identifier (void) +{ + finish_mangling_internal (); + /* Don't obstack_finish here, and the next start_mangling will + remove the identifier. */ + return get_identifier ((const char *) obstack_base (mangle_obstack)); +} + +/* Initialize data structures for mangling. */ + +void +init_mangle (void) +{ + gcc_obstack_init (&name_obstack); + name_base = obstack_alloc (&name_obstack, 0); + vec_alloc (G.substitutions, 0); + + /* Cache these identifiers for quick comparison when checking for + standard substitutions. */ + subst_identifiers[SUBID_ALLOCATOR] = get_identifier ("allocator"); + subst_identifiers[SUBID_BASIC_STRING] = get_identifier ("basic_string"); + subst_identifiers[SUBID_CHAR_TRAITS] = get_identifier ("char_traits"); + subst_identifiers[SUBID_BASIC_ISTREAM] = get_identifier ("basic_istream"); + subst_identifiers[SUBID_BASIC_OSTREAM] = get_identifier ("basic_ostream"); + subst_identifiers[SUBID_BASIC_IOSTREAM] = get_identifier ("basic_iostream"); +} + +/* Generate a mangling for MODULE's global initializer fn. */ + +tree +mangle_module_global_init (int module) +{ + start_mangling (NULL_TREE); + + write_string ("_ZGI"); + write_module (module, true); + write_char ('v'); + + return finish_mangling_get_identifier (); +} + +/* Generate the mangled name of DECL. */ + +static tree +mangle_decl_string (const tree decl) +{ + tree result; + tree saved_fn = NULL_TREE; + bool template_p = false; + + /* We shouldn't be trying to mangle an uninstantiated template. */ + gcc_assert (!type_dependent_expression_p (decl)); + + if (DECL_LANG_SPECIFIC (decl) && DECL_USE_TEMPLATE (decl)) + { + struct tinst_level *tl = current_instantiation (); + if ((!tl || tl->maybe_get_node () != decl) + && push_tinst_level (decl)) + { + template_p = true; + saved_fn = current_function_decl; + current_function_decl = NULL_TREE; + } + } + iloc_sentinel ils (DECL_SOURCE_LOCATION (decl)); + + start_mangling (decl); + + if (TREE_CODE (decl) == TYPE_DECL) + write_type (TREE_TYPE (decl)); + else + write_mangled_name (decl, true); + + result = finish_mangling_get_identifier (); + if (DEBUG_MANGLE) + fprintf (stderr, "mangle_decl_string = '%s'\n\n", + IDENTIFIER_POINTER (result)); + + if (template_p) + { + pop_tinst_level (); + current_function_decl = saved_fn; + } + + return result; +} + +/* Return an identifier for the external mangled name of DECL. */ + +static tree +get_mangled_id (tree decl) +{ + tree id = mangle_decl_string (decl); + return targetm.mangle_decl_assembler_name (decl, id); +} + +/* Create an identifier for the external mangled name of DECL. */ + +void +mangle_decl (const tree decl) +{ + tree id; + bool dep; + + /* Don't bother mangling uninstantiated templates. */ + ++processing_template_decl; + if (TREE_CODE (decl) == TYPE_DECL) + dep = dependent_type_p (TREE_TYPE (decl)); + else + dep = (DECL_LANG_SPECIFIC (decl) && DECL_TEMPLATE_INFO (decl) + && any_dependent_template_arguments_p (DECL_TI_ARGS (decl))); + --processing_template_decl; + if (dep) + return; + + /* During LTO we keep mangled names of TYPE_DECLs for ODR type merging. + It is not needed to assign names to anonymous namespace, but we use the + "<anon>" marker to be able to tell if type is C++ ODR type or type + produced by other language. */ + if (TREE_CODE (decl) == TYPE_DECL + && TYPE_STUB_DECL (TREE_TYPE (decl)) + && !TREE_PUBLIC (TYPE_STUB_DECL (TREE_TYPE (decl)))) + id = get_identifier ("<anon>"); + else + { + gcc_assert (TREE_CODE (decl) != TYPE_DECL + || !no_linkage_check (TREE_TYPE (decl), true)); + if (abi_version_at_least (10)) + if (tree fn = decl_function_context (decl)) + maybe_check_abi_tags (fn, decl); + id = get_mangled_id (decl); + } + SET_DECL_ASSEMBLER_NAME (decl, id); + + if (G.need_cxx17_warning + && (TREE_PUBLIC (decl) || DECL_REALLY_EXTERN (decl))) + warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wnoexcept_type, + "mangled name for %qD will change in C++17 because the " + "exception specification is part of a function type", + decl); + + if (id != DECL_NAME (decl) + /* Don't do this for a fake symbol we aren't going to emit anyway. */ + && TREE_CODE (decl) != TYPE_DECL + && !DECL_MAYBE_IN_CHARGE_CDTOR_P (decl)) + { + int save_ver = flag_abi_version; + tree id2 = NULL_TREE; + + if (!DECL_REALLY_EXTERN (decl)) + { + record_mangling (decl, G.need_abi_warning); + + if (!G.need_abi_warning) + return; + + flag_abi_version = flag_abi_compat_version; + id2 = mangle_decl_string (decl); + id2 = targetm.mangle_decl_assembler_name (decl, id2); + flag_abi_version = save_ver; + + if (id2 != id) + note_mangling_alias (decl, id2); + } + + if (warn_abi) + { + const char fabi_version[] = "-fabi-version"; + + if (flag_abi_compat_version != warn_abi_version + || id2 == NULL_TREE) + { + flag_abi_version = warn_abi_version; + id2 = mangle_decl_string (decl); + id2 = targetm.mangle_decl_assembler_name (decl, id2); + } + flag_abi_version = save_ver; + + if (id2 == id) + /* OK. */; + else if (warn_abi_version != 0 + && abi_version_at_least (warn_abi_version)) + warning_at (DECL_SOURCE_LOCATION (G.entity), OPT_Wabi, + "the mangled name of %qD changed between " + "%<%s=%d%> (%qD) and %<%s=%d%> (%qD)", + G.entity, fabi_version, warn_abi_version, id2, + fabi_version, save_ver, id); + else + warning_at (DECL_SOURCE_LOCATION (G.entity), OPT_Wabi, + "the mangled name of %qD changes between " + "%<%s=%d%> (%qD) and %<%s=%d%> (%qD)", + G.entity, fabi_version, save_ver, id, + fabi_version, warn_abi_version, id2); + } + + flag_abi_version = save_ver; + } +} + +/* Generate the mangled representation of TYPE. */ + +const char * +mangle_type_string (const tree type) +{ + const char *result; + + start_mangling (type); + write_type (type); + result = finish_mangling (); + if (DEBUG_MANGLE) + fprintf (stderr, "mangle_type_string = '%s'\n\n", result); + return result; +} + +/* Create an identifier for the mangled name of a special component + for belonging to TYPE. CODE is the ABI-specified code for this + component. */ + +static tree +mangle_special_for_type (const tree type, const char *code) +{ + tree result; + + /* We don't have an actual decl here for the special component, so + we can't just process the <encoded-name>. Instead, fake it. */ + start_mangling (type); + + /* Start the mangling. */ + write_string ("_Z"); + write_string (code); + + /* Add the type. */ + write_type (type); + result = finish_mangling_get_identifier (); + + if (DEBUG_MANGLE) + fprintf (stderr, "mangle_special_for_type = %s\n\n", + IDENTIFIER_POINTER (result)); + + return result; +} + +/* Create an identifier for the mangled representation of the typeinfo + structure for TYPE. */ + +tree +mangle_typeinfo_for_type (const tree type) +{ + return mangle_special_for_type (type, "TI"); +} + +/* Create an identifier for the mangled name of the NTBS containing + the mangled name of TYPE. */ + +tree +mangle_typeinfo_string_for_type (const tree type) +{ + return mangle_special_for_type (type, "TS"); +} + +/* Create an identifier for the mangled name of the vtable for TYPE. */ + +tree +mangle_vtbl_for_type (const tree type) +{ + return mangle_special_for_type (type, "TV"); +} + +/* Returns an identifier for the mangled name of the VTT for TYPE. */ + +tree +mangle_vtt_for_type (const tree type) +{ + return mangle_special_for_type (type, "TT"); +} + +/* Returns an identifier for the mangled name of the decomposition + artificial variable DECL. DECLS is the vector of the VAR_DECLs + for the identifier-list. */ + +tree +mangle_decomp (const tree decl, vec<tree> &decls) +{ + gcc_assert (!type_dependent_expression_p (decl)); + + location_t saved_loc = input_location; + input_location = DECL_SOURCE_LOCATION (decl); + + start_mangling (decl); + write_string ("_Z"); + + tree context = decl_mangling_context (decl); + gcc_assert (context != NULL_TREE); + + bool nested = false; + if (DECL_NAMESPACE_STD_P (context)) + write_string ("St"); + else if (context != global_namespace) + { + nested = true; + write_char ('N'); + write_prefix (decl_mangling_context (decl)); + } + + write_string ("DC"); + unsigned int i; + tree d; + FOR_EACH_VEC_ELT (decls, i, d) + write_unqualified_name (d); + write_char ('E'); + + if (nested) + write_char ('E'); + + tree id = finish_mangling_get_identifier (); + if (DEBUG_MANGLE) + fprintf (stderr, "mangle_decomp = '%s'\n\n", + IDENTIFIER_POINTER (id)); + + input_location = saved_loc; + return id; +} + +/* Return an identifier for a construction vtable group. TYPE is + the most derived class in the hierarchy; BINFO is the base + subobject for which this construction vtable group will be used. + + This mangling isn't part of the ABI specification; in the ABI + specification, the vtable group is dumped in the same COMDAT as the + main vtable, and is referenced only from that vtable, so it doesn't + need an external name. For binary formats without COMDAT sections, + though, we need external names for the vtable groups. + + We use the production + + <special-name> ::= CT <type> <offset number> _ <base type> */ + +tree +mangle_ctor_vtbl_for_type (const tree type, const tree binfo) +{ + tree result; + + start_mangling (type); + + write_string ("_Z"); + write_string ("TC"); + write_type (type); + write_integer_cst (BINFO_OFFSET (binfo)); + write_char ('_'); + write_type (BINFO_TYPE (binfo)); + + result = finish_mangling_get_identifier (); + if (DEBUG_MANGLE) + fprintf (stderr, "mangle_ctor_vtbl_for_type = %s\n\n", + IDENTIFIER_POINTER (result)); + return result; +} + +/* Mangle a this pointer or result pointer adjustment. + + <call-offset> ::= h <fixed offset number> _ + ::= v <fixed offset number> _ <virtual offset number> _ */ + +static void +mangle_call_offset (const tree fixed_offset, const tree virtual_offset) +{ + write_char (virtual_offset ? 'v' : 'h'); + + /* For either flavor, write the fixed offset. */ + write_integer_cst (fixed_offset); + write_char ('_'); + + /* For a virtual thunk, add the virtual offset. */ + if (virtual_offset) + { + write_integer_cst (virtual_offset); + write_char ('_'); + } +} + +/* Return an identifier for the mangled name of a this-adjusting or + covariant thunk to FN_DECL. FIXED_OFFSET is the initial adjustment + to this used to find the vptr. If VIRTUAL_OFFSET is non-NULL, this + is a virtual thunk, and it is the vtbl offset in + bytes. THIS_ADJUSTING is nonzero for a this adjusting thunk and + zero for a covariant thunk. Note, that FN_DECL might be a covariant + thunk itself. A covariant thunk name always includes the adjustment + for the this pointer, even if there is none. + + <special-name> ::= T <call-offset> <base encoding> + ::= Tc <this_adjust call-offset> <result_adjust call-offset> + <base encoding> */ + +tree +mangle_thunk (tree fn_decl, const int this_adjusting, tree fixed_offset, + tree virtual_offset, tree thunk) +{ + tree result; + + if (abi_version_at_least (11)) + maybe_check_abi_tags (fn_decl, thunk, 11); + + start_mangling (fn_decl); + + write_string ("_Z"); + write_char ('T'); + + if (!this_adjusting) + { + /* Covariant thunk with no this adjustment */ + write_char ('c'); + mangle_call_offset (integer_zero_node, NULL_TREE); + mangle_call_offset (fixed_offset, virtual_offset); + } + else if (!DECL_THUNK_P (fn_decl)) + /* Plain this adjusting thunk. */ + mangle_call_offset (fixed_offset, virtual_offset); + else + { + /* This adjusting thunk to covariant thunk. */ + write_char ('c'); + mangle_call_offset (fixed_offset, virtual_offset); + fixed_offset = ssize_int (THUNK_FIXED_OFFSET (fn_decl)); + virtual_offset = THUNK_VIRTUAL_OFFSET (fn_decl); + if (virtual_offset) + virtual_offset = BINFO_VPTR_FIELD (virtual_offset); + mangle_call_offset (fixed_offset, virtual_offset); + fn_decl = THUNK_TARGET (fn_decl); + } + + /* Scoped name. */ + write_encoding (fn_decl); + + result = finish_mangling_get_identifier (); + if (DEBUG_MANGLE) + fprintf (stderr, "mangle_thunk = %s\n\n", IDENTIFIER_POINTER (result)); + return result; +} + +/* Handle ABI backwards compatibility for past bugs where we didn't call + check_abi_tags in places where it's needed: call check_abi_tags and warn if + it makes a difference. If FOR_DECL is non-null, it's the declaration + that we're actually trying to mangle; if it's null, we're mangling the + guard variable for T. */ + +static void +maybe_check_abi_tags (tree t, tree for_decl, int ver) +{ + if (DECL_ASSEMBLER_NAME_SET_P (t)) + return; + + tree oldtags = get_abi_tags (t); + + mangle_decl (t); + + tree newtags = get_abi_tags (t); + if (newtags && newtags != oldtags + && abi_version_crosses (ver)) + { + if (for_decl && DECL_THUNK_P (for_decl)) + warning_at (DECL_SOURCE_LOCATION (t), OPT_Wabi, + "the mangled name of a thunk for %qD changes between " + "%<-fabi-version=%d%> and %<-fabi-version=%d%>", + t, flag_abi_version, warn_abi_version); + else if (for_decl) + warning_at (DECL_SOURCE_LOCATION (for_decl), OPT_Wabi, + "the mangled name of %qD changes between " + "%<-fabi-version=%d%> and %<-fabi-version=%d%>", + for_decl, flag_abi_version, warn_abi_version); + else + warning_at (DECL_SOURCE_LOCATION (t), OPT_Wabi, + "the mangled name of the initialization guard variable " + "for %qD changes between %<-fabi-version=%d%> and " + "%<-fabi-version=%d%>", + t, flag_abi_version, warn_abi_version); + } +} + +/* Write out the appropriate string for this variable when generating + another mangled name based on this one. */ + +static void +write_guarded_var_name (const tree variable) +{ + if (DECL_NAME (variable) + && startswith (IDENTIFIER_POINTER (DECL_NAME (variable)), "_ZGR")) + /* The name of a guard variable for a reference temporary should refer + to the reference, not the temporary. */ + write_string (IDENTIFIER_POINTER (DECL_NAME (variable)) + 4); + else + write_name (variable, /*ignore_local_scope=*/0); +} + +/* Return an identifier for the name of an initialization guard + variable for indicated VARIABLE. */ + +tree +mangle_guard_variable (const tree variable) +{ + if (abi_version_at_least (10)) + maybe_check_abi_tags (variable); + start_mangling (variable); + write_string ("_ZGV"); + write_guarded_var_name (variable); + return finish_mangling_get_identifier (); +} + +/* Return an identifier for the name of a thread_local initialization + function for VARIABLE. */ + +tree +mangle_tls_init_fn (const tree variable) +{ + check_abi_tags (variable); + start_mangling (variable); + write_string ("_ZTH"); + write_guarded_var_name (variable); + return finish_mangling_get_identifier (); +} + +/* Return an identifier for the name of a thread_local wrapper + function for VARIABLE. */ + +#define TLS_WRAPPER_PREFIX "_ZTW" + +tree +mangle_tls_wrapper_fn (const tree variable) +{ + check_abi_tags (variable); + start_mangling (variable); + write_string (TLS_WRAPPER_PREFIX); + write_guarded_var_name (variable); + return finish_mangling_get_identifier (); +} + +/* Return true iff FN is a thread_local wrapper function. */ + +bool +decl_tls_wrapper_p (const tree fn) +{ + if (TREE_CODE (fn) != FUNCTION_DECL) + return false; + tree name = DECL_NAME (fn); + return startswith (IDENTIFIER_POINTER (name), TLS_WRAPPER_PREFIX); +} + +/* Return an identifier for the name of a temporary variable used to + initialize a static reference. This is now part of the ABI. */ + +tree +mangle_ref_init_variable (const tree variable) +{ + start_mangling (variable); + write_string ("_ZGR"); + check_abi_tags (variable); + write_name (variable, /*ignore_local_scope=*/0); + /* Avoid name clashes with aggregate initialization of multiple + references at once. */ + write_compact_number (current_ref_temp_count++); + return finish_mangling_get_identifier (); +} + +/* Return an identifier for the mangled name of a C++20 template parameter + object for template argument EXPR. */ + +tree +mangle_template_parm_object (tree expr) +{ + start_mangling (expr); + write_string ("_ZTAX"); + write_expression (expr); + write_char ('E'); + return finish_mangling_get_identifier (); +} + +/* Given a CLASS_TYPE, such as a record for std::bad_exception this + function generates a mangled name for the vtable map variable of + the class type. For example, if the class type is + "std::bad_exception", the mangled name for the class is + "St13bad_exception". This function would generate the name + "_ZN4_VTVISt13bad_exceptionE12__vtable_mapE", which unmangles as: + "_VTV<std::bad_exception>::__vtable_map". */ + + +char * +get_mangled_vtable_map_var_name (tree class_type) +{ + char *var_name = NULL; + const char *prefix = "_ZN4_VTVI"; + const char *postfix = "E12__vtable_mapE"; + + gcc_assert (TREE_CODE (class_type) == RECORD_TYPE); + + tree class_id = DECL_ASSEMBLER_NAME (TYPE_NAME (class_type)); + + if (strstr (IDENTIFIER_POINTER (class_id), "<anon>") != NULL) + { + class_id = get_mangled_id (TYPE_NAME (class_type)); + vtbl_register_mangled_name (TYPE_NAME (class_type), class_id); + } + + unsigned int len = strlen (IDENTIFIER_POINTER (class_id)) + + strlen (prefix) + + strlen (postfix) + 1; + + var_name = (char *) xmalloc (len); + + sprintf (var_name, "%s%s%s", prefix, IDENTIFIER_POINTER (class_id), postfix); + + return var_name; +} + +#include "gt-cp-mangle.h" |