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/name-lookup.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/name-lookup.cc')
-rw-r--r-- | gcc/cp/name-lookup.cc | 8944 |
1 files changed, 8944 insertions, 0 deletions
diff --git a/gcc/cp/name-lookup.cc b/gcc/cp/name-lookup.cc new file mode 100644 index 0000000..caa23d3 --- /dev/null +++ b/gcc/cp/name-lookup.cc @@ -0,0 +1,8944 @@ +/* Definitions for C++ name lookup routines. + Copyright (C) 2003-2022 Free Software Foundation, Inc. + Contributed by Gabriel Dos Reis <gdr@integrable-solutions.net> + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +<http://www.gnu.org/licenses/>. */ + +#include "config.h" +#define INCLUDE_MEMORY +#include "system.h" +#include "coretypes.h" +#include "cp-tree.h" +#include "timevar.h" +#include "stringpool.h" +#include "print-tree.h" +#include "attribs.h" +#include "debug.h" +#include "c-family/c-pragma.h" +#include "gcc-rich-location.h" +#include "spellcheck-tree.h" +#include "parser.h" +#include "c-family/name-hint.h" +#include "c-family/known-headers.h" +#include "c-family/c-spellcheck.h" +#include "bitmap.h" + +static cxx_binding *cxx_binding_make (tree value, tree type); +static cp_binding_level *innermost_nonclass_level (void); +static void set_identifier_type_value_with_scope (tree id, tree decl, + cp_binding_level *b); +static name_hint maybe_suggest_missing_std_header (location_t location, + tree name); +static name_hint suggest_alternatives_for_1 (location_t location, tree name, + bool suggest_misspellings); + +/* Slots in BINDING_VECTOR. */ +enum binding_slots +{ + BINDING_SLOT_CURRENT, /* Slot for current TU. */ + BINDING_SLOT_GLOBAL, /* Slot for merged global module. */ + BINDING_SLOT_PARTITION, /* Slot for merged partition entities + (optional). */ + + /* Number of always-allocated slots. */ + BINDING_SLOTS_FIXED = BINDING_SLOT_GLOBAL + 1 +}; + +/* Create an overload suitable for recording an artificial TYPE_DECL + and another decl. We use this machanism to implement the struct + stat hack. */ + +#define STAT_HACK_P(N) ((N) && TREE_CODE (N) == OVERLOAD && OVL_LOOKUP_P (N)) +#define STAT_TYPE_VISIBLE_P(N) TREE_USED (OVERLOAD_CHECK (N)) +#define STAT_TYPE(N) TREE_TYPE (N) +#define STAT_DECL(N) OVL_FUNCTION (N) +#define STAT_VISIBLE(N) OVL_CHAIN (N) +#define MAYBE_STAT_DECL(N) (STAT_HACK_P (N) ? STAT_DECL (N) : N) +#define MAYBE_STAT_TYPE(N) (STAT_HACK_P (N) ? STAT_TYPE (N) : NULL_TREE) + +/* When a STAT_HACK_P is true, OVL_USING_P and OVL_EXPORT_P are valid + and apply to the hacked type. */ + +/* For regular (maybe) overloaded functions, we have OVL_HIDDEN_P. + But we also need to indicate hiddenness on implicit type decls + (injected friend classes), and (coming soon) decls injected from + block-scope externs. It is too awkward to press the existing + overload marking for that. If we have a hidden non-function, we + always create a STAT_HACK, and use these two markers as needed. */ +#define STAT_TYPE_HIDDEN_P(N) OVL_HIDDEN_P (N) +#define STAT_DECL_HIDDEN_P(N) OVL_DEDUP_P (N) + +/* Create a STAT_HACK node with DECL as the value binding and TYPE as + the type binding. */ + +static tree +stat_hack (tree decl = NULL_TREE, tree type = NULL_TREE) +{ + tree result = make_node (OVERLOAD); + + /* Mark this as a lookup, so we can tell this is a stat hack. */ + OVL_LOOKUP_P (result) = true; + STAT_DECL (result) = decl; + STAT_TYPE (result) = type; + return result; +} + +/* Create a local binding level for NAME. */ + +static cxx_binding * +create_local_binding (cp_binding_level *level, tree name) +{ + cxx_binding *binding = cxx_binding_make (NULL, NULL); + + LOCAL_BINDING_P (binding) = true; + binding->scope = level; + binding->previous = IDENTIFIER_BINDING (name); + + IDENTIFIER_BINDING (name) = binding; + + return binding; +} + +/* Find the binding for NAME in namespace NS. If CREATE_P is true, + make an empty binding if there wasn't one. */ + +static tree * +find_namespace_slot (tree ns, tree name, bool create_p = false) +{ + tree *slot = DECL_NAMESPACE_BINDINGS (ns) + ->find_slot_with_hash (name, name ? IDENTIFIER_HASH_VALUE (name) : 0, + create_p ? INSERT : NO_INSERT); + return slot; +} + +static tree +find_namespace_value (tree ns, tree name) +{ + tree *b = find_namespace_slot (ns, name); + + return b ? MAYBE_STAT_DECL (*b) : NULL_TREE; +} + +/* Look in *SLOT for a the binding of NAME in imported module IX. + Returns pointer to binding's slot, or NULL if not found. Does a + binary search, as this is mainly used for random access during + importing. Do not use for the fixed slots. */ + +static binding_slot * +search_imported_binding_slot (tree *slot, unsigned ix) +{ + gcc_assert (ix); + + if (!*slot) + return NULL; + + if (TREE_CODE (*slot) != BINDING_VECTOR) + return NULL; + + unsigned clusters = BINDING_VECTOR_NUM_CLUSTERS (*slot); + binding_cluster *cluster = BINDING_VECTOR_CLUSTER_BASE (*slot); + + if (BINDING_VECTOR_SLOTS_PER_CLUSTER == BINDING_SLOTS_FIXED) + { + clusters--; + cluster++; + } + + while (clusters > 1) + { + unsigned half = clusters / 2; + gcc_checking_assert (cluster[half].indices[0].span); + if (cluster[half].indices[0].base > ix) + clusters = half; + else + { + clusters -= half; + cluster += half; + } + } + + if (clusters) + /* Is it in this cluster? */ + for (unsigned off = 0; off != BINDING_VECTOR_SLOTS_PER_CLUSTER; off++) + { + if (!cluster->indices[off].span) + break; + if (cluster->indices[off].base > ix) + break; + + if (cluster->indices[off].base + cluster->indices[off].span > ix) + return &cluster->slots[off]; + } + + return NULL; +} + +static void +init_global_partition (binding_cluster *cluster, tree decl) +{ + bool purview = true; + + if (header_module_p ()) + purview = false; + else if (TREE_PUBLIC (decl) + && TREE_CODE (decl) == NAMESPACE_DECL + && !DECL_NAMESPACE_ALIAS (decl)) + purview = false; + else if (!get_originating_module (decl)) + purview = false; + + binding_slot *mslot; + if (!purview) + mslot = &cluster[0].slots[BINDING_SLOT_GLOBAL]; + else + mslot = &cluster[BINDING_SLOT_PARTITION + / BINDING_VECTOR_SLOTS_PER_CLUSTER] + .slots[BINDING_SLOT_PARTITION + % BINDING_VECTOR_SLOTS_PER_CLUSTER]; + + if (*mslot) + decl = ovl_make (decl, *mslot); + *mslot = decl; + + if (TREE_CODE (decl) == CONST_DECL) + { + tree type = TREE_TYPE (decl); + if (TREE_CODE (type) == ENUMERAL_TYPE + && IDENTIFIER_ANON_P (DECL_NAME (TYPE_NAME (type))) + && decl == TREE_VALUE (TYPE_VALUES (type))) + /* Anonymous enums are keyed by their first enumerator, put + the TYPE_DECL here too. */ + *mslot = ovl_make (TYPE_NAME (type), *mslot); + } +} + +/* Get the fixed binding slot IX. Creating the vector if CREATE is + non-zero. If CREATE is < 0, make sure there is at least 1 spare + slot for an import. (It is an error for CREATE < 0 and the slot to + already exist.) */ + +static tree * +get_fixed_binding_slot (tree *slot, tree name, unsigned ix, int create) +{ + gcc_checking_assert (ix <= BINDING_SLOT_PARTITION); + + /* An assumption is that the fixed slots all reside in one cluster. */ + gcc_checking_assert (BINDING_VECTOR_SLOTS_PER_CLUSTER >= BINDING_SLOTS_FIXED); + + if (!*slot || TREE_CODE (*slot) != BINDING_VECTOR) + { + if (ix == BINDING_SLOT_CURRENT) + /* The current TU can just use slot directly. */ + return slot; + + if (!create) + return NULL; + + /* The partition slot is only needed when we know we're a named + module. */ + bool partition_slot = named_module_p (); + unsigned want = ((BINDING_SLOTS_FIXED + partition_slot + (create < 0) + + BINDING_VECTOR_SLOTS_PER_CLUSTER - 1) + / BINDING_VECTOR_SLOTS_PER_CLUSTER); + tree new_vec = make_binding_vec (name, want); + BINDING_VECTOR_NUM_CLUSTERS (new_vec) = want; + binding_cluster *cluster = BINDING_VECTOR_CLUSTER_BASE (new_vec); + + /* Initialize the fixed slots. */ + for (unsigned jx = BINDING_SLOTS_FIXED; jx--;) + { + cluster[0].indices[jx].base = 0; + cluster[0].indices[jx].span = 1; + cluster[0].slots[jx] = NULL_TREE; + } + + if (partition_slot) + { + unsigned off = BINDING_SLOT_PARTITION % BINDING_VECTOR_SLOTS_PER_CLUSTER; + unsigned ind = BINDING_SLOT_PARTITION / BINDING_VECTOR_SLOTS_PER_CLUSTER; + cluster[ind].indices[off].base = 0; + cluster[ind].indices[off].span = 1; + cluster[ind].slots[off] = NULL_TREE; + } + + if (tree orig = *slot) + { + /* Propagate existing value to current slot. */ + + /* Propagate global & module entities to the global and + partition slots. */ + if (tree type = MAYBE_STAT_TYPE (orig)) + init_global_partition (cluster, type); + + for (ovl_iterator iter (MAYBE_STAT_DECL (orig)); iter; ++iter) + { + tree decl = *iter; + + /* Internal linkage entities are in deduplicateable. */ + init_global_partition (cluster, decl); + } + + if (cluster[0].slots[BINDING_SLOT_GLOBAL] + && !(TREE_CODE (orig) == NAMESPACE_DECL + && !DECL_NAMESPACE_ALIAS (orig))) + { + /* Note that we had some GMF entries. */ + if (!STAT_HACK_P (orig)) + orig = stat_hack (orig); + + MODULE_BINDING_GLOBAL_P (orig) = true; + } + + cluster[0].slots[BINDING_SLOT_CURRENT] = orig; + } + + *slot = new_vec; + } + else + gcc_checking_assert (create >= 0); + + unsigned off = ix % BINDING_VECTOR_SLOTS_PER_CLUSTER; + binding_cluster &cluster + = BINDING_VECTOR_CLUSTER (*slot, ix / BINDING_VECTOR_SLOTS_PER_CLUSTER); + + /* There must always be slots for these indices */ + gcc_checking_assert (cluster.indices[off].span == 1 + && !cluster.indices[off].base + && !cluster.slots[off].is_lazy ()); + + return reinterpret_cast<tree *> (&cluster.slots[off]); +} + +/* *SLOT is a namespace binding slot. Append a slot for imported + module IX. */ + +static binding_slot * +append_imported_binding_slot (tree *slot, tree name, unsigned ix) +{ + gcc_checking_assert (ix); + + if (!*slot || TREE_CODE (*slot) != BINDING_VECTOR) + /* Make an initial module vector. */ + get_fixed_binding_slot (slot, name, BINDING_SLOT_GLOBAL, -1); + else if (!BINDING_VECTOR_CLUSTER_LAST (*slot) + ->indices[BINDING_VECTOR_SLOTS_PER_CLUSTER - 1].span) + /* There is space in the last cluster. */; + else if (BINDING_VECTOR_NUM_CLUSTERS (*slot) + != BINDING_VECTOR_ALLOC_CLUSTERS (*slot)) + /* There is space in the vector. */ + BINDING_VECTOR_NUM_CLUSTERS (*slot)++; + else + { + /* Extend the vector. */ + unsigned have = BINDING_VECTOR_NUM_CLUSTERS (*slot); + unsigned want = (have * 3 + 1) / 2; + + if (want > (unsigned short)~0) + want = (unsigned short)~0; + + tree new_vec = make_binding_vec (name, want); + BINDING_VECTOR_NUM_CLUSTERS (new_vec) = have + 1; + memcpy (BINDING_VECTOR_CLUSTER_BASE (new_vec), + BINDING_VECTOR_CLUSTER_BASE (*slot), + have * sizeof (binding_cluster)); + *slot = new_vec; + } + + binding_cluster *last = BINDING_VECTOR_CLUSTER_LAST (*slot); + for (unsigned off = 0; off != BINDING_VECTOR_SLOTS_PER_CLUSTER; off++) + if (!last->indices[off].span) + { + /* Fill the free slot of the cluster. */ + last->indices[off].base = ix; + last->indices[off].span = 1; + last->slots[off] = NULL_TREE; + /* Check monotonicity. */ + gcc_checking_assert (last[off ? 0 : -1] + .indices[off ? off - 1 + : BINDING_VECTOR_SLOTS_PER_CLUSTER - 1] + .base < ix); + return &last->slots[off]; + } + + gcc_unreachable (); +} + +/* Add DECL to the list of things declared in binding level B. */ + +static void +add_decl_to_level (cp_binding_level *b, tree decl) +{ + gcc_assert (b->kind != sk_class); + + /* Make sure we don't create a circular list. xref_tag can end + up pushing the same artificial decl more than once. We + should have already detected that in update_binding. (This isn't a + complete verification of non-circularity.) */ + gcc_assert (b->names != decl); + + /* We build up the list in reverse order, and reverse it later if + necessary. */ + TREE_CHAIN (decl) = b->names; + b->names = decl; + + /* If appropriate, add decl to separate list of statics. We include + extern variables because they might turn out to be static later. + It's OK for this list to contain a few false positives. */ + if (b->kind == sk_namespace + && ((VAR_P (decl) && (TREE_STATIC (decl) || DECL_EXTERNAL (decl))) + || (TREE_CODE (decl) == FUNCTION_DECL + && (!TREE_PUBLIC (decl) + || decl_anon_ns_mem_p (decl) + || DECL_DECLARED_INLINE_P (decl))))) + vec_safe_push (static_decls, decl); +} + +/* Find the binding for NAME in the local binding level B. */ + +static cxx_binding * +find_local_binding (cp_binding_level *b, tree name) +{ + if (cxx_binding *binding = IDENTIFIER_BINDING (name)) + for (;; b = b->level_chain) + { + if (binding->scope == b) + return binding; + + /* Cleanup contours are transparent to the language. */ + if (b->kind != sk_cleanup) + break; + } + return NULL; +} + +class name_lookup +{ +public: + typedef std::pair<tree, tree> using_pair; + typedef vec<using_pair, va_heap, vl_embed> using_queue; + +public: + tree name; /* The identifier being looked for. */ + + /* Usually we just add things to the VALUE binding, but we record + (hidden) IMPLICIT_TYPEDEFs on the type binding, which is used for + using-decl resolution. */ + tree value; /* A (possibly ambiguous) set of things found. */ + tree type; /* A type that has been found. */ + + LOOK_want want; /* What kind of entity we want. */ + + bool deduping; /* Full deduping is needed because using declarations + are in play. */ + vec<tree, va_heap, vl_embed> *scopes; + name_lookup *previous; /* Previously active lookup. */ + +protected: + /* Marked scope stack for outermost name lookup. */ + static vec<tree, va_heap, vl_embed> *shared_scopes; + /* Currently active lookup. */ + static name_lookup *active; + +public: + name_lookup (tree n, LOOK_want w = LOOK_want::NORMAL) + : name (n), value (NULL_TREE), type (NULL_TREE), + want (w), + deduping (false), scopes (NULL), previous (NULL) + { + preserve_state (); + } + ~name_lookup () + { + gcc_checking_assert (!deduping); + restore_state (); + } + +private: /* Uncopyable, unmovable, unassignable. I am a rock. */ + name_lookup (const name_lookup &); + name_lookup &operator= (const name_lookup &); + + public: + /* Turn on or off deduping mode. */ + void dedup (bool state) + { + if (deduping != state) + { + deduping = state; + lookup_mark (value, state); + } + } + +protected: + static bool seen_p (tree scope) + { + return LOOKUP_SEEN_P (scope); + } + static bool found_p (tree scope) + { + return LOOKUP_FOUND_P (scope); + } + + void mark_seen (tree scope); /* Mark and add to scope vector. */ + static void mark_found (tree scope) + { + gcc_checking_assert (seen_p (scope)); + LOOKUP_FOUND_P (scope) = true; + } + bool see_and_mark (tree scope) + { + bool ret = seen_p (scope); + if (!ret) + mark_seen (scope); + return ret; + } + bool find_and_mark (tree scope); + +private: + void preserve_state (); + void restore_state (); + +private: + static tree ambiguous (tree thing, tree current); + void add_overload (tree fns); + void add_value (tree new_val); + void add_type (tree new_type); + bool process_binding (tree val_bind, tree type_bind); + unsigned process_module_binding (tree val_bind, tree type_bind, unsigned); + /* Look in only namespace. */ + bool search_namespace_only (tree scope); + /* Look in namespace and its (recursive) inlines. Ignore using + directives. Return true if something found (inc dups). */ + bool search_namespace (tree scope); + /* Look in the using directives of namespace + inlines using + qualified lookup rules. */ + bool search_usings (tree scope); + +private: + using_queue *queue_namespace (using_queue *queue, int depth, tree scope); + using_queue *do_queue_usings (using_queue *queue, int depth, + vec<tree, va_gc> *usings); + using_queue *queue_usings (using_queue *queue, int depth, + vec<tree, va_gc> *usings) + { + if (usings) + queue = do_queue_usings (queue, depth, usings); + return queue; + } + +private: + void add_fns (tree); + + private: + void adl_expr (tree); + void adl_type (tree); + void adl_template_arg (tree); + void adl_class (tree); + void adl_enum (tree); + void adl_bases (tree); + void adl_class_only (tree); + void adl_namespace (tree); + void adl_class_fns (tree); + void adl_namespace_fns (tree, bitmap); + +public: + /* Search namespace + inlines + maybe usings as qualified lookup. */ + bool search_qualified (tree scope, bool usings = true); + + /* Search namespace + inlines + usings as unqualified lookup. */ + bool search_unqualified (tree scope, cp_binding_level *); + + /* ADL lookup of ARGS. */ + tree search_adl (tree fns, vec<tree, va_gc> *args); +}; + +/* Scope stack shared by all outermost lookups. This avoids us + allocating and freeing on every single lookup. */ +vec<tree, va_heap, vl_embed> *name_lookup::shared_scopes; + +/* Currently active lookup. */ +name_lookup *name_lookup::active; + +/* Name lookup is recursive, becase ADL can cause template + instatiation. This is of course a rare event, so we optimize for + it not happening. When we discover an active name-lookup, which + must be an ADL lookup, we need to unmark the marked scopes and also + unmark the lookup we might have been accumulating. */ + +void +name_lookup::preserve_state () +{ + previous = active; + if (previous) + { + unsigned length = vec_safe_length (previous->scopes); + vec_safe_reserve (previous->scopes, length * 2); + for (unsigned ix = length; ix--;) + { + tree decl = (*previous->scopes)[ix]; + + gcc_checking_assert (LOOKUP_SEEN_P (decl)); + LOOKUP_SEEN_P (decl) = false; + + /* Preserve the FOUND_P state on the interrupted lookup's + stack. */ + if (LOOKUP_FOUND_P (decl)) + { + LOOKUP_FOUND_P (decl) = false; + previous->scopes->quick_push (decl); + } + } + + /* Unmark the outer partial lookup. */ + if (previous->deduping) + lookup_mark (previous->value, false); + } + else + scopes = shared_scopes; + active = this; +} + +/* Restore the marking state of a lookup we interrupted. */ + +void +name_lookup::restore_state () +{ + gcc_checking_assert (!deduping); + + /* Unmark and empty this lookup's scope stack. */ + for (unsigned ix = vec_safe_length (scopes); ix--;) + { + tree decl = scopes->pop (); + gcc_checking_assert (LOOKUP_SEEN_P (decl)); + LOOKUP_SEEN_P (decl) = false; + LOOKUP_FOUND_P (decl) = false; + } + + active = previous; + if (previous) + { + free (scopes); + + unsigned length = vec_safe_length (previous->scopes); + for (unsigned ix = 0; ix != length; ix++) + { + tree decl = (*previous->scopes)[ix]; + if (LOOKUP_SEEN_P (decl)) + { + /* The remainder of the scope stack must be recording + FOUND_P decls, which we want to pop off. */ + do + { + tree decl = previous->scopes->pop (); + gcc_checking_assert (LOOKUP_SEEN_P (decl) + && !LOOKUP_FOUND_P (decl)); + LOOKUP_FOUND_P (decl) = true; + } + while (++ix != length); + break; + } + + gcc_checking_assert (!LOOKUP_FOUND_P (decl)); + LOOKUP_SEEN_P (decl) = true; + } + + /* Remark the outer partial lookup. */ + if (previous->deduping) + lookup_mark (previous->value, true); + } + else + shared_scopes = scopes; +} + +void +name_lookup::mark_seen (tree scope) +{ + gcc_checking_assert (!seen_p (scope)); + LOOKUP_SEEN_P (scope) = true; + vec_safe_push (scopes, scope); +} + +bool +name_lookup::find_and_mark (tree scope) +{ + bool result = LOOKUP_FOUND_P (scope); + if (!result) + { + LOOKUP_FOUND_P (scope) = true; + if (!LOOKUP_SEEN_P (scope)) + vec_safe_push (scopes, scope); + } + + return result; +} + +/* THING and CURRENT are ambiguous, concatenate them. */ + +tree +name_lookup::ambiguous (tree thing, tree current) +{ + if (TREE_CODE (current) != TREE_LIST) + { + current = build_tree_list (NULL_TREE, current); + TREE_TYPE (current) = error_mark_node; + } + current = tree_cons (NULL_TREE, thing, current); + TREE_TYPE (current) = error_mark_node; + + return current; +} + +/* FNS is a new overload set to add to the exising set. */ + +void +name_lookup::add_overload (tree fns) +{ + if (!deduping && TREE_CODE (fns) == OVERLOAD) + { + tree probe = fns; + if (!bool (want & LOOK_want::HIDDEN_FRIEND)) + probe = ovl_skip_hidden (probe); + if (probe && TREE_CODE (probe) == OVERLOAD + && OVL_DEDUP_P (probe)) + /* We're about to add something found by multiple paths, so need to + engage deduping mode. */ + dedup (true); + } + + value = lookup_maybe_add (fns, value, deduping); +} + +/* Add a NEW_VAL, a found value binding into the current value binding. */ + +void +name_lookup::add_value (tree new_val) +{ + if (OVL_P (new_val) && (!value || OVL_P (value))) + add_overload (new_val); + else if (!value) + value = new_val; + else if (value == new_val) + ; + else if ((TREE_CODE (value) == TYPE_DECL + && TREE_CODE (new_val) == TYPE_DECL + && same_type_p (TREE_TYPE (value), TREE_TYPE (new_val)))) + /* Typedefs to the same type. */; + else if (TREE_CODE (value) == NAMESPACE_DECL + && TREE_CODE (new_val) == NAMESPACE_DECL + && ORIGINAL_NAMESPACE (value) == ORIGINAL_NAMESPACE (new_val)) + /* Namespace (possibly aliased) to the same namespace. Locate + the namespace*/ + value = ORIGINAL_NAMESPACE (value); + else + { + /* Disengage deduping mode. */ + dedup (false); + value = ambiguous (new_val, value); + } +} + +/* Add a NEW_TYPE, a found type binding into the current type binding. */ + +void +name_lookup::add_type (tree new_type) +{ + if (!type) + type = new_type; + else if (TREE_CODE (type) == TREE_LIST + || !same_type_p (TREE_TYPE (type), TREE_TYPE (new_type))) + type = ambiguous (new_type, type); +} + +/* Process a found binding containing NEW_VAL and NEW_TYPE. Returns + true if we actually found something noteworthy. Hiddenness has + already been handled in the caller. */ + +bool +name_lookup::process_binding (tree new_val, tree new_type) +{ + /* Did we really see a type? */ + if (new_type + && (want & LOOK_want::TYPE_NAMESPACE) == LOOK_want::NAMESPACE) + new_type = NULL_TREE; + + /* Do we really see a value? */ + if (new_val) + switch (TREE_CODE (new_val)) + { + case TEMPLATE_DECL: + /* If we expect types or namespaces, and not templates, + or this is not a template class. */ + if (bool (want & LOOK_want::TYPE_NAMESPACE) + && !DECL_TYPE_TEMPLATE_P (new_val)) + new_val = NULL_TREE; + break; + case TYPE_DECL: + if ((want & LOOK_want::TYPE_NAMESPACE) == LOOK_want::NAMESPACE + || (new_type && bool (want & LOOK_want::TYPE))) + new_val = NULL_TREE; + break; + case NAMESPACE_DECL: + if ((want & LOOK_want::TYPE_NAMESPACE) == LOOK_want::TYPE) + new_val = NULL_TREE; + break; + default: + if (bool (want & LOOK_want::TYPE_NAMESPACE)) + new_val = NULL_TREE; + } + + if (!new_val) + { + new_val = new_type; + new_type = NULL_TREE; + } + + /* Merge into the lookup */ + if (new_val) + add_value (new_val); + if (new_type) + add_type (new_type); + + return new_val != NULL_TREE; +} + +/* If we're importing a module containing this binding, add it to the + lookup set. The trickiness is with namespaces, we only want to + find it once. */ + +unsigned +name_lookup::process_module_binding (tree new_val, tree new_type, + unsigned marker) +{ + /* Optimize for (re-)finding a public namespace. We only need to + look once. */ + if (new_val && !new_type + && TREE_CODE (new_val) == NAMESPACE_DECL + && TREE_PUBLIC (new_val) + && !DECL_NAMESPACE_ALIAS (new_val)) + { + if (marker & 2) + return marker; + marker |= 2; + } + + if (new_type || new_val) + marker |= process_binding (new_val, new_type); + + return marker; +} + +/* Look in exactly namespace SCOPE. */ + +bool +name_lookup::search_namespace_only (tree scope) +{ + bool found = false; + if (tree *binding = find_namespace_slot (scope, name)) + { + tree val = *binding; + if (TREE_CODE (val) == BINDING_VECTOR) + { + /* I presume the binding list is going to be sparser than + the import bitmap. Hence iterate over the former + checking for bits set in the bitmap. */ + bitmap imports = get_import_bitmap (); + binding_cluster *cluster = BINDING_VECTOR_CLUSTER_BASE (val); + int marker = 0; + int dup_detect = 0; + + if (tree bind = cluster->slots[BINDING_SLOT_CURRENT]) + { + if (!deduping) + { + if (named_module_purview_p ()) + { + dup_detect |= 2; + + if (STAT_HACK_P (bind) && MODULE_BINDING_GLOBAL_P (bind)) + dup_detect |= 1; + } + else + dup_detect |= 1; + } + tree type = NULL_TREE; + tree value = bind; + + if (STAT_HACK_P (bind)) + { + type = STAT_TYPE (bind); + value = STAT_DECL (bind); + + if (!bool (want & LOOK_want::HIDDEN_FRIEND)) + { + if (STAT_TYPE_HIDDEN_P (bind)) + type = NULL_TREE; + if (STAT_DECL_HIDDEN_P (bind)) + value = NULL_TREE; + else + value = ovl_skip_hidden (value); + } + } + else if (!bool (want & LOOK_want::HIDDEN_FRIEND)) + value = ovl_skip_hidden (value); + + marker = process_module_binding (value, type, marker); + } + + /* Scan the imported bindings. */ + unsigned ix = BINDING_VECTOR_NUM_CLUSTERS (val); + if (BINDING_VECTOR_SLOTS_PER_CLUSTER == BINDING_SLOTS_FIXED) + { + ix--; + cluster++; + } + + /* Do this in forward order, so we load modules in an order + the user expects. */ + for (; ix--; cluster++) + for (unsigned jx = 0; jx != BINDING_VECTOR_SLOTS_PER_CLUSTER; jx++) + { + /* Are we importing this module? */ + if (unsigned base = cluster->indices[jx].base) + if (unsigned span = cluster->indices[jx].span) + do + if (bitmap_bit_p (imports, base)) + goto found; + while (++base, --span); + continue; + + found:; + /* Is it loaded? */ + if (cluster->slots[jx].is_lazy ()) + { + gcc_assert (cluster->indices[jx].span == 1); + lazy_load_binding (cluster->indices[jx].base, + scope, name, &cluster->slots[jx]); + } + tree bind = cluster->slots[jx]; + if (!bind) + /* Load errors could mean there's nothing here. */ + continue; + + /* Extract what we can see from here. If there's no + stat_hack, then everything was exported. */ + tree type = NULL_TREE; + + + /* If STAT_HACK_P is false, everything is visible, and + there's no duplication possibilities. */ + if (STAT_HACK_P (bind)) + { + if (!deduping) + { + /* Do we need to engage deduplication? */ + int dup = 0; + if (MODULE_BINDING_GLOBAL_P (bind)) + dup = 1; + else if (MODULE_BINDING_PARTITION_P (bind)) + dup = 2; + if (unsigned hit = dup_detect & dup) + { + if ((hit & 1 && BINDING_VECTOR_GLOBAL_DUPS_P (val)) + || (hit & 2 + && BINDING_VECTOR_PARTITION_DUPS_P (val))) + dedup (true); + } + dup_detect |= dup; + } + + if (STAT_TYPE_VISIBLE_P (bind)) + type = STAT_TYPE (bind); + bind = STAT_VISIBLE (bind); + } + + /* And process it. */ + marker = process_module_binding (bind, type, marker); + } + found |= marker & 1; + } + else + { + /* Only a current module binding, visible from the current module. */ + tree bind = *binding; + tree value = bind, type = NULL_TREE; + + if (STAT_HACK_P (bind)) + { + type = STAT_TYPE (bind); + value = STAT_DECL (bind); + + if (!bool (want & LOOK_want::HIDDEN_FRIEND)) + { + if (STAT_TYPE_HIDDEN_P (bind)) + type = NULL_TREE; + if (STAT_DECL_HIDDEN_P (bind)) + value = NULL_TREE; + else + value = ovl_skip_hidden (value); + } + } + else if (!bool (want & LOOK_want::HIDDEN_FRIEND)) + value = ovl_skip_hidden (value); + + found |= process_binding (value, type); + } + } + + return found; +} + +/* Conditionally look in namespace SCOPE and inline children. */ + +bool +name_lookup::search_namespace (tree scope) +{ + if (see_and_mark (scope)) + /* We've visited this scope before. Return what we found then. */ + return found_p (scope); + + /* Look in exactly namespace. */ + bool found = search_namespace_only (scope); + + /* Don't look into inline children, if we're looking for an + anonymous name -- it must be in the current scope, if anywhere. */ + if (name) + /* Recursively look in its inline children. */ + if (vec<tree, va_gc> *inlinees = DECL_NAMESPACE_INLINEES (scope)) + for (unsigned ix = inlinees->length (); ix--;) + found |= search_namespace ((*inlinees)[ix]); + + if (found) + mark_found (scope); + + return found; +} + +/* Recursively follow using directives of SCOPE & its inline children. + Such following is essentially a flood-fill algorithm. */ + +bool +name_lookup::search_usings (tree scope) +{ + /* We do not check seen_p here, as that was already set during the + namespace_only walk. */ + if (found_p (scope)) + return true; + + bool found = false; + if (vec<tree, va_gc> *usings = NAMESPACE_LEVEL (scope)->using_directives) + for (unsigned ix = usings->length (); ix--;) + found |= search_qualified ((*usings)[ix], true); + + /* Look in its inline children. */ + if (vec<tree, va_gc> *inlinees = DECL_NAMESPACE_INLINEES (scope)) + for (unsigned ix = inlinees->length (); ix--;) + found |= search_usings ((*inlinees)[ix]); + + if (found) + mark_found (scope); + + return found; +} + +/* Qualified namespace lookup in SCOPE. + 1) Look in SCOPE (+inlines). If found, we're done. + 2) Otherwise, if USINGS is true, + recurse for every using directive of SCOPE (+inlines). + + Trickiness is (a) loops and (b) multiple paths to same namespace. + In both cases we want to not repeat any lookups, and know whether + to stop the caller's step #2. Do this via the FOUND_P marker. */ + +bool +name_lookup::search_qualified (tree scope, bool usings) +{ + bool found = false; + + if (seen_p (scope)) + found = found_p (scope); + else + { + found = search_namespace (scope); + if (!found && usings) + found = search_usings (scope); + } + + dedup (false); + + return found; +} + +/* Add SCOPE to the unqualified search queue, recursively add its + inlines and those via using directives. */ + +name_lookup::using_queue * +name_lookup::queue_namespace (using_queue *queue, int depth, tree scope) +{ + if (see_and_mark (scope)) + return queue; + + /* Record it. */ + tree common = scope; + while (SCOPE_DEPTH (common) > depth) + common = CP_DECL_CONTEXT (common); + vec_safe_push (queue, using_pair (common, scope)); + + /* Queue its inline children. */ + if (vec<tree, va_gc> *inlinees = DECL_NAMESPACE_INLINEES (scope)) + for (unsigned ix = inlinees->length (); ix--;) + queue = queue_namespace (queue, depth, (*inlinees)[ix]); + + /* Queue its using targets. */ + queue = queue_usings (queue, depth, NAMESPACE_LEVEL (scope)->using_directives); + + return queue; +} + +/* Add the namespaces in USINGS to the unqualified search queue. */ + +name_lookup::using_queue * +name_lookup::do_queue_usings (using_queue *queue, int depth, + vec<tree, va_gc> *usings) +{ + for (unsigned ix = usings->length (); ix--;) + queue = queue_namespace (queue, depth, (*usings)[ix]); + + return queue; +} + +/* Unqualified namespace lookup in SCOPE. + 1) add scope+inlins to worklist. + 2) recursively add target of every using directive + 3) for each worklist item where SCOPE is common ancestor, search it + 4) if nothing find, scope=parent, goto 1. */ + +bool +name_lookup::search_unqualified (tree scope, cp_binding_level *level) +{ + /* Make static to avoid continual reallocation. We're not + recursive. */ + static using_queue *queue = NULL; + bool found = false; + int length = vec_safe_length (queue); + + /* Queue local using-directives. */ + for (; level->kind != sk_namespace; level = level->level_chain) + queue = queue_usings (queue, SCOPE_DEPTH (scope), level->using_directives); + + for (; !found; scope = CP_DECL_CONTEXT (scope)) + { + gcc_assert (!DECL_NAMESPACE_ALIAS (scope)); + int depth = SCOPE_DEPTH (scope); + + /* Queue namespaces reachable from SCOPE. */ + queue = queue_namespace (queue, depth, scope); + + /* Search every queued namespace where SCOPE is the common + ancestor. Adjust the others. */ + unsigned ix = length; + do + { + using_pair &pair = (*queue)[ix]; + while (pair.first == scope) + { + found |= search_namespace_only (pair.second); + pair = queue->pop (); + if (ix == queue->length ()) + goto done; + } + /* The depth is the same as SCOPE, find the parent scope. */ + if (SCOPE_DEPTH (pair.first) == depth) + pair.first = CP_DECL_CONTEXT (pair.first); + ix++; + } + while (ix < queue->length ()); + done:; + if (scope == global_namespace) + break; + + /* If looking for hidden friends, we only look in the innermost + namespace scope. [namespace.memdef]/3 If a friend + declaration in a non-local class first declares a class, + function, class template or function template the friend is a + member of the innermost enclosing namespace. See also + [basic.lookup.unqual]/7 */ + if (bool (want & LOOK_want::HIDDEN_FRIEND)) + break; + } + + dedup (false); + + /* Restore to incoming length. */ + vec_safe_truncate (queue, length); + + return found; +} + +/* FNS is a value binding. If it is a (set of overloaded) functions, + add them into the current value. */ + +void +name_lookup::add_fns (tree fns) +{ + if (!fns) + return; + else if (TREE_CODE (fns) == OVERLOAD) + { + if (TREE_TYPE (fns) != unknown_type_node) + fns = OVL_FUNCTION (fns); + } + else if (!DECL_DECLARES_FUNCTION_P (fns)) + return; + + add_overload (fns); +} + +/* Add the overloaded fns of SCOPE. */ + +void +name_lookup::adl_namespace_fns (tree scope, bitmap imports) +{ + if (tree *binding = find_namespace_slot (scope, name)) + { + tree val = *binding; + if (TREE_CODE (val) != BINDING_VECTOR) + add_fns (ovl_skip_hidden (MAYBE_STAT_DECL (val))); + else + { + /* I presume the binding list is going to be sparser than + the import bitmap. Hence iterate over the former + checking for bits set in the bitmap. */ + binding_cluster *cluster = BINDING_VECTOR_CLUSTER_BASE (val); + int dup_detect = 0; + + if (tree bind = cluster->slots[BINDING_SLOT_CURRENT]) + { + /* The current TU's bindings must be visible, we don't + need to check the bitmaps. */ + + if (!deduping) + { + if (named_module_purview_p ()) + { + dup_detect |= 2; + + if (STAT_HACK_P (bind) && MODULE_BINDING_GLOBAL_P (bind)) + dup_detect |= 1; + } + else + dup_detect |= 1; + } + + add_fns (ovl_skip_hidden (MAYBE_STAT_DECL (bind))); + } + + /* Scan the imported bindings. */ + unsigned ix = BINDING_VECTOR_NUM_CLUSTERS (val); + if (BINDING_VECTOR_SLOTS_PER_CLUSTER == BINDING_SLOTS_FIXED) + { + ix--; + cluster++; + } + + /* Do this in forward order, so we load modules in an order + the user expects. */ + for (; ix--; cluster++) + for (unsigned jx = 0; jx != BINDING_VECTOR_SLOTS_PER_CLUSTER; jx++) + { + /* Functions are never on merged slots. */ + if (!cluster->indices[jx].base + || cluster->indices[jx].span != 1) + continue; + + /* Is this slot visible? */ + if (!bitmap_bit_p (imports, cluster->indices[jx].base)) + continue; + + /* Is it loaded. */ + if (cluster->slots[jx].is_lazy ()) + lazy_load_binding (cluster->indices[jx].base, + scope, name, &cluster->slots[jx]); + + tree bind = cluster->slots[jx]; + if (!bind) + /* Load errors could mean there's nothing here. */ + continue; + + if (STAT_HACK_P (bind)) + { + if (!deduping) + { + /* Do we need to engage deduplication? */ + int dup = 0; + if (MODULE_BINDING_GLOBAL_P (bind)) + dup = 1; + else if (MODULE_BINDING_PARTITION_P (bind)) + dup = 2; + if (unsigned hit = dup_detect & dup) + if ((hit & 1 && BINDING_VECTOR_GLOBAL_DUPS_P (val)) + || (hit & 2 + && BINDING_VECTOR_PARTITION_DUPS_P (val))) + dedup (true); + dup_detect |= dup; + } + + bind = STAT_VISIBLE (bind); + } + + add_fns (bind); + } + } + } +} + +/* Add the hidden friends of SCOPE. */ + +void +name_lookup::adl_class_fns (tree type) +{ + /* Add friends. */ + for (tree list = DECL_FRIENDLIST (TYPE_MAIN_DECL (type)); + list; list = TREE_CHAIN (list)) + if (name == FRIEND_NAME (list)) + { + tree context = NULL_TREE; /* Lazily computed. */ + for (tree friends = FRIEND_DECLS (list); friends; + friends = TREE_CHAIN (friends)) + { + tree fn = TREE_VALUE (friends); + + /* Only interested in global functions with potentially hidden + (i.e. unqualified) declarations. */ + if (!context) + context = decl_namespace_context (type); + if (CP_DECL_CONTEXT (fn) != context) + continue; + + dedup (true); + + /* Template specializations are never found by name lookup. + (Templates themselves can be found, but not template + specializations.) */ + if (TREE_CODE (fn) == FUNCTION_DECL && DECL_USE_TEMPLATE (fn)) + continue; + + add_fns (fn); + } + } +} + +/* Find the containing non-inlined namespace, add it and all its + inlinees. */ + +void +name_lookup::adl_namespace (tree scope) +{ + if (see_and_mark (scope)) + return; + + /* Look down into inline namespaces. */ + if (vec<tree, va_gc> *inlinees = DECL_NAMESPACE_INLINEES (scope)) + for (unsigned ix = inlinees->length (); ix--;) + adl_namespace ((*inlinees)[ix]); + + if (DECL_NAMESPACE_INLINE_P (scope)) + /* Mark parent. */ + adl_namespace (CP_DECL_CONTEXT (scope)); +} + +/* Adds the class and its friends to the lookup structure. */ + +void +name_lookup::adl_class_only (tree type) +{ + /* Backend-built structures, such as __builtin_va_list, aren't + affected by all this. */ + if (!CLASS_TYPE_P (type)) + return; + + type = TYPE_MAIN_VARIANT (type); + + if (see_and_mark (type)) + return; + + tree context = decl_namespace_context (type); + adl_namespace (context); +} + +/* Adds the class and its bases to the lookup structure. + Returns true on error. */ + +void +name_lookup::adl_bases (tree type) +{ + adl_class_only (type); + + /* Process baseclasses. */ + if (tree binfo = TYPE_BINFO (type)) + { + tree base_binfo; + int i; + + for (i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); i++) + adl_bases (BINFO_TYPE (base_binfo)); + } +} + +/* Adds everything associated with a class argument type to the lookup + structure. + + If T is a class type (including unions), its associated classes are: the + class itself; the class of which it is a member, if any; and its direct + and indirect base classes. Its associated namespaces are the namespaces + of which its associated classes are members. Furthermore, if T is a + class template specialization, its associated namespaces and classes + also include: the namespaces and classes associated with the types of + the template arguments provided for template type parameters (excluding + template template parameters); the namespaces of which any template + template arguments are members; and the classes of which any member + templates used as template template arguments are members. [ Note: + non-type template arguments do not contribute to the set of associated + namespaces. --end note] */ + +void +name_lookup::adl_class (tree type) +{ + /* Backend build structures, such as __builtin_va_list, aren't + affected by all this. */ + if (!CLASS_TYPE_P (type)) + return; + + type = TYPE_MAIN_VARIANT (type); + + /* We don't set found here because we have to have set seen first, + which is done in the adl_bases walk. */ + if (found_p (type)) + return; + + complete_type (type); + adl_bases (type); + mark_found (type); + + if (TYPE_CLASS_SCOPE_P (type)) + adl_class_only (TYPE_CONTEXT (type)); + + /* Process template arguments. */ + if (CLASSTYPE_TEMPLATE_INFO (type) + && PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (type))) + { + tree list = INNERMOST_TEMPLATE_ARGS (CLASSTYPE_TI_ARGS (type)); + for (int i = 0; i < TREE_VEC_LENGTH (list); ++i) + adl_template_arg (TREE_VEC_ELT (list, i)); + } +} + +void +name_lookup::adl_enum (tree type) +{ + type = TYPE_MAIN_VARIANT (type); + if (see_and_mark (type)) + return; + + if (TYPE_CLASS_SCOPE_P (type)) + adl_class_only (TYPE_CONTEXT (type)); + else + adl_namespace (decl_namespace_context (type)); +} + +void +name_lookup::adl_expr (tree expr) +{ + if (!expr) + return; + + gcc_assert (!TYPE_P (expr)); + + if (TREE_TYPE (expr) != unknown_type_node) + { + adl_type (unlowered_expr_type (expr)); + return; + } + + if (TREE_CODE (expr) == ADDR_EXPR) + expr = TREE_OPERAND (expr, 0); + if (TREE_CODE (expr) == COMPONENT_REF + || TREE_CODE (expr) == OFFSET_REF) + expr = TREE_OPERAND (expr, 1); + expr = MAYBE_BASELINK_FUNCTIONS (expr); + + if (OVL_P (expr)) + for (lkp_iterator iter (expr); iter; ++iter) + adl_type (TREE_TYPE (*iter)); + else if (TREE_CODE (expr) == TEMPLATE_ID_EXPR) + { + /* The working paper doesn't currently say how to handle + template-id arguments. The sensible thing would seem to be + to handle the list of template candidates like a normal + overload set, and handle the template arguments like we do + for class template specializations. */ + + /* First the templates. */ + adl_expr (TREE_OPERAND (expr, 0)); + + /* Now the arguments. */ + if (tree args = TREE_OPERAND (expr, 1)) + for (int ix = TREE_VEC_LENGTH (args); ix--;) + adl_template_arg (TREE_VEC_ELT (args, ix)); + } +} + +void +name_lookup::adl_type (tree type) +{ + if (!type) + return; + + if (TYPE_PTRDATAMEM_P (type)) + { + /* Pointer to member: associate class type and value type. */ + adl_type (TYPE_PTRMEM_CLASS_TYPE (type)); + adl_type (TYPE_PTRMEM_POINTED_TO_TYPE (type)); + return; + } + + switch (TREE_CODE (type)) + { + case RECORD_TYPE: + if (TYPE_PTRMEMFUNC_P (type)) + { + adl_type (TYPE_PTRMEMFUNC_FN_TYPE (type)); + return; + } + /* FALLTHRU */ + case UNION_TYPE: + adl_class (type); + return; + + case METHOD_TYPE: + /* The basetype is referenced in the first arg type, so just + fall through. */ + case FUNCTION_TYPE: + /* Associate the parameter types. */ + for (tree args = TYPE_ARG_TYPES (type); args; args = TREE_CHAIN (args)) + adl_type (TREE_VALUE (args)); + /* FALLTHROUGH */ + + case POINTER_TYPE: + case REFERENCE_TYPE: + case ARRAY_TYPE: + adl_type (TREE_TYPE (type)); + return; + + case ENUMERAL_TYPE: + adl_enum (type); + return; + + case LANG_TYPE: + gcc_assert (type == unknown_type_node + || type == init_list_type_node); + return; + + case TYPE_PACK_EXPANSION: + adl_type (PACK_EXPANSION_PATTERN (type)); + return; + + default: + break; + } +} + +/* Adds everything associated with a template argument to the lookup + structure. */ + +void +name_lookup::adl_template_arg (tree arg) +{ + /* [basic.lookup.koenig] + + If T is a template-id, its associated namespaces and classes are + ... the namespaces and classes associated with the types of the + template arguments provided for template type parameters + (excluding template template parameters); the namespaces in which + any template template arguments are defined; and the classes in + which any member templates used as template template arguments + are defined. [Note: non-type template arguments do not + contribute to the set of associated namespaces. ] */ + + /* Consider first template template arguments. */ + if (TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM + || TREE_CODE (arg) == UNBOUND_CLASS_TEMPLATE) + ; + else if (TREE_CODE (arg) == TEMPLATE_DECL) + { + tree ctx = CP_DECL_CONTEXT (arg); + + /* It's not a member template. */ + if (TREE_CODE (ctx) == NAMESPACE_DECL) + adl_namespace (ctx); + /* Otherwise, it must be member template. */ + else + adl_class_only (ctx); + } + /* It's an argument pack; handle it recursively. */ + else if (ARGUMENT_PACK_P (arg)) + { + tree args = ARGUMENT_PACK_ARGS (arg); + int i, len = TREE_VEC_LENGTH (args); + for (i = 0; i < len; ++i) + adl_template_arg (TREE_VEC_ELT (args, i)); + } + /* It's not a template template argument, but it is a type template + argument. */ + else if (TYPE_P (arg)) + adl_type (arg); +} + +/* Perform ADL lookup. FNS is the existing lookup result and ARGS are + the call arguments. */ + +tree +name_lookup::search_adl (tree fns, vec<tree, va_gc> *args) +{ + gcc_checking_assert (!vec_safe_length (scopes)); + + /* Gather each associated entity onto the lookup's scope list. */ + unsigned ix; + tree arg; + + FOR_EACH_VEC_ELT_REVERSE (*args, ix, arg) + /* OMP reduction operators put an ADL-significant type as the + first arg. */ + if (TYPE_P (arg)) + adl_type (arg); + else + adl_expr (arg); + + if (vec_safe_length (scopes)) + { + /* Now do the lookups. */ + value = fns; + if (fns) + dedup (true); + + /* INST_PATH will be NULL, if this is /not/ 2nd-phase ADL. */ + bitmap inst_path = NULL; + /* VISIBLE is the regular import bitmap. */ + bitmap visible = visible_instantiation_path (&inst_path); + + for (unsigned ix = scopes->length (); ix--;) + { + tree scope = (*scopes)[ix]; + if (TREE_CODE (scope) == NAMESPACE_DECL) + adl_namespace_fns (scope, visible); + else + { + if (RECORD_OR_UNION_TYPE_P (scope)) + adl_class_fns (scope); + + /* During 2nd phase ADL: Any exported declaration D in N + declared within the purview of a named module M + (10.2) is visible if there is an associated entity + attached to M with the same innermost enclosing + non-inline namespace as D. + [basic.lookup.argdep]/4.4 */ + + if (!inst_path) + /* Not 2nd phase. */ + continue; + + tree ctx = CP_DECL_CONTEXT (TYPE_NAME (scope)); + if (TREE_CODE (ctx) != NAMESPACE_DECL) + /* Not namespace-scope class. */ + continue; + + tree origin = get_originating_module_decl (TYPE_NAME (scope)); + tree not_tmpl = STRIP_TEMPLATE (origin); + if (!DECL_LANG_SPECIFIC (not_tmpl) + || !DECL_MODULE_IMPORT_P (not_tmpl)) + /* Not imported. */ + continue; + + unsigned module = get_importing_module (origin); + + if (!bitmap_bit_p (inst_path, module)) + /* Not on path of instantiation. */ + continue; + + if (bitmap_bit_p (visible, module)) + /* If the module was in the visible set, we'll look at + its namespace partition anyway. */ + continue; + + if (tree *slot = find_namespace_slot (ctx, name, false)) + if (binding_slot *mslot = search_imported_binding_slot (slot, module)) + { + if (mslot->is_lazy ()) + lazy_load_binding (module, ctx, name, mslot); + + if (tree bind = *mslot) + { + /* We must turn on deduping, because some other class + from this module might also be in this namespace. */ + dedup (true); + + /* Add the exported fns */ + if (STAT_HACK_P (bind)) + add_fns (STAT_VISIBLE (bind)); + } + } + } + } + + fns = value; + dedup (false); + } + + return fns; +} + +static bool qualified_namespace_lookup (tree, name_lookup *); +static void consider_binding_level (tree name, + best_match <tree, const char *> &bm, + cp_binding_level *lvl, + bool look_within_fields, + enum lookup_name_fuzzy_kind kind); +static void diagnose_name_conflict (tree, tree); + +/* ADL lookup of NAME. FNS is the result of regular lookup, and we + don't add duplicates to it. ARGS is the vector of call + arguments (which will not be empty). */ + +tree +lookup_arg_dependent (tree name, tree fns, vec<tree, va_gc> *args) +{ + auto_cond_timevar tv (TV_NAME_LOOKUP); + name_lookup lookup (name); + return lookup.search_adl (fns, args); +} + +/* FNS is an overload set of conversion functions. Return the + overloads converting to TYPE. */ + +static tree +extract_conversion_operator (tree fns, tree type) +{ + tree convs = NULL_TREE; + tree tpls = NULL_TREE; + + for (ovl_iterator iter (fns); iter; ++iter) + { + if (same_type_p (DECL_CONV_FN_TYPE (*iter), type)) + convs = lookup_add (*iter, convs); + + if (TREE_CODE (*iter) == TEMPLATE_DECL) + tpls = lookup_add (*iter, tpls); + } + + if (!convs) + convs = tpls; + + return convs; +} + +/* Binary search of (ordered) MEMBER_VEC for NAME. */ + +static tree +member_vec_binary_search (vec<tree, va_gc> *member_vec, tree name) +{ + for (unsigned lo = 0, hi = member_vec->length (); lo < hi;) + { + unsigned mid = (lo + hi) / 2; + tree binding = (*member_vec)[mid]; + tree binding_name = OVL_NAME (binding); + + if (binding_name > name) + hi = mid; + else if (binding_name < name) + lo = mid + 1; + else + return binding; + } + + return NULL_TREE; +} + +/* Linear search of (unordered) MEMBER_VEC for NAME. */ + +static tree +member_vec_linear_search (vec<tree, va_gc> *member_vec, tree name) +{ + for (int ix = member_vec->length (); ix--;) + if (tree binding = (*member_vec)[ix]) + if (OVL_NAME (binding) == name) + return binding; + + return NULL_TREE; +} + +/* Linear search of (partially ordered) fields of KLASS for NAME. */ + +static tree +fields_linear_search (tree klass, tree name, bool want_type) +{ + for (tree fields = TYPE_FIELDS (klass); fields; fields = DECL_CHAIN (fields)) + { + tree decl = fields; + + if (TREE_CODE (decl) == FIELD_DECL + && ANON_AGGR_TYPE_P (TREE_TYPE (decl))) + { + if (tree temp = search_anon_aggr (TREE_TYPE (decl), name, want_type)) + return temp; + } + + if (DECL_NAME (decl) != name) + continue; + + if (TREE_CODE (decl) == USING_DECL) + { + decl = strip_using_decl (decl); + if (is_overloaded_fn (decl)) + continue; + } + + if (DECL_DECLARES_FUNCTION_P (decl)) + /* Functions are found separately. */ + continue; + + if (!want_type || DECL_DECLARES_TYPE_P (decl)) + return decl; + } + + return NULL_TREE; +} + +/* Look for NAME member inside of anonymous aggregate ANON. Although + such things should only contain FIELD_DECLs, we check that too + late, and would give very confusing errors if we weren't + permissive here. */ + +tree +search_anon_aggr (tree anon, tree name, bool want_type) +{ + gcc_assert (COMPLETE_TYPE_P (anon)); + tree ret = get_class_binding_direct (anon, name, want_type); + return ret; +} + +/* Look for NAME as an immediate member of KLASS (including + anon-members or unscoped enum member). TYPE_OR_FNS is zero for + regular search. >0 to get a type binding (if there is one) and <0 + if you want (just) the member function binding. + + Use this if you do not want lazy member creation. */ + +tree +get_class_binding_direct (tree klass, tree name, bool want_type) +{ + gcc_checking_assert (RECORD_OR_UNION_TYPE_P (klass)); + + /* Conversion operators can only be found by the marker conversion + operator name. */ + bool conv_op = IDENTIFIER_CONV_OP_P (name); + tree lookup = conv_op ? conv_op_identifier : name; + tree val = NULL_TREE; + vec<tree, va_gc> *member_vec = CLASSTYPE_MEMBER_VEC (klass); + + if (COMPLETE_TYPE_P (klass) && member_vec) + { + val = member_vec_binary_search (member_vec, lookup); + if (!val) + ; + else if (STAT_HACK_P (val)) + val = want_type ? STAT_TYPE (val) : STAT_DECL (val); + else if (want_type && !DECL_DECLARES_TYPE_P (val)) + val = NULL_TREE; + } + else + { + if (member_vec && !want_type) + val = member_vec_linear_search (member_vec, lookup); + + if (!val || (TREE_CODE (val) == OVERLOAD && OVL_DEDUP_P (val))) + /* Dependent using declarations are a 'field', make sure we + return that even if we saw an overload already. */ + if (tree field_val = fields_linear_search (klass, lookup, want_type)) + { + if (!val) + val = field_val; + else if (TREE_CODE (field_val) == USING_DECL) + val = ovl_make (field_val, val); + } + } + + /* Extract the conversion operators asked for, unless the general + conversion operator was requested. */ + if (val && conv_op) + { + gcc_checking_assert (OVL_FUNCTION (val) == conv_op_marker); + val = OVL_CHAIN (val); + if (tree type = TREE_TYPE (name)) + val = extract_conversion_operator (val, type); + } + + return val; +} + +/* We're about to lookup NAME in KLASS. Make sure any lazily declared + members are now declared. */ + +static void +maybe_lazily_declare (tree klass, tree name) +{ + /* See big comment anout module_state::write_pendings regarding adding a check + bit. */ + if (modules_p ()) + lazy_load_pendings (TYPE_NAME (klass)); + + /* Lazily declare functions, if we're going to search these. */ + if (IDENTIFIER_CTOR_P (name)) + { + if (CLASSTYPE_LAZY_DEFAULT_CTOR (klass)) + lazily_declare_fn (sfk_constructor, klass); + if (CLASSTYPE_LAZY_COPY_CTOR (klass)) + lazily_declare_fn (sfk_copy_constructor, klass); + if (CLASSTYPE_LAZY_MOVE_CTOR (klass)) + lazily_declare_fn (sfk_move_constructor, klass); + } + else if (IDENTIFIER_DTOR_P (name)) + { + if (CLASSTYPE_LAZY_DESTRUCTOR (klass)) + lazily_declare_fn (sfk_destructor, klass); + } + else if (name == assign_op_identifier) + { + if (CLASSTYPE_LAZY_COPY_ASSIGN (klass)) + lazily_declare_fn (sfk_copy_assignment, klass); + if (CLASSTYPE_LAZY_MOVE_ASSIGN (klass)) + lazily_declare_fn (sfk_move_assignment, klass); + } +} + +/* Look for NAME's binding in exactly KLASS. See + get_class_binding_direct for argument description. Does lazy + special function creation as necessary. */ + +tree +get_class_binding (tree klass, tree name, bool want_type /*=false*/) +{ + klass = complete_type (klass); + + if (COMPLETE_TYPE_P (klass)) + maybe_lazily_declare (klass, name); + + return get_class_binding_direct (klass, name, want_type); +} + +/* Find the slot containing overloads called 'NAME'. If there is no + such slot and the class is complete, create an empty one, at the + correct point in the sorted member vector. Otherwise return NULL. + Deals with conv_op marker handling. */ + +tree * +find_member_slot (tree klass, tree name) +{ + bool complete_p = COMPLETE_TYPE_P (klass); + + vec<tree, va_gc> *member_vec = CLASSTYPE_MEMBER_VEC (klass); + if (!member_vec) + { + vec_alloc (member_vec, 8); + CLASSTYPE_MEMBER_VEC (klass) = member_vec; + if (complete_p) + /* If the class is complete but had no member_vec, we need to + add the TYPE_FIELDS into it. We're also most likely to be + adding ctors & dtors, so ask for 6 spare slots (the + abstract cdtors and their clones). */ + member_vec = set_class_bindings (klass, 6); + } + + if (IDENTIFIER_CONV_OP_P (name)) + name = conv_op_identifier; + + unsigned ix, length = member_vec->length (); + for (ix = 0; ix < length; ix++) + { + tree *slot = &(*member_vec)[ix]; + tree fn_name = OVL_NAME (*slot); + + if (fn_name == name) + { + /* If we found an existing slot, it must be a function set. + Even with insertion after completion, because those only + happen with artificial fns that have unspellable names. + This means we do not have to deal with the stat hack + either. */ + gcc_checking_assert (OVL_P (*slot)); + if (name == conv_op_identifier) + { + gcc_checking_assert (OVL_FUNCTION (*slot) == conv_op_marker); + /* Skip the conv-op marker. */ + slot = &OVL_CHAIN (*slot); + } + return slot; + } + + if (complete_p && fn_name > name) + break; + } + + /* No slot found, add one if the class is complete. */ + if (complete_p) + { + /* Do exact allocation, as we don't expect to add many. */ + gcc_assert (name != conv_op_identifier); + vec_safe_reserve_exact (member_vec, 1); + CLASSTYPE_MEMBER_VEC (klass) = member_vec; + member_vec->quick_insert (ix, NULL_TREE); + return &(*member_vec)[ix]; + } + + return NULL; +} + +/* KLASS is an incomplete class to which we're adding a method NAME. + Add a slot and deal with conv_op marker handling. */ + +tree * +add_member_slot (tree klass, tree name) +{ + gcc_assert (!COMPLETE_TYPE_P (klass)); + + vec<tree, va_gc> *member_vec = CLASSTYPE_MEMBER_VEC (klass); + vec_safe_push (member_vec, NULL_TREE); + CLASSTYPE_MEMBER_VEC (klass) = member_vec; + + tree *slot = &member_vec->last (); + if (IDENTIFIER_CONV_OP_P (name)) + { + /* Install the marker prefix. */ + *slot = ovl_make (conv_op_marker, NULL_TREE); + slot = &OVL_CHAIN (*slot); + } + + return slot; +} + +/* Comparison function to compare two MEMBER_VEC entries by name. + Because we can have duplicates during insertion of TYPE_FIELDS, we + do extra checking so deduping doesn't have to deal with so many + cases. */ + +static int +member_name_cmp (const void *a_p, const void *b_p) +{ + tree a = *(const tree *)a_p; + tree b = *(const tree *)b_p; + tree name_a = DECL_NAME (TREE_CODE (a) == OVERLOAD ? OVL_FUNCTION (a) : a); + tree name_b = DECL_NAME (TREE_CODE (b) == OVERLOAD ? OVL_FUNCTION (b) : b); + + gcc_checking_assert (name_a && name_b); + if (name_a != name_b) + return name_a < name_b ? -1 : +1; + + if (name_a == conv_op_identifier) + { + /* Strip the conv-op markers. */ + gcc_checking_assert (OVL_FUNCTION (a) == conv_op_marker + && OVL_FUNCTION (b) == conv_op_marker); + a = OVL_CHAIN (a); + b = OVL_CHAIN (b); + } + + if (TREE_CODE (a) == OVERLOAD) + a = OVL_FUNCTION (a); + if (TREE_CODE (b) == OVERLOAD) + b = OVL_FUNCTION (b); + + /* We're in STAT_HACK or USING_DECL territory (or possibly error-land). */ + if (TREE_CODE (a) != TREE_CODE (b)) + { + /* If one of them is a TYPE_DECL, it loses. */ + if (TREE_CODE (a) == TYPE_DECL) + return +1; + else if (TREE_CODE (b) == TYPE_DECL) + return -1; + + /* If one of them is a USING_DECL, it loses. */ + if (TREE_CODE (a) == USING_DECL) + return +1; + else if (TREE_CODE (b) == USING_DECL) + return -1; + + /* There are no other cases with different kinds of decls, as + duplicate detection should have kicked in earlier. However, + some erroneous cases get though. */ + gcc_assert (errorcount); + } + + /* Using source location would be the best thing here, but we can + get identically-located decls in the following circumstances: + + 1) duplicate artificial type-decls for the same type. + + 2) pack expansions of using-decls. + + We should not be doing #1, but in either case it doesn't matter + how we order these. Use UID as a proxy for source ordering, so + that identically-located decls still have a well-defined stable + ordering. */ + if (DECL_UID (a) != DECL_UID (b)) + return DECL_UID (a) < DECL_UID (b) ? -1 : +1; + gcc_assert (a == b); + return 0; +} + +static struct { + gt_pointer_operator new_value; + void *cookie; +} resort_data; + +/* This routine compares two fields like member_name_cmp but using the + pointer operator in resort_field_decl_data. We don't have to deal + with duplicates here. */ + +static int +resort_member_name_cmp (const void *a_p, const void *b_p) +{ + tree a = *(const tree *)a_p; + tree b = *(const tree *)b_p; + tree name_a = OVL_NAME (a); + tree name_b = OVL_NAME (b); + + resort_data.new_value (&name_a, &name_a, resort_data.cookie); + resort_data.new_value (&name_b, &name_b, resort_data.cookie); + + gcc_checking_assert (name_a != name_b); + + return name_a < name_b ? -1 : +1; +} + +/* Resort CLASSTYPE_MEMBER_VEC because pointers have been reordered. */ + +void +resort_type_member_vec (void *obj, void */*orig_obj*/, + gt_pointer_operator new_value, void* cookie) +{ + if (vec<tree, va_gc> *member_vec = (vec<tree, va_gc> *) obj) + { + resort_data.new_value = new_value; + resort_data.cookie = cookie; + member_vec->qsort (resort_member_name_cmp); + } +} + +/* Recursively count the number of fields in KLASS, including anonymous + union members. */ + +static unsigned +count_class_fields (tree klass) +{ + unsigned n_fields = 0; + + for (tree fields = TYPE_FIELDS (klass); fields; fields = DECL_CHAIN (fields)) + if (DECL_DECLARES_FUNCTION_P (fields)) + /* Functions are dealt with separately. */; + else if (TREE_CODE (fields) == FIELD_DECL + && ANON_AGGR_TYPE_P (TREE_TYPE (fields))) + n_fields += count_class_fields (TREE_TYPE (fields)); + else if (DECL_NAME (fields)) + n_fields += 1; + + return n_fields; +} + +/* Append all the nonfunction members fields of KLASS to MEMBER_VEC. + Recurse for anonymous members. MEMBER_VEC must have space. */ + +static void +member_vec_append_class_fields (vec<tree, va_gc> *member_vec, tree klass) +{ + for (tree fields = TYPE_FIELDS (klass); fields; fields = DECL_CHAIN (fields)) + if (DECL_DECLARES_FUNCTION_P (fields)) + /* Functions are handled separately. */; + else if (TREE_CODE (fields) == FIELD_DECL + && ANON_AGGR_TYPE_P (TREE_TYPE (fields))) + member_vec_append_class_fields (member_vec, TREE_TYPE (fields)); + else if (DECL_NAME (fields)) + { + tree field = fields; + /* Mark a conv-op USING_DECL with the conv-op-marker. */ + if (TREE_CODE (field) == USING_DECL + && IDENTIFIER_CONV_OP_P (DECL_NAME (field))) + field = ovl_make (conv_op_marker, field); + member_vec->quick_push (field); + } +} + +/* Append all of the enum values of ENUMTYPE to MEMBER_VEC. + MEMBER_VEC must have space. */ + +static void +member_vec_append_enum_values (vec<tree, va_gc> *member_vec, tree enumtype) +{ + for (tree values = TYPE_VALUES (enumtype); + values; values = TREE_CHAIN (values)) + member_vec->quick_push (TREE_VALUE (values)); +} + +/* MEMBER_VEC has just had new DECLs added to it, but is sorted. + DeDup adjacent DECLS of the same name. We already dealt with + conflict resolution when adding the fields or methods themselves. + There are three cases (which could all be combined): + 1) a TYPE_DECL and non TYPE_DECL. Deploy STAT_HACK as appropriate. + 2) a USING_DECL and an overload. If the USING_DECL is dependent, + it wins. Otherwise the OVERLOAD does. + 3) two USING_DECLS. ... + + member_name_cmp will have ordered duplicates as + <fns><using><type> */ + +static void +member_vec_dedup (vec<tree, va_gc> *member_vec) +{ + unsigned len = member_vec->length (); + unsigned store = 0; + + if (!len) + return; + + tree name = OVL_NAME ((*member_vec)[0]); + for (unsigned jx, ix = 0; ix < len; ix = jx) + { + tree current = NULL_TREE; + tree to_type = NULL_TREE; + tree to_using = NULL_TREE; + tree marker = NULL_TREE; + + for (jx = ix; jx < len; jx++) + { + tree next = (*member_vec)[jx]; + if (jx != ix) + { + tree next_name = OVL_NAME (next); + if (next_name != name) + { + name = next_name; + break; + } + } + + if (IDENTIFIER_CONV_OP_P (name)) + { + marker = next; + next = OVL_CHAIN (next); + } + + if (TREE_CODE (next) == USING_DECL) + { + if (IDENTIFIER_CTOR_P (name)) + /* Dependent inherited ctor. */ + continue; + + next = strip_using_decl (next); + if (TREE_CODE (next) == USING_DECL) + { + to_using = next; + continue; + } + + if (is_overloaded_fn (next)) + continue; + } + + if (DECL_DECLARES_TYPE_P (next)) + { + to_type = next; + continue; + } + + if (!current) + current = next; + } + + if (to_using) + { + if (!current) + current = to_using; + else + current = ovl_make (to_using, current); + } + + if (to_type) + { + if (!current) + current = to_type; + else + current = stat_hack (current, to_type); + } + + if (current) + { + if (marker) + { + OVL_CHAIN (marker) = current; + current = marker; + } + (*member_vec)[store++] = current; + } + } + + while (store++ < len) + member_vec->pop (); +} + +/* Add the non-function members to CLASSTYPE_MEMBER_VEC. If there is + no existing MEMBER_VEC and fewer than 8 fields, do nothing. We + know there must be at least 1 field -- the self-reference + TYPE_DECL, except for anon aggregates, which will have at least + one field anyway. If EXTRA < 0, always create the vector. */ + +vec<tree, va_gc> * +set_class_bindings (tree klass, int extra) +{ + unsigned n_fields = count_class_fields (klass); + vec<tree, va_gc> *member_vec = CLASSTYPE_MEMBER_VEC (klass); + + if (member_vec || n_fields >= 8 || extra < 0) + { + /* Append the new fields. */ + vec_safe_reserve_exact (member_vec, n_fields + (extra >= 0 ? extra : 0)); + member_vec_append_class_fields (member_vec, klass); + } + + if (member_vec) + { + CLASSTYPE_MEMBER_VEC (klass) = member_vec; + member_vec->qsort (member_name_cmp); + member_vec_dedup (member_vec); + } + + return member_vec; +} + +/* Insert lately defined enum ENUMTYPE into KLASS for the sorted case. */ + +void +insert_late_enum_def_bindings (tree klass, tree enumtype) +{ + int n_fields; + vec<tree, va_gc> *member_vec = CLASSTYPE_MEMBER_VEC (klass); + + /* The enum bindings will already be on the TYPE_FIELDS, so don't + count them twice. */ + if (!member_vec) + n_fields = count_class_fields (klass); + else + n_fields = list_length (TYPE_VALUES (enumtype)); + + if (member_vec || n_fields >= 8) + { + vec_safe_reserve_exact (member_vec, n_fields); + if (CLASSTYPE_MEMBER_VEC (klass)) + member_vec_append_enum_values (member_vec, enumtype); + else + member_vec_append_class_fields (member_vec, klass); + CLASSTYPE_MEMBER_VEC (klass) = member_vec; + member_vec->qsort (member_name_cmp); + member_vec_dedup (member_vec); + } +} + +/* The binding oracle; see cp-tree.h. */ + +cp_binding_oracle_function *cp_binding_oracle; + +/* If we have a binding oracle, ask it for all namespace-scoped + definitions of NAME. */ + +static inline void +query_oracle (tree name) +{ + if (!cp_binding_oracle) + return; + + /* LOOKED_UP holds the set of identifiers that we have already + looked up with the oracle. */ + static hash_set<tree> looked_up; + if (looked_up.add (name)) + return; + + cp_binding_oracle (CP_ORACLE_IDENTIFIER, name); +} + +#ifndef ENABLE_SCOPE_CHECKING +# define ENABLE_SCOPE_CHECKING 0 +#else +# define ENABLE_SCOPE_CHECKING 1 +#endif + +/* A free list of "cxx_binding"s, connected by their PREVIOUS. */ + +static GTY((deletable)) cxx_binding *free_bindings; + +/* Initialize VALUE and TYPE field for BINDING, and set the PREVIOUS + field to NULL. */ + +static inline void +cxx_binding_init (cxx_binding *binding, tree value, tree type) +{ + binding->value = value; + binding->type = type; + binding->previous = NULL; +} + +/* (GC)-allocate a binding object with VALUE and TYPE member initialized. */ + +static cxx_binding * +cxx_binding_make (tree value, tree type) +{ + cxx_binding *binding = free_bindings; + + if (binding) + free_bindings = binding->previous; + else + binding = ggc_alloc<cxx_binding> (); + + /* Clear flags by default. */ + LOCAL_BINDING_P (binding) = false; + INHERITED_VALUE_BINDING_P (binding) = false; + HIDDEN_TYPE_BINDING_P (binding) = false; + + cxx_binding_init (binding, value, type); + + return binding; +} + +/* Put BINDING back on the free list. */ + +static inline void +cxx_binding_free (cxx_binding *binding) +{ + binding->scope = NULL; + binding->previous = free_bindings; + free_bindings = binding; +} + +/* Create a new binding for NAME (with the indicated VALUE and TYPE + bindings) in the class scope indicated by SCOPE. */ + +static cxx_binding * +new_class_binding (tree name, tree value, tree type, cp_binding_level *scope) +{ + cp_class_binding cb = {cxx_binding_make (value, type), name}; + cxx_binding *binding = cb.base; + vec_safe_push (scope->class_shadowed, cb); + binding->scope = scope; + return binding; +} + +/* Make DECL the innermost binding for ID. The LEVEL is the binding + level at which this declaration is being bound. */ + +void +push_binding (tree id, tree decl, cp_binding_level* level) +{ + cxx_binding *binding; + + if (level != class_binding_level) + { + binding = cxx_binding_make (decl, NULL_TREE); + binding->scope = level; + } + else + binding = new_class_binding (id, decl, /*type=*/NULL_TREE, level); + + /* Now, fill in the binding information. */ + binding->previous = IDENTIFIER_BINDING (id); + LOCAL_BINDING_P (binding) = (level != class_binding_level); + + /* And put it on the front of the list of bindings for ID. */ + IDENTIFIER_BINDING (id) = binding; +} + +/* Remove the binding for DECL which should be the innermost binding + for ID. */ + +void +pop_local_binding (tree id, tree decl) +{ + if (!id || IDENTIFIER_ANON_P (id)) + /* It's easiest to write the loops that call this function without + checking whether or not the entities involved have names. We + get here for such an entity. */ + return; + + /* Get the innermost binding for ID. */ + cxx_binding *binding = IDENTIFIER_BINDING (id); + + /* The name should be bound. */ + gcc_assert (binding != NULL); + + /* The DECL will be either the ordinary binding or the type binding + for this identifier. Remove that binding. We don't have to + clear HIDDEN_TYPE_BINDING_P, as the whole binding will be going + away. */ + if (binding->value == decl) + binding->value = NULL_TREE; + else + { + gcc_checking_assert (binding->type == decl); + binding->type = NULL_TREE; + } + + if (!binding->value && !binding->type) + { + /* We're completely done with the innermost binding for this + identifier. Unhook it from the list of bindings. */ + IDENTIFIER_BINDING (id) = binding->previous; + + /* Add it to the free list. */ + cxx_binding_free (binding); + } +} + +/* Remove the bindings for the decls of the current level and leave + the current scope. */ + +void +pop_bindings_and_leave_scope (void) +{ + for (tree t = get_local_decls (); t; t = DECL_CHAIN (t)) + { + tree decl = TREE_CODE (t) == TREE_LIST ? TREE_VALUE (t) : t; + tree name = OVL_NAME (decl); + + pop_local_binding (name, decl); + } + + leave_scope (); +} + +/* Strip non dependent using declarations. If DECL is dependent, + surreptitiously create a typename_type and return it. */ + +tree +strip_using_decl (tree decl) +{ + if (decl == NULL_TREE) + return NULL_TREE; + + while (TREE_CODE (decl) == USING_DECL && !DECL_DEPENDENT_P (decl)) + decl = USING_DECL_DECLS (decl); + + if (TREE_CODE (decl) == USING_DECL && DECL_DEPENDENT_P (decl) + && USING_DECL_TYPENAME_P (decl)) + { + /* We have found a type introduced by a using + declaration at class scope that refers to a dependent + type. + + using typename :: [opt] nested-name-specifier unqualified-id ; + */ + decl = make_typename_type (USING_DECL_SCOPE (decl), + DECL_NAME (decl), + typename_type, tf_error); + if (decl != error_mark_node) + decl = TYPE_NAME (decl); + } + + return decl; +} + +/* Return true if OVL is an overload for an anticipated builtin. */ + +static bool +anticipated_builtin_p (tree ovl) +{ + return (TREE_CODE (ovl) == OVERLOAD + && OVL_HIDDEN_P (ovl) + && DECL_IS_UNDECLARED_BUILTIN (OVL_FUNCTION (ovl))); +} + +/* BINDING records an existing declaration for a name in the current scope. + But, DECL is another declaration for that same identifier in the + same scope. This is the `struct stat' hack whereby a non-typedef + class name or enum-name can be bound at the same level as some other + kind of entity. + 3.3.7/1 + + A class name (9.1) or enumeration name (7.2) can be hidden by the + name of an object, function, or enumerator declared in the same scope. + If a class or enumeration name and an object, function, or enumerator + are declared in the same scope (in any order) with the same name, the + class or enumeration name is hidden wherever the object, function, or + enumerator name is visible. + + It's the responsibility of the caller to check that + inserting this name is valid here. Returns nonzero if the new binding + was successful. */ + +static bool +supplement_binding (cxx_binding *binding, tree decl) +{ + auto_cond_timevar tv (TV_NAME_LOOKUP); + + tree bval = binding->value; + bool ok = true; + tree target_bval = strip_using_decl (bval); + tree target_decl = strip_using_decl (decl); + + if (TREE_CODE (target_decl) == TYPE_DECL && DECL_ARTIFICIAL (target_decl) + && target_decl != target_bval + && (TREE_CODE (target_bval) != TYPE_DECL + /* We allow pushing an enum multiple times in a class + template in order to handle late matching of underlying + type on an opaque-enum-declaration followed by an + enum-specifier. */ + || (processing_template_decl + && TREE_CODE (TREE_TYPE (target_decl)) == ENUMERAL_TYPE + && TREE_CODE (TREE_TYPE (target_bval)) == ENUMERAL_TYPE + && (dependent_type_p (ENUM_UNDERLYING_TYPE + (TREE_TYPE (target_decl))) + || dependent_type_p (ENUM_UNDERLYING_TYPE + (TREE_TYPE (target_bval))))))) + /* The new name is the type name. */ + binding->type = decl; + else if (/* TARGET_BVAL is null when push_class_level_binding moves + an inherited type-binding out of the way to make room + for a new value binding. */ + !target_bval + /* TARGET_BVAL is error_mark_node when TARGET_DECL's name + has been used in a non-class scope prior declaration. + In that case, we should have already issued a + diagnostic; for graceful error recovery purpose, pretend + this was the intended declaration for that name. */ + || target_bval == error_mark_node + /* If TARGET_BVAL is anticipated but has not yet been + declared, pretend it is not there at all. */ + || anticipated_builtin_p (target_bval)) + binding->value = decl; + else if (TREE_CODE (target_bval) == TYPE_DECL + && DECL_ARTIFICIAL (target_bval) + && target_decl != target_bval + && (TREE_CODE (target_decl) != TYPE_DECL + || same_type_p (TREE_TYPE (target_decl), + TREE_TYPE (target_bval)))) + { + /* The old binding was a type name. It was placed in + VALUE field because it was thought, at the point it was + declared, to be the only entity with such a name. Move the + type name into the type slot; it is now hidden by the new + binding. */ + binding->type = bval; + binding->value = decl; + binding->value_is_inherited = false; + } + else if (TREE_CODE (target_bval) == TYPE_DECL + && TREE_CODE (target_decl) == TYPE_DECL + && DECL_NAME (target_decl) == DECL_NAME (target_bval) + && binding->scope->kind != sk_class + && (same_type_p (TREE_TYPE (target_decl), TREE_TYPE (target_bval)) + /* If either type involves template parameters, we must + wait until instantiation. */ + || uses_template_parms (TREE_TYPE (target_decl)) + || uses_template_parms (TREE_TYPE (target_bval)))) + /* We have two typedef-names, both naming the same type to have + the same name. In general, this is OK because of: + + [dcl.typedef] + + In a given scope, a typedef specifier can be used to redefine + the name of any type declared in that scope to refer to the + type to which it already refers. + + However, in class scopes, this rule does not apply due to the + stricter language in [class.mem] prohibiting redeclarations of + members. */ + ok = false; + /* There can be two block-scope declarations of the same variable, + so long as they are `extern' declarations. However, there cannot + be two declarations of the same static data member: + + [class.mem] + + A member shall not be declared twice in the + member-specification. */ + else if (VAR_P (target_decl) + && VAR_P (target_bval) + && DECL_EXTERNAL (target_decl) && DECL_EXTERNAL (target_bval) + && !DECL_CLASS_SCOPE_P (target_decl)) + { + duplicate_decls (decl, binding->value); + ok = false; + } + else if (TREE_CODE (decl) == NAMESPACE_DECL + && TREE_CODE (bval) == NAMESPACE_DECL + && DECL_NAMESPACE_ALIAS (decl) + && DECL_NAMESPACE_ALIAS (bval) + && ORIGINAL_NAMESPACE (bval) == ORIGINAL_NAMESPACE (decl)) + /* [namespace.alias] + + In a declarative region, a namespace-alias-definition can be + used to redefine a namespace-alias declared in that declarative + region to refer only to the namespace to which it already + refers. */ + ok = false; + else if (TREE_CODE (bval) == USING_DECL + && CONST_DECL_USING_P (decl)) + /* Let the clone hide the using-decl that introduced it. */ + binding->value = decl; + else + { + if (!error_operand_p (bval)) + diagnose_name_conflict (decl, bval); + ok = false; + } + + return ok; +} + +/* Diagnose a name conflict between DECL and BVAL. */ + +static void +diagnose_name_conflict (tree decl, tree bval) +{ + if (TREE_CODE (decl) == TREE_CODE (bval) + && TREE_CODE (decl) != NAMESPACE_DECL + && !DECL_DECLARES_FUNCTION_P (decl) + && (TREE_CODE (decl) != TYPE_DECL + || DECL_ARTIFICIAL (decl) == DECL_ARTIFICIAL (bval)) + && CP_DECL_CONTEXT (decl) == CP_DECL_CONTEXT (bval)) + { + if (concept_definition_p (decl)) + error ("redeclaration of %q#D with different template parameters", + decl); + else + error ("redeclaration of %q#D", decl); + } + else + error ("%q#D conflicts with a previous declaration", decl); + + inform (location_of (bval), "previous declaration %q#D", bval); +} + +/* Replace BINDING's current value on its scope's name list with + NEWVAL. */ + +static void +update_local_overload (cxx_binding *binding, tree newval) +{ + tree *d; + + for (d = &binding->scope->names; ; d = &TREE_CHAIN (*d)) + if (*d == binding->value) + { + /* Stitch new list node in. */ + *d = tree_cons (DECL_NAME (*d), NULL_TREE, TREE_CHAIN (*d)); + break; + } + else if (TREE_CODE (*d) == TREE_LIST && TREE_VALUE (*d) == binding->value) + break; + + TREE_VALUE (*d) = newval; +} + +/* Compares the parameter-type-lists of ONE and TWO and + returns false if they are different. If the DECLs are template + functions, the return types and the template parameter lists are + compared too (DR 565). */ + +static bool +matching_fn_p (tree one, tree two) +{ + if (TREE_CODE (one) != TREE_CODE (two)) + return false; + + if (!compparms (TYPE_ARG_TYPES (TREE_TYPE (one)), + TYPE_ARG_TYPES (TREE_TYPE (two)))) + return false; + + if (TREE_CODE (one) == TEMPLATE_DECL) + { + /* Compare template parms. */ + if (!comp_template_parms (DECL_TEMPLATE_PARMS (one), + DECL_TEMPLATE_PARMS (two))) + return false; + + /* And return type. */ + if (!same_type_p (TREE_TYPE (TREE_TYPE (one)), + TREE_TYPE (TREE_TYPE (two)))) + return false; + } + + if (!equivalently_constrained (one, two)) + return false; + + return true; +} + +/* Push DECL into nonclass LEVEL BINDING or SLOT. OLD is the current + binding value (possibly with anticipated builtins stripped). + Diagnose conflicts and return updated decl. */ + +static tree +update_binding (cp_binding_level *level, cxx_binding *binding, tree *slot, + tree old, tree decl, bool hiding = false) +{ + tree old_type = NULL_TREE; + bool hide_type = false; + bool hide_value = false; + + if (!slot) + { + old_type = binding->type; + hide_type = HIDDEN_TYPE_BINDING_P (binding); + if (!old_type) + hide_value = hide_type, hide_type = false; + } + else if (STAT_HACK_P (*slot)) + { + old_type = STAT_TYPE (*slot); + hide_type = STAT_TYPE_HIDDEN_P (*slot); + hide_value = STAT_DECL_HIDDEN_P (*slot); + } + + tree to_val = decl; + tree to_type = old_type; + bool local_overload = false; + + gcc_assert (!level || level->kind == sk_namespace ? !binding + : level->kind != sk_class && !slot); + + if (old == error_mark_node) + old = NULL_TREE; + + if (DECL_IMPLICIT_TYPEDEF_P (decl)) + { + /* Pushing an artificial decl. We should not find another + artificial decl here already -- lookup_elaborated_type will + have already found it. */ + gcc_checking_assert (!to_type + && !(old && DECL_IMPLICIT_TYPEDEF_P (old))); + + if (old) + { + /* Put DECL into the type slot. */ + gcc_checking_assert (!to_type); + hide_type = hiding; + to_type = decl; + to_val = old; + } + else + hide_value = hiding; + + goto done; + } + + if (old && DECL_IMPLICIT_TYPEDEF_P (old)) + { + /* OLD is an implicit typedef. Move it to to_type. */ + gcc_checking_assert (!to_type); + + to_type = old; + hide_type = hide_value; + old = NULL_TREE; + hide_value = false; + } + + if (DECL_DECLARES_FUNCTION_P (decl)) + { + if (!old) + ; + else if (OVL_P (old)) + { + for (ovl_iterator iter (old); iter; ++iter) + { + tree fn = *iter; + + if (iter.using_p () && matching_fn_p (fn, decl)) + { + gcc_checking_assert (!iter.hidden_p ()); + /* If a function declaration in namespace scope or + block scope has the same name and the same + parameter-type- list (8.3.5) as a function + introduced by a using-declaration, and the + declarations do not declare the same function, + the program is ill-formed. [namespace.udecl]/14 */ + if (tree match = duplicate_decls (decl, fn, hiding)) + return match; + else + /* FIXME: To preserve existing error behavior, we + still push the decl. This might change. */ + diagnose_name_conflict (decl, fn); + } + } + } + else + goto conflict; + + if (to_type != old_type + && warn_shadow + && MAYBE_CLASS_TYPE_P (TREE_TYPE (to_type)) + && !(DECL_IN_SYSTEM_HEADER (decl) + && DECL_IN_SYSTEM_HEADER (to_type))) + warning (OPT_Wshadow, "%q#D hides constructor for %q#D", + decl, to_type); + + local_overload = old && level && level->kind != sk_namespace; + to_val = ovl_insert (decl, old, -int (hiding)); + } + else if (old) + { + if (TREE_CODE (old) != TREE_CODE (decl)) + /* Different kinds of decls conflict. */ + goto conflict; + else if (TREE_CODE (old) == TYPE_DECL) + { + if (same_type_p (TREE_TYPE (old), TREE_TYPE (decl))) + /* Two type decls to the same type. Do nothing. */ + return old; + else + goto conflict; + } + else if (TREE_CODE (old) == NAMESPACE_DECL) + { + /* Two maybe-aliased namespaces. If they're to the same target + namespace, that's ok. */ + if (ORIGINAL_NAMESPACE (old) != ORIGINAL_NAMESPACE (decl)) + goto conflict; + + /* The new one must be an alias at this point. */ + gcc_assert (DECL_NAMESPACE_ALIAS (decl)); + return old; + } + else if (TREE_CODE (old) == VAR_DECL) + { + /* There can be two block-scope declarations of the same + variable, so long as they are `extern' declarations. */ + if (!DECL_EXTERNAL (old) || !DECL_EXTERNAL (decl)) + goto conflict; + else if (tree match = duplicate_decls (decl, old)) + { + gcc_checking_assert (!hide_value && !hiding); + return match; + } + else + goto conflict; + } + else + { + conflict: + diagnose_name_conflict (decl, old); + to_val = NULL_TREE; + } + } + else if (hiding) + hide_value = true; + + done: + if (to_val) + { + if (local_overload) + { + gcc_checking_assert (binding->value && OVL_P (binding->value)); + update_local_overload (binding, to_val); + } + else if (level + && !(TREE_CODE (decl) == NAMESPACE_DECL + && !DECL_NAMESPACE_ALIAS (decl))) + /* Don't add namespaces here. They're done in + push_namespace. */ + add_decl_to_level (level, decl); + + if (slot) + { + if (STAT_HACK_P (*slot)) + { + STAT_TYPE (*slot) = to_type; + STAT_DECL (*slot) = to_val; + STAT_TYPE_HIDDEN_P (*slot) = hide_type; + STAT_DECL_HIDDEN_P (*slot) = hide_value; + } + else if (to_type || hide_value) + { + *slot = stat_hack (to_val, to_type); + STAT_TYPE_HIDDEN_P (*slot) = hide_type; + STAT_DECL_HIDDEN_P (*slot) = hide_value; + } + else + { + gcc_checking_assert (!hide_type); + *slot = to_val; + } + } + else + { + binding->type = to_type; + binding->value = to_val; + HIDDEN_TYPE_BINDING_P (binding) = hide_type || hide_value; + } + } + + return decl; +} + +/* Table of identifiers to extern C declarations (or LISTS thereof). */ + +static GTY(()) hash_table<named_decl_hash> *extern_c_decls; + +/* DECL has C linkage. If we have an existing instance, make sure the + new one is compatible. Make sure it has the same exception + specification [7.5, 7.6]. Add DECL to the map. */ + +static void +check_extern_c_conflict (tree decl) +{ + /* Ignore artificial or system header decls. */ + if (DECL_ARTIFICIAL (decl) || DECL_IN_SYSTEM_HEADER (decl)) + return; + + /* This only applies to decls at namespace scope. */ + if (!DECL_NAMESPACE_SCOPE_P (decl)) + return; + + if (!extern_c_decls) + extern_c_decls = hash_table<named_decl_hash>::create_ggc (127); + + tree *slot = extern_c_decls + ->find_slot_with_hash (DECL_NAME (decl), + IDENTIFIER_HASH_VALUE (DECL_NAME (decl)), INSERT); + if (tree old = *slot) + { + if (TREE_CODE (old) == OVERLOAD) + old = OVL_FUNCTION (old); + + int mismatch = 0; + if (DECL_CONTEXT (old) == DECL_CONTEXT (decl)) + ; /* If they're in the same context, we'll have already complained + about a (possible) mismatch, when inserting the decl. */ + else if (!decls_match (decl, old)) + mismatch = 1; + else if (TREE_CODE (decl) == FUNCTION_DECL + && !comp_except_specs (TYPE_RAISES_EXCEPTIONS (TREE_TYPE (old)), + TYPE_RAISES_EXCEPTIONS (TREE_TYPE (decl)), + ce_normal)) + mismatch = -1; + else if (DECL_ASSEMBLER_NAME_SET_P (old)) + SET_DECL_ASSEMBLER_NAME (decl, DECL_ASSEMBLER_NAME (old)); + + if (mismatch) + { + auto_diagnostic_group d; + pedwarn (DECL_SOURCE_LOCATION (decl), 0, + "conflicting C language linkage declaration %q#D", decl); + inform (DECL_SOURCE_LOCATION (old), + "previous declaration %q#D", old); + if (mismatch < 0) + inform (DECL_SOURCE_LOCATION (decl), + "due to different exception specifications"); + } + else + { + if (old == *slot) + /* The hash table expects OVERLOADS, so construct one with + OLD as both the function and the chain. This allocate + an excess OVERLOAD node, but it's rare to have multiple + extern "C" decls of the same name. And we save + complicating the hash table logic (which is used + elsewhere). */ + *slot = ovl_make (old, old); + + slot = &OVL_CHAIN (*slot); + + /* Chain it on for c_linkage_binding's use. */ + *slot = tree_cons (NULL_TREE, decl, *slot); + } + } + else + *slot = decl; +} + +/* Returns a list of C-linkage decls with the name NAME. Used in + c-family/c-pragma.c to implement redefine_extname pragma. */ + +tree +c_linkage_bindings (tree name) +{ + if (extern_c_decls) + if (tree *slot = extern_c_decls + ->find_slot_with_hash (name, IDENTIFIER_HASH_VALUE (name), NO_INSERT)) + { + tree result = *slot; + if (TREE_CODE (result) == OVERLOAD) + result = OVL_CHAIN (result); + return result; + } + + return NULL_TREE; +} + +/* Subroutine of check_local_shadow. */ + +static void +inform_shadowed (tree shadowed) +{ + inform (DECL_SOURCE_LOCATION (shadowed), + "shadowed declaration is here"); +} + +/* DECL is being declared at a local scope. Emit suitable shadow + warnings. */ + +static void +check_local_shadow (tree decl) +{ + /* Don't complain about the parms we push and then pop + while tentatively parsing a function declarator. */ + if (TREE_CODE (decl) == PARM_DECL && !DECL_CONTEXT (decl)) + return; + + /* External decls are something else. */ + if (DECL_EXTERNAL (decl)) + return; + + tree old = NULL_TREE; + cp_binding_level *old_scope = NULL; + if (cxx_binding *binding = outer_binding (DECL_NAME (decl), NULL, true)) + { + old = binding->value; + old_scope = binding->scope; + } + + if (old + && (TREE_CODE (old) == PARM_DECL + || VAR_P (old) + || (TREE_CODE (old) == TYPE_DECL + && (!DECL_ARTIFICIAL (old) + || TREE_CODE (decl) == TYPE_DECL))) + && DECL_FUNCTION_SCOPE_P (old) + && (!DECL_ARTIFICIAL (decl) + || is_capture_proxy (decl) + || DECL_IMPLICIT_TYPEDEF_P (decl) + || (VAR_P (decl) && DECL_ANON_UNION_VAR_P (decl)))) + { + /* DECL shadows a local thing possibly of interest. */ + + /* DR 2211: check that captures and parameters + do not have the same name. */ + if (is_capture_proxy (decl)) + { + if (current_lambda_expr () + && DECL_CONTEXT (old) == lambda_function (current_lambda_expr ()) + && TREE_CODE (old) == PARM_DECL + && DECL_NAME (decl) != this_identifier) + { + error_at (DECL_SOURCE_LOCATION (old), + "lambda parameter %qD " + "previously declared as a capture", old); + } + return; + } + /* Don't complain if it's from an enclosing function. */ + else if (DECL_CONTEXT (old) == current_function_decl + && TREE_CODE (decl) != PARM_DECL + && TREE_CODE (old) == PARM_DECL) + { + /* Go to where the parms should be and see if we find + them there. */ + cp_binding_level *b = current_binding_level->level_chain; + + if (FUNCTION_NEEDS_BODY_BLOCK (current_function_decl)) + /* Skip the ctor/dtor cleanup level. */ + b = b->level_chain; + + /* [basic.scope.param] A parameter name shall not be redeclared + in the outermost block of the function definition. */ + if (b->kind == sk_function_parms) + { + error_at (DECL_SOURCE_LOCATION (decl), + "declaration of %q#D shadows a parameter", decl); + inform (DECL_SOURCE_LOCATION (old), + "%q#D previously declared here", old); + return; + } + } + + /* The local structure or class can't use parameters of + the containing function anyway. */ + if (DECL_CONTEXT (old) != current_function_decl) + { + for (cp_binding_level *scope = current_binding_level; + scope != old_scope; scope = scope->level_chain) + if (scope->kind == sk_class + && !LAMBDA_TYPE_P (scope->this_entity)) + return; + } + /* Error if redeclaring a local declared in a + init-statement or in the condition of an if or + switch statement when the new declaration is in the + outermost block of the controlled statement. + Redeclaring a variable from a for or while condition is + detected elsewhere. */ + else if (VAR_P (old) + && old_scope == current_binding_level->level_chain + && (old_scope->kind == sk_cond || old_scope->kind == sk_for)) + { + auto_diagnostic_group d; + error_at (DECL_SOURCE_LOCATION (decl), + "redeclaration of %q#D", decl); + inform (DECL_SOURCE_LOCATION (old), + "%q#D previously declared here", old); + return; + } + /* C++11: + 3.3.3/3: The name declared in an exception-declaration (...) + shall not be redeclared in the outermost block of the handler. + 3.3.3/2: A parameter name shall not be redeclared (...) in + the outermost block of any handler associated with a + function-try-block. + 3.4.1/15: The function parameter names shall not be redeclared + in the exception-declaration nor in the outermost block of a + handler for the function-try-block. */ + else if ((TREE_CODE (old) == VAR_DECL + && old_scope == current_binding_level->level_chain + && old_scope->kind == sk_catch) + || (TREE_CODE (old) == PARM_DECL + && (current_binding_level->kind == sk_catch + || current_binding_level->level_chain->kind == sk_catch) + && in_function_try_handler)) + { + auto_diagnostic_group d; + if (permerror (DECL_SOURCE_LOCATION (decl), + "redeclaration of %q#D", decl)) + inform (DECL_SOURCE_LOCATION (old), + "%q#D previously declared here", old); + return; + } + + /* If '-Wshadow=compatible-local' is specified without other + -Wshadow= flags, we will warn only when the type of the + shadowing variable (DECL) can be converted to that of the + shadowed parameter (OLD_LOCAL). The reason why we only check + if DECL's type can be converted to OLD_LOCAL's type (but not the + other way around) is because when users accidentally shadow a + parameter, more than often they would use the variable + thinking (mistakenly) it's still the parameter. It would be + rare that users would use the variable in the place that + expects the parameter but thinking it's a new decl. + If either object is a TYPE_DECL, '-Wshadow=compatible-local' + warns regardless of whether one of the types involved + is a subclass of the other, since that is never okay. */ + + enum opt_code warning_code; + if (warn_shadow) + warning_code = OPT_Wshadow; + else if ((TREE_TYPE (old) + && TREE_TYPE (decl) + && same_type_p (TREE_TYPE (old), TREE_TYPE (decl))) + || TREE_CODE (decl) == TYPE_DECL + || TREE_CODE (old) == TYPE_DECL + || (!dependent_type_p (TREE_TYPE (decl)) + && !dependent_type_p (TREE_TYPE (old)) + /* If the new decl uses auto, we don't yet know + its type (the old type cannot be using auto + at this point, without also being + dependent). This is an indication we're + (now) doing the shadow checking too + early. */ + && !type_uses_auto (TREE_TYPE (decl)) + && can_convert_arg (TREE_TYPE (old), TREE_TYPE (decl), + decl, LOOKUP_IMPLICIT, tf_none))) + warning_code = OPT_Wshadow_compatible_local; + else + warning_code = OPT_Wshadow_local; + + const char *msg; + if (TREE_CODE (old) == PARM_DECL) + msg = "declaration of %q#D shadows a parameter"; + else if (is_capture_proxy (old)) + msg = "declaration of %qD shadows a lambda capture"; + else + msg = "declaration of %qD shadows a previous local"; + + auto_diagnostic_group d; + if (warning_at (DECL_SOURCE_LOCATION (decl), warning_code, msg, decl)) + inform_shadowed (old); + return; + } + + if (!warn_shadow) + return; + + /* Don't warn for artificial things that are not implicit typedefs. */ + if (DECL_ARTIFICIAL (decl) && !DECL_IMPLICIT_TYPEDEF_P (decl)) + return; + + if (nonlambda_method_basetype ()) + if (tree member = lookup_member (current_nonlambda_class_type (), + DECL_NAME (decl), /*protect=*/0, + /*want_type=*/false, tf_warning_or_error)) + { + member = MAYBE_BASELINK_FUNCTIONS (member); + + /* Warn if a variable shadows a non-function, or the variable + is a function or a pointer-to-function. */ + if (!OVL_P (member) + || TREE_CODE (decl) == FUNCTION_DECL + || (TREE_TYPE (decl) + && (TYPE_PTRFN_P (TREE_TYPE (decl)) + || TYPE_PTRMEMFUNC_P (TREE_TYPE (decl))))) + { + auto_diagnostic_group d; + if (warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wshadow, + "declaration of %qD shadows a member of %qT", + decl, current_nonlambda_class_type ()) + && DECL_P (member)) + inform_shadowed (member); + } + return; + } + + /* Now look for a namespace shadow. */ + old = find_namespace_value (current_namespace, DECL_NAME (decl)); + if (old + && (VAR_P (old) + || (TREE_CODE (old) == TYPE_DECL + && (!DECL_ARTIFICIAL (old) + || TREE_CODE (decl) == TYPE_DECL))) + && !instantiating_current_function_p ()) + /* XXX shadow warnings in outer-more namespaces */ + { + auto_diagnostic_group d; + if (warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wshadow, + "declaration of %qD shadows a global declaration", + decl)) + inform_shadowed (old); + return; + } + + return; +} + +/* DECL is being pushed inside function CTX. Set its context, if + needed. */ + +static void +set_decl_context_in_fn (tree ctx, tree decl) +{ + if (TREE_CODE (decl) == FUNCTION_DECL + || (VAR_P (decl) && DECL_EXTERNAL (decl))) + /* Make sure local externs are marked as such. OMP UDRs really + are nested functions. */ + gcc_checking_assert (DECL_LOCAL_DECL_P (decl) + && (DECL_NAMESPACE_SCOPE_P (decl) + || (TREE_CODE (decl) == FUNCTION_DECL + && DECL_OMP_DECLARE_REDUCTION_P (decl)))); + + if (!DECL_CONTEXT (decl) + /* When parsing the parameter list of a function declarator, + don't set DECL_CONTEXT to an enclosing function. */ + && !(TREE_CODE (decl) == PARM_DECL + && parsing_function_declarator ())) + DECL_CONTEXT (decl) = ctx; +} + +/* DECL is a local extern decl. Find or create the namespace-scope + decl that it aliases. Also, determines the linkage of DECL. */ + +void +push_local_extern_decl_alias (tree decl) +{ + if (dependent_type_p (TREE_TYPE (decl)) + || (processing_template_decl + && VAR_P (decl) + && CP_DECL_THREAD_LOCAL_P (decl))) + return; + /* EH specs were not part of the function type prior to c++17, but + we still can't go pushing dependent eh specs into the namespace. */ + if (cxx_dialect < cxx17 + && TREE_CODE (decl) == FUNCTION_DECL + && (value_dependent_expression_p + (TYPE_RAISES_EXCEPTIONS (TREE_TYPE (decl))))) + return; + + gcc_checking_assert (!DECL_LANG_SPECIFIC (decl) + || !DECL_TEMPLATE_INFO (decl)); + if (DECL_LANG_SPECIFIC (decl) && DECL_LOCAL_DECL_ALIAS (decl)) + /* We're instantiating a non-dependent local decl, it already + knows the alias. */ + return; + + tree alias = NULL_TREE; + + if (DECL_SIZE (decl) && !TREE_CONSTANT (DECL_SIZE (decl))) + /* Do not let a VLA creep into a namespace. Diagnostic will be + emitted in layout_var_decl later. */ + alias = error_mark_node; + else + { + /* First look for a decl that matches. */ + tree ns = CP_DECL_CONTEXT (decl); + tree binding = find_namespace_value (ns, DECL_NAME (decl)); + + if (binding && TREE_CODE (binding) != TREE_LIST) + for (ovl_iterator iter (binding); iter; ++iter) + if (decls_match (decl, *iter, /*record_versions*/false)) + { + alias = *iter; + break; + } + + if (!alias) + { + /* No existing namespace-scope decl. Make one. */ + alias = copy_decl (decl); + if (TREE_CODE (alias) == FUNCTION_DECL) + { + /* Recontextualize the parms. */ + for (tree *chain = &DECL_ARGUMENTS (alias); + *chain; chain = &DECL_CHAIN (*chain)) + { + *chain = copy_decl (*chain); + DECL_CONTEXT (*chain) = alias; + } + + tree type = TREE_TYPE (alias); + for (tree args = TYPE_ARG_TYPES (type); + args; args = TREE_CHAIN (args)) + if (TREE_PURPOSE (args)) + { + /* There are default args. Lose them. */ + tree nargs = NULL_TREE; + tree *chain = &nargs; + for (args = TYPE_ARG_TYPES (type); + args; args = TREE_CHAIN (args)) + if (args == void_list_node) + { + *chain = args; + break; + } + else + { + *chain + = build_tree_list (NULL_TREE, TREE_VALUE (args)); + chain = &TREE_CHAIN (*chain); + } + + tree fn_type = build_function_type (TREE_TYPE (type), nargs); + + fn_type = apply_memfn_quals + (fn_type, type_memfn_quals (type)); + + fn_type = build_cp_fntype_variant + (fn_type, type_memfn_rqual (type), + TYPE_RAISES_EXCEPTIONS (type), + TYPE_HAS_LATE_RETURN_TYPE (type)); + + TREE_TYPE (alias) = fn_type; + break; + } + } + + /* This is the real thing. */ + DECL_LOCAL_DECL_P (alias) = false; + + /* Expected default linkage is from the namespace. */ + TREE_PUBLIC (alias) = TREE_PUBLIC (ns); + push_nested_namespace (ns); + alias = pushdecl (alias, /* hiding= */true); + pop_nested_namespace (ns); + if (VAR_P (decl) + && CP_DECL_THREAD_LOCAL_P (decl) + && alias != error_mark_node) + set_decl_tls_model (alias, DECL_TLS_MODEL (decl)); + } + } + + retrofit_lang_decl (decl); + DECL_LOCAL_DECL_ALIAS (decl) = alias; +} + +/* DECL is a global or module-purview entity. If it has non-internal + linkage, and we have a module vector, record it in the appropriate + slot. We have already checked for duplicates. */ + +static void +maybe_record_mergeable_decl (tree *slot, tree name, tree decl) +{ + if (TREE_CODE (*slot) != BINDING_VECTOR) + return; + + if (!TREE_PUBLIC (CP_DECL_CONTEXT (decl))) + /* Member of internal namespace. */ + return; + + tree not_tmpl = STRIP_TEMPLATE (decl); + if ((TREE_CODE (not_tmpl) == FUNCTION_DECL + || TREE_CODE (not_tmpl) == VAR_DECL) + && DECL_THIS_STATIC (not_tmpl)) + /* Internal linkage. */ + return; + + bool partition = named_module_p (); + tree *gslot = get_fixed_binding_slot + (slot, name, partition ? BINDING_SLOT_PARTITION : BINDING_SLOT_GLOBAL, true); + + if (!partition) + { + binding_slot &orig + = BINDING_VECTOR_CLUSTER (*slot, 0).slots[BINDING_SLOT_CURRENT]; + + if (!STAT_HACK_P (tree (orig))) + orig = stat_hack (tree (orig)); + + MODULE_BINDING_GLOBAL_P (tree (orig)) = true; + } + + add_mergeable_namespace_entity (gslot, decl); +} + +/* DECL is being pushed. Check whether it hides or ambiguates + something seen as an import. This include decls seen in our own + interface, which is OK. Also, check for merging a + global/partition decl. */ + +static tree +check_module_override (tree decl, tree mvec, bool hiding, + tree scope, tree name) +{ + tree match = NULL_TREE; + bitmap imports = get_import_bitmap (); + binding_cluster *cluster = BINDING_VECTOR_CLUSTER_BASE (mvec); + unsigned ix = BINDING_VECTOR_NUM_CLUSTERS (mvec); + + if (BINDING_VECTOR_SLOTS_PER_CLUSTER == BINDING_SLOTS_FIXED) + { + cluster++; + ix--; + } + + for (; ix--; cluster++) + for (unsigned jx = 0; jx != BINDING_VECTOR_SLOTS_PER_CLUSTER; jx++) + { + /* Are we importing this module? */ + if (cluster->indices[jx].span != 1) + continue; + if (!cluster->indices[jx].base) + continue; + if (!bitmap_bit_p (imports, cluster->indices[jx].base)) + continue; + /* Is it loaded? */ + if (cluster->slots[jx].is_lazy ()) + { + gcc_assert (cluster->indices[jx].span == 1); + lazy_load_binding (cluster->indices[jx].base, + scope, name, &cluster->slots[jx]); + } + tree bind = cluster->slots[jx]; + if (!bind) + /* Errors could cause there to be nothing. */ + continue; + + if (STAT_HACK_P (bind)) + /* We do not have to check STAT_TYPE here, the xref_tag + machinery deals with that problem. */ + bind = STAT_VISIBLE (bind); + + for (ovl_iterator iter (bind); iter; ++iter) + if (!iter.using_p ()) + { + match = duplicate_decls (decl, *iter, hiding); + if (match) + goto matched; + } + } + + if (TREE_PUBLIC (scope) && TREE_PUBLIC (STRIP_TEMPLATE (decl)) + /* Namespaces are dealt with specially in + make_namespace_finish. */ + && !(TREE_CODE (decl) == NAMESPACE_DECL && !DECL_NAMESPACE_ALIAS (decl))) + { + /* Look in the appropriate mergeable decl slot. */ + tree mergeable = NULL_TREE; + if (named_module_p ()) + mergeable = BINDING_VECTOR_CLUSTER (mvec, BINDING_SLOT_PARTITION + / BINDING_VECTOR_SLOTS_PER_CLUSTER) + .slots[BINDING_SLOT_PARTITION % BINDING_VECTOR_SLOTS_PER_CLUSTER]; + else + mergeable = BINDING_VECTOR_CLUSTER (mvec, 0).slots[BINDING_SLOT_GLOBAL]; + + for (ovl_iterator iter (mergeable); iter; ++iter) + { + match = duplicate_decls (decl, *iter, hiding); + if (match) + goto matched; + } + } + + return NULL_TREE; + + matched: + if (match != error_mark_node) + { + if (named_module_p ()) + BINDING_VECTOR_PARTITION_DUPS_P (mvec) = true; + else + BINDING_VECTOR_GLOBAL_DUPS_P (mvec) = true; + } + + return match; + + +} + +/* Record DECL as belonging to the current lexical scope. Check for + errors (such as an incompatible declaration for the same name + already seen in the same scope). + + The new binding is hidden if HIDING is true (an anticipated builtin + or hidden friend). + + Returns either DECL or an old decl for the same name. If an old + decl is returned, it may have been smashed to agree with what DECL + says. */ + +tree +pushdecl (tree decl, bool hiding) +{ + auto_cond_timevar tv (TV_NAME_LOOKUP); + + if (decl == error_mark_node) + return error_mark_node; + + if (!DECL_TEMPLATE_PARM_P (decl) && current_function_decl && !hiding) + set_decl_context_in_fn (current_function_decl, decl); + + /* The binding level we will be pushing into. During local class + pushing, we want to push to the containing scope. */ + cp_binding_level *level = current_binding_level; + while (level->kind == sk_class + || level->kind == sk_cleanup) + level = level->level_chain; + + /* An anonymous namespace has a NULL DECL_NAME, but we still want to + insert it. Other NULL-named decls, not so much. */ + tree name = DECL_NAME (decl); + if (name ? !IDENTIFIER_ANON_P (name) : TREE_CODE (decl) == NAMESPACE_DECL) + { + cxx_binding *binding = NULL; /* Local scope binding. */ + tree ns = NULL_TREE; /* Searched namespace. */ + tree *slot = NULL; /* Binding slot in namespace. */ + tree *mslot = NULL; /* Current module slot in namespace. */ + tree old = NULL_TREE; + + if (level->kind == sk_namespace) + { + /* We look in the decl's namespace for an existing + declaration, even though we push into the current + namespace. */ + ns = (DECL_NAMESPACE_SCOPE_P (decl) + ? CP_DECL_CONTEXT (decl) : current_namespace); + /* Create the binding, if this is current namespace, because + that's where we'll be pushing anyway. */ + slot = find_namespace_slot (ns, name, ns == current_namespace); + if (slot) + { + mslot = get_fixed_binding_slot (slot, name, BINDING_SLOT_CURRENT, + ns == current_namespace); + old = MAYBE_STAT_DECL (*mslot); + } + } + else + { + binding = find_local_binding (level, name); + if (binding) + old = binding->value; + } + + if (old == error_mark_node) + old = NULL_TREE; + + for (ovl_iterator iter (old); iter; ++iter) + if (iter.using_p ()) + ; /* Ignore using decls here. */ + else if (iter.hidden_p () + && TREE_CODE (*iter) == FUNCTION_DECL + && DECL_LANG_SPECIFIC (*iter) + && DECL_MODULE_IMPORT_P (*iter)) + ; /* An undeclared builtin imported from elsewhere. */ + else if (tree match + = duplicate_decls (decl, *iter, hiding, iter.hidden_p ())) + { + if (match == error_mark_node) + ; + else if (TREE_CODE (match) == TYPE_DECL) + gcc_checking_assert (REAL_IDENTIFIER_TYPE_VALUE (name) + == (level->kind == sk_namespace + ? NULL_TREE : TREE_TYPE (match))); + else if (iter.hidden_p () && !hiding) + { + /* Unhiding a previously hidden decl. */ + tree head = iter.reveal_node (old); + if (head != old) + { + gcc_checking_assert (ns); + if (STAT_HACK_P (*slot)) + STAT_DECL (*slot) = head; + else + *slot = head; + } + if (DECL_EXTERN_C_P (match)) + /* We need to check and register the decl now. */ + check_extern_c_conflict (match); + } + else if (slot && !hiding + && STAT_HACK_P (*slot) && STAT_DECL_HIDDEN_P (*slot)) + { + /* Unhide the non-function. */ + gcc_checking_assert (old == match); + if (!STAT_TYPE (*slot)) + *slot = match; + else + STAT_DECL (*slot) = match; + } + return match; + } + + /* Check for redeclaring an import. */ + if (slot && *slot && TREE_CODE (*slot) == BINDING_VECTOR) + if (tree match + = check_module_override (decl, *slot, hiding, ns, name)) + { + if (match == error_mark_node) + return match; + + /* We found a decl in an interface, push it into this + binding. */ + decl = update_binding (NULL, binding, mslot, old, + match, hiding); + + return decl; + } + + /* We are pushing a new decl. */ + + /* Skip a hidden builtin we failed to match already. There can + only be one. */ + if (old && anticipated_builtin_p (old)) + old = OVL_CHAIN (old); + + check_template_shadow (decl); + + if (DECL_DECLARES_FUNCTION_P (decl)) + { + check_default_args (decl); + + if (hiding) + { + if (level->kind != sk_namespace) + { + /* In a local class, a friend function declaration must + find a matching decl in the innermost non-class scope. + [class.friend/11] */ + error_at (DECL_SOURCE_LOCATION (decl), + "friend declaration %qD in local class without " + "prior local declaration", decl); + /* Don't attempt to push it. */ + return error_mark_node; + } + } + } + + if (level->kind != sk_namespace) + { + check_local_shadow (decl); + + if (TREE_CODE (decl) == NAMESPACE_DECL) + /* A local namespace alias. */ + set_identifier_type_value_with_scope (name, NULL_TREE, level); + + if (!binding) + binding = create_local_binding (level, name); + } + else if (!slot) + { + ns = current_namespace; + slot = find_namespace_slot (ns, name, true); + mslot = get_fixed_binding_slot (slot, name, BINDING_SLOT_CURRENT, true); + /* Update OLD to reflect the namespace we're going to be + pushing into. */ + old = MAYBE_STAT_DECL (*mslot); + } + + old = update_binding (level, binding, mslot, old, decl, hiding); + + if (old != decl) + /* An existing decl matched, use it. */ + decl = old; + else + { + if (TREE_CODE (decl) == TYPE_DECL) + { + tree type = TREE_TYPE (decl); + + if (type != error_mark_node) + { + if (TYPE_NAME (type) != decl) + set_underlying_type (decl); + + set_identifier_type_value_with_scope (name, decl, level); + + if (level->kind != sk_namespace + && !instantiating_current_function_p ()) + /* This is a locally defined typedef in a function that + is not a template instantation, record it to implement + -Wunused-local-typedefs. */ + record_locally_defined_typedef (decl); + } + } + else if (VAR_OR_FUNCTION_DECL_P (decl)) + { + if (DECL_EXTERN_C_P (decl)) + check_extern_c_conflict (decl); + + if (!DECL_LOCAL_DECL_P (decl) + && VAR_P (decl)) + maybe_register_incomplete_var (decl); + + if (DECL_LOCAL_DECL_P (decl) + && NAMESPACE_SCOPE_P (decl)) + push_local_extern_decl_alias (decl); + } + + if (level->kind == sk_namespace + && TREE_PUBLIC (level->this_entity) + && !not_module_p ()) + maybe_record_mergeable_decl (slot, name, decl); + } + } + else + add_decl_to_level (level, decl); + + return decl; +} + +/* A mergeable entity is being loaded into namespace NS slot NAME. + Create and return the appropriate vector slot for that. Either a + GMF slot or a module-specific one. */ + +tree * +mergeable_namespace_slots (tree ns, tree name, bool is_global, tree *vec) +{ + tree *mslot = find_namespace_slot (ns, name, true); + tree *vslot = get_fixed_binding_slot + (mslot, name, is_global ? BINDING_SLOT_GLOBAL : BINDING_SLOT_PARTITION, true); + + gcc_checking_assert (TREE_CODE (*mslot) == BINDING_VECTOR); + *vec = *mslot; + + return vslot; +} + +/* DECL is a new mergeable namespace-scope decl. Add it to the + mergeable entities on GSLOT. */ + +void +add_mergeable_namespace_entity (tree *gslot, tree decl) +{ + *gslot = ovl_make (decl, *gslot); +} + +/* A mergeable entity of KLASS called NAME is being loaded. Return + the set of things it could be. All such non-as_base classes have + been given a member vec. */ + +tree +lookup_class_binding (tree klass, tree name) +{ + tree found = NULL_TREE; + + if (!COMPLETE_TYPE_P (klass)) + ; + else if (TYPE_LANG_SPECIFIC (klass)) + { + vec<tree, va_gc> *member_vec = CLASSTYPE_MEMBER_VEC (klass); + + found = member_vec_binary_search (member_vec, name); + if (!found) + ; + else if (STAT_HACK_P (found)) + /* Rearrange the stat hack so that we don't need to expose that + internal detail. */ + found = ovl_make (STAT_TYPE (found), STAT_DECL (found)); + else if (IDENTIFIER_CONV_OP_P (name)) + { + gcc_checking_assert (name == conv_op_identifier); + found = OVL_CHAIN (found); + } + } + else + { + gcc_checking_assert (IS_FAKE_BASE_TYPE (klass) + || TYPE_PTRMEMFUNC_P (klass)); + found = fields_linear_search (klass, name, false); + } + + return found; +} + +/* Given a namespace-level binding BINDING, walk it, calling CALLBACK + for all decls of the current module. When partitions are involved, + decls might be mentioned more than once. Return the accumulation of + CALLBACK results. */ + +unsigned +walk_module_binding (tree binding, bitmap partitions, + bool (*callback) (tree decl, WMB_Flags, void *data), + void *data) +{ + // FIXME: We don't quite deal with using decls naming stat hack + // type. Also using decls exporting something from the same scope. + tree current = binding; + unsigned count = 0; + + if (TREE_CODE (binding) == BINDING_VECTOR) + current = BINDING_VECTOR_CLUSTER (binding, 0).slots[BINDING_SLOT_CURRENT]; + + bool decl_hidden = false; + if (tree type = MAYBE_STAT_TYPE (current)) + { + WMB_Flags flags = WMB_None; + if (STAT_TYPE_HIDDEN_P (current)) + flags = WMB_Flags (flags | WMB_Hidden); + count += callback (type, flags, data); + decl_hidden = STAT_DECL_HIDDEN_P (current); + } + + for (ovl_iterator iter (MAYBE_STAT_DECL (current)); iter; ++iter) + { + if (iter.hidden_p ()) + decl_hidden = true; + if (!(decl_hidden && DECL_IS_UNDECLARED_BUILTIN (*iter))) + { + WMB_Flags flags = WMB_None; + if (decl_hidden) + flags = WMB_Flags (flags | WMB_Hidden); + if (iter.using_p ()) + { + flags = WMB_Flags (flags | WMB_Using); + if (iter.exporting_p ()) + flags = WMB_Flags (flags | WMB_Export); + } + count += callback (*iter, flags, data); + } + decl_hidden = false; + } + + if (partitions && TREE_CODE (binding) == BINDING_VECTOR) + { + /* Process partition slots. */ + binding_cluster *cluster = BINDING_VECTOR_CLUSTER_BASE (binding); + unsigned ix = BINDING_VECTOR_NUM_CLUSTERS (binding); + if (BINDING_VECTOR_SLOTS_PER_CLUSTER == BINDING_SLOTS_FIXED) + { + ix--; + cluster++; + } + + bool maybe_dups = BINDING_VECTOR_PARTITION_DUPS_P (binding); + + for (; ix--; cluster++) + for (unsigned jx = 0; jx != BINDING_VECTOR_SLOTS_PER_CLUSTER; jx++) + if (!cluster->slots[jx].is_lazy ()) + if (tree bind = cluster->slots[jx]) + { + if (TREE_CODE (bind) == NAMESPACE_DECL + && !DECL_NAMESPACE_ALIAS (bind)) + { + if (unsigned base = cluster->indices[jx].base) + if (unsigned span = cluster->indices[jx].span) + do + if (bitmap_bit_p (partitions, base)) + goto found; + while (++base, --span); + /* Not a partition's namespace. */ + continue; + found: + + WMB_Flags flags = WMB_None; + if (maybe_dups) + flags = WMB_Flags (flags | WMB_Dups); + count += callback (bind, flags, data); + } + else if (STAT_HACK_P (bind) && MODULE_BINDING_PARTITION_P (bind)) + { + if (tree btype = STAT_TYPE (bind)) + { + WMB_Flags flags = WMB_None; + if (maybe_dups) + flags = WMB_Flags (flags | WMB_Dups); + if (STAT_TYPE_HIDDEN_P (bind)) + flags = WMB_Flags (flags | WMB_Hidden); + + count += callback (btype, flags, data); + } + bool hidden = STAT_DECL_HIDDEN_P (bind); + for (ovl_iterator iter (MAYBE_STAT_DECL (STAT_DECL (bind))); + iter; ++iter) + { + if (iter.hidden_p ()) + hidden = true; + gcc_checking_assert + (!(hidden && DECL_IS_UNDECLARED_BUILTIN (*iter))); + + WMB_Flags flags = WMB_None; + if (maybe_dups) + flags = WMB_Flags (flags | WMB_Dups); + if (decl_hidden) + flags = WMB_Flags (flags | WMB_Hidden); + if (iter.using_p ()) + { + flags = WMB_Flags (flags | WMB_Using); + if (iter.exporting_p ()) + flags = WMB_Flags (flags | WMB_Export); + } + count += callback (*iter, flags, data); + hidden = false; + } + } + } + } + + return count; +} + +/* Imported module MOD has a binding to NS::NAME, stored in section + SNUM. */ + +bool +import_module_binding (tree ns, tree name, unsigned mod, unsigned snum) +{ + tree *slot = find_namespace_slot (ns, name, true); + binding_slot *mslot = append_imported_binding_slot (slot, name, mod); + + if (mslot->is_lazy () || *mslot) + /* Oops, something was already there. */ + return false; + + mslot->set_lazy (snum); + return true; +} + +/* An import of MODULE is binding NS::NAME. There should be no + existing binding for >= MODULE. MOD_GLOB indicates whether MODULE + is a header_unit (-1) or part of the current module (+1). VALUE + and TYPE are the value and type bindings. VISIBLE are the value + bindings being exported. */ + +bool +set_module_binding (tree ns, tree name, unsigned mod, int mod_glob, + tree value, tree type, tree visible) +{ + if (!value) + /* Bogus BMIs could give rise to nothing to bind. */ + return false; + + gcc_assert (TREE_CODE (value) != NAMESPACE_DECL + || DECL_NAMESPACE_ALIAS (value)); + gcc_checking_assert (mod); + + tree *slot = find_namespace_slot (ns, name, true); + binding_slot *mslot = search_imported_binding_slot (slot, mod); + + if (!mslot || !mslot->is_lazy ()) + /* Again, bogus BMI could give find to missing or already loaded slot. */ + return false; + + tree bind = value; + if (type || visible != bind || mod_glob) + { + bind = stat_hack (bind, type); + STAT_VISIBLE (bind) = visible; + if ((mod_glob > 0 && TREE_PUBLIC (ns)) + || (type && DECL_MODULE_EXPORT_P (type))) + STAT_TYPE_VISIBLE_P (bind) = true; + } + + /* Note if this is this-module or global binding. */ + if (mod_glob > 0) + MODULE_BINDING_PARTITION_P (bind) = true; + else if (mod_glob < 0) + MODULE_BINDING_GLOBAL_P (bind) = true; + + *mslot = bind; + + return true; +} + +void +add_module_namespace_decl (tree ns, tree decl) +{ + gcc_assert (!DECL_CHAIN (decl)); + gcc_checking_assert (!(VAR_OR_FUNCTION_DECL_P (decl) + && DECL_LOCAL_DECL_P (decl))); + if (CHECKING_P) + /* Expensive already-there? check. */ + for (auto probe = NAMESPACE_LEVEL (ns)->names; probe; + probe = DECL_CHAIN (probe)) + gcc_assert (decl != probe); + + add_decl_to_level (NAMESPACE_LEVEL (ns), decl); + + if (VAR_P (decl)) + maybe_register_incomplete_var (decl); + + if (VAR_OR_FUNCTION_DECL_P (decl) + && DECL_EXTERN_C_P (decl)) + check_extern_c_conflict (decl); +} + +/* Enter DECL into the symbol table, if that's appropriate. Returns + DECL, or a modified version thereof. */ + +tree +maybe_push_decl (tree decl) +{ + tree type = TREE_TYPE (decl); + + /* Add this decl to the current binding level, but not if it comes + from another scope, e.g. a static member variable. TEM may equal + DECL or it may be a previous decl of the same name. */ + if (decl == error_mark_node + || (TREE_CODE (decl) != PARM_DECL + && DECL_CONTEXT (decl) != NULL_TREE + /* Definitions of namespace members outside their namespace are + possible. */ + && !DECL_NAMESPACE_SCOPE_P (decl)) + || (TREE_CODE (decl) == TEMPLATE_DECL && !namespace_bindings_p ()) + || type == unknown_type_node + /* The declaration of a template specialization does not affect + the functions available for overload resolution, so we do not + call pushdecl. */ + || (TREE_CODE (decl) == FUNCTION_DECL + && DECL_TEMPLATE_SPECIALIZATION (decl))) + return decl; + else + return pushdecl (decl); +} + +/* Bind DECL to ID in the current_binding_level, assumed to be a local + binding level. If IS_USING is true, DECL got here through a + using-declaration. */ + +static void +push_local_binding (tree id, tree decl, bool is_using) +{ + /* Skip over any local classes. This makes sense if we call + push_local_binding with a friend decl of a local class. */ + cp_binding_level *b = innermost_nonclass_level (); + + gcc_assert (b->kind != sk_namespace); + if (find_local_binding (b, id)) + { + /* Supplement the existing binding. */ + if (!supplement_binding (IDENTIFIER_BINDING (id), decl)) + /* It didn't work. Something else must be bound at this + level. Do not add DECL to the list of things to pop + later. */ + return; + } + else + /* Create a new binding. */ + push_binding (id, decl, b); + + if (TREE_CODE (decl) == OVERLOAD || is_using) + /* We must put the OVERLOAD or using into a TREE_LIST since we + cannot use the decl's chain itself. */ + decl = build_tree_list (id, decl); + + /* And put DECL on the list of things declared by the current + binding level. */ + add_decl_to_level (b, decl); +} + + +/* true means unconditionally make a BLOCK for the next level pushed. */ + +static bool keep_next_level_flag; + +static int binding_depth = 0; + +static void +indent (int depth) +{ + int i; + + for (i = 0; i < depth * 2; i++) + putc (' ', stderr); +} + +/* Return a string describing the kind of SCOPE we have. */ +static const char * +cp_binding_level_descriptor (cp_binding_level *scope) +{ + /* The order of this table must match the "scope_kind" + enumerators. */ + static const char* scope_kind_names[] = { + "block-scope", + "cleanup-scope", + "try-scope", + "catch-scope", + "for-scope", + "function-parameter-scope", + "class-scope", + "namespace-scope", + "template-parameter-scope", + "template-explicit-spec-scope" + }; + const scope_kind kind = scope->explicit_spec_p + ? sk_template_spec : scope->kind; + + return scope_kind_names[kind]; +} + +/* Output a debugging information about SCOPE when performing + ACTION at LINE. */ +static void +cp_binding_level_debug (cp_binding_level *scope, int line, const char *action) +{ + const char *desc = cp_binding_level_descriptor (scope); + if (scope->this_entity) + verbatim ("%s %<%s(%E)%> %p %d", action, desc, + scope->this_entity, (void *) scope, line); + else + verbatim ("%s %s %p %d", action, desc, (void *) scope, line); +} + +/* A chain of binding_level structures awaiting reuse. */ + +static GTY((deletable)) cp_binding_level *free_binding_level; + +/* Insert SCOPE as the innermost binding level. */ + +void +push_binding_level (cp_binding_level *scope) +{ + /* Add it to the front of currently active scopes stack. */ + scope->level_chain = current_binding_level; + current_binding_level = scope; + keep_next_level_flag = false; + + if (ENABLE_SCOPE_CHECKING) + { + scope->binding_depth = binding_depth; + indent (binding_depth); + cp_binding_level_debug (scope, LOCATION_LINE (input_location), + "push"); + binding_depth++; + } +} + +/* Create a new KIND scope and make it the top of the active scopes stack. + ENTITY is the scope of the associated C++ entity (namespace, class, + function, C++0x enumeration); it is NULL otherwise. */ + +cp_binding_level * +begin_scope (scope_kind kind, tree entity) +{ + cp_binding_level *scope; + + /* Reuse or create a struct for this binding level. */ + if (!ENABLE_SCOPE_CHECKING && free_binding_level) + { + scope = free_binding_level; + free_binding_level = scope->level_chain; + memset (scope, 0, sizeof (cp_binding_level)); + } + else + scope = ggc_cleared_alloc<cp_binding_level> (); + + scope->this_entity = entity; + scope->more_cleanups_ok = true; + switch (kind) + { + case sk_cleanup: + scope->keep = true; + break; + + case sk_template_spec: + scope->explicit_spec_p = true; + kind = sk_template_parms; + /* Fall through. */ + case sk_template_parms: + case sk_block: + case sk_try: + case sk_catch: + case sk_for: + case sk_cond: + case sk_class: + case sk_scoped_enum: + case sk_transaction: + case sk_omp: + scope->keep = keep_next_level_flag; + break; + + case sk_function_parms: + scope->keep = keep_next_level_flag; + if (entity) + scope->immediate_fn_ctx_p = DECL_IMMEDIATE_FUNCTION_P (entity); + break; + + case sk_namespace: + NAMESPACE_LEVEL (entity) = scope; + break; + + default: + /* Should not happen. */ + gcc_unreachable (); + break; + } + scope->kind = kind; + + push_binding_level (scope); + + return scope; +} + +/* We're about to leave current scope. Pop the top of the stack of + currently active scopes. Return the enclosing scope, now active. */ + +cp_binding_level * +leave_scope (void) +{ + cp_binding_level *scope = current_binding_level; + + if (scope->kind == sk_namespace && class_binding_level) + current_binding_level = class_binding_level; + + /* We cannot leave a scope, if there are none left. */ + if (NAMESPACE_LEVEL (global_namespace)) + gcc_assert (!global_scope_p (scope)); + + if (ENABLE_SCOPE_CHECKING) + { + indent (--binding_depth); + cp_binding_level_debug (scope, LOCATION_LINE (input_location), + "leave"); + } + + /* Move one nesting level up. */ + current_binding_level = scope->level_chain; + + /* Namespace-scopes are left most probably temporarily, not + completely; they can be reopened later, e.g. in namespace-extension + or any name binding activity that requires us to resume a + namespace. For classes, we cache some binding levels. For other + scopes, we just make the structure available for reuse. */ + if (scope->kind != sk_namespace + && scope != previous_class_level) + { + scope->level_chain = free_binding_level; + gcc_assert (!ENABLE_SCOPE_CHECKING + || scope->binding_depth == binding_depth); + free_binding_level = scope; + } + + if (scope->kind == sk_class) + { + /* Reset DEFINING_CLASS_P to allow for reuse of a + class-defining scope in a non-defining context. */ + scope->defining_class_p = 0; + + /* Find the innermost enclosing class scope, and reset + CLASS_BINDING_LEVEL appropriately. */ + class_binding_level = NULL; + for (scope = current_binding_level; scope; scope = scope->level_chain) + if (scope->kind == sk_class) + { + class_binding_level = scope; + break; + } + } + + return current_binding_level; +} + +/* When we exit a toplevel class scope, we save its binding level so + that we can restore it quickly. Here, we've entered some other + class, so we must invalidate our cache. */ + +void +invalidate_class_lookup_cache (void) +{ + previous_class_level->level_chain = free_binding_level; + free_binding_level = previous_class_level; + previous_class_level = NULL; +} + +static void +resume_scope (cp_binding_level* b) +{ + /* Resuming binding levels is meant only for namespaces, + and those cannot nest into classes. */ + gcc_assert (!class_binding_level); + /* Also, resuming a non-directly nested namespace is a no-no. */ + gcc_assert (b->level_chain == current_binding_level); + current_binding_level = b; + if (ENABLE_SCOPE_CHECKING) + { + b->binding_depth = binding_depth; + indent (binding_depth); + cp_binding_level_debug (b, LOCATION_LINE (input_location), "resume"); + binding_depth++; + } +} + +/* Return the innermost binding level that is not for a class scope. */ + +static cp_binding_level * +innermost_nonclass_level (void) +{ + cp_binding_level *b; + + b = current_binding_level; + while (b->kind == sk_class) + b = b->level_chain; + + return b; +} + +/* We're defining an object of type TYPE. If it needs a cleanup, but + we're not allowed to add any more objects with cleanups to the current + scope, create a new binding level. */ + +void +maybe_push_cleanup_level (tree type) +{ + if (type != error_mark_node + && TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type) + && current_binding_level->more_cleanups_ok == 0) + { + begin_scope (sk_cleanup, NULL); + current_binding_level->statement_list = push_stmt_list (); + } +} + +/* Return true if we are in the global binding level. */ + +bool +global_bindings_p (void) +{ + return global_scope_p (current_binding_level); +} + +/* True if we are currently in a toplevel binding level. This + means either the global binding level or a namespace in a toplevel + binding level. Since there are no non-toplevel namespace levels, + this really means any namespace or template parameter level. We + also include a class whose context is toplevel. */ + +bool +toplevel_bindings_p (void) +{ + cp_binding_level *b = innermost_nonclass_level (); + + return b->kind == sk_namespace || b->kind == sk_template_parms; +} + +/* True if this is a namespace scope, or if we are defining a class + which is itself at namespace scope, or whose enclosing class is + such a class, etc. */ + +bool +namespace_bindings_p (void) +{ + cp_binding_level *b = innermost_nonclass_level (); + + return b->kind == sk_namespace; +} + +/* True if the innermost non-class scope is a block scope. */ + +bool +local_bindings_p (void) +{ + cp_binding_level *b = innermost_nonclass_level (); + return b->kind < sk_function_parms || b->kind == sk_omp; +} + +/* True if the current level needs to have a BLOCK made. */ + +bool +kept_level_p (void) +{ + return (current_binding_level->blocks != NULL_TREE + || current_binding_level->keep + || current_binding_level->kind == sk_cleanup + || current_binding_level->names != NULL_TREE + || current_binding_level->using_directives); +} + +/* Returns the kind of the innermost scope. */ + +scope_kind +innermost_scope_kind (void) +{ + return current_binding_level->kind; +} + +/* Returns true if this scope was created to store template parameters. */ + +bool +template_parm_scope_p (void) +{ + return innermost_scope_kind () == sk_template_parms; +} + +/* If KEEP is true, make a BLOCK node for the next binding level, + unconditionally. Otherwise, use the normal logic to decide whether + or not to create a BLOCK. */ + +void +keep_next_level (bool keep) +{ + keep_next_level_flag = keep; +} + +/* Return the list of declarations of the current local scope. */ + +tree +get_local_decls (void) +{ + gcc_assert (current_binding_level->kind != sk_namespace + && current_binding_level->kind != sk_class); + return current_binding_level->names; +} + +/* Return how many function prototypes we are currently nested inside. */ + +int +function_parm_depth (void) +{ + int level = 0; + cp_binding_level *b; + + for (b = current_binding_level; + b->kind == sk_function_parms; + b = b->level_chain) + ++level; + + return level; +} + +/* For debugging. */ +static int no_print_functions = 0; +static int no_print_builtins = 0; + +static void +print_binding_level (cp_binding_level* lvl) +{ + tree t; + int i = 0, len; + if (lvl->this_entity) + print_node_brief (stderr, "entity=", lvl->this_entity, 1); + fprintf (stderr, " blocks=%p", (void *) lvl->blocks); + if (lvl->more_cleanups_ok) + fprintf (stderr, " more-cleanups-ok"); + if (lvl->have_cleanups) + fprintf (stderr, " have-cleanups"); + fprintf (stderr, "\n"); + if (lvl->names) + { + fprintf (stderr, " names:\t"); + /* We can probably fit 3 names to a line? */ + for (t = lvl->names; t; t = TREE_CHAIN (t)) + { + if (no_print_functions && (TREE_CODE (t) == FUNCTION_DECL)) + continue; + if (no_print_builtins + && (TREE_CODE (t) == TYPE_DECL) + && DECL_IS_UNDECLARED_BUILTIN (t)) + continue; + + /* Function decls tend to have longer names. */ + if (TREE_CODE (t) == FUNCTION_DECL) + len = 3; + else + len = 2; + i += len; + if (i > 6) + { + fprintf (stderr, "\n\t"); + i = len; + } + print_node_brief (stderr, "", t, 0); + if (t == error_mark_node) + break; + } + if (i) + fprintf (stderr, "\n"); + } + if (vec_safe_length (lvl->class_shadowed)) + { + size_t i; + cp_class_binding *b; + fprintf (stderr, " class-shadowed:"); + FOR_EACH_VEC_ELT (*lvl->class_shadowed, i, b) + fprintf (stderr, " %s ", IDENTIFIER_POINTER (b->identifier)); + fprintf (stderr, "\n"); + } + if (lvl->type_shadowed) + { + fprintf (stderr, " type-shadowed:"); + for (t = lvl->type_shadowed; t; t = TREE_CHAIN (t)) + { + fprintf (stderr, " %s ", IDENTIFIER_POINTER (TREE_PURPOSE (t))); + } + fprintf (stderr, "\n"); + } +} + +DEBUG_FUNCTION void +debug (cp_binding_level &ref) +{ + print_binding_level (&ref); +} + +DEBUG_FUNCTION void +debug (cp_binding_level *ptr) +{ + if (ptr) + debug (*ptr); + else + fprintf (stderr, "<nil>\n"); +} + +static void +print_other_binding_stack (cp_binding_level *stack) +{ + cp_binding_level *level; + for (level = stack; !global_scope_p (level); level = level->level_chain) + { + fprintf (stderr, "binding level %p\n", (void *) level); + print_binding_level (level); + } +} + +DEBUG_FUNCTION void +print_binding_stack (void) +{ + cp_binding_level *b; + fprintf (stderr, "current_binding_level=%p\n" + "class_binding_level=%p\n" + "NAMESPACE_LEVEL (global_namespace)=%p\n", + (void *) current_binding_level, (void *) class_binding_level, + (void *) NAMESPACE_LEVEL (global_namespace)); + if (class_binding_level) + { + for (b = class_binding_level; b; b = b->level_chain) + if (b == current_binding_level) + break; + if (b) + b = class_binding_level; + else + b = current_binding_level; + } + else + b = current_binding_level; + print_other_binding_stack (b); + fprintf (stderr, "global:\n"); + print_binding_level (NAMESPACE_LEVEL (global_namespace)); +} + +/* Push a definition of struct, union or enum tag named ID. into + binding_level B. DECL is a TYPE_DECL for the type. DECL has + already been pushed into its binding level. This is bookkeeping to + find it easily. */ + +static void +set_identifier_type_value_with_scope (tree id, tree decl, cp_binding_level *b) +{ + if (b->kind == sk_namespace) + /* At namespace scope we should not see an identifier type value. */ + gcc_checking_assert (!REAL_IDENTIFIER_TYPE_VALUE (id) + /* We could be pushing a friend underneath a template + parm (ill-formed). */ + || (TEMPLATE_PARM_P + (TYPE_NAME (REAL_IDENTIFIER_TYPE_VALUE (id))))); + else + { + /* Push the current type value, so we can restore it later */ + tree old = REAL_IDENTIFIER_TYPE_VALUE (id); + b->type_shadowed = tree_cons (id, old, b->type_shadowed); + tree type = decl ? TREE_TYPE (decl) : NULL_TREE; + TREE_TYPE (b->type_shadowed) = type; + SET_IDENTIFIER_TYPE_VALUE (id, type); + } +} + +/* As set_identifier_type_value_with_scope, but using + current_binding_level. */ + +void +set_identifier_type_value (tree id, tree decl) +{ + set_identifier_type_value_with_scope (id, decl, current_binding_level); +} + +/* Return the name for the constructor (or destructor) for the + specified class. */ + +tree +constructor_name (tree type) +{ + tree decl = TYPE_NAME (TYPE_MAIN_VARIANT (type)); + + return decl ? DECL_NAME (decl) : NULL_TREE; +} + +/* Returns TRUE if NAME is the name for the constructor for TYPE, + which must be a class type. */ + +bool +constructor_name_p (tree name, tree type) +{ + gcc_assert (MAYBE_CLASS_TYPE_P (type)); + + /* These don't have names. */ + if (TREE_CODE (type) == DECLTYPE_TYPE + || TREE_CODE (type) == TYPEOF_TYPE) + return false; + + if (name && name == constructor_name (type)) + return true; + + return false; +} + +/* Same as pushdecl, but define X in binding-level LEVEL. We rely on the + caller to set DECL_CONTEXT properly. + + Warning: For class and block-scope this must only be used when X + will be the new innermost binding for its name, as we tack it onto + the front of IDENTIFIER_BINDING without checking to see if the + current IDENTIFIER_BINDING comes from a closer binding level than + LEVEL. + + Warning: For namespace scope, this will look in LEVEL for an + existing binding to match, but if not found will push the decl into + CURRENT_NAMESPACE. Use push_nested_namespace/pushdecl/ + pop_nested_namespace if you really need to push it into a foreign + namespace. */ + +static tree +do_pushdecl_with_scope (tree x, cp_binding_level *level, bool hiding = false) +{ + cp_binding_level *b; + + if (level->kind == sk_class) + { + gcc_checking_assert (!hiding); + b = class_binding_level; + class_binding_level = level; + pushdecl_class_level (x); + class_binding_level = b; + } + else + { + tree function_decl = current_function_decl; + if (level->kind == sk_namespace) + current_function_decl = NULL_TREE; + b = current_binding_level; + current_binding_level = level; + x = pushdecl (x, hiding); + current_binding_level = b; + current_function_decl = function_decl; + } + return x; +} + +/* Inject X into the local scope just before the function parms. */ + +tree +pushdecl_outermost_localscope (tree x) +{ + cp_binding_level *b = NULL; + auto_cond_timevar tv (TV_NAME_LOOKUP); + + /* Find the scope just inside the function parms. */ + for (cp_binding_level *n = current_binding_level; + n->kind != sk_function_parms; n = b->level_chain) + b = n; + + return b ? do_pushdecl_with_scope (x, b) : error_mark_node; +} + +/* Process a local-scope or namespace-scope using declaration. LOOKUP + is the result of qualified lookup (both value & type are + significant). FN_SCOPE_P indicates if we're at function-scope (as + opposed to namespace-scope). *VALUE_P and *TYPE_P are the current + bindings, which are altered to reflect the newly brought in + declarations. */ + +static bool +do_nonmember_using_decl (name_lookup &lookup, bool fn_scope_p, + bool insert_p, tree *value_p, tree *type_p) +{ + tree value = *value_p; + tree type = *type_p; + bool failed = false; + + /* Shift the old and new bindings around so we're comparing class and + enumeration names to each other. */ + if (value && DECL_IMPLICIT_TYPEDEF_P (value)) + { + type = value; + value = NULL_TREE; + } + + if (lookup.value && DECL_IMPLICIT_TYPEDEF_P (lookup.value)) + { + lookup.type = lookup.value; + lookup.value = NULL_TREE; + } + + /* Only process exporting if we're going to be inserting. */ + bool revealing_p = insert_p && !fn_scope_p && module_has_cmi_p (); + + /* First do the value binding. */ + if (!lookup.value) + /* Nothing (only implicit typedef found). */ + gcc_checking_assert (lookup.type); + else if (OVL_P (lookup.value) && (!value || OVL_P (value))) + { + for (lkp_iterator usings (lookup.value); usings; ++usings) + { + tree new_fn = *usings; + bool exporting = revealing_p && module_exporting_p (); + if (exporting) + { + /* If the using decl is exported, the things it refers + to must also be exported (or not in module purview). */ + if (!DECL_MODULE_EXPORT_P (new_fn) + && (DECL_LANG_SPECIFIC (new_fn) + && DECL_MODULE_PURVIEW_P (new_fn))) + { + error ("%q#D does not have external linkage", new_fn); + inform (DECL_SOURCE_LOCATION (new_fn), + "%q#D declared here", new_fn); + exporting = false; + } + } + + /* [namespace.udecl] + + If a function declaration in namespace scope or block + scope has the same name and the same parameter types as a + function introduced by a using declaration the program is + ill-formed. */ + /* This seems overreaching, asking core -- why do we care + about decls in the namespace that we cannot name (because + they are not transitively imported. We just check the + decls that are in this TU. */ + bool found = false; + for (ovl_iterator old (value); !found && old; ++old) + { + tree old_fn = *old; + + if (new_fn == old_fn) + { + /* The function already exists in the current + namespace. We will still want to insert it if + it is revealing a not-revealed thing. */ + found = true; + if (!revealing_p) + ; + else if (old.using_p ()) + { + if (exporting) + /* Update in place. 'tis ok. */ + OVL_EXPORT_P (old.get_using ()) = true; + ; + } + else if (DECL_MODULE_EXPORT_P (new_fn)) + ; + else + { + value = old.remove_node (value); + found = false; + } + break; + } + else if (old.using_p ()) + continue; /* This is a using decl. */ + else if (old.hidden_p () && DECL_IS_UNDECLARED_BUILTIN (old_fn)) + continue; /* This is an anticipated builtin. */ + else if (!matching_fn_p (new_fn, old_fn)) + continue; /* Parameters do not match. */ + else if (decls_match (new_fn, old_fn)) + { + /* Extern "C" in different namespaces. */ + found = true; + break; + } + else + { + diagnose_name_conflict (new_fn, old_fn); + failed = true; + found = true; + break; + } + } + + if (!found && insert_p) + /* Unlike the decl-pushing case we don't drop anticipated + builtins here. They don't cause a problem, and we'd + like to match them with a future declaration. */ + value = ovl_insert (new_fn, value, 1 + exporting); + } + } + else if (value + /* Ignore anticipated builtins. */ + && !anticipated_builtin_p (value) + && (fn_scope_p || !decls_match (lookup.value, value))) + { + diagnose_name_conflict (lookup.value, value); + failed = true; + } + else if (insert_p) + // FIXME:what if we're newly exporting lookup.value + value = lookup.value; + + /* Now the type binding. */ + if (lookup.type && lookup.type != type) + { + // FIXME: What if we're exporting lookup.type? + if (type && !decls_match (lookup.type, type)) + { + diagnose_name_conflict (lookup.type, type); + failed = true; + } + else if (insert_p) + type = lookup.type; + } + + if (insert_p) + { + /* If value is empty, shift any class or enumeration name back. */ + if (!value) + { + value = type; + type = NULL_TREE; + } + *value_p = value; + *type_p = type; + } + + return failed; +} + +/* Returns true if ANCESTOR encloses DESCENDANT, including matching. + Both are namespaces. */ + +bool +is_nested_namespace (tree ancestor, tree descendant, bool inline_only) +{ + int depth = SCOPE_DEPTH (ancestor); + + if (!depth && !inline_only) + /* The global namespace encloses everything. */ + return true; + + while (SCOPE_DEPTH (descendant) > depth + && (!inline_only || DECL_NAMESPACE_INLINE_P (descendant))) + descendant = CP_DECL_CONTEXT (descendant); + + return ancestor == descendant; +} + +/* Returns true if ROOT (a non-alias namespace, class, or function) + encloses CHILD. CHILD may be either a class type or a namespace + (maybe alias). */ + +bool +is_ancestor (tree root, tree child) +{ + gcc_checking_assert ((TREE_CODE (root) == NAMESPACE_DECL + && !DECL_NAMESPACE_ALIAS (root)) + || TREE_CODE (root) == FUNCTION_DECL + || CLASS_TYPE_P (root)); + gcc_checking_assert (TREE_CODE (child) == NAMESPACE_DECL + || CLASS_TYPE_P (child)); + + /* The global namespace encloses everything. Early-out for the + common case. */ + if (root == global_namespace) + return true; + + /* Search CHILD until we reach namespace scope. */ + while (TREE_CODE (child) != NAMESPACE_DECL) + { + /* If we've reached the ROOT, it encloses CHILD. */ + if (root == child) + return true; + + /* Go out one level. */ + if (TYPE_P (child)) + child = TYPE_NAME (child); + child = CP_DECL_CONTEXT (child); + } + + if (TREE_CODE (root) != NAMESPACE_DECL) + /* Failed to meet the non-namespace we were looking for. */ + return false; + + if (tree alias = DECL_NAMESPACE_ALIAS (child)) + child = alias; + + return is_nested_namespace (root, child); +} + +/* Enter the class or namespace scope indicated by T suitable for name + lookup. T can be arbitrary scope, not necessary nested inside the + current scope. Returns a non-null scope to pop iff pop_scope + should be called later to exit this scope. */ + +tree +push_scope (tree t) +{ + if (TREE_CODE (t) == NAMESPACE_DECL) + push_decl_namespace (t); + else if (CLASS_TYPE_P (t)) + { + if (!at_class_scope_p () + || !same_type_p (current_class_type, t)) + push_nested_class (t); + else + /* T is the same as the current scope. There is therefore no + need to re-enter the scope. Since we are not actually + pushing a new scope, our caller should not call + pop_scope. */ + t = NULL_TREE; + } + + return t; +} + +/* Leave scope pushed by push_scope. */ + +void +pop_scope (tree t) +{ + if (t == NULL_TREE) + return; + if (TREE_CODE (t) == NAMESPACE_DECL) + pop_decl_namespace (); + else if CLASS_TYPE_P (t) + pop_nested_class (); +} + +/* Subroutine of push_inner_scope. */ + +static void +push_inner_scope_r (tree outer, tree inner) +{ + tree prev; + + if (outer == inner + || (TREE_CODE (inner) != NAMESPACE_DECL && !CLASS_TYPE_P (inner))) + return; + + prev = CP_DECL_CONTEXT (TREE_CODE (inner) == NAMESPACE_DECL ? inner : TYPE_NAME (inner)); + if (outer != prev) + push_inner_scope_r (outer, prev); + if (TREE_CODE (inner) == NAMESPACE_DECL) + { + cp_binding_level *save_template_parm = 0; + /* Temporary take out template parameter scopes. They are saved + in reversed order in save_template_parm. */ + while (current_binding_level->kind == sk_template_parms) + { + cp_binding_level *b = current_binding_level; + current_binding_level = b->level_chain; + b->level_chain = save_template_parm; + save_template_parm = b; + } + + resume_scope (NAMESPACE_LEVEL (inner)); + current_namespace = inner; + + /* Restore template parameter scopes. */ + while (save_template_parm) + { + cp_binding_level *b = save_template_parm; + save_template_parm = b->level_chain; + b->level_chain = current_binding_level; + current_binding_level = b; + } + } + else + pushclass (inner); +} + +/* Enter the scope INNER from current scope. INNER must be a scope + nested inside current scope. This works with both name lookup and + pushing name into scope. In case a template parameter scope is present, + namespace is pushed under the template parameter scope according to + name lookup rule in 14.6.1/6. + + Return the former current scope suitable for pop_inner_scope. */ + +tree +push_inner_scope (tree inner) +{ + tree outer = current_scope (); + if (!outer) + outer = current_namespace; + + push_inner_scope_r (outer, inner); + return outer; +} + +/* Exit the current scope INNER back to scope OUTER. */ + +void +pop_inner_scope (tree outer, tree inner) +{ + if (outer == inner + || (TREE_CODE (inner) != NAMESPACE_DECL && !CLASS_TYPE_P (inner))) + return; + + while (outer != inner) + { + if (TREE_CODE (inner) == NAMESPACE_DECL) + { + cp_binding_level *save_template_parm = 0; + /* Temporary take out template parameter scopes. They are saved + in reversed order in save_template_parm. */ + while (current_binding_level->kind == sk_template_parms) + { + cp_binding_level *b = current_binding_level; + current_binding_level = b->level_chain; + b->level_chain = save_template_parm; + save_template_parm = b; + } + + pop_namespace (); + + /* Restore template parameter scopes. */ + while (save_template_parm) + { + cp_binding_level *b = save_template_parm; + save_template_parm = b->level_chain; + b->level_chain = current_binding_level; + current_binding_level = b; + } + } + else + popclass (); + + inner = CP_DECL_CONTEXT (TREE_CODE (inner) == NAMESPACE_DECL ? inner : TYPE_NAME (inner)); + } +} + +/* Do a pushlevel for class declarations. */ + +void +pushlevel_class (void) +{ + class_binding_level = begin_scope (sk_class, current_class_type); +} + +/* ...and a poplevel for class declarations. */ + +void +poplevel_class (void) +{ + cp_binding_level *level = class_binding_level; + cp_class_binding *cb; + size_t i; + tree shadowed; + + auto_cond_timevar tv (TV_NAME_LOOKUP); + gcc_assert (level != 0); + + /* If we're leaving a toplevel class, cache its binding level. */ + if (current_class_depth == 1) + previous_class_level = level; + for (shadowed = level->type_shadowed; + shadowed; + shadowed = TREE_CHAIN (shadowed)) + SET_IDENTIFIER_TYPE_VALUE (TREE_PURPOSE (shadowed), TREE_VALUE (shadowed)); + + /* Remove the bindings for all of the class-level declarations. */ + if (level->class_shadowed) + { + FOR_EACH_VEC_ELT (*level->class_shadowed, i, cb) + { + IDENTIFIER_BINDING (cb->identifier) = cb->base->previous; + cxx_binding_free (cb->base); + } + ggc_free (level->class_shadowed); + level->class_shadowed = NULL; + } + + /* Now, pop out of the binding level which we created up in the + `pushlevel_class' routine. */ + gcc_assert (current_binding_level == level); + leave_scope (); +} + +/* Set INHERITED_VALUE_BINDING_P on BINDING to true or false, as + appropriate. DECL is the value to which a name has just been + bound. CLASS_TYPE is the class in which the lookup occurred. */ + +static void +set_inherited_value_binding_p (cxx_binding *binding, tree decl, + tree class_type) +{ + if (binding->value == decl && TREE_CODE (decl) != TREE_LIST) + { + tree context; + + if (is_overloaded_fn (decl)) + context = ovl_scope (decl); + else + { + gcc_assert (DECL_P (decl)); + context = context_for_name_lookup (decl); + } + + if (is_properly_derived_from (class_type, context)) + INHERITED_VALUE_BINDING_P (binding) = 1; + else + INHERITED_VALUE_BINDING_P (binding) = 0; + } + else if (binding->value == decl) + /* We only encounter a TREE_LIST when there is an ambiguity in the + base classes. Such an ambiguity can be overridden by a + definition in this class. */ + INHERITED_VALUE_BINDING_P (binding) = 1; + else + INHERITED_VALUE_BINDING_P (binding) = 0; +} + +/* Make the declaration of X appear in CLASS scope. */ + +bool +pushdecl_class_level (tree x) +{ + bool is_valid = true; + + /* Do nothing if we're adding to an outer lambda closure type, + outer_binding will add it later if it's needed. */ + if (current_class_type != class_binding_level->this_entity) + return true; + + auto_cond_timevar tv (TV_NAME_LOOKUP); + /* Get the name of X. */ + tree name = OVL_NAME (x); + + if (name) + { + is_valid = push_class_level_binding (name, x); + if (TREE_CODE (x) == TYPE_DECL) + set_identifier_type_value (name, x); + } + else if (ANON_AGGR_TYPE_P (TREE_TYPE (x))) + { + /* If X is an anonymous aggregate, all of its members are + treated as if they were members of the class containing the + aggregate, for naming purposes. */ + location_t save_location = input_location; + tree anon = TREE_TYPE (x); + if (vec<tree, va_gc> *member_vec = CLASSTYPE_MEMBER_VEC (anon)) + for (unsigned ix = member_vec->length (); ix--;) + { + tree binding = (*member_vec)[ix]; + if (STAT_HACK_P (binding)) + { + if (!pushdecl_class_level (STAT_TYPE (binding))) + is_valid = false; + binding = STAT_DECL (binding); + } + if (!pushdecl_class_level (binding)) + is_valid = false; + } + else + for (tree f = TYPE_FIELDS (anon); f; f = DECL_CHAIN (f)) + if (TREE_CODE (f) == FIELD_DECL) + { + input_location = DECL_SOURCE_LOCATION (f); + if (!pushdecl_class_level (f)) + is_valid = false; + } + input_location = save_location; + } + return is_valid; +} + +/* Return the BINDING (if any) for NAME in SCOPE, which is a class + scope. If the value returned is non-NULL, and the PREVIOUS field + is not set, callers must set the PREVIOUS field explicitly. */ + +static cxx_binding * +get_class_binding (tree name, cp_binding_level *scope) +{ + tree class_type; + tree type_binding; + tree value_binding; + cxx_binding *binding; + + class_type = scope->this_entity; + + /* Get the type binding. */ + type_binding = lookup_member (class_type, name, + /*protect=*/2, /*want_type=*/true, + tf_warning_or_error); + /* Get the value binding. */ + value_binding = lookup_member (class_type, name, + /*protect=*/2, /*want_type=*/false, + tf_warning_or_error); + + /* If we found either a type binding or a value binding, create a + new binding object. */ + if (type_binding || value_binding) + { + binding = new_class_binding (name, + value_binding, + type_binding, + scope); + set_inherited_value_binding_p (binding, value_binding, class_type); + } + else + binding = NULL; + + return binding; +} + +/* Make the declaration(s) of X appear in CLASS scope under the name + NAME. Returns true if the binding is valid. */ + +bool +push_class_level_binding (tree name, tree x) +{ + cxx_binding *binding; + tree decl = x; + bool ok; + + auto_cond_timevar tv (TV_NAME_LOOKUP); + + /* The class_binding_level will be NULL if x is a template + parameter name in a member template. */ + if (!class_binding_level) + return true; + + if (name == error_mark_node) + return false; + + /* Can happen for an erroneous declaration (c++/60384). */ + if (!identifier_p (name)) + { + gcc_assert (errorcount || sorrycount); + return false; + } + + /* Check for invalid member names. But don't worry about a default + argument-scope lambda being pushed after the class is complete. */ + gcc_assert (TYPE_BEING_DEFINED (current_class_type) + || LAMBDA_TYPE_P (TREE_TYPE (decl))); + /* Check that we're pushing into the right binding level. */ + gcc_assert (current_class_type == class_binding_level->this_entity); + + /* We could have been passed a tree list if this is an ambiguous + declaration. If so, pull the declaration out because + check_template_shadow will not handle a TREE_LIST. */ + if (TREE_CODE (decl) == TREE_LIST + && TREE_TYPE (decl) == error_mark_node) + decl = TREE_VALUE (decl); + + if (!check_template_shadow (decl)) + return false; + + /* [class.mem] + + If T is the name of a class, then each of the following shall + have a name different from T: + + -- every static data member of class T; + + -- every member of class T that is itself a type; + + -- every enumerator of every member of class T that is an + enumerated type; + + -- every member of every anonymous union that is a member of + class T. + + (Non-static data members were also forbidden to have the same + name as T until TC1.) */ + if ((VAR_P (x) + || TREE_CODE (x) == CONST_DECL + || (TREE_CODE (x) == TYPE_DECL + && !DECL_SELF_REFERENCE_P (x)) + /* A data member of an anonymous union. */ + || (TREE_CODE (x) == FIELD_DECL + && DECL_CONTEXT (x) != current_class_type)) + && DECL_NAME (x) == DECL_NAME (TYPE_NAME (current_class_type))) + { + tree scope = context_for_name_lookup (x); + if (TYPE_P (scope) && same_type_p (scope, current_class_type)) + { + error_at (DECL_SOURCE_LOCATION (x), + "%qD has the same name as the class in which it is " + "declared", x); + return false; + } + } + + /* Get the current binding for NAME in this class, if any. */ + binding = IDENTIFIER_BINDING (name); + if (!binding || binding->scope != class_binding_level) + { + binding = get_class_binding (name, class_binding_level); + /* If a new binding was created, put it at the front of the + IDENTIFIER_BINDING list. */ + if (binding) + { + binding->previous = IDENTIFIER_BINDING (name); + IDENTIFIER_BINDING (name) = binding; + } + } + + /* If there is already a binding, then we may need to update the + current value. */ + if (binding && binding->value) + { + tree bval = binding->value; + tree old_decl = NULL_TREE; + tree target_decl = strip_using_decl (decl); + tree target_bval = strip_using_decl (bval); + + if (INHERITED_VALUE_BINDING_P (binding)) + { + /* If the old binding was from a base class, and was for a + tag name, slide it over to make room for the new binding. + The old binding is still visible if explicitly qualified + with a class-key. */ + if (TREE_CODE (target_bval) == TYPE_DECL + && DECL_ARTIFICIAL (target_bval) + && !(TREE_CODE (target_decl) == TYPE_DECL + && DECL_ARTIFICIAL (target_decl))) + { + old_decl = binding->type; + binding->type = bval; + binding->value = NULL_TREE; + INHERITED_VALUE_BINDING_P (binding) = 0; + } + else + { + old_decl = bval; + /* Any inherited type declaration is hidden by the type + declaration in the derived class. */ + if (TREE_CODE (target_decl) == TYPE_DECL + && DECL_ARTIFICIAL (target_decl)) + binding->type = NULL_TREE; + } + } + else if (TREE_CODE (decl) == USING_DECL + && TREE_CODE (bval) == USING_DECL + && same_type_p (USING_DECL_SCOPE (decl), + USING_DECL_SCOPE (bval))) + /* This is a using redeclaration that will be diagnosed later + in supplement_binding */ + ; + else if (TREE_CODE (decl) == USING_DECL + && TREE_CODE (bval) == USING_DECL + && DECL_DEPENDENT_P (decl) + && DECL_DEPENDENT_P (bval)) + return true; + else if (TREE_CODE (decl) == USING_DECL + && OVL_P (target_bval)) + old_decl = bval; + else if (TREE_CODE (bval) == USING_DECL + && OVL_P (target_decl)) + old_decl = bval; + else if (OVL_P (target_decl) + && OVL_P (target_bval)) + old_decl = bval; + + if (old_decl && binding->scope == class_binding_level) + { + binding->value = x; + /* It is always safe to clear INHERITED_VALUE_BINDING_P + here. This function is only used to register bindings + from with the class definition itself. */ + INHERITED_VALUE_BINDING_P (binding) = 0; + return true; + } + } + + /* Note that we declared this value so that we can issue an error if + this is an invalid redeclaration of a name already used for some + other purpose. */ + note_name_declared_in_class (name, decl); + + /* If we didn't replace an existing binding, put the binding on the + stack of bindings for the identifier, and update the shadowed + list. */ + if (binding && binding->scope == class_binding_level) + /* Supplement the existing binding. */ + ok = supplement_binding (binding, decl); + else + { + /* Create a new binding. */ + push_binding (name, decl, class_binding_level); + ok = true; + } + + return ok; +} + +/* Process and lookup a using decl SCOPE::lookup.name, filling in + lookup.values & lookup.type. Return a USING_DECL, or NULL_TREE on + failure. */ + +static tree +lookup_using_decl (tree scope, name_lookup &lookup) +{ + tree current = current_scope (); + bool dependent_p = false; + tree binfo = NULL_TREE; + base_kind b_kind = bk_not_base; + + /* Because C++20 breaks the invariant that only member using-decls + refer to members and only non-member using-decls refer to + non-members, we first do the lookups, and then do validation that + what we found is ok. */ + + if (TREE_CODE (scope) == ENUMERAL_TYPE + && cxx_dialect < cxx20 + && UNSCOPED_ENUM_P (scope) + && !TYPE_FUNCTION_SCOPE_P (scope)) + { + /* PR c++/60265 argued that since C++11 added explicit enum scope, we + should allow it as meaning the enclosing scope. I don't see any + justification for this in C++11, but let's keep allowing it. */ + tree ctx = CP_TYPE_CONTEXT (scope); + if (CLASS_TYPE_P (ctx) == CLASS_TYPE_P (current)) + scope = ctx; + } + + /* You cannot using-decl a destructor. */ + if (TREE_CODE (lookup.name) == BIT_NOT_EXPR) + { + error ("%<%T%s%D%> names destructor", scope, + &"::"[scope == global_namespace ? 2 : 0], lookup.name); + return NULL_TREE; + } + + if (TREE_CODE (scope) == NAMESPACE_DECL) + { + /* Naming a namespace member. */ + qualified_namespace_lookup (scope, &lookup); + + if (TYPE_P (current) + && (!lookup.value + || lookup.type + || cxx_dialect < cxx20 + || TREE_CODE (lookup.value) != CONST_DECL)) + { + error ("using-declaration for non-member at class scope"); + return NULL_TREE; + } + } + else if (TREE_CODE (scope) == ENUMERAL_TYPE) + { + /* Naming an enumeration member. */ + if (cxx_dialect < cxx20) + error ("%<using%> with enumeration scope %q#T " + "only available with %<-std=c++20%> or %<-std=gnu++20%>", + scope); + lookup.value = lookup_enumerator (scope, lookup.name); + } + else + { + /* Naming a class member. This is awkward in C++20, because we + might be naming an enumerator of an unrelated class. */ + + tree npscope = scope; + if (PACK_EXPANSION_P (scope)) + npscope = PACK_EXPANSION_PATTERN (scope); + + if (!MAYBE_CLASS_TYPE_P (npscope)) + { + error ("%qT is not a class, namespace, or enumeration", npscope); + return NULL_TREE; + } + + /* Using T::T declares inheriting ctors, even if T is a typedef. */ + if (lookup.name == TYPE_IDENTIFIER (npscope) + || constructor_name_p (lookup.name, npscope)) + { + if (!TYPE_P (current)) + { + error ("non-member using-declaration names constructor of %qT", + npscope); + return NULL_TREE; + } + maybe_warn_cpp0x (CPP0X_INHERITING_CTORS); + lookup.name = ctor_identifier; + CLASSTYPE_NON_AGGREGATE (current) = true; + } + + if (!TYPE_P (current) && cxx_dialect < cxx20) + { + error ("using-declaration for member at non-class scope"); + return NULL_TREE; + } + + bool depscope = dependent_scope_p (scope); + + if (depscope) + /* Leave binfo null. */; + else if (TYPE_P (current)) + { + binfo = lookup_base (current, scope, ba_any, &b_kind, tf_none); + gcc_checking_assert (b_kind >= bk_not_base); + + if (b_kind == bk_not_base && any_dependent_bases_p ()) + /* Treat as-if dependent. */ + depscope = true; + else if (lookup.name == ctor_identifier + && (b_kind < bk_proper_base || !binfo_direct_p (binfo))) + { + if (any_dependent_bases_p ()) + depscope = true; + else + { + error ("%qT is not a direct base of %qT", scope, current); + return NULL_TREE; + } + } + + if (b_kind < bk_proper_base) + binfo = TYPE_BINFO (scope); + } + else + binfo = TYPE_BINFO (scope); + + dependent_p = (depscope + || (IDENTIFIER_CONV_OP_P (lookup.name) + && dependent_type_p (TREE_TYPE (lookup.name)))); + + if (!dependent_p) + lookup.value = lookup_member (binfo, lookup.name, /*protect=*/2, + /*want_type=*/false, tf_none); + + if (!depscope && b_kind < bk_proper_base) + { + if (cxx_dialect >= cxx20 && lookup.value + && TREE_CODE (lookup.value) == CONST_DECL) + { + /* Using an unrelated enum; check access here rather + than separately for class and non-class using. */ + perform_or_defer_access_check + (binfo, lookup.value, lookup.value, tf_warning_or_error); + /* And then if this is a copy from handle_using_decl, look + through to the original enumerator. */ + if (CONST_DECL_USING_P (lookup.value)) + lookup.value = DECL_ABSTRACT_ORIGIN (lookup.value); + } + else if (!TYPE_P (current)) + { + error ("using-declaration for member at non-class scope"); + return NULL_TREE; + } + else + { + auto_diagnostic_group g; + error_not_base_type (scope, current); + if (lookup.value && DECL_IMPLICIT_TYPEDEF_P (lookup.value) + && TREE_CODE (TREE_TYPE (lookup.value)) == ENUMERAL_TYPE) + inform (input_location, + "did you mean %<using enum %T::%D%>?", + scope, lookup.name); + return NULL_TREE; + } + } + } + + /* Did we find anything sane? */ + if (dependent_p) + ; + else if (!lookup.value) + { + error ("%qD has not been declared in %qD", lookup.name, scope); + return NULL_TREE; + } + else if (TREE_CODE (lookup.value) == TREE_LIST + /* We can (independently) have ambiguous implicit typedefs. */ + || (lookup.type && TREE_CODE (lookup.type) == TREE_LIST)) + { + error ("reference to %qD is ambiguous", lookup.name); + print_candidates (TREE_CODE (lookup.value) == TREE_LIST + ? lookup.value : lookup.type); + return NULL_TREE; + } + else if (TREE_CODE (lookup.value) == NAMESPACE_DECL) + { + error ("using-declaration may not name namespace %qD", lookup.value); + return NULL_TREE; + } + + if (TYPE_P (current)) + { + /* In class scope. */ + + /* Cannot introduce a constructor name. */ + if (constructor_name_p (lookup.name, current)) + { + error ("%<%T::%D%> names constructor in %qT", + scope, lookup.name, current); + return NULL_TREE; + } + + if (lookup.value && BASELINK_P (lookup.value)) + /* The binfo from which the functions came does not matter. */ + lookup.value = BASELINK_FUNCTIONS (lookup.value); + } + + tree using_decl = build_lang_decl (USING_DECL, lookup.name, NULL_TREE); + USING_DECL_SCOPE (using_decl) = scope; + USING_DECL_DECLS (using_decl) = lookup.value; + DECL_DEPENDENT_P (using_decl) = dependent_p; + DECL_CONTEXT (using_decl) = current; + if (TYPE_P (current) && b_kind == bk_not_base) + USING_DECL_UNRELATED_P (using_decl) = true; + + return using_decl; +} + +/* Process "using SCOPE::NAME" in a class scope. Return the + USING_DECL created. */ + +tree +do_class_using_decl (tree scope, tree name) +{ + if (name == error_mark_node + || scope == error_mark_node) + return NULL_TREE; + + name_lookup lookup (name); + return lookup_using_decl (scope, lookup); +} + + +/* Return the binding for NAME in NS in the current TU. If NS is + NULL, look in global_namespace. We will not find declarations + from imports. Users of this who, having found nothing, push a new + decl must be prepared for that pushing to match an existing decl. */ + +tree +get_namespace_binding (tree ns, tree name) +{ + auto_cond_timevar tv (TV_NAME_LOOKUP); + if (!ns) + ns = global_namespace; + gcc_checking_assert (!DECL_NAMESPACE_ALIAS (ns)); + tree ret = NULL_TREE; + + if (tree *b = find_namespace_slot (ns, name)) + { + ret = *b; + + if (TREE_CODE (ret) == BINDING_VECTOR) + ret = BINDING_VECTOR_CLUSTER (ret, 0).slots[0]; + if (ret) + ret = MAYBE_STAT_DECL (ret); + } + + return ret; +} + +/* Push internal DECL into the global namespace. Does not do the + full overload fn handling and does not add it to the list of things + in the namespace. */ + +void +set_global_binding (tree decl) +{ + auto_cond_timevar tv (TV_NAME_LOOKUP); + + tree *slot = find_namespace_slot (global_namespace, DECL_NAME (decl), true); + + if (*slot) + /* The user's placed something in the implementor's namespace. */ + diagnose_name_conflict (decl, MAYBE_STAT_DECL (*slot)); + + /* Force the binding, so compiler internals continue to work. */ + *slot = decl; +} + +/* Set the context of a declaration to scope. Complain if we are not + outside scope. */ + +void +set_decl_namespace (tree decl, tree scope, bool friendp) +{ + /* Get rid of namespace aliases. */ + scope = ORIGINAL_NAMESPACE (scope); + + /* It is ok for friends to be qualified in parallel space. */ + if (!friendp && !is_nested_namespace (current_namespace, scope)) + error ("declaration of %qD not in a namespace surrounding %qD", + decl, scope); + DECL_CONTEXT (decl) = FROB_CONTEXT (scope); + + /* See whether this has been declared in the namespace or inline + children. */ + tree old = NULL_TREE; + { + name_lookup lookup (DECL_NAME (decl), + LOOK_want::NORMAL | LOOK_want::HIDDEN_FRIEND); + if (!lookup.search_qualified (scope, /*usings=*/false)) + /* No old declaration at all. */ + goto not_found; + old = lookup.value; + } + + /* If it's a TREE_LIST, the result of the lookup was ambiguous. */ + if (TREE_CODE (old) == TREE_LIST) + { + ambiguous: + DECL_CONTEXT (decl) = FROB_CONTEXT (scope); + error ("reference to %qD is ambiguous", decl); + print_candidates (old); + return; + } + + if (!DECL_DECLARES_FUNCTION_P (decl)) + { + /* Don't compare non-function decls with decls_match here, since + it can't check for the correct constness at this + point. pushdecl will find those errors later. */ + + /* We might have found it in an inline namespace child of SCOPE. */ + if (TREE_CODE (decl) == TREE_CODE (old)) + DECL_CONTEXT (decl) = DECL_CONTEXT (old); + + found: + /* Writing "N::i" to declare something directly in "N" is invalid. */ + if (CP_DECL_CONTEXT (decl) == current_namespace + && at_namespace_scope_p ()) + error_at (DECL_SOURCE_LOCATION (decl), + "explicit qualification in declaration of %qD", decl); + return; + } + + /* Since decl is a function, old should contain a function decl. */ + if (!OVL_P (old)) + { + not_found: + /* It didn't work, go back to the explicit scope. */ + DECL_CONTEXT (decl) = FROB_CONTEXT (scope); + error ("%qD should have been declared inside %qD", decl, scope); + + return; + } + + /* We handle these in check_explicit_instantiation_namespace. */ + if (processing_explicit_instantiation) + return; + if (processing_template_decl || processing_specialization) + /* We have not yet called push_template_decl to turn a + FUNCTION_DECL into a TEMPLATE_DECL, so the declarations won't + match. But, we'll check later, when we construct the + template. */ + return; + + /* Instantiations or specializations of templates may be declared as + friends in any namespace. */ + if (friendp && DECL_USE_TEMPLATE (decl)) + return; + + tree found = NULL_TREE; + bool hidden_p = false; + + for (lkp_iterator iter (old); iter; ++iter) + { + if (iter.using_p ()) + continue; + + tree ofn = *iter; + + /* Adjust DECL_CONTEXT first so decls_match will return true + if DECL will match a declaration in an inline namespace. */ + DECL_CONTEXT (decl) = DECL_CONTEXT (ofn); + if (decls_match (decl, ofn)) + { + if (found) + { + /* We found more than one matching declaration. This + can happen if we have two inline namespace children, + each containing a suitable declaration. */ + DECL_CONTEXT (decl) = FROB_CONTEXT (scope); + goto ambiguous; + } + found = ofn; + hidden_p = iter.hidden_p (); + } + } + + if (found) + { + if (hidden_p) + { + pedwarn (DECL_SOURCE_LOCATION (decl), 0, + "%qD has not been declared within %qD", decl, scope); + inform (DECL_SOURCE_LOCATION (found), + "only here as a %<friend%>"); + } + DECL_CONTEXT (decl) = DECL_CONTEXT (found); + goto found; + } + + goto not_found; +} + +/* Return the namespace where the current declaration is declared. */ + +tree +current_decl_namespace (void) +{ + tree result; + /* If we have been pushed into a different namespace, use it. */ + if (!vec_safe_is_empty (decl_namespace_list)) + return decl_namespace_list->last (); + + if (current_class_type) + result = decl_namespace_context (current_class_type); + else if (current_function_decl) + result = decl_namespace_context (current_function_decl); + else + result = current_namespace; + return result; +} + +/* Process any ATTRIBUTES on a namespace definition. Returns true if + attribute visibility is seen. */ + +bool +handle_namespace_attrs (tree ns, tree attributes) +{ + tree d; + bool saw_vis = false; + + if (attributes == error_mark_node) + return false; + + for (d = attributes; d; d = TREE_CHAIN (d)) + { + tree name = get_attribute_name (d); + tree args = TREE_VALUE (d); + + if (is_attribute_p ("visibility", name)) + { + /* attribute visibility is a property of the syntactic block + rather than the namespace as a whole, so we don't touch the + NAMESPACE_DECL at all. */ + tree x = args ? TREE_VALUE (args) : NULL_TREE; + if (x == NULL_TREE || TREE_CODE (x) != STRING_CST || TREE_CHAIN (args)) + { + warning (OPT_Wattributes, + "%qD attribute requires a single NTBS argument", + name); + continue; + } + + if (!TREE_PUBLIC (ns)) + warning (OPT_Wattributes, + "%qD attribute is meaningless since members of the " + "anonymous namespace get local symbols", name); + + push_visibility (TREE_STRING_POINTER (x), 1); + saw_vis = true; + } + else if (is_attribute_p ("abi_tag", name)) + { + if (!DECL_NAME (ns)) + { + warning (OPT_Wattributes, "ignoring %qD attribute on anonymous " + "namespace", name); + continue; + } + if (!DECL_NAMESPACE_INLINE_P (ns)) + { + warning (OPT_Wattributes, "ignoring %qD attribute on non-inline " + "namespace", name); + continue; + } + if (!args) + { + tree dn = DECL_NAME (ns); + args = build_string (IDENTIFIER_LENGTH (dn) + 1, + IDENTIFIER_POINTER (dn)); + TREE_TYPE (args) = char_array_type_node; + args = fix_string_type (args); + args = build_tree_list (NULL_TREE, args); + } + if (check_abi_tag_args (args, name)) + DECL_ATTRIBUTES (ns) = tree_cons (name, args, + DECL_ATTRIBUTES (ns)); + } + else if (is_attribute_p ("deprecated", name)) + { + if (!DECL_NAME (ns)) + { + warning (OPT_Wattributes, "ignoring %qD attribute on anonymous " + "namespace", name); + continue; + } + if (args && TREE_CODE (TREE_VALUE (args)) != STRING_CST) + { + error ("deprecated message is not a string"); + continue; + } + TREE_DEPRECATED (ns) = 1; + if (args) + DECL_ATTRIBUTES (ns) = tree_cons (name, args, + DECL_ATTRIBUTES (ns)); + } + else + { + warning (OPT_Wattributes, "%qD attribute directive ignored", + name); + continue; + } + } + + return saw_vis; +} + +/* Temporarily set the namespace for the current declaration. */ + +void +push_decl_namespace (tree decl) +{ + if (TREE_CODE (decl) != NAMESPACE_DECL) + decl = decl_namespace_context (decl); + vec_safe_push (decl_namespace_list, ORIGINAL_NAMESPACE (decl)); +} + +/* [namespace.memdef]/2 */ + +void +pop_decl_namespace (void) +{ + decl_namespace_list->pop (); +} + +/* Process a namespace-alias declaration. */ + +void +do_namespace_alias (tree alias, tree name_space) +{ + if (name_space == error_mark_node) + return; + + gcc_assert (TREE_CODE (name_space) == NAMESPACE_DECL); + + name_space = ORIGINAL_NAMESPACE (name_space); + + /* Build the alias. */ + alias = build_lang_decl (NAMESPACE_DECL, alias, void_type_node); + DECL_NAMESPACE_ALIAS (alias) = name_space; + DECL_EXTERNAL (alias) = 1; + DECL_CONTEXT (alias) = FROB_CONTEXT (current_scope ()); + set_originating_module (alias); + + pushdecl (alias); + + /* Emit debug info for namespace alias. */ + if (!building_stmt_list_p ()) + (*debug_hooks->early_global_decl) (alias); +} + +/* Like pushdecl, only it places DECL in the current namespace, + if appropriate. */ + +tree +pushdecl_namespace_level (tree decl, bool hiding) +{ + auto_cond_timevar tv (TV_NAME_LOOKUP); + return do_pushdecl_with_scope (decl, NAMESPACE_LEVEL (current_namespace), + hiding); +} + +/* Wrapper around push_local_binding to push the bindings for + a non-member USING_DECL with NAME and VALUE. LOOKUP, if non-null, + is the result of name lookup during template parsing. */ + +static void +push_using_decl_bindings (name_lookup *lookup, tree name, tree value) +{ + tree type = NULL_TREE; + + cxx_binding *binding = find_local_binding (current_binding_level, name); + if (binding) + { + value = binding->value; + type = binding->type; + } + + /* DR 36 questions why using-decls at function scope may not be + duplicates. Disallow it, as C++11 claimed and PR 20420 + implemented. */ + if (lookup) + do_nonmember_using_decl (*lookup, true, true, &value, &type); + + if (!value) + ; + else if (binding && value == binding->value) + /* Redeclaration of this USING_DECL. */; + else if (binding && binding->value && TREE_CODE (value) == OVERLOAD) + { + /* We already have this binding, so replace it. */ + update_local_overload (IDENTIFIER_BINDING (name), value); + IDENTIFIER_BINDING (name)->value = value; + } + else + /* Install the new binding. */ + push_local_binding (name, value, /*using=*/true); + + if (!type) + ; + else if (binding && type == binding->type) + ; + else + { + push_local_binding (name, type, /*using=*/true); + set_identifier_type_value (name, type); + } +} + +/* Overload for push_using_decl_bindings that doesn't take a name_lookup. */ + +void +push_using_decl_bindings (tree name, tree value) +{ + push_using_decl_bindings (nullptr, name, value); +} + +/* Process a using declaration in non-class scope. */ + +void +finish_nonmember_using_decl (tree scope, tree name) +{ + gcc_checking_assert (current_binding_level->kind != sk_class); + + if (scope == error_mark_node || name == error_mark_node) + return; + + name_lookup lookup (name); + + tree using_decl = lookup_using_decl (scope, lookup); + if (!using_decl) + return; + + /* Emit debug info. */ + if (!processing_template_decl) + cp_emit_debug_info_for_using (lookup.value, + current_binding_level->this_entity); + + if (current_binding_level->kind == sk_namespace) + { + tree *slot = find_namespace_slot (current_namespace, name, true); + tree *mslot = get_fixed_binding_slot (slot, name, + BINDING_SLOT_CURRENT, true); + bool failed = false; + + if (mslot != slot) + { + /* A module vector. I presume the binding list is going to + be sparser than the import bitmap. Hence iterate over + the former checking for bits set in the bitmap. */ + bitmap imports = get_import_bitmap (); + binding_cluster *cluster = BINDING_VECTOR_CLUSTER_BASE (*slot); + + /* Scan the imported bindings. */ + unsigned ix = BINDING_VECTOR_NUM_CLUSTERS (*slot); + if (BINDING_VECTOR_SLOTS_PER_CLUSTER == BINDING_SLOTS_FIXED) + { + ix--; + cluster++; + } + + /* Do this in forward order, so we load modules in an order + the user expects. */ + for (; ix--; cluster++) + for (unsigned jx = 0; jx != BINDING_VECTOR_SLOTS_PER_CLUSTER; jx++) + { + /* Are we importing this module? */ + if (unsigned base = cluster->indices[jx].base) + if (unsigned span = cluster->indices[jx].span) + do + if (bitmap_bit_p (imports, base)) + goto found; + while (++base, --span); + continue; + + found:; + /* Is it loaded? */ + if (cluster->slots[jx].is_lazy ()) + { + gcc_assert (cluster->indices[jx].span == 1); + lazy_load_binding (cluster->indices[jx].base, + scope, name, &cluster->slots[jx]); + } + + tree value = cluster->slots[jx]; + if (!value) + /* Load errors could mean there's nothing here. */ + continue; + + /* Extract what we can see from here. If there's no + stat_hack, then everything was exported. */ + tree type = NULL_TREE; + + /* If no stat hack, everything is visible. */ + if (STAT_HACK_P (value)) + { + if (STAT_TYPE_VISIBLE_P (value)) + type = STAT_TYPE (value); + value = STAT_VISIBLE (value); + } + + if (do_nonmember_using_decl (lookup, false, false, + &value, &type)) + { + failed = true; + break; + } + } + } + + if (!failed) + { + /* Now do the current slot. */ + tree value = MAYBE_STAT_DECL (*mslot); + tree type = MAYBE_STAT_TYPE (*mslot); + + do_nonmember_using_decl (lookup, false, true, &value, &type); + + // FIXME: Partition mergeableness? + if (STAT_HACK_P (*mslot)) + { + STAT_DECL (*mslot) = value; + STAT_TYPE (*mslot) = type; + } + else if (type) + *mslot = stat_hack (value, type); + else + *mslot = value; + } + } + else + { + add_decl_expr (using_decl); + if (DECL_DEPENDENT_P (using_decl)) + lookup.value = using_decl; + push_using_decl_bindings (&lookup, name, NULL_TREE); + } +} + +/* Return the declarations that are members of the namespace NS. */ + +tree +cp_namespace_decls (tree ns) +{ + return NAMESPACE_LEVEL (ns)->names; +} + +/* Given a lookup that returned VAL, use FLAGS to decide if we want to + ignore it or not. Subroutine of lookup_name_1 and lookup_type_scope. */ + +static bool +qualify_lookup (tree val, LOOK_want want) +{ + if (val == NULL_TREE) + return false; + + if (bool (want & LOOK_want::TYPE)) + { + tree target_val = strip_using_decl (val); + + if (TREE_CODE (STRIP_TEMPLATE (target_val)) == TYPE_DECL) + return true; + } + + if (bool (want & LOOK_want::TYPE_NAMESPACE)) + return TREE_CODE (val) == NAMESPACE_DECL; + + return true; +} + +/* Is there a "using namespace std;" directive within USINGS? */ + +static bool +using_directives_contain_std_p (vec<tree, va_gc> *usings) +{ + if (!usings) + return false; + + for (unsigned ix = usings->length (); ix--;) + if ((*usings)[ix] == std_node) + return true; + + return false; +} + +/* Is there a "using namespace std;" directive within the current + namespace (or its ancestors)? + Compare with name_lookup::search_unqualified. */ + +static bool +has_using_namespace_std_directive_p () +{ + for (cp_binding_level *level = current_binding_level; + level; + level = level->level_chain) + if (using_directives_contain_std_p (level->using_directives)) + return true; + + return false; +} + +/* Subclass of deferred_diagnostic, for issuing a note when + --param cxx-max-namespaces-for-diagnostic-help is reached. + + The note should be issued after the error, but before any other + deferred diagnostics. This is handled by decorating a wrapped + deferred_diagnostic, and emitting a note before that wrapped note is + deleted. */ + +class namespace_limit_reached : public deferred_diagnostic +{ + public: + namespace_limit_reached (location_t loc, unsigned limit, tree name, + std::unique_ptr<deferred_diagnostic> wrapped) + : deferred_diagnostic (loc), + m_limit (limit), m_name (name), + m_wrapped (move (wrapped)) + { + } + + ~namespace_limit_reached () + { + /* Unconditionally warn that the search was truncated. */ + inform (get_location (), + "maximum limit of %d namespaces searched for %qE", + m_limit, m_name); + /* m_wrapped will be implicitly deleted after this, emitting any followup + diagnostic after the above note. */ + } + + private: + unsigned m_limit; + tree m_name; + std::unique_ptr<deferred_diagnostic> m_wrapped; +}; + +/* Subclass of deferred_diagnostic, for use when issuing a single suggestion. + Emit a note showing the location of the declaration of the suggestion. */ + +class show_candidate_location : public deferred_diagnostic +{ + public: + show_candidate_location (location_t loc, tree candidate) + : deferred_diagnostic (loc), + m_candidate (candidate) + { + } + + ~show_candidate_location () + { + inform (location_of (m_candidate), "%qE declared here", m_candidate); + } + + private: + tree m_candidate; +}; + +/* Subclass of deferred_diagnostic, for use when there are multiple candidates + to be suggested by suggest_alternatives_for. + + Emit a series of notes showing the various suggestions. */ + +class suggest_alternatives : public deferred_diagnostic +{ + public: + suggest_alternatives (location_t loc, vec<tree> candidates) + : deferred_diagnostic (loc), + m_candidates (candidates) + { + } + + ~suggest_alternatives () + { + if (m_candidates.length ()) + { + inform_n (get_location (), m_candidates.length (), + "suggested alternative:", + "suggested alternatives:"); + for (unsigned ix = 0; ix != m_candidates.length (); ix++) + { + tree val = m_candidates[ix]; + + inform (location_of (val), " %qE", val); + } + } + m_candidates.release (); + } + + private: + vec<tree> m_candidates; +}; + +/* A class for encapsulating the result of a search across + multiple namespaces (and scoped enums within them) for an + unrecognized name seen at a given source location. */ + +class namespace_hints +{ + public: + namespace_hints (location_t loc, tree name); + + name_hint convert_candidates_to_name_hint (); + name_hint maybe_decorate_with_limit (name_hint); + + private: + void maybe_add_candidate_for_scoped_enum (tree scoped_enum, tree name); + + location_t m_loc; + tree m_name; + vec<tree> m_candidates; + + /* Value of "--param cxx-max-namespaces-for-diagnostic-help". */ + unsigned m_limit; + + /* Was the limit reached? */ + bool m_limited; +}; + +/* Constructor for namespace_hints. Search namespaces and scoped enums, + looking for an exact match for unrecognized NAME seen at LOC. */ + +namespace_hints::namespace_hints (location_t loc, tree name) +: m_loc(loc), m_name (name) +{ + auto_vec<tree> worklist; + + m_candidates = vNULL; + m_limited = false; + m_limit = param_cxx_max_namespaces_for_diagnostic_help; + + /* Breadth-first search of namespaces. Up to limit namespaces + searched (limit zero == unlimited). */ + worklist.safe_push (global_namespace); + for (unsigned ix = 0; ix != worklist.length (); ix++) + { + tree ns = worklist[ix]; + name_lookup lookup (name); + + if (lookup.search_qualified (ns, false)) + m_candidates.safe_push (lookup.value); + + if (!m_limited) + { + /* Look for child namespaces. We have to do this + indirectly because they are chained in reverse order, + which is confusing to the user. */ + auto_vec<tree> children; + + for (tree decl = NAMESPACE_LEVEL (ns)->names; + decl; decl = TREE_CHAIN (decl)) + { + if (TREE_CODE (decl) == NAMESPACE_DECL + && !DECL_NAMESPACE_ALIAS (decl) + && !DECL_NAMESPACE_INLINE_P (decl)) + children.safe_push (decl); + + /* Look for exact matches for NAME within scoped enums. + These aren't added to the worklist, and so don't count + against the search limit. */ + if (TREE_CODE (decl) == TYPE_DECL) + { + tree type = TREE_TYPE (decl); + if (SCOPED_ENUM_P (type)) + maybe_add_candidate_for_scoped_enum (type, name); + } + } + + while (!m_limited && !children.is_empty ()) + { + if (worklist.length () == m_limit) + m_limited = true; + else + worklist.safe_push (children.pop ()); + } + } + } +} + +/* Drop ownership of m_candidates, using it to generate a name_hint at m_loc + for m_name, an IDENTIFIER_NODE for which name lookup failed. + + If m_candidates is non-empty, use it to generate a suggestion and/or + a deferred diagnostic that lists the possible candidate(s). +*/ + +name_hint +namespace_hints::convert_candidates_to_name_hint () +{ + /* How many candidates do we have? */ + + /* If we have just one candidate, issue a name_hint with it as a suggestion + (so that consumers are able to suggest it within the error message and emit + it as a fix-it hint), and with a note showing the candidate's location. */ + if (m_candidates.length () == 1) + { + tree candidate = m_candidates[0]; + /* Clean up CANDIDATES. */ + m_candidates.release (); + return name_hint (expr_to_string (candidate), + new show_candidate_location (m_loc, candidate)); + } + else if (m_candidates.length () > 1) + /* If we have more than one candidate, issue a name_hint without a single + "suggestion", but with a deferred diagnostic that lists the + various candidates. This takes ownership of m_candidates. */ + return name_hint (NULL, new suggest_alternatives (m_loc, m_candidates)); + + /* Otherwise, m_candidates ought to be empty, so no cleanup is necessary. */ + gcc_assert (m_candidates.length () == 0); + gcc_assert (m_candidates == vNULL); + + return name_hint (); +} + +/* If --param cxx-max-namespaces-for-diagnostic-help was reached, + then we want to emit a note about after the error, but before + any other deferred diagnostics. + + Handle this by figuring out what hint is needed, then optionally + decorating HINT with a namespace_limit_reached wrapper. */ + +name_hint +namespace_hints::maybe_decorate_with_limit (name_hint hint) +{ + if (m_limited) + return name_hint (hint.suggestion (), + new namespace_limit_reached (m_loc, m_limit, + m_name, + hint.take_deferred ())); + else + return hint; +} + +/* Look inside SCOPED_ENUM for exact matches for NAME. + If one is found, add its CONST_DECL to m_candidates. */ + +void +namespace_hints::maybe_add_candidate_for_scoped_enum (tree scoped_enum, + tree name) +{ + gcc_assert (SCOPED_ENUM_P (scoped_enum)); + + for (tree iter = TYPE_VALUES (scoped_enum); iter; iter = TREE_CHAIN (iter)) + { + tree id = TREE_PURPOSE (iter); + if (id == name) + { + m_candidates.safe_push (TREE_VALUE (iter)); + return; + } + } +} + +/* Generate a name_hint at LOCATION for NAME, an IDENTIFIER_NODE for which + name lookup failed. + + Search through all available namespaces and any scoped enums within them + and generate a suggestion and/or a deferred diagnostic that lists possible + candidate(s). + + If no exact matches are found, and SUGGEST_MISSPELLINGS is true, then also + look for near-matches and suggest the best near-match, if there is one. + + If nothing is found, then an empty name_hint is returned. */ + +name_hint +suggest_alternatives_for (location_t location, tree name, + bool suggest_misspellings) +{ + /* First, search for exact matches in other namespaces. */ + namespace_hints ns_hints (location, name); + name_hint result = ns_hints.convert_candidates_to_name_hint (); + + /* Otherwise, try other approaches. */ + if (!result) + result = suggest_alternatives_for_1 (location, name, suggest_misspellings); + + return ns_hints.maybe_decorate_with_limit (std::move (result)); +} + +/* The second half of suggest_alternatives_for, for when no exact matches + were found in other namespaces. */ + +static name_hint +suggest_alternatives_for_1 (location_t location, tree name, + bool suggest_misspellings) +{ + /* No candidates were found in the available namespaces. */ + + /* If there's a "using namespace std;" active, and this + is one of the most common "std::" names, then it's probably a + missing #include. */ + if (has_using_namespace_std_directive_p ()) + { + name_hint hint = maybe_suggest_missing_std_header (location, name); + if (hint) + return hint; + } + + /* Otherwise, consider misspellings. */ + if (!suggest_misspellings) + return name_hint (); + + return lookup_name_fuzzy (name, FUZZY_LOOKUP_NAME, location); +} + +/* Generate a name_hint at LOCATION for NAME, an IDENTIFIER_NODE for which + name lookup failed. + + Search through all available namespaces and generate a suggestion and/or + a deferred diagnostic that lists possible candidate(s). + + This is similiar to suggest_alternatives_for, but doesn't fallback to + the other approaches used by that function. */ + +name_hint +suggest_alternatives_in_other_namespaces (location_t location, tree name) +{ + namespace_hints ns_hints (location, name); + + name_hint result = ns_hints.convert_candidates_to_name_hint (); + + return ns_hints.maybe_decorate_with_limit (std::move (result)); +} + +/* A well-known name within the C++ standard library, returned by + get_std_name_hint. */ + +struct std_name_hint +{ + /* A name within "std::". */ + const char *name; + + /* The header name defining it within the C++ Standard Library + (with '<' and '>'). */ + const char *header; + + /* The dialect of C++ in which this was added. */ + enum cxx_dialect min_dialect; +}; + +/* Subroutine of maybe_suggest_missing_header for handling unrecognized names + for some of the most common names within "std::". + Given non-NULL NAME, return the std_name_hint for it, or NULL. */ + +static const std_name_hint * +get_std_name_hint (const char *name) +{ + static const std_name_hint hints[] = { + /* <any>. */ + {"any", "<any>", cxx17}, + {"any_cast", "<any>", cxx17}, + {"make_any", "<any>", cxx17}, + /* <array>. */ + {"array", "<array>", cxx11}, + {"to_array", "<array>", cxx20}, + /* <atomic>. */ + {"atomic", "<atomic>", cxx11}, + {"atomic_flag", "<atomic>", cxx11}, + {"atomic_ref", "<atomic>", cxx20}, + /* <bitset>. */ + {"bitset", "<bitset>", cxx11}, + /* <compare> */ + {"weak_equality", "<compare>", cxx20}, + {"strong_equality", "<compare>", cxx20}, + {"partial_ordering", "<compare>", cxx20}, + {"weak_ordering", "<compare>", cxx20}, + {"strong_ordering", "<compare>", cxx20}, + /* <complex>. */ + {"complex", "<complex>", cxx98}, + {"complex_literals", "<complex>", cxx14}, + /* <condition_variable>. */ + {"condition_variable", "<condition_variable>", cxx11}, + {"condition_variable_any", "<condition_variable>", cxx11}, + /* <cstddef>. */ + {"byte", "<cstddef>", cxx17}, + /* <deque>. */ + {"deque", "<deque>", cxx98}, + /* <forward_list>. */ + {"forward_list", "<forward_list>", cxx11}, + /* <fstream>. */ + {"basic_filebuf", "<fstream>", cxx98}, + {"basic_ifstream", "<fstream>", cxx98}, + {"basic_ofstream", "<fstream>", cxx98}, + {"basic_fstream", "<fstream>", cxx98}, + {"fstream", "<fstream>", cxx98}, + {"ifstream", "<fstream>", cxx98}, + {"ofstream", "<fstream>", cxx98}, + /* <functional>. */ + {"bind", "<functional>", cxx11}, + {"bind_front", "<functional>", cxx20}, + {"function", "<functional>", cxx11}, + {"hash", "<functional>", cxx11}, + {"invoke", "<functional>", cxx17}, + {"mem_fn", "<functional>", cxx11}, + {"not_fn", "<functional>", cxx17}, + {"reference_wrapper", "<functional>", cxx11}, + {"unwrap_reference", "<functional>", cxx20}, + {"unwrap_reference_t", "<functional>", cxx20}, + {"unwrap_ref_decay", "<functional>", cxx20}, + {"unwrap_ref_decay_t", "<functional>", cxx20}, + /* <future>. */ + {"async", "<future>", cxx11}, + {"future", "<future>", cxx11}, + {"packaged_task", "<future>", cxx11}, + {"promise", "<future>", cxx11}, + /* <iostream>. */ + {"cin", "<iostream>", cxx98}, + {"cout", "<iostream>", cxx98}, + {"cerr", "<iostream>", cxx98}, + {"clog", "<iostream>", cxx98}, + {"wcin", "<iostream>", cxx98}, + {"wcout", "<iostream>", cxx98}, + {"wclog", "<iostream>", cxx98}, + /* <istream>. */ + {"istream", "<istream>", cxx98}, + /* <iterator>. */ + {"advance", "<iterator>", cxx98}, + {"back_inserter", "<iterator>", cxx98}, + {"begin", "<iterator>", cxx11}, + {"distance", "<iterator>", cxx98}, + {"end", "<iterator>", cxx11}, + {"front_inserter", "<iterator>", cxx98}, + {"inserter", "<iterator>", cxx98}, + {"istream_iterator", "<iterator>", cxx98}, + {"istreambuf_iterator", "<iterator>", cxx98}, + {"iterator_traits", "<iterator>", cxx98}, + {"move_iterator", "<iterator>", cxx11}, + {"next", "<iterator>", cxx11}, + {"ostream_iterator", "<iterator>", cxx98}, + {"ostreambuf_iterator", "<iterator>", cxx98}, + {"prev", "<iterator>", cxx11}, + {"reverse_iterator", "<iterator>", cxx98}, + /* <ostream>. */ + {"ostream", "<ostream>", cxx98}, + /* <list>. */ + {"list", "<list>", cxx98}, + /* <map>. */ + {"map", "<map>", cxx98}, + {"multimap", "<map>", cxx98}, + /* <memory>. */ + {"allocate_shared", "<memory>", cxx11}, + {"allocator", "<memory>", cxx98}, + {"allocator_traits", "<memory>", cxx11}, + {"make_shared", "<memory>", cxx11}, + {"make_unique", "<memory>", cxx14}, + {"shared_ptr", "<memory>", cxx11}, + {"unique_ptr", "<memory>", cxx11}, + {"weak_ptr", "<memory>", cxx11}, + /* <memory_resource>. */ + {"pmr", "<memory_resource>", cxx17}, + /* <mutex>. */ + {"mutex", "<mutex>", cxx11}, + {"timed_mutex", "<mutex>", cxx11}, + {"recursive_mutex", "<mutex>", cxx11}, + {"recursive_timed_mutex", "<mutex>", cxx11}, + {"once_flag", "<mutex>", cxx11}, + {"call_once,", "<mutex>", cxx11}, + {"lock", "<mutex>", cxx11}, + {"scoped_lock", "<mutex>", cxx17}, + {"try_lock", "<mutex>", cxx11}, + {"lock_guard", "<mutex>", cxx11}, + {"unique_lock", "<mutex>", cxx11}, + /* <optional>. */ + {"optional", "<optional>", cxx17}, + {"make_optional", "<optional>", cxx17}, + /* <ostream>. */ + {"ostream", "<ostream>", cxx98}, + {"wostream", "<ostream>", cxx98}, + {"ends", "<ostream>", cxx98}, + {"flush", "<ostream>", cxx98}, + {"endl", "<ostream>", cxx98}, + /* <queue>. */ + {"queue", "<queue>", cxx98}, + {"priority_queue", "<queue>", cxx98}, + /* <set>. */ + {"set", "<set>", cxx98}, + {"multiset", "<set>", cxx98}, + /* <shared_mutex>. */ + {"shared_lock", "<shared_mutex>", cxx14}, + {"shared_mutex", "<shared_mutex>", cxx17}, + {"shared_timed_mutex", "<shared_mutex>", cxx14}, + /* <source_location>. */ + {"source_location", "<source_location>", cxx20}, + /* <sstream>. */ + {"basic_stringbuf", "<sstream>", cxx98}, + {"basic_istringstream", "<sstream>", cxx98}, + {"basic_ostringstream", "<sstream>", cxx98}, + {"basic_stringstream", "<sstream>", cxx98}, + {"istringstream", "<sstream>", cxx98}, + {"ostringstream", "<sstream>", cxx98}, + {"stringstream", "<sstream>", cxx98}, + /* <stack>. */ + {"stack", "<stack>", cxx98}, + /* <string>. */ + {"basic_string", "<string>", cxx98}, + {"string", "<string>", cxx98}, + {"wstring", "<string>", cxx98}, + {"u8string", "<string>", cxx20}, + {"u16string", "<string>", cxx11}, + {"u32string", "<string>", cxx11}, + /* <string_view>. */ + {"basic_string_view", "<string_view>", cxx17}, + {"string_view", "<string_view>", cxx17}, + /* <thread>. */ + {"thread", "<thread>", cxx11}, + {"this_thread", "<thread>", cxx11}, + /* <tuple>. */ + {"apply", "<tuple>", cxx17}, + {"forward_as_tuple", "<tuple>", cxx11}, + {"make_from_tuple", "<tuple>", cxx17}, + {"make_tuple", "<tuple>", cxx11}, + {"tie", "<tuple>", cxx11}, + {"tuple", "<tuple>", cxx11}, + {"tuple_cat", "<tuple>", cxx11}, + {"tuple_element", "<tuple>", cxx11}, + {"tuple_element_t", "<tuple>", cxx14}, + {"tuple_size", "<tuple>", cxx11}, + {"tuple_size_v", "<tuple>", cxx17}, + /* <type_traits>. */ + {"enable_if", "<type_traits>", cxx11}, + {"enable_if_t", "<type_traits>", cxx14}, + {"invoke_result", "<type_traits>", cxx17}, + {"invoke_result_t", "<type_traits>", cxx17}, + {"remove_cvref", "<type_traits>", cxx20}, + {"remove_cvref_t", "<type_traits>", cxx20}, + {"type_identity", "<type_traits>", cxx20}, + {"type_identity_t", "<type_traits>", cxx20}, + {"void_t", "<type_traits>", cxx17}, + {"conjunction", "<type_traits>", cxx17}, + {"conjunction_v", "<type_traits>", cxx17}, + {"disjunction", "<type_traits>", cxx17}, + {"disjunction_v", "<type_traits>", cxx17}, + {"negation", "<type_traits>", cxx17}, + {"negation_v", "<type_traits>", cxx17}, + /* <unordered_map>. */ + {"unordered_map", "<unordered_map>", cxx11}, + {"unordered_multimap", "<unordered_map>", cxx11}, + /* <unordered_set>. */ + {"unordered_set", "<unordered_set>", cxx11}, + {"unordered_multiset", "<unordered_set>", cxx11}, + /* <utility>. */ + {"declval", "<utility>", cxx11}, + {"forward", "<utility>", cxx11}, + {"make_pair", "<utility>", cxx98}, + {"move", "<utility>", cxx11}, + {"pair", "<utility>", cxx98}, + /* <variant>. */ + {"variant", "<variant>", cxx17}, + {"visit", "<variant>", cxx17}, + /* <vector>. */ + {"vector", "<vector>", cxx98}, + }; + const size_t num_hints = sizeof (hints) / sizeof (hints[0]); + for (size_t i = 0; i < num_hints; i++) + { + if (strcmp (name, hints[i].name) == 0) + return &hints[i]; + } + return NULL; +} + +/* Describe DIALECT. */ + +const char * +get_cxx_dialect_name (enum cxx_dialect dialect) +{ + switch (dialect) + { + default: + gcc_unreachable (); + case cxx98: + return "C++98"; + case cxx11: + return "C++11"; + case cxx14: + return "C++14"; + case cxx17: + return "C++17"; + case cxx20: + return "C++20"; + case cxx23: + return "C++23"; + } +} + +/* Subclass of deferred_diagnostic for use for names in the "std" namespace + that weren't recognized, but for which we know which header it ought to be + in. + + Emit a note either suggesting the header to be included, or noting that + the current dialect is too early for the given name. */ + +class missing_std_header : public deferred_diagnostic +{ + public: + missing_std_header (location_t loc, + const char *name_str, + const std_name_hint *header_hint) + : deferred_diagnostic (loc), + m_name_str (name_str), + m_header_hint (header_hint) + {} + ~missing_std_header () + { + gcc_rich_location richloc (get_location ()); + if (cxx_dialect >= m_header_hint->min_dialect) + { + const char *header = m_header_hint->header; + maybe_add_include_fixit (&richloc, header, true); + inform (&richloc, + "%<std::%s%> is defined in header %qs;" + " did you forget to %<#include %s%>?", + m_name_str, header, header); + } + else + inform (&richloc, + "%<std::%s%> is only available from %s onwards", + m_name_str, get_cxx_dialect_name (m_header_hint->min_dialect)); + } + +private: + const char *m_name_str; + const std_name_hint *m_header_hint; +}; + +/* Attempt to generate a name_hint that suggests pertinent header files + for NAME at LOCATION, for common names within the "std" namespace, + or an empty name_hint if this isn't applicable. */ + +static name_hint +maybe_suggest_missing_std_header (location_t location, tree name) +{ + gcc_assert (TREE_CODE (name) == IDENTIFIER_NODE); + + const char *name_str = IDENTIFIER_POINTER (name); + const std_name_hint *header_hint = get_std_name_hint (name_str); + if (!header_hint) + return name_hint (); + + return name_hint (NULL, new missing_std_header (location, name_str, + header_hint)); +} + +/* Attempt to generate a name_hint that suggests a missing header file + for NAME within SCOPE at LOCATION, or an empty name_hint if this isn't + applicable. */ + +static name_hint +maybe_suggest_missing_header (location_t location, tree name, tree scope) +{ + if (scope == NULL_TREE) + return name_hint (); + if (TREE_CODE (scope) != NAMESPACE_DECL) + return name_hint (); + /* We only offer suggestions for the "std" namespace. */ + if (scope != std_node) + return name_hint (); + return maybe_suggest_missing_std_header (location, name); +} + +/* Generate a name_hint at LOCATION for NAME, an IDENTIFIER_NODE for which name + lookup failed within the explicitly provided SCOPE. + + Suggest the best meaningful candidates (if any), otherwise + an empty name_hint is returned. */ + +name_hint +suggest_alternative_in_explicit_scope (location_t location, tree name, + tree scope) +{ + /* Something went very wrong; don't suggest anything. */ + if (name == error_mark_node) + return name_hint (); + + /* Resolve any namespace aliases. */ + scope = ORIGINAL_NAMESPACE (scope); + + name_hint hint = maybe_suggest_missing_header (location, name, scope); + if (hint) + return hint; + + cp_binding_level *level = NAMESPACE_LEVEL (scope); + + best_match <tree, const char *> bm (name); + consider_binding_level (name, bm, level, false, FUZZY_LOOKUP_NAME); + + /* See if we have a good suggesion for the user. */ + const char *fuzzy_name = bm.get_best_meaningful_candidate (); + if (fuzzy_name) + return name_hint (fuzzy_name, NULL); + + return name_hint (); +} + +/* Given NAME, look within SCOPED_ENUM for possible spell-correction + candidates. */ + +name_hint +suggest_alternative_in_scoped_enum (tree name, tree scoped_enum) +{ + gcc_assert (SCOPED_ENUM_P (scoped_enum)); + + best_match <tree, const char *> bm (name); + for (tree iter = TYPE_VALUES (scoped_enum); iter; iter = TREE_CHAIN (iter)) + { + tree id = TREE_PURPOSE (iter); + bm.consider (IDENTIFIER_POINTER (id)); + } + return name_hint (bm.get_best_meaningful_candidate (), NULL); +} + +/* Look up NAME (an IDENTIFIER_NODE) in SCOPE (either a NAMESPACE_DECL + or a class TYPE). + + WANT as for lookup_name_1. + + Returns a DECL (or OVERLOAD, or BASELINK) representing the + declaration found. If no suitable declaration can be found, + ERROR_MARK_NODE is returned. If COMPLAIN is true and SCOPE is + neither a class-type nor a namespace a diagnostic is issued. */ + +tree +lookup_qualified_name (tree scope, tree name, LOOK_want want, bool complain) +{ + tree t = NULL_TREE; + + if (TREE_CODE (scope) == NAMESPACE_DECL) + { + name_lookup lookup (name, want); + + if (qualified_namespace_lookup (scope, &lookup)) + { + t = lookup.value; + + /* If we have a known type overload, pull it out. This can happen + for using decls. */ + if (TREE_CODE (t) == OVERLOAD && TREE_TYPE (t) != unknown_type_node) + t = OVL_FUNCTION (t); + } + } + else if (cxx_dialect != cxx98 && TREE_CODE (scope) == ENUMERAL_TYPE) + t = lookup_enumerator (scope, name); + else if (is_class_type (scope, complain)) + t = lookup_member (scope, name, 2, bool (want & LOOK_want::TYPE), + tf_warning_or_error); + + if (!t) + return error_mark_node; + return t; +} + +/* Wrapper for the above that takes a string argument. The function name is + not at the beginning of the line to keep this wrapper out of etags. */ + +tree lookup_qualified_name (tree t, const char *p, LOOK_want w, bool c) +{ + return lookup_qualified_name (t, get_identifier (p), w, c); +} + +/* [namespace.qual] + Accepts the NAME to lookup and its qualifying SCOPE. + Returns the name/type pair found into the cxx_binding *RESULT, + or false on error. */ + +static bool +qualified_namespace_lookup (tree scope, name_lookup *lookup) +{ + timevar_start (TV_NAME_LOOKUP); + query_oracle (lookup->name); + bool found = lookup->search_qualified (ORIGINAL_NAMESPACE (scope)); + timevar_stop (TV_NAME_LOOKUP); + return found; +} + +/* If DECL is suitably visible to the user, consider its name for + spelling correction. */ + +static void +consider_decl (tree decl, best_match <tree, const char *> &bm, + bool consider_impl_names) +{ + /* Skip compiler-generated variables (e.g. __for_begin/__for_end + within range for). */ + if (TREE_CODE (decl) == VAR_DECL && DECL_ARTIFICIAL (decl)) + return; + + tree suggestion = DECL_NAME (decl); + if (!suggestion) + return; + + /* Don't suggest names that are for anonymous aggregate types, as + they are an implementation detail generated by the compiler. */ + if (IDENTIFIER_ANON_P (suggestion)) + return; + + const char *suggestion_str = IDENTIFIER_POINTER (suggestion); + + /* Ignore internal names with spaces in them. */ + if (strchr (suggestion_str, ' ')) + return; + + /* Don't suggest names that are reserved for use by the + implementation, unless NAME began with an underscore. */ + if (!consider_impl_names + && name_reserved_for_implementation_p (suggestion_str)) + return; + + bm.consider (suggestion_str); +} + +/* If DECL is suitably visible to the user, add its name to VEC and + return true. Otherwise return false. */ + +static bool +maybe_add_fuzzy_decl (auto_vec<tree> &vec, tree decl) +{ + /* Skip compiler-generated variables (e.g. __for_begin/__for_end + within range for). */ + if (TREE_CODE (decl) == VAR_DECL && DECL_ARTIFICIAL (decl)) + return false; + + tree suggestion = DECL_NAME (decl); + if (!suggestion) + return false; + + /* Don't suggest names that are for anonymous aggregate types, as + they are an implementation detail generated by the compiler. */ + if (IDENTIFIER_ANON_P (suggestion)) + return false; + + vec.safe_push (suggestion); + + return true; +} + +/* Examing the namespace binding BINDING, and add at most one instance + of the name, if it contains a visible entity of interest. Return + true if we added something. */ + +bool +maybe_add_fuzzy_binding (auto_vec<tree> &vec, tree binding, + lookup_name_fuzzy_kind kind) +{ + tree value = NULL_TREE; + + if (STAT_HACK_P (binding)) + { + if (!STAT_TYPE_HIDDEN_P (binding) + && STAT_TYPE (binding)) + { + if (maybe_add_fuzzy_decl (vec, STAT_TYPE (binding))) + return true; + } + else if (!STAT_DECL_HIDDEN_P (binding)) + value = STAT_DECL (binding); + } + else + value = binding; + + value = ovl_skip_hidden (value); + if (value) + { + value = OVL_FIRST (value); + if (kind != FUZZY_LOOKUP_TYPENAME + || TREE_CODE (STRIP_TEMPLATE (value)) == TYPE_DECL) + if (maybe_add_fuzzy_decl (vec, value)) + return true; + } + + /* Nothing found. */ + return false; +} + +/* Helper function for lookup_name_fuzzy. + Traverse binding level LVL, looking for good name matches for NAME + (and BM). */ +static void +consider_binding_level (tree name, best_match <tree, const char *> &bm, + cp_binding_level *lvl, bool look_within_fields, + enum lookup_name_fuzzy_kind kind) +{ + if (look_within_fields) + if (lvl->this_entity && TREE_CODE (lvl->this_entity) == RECORD_TYPE) + { + tree type = lvl->this_entity; + bool want_type_p = (kind == FUZZY_LOOKUP_TYPENAME); + tree best_matching_field + = lookup_member_fuzzy (type, name, want_type_p); + if (best_matching_field) + bm.consider (IDENTIFIER_POINTER (best_matching_field)); + } + + /* Only suggest names reserved for the implementation if NAME begins + with an underscore. */ + bool consider_implementation_names = (IDENTIFIER_POINTER (name)[0] == '_'); + + if (lvl->kind != sk_namespace) + for (tree t = lvl->names; t; t = TREE_CHAIN (t)) + { + tree d = t; + + /* OVERLOADs or decls from using declaration are wrapped into + TREE_LIST. */ + if (TREE_CODE (d) == TREE_LIST) + d = OVL_FIRST (TREE_VALUE (d)); + + /* Don't use bindings from implicitly declared functions, + as they were likely misspellings themselves. */ + if (TREE_TYPE (d) == error_mark_node) + continue; + + /* If we want a typename, ignore non-types. */ + if (kind == FUZZY_LOOKUP_TYPENAME + && TREE_CODE (STRIP_TEMPLATE (d)) != TYPE_DECL) + continue; + + consider_decl (d, bm, consider_implementation_names); + } + else + { + /* We need to iterate over the namespace hash table, in order to + not mention hidden entities. But hash table iteration is + (essentially) unpredictable, our correction-distance measure + is very granular, and we pick the first of equal distances. + Hence, we need to call the distance-measurer in a predictable + order. So, iterate over the namespace hash, inserting + visible names into a vector. Then sort the vector. Then + determine spelling distance. */ + + tree ns = lvl->this_entity; + auto_vec<tree> vec; + + hash_table<named_decl_hash>::iterator end + (DECL_NAMESPACE_BINDINGS (ns)->end ()); + for (hash_table<named_decl_hash>::iterator iter + (DECL_NAMESPACE_BINDINGS (ns)->begin ()); iter != end; ++iter) + { + tree binding = *iter; + + if (TREE_CODE (binding) == BINDING_VECTOR) + { + bitmap imports = get_import_bitmap (); + binding_cluster *cluster = BINDING_VECTOR_CLUSTER_BASE (binding); + + if (tree bind = cluster->slots[BINDING_SLOT_CURRENT]) + if (maybe_add_fuzzy_binding (vec, bind, kind)) + continue; + + /* Scan the imported bindings. */ + unsigned ix = BINDING_VECTOR_NUM_CLUSTERS (binding); + if (BINDING_VECTOR_SLOTS_PER_CLUSTER == BINDING_SLOTS_FIXED) + { + ix--; + cluster++; + } + + for (; ix--; cluster++) + for (unsigned jx = 0; jx != BINDING_VECTOR_SLOTS_PER_CLUSTER; + jx++) + { + /* Are we importing this module? */ + if (unsigned base = cluster->indices[jx].base) + if (unsigned span = cluster->indices[jx].span) + do + if (bitmap_bit_p (imports, base)) + goto found; + while (++base, --span); + continue; + + found:; + /* Is it loaded? */ + if (cluster->slots[jx].is_lazy ()) + /* Let's not read in everything on the first + spello! **/ + continue; + if (tree bind = cluster->slots[jx]) + if (maybe_add_fuzzy_binding (vec, bind, kind)) + break; + } + } + else + maybe_add_fuzzy_binding (vec, binding, kind); + } + + vec.qsort ([] (const void *a_, const void *b_) + { + return strcmp (IDENTIFIER_POINTER (*(const tree *)a_), + IDENTIFIER_POINTER (*(const tree *)b_)); + }); + + /* Examine longest to shortest. */ + for (unsigned ix = vec.length (); ix--;) + { + const char *str = IDENTIFIER_POINTER (vec[ix]); + + /* Ignore internal names with spaces in them. */ + if (strchr (str, ' ')) + continue; + + /* Don't suggest names that are reserved for use by the + implementation, unless NAME began with an underscore. */ + if (!consider_implementation_names + && name_reserved_for_implementation_p (str)) + continue; + + bm.consider (str); + } + } +} + +/* Subclass of deferred_diagnostic. Notify the user that the + given macro was used before it was defined. + This can be done in the C++ frontend since tokenization happens + upfront. */ + +class macro_use_before_def : public deferred_diagnostic +{ + public: + /* Factory function. Return a new macro_use_before_def instance if + appropriate, or return NULL. */ + static macro_use_before_def * + maybe_make (location_t use_loc, cpp_hashnode *macro) + { + location_t def_loc = cpp_macro_definition_location (macro); + if (def_loc == UNKNOWN_LOCATION) + return NULL; + + /* We only want to issue a note if the macro was used *before* it was + defined. + We don't want to issue a note for cases where a macro was incorrectly + used, leaving it unexpanded (e.g. by using the wrong argument + count). */ + if (!linemap_location_before_p (line_table, use_loc, def_loc)) + return NULL; + + return new macro_use_before_def (use_loc, macro); + } + + private: + /* Ctor. LOC is the location of the usage. MACRO is the + macro that was used. */ + macro_use_before_def (location_t loc, cpp_hashnode *macro) + : deferred_diagnostic (loc), m_macro (macro) + { + gcc_assert (macro); + } + + ~macro_use_before_def () + { + if (is_suppressed_p ()) + return; + + inform (get_location (), "the macro %qs had not yet been defined", + (const char *)m_macro->ident.str); + inform (cpp_macro_definition_location (m_macro), + "it was later defined here"); + } + + private: + cpp_hashnode *m_macro; +}; + +/* Determine if it can ever make sense to offer RID as a suggestion for + a misspelling. + + Subroutine of lookup_name_fuzzy. */ + +static bool +suggest_rid_p (enum rid rid) +{ + switch (rid) + { + /* Support suggesting function-like keywords. */ + case RID_STATIC_ASSERT: + return true; + + default: + /* Support suggesting the various decl-specifier words, to handle + e.g. "singed" vs "signed" typos. */ + if (cp_keyword_starts_decl_specifier_p (rid)) + return true; + + /* Otherwise, don't offer it. This avoids suggesting e.g. "if" + and "do" for short misspellings, which are likely to lead to + nonsensical results. */ + return false; + } +} + +/* Search for near-matches for NAME within the current bindings, and within + macro names, returning the best match as a const char *, or NULL if + no reasonable match is found. + + Use LOC for any deferred diagnostics. */ + +name_hint +lookup_name_fuzzy (tree name, enum lookup_name_fuzzy_kind kind, location_t loc) +{ + gcc_assert (TREE_CODE (name) == IDENTIFIER_NODE); + + /* First, try some well-known names in the C++ standard library, in case + the user forgot a #include. */ + const char *header_hint + = get_cp_stdlib_header_for_name (IDENTIFIER_POINTER (name)); + if (header_hint) + return name_hint (NULL, + new suggest_missing_header (loc, + IDENTIFIER_POINTER (name), + header_hint)); + + best_match <tree, const char *> bm (name); + + cp_binding_level *lvl; + for (lvl = scope_chain->class_bindings; lvl; lvl = lvl->level_chain) + consider_binding_level (name, bm, lvl, true, kind); + + for (lvl = current_binding_level; lvl; lvl = lvl->level_chain) + consider_binding_level (name, bm, lvl, false, kind); + + /* Consider macros: if the user misspelled a macro name e.g. "SOME_MACRO" + as: + x = SOME_OTHER_MACRO (y); + then "SOME_OTHER_MACRO" will survive to the frontend and show up + as a misspelled identifier. + + Use the best distance so far so that a candidate is only set if + a macro is better than anything so far. This allows early rejection + (without calculating the edit distance) of macro names that must have + distance >= bm.get_best_distance (), and means that we only get a + non-NULL result for best_macro_match if it's better than any of + the identifiers already checked. */ + best_macro_match bmm (name, bm.get_best_distance (), parse_in); + cpp_hashnode *best_macro = bmm.get_best_meaningful_candidate (); + /* If a macro is the closest so far to NAME, consider it. */ + if (best_macro) + bm.consider ((const char *)best_macro->ident.str); + else if (bmm.get_best_distance () == 0) + { + /* If we have an exact match for a macro name, then either the + macro was used with the wrong argument count, or the macro + has been used before it was defined. */ + if (cpp_hashnode *macro = bmm.blithely_get_best_candidate ()) + if (cpp_user_macro_p (macro)) + return name_hint (NULL, + macro_use_before_def::maybe_make (loc, macro)); + } + + /* Try the "starts_decl_specifier_p" keywords to detect + "singed" vs "signed" typos. */ + for (unsigned i = 0; i < num_c_common_reswords; i++) + { + const c_common_resword *resword = &c_common_reswords[i]; + + if (!suggest_rid_p (resword->rid)) + continue; + + tree resword_identifier = ridpointers [resword->rid]; + if (!resword_identifier) + continue; + gcc_assert (TREE_CODE (resword_identifier) == IDENTIFIER_NODE); + + /* Only consider reserved words that survived the + filtering in init_reswords (e.g. for -std). */ + if (!IDENTIFIER_KEYWORD_P (resword_identifier)) + continue; + + bm.consider (IDENTIFIER_POINTER (resword_identifier)); + } + + return name_hint (bm.get_best_meaningful_candidate (), NULL); +} + +/* Subroutine of outer_binding. + + Returns TRUE if BINDING is a binding to a template parameter of + SCOPE. In that case SCOPE is the scope of a primary template + parameter -- in the sense of G++, i.e, a template that has its own + template header. + + Returns FALSE otherwise. */ + +static bool +binding_to_template_parms_of_scope_p (cxx_binding *binding, + cp_binding_level *scope) +{ + tree binding_value, tmpl, tinfo; + int level; + + if (!binding || !scope || !scope->this_entity) + return false; + + binding_value = binding->value ? binding->value : binding->type; + tinfo = get_template_info (scope->this_entity); + + /* BINDING_VALUE must be a template parm. */ + if (binding_value == NULL_TREE + || (!DECL_P (binding_value) + || !DECL_TEMPLATE_PARM_P (binding_value))) + return false; + + /* The level of BINDING_VALUE. */ + level = + template_type_parameter_p (binding_value) + ? TEMPLATE_PARM_LEVEL (TEMPLATE_TYPE_PARM_INDEX + (TREE_TYPE (binding_value))) + : TEMPLATE_PARM_LEVEL (DECL_INITIAL (binding_value)); + + /* The template of the current scope, iff said scope is a primary + template. */ + tmpl = (tinfo + && PRIMARY_TEMPLATE_P (TI_TEMPLATE (tinfo)) + ? TI_TEMPLATE (tinfo) + : NULL_TREE); + + /* If the level of the parm BINDING_VALUE equals the depth of TMPL, + then BINDING_VALUE is a parameter of TMPL. */ + return (tmpl && level == TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (tmpl))); +} + +/* Return the innermost non-namespace binding for NAME from a scope + containing BINDING, or, if BINDING is NULL, the current scope. + Please note that for a given template, the template parameters are + considered to be in the scope containing the current scope. + If CLASS_P is false, then class bindings are ignored. */ + +cxx_binding * +outer_binding (tree name, + cxx_binding *binding, + bool class_p) +{ + cxx_binding *outer; + cp_binding_level *scope; + cp_binding_level *outer_scope; + + if (binding) + { + scope = binding->scope->level_chain; + outer = binding->previous; + } + else + { + scope = current_binding_level; + outer = IDENTIFIER_BINDING (name); + } + outer_scope = outer ? outer->scope : NULL; + + /* Because we create class bindings lazily, we might be missing a + class binding for NAME. If there are any class binding levels + between the LAST_BINDING_LEVEL and the scope in which OUTER was + declared, we must lookup NAME in those class scopes. */ + if (class_p) + while (scope && scope != outer_scope && scope->kind != sk_namespace) + { + if (scope->kind == sk_class) + { + cxx_binding *class_binding; + + class_binding = get_class_binding (name, scope); + if (class_binding) + { + /* Thread this new class-scope binding onto the + IDENTIFIER_BINDING list so that future lookups + find it quickly. */ + class_binding->previous = outer; + if (binding) + binding->previous = class_binding; + else + IDENTIFIER_BINDING (name) = class_binding; + return class_binding; + } + } + /* If we are in a member template, the template parms of the member + template are considered to be inside the scope of the containing + class, but within G++ the class bindings are all pushed between the + template parms and the function body. So if the outer binding is + a template parm for the current scope, return it now rather than + look for a class binding. */ + if (outer_scope && outer_scope->kind == sk_template_parms + && binding_to_template_parms_of_scope_p (outer, scope)) + return outer; + + scope = scope->level_chain; + } + + return outer; +} + +/* Return the innermost block-scope or class-scope value binding for + NAME, or NULL_TREE if there is no such binding. */ + +tree +innermost_non_namespace_value (tree name) +{ + cxx_binding *binding; + binding = outer_binding (name, /*binding=*/NULL, /*class_p=*/true); + return binding ? binding->value : NULL_TREE; +} + +/* Look up NAME in the current binding level and its superiors in the + namespace of variables, functions and typedefs. Return a ..._DECL + node of some kind representing its definition if there is only one + such declaration, or return a TREE_LIST with all the overloaded + definitions if there are many, or return NULL_TREE if it is undefined. + Hidden name, either friend declaration or built-in function, are + not ignored. + + WHERE controls which scopes are considered. It is a bit mask of + LOOK_where::BLOCK (look in block scope), LOOK_where::CLASS + (look in class scopes) & LOOK_where::NAMESPACE (look in namespace + scopes). It is an error for no bits to be set. These scopes are + searched from innermost to outermost. + + WANT controls what kind of entity we'd happy with. + LOOK_want::NORMAL for normal lookup (implicit typedefs can be + hidden). LOOK_want::TYPE for only TYPE_DECLS, LOOK_want::NAMESPACE + for only NAMESPACE_DECLS. These two can be bit-ored to find + namespace or type. + + WANT can also have LOOK_want::HIDDEN_FRIEND or + LOOK_want::HIDDEN_LAMBDa added to it. */ + +tree +lookup_name (tree name, LOOK_where where, LOOK_want want) +{ + tree val = NULL_TREE; + + auto_cond_timevar tv (TV_NAME_LOOKUP); + + gcc_checking_assert (unsigned (where) != 0); + /* If we're looking for hidden lambda things, we shouldn't be + looking in namespace scope. */ + gcc_checking_assert (!bool (want & LOOK_want::HIDDEN_LAMBDA) + || !bool (where & LOOK_where::NAMESPACE)); + query_oracle (name); + + /* Conversion operators are handled specially because ordinary + unqualified name lookup will not find template conversion + operators. */ + if (IDENTIFIER_CONV_OP_P (name)) + { + cp_binding_level *level; + + for (level = current_binding_level; + level && level->kind != sk_namespace; + level = level->level_chain) + { + tree class_type; + tree operators; + + /* A conversion operator can only be declared in a class + scope. */ + if (level->kind != sk_class) + continue; + + /* Lookup the conversion operator in the class. */ + class_type = level->this_entity; + operators = lookup_fnfields (class_type, name, /*protect=*/0, + tf_warning_or_error); + if (operators) + return operators; + } + + return NULL_TREE; + } + + /* First, look in non-namespace scopes. */ + + if (current_class_type == NULL_TREE) + /* Maybe avoid searching the binding stack at all. */ + where = LOOK_where (unsigned (where) & ~unsigned (LOOK_where::CLASS)); + + if (bool (where & (LOOK_where::BLOCK | LOOK_where::CLASS))) + for (cxx_binding *iter = nullptr; + (iter = outer_binding (name, iter, bool (where & LOOK_where::CLASS)));) + { + /* Skip entities we don't want. */ + if (!bool (where & (LOCAL_BINDING_P (iter) + ? LOOK_where::BLOCK : LOOK_where::CLASS))) + continue; + + /* If this is the kind of thing we're looking for, we're done. */ + if (iter->value) + { + tree binding = NULL_TREE; + + if (!(!iter->type && HIDDEN_TYPE_BINDING_P (iter)) + && (bool (want & LOOK_want::HIDDEN_LAMBDA) + || !is_lambda_ignored_entity (iter->value)) + && qualify_lookup (iter->value, want)) + binding = iter->value; + else if (bool (want & LOOK_want::TYPE) + && !HIDDEN_TYPE_BINDING_P (iter) + && iter->type) + binding = iter->type; + + if (binding) + { + val = binding; + break; + } + } + } + + /* Now lookup in namespace scopes. */ + if (!val && bool (where & LOOK_where::NAMESPACE)) + { + name_lookup lookup (name, want); + if (lookup.search_unqualified + (current_decl_namespace (), current_binding_level)) + val = lookup.value; + } + + /* If we have a known type overload, pull it out. This can happen + for both using decls and unhidden functions. */ + if (val && TREE_CODE (val) == OVERLOAD && TREE_TYPE (val) != unknown_type_node) + val = OVL_FUNCTION (val); + + return val; +} + +tree +lookup_name (tree name) +{ + return lookup_name (name, LOOK_where::ALL, LOOK_want::NORMAL); +} + +/* Look up NAME for type used in elaborated name specifier in + the scopes given by HOW. + + Unlike lookup_name_1, we make sure that NAME is actually + declared in the desired scope, not from inheritance, nor using + directive. For using declaration, there is DR138 still waiting + to be resolved. Hidden name coming from an earlier friend + declaration is also returned, and will be made visible unless HOW + is TAG_how::HIDDEN_FRIEND. + + A TYPE_DECL best matching the NAME is returned. Catching error + and issuing diagnostics are caller's responsibility. */ + +tree +lookup_elaborated_type (tree name, TAG_how how) +{ + auto_cond_timevar tv (TV_NAME_LOOKUP); + + cp_binding_level *b = current_binding_level; + + if (b->kind != sk_namespace) + /* Look in non-namespace scopes. */ + for (cxx_binding *iter = NULL; + (iter = outer_binding (name, iter, /*class_p=*/ true)); ) + { + /* First check we're supposed to be looking in this scope -- + if we're not, we're done. */ + for (; b != iter->scope; b = b->level_chain) + if (!(b->kind == sk_cleanup + || b->kind == sk_template_parms + || b->kind == sk_function_parms + || (b->kind == sk_class && how != TAG_how::CURRENT_ONLY))) + return NULL_TREE; + + /* Check if this is the kind of thing we're looking for. If + HOW is TAG_how::CURRENT_ONLY, also make sure it doesn't + come from base class. For ITER->VALUE, we can simply use + INHERITED_VALUE_BINDING_P. For ITER->TYPE, we have to use + our own check. + + We check ITER->TYPE before ITER->VALUE in order to handle + typedef struct C {} C; + correctly. */ + + if (tree type = iter->type) + { + if (qualify_lookup (type, LOOK_want::TYPE) + && (how != TAG_how::CURRENT_ONLY + || LOCAL_BINDING_P (iter) + || DECL_CONTEXT (type) == iter->scope->this_entity)) + { + if (how != TAG_how::HIDDEN_FRIEND) + /* It is no longer a hidden binding. */ + HIDDEN_TYPE_BINDING_P (iter) = false; + + return type; + } + } + else + { + if (qualify_lookup (iter->value, LOOK_want::TYPE) + && (how != TAG_how::CURRENT_ONLY + || !INHERITED_VALUE_BINDING_P (iter))) + { + if (how != TAG_how::HIDDEN_FRIEND && !iter->type) + /* It is no longer a hidden binding. */ + HIDDEN_TYPE_BINDING_P (iter) = false; + + return iter->value; + } + } + } + + /* Now check if we can look in namespace scope. */ + for (; b->kind != sk_namespace; b = b->level_chain) + if (!(b->kind == sk_cleanup + || b->kind == sk_template_parms + || b->kind == sk_function_parms + || (b->kind == sk_class && how != TAG_how::CURRENT_ONLY))) + return NULL_TREE; + + /* Look in the innermost namespace. */ + tree ns = b->this_entity; + if (tree *slot = find_namespace_slot (ns, name)) + { + tree bind = *slot; + if (TREE_CODE (bind) == BINDING_VECTOR) + bind = BINDING_VECTOR_CLUSTER (bind, 0).slots[BINDING_SLOT_CURRENT]; + + if (bind) + { + /* If this is the kind of thing we're looking for, we're done. */ + if (tree type = MAYBE_STAT_TYPE (bind)) + { + if (how != TAG_how::HIDDEN_FRIEND) + /* No longer hidden. */ + STAT_TYPE_HIDDEN_P (*slot) = false; + + return type; + } + else if (tree decl = MAYBE_STAT_DECL (bind)) + { + if (qualify_lookup (decl, LOOK_want::TYPE)) + { + if (how != TAG_how::HIDDEN_FRIEND && STAT_HACK_P (bind) + && STAT_DECL_HIDDEN_P (bind)) + { + if (STAT_TYPE (bind)) + STAT_DECL_HIDDEN_P (bind) = false; + else + { + /* There is no type, just remove the stat + hack. */ + if (*slot == bind) + *slot = decl; + else + BINDING_VECTOR_CLUSTER (*slot, 0) + .slots[BINDING_SLOT_CURRENT] = decl; + } + } + return decl; + } + } + } + + if (TREE_CODE (*slot) == BINDING_VECTOR) + { + /* We could be redeclaring a global module entity, (from GMF + or header unit), or from another partition, or + specializing an imported template. */ + bitmap imports = get_import_bitmap (); + binding_cluster *cluster = BINDING_VECTOR_CLUSTER_BASE (*slot); + + /* Scan the imported bindings. */ + unsigned ix = BINDING_VECTOR_NUM_CLUSTERS (*slot); + if (BINDING_VECTOR_SLOTS_PER_CLUSTER == BINDING_SLOTS_FIXED) + { + ix--; + cluster++; + } + + /* Do this in forward order, so we load modules in an order + the user expects. */ + for (; ix--; cluster++) + for (unsigned jx = 0; jx != BINDING_VECTOR_SLOTS_PER_CLUSTER; jx++) + { + /* Are we importing this module? */ + if (unsigned base = cluster->indices[jx].base) + if (unsigned span = cluster->indices[jx].span) + do + if (bitmap_bit_p (imports, base)) + goto found; + while (++base, --span); + continue; + + found:; + /* Is it loaded? */ + if (cluster->slots[jx].is_lazy ()) + { + gcc_assert (cluster->indices[jx].span == 1); + lazy_load_binding (cluster->indices[jx].base, + ns, name, &cluster->slots[jx]); + } + tree bind = cluster->slots[jx]; + if (!bind) + /* Load errors could mean there's nothing here. */ + continue; + + /* Extract what we can see from here. If there's no + stat_hack, then everything was exported. */ + tree type = NULL_TREE; + + /* If no stat hack, everything is visible. */ + if (STAT_HACK_P (bind)) + { + if (STAT_TYPE_VISIBLE_P (bind)) + type = STAT_TYPE (bind); + bind = STAT_VISIBLE (bind); + } + + if (type && qualify_lookup (type, LOOK_want::TYPE)) + return type; + + if (bind && qualify_lookup (bind, LOOK_want::TYPE)) + return bind; + } + + if (!module_purview_p ()) + { + /* We're in the global module, perhaps there's a tag + there? */ + // FIXME: This isn't quite right, if we find something + // here, from the language PoV we're not supposed to + // know it? + } + } + } + + return NULL_TREE; +} + +/* The type TYPE is being declared. If it is a class template, or a + specialization of a class template, do any processing required and + perform error-checking. If IS_FRIEND is nonzero, this TYPE is + being declared a friend. B is the binding level at which this TYPE + should be bound. + + Returns the TYPE_DECL for TYPE, which may have been altered by this + processing. */ + +static tree +maybe_process_template_type_declaration (tree type, int is_friend, + cp_binding_level *b) +{ + tree decl = TYPE_NAME (type); + + if (processing_template_parmlist) + /* You can't declare a new template type in a template parameter + list. But, you can declare a non-template type: + + template <class A*> struct S; + + is a forward-declaration of `A'. */ + ; + else if (b->kind == sk_namespace + && current_binding_level->kind != sk_namespace) + /* If this new type is being injected into a containing scope, + then it's not a template type. */ + ; + else + { + gcc_assert (MAYBE_CLASS_TYPE_P (type) + || TREE_CODE (type) == ENUMERAL_TYPE); + + if (processing_template_decl) + { + decl = push_template_decl (decl, is_friend); + if (decl == error_mark_node) + return error_mark_node; + + /* If the current binding level is the binding level for the + template parameters (see the comment in + begin_template_parm_list) and the enclosing level is a class + scope, and we're not looking at a friend, push the + declaration of the member class into the class scope. In the + friend case, push_template_decl will already have put the + friend into global scope, if appropriate. */ + if (TREE_CODE (type) != ENUMERAL_TYPE + && !is_friend && b->kind == sk_template_parms + && b->level_chain->kind == sk_class) + { + finish_member_declaration (CLASSTYPE_TI_TEMPLATE (type)); + + if (!COMPLETE_TYPE_P (current_class_type)) + maybe_add_class_template_decl_list (current_class_type, + type, /*friend_p=*/0); + } + } + } + + return decl; +} + +/* Push a tag name NAME for struct/class/union/enum type TYPE. In case + that the NAME is a class template, the tag is processed but not pushed. + + The pushed scope depend on the SCOPE parameter: + - When SCOPE is TS_CURRENT, put it into the inner-most non-sk_cleanup + scope. + - When SCOPE is TS_GLOBAL, put it in the inner-most non-class and + non-template-parameter scope. This case is needed for forward + declarations. + - When SCOPE is TS_WITHIN_ENCLOSING_NON_CLASS, this is similar to + TS_GLOBAL case except that names within template-parameter scopes + are not pushed at all. + + Returns TYPE upon success and ERROR_MARK_NODE otherwise. */ + +tree +pushtag (tree name, tree type, TAG_how how) +{ + tree decl; + + gcc_assert (identifier_p (name)); + + auto_cond_timevar tv (TV_NAME_LOOKUP); + + cp_binding_level *b = current_binding_level; + while (true) + { + if (/* Cleanup scopes are not scopes from the point of view of + the language. */ + b->kind == sk_cleanup + /* Neither are function parameter scopes. */ + || b->kind == sk_function_parms + /* Neither are the scopes used to hold template parameters + for an explicit specialization. For an ordinary template + declaration, these scopes are not scopes from the point of + view of the language. */ + || (b->kind == sk_template_parms + && (b->explicit_spec_p || how == TAG_how::GLOBAL))) + b = b->level_chain; + else if (b->kind == sk_class && how != TAG_how::CURRENT_ONLY) + { + b = b->level_chain; + if (b->kind == sk_template_parms) + b = b->level_chain; + } + else + break; + } + + /* Do C++ gratuitous typedefing. */ + if (REAL_IDENTIFIER_TYPE_VALUE (name) != type) + { + tree tdef; + tree context = TYPE_CONTEXT (type); + + if (! context) + { + cp_binding_level *cb = b; + while (cb->kind != sk_namespace + && cb->kind != sk_class + && (cb->kind != sk_function_parms + || !cb->this_entity)) + cb = cb->level_chain; + tree cs = cb->this_entity; + + gcc_checking_assert (TREE_CODE (cs) == FUNCTION_DECL + ? cs == current_function_decl + : TYPE_P (cs) ? cs == current_class_type + : cs == current_namespace); + + if (how == TAG_how::CURRENT_ONLY + || (cs && TREE_CODE (cs) == FUNCTION_DECL)) + context = cs; + else if (cs && TYPE_P (cs)) + /* When declaring a friend class of a local class, we want + to inject the newly named class into the scope + containing the local class, not the namespace + scope. */ + context = decl_function_context (get_type_decl (cs)); + } + if (!context) + context = current_namespace; + + tdef = create_implicit_typedef (name, type); + DECL_CONTEXT (tdef) = FROB_CONTEXT (context); + set_originating_module (tdef); + + decl = maybe_process_template_type_declaration + (type, how == TAG_how::HIDDEN_FRIEND, b); + if (decl == error_mark_node) + return decl; + + if (b->kind == sk_class) + { + if (!TYPE_BEING_DEFINED (current_class_type)) + /* Don't push anywhere if the class is complete; a lambda in an + NSDMI is not a member of the class. */ + ; + else if (!PROCESSING_REAL_TEMPLATE_DECL_P ()) + /* Put this TYPE_DECL on the TYPE_FIELDS list for the + class. But if it's a member template class, we want + the TEMPLATE_DECL, not the TYPE_DECL, so this is done + later. */ + finish_member_declaration (decl); + else + pushdecl_class_level (decl); + } + else if (b->kind == sk_template_parms) + { + /* Do not push the tag here -- we'll want to push the + TEMPLATE_DECL. */ + if (b->level_chain->kind != sk_class) + set_identifier_type_value_with_scope (name, tdef, b->level_chain); + } + else + { + decl = do_pushdecl_with_scope + (decl, b, /*hiding=*/(how == TAG_how::HIDDEN_FRIEND)); + if (decl == error_mark_node) + return decl; + + if (DECL_CONTEXT (decl) == std_node + && init_list_identifier == DECL_NAME (TYPE_NAME (type)) + && !CLASSTYPE_TEMPLATE_INFO (type)) + { + error ("declaration of %<std::initializer_list%> does not match " + "%<#include <initializer_list>%>, isn%'t a template"); + return error_mark_node; + } + } + + TYPE_CONTEXT (type) = DECL_CONTEXT (decl); + + /* If this is a local class, keep track of it. We need this + information for name-mangling, and so that it is possible to + find all function definitions in a translation unit in a + convenient way. (It's otherwise tricky to find a member + function definition it's only pointed to from within a local + class.) */ + if (TYPE_FUNCTION_SCOPE_P (type)) + { + if (processing_template_decl) + { + /* Push a DECL_EXPR so we call pushtag at the right time in + template instantiation rather than in some nested context. */ + add_decl_expr (decl); + } + /* Lambdas use LAMBDA_EXPR_DISCRIMINATOR instead. */ + else if (!LAMBDA_TYPE_P (type)) + determine_local_discriminator (TYPE_NAME (type)); + } + } + + if (b->kind == sk_class + && !COMPLETE_TYPE_P (current_class_type)) + maybe_add_class_template_decl_list (current_class_type, + type, /*friend_p=*/0); + + decl = TYPE_NAME (type); + gcc_assert (TREE_CODE (decl) == TYPE_DECL); + + /* Set type visibility now if this is a forward declaration. */ + TREE_PUBLIC (decl) = 1; + determine_visibility (decl); + + return type; +} + +/* Subroutines for reverting temporarily to top-level for instantiation + of templates and such. We actually need to clear out the class- and + local-value slots of all identifiers, so that only the global values + are at all visible. Simply setting current_binding_level to the global + scope isn't enough, because more binding levels may be pushed. */ +struct saved_scope *scope_chain; + +/* Return true if ID has not already been marked. */ + +static inline bool +store_binding_p (tree id) +{ + if (!id || !IDENTIFIER_BINDING (id)) + return false; + + if (IDENTIFIER_MARKED (id)) + return false; + + return true; +} + +/* Add an appropriate binding to *OLD_BINDINGS which needs to already + have enough space reserved. */ + +static void +store_binding (tree id, vec<cxx_saved_binding, va_gc> **old_bindings) +{ + cxx_saved_binding saved; + + gcc_checking_assert (store_binding_p (id)); + + IDENTIFIER_MARKED (id) = 1; + + saved.identifier = id; + saved.binding = IDENTIFIER_BINDING (id); + saved.real_type_value = REAL_IDENTIFIER_TYPE_VALUE (id); + (*old_bindings)->quick_push (saved); + IDENTIFIER_BINDING (id) = NULL; +} + +static void +store_bindings (tree names, vec<cxx_saved_binding, va_gc> **old_bindings) +{ + static vec<tree> bindings_need_stored; + tree t, id; + size_t i; + + auto_cond_timevar tv (TV_NAME_LOOKUP); + for (t = names; t; t = TREE_CHAIN (t)) + { + if (TREE_CODE (t) == TREE_LIST) + id = TREE_PURPOSE (t); + else + id = DECL_NAME (t); + + if (store_binding_p (id)) + bindings_need_stored.safe_push (id); + } + if (!bindings_need_stored.is_empty ()) + { + vec_safe_reserve_exact (*old_bindings, bindings_need_stored.length ()); + for (i = 0; bindings_need_stored.iterate (i, &id); ++i) + { + /* We can apparently have duplicates in NAMES. */ + if (store_binding_p (id)) + store_binding (id, old_bindings); + } + bindings_need_stored.truncate (0); + } +} + +/* Like store_bindings, but NAMES is a vector of cp_class_binding + objects, rather than a TREE_LIST. */ + +static void +store_class_bindings (vec<cp_class_binding, va_gc> *names, + vec<cxx_saved_binding, va_gc> **old_bindings) +{ + static vec<tree> bindings_need_stored; + size_t i; + cp_class_binding *cb; + + for (i = 0; vec_safe_iterate (names, i, &cb); ++i) + if (store_binding_p (cb->identifier)) + bindings_need_stored.safe_push (cb->identifier); + if (!bindings_need_stored.is_empty ()) + { + tree id; + vec_safe_reserve_exact (*old_bindings, bindings_need_stored.length ()); + for (i = 0; bindings_need_stored.iterate (i, &id); ++i) + store_binding (id, old_bindings); + bindings_need_stored.truncate (0); + } +} + +/* A chain of saved_scope structures awaiting reuse. */ + +static GTY((deletable)) struct saved_scope *free_saved_scope; + +void +push_to_top_level (void) +{ + struct saved_scope *s; + cp_binding_level *b; + cxx_saved_binding *sb; + size_t i; + bool need_pop; + + auto_cond_timevar tv (TV_NAME_LOOKUP); + + /* Reuse or create a new structure for this saved scope. */ + if (free_saved_scope != NULL) + { + s = free_saved_scope; + free_saved_scope = s->prev; + + vec<cxx_saved_binding, va_gc> *old_bindings = s->old_bindings; + memset (s, 0, sizeof (*s)); + /* Also reuse the structure's old_bindings vector. */ + vec_safe_truncate (old_bindings, 0); + s->old_bindings = old_bindings; + } + else + s = ggc_cleared_alloc<saved_scope> (); + + b = scope_chain ? current_binding_level : 0; + + /* If we're in the middle of some function, save our state. */ + if (cfun) + { + need_pop = true; + push_function_context (); + } + else + need_pop = false; + + if (scope_chain && previous_class_level) + store_class_bindings (previous_class_level->class_shadowed, + &s->old_bindings); + + /* Have to include the global scope, because class-scope decls + aren't listed anywhere useful. */ + for (; b; b = b->level_chain) + { + tree t; + + /* Template IDs are inserted into the global level. If they were + inserted into namespace level, finish_file wouldn't find them + when doing pending instantiations. Therefore, don't stop at + namespace level, but continue until :: . */ + if (global_scope_p (b)) + break; + + store_bindings (b->names, &s->old_bindings); + /* We also need to check class_shadowed to save class-level type + bindings, since pushclass doesn't fill in b->names. */ + if (b->kind == sk_class) + store_class_bindings (b->class_shadowed, &s->old_bindings); + + /* Unwind type-value slots back to top level. */ + for (t = b->type_shadowed; t; t = TREE_CHAIN (t)) + SET_IDENTIFIER_TYPE_VALUE (TREE_PURPOSE (t), TREE_VALUE (t)); + } + + FOR_EACH_VEC_SAFE_ELT (s->old_bindings, i, sb) + IDENTIFIER_MARKED (sb->identifier) = 0; + + s->prev = scope_chain; + s->bindings = b; + s->need_pop_function_context = need_pop; + s->function_decl = current_function_decl; + s->unevaluated_operand = cp_unevaluated_operand; + s->inhibit_evaluation_warnings = c_inhibit_evaluation_warnings; + s->suppress_location_wrappers = suppress_location_wrappers; + s->x_stmt_tree.stmts_are_full_exprs_p = true; + + scope_chain = s; + current_function_decl = NULL_TREE; + current_lang_base = NULL; + current_lang_name = lang_name_cplusplus; + current_namespace = global_namespace; + push_class_stack (); + cp_unevaluated_operand = 0; + c_inhibit_evaluation_warnings = 0; + suppress_location_wrappers = 0; +} + +void +pop_from_top_level (void) +{ + struct saved_scope *s = scope_chain; + cxx_saved_binding *saved; + size_t i; + + auto_cond_timevar tv (TV_NAME_LOOKUP); + + /* Clear out class-level bindings cache. */ + if (previous_class_level) + invalidate_class_lookup_cache (); + pop_class_stack (); + + release_tree_vector (current_lang_base); + + scope_chain = s->prev; + FOR_EACH_VEC_SAFE_ELT (s->old_bindings, i, saved) + { + tree id = saved->identifier; + + IDENTIFIER_BINDING (id) = saved->binding; + SET_IDENTIFIER_TYPE_VALUE (id, saved->real_type_value); + } + + /* If we were in the middle of compiling a function, restore our + state. */ + if (s->need_pop_function_context) + pop_function_context (); + current_function_decl = s->function_decl; + cp_unevaluated_operand = s->unevaluated_operand; + c_inhibit_evaluation_warnings = s->inhibit_evaluation_warnings; + suppress_location_wrappers = s->suppress_location_wrappers; + + /* Make this saved_scope structure available for reuse by + push_to_top_level. */ + s->prev = free_saved_scope; + free_saved_scope = s; +} + +/* Push into the scope of the namespace NS, even if it is deeply + nested within another namespace. */ + +void +push_nested_namespace (tree ns) +{ + auto_cond_timevar tv (TV_NAME_LOOKUP); + if (ns == global_namespace) + push_to_top_level (); + else + { + push_nested_namespace (CP_DECL_CONTEXT (ns)); + resume_scope (NAMESPACE_LEVEL (ns)); + current_namespace = ns; + } +} + +/* Pop back from the scope of the namespace NS, which was previously + entered with push_nested_namespace. */ + +void +pop_nested_namespace (tree ns) +{ + auto_cond_timevar tv (TV_NAME_LOOKUP); + while (ns != global_namespace) + { + ns = CP_DECL_CONTEXT (ns); + current_namespace = ns; + leave_scope (); + } + + pop_from_top_level (); +} + +/* Add TARGET to USINGS, if it does not already exist there. We used + to build the complete graph of usings at this point, from the POV + of the source namespaces. Now we build that as we perform the + unqualified search. */ + +static void +add_using_namespace (vec<tree, va_gc> *&usings, tree target) +{ + if (usings) + for (unsigned ix = usings->length (); ix--;) + if ((*usings)[ix] == target) + return; + + vec_safe_push (usings, target); +} + +/* Tell the debug system of a using directive. */ + +static void +emit_debug_info_using_namespace (tree from, tree target, bool implicit) +{ + /* Emit debugging info. */ + tree context = from != global_namespace ? from : NULL_TREE; + debug_hooks->imported_module_or_decl (target, NULL_TREE, context, false, + implicit); +} + +/* Process a using directive. */ + +void +finish_using_directive (tree target, tree attribs) +{ + if (target == error_mark_node) + return; + + if (current_binding_level->kind != sk_namespace) + add_stmt (build_stmt (input_location, USING_STMT, target)); + else + emit_debug_info_using_namespace (current_binding_level->this_entity, + ORIGINAL_NAMESPACE (target), false); + + add_using_namespace (current_binding_level->using_directives, + ORIGINAL_NAMESPACE (target)); + + bool diagnosed = false; + if (attribs != error_mark_node) + for (tree a = attribs; a; a = TREE_CHAIN (a)) + { + tree name = get_attribute_name (a); + if (current_binding_level->kind == sk_namespace + && is_attribute_p ("strong", name)) + { + if (warning (0, "%<strong%> using directive no longer supported") + && CP_DECL_CONTEXT (target) == current_namespace) + inform (DECL_SOURCE_LOCATION (target), + "you can use an inline namespace instead"); + } + else if ((flag_openmp || flag_openmp_simd) + && get_attribute_namespace (a) == omp_identifier + && (is_attribute_p ("directive", name) + || is_attribute_p ("sequence", name))) + { + if (!diagnosed) + error ("%<omp::%E%> not allowed to be specified in this " + "context", name); + diagnosed = true; + } + else + warning (OPT_Wattributes, "%qD attribute directive ignored", name); + } +} + +/* Pushes X into the global namespace. */ + +tree +pushdecl_top_level (tree x) +{ + auto_cond_timevar tv (TV_NAME_LOOKUP); + push_to_top_level (); + gcc_checking_assert (!DECL_CONTEXT (x)); + DECL_CONTEXT (x) = FROB_CONTEXT (global_namespace); + x = pushdecl_namespace_level (x); + pop_from_top_level (); + return x; +} + +/* Pushes X into the global namespace and calls cp_finish_decl to + register the variable, initializing it with INIT. */ + +tree +pushdecl_top_level_and_finish (tree x, tree init) +{ + auto_cond_timevar tv (TV_NAME_LOOKUP); + push_to_top_level (); + gcc_checking_assert (!DECL_CONTEXT (x)); + DECL_CONTEXT (x) = FROB_CONTEXT (global_namespace); + x = pushdecl_namespace_level (x); + cp_finish_decl (x, init, false, NULL_TREE, 0); + pop_from_top_level (); + return x; +} + +/* Enter the namespaces from current_namerspace to NS. */ + +static int +push_inline_namespaces (tree ns) +{ + int count = 0; + if (ns != current_namespace) + { + gcc_assert (ns != global_namespace); + count += push_inline_namespaces (CP_DECL_CONTEXT (ns)); + resume_scope (NAMESPACE_LEVEL (ns)); + current_namespace = ns; + count++; + } + return count; +} + +/* SLOT is the (possibly empty) binding slot for NAME in CTX. + Reuse or create a namespace NAME. NAME is null for the anonymous + namespace. */ + +static tree +reuse_namespace (tree *slot, tree ctx, tree name) +{ + if (modules_p () && *slot && TREE_PUBLIC (ctx) && name) + { + /* Public namespace. Shared. */ + tree *global_slot = slot; + if (TREE_CODE (*slot) == BINDING_VECTOR) + global_slot = get_fixed_binding_slot (slot, name, + BINDING_SLOT_GLOBAL, false); + + for (ovl_iterator iter (*global_slot); iter; ++iter) + { + tree decl = *iter; + + if (TREE_CODE (decl) == NAMESPACE_DECL && !DECL_NAMESPACE_ALIAS (decl)) + return decl; + } + } + return NULL_TREE; +} + +static tree +make_namespace (tree ctx, tree name, location_t loc, bool inline_p) +{ + /* Create the namespace. */ + tree ns = build_lang_decl (NAMESPACE_DECL, name, void_type_node); + DECL_SOURCE_LOCATION (ns) = loc; + SCOPE_DEPTH (ns) = SCOPE_DEPTH (ctx) + 1; + if (!SCOPE_DEPTH (ns)) + /* We only allow depth 255. */ + sorry ("cannot nest more than %d namespaces", SCOPE_DEPTH (ctx)); + DECL_CONTEXT (ns) = FROB_CONTEXT (ctx); + + if (!name) + /* Anon-namespaces in different header-unit imports are distinct. + But that's ok as their contents all have internal linkage. + (This is different to how they'd behave as textual includes, + but doing this at all is really odd source.) */ + SET_DECL_ASSEMBLER_NAME (ns, anon_identifier); + else if (TREE_PUBLIC (ctx)) + TREE_PUBLIC (ns) = true; + + if (inline_p) + DECL_NAMESPACE_INLINE_P (ns) = true; + + return ns; +} + +/* NS was newly created, finish off making it. */ + +static void +make_namespace_finish (tree ns, tree *slot, bool from_import = false) +{ + if (modules_p () && TREE_PUBLIC (ns) && (from_import || *slot != ns)) + { + /* Merge into global slot. */ + tree *gslot = get_fixed_binding_slot (slot, DECL_NAME (ns), + BINDING_SLOT_GLOBAL, true); + *gslot = ns; + } + + tree ctx = CP_DECL_CONTEXT (ns); + cp_binding_level *scope = ggc_cleared_alloc<cp_binding_level> (); + scope->this_entity = ns; + scope->more_cleanups_ok = true; + scope->kind = sk_namespace; + scope->level_chain = NAMESPACE_LEVEL (ctx); + NAMESPACE_LEVEL (ns) = scope; + + if (DECL_NAMESPACE_INLINE_P (ns)) + vec_safe_push (DECL_NAMESPACE_INLINEES (ctx), ns); + + if (DECL_NAMESPACE_INLINE_P (ns) || !DECL_NAME (ns)) + emit_debug_info_using_namespace (ctx, ns, true); +} + +/* Push into the scope of the NAME namespace. If NAME is NULL_TREE, + then we enter an anonymous namespace. If MAKE_INLINE is true, then + we create an inline namespace (it is up to the caller to check upon + redefinition). Return the number of namespaces entered. */ + +int +push_namespace (tree name, bool make_inline) +{ + auto_cond_timevar tv (TV_NAME_LOOKUP); + int count = 0; + + /* We should not get here if the global_namespace is not yet constructed + nor if NAME designates the global namespace: The global scope is + constructed elsewhere. */ + gcc_checking_assert (global_namespace != NULL && name != global_identifier); + + tree ns = NULL_TREE; + { + name_lookup lookup (name); + if (!lookup.search_qualified (current_namespace, /*usings=*/false)) + ; + else if (TREE_CODE (lookup.value) == TREE_LIST) + { + /* An ambiguous lookup. If exactly one is a namespace, we + want that. If more than one is a namespace, error, but + pick one of them. */ + /* DR2061 can cause us to find multiple namespaces of the same + name. We must treat that carefully and avoid thinking we + need to push a new (possibly) duplicate namespace. Hey, + if you want to use the same identifier within an inline + nest, knock yourself out. */ + for (tree *chain = &lookup.value, next; (next = *chain);) + { + tree decl = TREE_VALUE (next); + if (TREE_CODE (decl) == NAMESPACE_DECL) + { + if (!ns) + ns = decl; + else if (SCOPE_DEPTH (ns) >= SCOPE_DEPTH (decl)) + ns = decl; + + /* Advance. */ + chain = &TREE_CHAIN (next); + } + else + /* Stitch out. */ + *chain = TREE_CHAIN (next); + } + + if (TREE_CHAIN (lookup.value)) + { + error ("%<namespace %E%> is ambiguous", name); + print_candidates (lookup.value); + } + } + else if (TREE_CODE (lookup.value) == NAMESPACE_DECL) + ns = lookup.value; + + if (ns) + if (tree dna = DECL_NAMESPACE_ALIAS (ns)) + { + /* A namespace alias is not allowed here, but if the alias + is for a namespace also inside the current scope, + accept it with a diagnostic. That's better than dying + horribly. */ + if (is_nested_namespace (current_namespace, CP_DECL_CONTEXT (dna))) + { + error ("namespace alias %qD not allowed here, " + "assuming %qD", ns, dna); + ns = dna; + } + else + ns = NULL_TREE; + } + } + + if (ns) + { + /* DR2061. NS might be a member of an inline namespace. We + need to push into those namespaces. */ + if (modules_p ()) + { + for (tree parent, ctx = ns; ctx != current_namespace; + ctx = parent) + { + parent = CP_DECL_CONTEXT (ctx); + + tree bind = *find_namespace_slot (parent, DECL_NAME (ctx), false); + if (bind != ctx) + { + auto &cluster = BINDING_VECTOR_CLUSTER (bind, 0); + binding_slot &slot = cluster.slots[BINDING_SLOT_CURRENT]; + gcc_checking_assert (!(tree)slot || (tree)slot == ctx); + slot = ctx; + } + } + } + + count += push_inline_namespaces (CP_DECL_CONTEXT (ns)); + if (DECL_SOURCE_LOCATION (ns) == BUILTINS_LOCATION) + /* It's not builtin now. */ + DECL_SOURCE_LOCATION (ns) = input_location; + } + else + { + /* Before making a new namespace, see if we already have one in + the existing partitions of the current namespace. */ + tree *slot = find_namespace_slot (current_namespace, name, false); + if (slot) + ns = reuse_namespace (slot, current_namespace, name); + if (!ns) + ns = make_namespace (current_namespace, name, + input_location, make_inline); + + if (pushdecl (ns) == error_mark_node) + ns = NULL_TREE; + else + { + /* Finish up making the namespace. */ + add_decl_to_level (NAMESPACE_LEVEL (current_namespace), ns); + if (!slot) + { + slot = find_namespace_slot (current_namespace, name); + /* This should find the slot created by pushdecl. */ + gcc_checking_assert (slot && *slot == ns); + } + make_namespace_finish (ns, slot); + + /* Add the anon using-directive here, we don't do it in + make_namespace_finish. */ + if (!DECL_NAMESPACE_INLINE_P (ns) && !name) + add_using_namespace (current_binding_level->using_directives, ns); + } + } + + if (ns) + { + /* A public namespace is exported only if explicitly marked, or + it contains exported entities. */ + if (TREE_PUBLIC (ns) && module_exporting_p ()) + DECL_MODULE_EXPORT_P (ns) = true; + if (module_purview_p ()) + DECL_MODULE_PURVIEW_P (ns) = true; + + if (make_inline && !DECL_NAMESPACE_INLINE_P (ns)) + { + error_at (input_location, + "inline namespace must be specified at initial definition"); + inform (DECL_SOURCE_LOCATION (ns), "%qD defined here", ns); + } + resume_scope (NAMESPACE_LEVEL (ns)); + current_namespace = ns; + count++; + } + + return count; +} + +/* Pop from the scope of the current namespace. */ + +void +pop_namespace (void) +{ + auto_cond_timevar tv (TV_NAME_LOOKUP); + + gcc_assert (current_namespace != global_namespace); + current_namespace = CP_DECL_CONTEXT (current_namespace); + /* The binding level is not popped, as it might be re-opened later. */ + leave_scope (); +} + +/* An IMPORT is an import that is defining namespace NAME inside CTX. Find or + create that namespace and add it to the container's binding-vector. */ + +tree +add_imported_namespace (tree ctx, tree name, location_t loc, unsigned import, + bool inline_p, bool visible_p) +{ + // FIXME: Something is not correct about the VISIBLE_P handling. We + // need to insert this namespace into + // (a) the GLOBAL or PARTITION slot, if it is TREE_PUBLIC + // (b) The importing module's slot (always) + // (c) Do we need to put it in the CURRENT slot? This is the + // confused piece. + + tree *slot = find_namespace_slot (ctx, name, true); + tree decl = reuse_namespace (slot, ctx, name); + + /* Creating and binding. */ + if (!decl) + { + decl = make_namespace (ctx, name, loc, inline_p); + DECL_MODULE_IMPORT_P (decl) = true; + make_namespace_finish (decl, slot, true); + } + else if (DECL_NAMESPACE_INLINE_P (decl) != inline_p) + { + error_at (loc, "%s namespace %qD conflicts with reachable definition", + inline_p ? "inline" : "non-inline", decl); + inform (DECL_SOURCE_LOCATION (decl), "reachable %s definition here", + inline_p ? "non-inline" : "inline"); + } + + if (TREE_PUBLIC (decl) && TREE_CODE (*slot) == BINDING_VECTOR) + { + /* See if we can extend the final slot. */ + binding_cluster *last = BINDING_VECTOR_CLUSTER_LAST (*slot); + gcc_checking_assert (last->indices[0].span); + unsigned jx = BINDING_VECTOR_SLOTS_PER_CLUSTER; + + while (--jx) + if (last->indices[jx].span) + break; + tree final = last->slots[jx]; + if (visible_p == !STAT_HACK_P (final) + && MAYBE_STAT_DECL (final) == decl + && last->indices[jx].base + last->indices[jx].span == import + && (BINDING_VECTOR_NUM_CLUSTERS (*slot) > 1 + || (BINDING_VECTOR_SLOTS_PER_CLUSTER > BINDING_SLOTS_FIXED + && jx >= BINDING_SLOTS_FIXED))) + { + last->indices[jx].span++; + return decl; + } + } + + /* Append a new slot. */ + tree *mslot = &(tree &)*append_imported_binding_slot (slot, name, import); + + gcc_assert (!*mslot); + *mslot = visible_p ? decl : stat_hack (decl, NULL_TREE); + + return decl; +} + +/* Pop off extraneous binding levels left over due to syntax errors. + We don't pop past namespaces, as they might be valid. */ + +void +pop_everything (void) +{ + if (ENABLE_SCOPE_CHECKING) + verbatim ("XXX entering %<pop_everything ()%>"); + while (!namespace_bindings_p ()) + { + if (current_binding_level->kind == sk_class) + pop_nested_class (); + else + poplevel (0, 0, 0); + } + if (ENABLE_SCOPE_CHECKING) + verbatim ("XXX leaving %<pop_everything ()%>"); +} + +/* Emit debugging information for using declarations and directives. + If input tree is overloaded fn then emit debug info for all + candidates. */ + +void +cp_emit_debug_info_for_using (tree t, tree context) +{ + /* Don't try to emit any debug information if we have errors. */ + if (seen_error ()) + return; + + /* Do not supply context to imported_module_or_decl, if + it is a global namespace. */ + if (context == global_namespace) + context = NULL_TREE; + + t = MAYBE_BASELINK_FUNCTIONS (t); + + for (lkp_iterator iter (t); iter; ++iter) + { + tree fn = *iter; + + if (TREE_CODE (fn) == TEMPLATE_DECL) + /* FIXME: Handle TEMPLATE_DECLs. */ + continue; + + /* Ignore this FUNCTION_DECL if it refers to a builtin declaration + of a builtin function. */ + if (TREE_CODE (fn) == FUNCTION_DECL + && DECL_EXTERNAL (fn) + && fndecl_built_in_p (fn)) + continue; + + if (building_stmt_list_p ()) + add_stmt (build_stmt (input_location, USING_STMT, fn)); + else + debug_hooks->imported_module_or_decl (fn, NULL_TREE, context, + false, false); + } +} + +#include "gt-cp-name-lookup.h" |